From 0eea50f5a0a0e973ba0b2dcc6b1fba94028a2769 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 26 Jun 2019 00:12:32 +0200 Subject: [PATCH 0001/1854] Add support for compilation on RaspberryPiZero (armv6) More generally, add support for platforms with atomics, which not really linked to architecture but compiler features. This may also help on some mips for example. --- CHANGELOG.md | 1 + client/Makefile | 2 +- .../Linux-Installation-Instructions.md | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index de1f4f293..4726645c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Add support for compilation on RaspberryPiZero (armv6) (@doegox) - Change: updates to README (@iceman) - Change: hf mf/mfu dbg => hw dbg (@doegox) - Change: replace usb_poll_validate_length() by data_available() that supports USART too (@doegox) diff --git a/client/Makefile b/client/Makefile index c3300b0cd..135b143e4 100644 --- a/client/Makefile +++ b/client/Makefile @@ -31,7 +31,7 @@ platform = $(shell uname) VPATH = ../common ../zlib ../uart OBJDIR = obj -LDLIBS = -L/opt/local/lib -L/usr/local/lib -lreadline -lpthread -lm +LDLIBS = -L/opt/local/lib -L/usr/local/lib -lreadline -lpthread -lm -Wl,--as-needed -latomic -Wl,--no-as-needed LUALIB = ../liblua/liblua.a JANSSONLIBPATH = ./jansson JANSSONLIB = $(JANSSONLIBPATH)/libjansson.a diff --git a/doc/md/Installation_Instructions/Linux-Installation-Instructions.md b/doc/md/Installation_Instructions/Linux-Installation-Instructions.md index 5eb8bc66b..065672bca 100644 --- a/doc/md/Installation_Instructions/Linux-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Linux-Installation-Instructions.md @@ -13,7 +13,7 @@ You might want to follow one of these external resources to get an overview, but # Install the required dependencies -## On Debian / Ubuntu / Kali / ParrotOS +## On Debian / Ubuntu / Kali / ParrotOS / Raspbian First what we want to do is get an update for the system. If you need to upgrade do this **before** the install. An upgrade was carried out prior to following these instructions. From 3938933c632974d02e4719ff57ab16de764b5cbf Mon Sep 17 00:00:00 2001 From: Iceman Date: Fri, 28 Jun 2019 15:50:19 +0200 Subject: [PATCH 0002/1854] Update default_keys.dic from mct app pr. --- client/default_keys.dic | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/client/default_keys.dic b/client/default_keys.dic index 5add442e7..922d35914 100644 --- a/client/default_keys.dic +++ b/client/default_keys.dic @@ -902,5 +902,21 @@ b1a862985913, 3b0172066b2f, 3f1a87298691, f3f0172066b2, - - +# +# Tehran ezpay +# +38A88AEC1C43 +CBD2568BC7C6 +7BCB4774EC8F +22ECE9316461 +AE4B497A2527 +EEC0626B01A1 +2C71E22A32FE +91142568B22F +7D56759A974A +D3B1C7EA5C53 +41C82D231497 +0B8B21C692C2 +604Ac8D87C7E +8E7B29460F12 +BB3D7B11D224 From cdb68cd7a4e2b8a3dda1347e93a1a4408216fe82 Mon Sep 17 00:00:00 2001 From: Iceman Date: Sat, 29 Jun 2019 17:22:45 +0200 Subject: [PATCH 0003/1854] Update bt_manual_v10.md --- doc/bt_manual_v10.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/doc/bt_manual_v10.md b/doc/bt_manual_v10.md index 88f2acdaf..4889d3739 100644 --- a/doc/bt_manual_v10.md +++ b/doc/bt_manual_v10.md @@ -33,9 +33,12 @@ Built-in battery can support standalone mode, off-line sniffing, off-line readin * Unplug your Proxmark3 RDV4.0 device from any usb cable. * Remove the plastic upper case of Proxmark3 RDV4.0 with opener. -* Remove temporarily the antenna with a screwdriver to expose the FPC interface. -* Turn off all power switches, insert the FPC wire into the FPC connector, and lock the FPC connector. -* Tear off the blue film of heat conductive double-sided tape. Align the add-on to the hole positions and gently insert it into the case. +* Remove temporarily the antenna with a screwdriver to expose the FPC interface.

+ Image of blue shark add-on fpc interface

+* Turn off all power switches, insert the FPC wire into the FPC connector, and lock the FPC connector.

+ Image of blue shark add-on fpc wire

+* Tear off the blue film of heat conductive double-sided tape. Align the add-on to the hole positions and gently insert it into the case.

+ Image of blue shark add-on blue film location

* Assembly finished!

From f9075feacc9c646912286d86449d3945bdb8620b Mon Sep 17 00:00:00 2001 From: Iceman Date: Sat, 29 Jun 2019 17:30:07 +0200 Subject: [PATCH 0004/1854] Update bt_manual_v10.md --- doc/bt_manual_v10.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/doc/bt_manual_v10.md b/doc/bt_manual_v10.md index 4889d3739..d8d86b4fd 100644 --- a/doc/bt_manual_v10.md +++ b/doc/bt_manual_v10.md @@ -95,7 +95,8 @@ You can also switch serial port from inside the proxmark3 client using the new c * Install driver: http://www.silabs.com/products/development-tools/software/usb-to-uart-bridge-vcp-drivers * Insert the adapter into the USB port. The adapter will search automatically and establish the connection. The adapter will remember the device that was first connected and after that the same device will be connected. -* The adapter button can be used to delete memory so that other add-on can be searched and connected. +* The adapter button can be used to delete memory so that other add-on can be searched and connected.

+ Image of blue shark add-on HC-06 white dongle button * After the connection is established, the blue state LED on add-on will turn on solid. * look for _CP2104 USB tp UART bridge controller_ under devices in order to get the assigned serial port @@ -144,7 +145,9 @@ the device that was first connected and after that the same device will be connected. 2. The adapter button can be used to delete memory so that other add-on -can be searched and connected. +can be searched and connected.

+ Image of blue shark add-on HC-06 white dongle button +

3. After the connection is established, the blue state LED on add-on will turn on solid. From 9e15a3a79b00fb3fa5f5bf43b71dda661f848570 Mon Sep 17 00:00:00 2001 From: Iceman Date: Sat, 29 Jun 2019 20:06:02 +0200 Subject: [PATCH 0005/1854] Create termux_notes.md Massive thanks to Anon for this contribution --- doc/termux_notes.md | 68 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 doc/termux_notes.md diff --git a/doc/termux_notes.md b/doc/termux_notes.md new file mode 100644 index 000000000..f568c6f16 --- /dev/null +++ b/doc/termux_notes.md @@ -0,0 +1,68 @@ +# Proxmark 3 on Android + +## Requirements +- Android phone +- Kernel with one of: + - USB_ACM driver + - module loading enabled + - published sources +- Root +- [Termux](https://play.google.com/store/apps/details?id=com.termux) + +## Notes +From official Proxmark3 wiki: + > In any case, you would need a USB-C to A or USB-OTG cable to connect Proxmark3 to your Android device. Some Android devices may not supply enough power (USB-OTG = 100mA), and need a USB Y-cable and external battery, otherwise they will get strange failures. +ref : https://github.com/Proxmark/proxmark3/wiki/android + +## Tested setup +- OnePlus 5 (arm64, USB-C) +- [OmniROM (Android 9)](https://www.omnirom.org/) +- [OmniROM kernel](https://www.omnirom.org/) +- [Magisk 19.3](https://github.com/topjohnwu/Magisk/) + +## Setup +### Getting ncurses with termcap +You need `termcap` to build the Proxmark3 client. Unfortunately, the prebuilt `ncurses` package does not include it. Since [this PR](https://github.com/termux/termux-packages/pull/2131) hasn't been merged yet, you will have to build `ncurses` yourself + +1. Clone the [termux-packages](https://github.com/termux/termux-packages) repo +2. Apply [the PR](https://github.com/termux/termux-packages/pull/2131) +3. Build `ncurses`. Refer to the [build docs](https://github.com/termux/termux-packages/blob/master/docs/BUILD_ENVIRONMENT.md) for more information. The easiest way is to use Docker: + - `./scripts/run-docker.sh` + - `./build-package.sh ncurses` + - the built packages will be under the `debs` directory +4. Copy `ncurses_6.1.x-x_aarch64.deb` to your phone's `/sdcard` +### Setting up Termux +1. Install [Termux](https://play.google.com/store/apps/details?id=com.termux) and start it +2. Run the following commands: +``` +pkg install make, clang, clang++, readline-dev, libclang-dev, libc++, git, tsu +termux-setup-storage +dpkg -i /sdcard/ncurses_6.1.x-x_aarch64.deb +git clone https://github.com/RfidResearchGroup/proxmark3.git +``` +### Building Proxmark3 client +1. Edit `proxmark3/client/Makefile` and append `-fPIC` to the `CFLAGS` variable (line 30) +2. `make clean && make client` + +### USB_ACM +You need the `USB_ACM` driver enabled and working to communicate with the Proxmark3. To see if it's working, run `tsudo ls /dev/tty*` and it should list `/dev/ttyACM0` (or similar). If you see this, congratulations, skip this step! + +#### Enable the driver +If your kernel has module loading enabled, you should be able to build the module separately and load it on your system without any changes. Otherwise, grab your kernel sources and edit your build config to include `CONFIG_USB_ACM=y`. On the tested kernel, this was under: `android_kernel_oneplus_msm8998/arch/arm64/configs/omni_oneplus5_defconfig` + +#### Building the kernel +If using a custom kernel, refer to the build instructions provided by its maintainer. Otherwise, follow the standard Linux kernel build procedure + +#### Flashing the kernel +You can flash the kernel however it suits you. On the tested device, this was achieved using [TWRP](https://twrp.me/), the most popular custom recovery + +### Testing +Open Termux and start the Proxmark3 client: +``` +tsudo proxmark3/client/proxmark3 /dev/ttyACM0 +``` +Everything should work just like if it was your PC! + +### Troubleshooting +- `dmesg | grep usb` - useful debug info +- `/proc/config.gz` - contains your kernel's build configuration. Look for `CONFIG_USB_ACM`, which should be enabled From f7af3419b7e7ba82cd097220da551d732f1e7b23 Mon Sep 17 00:00:00 2001 From: Iceman Date: Sat, 29 Jun 2019 20:07:53 +0200 Subject: [PATCH 0006/1854] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 489a04044..e63e41ae2 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ This repo is based on iceman fork for Proxmark3. It is dedicated to bringing the |[Issues](#issues)|[Blue shark manual](/doc/bt_manual_v10.md) || |[Notes on UART](/doc/uart_notes.md)||| |[Notes on Frame format](/doc/new_frame_format.md)||| +|[Notes on Termux / Android](/doc/termux_notes.md)||| |[Developing standalone mode](/armsrc/Standalone/readme.md)|[Wiki about standalone mode](https://github.com/RfidResearchGroup/proxmark3/wiki/Standalone-mode) || |[Donations](#Donations)||| From 17f97abfcb89d86c741c6f8ec85ab237c5c2596e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 30 Jun 2019 04:18:03 -0400 Subject: [PATCH 0007/1854] fix: spurious chars because strlen doesnt count ending zero --- armsrc/appmain.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 23b55a23b..37ce14b20 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -368,10 +368,10 @@ void SendVersion(void) { struct p payload; payload.id = *(AT91C_DBGU_CIDR); payload.section_size = text_and_rodata_section_size + compressed_data_section_size; - payload.versionstr_len = strlen(VersionString); - memcpy(payload.versionstr, VersionString, strlen(VersionString)); + payload.versionstr_len = strlen(VersionString) + 1; + memcpy(payload.versionstr, VersionString, payload.versionstr_len); - reply_ng(CMD_VERSION, PM3_SUCCESS, (uint8_t *)&payload, 12 + strlen(VersionString)); + reply_ng(CMD_VERSION, PM3_SUCCESS, (uint8_t *)&payload, 12 + payload.versionstr_len); } // measure the Connection Speed by sending SpeedTestBufferSize bytes to client and measuring the elapsed time. From e02ac1541b2623b9587694c3d6f94fed8e4c654f Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 30 Jun 2019 18:26:08 +0200 Subject: [PATCH 0008/1854] addon doc: H5 & cli pairing --- doc/bt_manual_v10.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/doc/bt_manual_v10.md b/doc/bt_manual_v10.md index d8d86b4fd..11e5566ae 100644 --- a/doc/bt_manual_v10.md +++ b/doc/bt_manual_v10.md @@ -33,7 +33,7 @@ Built-in battery can support standalone mode, off-line sniffing, off-line readin * Unplug your Proxmark3 RDV4.0 device from any usb cable. * Remove the plastic upper case of Proxmark3 RDV4.0 with opener. -* Remove temporarily the antenna with a screwdriver to expose the FPC interface.

+* Remove temporarily the antenna with a H5 screwdriver to expose the FPC interface.

Image of blue shark add-on fpc interface

* Turn off all power switches, insert the FPC wire into the FPC connector, and lock the FPC connector.

Image of blue shark add-on fpc wire

@@ -134,6 +134,17 @@ The first time, your OS will ask you for pairing. The default PIN is 1234. If PIN is not typed in quickly, the client might timeout. Simply restart it again after pairing. +If your OS doesn't prompt you for pairing, you can do it in command line, e.g. (again, replace with your addon MAC address): + +```sh +bluetoothctl +[bluetooth]# pairable on +[bluetooth]# trust aa:bb:cc:dd:ee:ff +[bluetooth]# pair 20:19:04:20:04:08 +[agent] Enter PIN code: 1234 +[bluetooth]# quit +``` + #### (2) Fast connection using dedicated USB Bluetooth adapter under Linux

From eca84d4880d5b7693ef2e16335b914c2bfdc63a3 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 30 Jun 2019 18:29:54 +0200 Subject: [PATCH 0009/1854] fix mac --- doc/bt_manual_v10.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/bt_manual_v10.md b/doc/bt_manual_v10.md index 11e5566ae..d55efb6dc 100644 --- a/doc/bt_manual_v10.md +++ b/doc/bt_manual_v10.md @@ -140,7 +140,7 @@ If your OS doesn't prompt you for pairing, you can do it in command line, e.g. ( bluetoothctl [bluetooth]# pairable on [bluetooth]# trust aa:bb:cc:dd:ee:ff -[bluetooth]# pair 20:19:04:20:04:08 +[bluetooth]# pair aa:bb:cc:dd:ee:ff [agent] Enter PIN code: 1234 [bluetooth]# quit ``` From b814653eed9533182985b6de44b3837fc616a296 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 30 Jun 2019 18:31:46 +0200 Subject: [PATCH 0010/1854] Explain H5 --- doc/bt_manual_v10.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/bt_manual_v10.md b/doc/bt_manual_v10.md index d55efb6dc..448986302 100644 --- a/doc/bt_manual_v10.md +++ b/doc/bt_manual_v10.md @@ -33,7 +33,7 @@ Built-in battery can support standalone mode, off-line sniffing, off-line readin * Unplug your Proxmark3 RDV4.0 device from any usb cable. * Remove the plastic upper case of Proxmark3 RDV4.0 with opener. -* Remove temporarily the antenna with a H5 screwdriver to expose the FPC interface.

+* Remove temporarily the antenna with a H5 (Hex/Allen) screwdriver to expose the FPC interface.

Image of blue shark add-on fpc interface

* Turn off all power switches, insert the FPC wire into the FPC connector, and lock the FPC connector.

Image of blue shark add-on fpc wire

From c4036448827b2f74718c86bd168b9ecc09057229 Mon Sep 17 00:00:00 2001 From: jbono Date: Mon, 1 Jul 2019 16:47:10 +0200 Subject: [PATCH 0011/1854] Added documentation: Compiling for other boards --- .../0_Compilation-Instructions.md | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md b/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md index ffe312aac..bb3699a72 100644 --- a/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md +++ b/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md @@ -26,6 +26,41 @@ cd client ./proxmark3 /dev/ttyACM0 ``` +## Compiling for other boards + +Available boards + +| BOARD | PLATFORM | +|:---------------:|:---------------------------------------| +| `PM3RDV4` (def) | Proxmark3 rdv4 with AT91SAM7S512 | +| `PM3EVO` | Proxmark3 EVO with AT91SAM7S512 | +| `PM3EASY` | Proxmark3 rdv3 Easy with AT91SAM7S256 | +| `PM3RDV2` | Proxmark3 rdv2 with AT91SAM7S512 | +| `PM3OLD256` | Proxmark3 V1 with AT91SAM7S256 | +| `PM3OLD512` | Proxmark3 V1 with AT91SAM7S512 | + +Create a file named `Makefile.platform` in the root directory of the repository: + +```sh +# PLATFORM=${BOARD} +# Following example is to compile sources for Proxmark3 rdv3 Easy +PLATFORM=PM3EASY +``` + +From this point: + +```sh +# Clean and compile +make clean && make all + +# Flash the BOOTROM & FULLIMAGE +client/flasher /dev/ttyACM0 -b bootrom/obj/bootrom.elf armsrc/obj/fullimage.elf + +# Run the client +cd client +./proxmark3 /dev/ttyACM0 +``` + ## Next steps For the next steps, please read the following pages: From f5f9d9f0c0f9981f94cc9eeedc8d2e69f5acd0d3 Mon Sep 17 00:00:00 2001 From: Slurdge Date: Wed, 3 Jul 2019 14:16:16 +0200 Subject: [PATCH 0012/1854] Add support for automatic COM detection on Windows --- CHANGELOG.md | 1 + proxmark3.sh | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4726645c7..611ab4f1c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Add support for automatic COM detection on Windows (@slurdge) - Add support for compilation on RaspberryPiZero (armv6) (@doegox) - Change: updates to README (@iceman) - Change: hf mf/mfu dbg => hw dbg (@doegox) diff --git a/proxmark3.sh b/proxmark3.sh index b4cbd49fd..ef056752b 100755 --- a/proxmark3.sh +++ b/proxmark3.sh @@ -28,6 +28,19 @@ function wait4proxmark_macOS { echo $PM3 } +function wait4proxmark_Windows { + echo >&2 "Waiting for Proxmark to appear..." + while true; do + device=$(wmic path Win32_SerialPort get DeviceID,PNPDeviceID 2>/dev/null | awk 'NR==2') + if [[ $device =~ VID_9AC4\&PID_4B8F ]]; then + PM3=${device/ */} + break + fi + sleep .1 + done + echo $PM3 +} + SCRIPT=$(basename -- "$0") if [ "$SCRIPT" = "proxmark3.sh" ]; then @@ -51,6 +64,8 @@ if [ "$HOSTOS" = "LINUX" ]; then PORT=$(wait4proxmark_Linux) elif [ "$HOSTOS" = "DARWIN" ]; then PORT=$(wait4proxmark_macOS) +elif [[ "$HOSTOS" =~ MINGW(32|64)_NT* ]]; then + PORT=$(wait4proxmark_Windows) else echo "Host OS not recognized, abort: $HOSTOS" exit 1 From ea487f3d8863c31b5695f4dfea462916a7a01c0e Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 3 Jul 2019 14:45:41 +0200 Subject: [PATCH 0013/1854] Ease non-QT users life --- .../Linux-Installation-Instructions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/md/Installation_Instructions/Linux-Installation-Instructions.md b/doc/md/Installation_Instructions/Linux-Installation-Instructions.md index 065672bca..8954a38f7 100644 --- a/doc/md/Installation_Instructions/Linux-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Linux-Installation-Instructions.md @@ -25,7 +25,7 @@ Install the requirements ```sh sudo apt-get install p7zip git ca-certificates build-essential libreadline5 libreadline-dev \ -libusb-0.1-4 libusb-dev libqt4-dev perl pkg-config wget libncurses5-dev gcc-arm-none-eabi libstdc++-arm-none-eabi-newlib +libusb-0.1-4 libusb-dev perl pkg-config wget libncurses5-dev gcc-arm-none-eabi libstdc++-arm-none-eabi-newlib libqt4-dev ``` If you don't need the graphical components of the Proxmark3 client, you can skip the installation of `libqt4-dev`. From 7205a910c56466e9ea3babb06683604f96ec1bd3 Mon Sep 17 00:00:00 2001 From: Slurdge Date: Wed, 3 Jul 2019 16:01:07 +0200 Subject: [PATCH 0014/1854] Add compiler name in [CLIENT] section --- client/cmdhw.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/client/cmdhw.c b/client/cmdhw.c index 871d3bfbd..7fb241667 100644 --- a/client/cmdhw.c +++ b/client/cmdhw.c @@ -621,6 +621,11 @@ void pm3_version(bool verbose) { PrintAndLogEx(NORMAL, "\n" _BLUE_(" [ Proxmark3 RFID instrument ]") "\n"); PrintAndLogEx(NORMAL, "\n [ CLIENT ]"); PrintAndLogEx(NORMAL, " client: RRG/Iceman"); // TODO version info? +#if defined(__clang__) + PrintAndLogEx(NORMAL, " compiled with Clang/LLVM "__VERSION__); +#elif defined(__GNUC__) || defined(__GNUG__) + PrintAndLogEx(NORMAL, " compiled with GCC "__VERSION__); +#endif PrintAndLogEx(NORMAL, "\n [ PROXMARK RDV4 ]"); PrintAndLogEx(NORMAL, " external flash: %s", IfPm3Flash() ? _GREEN_("present") : _YELLOW_("absent")); PrintAndLogEx(NORMAL, " smartcard reader: %s", IfPm3Smartcard() ? _GREEN_("present") : _YELLOW_("absent")); From 6646c20ef33557f5148acd333efee54541996063 Mon Sep 17 00:00:00 2001 From: Victor Date: Thu, 4 Jul 2019 11:21:45 +0100 Subject: [PATCH 0015/1854] Fix clock deadlock in hitag sniff --- armsrc/hitag2.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index 2a7cf2859..2382be273 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -739,7 +739,7 @@ void SniffHitag(void) { AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; // synchronized startup procedure - while (AT91C_BASE_TC0->TC_CV > 0) {}; // wait until TC0 returned to zero + while (AT91C_BASE_TC1->TC_CV > 0) {}; // wait until TC1 returned to zero // Reset the received frame, frame count and timing info memset(rx, 0x00, sizeof(rx)); @@ -887,7 +887,6 @@ void SniffHitag(void) { set_tracing(false); AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; - AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; // release allocated memory from BigBuff. BigBuf_free(); From ae4c3374cb385f2ab1372aeddda7046a2d6a6f16 Mon Sep 17 00:00:00 2001 From: Iceman Date: Thu, 4 Jul 2019 12:33:01 +0200 Subject: [PATCH 0016/1854] Update default_keys.dic More keys from https://github.com/korsehindi/proxmark3/commit/6b6bafed5472cdfc793f5487e870705a7fb65b8a --- client/default_keys.dic | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/client/default_keys.dic b/client/default_keys.dic index 922d35914..8afac8995 100644 --- a/client/default_keys.dic +++ b/client/default_keys.dic @@ -920,3 +920,9 @@ D3B1C7EA5C53 604Ac8D87C7E 8E7B29460F12 BB3D7B11D224 +# +# Chaco +# +b210cfa436d2 +b8b1cfa646a8 +a9f95891f0a4 From ee222095c38d96a1d2f81da77687328dc199e275 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 4 Jul 2019 20:55:24 +0200 Subject: [PATCH 0017/1854] bt manual: add scan on step --- doc/bt_manual_v10.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/bt_manual_v10.md b/doc/bt_manual_v10.md index 448986302..aa9a7d9d8 100644 --- a/doc/bt_manual_v10.md +++ b/doc/bt_manual_v10.md @@ -139,6 +139,10 @@ If your OS doesn't prompt you for pairing, you can do it in command line, e.g. ( ```sh bluetoothctl [bluetooth]# pairable on +[bluetooth]# scan on +Discovery started +... +[CHG] Device aa:bb:cc:dd:ee:ff Name: PM3_RDV4.0 [bluetooth]# trust aa:bb:cc:dd:ee:ff [bluetooth]# pair aa:bb:cc:dd:ee:ff [agent] Enter PIN code: 1234 From 773845f4116e30212f7d7b0087957ab275e4f3ba Mon Sep 17 00:00:00 2001 From: Victor Date: Thu, 4 Jul 2019 22:11:18 +0100 Subject: [PATCH 0018/1854] Print help if unknown arg for hitag reader/writer --- client/cmdlfhitag.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/cmdlfhitag.c b/client/cmdlfhitag.c index 998512575..27c352c53 100644 --- a/client/cmdlfhitag.c +++ b/client/cmdlfhitag.c @@ -551,6 +551,7 @@ static int CmdLFHitagReader(const char *Cmd) { case WHTSF_CHALLENGE: case WHTSF_KEY: case WHT2F_CRYPTO: + default: return usage_hitag_reader(); } @@ -665,6 +666,7 @@ static int CmdLFHitagWriter(const char *Cmd) { case RHT2F_CRYPTO: case RHT2F_TEST_AUTH_ATTEMPTS: case RHT2F_UID_ONLY: + default: return usage_hitag_writer(); } From e047d223e4b1a68e24f8b2fc615df3a848809c8b Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 6 Jul 2019 10:06:04 +0200 Subject: [PATCH 0019/1854] Fix #216: skip --as-needed linker options under MacOSX --- client/Makefile | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/client/Makefile b/client/Makefile index 135b143e4..490716eda 100644 --- a/client/Makefile +++ b/client/Makefile @@ -31,7 +31,14 @@ platform = $(shell uname) VPATH = ../common ../zlib ../uart OBJDIR = obj -LDLIBS = -L/opt/local/lib -L/usr/local/lib -lreadline -lpthread -lm -Wl,--as-needed -latomic -Wl,--no-as-needed +LDLIBS = -L/opt/local/lib -L/usr/local/lib -lreadline -lpthread -lm +# RPi Zero gcc requires -latomic +# but MacOSX /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld +# doesn't recognize option --as-needed +ifneq ($(platform),Darwin) + LDLIBS += -Wl,--as-needed -latomic -Wl,--no-as-needed +endif + LUALIB = ../liblua/liblua.a JANSSONLIBPATH = ./jansson JANSSONLIB = $(JANSSONLIBPATH)/libjansson.a From 5fbbbc30ba13cf15832e72f6d94a83ccd6f8914d Mon Sep 17 00:00:00 2001 From: slurdge Date: Sat, 6 Jul 2019 15:31:32 +0200 Subject: [PATCH 0020/1854] Fix #224 --- proxmark3.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proxmark3.sh b/proxmark3.sh index ef056752b..b4aa51ffb 100755 --- a/proxmark3.sh +++ b/proxmark3.sh @@ -31,8 +31,8 @@ function wait4proxmark_macOS { function wait4proxmark_Windows { echo >&2 "Waiting for Proxmark to appear..." while true; do - device=$(wmic path Win32_SerialPort get DeviceID,PNPDeviceID 2>/dev/null | awk 'NR==2') - if [[ $device =~ VID_9AC4\&PID_4B8F ]]; then + device=$(wmic path Win32_SerialPort where "PNPDeviceID like '%VID_9AC4&PID_4B8F%'" get DeviceID,PNPDeviceID 2>/dev/null | awk 'NR==2') + if [[ $device != "" ]]; then PM3=${device/ */} break fi From 8926114b41ca6cbe87fa0b6a1f44b05fb5c6f101 Mon Sep 17 00:00:00 2001 From: slurdge Date: Sat, 6 Jul 2019 15:50:44 +0200 Subject: [PATCH 0021/1854] Gitignore more linux profile related files --- .gitignore | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.gitignore b/.gitignore index bad050e8f..e37ce9534 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,11 @@ .history .bash_history +.bash_profile +.bash_logout +.bashrc +.inputrc +.profile *.log *.eml *.o From 959a2a9c87a1ef1eb1bbab06d5caac6bbc9eb48c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 6 Jul 2019 11:16:39 -0400 Subject: [PATCH 0022/1854] mysterious keys #issue 839 offical repo --- client/default_keys.dic | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/client/default_keys.dic b/client/default_keys.dic index 8afac8995..13e289e0c 100644 --- a/client/default_keys.dic +++ b/client/default_keys.dic @@ -97,9 +97,15 @@ f1d83f964314,--RKFRejskortDanmarkKeyB fc00018778f7,--VästtrafikenKeyA, RKFÖstgötaTrafikenKeyA 44ab09010845,-- hotel system 85fed980ea5a,-- hotel system -314B49474956,--VIGIK1KeyA -564c505f4d41,--VIGIK1KeyB -ba5b895da162,--VIGIK1KeyB +314B49474956 --VIGIK1 A +564c505f4d41 --VIGIK1 B +ba5b895da162 --VIGIK1 B +# Vigik mystery Keys Mifare 1k EV1 (S50) +5c8ff9990da2, 16 A +75ccb59c9bed, 17 A +d01afeeb890a, 16 B +4b791bea7bcc, 17 B +# 4143414F5250, a9b43414F585,--Tehran Railway 1FB235AC1388,--Tehran Railway @@ -109,8 +115,6 @@ f4a9ef2afc6d,--BCARD KeyB # # a9f953def0a3,-- -75ccb59c9bed,-- mystery KeyA Mifare 1k EV1 (S50) Sector 17! -4b791bea7bcc,-- mystery KeyB Mifare 1k EV1 (S50) Sector 17! # # Here be BIP keys... 3A42F33AF429, From 95fd247e109be84d28a55d760ce90f131162fca9 Mon Sep 17 00:00:00 2001 From: t0m4 Date: Sun, 7 Jul 2019 10:52:00 +0200 Subject: [PATCH 0023/1854] Add 'hf 15 csetuid' command to set UID on ISO15693 Magic tags --- client/cmdhf15.c | 109 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) diff --git a/client/cmdhf15.c b/client/cmdhf15.c index 6f6d1ebc2..064781104 100644 --- a/client/cmdhf15.c +++ b/client/cmdhf15.c @@ -407,6 +407,17 @@ static int usage_15_readmulti(void) { "\tcount#: number of pages"); return 0; } +static int usage_15_csetuid(void) { + PrintAndLogEx(NORMAL, "Set UID for magic Chinese card (only works with such cards)\n" + "\n" + "Usage: hf 15 csetuid \n" + "Options:\n" + "\tuid : <8B hex> full UID eg E011223344556677\n" + "\n" + "Example:\n" + "\thf 15 csetuid E011223344556677"); + return 0; +} /** * parses common HF 15 CMD parameters and prepares some data structures @@ -1269,6 +1280,103 @@ static int CmdHF15Restore(const char *Cmd) { return 0; } +/** + * Commandline handling: HF15 CMD CSETUID + * Set UID for magic Chinese card + */ +static int CmdHF15CSetUID(const char *Cmd) { + uint8_t uid[8] = {0x00}; + uint8_t oldUid[8], newUid[8] = {0x00}; + PacketResponseNG resp; + int reply = 1, fast = 0; + uint8_t data[4][9] = {0x00}; + + char cmdp = param_getchar(Cmd, 0); + if (strlen(Cmd) < 1 || cmdp == 'h' || cmdp == 'H') return usage_15_csetuid(); + + if (param_gethex(Cmd, 0, uid, 16)) { + PrintAndLogEx(WARNING, "UID must include 16 HEX symbols"); + return 1; + } + + if (strcmp(sprint_hex_inrow_ex(uid, 1, 2), "E0") != 0) { + PrintAndLogEx(WARNING, "UID must begin with the byte 'E0'"); + return 1; + } + + PrintAndLogEx(SUCCESS, "new UID | %s", sprint_hex(uid, sizeof(uid))); + PrintAndLogEx(NORMAL, "Using backdoor Magic tag function"); + + if (!getUID(oldUid)) { + PrintAndLogEx(FAILED, "Can't get old UID."); + return 1; + } + + // Command 1 : 02213E00000000 + data[0][0] = 0x02; + data[0][1] = 0x21; + data[0][2] = 0x3e; + data[0][3] = 0x00; + data[0][4] = 0x00; + data[0][5] = 0x00; + data[0][6] = 0x00; + + // Command 2 : 02213F69960000 + data[1][0] = 0x02; + data[1][1] = 0x21; + data[1][2] = 0x3f; + data[1][3] = 0x69; + data[1][4] = 0x96; + data[1][5] = 0x00; + data[1][6] = 0x00; + + // Command 3 : 022138u8u7u6u5 (where uX = uid byte X) + data[2][0] = 0x02; + data[2][1] = 0x21; + data[2][2] = 0x38; + data[2][3] = uid[7]; + data[2][4] = uid[6]; + data[2][5] = uid[5]; + data[2][6] = uid[4]; + + // Command 4 : 022139u4u3u2u1 (where uX = uid byte X) + data[3][0] = 0x02; + data[3][1] = 0x21; + data[3][2] = 0x39; + data[3][3] = uid[3]; + data[3][4] = uid[2]; + data[3][5] = uid[1]; + data[3][6] = uid[0]; + + for (int i=0; i<4; i++) { + AddCrc15(data[i], 7); + + clearCommandBuffer(); + SendCommandOLD(CMD_ISO_15693_COMMAND, sizeof(data[i]), fast, reply, data[i], sizeof(data[i])); + + if (reply) { + if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { + uint8_t len = resp.oldarg[0]; + PrintAndLogEx(NORMAL, "received %i octets", len); + PrintAndLogEx(NORMAL, "%s", sprint_hex(resp.data.asBytes, len)); + } else { + PrintAndLogEx(WARNING, "timeout while waiting for reply."); + } + } + } + + if (!getUID(newUid)) { + PrintAndLogEx(FAILED, "Can't get new UID."); + return 1; + } + + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(SUCCESS, "old UID : %02X %02X %02X %02X %02X %02X %02X %02X", oldUid[7], oldUid[6], oldUid[5], oldUid[4], oldUid[3], oldUid[2], oldUid[1], oldUid[0]); + PrintAndLogEx(SUCCESS, "new UID : %02X %02X %02X %02X %02X %02X %02X %02X", newUid[7], newUid[6], newUid[5], newUid[4], newUid[3], newUid[2], newUid[1], newUid[0]); + + return 0; +} + static command_t CommandTable[] = { {"help", CmdHF15Help, AlwaysAvailable, "This help"}, {"demod", CmdHF15Demod, AlwaysAvailable, "Demodulate ISO15693 from tag"}, @@ -1285,6 +1393,7 @@ static command_t CommandTable[] = { {"read", CmdHF15Read, IfPm3Iso15693, "Read a block"}, {"write", CmdHF15Write, IfPm3Iso15693, "Write a block"}, {"readmulti", CmdHF15Readmulti, IfPm3Iso15693, "Reads multiple Blocks"}, + {"csetuid", CmdHF15CSetUID, IfPm3Iso15693, "Set UID for magic Chinese card"}, {NULL, NULL, NULL, NULL} }; From 88df59722ef4e45a28251bdd44b5396224066576 Mon Sep 17 00:00:00 2001 From: t0m4 Date: Sun, 7 Jul 2019 12:10:51 +0200 Subject: [PATCH 0024/1854] Code cleaning --- client/cmdhf15.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdhf15.c b/client/cmdhf15.c index 064781104..3d5ea9e59 100644 --- a/client/cmdhf15.c +++ b/client/cmdhf15.c @@ -1299,7 +1299,7 @@ static int CmdHF15CSetUID(const char *Cmd) { return 1; } - if (strcmp(sprint_hex_inrow_ex(uid, 1, 2), "E0") != 0) { + if (uid[0] != 0xe0) { PrintAndLogEx(WARNING, "UID must begin with the byte 'E0'"); return 1; } From 0a1b2698c976b61c7deae52a3fdbd14af6db4718 Mon Sep 17 00:00:00 2001 From: t0m4 Date: Sun, 7 Jul 2019 14:00:13 +0200 Subject: [PATCH 0025/1854] Code review --- client/cmdhf15.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/client/cmdhf15.c b/client/cmdhf15.c index 3d5ea9e59..9a40d03cd 100644 --- a/client/cmdhf15.c +++ b/client/cmdhf15.c @@ -1289,10 +1289,10 @@ static int CmdHF15CSetUID(const char *Cmd) { uint8_t oldUid[8], newUid[8] = {0x00}; PacketResponseNG resp; int reply = 1, fast = 0; - uint8_t data[4][9] = {0x00}; + uint8_t data[4][9] = {{0x00}}; - char cmdp = param_getchar(Cmd, 0); - if (strlen(Cmd) < 1 || cmdp == 'h' || cmdp == 'H') return usage_15_csetuid(); + char cmdp = tolower(param_getchar(Cmd, 0)); + if (strlen(Cmd) < 1 || cmdp == 'h') return usage_15_csetuid(); if (param_gethex(Cmd, 0, uid, 16)) { PrintAndLogEx(WARNING, "UID must include 16 HEX symbols"); @@ -1300,7 +1300,7 @@ static int CmdHF15CSetUID(const char *Cmd) { } if (uid[0] != 0xe0) { - PrintAndLogEx(WARNING, "UID must begin with the byte 'E0'"); + PrintAndLogEx(WARNING, "UID must begin with the byte " _YELLOW_("E0")); return 1; } @@ -1309,7 +1309,7 @@ static int CmdHF15CSetUID(const char *Cmd) { if (!getUID(oldUid)) { PrintAndLogEx(FAILED, "Can't get old UID."); - return 1; + return PM3_ESOFT; } // Command 1 : 02213E00000000 @@ -1367,14 +1367,14 @@ static int CmdHF15CSetUID(const char *Cmd) { if (!getUID(newUid)) { PrintAndLogEx(FAILED, "Can't get new UID."); - return 1; + return PM3_ESOFT; } PrintAndLogEx(NORMAL, ""); PrintAndLogEx(SUCCESS, "old UID : %02X %02X %02X %02X %02X %02X %02X %02X", oldUid[7], oldUid[6], oldUid[5], oldUid[4], oldUid[3], oldUid[2], oldUid[1], oldUid[0]); PrintAndLogEx(SUCCESS, "new UID : %02X %02X %02X %02X %02X %02X %02X %02X", newUid[7], newUid[6], newUid[5], newUid[4], newUid[3], newUid[2], newUid[1], newUid[0]); - return 0; + return PM3_SUCCESS; } static command_t CommandTable[] = { From c096a422a8e806bcb674cba5d502a8ae7f65049b Mon Sep 17 00:00:00 2001 From: t0m4 Date: Sun, 7 Jul 2019 14:33:29 +0200 Subject: [PATCH 0026/1854] Changelog update --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 611ab4f1c..368ec0073 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Add `hf 15 csetuid` - set UID on ISO-15693 Magic tags (@t0m4-null) - Add support for automatic COM detection on Windows (@slurdge) - Add support for compilation on RaspberryPiZero (armv6) (@doegox) - Change: updates to README (@iceman) From 0b1479b43c197af87f88eb4051f6f7f7aa18123c Mon Sep 17 00:00:00 2001 From: Uli Heilmeier Date: Sun, 7 Jul 2019 21:33:00 +0200 Subject: [PATCH 0027/1854] BT Manual: Update device info for macOS --- doc/bt_manual_v10.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/bt_manual_v10.md b/doc/bt_manual_v10.md index aa9a7d9d8..032680cfa 100644 --- a/doc/bt_manual_v10.md +++ b/doc/bt_manual_v10.md @@ -188,6 +188,11 @@ After reboot you can go ahead to pairing your Proxmark3 RDV4 Blue Shark: 5. Make sure the Blue Shark BT switch is turned ON 6. On your Mac, choose Apple menu -> System Preferences, then click Bluetooth. 7. Select the device in the list, then click Connect and add the 1234 pwd. + 8. A serial port like `/dev/tty.PM3_RDV40-DevB` will be created, use Proxmark3 client on it + +```sh +./proxmark /dev/tty.PM3_RDV40-DevB +``` ### 6. OTHER NOTES From 248b109c9a5374299d839878aeaa3c0b3b3fac2d Mon Sep 17 00:00:00 2001 From: slurdge Date: Tue, 9 Jul 2019 21:57:54 +0200 Subject: [PATCH 0028/1854] Check if bootloader segment is within bounds --- client/flash.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/client/flash.c b/client/flash.c index 891efaeb3..d8ac983e7 100644 --- a/client/flash.c +++ b/client/flash.c @@ -173,6 +173,10 @@ static int check_segs(flash_file_t *ctx, int can_write_bl) { PrintAndLogEx(ERR, "Attempted to write bootloader but bootloader writes are not enabled"); return -1; } + if (can_write_bl && seg->start < BOOTLOADER_END && (seg->start + seg->length > BOOTLOADER_END)) { + PrintAndLogEx(ERR, "Error: Segment is outside of bootloader bounds"); + return -1; + } } return 0; } From 71b70f4ffb7f0b83256d4645957973b178d543ba Mon Sep 17 00:00:00 2001 From: slurdge Date: Fri, 5 Jul 2019 14:43:28 +0200 Subject: [PATCH 0029/1854] Add compiler info for proxmark3 armsrc --- armsrc/appmain.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 37ce14b20..ec953f7ca 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -346,6 +346,12 @@ void SendVersion(void) { FormatVersionInformation(temp, sizeof(temp), " os: ", &version_information); strncat(VersionString, temp, sizeof(VersionString) - strlen(VersionString) - 1); +#if defined(__clang__) + strncat(VersionString, " compiled with Clang/LLVM "__VERSION__"\n", sizeof(VersionString) - strlen(VersionString) - 1); +#elif defined(__GNUC__) || defined(__GNUG__) + strncat(VersionString, " compiled with GCC "__VERSION__"\n", sizeof(VersionString) - strlen(VersionString) - 1); +#endif + strncat(VersionString, "\n [ FPGA ]\n", sizeof(VersionString) - strlen(VersionString) - 1); for (int i = 0; i < fpga_bitstream_num; i++) { From aab0558a5808257f37bad76d16081a2a689f8322 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 9 Jul 2019 22:49:57 +0200 Subject: [PATCH 0030/1854] minor txt alignments --- armsrc/Standalone/hf_bog.c | 2 +- armsrc/Standalone/hf_colin.c | 2 +- armsrc/Standalone/hf_mattyrun.c | 2 +- armsrc/Standalone/hf_young.c | 2 +- armsrc/Standalone/lf_hidbrute.c | 2 +- armsrc/Standalone/lf_icerun.c | 2 +- armsrc/Standalone/lf_proxbrute.c | 2 +- armsrc/Standalone/lf_samyrun.c | 2 +- armsrc/Standalone/placeholder.c | 2 +- armsrc/Standalone/readme.md | 6 +++--- armsrc/appmain.c | 12 ++++++------ 11 files changed, 18 insertions(+), 18 deletions(-) diff --git a/armsrc/Standalone/hf_bog.c b/armsrc/Standalone/hf_bog.c index 0ee0a9066..093bc841f 100644 --- a/armsrc/Standalone/hf_bog.c +++ b/armsrc/Standalone/hf_bog.c @@ -282,7 +282,7 @@ void RAMFUNC SniffAndStore(uint8_t param) { } void ModInfo(void) { - DbpString(" HF 14a sniff standalone with ULC/ULEV1/NTAG auth storing in flashmem - aka BogitoRun (Bogito)"); + DbpString(" HF 14a sniff standalone with ULC/ULEV1/NTAG auth storing in flashmem - aka BogitoRun (Bogito)"); } void RunMod() { diff --git a/armsrc/Standalone/hf_colin.c b/armsrc/Standalone/hf_colin.c index 76eefcc14..63366259e 100644 --- a/armsrc/Standalone/hf_colin.c +++ b/armsrc/Standalone/hf_colin.c @@ -197,7 +197,7 @@ void WriteTagToFlash(uint8_t index, size_t size) { } void ModInfo(void) { - DbpString(" HF Mifare ultra fast sniff/sim/clone - aka VIGIKPWN (Colin Brigato)"); + DbpString(" HF Mifare ultra fast sniff/sim/clone - aka VIGIKPWN (Colin Brigato)"); } void RunMod() { diff --git a/armsrc/Standalone/hf_mattyrun.c b/armsrc/Standalone/hf_mattyrun.c index 66147c2fb..7747a49da 100644 --- a/armsrc/Standalone/hf_mattyrun.c +++ b/armsrc/Standalone/hf_mattyrun.c @@ -193,7 +193,7 @@ static int saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace, ui } void ModInfo(void) { - DbpString(" HF Mifare sniff/clone - aka MattyRun (Matías A. Ré Medina)"); + DbpString(" HF Mifare sniff/clone - aka MattyRun (Matías A. Ré Medina)"); } void RunMod() { diff --git a/armsrc/Standalone/hf_young.c b/armsrc/Standalone/hf_young.c index 6b56935bd..3ef9e37cf 100644 --- a/armsrc/Standalone/hf_young.c +++ b/armsrc/Standalone/hf_young.c @@ -19,7 +19,7 @@ typedef struct { void ModInfo(void) { - DbpString(" HF Mifare sniff/simulation - (Craig Young)"); + DbpString(" HF Mifare sniff/simulation - (Craig Young)"); } void RunMod() { diff --git a/armsrc/Standalone/lf_hidbrute.c b/armsrc/Standalone/lf_hidbrute.c index 06b0049ad..2c784c31a 100644 --- a/armsrc/Standalone/lf_hidbrute.c +++ b/armsrc/Standalone/lf_hidbrute.c @@ -27,7 +27,7 @@ #include "lf_hidbrute.h" void ModInfo(void) { - DbpString(" LF HID corporate 1000 bruteforce - aka Corporatebrute (Federico dotta & Maurizio Agazzini)"); + DbpString(" LF HID corporate 1000 bruteforce - aka Corporatebrute (Federico dotta & Maurizio Agazzini)"); } // samy's sniff and repeat routine for LF diff --git a/armsrc/Standalone/lf_icerun.c b/armsrc/Standalone/lf_icerun.c index e62c79329..abc2daa4e 100644 --- a/armsrc/Standalone/lf_icerun.c +++ b/armsrc/Standalone/lf_icerun.c @@ -10,7 +10,7 @@ #include "lf_icerun.h" void ModInfo(void) { - DbpString(" LF skeleton mode - aka IceRun (iceman)"); + DbpString(" LF skeleton mode - aka IceRun (iceman)"); } // samy's sniff and repeat routine for LF diff --git a/armsrc/Standalone/lf_proxbrute.c b/armsrc/Standalone/lf_proxbrute.c index d10a1fbfe..09ddb1989 100644 --- a/armsrc/Standalone/lf_proxbrute.c +++ b/armsrc/Standalone/lf_proxbrute.c @@ -12,7 +12,7 @@ #include "lf_proxbrute.h" void ModInfo(void) { - DbpString(" LF HID ProxII bruteforce - aka Proxbrute (Brad Antoniewicz)"); + DbpString(" LF HID ProxII bruteforce - aka Proxbrute (Brad Antoniewicz)"); } // samy's sniff and repeat routine for LF diff --git a/armsrc/Standalone/lf_samyrun.c b/armsrc/Standalone/lf_samyrun.c index 03c2ddd12..07fe8bae5 100644 --- a/armsrc/Standalone/lf_samyrun.c +++ b/armsrc/Standalone/lf_samyrun.c @@ -11,7 +11,7 @@ #include "lf_samyrun.h" void ModInfo(void) { - DbpString(" LF HID26 standalone - aka SamyRun (Samy Kamkar)"); + DbpString(" LF HID26 standalone - aka SamyRun (Samy Kamkar)"); } // samy's sniff and repeat routine for LF diff --git a/armsrc/Standalone/placeholder.c b/armsrc/Standalone/placeholder.c index e179bc876..b8a426e37 100644 --- a/armsrc/Standalone/placeholder.c +++ b/armsrc/Standalone/placeholder.c @@ -2,7 +2,7 @@ #include "apps.h" // debug statements void ModInfo(void) { - DbpString(" No standalone mode present"); + DbpString(" No standalone mode present"); } void RunMod() { diff --git a/armsrc/Standalone/readme.md b/armsrc/Standalone/readme.md index 491490b1b..8d2420def 100644 --- a/armsrc/Standalone/readme.md +++ b/armsrc/Standalone/readme.md @@ -19,7 +19,7 @@ The RunMod function, which is your "main" function when running. You need to ch ```` void ModInfo(void) { - DbpString(" LF good description of your mode - aka FooRun (your name)"); + DbpString(" LF good description of your mode - aka FooRun (your name)"); } void RunMod(void) { @@ -80,7 +80,7 @@ Add your source code files like the following sample in the `armsrc/Makefile` ``` # WITH_STANDALONE_LF_ICERUN ifneq (,$(findstring WITH_STANDALONE_LF_ICERUN,$(APP_CFLAGS))) - SRC_STANDALONE = lf_icerun.c + SRC_STANDALONE = lf_icerun.c endif # WITH_STANDALONE_LF_FOO @@ -95,7 +95,7 @@ This will enable an easy way to detect on client side which standalone mode has ```` void ModInfo(void) { - DbpString(" LF good description of your mode - aka FooRun (your name)"); + DbpString(" LF good description of your mode - aka FooRun (your name)"); } ```` diff --git a/armsrc/appmain.c b/armsrc/appmain.c index ec953f7ca..3213fbe14 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -339,25 +339,25 @@ void SendVersion(void) { if (bootrom_version < &_flash_start || bootrom_version >= &_flash_end) { strcat(VersionString, "bootrom version information appears invalid\n"); } else { - FormatVersionInformation(temp, sizeof(temp), " bootrom: ", bootrom_version); + FormatVersionInformation(temp, sizeof(temp), " bootrom: ", bootrom_version); strncat(VersionString, temp, sizeof(VersionString) - strlen(VersionString) - 1); } - FormatVersionInformation(temp, sizeof(temp), " os: ", &version_information); + FormatVersionInformation(temp, sizeof(temp), " os: ", &version_information); strncat(VersionString, temp, sizeof(VersionString) - strlen(VersionString) - 1); #if defined(__clang__) - strncat(VersionString, " compiled with Clang/LLVM "__VERSION__"\n", sizeof(VersionString) - strlen(VersionString) - 1); + strncat(VersionString, " compiled with Clang/LLVM "__VERSION__"\n", sizeof(VersionString) - strlen(VersionString) - 1); #elif defined(__GNUC__) || defined(__GNUG__) - strncat(VersionString, " compiled with GCC "__VERSION__"\n", sizeof(VersionString) - strlen(VersionString) - 1); + strncat(VersionString, " compiled with GCC "__VERSION__"\n", sizeof(VersionString) - strlen(VersionString) - 1); #endif - strncat(VersionString, "\n [ FPGA ]\n", sizeof(VersionString) - strlen(VersionString) - 1); + strncat(VersionString, "\n [ FPGA ]\n ", sizeof(VersionString) - strlen(VersionString) - 1); for (int i = 0; i < fpga_bitstream_num; i++) { strncat(VersionString, fpga_version_information[i], sizeof(VersionString) - strlen(VersionString) - 1); if (i < fpga_bitstream_num - 1) { - strncat(VersionString, "\n", sizeof(VersionString) - strlen(VersionString) - 1); + strncat(VersionString, "\n ", sizeof(VersionString) - strlen(VersionString) - 1); } } // Send Chip ID and used flash memory From 4100f0dd76d910721f5de2544ac20d4c3ffe4005 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 9 Jul 2019 22:58:28 +0200 Subject: [PATCH 0031/1854] changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 368ec0073..d46c8222b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,11 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Add check if bootloader segment is within bounds (@slurdge) - Add `hf 15 csetuid` - set UID on ISO-15693 Magic tags (@t0m4-null) + - Change: Print help if unknown arg for hitag reader/writer (@ViRb3) + - Fix clock deadlock in hitag sniff (@ViRb3) + - Add compiler info in client & ARM sections (@slurdge) - Add support for automatic COM detection on Windows (@slurdge) - Add support for compilation on RaspberryPiZero (armv6) (@doegox) - Change: updates to README (@iceman) From cb453139813a7b1b5ff17e6bd66d3e80075ead35 Mon Sep 17 00:00:00 2001 From: Victor Date: Tue, 9 Jul 2019 23:00:57 +0100 Subject: [PATCH 0032/1854] Add hitag2 write password auth --- armsrc/hitag2.c | 139 +++++++++++++++++++++++++------------------- client/cmdlfhitag.c | 7 +++ include/hitag.h | 1 + 3 files changed, 88 insertions(+), 59 deletions(-) diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index 2382be273..46e9a43dd 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -331,64 +331,6 @@ size_t blocknr; // Hitag2 operations //----------------------------------------------------------------------------- -static bool hitag2_password(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t *txlen) { - // Reset the transmission frame length - *txlen = 0; - - // Try to find out which command was send by selecting on length (in bits) - switch (rxlen) { - // No answer, try to resurrect - case 0: { - // Stop if there is no answer (after sending password) - if (bPwd) { - DbpString("Password failed!"); - return false; - } - *txlen = 5; - memcpy(tx, "\xC0", nbytes(*txlen)); - } - break; - - // Received UID, tag password - case 32: { - if (!bPwd) { - *txlen = 32; - memcpy(tx, password, 4); - bPwd = true; - memcpy(tag.sectors[blocknr], rx, 4); - blocknr++; - } else { - - if (blocknr == 1) { - //store password in block1, the TAG answers with Block3, but we need the password in memory - memcpy(tag.sectors[blocknr], tx, 4); - } else { - memcpy(tag.sectors[blocknr], rx, 4); - } - - blocknr++; - if (blocknr > 7) { - DbpString("Read succesful!"); - bSuccessful = true; - return false; - } - *txlen = 10; - tx[0] = 0xC0 | (blocknr << 3) | ((blocknr ^ 7) >> 2); - tx[1] = ((blocknr ^ 7) << 6); - } - } - break; - - // Unexpected response - default: { - Dbprintf("Uknown frame length: %d", rxlen); - return false; - } - break; - } - return true; -} - static bool hitag2_write_page(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t *txlen) { switch (writestate) { case WRITE_STATE_START: @@ -431,6 +373,71 @@ static bool hitag2_write_page(uint8_t *rx, const size_t rxlen, uint8_t *tx, size return true; } +static bool hitag2_password(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t *txlen, bool write) { + // Reset the transmission frame length + *txlen = 0; + + if (bPwd && write) { + if (!hitag2_write_page(rx, rxlen, tx, txlen)) { + return false; + } + } else { + // Try to find out which command was send by selecting on length (in bits) + switch (rxlen) { + // No answer, try to resurrect + case 0: { + // Stop if there is no answer (after sending password) + if (bPwd) { + DbpString("Password failed!"); + return false; + } + *txlen = 5; + memcpy(tx, "\xC0", nbytes(*txlen)); + } + break; + + // Received UID, tag password + case 32: { + if (!bPwd) { + *txlen = 32; + memcpy(tx, password, 4); + bPwd = true; + memcpy(tag.sectors[blocknr], rx, 4); + blocknr++; + } else { + + if (blocknr == 1) { + //store password in block1, the TAG answers with Block3, but we need the password in memory + memcpy(tag.sectors[blocknr], tx, 4); + } else { + memcpy(tag.sectors[blocknr], rx, 4); + } + + blocknr++; + if (blocknr > 7) { + DbpString("Read succesful!"); + bSuccessful = true; + return false; + } + *txlen = 10; + tx[0] = 0xC0 | (blocknr << 3) | ((blocknr ^ 7) >> 2); + tx[1] = ((blocknr ^ 7) << 6); + } + } + break; + + // Unexpected response + default: { + Dbprintf("Uknown frame length: %d", rxlen); + return false; + } + break; + } + } + + return true; +} + static bool hitag2_crypto(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t *txlen, bool write) { // Reset the transmission frame length *txlen = 0; @@ -1217,7 +1224,7 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { tx = txbuf; switch (htf) { case RHT2F_PASSWORD: { - bStop = !hitag2_password(rx, rxlen, tx, &txlen); + bStop = !hitag2_password(rx, rxlen, tx, &txlen, false); break; } case RHT2F_AUTHENTICATE: { @@ -1391,6 +1398,16 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) { writestate = WRITE_STATE_START; } break; + case WHT2F_PASSWORD: { + DbpString("Authenticating using password:"); + memcpy(password, htd->pwd.password, 4); + memcpy(writedata, htd->crypto.data, 4); + Dbhexdump(4, password, false); + blocknr = page; + bPwd = false; + writestate = WRITE_STATE_START; + } + break; default: { Dbprintf("Error, unknown function: %d", htf); StartTicks(); @@ -1480,6 +1497,10 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) { bStop = !hitag2_crypto(rx, rxlen, tx, &txlen, true); } break; + case WHT2F_PASSWORD: { + bStop = !hitag2_password(rx, rxlen, tx, &txlen, true); + } + break; default: { Dbprintf("Error, unknown function: %d", htf); return; diff --git a/client/cmdlfhitag.c b/client/cmdlfhitag.c index 27c352c53..47e08eb2e 100644 --- a/client/cmdlfhitag.c +++ b/client/cmdlfhitag.c @@ -106,6 +106,7 @@ static int usage_hitag_writer(void) { PrintAndLogEx(NORMAL, " Hitag1 (1*)"); PrintAndLogEx(NORMAL, " Hitag2 (2*)"); PrintAndLogEx(NORMAL, " 24 (set to 0 if no authentication is needed) write page on a Hitag2 tag"); + PrintAndLogEx(NORMAL, " 27 write page on a Hitag2 tag"); return 0; } static int usage_hitag_checkchallenges(void) { @@ -659,6 +660,12 @@ static int CmdLFHitagWriter(const char *Cmd) { num_to_bytes(param_get32ex(Cmd, 3, 0, 16), 4, htd.crypto.data); break; } + case WHT2F_PASSWORD: { + num_to_bytes(param_get64ex(Cmd, 1, 0, 16), 4, htd.pwd.password); + arg2 = param_get32ex(Cmd, 2, 0, 10); + num_to_bytes(param_get32ex(Cmd, 3, 0, 16), 4, htd.crypto.data); + break; + } case RHTSF_CHALLENGE: case RHTSF_KEY: case RHT2F_PASSWORD: diff --git a/include/hitag.h b/include/hitag.h index 742d7ecd0..f57f1180a 100644 --- a/include/hitag.h +++ b/include/hitag.h @@ -31,6 +31,7 @@ typedef enum { WHT2F_CRYPTO = 24, RHT2F_TEST_AUTH_ATTEMPTS = 25, RHT2F_UID_ONLY = 26, + WHT2F_PASSWORD = 27, } hitag_function; typedef struct { From 16b6d7e5290d8b991dc139b0f4a0a8937b8e3d87 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 10 Jul 2019 19:11:56 +0300 Subject: [PATCH 0033/1854] apdu universal parser --- client/emv/apduinfo.c | 112 ++++++++++++++++++++++++++++++++++++++++++ client/emv/apduinfo.h | 25 ++++++++++ 2 files changed, 137 insertions(+) diff --git a/client/emv/apduinfo.c b/client/emv/apduinfo.c index df44ef961..6deeb618b 100644 --- a/client/emv/apduinfo.c +++ b/client/emv/apduinfo.c @@ -314,3 +314,115 @@ const char *GetAPDUCodeDescription(uint8_t sw1, uint8_t sw2) { else return APDUCodeTable[0].Description; //empty string } + +int apdu_decode(uint8_t *data, size_t len, APDU_STRUCT *apdu) +{ + EXT_APDU_HEADER *hapdu = (EXT_APDU_HEADER *)data; + + apdu->cla = hapdu->cla; + apdu->ins = hapdu->ins; + apdu->p1 = hapdu->p1; + apdu->p2 = hapdu->p2; + + apdu->lc = 0; + apdu->data = NULL; + apdu->le = 0; + apdu->extended_apdu = false; + apdu->case_type = 0x00; + + uint8_t b0 = hapdu->lc[0]; + + // case 1 + if (len == 4) + { + apdu->case_type = 0x01; + } + + // case 2S (Le) + if (len == 5) + { + apdu->case_type = 0x02; + apdu->le = b0; + if (!apdu->le) + apdu->le = 0x100; + } + + // case 3S (Lc + data) + if (len == 5U + b0 && b0 != 0) + { + apdu->case_type = 0x03; + apdu->lc = b0; + } + + // case 4S (Lc + data + Le) + if (len == 5U + b0 + 1U && b0 != 0) + { + apdu->case_type = 0x04; + apdu->lc = b0; + apdu->le = data[len - 1]; + if (!apdu->le) + apdu->le = 0x100; + } + + // extended length apdu + if (len >= 7 && b0 == 0) + { + uint16_t extlen = (hapdu->lc[1] << 8) + hapdu->lc[2]; + + // case 2E (Le) - extended + if (len == 7) + { + apdu->case_type = 0x12; + apdu->extended_apdu = true; + apdu->le = extlen; + if (!apdu->le) + apdu->le = 0x10000; + } + + // case 3E (Lc + data) - extended + if (len == 7U + extlen) + { + apdu->case_type = 0x13; + apdu->extended_apdu = true; + apdu->lc = extlen; + } + + // case 4E (Lc + data + Le) - extended 2-byte Le + if (len == 7U + extlen + 2U) + { + apdu->case_type = 0x14; + apdu->extended_apdu = true; + apdu->lc = extlen; + apdu->le = (data[len - 2] << 8) + data[len - 1]; + if (!apdu->le) + apdu->le = 0x10000; + } + + // case 4E (Lc + data + Le) - extended 3-byte Le + if (len == 7U + extlen + 3U && data[len - 3] == 0) + { + apdu->case_type = 0x24; + apdu->extended_apdu = true; + apdu->lc = extlen; + apdu->le = (data[len - 2] << 8) + data[len - 1]; + if (!apdu->le) + apdu->le = 0x10000; + } + } + + if (!apdu->case_type) + return 1; + + if (apdu->lc) + { + if (apdu->extended_apdu) + { + apdu->data = data + 7; + } else { + apdu->data = data + 5; + } + + } + + return 0; +} diff --git a/client/emv/apduinfo.h b/client/emv/apduinfo.h index 317d661ff..399fd44a1 100644 --- a/client/emv/apduinfo.h +++ b/client/emv/apduinfo.h @@ -14,6 +14,7 @@ #include #include #include +#include #include #define APDUCODE_TYPE_NONE 0 @@ -31,4 +32,28 @@ typedef struct { const APDUCode *GetAPDUCode(uint8_t sw1, uint8_t sw2); const char *GetAPDUCodeDescription(uint8_t sw1, uint8_t sw2); +typedef struct +{ + uint8_t cla; + uint8_t ins; + uint8_t p1; + uint8_t p2; + uint8_t lc[3]; +} __attribute__((packed)) EXT_APDU_HEADER; + +typedef struct +{ + uint8_t cla; + uint8_t ins; + uint8_t p1; + uint8_t p2; + uint16_t lc; + uint8_t *data; + uint32_t le; + bool extended_apdu; + uint8_t case_type; +} __attribute__((packed)) APDU_STRUCT; +extern int apdu_decode(uint8_t *data, size_t len, APDU_STRUCT *apdu); + + #endif From 1169a6cf1b054ce1550f03b5d160bf5adc74ec9b Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 10 Jul 2019 19:21:54 +0300 Subject: [PATCH 0034/1854] apdu rename and print --- client/emv/apduinfo.c | 16 ++++++++++++++-- client/emv/apduinfo.h | 8 +++++--- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/client/emv/apduinfo.c b/client/emv/apduinfo.c index 6deeb618b..8ea69437c 100644 --- a/client/emv/apduinfo.c +++ b/client/emv/apduinfo.c @@ -10,6 +10,8 @@ #include "apduinfo.h" +#include "util.h" + const APDUCode APDUCodeTable[] = { // ID Type Description {"XXXX", APDUCODE_TYPE_NONE, ""}, // blank string @@ -315,9 +317,9 @@ const char *GetAPDUCodeDescription(uint8_t sw1, uint8_t sw2) { return APDUCodeTable[0].Description; //empty string } -int apdu_decode(uint8_t *data, size_t len, APDU_STRUCT *apdu) +int APDUDecode(uint8_t *data, size_t len, APDUStruct *apdu) { - EXT_APDU_HEADER *hapdu = (EXT_APDU_HEADER *)data; + ExtAPDUHeader *hapdu = (ExtAPDUHeader *)data; apdu->cla = hapdu->cla; apdu->ins = hapdu->ins; @@ -426,3 +428,13 @@ int apdu_decode(uint8_t *data, size_t len, APDU_STRUCT *apdu) return 0; } + +int APDUEncode(APDUStruct apdu, uint8_t *data, size_t len) { + + return 0; +} + +void APDUPrint(APDUStruct apdu) { + PrintAndLogEx(INFO, "apdu: %scase=%02x cla=%02x ins=%02x p1=%02x p2=%02x lc=%d le=%d\n", + apdu.extended_apdu ? "[e]":"", apdu.case_type, apdu.cla, apdu.ins, apdu.p1, apdu.p2, apdu.lc, apdu.le); +} diff --git a/client/emv/apduinfo.h b/client/emv/apduinfo.h index 399fd44a1..ba4bf7b13 100644 --- a/client/emv/apduinfo.h +++ b/client/emv/apduinfo.h @@ -39,7 +39,7 @@ typedef struct uint8_t p1; uint8_t p2; uint8_t lc[3]; -} __attribute__((packed)) EXT_APDU_HEADER; +} __attribute__((packed)) ExtAPDUHeader; typedef struct { @@ -52,8 +52,10 @@ typedef struct uint32_t le; bool extended_apdu; uint8_t case_type; -} __attribute__((packed)) APDU_STRUCT; -extern int apdu_decode(uint8_t *data, size_t len, APDU_STRUCT *apdu); +} __attribute__((packed)) APDUStruct; +extern int APDUDecode(uint8_t *data, size_t len, APDUStruct *apdu); +extern int APDUEncode(APDUStruct apdu, uint8_t *data, size_t len); +extern void APDUPrint(APDUStruct apdu); #endif From 563050c8ba161cb375eceac2891dc84a5e646505 Mon Sep 17 00:00:00 2001 From: Gabriele Gristina Date: Wed, 10 Jul 2019 18:43:19 +0200 Subject: [PATCH 0035/1854] Fix compilation under MacOSX --- client/Makefile | 7 ++++++- client/jansson/Makefile | 13 ++++++++++++- client/tinycbor/Makefile | 7 +++++++ common/Makefile.common | 6 ++---- common/mbedtls/Makefile | 7 +++++++ liblua/Makefile | 7 +++++++ 6 files changed, 41 insertions(+), 6 deletions(-) diff --git a/client/Makefile b/client/Makefile index 490716eda..a1109a497 100644 --- a/client/Makefile +++ b/client/Makefile @@ -31,7 +31,12 @@ platform = $(shell uname) VPATH = ../common ../zlib ../uart OBJDIR = obj -LDLIBS = -L/opt/local/lib -L/usr/local/lib -lreadline -lpthread -lm +LDLIBS = +ifneq ($(platform),Darwin) + LDLIBS += -L/opt/local/lib +endif +LDLIBS += -L/usr/local/lib -lreadline -lpthread -lm + # RPi Zero gcc requires -latomic # but MacOSX /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld # doesn't recognize option --as-needed diff --git a/client/jansson/Makefile b/client/jansson/Makefile index 323d26216..1a60613d0 100644 --- a/client/jansson/Makefile +++ b/client/jansson/Makefile @@ -36,15 +36,26 @@ CFILES = $(filter %.c, $(libjansson_la_SOURCES)) CMDOBJS = $(CFILES:%.c=%.o) CLEAN = $(CMDOBJS) +platform = $(shell uname) + CC= gcc -CFLAGS= -O2 -Wall -Wno-unused-variable -Wno-unused-function -Wno-format-truncation +CFLAGS= -O2 -Wall -Wno-unused-variable -Wno-unused-function +ifneq ($(platform),Darwin) +CFLAGS += -Wno-format-truncation +endif + LDFLAGS= $(SYSLDFLAGS) $(libjansson_la_LDFLAGS) LIBS= $(SYSLIBS) $(MYLIBS) DEFAULT_INCLUDES = -I. DEFS = -DHAVE_STDINT_H +ifeq ($(platform),Darwin) +AR= /usr/bin/ar rcs +RANLIB= /usr/bin/ranlib +else AR= ar rcs RANLIB= ranlib +endif RM= rm -f TST= echo diff --git a/client/tinycbor/Makefile b/client/tinycbor/Makefile index 8124196eb..af22846e9 100644 --- a/client/tinycbor/Makefile +++ b/client/tinycbor/Makefile @@ -19,14 +19,21 @@ CFILES = $(filter %.c, $(tinycbor_SOURCES)) CMDOBJS = $(CFILES:%.c=%.o) CLEAN = $(CMDOBJS) +platform = $(shell uname) + CC= gcc CFLAGS= -O2 -Wall -Wno-unused-variable -Wno-unused-function LIBS= $(SYSLIBS) $(MYLIBS) DEFAULT_INCLUDES = -I. -I.. DEFS = -DHAVE_STDINT_H +ifeq ($(platform),Darwin) +AR= /usr/bin/ar rcs +RANLIB= /usr/bin/ranlib +else AR= ar rcs RANLIB= ranlib +endif RM= rm -f TST= echo diff --git a/common/Makefile.common b/common/Makefile.common index 132507547..2ab434562 100644 --- a/common/Makefile.common +++ b/common/Makefile.common @@ -43,15 +43,13 @@ TARFLAGS = -C .. -rvf # amount of shell command line parsing going on. echo "" on # Windows yields literal "", on Linux yields an empty line ifeq ($(shell echo ""),) - -# This is probably a proper system, so we can use uname -UNAME := $(shell uname) DELETE=rm -rf MOVE=mv COPY=cp PATHSEP=/ FLASH_TOOL=client/flasher -DETECTED_OS=$(UNAME) +# This is probably a proper system, so we can use uname +DETECTED_OS=$(platform) else # Assume that we are running on Windows. diff --git a/common/mbedtls/Makefile b/common/mbedtls/Makefile index fa0dff05f..a16b2cfd9 100644 --- a/common/mbedtls/Makefile +++ b/common/mbedtls/Makefile @@ -59,6 +59,8 @@ CFILES = $(filter %.c, $(mbedtls_SOURCES)) CMDOBJS = $(CFILES:%.c=%.o) CLEAN = $(CMDOBJS) +platform = $(shell uname) + CC= gcc CFLAGS= -O2 -Wall -Wno-unused-variable -Wno-unused-function LDFLAGS= $(SYSLDFLAGS) $(mbedtls_LDFLAGS) @@ -66,8 +68,13 @@ LIBS= $(SYSLIBS) $(MYLIBS) DEFAULT_INCLUDES = -I. -I.. DEFS = -DHAVE_STDINT_H +ifeq ($(platform),Darwin) +AR= /usr/bin/ar rcs +RANLIB= /usr/bin/ranlib +else AR= ar rcs RANLIB= ranlib +endif RM= rm -f TST= echo diff --git a/liblua/Makefile b/liblua/Makefile index bf2a4fa3c..2b3d7614f 100644 --- a/liblua/Makefile +++ b/liblua/Makefile @@ -12,13 +12,20 @@ endif # Your platform. See PLATS for possible values. PLAT= none +platform= $(shell uname) + CC= gcc CFLAGS= -O3 -Wall -DLUA_COMPAT_ALL $(SYSCFLAGS) $(MYCFLAGS) LDFLAGS= $(SYSLDFLAGS) $(MYLDFLAGS) LIBS= -lm $(SYSLIBS) $(MYLIBS) +ifeq ($(platform),Darwin) +AR= /usr/bin/ar rc +RANLIB= /usr/bin/ranlib +else AR= ar rc RANLIB= ranlib +endif RM= rm -f SYSCFLAGS= From fa2595a619d15c49639b8641e474426e1d84ee97 Mon Sep 17 00:00:00 2001 From: Gabriele Gristina Date: Wed, 10 Jul 2019 18:46:30 +0200 Subject: [PATCH 0036/1854] Fix Clang warnings --- client/proxguiqt.h | 4 ++-- client/proxmark3.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/client/proxguiqt.h b/client/proxguiqt.h index 458a70058..e50bfe073 100644 --- a/client/proxguiqt.h +++ b/client/proxguiqt.h @@ -97,8 +97,8 @@ class WorkerThread : public QThread { ~WorkerThread(); void run(); private: - char *script_cmds_file = NULL; - char *script_cmd = NULL; + char *script_cmds_file; + char *script_cmd; }; class ProxGuiQT : public QObject { diff --git a/client/proxmark3.c b/client/proxmark3.c index 879b3630b..480f39fa3 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -388,7 +388,7 @@ int main(int argc, char *argv[]) { show_help(false, exec_name); return 1; } - uint32_t tmpspeed = strtoul(argv[i + 1], NULL, 10); + uint64_t tmpspeed = strtoul(argv[i + 1], NULL, 10); if ((tmpspeed == ULONG_MAX) || (tmpspeed == 0)) { PrintAndLogEx(ERR, _RED_("ERROR:") "invalid baudrate: -b " _YELLOW_("%s") "\n", argv[i + 1]); return 1; From 1740d43655a7d90022b0615bceb33b46a87b7c81 Mon Sep 17 00:00:00 2001 From: Gabriele Gristina Date: Wed, 10 Jul 2019 18:48:15 +0200 Subject: [PATCH 0037/1854] Fix EMV bug --- client/emv/cmdemv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c index ca3866805..22fdea153 100644 --- a/client/emv/cmdemv.c +++ b/client/emv/cmdemv.c @@ -287,8 +287,8 @@ static int CmdEMVGPO(const char *Cmd) { PrintAndLogEx(ERR, "Can't create PDOL data."); tlvdb_free(tmp_ext); tlvdb_free(tlvRoot); - if (pdol_data_tlv != &data_tlv); - free(pdol_data_tlv); + if (pdol_data_tlv != &data_tlv) + free(pdol_data_tlv); return PM3_ESOFT; } PrintAndLogEx(INFO, "PDOL data[%d]: %s", pdol_data_tlv_data_len, sprint_hex(pdol_data_tlv_data, pdol_data_tlv_data_len)); From 4727ab96d7b5379aa5d448607596328a400c801a Mon Sep 17 00:00:00 2001 From: slurdge Date: Wed, 10 Jul 2019 18:41:42 +0200 Subject: [PATCH 0038/1854] Dynamic report of the chipID for flashing purposes --- bootrom/bootrom.c | 13 +++++++++++-- client/flash.c | 9 ++++++++- client/flash.h | 2 +- client/flasher.c | 41 ++++++++++++++++++++++++++++++++++++++++- include/pm3_cmd.h | 4 ++++ 5 files changed, 64 insertions(+), 5 deletions(-) diff --git a/bootrom/bootrom.c b/bootrom/bootrom.c index b2811cc6d..e889bb7da 100644 --- a/bootrom/bootrom.c +++ b/bootrom/bootrom.c @@ -122,8 +122,10 @@ void UsbPacketReceived(uint8_t *packet, int len) { switch (c->cmd) { case CMD_DEVICE_INFO: { dont_ack = 1; - arg0 = DEVICE_INFO_FLAG_BOOTROM_PRESENT | DEVICE_INFO_FLAG_CURRENT_MODE_BOOTROM | - DEVICE_INFO_FLAG_UNDERSTANDS_START_FLASH; + arg0 = DEVICE_INFO_FLAG_BOOTROM_PRESENT | + DEVICE_INFO_FLAG_CURRENT_MODE_BOOTROM | + DEVICE_INFO_FLAG_UNDERSTANDS_START_FLASH | + DEVICE_INFO_FLAG_UNDERSTANDS_CHIP_INFO; if (common_area.flags.osimage_present) arg0 |= DEVICE_INFO_FLAG_OSIMAGE_PRESENT; @@ -131,6 +133,13 @@ void UsbPacketReceived(uint8_t *packet, int len) { } break; + case CMD_CHIP_INFO: { + dont_ack = 1; + arg0 = *(AT91C_DBGU_CIDR); + reply_old(CMD_CHIP_INFO, arg0, 0, 0, 0, 0); + } + break; + case CMD_SETUP_WRITE: { /* The temporary write buffer of the embedded flash controller is mapped to the * whole memory region, only the last 8 bits are decoded. diff --git a/client/flash.c b/client/flash.c index d8ac983e7..3a1350c7c 100644 --- a/client/flash.c +++ b/client/flash.c @@ -347,7 +347,7 @@ static int wait_for_ack(PacketResponseNG *ack) { } // Go into flashing mode -int flash_start_flashing(int enable_bl_writes, char *serial_port_name) { +int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t * chipinfo) { uint32_t state; if (enter_bootloader(serial_port_name) < 0) @@ -356,6 +356,13 @@ int flash_start_flashing(int enable_bl_writes, char *serial_port_name) { if (get_proxmark_state(&state) < 0) return -1; + if (state & DEVICE_INFO_FLAG_UNDERSTANDS_CHIP_INFO) { + SendCommandBL(CMD_CHIP_INFO, 0, 0, 0, NULL, 0); + PacketResponseNG resp; + WaitForResponse(CMD_CHIP_INFO, &resp); + *chipinfo = resp.oldarg[0]; + } + if (state & DEVICE_INFO_FLAG_UNDERSTANDS_START_FLASH) { // This command is stupid. Why the heck does it care which area we're // flashing, as long as it's not the bootloader area? The mind boggles. diff --git a/client/flash.h b/client/flash.h index a230715d1..7140de673 100644 --- a/client/flash.h +++ b/client/flash.h @@ -38,7 +38,7 @@ typedef struct { } flash_file_t; int flash_load(flash_file_t *ctx, const char *name, int can_write_bl); -int flash_start_flashing(int enable_bl_writes, char *serial_port_name); +int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t *chipid); int flash_write(flash_file_t *ctx); void flash_free(flash_file_t *ctx); int flash_stop_flashing(void); diff --git a/client/flasher.c b/client/flasher.c index 88c154605..675f123e8 100644 --- a/client/flasher.c +++ b/client/flasher.c @@ -35,6 +35,42 @@ static void usage(char *argv0) { #endif } +int chipid_to_mem_avail(uint32_t iChipID) { + int mem_avail = 0; + switch ((iChipID & 0xF00) >> 8) { + case 0: + mem_avail = 0; + break; + case 1: + mem_avail = 8; + break; + case 2: + mem_avail = 16; + break; + case 3: + mem_avail = 32; + break; + case 5: + mem_avail = 64; + break; + case 7: + mem_avail = 128; + break; + case 9: + mem_avail = 256; + break; + case 10: + mem_avail = 512; + break; + case 12: + mem_avail = 1024; + break; + case 14: + mem_avail = 2048; + } + return mem_avail; +} + int main(int argc, char **argv) { int can_write_bl = 0; int num_files = 0; @@ -84,10 +120,13 @@ int main(int argc, char **argv) { return -1; } - res = flash_start_flashing(can_write_bl, serial_port_name); + uint32_t chipid = 0; + res = flash_start_flashing(can_write_bl, serial_port_name, &chipid); if (res < 0) return -1; + PrintAndLogEx(NORMAL, "Available memory on this board: 0x%08x\n", chipid_to_mem_avail(chipid)); + PrintAndLogEx(SUCCESS, "\n" _BLUE_("Flashing...")); for (int i = 0; i < num_files; i++) { diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 772ec02b9..cd129d3fc 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -216,6 +216,7 @@ typedef struct { #define CMD_FINISH_WRITE 0x0003 #define CMD_HARDWARE_RESET 0x0004 #define CMD_START_FLASH 0x0005 +#define CMD_CHIP_INFO 0x0006 #define CMD_NACK 0x00fe #define CMD_ACK 0x00ff @@ -541,6 +542,9 @@ typedef struct { /* Set if this device understands the extend start flash command */ #define DEVICE_INFO_FLAG_UNDERSTANDS_START_FLASH (1<<4) +/* Set if this device understands the extend start flash command */ +#define DEVICE_INFO_FLAG_UNDERSTANDS_CHIP_INFO (1<<5) + /* CMD_START_FLASH may have three arguments: start of area to flash, end of area to flash, optional magic. The bootrom will not allow to overwrite itself unless this magic From 99d2ed224a2817fb5c6f7fe90606c82d746aeaee Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 10 Jul 2019 21:49:14 +0200 Subject: [PATCH 0039/1854] Minor changes on bootloader chip info --- client/flasher.c | 12 +++++++++--- include/pm3_cmd.h | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/client/flasher.c b/client/flasher.c index 675f123e8..94e2ef6ba 100644 --- a/client/flasher.c +++ b/client/flasher.c @@ -125,10 +125,16 @@ int main(int argc, char **argv) { if (res < 0) return -1; - PrintAndLogEx(NORMAL, "Available memory on this board: 0x%08x\n", chipid_to_mem_avail(chipid)); - + int mem_avail = chipid_to_mem_avail(chipid); + if (mem_avail != 0) { + PrintAndLogEx(NORMAL, "Available memory on this board: %uK bytes\n", mem_avail); + } else { + PrintAndLogEx(NORMAL, "Available memory on this board: "_RED_("UNKNOWN")"\n"); + PrintAndLogEx(ERR, _RED_("Note: Your bootloader does not understand the new CHIP_INFO command")); + PrintAndLogEx(ERR, _RED_("It is recommended that you update your bootloader") "\n"); + } PrintAndLogEx(SUCCESS, "\n" _BLUE_("Flashing...")); - +// TODO check if enough space on Pm3 mem to write the given files for (int i = 0; i < num_files; i++) { res = flash_write(&files[i]); if (res < 0) diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index cd129d3fc..8eef7e75d 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -542,7 +542,7 @@ typedef struct { /* Set if this device understands the extend start flash command */ #define DEVICE_INFO_FLAG_UNDERSTANDS_START_FLASH (1<<4) -/* Set if this device understands the extend start flash command */ +/* Set if this device understands the chip info command */ #define DEVICE_INFO_FLAG_UNDERSTANDS_CHIP_INFO (1<<5) /* CMD_START_FLASH may have three arguments: start of area to flash, From 73bbb2e9e8d16df071fc923a1d311fbe35ca6f73 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 10 Jul 2019 22:32:55 +0200 Subject: [PATCH 0040/1854] Silent properly GCC format-truncation warnings in jansson --- client/jansson/Makefile | 3 --- client/jansson/load.c | 12 ++++++++++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/client/jansson/Makefile b/client/jansson/Makefile index 1a60613d0..e06ffbc76 100644 --- a/client/jansson/Makefile +++ b/client/jansson/Makefile @@ -40,9 +40,6 @@ platform = $(shell uname) CC= gcc CFLAGS= -O2 -Wall -Wno-unused-variable -Wno-unused-function -ifneq ($(platform),Darwin) -CFLAGS += -Wno-format-truncation -endif LDFLAGS= $(SYSLDFLAGS) $(libjansson_la_LDFLAGS) LIBS= $(SYSLIBS) $(MYLIBS) diff --git a/client/jansson/load.c b/client/jansson/load.c index 43e035cb2..4e05dc87b 100644 --- a/client/jansson/load.c +++ b/client/jansson/load.c @@ -111,7 +111,11 @@ static void error_set(json_error_t *error, const lex_t *lex, if (saved_text && saved_text[0]) { if (lex->saved_text.length <= 20) { - snprintf(msg_with_context, JSON_ERROR_TEXT_LENGTH, "%s near '%s'", msg_text, saved_text); + int ret = snprintf(msg_with_context, JSON_ERROR_TEXT_LENGTH, "%s near '%s'", msg_text, saved_text); + if (ret < 0) { + jsonp_error_set(error, line, col, pos, code, "%s", "internal snprint error"); + return; + } msg_with_context[JSON_ERROR_TEXT_LENGTH - 1] = '\0'; result = msg_with_context; } @@ -124,7 +128,11 @@ static void error_set(json_error_t *error, const lex_t *lex, /* No context for UTF-8 decoding errors */ result = msg_text; } else { - snprintf(msg_with_context, JSON_ERROR_TEXT_LENGTH, "%s near end of file", msg_text); + int ret = snprintf(msg_with_context, JSON_ERROR_TEXT_LENGTH, "%s near end of file", msg_text); + if (ret < 0) { + jsonp_error_set(error, line, col, pos, code, "%s", "internal snprint error"); + return; + } msg_with_context[JSON_ERROR_TEXT_LENGTH - 1] = '\0'; result = msg_with_context; } From 4bd15d900bdd7bdd578fbf397b2c88f41e5df74c Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 10 Jul 2019 22:35:29 +0200 Subject: [PATCH 0041/1854] jtag tools: some factorisation --- tools/jtag_openocd/general.cfg | 3 +++ tools/jtag_openocd/interface-armusbocd.cfg | 4 ---- tools/jtag_openocd/interface-busblaster.cfg | 4 ---- tools/jtag_openocd/interface-buspirate.cfg | 4 ---- tools/jtag_openocd/interface-jlink.cfg | 4 ---- tools/jtag_openocd/interface-jtagkey.cfg | 4 ---- tools/jtag_openocd/interface-shikra.cfg | 4 ---- tools/jtag_openocd/interface-wiggler.cfg | 3 --- tools/jtag_openocd/openocd_configuration.sample | 7 +++++++ tools/jtag_openocd/openocd_flash_dump.sh | 9 +++++++++ tools/jtag_openocd/openocd_flash_recovery.sh | 7 ++----- tools/jtag_openocd/openocd_interactive.sh | 8 ++++++++ 12 files changed, 29 insertions(+), 32 deletions(-) create mode 100644 tools/jtag_openocd/general.cfg create mode 100644 tools/jtag_openocd/openocd_configuration.sample create mode 100755 tools/jtag_openocd/openocd_flash_dump.sh create mode 100755 tools/jtag_openocd/openocd_interactive.sh diff --git a/tools/jtag_openocd/general.cfg b/tools/jtag_openocd/general.cfg new file mode 100644 index 000000000..6151d82bc --- /dev/null +++ b/tools/jtag_openocd/general.cfg @@ -0,0 +1,3 @@ +# Ports +telnet_port 4444 +gdb_port 3333 diff --git a/tools/jtag_openocd/interface-armusbocd.cfg b/tools/jtag_openocd/interface-armusbocd.cfg index e4689e21b..4820136f0 100644 --- a/tools/jtag_openocd/interface-armusbocd.cfg +++ b/tools/jtag_openocd/interface-armusbocd.cfg @@ -1,7 +1,3 @@ -# Ports -telnet_port 4444 -gdb_port 3333 - # Commands specific to the Olimex ARM-USB-OCD Dongle interface ft2232 ft2232_device_desc "Olimex OpenOCD JTAG" diff --git a/tools/jtag_openocd/interface-busblaster.cfg b/tools/jtag_openocd/interface-busblaster.cfg index 337e9a2de..bd1df2c5f 100644 --- a/tools/jtag_openocd/interface-busblaster.cfg +++ b/tools/jtag_openocd/interface-busblaster.cfg @@ -1,7 +1,3 @@ -# Ports -telnet_port 4444 -gdb_port 3333 - # Commands specific to the Bus Blaster interface ftdi ftdi_device_desc "Dual RS232-HS" diff --git a/tools/jtag_openocd/interface-buspirate.cfg b/tools/jtag_openocd/interface-buspirate.cfg index 4ed5b88a5..8eccadd79 100644 --- a/tools/jtag_openocd/interface-buspirate.cfg +++ b/tools/jtag_openocd/interface-buspirate.cfg @@ -1,7 +1,3 @@ -# Ports -telnet_port 4444 -gdb_port 3333 - # Commands specific to the BusPirate interface buspirate buspirate_port /dev/ttyUSB0 diff --git a/tools/jtag_openocd/interface-jlink.cfg b/tools/jtag_openocd/interface-jlink.cfg index 56a04fef2..011cb7844 100644 --- a/tools/jtag_openocd/interface-jlink.cfg +++ b/tools/jtag_openocd/interface-jlink.cfg @@ -1,7 +1,3 @@ -# Ports -telnet_port 4444 -gdb_port 3333 - # Commands specific to the Segger J-Link interface jlink transport select jtag diff --git a/tools/jtag_openocd/interface-jtagkey.cfg b/tools/jtag_openocd/interface-jtagkey.cfg index 3e48c08df..420e6e97e 100644 --- a/tools/jtag_openocd/interface-jtagkey.cfg +++ b/tools/jtag_openocd/interface-jtagkey.cfg @@ -1,7 +1,3 @@ -# Ports -telnet_port 4444 -gdb_port 3333 - # Commands specific to the Amontec JTAGKey interface ft2232 ft2232_device_desc "Amontec JTAGkey A" diff --git a/tools/jtag_openocd/interface-shikra.cfg b/tools/jtag_openocd/interface-shikra.cfg index 507c301b4..ba4b21419 100644 --- a/tools/jtag_openocd/interface-shikra.cfg +++ b/tools/jtag_openocd/interface-shikra.cfg @@ -1,7 +1,3 @@ -# Ports -telnet_port 4444 -gdb_port 3333 - # Commands specific to the Shikra interface ftdi transport select jtag diff --git a/tools/jtag_openocd/interface-wiggler.cfg b/tools/jtag_openocd/interface-wiggler.cfg index 88448de82..ce9a1da06 100644 --- a/tools/jtag_openocd/interface-wiggler.cfg +++ b/tools/jtag_openocd/interface-wiggler.cfg @@ -1,6 +1,3 @@ -telnet_port 4444 -gdb_port 3333 - # Commands specific to the Wiggler interface parport parport_port 0x378 diff --git a/tools/jtag_openocd/openocd_configuration.sample b/tools/jtag_openocd/openocd_configuration.sample new file mode 100644 index 000000000..466e28d9b --- /dev/null +++ b/tools/jtag_openocd/openocd_configuration.sample @@ -0,0 +1,7 @@ +CONFIG_GEN=general.cfg +CONFIG_CHIP=chip-at91sam7s.cfg +IMAGE=../../recovery/proxmark3_recovery.bin +DUMP="dump_$(date +'%Y%m%d-%H%M%S').bin" + +# Example using Segger Jlink: +CONFIG_IF=interface-jlink.cfg diff --git a/tools/jtag_openocd/openocd_flash_dump.sh b/tools/jtag_openocd/openocd_flash_dump.sh new file mode 100755 index 000000000..497847dd1 --- /dev/null +++ b/tools/jtag_openocd/openocd_flash_dump.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +. openocd_configuration || exit 1 + +if [ -e "$DUMP" ]; then + echo "$DUMP exists already. Abort!" + exit 1 +fi +openocd -f $CONFIG_GEN -f $CONFIG_IF -f $CONFIG_CHIP -c "init;halt;dump_image $DUMP 0x100000 0x80000;exit" diff --git a/tools/jtag_openocd/openocd_flash_recovery.sh b/tools/jtag_openocd/openocd_flash_recovery.sh index b51076d5a..2e88c52e6 100755 --- a/tools/jtag_openocd/openocd_flash_recovery.sh +++ b/tools/jtag_openocd/openocd_flash_recovery.sh @@ -1,12 +1,9 @@ #!/bin/bash -# Example using Segger Jlink: -CONFIG_CHIP=chip-at91sam7s.cfg -CONFIG_IF=interface-jlink.cfg -IMAGE=../../recovery/proxmark3_recovery.bin +. openocd_configuration || exit 1 if [ ! -e "$IMAGE" ]; then echo "$IMAGE missing. Abort!" exit 1 fi -openocd -f $CONFIG_IF -f $CONFIG_CHIP -c "init;halt;flash erase_sector 0 0 15;flash erase_sector 1 0 15;flash write_image $IMAGE 0x100000;exit" +openocd -f $CONFIG_GEN -f $CONFIG_IF -f $CONFIG_CHIP -c "init;halt;flash erase_sector 0 0 15;flash erase_sector 1 0 15;flash write_image $IMAGE 0x100000;exit" diff --git a/tools/jtag_openocd/openocd_interactive.sh b/tools/jtag_openocd/openocd_interactive.sh new file mode 100755 index 000000000..ea7919da8 --- /dev/null +++ b/tools/jtag_openocd/openocd_interactive.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +. openocd_configuration || exit 1 + +echo "*********************************************" +echo "Connect to OpenOCD via: telnet localhost $(awk '/^telnet_port/{print$2}' $CONFIG_GEN)" +echo "*********************************************" +openocd -f $CONFIG_GEN -f $CONFIG_IF -f $CONFIG_CHIP From 1ae85d20d74f06fc4d8ccfe5df5745ae8e50d929 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 10 Jul 2019 22:37:30 +0200 Subject: [PATCH 0042/1854] jtag tools: add config for FTDI C232HM-DDHSL-0 --- tools/jtag_openocd/interface-c232hm.cfg | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 tools/jtag_openocd/interface-c232hm.cfg diff --git a/tools/jtag_openocd/interface-c232hm.cfg b/tools/jtag_openocd/interface-c232hm.cfg new file mode 100644 index 000000000..f4d0f471a --- /dev/null +++ b/tools/jtag_openocd/interface-c232hm.cfg @@ -0,0 +1,23 @@ +# Commands specific to the FTDI USB Hi-Speed to MPSSE Cable +# http://www.ftdichip.com/Products/Cables/USBMPSSE.htm +# C232HM-DDHSL-0 => 3.3V +# C232HM-EDSL-0 => 5V !! don't apply 5V on the 3.3v pm3 pin !! + +# Pinouts: +# Brown <> TMS +# Yellow <> TDI +# Green <> TDO +# Orange <> TCK +# Black <> GND +# Red <> 3.3 (don't connect if C232HM-EDSL-0! power via USB instead) + +interface ftdi +#ftdi_device_desc "C232HM-DDHSL-0" +#ftdi_device_desc "C232HM-EDHSL-0" +ftdi_vid_pid 0x0403 0x6014 + +ftdi_layout_init 0x0008 0x400b +ftdi_layout_signal LED -ndata 0x4000 + +transport select jtag +adapter_khz 1000 From fd5c30f555012d8e93621e86d6eb918359532529 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 10 Jul 2019 22:51:42 +0200 Subject: [PATCH 0043/1854] jtag tools: add config for RaspberryPi --- tools/jtag_openocd/interface-raspberrypi.cfg | 37 +++++++++++++++++++ tools/jtag_openocd/interface-raspberrypi2.cfg | 37 +++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 tools/jtag_openocd/interface-raspberrypi.cfg create mode 100644 tools/jtag_openocd/interface-raspberrypi2.cfg diff --git a/tools/jtag_openocd/interface-raspberrypi.cfg b/tools/jtag_openocd/interface-raspberrypi.cfg new file mode 100644 index 000000000..984afe41b --- /dev/null +++ b/tools/jtag_openocd/interface-raspberrypi.cfg @@ -0,0 +1,37 @@ +# Config for using Raspberry Pi's expansion header +# Using BCM2835 chip present in models Pi1, Pi2 and Pi Zero + +# Use short cables! +# Make sure the CPU is not busy with other processes! +# Connect pm3 before booting to avoid power loss & reboot problems +# Pinouts: +# 22 <> TMS +# 19 <> TDI +# 21 <> TDO +# 23 <> TCK +# 6 <> GND +# 1 <> 3.3 + +interface bcm2835gpio + +# This file is meant for first versions of Raspberry Pi +# You can check yours with: +# dd if=/proc/device-tree/soc/ranges bs=4 skip=1 count=1 2>/dev/null|xxd -p +# if it returns 20000000, you're fine +# if it returns 3F000000, use interface-raspberrypi2.cfg +bcm2835gpio_peripheral_base 0x20000000 + +# Transition delay calculation: SPEED_COEFF/khz - SPEED_OFFSET +# These depend on system clock, calibrated for stock 700MHz +# bcm2835gpio_speed SPEED_COEFF SPEED_OFFSET +bcm2835gpio_speed_coeffs 113714 28 + +# Each of the JTAG lines need a gpio number set: tck tms tdi tdo +# Header pin numbers: 23 22 19 21 +bcm2835gpio_jtag_nums 11 25 10 9 + +bcm2835gpio_srst_num 18 +reset_config srst_only srst_push_pull + +transport select jtag +adapter_khz 1000 diff --git a/tools/jtag_openocd/interface-raspberrypi2.cfg b/tools/jtag_openocd/interface-raspberrypi2.cfg new file mode 100644 index 000000000..b779cd290 --- /dev/null +++ b/tools/jtag_openocd/interface-raspberrypi2.cfg @@ -0,0 +1,37 @@ +# Config for using Raspberry Pi's expansion header +# Using BCM2835 chip present in models 2+ and above + +# Use short cables! +# Make sure the CPU is not busy with other processes! +# Connect pm3 before booting to avoid power loss & reboot problems +# Pinouts: +# 22 <> TMS +# 19 <> TDI +# 21 <> TDO +# 23 <> TCK +# 6 <> GND +# 1 <> 3.3 + +interface bcm2835gpio + +# This file is meant for recent versions of Raspberry Pi +# You can check yours with: +# dd if=/proc/device-tree/soc/ranges bs=4 skip=1 count=1 2>/dev/null|xxd -p +# if it returns 20000000, use interface-raspberrypi2.cfg +# if it returns 3F000000, you're fine +bcm2835gpio_peripheral_base 0x3F000000 + +# Transition delay calculation: SPEED_COEFF/khz - SPEED_OFFSET +# These depend on system clock, calibrated for stock 700MHz +# bcm2835gpio_speed SPEED_COEFF SPEED_OFFSET +bcm2835gpio_speed_coeffs 146203 36 + +# Each of the JTAG lines need a gpio number set: tck tms tdi tdo +# Header pin numbers: 23 22 19 21 +bcm2835gpio_jtag_nums 11 25 10 9 + +bcm2835gpio_srst_num 18 +reset_config srst_only srst_push_pull + +transport select jtag +adapter_khz 1000 From 6f457873ccac8c47c5d797367bad17b6f4f0417b Mon Sep 17 00:00:00 2001 From: 3ldidi94 Date: Thu, 11 Jul 2019 10:37:00 +0200 Subject: [PATCH 0044/1854] Update default_keys.dic with keys from an APK Update the dic with keys from Android application "Scan Badge". I did the diff between keys already present and keys from the application. --- client/default_keys.dic | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/client/default_keys.dic b/client/default_keys.dic index 13e289e0c..4810e56da 100644 --- a/client/default_keys.dic +++ b/client/default_keys.dic @@ -930,3 +930,17 @@ BB3D7B11D224 b210cfa436d2 b8b1cfa646a8 a9f95891f0a4 +# +# Keys from APK application "Scan Badge" +4A4C474F524D +444156494442 +434143445649 +434456495243 +A00002000021 +EF61A3D48E2A +A23456789123 +010000000000 +363119000001 +A00003000084 +675A32413770 +395244733978 From 4d8a4114136caee23de826b3e046aef741a187bb Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Thu, 11 Jul 2019 13:08:43 +0300 Subject: [PATCH 0045/1854] APDUEncode --- client/emv/apduinfo.c | 69 +++++++++++++++++++++++++++---------------- client/emv/apduinfo.h | 2 +- 2 files changed, 45 insertions(+), 26 deletions(-) diff --git a/client/emv/apduinfo.c b/client/emv/apduinfo.c index 8ea69437c..79b502816 100644 --- a/client/emv/apduinfo.c +++ b/client/emv/apduinfo.c @@ -317,8 +317,7 @@ const char *GetAPDUCodeDescription(uint8_t sw1, uint8_t sw2) { return APDUCodeTable[0].Description; //empty string } -int APDUDecode(uint8_t *data, size_t len, APDUStruct *apdu) -{ +int APDUDecode(uint8_t *data, size_t len, APDUStruct *apdu) { ExtAPDUHeader *hapdu = (ExtAPDUHeader *)data; apdu->cla = hapdu->cla; @@ -335,14 +334,12 @@ int APDUDecode(uint8_t *data, size_t len, APDUStruct *apdu) uint8_t b0 = hapdu->lc[0]; // case 1 - if (len == 4) - { + if (len == 4) { apdu->case_type = 0x01; } // case 2S (Le) - if (len == 5) - { + if (len == 5) { apdu->case_type = 0x02; apdu->le = b0; if (!apdu->le) @@ -350,15 +347,13 @@ int APDUDecode(uint8_t *data, size_t len, APDUStruct *apdu) } // case 3S (Lc + data) - if (len == 5U + b0 && b0 != 0) - { + if (len == 5U + b0 && b0 != 0) { apdu->case_type = 0x03; apdu->lc = b0; } // case 4S (Lc + data + Le) - if (len == 5U + b0 + 1U && b0 != 0) - { + if (len == 5U + b0 + 1U && b0 != 0) { apdu->case_type = 0x04; apdu->lc = b0; apdu->le = data[len - 1]; @@ -367,13 +362,11 @@ int APDUDecode(uint8_t *data, size_t len, APDUStruct *apdu) } // extended length apdu - if (len >= 7 && b0 == 0) - { + if (len >= 7 && b0 == 0) { uint16_t extlen = (hapdu->lc[1] << 8) + hapdu->lc[2]; // case 2E (Le) - extended - if (len == 7) - { + if (len == 7) { apdu->case_type = 0x12; apdu->extended_apdu = true; apdu->le = extlen; @@ -382,16 +375,14 @@ int APDUDecode(uint8_t *data, size_t len, APDUStruct *apdu) } // case 3E (Lc + data) - extended - if (len == 7U + extlen) - { + if (len == 7U + extlen) { apdu->case_type = 0x13; apdu->extended_apdu = true; apdu->lc = extlen; } // case 4E (Lc + data + Le) - extended 2-byte Le - if (len == 7U + extlen + 2U) - { + if (len == 7U + extlen + 2U) { apdu->case_type = 0x14; apdu->extended_apdu = true; apdu->lc = extlen; @@ -401,8 +392,7 @@ int APDUDecode(uint8_t *data, size_t len, APDUStruct *apdu) } // case 4E (Lc + data + Le) - extended 3-byte Le - if (len == 7U + extlen + 3U && data[len - 3] == 0) - { + if (len == 7U + extlen + 3U && data[len - 3] == 0) { apdu->case_type = 0x24; apdu->extended_apdu = true; apdu->lc = extlen; @@ -415,10 +405,8 @@ int APDUDecode(uint8_t *data, size_t len, APDUStruct *apdu) if (!apdu->case_type) return 1; - if (apdu->lc) - { - if (apdu->extended_apdu) - { + if (apdu->lc) { + if (apdu->extended_apdu) { apdu->data = data + 7; } else { apdu->data = data + 5; @@ -429,8 +417,39 @@ int APDUDecode(uint8_t *data, size_t len, APDUStruct *apdu) return 0; } -int APDUEncode(APDUStruct apdu, uint8_t *data, size_t len) { +int APDUEncode(APDUStruct *apdu, uint8_t *data, size_t *len) { + size_t dptr = 0; + data[dptr++] = apdu->cla; + data[dptr++] = apdu->ins; + data[dptr++] = apdu->p1; + data[dptr++] = apdu->p2; + if (apdu->lc) { + if (apdu->extended_apdu || apdu->lc > 0xff || apdu->le > 0xff) { + data[dptr++] = 0x00; + data[dptr++] = (apdu->lc >> 8) & 0xff; + data[dptr++] = (apdu->lc) & 0xff; + memmove(&data[dptr], apdu->data, apdu->lc); + dptr += apdu->lc; + apdu->extended_apdu = true; + } else { + data[dptr++] = apdu->lc; + memmove(&data[dptr], apdu->data, apdu->lc); + dptr += apdu->lc; + } + } + + if (apdu->le) { + if (apdu->extended_apdu) { + data[dptr++] = 0x00; + data[dptr++] = (apdu->le >> 8) & 0xff; + data[dptr++] = (apdu->le) & 0xff; + } else { + data[dptr++] = apdu->le; + } + } + + *len = dptr; return 0; } diff --git a/client/emv/apduinfo.h b/client/emv/apduinfo.h index ba4bf7b13..e510492cf 100644 --- a/client/emv/apduinfo.h +++ b/client/emv/apduinfo.h @@ -55,7 +55,7 @@ typedef struct } __attribute__((packed)) APDUStruct; extern int APDUDecode(uint8_t *data, size_t len, APDUStruct *apdu); -extern int APDUEncode(APDUStruct apdu, uint8_t *data, size_t len); +extern int APDUEncode(APDUStruct *apdu, uint8_t *data, size_t *len); extern void APDUPrint(APDUStruct apdu); #endif From 844d732297d12f52fb43a3ac0696420605aa9af2 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 11 Jul 2019 13:01:34 +0200 Subject: [PATCH 0046/1854] Replace ukbhit by kbd_enter_pressed, not requiring tcgetattr: Note that it behaves differently now * it looks for Enter key only, not any key * it "eats" the input, no need for (void)getchar() after it * it works the same no matter the value of ICANON * the mingw version has been adapted to act the similarly This should fix its usage on Android where tcgetattr always returns -1 --- client/cmdanalyse.c | 3 +- client/cmdhf.c | 8 ++--- client/cmdhf14a.c | 6 ++-- client/cmdhffelica.c | 6 ++-- client/cmdhficlass.c | 24 +++++-------- client/cmdhfmf.c | 24 +++++-------- client/cmdlfawid.c | 6 ++-- client/cmdlfem4x.c | 8 ++--- client/cmdlfhid.c | 4 +-- client/cmdlft55xx.c | 4 +-- client/cmdsmartcard.c | 4 +-- client/cmdusart.c | 11 +++--- client/lualibs/hf_reader.lua | 4 +-- client/lualibs/read14a.lua | 4 +-- client/lualibs/read14b.lua | 4 +-- client/lualibs/read15.lua | 4 +-- client/mifare/mifarehost.c | 12 ++----- client/scripting.c | 6 ++-- client/scripts/didump.lua | 2 +- client/scripts/formatMifare.lua | 2 +- client/scripts/lf_bulk.lua | 2 +- client/scripts/mfkeys.lua | 2 +- client/scripts/mifare_autopwn.lua | 4 +-- client/scripts/tnp3dump.lua | 2 +- client/scripts/tracetest.lua | 2 +- client/util.c | 56 ++++++++++++++++++------------- client/util.h | 2 +- 27 files changed, 90 insertions(+), 126 deletions(-) diff --git a/client/cmdanalyse.c b/client/cmdanalyse.c index 1eee47c78..0821cc4d1 100644 --- a/client/cmdanalyse.c +++ b/client/cmdanalyse.c @@ -623,8 +623,7 @@ static int CmdAnalyseA(const char *Cmd) { for (uint8_t k=0; k<4; k = (k+1) % 4 ) { PrintAndLogEx(NORMAL, "\e[s%c\e[u", star[k]); fflush(stdout); - if (ukbhit()) { - int gc = getchar(); (void)gc; + if (kbd_enter_pressed()) { break; } } diff --git a/client/cmdhf.c b/client/cmdhf.c index 7e42202a9..03a5c1681 100644 --- a/client/cmdhf.c +++ b/client/cmdhf.c @@ -40,7 +40,7 @@ static int usage_hf_sniff() { static int usage_hf_tune() { PrintAndLogEx(NORMAL, "Usage: hf tune []"); PrintAndLogEx(NORMAL, "Continuously measure HF antenna tuning."); - PrintAndLogEx(NORMAL, "Press button or keyboard to interrupt."); + PrintAndLogEx(NORMAL, "Press button or Enter to interrupt."); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " - number of iterations (default: infinite)"); PrintAndLogEx(NORMAL, ""); @@ -98,7 +98,7 @@ int CmdHFTune(const char *Cmd) { int iter = param_get32ex(Cmd, 0, 0, 10); PacketResponseNG resp; - PrintAndLogEx(SUCCESS, "Measuring HF antenna, click button or press a key to exit"); + PrintAndLogEx(SUCCESS, "Measuring HF antenna, click button or press Enter to exit"); clearCommandBuffer(); uint8_t mode[] = {1}; SendCommandNG(CMD_MEASURE_ANTENNA_TUNING_HF, mode, sizeof(mode)); @@ -109,9 +109,7 @@ int CmdHFTune(const char *Cmd) { mode[0] = 2; // loop forever (till button pressed) if iter = 0 (default) for (uint8_t i = 0; iter == 0 || i < iter; i++) { - if (ukbhit()) { // abort by keyboard press - int gc = getchar(); - (void)gc; + if (kbd_enter_pressed()) { // abort by keyboard press break; } SendCommandNG(CMD_MEASURE_ANTENNA_TUNING_HF, mode, sizeof(mode)); diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index 018431a28..bb5144f0b 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -375,9 +375,7 @@ static int CmdHF14ACUIDs(const char *Cmd) { // repeat n times for (int i = 0; i < n; i++) { - if (ukbhit()) { - int gc = getchar(); - (void)gc; + if (kbd_enter_pressed()) { PrintAndLogEx(WARNING, "\n[!] aborted via keyboard!\n"); break; } @@ -489,7 +487,7 @@ int CmdHF14ASim(const char *Cmd) { PrintAndLogEx(SUCCESS, "press pm3-button to abort simulation"); - while (!ukbhit()) { + while (!kbd_enter_pressed()) { if (WaitForResponseTimeout(CMD_SIMULATE_MIFARE_CARD, &resp, 1500) == 0) continue; if (resp.status != PM3_SUCCESS) break; diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index 6f3e28737..91d171149 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -135,7 +135,7 @@ static int CmdHFFelicaSim(const char *Cmd) { if (verbose) PrintAndLogEx(NORMAL, "Press pm3-button to abort simulation"); - while (!ukbhit()) { + while (!kbd_enter_pressed()) { if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) continue; } return 0; @@ -357,9 +357,7 @@ static int CmdHFFelicaDumpLite(const char *Cmd) { timeout++; printf("."); fflush(stdout); - if (ukbhit()) { - int gc = getchar(); - (void)gc; + if (kbd_enter_pressed()) { PrintAndLogEx(WARNING, "\n[!] aborted via keyboard!\n"); DropField(); return 1; diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 2bdb91fa1..ec2179ab3 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -176,7 +176,7 @@ static int usage_hf_iclass_managekeys(void) { return 0; } static int usage_hf_iclass_reader(void) { - PrintAndLogEx(NORMAL, "Act as a Iclass reader. Look for iClass tags until a key or the pm3 button is pressed\n"); + PrintAndLogEx(NORMAL, "Act as a Iclass reader. Look for iClass tags until Enter or the pm3 button is pressed\n"); PrintAndLogEx(NORMAL, "Usage: hf iclass reader [h] [1]\n"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h This help text"); @@ -376,16 +376,14 @@ static int CmdHFiClassSim(const char *Cmd) { case 2: { PrintAndLogEx(INFO, "Starting iCLASS sim 2 attack (elite mode)"); - PrintAndLogEx(INFO, "press keyboard to cancel"); + PrintAndLogEx(INFO, "press Enter to cancel"); PacketResponseNG resp; clearCommandBuffer(); SendCommandOLD(CMD_SIMULATE_TAG_ICLASS, simType, NUM_CSNS, 0, csns, 8 * NUM_CSNS); while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { tries++; - if (ukbhit()) { - int gc = getchar(); - (void)gc; + if (kbd_enter_pressed()) { PrintAndLogEx(WARNING, "\naborted via keyboard."); return 0; } @@ -427,16 +425,14 @@ static int CmdHFiClassSim(const char *Cmd) { case 4: { // reader in key roll mode, when it has two keys it alternates when trying to verify. PrintAndLogEx(INFO, "Starting iCLASS sim 4 attack (elite mode, reader in key roll mode)"); - PrintAndLogEx(INFO, "press keyboard to cancel"); + PrintAndLogEx(INFO, "press Enter to cancel"); PacketResponseNG resp; clearCommandBuffer(); SendCommandOLD(CMD_SIMULATE_TAG_ICLASS, simType, NUM_CSNS, 0, csns, 8 * NUM_CSNS); while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { tries++; - if (ukbhit()) { - int gc = getchar(); - (void)gc; + if (kbd_enter_pressed()) { PrintAndLogEx(WARNING, "\naborted via keyboard."); return 0; } @@ -969,9 +965,7 @@ static int CmdHFiClassReader_Dump(const char *Cmd) { while (true) { printf("."); fflush(stdout); - if (ukbhit()) { - int gc = getchar(); - (void)gc; + if (kbd_enter_pressed()) { PrintAndLogEx(WARNING, "\n[!] aborted via keyboard!\n"); DropField(); return 0; @@ -1945,9 +1939,7 @@ static int CmdHFiClassCheckKeys(const char *Cmd) { uint64_t t2 = msclock(); uint8_t timeout = 0; - if (ukbhit()) { - int gc = getchar(); - (void)gc; + if (kbd_enter_pressed()) { PrintAndLogEx(WARNING, "\n[!] Aborted via keyboard!\n"); goto out; } @@ -2446,7 +2438,7 @@ int readIclass(bool loop, bool verbose) { // loop in client not device - else on windows have a communication error PacketResponseNG resp; - while (!ukbhit()) { + while (!kbd_enter_pressed()) { clearCommandBuffer(); SendCommandMIX(CMD_READER_ICLASS, flags, 0, 0, NULL, 0); diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 4fa3d8dc0..a81209215 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -1692,9 +1692,7 @@ static int CmdHF14AMfChk_fast(const char *Cmd) { // main keychunk loop for (i = 0; i < keycnt; i += chunksize) { - if (ukbhit()) { - int gc = getchar(); - (void)gc; + if (kbd_enter_pressed()) { PrintAndLogEx(WARNING, "\naborted via keyboard!\n"); goto out; } @@ -1974,9 +1972,7 @@ static int CmdHF14AMfChk(const char *Cmd) { printf("."); fflush(stdout); - if (ukbhit()) { - int gc = getchar(); - (void)gc; + if (kbd_enter_pressed()) { PrintAndLogEx(INFO, "\naborted via keyboard!\n"); goto out; } @@ -2281,7 +2277,7 @@ static int CmdHF14AMfSim(const char *Cmd) { if (flags & FLAG_INTERACTIVE) { PrintAndLogEx(INFO, "Press pm3-button or send another cmd to abort simulation"); - while (!ukbhit()) { + while (!kbd_enter_pressed()) { if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) continue; if (!(flags & FLAG_NR_AR_ATTACK)) break; if ((resp.oldarg[0] & 0xffff) != CMD_SIMULATE_MIFARE_CARD) break; @@ -2328,8 +2324,8 @@ static int CmdHF14AMfSniff(const char *Cmd) { PrintAndLogEx(NORMAL, "-------------------------------------------------------------------------\n"); PrintAndLogEx(NORMAL, "Executing mifare sniffing command. \n"); - PrintAndLogEx(NORMAL, "Press the key on the Proxmark3 device to abort both Proxmark3 and client.\n"); - PrintAndLogEx(NORMAL, "Press the key on pc keyboard to abort the client.\n"); + PrintAndLogEx(NORMAL, "Press the button on the Proxmark3 device to abort both Proxmark3 and client.\n"); + PrintAndLogEx(NORMAL, "Press Enter to abort the client.\n"); PrintAndLogEx(NORMAL, "-------------------------------------------------------------------------\n"); clearCommandBuffer(); @@ -2341,9 +2337,7 @@ static int CmdHF14AMfSniff(const char *Cmd) { while (true) { printf("."); fflush(stdout); - if (ukbhit()) { - int gc = getchar(); - (void)gc; + if (kbd_enter_pressed()) { PrintAndLogEx(INFO, "\naborted via keyboard!\n"); break; } @@ -3242,7 +3236,7 @@ static int CmdHf14AMfNack(const char *Cmd) { bool verbose = (ctmp == 'v'); if (verbose) - PrintAndLogEx(INFO, "Started testing card for NACK bug. Press key to abort"); + PrintAndLogEx(INFO, "Started testing card for NACK bug. Press Enter to abort"); detect_classic_nackbug(verbose); return PM3_SUCCESS; @@ -3307,9 +3301,7 @@ static int CmdHF14AMfice(const char *Cmd) { uint64_t t1 = msclock(); do { - if (ukbhit()) { - int gc = getchar(); - (void)gc; + if (kbd_enter_pressed()) { PrintAndLogEx(INFO, "\naborted via keyboard!\n"); break; } diff --git a/client/cmdlfawid.c b/client/cmdlfawid.c index 7cb24d9c2..1c2d96004 100644 --- a/client/cmdlfawid.c +++ b/client/cmdlfawid.c @@ -491,7 +491,7 @@ static int CmdAWIDBrute(const char *Cmd) { } PrintAndLogEx(SUCCESS, "Bruteforceing AWID %d Reader", fmtlen); - PrintAndLogEx(SUCCESS, "Press pm3-button to abort simulation or press key"); + PrintAndLogEx(SUCCESS, "Press pm3-button to abort simulation or press Enter"); uint16_t up = cn; uint16_t down = cn; @@ -503,9 +503,7 @@ static int CmdAWIDBrute(const char *Cmd) { PrintAndLogEx(WARNING, "Device offline\n"); return PM3_ENODATA; } - if (ukbhit()) { - int gc = getchar(); - (void)gc; + if (kbd_enter_pressed()) { PrintAndLogEx(INFO, "aborted via keyboard!"); return sendPing(); } diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c index 6a5fae76f..aa0add5fa 100644 --- a/client/cmdlfem4x.c +++ b/client/cmdlfem4x.c @@ -544,9 +544,7 @@ static int CmdEM410xBrute(const char *Cmd) { char testuid[11]; testuid[10] = 0; - if (ukbhit()) { - int gc = getchar(); - (void)gc; + if (kbd_enter_pressed()) { PrintAndLogEx(WARNING, "\nAborted via keyboard!\n"); free(uidBlock); return PM3_EOPABORTED; @@ -580,9 +578,7 @@ static int CmdEM410xBrute(const char *Cmd) { static int CmdEM410xWatch(const char *Cmd) { (void)Cmd; // Cmd is not used so far do { - if (ukbhit()) { - int gc = getchar(); - (void)gc; + if (kbd_enter_pressed()) { PrintAndLogEx(WARNING, "\naborted via keyboard!\n"); break; } diff --git a/client/cmdlfhid.c b/client/cmdlfhid.c index b300858d2..cc395c8c5 100644 --- a/client/cmdlfhid.c +++ b/client/cmdlfhid.c @@ -580,9 +580,7 @@ static int CmdHIDBrute(const char *Cmd) { return PM3_ENODATA; } - if (ukbhit()) { - int gc = getchar(); - (void)gc; + if (kbd_enter_pressed()) { PrintAndLogEx(INFO, "aborted via keyboard!"); return sendPing(); } diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 923e50110..04b2c6e9e 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -1843,9 +1843,7 @@ static int CmdT55xxWipe(const char *Cmd) { } static bool IsCancelled(void) { - if (ukbhit()) { - int gc = getchar(); - (void)gc; + if (kbd_enter_pressed()) { PrintAndLogEx(WARNING, "\naborted via keyboard!\n"); return true; } diff --git a/client/cmdsmartcard.c b/client/cmdsmartcard.c index c8529fa23..f936f10a9 100644 --- a/client/cmdsmartcard.c +++ b/client/cmdsmartcard.c @@ -914,9 +914,7 @@ static int smart_brute_sfi(bool decodeTLV) { for (uint16_t rec = 1; rec <= 255; rec++) { - if (ukbhit()) { - int gc = getchar(); - (void)gc; + if (kbd_enter_pressed()) { PrintAndLogEx(WARNING, "\naborted via keyboard!\n"); free(buf); return 1; diff --git a/client/cmdusart.c b/client/cmdusart.c index e57834545..d632901ef 100644 --- a/client/cmdusart.c +++ b/client/cmdusart.c @@ -312,11 +312,9 @@ static int CmdUsartBtFactory(const char *Cmd) { PrintAndLogEx(WARNING, _RED_("WARNING: process only if strictly needed!")); PrintAndLogEx(WARNING, "This requires BT turned ON and NOT connected!"); PrintAndLogEx(WARNING, "Is the add-on blue light blinking? (Say 'n' if you want to abort) [y/n]"); - while (!ukbhit()) { - msleep(200); - } - if (tolower(getchar()) != 'y') { + char input[3]; + if ((fgets(input,sizeof(input),stdin) == NULL) || (strncmp(input, "y\n", sizeof(input)) != 0)) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(FAILED, "Aborting."); return PM3_EOPABORTED; @@ -448,11 +446,10 @@ static int CmdUsartBtFactory(const char *Cmd) { } if ((baudrate != USART_BAUD_RATE) || (parity != USART_PARITY)) { - PrintAndLogEx(WARNING, "Add-on uart settings changed, please turn BT add-on OFF and ON again, then press any key."); - while (!ukbhit()) { + PrintAndLogEx(WARNING, "Add-on uart settings changed, please turn BT add-on OFF and ON again, then press Enter."); + while (!kbd_enter_pressed()) { msleep(200); } - getchar(); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(INFO, "Trying to connect add-on with the new settings."); found = usart_bt_testcomm(USART_BAUD_RATE, USART_PARITY) == PM3_SUCCESS; diff --git a/client/lualibs/hf_reader.lua b/client/lualibs/hf_reader.lua index b99b521da..ba7e3a17c 100644 --- a/client/lualibs/hf_reader.lua +++ b/client/lualibs/hf_reader.lua @@ -15,10 +15,10 @@ local reader15693 = require('read15') -- @return if successfull: an table containing card info -- @return if unsuccessfull : nil, error local function waitForTag() - print("Waiting for card... press any key to quit") + print("Waiting for card... press Enter to quit") local readers = {reader14443A, reader14443B, reader15693} local i = 0; - while not core.ukbhit() do + while not core.kbd_enter_pressed() do i = (i % 3) +1 r = readers[i] print("Reading with ",i) diff --git a/client/lualibs/read14a.lua b/client/lualibs/read14a.lua index 5cdf5a2e4..f68dfff81 100644 --- a/client/lualibs/read14a.lua +++ b/client/lualibs/read14a.lua @@ -121,8 +121,8 @@ end -- @return if successfull: an table containing card info -- @return if unsuccessfull : nil, error local function waitFor14443a() - print('Waiting for card... press any key to quit') - while not core.ukbhit() do + print('Waiting for card... press Enter to quit') + while not core.kbd_enter_pressed() do res, err = read14443a() if res then return res end -- err means that there was no response from card diff --git a/client/lualibs/read14b.lua b/client/lualibs/read14b.lua index 0421bee5b..0be958e25 100644 --- a/client/lualibs/read14b.lua +++ b/client/lualibs/read14b.lua @@ -99,8 +99,8 @@ end -- @return if successfull: an table containing card info -- @return if unsuccessfull : nil, error local function waitFor14443b() - print('Waiting for card... press any key to quit') - while not core.ukbhit() do + print('Waiting for card... press Enter to quit') + while not core.kbd_enter_pressed() do res, err = read14443b(false) if res then return res end -- err means that there was no response from card diff --git a/client/lualibs/read15.lua b/client/lualibs/read15.lua index 0b9a6476e..a70641186 100644 --- a/client/lualibs/read15.lua +++ b/client/lualibs/read15.lua @@ -133,8 +133,8 @@ end -- @return if successfull: an table containing card info -- @return if unsuccessfull : nil, error local function waitFor15693() - print('Waiting for card... press any key to quit') - while not core.ukbhit() do + print('Waiting for card... press Enter to quit') + while not core.kbd_enter_pressed() do res, err = read15693() if res then return res end -- err means that there was no response from card diff --git a/client/mifare/mifarehost.c b/client/mifare/mifarehost.c index 893664e86..e9810e71a 100644 --- a/client/mifare/mifarehost.c +++ b/client/mifare/mifarehost.c @@ -28,9 +28,7 @@ int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) { SendCommandMIX(CMD_READER_MIFARE, arg0, blockno, key_type, NULL, 0); //flush queue - while (ukbhit()) { - int gc = getchar(); - (void)gc; + while (kbd_enter_pressed()) { return PM3_EOPABORTED; } @@ -38,9 +36,7 @@ int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) { while (true) { printf("."); fflush(stdout); - if (ukbhit()) { - int gc = getchar(); - (void)gc; + if (kbd_enter_pressed()) { return PM3_EOPABORTED; } @@ -955,9 +951,7 @@ int detect_classic_nackbug(bool verbose) { while (true) { printf("."); fflush(stdout); - if (ukbhit()) { - int gc = getchar(); - (void)gc; + if (kbd_enter_pressed()) { return PM3_EOPABORTED; } diff --git a/client/scripting.c b/client/scripting.c index cfa361256..572899e2d 100644 --- a/client/scripting.c +++ b/client/scripting.c @@ -411,8 +411,8 @@ static int l_foobar(lua_State *L) { * @param L * @return boolean, true if kbhit, false otherwise. */ -static int l_ukbhit(lua_State *L) { - lua_pushboolean(L, ukbhit() ? true : false); +static int l_kbd_enter_pressed(lua_State *L) { + lua_pushboolean(L, kbd_enter_pressed() ? true : false); return 1; } @@ -1064,7 +1064,7 @@ int set_pm3_libraries(lua_State *L) { {"WaitForResponseTimeout", l_WaitForResponseTimeout}, {"mfDarkside", l_mfDarkside}, {"foobar", l_foobar}, - {"ukbhit", l_ukbhit}, + {"kbd_enter_pressed", l_kbd_enter_pressed}, {"clearCommandBuffer", l_clearCommandBuffer}, {"console", l_CmdConsole}, {"iso15693_crc", l_iso15693_crc}, diff --git a/client/scripts/didump.lua b/client/scripts/didump.lua index b0cc964ee..d5ac6f873 100644 --- a/client/scripts/didump.lua +++ b/client/scripts/didump.lua @@ -488,7 +488,7 @@ local function readtag(mfkey, aeskey ) for blockNo = 0, numBlocks-1 do - if core.ukbhit() then + if core.kbd_enter_pressed() then print("[fail] aborted by user") return nil end diff --git a/client/scripts/formatMifare.lua b/client/scripts/formatMifare.lua index e200d92cb..7c6fd92c0 100644 --- a/client/scripts/formatMifare.lua +++ b/client/scripts/formatMifare.lua @@ -206,7 +206,7 @@ local function main(args) if x then core.console(cmd) end end - if core.ukbhit() then + if core.kbd_enter_pressed() then print('aborted by user') break end diff --git a/client/scripts/lf_bulk.lua b/client/scripts/lf_bulk.lua index 5e8562ae7..54c60fb89 100644 --- a/client/scripts/lf_bulk.lua +++ b/client/scripts/lf_bulk.lua @@ -186,7 +186,7 @@ local function main(args) for cardnum = baseid, endid do local card = cardHex(cardnum, facility) print('Press enter to program card '..cardnum..':'..facility..' (hex: '..card..')') - --This would be better with 'press any key', but we'll take what we can get. + --This would be better with 'press Enter', but we'll take what we can get. io.read() core.console( ('lf hid clone %s'):format(card) ) end diff --git a/client/scripts/mfkeys.lua b/client/scripts/mfkeys.lua index 7d4a726d6..65f50eb9c 100644 --- a/client/scripts/mfkeys.lua +++ b/client/scripts/mfkeys.lua @@ -208,7 +208,7 @@ local function perform_check(numsectors) for sector = 0, #keys do -- Check if user aborted - if core.ukbhit() then + if core.kbd_enter_pressed() then print('Aborted by user') break end diff --git a/client/scripts/mifare_autopwn.lua b/client/scripts/mifare_autopwn.lua index a9859ac25..7a04cd641 100644 --- a/client/scripts/mifare_autopwn.lua +++ b/client/scripts/mifare_autopwn.lua @@ -70,7 +70,7 @@ end -- @return if successfull: an table containing card info -- @return if unsuccessfull : nil, error local function wait_for_mifare() - while not core.ukbhit() do + while not core.kbd_enter_pressed() do res, err = lib14a.read() if res then return res end -- err means that there was no response from card @@ -161,7 +161,7 @@ local function main(args) while not _exit do if print_message then - print('Waiting for card or press any key to stop') + print('Waiting for card or press Enter to stop') print_message = false end res, err = wait_for_mifare() diff --git a/client/scripts/tnp3dump.lua b/client/scripts/tnp3dump.lua index 00070eacc..0faadecaf 100644 --- a/client/scripts/tnp3dump.lua +++ b/client/scripts/tnp3dump.lua @@ -198,7 +198,7 @@ local function main(args) io.flush() - if core.ukbhit() then + if core.kbd_enter_pressed() then print("aborted by user") break end diff --git a/client/scripts/tracetest.lua b/client/scripts/tracetest.lua index e5943fd6a..44cd66b58 100644 --- a/client/scripts/tracetest.lua +++ b/client/scripts/tracetest.lua @@ -118,7 +118,7 @@ local function main(args) core.clearCommandBuffer() - if core.ukbhit() then + if core.kbd_enter_pressed() then print('aborted by user') break end diff --git a/client/util.c b/client/util.c index 568a022f1..a805b9c84 100644 --- a/client/util.c +++ b/client/util.c @@ -26,38 +26,46 @@ uint8_t g_debugMode = 0; #define MAX_BIN_BREAK_LENGTH (3072+384+1) #ifndef _WIN32 -#include -#include #include -#include +#include -int ukbhit(void) { - int cnt = 0; - int error; - static struct termios Otty, Ntty; - - if (tcgetattr(STDIN_FILENO, &Otty) == -1) return -1; - - Ntty = Otty; - - Ntty.c_iflag = 0x0000; // input mode - Ntty.c_oflag = 0x0000; // output mode - Ntty.c_lflag &= ~ICANON; // control mode = raw - Ntty.c_cc[VMIN] = 1; // return if at least 1 character is in the queue - Ntty.c_cc[VTIME] = 0; // no timeout. Wait forever - - if (0 == (error = tcsetattr(STDIN_FILENO, TCSANOW, &Ntty))) { // set new attributes - error += ioctl(STDIN_FILENO, FIONREAD, &cnt); // get number of characters available - error += tcsetattr(STDIN_FILENO, TCSANOW, &Otty); // reset attributes +int kbd_enter_pressed(void) { + int flags; + if ((flags = fcntl(STDIN_FILENO, F_GETFL, 0)) < 0) { + PrintAndLogEx(ERR, "fcntl failed in kbd_enter_pressed"); + return -1; } - return (error == 0 ? cnt : -1); + //non-blocking + flags |= O_NONBLOCK; + if (fcntl(STDIN_FILENO, F_SETFL, flags) < 0) { + PrintAndLogEx(ERR, "fcntl failed in kbd_enter_pressed"); + return -1; + } + int c; + int ret = 0; + do { //get all available chars + c = getchar(); + ret |= c == '\n'; + } while (c != EOF); + //blocking + flags &= ~O_NONBLOCK; + if (fcntl(STDIN_FILENO, F_SETFL, flags) < 0) { + PrintAndLogEx(ERR, "fcntl failed in kbd_enter_pressed"); + return -1; + } + return ret; } #else #include -int ukbhit(void) { - return kbhit(); +int kbd_enter_pressed(void) { + int ret = 0; + while(kbhit()) + { + ret |= getch() == '\r'; + } + return ret; } #endif diff --git a/client/util.h b/client/util.h index e194bb5be..b2c84f4e5 100644 --- a/client/util.h +++ b/client/util.h @@ -129,7 +129,7 @@ uint8_t g_debugMode; -int ukbhit(void); +int kbd_enter_pressed(void); void AddLogLine(const char *fn, const char *data, const char *c); void AddLogHex(const char *fn, const char *extData, const uint8_t *data, const size_t len); void AddLogUint64(const char *fn, const char *data, const uint64_t value); From e51b4f0fdd8ca3af14772f2a287fdc740169be21 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 11 Jul 2019 14:08:58 +0200 Subject: [PATCH 0047/1854] changelog --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d46c8222b..343d9ce88 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Change: replace ukbhit by kbd_enter_pressed, not requiring tcgetattr (@xianglin1998/@doegox) + - Add config for RaspberryPi in JTAG tools (@doegox) + - Add config for FTDI C232HM-DDHSL-0 in JTAG tools (@doegox) + - Fix compilation under MacOSX with binutils (@matrix) + - Add dynamic report of the chipID for flashing purposes (@slurdge) + - Fix Clang warnings (@matrix) + - Fix EMVGPO bug (@matrix) + - Add hitag2 write password auth (@ViRb3) - Add check if bootloader segment is within bounds (@slurdge) - Add `hf 15 csetuid` - set UID on ISO-15693 Magic tags (@t0m4-null) - Change: Print help if unknown arg for hitag reader/writer (@ViRb3) From cbfd195abfb483556cd3413d447d6a892f072300 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 12 Jul 2019 01:48:39 +0200 Subject: [PATCH 0048/1854] Document compilation options --- README.md | 3 +- .../0_Compilation-Instructions.md | 50 ++++------- .../4_Advanced-compilation-parameters.md | 82 +++++++++++++++++++ 3 files changed, 102 insertions(+), 33 deletions(-) create mode 100644 doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md diff --git a/README.md b/README.md index e63e41ae2..a1e7ad76c 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # Proxmark3 RDV4.0 Dedicated Github This repo is based on iceman fork for Proxmark3. It is dedicated to bringing the most out of the new features for Proxmark3 RDV4.0 new hardware and design. +Note that it also supports other Proxmark3 platforms as well! [![Build status](https://ci.appveyor.com/api/projects/status/ct5blik2wa96bv0x/branch/master?svg=true)](https://ci.appveyor.com/project/iceman1001/proxmark3-ji4wj/branch/master) [![Latest release](https://img.shields.io/github/release/RfidResearchGroup/proxmark3.svg)](https://github.com/RfidResearchGroup/proxmark3/releases/latest) @@ -15,7 +16,7 @@ This repo is based on iceman fork for Proxmark3. It is dedicated to bringing the |[Development](#development) | [Important notes on ModemManager for Linux users](/doc/md/Installation_Instructions/ModemManager-Must-Be-Discarded.md) | [Validating proxmark client functionality](/doc/md/Use_of_Proxmark/1_Validation.md) | |[Why didn't you base it on official PM3 Master?](#why-didnt-you-base-it-on-official-pm3-master)| [Homebrew (Mac OS X) & Upgrading HomeBrew Tap Formula](/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md) | [First Use and Verification](/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md)| |[PM3 GUI](#pm3-gui)|[Setup and build for Windows](/doc/md/Installation_Instructions/Windows-Installation-Instructions.md)|[Commands & Features](/doc/md/Use_of_Proxmark/3_Commands-and-Features.md)| -|[Issues](#issues)|[Blue shark manual](/doc/bt_manual_v10.md) || +|[Issues](#issues)|[Blue shark manual](/doc/bt_manual_v10.md) |[Advanced compilation parameters](/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md)| |[Notes on UART](/doc/uart_notes.md)||| |[Notes on Frame format](/doc/new_frame_format.md)||| |[Notes on Termux / Android](/doc/termux_notes.md)||| diff --git a/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md b/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md index bb3699a72..7493fba1a 100644 --- a/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md +++ b/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md @@ -1,5 +1,16 @@ # Compilation instructions +## Tuning compilation parameters + +The client and the Proxmark3 firmware should always be in sync. +Nevertheless, the firmware can be tuned depending on the Proxmark3 platform and options. + +Indeed, the RRG/Iceman fork can be used on other Proxmark3 hardware platforms as well. + +Via some definitions, you can adjust the firmware for a given platform, but also to add features like the support of the Blue Shark add-on or to select which standalone mode to embed. + +To learn how to adjust the firmware, please read [Advanced compilation parameters](/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md). + ## Get the latest commits ```sh @@ -15,48 +26,23 @@ make clean && make all ## Flash the BOOTROM & FULLIMAGE +In most cases, you can run the script `flash-all.sh` which try to auto-detect the port to use, on several OS. + +For the other cases, specify the port by yourself. For example, for a Proxmark3 connected via USB under Linux: + ```sh client/flasher /dev/ttyACM0 -b bootrom/obj/bootrom.elf armsrc/obj/fullimage.elf ``` ## Run the client -```sh -cd client -./proxmark3 /dev/ttyACM0 -``` +In most cases, you can run the script `proxmark3.sh` which try to auto-detect the port to use, on several OS. -## Compiling for other boards +For the other cases, specify the port by yourself. For example, for a Proxmark3 connected via USB under Linux: -Available boards - -| BOARD | PLATFORM | -|:---------------:|:---------------------------------------| -| `PM3RDV4` (def) | Proxmark3 rdv4 with AT91SAM7S512 | -| `PM3EVO` | Proxmark3 EVO with AT91SAM7S512 | -| `PM3EASY` | Proxmark3 rdv3 Easy with AT91SAM7S256 | -| `PM3RDV2` | Proxmark3 rdv2 with AT91SAM7S512 | -| `PM3OLD256` | Proxmark3 V1 with AT91SAM7S256 | -| `PM3OLD512` | Proxmark3 V1 with AT91SAM7S512 | - -Create a file named `Makefile.platform` in the root directory of the repository: +Here, for example, for a Proxmark3 connected via USB under Linux: ```sh -# PLATFORM=${BOARD} -# Following example is to compile sources for Proxmark3 rdv3 Easy -PLATFORM=PM3EASY -``` - -From this point: - -```sh -# Clean and compile -make clean && make all - -# Flash the BOOTROM & FULLIMAGE -client/flasher /dev/ttyACM0 -b bootrom/obj/bootrom.elf armsrc/obj/fullimage.elf - -# Run the client cd client ./proxmark3 /dev/ttyACM0 ``` diff --git a/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md b/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md new file mode 100644 index 000000000..aea5b5e30 --- /dev/null +++ b/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md @@ -0,0 +1,82 @@ +# Advanced compilation parameters + +The client and the Proxmark3 firmware should always be in sync. +Nevertheless, the firmware can be tuned depending on the Proxmark3 platform and options. + +Indeed, the RRG/Iceman fork can be used on other Proxmark3 hardware platforms as well. + +Via some definitions, you can adjust the firmware for a given platform, but also to add features like the support of the Blue Shark add-on or to select which standalone mode to embed. + +## Client + +The client doesn't depend on the capabilities of the Proxmark3 it's connected to. +So you can use the same client for different Proxmark3 platforms, given that everything is running the same version. + +## Firmware + +By default, the firmware is of course tuned for the Proxmark3 Rdv4.0 device, which has built-in support for 256kb onboard flash SPI memory, Sim module (smart card support), FPC connector. +These features make it very different from all other devices, there is non other like this one. + +**Recommendation**: if you don't have a RDV4, we strongly recommend your device to have at least a 512kb arm chip, since this repo is on the very edge of 256kb limit. + +A firmware built for the RDV4 can still run on the other platforms as it will auto-detect during boot that external SPI and Sim are not present, still it will boot faster if it's tuned to the platform. + +If you need to tune things and save the configuration, create a file `Makefile.platform` in the root directory of the repository, see `Makefile.platform.sample`. +For an up-to-date exhaustive list of options, you can run `make PLATFORM=`. + +## PLATFORM + +Here are the supported values you can assign to `PLATFORM` in `Makefile.platform`: + +| PLATFORM | DESCRIPTION | +|-----------------|----------------------------------------| +| PM3RDV4 (def) | Proxmark3 rdv4 with AT91SAM7S512 | +| PM3EVO | Proxmark3 EVO with AT91SAM7S512 | +| PM3EASY | Proxmark3 rdv3 Easy with AT91SAM7S256 | +| PM3RDV2 | Proxmark3 rdv2 with AT91SAM7S512 | +| PM3OLD256 | Proxmark3 V1 with AT91SAM7S256 | +| PM3OLD512 | Proxmark3 V1 with AT91SAM7S512 | + +By default `PLATFORM=PM3RDV4`. + +Known issues: + +* 256kb Arm chip devices: The compiled firmware image from this repo may/will be too large for your device. +* PM3 Evo: it has a different led/button pin assignment. It tends to be messed up. + +## PLATFORM_EXTRAS + +Here are the supported values you can assign to `PLATFORM_EXTRAS` in `Makefile.platform`: + +| PLATFORM_EXTRAS | DESCRIPTION | +|-----------------|----------------------------------------| +| BTADDON | Proxmark3 rdv4 BT add-on | + +By default `PLATFORM_EXTRAS=`. + +If you have installed a Blue Shark add-on on your RDV4, define `PLATFORM_EXTRAS=BTADDON` in your `Makefile.platform`. + + +## STANDALONE + +The RRG/Iceman fork gives you to easily choose which standalone mode to embed in the firmware. + +Here are the supported values you can assign to `STANDALONE` in `Makefile.platform`: + +| STANDALONE | DESCRIPTION | +|-----------------|----------------------------------------| +| | No standalone mode +| LF_SAMYRUN (def)| HID26 read/clone/sim - Samy Kamkar +| LF_ICERUN | standalone mode skeleton - iceman +| LF_PROXBRUTE | HID ProxII bruteforce - Brad Antoniewicz +| LF_HIDBRUTE | HID corporate 1000 bruteforce - Federico dotta & Maurizio Agazzini +| HF_YOUNG | Mifare sniff/simulation - Craig Young +| HF_MATTYRUN | Mifare sniff/clone - Matías A. Ré Medina +| HF_COLIN | Mifare ultra fast sniff/sim/clone - Colin Brigato +| HF_BOG | 14a sniff with ULC/ULEV1/NTAG auth storing in flashmem - Bogito + +By default `STANDALONE=LF_SAMYRUN`. + +## Next step + +See [Compilation instructions](/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md) From d94c74b24b4c680b778c8af3af9410d3ba7cb077 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 12 Jul 2019 13:58:38 +0300 Subject: [PATCH 0049/1854] make style --- client/comms.c | 2 +- client/emv/apduinfo.c | 98 +++++++++++++++++++++++++------------------ client/emv/apduinfo.h | 6 +-- client/util.c | 12 +++--- 4 files changed, 66 insertions(+), 52 deletions(-) diff --git a/client/comms.c b/client/comms.c index 5aa704728..6fd41ecad 100644 --- a/client/comms.c +++ b/client/comms.c @@ -136,7 +136,7 @@ static void SendCommandNG_internal(uint16_t cmd, uint8_t *data, size_t len, bool txBufferNG.pre.ng = ng; txBufferNG.pre.length = len; txBufferNG.pre.cmd = cmd; - if ( len > 0 && data ) + if (len > 0 && data) memcpy(&txBufferNG.data, data, len); if ((conn.send_via_fpc_usart && conn.send_with_crc_on_fpc) || ((!conn.send_via_fpc_usart) && conn.send_with_crc_on_usb)) { diff --git a/client/emv/apduinfo.c b/client/emv/apduinfo.c index 79b502816..3b3664e4b 100644 --- a/client/emv/apduinfo.c +++ b/client/emv/apduinfo.c @@ -319,39 +319,39 @@ const char *GetAPDUCodeDescription(uint8_t sw1, uint8_t sw2) { int APDUDecode(uint8_t *data, size_t len, APDUStruct *apdu) { ExtAPDUHeader *hapdu = (ExtAPDUHeader *)data; - + apdu->cla = hapdu->cla; apdu->ins = hapdu->ins; apdu->p1 = hapdu->p1; apdu->p2 = hapdu->p2; - + apdu->lc = 0; apdu->data = NULL; apdu->le = 0; apdu->extended_apdu = false; apdu->case_type = 0x00; - + uint8_t b0 = hapdu->lc[0]; - + // case 1 if (len == 4) { apdu->case_type = 0x01; } - - // case 2S (Le) + + // case 2S (Le) if (len == 5) { apdu->case_type = 0x02; apdu->le = b0; if (!apdu->le) apdu->le = 0x100; } - + // case 3S (Lc + data) if (len == 5U + b0 && b0 != 0) { apdu->case_type = 0x03; apdu->lc = b0; } - + // case 4S (Lc + data + Le) if (len == 5U + b0 + 1U && b0 != 0) { apdu->case_type = 0x04; @@ -360,12 +360,12 @@ int APDUDecode(uint8_t *data, size_t len, APDUStruct *apdu) { if (!apdu->le) apdu->le = 0x100; } - + // extended length apdu if (len >= 7 && b0 == 0) { uint16_t extlen = (hapdu->lc[1] << 8) + hapdu->lc[2]; - - // case 2E (Le) - extended + + // case 2E (Le) - extended if (len == 7) { apdu->case_type = 0x12; apdu->extended_apdu = true; @@ -373,59 +373,65 @@ int APDUDecode(uint8_t *data, size_t len, APDUStruct *apdu) { if (!apdu->le) apdu->le = 0x10000; } - - // case 3E (Lc + data) - extended - if (len == 7U + extlen) { + + // case 3E (Lc + data) - extended + if (len == 7U + extlen) { apdu->case_type = 0x13; apdu->extended_apdu = true; apdu->lc = extlen; } - // case 4E (Lc + data + Le) - extended 2-byte Le - if (len == 7U + extlen + 2U) { + // case 4E (Lc + data + Le) - extended 2-byte Le + if (len == 7U + extlen + 2U) { apdu->case_type = 0x14; apdu->extended_apdu = true; apdu->lc = extlen; apdu->le = (data[len - 2] << 8) + data[len - 1]; - if (!apdu->le) - apdu->le = 0x10000; + if (!apdu->le) + apdu->le = 0x10000; } - // case 4E (Lc + data + Le) - extended 3-byte Le - if (len == 7U + extlen + 3U && data[len - 3] == 0) { + // case 4E (Lc + data + Le) - extended 3-byte Le + if (len == 7U + extlen + 3U && data[len - 3] == 0) { apdu->case_type = 0x24; apdu->extended_apdu = true; apdu->lc = extlen; apdu->le = (data[len - 2] << 8) + data[len - 1]; - if (!apdu->le) - apdu->le = 0x10000; + if (!apdu->le) + apdu->le = 0x10000; } } - + if (!apdu->case_type) return 1; - + if (apdu->lc) { if (apdu->extended_apdu) { apdu->data = data + 7; } else { apdu->data = data + 5; } - - } - + + } + return 0; } int APDUEncode(APDUStruct *apdu, uint8_t *data, size_t *len) { + if (len) + *len = 0; + + if (apdu->le > 0x10000 || apdu->lc != 0xffff) + return 1; + size_t dptr = 0; data[dptr++] = apdu->cla; data[dptr++] = apdu->ins; data[dptr++] = apdu->p1; data[dptr++] = apdu->p2; - + if (apdu->lc) { - if (apdu->extended_apdu || apdu->lc > 0xff || apdu->le > 0xff) { + if (apdu->extended_apdu || apdu->lc > 0xff || apdu->le > 0x100) { data[dptr++] = 0x00; data[dptr++] = (apdu->lc >> 8) & 0xff; data[dptr++] = (apdu->lc) & 0xff; @@ -436,24 +442,34 @@ int APDUEncode(APDUStruct *apdu, uint8_t *data, size_t *len) { data[dptr++] = apdu->lc; memmove(&data[dptr], apdu->data, apdu->lc); dptr += apdu->lc; - } - } - + } + } + if (apdu->le) { if (apdu->extended_apdu) { - data[dptr++] = 0x00; - data[dptr++] = (apdu->le >> 8) & 0xff; - data[dptr++] = (apdu->le) & 0xff; + if (apdu->le != 0x10000) { + data[dptr++] = 0x00; + data[dptr++] = (apdu->le >> 8) & 0xff; + data[dptr++] = (apdu->le) & 0xff; + } else { + data[dptr++] = 0x00; + data[dptr++] = 0x00; + data[dptr++] = 0x00; + } } else { - data[dptr++] = apdu->le; - } + if (apdu->le != 0x100) + data[dptr++] = apdu->le; + else + data[dptr++] = 0x00; + } } - - *len = dptr; + + if (len) + *len = dptr; return 0; } void APDUPrint(APDUStruct apdu) { - PrintAndLogEx(INFO, "apdu: %scase=%02x cla=%02x ins=%02x p1=%02x p2=%02x lc=%d le=%d\n", - apdu.extended_apdu ? "[e]":"", apdu.case_type, apdu.cla, apdu.ins, apdu.p1, apdu.p2, apdu.lc, apdu.le); + PrintAndLogEx(INFO, "apdu: %scase=%02x cla=%02x ins=%02x p1=%02x p2=%02x Lc=%d Le=%d\n", + apdu.extended_apdu ? "[e]" : "", apdu.case_type, apdu.cla, apdu.ins, apdu.p1, apdu.p2, apdu.lc, apdu.le); } diff --git a/client/emv/apduinfo.h b/client/emv/apduinfo.h index e510492cf..7f1e8fd72 100644 --- a/client/emv/apduinfo.h +++ b/client/emv/apduinfo.h @@ -32,8 +32,7 @@ typedef struct { const APDUCode *GetAPDUCode(uint8_t sw1, uint8_t sw2); const char *GetAPDUCodeDescription(uint8_t sw1, uint8_t sw2); -typedef struct -{ +typedef struct { uint8_t cla; uint8_t ins; uint8_t p1; @@ -41,8 +40,7 @@ typedef struct uint8_t lc[3]; } __attribute__((packed)) ExtAPDUHeader; -typedef struct -{ +typedef struct { uint8_t cla; uint8_t ins; uint8_t p1; diff --git a/client/util.c b/client/util.c index 568a022f1..8121a7ed3 100644 --- a/client/util.c +++ b/client/util.c @@ -170,8 +170,8 @@ bool CheckStringIsHEXValue(const char *value) { void hex_to_buffer(const uint8_t *buf, const uint8_t *hex_data, const size_t hex_len, const size_t hex_max_len, const size_t min_str_len, const size_t spaces_between, bool uppercase) { - if (buf == NULL ) return; - + if (buf == NULL) return; + char *tmp = (char *)buf; size_t i; memset(tmp, 0x00, hex_max_len); @@ -197,16 +197,16 @@ void hex_to_buffer(const uint8_t *buf, const uint8_t *hex_data, const size_t hex // printing and converting functions void print_hex(const uint8_t *data, const size_t len) { - if (data == NULL || len == 0 ) return; - + if (data == NULL || len == 0) return; + for (size_t i = 0; i < len; i++) printf("%02x ", data[i]); printf("\n"); } void print_hex_break(const uint8_t *data, const size_t len, uint8_t breaks) { - if (data == NULL || len == 0 ) return; - + if (data == NULL || len == 0) return; + int rownum = 0; printf("[%02d] | ", rownum); for (size_t i = 0; i < len; ++i) { From ec534305de9073b3028e55edb726510ecaa778a5 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 12 Jul 2019 21:16:51 +0200 Subject: [PATCH 0050/1854] Document WSL and update ProxSpace instructions --- CHANGELOG.md | 1 + .../Windows-Installation-Instructions.md | 153 ++++++++++++++---- 2 files changed, 122 insertions(+), 32 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 343d9ce88..a276440d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Add documentation for usage of Proxmark3 under WSL (@doegox) - Change: replace ukbhit by kbd_enter_pressed, not requiring tcgetattr (@xianglin1998/@doegox) - Add config for RaspberryPi in JTAG tools (@doegox) - Add config for FTDI C232HM-DDHSL-0 in JTAG tools (@doegox) diff --git a/doc/md/Installation_Instructions/Windows-Installation-Instructions.md b/doc/md/Installation_Instructions/Windows-Installation-Instructions.md index ac88906da..1617ec6ec 100644 --- a/doc/md/Installation_Instructions/Windows-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Windows-Installation-Instructions.md @@ -1,60 +1,149 @@ -# Building on Windows -You will need to use the Gator96100 Proxspace package to assist in your windows installation. -This can be downloaded from https://github.com/Gator96100/ProxSpace/ +# Installing on Windows + +There are two ways to install, build and use Proxmark3 on Windows: + +* Using Gator96100 **ProxSpace**, a package to assist in your Windows installation of MinGW +* Using native **WSL**, if you're running a Windows 10 version recent enough (FCU 1709 or later) --- -# Video Installation guide + +# Installing on Windows with ProxSpace + +## Video Installation guide [![Windows Installation tutorial](https://github.com/5w0rdfish/Proxmark3-RDV4-ParrotOS/blob/master/screenshot-www.youtube.com-2019.03.17-20-44-33.png)](https://youtu.be/zzF0NCMJnYU "Windows Installation Tutorial") -## Manual Installation +## Driver Installation -### Driver Installation +Install required drivers for your Windows installation. You may need admin privileges to do this. +Step by step guides are online such as [RiscCorps](https://store.ryscc.com/blogs/news/how-to-install-a-proxmark3-driver-on-windows-10). -Install required drivers for your windows installation. You will may need admin privileges to do this. -(This is covered in the video) Step by step guides are online such as [RiscCorps](https://store.ryscc.com/blogs/news/how-to-install-a-proxmark3-driver-on-windows-10) +## Download / clone ProxSpace repo -### Install Github +Download the Gator96100 ProxSpace package from https://github.com/Gator96100/ProxSpace/ -Install Github for Windows https://desktop.github.com/ +If you prefer, you can clone it, provided that you installed Github for Windows https://desktop.github.com/. -### Download / clone Proxspace repo - -Download the required proxspace repo. https://github.com/Gator96100/ProxSpace/ - -Extract 'ProxSpace' to a location on drive without spaces. +Extract 'ProxSpace' to a location path without spaces. For example D:\OneDrive\Documents\GitHub is ok whereas C:\My Documents\My Projects\proxspace is not. -### Clone the RRG/Iceman repository +If you're running Windows in a Virtualbox guest, make sure not to install ProxSpace on a vbox shared drive. (It's ok later to move the `/pm3` subfolder to a shared drive and edit the `*.bat`) -```sh -git clone https://github.com/RfidResearchGroup/proxmark3.git -``` - -### Copy files to Proxspace - -Copy all the contents from the `proxmark3` folder into the proxspace `pm3` folder - -### Run the .bat +## Launch ProxSpace Run `runme.bat` or `runme64.bat` depending on your Windows architecture. -Please note you will need to use `/` as you are using BASH. +You'll get a Bash prompt and your home directory should become the ProxSpace `pm3` sub-directory. -### Compile and use the project +Please note you will need to use `/` in paths as you are using Bash. + +## Clone the RRG/Iceman repository + +```sh +cd +git clone https://github.com/RfidResearchGroup/proxmark3.git +cd proxmark3 +``` + +## Compile and use the project Now you're ready to follow the [compilation instructions](/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md). -The only differences are that executables end with `.exe` (e.g. `client/flasher.exe`) and that the Proxmark3 port is one of your `comX` ports where "X" is the com port number assigned to proxmark3 under Windows. +To use the compiled client and flasher, the only differences are that executables end with `.exe` (e.g. `client/flasher.exe`) and that the Proxmark3 port is one of your `comX` ports where "X" is the com port number assigned to proxmark3 under Windows. -So flashing will resemble +To flash: In principle, the helper script `flash-all.sh` should auto-detect your COM port, so you can just try: + +```sh +./flash-all.sh +``` + +If COM port detection failed, you'll have to call the flasher manually and specify the correct port: ```sh client/flasher.exe comX -b bootrom/obj/bootrom.elf armsrc/obj/fullimage.elf ``` -And running the client will resemble +Similarly, to run the client, you may try: ```sh -cd client -./proxmark3.exe comX +./proxmark3.sh +``` + +Or, by specifying the COM port manually: + +```sh +client/proxmark3.exe comX +``` + +# Installing on Windows with WSL + +It requires to run a Windows 10 version 1709 or above. Previous versions didn't have support for COM ports. + +Install WSL with e.g. the standard Ubuntu. + +For WSL configuration, see [Manage and configure Windows Subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl/wsl-config). + +## Driver Installation + +Install required drivers for your Windows installation. You may need admin privileges to do this. +Step by step guides are online such as [RiscCorps](https://store.ryscc.com/blogs/news/how-to-install-a-proxmark3-driver-on-windows-10). + +## X Server Installation + +If you want to run the graphical components of the Proxmark3 client, you need to install a X Server such as [VcXsrv](https://sourceforge.net/projects/vcxsrv/) or [Xming](https://sourceforge.net/projects/xming/). + +## Dependencies + +Enter WSL prompt (`wsl`) and from there, follow the [Linux Installation Instructions](/doc/md/Installation_Instructions/Linux-Installation-Instructions.md) for Ubuntu, summarized here below: + +```sh +sudo apt-get update +sudo apt-get install p7zip git ca-certificates build-essential libreadline5 libreadline-dev libusb-0.1-4 \ +libusb-dev perl pkg-config wget libncurses5-dev gcc-arm-none-eabi libstdc++-arm-none-eabi-newlib \ +libqt4-dev +``` + +If you don't need the graphical components of the Proxmark3 client, you can skip the installation of `libqt4-dev`. + +## Clone the RRG/Iceman repository + +```sh +git clone https://github.com/RfidResearchGroup/proxmark3.git +``` + +## Compile and use the project + +Now you're ready to follow the [compilation instructions](/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md). + +To use the compiled client and flasher, the only difference is that the Proxmark3 port is translated from your `comX` port where "X" is the com port number assigned to proxmark3 under Windows, to a `/dev/ttySX`. + +You will need to give permission to the current user to access `/dev/ttySX`: (change X to your port number) + +```sh +sudo chmod 666 /dev/ttySX +``` + +Unfortunately the access rights of the port won't survive and will have to be fixed again next time. + +If you installed a X Server and compiled the Proxmark3 with QT4 support, you've to export the `DISPLAY` environment variable: + +```sh +export DISPLAY=:0 +``` + +and add it to your Bash profile for the next times: + +```sh +echo "export DISPLAY=:0" >> ~/.bashrc +``` + +To flash, you've to call the flasher manually and specify the correct port: + +```sh +client/flasher /dev/ttySX -b bootrom/obj/bootrom.elf armsrc/obj/fullimage.elf +``` + +Similarly, to run the client: + +```sh +client/proxmark3 /dev/ttySX ``` From 996ed197fbfb9af8af6b8437adbe177e8d5a14db Mon Sep 17 00:00:00 2001 From: slurdge Date: Fri, 12 Jul 2019 23:48:54 +0200 Subject: [PATCH 0051/1854] Remove aes.c in favor of mbedtls implementation. Changelog --- CHANGELOG.md | 1 + armsrc/Makefile | 2 +- armsrc/aes.c | 1170 -------------------------------- armsrc/aes.h | 34 - armsrc/desfire_crypto.c | 16 +- armsrc/mifaredesfire.c | 28 +- common/Makefile.common | 2 +- common/desfire.h | 6 +- common/mbedtls/platform_util.c | 4 +- 9 files changed, 34 insertions(+), 1229 deletions(-) delete mode 100644 armsrc/aes.c delete mode 100644 armsrc/aes.h diff --git a/CHANGELOG.md b/CHANGELOG.md index a276440d7..a312e3992 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac ## [unreleased][unreleased] - Add documentation for usage of Proxmark3 under WSL (@doegox) + - Change: replace aes.c with mbedtls version (@slurdge) - Change: replace ukbhit by kbd_enter_pressed, not requiring tcgetattr (@xianglin1998/@doegox) - Add config for RaspberryPi in JTAG tools (@doegox) - Add config for FTDI C232HM-DDHSL-0 in JTAG tools (@doegox) diff --git a/armsrc/Makefile b/armsrc/Makefile index 7fda76b99..7fee5c79b 100644 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@ -30,7 +30,7 @@ SRC_ISO15693 = iso15693.c iso15693tools.c SRC_ISO14443a = iso14443a.c mifareutil.c mifarecmd.c epa.c mifaresim.c SRC_ISO14443b = iso14443b.c SRC_FELICA = felica.c -SRC_CRAPTO1 = crypto1.c des.c aes.c desfire_key.c desfire_crypto.c mifaredesfire.c +SRC_CRAPTO1 = crypto1.c des.c desfire_key.c desfire_crypto.c mifaredesfire.c aes.c platform_util.c SRC_CRC = crc.c crc16.c crc32.c SRC_ICLASS = iclass.c optimized_cipher.c SRC_LEGIC = legicrf.c legicrfsim.c legic_prng.c diff --git a/armsrc/aes.c b/armsrc/aes.c deleted file mode 100644 index f8a36f28c..000000000 --- a/armsrc/aes.c +++ /dev/null @@ -1,1170 +0,0 @@ -#include "aes.h" - -static const unsigned int Te0[256] = { - 0xc66363a5UL, 0xf87c7c84UL, 0xee777799UL, 0xf67b7b8dUL, - 0xfff2f20dUL, 0xd66b6bbdUL, 0xde6f6fb1UL, 0x91c5c554UL, - 0x60303050UL, 0x02010103UL, 0xce6767a9UL, 0x562b2b7dUL, - 0xe7fefe19UL, 0xb5d7d762UL, 0x4dababe6UL, 0xec76769aUL, - 0x8fcaca45UL, 0x1f82829dUL, 0x89c9c940UL, 0xfa7d7d87UL, - 0xeffafa15UL, 0xb25959ebUL, 0x8e4747c9UL, 0xfbf0f00bUL, - 0x41adadecUL, 0xb3d4d467UL, 0x5fa2a2fdUL, 0x45afafeaUL, - 0x239c9cbfUL, 0x53a4a4f7UL, 0xe4727296UL, 0x9bc0c05bUL, - 0x75b7b7c2UL, 0xe1fdfd1cUL, 0x3d9393aeUL, 0x4c26266aUL, - 0x6c36365aUL, 0x7e3f3f41UL, 0xf5f7f702UL, 0x83cccc4fUL, - 0x6834345cUL, 0x51a5a5f4UL, 0xd1e5e534UL, 0xf9f1f108UL, - 0xe2717193UL, 0xabd8d873UL, 0x62313153UL, 0x2a15153fUL, - 0x0804040cUL, 0x95c7c752UL, 0x46232365UL, 0x9dc3c35eUL, - 0x30181828UL, 0x379696a1UL, 0x0a05050fUL, 0x2f9a9ab5UL, - 0x0e070709UL, 0x24121236UL, 0x1b80809bUL, 0xdfe2e23dUL, - 0xcdebeb26UL, 0x4e272769UL, 0x7fb2b2cdUL, 0xea75759fUL, - 0x1209091bUL, 0x1d83839eUL, 0x582c2c74UL, 0x341a1a2eUL, - 0x361b1b2dUL, 0xdc6e6eb2UL, 0xb45a5aeeUL, 0x5ba0a0fbUL, - 0xa45252f6UL, 0x763b3b4dUL, 0xb7d6d661UL, 0x7db3b3ceUL, - 0x5229297bUL, 0xdde3e33eUL, 0x5e2f2f71UL, 0x13848497UL, - 0xa65353f5UL, 0xb9d1d168UL, 0x00000000UL, 0xc1eded2cUL, - 0x40202060UL, 0xe3fcfc1fUL, 0x79b1b1c8UL, 0xb65b5bedUL, - 0xd46a6abeUL, 0x8dcbcb46UL, 0x67bebed9UL, 0x7239394bUL, - 0x944a4adeUL, 0x984c4cd4UL, 0xb05858e8UL, 0x85cfcf4aUL, - 0xbbd0d06bUL, 0xc5efef2aUL, 0x4faaaae5UL, 0xedfbfb16UL, - 0x864343c5UL, 0x9a4d4dd7UL, 0x66333355UL, 0x11858594UL, - 0x8a4545cfUL, 0xe9f9f910UL, 0x04020206UL, 0xfe7f7f81UL, - 0xa05050f0UL, 0x783c3c44UL, 0x259f9fbaUL, 0x4ba8a8e3UL, - 0xa25151f3UL, 0x5da3a3feUL, 0x804040c0UL, 0x058f8f8aUL, - 0x3f9292adUL, 0x219d9dbcUL, 0x70383848UL, 0xf1f5f504UL, - 0x63bcbcdfUL, 0x77b6b6c1UL, 0xafdada75UL, 0x42212163UL, - 0x20101030UL, 0xe5ffff1aUL, 0xfdf3f30eUL, 0xbfd2d26dUL, - 0x81cdcd4cUL, 0x180c0c14UL, 0x26131335UL, 0xc3ecec2fUL, - 0xbe5f5fe1UL, 0x359797a2UL, 0x884444ccUL, 0x2e171739UL, - 0x93c4c457UL, 0x55a7a7f2UL, 0xfc7e7e82UL, 0x7a3d3d47UL, - 0xc86464acUL, 0xba5d5de7UL, 0x3219192bUL, 0xe6737395UL, - 0xc06060a0UL, 0x19818198UL, 0x9e4f4fd1UL, 0xa3dcdc7fUL, - 0x44222266UL, 0x542a2a7eUL, 0x3b9090abUL, 0x0b888883UL, - 0x8c4646caUL, 0xc7eeee29UL, 0x6bb8b8d3UL, 0x2814143cUL, - 0xa7dede79UL, 0xbc5e5ee2UL, 0x160b0b1dUL, 0xaddbdb76UL, - 0xdbe0e03bUL, 0x64323256UL, 0x743a3a4eUL, 0x140a0a1eUL, - 0x924949dbUL, 0x0c06060aUL, 0x4824246cUL, 0xb85c5ce4UL, - 0x9fc2c25dUL, 0xbdd3d36eUL, 0x43acacefUL, 0xc46262a6UL, - 0x399191a8UL, 0x319595a4UL, 0xd3e4e437UL, 0xf279798bUL, - 0xd5e7e732UL, 0x8bc8c843UL, 0x6e373759UL, 0xda6d6db7UL, - 0x018d8d8cUL, 0xb1d5d564UL, 0x9c4e4ed2UL, 0x49a9a9e0UL, - 0xd86c6cb4UL, 0xac5656faUL, 0xf3f4f407UL, 0xcfeaea25UL, - 0xca6565afUL, 0xf47a7a8eUL, 0x47aeaee9UL, 0x10080818UL, - 0x6fbabad5UL, 0xf0787888UL, 0x4a25256fUL, 0x5c2e2e72UL, - 0x381c1c24UL, 0x57a6a6f1UL, 0x73b4b4c7UL, 0x97c6c651UL, - 0xcbe8e823UL, 0xa1dddd7cUL, 0xe874749cUL, 0x3e1f1f21UL, - 0x964b4bddUL, 0x61bdbddcUL, 0x0d8b8b86UL, 0x0f8a8a85UL, - 0xe0707090UL, 0x7c3e3e42UL, 0x71b5b5c4UL, 0xcc6666aaUL, - 0x904848d8UL, 0x06030305UL, 0xf7f6f601UL, 0x1c0e0e12UL, - 0xc26161a3UL, 0x6a35355fUL, 0xae5757f9UL, 0x69b9b9d0UL, - 0x17868691UL, 0x99c1c158UL, 0x3a1d1d27UL, 0x279e9eb9UL, - 0xd9e1e138UL, 0xebf8f813UL, 0x2b9898b3UL, 0x22111133UL, - 0xd26969bbUL, 0xa9d9d970UL, 0x078e8e89UL, 0x339494a7UL, - 0x2d9b9bb6UL, 0x3c1e1e22UL, 0x15878792UL, 0xc9e9e920UL, - 0x87cece49UL, 0xaa5555ffUL, 0x50282878UL, 0xa5dfdf7aUL, - 0x038c8c8fUL, 0x59a1a1f8UL, 0x09898980UL, 0x1a0d0d17UL, - 0x65bfbfdaUL, 0xd7e6e631UL, 0x844242c6UL, 0xd06868b8UL, - 0x824141c3UL, 0x299999b0UL, 0x5a2d2d77UL, 0x1e0f0f11UL, - 0x7bb0b0cbUL, 0xa85454fcUL, 0x6dbbbbd6UL, 0x2c16163aUL, -}; -static const unsigned int Te1[256] = { - 0xa5c66363UL, 0x84f87c7cUL, 0x99ee7777UL, 0x8df67b7bUL, - 0x0dfff2f2UL, 0xbdd66b6bUL, 0xb1de6f6fUL, 0x5491c5c5UL, - 0x50603030UL, 0x03020101UL, 0xa9ce6767UL, 0x7d562b2bUL, - 0x19e7fefeUL, 0x62b5d7d7UL, 0xe64dababUL, 0x9aec7676UL, - 0x458fcacaUL, 0x9d1f8282UL, 0x4089c9c9UL, 0x87fa7d7dUL, - 0x15effafaUL, 0xebb25959UL, 0xc98e4747UL, 0x0bfbf0f0UL, - 0xec41adadUL, 0x67b3d4d4UL, 0xfd5fa2a2UL, 0xea45afafUL, - 0xbf239c9cUL, 0xf753a4a4UL, 0x96e47272UL, 0x5b9bc0c0UL, - 0xc275b7b7UL, 0x1ce1fdfdUL, 0xae3d9393UL, 0x6a4c2626UL, - 0x5a6c3636UL, 0x417e3f3fUL, 0x02f5f7f7UL, 0x4f83ccccUL, - 0x5c683434UL, 0xf451a5a5UL, 0x34d1e5e5UL, 0x08f9f1f1UL, - 0x93e27171UL, 0x73abd8d8UL, 0x53623131UL, 0x3f2a1515UL, - 0x0c080404UL, 0x5295c7c7UL, 0x65462323UL, 0x5e9dc3c3UL, - 0x28301818UL, 0xa1379696UL, 0x0f0a0505UL, 0xb52f9a9aUL, - 0x090e0707UL, 0x36241212UL, 0x9b1b8080UL, 0x3ddfe2e2UL, - 0x26cdebebUL, 0x694e2727UL, 0xcd7fb2b2UL, 0x9fea7575UL, - 0x1b120909UL, 0x9e1d8383UL, 0x74582c2cUL, 0x2e341a1aUL, - 0x2d361b1bUL, 0xb2dc6e6eUL, 0xeeb45a5aUL, 0xfb5ba0a0UL, - 0xf6a45252UL, 0x4d763b3bUL, 0x61b7d6d6UL, 0xce7db3b3UL, - 0x7b522929UL, 0x3edde3e3UL, 0x715e2f2fUL, 0x97138484UL, - 0xf5a65353UL, 0x68b9d1d1UL, 0x00000000UL, 0x2cc1ededUL, - 0x60402020UL, 0x1fe3fcfcUL, 0xc879b1b1UL, 0xedb65b5bUL, - 0xbed46a6aUL, 0x468dcbcbUL, 0xd967bebeUL, 0x4b723939UL, - 0xde944a4aUL, 0xd4984c4cUL, 0xe8b05858UL, 0x4a85cfcfUL, - 0x6bbbd0d0UL, 0x2ac5efefUL, 0xe54faaaaUL, 0x16edfbfbUL, - 0xc5864343UL, 0xd79a4d4dUL, 0x55663333UL, 0x94118585UL, - 0xcf8a4545UL, 0x10e9f9f9UL, 0x06040202UL, 0x81fe7f7fUL, - 0xf0a05050UL, 0x44783c3cUL, 0xba259f9fUL, 0xe34ba8a8UL, - 0xf3a25151UL, 0xfe5da3a3UL, 0xc0804040UL, 0x8a058f8fUL, - 0xad3f9292UL, 0xbc219d9dUL, 0x48703838UL, 0x04f1f5f5UL, - 0xdf63bcbcUL, 0xc177b6b6UL, 0x75afdadaUL, 0x63422121UL, - 0x30201010UL, 0x1ae5ffffUL, 0x0efdf3f3UL, 0x6dbfd2d2UL, - 0x4c81cdcdUL, 0x14180c0cUL, 0x35261313UL, 0x2fc3ececUL, - 0xe1be5f5fUL, 0xa2359797UL, 0xcc884444UL, 0x392e1717UL, - 0x5793c4c4UL, 0xf255a7a7UL, 0x82fc7e7eUL, 0x477a3d3dUL, - 0xacc86464UL, 0xe7ba5d5dUL, 0x2b321919UL, 0x95e67373UL, - 0xa0c06060UL, 0x98198181UL, 0xd19e4f4fUL, 0x7fa3dcdcUL, - 0x66442222UL, 0x7e542a2aUL, 0xab3b9090UL, 0x830b8888UL, - 0xca8c4646UL, 0x29c7eeeeUL, 0xd36bb8b8UL, 0x3c281414UL, - 0x79a7dedeUL, 0xe2bc5e5eUL, 0x1d160b0bUL, 0x76addbdbUL, - 0x3bdbe0e0UL, 0x56643232UL, 0x4e743a3aUL, 0x1e140a0aUL, - 0xdb924949UL, 0x0a0c0606UL, 0x6c482424UL, 0xe4b85c5cUL, - 0x5d9fc2c2UL, 0x6ebdd3d3UL, 0xef43acacUL, 0xa6c46262UL, - 0xa8399191UL, 0xa4319595UL, 0x37d3e4e4UL, 0x8bf27979UL, - 0x32d5e7e7UL, 0x438bc8c8UL, 0x596e3737UL, 0xb7da6d6dUL, - 0x8c018d8dUL, 0x64b1d5d5UL, 0xd29c4e4eUL, 0xe049a9a9UL, - 0xb4d86c6cUL, 0xfaac5656UL, 0x07f3f4f4UL, 0x25cfeaeaUL, - 0xafca6565UL, 0x8ef47a7aUL, 0xe947aeaeUL, 0x18100808UL, - 0xd56fbabaUL, 0x88f07878UL, 0x6f4a2525UL, 0x725c2e2eUL, - 0x24381c1cUL, 0xf157a6a6UL, 0xc773b4b4UL, 0x5197c6c6UL, - 0x23cbe8e8UL, 0x7ca1ddddUL, 0x9ce87474UL, 0x213e1f1fUL, - 0xdd964b4bUL, 0xdc61bdbdUL, 0x860d8b8bUL, 0x850f8a8aUL, - 0x90e07070UL, 0x427c3e3eUL, 0xc471b5b5UL, 0xaacc6666UL, - 0xd8904848UL, 0x05060303UL, 0x01f7f6f6UL, 0x121c0e0eUL, - 0xa3c26161UL, 0x5f6a3535UL, 0xf9ae5757UL, 0xd069b9b9UL, - 0x91178686UL, 0x5899c1c1UL, 0x273a1d1dUL, 0xb9279e9eUL, - 0x38d9e1e1UL, 0x13ebf8f8UL, 0xb32b9898UL, 0x33221111UL, - 0xbbd26969UL, 0x70a9d9d9UL, 0x89078e8eUL, 0xa7339494UL, - 0xb62d9b9bUL, 0x223c1e1eUL, 0x92158787UL, 0x20c9e9e9UL, - 0x4987ceceUL, 0xffaa5555UL, 0x78502828UL, 0x7aa5dfdfUL, - 0x8f038c8cUL, 0xf859a1a1UL, 0x80098989UL, 0x171a0d0dUL, - 0xda65bfbfUL, 0x31d7e6e6UL, 0xc6844242UL, 0xb8d06868UL, - 0xc3824141UL, 0xb0299999UL, 0x775a2d2dUL, 0x111e0f0fUL, - 0xcb7bb0b0UL, 0xfca85454UL, 0xd66dbbbbUL, 0x3a2c1616UL, -}; -static const unsigned int Te2[256] = { - 0x63a5c663UL, 0x7c84f87cUL, 0x7799ee77UL, 0x7b8df67bUL, - 0xf20dfff2UL, 0x6bbdd66bUL, 0x6fb1de6fUL, 0xc55491c5UL, - 0x30506030UL, 0x01030201UL, 0x67a9ce67UL, 0x2b7d562bUL, - 0xfe19e7feUL, 0xd762b5d7UL, 0xabe64dabUL, 0x769aec76UL, - 0xca458fcaUL, 0x829d1f82UL, 0xc94089c9UL, 0x7d87fa7dUL, - 0xfa15effaUL, 0x59ebb259UL, 0x47c98e47UL, 0xf00bfbf0UL, - 0xadec41adUL, 0xd467b3d4UL, 0xa2fd5fa2UL, 0xafea45afUL, - 0x9cbf239cUL, 0xa4f753a4UL, 0x7296e472UL, 0xc05b9bc0UL, - 0xb7c275b7UL, 0xfd1ce1fdUL, 0x93ae3d93UL, 0x266a4c26UL, - 0x365a6c36UL, 0x3f417e3fUL, 0xf702f5f7UL, 0xcc4f83ccUL, - 0x345c6834UL, 0xa5f451a5UL, 0xe534d1e5UL, 0xf108f9f1UL, - 0x7193e271UL, 0xd873abd8UL, 0x31536231UL, 0x153f2a15UL, - 0x040c0804UL, 0xc75295c7UL, 0x23654623UL, 0xc35e9dc3UL, - 0x18283018UL, 0x96a13796UL, 0x050f0a05UL, 0x9ab52f9aUL, - 0x07090e07UL, 0x12362412UL, 0x809b1b80UL, 0xe23ddfe2UL, - 0xeb26cdebUL, 0x27694e27UL, 0xb2cd7fb2UL, 0x759fea75UL, - 0x091b1209UL, 0x839e1d83UL, 0x2c74582cUL, 0x1a2e341aUL, - 0x1b2d361bUL, 0x6eb2dc6eUL, 0x5aeeb45aUL, 0xa0fb5ba0UL, - 0x52f6a452UL, 0x3b4d763bUL, 0xd661b7d6UL, 0xb3ce7db3UL, - 0x297b5229UL, 0xe33edde3UL, 0x2f715e2fUL, 0x84971384UL, - 0x53f5a653UL, 0xd168b9d1UL, 0x00000000UL, 0xed2cc1edUL, - 0x20604020UL, 0xfc1fe3fcUL, 0xb1c879b1UL, 0x5bedb65bUL, - 0x6abed46aUL, 0xcb468dcbUL, 0xbed967beUL, 0x394b7239UL, - 0x4ade944aUL, 0x4cd4984cUL, 0x58e8b058UL, 0xcf4a85cfUL, - 0xd06bbbd0UL, 0xef2ac5efUL, 0xaae54faaUL, 0xfb16edfbUL, - 0x43c58643UL, 0x4dd79a4dUL, 0x33556633UL, 0x85941185UL, - 0x45cf8a45UL, 0xf910e9f9UL, 0x02060402UL, 0x7f81fe7fUL, - 0x50f0a050UL, 0x3c44783cUL, 0x9fba259fUL, 0xa8e34ba8UL, - 0x51f3a251UL, 0xa3fe5da3UL, 0x40c08040UL, 0x8f8a058fUL, - 0x92ad3f92UL, 0x9dbc219dUL, 0x38487038UL, 0xf504f1f5UL, - 0xbcdf63bcUL, 0xb6c177b6UL, 0xda75afdaUL, 0x21634221UL, - 0x10302010UL, 0xff1ae5ffUL, 0xf30efdf3UL, 0xd26dbfd2UL, - 0xcd4c81cdUL, 0x0c14180cUL, 0x13352613UL, 0xec2fc3ecUL, - 0x5fe1be5fUL, 0x97a23597UL, 0x44cc8844UL, 0x17392e17UL, - 0xc45793c4UL, 0xa7f255a7UL, 0x7e82fc7eUL, 0x3d477a3dUL, - 0x64acc864UL, 0x5de7ba5dUL, 0x192b3219UL, 0x7395e673UL, - 0x60a0c060UL, 0x81981981UL, 0x4fd19e4fUL, 0xdc7fa3dcUL, - 0x22664422UL, 0x2a7e542aUL, 0x90ab3b90UL, 0x88830b88UL, - 0x46ca8c46UL, 0xee29c7eeUL, 0xb8d36bb8UL, 0x143c2814UL, - 0xde79a7deUL, 0x5ee2bc5eUL, 0x0b1d160bUL, 0xdb76addbUL, - 0xe03bdbe0UL, 0x32566432UL, 0x3a4e743aUL, 0x0a1e140aUL, - 0x49db9249UL, 0x060a0c06UL, 0x246c4824UL, 0x5ce4b85cUL, - 0xc25d9fc2UL, 0xd36ebdd3UL, 0xacef43acUL, 0x62a6c462UL, - 0x91a83991UL, 0x95a43195UL, 0xe437d3e4UL, 0x798bf279UL, - 0xe732d5e7UL, 0xc8438bc8UL, 0x37596e37UL, 0x6db7da6dUL, - 0x8d8c018dUL, 0xd564b1d5UL, 0x4ed29c4eUL, 0xa9e049a9UL, - 0x6cb4d86cUL, 0x56faac56UL, 0xf407f3f4UL, 0xea25cfeaUL, - 0x65afca65UL, 0x7a8ef47aUL, 0xaee947aeUL, 0x08181008UL, - 0xbad56fbaUL, 0x7888f078UL, 0x256f4a25UL, 0x2e725c2eUL, - 0x1c24381cUL, 0xa6f157a6UL, 0xb4c773b4UL, 0xc65197c6UL, - 0xe823cbe8UL, 0xdd7ca1ddUL, 0x749ce874UL, 0x1f213e1fUL, - 0x4bdd964bUL, 0xbddc61bdUL, 0x8b860d8bUL, 0x8a850f8aUL, - 0x7090e070UL, 0x3e427c3eUL, 0xb5c471b5UL, 0x66aacc66UL, - 0x48d89048UL, 0x03050603UL, 0xf601f7f6UL, 0x0e121c0eUL, - 0x61a3c261UL, 0x355f6a35UL, 0x57f9ae57UL, 0xb9d069b9UL, - 0x86911786UL, 0xc15899c1UL, 0x1d273a1dUL, 0x9eb9279eUL, - 0xe138d9e1UL, 0xf813ebf8UL, 0x98b32b98UL, 0x11332211UL, - 0x69bbd269UL, 0xd970a9d9UL, 0x8e89078eUL, 0x94a73394UL, - 0x9bb62d9bUL, 0x1e223c1eUL, 0x87921587UL, 0xe920c9e9UL, - 0xce4987ceUL, 0x55ffaa55UL, 0x28785028UL, 0xdf7aa5dfUL, - 0x8c8f038cUL, 0xa1f859a1UL, 0x89800989UL, 0x0d171a0dUL, - 0xbfda65bfUL, 0xe631d7e6UL, 0x42c68442UL, 0x68b8d068UL, - 0x41c38241UL, 0x99b02999UL, 0x2d775a2dUL, 0x0f111e0fUL, - 0xb0cb7bb0UL, 0x54fca854UL, 0xbbd66dbbUL, 0x163a2c16UL, -}; -static const unsigned int Te3[256] = { - 0x6363a5c6UL, 0x7c7c84f8UL, 0x777799eeUL, 0x7b7b8df6UL, - 0xf2f20dffUL, 0x6b6bbdd6UL, 0x6f6fb1deUL, 0xc5c55491UL, - 0x30305060UL, 0x01010302UL, 0x6767a9ceUL, 0x2b2b7d56UL, - 0xfefe19e7UL, 0xd7d762b5UL, 0xababe64dUL, 0x76769aecUL, - 0xcaca458fUL, 0x82829d1fUL, 0xc9c94089UL, 0x7d7d87faUL, - 0xfafa15efUL, 0x5959ebb2UL, 0x4747c98eUL, 0xf0f00bfbUL, - 0xadadec41UL, 0xd4d467b3UL, 0xa2a2fd5fUL, 0xafafea45UL, - 0x9c9cbf23UL, 0xa4a4f753UL, 0x727296e4UL, 0xc0c05b9bUL, - 0xb7b7c275UL, 0xfdfd1ce1UL, 0x9393ae3dUL, 0x26266a4cUL, - 0x36365a6cUL, 0x3f3f417eUL, 0xf7f702f5UL, 0xcccc4f83UL, - 0x34345c68UL, 0xa5a5f451UL, 0xe5e534d1UL, 0xf1f108f9UL, - 0x717193e2UL, 0xd8d873abUL, 0x31315362UL, 0x15153f2aUL, - 0x04040c08UL, 0xc7c75295UL, 0x23236546UL, 0xc3c35e9dUL, - 0x18182830UL, 0x9696a137UL, 0x05050f0aUL, 0x9a9ab52fUL, - 0x0707090eUL, 0x12123624UL, 0x80809b1bUL, 0xe2e23ddfUL, - 0xebeb26cdUL, 0x2727694eUL, 0xb2b2cd7fUL, 0x75759feaUL, - 0x09091b12UL, 0x83839e1dUL, 0x2c2c7458UL, 0x1a1a2e34UL, - 0x1b1b2d36UL, 0x6e6eb2dcUL, 0x5a5aeeb4UL, 0xa0a0fb5bUL, - 0x5252f6a4UL, 0x3b3b4d76UL, 0xd6d661b7UL, 0xb3b3ce7dUL, - 0x29297b52UL, 0xe3e33eddUL, 0x2f2f715eUL, 0x84849713UL, - 0x5353f5a6UL, 0xd1d168b9UL, 0x00000000UL, 0xeded2cc1UL, - 0x20206040UL, 0xfcfc1fe3UL, 0xb1b1c879UL, 0x5b5bedb6UL, - 0x6a6abed4UL, 0xcbcb468dUL, 0xbebed967UL, 0x39394b72UL, - 0x4a4ade94UL, 0x4c4cd498UL, 0x5858e8b0UL, 0xcfcf4a85UL, - 0xd0d06bbbUL, 0xefef2ac5UL, 0xaaaae54fUL, 0xfbfb16edUL, - 0x4343c586UL, 0x4d4dd79aUL, 0x33335566UL, 0x85859411UL, - 0x4545cf8aUL, 0xf9f910e9UL, 0x02020604UL, 0x7f7f81feUL, - 0x5050f0a0UL, 0x3c3c4478UL, 0x9f9fba25UL, 0xa8a8e34bUL, - 0x5151f3a2UL, 0xa3a3fe5dUL, 0x4040c080UL, 0x8f8f8a05UL, - 0x9292ad3fUL, 0x9d9dbc21UL, 0x38384870UL, 0xf5f504f1UL, - 0xbcbcdf63UL, 0xb6b6c177UL, 0xdada75afUL, 0x21216342UL, - 0x10103020UL, 0xffff1ae5UL, 0xf3f30efdUL, 0xd2d26dbfUL, - 0xcdcd4c81UL, 0x0c0c1418UL, 0x13133526UL, 0xecec2fc3UL, - 0x5f5fe1beUL, 0x9797a235UL, 0x4444cc88UL, 0x1717392eUL, - 0xc4c45793UL, 0xa7a7f255UL, 0x7e7e82fcUL, 0x3d3d477aUL, - 0x6464acc8UL, 0x5d5de7baUL, 0x19192b32UL, 0x737395e6UL, - 0x6060a0c0UL, 0x81819819UL, 0x4f4fd19eUL, 0xdcdc7fa3UL, - 0x22226644UL, 0x2a2a7e54UL, 0x9090ab3bUL, 0x8888830bUL, - 0x4646ca8cUL, 0xeeee29c7UL, 0xb8b8d36bUL, 0x14143c28UL, - 0xdede79a7UL, 0x5e5ee2bcUL, 0x0b0b1d16UL, 0xdbdb76adUL, - 0xe0e03bdbUL, 0x32325664UL, 0x3a3a4e74UL, 0x0a0a1e14UL, - 0x4949db92UL, 0x06060a0cUL, 0x24246c48UL, 0x5c5ce4b8UL, - 0xc2c25d9fUL, 0xd3d36ebdUL, 0xacacef43UL, 0x6262a6c4UL, - 0x9191a839UL, 0x9595a431UL, 0xe4e437d3UL, 0x79798bf2UL, - 0xe7e732d5UL, 0xc8c8438bUL, 0x3737596eUL, 0x6d6db7daUL, - 0x8d8d8c01UL, 0xd5d564b1UL, 0x4e4ed29cUL, 0xa9a9e049UL, - 0x6c6cb4d8UL, 0x5656faacUL, 0xf4f407f3UL, 0xeaea25cfUL, - 0x6565afcaUL, 0x7a7a8ef4UL, 0xaeaee947UL, 0x08081810UL, - 0xbabad56fUL, 0x787888f0UL, 0x25256f4aUL, 0x2e2e725cUL, - 0x1c1c2438UL, 0xa6a6f157UL, 0xb4b4c773UL, 0xc6c65197UL, - 0xe8e823cbUL, 0xdddd7ca1UL, 0x74749ce8UL, 0x1f1f213eUL, - 0x4b4bdd96UL, 0xbdbddc61UL, 0x8b8b860dUL, 0x8a8a850fUL, - 0x707090e0UL, 0x3e3e427cUL, 0xb5b5c471UL, 0x6666aaccUL, - 0x4848d890UL, 0x03030506UL, 0xf6f601f7UL, 0x0e0e121cUL, - 0x6161a3c2UL, 0x35355f6aUL, 0x5757f9aeUL, 0xb9b9d069UL, - 0x86869117UL, 0xc1c15899UL, 0x1d1d273aUL, 0x9e9eb927UL, - 0xe1e138d9UL, 0xf8f813ebUL, 0x9898b32bUL, 0x11113322UL, - 0x6969bbd2UL, 0xd9d970a9UL, 0x8e8e8907UL, 0x9494a733UL, - 0x9b9bb62dUL, 0x1e1e223cUL, 0x87879215UL, 0xe9e920c9UL, - 0xcece4987UL, 0x5555ffaaUL, 0x28287850UL, 0xdfdf7aa5UL, - 0x8c8c8f03UL, 0xa1a1f859UL, 0x89898009UL, 0x0d0d171aUL, - 0xbfbfda65UL, 0xe6e631d7UL, 0x4242c684UL, 0x6868b8d0UL, - 0x4141c382UL, 0x9999b029UL, 0x2d2d775aUL, 0x0f0f111eUL, - 0xb0b0cb7bUL, 0x5454fca8UL, 0xbbbbd66dUL, 0x16163a2cUL, -}; -static const unsigned int Te4[256] = { - 0x63636363UL, 0x7c7c7c7cUL, 0x77777777UL, 0x7b7b7b7bUL, - 0xf2f2f2f2UL, 0x6b6b6b6bUL, 0x6f6f6f6fUL, 0xc5c5c5c5UL, - 0x30303030UL, 0x01010101UL, 0x67676767UL, 0x2b2b2b2bUL, - 0xfefefefeUL, 0xd7d7d7d7UL, 0xababababUL, 0x76767676UL, - 0xcacacacaUL, 0x82828282UL, 0xc9c9c9c9UL, 0x7d7d7d7dUL, - 0xfafafafaUL, 0x59595959UL, 0x47474747UL, 0xf0f0f0f0UL, - 0xadadadadUL, 0xd4d4d4d4UL, 0xa2a2a2a2UL, 0xafafafafUL, - 0x9c9c9c9cUL, 0xa4a4a4a4UL, 0x72727272UL, 0xc0c0c0c0UL, - 0xb7b7b7b7UL, 0xfdfdfdfdUL, 0x93939393UL, 0x26262626UL, - 0x36363636UL, 0x3f3f3f3fUL, 0xf7f7f7f7UL, 0xccccccccUL, - 0x34343434UL, 0xa5a5a5a5UL, 0xe5e5e5e5UL, 0xf1f1f1f1UL, - 0x71717171UL, 0xd8d8d8d8UL, 0x31313131UL, 0x15151515UL, - 0x04040404UL, 0xc7c7c7c7UL, 0x23232323UL, 0xc3c3c3c3UL, - 0x18181818UL, 0x96969696UL, 0x05050505UL, 0x9a9a9a9aUL, - 0x07070707UL, 0x12121212UL, 0x80808080UL, 0xe2e2e2e2UL, - 0xebebebebUL, 0x27272727UL, 0xb2b2b2b2UL, 0x75757575UL, - 0x09090909UL, 0x83838383UL, 0x2c2c2c2cUL, 0x1a1a1a1aUL, - 0x1b1b1b1bUL, 0x6e6e6e6eUL, 0x5a5a5a5aUL, 0xa0a0a0a0UL, - 0x52525252UL, 0x3b3b3b3bUL, 0xd6d6d6d6UL, 0xb3b3b3b3UL, - 0x29292929UL, 0xe3e3e3e3UL, 0x2f2f2f2fUL, 0x84848484UL, - 0x53535353UL, 0xd1d1d1d1UL, 0x00000000UL, 0xededededUL, - 0x20202020UL, 0xfcfcfcfcUL, 0xb1b1b1b1UL, 0x5b5b5b5bUL, - 0x6a6a6a6aUL, 0xcbcbcbcbUL, 0xbebebebeUL, 0x39393939UL, - 0x4a4a4a4aUL, 0x4c4c4c4cUL, 0x58585858UL, 0xcfcfcfcfUL, - 0xd0d0d0d0UL, 0xefefefefUL, 0xaaaaaaaaUL, 0xfbfbfbfbUL, - 0x43434343UL, 0x4d4d4d4dUL, 0x33333333UL, 0x85858585UL, - 0x45454545UL, 0xf9f9f9f9UL, 0x02020202UL, 0x7f7f7f7fUL, - 0x50505050UL, 0x3c3c3c3cUL, 0x9f9f9f9fUL, 0xa8a8a8a8UL, - 0x51515151UL, 0xa3a3a3a3UL, 0x40404040UL, 0x8f8f8f8fUL, - 0x92929292UL, 0x9d9d9d9dUL, 0x38383838UL, 0xf5f5f5f5UL, - 0xbcbcbcbcUL, 0xb6b6b6b6UL, 0xdadadadaUL, 0x21212121UL, - 0x10101010UL, 0xffffffffUL, 0xf3f3f3f3UL, 0xd2d2d2d2UL, - 0xcdcdcdcdUL, 0x0c0c0c0cUL, 0x13131313UL, 0xececececUL, - 0x5f5f5f5fUL, 0x97979797UL, 0x44444444UL, 0x17171717UL, - 0xc4c4c4c4UL, 0xa7a7a7a7UL, 0x7e7e7e7eUL, 0x3d3d3d3dUL, - 0x64646464UL, 0x5d5d5d5dUL, 0x19191919UL, 0x73737373UL, - 0x60606060UL, 0x81818181UL, 0x4f4f4f4fUL, 0xdcdcdcdcUL, - 0x22222222UL, 0x2a2a2a2aUL, 0x90909090UL, 0x88888888UL, - 0x46464646UL, 0xeeeeeeeeUL, 0xb8b8b8b8UL, 0x14141414UL, - 0xdedededeUL, 0x5e5e5e5eUL, 0x0b0b0b0bUL, 0xdbdbdbdbUL, - 0xe0e0e0e0UL, 0x32323232UL, 0x3a3a3a3aUL, 0x0a0a0a0aUL, - 0x49494949UL, 0x06060606UL, 0x24242424UL, 0x5c5c5c5cUL, - 0xc2c2c2c2UL, 0xd3d3d3d3UL, 0xacacacacUL, 0x62626262UL, - 0x91919191UL, 0x95959595UL, 0xe4e4e4e4UL, 0x79797979UL, - 0xe7e7e7e7UL, 0xc8c8c8c8UL, 0x37373737UL, 0x6d6d6d6dUL, - 0x8d8d8d8dUL, 0xd5d5d5d5UL, 0x4e4e4e4eUL, 0xa9a9a9a9UL, - 0x6c6c6c6cUL, 0x56565656UL, 0xf4f4f4f4UL, 0xeaeaeaeaUL, - 0x65656565UL, 0x7a7a7a7aUL, 0xaeaeaeaeUL, 0x08080808UL, - 0xbabababaUL, 0x78787878UL, 0x25252525UL, 0x2e2e2e2eUL, - 0x1c1c1c1cUL, 0xa6a6a6a6UL, 0xb4b4b4b4UL, 0xc6c6c6c6UL, - 0xe8e8e8e8UL, 0xddddddddUL, 0x74747474UL, 0x1f1f1f1fUL, - 0x4b4b4b4bUL, 0xbdbdbdbdUL, 0x8b8b8b8bUL, 0x8a8a8a8aUL, - 0x70707070UL, 0x3e3e3e3eUL, 0xb5b5b5b5UL, 0x66666666UL, - 0x48484848UL, 0x03030303UL, 0xf6f6f6f6UL, 0x0e0e0e0eUL, - 0x61616161UL, 0x35353535UL, 0x57575757UL, 0xb9b9b9b9UL, - 0x86868686UL, 0xc1c1c1c1UL, 0x1d1d1d1dUL, 0x9e9e9e9eUL, - 0xe1e1e1e1UL, 0xf8f8f8f8UL, 0x98989898UL, 0x11111111UL, - 0x69696969UL, 0xd9d9d9d9UL, 0x8e8e8e8eUL, 0x94949494UL, - 0x9b9b9b9bUL, 0x1e1e1e1eUL, 0x87878787UL, 0xe9e9e9e9UL, - 0xcecececeUL, 0x55555555UL, 0x28282828UL, 0xdfdfdfdfUL, - 0x8c8c8c8cUL, 0xa1a1a1a1UL, 0x89898989UL, 0x0d0d0d0dUL, - 0xbfbfbfbfUL, 0xe6e6e6e6UL, 0x42424242UL, 0x68686868UL, - 0x41414141UL, 0x99999999UL, 0x2d2d2d2dUL, 0x0f0f0f0fUL, - 0xb0b0b0b0UL, 0x54545454UL, 0xbbbbbbbbUL, 0x16161616UL, -}; -static const unsigned int Td0[256] = { - 0x51f4a750UL, 0x7e416553UL, 0x1a17a4c3UL, 0x3a275e96UL, - 0x3bab6bcbUL, 0x1f9d45f1UL, 0xacfa58abUL, 0x4be30393UL, - 0x2030fa55UL, 0xad766df6UL, 0x88cc7691UL, 0xf5024c25UL, - 0x4fe5d7fcUL, 0xc52acbd7UL, 0x26354480UL, 0xb562a38fUL, - 0xdeb15a49UL, 0x25ba1b67UL, 0x45ea0e98UL, 0x5dfec0e1UL, - 0xc32f7502UL, 0x814cf012UL, 0x8d4697a3UL, 0x6bd3f9c6UL, - 0x038f5fe7UL, 0x15929c95UL, 0xbf6d7aebUL, 0x955259daUL, - 0xd4be832dUL, 0x587421d3UL, 0x49e06929UL, 0x8ec9c844UL, - 0x75c2896aUL, 0xf48e7978UL, 0x99583e6bUL, 0x27b971ddUL, - 0xbee14fb6UL, 0xf088ad17UL, 0xc920ac66UL, 0x7dce3ab4UL, - 0x63df4a18UL, 0xe51a3182UL, 0x97513360UL, 0x62537f45UL, - 0xb16477e0UL, 0xbb6bae84UL, 0xfe81a01cUL, 0xf9082b94UL, - 0x70486858UL, 0x8f45fd19UL, 0x94de6c87UL, 0x527bf8b7UL, - 0xab73d323UL, 0x724b02e2UL, 0xe31f8f57UL, 0x6655ab2aUL, - 0xb2eb2807UL, 0x2fb5c203UL, 0x86c57b9aUL, 0xd33708a5UL, - 0x302887f2UL, 0x23bfa5b2UL, 0x02036abaUL, 0xed16825cUL, - 0x8acf1c2bUL, 0xa779b492UL, 0xf307f2f0UL, 0x4e69e2a1UL, - 0x65daf4cdUL, 0x0605bed5UL, 0xd134621fUL, 0xc4a6fe8aUL, - 0x342e539dUL, 0xa2f355a0UL, 0x058ae132UL, 0xa4f6eb75UL, - 0x0b83ec39UL, 0x4060efaaUL, 0x5e719f06UL, 0xbd6e1051UL, - 0x3e218af9UL, 0x96dd063dUL, 0xdd3e05aeUL, 0x4de6bd46UL, - 0x91548db5UL, 0x71c45d05UL, 0x0406d46fUL, 0x605015ffUL, - 0x1998fb24UL, 0xd6bde997UL, 0x894043ccUL, 0x67d99e77UL, - 0xb0e842bdUL, 0x07898b88UL, 0xe7195b38UL, 0x79c8eedbUL, - 0xa17c0a47UL, 0x7c420fe9UL, 0xf8841ec9UL, 0x00000000UL, - 0x09808683UL, 0x322bed48UL, 0x1e1170acUL, 0x6c5a724eUL, - 0xfd0efffbUL, 0x0f853856UL, 0x3daed51eUL, 0x362d3927UL, - 0x0a0fd964UL, 0x685ca621UL, 0x9b5b54d1UL, 0x24362e3aUL, - 0x0c0a67b1UL, 0x9357e70fUL, 0xb4ee96d2UL, 0x1b9b919eUL, - 0x80c0c54fUL, 0x61dc20a2UL, 0x5a774b69UL, 0x1c121a16UL, - 0xe293ba0aUL, 0xc0a02ae5UL, 0x3c22e043UL, 0x121b171dUL, - 0x0e090d0bUL, 0xf28bc7adUL, 0x2db6a8b9UL, 0x141ea9c8UL, - 0x57f11985UL, 0xaf75074cUL, 0xee99ddbbUL, 0xa37f60fdUL, - 0xf701269fUL, 0x5c72f5bcUL, 0x44663bc5UL, 0x5bfb7e34UL, - 0x8b432976UL, 0xcb23c6dcUL, 0xb6edfc68UL, 0xb8e4f163UL, - 0xd731dccaUL, 0x42638510UL, 0x13972240UL, 0x84c61120UL, - 0x854a247dUL, 0xd2bb3df8UL, 0xaef93211UL, 0xc729a16dUL, - 0x1d9e2f4bUL, 0xdcb230f3UL, 0x0d8652ecUL, 0x77c1e3d0UL, - 0x2bb3166cUL, 0xa970b999UL, 0x119448faUL, 0x47e96422UL, - 0xa8fc8cc4UL, 0xa0f03f1aUL, 0x567d2cd8UL, 0x223390efUL, - 0x87494ec7UL, 0xd938d1c1UL, 0x8ccaa2feUL, 0x98d40b36UL, - 0xa6f581cfUL, 0xa57ade28UL, 0xdab78e26UL, 0x3fadbfa4UL, - 0x2c3a9de4UL, 0x5078920dUL, 0x6a5fcc9bUL, 0x547e4662UL, - 0xf68d13c2UL, 0x90d8b8e8UL, 0x2e39f75eUL, 0x82c3aff5UL, - 0x9f5d80beUL, 0x69d0937cUL, 0x6fd52da9UL, 0xcf2512b3UL, - 0xc8ac993bUL, 0x10187da7UL, 0xe89c636eUL, 0xdb3bbb7bUL, - 0xcd267809UL, 0x6e5918f4UL, 0xec9ab701UL, 0x834f9aa8UL, - 0xe6956e65UL, 0xaaffe67eUL, 0x21bccf08UL, 0xef15e8e6UL, - 0xbae79bd9UL, 0x4a6f36ceUL, 0xea9f09d4UL, 0x29b07cd6UL, - 0x31a4b2afUL, 0x2a3f2331UL, 0xc6a59430UL, 0x35a266c0UL, - 0x744ebc37UL, 0xfc82caa6UL, 0xe090d0b0UL, 0x33a7d815UL, - 0xf104984aUL, 0x41ecdaf7UL, 0x7fcd500eUL, 0x1791f62fUL, - 0x764dd68dUL, 0x43efb04dUL, 0xccaa4d54UL, 0xe49604dfUL, - 0x9ed1b5e3UL, 0x4c6a881bUL, 0xc12c1fb8UL, 0x4665517fUL, - 0x9d5eea04UL, 0x018c355dUL, 0xfa877473UL, 0xfb0b412eUL, - 0xb3671d5aUL, 0x92dbd252UL, 0xe9105633UL, 0x6dd64713UL, - 0x9ad7618cUL, 0x37a10c7aUL, 0x59f8148eUL, 0xeb133c89UL, - 0xcea927eeUL, 0xb761c935UL, 0xe11ce5edUL, 0x7a47b13cUL, - 0x9cd2df59UL, 0x55f2733fUL, 0x1814ce79UL, 0x73c737bfUL, - 0x53f7cdeaUL, 0x5ffdaa5bUL, 0xdf3d6f14UL, 0x7844db86UL, - 0xcaaff381UL, 0xb968c43eUL, 0x3824342cUL, 0xc2a3405fUL, - 0x161dc372UL, 0xbce2250cUL, 0x283c498bUL, 0xff0d9541UL, - 0x39a80171UL, 0x080cb3deUL, 0xd8b4e49cUL, 0x6456c190UL, - 0x7bcb8461UL, 0xd532b670UL, 0x486c5c74UL, 0xd0b85742UL, -}; -static const unsigned int Td1[256] = { - 0x5051f4a7UL, 0x537e4165UL, 0xc31a17a4UL, 0x963a275eUL, - 0xcb3bab6bUL, 0xf11f9d45UL, 0xabacfa58UL, 0x934be303UL, - 0x552030faUL, 0xf6ad766dUL, 0x9188cc76UL, 0x25f5024cUL, - 0xfc4fe5d7UL, 0xd7c52acbUL, 0x80263544UL, 0x8fb562a3UL, - 0x49deb15aUL, 0x6725ba1bUL, 0x9845ea0eUL, 0xe15dfec0UL, - 0x02c32f75UL, 0x12814cf0UL, 0xa38d4697UL, 0xc66bd3f9UL, - 0xe7038f5fUL, 0x9515929cUL, 0xebbf6d7aUL, 0xda955259UL, - 0x2dd4be83UL, 0xd3587421UL, 0x2949e069UL, 0x448ec9c8UL, - 0x6a75c289UL, 0x78f48e79UL, 0x6b99583eUL, 0xdd27b971UL, - 0xb6bee14fUL, 0x17f088adUL, 0x66c920acUL, 0xb47dce3aUL, - 0x1863df4aUL, 0x82e51a31UL, 0x60975133UL, 0x4562537fUL, - 0xe0b16477UL, 0x84bb6baeUL, 0x1cfe81a0UL, 0x94f9082bUL, - 0x58704868UL, 0x198f45fdUL, 0x8794de6cUL, 0xb7527bf8UL, - 0x23ab73d3UL, 0xe2724b02UL, 0x57e31f8fUL, 0x2a6655abUL, - 0x07b2eb28UL, 0x032fb5c2UL, 0x9a86c57bUL, 0xa5d33708UL, - 0xf2302887UL, 0xb223bfa5UL, 0xba02036aUL, 0x5ced1682UL, - 0x2b8acf1cUL, 0x92a779b4UL, 0xf0f307f2UL, 0xa14e69e2UL, - 0xcd65daf4UL, 0xd50605beUL, 0x1fd13462UL, 0x8ac4a6feUL, - 0x9d342e53UL, 0xa0a2f355UL, 0x32058ae1UL, 0x75a4f6ebUL, - 0x390b83ecUL, 0xaa4060efUL, 0x065e719fUL, 0x51bd6e10UL, - 0xf93e218aUL, 0x3d96dd06UL, 0xaedd3e05UL, 0x464de6bdUL, - 0xb591548dUL, 0x0571c45dUL, 0x6f0406d4UL, 0xff605015UL, - 0x241998fbUL, 0x97d6bde9UL, 0xcc894043UL, 0x7767d99eUL, - 0xbdb0e842UL, 0x8807898bUL, 0x38e7195bUL, 0xdb79c8eeUL, - 0x47a17c0aUL, 0xe97c420fUL, 0xc9f8841eUL, 0x00000000UL, - 0x83098086UL, 0x48322bedUL, 0xac1e1170UL, 0x4e6c5a72UL, - 0xfbfd0effUL, 0x560f8538UL, 0x1e3daed5UL, 0x27362d39UL, - 0x640a0fd9UL, 0x21685ca6UL, 0xd19b5b54UL, 0x3a24362eUL, - 0xb10c0a67UL, 0x0f9357e7UL, 0xd2b4ee96UL, 0x9e1b9b91UL, - 0x4f80c0c5UL, 0xa261dc20UL, 0x695a774bUL, 0x161c121aUL, - 0x0ae293baUL, 0xe5c0a02aUL, 0x433c22e0UL, 0x1d121b17UL, - 0x0b0e090dUL, 0xadf28bc7UL, 0xb92db6a8UL, 0xc8141ea9UL, - 0x8557f119UL, 0x4caf7507UL, 0xbbee99ddUL, 0xfda37f60UL, - 0x9ff70126UL, 0xbc5c72f5UL, 0xc544663bUL, 0x345bfb7eUL, - 0x768b4329UL, 0xdccb23c6UL, 0x68b6edfcUL, 0x63b8e4f1UL, - 0xcad731dcUL, 0x10426385UL, 0x40139722UL, 0x2084c611UL, - 0x7d854a24UL, 0xf8d2bb3dUL, 0x11aef932UL, 0x6dc729a1UL, - 0x4b1d9e2fUL, 0xf3dcb230UL, 0xec0d8652UL, 0xd077c1e3UL, - 0x6c2bb316UL, 0x99a970b9UL, 0xfa119448UL, 0x2247e964UL, - 0xc4a8fc8cUL, 0x1aa0f03fUL, 0xd8567d2cUL, 0xef223390UL, - 0xc787494eUL, 0xc1d938d1UL, 0xfe8ccaa2UL, 0x3698d40bUL, - 0xcfa6f581UL, 0x28a57adeUL, 0x26dab78eUL, 0xa43fadbfUL, - 0xe42c3a9dUL, 0x0d507892UL, 0x9b6a5fccUL, 0x62547e46UL, - 0xc2f68d13UL, 0xe890d8b8UL, 0x5e2e39f7UL, 0xf582c3afUL, - 0xbe9f5d80UL, 0x7c69d093UL, 0xa96fd52dUL, 0xb3cf2512UL, - 0x3bc8ac99UL, 0xa710187dUL, 0x6ee89c63UL, 0x7bdb3bbbUL, - 0x09cd2678UL, 0xf46e5918UL, 0x01ec9ab7UL, 0xa8834f9aUL, - 0x65e6956eUL, 0x7eaaffe6UL, 0x0821bccfUL, 0xe6ef15e8UL, - 0xd9bae79bUL, 0xce4a6f36UL, 0xd4ea9f09UL, 0xd629b07cUL, - 0xaf31a4b2UL, 0x312a3f23UL, 0x30c6a594UL, 0xc035a266UL, - 0x37744ebcUL, 0xa6fc82caUL, 0xb0e090d0UL, 0x1533a7d8UL, - 0x4af10498UL, 0xf741ecdaUL, 0x0e7fcd50UL, 0x2f1791f6UL, - 0x8d764dd6UL, 0x4d43efb0UL, 0x54ccaa4dUL, 0xdfe49604UL, - 0xe39ed1b5UL, 0x1b4c6a88UL, 0xb8c12c1fUL, 0x7f466551UL, - 0x049d5eeaUL, 0x5d018c35UL, 0x73fa8774UL, 0x2efb0b41UL, - 0x5ab3671dUL, 0x5292dbd2UL, 0x33e91056UL, 0x136dd647UL, - 0x8c9ad761UL, 0x7a37a10cUL, 0x8e59f814UL, 0x89eb133cUL, - 0xeecea927UL, 0x35b761c9UL, 0xede11ce5UL, 0x3c7a47b1UL, - 0x599cd2dfUL, 0x3f55f273UL, 0x791814ceUL, 0xbf73c737UL, - 0xea53f7cdUL, 0x5b5ffdaaUL, 0x14df3d6fUL, 0x867844dbUL, - 0x81caaff3UL, 0x3eb968c4UL, 0x2c382434UL, 0x5fc2a340UL, - 0x72161dc3UL, 0x0cbce225UL, 0x8b283c49UL, 0x41ff0d95UL, - 0x7139a801UL, 0xde080cb3UL, 0x9cd8b4e4UL, 0x906456c1UL, - 0x617bcb84UL, 0x70d532b6UL, 0x74486c5cUL, 0x42d0b857UL, -}; -static const unsigned int Td2[256] = { - 0xa75051f4UL, 0x65537e41UL, 0xa4c31a17UL, 0x5e963a27UL, - 0x6bcb3babUL, 0x45f11f9dUL, 0x58abacfaUL, 0x03934be3UL, - 0xfa552030UL, 0x6df6ad76UL, 0x769188ccUL, 0x4c25f502UL, - 0xd7fc4fe5UL, 0xcbd7c52aUL, 0x44802635UL, 0xa38fb562UL, - 0x5a49deb1UL, 0x1b6725baUL, 0x0e9845eaUL, 0xc0e15dfeUL, - 0x7502c32fUL, 0xf012814cUL, 0x97a38d46UL, 0xf9c66bd3UL, - 0x5fe7038fUL, 0x9c951592UL, 0x7aebbf6dUL, 0x59da9552UL, - 0x832dd4beUL, 0x21d35874UL, 0x692949e0UL, 0xc8448ec9UL, - 0x896a75c2UL, 0x7978f48eUL, 0x3e6b9958UL, 0x71dd27b9UL, - 0x4fb6bee1UL, 0xad17f088UL, 0xac66c920UL, 0x3ab47dceUL, - 0x4a1863dfUL, 0x3182e51aUL, 0x33609751UL, 0x7f456253UL, - 0x77e0b164UL, 0xae84bb6bUL, 0xa01cfe81UL, 0x2b94f908UL, - 0x68587048UL, 0xfd198f45UL, 0x6c8794deUL, 0xf8b7527bUL, - 0xd323ab73UL, 0x02e2724bUL, 0x8f57e31fUL, 0xab2a6655UL, - 0x2807b2ebUL, 0xc2032fb5UL, 0x7b9a86c5UL, 0x08a5d337UL, - 0x87f23028UL, 0xa5b223bfUL, 0x6aba0203UL, 0x825ced16UL, - 0x1c2b8acfUL, 0xb492a779UL, 0xf2f0f307UL, 0xe2a14e69UL, - 0xf4cd65daUL, 0xbed50605UL, 0x621fd134UL, 0xfe8ac4a6UL, - 0x539d342eUL, 0x55a0a2f3UL, 0xe132058aUL, 0xeb75a4f6UL, - 0xec390b83UL, 0xefaa4060UL, 0x9f065e71UL, 0x1051bd6eUL, - 0x8af93e21UL, 0x063d96ddUL, 0x05aedd3eUL, 0xbd464de6UL, - 0x8db59154UL, 0x5d0571c4UL, 0xd46f0406UL, 0x15ff6050UL, - 0xfb241998UL, 0xe997d6bdUL, 0x43cc8940UL, 0x9e7767d9UL, - 0x42bdb0e8UL, 0x8b880789UL, 0x5b38e719UL, 0xeedb79c8UL, - 0x0a47a17cUL, 0x0fe97c42UL, 0x1ec9f884UL, 0x00000000UL, - 0x86830980UL, 0xed48322bUL, 0x70ac1e11UL, 0x724e6c5aUL, - 0xfffbfd0eUL, 0x38560f85UL, 0xd51e3daeUL, 0x3927362dUL, - 0xd9640a0fUL, 0xa621685cUL, 0x54d19b5bUL, 0x2e3a2436UL, - 0x67b10c0aUL, 0xe70f9357UL, 0x96d2b4eeUL, 0x919e1b9bUL, - 0xc54f80c0UL, 0x20a261dcUL, 0x4b695a77UL, 0x1a161c12UL, - 0xba0ae293UL, 0x2ae5c0a0UL, 0xe0433c22UL, 0x171d121bUL, - 0x0d0b0e09UL, 0xc7adf28bUL, 0xa8b92db6UL, 0xa9c8141eUL, - 0x198557f1UL, 0x074caf75UL, 0xddbbee99UL, 0x60fda37fUL, - 0x269ff701UL, 0xf5bc5c72UL, 0x3bc54466UL, 0x7e345bfbUL, - 0x29768b43UL, 0xc6dccb23UL, 0xfc68b6edUL, 0xf163b8e4UL, - 0xdccad731UL, 0x85104263UL, 0x22401397UL, 0x112084c6UL, - 0x247d854aUL, 0x3df8d2bbUL, 0x3211aef9UL, 0xa16dc729UL, - 0x2f4b1d9eUL, 0x30f3dcb2UL, 0x52ec0d86UL, 0xe3d077c1UL, - 0x166c2bb3UL, 0xb999a970UL, 0x48fa1194UL, 0x642247e9UL, - 0x8cc4a8fcUL, 0x3f1aa0f0UL, 0x2cd8567dUL, 0x90ef2233UL, - 0x4ec78749UL, 0xd1c1d938UL, 0xa2fe8ccaUL, 0x0b3698d4UL, - 0x81cfa6f5UL, 0xde28a57aUL, 0x8e26dab7UL, 0xbfa43fadUL, - 0x9de42c3aUL, 0x920d5078UL, 0xcc9b6a5fUL, 0x4662547eUL, - 0x13c2f68dUL, 0xb8e890d8UL, 0xf75e2e39UL, 0xaff582c3UL, - 0x80be9f5dUL, 0x937c69d0UL, 0x2da96fd5UL, 0x12b3cf25UL, - 0x993bc8acUL, 0x7da71018UL, 0x636ee89cUL, 0xbb7bdb3bUL, - 0x7809cd26UL, 0x18f46e59UL, 0xb701ec9aUL, 0x9aa8834fUL, - 0x6e65e695UL, 0xe67eaaffUL, 0xcf0821bcUL, 0xe8e6ef15UL, - 0x9bd9bae7UL, 0x36ce4a6fUL, 0x09d4ea9fUL, 0x7cd629b0UL, - 0xb2af31a4UL, 0x23312a3fUL, 0x9430c6a5UL, 0x66c035a2UL, - 0xbc37744eUL, 0xcaa6fc82UL, 0xd0b0e090UL, 0xd81533a7UL, - 0x984af104UL, 0xdaf741ecUL, 0x500e7fcdUL, 0xf62f1791UL, - 0xd68d764dUL, 0xb04d43efUL, 0x4d54ccaaUL, 0x04dfe496UL, - 0xb5e39ed1UL, 0x881b4c6aUL, 0x1fb8c12cUL, 0x517f4665UL, - 0xea049d5eUL, 0x355d018cUL, 0x7473fa87UL, 0x412efb0bUL, - 0x1d5ab367UL, 0xd25292dbUL, 0x5633e910UL, 0x47136dd6UL, - 0x618c9ad7UL, 0x0c7a37a1UL, 0x148e59f8UL, 0x3c89eb13UL, - 0x27eecea9UL, 0xc935b761UL, 0xe5ede11cUL, 0xb13c7a47UL, - 0xdf599cd2UL, 0x733f55f2UL, 0xce791814UL, 0x37bf73c7UL, - 0xcdea53f7UL, 0xaa5b5ffdUL, 0x6f14df3dUL, 0xdb867844UL, - 0xf381caafUL, 0xc43eb968UL, 0x342c3824UL, 0x405fc2a3UL, - 0xc372161dUL, 0x250cbce2UL, 0x498b283cUL, 0x9541ff0dUL, - 0x017139a8UL, 0xb3de080cUL, 0xe49cd8b4UL, 0xc1906456UL, - 0x84617bcbUL, 0xb670d532UL, 0x5c74486cUL, 0x5742d0b8UL, -}; -static const unsigned int Td3[256] = { - 0xf4a75051UL, 0x4165537eUL, 0x17a4c31aUL, 0x275e963aUL, - 0xab6bcb3bUL, 0x9d45f11fUL, 0xfa58abacUL, 0xe303934bUL, - 0x30fa5520UL, 0x766df6adUL, 0xcc769188UL, 0x024c25f5UL, - 0xe5d7fc4fUL, 0x2acbd7c5UL, 0x35448026UL, 0x62a38fb5UL, - 0xb15a49deUL, 0xba1b6725UL, 0xea0e9845UL, 0xfec0e15dUL, - 0x2f7502c3UL, 0x4cf01281UL, 0x4697a38dUL, 0xd3f9c66bUL, - 0x8f5fe703UL, 0x929c9515UL, 0x6d7aebbfUL, 0x5259da95UL, - 0xbe832dd4UL, 0x7421d358UL, 0xe0692949UL, 0xc9c8448eUL, - 0xc2896a75UL, 0x8e7978f4UL, 0x583e6b99UL, 0xb971dd27UL, - 0xe14fb6beUL, 0x88ad17f0UL, 0x20ac66c9UL, 0xce3ab47dUL, - 0xdf4a1863UL, 0x1a3182e5UL, 0x51336097UL, 0x537f4562UL, - 0x6477e0b1UL, 0x6bae84bbUL, 0x81a01cfeUL, 0x082b94f9UL, - 0x48685870UL, 0x45fd198fUL, 0xde6c8794UL, 0x7bf8b752UL, - 0x73d323abUL, 0x4b02e272UL, 0x1f8f57e3UL, 0x55ab2a66UL, - 0xeb2807b2UL, 0xb5c2032fUL, 0xc57b9a86UL, 0x3708a5d3UL, - 0x2887f230UL, 0xbfa5b223UL, 0x036aba02UL, 0x16825cedUL, - 0xcf1c2b8aUL, 0x79b492a7UL, 0x07f2f0f3UL, 0x69e2a14eUL, - 0xdaf4cd65UL, 0x05bed506UL, 0x34621fd1UL, 0xa6fe8ac4UL, - 0x2e539d34UL, 0xf355a0a2UL, 0x8ae13205UL, 0xf6eb75a4UL, - 0x83ec390bUL, 0x60efaa40UL, 0x719f065eUL, 0x6e1051bdUL, - 0x218af93eUL, 0xdd063d96UL, 0x3e05aeddUL, 0xe6bd464dUL, - 0x548db591UL, 0xc45d0571UL, 0x06d46f04UL, 0x5015ff60UL, - 0x98fb2419UL, 0xbde997d6UL, 0x4043cc89UL, 0xd99e7767UL, - 0xe842bdb0UL, 0x898b8807UL, 0x195b38e7UL, 0xc8eedb79UL, - 0x7c0a47a1UL, 0x420fe97cUL, 0x841ec9f8UL, 0x00000000UL, - 0x80868309UL, 0x2bed4832UL, 0x1170ac1eUL, 0x5a724e6cUL, - 0x0efffbfdUL, 0x8538560fUL, 0xaed51e3dUL, 0x2d392736UL, - 0x0fd9640aUL, 0x5ca62168UL, 0x5b54d19bUL, 0x362e3a24UL, - 0x0a67b10cUL, 0x57e70f93UL, 0xee96d2b4UL, 0x9b919e1bUL, - 0xc0c54f80UL, 0xdc20a261UL, 0x774b695aUL, 0x121a161cUL, - 0x93ba0ae2UL, 0xa02ae5c0UL, 0x22e0433cUL, 0x1b171d12UL, - 0x090d0b0eUL, 0x8bc7adf2UL, 0xb6a8b92dUL, 0x1ea9c814UL, - 0xf1198557UL, 0x75074cafUL, 0x99ddbbeeUL, 0x7f60fda3UL, - 0x01269ff7UL, 0x72f5bc5cUL, 0x663bc544UL, 0xfb7e345bUL, - 0x4329768bUL, 0x23c6dccbUL, 0xedfc68b6UL, 0xe4f163b8UL, - 0x31dccad7UL, 0x63851042UL, 0x97224013UL, 0xc6112084UL, - 0x4a247d85UL, 0xbb3df8d2UL, 0xf93211aeUL, 0x29a16dc7UL, - 0x9e2f4b1dUL, 0xb230f3dcUL, 0x8652ec0dUL, 0xc1e3d077UL, - 0xb3166c2bUL, 0x70b999a9UL, 0x9448fa11UL, 0xe9642247UL, - 0xfc8cc4a8UL, 0xf03f1aa0UL, 0x7d2cd856UL, 0x3390ef22UL, - 0x494ec787UL, 0x38d1c1d9UL, 0xcaa2fe8cUL, 0xd40b3698UL, - 0xf581cfa6UL, 0x7ade28a5UL, 0xb78e26daUL, 0xadbfa43fUL, - 0x3a9de42cUL, 0x78920d50UL, 0x5fcc9b6aUL, 0x7e466254UL, - 0x8d13c2f6UL, 0xd8b8e890UL, 0x39f75e2eUL, 0xc3aff582UL, - 0x5d80be9fUL, 0xd0937c69UL, 0xd52da96fUL, 0x2512b3cfUL, - 0xac993bc8UL, 0x187da710UL, 0x9c636ee8UL, 0x3bbb7bdbUL, - 0x267809cdUL, 0x5918f46eUL, 0x9ab701ecUL, 0x4f9aa883UL, - 0x956e65e6UL, 0xffe67eaaUL, 0xbccf0821UL, 0x15e8e6efUL, - 0xe79bd9baUL, 0x6f36ce4aUL, 0x9f09d4eaUL, 0xb07cd629UL, - 0xa4b2af31UL, 0x3f23312aUL, 0xa59430c6UL, 0xa266c035UL, - 0x4ebc3774UL, 0x82caa6fcUL, 0x90d0b0e0UL, 0xa7d81533UL, - 0x04984af1UL, 0xecdaf741UL, 0xcd500e7fUL, 0x91f62f17UL, - 0x4dd68d76UL, 0xefb04d43UL, 0xaa4d54ccUL, 0x9604dfe4UL, - 0xd1b5e39eUL, 0x6a881b4cUL, 0x2c1fb8c1UL, 0x65517f46UL, - 0x5eea049dUL, 0x8c355d01UL, 0x877473faUL, 0x0b412efbUL, - 0x671d5ab3UL, 0xdbd25292UL, 0x105633e9UL, 0xd647136dUL, - 0xd7618c9aUL, 0xa10c7a37UL, 0xf8148e59UL, 0x133c89ebUL, - 0xa927eeceUL, 0x61c935b7UL, 0x1ce5ede1UL, 0x47b13c7aUL, - 0xd2df599cUL, 0xf2733f55UL, 0x14ce7918UL, 0xc737bf73UL, - 0xf7cdea53UL, 0xfdaa5b5fUL, 0x3d6f14dfUL, 0x44db8678UL, - 0xaff381caUL, 0x68c43eb9UL, 0x24342c38UL, 0xa3405fc2UL, - 0x1dc37216UL, 0xe2250cbcUL, 0x3c498b28UL, 0x0d9541ffUL, - 0xa8017139UL, 0x0cb3de08UL, 0xb4e49cd8UL, 0x56c19064UL, - 0xcb84617bUL, 0x32b670d5UL, 0x6c5c7448UL, 0xb85742d0UL, -}; -static const unsigned int Td4[256] = { - 0x52525252UL, 0x09090909UL, 0x6a6a6a6aUL, 0xd5d5d5d5UL, - 0x30303030UL, 0x36363636UL, 0xa5a5a5a5UL, 0x38383838UL, - 0xbfbfbfbfUL, 0x40404040UL, 0xa3a3a3a3UL, 0x9e9e9e9eUL, - 0x81818181UL, 0xf3f3f3f3UL, 0xd7d7d7d7UL, 0xfbfbfbfbUL, - 0x7c7c7c7cUL, 0xe3e3e3e3UL, 0x39393939UL, 0x82828282UL, - 0x9b9b9b9bUL, 0x2f2f2f2fUL, 0xffffffffUL, 0x87878787UL, - 0x34343434UL, 0x8e8e8e8eUL, 0x43434343UL, 0x44444444UL, - 0xc4c4c4c4UL, 0xdedededeUL, 0xe9e9e9e9UL, 0xcbcbcbcbUL, - 0x54545454UL, 0x7b7b7b7bUL, 0x94949494UL, 0x32323232UL, - 0xa6a6a6a6UL, 0xc2c2c2c2UL, 0x23232323UL, 0x3d3d3d3dUL, - 0xeeeeeeeeUL, 0x4c4c4c4cUL, 0x95959595UL, 0x0b0b0b0bUL, - 0x42424242UL, 0xfafafafaUL, 0xc3c3c3c3UL, 0x4e4e4e4eUL, - 0x08080808UL, 0x2e2e2e2eUL, 0xa1a1a1a1UL, 0x66666666UL, - 0x28282828UL, 0xd9d9d9d9UL, 0x24242424UL, 0xb2b2b2b2UL, - 0x76767676UL, 0x5b5b5b5bUL, 0xa2a2a2a2UL, 0x49494949UL, - 0x6d6d6d6dUL, 0x8b8b8b8bUL, 0xd1d1d1d1UL, 0x25252525UL, - 0x72727272UL, 0xf8f8f8f8UL, 0xf6f6f6f6UL, 0x64646464UL, - 0x86868686UL, 0x68686868UL, 0x98989898UL, 0x16161616UL, - 0xd4d4d4d4UL, 0xa4a4a4a4UL, 0x5c5c5c5cUL, 0xccccccccUL, - 0x5d5d5d5dUL, 0x65656565UL, 0xb6b6b6b6UL, 0x92929292UL, - 0x6c6c6c6cUL, 0x70707070UL, 0x48484848UL, 0x50505050UL, - 0xfdfdfdfdUL, 0xededededUL, 0xb9b9b9b9UL, 0xdadadadaUL, - 0x5e5e5e5eUL, 0x15151515UL, 0x46464646UL, 0x57575757UL, - 0xa7a7a7a7UL, 0x8d8d8d8dUL, 0x9d9d9d9dUL, 0x84848484UL, - 0x90909090UL, 0xd8d8d8d8UL, 0xababababUL, 0x00000000UL, - 0x8c8c8c8cUL, 0xbcbcbcbcUL, 0xd3d3d3d3UL, 0x0a0a0a0aUL, - 0xf7f7f7f7UL, 0xe4e4e4e4UL, 0x58585858UL, 0x05050505UL, - 0xb8b8b8b8UL, 0xb3b3b3b3UL, 0x45454545UL, 0x06060606UL, - 0xd0d0d0d0UL, 0x2c2c2c2cUL, 0x1e1e1e1eUL, 0x8f8f8f8fUL, - 0xcacacacaUL, 0x3f3f3f3fUL, 0x0f0f0f0fUL, 0x02020202UL, - 0xc1c1c1c1UL, 0xafafafafUL, 0xbdbdbdbdUL, 0x03030303UL, - 0x01010101UL, 0x13131313UL, 0x8a8a8a8aUL, 0x6b6b6b6bUL, - 0x3a3a3a3aUL, 0x91919191UL, 0x11111111UL, 0x41414141UL, - 0x4f4f4f4fUL, 0x67676767UL, 0xdcdcdcdcUL, 0xeaeaeaeaUL, - 0x97979797UL, 0xf2f2f2f2UL, 0xcfcfcfcfUL, 0xcecececeUL, - 0xf0f0f0f0UL, 0xb4b4b4b4UL, 0xe6e6e6e6UL, 0x73737373UL, - 0x96969696UL, 0xacacacacUL, 0x74747474UL, 0x22222222UL, - 0xe7e7e7e7UL, 0xadadadadUL, 0x35353535UL, 0x85858585UL, - 0xe2e2e2e2UL, 0xf9f9f9f9UL, 0x37373737UL, 0xe8e8e8e8UL, - 0x1c1c1c1cUL, 0x75757575UL, 0xdfdfdfdfUL, 0x6e6e6e6eUL, - 0x47474747UL, 0xf1f1f1f1UL, 0x1a1a1a1aUL, 0x71717171UL, - 0x1d1d1d1dUL, 0x29292929UL, 0xc5c5c5c5UL, 0x89898989UL, - 0x6f6f6f6fUL, 0xb7b7b7b7UL, 0x62626262UL, 0x0e0e0e0eUL, - 0xaaaaaaaaUL, 0x18181818UL, 0xbebebebeUL, 0x1b1b1b1bUL, - 0xfcfcfcfcUL, 0x56565656UL, 0x3e3e3e3eUL, 0x4b4b4b4bUL, - 0xc6c6c6c6UL, 0xd2d2d2d2UL, 0x79797979UL, 0x20202020UL, - 0x9a9a9a9aUL, 0xdbdbdbdbUL, 0xc0c0c0c0UL, 0xfefefefeUL, - 0x78787878UL, 0xcdcdcdcdUL, 0x5a5a5a5aUL, 0xf4f4f4f4UL, - 0x1f1f1f1fUL, 0xddddddddUL, 0xa8a8a8a8UL, 0x33333333UL, - 0x88888888UL, 0x07070707UL, 0xc7c7c7c7UL, 0x31313131UL, - 0xb1b1b1b1UL, 0x12121212UL, 0x10101010UL, 0x59595959UL, - 0x27272727UL, 0x80808080UL, 0xececececUL, 0x5f5f5f5fUL, - 0x60606060UL, 0x51515151UL, 0x7f7f7f7fUL, 0xa9a9a9a9UL, - 0x19191919UL, 0xb5b5b5b5UL, 0x4a4a4a4aUL, 0x0d0d0d0dUL, - 0x2d2d2d2dUL, 0xe5e5e5e5UL, 0x7a7a7a7aUL, 0x9f9f9f9fUL, - 0x93939393UL, 0xc9c9c9c9UL, 0x9c9c9c9cUL, 0xefefefefUL, - 0xa0a0a0a0UL, 0xe0e0e0e0UL, 0x3b3b3b3bUL, 0x4d4d4d4dUL, - 0xaeaeaeaeUL, 0x2a2a2a2aUL, 0xf5f5f5f5UL, 0xb0b0b0b0UL, - 0xc8c8c8c8UL, 0xebebebebUL, 0xbbbbbbbbUL, 0x3c3c3c3cUL, - 0x83838383UL, 0x53535353UL, 0x99999999UL, 0x61616161UL, - 0x17171717UL, 0x2b2b2b2bUL, 0x04040404UL, 0x7e7e7e7eUL, - 0xbabababaUL, 0x77777777UL, 0xd6d6d6d6UL, 0x26262626UL, - 0xe1e1e1e1UL, 0x69696969UL, 0x14141414UL, 0x63636363UL, - 0x55555555UL, 0x21212121UL, 0x0c0c0c0cUL, 0x7d7d7d7dUL, -}; -static const unsigned int rcon[] = { - 0x01000000UL, 0x02000000UL, 0x04000000UL, 0x08000000UL, - 0x10000000UL, 0x20000000UL, 0x40000000UL, 0x80000000UL, - 0x1B000000UL, 0x36000000UL, -}; - -#define GETU32(pt) (((unsigned int)(pt)[0] << 24) ^ \ - ((unsigned int)(pt)[1] << 16) ^ \ - ((unsigned int)(pt)[2] << 8) ^ \ - ((unsigned int)(pt)[3])) - -#define PUTU32(ct, st) { (ct)[0] = (unsigned char)((st) >> 24); \ - (ct)[1] = (unsigned char)((st) >> 16); \ - (ct)[2] = (unsigned char)((st) >> 8); \ - (ct)[3] = (unsigned char)(st); } - -/* -* Expand the cipher key into the encryption key schedule and return the -* number of rounds for the given cipher key size. -*/ -int aes_setkey_enc(unsigned int rk[], const unsigned char cipherKey[], int keyBytes) { - int i = 0; - unsigned int temp; - - rk[0] = GETU32(cipherKey); - rk[1] = GETU32(cipherKey + 4); - rk[2] = GETU32(cipherKey + 8); - rk[3] = GETU32(cipherKey + 12); - if (keyBytes == 16) { // 128 bits - for (;;) { - temp = rk[3]; - rk[4] = rk[0] ^ - (Te4[(temp >> 16) & 0xff] & 0xff000000) ^ - (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^ - (Te4[(temp) & 0xff] & 0x0000ff00) ^ - (Te4[(temp >> 24) ] & 0x000000ff) ^ - rcon[i]; - rk[5] = rk[1] ^ rk[4]; - rk[6] = rk[2] ^ rk[5]; - rk[7] = rk[3] ^ rk[6]; - if (++i == 10) { - return 10; - } - rk += 4; - } - } - rk[4] = GETU32(cipherKey + 16); - rk[5] = GETU32(cipherKey + 20); - if (keyBytes == 24) { // 192 bits - for (;;) { - temp = rk[ 5]; - rk[ 6] = rk[ 0] ^ - (Te4[(temp >> 16) & 0xff] & 0xff000000) ^ - (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^ - (Te4[(temp) & 0xff] & 0x0000ff00) ^ - (Te4[(temp >> 24) ] & 0x000000ff) ^ - rcon[i]; - rk[ 7] = rk[ 1] ^ rk[ 6]; - rk[ 8] = rk[ 2] ^ rk[ 7]; - rk[ 9] = rk[ 3] ^ rk[ 8]; - if (++i == 8) { - return 12; - } - rk[10] = rk[ 4] ^ rk[ 9]; - rk[11] = rk[ 5] ^ rk[10]; - rk += 6; - } - } - rk[6] = GETU32(cipherKey + 24); - rk[7] = GETU32(cipherKey + 28); - if (keyBytes == 32) { // 256 bits - for (;;) { - temp = rk[ 7]; - rk[ 8] = rk[ 0] ^ - (Te4[(temp >> 16) & 0xff] & 0xff000000) ^ - (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^ - (Te4[(temp) & 0xff] & 0x0000ff00) ^ - (Te4[(temp >> 24) ] & 0x000000ff) ^ - rcon[i]; - rk[ 9] = rk[ 1] ^ rk[ 8]; - rk[10] = rk[ 2] ^ rk[ 9]; - rk[11] = rk[ 3] ^ rk[10]; - if (++i == 7) { - return 14; - } - temp = rk[11]; - rk[12] = rk[ 4] ^ - (Te4[(temp >> 24) ] & 0xff000000) ^ - (Te4[(temp >> 16) & 0xff] & 0x00ff0000) ^ - (Te4[(temp >> 8) & 0xff] & 0x0000ff00) ^ - (Te4[(temp) & 0xff] & 0x000000ff); - rk[13] = rk[ 5] ^ rk[12]; - rk[14] = rk[ 6] ^ rk[13]; - rk[15] = rk[ 7] ^ rk[14]; - - rk += 8; - } - } - return 0; -} - -/* -* Expand the cipher key into encryption and decryption key schedule and -* return the number of rounds for the given cipher key size. -*/ -int AesGenKeySched(unsigned int rk[], unsigned int rrk[], const unsigned char cipherKey[], int keyBytes) { - int Nr, i; - - // expand the cipher key - Nr = aes_setkey_enc(rk, cipherKey, keyBytes); - // invert the order of the first round keys - rrk += Nr * 4; - rrk[0] = rk[0]; - rrk[1] = rk[1]; - rrk[2] = rk[2]; - rrk[3] = rk[3]; - - /* - * apply the inverse MixColumn transform to all round keys but the first - * and the last - */ - for (i = 1; i < Nr; i++) { - rrk -= 4; - rk += 4; - rrk[0] = - Td0[Te4[(rk[0] >> 24) ] & 0xff] ^ - Td1[Te4[(rk[0] >> 16) & 0xff] & 0xff] ^ - Td2[Te4[(rk[0] >> 8) & 0xff] & 0xff] ^ - Td3[Te4[(rk[0]) & 0xff] & 0xff]; - rrk[1] = - Td0[Te4[(rk[1] >> 24) ] & 0xff] ^ - Td1[Te4[(rk[1] >> 16) & 0xff] & 0xff] ^ - Td2[Te4[(rk[1] >> 8) & 0xff] & 0xff] ^ - Td3[Te4[(rk[1]) & 0xff] & 0xff]; - rrk[2] = - Td0[Te4[(rk[2] >> 24) ] & 0xff] ^ - Td1[Te4[(rk[2] >> 16) & 0xff] & 0xff] ^ - Td2[Te4[(rk[2] >> 8) & 0xff] & 0xff] ^ - Td3[Te4[(rk[2]) & 0xff] & 0xff]; - rrk[3] = - Td0[Te4[(rk[3] >> 24) ] & 0xff] ^ - Td1[Te4[(rk[3] >> 16) & 0xff] & 0xff] ^ - Td2[Te4[(rk[3] >> 8) & 0xff] & 0xff] ^ - Td3[Te4[(rk[3]) & 0xff] & 0xff]; - } - // invert the order of the last round keys - rrk -= 4; - rk += 4; - rrk[0] = rk[0]; - rrk[1] = rk[1]; - rrk[2] = rk[2]; - rrk[3] = rk[3]; - - return Nr; -} - -/* -* Encrypt the plain text into cipher -*/ -void AesEncBlk(AesCtx *pCtx, const unsigned char pt[], unsigned char ct[]) { - unsigned int s0, s1, s2, s3, t0, t1, t2, t3, *iv; - const unsigned int *rk; - int r; - - rk = pCtx->Ek; - iv = pCtx->Iv; - /* - * map byte array block to cipher state - * and add initial round key: - */ - s0 = GETU32(pt) ^ rk[0]; - s1 = GETU32(pt + 4) ^ rk[1]; - s2 = GETU32(pt + 8) ^ rk[2]; - s3 = GETU32(pt + 12) ^ rk[3]; - if (pCtx->Mode) { - s0 = s0 ^ iv[0]; - s1 = s1 ^ iv[1]; - s2 = s2 ^ iv[2]; - s3 = s3 ^ iv[3]; - } - /* - * Nr - 1 full rounds: - */ - r = pCtx->Nr >> 1; - for (;;) { - t0 = - Te0[(s0 >> 24) ] ^ - Te1[(s1 >> 16) & 0xff] ^ - Te2[(s2 >> 8) & 0xff] ^ - Te3[(s3) & 0xff] ^ - rk[4]; - t1 = - Te0[(s1 >> 24) ] ^ - Te1[(s2 >> 16) & 0xff] ^ - Te2[(s3 >> 8) & 0xff] ^ - Te3[(s0) & 0xff] ^ - rk[5]; - t2 = - Te0[(s2 >> 24) ] ^ - Te1[(s3 >> 16) & 0xff] ^ - Te2[(s0 >> 8) & 0xff] ^ - Te3[(s1) & 0xff] ^ - rk[6]; - t3 = - Te0[(s3 >> 24) ] ^ - Te1[(s0 >> 16) & 0xff] ^ - Te2[(s1 >> 8) & 0xff] ^ - Te3[(s2) & 0xff] ^ - rk[7]; - - rk += 8; - if (--r == 0) { - break; - } - - s0 = - Te0[(t0 >> 24) ] ^ - Te1[(t1 >> 16) & 0xff] ^ - Te2[(t2 >> 8) & 0xff] ^ - Te3[(t3) & 0xff] ^ - rk[0]; - s1 = - Te0[(t1 >> 24) ] ^ - Te1[(t2 >> 16) & 0xff] ^ - Te2[(t3 >> 8) & 0xff] ^ - Te3[(t0) & 0xff] ^ - rk[1]; - s2 = - Te0[(t2 >> 24) ] ^ - Te1[(t3 >> 16) & 0xff] ^ - Te2[(t0 >> 8) & 0xff] ^ - Te3[(t1) & 0xff] ^ - rk[2]; - s3 = - Te0[(t3 >> 24) ] ^ - Te1[(t0 >> 16) & 0xff] ^ - Te2[(t1 >> 8) & 0xff] ^ - Te3[(t2) & 0xff] ^ - rk[3]; - } - /* - * apply last round and - * map cipher state to byte array block: - */ - s0 = - (Te4[(t0 >> 24) ] & 0xff000000) ^ - (Te4[(t1 >> 16) & 0xff] & 0x00ff0000) ^ - (Te4[(t2 >> 8) & 0xff] & 0x0000ff00) ^ - (Te4[(t3) & 0xff] & 0x000000ff) ^ - rk[0]; - PUTU32(ct, s0); - s1 = - (Te4[(t1 >> 24) ] & 0xff000000) ^ - (Te4[(t2 >> 16) & 0xff] & 0x00ff0000) ^ - (Te4[(t3 >> 8) & 0xff] & 0x0000ff00) ^ - (Te4[(t0) & 0xff] & 0x000000ff) ^ - rk[1]; - PUTU32(ct + 4, s1); - s2 = - (Te4[(t2 >> 24) ] & 0xff000000) ^ - (Te4[(t3 >> 16) & 0xff] & 0x00ff0000) ^ - (Te4[(t0 >> 8) & 0xff] & 0x0000ff00) ^ - (Te4[(t1) & 0xff] & 0x000000ff) ^ - rk[2]; - PUTU32(ct + 8, s2); - s3 = - (Te4[(t3 >> 24) ] & 0xff000000) ^ - (Te4[(t0 >> 16) & 0xff] & 0x00ff0000) ^ - (Te4[(t1 >> 8) & 0xff] & 0x0000ff00) ^ - (Te4[(t2) & 0xff] & 0x000000ff) ^ - rk[3]; - PUTU32(ct + 12, s3); - - if (pCtx->Mode) { - iv[0] = s0; - iv[1] = s1; - iv[2] = s2; - iv[3] = s3; - } -} - -/* -* Decrypt the cipher into plain text -*/ -void AesDecBlk(AesCtx *pCtx, const unsigned char ct[], unsigned char pt[]) { - unsigned int s0, s1, s2, s3, t0, t1, t2, t3, v0, v1, v2, v3, *iv; - const unsigned int *rk; - int r; - - rk = pCtx->Dk; - iv = pCtx->Iv; - /* - * map byte array block to cipher state - * and add initial round key: - */ - v0 = GETU32(ct); - s0 = v0 ^ rk[0]; - v1 = GETU32(ct + 4); - s1 = v1 ^ rk[1]; - v2 = GETU32(ct + 8); - s2 = v2 ^ rk[2]; - v3 = GETU32(ct + 12); - s3 = v3 ^ rk[3]; - /* - * Nr - 1 full rounds: - */ - r = pCtx->Nr >> 1; - for (;;) { - t0 = - Td0[(s0 >> 24) ] ^ - Td1[(s3 >> 16) & 0xff] ^ - Td2[(s2 >> 8) & 0xff] ^ - Td3[(s1) & 0xff] ^ - rk[4]; - t1 = - Td0[(s1 >> 24) ] ^ - Td1[(s0 >> 16) & 0xff] ^ - Td2[(s3 >> 8) & 0xff] ^ - Td3[(s2) & 0xff] ^ - rk[5]; - t2 = - Td0[(s2 >> 24) ] ^ - Td1[(s1 >> 16) & 0xff] ^ - Td2[(s0 >> 8) & 0xff] ^ - Td3[(s3) & 0xff] ^ - rk[6]; - t3 = - Td0[(s3 >> 24) ] ^ - Td1[(s2 >> 16) & 0xff] ^ - Td2[(s1 >> 8) & 0xff] ^ - Td3[(s0) & 0xff] ^ - rk[7]; - - rk += 8; - if (--r == 0) { - break; - } - - s0 = - Td0[(t0 >> 24) ] ^ - Td1[(t3 >> 16) & 0xff] ^ - Td2[(t2 >> 8) & 0xff] ^ - Td3[(t1) & 0xff] ^ - rk[0]; - s1 = - Td0[(t1 >> 24) ] ^ - Td1[(t0 >> 16) & 0xff] ^ - Td2[(t3 >> 8) & 0xff] ^ - Td3[(t2) & 0xff] ^ - rk[1]; - s2 = - Td0[(t2 >> 24) ] ^ - Td1[(t1 >> 16) & 0xff] ^ - Td2[(t0 >> 8) & 0xff] ^ - Td3[(t3) & 0xff] ^ - rk[2]; - s3 = - Td0[(t3 >> 24) ] ^ - Td1[(t2 >> 16) & 0xff] ^ - Td2[(t1 >> 8) & 0xff] ^ - Td3[(t0) & 0xff] ^ - rk[3]; - } - /* - * apply last round and - * map cipher state to byte array block: - */ - s0 = - (Td4[(t0 >> 24) ] & 0xff000000) ^ - (Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^ - (Td4[(t2 >> 8) & 0xff] & 0x0000ff00) ^ - (Td4[(t1) & 0xff] & 0x000000ff) ^ - rk[0]; - s1 = - (Td4[(t1 >> 24) ] & 0xff000000) ^ - (Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^ - (Td4[(t3 >> 8) & 0xff] & 0x0000ff00) ^ - (Td4[(t2) & 0xff] & 0x000000ff) ^ - rk[1]; - s2 = - (Td4[(t2 >> 24) ] & 0xff000000) ^ - (Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^ - (Td4[(t0 >> 8) & 0xff] & 0x0000ff00) ^ - (Td4[(t3) & 0xff] & 0x000000ff) ^ - rk[2]; - s3 = - (Td4[(t3 >> 24) ] & 0xff000000) ^ - (Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^ - (Td4[(t1 >> 8) & 0xff] & 0x0000ff00) ^ - (Td4[(t0) & 0xff] & 0x000000ff) ^ - rk[3]; - - if (pCtx->Mode) { - s0 = s0 ^ iv[0]; - iv[0] = v0; - s1 = s1 ^ iv[1]; - iv[1] = v1; - s2 = s2 ^ iv[2]; - iv[2] = v2; - s3 = s3 ^ iv[3]; - iv[3] = v3; - } - - PUTU32(pt, s0); - PUTU32(pt + 4, s1); - PUTU32(pt + 8, s2); - PUTU32(pt + 12, s3); -} - -////////////////////////////////////////////////////////////////////////////// -// API functions // -////////////////////////////////////////////////////////////////////////////// - -/* -* initialize AES context -*/ -int AesCtxIni(AesCtx *pCtx, unsigned char *pIV, unsigned char *pKey, unsigned int KeyLen, unsigned char Mode) { - if (pKey == 0 || pCtx == 0 || (KeyLen != KEY128 && KeyLen != KEY192 && KeyLen != KEY256)) - return -1; - - // generate key schedule - pCtx->Nr = AesGenKeySched(pCtx->Ek, pCtx->Dk, pKey, KeyLen); - - // initialize IV - if (pIV != 0) { - pCtx->Iv[0] = GETU32(pIV); - pCtx->Iv[1] = GETU32(pIV + 4); - pCtx->Iv[2] = GETU32(pIV + 8); - pCtx->Iv[3] = GETU32(pIV + 12); - } - - // mode - pCtx->Mode = Mode; - - return 0; -} - -/* -* Encrypt plain text -*/ -int AesEncrypt(AesCtx *pCtx, unsigned char *pData, unsigned char *pCipher, unsigned int DataLen) { - int i; - - if (pData == 0 || pCipher == 0 || pCtx == 0 || (DataLen & 0xf) != 0) - return -1; - - for (i = 0; i < DataLen; i += BLOCKSZ) { - // encrypt block by block - AesEncBlk(pCtx, pData, pCipher); - pCipher += BLOCKSZ; - pData += BLOCKSZ; - } - return DataLen; -} - -/* -* Decrypt cipher -*/ -int AesDecrypt(AesCtx *pCtx, unsigned char *pCipher, unsigned char *pData, unsigned int CipherLen) { - int i; - - if (pData == 0 || pCipher == 0 || pCtx == 0 || (CipherLen & 0xf) != 0) - return -1; - - for (i = 0; i < CipherLen; i += BLOCKSZ) { - // decrypt block by block - AesDecBlk(pCtx, pCipher, pData); - pCipher += BLOCKSZ; - pData += BLOCKSZ; - } - return CipherLen; -} - -////////////////////////////////////////////////////////////////////////////// -// Sample main program // -////////////////////////////////////////////////////////////////////////////// - -#ifndef EMBEDDED - -#include - -int main() { - AesCtx ctx; - unsigned char iv[] = "INI VECTINI VECT"; - unsigned char key[] = "This is a sample AESKey"; - unsigned char databuf[] = "Data : AES Test"; // must be in multiple of 16 - - // initialize context and encrypt data at one end - - if (AesCtxIni(&ctx, iv, key, KEY128, CBC) < 0) - printf("init error\n"); - - if (AesEncrypt(&ctx, databuf, databuf, sizeof(databuf)) < 0) - printf("error in encryption\n"); - - // initialize context and decrypt cipher at other end - - if (AesCtxIni(&ctx, iv, key, KEY128, CBC) < 0) - printf("init error\n"); - - if (AesDecrypt(&ctx, databuf, databuf, sizeof(databuf)) < 0) - printf("error in decryption\n"); - - printf("%s\n", databuf); - - return 0; -} -#endif diff --git a/armsrc/aes.h b/armsrc/aes.h deleted file mode 100644 index aa9f0c582..000000000 --- a/armsrc/aes.h +++ /dev/null @@ -1,34 +0,0 @@ -/* -* AES Cryptographic Algorithm Header File. Include this header file in -* your source which uses these given APIs. (This source is kept under -* public domain) -*/ -#ifndef __AES_H -#define __AES_H - -// AES context structure -typedef struct { - unsigned int Ek[60]; - unsigned int Dk[60]; - unsigned int Iv[4]; - unsigned char Nr; - unsigned char Mode; -} AesCtx; - -// key length in bytes -#define KEY128 16 -#define KEY192 24 -#define KEY256 32 -// block size in bytes -#define BLOCKSZ 16 -// mode -#define EBC 0 -#define CBC 1 - -// AES API function prototype - -int AesCtxIni(AesCtx *pCtx, unsigned char *pIV, unsigned char *pKey, unsigned int KeyLen, unsigned char Mode); -int AesEncrypt(AesCtx *pCtx, unsigned char *pData, unsigned char *pCipher, unsigned int DataLen); -int AesDecrypt(AesCtx *pCtx, unsigned char *pCipher, unsigned char *pData, unsigned int CipherLen); - -#endif diff --git a/armsrc/desfire_crypto.c b/armsrc/desfire_crypto.c index 10ddf4162..2e9d5a8d3 100644 --- a/armsrc/desfire_crypto.c +++ b/armsrc/desfire_crypto.c @@ -571,15 +571,19 @@ void mifare_cypher_single_block(desfirekey_t key, uint8_t *data, uint8_t *ivect, case T_AES: switch (operation) { case MCO_ENCYPHER: { - AesCtx ctx; - AesCtxIni(&ctx, ivect, key->data, KEY128, CBC); - AesEncrypt(&ctx, data, edata, sizeof(edata)); + mbedtls_aes_context ctx; + mbedtls_aes_init(&ctx); + mbedtls_aes_setkey_enc(&ctx, key->data, 128); + mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_ENCRYPT, sizeof(edata), ivect, data, edata); + mbedtls_aes_free(&ctx); break; } case MCO_DECYPHER: { - AesCtx ctx; - AesCtxIni(&ctx, ivect, key->data, KEY128, CBC); - AesDecrypt(&ctx, edata, data, sizeof(edata)); + mbedtls_aes_context ctx; + mbedtls_aes_init(&ctx); + mbedtls_aes_setkey_dec(&ctx, key->data, 128); + mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_DECRYPT, sizeof(edata), ivect, edata, data); + mbedtls_aes_free(&ctx); break; } } diff --git a/armsrc/mifaredesfire.c b/armsrc/mifaredesfire.c index bda31790d..c57fed866 100644 --- a/armsrc/mifaredesfire.c +++ b/armsrc/mifaredesfire.c @@ -433,15 +433,9 @@ void MifareDES_Auth1(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) desfirekey_t key = &defaultkey; Desfire_aes_key_new(keybytes, key); - AesCtx ctx; + mbedtls_aes_context ctx; uint8_t IV[16] = {0x00}; - if (AesCtxIni(&ctx, IV, key->data, KEY128, CBC) < 0) { - if (DBGLEVEL >= 4) { - DbpString("AES context failed to init"); - } - OnError(7); - return; - } + mbedtls_aes_init(&ctx); cmd[0] = AUTHENTICATE_AES; cmd[1] = 0x00; //keynumber @@ -457,13 +451,27 @@ void MifareDES_Auth1(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) memcpy(encRndB, resp + 3, 16); // dekryptera tagnonce. - AesDecrypt(&ctx, encRndB, decRndB, 16); + if (mbedtls_aes_setkey_dec(&ctx, key->data, 128) != 0) { + if (DBGLEVEL >= 4) { + DbpString("mbedtls_aes_setkey_dec failed"); + } + OnError(7); + return; + } + mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_DECRYPT, 16, IV, encRndB, decRndB); rol(decRndB, 16); uint8_t nonce[16] = {0x00}; memcpy(both, nonce, 16); memcpy(both + 16, decRndB, 16); uint8_t encBoth[32] = {0x00}; - AesEncrypt(&ctx, both, encBoth, 32); + if (mbedtls_aes_setkey_enc(&ctx, key->data, 128) != 0) { + if (DBGLEVEL >= 4) { + DbpString("mbedtls_aes_setkey_enc failed"); + } + OnError(7); + return; + } + mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_ENCRYPT, 32, IV, both, encBoth); cmd[0] = ADDITIONAL_FRAME; memcpy(cmd + 1, encBoth, 32); diff --git a/common/Makefile.common b/common/Makefile.common index 2ab434562..282f242d9 100644 --- a/common/Makefile.common +++ b/common/Makefile.common @@ -63,7 +63,7 @@ DETECTED_OS=Windows endif # Also search prerequisites in the common directory (for usb.c), the fpga directory (for fpga.bit), and the zlib directory -VPATH = . ../common ../common/crapto1 ../common/polarssl ../fpga ../zlib ../armsrc/Standalone ../uart +VPATH = . ../common ../common/crapto1 ../common/mbedtls ../fpga ../zlib ../armsrc/Standalone ../uart INCLUDES = ../include/proxmark3.h ../include/at91sam7s512.h ../include/config_gpio.h ../include/pm3_cmd.h $(APP_INCLUDES) diff --git a/common/desfire.h b/common/desfire.h index 3cffd2967..41e5b6e12 100644 --- a/common/desfire.h +++ b/common/desfire.h @@ -3,7 +3,7 @@ #include #include -#include "aes.h" +#include "mbedtls/aes.h" #include "mifare.h" #define MAX_CRYPTO_BLOCK_SIZE 16 @@ -71,10 +71,6 @@ enum DESFIRE_CRYPTOALGO { struct desfire_key { enum DESFIRE_CRYPTOALGO type; uint8_t data[24]; - // DES_key_schedule ks1; - // DES_key_schedule ks2; - // DES_key_schedule ks3; - AesCtx aes_ks; uint8_t cmac_sk1[24]; uint8_t cmac_sk2[24]; uint8_t aes_version; diff --git a/common/mbedtls/platform_util.c b/common/mbedtls/platform_util.c index a3634e246..c30a52c08 100644 --- a/common/mbedtls/platform_util.c +++ b/common/mbedtls/platform_util.c @@ -60,9 +60,9 @@ * mbedtls_platform_zeroize() to use a suitable implementation for their * platform and needs. */ -static void *(* const volatile memset_func)(void *, int, size_t) = memset; +//static void *(* const volatile memset_func)(void *, int, size_t) = memset; void mbedtls_platform_zeroize(void *buf, size_t len) { - memset_func(buf, 0, len); + memset(buf, 0, len); } #endif /* MBEDTLS_PLATFORM_ZEROIZE_ALT */ From d11684fcabc4545647d12f033c89eeabdd20a8c0 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 13 Jul 2019 00:06:19 +0200 Subject: [PATCH 0052/1854] Get proxmark.sh supporting WSL --- CHANGELOG.md | 1 + .../Windows-Installation-Instructions.md | 28 +++++++++++++++---- proxmark3.sh | 21 ++++++++++++-- 3 files changed, 43 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a276440d7..2fb002175 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Add support for WSL in proxmark.sh (@doegox) - Add documentation for usage of Proxmark3 under WSL (@doegox) - Change: replace ukbhit by kbd_enter_pressed, not requiring tcgetattr (@xianglin1998/@doegox) - Add config for RaspberryPi in JTAG tools (@doegox) diff --git a/doc/md/Installation_Instructions/Windows-Installation-Instructions.md b/doc/md/Installation_Instructions/Windows-Installation-Instructions.md index 1617ec6ec..69f24dcf8 100644 --- a/doc/md/Installation_Instructions/Windows-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Windows-Installation-Instructions.md @@ -116,14 +116,19 @@ Now you're ready to follow the [compilation instructions](/doc/md/Use_of_Proxmar To use the compiled client and flasher, the only difference is that the Proxmark3 port is translated from your `comX` port where "X" is the com port number assigned to proxmark3 under Windows, to a `/dev/ttySX`. -You will need to give permission to the current user to access `/dev/ttySX`: (change X to your port number) +Depending on the Windows version, you might need to give permission to the current user to access `/dev/ttySX`: (change X to your port number) + +```sh +ls -al /dev/ttySX +groups|grep dialout +``` + +If group ownership is `dialout` and your user is member of `dialout` group, all is fine. Else you'll have to provide access to `/dev/ttySX`: (Unfortunately the access rights of the port won't survive and will have to be fixed again next time.) ```sh sudo chmod 666 /dev/ttySX ``` -Unfortunately the access rights of the port won't survive and will have to be fixed again next time. - If you installed a X Server and compiled the Proxmark3 with QT4 support, you've to export the `DISPLAY` environment variable: ```sh @@ -136,14 +141,27 @@ and add it to your Bash profile for the next times: echo "export DISPLAY=:0" >> ~/.bashrc ``` -To flash, you've to call the flasher manually and specify the correct port: +To flash: In principle, the helper script `flash-all.sh` should auto-detect your COMX==/dev/ttySX port, so you can just try: + +```sh +./flash-all.sh +``` + +If port detection failed, you'll have to call the flasher manually and specify the correct port: ```sh client/flasher /dev/ttySX -b bootrom/obj/bootrom.elf armsrc/obj/fullimage.elf ``` -Similarly, to run the client: +Similarly, to run the client, you may try: + +```sh +./proxmark3.sh +``` + +Or, by specifying the COM port manually: ```sh client/proxmark3 /dev/ttySX ``` + diff --git a/proxmark3.sh b/proxmark3.sh index b4aa51ffb..39eb80779 100755 --- a/proxmark3.sh +++ b/proxmark3.sh @@ -11,7 +11,6 @@ function wait4proxmark_Linux { sleep .1 done local PM3=`ls -1 /dev/pm3-? /dev/ttyACM? 2>/dev/null | head -1` - echo >&2 -e "Found proxmark on ${PM3}\n" echo $PM3 } @@ -41,6 +40,20 @@ function wait4proxmark_Windows { echo $PM3 } +function wait4proxmark_WSL { + echo >&2 "Waiting for Proxmark to appear..." + while true; do + device=$(wmic.exe path Win32_SerialPort where "PNPDeviceID like '%VID_9AC4&PID_4B8F%'" get DeviceID,PNPDeviceID 2>/dev/null | awk 'NR==2') + if [[ $device != "" ]]; then + PM3=${device/ */} + PM3="/dev/ttyS${PM3#COM}" + break + fi + sleep .1 + done + echo $PM3 +} + SCRIPT=$(basename -- "$0") if [ "$SCRIPT" = "proxmark3.sh" ]; then @@ -61,7 +74,11 @@ else fi HOSTOS=$(uname | awk '{print toupper($0)}') if [ "$HOSTOS" = "LINUX" ]; then - PORT=$(wait4proxmark_Linux) + if uname -a|grep -q Microsoft; then + PORT=$(wait4proxmark_WSL) + else + PORT=$(wait4proxmark_Linux) + fi elif [ "$HOSTOS" = "DARWIN" ]; then PORT=$(wait4proxmark_macOS) elif [[ "$HOSTOS" =~ MINGW(32|64)_NT* ]]; then From ed47ca7186239fc25a8a9cbdec3d06ab991d72bf Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 13 Jul 2019 00:36:10 +0200 Subject: [PATCH 0053/1854] tuning windows doc --- .../Windows-Installation-Instructions.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/doc/md/Installation_Instructions/Windows-Installation-Instructions.md b/doc/md/Installation_Instructions/Windows-Installation-Instructions.md index 69f24dcf8..73a5358e9 100644 --- a/doc/md/Installation_Instructions/Windows-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Windows-Installation-Instructions.md @@ -44,6 +44,12 @@ git clone https://github.com/RfidResearchGroup/proxmark3.git cd proxmark3 ``` +If you're a contributing developer, you probably want to be able to use `make style`. If so, you've to install astyle: + +```sh +pacman -S mingw-w64-x86_64-astyle +``` + ## Compile and use the project Now you're ready to follow the [compilation instructions](/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md). @@ -89,7 +95,7 @@ Step by step guides are online such as [RiscCorps](https://store.ryscc.com/blogs ## X Server Installation -If you want to run the graphical components of the Proxmark3 client, you need to install a X Server such as [VcXsrv](https://sourceforge.net/projects/vcxsrv/) or [Xming](https://sourceforge.net/projects/xming/). +If you want to run the graphical components of the Proxmark3 client, you need to install a X Server such as [VcXsrv](https://sourceforge.net/projects/vcxsrv/) or [Xming](https://sourceforge.net/projects/xming/) and launch it, e.g. by executing XLaunch. ## Dependencies From b0dbbd3683afeafcf45bfb79c9a2c0a01f88d14d Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 13 Jul 2019 00:38:30 +0200 Subject: [PATCH 0054/1854] make style --- armsrc/appmain.c | 4 ++-- armsrc/hitag2.c | 2 +- armsrc/lfsampling.c | 24 +++++++++---------- armsrc/mifaresim.c | 4 ++-- bootrom/bootrom.c | 2 +- client/cmdhf15.c | 2 +- client/cmdlf.c | 6 ++--- client/cmdlfem4x.c | 10 ++++---- client/cmdlft55xx.c | 8 +++---- client/cmdusart.c | 2 +- client/comms.c | 2 +- client/deprecated-hid-flasher/flasher/sleep.h | 22 ++++++++--------- client/flash.c | 2 +- client/util.c | 15 ++++++------ common/lfdemod.c | 6 ++--- 15 files changed, 55 insertions(+), 56 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 3213fbe14..facce653c 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -347,9 +347,9 @@ void SendVersion(void) { strncat(VersionString, temp, sizeof(VersionString) - strlen(VersionString) - 1); #if defined(__clang__) - strncat(VersionString, " compiled with Clang/LLVM "__VERSION__"\n", sizeof(VersionString) - strlen(VersionString) - 1); + strncat(VersionString, " compiled with Clang/LLVM "__VERSION__"\n", sizeof(VersionString) - strlen(VersionString) - 1); #elif defined(__GNUC__) || defined(__GNUG__) - strncat(VersionString, " compiled with GCC "__VERSION__"\n", sizeof(VersionString) - strlen(VersionString) - 1); + strncat(VersionString, " compiled with GCC "__VERSION__"\n", sizeof(VersionString) - strlen(VersionString) - 1); #endif strncat(VersionString, "\n [ FPGA ]\n ", sizeof(VersionString) - strlen(VersionString) - 1); diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index 46e9a43dd..682dd950a 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -434,7 +434,7 @@ static bool hitag2_password(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t break; } } - + return true; } diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index c5a075e7a..c88401229 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -136,11 +136,11 @@ uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averag uint32_t sample_total_numbers = 0; uint32_t sample_total_saved = 0; uint32_t cancel_counter = 0; - + uint16_t checker = 0; - + while (true) { - if ( checker == 1000 ) { + if (checker == 1000) { if (BUTTON_PRESS() || data_available()) break; else @@ -148,7 +148,7 @@ uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averag } else { ++checker; } - + WDT_HIT(); if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { @@ -293,11 +293,11 @@ void doT55x7Acquisition(size_t sample_size) { bool startFound = false; bool highFound = false; bool lowFound = false; - + uint16_t checker = 0; - - while ( skipCnt < 1000 && (i < bufsize)) { - if ( checker == 1000 ) { + + while (skipCnt < 1000 && (i < bufsize)) { + if (checker == 1000) { if (BUTTON_PRESS() || data_available()) break; else @@ -371,9 +371,9 @@ void doCotagAcquisition(size_t sample_size) { uint16_t noise_counter = 0; uint16_t checker = 0; - + while ((i < bufsize) && (noise_counter < (COTAG_T1 << 1))) { - if ( checker == 1000 ) { + if (checker == 1000) { if (BUTTON_PRESS() || data_available()) break; else @@ -431,9 +431,9 @@ uint32_t doCotagAcquisitionManchester() { uint8_t curr = 0, prev = 0; uint16_t noise_counter = 0; uint16_t checker = 0; - + while ((sample_counter < bufsize) && (noise_counter < (COTAG_T1 << 1))) { - if ( checker == 1000 ) { + if (checker == 1000) { if (BUTTON_PRESS() || data_available()) break; else diff --git a/armsrc/mifaresim.c b/armsrc/mifaresim.c index 714beb284..8f21882be 100644 --- a/armsrc/mifaresim.c +++ b/armsrc/mifaresim.c @@ -606,8 +606,8 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain) { if (receivedCmd_len == 9 && receivedCmd[1] == 0x70) { if (memcmp(&receivedCmd[2], responses[uid_index].response, 4) == 0) { bool cl_finished = (uid_len == 4 && uid_index == UIDBCC1) || - (uid_len == 7 && uid_index == UIDBCC2) || - (uid_len == 10 && uid_index == UIDBCC3); + (uid_len == 7 && uid_index == UIDBCC2) || + (uid_len == 10 && uid_index == UIDBCC3); EmSendPrecompiledCmd(&responses[cl_finished ? SAK : SAKuid]); if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("SELECT CLx %02x%02x%02x%02x received", receivedCmd[2], receivedCmd[3], receivedCmd[4], receivedCmd[5]); if (cl_finished) { diff --git a/bootrom/bootrom.c b/bootrom/bootrom.c index e889bb7da..4e92bc95b 100644 --- a/bootrom/bootrom.c +++ b/bootrom/bootrom.c @@ -122,7 +122,7 @@ void UsbPacketReceived(uint8_t *packet, int len) { switch (c->cmd) { case CMD_DEVICE_INFO: { dont_ack = 1; - arg0 = DEVICE_INFO_FLAG_BOOTROM_PRESENT | + arg0 = DEVICE_INFO_FLAG_BOOTROM_PRESENT | DEVICE_INFO_FLAG_CURRENT_MODE_BOOTROM | DEVICE_INFO_FLAG_UNDERSTANDS_START_FLASH | DEVICE_INFO_FLAG_UNDERSTANDS_CHIP_INFO; diff --git a/client/cmdhf15.c b/client/cmdhf15.c index 9a40d03cd..9d5f3802d 100644 --- a/client/cmdhf15.c +++ b/client/cmdhf15.c @@ -1348,7 +1348,7 @@ static int CmdHF15CSetUID(const char *Cmd) { data[3][5] = uid[1]; data[3][6] = uid[0]; - for (int i=0; i<4; i++) { + for (int i = 0; i < 4; i++) { AddCrc15(data[i], 7); clearCommandBuffer(); diff --git a/client/cmdlf.c b/client/cmdlf.c index 8459eca3a..389e76ca9 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -957,7 +957,7 @@ static bool CheckChipType(bool getDeviceData) { retval = true; goto out; } - + //check for t55xx chip... if (tryDetectP1(true)) { PrintAndLogEx(SUCCESS, "\nChipset detection : " _GREEN_("T55xx") "found"); @@ -1084,8 +1084,8 @@ int CmdLFfind(const char *Cmd) { } out: // identify chipset - if ( CheckChipType(isOnline) == false ) { - PrintAndLogEx(DEBUG, "Automatic chip type detection " _RED_("failed") ); + if (CheckChipType(isOnline) == false) { + PrintAndLogEx(DEBUG, "Automatic chip type detection " _RED_("failed")); } return PM3_SUCCESS; } diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c index aa0add5fa..ce9a9ea0a 100644 --- a/client/cmdlfem4x.c +++ b/client/cmdlfem4x.c @@ -1373,10 +1373,10 @@ static void printEM4x05config(uint32_t wordData) { PrintAndLogEx(NORMAL, " PSK CF: %u | %s", PSKcf, cf); PrintAndLogEx(NORMAL, " Delay: %u | %s", delay, cdelay); PrintAndLogEx(NORMAL, " LastWordR: %02u | Address of last word for default read - meaning %u blocks are output", LWR, numblks); - PrintAndLogEx(NORMAL, " ReadLogin: %u | Read login is %s", readLogin, readLogin ? _YELLOW_("required") : _GREEN_("not required") ); - PrintAndLogEx(NORMAL, " ReadHKL: %u | Read housekeeping words login is %s", readHKL, readHKL ? _YELLOW_("required") : _GREEN_("not required") ); - PrintAndLogEx(NORMAL, "WriteLogin: %u | Write login is %s", writeLogin, writeLogin ? _YELLOW_("required") : _GREEN_("not required") ); - PrintAndLogEx(NORMAL, " WriteHKL: %u | Write housekeeping words login is %s", writeHKL, writeHKL ? _YELLOW_("required") : _GREEN_("not Required") ); + PrintAndLogEx(NORMAL, " ReadLogin: %u | Read login is %s", readLogin, readLogin ? _YELLOW_("required") : _GREEN_("not required")); + PrintAndLogEx(NORMAL, " ReadHKL: %u | Read housekeeping words login is %s", readHKL, readHKL ? _YELLOW_("required") : _GREEN_("not required")); + PrintAndLogEx(NORMAL, "WriteLogin: %u | Write login is %s", writeLogin, writeLogin ? _YELLOW_("required") : _GREEN_("not required")); + PrintAndLogEx(NORMAL, " WriteHKL: %u | Write housekeeping words login is %s", writeHKL, writeHKL ? _YELLOW_("required") : _GREEN_("not Required")); PrintAndLogEx(NORMAL, " R.A.W.: %u | Read after write is %s", raw, raw ? "on" : "off"); PrintAndLogEx(NORMAL, " Disable: %u | Disable command is %s", disable, disable ? "accepted" : "not accepted"); PrintAndLogEx(NORMAL, " R.T.F.: %u | Reader talk first is %s", rtf, rtf ? _YELLOW_("enabled") : "disabled"); @@ -1396,7 +1396,7 @@ static void printEM4x05info(uint32_t block0, uint32_t serial) { snprintf(ctstr + strlen(ctstr), sizeof(ctstr) - strlen(ctstr), _YELLOW_("%s"), "EM4305"); break; case 8: - snprintf(ctstr + strlen(ctstr), sizeof(ctstr) - strlen(ctstr), _YELLOW_("%s"), "EM4205"); + snprintf(ctstr + strlen(ctstr), sizeof(ctstr) - strlen(ctstr), _YELLOW_("%s"), "EM4205"); break; case 4: snprintf(ctstr + strlen(ctstr), sizeof(ctstr) - strlen(ctstr), _YELLOW_("%s"), "Unknown"); diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 04b2c6e9e..b1c03b514 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -2153,7 +2153,7 @@ bool tryDetectP1(bool getData) { } return false; } - + // try ask clock detect. it could be another type even if successful. clk = GetAskClock("", false); if (clk > 0) { @@ -2162,14 +2162,14 @@ bool tryDetectP1(bool getData) { (DemodBufferLen == 32 || DemodBufferLen == 64)) { return true; } - + st = true; if ((ASKDemod_ext("0 1 1", false, false, 1, &st) == PM3_SUCCESS) && preambleSearchEx(DemodBuffer, preamble, sizeof(preamble), &DemodBufferLen, &startIdx, false) && (DemodBufferLen == 32 || DemodBufferLen == 64)) { return true; } - + if ((ASKbiphaseDemod("0 0 0 2", false) == PM3_SUCCESS) && preambleSearchEx(DemodBuffer, preamble, sizeof(preamble), &DemodBufferLen, &startIdx, false) && (DemodBufferLen == 32 || DemodBufferLen == 64)) { @@ -2182,7 +2182,7 @@ bool tryDetectP1(bool getData) { return true; } } - + // try NRZ clock detect. it could be another type even if successful. clk = GetNrzClock("", false); //has the most false positives :( if (clk > 0) { diff --git a/client/cmdusart.c b/client/cmdusart.c index d632901ef..60b977430 100644 --- a/client/cmdusart.c +++ b/client/cmdusart.c @@ -314,7 +314,7 @@ static int CmdUsartBtFactory(const char *Cmd) { PrintAndLogEx(WARNING, "Is the add-on blue light blinking? (Say 'n' if you want to abort) [y/n]"); char input[3]; - if ((fgets(input,sizeof(input),stdin) == NULL) || (strncmp(input, "y\n", sizeof(input)) != 0)) { + if ((fgets(input, sizeof(input), stdin) == NULL) || (strncmp(input, "y\n", sizeof(input)) != 0)) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(FAILED, "Aborting."); return PM3_EOPABORTED; diff --git a/client/comms.c b/client/comms.c index 5aa704728..6fd41ecad 100644 --- a/client/comms.c +++ b/client/comms.c @@ -136,7 +136,7 @@ static void SendCommandNG_internal(uint16_t cmd, uint8_t *data, size_t len, bool txBufferNG.pre.ng = ng; txBufferNG.pre.length = len; txBufferNG.pre.cmd = cmd; - if ( len > 0 && data ) + if (len > 0 && data) memcpy(&txBufferNG.data, data, len); if ((conn.send_via_fpc_usart && conn.send_with_crc_on_fpc) || ((!conn.send_via_fpc_usart) && conn.send_with_crc_on_usb)) { diff --git a/client/deprecated-hid-flasher/flasher/sleep.h b/client/deprecated-hid-flasher/flasher/sleep.h index f3aac0c8f..ffb5486aa 100644 --- a/client/deprecated-hid-flasher/flasher/sleep.h +++ b/client/deprecated-hid-flasher/flasher/sleep.h @@ -6,18 +6,18 @@ #define SLEEP_H__ #ifdef _WIN32 - #include - #define msleep(n) Sleep(n) +#include +#define msleep(n) Sleep(n) #else - #include - #include - static void nsleep(uint64_t n) { - struct timespec timeout; - timeout.tv_sec = n / 1000000000; - timeout.tv_nsec = n % 1000000000; - while (nanosleep(&timeout, &timeout) && errno == EINTR); - } - #define msleep(n) nsleep(1000000 * (uint64_t)n) +#include +#include +static void nsleep(uint64_t n) { + struct timespec timeout; + timeout.tv_sec = n / 1000000000; + timeout.tv_nsec = n % 1000000000; + while (nanosleep(&timeout, &timeout) && errno == EINTR); +} +#define msleep(n) nsleep(1000000 * (uint64_t)n) #endif #endif diff --git a/client/flash.c b/client/flash.c index 3a1350c7c..5b4cd205e 100644 --- a/client/flash.c +++ b/client/flash.c @@ -347,7 +347,7 @@ static int wait_for_ack(PacketResponseNG *ack) { } // Go into flashing mode -int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t * chipinfo) { +int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t *chipinfo) { uint32_t state; if (enter_bootloader(serial_port_name) < 0) diff --git a/client/util.c b/client/util.c index a805b9c84..f6f89e0ff 100644 --- a/client/util.c +++ b/client/util.c @@ -61,8 +61,7 @@ int kbd_enter_pressed(void) { #include int kbd_enter_pressed(void) { int ret = 0; - while(kbhit()) - { + while (kbhit()) { ret |= getch() == '\r'; } return ret; @@ -178,8 +177,8 @@ bool CheckStringIsHEXValue(const char *value) { void hex_to_buffer(const uint8_t *buf, const uint8_t *hex_data, const size_t hex_len, const size_t hex_max_len, const size_t min_str_len, const size_t spaces_between, bool uppercase) { - if (buf == NULL ) return; - + if (buf == NULL) return; + char *tmp = (char *)buf; size_t i; memset(tmp, 0x00, hex_max_len); @@ -205,16 +204,16 @@ void hex_to_buffer(const uint8_t *buf, const uint8_t *hex_data, const size_t hex // printing and converting functions void print_hex(const uint8_t *data, const size_t len) { - if (data == NULL || len == 0 ) return; - + if (data == NULL || len == 0) return; + for (size_t i = 0; i < len; i++) printf("%02x ", data[i]); printf("\n"); } void print_hex_break(const uint8_t *data, const size_t len, uint8_t breaks) { - if (data == NULL || len == 0 ) return; - + if (data == NULL || len == 0) return; + int rownum = 0; printf("[%02d] | ", rownum); for (size_t i = 0; i < len; ++i) { diff --git a/common/lfdemod.c b/common/lfdemod.c index ef18b59ef..f8daec079 100644 --- a/common/lfdemod.c +++ b/common/lfdemod.c @@ -103,7 +103,7 @@ void computeSignalProperties(uint8_t *samples, uint32_t size) { // we can detect noise signalprop.isnoise = signalprop.amplitude < NOISE_AMPLITUDE_THRESHOLD; - if (g_debugMode) + if (g_debugMode) printSignal(); } @@ -1365,8 +1365,8 @@ static int millerRawDecode(uint8_t *bits, size_t *size, int invert) { int BiphaseRawDecode(uint8_t *bits, size_t *size, int *offset, int invert) { //sanity check if (*size < 51) return -1; - - if ( *offset < 0 ) *offset = 0; + + if (*offset < 0) *offset = 0; uint16_t bitnum = 0; uint16_t errCnt = 0; From edcd2b974e8e88bc296a52319887e8bd870622c0 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 13 Jul 2019 13:05:38 +0200 Subject: [PATCH 0055/1854] wsl: no driver required --- .../Windows-Installation-Instructions.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/doc/md/Installation_Instructions/Windows-Installation-Instructions.md b/doc/md/Installation_Instructions/Windows-Installation-Instructions.md index 73a5358e9..eacdc4b62 100644 --- a/doc/md/Installation_Instructions/Windows-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Windows-Installation-Instructions.md @@ -88,11 +88,6 @@ Install WSL with e.g. the standard Ubuntu. For WSL configuration, see [Manage and configure Windows Subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl/wsl-config). -## Driver Installation - -Install required drivers for your Windows installation. You may need admin privileges to do this. -Step by step guides are online such as [RiscCorps](https://store.ryscc.com/blogs/news/how-to-install-a-proxmark3-driver-on-windows-10). - ## X Server Installation If you want to run the graphical components of the Proxmark3 client, you need to install a X Server such as [VcXsrv](https://sourceforge.net/projects/vcxsrv/) or [Xming](https://sourceforge.net/projects/xming/) and launch it, e.g. by executing XLaunch. From 735077f358ced58fa6604d9b712fc0a6a6c5644f Mon Sep 17 00:00:00 2001 From: Eloff Date: Sat, 13 Jul 2019 18:26:52 +0300 Subject: [PATCH 0056/1854] Does clear trace log only at first call 'hf mf chk', to save whole process history --- client/cmdhfmf.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index a81209215..0bed91dfd 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -1959,6 +1959,8 @@ static int CmdHF14AMfChk(const char *Cmd) { // fast push mode conn.block_after_ACK = true; + // clear trace log by first check keys call only + bool clearLog = true; // check keys. for (trgKeyType = (keyType == 2) ? 0 : keyType; trgKeyType < 2; (keyType == 2) ? (++trgKeyType) : (trgKeyType = 2)) { @@ -1979,11 +1981,13 @@ static int CmdHF14AMfChk(const char *Cmd) { uint16_t size = keycnt - c > max_keys ? max_keys : keycnt - c; - if (mfCheckKeys(b, trgKeyType, true, size, &keyBlock[6 * c], &key64) == PM3_SUCCESS) { + if (mfCheckKeys(b, trgKeyType, clearLog, size, &keyBlock[6 * c], &key64) == PM3_SUCCESS) { e_sector[i].Key[trgKeyType] = key64; e_sector[i].foundKey[trgKeyType] = true; + clearLog = false; break; } + clearLog = false; } b < 127 ? (b += 4) : (b += 16); } From 25e2ab9a4c55a0de2d4656e50e46f20f4f880d16 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 13 Jul 2019 18:29:36 +0200 Subject: [PATCH 0057/1854] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2fb002175..8dd057c73 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Change: Don't clear trace log during 'hf mf chk', to save whole process history (@McEloff) - Add support for WSL in proxmark.sh (@doegox) - Add documentation for usage of Proxmark3 under WSL (@doegox) - Change: replace ukbhit by kbd_enter_pressed, not requiring tcgetattr (@xianglin1998/@doegox) From bb3c5e364ef3c9b94a1fa6f344380f7cbbdfafbb Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 14 Jul 2019 00:30:57 +0200 Subject: [PATCH 0058/1854] remove perror --- client/emv/emv_pk.c | 4 ++-- client/flash.c | 1 - uart/uart_posix.c | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/client/emv/emv_pk.c b/client/emv/emv_pk.c index ae23c8470..b03567440 100644 --- a/client/emv/emv_pk.c +++ b/client/emv/emv_pk.c @@ -24,7 +24,7 @@ #include "emv_pk.h" #include "crypto.h" #include "proxmark3.h" - +#include "util.h" #include #include #include @@ -398,7 +398,7 @@ static struct emv_pk *emv_pk_get_ca_pk_from_file(const char *fname, FILE *f = fopen(fname, "r"); if (!f) { - perror("fopen"); + PrintAndLogEx(ERR, "Error: can't open file %s.", fname); return NULL; } diff --git a/client/flash.c b/client/flash.c index 5b4cd205e..e41b47fb0 100644 --- a/client/flash.c +++ b/client/flash.c @@ -192,7 +192,6 @@ int flash_load(flash_file_t *ctx, const char *name, int can_write_bl) { fd = fopen(name, "rb"); if (!fd) { PrintAndLogEx(ERR, _RED_("Could not open file") "%s >>> ", name); - perror(NULL); goto fail; } diff --git a/uart/uart_posix.c b/uart/uart_posix.c index 93b7229ce..22cc75207 100644 --- a/uart/uart_posix.c +++ b/uart/uart_posix.c @@ -238,7 +238,7 @@ void uart_close(const serial_port sp) { // Does the system allows us to place a lock on this file descriptor int err = fcntl(spu->fd, F_SETLK, &fl); if (err == -1) { - //perror("fcntl"); + printf("[!] UART error while closing port\n"); } close(spu->fd); free(sp); From 8bf4b4ad97b213da18481bc18ea6942a2a79b873 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 14 Jul 2019 00:35:18 +0200 Subject: [PATCH 0059/1854] Promote WARNING to ERR on some error msgs --- client/cmdcrc.c | 2 +- client/cmddata.c | 14 ++++++------ client/cmdflashmem.c | 6 ++--- client/cmdhf14a.c | 2 +- client/cmdhf15.c | 8 +++---- client/cmdhffido.c | 4 ++-- client/cmdhficlass.c | 18 +++++++-------- client/cmdhflegic.c | 4 ++-- client/cmdhfmf.c | 34 ++++++++++++++-------------- client/cmdhfmfhard.c | 24 ++++++++++---------- client/cmdhfmfu.c | 18 +++++++-------- client/cmdhftopaz.c | 10 ++++---- client/cmdlf.c | 6 ++--- client/cmdlfawid.c | 8 +++---- client/cmdlfem4x.c | 18 +++++++-------- client/cmdlffdx.c | 4 ++-- client/cmdlfguard.c | 6 ++--- client/cmdlfhitag.c | 2 +- client/cmdlfio.c | 4 ++-- client/cmdlfjablotron.c | 4 ++-- client/cmdlfkeri.c | 2 +- client/cmdlfnedap.c | 6 ++--- client/cmdlfnoralsy.c | 6 ++--- client/cmdlfparadox.c | 2 +- client/cmdlfpresco.c | 2 +- client/cmdlfpyramid.c | 6 ++--- client/cmdlft55xx.c | 8 +++---- client/cmdlfti.c | 4 ++-- client/cmdlfviking.c | 2 +- client/cmdlfvisa2000.c | 2 +- client/cmdsmartcard.c | 6 ++--- client/comms.c | 8 +++---- client/emv/cmdemv.c | 14 ++++++------ client/emv/emvcore.c | 44 ++++++++++++++++++------------------ client/fido/fidocore.c | 2 +- client/loclass/elite_crack.c | 14 ++++++------ client/mifare/mad.c | 2 +- client/mifare/mifarehost.c | 6 ++--- 38 files changed, 166 insertions(+), 166 deletions(-) diff --git a/client/cmdcrc.c b/client/cmdcrc.c index 58cab45e5..af4baae45 100644 --- a/client/cmdcrc.c +++ b/client/cmdcrc.c @@ -248,7 +248,7 @@ int RunModel(char *inModel, char *inHexStr, bool reverse, char endian, char *res //set model c = mbynam(&model, inModel); if (!c) { - PrintAndLogEx(WARNING, "error: preset model '%s' not found. Use reveng -D to list presets. [%d]", inModel, c); + PrintAndLogEx(ERR, "error: preset model '%s' not found. Use reveng -D to list presets. [%d]", inModel, c); return 0; } if (c < 0) { diff --git a/client/cmddata.c b/client/cmddata.c index d6a4e8e73..e0e0f73c1 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -602,7 +602,7 @@ static int Cmdmandecoderaw(const char *Cmd) { } if (high > 7 || low < 0) { - PrintAndLogEx(WARNING, "Error: please raw demod the wave first then manchester raw decode"); + PrintAndLogEx(ERR, "Error: please raw demod the wave first then manchester raw decode"); return PM3_ESOFT; } @@ -611,7 +611,7 @@ static int Cmdmandecoderaw(const char *Cmd) { uint8_t alignPos = 0; errCnt = manrawdecode(bits, &size, invert, &alignPos); if (errCnt >= maxErr) { - PrintAndLogEx(WARNING, "Too many errors: %u", errCnt); + PrintAndLogEx(ERR, "Too many errors: %u", errCnt); return PM3_ESOFT; } @@ -658,16 +658,16 @@ static int CmdBiphaseDecodeRaw(const char *Cmd) { errCnt = BiphaseRawDecode(bits, &size, &offset, invert); if (errCnt < 0) { - PrintAndLogEx(WARNING, "Error during decode:%d", errCnt); + PrintAndLogEx(ERR, "Error during decode:%d", errCnt); return PM3_ESOFT; } if (errCnt > maxErr) { - PrintAndLogEx(WARNING, "Too many errors attempting to decode: %d", errCnt); + PrintAndLogEx(ERR, "Too many errors attempting to decode: %d", errCnt); return PM3_ESOFT; } if (errCnt > 0) - PrintAndLogEx(WARNING, "# Errors found during Demod (shown as " _YELLOW_("7")" in bit stream): %d", errCnt); + PrintAndLogEx(ERR, "# Errors found during Demod (shown as " _YELLOW_("7")" in bit stream): %d", errCnt); PrintAndLogEx(NORMAL, "Biphase Decoded using offset: %d - # invert:%d - data:", offset, invert); PrintAndLogEx(NORMAL, "%s", sprint_bin_break(bits, size, 32)); @@ -1290,7 +1290,7 @@ int CmdPSK1rawDemod(const char *Cmd) { int ans = PSKDemod(Cmd, true); //output if (ans != PM3_SUCCESS) { - if (g_debugMode) PrintAndLogEx(WARNING, "Error demoding: %d", ans); + if (g_debugMode) PrintAndLogEx(ERR, "Error demoding: %d", ans); return PM3_ESOFT; } PrintAndLogEx(NORMAL, "PSK1 demoded bitstream:"); @@ -1307,7 +1307,7 @@ static int CmdPSK2rawDemod(const char *Cmd) { int ans = PSKDemod(Cmd, true); if (ans != PM3_SUCCESS) { - if (g_debugMode) PrintAndLogEx(WARNING, "Error demoding: %d", ans); + if (g_debugMode) PrintAndLogEx(ERR, "Error demoding: %d", ans); return PM3_ESOFT; } psk1TOpsk2(DemodBuffer, DemodBufferLen); diff --git a/client/cmdflashmem.c b/client/cmdflashmem.c index dafda3ae6..6bab15cd9 100644 --- a/client/cmdflashmem.c +++ b/client/cmdflashmem.c @@ -136,7 +136,7 @@ static int CmdFlashMemRead(const char *Cmd) { return PM3_EINVARG; } if (start_index + len > FLASH_MEM_MAX_SIZE) { - PrintAndLogDevice(WARNING, "error, start_index + length is larger than available memory"); + PrintAndLogDevice(ERR, "error, start_index + length is larger than available memory"); return PM3_EOVFLOW; } @@ -258,7 +258,7 @@ static int CmdFlashMemLoad(const char *Cmd) { } if (datalen > FLASH_MEM_MAX_SIZE) { - PrintAndLogDevice(WARNING, "error, filesize is larger than available memory"); + PrintAndLogDevice(ERR, "error, filesize is larger than available memory"); free(data); return PM3_EOVFLOW; } @@ -354,7 +354,7 @@ static int CmdFlashMemSave(const char *Cmd) { uint8_t *dump = calloc(len, sizeof(uint8_t)); if (!dump) { - PrintAndLogDevice(WARNING, "error, cannot allocate memory "); + PrintAndLogDevice(ERR, "error, cannot allocate memory "); return PM3_EMALLOC; } diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index bb5144f0b..c138aefa1 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -798,7 +798,7 @@ int ExchangeAPDU14a(uint8_t *datain, int datainlen, bool activateField, bool lea vActivateField = false; if (*dataoutlen) { if (clen != datainlen) - PrintAndLogEx(WARNING, "APDU: I-block/R-block sequence error. Data len=%d, Sent=%d, Last packet len=%d", datainlen, clen, *dataoutlen); + PrintAndLogEx(ERR, "APDU: I-block/R-block sequence error. Data len=%d, Sent=%d, Last packet len=%d", datainlen, clen, *dataoutlen); break; } } while (clen < datainlen); diff --git a/client/cmdhf15.c b/client/cmdhf15.c index 9d5f3802d..65bc26010 100644 --- a/client/cmdhf15.c +++ b/client/cmdhf15.c @@ -564,7 +564,7 @@ static int CmdHF15Demod(const char *Cmd) { } if (mask != 0x01) { - PrintAndLogEx(WARNING, "Error, uneven octet! (discard extra bits!)"); + PrintAndLogEx(ERR, "Error, uneven octet! (discard extra bits!)"); PrintAndLogEx(NORMAL, " mask = %02x", mask); } PrintAndLogEx(NORMAL, "%d octets", k); @@ -634,7 +634,7 @@ static int CmdHF15Info(const char *Cmd) { recv = resp.data.asBytes; if (recv[0] & ISO15_RES_ERROR) { - PrintAndLogEx(WARNING, "iso15693 card returned error %i: %s", recv[0], TagErrorStr(recv[0])); + PrintAndLogEx(ERR, "iso15693 card returned error %i: %s", recv[0], TagErrorStr(recv[0])); return 3; } @@ -1069,7 +1069,7 @@ static int CmdHF15Read(const char *Cmd) { } if (recv[0] & ISO15_RES_ERROR) { - PrintAndLogEx(WARNING, "iso15693 card returned error %i: %s", recv[0], TagErrorStr(recv[0])); + PrintAndLogEx(ERR, "iso15693 card returned error %i: %s", recv[0], TagErrorStr(recv[0])); return 3; } @@ -1246,7 +1246,7 @@ static int CmdHF15Restore(const char *Cmd) { fclose(f); return 0; } else if (bytes_read != blocksize) { - PrintAndLogEx(WARNING, "File reading error (%s), %u bytes read instead of %u bytes.", filename, bytes_read, blocksize); + PrintAndLogEx(ERR, "File reading error (%s), %u bytes read instead of %u bytes.", filename, bytes_read, blocksize); fclose(f); return 2; } diff --git a/client/cmdhffido.c b/client/cmdhffido.c index 39b080dca..9db6583f6 100644 --- a/client/cmdhffido.c +++ b/client/cmdhffido.c @@ -351,7 +351,7 @@ static int CmdHFFidoRegister(const char *cmd) { if (res == -0x4e00) { PrintAndLogEx(WARNING, "Signature is NOT VALID."); } else { - PrintAndLogEx(WARNING, "Other signature check error: %x %s", (res < 0) ? -res : res, ecdsa_get_error(res)); + PrintAndLogEx(ERR, "Other signature check error: %x %s", (res < 0) ? -res : res, ecdsa_get_error(res)); } } else { PrintAndLogEx(SUCCESS, "Signature is OK."); @@ -577,7 +577,7 @@ static int CmdHFFidoAuthenticate(const char *cmd) { if (res == -0x4e00) { PrintAndLogEx(WARNING, "Signature is NOT VALID."); } else { - PrintAndLogEx(WARNING, "Other signature check error: %x %s", (res < 0) ? -res : res, ecdsa_get_error(res)); + PrintAndLogEx(ERR, "Other signature check error: %x %s", (res < 0) ? -res : res, ecdsa_get_error(res)); } } else { PrintAndLogEx(SUCCESS, "Signature is OK."); diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index ec2179ab3..f8d57556f 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -550,14 +550,14 @@ static int CmdHFiClassELoad(const char *Cmd) { fseek(f, 0, SEEK_SET); if (fsize <= 0) { - PrintAndLogDevice(WARNING, "error, when getting filesize"); + PrintAndLogDevice(ERR, "error, when getting filesize"); fclose(f); return 1; } uint8_t *dump = calloc(fsize, sizeof(uint8_t)); if (!dump) { - PrintAndLogDevice(WARNING, "error, cannot allocate memory "); + PrintAndLogDevice(ERR, "error, cannot allocate memory "); fclose(f); return 1; } @@ -569,7 +569,7 @@ static int CmdHFiClassELoad(const char *Cmd) { //Validate if (bytes_read < fsize) { - PrintAndLogDevice(WARNING, "error, could only read %d bytes (should be %d)", bytes_read, fsize); + PrintAndLogDevice(ERR, "error, could only read %d bytes (should be %d)", bytes_read, fsize); free(dump); return 1; } @@ -650,7 +650,7 @@ static int CmdHFiClassDecrypt(const char *Cmd) { fseek(f, 0, SEEK_SET); if (fsize <= 0) { - PrintAndLogEx(WARNING, "error, when getting filesize"); + PrintAndLogEx(ERR, "error, when getting filesize"); fclose(f); return 2; } @@ -665,7 +665,7 @@ static int CmdHFiClassDecrypt(const char *Cmd) { size_t bytes_read = fread(decrypted, 1, fsize, f); fclose(f); if (bytes_read == 0) { - PrintAndLogEx(WARNING, "file reading error"); + PrintAndLogEx(ERR, "file reading error"); free(decrypted); return 3; } @@ -1281,7 +1281,7 @@ static int CmdHFiClassCloneTag(const char *Cmd) { fseek(f, startblock * 8, SEEK_SET); size_t bytes_read = fread(tag_data, sizeof(iclass_block_t), endblock - startblock + 1, f); if (bytes_read == 0) { - PrintAndLogEx(WARNING, "file reading error."); + PrintAndLogEx(ERR, "file reading error."); fclose(f); return 2; } @@ -1448,7 +1448,7 @@ static int CmdHFiClass_loclass(const char *Cmd) { errors += testMAC(); errors += doKeyTests(0); errors += testElite(); - if (errors) PrintAndLogDevice(WARNING, "There were errors!!!"); + if (errors) PrintAndLogDevice(ERR, "There were errors!!!"); return errors; } return PM3_SUCCESS; @@ -1518,7 +1518,7 @@ static int CmdHFiClassReadTagFile(const char *Cmd) { fseek(f, 0, SEEK_SET); if (fsize <= 0) { - PrintAndLogEx(WARNING, "Error, when getting filesize"); + PrintAndLogEx(ERR, "Error, when getting filesize"); fclose(f); return 1; } @@ -1676,7 +1676,7 @@ static int loadKeys(char *filename) { fseek(f, 0, SEEK_SET); if (fsize <= 0) { - PrintAndLogEx(WARNING, "Error, when getting filesize"); + PrintAndLogEx(ERR, "Error, when getting filesize"); fclose(f); return 1; } diff --git a/client/cmdhflegic.c b/client/cmdhflegic.c index 8bd976030..03c5ecfcd 100644 --- a/client/cmdhflegic.c +++ b/client/cmdhflegic.c @@ -1037,7 +1037,7 @@ static int CmdLegicRestore(const char *Cmd) { fclose(f); if (bytes_read == 0) { - PrintAndLogEx(WARNING, "File reading error"); + PrintAndLogEx(ERR, "File reading error"); free(data); return 2; } @@ -1139,7 +1139,7 @@ static int CmdLegicELoad(const char *Cmd) { // load file size_t bytes_read = fread(data, 1, numofbytes, f); if (bytes_read == 0) { - PrintAndLogEx(WARNING, "File reading error"); + PrintAndLogEx(ERR, "File reading error"); free(data); fclose(f); f = NULL; diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 0bed91dfd..3ca958f80 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -765,7 +765,7 @@ static int CmdHF14AMfDump(const char *Cmd) { for (sectorNo = 0; sectorNo < numSectors; sectorNo++) { bytes_read = fread(keyA[sectorNo], 1, 6, f); if (bytes_read != 6) { - PrintAndLogEx(WARNING, "File reading error."); + PrintAndLogEx(ERR, "File reading error."); fclose(f); return PM3_EFILE; } @@ -775,7 +775,7 @@ static int CmdHF14AMfDump(const char *Cmd) { for (sectorNo = 0; sectorNo < numSectors; sectorNo++) { bytes_read = fread(keyB[sectorNo], 1, 6, f); if (bytes_read != 6) { - PrintAndLogEx(WARNING, "File reading error."); + PrintAndLogEx(ERR, "File reading error."); fclose(f); return PM3_EFILE; } @@ -984,7 +984,7 @@ static int CmdHF14AMfRestore(const char *Cmd) { for (sectorNo = 0; sectorNo < numSectors; sectorNo++) { bytes_read = fread(keyA[sectorNo], 1, 6, fkeys); if (bytes_read != 6) { - PrintAndLogEx(WARNING, "File reading error " _YELLOW_("%s"), keyFilename); + PrintAndLogEx(ERR, "File reading error " _YELLOW_("%s"), keyFilename); fclose(fkeys); return 2; } @@ -993,7 +993,7 @@ static int CmdHF14AMfRestore(const char *Cmd) { for (sectorNo = 0; sectorNo < numSectors; sectorNo++) { bytes_read = fread(keyB[sectorNo], 1, 6, fkeys); if (bytes_read != 6) { - PrintAndLogEx(WARNING, "File reading error " _YELLOW_("%s"), keyFilename); + PrintAndLogEx(ERR, "File reading error " _YELLOW_("%s"), keyFilename); fclose(fkeys); return 2; } @@ -1021,7 +1021,7 @@ static int CmdHF14AMfRestore(const char *Cmd) { memcpy(data, key, 6); bytes_read = fread(bldata, 1, 16, fdump); if (bytes_read != 16) { - PrintAndLogEx(WARNING, "File reading error " _YELLOW_("%s"), dataFilename); + PrintAndLogEx(ERR, "File reading error " _YELLOW_("%s"), dataFilename); fclose(fdump); fdump = NULL; return 2; @@ -1129,7 +1129,7 @@ static int CmdHF14AMfNested(const char *Cmd) { int16_t isOK = mfnested(blockNo, keyType, key, trgBlockNo, trgKeyType, keyBlock, true); switch (isOK) { case -1 : - PrintAndLogEx(WARNING, "Error: No response from Proxmark3.\n"); + PrintAndLogEx(ERR, "Error: No response from Proxmark3.\n"); break; case -2 : PrintAndLogEx(WARNING, "Button pressed. Aborted.\n"); @@ -1162,7 +1162,7 @@ static int CmdHF14AMfNested(const char *Cmd) { } return PM3_SUCCESS; default : - PrintAndLogEx(WARNING, "Unknown Error.\n"); + PrintAndLogEx(ERR, "Unknown Error.\n"); } return PM3_SUCCESS; } else { // ------------------------------------ multiple sectors working @@ -1199,7 +1199,7 @@ static int CmdHF14AMfNested(const char *Cmd) { int16_t isOK = mfnested(blockNo, keyType, key, FirstBlockOfSector(sectorNo), trgKeyType, keyBlock, calibrate); switch (isOK) { case -1 : - PrintAndLogEx(WARNING, "error: No response from Proxmark3.\n"); + PrintAndLogEx(ERR, "error: No response from Proxmark3.\n"); break; case -2 : PrintAndLogEx(WARNING, "button pressed. Aborted.\n"); @@ -1221,7 +1221,7 @@ static int CmdHF14AMfNested(const char *Cmd) { continue; default : - PrintAndLogEx(WARNING, "unknown Error.\n"); + PrintAndLogEx(ERR, "unknown Error.\n"); } free(e_sector); return PM3_ESOFT; @@ -1502,7 +1502,7 @@ static int CmdHF14AMfNestedHard(const char *Cmd) { if (isOK) { switch (isOK) { case 1 : - PrintAndLogEx(WARNING, "Error: No response from Proxmark3.\n"); + PrintAndLogEx(ERR, "Error: No response from Proxmark3.\n"); break; case 2 : PrintAndLogEx(NORMAL, "Button pressed. Aborted.\n"); @@ -2765,7 +2765,7 @@ static int CmdHF14AMfEKeyPrn(const char *Cmd) { PrintAndLogEx(NORMAL, "|---|----------------|----------------|"); for (i = 0; i < numSectors; i++) { if (mfEmlGetMem(data, FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1, 1) != PM3_SUCCESS) { - PrintAndLogEx(WARNING, "error get block %d", FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1); + PrintAndLogEx(ERR, "error get block %d", FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1); break; } uint64_t keyA = bytes_to_num(data, 6); @@ -2828,7 +2828,7 @@ static int CmdHF14AMfCSetUID(const char *Cmd) { res = mfCSetUID(uid, (atqaPresent) ? atqa : NULL, (atqaPresent) ? sak : NULL, oldUid, wipeCard); if (res) { - PrintAndLogEx(WARNING, "Can't set UID. error=%d", res); + PrintAndLogEx(ERR, "Can't set UID. error=%d", res); return PM3_ESOFT; } @@ -2858,7 +2858,7 @@ static int CmdHF14AMfCSetBlk(const char *Cmd) { res = mfCSetBlock(blockNo, block, NULL, params); if (res) { - PrintAndLogEx(WARNING, "Can't write block. error=%d", res); + PrintAndLogEx(ERR, "Can't write block. error=%d", res); return PM3_ESOFT; } return PM3_SUCCESS; @@ -2933,7 +2933,7 @@ static int CmdHF14AMfCLoad(const char *Cmd) { // 64 or 256blocks. if (datalen != 1024 && datalen != 4096) { - PrintAndLogEx(WARNING, "File content error. "); + PrintAndLogEx(ERR, "File content error. "); free(data); return PM3_EFILE; } @@ -2972,7 +2972,7 @@ static int CmdHF14AMfCLoad(const char *Cmd) { // 64 or 256blocks. if (blockNum != 16 * 4 && blockNum != 32 * 4 + 8 * 16) { - PrintAndLogEx(WARNING, "File content error. There must be 64 blocks"); + PrintAndLogEx(ERR, "File content error. There must be 64 blocks"); free(data); return PM3_EFILE; } @@ -2994,7 +2994,7 @@ static int CmdHF14AMfCGetBlk(const char *Cmd) { int res = mfCGetBlock(blockNo, data, MAGIC_SINGLE); if (res) { - PrintAndLogEx(WARNING, "Can't read block. error=%d", res); + PrintAndLogEx(ERR, "Can't read block. error=%d", res); return PM3_ESOFT; } @@ -3045,7 +3045,7 @@ static int CmdHF14AMfCGetSc(const char *Cmd) { int res = mfCGetBlock(start + i, data, flags); if (res) { - PrintAndLogEx(WARNING, "Can't read block. %d error=%d", start + i, res); + PrintAndLogEx(ERR, "Can't read block. %d error=%d", start + i, res); return PM3_ESOFT; } PrintAndLogEx(NORMAL, "%3d | %s", start + i, sprint_hex(data, 16)); diff --git a/client/cmdhfmfhard.c b/client/cmdhfmfhard.c index 2b96d8d77..4de46d36a 100644 --- a/client/cmdhfmfhard.c +++ b/client/cmdhfmfhard.c @@ -258,7 +258,7 @@ static void init_bitflip_bitarrays(void) { fseek(statesfile, 0, SEEK_END); int fsize = ftell(statesfile); if (fsize == -1) { - PrintAndLogEx(WARNING, "File read error with %s. Aborting...\n", state_file_name); + PrintAndLogEx(ERR, "File read error with %s. Aborting...\n", state_file_name); fclose(statesfile); exit(5); } @@ -267,7 +267,7 @@ static void init_bitflip_bitarrays(void) { uint8_t input_buffer[filesize]; size_t bytesread = fread(input_buffer, 1, filesize, statesfile); if (bytesread != filesize) { - PrintAndLogEx(WARNING, "File read error with %s. Aborting...\n", state_file_name); + PrintAndLogEx(ERR, "File read error with %s. Aborting...\n", state_file_name); fclose(statesfile); //inflateEnd(&compressed_stream); exit(5); @@ -279,7 +279,7 @@ static void init_bitflip_bitarrays(void) { if ((float)count / (1 << 24) < IGNORE_BITFLIP_THRESHOLD) { uint32_t *bitset = (uint32_t *)malloc_bitarray(sizeof(uint32_t) * (1 << 19)); if (bitset == NULL) { - PrintAndLogEx(WARNING, "Out of memory error in init_bitflip_statelists(). Aborting...\n"); + PrintAndLogEx(ERR, "Out of memory error in init_bitflip_statelists(). Aborting...\n"); inflateEnd(&compressed_stream); exit(4); } @@ -390,7 +390,7 @@ static void init_part_sum_bitarrays(void) { for (uint16_t part_sum_a0 = 0; part_sum_a0 < NUM_PART_SUMS; part_sum_a0++) { part_sum_a0_bitarrays[odd_even][part_sum_a0] = (uint32_t *)malloc_bitarray(sizeof(uint32_t) * (1 << 19)); if (part_sum_a0_bitarrays[odd_even][part_sum_a0] == NULL) { - PrintAndLogEx(WARNING, "Out of memory error in init_part_suma0_statelists(). Aborting...\n"); + PrintAndLogEx(ERR, "Out of memory error in init_part_suma0_statelists(). Aborting...\n"); exit(4); } clear_bitarray24(part_sum_a0_bitarrays[odd_even][part_sum_a0]); @@ -410,7 +410,7 @@ static void init_part_sum_bitarrays(void) { for (uint16_t part_sum_a8 = 0; part_sum_a8 < NUM_PART_SUMS; part_sum_a8++) { part_sum_a8_bitarrays[odd_even][part_sum_a8] = (uint32_t *)malloc_bitarray(sizeof(uint32_t) * (1 << 19)); if (part_sum_a8_bitarrays[odd_even][part_sum_a8] == NULL) { - PrintAndLogEx(WARNING, "Out of memory error in init_part_suma8_statelists(). Aborting...\n"); + PrintAndLogEx(ERR, "Out of memory error in init_part_suma8_statelists(). Aborting...\n"); exit(4); } clear_bitarray24(part_sum_a8_bitarrays[odd_even][part_sum_a8]); @@ -449,7 +449,7 @@ static void init_sum_bitarrays(void) { for (odd_even_t odd_even = EVEN_STATE; odd_even <= ODD_STATE; odd_even++) { sum_a0_bitarrays[odd_even][sum_a0] = (uint32_t *)malloc_bitarray(sizeof(uint32_t) * (1 << 19)); if (sum_a0_bitarrays[odd_even][sum_a0] == NULL) { - PrintAndLogEx(WARNING, "Out of memory error in init_sum_bitarrays(). Aborting...\n"); + PrintAndLogEx(ERR, "Out of memory error in init_sum_bitarrays(). Aborting...\n"); exit(4); } clear_bitarray24(sum_a0_bitarrays[odd_even][sum_a0]); @@ -564,14 +564,14 @@ static void init_nonce_memory(void) { } nonces[i].states_bitarray[EVEN_STATE] = (uint32_t *)malloc_bitarray(sizeof(uint32_t) * (1 << 19)); if (nonces[i].states_bitarray[EVEN_STATE] == NULL) { - PrintAndLogEx(WARNING, "Out of memory error in init_nonce_memory(). Aborting...\n"); + PrintAndLogEx(ERR, "Out of memory error in init_nonce_memory(). Aborting...\n"); exit(4); } set_bitarray24(nonces[i].states_bitarray[EVEN_STATE]); nonces[i].num_states_bitarray[EVEN_STATE] = 1 << 24; nonces[i].states_bitarray[ODD_STATE] = (uint32_t *)malloc_bitarray(sizeof(uint32_t) * (1 << 19)); if (nonces[i].states_bitarray[ODD_STATE] == NULL) { - PrintAndLogEx(WARNING, "Out of memory error in init_nonce_memory(). Aborting...\n"); + PrintAndLogEx(ERR, "Out of memory error in init_nonce_memory(). Aborting...\n"); exit(4); } set_bitarray24(nonces[i].states_bitarray[ODD_STATE]); @@ -1048,7 +1048,7 @@ static int read_nonce_file(char *filename) { hardnested_print_progress(0, progress_text, (float)(1LL << 47), 0); size_t bytes_read = fread(read_buf, 1, 6, fnonces); if (bytes_read != 6) { - PrintAndLogEx(WARNING, "File reading error."); + PrintAndLogEx(ERR, "File reading error."); fclose(fnonces); return 1; } @@ -1711,12 +1711,12 @@ static void add_matching_states(statelist_t *candidates, uint8_t part_sum_a0, ui const uint32_t worstcase_size = 1 << 20; candidates->states[odd_even] = (uint32_t *)malloc(sizeof(uint32_t) * worstcase_size); if (candidates->states[odd_even] == NULL) { - PrintAndLogEx(WARNING, "Out of memory error in add_matching_states() - statelist.\n"); + PrintAndLogEx(ERR, "Out of memory error in add_matching_states() - statelist.\n"); exit(4); } uint32_t *candidates_bitarray = (uint32_t *)malloc_bitarray(sizeof(uint32_t) * worstcase_size); if (candidates_bitarray == NULL) { - PrintAndLogEx(WARNING, "Out of memory error in add_matching_states() - bitarray.\n"); + PrintAndLogEx(ERR, "Out of memory error in add_matching_states() - bitarray.\n"); free(candidates->states[odd_even]); exit(4); } @@ -1772,7 +1772,7 @@ static void add_bitflip_candidates(uint8_t byte) { uint32_t worstcase_size = nonces[byte].num_states_bitarray[odd_even] + 1; candidates1->states[odd_even] = (uint32_t *)malloc(sizeof(uint32_t) * worstcase_size); if (candidates1->states[odd_even] == NULL) { - PrintAndLogEx(WARNING, "Out of memory error in add_bitflip_candidates().\n"); + PrintAndLogEx(ERR, "Out of memory error in add_bitflip_candidates().\n"); exit(4); } diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index eb7d26c4f..91e223427 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -1232,7 +1232,7 @@ static int CmdHF14AMfUInfo(const char *Cmd) { status = ul_read(0, data, sizeof(data)); if (status == -1) { DropField(); - PrintAndLogEx(WARNING, "Error: tag didn't answer to READ"); + PrintAndLogEx(ERR, "Error: tag didn't answer to READ"); return status; } else if (status == 16) { ul_print_default(data); @@ -1248,7 +1248,7 @@ static int CmdHF14AMfUInfo(const char *Cmd) { uint8_t ulc_conf[16] = {0x00}; status = ul_read(0x28, ulc_conf, sizeof(ulc_conf)); if (status == -1) { - PrintAndLogEx(WARNING, "Error: tag didn't answer to READ UL-C"); + PrintAndLogEx(ERR, "Error: tag didn't answer to READ UL-C"); DropField(); return status; } @@ -1263,7 +1263,7 @@ static int CmdHF14AMfUInfo(const char *Cmd) { status = ul_read(0x2C, ulc_deskey, sizeof(ulc_deskey)); if (status == -1) { DropField(); - PrintAndLogEx(WARNING, "Error: tag didn't answer to READ magic"); + PrintAndLogEx(ERR, "Error: tag didn't answer to READ magic"); return status; } if (status == 16) ulc_print_3deskey(ulc_deskey); @@ -1306,7 +1306,7 @@ static int CmdHF14AMfUInfo(const char *Cmd) { uint8_t ulev1_signature[32] = {0x00}; status = ulev1_readSignature(ulev1_signature, sizeof(ulev1_signature)); if (status == -1) { - PrintAndLogEx(WARNING, "Error: tag didn't answer to READ SIGNATURE"); + PrintAndLogEx(ERR, "Error: tag didn't answer to READ SIGNATURE"); DropField(); return status; } @@ -1322,7 +1322,7 @@ static int CmdHF14AMfUInfo(const char *Cmd) { uint8_t version[10] = {0x00}; status = ulev1_getVersion(version, sizeof(version)); if (status == -1) { - PrintAndLogEx(WARNING, "Error: tag didn't answer to GETVERSION"); + PrintAndLogEx(ERR, "Error: tag didn't answer to GETVERSION"); DropField(); return status; } else if (status == 10) { @@ -1346,7 +1346,7 @@ static int CmdHF14AMfUInfo(const char *Cmd) { if (startconfigblock) { // if we know where the config block is... status = ul_read(startconfigblock, ulev1_conf, sizeof(ulev1_conf)); if (status == -1) { - PrintAndLogEx(WARNING, "Error: tag didn't answer to READ EV1"); + PrintAndLogEx(ERR, "Error: tag didn't answer to READ EV1"); DropField(); return status; } else if (status == 16) { @@ -2134,7 +2134,7 @@ static int CmdHF14AMfURestore(const char *Cmd) { long fsize = ftell(f); fseek(f, 0, SEEK_SET); if (fsize <= 0) { - PrintAndLogEx(WARNING, "Error, when getting filesize"); + PrintAndLogEx(ERR, "Error, when getting filesize"); fclose(f); return 1; } @@ -2150,7 +2150,7 @@ static int CmdHF14AMfURestore(const char *Cmd) { size_t bytes_read = fread(dump, 1, fsize, f); fclose(f); if (bytes_read < MFU_DUMP_PREFIX_LENGTH) { - PrintAndLogEx(WARNING, "Error, dump file is too small"); + PrintAndLogEx(ERR, "Error, dump file is too small"); free(dump); return 1; } @@ -2167,7 +2167,7 @@ static int CmdHF14AMfURestore(const char *Cmd) { uint8_t pages = (bytes_read - MFU_DUMP_PREFIX_LENGTH) / 4; if (pages - 1 != mem->pages) { - PrintAndLogEx(WARNING, "Error, invalid dump, wrong page count"); + PrintAndLogEx(ERR, "Error, invalid dump, wrong page count"); free(dump); return 1; } diff --git a/client/cmdhftopaz.c b/client/cmdhftopaz.c index 2b743a574..d604d4baf 100644 --- a/client/cmdhftopaz.c +++ b/client/cmdhftopaz.c @@ -321,7 +321,7 @@ static void topaz_print_control_TLVs(uint8_t *memory) { static int topaz_read_dynamic_data(void) { // first read the remaining block of segment 0 if (topaz_read_block(topaz_tag.uid, 0x0f, &topaz_tag.dynamic_memory[0]) == -1) { - PrintAndLogEx(WARNING, "Error while reading dynamic memory block %02x. Aborting...", 0x0f); + PrintAndLogEx(ERR, "Error while reading dynamic memory block %02x. Aborting...", 0x0f); return -1; } @@ -329,7 +329,7 @@ static int topaz_read_dynamic_data(void) { uint8_t max_segment = topaz_tag.size / 128 - 1; for (uint8_t segment = 1; segment <= max_segment; segment++) { if (topaz_read_segment(topaz_tag.uid, segment, &topaz_tag.dynamic_memory[(segment - 1) * 128 + 8]) == -1) { - PrintAndLogEx(WARNING, "Error while reading dynamic memory block %02x. Aborting...", 0x0f); + PrintAndLogEx(ERR, "Error while reading dynamic memory block %02x. Aborting...", 0x0f); return -1; } } @@ -381,7 +381,7 @@ static int CmdHFTopazReader(const char *Cmd) { status = topaz_select(atqa, rid_response); if (status == -1) { - if (verbose) PrintAndLogEx(WARNING, "Error: couldn't receive ATQA"); + if (verbose) PrintAndLogEx(ERR, "Error: couldn't receive ATQA"); return -1; } @@ -393,7 +393,7 @@ static int CmdHFTopazReader(const char *Cmd) { } if (status == -2) { - PrintAndLogEx(WARNING, "Error: tag didn't answer to RID"); + PrintAndLogEx(ERR, "Error: tag didn't answer to RID"); topaz_switch_off_field(); return -1; } @@ -411,7 +411,7 @@ static int CmdHFTopazReader(const char *Cmd) { status = topaz_rall(uid_echo, rall_response); if (status == -1) { - PrintAndLogEx(WARNING, "Error: tag didn't answer to RALL"); + PrintAndLogEx(ERR, "Error: tag didn't answer to RALL"); topaz_switch_off_field(); return -1; } diff --git a/client/cmdlf.c b/client/cmdlf.c index 389e76ca9..42b26be0d 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -573,7 +573,7 @@ int CmdLFfskSim(const char *Cmd) { dataLen = hextobinarray((char *)data, hexData); if (dataLen == 0) errors = true; - if (errors) PrintAndLogEx(WARNING, "Error getting hex data"); + if (errors) PrintAndLogEx(ERR, "Error getting hex data"); cmdp += 2; break; default: @@ -685,7 +685,7 @@ int CmdLFaskSim(const char *Cmd) { dataLen = hextobinarray((char *)data, hexData); if (dataLen == 0) errors = true; - if (errors) PrintAndLogEx(WARNING, "Error getting hex data, datalen: %d", dataLen); + if (errors) PrintAndLogEx(ERR, "Error getting hex data, datalen: %d", dataLen); cmdp += 2; break; default: @@ -788,7 +788,7 @@ int CmdLFpskSim(const char *Cmd) { dataLen = hextobinarray((char *)data, hexData); if (dataLen == 0) errors = true; - if (errors) PrintAndLogEx(WARNING, "Error getting hex data"); + if (errors) PrintAndLogEx(ERR, "Error getting hex data"); cmdp += 2; break; default: diff --git a/client/cmdlfawid.c b/client/cmdlfawid.c index 1c2d96004..386d14e5e 100644 --- a/client/cmdlfawid.c +++ b/client/cmdlfawid.c @@ -103,7 +103,7 @@ static int sendTry(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint32_t delay, uin PrintAndLogEx(INFO, "Trying FC: %u; CN: %u", fc, cn); if (getAWIDBits(fmtlen, fc, cn, bits) != PM3_SUCCESS) { - PrintAndLogEx(WARNING, "Error with tag bitstream generation."); + PrintAndLogEx(ERR, "Error with tag bitstream generation."); return PM3_ESOFT; } @@ -333,7 +333,7 @@ static int CmdAWIDSim(const char *Cmd) { verify_values(&fmtlen, &fc, &cn); if (getAWIDBits(fmtlen, fc, cn, bs) != PM3_SUCCESS) { - PrintAndLogEx(WARNING, "Error with tag bitstream generation."); + PrintAndLogEx(ERR, "Error with tag bitstream generation."); return PM3_ESOFT; } @@ -388,7 +388,7 @@ static int CmdAWIDClone(const char *Cmd) { verify_values(&fmtlen, &fc, &cn); if (getAWIDBits(fmtlen, fc, cn, bs) != PM3_SUCCESS) { - PrintAndLogEx(WARNING, "Error with tag bitstream generation."); + PrintAndLogEx(ERR, "Error with tag bitstream generation."); return PM3_ESOFT; } @@ -419,7 +419,7 @@ static int CmdAWIDClone(const char *Cmd) { SendCommandNG(CMD_T55XX_WRITE_BLOCK, (uint8_t *)&ng, sizeof(ng)); if (!WaitForResponseTimeout(CMD_T55XX_WRITE_BLOCK, &resp, T55XX_WRITE_TIMEOUT)) { - PrintAndLogEx(WARNING, "Error occurred, device did not respond during write operation."); + PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); return PM3_ETIMEOUT; } } diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c index ce9a9ea0a..aaf8c0db4 100644 --- a/client/cmdlfem4x.c +++ b/client/cmdlfem4x.c @@ -482,12 +482,12 @@ static int CmdEM410xBrute(const char *Cmd) { int filelen = param_getstr(Cmd, 0, filename, FILE_PATH_SIZE); if (filelen == 0) { - PrintAndLogEx(WARNING, "Error: Please specify a filename"); + PrintAndLogEx(ERR, "Error: Please specify a filename"); return PM3_EINVARG; } if ((f = fopen(filename, "r")) == NULL) { - PrintAndLogEx(WARNING, "Error: Could not open UIDs file ["_YELLOW_("%s")"]", filename); + PrintAndLogEx(ERR, "Error: Could not open UIDs file ["_YELLOW_("%s")"]", filename); return PM3_EFILE; } @@ -613,21 +613,21 @@ static int CmdEM410xWrite(const char *Cmd) { // Check ID if (id == 0xFFFFFFFFFFFFFFFF) { - PrintAndLogEx(WARNING, "Error! ID is required.\n"); + PrintAndLogEx(ERR, "Error! ID is required.\n"); return PM3_EINVARG; } if (id >= 0x10000000000) { - PrintAndLogEx(WARNING, "Error! Given EM410x ID is longer than 40 bits.\n"); + PrintAndLogEx(ERR, "Error! Given EM410x ID is longer than 40 bits.\n"); return PM3_EINVARG; } // Check Card if (card == 0xFF) { - PrintAndLogEx(WARNING, "Error! Card type required.\n"); + PrintAndLogEx(ERR, "Error! Card type required.\n"); return PM3_EINVARG; } if (card < 0) { - PrintAndLogEx(WARNING, "Error! Bad card type selected.\n"); + PrintAndLogEx(ERR, "Error! Bad card type selected.\n"); return PM3_EINVARG; } @@ -637,7 +637,7 @@ static int CmdEM410xWrite(const char *Cmd) { // Allowed clock rates: 16, 32, 40 and 64 if ((clock1 != 16) && (clock1 != 32) && (clock1 != 64) && (clock1 != 40)) { - PrintAndLogEx(WARNING, "Error! Clock rate" _YELLOW_("%d")" not valid. Supported clock rates are 16, 32, 40 and 64.\n", clock1); + PrintAndLogEx(ERR, "Error! Clock rate" _YELLOW_("%d")" not valid. Supported clock rates are 16, 32, 40 and 64.\n", clock1); return PM3_EINVARG; } @@ -837,7 +837,7 @@ int EM4x50Read(const char *Cmd, bool verbose) { } } if (!clk) { - if (verbose || g_debugMode) PrintAndLogEx(WARNING, "Error: EM4x50 - didn't find a clock"); + if (verbose || g_debugMode) PrintAndLogEx(ERR, "Error: EM4x50 - didn't find a clock"); return PM3_ESOFT; } } else tol = clk / 8; @@ -1262,7 +1262,7 @@ static int CmdEM4x05Write(const char *Cmd) { SendCommandNG(CMD_EM4X_WRITE_WORD, (uint8_t *)&payload, sizeof(payload)); PacketResponseNG resp; if (!WaitForResponseTimeout(CMD_EM4X_WRITE_WORD, &resp, 2000)) { - PrintAndLogEx(WARNING, "Error occurred, device did not respond during write operation."); + PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); return PM3_ETIMEOUT; } diff --git a/client/cmdlffdx.c b/client/cmdlffdx.c index 8cf93b12f..35f3216ad 100644 --- a/client/cmdlffdx.c +++ b/client/cmdlffdx.c @@ -264,7 +264,7 @@ static int CmdFdxClone(const char *Cmd) { // getFDXBits(uint64_t national_id, uint16_t country, uint8_t isanimal, uint8_t isextended, uint32_t extended, uint8_t *bits) if (getFDXBits(animalid, countryid, 1, 0, 0, bs) != PM3_SUCCESS) { - PrintAndLogEx(WARNING, "Error with tag bitstream generation."); + PrintAndLogEx(ERR, "Error with tag bitstream generation."); return PM3_ESOFT; } @@ -300,7 +300,7 @@ static int CmdFdxClone(const char *Cmd) { SendCommandNG(CMD_T55XX_WRITE_BLOCK, (uint8_t *)&ng, sizeof(ng)); if (!WaitForResponseTimeout(CMD_T55XX_WRITE_BLOCK, &resp, T55XX_WRITE_TIMEOUT)) { - PrintAndLogEx(WARNING, "Error occurred, device did not respond during write operation."); + PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); return PM3_ETIMEOUT; } } diff --git a/client/cmdlfguard.c b/client/cmdlfguard.c index 54073fc02..1b09eb18d 100644 --- a/client/cmdlfguard.c +++ b/client/cmdlfguard.c @@ -155,7 +155,7 @@ static int CmdGuardClone(const char *Cmd) { cardnumber = (cn & 0x0000FFFF); if (getGuardBits(fmtlen, facilitycode, cardnumber, bs) != PM3_SUCCESS) { - PrintAndLogEx(WARNING, "Error with tag bitstream generation."); + PrintAndLogEx(ERR, "Error with tag bitstream generation."); return PM3_ESOFT; } @@ -189,7 +189,7 @@ static int CmdGuardClone(const char *Cmd) { SendCommandNG(CMD_T55XX_WRITE_BLOCK, (uint8_t *)&ng, sizeof(ng)); if (!WaitForResponseTimeout(CMD_T55XX_WRITE_BLOCK, &resp, T55XX_WRITE_TIMEOUT)) { - PrintAndLogEx(WARNING, "Error occurred, device did not respond during write operation."); + PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); return PM3_ETIMEOUT; } } @@ -213,7 +213,7 @@ static int CmdGuardSim(const char *Cmd) { cardnumber = (cn & 0x0000FFFF); if (getGuardBits(fmtlen, facilitycode, cardnumber, bs) != PM3_SUCCESS) { - PrintAndLogEx(WARNING, "Error with tag bitstream generation."); + PrintAndLogEx(ERR, "Error with tag bitstream generation."); return PM3_ESOFT; } diff --git a/client/cmdlfhitag.c b/client/cmdlfhitag.c index 47e08eb2e..69ba874c1 100644 --- a/client/cmdlfhitag.c +++ b/client/cmdlfhitag.c @@ -177,7 +177,7 @@ static int CmdLFHitagList(const char *Cmd) { if (strlen(filename) > 0) { f = fopen(filename, "wb"); if (!f) { - PrintAndLogEx(WARNING, "Error: Could not open file [%s]", filename); + PrintAndLogEx(ERR, "Error: Could not open file [%s]", filename); return PM3_EFILE; } } diff --git a/client/cmdlfio.c b/client/cmdlfio.c index ad37b9fd7..d187daaab 100644 --- a/client/cmdlfio.c +++ b/client/cmdlfio.c @@ -199,7 +199,7 @@ static int CmdIOProxSim(const char *Cmd) { PrintAndLogEx(SUCCESS, "Press pm3-button to abort simulation or run another command"); if (getIOProxBits(version, fc, cn, bs) != PM3_SUCCESS) { - PrintAndLogEx(WARNING, "Error with tag bitstream generation."); + PrintAndLogEx(ERR, "Error with tag bitstream generation."); return PM3_ESOFT; } // IOProx uses: fcHigh: 10, fcLow: 8, clk: 64, invert: 1 @@ -249,7 +249,7 @@ static int CmdIOProxClone(const char *Cmd) { } if (getIOProxBits(version, fc, cn, bits) != PM3_SUCCESS) { - PrintAndLogEx(WARNING, "Error with tag bitstream generation."); + PrintAndLogEx(ERR, "Error with tag bitstream generation."); return PM3_ESOFT; } diff --git a/client/cmdlfjablotron.c b/client/cmdlfjablotron.c index a5b9166ac..c2478705c 100644 --- a/client/cmdlfjablotron.c +++ b/client/cmdlfjablotron.c @@ -145,7 +145,7 @@ static int CmdJablotronClone(const char *Cmd) { } if (getJablotronBits(fullcode, bits) != PM3_SUCCESS) { - PrintAndLogEx(WARNING, "Error with tag bitstream generation."); + PrintAndLogEx(ERR, "Error with tag bitstream generation."); return PM3_ESOFT; } @@ -174,7 +174,7 @@ static int CmdJablotronClone(const char *Cmd) { SendCommandNG(CMD_T55XX_WRITE_BLOCK, (uint8_t *)&ng, sizeof(ng)); if (!WaitForResponseTimeout(CMD_T55XX_WRITE_BLOCK, &resp, T55XX_WRITE_TIMEOUT)) { - PrintAndLogEx(WARNING, "Error occurred, device did not respond during write operation."); + PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); return PM3_ETIMEOUT; } } diff --git a/client/cmdlfkeri.c b/client/cmdlfkeri.c index 82d1b9f84..b3761055f 100644 --- a/client/cmdlfkeri.c +++ b/client/cmdlfkeri.c @@ -164,7 +164,7 @@ static int CmdKeriClone(const char *Cmd) { SendCommandNG(CMD_T55XX_WRITE_BLOCK, (uint8_t *)&ng, sizeof(ng)); if (!WaitForResponseTimeout(CMD_T55XX_WRITE_BLOCK, &resp, T55XX_WRITE_TIMEOUT)) { - PrintAndLogEx(WARNING, "Error occurred, device did not respond during write operation."); + PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); return PM3_ETIMEOUT; } } diff --git a/client/cmdlfnedap.c b/client/cmdlfnedap.c index d081ff56c..0b998d716 100644 --- a/client/cmdlfnedap.c +++ b/client/cmdlfnedap.c @@ -182,7 +182,7 @@ static int CmdLFNedapClone(const char *Cmd) { cardnumber = (cn & 0x00FFFFFF); if ( getNedapBits(cardnumber, bits) == PM3_SUCCESS ) { - PrintAndLogEx(WARNING, "Error with tag bitstream generation."); + PrintAndLogEx(ERR, "Error with tag bitstream generation."); return PM3_ESOFT; } @@ -220,7 +220,7 @@ static int CmdLFNedapClone(const char *Cmd) { SendCommandNG(CMD_T55XX_WRITE_BLOCK, (uint8_t *)&ng, sizeof(ng)); if (!WaitForResponseTimeout(CMD_T55XX_WRITE_BLOCK, &resp, T55XX_WRITE_TIMEOUT)) { - PrintAndLogEx(WARNING, "Error occurred, device did not respond during write operation."); + PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); return PM3_ETIMEOUT; } } @@ -243,7 +243,7 @@ static int CmdLFNedapSim(const char *Cmd) { memset(bs, 0x00, sizeof(bs)); if (getNedapBits(cardnumber, bs) != PM3_SUCCESS) { - PrintAndLogEx(WARNING, "Error with tag bitstream generation."); + PrintAndLogEx(ERR, "Error with tag bitstream generation."); return PM3_ESOFT; } diff --git a/client/cmdlfnoralsy.c b/client/cmdlfnoralsy.c index 9e3413405..34ad1023f 100644 --- a/client/cmdlfnoralsy.c +++ b/client/cmdlfnoralsy.c @@ -142,7 +142,7 @@ static int CmdNoralsyClone(const char *Cmd) { blocks[0] = T5555_MODULATION_MANCHESTER | T5555_SET_BITRATE(32) | T5555_ST_TERMINATOR | 3 << T5555_MAXBLOCK_SHIFT; if (getnoralsyBits(id, year, bits) != PM3_SUCCESS) { - PrintAndLogEx(WARNING, "Error with tag bitstream generation."); + PrintAndLogEx(ERR, "Error with tag bitstream generation."); return PM3_ESOFT; } @@ -172,7 +172,7 @@ static int CmdNoralsyClone(const char *Cmd) { SendCommandNG(CMD_T55XX_WRITE_BLOCK, (uint8_t *)&ng, sizeof(ng)); if (!WaitForResponseTimeout(CMD_T55XX_WRITE_BLOCK, &resp, T55XX_WRITE_TIMEOUT)) { - PrintAndLogEx(WARNING, "Error occurred, device did not respond during write operation."); + PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); return PM3_ETIMEOUT; } } @@ -195,7 +195,7 @@ static int CmdNoralsySim(const char *Cmd) { year = param_get32ex(Cmd, 1, 2000, 10); if (getnoralsyBits(id, year, bs) != PM3_SUCCESS) { - PrintAndLogEx(WARNING, "Error with tag bitstream generation."); + PrintAndLogEx(ERR, "Error with tag bitstream generation."); return PM3_ESOFT; } diff --git a/client/cmdlfparadox.c b/client/cmdlfparadox.c index 684730ef3..c5c022d9b 100644 --- a/client/cmdlfparadox.c +++ b/client/cmdlfparadox.c @@ -128,7 +128,7 @@ static int CmdParadoxSim(const char *Cmd) { cardnumber = (cn & 0x0000FFFF); // if ( GetParadoxBits(facilitycode, cardnumber, bs) != PM3_SUCCESS) { - // PrintAndLogEx(WARNING, "Error with tag bitstream generation."); + // PrintAndLogEx(ERR, "Error with tag bitstream generation."); // return 1; // } diff --git a/client/cmdlfpresco.c b/client/cmdlfpresco.c index a51155e78..3f1ce71f3 100644 --- a/client/cmdlfpresco.c +++ b/client/cmdlfpresco.c @@ -138,7 +138,7 @@ static int CmdPrescoClone(const char *Cmd) { SendCommandNG(CMD_T55XX_WRITE_BLOCK, (uint8_t *)&ng, sizeof(ng)); if (!WaitForResponseTimeout(CMD_T55XX_WRITE_BLOCK, &resp, T55XX_WRITE_TIMEOUT)) { - PrintAndLogEx(WARNING, "Error occurred, device did not respond during write operation."); + PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); return PM3_ETIMEOUT; } } diff --git a/client/cmdlfpyramid.c b/client/cmdlfpyramid.c index 91b895bcb..4e5588ec6 100644 --- a/client/cmdlfpyramid.c +++ b/client/cmdlfpyramid.c @@ -212,7 +212,7 @@ static int CmdPyramidClone(const char *Cmd) { cardnumber = (cn & 0x0000FFFF); if (getPyramidBits(facilitycode, cardnumber, bs) != PM3_SUCCESS) { - PrintAndLogEx(WARNING, "Error with tag bitstream generation."); + PrintAndLogEx(ERR, "Error with tag bitstream generation."); return PM3_ESOFT; } @@ -249,7 +249,7 @@ static int CmdPyramidClone(const char *Cmd) { SendCommandNG(CMD_T55XX_WRITE_BLOCK, (uint8_t *)&ng, sizeof(ng)); if (!WaitForResponseTimeout(CMD_T55XX_WRITE_BLOCK, &resp, T55XX_WRITE_TIMEOUT)) { - PrintAndLogEx(WARNING, "Error occurred, device did not respond during write operation."); + PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); return PM3_ETIMEOUT; } } @@ -272,7 +272,7 @@ static int CmdPyramidSim(const char *Cmd) { cardnumber = (cn & 0x0000FFFF); if (getPyramidBits(facilitycode, cardnumber, bs) != PM3_SUCCESS) { - PrintAndLogEx(WARNING, "Error with tag bitstream generation."); + PrintAndLogEx(ERR, "Error with tag bitstream generation."); return PM3_ESOFT; } diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index b1c03b514..07285053b 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -1103,7 +1103,7 @@ static int CmdT55xxWriteBlock(const char *Cmd) { SendCommandNG(CMD_T55XX_WRITE_BLOCK, (uint8_t *)&ng, sizeof(ng)); if (!WaitForResponseTimeout(CMD_T55XX_WRITE_BLOCK, &resp, 2000)) { - PrintAndLogEx(WARNING, "Error occurred, device did not ACK write operation. (May be due to old firmware)"); + PrintAndLogEx(ERR, "Error occurred, device did not ACK write operation. (May be due to old firmware)"); return PM3_ETIMEOUT; } return PM3_SUCCESS; @@ -1829,13 +1829,13 @@ static int CmdT55xxWipe(const char *Cmd) { else snprintf(ptrData, sizeof(writeData), "b 0 d 000880E0 p 0"); - if (CmdT55xxWriteBlock(ptrData) != PM3_SUCCESS) PrintAndLogEx(WARNING, "Error writing blk 0"); + if (CmdT55xxWriteBlock(ptrData) != PM3_SUCCESS) PrintAndLogEx(ERR, "Error writing blk 0"); for (uint8_t blk = 1; blk < 8; blk++) { snprintf(ptrData, sizeof(writeData), "b %d d 0", blk); - if (CmdT55xxWriteBlock(ptrData) != PM3_SUCCESS) PrintAndLogEx(WARNING, "Error writing blk %d", blk); + if (CmdT55xxWriteBlock(ptrData) != PM3_SUCCESS) PrintAndLogEx(ERR, "Error writing blk %d", blk); memset(writeData, 0x00, sizeof(writeData)); } @@ -1919,7 +1919,7 @@ static int CmdT55xxChkPwds(const char *Cmd) { // TODO, a way of reallocating memory if file was larger keyBlock = calloc(4 * 200, sizeof(uint8_t)); if (keyBlock == NULL) { - PrintAndLogDevice(WARNING, "error, cannot allocate memory "); + PrintAndLogDevice(ERR, "error, cannot allocate memory "); return PM3_ESOFT; } diff --git a/client/cmdlfti.c b/client/cmdlfti.c index 3baa8c2e6..b37a6fdc1 100644 --- a/client/cmdlfti.c +++ b/client/cmdlfti.c @@ -233,7 +233,7 @@ static int CmdTIDemod(const char *Cmd) { // only 15 bits compare, last bit of ident is not valid if ((shift3 ^ shift0) & 0x7FFF) { - PrintAndLogEx(WARNING, "Error: Ident mismatch!"); + PrintAndLogEx(ERR, "Error: Ident mismatch!"); } // WARNING the order of the bytes in which we calc crc below needs checking // i'm 99% sure the crc algorithm is correct, but it may need to eat the @@ -257,7 +257,7 @@ static int CmdTIDemod(const char *Cmd) { PrintAndLogEx(INFO, "Tag data = %08X%08X [Crc %04X %s]", shift1, shift0, crc, crcStr); if (crc != (shift2 & 0xFFFF)) - PrintAndLogEx(WARNING, "Error: CRC mismatch, calculated %04X, got %04X", crc, shift2 & 0xFFFF); + PrintAndLogEx(ERR, "Error: CRC mismatch, calculated %04X, got %04X", crc, shift2 & 0xFFFF); retval = PM3_SUCCESS; goto out; diff --git a/client/cmdlfviking.c b/client/cmdlfviking.c index 750070a34..41193ea12 100644 --- a/client/cmdlfviking.c +++ b/client/cmdlfviking.c @@ -91,7 +91,7 @@ static int CmdVikingClone(const char *Cmd) { SendCommandMIX(CMD_VIKING_CLONE_TAG, rawID >> 32, rawID & 0xFFFFFFFF, Q5, NULL, 0); PacketResponseNG resp; if (!WaitForResponseTimeout(CMD_ACK, &resp, T55XX_WRITE_TIMEOUT)) { - PrintAndLogEx(WARNING, "Error occurred, device did not respond during write operation."); + PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); return PM3_ETIMEOUT; } return PM3_SUCCESS; diff --git a/client/cmdlfvisa2000.c b/client/cmdlfvisa2000.c index b717f65dd..12d4ba1c6 100644 --- a/client/cmdlfvisa2000.c +++ b/client/cmdlfvisa2000.c @@ -186,7 +186,7 @@ static int CmdVisa2kClone(const char *Cmd) { SendCommandNG(CMD_T55XX_WRITE_BLOCK, (uint8_t *)&ng, sizeof(ng)); if (!WaitForResponseTimeout(CMD_T55XX_WRITE_BLOCK, &resp, T55XX_WRITE_TIMEOUT)) { - PrintAndLogEx(WARNING, "Error occurred, device did not respond during write operation."); + PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); return PM3_ETIMEOUT; } } diff --git a/client/cmdsmartcard.c b/client/cmdsmartcard.c index f936f10a9..f7a0b4ca4 100644 --- a/client/cmdsmartcard.c +++ b/client/cmdsmartcard.c @@ -284,7 +284,7 @@ static int PrintATR(uint8_t *atr, size_t atrlen) { vxor ^= atr[i]; if (vxor) - PrintAndLogEx(WARNING, "Check sum error. Must be 0 got 0x%02X", vxor); + PrintAndLogEx(ERR, "Check sum error. Must be 0 got 0x%02X", vxor); else PrintAndLogEx(INFO, "Check sum OK."); } @@ -568,14 +568,14 @@ static int CmdSmartUpgrade(const char *Cmd) { fseek(f, 0, SEEK_SET); if (fsize <= 0) { - PrintAndLogEx(WARNING, "error, when getting filesize"); + PrintAndLogEx(ERR, "error, when getting filesize"); fclose(f); return 1; } uint8_t *dump = calloc(fsize, sizeof(uint8_t)); if (!dump) { - PrintAndLogEx(WARNING, "error, cannot allocate memory "); + PrintAndLogEx(ERR, "error, cannot allocate memory "); fclose(f); return 1; } diff --git a/client/comms.c b/client/comms.c index 6fd41ecad..dad7c1640 100644 --- a/client/comms.c +++ b/client/comms.c @@ -359,7 +359,7 @@ __attribute__((force_align_arg_pointer)) res = uart_receive(sp, (uint8_t *)&rx_raw.data, length, &rxlen); if ((res != PM3_SUCCESS) || (rxlen != length)) { - PrintAndLogEx(WARNING, "Received packet frame error variable part too short? %d/%d", rxlen, length); + PrintAndLogEx(ERR, "Received packet frame error variable part too short? %d/%d", rxlen, length); error = true; } else { @@ -392,7 +392,7 @@ __attribute__((force_align_arg_pointer)) if (!error) { // Get the postamble res = uart_receive(sp, (uint8_t *)&rx_raw.foopost, sizeof(PacketResponseNGPostamble), &rxlen); if ((res != PM3_SUCCESS) || (rxlen != sizeof(PacketResponseNGPostamble))) { - PrintAndLogEx(WARNING, "Received packet frame error fetching postamble"); + PrintAndLogEx(ERR, "Received packet frame error fetching postamble"); error = true; } } @@ -402,7 +402,7 @@ __attribute__((force_align_arg_pointer)) uint8_t first, second; compute_crc(CRC_14443_A, (uint8_t *)&rx_raw, sizeof(PacketResponseNGPreamble) + length, &first, &second); if ((first << 8) + second != rx.crc) { - PrintAndLogEx(WARNING, "Received packet frame CRC error %02X%02X <> %04X", first, second, rx.crc); + PrintAndLogEx(ERR, "Received packet frame CRC error %02X%02X <> %04X", first, second, rx.crc); error = true; } } @@ -424,7 +424,7 @@ __attribute__((force_align_arg_pointer)) res = uart_receive(sp, ((uint8_t *)&rx_old) + sizeof(PacketResponseNGPreamble), sizeof(PacketResponseOLD) - sizeof(PacketResponseNGPreamble), &rxlen); if ((res != PM3_SUCCESS) || (rxlen != sizeof(PacketResponseOLD) - sizeof(PacketResponseNGPreamble))) { - PrintAndLogEx(WARNING, "Received packet OLD frame payload error too short? %d/%d", rxlen, sizeof(PacketResponseOLD) - sizeof(PacketResponseNGPreamble)); + PrintAndLogEx(ERR, "Received packet OLD frame payload error too short? %d/%d", rxlen, sizeof(PacketResponseOLD) - sizeof(PacketResponseNGPreamble)); error = true; } if (!error) { diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c index 22fdea153..0585c1661 100644 --- a/client/emv/cmdemv.c +++ b/client/emv/cmdemv.c @@ -931,7 +931,7 @@ static int CmdEMVExec(const char *Cmd) { while (AFL && AFL->len) { if (AFL->len % 4) { - PrintAndLogEx(WARNING, "Error: Wrong AFL length: %d", AFL->len); + PrintAndLogEx(ERR, "Error: Wrong AFL length: %d", AFL->len); break; } @@ -952,7 +952,7 @@ static int CmdEMVExec(const char *Cmd) { res = EMVReadRecord(channel, true, SFI, n, buf, sizeof(buf), &len, &sw, tlvRoot); if (res) { - PrintAndLogEx(WARNING, "Error SFI[%02x]. APDU error %4x", SFI, sw); + PrintAndLogEx(ERR, "Error SFI[%02x]. APDU error %4x", SFI, sw); continue; } @@ -972,7 +972,7 @@ static int CmdEMVExec(const char *Cmd) { memcpy(&ODAiList[ODAiListLen], &buf[len - elmlen], elmlen); ODAiListLen += elmlen; } else { - PrintAndLogEx(WARNING, "Error SFI[%02x]. Creating input list for Offline Data Authentication error.", SFI); + PrintAndLogEx(ERR, "Error SFI[%02x]. Creating input list for Offline Data Authentication error.", SFI); } } else { memcpy(&ODAiList[ODAiListLen], buf, len); @@ -1051,7 +1051,7 @@ static int CmdEMVExec(const char *Cmd) { } } else { - PrintAndLogEx(WARNING, "Error AC: Application Transaction Counter (ATC) not found."); + PrintAndLogEx(ERR, "Error AC: Application Transaction Counter (ATC) not found."); } } } @@ -1131,14 +1131,14 @@ static int CmdEMVExec(const char *Cmd) { PrintAndLogEx(NORMAL, "Transaction approved ONLINE."); break; default: - PrintAndLogEx(WARNING, "Error: CID transaction code error %2x", CID->value[0] & EMVAC_AC_MASK); + PrintAndLogEx(ERR, "Error: CID transaction code error %2x", CID->value[0] & EMVAC_AC_MASK); break; } } else { - PrintAndLogEx(WARNING, "Error: Wrong CID length %d", CID->len); + PrintAndLogEx(ERR, "Error: Wrong CID length %d", CID->len); } } else { - PrintAndLogEx(WARNING, "Error: CID(9F27) not found."); + PrintAndLogEx(ERR, "Error: CID(9F27) not found."); } } diff --git a/client/emv/emvcore.c b/client/emv/emvcore.c index e9e725448..e7bda4be5 100644 --- a/client/emv/emvcore.c +++ b/client/emv/emvcore.c @@ -511,7 +511,7 @@ int EMVSearchPSE(EMVCommandChannel channel, bool ActivateField, bool LeaveFieldO PrintAndLogEx(WARNING, "%s ERROR: Can't get TLV from response.", PSE_or_PPSE); } } else { - PrintAndLogEx(WARNING, "%s ERROR: Can't select PPSE AID. Error: %d", PSE_or_PPSE, res); + PrintAndLogEx(ERR, "%s ERROR: Can't select PPSE AID. Error: %d", PSE_or_PPSE, res); } if (!LeaveFieldON) @@ -654,14 +654,14 @@ int trSDA(struct tlvdb *tlv) { struct emv_pk *pk = get_ca_pk(tlv); if (!pk) { - PrintAndLogEx(WARNING, "Error: Key not found. Exit."); + PrintAndLogEx(ERR, "Error: Key not found. Exit."); return 2; } struct emv_pk *issuer_pk = emv_pki_recover_issuer_cert(pk, tlv); if (!issuer_pk) { emv_pk_free(pk); - PrintAndLogEx(WARNING, "Error: Issuer certificate not found. Exit."); + PrintAndLogEx(ERR, "Error: Issuer certificate not found. Exit."); return 2; } @@ -693,7 +693,7 @@ int trSDA(struct tlvdb *tlv) { } else { emv_pk_free(issuer_pk); emv_pk_free(pk); - PrintAndLogEx(WARNING, "SSAD verify error"); + PrintAndLogEx(ERR, "SSAD verify error"); return 4; } @@ -712,21 +712,21 @@ int trDDA(EMVCommandChannel channel, bool decodeTLV, struct tlvdb *tlv) { struct emv_pk *pk = get_ca_pk(tlv); if (!pk) { - PrintAndLogEx(WARNING, "Error: Key not found. Exit."); + PrintAndLogEx(ERR, "Error: Key not found. Exit."); return 2; } const struct tlv *sda_tlv = tlvdb_get(tlv, 0x21, NULL); /* if (!sda_tlv || sda_tlv->len < 1) { it may be 0!!!! emv_pk_free(pk); - PrintAndLogEx(WARNING, "Error: Can't find input list for Offline Data Authentication. Exit."); + PrintAndLogEx(ERR, "Error: Can't find input list for Offline Data Authentication. Exit."); return 3; } */ struct emv_pk *issuer_pk = emv_pki_recover_issuer_cert(pk, tlv); if (!issuer_pk) { emv_pk_free(pk); - PrintAndLogEx(WARNING, "Error: Issuer certificate not found. Exit."); + PrintAndLogEx(ERR, "Error: Issuer certificate not found. Exit."); return 2; } PrintAndLogEx(SUCCESS, "Issuer PK recovered. RID %02hhx:%02hhx:%02hhx:%02hhx:%02hhx IDX %02hhx CSN %02hhx:%02hhx:%02hhx\n", @@ -745,7 +745,7 @@ int trDDA(EMVCommandChannel channel, bool decodeTLV, struct tlvdb *tlv) { if (!icc_pk) { emv_pk_free(pk); emv_pk_free(issuer_pk); - PrintAndLogEx(WARNING, "Error: ICC certificate not found. Exit."); + PrintAndLogEx(ERR, "Error: ICC certificate not found. Exit."); return 2; } PrintAndLogEx(SUCCESS, "ICC PK recovered. RID %02hhx:%02hhx:%02hhx:%02hhx:%02hhx IDX %02hhx CSN %02hhx:%02hhx:%02hhx\n", @@ -763,7 +763,7 @@ int trDDA(EMVCommandChannel channel, bool decodeTLV, struct tlvdb *tlv) { if (tlvdb_get(tlv, 0x9f2d, NULL)) { struct emv_pk *icc_pe_pk = emv_pki_recover_icc_pe_cert(issuer_pk, tlv); if (!icc_pe_pk) { - PrintAndLogEx(WARNING, "WARNING: ICC PE PK recover error. "); + PrintAndLogEx(ERR, "WARNING: ICC PE PK recover error. "); } else { PrintAndLogEx(SUCCESS, "ICC PE PK recovered. RID %02hhx:%02hhx:%02hhx:%02hhx:%02hhx IDX %02hhx CSN %02hhx:%02hhx:%02hhx\n", icc_pe_pk->rid[0], @@ -790,7 +790,7 @@ int trDDA(EMVCommandChannel channel, bool decodeTLV, struct tlvdb *tlv) { const struct tlvdb *atc_db = emv_pki_recover_atc_ex(icc_pk, tlv, true); if (!atc_db) { - PrintAndLogEx(WARNING, "Error: Can't recover IDN (ICC Dynamic Number)"); + PrintAndLogEx(ERR, "Error: Can't recover IDN (ICC Dynamic Number)"); emv_pk_free(pk); emv_pk_free(issuer_pk); emv_pk_free(icc_pk); @@ -807,7 +807,7 @@ int trDDA(EMVCommandChannel channel, bool decodeTLV, struct tlvdb *tlv) { PrintAndLogEx(SUCCESS, "ATC check OK."); PrintAndLogEx(SUCCESS, "fDDA (fast DDA) verified OK."); } else { - PrintAndLogEx(WARNING, "Error: fDDA verified, but ATC in the certificate and ATC in the record not the same."); + PrintAndLogEx(ERR, "Error: fDDA verified, but ATC in the certificate and ATC in the record not the same."); } } else { PrintAndLogEx(NORMAL, "\nERROR: fDDA (fast DDA) verify error"); @@ -823,7 +823,7 @@ int trDDA(EMVCommandChannel channel, bool decodeTLV, struct tlvdb *tlv) { PrintAndLogEx(NORMAL, "SDAD verified OK. (Data Authentication Code: %02hhx:%02hhx)\n", dac_tlv->value[0], dac_tlv->value[1]); tlvdb_add(tlv, dac_db); } else { - PrintAndLogEx(WARNING, "Error: SSAD verify error"); + PrintAndLogEx(ERR, "Error: SSAD verify error"); emv_pk_free(pk); emv_pk_free(issuer_pk); emv_pk_free(icc_pk); @@ -839,7 +839,7 @@ int trDDA(EMVCommandChannel channel, bool decodeTLV, struct tlvdb *tlv) { struct tlv *ddol_data_tlv = dol_process(ddol_tlv, tlv, 0); if (!ddol_data_tlv) { - PrintAndLogEx(WARNING, "Error: Can't create DDOL TLV"); + PrintAndLogEx(ERR, "Error: Can't create DDOL TLV"); emv_pk_free(pk); emv_pk_free(issuer_pk); emv_pk_free(icc_pk); @@ -851,7 +851,7 @@ int trDDA(EMVCommandChannel channel, bool decodeTLV, struct tlvdb *tlv) { PrintAndLogEx(NORMAL, "\n* Internal Authenticate"); int res = EMVInternalAuthenticate(channel, true, (uint8_t *)ddol_data_tlv->value, ddol_data_tlv->len, buf, sizeof(buf), &len, &sw, NULL); if (res) { - PrintAndLogEx(WARNING, "Internal Authenticate error(%d): %4x. Exit...", res, sw); + PrintAndLogEx(ERR, "Internal Authenticate error(%d): %4x. Exit...", res, sw); free(ddol_data_tlv); emv_pk_free(pk); emv_pk_free(issuer_pk); @@ -862,7 +862,7 @@ int trDDA(EMVCommandChannel channel, bool decodeTLV, struct tlvdb *tlv) { struct tlvdb *dda_db = NULL; if (buf[0] == 0x80) { if (len < 3) { - PrintAndLogEx(WARNING, "Error: Internal Authenticate format1 parsing error. length=%d", len); + PrintAndLogEx(ERR, "Error: Internal Authenticate format1 parsing error. length=%d", len); } else { // parse response 0x80 struct tlvdb *t80 = tlvdb_parse_multi(buf, len); @@ -882,7 +882,7 @@ int trDDA(EMVCommandChannel channel, bool decodeTLV, struct tlvdb *tlv) { } else { dda_db = tlvdb_parse_multi(buf, len); if (!dda_db) { - PrintAndLogEx(WARNING, "Error: Can't parse Internal Authenticate result as TLV"); + PrintAndLogEx(ERR, "Error: Can't parse Internal Authenticate result as TLV"); free(ddol_data_tlv); emv_pk_free(pk); emv_pk_free(issuer_pk); @@ -898,7 +898,7 @@ int trDDA(EMVCommandChannel channel, bool decodeTLV, struct tlvdb *tlv) { struct tlvdb *idn_db = emv_pki_recover_idn_ex(icc_pk, dda_db, ddol_data_tlv, true); free(ddol_data_tlv); if (!idn_db) { - PrintAndLogEx(WARNING, "Error: Can't recover IDN (ICC Dynamic Number)"); + PrintAndLogEx(ERR, "Error: Can't recover IDN (ICC Dynamic Number)"); tlvdb_free(dda_db); emv_pk_free(pk); emv_pk_free(issuer_pk); @@ -935,20 +935,20 @@ int trCDA(struct tlvdb *tlv, struct tlvdb *ac_tlv, struct tlv *pdol_data_tlv, st struct emv_pk *pk = get_ca_pk(tlv); if (!pk) { - PrintAndLogEx(WARNING, "Error: Key not found. Exit."); + PrintAndLogEx(ERR, "Error: Key not found. Exit."); return 2; } const struct tlv *sda_tlv = tlvdb_get(tlv, 0x21, NULL); if (!sda_tlv || sda_tlv->len < 1) { - PrintAndLogEx(WARNING, "Error: Can't find input list for Offline Data Authentication. Exit."); + PrintAndLogEx(ERR, "Error: Can't find input list for Offline Data Authentication. Exit."); emv_pk_free(pk); return 3; } struct emv_pk *issuer_pk = emv_pki_recover_issuer_cert(pk, tlv); if (!issuer_pk) { - PrintAndLogEx(WARNING, "Error: Issuer certificate not found. Exit."); + PrintAndLogEx(ERR, "Error: Issuer certificate not found. Exit."); emv_pk_free(pk); return 2; } @@ -966,7 +966,7 @@ int trCDA(struct tlvdb *tlv, struct tlvdb *ac_tlv, struct tlv *pdol_data_tlv, st struct emv_pk *icc_pk = emv_pki_recover_icc_cert(issuer_pk, tlv, sda_tlv); if (!icc_pk) { - PrintAndLogEx(WARNING, "Error: ICC certificate not found. Exit."); + PrintAndLogEx(ERR, "Error: ICC certificate not found. Exit."); emv_pk_free(pk); emv_pk_free(issuer_pk); return 2; @@ -989,7 +989,7 @@ int trCDA(struct tlvdb *tlv, struct tlvdb *ac_tlv, struct tlv *pdol_data_tlv, st PrintAndLogEx(NORMAL, "SSAD verified OK. (%02hhx:%02hhx)", dac_tlv->value[0], dac_tlv->value[1]); tlvdb_add(tlv, dac_db); } else { - PrintAndLogEx(WARNING, "Error: SSAD verify error"); + PrintAndLogEx(ERR, "Error: SSAD verify error"); emv_pk_free(pk); emv_pk_free(issuer_pk); emv_pk_free(icc_pk); diff --git a/client/fido/fidocore.c b/client/fido/fidocore.c index c356c3456..21079eb34 100644 --- a/client/fido/fidocore.c +++ b/client/fido/fidocore.c @@ -386,7 +386,7 @@ static int FIDO2CheckSignature(json_t *root, uint8_t *publickey, uint8_t *sign, if (res == -0x4e00) { PrintAndLogEx(WARNING, "Signature is NOT VALID."); } else { - PrintAndLogEx(WARNING, "Other signature check error: %x %s", (res < 0) ? -res : res, ecdsa_get_error(res)); + PrintAndLogEx(ERR, "Other signature check error: %x %s", (res < 0) ? -res : res, ecdsa_get_error(res)); } return res; } else { diff --git a/client/loclass/elite_crack.c b/client/loclass/elite_crack.c index a461557b1..3e0aa1dc5 100644 --- a/client/loclass/elite_crack.c +++ b/client/loclass/elite_crack.c @@ -517,7 +517,7 @@ int bruteforceDump(uint8_t dump[], size_t dumpsize, uint16_t keytable[]) { first16bytes[i] = keytable[i] & 0xFF; if (!(keytable[i] & CRACKED)) - PrintAndLogDevice(WARNING, "error, we are missing byte %d, custom key calculation will fail...", i); + PrintAndLogDevice(ERR, "error, we are missing byte %d, custom key calculation will fail...", i); } errors += calculateMasterKey(first16bytes, NULL); return errors; @@ -541,7 +541,7 @@ int bruteforceFile(const char *filename, uint16_t keytable[]) { fseek(f, 0, SEEK_SET); if (fsize <= 0) { - PrintAndLogDevice(WARNING, "Error, when getting filesize"); + PrintAndLogDevice(ERR, "Error, when getting filesize"); fclose(f); return 1; } @@ -557,7 +557,7 @@ int bruteforceFile(const char *filename, uint16_t keytable[]) { fclose(f); if (bytes_read < fsize) { - PrintAndLogDevice(WARNING, "Error, could only read %d bytes (should be %d)", bytes_read, fsize); + PrintAndLogDevice(ERR, "Error, could only read %d bytes (should be %d)", bytes_read, fsize); } uint8_t res = bruteforceDump(dump, fsize, keytable); @@ -612,7 +612,7 @@ static int _testBruteforce() { } else if (fileExists("client/loclass/iclass_dump.bin")) { errors |= bruteforceFile("client/loclass/iclass_dump.bin", keytable); } else { - PrintAndLogDevice(WARNING, "Error: The file iclass_dump.bin was not found!"); + PrintAndLogDevice(ERR, "Error: The file iclass_dump.bin was not found!"); } } return errors; @@ -627,14 +627,14 @@ static int _test_iclass_key_permutation() { permutekey_rev(testcase_output, testcase_output_rev); if (memcmp(testcase_output, testcase_output_correct, 8) != 0) { - PrintAndLogDevice(WARNING, "Error with iclass key permute!"); + PrintAndLogDevice(ERR, "Error with iclass key permute!"); printarr("testcase_output", testcase_output, 8); printarr("testcase_output_correct", testcase_output_correct, 8); return 1; } if (memcmp(testcase, testcase_output_rev, 8) != 0) { - PrintAndLogDevice(WARNING, "Error with reverse iclass key permute"); + PrintAndLogDevice(ERR, "Error with reverse iclass key permute"); printarr("testcase", testcase, 8); printarr("testcase_output_rev", testcase_output_rev, 8); return 1; @@ -651,7 +651,7 @@ static int _testHash1() { hash1(csn, k); if (memcmp(k, expected, 8) != 0) { - PrintAndLogDevice(WARNING, "Error with hash1!"); + PrintAndLogDevice(ERR, "Error with hash1!"); printarr("calculated", k, 8); printarr("expected", expected, 8); return 1; diff --git a/client/mifare/mad.c b/client/mifare/mad.c index 47b7cb70a..fa5b7d259 100644 --- a/client/mifare/mad.c +++ b/client/mifare/mad.c @@ -225,7 +225,7 @@ int MAD1DecodeAndPrint(uint8_t *sector, bool verbose, bool *haveMAD2) { PrintAndLogEx(NORMAL, "Card publisher sector not present."); } if (InfoByte == 0x10 || InfoByte >= 0x28) - PrintAndLogEx(WARNING, "Info byte error"); + PrintAndLogEx(ERR, "Info byte error"); PrintAndLogEx(NORMAL, "00 MAD1"); for (int i = 1; i < 16; i++) { diff --git a/client/mifare/mifarehost.c b/client/mifare/mifarehost.c index e9810e71a..100b595ce 100644 --- a/client/mifare/mifarehost.c +++ b/client/mifare/mifarehost.c @@ -914,7 +914,7 @@ int detect_classic_prng(void) { // if select tag failed. if (resp.oldarg[0] == 0) { - PrintAndLogEx(WARNING, "error: selecting tag failed, can't detect prng\n"); + PrintAndLogEx(ERR, "error: selecting tag failed, can't detect prng\n"); return PM3_ERFTRANS; } if (!WaitForResponseTimeout(CMD_ACK, &respA, 2500)) { @@ -924,7 +924,7 @@ int detect_classic_prng(void) { // check respA if (respA.oldarg[0] != 4) { - PrintAndLogEx(WARNING, "PRNG data error: Wrong length: %d", respA.oldarg[0]); + PrintAndLogEx(ERR, "PRNG data error: Wrong length: %d", respA.oldarg[0]); return PM3_ESOFT; } @@ -996,7 +996,7 @@ int detect_classic_nackbug(bool verbose) { PrintAndLogEx(SUCCESS, "No NACK bug detected"); return PM3_SUCCESS; default : - PrintAndLogEx(WARNING, "errorcode from device [%i]", ok); + PrintAndLogEx(ERR, "errorcode from device [%i]", ok); return PM3_EUNDEF; } break; From 55602bf833c5a9c1c4c1dcb07e11cd89d73d58dd Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 14 Jul 2019 12:17:34 +0200 Subject: [PATCH 0060/1854] Fix few zelaous WARNING->ERR --- client/cmddata.c | 2 +- client/cmdhf15.c | 2 +- client/cmdhffido.c | 4 ++-- client/cmdhfmf.c | 2 +- client/cmdlft55xx.c | 4 ++-- client/cmdlfti.c | 4 ++-- client/cmdsmartcard.c | 4 ++-- client/comms.c | 8 ++++---- client/emv/cmdemv.c | 18 +++++++++--------- client/emv/emvcore.c | 6 +++--- client/fido/fidocore.c | 2 +- client/loclass/elite_crack.c | 4 ++-- client/mifare/mad.c | 2 +- 13 files changed, 31 insertions(+), 31 deletions(-) diff --git a/client/cmddata.c b/client/cmddata.c index e0e0f73c1..ba6790c93 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -667,7 +667,7 @@ static int CmdBiphaseDecodeRaw(const char *Cmd) { } if (errCnt > 0) - PrintAndLogEx(ERR, "# Errors found during Demod (shown as " _YELLOW_("7")" in bit stream): %d", errCnt); + PrintAndLogEx(WARNING, "# Errors found during Demod (shown as " _YELLOW_("7")" in bit stream): %d", errCnt); PrintAndLogEx(NORMAL, "Biphase Decoded using offset: %d - # invert:%d - data:", offset, invert); PrintAndLogEx(NORMAL, "%s", sprint_bin_break(bits, size, 32)); diff --git a/client/cmdhf15.c b/client/cmdhf15.c index 65bc26010..33c3957fe 100644 --- a/client/cmdhf15.c +++ b/client/cmdhf15.c @@ -564,7 +564,7 @@ static int CmdHF15Demod(const char *Cmd) { } if (mask != 0x01) { - PrintAndLogEx(ERR, "Error, uneven octet! (discard extra bits!)"); + PrintAndLogEx(WARNING, "Warning, uneven octet! (discard extra bits!)"); PrintAndLogEx(NORMAL, " mask = %02x", mask); } PrintAndLogEx(NORMAL, "%d octets", k); diff --git a/client/cmdhffido.c b/client/cmdhffido.c index 9db6583f6..39b080dca 100644 --- a/client/cmdhffido.c +++ b/client/cmdhffido.c @@ -351,7 +351,7 @@ static int CmdHFFidoRegister(const char *cmd) { if (res == -0x4e00) { PrintAndLogEx(WARNING, "Signature is NOT VALID."); } else { - PrintAndLogEx(ERR, "Other signature check error: %x %s", (res < 0) ? -res : res, ecdsa_get_error(res)); + PrintAndLogEx(WARNING, "Other signature check error: %x %s", (res < 0) ? -res : res, ecdsa_get_error(res)); } } else { PrintAndLogEx(SUCCESS, "Signature is OK."); @@ -577,7 +577,7 @@ static int CmdHFFidoAuthenticate(const char *cmd) { if (res == -0x4e00) { PrintAndLogEx(WARNING, "Signature is NOT VALID."); } else { - PrintAndLogEx(ERR, "Other signature check error: %x %s", (res < 0) ? -res : res, ecdsa_get_error(res)); + PrintAndLogEx(WARNING, "Other signature check error: %x %s", (res < 0) ? -res : res, ecdsa_get_error(res)); } } else { PrintAndLogEx(SUCCESS, "Signature is OK."); diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 3ca958f80..a62924787 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -2765,7 +2765,7 @@ static int CmdHF14AMfEKeyPrn(const char *Cmd) { PrintAndLogEx(NORMAL, "|---|----------------|----------------|"); for (i = 0; i < numSectors; i++) { if (mfEmlGetMem(data, FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1, 1) != PM3_SUCCESS) { - PrintAndLogEx(ERR, "error get block %d", FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1); + PrintAndLogEx(WARNING, "error get block %d", FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1); break; } uint64_t keyA = bytes_to_num(data, 6); diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 07285053b..9a23e660b 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -1829,13 +1829,13 @@ static int CmdT55xxWipe(const char *Cmd) { else snprintf(ptrData, sizeof(writeData), "b 0 d 000880E0 p 0"); - if (CmdT55xxWriteBlock(ptrData) != PM3_SUCCESS) PrintAndLogEx(ERR, "Error writing blk 0"); + if (CmdT55xxWriteBlock(ptrData) != PM3_SUCCESS) PrintAndLogEx(WARNING, "Warning: error writing blk 0"); for (uint8_t blk = 1; blk < 8; blk++) { snprintf(ptrData, sizeof(writeData), "b %d d 0", blk); - if (CmdT55xxWriteBlock(ptrData) != PM3_SUCCESS) PrintAndLogEx(ERR, "Error writing blk %d", blk); + if (CmdT55xxWriteBlock(ptrData) != PM3_SUCCESS) PrintAndLogEx(WARNING, "Warning: error writing blk %d", blk); memset(writeData, 0x00, sizeof(writeData)); } diff --git a/client/cmdlfti.c b/client/cmdlfti.c index b37a6fdc1..5236550b2 100644 --- a/client/cmdlfti.c +++ b/client/cmdlfti.c @@ -233,7 +233,7 @@ static int CmdTIDemod(const char *Cmd) { // only 15 bits compare, last bit of ident is not valid if ((shift3 ^ shift0) & 0x7FFF) { - PrintAndLogEx(ERR, "Error: Ident mismatch!"); + PrintAndLogEx(WARNING, "Warning: Ident mismatch!"); } // WARNING the order of the bytes in which we calc crc below needs checking // i'm 99% sure the crc algorithm is correct, but it may need to eat the @@ -257,7 +257,7 @@ static int CmdTIDemod(const char *Cmd) { PrintAndLogEx(INFO, "Tag data = %08X%08X [Crc %04X %s]", shift1, shift0, crc, crcStr); if (crc != (shift2 & 0xFFFF)) - PrintAndLogEx(ERR, "Error: CRC mismatch, calculated %04X, got %04X", crc, shift2 & 0xFFFF); + PrintAndLogEx(WARNING, "Warning: CRC mismatch, calculated %04X, got %04X", crc, shift2 & 0xFFFF); retval = PM3_SUCCESS; goto out; diff --git a/client/cmdsmartcard.c b/client/cmdsmartcard.c index f7a0b4ca4..c49f0d0e7 100644 --- a/client/cmdsmartcard.c +++ b/client/cmdsmartcard.c @@ -284,7 +284,7 @@ static int PrintATR(uint8_t *atr, size_t atrlen) { vxor ^= atr[i]; if (vxor) - PrintAndLogEx(ERR, "Check sum error. Must be 0 got 0x%02X", vxor); + PrintAndLogEx(WARNING, "Invalid check sum. Must be 0 got 0x%02X", vxor); else PrintAndLogEx(INFO, "Check sum OK."); } @@ -295,7 +295,7 @@ static int PrintATR(uint8_t *atr, size_t atrlen) { uint8_t calen = 2 + T1len + TD1len + TDilen + K; if (atrlen != calen && atrlen != calen + 1) // may be CRC - PrintAndLogEx(ERR, "ATR length error. len: %d, T1len: %d, TD1len: %d, TDilen: %d, K: %d", atrlen, T1len, TD1len, TDilen, K); + PrintAndLogEx(WARNING, "Invalid ATR length. len: %d, T1len: %d, TD1len: %d, TDilen: %d, K: %d", atrlen, T1len, TD1len, TDilen, K); if (K > 0) PrintAndLogEx(INFO, "\nHistorical bytes | len 0x%02d | format %02x", K, atr[2 + T1len + TD1len + TDilen]); diff --git a/client/comms.c b/client/comms.c index dad7c1640..304948a4d 100644 --- a/client/comms.c +++ b/client/comms.c @@ -359,7 +359,7 @@ __attribute__((force_align_arg_pointer)) res = uart_receive(sp, (uint8_t *)&rx_raw.data, length, &rxlen); if ((res != PM3_SUCCESS) || (rxlen != length)) { - PrintAndLogEx(ERR, "Received packet frame error variable part too short? %d/%d", rxlen, length); + PrintAndLogEx(WARNING, "Received packet frame with variable part too short? %d/%d", rxlen, length); error = true; } else { @@ -392,7 +392,7 @@ __attribute__((force_align_arg_pointer)) if (!error) { // Get the postamble res = uart_receive(sp, (uint8_t *)&rx_raw.foopost, sizeof(PacketResponseNGPostamble), &rxlen); if ((res != PM3_SUCCESS) || (rxlen != sizeof(PacketResponseNGPostamble))) { - PrintAndLogEx(ERR, "Received packet frame error fetching postamble"); + PrintAndLogEx(WARNING, "Received packet frame without postamble"); error = true; } } @@ -402,7 +402,7 @@ __attribute__((force_align_arg_pointer)) uint8_t first, second; compute_crc(CRC_14443_A, (uint8_t *)&rx_raw, sizeof(PacketResponseNGPreamble) + length, &first, &second); if ((first << 8) + second != rx.crc) { - PrintAndLogEx(ERR, "Received packet frame CRC error %02X%02X <> %04X", first, second, rx.crc); + PrintAndLogEx(WARNING, "Received packet frame with invalid CRC %02X%02X <> %04X", first, second, rx.crc); error = true; } } @@ -424,7 +424,7 @@ __attribute__((force_align_arg_pointer)) res = uart_receive(sp, ((uint8_t *)&rx_old) + sizeof(PacketResponseNGPreamble), sizeof(PacketResponseOLD) - sizeof(PacketResponseNGPreamble), &rxlen); if ((res != PM3_SUCCESS) || (rxlen != sizeof(PacketResponseOLD) - sizeof(PacketResponseNGPreamble))) { - PrintAndLogEx(ERR, "Received packet OLD frame payload error too short? %d/%d", rxlen, sizeof(PacketResponseOLD) - sizeof(PacketResponseNGPreamble)); + PrintAndLogEx(WARNING, "Received packet OLD frame with payload too short? %d/%d", rxlen, sizeof(PacketResponseOLD) - sizeof(PacketResponseNGPreamble)); error = true; } if (!error) { diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c index 0585c1661..0b50ecfe1 100644 --- a/client/emv/cmdemv.c +++ b/client/emv/cmdemv.c @@ -931,7 +931,7 @@ static int CmdEMVExec(const char *Cmd) { while (AFL && AFL->len) { if (AFL->len % 4) { - PrintAndLogEx(ERR, "Error: Wrong AFL length: %d", AFL->len); + PrintAndLogEx(WARNING, "Warning: Wrong AFL length: %d", AFL->len); break; } @@ -952,7 +952,7 @@ static int CmdEMVExec(const char *Cmd) { res = EMVReadRecord(channel, true, SFI, n, buf, sizeof(buf), &len, &sw, tlvRoot); if (res) { - PrintAndLogEx(ERR, "Error SFI[%02x]. APDU error %4x", SFI, sw); + PrintAndLogEx(WARNING, "Error SFI[%02x]. APDU error %4x", SFI, sw); continue; } @@ -972,7 +972,7 @@ static int CmdEMVExec(const char *Cmd) { memcpy(&ODAiList[ODAiListLen], &buf[len - elmlen], elmlen); ODAiListLen += elmlen; } else { - PrintAndLogEx(ERR, "Error SFI[%02x]. Creating input list for Offline Data Authentication error.", SFI); + PrintAndLogEx(WARNING, "Error SFI[%02x]. Creating input list for Offline Data Authentication error.", SFI); } } else { memcpy(&ODAiList[ODAiListLen], buf, len); @@ -1001,7 +1001,7 @@ static int CmdEMVExec(const char *Cmd) { AIP = AIPtlv->value[0] + AIPtlv->value[1] * 0x100; PrintAndLogEx(NORMAL, "* * AIP=%04x", AIP); } else { - PrintAndLogEx(ERR, "Can't found AIP."); + PrintAndLogEx(ERR, "Can't find AIP."); } // SDA @@ -1047,11 +1047,11 @@ static int CmdEMVExec(const char *Cmd) { TLVPrintFromTLVLev(cvr, 1); } } else { - PrintAndLogEx(NORMAL, "WARNING: IAD not found."); + PrintAndLogEx(WARNING, "WARNING: IAD not found."); } } else { - PrintAndLogEx(ERR, "Error AC: Application Transaction Counter (ATC) not found."); + PrintAndLogEx(WARNING, "Warning AC: Application Transaction Counter (ATC) not found."); } } } @@ -1131,14 +1131,14 @@ static int CmdEMVExec(const char *Cmd) { PrintAndLogEx(NORMAL, "Transaction approved ONLINE."); break; default: - PrintAndLogEx(ERR, "Error: CID transaction code error %2x", CID->value[0] & EMVAC_AC_MASK); + PrintAndLogEx(WARNING, "Warning: CID transaction code error %2x", CID->value[0] & EMVAC_AC_MASK); break; } } else { - PrintAndLogEx(ERR, "Error: Wrong CID length %d", CID->len); + PrintAndLogEx(WARNING, "Warning: Wrong CID length %d", CID->len); } } else { - PrintAndLogEx(ERR, "Error: CID(9F27) not found."); + PrintAndLogEx(WARNING, "Warning: CID(9F27) not found."); } } diff --git a/client/emv/emvcore.c b/client/emv/emvcore.c index e7bda4be5..2d96b567a 100644 --- a/client/emv/emvcore.c +++ b/client/emv/emvcore.c @@ -763,7 +763,7 @@ int trDDA(EMVCommandChannel channel, bool decodeTLV, struct tlvdb *tlv) { if (tlvdb_get(tlv, 0x9f2d, NULL)) { struct emv_pk *icc_pe_pk = emv_pki_recover_icc_pe_cert(issuer_pk, tlv); if (!icc_pe_pk) { - PrintAndLogEx(ERR, "WARNING: ICC PE PK recover error. "); + PrintAndLogEx(WARNING, "WARNING: ICC PE PK recover error. "); } else { PrintAndLogEx(SUCCESS, "ICC PE PK recovered. RID %02hhx:%02hhx:%02hhx:%02hhx:%02hhx IDX %02hhx CSN %02hhx:%02hhx:%02hhx\n", icc_pe_pk->rid[0], @@ -807,7 +807,7 @@ int trDDA(EMVCommandChannel channel, bool decodeTLV, struct tlvdb *tlv) { PrintAndLogEx(SUCCESS, "ATC check OK."); PrintAndLogEx(SUCCESS, "fDDA (fast DDA) verified OK."); } else { - PrintAndLogEx(ERR, "Error: fDDA verified, but ATC in the certificate and ATC in the record not the same."); + PrintAndLogEx(WARNING, "Error: fDDA verified, but ATC in the certificate and ATC in the record not the same."); } } else { PrintAndLogEx(NORMAL, "\nERROR: fDDA (fast DDA) verify error"); @@ -862,7 +862,7 @@ int trDDA(EMVCommandChannel channel, bool decodeTLV, struct tlvdb *tlv) { struct tlvdb *dda_db = NULL; if (buf[0] == 0x80) { if (len < 3) { - PrintAndLogEx(ERR, "Error: Internal Authenticate format1 parsing error. length=%d", len); + PrintAndLogEx(WARNING, "Warning: Internal Authenticate format1 parsing error. length=%d", len); } else { // parse response 0x80 struct tlvdb *t80 = tlvdb_parse_multi(buf, len); diff --git a/client/fido/fidocore.c b/client/fido/fidocore.c index 21079eb34..c356c3456 100644 --- a/client/fido/fidocore.c +++ b/client/fido/fidocore.c @@ -386,7 +386,7 @@ static int FIDO2CheckSignature(json_t *root, uint8_t *publickey, uint8_t *sign, if (res == -0x4e00) { PrintAndLogEx(WARNING, "Signature is NOT VALID."); } else { - PrintAndLogEx(ERR, "Other signature check error: %x %s", (res < 0) ? -res : res, ecdsa_get_error(res)); + PrintAndLogEx(WARNING, "Other signature check error: %x %s", (res < 0) ? -res : res, ecdsa_get_error(res)); } return res; } else { diff --git a/client/loclass/elite_crack.c b/client/loclass/elite_crack.c index 3e0aa1dc5..5b019d8e0 100644 --- a/client/loclass/elite_crack.c +++ b/client/loclass/elite_crack.c @@ -517,7 +517,7 @@ int bruteforceDump(uint8_t dump[], size_t dumpsize, uint16_t keytable[]) { first16bytes[i] = keytable[i] & 0xFF; if (!(keytable[i] & CRACKED)) - PrintAndLogDevice(ERR, "error, we are missing byte %d, custom key calculation will fail...", i); + PrintAndLogDevice(WARNING, "Warning: we are missing byte %d, custom key calculation will fail...", i); } errors += calculateMasterKey(first16bytes, NULL); return errors; @@ -557,7 +557,7 @@ int bruteforceFile(const char *filename, uint16_t keytable[]) { fclose(f); if (bytes_read < fsize) { - PrintAndLogDevice(ERR, "Error, could only read %d bytes (should be %d)", bytes_read, fsize); + PrintAndLogDevice(WARNING, "Warning: could only read %d bytes (should be %d)", bytes_read, fsize); } uint8_t res = bruteforceDump(dump, fsize, keytable); diff --git a/client/mifare/mad.c b/client/mifare/mad.c index fa5b7d259..47b7cb70a 100644 --- a/client/mifare/mad.c +++ b/client/mifare/mad.c @@ -225,7 +225,7 @@ int MAD1DecodeAndPrint(uint8_t *sector, bool verbose, bool *haveMAD2) { PrintAndLogEx(NORMAL, "Card publisher sector not present."); } if (InfoByte == 0x10 || InfoByte >= 0x28) - PrintAndLogEx(ERR, "Info byte error"); + PrintAndLogEx(WARNING, "Info byte error"); PrintAndLogEx(NORMAL, "00 MAD1"); for (int i = 1; i < 16; i++) { From 2fc26fbf3553c3c5497342174f2cf108582b0bbe Mon Sep 17 00:00:00 2001 From: "Colin J. Brigato" Date: Sun, 14 Jul 2019 13:29:40 +0200 Subject: [PATCH 0061/1854] HF_COLIN/STANDALONE: FIX Simulation/Writing Tag to flash/Reading back from flash * Simulation was broke by the 4/7/10 UID lenght pseudo-support (which, in regard of the whole, will never be of any use unless complete reimplementaiton). Kept this part as respect, but enforced UID_IN_EMUL, since it will _ALWAYS_ be the case, be it direct simulation after tag breaking or from reading back tag. * Writing tag was broken when flashmem driver had SPI settings changed, enforcing 48MHz speed as necessity for some work (like in hf_bog), so now it is * Reading back, however, should absolutely be done at 24Mhz to avoid those unecessary and unstable [On this chip] FAST_READS. Should worsk flawlessly now. If one has spare time, handling getting new keys or defining whole Schemes in Flashmem would be perfect. Just has to be a conditional and a 8/16key ordered answer. --- armsrc/Standalone/hf_colin.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/armsrc/Standalone/hf_colin.c b/armsrc/Standalone/hf_colin.c index 63366259e..060c4af06 100644 --- a/armsrc/Standalone/hf_colin.c +++ b/armsrc/Standalone/hf_colin.c @@ -101,6 +101,8 @@ void ReadLastTagFromFlash() { size_t size = len; uint8_t *mem = BigBuf_malloc(size); + FlashmemSetSpiBaudrate(24000000); + if (!FlashInit()) { return; } @@ -148,6 +150,9 @@ void WriteTagToFlash(uint8_t index, size_t size) { emlGetMem(data, 0, (size * 64) / 1024); + + FlashmemSetSpiBaudrate(48000000); + if (!FlashInit()) { return; } @@ -424,7 +429,7 @@ failtag: //----------------------------------------------------------------------------- // also we could avoid first UID check for every block - // then let’s expose this “optimal case” of “well known vigik schemes” : + // then let's expose this “optimal case” of “well known vigik schemes” : for (uint8_t type = 0; type < 2 && !err && !trapped; type++) { for (int sec = 0; sec < sectorsCnt && !err && !trapped; ++sec) { key = cjat91_saMifareChkKeys(sec * 4, type, NULL, size, &keyBlock[0], &key64); @@ -783,10 +788,18 @@ readysim: case 7: flags = FLAG_7B_UID_IN_DATA; break; - default: + case 4: flags = FLAG_4B_UID_IN_DATA; break; + default: + flags = FLAG_UID_IN_EMUL; + break; } + + // Use UID, SAK, ATQA from EMUL, if uid not defined + //if ((flags & (FLAG_4B_UID_IN_DATA | FLAG_7B_UID_IN_DATA | FLAG_10B_UID_IN_DATA)) == 0) { + flags |= FLAG_UID_IN_EMUL; + //} Mifare1ksim(flags | FLAG_MF_1K, 0, cjuid); LED_C_OFF(); SpinOff(50); @@ -902,7 +915,7 @@ int e_MifareECardLoad(uint32_t numofsectors, uint8_t keytype) { return (isOK) ? PM3_SUCCESS : PM3_EUNDEF; } -/* the chk function is a piwi’ed(tm) check that will try all keys for +/* the chk function is a piwi'ed(tm) check that will try all keys for a particular sector. also no tracing no dbg */ int cjat91_saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace, uint8_t keyCount, uint8_t *datain, uint64_t *key) { DBGLEVEL = DBG_NONE; From 68bfbde185e7bcad7757885f47d0ac9c5a5ded8a Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sun, 14 Jul 2019 14:59:59 +0300 Subject: [PATCH 0062/1854] CmdHF14AAPDU sketch --- client/cmdhf14a.c | 45 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index 018431a28..33bfa7cbe 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -839,17 +839,28 @@ static int CmdHF14AAPDU(const char *Cmd) { bool activateField = false; bool leaveSignalON = false; bool decodeTLV = false; + bool decodeAPDU = false; + bool makeAPDU = false; + bool extendedAPDU = false; + int le = 0; CLIParserInit("hf 14a apdu", - "Sends an ISO 7816-4 APDU via ISO 14443-4 block transmission protocol (T=CL)", - "Sample:\n\thf 14a apdu -st 00A404000E325041592E5359532E444446303100\n"); + "Sends an ISO 7816-4 APDU via ISO 14443-4 block transmission protocol (T=CL). works with all apdu types from ISO 7816-4:2013", + "Sample:\n\thf 14a apdu -st 00A404000E325041592E5359532E444446303100\n" + "\thf 14a apdu -sd 00A404000E325041592E5359532E444446303100 - decode apdu\n" + "\thf 14a apdu -sm 00A40400 325041592E5359532E4444463031 -l 256 - encode extended apdu\n" + "\thf 14a apdu -sm 00A40400 325041592E5359532E4444463031 -el 65536 - encode standard apdu\n"); void *argtable[] = { arg_param_begin, - arg_lit0("sS", "select", "activate field and select card"), - arg_lit0("kK", "keep", "leave the signal field ON after receive response"), - arg_lit0("tT", "tlv", "executes TLV decoder if it possible"), - arg_strx1(NULL, NULL, "", NULL), + arg_lit0("sS", "select", "activate field and select card"), + arg_lit0("kK", "keep", "leave the signal field ON after receive response"), + arg_lit0("tT", "tlv", "executes TLV decoder if it possible"), + arg_lit0("dD", "decapdu", "decode apdu request if it possible"), + arg_lit0("mM", "make", "", "make apdu with head from this field and data from data field. Must be 4 bytes length: "), + arg_lit0("eE", "extended", "make extended length apdu if `m` parameter included"), + arg_lit0("lL", "le", "Le apdu parameter if `m` parameter included"), + arg_strx1(NULL, NULL, "", "data if `m` parameter included"), arg_param_end }; CLIExecWithReturn(Cmd, argtable, false); @@ -857,8 +868,26 @@ static int CmdHF14AAPDU(const char *Cmd) { activateField = arg_get_lit(1); leaveSignalON = arg_get_lit(2); decodeTLV = arg_get_lit(3); - // len = data + PCB(1b) + CRC(2b) - CLIGetHexBLessWithReturn(4, data, &datalen, 1 + 2); + decodeAPDU = arg_get_lit(4); + makeAPDU = arg_get_lit(5); + extendedAPDU = arg_get_lit(6); + le = arg_get_lit(7); + + if (makeAPDU) { + + } else { + if (extendedAPDU) { + PrintAndLogEx(ERR, "make mode not set but here `e` option."); + return 1; + } + if (le > 0) { + PrintAndLogEx(ERR, "make mode not set but here `l` option."); + return 1; + } + + // len = data + PCB(1b) + CRC(2b) + CLIGetHexBLessWithReturn(4, data, &datalen, 1 + 2); + } CLIParserFree(); PrintAndLogEx(NORMAL, ">>>>[%s%s%s] %s", activateField ? "sel " : "", leaveSignalON ? "keep " : "", decodeTLV ? "TLV" : "", sprint_hex(data, datalen)); From 51bcc80a2bffe0140a8d788bfe235d5af92c9f8a Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sun, 14 Jul 2019 15:00:40 +0300 Subject: [PATCH 0063/1854] small fix --- client/cmdhf14a.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index 33bfa7cbe..1ff54265c 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -848,8 +848,8 @@ static int CmdHF14AAPDU(const char *Cmd) { "Sends an ISO 7816-4 APDU via ISO 14443-4 block transmission protocol (T=CL). works with all apdu types from ISO 7816-4:2013", "Sample:\n\thf 14a apdu -st 00A404000E325041592E5359532E444446303100\n" "\thf 14a apdu -sd 00A404000E325041592E5359532E444446303100 - decode apdu\n" - "\thf 14a apdu -sm 00A40400 325041592E5359532E4444463031 -l 256 - encode extended apdu\n" - "\thf 14a apdu -sm 00A40400 325041592E5359532E4444463031 -el 65536 - encode standard apdu\n"); + "\thf 14a apdu -sm 00A40400 325041592E5359532E4444463031 -l 256 - encode standard apdu\n" + "\thf 14a apdu -sm 00A40400 325041592E5359532E4444463031 -el 65536 - encode extended apdu\n"); void *argtable[] = { arg_param_begin, From a9d15d85e613d231c044d6d22f5aa36cb91529c2 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sun, 14 Jul 2019 15:14:54 +0300 Subject: [PATCH 0064/1854] sketch2 --- client/cmdhf14a.c | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index 1ff54265c..fb8753921 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -836,6 +836,8 @@ int ExchangeAPDU14a(uint8_t *datain, int datainlen, bool activateField, bool lea static int CmdHF14AAPDU(const char *Cmd) { uint8_t data[PM3_CMD_DATA_SIZE]; int datalen = 0; + uint8_t header[PM3_CMD_DATA_SIZE]; + int headerlen = 0; bool activateField = false; bool leaveSignalON = false; bool decodeTLV = false; @@ -874,24 +876,54 @@ static int CmdHF14AAPDU(const char *Cmd) { le = arg_get_lit(7); if (makeAPDU) { + uint8_t apdudata[PM3_CMD_DATA_SIZE] = {0}; + int apdudatalen = 0; + + CLIGetHexBLessWithReturn(8, apdudata, &apdudatalen, 1 + 2); + + APDUStruct apdu; + apdu.cla = header[0]; + apdu.ins = header[1]; + apdu.p1 = header[2]; + apdu.p2 = header[3]; + + apdu.lc = apdudatalen; + apdu.data = apdudata; + + apdu.extended_apdu = extendedAPDU; + apdu.le = le; + + if (APDUEncode(&apdu, data, &datalen)) { + PrintAndLogEx(ERR, "can't make apdu with provided parameters."); + return 1; + } } else { if (extendedAPDU) { PrintAndLogEx(ERR, "make mode not set but here `e` option."); - return 1; + return 2; } if (le > 0) { PrintAndLogEx(ERR, "make mode not set but here `l` option."); - return 1; + return 2; } // len = data + PCB(1b) + CRC(2b) - CLIGetHexBLessWithReturn(4, data, &datalen, 1 + 2); + CLIGetHexBLessWithReturn(8, data, &datalen, 1 + 2); } CLIParserFree(); PrintAndLogEx(NORMAL, ">>>>[%s%s%s] %s", activateField ? "sel " : "", leaveSignalON ? "keep " : "", decodeTLV ? "TLV" : "", sprint_hex(data, datalen)); + if (decodeAPDU) { + APDUStruct apdu; + + if (APDUDecode(data, datalen, &apdu) == 0) + APDUPrint(apdu); + else + PrintAndLogEx(WARNING, "can't decode APDU."); + } + int res = ExchangeAPDU14a(data, datalen, activateField, leaveSignalON, data, PM3_CMD_DATA_SIZE, &datalen); if (res) From d746847d134f9272c4c7565e9242c38b32e990a3 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 14 Jul 2019 17:58:47 +0200 Subject: [PATCH 0065/1854] proxmark3.sh for WSL: handle case when chmod is needed --- .../Windows-Installation-Instructions.md | 1 + proxmark3.sh | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/doc/md/Installation_Instructions/Windows-Installation-Instructions.md b/doc/md/Installation_Instructions/Windows-Installation-Instructions.md index eacdc4b62..db9a9084f 100644 --- a/doc/md/Installation_Instructions/Windows-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Windows-Installation-Instructions.md @@ -166,3 +166,4 @@ Or, by specifying the COM port manually: client/proxmark3 /dev/ttySX ``` +Note that it may take a quite long time for a freshly plugged Proxmark3 to be visible on a WSL /dev/ttySX port. diff --git a/proxmark3.sh b/proxmark3.sh index 39eb80779..b45887a23 100755 --- a/proxmark3.sh +++ b/proxmark3.sh @@ -51,6 +51,10 @@ function wait4proxmark_WSL { fi sleep .1 done + if [ -e "$PM3" ] && ! [ -w "$PM3" ]; then + echo "We need to give current user read/write access to $PM3" + sudo chmod 666 "$PM3" + fi echo $PM3 } From 82e0568e65abf13af613f28c4ed418de4b78f8e5 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 14 Jul 2019 18:20:41 +0200 Subject: [PATCH 0066/1854] shellcheck bash scripts --- flash-all.sh | 3 ++- flash-bootrom.sh | 3 ++- flash-fullimage.sh | 3 ++- proxmark3.sh | 40 +++++++++++++++++++--------------------- 4 files changed, 25 insertions(+), 24 deletions(-) diff --git a/flash-all.sh b/flash-all.sh index 27e1fb526..d4fcdc975 100755 --- a/flash-all.sh +++ b/flash-all.sh @@ -1,4 +1,5 @@ #!/bin/bash -cd $(dirname "$0") +PM3PATH=$(dirname "$0") +cd "$PM3PATH" || exit 1 . proxmark3.sh diff --git a/flash-bootrom.sh b/flash-bootrom.sh index 27e1fb526..d4fcdc975 100755 --- a/flash-bootrom.sh +++ b/flash-bootrom.sh @@ -1,4 +1,5 @@ #!/bin/bash -cd $(dirname "$0") +PM3PATH=$(dirname "$0") +cd "$PM3PATH" || exit 1 . proxmark3.sh diff --git a/flash-fullimage.sh b/flash-fullimage.sh index 27e1fb526..d4fcdc975 100755 --- a/flash-fullimage.sh +++ b/flash-fullimage.sh @@ -1,4 +1,5 @@ #!/bin/bash -cd $(dirname "$0") +PM3PATH=$(dirname "$0") +cd "$PM3PATH" || exit 1 . proxmark3.sh diff --git a/proxmark3.sh b/proxmark3.sh index b45887a23..b8d6acabb 100755 --- a/proxmark3.sh +++ b/proxmark3.sh @@ -3,28 +3,31 @@ FULLIMAGE="armsrc/obj/fullimage.elf" BOOTIMAGE="bootrom/obj/bootrom.elf" -cd $(dirname "$0") +PM3PATH=$(dirname "$0") +cd "$PM3PATH" || exit 1 function wait4proxmark_Linux { echo >&2 "Waiting for Proxmark to appear..." - while [ ! -c /dev/ttyACM? -a ! -c /dev/pm3-? ]; do + while true; do + PM3=$(find /dev/pm3-* /dev/ttyACM* 2>/dev/null | head -1) + if [[ $PM3 != "" ]]; then + break + fi sleep .1 done - local PM3=`ls -1 /dev/pm3-? /dev/ttyACM? 2>/dev/null | head -1` - echo $PM3 + echo "$PM3" } function wait4proxmark_macOS { echo >&2 "Waiting for Proxmark to appear..." while true; do - PM3=$(ls /dev/pm3-* /dev/cu.usbmodem* 2>/dev/null | head -1) + PM3=$(find /dev/pm3-* /dev/cu.usbmodem* 2>/dev/null | head -1) if [[ $PM3 != "" ]]; then - #echo >&2 -e "Found proxmark on $(ls /dev/pm3-* /dev/cu.usbmodem* 2>/dev/null | head -1)\n" break fi sleep .1 done - echo $PM3 + echo "$PM3" } function wait4proxmark_Windows { @@ -37,7 +40,7 @@ function wait4proxmark_Windows { fi sleep .1 done - echo $PM3 + echo "$PM3" } function wait4proxmark_WSL { @@ -51,27 +54,23 @@ function wait4proxmark_WSL { fi sleep .1 done - if [ -e "$PM3" ] && ! [ -w "$PM3" ]; then + if [ -e "$PM3" ] && [ ! -w "$PM3" ]; then echo "We need to give current user read/write access to $PM3" sudo chmod 666 "$PM3" fi - echo $PM3 + echo "$PM3" } SCRIPT=$(basename -- "$0") if [ "$SCRIPT" = "proxmark3.sh" ]; then - CMD=client/proxmark3 + CMD() { client/proxmark3 "$@"; } elif [ "$SCRIPT" = "flash-all.sh" ]; then - CMD=client/flasher - ARG1="-b $BOOTIMAGE" - ARG2="$FULLIMAGE" -elif [ "$SCRIPT" = "flash-fullimage.sh" ]; then - CMD=client/flasher - ARG2="$FULLIMAGE" + CMD() { client/flasher "$1" -b "$BOOTIMAGE" "$FULLIMAGE"; } +elif [ "$SCRIPT" = "flash-fullimage.sh" ]; then CMD=client/flasher + CMD() { client/flasher "$1" "$FULLIMAGE"; } elif [ "$SCRIPT" = "flash-bootrom.sh" ]; then - CMD=client/flasher - ARG1="-b $BOOTIMAGE" + CMD() { client/flasher "$1" -b "$BOOTIMAGE"; } else echo "Script ran under unknown name, abort: $SCRIPT" exit 1 @@ -96,6 +95,5 @@ if [ "$PORT" = "" ]; then exit 1 fi -#echo Running "$CMD" "$PORT" $ARG1 $ARG2 "$@" -"$CMD" "$PORT" $ARG1 $ARG2 "$@" +CMD "$PORT" "$@" exit $? From fee9c0ef847b8b7471d7e7af3cbf17fcb9fa4ee8 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 14 Jul 2019 18:26:04 +0200 Subject: [PATCH 0067/1854] silent uart_close error message as it can be called from uart_open failing modes, e.g. when waiting for port to appear --- uart/uart_posix.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/uart/uart_posix.c b/uart/uart_posix.c index 22cc75207..ea535fd73 100644 --- a/uart/uart_posix.c +++ b/uart/uart_posix.c @@ -238,7 +238,8 @@ void uart_close(const serial_port sp) { // Does the system allows us to place a lock on this file descriptor int err = fcntl(spu->fd, F_SETLK, &fl); if (err == -1) { - printf("[!] UART error while closing port\n"); + //silent error message as it can be called from uart_open failing modes, e.g. when waiting for port to appear + //printf("[!] UART error while closing port\n"); } close(spu->fd); free(sp); From 383d3327be40c3a276971bd0b371d9b3520b1dac Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 14 Jul 2019 18:42:11 +0200 Subject: [PATCH 0068/1854] remove spurious changes in make style --- Makefile | 4 ++-- client/fpga_compress.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 910aa62f6..64dbea4eb 100644 --- a/Makefile +++ b/Makefile @@ -145,12 +145,12 @@ style: # Make sure astyle is installed @which astyle >/dev/null || ( echo "Please install 'astyle' package first" ; exit 1 ) # Remove spaces & tabs at EOL, add LF at EOF if needed on *.c, *.h, *.cpp. *.lua, *.py, *.pl, Makefile - find . \( -name "*.[ch]" -or -name "*.cpp" -or -name "*.lua" -or -name "*.py" -or -name "*.pl" -or -name "Makefile" \) \ + find . \( -name "*.[ch]" -or \( -name "*.cpp" -and -not -name "*.moc.cpp" \) -or -name "*.lua" -or -name "*.py" -or -name "*.pl" -or -name "Makefile" \) \ -exec perl -pi -e 's/[ \t]+$$//' {} \; \ -exec sh -c "tail -c1 {} | xxd -p | tail -1 | grep -q -v 0a$$" \; \ -exec sh -c "echo >> {}" \; # Apply astyle on *.c, *.h, *.cpp - find . \( -name "*.[ch]" -or -name "*.cpp" \) -exec astyle --formatted --mode=c --suffix=none \ + find . \( -name "*.[ch]" -or \( -name "*.cpp" -and -not -name "*.moc.cpp" \) \) -exec astyle --formatted --mode=c --suffix=none \ --indent=spaces=4 --indent-switches \ --keep-one-line-blocks --max-instatement-indent=60 \ --style=google --pad-oper --unpad-paren --pad-header \ diff --git a/client/fpga_compress.c b/client/fpga_compress.c index 7cd4652e1..a030afe81 100644 --- a/client/fpga_compress.c +++ b/client/fpga_compress.c @@ -375,7 +375,7 @@ static void print_version_info_preamble(FILE *outfile, int num_infiles) { fprintf(outfile, "\n"); fprintf(outfile, "\n"); fprintf(outfile, "const int fpga_bitstream_num = %d;\n", num_infiles); - fprintf(outfile, "const char* const fpga_version_information[%d] = {\n", num_infiles); + fprintf(outfile, "const char *const fpga_version_information[%d] = {\n", num_infiles); } static int generate_fpga_version_info(FILE *infile[], char *infile_names[], int num_infiles, FILE *outfile) { @@ -386,7 +386,7 @@ static int generate_fpga_version_info(FILE *infile[], char *infile_names[], int for (int i = 0; i < num_infiles; i++) { FpgaGatherVersion(infile[i], infile_names[i], version_string, sizeof(version_string)); - fprintf(outfile, "\t\" %s\"", version_string); + fprintf(outfile, " \" %s\"", version_string); if (i != num_infiles - 1) { fprintf(outfile, ","); } From f6f7e7a9f62de7ef37e44b2001a50f4c6900219b Mon Sep 17 00:00:00 2001 From: Eloff Date: Sun, 14 Jul 2019 23:12:39 +0300 Subject: [PATCH 0069/1854] hf_mf_sim. Really tags not respond NACK on invalid authentication --- armsrc/mifaresim.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/armsrc/mifaresim.c b/armsrc/mifaresim.c index 8f21882be..36f5c3593 100644 --- a/armsrc/mifaresim.c +++ b/armsrc/mifaresim.c @@ -1036,8 +1036,9 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain) { ); } cardAUTHKEY = AUTHKEYNONE; // not authenticated - EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA)); cardSTATE_TO_IDLE(); + // Really tags not respond NACK on invalid authentication + LogTrace(uart->output, uart->len, uart->startTime * 16 - DELAY_AIR2ARM_AS_TAG, uart->endTime * 16 - DELAY_AIR2ARM_AS_TAG, uart->parity, true); break; } From 055efaff88b5f387d2cbaaee1bf2dcd1045d7b1e Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 14 Jul 2019 22:13:40 +0200 Subject: [PATCH 0070/1854] proxmark.sh: remove leftover var --- proxmark3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proxmark3.sh b/proxmark3.sh index b8d6acabb..4cd6d76bc 100755 --- a/proxmark3.sh +++ b/proxmark3.sh @@ -67,7 +67,7 @@ if [ "$SCRIPT" = "proxmark3.sh" ]; then CMD() { client/proxmark3 "$@"; } elif [ "$SCRIPT" = "flash-all.sh" ]; then CMD() { client/flasher "$1" -b "$BOOTIMAGE" "$FULLIMAGE"; } -elif [ "$SCRIPT" = "flash-fullimage.sh" ]; then CMD=client/flasher +elif [ "$SCRIPT" = "flash-fullimage.sh" ]; then CMD() { client/flasher "$1" "$FULLIMAGE"; } elif [ "$SCRIPT" = "flash-bootrom.sh" ]; then CMD() { client/flasher "$1" -b "$BOOTIMAGE"; } From a28e359095f395ee7153c1eeda39d825bb35be97 Mon Sep 17 00:00:00 2001 From: Eloff Date: Sun, 14 Jul 2019 23:18:07 +0300 Subject: [PATCH 0071/1854] Fix. More flexible anti-collision frame check --- armsrc/mifaresim.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/armsrc/mifaresim.c b/armsrc/mifaresim.c index 8f21882be..f17381ecd 100644 --- a/armsrc/mifaresim.c +++ b/armsrc/mifaresim.c @@ -625,7 +625,8 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain) { } // Incoming anti-collision frame - if (receivedCmd_len >= 2 && receivedCmd_len <= 6 && receivedCmd[1] == 0x50) { + // receivedCmd[1] indicates number of byte and bit collision, supports only for bit collision is zero + if (receivedCmd_len >= 3 && receivedCmd_len <= 6 && (receivedCmd[1] & 0x0f) == 0) { // we can process only full-byte frame anti-collision procedure if (memcmp(&receivedCmd[2], responses[uid_index].response, receivedCmd_len - 2) == 0) { // response missing part of UID via relative array index From 0a845df8c3fee8db399268b2b8658a594b3518e2 Mon Sep 17 00:00:00 2001 From: Chris Date: Sun, 14 Jul 2019 22:52:34 +0200 Subject: [PATCH 0072/1854] chg: 'script run read_pwd_mem' - now can correctly deal with more than 4096 bytes when printing mifare classic keys --- client/scripts/read_pwd_mem.lua | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/client/scripts/read_pwd_mem.lua b/client/scripts/read_pwd_mem.lua index 4aa2e6299..7dbfa6fba 100644 --- a/client/scripts/read_pwd_mem.lua +++ b/client/scripts/read_pwd_mem.lua @@ -81,18 +81,19 @@ local function main(args) if o == 'o' then offset = tonumber(a) end -- num of bytes to read - if o == 'l' then length = tonumber(a) end + if o == 'l' then + length = tonumber(a) + if length < 0 or length > 256 then + return oops('Error: Length is not valid. Must be less than 256') + end + end -- keylength if o == 'k' then keylength = tonumber(a); usedkey = true end - if o == 'm' then keylength =6; usedkey = true; offset = 0x3F000-0x6000; end - if o == 't' then keylength =4; usedkey = true; offset = 0x3F000-0x3000; end - if o == 'i' then keylength =8; usedkey = true; offset = 0x3F000-0x4000; end - end - - if length < 0 or length > 256 then - return oops('Error: Length is not valid. Must be less than 256') + if o == 'm' then keylength = 6; usedkey = true; length = 8192; offset = 0x3F000-0x6000; end + if o == 't' then keylength = 4; usedkey = true; length = 4096; offset = 0x3F000-0x3000; end + if o == 'i' then keylength = 8; usedkey = true; length = 4096; offset = 0x3F000-0x4000; end end if (offset < 0) or (offset % 4 ~= 0) then @@ -102,9 +103,7 @@ local function main(args) print('Memory offset', offset) print('Length ', length) print('Key length ', keylength) - print( string.rep('--',20) ) - - if usedkey then length = 4096 end + print( string.rep('--', 20) ) data, err = core.GetFromFlashMem(offset, length) if err then return oops(err) end @@ -116,7 +115,6 @@ local function main(args) local kl = keylength * 2 for i = 1, keys do - key = string.sub(s, (i - 1) * kl + 1, i * kl ) print(string.format('[%02d] %s',i, key)) end From 0c3d2cee2baf7c18d98e027b3a902aba467240a5 Mon Sep 17 00:00:00 2001 From: Eloff Date: Mon, 15 Jul 2019 00:00:34 +0300 Subject: [PATCH 0073/1854] Changelog for PR #245, #246 --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8dd057c73..3b9a41a37 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Fix Mifare Classic simulation more flexible anti-collision check (@McEloff) + - Change: Mifare Classic simulation not respond NACK on invalid authentication request (@McEloff) - Change: Don't clear trace log during 'hf mf chk', to save whole process history (@McEloff) - Add support for WSL in proxmark.sh (@doegox) - Add documentation for usage of Proxmark3 under WSL (@doegox) From 1f9eb10d15ee648a5a75c3f0a1964abd9eaa6557 Mon Sep 17 00:00:00 2001 From: Chris Date: Sun, 14 Jul 2019 23:02:24 +0200 Subject: [PATCH 0074/1854] textual --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8dd057c73..7cb72cea9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Change: 'read_pwd_mem.lua' now handles Mifare Classic dictionaries large than 4096 bytes (@iceman) - Change: Don't clear trace log during 'hf mf chk', to save whole process history (@McEloff) - Add support for WSL in proxmark.sh (@doegox) - Add documentation for usage of Proxmark3 under WSL (@doegox) From cad1d500ca928f34c607a05d6eff955eaeb71a0b Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 15 Jul 2019 00:31:38 +0200 Subject: [PATCH 0075/1854] add msleep command --- client/cmdmain.c | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/client/cmdmain.c b/client/cmdmain.c index 311e2d6de..6748f81f0 100644 --- a/client/cmdmain.c +++ b/client/cmdmain.c @@ -31,6 +31,32 @@ static int CmdRem(const char *Cmd) { return PM3_SUCCESS; } +static int usage_msleep(void) { + PrintAndLogEx(NORMAL, "Sleep for given amount of milliseconds"); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Usage: msleep "); + PrintAndLogEx(NORMAL, "Options:"); + PrintAndLogEx(NORMAL, " h This help"); + PrintAndLogEx(NORMAL, " time in milliseconds"); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Examples:"); + PrintAndLogEx(NORMAL, " msleep 100"); + return PM3_SUCCESS; +} + +static int CmdMsleep(const char *Cmd) { + uint32_t ms = 0; + char ctmp = tolower(param_getchar(Cmd, 0)); + if (strlen(Cmd) < 1 || ctmp == 'h') return usage_msleep(); + if (param_getchar(Cmd, 0) != 0x00) { + ms = param_get32ex(Cmd, 0, 0, 10); + if (ms == 0) + return usage_msleep(); + } + msleep(ms); + return PM3_SUCCESS; +} + static int CmdQuit(const char *Cmd) { (void)Cmd; // Cmd is not used so far return PM3_EFATAL; @@ -50,8 +76,9 @@ static command_t CommandTable[] = { {"hw", CmdHW, AlwaysAvailable, "{ Hardware commands... }"}, {"lf", CmdLF, AlwaysAvailable, "{ Low Frequency commands... }"}, {"mem", CmdFlashMem, IfPm3Flash, "{ Flash Memory manipulation... }"}, - {"rem", CmdRem, AlwaysAvailable, "{ Add text to row in log file }"}, - {"reveng", CmdRev, AlwaysAvailable, "{ Crc calculations from the RevEng software... }"}, + {"msleep", CmdMsleep, AlwaysAvailable, "Add a pause in milliseconds"}, + {"rem", CmdRem, AlwaysAvailable, "Add text to row in log file"}, + {"reveng", CmdRev, AlwaysAvailable, "{ Crc calculations from the RevEng software }"}, {"sc", CmdSmartcard, IfPm3Smartcard, "{ Smart card ISO7816 commands... }"}, {"script", CmdScript, AlwaysAvailable, "{ Scripting commands }"}, {"trace", CmdTrace, AlwaysAvailable, "{ Trace manipulation... }"}, From 2209a0c00d415870751fed9f66ddabbd56537336 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 15 Jul 2019 01:13:11 +0200 Subject: [PATCH 0076/1854] BUSY_TIMEOUT for mem wipe was too short, thanks @cjbrigato --- armsrc/flashmem.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/flashmem.h b/armsrc/flashmem.h index 4016e66bd..59d3bef9c 100644 --- a/armsrc/flashmem.h +++ b/armsrc/flashmem.h @@ -62,7 +62,7 @@ #define RESUME 0x7A // Flash busy timeout: 20ms is the strict minimum when writing 256kb -#define BUSY_TIMEOUT 50000L +#define BUSY_TIMEOUT 200000L #define WINBOND_MANID 0xEF #define WINBOND_DEVID 0x11 From 6a54de1184ba9861785cbd724e717b3bdb7dc646 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 15 Jul 2019 12:47:42 +0200 Subject: [PATCH 0077/1854] changelog --- CHANGELOG.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f2f7f952c..d53738a29 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,10 +3,12 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Fix: timeout for mem wipe was too short, thanks @cjbrigato (@doegox) - Fix 'hf mf sim' - Mifare Classic simulation more flexible anti-collision check (@McEloff) - - Change: 'hf mf sim ' - Mifare Classic simulation not respond NACK on invalid authentication request (@McEloff) + - Change: 'hf mf sim' - Mifare Classic simulation not respond NACK on invalid authentication request (@McEloff) - Change: 'read_pwd_mem.lua' now handles Mifare Classic dictionaries large than 4096 bytes (@iceman) - Change: Don't clear trace log during 'hf mf chk', to save whole process history (@McEloff) + - Add 'msleep' command, for pauses in scripts (@doegox) - Add support for WSL in proxmark.sh (@doegox) - Add documentation for usage of Proxmark3 under WSL (@doegox) - Change: replace aes.c with mbedtls version (@slurdge) @@ -19,14 +21,14 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Fix EMVGPO bug (@matrix) - Add hitag2 write password auth (@ViRb3) - Add check if bootloader segment is within bounds (@slurdge) - - Add `hf 15 csetuid` - set UID on ISO-15693 Magic tags (@t0m4-null) + - Add 'hf 15 csetuid' - set UID on ISO-15693 Magic tags (@t0m4-null) - Change: Print help if unknown arg for hitag reader/writer (@ViRb3) - Fix clock deadlock in hitag sniff (@ViRb3) - Add compiler info in client & ARM sections (@slurdge) - Add support for automatic COM detection on Windows (@slurdge) - Add support for compilation on RaspberryPiZero (armv6) (@doegox) - Change: updates to README (@iceman) - - Change: hf mf/mfu dbg => hw dbg (@doegox) + - Change: 'hf mf/mfu dbg' => 'hw dbg' (@doegox) - Change: replace usb_poll_validate_length() by data_available() that supports USART too (@doegox) - Make sure standalone modes can be launched when connected on USB without client (@doegox) - Change: cleaner makefile execution, use 'make V=1' if you want to see full lines (@doegox) From 0ea7fa7784f99f95a4629ac4619e70adeacb43fc Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 15 Jul 2019 12:48:43 +0200 Subject: [PATCH 0078/1854] buggy 'mem read' removed, 'mem save' renamed 'mem dump', can now display too --- CHANGELOG.md | 1 + armsrc/Standalone/hf_bog.c | 2 +- armsrc/appmain.c | 32 -------------- client/cmdflashmem.c | 90 +++++++++++--------------------------- doc/new_frame_format.md | 4 +- include/pm3_cmd.h | 1 - 6 files changed, 30 insertions(+), 100 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d53738a29..df03c68c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Change: buggy 'mem read' removed, 'mem save' renamed 'mem dump', can now display too (@doegox) - Fix: timeout for mem wipe was too short, thanks @cjbrigato (@doegox) - Fix 'hf mf sim' - Mifare Classic simulation more flexible anti-collision check (@McEloff) - Change: 'hf mf sim' - Mifare Classic simulation not respond NACK on invalid authentication request (@McEloff) diff --git a/armsrc/Standalone/hf_bog.c b/armsrc/Standalone/hf_bog.c index 093bc841f..ca0b0eeeb 100644 --- a/armsrc/Standalone/hf_bog.c +++ b/armsrc/Standalone/hf_bog.c @@ -15,7 +15,7 @@ The retrieved sniffing session can be acquired by connecting the device to a client that supports the reconnect capability and issue 'hf 14a list'. In order to view the grabbed authentication attempts in the flash mem, -you can simply run 'script run read_pwd_mem' or just 'mem read l 256' +you can simply run 'script run read_pwd_mem' or just 'mem dump p l 256' from the client to view the stored quadlets. */ diff --git a/armsrc/appmain.c b/armsrc/appmain.c index facce653c..b91853199 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1592,38 +1592,6 @@ static void PacketReceived(PacketCommandNG *packet) { FlashmemSetSpiBaudrate(packet->oldarg[0]); break; } - case CMD_FLASHMEM_READ: { - LED_B_ON(); - uint32_t startidx = packet->oldarg[0]; - uint16_t len = packet->oldarg[1]; - - Dbprintf("FlashMem read | %d - %d | ", startidx, len); - - size_t size = MIN(PM3_CMD_DATA_SIZE, len); - - if (!FlashInit()) { - break; - } - - uint8_t *mem = BigBuf_malloc(size); - - for (size_t i = 0; i < len; i += size) { - len = MIN((len - i), size); - - Dbprintf("FlashMem reading | %d | %d | %d |", startidx + i, i, len); - uint16_t isok = Flash_ReadDataCont(startidx + i, mem, len); - if (isok == len) { - print_result("Chunk: ", mem, len); - } else { - Dbprintf("FlashMem reading failed | %d | %d", len, isok); - break; - } - } - BigBuf_free(); - FlashStop(); - LED_B_OFF(); - break; - } case CMD_FLASHMEM_WRITE: { LED_B_ON(); uint8_t isok = 0; diff --git a/client/cmdflashmem.c b/client/cmdflashmem.c index 6bab15cd9..9546b421f 100644 --- a/client/cmdflashmem.c +++ b/client/cmdflashmem.c @@ -37,17 +37,6 @@ static int usage_flashmem_spibaud(void) { return PM3_SUCCESS; } -static int usage_flashmem_read(void) { - PrintAndLogEx(NORMAL, "Read flash memory on device"); - PrintAndLogEx(NORMAL, "Usage: mem read o l "); - PrintAndLogEx(NORMAL, " o : offset in memory"); - PrintAndLogEx(NORMAL, " l : length"); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " mem read o 0 l 32"); // read 32 bytes starting at offset 0 - PrintAndLogEx(NORMAL, " mem read o 1024 l 10"); // read 10 bytes starting at offset 1024 - return PM3_SUCCESS; -} static int usage_flashmem_load(void) { PrintAndLogEx(NORMAL, "Loads binary file into flash memory on device"); PrintAndLogEx(NORMAL, "Usage: mem load [o ] f [m|t|i]"); @@ -67,17 +56,19 @@ static int usage_flashmem_load(void) { PrintAndLogEx(NORMAL, " mem load f default_iclass_keys i"); return PM3_SUCCESS; } -static int usage_flashmem_save(void) { - PrintAndLogEx(NORMAL, "Saves flash memory on device into the file"); - PrintAndLogEx(NORMAL, " Usage: mem save [o ] [l ] f "); +static int usage_flashmem_dump(void) { + PrintAndLogEx(NORMAL, "Dumps flash memory on device into a file or in console"); + PrintAndLogEx(NORMAL, " Usage: mem dump [o ] [l ] [f ] [p]"); PrintAndLogEx(NORMAL, " o : offset in memory"); PrintAndLogEx(NORMAL, " l : length"); PrintAndLogEx(NORMAL, " f : file name"); + PrintAndLogEx(NORMAL, " p : print dump in console"); + PrintAndLogEx(NORMAL, " You must specify at lease option f or option p, both if you wish"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " mem save f myfile"); // download whole flashmem to file myfile - PrintAndLogEx(NORMAL, " mem save f myfile l 4096"); // download 4096 bytes from default offset 0 to file myfile - PrintAndLogEx(NORMAL, " mem save f myfile o 1024 l 4096"); // downlowd 4096 bytes from offset 1024 to file myfile + PrintAndLogEx(NORMAL, " mem dump f myfile"); // download whole flashmem to file myfile + PrintAndLogEx(NORMAL, " mem dump p o 262015 l 128"); // display 128 bytes from offset 262015 (RSA sig) + PrintAndLogEx(NORMAL, " mem dump p f myfile o 241664 l 58"); // download and display 58 bytes from offset 241664 to file myfile return PM3_SUCCESS; } static int usage_flashmem_wipe(void) { @@ -105,46 +96,6 @@ static int usage_flashmem_info(void) { return PM3_SUCCESS; } -static int CmdFlashMemRead(const char *Cmd) { - - uint8_t cmdp = 0; - bool errors = false; - uint32_t start_index = 0, len = 0; - - while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { - switch (tolower(param_getchar(Cmd, cmdp))) { - case 'o': - start_index = param_get32ex(Cmd, cmdp + 1, 0, 10); - cmdp += 2; - break; - case 'l': - len = param_get32ex(Cmd, cmdp + 1, 0, 10); - cmdp += 2; - break; - case 'h': - return usage_flashmem_read(); - default: - PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); - errors = true; - break; - } - } - - //Validations - if (errors || cmdp == 0) { - usage_flashmem_read(); - return PM3_EINVARG; - } - if (start_index + len > FLASH_MEM_MAX_SIZE) { - PrintAndLogDevice(ERR, "error, start_index + length is larger than available memory"); - return PM3_EOVFLOW; - } - - clearCommandBuffer(); - SendCommandMIX(CMD_FLASHMEM_READ, start_index, len, 0, NULL, 0); - return PM3_SUCCESS; -} - static int CmdFlashmemSpiBaudrate(const char *Cmd) { char ctmp = tolower(param_getchar(Cmd, 0)); @@ -311,17 +262,18 @@ static int CmdFlashMemLoad(const char *Cmd) { PrintAndLogEx(SUCCESS, "Wrote "_GREEN_("%u")"bytes to offset "_GREEN_("%u"), datalen, start_index); return PM3_SUCCESS; } -static int CmdFlashMemSave(const char *Cmd) { +static int CmdFlashMemDump(const char *Cmd) { char filename[FILE_PATH_SIZE] = {0}; uint8_t cmdp = 0; bool errors = false; + bool print = false; uint32_t start_index = 0, len = FLASH_MEM_MAX_SIZE; while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { case 'h': - return usage_flashmem_save(); + return usage_flashmem_dump(); case 'l': len = param_get32ex(Cmd, cmdp + 1, FLASH_MEM_MAX_SIZE, 10); cmdp += 2; @@ -330,6 +282,10 @@ static int CmdFlashMemSave(const char *Cmd) { start_index = param_get32ex(Cmd, cmdp + 1, 0, 10); cmdp += 2; break; + case 'p': + print = true; + cmdp += 1; + break; case 'f': //File handling if (param_getstr(Cmd, cmdp + 1, filename, FILE_PATH_SIZE) >= FILE_PATH_SIZE) { @@ -348,7 +304,7 @@ static int CmdFlashMemSave(const char *Cmd) { //Validations if (errors || cmdp == 0) { - usage_flashmem_save(); + usage_flashmem_dump(); return PM3_EINVARG; } @@ -365,8 +321,15 @@ static int CmdFlashMemSave(const char *Cmd) { return PM3_EFLASH; } - saveFile(filename, ".bin", dump, len); - saveFileEML(filename, dump, len, 16); + if (print) { + print_hex_break(dump, len, 32); + } + + if (filename[0] != '\0') { + saveFile(filename, ".bin", dump, len); + saveFileEML(filename, dump, len, 16); + } + free(dump); return PM3_SUCCESS; } @@ -612,10 +575,9 @@ static int CmdFlashMemInfo(const char *Cmd) { static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, {"spibaud", CmdFlashmemSpiBaudrate, IfPm3Flash, "Set Flash memory Spi baudrate [rdv40]"}, - {"read", CmdFlashMemRead, IfPm3Flash, "Read Flash memory [rdv40]"}, {"info", CmdFlashMemInfo, IfPm3Flash, "Flash memory information [rdv40]"}, {"load", CmdFlashMemLoad, IfPm3Flash, "Load data into flash memory [rdv40]"}, - {"save", CmdFlashMemSave, IfPm3Flash, "Save data from flash memory [rdv40]"}, + {"dump", CmdFlashMemDump, IfPm3Flash, "Dump data from flash memory [rdv40]"}, {"wipe", CmdFlashMemWipe, IfPm3Flash, "Wipe data from flash memory [rdv40]"}, {NULL, NULL, NULL, NULL} }; diff --git a/doc/new_frame_format.md b/doc/new_frame_format.md index 76424f8b6..17c94120a 100644 --- a/doc/new_frame_format.md +++ b/doc/new_frame_format.md @@ -373,9 +373,9 @@ It was needed to tune pm3 RX usart `maxtry` : time client/proxmark3 -p /dev/ttyUSB0 -b 115200 -c "lf read" 6.28s - time client/proxmark3 -p /dev/ttyACM0 -c "mem save f foo_usb" + time client/proxmark3 -p /dev/ttyACM0 -c "mem dump f foo_usb" 1.48s - time client/proxmark3 -p /dev/ttyUSB0 -b 115200 -c "mem save f foo_fpc" + time client/proxmark3 -p /dev/ttyUSB0 -b 115200 -c "mem dump f foo_fpc" 25.34s diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 8eef7e75d..e19cbf686 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -238,7 +238,6 @@ typedef struct { #define CMD_SET_DBGMODE 0x0114 // RDV40, Flash memory operations -#define CMD_FLASHMEM_READ 0x0120 #define CMD_FLASHMEM_WRITE 0x0121 #define CMD_FLASHMEM_WIPE 0x0122 #define CMD_FLASHMEM_DOWNLOAD 0x0123 From caceea24a4c61b84eb12b8ff4b0c366113d47aec Mon Sep 17 00:00:00 2001 From: Iceman Date: Mon, 15 Jul 2019 15:36:12 +0200 Subject: [PATCH 0079/1854] Update default_keys.dic --- client/default_keys.dic | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/default_keys.dic b/client/default_keys.dic index 4810e56da..c8d96bd44 100644 --- a/client/default_keys.dic +++ b/client/default_keys.dic @@ -944,3 +944,5 @@ A23456789123 A00003000084 675A32413770 395244733978 +# +B069D0D03D17 From df1dd71d14139e9c0e8fdb578ff17d603bb40c3c Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 15 Jul 2019 17:26:42 +0300 Subject: [PATCH 0080/1854] apdu format and print works --- client/cmdhf14a.c | 20 +++++++++++++------- client/emv/apduinfo.c | 6 +++--- client/emv/apduinfo.h | 4 ++-- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index fb8753921..c7dc037a4 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -859,9 +859,9 @@ static int CmdHF14AAPDU(const char *Cmd) { arg_lit0("kK", "keep", "leave the signal field ON after receive response"), arg_lit0("tT", "tlv", "executes TLV decoder if it possible"), arg_lit0("dD", "decapdu", "decode apdu request if it possible"), - arg_lit0("mM", "make", "", "make apdu with head from this field and data from data field. Must be 4 bytes length: "), + arg_str0("mM", "make", "", "make apdu with head from this field and data from data field. Must be 4 bytes length: "), arg_lit0("eE", "extended", "make extended length apdu if `m` parameter included"), - arg_lit0("lL", "le", "Le apdu parameter if `m` parameter included"), + arg_int0("lL", "le", "", "Le apdu parameter if `m` parameter included"), arg_strx1(NULL, NULL, "", "data if `m` parameter included"), arg_param_end }; @@ -871,9 +871,15 @@ static int CmdHF14AAPDU(const char *Cmd) { leaveSignalON = arg_get_lit(2); decodeTLV = arg_get_lit(3); decodeAPDU = arg_get_lit(4); - makeAPDU = arg_get_lit(5); + + CLIGetHexWithReturn(5, header, &headerlen); + makeAPDU = headerlen > 0; + if (makeAPDU && headerlen != 4) { + PrintAndLogEx(ERR, "header length must be 4 bytes instead of %d", headerlen); + return 1; + } extendedAPDU = arg_get_lit(6); - le = arg_get_lit(7); + le = arg_get_int_def(7, 0); if (makeAPDU) { uint8_t apdudata[PM3_CMD_DATA_SIZE] = {0}; @@ -895,17 +901,17 @@ static int CmdHF14AAPDU(const char *Cmd) { if (APDUEncode(&apdu, data, &datalen)) { PrintAndLogEx(ERR, "can't make apdu with provided parameters."); - return 1; + return 2; } } else { if (extendedAPDU) { PrintAndLogEx(ERR, "make mode not set but here `e` option."); - return 2; + return 3; } if (le > 0) { PrintAndLogEx(ERR, "make mode not set but here `l` option."); - return 2; + return 3; } // len = data + PCB(1b) + CRC(2b) diff --git a/client/emv/apduinfo.c b/client/emv/apduinfo.c index 3b3664e4b..1e6975107 100644 --- a/client/emv/apduinfo.c +++ b/client/emv/apduinfo.c @@ -317,7 +317,7 @@ const char *GetAPDUCodeDescription(uint8_t sw1, uint8_t sw2) { return APDUCodeTable[0].Description; //empty string } -int APDUDecode(uint8_t *data, size_t len, APDUStruct *apdu) { +int APDUDecode(uint8_t *data, int len, APDUStruct *apdu) { ExtAPDUHeader *hapdu = (ExtAPDUHeader *)data; apdu->cla = hapdu->cla; @@ -417,11 +417,11 @@ int APDUDecode(uint8_t *data, size_t len, APDUStruct *apdu) { return 0; } -int APDUEncode(APDUStruct *apdu, uint8_t *data, size_t *len) { +int APDUEncode(APDUStruct *apdu, uint8_t *data, int *len) { if (len) *len = 0; - if (apdu->le > 0x10000 || apdu->lc != 0xffff) + if (apdu->le > 0x10000 || apdu->lc > 0xffff) return 1; size_t dptr = 0; diff --git a/client/emv/apduinfo.h b/client/emv/apduinfo.h index 7f1e8fd72..5d5173e2f 100644 --- a/client/emv/apduinfo.h +++ b/client/emv/apduinfo.h @@ -52,8 +52,8 @@ typedef struct { uint8_t case_type; } __attribute__((packed)) APDUStruct; -extern int APDUDecode(uint8_t *data, size_t len, APDUStruct *apdu); -extern int APDUEncode(APDUStruct *apdu, uint8_t *data, size_t *len); +extern int APDUDecode(uint8_t *data, int len, APDUStruct *apdu); +extern int APDUEncode(APDUStruct *apdu, uint8_t *data, int *len); extern void APDUPrint(APDUStruct apdu); #endif From d2a2acf69ce8a73813161f5d237eeb5d0672d4ea Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 15 Jul 2019 19:12:01 +0300 Subject: [PATCH 0081/1854] make style --- client/cmdhf14a.c | 30 +++++++++++++++--------------- client/emv/apduinfo.c | 10 ++++++++-- client/emv/apduinfo.h | 1 + 3 files changed, 24 insertions(+), 17 deletions(-) diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index c7dc037a4..47586a94a 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -876,15 +876,15 @@ static int CmdHF14AAPDU(const char *Cmd) { makeAPDU = headerlen > 0; if (makeAPDU && headerlen != 4) { PrintAndLogEx(ERR, "header length must be 4 bytes instead of %d", headerlen); - return 1; + return 1; } extendedAPDU = arg_get_lit(6); le = arg_get_int_def(7, 0); - + if (makeAPDU) { uint8_t apdudata[PM3_CMD_DATA_SIZE] = {0}; int apdudatalen = 0; - + CLIGetHexBLessWithReturn(8, apdudata, &apdudatalen, 1 + 2); APDUStruct apdu; @@ -892,28 +892,28 @@ static int CmdHF14AAPDU(const char *Cmd) { apdu.ins = header[1]; apdu.p1 = header[2]; apdu.p2 = header[3]; - + apdu.lc = apdudatalen; apdu.data = apdudata; - + apdu.extended_apdu = extendedAPDU; apdu.le = le; - + if (APDUEncode(&apdu, data, &datalen)) { PrintAndLogEx(ERR, "can't make apdu with provided parameters."); - return 2; + return 2; } - - } else { + + } else { if (extendedAPDU) { PrintAndLogEx(ERR, "make mode not set but here `e` option."); - return 3; + return 3; } if (le > 0) { PrintAndLogEx(ERR, "make mode not set but here `l` option."); - return 3; + return 3; } - + // len = data + PCB(1b) + CRC(2b) CLIGetHexBLessWithReturn(8, data, &datalen, 1 + 2); } @@ -922,12 +922,12 @@ static int CmdHF14AAPDU(const char *Cmd) { PrintAndLogEx(NORMAL, ">>>>[%s%s%s] %s", activateField ? "sel " : "", leaveSignalON ? "keep " : "", decodeTLV ? "TLV" : "", sprint_hex(data, datalen)); if (decodeAPDU) { - APDUStruct apdu; - + APDUStruct apdu; + if (APDUDecode(data, datalen, &apdu) == 0) APDUPrint(apdu); else - PrintAndLogEx(WARNING, "can't decode APDU."); + PrintAndLogEx(WARNING, "can't decode APDU."); } int res = ExchangeAPDU14a(data, datalen, activateField, leaveSignalON, data, PM3_CMD_DATA_SIZE, &datalen); diff --git a/client/emv/apduinfo.c b/client/emv/apduinfo.c index 1e6975107..a7a8e1672 100644 --- a/client/emv/apduinfo.c +++ b/client/emv/apduinfo.c @@ -470,6 +470,12 @@ int APDUEncode(APDUStruct *apdu, uint8_t *data, int *len) { } void APDUPrint(APDUStruct apdu) { - PrintAndLogEx(INFO, "apdu: %scase=%02x cla=%02x ins=%02x p1=%02x p2=%02x Lc=%d Le=%d\n", - apdu.extended_apdu ? "[e]" : "", apdu.case_type, apdu.cla, apdu.ins, apdu.p1, apdu.p2, apdu.lc, apdu.le); + APDUPrintEx(apdu, 0); +} + +void APDUPrintEx(APDUStruct apdu, size_t maxdatalen) { + PrintAndLogEx(INFO, "APDU: %scase=0x%02x cla=0x%02x ins=0x%02x p1=0x%02x p2=0x%02x Lc=0x%02x(%d) Le=0x%02x(%d)", + apdu.extended_apdu ? "[e]" : "", apdu.case_type, apdu.cla, apdu.ins, apdu.p1, apdu.p2, apdu.lc, apdu.lc, apdu.le, apdu.le); + if (maxdatalen > 0) + PrintAndLogEx(INFO, "data: %s%s", sprint_hex(apdu.data, MIN(apdu.lc, maxdatalen)), apdu.lc > maxdatalen ? "..." : ""); } diff --git a/client/emv/apduinfo.h b/client/emv/apduinfo.h index 5d5173e2f..1fbb3bf00 100644 --- a/client/emv/apduinfo.h +++ b/client/emv/apduinfo.h @@ -55,5 +55,6 @@ typedef struct { extern int APDUDecode(uint8_t *data, int len, APDUStruct *apdu); extern int APDUEncode(APDUStruct *apdu, uint8_t *data, int *len); extern void APDUPrint(APDUStruct apdu); +extern void APDUPrintEx(APDUStruct apdu, size_t maxdatalen); #endif From 84c09ce88158bb5850a58103d1d97c490d453fd8 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 15 Jul 2019 19:21:19 +0300 Subject: [PATCH 0082/1854] added define PACKED --- client/emv/apduinfo.c | 2 -- client/emv/apduinfo.h | 6 ++++-- client/util.h | 6 ++++++ 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/client/emv/apduinfo.c b/client/emv/apduinfo.c index a7a8e1672..469078456 100644 --- a/client/emv/apduinfo.c +++ b/client/emv/apduinfo.c @@ -10,8 +10,6 @@ #include "apduinfo.h" -#include "util.h" - const APDUCode APDUCodeTable[] = { // ID Type Description {"XXXX", APDUCODE_TYPE_NONE, ""}, // blank string diff --git a/client/emv/apduinfo.h b/client/emv/apduinfo.h index 1fbb3bf00..b81877366 100644 --- a/client/emv/apduinfo.h +++ b/client/emv/apduinfo.h @@ -17,6 +17,8 @@ #include #include +#include "util.h" + #define APDUCODE_TYPE_NONE 0 #define APDUCODE_TYPE_INFO 1 #define APDUCODE_TYPE_WARNING 2 @@ -38,7 +40,7 @@ typedef struct { uint8_t p1; uint8_t p2; uint8_t lc[3]; -} __attribute__((packed)) ExtAPDUHeader; +} PACKED ExtAPDUHeader; typedef struct { uint8_t cla; @@ -50,7 +52,7 @@ typedef struct { uint32_t le; bool extended_apdu; uint8_t case_type; -} __attribute__((packed)) APDUStruct; +} PACKED APDUStruct; extern int APDUDecode(uint8_t *data, int len, APDUStruct *apdu); extern int APDUEncode(APDUStruct *apdu, uint8_t *data, int *len); diff --git a/client/util.h b/client/util.h index e194bb5be..aade8bf96 100644 --- a/client/util.h +++ b/client/util.h @@ -21,6 +21,12 @@ #include "ui.h" // PrintAndLog #include "commonutil.h" +#ifdef _MSC_VER +#define PACKED +#else +#define PACKED __attribute__((packed)) +#endif + #ifdef ANDROID #include #endif From ecf7eda08f0399d0be4b51b309877b65a510cb17 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 15 Jul 2019 19:25:06 +0300 Subject: [PATCH 0083/1854] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d46c8222b..63e2e76d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Added to `hf 14a apdu` print apdu and compose apdu (@merlokk) - Add check if bootloader segment is within bounds (@slurdge) - Add `hf 15 csetuid` - set UID on ISO-15693 Magic tags (@t0m4-null) - Change: Print help if unknown arg for hitag reader/writer (@ViRb3) From b845404f39206e3ff3a16de2c58565a4bbd5ac51 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 15 Jul 2019 22:28:18 +0200 Subject: [PATCH 0084/1854] Remove misplaced comment --- armsrc/Standalone/lf_icerun.c | 1 - 1 file changed, 1 deletion(-) diff --git a/armsrc/Standalone/lf_icerun.c b/armsrc/Standalone/lf_icerun.c index abc2daa4e..eafd4ca7d 100644 --- a/armsrc/Standalone/lf_icerun.c +++ b/armsrc/Standalone/lf_icerun.c @@ -13,7 +13,6 @@ void ModInfo(void) { DbpString(" LF skeleton mode - aka IceRun (iceman)"); } -// samy's sniff and repeat routine for LF void RunMod() { StandAloneMode(); Dbprintf("[=] LF skeleton code a.k.a IceRun started"); From d8763509deeb33db30bb86fbb4bc7843341097eb Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 15 Jul 2019 22:31:19 +0200 Subject: [PATCH 0085/1854] Add 'hw standalone' to jump to standalone mode from command line or script --- CHANGELOG.md | 3 ++- armsrc/appmain.c | 4 ++++ client/cmdhw.c | 8 ++++++++ include/pm3_cmd.h | 1 + 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eacaa37d1..c78d813db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,8 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] - - Added to `hf 14a apdu` print apdu and compose apdu (@merlokk) + - Add 'hw standalone' to jump to standalone mode from command line or script (@doegox) + - Add to 'hf 14a apdu' print apdu and compose apdu (@merlokk) - Change: buggy 'mem read' removed, 'mem save' renamed 'mem dump', can now display too (@doegox) - Fix: timeout for mem wipe was too short, thanks @cjbrigato (@doegox) - Fix 'hf mf sim' - Mifare Classic simulation more flexible anti-collision check (@McEloff) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index b91853199..8895fd327 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1757,6 +1757,10 @@ static void PacketReceived(PacketCommandNG *packet) { SendStatus(); break; } + case CMD_STANDALONE: { + RunMod(); + break; + } case CMD_CAPABILITIES: { SendCapabilities(); break; diff --git a/client/cmdhw.c b/client/cmdhw.c index 7fb241667..1348f16b4 100644 --- a/client/cmdhw.c +++ b/client/cmdhw.c @@ -479,6 +479,13 @@ static int CmdSetMux(const char *Cmd) { return PM3_SUCCESS; } +static int CmdStandalone(const char *Cmd) { + (void)Cmd; // Cmd is not used so far + clearCommandBuffer(); + SendCommandNG(CMD_STANDALONE, NULL, 0); + return PM3_SUCCESS; +} + static int CmdTune(const char *Cmd) { return CmdTuneSamples(Cmd); } @@ -591,6 +598,7 @@ static command_t CommandTable[] = { {"reset", CmdReset, IfPm3Present, "Reset the Proxmark3"}, {"setlfdivisor", CmdSetDivisor, IfPm3Present, "<19 - 255> -- Drive LF antenna at 12Mhz/(divisor+1)"}, {"setmux", CmdSetMux, IfPm3Present, "Set the ADC mux to a specific value"}, + {"standalone", CmdStandalone, IfPm3Present, "Jump to the standalone mode"}, {"status", CmdStatus, IfPm3Present, "Show runtime status information about the connected Proxmark3"}, {"tune", CmdTune, IfPm3Present, "Measure antenna tuning"}, {"version", CmdVersion, IfPm3Present, "Show version information about the connected Proxmark3"}, diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index e19cbf686..284b072eb 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -236,6 +236,7 @@ typedef struct { #define CMD_CAPABILITIES 0x0112 #define CMD_QUIT_SESSION 0x0113 #define CMD_SET_DBGMODE 0x0114 +#define CMD_STANDALONE 0x0115 // RDV40, Flash memory operations #define CMD_FLASHMEM_WRITE 0x0121 From 20d13d550942664c2d43a39a311d8da44da2713b Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Tue, 16 Jul 2019 14:50:38 +0300 Subject: [PATCH 0086/1854] added PACKED attribute for structures and reorganize include folder --- armsrc/Standalone/hf_young.c | 4 +- armsrc/appmain.c | 1 + armsrc/flashmem.c | 1 + armsrc/lfops.c | 1 + armsrc/mifarecmd.c | 3 + client/cmdflashmem.h | 3 +- client/deprecated-hid-flasher/flasher/elf.h | 6 +- .../deprecated-hid-flasher/flasher/usb_cmd.h | 12 +- client/elf.h | 6 +- client/lualibs/read14a.lua | 2 +- client/lualibs/read14b.lua | 2 +- client/util.h | 90 +------------ include/common.h | 125 ++++++++++-------- include/hitag.h | 6 +- include/mifare.h | 6 +- include/pm3_cmd.h | 13 +- include/pmflash.h | 97 ++++++++++++++ include/proxmark3.h | 9 +- 18 files changed, 204 insertions(+), 183 deletions(-) create mode 100644 include/pmflash.h diff --git a/armsrc/Standalone/hf_young.c b/armsrc/Standalone/hf_young.c index 3ef9e37cf..906d0b36c 100644 --- a/armsrc/Standalone/hf_young.c +++ b/armsrc/Standalone/hf_young.c @@ -8,14 +8,16 @@ //----------------------------------------------------------------------------- // main code for HF standalone mode Mifare /sniff/emulation by Craig Young //----------------------------------------------------------------------------- + #include "hf_young.h" +#include "common.h" typedef struct { uint8_t uid[10]; uint8_t uidlen; uint8_t atqa[2]; uint8_t sak; -} __attribute__((__packed__)) card_clone_t; +} PACKED card_clone_t; void ModInfo(void) { diff --git a/armsrc/appmain.c b/armsrc/appmain.c index b91853199..41453dd40 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -13,6 +13,7 @@ #include #include "usb_cdc.h" #include "proxmark3.h" +#include "pmflash.h" #include "apps.h" #include "fpga.h" #include "util.h" diff --git a/armsrc/flashmem.c b/armsrc/flashmem.c index 4584d41b2..ad4861ce3 100644 --- a/armsrc/flashmem.c +++ b/armsrc/flashmem.c @@ -1,4 +1,5 @@ #include "flashmem.h" +#include "pmflash.h" /* here: use NCPS2 @ PA10: */ #define SPI_CSR_NUM 2 diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 09a1632cb..96fd3ae37 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -19,6 +19,7 @@ #include "protocols.h" #include "usb_cdc.h" // for usb_poll_validate_length #include "common.h" +#include "pmflash.h" #include "flashmem.h" // persistence on mem //#define START_GAP 31*8 // was 250 // SPEC: 1*8 to 50*8 - typ 15*8 (15fc) diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 26b6583fc..2d56a8a37 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -14,8 +14,11 @@ //----------------------------------------------------------------------------- #include "mifarecmd.h" + #include +#include "pmflash.h" + #ifndef HARDNESTED_AUTHENTICATION_TIMEOUT # define HARDNESTED_AUTHENTICATION_TIMEOUT 848 // card times out 1ms after wrong authentication (according to NXP documentation) #endif diff --git a/client/cmdflashmem.h b/client/cmdflashmem.h index 3c37239b7..790d42a5d 100644 --- a/client/cmdflashmem.h +++ b/client/cmdflashmem.h @@ -15,10 +15,11 @@ #include #include #include +#include "pmflash.h" +#include "common.h" #include "proxmark3.h" #include "ui.h" #include "cmdparser.h" -#include "common.h" #include "util.h" #include "util_posix.h" // msclock #include "loclass/fileutils.h" //saveFile diff --git a/client/deprecated-hid-flasher/flasher/elf.h b/client/deprecated-hid-flasher/flasher/elf.h index 0551cbd76..50533224f 100644 --- a/client/deprecated-hid-flasher/flasher/elf.h +++ b/client/deprecated-hid-flasher/flasher/elf.h @@ -9,6 +9,8 @@ #ifndef __ELF_H__ #define __ELF_H__ +#include "common.h" + typedef struct { uint32_t p_type; uint32_t p_offset; @@ -18,7 +20,7 @@ typedef struct { uint32_t p_memsz; uint32_t p_flags; uint32_t p_align; -} __attribute__((__packed__)) Elf32_Phdr; +} PACKED Elf32_Phdr; #define EI_NIDENT 16 @@ -37,7 +39,7 @@ typedef struct { uint16_t e_shentsize; uint16_t e_shnum; uint16_t e_shtrndx; -} __attribute__((__packed__)) Elf32_Ehdr; +} PACKED Elf32_Ehdr; #define PT_NULL 0 #define PT_LOAD 1 diff --git a/client/deprecated-hid-flasher/flasher/usb_cmd.h b/client/deprecated-hid-flasher/flasher/usb_cmd.h index 2b383faf8..95cca0cfc 100644 --- a/client/deprecated-hid-flasher/flasher/usb_cmd.h +++ b/client/deprecated-hid-flasher/flasher/usb_cmd.h @@ -12,16 +12,8 @@ #ifndef __USB_CMD_H #define __USB_CMD_H -#ifdef _MSC_VER -typedef DWORD uint32_t; -typedef BYTE uint8_t; -#define PACKED -// stuff -#else -#include -#include -#define PACKED __attribute__((packed)) -#endif + +#include "common.h" typedef struct { uint32_t cmd; diff --git a/client/elf.h b/client/elf.h index 0551cbd76..50533224f 100644 --- a/client/elf.h +++ b/client/elf.h @@ -9,6 +9,8 @@ #ifndef __ELF_H__ #define __ELF_H__ +#include "common.h" + typedef struct { uint32_t p_type; uint32_t p_offset; @@ -18,7 +20,7 @@ typedef struct { uint32_t p_memsz; uint32_t p_flags; uint32_t p_align; -} __attribute__((__packed__)) Elf32_Phdr; +} PACKED Elf32_Phdr; #define EI_NIDENT 16 @@ -37,7 +39,7 @@ typedef struct { uint16_t e_shentsize; uint16_t e_shnum; uint16_t e_shtrndx; -} __attribute__((__packed__)) Elf32_Ehdr; +} PACKED Elf32_Ehdr; #define PT_NULL 0 #define PT_LOAD 1 diff --git a/client/lualibs/read14a.lua b/client/lualibs/read14a.lua index f68dfff81..3bf243235 100644 --- a/client/lualibs/read14a.lua +++ b/client/lualibs/read14a.lua @@ -60,7 +60,7 @@ local function parse14443a(data) uint8_t sak; uint8_t ats_len; uint8_t ats[256]; - } __attribute__((__packed__)) iso14a_card_select_t; + } PACKED iso14a_card_select_t; --]] local count, uid, uidlen, atqa, sak, ats_len, ats = bin.unpack('H10CH2CCH', data) diff --git a/client/lualibs/read14b.lua b/client/lualibs/read14b.lua index 0be958e25..67d2bd469 100644 --- a/client/lualibs/read14b.lua +++ b/client/lualibs/read14b.lua @@ -39,7 +39,7 @@ local function parse1443b(data) uint8_t atqb[7]; uint8_t chipid; uint8_t cid; - } __attribute__((__packed__)) iso14b_card_select_t; + } PACKED iso14b_card_select_t; --]] diff --git a/client/util.h b/client/util.h index 3d2de1dc7..3f677df7a 100644 --- a/client/util.h +++ b/client/util.h @@ -20,100 +20,12 @@ #include #include "ui.h" // PrintAndLog #include "commonutil.h" - -#ifdef _MSC_VER -#define PACKED -#else -#define PACKED __attribute__((packed)) -#endif +#include "common.h" #ifdef ANDROID #include #endif -#ifndef ROTR -# define ROTR(x,n) (((uintmax_t)(x) >> (n)) | ((uintmax_t)(x) << ((sizeof(x) * 8) - (n)))) -#endif -#ifndef ROTL -# define ROTL(x,n) (((uintmax_t)(x) << (n)) | ((uintmax_t)(x) >> ((sizeof(x) * 8) - (n)))) -#endif - -#ifndef MIN -# define MIN(a, b) (((a) < (b)) ? (a) : (b)) -#endif -#ifndef MAX -# define MAX(a, b) (((a) > (b)) ? (a) : (b)) -#endif - -// endian change for 64bit -#ifdef __GNUC__ -#ifndef BSWAP_64 -#define BSWAP_64(x) __builtin_bswap64(x) -#endif -#else -#ifdef _MSC_VER -#ifndef BSWAP_64 -#define BSWAP_64(x) _byteswap_uint64(x) -#endif -#else -#ifndef BSWAP_64 -#define BSWAP_64(x) \ - (((uint64_t)(x) << 56) | \ - (((uint64_t)(x) << 40) & 0xff000000000000ULL) | \ - (((uint64_t)(x) << 24) & 0xff0000000000ULL) | \ - (((uint64_t)(x) << 8) & 0xff00000000ULL) | \ - (((uint64_t)(x) >> 8) & 0xff000000ULL) | \ - (((uint64_t)(x) >> 24) & 0xff0000ULL) | \ - (((uint64_t)(x) >> 40) & 0xff00ULL) | \ - ((uint64_t)(x) >> 56)) -#endif -#endif -#endif - -// endian change for 32bit -#ifdef __GNUC__ -#ifndef BSWAP_32 -#define BSWAP_32(x) __builtin_bswap32(x) -#endif -#else -#ifdef _MSC_VER -#ifndef BSWAP_32 -#define BSWAP_32(x) _byteswap_ulong(x) -#endif -#else -#ifndef BSWAP_32 -# define BSWAP_32(x) \ - ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \ - (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24)) -#endif -#endif -#endif - -#define EVEN 0 -#define ODD 1 - -// Nibble logic -#ifndef NIBBLE_HIGH -# define NIBBLE_HIGH(b) ( (b & 0xF0) >> 4 ) -#endif -#ifndef NIBBLE_LOW -# define NIBBLE_LOW(b) ( b & 0x0F ) -#endif -#ifndef CRUMB -# define CRUMB(b,p) (((b & (0x3 << p) ) >> p ) & 0xF) -#endif -#ifndef SWAP_NIBBLE -# define SWAP_NIBBLE(b) ( (NIBBLE_LOW(b)<< 4) | NIBBLE_HIGH(b)) -#endif - -// Binary Encoded Digit -#ifndef BCD2DEC -# define BCD2DEC(bcd) HornerScheme(bcd, 0x10, 10) -#endif -#ifndef DEC2BCD -# define DEC2BCD(dec) HornerScheme(dec, 10, 0x10) -#endif - // used for save/load files #ifndef FILE_PATH_SIZE # define FILE_PATH_SIZE 1000 diff --git a/include/common.h b/include/common.h index 3dbf77622..dec2261ec 100644 --- a/include/common.h +++ b/include/common.h @@ -19,9 +19,20 @@ extern "C" { #include #include #include -#include + typedef unsigned char byte_t; +#ifdef _MSC_VER +typedef DWORD uint32_t; +typedef BYTE uint8_t; +#define PACKED +// stuff +#else +#include +#include +#define PACKED __attribute__((packed)) +#endif + // debug #define DBG_NONE 0 // no messages #define DBG_ERROR 1 // errors only @@ -30,9 +41,6 @@ typedef unsigned char byte_t; #define DBG_EXTENDED 4 // errors + info + debug + breaking debug messages extern int DBGLEVEL; -// Flashmem spi baudrate -extern uint32_t FLASHMEM_SPIBAUDRATE; - // reader voltage field detector #define MF_MINFIELDV 4000 @@ -49,74 +57,87 @@ extern uint32_t FLASHMEM_SPIBAUDRATE; #endif #define RAMFUNC __attribute((long_call, section(".ramfunc"))) -// RDV40 Section -// 256kb divided into 4k sectors. -// -// 0x3F000 - 1 4kb sector = signature -// 0x3E000 - 1 4kb sector = settings -// 0x3D000 - 1 4kb sector = default T55XX keys dictionary -// 0x3B000 - 1 4kb sector = default ICLASS keys dictionary -// 0x39000 - 2 4kb sectors = default MFC keys dictionary -// -#ifndef FLASH_MEM_BLOCK_SIZE -# define FLASH_MEM_BLOCK_SIZE 256 +#ifndef ROTR +# define ROTR(x,n) (((uintmax_t)(x) >> (n)) | ((uintmax_t)(x) << ((sizeof(x) * 8) - (n)))) #endif -#ifndef FLASH_MEM_MAX_SIZE -# define FLASH_MEM_MAX_SIZE 0x40000 // (262144) +#ifndef ROTL +# define ROTL(x,n) (((uintmax_t)(x) << (n)) | ((uintmax_t)(x) >> ((sizeof(x) * 8) - (n)))) #endif -#ifndef FLASH_MEM_MAX_4K_SECTOR -# define FLASH_MEM_MAX_4K_SECTOR 0x3F000 +// endian change for 64bit +#ifdef __GNUC__ +#ifndef BSWAP_64 +#define BSWAP_64(x) __builtin_bswap64(x) +#endif +#else +#ifdef _MSC_VER +#ifndef BSWAP_64 +#define BSWAP_64(x) _byteswap_uint64(x) +#endif +#else +#ifndef BSWAP_64 +#define BSWAP_64(x) \ + (((uint64_t)(x) << 56) | \ + (((uint64_t)(x) << 40) & 0xff000000000000ULL) | \ + (((uint64_t)(x) << 24) & 0xff0000000000ULL) | \ + (((uint64_t)(x) << 8) & 0xff00000000ULL) | \ + (((uint64_t)(x) >> 8) & 0xff000000ULL) | \ + (((uint64_t)(x) >> 24) & 0xff0000ULL) | \ + (((uint64_t)(x) >> 40) & 0xff00ULL) | \ + ((uint64_t)(x) >> 56)) +#endif +#endif #endif - -#ifndef FLASH_MEM_ID_LEN -# define FLASH_MEM_ID_LEN 8 +// endian change for 32bit +#ifdef __GNUC__ +#ifndef BSWAP_32 +#define BSWAP_32(x) __builtin_bswap32(x) +#endif +#else +#ifdef _MSC_VER +#ifndef BSWAP_32 +#define BSWAP_32(x) _byteswap_ulong(x) +#endif +#else +#ifndef BSWAP_32 +# define BSWAP_32(x) \ + ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \ + (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24)) +#endif +#endif #endif -#ifndef FLASH_MEM_SIGNATURE_LEN -# define FLASH_MEM_SIGNATURE_LEN 128 +#define EVEN 0 +#define ODD 1 + +// Nibble logic +#ifndef NIBBLE_HIGH +# define NIBBLE_HIGH(b) ( (b & 0xF0) >> 4 ) #endif -#ifndef FLASH_MEM_SIGNATURE_OFFSET -// -1 for historical compatibility with already released Proxmark3 RDV4.0 devices -# define FLASH_MEM_SIGNATURE_OFFSET (FLASH_MEM_MAX_SIZE - FLASH_MEM_SIGNATURE_LEN - 1) +#ifndef NIBBLE_LOW +# define NIBBLE_LOW(b) ( b & 0x0F ) #endif -#ifndef T55XX_CONFIG_LEN -# define T55XX_CONFIG_LEN sizeof( t55xx_config ) +#ifndef CRUMB +# define CRUMB(b,p) (((b & (0x3 << p) ) >> p ) & 0xF) #endif -#ifndef T55XX_CONFIG_OFFSET -# define T55XX_CONFIG_OFFSET (FLASH_MEM_MAX_4K_SECTOR - 0x2000) +#ifndef SWAP_NIBBLE +# define SWAP_NIBBLE(b) ( (NIBBLE_LOW(b)<< 4) | NIBBLE_HIGH(b)) #endif -// Reserved space for T55XX PWD = 4 kb -#ifndef DEFAULT_T55XX_KEYS_OFFSET -# define DEFAULT_T55XX_KEYS_OFFSET (FLASH_MEM_MAX_4K_SECTOR - 0x3000) +// Binary Encoded Digit +#ifndef BCD2DEC +# define BCD2DEC(bcd) HornerScheme(bcd, 0x10, 10) #endif -// Reserved space for iClass keys = 4 kb -#ifndef DEFAULT_ICLASS_KEYS_OFFSET -# define DEFAULT_ICLASS_KEYS_OFFSET (FLASH_MEM_MAX_4K_SECTOR - 0x4000) +#ifndef DEC2BCD +# define DEC2BCD(dec) HornerScheme(dec, 10, 0x10) #endif -// Reserved space for MIFARE Keys = 8 kb -#ifndef DEFAULT_MF_KEYS_OFFSET -# define DEFAULT_MF_KEYS_OFFSET (FLASH_MEM_MAX_4K_SECTOR - 0x6000) -#endif - - - -// RDV40, validation structure to help identifying that client/firmware is talking with RDV40 -typedef struct { - uint8_t magic[4]; - uint8_t flashid[FLASH_MEM_ID_LEN]; - uint8_t signature[FLASH_MEM_SIGNATURE_LEN]; -} __attribute__((__packed__)) rdv40_validation_t; - - #ifdef __cplusplus } #endif diff --git a/include/hitag.h b/include/hitag.h index f57f1180a..9df93fcf7 100644 --- a/include/hitag.h +++ b/include/hitag.h @@ -14,11 +14,7 @@ #ifndef HITAG_H__ #define HITAG_H__ -#ifdef _MSC_VER -#define PACKED -#else -#define PACKED __attribute__((packed)) -#endif +#include "common.h" typedef enum { RHTSF_CHALLENGE = 01, diff --git a/include/mifare.h b/include/mifare.h index 87ba3a74e..9d444e833 100644 --- a/include/mifare.h +++ b/include/mifare.h @@ -46,7 +46,7 @@ typedef struct { uint8_t sak; uint8_t ats_len; uint8_t ats[256]; -} __attribute__((__packed__)) iso14a_card_select_t; +} PACKED iso14a_card_select_t; typedef enum ISO14A_COMMAND { ISO14A_CONNECT = (1 << 0), @@ -129,7 +129,7 @@ typedef struct { typedef struct { uint8_t atr_len; uint8_t atr[30]; -} __attribute__((__packed__)) smart_card_atr_t; +} PACKED smart_card_atr_t; typedef enum SMARTCARD_COMMAND { SC_CONNECT = (1 << 0), @@ -167,7 +167,7 @@ typedef struct { uint8_t iccode[2]; uint8_t mrt[6]; uint8_t servicecode[2]; -} __attribute__((__packed__)) felica_card_select_t; +} PACKED felica_card_select_t; typedef enum FELICA_COMMAND { FELICA_CONNECT = (1 << 0), diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index e19cbf686..8a55a9b88 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -13,20 +13,11 @@ #ifndef __PM3_CMD_H #define __PM3_CMD_H +#include "common.h" + // Use it e.g. when using slow links such as BT #define USART_SLOW_LINK -#ifdef _MSC_VER -typedef DWORD uint32_t; -typedef BYTE uint8_t; -#define PACKED -// stuff -#else -#include -#include -#define PACKED __attribute__((packed)) -#endif - #define PM3_CMD_DATA_SIZE 512 #define PM3_CMD_DATA_SIZE_MIX ( PM3_CMD_DATA_SIZE - 3 * sizeof(uint64_t) ) diff --git a/include/pmflash.h b/include/pmflash.h new file mode 100644 index 000000000..a76b90dae --- /dev/null +++ b/include/pmflash.h @@ -0,0 +1,97 @@ +//----------------------------------------------------------------------------- +// (c) RFID Research Group - 2019 +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +// +//----------------------------------------------------------------------------- +// RDV4 flash constants +//----------------------------------------------------------------------------- + +#ifndef __PMFLASH_H +#define __PMFLASH_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +#include "common.h" + +// Flashmem spi baudrate +extern uint32_t FLASHMEM_SPIBAUDRATE; + +// RDV40 Section +// 256kb divided into 4k sectors. +// +// 0x3F000 - 1 4kb sector = signature +// 0x3E000 - 1 4kb sector = settings +// 0x3D000 - 1 4kb sector = default T55XX keys dictionary +// 0x3B000 - 1 4kb sector = default ICLASS keys dictionary +// 0x39000 - 2 4kb sectors = default MFC keys dictionary +// +#ifndef FLASH_MEM_BLOCK_SIZE +# define FLASH_MEM_BLOCK_SIZE 256 +#endif + +#ifndef FLASH_MEM_MAX_SIZE +# define FLASH_MEM_MAX_SIZE 0x40000 // (262144) +#endif + +#ifndef FLASH_MEM_MAX_4K_SECTOR +# define FLASH_MEM_MAX_4K_SECTOR 0x3F000 +#endif + + +#ifndef FLASH_MEM_ID_LEN +# define FLASH_MEM_ID_LEN 8 +#endif + +#ifndef FLASH_MEM_SIGNATURE_LEN +# define FLASH_MEM_SIGNATURE_LEN 128 +#endif + +#ifndef FLASH_MEM_SIGNATURE_OFFSET +// -1 for historical compatibility with already released Proxmark3 RDV4.0 devices +# define FLASH_MEM_SIGNATURE_OFFSET (FLASH_MEM_MAX_SIZE - FLASH_MEM_SIGNATURE_LEN - 1) +#endif + +#ifndef T55XX_CONFIG_LEN +# define T55XX_CONFIG_LEN sizeof( t55xx_config ) +#endif + +#ifndef T55XX_CONFIG_OFFSET +# define T55XX_CONFIG_OFFSET (FLASH_MEM_MAX_4K_SECTOR - 0x2000) +#endif + +// Reserved space for T55XX PWD = 4 kb +#ifndef DEFAULT_T55XX_KEYS_OFFSET +# define DEFAULT_T55XX_KEYS_OFFSET (FLASH_MEM_MAX_4K_SECTOR - 0x3000) +#endif + +// Reserved space for iClass keys = 4 kb +#ifndef DEFAULT_ICLASS_KEYS_OFFSET +# define DEFAULT_ICLASS_KEYS_OFFSET (FLASH_MEM_MAX_4K_SECTOR - 0x4000) +#endif + +// Reserved space for MIFARE Keys = 8 kb +#ifndef DEFAULT_MF_KEYS_OFFSET +# define DEFAULT_MF_KEYS_OFFSET (FLASH_MEM_MAX_4K_SECTOR - 0x6000) +#endif + +// RDV40, validation structure to help identifying that client/firmware is talking with RDV40 +typedef struct { + uint8_t magic[4]; + uint8_t flashid[FLASH_MEM_ID_LEN]; + uint8_t signature[FLASH_MEM_SIGNATURE_LEN]; +} PACKED rdv40_validation_t; + +#ifdef __cplusplus +} +#endif + +#endif // __PMFLASH_H \ No newline at end of file diff --git a/include/proxmark3.h b/include/proxmark3.h index 8748e82d8..469713b5b 100644 --- a/include/proxmark3.h +++ b/include/proxmark3.h @@ -15,6 +15,7 @@ #include "at91sam7s512.h" #include "config_gpio.h" #include "pm3_cmd.h" +#include "common.h" #define WDT_HIT() AT91C_BASE_WDTC->WDTC_WDCR = 0xa5000001 @@ -71,8 +72,6 @@ #define COTAG_BITS 264 #endif -//#define PACKED __attribute__((__packed__)) - #define LED_A_ON() HIGH(GPIO_LED_A) #define LED_A_OFF() LOW(GPIO_LED_A) #define LED_A_INV() INVBIT(GPIO_LED_A) @@ -116,7 +115,7 @@ struct version_information { char clean; /* 1: Tree was clean, no local changes. 0: Tree was unclean. 2: Couldn't be determined */ char gitversion[50]; /* String with the git revision */ char buildtime[30]; /* string with the build time */ -} __attribute__((packed)); +} PACKED; #define COMMON_AREA_MAGIC 0x43334d50 // "PM3C" #define COMMON_AREA_COMMAND_NONE 0 @@ -129,8 +128,8 @@ struct common_area { unsigned int bootrom_present: 1; /* Set when a bootrom that is capable of parsing the common area is present */ unsigned int osimage_present: 1; /* Set when a osimage that is capable of parsing the common area is present */ unsigned int button_pressed: 1; - } __attribute__((packed)) flags; + } PACKED flags; int arg1, arg2; -} __attribute__((packed)); +} PACKED; #endif From 12c6b5cb20b12aacb52a136dce3a51193735793b Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Tue, 16 Jul 2019 15:25:48 +0300 Subject: [PATCH 0087/1854] add the definition of PACKED in its client/deprecated-hid-flasher/flasher/proxmark3.h --- client/deprecated-hid-flasher/flasher/elf.h | 2 +- client/deprecated-hid-flasher/flasher/proxmark3.h | 12 ++++++++++++ client/deprecated-hid-flasher/flasher/usb_cmd.h | 2 +- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/client/deprecated-hid-flasher/flasher/elf.h b/client/deprecated-hid-flasher/flasher/elf.h index 50533224f..eef2863d8 100644 --- a/client/deprecated-hid-flasher/flasher/elf.h +++ b/client/deprecated-hid-flasher/flasher/elf.h @@ -9,7 +9,7 @@ #ifndef __ELF_H__ #define __ELF_H__ -#include "common.h" +#include "proxmark3.h" typedef struct { uint32_t p_type; diff --git a/client/deprecated-hid-flasher/flasher/proxmark3.h b/client/deprecated-hid-flasher/flasher/proxmark3.h index f5dd2b7fa..c9e42efd8 100644 --- a/client/deprecated-hid-flasher/flasher/proxmark3.h +++ b/client/deprecated-hid-flasher/flasher/proxmark3.h @@ -14,4 +14,16 @@ #define PROXPROMPT "proxmark3> " +#ifdef _MSC_VER +typedef DWORD uint32_t; +typedef BYTE uint8_t; +#define PACKED +// stuff +#else +#include +#include +#define PACKED __attribute__((packed)) +#endif + + #endif diff --git a/client/deprecated-hid-flasher/flasher/usb_cmd.h b/client/deprecated-hid-flasher/flasher/usb_cmd.h index 95cca0cfc..60c359e5a 100644 --- a/client/deprecated-hid-flasher/flasher/usb_cmd.h +++ b/client/deprecated-hid-flasher/flasher/usb_cmd.h @@ -13,7 +13,7 @@ #ifndef __USB_CMD_H #define __USB_CMD_H -#include "common.h" +#include "proxmark3.h" typedef struct { uint32_t cmd; From 7726ec60006f29a58ee287ed0e1cc33615ab38b8 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Tue, 16 Jul 2019 16:05:47 +0300 Subject: [PATCH 0088/1854] move sAPDU --- client/emv/apduinfo.h | 9 +++++++++ client/emv/emvcore.h | 9 --------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/client/emv/apduinfo.h b/client/emv/apduinfo.h index b81877366..b2d323e5b 100644 --- a/client/emv/apduinfo.h +++ b/client/emv/apduinfo.h @@ -34,6 +34,15 @@ typedef struct { const APDUCode *GetAPDUCode(uint8_t sw1, uint8_t sw2); const char *GetAPDUCodeDescription(uint8_t sw1, uint8_t sw2); +typedef struct { + uint8_t CLA; + uint8_t INS; + uint8_t P1; + uint8_t P2; + uint8_t Lc; + uint8_t *data; +} PACKED sAPDU; + typedef struct { uint8_t cla; uint8_t ins; diff --git a/client/emv/emvcore.h b/client/emv/emvcore.h index 219c3f9b5..3faae283d 100644 --- a/client/emv/emvcore.h +++ b/client/emv/emvcore.h @@ -45,15 +45,6 @@ enum TransactionType { }; extern const char *TransactionTypeStr[]; -typedef struct { - uint8_t CLA; - uint8_t INS; - uint8_t P1; - uint8_t P2; - uint8_t Lc; - uint8_t *data; -} sAPDU; - enum CardPSVendor { CV_NA, CV_VISA, From bd8824a2f308a597690c91f47efb279801534870 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Tue, 16 Jul 2019 16:10:11 +0300 Subject: [PATCH 0089/1854] make style --- armsrc/Standalone/hf_colin.c | 6 +++--- client/scripts/read_pwd_mem.lua | 4 ++-- include/pmflash.h | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/armsrc/Standalone/hf_colin.c b/armsrc/Standalone/hf_colin.c index 060c4af06..d74eaeb95 100644 --- a/armsrc/Standalone/hf_colin.c +++ b/armsrc/Standalone/hf_colin.c @@ -792,13 +792,13 @@ readysim: flags = FLAG_4B_UID_IN_DATA; break; default: - flags = FLAG_UID_IN_EMUL; - break; + flags = FLAG_UID_IN_EMUL; + break; } // Use UID, SAK, ATQA from EMUL, if uid not defined //if ((flags & (FLAG_4B_UID_IN_DATA | FLAG_7B_UID_IN_DATA | FLAG_10B_UID_IN_DATA)) == 0) { - flags |= FLAG_UID_IN_EMUL; + flags |= FLAG_UID_IN_EMUL; //} Mifare1ksim(flags | FLAG_MF_1K, 0, cjuid); LED_C_OFF(); diff --git a/client/scripts/read_pwd_mem.lua b/client/scripts/read_pwd_mem.lua index 7dbfa6fba..5f8edcc74 100644 --- a/client/scripts/read_pwd_mem.lua +++ b/client/scripts/read_pwd_mem.lua @@ -81,8 +81,8 @@ local function main(args) if o == 'o' then offset = tonumber(a) end -- num of bytes to read - if o == 'l' then - length = tonumber(a) + if o == 'l' then + length = tonumber(a) if length < 0 or length > 256 then return oops('Error: Length is not valid. Must be less than 256') end diff --git a/include/pmflash.h b/include/pmflash.h index a76b90dae..b7bf39ddc 100644 --- a/include/pmflash.h +++ b/include/pmflash.h @@ -94,4 +94,4 @@ typedef struct { } #endif -#endif // __PMFLASH_H \ No newline at end of file +#endif // __PMFLASH_H From a30c62137b53be28370112cb35ab3ed916bc57c5 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Tue, 16 Jul 2019 17:04:54 +0300 Subject: [PATCH 0090/1854] use apduencode for emv commands --- client/emv/apduinfo.c | 24 ++++++++++++++++++++++++ client/emv/apduinfo.h | 1 + client/emv/emvcore.c | 26 ++++++++++++-------------- 3 files changed, 37 insertions(+), 14 deletions(-) diff --git a/client/emv/apduinfo.c b/client/emv/apduinfo.c index 469078456..2449391b7 100644 --- a/client/emv/apduinfo.c +++ b/client/emv/apduinfo.c @@ -467,6 +467,30 @@ int APDUEncode(APDUStruct *apdu, uint8_t *data, int *len) { return 0; } +int APDUEncodeS(sAPDU *sapdu, bool extended, uint16_t le, uint8_t *data, int *len) { + if (extended && le > 0x100) + return 10; + + APDUStruct apdu; + + apdu.cla = sapdu->CLA; + apdu.ins = sapdu->INS; + apdu.p1 = sapdu->P1; + apdu.p2 = sapdu->P2; + + apdu.lc = sapdu->Lc; + if (sapdu->Lc) + apdu.data = sapdu->data; + else + apdu.data = NULL; + apdu.le = le; + + apdu.extended_apdu = extended; + apdu.case_type = 0x00; + + return APDUEncode(&apdu, data, len); +} + void APDUPrint(APDUStruct apdu) { APDUPrintEx(apdu, 0); } diff --git a/client/emv/apduinfo.h b/client/emv/apduinfo.h index b2d323e5b..25d062dcf 100644 --- a/client/emv/apduinfo.h +++ b/client/emv/apduinfo.h @@ -65,6 +65,7 @@ typedef struct { extern int APDUDecode(uint8_t *data, int len, APDUStruct *apdu); extern int APDUEncode(APDUStruct *apdu, uint8_t *data, int *len); +extern int APDUEncodeS(sAPDU *apdu, bool extended, uint16_t le, uint8_t *data, int *len); extern void APDUPrint(APDUStruct apdu); extern void APDUPrintEx(APDUStruct apdu, size_t maxdatalen); diff --git a/client/emv/emvcore.c b/client/emv/emvcore.c index 2d96b567a..e7c2690b7 100644 --- a/client/emv/emvcore.c +++ b/client/emv/emvcore.c @@ -277,24 +277,22 @@ static int EMVExchangeEx(EMVCommandChannel channel, bool ActivateField, bool Lea } // COMPUTE APDU - memcpy(data, &apdu, 5); - if (apdu.data) - memcpy(&data[5], apdu.data, apdu.Lc); + int datalen = 0; + APDUEncodeS(&apdu, false, IncludeLe ? 0x100 : 0x00, data, &datalen); if (APDULogging) - PrintAndLogEx(SUCCESS, ">>>> %s", sprint_hex(data, (IncludeLe ? 6 : 5) + apdu.Lc)); + PrintAndLogEx(SUCCESS, ">>>> %s", sprint_hex(data, datalen)); switch (channel) { case ECC_CONTACTLESS: - // 6 byes + data = INS + CLA + P1 + P2 + Lc + + Le(?IncludeLe) - res = ExchangeAPDU14a(data, (IncludeLe ? 6 : 5) + apdu.Lc, ActivateField, LeaveFieldON, Result, (int)MaxResultLen, (int *)ResultLen); + res = ExchangeAPDU14a(data, datalen, ActivateField, LeaveFieldON, Result, (int)MaxResultLen, (int *)ResultLen); if (res) { return res; } break; case ECC_CONTACT: if (IfPm3Smartcard()) - res = ExchangeAPDUSC(data, (IncludeLe ? 6 : 5) + apdu.Lc, ActivateField, LeaveFieldON, Result, (int)MaxResultLen, (int *)ResultLen); + res = ExchangeAPDUSC(data, datalen, ActivateField, LeaveFieldON, Result, (int)MaxResultLen, (int *)ResultLen); else res = 1; if (res) { @@ -336,7 +334,7 @@ static int EMVExchangeEx(EMVCommandChannel channel, bool ActivateField, bool Lea } int EMVExchange(EMVCommandChannel channel, bool LeaveFieldON, sAPDU apdu, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw, struct tlvdb *tlv) { - return EMVExchangeEx(channel, false, LeaveFieldON, apdu, (channel == ECC_CONTACTLESS), Result, MaxResultLen, ResultLen, sw, tlv); + return EMVExchangeEx(channel, false, LeaveFieldON, apdu, false, Result, MaxResultLen, ResultLen, sw, tlv); } int EMVSelect(EMVCommandChannel channel, bool ActivateField, bool LeaveFieldON, uint8_t *AID, size_t AIDLen, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw, struct tlvdb *tlv) { @@ -609,9 +607,9 @@ int EMVGPO(EMVCommandChannel channel, bool LeaveFieldON, uint8_t *PDOL, size_t P } int EMVReadRecord(EMVCommandChannel channel, bool LeaveFieldON, uint8_t SFI, uint8_t SFIrec, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw, struct tlvdb *tlv) { - int res = EMVExchange(channel, LeaveFieldON, (sAPDU) {0x00, 0xb2, SFIrec, (SFI << 3) | 0x04, 0, NULL}, Result, MaxResultLen, ResultLen, sw, tlv); - if (*sw == 0x6700) { - PrintAndLogEx(INFO, ">>> trying to reissue command withouth Le..."); + int res = EMVExchangeEx(channel, false, LeaveFieldON, (sAPDU) {0x00, 0xb2, SFIrec, (SFI << 3) | 0x04, 0, NULL}, true, Result, MaxResultLen, ResultLen, sw, tlv); + if (*sw == 0x6700 || *sw == 0x6f00) { + PrintAndLogEx(INFO, ">>> trying to reissue command without Le..."); res = EMVExchangeEx(channel, false, LeaveFieldON, (sAPDU) {0x00, 0xb2, SFIrec, (SFI << 3) | 0x04, 0, NULL}, false, Result, MaxResultLen, ResultLen, sw, tlv); } return res; @@ -622,9 +620,9 @@ int EMVAC(EMVCommandChannel channel, bool LeaveFieldON, uint8_t RefControl, uint } int EMVGenerateChallenge(EMVCommandChannel channel, bool LeaveFieldON, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw, struct tlvdb *tlv) { - int res = EMVExchange(channel, LeaveFieldON, (sAPDU) {0x00, 0x84, 0x00, 0x00, 0x00, NULL}, Result, MaxResultLen, ResultLen, sw, tlv); - if (*sw == 0x6700) { - PrintAndLogEx(INFO, ">>> trying to reissue command withouth Le..."); + int res = EMVExchangeEx(channel, false, LeaveFieldON, (sAPDU) {0x00, 0x84, 0x00, 0x00, 0x00, NULL}, true, Result, MaxResultLen, ResultLen, sw, tlv); + if (*sw == 0x6700 || *sw == 0x6f00) { + PrintAndLogEx(INFO, ">>> trying to reissue command without Le..."); res = EMVExchangeEx(channel, false, LeaveFieldON, (sAPDU) {0x00, 0x84, 0x00, 0x00, 0x00, NULL}, false, Result, MaxResultLen, ResultLen, sw, tlv); } return res; From e61a65fbe87c4f232ca4cc48472539d5c3dbfd6c Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Tue, 16 Jul 2019 17:15:32 +0300 Subject: [PATCH 0091/1854] check PPSE instead of PSE and vice versa. I have one card with this strange behavior... --- client/emv/cmdemv.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c index 0b50ecfe1..5ac9adb00 100644 --- a/client/emv/cmdemv.c +++ b/client/emv/cmdemv.c @@ -829,6 +829,12 @@ static int CmdEMVExec(const char *Cmd) { PrintAndLogEx(NORMAL, "\n* PPSE."); SetAPDULogging(showAPDU); res = EMVSearchPSE(channel, activateField, true, psenum, decodeTLV, tlvSelect); + + // check PPSE instead of PSE and vice versa + if (res) { + PrintAndLogEx(NORMAL, "Check PPSE instead of PSE and vice versa..."); + res = EMVSearchPSE(channel, false, true, psenum == 1 ? 2 : 1, decodeTLV, tlvSelect); + } // check PPSE and select application id if (!res) { From 5fd2a7613fa476b32e96d6daa276801de4203578 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Tue, 16 Jul 2019 18:05:23 +0300 Subject: [PATCH 0092/1854] add check --- client/emv/emvcore.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/client/emv/emvcore.c b/client/emv/emvcore.c index e7c2690b7..fd70ca871 100644 --- a/client/emv/emvcore.c +++ b/client/emv/emvcore.c @@ -278,7 +278,10 @@ static int EMVExchangeEx(EMVCommandChannel channel, bool ActivateField, bool Lea // COMPUTE APDU int datalen = 0; - APDUEncodeS(&apdu, false, IncludeLe ? 0x100 : 0x00, data, &datalen); + if (APDUEncodeS(&apdu, false, IncludeLe ? 0x100 : 0x00, data, &datalen)) { + PrintAndLogEx(ERR, "APDU encoding error."); + return 201; + } if (APDULogging) PrintAndLogEx(SUCCESS, ">>>> %s", sprint_hex(data, datalen)); From 638d6984456a7c9c9dbafd0a3dc53df5f4b0a188 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Tue, 16 Jul 2019 18:05:36 +0300 Subject: [PATCH 0093/1854] make style --- client/emv/apduinfo.c | 6 +++--- client/emv/cmdemv.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/client/emv/apduinfo.c b/client/emv/apduinfo.c index 2449391b7..48e97622b 100644 --- a/client/emv/apduinfo.c +++ b/client/emv/apduinfo.c @@ -472,7 +472,7 @@ int APDUEncodeS(sAPDU *sapdu, bool extended, uint16_t le, uint8_t *data, int *le return 10; APDUStruct apdu; - + apdu.cla = sapdu->CLA; apdu.ins = sapdu->INS; apdu.p1 = sapdu->P1; @@ -484,10 +484,10 @@ int APDUEncodeS(sAPDU *sapdu, bool extended, uint16_t le, uint8_t *data, int *le else apdu.data = NULL; apdu.le = le; - + apdu.extended_apdu = extended; apdu.case_type = 0x00; - + return APDUEncode(&apdu, data, len); } diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c index 5ac9adb00..0cf177620 100644 --- a/client/emv/cmdemv.c +++ b/client/emv/cmdemv.c @@ -829,7 +829,7 @@ static int CmdEMVExec(const char *Cmd) { PrintAndLogEx(NORMAL, "\n* PPSE."); SetAPDULogging(showAPDU); res = EMVSearchPSE(channel, activateField, true, psenum, decodeTLV, tlvSelect); - + // check PPSE instead of PSE and vice versa if (res) { PrintAndLogEx(NORMAL, "Check PPSE instead of PSE and vice versa..."); From 710b38f20903d200a7be3618a65ffceeeab8555e Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 16 Jul 2019 19:18:45 +0200 Subject: [PATCH 0094/1854] Move Makefile standalone stuff to armsrc/Standalone for easier access --- armsrc/Makefile | 36 +-------------- armsrc/Standalone/Makefile.hal | 46 +++++++++++++++++++ armsrc/Standalone/Makefile.inc | 36 +++++++++++++++ armsrc/Standalone/readme.md | 14 +++--- common/Makefile.hal | 80 ++++++++++++---------------------- 5 files changed, 118 insertions(+), 94 deletions(-) create mode 100644 armsrc/Standalone/Makefile.hal create mode 100644 armsrc/Standalone/Makefile.inc diff --git a/armsrc/Makefile b/armsrc/Makefile index 7fee5c79b..6d3921084 100644 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@ -68,41 +68,7 @@ else endif # Generic standalone Mode injection of source code - - -SRC_STANDALONE = placeholder.c -# WITH_STANDALONE_LF_ICERUN -ifneq (,$(findstring WITH_STANDALONE_LF_ICERUN,$(APP_CFLAGS))) - SRC_STANDALONE = lf_icerun.c -endif -# WITH_STANDALONE_LF_SAMYRUN -ifneq (,$(findstring WITH_STANDALONE_LF_SAMYRUN,$(APP_CFLAGS))) - SRC_STANDALONE = lf_samyrun.c -endif -# WITH_STANDALONE_LF_PROXBRUTE -ifneq (,$(findstring WITH_STANDALONE_LF_PROXBRUTE,$(APP_CFLAGS))) - SRC_STANDALONE = lf_proxbrute.c -endif -# WITH_STANDALONE_LF_HIDBRUTE -ifneq (,$(findstring WITH_STANDALONE_LF_HIDBRUTE,$(APP_CFLAGS))) - SRC_STANDALONE = lf_hidbrute.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 -endif -# WITH_STANDALONE_HF_BOG -ifneq (,$(findstring WITH_STANDALONE_HF_BOG,$(APP_CFLAGS))) - SRC_STANDALONE = hf_bog.c -endif +include Standalone/Makefile.inc #the FPGA bitstream files. Note: order matters! FPGA_BITSTREAMS = fpga_lf.bit fpga_hf.bit diff --git a/armsrc/Standalone/Makefile.hal b/armsrc/Standalone/Makefile.hal new file mode 100644 index 000000000..6181b5072 --- /dev/null +++ b/armsrc/Standalone/Makefile.hal @@ -0,0 +1,46 @@ +# Default standalone if no standalone specified +DEFAULT_STANDALONE=LF_SAMYRUN +HELP_EXAMPLE_STANDALONE=HF_COLIN +# (you can set explicitly STANDALONE= to disable standalone modes) +STANDALONE?=$(DEFAULT_STANDALONE) + +define KNOWN_STANDALONE_DEFINITIONS ++==========================================================+ +| STANDALONE | DESCRIPTION | ++==========================================================+ +| | No standalone mode | ++----------------------------------------------------------+ +| LF_SAMYRUN (def)| HID26 read/clone/sim | +| | - Samy Kamkar | ++----------------------------------------------------------+ +| LF_ICERUN | standalone mode skeleton | +| | - iceman | ++----------------------------------------------------------+ +| LF_PROXBRUTE | HID ProxII bruteforce | +| | - Brad Antoniewicz | ++----------------------------------------------------------+ +| LF_HIDBRUTE | HID corporate 1000 bruteforce | +| | - Federico dotta & Maurizio Agazzini | ++----------------------------------------------------------+ +| HF_YOUNG | Mifare sniff/simulation | +| | - Craig Young | ++----------------------------------------------------------+ +| HF_MATTYRUN | Mifare sniff/clone | +| | - Matías A. Ré Medina | ++----------------------------------------------------------+ +| HF_COLIN | Mifare ultra fast sniff/sim/clone | +| | - Colin Brigato | ++----------------------------------------------------------+ +| HF_BOG | 14a sniff with ULC/ULEV1/NTAG auth | +| | storing in flashmem - Bogito | ++----------------------------------------------------------+ + +endef + +STANDALONE_MODES := LF_SAMYRUN LF_ICERUN LF_PROXBRUTE LF_HIDBRUTE +STANDALONE_MODES += HF_YOUNG HF_MATTYRUN HF_COLIN HF_BOG +ifneq ($(filter $(STANDALONE),$(STANDALONE_MODES)),) + STANDALONE_PLATFORM_DEFS += -DWITH_STANDALONE_$(STANDALONE) +else ifneq ($(STANDALONE),) + $(error Invalid STANDALONE: $(STANDALONE). $(KNOWN_DEFINITIONS)) +endif diff --git a/armsrc/Standalone/Makefile.inc b/armsrc/Standalone/Makefile.inc new file mode 100644 index 000000000..cc7221a73 --- /dev/null +++ b/armsrc/Standalone/Makefile.inc @@ -0,0 +1,36 @@ +# Generic standalone Mode injection of source code + +SRC_STANDALONE = placeholder.c +# WITH_STANDALONE_LF_ICERUN +ifneq (,$(findstring WITH_STANDALONE_LF_ICERUN,$(APP_CFLAGS))) + SRC_STANDALONE = lf_icerun.c +endif +# WITH_STANDALONE_LF_SAMYRUN +ifneq (,$(findstring WITH_STANDALONE_LF_SAMYRUN,$(APP_CFLAGS))) + SRC_STANDALONE = lf_samyrun.c +endif +# WITH_STANDALONE_LF_PROXBRUTE +ifneq (,$(findstring WITH_STANDALONE_LF_PROXBRUTE,$(APP_CFLAGS))) + SRC_STANDALONE = lf_proxbrute.c +endif +# WITH_STANDALONE_LF_HIDBRUTE +ifneq (,$(findstring WITH_STANDALONE_LF_HIDBRUTE,$(APP_CFLAGS))) + SRC_STANDALONE = lf_hidbrute.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 +endif +# WITH_STANDALONE_HF_BOG +ifneq (,$(findstring WITH_STANDALONE_HF_BOG,$(APP_CFLAGS))) + SRC_STANDALONE = hf_bog.c +endif + diff --git a/armsrc/Standalone/readme.md b/armsrc/Standalone/readme.md index 8d2420def..4ff83b9fd 100644 --- a/armsrc/Standalone/readme.md +++ b/armsrc/Standalone/readme.md @@ -1,6 +1,6 @@ # Standalone Modes -This contains functionality for different StandAlone modes. The fullimage will be built given the correct compiler flags used. Build targets for these files are contained in `armsrc/Makefile` and `common/Makefile.hal` +This contains functionality for different StandAlone modes. The fullimage will be built given the correct compiler flags used. Build targets for these files are contained in `Makefile.inc` and `Makefile.hal` If you want to implement a new standalone mode, you need to implement the methods provided in `standalone.h`. Have a look at the skeleton standalone mode called IceRun, in the files `lf_icerun.c lf_icerun.h`. @@ -40,8 +40,6 @@ void RunMod(void) { } ```` -Each standalone mode needs to have its own compiler flag to be added in `armsrc/Makefile`. - ## Naming your standalone mode We suggest that you follow these guidelines: @@ -58,9 +56,9 @@ This leads to your next step, your DEFINE name needed in Makefile. `WITH_STANDALONE_LF_FOO` -## Update COMMON/MAKEFILE.HAL +## Update MAKEFILE.HAL -Add your mode to the `common/Makefile.hal` help and modes list: +Add your mode to the `Makefile.hal` help and modes list: ``` +==========================================================+ | STANDALONE | DESCRIPTION | @@ -74,8 +72,8 @@ STANDALONE_MODES := LF_SAMYRUN LF_ICERUN LF_PROXBRUTE LF_HIDBRUTE LF_FOO STANDALONE_MODES += HF_YOUNG HF_MATTYRUN HF_COLIN HF_BOG ``` -## Update ARMSRC/MAKEFILE -Add your source code files like the following sample in the `armsrc/Makefile` +## Update MAKEFILE.INC +Add your source code files like the following sample in the `Makefile.inc` ``` # WITH_STANDALONE_LF_ICERUN @@ -100,7 +98,7 @@ void ModInfo(void) { ```` ## Compiling your standalone mode -Once all this is done, you and others can now easily compile different standalone modes by just selecting one of the standalone modes (list in `common/Makefile.hal` or ) , e.g.: +Once all this is done, you and others can now easily compile different standalone modes by just selecting one of the standalone modes (list in `Makefile.hal` or ) , e.g.: - rename Makefile.platform.sample -> Makefile.platform - edit the "STANDALONE" row inside Makefile.platform. You need to uncomment it and add your standalone mode name diff --git a/common/Makefile.hal b/common/Makefile.hal index ff3f83a4c..bf9231f5c 100644 --- a/common/Makefile.hal +++ b/common/Makefile.hal @@ -1,10 +1,14 @@ # Default platform if no platform specified PLATFORM?=PM3RDV4 -# Default standalone if no standalone specified -# (you can set explicitly STANDALONE= to disable standalone modes) -STANDALONE?=LF_SAMYRUN -define KNOWN_DEFINITIONS +# Standalone Mode info (path depends if make is called at top or from armsrc) +-include armsrc/Standalone/Makefile.hal +-include Standalone/Makefile.hal +ifndef DEFAULT_STANDALONE +$(error Could not find armsrc/Standalone/Makefile.hal) +endif + +define KNOWN_PLATFORM_DEFINITIONS Known definitions: @@ -30,39 +34,12 @@ Known definitions: | BTADDON | Proxmark3 rdv4 BT add-on | +----------------------------------------------------------+ -+==========================================================+ -| STANDALONE | DESCRIPTION | -+==========================================================+ -| | No standalone mode | -+----------------------------------------------------------+ -| LF_SAMYRUN (def)| HID26 read/clone/sim | -| | - Samy Kamkar | -+----------------------------------------------------------+ -| LF_ICERUN | standalone mode skeleton | -| | - iceman | -+----------------------------------------------------------+ -| LF_PROXBRUTE | HID ProxII bruteforce | -| | - Brad Antoniewicz | -+----------------------------------------------------------+ -| LF_HIDBRUTE | HID corporate 1000 bruteforce | -| | - Federico dotta & Maurizio Agazzini | -+----------------------------------------------------------+ -| HF_YOUNG | Mifare sniff/simulation | -| | - Craig Young | -+----------------------------------------------------------+ -| HF_MATTYRUN | Mifare sniff/clone | -| | - Matías A. Ré Medina | -+----------------------------------------------------------+ -| HF_COLIN | Mifare ultra fast sniff/sim/clone | -| | - Colin Brigato | -+----------------------------------------------------------+ -| HF_BOG | 14a sniff with ULC/ULEV1/NTAG auth | -| | storing in flashmem - Bogito | -+----------------------------------------------------------+ +endef +define HELP_DEFINITIONS Options to define platform, platform extras and/or standalone mode: (1) Run make with PLATFORM, PLATFORM_EXTRAS and/or STANDALONE as follows: -make PLATFORM=PM3EASY STANDALONE=HF_COLIN +make PLATFORM=PM3EASY STANDALONE=$(HELP_EXAMPLE_STANDALONE) (2) Save a file called Makefile.platform with contents: PLATFORM=PM3EASY @@ -71,11 +48,17 @@ or if you have a Proxmark 3 RDV4 with the BT add-on: PLATFORM=PM3RDV4 PLATFORM_EXTRAS=BTADDON -Default standalone mode is LF_SAMYRUN. +Default standalone mode is $(DEFAULT_STANDALONE). To disable standalone modes, set explicitly an empty STANDALONE: STANDALONE= endef +define KNOWN_DEFINITIONS +$(KNOWN_PLATFORM_DEFINITIONS) +$(KNOWN_STANDALONE_DEFINITIONS) +$(HELP_DEFINITIONS) +endef + PLTNAME = Unknown Platform ifeq ($(PLATFORM),PM3RDV4) @@ -131,13 +114,7 @@ PLATFORM_DEFS += \ -DWITH_HFSNIFF # Standalone mode -STANDALONE_MODES := LF_SAMYRUN LF_ICERUN LF_PROXBRUTE LF_HIDBRUTE -STANDALONE_MODES += HF_YOUNG HF_MATTYRUN HF_COLIN HF_BOG -ifneq ($(filter $(STANDALONE),$(STANDALONE_MODES)),) - PLATFORM_DEFS += -DWITH_STANDALONE_$(STANDALONE) -else ifneq ($(STANDALONE),) - $(error Invalid STANDALONE: $(STANDALONE). $(KNOWN_DEFINITIONS)) -endif +PLATFORM_DEFS+=$(STANDALONE_PLATFORM_DEFS) $(info $(findstring WITH_STANDALONE_*,$(PLATFORM_DEFS))) @@ -171,15 +148,6 @@ ifeq (,$(PLATFORM_DEFS_INFO_STANDALONE)) PLATFORM_DEFS_INFO_STANDALONE = No standalone mode selected endif -export PLATFORM -export PLATFORM_EXTRAS -export PLATFORM_EXTRAS_INFO -export PLTNAME -export MCU -export PLATFORM_DEFS -export PLATFORM_DEFS_INFO -export PLATFORM_DEFS_INFO_STANDALONE - PLATFORM_CHANGED=false ifneq ($(PLATFORM), $(CACHED_PLATFORM)) PLATFORM_CHANGED=true @@ -189,6 +157,16 @@ else ifneq ($(PLATFORM_DEFS), $(CACHED_PLATFORM_DEFS)) PLATFORM_CHANGED=true endif +export PLATFORM +export PLATFORM_EXTRAS +export PLATFORM_EXTRAS_INFO +export PLTNAME +export MCU +export PLATFORM_DEFS +export PLATFORM_DEFS_INFO +export PLATFORM_DEFS_INFO_STANDALONE +export PLATFORM_CHANGED + $(info ===================================================================) $(info Platform name: $(PLTNAME)) $(info PLATFORM: $(PLATFORM)) From 48279e85d9b0abbc8d97c769372350e3933e1101 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 16 Jul 2019 19:31:59 +0200 Subject: [PATCH 0095/1854] Fix hf_colin standalone broken by recent include files reorganization --- armsrc/Standalone/hf_colin.h | 1 + 1 file changed, 1 insertion(+) diff --git a/armsrc/Standalone/hf_colin.h b/armsrc/Standalone/hf_colin.h index 8c8e391e1..9068e2d09 100644 --- a/armsrc/Standalone/hf_colin.h +++ b/armsrc/Standalone/hf_colin.h @@ -22,6 +22,7 @@ #include "iso14443a.h" #include "protocols.h" #include "util.h" +#include "pmflash.h" #include "standalone.h" // standalone definitions #include // for bool #include From a784608d946fbdc4df9f6f66e456b4c633c54404 Mon Sep 17 00:00:00 2001 From: slurdge Date: Tue, 16 Jul 2019 22:05:51 +0200 Subject: [PATCH 0096/1854] Add the needed qt package on ArchLinux qt5-base is enough on my Arch --- .../Linux-Installation-Instructions.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/md/Installation_Instructions/Linux-Installation-Instructions.md b/doc/md/Installation_Instructions/Linux-Installation-Instructions.md index 8954a38f7..bb5afb268 100644 --- a/doc/md/Installation_Instructions/Linux-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Linux-Installation-Instructions.md @@ -41,8 +41,10 @@ Additional AUR packages: ```sh yaourt -S termcap ``` - -Note that with only these requirements, you will not get the graphical components of the Proxmark3 client. (Untested: how to get it? `yaourt -S qt4` ?) +If you want graphical output (such as in `hw tune`): +```sh +sudo pacman -Su qt5-base +``` # Clone the RRG/Iceman repository From 8281d3a384b6e2b43f92abc123d6dd1fbf951b1b Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 16 Jul 2019 22:47:34 +0200 Subject: [PATCH 0097/1854] Fix hf_mattyrun bug introduced in 732bc766f9a9a0ec --- armsrc/Standalone/hf_mattyrun.c | 1 + 1 file changed, 1 insertion(+) diff --git a/armsrc/Standalone/hf_mattyrun.c b/armsrc/Standalone/hf_mattyrun.c index 7747a49da..9ea0ba524 100644 --- a/armsrc/Standalone/hf_mattyrun.c +++ b/armsrc/Standalone/hf_mattyrun.c @@ -223,6 +223,7 @@ void RunMod() { */ bool printKeys = false; // Prints keys bool transferToEml = true; // Transfer keys to emulator memory + bool ecfill = true; // Fill emulator memory with cards content. bool simulation = true; // Simulates an exact copy of the target tag bool fillFromEmulator = false; // Dump emulator memory. From 2ad63c07ff9f8a2b35f5660a5581531514777413 Mon Sep 17 00:00:00 2001 From: "Colin J. Brigato" Date: Wed, 17 Jul 2019 03:16:13 +0200 Subject: [PATCH 0098/1854] FIX: Get a usable AES implementation again see #258 for more information. --- common/mbedtls/config.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/mbedtls/config.h b/common/mbedtls/config.h index dfda7ca40..9f4b19c5e 100644 --- a/common/mbedtls/config.h +++ b/common/mbedtls/config.h @@ -489,7 +489,7 @@ * This option is independent of \c MBEDTLS_AES_FEWER_TABLES. * */ -//#define MBEDTLS_AES_ROM_TABLES +#define MBEDTLS_AES_ROM_TABLES /** * \def MBEDTLS_AES_FEWER_TABLES @@ -511,7 +511,7 @@ * This option is independent of \c MBEDTLS_AES_ROM_TABLES. * */ -//#define MBEDTLS_AES_FEWER_TABLES +#define MBEDTLS_AES_FEWER_TABLES /** * \def MBEDTLS_CAMELLIA_SMALL_MEMORY From a6977860db5d21ce160e91462dfbf10e9f1bdade Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 17 Jul 2019 11:27:05 +0300 Subject: [PATCH 0099/1854] fix emv search keep field bug --- client/emv/emvcore.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/client/emv/emvcore.c b/client/emv/emvcore.c index fd70ca871..178a18d58 100644 --- a/client/emv/emvcore.c +++ b/client/emv/emvcore.c @@ -532,7 +532,7 @@ int EMVSearch(EMVCommandChannel channel, bool ActivateField, bool LeaveFieldON, int retrycnt = 0; for (int i = 0; i < AIDlistLen; i ++) { param_gethex_to_eol(AIDlist[i].aid, 0, aidbuf, sizeof(aidbuf), &aidlen); - res = EMVSelect(channel, (i == 0) ? ActivateField : false, (i == AIDlistLen - 1) ? LeaveFieldON : true, aidbuf, aidlen, data, sizeof(data), &datalen, &sw, tlv); + res = EMVSelect(channel, (i == 0) ? ActivateField : false, true, aidbuf, aidlen, data, sizeof(data), &datalen, &sw, tlv); // retry if error and not returned sw error if (res && res != 5) { if (++retrycnt < 3) { @@ -540,6 +540,9 @@ int EMVSearch(EMVCommandChannel channel, bool ActivateField, bool LeaveFieldON, } else { // (1) - card select error, proxmark error OR (200) - result length = 0 if (res == 1 || res == 200) { + if (!LeaveFieldON) + DropFieldEx(channel); + PrintAndLogEx(WARNING, "Exit..."); return 1; } @@ -563,6 +566,9 @@ int EMVSearch(EMVCommandChannel channel, bool ActivateField, bool LeaveFieldON, } } + if (!LeaveFieldON) + DropFieldEx(channel); + return 0; } From 84022807a843d02c7214e570a28fe071d7818a75 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 17 Jul 2019 12:20:04 +0300 Subject: [PATCH 0100/1854] fix rare emv search behavior --- client/emv/emvcore.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/emv/emvcore.c b/client/emv/emvcore.c index 178a18d58..6657f2ce3 100644 --- a/client/emv/emvcore.c +++ b/client/emv/emvcore.c @@ -538,8 +538,8 @@ int EMVSearch(EMVCommandChannel channel, bool ActivateField, bool LeaveFieldON, if (++retrycnt < 3) { i--; } else { - // (1) - card select error, proxmark error OR (200) - result length = 0 - if (res == 1 || res == 200) { + // (1) - card select error, (4) reply timeout, (200) - result length = 0 + if (res == 1 || res == 4 ||res == 200) { if (!LeaveFieldON) DropFieldEx(channel); From 6e1bd28aac052e6b8f77964d2c182802fc109d7e Mon Sep 17 00:00:00 2001 From: slurdge Date: Wed, 17 Jul 2019 14:50:59 +0200 Subject: [PATCH 0101/1854] Fix build for linux And move to xenial --- .travis.yml | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/.travis.yml b/.travis.yml index be68e761a..ee0ed1196 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,22 +1,16 @@ # Travis-CI Build for RfidResearchGroup/Proxmark3 language: c -#default linux build env is: Ubuntu 14.04 trusty +#default linux build env is: xenial compiler: gcc # Test on Linux and MacOS matrix: include: -# - os: osx -# osx_image: xcode7.3 # OS X 10.11 -# - os: osx -# osx_image: xcode8.3 # OS X 10.12 -# - os: osx -# osx_image: xcode9 # OS X 10.13 - os: osx osx_image: xcode9.1 # OS X 10.13.1 - os: linux - dist: trusty + dist: xenial sudo: required before_install: @@ -25,7 +19,7 @@ before_install: ## Note: all dependencies on MacOS should be resolved by the brew install command if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get update -qq; - sudo apt-get install -y gcc-arm-none-eabi; + sudo apt-get install -y gcc-arm-none-eabi libnewlib-arm-none-eabi libnewlib-dev binutils-arm-none-eabi; elif [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update; brew tap RfidResearchGroup/proxmark3; From 67ad6298cd4f7d4e34a40cb43c2302c710df5e1b Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 17 Jul 2019 15:54:22 +0300 Subject: [PATCH 0102/1854] added 14a send/receive arm timeout --- armsrc/iso14443a.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index b5e612ec9..6851ef85a 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -1578,6 +1578,7 @@ static void TransmitFor14443a(const uint8_t *cmd, uint16_t len, uint32_t *timing volatile uint8_t b; uint16_t c = 0; + uint32_t sendtimer = GetTickCount(); while (c < len) { if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { AT91C_BASE_SSC->SSC_THR = cmd[c++]; @@ -1587,6 +1588,8 @@ static void TransmitFor14443a(const uint8_t *cmd, uint16_t len, uint32_t *timing b = (uint16_t)(AT91C_BASE_SSC->SSC_RHR); (void)b; } + if (GetTickCount() - sendtimer > 100) + break; } NextTransferTime = MAX(NextTransferTime, LastTimeProxToAirStart + REQUEST_GUARD_TIME); @@ -1937,6 +1940,7 @@ static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receive (void)b; uint32_t timeout = iso14a_get_timeout(); + uint32_t receive_timer = GetTickCount(); for (;;) { WDT_HIT(); @@ -1949,7 +1953,12 @@ static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receive return false; } } + + // timeout already in ms + 100ms guard time + if (GetTickCount() - receive_timer > timeout + 100) + break; } + return false; } void ReaderTransmitBitsPar(uint8_t *frame, uint16_t bits, uint8_t *par, uint32_t *timing) { From 81fa3f20df702815602e922e52380f0994965ac2 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 17 Jul 2019 16:22:14 +0300 Subject: [PATCH 0103/1854] speed optimization --- armsrc/iso14443a.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 6851ef85a..8543cdfa5 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -1579,17 +1579,23 @@ static void TransmitFor14443a(const uint8_t *cmd, uint16_t len, uint32_t *timing volatile uint8_t b; uint16_t c = 0; uint32_t sendtimer = GetTickCount(); + uint32_t cntr = 0; while (c < len) { if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { AT91C_BASE_SSC->SSC_THR = cmd[c++]; + } else { + if (cntr++ > 1000) { + cntr = 0; + if (GetTickCount() - sendtimer > 100) + break; + } } + //iceman test if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { b = (uint16_t)(AT91C_BASE_SSC->SSC_RHR); (void)b; } - if (GetTickCount() - sendtimer > 100) - break; } NextTransferTime = MAX(NextTransferTime, LastTimeProxToAirStart + REQUEST_GUARD_TIME); From 87e183e664140662c3bfbba2de6270195a37de79 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 17 Jul 2019 16:26:10 +0300 Subject: [PATCH 0104/1854] small fix --- armsrc/iso14443a.c | 1 + 1 file changed, 1 insertion(+) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 8543cdfa5..032766cb6 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -1583,6 +1583,7 @@ static void TransmitFor14443a(const uint8_t *cmd, uint16_t len, uint32_t *timing while (c < len) { if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { AT91C_BASE_SSC->SSC_THR = cmd[c++]; + cntr = 0; } else { if (cntr++ > 1000) { cntr = 0; From 7efaeec0549a785f3c7037970b7a2fbd1d119c91 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 17 Jul 2019 19:01:51 +0200 Subject: [PATCH 0105/1854] Linux install: limit dependencies to the really needed ones --- .../Linux-Installation-Instructions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/md/Installation_Instructions/Linux-Installation-Instructions.md b/doc/md/Installation_Instructions/Linux-Installation-Instructions.md index bb5afb268..fe23db001 100644 --- a/doc/md/Installation_Instructions/Linux-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Linux-Installation-Instructions.md @@ -25,7 +25,7 @@ Install the requirements ```sh sudo apt-get install p7zip git ca-certificates build-essential libreadline5 libreadline-dev \ -libusb-0.1-4 libusb-dev perl pkg-config wget libncurses5-dev gcc-arm-none-eabi libstdc++-arm-none-eabi-newlib libqt4-dev +libusb-0.1-4 libusb-dev perl pkg-config wget libncurses5-dev gcc-arm-none-eabi libnewlib-dev libqt4-dev ``` If you don't need the graphical components of the Proxmark3 client, you can skip the installation of `libqt4-dev`. From 7d836d9f1b76c6054b7fbc4b195bb613048b0d17 Mon Sep 17 00:00:00 2001 From: slurdge Date: Wed, 17 Jul 2019 19:17:20 +0200 Subject: [PATCH 0106/1854] Less apt libs for compilation --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index ee0ed1196..b81af3d97 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,7 +19,7 @@ before_install: ## Note: all dependencies on MacOS should be resolved by the brew install command if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get update -qq; - sudo apt-get install -y gcc-arm-none-eabi libnewlib-arm-none-eabi libnewlib-dev binutils-arm-none-eabi; + sudo apt-get install -y gcc-arm-none-eabi libnewlib-dev; elif [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update; brew tap RfidResearchGroup/proxmark3; From 259c730bb06f0c45ae8050ea281507c5b390094e Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 17 Jul 2019 20:15:47 +0200 Subject: [PATCH 0107/1854] exit(EXIT_FAILURE) if a port was specified to the client and no pm3 is usable --- client/proxmark3.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/client/proxmark3.c b/client/proxmark3.c index 480f39fa3..1d3a0e8b5 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -503,6 +503,9 @@ int main(int argc, char *argv[]) { CloseProxmark(); } + if ((port != NULL) && (!session.pm3_present)) + exit(EXIT_FAILURE); + if (!session.pm3_present) PrintAndLogEx(INFO, "Running in " _YELLOW_("OFFLINE") "mode. Check \"%s -h\" if it's not what you want.\n", exec_name); @@ -531,5 +534,5 @@ int main(int argc, char *argv[]) { CloseProxmark(); } - exit(0); + exit(EXIT_SUCCESS); } From dfdef0bbcc6d5d3888d4851cbd14c2d20ac3cb32 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 17 Jul 2019 20:39:32 +0200 Subject: [PATCH 0108/1854] Clarify some PLATFORM_EXTRAS usages --- Makefile.platform.sample | 3 +++ doc/uart_notes.md | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Makefile.platform.sample b/Makefile.platform.sample index b0d6cf5fe..9d0e2d965 100644 --- a/Makefile.platform.sample +++ b/Makefile.platform.sample @@ -1,4 +1,7 @@ # If you want to use it, copy this file as Makefile.platform and adjust it to your needs +# Run 'make PLATFORM=' to get an exhaustive list of possible parameters for this file. + PLATFORM=PM3RDV4 +# If you want more than one PLATFORM_EXTRAS option, separate them by spaces: #PLATFORM_EXTRAS=BTADDON #STANDALONE=LF_SAMYRUN diff --git a/doc/uart_notes.md b/doc/uart_notes.md index d074bddc8..88b10a109 100644 --- a/doc/uart_notes.md +++ b/doc/uart_notes.md @@ -27,10 +27,10 @@ Proxmark3 RDV4 has a FPC connector outputting on 2 pins a USART from the ARM: USART support is in `common/usart.c`. There are mainly two ways to use this USART: -* connect the host client to the Proxmark3 via this USART instead of USB-CDC, this is the `FPC_USART_HOST`. The most used way is through the BT add-on (blue shark) that we will cover later. Instead of BT add-on, we can also use e.g. a FTDI cable (mostly for internal development, it's much slower than USB-CDC anyway) or in the future other ways to connect the host such as a USART-to-Wi-Fi bridge. +* connect the host client to the Proxmark3 via this USART instead of USB-CDC, this is the `FPC_USART_HOST` option you can add to `PLATFORM_EXTRAS` in `Makefile.platform`. The most used way is through the BT add-on (blue shark) that we will cover later. Instead of BT add-on, we can also use e.g. a FTDI cable (mostly for internal development, it's much slower than USB-CDC anyway) or in the future other ways to connect the host such as a USART-to-Wi-Fi bridge. * connect "slave" devices to the Proxmark3 to add functionnalities. In such case, the host client will use USB-CDC and the USART will be use to, e.g. connect the Proxmark3 to various daughterboards. These is no such example of daughterboard as of today, except when we're talking to the BT add-on in its AT configuration mode. -This USART can be reached from the host client (if connected via USB-CDC) through the following commands, available in `FPC_USART_DEV` build: +This USART can be reached from the host client (if connected via USB-CDC) through the following commands, available when you add `FPC_USART_DEV` to `PLATFORM_EXTRAS` in `Makefile.platform`: * `usart config`, to configure the baudrate and the parity of the Proxmark3 USART * `usart txrx/tx/rx/txhex/rxhex` to transmit and receive bytes @@ -45,7 +45,7 @@ Internally, the desired baudrate is converted to UART settings: a BRGR and a FP. When the BT add-on is turned on but no actively connected to a host, it's in a configuration mode where it accepts "AT" commands and its blue LED is blinking at about 1Hz. -Some specific commands are available in `BTADDON` build, only to configure specific features of the BT add-on: +Some specific commands are available when you add `BTADDON` to `PLATFORM_EXTRAS` in `Makefile.platform` (it will automatically enable `FPC_USART_HOST` as well), to configure specific features of the BT add-on: * `usart btpin`, to change the BT add-on PIN * `usart btfactory`, to guess the current BT add-on UART settings and to reset its configuration. From 9dc1b1664d6c5e8bb908295141e41e39038f01f9 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 17 Jul 2019 21:11:34 +0200 Subject: [PATCH 0109/1854] Add external flash layout notes --- README.md | 1 + doc/ext_flash_notes.md | 95 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 doc/ext_flash_notes.md diff --git a/README.md b/README.md index a1e7ad76c..e3be68472 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,7 @@ Note that it also supports other Proxmark3 platforms as well! |[Issues](#issues)|[Blue shark manual](/doc/bt_manual_v10.md) |[Advanced compilation parameters](/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md)| |[Notes on UART](/doc/uart_notes.md)||| |[Notes on Frame format](/doc/new_frame_format.md)||| +|[Notes on external flash](/doc/ext_flash_notes.md)||| |[Notes on Termux / Android](/doc/termux_notes.md)||| |[Developing standalone mode](/armsrc/Standalone/readme.md)|[Wiki about standalone mode](https://github.com/RfidResearchGroup/proxmark3/wiki/Standalone-mode) || |[Donations](#Donations)||| diff --git a/doc/ext_flash_notes.md b/doc/ext_flash_notes.md new file mode 100644 index 000000000..46059d9ca --- /dev/null +++ b/doc/ext_flash_notes.md @@ -0,0 +1,95 @@ +# External flash + +External 256kbytes flash is a unique feature of the RDV4 edition. + +## Addresses + +Flash memory is + +* 256kb (0x40000= 262144) +* divided into 4 pages of 64kb (0x10000 = 65536) +* 4 pages divided into 16 sectors of 4kb (0x1000 = 4096), so last sector is at 0x3F000 + +Therefore a flash address can be interpreted as such: +``` +0xPSxxx e.g. 0x3FF7F + ^ page ^ page 3 + ^ sector ^ sector 0xF + ^^^ offset ^^^ offset 0xF7F +``` + +## Layout + +Page 0: +* available for user data +* to dump it: `mem dump f page0_dump o 0 l 65536` +* to erase it: `mem wipe p 0` + +Page 1: +* available for user data +* to dump it: `mem dump f page1_dump o 65536 l 65536` +* to erase it: `mem wipe p 1` + +Page 2: +* available for user data +* to dump it: `mem dump f page2_dump o 131072 l 65536` +* to erase it: `mem wipe p 2` + +Page 3: +* used by Proxmark3 RDV4 specific functions: flash signature and keys dictionaries, see below for details +* to dump it: `mem dump f page3_dump o 196608 l 65536` +* to erase it: + * **Beware** it will erase your flash signature (see below) so better to back it up first as you won't be able to regenerate it by yourself! + * It's possible to erase completely page 3 by erase the entire flash memory with the voluntarily undocumented command `mem wipe i`. + * Updating keys dictionaries doesn't require to erase page 3. + +## Page3 Layout + +Page3 is used as follows by the Proxmark3 RDV4 firmware: + +* **MF_KEYS** + * offset: page 3 sector 9 (0x9) @ 3*0x10000+9*0x1000=0x39000 + * length: 2 sectors + +* **ICLASS_KEYS** + * offset: page 3 sector 11 (0xB) @ 3*0x10000+11*0x1000=0x3B000 + * length: 1 sector + +* **T55XX_KEYS** + * offset: page 3 sector 12 (0xC) @ 3*0x10000+12*0x1000=0x3C000 + * length: 1 sector + +* **T55XX_CONFIG** + * offset: page 3 sector 13 (0xD) @ 3*0x10000+13*0x1000=0x3D000 + * length: 1 sector (actually only a few bytes are used to store `t55xx_config` structure) + +* **RSA SIGNATURE**, see below for details + * offset: page 3 sector 15 (0xF) offset 0xF7F @ 3*0x10000+15*0x1000+0xF7F=0x3FF7F + * length: 128 bytes + * offset should have been 0x3FF80 but historically it's one byte off and therefore the last byte of the flash is unused + +## RSA signature + +To ensure your Proxmark3 RDV4 is not a counterfeit product, its external flash contains a RSA signature of the flash unique ID. +You can verify it with: `mem info` + +``` +[usb] pm3 --> mem info + +[=] --- Flash memory Information --------- + +[=] ------------------------------------------------------------- +[=] ID | xx xx xx xx xx xx xx xx +[=] SHA1 | xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx +[=] RSA SIGNATURE | +[00] | xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx +[01] | xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx +[02] | xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx +[03] | xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx +[=] KEY length | 128 +[+] RSA key validation ok +[+] RSA Verification ok +``` + +For a backup of the signature: `mem dump p f flash_signature_dump o 262015 l 128` + From f748c217b6013e2af335d66a03aea2d9fa2981a3 Mon Sep 17 00:00:00 2001 From: Iceman Date: Thu, 18 Jul 2019 15:27:12 +0200 Subject: [PATCH 0110/1854] Update README.md appveyor RRG/Iceman link. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e3be68472..46dc5f785 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ This repo is based on iceman fork for Proxmark3. It is dedicated to bringing the most out of the new features for Proxmark3 RDV4.0 new hardware and design. Note that it also supports other Proxmark3 platforms as well! -[![Build status](https://ci.appveyor.com/api/projects/status/ct5blik2wa96bv0x/branch/master?svg=true)](https://ci.appveyor.com/project/iceman1001/proxmark3-ji4wj/branch/master) +[![Build status](https://ci.appveyor.com/api/projects/status/uvk6cexs6xxwonn4/branch/master?svg=true)](https://ci.appveyor.com/project/iceman1001/proxmark3-isfoh/branch/master) [![Latest release](https://img.shields.io/github/release/RfidResearchGroup/proxmark3.svg)](https://github.com/RfidResearchGroup/proxmark3/releases/latest) --- From 29f8bfb80c08bc506ca85cf554912b2a1592f3a3 Mon Sep 17 00:00:00 2001 From: Julien Piat Date: Thu, 18 Jul 2019 15:54:21 +0200 Subject: [PATCH 0111/1854] Update default_keys.dic with new keys from Scan Badge APK --- client/default_keys.dic | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/client/default_keys.dic b/client/default_keys.dic index c8d96bd44..4df09cb1c 100644 --- a/client/default_keys.dic +++ b/client/default_keys.dic @@ -944,5 +944,9 @@ A23456789123 A00003000084 675A32413770 395244733978 +A0004A000036 +2C9F3D45BA13 +4243414F5250 +DFE73BE48AC6 # B069D0D03D17 From 5a5b3db92ee618b435c202b1946723b98f1b5b85 Mon Sep 17 00:00:00 2001 From: Julien Piat Date: Thu, 18 Jul 2019 16:11:03 +0200 Subject: [PATCH 0112/1854] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c78d813db..89a4d7ec8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Change: new keys for Vigik badges in default_keys.dict (@luminouw) - Add 'hw standalone' to jump to standalone mode from command line or script (@doegox) - Add to 'hf 14a apdu' print apdu and compose apdu (@merlokk) - Change: buggy 'mem read' removed, 'mem save' renamed 'mem dump', can now display too (@doegox) From 1e0433c1d79002cce7e67e54d247673ce3a29403 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 17 Jul 2019 19:02:01 +0300 Subject: [PATCH 0113/1854] now code can't use uninitialized fpga link and encoders/decoders --- armsrc/iso14443a.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index b5e612ec9..db20481c8 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -13,6 +13,7 @@ #define MAX_ISO14A_TIMEOUT 524288 static uint32_t iso14a_timeout; +static bool iso14443a_active = false; uint8_t colpos = 0; int rsamples = 0; @@ -1551,6 +1552,9 @@ void PrepareDelayedTransfer(uint16_t delay) { //------------------------------------------------------------------------------------- static void TransmitFor14443a(const uint8_t *cmd, uint16_t len, uint32_t *timing) { + if (!iso14443a_active) + return; + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD); if (timing) { @@ -1922,6 +1926,9 @@ bool EmLogTrace(uint8_t *reader_data, uint16_t reader_len, uint32_t reader_Start //----------------------------------------------------------------------------- static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receivedResponsePar, uint16_t offset) { uint32_t c = 0; + + if (!iso14443a_active) + return false; // Set FPGA mode to "reader listen mode", no modulation (listen // only, since we are receiving, not transmitting). @@ -2354,6 +2361,14 @@ void iso14443a_setup(uint8_t fpga_minor_mode) { UartReset(); NextTransferTime = 2 * DELAY_ARM2AIR_AS_READER; iso14a_set_timeout(1060); // 106 * 10ms default + + iso14443a_active = true; +} + +void iso14443a_off() { + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LED_D_OFF(); + iso14443a_active = false; } /* Peter Fillmore 2015 @@ -2558,7 +2573,7 @@ void ReaderIso14443a(PacketCommandNG *c) { return; OUT: - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + iso14443a_off(); set_tracing(false); LEDsoff(); } @@ -2854,7 +2869,7 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) { reply_mix(CMD_ACK, isOK, 0, 0, buf, sizeof(buf)); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + iso14443a_off(); LEDsoff(); set_tracing(false); } @@ -3094,7 +3109,7 @@ void DetectNACKbug() { //reply_mix(CMD_ACK, isOK, num_nacks, i, 0, 0); BigBuf_free(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + iso14443a_off(); LEDsoff(); set_tracing(false); } From e87abc9681ecae0cac02adc52984bbd92c1511e5 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Thu, 18 Jul 2019 17:32:56 +0300 Subject: [PATCH 0114/1854] small fix apdu leds --- armsrc/iso14443a.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index db20481c8..11f2ca66b 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -13,6 +13,7 @@ #define MAX_ISO14A_TIMEOUT 524288 static uint32_t iso14a_timeout; +// if iso14443a not active - transmit/receive dont try to execute static bool iso14443a_active = false; uint8_t colpos = 0; @@ -2367,7 +2368,7 @@ void iso14443a_setup(uint8_t fpga_minor_mode) { void iso14443a_off() { FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LED_D_OFF(); + LEDsoff(); iso14443a_active = false; } @@ -2575,7 +2576,6 @@ void ReaderIso14443a(PacketCommandNG *c) { OUT: iso14443a_off(); set_tracing(false); - LEDsoff(); } // Determine the distance between two nonces. @@ -2870,7 +2870,6 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) { reply_mix(CMD_ACK, isOK, 0, 0, buf, sizeof(buf)); iso14443a_off(); - LEDsoff(); set_tracing(false); } @@ -3110,6 +3109,5 @@ void DetectNACKbug() { //reply_mix(CMD_ACK, isOK, num_nacks, i, 0, 0); BigBuf_free(); iso14443a_off(); - LEDsoff(); set_tracing(false); } From 9cd80406e210830d04e4fb3f7f24e7c32f2c01e9 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 18 Jul 2019 16:39:48 +0200 Subject: [PATCH 0115/1854] Add Travis badge --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 46dc5f785..331edb337 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,9 @@ This repo is based on iceman fork for Proxmark3. It is dedicated to bringing the most out of the new features for Proxmark3 RDV4.0 new hardware and design. Note that it also supports other Proxmark3 platforms as well! -[![Build status](https://ci.appveyor.com/api/projects/status/uvk6cexs6xxwonn4/branch/master?svg=true)](https://ci.appveyor.com/project/iceman1001/proxmark3-isfoh/branch/master) -[![Latest release](https://img.shields.io/github/release/RfidResearchGroup/proxmark3.svg)](https://github.com/RfidResearchGroup/proxmark3/releases/latest) +| Releases | Linux & OSX CI | Windows CI | +| ------------------- |:-------------------:| -------------------:| +| [![Latest release](https://img.shields.io/github/release/RfidResearchGroup/proxmark3.svg)](https://github.com/RfidResearchGroup/proxmark3/releases/latest) | [![Build status](https://travis-ci.org/RfidResearchGroup/proxmark3.svg?branch=master)](https://travis-ci.org/RfidResearchGroup/proxmark3) | [![Build status](https://ci.appveyor.com/api/projects/status/uvk6cexs6xxwonn4/branch/master?svg=true)](https://ci.appveyor.com/project/iceman1001/proxmark3-isfoh/branch/master) | --- From fdada47325d3c0622c179d7c095fa2a0d1ae0106 Mon Sep 17 00:00:00 2001 From: RFID Research Group Date: Thu, 18 Jul 2019 20:45:08 +0200 Subject: [PATCH 0116/1854] Update README.md swapped to RRG account for Appveyor --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 331edb337..50813868e 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ Note that it also supports other Proxmark3 platforms as well! | Releases | Linux & OSX CI | Windows CI | | ------------------- |:-------------------:| -------------------:| -| [![Latest release](https://img.shields.io/github/release/RfidResearchGroup/proxmark3.svg)](https://github.com/RfidResearchGroup/proxmark3/releases/latest) | [![Build status](https://travis-ci.org/RfidResearchGroup/proxmark3.svg?branch=master)](https://travis-ci.org/RfidResearchGroup/proxmark3) | [![Build status](https://ci.appveyor.com/api/projects/status/uvk6cexs6xxwonn4/branch/master?svg=true)](https://ci.appveyor.com/project/iceman1001/proxmark3-isfoh/branch/master) | +| [![Latest release](https://img.shields.io/github/release/RfidResearchGroup/proxmark3.svg)](https://github.com/RfidResearchGroup/proxmark3/releases/latest) | [![Build status](https://travis-ci.org/RfidResearchGroup/proxmark3.svg?branch=master)](https://travis-ci.org/RfidResearchGroup/proxmark3) | [![Build status](https://ci.appveyor.com/api/projects/status/b4gwrhq3nc876cuu/branch/master?svg=true)](https://ci.appveyor.com/project/RfidResearchGroup/proxmark3/branch/master) | --- From 01e6db5c2e05f4dfde50c5b8823f2b5fa8d447e1 Mon Sep 17 00:00:00 2001 From: slurdge Date: Thu, 18 Jul 2019 22:26:01 +0200 Subject: [PATCH 0117/1854] Add a simple tool to analyze elf files --- CHANGELOG.md | 1 + tools/analyzesize.py | 31 +++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100755 tools/analyzesize.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 89a4d7ec8..bedc1dc04 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Add a simple python tool to check the elf sizes (@slurdge) - Change: new keys for Vigik badges in default_keys.dict (@luminouw) - Add 'hw standalone' to jump to standalone mode from command line or script (@doegox) - Add to 'hf 14a apdu' print apdu and compose apdu (@merlokk) diff --git a/tools/analyzesize.py b/tools/analyzesize.py new file mode 100755 index 000000000..ef14e2879 --- /dev/null +++ b/tools/analyzesize.py @@ -0,0 +1,31 @@ +#! /usr/bin/python3 + +import json +import subprocess +import sys + +def print_increase(x, y, name): + if x > y: + print("{} increase by: {} (0x{:08X}) bytes ({}%)".format(name, x-y, x-y, (x-y)*100/y)) + else: + print("{} decrease by: {} (0x{:08X}) bytes ({}%)".format(name, y-x, y-x, (y-x)*100/x)) +dbname = "tools/data.json" +db = json.load(open(dbname,"r")) + +if len(sys.argv) < 3: + print("Usage: analazysize.py ") + exit(-1) +action, name = sys.argv[1:3] +currentdata = subprocess.run(["arm-none-eabi-size","armsrc/obj/fullimage.stage1.elf"], stdout=subprocess.PIPE).stdout +currentdata = currentdata.split(b"\n")[1].strip() +text,data,bss = [int(x) for x in currentdata.split(b"\t")[:3]] +if action.lower() == "add": + db[name] = [text, data, bss] + json.dump(db, open(dbname, "w")) +elif action.lower() == "diff": + text_ref, data_ref, bss_ref = db[name] + flash_ref = text_ref+data_ref + flash = text+data + print_increase(flash, flash_ref, "Flash") + print_increase(bss, bss_ref, "RAM") + \ No newline at end of file From 32382ace3be9efd3e99e6f8e5b0903360d9f29ca Mon Sep 17 00:00:00 2001 From: slurdge Date: Thu, 18 Jul 2019 22:28:07 +0200 Subject: [PATCH 0118/1854] Ignore local openocd configuration --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index e37ce9534..f5ee135e6 100644 --- a/.gitignore +++ b/.gitignore @@ -66,6 +66,7 @@ client/traces/* armsrc/TEMP EMV/* tools/mf_nonce_brute/* tools/andrew/* +tools/jtag_openocd/openocd_configuration ppls patches/* *- Copy.* @@ -73,3 +74,4 @@ client/lualibs/mf_default_keys.lua client/lualibs/pm3_cmd.lua # recompiled fpga_version_info.c + From 41731ea0849c4d5bca0e46236292e06570b01f0d Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 18 Jul 2019 23:42:58 +0200 Subject: [PATCH 0119/1854] analyzesize: create db on first use --- tools/analyzesize.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/analyzesize.py b/tools/analyzesize.py index ef14e2879..70c35de26 100755 --- a/tools/analyzesize.py +++ b/tools/analyzesize.py @@ -10,7 +10,10 @@ def print_increase(x, y, name): else: print("{} decrease by: {} (0x{:08X}) bytes ({}%)".format(name, y-x, y-x, (y-x)*100/x)) dbname = "tools/data.json" -db = json.load(open(dbname,"r")) +try: + db = json.load(open(dbname,"r")) +except FileNotFoundError: + db = dict() if len(sys.argv) < 3: print("Usage: analazysize.py ") From 4e9e7d6da004140c7c4a2ed2c3f560ac9a4d6763 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 18 Jul 2019 23:50:45 +0200 Subject: [PATCH 0120/1854] temporary fix to get Appveyor happy. Will need more tuning later. --- client/cmdhfmf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index a62924787..e75224cd2 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -3591,7 +3591,7 @@ static command_t CommandTable[] = { {"list", CmdHF14AMfList, AlwaysAvailable, "List Mifare history"}, {"darkside", CmdHF14AMfDarkside, IfPm3Iso14443a, "Darkside attack. read parity error messages."}, {"nested", CmdHF14AMfNested, IfPm3Iso14443a, "Nested attack. Test nested authentication"}, - {"hardnested", CmdHF14AMfNestedHard, IfPm3Iso14443a, "Nested attack for hardened Mifare cards"}, + {"hardnested", CmdHF14AMfNestedHard, AlwaysAvailable, "Nested attack for hardened Mifare cards"}, {"keybrute", CmdHF14AMfKeyBrute, IfPm3Iso14443a, "J_Run's 2nd phase of multiple sector nested authentication key recovery"}, {"nack", CmdHf14AMfNack, IfPm3Iso14443a, "Test for Mifare NACK bug"}, {"chk", CmdHF14AMfChk, IfPm3Iso14443a, "Check keys"}, From 7bf3255a6cd6f901a8cc01306c5dd4794ed974cc Mon Sep 17 00:00:00 2001 From: slurdge Date: Thu, 18 Jul 2019 21:18:52 +0200 Subject: [PATCH 0121/1854] Flasher support for 512K flash A better way would be to cut the connecting function and flashing function and to move the whole mem computation to flash.c Working flasher --- CHANGELOG.md | 1 + bootrom/bootrom.c | 29 ++++++++++++++++++----------- client/flash.c | 35 ++++++++++++++++++----------------- client/flash.h | 2 +- client/flasher.c | 20 ++++++++++++++------ 5 files changed, 52 insertions(+), 35 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bedc1dc04..cfa26a2b3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Add support for flashing 512K units (@slurdge) - Add a simple python tool to check the elf sizes (@slurdge) - Change: new keys for Vigik badges in default_keys.dict (@luminouw) - Add 'hw standalone' to jump to standalone mode from command line or script (@doegox) diff --git a/bootrom/bootrom.c b/bootrom/bootrom.c index 4e92bc95b..bda7de2c6 100644 --- a/bootrom/bootrom.c +++ b/bootrom/bootrom.c @@ -153,28 +153,35 @@ void UsbPacketReceived(uint8_t *packet, int len) { case CMD_FINISH_WRITE: { uint32_t *flash_mem = (uint32_t *)(&_flash_start); for (int j = 0; j < 2; j++) { - for (i = 0 + (64 * j); i < 64 + (64 * j); i++) { - flash_mem[i] = c->d.asDwords[i]; - } - uint32_t flash_address = arg0 + (0x100 * j); - + AT91PS_EFC efc_bank = AT91C_BASE_EFC0; + int offset = 0; + uint32_t page_n = (flash_address - ((uint32_t)flash_mem)) / AT91C_IFLASH_PAGE_SIZE; + if (page_n >= AT91C_IFLASH_NB_OF_PAGES / 2) { + page_n -= AT91C_IFLASH_NB_OF_PAGES / 2; + efc_bank = AT91C_BASE_EFC1; + // We need to offset the writes or it will not fill the correct bank write buffer. + offset = (AT91C_IFLASH_NB_OF_PAGES / 2) * AT91C_IFLASH_PAGE_SIZE / sizeof(uint32_t); + } + for (i = 0 + (64 * j); i < 64 + (64 * j); i++) { + flash_mem[offset+i] = c->d.asDwords[i]; + } + /* Check that the address that we are supposed to write to is within our allowed region */ if (((flash_address + AT91C_IFLASH_PAGE_SIZE - 1) >= end_addr) || (flash_address < start_addr)) { /* Disallow write */ dont_ack = 1; reply_old(CMD_NACK, 0, 0, 0, 0, 0); } else { - uint32_t page_n = (flash_address - ((uint32_t)flash_mem)) / AT91C_IFLASH_PAGE_SIZE; - /* Translate address to flash page and do flash, update here for the 512k part */ - AT91C_BASE_EFC0->EFC_FCR = MC_FLASH_COMMAND_KEY | - MC_FLASH_COMMAND_PAGEN(page_n) | - AT91C_MC_FCMD_START_PROG; + + efc_bank->EFC_FCR = MC_FLASH_COMMAND_KEY | + MC_FLASH_COMMAND_PAGEN(page_n) | + AT91C_MC_FCMD_START_PROG; } // Wait until flashing of page finishes uint32_t sr; - while (!((sr = AT91C_BASE_EFC0->EFC_FSR) & AT91C_MC_FRDY)); + while (!((sr = efc_bank->EFC_FSR) & AT91C_MC_FRDY)); if (sr & (AT91C_MC_LOCKE | AT91C_MC_PROGE)) { dont_ack = 1; reply_old(CMD_NACK, sr, 0, 0, 0, 0); diff --git a/client/flash.c b/client/flash.c index e41b47fb0..a29d8d7b0 100644 --- a/client/flash.c +++ b/client/flash.c @@ -12,13 +12,6 @@ #define FLASH_START 0x100000 -#ifdef HAS_512_FLASH -# define FLASH_SIZE (512*1024) -#else -# define FLASH_SIZE (256*1024) -#endif - -#define FLASH_END (FLASH_START + FLASH_SIZE) #define BOOTLOADER_SIZE 0x2000 #define BOOTLOADER_END (FLASH_START + BOOTLOADER_SIZE) @@ -33,7 +26,7 @@ static const uint8_t elf_ident[] = { // Turn PHDRs into flasher segments, checking for PHDR sanity and merging adjacent // unaligned segments if needed -static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs, uint16_t num_phdrs) { +static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs, uint16_t num_phdrs, uint32_t flash_end) { Elf32_Phdr *phdr = phdrs; flash_seg_t *seg; uint32_t last_end = 0; @@ -77,11 +70,11 @@ static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs, PrintAndLogEx(ERR, "Error: PHDRs not sorted or overlap"); return -1; } - if (paddr < FLASH_START || (paddr + filesz) > FLASH_END) { + if (paddr < FLASH_START || (paddr + filesz) > flash_end) { PrintAndLogEx(ERR, "Error: PHDR is not contained in Flash"); return -1; } - if (vaddr >= FLASH_START && vaddr < FLASH_END && (flags & PF_W)) { + if (vaddr >= FLASH_START && vaddr < flash_end && (flags & PF_W)) { PrintAndLogEx(ERR, "Error: Flash VMA segment is writable"); return -1; } @@ -153,7 +146,7 @@ static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs, } // Sanity check segments and check for bootloader writes -static int check_segs(flash_file_t *ctx, int can_write_bl) { +static int check_segs(flash_file_t *ctx, int can_write_bl, uint32_t flash_end) { for (int i = 0; i < ctx->num_segs; i++) { flash_seg_t *seg = &ctx->segments[i]; @@ -165,7 +158,7 @@ static int check_segs(flash_file_t *ctx, int can_write_bl) { PrintAndLogEx(ERR, "Error: Segment is outside of flash bounds"); return -1; } - if (seg->start + seg->length > FLASH_END) { + if (seg->start + seg->length > flash_end) { PrintAndLogEx(ERR, "Error: Segment is outside of flash bounds"); return -1; } @@ -182,11 +175,12 @@ static int check_segs(flash_file_t *ctx, int can_write_bl) { } // Load an ELF file and prepare it for flashing -int flash_load(flash_file_t *ctx, const char *name, int can_write_bl) { +int flash_load(flash_file_t *ctx, const char *name, int can_write_bl, int flash_size) { FILE *fd; Elf32_Ehdr ehdr; Elf32_Phdr *phdrs = NULL; uint16_t num_phdrs; + uint32_t flash_end = FLASH_START + flash_size; int res; fd = fopen(name, "rb"); @@ -239,10 +233,10 @@ int flash_load(flash_file_t *ctx, const char *name, int can_write_bl) { goto fail; } - res = build_segs_from_phdrs(ctx, fd, phdrs, num_phdrs); + res = build_segs_from_phdrs(ctx, fd, phdrs, num_phdrs, flash_end); if (res < 0) goto fail; - res = check_segs(ctx, can_write_bl); + res = check_segs(ctx, can_write_bl, flash_end); if (res < 0) goto fail; @@ -362,15 +356,22 @@ int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t *chipinfo = resp.oldarg[0]; } + uint32_t flash_end = FLASH_START + AT91C_IFLASH_PAGE_SIZE * AT91C_IFLASH_NB_OF_PAGES / 2; + if (((*chipinfo & 0xF00) >> 8) > 9) { + flash_end = FLASH_START + AT91C_IFLASH_PAGE_SIZE * AT91C_IFLASH_NB_OF_PAGES; + } + + PrintAndLogEx(INFO, "End of flahs: 0x%08x", flash_end); + if (state & DEVICE_INFO_FLAG_UNDERSTANDS_START_FLASH) { // This command is stupid. Why the heck does it care which area we're // flashing, as long as it's not the bootloader area? The mind boggles. PacketResponseNG resp; if (enable_bl_writes) { - SendCommandBL(CMD_START_FLASH, FLASH_START, FLASH_END, START_FLASH_MAGIC, NULL, 0); + SendCommandBL(CMD_START_FLASH, FLASH_START, flash_end, START_FLASH_MAGIC, NULL, 0); } else { - SendCommandBL(CMD_START_FLASH, BOOTLOADER_END, FLASH_END, 0, NULL, 0); + SendCommandBL(CMD_START_FLASH, BOOTLOADER_END, flash_end, 0, NULL, 0); } return wait_for_ack(&resp); } else { diff --git a/client/flash.h b/client/flash.h index 7140de673..cc0387bf3 100644 --- a/client/flash.h +++ b/client/flash.h @@ -37,7 +37,7 @@ typedef struct { flash_seg_t *segments; } flash_file_t; -int flash_load(flash_file_t *ctx, const char *name, int can_write_bl); +int flash_load(flash_file_t *ctx, const char *name, int can_write_bl, int flash_size); int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t *chipid); int flash_write(flash_file_t *ctx); void flash_free(flash_file_t *ctx); diff --git a/client/flasher.c b/client/flasher.c index 94e2ef6ba..8b6a87bf8 100644 --- a/client/flasher.c +++ b/client/flasher.c @@ -21,6 +21,7 @@ #include "ui.h" #define MAX_FILES 4 +#define ONE_KB 1024 static void usage(char *argv0) { PrintAndLogEx(NORMAL, "Usage: %s [-b] image.elf [image.elf...]\n", argv0); @@ -76,6 +77,7 @@ int main(int argc, char **argv) { int num_files = 0; int res; flash_file_t files[MAX_FILES]; + char * filenames[MAX_FILES]; memset(files, 0, sizeof(files)); @@ -102,11 +104,7 @@ int main(int argc, char **argv) { return -1; } } else { - res = flash_load(&files[num_files], argv[i], can_write_bl); - if (res < 0) - return -1; - - PrintAndLogEx(NORMAL, ""); + filenames[num_files] = argv[i]; num_files++; } } @@ -132,9 +130,19 @@ int main(int argc, char **argv) { PrintAndLogEx(NORMAL, "Available memory on this board: "_RED_("UNKNOWN")"\n"); PrintAndLogEx(ERR, _RED_("Note: Your bootloader does not understand the new CHIP_INFO command")); PrintAndLogEx(ERR, _RED_("It is recommended that you update your bootloader") "\n"); + mem_avail = 256; //we default to a low value } + + for (int i = 0 ; i < num_files; ++i){ + res = flash_load(&files[i], filenames[i], can_write_bl, mem_avail*ONE_KB); + if (res < 0) + return -1; + + PrintAndLogEx(NORMAL, ""); + } + PrintAndLogEx(SUCCESS, "\n" _BLUE_("Flashing...")); -// TODO check if enough space on Pm3 mem to write the given files + for (int i = 0; i < num_files; i++) { res = flash_write(&files[i]); if (res < 0) From 44278272a41e9140ba459e87845de1c9196920c2 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 19 Jul 2019 12:39:23 +0200 Subject: [PATCH 0122/1854] typo --- client/flash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/flash.c b/client/flash.c index a29d8d7b0..abd81a9de 100644 --- a/client/flash.c +++ b/client/flash.c @@ -361,7 +361,7 @@ int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t flash_end = FLASH_START + AT91C_IFLASH_PAGE_SIZE * AT91C_IFLASH_NB_OF_PAGES; } - PrintAndLogEx(INFO, "End of flahs: 0x%08x", flash_end); + PrintAndLogEx(INFO, "End of flash: 0x%08x", flash_end); if (state & DEVICE_INFO_FLAG_UNDERSTANDS_START_FLASH) { // This command is stupid. Why the heck does it care which area we're From f6f14f82d48d7306492e356f5dd8d36db6ab2c83 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 19 Jul 2019 13:02:12 +0200 Subject: [PATCH 0123/1854] Add option -i to flasher to query Pm3 for its memory size, and some doc tuning --- CHANGELOG.md | 1 + client/flasher.c | 58 +++++++++++++++++++++++++++--------------------- 2 files changed, 34 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cfa26a2b3..45c2074b3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Add option -i to flasher to query Pm3 for its memory size (@doegox) - Add support for flashing 512K units (@slurdge) - Add a simple python tool to check the elf sizes (@slurdge) - Change: new keys for Vigik badges in default_keys.dict (@luminouw) diff --git a/client/flasher.c b/client/flasher.c index 8b6a87bf8..4caeab63b 100644 --- a/client/flasher.c +++ b/client/flasher.c @@ -24,15 +24,20 @@ #define ONE_KB 1024 static void usage(char *argv0) { - PrintAndLogEx(NORMAL, "Usage: %s [-b] image.elf [image.elf...]\n", argv0); - PrintAndLogEx(NORMAL, "\t-b\tEnable flashing of bootloader area (DANGEROUS)\n"); - PrintAndLogEx(NORMAL, "\nExample:\n\n\t %s "SERIAL_PORT_EXAMPLE_H" armsrc/obj/fullimage.elf", argv0); + PrintAndLogEx(NORMAL, "Usage: %s [-b] image.elf [image.elf...]", argv0); + PrintAndLogEx(NORMAL, " %s -i\n", argv0); + PrintAndLogEx(NORMAL, "\t-b\tEnable flashing of bootloader area (DANGEROUS)"); + PrintAndLogEx(NORMAL, "\t-i\tProbe the connected Proxmark3 to retrieve its memory size"); + PrintAndLogEx(NORMAL, "\nExamples:\n\t %s "SERIAL_PORT_EXAMPLE_H" -i", argv0); + PrintAndLogEx(NORMAL, "\t %s "SERIAL_PORT_EXAMPLE_H" armsrc/obj/fullimage.elf", argv0); #ifdef __linux__ - PrintAndLogEx(NORMAL, "\nNote (Linux): if the flasher gets stuck in 'Waiting for Proxmark3 to reappear on ',"); - PrintAndLogEx(NORMAL, " you need to blacklist Proxmark3 for modem-manager - see wiki for more details:\n"); - PrintAndLogEx(NORMAL, " https://github.com/Proxmark/proxmark3/wiki/Gentoo Linux\n"); - PrintAndLogEx(NORMAL, " https://github.com/Proxmark/proxmark3/wiki/Ubuntu Linux\n"); - PrintAndLogEx(NORMAL, " https://github.com/Proxmark/proxmark3/wiki/OSX\n"); + PrintAndLogEx(NORMAL, "\nNote (Linux):\nif the flasher gets stuck in 'Waiting for Proxmark3 to reappear on ',"); + PrintAndLogEx(NORMAL, "you need to blacklist Proxmark3 for modem-manager - see documentation for more details:"); + PrintAndLogEx(NORMAL, "* https://github.com/RfidResearchGroup/proxmark3/blob/master/doc/md/Installation_Instructions/ModemManager-Must-Be-Discarded.md"); + PrintAndLogEx(NORMAL, "\nMore info on flashing procedure from the official Proxmark3 wiki:"); + PrintAndLogEx(NORMAL, "* https://github.com/Proxmark/proxmark3/wiki/Gentoo%%20Linux"); + PrintAndLogEx(NORMAL, "* https://github.com/Proxmark/proxmark3/wiki/Ubuntu%%20Linux"); + PrintAndLogEx(NORMAL, "* https://github.com/Proxmark/proxmark3/wiki/OSX\n"); #endif } @@ -78,7 +83,7 @@ int main(int argc, char **argv) { int res; flash_file_t files[MAX_FILES]; char * filenames[MAX_FILES]; - + bool info = false; memset(files, 0, sizeof(files)); session.supports_colors = false; @@ -99,6 +104,8 @@ int main(int argc, char **argv) { if (argv[i][0] == '-') { if (!strcmp(argv[i], "-b")) { can_write_bl = 1; + } else if (!strcmp(argv[i], "-i")) { + info = true; } else { usage(argv[0]); return -1; @@ -133,24 +140,25 @@ int main(int argc, char **argv) { mem_avail = 256; //we default to a low value } - for (int i = 0 ; i < num_files; ++i){ - res = flash_load(&files[i], filenames[i], can_write_bl, mem_avail*ONE_KB); - if (res < 0) - return -1; + if (! info) { + for (int i = 0 ; i < num_files; ++i){ + res = flash_load(&files[i], filenames[i], can_write_bl, mem_avail*ONE_KB); + if (res < 0) + return -1; - PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, ""); + } + + PrintAndLogEx(SUCCESS, "\n" _BLUE_("Flashing...")); + + for (int i = 0; i < num_files; i++) { + res = flash_write(&files[i]); + if (res < 0) + return -1; + flash_free(&files[i]); + PrintAndLogEx(NORMAL, "\n"); + } } - - PrintAndLogEx(SUCCESS, "\n" _BLUE_("Flashing...")); - - for (int i = 0; i < num_files; i++) { - res = flash_write(&files[i]); - if (res < 0) - return -1; - flash_free(&files[i]); - PrintAndLogEx(NORMAL, "\n"); - } - res = flash_stop_flashing(); if (res < 0) return -1; From 33f2cb09817936a7bcf8ae8311bc3d46fdb83792 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 19 Jul 2019 13:15:32 +0200 Subject: [PATCH 0124/1854] Rework flasher exit on error --- client/flasher.c | 56 +++++++++++++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 22 deletions(-) diff --git a/client/flasher.c b/client/flasher.c index 4caeab63b..0db87cb94 100644 --- a/client/flasher.c +++ b/client/flasher.c @@ -81,6 +81,7 @@ int main(int argc, char **argv) { int can_write_bl = 0; int num_files = 0; int res; + int ret = 0; flash_file_t files[MAX_FILES]; char * filenames[MAX_FILES]; bool info = false; @@ -127,8 +128,10 @@ int main(int argc, char **argv) { uint32_t chipid = 0; res = flash_start_flashing(can_write_bl, serial_port_name, &chipid); - if (res < 0) - return -1; + if (res < 0) { + ret = -1; + goto finish; + } int mem_avail = chipid_to_mem_avail(chipid); if (mem_avail != 0) { @@ -140,32 +143,41 @@ int main(int argc, char **argv) { mem_avail = 256; //we default to a low value } - if (! info) { - for (int i = 0 ; i < num_files; ++i){ - res = flash_load(&files[i], filenames[i], can_write_bl, mem_avail*ONE_KB); - if (res < 0) - return -1; + if (info) + goto finish; - PrintAndLogEx(NORMAL, ""); - } - - PrintAndLogEx(SUCCESS, "\n" _BLUE_("Flashing...")); - - for (int i = 0; i < num_files; i++) { - res = flash_write(&files[i]); - if (res < 0) - return -1; - flash_free(&files[i]); - PrintAndLogEx(NORMAL, "\n"); + for (int i = 0 ; i < num_files; ++i){ + res = flash_load(&files[i], filenames[i], can_write_bl, mem_avail*ONE_KB); + if (res < 0) { + ret = -1; + goto finish; } + PrintAndLogEx(NORMAL, ""); } + + PrintAndLogEx(SUCCESS, "\n" _BLUE_("Flashing...")); + + for (int i = 0; i < num_files; i++) { + res = flash_write(&files[i]); + if (res < 0) { + ret = -1; + goto finish; + } + flash_free(&files[i]); + PrintAndLogEx(NORMAL, "\n"); + } + +finish: res = flash_stop_flashing(); if (res < 0) - return -1; + ret = -1; CloseProxmark(); - PrintAndLogEx(SUCCESS, _BLUE_("All done.")); - PrintAndLogEx(SUCCESS, "\nHave a nice day!"); - return 0; + if (ret==0) + PrintAndLogEx(SUCCESS, _BLUE_("All done.")); + else + PrintAndLogEx(ERR, "Aborted on error."); + PrintAndLogEx(NORMAL, "\nHave a nice day!"); + return ret; } From 8e6258936caea0fda3c6b82d2038cfae66acac66 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 19 Jul 2019 13:18:35 +0200 Subject: [PATCH 0125/1854] make style --- armsrc/iso14443a.c | 8 ++++---- bootrom/bootrom.c | 8 ++++---- client/emv/emvcore.c | 2 +- client/flasher.c | 8 ++++---- tools/analyzesize.py | 1 - 5 files changed, 13 insertions(+), 14 deletions(-) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index bcd898c89..9c76a476d 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -1596,7 +1596,7 @@ static void TransmitFor14443a(const uint8_t *cmd, uint16_t len, uint32_t *timing break; } } - + //iceman test if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { b = (uint16_t)(AT91C_BASE_SSC->SSC_RHR); @@ -1937,7 +1937,7 @@ bool EmLogTrace(uint8_t *reader_data, uint16_t reader_len, uint32_t reader_Start //----------------------------------------------------------------------------- static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receivedResponsePar, uint16_t offset) { uint32_t c = 0; - + if (!iso14443a_active) return false; @@ -1968,7 +1968,7 @@ static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receive return false; } } - + // timeout already in ms + 100ms guard time if (GetTickCount() - receive_timer > timeout + 100) break; @@ -2378,7 +2378,7 @@ void iso14443a_setup(uint8_t fpga_minor_mode) { UartReset(); NextTransferTime = 2 * DELAY_ARM2AIR_AS_READER; iso14a_set_timeout(1060); // 106 * 10ms default - + iso14443a_active = true; } diff --git a/bootrom/bootrom.c b/bootrom/bootrom.c index bda7de2c6..0726f332d 100644 --- a/bootrom/bootrom.c +++ b/bootrom/bootrom.c @@ -164,9 +164,9 @@ void UsbPacketReceived(uint8_t *packet, int len) { offset = (AT91C_IFLASH_NB_OF_PAGES / 2) * AT91C_IFLASH_PAGE_SIZE / sizeof(uint32_t); } for (i = 0 + (64 * j); i < 64 + (64 * j); i++) { - flash_mem[offset+i] = c->d.asDwords[i]; + flash_mem[offset + i] = c->d.asDwords[i]; } - + /* Check that the address that we are supposed to write to is within our allowed region */ if (((flash_address + AT91C_IFLASH_PAGE_SIZE - 1) >= end_addr) || (flash_address < start_addr)) { /* Disallow write */ @@ -175,8 +175,8 @@ void UsbPacketReceived(uint8_t *packet, int len) { } else { efc_bank->EFC_FCR = MC_FLASH_COMMAND_KEY | - MC_FLASH_COMMAND_PAGEN(page_n) | - AT91C_MC_FCMD_START_PROG; + MC_FLASH_COMMAND_PAGEN(page_n) | + AT91C_MC_FCMD_START_PROG; } // Wait until flashing of page finishes diff --git a/client/emv/emvcore.c b/client/emv/emvcore.c index 6657f2ce3..c814eb11e 100644 --- a/client/emv/emvcore.c +++ b/client/emv/emvcore.c @@ -539,7 +539,7 @@ int EMVSearch(EMVCommandChannel channel, bool ActivateField, bool LeaveFieldON, i--; } else { // (1) - card select error, (4) reply timeout, (200) - result length = 0 - if (res == 1 || res == 4 ||res == 200) { + if (res == 1 || res == 4 || res == 200) { if (!LeaveFieldON) DropFieldEx(channel); diff --git a/client/flasher.c b/client/flasher.c index 0db87cb94..25585e7cd 100644 --- a/client/flasher.c +++ b/client/flasher.c @@ -83,7 +83,7 @@ int main(int argc, char **argv) { int res; int ret = 0; flash_file_t files[MAX_FILES]; - char * filenames[MAX_FILES]; + char *filenames[MAX_FILES]; bool info = false; memset(files, 0, sizeof(files)); @@ -146,8 +146,8 @@ int main(int argc, char **argv) { if (info) goto finish; - for (int i = 0 ; i < num_files; ++i){ - res = flash_load(&files[i], filenames[i], can_write_bl, mem_avail*ONE_KB); + for (int i = 0 ; i < num_files; ++i) { + res = flash_load(&files[i], filenames[i], can_write_bl, mem_avail * ONE_KB); if (res < 0) { ret = -1; goto finish; @@ -174,7 +174,7 @@ finish: CloseProxmark(); - if (ret==0) + if (ret == 0) PrintAndLogEx(SUCCESS, _BLUE_("All done.")); else PrintAndLogEx(ERR, "Aborted on error."); diff --git a/tools/analyzesize.py b/tools/analyzesize.py index 70c35de26..4a5211c67 100755 --- a/tools/analyzesize.py +++ b/tools/analyzesize.py @@ -31,4 +31,3 @@ elif action.lower() == "diff": flash = text+data print_increase(flash, flash_ref, "Flash") print_increase(bss, bss_ref, "RAM") - \ No newline at end of file From f4ffa005c9783549192f04fcc0d5d6a77207e6f3 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 19 Jul 2019 14:00:26 +0200 Subject: [PATCH 0126/1854] Travis on osx: testing xcode9.2 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index b81af3d97..723d1c1a2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ compiler: gcc matrix: include: - os: osx - osx_image: xcode9.1 # OS X 10.13.1 + osx_image: xcode9.2 # OS X 10.13 - os: linux dist: xenial sudo: required From 0b38c23ed3161153ad1735ec82decd5f3e35b6d5 Mon Sep 17 00:00:00 2001 From: Eloff Date: Fri, 19 Jul 2019 16:27:08 +0300 Subject: [PATCH 0127/1854] 'hf mf sim' - wrong access rights to write key B in trailer; typo; simple code optimization --- CHANGELOG.md | 1 + armsrc/iso14443a.c | 4 ++-- armsrc/mifaresim.c | 12 +++++------- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c78d813db..95930c002 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Fix 'hf mf sim' - wrong access rights to write key B in trailer (@McEloff) - Add 'hw standalone' to jump to standalone mode from command line or script (@doegox) - Add to 'hf 14a apdu' print apdu and compose apdu (@merlokk) - Change: buggy 'mem read' removed, 'mem save' renamed 'mem dump', can now display too (@doegox) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index b5e612ec9..f905fc536 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -741,7 +741,7 @@ static void Code4bitAnswerAsTag(uint8_t cmd) { //----------------------------------------------------------------------------- // Wait for commands from reader -// stop when button is pressed +// stop when button is pressed or client usb connection resets // or return TRUE when command is captured //----------------------------------------------------------------------------- static bool GetIso14443aCommandFromReader(uint8_t *received, uint8_t *par, int *len) { @@ -1092,7 +1092,7 @@ void SimulateIso14443aTag(uint8_t tagType, uint8_t flags, uint8_t *data) { #define ORDER_SELECT_CL2 30 #define ORDER_EV1_COMP_WRITE 40 #define ORDER_RATS 70 - int order = ORDER_NONE; + uint8_t order = ORDER_NONE; int retval = PM3_SUCCESS; diff --git a/armsrc/mifaresim.c b/armsrc/mifaresim.c index d211b543b..25abcb10a 100644 --- a/armsrc/mifaresim.c +++ b/armsrc/mifaresim.c @@ -56,7 +56,7 @@ static bool IsTrailerAccessAllowed(uint8_t blockNo, uint8_t keytype, uint8_t act } case AC_KEYB_WRITE: { if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("IsTrailerAccessAllowed: AC_KEYB_WRITE"); - return ((keytype == AUTHKEYA && (AC == 0x00 || AC == 0x04)) + return ((keytype == AUTHKEYA && (AC == 0x00 || AC == 0x01)) || (keytype == AUTHKEYB && (AC == 0x04 || AC == 0x03))); } case AC_AC_READ: { @@ -457,8 +457,6 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain) { uint8_t *rats = NULL; uint8_t rats_len = 0; - uint8_t rAUTH_AT[] = {0x00, 0x00, 0x00, 0x00}; - //Here, we collect UID,sector,keytype,NT,AR,NR,NT2,AR2,NR2 // This will be used in the reader-only attack. @@ -713,7 +711,7 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain) { crypto1_word(pcs, cuid ^ nonce, 0); // rAUTH_NT contains prepared nonce for authenticate EmSendCmd(rAUTH_NT, sizeof(rAUTH_NT)); - if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] Reader authenticating for block %d (0x%02x) with key %c - nonce: %02X - ciud: %02X", receivedCmd_dec[1], receivedCmd_dec[1], (cardAUTHKEY == 0) ? 'A' : 'B', rAUTH_AT, cuid); + if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] Reader authenticating for block %d (0x%02x) with key %c - nonce: %02X - ciud: %02X", receivedCmd_dec[1], receivedCmd_dec[1], (cardAUTHKEY == 0) ? 'A' : 'B', rAUTH_NT, cuid); } else { // nested authentication /* @@ -1044,9 +1042,9 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain) { } ans = prng_successor(nonce, 96); - num_to_bytes(ans, 4, rAUTH_AT); - mf_crypto1_encrypt(pcs, rAUTH_AT, 4, response_par); - EmSendCmdPar(rAUTH_AT, 4, response_par); + num_to_bytes(ans, 4, response); + mf_crypto1_encrypt(pcs, response, 4, response_par); + EmSendCmdPar(response, 4, response_par); if (DBGLEVEL >= DBG_EXTENDED) { Dbprintf("[MFEMUL_AUTH1] AUTH COMPLETED for sector %d with key %c. time=%d", From c056e56492db04a8b578ecb34241663927c82cb0 Mon Sep 17 00:00:00 2001 From: slurdge Date: Fri, 19 Jul 2019 18:08:59 +0200 Subject: [PATCH 0128/1854] Add a version command to the bootloader (not activated yet) --- bootrom/bootrom.c | 7 +++++++ include/pm3_cmd.h | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/bootrom/bootrom.c b/bootrom/bootrom.c index 0726f332d..491cafec7 100644 --- a/bootrom/bootrom.c +++ b/bootrom/bootrom.c @@ -126,6 +126,7 @@ void UsbPacketReceived(uint8_t *packet, int len) { DEVICE_INFO_FLAG_CURRENT_MODE_BOOTROM | DEVICE_INFO_FLAG_UNDERSTANDS_START_FLASH | DEVICE_INFO_FLAG_UNDERSTANDS_CHIP_INFO; + //to add later: DEVICE_INFO_FLAG_UNDERSTANDS_VERSION if (common_area.flags.osimage_present) arg0 |= DEVICE_INFO_FLAG_OSIMAGE_PRESENT; @@ -140,6 +141,12 @@ void UsbPacketReceived(uint8_t *packet, int len) { } break; + case CMD_BL_VERSION: { + dont_ack = 1; + arg0 = VERSION_1_0_0; + reply_old(CMD_BL_VERSION, arg0, 0, 0, 0, 0); + } + case CMD_SETUP_WRITE: { /* The temporary write buffer of the embedded flash controller is mapped to the * whole memory region, only the last 8 bits are decoded. diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index d271d3099..55204e1a4 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -208,6 +208,7 @@ typedef struct { #define CMD_HARDWARE_RESET 0x0004 #define CMD_START_FLASH 0x0005 #define CMD_CHIP_INFO 0x0006 +#define CMD_BL_VERSION 0x0007 #define CMD_NACK 0x00fe #define CMD_ACK 0x00ff @@ -536,6 +537,12 @@ typedef struct { /* Set if this device understands the chip info command */ #define DEVICE_INFO_FLAG_UNDERSTANDS_CHIP_INFO (1<<5) +/* Set if this device understands the version command */ +#define DEVICE_INFO_FLAG_UNDERSTANDS_VERSION (1<<6) + +// Different versions here. Each version should increse the number +#define VERSION_1_0_0 1 + /* CMD_START_FLASH may have three arguments: start of area to flash, end of area to flash, optional magic. The bootrom will not allow to overwrite itself unless this magic From 68aa9d631dc1b448eb9ad1311133871dd00f01a8 Mon Sep 17 00:00:00 2001 From: slurdge Date: Fri, 19 Jul 2019 18:21:20 +0200 Subject: [PATCH 0129/1854] Flasher support for versionning Only bootrom with version > 1.0.0 will allow 512K writes --- bootrom/bootrom.c | 2 +- client/flash.c | 24 +++++++++++++++++++++++- include/pm3_cmd.h | 5 ++++- 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/bootrom/bootrom.c b/bootrom/bootrom.c index 491cafec7..030074177 100644 --- a/bootrom/bootrom.c +++ b/bootrom/bootrom.c @@ -143,7 +143,7 @@ void UsbPacketReceived(uint8_t *packet, int len) { case CMD_BL_VERSION: { dont_ack = 1; - arg0 = VERSION_1_0_0; + arg0 = BL_VERSION_1_0_0; reply_old(CMD_BL_VERSION, arg0, 0, 0, 0, 0); } diff --git a/client/flash.c b/client/flash.c index abd81a9de..2c990a80a 100644 --- a/client/flash.c +++ b/client/flash.c @@ -356,8 +356,30 @@ int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t *chipinfo = resp.oldarg[0]; } + int version = BL_VERSION_INVALID; + if (state & DEVICE_INFO_FLAG_UNDERSTANDS_VERSION) { + SendCommandBL(CMD_BL_VERSION, 0, 0, 0, NULL, 0); + PacketResponseNG resp; + WaitForResponse(CMD_BL_VERSION, &resp); + version = resp.oldarg[0]; + if ((version < BL_VERSION_FIRST || version > BL_VERSION_LAST)) { + version = BL_VERSION_INVALID; + } + } else { + PrintAndLogEx(ERR, _RED_("Note: Your bootloader does not understand the new CMD_BL_VERSION command")); + PrintAndLogEx(ERR, _RED_("It is recommended that you update your bootloader") "\n"); + } + + bool allow_512k_writes = false; + if (version == BL_VERSION_INVALID) { + PrintAndLogEx(ERR, _RED_("Note: Your bootloader reported an invalid version number")); + PrintAndLogEx(ERR, _RED_("It is recommended that you update your bootloader") "\n"); + } else if (version >= BL_VERSION_1_0_0) { + allow_512k_writes = true; + } + uint32_t flash_end = FLASH_START + AT91C_IFLASH_PAGE_SIZE * AT91C_IFLASH_NB_OF_PAGES / 2; - if (((*chipinfo & 0xF00) >> 8) > 9) { + if ((((*chipinfo & 0xF00) >> 8) > 9) && allow_512k_writes) { flash_end = FLASH_START + AT91C_IFLASH_PAGE_SIZE * AT91C_IFLASH_NB_OF_PAGES; } diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 55204e1a4..640a3e2bf 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -541,7 +541,10 @@ typedef struct { #define DEVICE_INFO_FLAG_UNDERSTANDS_VERSION (1<<6) // Different versions here. Each version should increse the number -#define VERSION_1_0_0 1 +#define BL_VERSION_INVALID 0 +#define BL_VERSION_1_0_0 1 +#define BL_VERSION_FIRST BL_VERSION_1_0_0 +#define BL_VERSION_LAST BL_VERSION_1_0_0 /* CMD_START_FLASH may have three arguments: start of area to flash, end of area to flash, optional magic. From daae8906675491d2b64bd7346f2fb41473243f82 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 19 Jul 2019 22:59:51 +0200 Subject: [PATCH 0130/1854] Bootrom & flasher changes: * use macros for versions * activate UNDERSTANDS_VERSION in bootrom * fix missing break; bug in bootrom * force flash_load to reject images > 256k if bootloader not up to date * move logic from flasher to flash --- CHANGELOG.md | 1 + bootrom/bootrom.c | 5 ++- client/flash.c | 107 +++++++++++++++++++++++++++++++++++++--------- client/flash.h | 3 +- client/flasher.c | 52 ++-------------------- include/pm3_cmd.h | 14 ++++-- 6 files changed, 105 insertions(+), 77 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 001a53a34..b38e12e3d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Fix support for flashing 512K units with old bootrom (@slurdge/@doegox) - Fix 'hf mf sim' - wrong access rights to write key B in trailer (@McEloff) - Add option -i to flasher to query Pm3 for its memory size (@doegox) - Add support for flashing 512K units (@slurdge) diff --git a/bootrom/bootrom.c b/bootrom/bootrom.c index 030074177..1a3dafc12 100644 --- a/bootrom/bootrom.c +++ b/bootrom/bootrom.c @@ -125,8 +125,8 @@ void UsbPacketReceived(uint8_t *packet, int len) { arg0 = DEVICE_INFO_FLAG_BOOTROM_PRESENT | DEVICE_INFO_FLAG_CURRENT_MODE_BOOTROM | DEVICE_INFO_FLAG_UNDERSTANDS_START_FLASH | - DEVICE_INFO_FLAG_UNDERSTANDS_CHIP_INFO; - //to add later: DEVICE_INFO_FLAG_UNDERSTANDS_VERSION + DEVICE_INFO_FLAG_UNDERSTANDS_CHIP_INFO | + DEVICE_INFO_FLAG_UNDERSTANDS_VERSION; if (common_area.flags.osimage_present) arg0 |= DEVICE_INFO_FLAG_OSIMAGE_PRESENT; @@ -146,6 +146,7 @@ void UsbPacketReceived(uint8_t *packet, int len) { arg0 = BL_VERSION_1_0_0; reply_old(CMD_BL_VERSION, arg0, 0, 0, 0, 0); } + break; case CMD_SETUP_WRITE: { /* The temporary write buffer of the embedded flash controller is mapped to the diff --git a/client/flash.c b/client/flash.c index 2c990a80a..316b53066 100644 --- a/client/flash.c +++ b/client/flash.c @@ -17,6 +17,8 @@ #define BLOCK_SIZE 0x200 +#define FLASHER_VERSION BL_VERSION_1_0_0 + static const uint8_t elf_ident[] = { 0x7f, 'E', 'L', 'F', ELFCLASS32, @@ -24,6 +26,42 @@ static const uint8_t elf_ident[] = { EV_CURRENT }; +static int chipid_to_mem_avail(uint32_t iChipID) { + int mem_avail = 0; + switch ((iChipID & 0xF00) >> 8) { + case 0: + mem_avail = 0; + break; + case 1: + mem_avail = 8; + break; + case 2: + mem_avail = 16; + break; + case 3: + mem_avail = 32; + break; + case 5: + mem_avail = 64; + break; + case 7: + mem_avail = 128; + break; + case 9: + mem_avail = 256; + break; + case 10: + mem_avail = 512; + break; + case 12: + mem_avail = 1024; + break; + case 14: + mem_avail = 2048; + } + return mem_avail; +} + // Turn PHDRs into flasher segments, checking for PHDR sanity and merging adjacent // unaligned segments if needed static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs, uint16_t num_phdrs, uint32_t flash_end) { @@ -339,9 +377,19 @@ static int wait_for_ack(PacketResponseNG *ack) { return 0; } +static void flash_suggest_update_bootloader(void) { + PrintAndLogEx(ERR, _RED_("It is recommended that you first update your bootloader alone,")); + PrintAndLogEx(ERR, _RED_("reboot the Proxmark3 then only update the main firmware") "\n"); +} + +static void flash_suggest_update_flasher(void) { + PrintAndLogEx(ERR, _RED_("It is recommended that you first update your flasher")); +} + // Go into flashing mode -int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t *chipinfo) { +int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t *max_allowed) { uint32_t state; + uint32_t chipinfo = 0; if (enter_bootloader(serial_port_name) < 0) return -1; @@ -353,7 +401,7 @@ int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t SendCommandBL(CMD_CHIP_INFO, 0, 0, 0, NULL, 0); PacketResponseNG resp; WaitForResponse(CMD_CHIP_INFO, &resp); - *chipinfo = resp.oldarg[0]; + chipinfo = resp.oldarg[0]; } int version = BL_VERSION_INVALID; @@ -362,32 +410,51 @@ int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t PacketResponseNG resp; WaitForResponse(CMD_BL_VERSION, &resp); version = resp.oldarg[0]; - if ((version < BL_VERSION_FIRST || version > BL_VERSION_LAST)) { + if ((BL_VERSION_MAJOR(version) < BL_VERSION_FIRST_MAJOR) || (BL_VERSION_MAJOR(version) > BL_VERSION_LAST_MAJOR)) { + // version info seems fishy version = BL_VERSION_INVALID; + PrintAndLogEx(ERR, _RED_("Note: Your bootloader reported an invalid version number")); + flash_suggest_update_bootloader(); + // + } else if (BL_VERSION_MAJOR(version) < BL_VERSION_MAJOR(FLASHER_VERSION)) { + PrintAndLogEx(ERR, _RED_("Note: Your bootloader reported a version older than this flasher")); + flash_suggest_update_bootloader(); + } else if (BL_VERSION_MAJOR(version) > BL_VERSION_MAJOR(FLASHER_VERSION)) { + PrintAndLogEx(ERR, _RED_("Note: Your bootloader is more recent than this flasher")); + flash_suggest_update_flasher(); } } else { PrintAndLogEx(ERR, _RED_("Note: Your bootloader does not understand the new CMD_BL_VERSION command")); - PrintAndLogEx(ERR, _RED_("It is recommended that you update your bootloader") "\n"); - } - - bool allow_512k_writes = false; - if (version == BL_VERSION_INVALID) { - PrintAndLogEx(ERR, _RED_("Note: Your bootloader reported an invalid version number")); - PrintAndLogEx(ERR, _RED_("It is recommended that you update your bootloader") "\n"); - } else if (version >= BL_VERSION_1_0_0) { - allow_512k_writes = true; + flash_suggest_update_bootloader(); } uint32_t flash_end = FLASH_START + AT91C_IFLASH_PAGE_SIZE * AT91C_IFLASH_NB_OF_PAGES / 2; - if ((((*chipinfo & 0xF00) >> 8) > 9) && allow_512k_writes) { - flash_end = FLASH_START + AT91C_IFLASH_PAGE_SIZE * AT91C_IFLASH_NB_OF_PAGES; + *max_allowed = 256; + + int mem_avail = chipid_to_mem_avail(chipinfo); + if (mem_avail != 0) { + PrintAndLogEx(NORMAL, "Available memory on this board: %uK bytes\n", mem_avail); + if (mem_avail > 256) { + if (BL_VERSION_MAJOR(version) < BL_VERSION_MAJOR(BL_VERSION_1_0_0)) { + PrintAndLogEx(ERR, _RED_("Your bootloader does not support writing above 256k")); + flash_suggest_update_bootloader(); + } else { + flash_end = FLASH_START + AT91C_IFLASH_PAGE_SIZE * AT91C_IFLASH_NB_OF_PAGES; + *max_allowed = mem_avail; + } + } + } else { + PrintAndLogEx(NORMAL, "Available memory on this board: "_RED_("UNKNOWN")"\n"); + PrintAndLogEx(ERR, _RED_("Note: Your bootloader does not understand the new CHIP_INFO command")); + flash_suggest_update_bootloader(); + } + + if (enable_bl_writes) { + PrintAndLogEx(INFO, "Permitted flash range: 0x%08x-0x%08x", FLASH_START, flash_end); + } else { + PrintAndLogEx(INFO, "Permitted flash range: 0x%08x-0x%08x", BOOTLOADER_END, flash_end); } - - PrintAndLogEx(INFO, "End of flash: 0x%08x", flash_end); - if (state & DEVICE_INFO_FLAG_UNDERSTANDS_START_FLASH) { - // This command is stupid. Why the heck does it care which area we're - // flashing, as long as it's not the bootloader area? The mind boggles. PacketResponseNG resp; if (enable_bl_writes) { @@ -398,7 +465,7 @@ int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t return wait_for_ack(&resp); } else { PrintAndLogEx(ERR, _RED_("Note: Your bootloader does not understand the new START_FLASH command")); - PrintAndLogEx(ERR, _RED_("It is recommended that you update your bootloader") "\n"); + flash_suggest_update_bootloader(); } return 0; } diff --git a/client/flash.h b/client/flash.h index cc0387bf3..4f05029dc 100644 --- a/client/flash.h +++ b/client/flash.h @@ -38,10 +38,9 @@ typedef struct { } flash_file_t; int flash_load(flash_file_t *ctx, const char *name, int can_write_bl, int flash_size); -int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t *chipid); +int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t *max_allowed); int flash_write(flash_file_t *ctx); void flash_free(flash_file_t *ctx); int flash_stop_flashing(void); - #endif diff --git a/client/flasher.c b/client/flasher.c index 25585e7cd..97e3d7a1c 100644 --- a/client/flasher.c +++ b/client/flasher.c @@ -41,42 +41,6 @@ static void usage(char *argv0) { #endif } -int chipid_to_mem_avail(uint32_t iChipID) { - int mem_avail = 0; - switch ((iChipID & 0xF00) >> 8) { - case 0: - mem_avail = 0; - break; - case 1: - mem_avail = 8; - break; - case 2: - mem_avail = 16; - break; - case 3: - mem_avail = 32; - break; - case 5: - mem_avail = 64; - break; - case 7: - mem_avail = 128; - break; - case 9: - mem_avail = 256; - break; - case 10: - mem_avail = 512; - break; - case 12: - mem_avail = 1024; - break; - case 14: - mem_avail = 2048; - } - return mem_avail; -} - int main(int argc, char **argv) { int can_write_bl = 0; int num_files = 0; @@ -126,28 +90,18 @@ int main(int argc, char **argv) { return -1; } - uint32_t chipid = 0; - res = flash_start_flashing(can_write_bl, serial_port_name, &chipid); + uint32_t max_allowed = 0; + res = flash_start_flashing(can_write_bl, serial_port_name, &max_allowed); if (res < 0) { ret = -1; goto finish; } - int mem_avail = chipid_to_mem_avail(chipid); - if (mem_avail != 0) { - PrintAndLogEx(NORMAL, "Available memory on this board: %uK bytes\n", mem_avail); - } else { - PrintAndLogEx(NORMAL, "Available memory on this board: "_RED_("UNKNOWN")"\n"); - PrintAndLogEx(ERR, _RED_("Note: Your bootloader does not understand the new CHIP_INFO command")); - PrintAndLogEx(ERR, _RED_("It is recommended that you update your bootloader") "\n"); - mem_avail = 256; //we default to a low value - } - if (info) goto finish; for (int i = 0 ; i < num_files; ++i) { - res = flash_load(&files[i], filenames[i], can_write_bl, mem_avail * ONE_KB); + res = flash_load(&files[i], filenames[i], can_write_bl, max_allowed * ONE_KB); if (res < 0) { ret = -1; goto finish; diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 640a3e2bf..39edb2b61 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -540,11 +540,17 @@ typedef struct { /* Set if this device understands the version command */ #define DEVICE_INFO_FLAG_UNDERSTANDS_VERSION (1<<6) -// Different versions here. Each version should increse the number +#define BL_VERSION_MAJOR(version) ((uint32_t)(version) >> 22) +#define BL_VERSION_MINOR(version) (((uint32_t)(version) >> 12) & 0x3ff) +#define BL_VERSION_PATCH(version) ((uint32_t)(version) & 0xfff) +#define BL_MAKE_VERSION(major, minor, patch) (((major) << 22) | ((minor) << 12) | (patch)) +// Some boundaries to distinguish valid versions from corrupted info +#define BL_VERSION_FIRST_MAJOR 1 +#define BL_VERSION_LAST_MAJOR 99 #define BL_VERSION_INVALID 0 -#define BL_VERSION_1_0_0 1 -#define BL_VERSION_FIRST BL_VERSION_1_0_0 -#define BL_VERSION_LAST BL_VERSION_1_0_0 +// Different versions here. Each version should increase the numbers +#define BL_VERSION_1_0_0 BL_MAKE_VERSION(1, 0, 0) + /* CMD_START_FLASH may have three arguments: start of area to flash, end of area to flash, optional magic. From 5c3676ad8133609edc63b3c6d23e04550bccd239 Mon Sep 17 00:00:00 2001 From: cjbrigato Date: Mon, 22 Jul 2019 22:56:06 +0200 Subject: [PATCH 0131/1854] ADD: Early SPIFFS implementation see #257, UPDATE HF_COLIN accordingly --- armsrc/Makefile | 2 + armsrc/Standalone/hf_colin.c | 105 +- armsrc/Standalone/hf_colin.h | 3 +- armsrc/appmain.c | 129 ++ armsrc/flashmem.c | 1 + armsrc/flashmem.h | 1 + armsrc/spiffs.c | 606 +++++++++ armsrc/spiffs.h | 861 +++++++++++++ armsrc/spiffs_cache.c | 319 +++++ armsrc/spiffs_check.c | 1008 +++++++++++++++ armsrc/spiffs_config.h | 388 ++++++ armsrc/spiffs_gc.c | 606 +++++++++ armsrc/spiffs_hydrogen.c | 1452 +++++++++++++++++++++ armsrc/spiffs_nucleus.c | 2365 ++++++++++++++++++++++++++++++++++ armsrc/spiffs_nucleus.h | 842 ++++++++++++ armsrc/string.c | 98 ++ armsrc/string.h | 4 + client/Makefile | 1 + client/cmddata.c | 6 +- client/cmdflashmem.c | 3 +- client/cmdflashmem.h | 1 + client/cmdflashmemspiffs.c | 457 +++++++ client/cmdflashmemspiffs.h | 30 + client/cmdhffelica.c | 2 +- client/cmdhficlass.c | 4 +- client/cmdhflegic.c | 6 +- client/cmdhfmf.c | 2 +- client/cmdhfmfu.c | 2 +- client/cmdlfcotag.c | 2 +- client/cmdlfem4x.c | 2 +- client/cmdlft55xx.c | 2 +- client/cmdtrace.c | 4 +- client/comms.c | 6 +- client/comms.h | 4 +- client/scripting.c | 4 +- include/pm3_cmd.h | 34 + 36 files changed, 9258 insertions(+), 104 deletions(-) create mode 100644 armsrc/spiffs.c create mode 100644 armsrc/spiffs.h create mode 100644 armsrc/spiffs_cache.c create mode 100644 armsrc/spiffs_check.c create mode 100644 armsrc/spiffs_config.h create mode 100644 armsrc/spiffs_gc.c create mode 100644 armsrc/spiffs_hydrogen.c create mode 100644 armsrc/spiffs_nucleus.c create mode 100644 armsrc/spiffs_nucleus.h create mode 100644 client/cmdflashmemspiffs.c create mode 100644 client/cmdflashmemspiffs.h diff --git a/armsrc/Makefile b/armsrc/Makefile index 6d3921084..105a880a7 100644 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@ -34,6 +34,7 @@ SRC_CRAPTO1 = crypto1.c des.c desfire_key.c desfire_crypto.c mifaredesfire.c aes SRC_CRC = crc.c crc16.c crc32.c SRC_ICLASS = iclass.c optimized_cipher.c SRC_LEGIC = legicrf.c legicrfsim.c legic_prng.c +SRC_SPIFFS = spiffs.c spiffs_cache.c spiffs_check.c spiffs_gc.c spiffs_nucleus.c spiffs_hydrogen.c # SRC_BEE = bee.c # RDV40 related hardware support @@ -97,6 +98,7 @@ THUMBSRC = start.c \ $(SRC_SMARTCARD) \ $(SRC_FPC) \ $(SRC_HITAG) \ + $(SRC_SPIFFS) \ appmain.c \ printf.c \ commonutil.c \ diff --git a/armsrc/Standalone/hf_colin.c b/armsrc/Standalone/hf_colin.c index d74eaeb95..2189f1146 100644 --- a/armsrc/Standalone/hf_colin.c +++ b/armsrc/Standalone/hf_colin.c @@ -1,5 +1,5 @@ //----------------------------------------------------------------------------- -// Colin Brigato, 2016, 2017 +// Colin Brigato, 2016, 2017, 2018, 2019 // Christian Herrmann, 2017 // // This code is licensed to you under the terms of the GNU GPL, version 2 or, @@ -13,6 +13,7 @@ #define MF1KSZ 1024 #define MF1KSZSIZE 64 #define AUTHENTICATION_TIMEOUT 848 +#define HFCOLIN_LASTTAG_SYMLINK "hf_colin/lasttag.bin" uint8_t cjuid[10]; uint32_t cjcuid; @@ -92,49 +93,26 @@ void ReadLastTagFromFlash() { LED_B_ON(); LED_C_ON(); LED_D_ON(); - uint32_t startidx = 0; uint16_t len = 1024; + size_t size = len; DbprintfEx(FLAG_NEWLINE, "Button HELD ! Using LAST Known TAG for Simulation..."); cjSetCursLeft(); - size_t size = len; uint8_t *mem = BigBuf_malloc(size); - FlashmemSetSpiBaudrate(24000000); + //this one will handle filetype (symlink or not) and resolving by itself + rdv40_spiffs_read_as_filetype((char *)HFCOLIN_LASTTAG_SYMLINK,(uint8_t *)mem,len, RDV40_SPIFFS_SAFETY_SAFE); - if (!FlashInit()) { - return; - } - Flash_CheckBusy(BUSY_TIMEOUT); + emlSetMem(mem, 0, 64); - uint32_t start_time = GetTickCount(); - uint32_t delta_time = 0; - - for (size_t i = 0; i < len; i += size) { - len = MIN((len - i), size); - uint16_t isok = Flash_ReadDataCont(startidx + i, mem, len); - if (isok == len) { - emlSetMem(mem, 0, 64); - } else { - DbprintfEx(FLAG_NEWLINE, "FlashMem reading failed | %d | %d", len, isok); - cjSetCursLeft(); - FlashStop(); - SpinOff(100); - return; - } - } - delta_time = GetTickCountDelta(start_time); DbprintfEx(FLAG_NEWLINE, "[OK] Last tag recovered from FLASHMEM set to emulator"); cjSetCursLeft(); - DbprintfEx(FLAG_NEWLINE, "%s[IN]%s %s%dms%s for TAG_FLASH_READ", _XGREEN_, _XWHITE_, _XYELLOW_, delta_time, _XWHITE_); - cjSetCursLeft(); - FlashStop(); SpinOff(0); return; } -void WriteTagToFlash(uint8_t index, size_t size) { +void WriteTagToFlash(uint32_t uid, size_t size) { SpinOff(0); LED_A_ON(); LED_B_ON(); @@ -142,61 +120,23 @@ void WriteTagToFlash(uint8_t index, size_t size) { LED_D_ON(); uint32_t len = size; - uint32_t bytes_sent = 0; - uint32_t bytes_remaining = len; - uint8_t data[(size * (16 * 64)) / 1024]; - uint8_t buff[PAGESIZE]; emlGetMem(data, 0, (size * 64) / 1024); + char dest[SPIFFS_OBJ_NAME_LEN]; + uint8_t buid[4]; + num_to_bytes(uid,4,buid); + sprintf(dest,"hf_colin/mf_%02x%02x%02x%02x.bin",buid[0],buid[1],buid[2],buid[3]); + + // TODO : by using safe function for multiple writes we are both breaking cache mecanisms and making useless and unoptimized mount operations + // we should manage at out level the mount status before and after the whole standalone mode + rdv40_spiffs_write((char *)dest,(uint8_t *)data,len, RDV40_SPIFFS_SAFETY_SAFE); + // lastag will only contain filename/path to last written tag file so we don't loose time or space. + rdv40_spiffs_make_symlink((char *)dest,(char *)HFCOLIN_LASTTAG_SYMLINK,RDV40_SPIFFS_SAFETY_SAFE); - FlashmemSetSpiBaudrate(48000000); - - if (!FlashInit()) { - return; - } - - Flash_CheckBusy(BUSY_TIMEOUT); - Flash_WriteEnable(); - Flash_Erase4k(0, 0); - - uint32_t start_time = GetTickCount(); - uint32_t delta_time = 0; - - while (bytes_remaining > 0) { - Flash_CheckBusy(BUSY_TIMEOUT); - Flash_WriteEnable(); - - uint32_t bytes_in_packet = MIN(FLASH_MEM_BLOCK_SIZE, bytes_remaining); - - memcpy(buff, data + bytes_sent, bytes_in_packet); - - bytes_remaining -= bytes_in_packet; - uint16_t res = Flash_WriteDataCont(bytes_sent + (index * size), buff, bytes_in_packet); - bytes_sent += bytes_in_packet; - - uint8_t isok = (res == bytes_in_packet) ? 1 : 0; - - if (!isok) { - DbprintfEx(FLAG_NEWLINE, "FlashMem write FAILEd [offset %u]", bytes_sent); - cjSetCursLeft(); - SpinOff(100); - return; - } - - LED_A_INV(); - LED_B_INV(); - LED_C_INV(); - LED_D_INV(); - } - delta_time = GetTickCountDelta(start_time); - - DbprintfEx(FLAG_NEWLINE, "[OK] TAG WRITTEN TO FLASH ! [0-to offset %u]", bytes_sent); + DbprintfEx(FLAG_NEWLINE, "[OK] TAG WRITTEN TO FLASH !"); cjSetCursLeft(); - DbprintfEx(FLAG_NEWLINE, "%s[IN]%s %s%dms%s for TAG_FLASH_WRITE", _XGREEN_, _XWHITE_, _XYELLOW_, delta_time, _XWHITE_); - cjSetCursLeft(); - FlashStop(); SpinOff(0); return; } @@ -429,7 +369,7 @@ failtag: //----------------------------------------------------------------------------- // also we could avoid first UID check for every block - // then let's expose this “optimal case” of “well known vigik schemes” : + // then let's expose this optimal case of well known vigik schemes : for (uint8_t type = 0; type < 2 && !err && !trapped; type++) { for (int sec = 0; sec < sectorsCnt && !err && !trapped; ++sec) { key = cjat91_saMifareChkKeys(sec * 4, type, NULL, size, &keyBlock[0], &key64); @@ -437,7 +377,7 @@ failtag: if (key == -1) { err = 1; allKeysFound = false; - // used in “portable” imlementation on microcontroller: it reports back the fail and open the standalone lock + // used in portable imlementation on microcontroller: it reports back the fail and open the standalone lock // reply_old(CMD_CJB_FSMSTATE_MENU, 0, 0, 0, 0, 0); break; } else if (key == -2) { @@ -755,10 +695,9 @@ failtag: cjSetCursLeft(); cjSetCursLeft(); - WriteTagToFlash(0, 1024); + WriteTagToFlash(cjcuid, 1024); readysim: - // SIM ? cjSetCursLeft(); DbprintfEx(FLAG_NEWLINE, "-> We launch Emulation ->"); @@ -1022,6 +961,8 @@ void saMifareMakeTag(void) { } } + +//TODO : make this work either for a Gen1a or for a block 0 direct write all transparently //----------------------------------------------------------------------------- // Matt's StandAlone mod. // Work with "magic Chinese" card (email him: ouyangweidaxian@live.cn) diff --git a/armsrc/Standalone/hf_colin.h b/armsrc/Standalone/hf_colin.h index 9068e2d09..e669f0417 100644 --- a/armsrc/Standalone/hf_colin.h +++ b/armsrc/Standalone/hf_colin.h @@ -30,6 +30,7 @@ #include "vtsend.h" #include "apps.h" #include "printf.h" +#include "spiffs.h" #define _XRED_ "\x1b[31m" #define _XGREEN_ "\x1b[32m" @@ -44,7 +45,7 @@ int cjat91_saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace, ui int e_MifareECardLoad(uint32_t numofsectors, uint8_t keytype); void saMifareMakeTag(void); int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain); -void WriteTagToFlash(uint8_t index, size_t size); +void WriteTagToFlash(uint32_t uid, size_t size); const char clearTerm[8] = {0x1b, 0x5b, 0x48, 0x1b, 0x5b, 0x32, 0x4a, '\0'}; diff --git a/armsrc/appmain.c b/armsrc/appmain.c index d9c17e3b3..59174153f 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -43,6 +43,7 @@ #ifdef WITH_FLASH #include "flashmem.h" +#include "spiffs.h" #endif //============================================================================= @@ -1589,6 +1590,134 @@ static void PacketReceived(PacketCommandNG *packet) { break; } #ifdef WITH_FLASH + case CMD_SPIFFS_TEST: { + test_spiffs(); + break; + } + case CMD_SPIFFS_MOUNT: { + rdv40_spiffs_lazy_mount(); + break; + } + case CMD_SPIFFS_UNMOUNT: { + rdv40_spiffs_lazy_unmount(); + break; + } + case CMD_SPIFFS_PRINT_TREE: { + rdv40_spiffs_safe_print_tree(false); + break; + } + case CMD_SPIFFS_PRINT_FSINFO: { + rdv40_spiffs_safe_print_fsinfos(); + break; + } + case CMD_SPIFFS_DOWNLOAD: { + LED_B_ON(); + uint8_t filename[32]; + uint8_t *pfilename = packet->data.asBytes; + memcpy(filename,pfilename,SPIFFS_OBJ_NAME_LEN); + if (DBGLEVEL > 1) Dbprintf("> Filename received for spiffs dump : %s", filename); + + //uint32_t size = 0; + //rdv40_spiffs_stat((char *)filename, (uint32_t *)size,RDV40_SPIFFS_SAFETY_SAFE); + uint32_t size = packet->oldarg[1]; + //uint8_t buff[size]; + + uint8_t *buff = BigBuf_malloc(size); + rdv40_spiffs_read_as_filetype((char *)filename,(uint8_t *)buff, size, RDV40_SPIFFS_SAFETY_SAFE); + + // arg0 = filename + // arg1 = size + // arg2 = RFU + + for (size_t i = 0; i < size; i += PM3_CMD_DATA_SIZE) { + size_t len = MIN((size - i), PM3_CMD_DATA_SIZE); + int result = reply_old(CMD_SPIFFS_DOWNLOADED, i, len, 0, buff + i, len); + if (result != PM3_SUCCESS) + Dbprintf("transfer to client failed :: | bytes between %d - %d (%d) | result: %d", i, i + len, len, result); + } + // Trigger a finish downloading signal with an ACK frame + reply_old(CMD_ACK, 1, 0, 0, 0, 0); + LED_B_OFF(); + break; + } + case CMD_SPIFFS_STAT:{ + LED_B_ON(); + uint8_t filename[32]; + uint8_t *pfilename = packet->data.asBytes; + memcpy(filename,pfilename,SPIFFS_OBJ_NAME_LEN); + if (DBGLEVEL > 1) Dbprintf("> Filename received for spiffs STAT : %s", filename); + int changed = rdv40_spiffs_lazy_mount(); + uint32_t size = size_in_spiffs((char *)filename); + if (changed) rdv40_spiffs_lazy_unmount(); + reply_old(CMD_ACK, size, 0, 0, 0, 0); + LED_B_OFF(); + break; + } + case CMD_SPIFFS_REMOVE:{ + LED_B_ON(); + uint8_t filename[32]; + uint8_t *pfilename = packet->data.asBytes; + memcpy(filename,pfilename,SPIFFS_OBJ_NAME_LEN); + if (DBGLEVEL > 1) Dbprintf("> Filename received for spiffs REMOVE : %s", filename); + rdv40_spiffs_remove((char *) filename,RDV40_SPIFFS_SAFETY_SAFE); + LED_B_OFF(); + break; + } + case CMD_SPIFFS_RENAME:{ + LED_B_ON(); + uint8_t srcfilename[32]; + uint8_t destfilename[32]; + uint8_t *pfilename = packet->data.asBytes; + char *token; + token = strtok((char *)pfilename, ","); + strcpy((char*)srcfilename,token); + token = strtok(NULL,","); + strcpy((char *)destfilename,token); + if (DBGLEVEL > 1) Dbprintf("> Filename received as source for spiffs RENAME : %s", srcfilename); + if (DBGLEVEL > 1) Dbprintf("> Filename received as destination for spiffs RENAME : %s", destfilename); + rdv40_spiffs_rename((char *) srcfilename,(char *)destfilename,RDV40_SPIFFS_SAFETY_SAFE); + LED_B_OFF(); + break; + } + case CMD_SPIFFS_COPY:{ + LED_B_ON(); + uint8_t srcfilename[32]; + uint8_t destfilename[32]; + uint8_t *pfilename = packet->data.asBytes; + char *token; + token = strtok((char *)pfilename, ","); + strcpy((char*)srcfilename,token); + token = strtok(NULL,","); + strcpy((char *)destfilename,token); + if (DBGLEVEL > 1) Dbprintf("> Filename received as source for spiffs COPY : %s", srcfilename); + if (DBGLEVEL > 1) Dbprintf("> Filename received as destination for spiffs COPY : %s", destfilename); + rdv40_spiffs_copy((char *) srcfilename,(char *)destfilename,RDV40_SPIFFS_SAFETY_SAFE); + LED_B_OFF(); + break; + } + case CMD_SPIFFS_WRITE: { + LED_B_ON(); + uint8_t filename[32]; + uint32_t append = packet->oldarg[0]; + uint32_t size = packet->oldarg[1]; + uint8_t *data = packet->data.asBytes; + + //rdv40_spiffs_lazy_mount(); + + uint8_t *pfilename = packet->data.asBytes; + memcpy(filename,pfilename,SPIFFS_OBJ_NAME_LEN); + data+=SPIFFS_OBJ_NAME_LEN; + + if (DBGLEVEL > 1) Dbprintf("> Filename received for spiffs WRITE : %s with APPEND SET TO : %d", filename, append); + if (!append) { + rdv40_spiffs_write((char *) filename,(uint8_t *)data, size, RDV40_SPIFFS_SAFETY_SAFE); + } else { + rdv40_spiffs_append((char *) filename,(uint8_t *)data, size, RDV40_SPIFFS_SAFETY_SAFE); + } + reply_old(CMD_ACK, 1, 0, 0, 0, 0); + LED_B_OFF(); + break; + } case CMD_FLASHMEM_SET_SPIBAUDRATE: { FlashmemSetSpiBaudrate(packet->oldarg[0]); break; diff --git a/armsrc/flashmem.c b/armsrc/flashmem.c index ad4861ce3..c53169255 100644 --- a/armsrc/flashmem.c +++ b/armsrc/flashmem.c @@ -554,6 +554,7 @@ void Flashmem_print_status(void) { } void Flashmem_print_info(void) { + if (!FlashInit()) return; DbpString(_BLUE_("Flash memory dictionary loaded")); diff --git a/armsrc/flashmem.h b/armsrc/flashmem.h index 59d3bef9c..26d2d974d 100644 --- a/armsrc/flashmem.h +++ b/armsrc/flashmem.h @@ -142,5 +142,6 @@ 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); void Flashmem_print_status(void); void Flashmem_print_info(void); +uint16_t FlashSendLastByte(uint32_t data); #endif diff --git a/armsrc/spiffs.c b/armsrc/spiffs.c new file mode 100644 index 000000000..b5db53c42 --- /dev/null +++ b/armsrc/spiffs.c @@ -0,0 +1,606 @@ +//----------------------------------------------------------------------------- +// Colin J. Brigato, 2019 - [colin@brigato.fr] +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// SPIFFS api for RDV40 Integration by Colin Brigato +//----------------------------------------------------------------------------- + +#define SPIFFS_CFG_PHYS_SZ (1024 * 128) +#define SPIFFS_CFG_PHYS_ERASE_SZ (4 * 1024) +#define SPIFFS_CFG_PHYS_ADDR (0) +#define SPIFFS_CFG_LOG_PAGE_SZ (256) +#define SPIFFS_CFG_LOG_BLOCK_SZ (4 * 1024) +#define LOG_PAGE_SIZE 256 +#define RDV40_SPIFFS_WORKBUF_SZ (LOG_PAGE_SIZE * 2) +// Experimental : 4 full pages(LOG_PAGE_SIZE + file descript size) of cache for +// Reading and writing if reading cache is stable, writing cache may need more +// testing regarding power loss, page consistency checks, Garbage collector +// Flushing handling... in doubt, use maximal safetylevel as, in most of the +// case, will ensure a flush by rollbacking to previous Unmounted state +#define RDV40_SPIFFS_CACHE_SZ ((LOG_PAGE_SIZE + 32) * 4) +#define SPIFFS_FD_SIZE (32) +#define RDV40_SPIFFS_MAX_FD (2) +#define RDV40_SPIFFS_FDBUF_SZ (SPIFFS_FD_SIZE * RDV40_SPIFFS_MAX_FD) + +#define RDV40_SPIFFS_LAZY_HEADER \ + int changed = 0; \ + if ((level == RDV40_SPIFFS_SAFETY_LAZY) || (level == RDV40_SPIFFS_SAFETY_SAFE)) { \ + changed = rdv40_spiffs_lazy_mount(); \ + } + +#define RDV40_SPIFFS_SAFE_FOOTER \ + if (level == RDV40_SPIFFS_SAFETY_SAFE) { \ + changed = rdv40_spiffs_lazy_mount_rollback(changed); \ + } \ + return changed; + +#define RDV40_SPIFFS_SAFE_FUNCTION(RDV40_SPIFFS_LLFUNCT) \ + RDV40_SPIFFS_LAZY_HEADER \ + RDV40_SPIFFS_LLFUNCT \ + RDV40_SPIFFS_SAFE_FOOTER + +#include "spiffs.h" + +///// FLASH LEVEL R/W/E operations for feeding SPIFFS Driver///////////////// +static s32_t rdv40_spiffs_llread(u32_t addr, u32_t size, u8_t *dst) { + + if (!Flash_ReadData(addr, dst, size)) { + return 128; + } + return SPIFFS_OK; +} + +static s32_t rdv40_spiffs_llwrite(u32_t addr, u32_t size, u8_t *src) { + + if (!FlashInit()) { + return 129; + } + Flash_Write(addr, src, size); + return SPIFFS_OK; +} + +static s32_t rdv40_spiffs_llerase(u32_t addr, u32_t size) { + + if (!FlashInit()) { + return 130; + } + + uint32_t bytes_erased = 0, bytes_remaining = size; + while (bytes_remaining > 0) { + + addr += bytes_erased; + Flash_CheckBusy(BUSY_TIMEOUT); + Flash_WriteEnable(); + FlashSendByte(SECTORERASE); + Flash_TransferAdresse(addr); + FlashSendLastByte(0); + + bytes_remaining -= 4096; + bytes_erased += 4096; + } + + Flash_CheckBusy(BUSY_TIMEOUT); + FlashStop(); + + return SPIFFS_OK; +} + +//////////////////////////////////////////////////////////////////////////////// + +////// SPIFFS LOW LEVEL OPERATIONS ///////////////////////////////////////////// +static u8_t spiffs_work_buf[RDV40_SPIFFS_WORKBUF_SZ]; +static u8_t spiffs_fds[RDV40_SPIFFS_FDBUF_SZ]; +static u8_t spiffs_cache_buf[RDV40_SPIFFS_CACHE_SZ]; + +static spiffs fs; + +static enum spiffs_mount_status { + RDV40_SPIFFS_UNMOUNTED, + RDV40_SPIFFS_MOUNTED, + RDV40_SPIFFS_UNKNOWN +} RDV40_SPIFFS_MOUNT_STATUS; + +int rdv40_spiffs_mounted() { + int ret = 0; + + switch (RDV40_SPIFFS_MOUNT_STATUS) { + case RDV40_SPIFFS_MOUNTED: + ret = 1; + break; + case RDV40_SPIFFS_UNMOUNTED: + case RDV40_SPIFFS_UNKNOWN: + default: + ret = 0; + } + + return ret; +} + +int rdv40_spiffs_mount() { + if (rdv40_spiffs_mounted()) { + Dbprintf("ERR: SPIFFS already mounted !"); + return SPIFFS_ERR_MOUNTED; + } + + spiffs_config cfg; + cfg.hal_read_f = rdv40_spiffs_llread; + cfg.hal_write_f = rdv40_spiffs_llwrite; + cfg.hal_erase_f = rdv40_spiffs_llerase; + + // uncached version + // int ret = SPIFFS_mount(&fs, &cfg, spiffs_work_buf, spiffs_fds, + // sizeof(spiffs_fds), 0, 0, 0); cached version, experimental + int ret = SPIFFS_mount(&fs, &cfg, spiffs_work_buf, spiffs_fds, sizeof(spiffs_fds), spiffs_cache_buf, + sizeof(spiffs_cache_buf), 0); + if (ret == SPIFFS_OK) { + RDV40_SPIFFS_MOUNT_STATUS = RDV40_SPIFFS_MOUNTED; + } + return ret; +} + +int rdv40_spiffs_unmount() { + if (!rdv40_spiffs_mounted()) { + Dbprintf("ERR: SPIFFS not mounted !"); + return SPIFFS_ERR_NOT_MOUNTED; + } + + SPIFFS_clearerr(&fs); + SPIFFS_unmount(&fs); + + int ret = SPIFFS_errno(&fs); + if (ret == SPIFFS_OK) { + RDV40_SPIFFS_MOUNT_STATUS = RDV40_SPIFFS_UNMOUNTED; + } + return ret; +} +//////////////////////////////////////////////////////////////////////////////// + +///// Base RDV40_SPIFFS_SAFETY_NORMAL operations//////////////////////////////// + +void write_to_spiffs(const char *filename, uint8_t *src, uint32_t size) { + spiffs_file fd = SPIFFS_open(&fs, filename, SPIFFS_CREAT | SPIFFS_TRUNC | SPIFFS_RDWR, 0); + if (SPIFFS_write(&fs, fd, src, size) < 0) + Dbprintf("errno %i\n", SPIFFS_errno(&fs)); + SPIFFS_close(&fs, fd); +} + +void append_to_spiffs(const char *filename, uint8_t *src, uint32_t size) { + spiffs_file fd = SPIFFS_open(&fs, filename, SPIFFS_APPEND | SPIFFS_RDWR, 0); + if (SPIFFS_write(&fs, fd, src, size) < 0) + Dbprintf("errno %i\n", SPIFFS_errno(&fs)); + SPIFFS_close(&fs, fd); +} + +void read_from_spiffs(const char *filename, uint8_t *dst, uint32_t size) { + spiffs_file fd = SPIFFS_open(&fs, filename, SPIFFS_RDWR, 0); + if (SPIFFS_read(&fs, fd, dst, size) < 0) + Dbprintf("errno %i\n", SPIFFS_errno(&fs)); + SPIFFS_close(&fs, fd); +} + +void rename_in_spiffs(const char *old_filename, const char *new_filename) { + if (SPIFFS_rename(&fs, old_filename, new_filename) < 0) + Dbprintf("errno %i\n", SPIFFS_errno(&fs)); +} + +void remove_from_spiffs(const char *filename) { + if (SPIFFS_remove(&fs, filename) < 0) + Dbprintf("errno %i\n", SPIFFS_errno(&fs)); +} + +spiffs_stat stat_in_spiffs(const char *filename) { + spiffs_stat s; + if (SPIFFS_stat(&fs, filename, &s) < 0) + Dbprintf("errno %i\n", SPIFFS_errno(&fs)); + return s; +} + +uint32_t size_in_spiffs(const char *filename) { + spiffs_stat s = stat_in_spiffs(filename); + return s.size; +} + +rdv40_spiffs_fsinfo info_of_spiffs() { + rdv40_spiffs_fsinfo fsinfo; + fsinfo.blockSize = SPIFFS_CFG_LOG_BLOCK_SZ; + fsinfo.pageSize = LOG_PAGE_SIZE; + fsinfo.maxOpenFiles = RDV40_SPIFFS_MAX_FD; + fsinfo.maxPathLenght = SPIFFS_OBJ_NAME_LEN; + if (SPIFFS_info(&fs, &fsinfo.totalBytes, &fsinfo.usedBytes) < 0) + Dbprintf("errno %i\n", SPIFFS_errno(&fs)); + fsinfo.freeBytes = fsinfo.totalBytes - fsinfo.usedBytes; + // Rounding without float may be improved + fsinfo.usedPercent = ((100 * fsinfo.usedBytes) + (fsinfo.totalBytes / 2)) / fsinfo.totalBytes; + fsinfo.freePercent = (100 - fsinfo.usedPercent); + return fsinfo; +} + +int exists_in_spiffs(const char *filename) { + spiffs_stat stat; + int rc = SPIFFS_stat(&fs, filename, &stat); + return rc == SPIFFS_OK; +} + +RDV40SpiFFSFileType filetype_in_spiffs(const char *filename) { + RDV40SpiFFSFileType filetype = RDV40_SPIFFS_FILETYPE_UNKNOWN; + char symlinked[SPIFFS_OBJ_NAME_LEN]; + sprintf(symlinked, "%s.lnk", filename); + if (exists_in_spiffs(filename)) { + filetype = RDV40_SPIFFS_FILETYPE_REAL; + } + if (exists_in_spiffs(symlinked)) { + if (filetype != RDV40_SPIFFS_FILETYPE_UNKNOWN) { + filetype = RDV40_SPIFFS_FILETYPE_BOTH; + } else { + filetype = RDV40_SPIFFS_FILETYPE_SYMLINK; + } + } + if (DBGLEVEL > 1) { + switch (filetype) { + case RDV40_SPIFFS_FILETYPE_REAL: + Dbprintf("Filetype is : RDV40_SPIFFS_FILETYPE_REAL"); + break; + case RDV40_SPIFFS_FILETYPE_SYMLINK: + Dbprintf("Filetype is : RDV40_SPIFFS_FILETYPE_SYMLINK"); + break; + case RDV40_SPIFFS_FILETYPE_BOTH: + Dbprintf("Filetype is : RDV40_SPIFFS_FILETYPE_BOTH"); + break; + case RDV40_SPIFFS_FILETYPE_UNKNOWN: + Dbprintf("Filetype is : RDV40_SPIFFS_FILETYPE_UNKNOWN"); + break; + } + } + return filetype; +} + +int is_valid_filename(const char *filename) { + if (filename == NULL) { + return false; + } + uint32_t len = strlen(filename); + return len > 0 && len < SPIFFS_OBJ_NAME_LEN; +} + +void copy_in_spiffs(const char *src, const char *dst) { + uint32_t size = size_in_spiffs((char *)src); + uint8_t *mem = BigBuf_malloc(size); + read_from_spiffs((char *)src, (uint8_t *)mem, size); + write_to_spiffs((char *)dst, (uint8_t *)mem, size); +} + +//////////////////////////////////////////////////////////////////////////////// + +////// Abstract Operations for base Safetyness ///////////////////////////////// +// +// mount if not already +// As an "hint" to the behavior one should adopt after his or her lazyness +// it will return 0 if the call was a noop, either because it did not need to +// change OR because it wasn't ABLE to change :) +// 1 if the mount status actually changed +// so you know what to do IN CASE you wished to set things "back to previous +// state" +int rdv40_spiffs_lazy_mount() { + int changed = 0; + if (!rdv40_spiffs_mounted()) { + changed = rdv40_spiffs_mount(); + /* if changed = 0 = SPIFFS_OK then all went well then the change + * actually occured :)*/ + changed = !changed; + } + return changed; +} + +// unmount if not already +int rdv40_spiffs_lazy_unmount() { + int changed = 0; + if (rdv40_spiffs_mounted()) { + changed = rdv40_spiffs_unmount(); + changed = !changed; + } + return changed; +} + +// Before further Reading, it is required to have in mind that UNMOUTING is +// important in some ways Because it is the ONLY operation which ensure that +// -> all Caches and writings are flushed to the FS +// -> all FD are properly closed +// -> Every best effort has been done to ensure consistency and integrity of the +// state reputated to be the actual state of the Filesystem. +//--- + +// This will "toggle" mount status +// on "changement" conditional +// so it is for the former lazy_ mounting function to actually rollback or not +// depending on the result of the previous This is super lazy implementation as +// it is either a toggle to previous state or again a noop as everything was a +// nonevent If you have a function which NEEDS mounting but you want to exit +// this function in the very state mounting was before your intervention all +// things can now be transparent like +/* +void my_lazy_spiffs_act(){ + uint8_t changed = rdv40_spiffs_lazy_mount(); + [..] Do what you have to do with spiffs + rdv40_spiffs_lazy_rollback(changed) +} +*/ +// The exact same goes for needed unmouting with eventual rollback, you just +// have to use lazy_unmount insted of lazy mount This way, you can ensure +// consistency in operation even with complex chain of mounting and unmounting +// Lets's say you are in a function which needs to mount if not already, and in +// the middle of itself calls function which indeed will need to unmount if not +// already. Well you better use safe or wrapped function which are made to +// rollback to previous state, so you can continue right after to do your +// things. +// +// As an extreme example: let's imagine that we have a function which is made +// to FORMAT the whole SPIFFS if a SPECIFIC content is written in the 4 first +// byte of that file. Also in such a case it should quickly create a bunch of +// skkeleton to get itself back to a known and wanted state. This behavior has +// to be done at every "manual" (not a lazy or internal event) mounting, just +// like an action upon boot. +/* + void my_spiffs_boot(){ + uint8_t resetret[4]; + // this lazy_mount since needed and can also report back the change on +state implied by eventual mount, if needed rdv40_spiffs_lazy_read((const char +*)".SHOULDRESET",(uint8_t *)resetret,4); if( resetret == "YESS" ) { uint8_t +changed = rdv40_spiffs_lazy_format(); // this will imply change only if we where +already mounted beforehand, was the case after our reading without further +rollback rdv40_spiffs_lazy_mount_rollback(changed); // so if we were mounted +just get back to this state. If not, just don't. + [...] + } + [...] +} +*/ +// Again : This will "toggle" spiffs mount status only if a "change" occured +// (and should be fed by the result of a spiffs_lazy* function) If everything +// went well, it will return SPIFFS_OK if everything went well, and a report +// back the chain a SPI_ERRNO if not. +int rdv40_spiffs_lazy_mount_rollback(int changed) { + if (!changed) + return SPIFFS_OK; + if (rdv40_spiffs_mounted()) + return rdv40_spiffs_unmount(); + return rdv40_spiffs_mount(); +} +/////////////////////////////////////////////////////////////////////////////// + +// High level functions with SatefetyLevel +// Beware that different safety level makes different return behavior +// +// RDV40_SPIFFS_SAFETY_NORMAL : will operate withtout further change on mount +// status RDV40_SPIFFS_SAFETY_LAZY : will ensure mount status already being in +// correct state before ops, +// will return !false if mount state had to change +// RDV40_SPIFFS_SAFETY_SAFE : will do same as RDV40_SPIFFS_SAFETY_LAZY +// will also safely rollback to previous state IF +// mount state had to change will return SPIFFS_OK / +// 0 / false if everything went well + +// TODO : this functions are common enought to be unified with a switchcase +// statement or some function taking function parameters +// TODO : forbid writing to a filename which already exists as lnk ! +// TODO : forbid writing to a filename.lnk which already exists without lnk ! +int rdv40_spiffs_write(char *filename, uint8_t *src, uint32_t size, RDV40SpiFFSSafetyLevel level) { + RDV40_SPIFFS_SAFE_FUNCTION( // + write_to_spiffs((char *)filename, (uint8_t *)src, size); // + ) +} + +int rdv40_spiffs_append(char *filename, uint8_t *src, uint32_t size, RDV40SpiFFSSafetyLevel level) { + RDV40_SPIFFS_SAFE_FUNCTION( // + append_to_spiffs((char *)filename, (uint8_t *)src, size); // + ) +} + +// todo integrate reading symlinks transparently +int rdv40_spiffs_read(char *filename, uint8_t *dst, uint32_t size, RDV40SpiFFSSafetyLevel level) { + RDV40_SPIFFS_SAFE_FUNCTION( // + read_from_spiffs((char *)filename, (uint8_t *)dst, size); // + ) +} + +// TODO : forbid writing to a filename which already exists as lnk ! +// TODO : forbid writing to a filename.lnk which already exists without lnk ! +int rdv40_spiffs_rename(char *old_filename, char *new_filename, RDV40SpiFFSSafetyLevel level) { + RDV40_SPIFFS_SAFE_FUNCTION( // + rename_in_spiffs((char *)old_filename, (char *)new_filename); // + ) +} +int rdv40_spiffs_remove(char *filename, RDV40SpiFFSSafetyLevel level) { + RDV40_SPIFFS_SAFE_FUNCTION( // + remove_from_spiffs((char *)filename); // + ) +} + +int rdv40_spiffs_copy(char *src, char *dst, RDV40SpiFFSSafetyLevel level) { + RDV40_SPIFFS_SAFE_FUNCTION( // + copy_in_spiffs((char *)src, (char *)dst); // + ) +} + +int rdv40_spiffs_stat(char *filename, uint32_t *buf, RDV40SpiFFSSafetyLevel level) { + RDV40_SPIFFS_SAFE_FUNCTION( // + *buf = size_in_spiffs((char *)filename); // + ) +} + +int rdv40_spiffs_getfsinfo(rdv40_spiffs_fsinfo *fsinfo, RDV40SpiFFSSafetyLevel level) { + RDV40_SPIFFS_SAFE_FUNCTION( // + *fsinfo = info_of_spiffs(); // + ) +} + +// test for symlink from filename +int rdv40_spiffs_is_symlink(const char *s) { + int ret = 0; + + if (s != NULL) { + size_t size = strlen(s); + + if (size >= 4 && s[size - 4] == '.' && s[size - 3] == 'l' && s[size - 2] == 'n' && s[size - 1] == 'k') { + ret = 1; + } + } + + return ret; +} + +// since FILENAME can't be longer than 32Bytes as of hard configuration, we're +// safe with Such maximum. So the "size" variable is actually the known/intended +// size of DESTINATION file, may it be known (may we provide a "stat from +// symlinkk ?") +// ATTENTION : you must NOT provide the whole filename (so please do not include the .lnk extension) +// TODO : integrate in read_function +int rdv40_spiffs_read_as_symlink(char *filename, uint8_t *dst, uint32_t size, RDV40SpiFFSSafetyLevel level) { + RDV40_SPIFFS_SAFE_FUNCTION( // + char linkdest[SPIFFS_OBJ_NAME_LEN]; // + char linkfilename[SPIFFS_OBJ_NAME_LEN]; // + sprintf(linkfilename, "%s.lnk", filename); + if (DBGLEVEL > 1) Dbprintf("Linkk real filename is destination is : %s", linkfilename); + read_from_spiffs((char *)linkfilename, (uint8_t *)linkdest, SPIFFS_OBJ_NAME_LEN); + if (DBGLEVEL > 1) Dbprintf("Symlink destination is : %s", linkdest); + read_from_spiffs((char *)linkdest, (uint8_t *)dst, size); // + ) +} + +// BEWARE ! This function is DESTRUCTIVE as it will UPDATE an existing symlink +// Since it creates a .lnk extension file it may be minor to mistake the order of arguments +// Still please use this function with care. +// Also, remind that it will NOT check if destination filename actually exists +// As a mnenotechnic, think about the "ln" unix command, which order is the same as "cp" unix command +// in regard of arguments orders. +// Eg : +// rdv40_spiffs_make_symlink((uint8_t *)"hello", (uint8_t *)"world", RDV40_SPIFFS_SAFETY_SAFE) +// will generate a file named "world.lnk" with the path to file "hello" written in +// wich you can then read back with : +// rdv40_spiffs_read_as_symlink((uint8_t *)"world",(uint8_t *) buffer, orig_file_size, RDV40_SPIFFS_SAFETY_SAFE); +// TODO : FORBID creating a symlink with a basename (before.lnk) which already exists as a file ! +int rdv40_spiffs_make_symlink(char *linkdest, char *filename, RDV40SpiFFSSafetyLevel level) { + RDV40_SPIFFS_SAFE_FUNCTION( // + char linkfilename[SPIFFS_OBJ_NAME_LEN]; // + sprintf(linkfilename, "%s.lnk", filename); + write_to_spiffs((char *)linkfilename, (uint8_t *)linkdest, SPIFFS_OBJ_NAME_LEN); // + ) +} + +// filename and filename.lnk will both the existence-checked +// if filename exists, read will be used, if filename.lnk exists, read_as_symlink will be used +// Both existence is not handled right now and should not happen or create a default fallback behavior +// Still, this case won't happend when the write(s) functions will check for both symlink and real file +// preexistance, avoiding a link being created if filename exists, or avoiding a file being created if +// symlink exists with same name +int rdv40_spiffs_read_as_filetype(char *filename, uint8_t *dst, uint32_t size, RDV40SpiFFSSafetyLevel level) { + RDV40_SPIFFS_SAFE_FUNCTION( // + RDV40SpiFFSFileType filetype = filetype_in_spiffs((char *)filename); // + switch (filetype) { + case RDV40_SPIFFS_FILETYPE_REAL: + rdv40_spiffs_read((char *)filename, (uint8_t *)dst, size, level); + break; + case RDV40_SPIFFS_FILETYPE_SYMLINK: + rdv40_spiffs_read_as_symlink((char *)filename, (uint8_t *)dst, size, level); + break; + case RDV40_SPIFFS_FILETYPE_BOTH: + case RDV40_SPIFFS_FILETYPE_UNKNOWN: + default:; + } // + ) +} + +// TODO regarding reads/write and symlinks : +// Provide a higher level readFile function which +// - don't need a size to be provided, getting it from STAT call and using bigbuff malloc +// - send back the whole readed file as return Result +// Maybe a good think to implement a VFS api here. + +//////////////////////////////////////////////////////////////////////////////// + +///////// MISC HIGH LEVEL FUNCTIONS //////////////////////////////////////////// + +void rdv40_spiffs_safe_print_fsinfos() { + rdv40_spiffs_fsinfo fsinfo; + rdv40_spiffs_getfsinfo(&fsinfo, RDV40_SPIFFS_SAFETY_SAFE); + DbpString(_BLUE_("Flash Memory FileSystem Infos (SPIFFS)")); + Dbprintf("-------------------------------------"); + Dbprintf("* Filesystem Logical Block Size.........%d bytes", fsinfo.blockSize); + Dbprintf("* Filesystem Logical Page Size..........%d bytes", fsinfo.pageSize); + Dbprintf("--"); + Dbprintf("* Filesystem Max Open Files.............%d file descriptors", fsinfo.maxOpenFiles); + Dbprintf("* Filesystem Max Path Lenght............%d chars", fsinfo.maxPathLenght); + Dbprintf("--"); + Dbprintf("Filesystem\tSize\tUsed\tAvailable\tUse%\tMounted on"); + Dbprintf("spiffs\t%dB\t%dB\t%dB\t\t%d%\t/", fsinfo.totalBytes, fsinfo.usedBytes, fsinfo.freeBytes, + fsinfo.usedPercent); +} + +// this function is safe and WILL rollback since it is only a PRINTING function, +// not a function intended to give any sort of struct to manipulate the FS +// objects +// TODO : Fake the Directory availability by spliting strings , buffering, +// maintaining prefix list sorting, unique_checking, THEN outputing precomputed +// tree Other solutio nwould be to add directory support to SPIFFS, but that we +// dont want, as prefix are way easier and lighter in every aspect. +void rdv40_spiffs_safe_print_tree(uint8_t banner) { + + int changed = rdv40_spiffs_lazy_mount(); + spiffs_DIR d; + struct spiffs_dirent e; + struct spiffs_dirent *pe = &e; + if (banner) { + DbpString(_BLUE_("Flash Memory FileSystem tree (SPIFFS)")); + Dbprintf("-------------------------------------"); + } + SPIFFS_opendir(&fs, "/", &d); + Dbprintf(" \t \t/"); + while ((pe = SPIFFS_readdir(&d, pe))) { + + char resolvedlink[11 + SPIFFS_OBJ_NAME_LEN]; + if (rdv40_spiffs_is_symlink((const char *)pe->name)) { + char linkdest[SPIFFS_OBJ_NAME_LEN]; + read_from_spiffs((char *)pe->name, (uint8_t *)linkdest, SPIFFS_OBJ_NAME_LEN); + sprintf(resolvedlink, "(.lnk) --> %s", linkdest); + // Kind of stripping the .lnk extension + strtok((char *)pe->name, "."); + } else { + memset(resolvedlink, 0, sizeof(resolvedlink)); + } + + Dbprintf("[%04x]\t %ibytes \t|-- %s%s", pe->obj_id, pe->size, pe->name, resolvedlink); + } + SPIFFS_closedir(&d); + + rdv40_spiffs_lazy_mount_rollback(changed); +} + +void test_spiffs() { + Dbprintf("---------------------------"); + Dbprintf("Testing SPIFFS functionning"); + Dbprintf("---------------------------"); + Dbprintf("(all test are made using lazy safetylevel)"); + Dbprintf("* Mounting filesystem (lazy)......."); + int changed = rdv40_spiffs_lazy_mount(); + Dbprintf("* Printing tree.............."); + rdv40_spiffs_safe_print_tree(false); + Dbprintf("* Writing 'I love Proxmark' in a testspiffs.txt"); + // Since We lazy_mounted manually before hand, the wrte safety level will + // just imply noops + rdv40_spiffs_write((char *)"testspiffs.txt", (uint8_t *)"I love Proxmark", 15, RDV40_SPIFFS_SAFETY_SAFE); + Dbprintf("* Printing tree again......."); + rdv40_spiffs_safe_print_tree(false); + Dbprintf("* Making a symlink to testspiffs.txt"); + rdv40_spiffs_make_symlink((char *)"testspiffs.txt", (char *)"linktotestspiffs.txt", RDV40_SPIFFS_SAFETY_SAFE); + Dbprintf("* Printing tree again......."); + rdv40_spiffs_safe_print_tree(false); + // TODO READBACK, rename,print tree read back, remove, print tree; + Dbprintf("* Rollbacking The mount status IF things have changed"); + rdv40_spiffs_lazy_mount_rollback(changed); + Dbprintf("All done"); + return; +} + +/////////////////////////////////////////////////////////////////////////////// diff --git a/armsrc/spiffs.h b/armsrc/spiffs.h new file mode 100644 index 000000000..e0bbbe68c --- /dev/null +++ b/armsrc/spiffs.h @@ -0,0 +1,861 @@ +/* + * spiffs.h + * + * Created on: May 26, 2013 + * Author: petera + */ + +#ifndef SPIFFS_H_ +#define SPIFFS_H_ +#if defined(__cplusplus) +extern "C" { +#endif + +#include "spiffs_config.h" + +typedef enum spiffs_safety_level { RDV40_SPIFFS_SAFETY_NORMAL, RDV40_SPIFFS_SAFETY_LAZY, RDV40_SPIFFS_SAFETY_SAFE } RDV40SpiFFSSafetyLevel; + +typedef enum spiffs_file_type { + RDV40_SPIFFS_FILETYPE_REAL, + RDV40_SPIFFS_FILETYPE_SYMLINK, + RDV40_SPIFFS_FILETYPE_BOTH, + RDV40_SPIFFS_FILETYPE_UNKNOWN +} RDV40SpiFFSFileType; + +typedef struct rdv40_spiffs_fsinfo + { + uint32_t blockSize; + uint32_t pageSize; + uint32_t maxOpenFiles; + uint32_t maxPathLenght; + uint32_t totalBytes, usedBytes, freeBytes; + uint32_t usedPercent, freePercent; + } rdv40_spiffs_fsinfo; + +int rdv40_spiffs_read_as_filetype(char *filename, uint8_t *dst, uint32_t size, RDV40SpiFFSSafetyLevel level); + + +int rdv40_spiffs_lazy_unmount(); +int rdv40_spiffs_lazy_mount(); +int rdv40_spiffs_lazy_mount_rollback(int changed); +int rdv40_spiffs_write(char *filename, uint8_t *src, uint32_t size, RDV40SpiFFSSafetyLevel level); +int rdv40_spiffs_read(char *filename, uint8_t *dst, uint32_t size, RDV40SpiFFSSafetyLevel level); +int rdv40_spiffs_rename(char *old_filename, char *new_filename, RDV40SpiFFSSafetyLevel level); +int rdv40_spiffs_remove(char *filename, RDV40SpiFFSSafetyLevel level); +int rdv40_spiffs_read_as_symlink(char *filename, uint8_t *dst, uint32_t size, RDV40SpiFFSSafetyLevel level); +void write_to_spiffs(const char *filename, uint8_t *src, uint32_t size); +void read_from_spiffs(const char *filename, uint8_t *dst, uint32_t size); +void test_spiffs(); +void rdv40_spiffs_safe_print_tree(uint8_t banner); +int rdv40_spiffs_unmount(); +int rdv40_spiffs_mount(); +int rdv40_spiffs_is_symlink(const char *s); +void rdv40_spiffs_safe_print_fsinfos(); +int rdv40_spiffs_make_symlink(char *linkdest, char *filename, RDV40SpiFFSSafetyLevel level); +void append_to_spiffs(const char *filename, uint8_t *src, uint32_t size); +int rdv40_spiffs_copy(char *src, char *dst, RDV40SpiFFSSafetyLevel level); +int rdv40_spiffs_append(char *filename, uint8_t *src, uint32_t size, RDV40SpiFFSSafetyLevel level); +int rdv40_spiffs_stat(char *filename, uint32_t *buf, RDV40SpiFFSSafetyLevel level); +uint32_t size_in_spiffs(const char *filename); + +#define SPIFFS_OK 0 +#define SPIFFS_ERR_NOT_MOUNTED -10000 +#define SPIFFS_ERR_FULL -10001 +#define SPIFFS_ERR_NOT_FOUND -10002 +#define SPIFFS_ERR_END_OF_OBJECT -10003 +#define SPIFFS_ERR_DELETED -10004 +#define SPIFFS_ERR_NOT_FINALIZED -10005 +#define SPIFFS_ERR_NOT_INDEX -10006 +#define SPIFFS_ERR_OUT_OF_FILE_DESCS -10007 +#define SPIFFS_ERR_FILE_CLOSED -10008 +#define SPIFFS_ERR_FILE_DELETED -10009 +#define SPIFFS_ERR_BAD_DESCRIPTOR -10010 +#define SPIFFS_ERR_IS_INDEX -10011 +#define SPIFFS_ERR_IS_FREE -10012 +#define SPIFFS_ERR_INDEX_SPAN_MISMATCH -10013 +#define SPIFFS_ERR_DATA_SPAN_MISMATCH -10014 +#define SPIFFS_ERR_INDEX_REF_FREE -10015 +#define SPIFFS_ERR_INDEX_REF_LU -10016 +#define SPIFFS_ERR_INDEX_REF_INVALID -10017 +#define SPIFFS_ERR_INDEX_FREE -10018 +#define SPIFFS_ERR_INDEX_LU -10019 +#define SPIFFS_ERR_INDEX_INVALID -10020 +#define SPIFFS_ERR_NOT_WRITABLE -10021 +#define SPIFFS_ERR_NOT_READABLE -10022 +#define SPIFFS_ERR_CONFLICTING_NAME -10023 +#define SPIFFS_ERR_NOT_CONFIGURED -10024 + +#define SPIFFS_ERR_NOT_A_FS -10025 +#define SPIFFS_ERR_MOUNTED -10026 +#define SPIFFS_ERR_ERASE_FAIL -10027 +#define SPIFFS_ERR_MAGIC_NOT_POSSIBLE -10028 + +#define SPIFFS_ERR_NO_DELETED_BLOCKS -10029 + +#define SPIFFS_ERR_FILE_EXISTS -10030 + +#define SPIFFS_ERR_NOT_A_FILE -10031 +#define SPIFFS_ERR_RO_NOT_IMPL -10032 +#define SPIFFS_ERR_RO_ABORTED_OPERATION -10033 +#define SPIFFS_ERR_PROBE_TOO_FEW_BLOCKS -10034 +#define SPIFFS_ERR_PROBE_NOT_A_FS -10035 +#define SPIFFS_ERR_NAME_TOO_LONG -10036 + +#define SPIFFS_ERR_IX_MAP_UNMAPPED -10037 +#define SPIFFS_ERR_IX_MAP_MAPPED -10038 +#define SPIFFS_ERR_IX_MAP_BAD_RANGE -10039 + +#define SPIFFS_ERR_SEEK_BOUNDS -10040 + + +#define SPIFFS_ERR_INTERNAL -10050 + +#define SPIFFS_ERR_TEST -10100 + + +// spiffs file descriptor index type. must be signed +typedef s16_t spiffs_file; +// spiffs file descriptor flags +typedef u16_t spiffs_flags; +// spiffs file mode +typedef u16_t spiffs_mode; +// object type +typedef u8_t spiffs_obj_type; + +struct spiffs_t; + +#if SPIFFS_HAL_CALLBACK_EXTRA + +/* spi read call function type */ +typedef s32_t (*spiffs_read)(struct spiffs_t *fs, u32_t addr, u32_t size, u8_t *dst); +/* spi write call function type */ +typedef s32_t (*spiffs_write)(struct spiffs_t *fs, u32_t addr, u32_t size, u8_t *src); +/* spi erase call function type */ +typedef s32_t (*spiffs_erase)(struct spiffs_t *fs, u32_t addr, u32_t size); + +#else // SPIFFS_HAL_CALLBACK_EXTRA + +/* spi read call function type */ +typedef s32_t (*spiffs_read)(u32_t addr, u32_t size, u8_t *dst); +/* spi write call function type */ +typedef s32_t (*spiffs_write)(u32_t addr, u32_t size, u8_t *src); +/* spi erase call function type */ +typedef s32_t (*spiffs_erase)(u32_t addr, u32_t size); +#endif // SPIFFS_HAL_CALLBACK_EXTRA + +/* file system check callback report operation */ +typedef enum { + SPIFFS_CHECK_LOOKUP = 0, + SPIFFS_CHECK_INDEX, + SPIFFS_CHECK_PAGE +} spiffs_check_type; + +/* file system check callback report type */ +typedef enum { + SPIFFS_CHECK_PROGRESS = 0, + SPIFFS_CHECK_ERROR, + SPIFFS_CHECK_FIX_INDEX, + SPIFFS_CHECK_FIX_LOOKUP, + SPIFFS_CHECK_DELETE_ORPHANED_INDEX, + SPIFFS_CHECK_DELETE_PAGE, + SPIFFS_CHECK_DELETE_BAD_FILE +} spiffs_check_report; + +/* file system check callback function */ +#if SPIFFS_HAL_CALLBACK_EXTRA +typedef void (*spiffs_check_callback)(struct spiffs_t *fs, spiffs_check_type type, spiffs_check_report report, + u32_t arg1, u32_t arg2); +#else // SPIFFS_HAL_CALLBACK_EXTRA +typedef void (*spiffs_check_callback)(spiffs_check_type type, spiffs_check_report report, + u32_t arg1, u32_t arg2); +#endif // SPIFFS_HAL_CALLBACK_EXTRA + +/* file system listener callback operation */ +typedef enum { + /* the file has been created */ + SPIFFS_CB_CREATED = 0, + /* the file has been updated or moved to another page */ + SPIFFS_CB_UPDATED, + /* the file has been deleted */ + SPIFFS_CB_DELETED +} spiffs_fileop_type; + +/* file system listener callback function */ +typedef void (*spiffs_file_callback)(struct spiffs_t *fs, spiffs_fileop_type op, spiffs_obj_id obj_id, spiffs_page_ix pix); + +#ifndef SPIFFS_DBG +#define SPIFFS_DBG(...) \ + printf(__VA_ARGS__) +#endif +#ifndef SPIFFS_GC_DBG +#define SPIFFS_GC_DBG(...) printf(__VA_ARGS__) +#endif +#ifndef SPIFFS_CACHE_DBG +#define SPIFFS_CACHE_DBG(...) printf(__VA_ARGS__) +#endif +#ifndef SPIFFS_CHECK_DBG +#define SPIFFS_CHECK_DBG(...) printf(__VA_ARGS__) +#endif + +/* Any write to the filehandle is appended to end of the file */ +#define SPIFFS_APPEND (1<<0) +#define SPIFFS_O_APPEND SPIFFS_APPEND +/* If the opened file exists, it will be truncated to zero length before opened */ +#define SPIFFS_TRUNC (1<<1) +#define SPIFFS_O_TRUNC SPIFFS_TRUNC +/* If the opened file does not exist, it will be created before opened */ +#define SPIFFS_CREAT (1<<2) +#define SPIFFS_O_CREAT SPIFFS_CREAT +/* The opened file may only be read */ +#define SPIFFS_RDONLY (1<<3) +#define SPIFFS_O_RDONLY SPIFFS_RDONLY +/* The opened file may only be written */ +#define SPIFFS_WRONLY (1<<4) +#define SPIFFS_O_WRONLY SPIFFS_WRONLY +/* The opened file may be both read and written */ +#define SPIFFS_RDWR (SPIFFS_RDONLY | SPIFFS_WRONLY) +#define SPIFFS_O_RDWR SPIFFS_RDWR +/* Any writes to the filehandle will never be cached but flushed directly */ +#define SPIFFS_DIRECT (1<<5) +#define SPIFFS_O_DIRECT SPIFFS_DIRECT +/* If SPIFFS_O_CREAT and SPIFFS_O_EXCL are set, SPIFFS_open() shall fail if the file exists */ +#define SPIFFS_EXCL (1<<6) +#define SPIFFS_O_EXCL SPIFFS_EXCL + +#define SPIFFS_SEEK_SET (0) +#define SPIFFS_SEEK_CUR (1) +#define SPIFFS_SEEK_END (2) + +#define SPIFFS_TYPE_FILE (1) +#define SPIFFS_TYPE_DIR (2) +#define SPIFFS_TYPE_HARD_LINK (3) +#define SPIFFS_TYPE_SOFT_LINK (4) + +#ifndef SPIFFS_LOCK +#define SPIFFS_LOCK(fs) +#endif + +#ifndef SPIFFS_UNLOCK +#define SPIFFS_UNLOCK(fs) +#endif + +// phys structs + +// spiffs spi configuration struct +typedef struct { + // physical read function + spiffs_read hal_read_f; + // physical write function + spiffs_write hal_write_f; + // physical erase function + spiffs_erase hal_erase_f; +#if SPIFFS_SINGLETON == 0 + // physical size of the spi flash + u32_t phys_size; + // physical offset in spi flash used for spiffs, + // must be on block boundary + u32_t phys_addr; + // physical size when erasing a block + u32_t phys_erase_block; + + // logical size of a block, must be on physical + // block size boundary and must never be less than + // a physical block + u32_t log_block_size; + // logical size of a page, must be at least + // log_block_size / 8 + u32_t log_page_size; + +#endif +#if SPIFFS_FILEHDL_OFFSET + // an integer offset added to each file handle + u16_t fh_ix_offset; +#endif +} spiffs_config; + +typedef struct spiffs_t { + // file system configuration + spiffs_config cfg; + // number of logical blocks + u32_t block_count; + + // cursor for free blocks, block index + spiffs_block_ix free_cursor_block_ix; + // cursor for free blocks, entry index + int free_cursor_obj_lu_entry; + // cursor when searching, block index + spiffs_block_ix cursor_block_ix; + // cursor when searching, entry index + int cursor_obj_lu_entry; + + // primary work buffer, size of a logical page + u8_t *lu_work; + // secondary work buffer, size of a logical page + u8_t *work; + // file descriptor memory area + u8_t *fd_space; + // available file descriptors + u32_t fd_count; + + // last error + s32_t err_code; + + // current number of free blocks + u32_t free_blocks; + // current number of busy pages + u32_t stats_p_allocated; + // current number of deleted pages + u32_t stats_p_deleted; + // flag indicating that garbage collector is cleaning + u8_t cleaning; + // max erase count amongst all blocks + spiffs_obj_id max_erase_count; + +#if SPIFFS_GC_STATS + u32_t stats_gc_runs; +#endif + +#if SPIFFS_CACHE + // cache memory + void *cache; + // cache size + u32_t cache_size; +#if SPIFFS_CACHE_STATS + u32_t cache_hits; + u32_t cache_misses; +#endif +#endif + + // check callback function + spiffs_check_callback check_cb_f; + // file callback function + spiffs_file_callback file_cb_f; + // mounted flag + u8_t mounted; + // user data + void *user_data; + // config magic + u32_t config_magic; +} spiffs; + +/* spiffs file status struct */ +typedef struct { + spiffs_obj_id obj_id; + u32_t size; + spiffs_obj_type type; + spiffs_page_ix pix; + u8_t name[SPIFFS_OBJ_NAME_LEN]; +#if SPIFFS_OBJ_META_LEN + u8_t meta[SPIFFS_OBJ_META_LEN]; +#endif +} spiffs_stat; + +struct spiffs_dirent { + spiffs_obj_id obj_id; + u8_t name[SPIFFS_OBJ_NAME_LEN]; + spiffs_obj_type type; + u32_t size; + spiffs_page_ix pix; +#if SPIFFS_OBJ_META_LEN + u8_t meta[SPIFFS_OBJ_META_LEN]; +#endif +}; + +typedef struct { + spiffs *fs; + spiffs_block_ix block; + int entry; +} spiffs_DIR; + +#if SPIFFS_IX_MAP + +typedef struct { + // buffer with looked up data pixes + spiffs_page_ix *map_buf; + // precise file byte offset + u32_t offset; + // start data span index of lookup buffer + spiffs_span_ix start_spix; + // end data span index of lookup buffer + spiffs_span_ix end_spix; +} spiffs_ix_map; + +#endif + +// functions + +#if SPIFFS_USE_MAGIC && SPIFFS_USE_MAGIC_LENGTH && SPIFFS_SINGLETON==0 +/** + * Special function. This takes a spiffs config struct and returns the number + * of blocks this file system was formatted with. This function relies on + * that following info is set correctly in given config struct: + * + * phys_addr, log_page_size, and log_block_size. + * + * Also, hal_read_f must be set in the config struct. + * + * One must be sure of the correct page size and that the physical address is + * correct in the probed file system when calling this function. It is not + * checked if the phys_addr actually points to the start of the file system, + * so one might get a false positive if entering a phys_addr somewhere in the + * middle of the file system at block boundary. In addition, it is not checked + * if the page size is actually correct. If it is not, weird file system sizes + * will be returned. + * + * If this function detects a file system it returns the assumed file system + * size, which can be used to set the phys_size. + * + * Otherwise, it returns an error indicating why it is not regarded as a file + * system. + * + * Note: this function is not protected with SPIFFS_LOCK and SPIFFS_UNLOCK + * macros. It returns the error code directly, instead of as read by + * SPIFFS_errno. + * + * @param config essential parts of the physical and logical + * configuration of the file system. + */ +s32_t SPIFFS_probe_fs(spiffs_config *config); +#endif // SPIFFS_USE_MAGIC && SPIFFS_USE_MAGIC_LENGTH && SPIFFS_SINGLETON==0 + +/** + * Initializes the file system dynamic parameters and mounts the filesystem. + * If SPIFFS_USE_MAGIC is enabled the mounting may fail with SPIFFS_ERR_NOT_A_FS + * if the flash does not contain a recognizable file system. + * In this case, SPIFFS_format must be called prior to remounting. + * @param fs the file system struct + * @param config the physical and logical configuration of the file system + * @param work a memory work buffer comprising 2*config->log_page_size + * bytes used throughout all file system operations + * @param fd_space memory for file descriptors + * @param fd_space_size memory size of file descriptors + * @param cache memory for cache, may be null + * @param cache_size memory size of cache + * @param check_cb_f callback function for reporting during consistency checks + */ +s32_t SPIFFS_mount(spiffs *fs, spiffs_config *config, u8_t *work, + u8_t *fd_space, u32_t fd_space_size, + void *cache, u32_t cache_size, + spiffs_check_callback check_cb_f); + +/** + * Unmounts the file system. All file handles will be flushed of any + * cached writes and closed. + * @param fs the file system struct + */ +void SPIFFS_unmount(spiffs *fs); + +/** + * Creates a new file. + * @param fs the file system struct + * @param path the path of the new file + * @param mode ignored, for posix compliance + */ +s32_t SPIFFS_creat(spiffs *fs, const char *path, spiffs_mode mode); + +/** + * Opens/creates a file. + * @param fs the file system struct + * @param path the path of the new file + * @param flags the flags for the open command, can be combinations of + * SPIFFS_O_APPEND, SPIFFS_O_TRUNC, SPIFFS_O_CREAT, SPIFFS_O_RDONLY, + * SPIFFS_O_WRONLY, SPIFFS_O_RDWR, SPIFFS_O_DIRECT, SPIFFS_O_EXCL + * @param mode ignored, for posix compliance + */ +spiffs_file SPIFFS_open(spiffs *fs, const char *path, spiffs_flags flags, spiffs_mode mode); + +/** + * Opens a file by given dir entry. + * Optimization purposes, when traversing a file system with SPIFFS_readdir + * a normal SPIFFS_open would need to traverse the filesystem again to find + * the file, whilst SPIFFS_open_by_dirent already knows where the file resides. + * @param fs the file system struct + * @param e the dir entry to the file + * @param flags the flags for the open command, can be combinations of + * SPIFFS_APPEND, SPIFFS_TRUNC, SPIFFS_CREAT, SPIFFS_RD_ONLY, + * SPIFFS_WR_ONLY, SPIFFS_RDWR, SPIFFS_DIRECT. + * SPIFFS_CREAT will have no effect in this case. + * @param mode ignored, for posix compliance + */ +spiffs_file SPIFFS_open_by_dirent(spiffs *fs, struct spiffs_dirent *e, spiffs_flags flags, spiffs_mode mode); + +/** + * Opens a file by given page index. + * Optimization purposes, opens a file by directly pointing to the page + * index in the spi flash. + * If the page index does not point to a file header SPIFFS_ERR_NOT_A_FILE + * is returned. + * @param fs the file system struct + * @param page_ix the page index + * @param flags the flags for the open command, can be combinations of + * SPIFFS_APPEND, SPIFFS_TRUNC, SPIFFS_CREAT, SPIFFS_RD_ONLY, + * SPIFFS_WR_ONLY, SPIFFS_RDWR, SPIFFS_DIRECT. + * SPIFFS_CREAT will have no effect in this case. + * @param mode ignored, for posix compliance + */ +spiffs_file SPIFFS_open_by_page(spiffs *fs, spiffs_page_ix page_ix, spiffs_flags flags, spiffs_mode mode); + +/** + * Reads from given filehandle. + * @param fs the file system struct + * @param fh the filehandle + * @param buf where to put read data + * @param len how much to read + * @returns number of bytes read, or -1 if error + */ +s32_t SPIFFS_read(spiffs *fs, spiffs_file fh, void *buf, s32_t len); + +/** + * Writes to given filehandle. + * @param fs the file system struct + * @param fh the filehandle + * @param buf the data to write + * @param len how much to write + * @returns number of bytes written, or -1 if error + */ +s32_t SPIFFS_write(spiffs *fs, spiffs_file fh, void *buf, s32_t len); + +/** + * Moves the read/write file offset. Resulting offset is returned or negative if error. + * lseek(fs, fd, 0, SPIFFS_SEEK_CUR) will thus return current offset. + * @param fs the file system struct + * @param fh the filehandle + * @param offs how much/where to move the offset + * @param whence if SPIFFS_SEEK_SET, the file offset shall be set to offset bytes + * if SPIFFS_SEEK_CUR, the file offset shall be set to its current location plus offset + * if SPIFFS_SEEK_END, the file offset shall be set to the size of the file plus offse, which should be negative + */ +s32_t SPIFFS_lseek(spiffs *fs, spiffs_file fh, s32_t offs, int whence); + +/** + * Removes a file by path + * @param fs the file system struct + * @param path the path of the file to remove + */ +s32_t SPIFFS_remove(spiffs *fs, const char *path); + +/** + * Removes a file by filehandle + * @param fs the file system struct + * @param fh the filehandle of the file to remove + */ +s32_t SPIFFS_fremove(spiffs *fs, spiffs_file fh); + +/** + * Gets file status by path + * @param fs the file system struct + * @param path the path of the file to stat + * @param s the stat struct to populate + */ +s32_t SPIFFS_stat(spiffs *fs, const char *path, spiffs_stat *s); + +/** + * Gets file status by filehandle + * @param fs the file system struct + * @param fh the filehandle of the file to stat + * @param s the stat struct to populate + */ +s32_t SPIFFS_fstat(spiffs *fs, spiffs_file fh, spiffs_stat *s); + +/** + * Flushes all pending write operations from cache for given file + * @param fs the file system struct + * @param fh the filehandle of the file to flush + */ +s32_t SPIFFS_fflush(spiffs *fs, spiffs_file fh); + +/** + * Closes a filehandle. If there are pending write operations, these are finalized before closing. + * @param fs the file system struct + * @param fh the filehandle of the file to close + */ +s32_t SPIFFS_close(spiffs *fs, spiffs_file fh); + +/** + * Renames a file + * @param fs the file system struct + * @param old path of file to rename + * @param newPath new path of file + */ +s32_t SPIFFS_rename(spiffs *fs, const char *old, const char *newPath); + +#if SPIFFS_OBJ_META_LEN +/** + * Updates file's metadata + * @param fs the file system struct + * @param path path to the file + * @param meta new metadata. must be SPIFFS_OBJ_META_LEN bytes long. + */ +s32_t SPIFFS_update_meta(spiffs *fs, const char *name, const void *meta); + +/** + * Updates file's metadata + * @param fs the file system struct + * @param fh file handle of the file + * @param meta new metadata. must be SPIFFS_OBJ_META_LEN bytes long. + */ +s32_t SPIFFS_fupdate_meta(spiffs *fs, spiffs_file fh, const void *meta); +#endif + +/** + * Returns last error of last file operation. + * @param fs the file system struct + */ +s32_t SPIFFS_errno(spiffs *fs); + +/** + * Clears last error. + * @param fs the file system struct + */ +void SPIFFS_clearerr(spiffs *fs); + +/** + * Opens a directory stream corresponding to the given name. + * The stream is positioned at the first entry in the directory. + * On hydrogen builds the name argument is ignored as hydrogen builds always correspond + * to a flat file structure - no directories. + * @param fs the file system struct + * @param name the name of the directory + * @param d pointer the directory stream to be populated + */ +spiffs_DIR *SPIFFS_opendir(spiffs *fs, const char *name, spiffs_DIR *d); + +/** + * Closes a directory stream + * @param d the directory stream to close + */ +s32_t SPIFFS_closedir(spiffs_DIR *d); + +/** + * Reads a directory into given spifs_dirent struct. + * @param d pointer to the directory stream + * @param e the dirent struct to be populated + * @returns null if error or end of stream, else given dirent is returned + */ +struct spiffs_dirent *SPIFFS_readdir(spiffs_DIR *d, struct spiffs_dirent *e); + +/** + * Runs a consistency check on given filesystem. + * @param fs the file system struct + */ +s32_t SPIFFS_check(spiffs *fs); + +/** + * Returns number of total bytes available and number of used bytes. + * This is an estimation, and depends on if there a many files with little + * data or few files with much data. + * NB: If used number of bytes exceeds total bytes, a SPIFFS_check should + * run. This indicates a power loss in midst of things. In worst case + * (repeated powerlosses in mending or gc) you might have to delete some files. + * + * @param fs the file system struct + * @param total total number of bytes in filesystem + * @param used used number of bytes in filesystem + */ +s32_t SPIFFS_info(spiffs *fs, u32_t *total, u32_t *used); + +/** + * Formats the entire file system. All data will be lost. + * The filesystem must not be mounted when calling this. + * + * NB: formatting is awkward. Due to backwards compatibility, SPIFFS_mount + * MUST be called prior to formatting in order to configure the filesystem. + * If SPIFFS_mount succeeds, SPIFFS_unmount must be called before calling + * SPIFFS_format. + * If SPIFFS_mount fails, SPIFFS_format can be called directly without calling + * SPIFFS_unmount first. + * + * @param fs the file system struct + */ +s32_t SPIFFS_format(spiffs *fs); + +/** + * Returns nonzero if spiffs is mounted, or zero if unmounted. + * @param fs the file system struct + */ +u8_t SPIFFS_mounted(spiffs *fs); + +/** + * Tries to find a block where most or all pages are deleted, and erase that + * block if found. Does not care for wear levelling. Will not move pages + * around. + * If parameter max_free_pages are set to 0, only blocks with only deleted + * pages will be selected. + * + * NB: the garbage collector is automatically called when spiffs needs free + * pages. The reason for this function is to give possibility to do background + * tidying when user knows the system is idle. + * + * Use with care. + * + * Setting max_free_pages to anything larger than zero will eventually wear + * flash more as a block containing free pages can be erased. + * + * Will set err_no to SPIFFS_OK if a block was found and erased, + * SPIFFS_ERR_NO_DELETED_BLOCK if no matching block was found, + * or other error. + * + * @param fs the file system struct + * @param max_free_pages maximum number allowed free pages in block + */ +s32_t SPIFFS_gc_quick(spiffs *fs, u16_t max_free_pages); + +/** + * Will try to make room for given amount of bytes in the filesystem by moving + * pages and erasing blocks. + * If it is physically impossible, err_no will be set to SPIFFS_ERR_FULL. If + * there already is this amount (or more) of free space, SPIFFS_gc will + * silently return. It is recommended to call SPIFFS_info before invoking + * this method in order to determine what amount of bytes to give. + * + * NB: the garbage collector is automatically called when spiffs needs free + * pages. The reason for this function is to give possibility to do background + * tidying when user knows the system is idle. + * + * Use with care. + * + * @param fs the file system struct + * @param size amount of bytes that should be freed + */ +s32_t SPIFFS_gc(spiffs *fs, u32_t size); + +/** + * Check if EOF reached. + * @param fs the file system struct + * @param fh the filehandle of the file to check + */ +s32_t SPIFFS_eof(spiffs *fs, spiffs_file fh); + +/** + * Get position in file. + * @param fs the file system struct + * @param fh the filehandle of the file to check + */ +s32_t SPIFFS_tell(spiffs *fs, spiffs_file fh); + +/** + * Registers a callback function that keeps track on operations on file + * headers. Do note, that this callback is called from within internal spiffs + * mechanisms. Any operations on the actual file system being callbacked from + * in this callback will mess things up for sure - do not do this. + * This can be used to track where files are and move around during garbage + * collection, which in turn can be used to build location tables in ram. + * Used in conjuction with SPIFFS_open_by_page this may improve performance + * when opening a lot of files. + * Must be invoked after mount. + * + * @param fs the file system struct + * @param cb_func the callback on file operations + */ +s32_t SPIFFS_set_file_callback_func(spiffs *fs, spiffs_file_callback cb_func); + +#if SPIFFS_IX_MAP + +/** + * Maps the first level index lookup to a given memory map. + * This will make reading big files faster, as the memory map will be used for + * looking up data pages instead of searching for the indices on the physical + * medium. When mapping, all affected indicies are found and the information is + * copied to the array. + * Whole file or only parts of it may be mapped. The index map will cover file + * contents from argument offset until and including arguments (offset+len). + * It is valid to map a longer range than the current file size. The map will + * then be populated when the file grows. + * On garbage collections and file data page movements, the map array will be + * automatically updated. Do not tamper with the map array, as this contains + * the references to the data pages. Modifying it from outside will corrupt any + * future readings using this file descriptor. + * The map will no longer be used when the file descriptor closed or the file + * is unmapped. + * This can be useful to get faster and more deterministic timing when reading + * large files, or when seeking and reading a lot within a file. + * @param fs the file system struct + * @param fh the file handle of the file to map + * @param map a spiffs_ix_map struct, describing the index map + * @param offset absolute file offset where to start the index map + * @param len length of the mapping in actual file bytes + * @param map_buf the array buffer for the look up data - number of required + * elements in the array can be derived from function + * SPIFFS_bytes_to_ix_map_entries given the length + */ +s32_t SPIFFS_ix_map(spiffs *fs, spiffs_file fh, spiffs_ix_map *map, + u32_t offset, u32_t len, spiffs_page_ix *map_buf); + +/** + * Unmaps the index lookup from this filehandle. All future readings will + * proceed as normal, requiring reading of the first level indices from + * physical media. + * The map and map buffer given in function SPIFFS_ix_map will no longer be + * referenced by spiffs. + * It is not strictly necessary to unmap a file before closing it, as closing + * a file will automatically unmap it. + * @param fs the file system struct + * @param fh the file handle of the file to unmap + */ +s32_t SPIFFS_ix_unmap(spiffs *fs, spiffs_file fh); + +/** + * Moves the offset for the index map given in function SPIFFS_ix_map. Parts or + * all of the map buffer will repopulated. + * @param fs the file system struct + * @param fh the mapped file handle of the file to remap + * @param offset new absolute file offset where to start the index map + */ +s32_t SPIFFS_ix_remap(spiffs *fs, spiffs_file fh, u32_t offs); + +/** + * Utility function to get number of spiffs_page_ix entries a map buffer must + * contain on order to map given amount of file data in bytes. + * See function SPIFFS_ix_map and SPIFFS_ix_map_entries_to_bytes. + * @param fs the file system struct + * @param bytes number of file data bytes to map + * @return needed number of elements in a spiffs_page_ix array needed to + * map given amount of bytes in a file + */ +s32_t SPIFFS_bytes_to_ix_map_entries(spiffs *fs, u32_t bytes); + +/** + * Utility function to amount of file data bytes that can be mapped when + * mapping a file with buffer having given number of spiffs_page_ix entries. + * See function SPIFFS_ix_map and SPIFFS_bytes_to_ix_map_entries. + * @param fs the file system struct + * @param map_page_ix_entries number of entries in a spiffs_page_ix array + * @return amount of file data in bytes that can be mapped given a map + * buffer having given amount of spiffs_page_ix entries + */ +s32_t SPIFFS_ix_map_entries_to_bytes(spiffs *fs, u32_t map_page_ix_entries); + +#endif // SPIFFS_IX_MAP + + +#if SPIFFS_TEST_VISUALISATION +/** + * Prints out a visualization of the filesystem. + * @param fs the file system struct + */ +s32_t SPIFFS_vis(spiffs *fs); +#endif + +#if SPIFFS_BUFFER_HELP +/** + * Returns number of bytes needed for the filedescriptor buffer given + * amount of file descriptors. + */ +u32_t SPIFFS_buffer_bytes_for_filedescs(spiffs *fs, u32_t num_descs); + +#if SPIFFS_CACHE +/** + * Returns number of bytes needed for the cache buffer given + * amount of cache pages. + */ +u32_t SPIFFS_buffer_bytes_for_cache(spiffs *fs, u32_t num_pages); +#endif +#endif + +#if SPIFFS_CACHE +#endif +#if defined(__cplusplus) +} +#endif + +#endif /* SPIFFS_H_ */ diff --git a/armsrc/spiffs_cache.c b/armsrc/spiffs_cache.c new file mode 100644 index 000000000..ad9995eae --- /dev/null +++ b/armsrc/spiffs_cache.c @@ -0,0 +1,319 @@ +/* + * spiffs_cache.c + * + * Created on: Jun 23, 2013 + * Author: petera + */ + +#include "spiffs.h" +#include "spiffs_nucleus.h" + +#if SPIFFS_CACHE + +// returns cached page for give page index, or null if no such cached page +static spiffs_cache_page *spiffs_cache_page_get(spiffs *fs, spiffs_page_ix pix) { + spiffs_cache *cache = spiffs_get_cache(fs); + if ((cache->cpage_use_map & cache->cpage_use_mask) == 0) return 0; + int i; + for (i = 0; i < cache->cpage_count; i++) { + spiffs_cache_page *cp = spiffs_get_cache_page_hdr(fs, cache, i); + if ((cache->cpage_use_map & (1<flags & SPIFFS_CACHE_FLAG_TYPE_WR) == 0 && + cp->ucache.spix.pix == pix ) { + //SPIFFS_CACHE_DBG("CACHE_GET: have cache page "_SPIPRIi" for "_SPIPRIpg"\n", i, pix); + cp->last_access = cache->last_access; + return cp; + } + } + //SPIFFS_CACHE_DBG("CACHE_GET: no cache for "_SPIPRIpg"\n", pix); + return 0; +} + +// frees cached page +static s32_t spiffs_cache_page_free(spiffs *fs, int ix, u8_t write_back) { + s32_t res = SPIFFS_OK; + spiffs_cache *cache = spiffs_get_cache(fs); + spiffs_cache_page *cp = spiffs_get_cache_page_hdr(fs, cache, ix); + if (cache->cpage_use_map & (1<flags & SPIFFS_CACHE_FLAG_TYPE_WR) == 0 && + (cp->flags & SPIFFS_CACHE_FLAG_DIRTY)) { + u8_t *mem = spiffs_get_cache_page(fs, cache, ix); + SPIFFS_CACHE_DBG("CACHE_FREE: write cache page "_SPIPRIi" pix "_SPIPRIpg"\n", ix, cp->pix); + res = SPIFFS_HAL_WRITE(fs, SPIFFS_PAGE_TO_PADDR(fs, cp->ucache.spix.pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), mem); + } + +#if SPIFFS_CACHE_WR + if (cp->flags & SPIFFS_CACHE_FLAG_TYPE_WR) { + SPIFFS_CACHE_DBG("CACHE_FREE: free cache page "_SPIPRIi" objid "_SPIPRIid"\n", ix, cp->obj_id); + } else +#endif + { + SPIFFS_CACHE_DBG("CACHE_FREE: free cache page "_SPIPRIi" pix "_SPIPRIpg"\n", ix, cp->pix); + } + cache->cpage_use_map &= ~(1 << ix); + cp->flags = 0; + } + + return res; +} + +// removes the oldest accessed cached page +static s32_t spiffs_cache_page_remove_oldest(spiffs *fs, u8_t flag_mask, u8_t flags) { + s32_t res = SPIFFS_OK; + spiffs_cache *cache = spiffs_get_cache(fs); + + if ((cache->cpage_use_map & cache->cpage_use_mask) != cache->cpage_use_mask) { + // at least one free cpage + return SPIFFS_OK; + } + + // all busy, scan thru all to find the cpage which has oldest access + int i; + int cand_ix = -1; + u32_t oldest_val = 0; + for (i = 0; i < cache->cpage_count; i++) { + spiffs_cache_page *cp = spiffs_get_cache_page_hdr(fs, cache, i); + if ((cache->last_access - cp->last_access) > oldest_val && + (cp->flags & flag_mask) == flags) { + oldest_val = cache->last_access - cp->last_access; + cand_ix = i; + } + } + + if (cand_ix >= 0) { + res = spiffs_cache_page_free(fs, cand_ix, 1); + } + + return res; +} + +// allocates a new cached page and returns it, or null if all cache pages are busy +static spiffs_cache_page *spiffs_cache_page_allocate(spiffs *fs) { + spiffs_cache *cache = spiffs_get_cache(fs); + if (cache->cpage_use_map == 0xffffffff) { + // out of cache memory + return 0; + } + int i; + for (i = 0; i < cache->cpage_count; i++) { + if ((cache->cpage_use_map & (1<cpage_use_map |= (1<last_access = cache->last_access; + //SPIFFS_CACHE_DBG("CACHE_ALLO: allocated cache page "_SPIPRIi"\n", i); + return cp; + } + } + // out of cache entries + return 0; +} + +// drops the cache page for give page index +void spiffs_cache_drop_page(spiffs *fs, spiffs_page_ix pix) { + spiffs_cache_page *cp = spiffs_cache_page_get(fs, pix); + if (cp) { + spiffs_cache_page_free(fs, cp->ix, 0); + } +} + +// ------------------------------ + +// reads from spi flash or the cache +s32_t spiffs_phys_rd( + spiffs *fs, + u8_t op, + spiffs_file fh, + u32_t addr, + u32_t len, + u8_t *dst) { + (void)fh; + s32_t res = SPIFFS_OK; + spiffs_cache *cache = spiffs_get_cache(fs); + spiffs_cache_page *cp = spiffs_cache_page_get(fs, SPIFFS_PADDR_TO_PAGE(fs, addr)); + cache->last_access++; + if (cp) { + // we've already got one, you see +#if SPIFFS_CACHE_STATS + fs->cache_hits++; +#endif + cp->last_access = cache->last_access; + u8_t *mem = spiffs_get_cache_page(fs, cache, cp->ix); + _SPIFFS_MEMCPY(dst, &mem[SPIFFS_PADDR_TO_PAGE_OFFSET(fs, addr)], len); + } else { + if ((op & SPIFFS_OP_TYPE_MASK) == SPIFFS_OP_T_OBJ_LU2) { + // for second layer lookup functions, we do not cache in order to prevent shredding + return SPIFFS_HAL_READ(fs, addr, len, dst); + } +#if SPIFFS_CACHE_STATS + fs->cache_misses++; +#endif + // this operation will always free one cache page (unless all already free), + // the result code stems from the write operation of the possibly freed cache page + res = spiffs_cache_page_remove_oldest(fs, SPIFFS_CACHE_FLAG_TYPE_WR, 0); + + cp = spiffs_cache_page_allocate(fs); + if (cp) { + cp->flags = SPIFFS_CACHE_FLAG_WRTHRU; + cp->ucache.spix.pix = SPIFFS_PADDR_TO_PAGE(fs, addr); + SPIFFS_CACHE_DBG("CACHE_ALLO: allocated cache page "_SPIPRIi" for pix "_SPIPRIpg "\n", cp->ix, cp->pix); + + s32_t res2 = SPIFFS_HAL_READ(fs, + addr - SPIFFS_PADDR_TO_PAGE_OFFSET(fs, addr), + SPIFFS_CFG_LOG_PAGE_SZ(fs), + spiffs_get_cache_page(fs, cache, cp->ix)); + if (res2 != SPIFFS_OK) { + // honor read failure before possible write failure (bad idea?) + res = res2; + } + u8_t *mem = spiffs_get_cache_page(fs, cache, cp->ix); + _SPIFFS_MEMCPY(dst, &mem[SPIFFS_PADDR_TO_PAGE_OFFSET(fs, addr)], len); + } else { + // this will never happen, last resort for sake of symmetry + s32_t res2 = SPIFFS_HAL_READ(fs, addr, len, dst); + if (res2 != SPIFFS_OK) { + // honor read failure before possible write failure (bad idea?) + res = res2; + } + } + } + return res; +} + +// writes to spi flash and/or the cache +s32_t spiffs_phys_wr( + spiffs *fs, + u8_t op, + spiffs_file fh, + u32_t addr, + u32_t len, + u8_t *src) { + (void)fh; + spiffs_page_ix pix = SPIFFS_PADDR_TO_PAGE(fs, addr); + spiffs_cache *cache = spiffs_get_cache(fs); + spiffs_cache_page *cp = spiffs_cache_page_get(fs, pix); + + if (cp && (op & SPIFFS_OP_COM_MASK) != SPIFFS_OP_C_WRTHRU) { + // have a cache page + // copy in data to cache page + + if ((op & SPIFFS_OP_COM_MASK) == SPIFFS_OP_C_DELE && + (op & SPIFFS_OP_TYPE_MASK) != SPIFFS_OP_T_OBJ_LU) { + // page is being deleted, wipe from cache - unless it is a lookup page + spiffs_cache_page_free(fs, cp->ix, 0); + return SPIFFS_HAL_WRITE(fs, addr, len, src); + } + + u8_t *mem = spiffs_get_cache_page(fs, cache, cp->ix); + _SPIFFS_MEMCPY(&mem[SPIFFS_PADDR_TO_PAGE_OFFSET(fs, addr)], src, len); + + cache->last_access++; + cp->last_access = cache->last_access; + + if (cp->flags & SPIFFS_CACHE_FLAG_WRTHRU) { + // page is being updated, no write-cache, just pass thru + return SPIFFS_HAL_WRITE(fs, addr, len, src); + } else { + return SPIFFS_OK; + } + } else { + // no cache page, no write cache - just write thru + return SPIFFS_HAL_WRITE(fs, addr, len, src); + } +} + +#if SPIFFS_CACHE_WR +// returns the cache page that this fd refers, or null if no cache page +spiffs_cache_page *spiffs_cache_page_get_by_fd(spiffs *fs, spiffs_fd *fd) { + spiffs_cache *cache = spiffs_get_cache(fs); + + if ((cache->cpage_use_map & cache->cpage_use_mask) == 0) { + // all cpages free, no cpage cannot be assigned to obj_id + return 0; + } + + int i; + for (i = 0; i < cache->cpage_count; i++) { + spiffs_cache_page *cp = spiffs_get_cache_page_hdr(fs, cache, i); + if ((cache->cpage_use_map & (1<flags & SPIFFS_CACHE_FLAG_TYPE_WR) && + cp->ucache.swrc.obj_id == fd->obj_id) { + return cp; + } + } + + return 0; +} + +// allocates a new cache page and refers this to given fd - flushes an old cache +// page if all cache is busy +spiffs_cache_page *spiffs_cache_page_allocate_by_fd(spiffs *fs, spiffs_fd *fd) { + // before this function is called, it is ensured that there is no already existing + // cache page with same object id + spiffs_cache_page_remove_oldest(fs, SPIFFS_CACHE_FLAG_TYPE_WR, 0); + spiffs_cache_page *cp = spiffs_cache_page_allocate(fs); + if (cp == 0) { + // could not get cache page + return 0; + } + + cp->flags = SPIFFS_CACHE_FLAG_TYPE_WR; + cp->ucache.swrc.obj_id = fd->obj_id; + fd->cache_page = cp; + SPIFFS_CACHE_DBG("CACHE_ALLO: allocated cache page "_SPIPRIi" for fd "_SPIPRIfd ":"_SPIPRIid "\n", cp->ix, fd->file_nbr, fd->obj_id); + return cp; +} + +// unrefers all fds that this cache page refers to and releases the cache page +void spiffs_cache_fd_release(spiffs *fs, spiffs_cache_page *cp) { + if (cp == 0) return; + u32_t i; + spiffs_fd *fds = (spiffs_fd *)fs->fd_space; + for (i = 0; i < fs->fd_count; i++) { + spiffs_fd *cur_fd = &fds[i]; + if (cur_fd->file_nbr != 0 && cur_fd->cache_page == cp) { + cur_fd->cache_page = 0; + } + } + spiffs_cache_page_free(fs, cp->ix, 0); + + cp->ucache.swrc.obj_id = 0; +} + +#endif + +// initializes the cache +void spiffs_cache_init(spiffs *fs) { + if (fs->cache == 0) return; + u32_t sz = fs->cache_size; + u32_t cache_mask = 0; + int i; + int cache_entries = + (sz - sizeof(spiffs_cache)) / (SPIFFS_CACHE_PAGE_SIZE(fs)); + if (cache_entries <= 0) return; + + for (i = 0; i < cache_entries; i++) { + cache_mask <<= 1; + cache_mask |= 1; + } + + spiffs_cache cache; + memset(&cache, 0, sizeof(spiffs_cache)); + cache.cpage_count = cache_entries; + cache.cpages = (u8_t *)((u8_t *)fs->cache + sizeof(spiffs_cache)); + + cache.cpage_use_map = 0xffffffff; + cache.cpage_use_mask = cache_mask; + _SPIFFS_MEMCPY(fs->cache, &cache, sizeof(spiffs_cache)); + + spiffs_cache *c = spiffs_get_cache(fs); + + memset(c->cpages, 0, c->cpage_count * SPIFFS_CACHE_PAGE_SIZE(fs)); + + c->cpage_use_map &= ~(c->cpage_use_mask); + for (i = 0; i < cache.cpage_count; i++) { + spiffs_get_cache_page_hdr(fs, c, i)->ix = i; + } +} + +#endif // SPIFFS_CACHE diff --git a/armsrc/spiffs_check.c b/armsrc/spiffs_check.c new file mode 100644 index 000000000..2b3b3a14d --- /dev/null +++ b/armsrc/spiffs_check.c @@ -0,0 +1,1008 @@ +/* + * spiffs_check.c + * + * Contains functionality for checking file system consistency + * and mending problems. + * Three levels of consistency checks are implemented: + * + * Look up consistency + * Checks if indices in lookup pages are coherent with page headers + * Object index consistency + * Checks if there are any orphaned object indices (missing object index headers). + * If an object index is found but not its header, the object index is deleted. + * This is critical for the following page consistency check. + * Page consistency + * Checks for pages that ought to be indexed, ought not to be indexed, are multiple indexed + * + * + * Created on: Jul 7, 2013 + * Author: petera + */ + + +#include "spiffs.h" +#include "spiffs_nucleus.h" + +#if !SPIFFS_READ_ONLY + +#if SPIFFS_HAL_CALLBACK_EXTRA +#define CHECK_CB(_fs, _type, _rep, _arg1, _arg2) \ + do { \ + if ((_fs)->check_cb_f) (_fs)->check_cb_f((_fs), (_type), (_rep), (_arg1), (_arg2)); \ + } while (0) +#else +#define CHECK_CB(_fs, _type, _rep, _arg1, _arg2) \ + do { \ + if ((_fs)->check_cb_f) (_fs)->check_cb_f((_type), (_rep), (_arg1), (_arg2)); \ + } while (0) +#endif + +//--------------------------------------- +// Look up consistency + +// searches in the object indices and returns the referenced page index given +// the object id and the data span index +// destroys fs->lu_work +static s32_t spiffs_object_get_data_page_index_reference( + spiffs *fs, + spiffs_obj_id obj_id, + spiffs_span_ix data_spix, + spiffs_page_ix *pix, + spiffs_page_ix *objix_pix) { + s32_t res; + + // calculate object index span index for given data page span index + spiffs_span_ix objix_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, data_spix); + + // find obj index for obj id and span index + res = spiffs_obj_lu_find_id_and_span(fs, obj_id | SPIFFS_OBJ_ID_IX_FLAG, objix_spix, 0, objix_pix); + SPIFFS_CHECK_RES(res); + + // load obj index entry + u32_t addr = SPIFFS_PAGE_TO_PADDR(fs, *objix_pix); + if (objix_spix == 0) { + // get referenced page from object index header + addr += sizeof(spiffs_page_object_ix_header) + data_spix * sizeof(spiffs_page_ix); + } else { + // get referenced page from object index + addr += sizeof(spiffs_page_object_ix) + SPIFFS_OBJ_IX_ENTRY(fs, data_spix) * sizeof(spiffs_page_ix); + } + + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, 0, addr, sizeof(spiffs_page_ix), (u8_t *)pix); + + return res; +} + +// copies page contents to a new page +static s32_t spiffs_rewrite_page(spiffs *fs, spiffs_page_ix cur_pix, spiffs_page_header *p_hdr, spiffs_page_ix *new_pix) { + s32_t res; + res = spiffs_page_allocate_data(fs, p_hdr->obj_id, p_hdr, 0,0,0,0, new_pix); + SPIFFS_CHECK_RES(res); + res = spiffs_phys_cpy(fs, 0, + SPIFFS_PAGE_TO_PADDR(fs, *new_pix) + sizeof(spiffs_page_header), + SPIFFS_PAGE_TO_PADDR(fs, cur_pix) + sizeof(spiffs_page_header), + SPIFFS_DATA_PAGE_SIZE(fs)); + SPIFFS_CHECK_RES(res); + return res; +} + +// rewrites the object index for given object id and replaces the +// data page index to a new page index +static s32_t spiffs_rewrite_index(spiffs *fs, spiffs_obj_id obj_id, spiffs_span_ix data_spix, spiffs_page_ix new_data_pix, spiffs_page_ix objix_pix) { + s32_t res; + spiffs_block_ix bix; + int entry; + spiffs_page_ix free_pix; + obj_id |= SPIFFS_OBJ_ID_IX_FLAG; + + // find free entry + res = spiffs_obj_lu_find_free(fs, fs->free_cursor_block_ix, fs->free_cursor_obj_lu_entry, &bix, &entry); + SPIFFS_CHECK_RES(res); + free_pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, entry); + + // calculate object index span index for given data page span index + spiffs_span_ix objix_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, data_spix); + if (objix_spix == 0) { + // calc index in index header + entry = data_spix; + } else { + // calc entry in index + entry = SPIFFS_OBJ_IX_ENTRY(fs, data_spix); + + } + // load index + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, + 0, SPIFFS_PAGE_TO_PADDR(fs, objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); + SPIFFS_CHECK_RES(res); + spiffs_page_header *objix_p_hdr = (spiffs_page_header *)fs->lu_work; + + // be ultra safe, double check header against provided data + if (objix_p_hdr->obj_id != obj_id) { + spiffs_page_delete(fs, free_pix); + return SPIFFS_ERR_CHECK_OBJ_ID_MISM; + } + if (objix_p_hdr->span_ix != objix_spix) { + spiffs_page_delete(fs, free_pix); + return SPIFFS_ERR_CHECK_SPIX_MISM; + } + if ((objix_p_hdr->flags & (SPIFFS_PH_FLAG_USED | SPIFFS_PH_FLAG_IXDELE | SPIFFS_PH_FLAG_INDEX | + SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_DELET)) != + (SPIFFS_PH_FLAG_IXDELE | SPIFFS_PH_FLAG_DELET)) { + spiffs_page_delete(fs, free_pix); + return SPIFFS_ERR_CHECK_FLAGS_BAD; + } + + // rewrite in mem + if (objix_spix == 0) { + ((spiffs_page_ix*)((u8_t *)fs->lu_work + sizeof(spiffs_page_object_ix_header)))[data_spix] = new_data_pix; + } else { + ((spiffs_page_ix*)((u8_t *)fs->lu_work + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)] = new_data_pix; + } + + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, + 0, SPIFFS_PAGE_TO_PADDR(fs, free_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); + SPIFFS_CHECK_RES(res); + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_UPDT, + 0, SPIFFS_BLOCK_TO_PADDR(fs, SPIFFS_BLOCK_FOR_PAGE(fs, free_pix)) + SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(fs, free_pix) * sizeof(spiffs_page_ix), + sizeof(spiffs_obj_id), + (u8_t *)&obj_id); + SPIFFS_CHECK_RES(res); + res = spiffs_page_delete(fs, objix_pix); + + return res; +} + +// deletes an object just by marking object index header as deleted +static s32_t spiffs_delete_obj_lazy(spiffs *fs, spiffs_obj_id obj_id) { + spiffs_page_ix objix_hdr_pix; + s32_t res; + res = spiffs_obj_lu_find_id_and_span(fs, obj_id, 0, 0, &objix_hdr_pix); + if (res == SPIFFS_ERR_NOT_FOUND) { + return SPIFFS_OK; + } + SPIFFS_CHECK_RES(res); + u8_t flags = 0xff; +#if SPIFFS_NO_BLIND_WRITES + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, + 0, SPIFFS_PAGE_TO_PADDR(fs, objix_hdr_pix) + offsetof(spiffs_page_header, flags), + sizeof(flags), &flags); + SPIFFS_CHECK_RES(res); +#endif + flags &= ~SPIFFS_PH_FLAG_IXDELE; + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_UPDT, + 0, SPIFFS_PAGE_TO_PADDR(fs, objix_hdr_pix) + offsetof(spiffs_page_header, flags), + sizeof(flags), &flags); + return res; +} + +// validates the given look up entry +static s32_t spiffs_lookup_check_validate(spiffs *fs, spiffs_obj_id lu_obj_id, spiffs_page_header *p_hdr, + spiffs_page_ix cur_pix, spiffs_block_ix cur_block, int cur_entry, int *reload_lu) { + (void)cur_block; + (void)cur_entry; + u8_t delete_page = 0; + s32_t res = SPIFFS_OK; + spiffs_page_ix objix_pix; + spiffs_page_ix ref_pix; + // check validity, take actions + if (((lu_obj_id == SPIFFS_OBJ_ID_DELETED) && (p_hdr->flags & SPIFFS_PH_FLAG_DELET)) || + ((lu_obj_id == SPIFFS_OBJ_ID_FREE) && (p_hdr->flags & SPIFFS_PH_FLAG_USED) == 0)) { + // look up entry deleted / free but used in page header + SPIFFS_CHECK_DBG("LU: pix "_SPIPRIpg" deleted/free in lu but not on page\n", cur_pix); + *reload_lu = 1; + delete_page = 1; + if (p_hdr->flags & SPIFFS_PH_FLAG_INDEX) { + // header says data page + // data page can be removed if not referenced by some object index + res = spiffs_object_get_data_page_index_reference(fs, p_hdr->obj_id, p_hdr->span_ix, &ref_pix, &objix_pix); + if (res == SPIFFS_ERR_NOT_FOUND) { + // no object with this id, so remove page safely + res = SPIFFS_OK; + } else { + SPIFFS_CHECK_RES(res); + if (ref_pix == cur_pix) { + // data page referenced by object index but deleted in lu + // copy page to new place and re-write the object index to new place + spiffs_page_ix new_pix; + res = spiffs_rewrite_page(fs, cur_pix, p_hdr, &new_pix); + SPIFFS_CHECK_DBG("LU: FIXUP: data page not found elsewhere, rewriting "_SPIPRIpg" to new page "_SPIPRIpg"\n", cur_pix, new_pix); + SPIFFS_CHECK_RES(res); + *reload_lu = 1; + SPIFFS_CHECK_DBG("LU: FIXUP: "_SPIPRIpg" rewritten to "_SPIPRIpg", affected objix_pix "_SPIPRIpg"\n", cur_pix, new_pix, objix_pix); + res = spiffs_rewrite_index(fs, p_hdr->obj_id, p_hdr->span_ix, new_pix, objix_pix); + if (res <= _SPIFFS_ERR_CHECK_FIRST && res > _SPIFFS_ERR_CHECK_LAST) { + // index bad also, cannot mend this file + SPIFFS_CHECK_DBG("LU: FIXUP: index bad "_SPIPRIi", cannot mend!\n", res); + res = spiffs_page_delete(fs, new_pix); + SPIFFS_CHECK_RES(res); + res = spiffs_delete_obj_lazy(fs, p_hdr->obj_id); + CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_DELETE_BAD_FILE, p_hdr->obj_id, 0); + } else { + CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_INDEX, p_hdr->obj_id, p_hdr->span_ix); + } + SPIFFS_CHECK_RES(res); + } + } + } else { + // header says index page + // index page can be removed if other index with same obj_id and spanix is found + res = spiffs_obj_lu_find_id_and_span(fs, p_hdr->obj_id | SPIFFS_OBJ_ID_IX_FLAG, p_hdr->span_ix, cur_pix, 0); + if (res == SPIFFS_ERR_NOT_FOUND) { + // no such index page found, check for a data page amongst page headers + // lu cannot be trusted + res = spiffs_obj_lu_find_id_and_span_by_phdr(fs, p_hdr->obj_id | SPIFFS_OBJ_ID_IX_FLAG, 0, 0, 0); + if (res == SPIFFS_OK) { // ignore other errors + // got a data page also, assume lu corruption only, rewrite to new page + spiffs_page_ix new_pix; + res = spiffs_rewrite_page(fs, cur_pix, p_hdr, &new_pix); + SPIFFS_CHECK_DBG("LU: FIXUP: ix page with data not found elsewhere, rewriting "_SPIPRIpg" to new page "_SPIPRIpg"\n", cur_pix, new_pix); + SPIFFS_CHECK_RES(res); + *reload_lu = 1; + CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_LOOKUP, p_hdr->obj_id, p_hdr->span_ix); + } + } else { + SPIFFS_CHECK_RES(res); + } + } + } + if (lu_obj_id != SPIFFS_OBJ_ID_FREE && lu_obj_id != SPIFFS_OBJ_ID_DELETED) { + // look up entry used + if ((p_hdr->obj_id | SPIFFS_OBJ_ID_IX_FLAG) != (lu_obj_id | SPIFFS_OBJ_ID_IX_FLAG)) { + SPIFFS_CHECK_DBG("LU: pix "_SPIPRIpg" differ in obj_id lu:"_SPIPRIid" ph:"_SPIPRIid"\n", cur_pix, lu_obj_id, p_hdr->obj_id); + delete_page = 1; + if ((p_hdr->flags & SPIFFS_PH_FLAG_DELET) == 0 || + (p_hdr->flags & SPIFFS_PH_FLAG_FINAL) || + (p_hdr->flags & (SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_IXDELE)) == 0) { + // page deleted or not finalized, just remove it + } else { + if (p_hdr->flags & SPIFFS_PH_FLAG_INDEX) { + // if data page, check for reference to this page + res = spiffs_object_get_data_page_index_reference(fs, p_hdr->obj_id, p_hdr->span_ix, &ref_pix, &objix_pix); + if (res == SPIFFS_ERR_NOT_FOUND) { + // no object with this id, so remove page safely + res = SPIFFS_OK; + } else { + SPIFFS_CHECK_RES(res); + // if found, rewrite page with object id, update index, and delete current + if (ref_pix == cur_pix) { + spiffs_page_ix new_pix; + res = spiffs_rewrite_page(fs, cur_pix, p_hdr, &new_pix); + SPIFFS_CHECK_RES(res); + res = spiffs_rewrite_index(fs, p_hdr->obj_id, p_hdr->span_ix, new_pix, objix_pix); + if (res <= _SPIFFS_ERR_CHECK_FIRST && res > _SPIFFS_ERR_CHECK_LAST) { + // index bad also, cannot mend this file + SPIFFS_CHECK_DBG("LU: FIXUP: index bad "_SPIPRIi", cannot mend!\n", res); + res = spiffs_page_delete(fs, new_pix); + SPIFFS_CHECK_RES(res); + res = spiffs_delete_obj_lazy(fs, p_hdr->obj_id); + *reload_lu = 1; + CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_DELETE_BAD_FILE, p_hdr->obj_id, 0); + } + SPIFFS_CHECK_RES(res); + } + } + } else { + // else if index, check for other pages with both obj_id's and spanix + spiffs_page_ix objix_pix_lu, objix_pix_ph; + // see if other object index page exists for lookup obj id and span index + res = spiffs_obj_lu_find_id_and_span(fs, lu_obj_id | SPIFFS_OBJ_ID_IX_FLAG, p_hdr->span_ix, 0, &objix_pix_lu); + if (res == SPIFFS_ERR_NOT_FOUND) { + res = SPIFFS_OK; + objix_pix_lu = 0; + } + SPIFFS_CHECK_RES(res); + // see if other object index exists for page header obj id and span index + res = spiffs_obj_lu_find_id_and_span(fs, p_hdr->obj_id | SPIFFS_OBJ_ID_IX_FLAG, p_hdr->span_ix, 0, &objix_pix_ph); + if (res == SPIFFS_ERR_NOT_FOUND) { + res = SPIFFS_OK; + objix_pix_ph = 0; + } + SPIFFS_CHECK_RES(res); + // if both obj_id's found, just delete current + if (objix_pix_ph == 0 || objix_pix_lu == 0) { + // otherwise try finding first corresponding data pages + spiffs_page_ix data_pix_lu, data_pix_ph; + // see if other data page exists for look up obj id and span index + res = spiffs_obj_lu_find_id_and_span(fs, lu_obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &data_pix_lu); + if (res == SPIFFS_ERR_NOT_FOUND) { + res = SPIFFS_OK; + objix_pix_lu = 0; + } + SPIFFS_CHECK_RES(res); + // see if other data page exists for page header obj id and span index + res = spiffs_obj_lu_find_id_and_span(fs, p_hdr->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &data_pix_ph); + if (res == SPIFFS_ERR_NOT_FOUND) { + res = SPIFFS_OK; + objix_pix_ph = 0; + } + SPIFFS_CHECK_RES(res); + + spiffs_page_header new_ph; + new_ph.flags = 0xff & ~(SPIFFS_PH_FLAG_USED | SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_FINAL); + new_ph.span_ix = p_hdr->span_ix; + spiffs_page_ix new_pix; + if ((objix_pix_lu && data_pix_lu && data_pix_ph && objix_pix_ph == 0) || + (objix_pix_lu == 0 && data_pix_ph && objix_pix_ph == 0)) { + // got a data page for page header obj id + // rewrite as obj_id_ph + new_ph.obj_id = p_hdr->obj_id | SPIFFS_OBJ_ID_IX_FLAG; + res = spiffs_rewrite_page(fs, cur_pix, &new_ph, &new_pix); + SPIFFS_CHECK_DBG("LU: FIXUP: rewrite page "_SPIPRIpg" as "_SPIPRIid" to pix "_SPIPRIpg"\n", cur_pix, new_ph.obj_id, new_pix); + CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_LOOKUP, p_hdr->obj_id, p_hdr->span_ix); + SPIFFS_CHECK_RES(res); + *reload_lu = 1; + } else if ((objix_pix_ph && data_pix_ph && data_pix_lu && objix_pix_lu == 0) || + (objix_pix_ph == 0 && data_pix_lu && objix_pix_lu == 0)) { + // got a data page for look up obj id + // rewrite as obj_id_lu + new_ph.obj_id = lu_obj_id | SPIFFS_OBJ_ID_IX_FLAG; + SPIFFS_CHECK_DBG("LU: FIXUP: rewrite page "_SPIPRIpg" as "_SPIPRIid"\n", cur_pix, new_ph.obj_id); + CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_LOOKUP, p_hdr->obj_id, p_hdr->span_ix); + res = spiffs_rewrite_page(fs, cur_pix, &new_ph, &new_pix); + SPIFFS_CHECK_RES(res); + *reload_lu = 1; + } else { + // cannot safely do anything + SPIFFS_CHECK_DBG("LU: FIXUP: nothing to do, just delete\n",NULL); + } + } + } + } + } else if (((lu_obj_id & SPIFFS_OBJ_ID_IX_FLAG) && (p_hdr->flags & SPIFFS_PH_FLAG_INDEX)) || + ((lu_obj_id & SPIFFS_OBJ_ID_IX_FLAG) == 0 && (p_hdr->flags & SPIFFS_PH_FLAG_INDEX) == 0)) { + SPIFFS_CHECK_DBG("LU: "_SPIPRIpg" lu/page index marking differ\n", cur_pix); + spiffs_page_ix data_pix, objix_pix_d; + // see if other data page exists for given obj id and span index + res = spiffs_obj_lu_find_id_and_span(fs, lu_obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, p_hdr->span_ix, cur_pix, &data_pix); + if (res == SPIFFS_ERR_NOT_FOUND) { + res = SPIFFS_OK; + data_pix = 0; + } + SPIFFS_CHECK_RES(res); + // see if other object index exists for given obj id and span index + res = spiffs_obj_lu_find_id_and_span(fs, lu_obj_id | SPIFFS_OBJ_ID_IX_FLAG, p_hdr->span_ix, cur_pix, &objix_pix_d); + if (res == SPIFFS_ERR_NOT_FOUND) { + res = SPIFFS_OK; + objix_pix_d = 0; + } + SPIFFS_CHECK_RES(res); + + delete_page = 1; + // if other data page exists and object index exists, just delete page + if (data_pix && objix_pix_d) { + SPIFFS_CHECK_DBG("LU: FIXUP: other index and data page exists, simply remove\n",NULL); + } else + // if only data page exists, make this page index + if (data_pix && objix_pix_d == 0) { + SPIFFS_CHECK_DBG("LU: FIXUP: other data page exists, make this index\n",NULL); + CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_INDEX, lu_obj_id, p_hdr->span_ix); + spiffs_page_header new_ph; + spiffs_page_ix new_pix; + new_ph.flags = 0xff & ~(SPIFFS_PH_FLAG_USED | SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_INDEX); + new_ph.obj_id = lu_obj_id | SPIFFS_OBJ_ID_IX_FLAG; + new_ph.span_ix = p_hdr->span_ix; + res = spiffs_page_allocate_data(fs, new_ph.obj_id, &new_ph, 0, 0, 0, 1, &new_pix); + SPIFFS_CHECK_RES(res); + res = spiffs_phys_cpy(fs, 0, SPIFFS_PAGE_TO_PADDR(fs, new_pix) + sizeof(spiffs_page_header), + SPIFFS_PAGE_TO_PADDR(fs, cur_pix) + sizeof(spiffs_page_header), + SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_page_header)); + SPIFFS_CHECK_RES(res); + } else + // if only index exists, make data page + if (data_pix == 0 && objix_pix_d) { + SPIFFS_CHECK_DBG("LU: FIXUP: other index page exists, make this data\n",NULL); + CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_LOOKUP, lu_obj_id, p_hdr->span_ix); + spiffs_page_header new_ph; + spiffs_page_ix new_pix; + new_ph.flags = 0xff & ~(SPIFFS_PH_FLAG_USED | SPIFFS_PH_FLAG_FINAL); + new_ph.obj_id = lu_obj_id & ~SPIFFS_OBJ_ID_IX_FLAG; + new_ph.span_ix = p_hdr->span_ix; + res = spiffs_page_allocate_data(fs, new_ph.obj_id, &new_ph, 0, 0, 0, 1, &new_pix); + SPIFFS_CHECK_RES(res); + res = spiffs_phys_cpy(fs, 0, SPIFFS_PAGE_TO_PADDR(fs, new_pix) + sizeof(spiffs_page_header), + SPIFFS_PAGE_TO_PADDR(fs, cur_pix) + sizeof(spiffs_page_header), + SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_page_header)); + SPIFFS_CHECK_RES(res); + } else { + // if nothing exists, we cannot safely make a decision - delete + } + } + else if ((p_hdr->flags & SPIFFS_PH_FLAG_DELET) == 0) { + SPIFFS_CHECK_DBG("LU: pix "_SPIPRIpg" busy in lu but deleted on page\n", cur_pix); + delete_page = 1; + } else if ((p_hdr->flags & SPIFFS_PH_FLAG_FINAL)) { + SPIFFS_CHECK_DBG("LU: pix "_SPIPRIpg" busy but not final\n", cur_pix); + // page can be removed if not referenced by object index + *reload_lu = 1; + res = spiffs_object_get_data_page_index_reference(fs, lu_obj_id, p_hdr->span_ix, &ref_pix, &objix_pix); + if (res == SPIFFS_ERR_NOT_FOUND) { + // no object with this id, so remove page safely + res = SPIFFS_OK; + delete_page = 1; + } else { + SPIFFS_CHECK_RES(res); + if (ref_pix != cur_pix) { + SPIFFS_CHECK_DBG("LU: FIXUP: other finalized page is referred, just delete\n",NULL); + delete_page = 1; + } else { + // page referenced by object index but not final + // just finalize + SPIFFS_CHECK_DBG("LU: FIXUP: unfinalized page is referred, finalizing\n",NULL); + CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_LOOKUP, p_hdr->obj_id, p_hdr->span_ix); + u8_t flags = 0xff; +#if SPIFFS_NO_BLIND_WRITES + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_READ, + 0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix) + offsetof(spiffs_page_header, flags), + sizeof(flags), &flags); + SPIFFS_CHECK_RES(res); +#endif + flags &= ~SPIFFS_PH_FLAG_FINAL; + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, + 0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix) + offsetof(spiffs_page_header, flags), + sizeof(flags), &flags); + } + } + } + } + + if (delete_page) { + SPIFFS_CHECK_DBG("LU: FIXUP: deleting page "_SPIPRIpg"\n", cur_pix); + CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_DELETE_PAGE, cur_pix, 0); + res = spiffs_page_delete(fs, cur_pix); + SPIFFS_CHECK_RES(res); + } + + return res; +} + +static s32_t spiffs_lookup_check_v(spiffs *fs, spiffs_obj_id obj_id, spiffs_block_ix cur_block, int cur_entry, + const void *user_const_p, void *user_var_p) { + (void)user_const_p; + (void)user_var_p; + s32_t res = SPIFFS_OK; + spiffs_page_header p_hdr; + spiffs_page_ix cur_pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, cur_block, cur_entry); + + CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_PROGRESS, + (cur_block * 256)/fs->block_count, 0); + + // load header + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, + 0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix), sizeof(spiffs_page_header), (u8_t*)&p_hdr); + SPIFFS_CHECK_RES(res); + + int reload_lu = 0; + + res = spiffs_lookup_check_validate(fs, obj_id, &p_hdr, cur_pix, cur_block, cur_entry, &reload_lu); + SPIFFS_CHECK_RES(res); + + if (res == SPIFFS_OK) { + return reload_lu ? SPIFFS_VIS_COUNTINUE_RELOAD : SPIFFS_VIS_COUNTINUE; + } + return res; +} + + +// Scans all object look up. For each entry, corresponding page header is checked for validity. +// If an object index header page is found, this is also checked +s32_t spiffs_lookup_consistency_check(spiffs *fs, u8_t check_all_objects) { + (void)check_all_objects; + s32_t res = SPIFFS_OK; + + CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_PROGRESS, 0, 0); + + res = spiffs_obj_lu_find_entry_visitor(fs, 0, 0, 0, 0, spiffs_lookup_check_v, 0, 0, 0, 0); + + if (res == SPIFFS_VIS_END) { + res = SPIFFS_OK; + } + + if (res != SPIFFS_OK) { + CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_ERROR, res, 0); + } + + CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_PROGRESS, 256, 0); + + return res; +} + +//--------------------------------------- +// Page consistency + +// Scans all pages (except lu pages), reserves 4 bits in working memory for each page +// bit 0: 0 == FREE|DELETED, 1 == USED +// bit 1: 0 == UNREFERENCED, 1 == REFERENCED +// bit 2: 0 == NOT_INDEX, 1 == INDEX +// bit 3: unused +// A consistent file system will have only pages being +// * x000 free, unreferenced, not index +// * x011 used, referenced only once, not index +// * x101 used, unreferenced, index +// The working memory might not fit all pages so several scans might be needed +static s32_t spiffs_page_consistency_check_i(spiffs *fs) { + const u32_t bits = 4; + const spiffs_page_ix pages_per_scan = SPIFFS_CFG_LOG_PAGE_SZ(fs) * 8 / bits; + + s32_t res = SPIFFS_OK; + spiffs_page_ix pix_offset = 0; + + // for each range of pages fitting into work memory + while (pix_offset < SPIFFS_PAGES_PER_BLOCK(fs) * fs->block_count) { + // set this flag to abort all checks and rescan the page range + u8_t restart = 0; + memset(fs->work, 0, SPIFFS_CFG_LOG_PAGE_SZ(fs)); + + spiffs_block_ix cur_block = 0; + // build consistency bitmap for id range traversing all blocks + while (!restart && cur_block < fs->block_count) { + CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_PROGRESS, + (pix_offset*256)/(SPIFFS_PAGES_PER_BLOCK(fs) * fs->block_count) + + ((((cur_block * pages_per_scan * 256)/ (SPIFFS_PAGES_PER_BLOCK(fs) * fs->block_count))) / fs->block_count), + 0); + // traverse each page except for lookup pages + spiffs_page_ix cur_pix = SPIFFS_OBJ_LOOKUP_PAGES(fs) + SPIFFS_PAGES_PER_BLOCK(fs) * cur_block; + while (!restart && cur_pix < SPIFFS_PAGES_PER_BLOCK(fs) * (cur_block+1)) { + //if ((cur_pix & 0xff) == 0) + // SPIFFS_CHECK_DBG("PA: processing pix "_SPIPRIpg", block "_SPIPRIbl" of pix "_SPIPRIpg", block "_SPIPRIbl"\n", + // cur_pix, cur_block, SPIFFS_PAGES_PER_BLOCK(fs) * fs->block_count, fs->block_count); + + // read header + spiffs_page_header p_hdr; + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, + 0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix), sizeof(spiffs_page_header), (u8_t*)&p_hdr); + SPIFFS_CHECK_RES(res); + + u8_t within_range = (cur_pix >= pix_offset && cur_pix < pix_offset + pages_per_scan); + const u32_t pix_byte_ix = (cur_pix - pix_offset) / (8/bits); + const u8_t pix_bit_ix = (cur_pix & ((8/bits)-1)) * bits; + + if (within_range && + (p_hdr.flags & SPIFFS_PH_FLAG_DELET) && (p_hdr.flags & SPIFFS_PH_FLAG_USED) == 0) { + // used + fs->work[pix_byte_ix] |= (1<<(pix_bit_ix + 0)); + } + if ((p_hdr.flags & SPIFFS_PH_FLAG_DELET) && + (p_hdr.flags & SPIFFS_PH_FLAG_IXDELE) && + (p_hdr.flags & (SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_USED)) == 0) { + // found non-deleted index + if (within_range) { + fs->work[pix_byte_ix] |= (1<<(pix_bit_ix + 2)); + } + + // load non-deleted index + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, + 0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); + SPIFFS_CHECK_RES(res); + + // traverse index for referenced pages + spiffs_page_ix *object_page_index; + spiffs_page_header *objix_p_hdr = (spiffs_page_header *)fs->lu_work; + + int entries; + int i; + spiffs_span_ix data_spix_offset; + if (p_hdr.span_ix == 0) { + // object header page index + entries = SPIFFS_OBJ_HDR_IX_LEN(fs); + data_spix_offset = 0; + object_page_index = (spiffs_page_ix *)((u8_t *)fs->lu_work + sizeof(spiffs_page_object_ix_header)); + } else { + // object page index + entries = SPIFFS_OBJ_IX_LEN(fs); + data_spix_offset = SPIFFS_OBJ_HDR_IX_LEN(fs) + SPIFFS_OBJ_IX_LEN(fs) * (p_hdr.span_ix - 1); + object_page_index = (spiffs_page_ix *)((u8_t *)fs->lu_work + sizeof(spiffs_page_object_ix)); + } + + // for all entries in index + for (i = 0; !restart && i < entries; i++) { + spiffs_page_ix rpix = object_page_index[i]; + u8_t rpix_within_range = rpix >= pix_offset && rpix < pix_offset + pages_per_scan; + + if ((rpix != (spiffs_page_ix)-1 && rpix > SPIFFS_MAX_PAGES(fs)) + || (rpix_within_range && SPIFFS_IS_LOOKUP_PAGE(fs, rpix))) { + + // bad reference + SPIFFS_CHECK_DBG("PA: pix "_SPIPRIpg"x bad pix / LU referenced from page "_SPIPRIpg"\n", + rpix, cur_pix); + // check for data page elsewhere + spiffs_page_ix data_pix; + res = spiffs_obj_lu_find_id_and_span(fs, objix_p_hdr->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, + data_spix_offset + i, 0, &data_pix); + if (res == SPIFFS_ERR_NOT_FOUND) { + res = SPIFFS_OK; + data_pix = 0; + } + SPIFFS_CHECK_RES(res); + if (data_pix == 0) { + // if not, allocate free page + spiffs_page_header new_ph; + new_ph.flags = 0xff & ~(SPIFFS_PH_FLAG_USED | SPIFFS_PH_FLAG_FINAL); + new_ph.obj_id = objix_p_hdr->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG; + new_ph.span_ix = data_spix_offset + i; + res = spiffs_page_allocate_data(fs, new_ph.obj_id, &new_ph, 0, 0, 0, 1, &data_pix); + SPIFFS_CHECK_RES(res); + SPIFFS_CHECK_DBG("PA: FIXUP: found no existing data page, created new @ "_SPIPRIpg"\n", data_pix); + } + // remap index + SPIFFS_CHECK_DBG("PA: FIXUP: rewriting index pix "_SPIPRIpg"\n", cur_pix); + res = spiffs_rewrite_index(fs, objix_p_hdr->obj_id | SPIFFS_OBJ_ID_IX_FLAG, + data_spix_offset + i, data_pix, cur_pix); + if (res <= _SPIFFS_ERR_CHECK_FIRST && res > _SPIFFS_ERR_CHECK_LAST) { + // index bad also, cannot mend this file + SPIFFS_CHECK_DBG("PA: FIXUP: index bad "_SPIPRIi", cannot mend - delete object\n", res); + CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_DELETE_BAD_FILE, objix_p_hdr->obj_id, 0); + // delete file + res = spiffs_page_delete(fs, cur_pix); + } else { + CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_FIX_INDEX, objix_p_hdr->obj_id, objix_p_hdr->span_ix); + } + SPIFFS_CHECK_RES(res); + restart = 1; + + } else if (rpix_within_range) { + + // valid reference + // read referenced page header + spiffs_page_header rp_hdr; + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, + 0, SPIFFS_PAGE_TO_PADDR(fs, rpix), sizeof(spiffs_page_header), (u8_t*)&rp_hdr); + SPIFFS_CHECK_RES(res); + + // cross reference page header check + if (rp_hdr.obj_id != (p_hdr.obj_id & ~SPIFFS_OBJ_ID_IX_FLAG) || + rp_hdr.span_ix != data_spix_offset + i || + (rp_hdr.flags & (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_USED)) != + (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_INDEX)) { + SPIFFS_CHECK_DBG("PA: pix "_SPIPRIpg" has inconsistent page header ix id/span:"_SPIPRIid"/"_SPIPRIsp", ref id/span:"_SPIPRIid"/"_SPIPRIsp" flags:"_SPIPRIfl"\n", + rpix, p_hdr.obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, data_spix_offset + i, + rp_hdr.obj_id, rp_hdr.span_ix, rp_hdr.flags); + // try finding correct page + spiffs_page_ix data_pix; + res = spiffs_obj_lu_find_id_and_span(fs, p_hdr.obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, + data_spix_offset + i, rpix, &data_pix); + if (res == SPIFFS_ERR_NOT_FOUND) { + res = SPIFFS_OK; + data_pix = 0; + } + SPIFFS_CHECK_RES(res); + if (data_pix == 0) { + // not found, this index is badly borked + SPIFFS_CHECK_DBG("PA: FIXUP: index bad, delete object id "_SPIPRIid"\n", p_hdr.obj_id); + CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_DELETE_BAD_FILE, p_hdr.obj_id, 0); + res = spiffs_delete_obj_lazy(fs, p_hdr.obj_id); + SPIFFS_CHECK_RES(res); + break; + } else { + // found it, so rewrite index + SPIFFS_CHECK_DBG("PA: FIXUP: found correct data pix "_SPIPRIpg", rewrite ix pix "_SPIPRIpg" id "_SPIPRIid"\n", + data_pix, cur_pix, p_hdr.obj_id); + res = spiffs_rewrite_index(fs, p_hdr.obj_id, data_spix_offset + i, data_pix, cur_pix); + if (res <= _SPIFFS_ERR_CHECK_FIRST && res > _SPIFFS_ERR_CHECK_LAST) { + // index bad also, cannot mend this file + SPIFFS_CHECK_DBG("PA: FIXUP: index bad "_SPIPRIi", cannot mend!\n", res); + CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_DELETE_BAD_FILE, p_hdr.obj_id, 0); + res = spiffs_delete_obj_lazy(fs, p_hdr.obj_id); + } else { + CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_FIX_INDEX, p_hdr.obj_id, p_hdr.span_ix); + } + SPIFFS_CHECK_RES(res); + restart = 1; + } + } + else { + // mark rpix as referenced + const u32_t rpix_byte_ix = (rpix - pix_offset) / (8/bits); + const u8_t rpix_bit_ix = (rpix & ((8/bits)-1)) * bits; + if (fs->work[rpix_byte_ix] & (1<<(rpix_bit_ix + 1))) { + SPIFFS_CHECK_DBG("PA: pix "_SPIPRIpg" multiple referenced from page "_SPIPRIpg"\n", + rpix, cur_pix); + // Here, we should have fixed all broken references - getting this means there + // must be multiple files with same object id. Only solution is to delete + // the object which is referring to this page + SPIFFS_CHECK_DBG("PA: FIXUP: removing object "_SPIPRIid" and page "_SPIPRIpg"\n", + p_hdr.obj_id, cur_pix); + CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_DELETE_BAD_FILE, p_hdr.obj_id, 0); + res = spiffs_delete_obj_lazy(fs, p_hdr.obj_id); + SPIFFS_CHECK_RES(res); + // extra precaution, delete this page also + res = spiffs_page_delete(fs, cur_pix); + SPIFFS_CHECK_RES(res); + restart = 1; + } + fs->work[rpix_byte_ix] |= (1<<(rpix_bit_ix + 1)); + } + } + } // for all index entries + } // found index + + // next page + cur_pix++; + } + // next block + cur_block++; + } + // check consistency bitmap + if (!restart) { + spiffs_page_ix objix_pix; + spiffs_page_ix rpix; + + u32_t byte_ix; + u8_t bit_ix; + for (byte_ix = 0; !restart && byte_ix < SPIFFS_CFG_LOG_PAGE_SZ(fs); byte_ix++) { + for (bit_ix = 0; !restart && bit_ix < 8/bits; bit_ix ++) { + u8_t bitmask = (fs->work[byte_ix] >> (bit_ix * bits)) & 0x7; + spiffs_page_ix cur_pix = pix_offset + byte_ix * (8/bits) + bit_ix; + + // 000 ok - free, unreferenced, not index + + if (bitmask == 0x1) { + + // 001 + SPIFFS_CHECK_DBG("PA: pix "_SPIPRIpg" USED, UNREFERENCED, not index\n", cur_pix); + + u8_t rewrite_ix_to_this = 0; + u8_t delete_page = 0; + // check corresponding object index entry + spiffs_page_header p_hdr; + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, + 0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix), sizeof(spiffs_page_header), (u8_t*)&p_hdr); + SPIFFS_CHECK_RES(res); + + res = spiffs_object_get_data_page_index_reference(fs, p_hdr.obj_id, p_hdr.span_ix, + &rpix, &objix_pix); + if (res == SPIFFS_OK) { + if (((rpix == (spiffs_page_ix)-1 || rpix > SPIFFS_MAX_PAGES(fs)) || (SPIFFS_IS_LOOKUP_PAGE(fs, rpix)))) { + // pointing to a bad page altogether, rewrite index to this + rewrite_ix_to_this = 1; + SPIFFS_CHECK_DBG("PA: corresponding ref is bad: "_SPIPRIpg", rewrite to this "_SPIPRIpg"\n", rpix, cur_pix); + } else { + // pointing to something else, check what + spiffs_page_header rp_hdr; + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, + 0, SPIFFS_PAGE_TO_PADDR(fs, rpix), sizeof(spiffs_page_header), (u8_t*)&rp_hdr); + SPIFFS_CHECK_RES(res); + if (((p_hdr.obj_id & ~SPIFFS_OBJ_ID_IX_FLAG) == rp_hdr.obj_id) && + ((rp_hdr.flags & (SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_USED | SPIFFS_PH_FLAG_FINAL)) == + (SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_DELET))) { + // pointing to something else valid, just delete this page then + SPIFFS_CHECK_DBG("PA: corresponding ref is good but different: "_SPIPRIpg", delete this "_SPIPRIpg"\n", rpix, cur_pix); + delete_page = 1; + } else { + // pointing to something weird, update index to point to this page instead + if (rpix != cur_pix) { + SPIFFS_CHECK_DBG("PA: corresponding ref is weird: "_SPIPRIpg" %s%s%s%s, rewrite this "_SPIPRIpg"\n", rpix, + (rp_hdr.flags & SPIFFS_PH_FLAG_INDEX) ? "" : "INDEX ", + (rp_hdr.flags & SPIFFS_PH_FLAG_DELET) ? "" : "DELETED ", + (rp_hdr.flags & SPIFFS_PH_FLAG_USED) ? "NOTUSED " : "", + (rp_hdr.flags & SPIFFS_PH_FLAG_FINAL) ? "NOTFINAL " : "", + cur_pix); + rewrite_ix_to_this = 1; + } else { + // should not happen, destined for fubar + } + } + } + } else if (res == SPIFFS_ERR_NOT_FOUND) { + SPIFFS_CHECK_DBG("PA: corresponding ref not found, delete "_SPIPRIpg"\n", cur_pix); + delete_page = 1; + res = SPIFFS_OK; + } + + if (rewrite_ix_to_this) { + // if pointing to invalid page, redirect index to this page + SPIFFS_CHECK_DBG("PA: FIXUP: rewrite index id "_SPIPRIid" data spix "_SPIPRIsp" to point to this pix: "_SPIPRIpg"\n", + p_hdr.obj_id, p_hdr.span_ix, cur_pix); + res = spiffs_rewrite_index(fs, p_hdr.obj_id, p_hdr.span_ix, cur_pix, objix_pix); + if (res <= _SPIFFS_ERR_CHECK_FIRST && res > _SPIFFS_ERR_CHECK_LAST) { + // index bad also, cannot mend this file + SPIFFS_CHECK_DBG("PA: FIXUP: index bad "_SPIPRIi", cannot mend!\n", res); + CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_DELETE_BAD_FILE, p_hdr.obj_id, 0); + res = spiffs_page_delete(fs, cur_pix); + SPIFFS_CHECK_RES(res); + res = spiffs_delete_obj_lazy(fs, p_hdr.obj_id); + } else { + CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_FIX_INDEX, p_hdr.obj_id, p_hdr.span_ix); + } + SPIFFS_CHECK_RES(res); + restart = 1; + continue; + } else if (delete_page) { + SPIFFS_CHECK_DBG("PA: FIXUP: deleting page "_SPIPRIpg"\n", cur_pix); + CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_DELETE_PAGE, cur_pix, 0); + res = spiffs_page_delete(fs, cur_pix); + } + SPIFFS_CHECK_RES(res); + } + if (bitmask == 0x2) { + + // 010 + SPIFFS_CHECK_DBG("PA: pix "_SPIPRIpg" FREE, REFERENCED, not index\n", cur_pix); + + // no op, this should be taken care of when checking valid references + } + + // 011 ok - busy, referenced, not index + + if (bitmask == 0x4) { + + // 100 + SPIFFS_CHECK_DBG("PA: pix "_SPIPRIpg" FREE, unreferenced, INDEX\n", cur_pix); + + // this should never happen, major fubar + } + + // 101 ok - busy, unreferenced, index + + if (bitmask == 0x6) { + + // 110 + SPIFFS_CHECK_DBG("PA: pix "_SPIPRIpg" FREE, REFERENCED, INDEX\n", cur_pix); + + // no op, this should be taken care of when checking valid references + } + if (bitmask == 0x7) { + + // 111 + SPIFFS_CHECK_DBG("PA: pix "_SPIPRIpg" USED, REFERENCED, INDEX\n", cur_pix); + + // no op, this should be taken care of when checking valid references + } + } + } + } + + SPIFFS_CHECK_DBG("PA: processed "_SPIPRIpg", restart "_SPIPRIi"\n", pix_offset, restart); + // next page range + if (!restart) { + pix_offset += pages_per_scan; + } + } // while page range not reached end + return res; +} + +// Checks consistency amongst all pages and fixes irregularities +s32_t spiffs_page_consistency_check(spiffs *fs) { + CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_PROGRESS, 0, 0); + s32_t res = spiffs_page_consistency_check_i(fs); + if (res != SPIFFS_OK) { + CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_ERROR, res, 0); + } + CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_PROGRESS, 256, 0); + return res; +} + +//--------------------------------------- +// Object index consistency + +// searches for given object id in temporary object id index, +// returns the index or -1 +static int spiffs_object_index_search(spiffs *fs, spiffs_obj_id obj_id) { + u32_t i; + spiffs_obj_id *obj_table = (spiffs_obj_id *)fs->work; + obj_id &= ~SPIFFS_OBJ_ID_IX_FLAG; + for (i = 0; i < SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id); i++) { + if ((obj_table[i] & ~SPIFFS_OBJ_ID_IX_FLAG) == obj_id) { + return i; + } + } + return -1; +} + +static s32_t spiffs_object_index_consistency_check_v(spiffs *fs, spiffs_obj_id obj_id, spiffs_block_ix cur_block, + int cur_entry, const void *user_const_p, void *user_var_p) { + (void)user_const_p; + s32_t res_c = SPIFFS_VIS_COUNTINUE; + s32_t res = SPIFFS_OK; + u32_t *log_ix = (u32_t*)user_var_p; + spiffs_obj_id *obj_table = (spiffs_obj_id *)fs->work; + + CHECK_CB(fs, SPIFFS_CHECK_INDEX, SPIFFS_CHECK_PROGRESS, + (cur_block * 256)/fs->block_count, 0); + + if (obj_id != SPIFFS_OBJ_ID_FREE && obj_id != SPIFFS_OBJ_ID_DELETED && (obj_id & SPIFFS_OBJ_ID_IX_FLAG)) { + spiffs_page_header p_hdr; + spiffs_page_ix cur_pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, cur_block, cur_entry); + + // load header + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, + 0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix), sizeof(spiffs_page_header), (u8_t*)&p_hdr); + SPIFFS_CHECK_RES(res); + + if (p_hdr.span_ix == 0 && + (p_hdr.flags & (SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_IXDELE)) == + (SPIFFS_PH_FLAG_DELET)) { + SPIFFS_CHECK_DBG("IX: pix "_SPIPRIpg", obj id:"_SPIPRIid" spix:"_SPIPRIsp" header not fully deleted - deleting\n", + cur_pix, obj_id, p_hdr.span_ix); + CHECK_CB(fs, SPIFFS_CHECK_INDEX, SPIFFS_CHECK_DELETE_PAGE, cur_pix, obj_id); + res = spiffs_page_delete(fs, cur_pix); + SPIFFS_CHECK_RES(res); + return res_c; + } + + if ((p_hdr.flags & (SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_IXDELE)) == + (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_IXDELE)) { + return res_c; + } + + if (p_hdr.span_ix == 0) { + // objix header page, register objid as reachable + int r = spiffs_object_index_search(fs, obj_id); + if (r == -1) { + // not registered, do it + obj_table[*log_ix] = obj_id & ~SPIFFS_OBJ_ID_IX_FLAG; + (*log_ix)++; + if (*log_ix >= SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id)) { + *log_ix = 0; + } + } + } else { // span index + // objix page, see if header can be found + int r = spiffs_object_index_search(fs, obj_id); + u8_t delete = 0; + if (r == -1) { + // not in temporary index, try finding it + spiffs_page_ix objix_hdr_pix; + res = spiffs_obj_lu_find_id_and_span(fs, obj_id | SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &objix_hdr_pix); + res_c = SPIFFS_VIS_COUNTINUE_RELOAD; + if (res == SPIFFS_OK) { + // found, register as reachable + obj_table[*log_ix] = obj_id & ~SPIFFS_OBJ_ID_IX_FLAG; + } else if (res == SPIFFS_ERR_NOT_FOUND) { + // not found, register as unreachable + delete = 1; + obj_table[*log_ix] = obj_id | SPIFFS_OBJ_ID_IX_FLAG; + } else { + SPIFFS_CHECK_RES(res); + } + (*log_ix)++; + if (*log_ix >= SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id)) { + *log_ix = 0; + } + } else { + // in temporary index, check reachable flag + if ((obj_table[r] & SPIFFS_OBJ_ID_IX_FLAG)) { + // registered as unreachable + delete = 1; + } + } + + if (delete) { + SPIFFS_CHECK_DBG("IX: FIXUP: pix "_SPIPRIpg", obj id:"_SPIPRIid" spix:"_SPIPRIsp" is orphan index - deleting\n", + cur_pix, obj_id, p_hdr.span_ix); + CHECK_CB(fs, SPIFFS_CHECK_INDEX, SPIFFS_CHECK_DELETE_ORPHANED_INDEX, cur_pix, obj_id); + res = spiffs_page_delete(fs, cur_pix); + SPIFFS_CHECK_RES(res); + } + } // span index + } // valid object index id + + return res_c; +} + +// Removes orphaned and partially deleted index pages. +// Scans for index pages. When an index page is found, corresponding index header is searched for. +// If no such page exists, the index page cannot be reached as no index header exists and must be +// deleted. +s32_t spiffs_object_index_consistency_check(spiffs *fs) { + s32_t res = SPIFFS_OK; + // impl note: + // fs->work is used for a temporary object index memory, listing found object ids and + // indicating whether they can be reached or not. Acting as a fifo if object ids cannot fit. + // In the temporary object index memory, SPIFFS_OBJ_ID_IX_FLAG bit is used to indicate + // a reachable/unreachable object id. + memset(fs->work, 0, SPIFFS_CFG_LOG_PAGE_SZ(fs)); + u32_t obj_id_log_ix = 0; + CHECK_CB(fs, SPIFFS_CHECK_INDEX, SPIFFS_CHECK_PROGRESS, 0, 0); + res = spiffs_obj_lu_find_entry_visitor(fs, 0, 0, 0, 0, spiffs_object_index_consistency_check_v, 0, &obj_id_log_ix, + 0, 0); + if (res == SPIFFS_VIS_END) { + res = SPIFFS_OK; + } + if (res != SPIFFS_OK) { + CHECK_CB(fs, SPIFFS_CHECK_INDEX, SPIFFS_CHECK_ERROR, res, 0); + } + CHECK_CB(fs, SPIFFS_CHECK_INDEX, SPIFFS_CHECK_PROGRESS, 256, 0); + return res; +} + +#endif // !SPIFFS_READ_ONLY diff --git a/armsrc/spiffs_config.h b/armsrc/spiffs_config.h new file mode 100644 index 000000000..5e214380b --- /dev/null +++ b/armsrc/spiffs_config.h @@ -0,0 +1,388 @@ +/* + * spiffs_config.h + * + * Created on: Jul 3, 2013 + * Author: petera + */ + +#ifndef SPIFFS_CONFIG_H_ +#define SPIFFS_CONFIG_H_ + +// ----------- 8< ------------ +// Following includes are for the linux test build of spiffs +// These may/should/must be removed/altered/replaced in your target +//#include +//#include +// +#include "printf.h" +#include "string.h" +#include "flashmem.h" + +void Dbprintf(const char *fmt, ...); + +//#include +//#include +// ----------- >8 ------------ + + + typedef int s32_t; + typedef uint32_t u32_t; + typedef int16_t s16_t; + typedef uint16_t u16_t; + typedef int8_t s8_t; + typedef uint8_t u8_t; + +// compile time switches + +// Set generic spiffs debug output call. +#ifndef SPIFFS_DBG +#define SPIFFS_DBG(_f, ...) //Dbprintf(_f, ## __VA_ARGS__) +#define SPIFFS_DBGF(str) SPIFFS_DBG(str,NULL) +#endif +// Set spiffs debug output call for garbage collecting. +#ifndef SPIFFS_GC_DBG +#define SPIFFS_GC_DBG(_f, ...) +#define SPIFFS_GC_DBGF(str) SPIFFS_GC_DBG(str,NULL) +#endif +// Set spiffs debug output call for caching. +#ifndef SPIFFS_CACHE_DBG +#define SPIFFS_CACHE_DBG(_f, ...) //Dbprintf(_f, ## __VA_ARGS__) +#define SPIFFS_CACHE_DBGF(str) SPIFFS_CACHE_DBG(str,NULL) +#endif +// Set spiffs debug output call for system consistency checks. +#ifndef SPIFFS_CHECK_DBG +#define SPIFFS_CHECK_DBG(_f, ...) //SPIFFS_CHECK_DBG(_f, ## __VA_ARGS__) +#define SPIFFS_CHECK_DBGF(str) SPIFFS_CHECK_DBG(str,NULL) +#endif +// Set spiffs debug output call for all api invocations. +#ifndef SPIFFS_API_DBG +#define SPIFFS_API_DBG(_f, ...) //Dbprintf(_f, ## __VA_ARGS__) +#define SPIFFS_API_DBGF(str) SPIFFS_API_DBG(str,NULL) +#endif + + + +// Defines spiffs debug print formatters +// some general signed number +#ifndef _SPIPRIi +#define _SPIPRIi "%d" +#endif +// address +#ifndef _SPIPRIad +#define _SPIPRIad "%08x" +#endif +// block +#ifndef _SPIPRIbl +#define _SPIPRIbl "%04x" +#endif +// page +#ifndef _SPIPRIpg +#define _SPIPRIpg "%04x" +#endif +// span index +#ifndef _SPIPRIsp +#define _SPIPRIsp "%04x" +#endif +// file descriptor +#ifndef _SPIPRIfd +#define _SPIPRIfd "%d" +#endif +// file object id +#ifndef _SPIPRIid +#define _SPIPRIid "%04x" +#endif +// file flags +#ifndef _SPIPRIfl +#define _SPIPRIfl "%02x" +#endif + + +// Enable/disable API functions to determine exact number of bytes +// for filedescriptor and cache buffers. Once decided for a configuration, +// this can be disabled to reduce flash. +#ifndef SPIFFS_BUFFER_HELP +#define SPIFFS_BUFFER_HELP 0 +#endif + +// Enables/disable memory read caching of nucleus file system operations. +// If enabled, memory area must be provided for cache in SPIFFS_mount. +#ifndef SPIFFS_CACHE +#define SPIFFS_CACHE 1 +#endif +#if SPIFFS_CACHE +// Enables memory write caching for file descriptors in hydrogen +#ifndef SPIFFS_CACHE_WR +#define SPIFFS_CACHE_WR 1 +#endif + +// Enable/disable statistics on caching. Debug/test purpose only. +#ifndef SPIFFS_CACHE_STATS +#define SPIFFS_CACHE_STATS 0 +#endif +#endif + +// Always check header of each accessed page to ensure consistent state. +// If enabled it will increase number of reads, will increase flash. +#ifndef SPIFFS_PAGE_CHECK +#define SPIFFS_PAGE_CHECK 0 +#endif + +// Define maximum number of gc runs to perform to reach desired free pages. +#ifndef SPIFFS_GC_MAX_RUNS +#define SPIFFS_GC_MAX_RUNS 5 +#endif + +// Enable/disable statistics on gc. Debug/test purpose only. +#ifndef SPIFFS_GC_STATS +#define SPIFFS_GC_STATS 0 +#endif + +// Garbage collecting examines all pages in a block which and sums up +// to a block score. Deleted pages normally gives positive score and +// used pages normally gives a negative score (as these must be moved). +// To have a fair wear-leveling, the erase age is also included in score, +// whose factor normally is the most positive. +// The larger the score, the more likely it is that the block will +// picked for garbage collection. + +// Garbage collecting heuristics - weight used for deleted pages. +#ifndef SPIFFS_GC_HEUR_W_DELET +#define SPIFFS_GC_HEUR_W_DELET (5) +#endif +// Garbage collecting heuristics - weight used for used pages. +#ifndef SPIFFS_GC_HEUR_W_USED +#define SPIFFS_GC_HEUR_W_USED (-1) +#endif +// Garbage collecting heuristics - weight used for time between +// last erased and erase of this block. +#ifndef SPIFFS_GC_HEUR_W_ERASE_AGE +#define SPIFFS_GC_HEUR_W_ERASE_AGE (50) +#endif + +// Object name maximum length. Note that this length include the +// zero-termination character, meaning maximum string of characters +// can at most be SPIFFS_OBJ_NAME_LEN - 1. +#ifndef SPIFFS_OBJ_NAME_LEN +#define SPIFFS_OBJ_NAME_LEN (32) +#endif + +// Maximum length of the metadata associated with an object. +// Setting to non-zero value enables metadata-related API but also +// changes the on-disk format, so the change is not backward-compatible. +// +// Do note: the meta length must never exceed +// logical_page_size - (SPIFFS_OBJ_NAME_LEN + 64) +// +// This is derived from following: +// logical_page_size - (SPIFFS_OBJ_NAME_LEN + sizeof(spiffs_page_header) + +// spiffs_object_ix_header fields + at least some LUT entries) +#ifndef SPIFFS_OBJ_META_LEN +#define SPIFFS_OBJ_META_LEN (0) +#endif + +// Size of buffer allocated on stack used when copying data. +// Lower value generates more read/writes. No meaning having it bigger +// than logical page size. +#ifndef SPIFFS_COPY_BUFFER_STACK +#define SPIFFS_COPY_BUFFER_STACK (256) +#endif + +// Enable this to have an identifiable spiffs filesystem. This will look for +// a magic in all sectors to determine if this is a valid spiffs system or +// not on mount point. If not, SPIFFS_format must be called prior to mounting +// again. +#ifndef SPIFFS_USE_MAGIC +#define SPIFFS_USE_MAGIC (0) +#endif + +#if SPIFFS_USE_MAGIC +// Only valid when SPIFFS_USE_MAGIC is enabled. If SPIFFS_USE_MAGIC_LENGTH is +// enabled, the magic will also be dependent on the length of the filesystem. +// For example, a filesystem configured and formatted for 4 megabytes will not +// be accepted for mounting with a configuration defining the filesystem as 2 +// megabytes. +#ifndef SPIFFS_USE_MAGIC_LENGTH +#define SPIFFS_USE_MAGIC_LENGTH (0) +#endif +#endif + +// SPIFFS_LOCK and SPIFFS_UNLOCK protects spiffs from reentrancy on api level +// These should be defined on a multithreaded system + +// define this to enter a mutex if you're running on a multithreaded system +#ifndef SPIFFS_LOCK +#define SPIFFS_LOCK(fs) +#endif +// define this to exit a mutex if you're running on a multithreaded system +#ifndef SPIFFS_UNLOCK +#define SPIFFS_UNLOCK(fs) +#endif + +// Enable if only one spiffs instance with constant configuration will exist +// on the target. This will reduce calculations, flash and memory accesses. +// Parts of configuration must be defined below instead of at time of mount. +#ifndef SPIFFS_SINGLETON +#define SPIFFS_SINGLETON (1) +#endif + +#if SPIFFS_SINGLETON +// Instead of giving parameters in config struct, singleton build must +// give parameters in defines below. +#ifndef SPIFFS_CFG_PHYS_SZ +#define SPIFFS_CFG_PHYS_SZ(ignore) (1024*128) +#endif +#ifndef SPIFFS_CFG_PHYS_ERASE_SZ +#define SPIFFS_CFG_PHYS_ERASE_SZ(ignore) (4*1024) +#endif +#ifndef SPIFFS_CFG_PHYS_ADDR +#define SPIFFS_CFG_PHYS_ADDR(ignore) (0) +#endif +#ifndef SPIFFS_CFG_LOG_PAGE_SZ +#define SPIFFS_CFG_LOG_PAGE_SZ(ignore) (256) +#endif +#ifndef SPIFFS_CFG_LOG_BLOCK_SZ +#define SPIFFS_CFG_LOG_BLOCK_SZ(ignore) (4*1024) +#endif +#endif + +// Enable this if your target needs aligned data for index tables +#ifndef SPIFFS_ALIGNED_OBJECT_INDEX_TABLES +#define SPIFFS_ALIGNED_OBJECT_INDEX_TABLES 1 +#endif + +// Enable this if you want the HAL callbacks to be called with the spiffs struct +#ifndef SPIFFS_HAL_CALLBACK_EXTRA +#define SPIFFS_HAL_CALLBACK_EXTRA 0 +#endif + +// Enable this if you want to add an integer offset to all file handles +// (spiffs_file). This is useful if running multiple instances of spiffs on +// same target, in order to recognise to what spiffs instance a file handle +// belongs. +// NB: This adds config field fh_ix_offset in the configuration struct when +// mounting, which must be defined. +#ifndef SPIFFS_FILEHDL_OFFSET +#define SPIFFS_FILEHDL_OFFSET 0 +#endif + +// Enable this to compile a read only version of spiffs. +// This will reduce binary size of spiffs. All code comprising modification +// of the file system will not be compiled. Some config will be ignored. +// HAL functions for erasing and writing to spi-flash may be null. Cache +// can be disabled for even further binary size reduction (and ram savings). +// Functions modifying the fs will return SPIFFS_ERR_RO_NOT_IMPL. +// If the file system cannot be mounted due to aborted erase operation and +// SPIFFS_USE_MAGIC is enabled, SPIFFS_ERR_RO_ABORTED_OPERATION will be +// returned. +// Might be useful for e.g. bootloaders and such. +#ifndef SPIFFS_READ_ONLY +#define SPIFFS_READ_ONLY 0 +#endif + +// Enable this to add a temporal file cache using the fd buffer. +// The effects of the cache is that SPIFFS_open will find the file faster in +// certain cases. It will make it a lot easier for spiffs to find files +// opened frequently, reducing number of readings from the spi flash for +// finding those files. +// This will grow each fd by 6 bytes. If your files are opened in patterns +// with a degree of temporal locality, the system is optimized. +// Examples can be letting spiffs serve web content, where one file is the css. +// The css is accessed for each html file that is opened, meaning it is +// accessed almost every second time a file is opened. Another example could be +// a log file that is often opened, written, and closed. +// The size of the cache is number of given file descriptors, as it piggybacks +// on the fd update mechanism. The cache lives in the closed file descriptors. +// When closed, the fd know the whereabouts of the file. Instead of forgetting +// this, the temporal cache will keep handling updates to that file even if the +// fd is closed. If the file is opened again, the location of the file is found +// directly. If all available descriptors become opened, all cache memory is +// lost. +#ifndef SPIFFS_TEMPORAL_FD_CACHE +#define SPIFFS_TEMPORAL_FD_CACHE 1 +#endif + +// Temporal file cache hit score. Each time a file is opened, all cached files +// will lose one point. If the opened file is found in cache, that entry will +// gain SPIFFS_TEMPORAL_CACHE_HIT_SCORE points. One can experiment with this +// value for the specific access patterns of the application. However, it must +// be between 1 (no gain for hitting a cached entry often) and 255. +#ifndef SPIFFS_TEMPORAL_CACHE_HIT_SCORE +#define SPIFFS_TEMPORAL_CACHE_HIT_SCORE 4 +#endif + +// Enable to be able to map object indices to memory. +// This allows for faster and more deterministic reading if cases of reading +// large files and when changing file offset by seeking around a lot. +// When mapping a file's index, the file system will be scanned for index pages +// and the info will be put in memory provided by user. When reading, the +// memory map can be looked up instead of searching for index pages on the +// medium. This way, user can trade memory against performance. +// Whole, parts of, or future parts not being written yet can be mapped. The +// memory array will be owned by spiffs and updated accordingly during garbage +// collecting or when modifying the indices. The latter is invoked by when the +// file is modified in some way. The index buffer is tied to the file +// descriptor. +#ifndef SPIFFS_IX_MAP +#define SPIFFS_IX_MAP 1 +#endif + +// By default SPIFFS in some cases relies on the property of NOR flash that bits +// cannot be set from 0 to 1 by writing and that controllers will ignore such +// bit changes. This results in fewer reads as SPIFFS can in some cases perform +// blind writes, with all bits set to 1 and only those it needs reset set to 0. +// Most of the chips and controllers allow this behavior, so the default is to +// use this technique. If your controller is one of the rare ones that don't, +// turn this option on and SPIFFS will perform a read-modify-write instead. +#ifndef SPIFFS_NO_BLIND_WRITES +#define SPIFFS_NO_BLIND_WRITES 0 +#endif + +// Set SPIFFS_TEST_VISUALISATION to non-zero to enable SPIFFS_vis function +// in the api. This function will visualize all filesystem using given printf +// function. +#ifndef SPIFFS_TEST_VISUALISATION +#define SPIFFS_TEST_VISUALISATION 0 +#endif +#if SPIFFS_TEST_VISUALISATION +#ifndef spiffs_printf +#define spiffs_printf(...) Dbprintf(__VA_ARGS__) +#endif +// spiffs_printf argument for a free page +#ifndef SPIFFS_TEST_VIS_FREE_STR +#define SPIFFS_TEST_VIS_FREE_STR "_" +#endif +// spiffs_printf argument for a deleted page +#ifndef SPIFFS_TEST_VIS_DELE_STR +#define SPIFFS_TEST_VIS_DELE_STR "/" +#endif +// spiffs_printf argument for an index page for given object id +#ifndef SPIFFS_TEST_VIS_INDX_STR +#define SPIFFS_TEST_VIS_INDX_STR(id) "i" +#endif +// spiffs_printf argument for a data page for given object id +#ifndef SPIFFS_TEST_VIS_DATA_STR +#define SPIFFS_TEST_VIS_DATA_STR(id) "d" +#endif +#endif + +// Types depending on configuration such as the amount of flash bytes +// given to spiffs file system in total (spiffs_file_system_size), +// the logical block size (log_block_size), and the logical page size +// (log_page_size) + +// Block index type. Make sure the size of this type can hold +// the highest number of all blocks - i.e. spiffs_file_system_size / log_block_size +typedef u16_t spiffs_block_ix; +// Page index type. Make sure the size of this type can hold +// the highest page number of all pages - i.e. spiffs_file_system_size / log_page_size +typedef u16_t spiffs_page_ix; +// Object id type - most significant bit is reserved for index flag. Make sure the +// size of this type can hold the highest object id on a full system, +// i.e. 2 + (spiffs_file_system_size / (2*log_page_size))*2 +typedef u16_t spiffs_obj_id; +// Object span index type. Make sure the size of this type can +// hold the largest possible span index on the system - +// i.e. (spiffs_file_system_size / log_page_size) - 1 +typedef u16_t spiffs_span_ix; + +#endif /* SPIFFS_CONFIG_H_ */ diff --git a/armsrc/spiffs_gc.c b/armsrc/spiffs_gc.c new file mode 100644 index 000000000..9da80e375 --- /dev/null +++ b/armsrc/spiffs_gc.c @@ -0,0 +1,606 @@ +#include "spiffs.h" +#include "spiffs_nucleus.h" + +#if !SPIFFS_READ_ONLY + +// Erases a logical block and updates the erase counter. +// If cache is enabled, all pages that might be cached in this block +// is dropped. +static s32_t spiffs_gc_erase_block( + spiffs *fs, + spiffs_block_ix bix) { + s32_t res; + + SPIFFS_GC_DBG("gc: erase block "_SPIPRIbl"\n", bix); + res = spiffs_erase_block(fs, bix); + SPIFFS_CHECK_RES(res); + +#if SPIFFS_CACHE + { + u32_t i; + for (i = 0; i < SPIFFS_PAGES_PER_BLOCK(fs); i++) { + spiffs_cache_drop_page(fs, SPIFFS_PAGE_FOR_BLOCK(fs, bix) + i); + } + } +#endif + return res; +} + +// Searches for blocks where all entries are deleted - if one is found, +// the block is erased. Compared to the non-quick gc, the quick one ensures +// that no updates are needed on existing objects on pages that are erased. +s32_t spiffs_gc_quick( + spiffs *fs, u16_t max_free_pages) { + s32_t res = SPIFFS_OK; + u32_t blocks = fs->block_count; + spiffs_block_ix cur_block = 0; + u32_t cur_block_addr = 0; + int cur_entry = 0; + spiffs_obj_id *obj_lu_buf = (spiffs_obj_id *)fs->lu_work; + + SPIFFS_GC_DBGF("gc_quick: running\n"); +#if SPIFFS_GC_STATS + fs->stats_gc_runs++; +#endif + + int entries_per_page = (SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id)); + + // find fully deleted blocks + // check each block + while (res == SPIFFS_OK && blocks--) { + u16_t deleted_pages_in_block = 0; + u16_t free_pages_in_block = 0; + + int obj_lookup_page = 0; + // check each object lookup page + while (res == SPIFFS_OK && obj_lookup_page < (int)SPIFFS_OBJ_LOOKUP_PAGES(fs)) { + int entry_offset = obj_lookup_page * entries_per_page; + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, + 0, cur_block_addr + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); + // check each entry + while (res == SPIFFS_OK && + cur_entry - entry_offset < entries_per_page && + cur_entry < (int)(SPIFFS_PAGES_PER_BLOCK(fs)-SPIFFS_OBJ_LOOKUP_PAGES(fs))) { + spiffs_obj_id obj_id = obj_lu_buf[cur_entry-entry_offset]; + if (obj_id == SPIFFS_OBJ_ID_DELETED) { + deleted_pages_in_block++; + } else if (obj_id == SPIFFS_OBJ_ID_FREE) { + // kill scan, go for next block + free_pages_in_block++; + if (free_pages_in_block > max_free_pages) { + obj_lookup_page = SPIFFS_OBJ_LOOKUP_PAGES(fs); + res = 1; // kill object lu loop + break; + } + } else { + // kill scan, go for next block + obj_lookup_page = SPIFFS_OBJ_LOOKUP_PAGES(fs); + res = 1; // kill object lu loop + break; + } + cur_entry++; + } // per entry + obj_lookup_page++; + } // per object lookup page + if (res == 1) res = SPIFFS_OK; + + if (res == SPIFFS_OK && + deleted_pages_in_block + free_pages_in_block == SPIFFS_PAGES_PER_BLOCK(fs)-SPIFFS_OBJ_LOOKUP_PAGES(fs) && + free_pages_in_block <= max_free_pages) { + // found a fully deleted block + fs->stats_p_deleted -= deleted_pages_in_block; + res = spiffs_gc_erase_block(fs, cur_block); + return res; + } + + cur_entry = 0; + cur_block++; + cur_block_addr += SPIFFS_CFG_LOG_BLOCK_SZ(fs); + } // per block + + if (res == SPIFFS_OK) { + res = SPIFFS_ERR_NO_DELETED_BLOCKS; + } + return res; +} + +// Checks if garbage collecting is necessary. If so a candidate block is found, +// cleansed and erased +s32_t spiffs_gc_check( + spiffs *fs, + u32_t len) { + s32_t res; + s32_t free_pages = + (SPIFFS_PAGES_PER_BLOCK(fs) - SPIFFS_OBJ_LOOKUP_PAGES(fs)) * (fs->block_count-2) + - fs->stats_p_allocated - fs->stats_p_deleted; + int tries = 0; + + if (fs->free_blocks > 3 && + (s32_t)len < free_pages * (s32_t)SPIFFS_DATA_PAGE_SIZE(fs)) { + return SPIFFS_OK; + } + + u32_t needed_pages = (len + SPIFFS_DATA_PAGE_SIZE(fs) - 1) / SPIFFS_DATA_PAGE_SIZE(fs); +// if (fs->free_blocks <= 2 && (s32_t)needed_pages > free_pages) { +// SPIFFS_GC_DBG("gc: full freeblk:"_SPIPRIi" needed:"_SPIPRIi" free:"_SPIPRIi" dele:"_SPIPRIi"\n", fs->free_blocks, needed_pages, free_pages, fs->stats_p_deleted); +// return SPIFFS_ERR_FULL; +// } + if ((s32_t)needed_pages > (s32_t)(free_pages + fs->stats_p_deleted)) { + SPIFFS_GC_DBG("gc_check: full freeblk:"_SPIPRIi" needed:"_SPIPRIi" free:"_SPIPRIi" dele:"_SPIPRIi"\n", fs->free_blocks, needed_pages, free_pages, fs->stats_p_deleted); + return SPIFFS_ERR_FULL; + } + + do { + SPIFFS_GC_DBG("\ngc_check #"_SPIPRIi": run gc free_blocks:"_SPIPRIi" pfree:"_SPIPRIi" pallo:"_SPIPRIi" pdele:"_SPIPRIi" ["_SPIPRIi"] len:"_SPIPRIi" of "_SPIPRIi"\n", + tries, + fs->free_blocks, free_pages, fs->stats_p_allocated, fs->stats_p_deleted, (free_pages+fs->stats_p_allocated+fs->stats_p_deleted), + len, (u32_t)(free_pages*SPIFFS_DATA_PAGE_SIZE(fs))); + + spiffs_block_ix *cands; + int count; + spiffs_block_ix cand; + s32_t prev_free_pages = free_pages; + // if the fs is crammed, ignore block age when selecting candidate - kind of a bad state + res = spiffs_gc_find_candidate(fs, &cands, &count, free_pages <= 0); + SPIFFS_CHECK_RES(res); + if (count == 0) { + SPIFFS_GC_DBGF("gc_check: no candidates, return\n"); + return (s32_t)needed_pages < free_pages ? SPIFFS_OK : SPIFFS_ERR_FULL; + } +#if SPIFFS_GC_STATS + fs->stats_gc_runs++; +#endif + cand = cands[0]; + fs->cleaning = 1; + //SPIFFS_GC_DBG("gcing: cleaning block "_SPIPRIi"\n", cand); + res = spiffs_gc_clean(fs, cand); + fs->cleaning = 0; + if (res < 0) { + SPIFFS_GC_DBG("gc_check: cleaning block "_SPIPRIi", result "_SPIPRIi"\n", cand, res); + } else { + SPIFFS_GC_DBG("gc_check: cleaning block "_SPIPRIi", result "_SPIPRIi"\n", cand, res); + } + SPIFFS_CHECK_RES(res); + + res = spiffs_gc_erase_page_stats(fs, cand); + SPIFFS_CHECK_RES(res); + + res = spiffs_gc_erase_block(fs, cand); + SPIFFS_CHECK_RES(res); + + free_pages = + (SPIFFS_PAGES_PER_BLOCK(fs) - SPIFFS_OBJ_LOOKUP_PAGES(fs)) * (fs->block_count - 2) + - fs->stats_p_allocated - fs->stats_p_deleted; + + if (prev_free_pages <= 0 && prev_free_pages == free_pages) { + // abort early to reduce wear, at least tried once + SPIFFS_GC_DBGF("gc_check: early abort, no result on gc when fs crammed\n"); + break; + } + + } while (++tries < SPIFFS_GC_MAX_RUNS && (fs->free_blocks <= 2 || + (s32_t)len > free_pages*(s32_t)SPIFFS_DATA_PAGE_SIZE(fs))); + + free_pages = + (SPIFFS_PAGES_PER_BLOCK(fs) - SPIFFS_OBJ_LOOKUP_PAGES(fs)) * (fs->block_count - 2) + - fs->stats_p_allocated - fs->stats_p_deleted; + if ((s32_t)len > free_pages*(s32_t)SPIFFS_DATA_PAGE_SIZE(fs)) { + res = SPIFFS_ERR_FULL; + } + + SPIFFS_GC_DBG("gc_check: finished, "_SPIPRIi" dirty, blocks "_SPIPRIi" free, "_SPIPRIi" pages free, "_SPIPRIi" tries, res "_SPIPRIi"\n", + fs->stats_p_allocated + fs->stats_p_deleted, + fs->free_blocks, free_pages, tries, res); + + return res; +} + +// Updates page statistics for a block that is about to be erased +s32_t spiffs_gc_erase_page_stats( + spiffs *fs, + spiffs_block_ix bix) { + s32_t res = SPIFFS_OK; + int obj_lookup_page = 0; + int entries_per_page = (SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id)); + spiffs_obj_id *obj_lu_buf = (spiffs_obj_id *)fs->lu_work; + int cur_entry = 0; + u32_t dele = 0; + u32_t allo = 0; + + // check each object lookup page + while (res == SPIFFS_OK && obj_lookup_page < (int)SPIFFS_OBJ_LOOKUP_PAGES(fs)) { + int entry_offset = obj_lookup_page * entries_per_page; + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, + 0, bix * SPIFFS_CFG_LOG_BLOCK_SZ(fs) + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); + // check each entry + while (res == SPIFFS_OK && + cur_entry - entry_offset < entries_per_page && cur_entry < (int)(SPIFFS_PAGES_PER_BLOCK(fs)-SPIFFS_OBJ_LOOKUP_PAGES(fs))) { + spiffs_obj_id obj_id = obj_lu_buf[cur_entry-entry_offset]; + if (obj_id == SPIFFS_OBJ_ID_FREE) { + } else if (obj_id == SPIFFS_OBJ_ID_DELETED) { + dele++; + } else { + allo++; + } + cur_entry++; + } // per entry + obj_lookup_page++; + } // per object lookup page + SPIFFS_GC_DBG("gc_check: wipe pallo:"_SPIPRIi" pdele:"_SPIPRIi"\n", allo, dele); + fs->stats_p_allocated -= allo; + fs->stats_p_deleted -= dele; + return res; +} + +// Finds block candidates to erase +s32_t spiffs_gc_find_candidate( + spiffs *fs, + spiffs_block_ix **block_candidates, + int *candidate_count, + char fs_crammed) { + s32_t res = SPIFFS_OK; + u32_t blocks = fs->block_count; + spiffs_block_ix cur_block = 0; + u32_t cur_block_addr = 0; + spiffs_obj_id *obj_lu_buf = (spiffs_obj_id *)fs->lu_work; + int cur_entry = 0; + + // using fs->work area as sorted candidate memory, (spiffs_block_ix)cand_bix/(s32_t)score + int max_candidates = MIN(fs->block_count, (SPIFFS_CFG_LOG_PAGE_SZ(fs)-8)/(sizeof(spiffs_block_ix) + sizeof(s32_t))); + *candidate_count = 0; + memset(fs->work, 0xff, SPIFFS_CFG_LOG_PAGE_SZ(fs)); + + // divide up work area into block indices and scores + spiffs_block_ix *cand_blocks = (spiffs_block_ix *)fs->work; + s32_t *cand_scores = (s32_t *)(fs->work + max_candidates * sizeof(spiffs_block_ix)); + + // align cand_scores on s32_t boundary + cand_scores = (s32_t*)(((intptr_t)cand_scores + sizeof(intptr_t) - 1) & ~(sizeof(intptr_t) - 1)); + + *block_candidates = cand_blocks; + + int entries_per_page = (SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id)); + + // check each block + while (res == SPIFFS_OK && blocks--) { + u16_t deleted_pages_in_block = 0; + u16_t used_pages_in_block = 0; + + int obj_lookup_page = 0; + // check each object lookup page + while (res == SPIFFS_OK && obj_lookup_page < (int)SPIFFS_OBJ_LOOKUP_PAGES(fs)) { + int entry_offset = obj_lookup_page * entries_per_page; + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, + 0, cur_block_addr + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); + // check each entry + while (res == SPIFFS_OK && + cur_entry - entry_offset < entries_per_page && + cur_entry < (int)(SPIFFS_PAGES_PER_BLOCK(fs)-SPIFFS_OBJ_LOOKUP_PAGES(fs))) { + spiffs_obj_id obj_id = obj_lu_buf[cur_entry-entry_offset]; + if (obj_id == SPIFFS_OBJ_ID_FREE) { + // when a free entry is encountered, scan logic ensures that all following entries are free also + res = 1; // kill object lu loop + break; + } else if (obj_id == SPIFFS_OBJ_ID_DELETED) { + deleted_pages_in_block++; + } else { + used_pages_in_block++; + } + cur_entry++; + } // per entry + obj_lookup_page++; + } // per object lookup page + if (res == 1) res = SPIFFS_OK; + + // calculate score and insert into candidate table + // stoneage sort, but probably not so many blocks + if (res == SPIFFS_OK /*&& deleted_pages_in_block > 0*/) { + // read erase count + spiffs_obj_id erase_count; + res = _spiffs_rd(fs, SPIFFS_OP_C_READ | SPIFFS_OP_T_OBJ_LU2, 0, + SPIFFS_ERASE_COUNT_PADDR(fs, cur_block), + sizeof(spiffs_obj_id), (u8_t *)&erase_count); + SPIFFS_CHECK_RES(res); + + spiffs_obj_id erase_age; + if (fs->max_erase_count > erase_count) { + erase_age = fs->max_erase_count - erase_count; + } else { + erase_age = SPIFFS_OBJ_ID_FREE - (erase_count - fs->max_erase_count); + } + + s32_t score = + deleted_pages_in_block * SPIFFS_GC_HEUR_W_DELET + + used_pages_in_block * SPIFFS_GC_HEUR_W_USED + + erase_age * (fs_crammed ? 0 : SPIFFS_GC_HEUR_W_ERASE_AGE); + int cand_ix = 0; + SPIFFS_GC_DBG("gc_check: bix:"_SPIPRIbl" del:"_SPIPRIi" use:"_SPIPRIi" score:"_SPIPRIi"\n", cur_block, deleted_pages_in_block, used_pages_in_block, score); + while (cand_ix < max_candidates) { + if (cand_blocks[cand_ix] == (spiffs_block_ix)-1) { + cand_blocks[cand_ix] = cur_block; + cand_scores[cand_ix] = score; + break; + } else if (cand_scores[cand_ix] < score) { + int reorder_cand_ix = max_candidates - 2; + while (reorder_cand_ix >= cand_ix) { + cand_blocks[reorder_cand_ix + 1] = cand_blocks[reorder_cand_ix]; + cand_scores[reorder_cand_ix + 1] = cand_scores[reorder_cand_ix]; + reorder_cand_ix--; + } + cand_blocks[cand_ix] = cur_block; + cand_scores[cand_ix] = score; + break; + } + cand_ix++; + } + (*candidate_count)++; + } + + cur_entry = 0; + cur_block++; + cur_block_addr += SPIFFS_CFG_LOG_BLOCK_SZ(fs); + } // per block + + return res; +} + +typedef enum { + FIND_OBJ_DATA, + MOVE_OBJ_DATA, + MOVE_OBJ_IX, + FINISHED +} spiffs_gc_clean_state; + +typedef struct { + spiffs_gc_clean_state state; + spiffs_obj_id cur_obj_id; + spiffs_span_ix cur_objix_spix; + spiffs_page_ix cur_objix_pix; + spiffs_page_ix cur_data_pix; + int stored_scan_entry_index; + u8_t obj_id_found; +} spiffs_gc; + +// Empties given block by moving all data into free pages of another block +// Strategy: +// loop: +// scan object lookup for object data pages +// for first found id, check spix and load corresponding object index page to memory +// push object scan lookup entry index +// rescan object lookup, find data pages with same id and referenced by same object index +// move data page, update object index in memory +// when reached end of lookup, store updated object index +// pop object scan lookup entry index +// repeat loop until end of object lookup +// scan object lookup again for remaining object index pages, move to new page in other block +// +s32_t spiffs_gc_clean(spiffs *fs, spiffs_block_ix bix) { + s32_t res = SPIFFS_OK; + const int entries_per_page = (SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id)); + // this is the global localizer being pushed and popped + int cur_entry = 0; + spiffs_obj_id *obj_lu_buf = (spiffs_obj_id *)fs->lu_work; + spiffs_gc gc; // our stack frame/state + spiffs_page_ix cur_pix = 0; + spiffs_page_object_ix_header *objix_hdr = (spiffs_page_object_ix_header *)fs->work; + spiffs_page_object_ix *objix = (spiffs_page_object_ix *)fs->work; + + SPIFFS_GC_DBG("gc_clean: cleaning block "_SPIPRIbl"\n", bix); + + memset(&gc, 0, sizeof(spiffs_gc)); + gc.state = FIND_OBJ_DATA; + + if (fs->free_cursor_block_ix == bix) { + // move free cursor to next block, cannot use free pages from the block we want to clean + fs->free_cursor_block_ix = (bix+1)%fs->block_count; + fs->free_cursor_obj_lu_entry = 0; + SPIFFS_GC_DBG("gc_clean: move free cursor to block "_SPIPRIbl"\n", fs->free_cursor_block_ix); + } + + while (res == SPIFFS_OK && gc.state != FINISHED) { + SPIFFS_GC_DBG("gc_clean: state = "_SPIPRIi" entry:"_SPIPRIi"\n", gc.state, cur_entry); + gc.obj_id_found = 0; // reset (to no found data page) + + // scan through lookup pages + int obj_lookup_page = cur_entry / entries_per_page; + u8_t scan = 1; + // check each object lookup page + while (scan && res == SPIFFS_OK && obj_lookup_page < (int)SPIFFS_OBJ_LOOKUP_PAGES(fs)) { + int entry_offset = obj_lookup_page * entries_per_page; + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, + 0, bix * SPIFFS_CFG_LOG_BLOCK_SZ(fs) + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), + SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); + // check each object lookup entry + while (scan && res == SPIFFS_OK && + cur_entry - entry_offset < entries_per_page && cur_entry < (int)(SPIFFS_PAGES_PER_BLOCK(fs)-SPIFFS_OBJ_LOOKUP_PAGES(fs))) { + spiffs_obj_id obj_id = obj_lu_buf[cur_entry-entry_offset]; + cur_pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, cur_entry); + + // act upon object id depending on gc state + switch (gc.state) { + case FIND_OBJ_DATA: + // find a data page + if (obj_id != SPIFFS_OBJ_ID_DELETED && obj_id != SPIFFS_OBJ_ID_FREE && + ((obj_id & SPIFFS_OBJ_ID_IX_FLAG) == 0)) { + // found a data page, stop scanning and handle in switch case below + SPIFFS_GC_DBG("gc_clean: FIND_DATA state:"_SPIPRIi" - found obj id "_SPIPRIid"\n", gc.state, obj_id); + gc.obj_id_found = 1; + gc.cur_obj_id = obj_id; + gc.cur_data_pix = cur_pix; + scan = 0; + } + break; + case MOVE_OBJ_DATA: + // evacuate found data pages for corresponding object index we have in memory, + // update memory representation + if (obj_id == gc.cur_obj_id) { + spiffs_page_header p_hdr; + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, + 0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix), sizeof(spiffs_page_header), (u8_t*)&p_hdr); + SPIFFS_CHECK_RES(res); + SPIFFS_GC_DBG("gc_clean: MOVE_DATA found data page "_SPIPRIid":"_SPIPRIsp" @ "_SPIPRIpg"\n", gc.cur_obj_id, p_hdr.span_ix, cur_pix); + if (SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, p_hdr.span_ix) != gc.cur_objix_spix) { + SPIFFS_GC_DBGF("gc_clean: MOVE_DATA no objix spix match, take in another run\n"); + } else { + spiffs_page_ix new_data_pix; + if (p_hdr.flags & SPIFFS_PH_FLAG_DELET) { + // move page + res = spiffs_page_move(fs, 0, 0, obj_id, &p_hdr, cur_pix, &new_data_pix); + SPIFFS_GC_DBG("gc_clean: MOVE_DATA move objix "_SPIPRIid":"_SPIPRIsp" page "_SPIPRIpg" to "_SPIPRIpg"\n", gc.cur_obj_id, p_hdr.span_ix, cur_pix, new_data_pix); + SPIFFS_CHECK_RES(res); + // move wipes obj_lu, reload it + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, + 0, bix * SPIFFS_CFG_LOG_BLOCK_SZ(fs) + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), + SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); + SPIFFS_CHECK_RES(res); + } else { + // page is deleted but not deleted in lookup, scrap it - + // might seem unnecessary as we will erase this block, but + // we might get aborted + SPIFFS_GC_DBG("gc_clean: MOVE_DATA wipe objix "_SPIPRIid":"_SPIPRIsp" page "_SPIPRIpg"\n", obj_id, p_hdr.span_ix, cur_pix); + res = spiffs_page_delete(fs, cur_pix); + SPIFFS_CHECK_RES(res); + new_data_pix = SPIFFS_OBJ_ID_FREE; + } + // update memory representation of object index page with new data page + if (gc.cur_objix_spix == 0) { + // update object index header page + ((spiffs_page_ix*)((u8_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[p_hdr.span_ix] = new_data_pix; + SPIFFS_GC_DBG("gc_clean: MOVE_DATA wrote page "_SPIPRIpg" to objix_hdr entry "_SPIPRIsp" in mem\n", new_data_pix, (spiffs_span_ix)SPIFFS_OBJ_IX_ENTRY(fs, p_hdr.span_ix)); + } else { + // update object index page + ((spiffs_page_ix*)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, p_hdr.span_ix)] = new_data_pix; + SPIFFS_GC_DBG("gc_clean: MOVE_DATA wrote page "_SPIPRIpg" to objix entry "_SPIPRIsp" in mem\n", new_data_pix, (spiffs_span_ix)SPIFFS_OBJ_IX_ENTRY(fs, p_hdr.span_ix)); + } + } + } + break; + case MOVE_OBJ_IX: + // find and evacuate object index pages + if (obj_id != SPIFFS_OBJ_ID_DELETED && obj_id != SPIFFS_OBJ_ID_FREE && + (obj_id & SPIFFS_OBJ_ID_IX_FLAG)) { + // found an index object id + spiffs_page_header p_hdr; + spiffs_page_ix new_pix; + // load header + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, + 0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix), sizeof(spiffs_page_header), (u8_t*)&p_hdr); + SPIFFS_CHECK_RES(res); + if (p_hdr.flags & SPIFFS_PH_FLAG_DELET) { + // move page + res = spiffs_page_move(fs, 0, 0, obj_id, &p_hdr, cur_pix, &new_pix); + SPIFFS_GC_DBG("gc_clean: MOVE_OBJIX move objix "_SPIPRIid":"_SPIPRIsp" page "_SPIPRIpg" to "_SPIPRIpg"\n", obj_id, p_hdr.span_ix, cur_pix, new_pix); + SPIFFS_CHECK_RES(res); + spiffs_cb_object_event(fs, (spiffs_page_object_ix *)&p_hdr, + SPIFFS_EV_IX_MOV, obj_id, p_hdr.span_ix, new_pix, 0); + // move wipes obj_lu, reload it + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, + 0, bix * SPIFFS_CFG_LOG_BLOCK_SZ(fs) + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), + SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); + SPIFFS_CHECK_RES(res); + } else { + // page is deleted but not deleted in lookup, scrap it - + // might seem unnecessary as we will erase this block, but + // we might get aborted + SPIFFS_GC_DBG("gc_clean: MOVE_OBJIX wipe objix "_SPIPRIid":"_SPIPRIsp" page "_SPIPRIpg"\n", obj_id, p_hdr.span_ix, cur_pix); + res = spiffs_page_delete(fs, cur_pix); + if (res == SPIFFS_OK) { + spiffs_cb_object_event(fs, (spiffs_page_object_ix *)0, + SPIFFS_EV_IX_DEL, obj_id, p_hdr.span_ix, cur_pix, 0); + } + } + SPIFFS_CHECK_RES(res); + } + break; + default: + scan = 0; + break; + } // switch gc state + cur_entry++; + } // per entry + obj_lookup_page++; // no need to check scan variable here, obj_lookup_page is set in start of loop + } // per object lookup page + if (res != SPIFFS_OK) break; + + // state finalization and switch + switch (gc.state) { + case FIND_OBJ_DATA: + if (gc.obj_id_found) { + // handle found data page - + // find out corresponding obj ix page and load it to memory + spiffs_page_header p_hdr; + spiffs_page_ix objix_pix; + gc.stored_scan_entry_index = cur_entry; // push cursor + cur_entry = 0; // restart scan from start + gc.state = MOVE_OBJ_DATA; + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, + 0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix), sizeof(spiffs_page_header), (u8_t*)&p_hdr); + SPIFFS_CHECK_RES(res); + gc.cur_objix_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, p_hdr.span_ix); + SPIFFS_GC_DBG("gc_clean: FIND_DATA find objix span_ix:"_SPIPRIsp"\n", gc.cur_objix_spix); + res = spiffs_obj_lu_find_id_and_span(fs, gc.cur_obj_id | SPIFFS_OBJ_ID_IX_FLAG, gc.cur_objix_spix, 0, &objix_pix); + if (res == SPIFFS_ERR_NOT_FOUND) { + // on borked systems we might get an ERR_NOT_FOUND here - + // this is handled by simply deleting the page as it is not referenced + // from anywhere + SPIFFS_GC_DBG("gc_clean: FIND_OBJ_DATA objix not found! Wipe page "_SPIPRIpg"\n", gc.cur_data_pix); + res = spiffs_page_delete(fs, gc.cur_data_pix); + SPIFFS_CHECK_RES(res); + // then we restore states and continue scanning for data pages + cur_entry = gc.stored_scan_entry_index; // pop cursor + gc.state = FIND_OBJ_DATA; + break; // done + } + SPIFFS_CHECK_RES(res); + SPIFFS_GC_DBG("gc_clean: FIND_DATA found object index at page "_SPIPRIpg"\n", objix_pix); + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, + 0, SPIFFS_PAGE_TO_PADDR(fs, objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); + SPIFFS_CHECK_RES(res); + // cannot allow a gc if the presumed index in fact is no index, a + // check must run or lot of data may be lost + SPIFFS_VALIDATE_OBJIX(objix->p_hdr, gc.cur_obj_id | SPIFFS_OBJ_ID_IX_FLAG, gc.cur_objix_spix); + gc.cur_objix_pix = objix_pix; + } else { + // no more data pages found, passed thru all block, start evacuating object indices + gc.state = MOVE_OBJ_IX; + cur_entry = 0; // restart entry scan index + } + break; + case MOVE_OBJ_DATA: { + // store modified objix (hdr) page residing in memory now that all + // data pages belonging to this object index and residing in the block + // we want to evacuate + spiffs_page_ix new_objix_pix; + gc.state = FIND_OBJ_DATA; + cur_entry = gc.stored_scan_entry_index; // pop cursor + if (gc.cur_objix_spix == 0) { + // store object index header page + res = spiffs_object_update_index_hdr(fs, 0, gc.cur_obj_id | SPIFFS_OBJ_ID_IX_FLAG, gc.cur_objix_pix, fs->work, 0, 0, 0, &new_objix_pix); + SPIFFS_GC_DBG("gc_clean: MOVE_DATA store modified objix_hdr page, "_SPIPRIpg":"_SPIPRIsp"\n", new_objix_pix, 0); + SPIFFS_CHECK_RES(res); + } else { + // store object index page + res = spiffs_page_move(fs, 0, fs->work, gc.cur_obj_id | SPIFFS_OBJ_ID_IX_FLAG, 0, gc.cur_objix_pix, &new_objix_pix); + SPIFFS_GC_DBG("gc_clean: MOVE_DATA store modified objix page, "_SPIPRIpg":"_SPIPRIsp"\n", new_objix_pix, objix->p_hdr.span_ix); + SPIFFS_CHECK_RES(res); + spiffs_cb_object_event(fs, (spiffs_page_object_ix *)fs->work, + SPIFFS_EV_IX_UPD, gc.cur_obj_id, objix->p_hdr.span_ix, new_objix_pix, 0); + } + } + break; + case MOVE_OBJ_IX: + // scanned thru all block, no more object indices found - our work here is done + gc.state = FINISHED; + break; + default: + cur_entry = 0; + break; + } // switch gc.state + SPIFFS_GC_DBG("gc_clean: state-> "_SPIPRIi"\n", gc.state); + } // while state != FINISHED + + + return res; +} + +#endif // !SPIFFS_READ_ONLY diff --git a/armsrc/spiffs_hydrogen.c b/armsrc/spiffs_hydrogen.c new file mode 100644 index 000000000..adc107270 --- /dev/null +++ b/armsrc/spiffs_hydrogen.c @@ -0,0 +1,1452 @@ +/* + * spiffs_hydrogen.c + * + * Created on: Jun 16, 2013 + * Author: petera + */ + +#include "spiffs.h" +#include "spiffs_nucleus.h" +#include "printf.h" + +#if SPIFFS_CACHE == 1 +static s32_t spiffs_fflush_cache(spiffs *fs, spiffs_file fh); +#endif + +#if SPIFFS_BUFFER_HELP +u32_t SPIFFS_buffer_bytes_for_filedescs(spiffs *fs, u32_t num_descs) { + return num_descs * sizeof(spiffs_fd); +} +#if SPIFFS_CACHE +u32_t SPIFFS_buffer_bytes_for_cache(spiffs *fs, u32_t num_pages) { + return sizeof(spiffs_cache) + num_pages * (sizeof(spiffs_cache_page) + SPIFFS_CFG_LOG_PAGE_SZ(fs)); +} +#endif +#endif + +u8_t SPIFFS_mounted(spiffs *fs) { + return SPIFFS_CHECK_MOUNT(fs); +} + +s32_t SPIFFS_format(spiffs *fs) { +#if SPIFFS_READ_ONLY + (void)fs; + return SPIFFS_ERR_RO_NOT_IMPL; +#else + SPIFFS_API_CHECK_CFG(fs); + if (SPIFFS_CHECK_MOUNT(fs)) { + fs->err_code = SPIFFS_ERR_MOUNTED; + return -1; + } + + s32_t res; + SPIFFS_LOCK(fs); + + spiffs_block_ix bix = 0; + while (bix < fs->block_count) { + fs->max_erase_count = 0; + res = spiffs_erase_block(fs, bix); + if (res != SPIFFS_OK) { + res = SPIFFS_ERR_ERASE_FAIL; + } + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + bix++; + } + + SPIFFS_UNLOCK(fs); + + return 0; +#endif // SPIFFS_READ_ONLY +} + +#if SPIFFS_USE_MAGIC && SPIFFS_USE_MAGIC_LENGTH && SPIFFS_SINGLETON==0 + +s32_t SPIFFS_probe_fs(spiffs_config *config) { + SPIFFS_API_DBG("%s\n", __func__); + s32_t res = spiffs_probe(config); + return res; +} + +#endif // SPIFFS_USE_MAGIC && SPIFFS_USE_MAGIC_LENGTH && SPIFFS_SINGLETON==0 + +s32_t SPIFFS_mount(spiffs *fs, spiffs_config *config, u8_t *work, + u8_t *fd_space, u32_t fd_space_size, + void *cache, u32_t cache_size, + spiffs_check_callback check_cb_f) { + SPIFFS_API_DBG("%s " + " sz:"_SPIPRIi " logpgsz:"_SPIPRIi " logblksz:"_SPIPRIi " perasz:"_SPIPRIi + " addr:"_SPIPRIad + " fdsz:"_SPIPRIi " cachesz:"_SPIPRIi + "\n", + __func__, + SPIFFS_CFG_PHYS_SZ(fs), + SPIFFS_CFG_LOG_PAGE_SZ(fs), + SPIFFS_CFG_LOG_BLOCK_SZ(fs), + SPIFFS_CFG_PHYS_ERASE_SZ(fs), + SPIFFS_CFG_PHYS_ADDR(fs), + fd_space_size, cache_size); + void *user_data; + SPIFFS_LOCK(fs); + user_data = fs->user_data; + memset(fs, 0, sizeof(spiffs)); + _SPIFFS_MEMCPY(&fs->cfg, config, sizeof(spiffs_config)); + fs->user_data = user_data; + fs->block_count = SPIFFS_CFG_PHYS_SZ(fs) / SPIFFS_CFG_LOG_BLOCK_SZ(fs); + fs->work = &work[0]; + fs->lu_work = &work[SPIFFS_CFG_LOG_PAGE_SZ(fs)]; + memset(fd_space, 0, fd_space_size); + // align fd_space pointer to pointer size byte boundary + u8_t ptr_size = sizeof(void*); + u8_t addr_lsb = ((u8_t)(intptr_t)fd_space) & (ptr_size-1); + if (addr_lsb) { + fd_space += (ptr_size-addr_lsb); + fd_space_size -= (ptr_size-addr_lsb); + } + fs->fd_space = fd_space; + fs->fd_count = (fd_space_size/sizeof(spiffs_fd)); + + // align cache pointer to 4 byte boundary + addr_lsb = ((u8_t)(intptr_t)cache) & (ptr_size-1); + if (addr_lsb) { + u8_t *cache_8 = (u8_t *)cache; + cache_8 += (ptr_size-addr_lsb); + cache = cache_8; + cache_size -= (ptr_size-addr_lsb); + } + if (cache_size & (ptr_size-1)) { + cache_size -= (cache_size & (ptr_size-1)); + } + +#if SPIFFS_CACHE + fs->cache = cache; + fs->cache_size = (cache_size > (SPIFFS_CFG_LOG_PAGE_SZ(fs)*32)) ? SPIFFS_CFG_LOG_PAGE_SZ(fs)*32 : cache_size; + spiffs_cache_init(fs); +#endif + + s32_t res; + +#if SPIFFS_USE_MAGIC + res = SPIFFS_CHECK_MAGIC_POSSIBLE(fs) ? SPIFFS_OK : SPIFFS_ERR_MAGIC_NOT_POSSIBLE; + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); +#endif + + fs->config_magic = SPIFFS_CONFIG_MAGIC; + + res = spiffs_obj_lu_scan(fs); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + + SPIFFS_DBG("page index byte len: "_SPIPRIi"\n", (u32_t)SPIFFS_CFG_LOG_PAGE_SZ(fs)); + SPIFFS_DBG("object lookup pages: "_SPIPRIi"\n", (u32_t)SPIFFS_OBJ_LOOKUP_PAGES(fs)); + SPIFFS_DBG("page pages per block: "_SPIPRIi"\n", (u32_t)SPIFFS_PAGES_PER_BLOCK(fs)); + SPIFFS_DBG("page header length: "_SPIPRIi"\n", (u32_t)sizeof(spiffs_page_header)); + SPIFFS_DBG("object header index entries: "_SPIPRIi"\n", (u32_t)SPIFFS_OBJ_HDR_IX_LEN(fs)); + SPIFFS_DBG("object index entries: "_SPIPRIi"\n", (u32_t)SPIFFS_OBJ_IX_LEN(fs)); + SPIFFS_DBG("available file descriptors: "_SPIPRIi"\n", (u32_t)fs->fd_count); + SPIFFS_DBG("free blocks: "_SPIPRIi"\n", (u32_t)fs->free_blocks); + + fs->check_cb_f = check_cb_f; + + fs->mounted = 1; + + SPIFFS_UNLOCK(fs); + + return 0; +} + +void SPIFFS_unmount(spiffs *fs) { + SPIFFS_API_DBG("%s\n", __func__); + if (!SPIFFS_CHECK_CFG(fs) || !SPIFFS_CHECK_MOUNT(fs)) return; + SPIFFS_LOCK(fs); + u32_t i; + spiffs_fd *fds = (spiffs_fd *)fs->fd_space; + for (i = 0; i < fs->fd_count; i++) { + spiffs_fd *cur_fd = &fds[i]; + if (cur_fd->file_nbr != 0) { +#if SPIFFS_CACHE + (void)spiffs_fflush_cache(fs, cur_fd->file_nbr); +#endif + spiffs_fd_return(fs, cur_fd->file_nbr); + } + } + fs->mounted = 0; + + SPIFFS_UNLOCK(fs); +} + +s32_t SPIFFS_errno(spiffs *fs) { + return fs->err_code; +} + +void SPIFFS_clearerr(spiffs *fs) { + SPIFFS_API_DBG("%s\n", __func__); + fs->err_code = SPIFFS_OK; +} + +s32_t SPIFFS_creat(spiffs *fs, const char *path, spiffs_mode mode) { + SPIFFS_API_DBG("%s '%s'\n", __func__, path); +#if SPIFFS_READ_ONLY + (void)fs; (void)path; (void)mode; + return SPIFFS_ERR_RO_NOT_IMPL; +#else + (void)mode; + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + if (strlen(path) > SPIFFS_OBJ_NAME_LEN - 1) { + SPIFFS_API_CHECK_RES(fs, SPIFFS_ERR_NAME_TOO_LONG); + } + SPIFFS_LOCK(fs); + spiffs_obj_id obj_id; + s32_t res; + + res = spiffs_obj_lu_find_free_obj_id(fs, &obj_id, (const u8_t*)path); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + res = spiffs_object_create(fs, obj_id, (const u8_t*)path, 0, SPIFFS_TYPE_FILE, 0); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + SPIFFS_UNLOCK(fs); + return 0; +#endif // SPIFFS_READ_ONLY +} + +spiffs_file SPIFFS_open(spiffs *fs, const char *path, spiffs_flags flags, spiffs_mode mode) { + SPIFFS_API_DBG("%s '%s' "_SPIPRIfl "\n", __func__, path, flags); + (void)mode; + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + if (strlen(path) > SPIFFS_OBJ_NAME_LEN - 1) { + SPIFFS_API_CHECK_RES(fs, SPIFFS_ERR_NAME_TOO_LONG); + } + SPIFFS_LOCK(fs); + + spiffs_fd *fd; + spiffs_page_ix pix; + +#if SPIFFS_READ_ONLY + // not valid flags in read only mode + flags &= ~(SPIFFS_WRONLY | SPIFFS_CREAT | SPIFFS_TRUNC); +#endif // SPIFFS_READ_ONLY + + s32_t res = spiffs_fd_find_new(fs, &fd, path); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + + res = spiffs_object_find_object_index_header_by_name(fs, (const u8_t*)path, &pix); + if ((flags & SPIFFS_O_CREAT) == 0) { + if (res < SPIFFS_OK) { + spiffs_fd_return(fs, fd->file_nbr); + } + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + } + + if (res == SPIFFS_OK && + (flags & (SPIFFS_O_CREAT | SPIFFS_O_EXCL)) == (SPIFFS_O_CREAT | SPIFFS_O_EXCL)) { + // creat and excl and file exists - fail + res = SPIFFS_ERR_FILE_EXISTS; + spiffs_fd_return(fs, fd->file_nbr); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + } + + if ((flags & SPIFFS_O_CREAT) && res == SPIFFS_ERR_NOT_FOUND) { +#if !SPIFFS_READ_ONLY + spiffs_obj_id obj_id; + // no need to enter conflicting name here, already looked for it above + res = spiffs_obj_lu_find_free_obj_id(fs, &obj_id, 0); + if (res < SPIFFS_OK) { + spiffs_fd_return(fs, fd->file_nbr); + } + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + res = spiffs_object_create(fs, obj_id, (const u8_t*)path, 0, SPIFFS_TYPE_FILE, &pix); + if (res < SPIFFS_OK) { + spiffs_fd_return(fs, fd->file_nbr); + } + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + flags &= ~SPIFFS_O_TRUNC; +#endif // !SPIFFS_READ_ONLY + } else { + if (res < SPIFFS_OK) { + spiffs_fd_return(fs, fd->file_nbr); + } + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + } + res = spiffs_object_open_by_page(fs, pix, fd, flags, mode); + if (res < SPIFFS_OK) { + spiffs_fd_return(fs, fd->file_nbr); + } + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); +#if !SPIFFS_READ_ONLY + if (flags & SPIFFS_O_TRUNC) { + res = spiffs_object_truncate(fd, 0, 0); + if (res < SPIFFS_OK) { + spiffs_fd_return(fs, fd->file_nbr); + } + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + } +#endif // !SPIFFS_READ_ONLY + + fd->fdoffset = 0; + + SPIFFS_UNLOCK(fs); + + return SPIFFS_FH_OFFS(fs, fd->file_nbr); +} + +spiffs_file SPIFFS_open_by_dirent(spiffs *fs, struct spiffs_dirent *e, spiffs_flags flags, spiffs_mode mode) { + SPIFFS_API_DBG("%s '%s':"_SPIPRIid " "_SPIPRIfl "\n", __func__, e->name, e->obj_id, flags); + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + SPIFFS_LOCK(fs); + + spiffs_fd *fd; + + s32_t res = spiffs_fd_find_new(fs, &fd, 0); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + + res = spiffs_object_open_by_page(fs, e->pix, fd, flags, mode); + if (res < SPIFFS_OK) { + spiffs_fd_return(fs, fd->file_nbr); + } + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); +#if !SPIFFS_READ_ONLY + if (flags & SPIFFS_O_TRUNC) { + res = spiffs_object_truncate(fd, 0, 0); + if (res < SPIFFS_OK) { + spiffs_fd_return(fs, fd->file_nbr); + } + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + } +#endif // !SPIFFS_READ_ONLY + + fd->fdoffset = 0; + + SPIFFS_UNLOCK(fs); + + return SPIFFS_FH_OFFS(fs, fd->file_nbr); +} + +spiffs_file SPIFFS_open_by_page(spiffs *fs, spiffs_page_ix page_ix, spiffs_flags flags, spiffs_mode mode) { + SPIFFS_API_DBG("%s "_SPIPRIpg " "_SPIPRIfl "\n", __func__, page_ix, flags); + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + SPIFFS_LOCK(fs); + + spiffs_fd *fd; + + s32_t res = spiffs_fd_find_new(fs, &fd, 0); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + + if (SPIFFS_IS_LOOKUP_PAGE(fs, page_ix)) { + res = SPIFFS_ERR_NOT_A_FILE; + spiffs_fd_return(fs, fd->file_nbr); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + } + + res = spiffs_object_open_by_page(fs, page_ix, fd, flags, mode); + if (res == SPIFFS_ERR_IS_FREE || + res == SPIFFS_ERR_DELETED || + res == SPIFFS_ERR_NOT_FINALIZED || + res == SPIFFS_ERR_NOT_INDEX || + res == SPIFFS_ERR_INDEX_SPAN_MISMATCH) { + res = SPIFFS_ERR_NOT_A_FILE; + } + if (res < SPIFFS_OK) { + spiffs_fd_return(fs, fd->file_nbr); + } + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + +#if !SPIFFS_READ_ONLY + if (flags & SPIFFS_O_TRUNC) { + res = spiffs_object_truncate(fd, 0, 0); + if (res < SPIFFS_OK) { + spiffs_fd_return(fs, fd->file_nbr); + } + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + } +#endif // !SPIFFS_READ_ONLY + + fd->fdoffset = 0; + + SPIFFS_UNLOCK(fs); + + return SPIFFS_FH_OFFS(fs, fd->file_nbr); +} + +static s32_t spiffs_hydro_read(spiffs *fs, spiffs_file fh, void *buf, s32_t len) { + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + SPIFFS_LOCK(fs); + + spiffs_fd *fd; + s32_t res; + + fh = SPIFFS_FH_UNOFFS(fs, fh); + res = spiffs_fd_get(fs, fh, &fd); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + + if ((fd->flags & SPIFFS_O_RDONLY) == 0) { + res = SPIFFS_ERR_NOT_READABLE; + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + } + + if (fd->size == SPIFFS_UNDEFINED_LEN && len > 0) { + // special case for zero sized files + res = SPIFFS_ERR_END_OF_OBJECT; + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + } + +#if SPIFFS_CACHE_WR + spiffs_fflush_cache(fs, fh); +#endif + + if (fd->fdoffset + len >= fd->size) { + // reading beyond file size + s32_t avail = fd->size - fd->fdoffset; + if (avail <= 0) { + SPIFFS_API_CHECK_RES_UNLOCK(fs, SPIFFS_ERR_END_OF_OBJECT); + } + res = spiffs_object_read(fd, fd->fdoffset, avail, (u8_t*)buf); + if (res == SPIFFS_ERR_END_OF_OBJECT) { + fd->fdoffset += avail; + SPIFFS_UNLOCK(fs); + return avail; + } else { + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + len = avail; + } + } else { + // reading within file size + res = spiffs_object_read(fd, fd->fdoffset, len, (u8_t*)buf); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + } + fd->fdoffset += len; + + SPIFFS_UNLOCK(fs); + + return len; +} + +s32_t SPIFFS_read(spiffs *fs, spiffs_file fh, void *buf, s32_t len) { + SPIFFS_API_DBG("%s "_SPIPRIfd " "_SPIPRIi "\n", __func__, fh, len); + s32_t res = spiffs_hydro_read(fs, fh, buf, len); + if (res == SPIFFS_ERR_END_OF_OBJECT) { + res = 0; + } + return res; +} + + +#if !SPIFFS_READ_ONLY +static s32_t spiffs_hydro_write(spiffs *fs, spiffs_fd *fd, void *buf, u32_t offset, s32_t len) { + (void)fs; + s32_t res = SPIFFS_OK; + s32_t remaining = len; + if (fd->size != SPIFFS_UNDEFINED_LEN && offset < fd->size) { + s32_t m_len = MIN((s32_t)(fd->size - offset), len); + res = spiffs_object_modify(fd, offset, (u8_t *)buf, m_len); + SPIFFS_CHECK_RES(res); + remaining -= m_len; + u8_t *buf_8 = (u8_t *)buf; + buf_8 += m_len; + buf = buf_8; + offset += m_len; + } + if (remaining > 0) { + res = spiffs_object_append(fd, offset, (u8_t *)buf, remaining); + SPIFFS_CHECK_RES(res); + } + return len; + +} +#endif // !SPIFFS_READ_ONLY + +s32_t SPIFFS_write(spiffs *fs, spiffs_file fh, void *buf, s32_t len) { + SPIFFS_API_DBG("%s "_SPIPRIfd " "_SPIPRIi "\n", __func__, fh, len); +#if SPIFFS_READ_ONLY + (void)fs; (void)fh; (void)buf; (void)len; + return SPIFFS_ERR_RO_NOT_IMPL; +#else + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + SPIFFS_LOCK(fs); + + spiffs_fd *fd; + s32_t res; + u32_t offset; + + fh = SPIFFS_FH_UNOFFS(fs, fh); + res = spiffs_fd_get(fs, fh, &fd); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + + if ((fd->flags & SPIFFS_O_WRONLY) == 0) { + res = SPIFFS_ERR_NOT_WRITABLE; + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + } + + if ((fd->flags & SPIFFS_O_APPEND)) { + fd->fdoffset = fd->size == SPIFFS_UNDEFINED_LEN ? 0 : fd->size; + } + offset = fd->fdoffset; + +#if SPIFFS_CACHE_WR + if (fd->cache_page == 0) { + // see if object id is associated with cache already + fd->cache_page = spiffs_cache_page_get_by_fd(fs, fd); + } +#endif + if (fd->flags & SPIFFS_O_APPEND) { + if (fd->size == SPIFFS_UNDEFINED_LEN) { + offset = 0; + } else { + offset = fd->size; + } +#if SPIFFS_CACHE_WR + if (fd->cache_page) { + offset = MAX(offset, fd->cache_page->ucache.swrc.offset + fd->cache_page->ucache.swrc.size); + } +#endif + } + +#if SPIFFS_CACHE_WR + if ((fd->flags & SPIFFS_O_DIRECT) == 0) { + if (len < (s32_t)SPIFFS_CFG_LOG_PAGE_SZ(fs)) { + // small write, try to cache it + u8_t alloc_cpage = 1; + if (fd->cache_page) { + // have a cached page for this fd already, check cache page boundaries + if (offset < fd->cache_page->ucache.swrc.offset || // writing before cache + offset > fd->cache_page->ucache.swrc.offset + fd->cache_page->ucache.swrc.size || // writing after cache + offset + len > fd->cache_page->ucache.swrc.offset + SPIFFS_CFG_LOG_PAGE_SZ(fs)) // writing beyond cache page + { + // boundary violation, write back cache first and allocate new + SPIFFS_CACHE_DBG("CACHE_WR_DUMP: dumping cache page "_SPIPRIi" for fd "_SPIPRIfd":"_SPIPRIid", boundary viol, offs:"_SPIPRIi" size:"_SPIPRIi"\n", + fd->cache_page->ix, fd->file_nbr, fd->obj_id, fd->cache_page->ucache.swrc.offset, fd->cache_page->ucache.swrc.size); + res = spiffs_hydro_write(fs, fd, + spiffs_get_cache_page(fs, spiffs_get_cache(fs), fd->cache_page->ix), + fd->cache_page->ucache.swrc.offset, fd->cache_page->ucache.swrc.size); + spiffs_cache_fd_release(fs, fd->cache_page); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + } else { + // writing within cache + alloc_cpage = 0; + } + } + + if (alloc_cpage) { + fd->cache_page = spiffs_cache_page_allocate_by_fd(fs, fd); + if (fd->cache_page) { + fd->cache_page->ucache.swrc.offset = offset; + fd->cache_page->ucache.swrc.size = 0; + SPIFFS_CACHE_DBG("CACHE_WR_ALLO: allocating cache page "_SPIPRIi" for fd "_SPIPRIfd":"_SPIPRIid"\n", + fd->cache_page->ix, fd->file_nbr, fd->obj_id); + } + } + + if (fd->cache_page) { + u32_t offset_in_cpage = offset - fd->cache_page->ucache.swrc.offset; + SPIFFS_CACHE_DBG("CACHE_WR_WRITE: storing to cache page "_SPIPRIi" for fd "_SPIPRIfd":"_SPIPRIid", offs "_SPIPRIi":"_SPIPRIi" len "_SPIPRIi"\n", + fd->cache_page->ix, fd->file_nbr, fd->obj_id, + offset, offset_in_cpage, len); + spiffs_cache *cache = spiffs_get_cache(fs); + u8_t *cpage_data = spiffs_get_cache_page(fs, cache, fd->cache_page->ix); +#ifdef _SPIFFS_TEST + { + intptr_t __a1 = (u8_t*)&cpage_data[offset_in_cpage]-(u8_t*)cache; + intptr_t __a2 = (u8_t*)&cpage_data[offset_in_cpage]+len-(u8_t*)cache; + intptr_t __b = sizeof(spiffs_cache) + cache->cpage_count * (sizeof(spiffs_cache_page) + SPIFFS_CFG_LOG_PAGE_SZ(fs)); + if (__a1 > __b || __a2 > __b) { + printf("FATAL OOB: CACHE_WR: memcpy to cache buffer ixs:%4ld..%4ld of %4ld\n", __a1, __a2, __b); + ERREXIT(); + } + } +#endif + _SPIFFS_MEMCPY(&cpage_data[offset_in_cpage], buf, len); + fd->cache_page->ucache.swrc.size = MAX(fd->cache_page->ucache.swrc.size, offset_in_cpage + len); + fd->fdoffset += len; + SPIFFS_UNLOCK(fs); + return len; + } else { + res = spiffs_hydro_write(fs, fd, buf, offset, len); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + fd->fdoffset += len; + SPIFFS_UNLOCK(fs); + return res; + } + } else { + // big write, no need to cache it - but first check if there is a cached write already + if (fd->cache_page) { + // write back cache first + SPIFFS_CACHE_DBG("CACHE_WR_DUMP: dumping cache page "_SPIPRIi" for fd "_SPIPRIfd":"_SPIPRIid", big write, offs:"_SPIPRIi" size:"_SPIPRIi"\n", + fd->cache_page->ix, fd->file_nbr, fd->obj_id, fd->cache_page->ucache.swrc.offset, fd->cache_page->ucache.swrc.size); + res = spiffs_hydro_write(fs, fd, + spiffs_get_cache_page(fs, spiffs_get_cache(fs), fd->cache_page->ix), + fd->cache_page->ucache.swrc.offset, fd->cache_page->ucache.swrc.size); + spiffs_cache_fd_release(fs, fd->cache_page); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + // data written below + } + } + } +#endif + + res = spiffs_hydro_write(fs, fd, buf, offset, len); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + fd->fdoffset += len; + + SPIFFS_UNLOCK(fs); + + return res; +#endif // SPIFFS_READ_ONLY +} + +s32_t SPIFFS_lseek(spiffs *fs, spiffs_file fh, s32_t offs, int whence) { + SPIFFS_API_DBG("%s "_SPIPRIfd " "_SPIPRIi " %s\n", __func__, fh, offs, (const char* []){"SET","CUR","END","???"}[MIN(whence,3)]); + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + SPIFFS_LOCK(fs); + + spiffs_fd *fd; + s32_t res; + fh = SPIFFS_FH_UNOFFS(fs, fh); + res = spiffs_fd_get(fs, fh, &fd); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + +#if SPIFFS_CACHE_WR + spiffs_fflush_cache(fs, fh); +#endif + + s32_t file_size = fd->size == SPIFFS_UNDEFINED_LEN ? 0 : fd->size; + + switch (whence) { + case SPIFFS_SEEK_CUR: + offs = fd->fdoffset+offs; + break; + case SPIFFS_SEEK_END: + offs = file_size + offs; + break; + } + if (offs < 0) { + SPIFFS_API_CHECK_RES_UNLOCK(fs, SPIFFS_ERR_SEEK_BOUNDS); + } + if (offs > file_size) { + fd->fdoffset = file_size; + res = SPIFFS_ERR_END_OF_OBJECT; + } + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + + spiffs_span_ix data_spix = (offs > 0 ? (offs-1) : 0) / SPIFFS_DATA_PAGE_SIZE(fs); + spiffs_span_ix objix_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, data_spix); + if (fd->cursor_objix_spix != objix_spix) { + spiffs_page_ix pix; + res = spiffs_obj_lu_find_id_and_span( + fs, fd->obj_id | SPIFFS_OBJ_ID_IX_FLAG, objix_spix, 0, &pix); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + fd->cursor_objix_spix = objix_spix; + fd->cursor_objix_pix = pix; + } + fd->fdoffset = offs; + + SPIFFS_UNLOCK(fs); + + return offs; +} + +s32_t SPIFFS_remove(spiffs *fs, const char *path) { + SPIFFS_API_DBG("%s '%s'\n", __func__, path); +#if SPIFFS_READ_ONLY + (void)fs; (void)path; + return SPIFFS_ERR_RO_NOT_IMPL; +#else + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + if (strlen(path) > SPIFFS_OBJ_NAME_LEN - 1) { + SPIFFS_API_CHECK_RES(fs, SPIFFS_ERR_NAME_TOO_LONG); + } + SPIFFS_LOCK(fs); + + spiffs_fd *fd; + spiffs_page_ix pix; + s32_t res; + + res = spiffs_fd_find_new(fs, &fd, 0); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + + res = spiffs_object_find_object_index_header_by_name(fs, (const u8_t*)path, &pix); + if (res != SPIFFS_OK) { + spiffs_fd_return(fs, fd->file_nbr); + } + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + + res = spiffs_object_open_by_page(fs, pix, fd, 0,0); + if (res != SPIFFS_OK) { + spiffs_fd_return(fs, fd->file_nbr); + } + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + + res = spiffs_object_truncate(fd, 0, 1); + if (res != SPIFFS_OK) { + spiffs_fd_return(fs, fd->file_nbr); + } + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + + SPIFFS_UNLOCK(fs); + return 0; +#endif // SPIFFS_READ_ONLY +} + +s32_t SPIFFS_fremove(spiffs *fs, spiffs_file fh) { + SPIFFS_API_DBG("%s "_SPIPRIfd "\n", __func__, fh); +#if SPIFFS_READ_ONLY + (void)fs; (void)fh; + return SPIFFS_ERR_RO_NOT_IMPL; +#else + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + SPIFFS_LOCK(fs); + + spiffs_fd *fd; + s32_t res; + fh = SPIFFS_FH_UNOFFS(fs, fh); + res = spiffs_fd_get(fs, fh, &fd); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + + if ((fd->flags & SPIFFS_O_WRONLY) == 0) { + res = SPIFFS_ERR_NOT_WRITABLE; + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + } + +#if SPIFFS_CACHE_WR + spiffs_cache_fd_release(fs, fd->cache_page); +#endif + + res = spiffs_object_truncate(fd, 0, 1); + + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + + SPIFFS_UNLOCK(fs); + + return 0; +#endif // SPIFFS_READ_ONLY +} + +static s32_t spiffs_stat_pix(spiffs *fs, spiffs_page_ix pix, spiffs_file fh, spiffs_stat *s) { + (void)fh; + spiffs_page_object_ix_header objix_hdr; + spiffs_obj_id obj_id; + s32_t res =_spiffs_rd(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, fh, + SPIFFS_PAGE_TO_PADDR(fs, pix), sizeof(spiffs_page_object_ix_header), (u8_t *)&objix_hdr); + SPIFFS_API_CHECK_RES(fs, res); + + u32_t obj_id_addr = SPIFFS_BLOCK_TO_PADDR(fs, SPIFFS_BLOCK_FOR_PAGE(fs , pix)) + + SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(fs, pix) * sizeof(spiffs_obj_id); + res =_spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, fh, + obj_id_addr, sizeof(spiffs_obj_id), (u8_t *)&obj_id); + SPIFFS_API_CHECK_RES(fs, res); + + s->obj_id = obj_id & ~SPIFFS_OBJ_ID_IX_FLAG; + s->type = objix_hdr.type; + s->size = objix_hdr.size == SPIFFS_UNDEFINED_LEN ? 0 : objix_hdr.size; + s->pix = pix; + strncpy((char *)s->name, (char *)objix_hdr.name, SPIFFS_OBJ_NAME_LEN); +#if SPIFFS_OBJ_META_LEN + _SPIFFS_MEMCPY(s->meta, objix_hdr.meta, SPIFFS_OBJ_META_LEN); +#endif + + return res; +} + +s32_t SPIFFS_stat(spiffs *fs, const char *path, spiffs_stat *s) { + SPIFFS_API_DBG("%s '%s'\n", __func__, path); + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + if (strlen(path) > SPIFFS_OBJ_NAME_LEN - 1) { + SPIFFS_API_CHECK_RES(fs, SPIFFS_ERR_NAME_TOO_LONG); + } + SPIFFS_LOCK(fs); + + s32_t res; + spiffs_page_ix pix; + + res = spiffs_object_find_object_index_header_by_name(fs, (const u8_t*)path, &pix); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + + res = spiffs_stat_pix(fs, pix, 0, s); + + SPIFFS_UNLOCK(fs); + + return res; +} + +s32_t SPIFFS_fstat(spiffs *fs, spiffs_file fh, spiffs_stat *s) { + SPIFFS_API_DBG("%s "_SPIPRIfd "\n", __func__, fh); + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + SPIFFS_LOCK(fs); + + spiffs_fd *fd; + s32_t res; + + fh = SPIFFS_FH_UNOFFS(fs, fh); + res = spiffs_fd_get(fs, fh, &fd); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + +#if SPIFFS_CACHE_WR + spiffs_fflush_cache(fs, fh); +#endif + + res = spiffs_stat_pix(fs, fd->objix_hdr_pix, fh, s); + + SPIFFS_UNLOCK(fs); + + return res; +} + +// Checks if there are any cached writes for the object id associated with +// given filehandle. If so, these writes are flushed. +#if SPIFFS_CACHE == 1 +static s32_t spiffs_fflush_cache(spiffs *fs, spiffs_file fh) { + (void)fs; + (void)fh; + s32_t res = SPIFFS_OK; +#if !SPIFFS_READ_ONLY && SPIFFS_CACHE_WR + + spiffs_fd *fd; + res = spiffs_fd_get(fs, fh, &fd); + SPIFFS_API_CHECK_RES(fs, res); + + if ((fd->flags & SPIFFS_O_DIRECT) == 0) { + if (fd->cache_page == 0) { + // see if object id is associated with cache already + fd->cache_page = spiffs_cache_page_get_by_fd(fs, fd); + } + if (fd->cache_page) { + SPIFFS_CACHE_DBG("CACHE_WR_DUMP: dumping cache page "_SPIPRIi" for fd "_SPIPRIfd":"_SPIPRIid", flush, offs:"_SPIPRIi" size:"_SPIPRIi"\n", + fd->cache_page->ix, fd->file_nbr, fd->obj_id, fd->cache_page->ucache.swrc.offset, fd->cache_page->ucache.swrc.size); + res = spiffs_hydro_write(fs, fd, + spiffs_get_cache_page(fs, spiffs_get_cache(fs), fd->cache_page->ix), + fd->cache_page->ucache.swrc.offset, fd->cache_page->ucache.swrc.size); + if (res < SPIFFS_OK) { + fs->err_code = res; + } + spiffs_cache_fd_release(fs, fd->cache_page); + } + } +#endif + + return res; +} +#endif + +s32_t SPIFFS_fflush(spiffs *fs, spiffs_file fh) { + SPIFFS_API_DBG("%s "_SPIPRIfd "\n", __func__, fh); + (void)fh; + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + s32_t res = SPIFFS_OK; +#if !SPIFFS_READ_ONLY && SPIFFS_CACHE_WR + SPIFFS_LOCK(fs); + fh = SPIFFS_FH_UNOFFS(fs, fh); + res = spiffs_fflush_cache(fs, fh); + SPIFFS_API_CHECK_RES_UNLOCK(fs,res); + SPIFFS_UNLOCK(fs); +#endif + + return res; +} + +s32_t SPIFFS_close(spiffs *fs, spiffs_file fh) { + SPIFFS_API_DBG("%s "_SPIPRIfd "\n", __func__, fh); + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + + s32_t res = SPIFFS_OK; + SPIFFS_LOCK(fs); + + fh = SPIFFS_FH_UNOFFS(fs, fh); +#if SPIFFS_CACHE + res = spiffs_fflush_cache(fs, fh); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); +#endif + res = spiffs_fd_return(fs, fh); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + + SPIFFS_UNLOCK(fs); + + return res; +} + +s32_t SPIFFS_rename(spiffs *fs, const char *old_path, const char *new_path) { + SPIFFS_API_DBG("%s %s %s\n", __func__, old_path, new_path); +#if SPIFFS_READ_ONLY + (void)fs; (void)old_path; (void)new_path; + return SPIFFS_ERR_RO_NOT_IMPL; +#else + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + if (strlen(new_path) > SPIFFS_OBJ_NAME_LEN - 1 || + strlen(old_path) > SPIFFS_OBJ_NAME_LEN - 1) { + SPIFFS_API_CHECK_RES(fs, SPIFFS_ERR_NAME_TOO_LONG); + } + SPIFFS_LOCK(fs); + + spiffs_page_ix pix_old, pix_dummy; + spiffs_fd *fd; + + s32_t res = spiffs_object_find_object_index_header_by_name(fs, (const u8_t*)old_path, &pix_old); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + + res = spiffs_object_find_object_index_header_by_name(fs, (const u8_t*)new_path, &pix_dummy); + if (res == SPIFFS_ERR_NOT_FOUND) { + res = SPIFFS_OK; + } else if (res == SPIFFS_OK) { + res = SPIFFS_ERR_CONFLICTING_NAME; + } + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + + res = spiffs_fd_find_new(fs, &fd, 0); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + + res = spiffs_object_open_by_page(fs, pix_old, fd, 0, 0); + if (res != SPIFFS_OK) { + spiffs_fd_return(fs, fd->file_nbr); + } + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + + res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, fd->objix_hdr_pix, 0, (const u8_t*)new_path, + 0, 0, &pix_dummy); +#if SPIFFS_TEMPORAL_FD_CACHE + if (res == SPIFFS_OK) { + spiffs_fd_temporal_cache_rehash(fs, old_path, new_path); + } +#endif + + spiffs_fd_return(fs, fd->file_nbr); + + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + + SPIFFS_UNLOCK(fs); + + return res; +#endif // SPIFFS_READ_ONLY +} + +#if SPIFFS_OBJ_META_LEN +s32_t SPIFFS_update_meta(spiffs *fs, const char *name, const void *meta) { +#if SPIFFS_READ_ONLY + (void)fs; (void)name; (void)meta; + return SPIFFS_ERR_RO_NOT_IMPL; +#else + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + SPIFFS_LOCK(fs); + + spiffs_page_ix pix, pix_dummy; + spiffs_fd *fd; + + s32_t res = spiffs_object_find_object_index_header_by_name(fs, (const u8_t*)name, &pix); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + + res = spiffs_fd_find_new(fs, &fd, 0); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + + res = spiffs_object_open_by_page(fs, pix, fd, 0, 0); + if (res != SPIFFS_OK) { + spiffs_fd_return(fs, fd->file_nbr); + } + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + + res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, fd->objix_hdr_pix, 0, 0, meta, + 0, &pix_dummy); + + spiffs_fd_return(fs, fd->file_nbr); + + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + + SPIFFS_UNLOCK(fs); + + return res; +#endif // SPIFFS_READ_ONLY +} + +s32_t SPIFFS_fupdate_meta(spiffs *fs, spiffs_file fh, const void *meta) { +#if SPIFFS_READ_ONLY + (void)fs; (void)fh; (void)meta; + return SPIFFS_ERR_RO_NOT_IMPL; +#else + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + SPIFFS_LOCK(fs); + + s32_t res; + spiffs_fd *fd; + spiffs_page_ix pix_dummy; + + fh = SPIFFS_FH_UNOFFS(fs, fh); + res = spiffs_fd_get(fs, fh, &fd); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + + if ((fd->flags & SPIFFS_O_WRONLY) == 0) { + res = SPIFFS_ERR_NOT_WRITABLE; + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + } + + res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, fd->objix_hdr_pix, 0, 0, meta, + 0, &pix_dummy); + + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + + SPIFFS_UNLOCK(fs); + + return res; +#endif // SPIFFS_READ_ONLY +} +#endif // SPIFFS_OBJ_META_LEN + +spiffs_DIR *SPIFFS_opendir(spiffs *fs, const char *name, spiffs_DIR *d) { + SPIFFS_API_DBG("%s\n", __func__); + (void)name; + + if (!SPIFFS_CHECK_CFG((fs))) { + (fs)->err_code = SPIFFS_ERR_NOT_CONFIGURED; + return 0; + } + + if (!SPIFFS_CHECK_MOUNT(fs)) { + fs->err_code = SPIFFS_ERR_NOT_MOUNTED; + return 0; + } + + d->fs = fs; + d->block = 0; + d->entry = 0; + return d; +} + +static s32_t spiffs_read_dir_v( + spiffs *fs, + spiffs_obj_id obj_id, + spiffs_block_ix bix, + int ix_entry, + const void *user_const_p, + void *user_var_p) { + (void)user_const_p; + s32_t res; + spiffs_page_object_ix_header objix_hdr; + if (obj_id == SPIFFS_OBJ_ID_FREE || obj_id == SPIFFS_OBJ_ID_DELETED || + (obj_id & SPIFFS_OBJ_ID_IX_FLAG) == 0) { + return SPIFFS_VIS_COUNTINUE; + } + + spiffs_page_ix pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, ix_entry); + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, + 0, SPIFFS_PAGE_TO_PADDR(fs, pix), sizeof(spiffs_page_object_ix_header), (u8_t *)&objix_hdr); + if (res != SPIFFS_OK) return res; + if ((obj_id & SPIFFS_OBJ_ID_IX_FLAG) && + objix_hdr.p_hdr.span_ix == 0 && + (objix_hdr.p_hdr.flags & (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_IXDELE)) == + (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_IXDELE)) { + struct spiffs_dirent *e = (struct spiffs_dirent*)user_var_p; + e->obj_id = obj_id; + strcpy((char *)e->name, (char *)objix_hdr.name); + e->type = objix_hdr.type; + e->size = objix_hdr.size == SPIFFS_UNDEFINED_LEN ? 0 : objix_hdr.size; + e->pix = pix; +#if SPIFFS_OBJ_META_LEN + _SPIFFS_MEMCPY(e->meta, objix_hdr.meta, SPIFFS_OBJ_META_LEN); +#endif + return SPIFFS_OK; + } + return SPIFFS_VIS_COUNTINUE; +} + +struct spiffs_dirent *SPIFFS_readdir(spiffs_DIR *d, struct spiffs_dirent *e) { + SPIFFS_API_DBG("%s\n", __func__); + if (!SPIFFS_CHECK_MOUNT(d->fs)) { + d->fs->err_code = SPIFFS_ERR_NOT_MOUNTED; + return 0; + } + SPIFFS_LOCK(d->fs); + + spiffs_block_ix bix; + int entry; + s32_t res; + struct spiffs_dirent *ret = 0; + + res = spiffs_obj_lu_find_entry_visitor(d->fs, + d->block, + d->entry, + SPIFFS_VIS_NO_WRAP, + 0, + spiffs_read_dir_v, + 0, + e, + &bix, + &entry); + if (res == SPIFFS_OK) { + d->block = bix; + d->entry = entry + 1; + e->obj_id &= ~SPIFFS_OBJ_ID_IX_FLAG; + ret = e; + } else { + d->fs->err_code = res; + } + SPIFFS_UNLOCK(d->fs); + return ret; +} + +s32_t SPIFFS_closedir(spiffs_DIR *d) { + SPIFFS_API_DBG("%s\n", __func__); + SPIFFS_API_CHECK_CFG(d->fs); + SPIFFS_API_CHECK_MOUNT(d->fs); + return 0; +} + +s32_t SPIFFS_check(spiffs *fs) { + SPIFFS_API_DBG("%s\n", __func__); +#if SPIFFS_READ_ONLY + (void)fs; + return SPIFFS_ERR_RO_NOT_IMPL; +#else + s32_t res; + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + SPIFFS_LOCK(fs); + + res = spiffs_lookup_consistency_check(fs, 0); + + res = spiffs_object_index_consistency_check(fs); + + res = spiffs_page_consistency_check(fs); + + res = spiffs_obj_lu_scan(fs); + + SPIFFS_UNLOCK(fs); + return res; +#endif // SPIFFS_READ_ONLY +} + +s32_t SPIFFS_info(spiffs *fs, u32_t *total, u32_t *used) { + SPIFFS_API_DBG("%s\n", __func__); + s32_t res = SPIFFS_OK; + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + SPIFFS_LOCK(fs); + + u32_t pages_per_block = SPIFFS_PAGES_PER_BLOCK(fs); + u32_t blocks = fs->block_count; + u32_t obj_lu_pages = SPIFFS_OBJ_LOOKUP_PAGES(fs); + u32_t data_page_size = SPIFFS_DATA_PAGE_SIZE(fs); + u32_t total_data_pages = (blocks - 2) * (pages_per_block - obj_lu_pages) + 1; // -2 for spare blocks, +1 for emergency page + + if (total) { + *total = total_data_pages * data_page_size; + } + + if (used) { + *used = fs->stats_p_allocated * data_page_size; + } + + SPIFFS_UNLOCK(fs); + return res; +} + +s32_t SPIFFS_gc_quick(spiffs *fs, u16_t max_free_pages) { + SPIFFS_API_DBG("%s "_SPIPRIi "\n", __func__, max_free_pages); +#if SPIFFS_READ_ONLY + (void)fs; (void)max_free_pages; + return SPIFFS_ERR_RO_NOT_IMPL; +#else + s32_t res; + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + SPIFFS_LOCK(fs); + + res = spiffs_gc_quick(fs, max_free_pages); + + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + SPIFFS_UNLOCK(fs); + return 0; +#endif // SPIFFS_READ_ONLY +} + + +s32_t SPIFFS_gc(spiffs *fs, u32_t size) { + SPIFFS_API_DBG("%s "_SPIPRIi "\n", __func__, size); +#if SPIFFS_READ_ONLY + (void)fs; (void)size; + return SPIFFS_ERR_RO_NOT_IMPL; +#else + s32_t res; + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + SPIFFS_LOCK(fs); + + res = spiffs_gc_check(fs, size); + + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + SPIFFS_UNLOCK(fs); + return 0; +#endif // SPIFFS_READ_ONLY +} + +s32_t SPIFFS_eof(spiffs *fs, spiffs_file fh) { + SPIFFS_API_DBG("%s "_SPIPRIfd "\n", __func__, fh); + s32_t res; + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + SPIFFS_LOCK(fs); + + fh = SPIFFS_FH_UNOFFS(fs, fh); + + spiffs_fd *fd; + res = spiffs_fd_get(fs, fh, &fd); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + +#if SPIFFS_CACHE_WR + res = spiffs_fflush_cache(fs, fh); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); +#endif + + res = (fd->fdoffset >= (fd->size == SPIFFS_UNDEFINED_LEN ? 0 : fd->size)); + + SPIFFS_UNLOCK(fs); + return res; +} + +s32_t SPIFFS_tell(spiffs *fs, spiffs_file fh) { + SPIFFS_API_DBG("%s "_SPIPRIfd "\n", __func__, fh); + s32_t res; + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + SPIFFS_LOCK(fs); + + fh = SPIFFS_FH_UNOFFS(fs, fh); + + spiffs_fd *fd; + res = spiffs_fd_get(fs, fh, &fd); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + +#if SPIFFS_CACHE_WR + res = spiffs_fflush_cache(fs, fh); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); +#endif + + res = fd->fdoffset; + + SPIFFS_UNLOCK(fs); + return res; +} + +s32_t SPIFFS_set_file_callback_func(spiffs *fs, spiffs_file_callback cb_func) { + SPIFFS_API_DBG("%s\n", __func__); + SPIFFS_LOCK(fs); + fs->file_cb_f = cb_func; + SPIFFS_UNLOCK(fs); + return 0; +} + +#if SPIFFS_IX_MAP + +s32_t SPIFFS_ix_map(spiffs *fs, spiffs_file fh, spiffs_ix_map *map, + u32_t offset, u32_t len, spiffs_page_ix *map_buf) { + SPIFFS_API_DBG("%s "_SPIPRIfd " "_SPIPRIi " "_SPIPRIi "\n", __func__, fh, offset, len); + s32_t res; + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + SPIFFS_LOCK(fs); + + fh = SPIFFS_FH_UNOFFS(fs, fh); + + spiffs_fd *fd; + res = spiffs_fd_get(fs, fh, &fd); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + + if (fd->ix_map) { + SPIFFS_API_CHECK_RES_UNLOCK(fs, SPIFFS_ERR_IX_MAP_MAPPED); + } + + map->map_buf = map_buf; + map->offset = offset; + // nb: spix range includes last + map->start_spix = offset / SPIFFS_DATA_PAGE_SIZE(fs); + map->end_spix = (offset + len) / SPIFFS_DATA_PAGE_SIZE(fs); + memset(map_buf, 0, sizeof(spiffs_page_ix) * (map->end_spix - map->start_spix + 1)); + fd->ix_map = map; + + // scan for pixes + res = spiffs_populate_ix_map(fs, fd, 0, map->end_spix - map->start_spix + 1); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + + SPIFFS_UNLOCK(fs); + return res; +} + +s32_t SPIFFS_ix_unmap(spiffs *fs, spiffs_file fh) { + SPIFFS_API_DBG("%s "_SPIPRIfd "\n", __func__, fh); + s32_t res; + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + SPIFFS_LOCK(fs); + + fh = SPIFFS_FH_UNOFFS(fs, fh); + + spiffs_fd *fd; + res = spiffs_fd_get(fs, fh, &fd); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + + if (fd->ix_map == 0) { + SPIFFS_API_CHECK_RES_UNLOCK(fs, SPIFFS_ERR_IX_MAP_UNMAPPED); + } + + fd->ix_map = 0; + + SPIFFS_UNLOCK(fs); + return res; +} + +s32_t SPIFFS_ix_remap(spiffs *fs, spiffs_file fh, u32_t offset) { + SPIFFS_API_DBG("%s "_SPIPRIfd " "_SPIPRIi "\n", __func__, fh, offset); + s32_t res = SPIFFS_OK; + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + SPIFFS_LOCK(fs); + + fh = SPIFFS_FH_UNOFFS(fs, fh); + + spiffs_fd *fd; + res = spiffs_fd_get(fs, fh, &fd); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + + if (fd->ix_map == 0) { + SPIFFS_API_CHECK_RES_UNLOCK(fs, SPIFFS_ERR_IX_MAP_UNMAPPED); + } + + spiffs_ix_map *map = fd->ix_map; + + s32_t spix_diff = offset / SPIFFS_DATA_PAGE_SIZE(fs) - map->start_spix; + map->offset = offset; + + // move existing pixes if within map offs + if (spix_diff != 0) { + // move vector + int i; + const s32_t vec_len = map->end_spix - map->start_spix + 1; // spix range includes last + map->start_spix += spix_diff; + map->end_spix += spix_diff; + if (spix_diff >= vec_len) { + // moving beyond range + memset(&map->map_buf, 0, vec_len * sizeof(spiffs_page_ix)); + // populate_ix_map is inclusive + res = spiffs_populate_ix_map(fs, fd, 0, vec_len-1); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + } else if (spix_diff > 0) { + // diff positive + for (i = 0; i < vec_len - spix_diff; i++) { + map->map_buf[i] = map->map_buf[i + spix_diff]; + } + // memset is non-inclusive + memset(&map->map_buf[vec_len - spix_diff], 0, spix_diff * sizeof(spiffs_page_ix)); + // populate_ix_map is inclusive + res = spiffs_populate_ix_map(fs, fd, vec_len - spix_diff, vec_len-1); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + } else { + // diff negative + for (i = vec_len - 1; i >= -spix_diff; i--) { + map->map_buf[i] = map->map_buf[i + spix_diff]; + } + // memset is non-inclusive + memset(&map->map_buf[0], 0, -spix_diff * sizeof(spiffs_page_ix)); + // populate_ix_map is inclusive + res = spiffs_populate_ix_map(fs, fd, 0, -spix_diff - 1); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + } + + } + + SPIFFS_UNLOCK(fs); + return res; +} + +s32_t SPIFFS_bytes_to_ix_map_entries(spiffs *fs, u32_t bytes) { + SPIFFS_API_CHECK_CFG(fs); + // always add one extra page, the offset might change to the middle of a page + return (bytes + SPIFFS_DATA_PAGE_SIZE(fs) ) / SPIFFS_DATA_PAGE_SIZE(fs); +} + +s32_t SPIFFS_ix_map_entries_to_bytes(spiffs *fs, u32_t map_page_ix_entries) { + SPIFFS_API_CHECK_CFG(fs); + return map_page_ix_entries * SPIFFS_DATA_PAGE_SIZE(fs); +} + +#endif // SPIFFS_IX_MAP + +#if SPIFFS_TEST_VISUALISATION +s32_t SPIFFS_vis(spiffs *fs) { + s32_t res = SPIFFS_OK; + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + SPIFFS_LOCK(fs); + + int entries_per_page = (SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id)); + spiffs_obj_id *obj_lu_buf = (spiffs_obj_id *)fs->lu_work; + spiffs_block_ix bix = 0; + + while (bix < fs->block_count) { + // check each object lookup page + int obj_lookup_page = 0; + int cur_entry = 0; + + while (res == SPIFFS_OK && obj_lookup_page < (int)SPIFFS_OBJ_LOOKUP_PAGES(fs)) { + int entry_offset = obj_lookup_page * entries_per_page; + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, + 0, bix * SPIFFS_CFG_LOG_BLOCK_SZ(fs) + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); + // check each entry + while (res == SPIFFS_OK && + cur_entry - entry_offset < entries_per_page && cur_entry < (int)(SPIFFS_PAGES_PER_BLOCK(fs)-SPIFFS_OBJ_LOOKUP_PAGES(fs))) { + spiffs_obj_id obj_id = obj_lu_buf[cur_entry-entry_offset]; + if (cur_entry == 0) { + spiffs_printf(_SPIPRIbl" ", bix); + } else if ((cur_entry & 0x3f) == 0) { + spiffs_printf(" "); + } + if (obj_id == SPIFFS_OBJ_ID_FREE) { + spiffs_printf(SPIFFS_TEST_VIS_FREE_STR); + } else if (obj_id == SPIFFS_OBJ_ID_DELETED) { + spiffs_printf(SPIFFS_TEST_VIS_DELE_STR); + } else if (obj_id & SPIFFS_OBJ_ID_IX_FLAG){ + spiffs_printf(SPIFFS_TEST_VIS_INDX_STR(obj_id)); + } else { + spiffs_printf(SPIFFS_TEST_VIS_DATA_STR(obj_id)); + } + cur_entry++; + if ((cur_entry & 0x3f) == 0) { + spiffs_printf("\n"); + } + } // per entry + obj_lookup_page++; + } // per object lookup page + + spiffs_obj_id erase_count; + res = _spiffs_rd(fs, SPIFFS_OP_C_READ | SPIFFS_OP_T_OBJ_LU2, 0, + SPIFFS_ERASE_COUNT_PADDR(fs, bix), + sizeof(spiffs_obj_id), (u8_t *)&erase_count); + SPIFFS_CHECK_RES(res); + + if (erase_count != (spiffs_obj_id)-1) { + spiffs_printf("\tera_cnt: "_SPIPRIi"\n", erase_count); + } else { + spiffs_printf("\tera_cnt: N/A\n"); + } + + bix++; + } // per block + + spiffs_printf("era_cnt_max: "_SPIPRIi"\n", fs->max_erase_count); + spiffs_printf("last_errno: "_SPIPRIi"\n", fs->err_code); + spiffs_printf("blocks: "_SPIPRIi"\n", fs->block_count); + spiffs_printf("free_blocks: "_SPIPRIi"\n", fs->free_blocks); + spiffs_printf("page_alloc: "_SPIPRIi"\n", fs->stats_p_allocated); + spiffs_printf("page_delet: "_SPIPRIi"\n", fs->stats_p_deleted); + SPIFFS_UNLOCK(fs); + u32_t total, used; + SPIFFS_info(fs, &total, &used); + spiffs_printf("used: "_SPIPRIi" of "_SPIPRIi"\n", used, total); + return res; +} +#endif diff --git a/armsrc/spiffs_nucleus.c b/armsrc/spiffs_nucleus.c new file mode 100644 index 000000000..1c913921b --- /dev/null +++ b/armsrc/spiffs_nucleus.c @@ -0,0 +1,2365 @@ +#include "spiffs.h" +#include "spiffs_nucleus.h" +#include "printf.h" + +static s32_t spiffs_page_data_check(spiffs *fs, spiffs_fd *fd, spiffs_page_ix pix, spiffs_span_ix spix) { + s32_t res = SPIFFS_OK; + if (pix == (spiffs_page_ix)-1) { + // referring to page 0xffff...., bad object index + return SPIFFS_ERR_INDEX_REF_FREE; + } + if (pix % SPIFFS_PAGES_PER_BLOCK(fs) < SPIFFS_OBJ_LOOKUP_PAGES(fs)) { + // referring to an object lookup page, bad object index + return SPIFFS_ERR_INDEX_REF_LU; + } + if (pix > SPIFFS_MAX_PAGES(fs)) { + // referring to a bad page + return SPIFFS_ERR_INDEX_REF_INVALID; + } +#if SPIFFS_PAGE_CHECK + spiffs_page_header ph; + res = _spiffs_rd( + fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_READ, + fd->file_nbr, + SPIFFS_PAGE_TO_PADDR(fs, pix), + sizeof(spiffs_page_header), + (u8_t *)&ph); + SPIFFS_CHECK_RES(res); + SPIFFS_VALIDATE_DATA(ph, fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, spix); +#endif + return res; +} + +#if !SPIFFS_READ_ONLY +static s32_t spiffs_page_index_check(spiffs *fs, spiffs_fd *fd, spiffs_page_ix pix, spiffs_span_ix spix) { + s32_t res = SPIFFS_OK; + if (pix == (spiffs_page_ix)-1) { + // referring to page 0xffff...., bad object index + return SPIFFS_ERR_INDEX_FREE; + } + if (pix % SPIFFS_PAGES_PER_BLOCK(fs) < SPIFFS_OBJ_LOOKUP_PAGES(fs)) { + // referring to an object lookup page, bad object index + return SPIFFS_ERR_INDEX_LU; + } + if (pix > SPIFFS_MAX_PAGES(fs)) { + // referring to a bad page + return SPIFFS_ERR_INDEX_INVALID; + } +#if SPIFFS_PAGE_CHECK + spiffs_page_header ph; + res = _spiffs_rd( + fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, + fd->file_nbr, + SPIFFS_PAGE_TO_PADDR(fs, pix), + sizeof(spiffs_page_header), + (u8_t *)&ph); + SPIFFS_CHECK_RES(res); + SPIFFS_VALIDATE_OBJIX(ph, fd->obj_id, spix); +#endif + return res; +} +#endif // !SPIFFS_READ_ONLY + +#if !SPIFFS_CACHE + +s32_t spiffs_phys_rd( + spiffs *fs, + u32_t addr, + u32_t len, + u8_t *dst) { + return SPIFFS_HAL_READ(fs, addr, len, dst); +} + +s32_t spiffs_phys_wr( + spiffs *fs, + u32_t addr, + u32_t len, + u8_t *src) { + return SPIFFS_HAL_WRITE(fs, addr, len, src); +} + +#endif + +#if !SPIFFS_READ_ONLY +s32_t spiffs_phys_cpy( + spiffs *fs, + spiffs_file fh, + u32_t dst, + u32_t src, + u32_t len) { + (void)fh; + s32_t res; + u8_t b[SPIFFS_COPY_BUFFER_STACK]; + while (len > 0) { + u32_t chunk_size = MIN(SPIFFS_COPY_BUFFER_STACK, len); + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_MOVS, fh, src, chunk_size, b); + SPIFFS_CHECK_RES(res); + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_MOVD, fh, dst, chunk_size, b); + SPIFFS_CHECK_RES(res); + len -= chunk_size; + src += chunk_size; + dst += chunk_size; + } + return SPIFFS_OK; +} +#endif // !SPIFFS_READ_ONLY + +// Find object lookup entry containing given id with visitor. +// Iterate over object lookup pages in each block until a given object id entry is found. +// When found, the visitor function is called with block index, entry index and user data. +// If visitor returns SPIFFS_VIS_CONTINUE, the search goes on. Otherwise, the search will be +// ended and visitor's return code is returned to caller. +// If no visitor is given (0) the search returns on first entry with matching object id. +// If no match is found in all look up, SPIFFS_VIS_END is returned. +// @param fs the file system +// @param starting_block the starting block to start search in +// @param starting_lu_entry the look up index entry to start search in +// @param flags ored combination of SPIFFS_VIS_CHECK_ID, SPIFFS_VIS_CHECK_PH, +// SPIFFS_VIS_NO_WRAP +// @param obj_id argument object id +// @param v visitor callback function +// @param user_const_p any const pointer, passed to the callback visitor function +// @param user_var_p any pointer, passed to the callback visitor function +// @param block_ix reported block index where match was found +// @param lu_entry reported look up index where match was found +s32_t spiffs_obj_lu_find_entry_visitor( + spiffs *fs, + spiffs_block_ix starting_block, + int starting_lu_entry, + u8_t flags, + spiffs_obj_id obj_id, + spiffs_visitor_f v, + const void *user_const_p, + void *user_var_p, + spiffs_block_ix *block_ix, + int *lu_entry) { + s32_t res = SPIFFS_OK; + s32_t entry_count = fs->block_count * SPIFFS_OBJ_LOOKUP_MAX_ENTRIES(fs); + spiffs_block_ix cur_block = starting_block; + u32_t cur_block_addr = starting_block * SPIFFS_CFG_LOG_BLOCK_SZ(fs); + + spiffs_obj_id *obj_lu_buf = (spiffs_obj_id *)fs->lu_work; + int cur_entry = starting_lu_entry; + int entries_per_page = (SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id)); + + // wrap initial + if (cur_entry > (int)SPIFFS_OBJ_LOOKUP_MAX_ENTRIES(fs) - 1) { + cur_entry = 0; + cur_block++; + cur_block_addr = cur_block * SPIFFS_CFG_LOG_BLOCK_SZ(fs); + if (cur_block >= fs->block_count) { + if (flags & SPIFFS_VIS_NO_WRAP) { + return SPIFFS_VIS_END; + } else { + // block wrap + cur_block = 0; + cur_block_addr = 0; + } + } + } + + // check each block + while (res == SPIFFS_OK && entry_count > 0) { + int obj_lookup_page = cur_entry / entries_per_page; + // check each object lookup page + while (res == SPIFFS_OK && obj_lookup_page < (int)SPIFFS_OBJ_LOOKUP_PAGES(fs)) { + int entry_offset = obj_lookup_page * entries_per_page; + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, + 0, cur_block_addr + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); + // check each entry + while (res == SPIFFS_OK && + cur_entry - entry_offset < entries_per_page && // for non-last obj lookup pages + cur_entry < (int)SPIFFS_OBJ_LOOKUP_MAX_ENTRIES(fs)) // for last obj lookup page + { + if ((flags & SPIFFS_VIS_CHECK_ID) == 0 || obj_lu_buf[cur_entry-entry_offset] == obj_id) { + if (block_ix) *block_ix = cur_block; + if (lu_entry) *lu_entry = cur_entry; + if (v) { + res = v( + fs, + (flags & SPIFFS_VIS_CHECK_PH) ? obj_id : obj_lu_buf[cur_entry-entry_offset], + cur_block, + cur_entry, + user_const_p, + user_var_p); + if (res == SPIFFS_VIS_COUNTINUE || res == SPIFFS_VIS_COUNTINUE_RELOAD) { + if (res == SPIFFS_VIS_COUNTINUE_RELOAD) { + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, + 0, cur_block_addr + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); + SPIFFS_CHECK_RES(res); + } + res = SPIFFS_OK; + cur_entry++; + entry_count--; + continue; + } else { + return res; + } + } else { + return SPIFFS_OK; + } + } + entry_count--; + cur_entry++; + } // per entry + obj_lookup_page++; + } // per object lookup page + cur_entry = 0; + cur_block++; + cur_block_addr += SPIFFS_CFG_LOG_BLOCK_SZ(fs); + if (cur_block >= fs->block_count) { + if (flags & SPIFFS_VIS_NO_WRAP) { + return SPIFFS_VIS_END; + } else { + // block wrap + cur_block = 0; + cur_block_addr = 0; + } + } + } // per block + + SPIFFS_CHECK_RES(res); + + return SPIFFS_VIS_END; +} + +#if !SPIFFS_READ_ONLY +s32_t spiffs_erase_block( + spiffs *fs, + spiffs_block_ix bix) { + s32_t res; + u32_t addr = SPIFFS_BLOCK_TO_PADDR(fs, bix); + s32_t size = SPIFFS_CFG_LOG_BLOCK_SZ(fs); + + // here we ignore res, just try erasing the block + while (size > 0) { + SPIFFS_DBG("erase "_SPIPRIad":"_SPIPRIi"\n", addr, SPIFFS_CFG_PHYS_ERASE_SZ(fs)); + SPIFFS_HAL_ERASE(fs, addr, SPIFFS_CFG_PHYS_ERASE_SZ(fs)); + + addr += SPIFFS_CFG_PHYS_ERASE_SZ(fs); + size -= SPIFFS_CFG_PHYS_ERASE_SZ(fs); + } + fs->free_blocks++; + + // register erase count for this block + res = _spiffs_wr(fs, SPIFFS_OP_C_WRTHRU | SPIFFS_OP_T_OBJ_LU2, 0, + SPIFFS_ERASE_COUNT_PADDR(fs, bix), + sizeof(spiffs_obj_id), (u8_t *)&fs->max_erase_count); + SPIFFS_CHECK_RES(res); + +#if SPIFFS_USE_MAGIC + // finally, write magic + spiffs_obj_id magic = SPIFFS_MAGIC(fs, bix); + res = _spiffs_wr(fs, SPIFFS_OP_C_WRTHRU | SPIFFS_OP_T_OBJ_LU2, 0, + SPIFFS_MAGIC_PADDR(fs, bix), + sizeof(spiffs_obj_id), (u8_t *)&magic); + SPIFFS_CHECK_RES(res); +#endif + + fs->max_erase_count++; + if (fs->max_erase_count == SPIFFS_OBJ_ID_IX_FLAG) { + fs->max_erase_count = 0; + } + + return res; +} +#endif // !SPIFFS_READ_ONLY + +#if SPIFFS_USE_MAGIC && SPIFFS_USE_MAGIC_LENGTH && SPIFFS_SINGLETON==0 +s32_t spiffs_probe( + spiffs_config *cfg) { + s32_t res; + u32_t paddr; + spiffs dummy_fs; // create a dummy fs struct just to be able to use macros + _SPIFFS_MEMCPY(&dummy_fs.cfg, cfg, sizeof(spiffs_config)); + dummy_fs.block_count = 0; + + // Read three magics, as one block may be in an aborted erase state. + // At least two of these must contain magic and be in decreasing order. + spiffs_obj_id magic[3]; + spiffs_obj_id bix_count[3]; + + spiffs_block_ix bix; + for (bix = 0; bix < 3; bix++) { + paddr = SPIFFS_MAGIC_PADDR(&dummy_fs, bix); +#if SPIFFS_HAL_CALLBACK_EXTRA + // not any proper fs to report here, so callback with null + // (cross fingers that no-one gets angry) + res = cfg->hal_read_f((void *)0, paddr, sizeof(spiffs_obj_id), (u8_t *)&magic[bix]); +#else + res = cfg->hal_read_f(paddr, sizeof(spiffs_obj_id), (u8_t *)&magic[bix]); +#endif + bix_count[bix] = magic[bix] ^ SPIFFS_MAGIC(&dummy_fs, 0); + SPIFFS_CHECK_RES(res); + } + + // check that we have sane number of blocks + if (bix_count[0] < 3) return SPIFFS_ERR_PROBE_TOO_FEW_BLOCKS; + // check that the order is correct, take aborted erases in calculation + // first block aborted erase + if (magic[0] == (spiffs_obj_id)(-1) && bix_count[1] - bix_count[2] == 1) { + return (bix_count[1]+1) * cfg->log_block_size; + } + // second block aborted erase + if (magic[1] == (spiffs_obj_id)(-1) && bix_count[0] - bix_count[2] == 2) { + return bix_count[0] * cfg->log_block_size; + } + // third block aborted erase + if (magic[2] == (spiffs_obj_id)(-1) && bix_count[0] - bix_count[1] == 1) { + return bix_count[0] * cfg->log_block_size; + } + // no block has aborted erase + if (bix_count[0] - bix_count[1] == 1 && bix_count[1] - bix_count[2] == 1) { + return bix_count[0] * cfg->log_block_size; + } + + return SPIFFS_ERR_PROBE_NOT_A_FS; +} +#endif // SPIFFS_USE_MAGIC && SPIFFS_USE_MAGIC_LENGTH && SPIFFS_SINGLETON==0 + + +static s32_t spiffs_obj_lu_scan_v( + spiffs *fs, + spiffs_obj_id obj_id, + spiffs_block_ix bix, + int ix_entry, + const void *user_const_p, + void *user_var_p) { + (void)bix; + (void)user_const_p; + (void)user_var_p; + if (obj_id == SPIFFS_OBJ_ID_FREE) { + if (ix_entry == 0) { + fs->free_blocks++; + // todo optimize further, return SPIFFS_NEXT_BLOCK + } + } else if (obj_id == SPIFFS_OBJ_ID_DELETED) { + fs->stats_p_deleted++; + } else { + fs->stats_p_allocated++; + } + + return SPIFFS_VIS_COUNTINUE; +} + + +// Scans thru all obj lu and counts free, deleted and used pages +// Find the maximum block erase count +// Checks magic if enabled +s32_t spiffs_obj_lu_scan( + spiffs *fs) { + s32_t res; + spiffs_block_ix bix; + int entry; +#if SPIFFS_USE_MAGIC + spiffs_block_ix unerased_bix = (spiffs_block_ix)-1; +#endif + + // find out erase count + // if enabled, check magic + bix = 0; + spiffs_obj_id erase_count_final; + spiffs_obj_id erase_count_min = SPIFFS_OBJ_ID_FREE; + spiffs_obj_id erase_count_max = 0; + while (bix < fs->block_count) { +#if SPIFFS_USE_MAGIC + spiffs_obj_id magic; + res = _spiffs_rd(fs, + SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, + 0, SPIFFS_MAGIC_PADDR(fs, bix) , + sizeof(spiffs_obj_id), (u8_t *)&magic); + + SPIFFS_CHECK_RES(res); + if (magic != SPIFFS_MAGIC(fs, bix)) { + if (unerased_bix == (spiffs_block_ix)-1) { + // allow one unerased block as it might be powered down during an erase + unerased_bix = bix; + } else { + // more than one unerased block, bail out + SPIFFS_CHECK_RES(SPIFFS_ERR_NOT_A_FS); + } + } +#endif + spiffs_obj_id erase_count; + res = _spiffs_rd(fs, + SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, + 0, SPIFFS_ERASE_COUNT_PADDR(fs, bix) , + sizeof(spiffs_obj_id), (u8_t *)&erase_count); + SPIFFS_CHECK_RES(res); + if (erase_count != SPIFFS_OBJ_ID_FREE) { + erase_count_min = MIN(erase_count_min, erase_count); + erase_count_max = MAX(erase_count_max, erase_count); + } + bix++; + } + + if (erase_count_min == 0 && erase_count_max == SPIFFS_OBJ_ID_FREE) { + // clean system, set counter to zero + erase_count_final = 0; + } else if (erase_count_max - erase_count_min > (SPIFFS_OBJ_ID_FREE)/2) { + // wrap, take min + erase_count_final = erase_count_min+1; + } else { + erase_count_final = erase_count_max+1; + } + + fs->max_erase_count = erase_count_final; + +#if SPIFFS_USE_MAGIC + if (unerased_bix != (spiffs_block_ix)-1) { + // found one unerased block, remedy + SPIFFS_DBG("mount: erase block "_SPIPRIbl"\n", bix); +#if SPIFFS_READ_ONLY + res = SPIFFS_ERR_RO_ABORTED_OPERATION; +#else + res = spiffs_erase_block(fs, unerased_bix); +#endif // SPIFFS_READ_ONLY + SPIFFS_CHECK_RES(res); + } +#endif + + // count blocks + + fs->free_blocks = 0; + fs->stats_p_allocated = 0; + fs->stats_p_deleted = 0; + + res = spiffs_obj_lu_find_entry_visitor(fs, + 0, + 0, + 0, + 0, + spiffs_obj_lu_scan_v, + 0, + 0, + &bix, + &entry); + + if (res == SPIFFS_VIS_END) { + res = SPIFFS_OK; + } + + SPIFFS_CHECK_RES(res); + + return res; +} + +#if !SPIFFS_READ_ONLY +// Find free object lookup entry +// Iterate over object lookup pages in each block until a free object id entry is found +s32_t spiffs_obj_lu_find_free( + spiffs *fs, + spiffs_block_ix starting_block, + int starting_lu_entry, + spiffs_block_ix *block_ix, + int *lu_entry) { + s32_t res; + if (!fs->cleaning && fs->free_blocks < 2) { + res = spiffs_gc_quick(fs, 0); + if (res == SPIFFS_ERR_NO_DELETED_BLOCKS) { + res = SPIFFS_OK; + } + SPIFFS_CHECK_RES(res); + if (fs->free_blocks < 2) { + return SPIFFS_ERR_FULL; + } + } + res = spiffs_obj_lu_find_id(fs, starting_block, starting_lu_entry, + SPIFFS_OBJ_ID_FREE, block_ix, lu_entry); + if (res == SPIFFS_OK) { + fs->free_cursor_block_ix = *block_ix; + fs->free_cursor_obj_lu_entry = (*lu_entry) + 1; + if (*lu_entry == 0) { + fs->free_blocks--; + } + } + if (res == SPIFFS_ERR_FULL) { + SPIFFS_DBGF("fs full\n"); + } + + return res; +} +#endif // !SPIFFS_READ_ONLY + +// Find object lookup entry containing given id +// Iterate over object lookup pages in each block until a given object id entry is found +s32_t spiffs_obj_lu_find_id( + spiffs *fs, + spiffs_block_ix starting_block, + int starting_lu_entry, + spiffs_obj_id obj_id, + spiffs_block_ix *block_ix, + int *lu_entry) { + s32_t res = spiffs_obj_lu_find_entry_visitor( + fs, starting_block, starting_lu_entry, SPIFFS_VIS_CHECK_ID, obj_id, 0, 0, 0, block_ix, lu_entry); + if (res == SPIFFS_VIS_END) { + res = SPIFFS_ERR_NOT_FOUND; + } + return res; +} + + +static s32_t spiffs_obj_lu_find_id_and_span_v( + spiffs *fs, + spiffs_obj_id obj_id, + spiffs_block_ix bix, + int ix_entry, + const void *user_const_p, + void *user_var_p) { + s32_t res; + spiffs_page_header ph; + spiffs_page_ix pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, ix_entry); + res = _spiffs_rd(fs, 0, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, + SPIFFS_PAGE_TO_PADDR(fs, pix), sizeof(spiffs_page_header), (u8_t *)&ph); + SPIFFS_CHECK_RES(res); + if (ph.obj_id == obj_id && + ph.span_ix == *((spiffs_span_ix*)user_var_p) && + (ph.flags & (SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_USED)) == SPIFFS_PH_FLAG_DELET && + !((obj_id & SPIFFS_OBJ_ID_IX_FLAG) && (ph.flags & SPIFFS_PH_FLAG_IXDELE) == 0 && ph.span_ix == 0) && + (user_const_p == 0 || *((const spiffs_page_ix*)user_const_p) != pix)) { + return SPIFFS_OK; + } else { + return SPIFFS_VIS_COUNTINUE; + } +} + +// Find object lookup entry containing given id and span index +// Iterate over object lookup pages in each block until a given object id entry is found +s32_t spiffs_obj_lu_find_id_and_span( + spiffs *fs, + spiffs_obj_id obj_id, + spiffs_span_ix spix, + spiffs_page_ix exclusion_pix, + spiffs_page_ix *pix) { + s32_t res; + spiffs_block_ix bix; + int entry; + + res = spiffs_obj_lu_find_entry_visitor(fs, + fs->cursor_block_ix, + fs->cursor_obj_lu_entry, + SPIFFS_VIS_CHECK_ID, + obj_id, + spiffs_obj_lu_find_id_and_span_v, + exclusion_pix ? &exclusion_pix : 0, + &spix, + &bix, + &entry); + + if (res == SPIFFS_VIS_END) { + res = SPIFFS_ERR_NOT_FOUND; + } + + SPIFFS_CHECK_RES(res); + + if (pix) { + *pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, entry); + } + + fs->cursor_block_ix = bix; + fs->cursor_obj_lu_entry = entry; + + return res; +} + +// Find object lookup entry containing given id and span index in page headers only +// Iterate over object lookup pages in each block until a given object id entry is found +s32_t spiffs_obj_lu_find_id_and_span_by_phdr( + spiffs *fs, + spiffs_obj_id obj_id, + spiffs_span_ix spix, + spiffs_page_ix exclusion_pix, + spiffs_page_ix *pix) { + s32_t res; + spiffs_block_ix bix; + int entry; + + res = spiffs_obj_lu_find_entry_visitor(fs, + fs->cursor_block_ix, + fs->cursor_obj_lu_entry, + SPIFFS_VIS_CHECK_PH, + obj_id, + spiffs_obj_lu_find_id_and_span_v, + exclusion_pix ? &exclusion_pix : 0, + &spix, + &bix, + &entry); + + if (res == SPIFFS_VIS_END) { + res = SPIFFS_ERR_NOT_FOUND; + } + + SPIFFS_CHECK_RES(res); + + if (pix) { + *pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, entry); + } + + fs->cursor_block_ix = bix; + fs->cursor_obj_lu_entry = entry; + + return res; +} + +#if SPIFFS_IX_MAP + +// update index map of given fd with given object index data +static void spiffs_update_ix_map(spiffs *fs, + spiffs_fd *fd, spiffs_span_ix objix_spix, spiffs_page_object_ix *objix) { +#if SPIFFS_SINGLETON + (void)fs; +#endif + spiffs_ix_map *map = fd->ix_map; + spiffs_span_ix map_objix_start_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, map->start_spix); + spiffs_span_ix map_objix_end_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, map->end_spix); + + // check if updated ix is within map range + if (objix_spix < map_objix_start_spix || objix_spix > map_objix_end_spix) { + return; + } + + // update memory mapped page index buffer to new pages + + // get range of updated object index map data span indices + spiffs_span_ix objix_data_spix_start = + SPIFFS_DATA_SPAN_IX_FOR_OBJ_IX_SPAN_IX(fs, objix_spix); + spiffs_span_ix objix_data_spix_end = objix_data_spix_start + + (objix_spix == 0 ? SPIFFS_OBJ_HDR_IX_LEN(fs) : SPIFFS_OBJ_IX_LEN(fs)); + + // calc union of object index range and index map range array + spiffs_span_ix map_spix = MAX(map->start_spix, objix_data_spix_start); + spiffs_span_ix map_spix_end = MIN(map->end_spix + 1, objix_data_spix_end); + + while (map_spix < map_spix_end) { + spiffs_page_ix objix_data_pix; + if (objix_spix == 0) { + // get data page from object index header page + objix_data_pix = ((spiffs_page_ix*)((u8_t *)objix + sizeof(spiffs_page_object_ix_header)))[map_spix]; + } else { + // get data page from object index page + objix_data_pix = ((spiffs_page_ix*)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, map_spix)]; + } + + if (objix_data_pix == (spiffs_page_ix)-1) { + // reached end of object, abort + break; + } + + map->map_buf[map_spix - map->start_spix] = objix_data_pix; + SPIFFS_DBG("map "_SPIPRIid":"_SPIPRIsp" ("_SPIPRIsp"--"_SPIPRIsp") objix.spix:"_SPIPRIsp" to pix "_SPIPRIpg"\n", + fd->obj_id, map_spix - map->start_spix, + map->start_spix, map->end_spix, + objix->p_hdr.span_ix, + objix_data_pix); + + map_spix++; + } +} + +typedef struct { + spiffs_fd *fd; + u32_t remaining_objix_pages_to_visit; + spiffs_span_ix map_objix_start_spix; + spiffs_span_ix map_objix_end_spix; +} spiffs_ix_map_populate_state; + +static s32_t spiffs_populate_ix_map_v( + spiffs *fs, + spiffs_obj_id obj_id, + spiffs_block_ix bix, + int ix_entry, + const void *user_const_p, + void *user_var_p) { + (void)user_const_p; + s32_t res; + spiffs_ix_map_populate_state *state = (spiffs_ix_map_populate_state *)user_var_p; + spiffs_page_ix pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, ix_entry); + + // load header to check it + spiffs_page_object_ix *objix = (spiffs_page_object_ix *)fs->work; + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, + 0, SPIFFS_PAGE_TO_PADDR(fs, pix), sizeof(spiffs_page_object_ix), (u8_t *)objix); + SPIFFS_CHECK_RES(res); + SPIFFS_VALIDATE_OBJIX(objix->p_hdr, obj_id, objix->p_hdr.span_ix); + + // check if hdr is ok, and if objix range overlap with ix map range + if ((objix->p_hdr.flags & (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_IXDELE)) == + (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_IXDELE) && + objix->p_hdr.span_ix >= state->map_objix_start_spix && + objix->p_hdr.span_ix <= state->map_objix_end_spix) { + // ok, load rest of object index + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, + 0, SPIFFS_PAGE_TO_PADDR(fs, pix) + sizeof(spiffs_page_object_ix), + SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_page_object_ix), + (u8_t *)objix + sizeof(spiffs_page_object_ix)); + SPIFFS_CHECK_RES(res); + + spiffs_update_ix_map(fs, state->fd, objix->p_hdr.span_ix, objix); + + state->remaining_objix_pages_to_visit--; + SPIFFS_DBG("map "_SPIPRIid" ("_SPIPRIsp"--"_SPIPRIsp") remaining objix pages "_SPIPRIi"\n", + state->fd->obj_id, + state->fd->ix_map->start_spix, state->fd->ix_map->end_spix, + state->remaining_objix_pages_to_visit); + } + + if (res == SPIFFS_OK) { + res = state->remaining_objix_pages_to_visit ? SPIFFS_VIS_COUNTINUE : SPIFFS_VIS_END; + } + return res; +} + +// populates index map, from vector entry start to vector entry end, inclusive +s32_t spiffs_populate_ix_map(spiffs *fs, spiffs_fd *fd, u32_t vec_entry_start, u32_t vec_entry_end) { + s32_t res; + spiffs_ix_map *map = fd->ix_map; + spiffs_ix_map_populate_state state; + vec_entry_start = MIN((u32_t)(map->end_spix - map->start_spix), vec_entry_start); + vec_entry_end = MAX((u32_t)(map->end_spix - map->start_spix), vec_entry_end); + if (vec_entry_start > vec_entry_end) { + return SPIFFS_ERR_IX_MAP_BAD_RANGE; + } + state.map_objix_start_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, map->start_spix + vec_entry_start); + state.map_objix_end_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, map->start_spix + vec_entry_end); + state.remaining_objix_pages_to_visit = + state.map_objix_end_spix - state.map_objix_start_spix + 1; + state.fd = fd; + + res = spiffs_obj_lu_find_entry_visitor( + fs, + SPIFFS_BLOCK_FOR_PAGE(fs, fd->objix_hdr_pix), + SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(fs, fd->objix_hdr_pix), + SPIFFS_VIS_CHECK_ID, + fd->obj_id | SPIFFS_OBJ_ID_IX_FLAG, + spiffs_populate_ix_map_v, + 0, + &state, + 0, + 0); + + if (res == SPIFFS_VIS_END) { + res = SPIFFS_OK; + } + + return res; +} + +#endif + + +#if !SPIFFS_READ_ONLY +// Allocates a free defined page with given obj_id +// Occupies object lookup entry and page +// data may be NULL; where only page header is stored, len and page_offs is ignored +s32_t spiffs_page_allocate_data( + spiffs *fs, + spiffs_obj_id obj_id, + spiffs_page_header *ph, + u8_t *data, + u32_t len, + u32_t page_offs, + u8_t finalize, + spiffs_page_ix *pix) { + s32_t res = SPIFFS_OK; + spiffs_block_ix bix; + int entry; + + // find free entry + res = spiffs_obj_lu_find_free(fs, fs->free_cursor_block_ix, fs->free_cursor_obj_lu_entry, &bix, &entry); + SPIFFS_CHECK_RES(res); + + // occupy page in object lookup + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_UPDT, + 0, SPIFFS_BLOCK_TO_PADDR(fs, bix) + entry * sizeof(spiffs_obj_id), sizeof(spiffs_obj_id), (u8_t*)&obj_id); + SPIFFS_CHECK_RES(res); + + fs->stats_p_allocated++; + + // write page header + ph->flags &= ~SPIFFS_PH_FLAG_USED; + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, + 0, SPIFFS_OBJ_LOOKUP_ENTRY_TO_PADDR(fs, bix, entry), sizeof(spiffs_page_header), (u8_t*)ph); + SPIFFS_CHECK_RES(res); + + // write page data + if (data) { + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, + 0,SPIFFS_OBJ_LOOKUP_ENTRY_TO_PADDR(fs, bix, entry) + sizeof(spiffs_page_header) + page_offs, len, data); + SPIFFS_CHECK_RES(res); + } + + // finalize header if necessary + if (finalize && (ph->flags & SPIFFS_PH_FLAG_FINAL)) { + ph->flags &= ~SPIFFS_PH_FLAG_FINAL; + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, + 0, SPIFFS_OBJ_LOOKUP_ENTRY_TO_PADDR(fs, bix, entry) + offsetof(spiffs_page_header, flags), + sizeof(u8_t), + (u8_t *)&ph->flags); + SPIFFS_CHECK_RES(res); + } + + // return written page + if (pix) { + *pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, entry); + } + + return res; +} +#endif // !SPIFFS_READ_ONLY + +#if !SPIFFS_READ_ONLY +// Moves a page from src to a free page and finalizes it. Updates page index. Page data is given in param page. +// If page data is null, provided header is used for metainfo and page data is physically copied. +s32_t spiffs_page_move( + spiffs *fs, + spiffs_file fh, + u8_t *page_data, + spiffs_obj_id obj_id, + spiffs_page_header *page_hdr, + spiffs_page_ix src_pix, + spiffs_page_ix *dst_pix) { + s32_t res; + u8_t was_final = 0; + spiffs_page_header *p_hdr; + spiffs_block_ix bix; + int entry; + spiffs_page_ix free_pix; + + // find free entry + res = spiffs_obj_lu_find_free(fs, fs->free_cursor_block_ix, fs->free_cursor_obj_lu_entry, &bix, &entry); + SPIFFS_CHECK_RES(res); + free_pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, entry); + + if (dst_pix) *dst_pix = free_pix; + + p_hdr = page_data ? (spiffs_page_header *)page_data : page_hdr; + if (page_data) { + // got page data + was_final = (p_hdr->flags & SPIFFS_PH_FLAG_FINAL) == 0; + // write unfinalized page + p_hdr->flags |= SPIFFS_PH_FLAG_FINAL; + p_hdr->flags &= ~SPIFFS_PH_FLAG_USED; + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, + 0, SPIFFS_PAGE_TO_PADDR(fs, free_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), page_data); + } else { + // copy page data + res = spiffs_phys_cpy(fs, fh, SPIFFS_PAGE_TO_PADDR(fs, free_pix), SPIFFS_PAGE_TO_PADDR(fs, src_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs)); + } + SPIFFS_CHECK_RES(res); + + // mark entry in destination object lookup + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_UPDT, + 0, SPIFFS_BLOCK_TO_PADDR(fs, SPIFFS_BLOCK_FOR_PAGE(fs, free_pix)) + SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(fs, free_pix) * sizeof(spiffs_page_ix), + sizeof(spiffs_obj_id), + (u8_t *)&obj_id); + SPIFFS_CHECK_RES(res); + + fs->stats_p_allocated++; + + if (was_final) { + // mark finalized in destination page + p_hdr->flags &= ~(SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_USED); + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, + fh, + SPIFFS_PAGE_TO_PADDR(fs, free_pix) + offsetof(spiffs_page_header, flags), + sizeof(u8_t), + (u8_t *)&p_hdr->flags); + SPIFFS_CHECK_RES(res); + } + // mark source deleted + res = spiffs_page_delete(fs, src_pix); + return res; +} +#endif // !SPIFFS_READ_ONLY + +#if !SPIFFS_READ_ONLY +// Deletes a page and removes it from object lookup. +s32_t spiffs_page_delete( + spiffs *fs, + spiffs_page_ix pix) { + s32_t res; + // mark deleted entry in source object lookup + spiffs_obj_id d_obj_id = SPIFFS_OBJ_ID_DELETED; + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_DELE, + 0, + SPIFFS_BLOCK_TO_PADDR(fs, SPIFFS_BLOCK_FOR_PAGE(fs, pix)) + SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(fs, pix) * sizeof(spiffs_page_ix), + sizeof(spiffs_obj_id), + (u8_t *)&d_obj_id); + SPIFFS_CHECK_RES(res); + + fs->stats_p_deleted++; + fs->stats_p_allocated--; + + // mark deleted in source page + u8_t flags = 0xff; +#if SPIFFS_NO_BLIND_WRITES + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_READ, + 0, SPIFFS_PAGE_TO_PADDR(fs, pix) + offsetof(spiffs_page_header, flags), + sizeof(flags), &flags); + SPIFFS_CHECK_RES(res); +#endif + flags &= ~(SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_USED); + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_DELE, + 0, + SPIFFS_PAGE_TO_PADDR(fs, pix) + offsetof(spiffs_page_header, flags), + sizeof(flags), &flags); + + return res; +} +#endif // !SPIFFS_READ_ONLY + +#if !SPIFFS_READ_ONLY +// Create an object index header page with empty index and undefined length +s32_t spiffs_object_create( + spiffs *fs, + spiffs_obj_id obj_id, + const u8_t name[], + const u8_t meta[], + spiffs_obj_type type, + spiffs_page_ix *objix_hdr_pix) { + s32_t res = SPIFFS_OK; + spiffs_block_ix bix; + spiffs_page_object_ix_header oix_hdr; + int entry; + + res = spiffs_gc_check(fs, SPIFFS_DATA_PAGE_SIZE(fs)); + SPIFFS_CHECK_RES(res); + + obj_id |= SPIFFS_OBJ_ID_IX_FLAG; + + // find free entry + res = spiffs_obj_lu_find_free(fs, fs->free_cursor_block_ix, fs->free_cursor_obj_lu_entry, &bix, &entry); + SPIFFS_CHECK_RES(res); + SPIFFS_DBG("create: found free page @ "_SPIPRIpg" bix:"_SPIPRIbl" entry:"_SPIPRIsp"\n", (spiffs_page_ix)SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, entry), bix, entry); + + // occupy page in object lookup + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_UPDT, + 0, SPIFFS_BLOCK_TO_PADDR(fs, bix) + entry * sizeof(spiffs_obj_id), sizeof(spiffs_obj_id), (u8_t*)&obj_id); + SPIFFS_CHECK_RES(res); + + fs->stats_p_allocated++; + + // write empty object index page + oix_hdr.p_hdr.obj_id = obj_id; + oix_hdr.p_hdr.span_ix = 0; + oix_hdr.p_hdr.flags = 0xff & ~(SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_USED); + oix_hdr.type = type; + oix_hdr.size = SPIFFS_UNDEFINED_LEN; // keep ones so we can update later without wasting this page + strncpy((char*)oix_hdr.name, (const char*)name, SPIFFS_OBJ_NAME_LEN); +#if SPIFFS_OBJ_META_LEN + if (meta) { + _SPIFFS_MEMCPY(oix_hdr.meta, meta, SPIFFS_OBJ_META_LEN); + } else { + memset(oix_hdr.meta, 0xff, SPIFFS_OBJ_META_LEN); + } +#else + (void) meta; +#endif + + // update page + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, + 0, SPIFFS_OBJ_LOOKUP_ENTRY_TO_PADDR(fs, bix, entry), sizeof(spiffs_page_object_ix_header), (u8_t*)&oix_hdr); + + SPIFFS_CHECK_RES(res); + spiffs_cb_object_event(fs, (spiffs_page_object_ix *)&oix_hdr, + SPIFFS_EV_IX_NEW, obj_id, 0, SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, entry), SPIFFS_UNDEFINED_LEN); + + if (objix_hdr_pix) { + *objix_hdr_pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, entry); + } + + return res; +} +#endif // !SPIFFS_READ_ONLY + +#if !SPIFFS_READ_ONLY +// update object index header with any combination of name/size/index +// new_objix_hdr_data may be null, if so the object index header page is loaded +// name may be null, if so name is not changed +// size may be null, if so size is not changed +s32_t spiffs_object_update_index_hdr( + spiffs *fs, + spiffs_fd *fd, + spiffs_obj_id obj_id, + spiffs_page_ix objix_hdr_pix, + u8_t *new_objix_hdr_data, + const u8_t name[], + const u8_t meta[], + u32_t size, + spiffs_page_ix *new_pix) { + s32_t res = SPIFFS_OK; + spiffs_page_object_ix_header *objix_hdr; + spiffs_page_ix new_objix_hdr_pix; + + obj_id |= SPIFFS_OBJ_ID_IX_FLAG; + + if (new_objix_hdr_data) { + // object index header page already given to us, no need to load it + objix_hdr = (spiffs_page_object_ix_header *)new_objix_hdr_data; + } else { + // read object index header page + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, + fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, objix_hdr_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); + SPIFFS_CHECK_RES(res); + objix_hdr = (spiffs_page_object_ix_header *)fs->work; + } + + SPIFFS_VALIDATE_OBJIX(objix_hdr->p_hdr, obj_id, 0); + + // change name + if (name) { + strncpy((char*)objix_hdr->name, (const char*)name, SPIFFS_OBJ_NAME_LEN); + } +#if SPIFFS_OBJ_META_LEN + if (meta) { + _SPIFFS_MEMCPY(objix_hdr->meta, meta, SPIFFS_OBJ_META_LEN); + } +#else + (void) meta; +#endif + if (size) { + objix_hdr->size = size; + } + + // move and update page + res = spiffs_page_move(fs, fd == 0 ? 0 : fd->file_nbr, (u8_t*)objix_hdr, obj_id, 0, objix_hdr_pix, &new_objix_hdr_pix); + + if (res == SPIFFS_OK) { + if (new_pix) { + *new_pix = new_objix_hdr_pix; + } + // callback on object index update + spiffs_cb_object_event(fs, (spiffs_page_object_ix *)objix_hdr, + new_objix_hdr_data ? SPIFFS_EV_IX_UPD : SPIFFS_EV_IX_UPD_HDR, + obj_id, objix_hdr->p_hdr.span_ix, new_objix_hdr_pix, objix_hdr->size); + if (fd) fd->objix_hdr_pix = new_objix_hdr_pix; // if this is not in the registered cluster + } + + return res; +} +#endif // !SPIFFS_READ_ONLY + +void spiffs_cb_object_event( + spiffs *fs, + spiffs_page_object_ix *objix, + int ev, + spiffs_obj_id obj_id_raw, + spiffs_span_ix spix, + spiffs_page_ix new_pix, + u32_t new_size) { +#if SPIFFS_IX_MAP == 0 + (void)objix; +#endif + // update index caches in all file descriptors + spiffs_obj_id obj_id = obj_id_raw & ~SPIFFS_OBJ_ID_IX_FLAG; + u32_t i; + spiffs_fd *fds = (spiffs_fd *)fs->fd_space; + SPIFFS_DBG(" CALLBACK %s obj_id:"_SPIPRIid" spix:"_SPIPRIsp" npix:"_SPIPRIpg" nsz:"_SPIPRIi"\n", (const char *[]){"UPD", "NEW", "DEL", "MOV", "HUP","???"}[MIN(ev,5)], + obj_id_raw, spix, new_pix, new_size); + for (i = 0; i < fs->fd_count; i++) { + spiffs_fd *cur_fd = &fds[i]; + if ((cur_fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG) != obj_id) continue; // fd not related to updated file +#if !SPIFFS_TEMPORAL_FD_CACHE + if (cur_fd->file_nbr == 0) continue; // fd closed +#endif + if (spix == 0) { // object index header update + if (ev != SPIFFS_EV_IX_DEL) { +#if SPIFFS_TEMPORAL_FD_CACHE + if (cur_fd->score == 0) continue; // never used fd +#endif + SPIFFS_DBG(" callback: setting fd "_SPIPRIfd":"_SPIPRIid"(fdoffs:"_SPIPRIi" offs:"_SPIPRIi") objix_hdr_pix to "_SPIPRIpg", size:"_SPIPRIi"\n", + SPIFFS_FH_OFFS(fs, cur_fd->file_nbr), cur_fd->obj_id, cur_fd->fdoffset, cur_fd->offset, new_pix, new_size); + cur_fd->objix_hdr_pix = new_pix; + if (new_size != 0) { + // update size and offsets for fds to this file + cur_fd->size = new_size; + u32_t act_new_size = new_size == SPIFFS_UNDEFINED_LEN ? 0 : new_size; +#if SPIFFS_CACHE_WR + if (act_new_size > 0 && cur_fd->cache_page) { + act_new_size = MAX(act_new_size, cur_fd->cache_page->ucache.swrc.offset + cur_fd->cache_page->ucache.swrc.size); + } +#endif + if (cur_fd->offset > act_new_size) { + cur_fd->offset = act_new_size; + } + if (cur_fd->fdoffset > act_new_size) { + cur_fd->fdoffset = act_new_size; + } +#if SPIFFS_CACHE_WR + if (cur_fd->cache_page && cur_fd->cache_page->ucache.swrc.offset > act_new_size+1) { + SPIFFS_CACHE_DBG("CACHE_DROP: file trunced, dropping cache page "_SPIPRIi", no writeback\n", cur_fd->cache_page->ix); + spiffs_cache_fd_release(fs, cur_fd->cache_page); + } +#endif + } + } else { + // removing file +#if SPIFFS_CACHE_WR + if (cur_fd->file_nbr && cur_fd->cache_page) { + SPIFFS_CACHE_DBG("CACHE_DROP: file deleted, dropping cache page "_SPIPRIi", no writeback\n", cur_fd->cache_page->ix); + spiffs_cache_fd_release(fs, cur_fd->cache_page); + } +#endif + SPIFFS_DBG(" callback: release fd "_SPIPRIfd":"_SPIPRIid" span:"_SPIPRIsp" objix_pix to "_SPIPRIpg"\n", SPIFFS_FH_OFFS(fs, cur_fd->file_nbr), cur_fd->obj_id, spix, new_pix); + cur_fd->file_nbr = 0; + cur_fd->obj_id = SPIFFS_OBJ_ID_DELETED; + } + } // object index header update + if (cur_fd->cursor_objix_spix == spix) { + if (ev != SPIFFS_EV_IX_DEL) { + SPIFFS_DBG(" callback: setting fd "_SPIPRIfd":"_SPIPRIid" span:"_SPIPRIsp" objix_pix to "_SPIPRIpg"\n", SPIFFS_FH_OFFS(fs, cur_fd->file_nbr), cur_fd->obj_id, spix, new_pix); + cur_fd->cursor_objix_pix = new_pix; + } else { + cur_fd->cursor_objix_pix = 0; + } + } + } // fd update loop + +#if SPIFFS_IX_MAP + + // update index maps + if (ev == SPIFFS_EV_IX_UPD || ev == SPIFFS_EV_IX_NEW) { + for (i = 0; i < fs->fd_count; i++) { + spiffs_fd *cur_fd = &fds[i]; + // check fd opened, having ix map, match obj id + if (cur_fd->file_nbr == 0 || + cur_fd->ix_map == 0 || + (cur_fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG) != obj_id) continue; + SPIFFS_DBG(" callback: map ix update fd "_SPIPRIfd":"_SPIPRIid" span:"_SPIPRIsp"\n", SPIFFS_FH_OFFS(fs, cur_fd->file_nbr), cur_fd->obj_id, spix); + spiffs_update_ix_map(fs, cur_fd, spix, objix); + } + } + +#endif + + // callback to user if object index header + if (fs->file_cb_f && spix == 0 && (obj_id_raw & SPIFFS_OBJ_ID_IX_FLAG)) { + spiffs_fileop_type op; + if (ev == SPIFFS_EV_IX_NEW) { + op = SPIFFS_CB_CREATED; + } else if (ev == SPIFFS_EV_IX_UPD || + ev == SPIFFS_EV_IX_MOV || + ev == SPIFFS_EV_IX_UPD_HDR) { + op = SPIFFS_CB_UPDATED; + } else if (ev == SPIFFS_EV_IX_DEL) { + op = SPIFFS_CB_DELETED; + } else { + SPIFFS_DBG(" callback: WARNING unknown callback event "_SPIPRIi"\n", ev); + return; // bail out + } + fs->file_cb_f(fs, op, obj_id, new_pix); + } +} + +// Open object by id +s32_t spiffs_object_open_by_id( + spiffs *fs, + spiffs_obj_id obj_id, + spiffs_fd *fd, + spiffs_flags flags, + spiffs_mode mode) { + s32_t res = SPIFFS_OK; + spiffs_page_ix pix; + + res = spiffs_obj_lu_find_id_and_span(fs, obj_id | SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &pix); + SPIFFS_CHECK_RES(res); + + res = spiffs_object_open_by_page(fs, pix, fd, flags, mode); + + return res; +} + +// Open object by page index +s32_t spiffs_object_open_by_page( + spiffs *fs, + spiffs_page_ix pix, + spiffs_fd *fd, + spiffs_flags flags, + spiffs_mode mode) { + (void)mode; + s32_t res = SPIFFS_OK; + spiffs_page_object_ix_header oix_hdr; + spiffs_obj_id obj_id; + + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, + fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, pix), sizeof(spiffs_page_object_ix_header), (u8_t *)&oix_hdr); + SPIFFS_CHECK_RES(res); + + spiffs_block_ix bix = SPIFFS_BLOCK_FOR_PAGE(fs, pix); + int entry = SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(fs, pix); + + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, + 0, SPIFFS_BLOCK_TO_PADDR(fs, bix) + entry * sizeof(spiffs_obj_id), sizeof(spiffs_obj_id), (u8_t *)&obj_id); + + fd->fs = fs; + fd->objix_hdr_pix = pix; + fd->size = oix_hdr.size; + fd->offset = 0; + fd->cursor_objix_pix = pix; + fd->cursor_objix_spix = 0; + fd->obj_id = obj_id; + fd->flags = flags; + + SPIFFS_VALIDATE_OBJIX(oix_hdr.p_hdr, fd->obj_id, 0); + + SPIFFS_DBG("open: fd "_SPIPRIfd" is obj id "_SPIPRIid"\n", SPIFFS_FH_OFFS(fs, fd->file_nbr), fd->obj_id); + + return res; +} + +#if !SPIFFS_READ_ONLY +// Append to object +// keep current object index (header) page in fs->work buffer +s32_t spiffs_object_append(spiffs_fd *fd, u32_t offset, u8_t *data, u32_t len) { + spiffs *fs = fd->fs; + s32_t res = SPIFFS_OK; + u32_t written = 0; + + SPIFFS_DBG("append: "_SPIPRIi" bytes @ offs "_SPIPRIi" of size "_SPIPRIi"\n", len, offset, fd->size); + + if (offset > fd->size) { + SPIFFS_DBGF("append: offset reversed to size\n"); + offset = fd->size; + } + + res = spiffs_gc_check(fs, len + SPIFFS_DATA_PAGE_SIZE(fs)); // add an extra page of data worth for meta + if (res != SPIFFS_OK) { + SPIFFS_DBG("append: gc check fail "_SPIPRIi"\n", res); + } + SPIFFS_CHECK_RES(res); + + spiffs_page_object_ix_header *objix_hdr = (spiffs_page_object_ix_header *)fs->work; + spiffs_page_object_ix *objix = (spiffs_page_object_ix *)fs->work; + spiffs_page_header p_hdr; + + spiffs_span_ix cur_objix_spix = 0; + spiffs_span_ix prev_objix_spix = (spiffs_span_ix)-1; + spiffs_page_ix cur_objix_pix = fd->objix_hdr_pix; + spiffs_page_ix new_objix_hdr_page; + + spiffs_span_ix data_spix = offset / SPIFFS_DATA_PAGE_SIZE(fs); + spiffs_page_ix data_page; + u32_t page_offs = offset % SPIFFS_DATA_PAGE_SIZE(fs); + + // write all data + while (res == SPIFFS_OK && written < len) { + // calculate object index page span index + cur_objix_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, data_spix); + + // handle storing and loading of object indices + if (cur_objix_spix != prev_objix_spix) { + // new object index page + // within this clause we return directly if something fails, object index mess-up + if (written > 0) { + // store previous object index page, unless first pass + SPIFFS_DBG("append: "_SPIPRIid" store objix "_SPIPRIpg":"_SPIPRIsp", written "_SPIPRIi"\n", fd->obj_id, + cur_objix_pix, prev_objix_spix, written); + if (prev_objix_spix == 0) { + // this is an update to object index header page + objix_hdr->size = offset+written; + if (offset == 0) { + // was an empty object, update same page (size was 0xffffffff) + res = spiffs_page_index_check(fs, fd, cur_objix_pix, 0); + SPIFFS_CHECK_RES(res); + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_UPDT, + fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, cur_objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); + SPIFFS_CHECK_RES(res); + } else { + // was a nonempty object, update to new page + res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, + fd->objix_hdr_pix, fs->work, 0, 0, offset+written, &new_objix_hdr_page); + SPIFFS_CHECK_RES(res); + SPIFFS_DBG("append: "_SPIPRIid" store new objix_hdr, "_SPIPRIpg":"_SPIPRIsp", written "_SPIPRIi"\n", fd->obj_id, + new_objix_hdr_page, 0, written); + } + } else { + // this is an update to an object index page + res = spiffs_page_index_check(fs, fd, cur_objix_pix, prev_objix_spix); + SPIFFS_CHECK_RES(res); + + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_UPDT, + fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, cur_objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); + SPIFFS_CHECK_RES(res); + spiffs_cb_object_event(fs, (spiffs_page_object_ix *)fs->work, + SPIFFS_EV_IX_UPD,fd->obj_id, objix->p_hdr.span_ix, cur_objix_pix, 0); + // update length in object index header page + res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, + fd->objix_hdr_pix, 0, 0, 0, offset+written, &new_objix_hdr_page); + SPIFFS_CHECK_RES(res); + SPIFFS_DBG("append: "_SPIPRIid" store new size I "_SPIPRIi" in objix_hdr, "_SPIPRIpg":"_SPIPRIsp", written "_SPIPRIi"\n", fd->obj_id, + offset+written, new_objix_hdr_page, 0, written); + } + fd->size = offset+written; + fd->offset = offset+written; + } + + // create or load new object index page + if (cur_objix_spix == 0) { + // load object index header page, must always exist + SPIFFS_DBG("append: "_SPIPRIid" load objixhdr page "_SPIPRIpg":"_SPIPRIsp"\n", fd->obj_id, cur_objix_pix, cur_objix_spix); + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, + fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, cur_objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); + SPIFFS_CHECK_RES(res); + SPIFFS_VALIDATE_OBJIX(objix_hdr->p_hdr, fd->obj_id, cur_objix_spix); + } else { + spiffs_span_ix len_objix_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, (fd->size-1)/SPIFFS_DATA_PAGE_SIZE(fs)); + // on subsequent passes, create a new object index page + if (written > 0 || cur_objix_spix > len_objix_spix) { + p_hdr.obj_id = fd->obj_id | SPIFFS_OBJ_ID_IX_FLAG; + p_hdr.span_ix = cur_objix_spix; + p_hdr.flags = 0xff & ~(SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_INDEX); + res = spiffs_page_allocate_data(fs, fd->obj_id | SPIFFS_OBJ_ID_IX_FLAG, + &p_hdr, 0, 0, 0, 1, &cur_objix_pix); + SPIFFS_CHECK_RES(res); + // quick "load" of new object index page + memset(fs->work, 0xff, SPIFFS_CFG_LOG_PAGE_SZ(fs)); + _SPIFFS_MEMCPY(fs->work, &p_hdr, sizeof(spiffs_page_header)); + spiffs_cb_object_event(fs, (spiffs_page_object_ix *)fs->work, + SPIFFS_EV_IX_NEW, fd->obj_id, cur_objix_spix, cur_objix_pix, 0); + SPIFFS_DBG("append: "_SPIPRIid" create objix page, "_SPIPRIpg":"_SPIPRIsp", written "_SPIPRIi"\n", fd->obj_id + , cur_objix_pix, cur_objix_spix, written); + } else { + // on first pass, we load existing object index page + spiffs_page_ix pix; + SPIFFS_DBG("append: "_SPIPRIid" find objix span_ix:"_SPIPRIsp"\n", fd->obj_id, cur_objix_spix); + if (fd->cursor_objix_spix == cur_objix_spix) { + pix = fd->cursor_objix_pix; + } else { + res = spiffs_obj_lu_find_id_and_span(fs, fd->obj_id | SPIFFS_OBJ_ID_IX_FLAG, cur_objix_spix, 0, &pix); + SPIFFS_CHECK_RES(res); + } + SPIFFS_DBG("append: "_SPIPRIid" found object index at page "_SPIPRIpg" [fd size "_SPIPRIi"]\n", fd->obj_id, pix, fd->size); + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, + fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); + SPIFFS_CHECK_RES(res); + SPIFFS_VALIDATE_OBJIX(objix_hdr->p_hdr, fd->obj_id, cur_objix_spix); + cur_objix_pix = pix; + } + fd->cursor_objix_pix = cur_objix_pix; + fd->cursor_objix_spix = cur_objix_spix; + fd->offset = offset+written; + fd->size = offset+written; + } + prev_objix_spix = cur_objix_spix; + } + + // write data + u32_t to_write = MIN(len-written, SPIFFS_DATA_PAGE_SIZE(fs) - page_offs); + if (page_offs == 0) { + // at beginning of a page, allocate and write a new page of data + p_hdr.obj_id = fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG; + p_hdr.span_ix = data_spix; + p_hdr.flags = 0xff & ~(SPIFFS_PH_FLAG_FINAL); // finalize immediately + res = spiffs_page_allocate_data(fs, fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, + &p_hdr, &data[written], to_write, page_offs, 1, &data_page); + SPIFFS_DBG("append: "_SPIPRIid" store new data page, "_SPIPRIpg":"_SPIPRIsp" offset:"_SPIPRIi", len "_SPIPRIi", written "_SPIPRIi"\n", fd->obj_id, + data_page, data_spix, page_offs, to_write, written); + } else { + // append to existing page, fill out free data in existing page + if (cur_objix_spix == 0) { + // get data page from object index header page + data_page = ((spiffs_page_ix*)((u8_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[data_spix]; + } else { + // get data page from object index page + data_page = ((spiffs_page_ix*)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)]; + } + + res = spiffs_page_data_check(fs, fd, data_page, data_spix); + SPIFFS_CHECK_RES(res); + + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, + fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, data_page) + sizeof(spiffs_page_header) + page_offs, to_write, &data[written]); + SPIFFS_DBG("append: "_SPIPRIid" store to existing data page, "_SPIPRIpg":"_SPIPRIsp" offset:"_SPIPRIi", len "_SPIPRIi", written "_SPIPRIi"\n", fd->obj_id + , data_page, data_spix, page_offs, to_write, written); + } + + if (res != SPIFFS_OK) break; + + // update memory representation of object index page with new data page + if (cur_objix_spix == 0) { + // update object index header page + ((spiffs_page_ix*)((u8_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[data_spix] = data_page; + SPIFFS_DBG("append: "_SPIPRIid" wrote page "_SPIPRIpg" to objix_hdr entry "_SPIPRIsp" in mem\n", fd->obj_id + , data_page, data_spix); + objix_hdr->size = offset+written; + } else { + // update object index page + ((spiffs_page_ix*)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)] = data_page; + SPIFFS_DBG("append: "_SPIPRIid" wrote page "_SPIPRIpg" to objix entry "_SPIPRIsp" in mem\n", fd->obj_id + , data_page, (spiffs_span_ix)SPIFFS_OBJ_IX_ENTRY(fs, data_spix)); + } + + // update internals + page_offs = 0; + data_spix++; + written += to_write; + } // while all data + + fd->size = offset+written; + fd->offset = offset+written; + fd->cursor_objix_pix = cur_objix_pix; + fd->cursor_objix_spix = cur_objix_spix; + + // finalize updated object indices + s32_t res2 = SPIFFS_OK; + if (cur_objix_spix != 0) { + // wrote beyond object index header page + // write last modified object index page, unless object header index page + SPIFFS_DBG("append: "_SPIPRIid" store objix page, "_SPIPRIpg":"_SPIPRIsp", written "_SPIPRIi"\n", fd->obj_id, + cur_objix_pix, cur_objix_spix, written); + + res2 = spiffs_page_index_check(fs, fd, cur_objix_pix, cur_objix_spix); + SPIFFS_CHECK_RES(res2); + + res2 = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_UPDT, + fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, cur_objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); + SPIFFS_CHECK_RES(res2); + spiffs_cb_object_event(fs, (spiffs_page_object_ix *)fs->work, + SPIFFS_EV_IX_UPD, fd->obj_id, objix->p_hdr.span_ix, cur_objix_pix, 0); + + // update size in object header index page + res2 = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, + fd->objix_hdr_pix, 0, 0, 0, offset+written, &new_objix_hdr_page); + SPIFFS_DBG("append: "_SPIPRIid" store new size II "_SPIPRIi" in objix_hdr, "_SPIPRIpg":"_SPIPRIsp", written "_SPIPRIi", res "_SPIPRIi"\n", fd->obj_id + , offset+written, new_objix_hdr_page, 0, written, res2); + SPIFFS_CHECK_RES(res2); + } else { + // wrote within object index header page + if (offset == 0) { + // wrote to empty object - simply update size and write whole page + objix_hdr->size = offset+written; + SPIFFS_DBG("append: "_SPIPRIid" store fresh objix_hdr page, "_SPIPRIpg":"_SPIPRIsp", written "_SPIPRIi"\n", fd->obj_id + , cur_objix_pix, cur_objix_spix, written); + + res2 = spiffs_page_index_check(fs, fd, cur_objix_pix, cur_objix_spix); + SPIFFS_CHECK_RES(res2); + + res2 = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_UPDT, + fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, cur_objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); + SPIFFS_CHECK_RES(res2); + // callback on object index update + spiffs_cb_object_event(fs, (spiffs_page_object_ix *)fs->work, + SPIFFS_EV_IX_UPD_HDR, fd->obj_id, objix_hdr->p_hdr.span_ix, cur_objix_pix, objix_hdr->size); + } else { + // modifying object index header page, update size and make new copy + res2 = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, + fd->objix_hdr_pix, fs->work, 0, 0, offset+written, &new_objix_hdr_page); + SPIFFS_DBG("append: "_SPIPRIid" store modified objix_hdr page, "_SPIPRIpg":"_SPIPRIsp", written "_SPIPRIi"\n", fd->obj_id + , new_objix_hdr_page, 0, written); + SPIFFS_CHECK_RES(res2); + } + } + + return res; +} // spiffs_object_append +#endif // !SPIFFS_READ_ONLY + +#if !SPIFFS_READ_ONLY +// Modify object +// keep current object index (header) page in fs->work buffer +s32_t spiffs_object_modify(spiffs_fd *fd, u32_t offset, u8_t *data, u32_t len) { + spiffs *fs = fd->fs; + s32_t res = SPIFFS_OK; + u32_t written = 0; + + res = spiffs_gc_check(fs, len + SPIFFS_DATA_PAGE_SIZE(fs)); + SPIFFS_CHECK_RES(res); + + spiffs_page_object_ix_header *objix_hdr = (spiffs_page_object_ix_header *)fs->work; + spiffs_page_object_ix *objix = (spiffs_page_object_ix *)fs->work; + spiffs_page_header p_hdr; + + spiffs_span_ix cur_objix_spix = 0; + spiffs_span_ix prev_objix_spix = (spiffs_span_ix)-1; + spiffs_page_ix cur_objix_pix = fd->objix_hdr_pix; + spiffs_page_ix new_objix_hdr_pix; + + spiffs_span_ix data_spix = offset / SPIFFS_DATA_PAGE_SIZE(fs); + spiffs_page_ix data_pix; + u32_t page_offs = offset % SPIFFS_DATA_PAGE_SIZE(fs); + + + // write all data + while (res == SPIFFS_OK && written < len) { + // calculate object index page span index + cur_objix_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, data_spix); + + // handle storing and loading of object indices + if (cur_objix_spix != prev_objix_spix) { + // new object index page + // within this clause we return directly if something fails, object index mess-up + if (written > 0) { + // store previous object index (header) page, unless first pass + if (prev_objix_spix == 0) { + // store previous object index header page + res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, + fd->objix_hdr_pix, fs->work, 0, 0, 0, &new_objix_hdr_pix); + SPIFFS_DBG("modify: store modified objix_hdr page, "_SPIPRIpg":"_SPIPRIsp", written "_SPIPRIi"\n", new_objix_hdr_pix, 0, written); + SPIFFS_CHECK_RES(res); + } else { + // store new version of previous object index page + spiffs_page_ix new_objix_pix; + + res = spiffs_page_index_check(fs, fd, cur_objix_pix, prev_objix_spix); + SPIFFS_CHECK_RES(res); + + res = spiffs_page_move(fs, fd->file_nbr, (u8_t*)objix, fd->obj_id, 0, cur_objix_pix, &new_objix_pix); + SPIFFS_DBG("modify: store previous modified objix page, "_SPIPRIid":"_SPIPRIsp", written "_SPIPRIi"\n", new_objix_pix, objix->p_hdr.span_ix, written); + SPIFFS_CHECK_RES(res); + spiffs_cb_object_event(fs, (spiffs_page_object_ix *)objix, + SPIFFS_EV_IX_UPD, fd->obj_id, objix->p_hdr.span_ix, new_objix_pix, 0); + } + } + + // load next object index page + if (cur_objix_spix == 0) { + // load object index header page, must exist + SPIFFS_DBG("modify: load objixhdr page "_SPIPRIpg":"_SPIPRIsp"\n", cur_objix_pix, cur_objix_spix); + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, + fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, cur_objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); + SPIFFS_CHECK_RES(res); + SPIFFS_VALIDATE_OBJIX(objix_hdr->p_hdr, fd->obj_id, cur_objix_spix); + } else { + // load existing object index page on first pass + spiffs_page_ix pix; + SPIFFS_DBG("modify: find objix span_ix:"_SPIPRIsp"\n", cur_objix_spix); + if (fd->cursor_objix_spix == cur_objix_spix) { + pix = fd->cursor_objix_pix; + } else { + res = spiffs_obj_lu_find_id_and_span(fs, fd->obj_id | SPIFFS_OBJ_ID_IX_FLAG, cur_objix_spix, 0, &pix); + SPIFFS_CHECK_RES(res); + } + SPIFFS_DBG("modify: found object index at page "_SPIPRIpg"\n", pix); + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, + fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); + SPIFFS_CHECK_RES(res); + SPIFFS_VALIDATE_OBJIX(objix_hdr->p_hdr, fd->obj_id, cur_objix_spix); + cur_objix_pix = pix; + } + fd->cursor_objix_pix = cur_objix_pix; + fd->cursor_objix_spix = cur_objix_spix; + fd->offset = offset+written; + prev_objix_spix = cur_objix_spix; + } + + // write partial data + u32_t to_write = MIN(len-written, SPIFFS_DATA_PAGE_SIZE(fs) - page_offs); + spiffs_page_ix orig_data_pix; + if (cur_objix_spix == 0) { + // get data page from object index header page + orig_data_pix = ((spiffs_page_ix*)((u8_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[data_spix]; + } else { + // get data page from object index page + orig_data_pix = ((spiffs_page_ix*)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)]; + } + + p_hdr.obj_id = fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG; + p_hdr.span_ix = data_spix; + p_hdr.flags = 0xff; + if (page_offs == 0 && to_write == SPIFFS_DATA_PAGE_SIZE(fs)) { + // a full page, allocate and write a new page of data + res = spiffs_page_allocate_data(fs, fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, + &p_hdr, &data[written], to_write, page_offs, 1, &data_pix); + SPIFFS_DBG("modify: store new data page, "_SPIPRIpg":"_SPIPRIsp" offset:"_SPIPRIi", len "_SPIPRIi", written "_SPIPRIi"\n", data_pix, data_spix, page_offs, to_write, written); + } else { + // write to existing page, allocate new and copy unmodified data + + res = spiffs_page_data_check(fs, fd, orig_data_pix, data_spix); + SPIFFS_CHECK_RES(res); + + res = spiffs_page_allocate_data(fs, fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, + &p_hdr, 0, 0, 0, 0, &data_pix); + if (res != SPIFFS_OK) break; + + // copy unmodified data + if (page_offs > 0) { + // before modification + res = spiffs_phys_cpy(fs, fd->file_nbr, + SPIFFS_PAGE_TO_PADDR(fs, data_pix) + sizeof(spiffs_page_header), + SPIFFS_PAGE_TO_PADDR(fs, orig_data_pix) + sizeof(spiffs_page_header), + page_offs); + if (res != SPIFFS_OK) break; + } + if (page_offs + to_write < SPIFFS_DATA_PAGE_SIZE(fs)) { + // after modification + res = spiffs_phys_cpy(fs, fd->file_nbr, + SPIFFS_PAGE_TO_PADDR(fs, data_pix) + sizeof(spiffs_page_header) + page_offs + to_write, + SPIFFS_PAGE_TO_PADDR(fs, orig_data_pix) + sizeof(spiffs_page_header) + page_offs + to_write, + SPIFFS_DATA_PAGE_SIZE(fs) - (page_offs + to_write)); + if (res != SPIFFS_OK) break; + } + + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, + fd->file_nbr, + SPIFFS_PAGE_TO_PADDR(fs, data_pix) + sizeof(spiffs_page_header) + page_offs, to_write, &data[written]); + if (res != SPIFFS_OK) break; + p_hdr.flags &= ~SPIFFS_PH_FLAG_FINAL; + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, + fd->file_nbr, + SPIFFS_PAGE_TO_PADDR(fs, data_pix) + offsetof(spiffs_page_header, flags), + sizeof(u8_t), + (u8_t *)&p_hdr.flags); + if (res != SPIFFS_OK) break; + + SPIFFS_DBG("modify: store to existing data page, src:"_SPIPRIpg", dst:"_SPIPRIpg":"_SPIPRIsp" offset:"_SPIPRIi", len "_SPIPRIi", written "_SPIPRIi"\n", orig_data_pix, data_pix, data_spix, page_offs, to_write, written); + } + + // delete original data page + res = spiffs_page_delete(fs, orig_data_pix); + if (res != SPIFFS_OK) break; + // update memory representation of object index page with new data page + if (cur_objix_spix == 0) { + // update object index header page + ((spiffs_page_ix*)((u8_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[data_spix] = data_pix; + SPIFFS_DBG("modify: wrote page "_SPIPRIpg" to objix_hdr entry "_SPIPRIsp" in mem\n", data_pix, data_spix); + } else { + // update object index page + ((spiffs_page_ix*)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)] = data_pix; + SPIFFS_DBG("modify: wrote page "_SPIPRIpg" to objix entry "_SPIPRIsp" in mem\n", data_pix, (spiffs_span_ix)SPIFFS_OBJ_IX_ENTRY(fs, data_spix)); + } + + // update internals + page_offs = 0; + data_spix++; + written += to_write; + } // while all data + + fd->offset = offset+written; + fd->cursor_objix_pix = cur_objix_pix; + fd->cursor_objix_spix = cur_objix_spix; + + // finalize updated object indices + s32_t res2 = SPIFFS_OK; + if (cur_objix_spix != 0) { + // wrote beyond object index header page + // write last modified object index page + // move and update page + spiffs_page_ix new_objix_pix; + + res2 = spiffs_page_index_check(fs, fd, cur_objix_pix, cur_objix_spix); + SPIFFS_CHECK_RES(res2); + + res2 = spiffs_page_move(fs, fd->file_nbr, (u8_t*)objix, fd->obj_id, 0, cur_objix_pix, &new_objix_pix); + SPIFFS_DBG("modify: store modified objix page, "_SPIPRIpg":"_SPIPRIsp", written "_SPIPRIi"\n", new_objix_pix, cur_objix_spix, written); + fd->cursor_objix_pix = new_objix_pix; + fd->cursor_objix_spix = cur_objix_spix; + SPIFFS_CHECK_RES(res2); + spiffs_cb_object_event(fs, (spiffs_page_object_ix *)objix, + SPIFFS_EV_IX_UPD, fd->obj_id, objix->p_hdr.span_ix, new_objix_pix, 0); + + } else { + // wrote within object index header page + res2 = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, + fd->objix_hdr_pix, fs->work, 0, 0, 0, &new_objix_hdr_pix); + SPIFFS_DBG("modify: store modified objix_hdr page, "_SPIPRIpg":"_SPIPRIsp", written "_SPIPRIi"\n", new_objix_hdr_pix, 0, written); + SPIFFS_CHECK_RES(res2); + } + + return res; +} // spiffs_object_modify +#endif // !SPIFFS_READ_ONLY + +static s32_t spiffs_object_find_object_index_header_by_name_v( + spiffs *fs, + spiffs_obj_id obj_id, + spiffs_block_ix bix, + int ix_entry, + const void *user_const_p, + void *user_var_p) { + (void)user_var_p; + s32_t res; + spiffs_page_object_ix_header objix_hdr; + spiffs_page_ix pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, ix_entry); + if (obj_id == SPIFFS_OBJ_ID_FREE || obj_id == SPIFFS_OBJ_ID_DELETED || + (obj_id & SPIFFS_OBJ_ID_IX_FLAG) == 0) { + return SPIFFS_VIS_COUNTINUE; + } + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, + 0, SPIFFS_PAGE_TO_PADDR(fs, pix), sizeof(spiffs_page_object_ix_header), (u8_t *)&objix_hdr); + SPIFFS_CHECK_RES(res); + if (objix_hdr.p_hdr.span_ix == 0 && + (objix_hdr.p_hdr.flags & (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_IXDELE)) == + (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_IXDELE)) { + if (strcmp((const char*)user_const_p, (char*)objix_hdr.name) == 0) { + return SPIFFS_OK; + } + } + + return SPIFFS_VIS_COUNTINUE; +} + +// Finds object index header page by name +s32_t spiffs_object_find_object_index_header_by_name( + spiffs *fs, + const u8_t name[SPIFFS_OBJ_NAME_LEN], + spiffs_page_ix *pix) { + s32_t res; + spiffs_block_ix bix; + int entry; + + res = spiffs_obj_lu_find_entry_visitor(fs, + fs->cursor_block_ix, + fs->cursor_obj_lu_entry, + 0, + 0, + spiffs_object_find_object_index_header_by_name_v, + name, + 0, + &bix, + &entry); + + if (res == SPIFFS_VIS_END) { + res = SPIFFS_ERR_NOT_FOUND; + } + SPIFFS_CHECK_RES(res); + + if (pix) { + *pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, entry); + } + + fs->cursor_block_ix = bix; + fs->cursor_obj_lu_entry = entry; + + return res; +} + +#if !SPIFFS_READ_ONLY +// Truncates object to new size. If new size is null, object may be removed totally +s32_t spiffs_object_truncate( + spiffs_fd *fd, + u32_t new_size, + u8_t remove_full) { + s32_t res = SPIFFS_OK; + spiffs *fs = fd->fs; + + if ((fd->size == SPIFFS_UNDEFINED_LEN || fd->size == 0) && !remove_full) { + // no op + return res; + } + + // need 2 pages if not removing: object index page + possibly chopped data page + if (remove_full == 0) { + res = spiffs_gc_check(fs, SPIFFS_DATA_PAGE_SIZE(fs) * 2); + SPIFFS_CHECK_RES(res); + } + + spiffs_page_ix objix_pix = fd->objix_hdr_pix; + spiffs_span_ix data_spix = (fd->size > 0 ? fd->size-1 : 0) / SPIFFS_DATA_PAGE_SIZE(fs); + u32_t cur_size = fd->size == (u32_t)SPIFFS_UNDEFINED_LEN ? 0 : fd->size ; + spiffs_span_ix cur_objix_spix = 0; + spiffs_span_ix prev_objix_spix = (spiffs_span_ix)-1; + spiffs_page_object_ix_header *objix_hdr = (spiffs_page_object_ix_header *)fs->work; + spiffs_page_object_ix *objix = (spiffs_page_object_ix *)fs->work; + spiffs_page_ix data_pix; + spiffs_page_ix new_objix_hdr_pix; + + // before truncating, check if object is to be fully removed and mark this + if (remove_full && new_size == 0) { + u8_t flags = ~( SPIFFS_PH_FLAG_USED | SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_IXDELE); + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_UPDT, + fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, fd->objix_hdr_pix) + offsetof(spiffs_page_header, flags), + sizeof(u8_t), + (u8_t *)&flags); + SPIFFS_CHECK_RES(res); + } + + // delete from end of object until desired len is reached + while (cur_size > new_size) { + cur_objix_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, data_spix); + + // put object index for current data span index in work buffer + if (prev_objix_spix != cur_objix_spix) { + if (prev_objix_spix != (spiffs_span_ix)-1) { + // remove previous object index page + SPIFFS_DBG("truncate: delete objix page "_SPIPRIpg":"_SPIPRIsp"\n", objix_pix, prev_objix_spix); + + res = spiffs_page_index_check(fs, fd, objix_pix, prev_objix_spix); + SPIFFS_CHECK_RES(res); + + res = spiffs_page_delete(fs, objix_pix); + SPIFFS_CHECK_RES(res); + spiffs_cb_object_event(fs, (spiffs_page_object_ix *)0, + SPIFFS_EV_IX_DEL, fd->obj_id, objix->p_hdr.span_ix, objix_pix, 0); + if (prev_objix_spix > 0) { + // Update object index header page, unless we totally want to remove the file. + // If fully removing, we're not keeping consistency as good as when storing the header between chunks, + // would we be aborted. But when removing full files, a crammed system may otherwise + // report ERR_FULL a la windows. We cannot have that. + // Hence, take the risk - if aborted, a file check would free the lost pages and mend things + // as the file is marked as fully deleted in the beginning. + if (remove_full == 0) { + SPIFFS_DBG("truncate: update objix hdr page "_SPIPRIpg":"_SPIPRIsp" to size "_SPIPRIi"\n", fd->objix_hdr_pix, prev_objix_spix, cur_size); + res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, + fd->objix_hdr_pix, 0, 0, 0, cur_size, &new_objix_hdr_pix); + SPIFFS_CHECK_RES(res); + } + fd->size = cur_size; + } + } + // load current object index (header) page + if (cur_objix_spix == 0) { + objix_pix = fd->objix_hdr_pix; + } else { + res = spiffs_obj_lu_find_id_and_span(fs, fd->obj_id | SPIFFS_OBJ_ID_IX_FLAG, cur_objix_spix, 0, &objix_pix); + SPIFFS_CHECK_RES(res); + } + + SPIFFS_DBG("truncate: load objix page "_SPIPRIpg":"_SPIPRIsp" for data spix:"_SPIPRIsp"\n", objix_pix, cur_objix_spix, data_spix); + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, + fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); + SPIFFS_CHECK_RES(res); + SPIFFS_VALIDATE_OBJIX(objix_hdr->p_hdr, fd->obj_id, cur_objix_spix); + fd->cursor_objix_pix = objix_pix; + fd->cursor_objix_spix = cur_objix_spix; + fd->offset = cur_size; + + prev_objix_spix = cur_objix_spix; + } + + if (cur_objix_spix == 0) { + // get data page from object index header page + data_pix = ((spiffs_page_ix*)((u8_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[data_spix]; + ((spiffs_page_ix*)((u8_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[data_spix] = SPIFFS_OBJ_ID_FREE; + } else { + // get data page from object index page + data_pix = ((spiffs_page_ix*)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)]; + ((spiffs_page_ix*)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)] = SPIFFS_OBJ_ID_FREE; + } + + SPIFFS_DBG("truncate: got data pix "_SPIPRIpg"\n", data_pix); + + if (new_size == 0 || remove_full || cur_size - new_size >= SPIFFS_DATA_PAGE_SIZE(fs)) { + // delete full data page + res = spiffs_page_data_check(fs, fd, data_pix, data_spix); + if (res != SPIFFS_ERR_DELETED && res != SPIFFS_OK && res != SPIFFS_ERR_INDEX_REF_FREE) { + SPIFFS_DBG("truncate: err validating data pix "_SPIPRIi"\n", res); + break; + } + + if (res == SPIFFS_OK) { + res = spiffs_page_delete(fs, data_pix); + if (res != SPIFFS_OK) { + SPIFFS_DBG("truncate: err deleting data pix "_SPIPRIi"\n", res); + break; + } + } else if (res == SPIFFS_ERR_DELETED || res == SPIFFS_ERR_INDEX_REF_FREE) { + res = SPIFFS_OK; + } + + // update current size + if (cur_size % SPIFFS_DATA_PAGE_SIZE(fs) == 0) { + cur_size -= SPIFFS_DATA_PAGE_SIZE(fs); + } else { + cur_size -= cur_size % SPIFFS_DATA_PAGE_SIZE(fs); + } + fd->size = cur_size; + fd->offset = cur_size; + SPIFFS_DBG("truncate: delete data page "_SPIPRIpg" for data spix:"_SPIPRIsp", cur_size:"_SPIPRIi"\n", data_pix, data_spix, cur_size); + } else { + // delete last page, partially + spiffs_page_header p_hdr; + spiffs_page_ix new_data_pix; + u32_t bytes_to_remove = SPIFFS_DATA_PAGE_SIZE(fs) - (new_size % SPIFFS_DATA_PAGE_SIZE(fs)); + SPIFFS_DBG("truncate: delete "_SPIPRIi" bytes from data page "_SPIPRIpg" for data spix:"_SPIPRIsp", cur_size:"_SPIPRIi"\n", bytes_to_remove, data_pix, data_spix, cur_size); + + res = spiffs_page_data_check(fs, fd, data_pix, data_spix); + if (res != SPIFFS_OK) break; + + p_hdr.obj_id = fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG; + p_hdr.span_ix = data_spix; + p_hdr.flags = 0xff; + // allocate new page and copy unmodified data + res = spiffs_page_allocate_data(fs, fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, + &p_hdr, 0, 0, 0, 0, &new_data_pix); + if (res != SPIFFS_OK) break; + res = spiffs_phys_cpy(fs, 0, + SPIFFS_PAGE_TO_PADDR(fs, new_data_pix) + sizeof(spiffs_page_header), + SPIFFS_PAGE_TO_PADDR(fs, data_pix) + sizeof(spiffs_page_header), + SPIFFS_DATA_PAGE_SIZE(fs) - bytes_to_remove); + if (res != SPIFFS_OK) break; + // delete original data page + res = spiffs_page_delete(fs, data_pix); + if (res != SPIFFS_OK) break; + p_hdr.flags &= ~SPIFFS_PH_FLAG_FINAL; + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, + fd->file_nbr, + SPIFFS_PAGE_TO_PADDR(fs, new_data_pix) + offsetof(spiffs_page_header, flags), + sizeof(u8_t), + (u8_t *)&p_hdr.flags); + if (res != SPIFFS_OK) break; + + // update memory representation of object index page with new data page + if (cur_objix_spix == 0) { + // update object index header page + ((spiffs_page_ix*)((u8_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[data_spix] = new_data_pix; + SPIFFS_DBG("truncate: wrote page "_SPIPRIpg" to objix_hdr entry "_SPIPRIsp" in mem\n", new_data_pix, (spiffs_span_ix)SPIFFS_OBJ_IX_ENTRY(fs, data_spix)); + } else { + // update object index page + ((spiffs_page_ix*)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)] = new_data_pix; + SPIFFS_DBG("truncate: wrote page "_SPIPRIpg" to objix entry "_SPIPRIsp" in mem\n", new_data_pix, (spiffs_span_ix)SPIFFS_OBJ_IX_ENTRY(fs, data_spix)); + } + cur_size = new_size; + fd->size = new_size; + fd->offset = cur_size; + break; + } + data_spix--; + } // while all data + + // update object indices + if (cur_objix_spix == 0) { + // update object index header page + if (cur_size == 0) { + if (remove_full) { + // remove object altogether + SPIFFS_DBG("truncate: remove object index header page "_SPIPRIpg"\n", objix_pix); + + res = spiffs_page_index_check(fs, fd, objix_pix, 0); + SPIFFS_CHECK_RES(res); + + res = spiffs_page_delete(fs, objix_pix); + SPIFFS_CHECK_RES(res); + spiffs_cb_object_event(fs, (spiffs_page_object_ix *)0, + SPIFFS_EV_IX_DEL, fd->obj_id, 0, objix_pix, 0); + } else { + // make uninitialized object + SPIFFS_DBG("truncate: reset objix_hdr page "_SPIPRIpg"\n", objix_pix); + memset(fs->work + sizeof(spiffs_page_object_ix_header), 0xff, + SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_page_object_ix_header)); + res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, + objix_pix, fs->work, 0, 0, SPIFFS_UNDEFINED_LEN, &new_objix_hdr_pix); + SPIFFS_CHECK_RES(res); + } + } else { + // update object index header page + SPIFFS_DBGF("truncate: update object index header page with indices and size\n"); + res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, + objix_pix, fs->work, 0, 0, cur_size, &new_objix_hdr_pix); + SPIFFS_CHECK_RES(res); + } + } else { + // update both current object index page and object index header page + spiffs_page_ix new_objix_pix; + + res = spiffs_page_index_check(fs, fd, objix_pix, cur_objix_spix); + SPIFFS_CHECK_RES(res); + + // move and update object index page + res = spiffs_page_move(fs, fd->file_nbr, (u8_t*)objix_hdr, fd->obj_id, 0, objix_pix, &new_objix_pix); + SPIFFS_CHECK_RES(res); + spiffs_cb_object_event(fs, (spiffs_page_object_ix *)objix_hdr, + SPIFFS_EV_IX_UPD, fd->obj_id, objix->p_hdr.span_ix, new_objix_pix, 0); + SPIFFS_DBG("truncate: store modified objix page, "_SPIPRIpg":"_SPIPRIsp"\n", new_objix_pix, cur_objix_spix); + fd->cursor_objix_pix = new_objix_pix; + fd->cursor_objix_spix = cur_objix_spix; + fd->offset = cur_size; + // update object index header page with new size + res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, + fd->objix_hdr_pix, 0, 0, 0, cur_size, &new_objix_hdr_pix); + SPIFFS_CHECK_RES(res); + } + fd->size = cur_size; + + return res; +} // spiffs_object_truncate +#endif // !SPIFFS_READ_ONLY + +s32_t spiffs_object_read( + spiffs_fd *fd, + u32_t offset, + u32_t len, + u8_t *dst) { + s32_t res = SPIFFS_OK; + spiffs *fs = fd->fs; + spiffs_page_ix objix_pix; + spiffs_page_ix data_pix; + spiffs_span_ix data_spix = offset / SPIFFS_DATA_PAGE_SIZE(fs); + u32_t cur_offset = offset; + spiffs_span_ix cur_objix_spix; + spiffs_span_ix prev_objix_spix = (spiffs_span_ix)-1; + spiffs_page_object_ix_header *objix_hdr = (spiffs_page_object_ix_header *)fs->work; + spiffs_page_object_ix *objix = (spiffs_page_object_ix *)fs->work; + + while (cur_offset < offset + len) { +#if SPIFFS_IX_MAP + // check if we have a memory, index map and if so, if we're within index map's range + // and if so, if the entry is populated + if (fd->ix_map && data_spix >= fd->ix_map->start_spix && data_spix <= fd->ix_map->end_spix + && fd->ix_map->map_buf[data_spix - fd->ix_map->start_spix]) { + data_pix = fd->ix_map->map_buf[data_spix - fd->ix_map->start_spix]; + } else { +#endif + cur_objix_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, data_spix); + if (prev_objix_spix != cur_objix_spix) { + // load current object index (header) page + if (cur_objix_spix == 0) { + objix_pix = fd->objix_hdr_pix; + } else { + SPIFFS_DBG("read: find objix "_SPIPRIid":"_SPIPRIsp"\n", fd->obj_id, cur_objix_spix); + if (fd->cursor_objix_spix == cur_objix_spix) { + objix_pix = fd->cursor_objix_pix; + } else { + res = spiffs_obj_lu_find_id_and_span(fs, fd->obj_id | SPIFFS_OBJ_ID_IX_FLAG, cur_objix_spix, 0, &objix_pix); + SPIFFS_CHECK_RES(res); + } + } + SPIFFS_DBG("read: load objix page "_SPIPRIpg":"_SPIPRIsp" for data spix:"_SPIPRIsp"\n", objix_pix, cur_objix_spix, data_spix); + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, + fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); + SPIFFS_CHECK_RES(res); + SPIFFS_VALIDATE_OBJIX(objix->p_hdr, fd->obj_id, cur_objix_spix); + + fd->offset = cur_offset; + fd->cursor_objix_pix = objix_pix; + fd->cursor_objix_spix = cur_objix_spix; + + prev_objix_spix = cur_objix_spix; + } + + if (cur_objix_spix == 0) { + // get data page from object index header page + data_pix = ((spiffs_page_ix*)((u8_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[data_spix]; + } else { + // get data page from object index page + data_pix = ((spiffs_page_ix*)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)]; + } +#if SPIFFS_IX_MAP + } +#endif + // all remaining data + u32_t len_to_read = offset + len - cur_offset; + // remaining data in page + len_to_read = MIN(len_to_read, SPIFFS_DATA_PAGE_SIZE(fs) - (cur_offset % SPIFFS_DATA_PAGE_SIZE(fs))); + // remaining data in file + len_to_read = MIN(len_to_read, fd->size - cur_offset); + SPIFFS_DBG("read: offset:"_SPIPRIi" rd:"_SPIPRIi" data spix:"_SPIPRIsp" is data_pix:"_SPIPRIpg" addr:"_SPIPRIad"\n", cur_offset, len_to_read, data_spix, data_pix, + (u32_t)(SPIFFS_PAGE_TO_PADDR(fs, data_pix) + sizeof(spiffs_page_header) + (cur_offset % SPIFFS_DATA_PAGE_SIZE(fs)))); + if (len_to_read <= 0) { + res = SPIFFS_ERR_END_OF_OBJECT; + break; + } + res = spiffs_page_data_check(fs, fd, data_pix, data_spix); + SPIFFS_CHECK_RES(res); + res = _spiffs_rd( + fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_READ, + fd->file_nbr, + SPIFFS_PAGE_TO_PADDR(fs, data_pix) + sizeof(spiffs_page_header) + (cur_offset % SPIFFS_DATA_PAGE_SIZE(fs)), + len_to_read, + dst); + SPIFFS_CHECK_RES(res); + dst += len_to_read; + cur_offset += len_to_read; + fd->offset = cur_offset; + data_spix++; + } + + return res; +} + +#if !SPIFFS_READ_ONLY +typedef struct { + spiffs_obj_id min_obj_id; + spiffs_obj_id max_obj_id; + u32_t compaction; + const u8_t *conflicting_name; +} spiffs_free_obj_id_state; + +static s32_t spiffs_obj_lu_find_free_obj_id_bitmap_v(spiffs *fs, spiffs_obj_id id, spiffs_block_ix bix, int ix_entry, + const void *user_const_p, void *user_var_p) { + if (id != SPIFFS_OBJ_ID_FREE && id != SPIFFS_OBJ_ID_DELETED) { + spiffs_obj_id min_obj_id = *((spiffs_obj_id*)user_var_p); + const u8_t *conflicting_name = (const u8_t*)user_const_p; + + // if conflicting name parameter is given, also check if this name is found in object index hdrs + if (conflicting_name && (id & SPIFFS_OBJ_ID_IX_FLAG)) { + spiffs_page_ix pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, ix_entry); + int res; + spiffs_page_object_ix_header objix_hdr; + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, + 0, SPIFFS_PAGE_TO_PADDR(fs, pix), sizeof(spiffs_page_object_ix_header), (u8_t *)&objix_hdr); + SPIFFS_CHECK_RES(res); + if (objix_hdr.p_hdr.span_ix == 0 && + (objix_hdr.p_hdr.flags & (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_IXDELE)) == + (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_IXDELE)) { + if (strcmp((const char*)user_const_p, (char*)objix_hdr.name) == 0) { + return SPIFFS_ERR_CONFLICTING_NAME; + } + } + } + + id &= ~SPIFFS_OBJ_ID_IX_FLAG; + u32_t bit_ix = (id-min_obj_id) & 7; + int byte_ix = (id-min_obj_id) >> 3; + if (byte_ix >= 0 && (u32_t)byte_ix < SPIFFS_CFG_LOG_PAGE_SZ(fs)) { + fs->work[byte_ix] |= (1<conflicting_name && strcmp((const char *)state->conflicting_name, (char *)objix_hdr.name) == 0) { + return SPIFFS_ERR_CONFLICTING_NAME; + } + + id &= ~SPIFFS_OBJ_ID_IX_FLAG; + if (id >= state->min_obj_id && id <= state->max_obj_id) { + u8_t *map = (u8_t *)fs->work; + int ix = (id - state->min_obj_id) / state->compaction; + //SPIFFS_DBG("free_obj_id: add ix "_SPIPRIi" for id "_SPIPRIid" min"_SPIPRIid" max"_SPIPRIid" comp:"_SPIPRIi"\n", ix, id, state->min_obj_id, state->max_obj_id, state->compaction); + map[ix]++; + } + } + } + return SPIFFS_VIS_COUNTINUE; +} + +// Scans thru all object lookup for object index header pages. If total possible number of +// object ids cannot fit into a work buffer, these are grouped. When a group containing free +// object ids is found, the object lu is again scanned for object ids within group and bitmasked. +// Finally, the bitmask is searched for a free id +s32_t spiffs_obj_lu_find_free_obj_id(spiffs *fs, spiffs_obj_id *obj_id, const u8_t *conflicting_name) { + s32_t res = SPIFFS_OK; + u32_t max_objects = (fs->block_count * SPIFFS_OBJ_LOOKUP_MAX_ENTRIES(fs)) / 2; + spiffs_free_obj_id_state state; + spiffs_obj_id free_obj_id = SPIFFS_OBJ_ID_FREE; + state.min_obj_id = 1; + state.max_obj_id = max_objects + 1; + if (state.max_obj_id & SPIFFS_OBJ_ID_IX_FLAG) { + state.max_obj_id = ((spiffs_obj_id)-1) & ~SPIFFS_OBJ_ID_IX_FLAG; + } + state.compaction = 0; + state.conflicting_name = conflicting_name; + while (res == SPIFFS_OK && free_obj_id == SPIFFS_OBJ_ID_FREE) { + if (state.max_obj_id - state.min_obj_id <= (spiffs_obj_id)SPIFFS_CFG_LOG_PAGE_SZ(fs)*8) { + // possible to represent in bitmap + u32_t i, j; + SPIFFS_DBG("free_obj_id: BITM min:"_SPIPRIid" max:"_SPIPRIid"\n", state.min_obj_id, state.max_obj_id); + + memset(fs->work, 0, SPIFFS_CFG_LOG_PAGE_SZ(fs)); + res = spiffs_obj_lu_find_entry_visitor(fs, 0, 0, 0, 0, spiffs_obj_lu_find_free_obj_id_bitmap_v, + conflicting_name, &state.min_obj_id, 0, 0); + if (res == SPIFFS_VIS_END) res = SPIFFS_OK; + SPIFFS_CHECK_RES(res); + // traverse bitmask until found free obj_id + for (i = 0; i < SPIFFS_CFG_LOG_PAGE_SZ(fs); i++) { + u8_t mask = fs->work[i]; + if (mask == 0xff) { + continue; + } + for (j = 0; j < 8; j++) { + if ((mask & (1<work; + u8_t min_count = 0xff; + + for (i = 0; i < SPIFFS_CFG_LOG_PAGE_SZ(fs)/sizeof(u8_t); i++) { + if (map[i] < min_count) { + min_count = map[i]; + min_i = i; + if (min_count == 0) { + break; + } + } + } + + if (min_count == state.compaction) { + // there are no free objids! + SPIFFS_DBGF("free_obj_id: compacted table is full\n"); + return SPIFFS_ERR_FULL; + } + + SPIFFS_DBG("free_obj_id: COMP select index:"_SPIPRIi" min_count:"_SPIPRIi" min:"_SPIPRIid" max:"_SPIPRIid" compact:"_SPIPRIi"\n", min_i, min_count, state.min_obj_id, state.max_obj_id, state.compaction); + + if (min_count == 0) { + // no id in this range, skip compacting and use directly + *obj_id = min_i * state.compaction + state.min_obj_id; + return SPIFFS_OK; + } else { + SPIFFS_DBG("free_obj_id: COMP SEL chunk:"_SPIPRIi" min:"_SPIPRIid" -> "_SPIPRIid"\n", state.compaction, state.min_obj_id, state.min_obj_id + min_i * state.compaction); + state.min_obj_id += min_i * state.compaction; + state.max_obj_id = state.min_obj_id + state.compaction; + // decrease compaction + } + if ((state.max_obj_id - state.min_obj_id <= (spiffs_obj_id)SPIFFS_CFG_LOG_PAGE_SZ(fs)*8)) { + // no need for compacting, use bitmap + continue; + } + } + // in a work memory of log_page_size bytes, we may fit in log_page_size ids + // todo what if compaction is > 255 - then we cannot fit it in a byte + state.compaction = (state.max_obj_id-state.min_obj_id) / ((SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(u8_t))); + SPIFFS_DBG("free_obj_id: COMP min:"_SPIPRIid" max:"_SPIPRIid" compact:"_SPIPRIi"\n", state.min_obj_id, state.max_obj_id, state.compaction); + + memset(fs->work, 0, SPIFFS_CFG_LOG_PAGE_SZ(fs)); + res = spiffs_obj_lu_find_entry_visitor(fs, 0, 0, 0, 0, spiffs_obj_lu_find_free_obj_id_compact_v, &state, 0, 0, 0); + if (res == SPIFFS_VIS_END) res = SPIFFS_OK; + SPIFFS_CHECK_RES(res); + state.conflicting_name = 0; // searched for conflicting name once, no need to do it again + } + } + + return res; +} +#endif // !SPIFFS_READ_ONLY + +#if SPIFFS_TEMPORAL_FD_CACHE +// djb2 hash +static u32_t spiffs_hash(spiffs *fs, const u8_t *name) { + (void)fs; + u32_t hash = 5381; + u8_t c; + int i = 0; + while ((c = name[i++]) && i < SPIFFS_OBJ_NAME_LEN) { + hash = (hash * 33) ^ c; + } + return hash; +} +#endif + +s32_t spiffs_fd_find_new(spiffs *fs, spiffs_fd **fd, const char *name) { +#if SPIFFS_TEMPORAL_FD_CACHE + u32_t i; + u16_t min_score = 0xffff; + u32_t cand_ix = (u32_t)-1; + u32_t name_hash = name ? spiffs_hash(fs, (const u8_t *)name) : 0; + spiffs_fd *fds = (spiffs_fd *)fs->fd_space; + + if (name) { + // first, decrease score of all closed descriptors + for (i = 0; i < fs->fd_count; i++) { + spiffs_fd *cur_fd = &fds[i]; + if (cur_fd->file_nbr == 0) { + if (cur_fd->score > 1) { // score == 0 indicates never used fd + cur_fd->score--; + } + } + } + } + + // find the free fd with least score or name match + for (i = 0; i < fs->fd_count; i++) { + spiffs_fd *cur_fd = &fds[i]; + if (cur_fd->file_nbr == 0) { + if (name && cur_fd->name_hash == name_hash) { + cand_ix = i; + break; + } + if (cur_fd->score < min_score) { + min_score = cur_fd->score; + cand_ix = i; + } + } + } + + if (cand_ix != (u32_t)-1) { + spiffs_fd *cur_fd = &fds[cand_ix]; + if (name) { + if (cur_fd->name_hash == name_hash && cur_fd->score > 0) { + // opened an fd with same name hash, assume same file + // set search point to saved obj index page and hope we have a correct match directly + // when start searching - if not, we will just keep searching until it is found + fs->cursor_block_ix = SPIFFS_BLOCK_FOR_PAGE(fs, cur_fd->objix_hdr_pix); + fs->cursor_obj_lu_entry = SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(fs, cur_fd->objix_hdr_pix); + // update score + if (cur_fd->score < 0xffff-SPIFFS_TEMPORAL_CACHE_HIT_SCORE) { + cur_fd->score += SPIFFS_TEMPORAL_CACHE_HIT_SCORE; + } else { + cur_fd->score = 0xffff; + } + } else { + // no hash hit, restore this fd to initial state + cur_fd->score = SPIFFS_TEMPORAL_CACHE_HIT_SCORE; + cur_fd->name_hash = name_hash; + } + } + cur_fd->file_nbr = cand_ix+1; + *fd = cur_fd; + return SPIFFS_OK; + } else { + return SPIFFS_ERR_OUT_OF_FILE_DESCS; + } +#else + (void)name; + u32_t i; + spiffs_fd *fds = (spiffs_fd *)fs->fd_space; + for (i = 0; i < fs->fd_count; i++) { + spiffs_fd *cur_fd = &fds[i]; + if (cur_fd->file_nbr == 0) { + cur_fd->file_nbr = i+1; + *fd = cur_fd; + return SPIFFS_OK; + } + } + return SPIFFS_ERR_OUT_OF_FILE_DESCS; +#endif +} + +s32_t spiffs_fd_return(spiffs *fs, spiffs_file f) { + if (f <= 0 || f > (s16_t)fs->fd_count) { + return SPIFFS_ERR_BAD_DESCRIPTOR; + } + spiffs_fd *fds = (spiffs_fd *)fs->fd_space; + spiffs_fd *fd = &fds[f-1]; + if (fd->file_nbr == 0) { + return SPIFFS_ERR_FILE_CLOSED; + } + fd->file_nbr = 0; +#if SPIFFS_IX_MAP + fd->ix_map = 0; +#endif + return SPIFFS_OK; +} + +s32_t spiffs_fd_get(spiffs *fs, spiffs_file f, spiffs_fd **fd) { + if (f <= 0 || f > (s16_t)fs->fd_count) { + return SPIFFS_ERR_BAD_DESCRIPTOR; + } + spiffs_fd *fds = (spiffs_fd *)fs->fd_space; + *fd = &fds[f-1]; + if ((*fd)->file_nbr == 0) { + return SPIFFS_ERR_FILE_CLOSED; + } + return SPIFFS_OK; +} + +#if SPIFFS_TEMPORAL_FD_CACHE +void spiffs_fd_temporal_cache_rehash( + spiffs *fs, + const char *old_path, + const char *new_path) { + u32_t i; + u32_t old_hash = spiffs_hash(fs, (const u8_t *)old_path); + u32_t new_hash = spiffs_hash(fs, (const u8_t *)new_path); + spiffs_fd *fds = (spiffs_fd *)fs->fd_space; + for (i = 0; i < fs->fd_count; i++) { + spiffs_fd *cur_fd = &fds[i]; + if (cur_fd->score > 0 && cur_fd->name_hash == old_hash) { + cur_fd->name_hash = new_hash; + } + } +} +#endif diff --git a/armsrc/spiffs_nucleus.h b/armsrc/spiffs_nucleus.h new file mode 100644 index 000000000..255c5aa08 --- /dev/null +++ b/armsrc/spiffs_nucleus.h @@ -0,0 +1,842 @@ +/* + * spiffs_nucleus.h + * + * Created on: Jun 15, 2013 + * Author: petera + */ + +/* SPIFFS layout + * + * spiffs is designed for following spi flash characteristics: + * - only big areas of data (blocks) can be erased + * - erasing resets all bits in a block to ones + * - writing pulls ones to zeroes + * - zeroes cannot be pulled to ones, without erase + * - wear leveling + * + * spiffs is also meant to be run on embedded, memory constraint devices. + * + * Entire area is divided in blocks. Entire area is also divided in pages. + * Each block contains same number of pages. A page cannot be erased, but a + * block can be erased. + * + * Entire area must be block_size * x + * page_size must be block_size / (2^y) where y > 2 + * + * ex: area = 1024*1024 bytes, block size = 65536 bytes, page size = 256 bytes + * + * BLOCK 0 PAGE 0 object lookup 1 + * PAGE 1 object lookup 2 + * ... + * PAGE n-1 object lookup n + * PAGE n object data 1 + * PAGE n+1 object data 2 + * ... + * PAGE n+m-1 object data m + * + * BLOCK 1 PAGE n+m object lookup 1 + * PAGE n+m+1 object lookup 2 + * ... + * PAGE 2n+m-1 object lookup n + * PAGE 2n+m object data 1 + * PAGE 2n+m object data 2 + * ... + * PAGE 2n+2m-1 object data m + * ... + * + * n is number of object lookup pages, which is number of pages needed to index all pages + * in a block by object id + * : block_size / page_size * sizeof(obj_id) / page_size + * m is number data pages, which is number of pages in block minus number of lookup pages + * : block_size / page_size - block_size / page_size * sizeof(obj_id) / page_size + * thus, n+m is total number of pages in a block + * : block_size / page_size + * + * ex: n = 65536/256*2/256 = 2, m = 65536/256 - 2 = 254 => n+m = 65536/256 = 256 + * + * Object lookup pages contain object id entries. Each entry represent the corresponding + * data page. + * Assuming a 16 bit object id, an object id being 0xffff represents a free page. + * An object id being 0x0000 represents a deleted page. + * + * ex: page 0 : lookup : 0008 0001 0aaa ffff ffff ffff ffff ffff .. + * page 1 : lookup : ffff ffff ffff ffff ffff ffff ffff ffff .. + * page 2 : data : data for object id 0008 + * page 3 : data : data for object id 0001 + * page 4 : data : data for object id 0aaa + * ... + * + * + * Object data pages can be either object index pages or object content. + * All object data pages contains a data page header, containing object id and span index. + * The span index denotes the object page ordering amongst data pages with same object id. + * This applies to both object index pages (when index spans more than one page of entries), + * and object data pages. + * An object index page contains page entries pointing to object content page. The entry index + * in a object index page correlates to the span index in the actual object data page. + * The first object index page (span index 0) is called object index header page, and also + * contains object flags (directory/file), size, object name etc. + * + * ex: + * BLOCK 1 + * PAGE 256: objectl lookup page 1 + * [*123] [ 123] [ 123] [ 123] + * [ 123] [*123] [ 123] [ 123] + * [free] [free] [free] [free] ... + * PAGE 257: objectl lookup page 2 + * [free] [free] [free] [free] ... + * PAGE 258: object index page (header) + * obj.id:0123 span.ix:0000 flags:INDEX + * size:1600 name:ex.txt type:file + * [259] [260] [261] [262] + * PAGE 259: object data page + * obj.id:0123 span.ix:0000 flags:DATA + * PAGE 260: object data page + * obj.id:0123 span.ix:0001 flags:DATA + * PAGE 261: object data page + * obj.id:0123 span.ix:0002 flags:DATA + * PAGE 262: object data page + * obj.id:0123 span.ix:0003 flags:DATA + * PAGE 263: object index page + * obj.id:0123 span.ix:0001 flags:INDEX + * [264] [265] [fre] [fre] + * [fre] [fre] [fre] [fre] + * PAGE 264: object data page + * obj.id:0123 span.ix:0004 flags:DATA + * PAGE 265: object data page + * obj.id:0123 span.ix:0005 flags:DATA + * + */ +#ifndef SPIFFS_NUCLEUS_H_ +#define SPIFFS_NUCLEUS_H_ + +#define _SPIFFS_ERR_CHECK_FIRST (SPIFFS_ERR_INTERNAL - 1) +#define SPIFFS_ERR_CHECK_OBJ_ID_MISM (SPIFFS_ERR_INTERNAL - 1) +#define SPIFFS_ERR_CHECK_SPIX_MISM (SPIFFS_ERR_INTERNAL - 2) +#define SPIFFS_ERR_CHECK_FLAGS_BAD (SPIFFS_ERR_INTERNAL - 3) +#define _SPIFFS_ERR_CHECK_LAST (SPIFFS_ERR_INTERNAL - 4) + +// visitor result, continue searching +#define SPIFFS_VIS_COUNTINUE (SPIFFS_ERR_INTERNAL - 20) +// visitor result, continue searching after reloading lu buffer +#define SPIFFS_VIS_COUNTINUE_RELOAD (SPIFFS_ERR_INTERNAL - 21) +// visitor result, stop searching +#define SPIFFS_VIS_END (SPIFFS_ERR_INTERNAL - 22) + +// updating an object index contents +#define SPIFFS_EV_IX_UPD (0) +// creating a new object index +#define SPIFFS_EV_IX_NEW (1) +// deleting an object index +#define SPIFFS_EV_IX_DEL (2) +// moving an object index without updating contents +#define SPIFFS_EV_IX_MOV (3) +// updating an object index header data only, not the table itself +#define SPIFFS_EV_IX_UPD_HDR (4) + +#define SPIFFS_OBJ_ID_IX_FLAG ((spiffs_obj_id)(1<<(8*sizeof(spiffs_obj_id)-1))) + +#define SPIFFS_UNDEFINED_LEN (u32_t)(-1) + +#define SPIFFS_OBJ_ID_DELETED ((spiffs_obj_id)0) +#define SPIFFS_OBJ_ID_FREE ((spiffs_obj_id)-1) + + + +#if defined(__GNUC__) || defined(__clang__) || defined(__TI_COMPILER_VERSION__) + /* For GCC, clang and TI compilers */ +#define SPIFFS_PACKED __attribute__((packed)) +#elif defined(__ICCARM__) || defined(__CC_ARM) + /* For IAR ARM and Keil MDK-ARM compilers */ +#define SPIFFS_PACKED + +#else + /* Unknown compiler */ +#define SPIFFS_PACKED +#endif + + + +#if SPIFFS_USE_MAGIC +#if !SPIFFS_USE_MAGIC_LENGTH +#define SPIFFS_MAGIC(fs, bix) \ + ((spiffs_obj_id)(0x20140529 ^ SPIFFS_CFG_LOG_PAGE_SZ(fs))) +#else // SPIFFS_USE_MAGIC_LENGTH +#define SPIFFS_MAGIC(fs, bix) \ + ((spiffs_obj_id)(0x20140529 ^ SPIFFS_CFG_LOG_PAGE_SZ(fs) ^ ((fs)->block_count - (bix)))) +#endif // SPIFFS_USE_MAGIC_LENGTH +#endif // SPIFFS_USE_MAGIC + +#define SPIFFS_CONFIG_MAGIC (0x20090315) + +#if SPIFFS_SINGLETON == 0 +#define SPIFFS_CFG_LOG_PAGE_SZ(fs) \ + ((fs)->cfg.log_page_size) +#define SPIFFS_CFG_LOG_BLOCK_SZ(fs) \ + ((fs)->cfg.log_block_size) +#define SPIFFS_CFG_PHYS_SZ(fs) \ + ((fs)->cfg.phys_size) +#define SPIFFS_CFG_PHYS_ERASE_SZ(fs) \ + ((fs)->cfg.phys_erase_block) +#define SPIFFS_CFG_PHYS_ADDR(fs) \ + ((fs)->cfg.phys_addr) +#endif + +// total number of pages +#define SPIFFS_MAX_PAGES(fs) \ + ( SPIFFS_CFG_PHYS_SZ(fs)/SPIFFS_CFG_LOG_PAGE_SZ(fs) ) +// total number of pages per block, including object lookup pages +#define SPIFFS_PAGES_PER_BLOCK(fs) \ + ( SPIFFS_CFG_LOG_BLOCK_SZ(fs)/SPIFFS_CFG_LOG_PAGE_SZ(fs) ) +// number of object lookup pages per block +#define SPIFFS_OBJ_LOOKUP_PAGES(fs) \ + (MAX(1, (SPIFFS_PAGES_PER_BLOCK(fs) * sizeof(spiffs_obj_id)) / SPIFFS_CFG_LOG_PAGE_SZ(fs)) ) +// checks if page index belongs to object lookup +#define SPIFFS_IS_LOOKUP_PAGE(fs,pix) \ + (((pix) % SPIFFS_PAGES_PER_BLOCK(fs)) < SPIFFS_OBJ_LOOKUP_PAGES(fs)) +// number of object lookup entries in all object lookup pages +#define SPIFFS_OBJ_LOOKUP_MAX_ENTRIES(fs) \ + (SPIFFS_PAGES_PER_BLOCK(fs)-SPIFFS_OBJ_LOOKUP_PAGES(fs)) +// converts a block to physical address +#define SPIFFS_BLOCK_TO_PADDR(fs, block) \ + ( SPIFFS_CFG_PHYS_ADDR(fs) + (block)* SPIFFS_CFG_LOG_BLOCK_SZ(fs) ) +// converts a object lookup entry to page index +#define SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, block, entry) \ + ((block)*SPIFFS_PAGES_PER_BLOCK(fs) + (SPIFFS_OBJ_LOOKUP_PAGES(fs) + entry)) +// converts a object lookup entry to physical address of corresponding page +#define SPIFFS_OBJ_LOOKUP_ENTRY_TO_PADDR(fs, block, entry) \ + (SPIFFS_BLOCK_TO_PADDR(fs, block) + (SPIFFS_OBJ_LOOKUP_PAGES(fs) + entry) * SPIFFS_CFG_LOG_PAGE_SZ(fs) ) +// converts a page to physical address +#define SPIFFS_PAGE_TO_PADDR(fs, page) \ + ( SPIFFS_CFG_PHYS_ADDR(fs) + (page) * SPIFFS_CFG_LOG_PAGE_SZ(fs) ) +// converts a physical address to page +#define SPIFFS_PADDR_TO_PAGE(fs, addr) \ + ( ((addr) - SPIFFS_CFG_PHYS_ADDR(fs)) / SPIFFS_CFG_LOG_PAGE_SZ(fs) ) +// gives index in page for a physical address +#define SPIFFS_PADDR_TO_PAGE_OFFSET(fs, addr) \ + ( ((addr) - SPIFFS_CFG_PHYS_ADDR(fs)) % SPIFFS_CFG_LOG_PAGE_SZ(fs) ) +// returns containing block for given page +#define SPIFFS_BLOCK_FOR_PAGE(fs, page) \ + ( (page) / SPIFFS_PAGES_PER_BLOCK(fs) ) +// returns starting page for block +#define SPIFFS_PAGE_FOR_BLOCK(fs, block) \ + ( (block) * SPIFFS_PAGES_PER_BLOCK(fs) ) +// converts page to entry in object lookup page +#define SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(fs, page) \ + ( (page) % SPIFFS_PAGES_PER_BLOCK(fs) - SPIFFS_OBJ_LOOKUP_PAGES(fs) ) +// returns data size in a data page +#define SPIFFS_DATA_PAGE_SIZE(fs) \ + ( SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_page_header) ) +// returns physical address for block's erase count, +// always in the physical last entry of the last object lookup page +#define SPIFFS_ERASE_COUNT_PADDR(fs, bix) \ + ( SPIFFS_BLOCK_TO_PADDR(fs, bix) + SPIFFS_OBJ_LOOKUP_PAGES(fs) * SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_obj_id) ) +// returns physical address for block's magic, +// always in the physical second last entry of the last object lookup page +#define SPIFFS_MAGIC_PADDR(fs, bix) \ + ( SPIFFS_BLOCK_TO_PADDR(fs, bix) + SPIFFS_OBJ_LOOKUP_PAGES(fs) * SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_obj_id)*2 ) +// checks if there is any room for magic in the object luts +#define SPIFFS_CHECK_MAGIC_POSSIBLE(fs) \ + ( (SPIFFS_OBJ_LOOKUP_MAX_ENTRIES(fs) % (SPIFFS_CFG_LOG_PAGE_SZ(fs)/sizeof(spiffs_obj_id))) * sizeof(spiffs_obj_id) \ + <= (SPIFFS_CFG_LOG_PAGE_SZ(fs)-sizeof(spiffs_obj_id)*2) ) + +// define helpers object + +// entries in an object header page index +#define SPIFFS_OBJ_HDR_IX_LEN(fs) \ + ((SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_page_object_ix_header))/sizeof(spiffs_page_ix)) +// entries in an object page index +#define SPIFFS_OBJ_IX_LEN(fs) \ + ((SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_page_object_ix))/sizeof(spiffs_page_ix)) +// object index entry for given data span index +#define SPIFFS_OBJ_IX_ENTRY(fs, spix) \ + ((spix) < SPIFFS_OBJ_HDR_IX_LEN(fs) ? (spix) : (((spix)-SPIFFS_OBJ_HDR_IX_LEN(fs))%SPIFFS_OBJ_IX_LEN(fs))) +// object index span index number for given data span index or entry +#define SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, spix) \ + ((spix) < SPIFFS_OBJ_HDR_IX_LEN(fs) ? 0 : (1+((spix)-SPIFFS_OBJ_HDR_IX_LEN(fs))/SPIFFS_OBJ_IX_LEN(fs))) +// get data span index for object index span index +#define SPIFFS_DATA_SPAN_IX_FOR_OBJ_IX_SPAN_IX(fs, spix) \ + ( (spix) == 0 ? 0 : (SPIFFS_OBJ_HDR_IX_LEN(fs) + (((spix)-1) * SPIFFS_OBJ_IX_LEN(fs))) ) + +#if SPIFFS_FILEHDL_OFFSET +#define SPIFFS_FH_OFFS(fs, fh) ((fh) != 0 ? ((fh) + (fs)->cfg.fh_ix_offset) : 0) +#define SPIFFS_FH_UNOFFS(fs, fh) ((fh) != 0 ? ((fh) - (fs)->cfg.fh_ix_offset) : 0) +#else +#define SPIFFS_FH_OFFS(fs, fh) (fh) +#define SPIFFS_FH_UNOFFS(fs, fh) (fh) +#endif + + +#define SPIFFS_OP_T_OBJ_LU (0<<0) +#define SPIFFS_OP_T_OBJ_LU2 (1<<0) +#define SPIFFS_OP_T_OBJ_IX (2<<0) +#define SPIFFS_OP_T_OBJ_DA (3<<0) +#define SPIFFS_OP_C_DELE (0<<2) +#define SPIFFS_OP_C_UPDT (1<<2) +#define SPIFFS_OP_C_MOVS (2<<2) +#define SPIFFS_OP_C_MOVD (3<<2) +#define SPIFFS_OP_C_FLSH (4<<2) +#define SPIFFS_OP_C_READ (5<<2) +#define SPIFFS_OP_C_WRTHRU (6<<2) + +#define SPIFFS_OP_TYPE_MASK (3<<0) +#define SPIFFS_OP_COM_MASK (7<<2) + + +// if 0, this page is written to, else clean +#define SPIFFS_PH_FLAG_USED (1<<0) +// if 0, writing is finalized, else under modification +#define SPIFFS_PH_FLAG_FINAL (1<<1) +// if 0, this is an index page, else a data page +#define SPIFFS_PH_FLAG_INDEX (1<<2) +// if 0, page is deleted, else valid +#define SPIFFS_PH_FLAG_DELET (1<<7) +// if 0, this index header is being deleted +#define SPIFFS_PH_FLAG_IXDELE (1<<6) + + +#define SPIFFS_CHECK_MOUNT(fs) \ + ((fs)->mounted != 0) + +#define SPIFFS_CHECK_CFG(fs) \ + ((fs)->config_magic == SPIFFS_CONFIG_MAGIC) + +#define SPIFFS_CHECK_RES(res) \ + do { \ + if ((res) < SPIFFS_OK) return (res); \ + } while (0); + +#define SPIFFS_API_CHECK_MOUNT(fs) \ + if (!SPIFFS_CHECK_MOUNT((fs))) { \ + (fs)->err_code = SPIFFS_ERR_NOT_MOUNTED; \ + return SPIFFS_ERR_NOT_MOUNTED; \ + } + +#define SPIFFS_API_CHECK_CFG(fs) \ + if (!SPIFFS_CHECK_CFG((fs))) { \ + (fs)->err_code = SPIFFS_ERR_NOT_CONFIGURED; \ + return SPIFFS_ERR_NOT_CONFIGURED; \ + } + +#define SPIFFS_API_CHECK_RES(fs, res) \ + if ((res) < SPIFFS_OK) { \ + (fs)->err_code = (res); \ + return (res); \ + } + +#define SPIFFS_API_CHECK_RES_UNLOCK(fs, res) \ + if ((res) < SPIFFS_OK) { \ + (fs)->err_code = (res); \ + SPIFFS_UNLOCK(fs); \ + return (res); \ + } + +#define SPIFFS_VALIDATE_OBJIX(ph, objid, spix) \ + if (((ph).flags & SPIFFS_PH_FLAG_USED) != 0) return SPIFFS_ERR_IS_FREE; \ + if (((ph).flags & SPIFFS_PH_FLAG_DELET) == 0) return SPIFFS_ERR_DELETED; \ + if (((ph).flags & SPIFFS_PH_FLAG_FINAL) != 0) return SPIFFS_ERR_NOT_FINALIZED; \ + if (((ph).flags & SPIFFS_PH_FLAG_INDEX) != 0) return SPIFFS_ERR_NOT_INDEX; \ + if (((objid) & SPIFFS_OBJ_ID_IX_FLAG) == 0) return SPIFFS_ERR_NOT_INDEX; \ + if ((ph).span_ix != (spix)) return SPIFFS_ERR_INDEX_SPAN_MISMATCH; + //if ((spix) == 0 && ((ph).flags & SPIFFS_PH_FLAG_IXDELE) == 0) return SPIFFS_ERR_DELETED; + +#define SPIFFS_VALIDATE_DATA(ph, objid, spix) \ + if (((ph).flags & SPIFFS_PH_FLAG_USED) != 0) return SPIFFS_ERR_IS_FREE; \ + if (((ph).flags & SPIFFS_PH_FLAG_DELET) == 0) return SPIFFS_ERR_DELETED; \ + if (((ph).flags & SPIFFS_PH_FLAG_FINAL) != 0) return SPIFFS_ERR_NOT_FINALIZED; \ + if (((ph).flags & SPIFFS_PH_FLAG_INDEX) == 0) return SPIFFS_ERR_IS_INDEX; \ + if ((objid) & SPIFFS_OBJ_ID_IX_FLAG) return SPIFFS_ERR_IS_INDEX; \ + if ((ph).span_ix != (spix)) return SPIFFS_ERR_DATA_SPAN_MISMATCH; + + +// check id, only visit matching objec ids +#define SPIFFS_VIS_CHECK_ID (1<<0) +// report argument object id to visitor - else object lookup id is reported +#define SPIFFS_VIS_CHECK_PH (1<<1) +// stop searching at end of all look up pages +#define SPIFFS_VIS_NO_WRAP (1<<2) + +#if SPIFFS_HAL_CALLBACK_EXTRA + +#define SPIFFS_HAL_WRITE(_fs, _paddr, _len, _src) \ + (_fs)->cfg.hal_write_f((_fs), (_paddr), (_len), (_src)) +#define SPIFFS_HAL_READ(_fs, _paddr, _len, _dst) \ + (_fs)->cfg.hal_read_f((_fs), (_paddr), (_len), (_dst)) +#define SPIFFS_HAL_ERASE(_fs, _paddr, _len) \ + (_fs)->cfg.hal_erase_f((_fs), (_paddr), (_len)) + +#else // SPIFFS_HAL_CALLBACK_EXTRA + +#define SPIFFS_HAL_WRITE(_fs, _paddr, _len, _src) \ + (_fs)->cfg.hal_write_f((_paddr), (_len), (_src)) +#define SPIFFS_HAL_READ(_fs, _paddr, _len, _dst) \ + (_fs)->cfg.hal_read_f((_paddr), (_len), (_dst)) +#define SPIFFS_HAL_ERASE(_fs, _paddr, _len) \ + (_fs)->cfg.hal_erase_f((_paddr), (_len)) + +#endif // SPIFFS_HAL_CALLBACK_EXTRA + +#if SPIFFS_CACHE + +#define SPIFFS_CACHE_FLAG_DIRTY (1<<0) +#define SPIFFS_CACHE_FLAG_WRTHRU (1<<1) +#define SPIFFS_CACHE_FLAG_OBJLU (1<<2) +#define SPIFFS_CACHE_FLAG_OBJIX (1<<3) +#define SPIFFS_CACHE_FLAG_DATA (1<<4) +#define SPIFFS_CACHE_FLAG_TYPE_WR (1<<7) + +#define SPIFFS_CACHE_PAGE_SIZE(fs) \ + (sizeof(spiffs_cache_page) + SPIFFS_CFG_LOG_PAGE_SZ(fs)) + +#define spiffs_get_cache(fs) \ + ((spiffs_cache *)((fs)->cache)) + +#define spiffs_get_cache_page_hdr(fs, c, ix) \ + ((spiffs_cache_page *)(&((c)->cpages[(ix) * SPIFFS_CACHE_PAGE_SIZE(fs)]))) + +#define spiffs_get_cache_page(fs, c, ix) \ + ((u8_t *)(&((c)->cpages[(ix) * SPIFFS_CACHE_PAGE_SIZE(fs)])) + sizeof(spiffs_cache_page)) + +// cache page struct +typedef struct { + // cache flags + u8_t flags; + // cache page index + u8_t ix; + // last access of this cache page + u32_t last_access; + union { + // type read cache + struct spix { + // read cache page index + spiffs_page_ix pix; + } spix; +#if SPIFFS_CACHE_WR + // type write cache + struct swrc { + // write cache + spiffs_obj_id obj_id; + // offset in cache page + u32_t offset; + // size of cache page + u16_t size; + } swrc; +#endif + } ucache; +} spiffs_cache_page; + +// cache struct +typedef struct { + u8_t cpage_count; + u32_t last_access; + u32_t cpage_use_map; + u32_t cpage_use_mask; + u8_t *cpages; +} spiffs_cache; + +#endif + + +// spiffs nucleus file descriptor +typedef struct { + // the filesystem of this descriptor + spiffs *fs; + // number of file descriptor - if 0, the file descriptor is closed + spiffs_file file_nbr; + // object id - if SPIFFS_OBJ_ID_ERASED, the file was deleted + spiffs_obj_id obj_id; + // size of the file + u32_t size; + // cached object index header page index + spiffs_page_ix objix_hdr_pix; + // cached offset object index page index + spiffs_page_ix cursor_objix_pix; + // cached offset object index span index + spiffs_span_ix cursor_objix_spix; + // current absolute offset + u32_t offset; + // current file descriptor offset (cached) + u32_t fdoffset; + // fd flags + spiffs_flags flags; +#if SPIFFS_CACHE_WR + spiffs_cache_page *cache_page; +#endif +#if SPIFFS_TEMPORAL_FD_CACHE + // djb2 hash of filename + u32_t name_hash; + // hit score (score == 0 indicates never used fd) + u16_t score; +#endif +#if SPIFFS_IX_MAP + // spiffs index map, if 0 it means unmapped + spiffs_ix_map *ix_map; +#endif +} spiffs_fd; + + +// object structs + +// page header, part of each page except object lookup pages +// NB: this is always aligned when the data page is an object index, +// as in this case struct spiffs_page_object_ix is used +typedef struct SPIFFS_PACKED { + // object id + spiffs_obj_id obj_id; + // object span index + spiffs_span_ix span_ix; + // flags + u8_t flags; +} spiffs_page_header; + +// object index header page header +typedef struct SPIFFS_PACKED +#if SPIFFS_ALIGNED_OBJECT_INDEX_TABLES + __attribute(( aligned(sizeof(spiffs_page_ix)) )) +#endif +{ + // common page header + spiffs_page_header p_hdr; + // alignment + u8_t _align[4 - ((sizeof(spiffs_page_header)&3)==0 ? 4 : (sizeof(spiffs_page_header)&3))]; + // size of object + u32_t size; + // type of object + spiffs_obj_type type; + // name of object + u8_t name[SPIFFS_OBJ_NAME_LEN]; +#if SPIFFS_OBJ_META_LEN + // metadata. not interpreted by SPIFFS in any way. + u8_t meta[SPIFFS_OBJ_META_LEN]; +#endif +} spiffs_page_object_ix_header; + +// object index page header +typedef struct SPIFFS_PACKED { + spiffs_page_header p_hdr; + u8_t _align[4 - ((sizeof(spiffs_page_header)&3)==0 ? 4 : (sizeof(spiffs_page_header)&3))]; +} spiffs_page_object_ix; + +// callback func for object lookup visitor +typedef s32_t (*spiffs_visitor_f)(spiffs *fs, spiffs_obj_id id, spiffs_block_ix bix, int ix_entry, + const void *user_const_p, void *user_var_p); + + +#if SPIFFS_CACHE +#define _spiffs_rd(fs, op, fh, addr, len, dst) \ + spiffs_phys_rd((fs), (op), (fh), (addr), (len), (dst)) +#define _spiffs_wr(fs, op, fh, addr, len, src) \ + spiffs_phys_wr((fs), (op), (fh), (addr), (len), (src)) +#else +#define _spiffs_rd(fs, op, fh, addr, len, dst) \ + spiffs_phys_rd((fs), (addr), (len), (dst)) +#define _spiffs_wr(fs, op, fh, addr, len, src) \ + spiffs_phys_wr((fs), (addr), (len), (src)) +#endif + +#ifndef MIN +#define MIN(a,b) ((a) < (b) ? (a) : (b)) +#endif +#ifndef MAX +#define MAX(a,b) ((a) > (b) ? (a) : (b)) +#endif + +// --------------- + +s32_t spiffs_phys_rd( + spiffs *fs, +#if SPIFFS_CACHE + u8_t op, + spiffs_file fh, +#endif + u32_t addr, + u32_t len, + u8_t *dst); + +s32_t spiffs_phys_wr( + spiffs *fs, +#if SPIFFS_CACHE + u8_t op, + spiffs_file fh, +#endif + u32_t addr, + u32_t len, + u8_t *src); + +s32_t spiffs_phys_cpy( + spiffs *fs, + spiffs_file fh, + u32_t dst, + u32_t src, + u32_t len); + +s32_t spiffs_phys_count_free_blocks( + spiffs *fs); + +s32_t spiffs_obj_lu_find_entry_visitor( + spiffs *fs, + spiffs_block_ix starting_block, + int starting_lu_entry, + u8_t flags, + spiffs_obj_id obj_id, + spiffs_visitor_f v, + const void *user_const_p, + void *user_var_p, + spiffs_block_ix *block_ix, + int *lu_entry); + +s32_t spiffs_erase_block( + spiffs *fs, + spiffs_block_ix bix); + +#if SPIFFS_USE_MAGIC && SPIFFS_USE_MAGIC_LENGTH +s32_t spiffs_probe( + spiffs_config *cfg); +#endif // SPIFFS_USE_MAGIC && SPIFFS_USE_MAGIC_LENGTH + +// --------------- + +s32_t spiffs_obj_lu_scan( + spiffs *fs); + +s32_t spiffs_obj_lu_find_free_obj_id( + spiffs *fs, + spiffs_obj_id *obj_id, + const u8_t *conflicting_name); + +s32_t spiffs_obj_lu_find_free( + spiffs *fs, + spiffs_block_ix starting_block, + int starting_lu_entry, + spiffs_block_ix *block_ix, + int *lu_entry); + +s32_t spiffs_obj_lu_find_id( + spiffs *fs, + spiffs_block_ix starting_block, + int starting_lu_entry, + spiffs_obj_id obj_id, + spiffs_block_ix *block_ix, + int *lu_entry); + +s32_t spiffs_obj_lu_find_id_and_span( + spiffs *fs, + spiffs_obj_id obj_id, + spiffs_span_ix spix, + spiffs_page_ix exclusion_pix, + spiffs_page_ix *pix); + +s32_t spiffs_obj_lu_find_id_and_span_by_phdr( + spiffs *fs, + spiffs_obj_id obj_id, + spiffs_span_ix spix, + spiffs_page_ix exclusion_pix, + spiffs_page_ix *pix); + +// --------------- + +s32_t spiffs_page_allocate_data( + spiffs *fs, + spiffs_obj_id obj_id, + spiffs_page_header *ph, + u8_t *data, + u32_t len, + u32_t page_offs, + u8_t finalize, + spiffs_page_ix *pix); + +s32_t spiffs_page_move( + spiffs *fs, + spiffs_file fh, + u8_t *page_data, + spiffs_obj_id obj_id, + spiffs_page_header *page_hdr, + spiffs_page_ix src_pix, + spiffs_page_ix *dst_pix); + +s32_t spiffs_page_delete( + spiffs *fs, + spiffs_page_ix pix); + +// --------------- + +s32_t spiffs_object_create( + spiffs *fs, + spiffs_obj_id obj_id, + const u8_t name[], + const u8_t meta[], + spiffs_obj_type type, + spiffs_page_ix *objix_hdr_pix); + +s32_t spiffs_object_update_index_hdr( + spiffs *fs, + spiffs_fd *fd, + spiffs_obj_id obj_id, + spiffs_page_ix objix_hdr_pix, + u8_t *new_objix_hdr_data, + const u8_t name[], + const u8_t meta[], + u32_t size, + spiffs_page_ix *new_pix); + +#if SPIFFS_IX_MAP + +s32_t spiffs_populate_ix_map( + spiffs *fs, + spiffs_fd *fd, + u32_t vec_entry_start, + u32_t vec_entry_end); + +#endif + +void spiffs_cb_object_event( + spiffs *fs, + spiffs_page_object_ix *objix, + int ev, + spiffs_obj_id obj_id, + spiffs_span_ix spix, + spiffs_page_ix new_pix, + u32_t new_size); + +s32_t spiffs_object_open_by_id( + spiffs *fs, + spiffs_obj_id obj_id, + spiffs_fd *f, + spiffs_flags flags, + spiffs_mode mode); + +s32_t spiffs_object_open_by_page( + spiffs *fs, + spiffs_page_ix pix, + spiffs_fd *f, + spiffs_flags flags, + spiffs_mode mode); + +s32_t spiffs_object_append( + spiffs_fd *fd, + u32_t offset, + u8_t *data, + u32_t len); + +s32_t spiffs_object_modify( + spiffs_fd *fd, + u32_t offset, + u8_t *data, + u32_t len); + +s32_t spiffs_object_read( + spiffs_fd *fd, + u32_t offset, + u32_t len, + u8_t *dst); + +s32_t spiffs_object_truncate( + spiffs_fd *fd, + u32_t new_len, + u8_t remove_object); + +s32_t spiffs_object_find_object_index_header_by_name( + spiffs *fs, + const u8_t name[SPIFFS_OBJ_NAME_LEN], + spiffs_page_ix *pix); + +// --------------- + +s32_t spiffs_gc_check( + spiffs *fs, + u32_t len); + +s32_t spiffs_gc_erase_page_stats( + spiffs *fs, + spiffs_block_ix bix); + +s32_t spiffs_gc_find_candidate( + spiffs *fs, + spiffs_block_ix **block_candidate, + int *candidate_count, + char fs_crammed); + +s32_t spiffs_gc_clean( + spiffs *fs, + spiffs_block_ix bix); + +s32_t spiffs_gc_quick( + spiffs *fs, u16_t max_free_pages); + +// --------------- + +s32_t spiffs_fd_find_new( + spiffs *fs, + spiffs_fd **fd, + const char *name); + +s32_t spiffs_fd_return( + spiffs *fs, + spiffs_file f); + +s32_t spiffs_fd_get( + spiffs *fs, + spiffs_file f, + spiffs_fd **fd); + +#if SPIFFS_TEMPORAL_FD_CACHE +void spiffs_fd_temporal_cache_rehash( + spiffs *fs, + const char *old_path, + const char *new_path); +#endif + +#if SPIFFS_CACHE +void spiffs_cache_init( + spiffs *fs); + +void spiffs_cache_drop_page( + spiffs *fs, + spiffs_page_ix pix); + +#if SPIFFS_CACHE_WR +spiffs_cache_page *spiffs_cache_page_allocate_by_fd( + spiffs *fs, + spiffs_fd *fd); + +void spiffs_cache_fd_release( + spiffs *fs, + spiffs_cache_page *cp); + +spiffs_cache_page *spiffs_cache_page_get_by_fd( + spiffs *fs, + spiffs_fd *fd); +#endif +#endif + +s32_t spiffs_lookup_consistency_check( + spiffs *fs, + u8_t check_all_objects); + +s32_t spiffs_page_consistency_check( + spiffs *fs); + +s32_t spiffs_object_index_consistency_check( + spiffs *fs); + +// memcpy macro, +// checked in test builds, otherwise plain memcpy (unless already defined) +#ifdef _SPIFFS_TEST +#define _SPIFFS_MEMCPY(__d, __s, __l) do { \ + intptr_t __a1 = (intptr_t)((u8_t*)(__s)); \ + intptr_t __a2 = (intptr_t)((u8_t*)(__s)+(__l)); \ + intptr_t __b1 = (intptr_t)((u8_t*)(__d)); \ + intptr_t __b2 = (intptr_t)((u8_t*)(__d)+(__l)); \ + if (__a1 <= __b2 && __b1 <= __a2) { \ + printf("FATAL OVERLAP: memcpy from %lx..%lx to %lx..%lx\n", __a1, __a2, __b1, __b2); \ + ERREXIT(); \ + } \ + memcpy((__d),(__s),(__l)); \ +} while (0) +#else +#ifndef _SPIFFS_MEMCPY +#define _SPIFFS_MEMCPY(__d, __s, __l) do{memcpy((__d),(__s),(__l));}while(0) +#endif +#endif //_SPIFFS_TEST + +#endif /* SPIFFS_NUCLEUS_H_ */ diff --git a/armsrc/string.c b/armsrc/string.c index 5c154643c..02392ec40 100644 --- a/armsrc/string.c +++ b/armsrc/string.c @@ -106,3 +106,101 @@ void itoa(int n, char s[]) { } //////////////////////////////////////// END 'itoa' CODE + + + +char *strcpy(char *dst, const char *src) + { + char *save = dst; + + for (; (*dst = *src) != '\0'; ++src, ++dst); + return save; + } + +char *strncpy(char *dst, const char *src, size_t n) + { + if (n != 0) { + char *d = dst; + const char *s = src; + + do { + if ((*d++ = *s++) == 0) { + /* NUL pad the remaining n-1 bytes */ + while (--n) { + *d++ = 0; + } + break; + } + } while (--n); + } + return dst; + } + +int strcmp(const char *s1, const char *s2) +{ + while (*s1 == *s2++) { + if (*s1++ == 0) { + return (0); + } + } + return (*(unsigned char *) s1 - *(unsigned char *) --s2); +} + +char* __strtok_r(char*, const char*, char**); + +char* __strtok_r(char* s, const char* delim, char** last) +{ + char *spanp, *tok; + int c, sc; + + if(s == NULL && (s = *last) == NULL) + return (NULL); + +/* + * Skip (span) leading delimiters (s += strspn(s, delim), sort of). + */ +cont: + c = *s++; + for(spanp = (char*)delim; (sc = *spanp++) != 0;) + { + if(c == sc) + goto cont; + } + + if(c == 0) + { /* no non-delimiter characters */ + *last = NULL; + return (NULL); + } + tok = s - 1; + + /* + * Scan token (scan for delimiters: s += strcspn(s, delim), sort of). + * Note that delim must have one NUL; we stop if we see that, too. + */ + for(;;) + { + c = *s++; + spanp = (char*)delim; + do + { + if((sc = *spanp++) == c) + { + if(c == 0) + s = NULL; + else + s[-1] = '\0'; + *last = s; + return (tok); + } + } while(sc != 0); + } + /* NOTREACHED */ +} + +char* strtok(char* s, const char* delim) +{ + static char* last; + + return (__strtok_r(s, delim, &last)); +} diff --git a/armsrc/string.h b/armsrc/string.h index f6f094c48..9a899cfc7 100644 --- a/armsrc/string.h +++ b/armsrc/string.h @@ -23,5 +23,9 @@ char *strncat(char *dest, const char *src, unsigned int n); char *strcat(char *dest, const char *src); void strreverse(char s[]); void itoa(int n, char s[]); +char *strcpy(char *dst, const char *src); +char* strncpy(char* destination, const char* source, size_t num); +int strcmp(const char *s1, const char *s2); +char* strtok(char* s, const char* delim); #endif /* __STRING_H */ diff --git a/client/Makefile b/client/Makefile index a1109a497..440f2b888 100644 --- a/client/Makefile +++ b/client/Makefile @@ -227,6 +227,7 @@ CMDSRCS = crapto1/crapto1.c \ cmdlfvisa2000.c \ cmdtrace.c \ cmdflashmem.c \ + cmdflashmemspiffs.c \ cmdsmartcard.c \ cmdusart.c \ cmdparser.c \ diff --git a/client/cmddata.c b/client/cmddata.c index ba6790c93..8a220a39d 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -865,7 +865,7 @@ static int CmdBitsamples(const char *Cmd) { int cnt = 0; uint8_t got[12288]; - if (!GetFromDevice(BIG_BUF, got, sizeof(got), 0, NULL, 2500, false)) { + if (!GetFromDevice(BIG_BUF, got, sizeof(got), 0,NULL,0, NULL, 2500, false)) { PrintAndLogEx(WARNING, "command execution time out"); return PM3_ETIMEOUT; } @@ -1397,7 +1397,7 @@ static int CmdHexsamples(const char *Cmd) { return PM3_EINVARG; } - if (!GetFromDevice(BIG_BUF, got, requested, offset, NULL, 2500, false)) { + if (!GetFromDevice(BIG_BUF, got, requested, offset,NULL,0, NULL, 2500, false)) { PrintAndLogEx(WARNING, "command execution time out"); return PM3_ESOFT; } @@ -1470,7 +1470,7 @@ int getSamples(uint32_t n, bool silent) { if (!silent) PrintAndLogEx(NORMAL, "Reading %d bytes from device memory\n", n); PacketResponseNG response; - if (!GetFromDevice(BIG_BUF, got, n, 0, &response, 10000, true)) { + if (!GetFromDevice(BIG_BUF, got, n, 0,NULL,0, &response, 10000, true)) { PrintAndLogEx(WARNING, "timeout while waiting for reply."); return PM3_ETIMEOUT; } diff --git a/client/cmdflashmem.c b/client/cmdflashmem.c index 9546b421f..a3a957552 100644 --- a/client/cmdflashmem.c +++ b/client/cmdflashmem.c @@ -315,7 +315,7 @@ static int CmdFlashMemDump(const char *Cmd) { } PrintAndLogEx(INFO, "downloading "_YELLOW_("%u")"bytes from flashmem", len); - if (!GetFromDevice(FLASH_MEM, dump, len, start_index, NULL, -1, true)) { + if (!GetFromDevice(FLASH_MEM, dump, len, start_index,NULL,0, NULL, -1, true)) { PrintAndLogEx(FAILED, "ERROR; downloading from flashmemory"); free(dump); return PM3_EFLASH; @@ -574,6 +574,7 @@ static int CmdFlashMemInfo(const char *Cmd) { static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, + {"spiffs", CmdFlashMemSpiFFS, IfPm3Flash, "High level SPI FileSystem Flash manipulation [rdv40]"}, {"spibaud", CmdFlashmemSpiBaudrate, IfPm3Flash, "Set Flash memory Spi baudrate [rdv40]"}, {"info", CmdFlashMemInfo, IfPm3Flash, "Flash memory information [rdv40]"}, {"load", CmdFlashMemLoad, IfPm3Flash, "Load data into flash memory [rdv40]"}, diff --git a/client/cmdflashmem.h b/client/cmdflashmem.h index 790d42a5d..b08164837 100644 --- a/client/cmdflashmem.h +++ b/client/cmdflashmem.h @@ -24,6 +24,7 @@ #include "util_posix.h" // msclock #include "loclass/fileutils.h" //saveFile #include "comms.h" //getfromdevice +#include "cmdflashmemspiffs.h" // spiffs commands typedef enum { DICTIONARY_NONE = 0, diff --git a/client/cmdflashmemspiffs.c b/client/cmdflashmemspiffs.c new file mode 100644 index 000000000..c6ae55211 --- /dev/null +++ b/client/cmdflashmemspiffs.c @@ -0,0 +1,457 @@ +//----------------------------------------------------------------------------- +// Copyright (C) 2018 iceman +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// Proxmark3 RDV40 Flash memory commands +//----------------------------------------------------------------------------- +#include "cmdflashmemspiffs.h" + +#include "mbedtls/base64.h" +#include "mbedtls/rsa.h" +#include "mbedtls/sha1.h" + +static int CmdHelp(const char *Cmd); + +static int CmdFlashMemSpiFFSMount(const char *Cmd) { + (void)Cmd; // Cmd is not used so far + clearCommandBuffer(); + SendCommandNG(CMD_SPIFFS_MOUNT, NULL, 0); + return PM3_SUCCESS; +} + +static int CmdFlashMemSpiFFSUnmount(const char *Cmd) { + (void)Cmd; // Cmd is not used so far + clearCommandBuffer(); + SendCommandNG(CMD_SPIFFS_UNMOUNT, NULL, 0); + return PM3_SUCCESS; +} + +static int CmdFlashMemSpiFFSTest(const char *Cmd) { + (void)Cmd; // Cmd is not used so far + clearCommandBuffer(); + SendCommandNG(CMD_SPIFFS_TEST, NULL, 0); + return PM3_SUCCESS; +} + +static int CmdFlashMemSpiFFSTree(const char *Cmd) { + (void)Cmd; // Cmd is not used so far + clearCommandBuffer(); + SendCommandNG(CMD_SPIFFS_PRINT_TREE, NULL, 0); + return PM3_SUCCESS; +} + +static int CmdFlashMemSpiFFSInfo(const char *Cmd) { + (void)Cmd; // Cmd is not used so far + clearCommandBuffer(); + SendCommandNG(CMD_SPIFFS_PRINT_FSINFO, NULL, 0); + return PM3_SUCCESS; +} + +static int usage_flashmemspiffs_remove(void) { + PrintAndLogEx(NORMAL, "Remove a file from spiffs filesystem"); + PrintAndLogEx(NORMAL, " Usage: mem spiffs remove "); + return PM3_SUCCESS; +} + +static int usage_flashmemspiffs_rename(void) { + PrintAndLogEx(NORMAL, "Rename/move a file in spiffs filesystem"); + PrintAndLogEx(NORMAL, " Usage: mem spiffs rename "); + return PM3_SUCCESS; +} + +static int usage_flashmemspiffs_copy(void) { + PrintAndLogEx(NORMAL, "Copy a file to another (destructively) in spiffs filesystem"); + PrintAndLogEx(NORMAL, " Usage: mem spiffs copy "); + return PM3_SUCCESS; +} + +static int usage_flashmemspiffs_dump(void) { + PrintAndLogEx(NORMAL, "Dumps flash memory on device into a file or in console"); + PrintAndLogEx(NORMAL, "Size is handled by first sending a STAT command against file existence"); + PrintAndLogEx(NORMAL, " Usage: mem spiffs dump o [f [e]] [p]"); + PrintAndLogEx(NORMAL, " o : filename in SPIFFS"); + PrintAndLogEx(NORMAL, " f : file name to save to"); + PrintAndLogEx(NORMAL, " p : print dump in console"); + PrintAndLogEx(NORMAL, " e : also save in EML format (good for tags save and dictonnary files)"); + PrintAndLogEx(NORMAL, " You must specify at lease option f or option p, both if you wish"); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Examples:"); + PrintAndLogEx(NORMAL, " mem spiffs dump o hf_colin/lasttag f lasttag e"); + PrintAndLogEx(NORMAL, " mem spiffs dump o hf_colin/lasttag p"); + return PM3_SUCCESS; +} + +static int usage_flashmemspiffs_load(void) { + PrintAndLogEx(NORMAL, "Uploads binary-wise file into device filesystem"); + PrintAndLogEx(NORMAL, "Usage: mem spiffs load o f "); + PrintAndLogEx(NORMAL, "Warning: mem area to be written must have been wiped first"); + PrintAndLogEx(NORMAL, "(this is already taken care when loading dictionaries)"); + PrintAndLogEx(NORMAL, " o : destination filename"); + PrintAndLogEx(NORMAL, " f : local filename"); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Examples:"); + PrintAndLogEx(NORMAL, " mem spiffs load f myfile o myapp.conf"); + return PM3_SUCCESS; +} + +static int CmdFlashMemSpiFFSRemove(const char *Cmd) { + + char filename[32] = {0}; + bool errors = false; + + /*char ctmp = tolower(param_getchar(Cmd, 0)); + if (strlen(Cmd) < 1 || ctmp == 'h') { + return usage_flashmemspiffs_remove(); + }*/ + + if (param_getstr(Cmd, 0, filename, 32) >= 32) { + PrintAndLogEx(FAILED, "Filename too long"); + errors = true; + } + + // check null filename ? + if (errors) { + usage_flashmemspiffs_remove(); + return PM3_EINVARG; + } + + SendCommandMIX(CMD_SPIFFS_REMOVE, 0, 0, 0, (uint8_t *)filename, 32); + return PM3_SUCCESS; +} + +static int CmdFlashMemSpiFFSRename(const char *Cmd) { + + char srcfilename[32] = {0}; + char destfilename[32] = {0}; + bool errors = false; + + /*char ctmp = tolower(param_getchar(Cmd, 0)); + if (strlen(Cmd) < 1 || ctmp == 'h') { + return usage_flashmemspiffs_rename(); + }*/ + + if (param_getstr(Cmd, 0, srcfilename, 32) >= 32) { + PrintAndLogEx(FAILED, "Source Filename too long"); + errors = true; + } + if (srcfilename[0] == '\0') { + PrintAndLogEx(FAILED, "Source Filename missing or invalid"); + errors = true; + } + + if (param_getstr(Cmd, 1, destfilename, 32) >= 32) { + PrintAndLogEx(FAILED, "Source Filename too long"); + errors = true; + } + if (destfilename[0] == '\0') { + PrintAndLogEx(FAILED, "Source Filename missing or invalid"); + errors = true; + } + + // check null filename ? + if (errors) { + usage_flashmemspiffs_rename(); + return PM3_EINVARG; + } + + char data[65]; + sprintf(data, "%s,%s", srcfilename, destfilename); + SendCommandMIX(CMD_SPIFFS_RENAME, 0, 0, 0, (uint8_t *)data, 65); + return PM3_SUCCESS; +} + +static int CmdFlashMemSpiFFSCopy(const char *Cmd) { + + char srcfilename[32] = {0}; + char destfilename[32] = {0}; + bool errors = false; + + /*char ctmp = tolower(param_getchar(Cmd, 0)); + if (strlen(Cmd) < 1 || ctmp == 'h') { + return usage_flashmemspiffs_copy(); + }*/ + + if (param_getstr(Cmd, 0, srcfilename, 32) >= 32) { + PrintAndLogEx(FAILED, "Source Filename too long"); + errors = true; + } + if (srcfilename[0] == '\0') { + PrintAndLogEx(FAILED, "Source Filename missing or invalid"); + errors = true; + } + + if (param_getstr(Cmd, 1, destfilename, 32) >= 32) { + PrintAndLogEx(FAILED, "Source Filename too long"); + errors = true; + } + if (destfilename[0] == '\0') { + PrintAndLogEx(FAILED, "Source Filename missing or invalid"); + errors = true; + } + + // check null filename ? + if (errors) { + usage_flashmemspiffs_copy(); + return PM3_EINVARG; + } + + char data[65]; + sprintf(data, "%s,%s", srcfilename, destfilename); + SendCommandMIX(CMD_SPIFFS_COPY, 0, 0, 0, (uint8_t *)data, 65); + return PM3_SUCCESS; +} + +static int CmdFlashMemSpiFFSDump(const char *Cmd) { + + char filename[FILE_PATH_SIZE] = {0}; + uint8_t cmdp = 0; + bool errors = false; + bool print = false; + uint32_t start_index = 0, len = FLASH_MEM_MAX_SIZE; + char destfilename[32] = {0}; + bool eml = false; + + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { + case 'h': + return usage_flashmemspiffs_dump(); + /*case 'l': + len = param_get32ex(Cmd, cmdp + 1, FLASH_MEM_MAX_SIZE, 10); + cmdp += 2; + break;*/ + case 'o': + param_getstr(Cmd, cmdp + 1, destfilename, 32); + cmdp += 2; + break; + case 'p': + print = true; + cmdp += 1; + break; + case 'e': + eml = true; + cmdp += 1; + break; + case 'f': + // File handling + if (param_getstr(Cmd, cmdp + 1, filename, FILE_PATH_SIZE) >= FILE_PATH_SIZE) { + PrintAndLogEx(FAILED, "Filename too long"); + errors = true; + break; + } + cmdp += 2; + break; + default: + PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } + } + + if ((filename[0] == '\0') && (!print)) { + PrintAndLogEx(FAILED, "No print asked and Local dump Filename missing or invalid"); + errors = true; + } + + if (destfilenamse[0] == '\0') { + PrintAndLogEx(FAILED, "SPIFFS Filename missing or invalid"); + errors = true; + } + + // Validations + if (errors || cmdp == 0) { + usage_flashmemspiffs_dump(); + return PM3_EINVARG; + } + + // get size from spiffs itself ! + SendCommandMIX(CMD_SPIFFS_STAT, 0, 0, 0, (uint8_t *)destfilename, 32); + PacketResponseNG resp; + if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { + PrintAndLogEx(WARNING, "timeout while waiting for reply."); + return PM3_ETIMEOUT; + } + + len = resp.oldarg[0]; + + uint8_t *dump = calloc(len, sizeof(uint8_t)); + if (!dump) { + PrintAndLogDevice(ERR, "error, cannot allocate memory "); + return PM3_EMALLOC; + } + + PrintAndLogEx(INFO, "downloading "_YELLOW_("%u") "bytes from spiffs (flashmem)", len); + if (!GetFromDevice(SPIFFS, dump, len, start_index, (uint8_t *)destfilename, 32, NULL, -1, true)) { + PrintAndLogEx(FAILED, "ERROR; downloading from spiffs(flashmemory)"); + free(dump); + return PM3_EFLASH; + } + + if (print) { + print_hex_break(dump, len, 32); + } + + if (filename[0] != '\0') { + saveFile(filename, "", dump, len); + if (eml) { + saveFileEML(filename, dump, len, 16); + } + } + + free(dump); + return PM3_SUCCESS; +} + +static int CmdFlashMemSpiFFSLoad(const char *Cmd) { + + uint32_t append = 0; + char filename[FILE_PATH_SIZE] = {0}; + char destfilename[32] = {0}; + bool errors = false; + uint8_t cmdp = 0; + + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { + case 'h': + return usage_flashmemspiffs_load(); + case 'f': + if (param_getstr(Cmd, cmdp + 1, filename, FILE_PATH_SIZE) >= FILE_PATH_SIZE) { + PrintAndLogEx(FAILED, "Filename too long"); + errors = true; + break; + } + cmdp += 2; + break; + case 'o': + param_getstr(Cmd, cmdp + 1, destfilename, 32); + cmdp += 2; + break; + default: + PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } + } + + if (destfilename[0] == '\0') { + PrintAndLogEx(FAILED, "Destination Filename missing or invalid"); + errors = true; + } + + // Validations + if (errors || cmdp == 0) { + usage_flashmemspiffs_load(); + return PM3_EINVARG; + } + + size_t datalen = 0; + int res = 0; + uint8_t *data = calloc(FLASH_MEM_MAX_SIZE, sizeof(uint8_t)); + + res = loadFile(filename, "", data, FLASH_MEM_MAX_SIZE, &datalen); + // int res = loadFileEML( filename, data, &datalen); + if (res) { + free(data); + return PM3_EFILE; + } + + if (datalen > FLASH_MEM_MAX_SIZE) { + PrintAndLogDevice(ERR, "error, filesize is larger than available memory"); + free(data); + return PM3_EOVFLOW; + } + + uint8_t *newdata = realloc(data, datalen); + if (newdata == NULL) { + free(data); + return PM3_EMALLOC; + } else { + data = newdata; + } + + // We want to mount before multiple operation so the lazy writes/append will not + // trigger a mount + umount each loop iteration (lazy ops device side) + SendCommandNG(CMD_SPIFFS_MOUNT, NULL, 0); + + // Send to device + uint32_t bytes_sent = 0; + uint32_t bytes_remaining = datalen; + + // fast push mode + conn.block_after_ACK = true; + + // SendCommandMIX(CMD_SPIFFS_COPY, 0, 0, 0, (uint8_t *)data, 65); + + while (bytes_remaining > 0) { + uint32_t bytes_in_packet = MIN(FLASH_MEM_BLOCK_SIZE, bytes_remaining); + + clearCommandBuffer(); + + char fdata[32 + bytes_in_packet]; + memset(fdata, 0, sizeof(fdata)); + memcpy(fdata, destfilename, 32); + memcpy(fdata + 32, data + bytes_sent, bytes_in_packet); + // sprintf(fdata, "%s%s", destfilename, data + bytes_sent); + + if (bytes_sent > 0) + append = 1; + + SendCommandOLD(CMD_SPIFFS_WRITE, append, bytes_in_packet, 0, fdata, 32 + bytes_in_packet); + + bytes_remaining -= bytes_in_packet; + bytes_sent += bytes_in_packet; + + PacketResponseNG resp; + if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { + PrintAndLogEx(WARNING, "timeout while waiting for reply."); + conn.block_after_ACK = false; + free(data); + return PM3_ETIMEOUT; + } + + uint8_t isok = resp.oldarg[0] & 0xFF; + if (!isok) { + conn.block_after_ACK = false; + PrintAndLogEx(FAILED, "Flash write fail [offset %u]", bytes_sent); + return PM3_EFLASH; + } + } + + conn.block_after_ACK = false; + free(data); + PrintAndLogEx(SUCCESS, "Wrote "_GREEN_("%u") "bytes to file "_GREEN_("%s"), datalen, destfilename); + + // We want to unmount after these to set things back to normal but more than this + // unmouting ensure that SPIFFS CACHES are all flushed so our file is actually written on memory + SendCommandNG(CMD_SPIFFS_UNMOUNT, NULL, 0); + return PM3_SUCCESS; +} + +static command_t CommandTable[] = { + + {"help", CmdHelp, AlwaysAvailable, "This help"}, + {"copy", CmdFlashMemSpiFFSCopy, IfPm3Flash, + "Copy a file to another (destructively) in SPIFFS FileSystem in FlashMEM (spiffs)"}, + {"dump", CmdFlashMemSpiFFSDump, IfPm3Flash, "Dump a file from SPIFFS FileSystem in FlashMEM (spiffs)"}, + {"info", CmdFlashMemSpiFFSInfo, IfPm3Flash, "Print filesystem info and usage statistics (spiffs)"}, + {"load", CmdFlashMemSpiFFSLoad, IfPm3Flash, "Upload file into SPIFFS Filesystem (spiffs)"}, + {"mount", CmdFlashMemSpiFFSMount, IfPm3Flash, "Mount the SPIFFS Filesystem if not already mounted (spiffs)"}, + {"remove", CmdFlashMemSpiFFSRemove, IfPm3Flash, "Remove a file from SPIFFS FileSystem in FlashMEM (spiffs)"}, + {"rename", CmdFlashMemSpiFFSRename, IfPm3Flash, "Rename/move a file in SPIFFS FileSystem in FlashMEM (spiffs)"}, + {"test", CmdFlashMemSpiFFSTest, IfPm3Flash, "Test SPIFFS Functionning (require wiping pages 0 and 1)"}, + {"tree", CmdFlashMemSpiFFSTree, IfPm3Flash, "Print the Flash Memory FileSystem Tree (spiffs)"}, + {"unmount", CmdFlashMemSpiFFSUnmount, IfPm3Flash, "Un-mount the SPIFFS Filesystem if not already mounted (spiffs)"}, + {NULL, NULL, NULL, NULL}}; + +static int CmdHelp(const char *Cmd) { + (void)Cmd; // Cmd is not used so far + CmdsHelp(CommandTable); + return PM3_SUCCESS; +} + +int CmdFlashMemSpiFFS(const char *Cmd) { + clearCommandBuffer(); + return CmdsParse(CommandTable, Cmd); +} diff --git a/client/cmdflashmemspiffs.h b/client/cmdflashmemspiffs.h new file mode 100644 index 000000000..b3589ce86 --- /dev/null +++ b/client/cmdflashmemspiffs.h @@ -0,0 +1,30 @@ +//----------------------------------------------------------------------------- +// Copyright (C) 2018 iceman +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// Proxmark3 RDV40 Flash memory commands +//----------------------------------------------------------------------------- + +#ifndef CMDFLASHMEMSPIFFS_H__ +#define CMDFLASHMEMSPIFFS_H__ + +#include +#include +#include +#include +#include "pmflash.h" +#include "common.h" +#include "proxmark3.h" +#include "ui.h" +#include "cmdparser.h" +#include "util.h" +#include "util_posix.h" // msclock +#include "loclass/fileutils.h" //saveFile +#include "comms.h" //getfromdevice + +int CmdFlashMemSpiFFS(const char *Cmd); + +#endif diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index 91d171149..3e6001ee1 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -383,7 +383,7 @@ static int CmdHFFelicaDumpLite(const char *Cmd) { return 1; } - if (!GetFromDevice(BIG_BUF, trace, tracelen, 0, NULL, 2500, false)) { + if (!GetFromDevice(BIG_BUF, trace, tracelen, 0,NULL,0, NULL, 2500, false)) { PrintAndLogEx(WARNING, "command execution time out"); free(trace); return 0; diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index f8d57556f..96b9a0ee5 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -990,7 +990,7 @@ static int CmdHFiClassReader_Dump(const char *Cmd) { } // response ok - now get bigbuf content of the dump - if (!GetFromDevice(BIG_BUF, tag_data + (blockno * 8), blocksRead * 8, startindex, NULL, 2500, false)) { + if (!GetFromDevice(BIG_BUF, tag_data + (blockno * 8), blocksRead * 8, startindex,NULL,0, NULL, 2500, false)) { PrintAndLogEx(WARNING, "command execution time out"); return 0; } @@ -1033,7 +1033,7 @@ static int CmdHFiClassReader_Dump(const char *Cmd) { blocksRead = (sizeof(tag_data) - gotBytes) / 8; } // get dumped data from bigbuf - if (!GetFromDevice(BIG_BUF, tag_data + gotBytes, blocksRead * 8, startindex, NULL, 2500, false)) { + if (!GetFromDevice(BIG_BUF, tag_data + gotBytes, blocksRead * 8, startindex,NULL,0, NULL, 2500, false)) { PrintAndLogEx(WARNING, "command execution time out"); return 0; } diff --git a/client/cmdhflegic.c b/client/cmdhflegic.c index 03c5ecfcd..031f5c95a 100644 --- a/client/cmdhflegic.c +++ b/client/cmdhflegic.c @@ -781,7 +781,7 @@ int legic_read_mem(uint32_t offset, uint32_t len, uint32_t iv, uint8_t *out, uin PrintAndLogEx(WARNING, "Fail, only managed to read %u bytes", *outlen); // copy data from device - if (!GetFromDevice(BIG_BUF_EML, out, *outlen, 0, NULL, 2500, false)) { + if (!GetFromDevice(BIG_BUF_EML, out, *outlen, 0,NULL,0, NULL, 2500, false)) { PrintAndLogEx(WARNING, "Fail, transfer from device time-out"); return 4; } @@ -930,7 +930,7 @@ static int CmdLegicDump(const char *Cmd) { PrintAndLogEx(WARNING, "Fail, only managed to read 0x%02X bytes of 0x%02X", readlen, dumplen); // copy data from device - if (!GetFromDevice(BIG_BUF_EML, data, readlen, 0, NULL, 2500, false)) { + if (!GetFromDevice(BIG_BUF_EML, data, readlen, 0,NULL,0, NULL, 2500, false)) { PrintAndLogEx(WARNING, "Fail, transfer from device time-out"); free(data); return 4; @@ -1200,7 +1200,7 @@ static int CmdLegicESave(const char *Cmd) { // download emulator memory PrintAndLogEx(SUCCESS, "Reading emulator memory..."); - if (!GetFromDevice(BIG_BUF_EML, data, numofbytes, 0, NULL, 2500, false)) { + if (!GetFromDevice(BIG_BUF_EML, data, numofbytes, 0,NULL,0, NULL, 2500, false)) { PrintAndLogEx(WARNING, "Fail, transfer from device time-out"); free(data); return 4; diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index e75224cd2..c227b1a83 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -2693,7 +2693,7 @@ static int CmdHF14AMfESave(const char *Cmd) { memset(dump, 0, bytes); PrintAndLogEx(INFO, "downloading from emulator memory"); - if (!GetFromDevice(BIG_BUF_EML, dump, bytes, 0, NULL, 2500, false)) { + if (!GetFromDevice(BIG_BUF_EML, dump, bytes, 0,NULL,0, NULL, 2500, false)) { PrintAndLogEx(WARNING, "Fail, transfer from device time-out"); free(dump); return PM3_ETIMEOUT; diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index 91e223427..935c178f2 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -1931,7 +1931,7 @@ static int CmdHF14AMfUDump(const char *Cmd) { bufferSize = sizeof(data); } - if (!GetFromDevice(BIG_BUF, data, bufferSize, startindex, NULL, 2500, false)) { + if (!GetFromDevice(BIG_BUF, data, bufferSize, startindex,NULL,0, NULL, 2500, false)) { PrintAndLogEx(WARNING, "command execution time out"); return 1; } diff --git a/client/cmdlfcotag.c b/client/cmdlfcotag.c index 0f5e7a835..fa6ff01a8 100644 --- a/client/cmdlfcotag.c +++ b/client/cmdlfcotag.c @@ -91,7 +91,7 @@ static int CmdCOTAGRead(const char *Cmd) { } case 1: { - if (!GetFromDevice(BIG_BUF, DemodBuffer, COTAG_BITS, 0, NULL, 1000, false)) { + if (!GetFromDevice(BIG_BUF, DemodBuffer, COTAG_BITS, 0,NULL,0, NULL, 1000, false)) { PrintAndLogEx(WARNING, "timeout while waiting for reply."); return PM3_ETIMEOUT; } diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c index aaf8c0db4..b594eb4bc 100644 --- a/client/cmdlfem4x.c +++ b/client/cmdlfem4x.c @@ -986,7 +986,7 @@ static bool downloadSamplesEM() { // 8 bit preamble + 32 bit word response (max clock (128) * 40bits = 5120 samples) uint8_t got[6000]; - if (!GetFromDevice(BIG_BUF, got, sizeof(got), 0, NULL, 2500, false)) { + if (!GetFromDevice(BIG_BUF, got, sizeof(got), 0,NULL,0, NULL, 2500, false)) { PrintAndLogEx(WARNING, "command execution time out"); return false; } diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 9a23e660b..1af8defe4 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -1804,7 +1804,7 @@ static int CmdResetRead(const char *Cmd) { } uint8_t got[BIGBUF_SIZE - 1]; - if (!GetFromDevice(BIG_BUF, got, sizeof(got), 0, NULL, 2500, false)) { + if (!GetFromDevice(BIG_BUF, got, sizeof(got), 0,NULL,0, NULL, 2500, false)) { PrintAndLogEx(WARNING, "command execution time out"); return PM3_ETIMEOUT; } diff --git a/client/cmdtrace.c b/client/cmdtrace.c index 914bf06d6..e9a609184 100644 --- a/client/cmdtrace.c +++ b/client/cmdtrace.c @@ -759,7 +759,7 @@ int CmdTraceList(const char *Cmd) { if (isOnline) { // Query for the size of the trace, downloading PM3_CMD_DATA_SIZE PacketResponseNG response; - if (!GetFromDevice(BIG_BUF, trace, PM3_CMD_DATA_SIZE, 0, &response, 4000, true)) { + if (!GetFromDevice(BIG_BUF, trace, PM3_CMD_DATA_SIZE, 0,NULL,0, &response, 4000, true)) { PrintAndLogEx(WARNING, "timeout while waiting for reply."); return 1; } @@ -773,7 +773,7 @@ int CmdTraceList(const char *Cmd) { return 2; } trace = p; - if (!GetFromDevice(BIG_BUF, trace, traceLen, 0, NULL, 2500, false)) { + if (!GetFromDevice(BIG_BUF, trace, traceLen, 0,NULL,0, NULL, 2500, false)) { PrintAndLogEx(WARNING, "command execution time out"); free(trace); return 3; diff --git a/client/comms.c b/client/comms.c index 304948a4d..45771c60d 100644 --- a/client/comms.c +++ b/client/comms.c @@ -739,7 +739,7 @@ bool WaitForResponse(uint32_t cmd, PacketResponseNG *response) { * @param show_warning display message after 2 seconds * @return true if command was returned, otherwise false */ -bool GetFromDevice(DeviceMemType_t memtype, uint8_t *dest, uint32_t bytes, uint32_t start_index, PacketResponseNG *response, size_t ms_timeout, bool show_warning) { +bool GetFromDevice(DeviceMemType_t memtype, uint8_t *dest, uint32_t bytes, uint32_t start_index, uint8_t *data, uint32_t datalen, PacketResponseNG *response, size_t ms_timeout, bool show_warning) { if (dest == NULL) return false; if (bytes == 0) return true; @@ -760,6 +760,10 @@ bool GetFromDevice(DeviceMemType_t memtype, uint8_t *dest, uint32_t bytes, uint3 SendCommandMIX(CMD_DOWNLOAD_EML_BIGBUF, start_index, bytes, 0, NULL, 0); return dl_it(dest, bytes, start_index, response, ms_timeout, show_warning, CMD_DOWNLOADED_EML_BIGBUF); } + case SPIFFS: { + SendCommandMIX(CMD_SPIFFS_DOWNLOAD, start_index, bytes, 0, data, datalen); + return dl_it(dest, bytes, start_index, response, ms_timeout, show_warning, CMD_SPIFFS_DOWNLOADED); + } case FLASH_MEM: { SendCommandMIX(CMD_FLASHMEM_DOWNLOAD, start_index, bytes, 0, NULL, 0); return dl_it(dest, bytes, start_index, response, ms_timeout, show_warning, CMD_FLASHMEM_DOWNLOADED); diff --git a/client/comms.h b/client/comms.h index 6ec14331d..bc036f008 100644 --- a/client/comms.h +++ b/client/comms.h @@ -37,6 +37,7 @@ typedef enum { BIG_BUF_EML, FLASH_MEM, SIM_MEM, + SPIFFS } DeviceMemType_t; typedef struct { @@ -72,7 +73,8 @@ bool WaitForResponseTimeoutW(uint32_t cmd, PacketResponseNG *response, size_t ms bool WaitForResponseTimeout(uint32_t cmd, PacketResponseNG *response, size_t ms_timeout); bool WaitForResponse(uint32_t cmd, PacketResponseNG *response); -bool GetFromDevice(DeviceMemType_t memtype, uint8_t *dest, uint32_t bytes, uint32_t start_index, PacketResponseNG *response, size_t ms_timeout, bool show_warning); +//bool GetFromDevice(DeviceMemType_t memtype, uint8_t *dest, uint32_t bytes, uint32_t start_index, PacketResponseNG *response, size_t ms_timeout, bool show_warning); +bool GetFromDevice(DeviceMemType_t memtype, uint8_t *dest, uint32_t bytes, uint32_t start_index, uint8_t *data, uint32_t datalen, PacketResponseNG *response, size_t ms_timeout, bool show_warning); #endif diff --git a/client/scripting.c b/client/scripting.c index 572899e2d..9e735b0db 100644 --- a/client/scripting.c +++ b/client/scripting.c @@ -223,7 +223,7 @@ static int l_GetFromBigBuf(lua_State *L) { return returnToLuaWithError(L, "Allocating memory failed"); } - if (!GetFromDevice(BIG_BUF, data, len, startindex, NULL, 2500, false)) { + if (!GetFromDevice(BIG_BUF, data, len, startindex,NULL,0, NULL, 2500, false)) { free(data); return returnToLuaWithError(L, "command execution time out"); } @@ -263,7 +263,7 @@ static int l_GetFromFlashMem(lua_State *L) { if (!data) return returnToLuaWithError(L, "Allocating memory failed"); - if (!GetFromDevice(FLASH_MEM, data, len, startindex, NULL, -1, false)) { + if (!GetFromDevice(FLASH_MEM, data, len, startindex,NULL,0, NULL, -1, false)) { free(data); return returnToLuaWithError(L, "command execution time out"); } diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 39edb2b61..99a858ff0 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -238,6 +238,40 @@ typedef struct { #define CMD_FLASHMEM_INFO 0x0125 #define CMD_FLASHMEM_SET_SPIBAUDRATE 0x0126 +// RDV40, High level flashmem SPIFFS Manipulation +// ALL function will have a lazy or Safe version +// that will be handled as argument of safety level [0..2] respectiveley normal / lazy / safe +// However as how design is, MOUNT and UNMOUNT only need/have lazy as safest level so a safe level will still execute a lazy version +// see spiffs.c for more about the normal/lazy/safety information) +#define CMD_SPIFFS_MOUNT 0x0130 +#define CMD_SPIFFS_UNMOUNT 0x0131 +#define CMD_SPIFFS_WRITE 0x0132 +// We take +0x1000 when having a variant of similar function (todo : make it an argument!) +#define CMD_SPIFFS_APPEND 0x1132 + +#define CMD_SPIFFS_READ 0x0133 +//We use no open/close instruvtion, as they are handled internally. +#define CMD_SPIFFS_REMOVE 0x0134 +#define CMD_SPIFFS_RM CMD_SPIFFS_REMOVE +#define CMD_SPIFFS_RENAME 0x0135 +#define CMD_SPIFFS_MV CMD_SPIFFS_RENAME +#define CMD_SPIFFS_COPY 0x0136 +#define CMD_SPIFFS_CP CMD_SPIFFS_COPY +#define CMD_SPIFFS_STAT 0x0137 +#define CMD_SPIFFS_FSTAT 0x0138 +#define CMD_SPIFFS_INFO 0x0139 +#define CMD_SPIFFS_FORMAT CMD_FLASHMEM_WIPE +// This take a +0x2000 as they are high level helper and special functions +// As the others, they may have safety level argument if it makkes sense +#define CMD_SPIFFS_PRINT_TREE 0x2130 +#define CMD_SPIFFS_GET_TREE 0x2131 +#define CMD_SPIFFS_TEST 0x2132 +#define CMD_SPIFFS_PRINT_FSINFO 0x2133 +#define CMD_SPIFFS_DOWNLOAD 0x2134 +#define CMD_SPIFFS_DOWNLOADED 0x2135 +// more ? + + // RDV40, Smart card operations #define CMD_SMART_RAW 0x0140 #define CMD_SMART_UPGRADE 0x0141 From 4e0e69ed631eb05543fe91b2bbf3339879d10c8e Mon Sep 17 00:00:00 2001 From: mwalker33 Date: Tue, 23 Jul 2019 09:50:28 +1000 Subject: [PATCH 0132/1854] Added T55 downlink mode support --- CHANGELOG.md | 1 + armsrc/appmain.c | 17 +- armsrc/apps.h | 11 +- armsrc/lfops.c | 674 ++++++++++++++++++++++++++++++------------- client/cmdlft55xx.c | 684 +++++++++++++++++++++++++++++++------------- client/cmdlft55xx.h | 10 +- client/scripting.c | 6 +- include/pm3_cmd.h | 29 +- 8 files changed, 1017 insertions(+), 415 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c78d813db..86321ee9a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -293,6 +293,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Added `hf fido` `assert` and `make` commands from fido2 protocol (authenticatorMakeCredential and authenticatorGetAssertion) (@merlokk) - Added trailer block decoding to `hf mf rdbl` and `hf mf cgetbl` (@merlokk) - Added `hf mf mad` and `hf mfp mad` MAD decode, check and print commands (@merlokk) + - Added T55x7 downlink mode support r 0 Default, 1 Long Leading 0, 2 Leading 0, 3 1 of 4 and 4 (in some commands) try all. ### Fixed - Changed driver file proxmark3.inf to support both old and new Product/Vendor IDs (piwi) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index d9c17e3b3..1fed86574 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -873,12 +873,13 @@ static void PacketReceived(PacketCommandNG *packet) { case CMD_T55XX_READ_BLOCK: { struct p { uint32_t password; - uint8_t blockno; - uint8_t page; - bool pwdmode; + uint8_t blockno; + uint8_t page; + bool pwdmode; + uint8_t downlink_mode; } PACKED; struct p *payload = (struct p *) packet->data.asBytes; - T55xxReadBlock(payload->page, payload->pwdmode, false, payload->blockno, payload->password); + T55xxReadBlock(payload->page, payload->pwdmode, false, payload->blockno, payload->password,payload->downlink_mode); break; } case CMD_T55XX_WRITE_BLOCK: { @@ -887,15 +888,15 @@ static void PacketReceived(PacketCommandNG *packet) { break; } case CMD_T55XX_WAKEUP: { - T55xxWakeUp(packet->oldarg[0]); - break; + T55xxWakeUp(packet->oldarg[0],packet->oldarg[1]); + break; } case CMD_T55XX_RESET_READ: { - T55xxResetRead(); + T55xxResetRead(packet->data.asBytes[0]&0xff); break; } case CMD_T55XX_CHKPWDS: { - T55xx_ChkPwds(); + T55xx_ChkPwds(packet->data.asBytes[0]&0xff); break; } case CMD_PCF7931_READ: { diff --git a/armsrc/apps.h b/armsrc/apps.h index 41a1f0271..a508b74b0 100644 --- a/armsrc/apps.h +++ b/armsrc/apps.h @@ -102,12 +102,13 @@ void CopyVikingtoT55xx(uint32_t block1, uint32_t block2, uint8_t Q5); void WriteEM410x(uint32_t card, uint32_t id_hi, uint32_t id_lo); void CopyIndala64toT55x7(uint32_t hi, uint32_t lo); // Clone Indala 64-bit tag by UID to T55x7 void CopyIndala224toT55x7(uint32_t uid1, uint32_t uid2, uint32_t uid3, uint32_t uid4, uint32_t uid5, uint32_t uid6, uint32_t uid7); // Clone Indala 224-bit tag by UID to T55x7 -void T55xxResetRead(void); +void T55xxResetRead(uint8_t flags); +//id T55xxWriteBlock(uint32_t data, uint8_t blockno, uint32_t pwd, uint8_t flags); void T55xxWriteBlock(uint8_t *data); -void T55xxWriteBlockExt(uint32_t data, uint8_t blockno, uint32_t pwd, uint8_t flags); -void T55xxReadBlock(uint8_t page, bool pwd_mode, bool brute_mem, uint8_t block, uint32_t pwd); -void T55xxWakeUp(uint32_t Pwd); -void T55xx_ChkPwds(void); +// void T55xxWriteBlockExt(uint32_t data, uint8_t blockno, uint32_t pwd, uint8_t flags); +void T55xxReadBlock(uint8_t page, bool pwd_mode, bool brute_mem, uint8_t block, uint32_t pwd,uint8_t downlink_mode); +void T55xxWakeUp(uint32_t Pwd, uint8_t flags); +void T55xx_ChkPwds(uint8_t flags); void TurnReadLFOn(uint32_t delay); diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 96fd3ae37..6efbc6bd9 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -46,31 +46,133 @@ // = 1us = 1.5ticks // 1fc = 8us = 12ticks /* -Default LF T55xx config is set to: - startgap = 31*8 - writegap = 17*8 - write_0 = 15*8 - write_1 = 47*8 - read_gap = 15*8 + ========================================================================================================== + T55x7 Timing + ========================================================================================================== + + // t55xx_config t_config = { 29 * 8, 17 * 8, 15 * 8, 47 * 8, 15 * 8 } ; + + ATA5577 Downlink Protocol Timings. + Note: All absolute times assume TC = 1 / fC = 8 μs (fC = 125 kHz) + ----------------------------------------------------------------------- + Fixed-bit-length Protocol | Normal Downlink | Fast Downlink | + ------------------------------+-----------------------------------+-----------------------------------+------ +| Parameter | Remark | Symbol | Min. | Typ. | Max. | Min. | Typ. | Max. | Unit | +|------------+--------+--------+-----------+-----------+-----------+-----------+-----------+-----------+------| +| Start gap | | Sgap | 8 | 15 | 50 | 8 | 15 | 50 | Tc | +| Write gap | | Wgap | 8 | 10 | 20 | 8 | 10 | 20 | Tc | +|------------+--------+--------+-----------+-----------+-----------+-----------+-----------+-----------+------| +| coding | 0 data | d0 | 16 | 24 | 32 | 8 | 12 | 16 | Tc | +| | 1 data | d1 | 48 | 56 | 64 | 24 | 28 | 32 | Tc | + ------------------------------------------------------------------------------------------------------------- + + ----------------------------------------------------------------------- + Long Leading Reference | Normal Downlink | Fast Downlink | + ------------------------------+-----------------------------------+-----------------------------------+------ +| Parameter | Remark | Symbol | Min. | Typ. | Max. | Min. | Typ. | Max. | Unit | +|-----------+--------+---------+-----------+-----------+-----------+-----------+-----------+-----------+------| +| Start gap | | Sgap | 8 | 10 | 50 | 8 | 10 | 50 | Tc | +| Write gap | | Wgap | 8 | 10 | 20 | 8 | 10 | 20 | Tc | +|-----------+--------+---------+-----------+-----------+-----------+-----------+-----------+-----------+------| +| Write | Ref | | 152 | 160 | 168 | 140 | 144 | 148 | Tc | +| data | Pulse | dref | 136 clocks + 0 data bit | 132 clocks + 0 data bit | Tc | +| coding |--------+---------+-----------------------------------+-----------------------------------+------| +| | 0 data | d0 |dref – 143 |dref – 136 |dref – 128 |dref – 135 |dref – 132 |dref – 124 | Tc | +| | 1 data | d1 |dref – 111 |dref – 104 |dref – 96 |dref – 119 |dref – 116 |dref – 112 | Tc | + ------------------------------------------------------------------------------------------------------------- + + ----------------------------------------------------------------------- + Leading-zero Reference | Normal Downlink | Fast Downlink | + ------------------------------+-----------------------------------+-----------------------------------+------ +| Parameter | Remark | Symbol | Min. | Typ. | Max. | Min. | Typ. | Max. | Unit | +|-----------+--------+---------+-----------+-----------+-----------+-----------+-----------+-----------+------| +| Start gap | | Sgap | 8 | 10 | 50 | 8 | 10 | 50 | Tc | +| Write gap | | Wgap | 8 | 10 | 20 | 8 | 10 | 20 | Tc | +|-----------+--------+---------+-----------+-----------+-----------+-----------+-----------+-----------+------| +| Write | Ref | dref | 12 | – | 72 | 8 | – | 68 | Tc | +| data | 0 data | d0 | dref – 7 | dref | dref + 8 | dref – 3 | dref | dref + 4 | Tc | +| coding | 1 data | d1 | dref + 9 | dref + 16 | dref + 24 | dref + 5 | dref + 8 | dref + 12 | Tc | + ------------------------------------------------------------------------------------------------------------- + + ----------------------------------------------------------------------- + 1-of-4 Coding | Normal Downlink | Fast Downlink | + ------------------------------+-----------------------------------+-----------------------------------+------ +| Parameter | Remark | Symbol | Min. | Typ. | Max. | Min. | Typ. | Max. | Unit | +|-----------+--------+---------+-----------+-----------+-----------+-----------+-----------+-----------+------| +| Start gap | | Sgap | 8 | 10 | 50 | 8 | 10 | 50 | Tc | +| Write gap | | Wgap | 8 | 10 | 20 | 8 | 10 | 20 | Tc | +|-----------+--------+---------+-----------+-----------+-----------+-----------+-----------+-----------+------| +| Write | Ref 00 | dref | 8 | – | 68 | 12 | – | 72 | Tc | +| data |00 data | d00 | dref – 7 | dref | dref + 8 | dref – 3 | dref | dref+ 4 | Tc | +| coding |01 data | d01 | dref + 9 | dref + 16 | dref + 24 | dref + 5 | dref + 8 | dref + 12 | Tc | +| |10 data | d10 | dref + 25 | dref + 32 | dref + 40 | dref + 13 | dref + 16 | dref + 20 | Tc | +| |11 data | d11 | dref + 41 | dref + 48 | dref + 56 | dref + 21 | dref + 24 | dref + 28 | Tc | + ------------------------------------------------------------------------------------------------------------- */ -t55xx_config t_config = { 29 * 8, 17 * 8, 15 * 8, 47 * 8, 15 * 8 } ; +// Initial values if not in flash +// Note: Moved * 8 to apply when used. Saving 28 bytes here (- the *8) and 28 bytes flash. +// StartGap WriteGap Bit 0/00 Bit 1/01 Bit 10 Bit 11 ReadGap +t55xx_config T55xx_Timing = {{{ 29 , 17 , 15 , 50 , 0 , 0 , 15 }, // Default Fixed + { 31 , 20 , 18 , 50 , 0 , 0 , 15 }, // Long Leading Ref. + { 31 , 20 , 18 , 40 , 0 , 0 , 15 }, // Leading 0 + { 29 , 17 , 15 , 31 , 47 , 63 , 15 } }}; // 1 of 4 +/* +// StartGap WriteGap Bit 0/00 Bit 1/01 Bit 10 Bit 11 ReadGap +t55xx_config T55xx_Timing = {{{ 29 * 8 , 17 * 8 , 15 * 8 , 50 * 8 , 0 , 0 , 15 * 8 }, // Default Fixed + { 31 * 8 , 20 * 8 , 18 * 8 , 50 * 8 , 0 , 0 , 15 * 8 }, // Long Leading Ref. + { 31 * 8 , 20 * 8 , 18 * 8 , 40 * 8 , 0 , 0 , 15 * 8 }, // Leading 0 + { 29 * 8 , 17 * 8 , 15 * 8 , 31 * 8 , 47 * 8, 63 * 8, 15 * 8 } }}; // 1 of 4 +*/ + +// Some defines for readability +#define T55xx_DLMode_Fixed 0 // Default Mode +#define T55xx_DLMode_LLR 1 // Long Leading Reference +#define T55xx_DLMode_Leading0 2 // Leading Zero +#define T55xx_DLMode_1of4 3 // 1 of 4 +#define T55xx_LongLeadingReference 4 // Value to tell Write Bit to send long reference void printT55xxConfig(void) { + int DLMode; + DbpString(_BLUE_("LF T55XX config")); - Dbprintf(" [a] startgap............%d*8 (%d)", t_config.start_gap / 8, t_config.start_gap); - Dbprintf(" [b] writegap............%d*8 (%d)", t_config.write_gap / 8, t_config.write_gap); - Dbprintf(" [c] write_0.............%d*8 (%d)", t_config.write_0 / 8, t_config.write_0); - Dbprintf(" [d] write_1.............%d*8 (%d)", t_config.write_1 / 8, t_config.write_1); - Dbprintf(" [e] readgap.............%d*8 (%d)", t_config.read_gap / 8, t_config.read_gap); + for (DLMode = 0; DLMode < 4; DLMode++) { + switch (DLMode){ + case T55xx_DLMode_Fixed : Dbprintf("r 0 fixed bit length (default)"); break; + case T55xx_DLMode_LLR : Dbprintf("r 1 long leading reference"); break; + case T55xx_DLMode_Leading0 : Dbprintf("r 2 leading zero"); break; + case T55xx_DLMode_1of4 : Dbprintf("r 3 1 of 4 coding reference"); break; + } + // Save 36 bytes by not showing dec. all data sheets and entry is the x * 8 value, so not sure what we get for the 36 bytes dec? + Dbprintf(" [a] startgap............%d*8", T55xx_Timing.m[DLMode].start_gap );//, T55xx_Timing.start_gap[DLMode]); + Dbprintf(" [b] writegap............%d*8", T55xx_Timing.m[DLMode].write_gap );//, T55xx_Timing.write_gap[DLMode]); + Dbprintf(" [c] write_0.............%d*8", T55xx_Timing.m[DLMode].write_0 );//, T55xx_Timing.write_0 [DLMode]); + Dbprintf(" [d] write_1.............%d*8", T55xx_Timing.m[DLMode].write_1 );//, T55xx_Timing.write_1 [DLMode]); + if (DLMode == T55xx_DLMode_1of4) { + Dbprintf(" [e] write_2.............%d*8", T55xx_Timing.m[DLMode].write_2 );//, T55xx_Timing.write_2 [DLMode]); + Dbprintf(" [f] write_3.............%d*8", T55xx_Timing.m[DLMode].write_3 );//, T55xx_Timing.write_3 [DLMode]); + } + Dbprintf(" [g] readgap.............%d*8", T55xx_Timing.m[DLMode].read_gap );//, T55xx_Timing.read_gap [DLMode]); + } } void setT55xxConfig(uint8_t arg0, t55xx_config *c) { - - if (c->start_gap != 0) t_config.start_gap = c->start_gap; - if (c->write_gap != 0) t_config.write_gap = c->write_gap; - if (c->write_0 != 0) t_config.write_0 = c->write_0; - if (c->write_1 != 0) t_config.write_1 = c->write_1; - if (c->read_gap != 0) t_config.read_gap = c->read_gap; + uint8_t DLMode; + + for (DLMode = 0; DLMode < 4; DLMode++) { + if (c->m[DLMode].start_gap != 0) T55xx_Timing.m[DLMode].start_gap = c->m[DLMode].start_gap; + if (c->m[DLMode].write_gap != 0) T55xx_Timing.m[DLMode].write_gap = c->m[DLMode].write_gap; + if (c->m[DLMode].write_0 != 0) T55xx_Timing.m[DLMode].write_0 = c->m[DLMode].write_0 ; + if (c->m[DLMode].write_1 != 0) T55xx_Timing.m[DLMode].write_1 = c->m[DLMode].write_1 ; + if (DLMode == T55xx_DLMode_1of4) { + if (c->m[DLMode].write_2 != 0) T55xx_Timing.m[DLMode].write_2 = c->m[DLMode].write_2 ; + if (c->m[DLMode].write_3 != 0) T55xx_Timing.m[DLMode].write_3 = c->m[DLMode].write_3 ; + } + else{ + T55xx_Timing.m[DLMode].write_2 = 0x00; + T55xx_Timing.m[DLMode].write_3 = 0x00; + } + if (c->m[DLMode].read_gap != 0) T55xx_Timing.m[DLMode].read_gap = c->m[DLMode].read_gap ; + } printT55xxConfig(); @@ -93,27 +195,32 @@ void setT55xxConfig(uint8_t arg0, t55xx_config *c) { return; } - memcpy(buf, &t_config, T55XX_CONFIG_LEN); + memcpy(buf, &T55xx_Timing, T55XX_CONFIG_LEN); Flash_CheckBusy(BUSY_TIMEOUT); Flash_WriteEnable(); Flash_Erase4k(3, 0xD); - res = Flash_Write(T55XX_CONFIG_OFFSET, buf, T55XX_CONFIG_LEN); - if (res == T55XX_CONFIG_LEN && DBGLEVEL > 1) { + // if not a settings erase, write data + if (buf[0] != 0xff) { + res = Flash_Write(T55XX_CONFIG_OFFSET, buf, T55XX_CONFIG_LEN); + + if (res == T55XX_CONFIG_LEN && DBGLEVEL > 1) { DbpString("T55XX Config save success"); - } + } + } BigBuf_free(); #endif } t55xx_config *getT55xxConfig(void) { - return &t_config; + return &T55xx_Timing;//_FixedBit; } void loadT55xxConfig(void) { #ifdef WITH_FLASH + if (!FlashInit()) { return; } @@ -135,7 +242,7 @@ void loadT55xxConfig(void) { return; } - memcpy((uint8_t *)&t_config, buf, T55XX_CONFIG_LEN); + memcpy((uint8_t *)&T55xx_Timing, buf, T55XX_CONFIG_LEN); if (isok == T55XX_CONFIG_LEN) { if (DBGLEVEL > 1) DbpString("T55XX Config load success"); @@ -1354,187 +1461,302 @@ void TurnReadLF_off(uint32_t delay) { WaitUS(delay); } -// Write one bit to card -void T55xxWriteBit(int bit) { - if (!bit) - TurnReadLFOn(t_config.write_0); - else - TurnReadLFOn(t_config.write_1); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - WaitUS(t_config.write_gap); +// Macro for code readability +#define BitStream_Byte(X) ((X) >> 3) +#define BitStream_Bit(X) ((X) & 7) +#define t55_send_PwdMode (arg & 0x01) +#define t55_send_Page ((arg & 0x02) >> 1) +#define t55_send_TestMode ((arg & 0x04) >> 2) +#define t55_send_RegReadMode ((arg & 0x20) >> 5) +#define t55_send_ReadCmd ((arg & 0x40) >> 6) +#define t55_send_Reset ((arg & 0x80) >> 7) + +// Write one bit to chip +void T55xxWriteBit(uint8_t bit, uint8_t downlink_idx) { + + // Dbprintf ("%d",bit); + // If bit = 4 Send Long Leading Reference which is (138*8) + WRITE_0 + switch (bit){ + case 0 : TurnReadLFOn(T55xx_Timing.m[downlink_idx].write_0 * 8); break; // Send bit 0/00 + case 1 : TurnReadLFOn(T55xx_Timing.m[downlink_idx].write_1 * 8); break; // Send bit 1/01 + case 2 : TurnReadLFOn(T55xx_Timing.m[downlink_idx].write_2 * 8); break; // Send bits 10 (1 of 4) + case 3 : TurnReadLFOn(T55xx_Timing.m[downlink_idx].write_3 * 8); break; // Send bits 11 (1 of 4) + case 4 : TurnReadLFOn((T55xx_Timing.m[downlink_idx].write_0 + 136) * 8); break; // Send Long Leading Reference + } + + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + WaitUS(T55xx_Timing.m[downlink_idx].write_gap * 8); +} + +// Function to abstract an Arbitrary length byte array to store bit pattern. +// bit_array - Array to hold data/bit pattern +// start_offset - bit location to start storing new bits. +// data - upto 32 bits of data to store +// num_bits - how many bits (low x bits of data) Max 32 bits at a time +// max_len - how many bytes can the bit_array hold (ensure no buffer overflow) +// returns "Next" bit offset / bits stored (for next store) +uint8_t T55xx_SetBits (uint8_t *BitStream, uint8_t start_offset, uint32_t data , uint8_t num_bits, uint8_t max_len) +{ + int8_t offset; + int8_t NextOffset = start_offset; + + // Check if data will fit. + if ((start_offset + num_bits) <= (max_len*8)) { + // Loop through the data and store + for (offset = (num_bits-1); offset >= 0; offset--) { + + if ((data >> offset) & 1) BitStream[BitStream_Byte(NextOffset)] |= (1 << BitStream_Bit(NextOffset)); // Set the bit to 1 + else BitStream[BitStream_Byte(NextOffset)] &= (0xff ^ (1 << BitStream_Bit(NextOffset))); // Set the bit to 0 + + NextOffset++; + } + } + else { + // Note: This should never happen unless some code changes cause it. + // So short message for coders when testing. + Dbprintf ("T55 too many bits"); + } + return NextOffset; +} + +// Send one downlink command to the card +// void T55xx_SendCMD (uint32_t Data, uint8_t Block, uint32_t Pwd, uint8_t arg) { +void T55xx_SendCMD (uint32_t Data, uint32_t Pwd, uint16_t arg) { + + /* + arg bits + xxxx xxxxxxx1 0x001 PwdMode + xxxx xxxxxx1x 0x002 Page + xxxx xxxxx1xx 0x004 testMode + xxxx xxx11xxx 0x018 downlink mode + xxxx xx1xxxxx 0x020 !reg_readmode + xxxx x1xxxxxx 0x040 called for a read, so no data packet + xxxx 1xxxxxxx 0x080 reset + xxx1 xxxxxxxx 0x100 brute force + 111x xxxxxxxx 0xE00 Block + + */ + + uint8_t downlink_mode = (arg >> 3) & 0x03; + uint8_t i = 0; + uint8_t BitStream[10]; // Max Downlink Command size ~74 bits, so 10 bytes (80 bits) + uint8_t BitStreamLen = 0; + uint8_t SendBits; + uint8_t start_wait = 4; + bool brute_mem = (arg & 0x100); + uint8_t Block = (arg >> 9) & 0x07; + + if (brute_mem) start_wait = 0; + + // Build Bit Stream to send. + memset (BitStream,0x00,sizeof(BitStream)); + + BitStreamLen = 0; // Ensure 0 bit index to start. + + // Add Leading 0 and 1 of 4 reference bit + if ((downlink_mode == T55xx_DLMode_Leading0) || (downlink_mode == T55xx_DLMode_1of4)) + BitStreamLen = T55xx_SetBits (BitStream, BitStreamLen, 0, 1,sizeof(BitStream)); + + // Add extra reference 0 for 1 of 4 + if (downlink_mode == T55xx_DLMode_1of4) + BitStreamLen = T55xx_SetBits (BitStream, BitStreamLen, 0, 1,sizeof(BitStream)); + + // Add Opcode + if (t55_send_Reset) { + // Reset : r*) 00 + BitStreamLen = T55xx_SetBits (BitStream, BitStreamLen, 0, 2,sizeof(BitStream)); + } + else { + if (t55_send_TestMode) Dbprintf("TestMODE"); + BitStreamLen = T55xx_SetBits (BitStream, BitStreamLen,t55_send_TestMode ? 0 : 1 , 1,sizeof(BitStream)); + BitStreamLen = T55xx_SetBits (BitStream, BitStreamLen,t55_send_TestMode ? 1 : t55_send_Page , 1,sizeof(BitStream)); + //if (PwdMode) { + if (t55_send_PwdMode) { + // Leading 0 and 1 of 4 00 fixed bits if passsword used + if ((downlink_mode == T55xx_DLMode_Leading0) || (downlink_mode == T55xx_DLMode_1of4)) { + BitStreamLen = T55xx_SetBits (BitStream, BitStreamLen, 0, 2,sizeof(BitStream)); + } + BitStreamLen = T55xx_SetBits (BitStream, BitStreamLen, Pwd, 32,sizeof(BitStream)); + } + + // Add Lock bit 0 + if (!t55_send_RegReadMode) BitStreamLen = T55xx_SetBits (BitStream, BitStreamLen, 0, 1,sizeof(BitStream)); + + // Add Data if a write command + if (!t55_send_ReadCmd) BitStreamLen = T55xx_SetBits (BitStream, BitStreamLen, Data, 32,sizeof(BitStream)); + + // Add Address + if (!t55_send_RegReadMode) BitStreamLen = T55xx_SetBits (BitStream, BitStreamLen, Block, 3,sizeof(BitStream)); + } + + // Send Bits to T55xx + // Set up FPGA, 125kHz + LFSetupFPGAForADC(95, true); + + // make sure tag is fully powered up... + WaitMS(start_wait); + + // Trigger T55x7 in mode. + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + WaitUS(T55xx_Timing.m[downlink_mode].start_gap * 8); + + // If long leading 0 send long reference pulse + if (downlink_mode == T55xx_DLMode_LLR) + T55xxWriteBit (T55xx_LongLeadingReference,downlink_mode);//Timing); // Send Long Leading Start Reference + + if ((downlink_mode == T55xx_DLMode_1of4) && (BitStreamLen > 0)) { // 1 of 4 need to send 2 bits at a time + for ( i = 0; i < BitStreamLen-1; i+=2 ) { + SendBits = (BitStream[BitStream_Byte(i )] >> (BitStream_Bit(i )) & 1) << 1; // Bit i + SendBits += (BitStream[BitStream_Byte(i+1)] >> (BitStream_Bit(i+1)) & 1); // Bit i+1; + T55xxWriteBit (SendBits & 3,downlink_mode);//Timing); + } + } + else { + for (i = 0; i < BitStreamLen; i++) { + SendBits = (BitStream[BitStream_Byte(i)] >> BitStream_Bit(i)); + T55xxWriteBit (SendBits & 1,downlink_mode);//Timing); + } + } } // Send T5577 reset command then read stream (see if we can identify the start of the stream) -void T55xxResetRead(void) { +void T55xxResetRead(uint8_t flags) { + + uint8_t downlink_mode = ((flags >> 3) & 3); + uint8_t arg = 0x80 | downlink_mode; + LED_A_ON(); + //clear buffer now so it does not interfere with timing later BigBuf_Clear_keep_EM(); - // Set up FPGA, 125kHz - LFSetupFPGAForADC(95, true); - // make sure tag is fully powered up... - WaitMS(4); - - // Trigger T55x7 in mode. - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - WaitUS(t_config.start_gap); - - // reset tag - op code 00 - T55xxWriteBit(0); - T55xxWriteBit(0); - - TurnReadLFOn(t_config.read_gap); + T55xx_SendCMD (0, 0, arg); + TurnReadLFOn(T55xx_Timing.m[downlink_mode].read_gap * 8); + // Acquisition DoPartialAcquisition(0, true, BigBuf_max_traceLen(), 0); // Turn the field off FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off reply_mix(CMD_ACK, 0, 0, 0, 0, 0); + LED_A_OFF(); } // Write one card block in page 0, no lock -void T55xxWriteBlockExt(uint32_t data, uint8_t blockno, uint32_t pwd, uint8_t flags) { - LED_A_ON(); - bool pwd_mode = (flags & 0x1); - uint8_t page = (flags & 0x2) >> 1; - bool test_mode = (flags & 0x4) >> 2; - uint32_t i = 0; +//void T55xxWriteBlockExt(uint32_t data, uint8_t blockno, uint32_t pwd, uint8_t flags) { +void T55xxWriteBlock(uint8_t *data) { - // Set up FPGA, 125kHz - LFSetupFPGAForADC(95, true); + /* + flag bits + xxxxxxx1 0x01 PwdMode + xxxxxx1x 0x02 Page + xxxxx1xx 0x04 testMode + xxx11xxx 0x18 downlink mode + xx1xxxxx 0x20 !reg_readmode + x1xxxxxx 0x40 called for a read, so no data packet + 1xxxxxxx 0x80 reset + */ + + t55xx_write_block_t *c = (t55xx_write_block_t *)data; + // c->data, c->blockno, c->pwd, c->flags - // make sure tag is fully powered up... - WaitMS(4); + bool testMode = ((c->flags & 0x04) == 0x04); - // Trigger T55x7 in mode. - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - WaitUS(t_config.start_gap); + c->flags &= (0xff ^ 0x40); // Called for a write, so ensure it is clear/0 + + LED_A_ON (); + T55xx_SendCMD (c->data, c->pwd, c->flags | (c->blockno << 9)) ;//, false); - if (test_mode) { - Dbprintf("T55xx writing with %s", _YELLOW_("test mode enabled")); - // undocmented testmode opcode 01 - T55xxWriteBit(0); - T55xxWriteBit(1); - } else { - // std opcode 10 == page 0 - // std opcode 11 == page 1 - T55xxWriteBit(1); - T55xxWriteBit(page); - } + // Perform write (nominal is 5.6 ms for T55x7 and 18ms for E5550, + // so wait a little more) - if (pwd_mode) { - // Send pwd - for (i = 0x80000000; i != 0; i >>= 1) - T55xxWriteBit(pwd & i); - } - // Send lock bit - T55xxWriteBit(0); + // "there is a clock delay before programming" + // - programming takes ~5.6ms for t5577 ~18ms for E5550 or t5567 + // so we should wait 1 clock + 5.6ms then read response? + // but we need to know we are dealing with t5577 vs t5567 vs e5550 (or q5) marshmellow... + if (testMode) { + //TESTMODE TIMING TESTS: + // <566us does nothing + // 566-568 switches between wiping to 0s and doing nothing + // 5184 wipes and allows 1 block to be programmed. + // indefinite power on wipes and then programs all blocks with bitshifted data sent. + TurnReadLFOn(5184); - // Send data - for (i = 0x80000000; i != 0; i >>= 1) - T55xxWriteBit(data & i); + } else { + TurnReadLFOn(20 * 1000); + //could attempt to do a read to confirm write took + // as the tag should repeat back the new block + // until it is reset, but to confirm it we would + // need to know the current block 0 config mode for + // modulation clock an other details to demod the response... + // response should be (for t55x7) a 0 bit then (ST if on) + // block data written in on repeat until reset. - // Send block number - for (i = 0x04; i != 0; i >>= 1) - T55xxWriteBit(blockno & i); + //DoPartialAcquisition(20, true, 12000); + } + // turn field off + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - // Perform write (nominal is 5.6 ms for T55x7 and 18ms for E5550, - // so wait a little more) - - // "there is a clock delay before programming" - // - programming takes ~5.6ms for t5577 ~18ms for E5550 or t5567 - // so we should wait 1 clock + 5.6ms then read response? - // but we need to know we are dealing with t5577 vs t5567 vs e5550 (or q5) marshmellow... - if (test_mode) { - //TESTMODE TIMING TESTS: - // <566us does nothing - // 566-568 switches between wiping to 0s and doing nothing - // 5184 wipes and allows 1 block to be programmed. - // indefinite power on wipes and then programs all blocks with bitshifted data sent. - TurnReadLFOn(5184); - - } else { - TurnReadLFOn(20 * 1000); - - //could attempt to do a read to confirm write took - // as the tag should repeat back the new block - // until it is reset, but to confirm it we would - // need to know the current block 0 config mode for - // modulation clock an other details to demod the response... - // response should be (for t55x7) a 0 bit then (ST if on) - // block data written in on repeat until reset. - - //DoPartialAcquisition(20, true, 12000); - } - - // turn field off - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LED_A_OFF(); + // cmd_send(CMD_ACK,0,0,0,0,0); + reply_ng(CMD_T55XX_WRITE_BLOCK, PM3_SUCCESS, NULL, 0); + LED_A_OFF (); } -// Write one card block in page 0, no lock +/* // uses NG format void T55xxWriteBlock(uint8_t *data) { t55xx_write_block_t *c = (t55xx_write_block_t *)data; T55xxWriteBlockExt(c->data, c->blockno, c->pwd, c->flags); - reply_ng(CMD_T55XX_WRITE_BLOCK, PM3_SUCCESS, NULL, 0); + // reply_ng(CMD_T55XX_WRITE_BLOCK, PM3_SUCCESS, NULL, 0); } - +*/ +/* // Read one card block in page [page] -void T55xxReadBlock(uint8_t page, bool pwd_mode, bool brute_mem, uint8_t block, uint32_t pwd) { - LED_A_ON(); - bool regular_readmode = (block == 0xFF); - uint8_t start_wait = 4; - size_t samples = 12000; - uint32_t i; +void T55xxReadBlockExt (uint16_t flags, uint8_t block, uint32_t pwd) { + / * + flag bits + xxxx xxxxxxx1 0x0001 PwdMode + xxxx xxxxxx1x 0x0002 Page + xxxx xxxxx1xx 0x0004 testMode + xxxx xxx11xxx 0x0018 downlink mode + xxxx xx1xxxxx 0x0020 !reg_readmode + xxxx x1xxxxxx 0x0040 called for a read, so no data packet + xxxx 1xxxxxxx 0x0080 reset + xxx1 xxxxxxxx 0x0100 brute/leave field on + * / + size_t samples = 12000; + bool brute_mem = (flags & 0x0100) >> 8; + + LED_A_ON(); - if (brute_mem) { - start_wait = 0; - samples = 1024; - } + if (brute_mem) samples = 1024; + + // Set Read Flag to ensure SendCMD does not add "data" to the packet + flags |= 0x40; - //clear buffer now so it does not interfere with timing later - BigBuf_Clear_keep_EM(); + // RegRead Mode true block = 0xff, so read without an address + if (block == 0xff) flags |= 0x20; + + //make sure block is at max 7 + block &= 0x7; - //make sure block is at max 7 - block &= 0x7; + //clear buffer now so it does not interfere with timing later + BigBuf_Clear_keep_EM(); - // Set up FPGA, 125kHz to power up the tag - LFSetupFPGAForADC(95, true); - // make sure tag is fully powered up... - WaitMS(start_wait); + T55xx_SendCMD (0, pwd, flags | (block << 9)); //, true); - // Trigger T55x7 Direct Access Mode with start gap - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - WaitUS(t_config.start_gap); + // Turn field on to read the response + // 137*8 seems to get to the start of data pretty well... + // but we want to go past the start and let the repeating data settle in... - // Opcode 1[page] - T55xxWriteBit(1); - T55xxWriteBit(page); //Page 0 + // TurnReadLFOn(210*8); // issues with block 1 reads so dropping down seemed to help + TurnReadLFOn(137*8); - if (pwd_mode) { - // Send Pwd - for (i = 0x80000000; i != 0; i >>= 1) - T55xxWriteBit(pwd & i); - } - // Send a zero bit separation - T55xxWriteBit(0); - - // Send Block number (if direct access mode) - if (!regular_readmode) - for (i = 0x04; i != 0; i >>= 1) - T55xxWriteBit(block & i); - - // Turn field on to read the response - // 137*8 seems to get to the start of data pretty well... - // but we want to go past the start and let the repeating data settle in... - TurnReadLFOn(150 * 8); - - // Acquisition - // Now do the acquisition - DoPartialAcquisition(0, true, samples, 0); + // Acquisition + // Now do the acquisition + DoPartialAcquisition(0, true, samples, 0); // Turn the field off if (!brute_mem) { @@ -1543,25 +1765,84 @@ void T55xxReadBlock(uint8_t page, bool pwd_mode, bool brute_mem, uint8_t block, LED_A_OFF(); } } +*/ +// Read one card block in page [page] +void T55xxReadBlock(uint8_t page, bool pwd_mode, bool brute_mem, uint8_t block, uint32_t pwd, uint8_t downlink_mode) { + /* + flag bits + xxxxxxx1 0x0001 PwdMode + xxxxxx1x 0x0002 Page + xxxxx1xx 0x0004 testMode + xxx11xxx 0x0018 downlink mode + xx1xxxxx 0x0020 !reg_readmode + x1xxxxxx 0x0040 called for a read, so no data packet + 1xxxxxxx 0x0080 reset + 1xxxxxxxx 0x0100 brute/leave field on + */ + uint16_t flags = 0x0040; // read packet + if (pwd_mode) flags |= 0x0001; + if (page) flags |= 0x0002; + flags |= (downlink_mode & 3) << 3; + if (brute_mem) flags |= 0x0100; + +// T55xxReadBlockExt (flags,block,pwd); + size_t samples = 12000; + // bool brute_mem = (flags & 0x0100) >> 8; + + LED_A_ON(); -void T55xx_ChkPwds() { + if (brute_mem) samples = 1024; + + //-- Set Read Flag to ensure SendCMD does not add "data" to the packet + //-- flags |= 0x40; + + // RegRead Mode true block = 0xff, so read without an address + if (block == 0xff) flags |= 0x20; + + //make sure block is at max 7 + block &= 0x7; + + //clear buffer now so it does not interfere with timing later + BigBuf_Clear_keep_EM(); + + T55xx_SendCMD (0, pwd, flags | (block << 9)); //, true); + + // Turn field on to read the response + // 137*8 seems to get to the start of data pretty well... + // but we want to go past the start and let the repeating data settle in... + + // TurnReadLFOn(210*8); // issues with block 1 reads so dropping down seemed to help + TurnReadLFOn(137*8); + + // Acquisition + // Now do the acquisition + DoPartialAcquisition(0, true, samples, 0); + + // Turn the field off + if (!brute_mem) { + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + reply_ng(CMD_T55XX_READ_BLOCK, PM3_SUCCESS, NULL, 0); + LED_A_OFF(); + } + +} + +void T55xx_ChkPwds(uint8_t flags) { DbpString("[+] T55XX Check pwds using flashmemory starting"); uint8_t ret = 0; // First get baseline and setup LF mode. // tends to mess up BigBuf - uint8_t *buf = BigBuf_get_addr(); - - uint32_t b1, baseline = 0; - + uint8_t *buf = BigBuf_get_addr(); + uint32_t b1, baseline = 0; + uint8_t downlink_mode = (flags >> 3) & 0x03; + // collect baseline for failed attempt uint8_t x = 32; while (x--) { b1 = 0; - -// T55xxReadBlock(uint8_t page, bool pwd_mode, bool brute_mem, uint8_t block, uint32_t pwd) - T55xxReadBlock(0, 0, true, 1, 0); + T55xxReadBlock(0, 0, true, 1, 0,downlink_mode); for (uint16_t j = 0; j < 1024; ++j) b1 += buf[j]; @@ -1576,8 +1857,8 @@ void T55xx_ChkPwds() { uint8_t *pwds = BigBuf_get_EM_addr(); uint16_t pwdCount = 0; uint32_t candidate = 0; - #ifdef WITH_FLASH + BigBuf_Clear_EM(); uint16_t isok = 0; uint8_t counter[2] = {0x00, 0x00}; @@ -1606,7 +1887,7 @@ void T55xx_ChkPwds() { pwd = bytes_to_num(pwds + i * 4, 4); - T55xxReadBlock(0, true, true, 0, pwd); + T55xxReadBlock(0, true, true, 0, pwd,downlink_mode); // calc mean of BigBuf 1024 samples. uint32_t sum = 0; @@ -1623,9 +1904,7 @@ void T55xx_ChkPwds() { Dbprintf("[=] Pwd %08X | ABS %u", pwd, curr); if (curr > prev) { - - - Dbprintf("[=] --> ABS %u Candidate %08X <--", curr, pwd); + Dbprintf("[=] --> ABS %u Candidate %08X <--", curr, pwd); candidate = pwd; prev = curr; } @@ -1640,36 +1919,31 @@ OUT: LEDsoff(); } -void T55xxWakeUp(uint32_t Pwd) { +void T55xxWakeUp(uint32_t Pwd, uint8_t flags) { + + flags |= 0x01 | 0x40 | 0x20; //Password | Read Call (no data) | reg_read no block LED_B_ON(); - uint32_t i = 0; - // Set up FPGA, 125kHz - LFSetupFPGAForADC(95, true); - // make sure tag is fully powered up... - WaitMS(4); - - // Trigger T55x7 Direct Access Mode - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - WaitUS(t_config.start_gap); - - // Opcode 10 - T55xxWriteBit(1); - T55xxWriteBit(0); //Page 0 - - // Send Pwd - for (i = 0x80000000; i != 0; i >>= 1) - T55xxWriteBit(Pwd & i); - - // Turn and leave field on to let the begin repeating transmission + T55xx_SendCMD (0, Pwd, flags); + + //-- Turn and leave field on to let the begin repeating transmission TurnReadLFOn(20 * 1000); } + /*-------------- Cloning routines -----------*/ void WriteT55xx(uint32_t *blockdata, uint8_t startblock, uint8_t numblocks) { - // write last block first and config block last (if included) - for (uint8_t i = numblocks + startblock; i > startblock; i--) - T55xxWriteBlockExt(blockdata[i - 1], i - 1, 0, 0); + + t55xx_write_block_t cmd; + cmd.pwd = 0; + cmd.flags = 0; + + for (uint8_t i = numblocks + startblock; i > startblock; i--) { + cmd.data = blockdata[i - 1]; + cmd.blockno = i - 1; + T55xxWriteBlock ((uint8_t *)&cmd); + } + } // Copy HID id to card and setup block 0 config diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 9a23e660b..811a78b70 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -43,12 +43,14 @@ static int usage_t55xx_config() { return PM3_SUCCESS; } static int usage_t55xx_read() { - PrintAndLogEx(NORMAL, "Usage: lf t55xx read [b ] [p ] "); + PrintAndLogEx(NORMAL, "Usage: lf t55xx read [r ] b [p ] "); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " b - block number to read. Between 0-7"); PrintAndLogEx(NORMAL, " p - OPTIONAL password (8 hex characters)"); PrintAndLogEx(NORMAL, " o - OPTIONAL override safety check"); PrintAndLogEx(NORMAL, " 1 - OPTIONAL read Page 1 instead of Page 0"); + PrintAndLogEx(NORMAL, " r - downlink encoding '0' fixed bit length (default), '1' long leading ref."); + PrintAndLogEx(NORMAL, " '2' leading zero, '3' 1 of 4 coding ref."); PrintAndLogEx(NORMAL, " ****WARNING****"); PrintAndLogEx(NORMAL, " Use of read with password on a tag not configured for a pwd"); PrintAndLogEx(NORMAL, " can damage the tag"); @@ -61,13 +63,15 @@ static int usage_t55xx_read() { return PM3_SUCCESS; } static int usage_t55xx_write() { - PrintAndLogEx(NORMAL, "Usage: lf t55xx write [b ] [d ] [p ] [1] [t]"); + PrintAndLogEx(NORMAL, "Usage: lf t55xx write [r ] b d [p ] [1] [t]"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " b - block number to write. Between 0-7"); PrintAndLogEx(NORMAL, " d - 4 bytes of data to write (8 hex characters)"); PrintAndLogEx(NORMAL, " p - OPTIONAL password 4bytes (8 hex characters)"); PrintAndLogEx(NORMAL, " 1 - OPTIONAL write Page 1 instead of Page 0"); PrintAndLogEx(NORMAL, " t - OPTIONAL test mode write - ****DANGER****"); + PrintAndLogEx(NORMAL, " r - downlink encoding '0' fixed bit length (default), '1' long leading ref."); + PrintAndLogEx(NORMAL, " '2' leading zero, '3' 1 of 4 coding ref."); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx write b 3 d 11223344 - write 11223344 to block 3"); @@ -76,24 +80,29 @@ static int usage_t55xx_write() { return PM3_SUCCESS; } static int usage_t55xx_trace() { - PrintAndLogEx(NORMAL, "Usage: lf t55xx trace [1]"); + PrintAndLogEx(NORMAL, "Usage: lf t55xx trace [r mode]"); PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " 1 - if set, use Graphbuffer otherwise read data from tag."); + PrintAndLogEx(NORMAL, " r - downlink encoding '0' fixed bit length (default), '1' long leading ref."); + PrintAndLogEx(NORMAL, " '2' leading zero, '3' 1 of 4 coding ref."); + // Command did not seem to support the 1 option (yet) so have removed the help lines + // PrintAndLogEx(NORMAL, " 1 - if set, use Graphbuffer otherwise read data from tag."); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx trace"); - PrintAndLogEx(NORMAL, " lf t55xx trace 1"); + // PrintAndLogEx(NORMAL, " lf t55xx trace 1"); PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } static int usage_t55xx_info() { - PrintAndLogEx(NORMAL, "Usage: lf t55xx info [1] [d [q]]"); + PrintAndLogEx(NORMAL, "Usage: lf t55xx info [1] [r ] [d [q]]"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " (default) - read data from tag."); PrintAndLogEx(NORMAL, " 1 - if set, use Graphbuffer instead of reading tag."); PrintAndLogEx(NORMAL, " d - 4 bytes of data (8 hex characters)"); PrintAndLogEx(NORMAL, " if set, use these data instead of reading tag."); PrintAndLogEx(NORMAL, " q - if set, provided data are interpreted as Q5 config."); + PrintAndLogEx(NORMAL, " r - downlink encoding '0' fixed bit length (default), '1' long leading ref."); + PrintAndLogEx(NORMAL, " '2' leading zero, '3' 1 of 4 coding ref."); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx info"); @@ -104,10 +113,12 @@ static int usage_t55xx_info() { return PM3_SUCCESS; } static int usage_t55xx_dump() { - PrintAndLogEx(NORMAL, "Usage: lf t55xx dump [o]"); + PrintAndLogEx(NORMAL, "Usage: lf t55xx dump [r ] [ [o]]"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " - OPTIONAL password 4bytes (8 hex symbols)"); PrintAndLogEx(NORMAL, " o - OPTIONAL override, force pwd read despite danger to card"); + PrintAndLogEx(NORMAL, " r - downlink encoding '0' fixed bit length (default), '1' long leading ref."); + PrintAndLogEx(NORMAL, " '2' leading zero, '3' 1 of 4 coding ref."); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx dump"); @@ -116,10 +127,13 @@ static int usage_t55xx_dump() { return PM3_SUCCESS; } static int usage_t55xx_detect() { - PrintAndLogEx(NORMAL, "Usage: lf t55xx detect [1] [p ]"); + PrintAndLogEx(NORMAL, "Usage: lf t55xx detect [1] [r ] [p ]"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " 1 - if set, use Graphbuffer otherwise read data from tag."); - PrintAndLogEx(NORMAL, " p - OPTIONAL password (8 hex characters)"); + PrintAndLogEx(NORMAL, " p - downlink encoding '0' fixed bit length (default)"); + PrintAndLogEx(NORMAL, " '1' long leading ref., '2' leading zero "); + PrintAndLogEx(NORMAL, " '3' 1 of 4 coding ref., '4' try all modes"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx detect"); @@ -130,10 +144,13 @@ static int usage_t55xx_detect() { } static int usage_t55xx_detectP1() { PrintAndLogEx(NORMAL, "Command: Detect Page 1 of a t55xx chip"); - PrintAndLogEx(NORMAL, "Usage: lf t55xx p1detect [1] [p ]"); + PrintAndLogEx(NORMAL, "Usage: lf t55xx p1detect [1] [r ] [p ]"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " 1 - if set, use Graphbuffer otherwise read data from tag."); PrintAndLogEx(NORMAL, " p - OPTIONAL password (8 hex characters)"); + PrintAndLogEx(NORMAL, " r - downlink encoding '0' fixed bit length (default)"); + PrintAndLogEx(NORMAL, " '1' long leading ref., '2' leading zero "); + PrintAndLogEx(NORMAL, " '3' 1 of 4 coding ref., '4' try all modes"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx p1detect"); @@ -143,11 +160,13 @@ static int usage_t55xx_detectP1() { return PM3_SUCCESS; } static int usage_t55xx_wakup() { - PrintAndLogEx(NORMAL, "Usage: lf t55xx wakeup [h] p "); - PrintAndLogEx(NORMAL, "This commands send the Answer-On-Request command and leaves the readerfield ON afterwards."); + PrintAndLogEx(NORMAL, "Usage: lf t55xx wakeup [h] [r ] p "); + PrintAndLogEx(NORMAL, "This commands sends the Answer-On-Request command and leaves the readerfield ON afterwards."); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h - this help"); PrintAndLogEx(NORMAL, " p - password 4bytes (8 hex symbols)"); + PrintAndLogEx(NORMAL, " r - downlink encoding '0' fixed bit length (default), '1' long leading ref."); + PrintAndLogEx(NORMAL, " '2' leading zero, '3' 1 of 4 coding ref."); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx wakeup p 11223344 - send wakeup password"); @@ -158,11 +177,14 @@ static int usage_t55xx_chk() { PrintAndLogEx(NORMAL, "press " _YELLOW_("'enter'") " to cancel the command"); PrintAndLogEx(NORMAL, "WARNING: this may brick non-password protected chips!"); PrintAndLogEx(NORMAL, "Try to reading block 7 before\n"); - PrintAndLogEx(NORMAL, "Usage: lf t55xx chk [h] [i <*.dic>]"); + PrintAndLogEx(NORMAL, "Usage: lf t55xx chk [h] [m] [r ] [i <*.dic>]"); PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " h - this help"); - PrintAndLogEx(NORMAL, " m - use dictionary from flashmemory\n"); - PrintAndLogEx(NORMAL, " i <*.dic> - loads a default keys dictionary file <*.dic>"); + PrintAndLogEx(NORMAL, " h - this help"); + PrintAndLogEx(NORMAL, " m - use dictionary from flashmemory\n"); + PrintAndLogEx(NORMAL, " r - downlink encoding '0' fixed bit length (default)"); + PrintAndLogEx(NORMAL, " '1' long leading ref., '2' leading zero "); + PrintAndLogEx(NORMAL, " '3' 1 of 4 coding ref., '4' try all modes"); + PrintAndLogEx(NORMAL, " i <*.dic> - loads a default keys dictionary file <*.dic>"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx chk m"); @@ -174,16 +196,19 @@ static int usage_t55xx_bruteforce() { PrintAndLogEx(NORMAL, "This command uses bruteforce to scan a number range"); PrintAndLogEx(NORMAL, "press " _YELLOW_("'enter'") " to cancel the command"); PrintAndLogEx(NORMAL, "WARNING: this may brick non-password protected chips!"); - PrintAndLogEx(NORMAL, "Try to reading block 7 before\n"); - PrintAndLogEx(NORMAL, "Usage: lf t55xx bruteforce [h] "); + PrintAndLogEx(NORMAL, "Try reading block 7 before\n"); + PrintAndLogEx(NORMAL, "Usage: lf t55xx bruteforce [h] [r ] "); PrintAndLogEx(NORMAL, " password must be 4 bytes (8 hex symbols)"); PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " h - this help"); - PrintAndLogEx(NORMAL, " - 4 byte hex value to start pwd search at"); - PrintAndLogEx(NORMAL, " - 4 byte hex value to end pwd search at"); + PrintAndLogEx(NORMAL, " h - this help"); + PrintAndLogEx(NORMAL, " r - downlink encoding '0' fixed bit length (default)"); + PrintAndLogEx(NORMAL, " '1' long leading ref., '2' leading zero "); + PrintAndLogEx(NORMAL, " '3' 1 of 4 coding ref., '4' try all modes"); + PrintAndLogEx(NORMAL, " - 4 byte hex value to start pwd search at"); + PrintAndLogEx(NORMAL, " - 4 byte hex value to end pwd search at"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " lf t55xx bruteforce aaaaaa77 aaaaaa99"); + PrintAndLogEx(NORMAL, " lf t55xx bruteforce r 2 aaaaaa77 aaaaaa99"); PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } @@ -191,17 +216,20 @@ static int usage_t55xx_recoverpw() { PrintAndLogEx(NORMAL, "This command uses a few tricks to try to recover mangled password"); PrintAndLogEx(NORMAL, "press " _YELLOW_("'enter'") " to cancel the command"); PrintAndLogEx(NORMAL, "WARNING: this may brick non-password protected chips!"); - PrintAndLogEx(NORMAL, "Try to reading block 7 before\n"); - PrintAndLogEx(NORMAL, "Usage: lf t55xx recoverpw [password]"); + PrintAndLogEx(NORMAL, "Try reading block 7 before\n"); + PrintAndLogEx(NORMAL, "Usage: lf t55xx recoverpw [r ] [password]"); PrintAndLogEx(NORMAL, " password must be 4 bytes (8 hex symbols)"); PrintAndLogEx(NORMAL, " default password is 51243648, used by many cloners"); PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " h - this help"); - PrintAndLogEx(NORMAL, " [password] - 4 byte hex value of password written by cloner"); + PrintAndLogEx(NORMAL, " h - this help"); + PrintAndLogEx(NORMAL, " r - downlink encoding '0' fixed bit length (default)"); + PrintAndLogEx(NORMAL, " '1' long leading ref., '2' leading zero "); + PrintAndLogEx(NORMAL, " '3' 1 of 4 coding ref., '4' try all modes"); + PrintAndLogEx(NORMAL, " [password] - 4 byte hex value of password written by cloner"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx recoverpw"); - PrintAndLogEx(NORMAL, " lf t55xx recoverpw 51243648"); + PrintAndLogEx(NORMAL, " lf t55xx r 3 recoverpw 51243648"); PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } @@ -218,17 +246,22 @@ static int usage_t55xx_wipe() { return PM3_SUCCESS; } static int usage_lf_deviceconfig() { - PrintAndLogEx(NORMAL, "Sets t55x7 timings for direkt commands. The timings are set here in Field Clocks (FC), \nwhich is converted to (US) on device"); - PrintAndLogEx(NORMAL, "Usage: lf t55xx deviceconfig a b c d e p"); + PrintAndLogEx(NORMAL, "Sets t55x7 timings for direct commands. The timings are set here in Field Clocks (FC), \nwhich is converted to (US) on device"); + PrintAndLogEx(NORMAL, "Usage: lf t55xx deviceconfig [r ] a b c d e f g [p]"); PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " h - This help"); - PrintAndLogEx(NORMAL, " a <8..255> - Set start gap"); - PrintAndLogEx(NORMAL, " b <8..255> - Set write gap"); - PrintAndLogEx(NORMAL, " c <8..255> - Set write ZERO gap"); - PrintAndLogEx(NORMAL, " d <8..255> - Set write ONE gap"); - PrintAndLogEx(NORMAL, " e <8..255> - Set read gap"); - PrintAndLogEx(NORMAL, " p - persist to flashmemory"); - PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, " h - This help"); + PrintAndLogEx(NORMAL, " a <8..255> - Set start gap"); + PrintAndLogEx(NORMAL, " b <8..255> - Set write gap"); + PrintAndLogEx(NORMAL, " c <8..255> - Set write ZERO gap"); + PrintAndLogEx(NORMAL, " d <8..255> - Set write ONE gap"); + PrintAndLogEx(NORMAL, " e <8..255> - Set write TWO gap (1 of 4 only)"); + PrintAndLogEx(NORMAL, " f <8..255> - Set write THREE gap (1 of 4 only)"); + PrintAndLogEx(NORMAL, " g <8..255> - Set read gap"); + PrintAndLogEx(NORMAL, " p - persist to flashmemory"); + PrintAndLogEx(NORMAL, " r - downlink encoding '0' fixed bit length (default), '1' long leading ref."); + PrintAndLogEx(NORMAL, " '2' leading zero, '3' 1 of 4 coding ref."); + PrintAndLogEx(NORMAL, " z - erase t55x7 timings (needs p and reboot to load defaults)"); + PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx deviceconfig a 29 b 17 c 15 d 47 e 15 - default T55XX"); PrintAndLogEx(NORMAL, " lf t55xx deviceconfig a 55 b 14 c 21 d 30 - default EM4305"); @@ -359,13 +392,12 @@ static int CmdT55xxSetConfig(const char *Cmd) { return printConfiguration(config); } -int T55xxReadBlock(uint8_t block, bool page1, bool usepwd, bool override, uint32_t password) { +int T55xxReadBlock(uint8_t block, bool page1, bool usepwd, uint8_t override, uint32_t password, uint8_t downlink_mode) { //Password mode if (usepwd) { // try reading the config block and verify that PWD bit is set before doing this! if (!override) { - - if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, false, 0)) return PM3_ESOFT; + if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, false, 0,downlink_mode)) return PM3_ESOFT; if (!tryDetectModulation()) { PrintAndLogEx(NORMAL, "Safety Check: Could not detect if PWD bit is set in config block. Exits."); @@ -376,11 +408,14 @@ int T55xxReadBlock(uint8_t block, bool page1, bool usepwd, bool override, uint32 page1 = false; } } else { + // Show only if first for command i.e. override = 1 (override and display) override = 2 (override and dont display) + if ((override & 2) != 2) PrintAndLogEx(NORMAL, "Safety Check Overriden - proceeding despite risk"); } } - if (!AquireData(page1, block, usepwd, password)) return PM3_ESOFT; + + if (!AquireData(page1, block, usepwd, password, downlink_mode)) return PM3_ESOFT; if (!DecodeT55xxBlock()) return PM3_ESOFT; printT55xxBlock(block); @@ -388,13 +423,15 @@ int T55xxReadBlock(uint8_t block, bool page1, bool usepwd, bool override, uint32 } static int CmdT55xxReadBlock(const char *Cmd) { - uint8_t block = REGULAR_READ_MODE_BLOCK; - uint32_t password = 0; //default to blank Block 7 - bool usepwd = false; - bool override = false; - bool page1 = false; - bool errors = false; - uint8_t cmdp = 0; + uint8_t block = REGULAR_READ_MODE_BLOCK; + uint32_t password = 0; //default to blank Block 7 + bool usepwd = false; + bool override = false; + bool page1 = false; + bool errors = false; + uint8_t cmdp = 0; + uint8_t downlink_mode = 0; + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { case 'h': @@ -416,6 +453,13 @@ static int CmdT55xxReadBlock(const char *Cmd) { page1 = true; cmdp++; break; + case 'r': + case 'R': + downlink_mode = param_getchar(Cmd, cmdp+1) - '0'; + if (downlink_mode > 3) downlink_mode = 0; + cmdp +=2; + break; + default: PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); errors = true; @@ -430,7 +474,7 @@ static int CmdT55xxReadBlock(const char *Cmd) { } printT5xxHeader(page1); - return T55xxReadBlock(block, page1, usepwd, override, password); + return T55xxReadBlock(block, page1, usepwd, override, password, downlink_mode); } bool DecodeT55xxBlock(void) { @@ -512,11 +556,34 @@ static int SanityOfflineCheck(bool useGraphBuffer) { return PM3_SUCCESS; } +void T55xx_Print_DownlinkMode (uint8_t downlink_mode) +{ + char Msg[80]; + sprintf (Msg,"Downlink Mode used : "); + + switch (downlink_mode) { + case 0 : strcat (Msg,"default/fixed bit length"); break; + case 1 : strcat (Msg,"long leading reference (r 1)"); break; + case 2 : strcat (Msg,"leading zero reference (r 2)"); break; + case 3 : strcat (Msg,"1 of 4 coding reference (r 3)"); break; + default : + strcat (Msg,"default/fixed bit length"); break; + } + + PrintAndLogEx (NORMAL,Msg); +} +// static int CmdT55xxDetect(const char *Cmd) { - bool errors = false; - bool useGB = false, usepwd = false; - uint32_t password = 0; - uint8_t cmdp = 0; + + bool errors = false; + bool useGB = false; + bool usepwd = false; + bool try_all_dl_modes = false; + bool found = false; + uint32_t password = 0; + uint8_t cmdp = 0; + uint8_t downlink_mode = 0; + uint8_t dl_mode = 0; while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { @@ -532,6 +599,12 @@ static int CmdT55xxDetect(const char *Cmd) { useGB = true; cmdp++; break; + case 'r': + downlink_mode = param_getchar(Cmd, cmdp+1) - '0'; + if (downlink_mode == 4) try_all_dl_modes = true; + if (downlink_mode > 3) downlink_mode = 0; + cmdp +=2; + break; default: PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); errors = true; @@ -544,16 +617,47 @@ static int CmdT55xxDetect(const char *Cmd) { if (SanityOfflineCheck(useGB) != PM3_SUCCESS) return PM3_ENODATA; if (!useGB) { - if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password)) - return PM3_ENODATA; + for (dl_mode = downlink_mode; dl_mode < 4; dl_mode++) { + found = AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password,dl_mode); + + // found = false if password is supplied but wrong d/l mode + // so keep trying other modes (if requested) + /* if (!found) { + printf ("Aquire not found"); + return PM3_ENODATA; + } + */ + if (tryDetectModulation()) + { + T55xx_Print_DownlinkMode (dl_mode); + dl_mode = 4; + found = true; + } + else found = false; + + if (!try_all_dl_modes) dl_mode = 4; + } } + + if (useGB) found = tryDetectModulation(); + + if (!found) + PrintAndLogEx(WARNING, "Could not detect modulation automatically. Try setting it manually with " _YELLOW_("\'lf t55xx config\'")); + + + /* if (!useGB) { + if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password,downlink_mode)) + return PM3_ENODATA; + } if (!tryDetectModulation()) PrintAndLogEx(WARNING, "Could not detect modulation automatically. Try setting it manually with " _YELLOW_("\'lf t55xx config\'")); + else + T55xx_Print_DownlinkMode (downlink_mode); +*/ return PM3_SUCCESS; } - // detect configuration? bool tryDetectModulation(void) { @@ -997,10 +1101,14 @@ int printConfiguration(t55xx_conf_block_t b) { } static int CmdT55xxWakeUp(const char *Cmd) { - uint32_t password = 0; - uint8_t cmdp = 0; - bool errors = false; - while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + + uint32_t password = 0; + uint8_t cmdp = 0; + bool errors = false; + uint8_t downlink_mode = 0; + uint8_t flags = 0; + + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { case 'h': return usage_t55xx_wakup(); @@ -1009,30 +1117,40 @@ static int CmdT55xxWakeUp(const char *Cmd) { cmdp += 2; errors = false; break; + case 'r': + downlink_mode = param_getchar(Cmd, cmdp+1) - '0'; + if (downlink_mode > 3) downlink_mode = 0; + cmdp +=2; + break; default: PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); errors = true; break; } } + if (errors) return usage_t55xx_wakup(); + flags = (downlink_mode & 3) << 3; clearCommandBuffer(); - SendCommandMIX(CMD_T55XX_WAKEUP, password, 0, 0, NULL, 0); + SendCommandMIX(CMD_T55XX_WAKEUP, password, flags, 0, NULL, 0); PrintAndLogEx(SUCCESS, "Wake up command sent. Try read now"); + return PM3_SUCCESS; } static int CmdT55xxWriteBlock(const char *Cmd) { - uint8_t block = 0xFF; //default to invalid block - uint32_t data = 0; //default to blank Block - uint32_t password = 0; //default to blank Block 7 - bool usepwd = false; - bool page1 = false; - bool gotdata = false; - bool testMode = false; - bool errors = false; - uint8_t cmdp = 0; + uint8_t block = 0xFF; //default to invalid block + uint32_t data = 0; //default to blank Block + uint32_t password = 0; //default to blank Block 7 + bool usepwd = false; + bool page1 = false; + bool gotdata = false; + bool testMode = false; + bool errors = false; + uint8_t cmdp = 0; + uint32_t downlink_mode = 0; + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { case 'h': @@ -1064,6 +1182,11 @@ static int CmdT55xxWriteBlock(const char *Cmd) { page1 = true; cmdp++; break; + case 'r': + downlink_mode = param_getchar(Cmd, cmdp+1) - '0'; + if (downlink_mode > 3) downlink_mode = 0; + cmdp +=2; + break; default: PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); errors = true; @@ -1074,10 +1197,11 @@ static int CmdT55xxWriteBlock(const char *Cmd) { PacketResponseNG resp; uint8_t flags; - flags = (usepwd) ? 0x1 : 0; - flags |= (page1) ? 0x2 : 0; + flags = (usepwd) ? 0x1 : 0; + flags |= (page1) ? 0x2 : 0; flags |= (testMode) ? 0x4 : 0; - + flags |= (downlink_mode << 3); + char pwdStr[16] = {0}; snprintf(pwdStr, sizeof(pwdStr), "pwd: 0x%08X", password); @@ -1096,10 +1220,10 @@ static int CmdT55xxWriteBlock(const char *Cmd) { uses struct in pm3_cmd.h */ t55xx_write_block_t ng; - ng.data = data; - ng.pwd = password; + ng.data = data; + ng.pwd = password; ng.blockno = block; - ng.flags = flags; + ng.flags = flags; SendCommandNG(CMD_T55XX_WRITE_BLOCK, (uint8_t *)&ng, sizeof(ng)); if (!WaitForResponseTimeout(CMD_T55XX_WRITE_BLOCK, &resp, 2000)) { @@ -1110,16 +1234,26 @@ static int CmdT55xxWriteBlock(const char *Cmd) { } static int CmdT55xxReadTrace(const char *Cmd) { + uint8_t cmd_len = 0; + uint8_t downlink_mode = 0; + char cmdp = tolower(param_getchar(Cmd, 0)); - if (strlen(Cmd) > 1 || cmdp == 'h') return usage_t55xx_trace(); - - if (strlen(Cmd) == 0) { + if (cmdp == 'r') { + downlink_mode = param_getchar(Cmd, 1) - '0'; + if (downlink_mode > 3) downlink_mode = 0; + cmd_len = 3; + } + if ((strlen(Cmd) != cmd_len) || (cmdp == 'h')) return usage_t55xx_trace(); + + if (strlen(Cmd) == cmd_len) { // sanity check. if (SanityOfflineCheck(false) != PM3_SUCCESS) return PM3_ENODATA; bool pwdmode = false; uint32_t password = 0; - if (!AquireData(T55x7_PAGE1, T55x7_TRACE_BLOCK1, pwdmode, password)) +// REGULAR_READ_MODE_BLOCK - yeilds correct Page 1 Block 2 data i.e. + 32 bit offset. +// if (!AquireData(T55x7_PAGE1, T55x7_TRACE_BLOCK1, pwdmode, password,downlink_mode)) + if (!AquireData(T55x7_PAGE1, REGULAR_READ_MODE_BLOCK, pwdmode, password,downlink_mode)) return PM3_ENODATA; } @@ -1361,10 +1495,11 @@ static int CmdT55xxInfo(const char *Cmd) { Normal mode Extended mode */ - bool frombuff = false, gotdata = false, dataasq5 = false; - uint8_t cmdp = 0; - uint32_t block0 = 0; - + bool frombuff = false, gotdata = false, dataasq5 = false; + uint8_t cmdp = 0; + uint8_t downlink_mode = 0; + uint32_t block0 = 0; + while (param_getchar(Cmd, cmdp) != 0x00) { switch (tolower(param_getchar(Cmd, cmdp))) { case 'h': @@ -1382,6 +1517,11 @@ static int CmdT55xxInfo(const char *Cmd) { dataasq5 = true; cmdp += 2; break; + case 'r': + downlink_mode = param_getchar(Cmd, cmdp+1)- '0'; + if (downlink_mode > 3) downlink_mode = 0; + cmdp += 2; + break; default: PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); return usage_t55xx_info(); @@ -1400,7 +1540,7 @@ static int CmdT55xxInfo(const char *Cmd) { bool pwdmode = false; uint32_t password = 0; - if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, pwdmode, password)) + if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, pwdmode, password,downlink_mode)) return PM3_ENODATA; } if (!gotdata) { @@ -1495,30 +1635,43 @@ static int CmdT55xxInfo(const char *Cmd) { static int CmdT55xxDump(const char *Cmd) { - uint32_t password = 0; - bool override = false; - char cmdp = tolower(param_getchar(Cmd, 0)); - if (cmdp == 'h') return usage_t55xx_dump(); + uint32_t password = 0; + uint8_t override = false; + uint8_t cmd_opt_idx = 0; + uint8_t downlink_mode = 0; + uint8_t pwd_offset = 0; + char cmdp = tolower(param_getchar(Cmd, 0)); + - bool usepwd = (strlen(Cmd) > 0); + if (cmdp == 'h') return usage_t55xx_dump(); + if (cmdp == 'r') { + cmd_opt_idx++; + downlink_mode = param_getchar(Cmd, cmd_opt_idx++) - '0'; + if (downlink_mode > 3) downlink_mode = 0; + pwd_offset = 3; + } + bool usepwd = (strlen(Cmd) > pwd_offset); if (usepwd) { - password = param_get32ex(Cmd, 0, 0, 16); - if (param_getchar(Cmd, 1) == 'o') + password = param_get32ex(Cmd, cmd_opt_idx++, 0, 16); + if (param_getchar(Cmd, cmd_opt_idx++) == 'o') override = true; } printT5xxHeader(0); - for (uint8_t i = 0; i < 8; ++i) - T55xxReadBlock(i, 0, usepwd, override, password); - + for (uint8_t i = 0; i < 8; ++i) { + T55xxReadBlock(i, 0, usepwd, override, password,downlink_mode); + // idea for better user experience and display. + // only show override warning on the first block read + if (override) override |= 2; // flag not to show safty for 2nd and on. + } printT5xxHeader(1); for (uint8_t i = 0; i < 4; i++) - T55xxReadBlock(i, 1, usepwd, override, password); + T55xxReadBlock(i, 1, usepwd, override, password,downlink_mode); return PM3_SUCCESS; } -bool AquireData(uint8_t page, uint8_t block, bool pwdmode, uint32_t password) { +bool AquireData(uint8_t page, uint8_t block, bool pwdmode, uint32_t password, uint8_t downlink_mode) { // arg0 bitmodes: // b0 = pwdmode // b1 = page to read from @@ -1527,15 +1680,17 @@ bool AquireData(uint8_t page, uint8_t block, bool pwdmode, uint32_t password) { // arg2: password struct p { uint32_t password; - uint8_t blockno; - uint8_t page; - bool pwdmode; + uint8_t blockno; + uint8_t page; + bool pwdmode; + uint8_t downlink_mode; } PACKED; struct p payload; - payload.password = password; - payload.blockno = block; - payload.page = page & 0x1; - payload.pwdmode = pwdmode; + payload.password = password; + payload.blockno = block; + payload.page = page & 0x1; + payload.pwdmode = pwdmode; + payload.downlink_mode = downlink_mode; clearCommandBuffer(); SendCommandNG(CMD_T55XX_READ_BLOCK, (uint8_t *)&payload, sizeof(payload)); @@ -1795,9 +1950,20 @@ static void t55x7_create_config_block(int tagtype) { */ static int CmdResetRead(const char *Cmd) { - (void)Cmd; // Cmd is not used so far + + uint8_t downlink_mode = 0; + uint8_t flags = 0; + + + if (strlen (Cmd) == 3) + downlink_mode = param_getchar(Cmd, 1) - '0'; + + if (downlink_mode > 3) downlink_mode = 0; + + printf ("DL : %d\n",downlink_mode); + flags = downlink_mode << 3; clearCommandBuffer(); - SendCommandNG(CMD_T55XX_RESET_READ, NULL, 0); + SendCommandNG(CMD_T55XX_RESET_READ, &flags, sizeof(flags)); if (!WaitForResponseTimeout(CMD_ACK, NULL, 2500)) { PrintAndLogEx(WARNING, "command execution time out"); return PM3_ETIMEOUT; @@ -1853,13 +2019,44 @@ static bool IsCancelled(void) { // load a default pwd file. static int CmdT55xxChkPwds(const char *Cmd) { - char filename[FILE_PATH_SIZE] = {0}; - bool found = false; - uint8_t timeout = 0; - uint8_t *keyBlock = NULL; - - char cmdp = tolower(param_getchar(Cmd, 0)); - if (strlen(Cmd) == 0 || cmdp == 'h') return usage_t55xx_chk(); + char filename[FILE_PATH_SIZE] = {0}; + bool found = false; + uint8_t timeout = 0; + uint8_t *keyBlock = NULL; + bool from_flash = false; + bool try_all_dl_modes = false; + uint8_t downlink_mode = 0; + int len; + char cmdp; + bool use_pwd_file = false; + int dl_mode; // to try each downlink mode for each password + + + cmdp = tolower(param_getchar(Cmd,0)); + + if (cmdp == 'h') return usage_t55xx_chk(); + if (cmdp == 'm') { + from_flash = true; + Cmd +=2; + cmdp = tolower(param_getchar(Cmd,0)); + } + if (cmdp == 'r') { + Cmd += 2; + downlink_mode = param_getchar(Cmd,0 ) - '0'; // get 2nd option, as this is fixed order. + if (downlink_mode == 4) try_all_dl_modes = true; + if (downlink_mode > 3) downlink_mode = 0; + Cmd += 2; + cmdp = param_getchar(Cmd,0); + } + if (cmdp == 'i') { + Cmd+=2; + len = strlen(Cmd); + if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE; + memcpy(filename, Cmd, len); + use_pwd_file = true; + } + + /* // block 7, page1 = false, usepwd = false, override = false, pwd = 00000000 @@ -1872,10 +2069,11 @@ static int CmdT55xxChkPwds(const char *Cmd) { */ uint64_t t1 = msclock(); - - if (cmdp == 'm') { + uint8_t flags = downlink_mode << 3; + + if (from_flash) { clearCommandBuffer(); - SendCommandNG(CMD_T55XX_CHKPWDS, NULL, 0); + SendCommandNG(CMD_T55XX_CHKPWDS, &flags, sizeof(flags)); PacketResponseNG resp; while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { @@ -1891,10 +2089,12 @@ static int CmdT55xxChkPwds(const char *Cmd) { if (resp.oldarg[0]) { PrintAndLogEx(SUCCESS, "\nFound a candidate [ " _YELLOW_("%08X") " ]. Trying to validate", resp.oldarg[1]); - if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, resp.oldarg[1])) { + if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, resp.oldarg[1],downlink_mode)) { found = tryDetectModulation(); if (found) { - PrintAndLogEx(SUCCESS, "Found valid password: [ " _GREEN_("%08") " ]", resp.oldarg[1]); + PrintAndLogEx(SUCCESS, "Found valid password: [ " _GREEN_("%08X") " ]", resp.oldarg[1]); + T55xx_Print_DownlinkMode (downlink_mode); + } else { PrintAndLogEx(WARNING, "Check pwd failed"); } @@ -1907,12 +2107,7 @@ static int CmdT55xxChkPwds(const char *Cmd) { goto out; } - if (cmdp == 'i') { - - int len = strlen(Cmd + 2); - if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE; - memcpy(filename, Cmd + 2, len); - + if (use_pwd_file) { uint16_t keycount = 0; size_t datalen = 0; @@ -1948,19 +2143,25 @@ static int CmdT55xxChkPwds(const char *Cmd) { curr_password = bytes_to_num(keyBlock + 4 * c, 4); PrintAndLogEx(INFO, "Testing %08X", curr_password); + for (dl_mode = downlink_mode; dl_mode <= 3; dl_mode++){ + + if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, curr_password,dl_mode)) { + continue; + } - if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, curr_password)) { - continue; - } - - found = tryDetectModulation(); - if (found) - break; - } - if (found) - PrintAndLogEx(SUCCESS, "Found valid password: [ " _GREEN_("%08X") " ]", curr_password); - else - PrintAndLogEx(WARNING, "Check pwd failed"); + found = tryDetectModulation(); + if (found) { + PrintAndLogEx(SUCCESS, "Found valid password: [ " _GREEN_("%08X") " ]", curr_password); + T55xx_Print_DownlinkMode (dl_mode); + dl_mode = 4; // Exit other downlink mode checks + c = keycount; // Exit loop + } + + if (!try_all_dl_modes) // Exit loop if not trying all downlink modes + dl_mode = 4; + } + } + if (!found) PrintAndLogEx(WARNING, "Check pwd failed"); } free(keyBlock); @@ -1976,16 +2177,25 @@ static int CmdT55xxBruteForce(const char *Cmd) { uint32_t start_password = 0x00000000; //start password uint32_t end_password = 0xFFFFFFFF; //end password - uint32_t curr = 0; - bool found = false; + uint32_t curr = 0; + uint8_t downlink_mode = 0; + uint8_t cmd_opt_idx = 0; + uint8_t found = 0; // > 0 if found xx1 xx downlink needed, 1 found + + char cmdp = tolower(param_getchar(Cmd, cmd_opt_idx)); - char cmdp = tolower(param_getchar(Cmd, 0)); if (cmdp == 'h') return usage_t55xx_bruteforce(); + if (cmdp == 'r') { // downlink mode supplied + cmd_opt_idx++; // skip over 'r' + downlink_mode = param_getchar (Cmd,cmd_opt_idx++) - '0'; + if (downlink_mode > 4) downlink_mode = 0; + } + uint64_t t1 = msclock(); - start_password = param_get32ex(Cmd, 0, 0, 16); - end_password = param_get32ex(Cmd, 1, 0, 16); + start_password = param_get32ex(Cmd, cmd_opt_idx++, 0, 16); + end_password = param_get32ex(Cmd, cmd_opt_idx++, 0, 16); curr = start_password; @@ -1995,7 +2205,7 @@ static int CmdT55xxBruteForce(const char *Cmd) { PrintAndLogEx(INFO, "Search password range [%08X -> %08X]", start_password, end_password); - while (!found) { + while (found == 0) { printf("."); fflush(stdout); @@ -2004,7 +2214,7 @@ static int CmdT55xxBruteForce(const char *Cmd) { return PM3_EOPABORTED; } - found = tryOnePassword(curr); + found = tryOnePassword(curr,downlink_mode); if (curr == end_password) break; @@ -2014,47 +2224,72 @@ static int CmdT55xxBruteForce(const char *Cmd) { PrintAndLogEx(NORMAL, ""); - if (found) - PrintAndLogEx(SUCCESS, "Found valid password: [ " _GREEN_("%08X") " ]", curr); + if (found) { + PrintAndLogEx(SUCCESS, "Found valid password: [ " _GREEN_("%08X") "]", curr-1); + T55xx_Print_DownlinkMode ((found >> 1) & 3); + } else - PrintAndLogEx(WARNING, "Bruteforce failed, last tried: [ " _YELLOW_("%08X") " ]", --curr); + PrintAndLogEx(WARNING, "Bruteforce failed, last tried: [ " _YELLOW_("%08X") " ]", curr); t1 = msclock() - t1; PrintAndLogEx(SUCCESS, "\nTime in bruteforce: %.0f seconds\n", (float)t1 / 1000.0); return PM3_SUCCESS; } -int tryOnePassword(uint32_t password) { - PrintAndLogEx(INFO, "Trying password %08X", password); +uint8_t tryOnePassword(uint32_t password, uint8_t downlink_mode) { + + bool try_all_dl_modes = false; + uint8_t dl_mode = 0; + + PrintAndLogEx(INFO, "Trying password %08X", password); - AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, password); + if (downlink_mode == 4) try_all_dl_modes = true; + + downlink_mode = (downlink_mode & 3); // ensure 0-3 + + // check if dl mode 4 and loop if needed + for (dl_mode = downlink_mode; dl_mode < 4; dl_mode++){ - if (getSignalProperties()->isnoise == false) - return 0; + AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, password,dl_mode); - if (tryDetectModulation()) - return 1; - else - return 0; + // if (getSignalProperties()->isnoise == false) { + // } else { + if (tryDetectModulation()) + { + return 1 + (dl_mode << 1); + } + // } + if (!try_all_dl_modes) dl_mode = 4; + } + return 0; } static int CmdT55xxRecoverPW(const char *Cmd) { - int bit = 0; + int bit = 0; uint32_t orig_password = 0x0; uint32_t curr_password = 0x0; uint32_t prev_password = 0xffffffff; - uint32_t mask = 0x0; - int found = 0; - char cmdp = tolower(param_getchar(Cmd, 0)); - if (cmdp == 'h') return usage_t55xx_recoverpw(); + uint32_t mask = 0x0; + uint8_t downlink_mode = 0; + uint8_t found = 0; + uint8_t cmd_opt_idx = 0; + + char cmdp = tolower(param_getchar(Cmd, cmd_opt_idx)); - orig_password = param_get32ex(Cmd, 0, 0x51243648, 16); //password used by handheld cloners + if (cmdp == 'h') return usage_t55xx_recoverpw(); + if (cmdp == 'r') { // downlink mode supplied + cmd_opt_idx++; // skip over 'r' + downlink_mode = param_getchar (Cmd,cmd_opt_idx++) - '0'; + if (downlink_mode > 4) downlink_mode = 0; + } + + orig_password = param_get32ex(Cmd, cmd_opt_idx++, 0x51243648, 16); //password used by handheld cloners // first try fliping each bit in the expected password while (bit < 32) { curr_password = orig_password ^ (1u << bit); - found = tryOnePassword(curr_password); - if (found == 1) + found = tryOnePassword(curr_password,downlink_mode); + if (found > 0) // xx1 for found xx = dl mode used goto out; bit++; @@ -2078,8 +2313,8 @@ static int CmdT55xxRecoverPW(const char *Cmd) { continue; } - found = tryOnePassword(curr_password); - if (found == 1) + found = tryOnePassword(curr_password,downlink_mode); + if (found > 0) goto out; bit++; @@ -2100,8 +2335,8 @@ static int CmdT55xxRecoverPW(const char *Cmd) { bit++; continue; } - found = tryOnePassword(curr_password); - if (found == 1) + found = tryOnePassword(curr_password,downlink_mode); + if (found > 0) goto out; bit++; @@ -2115,8 +2350,10 @@ out: PrintAndLogEx(NORMAL, ""); - if (found == 1) - PrintAndLogEx(SUCCESS, "Found valid password: [ " _GREEN_("%08X") " ]", curr_password); + if (found > 0) { + PrintAndLogEx(SUCCESS, "Found valid password: [ " _GREEN_("%08X") "]", curr_password); + T55xx_Print_DownlinkMode ((found >> 1) & 3); + } else PrintAndLogEx(WARNING, "Recover pwd failed"); @@ -2127,14 +2364,14 @@ out: // some return all page 1 (64 bits) and others return just that block (32 bits) // unfortunately the 64 bits makes this more likely to get a false positive... bool tryDetectP1(bool getData) { - uint8_t preamble[] = {1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1}; - size_t startIdx = 0; - uint8_t fc1 = 0, fc2 = 0, ans = 0; - int clk = 0, firstClockEdge = 0; - bool st = true; + uint8_t preamble[] = {1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1}; + size_t startIdx = 0; + uint8_t fc1 = 0, fc2 = 0, ans = 0; + int clk = 0, firstClockEdge = 0; + bool st = true; if (getData) { - if (!AquireData(T55x7_PAGE1, T55x7_TRACE_BLOCK1, false, 0)) + if (!AquireData(T55x7_PAGE1, T55x7_TRACE_BLOCK1, false, 0,0)) return false; } @@ -2237,11 +2474,15 @@ bool tryDetectP1(bool getData) { } // does this need to be a callable command? static int CmdT55xxDetectPage1(const char *Cmd) { - bool errors = false; - bool useGB = false; - bool usepwd = false; - uint32_t password = 0; - uint8_t cmdp = 0; + bool errors = false; + bool useGB = false; + bool usepwd = false; + bool try_all_dl_modes = false; + uint8_t found = 0; + uint32_t password = 0; + uint8_t cmdp = 0; + uint8_t downlink_mode = 0; + uint8_t dl_mode = 0; while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { @@ -2257,6 +2498,12 @@ static int CmdT55xxDetectPage1(const char *Cmd) { useGB = true; cmdp++; break; + case 'r': + downlink_mode = param_getchar(Cmd, cmdp+1) - '0'; + if (downlink_mode == 4) try_all_dl_modes = true; + if (downlink_mode > 3) downlink_mode = 0; + cmdp +=2; + break; default: PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); errors = true; @@ -2266,21 +2513,42 @@ static int CmdT55xxDetectPage1(const char *Cmd) { if (errors) return usage_t55xx_detectP1(); if (!useGB) { - if (!AquireData(T55x7_PAGE1, T55x7_TRACE_BLOCK1, usepwd, password)) - return PM3_ENODATA; - } + for (dl_mode = downlink_mode; dl_mode < 4; dl_mode++) { + found = AquireData(T55x7_PAGE1, T55x7_TRACE_BLOCK1, usepwd, password,dl_mode); + //return PM3_ENODATA; + if (tryDetectP1(false)) //tryDetectModulation()) + { + found = dl_mode; + dl_mode = 4; + } + else found = false; + + if (!try_all_dl_modes) dl_mode = 4; + } + + } + + if (useGB) found = tryDetectP1(false); + + if (found) { + PrintAndLogEx(SUCCESS, "T55xx chip found!"); + T55xx_Print_DownlinkMode (found); + } + else + PrintAndLogEx(WARNING, "Could not detect modulation automatically. Try setting it manually with " _YELLOW_("\'lf t55xx config\'")); - if (tryDetectP1(false)) - PrintAndLogEx(SUCCESS, "T55xx chip found!"); return PM3_SUCCESS; } static int CmdT55xxSetDeviceConfig(const char *Cmd) { - uint8_t startgap = 0, writegap = 0; - uint8_t write0 = 0, write1 = 0, readgap = 0; - bool errors = false, shall_persist = false; - uint8_t cmdp = 0; + uint8_t startgap = 0, writegap = 0, readgap = 0; + uint8_t write0 = 0, write1 = 0, write2 = 0, write3 = 0; + bool errors = false, shall_persist = false; + uint8_t cmdp = 0; + uint8_t downlink_mode = 0; + bool erase = false; + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { case 'h': @@ -2302,13 +2570,30 @@ static int CmdT55xxSetDeviceConfig(const char *Cmd) { cmdp += 2; break; case 'e': + errors |= param_getdec(Cmd, cmdp + 1, &write2); + cmdp += 2; + break; + case 'f': + errors |= param_getdec(Cmd, cmdp + 1, &write3); + cmdp += 2; + break; + case 'g': errors |= param_getdec(Cmd, cmdp + 1, &readgap); cmdp += 2; break; + case 'r': + downlink_mode = param_getchar(Cmd, cmdp + 1) - '0'; + if (downlink_mode > 3) downlink_mode = 0; + cmdp += 2; + break; case 'p': shall_persist = true; cmdp++; break; + case 'z': + erase = true; + cmdp++; + break; default: PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); errors = 1; @@ -2319,8 +2604,21 @@ static int CmdT55xxSetDeviceConfig(const char *Cmd) { //Validations if (errors || cmdp == 0) return usage_lf_deviceconfig(); - t55xx_config conf = { startgap * 8, writegap * 8, write0 * 8, write1 * 8, readgap * 8 }; - +// printf ("DLmode %d\n",downlink_mode); + t55xx_config conf = {0}; + if (erase) { + memset (&conf,0xff, sizeof(conf)); + } + else { + + conf.m[downlink_mode].start_gap = startgap;// * 8; + conf.m[downlink_mode].write_gap = writegap;// * 8; + conf.m[downlink_mode].write_0 = write0 ;// * 8; + conf.m[downlink_mode].write_1 = write1 ;// * 8; + conf.m[downlink_mode].write_2 = write2 ;// * 8; + conf.m[downlink_mode].write_3 = write3 ;// * 8; + conf.m[downlink_mode].read_gap = readgap ;// * 8; + } clearCommandBuffer(); SendCommandOLD(CMD_SET_LF_T55XX_CONFIG, shall_persist, 0, 0, &conf, sizeof(t55xx_config)); return PM3_SUCCESS; @@ -2328,9 +2626,9 @@ static int CmdT55xxSetDeviceConfig(const char *Cmd) { static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, - {"bruteforce", CmdT55xxBruteForce, IfPm3Lf, " [i <*.dic>] Simple bruteforce attack to find password"}, + {"bruteforce", CmdT55xxBruteForce, IfPm3Lf, " Simple bruteforce attack to find password"}, {"config", CmdT55xxSetConfig, AlwaysAvailable, "Set/Get T55XX configuration (modulation, inverted, offset, rate)"}, - {"chk", CmdT55xxChkPwds, IfPm3Lf, "Check passwords"}, + {"chk", CmdT55xxChkPwds, IfPm3Lf, "Check passwords from dictionary/flash"}, {"detect", CmdT55xxDetect, AlwaysAvailable, "[1] Try detecting the tag modulation from reading the configuration block."}, {"deviceconfig", CmdT55xxSetDeviceConfig, IfPm3Lf, "Set/Get T55XX device configuration (startgap, writegap, write0, write1, readgap"}, {"p1detect", CmdT55xxDetectPage1, IfPm3Lf, "[1] Try detecting if this is a t55xx tag by reading page 1"}, diff --git a/client/cmdlft55xx.h b/client/cmdlft55xx.h index 56fc942fd..c61ef137d 100644 --- a/client/cmdlft55xx.h +++ b/client/cmdlft55xx.h @@ -148,9 +148,9 @@ char *GetModelStrFromCID(uint32_t cid); char *GetSelectedModulationStr(uint8_t id); void printT5xxHeader(uint8_t page); void printT55xxBlock(uint8_t blockNum); -int printConfiguration(t55xx_conf_block_t b); +int printConfiguration(t55xx_conf_block_t b); -int T55xxReadBlock(uint8_t block, bool page1, bool usepwd, bool override, uint32_t password); +int T55xxReadBlock(uint8_t block, bool page1, bool usepwd, uint8_t override, uint32_t password, uint8_t downlink_mode); bool GetT55xxBlockData(uint32_t *blockdata); bool DecodeT55xxBlock(void); bool tryDetectModulation(void); @@ -158,9 +158,9 @@ bool testKnownConfigBlock(uint32_t block0); bool tryDetectP1(bool getData); bool test(uint8_t mode, uint8_t *offset, int *fndBitRate, uint8_t clk, bool *Q5); -int special(const char *Cmd); -bool AquireData(uint8_t page, uint8_t block, bool pwdmode, uint32_t password); -int tryOnePassword(uint32_t password); +int special(const char *Cmd); +bool AquireData(uint8_t page, uint8_t block, bool pwdmode, uint32_t password, uint8_t downlink_mode); +uint8_t tryOnePassword(uint32_t password, uint8_t downlink_mode); void printT55x7Trace(t55x7_tracedata_t data, uint8_t repeat); void printT5555Trace(t5555_tracedata_t data, uint8_t repeat); diff --git a/client/scripting.c b/client/scripting.c index 572899e2d..a88f1dfea 100644 --- a/client/scripting.c +++ b/client/scripting.c @@ -903,7 +903,7 @@ static int l_T55xx_readblock(lua_State *L) { // try reading the config block and verify that PWD bit is set before doing this! if (!override) { - if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, false, 0)) { + if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, false, 0,0)) { return returnToLuaWithError(L, "Failed to read config block"); } @@ -920,7 +920,7 @@ static int l_T55xx_readblock(lua_State *L) { } } - if (!AquireData(usepage1, block, usepwd, password)) { + if (!AquireData(usepage1, block, usepwd, password,0)) { return returnToLuaWithError(L, "Failed to aquire data from card"); } @@ -977,7 +977,7 @@ static int l_T55xx_detect(lua_State *L) { if (!useGB) { - isok = AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password); + isok = AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password,0); if (isok == false) { return returnToLuaWithError(L, "Failed to aquire LF signal data"); } diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index d271d3099..297d52337 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -119,7 +119,7 @@ typedef struct { int divisor; int trigger_threshold; } sample_config; - +/* typedef struct { uint16_t start_gap; uint16_t write_gap; @@ -127,7 +127,34 @@ typedef struct { uint16_t write_1; uint16_t read_gap; } t55xx_config; +*/ +// Extended to support 1 of 4 timing +typedef struct { + uint8_t start_gap ; + uint8_t write_gap ; + uint8_t write_0 ; + uint8_t write_1 ; + uint8_t write_2 ; + uint8_t write_3 ; + uint8_t read_gap ; +} t55xx_config_t; +// This setup will allow for the 4 downlink modes "m" as well as other items if needed. +// Given the one struct we can then read/write to flash/client in one go. +typedef struct { + t55xx_config_t m[4]; // mode +} t55xx_config; + +/*typedef struct { + uint16_t start_gap [4]; + uint16_t write_gap [4]; + uint16_t write_0 [4]; + uint16_t write_1 [4]; + uint16_t write_2 [4]; + uint16_t write_3 [4]; + uint16_t read_gap [4]; +} t55xx_config; +*/ typedef struct { uint8_t version; uint32_t baudrate; From 70cd0d844b4578a0e92e3a8989a3aec1f4be6127 Mon Sep 17 00:00:00 2001 From: cjbrigato Date: Tue, 23 Jul 2019 07:39:34 +0200 Subject: [PATCH 0133/1854] FIX : Tereifying typo --- client/cmdflashmemspiffs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdflashmemspiffs.c b/client/cmdflashmemspiffs.c index c6ae55211..e06f492a0 100644 --- a/client/cmdflashmemspiffs.c +++ b/client/cmdflashmemspiffs.c @@ -255,7 +255,7 @@ static int CmdFlashMemSpiFFSDump(const char *Cmd) { errors = true; } - if (destfilenamse[0] == '\0') { + if (destfilename[0] == '\0') { PrintAndLogEx(FAILED, "SPIFFS Filename missing or invalid"); errors = true; } From 5de04f84e9088ca08071385df0d9651f0ec3092a Mon Sep 17 00:00:00 2001 From: mwalker33 Date: Tue, 23 Jul 2019 20:12:05 +1000 Subject: [PATCH 0134/1854] Restored * 8 Revert back to store and use the full value (*8) for the timing. --- armsrc/lfops.c | 63 ++++++++++++++++++++++++--------------------- client/cmdlft55xx.c | 16 +++++++----- include/pm3_cmd.h | 14 +++++----- 3 files changed, 50 insertions(+), 43 deletions(-) diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 6efbc6bd9..17ac49dd2 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -110,19 +110,20 @@ ------------------------------------------------------------------------------------------------------------- */ // Initial values if not in flash +/* // Note: Moved * 8 to apply when used. Saving 28 bytes here (- the *8) and 28 bytes flash. // StartGap WriteGap Bit 0/00 Bit 1/01 Bit 10 Bit 11 ReadGap t55xx_config T55xx_Timing = {{{ 29 , 17 , 15 , 50 , 0 , 0 , 15 }, // Default Fixed { 31 , 20 , 18 , 50 , 0 , 0 , 15 }, // Long Leading Ref. { 31 , 20 , 18 , 40 , 0 , 0 , 15 }, // Leading 0 { 29 , 17 , 15 , 31 , 47 , 63 , 15 } }}; // 1 of 4 -/* +*/ // StartGap WriteGap Bit 0/00 Bit 1/01 Bit 10 Bit 11 ReadGap t55xx_config T55xx_Timing = {{{ 29 * 8 , 17 * 8 , 15 * 8 , 50 * 8 , 0 , 0 , 15 * 8 }, // Default Fixed { 31 * 8 , 20 * 8 , 18 * 8 , 50 * 8 , 0 , 0 , 15 * 8 }, // Long Leading Ref. { 31 * 8 , 20 * 8 , 18 * 8 , 40 * 8 , 0 , 0 , 15 * 8 }, // Leading 0 { 29 * 8 , 17 * 8 , 15 * 8 , 31 * 8 , 47 * 8, 63 * 8, 15 * 8 } }}; // 1 of 4 -*/ + // Some defines for readability #define T55xx_DLMode_Fixed 0 // Default Mode @@ -142,36 +143,37 @@ void printT55xxConfig(void) { case T55xx_DLMode_Leading0 : Dbprintf("r 2 leading zero"); break; case T55xx_DLMode_1of4 : Dbprintf("r 3 1 of 4 coding reference"); break; } - // Save 36 bytes by not showing dec. all data sheets and entry is the x * 8 value, so not sure what we get for the 36 bytes dec? - Dbprintf(" [a] startgap............%d*8", T55xx_Timing.m[DLMode].start_gap );//, T55xx_Timing.start_gap[DLMode]); - Dbprintf(" [b] writegap............%d*8", T55xx_Timing.m[DLMode].write_gap );//, T55xx_Timing.write_gap[DLMode]); - Dbprintf(" [c] write_0.............%d*8", T55xx_Timing.m[DLMode].write_0 );//, T55xx_Timing.write_0 [DLMode]); - Dbprintf(" [d] write_1.............%d*8", T55xx_Timing.m[DLMode].write_1 );//, T55xx_Timing.write_1 [DLMode]); + Dbprintf(" [a] startgap............%d*8 (%d)", T55xx_Timing.m[DLMode].start_gap / 8, T55xx_Timing.m[DLMode].start_gap); + Dbprintf(" [b] writegap............%d*8 (%d)", T55xx_Timing.m[DLMode].write_gap / 8, T55xx_Timing.m[DLMode].write_gap); + Dbprintf(" [c] write_0.............%d*8 (%d)", T55xx_Timing.m[DLMode].write_0 / 8, T55xx_Timing.m[DLMode].write_0 ); + Dbprintf(" [d] write_1.............%d*8 (%d)", T55xx_Timing.m[DLMode].write_1 / 8, T55xx_Timing.m[DLMode].write_1 ); if (DLMode == T55xx_DLMode_1of4) { - Dbprintf(" [e] write_2.............%d*8", T55xx_Timing.m[DLMode].write_2 );//, T55xx_Timing.write_2 [DLMode]); - Dbprintf(" [f] write_3.............%d*8", T55xx_Timing.m[DLMode].write_3 );//, T55xx_Timing.write_3 [DLMode]); + Dbprintf(" [e] write_2.............%d*8 (%d)", T55xx_Timing.m[DLMode].write_2 / 8, T55xx_Timing.m[DLMode].write_2); + Dbprintf(" [f] write_3.............%d*8 (%d)", T55xx_Timing.m[DLMode].write_3 / 8, T55xx_Timing.m[DLMode].write_3); } - Dbprintf(" [g] readgap.............%d*8", T55xx_Timing.m[DLMode].read_gap );//, T55xx_Timing.read_gap [DLMode]); + Dbprintf(" [g] readgap.............%d*8 (%d)", T55xx_Timing.m[DLMode].read_gap / 8, T55xx_Timing.m[DLMode].read_gap); } } void setT55xxConfig(uint8_t arg0, t55xx_config *c) { uint8_t DLMode; +// uint8_t ClearT55Settings = c->m[0].start_gap & 0xffff; // all values will be ffff if clear requested + for (DLMode = 0; DLMode < 4; DLMode++) { - if (c->m[DLMode].start_gap != 0) T55xx_Timing.m[DLMode].start_gap = c->m[DLMode].start_gap; - if (c->m[DLMode].write_gap != 0) T55xx_Timing.m[DLMode].write_gap = c->m[DLMode].write_gap; - if (c->m[DLMode].write_0 != 0) T55xx_Timing.m[DLMode].write_0 = c->m[DLMode].write_0 ; - if (c->m[DLMode].write_1 != 0) T55xx_Timing.m[DLMode].write_1 = c->m[DLMode].write_1 ; + if (c->m[DLMode].start_gap != 0) T55xx_Timing.m[DLMode].start_gap = c->m[DLMode].start_gap;// * 8; + if (c->m[DLMode].write_gap != 0) T55xx_Timing.m[DLMode].write_gap = c->m[DLMode].write_gap;// * 8; + if (c->m[DLMode].write_0 != 0) T55xx_Timing.m[DLMode].write_0 = c->m[DLMode].write_0 ;// * 8; + if (c->m[DLMode].write_1 != 0) T55xx_Timing.m[DLMode].write_1 = c->m[DLMode].write_1 ;// * 8; if (DLMode == T55xx_DLMode_1of4) { - if (c->m[DLMode].write_2 != 0) T55xx_Timing.m[DLMode].write_2 = c->m[DLMode].write_2 ; - if (c->m[DLMode].write_3 != 0) T55xx_Timing.m[DLMode].write_3 = c->m[DLMode].write_3 ; + if (c->m[DLMode].write_2 != 0) T55xx_Timing.m[DLMode].write_2 = c->m[DLMode].write_2;// * 8; + if (c->m[DLMode].write_3 != 0) T55xx_Timing.m[DLMode].write_3 = c->m[DLMode].write_3;// * 8 ; } else{ T55xx_Timing.m[DLMode].write_2 = 0x00; T55xx_Timing.m[DLMode].write_3 = 0x00; } - if (c->m[DLMode].read_gap != 0) T55xx_Timing.m[DLMode].read_gap = c->m[DLMode].read_gap ; + if (c->m[DLMode].read_gap != 0) T55xx_Timing.m[DLMode].read_gap = c->m[DLMode].read_gap;//* 8; } printT55xxConfig(); @@ -186,6 +188,7 @@ void setT55xxConfig(uint8_t arg0, t55xx_config *c) { return; } + uint8_t *buf = BigBuf_malloc(T55XX_CONFIG_LEN); Flash_CheckBusy(BUSY_TIMEOUT); uint16_t res = Flash_ReadDataCont(T55XX_CONFIG_OFFSET, buf, T55XX_CONFIG_LEN); @@ -195,20 +198,21 @@ void setT55xxConfig(uint8_t arg0, t55xx_config *c) { return; } + // if ( ClearT55Settings) // dont copy over new timings memcpy(buf, &T55xx_Timing, T55XX_CONFIG_LEN); - - Flash_CheckBusy(BUSY_TIMEOUT); + + Flash_CheckBusy(BUSY_TIMEOUT); Flash_WriteEnable(); Flash_Erase4k(3, 0xD); // if not a settings erase, write data - if (buf[0] != 0xff) { + // if ( ClearT55Settings) { res = Flash_Write(T55XX_CONFIG_OFFSET, buf, T55XX_CONFIG_LEN); if (res == T55XX_CONFIG_LEN && DBGLEVEL > 1) { DbpString("T55XX Config save success"); } - } +// } BigBuf_free(); #endif @@ -242,7 +246,8 @@ void loadT55xxConfig(void) { return; } - memcpy((uint8_t *)&T55xx_Timing, buf, T55XX_CONFIG_LEN); + if (buf[0] != 0xFF) // if not set for clear + memcpy((uint8_t *)&T55xx_Timing, buf, T55XX_CONFIG_LEN); if (isok == T55XX_CONFIG_LEN) { if (DBGLEVEL > 1) DbpString("T55XX Config load success"); @@ -1477,15 +1482,15 @@ void T55xxWriteBit(uint8_t bit, uint8_t downlink_idx) { // Dbprintf ("%d",bit); // If bit = 4 Send Long Leading Reference which is (138*8) + WRITE_0 switch (bit){ - case 0 : TurnReadLFOn(T55xx_Timing.m[downlink_idx].write_0 * 8); break; // Send bit 0/00 - case 1 : TurnReadLFOn(T55xx_Timing.m[downlink_idx].write_1 * 8); break; // Send bit 1/01 - case 2 : TurnReadLFOn(T55xx_Timing.m[downlink_idx].write_2 * 8); break; // Send bits 10 (1 of 4) - case 3 : TurnReadLFOn(T55xx_Timing.m[downlink_idx].write_3 * 8); break; // Send bits 11 (1 of 4) - case 4 : TurnReadLFOn((T55xx_Timing.m[downlink_idx].write_0 + 136) * 8); break; // Send Long Leading Reference + case 0 : TurnReadLFOn(T55xx_Timing.m[downlink_idx].write_0 ); break; // Send bit 0/00 + case 1 : TurnReadLFOn(T55xx_Timing.m[downlink_idx].write_1 ); break; // Send bit 1/01 + case 2 : TurnReadLFOn(T55xx_Timing.m[downlink_idx].write_2 ); break; // Send bits 10 (1 of 4) + case 3 : TurnReadLFOn(T55xx_Timing.m[downlink_idx].write_3 ); break; // Send bits 11 (1 of 4) + case 4 : TurnReadLFOn(T55xx_Timing.m[downlink_idx].write_0 + (136 * 8)); break; // Send Long Leading Reference } FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - WaitUS(T55xx_Timing.m[downlink_idx].write_gap * 8); + WaitUS(T55xx_Timing.m[downlink_idx].write_gap ); } // Function to abstract an Arbitrary length byte array to store bit pattern. @@ -1632,7 +1637,7 @@ void T55xxResetRead(uint8_t flags) { T55xx_SendCMD (0, 0, arg); - TurnReadLFOn(T55xx_Timing.m[downlink_mode].read_gap * 8); + TurnReadLFOn(T55xx_Timing.m[downlink_mode].read_gap); // Acquisition DoPartialAcquisition(0, true, BigBuf_max_traceLen(), 0); diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 811a78b70..bb8463692 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -2606,18 +2606,20 @@ static int CmdT55xxSetDeviceConfig(const char *Cmd) { // printf ("DLmode %d\n",downlink_mode); t55xx_config conf = {0}; + printf ("Size conf %lld\n",sizeof(conf)); if (erase) { memset (&conf,0xff, sizeof(conf)); + printf ("Conf.m[0] %x\n",conf.m[0].start_gap); } else { - conf.m[downlink_mode].start_gap = startgap;// * 8; - conf.m[downlink_mode].write_gap = writegap;// * 8; - conf.m[downlink_mode].write_0 = write0 ;// * 8; - conf.m[downlink_mode].write_1 = write1 ;// * 8; - conf.m[downlink_mode].write_2 = write2 ;// * 8; - conf.m[downlink_mode].write_3 = write3 ;// * 8; - conf.m[downlink_mode].read_gap = readgap ;// * 8; + conf.m[downlink_mode].start_gap = startgap * 8; + conf.m[downlink_mode].write_gap = writegap * 8; + conf.m[downlink_mode].write_0 = write0 * 8; + conf.m[downlink_mode].write_1 = write1 * 8; + conf.m[downlink_mode].write_2 = write2 * 8; + conf.m[downlink_mode].write_3 = write3 * 8; + conf.m[downlink_mode].read_gap = readgap * 8; } clearCommandBuffer(); SendCommandOLD(CMD_SET_LF_T55XX_CONFIG, shall_persist, 0, 0, &conf, sizeof(t55xx_config)); diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 297d52337..0b454eb87 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -131,13 +131,13 @@ typedef struct { // Extended to support 1 of 4 timing typedef struct { - uint8_t start_gap ; - uint8_t write_gap ; - uint8_t write_0 ; - uint8_t write_1 ; - uint8_t write_2 ; - uint8_t write_3 ; - uint8_t read_gap ; + uint16_t start_gap ; + uint16_t write_gap ; + uint16_t write_0 ; + uint16_t write_1 ; + uint16_t write_2 ; + uint16_t write_3 ; + uint16_t read_gap ; } t55xx_config_t; // This setup will allow for the 4 downlink modes "m" as well as other items if needed. // Given the one struct we can then read/write to flash/client in one go. From 9beabaabf528f5e39e399e86d9b9f4610135d268 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 23 Jul 2019 21:33:52 +0200 Subject: [PATCH 0135/1854] make style --- armsrc/Standalone/hf_colin.c | 12 +- armsrc/appmain.c | 110 +- armsrc/spiffs.c | 71 +- armsrc/spiffs.h | 249 ++- armsrc/spiffs_cache.c | 422 ++-- armsrc/spiffs_check.c | 1694 ++++++++-------- armsrc/spiffs_config.h | 12 +- armsrc/spiffs_gc.c | 988 +++++----- armsrc/spiffs_hydrogen.c | 2012 +++++++++---------- armsrc/spiffs_nucleus.c | 3537 +++++++++++++++++----------------- armsrc/spiffs_nucleus.h | 167 +- armsrc/string.c | 135 +- armsrc/string.h | 4 +- client/cmddata.c | 6 +- client/cmdflashmem.c | 2 +- client/cmdflashmemspiffs.c | 99 +- client/cmdhffelica.c | 2 +- client/cmdhficlass.c | 4 +- client/cmdhflegic.c | 6 +- client/cmdhfmf.c | 2 +- client/cmdhfmfu.c | 2 +- client/cmdlfcotag.c | 2 +- client/cmdlfem4x.c | 2 +- client/cmdlft55xx.c | 2 +- client/cmdtrace.c | 4 +- client/comms.c | 4 +- client/flash.c | 4 +- client/scripting.c | 4 +- include/pm3_cmd.h | 4 +- 29 files changed, 4784 insertions(+), 4778 deletions(-) diff --git a/armsrc/Standalone/hf_colin.c b/armsrc/Standalone/hf_colin.c index 2189f1146..bd184fad6 100644 --- a/armsrc/Standalone/hf_colin.c +++ b/armsrc/Standalone/hf_colin.c @@ -102,7 +102,7 @@ void ReadLastTagFromFlash() { uint8_t *mem = BigBuf_malloc(size); //this one will handle filetype (symlink or not) and resolving by itself - rdv40_spiffs_read_as_filetype((char *)HFCOLIN_LASTTAG_SYMLINK,(uint8_t *)mem,len, RDV40_SPIFFS_SAFETY_SAFE); + rdv40_spiffs_read_as_filetype((char *)HFCOLIN_LASTTAG_SYMLINK, (uint8_t *)mem, len, RDV40_SPIFFS_SAFETY_SAFE); emlSetMem(mem, 0, 64); @@ -126,14 +126,14 @@ void WriteTagToFlash(uint32_t uid, size_t size) { char dest[SPIFFS_OBJ_NAME_LEN]; uint8_t buid[4]; - num_to_bytes(uid,4,buid); - sprintf(dest,"hf_colin/mf_%02x%02x%02x%02x.bin",buid[0],buid[1],buid[2],buid[3]); - + num_to_bytes(uid, 4, buid); + sprintf(dest, "hf_colin/mf_%02x%02x%02x%02x.bin", buid[0], buid[1], buid[2], buid[3]); + // TODO : by using safe function for multiple writes we are both breaking cache mecanisms and making useless and unoptimized mount operations // we should manage at out level the mount status before and after the whole standalone mode - rdv40_spiffs_write((char *)dest,(uint8_t *)data,len, RDV40_SPIFFS_SAFETY_SAFE); + rdv40_spiffs_write((char *)dest, (uint8_t *)data, len, RDV40_SPIFFS_SAFETY_SAFE); // lastag will only contain filename/path to last written tag file so we don't loose time or space. - rdv40_spiffs_make_symlink((char *)dest,(char *)HFCOLIN_LASTTAG_SYMLINK,RDV40_SPIFFS_SAFETY_SAFE); + rdv40_spiffs_make_symlink((char *)dest, (char *)HFCOLIN_LASTTAG_SYMLINK, RDV40_SPIFFS_SAFETY_SAFE); DbprintfEx(FLAG_NEWLINE, "[OK] TAG WRITTEN TO FLASH !"); cjSetCursLeft(); diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 59174153f..7128c4a2f 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1591,13 +1591,13 @@ static void PacketReceived(PacketCommandNG *packet) { } #ifdef WITH_FLASH case CMD_SPIFFS_TEST: { - test_spiffs(); - break; + test_spiffs(); + break; } case CMD_SPIFFS_MOUNT: { - rdv40_spiffs_lazy_mount(); - break; - } + rdv40_spiffs_lazy_mount(); + break; + } case CMD_SPIFFS_UNMOUNT: { rdv40_spiffs_lazy_unmount(); break; @@ -1606,24 +1606,24 @@ static void PacketReceived(PacketCommandNG *packet) { rdv40_spiffs_safe_print_tree(false); break; } - case CMD_SPIFFS_PRINT_FSINFO: { - rdv40_spiffs_safe_print_fsinfos(); - break; - } + case CMD_SPIFFS_PRINT_FSINFO: { + rdv40_spiffs_safe_print_fsinfos(); + break; + } case CMD_SPIFFS_DOWNLOAD: { LED_B_ON(); uint8_t filename[32]; uint8_t *pfilename = packet->data.asBytes; - memcpy(filename,pfilename,SPIFFS_OBJ_NAME_LEN); - if (DBGLEVEL > 1) Dbprintf("> Filename received for spiffs dump : %s", filename); - - //uint32_t size = 0; + memcpy(filename, pfilename, SPIFFS_OBJ_NAME_LEN); + if (DBGLEVEL > 1) Dbprintf("> Filename received for spiffs dump : %s", filename); + + //uint32_t size = 0; //rdv40_spiffs_stat((char *)filename, (uint32_t *)size,RDV40_SPIFFS_SAFETY_SAFE); uint32_t size = packet->oldarg[1]; //uint8_t buff[size]; uint8_t *buff = BigBuf_malloc(size); - rdv40_spiffs_read_as_filetype((char *)filename,(uint8_t *)buff, size, RDV40_SPIFFS_SAFETY_SAFE); + rdv40_spiffs_read_as_filetype((char *)filename, (uint8_t *)buff, size, RDV40_SPIFFS_SAFETY_SAFE); // arg0 = filename // arg1 = size @@ -1640,59 +1640,59 @@ static void PacketReceived(PacketCommandNG *packet) { LED_B_OFF(); break; } - case CMD_SPIFFS_STAT:{ + case CMD_SPIFFS_STAT: { LED_B_ON(); uint8_t filename[32]; uint8_t *pfilename = packet->data.asBytes; - memcpy(filename,pfilename,SPIFFS_OBJ_NAME_LEN); - if (DBGLEVEL > 1) Dbprintf("> Filename received for spiffs STAT : %s", filename); + memcpy(filename, pfilename, SPIFFS_OBJ_NAME_LEN); + if (DBGLEVEL > 1) Dbprintf("> Filename received for spiffs STAT : %s", filename); int changed = rdv40_spiffs_lazy_mount(); uint32_t size = size_in_spiffs((char *)filename); if (changed) rdv40_spiffs_lazy_unmount(); - reply_old(CMD_ACK, size, 0, 0, 0, 0); + reply_old(CMD_ACK, size, 0, 0, 0, 0); LED_B_OFF(); break; } - case CMD_SPIFFS_REMOVE:{ - LED_B_ON(); - uint8_t filename[32]; - uint8_t *pfilename = packet->data.asBytes; - memcpy(filename,pfilename,SPIFFS_OBJ_NAME_LEN); - if (DBGLEVEL > 1) Dbprintf("> Filename received for spiffs REMOVE : %s", filename); - rdv40_spiffs_remove((char *) filename,RDV40_SPIFFS_SAFETY_SAFE); - LED_B_OFF(); - break; - } - case CMD_SPIFFS_RENAME:{ + case CMD_SPIFFS_REMOVE: { LED_B_ON(); - uint8_t srcfilename[32]; - uint8_t destfilename[32]; + uint8_t filename[32]; uint8_t *pfilename = packet->data.asBytes; - char *token; - token = strtok((char *)pfilename, ","); - strcpy((char*)srcfilename,token); - token = strtok(NULL,","); - strcpy((char *)destfilename,token); - if (DBGLEVEL > 1) Dbprintf("> Filename received as source for spiffs RENAME : %s", srcfilename); - if (DBGLEVEL > 1) Dbprintf("> Filename received as destination for spiffs RENAME : %s", destfilename); - rdv40_spiffs_rename((char *) srcfilename,(char *)destfilename,RDV40_SPIFFS_SAFETY_SAFE); - LED_B_OFF(); + memcpy(filename, pfilename, SPIFFS_OBJ_NAME_LEN); + if (DBGLEVEL > 1) Dbprintf("> Filename received for spiffs REMOVE : %s", filename); + rdv40_spiffs_remove((char *) filename, RDV40_SPIFFS_SAFETY_SAFE); + LED_B_OFF(); break; } - case CMD_SPIFFS_COPY:{ + case CMD_SPIFFS_RENAME: { LED_B_ON(); uint8_t srcfilename[32]; uint8_t destfilename[32]; uint8_t *pfilename = packet->data.asBytes; char *token; token = strtok((char *)pfilename, ","); - strcpy((char*)srcfilename,token); - token = strtok(NULL,","); - strcpy((char *)destfilename,token); + strcpy((char *)srcfilename, token); + token = strtok(NULL, ","); + strcpy((char *)destfilename, token); + if (DBGLEVEL > 1) Dbprintf("> Filename received as source for spiffs RENAME : %s", srcfilename); + if (DBGLEVEL > 1) Dbprintf("> Filename received as destination for spiffs RENAME : %s", destfilename); + rdv40_spiffs_rename((char *) srcfilename, (char *)destfilename, RDV40_SPIFFS_SAFETY_SAFE); + LED_B_OFF(); + break; + } + case CMD_SPIFFS_COPY: { + LED_B_ON(); + uint8_t srcfilename[32]; + uint8_t destfilename[32]; + uint8_t *pfilename = packet->data.asBytes; + char *token; + token = strtok((char *)pfilename, ","); + strcpy((char *)srcfilename, token); + token = strtok(NULL, ","); + strcpy((char *)destfilename, token); if (DBGLEVEL > 1) Dbprintf("> Filename received as source for spiffs COPY : %s", srcfilename); if (DBGLEVEL > 1) Dbprintf("> Filename received as destination for spiffs COPY : %s", destfilename); - rdv40_spiffs_copy((char *) srcfilename,(char *)destfilename,RDV40_SPIFFS_SAFETY_SAFE); - LED_B_OFF(); + rdv40_spiffs_copy((char *) srcfilename, (char *)destfilename, RDV40_SPIFFS_SAFETY_SAFE); + LED_B_OFF(); break; } case CMD_SPIFFS_WRITE: { @@ -1702,18 +1702,18 @@ static void PacketReceived(PacketCommandNG *packet) { uint32_t size = packet->oldarg[1]; uint8_t *data = packet->data.asBytes; - //rdv40_spiffs_lazy_mount(); + //rdv40_spiffs_lazy_mount(); uint8_t *pfilename = packet->data.asBytes; - memcpy(filename,pfilename,SPIFFS_OBJ_NAME_LEN); - data+=SPIFFS_OBJ_NAME_LEN; + memcpy(filename, pfilename, SPIFFS_OBJ_NAME_LEN); + data += SPIFFS_OBJ_NAME_LEN; - if (DBGLEVEL > 1) Dbprintf("> Filename received for spiffs WRITE : %s with APPEND SET TO : %d", filename, append); - if (!append) { - rdv40_spiffs_write((char *) filename,(uint8_t *)data, size, RDV40_SPIFFS_SAFETY_SAFE); - } else { - rdv40_spiffs_append((char *) filename,(uint8_t *)data, size, RDV40_SPIFFS_SAFETY_SAFE); - } + if (DBGLEVEL > 1) Dbprintf("> Filename received for spiffs WRITE : %s with APPEND SET TO : %d", filename, append); + if (!append) { + rdv40_spiffs_write((char *) filename, (uint8_t *)data, size, RDV40_SPIFFS_SAFETY_SAFE); + } else { + rdv40_spiffs_append((char *) filename, (uint8_t *)data, size, RDV40_SPIFFS_SAFETY_SAFE); + } reply_old(CMD_ACK, 1, 0, 0, 0, 0); LED_B_OFF(); break; diff --git a/armsrc/spiffs.c b/armsrc/spiffs.c index b5db53c42..0fecc556c 100644 --- a/armsrc/spiffs.c +++ b/armsrc/spiffs.c @@ -107,13 +107,13 @@ int rdv40_spiffs_mounted() { int ret = 0; switch (RDV40_SPIFFS_MOUNT_STATUS) { - case RDV40_SPIFFS_MOUNTED: - ret = 1; - break; - case RDV40_SPIFFS_UNMOUNTED: - case RDV40_SPIFFS_UNKNOWN: - default: - ret = 0; + case RDV40_SPIFFS_MOUNTED: + ret = 1; + break; + case RDV40_SPIFFS_UNMOUNTED: + case RDV40_SPIFFS_UNKNOWN: + default: + ret = 0; } return ret; @@ -240,18 +240,18 @@ RDV40SpiFFSFileType filetype_in_spiffs(const char *filename) { } if (DBGLEVEL > 1) { switch (filetype) { - case RDV40_SPIFFS_FILETYPE_REAL: - Dbprintf("Filetype is : RDV40_SPIFFS_FILETYPE_REAL"); - break; - case RDV40_SPIFFS_FILETYPE_SYMLINK: - Dbprintf("Filetype is : RDV40_SPIFFS_FILETYPE_SYMLINK"); - break; - case RDV40_SPIFFS_FILETYPE_BOTH: - Dbprintf("Filetype is : RDV40_SPIFFS_FILETYPE_BOTH"); - break; - case RDV40_SPIFFS_FILETYPE_UNKNOWN: - Dbprintf("Filetype is : RDV40_SPIFFS_FILETYPE_UNKNOWN"); - break; + case RDV40_SPIFFS_FILETYPE_REAL: + Dbprintf("Filetype is : RDV40_SPIFFS_FILETYPE_REAL"); + break; + case RDV40_SPIFFS_FILETYPE_SYMLINK: + Dbprintf("Filetype is : RDV40_SPIFFS_FILETYPE_SYMLINK"); + break; + case RDV40_SPIFFS_FILETYPE_BOTH: + Dbprintf("Filetype is : RDV40_SPIFFS_FILETYPE_BOTH"); + break; + case RDV40_SPIFFS_FILETYPE_UNKNOWN: + Dbprintf("Filetype is : RDV40_SPIFFS_FILETYPE_UNKNOWN"); + break; } } return filetype; @@ -426,13 +426,13 @@ int rdv40_spiffs_copy(char *src, char *dst, RDV40SpiFFSSafetyLevel level) { int rdv40_spiffs_stat(char *filename, uint32_t *buf, RDV40SpiFFSSafetyLevel level) { RDV40_SPIFFS_SAFE_FUNCTION( // - *buf = size_in_spiffs((char *)filename); // + *buf = size_in_spiffs((char *)filename); // ) } int rdv40_spiffs_getfsinfo(rdv40_spiffs_fsinfo *fsinfo, RDV40SpiFFSSafetyLevel level) { RDV40_SPIFFS_SAFE_FUNCTION( // - *fsinfo = info_of_spiffs(); // + *fsinfo = info_of_spiffs(); // ) } @@ -465,9 +465,9 @@ int rdv40_spiffs_read_as_symlink(char *filename, uint8_t *dst, uint32_t size, RD if (DBGLEVEL > 1) Dbprintf("Linkk real filename is destination is : %s", linkfilename); read_from_spiffs((char *)linkfilename, (uint8_t *)linkdest, SPIFFS_OBJ_NAME_LEN); if (DBGLEVEL > 1) Dbprintf("Symlink destination is : %s", linkdest); - read_from_spiffs((char *)linkdest, (uint8_t *)dst, size); // - ) -} + read_from_spiffs((char *)linkdest, (uint8_t *)dst, size); // + ) + } // BEWARE ! This function is DESTRUCTIVE as it will UPDATE an existing symlink // Since it creates a .lnk extension file it may be minor to mistake the order of arguments @@ -498,17 +498,18 @@ int rdv40_spiffs_make_symlink(char *linkdest, char *filename, RDV40SpiFFSSafetyL int rdv40_spiffs_read_as_filetype(char *filename, uint8_t *dst, uint32_t size, RDV40SpiFFSSafetyLevel level) { RDV40_SPIFFS_SAFE_FUNCTION( // RDV40SpiFFSFileType filetype = filetype_in_spiffs((char *)filename); // - switch (filetype) { - case RDV40_SPIFFS_FILETYPE_REAL: - rdv40_spiffs_read((char *)filename, (uint8_t *)dst, size, level); - break; - case RDV40_SPIFFS_FILETYPE_SYMLINK: - rdv40_spiffs_read_as_symlink((char *)filename, (uint8_t *)dst, size, level); - break; - case RDV40_SPIFFS_FILETYPE_BOTH: - case RDV40_SPIFFS_FILETYPE_UNKNOWN: - default:; - } // + switch (filetype) { + case RDV40_SPIFFS_FILETYPE_REAL: + rdv40_spiffs_read((char *)filename, (uint8_t *)dst, size, level); + break; + case RDV40_SPIFFS_FILETYPE_SYMLINK: + rdv40_spiffs_read_as_symlink((char *)filename, (uint8_t *)dst, size, level); + break; + case RDV40_SPIFFS_FILETYPE_BOTH: + case RDV40_SPIFFS_FILETYPE_UNKNOWN: + default: + ; + } // ) } diff --git a/armsrc/spiffs.h b/armsrc/spiffs.h index e0bbbe68c..b9308f4dd 100644 --- a/armsrc/spiffs.h +++ b/armsrc/spiffs.h @@ -22,15 +22,14 @@ typedef enum spiffs_file_type { RDV40_SPIFFS_FILETYPE_UNKNOWN } RDV40SpiFFSFileType; -typedef struct rdv40_spiffs_fsinfo - { - uint32_t blockSize; - uint32_t pageSize; - uint32_t maxOpenFiles; - uint32_t maxPathLenght; - uint32_t totalBytes, usedBytes, freeBytes; - uint32_t usedPercent, freePercent; - } rdv40_spiffs_fsinfo; +typedef struct rdv40_spiffs_fsinfo { + uint32_t blockSize; + uint32_t pageSize; + uint32_t maxOpenFiles; + uint32_t maxPathLenght; + uint32_t totalBytes, usedBytes, freeBytes; + uint32_t usedPercent, freePercent; +} rdv40_spiffs_fsinfo; int rdv40_spiffs_read_as_filetype(char *filename, uint8_t *dst, uint32_t size, RDV40SpiFFSSafetyLevel level); @@ -145,39 +144,39 @@ typedef s32_t (*spiffs_erase)(u32_t addr, u32_t size); /* file system check callback report operation */ typedef enum { - SPIFFS_CHECK_LOOKUP = 0, - SPIFFS_CHECK_INDEX, - SPIFFS_CHECK_PAGE + SPIFFS_CHECK_LOOKUP = 0, + SPIFFS_CHECK_INDEX, + SPIFFS_CHECK_PAGE } spiffs_check_type; /* file system check callback report type */ typedef enum { - SPIFFS_CHECK_PROGRESS = 0, - SPIFFS_CHECK_ERROR, - SPIFFS_CHECK_FIX_INDEX, - SPIFFS_CHECK_FIX_LOOKUP, - SPIFFS_CHECK_DELETE_ORPHANED_INDEX, - SPIFFS_CHECK_DELETE_PAGE, - SPIFFS_CHECK_DELETE_BAD_FILE + SPIFFS_CHECK_PROGRESS = 0, + SPIFFS_CHECK_ERROR, + SPIFFS_CHECK_FIX_INDEX, + SPIFFS_CHECK_FIX_LOOKUP, + SPIFFS_CHECK_DELETE_ORPHANED_INDEX, + SPIFFS_CHECK_DELETE_PAGE, + SPIFFS_CHECK_DELETE_BAD_FILE } spiffs_check_report; /* file system check callback function */ #if SPIFFS_HAL_CALLBACK_EXTRA typedef void (*spiffs_check_callback)(struct spiffs_t *fs, spiffs_check_type type, spiffs_check_report report, - u32_t arg1, u32_t arg2); + u32_t arg1, u32_t arg2); #else // SPIFFS_HAL_CALLBACK_EXTRA typedef void (*spiffs_check_callback)(spiffs_check_type type, spiffs_check_report report, - u32_t arg1, u32_t arg2); + u32_t arg1, u32_t arg2); #endif // SPIFFS_HAL_CALLBACK_EXTRA /* file system listener callback operation */ typedef enum { - /* the file has been created */ - SPIFFS_CB_CREATED = 0, - /* the file has been updated or moved to another page */ - SPIFFS_CB_UPDATED, - /* the file has been deleted */ - SPIFFS_CB_DELETED + /* the file has been created */ + SPIFFS_CB_CREATED = 0, + /* the file has been updated or moved to another page */ + SPIFFS_CB_UPDATED, + /* the file has been deleted */ + SPIFFS_CB_DELETED } spiffs_fileop_type; /* file system listener callback function */ @@ -243,141 +242,141 @@ typedef void (*spiffs_file_callback)(struct spiffs_t *fs, spiffs_fileop_type op, // spiffs spi configuration struct typedef struct { - // physical read function - spiffs_read hal_read_f; - // physical write function - spiffs_write hal_write_f; - // physical erase function - spiffs_erase hal_erase_f; + // physical read function + spiffs_read hal_read_f; + // physical write function + spiffs_write hal_write_f; + // physical erase function + spiffs_erase hal_erase_f; #if SPIFFS_SINGLETON == 0 - // physical size of the spi flash - u32_t phys_size; - // physical offset in spi flash used for spiffs, - // must be on block boundary - u32_t phys_addr; - // physical size when erasing a block - u32_t phys_erase_block; + // physical size of the spi flash + u32_t phys_size; + // physical offset in spi flash used for spiffs, + // must be on block boundary + u32_t phys_addr; + // physical size when erasing a block + u32_t phys_erase_block; - // logical size of a block, must be on physical - // block size boundary and must never be less than - // a physical block - u32_t log_block_size; - // logical size of a page, must be at least - // log_block_size / 8 - u32_t log_page_size; + // logical size of a block, must be on physical + // block size boundary and must never be less than + // a physical block + u32_t log_block_size; + // logical size of a page, must be at least + // log_block_size / 8 + u32_t log_page_size; #endif #if SPIFFS_FILEHDL_OFFSET - // an integer offset added to each file handle - u16_t fh_ix_offset; + // an integer offset added to each file handle + u16_t fh_ix_offset; #endif } spiffs_config; typedef struct spiffs_t { - // file system configuration - spiffs_config cfg; - // number of logical blocks - u32_t block_count; + // file system configuration + spiffs_config cfg; + // number of logical blocks + u32_t block_count; - // cursor for free blocks, block index - spiffs_block_ix free_cursor_block_ix; - // cursor for free blocks, entry index - int free_cursor_obj_lu_entry; - // cursor when searching, block index - spiffs_block_ix cursor_block_ix; - // cursor when searching, entry index - int cursor_obj_lu_entry; + // cursor for free blocks, block index + spiffs_block_ix free_cursor_block_ix; + // cursor for free blocks, entry index + int free_cursor_obj_lu_entry; + // cursor when searching, block index + spiffs_block_ix cursor_block_ix; + // cursor when searching, entry index + int cursor_obj_lu_entry; - // primary work buffer, size of a logical page - u8_t *lu_work; - // secondary work buffer, size of a logical page - u8_t *work; - // file descriptor memory area - u8_t *fd_space; - // available file descriptors - u32_t fd_count; + // primary work buffer, size of a logical page + u8_t *lu_work; + // secondary work buffer, size of a logical page + u8_t *work; + // file descriptor memory area + u8_t *fd_space; + // available file descriptors + u32_t fd_count; - // last error - s32_t err_code; + // last error + s32_t err_code; - // current number of free blocks - u32_t free_blocks; - // current number of busy pages - u32_t stats_p_allocated; - // current number of deleted pages - u32_t stats_p_deleted; - // flag indicating that garbage collector is cleaning - u8_t cleaning; - // max erase count amongst all blocks - spiffs_obj_id max_erase_count; + // current number of free blocks + u32_t free_blocks; + // current number of busy pages + u32_t stats_p_allocated; + // current number of deleted pages + u32_t stats_p_deleted; + // flag indicating that garbage collector is cleaning + u8_t cleaning; + // max erase count amongst all blocks + spiffs_obj_id max_erase_count; #if SPIFFS_GC_STATS - u32_t stats_gc_runs; + u32_t stats_gc_runs; #endif #if SPIFFS_CACHE - // cache memory - void *cache; - // cache size - u32_t cache_size; + // cache memory + void *cache; + // cache size + u32_t cache_size; #if SPIFFS_CACHE_STATS - u32_t cache_hits; - u32_t cache_misses; + u32_t cache_hits; + u32_t cache_misses; #endif #endif - // check callback function - spiffs_check_callback check_cb_f; - // file callback function - spiffs_file_callback file_cb_f; - // mounted flag - u8_t mounted; - // user data - void *user_data; - // config magic - u32_t config_magic; + // check callback function + spiffs_check_callback check_cb_f; + // file callback function + spiffs_file_callback file_cb_f; + // mounted flag + u8_t mounted; + // user data + void *user_data; + // config magic + u32_t config_magic; } spiffs; /* spiffs file status struct */ typedef struct { - spiffs_obj_id obj_id; - u32_t size; - spiffs_obj_type type; - spiffs_page_ix pix; - u8_t name[SPIFFS_OBJ_NAME_LEN]; + spiffs_obj_id obj_id; + u32_t size; + spiffs_obj_type type; + spiffs_page_ix pix; + u8_t name[SPIFFS_OBJ_NAME_LEN]; #if SPIFFS_OBJ_META_LEN - u8_t meta[SPIFFS_OBJ_META_LEN]; + u8_t meta[SPIFFS_OBJ_META_LEN]; #endif } spiffs_stat; struct spiffs_dirent { - spiffs_obj_id obj_id; - u8_t name[SPIFFS_OBJ_NAME_LEN]; - spiffs_obj_type type; - u32_t size; - spiffs_page_ix pix; + spiffs_obj_id obj_id; + u8_t name[SPIFFS_OBJ_NAME_LEN]; + spiffs_obj_type type; + u32_t size; + spiffs_page_ix pix; #if SPIFFS_OBJ_META_LEN - u8_t meta[SPIFFS_OBJ_META_LEN]; + u8_t meta[SPIFFS_OBJ_META_LEN]; #endif }; typedef struct { - spiffs *fs; - spiffs_block_ix block; - int entry; + spiffs *fs; + spiffs_block_ix block; + int entry; } spiffs_DIR; #if SPIFFS_IX_MAP typedef struct { - // buffer with looked up data pixes - spiffs_page_ix *map_buf; - // precise file byte offset - u32_t offset; - // start data span index of lookup buffer - spiffs_span_ix start_spix; - // end data span index of lookup buffer - spiffs_span_ix end_spix; + // buffer with looked up data pixes + spiffs_page_ix *map_buf; + // precise file byte offset + u32_t offset; + // start data span index of lookup buffer + spiffs_span_ix start_spix; + // end data span index of lookup buffer + spiffs_span_ix end_spix; } spiffs_ix_map; #endif @@ -434,9 +433,9 @@ s32_t SPIFFS_probe_fs(spiffs_config *config); * @param check_cb_f callback function for reporting during consistency checks */ s32_t SPIFFS_mount(spiffs *fs, spiffs_config *config, u8_t *work, - u8_t *fd_space, u32_t fd_space_size, - void *cache, u32_t cache_size, - spiffs_check_callback check_cb_f); + u8_t *fd_space, u32_t fd_space_size, + void *cache, u32_t cache_size, + spiffs_check_callback check_cb_f); /** * Unmounts the file system. All file handles will be flushed of any @@ -779,7 +778,7 @@ s32_t SPIFFS_set_file_callback_func(spiffs *fs, spiffs_file_callback cb_func); * SPIFFS_bytes_to_ix_map_entries given the length */ s32_t SPIFFS_ix_map(spiffs *fs, spiffs_file fh, spiffs_ix_map *map, - u32_t offset, u32_t len, spiffs_page_ix *map_buf); + u32_t offset, u32_t len, spiffs_page_ix *map_buf); /** * Unmaps the index lookup from this filehandle. All future readings will diff --git a/armsrc/spiffs_cache.c b/armsrc/spiffs_cache.c index ad9995eae..f86133be4 100644 --- a/armsrc/spiffs_cache.c +++ b/armsrc/spiffs_cache.c @@ -12,109 +12,109 @@ // returns cached page for give page index, or null if no such cached page static spiffs_cache_page *spiffs_cache_page_get(spiffs *fs, spiffs_page_ix pix) { - spiffs_cache *cache = spiffs_get_cache(fs); - if ((cache->cpage_use_map & cache->cpage_use_mask) == 0) return 0; - int i; - for (i = 0; i < cache->cpage_count; i++) { - spiffs_cache_page *cp = spiffs_get_cache_page_hdr(fs, cache, i); - if ((cache->cpage_use_map & (1<flags & SPIFFS_CACHE_FLAG_TYPE_WR) == 0 && - cp->ucache.spix.pix == pix ) { - //SPIFFS_CACHE_DBG("CACHE_GET: have cache page "_SPIPRIi" for "_SPIPRIpg"\n", i, pix); - cp->last_access = cache->last_access; - return cp; + spiffs_cache *cache = spiffs_get_cache(fs); + if ((cache->cpage_use_map & cache->cpage_use_mask) == 0) return 0; + int i; + for (i = 0; i < cache->cpage_count; i++) { + spiffs_cache_page *cp = spiffs_get_cache_page_hdr(fs, cache, i); + if ((cache->cpage_use_map & (1 << i)) && + (cp->flags & SPIFFS_CACHE_FLAG_TYPE_WR) == 0 && + cp->ucache.spix.pix == pix) { + //SPIFFS_CACHE_DBG("CACHE_GET: have cache page "_SPIPRIi" for "_SPIPRIpg"\n", i, pix); + cp->last_access = cache->last_access; + return cp; + } } - } - //SPIFFS_CACHE_DBG("CACHE_GET: no cache for "_SPIPRIpg"\n", pix); - return 0; + //SPIFFS_CACHE_DBG("CACHE_GET: no cache for "_SPIPRIpg"\n", pix); + return 0; } // frees cached page static s32_t spiffs_cache_page_free(spiffs *fs, int ix, u8_t write_back) { - s32_t res = SPIFFS_OK; - spiffs_cache *cache = spiffs_get_cache(fs); - spiffs_cache_page *cp = spiffs_get_cache_page_hdr(fs, cache, ix); - if (cache->cpage_use_map & (1<flags & SPIFFS_CACHE_FLAG_TYPE_WR) == 0 && - (cp->flags & SPIFFS_CACHE_FLAG_DIRTY)) { - u8_t *mem = spiffs_get_cache_page(fs, cache, ix); - SPIFFS_CACHE_DBG("CACHE_FREE: write cache page "_SPIPRIi" pix "_SPIPRIpg"\n", ix, cp->pix); - res = SPIFFS_HAL_WRITE(fs, SPIFFS_PAGE_TO_PADDR(fs, cp->ucache.spix.pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), mem); - } + s32_t res = SPIFFS_OK; + spiffs_cache *cache = spiffs_get_cache(fs); + spiffs_cache_page *cp = spiffs_get_cache_page_hdr(fs, cache, ix); + if (cache->cpage_use_map & (1 << ix)) { + if (write_back && + (cp->flags & SPIFFS_CACHE_FLAG_TYPE_WR) == 0 && + (cp->flags & SPIFFS_CACHE_FLAG_DIRTY)) { + u8_t *mem = spiffs_get_cache_page(fs, cache, ix); + SPIFFS_CACHE_DBG("CACHE_FREE: write cache page "_SPIPRIi" pix "_SPIPRIpg"\n", ix, cp->pix); + res = SPIFFS_HAL_WRITE(fs, SPIFFS_PAGE_TO_PADDR(fs, cp->ucache.spix.pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), mem); + } #if SPIFFS_CACHE_WR - if (cp->flags & SPIFFS_CACHE_FLAG_TYPE_WR) { - SPIFFS_CACHE_DBG("CACHE_FREE: free cache page "_SPIPRIi" objid "_SPIPRIid"\n", ix, cp->obj_id); - } else + if (cp->flags & SPIFFS_CACHE_FLAG_TYPE_WR) { + SPIFFS_CACHE_DBG("CACHE_FREE: free cache page "_SPIPRIi" objid "_SPIPRIid"\n", ix, cp->obj_id); + } else #endif - { - SPIFFS_CACHE_DBG("CACHE_FREE: free cache page "_SPIPRIi" pix "_SPIPRIpg"\n", ix, cp->pix); + { + SPIFFS_CACHE_DBG("CACHE_FREE: free cache page "_SPIPRIi" pix "_SPIPRIpg"\n", ix, cp->pix); + } + cache->cpage_use_map &= ~(1 << ix); + cp->flags = 0; } - cache->cpage_use_map &= ~(1 << ix); - cp->flags = 0; - } - return res; + return res; } // removes the oldest accessed cached page static s32_t spiffs_cache_page_remove_oldest(spiffs *fs, u8_t flag_mask, u8_t flags) { - s32_t res = SPIFFS_OK; - spiffs_cache *cache = spiffs_get_cache(fs); + s32_t res = SPIFFS_OK; + spiffs_cache *cache = spiffs_get_cache(fs); - if ((cache->cpage_use_map & cache->cpage_use_mask) != cache->cpage_use_mask) { - // at least one free cpage - return SPIFFS_OK; - } - - // all busy, scan thru all to find the cpage which has oldest access - int i; - int cand_ix = -1; - u32_t oldest_val = 0; - for (i = 0; i < cache->cpage_count; i++) { - spiffs_cache_page *cp = spiffs_get_cache_page_hdr(fs, cache, i); - if ((cache->last_access - cp->last_access) > oldest_val && - (cp->flags & flag_mask) == flags) { - oldest_val = cache->last_access - cp->last_access; - cand_ix = i; + if ((cache->cpage_use_map & cache->cpage_use_mask) != cache->cpage_use_mask) { + // at least one free cpage + return SPIFFS_OK; } - } - if (cand_ix >= 0) { - res = spiffs_cache_page_free(fs, cand_ix, 1); - } + // all busy, scan thru all to find the cpage which has oldest access + int i; + int cand_ix = -1; + u32_t oldest_val = 0; + for (i = 0; i < cache->cpage_count; i++) { + spiffs_cache_page *cp = spiffs_get_cache_page_hdr(fs, cache, i); + if ((cache->last_access - cp->last_access) > oldest_val && + (cp->flags & flag_mask) == flags) { + oldest_val = cache->last_access - cp->last_access; + cand_ix = i; + } + } - return res; + if (cand_ix >= 0) { + res = spiffs_cache_page_free(fs, cand_ix, 1); + } + + return res; } // allocates a new cached page and returns it, or null if all cache pages are busy static spiffs_cache_page *spiffs_cache_page_allocate(spiffs *fs) { - spiffs_cache *cache = spiffs_get_cache(fs); - if (cache->cpage_use_map == 0xffffffff) { - // out of cache memory - return 0; - } - int i; - for (i = 0; i < cache->cpage_count; i++) { - if ((cache->cpage_use_map & (1<cpage_use_map |= (1<last_access = cache->last_access; - //SPIFFS_CACHE_DBG("CACHE_ALLO: allocated cache page "_SPIPRIi"\n", i); - return cp; + spiffs_cache *cache = spiffs_get_cache(fs); + if (cache->cpage_use_map == 0xffffffff) { + // out of cache memory + return 0; } - } - // out of cache entries - return 0; + int i; + for (i = 0; i < cache->cpage_count; i++) { + if ((cache->cpage_use_map & (1 << i)) == 0) { + spiffs_cache_page *cp = spiffs_get_cache_page_hdr(fs, cache, i); + cache->cpage_use_map |= (1 << i); + cp->last_access = cache->last_access; + //SPIFFS_CACHE_DBG("CACHE_ALLO: allocated cache page "_SPIPRIi"\n", i); + return cp; + } + } + // out of cache entries + return 0; } // drops the cache page for give page index void spiffs_cache_drop_page(spiffs *fs, spiffs_page_ix pix) { - spiffs_cache_page *cp = spiffs_cache_page_get(fs, pix); - if (cp) { - spiffs_cache_page_free(fs, cp->ix, 0); - } + spiffs_cache_page *cp = spiffs_cache_page_get(fs, pix); + if (cp) { + spiffs_cache_page_free(fs, cp->ix, 0); + } } // ------------------------------ @@ -127,57 +127,57 @@ s32_t spiffs_phys_rd( u32_t addr, u32_t len, u8_t *dst) { - (void)fh; - s32_t res = SPIFFS_OK; - spiffs_cache *cache = spiffs_get_cache(fs); - spiffs_cache_page *cp = spiffs_cache_page_get(fs, SPIFFS_PADDR_TO_PAGE(fs, addr)); - cache->last_access++; - if (cp) { - // we've already got one, you see -#if SPIFFS_CACHE_STATS - fs->cache_hits++; -#endif - cp->last_access = cache->last_access; - u8_t *mem = spiffs_get_cache_page(fs, cache, cp->ix); - _SPIFFS_MEMCPY(dst, &mem[SPIFFS_PADDR_TO_PAGE_OFFSET(fs, addr)], len); - } else { - if ((op & SPIFFS_OP_TYPE_MASK) == SPIFFS_OP_T_OBJ_LU2) { - // for second layer lookup functions, we do not cache in order to prevent shredding - return SPIFFS_HAL_READ(fs, addr, len, dst); - } -#if SPIFFS_CACHE_STATS - fs->cache_misses++; -#endif - // this operation will always free one cache page (unless all already free), - // the result code stems from the write operation of the possibly freed cache page - res = spiffs_cache_page_remove_oldest(fs, SPIFFS_CACHE_FLAG_TYPE_WR, 0); - - cp = spiffs_cache_page_allocate(fs); + (void)fh; + s32_t res = SPIFFS_OK; + spiffs_cache *cache = spiffs_get_cache(fs); + spiffs_cache_page *cp = spiffs_cache_page_get(fs, SPIFFS_PADDR_TO_PAGE(fs, addr)); + cache->last_access++; if (cp) { - cp->flags = SPIFFS_CACHE_FLAG_WRTHRU; - cp->ucache.spix.pix = SPIFFS_PADDR_TO_PAGE(fs, addr); - SPIFFS_CACHE_DBG("CACHE_ALLO: allocated cache page "_SPIPRIi" for pix "_SPIPRIpg "\n", cp->ix, cp->pix); - - s32_t res2 = SPIFFS_HAL_READ(fs, - addr - SPIFFS_PADDR_TO_PAGE_OFFSET(fs, addr), - SPIFFS_CFG_LOG_PAGE_SZ(fs), - spiffs_get_cache_page(fs, cache, cp->ix)); - if (res2 != SPIFFS_OK) { - // honor read failure before possible write failure (bad idea?) - res = res2; - } - u8_t *mem = spiffs_get_cache_page(fs, cache, cp->ix); - _SPIFFS_MEMCPY(dst, &mem[SPIFFS_PADDR_TO_PAGE_OFFSET(fs, addr)], len); + // we've already got one, you see +#if SPIFFS_CACHE_STATS + fs->cache_hits++; +#endif + cp->last_access = cache->last_access; + u8_t *mem = spiffs_get_cache_page(fs, cache, cp->ix); + _SPIFFS_MEMCPY(dst, &mem[SPIFFS_PADDR_TO_PAGE_OFFSET(fs, addr)], len); } else { - // this will never happen, last resort for sake of symmetry - s32_t res2 = SPIFFS_HAL_READ(fs, addr, len, dst); - if (res2 != SPIFFS_OK) { - // honor read failure before possible write failure (bad idea?) - res = res2; - } + if ((op & SPIFFS_OP_TYPE_MASK) == SPIFFS_OP_T_OBJ_LU2) { + // for second layer lookup functions, we do not cache in order to prevent shredding + return SPIFFS_HAL_READ(fs, addr, len, dst); + } +#if SPIFFS_CACHE_STATS + fs->cache_misses++; +#endif + // this operation will always free one cache page (unless all already free), + // the result code stems from the write operation of the possibly freed cache page + res = spiffs_cache_page_remove_oldest(fs, SPIFFS_CACHE_FLAG_TYPE_WR, 0); + + cp = spiffs_cache_page_allocate(fs); + if (cp) { + cp->flags = SPIFFS_CACHE_FLAG_WRTHRU; + cp->ucache.spix.pix = SPIFFS_PADDR_TO_PAGE(fs, addr); + SPIFFS_CACHE_DBG("CACHE_ALLO: allocated cache page "_SPIPRIi" for pix "_SPIPRIpg "\n", cp->ix, cp->pix); + + s32_t res2 = SPIFFS_HAL_READ(fs, + addr - SPIFFS_PADDR_TO_PAGE_OFFSET(fs, addr), + SPIFFS_CFG_LOG_PAGE_SZ(fs), + spiffs_get_cache_page(fs, cache, cp->ix)); + if (res2 != SPIFFS_OK) { + // honor read failure before possible write failure (bad idea?) + res = res2; + } + u8_t *mem = spiffs_get_cache_page(fs, cache, cp->ix); + _SPIFFS_MEMCPY(dst, &mem[SPIFFS_PADDR_TO_PAGE_OFFSET(fs, addr)], len); + } else { + // this will never happen, last resort for sake of symmetry + s32_t res2 = SPIFFS_HAL_READ(fs, addr, len, dst); + if (res2 != SPIFFS_OK) { + // honor read failure before possible write failure (bad idea?) + res = res2; + } + } } - } - return res; + return res; } // writes to spi flash and/or the cache @@ -188,132 +188,132 @@ s32_t spiffs_phys_wr( u32_t addr, u32_t len, u8_t *src) { - (void)fh; - spiffs_page_ix pix = SPIFFS_PADDR_TO_PAGE(fs, addr); - spiffs_cache *cache = spiffs_get_cache(fs); - spiffs_cache_page *cp = spiffs_cache_page_get(fs, pix); + (void)fh; + spiffs_page_ix pix = SPIFFS_PADDR_TO_PAGE(fs, addr); + spiffs_cache *cache = spiffs_get_cache(fs); + spiffs_cache_page *cp = spiffs_cache_page_get(fs, pix); - if (cp && (op & SPIFFS_OP_COM_MASK) != SPIFFS_OP_C_WRTHRU) { - // have a cache page - // copy in data to cache page + if (cp && (op & SPIFFS_OP_COM_MASK) != SPIFFS_OP_C_WRTHRU) { + // have a cache page + // copy in data to cache page - if ((op & SPIFFS_OP_COM_MASK) == SPIFFS_OP_C_DELE && - (op & SPIFFS_OP_TYPE_MASK) != SPIFFS_OP_T_OBJ_LU) { - // page is being deleted, wipe from cache - unless it is a lookup page - spiffs_cache_page_free(fs, cp->ix, 0); - return SPIFFS_HAL_WRITE(fs, addr, len, src); - } + if ((op & SPIFFS_OP_COM_MASK) == SPIFFS_OP_C_DELE && + (op & SPIFFS_OP_TYPE_MASK) != SPIFFS_OP_T_OBJ_LU) { + // page is being deleted, wipe from cache - unless it is a lookup page + spiffs_cache_page_free(fs, cp->ix, 0); + return SPIFFS_HAL_WRITE(fs, addr, len, src); + } - u8_t *mem = spiffs_get_cache_page(fs, cache, cp->ix); - _SPIFFS_MEMCPY(&mem[SPIFFS_PADDR_TO_PAGE_OFFSET(fs, addr)], src, len); + u8_t *mem = spiffs_get_cache_page(fs, cache, cp->ix); + _SPIFFS_MEMCPY(&mem[SPIFFS_PADDR_TO_PAGE_OFFSET(fs, addr)], src, len); - cache->last_access++; - cp->last_access = cache->last_access; + cache->last_access++; + cp->last_access = cache->last_access; - if (cp->flags & SPIFFS_CACHE_FLAG_WRTHRU) { - // page is being updated, no write-cache, just pass thru - return SPIFFS_HAL_WRITE(fs, addr, len, src); + if (cp->flags & SPIFFS_CACHE_FLAG_WRTHRU) { + // page is being updated, no write-cache, just pass thru + return SPIFFS_HAL_WRITE(fs, addr, len, src); + } else { + return SPIFFS_OK; + } } else { - return SPIFFS_OK; + // no cache page, no write cache - just write thru + return SPIFFS_HAL_WRITE(fs, addr, len, src); } - } else { - // no cache page, no write cache - just write thru - return SPIFFS_HAL_WRITE(fs, addr, len, src); - } } #if SPIFFS_CACHE_WR // returns the cache page that this fd refers, or null if no cache page spiffs_cache_page *spiffs_cache_page_get_by_fd(spiffs *fs, spiffs_fd *fd) { - spiffs_cache *cache = spiffs_get_cache(fs); + spiffs_cache *cache = spiffs_get_cache(fs); - if ((cache->cpage_use_map & cache->cpage_use_mask) == 0) { - // all cpages free, no cpage cannot be assigned to obj_id - return 0; - } - - int i; - for (i = 0; i < cache->cpage_count; i++) { - spiffs_cache_page *cp = spiffs_get_cache_page_hdr(fs, cache, i); - if ((cache->cpage_use_map & (1<flags & SPIFFS_CACHE_FLAG_TYPE_WR) && - cp->ucache.swrc.obj_id == fd->obj_id) { - return cp; + if ((cache->cpage_use_map & cache->cpage_use_mask) == 0) { + // all cpages free, no cpage cannot be assigned to obj_id + return 0; } - } - return 0; + int i; + for (i = 0; i < cache->cpage_count; i++) { + spiffs_cache_page *cp = spiffs_get_cache_page_hdr(fs, cache, i); + if ((cache->cpage_use_map & (1 << i)) && + (cp->flags & SPIFFS_CACHE_FLAG_TYPE_WR) && + cp->ucache.swrc.obj_id == fd->obj_id) { + return cp; + } + } + + return 0; } // allocates a new cache page and refers this to given fd - flushes an old cache // page if all cache is busy spiffs_cache_page *spiffs_cache_page_allocate_by_fd(spiffs *fs, spiffs_fd *fd) { - // before this function is called, it is ensured that there is no already existing - // cache page with same object id - spiffs_cache_page_remove_oldest(fs, SPIFFS_CACHE_FLAG_TYPE_WR, 0); - spiffs_cache_page *cp = spiffs_cache_page_allocate(fs); - if (cp == 0) { - // could not get cache page - return 0; - } + // before this function is called, it is ensured that there is no already existing + // cache page with same object id + spiffs_cache_page_remove_oldest(fs, SPIFFS_CACHE_FLAG_TYPE_WR, 0); + spiffs_cache_page *cp = spiffs_cache_page_allocate(fs); + if (cp == 0) { + // could not get cache page + return 0; + } - cp->flags = SPIFFS_CACHE_FLAG_TYPE_WR; - cp->ucache.swrc.obj_id = fd->obj_id; - fd->cache_page = cp; - SPIFFS_CACHE_DBG("CACHE_ALLO: allocated cache page "_SPIPRIi" for fd "_SPIPRIfd ":"_SPIPRIid "\n", cp->ix, fd->file_nbr, fd->obj_id); - return cp; + cp->flags = SPIFFS_CACHE_FLAG_TYPE_WR; + cp->ucache.swrc.obj_id = fd->obj_id; + fd->cache_page = cp; + SPIFFS_CACHE_DBG("CACHE_ALLO: allocated cache page "_SPIPRIi" for fd "_SPIPRIfd ":"_SPIPRIid "\n", cp->ix, fd->file_nbr, fd->obj_id); + return cp; } // unrefers all fds that this cache page refers to and releases the cache page void spiffs_cache_fd_release(spiffs *fs, spiffs_cache_page *cp) { - if (cp == 0) return; - u32_t i; - spiffs_fd *fds = (spiffs_fd *)fs->fd_space; - for (i = 0; i < fs->fd_count; i++) { - spiffs_fd *cur_fd = &fds[i]; - if (cur_fd->file_nbr != 0 && cur_fd->cache_page == cp) { - cur_fd->cache_page = 0; + if (cp == 0) return; + u32_t i; + spiffs_fd *fds = (spiffs_fd *)fs->fd_space; + for (i = 0; i < fs->fd_count; i++) { + spiffs_fd *cur_fd = &fds[i]; + if (cur_fd->file_nbr != 0 && cur_fd->cache_page == cp) { + cur_fd->cache_page = 0; + } } - } - spiffs_cache_page_free(fs, cp->ix, 0); + spiffs_cache_page_free(fs, cp->ix, 0); - cp->ucache.swrc.obj_id = 0; + cp->ucache.swrc.obj_id = 0; } #endif // initializes the cache void spiffs_cache_init(spiffs *fs) { - if (fs->cache == 0) return; - u32_t sz = fs->cache_size; - u32_t cache_mask = 0; - int i; - int cache_entries = - (sz - sizeof(spiffs_cache)) / (SPIFFS_CACHE_PAGE_SIZE(fs)); - if (cache_entries <= 0) return; + if (fs->cache == 0) return; + u32_t sz = fs->cache_size; + u32_t cache_mask = 0; + int i; + int cache_entries = + (sz - sizeof(spiffs_cache)) / (SPIFFS_CACHE_PAGE_SIZE(fs)); + if (cache_entries <= 0) return; - for (i = 0; i < cache_entries; i++) { - cache_mask <<= 1; - cache_mask |= 1; - } + for (i = 0; i < cache_entries; i++) { + cache_mask <<= 1; + cache_mask |= 1; + } - spiffs_cache cache; - memset(&cache, 0, sizeof(spiffs_cache)); - cache.cpage_count = cache_entries; - cache.cpages = (u8_t *)((u8_t *)fs->cache + sizeof(spiffs_cache)); + spiffs_cache cache; + memset(&cache, 0, sizeof(spiffs_cache)); + cache.cpage_count = cache_entries; + cache.cpages = (u8_t *)((u8_t *)fs->cache + sizeof(spiffs_cache)); - cache.cpage_use_map = 0xffffffff; - cache.cpage_use_mask = cache_mask; - _SPIFFS_MEMCPY(fs->cache, &cache, sizeof(spiffs_cache)); + cache.cpage_use_map = 0xffffffff; + cache.cpage_use_mask = cache_mask; + _SPIFFS_MEMCPY(fs->cache, &cache, sizeof(spiffs_cache)); - spiffs_cache *c = spiffs_get_cache(fs); + spiffs_cache *c = spiffs_get_cache(fs); - memset(c->cpages, 0, c->cpage_count * SPIFFS_CACHE_PAGE_SIZE(fs)); + memset(c->cpages, 0, c->cpage_count * SPIFFS_CACHE_PAGE_SIZE(fs)); - c->cpage_use_map &= ~(c->cpage_use_mask); - for (i = 0; i < cache.cpage_count; i++) { - spiffs_get_cache_page_hdr(fs, c, i)->ix = i; - } + c->cpage_use_map &= ~(c->cpage_use_mask); + for (i = 0; i < cache.cpage_count; i++) { + spiffs_get_cache_page_hdr(fs, c, i)->ix = i; + } } #endif // SPIFFS_CACHE diff --git a/armsrc/spiffs_check.c b/armsrc/spiffs_check.c index 2b3b3a14d..90fba8a41 100644 --- a/armsrc/spiffs_check.c +++ b/armsrc/spiffs_check.c @@ -44,466 +44,465 @@ // the object id and the data span index // destroys fs->lu_work static s32_t spiffs_object_get_data_page_index_reference( - spiffs *fs, - spiffs_obj_id obj_id, - spiffs_span_ix data_spix, - spiffs_page_ix *pix, - spiffs_page_ix *objix_pix) { - s32_t res; + spiffs *fs, + spiffs_obj_id obj_id, + spiffs_span_ix data_spix, + spiffs_page_ix *pix, + spiffs_page_ix *objix_pix) { + s32_t res; - // calculate object index span index for given data page span index - spiffs_span_ix objix_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, data_spix); + // calculate object index span index for given data page span index + spiffs_span_ix objix_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, data_spix); - // find obj index for obj id and span index - res = spiffs_obj_lu_find_id_and_span(fs, obj_id | SPIFFS_OBJ_ID_IX_FLAG, objix_spix, 0, objix_pix); - SPIFFS_CHECK_RES(res); + // find obj index for obj id and span index + res = spiffs_obj_lu_find_id_and_span(fs, obj_id | SPIFFS_OBJ_ID_IX_FLAG, objix_spix, 0, objix_pix); + SPIFFS_CHECK_RES(res); - // load obj index entry - u32_t addr = SPIFFS_PAGE_TO_PADDR(fs, *objix_pix); - if (objix_spix == 0) { - // get referenced page from object index header - addr += sizeof(spiffs_page_object_ix_header) + data_spix * sizeof(spiffs_page_ix); - } else { - // get referenced page from object index - addr += sizeof(spiffs_page_object_ix) + SPIFFS_OBJ_IX_ENTRY(fs, data_spix) * sizeof(spiffs_page_ix); - } + // load obj index entry + u32_t addr = SPIFFS_PAGE_TO_PADDR(fs, *objix_pix); + if (objix_spix == 0) { + // get referenced page from object index header + addr += sizeof(spiffs_page_object_ix_header) + data_spix * sizeof(spiffs_page_ix); + } else { + // get referenced page from object index + addr += sizeof(spiffs_page_object_ix) + SPIFFS_OBJ_IX_ENTRY(fs, data_spix) * sizeof(spiffs_page_ix); + } - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, 0, addr, sizeof(spiffs_page_ix), (u8_t *)pix); + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, 0, addr, sizeof(spiffs_page_ix), (u8_t *)pix); - return res; + return res; } // copies page contents to a new page static s32_t spiffs_rewrite_page(spiffs *fs, spiffs_page_ix cur_pix, spiffs_page_header *p_hdr, spiffs_page_ix *new_pix) { - s32_t res; - res = spiffs_page_allocate_data(fs, p_hdr->obj_id, p_hdr, 0,0,0,0, new_pix); - SPIFFS_CHECK_RES(res); - res = spiffs_phys_cpy(fs, 0, - SPIFFS_PAGE_TO_PADDR(fs, *new_pix) + sizeof(spiffs_page_header), - SPIFFS_PAGE_TO_PADDR(fs, cur_pix) + sizeof(spiffs_page_header), - SPIFFS_DATA_PAGE_SIZE(fs)); - SPIFFS_CHECK_RES(res); - return res; + s32_t res; + res = spiffs_page_allocate_data(fs, p_hdr->obj_id, p_hdr, 0, 0, 0, 0, new_pix); + SPIFFS_CHECK_RES(res); + res = spiffs_phys_cpy(fs, 0, + SPIFFS_PAGE_TO_PADDR(fs, *new_pix) + sizeof(spiffs_page_header), + SPIFFS_PAGE_TO_PADDR(fs, cur_pix) + sizeof(spiffs_page_header), + SPIFFS_DATA_PAGE_SIZE(fs)); + SPIFFS_CHECK_RES(res); + return res; } // rewrites the object index for given object id and replaces the // data page index to a new page index static s32_t spiffs_rewrite_index(spiffs *fs, spiffs_obj_id obj_id, spiffs_span_ix data_spix, spiffs_page_ix new_data_pix, spiffs_page_ix objix_pix) { - s32_t res; - spiffs_block_ix bix; - int entry; - spiffs_page_ix free_pix; - obj_id |= SPIFFS_OBJ_ID_IX_FLAG; + s32_t res; + spiffs_block_ix bix; + int entry; + spiffs_page_ix free_pix; + obj_id |= SPIFFS_OBJ_ID_IX_FLAG; - // find free entry - res = spiffs_obj_lu_find_free(fs, fs->free_cursor_block_ix, fs->free_cursor_obj_lu_entry, &bix, &entry); - SPIFFS_CHECK_RES(res); - free_pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, entry); + // find free entry + res = spiffs_obj_lu_find_free(fs, fs->free_cursor_block_ix, fs->free_cursor_obj_lu_entry, &bix, &entry); + SPIFFS_CHECK_RES(res); + free_pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, entry); - // calculate object index span index for given data page span index - spiffs_span_ix objix_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, data_spix); - if (objix_spix == 0) { - // calc index in index header - entry = data_spix; - } else { - // calc entry in index - entry = SPIFFS_OBJ_IX_ENTRY(fs, data_spix); + // calculate object index span index for given data page span index + spiffs_span_ix objix_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, data_spix); + if (objix_spix == 0) { + // calc index in index header + entry = data_spix; + } else { + // calc entry in index + entry = SPIFFS_OBJ_IX_ENTRY(fs, data_spix); - } - // load index - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, - 0, SPIFFS_PAGE_TO_PADDR(fs, objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); - SPIFFS_CHECK_RES(res); - spiffs_page_header *objix_p_hdr = (spiffs_page_header *)fs->lu_work; + } + // load index + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, + 0, SPIFFS_PAGE_TO_PADDR(fs, objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); + SPIFFS_CHECK_RES(res); + spiffs_page_header *objix_p_hdr = (spiffs_page_header *)fs->lu_work; - // be ultra safe, double check header against provided data - if (objix_p_hdr->obj_id != obj_id) { - spiffs_page_delete(fs, free_pix); - return SPIFFS_ERR_CHECK_OBJ_ID_MISM; - } - if (objix_p_hdr->span_ix != objix_spix) { - spiffs_page_delete(fs, free_pix); - return SPIFFS_ERR_CHECK_SPIX_MISM; - } - if ((objix_p_hdr->flags & (SPIFFS_PH_FLAG_USED | SPIFFS_PH_FLAG_IXDELE | SPIFFS_PH_FLAG_INDEX | - SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_DELET)) != - (SPIFFS_PH_FLAG_IXDELE | SPIFFS_PH_FLAG_DELET)) { - spiffs_page_delete(fs, free_pix); - return SPIFFS_ERR_CHECK_FLAGS_BAD; - } + // be ultra safe, double check header against provided data + if (objix_p_hdr->obj_id != obj_id) { + spiffs_page_delete(fs, free_pix); + return SPIFFS_ERR_CHECK_OBJ_ID_MISM; + } + if (objix_p_hdr->span_ix != objix_spix) { + spiffs_page_delete(fs, free_pix); + return SPIFFS_ERR_CHECK_SPIX_MISM; + } + if ((objix_p_hdr->flags & (SPIFFS_PH_FLAG_USED | SPIFFS_PH_FLAG_IXDELE | SPIFFS_PH_FLAG_INDEX | + SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_DELET)) != + (SPIFFS_PH_FLAG_IXDELE | SPIFFS_PH_FLAG_DELET)) { + spiffs_page_delete(fs, free_pix); + return SPIFFS_ERR_CHECK_FLAGS_BAD; + } - // rewrite in mem - if (objix_spix == 0) { - ((spiffs_page_ix*)((u8_t *)fs->lu_work + sizeof(spiffs_page_object_ix_header)))[data_spix] = new_data_pix; - } else { - ((spiffs_page_ix*)((u8_t *)fs->lu_work + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)] = new_data_pix; - } + // rewrite in mem + if (objix_spix == 0) { + ((spiffs_page_ix *)((u8_t *)fs->lu_work + sizeof(spiffs_page_object_ix_header)))[data_spix] = new_data_pix; + } else { + ((spiffs_page_ix *)((u8_t *)fs->lu_work + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)] = new_data_pix; + } - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, - 0, SPIFFS_PAGE_TO_PADDR(fs, free_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); - SPIFFS_CHECK_RES(res); - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_UPDT, - 0, SPIFFS_BLOCK_TO_PADDR(fs, SPIFFS_BLOCK_FOR_PAGE(fs, free_pix)) + SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(fs, free_pix) * sizeof(spiffs_page_ix), - sizeof(spiffs_obj_id), - (u8_t *)&obj_id); - SPIFFS_CHECK_RES(res); - res = spiffs_page_delete(fs, objix_pix); + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, + 0, SPIFFS_PAGE_TO_PADDR(fs, free_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); + SPIFFS_CHECK_RES(res); + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_UPDT, + 0, SPIFFS_BLOCK_TO_PADDR(fs, SPIFFS_BLOCK_FOR_PAGE(fs, free_pix)) + SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(fs, free_pix) * sizeof(spiffs_page_ix), + sizeof(spiffs_obj_id), + (u8_t *)&obj_id); + SPIFFS_CHECK_RES(res); + res = spiffs_page_delete(fs, objix_pix); - return res; + return res; } // deletes an object just by marking object index header as deleted static s32_t spiffs_delete_obj_lazy(spiffs *fs, spiffs_obj_id obj_id) { - spiffs_page_ix objix_hdr_pix; - s32_t res; - res = spiffs_obj_lu_find_id_and_span(fs, obj_id, 0, 0, &objix_hdr_pix); - if (res == SPIFFS_ERR_NOT_FOUND) { - return SPIFFS_OK; - } - SPIFFS_CHECK_RES(res); - u8_t flags = 0xff; + spiffs_page_ix objix_hdr_pix; + s32_t res; + res = spiffs_obj_lu_find_id_and_span(fs, obj_id, 0, 0, &objix_hdr_pix); + if (res == SPIFFS_ERR_NOT_FOUND) { + return SPIFFS_OK; + } + SPIFFS_CHECK_RES(res); + u8_t flags = 0xff; #if SPIFFS_NO_BLIND_WRITES - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, - 0, SPIFFS_PAGE_TO_PADDR(fs, objix_hdr_pix) + offsetof(spiffs_page_header, flags), - sizeof(flags), &flags); - SPIFFS_CHECK_RES(res); + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, + 0, SPIFFS_PAGE_TO_PADDR(fs, objix_hdr_pix) + offsetof(spiffs_page_header, flags), + sizeof(flags), &flags); + SPIFFS_CHECK_RES(res); #endif - flags &= ~SPIFFS_PH_FLAG_IXDELE; - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_UPDT, - 0, SPIFFS_PAGE_TO_PADDR(fs, objix_hdr_pix) + offsetof(spiffs_page_header, flags), - sizeof(flags), &flags); - return res; + flags &= ~SPIFFS_PH_FLAG_IXDELE; + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_UPDT, + 0, SPIFFS_PAGE_TO_PADDR(fs, objix_hdr_pix) + offsetof(spiffs_page_header, flags), + sizeof(flags), &flags); + return res; } // validates the given look up entry static s32_t spiffs_lookup_check_validate(spiffs *fs, spiffs_obj_id lu_obj_id, spiffs_page_header *p_hdr, - spiffs_page_ix cur_pix, spiffs_block_ix cur_block, int cur_entry, int *reload_lu) { - (void)cur_block; - (void)cur_entry; - u8_t delete_page = 0; - s32_t res = SPIFFS_OK; - spiffs_page_ix objix_pix; - spiffs_page_ix ref_pix; - // check validity, take actions - if (((lu_obj_id == SPIFFS_OBJ_ID_DELETED) && (p_hdr->flags & SPIFFS_PH_FLAG_DELET)) || - ((lu_obj_id == SPIFFS_OBJ_ID_FREE) && (p_hdr->flags & SPIFFS_PH_FLAG_USED) == 0)) { - // look up entry deleted / free but used in page header - SPIFFS_CHECK_DBG("LU: pix "_SPIPRIpg" deleted/free in lu but not on page\n", cur_pix); - *reload_lu = 1; - delete_page = 1; - if (p_hdr->flags & SPIFFS_PH_FLAG_INDEX) { - // header says data page - // data page can be removed if not referenced by some object index - res = spiffs_object_get_data_page_index_reference(fs, p_hdr->obj_id, p_hdr->span_ix, &ref_pix, &objix_pix); - if (res == SPIFFS_ERR_NOT_FOUND) { - // no object with this id, so remove page safely - res = SPIFFS_OK; - } else { - SPIFFS_CHECK_RES(res); - if (ref_pix == cur_pix) { - // data page referenced by object index but deleted in lu - // copy page to new place and re-write the object index to new place - spiffs_page_ix new_pix; - res = spiffs_rewrite_page(fs, cur_pix, p_hdr, &new_pix); - SPIFFS_CHECK_DBG("LU: FIXUP: data page not found elsewhere, rewriting "_SPIPRIpg" to new page "_SPIPRIpg"\n", cur_pix, new_pix); - SPIFFS_CHECK_RES(res); - *reload_lu = 1; - SPIFFS_CHECK_DBG("LU: FIXUP: "_SPIPRIpg" rewritten to "_SPIPRIpg", affected objix_pix "_SPIPRIpg"\n", cur_pix, new_pix, objix_pix); - res = spiffs_rewrite_index(fs, p_hdr->obj_id, p_hdr->span_ix, new_pix, objix_pix); - if (res <= _SPIFFS_ERR_CHECK_FIRST && res > _SPIFFS_ERR_CHECK_LAST) { - // index bad also, cannot mend this file - SPIFFS_CHECK_DBG("LU: FIXUP: index bad "_SPIPRIi", cannot mend!\n", res); - res = spiffs_page_delete(fs, new_pix); - SPIFFS_CHECK_RES(res); - res = spiffs_delete_obj_lazy(fs, p_hdr->obj_id); - CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_DELETE_BAD_FILE, p_hdr->obj_id, 0); - } else { - CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_INDEX, p_hdr->obj_id, p_hdr->span_ix); - } - SPIFFS_CHECK_RES(res); - } - } - } else { - // header says index page - // index page can be removed if other index with same obj_id and spanix is found - res = spiffs_obj_lu_find_id_and_span(fs, p_hdr->obj_id | SPIFFS_OBJ_ID_IX_FLAG, p_hdr->span_ix, cur_pix, 0); - if (res == SPIFFS_ERR_NOT_FOUND) { - // no such index page found, check for a data page amongst page headers - // lu cannot be trusted - res = spiffs_obj_lu_find_id_and_span_by_phdr(fs, p_hdr->obj_id | SPIFFS_OBJ_ID_IX_FLAG, 0, 0, 0); - if (res == SPIFFS_OK) { // ignore other errors - // got a data page also, assume lu corruption only, rewrite to new page - spiffs_page_ix new_pix; - res = spiffs_rewrite_page(fs, cur_pix, p_hdr, &new_pix); - SPIFFS_CHECK_DBG("LU: FIXUP: ix page with data not found elsewhere, rewriting "_SPIPRIpg" to new page "_SPIPRIpg"\n", cur_pix, new_pix); - SPIFFS_CHECK_RES(res); - *reload_lu = 1; - CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_LOOKUP, p_hdr->obj_id, p_hdr->span_ix); - } - } else { - SPIFFS_CHECK_RES(res); - } - } - } - if (lu_obj_id != SPIFFS_OBJ_ID_FREE && lu_obj_id != SPIFFS_OBJ_ID_DELETED) { - // look up entry used - if ((p_hdr->obj_id | SPIFFS_OBJ_ID_IX_FLAG) != (lu_obj_id | SPIFFS_OBJ_ID_IX_FLAG)) { - SPIFFS_CHECK_DBG("LU: pix "_SPIPRIpg" differ in obj_id lu:"_SPIPRIid" ph:"_SPIPRIid"\n", cur_pix, lu_obj_id, p_hdr->obj_id); - delete_page = 1; - if ((p_hdr->flags & SPIFFS_PH_FLAG_DELET) == 0 || - (p_hdr->flags & SPIFFS_PH_FLAG_FINAL) || - (p_hdr->flags & (SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_IXDELE)) == 0) { - // page deleted or not finalized, just remove it - } else { - if (p_hdr->flags & SPIFFS_PH_FLAG_INDEX) { - // if data page, check for reference to this page - res = spiffs_object_get_data_page_index_reference(fs, p_hdr->obj_id, p_hdr->span_ix, &ref_pix, &objix_pix); - if (res == SPIFFS_ERR_NOT_FOUND) { - // no object with this id, so remove page safely - res = SPIFFS_OK; - } else { - SPIFFS_CHECK_RES(res); - // if found, rewrite page with object id, update index, and delete current - if (ref_pix == cur_pix) { - spiffs_page_ix new_pix; - res = spiffs_rewrite_page(fs, cur_pix, p_hdr, &new_pix); - SPIFFS_CHECK_RES(res); - res = spiffs_rewrite_index(fs, p_hdr->obj_id, p_hdr->span_ix, new_pix, objix_pix); - if (res <= _SPIFFS_ERR_CHECK_FIRST && res > _SPIFFS_ERR_CHECK_LAST) { - // index bad also, cannot mend this file - SPIFFS_CHECK_DBG("LU: FIXUP: index bad "_SPIPRIi", cannot mend!\n", res); - res = spiffs_page_delete(fs, new_pix); - SPIFFS_CHECK_RES(res); - res = spiffs_delete_obj_lazy(fs, p_hdr->obj_id); - *reload_lu = 1; - CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_DELETE_BAD_FILE, p_hdr->obj_id, 0); - } - SPIFFS_CHECK_RES(res); - } - } - } else { - // else if index, check for other pages with both obj_id's and spanix - spiffs_page_ix objix_pix_lu, objix_pix_ph; - // see if other object index page exists for lookup obj id and span index - res = spiffs_obj_lu_find_id_and_span(fs, lu_obj_id | SPIFFS_OBJ_ID_IX_FLAG, p_hdr->span_ix, 0, &objix_pix_lu); - if (res == SPIFFS_ERR_NOT_FOUND) { - res = SPIFFS_OK; - objix_pix_lu = 0; - } - SPIFFS_CHECK_RES(res); - // see if other object index exists for page header obj id and span index - res = spiffs_obj_lu_find_id_and_span(fs, p_hdr->obj_id | SPIFFS_OBJ_ID_IX_FLAG, p_hdr->span_ix, 0, &objix_pix_ph); - if (res == SPIFFS_ERR_NOT_FOUND) { - res = SPIFFS_OK; - objix_pix_ph = 0; - } - SPIFFS_CHECK_RES(res); - // if both obj_id's found, just delete current - if (objix_pix_ph == 0 || objix_pix_lu == 0) { - // otherwise try finding first corresponding data pages - spiffs_page_ix data_pix_lu, data_pix_ph; - // see if other data page exists for look up obj id and span index - res = spiffs_obj_lu_find_id_and_span(fs, lu_obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &data_pix_lu); - if (res == SPIFFS_ERR_NOT_FOUND) { - res = SPIFFS_OK; - objix_pix_lu = 0; - } - SPIFFS_CHECK_RES(res); - // see if other data page exists for page header obj id and span index - res = spiffs_obj_lu_find_id_and_span(fs, p_hdr->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &data_pix_ph); - if (res == SPIFFS_ERR_NOT_FOUND) { - res = SPIFFS_OK; - objix_pix_ph = 0; - } - SPIFFS_CHECK_RES(res); - - spiffs_page_header new_ph; - new_ph.flags = 0xff & ~(SPIFFS_PH_FLAG_USED | SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_FINAL); - new_ph.span_ix = p_hdr->span_ix; - spiffs_page_ix new_pix; - if ((objix_pix_lu && data_pix_lu && data_pix_ph && objix_pix_ph == 0) || - (objix_pix_lu == 0 && data_pix_ph && objix_pix_ph == 0)) { - // got a data page for page header obj id - // rewrite as obj_id_ph - new_ph.obj_id = p_hdr->obj_id | SPIFFS_OBJ_ID_IX_FLAG; - res = spiffs_rewrite_page(fs, cur_pix, &new_ph, &new_pix); - SPIFFS_CHECK_DBG("LU: FIXUP: rewrite page "_SPIPRIpg" as "_SPIPRIid" to pix "_SPIPRIpg"\n", cur_pix, new_ph.obj_id, new_pix); - CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_LOOKUP, p_hdr->obj_id, p_hdr->span_ix); - SPIFFS_CHECK_RES(res); - *reload_lu = 1; - } else if ((objix_pix_ph && data_pix_ph && data_pix_lu && objix_pix_lu == 0) || - (objix_pix_ph == 0 && data_pix_lu && objix_pix_lu == 0)) { - // got a data page for look up obj id - // rewrite as obj_id_lu - new_ph.obj_id = lu_obj_id | SPIFFS_OBJ_ID_IX_FLAG; - SPIFFS_CHECK_DBG("LU: FIXUP: rewrite page "_SPIPRIpg" as "_SPIPRIid"\n", cur_pix, new_ph.obj_id); - CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_LOOKUP, p_hdr->obj_id, p_hdr->span_ix); - res = spiffs_rewrite_page(fs, cur_pix, &new_ph, &new_pix); - SPIFFS_CHECK_RES(res); - *reload_lu = 1; - } else { - // cannot safely do anything - SPIFFS_CHECK_DBG("LU: FIXUP: nothing to do, just delete\n",NULL); - } - } - } - } - } else if (((lu_obj_id & SPIFFS_OBJ_ID_IX_FLAG) && (p_hdr->flags & SPIFFS_PH_FLAG_INDEX)) || - ((lu_obj_id & SPIFFS_OBJ_ID_IX_FLAG) == 0 && (p_hdr->flags & SPIFFS_PH_FLAG_INDEX) == 0)) { - SPIFFS_CHECK_DBG("LU: "_SPIPRIpg" lu/page index marking differ\n", cur_pix); - spiffs_page_ix data_pix, objix_pix_d; - // see if other data page exists for given obj id and span index - res = spiffs_obj_lu_find_id_and_span(fs, lu_obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, p_hdr->span_ix, cur_pix, &data_pix); - if (res == SPIFFS_ERR_NOT_FOUND) { - res = SPIFFS_OK; - data_pix = 0; - } - SPIFFS_CHECK_RES(res); - // see if other object index exists for given obj id and span index - res = spiffs_obj_lu_find_id_and_span(fs, lu_obj_id | SPIFFS_OBJ_ID_IX_FLAG, p_hdr->span_ix, cur_pix, &objix_pix_d); - if (res == SPIFFS_ERR_NOT_FOUND) { - res = SPIFFS_OK; - objix_pix_d = 0; - } - SPIFFS_CHECK_RES(res); - - delete_page = 1; - // if other data page exists and object index exists, just delete page - if (data_pix && objix_pix_d) { - SPIFFS_CHECK_DBG("LU: FIXUP: other index and data page exists, simply remove\n",NULL); - } else - // if only data page exists, make this page index - if (data_pix && objix_pix_d == 0) { - SPIFFS_CHECK_DBG("LU: FIXUP: other data page exists, make this index\n",NULL); - CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_INDEX, lu_obj_id, p_hdr->span_ix); - spiffs_page_header new_ph; - spiffs_page_ix new_pix; - new_ph.flags = 0xff & ~(SPIFFS_PH_FLAG_USED | SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_INDEX); - new_ph.obj_id = lu_obj_id | SPIFFS_OBJ_ID_IX_FLAG; - new_ph.span_ix = p_hdr->span_ix; - res = spiffs_page_allocate_data(fs, new_ph.obj_id, &new_ph, 0, 0, 0, 1, &new_pix); - SPIFFS_CHECK_RES(res); - res = spiffs_phys_cpy(fs, 0, SPIFFS_PAGE_TO_PADDR(fs, new_pix) + sizeof(spiffs_page_header), - SPIFFS_PAGE_TO_PADDR(fs, cur_pix) + sizeof(spiffs_page_header), - SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_page_header)); - SPIFFS_CHECK_RES(res); - } else - // if only index exists, make data page - if (data_pix == 0 && objix_pix_d) { - SPIFFS_CHECK_DBG("LU: FIXUP: other index page exists, make this data\n",NULL); - CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_LOOKUP, lu_obj_id, p_hdr->span_ix); - spiffs_page_header new_ph; - spiffs_page_ix new_pix; - new_ph.flags = 0xff & ~(SPIFFS_PH_FLAG_USED | SPIFFS_PH_FLAG_FINAL); - new_ph.obj_id = lu_obj_id & ~SPIFFS_OBJ_ID_IX_FLAG; - new_ph.span_ix = p_hdr->span_ix; - res = spiffs_page_allocate_data(fs, new_ph.obj_id, &new_ph, 0, 0, 0, 1, &new_pix); - SPIFFS_CHECK_RES(res); - res = spiffs_phys_cpy(fs, 0, SPIFFS_PAGE_TO_PADDR(fs, new_pix) + sizeof(spiffs_page_header), - SPIFFS_PAGE_TO_PADDR(fs, cur_pix) + sizeof(spiffs_page_header), - SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_page_header)); - SPIFFS_CHECK_RES(res); - } else { - // if nothing exists, we cannot safely make a decision - delete - } - } - else if ((p_hdr->flags & SPIFFS_PH_FLAG_DELET) == 0) { - SPIFFS_CHECK_DBG("LU: pix "_SPIPRIpg" busy in lu but deleted on page\n", cur_pix); - delete_page = 1; - } else if ((p_hdr->flags & SPIFFS_PH_FLAG_FINAL)) { - SPIFFS_CHECK_DBG("LU: pix "_SPIPRIpg" busy but not final\n", cur_pix); - // page can be removed if not referenced by object index - *reload_lu = 1; - res = spiffs_object_get_data_page_index_reference(fs, lu_obj_id, p_hdr->span_ix, &ref_pix, &objix_pix); - if (res == SPIFFS_ERR_NOT_FOUND) { - // no object with this id, so remove page safely - res = SPIFFS_OK; + spiffs_page_ix cur_pix, spiffs_block_ix cur_block, int cur_entry, int *reload_lu) { + (void)cur_block; + (void)cur_entry; + u8_t delete_page = 0; + s32_t res = SPIFFS_OK; + spiffs_page_ix objix_pix; + spiffs_page_ix ref_pix; + // check validity, take actions + if (((lu_obj_id == SPIFFS_OBJ_ID_DELETED) && (p_hdr->flags & SPIFFS_PH_FLAG_DELET)) || + ((lu_obj_id == SPIFFS_OBJ_ID_FREE) && (p_hdr->flags & SPIFFS_PH_FLAG_USED) == 0)) { + // look up entry deleted / free but used in page header + SPIFFS_CHECK_DBG("LU: pix "_SPIPRIpg" deleted/free in lu but not on page\n", cur_pix); + *reload_lu = 1; delete_page = 1; - } else { - SPIFFS_CHECK_RES(res); - if (ref_pix != cur_pix) { - SPIFFS_CHECK_DBG("LU: FIXUP: other finalized page is referred, just delete\n",NULL); - delete_page = 1; + if (p_hdr->flags & SPIFFS_PH_FLAG_INDEX) { + // header says data page + // data page can be removed if not referenced by some object index + res = spiffs_object_get_data_page_index_reference(fs, p_hdr->obj_id, p_hdr->span_ix, &ref_pix, &objix_pix); + if (res == SPIFFS_ERR_NOT_FOUND) { + // no object with this id, so remove page safely + res = SPIFFS_OK; + } else { + SPIFFS_CHECK_RES(res); + if (ref_pix == cur_pix) { + // data page referenced by object index but deleted in lu + // copy page to new place and re-write the object index to new place + spiffs_page_ix new_pix; + res = spiffs_rewrite_page(fs, cur_pix, p_hdr, &new_pix); + SPIFFS_CHECK_DBG("LU: FIXUP: data page not found elsewhere, rewriting "_SPIPRIpg" to new page "_SPIPRIpg"\n", cur_pix, new_pix); + SPIFFS_CHECK_RES(res); + *reload_lu = 1; + SPIFFS_CHECK_DBG("LU: FIXUP: "_SPIPRIpg" rewritten to "_SPIPRIpg", affected objix_pix "_SPIPRIpg"\n", cur_pix, new_pix, objix_pix); + res = spiffs_rewrite_index(fs, p_hdr->obj_id, p_hdr->span_ix, new_pix, objix_pix); + if (res <= _SPIFFS_ERR_CHECK_FIRST && res > _SPIFFS_ERR_CHECK_LAST) { + // index bad also, cannot mend this file + SPIFFS_CHECK_DBG("LU: FIXUP: index bad "_SPIPRIi", cannot mend!\n", res); + res = spiffs_page_delete(fs, new_pix); + SPIFFS_CHECK_RES(res); + res = spiffs_delete_obj_lazy(fs, p_hdr->obj_id); + CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_DELETE_BAD_FILE, p_hdr->obj_id, 0); + } else { + CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_INDEX, p_hdr->obj_id, p_hdr->span_ix); + } + SPIFFS_CHECK_RES(res); + } + } } else { - // page referenced by object index but not final - // just finalize - SPIFFS_CHECK_DBG("LU: FIXUP: unfinalized page is referred, finalizing\n",NULL); - CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_LOOKUP, p_hdr->obj_id, p_hdr->span_ix); - u8_t flags = 0xff; -#if SPIFFS_NO_BLIND_WRITES - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_READ, - 0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix) + offsetof(spiffs_page_header, flags), - sizeof(flags), &flags); - SPIFFS_CHECK_RES(res); -#endif - flags &= ~SPIFFS_PH_FLAG_FINAL; - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, - 0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix) + offsetof(spiffs_page_header, flags), - sizeof(flags), &flags); + // header says index page + // index page can be removed if other index with same obj_id and spanix is found + res = spiffs_obj_lu_find_id_and_span(fs, p_hdr->obj_id | SPIFFS_OBJ_ID_IX_FLAG, p_hdr->span_ix, cur_pix, 0); + if (res == SPIFFS_ERR_NOT_FOUND) { + // no such index page found, check for a data page amongst page headers + // lu cannot be trusted + res = spiffs_obj_lu_find_id_and_span_by_phdr(fs, p_hdr->obj_id | SPIFFS_OBJ_ID_IX_FLAG, 0, 0, 0); + if (res == SPIFFS_OK) { // ignore other errors + // got a data page also, assume lu corruption only, rewrite to new page + spiffs_page_ix new_pix; + res = spiffs_rewrite_page(fs, cur_pix, p_hdr, &new_pix); + SPIFFS_CHECK_DBG("LU: FIXUP: ix page with data not found elsewhere, rewriting "_SPIPRIpg" to new page "_SPIPRIpg"\n", cur_pix, new_pix); + SPIFFS_CHECK_RES(res); + *reload_lu = 1; + CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_LOOKUP, p_hdr->obj_id, p_hdr->span_ix); + } + } else { + SPIFFS_CHECK_RES(res); + } } - } } - } + if (lu_obj_id != SPIFFS_OBJ_ID_FREE && lu_obj_id != SPIFFS_OBJ_ID_DELETED) { + // look up entry used + if ((p_hdr->obj_id | SPIFFS_OBJ_ID_IX_FLAG) != (lu_obj_id | SPIFFS_OBJ_ID_IX_FLAG)) { + SPIFFS_CHECK_DBG("LU: pix "_SPIPRIpg" differ in obj_id lu:"_SPIPRIid" ph:"_SPIPRIid"\n", cur_pix, lu_obj_id, p_hdr->obj_id); + delete_page = 1; + if ((p_hdr->flags & SPIFFS_PH_FLAG_DELET) == 0 || + (p_hdr->flags & SPIFFS_PH_FLAG_FINAL) || + (p_hdr->flags & (SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_IXDELE)) == 0) { + // page deleted or not finalized, just remove it + } else { + if (p_hdr->flags & SPIFFS_PH_FLAG_INDEX) { + // if data page, check for reference to this page + res = spiffs_object_get_data_page_index_reference(fs, p_hdr->obj_id, p_hdr->span_ix, &ref_pix, &objix_pix); + if (res == SPIFFS_ERR_NOT_FOUND) { + // no object with this id, so remove page safely + res = SPIFFS_OK; + } else { + SPIFFS_CHECK_RES(res); + // if found, rewrite page with object id, update index, and delete current + if (ref_pix == cur_pix) { + spiffs_page_ix new_pix; + res = spiffs_rewrite_page(fs, cur_pix, p_hdr, &new_pix); + SPIFFS_CHECK_RES(res); + res = spiffs_rewrite_index(fs, p_hdr->obj_id, p_hdr->span_ix, new_pix, objix_pix); + if (res <= _SPIFFS_ERR_CHECK_FIRST && res > _SPIFFS_ERR_CHECK_LAST) { + // index bad also, cannot mend this file + SPIFFS_CHECK_DBG("LU: FIXUP: index bad "_SPIPRIi", cannot mend!\n", res); + res = spiffs_page_delete(fs, new_pix); + SPIFFS_CHECK_RES(res); + res = spiffs_delete_obj_lazy(fs, p_hdr->obj_id); + *reload_lu = 1; + CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_DELETE_BAD_FILE, p_hdr->obj_id, 0); + } + SPIFFS_CHECK_RES(res); + } + } + } else { + // else if index, check for other pages with both obj_id's and spanix + spiffs_page_ix objix_pix_lu, objix_pix_ph; + // see if other object index page exists for lookup obj id and span index + res = spiffs_obj_lu_find_id_and_span(fs, lu_obj_id | SPIFFS_OBJ_ID_IX_FLAG, p_hdr->span_ix, 0, &objix_pix_lu); + if (res == SPIFFS_ERR_NOT_FOUND) { + res = SPIFFS_OK; + objix_pix_lu = 0; + } + SPIFFS_CHECK_RES(res); + // see if other object index exists for page header obj id and span index + res = spiffs_obj_lu_find_id_and_span(fs, p_hdr->obj_id | SPIFFS_OBJ_ID_IX_FLAG, p_hdr->span_ix, 0, &objix_pix_ph); + if (res == SPIFFS_ERR_NOT_FOUND) { + res = SPIFFS_OK; + objix_pix_ph = 0; + } + SPIFFS_CHECK_RES(res); + // if both obj_id's found, just delete current + if (objix_pix_ph == 0 || objix_pix_lu == 0) { + // otherwise try finding first corresponding data pages + spiffs_page_ix data_pix_lu, data_pix_ph; + // see if other data page exists for look up obj id and span index + res = spiffs_obj_lu_find_id_and_span(fs, lu_obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &data_pix_lu); + if (res == SPIFFS_ERR_NOT_FOUND) { + res = SPIFFS_OK; + objix_pix_lu = 0; + } + SPIFFS_CHECK_RES(res); + // see if other data page exists for page header obj id and span index + res = spiffs_obj_lu_find_id_and_span(fs, p_hdr->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &data_pix_ph); + if (res == SPIFFS_ERR_NOT_FOUND) { + res = SPIFFS_OK; + objix_pix_ph = 0; + } + SPIFFS_CHECK_RES(res); - if (delete_page) { - SPIFFS_CHECK_DBG("LU: FIXUP: deleting page "_SPIPRIpg"\n", cur_pix); - CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_DELETE_PAGE, cur_pix, 0); - res = spiffs_page_delete(fs, cur_pix); - SPIFFS_CHECK_RES(res); - } + spiffs_page_header new_ph; + new_ph.flags = 0xff & ~(SPIFFS_PH_FLAG_USED | SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_FINAL); + new_ph.span_ix = p_hdr->span_ix; + spiffs_page_ix new_pix; + if ((objix_pix_lu && data_pix_lu && data_pix_ph && objix_pix_ph == 0) || + (objix_pix_lu == 0 && data_pix_ph && objix_pix_ph == 0)) { + // got a data page for page header obj id + // rewrite as obj_id_ph + new_ph.obj_id = p_hdr->obj_id | SPIFFS_OBJ_ID_IX_FLAG; + res = spiffs_rewrite_page(fs, cur_pix, &new_ph, &new_pix); + SPIFFS_CHECK_DBG("LU: FIXUP: rewrite page "_SPIPRIpg" as "_SPIPRIid" to pix "_SPIPRIpg"\n", cur_pix, new_ph.obj_id, new_pix); + CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_LOOKUP, p_hdr->obj_id, p_hdr->span_ix); + SPIFFS_CHECK_RES(res); + *reload_lu = 1; + } else if ((objix_pix_ph && data_pix_ph && data_pix_lu && objix_pix_lu == 0) || + (objix_pix_ph == 0 && data_pix_lu && objix_pix_lu == 0)) { + // got a data page for look up obj id + // rewrite as obj_id_lu + new_ph.obj_id = lu_obj_id | SPIFFS_OBJ_ID_IX_FLAG; + SPIFFS_CHECK_DBG("LU: FIXUP: rewrite page "_SPIPRIpg" as "_SPIPRIid"\n", cur_pix, new_ph.obj_id); + CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_LOOKUP, p_hdr->obj_id, p_hdr->span_ix); + res = spiffs_rewrite_page(fs, cur_pix, &new_ph, &new_pix); + SPIFFS_CHECK_RES(res); + *reload_lu = 1; + } else { + // cannot safely do anything + SPIFFS_CHECK_DBG("LU: FIXUP: nothing to do, just delete\n", NULL); + } + } + } + } + } else if (((lu_obj_id & SPIFFS_OBJ_ID_IX_FLAG) && (p_hdr->flags & SPIFFS_PH_FLAG_INDEX)) || + ((lu_obj_id & SPIFFS_OBJ_ID_IX_FLAG) == 0 && (p_hdr->flags & SPIFFS_PH_FLAG_INDEX) == 0)) { + SPIFFS_CHECK_DBG("LU: "_SPIPRIpg" lu/page index marking differ\n", cur_pix); + spiffs_page_ix data_pix, objix_pix_d; + // see if other data page exists for given obj id and span index + res = spiffs_obj_lu_find_id_and_span(fs, lu_obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, p_hdr->span_ix, cur_pix, &data_pix); + if (res == SPIFFS_ERR_NOT_FOUND) { + res = SPIFFS_OK; + data_pix = 0; + } + SPIFFS_CHECK_RES(res); + // see if other object index exists for given obj id and span index + res = spiffs_obj_lu_find_id_and_span(fs, lu_obj_id | SPIFFS_OBJ_ID_IX_FLAG, p_hdr->span_ix, cur_pix, &objix_pix_d); + if (res == SPIFFS_ERR_NOT_FOUND) { + res = SPIFFS_OK; + objix_pix_d = 0; + } + SPIFFS_CHECK_RES(res); - return res; + delete_page = 1; + // if other data page exists and object index exists, just delete page + if (data_pix && objix_pix_d) { + SPIFFS_CHECK_DBG("LU: FIXUP: other index and data page exists, simply remove\n", NULL); + } else + // if only data page exists, make this page index + if (data_pix && objix_pix_d == 0) { + SPIFFS_CHECK_DBG("LU: FIXUP: other data page exists, make this index\n", NULL); + CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_INDEX, lu_obj_id, p_hdr->span_ix); + spiffs_page_header new_ph; + spiffs_page_ix new_pix; + new_ph.flags = 0xff & ~(SPIFFS_PH_FLAG_USED | SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_INDEX); + new_ph.obj_id = lu_obj_id | SPIFFS_OBJ_ID_IX_FLAG; + new_ph.span_ix = p_hdr->span_ix; + res = spiffs_page_allocate_data(fs, new_ph.obj_id, &new_ph, 0, 0, 0, 1, &new_pix); + SPIFFS_CHECK_RES(res); + res = spiffs_phys_cpy(fs, 0, SPIFFS_PAGE_TO_PADDR(fs, new_pix) + sizeof(spiffs_page_header), + SPIFFS_PAGE_TO_PADDR(fs, cur_pix) + sizeof(spiffs_page_header), + SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_page_header)); + SPIFFS_CHECK_RES(res); + } else + // if only index exists, make data page + if (data_pix == 0 && objix_pix_d) { + SPIFFS_CHECK_DBG("LU: FIXUP: other index page exists, make this data\n", NULL); + CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_LOOKUP, lu_obj_id, p_hdr->span_ix); + spiffs_page_header new_ph; + spiffs_page_ix new_pix; + new_ph.flags = 0xff & ~(SPIFFS_PH_FLAG_USED | SPIFFS_PH_FLAG_FINAL); + new_ph.obj_id = lu_obj_id & ~SPIFFS_OBJ_ID_IX_FLAG; + new_ph.span_ix = p_hdr->span_ix; + res = spiffs_page_allocate_data(fs, new_ph.obj_id, &new_ph, 0, 0, 0, 1, &new_pix); + SPIFFS_CHECK_RES(res); + res = spiffs_phys_cpy(fs, 0, SPIFFS_PAGE_TO_PADDR(fs, new_pix) + sizeof(spiffs_page_header), + SPIFFS_PAGE_TO_PADDR(fs, cur_pix) + sizeof(spiffs_page_header), + SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_page_header)); + SPIFFS_CHECK_RES(res); + } else { + // if nothing exists, we cannot safely make a decision - delete + } + } else if ((p_hdr->flags & SPIFFS_PH_FLAG_DELET) == 0) { + SPIFFS_CHECK_DBG("LU: pix "_SPIPRIpg" busy in lu but deleted on page\n", cur_pix); + delete_page = 1; + } else if ((p_hdr->flags & SPIFFS_PH_FLAG_FINAL)) { + SPIFFS_CHECK_DBG("LU: pix "_SPIPRIpg" busy but not final\n", cur_pix); + // page can be removed if not referenced by object index + *reload_lu = 1; + res = spiffs_object_get_data_page_index_reference(fs, lu_obj_id, p_hdr->span_ix, &ref_pix, &objix_pix); + if (res == SPIFFS_ERR_NOT_FOUND) { + // no object with this id, so remove page safely + res = SPIFFS_OK; + delete_page = 1; + } else { + SPIFFS_CHECK_RES(res); + if (ref_pix != cur_pix) { + SPIFFS_CHECK_DBG("LU: FIXUP: other finalized page is referred, just delete\n", NULL); + delete_page = 1; + } else { + // page referenced by object index but not final + // just finalize + SPIFFS_CHECK_DBG("LU: FIXUP: unfinalized page is referred, finalizing\n", NULL); + CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_LOOKUP, p_hdr->obj_id, p_hdr->span_ix); + u8_t flags = 0xff; +#if SPIFFS_NO_BLIND_WRITES + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_READ, + 0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix) + offsetof(spiffs_page_header, flags), + sizeof(flags), &flags); + SPIFFS_CHECK_RES(res); +#endif + flags &= ~SPIFFS_PH_FLAG_FINAL; + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, + 0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix) + offsetof(spiffs_page_header, flags), + sizeof(flags), &flags); + } + } + } + } + + if (delete_page) { + SPIFFS_CHECK_DBG("LU: FIXUP: deleting page "_SPIPRIpg"\n", cur_pix); + CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_DELETE_PAGE, cur_pix, 0); + res = spiffs_page_delete(fs, cur_pix); + SPIFFS_CHECK_RES(res); + } + + return res; } static s32_t spiffs_lookup_check_v(spiffs *fs, spiffs_obj_id obj_id, spiffs_block_ix cur_block, int cur_entry, - const void *user_const_p, void *user_var_p) { - (void)user_const_p; - (void)user_var_p; - s32_t res = SPIFFS_OK; - spiffs_page_header p_hdr; - spiffs_page_ix cur_pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, cur_block, cur_entry); + const void *user_const_p, void *user_var_p) { + (void)user_const_p; + (void)user_var_p; + s32_t res = SPIFFS_OK; + spiffs_page_header p_hdr; + spiffs_page_ix cur_pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, cur_block, cur_entry); - CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_PROGRESS, - (cur_block * 256)/fs->block_count, 0); + CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_PROGRESS, + (cur_block * 256) / fs->block_count, 0); - // load header - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, - 0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix), sizeof(spiffs_page_header), (u8_t*)&p_hdr); - SPIFFS_CHECK_RES(res); + // load header + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, + 0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix), sizeof(spiffs_page_header), (u8_t *)&p_hdr); + SPIFFS_CHECK_RES(res); - int reload_lu = 0; + int reload_lu = 0; - res = spiffs_lookup_check_validate(fs, obj_id, &p_hdr, cur_pix, cur_block, cur_entry, &reload_lu); - SPIFFS_CHECK_RES(res); + res = spiffs_lookup_check_validate(fs, obj_id, &p_hdr, cur_pix, cur_block, cur_entry, &reload_lu); + SPIFFS_CHECK_RES(res); - if (res == SPIFFS_OK) { - return reload_lu ? SPIFFS_VIS_COUNTINUE_RELOAD : SPIFFS_VIS_COUNTINUE; - } - return res; + if (res == SPIFFS_OK) { + return reload_lu ? SPIFFS_VIS_COUNTINUE_RELOAD : SPIFFS_VIS_COUNTINUE; + } + return res; } // Scans all object look up. For each entry, corresponding page header is checked for validity. // If an object index header page is found, this is also checked s32_t spiffs_lookup_consistency_check(spiffs *fs, u8_t check_all_objects) { - (void)check_all_objects; - s32_t res = SPIFFS_OK; + (void)check_all_objects; + s32_t res = SPIFFS_OK; - CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_PROGRESS, 0, 0); + CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_PROGRESS, 0, 0); - res = spiffs_obj_lu_find_entry_visitor(fs, 0, 0, 0, 0, spiffs_lookup_check_v, 0, 0, 0, 0); + res = spiffs_obj_lu_find_entry_visitor(fs, 0, 0, 0, 0, spiffs_lookup_check_v, 0, 0, 0, 0); - if (res == SPIFFS_VIS_END) { - res = SPIFFS_OK; - } + if (res == SPIFFS_VIS_END) { + res = SPIFFS_OK; + } - if (res != SPIFFS_OK) { - CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_ERROR, res, 0); - } + if (res != SPIFFS_OK) { + CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_ERROR, res, 0); + } - CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_PROGRESS, 256, 0); + CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_PROGRESS, 256, 0); - return res; + return res; } //--------------------------------------- @@ -520,355 +519,354 @@ s32_t spiffs_lookup_consistency_check(spiffs *fs, u8_t check_all_objects) { // * x101 used, unreferenced, index // The working memory might not fit all pages so several scans might be needed static s32_t spiffs_page_consistency_check_i(spiffs *fs) { - const u32_t bits = 4; - const spiffs_page_ix pages_per_scan = SPIFFS_CFG_LOG_PAGE_SZ(fs) * 8 / bits; + const u32_t bits = 4; + const spiffs_page_ix pages_per_scan = SPIFFS_CFG_LOG_PAGE_SZ(fs) * 8 / bits; - s32_t res = SPIFFS_OK; - spiffs_page_ix pix_offset = 0; + s32_t res = SPIFFS_OK; + spiffs_page_ix pix_offset = 0; - // for each range of pages fitting into work memory - while (pix_offset < SPIFFS_PAGES_PER_BLOCK(fs) * fs->block_count) { - // set this flag to abort all checks and rescan the page range - u8_t restart = 0; - memset(fs->work, 0, SPIFFS_CFG_LOG_PAGE_SZ(fs)); + // for each range of pages fitting into work memory + while (pix_offset < SPIFFS_PAGES_PER_BLOCK(fs) * fs->block_count) { + // set this flag to abort all checks and rescan the page range + u8_t restart = 0; + memset(fs->work, 0, SPIFFS_CFG_LOG_PAGE_SZ(fs)); - spiffs_block_ix cur_block = 0; - // build consistency bitmap for id range traversing all blocks - while (!restart && cur_block < fs->block_count) { - CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_PROGRESS, - (pix_offset*256)/(SPIFFS_PAGES_PER_BLOCK(fs) * fs->block_count) + - ((((cur_block * pages_per_scan * 256)/ (SPIFFS_PAGES_PER_BLOCK(fs) * fs->block_count))) / fs->block_count), - 0); - // traverse each page except for lookup pages - spiffs_page_ix cur_pix = SPIFFS_OBJ_LOOKUP_PAGES(fs) + SPIFFS_PAGES_PER_BLOCK(fs) * cur_block; - while (!restart && cur_pix < SPIFFS_PAGES_PER_BLOCK(fs) * (cur_block+1)) { - //if ((cur_pix & 0xff) == 0) - // SPIFFS_CHECK_DBG("PA: processing pix "_SPIPRIpg", block "_SPIPRIbl" of pix "_SPIPRIpg", block "_SPIPRIbl"\n", - // cur_pix, cur_block, SPIFFS_PAGES_PER_BLOCK(fs) * fs->block_count, fs->block_count); + spiffs_block_ix cur_block = 0; + // build consistency bitmap for id range traversing all blocks + while (!restart && cur_block < fs->block_count) { + CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_PROGRESS, + (pix_offset * 256) / (SPIFFS_PAGES_PER_BLOCK(fs) * fs->block_count) + + ((((cur_block * pages_per_scan * 256) / (SPIFFS_PAGES_PER_BLOCK(fs) * fs->block_count))) / fs->block_count), + 0); + // traverse each page except for lookup pages + spiffs_page_ix cur_pix = SPIFFS_OBJ_LOOKUP_PAGES(fs) + SPIFFS_PAGES_PER_BLOCK(fs) * cur_block; + while (!restart && cur_pix < SPIFFS_PAGES_PER_BLOCK(fs) * (cur_block + 1)) { + //if ((cur_pix & 0xff) == 0) + // SPIFFS_CHECK_DBG("PA: processing pix "_SPIPRIpg", block "_SPIPRIbl" of pix "_SPIPRIpg", block "_SPIPRIbl"\n", + // cur_pix, cur_block, SPIFFS_PAGES_PER_BLOCK(fs) * fs->block_count, fs->block_count); - // read header - spiffs_page_header p_hdr; - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, - 0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix), sizeof(spiffs_page_header), (u8_t*)&p_hdr); - SPIFFS_CHECK_RES(res); - - u8_t within_range = (cur_pix >= pix_offset && cur_pix < pix_offset + pages_per_scan); - const u32_t pix_byte_ix = (cur_pix - pix_offset) / (8/bits); - const u8_t pix_bit_ix = (cur_pix & ((8/bits)-1)) * bits; - - if (within_range && - (p_hdr.flags & SPIFFS_PH_FLAG_DELET) && (p_hdr.flags & SPIFFS_PH_FLAG_USED) == 0) { - // used - fs->work[pix_byte_ix] |= (1<<(pix_bit_ix + 0)); - } - if ((p_hdr.flags & SPIFFS_PH_FLAG_DELET) && - (p_hdr.flags & SPIFFS_PH_FLAG_IXDELE) && - (p_hdr.flags & (SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_USED)) == 0) { - // found non-deleted index - if (within_range) { - fs->work[pix_byte_ix] |= (1<<(pix_bit_ix + 2)); - } - - // load non-deleted index - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, - 0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); - SPIFFS_CHECK_RES(res); - - // traverse index for referenced pages - spiffs_page_ix *object_page_index; - spiffs_page_header *objix_p_hdr = (spiffs_page_header *)fs->lu_work; - - int entries; - int i; - spiffs_span_ix data_spix_offset; - if (p_hdr.span_ix == 0) { - // object header page index - entries = SPIFFS_OBJ_HDR_IX_LEN(fs); - data_spix_offset = 0; - object_page_index = (spiffs_page_ix *)((u8_t *)fs->lu_work + sizeof(spiffs_page_object_ix_header)); - } else { - // object page index - entries = SPIFFS_OBJ_IX_LEN(fs); - data_spix_offset = SPIFFS_OBJ_HDR_IX_LEN(fs) + SPIFFS_OBJ_IX_LEN(fs) * (p_hdr.span_ix - 1); - object_page_index = (spiffs_page_ix *)((u8_t *)fs->lu_work + sizeof(spiffs_page_object_ix)); - } - - // for all entries in index - for (i = 0; !restart && i < entries; i++) { - spiffs_page_ix rpix = object_page_index[i]; - u8_t rpix_within_range = rpix >= pix_offset && rpix < pix_offset + pages_per_scan; - - if ((rpix != (spiffs_page_ix)-1 && rpix > SPIFFS_MAX_PAGES(fs)) - || (rpix_within_range && SPIFFS_IS_LOOKUP_PAGE(fs, rpix))) { - - // bad reference - SPIFFS_CHECK_DBG("PA: pix "_SPIPRIpg"x bad pix / LU referenced from page "_SPIPRIpg"\n", - rpix, cur_pix); - // check for data page elsewhere - spiffs_page_ix data_pix; - res = spiffs_obj_lu_find_id_and_span(fs, objix_p_hdr->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, - data_spix_offset + i, 0, &data_pix); - if (res == SPIFFS_ERR_NOT_FOUND) { - res = SPIFFS_OK; - data_pix = 0; - } - SPIFFS_CHECK_RES(res); - if (data_pix == 0) { - // if not, allocate free page - spiffs_page_header new_ph; - new_ph.flags = 0xff & ~(SPIFFS_PH_FLAG_USED | SPIFFS_PH_FLAG_FINAL); - new_ph.obj_id = objix_p_hdr->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG; - new_ph.span_ix = data_spix_offset + i; - res = spiffs_page_allocate_data(fs, new_ph.obj_id, &new_ph, 0, 0, 0, 1, &data_pix); - SPIFFS_CHECK_RES(res); - SPIFFS_CHECK_DBG("PA: FIXUP: found no existing data page, created new @ "_SPIPRIpg"\n", data_pix); - } - // remap index - SPIFFS_CHECK_DBG("PA: FIXUP: rewriting index pix "_SPIPRIpg"\n", cur_pix); - res = spiffs_rewrite_index(fs, objix_p_hdr->obj_id | SPIFFS_OBJ_ID_IX_FLAG, - data_spix_offset + i, data_pix, cur_pix); - if (res <= _SPIFFS_ERR_CHECK_FIRST && res > _SPIFFS_ERR_CHECK_LAST) { - // index bad also, cannot mend this file - SPIFFS_CHECK_DBG("PA: FIXUP: index bad "_SPIPRIi", cannot mend - delete object\n", res); - CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_DELETE_BAD_FILE, objix_p_hdr->obj_id, 0); - // delete file - res = spiffs_page_delete(fs, cur_pix); - } else { - CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_FIX_INDEX, objix_p_hdr->obj_id, objix_p_hdr->span_ix); - } - SPIFFS_CHECK_RES(res); - restart = 1; - - } else if (rpix_within_range) { - - // valid reference - // read referenced page header - spiffs_page_header rp_hdr; - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, - 0, SPIFFS_PAGE_TO_PADDR(fs, rpix), sizeof(spiffs_page_header), (u8_t*)&rp_hdr); - SPIFFS_CHECK_RES(res); - - // cross reference page header check - if (rp_hdr.obj_id != (p_hdr.obj_id & ~SPIFFS_OBJ_ID_IX_FLAG) || - rp_hdr.span_ix != data_spix_offset + i || - (rp_hdr.flags & (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_USED)) != - (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_INDEX)) { - SPIFFS_CHECK_DBG("PA: pix "_SPIPRIpg" has inconsistent page header ix id/span:"_SPIPRIid"/"_SPIPRIsp", ref id/span:"_SPIPRIid"/"_SPIPRIsp" flags:"_SPIPRIfl"\n", - rpix, p_hdr.obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, data_spix_offset + i, - rp_hdr.obj_id, rp_hdr.span_ix, rp_hdr.flags); - // try finding correct page - spiffs_page_ix data_pix; - res = spiffs_obj_lu_find_id_and_span(fs, p_hdr.obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, - data_spix_offset + i, rpix, &data_pix); - if (res == SPIFFS_ERR_NOT_FOUND) { - res = SPIFFS_OK; - data_pix = 0; - } - SPIFFS_CHECK_RES(res); - if (data_pix == 0) { - // not found, this index is badly borked - SPIFFS_CHECK_DBG("PA: FIXUP: index bad, delete object id "_SPIPRIid"\n", p_hdr.obj_id); - CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_DELETE_BAD_FILE, p_hdr.obj_id, 0); - res = spiffs_delete_obj_lazy(fs, p_hdr.obj_id); - SPIFFS_CHECK_RES(res); - break; - } else { - // found it, so rewrite index - SPIFFS_CHECK_DBG("PA: FIXUP: found correct data pix "_SPIPRIpg", rewrite ix pix "_SPIPRIpg" id "_SPIPRIid"\n", - data_pix, cur_pix, p_hdr.obj_id); - res = spiffs_rewrite_index(fs, p_hdr.obj_id, data_spix_offset + i, data_pix, cur_pix); - if (res <= _SPIFFS_ERR_CHECK_FIRST && res > _SPIFFS_ERR_CHECK_LAST) { - // index bad also, cannot mend this file - SPIFFS_CHECK_DBG("PA: FIXUP: index bad "_SPIPRIi", cannot mend!\n", res); - CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_DELETE_BAD_FILE, p_hdr.obj_id, 0); - res = spiffs_delete_obj_lazy(fs, p_hdr.obj_id); - } else { - CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_FIX_INDEX, p_hdr.obj_id, p_hdr.span_ix); - } - SPIFFS_CHECK_RES(res); - restart = 1; - } - } - else { - // mark rpix as referenced - const u32_t rpix_byte_ix = (rpix - pix_offset) / (8/bits); - const u8_t rpix_bit_ix = (rpix & ((8/bits)-1)) * bits; - if (fs->work[rpix_byte_ix] & (1<<(rpix_bit_ix + 1))) { - SPIFFS_CHECK_DBG("PA: pix "_SPIPRIpg" multiple referenced from page "_SPIPRIpg"\n", - rpix, cur_pix); - // Here, we should have fixed all broken references - getting this means there - // must be multiple files with same object id. Only solution is to delete - // the object which is referring to this page - SPIFFS_CHECK_DBG("PA: FIXUP: removing object "_SPIPRIid" and page "_SPIPRIpg"\n", - p_hdr.obj_id, cur_pix); - CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_DELETE_BAD_FILE, p_hdr.obj_id, 0); - res = spiffs_delete_obj_lazy(fs, p_hdr.obj_id); - SPIFFS_CHECK_RES(res); - // extra precaution, delete this page also - res = spiffs_page_delete(fs, cur_pix); - SPIFFS_CHECK_RES(res); - restart = 1; - } - fs->work[rpix_byte_ix] |= (1<<(rpix_bit_ix + 1)); - } - } - } // for all index entries - } // found index - - // next page - cur_pix++; - } - // next block - cur_block++; - } - // check consistency bitmap - if (!restart) { - spiffs_page_ix objix_pix; - spiffs_page_ix rpix; - - u32_t byte_ix; - u8_t bit_ix; - for (byte_ix = 0; !restart && byte_ix < SPIFFS_CFG_LOG_PAGE_SZ(fs); byte_ix++) { - for (bit_ix = 0; !restart && bit_ix < 8/bits; bit_ix ++) { - u8_t bitmask = (fs->work[byte_ix] >> (bit_ix * bits)) & 0x7; - spiffs_page_ix cur_pix = pix_offset + byte_ix * (8/bits) + bit_ix; - - // 000 ok - free, unreferenced, not index - - if (bitmask == 0x1) { - - // 001 - SPIFFS_CHECK_DBG("PA: pix "_SPIPRIpg" USED, UNREFERENCED, not index\n", cur_pix); - - u8_t rewrite_ix_to_this = 0; - u8_t delete_page = 0; - // check corresponding object index entry - spiffs_page_header p_hdr; - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, - 0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix), sizeof(spiffs_page_header), (u8_t*)&p_hdr); - SPIFFS_CHECK_RES(res); - - res = spiffs_object_get_data_page_index_reference(fs, p_hdr.obj_id, p_hdr.span_ix, - &rpix, &objix_pix); - if (res == SPIFFS_OK) { - if (((rpix == (spiffs_page_ix)-1 || rpix > SPIFFS_MAX_PAGES(fs)) || (SPIFFS_IS_LOOKUP_PAGE(fs, rpix)))) { - // pointing to a bad page altogether, rewrite index to this - rewrite_ix_to_this = 1; - SPIFFS_CHECK_DBG("PA: corresponding ref is bad: "_SPIPRIpg", rewrite to this "_SPIPRIpg"\n", rpix, cur_pix); - } else { - // pointing to something else, check what - spiffs_page_header rp_hdr; + // read header + spiffs_page_header p_hdr; res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, - 0, SPIFFS_PAGE_TO_PADDR(fs, rpix), sizeof(spiffs_page_header), (u8_t*)&rp_hdr); + 0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix), sizeof(spiffs_page_header), (u8_t *)&p_hdr); SPIFFS_CHECK_RES(res); - if (((p_hdr.obj_id & ~SPIFFS_OBJ_ID_IX_FLAG) == rp_hdr.obj_id) && - ((rp_hdr.flags & (SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_USED | SPIFFS_PH_FLAG_FINAL)) == - (SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_DELET))) { - // pointing to something else valid, just delete this page then - SPIFFS_CHECK_DBG("PA: corresponding ref is good but different: "_SPIPRIpg", delete this "_SPIPRIpg"\n", rpix, cur_pix); - delete_page = 1; - } else { - // pointing to something weird, update index to point to this page instead - if (rpix != cur_pix) { - SPIFFS_CHECK_DBG("PA: corresponding ref is weird: "_SPIPRIpg" %s%s%s%s, rewrite this "_SPIPRIpg"\n", rpix, - (rp_hdr.flags & SPIFFS_PH_FLAG_INDEX) ? "" : "INDEX ", - (rp_hdr.flags & SPIFFS_PH_FLAG_DELET) ? "" : "DELETED ", - (rp_hdr.flags & SPIFFS_PH_FLAG_USED) ? "NOTUSED " : "", - (rp_hdr.flags & SPIFFS_PH_FLAG_FINAL) ? "NOTFINAL " : "", - cur_pix); - rewrite_ix_to_this = 1; - } else { - // should not happen, destined for fubar - } + + u8_t within_range = (cur_pix >= pix_offset && cur_pix < pix_offset + pages_per_scan); + const u32_t pix_byte_ix = (cur_pix - pix_offset) / (8 / bits); + const u8_t pix_bit_ix = (cur_pix & ((8 / bits) - 1)) * bits; + + if (within_range && + (p_hdr.flags & SPIFFS_PH_FLAG_DELET) && (p_hdr.flags & SPIFFS_PH_FLAG_USED) == 0) { + // used + fs->work[pix_byte_ix] |= (1 << (pix_bit_ix + 0)); } - } - } else if (res == SPIFFS_ERR_NOT_FOUND) { - SPIFFS_CHECK_DBG("PA: corresponding ref not found, delete "_SPIPRIpg"\n", cur_pix); - delete_page = 1; - res = SPIFFS_OK; + if ((p_hdr.flags & SPIFFS_PH_FLAG_DELET) && + (p_hdr.flags & SPIFFS_PH_FLAG_IXDELE) && + (p_hdr.flags & (SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_USED)) == 0) { + // found non-deleted index + if (within_range) { + fs->work[pix_byte_ix] |= (1 << (pix_bit_ix + 2)); + } + + // load non-deleted index + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, + 0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); + SPIFFS_CHECK_RES(res); + + // traverse index for referenced pages + spiffs_page_ix *object_page_index; + spiffs_page_header *objix_p_hdr = (spiffs_page_header *)fs->lu_work; + + int entries; + int i; + spiffs_span_ix data_spix_offset; + if (p_hdr.span_ix == 0) { + // object header page index + entries = SPIFFS_OBJ_HDR_IX_LEN(fs); + data_spix_offset = 0; + object_page_index = (spiffs_page_ix *)((u8_t *)fs->lu_work + sizeof(spiffs_page_object_ix_header)); + } else { + // object page index + entries = SPIFFS_OBJ_IX_LEN(fs); + data_spix_offset = SPIFFS_OBJ_HDR_IX_LEN(fs) + SPIFFS_OBJ_IX_LEN(fs) * (p_hdr.span_ix - 1); + object_page_index = (spiffs_page_ix *)((u8_t *)fs->lu_work + sizeof(spiffs_page_object_ix)); + } + + // for all entries in index + for (i = 0; !restart && i < entries; i++) { + spiffs_page_ix rpix = object_page_index[i]; + u8_t rpix_within_range = rpix >= pix_offset && rpix < pix_offset + pages_per_scan; + + if ((rpix != (spiffs_page_ix) - 1 && rpix > SPIFFS_MAX_PAGES(fs)) + || (rpix_within_range && SPIFFS_IS_LOOKUP_PAGE(fs, rpix))) { + + // bad reference + SPIFFS_CHECK_DBG("PA: pix "_SPIPRIpg"x bad pix / LU referenced from page "_SPIPRIpg"\n", + rpix, cur_pix); + // check for data page elsewhere + spiffs_page_ix data_pix; + res = spiffs_obj_lu_find_id_and_span(fs, objix_p_hdr->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, + data_spix_offset + i, 0, &data_pix); + if (res == SPIFFS_ERR_NOT_FOUND) { + res = SPIFFS_OK; + data_pix = 0; + } + SPIFFS_CHECK_RES(res); + if (data_pix == 0) { + // if not, allocate free page + spiffs_page_header new_ph; + new_ph.flags = 0xff & ~(SPIFFS_PH_FLAG_USED | SPIFFS_PH_FLAG_FINAL); + new_ph.obj_id = objix_p_hdr->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG; + new_ph.span_ix = data_spix_offset + i; + res = spiffs_page_allocate_data(fs, new_ph.obj_id, &new_ph, 0, 0, 0, 1, &data_pix); + SPIFFS_CHECK_RES(res); + SPIFFS_CHECK_DBG("PA: FIXUP: found no existing data page, created new @ "_SPIPRIpg"\n", data_pix); + } + // remap index + SPIFFS_CHECK_DBG("PA: FIXUP: rewriting index pix "_SPIPRIpg"\n", cur_pix); + res = spiffs_rewrite_index(fs, objix_p_hdr->obj_id | SPIFFS_OBJ_ID_IX_FLAG, + data_spix_offset + i, data_pix, cur_pix); + if (res <= _SPIFFS_ERR_CHECK_FIRST && res > _SPIFFS_ERR_CHECK_LAST) { + // index bad also, cannot mend this file + SPIFFS_CHECK_DBG("PA: FIXUP: index bad "_SPIPRIi", cannot mend - delete object\n", res); + CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_DELETE_BAD_FILE, objix_p_hdr->obj_id, 0); + // delete file + res = spiffs_page_delete(fs, cur_pix); + } else { + CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_FIX_INDEX, objix_p_hdr->obj_id, objix_p_hdr->span_ix); + } + SPIFFS_CHECK_RES(res); + restart = 1; + + } else if (rpix_within_range) { + + // valid reference + // read referenced page header + spiffs_page_header rp_hdr; + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, + 0, SPIFFS_PAGE_TO_PADDR(fs, rpix), sizeof(spiffs_page_header), (u8_t *)&rp_hdr); + SPIFFS_CHECK_RES(res); + + // cross reference page header check + if (rp_hdr.obj_id != (p_hdr.obj_id & ~SPIFFS_OBJ_ID_IX_FLAG) || + rp_hdr.span_ix != data_spix_offset + i || + (rp_hdr.flags & (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_USED)) != + (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_INDEX)) { + SPIFFS_CHECK_DBG("PA: pix "_SPIPRIpg" has inconsistent page header ix id/span:"_SPIPRIid"/"_SPIPRIsp", ref id/span:"_SPIPRIid"/"_SPIPRIsp" flags:"_SPIPRIfl"\n", + rpix, p_hdr.obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, data_spix_offset + i, + rp_hdr.obj_id, rp_hdr.span_ix, rp_hdr.flags); + // try finding correct page + spiffs_page_ix data_pix; + res = spiffs_obj_lu_find_id_and_span(fs, p_hdr.obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, + data_spix_offset + i, rpix, &data_pix); + if (res == SPIFFS_ERR_NOT_FOUND) { + res = SPIFFS_OK; + data_pix = 0; + } + SPIFFS_CHECK_RES(res); + if (data_pix == 0) { + // not found, this index is badly borked + SPIFFS_CHECK_DBG("PA: FIXUP: index bad, delete object id "_SPIPRIid"\n", p_hdr.obj_id); + CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_DELETE_BAD_FILE, p_hdr.obj_id, 0); + res = spiffs_delete_obj_lazy(fs, p_hdr.obj_id); + SPIFFS_CHECK_RES(res); + break; + } else { + // found it, so rewrite index + SPIFFS_CHECK_DBG("PA: FIXUP: found correct data pix "_SPIPRIpg", rewrite ix pix "_SPIPRIpg" id "_SPIPRIid"\n", + data_pix, cur_pix, p_hdr.obj_id); + res = spiffs_rewrite_index(fs, p_hdr.obj_id, data_spix_offset + i, data_pix, cur_pix); + if (res <= _SPIFFS_ERR_CHECK_FIRST && res > _SPIFFS_ERR_CHECK_LAST) { + // index bad also, cannot mend this file + SPIFFS_CHECK_DBG("PA: FIXUP: index bad "_SPIPRIi", cannot mend!\n", res); + CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_DELETE_BAD_FILE, p_hdr.obj_id, 0); + res = spiffs_delete_obj_lazy(fs, p_hdr.obj_id); + } else { + CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_FIX_INDEX, p_hdr.obj_id, p_hdr.span_ix); + } + SPIFFS_CHECK_RES(res); + restart = 1; + } + } else { + // mark rpix as referenced + const u32_t rpix_byte_ix = (rpix - pix_offset) / (8 / bits); + const u8_t rpix_bit_ix = (rpix & ((8 / bits) - 1)) * bits; + if (fs->work[rpix_byte_ix] & (1 << (rpix_bit_ix + 1))) { + SPIFFS_CHECK_DBG("PA: pix "_SPIPRIpg" multiple referenced from page "_SPIPRIpg"\n", + rpix, cur_pix); + // Here, we should have fixed all broken references - getting this means there + // must be multiple files with same object id. Only solution is to delete + // the object which is referring to this page + SPIFFS_CHECK_DBG("PA: FIXUP: removing object "_SPIPRIid" and page "_SPIPRIpg"\n", + p_hdr.obj_id, cur_pix); + CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_DELETE_BAD_FILE, p_hdr.obj_id, 0); + res = spiffs_delete_obj_lazy(fs, p_hdr.obj_id); + SPIFFS_CHECK_RES(res); + // extra precaution, delete this page also + res = spiffs_page_delete(fs, cur_pix); + SPIFFS_CHECK_RES(res); + restart = 1; + } + fs->work[rpix_byte_ix] |= (1 << (rpix_bit_ix + 1)); + } + } + } // for all index entries + } // found index + + // next page + cur_pix++; } - - if (rewrite_ix_to_this) { - // if pointing to invalid page, redirect index to this page - SPIFFS_CHECK_DBG("PA: FIXUP: rewrite index id "_SPIPRIid" data spix "_SPIPRIsp" to point to this pix: "_SPIPRIpg"\n", - p_hdr.obj_id, p_hdr.span_ix, cur_pix); - res = spiffs_rewrite_index(fs, p_hdr.obj_id, p_hdr.span_ix, cur_pix, objix_pix); - if (res <= _SPIFFS_ERR_CHECK_FIRST && res > _SPIFFS_ERR_CHECK_LAST) { - // index bad also, cannot mend this file - SPIFFS_CHECK_DBG("PA: FIXUP: index bad "_SPIPRIi", cannot mend!\n", res); - CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_DELETE_BAD_FILE, p_hdr.obj_id, 0); - res = spiffs_page_delete(fs, cur_pix); - SPIFFS_CHECK_RES(res); - res = spiffs_delete_obj_lazy(fs, p_hdr.obj_id); - } else { - CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_FIX_INDEX, p_hdr.obj_id, p_hdr.span_ix); - } - SPIFFS_CHECK_RES(res); - restart = 1; - continue; - } else if (delete_page) { - SPIFFS_CHECK_DBG("PA: FIXUP: deleting page "_SPIPRIpg"\n", cur_pix); - CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_DELETE_PAGE, cur_pix, 0); - res = spiffs_page_delete(fs, cur_pix); - } - SPIFFS_CHECK_RES(res); - } - if (bitmask == 0x2) { - - // 010 - SPIFFS_CHECK_DBG("PA: pix "_SPIPRIpg" FREE, REFERENCED, not index\n", cur_pix); - - // no op, this should be taken care of when checking valid references - } - - // 011 ok - busy, referenced, not index - - if (bitmask == 0x4) { - - // 100 - SPIFFS_CHECK_DBG("PA: pix "_SPIPRIpg" FREE, unreferenced, INDEX\n", cur_pix); - - // this should never happen, major fubar - } - - // 101 ok - busy, unreferenced, index - - if (bitmask == 0x6) { - - // 110 - SPIFFS_CHECK_DBG("PA: pix "_SPIPRIpg" FREE, REFERENCED, INDEX\n", cur_pix); - - // no op, this should be taken care of when checking valid references - } - if (bitmask == 0x7) { - - // 111 - SPIFFS_CHECK_DBG("PA: pix "_SPIPRIpg" USED, REFERENCED, INDEX\n", cur_pix); - - // no op, this should be taken care of when checking valid references - } + // next block + cur_block++; } - } - } + // check consistency bitmap + if (!restart) { + spiffs_page_ix objix_pix; + spiffs_page_ix rpix; - SPIFFS_CHECK_DBG("PA: processed "_SPIPRIpg", restart "_SPIPRIi"\n", pix_offset, restart); - // next page range - if (!restart) { - pix_offset += pages_per_scan; - } - } // while page range not reached end - return res; + u32_t byte_ix; + u8_t bit_ix; + for (byte_ix = 0; !restart && byte_ix < SPIFFS_CFG_LOG_PAGE_SZ(fs); byte_ix++) { + for (bit_ix = 0; !restart && bit_ix < 8 / bits; bit_ix ++) { + u8_t bitmask = (fs->work[byte_ix] >> (bit_ix * bits)) & 0x7; + spiffs_page_ix cur_pix = pix_offset + byte_ix * (8 / bits) + bit_ix; + + // 000 ok - free, unreferenced, not index + + if (bitmask == 0x1) { + + // 001 + SPIFFS_CHECK_DBG("PA: pix "_SPIPRIpg" USED, UNREFERENCED, not index\n", cur_pix); + + u8_t rewrite_ix_to_this = 0; + u8_t delete_page = 0; + // check corresponding object index entry + spiffs_page_header p_hdr; + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, + 0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix), sizeof(spiffs_page_header), (u8_t *)&p_hdr); + SPIFFS_CHECK_RES(res); + + res = spiffs_object_get_data_page_index_reference(fs, p_hdr.obj_id, p_hdr.span_ix, + &rpix, &objix_pix); + if (res == SPIFFS_OK) { + if (((rpix == (spiffs_page_ix) - 1 || rpix > SPIFFS_MAX_PAGES(fs)) || (SPIFFS_IS_LOOKUP_PAGE(fs, rpix)))) { + // pointing to a bad page altogether, rewrite index to this + rewrite_ix_to_this = 1; + SPIFFS_CHECK_DBG("PA: corresponding ref is bad: "_SPIPRIpg", rewrite to this "_SPIPRIpg"\n", rpix, cur_pix); + } else { + // pointing to something else, check what + spiffs_page_header rp_hdr; + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, + 0, SPIFFS_PAGE_TO_PADDR(fs, rpix), sizeof(spiffs_page_header), (u8_t *)&rp_hdr); + SPIFFS_CHECK_RES(res); + if (((p_hdr.obj_id & ~SPIFFS_OBJ_ID_IX_FLAG) == rp_hdr.obj_id) && + ((rp_hdr.flags & (SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_USED | SPIFFS_PH_FLAG_FINAL)) == + (SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_DELET))) { + // pointing to something else valid, just delete this page then + SPIFFS_CHECK_DBG("PA: corresponding ref is good but different: "_SPIPRIpg", delete this "_SPIPRIpg"\n", rpix, cur_pix); + delete_page = 1; + } else { + // pointing to something weird, update index to point to this page instead + if (rpix != cur_pix) { + SPIFFS_CHECK_DBG("PA: corresponding ref is weird: "_SPIPRIpg" %s%s%s%s, rewrite this "_SPIPRIpg"\n", rpix, + (rp_hdr.flags & SPIFFS_PH_FLAG_INDEX) ? "" : "INDEX ", + (rp_hdr.flags & SPIFFS_PH_FLAG_DELET) ? "" : "DELETED ", + (rp_hdr.flags & SPIFFS_PH_FLAG_USED) ? "NOTUSED " : "", + (rp_hdr.flags & SPIFFS_PH_FLAG_FINAL) ? "NOTFINAL " : "", + cur_pix); + rewrite_ix_to_this = 1; + } else { + // should not happen, destined for fubar + } + } + } + } else if (res == SPIFFS_ERR_NOT_FOUND) { + SPIFFS_CHECK_DBG("PA: corresponding ref not found, delete "_SPIPRIpg"\n", cur_pix); + delete_page = 1; + res = SPIFFS_OK; + } + + if (rewrite_ix_to_this) { + // if pointing to invalid page, redirect index to this page + SPIFFS_CHECK_DBG("PA: FIXUP: rewrite index id "_SPIPRIid" data spix "_SPIPRIsp" to point to this pix: "_SPIPRIpg"\n", + p_hdr.obj_id, p_hdr.span_ix, cur_pix); + res = spiffs_rewrite_index(fs, p_hdr.obj_id, p_hdr.span_ix, cur_pix, objix_pix); + if (res <= _SPIFFS_ERR_CHECK_FIRST && res > _SPIFFS_ERR_CHECK_LAST) { + // index bad also, cannot mend this file + SPIFFS_CHECK_DBG("PA: FIXUP: index bad "_SPIPRIi", cannot mend!\n", res); + CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_DELETE_BAD_FILE, p_hdr.obj_id, 0); + res = spiffs_page_delete(fs, cur_pix); + SPIFFS_CHECK_RES(res); + res = spiffs_delete_obj_lazy(fs, p_hdr.obj_id); + } else { + CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_FIX_INDEX, p_hdr.obj_id, p_hdr.span_ix); + } + SPIFFS_CHECK_RES(res); + restart = 1; + continue; + } else if (delete_page) { + SPIFFS_CHECK_DBG("PA: FIXUP: deleting page "_SPIPRIpg"\n", cur_pix); + CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_DELETE_PAGE, cur_pix, 0); + res = spiffs_page_delete(fs, cur_pix); + } + SPIFFS_CHECK_RES(res); + } + if (bitmask == 0x2) { + + // 010 + SPIFFS_CHECK_DBG("PA: pix "_SPIPRIpg" FREE, REFERENCED, not index\n", cur_pix); + + // no op, this should be taken care of when checking valid references + } + + // 011 ok - busy, referenced, not index + + if (bitmask == 0x4) { + + // 100 + SPIFFS_CHECK_DBG("PA: pix "_SPIPRIpg" FREE, unreferenced, INDEX\n", cur_pix); + + // this should never happen, major fubar + } + + // 101 ok - busy, unreferenced, index + + if (bitmask == 0x6) { + + // 110 + SPIFFS_CHECK_DBG("PA: pix "_SPIPRIpg" FREE, REFERENCED, INDEX\n", cur_pix); + + // no op, this should be taken care of when checking valid references + } + if (bitmask == 0x7) { + + // 111 + SPIFFS_CHECK_DBG("PA: pix "_SPIPRIpg" USED, REFERENCED, INDEX\n", cur_pix); + + // no op, this should be taken care of when checking valid references + } + } + } + } + + SPIFFS_CHECK_DBG("PA: processed "_SPIPRIpg", restart "_SPIPRIi"\n", pix_offset, restart); + // next page range + if (!restart) { + pix_offset += pages_per_scan; + } + } // while page range not reached end + return res; } // Checks consistency amongst all pages and fixes irregularities s32_t spiffs_page_consistency_check(spiffs *fs) { - CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_PROGRESS, 0, 0); - s32_t res = spiffs_page_consistency_check_i(fs); - if (res != SPIFFS_OK) { - CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_ERROR, res, 0); - } - CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_PROGRESS, 256, 0); - return res; + CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_PROGRESS, 0, 0); + s32_t res = spiffs_page_consistency_check_i(fs); + if (res != SPIFFS_OK) { + CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_ERROR, res, 0); + } + CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_PROGRESS, 256, 0); + return res; } //--------------------------------------- @@ -877,106 +875,106 @@ s32_t spiffs_page_consistency_check(spiffs *fs) { // searches for given object id in temporary object id index, // returns the index or -1 static int spiffs_object_index_search(spiffs *fs, spiffs_obj_id obj_id) { - u32_t i; - spiffs_obj_id *obj_table = (spiffs_obj_id *)fs->work; - obj_id &= ~SPIFFS_OBJ_ID_IX_FLAG; - for (i = 0; i < SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id); i++) { - if ((obj_table[i] & ~SPIFFS_OBJ_ID_IX_FLAG) == obj_id) { - return i; + u32_t i; + spiffs_obj_id *obj_table = (spiffs_obj_id *)fs->work; + obj_id &= ~SPIFFS_OBJ_ID_IX_FLAG; + for (i = 0; i < SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id); i++) { + if ((obj_table[i] & ~SPIFFS_OBJ_ID_IX_FLAG) == obj_id) { + return i; + } } - } - return -1; + return -1; } static s32_t spiffs_object_index_consistency_check_v(spiffs *fs, spiffs_obj_id obj_id, spiffs_block_ix cur_block, - int cur_entry, const void *user_const_p, void *user_var_p) { - (void)user_const_p; - s32_t res_c = SPIFFS_VIS_COUNTINUE; - s32_t res = SPIFFS_OK; - u32_t *log_ix = (u32_t*)user_var_p; - spiffs_obj_id *obj_table = (spiffs_obj_id *)fs->work; + int cur_entry, const void *user_const_p, void *user_var_p) { + (void)user_const_p; + s32_t res_c = SPIFFS_VIS_COUNTINUE; + s32_t res = SPIFFS_OK; + u32_t *log_ix = (u32_t *)user_var_p; + spiffs_obj_id *obj_table = (spiffs_obj_id *)fs->work; - CHECK_CB(fs, SPIFFS_CHECK_INDEX, SPIFFS_CHECK_PROGRESS, - (cur_block * 256)/fs->block_count, 0); + CHECK_CB(fs, SPIFFS_CHECK_INDEX, SPIFFS_CHECK_PROGRESS, + (cur_block * 256) / fs->block_count, 0); - if (obj_id != SPIFFS_OBJ_ID_FREE && obj_id != SPIFFS_OBJ_ID_DELETED && (obj_id & SPIFFS_OBJ_ID_IX_FLAG)) { - spiffs_page_header p_hdr; - spiffs_page_ix cur_pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, cur_block, cur_entry); + if (obj_id != SPIFFS_OBJ_ID_FREE && obj_id != SPIFFS_OBJ_ID_DELETED && (obj_id & SPIFFS_OBJ_ID_IX_FLAG)) { + spiffs_page_header p_hdr; + spiffs_page_ix cur_pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, cur_block, cur_entry); - // load header - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, - 0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix), sizeof(spiffs_page_header), (u8_t*)&p_hdr); - SPIFFS_CHECK_RES(res); - - if (p_hdr.span_ix == 0 && - (p_hdr.flags & (SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_IXDELE)) == - (SPIFFS_PH_FLAG_DELET)) { - SPIFFS_CHECK_DBG("IX: pix "_SPIPRIpg", obj id:"_SPIPRIid" spix:"_SPIPRIsp" header not fully deleted - deleting\n", - cur_pix, obj_id, p_hdr.span_ix); - CHECK_CB(fs, SPIFFS_CHECK_INDEX, SPIFFS_CHECK_DELETE_PAGE, cur_pix, obj_id); - res = spiffs_page_delete(fs, cur_pix); - SPIFFS_CHECK_RES(res); - return res_c; - } - - if ((p_hdr.flags & (SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_IXDELE)) == - (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_IXDELE)) { - return res_c; - } - - if (p_hdr.span_ix == 0) { - // objix header page, register objid as reachable - int r = spiffs_object_index_search(fs, obj_id); - if (r == -1) { - // not registered, do it - obj_table[*log_ix] = obj_id & ~SPIFFS_OBJ_ID_IX_FLAG; - (*log_ix)++; - if (*log_ix >= SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id)) { - *log_ix = 0; - } - } - } else { // span index - // objix page, see if header can be found - int r = spiffs_object_index_search(fs, obj_id); - u8_t delete = 0; - if (r == -1) { - // not in temporary index, try finding it - spiffs_page_ix objix_hdr_pix; - res = spiffs_obj_lu_find_id_and_span(fs, obj_id | SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &objix_hdr_pix); - res_c = SPIFFS_VIS_COUNTINUE_RELOAD; - if (res == SPIFFS_OK) { - // found, register as reachable - obj_table[*log_ix] = obj_id & ~SPIFFS_OBJ_ID_IX_FLAG; - } else if (res == SPIFFS_ERR_NOT_FOUND) { - // not found, register as unreachable - delete = 1; - obj_table[*log_ix] = obj_id | SPIFFS_OBJ_ID_IX_FLAG; - } else { - SPIFFS_CHECK_RES(res); - } - (*log_ix)++; - if (*log_ix >= SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id)) { - *log_ix = 0; - } - } else { - // in temporary index, check reachable flag - if ((obj_table[r] & SPIFFS_OBJ_ID_IX_FLAG)) { - // registered as unreachable - delete = 1; - } - } - - if (delete) { - SPIFFS_CHECK_DBG("IX: FIXUP: pix "_SPIPRIpg", obj id:"_SPIPRIid" spix:"_SPIPRIsp" is orphan index - deleting\n", - cur_pix, obj_id, p_hdr.span_ix); - CHECK_CB(fs, SPIFFS_CHECK_INDEX, SPIFFS_CHECK_DELETE_ORPHANED_INDEX, cur_pix, obj_id); - res = spiffs_page_delete(fs, cur_pix); + // load header + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, + 0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix), sizeof(spiffs_page_header), (u8_t *)&p_hdr); SPIFFS_CHECK_RES(res); - } - } // span index - } // valid object index id - return res_c; + if (p_hdr.span_ix == 0 && + (p_hdr.flags & (SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_IXDELE)) == + (SPIFFS_PH_FLAG_DELET)) { + SPIFFS_CHECK_DBG("IX: pix "_SPIPRIpg", obj id:"_SPIPRIid" spix:"_SPIPRIsp" header not fully deleted - deleting\n", + cur_pix, obj_id, p_hdr.span_ix); + CHECK_CB(fs, SPIFFS_CHECK_INDEX, SPIFFS_CHECK_DELETE_PAGE, cur_pix, obj_id); + res = spiffs_page_delete(fs, cur_pix); + SPIFFS_CHECK_RES(res); + return res_c; + } + + if ((p_hdr.flags & (SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_IXDELE)) == + (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_IXDELE)) { + return res_c; + } + + if (p_hdr.span_ix == 0) { + // objix header page, register objid as reachable + int r = spiffs_object_index_search(fs, obj_id); + if (r == -1) { + // not registered, do it + obj_table[*log_ix] = obj_id & ~SPIFFS_OBJ_ID_IX_FLAG; + (*log_ix)++; + if (*log_ix >= SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id)) { + *log_ix = 0; + } + } + } else { // span index + // objix page, see if header can be found + int r = spiffs_object_index_search(fs, obj_id); + u8_t delete = 0; + if (r == -1) { + // not in temporary index, try finding it + spiffs_page_ix objix_hdr_pix; + res = spiffs_obj_lu_find_id_and_span(fs, obj_id | SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &objix_hdr_pix); + res_c = SPIFFS_VIS_COUNTINUE_RELOAD; + if (res == SPIFFS_OK) { + // found, register as reachable + obj_table[*log_ix] = obj_id & ~SPIFFS_OBJ_ID_IX_FLAG; + } else if (res == SPIFFS_ERR_NOT_FOUND) { + // not found, register as unreachable + delete = 1; + obj_table[*log_ix] = obj_id | SPIFFS_OBJ_ID_IX_FLAG; + } else { + SPIFFS_CHECK_RES(res); + } + (*log_ix)++; + if (*log_ix >= SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id)) { + *log_ix = 0; + } + } else { + // in temporary index, check reachable flag + if ((obj_table[r] & SPIFFS_OBJ_ID_IX_FLAG)) { + // registered as unreachable + delete = 1; + } + } + + if (delete) { + SPIFFS_CHECK_DBG("IX: FIXUP: pix "_SPIPRIpg", obj id:"_SPIPRIid" spix:"_SPIPRIsp" is orphan index - deleting\n", + cur_pix, obj_id, p_hdr.span_ix); + CHECK_CB(fs, SPIFFS_CHECK_INDEX, SPIFFS_CHECK_DELETE_ORPHANED_INDEX, cur_pix, obj_id); + res = spiffs_page_delete(fs, cur_pix); + SPIFFS_CHECK_RES(res); + } + } // span index + } // valid object index id + + return res_c; } // Removes orphaned and partially deleted index pages. @@ -984,25 +982,25 @@ static s32_t spiffs_object_index_consistency_check_v(spiffs *fs, spiffs_obj_id o // If no such page exists, the index page cannot be reached as no index header exists and must be // deleted. s32_t spiffs_object_index_consistency_check(spiffs *fs) { - s32_t res = SPIFFS_OK; - // impl note: - // fs->work is used for a temporary object index memory, listing found object ids and - // indicating whether they can be reached or not. Acting as a fifo if object ids cannot fit. - // In the temporary object index memory, SPIFFS_OBJ_ID_IX_FLAG bit is used to indicate - // a reachable/unreachable object id. - memset(fs->work, 0, SPIFFS_CFG_LOG_PAGE_SZ(fs)); - u32_t obj_id_log_ix = 0; - CHECK_CB(fs, SPIFFS_CHECK_INDEX, SPIFFS_CHECK_PROGRESS, 0, 0); - res = spiffs_obj_lu_find_entry_visitor(fs, 0, 0, 0, 0, spiffs_object_index_consistency_check_v, 0, &obj_id_log_ix, - 0, 0); - if (res == SPIFFS_VIS_END) { - res = SPIFFS_OK; - } - if (res != SPIFFS_OK) { - CHECK_CB(fs, SPIFFS_CHECK_INDEX, SPIFFS_CHECK_ERROR, res, 0); - } - CHECK_CB(fs, SPIFFS_CHECK_INDEX, SPIFFS_CHECK_PROGRESS, 256, 0); - return res; + s32_t res = SPIFFS_OK; + // impl note: + // fs->work is used for a temporary object index memory, listing found object ids and + // indicating whether they can be reached or not. Acting as a fifo if object ids cannot fit. + // In the temporary object index memory, SPIFFS_OBJ_ID_IX_FLAG bit is used to indicate + // a reachable/unreachable object id. + memset(fs->work, 0, SPIFFS_CFG_LOG_PAGE_SZ(fs)); + u32_t obj_id_log_ix = 0; + CHECK_CB(fs, SPIFFS_CHECK_INDEX, SPIFFS_CHECK_PROGRESS, 0, 0); + res = spiffs_obj_lu_find_entry_visitor(fs, 0, 0, 0, 0, spiffs_object_index_consistency_check_v, 0, &obj_id_log_ix, + 0, 0); + if (res == SPIFFS_VIS_END) { + res = SPIFFS_OK; + } + if (res != SPIFFS_OK) { + CHECK_CB(fs, SPIFFS_CHECK_INDEX, SPIFFS_CHECK_ERROR, res, 0); + } + CHECK_CB(fs, SPIFFS_CHECK_INDEX, SPIFFS_CHECK_PROGRESS, 256, 0); + return res; } #endif // !SPIFFS_READ_ONLY diff --git a/armsrc/spiffs_config.h b/armsrc/spiffs_config.h index 5e214380b..99557f41f 100644 --- a/armsrc/spiffs_config.h +++ b/armsrc/spiffs_config.h @@ -25,12 +25,12 @@ void Dbprintf(const char *fmt, ...); // ----------- >8 ------------ - typedef int s32_t; - typedef uint32_t u32_t; - typedef int16_t s16_t; - typedef uint16_t u16_t; - typedef int8_t s8_t; - typedef uint8_t u8_t; +typedef int s32_t; +typedef uint32_t u32_t; +typedef int16_t s16_t; +typedef uint16_t u16_t; +typedef int8_t s8_t; +typedef uint8_t u8_t; // compile time switches diff --git a/armsrc/spiffs_gc.c b/armsrc/spiffs_gc.c index 9da80e375..76ff094c9 100644 --- a/armsrc/spiffs_gc.c +++ b/armsrc/spiffs_gc.c @@ -9,21 +9,21 @@ static s32_t spiffs_gc_erase_block( spiffs *fs, spiffs_block_ix bix) { - s32_t res; + s32_t res; - SPIFFS_GC_DBG("gc: erase block "_SPIPRIbl"\n", bix); - res = spiffs_erase_block(fs, bix); - SPIFFS_CHECK_RES(res); + SPIFFS_GC_DBG("gc: erase block "_SPIPRIbl"\n", bix); + res = spiffs_erase_block(fs, bix); + SPIFFS_CHECK_RES(res); #if SPIFFS_CACHE - { - u32_t i; - for (i = 0; i < SPIFFS_PAGES_PER_BLOCK(fs); i++) { - spiffs_cache_drop_page(fs, SPIFFS_PAGE_FOR_BLOCK(fs, bix) + i); + { + u32_t i; + for (i = 0; i < SPIFFS_PAGES_PER_BLOCK(fs); i++) { + spiffs_cache_drop_page(fs, SPIFFS_PAGE_FOR_BLOCK(fs, bix) + i); + } } - } #endif - return res; + return res; } // Searches for blocks where all entries are deleted - if one is found, @@ -31,77 +31,77 @@ static s32_t spiffs_gc_erase_block( // that no updates are needed on existing objects on pages that are erased. s32_t spiffs_gc_quick( spiffs *fs, u16_t max_free_pages) { - s32_t res = SPIFFS_OK; - u32_t blocks = fs->block_count; - spiffs_block_ix cur_block = 0; - u32_t cur_block_addr = 0; - int cur_entry = 0; - spiffs_obj_id *obj_lu_buf = (spiffs_obj_id *)fs->lu_work; + s32_t res = SPIFFS_OK; + u32_t blocks = fs->block_count; + spiffs_block_ix cur_block = 0; + u32_t cur_block_addr = 0; + int cur_entry = 0; + spiffs_obj_id *obj_lu_buf = (spiffs_obj_id *)fs->lu_work; - SPIFFS_GC_DBGF("gc_quick: running\n"); + SPIFFS_GC_DBGF("gc_quick: running\n"); #if SPIFFS_GC_STATS - fs->stats_gc_runs++; + fs->stats_gc_runs++; #endif - int entries_per_page = (SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id)); + int entries_per_page = (SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id)); - // find fully deleted blocks - // check each block - while (res == SPIFFS_OK && blocks--) { - u16_t deleted_pages_in_block = 0; - u16_t free_pages_in_block = 0; + // find fully deleted blocks + // check each block + while (res == SPIFFS_OK && blocks--) { + u16_t deleted_pages_in_block = 0; + u16_t free_pages_in_block = 0; - int obj_lookup_page = 0; - // check each object lookup page - while (res == SPIFFS_OK && obj_lookup_page < (int)SPIFFS_OBJ_LOOKUP_PAGES(fs)) { - int entry_offset = obj_lookup_page * entries_per_page; - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, - 0, cur_block_addr + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); - // check each entry - while (res == SPIFFS_OK && - cur_entry - entry_offset < entries_per_page && - cur_entry < (int)(SPIFFS_PAGES_PER_BLOCK(fs)-SPIFFS_OBJ_LOOKUP_PAGES(fs))) { - spiffs_obj_id obj_id = obj_lu_buf[cur_entry-entry_offset]; - if (obj_id == SPIFFS_OBJ_ID_DELETED) { - deleted_pages_in_block++; - } else if (obj_id == SPIFFS_OBJ_ID_FREE) { - // kill scan, go for next block - free_pages_in_block++; - if (free_pages_in_block > max_free_pages) { - obj_lookup_page = SPIFFS_OBJ_LOOKUP_PAGES(fs); - res = 1; // kill object lu loop - break; - } - } else { - // kill scan, go for next block - obj_lookup_page = SPIFFS_OBJ_LOOKUP_PAGES(fs); - res = 1; // kill object lu loop - break; + int obj_lookup_page = 0; + // check each object lookup page + while (res == SPIFFS_OK && obj_lookup_page < (int)SPIFFS_OBJ_LOOKUP_PAGES(fs)) { + int entry_offset = obj_lookup_page * entries_per_page; + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, + 0, cur_block_addr + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); + // check each entry + while (res == SPIFFS_OK && + cur_entry - entry_offset < entries_per_page && + cur_entry < (int)(SPIFFS_PAGES_PER_BLOCK(fs) - SPIFFS_OBJ_LOOKUP_PAGES(fs))) { + spiffs_obj_id obj_id = obj_lu_buf[cur_entry - entry_offset]; + if (obj_id == SPIFFS_OBJ_ID_DELETED) { + deleted_pages_in_block++; + } else if (obj_id == SPIFFS_OBJ_ID_FREE) { + // kill scan, go for next block + free_pages_in_block++; + if (free_pages_in_block > max_free_pages) { + obj_lookup_page = SPIFFS_OBJ_LOOKUP_PAGES(fs); + res = 1; // kill object lu loop + break; + } + } else { + // kill scan, go for next block + obj_lookup_page = SPIFFS_OBJ_LOOKUP_PAGES(fs); + res = 1; // kill object lu loop + break; + } + cur_entry++; + } // per entry + obj_lookup_page++; + } // per object lookup page + if (res == 1) res = SPIFFS_OK; + + if (res == SPIFFS_OK && + deleted_pages_in_block + free_pages_in_block == SPIFFS_PAGES_PER_BLOCK(fs) - SPIFFS_OBJ_LOOKUP_PAGES(fs) && + free_pages_in_block <= max_free_pages) { + // found a fully deleted block + fs->stats_p_deleted -= deleted_pages_in_block; + res = spiffs_gc_erase_block(fs, cur_block); + return res; } - cur_entry++; - } // per entry - obj_lookup_page++; - } // per object lookup page - if (res == 1) res = SPIFFS_OK; - if (res == SPIFFS_OK && - deleted_pages_in_block + free_pages_in_block == SPIFFS_PAGES_PER_BLOCK(fs)-SPIFFS_OBJ_LOOKUP_PAGES(fs) && - free_pages_in_block <= max_free_pages) { - // found a fully deleted block - fs->stats_p_deleted -= deleted_pages_in_block; - res = spiffs_gc_erase_block(fs, cur_block); - return res; + cur_entry = 0; + cur_block++; + cur_block_addr += SPIFFS_CFG_LOG_BLOCK_SZ(fs); + } // per block + + if (res == SPIFFS_OK) { + res = SPIFFS_ERR_NO_DELETED_BLOCKS; } - - cur_entry = 0; - cur_block++; - cur_block_addr += SPIFFS_CFG_LOG_BLOCK_SZ(fs); - } // per block - - if (res == SPIFFS_OK) { - res = SPIFFS_ERR_NO_DELETED_BLOCKS; - } - return res; + return res; } // Checks if garbage collecting is necessary. If so a candidate block is found, @@ -109,127 +109,127 @@ s32_t spiffs_gc_quick( s32_t spiffs_gc_check( spiffs *fs, u32_t len) { - s32_t res; - s32_t free_pages = - (SPIFFS_PAGES_PER_BLOCK(fs) - SPIFFS_OBJ_LOOKUP_PAGES(fs)) * (fs->block_count-2) - - fs->stats_p_allocated - fs->stats_p_deleted; - int tries = 0; + s32_t res; + s32_t free_pages = + (SPIFFS_PAGES_PER_BLOCK(fs) - SPIFFS_OBJ_LOOKUP_PAGES(fs)) * (fs->block_count - 2) + - fs->stats_p_allocated - fs->stats_p_deleted; + int tries = 0; - if (fs->free_blocks > 3 && - (s32_t)len < free_pages * (s32_t)SPIFFS_DATA_PAGE_SIZE(fs)) { - return SPIFFS_OK; - } + if (fs->free_blocks > 3 && + (s32_t)len < free_pages * (s32_t)SPIFFS_DATA_PAGE_SIZE(fs)) { + return SPIFFS_OK; + } - u32_t needed_pages = (len + SPIFFS_DATA_PAGE_SIZE(fs) - 1) / SPIFFS_DATA_PAGE_SIZE(fs); + u32_t needed_pages = (len + SPIFFS_DATA_PAGE_SIZE(fs) - 1) / SPIFFS_DATA_PAGE_SIZE(fs); // if (fs->free_blocks <= 2 && (s32_t)needed_pages > free_pages) { // SPIFFS_GC_DBG("gc: full freeblk:"_SPIPRIi" needed:"_SPIPRIi" free:"_SPIPRIi" dele:"_SPIPRIi"\n", fs->free_blocks, needed_pages, free_pages, fs->stats_p_deleted); // return SPIFFS_ERR_FULL; // } - if ((s32_t)needed_pages > (s32_t)(free_pages + fs->stats_p_deleted)) { - SPIFFS_GC_DBG("gc_check: full freeblk:"_SPIPRIi" needed:"_SPIPRIi" free:"_SPIPRIi" dele:"_SPIPRIi"\n", fs->free_blocks, needed_pages, free_pages, fs->stats_p_deleted); - return SPIFFS_ERR_FULL; - } - - do { - SPIFFS_GC_DBG("\ngc_check #"_SPIPRIi": run gc free_blocks:"_SPIPRIi" pfree:"_SPIPRIi" pallo:"_SPIPRIi" pdele:"_SPIPRIi" ["_SPIPRIi"] len:"_SPIPRIi" of "_SPIPRIi"\n", - tries, - fs->free_blocks, free_pages, fs->stats_p_allocated, fs->stats_p_deleted, (free_pages+fs->stats_p_allocated+fs->stats_p_deleted), - len, (u32_t)(free_pages*SPIFFS_DATA_PAGE_SIZE(fs))); - - spiffs_block_ix *cands; - int count; - spiffs_block_ix cand; - s32_t prev_free_pages = free_pages; - // if the fs is crammed, ignore block age when selecting candidate - kind of a bad state - res = spiffs_gc_find_candidate(fs, &cands, &count, free_pages <= 0); - SPIFFS_CHECK_RES(res); - if (count == 0) { - SPIFFS_GC_DBGF("gc_check: no candidates, return\n"); - return (s32_t)needed_pages < free_pages ? SPIFFS_OK : SPIFFS_ERR_FULL; + if ((s32_t)needed_pages > (s32_t)(free_pages + fs->stats_p_deleted)) { + SPIFFS_GC_DBG("gc_check: full freeblk:"_SPIPRIi" needed:"_SPIPRIi" free:"_SPIPRIi" dele:"_SPIPRIi"\n", fs->free_blocks, needed_pages, free_pages, fs->stats_p_deleted); + return SPIFFS_ERR_FULL; } + + do { + SPIFFS_GC_DBG("\ngc_check #"_SPIPRIi": run gc free_blocks:"_SPIPRIi" pfree:"_SPIPRIi" pallo:"_SPIPRIi" pdele:"_SPIPRIi" ["_SPIPRIi"] len:"_SPIPRIi" of "_SPIPRIi"\n", + tries, + fs->free_blocks, free_pages, fs->stats_p_allocated, fs->stats_p_deleted, (free_pages + fs->stats_p_allocated + fs->stats_p_deleted), + len, (u32_t)(free_pages * SPIFFS_DATA_PAGE_SIZE(fs))); + + spiffs_block_ix *cands; + int count; + spiffs_block_ix cand; + s32_t prev_free_pages = free_pages; + // if the fs is crammed, ignore block age when selecting candidate - kind of a bad state + res = spiffs_gc_find_candidate(fs, &cands, &count, free_pages <= 0); + SPIFFS_CHECK_RES(res); + if (count == 0) { + SPIFFS_GC_DBGF("gc_check: no candidates, return\n"); + return (s32_t)needed_pages < free_pages ? SPIFFS_OK : SPIFFS_ERR_FULL; + } #if SPIFFS_GC_STATS - fs->stats_gc_runs++; + fs->stats_gc_runs++; #endif - cand = cands[0]; - fs->cleaning = 1; - //SPIFFS_GC_DBG("gcing: cleaning block "_SPIPRIi"\n", cand); - res = spiffs_gc_clean(fs, cand); - fs->cleaning = 0; - if (res < 0) { - SPIFFS_GC_DBG("gc_check: cleaning block "_SPIPRIi", result "_SPIPRIi"\n", cand, res); - } else { - SPIFFS_GC_DBG("gc_check: cleaning block "_SPIPRIi", result "_SPIPRIi"\n", cand, res); - } - SPIFFS_CHECK_RES(res); + cand = cands[0]; + fs->cleaning = 1; + //SPIFFS_GC_DBG("gcing: cleaning block "_SPIPRIi"\n", cand); + res = spiffs_gc_clean(fs, cand); + fs->cleaning = 0; + if (res < 0) { + SPIFFS_GC_DBG("gc_check: cleaning block "_SPIPRIi", result "_SPIPRIi"\n", cand, res); + } else { + SPIFFS_GC_DBG("gc_check: cleaning block "_SPIPRIi", result "_SPIPRIi"\n", cand, res); + } + SPIFFS_CHECK_RES(res); - res = spiffs_gc_erase_page_stats(fs, cand); - SPIFFS_CHECK_RES(res); + res = spiffs_gc_erase_page_stats(fs, cand); + SPIFFS_CHECK_RES(res); - res = spiffs_gc_erase_block(fs, cand); - SPIFFS_CHECK_RES(res); + res = spiffs_gc_erase_block(fs, cand); + SPIFFS_CHECK_RES(res); + + free_pages = + (SPIFFS_PAGES_PER_BLOCK(fs) - SPIFFS_OBJ_LOOKUP_PAGES(fs)) * (fs->block_count - 2) + - fs->stats_p_allocated - fs->stats_p_deleted; + + if (prev_free_pages <= 0 && prev_free_pages == free_pages) { + // abort early to reduce wear, at least tried once + SPIFFS_GC_DBGF("gc_check: early abort, no result on gc when fs crammed\n"); + break; + } + + } while (++tries < SPIFFS_GC_MAX_RUNS && (fs->free_blocks <= 2 || + (s32_t)len > free_pages * (s32_t)SPIFFS_DATA_PAGE_SIZE(fs))); free_pages = - (SPIFFS_PAGES_PER_BLOCK(fs) - SPIFFS_OBJ_LOOKUP_PAGES(fs)) * (fs->block_count - 2) - - fs->stats_p_allocated - fs->stats_p_deleted; - - if (prev_free_pages <= 0 && prev_free_pages == free_pages) { - // abort early to reduce wear, at least tried once - SPIFFS_GC_DBGF("gc_check: early abort, no result on gc when fs crammed\n"); - break; - } - - } while (++tries < SPIFFS_GC_MAX_RUNS && (fs->free_blocks <= 2 || - (s32_t)len > free_pages*(s32_t)SPIFFS_DATA_PAGE_SIZE(fs))); - - free_pages = (SPIFFS_PAGES_PER_BLOCK(fs) - SPIFFS_OBJ_LOOKUP_PAGES(fs)) * (fs->block_count - 2) - fs->stats_p_allocated - fs->stats_p_deleted; - if ((s32_t)len > free_pages*(s32_t)SPIFFS_DATA_PAGE_SIZE(fs)) { - res = SPIFFS_ERR_FULL; - } + if ((s32_t)len > free_pages * (s32_t)SPIFFS_DATA_PAGE_SIZE(fs)) { + res = SPIFFS_ERR_FULL; + } - SPIFFS_GC_DBG("gc_check: finished, "_SPIPRIi" dirty, blocks "_SPIPRIi" free, "_SPIPRIi" pages free, "_SPIPRIi" tries, res "_SPIPRIi"\n", - fs->stats_p_allocated + fs->stats_p_deleted, - fs->free_blocks, free_pages, tries, res); + SPIFFS_GC_DBG("gc_check: finished, "_SPIPRIi" dirty, blocks "_SPIPRIi" free, "_SPIPRIi" pages free, "_SPIPRIi" tries, res "_SPIPRIi"\n", + fs->stats_p_allocated + fs->stats_p_deleted, + fs->free_blocks, free_pages, tries, res); - return res; + return res; } // Updates page statistics for a block that is about to be erased s32_t spiffs_gc_erase_page_stats( spiffs *fs, spiffs_block_ix bix) { - s32_t res = SPIFFS_OK; - int obj_lookup_page = 0; - int entries_per_page = (SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id)); - spiffs_obj_id *obj_lu_buf = (spiffs_obj_id *)fs->lu_work; - int cur_entry = 0; - u32_t dele = 0; - u32_t allo = 0; + s32_t res = SPIFFS_OK; + int obj_lookup_page = 0; + int entries_per_page = (SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id)); + spiffs_obj_id *obj_lu_buf = (spiffs_obj_id *)fs->lu_work; + int cur_entry = 0; + u32_t dele = 0; + u32_t allo = 0; - // check each object lookup page - while (res == SPIFFS_OK && obj_lookup_page < (int)SPIFFS_OBJ_LOOKUP_PAGES(fs)) { - int entry_offset = obj_lookup_page * entries_per_page; - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, - 0, bix * SPIFFS_CFG_LOG_BLOCK_SZ(fs) + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); - // check each entry - while (res == SPIFFS_OK && - cur_entry - entry_offset < entries_per_page && cur_entry < (int)(SPIFFS_PAGES_PER_BLOCK(fs)-SPIFFS_OBJ_LOOKUP_PAGES(fs))) { - spiffs_obj_id obj_id = obj_lu_buf[cur_entry-entry_offset]; - if (obj_id == SPIFFS_OBJ_ID_FREE) { - } else if (obj_id == SPIFFS_OBJ_ID_DELETED) { - dele++; - } else { - allo++; - } - cur_entry++; - } // per entry - obj_lookup_page++; - } // per object lookup page - SPIFFS_GC_DBG("gc_check: wipe pallo:"_SPIPRIi" pdele:"_SPIPRIi"\n", allo, dele); - fs->stats_p_allocated -= allo; - fs->stats_p_deleted -= dele; - return res; + // check each object lookup page + while (res == SPIFFS_OK && obj_lookup_page < (int)SPIFFS_OBJ_LOOKUP_PAGES(fs)) { + int entry_offset = obj_lookup_page * entries_per_page; + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, + 0, bix * SPIFFS_CFG_LOG_BLOCK_SZ(fs) + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); + // check each entry + while (res == SPIFFS_OK && + cur_entry - entry_offset < entries_per_page && cur_entry < (int)(SPIFFS_PAGES_PER_BLOCK(fs) - SPIFFS_OBJ_LOOKUP_PAGES(fs))) { + spiffs_obj_id obj_id = obj_lu_buf[cur_entry - entry_offset]; + if (obj_id == SPIFFS_OBJ_ID_FREE) { + } else if (obj_id == SPIFFS_OBJ_ID_DELETED) { + dele++; + } else { + allo++; + } + cur_entry++; + } // per entry + obj_lookup_page++; + } // per object lookup page + SPIFFS_GC_DBG("gc_check: wipe pallo:"_SPIPRIi" pdele:"_SPIPRIi"\n", allo, dele); + fs->stats_p_allocated -= allo; + fs->stats_p_deleted -= dele; + return res; } // Finds block candidates to erase @@ -238,127 +238,127 @@ s32_t spiffs_gc_find_candidate( spiffs_block_ix **block_candidates, int *candidate_count, char fs_crammed) { - s32_t res = SPIFFS_OK; - u32_t blocks = fs->block_count; - spiffs_block_ix cur_block = 0; - u32_t cur_block_addr = 0; - spiffs_obj_id *obj_lu_buf = (spiffs_obj_id *)fs->lu_work; - int cur_entry = 0; + s32_t res = SPIFFS_OK; + u32_t blocks = fs->block_count; + spiffs_block_ix cur_block = 0; + u32_t cur_block_addr = 0; + spiffs_obj_id *obj_lu_buf = (spiffs_obj_id *)fs->lu_work; + int cur_entry = 0; - // using fs->work area as sorted candidate memory, (spiffs_block_ix)cand_bix/(s32_t)score - int max_candidates = MIN(fs->block_count, (SPIFFS_CFG_LOG_PAGE_SZ(fs)-8)/(sizeof(spiffs_block_ix) + sizeof(s32_t))); - *candidate_count = 0; - memset(fs->work, 0xff, SPIFFS_CFG_LOG_PAGE_SZ(fs)); + // using fs->work area as sorted candidate memory, (spiffs_block_ix)cand_bix/(s32_t)score + int max_candidates = MIN(fs->block_count, (SPIFFS_CFG_LOG_PAGE_SZ(fs) - 8) / (sizeof(spiffs_block_ix) + sizeof(s32_t))); + *candidate_count = 0; + memset(fs->work, 0xff, SPIFFS_CFG_LOG_PAGE_SZ(fs)); - // divide up work area into block indices and scores - spiffs_block_ix *cand_blocks = (spiffs_block_ix *)fs->work; - s32_t *cand_scores = (s32_t *)(fs->work + max_candidates * sizeof(spiffs_block_ix)); + // divide up work area into block indices and scores + spiffs_block_ix *cand_blocks = (spiffs_block_ix *)fs->work; + s32_t *cand_scores = (s32_t *)(fs->work + max_candidates * sizeof(spiffs_block_ix)); - // align cand_scores on s32_t boundary - cand_scores = (s32_t*)(((intptr_t)cand_scores + sizeof(intptr_t) - 1) & ~(sizeof(intptr_t) - 1)); + // align cand_scores on s32_t boundary + cand_scores = (s32_t *)(((intptr_t)cand_scores + sizeof(intptr_t) - 1) & ~(sizeof(intptr_t) - 1)); - *block_candidates = cand_blocks; + *block_candidates = cand_blocks; - int entries_per_page = (SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id)); + int entries_per_page = (SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id)); - // check each block - while (res == SPIFFS_OK && blocks--) { - u16_t deleted_pages_in_block = 0; - u16_t used_pages_in_block = 0; + // check each block + while (res == SPIFFS_OK && blocks--) { + u16_t deleted_pages_in_block = 0; + u16_t used_pages_in_block = 0; - int obj_lookup_page = 0; - // check each object lookup page - while (res == SPIFFS_OK && obj_lookup_page < (int)SPIFFS_OBJ_LOOKUP_PAGES(fs)) { - int entry_offset = obj_lookup_page * entries_per_page; - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, - 0, cur_block_addr + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); - // check each entry - while (res == SPIFFS_OK && - cur_entry - entry_offset < entries_per_page && - cur_entry < (int)(SPIFFS_PAGES_PER_BLOCK(fs)-SPIFFS_OBJ_LOOKUP_PAGES(fs))) { - spiffs_obj_id obj_id = obj_lu_buf[cur_entry-entry_offset]; - if (obj_id == SPIFFS_OBJ_ID_FREE) { - // when a free entry is encountered, scan logic ensures that all following entries are free also - res = 1; // kill object lu loop - break; - } else if (obj_id == SPIFFS_OBJ_ID_DELETED) { - deleted_pages_in_block++; - } else { - used_pages_in_block++; + int obj_lookup_page = 0; + // check each object lookup page + while (res == SPIFFS_OK && obj_lookup_page < (int)SPIFFS_OBJ_LOOKUP_PAGES(fs)) { + int entry_offset = obj_lookup_page * entries_per_page; + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, + 0, cur_block_addr + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); + // check each entry + while (res == SPIFFS_OK && + cur_entry - entry_offset < entries_per_page && + cur_entry < (int)(SPIFFS_PAGES_PER_BLOCK(fs) - SPIFFS_OBJ_LOOKUP_PAGES(fs))) { + spiffs_obj_id obj_id = obj_lu_buf[cur_entry - entry_offset]; + if (obj_id == SPIFFS_OBJ_ID_FREE) { + // when a free entry is encountered, scan logic ensures that all following entries are free also + res = 1; // kill object lu loop + break; + } else if (obj_id == SPIFFS_OBJ_ID_DELETED) { + deleted_pages_in_block++; + } else { + used_pages_in_block++; + } + cur_entry++; + } // per entry + obj_lookup_page++; + } // per object lookup page + if (res == 1) res = SPIFFS_OK; + + // calculate score and insert into candidate table + // stoneage sort, but probably not so many blocks + if (res == SPIFFS_OK /*&& deleted_pages_in_block > 0*/) { + // read erase count + spiffs_obj_id erase_count; + res = _spiffs_rd(fs, SPIFFS_OP_C_READ | SPIFFS_OP_T_OBJ_LU2, 0, + SPIFFS_ERASE_COUNT_PADDR(fs, cur_block), + sizeof(spiffs_obj_id), (u8_t *)&erase_count); + SPIFFS_CHECK_RES(res); + + spiffs_obj_id erase_age; + if (fs->max_erase_count > erase_count) { + erase_age = fs->max_erase_count - erase_count; + } else { + erase_age = SPIFFS_OBJ_ID_FREE - (erase_count - fs->max_erase_count); + } + + s32_t score = + deleted_pages_in_block * SPIFFS_GC_HEUR_W_DELET + + used_pages_in_block * SPIFFS_GC_HEUR_W_USED + + erase_age * (fs_crammed ? 0 : SPIFFS_GC_HEUR_W_ERASE_AGE); + int cand_ix = 0; + SPIFFS_GC_DBG("gc_check: bix:"_SPIPRIbl" del:"_SPIPRIi" use:"_SPIPRIi" score:"_SPIPRIi"\n", cur_block, deleted_pages_in_block, used_pages_in_block, score); + while (cand_ix < max_candidates) { + if (cand_blocks[cand_ix] == (spiffs_block_ix) - 1) { + cand_blocks[cand_ix] = cur_block; + cand_scores[cand_ix] = score; + break; + } else if (cand_scores[cand_ix] < score) { + int reorder_cand_ix = max_candidates - 2; + while (reorder_cand_ix >= cand_ix) { + cand_blocks[reorder_cand_ix + 1] = cand_blocks[reorder_cand_ix]; + cand_scores[reorder_cand_ix + 1] = cand_scores[reorder_cand_ix]; + reorder_cand_ix--; + } + cand_blocks[cand_ix] = cur_block; + cand_scores[cand_ix] = score; + break; + } + cand_ix++; + } + (*candidate_count)++; } - cur_entry++; - } // per entry - obj_lookup_page++; - } // per object lookup page - if (res == 1) res = SPIFFS_OK; - // calculate score and insert into candidate table - // stoneage sort, but probably not so many blocks - if (res == SPIFFS_OK /*&& deleted_pages_in_block > 0*/) { - // read erase count - spiffs_obj_id erase_count; - res = _spiffs_rd(fs, SPIFFS_OP_C_READ | SPIFFS_OP_T_OBJ_LU2, 0, - SPIFFS_ERASE_COUNT_PADDR(fs, cur_block), - sizeof(spiffs_obj_id), (u8_t *)&erase_count); - SPIFFS_CHECK_RES(res); + cur_entry = 0; + cur_block++; + cur_block_addr += SPIFFS_CFG_LOG_BLOCK_SZ(fs); + } // per block - spiffs_obj_id erase_age; - if (fs->max_erase_count > erase_count) { - erase_age = fs->max_erase_count - erase_count; - } else { - erase_age = SPIFFS_OBJ_ID_FREE - (erase_count - fs->max_erase_count); - } - - s32_t score = - deleted_pages_in_block * SPIFFS_GC_HEUR_W_DELET + - used_pages_in_block * SPIFFS_GC_HEUR_W_USED + - erase_age * (fs_crammed ? 0 : SPIFFS_GC_HEUR_W_ERASE_AGE); - int cand_ix = 0; - SPIFFS_GC_DBG("gc_check: bix:"_SPIPRIbl" del:"_SPIPRIi" use:"_SPIPRIi" score:"_SPIPRIi"\n", cur_block, deleted_pages_in_block, used_pages_in_block, score); - while (cand_ix < max_candidates) { - if (cand_blocks[cand_ix] == (spiffs_block_ix)-1) { - cand_blocks[cand_ix] = cur_block; - cand_scores[cand_ix] = score; - break; - } else if (cand_scores[cand_ix] < score) { - int reorder_cand_ix = max_candidates - 2; - while (reorder_cand_ix >= cand_ix) { - cand_blocks[reorder_cand_ix + 1] = cand_blocks[reorder_cand_ix]; - cand_scores[reorder_cand_ix + 1] = cand_scores[reorder_cand_ix]; - reorder_cand_ix--; - } - cand_blocks[cand_ix] = cur_block; - cand_scores[cand_ix] = score; - break; - } - cand_ix++; - } - (*candidate_count)++; - } - - cur_entry = 0; - cur_block++; - cur_block_addr += SPIFFS_CFG_LOG_BLOCK_SZ(fs); - } // per block - - return res; + return res; } typedef enum { - FIND_OBJ_DATA, - MOVE_OBJ_DATA, - MOVE_OBJ_IX, - FINISHED + FIND_OBJ_DATA, + MOVE_OBJ_DATA, + MOVE_OBJ_IX, + FINISHED } spiffs_gc_clean_state; typedef struct { - spiffs_gc_clean_state state; - spiffs_obj_id cur_obj_id; - spiffs_span_ix cur_objix_spix; - spiffs_page_ix cur_objix_pix; - spiffs_page_ix cur_data_pix; - int stored_scan_entry_index; - u8_t obj_id_found; + spiffs_gc_clean_state state; + spiffs_obj_id cur_obj_id; + spiffs_span_ix cur_objix_spix; + spiffs_page_ix cur_objix_pix; + spiffs_page_ix cur_data_pix; + int stored_scan_entry_index; + u8_t obj_id_found; } spiffs_gc; // Empties given block by moving all data into free pages of another block @@ -375,232 +375,232 @@ typedef struct { // scan object lookup again for remaining object index pages, move to new page in other block // s32_t spiffs_gc_clean(spiffs *fs, spiffs_block_ix bix) { - s32_t res = SPIFFS_OK; - const int entries_per_page = (SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id)); - // this is the global localizer being pushed and popped - int cur_entry = 0; - spiffs_obj_id *obj_lu_buf = (spiffs_obj_id *)fs->lu_work; - spiffs_gc gc; // our stack frame/state - spiffs_page_ix cur_pix = 0; - spiffs_page_object_ix_header *objix_hdr = (spiffs_page_object_ix_header *)fs->work; - spiffs_page_object_ix *objix = (spiffs_page_object_ix *)fs->work; + s32_t res = SPIFFS_OK; + const int entries_per_page = (SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id)); + // this is the global localizer being pushed and popped + int cur_entry = 0; + spiffs_obj_id *obj_lu_buf = (spiffs_obj_id *)fs->lu_work; + spiffs_gc gc; // our stack frame/state + spiffs_page_ix cur_pix = 0; + spiffs_page_object_ix_header *objix_hdr = (spiffs_page_object_ix_header *)fs->work; + spiffs_page_object_ix *objix = (spiffs_page_object_ix *)fs->work; - SPIFFS_GC_DBG("gc_clean: cleaning block "_SPIPRIbl"\n", bix); + SPIFFS_GC_DBG("gc_clean: cleaning block "_SPIPRIbl"\n", bix); - memset(&gc, 0, sizeof(spiffs_gc)); - gc.state = FIND_OBJ_DATA; + memset(&gc, 0, sizeof(spiffs_gc)); + gc.state = FIND_OBJ_DATA; - if (fs->free_cursor_block_ix == bix) { - // move free cursor to next block, cannot use free pages from the block we want to clean - fs->free_cursor_block_ix = (bix+1)%fs->block_count; - fs->free_cursor_obj_lu_entry = 0; - SPIFFS_GC_DBG("gc_clean: move free cursor to block "_SPIPRIbl"\n", fs->free_cursor_block_ix); - } - - while (res == SPIFFS_OK && gc.state != FINISHED) { - SPIFFS_GC_DBG("gc_clean: state = "_SPIPRIi" entry:"_SPIPRIi"\n", gc.state, cur_entry); - gc.obj_id_found = 0; // reset (to no found data page) - - // scan through lookup pages - int obj_lookup_page = cur_entry / entries_per_page; - u8_t scan = 1; - // check each object lookup page - while (scan && res == SPIFFS_OK && obj_lookup_page < (int)SPIFFS_OBJ_LOOKUP_PAGES(fs)) { - int entry_offset = obj_lookup_page * entries_per_page; - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, - 0, bix * SPIFFS_CFG_LOG_BLOCK_SZ(fs) + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), - SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); - // check each object lookup entry - while (scan && res == SPIFFS_OK && - cur_entry - entry_offset < entries_per_page && cur_entry < (int)(SPIFFS_PAGES_PER_BLOCK(fs)-SPIFFS_OBJ_LOOKUP_PAGES(fs))) { - spiffs_obj_id obj_id = obj_lu_buf[cur_entry-entry_offset]; - cur_pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, cur_entry); - - // act upon object id depending on gc state - switch (gc.state) { - case FIND_OBJ_DATA: - // find a data page - if (obj_id != SPIFFS_OBJ_ID_DELETED && obj_id != SPIFFS_OBJ_ID_FREE && - ((obj_id & SPIFFS_OBJ_ID_IX_FLAG) == 0)) { - // found a data page, stop scanning and handle in switch case below - SPIFFS_GC_DBG("gc_clean: FIND_DATA state:"_SPIPRIi" - found obj id "_SPIPRIid"\n", gc.state, obj_id); - gc.obj_id_found = 1; - gc.cur_obj_id = obj_id; - gc.cur_data_pix = cur_pix; - scan = 0; - } - break; - case MOVE_OBJ_DATA: - // evacuate found data pages for corresponding object index we have in memory, - // update memory representation - if (obj_id == gc.cur_obj_id) { - spiffs_page_header p_hdr; - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, - 0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix), sizeof(spiffs_page_header), (u8_t*)&p_hdr); - SPIFFS_CHECK_RES(res); - SPIFFS_GC_DBG("gc_clean: MOVE_DATA found data page "_SPIPRIid":"_SPIPRIsp" @ "_SPIPRIpg"\n", gc.cur_obj_id, p_hdr.span_ix, cur_pix); - if (SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, p_hdr.span_ix) != gc.cur_objix_spix) { - SPIFFS_GC_DBGF("gc_clean: MOVE_DATA no objix spix match, take in another run\n"); - } else { - spiffs_page_ix new_data_pix; - if (p_hdr.flags & SPIFFS_PH_FLAG_DELET) { - // move page - res = spiffs_page_move(fs, 0, 0, obj_id, &p_hdr, cur_pix, &new_data_pix); - SPIFFS_GC_DBG("gc_clean: MOVE_DATA move objix "_SPIPRIid":"_SPIPRIsp" page "_SPIPRIpg" to "_SPIPRIpg"\n", gc.cur_obj_id, p_hdr.span_ix, cur_pix, new_data_pix); - SPIFFS_CHECK_RES(res); - // move wipes obj_lu, reload it - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, - 0, bix * SPIFFS_CFG_LOG_BLOCK_SZ(fs) + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), - SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); - SPIFFS_CHECK_RES(res); - } else { - // page is deleted but not deleted in lookup, scrap it - - // might seem unnecessary as we will erase this block, but - // we might get aborted - SPIFFS_GC_DBG("gc_clean: MOVE_DATA wipe objix "_SPIPRIid":"_SPIPRIsp" page "_SPIPRIpg"\n", obj_id, p_hdr.span_ix, cur_pix); - res = spiffs_page_delete(fs, cur_pix); - SPIFFS_CHECK_RES(res); - new_data_pix = SPIFFS_OBJ_ID_FREE; - } - // update memory representation of object index page with new data page - if (gc.cur_objix_spix == 0) { - // update object index header page - ((spiffs_page_ix*)((u8_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[p_hdr.span_ix] = new_data_pix; - SPIFFS_GC_DBG("gc_clean: MOVE_DATA wrote page "_SPIPRIpg" to objix_hdr entry "_SPIPRIsp" in mem\n", new_data_pix, (spiffs_span_ix)SPIFFS_OBJ_IX_ENTRY(fs, p_hdr.span_ix)); - } else { - // update object index page - ((spiffs_page_ix*)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, p_hdr.span_ix)] = new_data_pix; - SPIFFS_GC_DBG("gc_clean: MOVE_DATA wrote page "_SPIPRIpg" to objix entry "_SPIPRIsp" in mem\n", new_data_pix, (spiffs_span_ix)SPIFFS_OBJ_IX_ENTRY(fs, p_hdr.span_ix)); - } - } - } - break; - case MOVE_OBJ_IX: - // find and evacuate object index pages - if (obj_id != SPIFFS_OBJ_ID_DELETED && obj_id != SPIFFS_OBJ_ID_FREE && - (obj_id & SPIFFS_OBJ_ID_IX_FLAG)) { - // found an index object id - spiffs_page_header p_hdr; - spiffs_page_ix new_pix; - // load header - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, - 0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix), sizeof(spiffs_page_header), (u8_t*)&p_hdr); - SPIFFS_CHECK_RES(res); - if (p_hdr.flags & SPIFFS_PH_FLAG_DELET) { - // move page - res = spiffs_page_move(fs, 0, 0, obj_id, &p_hdr, cur_pix, &new_pix); - SPIFFS_GC_DBG("gc_clean: MOVE_OBJIX move objix "_SPIPRIid":"_SPIPRIsp" page "_SPIPRIpg" to "_SPIPRIpg"\n", obj_id, p_hdr.span_ix, cur_pix, new_pix); - SPIFFS_CHECK_RES(res); - spiffs_cb_object_event(fs, (spiffs_page_object_ix *)&p_hdr, - SPIFFS_EV_IX_MOV, obj_id, p_hdr.span_ix, new_pix, 0); - // move wipes obj_lu, reload it - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, - 0, bix * SPIFFS_CFG_LOG_BLOCK_SZ(fs) + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), - SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); - SPIFFS_CHECK_RES(res); - } else { - // page is deleted but not deleted in lookup, scrap it - - // might seem unnecessary as we will erase this block, but - // we might get aborted - SPIFFS_GC_DBG("gc_clean: MOVE_OBJIX wipe objix "_SPIPRIid":"_SPIPRIsp" page "_SPIPRIpg"\n", obj_id, p_hdr.span_ix, cur_pix); - res = spiffs_page_delete(fs, cur_pix); - if (res == SPIFFS_OK) { - spiffs_cb_object_event(fs, (spiffs_page_object_ix *)0, - SPIFFS_EV_IX_DEL, obj_id, p_hdr.span_ix, cur_pix, 0); - } - } - SPIFFS_CHECK_RES(res); - } - break; - default: - scan = 0; - break; - } // switch gc state - cur_entry++; - } // per entry - obj_lookup_page++; // no need to check scan variable here, obj_lookup_page is set in start of loop - } // per object lookup page - if (res != SPIFFS_OK) break; - - // state finalization and switch - switch (gc.state) { - case FIND_OBJ_DATA: - if (gc.obj_id_found) { - // handle found data page - - // find out corresponding obj ix page and load it to memory - spiffs_page_header p_hdr; - spiffs_page_ix objix_pix; - gc.stored_scan_entry_index = cur_entry; // push cursor - cur_entry = 0; // restart scan from start - gc.state = MOVE_OBJ_DATA; - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, - 0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix), sizeof(spiffs_page_header), (u8_t*)&p_hdr); - SPIFFS_CHECK_RES(res); - gc.cur_objix_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, p_hdr.span_ix); - SPIFFS_GC_DBG("gc_clean: FIND_DATA find objix span_ix:"_SPIPRIsp"\n", gc.cur_objix_spix); - res = spiffs_obj_lu_find_id_and_span(fs, gc.cur_obj_id | SPIFFS_OBJ_ID_IX_FLAG, gc.cur_objix_spix, 0, &objix_pix); - if (res == SPIFFS_ERR_NOT_FOUND) { - // on borked systems we might get an ERR_NOT_FOUND here - - // this is handled by simply deleting the page as it is not referenced - // from anywhere - SPIFFS_GC_DBG("gc_clean: FIND_OBJ_DATA objix not found! Wipe page "_SPIPRIpg"\n", gc.cur_data_pix); - res = spiffs_page_delete(fs, gc.cur_data_pix); - SPIFFS_CHECK_RES(res); - // then we restore states and continue scanning for data pages - cur_entry = gc.stored_scan_entry_index; // pop cursor - gc.state = FIND_OBJ_DATA; - break; // done - } - SPIFFS_CHECK_RES(res); - SPIFFS_GC_DBG("gc_clean: FIND_DATA found object index at page "_SPIPRIpg"\n", objix_pix); - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, - 0, SPIFFS_PAGE_TO_PADDR(fs, objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); - SPIFFS_CHECK_RES(res); - // cannot allow a gc if the presumed index in fact is no index, a - // check must run or lot of data may be lost - SPIFFS_VALIDATE_OBJIX(objix->p_hdr, gc.cur_obj_id | SPIFFS_OBJ_ID_IX_FLAG, gc.cur_objix_spix); - gc.cur_objix_pix = objix_pix; - } else { - // no more data pages found, passed thru all block, start evacuating object indices - gc.state = MOVE_OBJ_IX; - cur_entry = 0; // restart entry scan index - } - break; - case MOVE_OBJ_DATA: { - // store modified objix (hdr) page residing in memory now that all - // data pages belonging to this object index and residing in the block - // we want to evacuate - spiffs_page_ix new_objix_pix; - gc.state = FIND_OBJ_DATA; - cur_entry = gc.stored_scan_entry_index; // pop cursor - if (gc.cur_objix_spix == 0) { - // store object index header page - res = spiffs_object_update_index_hdr(fs, 0, gc.cur_obj_id | SPIFFS_OBJ_ID_IX_FLAG, gc.cur_objix_pix, fs->work, 0, 0, 0, &new_objix_pix); - SPIFFS_GC_DBG("gc_clean: MOVE_DATA store modified objix_hdr page, "_SPIPRIpg":"_SPIPRIsp"\n", new_objix_pix, 0); - SPIFFS_CHECK_RES(res); - } else { - // store object index page - res = spiffs_page_move(fs, 0, fs->work, gc.cur_obj_id | SPIFFS_OBJ_ID_IX_FLAG, 0, gc.cur_objix_pix, &new_objix_pix); - SPIFFS_GC_DBG("gc_clean: MOVE_DATA store modified objix page, "_SPIPRIpg":"_SPIPRIsp"\n", new_objix_pix, objix->p_hdr.span_ix); - SPIFFS_CHECK_RES(res); - spiffs_cb_object_event(fs, (spiffs_page_object_ix *)fs->work, - SPIFFS_EV_IX_UPD, gc.cur_obj_id, objix->p_hdr.span_ix, new_objix_pix, 0); - } + if (fs->free_cursor_block_ix == bix) { + // move free cursor to next block, cannot use free pages from the block we want to clean + fs->free_cursor_block_ix = (bix + 1) % fs->block_count; + fs->free_cursor_obj_lu_entry = 0; + SPIFFS_GC_DBG("gc_clean: move free cursor to block "_SPIPRIbl"\n", fs->free_cursor_block_ix); } - break; - case MOVE_OBJ_IX: - // scanned thru all block, no more object indices found - our work here is done - gc.state = FINISHED; - break; - default: - cur_entry = 0; - break; - } // switch gc.state - SPIFFS_GC_DBG("gc_clean: state-> "_SPIPRIi"\n", gc.state); - } // while state != FINISHED + + while (res == SPIFFS_OK && gc.state != FINISHED) { + SPIFFS_GC_DBG("gc_clean: state = "_SPIPRIi" entry:"_SPIPRIi"\n", gc.state, cur_entry); + gc.obj_id_found = 0; // reset (to no found data page) + + // scan through lookup pages + int obj_lookup_page = cur_entry / entries_per_page; + u8_t scan = 1; + // check each object lookup page + while (scan && res == SPIFFS_OK && obj_lookup_page < (int)SPIFFS_OBJ_LOOKUP_PAGES(fs)) { + int entry_offset = obj_lookup_page * entries_per_page; + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, + 0, bix * SPIFFS_CFG_LOG_BLOCK_SZ(fs) + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), + SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); + // check each object lookup entry + while (scan && res == SPIFFS_OK && + cur_entry - entry_offset < entries_per_page && cur_entry < (int)(SPIFFS_PAGES_PER_BLOCK(fs) - SPIFFS_OBJ_LOOKUP_PAGES(fs))) { + spiffs_obj_id obj_id = obj_lu_buf[cur_entry - entry_offset]; + cur_pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, cur_entry); + + // act upon object id depending on gc state + switch (gc.state) { + case FIND_OBJ_DATA: + // find a data page + if (obj_id != SPIFFS_OBJ_ID_DELETED && obj_id != SPIFFS_OBJ_ID_FREE && + ((obj_id & SPIFFS_OBJ_ID_IX_FLAG) == 0)) { + // found a data page, stop scanning and handle in switch case below + SPIFFS_GC_DBG("gc_clean: FIND_DATA state:"_SPIPRIi" - found obj id "_SPIPRIid"\n", gc.state, obj_id); + gc.obj_id_found = 1; + gc.cur_obj_id = obj_id; + gc.cur_data_pix = cur_pix; + scan = 0; + } + break; + case MOVE_OBJ_DATA: + // evacuate found data pages for corresponding object index we have in memory, + // update memory representation + if (obj_id == gc.cur_obj_id) { + spiffs_page_header p_hdr; + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, + 0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix), sizeof(spiffs_page_header), (u8_t *)&p_hdr); + SPIFFS_CHECK_RES(res); + SPIFFS_GC_DBG("gc_clean: MOVE_DATA found data page "_SPIPRIid":"_SPIPRIsp" @ "_SPIPRIpg"\n", gc.cur_obj_id, p_hdr.span_ix, cur_pix); + if (SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, p_hdr.span_ix) != gc.cur_objix_spix) { + SPIFFS_GC_DBGF("gc_clean: MOVE_DATA no objix spix match, take in another run\n"); + } else { + spiffs_page_ix new_data_pix; + if (p_hdr.flags & SPIFFS_PH_FLAG_DELET) { + // move page + res = spiffs_page_move(fs, 0, 0, obj_id, &p_hdr, cur_pix, &new_data_pix); + SPIFFS_GC_DBG("gc_clean: MOVE_DATA move objix "_SPIPRIid":"_SPIPRIsp" page "_SPIPRIpg" to "_SPIPRIpg"\n", gc.cur_obj_id, p_hdr.span_ix, cur_pix, new_data_pix); + SPIFFS_CHECK_RES(res); + // move wipes obj_lu, reload it + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, + 0, bix * SPIFFS_CFG_LOG_BLOCK_SZ(fs) + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), + SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); + SPIFFS_CHECK_RES(res); + } else { + // page is deleted but not deleted in lookup, scrap it - + // might seem unnecessary as we will erase this block, but + // we might get aborted + SPIFFS_GC_DBG("gc_clean: MOVE_DATA wipe objix "_SPIPRIid":"_SPIPRIsp" page "_SPIPRIpg"\n", obj_id, p_hdr.span_ix, cur_pix); + res = spiffs_page_delete(fs, cur_pix); + SPIFFS_CHECK_RES(res); + new_data_pix = SPIFFS_OBJ_ID_FREE; + } + // update memory representation of object index page with new data page + if (gc.cur_objix_spix == 0) { + // update object index header page + ((spiffs_page_ix *)((u8_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[p_hdr.span_ix] = new_data_pix; + SPIFFS_GC_DBG("gc_clean: MOVE_DATA wrote page "_SPIPRIpg" to objix_hdr entry "_SPIPRIsp" in mem\n", new_data_pix, (spiffs_span_ix)SPIFFS_OBJ_IX_ENTRY(fs, p_hdr.span_ix)); + } else { + // update object index page + ((spiffs_page_ix *)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, p_hdr.span_ix)] = new_data_pix; + SPIFFS_GC_DBG("gc_clean: MOVE_DATA wrote page "_SPIPRIpg" to objix entry "_SPIPRIsp" in mem\n", new_data_pix, (spiffs_span_ix)SPIFFS_OBJ_IX_ENTRY(fs, p_hdr.span_ix)); + } + } + } + break; + case MOVE_OBJ_IX: + // find and evacuate object index pages + if (obj_id != SPIFFS_OBJ_ID_DELETED && obj_id != SPIFFS_OBJ_ID_FREE && + (obj_id & SPIFFS_OBJ_ID_IX_FLAG)) { + // found an index object id + spiffs_page_header p_hdr; + spiffs_page_ix new_pix; + // load header + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, + 0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix), sizeof(spiffs_page_header), (u8_t *)&p_hdr); + SPIFFS_CHECK_RES(res); + if (p_hdr.flags & SPIFFS_PH_FLAG_DELET) { + // move page + res = spiffs_page_move(fs, 0, 0, obj_id, &p_hdr, cur_pix, &new_pix); + SPIFFS_GC_DBG("gc_clean: MOVE_OBJIX move objix "_SPIPRIid":"_SPIPRIsp" page "_SPIPRIpg" to "_SPIPRIpg"\n", obj_id, p_hdr.span_ix, cur_pix, new_pix); + SPIFFS_CHECK_RES(res); + spiffs_cb_object_event(fs, (spiffs_page_object_ix *)&p_hdr, + SPIFFS_EV_IX_MOV, obj_id, p_hdr.span_ix, new_pix, 0); + // move wipes obj_lu, reload it + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, + 0, bix * SPIFFS_CFG_LOG_BLOCK_SZ(fs) + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), + SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); + SPIFFS_CHECK_RES(res); + } else { + // page is deleted but not deleted in lookup, scrap it - + // might seem unnecessary as we will erase this block, but + // we might get aborted + SPIFFS_GC_DBG("gc_clean: MOVE_OBJIX wipe objix "_SPIPRIid":"_SPIPRIsp" page "_SPIPRIpg"\n", obj_id, p_hdr.span_ix, cur_pix); + res = spiffs_page_delete(fs, cur_pix); + if (res == SPIFFS_OK) { + spiffs_cb_object_event(fs, (spiffs_page_object_ix *)0, + SPIFFS_EV_IX_DEL, obj_id, p_hdr.span_ix, cur_pix, 0); + } + } + SPIFFS_CHECK_RES(res); + } + break; + default: + scan = 0; + break; + } // switch gc state + cur_entry++; + } // per entry + obj_lookup_page++; // no need to check scan variable here, obj_lookup_page is set in start of loop + } // per object lookup page + if (res != SPIFFS_OK) break; + + // state finalization and switch + switch (gc.state) { + case FIND_OBJ_DATA: + if (gc.obj_id_found) { + // handle found data page - + // find out corresponding obj ix page and load it to memory + spiffs_page_header p_hdr; + spiffs_page_ix objix_pix; + gc.stored_scan_entry_index = cur_entry; // push cursor + cur_entry = 0; // restart scan from start + gc.state = MOVE_OBJ_DATA; + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, + 0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix), sizeof(spiffs_page_header), (u8_t *)&p_hdr); + SPIFFS_CHECK_RES(res); + gc.cur_objix_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, p_hdr.span_ix); + SPIFFS_GC_DBG("gc_clean: FIND_DATA find objix span_ix:"_SPIPRIsp"\n", gc.cur_objix_spix); + res = spiffs_obj_lu_find_id_and_span(fs, gc.cur_obj_id | SPIFFS_OBJ_ID_IX_FLAG, gc.cur_objix_spix, 0, &objix_pix); + if (res == SPIFFS_ERR_NOT_FOUND) { + // on borked systems we might get an ERR_NOT_FOUND here - + // this is handled by simply deleting the page as it is not referenced + // from anywhere + SPIFFS_GC_DBG("gc_clean: FIND_OBJ_DATA objix not found! Wipe page "_SPIPRIpg"\n", gc.cur_data_pix); + res = spiffs_page_delete(fs, gc.cur_data_pix); + SPIFFS_CHECK_RES(res); + // then we restore states and continue scanning for data pages + cur_entry = gc.stored_scan_entry_index; // pop cursor + gc.state = FIND_OBJ_DATA; + break; // done + } + SPIFFS_CHECK_RES(res); + SPIFFS_GC_DBG("gc_clean: FIND_DATA found object index at page "_SPIPRIpg"\n", objix_pix); + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, + 0, SPIFFS_PAGE_TO_PADDR(fs, objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); + SPIFFS_CHECK_RES(res); + // cannot allow a gc if the presumed index in fact is no index, a + // check must run or lot of data may be lost + SPIFFS_VALIDATE_OBJIX(objix->p_hdr, gc.cur_obj_id | SPIFFS_OBJ_ID_IX_FLAG, gc.cur_objix_spix); + gc.cur_objix_pix = objix_pix; + } else { + // no more data pages found, passed thru all block, start evacuating object indices + gc.state = MOVE_OBJ_IX; + cur_entry = 0; // restart entry scan index + } + break; + case MOVE_OBJ_DATA: { + // store modified objix (hdr) page residing in memory now that all + // data pages belonging to this object index and residing in the block + // we want to evacuate + spiffs_page_ix new_objix_pix; + gc.state = FIND_OBJ_DATA; + cur_entry = gc.stored_scan_entry_index; // pop cursor + if (gc.cur_objix_spix == 0) { + // store object index header page + res = spiffs_object_update_index_hdr(fs, 0, gc.cur_obj_id | SPIFFS_OBJ_ID_IX_FLAG, gc.cur_objix_pix, fs->work, 0, 0, 0, &new_objix_pix); + SPIFFS_GC_DBG("gc_clean: MOVE_DATA store modified objix_hdr page, "_SPIPRIpg":"_SPIPRIsp"\n", new_objix_pix, 0); + SPIFFS_CHECK_RES(res); + } else { + // store object index page + res = spiffs_page_move(fs, 0, fs->work, gc.cur_obj_id | SPIFFS_OBJ_ID_IX_FLAG, 0, gc.cur_objix_pix, &new_objix_pix); + SPIFFS_GC_DBG("gc_clean: MOVE_DATA store modified objix page, "_SPIPRIpg":"_SPIPRIsp"\n", new_objix_pix, objix->p_hdr.span_ix); + SPIFFS_CHECK_RES(res); + spiffs_cb_object_event(fs, (spiffs_page_object_ix *)fs->work, + SPIFFS_EV_IX_UPD, gc.cur_obj_id, objix->p_hdr.span_ix, new_objix_pix, 0); + } + } + break; + case MOVE_OBJ_IX: + // scanned thru all block, no more object indices found - our work here is done + gc.state = FINISHED; + break; + default: + cur_entry = 0; + break; + } // switch gc.state + SPIFFS_GC_DBG("gc_clean: state-> "_SPIPRIi"\n", gc.state); + } // while state != FINISHED - return res; + return res; } #endif // !SPIFFS_READ_ONLY diff --git a/armsrc/spiffs_hydrogen.c b/armsrc/spiffs_hydrogen.c index adc107270..dee72fb5f 100644 --- a/armsrc/spiffs_hydrogen.c +++ b/armsrc/spiffs_hydrogen.c @@ -15,1007 +15,1019 @@ static s32_t spiffs_fflush_cache(spiffs *fs, spiffs_file fh); #if SPIFFS_BUFFER_HELP u32_t SPIFFS_buffer_bytes_for_filedescs(spiffs *fs, u32_t num_descs) { - return num_descs * sizeof(spiffs_fd); + return num_descs * sizeof(spiffs_fd); } #if SPIFFS_CACHE u32_t SPIFFS_buffer_bytes_for_cache(spiffs *fs, u32_t num_pages) { - return sizeof(spiffs_cache) + num_pages * (sizeof(spiffs_cache_page) + SPIFFS_CFG_LOG_PAGE_SZ(fs)); + return sizeof(spiffs_cache) + num_pages * (sizeof(spiffs_cache_page) + SPIFFS_CFG_LOG_PAGE_SZ(fs)); } #endif #endif u8_t SPIFFS_mounted(spiffs *fs) { - return SPIFFS_CHECK_MOUNT(fs); + return SPIFFS_CHECK_MOUNT(fs); } s32_t SPIFFS_format(spiffs *fs) { #if SPIFFS_READ_ONLY - (void)fs; - return SPIFFS_ERR_RO_NOT_IMPL; + (void)fs; + return SPIFFS_ERR_RO_NOT_IMPL; #else - SPIFFS_API_CHECK_CFG(fs); - if (SPIFFS_CHECK_MOUNT(fs)) { - fs->err_code = SPIFFS_ERR_MOUNTED; - return -1; - } - - s32_t res; - SPIFFS_LOCK(fs); - - spiffs_block_ix bix = 0; - while (bix < fs->block_count) { - fs->max_erase_count = 0; - res = spiffs_erase_block(fs, bix); - if (res != SPIFFS_OK) { - res = SPIFFS_ERR_ERASE_FAIL; + SPIFFS_API_CHECK_CFG(fs); + if (SPIFFS_CHECK_MOUNT(fs)) { + fs->err_code = SPIFFS_ERR_MOUNTED; + return -1; } - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - bix++; - } - SPIFFS_UNLOCK(fs); + s32_t res; + SPIFFS_LOCK(fs); - return 0; + spiffs_block_ix bix = 0; + while (bix < fs->block_count) { + fs->max_erase_count = 0; + res = spiffs_erase_block(fs, bix); + if (res != SPIFFS_OK) { + res = SPIFFS_ERR_ERASE_FAIL; + } + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + bix++; + } + + SPIFFS_UNLOCK(fs); + + return 0; #endif // SPIFFS_READ_ONLY } #if SPIFFS_USE_MAGIC && SPIFFS_USE_MAGIC_LENGTH && SPIFFS_SINGLETON==0 s32_t SPIFFS_probe_fs(spiffs_config *config) { - SPIFFS_API_DBG("%s\n", __func__); - s32_t res = spiffs_probe(config); - return res; + SPIFFS_API_DBG("%s\n", __func__); + s32_t res = spiffs_probe(config); + return res; } #endif // SPIFFS_USE_MAGIC && SPIFFS_USE_MAGIC_LENGTH && SPIFFS_SINGLETON==0 s32_t SPIFFS_mount(spiffs *fs, spiffs_config *config, u8_t *work, - u8_t *fd_space, u32_t fd_space_size, - void *cache, u32_t cache_size, - spiffs_check_callback check_cb_f) { - SPIFFS_API_DBG("%s " - " sz:"_SPIPRIi " logpgsz:"_SPIPRIi " logblksz:"_SPIPRIi " perasz:"_SPIPRIi - " addr:"_SPIPRIad - " fdsz:"_SPIPRIi " cachesz:"_SPIPRIi - "\n", - __func__, - SPIFFS_CFG_PHYS_SZ(fs), - SPIFFS_CFG_LOG_PAGE_SZ(fs), - SPIFFS_CFG_LOG_BLOCK_SZ(fs), - SPIFFS_CFG_PHYS_ERASE_SZ(fs), - SPIFFS_CFG_PHYS_ADDR(fs), - fd_space_size, cache_size); - void *user_data; - SPIFFS_LOCK(fs); - user_data = fs->user_data; - memset(fs, 0, sizeof(spiffs)); - _SPIFFS_MEMCPY(&fs->cfg, config, sizeof(spiffs_config)); - fs->user_data = user_data; - fs->block_count = SPIFFS_CFG_PHYS_SZ(fs) / SPIFFS_CFG_LOG_BLOCK_SZ(fs); - fs->work = &work[0]; - fs->lu_work = &work[SPIFFS_CFG_LOG_PAGE_SZ(fs)]; - memset(fd_space, 0, fd_space_size); - // align fd_space pointer to pointer size byte boundary - u8_t ptr_size = sizeof(void*); - u8_t addr_lsb = ((u8_t)(intptr_t)fd_space) & (ptr_size-1); - if (addr_lsb) { - fd_space += (ptr_size-addr_lsb); - fd_space_size -= (ptr_size-addr_lsb); - } - fs->fd_space = fd_space; - fs->fd_count = (fd_space_size/sizeof(spiffs_fd)); + u8_t *fd_space, u32_t fd_space_size, + void *cache, u32_t cache_size, + spiffs_check_callback check_cb_f) { + SPIFFS_API_DBG("%s " + " sz:"_SPIPRIi " logpgsz:"_SPIPRIi " logblksz:"_SPIPRIi " perasz:"_SPIPRIi + " addr:"_SPIPRIad + " fdsz:"_SPIPRIi " cachesz:"_SPIPRIi + "\n", + __func__, + SPIFFS_CFG_PHYS_SZ(fs), + SPIFFS_CFG_LOG_PAGE_SZ(fs), + SPIFFS_CFG_LOG_BLOCK_SZ(fs), + SPIFFS_CFG_PHYS_ERASE_SZ(fs), + SPIFFS_CFG_PHYS_ADDR(fs), + fd_space_size, cache_size); + void *user_data; + SPIFFS_LOCK(fs); + user_data = fs->user_data; + memset(fs, 0, sizeof(spiffs)); + _SPIFFS_MEMCPY(&fs->cfg, config, sizeof(spiffs_config)); + fs->user_data = user_data; + fs->block_count = SPIFFS_CFG_PHYS_SZ(fs) / SPIFFS_CFG_LOG_BLOCK_SZ(fs); + fs->work = &work[0]; + fs->lu_work = &work[SPIFFS_CFG_LOG_PAGE_SZ(fs)]; + memset(fd_space, 0, fd_space_size); + // align fd_space pointer to pointer size byte boundary + u8_t ptr_size = sizeof(void *); + u8_t addr_lsb = ((u8_t)(intptr_t)fd_space) & (ptr_size - 1); + if (addr_lsb) { + fd_space += (ptr_size - addr_lsb); + fd_space_size -= (ptr_size - addr_lsb); + } + fs->fd_space = fd_space; + fs->fd_count = (fd_space_size / sizeof(spiffs_fd)); - // align cache pointer to 4 byte boundary - addr_lsb = ((u8_t)(intptr_t)cache) & (ptr_size-1); - if (addr_lsb) { - u8_t *cache_8 = (u8_t *)cache; - cache_8 += (ptr_size-addr_lsb); - cache = cache_8; - cache_size -= (ptr_size-addr_lsb); - } - if (cache_size & (ptr_size-1)) { - cache_size -= (cache_size & (ptr_size-1)); - } + // align cache pointer to 4 byte boundary + addr_lsb = ((u8_t)(intptr_t)cache) & (ptr_size - 1); + if (addr_lsb) { + u8_t *cache_8 = (u8_t *)cache; + cache_8 += (ptr_size - addr_lsb); + cache = cache_8; + cache_size -= (ptr_size - addr_lsb); + } + if (cache_size & (ptr_size - 1)) { + cache_size -= (cache_size & (ptr_size - 1)); + } #if SPIFFS_CACHE - fs->cache = cache; - fs->cache_size = (cache_size > (SPIFFS_CFG_LOG_PAGE_SZ(fs)*32)) ? SPIFFS_CFG_LOG_PAGE_SZ(fs)*32 : cache_size; - spiffs_cache_init(fs); + fs->cache = cache; + fs->cache_size = (cache_size > (SPIFFS_CFG_LOG_PAGE_SZ(fs) * 32)) ? SPIFFS_CFG_LOG_PAGE_SZ(fs) * 32 : cache_size; + spiffs_cache_init(fs); #endif - s32_t res; + s32_t res; #if SPIFFS_USE_MAGIC - res = SPIFFS_CHECK_MAGIC_POSSIBLE(fs) ? SPIFFS_OK : SPIFFS_ERR_MAGIC_NOT_POSSIBLE; - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + res = SPIFFS_CHECK_MAGIC_POSSIBLE(fs) ? SPIFFS_OK : SPIFFS_ERR_MAGIC_NOT_POSSIBLE; + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); #endif - fs->config_magic = SPIFFS_CONFIG_MAGIC; + fs->config_magic = SPIFFS_CONFIG_MAGIC; - res = spiffs_obj_lu_scan(fs); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + res = spiffs_obj_lu_scan(fs); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - SPIFFS_DBG("page index byte len: "_SPIPRIi"\n", (u32_t)SPIFFS_CFG_LOG_PAGE_SZ(fs)); - SPIFFS_DBG("object lookup pages: "_SPIPRIi"\n", (u32_t)SPIFFS_OBJ_LOOKUP_PAGES(fs)); - SPIFFS_DBG("page pages per block: "_SPIPRIi"\n", (u32_t)SPIFFS_PAGES_PER_BLOCK(fs)); - SPIFFS_DBG("page header length: "_SPIPRIi"\n", (u32_t)sizeof(spiffs_page_header)); - SPIFFS_DBG("object header index entries: "_SPIPRIi"\n", (u32_t)SPIFFS_OBJ_HDR_IX_LEN(fs)); - SPIFFS_DBG("object index entries: "_SPIPRIi"\n", (u32_t)SPIFFS_OBJ_IX_LEN(fs)); - SPIFFS_DBG("available file descriptors: "_SPIPRIi"\n", (u32_t)fs->fd_count); - SPIFFS_DBG("free blocks: "_SPIPRIi"\n", (u32_t)fs->free_blocks); + SPIFFS_DBG("page index byte len: "_SPIPRIi"\n", (u32_t)SPIFFS_CFG_LOG_PAGE_SZ(fs)); + SPIFFS_DBG("object lookup pages: "_SPIPRIi"\n", (u32_t)SPIFFS_OBJ_LOOKUP_PAGES(fs)); + SPIFFS_DBG("page pages per block: "_SPIPRIi"\n", (u32_t)SPIFFS_PAGES_PER_BLOCK(fs)); + SPIFFS_DBG("page header length: "_SPIPRIi"\n", (u32_t)sizeof(spiffs_page_header)); + SPIFFS_DBG("object header index entries: "_SPIPRIi"\n", (u32_t)SPIFFS_OBJ_HDR_IX_LEN(fs)); + SPIFFS_DBG("object index entries: "_SPIPRIi"\n", (u32_t)SPIFFS_OBJ_IX_LEN(fs)); + SPIFFS_DBG("available file descriptors: "_SPIPRIi"\n", (u32_t)fs->fd_count); + SPIFFS_DBG("free blocks: "_SPIPRIi"\n", (u32_t)fs->free_blocks); - fs->check_cb_f = check_cb_f; + fs->check_cb_f = check_cb_f; - fs->mounted = 1; + fs->mounted = 1; - SPIFFS_UNLOCK(fs); + SPIFFS_UNLOCK(fs); - return 0; + return 0; } void SPIFFS_unmount(spiffs *fs) { - SPIFFS_API_DBG("%s\n", __func__); - if (!SPIFFS_CHECK_CFG(fs) || !SPIFFS_CHECK_MOUNT(fs)) return; - SPIFFS_LOCK(fs); - u32_t i; - spiffs_fd *fds = (spiffs_fd *)fs->fd_space; - for (i = 0; i < fs->fd_count; i++) { - spiffs_fd *cur_fd = &fds[i]; - if (cur_fd->file_nbr != 0) { + SPIFFS_API_DBG("%s\n", __func__); + if (!SPIFFS_CHECK_CFG(fs) || !SPIFFS_CHECK_MOUNT(fs)) return; + SPIFFS_LOCK(fs); + u32_t i; + spiffs_fd *fds = (spiffs_fd *)fs->fd_space; + for (i = 0; i < fs->fd_count; i++) { + spiffs_fd *cur_fd = &fds[i]; + if (cur_fd->file_nbr != 0) { #if SPIFFS_CACHE - (void)spiffs_fflush_cache(fs, cur_fd->file_nbr); + (void)spiffs_fflush_cache(fs, cur_fd->file_nbr); #endif - spiffs_fd_return(fs, cur_fd->file_nbr); + spiffs_fd_return(fs, cur_fd->file_nbr); + } } - } - fs->mounted = 0; + fs->mounted = 0; - SPIFFS_UNLOCK(fs); + SPIFFS_UNLOCK(fs); } s32_t SPIFFS_errno(spiffs *fs) { - return fs->err_code; + return fs->err_code; } void SPIFFS_clearerr(spiffs *fs) { - SPIFFS_API_DBG("%s\n", __func__); - fs->err_code = SPIFFS_OK; + SPIFFS_API_DBG("%s\n", __func__); + fs->err_code = SPIFFS_OK; } s32_t SPIFFS_creat(spiffs *fs, const char *path, spiffs_mode mode) { - SPIFFS_API_DBG("%s '%s'\n", __func__, path); + SPIFFS_API_DBG("%s '%s'\n", __func__, path); #if SPIFFS_READ_ONLY - (void)fs; (void)path; (void)mode; - return SPIFFS_ERR_RO_NOT_IMPL; + (void)fs; + (void)path; + (void)mode; + return SPIFFS_ERR_RO_NOT_IMPL; #else - (void)mode; - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - if (strlen(path) > SPIFFS_OBJ_NAME_LEN - 1) { - SPIFFS_API_CHECK_RES(fs, SPIFFS_ERR_NAME_TOO_LONG); - } - SPIFFS_LOCK(fs); - spiffs_obj_id obj_id; - s32_t res; + (void)mode; + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + if (strlen(path) > SPIFFS_OBJ_NAME_LEN - 1) { + SPIFFS_API_CHECK_RES(fs, SPIFFS_ERR_NAME_TOO_LONG); + } + SPIFFS_LOCK(fs); + spiffs_obj_id obj_id; + s32_t res; - res = spiffs_obj_lu_find_free_obj_id(fs, &obj_id, (const u8_t*)path); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - res = spiffs_object_create(fs, obj_id, (const u8_t*)path, 0, SPIFFS_TYPE_FILE, 0); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - SPIFFS_UNLOCK(fs); - return 0; + res = spiffs_obj_lu_find_free_obj_id(fs, &obj_id, (const u8_t *)path); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + res = spiffs_object_create(fs, obj_id, (const u8_t *)path, 0, SPIFFS_TYPE_FILE, 0); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + SPIFFS_UNLOCK(fs); + return 0; #endif // SPIFFS_READ_ONLY } spiffs_file SPIFFS_open(spiffs *fs, const char *path, spiffs_flags flags, spiffs_mode mode) { - SPIFFS_API_DBG("%s '%s' "_SPIPRIfl "\n", __func__, path, flags); - (void)mode; - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - if (strlen(path) > SPIFFS_OBJ_NAME_LEN - 1) { - SPIFFS_API_CHECK_RES(fs, SPIFFS_ERR_NAME_TOO_LONG); - } - SPIFFS_LOCK(fs); + SPIFFS_API_DBG("%s '%s' "_SPIPRIfl "\n", __func__, path, flags); + (void)mode; + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + if (strlen(path) > SPIFFS_OBJ_NAME_LEN - 1) { + SPIFFS_API_CHECK_RES(fs, SPIFFS_ERR_NAME_TOO_LONG); + } + SPIFFS_LOCK(fs); - spiffs_fd *fd; - spiffs_page_ix pix; + spiffs_fd *fd; + spiffs_page_ix pix; #if SPIFFS_READ_ONLY - // not valid flags in read only mode - flags &= ~(SPIFFS_WRONLY | SPIFFS_CREAT | SPIFFS_TRUNC); + // not valid flags in read only mode + flags &= ~(SPIFFS_WRONLY | SPIFFS_CREAT | SPIFFS_TRUNC); #endif // SPIFFS_READ_ONLY - s32_t res = spiffs_fd_find_new(fs, &fd, path); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + s32_t res = spiffs_fd_find_new(fs, &fd, path); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - res = spiffs_object_find_object_index_header_by_name(fs, (const u8_t*)path, &pix); - if ((flags & SPIFFS_O_CREAT) == 0) { - if (res < SPIFFS_OK) { - spiffs_fd_return(fs, fd->file_nbr); + res = spiffs_object_find_object_index_header_by_name(fs, (const u8_t *)path, &pix); + if ((flags & SPIFFS_O_CREAT) == 0) { + if (res < SPIFFS_OK) { + spiffs_fd_return(fs, fd->file_nbr); + } + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); } - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - } - if (res == SPIFFS_OK && - (flags & (SPIFFS_O_CREAT | SPIFFS_O_EXCL)) == (SPIFFS_O_CREAT | SPIFFS_O_EXCL)) { - // creat and excl and file exists - fail - res = SPIFFS_ERR_FILE_EXISTS; - spiffs_fd_return(fs, fd->file_nbr); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - } + if (res == SPIFFS_OK && + (flags & (SPIFFS_O_CREAT | SPIFFS_O_EXCL)) == (SPIFFS_O_CREAT | SPIFFS_O_EXCL)) { + // creat and excl and file exists - fail + res = SPIFFS_ERR_FILE_EXISTS; + spiffs_fd_return(fs, fd->file_nbr); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + } - if ((flags & SPIFFS_O_CREAT) && res == SPIFFS_ERR_NOT_FOUND) { + if ((flags & SPIFFS_O_CREAT) && res == SPIFFS_ERR_NOT_FOUND) { #if !SPIFFS_READ_ONLY - spiffs_obj_id obj_id; - // no need to enter conflicting name here, already looked for it above - res = spiffs_obj_lu_find_free_obj_id(fs, &obj_id, 0); - if (res < SPIFFS_OK) { - spiffs_fd_return(fs, fd->file_nbr); - } - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - res = spiffs_object_create(fs, obj_id, (const u8_t*)path, 0, SPIFFS_TYPE_FILE, &pix); - if (res < SPIFFS_OK) { - spiffs_fd_return(fs, fd->file_nbr); - } - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - flags &= ~SPIFFS_O_TRUNC; + spiffs_obj_id obj_id; + // no need to enter conflicting name here, already looked for it above + res = spiffs_obj_lu_find_free_obj_id(fs, &obj_id, 0); + if (res < SPIFFS_OK) { + spiffs_fd_return(fs, fd->file_nbr); + } + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + res = spiffs_object_create(fs, obj_id, (const u8_t *)path, 0, SPIFFS_TYPE_FILE, &pix); + if (res < SPIFFS_OK) { + spiffs_fd_return(fs, fd->file_nbr); + } + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + flags &= ~SPIFFS_O_TRUNC; #endif // !SPIFFS_READ_ONLY - } else { + } else { + if (res < SPIFFS_OK) { + spiffs_fd_return(fs, fd->file_nbr); + } + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + } + res = spiffs_object_open_by_page(fs, pix, fd, flags, mode); if (res < SPIFFS_OK) { - spiffs_fd_return(fs, fd->file_nbr); + spiffs_fd_return(fs, fd->file_nbr); } SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - } - res = spiffs_object_open_by_page(fs, pix, fd, flags, mode); - if (res < SPIFFS_OK) { - spiffs_fd_return(fs, fd->file_nbr); - } - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); #if !SPIFFS_READ_ONLY - if (flags & SPIFFS_O_TRUNC) { - res = spiffs_object_truncate(fd, 0, 0); - if (res < SPIFFS_OK) { - spiffs_fd_return(fs, fd->file_nbr); + if (flags & SPIFFS_O_TRUNC) { + res = spiffs_object_truncate(fd, 0, 0); + if (res < SPIFFS_OK) { + spiffs_fd_return(fs, fd->file_nbr); + } + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); } - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - } #endif // !SPIFFS_READ_ONLY - fd->fdoffset = 0; + fd->fdoffset = 0; - SPIFFS_UNLOCK(fs); + SPIFFS_UNLOCK(fs); - return SPIFFS_FH_OFFS(fs, fd->file_nbr); + return SPIFFS_FH_OFFS(fs, fd->file_nbr); } spiffs_file SPIFFS_open_by_dirent(spiffs *fs, struct spiffs_dirent *e, spiffs_flags flags, spiffs_mode mode) { - SPIFFS_API_DBG("%s '%s':"_SPIPRIid " "_SPIPRIfl "\n", __func__, e->name, e->obj_id, flags); - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - SPIFFS_LOCK(fs); + SPIFFS_API_DBG("%s '%s':"_SPIPRIid " "_SPIPRIfl "\n", __func__, e->name, e->obj_id, flags); + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + SPIFFS_LOCK(fs); - spiffs_fd *fd; + spiffs_fd *fd; - s32_t res = spiffs_fd_find_new(fs, &fd, 0); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + s32_t res = spiffs_fd_find_new(fs, &fd, 0); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - res = spiffs_object_open_by_page(fs, e->pix, fd, flags, mode); - if (res < SPIFFS_OK) { - spiffs_fd_return(fs, fd->file_nbr); - } - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); -#if !SPIFFS_READ_ONLY - if (flags & SPIFFS_O_TRUNC) { - res = spiffs_object_truncate(fd, 0, 0); + res = spiffs_object_open_by_page(fs, e->pix, fd, flags, mode); if (res < SPIFFS_OK) { - spiffs_fd_return(fs, fd->file_nbr); + spiffs_fd_return(fs, fd->file_nbr); } SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - } +#if !SPIFFS_READ_ONLY + if (flags & SPIFFS_O_TRUNC) { + res = spiffs_object_truncate(fd, 0, 0); + if (res < SPIFFS_OK) { + spiffs_fd_return(fs, fd->file_nbr); + } + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + } #endif // !SPIFFS_READ_ONLY - fd->fdoffset = 0; + fd->fdoffset = 0; - SPIFFS_UNLOCK(fs); + SPIFFS_UNLOCK(fs); - return SPIFFS_FH_OFFS(fs, fd->file_nbr); + return SPIFFS_FH_OFFS(fs, fd->file_nbr); } spiffs_file SPIFFS_open_by_page(spiffs *fs, spiffs_page_ix page_ix, spiffs_flags flags, spiffs_mode mode) { - SPIFFS_API_DBG("%s "_SPIPRIpg " "_SPIPRIfl "\n", __func__, page_ix, flags); - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - SPIFFS_LOCK(fs); + SPIFFS_API_DBG("%s "_SPIPRIpg " "_SPIPRIfl "\n", __func__, page_ix, flags); + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + SPIFFS_LOCK(fs); - spiffs_fd *fd; + spiffs_fd *fd; - s32_t res = spiffs_fd_find_new(fs, &fd, 0); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - - if (SPIFFS_IS_LOOKUP_PAGE(fs, page_ix)) { - res = SPIFFS_ERR_NOT_A_FILE; - spiffs_fd_return(fs, fd->file_nbr); + s32_t res = spiffs_fd_find_new(fs, &fd, 0); SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - } - res = spiffs_object_open_by_page(fs, page_ix, fd, flags, mode); - if (res == SPIFFS_ERR_IS_FREE || - res == SPIFFS_ERR_DELETED || - res == SPIFFS_ERR_NOT_FINALIZED || - res == SPIFFS_ERR_NOT_INDEX || - res == SPIFFS_ERR_INDEX_SPAN_MISMATCH) { - res = SPIFFS_ERR_NOT_A_FILE; - } - if (res < SPIFFS_OK) { - spiffs_fd_return(fs, fd->file_nbr); - } - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + if (SPIFFS_IS_LOOKUP_PAGE(fs, page_ix)) { + res = SPIFFS_ERR_NOT_A_FILE; + spiffs_fd_return(fs, fd->file_nbr); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + } -#if !SPIFFS_READ_ONLY - if (flags & SPIFFS_O_TRUNC) { - res = spiffs_object_truncate(fd, 0, 0); + res = spiffs_object_open_by_page(fs, page_ix, fd, flags, mode); + if (res == SPIFFS_ERR_IS_FREE || + res == SPIFFS_ERR_DELETED || + res == SPIFFS_ERR_NOT_FINALIZED || + res == SPIFFS_ERR_NOT_INDEX || + res == SPIFFS_ERR_INDEX_SPAN_MISMATCH) { + res = SPIFFS_ERR_NOT_A_FILE; + } if (res < SPIFFS_OK) { - spiffs_fd_return(fs, fd->file_nbr); + spiffs_fd_return(fs, fd->file_nbr); } SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - } + +#if !SPIFFS_READ_ONLY + if (flags & SPIFFS_O_TRUNC) { + res = spiffs_object_truncate(fd, 0, 0); + if (res < SPIFFS_OK) { + spiffs_fd_return(fs, fd->file_nbr); + } + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + } #endif // !SPIFFS_READ_ONLY - fd->fdoffset = 0; + fd->fdoffset = 0; - SPIFFS_UNLOCK(fs); + SPIFFS_UNLOCK(fs); - return SPIFFS_FH_OFFS(fs, fd->file_nbr); + return SPIFFS_FH_OFFS(fs, fd->file_nbr); } static s32_t spiffs_hydro_read(spiffs *fs, spiffs_file fh, void *buf, s32_t len) { - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - SPIFFS_LOCK(fs); + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + SPIFFS_LOCK(fs); - spiffs_fd *fd; - s32_t res; + spiffs_fd *fd; + s32_t res; - fh = SPIFFS_FH_UNOFFS(fs, fh); - res = spiffs_fd_get(fs, fh, &fd); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - - if ((fd->flags & SPIFFS_O_RDONLY) == 0) { - res = SPIFFS_ERR_NOT_READABLE; + fh = SPIFFS_FH_UNOFFS(fs, fh); + res = spiffs_fd_get(fs, fh, &fd); SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - } - if (fd->size == SPIFFS_UNDEFINED_LEN && len > 0) { - // special case for zero sized files - res = SPIFFS_ERR_END_OF_OBJECT; - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - } + if ((fd->flags & SPIFFS_O_RDONLY) == 0) { + res = SPIFFS_ERR_NOT_READABLE; + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + } + + if (fd->size == SPIFFS_UNDEFINED_LEN && len > 0) { + // special case for zero sized files + res = SPIFFS_ERR_END_OF_OBJECT; + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + } #if SPIFFS_CACHE_WR - spiffs_fflush_cache(fs, fh); + spiffs_fflush_cache(fs, fh); #endif - if (fd->fdoffset + len >= fd->size) { - // reading beyond file size - s32_t avail = fd->size - fd->fdoffset; - if (avail <= 0) { - SPIFFS_API_CHECK_RES_UNLOCK(fs, SPIFFS_ERR_END_OF_OBJECT); - } - res = spiffs_object_read(fd, fd->fdoffset, avail, (u8_t*)buf); - if (res == SPIFFS_ERR_END_OF_OBJECT) { - fd->fdoffset += avail; - SPIFFS_UNLOCK(fs); - return avail; + if (fd->fdoffset + len >= fd->size) { + // reading beyond file size + s32_t avail = fd->size - fd->fdoffset; + if (avail <= 0) { + SPIFFS_API_CHECK_RES_UNLOCK(fs, SPIFFS_ERR_END_OF_OBJECT); + } + res = spiffs_object_read(fd, fd->fdoffset, avail, (u8_t *)buf); + if (res == SPIFFS_ERR_END_OF_OBJECT) { + fd->fdoffset += avail; + SPIFFS_UNLOCK(fs); + return avail; + } else { + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + len = avail; + } } else { - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - len = avail; + // reading within file size + res = spiffs_object_read(fd, fd->fdoffset, len, (u8_t *)buf); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); } - } else { - // reading within file size - res = spiffs_object_read(fd, fd->fdoffset, len, (u8_t*)buf); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - } - fd->fdoffset += len; + fd->fdoffset += len; - SPIFFS_UNLOCK(fs); + SPIFFS_UNLOCK(fs); - return len; + return len; } s32_t SPIFFS_read(spiffs *fs, spiffs_file fh, void *buf, s32_t len) { - SPIFFS_API_DBG("%s "_SPIPRIfd " "_SPIPRIi "\n", __func__, fh, len); - s32_t res = spiffs_hydro_read(fs, fh, buf, len); - if (res == SPIFFS_ERR_END_OF_OBJECT) { - res = 0; - } - return res; + SPIFFS_API_DBG("%s "_SPIPRIfd " "_SPIPRIi "\n", __func__, fh, len); + s32_t res = spiffs_hydro_read(fs, fh, buf, len); + if (res == SPIFFS_ERR_END_OF_OBJECT) { + res = 0; + } + return res; } #if !SPIFFS_READ_ONLY static s32_t spiffs_hydro_write(spiffs *fs, spiffs_fd *fd, void *buf, u32_t offset, s32_t len) { - (void)fs; - s32_t res = SPIFFS_OK; - s32_t remaining = len; - if (fd->size != SPIFFS_UNDEFINED_LEN && offset < fd->size) { - s32_t m_len = MIN((s32_t)(fd->size - offset), len); - res = spiffs_object_modify(fd, offset, (u8_t *)buf, m_len); - SPIFFS_CHECK_RES(res); - remaining -= m_len; - u8_t *buf_8 = (u8_t *)buf; - buf_8 += m_len; - buf = buf_8; - offset += m_len; - } - if (remaining > 0) { - res = spiffs_object_append(fd, offset, (u8_t *)buf, remaining); - SPIFFS_CHECK_RES(res); - } - return len; + (void)fs; + s32_t res = SPIFFS_OK; + s32_t remaining = len; + if (fd->size != SPIFFS_UNDEFINED_LEN && offset < fd->size) { + s32_t m_len = MIN((s32_t)(fd->size - offset), len); + res = spiffs_object_modify(fd, offset, (u8_t *)buf, m_len); + SPIFFS_CHECK_RES(res); + remaining -= m_len; + u8_t *buf_8 = (u8_t *)buf; + buf_8 += m_len; + buf = buf_8; + offset += m_len; + } + if (remaining > 0) { + res = spiffs_object_append(fd, offset, (u8_t *)buf, remaining); + SPIFFS_CHECK_RES(res); + } + return len; } #endif // !SPIFFS_READ_ONLY s32_t SPIFFS_write(spiffs *fs, spiffs_file fh, void *buf, s32_t len) { - SPIFFS_API_DBG("%s "_SPIPRIfd " "_SPIPRIi "\n", __func__, fh, len); + SPIFFS_API_DBG("%s "_SPIPRIfd " "_SPIPRIi "\n", __func__, fh, len); #if SPIFFS_READ_ONLY - (void)fs; (void)fh; (void)buf; (void)len; - return SPIFFS_ERR_RO_NOT_IMPL; + (void)fs; + (void)fh; + (void)buf; + (void)len; + return SPIFFS_ERR_RO_NOT_IMPL; #else - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - SPIFFS_LOCK(fs); + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + SPIFFS_LOCK(fs); - spiffs_fd *fd; - s32_t res; - u32_t offset; + spiffs_fd *fd; + s32_t res; + u32_t offset; - fh = SPIFFS_FH_UNOFFS(fs, fh); - res = spiffs_fd_get(fs, fh, &fd); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - - if ((fd->flags & SPIFFS_O_WRONLY) == 0) { - res = SPIFFS_ERR_NOT_WRITABLE; + fh = SPIFFS_FH_UNOFFS(fs, fh); + res = spiffs_fd_get(fs, fh, &fd); SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - } - if ((fd->flags & SPIFFS_O_APPEND)) { - fd->fdoffset = fd->size == SPIFFS_UNDEFINED_LEN ? 0 : fd->size; - } - offset = fd->fdoffset; - -#if SPIFFS_CACHE_WR - if (fd->cache_page == 0) { - // see if object id is associated with cache already - fd->cache_page = spiffs_cache_page_get_by_fd(fs, fd); - } -#endif - if (fd->flags & SPIFFS_O_APPEND) { - if (fd->size == SPIFFS_UNDEFINED_LEN) { - offset = 0; - } else { - offset = fd->size; + if ((fd->flags & SPIFFS_O_WRONLY) == 0) { + res = SPIFFS_ERR_NOT_WRITABLE; + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); } + + if ((fd->flags & SPIFFS_O_APPEND)) { + fd->fdoffset = fd->size == SPIFFS_UNDEFINED_LEN ? 0 : fd->size; + } + offset = fd->fdoffset; + #if SPIFFS_CACHE_WR - if (fd->cache_page) { - offset = MAX(offset, fd->cache_page->ucache.swrc.offset + fd->cache_page->ucache.swrc.size); + if (fd->cache_page == 0) { + // see if object id is associated with cache already + fd->cache_page = spiffs_cache_page_get_by_fd(fs, fd); } #endif - } - -#if SPIFFS_CACHE_WR - if ((fd->flags & SPIFFS_O_DIRECT) == 0) { - if (len < (s32_t)SPIFFS_CFG_LOG_PAGE_SZ(fs)) { - // small write, try to cache it - u8_t alloc_cpage = 1; - if (fd->cache_page) { - // have a cached page for this fd already, check cache page boundaries - if (offset < fd->cache_page->ucache.swrc.offset || // writing before cache - offset > fd->cache_page->ucache.swrc.offset + fd->cache_page->ucache.swrc.size || // writing after cache - offset + len > fd->cache_page->ucache.swrc.offset + SPIFFS_CFG_LOG_PAGE_SZ(fs)) // writing beyond cache page - { - // boundary violation, write back cache first and allocate new - SPIFFS_CACHE_DBG("CACHE_WR_DUMP: dumping cache page "_SPIPRIi" for fd "_SPIPRIfd":"_SPIPRIid", boundary viol, offs:"_SPIPRIi" size:"_SPIPRIi"\n", - fd->cache_page->ix, fd->file_nbr, fd->obj_id, fd->cache_page->ucache.swrc.offset, fd->cache_page->ucache.swrc.size); - res = spiffs_hydro_write(fs, fd, - spiffs_get_cache_page(fs, spiffs_get_cache(fs), fd->cache_page->ix), - fd->cache_page->ucache.swrc.offset, fd->cache_page->ucache.swrc.size); - spiffs_cache_fd_release(fs, fd->cache_page); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + if (fd->flags & SPIFFS_O_APPEND) { + if (fd->size == SPIFFS_UNDEFINED_LEN) { + offset = 0; } else { - // writing within cache - alloc_cpage = 0; + offset = fd->size; } - } - - if (alloc_cpage) { - fd->cache_page = spiffs_cache_page_allocate_by_fd(fs, fd); +#if SPIFFS_CACHE_WR if (fd->cache_page) { - fd->cache_page->ucache.swrc.offset = offset; - fd->cache_page->ucache.swrc.size = 0; - SPIFFS_CACHE_DBG("CACHE_WR_ALLO: allocating cache page "_SPIPRIi" for fd "_SPIPRIfd":"_SPIPRIid"\n", - fd->cache_page->ix, fd->file_nbr, fd->obj_id); - } - } - - if (fd->cache_page) { - u32_t offset_in_cpage = offset - fd->cache_page->ucache.swrc.offset; - SPIFFS_CACHE_DBG("CACHE_WR_WRITE: storing to cache page "_SPIPRIi" for fd "_SPIPRIfd":"_SPIPRIid", offs "_SPIPRIi":"_SPIPRIi" len "_SPIPRIi"\n", - fd->cache_page->ix, fd->file_nbr, fd->obj_id, - offset, offset_in_cpage, len); - spiffs_cache *cache = spiffs_get_cache(fs); - u8_t *cpage_data = spiffs_get_cache_page(fs, cache, fd->cache_page->ix); -#ifdef _SPIFFS_TEST - { - intptr_t __a1 = (u8_t*)&cpage_data[offset_in_cpage]-(u8_t*)cache; - intptr_t __a2 = (u8_t*)&cpage_data[offset_in_cpage]+len-(u8_t*)cache; - intptr_t __b = sizeof(spiffs_cache) + cache->cpage_count * (sizeof(spiffs_cache_page) + SPIFFS_CFG_LOG_PAGE_SZ(fs)); - if (__a1 > __b || __a2 > __b) { - printf("FATAL OOB: CACHE_WR: memcpy to cache buffer ixs:%4ld..%4ld of %4ld\n", __a1, __a2, __b); - ERREXIT(); - } + offset = MAX(offset, fd->cache_page->ucache.swrc.offset + fd->cache_page->ucache.swrc.size); } #endif - _SPIFFS_MEMCPY(&cpage_data[offset_in_cpage], buf, len); - fd->cache_page->ucache.swrc.size = MAX(fd->cache_page->ucache.swrc.size, offset_in_cpage + len); - fd->fdoffset += len; - SPIFFS_UNLOCK(fs); - return len; - } else { - res = spiffs_hydro_write(fs, fd, buf, offset, len); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - fd->fdoffset += len; - SPIFFS_UNLOCK(fs); - return res; - } - } else { - // big write, no need to cache it - but first check if there is a cached write already - if (fd->cache_page) { - // write back cache first - SPIFFS_CACHE_DBG("CACHE_WR_DUMP: dumping cache page "_SPIPRIi" for fd "_SPIPRIfd":"_SPIPRIid", big write, offs:"_SPIPRIi" size:"_SPIPRIi"\n", - fd->cache_page->ix, fd->file_nbr, fd->obj_id, fd->cache_page->ucache.swrc.offset, fd->cache_page->ucache.swrc.size); - res = spiffs_hydro_write(fs, fd, - spiffs_get_cache_page(fs, spiffs_get_cache(fs), fd->cache_page->ix), - fd->cache_page->ucache.swrc.offset, fd->cache_page->ucache.swrc.size); - spiffs_cache_fd_release(fs, fd->cache_page); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - // data written below - } } - } + +#if SPIFFS_CACHE_WR + if ((fd->flags & SPIFFS_O_DIRECT) == 0) { + if (len < (s32_t)SPIFFS_CFG_LOG_PAGE_SZ(fs)) { + // small write, try to cache it + u8_t alloc_cpage = 1; + if (fd->cache_page) { + // have a cached page for this fd already, check cache page boundaries + if (offset < fd->cache_page->ucache.swrc.offset || // writing before cache + offset > fd->cache_page->ucache.swrc.offset + fd->cache_page->ucache.swrc.size || // writing after cache + offset + len > fd->cache_page->ucache.swrc.offset + SPIFFS_CFG_LOG_PAGE_SZ(fs)) { // writing beyond cache page + // boundary violation, write back cache first and allocate new + SPIFFS_CACHE_DBG("CACHE_WR_DUMP: dumping cache page "_SPIPRIi" for fd "_SPIPRIfd":"_SPIPRIid", boundary viol, offs:"_SPIPRIi" size:"_SPIPRIi"\n", + fd->cache_page->ix, fd->file_nbr, fd->obj_id, fd->cache_page->ucache.swrc.offset, fd->cache_page->ucache.swrc.size); + res = spiffs_hydro_write(fs, fd, + spiffs_get_cache_page(fs, spiffs_get_cache(fs), fd->cache_page->ix), + fd->cache_page->ucache.swrc.offset, fd->cache_page->ucache.swrc.size); + spiffs_cache_fd_release(fs, fd->cache_page); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + } else { + // writing within cache + alloc_cpage = 0; + } + } + + if (alloc_cpage) { + fd->cache_page = spiffs_cache_page_allocate_by_fd(fs, fd); + if (fd->cache_page) { + fd->cache_page->ucache.swrc.offset = offset; + fd->cache_page->ucache.swrc.size = 0; + SPIFFS_CACHE_DBG("CACHE_WR_ALLO: allocating cache page "_SPIPRIi" for fd "_SPIPRIfd":"_SPIPRIid"\n", + fd->cache_page->ix, fd->file_nbr, fd->obj_id); + } + } + + if (fd->cache_page) { + u32_t offset_in_cpage = offset - fd->cache_page->ucache.swrc.offset; + SPIFFS_CACHE_DBG("CACHE_WR_WRITE: storing to cache page "_SPIPRIi" for fd "_SPIPRIfd":"_SPIPRIid", offs "_SPIPRIi":"_SPIPRIi" len "_SPIPRIi"\n", + fd->cache_page->ix, fd->file_nbr, fd->obj_id, + offset, offset_in_cpage, len); + spiffs_cache *cache = spiffs_get_cache(fs); + u8_t *cpage_data = spiffs_get_cache_page(fs, cache, fd->cache_page->ix); +#ifdef _SPIFFS_TEST + { + intptr_t __a1 = (u8_t *)&cpage_data[offset_in_cpage] - (u8_t *)cache; + intptr_t __a2 = (u8_t *)&cpage_data[offset_in_cpage] + len - (u8_t *)cache; + intptr_t __b = sizeof(spiffs_cache) + cache->cpage_count * (sizeof(spiffs_cache_page) + SPIFFS_CFG_LOG_PAGE_SZ(fs)); + if (__a1 > __b || __a2 > __b) { + printf("FATAL OOB: CACHE_WR: memcpy to cache buffer ixs:%4ld..%4ld of %4ld\n", __a1, __a2, __b); + ERREXIT(); + } + } +#endif + _SPIFFS_MEMCPY(&cpage_data[offset_in_cpage], buf, len); + fd->cache_page->ucache.swrc.size = MAX(fd->cache_page->ucache.swrc.size, offset_in_cpage + len); + fd->fdoffset += len; + SPIFFS_UNLOCK(fs); + return len; + } else { + res = spiffs_hydro_write(fs, fd, buf, offset, len); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + fd->fdoffset += len; + SPIFFS_UNLOCK(fs); + return res; + } + } else { + // big write, no need to cache it - but first check if there is a cached write already + if (fd->cache_page) { + // write back cache first + SPIFFS_CACHE_DBG("CACHE_WR_DUMP: dumping cache page "_SPIPRIi" for fd "_SPIPRIfd":"_SPIPRIid", big write, offs:"_SPIPRIi" size:"_SPIPRIi"\n", + fd->cache_page->ix, fd->file_nbr, fd->obj_id, fd->cache_page->ucache.swrc.offset, fd->cache_page->ucache.swrc.size); + res = spiffs_hydro_write(fs, fd, + spiffs_get_cache_page(fs, spiffs_get_cache(fs), fd->cache_page->ix), + fd->cache_page->ucache.swrc.offset, fd->cache_page->ucache.swrc.size); + spiffs_cache_fd_release(fs, fd->cache_page); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + // data written below + } + } + } #endif - res = spiffs_hydro_write(fs, fd, buf, offset, len); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - fd->fdoffset += len; + res = spiffs_hydro_write(fs, fd, buf, offset, len); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + fd->fdoffset += len; - SPIFFS_UNLOCK(fs); + SPIFFS_UNLOCK(fs); - return res; + return res; #endif // SPIFFS_READ_ONLY } s32_t SPIFFS_lseek(spiffs *fs, spiffs_file fh, s32_t offs, int whence) { - SPIFFS_API_DBG("%s "_SPIPRIfd " "_SPIPRIi " %s\n", __func__, fh, offs, (const char* []){"SET","CUR","END","???"}[MIN(whence,3)]); - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - SPIFFS_LOCK(fs); + SPIFFS_API_DBG("%s "_SPIPRIfd " "_SPIPRIi " %s\n", __func__, fh, offs, (const char *[]) {"SET", "CUR", "END", "???"}[MIN(whence, 3)]); + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + SPIFFS_LOCK(fs); - spiffs_fd *fd; - s32_t res; - fh = SPIFFS_FH_UNOFFS(fs, fh); - res = spiffs_fd_get(fs, fh, &fd); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + spiffs_fd *fd; + s32_t res; + fh = SPIFFS_FH_UNOFFS(fs, fh); + res = spiffs_fd_get(fs, fh, &fd); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); #if SPIFFS_CACHE_WR - spiffs_fflush_cache(fs, fh); + spiffs_fflush_cache(fs, fh); #endif - s32_t file_size = fd->size == SPIFFS_UNDEFINED_LEN ? 0 : fd->size; + s32_t file_size = fd->size == SPIFFS_UNDEFINED_LEN ? 0 : fd->size; - switch (whence) { - case SPIFFS_SEEK_CUR: - offs = fd->fdoffset+offs; - break; - case SPIFFS_SEEK_END: - offs = file_size + offs; - break; - } - if (offs < 0) { - SPIFFS_API_CHECK_RES_UNLOCK(fs, SPIFFS_ERR_SEEK_BOUNDS); - } - if (offs > file_size) { - fd->fdoffset = file_size; - res = SPIFFS_ERR_END_OF_OBJECT; - } - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - - spiffs_span_ix data_spix = (offs > 0 ? (offs-1) : 0) / SPIFFS_DATA_PAGE_SIZE(fs); - spiffs_span_ix objix_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, data_spix); - if (fd->cursor_objix_spix != objix_spix) { - spiffs_page_ix pix; - res = spiffs_obj_lu_find_id_and_span( - fs, fd->obj_id | SPIFFS_OBJ_ID_IX_FLAG, objix_spix, 0, &pix); + switch (whence) { + case SPIFFS_SEEK_CUR: + offs = fd->fdoffset + offs; + break; + case SPIFFS_SEEK_END: + offs = file_size + offs; + break; + } + if (offs < 0) { + SPIFFS_API_CHECK_RES_UNLOCK(fs, SPIFFS_ERR_SEEK_BOUNDS); + } + if (offs > file_size) { + fd->fdoffset = file_size; + res = SPIFFS_ERR_END_OF_OBJECT; + } SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - fd->cursor_objix_spix = objix_spix; - fd->cursor_objix_pix = pix; - } - fd->fdoffset = offs; - SPIFFS_UNLOCK(fs); + spiffs_span_ix data_spix = (offs > 0 ? (offs - 1) : 0) / SPIFFS_DATA_PAGE_SIZE(fs); + spiffs_span_ix objix_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, data_spix); + if (fd->cursor_objix_spix != objix_spix) { + spiffs_page_ix pix; + res = spiffs_obj_lu_find_id_and_span( + fs, fd->obj_id | SPIFFS_OBJ_ID_IX_FLAG, objix_spix, 0, &pix); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + fd->cursor_objix_spix = objix_spix; + fd->cursor_objix_pix = pix; + } + fd->fdoffset = offs; - return offs; + SPIFFS_UNLOCK(fs); + + return offs; } s32_t SPIFFS_remove(spiffs *fs, const char *path) { - SPIFFS_API_DBG("%s '%s'\n", __func__, path); + SPIFFS_API_DBG("%s '%s'\n", __func__, path); #if SPIFFS_READ_ONLY - (void)fs; (void)path; - return SPIFFS_ERR_RO_NOT_IMPL; + (void)fs; + (void)path; + return SPIFFS_ERR_RO_NOT_IMPL; #else - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - if (strlen(path) > SPIFFS_OBJ_NAME_LEN - 1) { - SPIFFS_API_CHECK_RES(fs, SPIFFS_ERR_NAME_TOO_LONG); - } - SPIFFS_LOCK(fs); + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + if (strlen(path) > SPIFFS_OBJ_NAME_LEN - 1) { + SPIFFS_API_CHECK_RES(fs, SPIFFS_ERR_NAME_TOO_LONG); + } + SPIFFS_LOCK(fs); - spiffs_fd *fd; - spiffs_page_ix pix; - s32_t res; + spiffs_fd *fd; + spiffs_page_ix pix; + s32_t res; - res = spiffs_fd_find_new(fs, &fd, 0); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + res = spiffs_fd_find_new(fs, &fd, 0); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - res = spiffs_object_find_object_index_header_by_name(fs, (const u8_t*)path, &pix); - if (res != SPIFFS_OK) { - spiffs_fd_return(fs, fd->file_nbr); - } - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + res = spiffs_object_find_object_index_header_by_name(fs, (const u8_t *)path, &pix); + if (res != SPIFFS_OK) { + spiffs_fd_return(fs, fd->file_nbr); + } + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - res = spiffs_object_open_by_page(fs, pix, fd, 0,0); - if (res != SPIFFS_OK) { - spiffs_fd_return(fs, fd->file_nbr); - } - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + res = spiffs_object_open_by_page(fs, pix, fd, 0, 0); + if (res != SPIFFS_OK) { + spiffs_fd_return(fs, fd->file_nbr); + } + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - res = spiffs_object_truncate(fd, 0, 1); - if (res != SPIFFS_OK) { - spiffs_fd_return(fs, fd->file_nbr); - } - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + res = spiffs_object_truncate(fd, 0, 1); + if (res != SPIFFS_OK) { + spiffs_fd_return(fs, fd->file_nbr); + } + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - SPIFFS_UNLOCK(fs); - return 0; + SPIFFS_UNLOCK(fs); + return 0; #endif // SPIFFS_READ_ONLY } s32_t SPIFFS_fremove(spiffs *fs, spiffs_file fh) { - SPIFFS_API_DBG("%s "_SPIPRIfd "\n", __func__, fh); + SPIFFS_API_DBG("%s "_SPIPRIfd "\n", __func__, fh); #if SPIFFS_READ_ONLY - (void)fs; (void)fh; - return SPIFFS_ERR_RO_NOT_IMPL; + (void)fs; + (void)fh; + return SPIFFS_ERR_RO_NOT_IMPL; #else - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - SPIFFS_LOCK(fs); + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + SPIFFS_LOCK(fs); - spiffs_fd *fd; - s32_t res; - fh = SPIFFS_FH_UNOFFS(fs, fh); - res = spiffs_fd_get(fs, fh, &fd); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - - if ((fd->flags & SPIFFS_O_WRONLY) == 0) { - res = SPIFFS_ERR_NOT_WRITABLE; + spiffs_fd *fd; + s32_t res; + fh = SPIFFS_FH_UNOFFS(fs, fh); + res = spiffs_fd_get(fs, fh, &fd); SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - } + + if ((fd->flags & SPIFFS_O_WRONLY) == 0) { + res = SPIFFS_ERR_NOT_WRITABLE; + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + } #if SPIFFS_CACHE_WR - spiffs_cache_fd_release(fs, fd->cache_page); + spiffs_cache_fd_release(fs, fd->cache_page); #endif - res = spiffs_object_truncate(fd, 0, 1); + res = spiffs_object_truncate(fd, 0, 1); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - SPIFFS_UNLOCK(fs); + SPIFFS_UNLOCK(fs); - return 0; + return 0; #endif // SPIFFS_READ_ONLY } static s32_t spiffs_stat_pix(spiffs *fs, spiffs_page_ix pix, spiffs_file fh, spiffs_stat *s) { - (void)fh; - spiffs_page_object_ix_header objix_hdr; - spiffs_obj_id obj_id; - s32_t res =_spiffs_rd(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, fh, - SPIFFS_PAGE_TO_PADDR(fs, pix), sizeof(spiffs_page_object_ix_header), (u8_t *)&objix_hdr); - SPIFFS_API_CHECK_RES(fs, res); + (void)fh; + spiffs_page_object_ix_header objix_hdr; + spiffs_obj_id obj_id; + s32_t res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, fh, + SPIFFS_PAGE_TO_PADDR(fs, pix), sizeof(spiffs_page_object_ix_header), (u8_t *)&objix_hdr); + SPIFFS_API_CHECK_RES(fs, res); - u32_t obj_id_addr = SPIFFS_BLOCK_TO_PADDR(fs, SPIFFS_BLOCK_FOR_PAGE(fs , pix)) + - SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(fs, pix) * sizeof(spiffs_obj_id); - res =_spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, fh, - obj_id_addr, sizeof(spiffs_obj_id), (u8_t *)&obj_id); - SPIFFS_API_CHECK_RES(fs, res); + u32_t obj_id_addr = SPIFFS_BLOCK_TO_PADDR(fs, SPIFFS_BLOCK_FOR_PAGE(fs, pix)) + + SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(fs, pix) * sizeof(spiffs_obj_id); + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, fh, + obj_id_addr, sizeof(spiffs_obj_id), (u8_t *)&obj_id); + SPIFFS_API_CHECK_RES(fs, res); - s->obj_id = obj_id & ~SPIFFS_OBJ_ID_IX_FLAG; - s->type = objix_hdr.type; - s->size = objix_hdr.size == SPIFFS_UNDEFINED_LEN ? 0 : objix_hdr.size; - s->pix = pix; - strncpy((char *)s->name, (char *)objix_hdr.name, SPIFFS_OBJ_NAME_LEN); + s->obj_id = obj_id & ~SPIFFS_OBJ_ID_IX_FLAG; + s->type = objix_hdr.type; + s->size = objix_hdr.size == SPIFFS_UNDEFINED_LEN ? 0 : objix_hdr.size; + s->pix = pix; + strncpy((char *)s->name, (char *)objix_hdr.name, SPIFFS_OBJ_NAME_LEN); #if SPIFFS_OBJ_META_LEN - _SPIFFS_MEMCPY(s->meta, objix_hdr.meta, SPIFFS_OBJ_META_LEN); + _SPIFFS_MEMCPY(s->meta, objix_hdr.meta, SPIFFS_OBJ_META_LEN); #endif - return res; + return res; } s32_t SPIFFS_stat(spiffs *fs, const char *path, spiffs_stat *s) { - SPIFFS_API_DBG("%s '%s'\n", __func__, path); - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - if (strlen(path) > SPIFFS_OBJ_NAME_LEN - 1) { - SPIFFS_API_CHECK_RES(fs, SPIFFS_ERR_NAME_TOO_LONG); - } - SPIFFS_LOCK(fs); + SPIFFS_API_DBG("%s '%s'\n", __func__, path); + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + if (strlen(path) > SPIFFS_OBJ_NAME_LEN - 1) { + SPIFFS_API_CHECK_RES(fs, SPIFFS_ERR_NAME_TOO_LONG); + } + SPIFFS_LOCK(fs); - s32_t res; - spiffs_page_ix pix; + s32_t res; + spiffs_page_ix pix; - res = spiffs_object_find_object_index_header_by_name(fs, (const u8_t*)path, &pix); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + res = spiffs_object_find_object_index_header_by_name(fs, (const u8_t *)path, &pix); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - res = spiffs_stat_pix(fs, pix, 0, s); + res = spiffs_stat_pix(fs, pix, 0, s); - SPIFFS_UNLOCK(fs); + SPIFFS_UNLOCK(fs); - return res; + return res; } s32_t SPIFFS_fstat(spiffs *fs, spiffs_file fh, spiffs_stat *s) { - SPIFFS_API_DBG("%s "_SPIPRIfd "\n", __func__, fh); - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - SPIFFS_LOCK(fs); + SPIFFS_API_DBG("%s "_SPIPRIfd "\n", __func__, fh); + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + SPIFFS_LOCK(fs); - spiffs_fd *fd; - s32_t res; + spiffs_fd *fd; + s32_t res; - fh = SPIFFS_FH_UNOFFS(fs, fh); - res = spiffs_fd_get(fs, fh, &fd); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + fh = SPIFFS_FH_UNOFFS(fs, fh); + res = spiffs_fd_get(fs, fh, &fd); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); #if SPIFFS_CACHE_WR - spiffs_fflush_cache(fs, fh); + spiffs_fflush_cache(fs, fh); #endif - res = spiffs_stat_pix(fs, fd->objix_hdr_pix, fh, s); + res = spiffs_stat_pix(fs, fd->objix_hdr_pix, fh, s); - SPIFFS_UNLOCK(fs); + SPIFFS_UNLOCK(fs); - return res; + return res; } // Checks if there are any cached writes for the object id associated with // given filehandle. If so, these writes are flushed. #if SPIFFS_CACHE == 1 static s32_t spiffs_fflush_cache(spiffs *fs, spiffs_file fh) { - (void)fs; - (void)fh; - s32_t res = SPIFFS_OK; + (void)fs; + (void)fh; + s32_t res = SPIFFS_OK; #if !SPIFFS_READ_ONLY && SPIFFS_CACHE_WR - spiffs_fd *fd; - res = spiffs_fd_get(fs, fh, &fd); - SPIFFS_API_CHECK_RES(fs, res); + spiffs_fd *fd; + res = spiffs_fd_get(fs, fh, &fd); + SPIFFS_API_CHECK_RES(fs, res); - if ((fd->flags & SPIFFS_O_DIRECT) == 0) { - if (fd->cache_page == 0) { - // see if object id is associated with cache already - fd->cache_page = spiffs_cache_page_get_by_fd(fs, fd); + if ((fd->flags & SPIFFS_O_DIRECT) == 0) { + if (fd->cache_page == 0) { + // see if object id is associated with cache already + fd->cache_page = spiffs_cache_page_get_by_fd(fs, fd); + } + if (fd->cache_page) { + SPIFFS_CACHE_DBG("CACHE_WR_DUMP: dumping cache page "_SPIPRIi" for fd "_SPIPRIfd":"_SPIPRIid", flush, offs:"_SPIPRIi" size:"_SPIPRIi"\n", + fd->cache_page->ix, fd->file_nbr, fd->obj_id, fd->cache_page->ucache.swrc.offset, fd->cache_page->ucache.swrc.size); + res = spiffs_hydro_write(fs, fd, + spiffs_get_cache_page(fs, spiffs_get_cache(fs), fd->cache_page->ix), + fd->cache_page->ucache.swrc.offset, fd->cache_page->ucache.swrc.size); + if (res < SPIFFS_OK) { + fs->err_code = res; + } + spiffs_cache_fd_release(fs, fd->cache_page); + } } - if (fd->cache_page) { - SPIFFS_CACHE_DBG("CACHE_WR_DUMP: dumping cache page "_SPIPRIi" for fd "_SPIPRIfd":"_SPIPRIid", flush, offs:"_SPIPRIi" size:"_SPIPRIi"\n", - fd->cache_page->ix, fd->file_nbr, fd->obj_id, fd->cache_page->ucache.swrc.offset, fd->cache_page->ucache.swrc.size); - res = spiffs_hydro_write(fs, fd, - spiffs_get_cache_page(fs, spiffs_get_cache(fs), fd->cache_page->ix), - fd->cache_page->ucache.swrc.offset, fd->cache_page->ucache.swrc.size); - if (res < SPIFFS_OK) { - fs->err_code = res; - } - spiffs_cache_fd_release(fs, fd->cache_page); - } - } #endif - return res; + return res; } #endif s32_t SPIFFS_fflush(spiffs *fs, spiffs_file fh) { - SPIFFS_API_DBG("%s "_SPIPRIfd "\n", __func__, fh); - (void)fh; - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - s32_t res = SPIFFS_OK; + SPIFFS_API_DBG("%s "_SPIPRIfd "\n", __func__, fh); + (void)fh; + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + s32_t res = SPIFFS_OK; #if !SPIFFS_READ_ONLY && SPIFFS_CACHE_WR - SPIFFS_LOCK(fs); - fh = SPIFFS_FH_UNOFFS(fs, fh); - res = spiffs_fflush_cache(fs, fh); - SPIFFS_API_CHECK_RES_UNLOCK(fs,res); - SPIFFS_UNLOCK(fs); + SPIFFS_LOCK(fs); + fh = SPIFFS_FH_UNOFFS(fs, fh); + res = spiffs_fflush_cache(fs, fh); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + SPIFFS_UNLOCK(fs); #endif - return res; + return res; } s32_t SPIFFS_close(spiffs *fs, spiffs_file fh) { - SPIFFS_API_DBG("%s "_SPIPRIfd "\n", __func__, fh); - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); + SPIFFS_API_DBG("%s "_SPIPRIfd "\n", __func__, fh); + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); - s32_t res = SPIFFS_OK; - SPIFFS_LOCK(fs); + s32_t res = SPIFFS_OK; + SPIFFS_LOCK(fs); - fh = SPIFFS_FH_UNOFFS(fs, fh); + fh = SPIFFS_FH_UNOFFS(fs, fh); #if SPIFFS_CACHE - res = spiffs_fflush_cache(fs, fh); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + res = spiffs_fflush_cache(fs, fh); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); #endif - res = spiffs_fd_return(fs, fh); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + res = spiffs_fd_return(fs, fh); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - SPIFFS_UNLOCK(fs); + SPIFFS_UNLOCK(fs); - return res; + return res; } s32_t SPIFFS_rename(spiffs *fs, const char *old_path, const char *new_path) { - SPIFFS_API_DBG("%s %s %s\n", __func__, old_path, new_path); + SPIFFS_API_DBG("%s %s %s\n", __func__, old_path, new_path); #if SPIFFS_READ_ONLY - (void)fs; (void)old_path; (void)new_path; - return SPIFFS_ERR_RO_NOT_IMPL; + (void)fs; + (void)old_path; + (void)new_path; + return SPIFFS_ERR_RO_NOT_IMPL; #else - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - if (strlen(new_path) > SPIFFS_OBJ_NAME_LEN - 1 || - strlen(old_path) > SPIFFS_OBJ_NAME_LEN - 1) { - SPIFFS_API_CHECK_RES(fs, SPIFFS_ERR_NAME_TOO_LONG); - } - SPIFFS_LOCK(fs); + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + if (strlen(new_path) > SPIFFS_OBJ_NAME_LEN - 1 || + strlen(old_path) > SPIFFS_OBJ_NAME_LEN - 1) { + SPIFFS_API_CHECK_RES(fs, SPIFFS_ERR_NAME_TOO_LONG); + } + SPIFFS_LOCK(fs); - spiffs_page_ix pix_old, pix_dummy; - spiffs_fd *fd; + spiffs_page_ix pix_old, pix_dummy; + spiffs_fd *fd; - s32_t res = spiffs_object_find_object_index_header_by_name(fs, (const u8_t*)old_path, &pix_old); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + s32_t res = spiffs_object_find_object_index_header_by_name(fs, (const u8_t *)old_path, &pix_old); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - res = spiffs_object_find_object_index_header_by_name(fs, (const u8_t*)new_path, &pix_dummy); - if (res == SPIFFS_ERR_NOT_FOUND) { - res = SPIFFS_OK; - } else if (res == SPIFFS_OK) { - res = SPIFFS_ERR_CONFLICTING_NAME; - } - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + res = spiffs_object_find_object_index_header_by_name(fs, (const u8_t *)new_path, &pix_dummy); + if (res == SPIFFS_ERR_NOT_FOUND) { + res = SPIFFS_OK; + } else if (res == SPIFFS_OK) { + res = SPIFFS_ERR_CONFLICTING_NAME; + } + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - res = spiffs_fd_find_new(fs, &fd, 0); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + res = spiffs_fd_find_new(fs, &fd, 0); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - res = spiffs_object_open_by_page(fs, pix_old, fd, 0, 0); - if (res != SPIFFS_OK) { - spiffs_fd_return(fs, fd->file_nbr); - } - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + res = spiffs_object_open_by_page(fs, pix_old, fd, 0, 0); + if (res != SPIFFS_OK) { + spiffs_fd_return(fs, fd->file_nbr); + } + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, fd->objix_hdr_pix, 0, (const u8_t*)new_path, - 0, 0, &pix_dummy); + res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, fd->objix_hdr_pix, 0, (const u8_t *)new_path, + 0, 0, &pix_dummy); #if SPIFFS_TEMPORAL_FD_CACHE - if (res == SPIFFS_OK) { - spiffs_fd_temporal_cache_rehash(fs, old_path, new_path); - } + if (res == SPIFFS_OK) { + spiffs_fd_temporal_cache_rehash(fs, old_path, new_path); + } #endif - spiffs_fd_return(fs, fd->file_nbr); + spiffs_fd_return(fs, fd->file_nbr); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - SPIFFS_UNLOCK(fs); + SPIFFS_UNLOCK(fs); - return res; + return res; #endif // SPIFFS_READ_ONLY } #if SPIFFS_OBJ_META_LEN s32_t SPIFFS_update_meta(spiffs *fs, const char *name, const void *meta) { #if SPIFFS_READ_ONLY - (void)fs; (void)name; (void)meta; - return SPIFFS_ERR_RO_NOT_IMPL; + (void)fs; + (void)name; + (void)meta; + return SPIFFS_ERR_RO_NOT_IMPL; #else - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - SPIFFS_LOCK(fs); + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + SPIFFS_LOCK(fs); - spiffs_page_ix pix, pix_dummy; - spiffs_fd *fd; + spiffs_page_ix pix, pix_dummy; + spiffs_fd *fd; - s32_t res = spiffs_object_find_object_index_header_by_name(fs, (const u8_t*)name, &pix); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + s32_t res = spiffs_object_find_object_index_header_by_name(fs, (const u8_t *)name, &pix); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - res = spiffs_fd_find_new(fs, &fd, 0); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + res = spiffs_fd_find_new(fs, &fd, 0); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + + res = spiffs_object_open_by_page(fs, pix, fd, 0, 0); + if (res != SPIFFS_OK) { + spiffs_fd_return(fs, fd->file_nbr); + } + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + + res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, fd->objix_hdr_pix, 0, 0, meta, + 0, &pix_dummy); - res = spiffs_object_open_by_page(fs, pix, fd, 0, 0); - if (res != SPIFFS_OK) { spiffs_fd_return(fs, fd->file_nbr); - } - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, fd->objix_hdr_pix, 0, 0, meta, - 0, &pix_dummy); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - spiffs_fd_return(fs, fd->file_nbr); + SPIFFS_UNLOCK(fs); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - - SPIFFS_UNLOCK(fs); - - return res; + return res; #endif // SPIFFS_READ_ONLY } s32_t SPIFFS_fupdate_meta(spiffs *fs, spiffs_file fh, const void *meta) { #if SPIFFS_READ_ONLY - (void)fs; (void)fh; (void)meta; - return SPIFFS_ERR_RO_NOT_IMPL; + (void)fs; + (void)fh; + (void)meta; + return SPIFFS_ERR_RO_NOT_IMPL; #else - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - SPIFFS_LOCK(fs); + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + SPIFFS_LOCK(fs); - s32_t res; - spiffs_fd *fd; - spiffs_page_ix pix_dummy; + s32_t res; + spiffs_fd *fd; + spiffs_page_ix pix_dummy; - fh = SPIFFS_FH_UNOFFS(fs, fh); - res = spiffs_fd_get(fs, fh, &fd); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - - if ((fd->flags & SPIFFS_O_WRONLY) == 0) { - res = SPIFFS_ERR_NOT_WRITABLE; + fh = SPIFFS_FH_UNOFFS(fs, fh); + res = spiffs_fd_get(fs, fh, &fd); SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - } - res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, fd->objix_hdr_pix, 0, 0, meta, - 0, &pix_dummy); + if ((fd->flags & SPIFFS_O_WRONLY) == 0) { + res = SPIFFS_ERR_NOT_WRITABLE; + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + } - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, fd->objix_hdr_pix, 0, 0, meta, + 0, &pix_dummy); - SPIFFS_UNLOCK(fs); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - return res; + SPIFFS_UNLOCK(fs); + + return res; #endif // SPIFFS_READ_ONLY } #endif // SPIFFS_OBJ_META_LEN spiffs_DIR *SPIFFS_opendir(spiffs *fs, const char *name, spiffs_DIR *d) { - SPIFFS_API_DBG("%s\n", __func__); - (void)name; + SPIFFS_API_DBG("%s\n", __func__); + (void)name; - if (!SPIFFS_CHECK_CFG((fs))) { - (fs)->err_code = SPIFFS_ERR_NOT_CONFIGURED; - return 0; - } + if (!SPIFFS_CHECK_CFG((fs))) { + (fs)->err_code = SPIFFS_ERR_NOT_CONFIGURED; + return 0; + } - if (!SPIFFS_CHECK_MOUNT(fs)) { - fs->err_code = SPIFFS_ERR_NOT_MOUNTED; - return 0; - } + if (!SPIFFS_CHECK_MOUNT(fs)) { + fs->err_code = SPIFFS_ERR_NOT_MOUNTED; + return 0; + } - d->fs = fs; - d->block = 0; - d->entry = 0; - return d; + d->fs = fs; + d->block = 0; + d->entry = 0; + return d; } static s32_t spiffs_read_dir_v( @@ -1025,428 +1037,430 @@ static s32_t spiffs_read_dir_v( int ix_entry, const void *user_const_p, void *user_var_p) { - (void)user_const_p; - s32_t res; - spiffs_page_object_ix_header objix_hdr; - if (obj_id == SPIFFS_OBJ_ID_FREE || obj_id == SPIFFS_OBJ_ID_DELETED || - (obj_id & SPIFFS_OBJ_ID_IX_FLAG) == 0) { - return SPIFFS_VIS_COUNTINUE; - } + (void)user_const_p; + s32_t res; + spiffs_page_object_ix_header objix_hdr; + if (obj_id == SPIFFS_OBJ_ID_FREE || obj_id == SPIFFS_OBJ_ID_DELETED || + (obj_id & SPIFFS_OBJ_ID_IX_FLAG) == 0) { + return SPIFFS_VIS_COUNTINUE; + } - spiffs_page_ix pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, ix_entry); - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, - 0, SPIFFS_PAGE_TO_PADDR(fs, pix), sizeof(spiffs_page_object_ix_header), (u8_t *)&objix_hdr); - if (res != SPIFFS_OK) return res; - if ((obj_id & SPIFFS_OBJ_ID_IX_FLAG) && - objix_hdr.p_hdr.span_ix == 0 && - (objix_hdr.p_hdr.flags & (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_IXDELE)) == - (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_IXDELE)) { - struct spiffs_dirent *e = (struct spiffs_dirent*)user_var_p; - e->obj_id = obj_id; - strcpy((char *)e->name, (char *)objix_hdr.name); - e->type = objix_hdr.type; - e->size = objix_hdr.size == SPIFFS_UNDEFINED_LEN ? 0 : objix_hdr.size; - e->pix = pix; + spiffs_page_ix pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, ix_entry); + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, + 0, SPIFFS_PAGE_TO_PADDR(fs, pix), sizeof(spiffs_page_object_ix_header), (u8_t *)&objix_hdr); + if (res != SPIFFS_OK) return res; + if ((obj_id & SPIFFS_OBJ_ID_IX_FLAG) && + objix_hdr.p_hdr.span_ix == 0 && + (objix_hdr.p_hdr.flags & (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_IXDELE)) == + (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_IXDELE)) { + struct spiffs_dirent *e = (struct spiffs_dirent *)user_var_p; + e->obj_id = obj_id; + strcpy((char *)e->name, (char *)objix_hdr.name); + e->type = objix_hdr.type; + e->size = objix_hdr.size == SPIFFS_UNDEFINED_LEN ? 0 : objix_hdr.size; + e->pix = pix; #if SPIFFS_OBJ_META_LEN - _SPIFFS_MEMCPY(e->meta, objix_hdr.meta, SPIFFS_OBJ_META_LEN); + _SPIFFS_MEMCPY(e->meta, objix_hdr.meta, SPIFFS_OBJ_META_LEN); #endif - return SPIFFS_OK; - } - return SPIFFS_VIS_COUNTINUE; + return SPIFFS_OK; + } + return SPIFFS_VIS_COUNTINUE; } struct spiffs_dirent *SPIFFS_readdir(spiffs_DIR *d, struct spiffs_dirent *e) { - SPIFFS_API_DBG("%s\n", __func__); - if (!SPIFFS_CHECK_MOUNT(d->fs)) { - d->fs->err_code = SPIFFS_ERR_NOT_MOUNTED; - return 0; - } - SPIFFS_LOCK(d->fs); + SPIFFS_API_DBG("%s\n", __func__); + if (!SPIFFS_CHECK_MOUNT(d->fs)) { + d->fs->err_code = SPIFFS_ERR_NOT_MOUNTED; + return 0; + } + SPIFFS_LOCK(d->fs); - spiffs_block_ix bix; - int entry; - s32_t res; - struct spiffs_dirent *ret = 0; + spiffs_block_ix bix; + int entry; + s32_t res; + struct spiffs_dirent *ret = 0; - res = spiffs_obj_lu_find_entry_visitor(d->fs, - d->block, - d->entry, - SPIFFS_VIS_NO_WRAP, - 0, - spiffs_read_dir_v, - 0, - e, - &bix, - &entry); - if (res == SPIFFS_OK) { - d->block = bix; - d->entry = entry + 1; - e->obj_id &= ~SPIFFS_OBJ_ID_IX_FLAG; - ret = e; - } else { - d->fs->err_code = res; - } - SPIFFS_UNLOCK(d->fs); - return ret; + res = spiffs_obj_lu_find_entry_visitor(d->fs, + d->block, + d->entry, + SPIFFS_VIS_NO_WRAP, + 0, + spiffs_read_dir_v, + 0, + e, + &bix, + &entry); + if (res == SPIFFS_OK) { + d->block = bix; + d->entry = entry + 1; + e->obj_id &= ~SPIFFS_OBJ_ID_IX_FLAG; + ret = e; + } else { + d->fs->err_code = res; + } + SPIFFS_UNLOCK(d->fs); + return ret; } s32_t SPIFFS_closedir(spiffs_DIR *d) { - SPIFFS_API_DBG("%s\n", __func__); - SPIFFS_API_CHECK_CFG(d->fs); - SPIFFS_API_CHECK_MOUNT(d->fs); - return 0; + SPIFFS_API_DBG("%s\n", __func__); + SPIFFS_API_CHECK_CFG(d->fs); + SPIFFS_API_CHECK_MOUNT(d->fs); + return 0; } s32_t SPIFFS_check(spiffs *fs) { - SPIFFS_API_DBG("%s\n", __func__); + SPIFFS_API_DBG("%s\n", __func__); #if SPIFFS_READ_ONLY - (void)fs; - return SPIFFS_ERR_RO_NOT_IMPL; + (void)fs; + return SPIFFS_ERR_RO_NOT_IMPL; #else - s32_t res; - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - SPIFFS_LOCK(fs); + s32_t res; + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + SPIFFS_LOCK(fs); - res = spiffs_lookup_consistency_check(fs, 0); + res = spiffs_lookup_consistency_check(fs, 0); - res = spiffs_object_index_consistency_check(fs); + res = spiffs_object_index_consistency_check(fs); - res = spiffs_page_consistency_check(fs); + res = spiffs_page_consistency_check(fs); - res = spiffs_obj_lu_scan(fs); + res = spiffs_obj_lu_scan(fs); - SPIFFS_UNLOCK(fs); - return res; + SPIFFS_UNLOCK(fs); + return res; #endif // SPIFFS_READ_ONLY } s32_t SPIFFS_info(spiffs *fs, u32_t *total, u32_t *used) { - SPIFFS_API_DBG("%s\n", __func__); - s32_t res = SPIFFS_OK; - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - SPIFFS_LOCK(fs); + SPIFFS_API_DBG("%s\n", __func__); + s32_t res = SPIFFS_OK; + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + SPIFFS_LOCK(fs); - u32_t pages_per_block = SPIFFS_PAGES_PER_BLOCK(fs); - u32_t blocks = fs->block_count; - u32_t obj_lu_pages = SPIFFS_OBJ_LOOKUP_PAGES(fs); - u32_t data_page_size = SPIFFS_DATA_PAGE_SIZE(fs); - u32_t total_data_pages = (blocks - 2) * (pages_per_block - obj_lu_pages) + 1; // -2 for spare blocks, +1 for emergency page + u32_t pages_per_block = SPIFFS_PAGES_PER_BLOCK(fs); + u32_t blocks = fs->block_count; + u32_t obj_lu_pages = SPIFFS_OBJ_LOOKUP_PAGES(fs); + u32_t data_page_size = SPIFFS_DATA_PAGE_SIZE(fs); + u32_t total_data_pages = (blocks - 2) * (pages_per_block - obj_lu_pages) + 1; // -2 for spare blocks, +1 for emergency page - if (total) { - *total = total_data_pages * data_page_size; - } + if (total) { + *total = total_data_pages * data_page_size; + } - if (used) { - *used = fs->stats_p_allocated * data_page_size; - } + if (used) { + *used = fs->stats_p_allocated * data_page_size; + } - SPIFFS_UNLOCK(fs); - return res; + SPIFFS_UNLOCK(fs); + return res; } s32_t SPIFFS_gc_quick(spiffs *fs, u16_t max_free_pages) { - SPIFFS_API_DBG("%s "_SPIPRIi "\n", __func__, max_free_pages); + SPIFFS_API_DBG("%s "_SPIPRIi "\n", __func__, max_free_pages); #if SPIFFS_READ_ONLY - (void)fs; (void)max_free_pages; - return SPIFFS_ERR_RO_NOT_IMPL; + (void)fs; + (void)max_free_pages; + return SPIFFS_ERR_RO_NOT_IMPL; #else - s32_t res; - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - SPIFFS_LOCK(fs); + s32_t res; + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + SPIFFS_LOCK(fs); - res = spiffs_gc_quick(fs, max_free_pages); + res = spiffs_gc_quick(fs, max_free_pages); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - SPIFFS_UNLOCK(fs); - return 0; + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + SPIFFS_UNLOCK(fs); + return 0; #endif // SPIFFS_READ_ONLY } s32_t SPIFFS_gc(spiffs *fs, u32_t size) { - SPIFFS_API_DBG("%s "_SPIPRIi "\n", __func__, size); + SPIFFS_API_DBG("%s "_SPIPRIi "\n", __func__, size); #if SPIFFS_READ_ONLY - (void)fs; (void)size; - return SPIFFS_ERR_RO_NOT_IMPL; + (void)fs; + (void)size; + return SPIFFS_ERR_RO_NOT_IMPL; #else - s32_t res; - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - SPIFFS_LOCK(fs); + s32_t res; + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + SPIFFS_LOCK(fs); - res = spiffs_gc_check(fs, size); + res = spiffs_gc_check(fs, size); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - SPIFFS_UNLOCK(fs); - return 0; + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + SPIFFS_UNLOCK(fs); + return 0; #endif // SPIFFS_READ_ONLY } s32_t SPIFFS_eof(spiffs *fs, spiffs_file fh) { - SPIFFS_API_DBG("%s "_SPIPRIfd "\n", __func__, fh); - s32_t res; - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - SPIFFS_LOCK(fs); + SPIFFS_API_DBG("%s "_SPIPRIfd "\n", __func__, fh); + s32_t res; + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + SPIFFS_LOCK(fs); - fh = SPIFFS_FH_UNOFFS(fs, fh); + fh = SPIFFS_FH_UNOFFS(fs, fh); - spiffs_fd *fd; - res = spiffs_fd_get(fs, fh, &fd); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + spiffs_fd *fd; + res = spiffs_fd_get(fs, fh, &fd); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); #if SPIFFS_CACHE_WR - res = spiffs_fflush_cache(fs, fh); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + res = spiffs_fflush_cache(fs, fh); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); #endif - res = (fd->fdoffset >= (fd->size == SPIFFS_UNDEFINED_LEN ? 0 : fd->size)); + res = (fd->fdoffset >= (fd->size == SPIFFS_UNDEFINED_LEN ? 0 : fd->size)); - SPIFFS_UNLOCK(fs); - return res; + SPIFFS_UNLOCK(fs); + return res; } s32_t SPIFFS_tell(spiffs *fs, spiffs_file fh) { - SPIFFS_API_DBG("%s "_SPIPRIfd "\n", __func__, fh); - s32_t res; - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - SPIFFS_LOCK(fs); + SPIFFS_API_DBG("%s "_SPIPRIfd "\n", __func__, fh); + s32_t res; + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + SPIFFS_LOCK(fs); - fh = SPIFFS_FH_UNOFFS(fs, fh); + fh = SPIFFS_FH_UNOFFS(fs, fh); - spiffs_fd *fd; - res = spiffs_fd_get(fs, fh, &fd); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + spiffs_fd *fd; + res = spiffs_fd_get(fs, fh, &fd); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); #if SPIFFS_CACHE_WR - res = spiffs_fflush_cache(fs, fh); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + res = spiffs_fflush_cache(fs, fh); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); #endif - res = fd->fdoffset; + res = fd->fdoffset; - SPIFFS_UNLOCK(fs); - return res; + SPIFFS_UNLOCK(fs); + return res; } s32_t SPIFFS_set_file_callback_func(spiffs *fs, spiffs_file_callback cb_func) { - SPIFFS_API_DBG("%s\n", __func__); - SPIFFS_LOCK(fs); - fs->file_cb_f = cb_func; - SPIFFS_UNLOCK(fs); - return 0; + SPIFFS_API_DBG("%s\n", __func__); + SPIFFS_LOCK(fs); + fs->file_cb_f = cb_func; + SPIFFS_UNLOCK(fs); + return 0; } #if SPIFFS_IX_MAP s32_t SPIFFS_ix_map(spiffs *fs, spiffs_file fh, spiffs_ix_map *map, - u32_t offset, u32_t len, spiffs_page_ix *map_buf) { - SPIFFS_API_DBG("%s "_SPIPRIfd " "_SPIPRIi " "_SPIPRIi "\n", __func__, fh, offset, len); - s32_t res; - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - SPIFFS_LOCK(fs); + u32_t offset, u32_t len, spiffs_page_ix *map_buf) { + SPIFFS_API_DBG("%s "_SPIPRIfd " "_SPIPRIi " "_SPIPRIi "\n", __func__, fh, offset, len); + s32_t res; + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + SPIFFS_LOCK(fs); - fh = SPIFFS_FH_UNOFFS(fs, fh); + fh = SPIFFS_FH_UNOFFS(fs, fh); - spiffs_fd *fd; - res = spiffs_fd_get(fs, fh, &fd); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + spiffs_fd *fd; + res = spiffs_fd_get(fs, fh, &fd); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - if (fd->ix_map) { - SPIFFS_API_CHECK_RES_UNLOCK(fs, SPIFFS_ERR_IX_MAP_MAPPED); - } + if (fd->ix_map) { + SPIFFS_API_CHECK_RES_UNLOCK(fs, SPIFFS_ERR_IX_MAP_MAPPED); + } - map->map_buf = map_buf; - map->offset = offset; - // nb: spix range includes last - map->start_spix = offset / SPIFFS_DATA_PAGE_SIZE(fs); - map->end_spix = (offset + len) / SPIFFS_DATA_PAGE_SIZE(fs); - memset(map_buf, 0, sizeof(spiffs_page_ix) * (map->end_spix - map->start_spix + 1)); - fd->ix_map = map; + map->map_buf = map_buf; + map->offset = offset; + // nb: spix range includes last + map->start_spix = offset / SPIFFS_DATA_PAGE_SIZE(fs); + map->end_spix = (offset + len) / SPIFFS_DATA_PAGE_SIZE(fs); + memset(map_buf, 0, sizeof(spiffs_page_ix) * (map->end_spix - map->start_spix + 1)); + fd->ix_map = map; - // scan for pixes - res = spiffs_populate_ix_map(fs, fd, 0, map->end_spix - map->start_spix + 1); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + // scan for pixes + res = spiffs_populate_ix_map(fs, fd, 0, map->end_spix - map->start_spix + 1); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - SPIFFS_UNLOCK(fs); - return res; + SPIFFS_UNLOCK(fs); + return res; } s32_t SPIFFS_ix_unmap(spiffs *fs, spiffs_file fh) { - SPIFFS_API_DBG("%s "_SPIPRIfd "\n", __func__, fh); - s32_t res; - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - SPIFFS_LOCK(fs); + SPIFFS_API_DBG("%s "_SPIPRIfd "\n", __func__, fh); + s32_t res; + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + SPIFFS_LOCK(fs); - fh = SPIFFS_FH_UNOFFS(fs, fh); + fh = SPIFFS_FH_UNOFFS(fs, fh); - spiffs_fd *fd; - res = spiffs_fd_get(fs, fh, &fd); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + spiffs_fd *fd; + res = spiffs_fd_get(fs, fh, &fd); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - if (fd->ix_map == 0) { - SPIFFS_API_CHECK_RES_UNLOCK(fs, SPIFFS_ERR_IX_MAP_UNMAPPED); - } + if (fd->ix_map == 0) { + SPIFFS_API_CHECK_RES_UNLOCK(fs, SPIFFS_ERR_IX_MAP_UNMAPPED); + } - fd->ix_map = 0; + fd->ix_map = 0; - SPIFFS_UNLOCK(fs); - return res; + SPIFFS_UNLOCK(fs); + return res; } s32_t SPIFFS_ix_remap(spiffs *fs, spiffs_file fh, u32_t offset) { - SPIFFS_API_DBG("%s "_SPIPRIfd " "_SPIPRIi "\n", __func__, fh, offset); - s32_t res = SPIFFS_OK; - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - SPIFFS_LOCK(fs); + SPIFFS_API_DBG("%s "_SPIPRIfd " "_SPIPRIi "\n", __func__, fh, offset); + s32_t res = SPIFFS_OK; + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + SPIFFS_LOCK(fs); - fh = SPIFFS_FH_UNOFFS(fs, fh); + fh = SPIFFS_FH_UNOFFS(fs, fh); - spiffs_fd *fd; - res = spiffs_fd_get(fs, fh, &fd); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + spiffs_fd *fd; + res = spiffs_fd_get(fs, fh, &fd); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - if (fd->ix_map == 0) { - SPIFFS_API_CHECK_RES_UNLOCK(fs, SPIFFS_ERR_IX_MAP_UNMAPPED); - } - - spiffs_ix_map *map = fd->ix_map; - - s32_t spix_diff = offset / SPIFFS_DATA_PAGE_SIZE(fs) - map->start_spix; - map->offset = offset; - - // move existing pixes if within map offs - if (spix_diff != 0) { - // move vector - int i; - const s32_t vec_len = map->end_spix - map->start_spix + 1; // spix range includes last - map->start_spix += spix_diff; - map->end_spix += spix_diff; - if (spix_diff >= vec_len) { - // moving beyond range - memset(&map->map_buf, 0, vec_len * sizeof(spiffs_page_ix)); - // populate_ix_map is inclusive - res = spiffs_populate_ix_map(fs, fd, 0, vec_len-1); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - } else if (spix_diff > 0) { - // diff positive - for (i = 0; i < vec_len - spix_diff; i++) { - map->map_buf[i] = map->map_buf[i + spix_diff]; - } - // memset is non-inclusive - memset(&map->map_buf[vec_len - spix_diff], 0, spix_diff * sizeof(spiffs_page_ix)); - // populate_ix_map is inclusive - res = spiffs_populate_ix_map(fs, fd, vec_len - spix_diff, vec_len-1); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - } else { - // diff negative - for (i = vec_len - 1; i >= -spix_diff; i--) { - map->map_buf[i] = map->map_buf[i + spix_diff]; - } - // memset is non-inclusive - memset(&map->map_buf[0], 0, -spix_diff * sizeof(spiffs_page_ix)); - // populate_ix_map is inclusive - res = spiffs_populate_ix_map(fs, fd, 0, -spix_diff - 1); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + if (fd->ix_map == 0) { + SPIFFS_API_CHECK_RES_UNLOCK(fs, SPIFFS_ERR_IX_MAP_UNMAPPED); } - } + spiffs_ix_map *map = fd->ix_map; - SPIFFS_UNLOCK(fs); - return res; + s32_t spix_diff = offset / SPIFFS_DATA_PAGE_SIZE(fs) - map->start_spix; + map->offset = offset; + + // move existing pixes if within map offs + if (spix_diff != 0) { + // move vector + int i; + const s32_t vec_len = map->end_spix - map->start_spix + 1; // spix range includes last + map->start_spix += spix_diff; + map->end_spix += spix_diff; + if (spix_diff >= vec_len) { + // moving beyond range + memset(&map->map_buf, 0, vec_len * sizeof(spiffs_page_ix)); + // populate_ix_map is inclusive + res = spiffs_populate_ix_map(fs, fd, 0, vec_len - 1); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + } else if (spix_diff > 0) { + // diff positive + for (i = 0; i < vec_len - spix_diff; i++) { + map->map_buf[i] = map->map_buf[i + spix_diff]; + } + // memset is non-inclusive + memset(&map->map_buf[vec_len - spix_diff], 0, spix_diff * sizeof(spiffs_page_ix)); + // populate_ix_map is inclusive + res = spiffs_populate_ix_map(fs, fd, vec_len - spix_diff, vec_len - 1); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + } else { + // diff negative + for (i = vec_len - 1; i >= -spix_diff; i--) { + map->map_buf[i] = map->map_buf[i + spix_diff]; + } + // memset is non-inclusive + memset(&map->map_buf[0], 0, -spix_diff * sizeof(spiffs_page_ix)); + // populate_ix_map is inclusive + res = spiffs_populate_ix_map(fs, fd, 0, -spix_diff - 1); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + } + + } + + SPIFFS_UNLOCK(fs); + return res; } s32_t SPIFFS_bytes_to_ix_map_entries(spiffs *fs, u32_t bytes) { - SPIFFS_API_CHECK_CFG(fs); - // always add one extra page, the offset might change to the middle of a page - return (bytes + SPIFFS_DATA_PAGE_SIZE(fs) ) / SPIFFS_DATA_PAGE_SIZE(fs); + SPIFFS_API_CHECK_CFG(fs); + // always add one extra page, the offset might change to the middle of a page + return (bytes + SPIFFS_DATA_PAGE_SIZE(fs)) / SPIFFS_DATA_PAGE_SIZE(fs); } s32_t SPIFFS_ix_map_entries_to_bytes(spiffs *fs, u32_t map_page_ix_entries) { - SPIFFS_API_CHECK_CFG(fs); - return map_page_ix_entries * SPIFFS_DATA_PAGE_SIZE(fs); + SPIFFS_API_CHECK_CFG(fs); + return map_page_ix_entries * SPIFFS_DATA_PAGE_SIZE(fs); } #endif // SPIFFS_IX_MAP #if SPIFFS_TEST_VISUALISATION s32_t SPIFFS_vis(spiffs *fs) { - s32_t res = SPIFFS_OK; - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - SPIFFS_LOCK(fs); + s32_t res = SPIFFS_OK; + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + SPIFFS_LOCK(fs); - int entries_per_page = (SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id)); - spiffs_obj_id *obj_lu_buf = (spiffs_obj_id *)fs->lu_work; - spiffs_block_ix bix = 0; + int entries_per_page = (SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id)); + spiffs_obj_id *obj_lu_buf = (spiffs_obj_id *)fs->lu_work; + spiffs_block_ix bix = 0; - while (bix < fs->block_count) { - // check each object lookup page - int obj_lookup_page = 0; - int cur_entry = 0; + while (bix < fs->block_count) { + // check each object lookup page + int obj_lookup_page = 0; + int cur_entry = 0; - while (res == SPIFFS_OK && obj_lookup_page < (int)SPIFFS_OBJ_LOOKUP_PAGES(fs)) { - int entry_offset = obj_lookup_page * entries_per_page; - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, - 0, bix * SPIFFS_CFG_LOG_BLOCK_SZ(fs) + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); - // check each entry - while (res == SPIFFS_OK && - cur_entry - entry_offset < entries_per_page && cur_entry < (int)(SPIFFS_PAGES_PER_BLOCK(fs)-SPIFFS_OBJ_LOOKUP_PAGES(fs))) { - spiffs_obj_id obj_id = obj_lu_buf[cur_entry-entry_offset]; - if (cur_entry == 0) { - spiffs_printf(_SPIPRIbl" ", bix); - } else if ((cur_entry & 0x3f) == 0) { - spiffs_printf(" "); - } - if (obj_id == SPIFFS_OBJ_ID_FREE) { - spiffs_printf(SPIFFS_TEST_VIS_FREE_STR); - } else if (obj_id == SPIFFS_OBJ_ID_DELETED) { - spiffs_printf(SPIFFS_TEST_VIS_DELE_STR); - } else if (obj_id & SPIFFS_OBJ_ID_IX_FLAG){ - spiffs_printf(SPIFFS_TEST_VIS_INDX_STR(obj_id)); + while (res == SPIFFS_OK && obj_lookup_page < (int)SPIFFS_OBJ_LOOKUP_PAGES(fs)) { + int entry_offset = obj_lookup_page * entries_per_page; + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, + 0, bix * SPIFFS_CFG_LOG_BLOCK_SZ(fs) + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); + // check each entry + while (res == SPIFFS_OK && + cur_entry - entry_offset < entries_per_page && cur_entry < (int)(SPIFFS_PAGES_PER_BLOCK(fs) - SPIFFS_OBJ_LOOKUP_PAGES(fs))) { + spiffs_obj_id obj_id = obj_lu_buf[cur_entry - entry_offset]; + if (cur_entry == 0) { + spiffs_printf(_SPIPRIbl" ", bix); + } else if ((cur_entry & 0x3f) == 0) { + spiffs_printf(" "); + } + if (obj_id == SPIFFS_OBJ_ID_FREE) { + spiffs_printf(SPIFFS_TEST_VIS_FREE_STR); + } else if (obj_id == SPIFFS_OBJ_ID_DELETED) { + spiffs_printf(SPIFFS_TEST_VIS_DELE_STR); + } else if (obj_id & SPIFFS_OBJ_ID_IX_FLAG) { + spiffs_printf(SPIFFS_TEST_VIS_INDX_STR(obj_id)); + } else { + spiffs_printf(SPIFFS_TEST_VIS_DATA_STR(obj_id)); + } + cur_entry++; + if ((cur_entry & 0x3f) == 0) { + spiffs_printf("\n"); + } + } // per entry + obj_lookup_page++; + } // per object lookup page + + spiffs_obj_id erase_count; + res = _spiffs_rd(fs, SPIFFS_OP_C_READ | SPIFFS_OP_T_OBJ_LU2, 0, + SPIFFS_ERASE_COUNT_PADDR(fs, bix), + sizeof(spiffs_obj_id), (u8_t *)&erase_count); + SPIFFS_CHECK_RES(res); + + if (erase_count != (spiffs_obj_id) - 1) { + spiffs_printf("\tera_cnt: "_SPIPRIi"\n", erase_count); } else { - spiffs_printf(SPIFFS_TEST_VIS_DATA_STR(obj_id)); + spiffs_printf("\tera_cnt: N/A\n"); } - cur_entry++; - if ((cur_entry & 0x3f) == 0) { - spiffs_printf("\n"); - } - } // per entry - obj_lookup_page++; - } // per object lookup page - spiffs_obj_id erase_count; - res = _spiffs_rd(fs, SPIFFS_OP_C_READ | SPIFFS_OP_T_OBJ_LU2, 0, - SPIFFS_ERASE_COUNT_PADDR(fs, bix), - sizeof(spiffs_obj_id), (u8_t *)&erase_count); - SPIFFS_CHECK_RES(res); + bix++; + } // per block - if (erase_count != (spiffs_obj_id)-1) { - spiffs_printf("\tera_cnt: "_SPIPRIi"\n", erase_count); - } else { - spiffs_printf("\tera_cnt: N/A\n"); - } - - bix++; - } // per block - - spiffs_printf("era_cnt_max: "_SPIPRIi"\n", fs->max_erase_count); - spiffs_printf("last_errno: "_SPIPRIi"\n", fs->err_code); - spiffs_printf("blocks: "_SPIPRIi"\n", fs->block_count); - spiffs_printf("free_blocks: "_SPIPRIi"\n", fs->free_blocks); - spiffs_printf("page_alloc: "_SPIPRIi"\n", fs->stats_p_allocated); - spiffs_printf("page_delet: "_SPIPRIi"\n", fs->stats_p_deleted); - SPIFFS_UNLOCK(fs); - u32_t total, used; - SPIFFS_info(fs, &total, &used); - spiffs_printf("used: "_SPIPRIi" of "_SPIPRIi"\n", used, total); - return res; + spiffs_printf("era_cnt_max: "_SPIPRIi"\n", fs->max_erase_count); + spiffs_printf("last_errno: "_SPIPRIi"\n", fs->err_code); + spiffs_printf("blocks: "_SPIPRIi"\n", fs->block_count); + spiffs_printf("free_blocks: "_SPIPRIi"\n", fs->free_blocks); + spiffs_printf("page_alloc: "_SPIPRIi"\n", fs->stats_p_allocated); + spiffs_printf("page_delet: "_SPIPRIi"\n", fs->stats_p_deleted); + SPIFFS_UNLOCK(fs); + u32_t total, used; + SPIFFS_info(fs, &total, &used); + spiffs_printf("used: "_SPIPRIi" of "_SPIPRIi"\n", used, total); + return res; } #endif diff --git a/armsrc/spiffs_nucleus.c b/armsrc/spiffs_nucleus.c index 1c913921b..7951a7952 100644 --- a/armsrc/spiffs_nucleus.c +++ b/armsrc/spiffs_nucleus.c @@ -3,60 +3,60 @@ #include "printf.h" static s32_t spiffs_page_data_check(spiffs *fs, spiffs_fd *fd, spiffs_page_ix pix, spiffs_span_ix spix) { - s32_t res = SPIFFS_OK; - if (pix == (spiffs_page_ix)-1) { - // referring to page 0xffff...., bad object index - return SPIFFS_ERR_INDEX_REF_FREE; - } - if (pix % SPIFFS_PAGES_PER_BLOCK(fs) < SPIFFS_OBJ_LOOKUP_PAGES(fs)) { - // referring to an object lookup page, bad object index - return SPIFFS_ERR_INDEX_REF_LU; - } - if (pix > SPIFFS_MAX_PAGES(fs)) { - // referring to a bad page - return SPIFFS_ERR_INDEX_REF_INVALID; - } + s32_t res = SPIFFS_OK; + if (pix == (spiffs_page_ix) - 1) { + // referring to page 0xffff...., bad object index + return SPIFFS_ERR_INDEX_REF_FREE; + } + if (pix % SPIFFS_PAGES_PER_BLOCK(fs) < SPIFFS_OBJ_LOOKUP_PAGES(fs)) { + // referring to an object lookup page, bad object index + return SPIFFS_ERR_INDEX_REF_LU; + } + if (pix > SPIFFS_MAX_PAGES(fs)) { + // referring to a bad page + return SPIFFS_ERR_INDEX_REF_INVALID; + } #if SPIFFS_PAGE_CHECK - spiffs_page_header ph; - res = _spiffs_rd( - fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_READ, - fd->file_nbr, - SPIFFS_PAGE_TO_PADDR(fs, pix), - sizeof(spiffs_page_header), - (u8_t *)&ph); - SPIFFS_CHECK_RES(res); - SPIFFS_VALIDATE_DATA(ph, fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, spix); + spiffs_page_header ph; + res = _spiffs_rd( + fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_READ, + fd->file_nbr, + SPIFFS_PAGE_TO_PADDR(fs, pix), + sizeof(spiffs_page_header), + (u8_t *)&ph); + SPIFFS_CHECK_RES(res); + SPIFFS_VALIDATE_DATA(ph, fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, spix); #endif - return res; + return res; } #if !SPIFFS_READ_ONLY static s32_t spiffs_page_index_check(spiffs *fs, spiffs_fd *fd, spiffs_page_ix pix, spiffs_span_ix spix) { - s32_t res = SPIFFS_OK; - if (pix == (spiffs_page_ix)-1) { - // referring to page 0xffff...., bad object index - return SPIFFS_ERR_INDEX_FREE; - } - if (pix % SPIFFS_PAGES_PER_BLOCK(fs) < SPIFFS_OBJ_LOOKUP_PAGES(fs)) { - // referring to an object lookup page, bad object index - return SPIFFS_ERR_INDEX_LU; - } - if (pix > SPIFFS_MAX_PAGES(fs)) { - // referring to a bad page - return SPIFFS_ERR_INDEX_INVALID; - } + s32_t res = SPIFFS_OK; + if (pix == (spiffs_page_ix) - 1) { + // referring to page 0xffff...., bad object index + return SPIFFS_ERR_INDEX_FREE; + } + if (pix % SPIFFS_PAGES_PER_BLOCK(fs) < SPIFFS_OBJ_LOOKUP_PAGES(fs)) { + // referring to an object lookup page, bad object index + return SPIFFS_ERR_INDEX_LU; + } + if (pix > SPIFFS_MAX_PAGES(fs)) { + // referring to a bad page + return SPIFFS_ERR_INDEX_INVALID; + } #if SPIFFS_PAGE_CHECK - spiffs_page_header ph; - res = _spiffs_rd( - fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, - fd->file_nbr, - SPIFFS_PAGE_TO_PADDR(fs, pix), - sizeof(spiffs_page_header), - (u8_t *)&ph); - SPIFFS_CHECK_RES(res); - SPIFFS_VALIDATE_OBJIX(ph, fd->obj_id, spix); + spiffs_page_header ph; + res = _spiffs_rd( + fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, + fd->file_nbr, + SPIFFS_PAGE_TO_PADDR(fs, pix), + sizeof(spiffs_page_header), + (u8_t *)&ph); + SPIFFS_CHECK_RES(res); + SPIFFS_VALIDATE_OBJIX(ph, fd->obj_id, spix); #endif - return res; + return res; } #endif // !SPIFFS_READ_ONLY @@ -67,7 +67,7 @@ s32_t spiffs_phys_rd( u32_t addr, u32_t len, u8_t *dst) { - return SPIFFS_HAL_READ(fs, addr, len, dst); + return SPIFFS_HAL_READ(fs, addr, len, dst); } s32_t spiffs_phys_wr( @@ -75,7 +75,7 @@ s32_t spiffs_phys_wr( u32_t addr, u32_t len, u8_t *src) { - return SPIFFS_HAL_WRITE(fs, addr, len, src); + return SPIFFS_HAL_WRITE(fs, addr, len, src); } #endif @@ -87,20 +87,20 @@ s32_t spiffs_phys_cpy( u32_t dst, u32_t src, u32_t len) { - (void)fh; - s32_t res; - u8_t b[SPIFFS_COPY_BUFFER_STACK]; - while (len > 0) { - u32_t chunk_size = MIN(SPIFFS_COPY_BUFFER_STACK, len); - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_MOVS, fh, src, chunk_size, b); - SPIFFS_CHECK_RES(res); - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_MOVD, fh, dst, chunk_size, b); - SPIFFS_CHECK_RES(res); - len -= chunk_size; - src += chunk_size; - dst += chunk_size; - } - return SPIFFS_OK; + (void)fh; + s32_t res; + u8_t b[SPIFFS_COPY_BUFFER_STACK]; + while (len > 0) { + u32_t chunk_size = MIN(SPIFFS_COPY_BUFFER_STACK, len); + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_MOVS, fh, src, chunk_size, b); + SPIFFS_CHECK_RES(res); + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_MOVD, fh, dst, chunk_size, b); + SPIFFS_CHECK_RES(res); + len -= chunk_size; + src += chunk_size; + dst += chunk_size; + } + return SPIFFS_OK; } #endif // !SPIFFS_READ_ONLY @@ -133,187 +133,186 @@ s32_t spiffs_obj_lu_find_entry_visitor( void *user_var_p, spiffs_block_ix *block_ix, int *lu_entry) { - s32_t res = SPIFFS_OK; - s32_t entry_count = fs->block_count * SPIFFS_OBJ_LOOKUP_MAX_ENTRIES(fs); - spiffs_block_ix cur_block = starting_block; - u32_t cur_block_addr = starting_block * SPIFFS_CFG_LOG_BLOCK_SZ(fs); + s32_t res = SPIFFS_OK; + s32_t entry_count = fs->block_count * SPIFFS_OBJ_LOOKUP_MAX_ENTRIES(fs); + spiffs_block_ix cur_block = starting_block; + u32_t cur_block_addr = starting_block * SPIFFS_CFG_LOG_BLOCK_SZ(fs); - spiffs_obj_id *obj_lu_buf = (spiffs_obj_id *)fs->lu_work; - int cur_entry = starting_lu_entry; - int entries_per_page = (SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id)); + spiffs_obj_id *obj_lu_buf = (spiffs_obj_id *)fs->lu_work; + int cur_entry = starting_lu_entry; + int entries_per_page = (SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id)); - // wrap initial - if (cur_entry > (int)SPIFFS_OBJ_LOOKUP_MAX_ENTRIES(fs) - 1) { - cur_entry = 0; - cur_block++; - cur_block_addr = cur_block * SPIFFS_CFG_LOG_BLOCK_SZ(fs); - if (cur_block >= fs->block_count) { - if (flags & SPIFFS_VIS_NO_WRAP) { - return SPIFFS_VIS_END; - } else { - // block wrap - cur_block = 0; - cur_block_addr = 0; - } - } - } - - // check each block - while (res == SPIFFS_OK && entry_count > 0) { - int obj_lookup_page = cur_entry / entries_per_page; - // check each object lookup page - while (res == SPIFFS_OK && obj_lookup_page < (int)SPIFFS_OBJ_LOOKUP_PAGES(fs)) { - int entry_offset = obj_lookup_page * entries_per_page; - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, - 0, cur_block_addr + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); - // check each entry - while (res == SPIFFS_OK && - cur_entry - entry_offset < entries_per_page && // for non-last obj lookup pages - cur_entry < (int)SPIFFS_OBJ_LOOKUP_MAX_ENTRIES(fs)) // for last obj lookup page - { - if ((flags & SPIFFS_VIS_CHECK_ID) == 0 || obj_lu_buf[cur_entry-entry_offset] == obj_id) { - if (block_ix) *block_ix = cur_block; - if (lu_entry) *lu_entry = cur_entry; - if (v) { - res = v( - fs, - (flags & SPIFFS_VIS_CHECK_PH) ? obj_id : obj_lu_buf[cur_entry-entry_offset], - cur_block, - cur_entry, - user_const_p, - user_var_p); - if (res == SPIFFS_VIS_COUNTINUE || res == SPIFFS_VIS_COUNTINUE_RELOAD) { - if (res == SPIFFS_VIS_COUNTINUE_RELOAD) { - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, - 0, cur_block_addr + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); - SPIFFS_CHECK_RES(res); - } - res = SPIFFS_OK; - cur_entry++; - entry_count--; - continue; + // wrap initial + if (cur_entry > (int)SPIFFS_OBJ_LOOKUP_MAX_ENTRIES(fs) - 1) { + cur_entry = 0; + cur_block++; + cur_block_addr = cur_block * SPIFFS_CFG_LOG_BLOCK_SZ(fs); + if (cur_block >= fs->block_count) { + if (flags & SPIFFS_VIS_NO_WRAP) { + return SPIFFS_VIS_END; } else { - return res; + // block wrap + cur_block = 0; + cur_block_addr = 0; } - } else { - return SPIFFS_OK; - } } - entry_count--; - cur_entry++; - } // per entry - obj_lookup_page++; - } // per object lookup page - cur_entry = 0; - cur_block++; - cur_block_addr += SPIFFS_CFG_LOG_BLOCK_SZ(fs); - if (cur_block >= fs->block_count) { - if (flags & SPIFFS_VIS_NO_WRAP) { - return SPIFFS_VIS_END; - } else { - // block wrap - cur_block = 0; - cur_block_addr = 0; - } } - } // per block - SPIFFS_CHECK_RES(res); + // check each block + while (res == SPIFFS_OK && entry_count > 0) { + int obj_lookup_page = cur_entry / entries_per_page; + // check each object lookup page + while (res == SPIFFS_OK && obj_lookup_page < (int)SPIFFS_OBJ_LOOKUP_PAGES(fs)) { + int entry_offset = obj_lookup_page * entries_per_page; + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, + 0, cur_block_addr + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); + // check each entry + while (res == SPIFFS_OK && + cur_entry - entry_offset < entries_per_page && // for non-last obj lookup pages + cur_entry < (int)SPIFFS_OBJ_LOOKUP_MAX_ENTRIES(fs)) { // for last obj lookup page + if ((flags & SPIFFS_VIS_CHECK_ID) == 0 || obj_lu_buf[cur_entry - entry_offset] == obj_id) { + if (block_ix) *block_ix = cur_block; + if (lu_entry) *lu_entry = cur_entry; + if (v) { + res = v( + fs, + (flags & SPIFFS_VIS_CHECK_PH) ? obj_id : obj_lu_buf[cur_entry - entry_offset], + cur_block, + cur_entry, + user_const_p, + user_var_p); + if (res == SPIFFS_VIS_COUNTINUE || res == SPIFFS_VIS_COUNTINUE_RELOAD) { + if (res == SPIFFS_VIS_COUNTINUE_RELOAD) { + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, + 0, cur_block_addr + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); + SPIFFS_CHECK_RES(res); + } + res = SPIFFS_OK; + cur_entry++; + entry_count--; + continue; + } else { + return res; + } + } else { + return SPIFFS_OK; + } + } + entry_count--; + cur_entry++; + } // per entry + obj_lookup_page++; + } // per object lookup page + cur_entry = 0; + cur_block++; + cur_block_addr += SPIFFS_CFG_LOG_BLOCK_SZ(fs); + if (cur_block >= fs->block_count) { + if (flags & SPIFFS_VIS_NO_WRAP) { + return SPIFFS_VIS_END; + } else { + // block wrap + cur_block = 0; + cur_block_addr = 0; + } + } + } // per block - return SPIFFS_VIS_END; + SPIFFS_CHECK_RES(res); + + return SPIFFS_VIS_END; } #if !SPIFFS_READ_ONLY s32_t spiffs_erase_block( spiffs *fs, spiffs_block_ix bix) { - s32_t res; - u32_t addr = SPIFFS_BLOCK_TO_PADDR(fs, bix); - s32_t size = SPIFFS_CFG_LOG_BLOCK_SZ(fs); + s32_t res; + u32_t addr = SPIFFS_BLOCK_TO_PADDR(fs, bix); + s32_t size = SPIFFS_CFG_LOG_BLOCK_SZ(fs); - // here we ignore res, just try erasing the block - while (size > 0) { - SPIFFS_DBG("erase "_SPIPRIad":"_SPIPRIi"\n", addr, SPIFFS_CFG_PHYS_ERASE_SZ(fs)); - SPIFFS_HAL_ERASE(fs, addr, SPIFFS_CFG_PHYS_ERASE_SZ(fs)); + // here we ignore res, just try erasing the block + while (size > 0) { + SPIFFS_DBG("erase "_SPIPRIad":"_SPIPRIi"\n", addr, SPIFFS_CFG_PHYS_ERASE_SZ(fs)); + SPIFFS_HAL_ERASE(fs, addr, SPIFFS_CFG_PHYS_ERASE_SZ(fs)); - addr += SPIFFS_CFG_PHYS_ERASE_SZ(fs); - size -= SPIFFS_CFG_PHYS_ERASE_SZ(fs); - } - fs->free_blocks++; + addr += SPIFFS_CFG_PHYS_ERASE_SZ(fs); + size -= SPIFFS_CFG_PHYS_ERASE_SZ(fs); + } + fs->free_blocks++; - // register erase count for this block - res = _spiffs_wr(fs, SPIFFS_OP_C_WRTHRU | SPIFFS_OP_T_OBJ_LU2, 0, - SPIFFS_ERASE_COUNT_PADDR(fs, bix), - sizeof(spiffs_obj_id), (u8_t *)&fs->max_erase_count); - SPIFFS_CHECK_RES(res); + // register erase count for this block + res = _spiffs_wr(fs, SPIFFS_OP_C_WRTHRU | SPIFFS_OP_T_OBJ_LU2, 0, + SPIFFS_ERASE_COUNT_PADDR(fs, bix), + sizeof(spiffs_obj_id), (u8_t *)&fs->max_erase_count); + SPIFFS_CHECK_RES(res); #if SPIFFS_USE_MAGIC - // finally, write magic - spiffs_obj_id magic = SPIFFS_MAGIC(fs, bix); - res = _spiffs_wr(fs, SPIFFS_OP_C_WRTHRU | SPIFFS_OP_T_OBJ_LU2, 0, - SPIFFS_MAGIC_PADDR(fs, bix), - sizeof(spiffs_obj_id), (u8_t *)&magic); - SPIFFS_CHECK_RES(res); + // finally, write magic + spiffs_obj_id magic = SPIFFS_MAGIC(fs, bix); + res = _spiffs_wr(fs, SPIFFS_OP_C_WRTHRU | SPIFFS_OP_T_OBJ_LU2, 0, + SPIFFS_MAGIC_PADDR(fs, bix), + sizeof(spiffs_obj_id), (u8_t *)&magic); + SPIFFS_CHECK_RES(res); #endif - fs->max_erase_count++; - if (fs->max_erase_count == SPIFFS_OBJ_ID_IX_FLAG) { - fs->max_erase_count = 0; - } + fs->max_erase_count++; + if (fs->max_erase_count == SPIFFS_OBJ_ID_IX_FLAG) { + fs->max_erase_count = 0; + } - return res; + return res; } #endif // !SPIFFS_READ_ONLY #if SPIFFS_USE_MAGIC && SPIFFS_USE_MAGIC_LENGTH && SPIFFS_SINGLETON==0 s32_t spiffs_probe( spiffs_config *cfg) { - s32_t res; - u32_t paddr; - spiffs dummy_fs; // create a dummy fs struct just to be able to use macros - _SPIFFS_MEMCPY(&dummy_fs.cfg, cfg, sizeof(spiffs_config)); - dummy_fs.block_count = 0; + s32_t res; + u32_t paddr; + spiffs dummy_fs; // create a dummy fs struct just to be able to use macros + _SPIFFS_MEMCPY(&dummy_fs.cfg, cfg, sizeof(spiffs_config)); + dummy_fs.block_count = 0; - // Read three magics, as one block may be in an aborted erase state. - // At least two of these must contain magic and be in decreasing order. - spiffs_obj_id magic[3]; - spiffs_obj_id bix_count[3]; + // Read three magics, as one block may be in an aborted erase state. + // At least two of these must contain magic and be in decreasing order. + spiffs_obj_id magic[3]; + spiffs_obj_id bix_count[3]; - spiffs_block_ix bix; - for (bix = 0; bix < 3; bix++) { - paddr = SPIFFS_MAGIC_PADDR(&dummy_fs, bix); + spiffs_block_ix bix; + for (bix = 0; bix < 3; bix++) { + paddr = SPIFFS_MAGIC_PADDR(&dummy_fs, bix); #if SPIFFS_HAL_CALLBACK_EXTRA - // not any proper fs to report here, so callback with null - // (cross fingers that no-one gets angry) - res = cfg->hal_read_f((void *)0, paddr, sizeof(spiffs_obj_id), (u8_t *)&magic[bix]); + // not any proper fs to report here, so callback with null + // (cross fingers that no-one gets angry) + res = cfg->hal_read_f((void *)0, paddr, sizeof(spiffs_obj_id), (u8_t *)&magic[bix]); #else - res = cfg->hal_read_f(paddr, sizeof(spiffs_obj_id), (u8_t *)&magic[bix]); + res = cfg->hal_read_f(paddr, sizeof(spiffs_obj_id), (u8_t *)&magic[bix]); #endif - bix_count[bix] = magic[bix] ^ SPIFFS_MAGIC(&dummy_fs, 0); - SPIFFS_CHECK_RES(res); - } + bix_count[bix] = magic[bix] ^ SPIFFS_MAGIC(&dummy_fs, 0); + SPIFFS_CHECK_RES(res); + } - // check that we have sane number of blocks - if (bix_count[0] < 3) return SPIFFS_ERR_PROBE_TOO_FEW_BLOCKS; - // check that the order is correct, take aborted erases in calculation - // first block aborted erase - if (magic[0] == (spiffs_obj_id)(-1) && bix_count[1] - bix_count[2] == 1) { - return (bix_count[1]+1) * cfg->log_block_size; - } - // second block aborted erase - if (magic[1] == (spiffs_obj_id)(-1) && bix_count[0] - bix_count[2] == 2) { - return bix_count[0] * cfg->log_block_size; - } - // third block aborted erase - if (magic[2] == (spiffs_obj_id)(-1) && bix_count[0] - bix_count[1] == 1) { - return bix_count[0] * cfg->log_block_size; - } - // no block has aborted erase - if (bix_count[0] - bix_count[1] == 1 && bix_count[1] - bix_count[2] == 1) { - return bix_count[0] * cfg->log_block_size; - } + // check that we have sane number of blocks + if (bix_count[0] < 3) return SPIFFS_ERR_PROBE_TOO_FEW_BLOCKS; + // check that the order is correct, take aborted erases in calculation + // first block aborted erase + if (magic[0] == (spiffs_obj_id)(-1) && bix_count[1] - bix_count[2] == 1) { + return (bix_count[1] + 1) * cfg->log_block_size; + } + // second block aborted erase + if (magic[1] == (spiffs_obj_id)(-1) && bix_count[0] - bix_count[2] == 2) { + return bix_count[0] * cfg->log_block_size; + } + // third block aborted erase + if (magic[2] == (spiffs_obj_id)(-1) && bix_count[0] - bix_count[1] == 1) { + return bix_count[0] * cfg->log_block_size; + } + // no block has aborted erase + if (bix_count[0] - bix_count[1] == 1 && bix_count[1] - bix_count[2] == 1) { + return bix_count[0] * cfg->log_block_size; + } - return SPIFFS_ERR_PROBE_NOT_A_FS; + return SPIFFS_ERR_PROBE_NOT_A_FS; } #endif // SPIFFS_USE_MAGIC && SPIFFS_USE_MAGIC_LENGTH && SPIFFS_SINGLETON==0 @@ -325,21 +324,21 @@ static s32_t spiffs_obj_lu_scan_v( int ix_entry, const void *user_const_p, void *user_var_p) { - (void)bix; - (void)user_const_p; - (void)user_var_p; - if (obj_id == SPIFFS_OBJ_ID_FREE) { - if (ix_entry == 0) { - fs->free_blocks++; - // todo optimize further, return SPIFFS_NEXT_BLOCK + (void)bix; + (void)user_const_p; + (void)user_var_p; + if (obj_id == SPIFFS_OBJ_ID_FREE) { + if (ix_entry == 0) { + fs->free_blocks++; + // todo optimize further, return SPIFFS_NEXT_BLOCK + } + } else if (obj_id == SPIFFS_OBJ_ID_DELETED) { + fs->stats_p_deleted++; + } else { + fs->stats_p_allocated++; } - } else if (obj_id == SPIFFS_OBJ_ID_DELETED) { - fs->stats_p_deleted++; - } else { - fs->stats_p_allocated++; - } - return SPIFFS_VIS_COUNTINUE; + return SPIFFS_VIS_COUNTINUE; } @@ -348,100 +347,100 @@ static s32_t spiffs_obj_lu_scan_v( // Checks magic if enabled s32_t spiffs_obj_lu_scan( spiffs *fs) { - s32_t res; - spiffs_block_ix bix; - int entry; + s32_t res; + spiffs_block_ix bix; + int entry; #if SPIFFS_USE_MAGIC - spiffs_block_ix unerased_bix = (spiffs_block_ix)-1; + spiffs_block_ix unerased_bix = (spiffs_block_ix) - 1; #endif - // find out erase count - // if enabled, check magic - bix = 0; - spiffs_obj_id erase_count_final; - spiffs_obj_id erase_count_min = SPIFFS_OBJ_ID_FREE; - spiffs_obj_id erase_count_max = 0; - while (bix < fs->block_count) { + // find out erase count + // if enabled, check magic + bix = 0; + spiffs_obj_id erase_count_final; + spiffs_obj_id erase_count_min = SPIFFS_OBJ_ID_FREE; + spiffs_obj_id erase_count_max = 0; + while (bix < fs->block_count) { #if SPIFFS_USE_MAGIC - spiffs_obj_id magic; - res = _spiffs_rd(fs, - SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, - 0, SPIFFS_MAGIC_PADDR(fs, bix) , - sizeof(spiffs_obj_id), (u8_t *)&magic); + spiffs_obj_id magic; + res = _spiffs_rd(fs, + SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, + 0, SPIFFS_MAGIC_PADDR(fs, bix), + sizeof(spiffs_obj_id), (u8_t *)&magic); - SPIFFS_CHECK_RES(res); - if (magic != SPIFFS_MAGIC(fs, bix)) { - if (unerased_bix == (spiffs_block_ix)-1) { - // allow one unerased block as it might be powered down during an erase - unerased_bix = bix; - } else { - // more than one unerased block, bail out - SPIFFS_CHECK_RES(SPIFFS_ERR_NOT_A_FS); - } - } + SPIFFS_CHECK_RES(res); + if (magic != SPIFFS_MAGIC(fs, bix)) { + if (unerased_bix == (spiffs_block_ix) - 1) { + // allow one unerased block as it might be powered down during an erase + unerased_bix = bix; + } else { + // more than one unerased block, bail out + SPIFFS_CHECK_RES(SPIFFS_ERR_NOT_A_FS); + } + } #endif - spiffs_obj_id erase_count; - res = _spiffs_rd(fs, - SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, - 0, SPIFFS_ERASE_COUNT_PADDR(fs, bix) , - sizeof(spiffs_obj_id), (u8_t *)&erase_count); - SPIFFS_CHECK_RES(res); - if (erase_count != SPIFFS_OBJ_ID_FREE) { - erase_count_min = MIN(erase_count_min, erase_count); - erase_count_max = MAX(erase_count_max, erase_count); + spiffs_obj_id erase_count; + res = _spiffs_rd(fs, + SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, + 0, SPIFFS_ERASE_COUNT_PADDR(fs, bix), + sizeof(spiffs_obj_id), (u8_t *)&erase_count); + SPIFFS_CHECK_RES(res); + if (erase_count != SPIFFS_OBJ_ID_FREE) { + erase_count_min = MIN(erase_count_min, erase_count); + erase_count_max = MAX(erase_count_max, erase_count); + } + bix++; } - bix++; - } - if (erase_count_min == 0 && erase_count_max == SPIFFS_OBJ_ID_FREE) { - // clean system, set counter to zero - erase_count_final = 0; - } else if (erase_count_max - erase_count_min > (SPIFFS_OBJ_ID_FREE)/2) { - // wrap, take min - erase_count_final = erase_count_min+1; - } else { - erase_count_final = erase_count_max+1; - } + if (erase_count_min == 0 && erase_count_max == SPIFFS_OBJ_ID_FREE) { + // clean system, set counter to zero + erase_count_final = 0; + } else if (erase_count_max - erase_count_min > (SPIFFS_OBJ_ID_FREE) / 2) { + // wrap, take min + erase_count_final = erase_count_min + 1; + } else { + erase_count_final = erase_count_max + 1; + } - fs->max_erase_count = erase_count_final; + fs->max_erase_count = erase_count_final; #if SPIFFS_USE_MAGIC - if (unerased_bix != (spiffs_block_ix)-1) { - // found one unerased block, remedy - SPIFFS_DBG("mount: erase block "_SPIPRIbl"\n", bix); + if (unerased_bix != (spiffs_block_ix) - 1) { + // found one unerased block, remedy + SPIFFS_DBG("mount: erase block "_SPIPRIbl"\n", bix); #if SPIFFS_READ_ONLY - res = SPIFFS_ERR_RO_ABORTED_OPERATION; + res = SPIFFS_ERR_RO_ABORTED_OPERATION; #else - res = spiffs_erase_block(fs, unerased_bix); + res = spiffs_erase_block(fs, unerased_bix); #endif // SPIFFS_READ_ONLY - SPIFFS_CHECK_RES(res); - } + SPIFFS_CHECK_RES(res); + } #endif - // count blocks + // count blocks - fs->free_blocks = 0; - fs->stats_p_allocated = 0; - fs->stats_p_deleted = 0; + fs->free_blocks = 0; + fs->stats_p_allocated = 0; + fs->stats_p_deleted = 0; - res = spiffs_obj_lu_find_entry_visitor(fs, - 0, - 0, - 0, - 0, - spiffs_obj_lu_scan_v, - 0, - 0, - &bix, - &entry); + res = spiffs_obj_lu_find_entry_visitor(fs, + 0, + 0, + 0, + 0, + spiffs_obj_lu_scan_v, + 0, + 0, + &bix, + &entry); - if (res == SPIFFS_VIS_END) { - res = SPIFFS_OK; - } + if (res == SPIFFS_VIS_END) { + res = SPIFFS_OK; + } - SPIFFS_CHECK_RES(res); + SPIFFS_CHECK_RES(res); - return res; + return res; } #if !SPIFFS_READ_ONLY @@ -453,31 +452,31 @@ s32_t spiffs_obj_lu_find_free( int starting_lu_entry, spiffs_block_ix *block_ix, int *lu_entry) { - s32_t res; - if (!fs->cleaning && fs->free_blocks < 2) { - res = spiffs_gc_quick(fs, 0); - if (res == SPIFFS_ERR_NO_DELETED_BLOCKS) { - res = SPIFFS_OK; + s32_t res; + if (!fs->cleaning && fs->free_blocks < 2) { + res = spiffs_gc_quick(fs, 0); + if (res == SPIFFS_ERR_NO_DELETED_BLOCKS) { + res = SPIFFS_OK; + } + SPIFFS_CHECK_RES(res); + if (fs->free_blocks < 2) { + return SPIFFS_ERR_FULL; + } } - SPIFFS_CHECK_RES(res); - if (fs->free_blocks < 2) { - return SPIFFS_ERR_FULL; + res = spiffs_obj_lu_find_id(fs, starting_block, starting_lu_entry, + SPIFFS_OBJ_ID_FREE, block_ix, lu_entry); + if (res == SPIFFS_OK) { + fs->free_cursor_block_ix = *block_ix; + fs->free_cursor_obj_lu_entry = (*lu_entry) + 1; + if (*lu_entry == 0) { + fs->free_blocks--; + } } - } - res = spiffs_obj_lu_find_id(fs, starting_block, starting_lu_entry, - SPIFFS_OBJ_ID_FREE, block_ix, lu_entry); - if (res == SPIFFS_OK) { - fs->free_cursor_block_ix = *block_ix; - fs->free_cursor_obj_lu_entry = (*lu_entry) + 1; - if (*lu_entry == 0) { - fs->free_blocks--; + if (res == SPIFFS_ERR_FULL) { + SPIFFS_DBGF("fs full\n"); } - } - if (res == SPIFFS_ERR_FULL) { - SPIFFS_DBGF("fs full\n"); - } - return res; + return res; } #endif // !SPIFFS_READ_ONLY @@ -490,12 +489,12 @@ s32_t spiffs_obj_lu_find_id( spiffs_obj_id obj_id, spiffs_block_ix *block_ix, int *lu_entry) { - s32_t res = spiffs_obj_lu_find_entry_visitor( - fs, starting_block, starting_lu_entry, SPIFFS_VIS_CHECK_ID, obj_id, 0, 0, 0, block_ix, lu_entry); - if (res == SPIFFS_VIS_END) { - res = SPIFFS_ERR_NOT_FOUND; - } - return res; + s32_t res = spiffs_obj_lu_find_entry_visitor( + fs, starting_block, starting_lu_entry, SPIFFS_VIS_CHECK_ID, obj_id, 0, 0, 0, block_ix, lu_entry); + if (res == SPIFFS_VIS_END) { + res = SPIFFS_ERR_NOT_FOUND; + } + return res; } @@ -506,21 +505,21 @@ static s32_t spiffs_obj_lu_find_id_and_span_v( int ix_entry, const void *user_const_p, void *user_var_p) { - s32_t res; - spiffs_page_header ph; - spiffs_page_ix pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, ix_entry); - res = _spiffs_rd(fs, 0, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, - SPIFFS_PAGE_TO_PADDR(fs, pix), sizeof(spiffs_page_header), (u8_t *)&ph); - SPIFFS_CHECK_RES(res); - if (ph.obj_id == obj_id && - ph.span_ix == *((spiffs_span_ix*)user_var_p) && - (ph.flags & (SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_USED)) == SPIFFS_PH_FLAG_DELET && - !((obj_id & SPIFFS_OBJ_ID_IX_FLAG) && (ph.flags & SPIFFS_PH_FLAG_IXDELE) == 0 && ph.span_ix == 0) && - (user_const_p == 0 || *((const spiffs_page_ix*)user_const_p) != pix)) { - return SPIFFS_OK; - } else { - return SPIFFS_VIS_COUNTINUE; - } + s32_t res; + spiffs_page_header ph; + spiffs_page_ix pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, ix_entry); + res = _spiffs_rd(fs, 0, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, + SPIFFS_PAGE_TO_PADDR(fs, pix), sizeof(spiffs_page_header), (u8_t *)&ph); + SPIFFS_CHECK_RES(res); + if (ph.obj_id == obj_id && + ph.span_ix == *((spiffs_span_ix *)user_var_p) && + (ph.flags & (SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_USED)) == SPIFFS_PH_FLAG_DELET && + !((obj_id & SPIFFS_OBJ_ID_IX_FLAG) && (ph.flags & SPIFFS_PH_FLAG_IXDELE) == 0 && ph.span_ix == 0) && + (user_const_p == 0 || *((const spiffs_page_ix *)user_const_p) != pix)) { + return SPIFFS_OK; + } else { + return SPIFFS_VIS_COUNTINUE; + } } // Find object lookup entry containing given id and span index @@ -531,35 +530,35 @@ s32_t spiffs_obj_lu_find_id_and_span( spiffs_span_ix spix, spiffs_page_ix exclusion_pix, spiffs_page_ix *pix) { - s32_t res; - spiffs_block_ix bix; - int entry; + s32_t res; + spiffs_block_ix bix; + int entry; - res = spiffs_obj_lu_find_entry_visitor(fs, - fs->cursor_block_ix, - fs->cursor_obj_lu_entry, - SPIFFS_VIS_CHECK_ID, - obj_id, - spiffs_obj_lu_find_id_and_span_v, - exclusion_pix ? &exclusion_pix : 0, - &spix, - &bix, - &entry); + res = spiffs_obj_lu_find_entry_visitor(fs, + fs->cursor_block_ix, + fs->cursor_obj_lu_entry, + SPIFFS_VIS_CHECK_ID, + obj_id, + spiffs_obj_lu_find_id_and_span_v, + exclusion_pix ? &exclusion_pix : 0, + &spix, + &bix, + &entry); - if (res == SPIFFS_VIS_END) { - res = SPIFFS_ERR_NOT_FOUND; - } + if (res == SPIFFS_VIS_END) { + res = SPIFFS_ERR_NOT_FOUND; + } - SPIFFS_CHECK_RES(res); + SPIFFS_CHECK_RES(res); - if (pix) { - *pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, entry); - } + if (pix) { + *pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, entry); + } - fs->cursor_block_ix = bix; - fs->cursor_obj_lu_entry = entry; + fs->cursor_block_ix = bix; + fs->cursor_obj_lu_entry = entry; - return res; + return res; } // Find object lookup entry containing given id and span index in page headers only @@ -570,97 +569,97 @@ s32_t spiffs_obj_lu_find_id_and_span_by_phdr( spiffs_span_ix spix, spiffs_page_ix exclusion_pix, spiffs_page_ix *pix) { - s32_t res; - spiffs_block_ix bix; - int entry; + s32_t res; + spiffs_block_ix bix; + int entry; - res = spiffs_obj_lu_find_entry_visitor(fs, - fs->cursor_block_ix, - fs->cursor_obj_lu_entry, - SPIFFS_VIS_CHECK_PH, - obj_id, - spiffs_obj_lu_find_id_and_span_v, - exclusion_pix ? &exclusion_pix : 0, - &spix, - &bix, - &entry); + res = spiffs_obj_lu_find_entry_visitor(fs, + fs->cursor_block_ix, + fs->cursor_obj_lu_entry, + SPIFFS_VIS_CHECK_PH, + obj_id, + spiffs_obj_lu_find_id_and_span_v, + exclusion_pix ? &exclusion_pix : 0, + &spix, + &bix, + &entry); - if (res == SPIFFS_VIS_END) { - res = SPIFFS_ERR_NOT_FOUND; - } + if (res == SPIFFS_VIS_END) { + res = SPIFFS_ERR_NOT_FOUND; + } - SPIFFS_CHECK_RES(res); + SPIFFS_CHECK_RES(res); - if (pix) { - *pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, entry); - } + if (pix) { + *pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, entry); + } - fs->cursor_block_ix = bix; - fs->cursor_obj_lu_entry = entry; + fs->cursor_block_ix = bix; + fs->cursor_obj_lu_entry = entry; - return res; + return res; } #if SPIFFS_IX_MAP // update index map of given fd with given object index data static void spiffs_update_ix_map(spiffs *fs, - spiffs_fd *fd, spiffs_span_ix objix_spix, spiffs_page_object_ix *objix) { + spiffs_fd *fd, spiffs_span_ix objix_spix, spiffs_page_object_ix *objix) { #if SPIFFS_SINGLETON - (void)fs; + (void)fs; #endif - spiffs_ix_map *map = fd->ix_map; - spiffs_span_ix map_objix_start_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, map->start_spix); - spiffs_span_ix map_objix_end_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, map->end_spix); + spiffs_ix_map *map = fd->ix_map; + spiffs_span_ix map_objix_start_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, map->start_spix); + spiffs_span_ix map_objix_end_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, map->end_spix); - // check if updated ix is within map range - if (objix_spix < map_objix_start_spix || objix_spix > map_objix_end_spix) { - return; - } - - // update memory mapped page index buffer to new pages - - // get range of updated object index map data span indices - spiffs_span_ix objix_data_spix_start = - SPIFFS_DATA_SPAN_IX_FOR_OBJ_IX_SPAN_IX(fs, objix_spix); - spiffs_span_ix objix_data_spix_end = objix_data_spix_start + - (objix_spix == 0 ? SPIFFS_OBJ_HDR_IX_LEN(fs) : SPIFFS_OBJ_IX_LEN(fs)); - - // calc union of object index range and index map range array - spiffs_span_ix map_spix = MAX(map->start_spix, objix_data_spix_start); - spiffs_span_ix map_spix_end = MIN(map->end_spix + 1, objix_data_spix_end); - - while (map_spix < map_spix_end) { - spiffs_page_ix objix_data_pix; - if (objix_spix == 0) { - // get data page from object index header page - objix_data_pix = ((spiffs_page_ix*)((u8_t *)objix + sizeof(spiffs_page_object_ix_header)))[map_spix]; - } else { - // get data page from object index page - objix_data_pix = ((spiffs_page_ix*)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, map_spix)]; + // check if updated ix is within map range + if (objix_spix < map_objix_start_spix || objix_spix > map_objix_end_spix) { + return; } - if (objix_data_pix == (spiffs_page_ix)-1) { - // reached end of object, abort - break; + // update memory mapped page index buffer to new pages + + // get range of updated object index map data span indices + spiffs_span_ix objix_data_spix_start = + SPIFFS_DATA_SPAN_IX_FOR_OBJ_IX_SPAN_IX(fs, objix_spix); + spiffs_span_ix objix_data_spix_end = objix_data_spix_start + + (objix_spix == 0 ? SPIFFS_OBJ_HDR_IX_LEN(fs) : SPIFFS_OBJ_IX_LEN(fs)); + + // calc union of object index range and index map range array + spiffs_span_ix map_spix = MAX(map->start_spix, objix_data_spix_start); + spiffs_span_ix map_spix_end = MIN(map->end_spix + 1, objix_data_spix_end); + + while (map_spix < map_spix_end) { + spiffs_page_ix objix_data_pix; + if (objix_spix == 0) { + // get data page from object index header page + objix_data_pix = ((spiffs_page_ix *)((u8_t *)objix + sizeof(spiffs_page_object_ix_header)))[map_spix]; + } else { + // get data page from object index page + objix_data_pix = ((spiffs_page_ix *)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, map_spix)]; + } + + if (objix_data_pix == (spiffs_page_ix) - 1) { + // reached end of object, abort + break; + } + + map->map_buf[map_spix - map->start_spix] = objix_data_pix; + SPIFFS_DBG("map "_SPIPRIid":"_SPIPRIsp" ("_SPIPRIsp"--"_SPIPRIsp") objix.spix:"_SPIPRIsp" to pix "_SPIPRIpg"\n", + fd->obj_id, map_spix - map->start_spix, + map->start_spix, map->end_spix, + objix->p_hdr.span_ix, + objix_data_pix); + + map_spix++; } - - map->map_buf[map_spix - map->start_spix] = objix_data_pix; - SPIFFS_DBG("map "_SPIPRIid":"_SPIPRIsp" ("_SPIPRIsp"--"_SPIPRIsp") objix.spix:"_SPIPRIsp" to pix "_SPIPRIpg"\n", - fd->obj_id, map_spix - map->start_spix, - map->start_spix, map->end_spix, - objix->p_hdr.span_ix, - objix_data_pix); - - map_spix++; - } } typedef struct { - spiffs_fd *fd; - u32_t remaining_objix_pages_to_visit; - spiffs_span_ix map_objix_start_spix; - spiffs_span_ix map_objix_end_spix; + spiffs_fd *fd; + u32_t remaining_objix_pages_to_visit; + spiffs_span_ix map_objix_start_spix; + spiffs_span_ix map_objix_end_spix; } spiffs_ix_map_populate_state; static s32_t spiffs_populate_ix_map_v( @@ -670,78 +669,78 @@ static s32_t spiffs_populate_ix_map_v( int ix_entry, const void *user_const_p, void *user_var_p) { - (void)user_const_p; - s32_t res; - spiffs_ix_map_populate_state *state = (spiffs_ix_map_populate_state *)user_var_p; - spiffs_page_ix pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, ix_entry); + (void)user_const_p; + s32_t res; + spiffs_ix_map_populate_state *state = (spiffs_ix_map_populate_state *)user_var_p; + spiffs_page_ix pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, ix_entry); - // load header to check it - spiffs_page_object_ix *objix = (spiffs_page_object_ix *)fs->work; - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, - 0, SPIFFS_PAGE_TO_PADDR(fs, pix), sizeof(spiffs_page_object_ix), (u8_t *)objix); - SPIFFS_CHECK_RES(res); - SPIFFS_VALIDATE_OBJIX(objix->p_hdr, obj_id, objix->p_hdr.span_ix); - - // check if hdr is ok, and if objix range overlap with ix map range - if ((objix->p_hdr.flags & (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_IXDELE)) == - (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_IXDELE) && - objix->p_hdr.span_ix >= state->map_objix_start_spix && - objix->p_hdr.span_ix <= state->map_objix_end_spix) { - // ok, load rest of object index + // load header to check it + spiffs_page_object_ix *objix = (spiffs_page_object_ix *)fs->work; res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, - 0, SPIFFS_PAGE_TO_PADDR(fs, pix) + sizeof(spiffs_page_object_ix), - SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_page_object_ix), - (u8_t *)objix + sizeof(spiffs_page_object_ix)); + 0, SPIFFS_PAGE_TO_PADDR(fs, pix), sizeof(spiffs_page_object_ix), (u8_t *)objix); SPIFFS_CHECK_RES(res); + SPIFFS_VALIDATE_OBJIX(objix->p_hdr, obj_id, objix->p_hdr.span_ix); - spiffs_update_ix_map(fs, state->fd, objix->p_hdr.span_ix, objix); + // check if hdr is ok, and if objix range overlap with ix map range + if ((objix->p_hdr.flags & (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_IXDELE)) == + (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_IXDELE) && + objix->p_hdr.span_ix >= state->map_objix_start_spix && + objix->p_hdr.span_ix <= state->map_objix_end_spix) { + // ok, load rest of object index + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, + 0, SPIFFS_PAGE_TO_PADDR(fs, pix) + sizeof(spiffs_page_object_ix), + SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_page_object_ix), + (u8_t *)objix + sizeof(spiffs_page_object_ix)); + SPIFFS_CHECK_RES(res); - state->remaining_objix_pages_to_visit--; - SPIFFS_DBG("map "_SPIPRIid" ("_SPIPRIsp"--"_SPIPRIsp") remaining objix pages "_SPIPRIi"\n", - state->fd->obj_id, - state->fd->ix_map->start_spix, state->fd->ix_map->end_spix, - state->remaining_objix_pages_to_visit); - } + spiffs_update_ix_map(fs, state->fd, objix->p_hdr.span_ix, objix); - if (res == SPIFFS_OK) { - res = state->remaining_objix_pages_to_visit ? SPIFFS_VIS_COUNTINUE : SPIFFS_VIS_END; - } - return res; + state->remaining_objix_pages_to_visit--; + SPIFFS_DBG("map "_SPIPRIid" ("_SPIPRIsp"--"_SPIPRIsp") remaining objix pages "_SPIPRIi"\n", + state->fd->obj_id, + state->fd->ix_map->start_spix, state->fd->ix_map->end_spix, + state->remaining_objix_pages_to_visit); + } + + if (res == SPIFFS_OK) { + res = state->remaining_objix_pages_to_visit ? SPIFFS_VIS_COUNTINUE : SPIFFS_VIS_END; + } + return res; } // populates index map, from vector entry start to vector entry end, inclusive s32_t spiffs_populate_ix_map(spiffs *fs, spiffs_fd *fd, u32_t vec_entry_start, u32_t vec_entry_end) { - s32_t res; - spiffs_ix_map *map = fd->ix_map; - spiffs_ix_map_populate_state state; - vec_entry_start = MIN((u32_t)(map->end_spix - map->start_spix), vec_entry_start); - vec_entry_end = MAX((u32_t)(map->end_spix - map->start_spix), vec_entry_end); - if (vec_entry_start > vec_entry_end) { - return SPIFFS_ERR_IX_MAP_BAD_RANGE; - } - state.map_objix_start_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, map->start_spix + vec_entry_start); - state.map_objix_end_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, map->start_spix + vec_entry_end); - state.remaining_objix_pages_to_visit = - state.map_objix_end_spix - state.map_objix_start_spix + 1; - state.fd = fd; + s32_t res; + spiffs_ix_map *map = fd->ix_map; + spiffs_ix_map_populate_state state; + vec_entry_start = MIN((u32_t)(map->end_spix - map->start_spix), vec_entry_start); + vec_entry_end = MAX((u32_t)(map->end_spix - map->start_spix), vec_entry_end); + if (vec_entry_start > vec_entry_end) { + return SPIFFS_ERR_IX_MAP_BAD_RANGE; + } + state.map_objix_start_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, map->start_spix + vec_entry_start); + state.map_objix_end_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, map->start_spix + vec_entry_end); + state.remaining_objix_pages_to_visit = + state.map_objix_end_spix - state.map_objix_start_spix + 1; + state.fd = fd; - res = spiffs_obj_lu_find_entry_visitor( - fs, - SPIFFS_BLOCK_FOR_PAGE(fs, fd->objix_hdr_pix), - SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(fs, fd->objix_hdr_pix), - SPIFFS_VIS_CHECK_ID, - fd->obj_id | SPIFFS_OBJ_ID_IX_FLAG, - spiffs_populate_ix_map_v, - 0, - &state, - 0, - 0); + res = spiffs_obj_lu_find_entry_visitor( + fs, + SPIFFS_BLOCK_FOR_PAGE(fs, fd->objix_hdr_pix), + SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(fs, fd->objix_hdr_pix), + SPIFFS_VIS_CHECK_ID, + fd->obj_id | SPIFFS_OBJ_ID_IX_FLAG, + spiffs_populate_ix_map_v, + 0, + &state, + 0, + 0); - if (res == SPIFFS_VIS_END) { - res = SPIFFS_OK; - } + if (res == SPIFFS_VIS_END) { + res = SPIFFS_OK; + } - return res; + return res; } #endif @@ -760,50 +759,50 @@ s32_t spiffs_page_allocate_data( u32_t page_offs, u8_t finalize, spiffs_page_ix *pix) { - s32_t res = SPIFFS_OK; - spiffs_block_ix bix; - int entry; + s32_t res = SPIFFS_OK; + spiffs_block_ix bix; + int entry; - // find free entry - res = spiffs_obj_lu_find_free(fs, fs->free_cursor_block_ix, fs->free_cursor_obj_lu_entry, &bix, &entry); - SPIFFS_CHECK_RES(res); - - // occupy page in object lookup - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_UPDT, - 0, SPIFFS_BLOCK_TO_PADDR(fs, bix) + entry * sizeof(spiffs_obj_id), sizeof(spiffs_obj_id), (u8_t*)&obj_id); - SPIFFS_CHECK_RES(res); - - fs->stats_p_allocated++; - - // write page header - ph->flags &= ~SPIFFS_PH_FLAG_USED; - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, - 0, SPIFFS_OBJ_LOOKUP_ENTRY_TO_PADDR(fs, bix, entry), sizeof(spiffs_page_header), (u8_t*)ph); - SPIFFS_CHECK_RES(res); - - // write page data - if (data) { - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, - 0,SPIFFS_OBJ_LOOKUP_ENTRY_TO_PADDR(fs, bix, entry) + sizeof(spiffs_page_header) + page_offs, len, data); + // find free entry + res = spiffs_obj_lu_find_free(fs, fs->free_cursor_block_ix, fs->free_cursor_obj_lu_entry, &bix, &entry); SPIFFS_CHECK_RES(res); - } - // finalize header if necessary - if (finalize && (ph->flags & SPIFFS_PH_FLAG_FINAL)) { - ph->flags &= ~SPIFFS_PH_FLAG_FINAL; + // occupy page in object lookup + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_UPDT, + 0, SPIFFS_BLOCK_TO_PADDR(fs, bix) + entry * sizeof(spiffs_obj_id), sizeof(spiffs_obj_id), (u8_t *)&obj_id); + SPIFFS_CHECK_RES(res); + + fs->stats_p_allocated++; + + // write page header + ph->flags &= ~SPIFFS_PH_FLAG_USED; res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, - 0, SPIFFS_OBJ_LOOKUP_ENTRY_TO_PADDR(fs, bix, entry) + offsetof(spiffs_page_header, flags), - sizeof(u8_t), - (u8_t *)&ph->flags); + 0, SPIFFS_OBJ_LOOKUP_ENTRY_TO_PADDR(fs, bix, entry), sizeof(spiffs_page_header), (u8_t *)ph); SPIFFS_CHECK_RES(res); - } - // return written page - if (pix) { - *pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, entry); - } + // write page data + if (data) { + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, + 0, SPIFFS_OBJ_LOOKUP_ENTRY_TO_PADDR(fs, bix, entry) + sizeof(spiffs_page_header) + page_offs, len, data); + SPIFFS_CHECK_RES(res); + } - return res; + // finalize header if necessary + if (finalize && (ph->flags & SPIFFS_PH_FLAG_FINAL)) { + ph->flags &= ~SPIFFS_PH_FLAG_FINAL; + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, + 0, SPIFFS_OBJ_LOOKUP_ENTRY_TO_PADDR(fs, bix, entry) + offsetof(spiffs_page_header, flags), + sizeof(u8_t), + (u8_t *)&ph->flags); + SPIFFS_CHECK_RES(res); + } + + // return written page + if (pix) { + *pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, entry); + } + + return res; } #endif // !SPIFFS_READ_ONLY @@ -818,57 +817,57 @@ s32_t spiffs_page_move( spiffs_page_header *page_hdr, spiffs_page_ix src_pix, spiffs_page_ix *dst_pix) { - s32_t res; - u8_t was_final = 0; - spiffs_page_header *p_hdr; - spiffs_block_ix bix; - int entry; - spiffs_page_ix free_pix; + s32_t res; + u8_t was_final = 0; + spiffs_page_header *p_hdr; + spiffs_block_ix bix; + int entry; + spiffs_page_ix free_pix; - // find free entry - res = spiffs_obj_lu_find_free(fs, fs->free_cursor_block_ix, fs->free_cursor_obj_lu_entry, &bix, &entry); - SPIFFS_CHECK_RES(res); - free_pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, entry); - - if (dst_pix) *dst_pix = free_pix; - - p_hdr = page_data ? (spiffs_page_header *)page_data : page_hdr; - if (page_data) { - // got page data - was_final = (p_hdr->flags & SPIFFS_PH_FLAG_FINAL) == 0; - // write unfinalized page - p_hdr->flags |= SPIFFS_PH_FLAG_FINAL; - p_hdr->flags &= ~SPIFFS_PH_FLAG_USED; - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, - 0, SPIFFS_PAGE_TO_PADDR(fs, free_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), page_data); - } else { - // copy page data - res = spiffs_phys_cpy(fs, fh, SPIFFS_PAGE_TO_PADDR(fs, free_pix), SPIFFS_PAGE_TO_PADDR(fs, src_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs)); - } - SPIFFS_CHECK_RES(res); - - // mark entry in destination object lookup - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_UPDT, - 0, SPIFFS_BLOCK_TO_PADDR(fs, SPIFFS_BLOCK_FOR_PAGE(fs, free_pix)) + SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(fs, free_pix) * sizeof(spiffs_page_ix), - sizeof(spiffs_obj_id), - (u8_t *)&obj_id); - SPIFFS_CHECK_RES(res); - - fs->stats_p_allocated++; - - if (was_final) { - // mark finalized in destination page - p_hdr->flags &= ~(SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_USED); - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, - fh, - SPIFFS_PAGE_TO_PADDR(fs, free_pix) + offsetof(spiffs_page_header, flags), - sizeof(u8_t), - (u8_t *)&p_hdr->flags); + // find free entry + res = spiffs_obj_lu_find_free(fs, fs->free_cursor_block_ix, fs->free_cursor_obj_lu_entry, &bix, &entry); SPIFFS_CHECK_RES(res); - } - // mark source deleted - res = spiffs_page_delete(fs, src_pix); - return res; + free_pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, entry); + + if (dst_pix) *dst_pix = free_pix; + + p_hdr = page_data ? (spiffs_page_header *)page_data : page_hdr; + if (page_data) { + // got page data + was_final = (p_hdr->flags & SPIFFS_PH_FLAG_FINAL) == 0; + // write unfinalized page + p_hdr->flags |= SPIFFS_PH_FLAG_FINAL; + p_hdr->flags &= ~SPIFFS_PH_FLAG_USED; + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, + 0, SPIFFS_PAGE_TO_PADDR(fs, free_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), page_data); + } else { + // copy page data + res = spiffs_phys_cpy(fs, fh, SPIFFS_PAGE_TO_PADDR(fs, free_pix), SPIFFS_PAGE_TO_PADDR(fs, src_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs)); + } + SPIFFS_CHECK_RES(res); + + // mark entry in destination object lookup + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_UPDT, + 0, SPIFFS_BLOCK_TO_PADDR(fs, SPIFFS_BLOCK_FOR_PAGE(fs, free_pix)) + SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(fs, free_pix) * sizeof(spiffs_page_ix), + sizeof(spiffs_obj_id), + (u8_t *)&obj_id); + SPIFFS_CHECK_RES(res); + + fs->stats_p_allocated++; + + if (was_final) { + // mark finalized in destination page + p_hdr->flags &= ~(SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_USED); + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, + fh, + SPIFFS_PAGE_TO_PADDR(fs, free_pix) + offsetof(spiffs_page_header, flags), + sizeof(u8_t), + (u8_t *)&p_hdr->flags); + SPIFFS_CHECK_RES(res); + } + // mark source deleted + res = spiffs_page_delete(fs, src_pix); + return res; } #endif // !SPIFFS_READ_ONLY @@ -877,34 +876,34 @@ s32_t spiffs_page_move( s32_t spiffs_page_delete( spiffs *fs, spiffs_page_ix pix) { - s32_t res; - // mark deleted entry in source object lookup - spiffs_obj_id d_obj_id = SPIFFS_OBJ_ID_DELETED; - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_DELE, - 0, - SPIFFS_BLOCK_TO_PADDR(fs, SPIFFS_BLOCK_FOR_PAGE(fs, pix)) + SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(fs, pix) * sizeof(spiffs_page_ix), - sizeof(spiffs_obj_id), - (u8_t *)&d_obj_id); - SPIFFS_CHECK_RES(res); + s32_t res; + // mark deleted entry in source object lookup + spiffs_obj_id d_obj_id = SPIFFS_OBJ_ID_DELETED; + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_DELE, + 0, + SPIFFS_BLOCK_TO_PADDR(fs, SPIFFS_BLOCK_FOR_PAGE(fs, pix)) + SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(fs, pix) * sizeof(spiffs_page_ix), + sizeof(spiffs_obj_id), + (u8_t *)&d_obj_id); + SPIFFS_CHECK_RES(res); - fs->stats_p_deleted++; - fs->stats_p_allocated--; + fs->stats_p_deleted++; + fs->stats_p_allocated--; - // mark deleted in source page - u8_t flags = 0xff; + // mark deleted in source page + u8_t flags = 0xff; #if SPIFFS_NO_BLIND_WRITES - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_READ, - 0, SPIFFS_PAGE_TO_PADDR(fs, pix) + offsetof(spiffs_page_header, flags), - sizeof(flags), &flags); - SPIFFS_CHECK_RES(res); + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_READ, + 0, SPIFFS_PAGE_TO_PADDR(fs, pix) + offsetof(spiffs_page_header, flags), + sizeof(flags), &flags); + SPIFFS_CHECK_RES(res); #endif - flags &= ~(SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_USED); - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_DELE, - 0, - SPIFFS_PAGE_TO_PADDR(fs, pix) + offsetof(spiffs_page_header, flags), - sizeof(flags), &flags); + flags &= ~(SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_USED); + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_DELE, + 0, + SPIFFS_PAGE_TO_PADDR(fs, pix) + offsetof(spiffs_page_header, flags), + sizeof(flags), &flags); - return res; + return res; } #endif // !SPIFFS_READ_ONLY @@ -917,58 +916,58 @@ s32_t spiffs_object_create( const u8_t meta[], spiffs_obj_type type, spiffs_page_ix *objix_hdr_pix) { - s32_t res = SPIFFS_OK; - spiffs_block_ix bix; - spiffs_page_object_ix_header oix_hdr; - int entry; + s32_t res = SPIFFS_OK; + spiffs_block_ix bix; + spiffs_page_object_ix_header oix_hdr; + int entry; - res = spiffs_gc_check(fs, SPIFFS_DATA_PAGE_SIZE(fs)); - SPIFFS_CHECK_RES(res); + res = spiffs_gc_check(fs, SPIFFS_DATA_PAGE_SIZE(fs)); + SPIFFS_CHECK_RES(res); - obj_id |= SPIFFS_OBJ_ID_IX_FLAG; + obj_id |= SPIFFS_OBJ_ID_IX_FLAG; - // find free entry - res = spiffs_obj_lu_find_free(fs, fs->free_cursor_block_ix, fs->free_cursor_obj_lu_entry, &bix, &entry); - SPIFFS_CHECK_RES(res); - SPIFFS_DBG("create: found free page @ "_SPIPRIpg" bix:"_SPIPRIbl" entry:"_SPIPRIsp"\n", (spiffs_page_ix)SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, entry), bix, entry); + // find free entry + res = spiffs_obj_lu_find_free(fs, fs->free_cursor_block_ix, fs->free_cursor_obj_lu_entry, &bix, &entry); + SPIFFS_CHECK_RES(res); + SPIFFS_DBG("create: found free page @ "_SPIPRIpg" bix:"_SPIPRIbl" entry:"_SPIPRIsp"\n", (spiffs_page_ix)SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, entry), bix, entry); - // occupy page in object lookup - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_UPDT, - 0, SPIFFS_BLOCK_TO_PADDR(fs, bix) + entry * sizeof(spiffs_obj_id), sizeof(spiffs_obj_id), (u8_t*)&obj_id); - SPIFFS_CHECK_RES(res); + // occupy page in object lookup + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_UPDT, + 0, SPIFFS_BLOCK_TO_PADDR(fs, bix) + entry * sizeof(spiffs_obj_id), sizeof(spiffs_obj_id), (u8_t *)&obj_id); + SPIFFS_CHECK_RES(res); - fs->stats_p_allocated++; + fs->stats_p_allocated++; - // write empty object index page - oix_hdr.p_hdr.obj_id = obj_id; - oix_hdr.p_hdr.span_ix = 0; - oix_hdr.p_hdr.flags = 0xff & ~(SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_USED); - oix_hdr.type = type; - oix_hdr.size = SPIFFS_UNDEFINED_LEN; // keep ones so we can update later without wasting this page - strncpy((char*)oix_hdr.name, (const char*)name, SPIFFS_OBJ_NAME_LEN); + // write empty object index page + oix_hdr.p_hdr.obj_id = obj_id; + oix_hdr.p_hdr.span_ix = 0; + oix_hdr.p_hdr.flags = 0xff & ~(SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_USED); + oix_hdr.type = type; + oix_hdr.size = SPIFFS_UNDEFINED_LEN; // keep ones so we can update later without wasting this page + strncpy((char *)oix_hdr.name, (const char *)name, SPIFFS_OBJ_NAME_LEN); #if SPIFFS_OBJ_META_LEN - if (meta) { - _SPIFFS_MEMCPY(oix_hdr.meta, meta, SPIFFS_OBJ_META_LEN); - } else { - memset(oix_hdr.meta, 0xff, SPIFFS_OBJ_META_LEN); - } + if (meta) { + _SPIFFS_MEMCPY(oix_hdr.meta, meta, SPIFFS_OBJ_META_LEN); + } else { + memset(oix_hdr.meta, 0xff, SPIFFS_OBJ_META_LEN); + } #else - (void) meta; + (void) meta; #endif - // update page - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, - 0, SPIFFS_OBJ_LOOKUP_ENTRY_TO_PADDR(fs, bix, entry), sizeof(spiffs_page_object_ix_header), (u8_t*)&oix_hdr); + // update page + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, + 0, SPIFFS_OBJ_LOOKUP_ENTRY_TO_PADDR(fs, bix, entry), sizeof(spiffs_page_object_ix_header), (u8_t *)&oix_hdr); - SPIFFS_CHECK_RES(res); - spiffs_cb_object_event(fs, (spiffs_page_object_ix *)&oix_hdr, - SPIFFS_EV_IX_NEW, obj_id, 0, SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, entry), SPIFFS_UNDEFINED_LEN); + SPIFFS_CHECK_RES(res); + spiffs_cb_object_event(fs, (spiffs_page_object_ix *)&oix_hdr, + SPIFFS_EV_IX_NEW, obj_id, 0, SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, entry), SPIFFS_UNDEFINED_LEN); - if (objix_hdr_pix) { - *objix_hdr_pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, entry); - } + if (objix_hdr_pix) { + *objix_hdr_pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, entry); + } - return res; + return res; } #endif // !SPIFFS_READ_ONLY @@ -987,55 +986,55 @@ s32_t spiffs_object_update_index_hdr( const u8_t meta[], u32_t size, spiffs_page_ix *new_pix) { - s32_t res = SPIFFS_OK; - spiffs_page_object_ix_header *objix_hdr; - spiffs_page_ix new_objix_hdr_pix; + s32_t res = SPIFFS_OK; + spiffs_page_object_ix_header *objix_hdr; + spiffs_page_ix new_objix_hdr_pix; - obj_id |= SPIFFS_OBJ_ID_IX_FLAG; + obj_id |= SPIFFS_OBJ_ID_IX_FLAG; - if (new_objix_hdr_data) { - // object index header page already given to us, no need to load it - objix_hdr = (spiffs_page_object_ix_header *)new_objix_hdr_data; - } else { - // read object index header page - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, - fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, objix_hdr_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); - SPIFFS_CHECK_RES(res); - objix_hdr = (spiffs_page_object_ix_header *)fs->work; - } - - SPIFFS_VALIDATE_OBJIX(objix_hdr->p_hdr, obj_id, 0); - - // change name - if (name) { - strncpy((char*)objix_hdr->name, (const char*)name, SPIFFS_OBJ_NAME_LEN); - } -#if SPIFFS_OBJ_META_LEN - if (meta) { - _SPIFFS_MEMCPY(objix_hdr->meta, meta, SPIFFS_OBJ_META_LEN); - } -#else - (void) meta; -#endif - if (size) { - objix_hdr->size = size; - } - - // move and update page - res = spiffs_page_move(fs, fd == 0 ? 0 : fd->file_nbr, (u8_t*)objix_hdr, obj_id, 0, objix_hdr_pix, &new_objix_hdr_pix); - - if (res == SPIFFS_OK) { - if (new_pix) { - *new_pix = new_objix_hdr_pix; + if (new_objix_hdr_data) { + // object index header page already given to us, no need to load it + objix_hdr = (spiffs_page_object_ix_header *)new_objix_hdr_data; + } else { + // read object index header page + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, + fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, objix_hdr_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); + SPIFFS_CHECK_RES(res); + objix_hdr = (spiffs_page_object_ix_header *)fs->work; } - // callback on object index update - spiffs_cb_object_event(fs, (spiffs_page_object_ix *)objix_hdr, - new_objix_hdr_data ? SPIFFS_EV_IX_UPD : SPIFFS_EV_IX_UPD_HDR, - obj_id, objix_hdr->p_hdr.span_ix, new_objix_hdr_pix, objix_hdr->size); - if (fd) fd->objix_hdr_pix = new_objix_hdr_pix; // if this is not in the registered cluster - } - return res; + SPIFFS_VALIDATE_OBJIX(objix_hdr->p_hdr, obj_id, 0); + + // change name + if (name) { + strncpy((char *)objix_hdr->name, (const char *)name, SPIFFS_OBJ_NAME_LEN); + } +#if SPIFFS_OBJ_META_LEN + if (meta) { + _SPIFFS_MEMCPY(objix_hdr->meta, meta, SPIFFS_OBJ_META_LEN); + } +#else + (void) meta; +#endif + if (size) { + objix_hdr->size = size; + } + + // move and update page + res = spiffs_page_move(fs, fd == 0 ? 0 : fd->file_nbr, (u8_t *)objix_hdr, obj_id, 0, objix_hdr_pix, &new_objix_hdr_pix); + + if (res == SPIFFS_OK) { + if (new_pix) { + *new_pix = new_objix_hdr_pix; + } + // callback on object index update + spiffs_cb_object_event(fs, (spiffs_page_object_ix *)objix_hdr, + new_objix_hdr_data ? SPIFFS_EV_IX_UPD : SPIFFS_EV_IX_UPD_HDR, + obj_id, objix_hdr->p_hdr.span_ix, new_objix_hdr_pix, objix_hdr->size); + if (fd) fd->objix_hdr_pix = new_objix_hdr_pix; // if this is not in the registered cluster + } + + return res; } #endif // !SPIFFS_READ_ONLY @@ -1048,107 +1047,107 @@ void spiffs_cb_object_event( spiffs_page_ix new_pix, u32_t new_size) { #if SPIFFS_IX_MAP == 0 - (void)objix; + (void)objix; #endif - // update index caches in all file descriptors - spiffs_obj_id obj_id = obj_id_raw & ~SPIFFS_OBJ_ID_IX_FLAG; - u32_t i; - spiffs_fd *fds = (spiffs_fd *)fs->fd_space; - SPIFFS_DBG(" CALLBACK %s obj_id:"_SPIPRIid" spix:"_SPIPRIsp" npix:"_SPIPRIpg" nsz:"_SPIPRIi"\n", (const char *[]){"UPD", "NEW", "DEL", "MOV", "HUP","???"}[MIN(ev,5)], - obj_id_raw, spix, new_pix, new_size); - for (i = 0; i < fs->fd_count; i++) { - spiffs_fd *cur_fd = &fds[i]; - if ((cur_fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG) != obj_id) continue; // fd not related to updated file + // update index caches in all file descriptors + spiffs_obj_id obj_id = obj_id_raw & ~SPIFFS_OBJ_ID_IX_FLAG; + u32_t i; + spiffs_fd *fds = (spiffs_fd *)fs->fd_space; + SPIFFS_DBG(" CALLBACK %s obj_id:"_SPIPRIid" spix:"_SPIPRIsp" npix:"_SPIPRIpg" nsz:"_SPIPRIi"\n", (const char *[]) {"UPD", "NEW", "DEL", "MOV", "HUP", "???"}[MIN(ev, 5)], + obj_id_raw, spix, new_pix, new_size); + for (i = 0; i < fs->fd_count; i++) { + spiffs_fd *cur_fd = &fds[i]; + if ((cur_fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG) != obj_id) continue; // fd not related to updated file #if !SPIFFS_TEMPORAL_FD_CACHE - if (cur_fd->file_nbr == 0) continue; // fd closed + if (cur_fd->file_nbr == 0) continue; // fd closed #endif - if (spix == 0) { // object index header update - if (ev != SPIFFS_EV_IX_DEL) { + if (spix == 0) { // object index header update + if (ev != SPIFFS_EV_IX_DEL) { #if SPIFFS_TEMPORAL_FD_CACHE - if (cur_fd->score == 0) continue; // never used fd + if (cur_fd->score == 0) continue; // never used fd #endif - SPIFFS_DBG(" callback: setting fd "_SPIPRIfd":"_SPIPRIid"(fdoffs:"_SPIPRIi" offs:"_SPIPRIi") objix_hdr_pix to "_SPIPRIpg", size:"_SPIPRIi"\n", - SPIFFS_FH_OFFS(fs, cur_fd->file_nbr), cur_fd->obj_id, cur_fd->fdoffset, cur_fd->offset, new_pix, new_size); - cur_fd->objix_hdr_pix = new_pix; - if (new_size != 0) { - // update size and offsets for fds to this file - cur_fd->size = new_size; - u32_t act_new_size = new_size == SPIFFS_UNDEFINED_LEN ? 0 : new_size; + SPIFFS_DBG(" callback: setting fd "_SPIPRIfd":"_SPIPRIid"(fdoffs:"_SPIPRIi" offs:"_SPIPRIi") objix_hdr_pix to "_SPIPRIpg", size:"_SPIPRIi"\n", + SPIFFS_FH_OFFS(fs, cur_fd->file_nbr), cur_fd->obj_id, cur_fd->fdoffset, cur_fd->offset, new_pix, new_size); + cur_fd->objix_hdr_pix = new_pix; + if (new_size != 0) { + // update size and offsets for fds to this file + cur_fd->size = new_size; + u32_t act_new_size = new_size == SPIFFS_UNDEFINED_LEN ? 0 : new_size; #if SPIFFS_CACHE_WR - if (act_new_size > 0 && cur_fd->cache_page) { - act_new_size = MAX(act_new_size, cur_fd->cache_page->ucache.swrc.offset + cur_fd->cache_page->ucache.swrc.size); - } + if (act_new_size > 0 && cur_fd->cache_page) { + act_new_size = MAX(act_new_size, cur_fd->cache_page->ucache.swrc.offset + cur_fd->cache_page->ucache.swrc.size); + } #endif - if (cur_fd->offset > act_new_size) { - cur_fd->offset = act_new_size; - } - if (cur_fd->fdoffset > act_new_size) { - cur_fd->fdoffset = act_new_size; - } + if (cur_fd->offset > act_new_size) { + cur_fd->offset = act_new_size; + } + if (cur_fd->fdoffset > act_new_size) { + cur_fd->fdoffset = act_new_size; + } #if SPIFFS_CACHE_WR - if (cur_fd->cache_page && cur_fd->cache_page->ucache.swrc.offset > act_new_size+1) { - SPIFFS_CACHE_DBG("CACHE_DROP: file trunced, dropping cache page "_SPIPRIi", no writeback\n", cur_fd->cache_page->ix); - spiffs_cache_fd_release(fs, cur_fd->cache_page); - } + if (cur_fd->cache_page && cur_fd->cache_page->ucache.swrc.offset > act_new_size + 1) { + SPIFFS_CACHE_DBG("CACHE_DROP: file trunced, dropping cache page "_SPIPRIi", no writeback\n", cur_fd->cache_page->ix); + spiffs_cache_fd_release(fs, cur_fd->cache_page); + } #endif + } + } else { + // removing file +#if SPIFFS_CACHE_WR + if (cur_fd->file_nbr && cur_fd->cache_page) { + SPIFFS_CACHE_DBG("CACHE_DROP: file deleted, dropping cache page "_SPIPRIi", no writeback\n", cur_fd->cache_page->ix); + spiffs_cache_fd_release(fs, cur_fd->cache_page); + } +#endif + SPIFFS_DBG(" callback: release fd "_SPIPRIfd":"_SPIPRIid" span:"_SPIPRIsp" objix_pix to "_SPIPRIpg"\n", SPIFFS_FH_OFFS(fs, cur_fd->file_nbr), cur_fd->obj_id, spix, new_pix); + cur_fd->file_nbr = 0; + cur_fd->obj_id = SPIFFS_OBJ_ID_DELETED; + } + } // object index header update + if (cur_fd->cursor_objix_spix == spix) { + if (ev != SPIFFS_EV_IX_DEL) { + SPIFFS_DBG(" callback: setting fd "_SPIPRIfd":"_SPIPRIid" span:"_SPIPRIsp" objix_pix to "_SPIPRIpg"\n", SPIFFS_FH_OFFS(fs, cur_fd->file_nbr), cur_fd->obj_id, spix, new_pix); + cur_fd->cursor_objix_pix = new_pix; + } else { + cur_fd->cursor_objix_pix = 0; + } } - } else { - // removing file -#if SPIFFS_CACHE_WR - if (cur_fd->file_nbr && cur_fd->cache_page) { - SPIFFS_CACHE_DBG("CACHE_DROP: file deleted, dropping cache page "_SPIPRIi", no writeback\n", cur_fd->cache_page->ix); - spiffs_cache_fd_release(fs, cur_fd->cache_page); - } -#endif - SPIFFS_DBG(" callback: release fd "_SPIPRIfd":"_SPIPRIid" span:"_SPIPRIsp" objix_pix to "_SPIPRIpg"\n", SPIFFS_FH_OFFS(fs, cur_fd->file_nbr), cur_fd->obj_id, spix, new_pix); - cur_fd->file_nbr = 0; - cur_fd->obj_id = SPIFFS_OBJ_ID_DELETED; - } - } // object index header update - if (cur_fd->cursor_objix_spix == spix) { - if (ev != SPIFFS_EV_IX_DEL) { - SPIFFS_DBG(" callback: setting fd "_SPIPRIfd":"_SPIPRIid" span:"_SPIPRIsp" objix_pix to "_SPIPRIpg"\n", SPIFFS_FH_OFFS(fs, cur_fd->file_nbr), cur_fd->obj_id, spix, new_pix); - cur_fd->cursor_objix_pix = new_pix; - } else { - cur_fd->cursor_objix_pix = 0; - } - } - } // fd update loop + } // fd update loop #if SPIFFS_IX_MAP - // update index maps - if (ev == SPIFFS_EV_IX_UPD || ev == SPIFFS_EV_IX_NEW) { - for (i = 0; i < fs->fd_count; i++) { - spiffs_fd *cur_fd = &fds[i]; - // check fd opened, having ix map, match obj id - if (cur_fd->file_nbr == 0 || - cur_fd->ix_map == 0 || - (cur_fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG) != obj_id) continue; - SPIFFS_DBG(" callback: map ix update fd "_SPIPRIfd":"_SPIPRIid" span:"_SPIPRIsp"\n", SPIFFS_FH_OFFS(fs, cur_fd->file_nbr), cur_fd->obj_id, spix); - spiffs_update_ix_map(fs, cur_fd, spix, objix); + // update index maps + if (ev == SPIFFS_EV_IX_UPD || ev == SPIFFS_EV_IX_NEW) { + for (i = 0; i < fs->fd_count; i++) { + spiffs_fd *cur_fd = &fds[i]; + // check fd opened, having ix map, match obj id + if (cur_fd->file_nbr == 0 || + cur_fd->ix_map == 0 || + (cur_fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG) != obj_id) continue; + SPIFFS_DBG(" callback: map ix update fd "_SPIPRIfd":"_SPIPRIid" span:"_SPIPRIsp"\n", SPIFFS_FH_OFFS(fs, cur_fd->file_nbr), cur_fd->obj_id, spix); + spiffs_update_ix_map(fs, cur_fd, spix, objix); + } } - } #endif - // callback to user if object index header - if (fs->file_cb_f && spix == 0 && (obj_id_raw & SPIFFS_OBJ_ID_IX_FLAG)) { - spiffs_fileop_type op; - if (ev == SPIFFS_EV_IX_NEW) { - op = SPIFFS_CB_CREATED; - } else if (ev == SPIFFS_EV_IX_UPD || - ev == SPIFFS_EV_IX_MOV || - ev == SPIFFS_EV_IX_UPD_HDR) { - op = SPIFFS_CB_UPDATED; - } else if (ev == SPIFFS_EV_IX_DEL) { - op = SPIFFS_CB_DELETED; - } else { - SPIFFS_DBG(" callback: WARNING unknown callback event "_SPIPRIi"\n", ev); - return; // bail out + // callback to user if object index header + if (fs->file_cb_f && spix == 0 && (obj_id_raw & SPIFFS_OBJ_ID_IX_FLAG)) { + spiffs_fileop_type op; + if (ev == SPIFFS_EV_IX_NEW) { + op = SPIFFS_CB_CREATED; + } else if (ev == SPIFFS_EV_IX_UPD || + ev == SPIFFS_EV_IX_MOV || + ev == SPIFFS_EV_IX_UPD_HDR) { + op = SPIFFS_CB_UPDATED; + } else if (ev == SPIFFS_EV_IX_DEL) { + op = SPIFFS_CB_DELETED; + } else { + SPIFFS_DBG(" callback: WARNING unknown callback event "_SPIPRIi"\n", ev); + return; // bail out + } + fs->file_cb_f(fs, op, obj_id, new_pix); } - fs->file_cb_f(fs, op, obj_id, new_pix); - } } // Open object by id @@ -1158,15 +1157,15 @@ s32_t spiffs_object_open_by_id( spiffs_fd *fd, spiffs_flags flags, spiffs_mode mode) { - s32_t res = SPIFFS_OK; - spiffs_page_ix pix; + s32_t res = SPIFFS_OK; + spiffs_page_ix pix; - res = spiffs_obj_lu_find_id_and_span(fs, obj_id | SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &pix); - SPIFFS_CHECK_RES(res); + res = spiffs_obj_lu_find_id_and_span(fs, obj_id | SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &pix); + SPIFFS_CHECK_RES(res); - res = spiffs_object_open_by_page(fs, pix, fd, flags, mode); + res = spiffs_object_open_by_page(fs, pix, fd, flags, mode); - return res; + return res; } // Open object by page index @@ -1176,281 +1175,281 @@ s32_t spiffs_object_open_by_page( spiffs_fd *fd, spiffs_flags flags, spiffs_mode mode) { - (void)mode; - s32_t res = SPIFFS_OK; - spiffs_page_object_ix_header oix_hdr; - spiffs_obj_id obj_id; + (void)mode; + s32_t res = SPIFFS_OK; + spiffs_page_object_ix_header oix_hdr; + spiffs_obj_id obj_id; - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, - fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, pix), sizeof(spiffs_page_object_ix_header), (u8_t *)&oix_hdr); - SPIFFS_CHECK_RES(res); + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, + fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, pix), sizeof(spiffs_page_object_ix_header), (u8_t *)&oix_hdr); + SPIFFS_CHECK_RES(res); - spiffs_block_ix bix = SPIFFS_BLOCK_FOR_PAGE(fs, pix); - int entry = SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(fs, pix); + spiffs_block_ix bix = SPIFFS_BLOCK_FOR_PAGE(fs, pix); + int entry = SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(fs, pix); - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, - 0, SPIFFS_BLOCK_TO_PADDR(fs, bix) + entry * sizeof(spiffs_obj_id), sizeof(spiffs_obj_id), (u8_t *)&obj_id); + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, + 0, SPIFFS_BLOCK_TO_PADDR(fs, bix) + entry * sizeof(spiffs_obj_id), sizeof(spiffs_obj_id), (u8_t *)&obj_id); - fd->fs = fs; - fd->objix_hdr_pix = pix; - fd->size = oix_hdr.size; - fd->offset = 0; - fd->cursor_objix_pix = pix; - fd->cursor_objix_spix = 0; - fd->obj_id = obj_id; - fd->flags = flags; + fd->fs = fs; + fd->objix_hdr_pix = pix; + fd->size = oix_hdr.size; + fd->offset = 0; + fd->cursor_objix_pix = pix; + fd->cursor_objix_spix = 0; + fd->obj_id = obj_id; + fd->flags = flags; - SPIFFS_VALIDATE_OBJIX(oix_hdr.p_hdr, fd->obj_id, 0); + SPIFFS_VALIDATE_OBJIX(oix_hdr.p_hdr, fd->obj_id, 0); - SPIFFS_DBG("open: fd "_SPIPRIfd" is obj id "_SPIPRIid"\n", SPIFFS_FH_OFFS(fs, fd->file_nbr), fd->obj_id); + SPIFFS_DBG("open: fd "_SPIPRIfd" is obj id "_SPIPRIid"\n", SPIFFS_FH_OFFS(fs, fd->file_nbr), fd->obj_id); - return res; + return res; } #if !SPIFFS_READ_ONLY // Append to object // keep current object index (header) page in fs->work buffer s32_t spiffs_object_append(spiffs_fd *fd, u32_t offset, u8_t *data, u32_t len) { - spiffs *fs = fd->fs; - s32_t res = SPIFFS_OK; - u32_t written = 0; + spiffs *fs = fd->fs; + s32_t res = SPIFFS_OK; + u32_t written = 0; - SPIFFS_DBG("append: "_SPIPRIi" bytes @ offs "_SPIPRIi" of size "_SPIPRIi"\n", len, offset, fd->size); + SPIFFS_DBG("append: "_SPIPRIi" bytes @ offs "_SPIPRIi" of size "_SPIPRIi"\n", len, offset, fd->size); - if (offset > fd->size) { - SPIFFS_DBGF("append: offset reversed to size\n"); - offset = fd->size; - } + if (offset > fd->size) { + SPIFFS_DBGF("append: offset reversed to size\n"); + offset = fd->size; + } - res = spiffs_gc_check(fs, len + SPIFFS_DATA_PAGE_SIZE(fs)); // add an extra page of data worth for meta - if (res != SPIFFS_OK) { - SPIFFS_DBG("append: gc check fail "_SPIPRIi"\n", res); - } - SPIFFS_CHECK_RES(res); + res = spiffs_gc_check(fs, len + SPIFFS_DATA_PAGE_SIZE(fs)); // add an extra page of data worth for meta + if (res != SPIFFS_OK) { + SPIFFS_DBG("append: gc check fail "_SPIPRIi"\n", res); + } + SPIFFS_CHECK_RES(res); - spiffs_page_object_ix_header *objix_hdr = (spiffs_page_object_ix_header *)fs->work; - spiffs_page_object_ix *objix = (spiffs_page_object_ix *)fs->work; - spiffs_page_header p_hdr; + spiffs_page_object_ix_header *objix_hdr = (spiffs_page_object_ix_header *)fs->work; + spiffs_page_object_ix *objix = (spiffs_page_object_ix *)fs->work; + spiffs_page_header p_hdr; - spiffs_span_ix cur_objix_spix = 0; - spiffs_span_ix prev_objix_spix = (spiffs_span_ix)-1; - spiffs_page_ix cur_objix_pix = fd->objix_hdr_pix; - spiffs_page_ix new_objix_hdr_page; + spiffs_span_ix cur_objix_spix = 0; + spiffs_span_ix prev_objix_spix = (spiffs_span_ix) - 1; + spiffs_page_ix cur_objix_pix = fd->objix_hdr_pix; + spiffs_page_ix new_objix_hdr_page; - spiffs_span_ix data_spix = offset / SPIFFS_DATA_PAGE_SIZE(fs); - spiffs_page_ix data_page; - u32_t page_offs = offset % SPIFFS_DATA_PAGE_SIZE(fs); + spiffs_span_ix data_spix = offset / SPIFFS_DATA_PAGE_SIZE(fs); + spiffs_page_ix data_page; + u32_t page_offs = offset % SPIFFS_DATA_PAGE_SIZE(fs); - // write all data - while (res == SPIFFS_OK && written < len) { - // calculate object index page span index - cur_objix_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, data_spix); + // write all data + while (res == SPIFFS_OK && written < len) { + // calculate object index page span index + cur_objix_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, data_spix); - // handle storing and loading of object indices - if (cur_objix_spix != prev_objix_spix) { - // new object index page - // within this clause we return directly if something fails, object index mess-up - if (written > 0) { - // store previous object index page, unless first pass - SPIFFS_DBG("append: "_SPIPRIid" store objix "_SPIPRIpg":"_SPIPRIsp", written "_SPIPRIi"\n", fd->obj_id, - cur_objix_pix, prev_objix_spix, written); - if (prev_objix_spix == 0) { - // this is an update to object index header page - objix_hdr->size = offset+written; - if (offset == 0) { - // was an empty object, update same page (size was 0xffffffff) - res = spiffs_page_index_check(fs, fd, cur_objix_pix, 0); - SPIFFS_CHECK_RES(res); - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_UPDT, - fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, cur_objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); - SPIFFS_CHECK_RES(res); - } else { - // was a nonempty object, update to new page - res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, - fd->objix_hdr_pix, fs->work, 0, 0, offset+written, &new_objix_hdr_page); - SPIFFS_CHECK_RES(res); - SPIFFS_DBG("append: "_SPIPRIid" store new objix_hdr, "_SPIPRIpg":"_SPIPRIsp", written "_SPIPRIi"\n", fd->obj_id, - new_objix_hdr_page, 0, written); - } - } else { - // this is an update to an object index page - res = spiffs_page_index_check(fs, fd, cur_objix_pix, prev_objix_spix); - SPIFFS_CHECK_RES(res); + // handle storing and loading of object indices + if (cur_objix_spix != prev_objix_spix) { + // new object index page + // within this clause we return directly if something fails, object index mess-up + if (written > 0) { + // store previous object index page, unless first pass + SPIFFS_DBG("append: "_SPIPRIid" store objix "_SPIPRIpg":"_SPIPRIsp", written "_SPIPRIi"\n", fd->obj_id, + cur_objix_pix, prev_objix_spix, written); + if (prev_objix_spix == 0) { + // this is an update to object index header page + objix_hdr->size = offset + written; + if (offset == 0) { + // was an empty object, update same page (size was 0xffffffff) + res = spiffs_page_index_check(fs, fd, cur_objix_pix, 0); + SPIFFS_CHECK_RES(res); + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_UPDT, + fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, cur_objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); + SPIFFS_CHECK_RES(res); + } else { + // was a nonempty object, update to new page + res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, + fd->objix_hdr_pix, fs->work, 0, 0, offset + written, &new_objix_hdr_page); + SPIFFS_CHECK_RES(res); + SPIFFS_DBG("append: "_SPIPRIid" store new objix_hdr, "_SPIPRIpg":"_SPIPRIsp", written "_SPIPRIi"\n", fd->obj_id, + new_objix_hdr_page, 0, written); + } + } else { + // this is an update to an object index page + res = spiffs_page_index_check(fs, fd, cur_objix_pix, prev_objix_spix); + SPIFFS_CHECK_RES(res); - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_UPDT, - fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, cur_objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); - SPIFFS_CHECK_RES(res); - spiffs_cb_object_event(fs, (spiffs_page_object_ix *)fs->work, - SPIFFS_EV_IX_UPD,fd->obj_id, objix->p_hdr.span_ix, cur_objix_pix, 0); - // update length in object index header page - res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, - fd->objix_hdr_pix, 0, 0, 0, offset+written, &new_objix_hdr_page); - SPIFFS_CHECK_RES(res); - SPIFFS_DBG("append: "_SPIPRIid" store new size I "_SPIPRIi" in objix_hdr, "_SPIPRIpg":"_SPIPRIsp", written "_SPIPRIi"\n", fd->obj_id, - offset+written, new_objix_hdr_page, 0, written); + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_UPDT, + fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, cur_objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); + SPIFFS_CHECK_RES(res); + spiffs_cb_object_event(fs, (spiffs_page_object_ix *)fs->work, + SPIFFS_EV_IX_UPD, fd->obj_id, objix->p_hdr.span_ix, cur_objix_pix, 0); + // update length in object index header page + res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, + fd->objix_hdr_pix, 0, 0, 0, offset + written, &new_objix_hdr_page); + SPIFFS_CHECK_RES(res); + SPIFFS_DBG("append: "_SPIPRIid" store new size I "_SPIPRIi" in objix_hdr, "_SPIPRIpg":"_SPIPRIsp", written "_SPIPRIi"\n", fd->obj_id, + offset + written, new_objix_hdr_page, 0, written); + } + fd->size = offset + written; + fd->offset = offset + written; + } + + // create or load new object index page + if (cur_objix_spix == 0) { + // load object index header page, must always exist + SPIFFS_DBG("append: "_SPIPRIid" load objixhdr page "_SPIPRIpg":"_SPIPRIsp"\n", fd->obj_id, cur_objix_pix, cur_objix_spix); + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, + fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, cur_objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); + SPIFFS_CHECK_RES(res); + SPIFFS_VALIDATE_OBJIX(objix_hdr->p_hdr, fd->obj_id, cur_objix_spix); + } else { + spiffs_span_ix len_objix_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, (fd->size - 1) / SPIFFS_DATA_PAGE_SIZE(fs)); + // on subsequent passes, create a new object index page + if (written > 0 || cur_objix_spix > len_objix_spix) { + p_hdr.obj_id = fd->obj_id | SPIFFS_OBJ_ID_IX_FLAG; + p_hdr.span_ix = cur_objix_spix; + p_hdr.flags = 0xff & ~(SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_INDEX); + res = spiffs_page_allocate_data(fs, fd->obj_id | SPIFFS_OBJ_ID_IX_FLAG, + &p_hdr, 0, 0, 0, 1, &cur_objix_pix); + SPIFFS_CHECK_RES(res); + // quick "load" of new object index page + memset(fs->work, 0xff, SPIFFS_CFG_LOG_PAGE_SZ(fs)); + _SPIFFS_MEMCPY(fs->work, &p_hdr, sizeof(spiffs_page_header)); + spiffs_cb_object_event(fs, (spiffs_page_object_ix *)fs->work, + SPIFFS_EV_IX_NEW, fd->obj_id, cur_objix_spix, cur_objix_pix, 0); + SPIFFS_DBG("append: "_SPIPRIid" create objix page, "_SPIPRIpg":"_SPIPRIsp", written "_SPIPRIi"\n", fd->obj_id + , cur_objix_pix, cur_objix_spix, written); + } else { + // on first pass, we load existing object index page + spiffs_page_ix pix; + SPIFFS_DBG("append: "_SPIPRIid" find objix span_ix:"_SPIPRIsp"\n", fd->obj_id, cur_objix_spix); + if (fd->cursor_objix_spix == cur_objix_spix) { + pix = fd->cursor_objix_pix; + } else { + res = spiffs_obj_lu_find_id_and_span(fs, fd->obj_id | SPIFFS_OBJ_ID_IX_FLAG, cur_objix_spix, 0, &pix); + SPIFFS_CHECK_RES(res); + } + SPIFFS_DBG("append: "_SPIPRIid" found object index at page "_SPIPRIpg" [fd size "_SPIPRIi"]\n", fd->obj_id, pix, fd->size); + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, + fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); + SPIFFS_CHECK_RES(res); + SPIFFS_VALIDATE_OBJIX(objix_hdr->p_hdr, fd->obj_id, cur_objix_spix); + cur_objix_pix = pix; + } + fd->cursor_objix_pix = cur_objix_pix; + fd->cursor_objix_spix = cur_objix_spix; + fd->offset = offset + written; + fd->size = offset + written; + } + prev_objix_spix = cur_objix_spix; } - fd->size = offset+written; - fd->offset = offset+written; - } - // create or load new object index page - if (cur_objix_spix == 0) { - // load object index header page, must always exist - SPIFFS_DBG("append: "_SPIPRIid" load objixhdr page "_SPIPRIpg":"_SPIPRIsp"\n", fd->obj_id, cur_objix_pix, cur_objix_spix); - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, - fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, cur_objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); - SPIFFS_CHECK_RES(res); - SPIFFS_VALIDATE_OBJIX(objix_hdr->p_hdr, fd->obj_id, cur_objix_spix); - } else { - spiffs_span_ix len_objix_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, (fd->size-1)/SPIFFS_DATA_PAGE_SIZE(fs)); - // on subsequent passes, create a new object index page - if (written > 0 || cur_objix_spix > len_objix_spix) { - p_hdr.obj_id = fd->obj_id | SPIFFS_OBJ_ID_IX_FLAG; - p_hdr.span_ix = cur_objix_spix; - p_hdr.flags = 0xff & ~(SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_INDEX); - res = spiffs_page_allocate_data(fs, fd->obj_id | SPIFFS_OBJ_ID_IX_FLAG, - &p_hdr, 0, 0, 0, 1, &cur_objix_pix); - SPIFFS_CHECK_RES(res); - // quick "load" of new object index page - memset(fs->work, 0xff, SPIFFS_CFG_LOG_PAGE_SZ(fs)); - _SPIFFS_MEMCPY(fs->work, &p_hdr, sizeof(spiffs_page_header)); - spiffs_cb_object_event(fs, (spiffs_page_object_ix *)fs->work, - SPIFFS_EV_IX_NEW, fd->obj_id, cur_objix_spix, cur_objix_pix, 0); - SPIFFS_DBG("append: "_SPIPRIid" create objix page, "_SPIPRIpg":"_SPIPRIsp", written "_SPIPRIi"\n", fd->obj_id - , cur_objix_pix, cur_objix_spix, written); + // write data + u32_t to_write = MIN(len - written, SPIFFS_DATA_PAGE_SIZE(fs) - page_offs); + if (page_offs == 0) { + // at beginning of a page, allocate and write a new page of data + p_hdr.obj_id = fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG; + p_hdr.span_ix = data_spix; + p_hdr.flags = 0xff & ~(SPIFFS_PH_FLAG_FINAL); // finalize immediately + res = spiffs_page_allocate_data(fs, fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, + &p_hdr, &data[written], to_write, page_offs, 1, &data_page); + SPIFFS_DBG("append: "_SPIPRIid" store new data page, "_SPIPRIpg":"_SPIPRIsp" offset:"_SPIPRIi", len "_SPIPRIi", written "_SPIPRIi"\n", fd->obj_id, + data_page, data_spix, page_offs, to_write, written); } else { - // on first pass, we load existing object index page - spiffs_page_ix pix; - SPIFFS_DBG("append: "_SPIPRIid" find objix span_ix:"_SPIPRIsp"\n", fd->obj_id, cur_objix_spix); - if (fd->cursor_objix_spix == cur_objix_spix) { - pix = fd->cursor_objix_pix; - } else { - res = spiffs_obj_lu_find_id_and_span(fs, fd->obj_id | SPIFFS_OBJ_ID_IX_FLAG, cur_objix_spix, 0, &pix); + // append to existing page, fill out free data in existing page + if (cur_objix_spix == 0) { + // get data page from object index header page + data_page = ((spiffs_page_ix *)((u8_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[data_spix]; + } else { + // get data page from object index page + data_page = ((spiffs_page_ix *)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)]; + } + + res = spiffs_page_data_check(fs, fd, data_page, data_spix); SPIFFS_CHECK_RES(res); - } - SPIFFS_DBG("append: "_SPIPRIid" found object index at page "_SPIPRIpg" [fd size "_SPIPRIi"]\n", fd->obj_id, pix, fd->size); - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, - fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); - SPIFFS_CHECK_RES(res); - SPIFFS_VALIDATE_OBJIX(objix_hdr->p_hdr, fd->obj_id, cur_objix_spix); - cur_objix_pix = pix; + + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, + fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, data_page) + sizeof(spiffs_page_header) + page_offs, to_write, &data[written]); + SPIFFS_DBG("append: "_SPIPRIid" store to existing data page, "_SPIPRIpg":"_SPIPRIsp" offset:"_SPIPRIi", len "_SPIPRIi", written "_SPIPRIi"\n", fd->obj_id + , data_page, data_spix, page_offs, to_write, written); } - fd->cursor_objix_pix = cur_objix_pix; - fd->cursor_objix_spix = cur_objix_spix; - fd->offset = offset+written; - fd->size = offset+written; - } - prev_objix_spix = cur_objix_spix; - } - // write data - u32_t to_write = MIN(len-written, SPIFFS_DATA_PAGE_SIZE(fs) - page_offs); - if (page_offs == 0) { - // at beginning of a page, allocate and write a new page of data - p_hdr.obj_id = fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG; - p_hdr.span_ix = data_spix; - p_hdr.flags = 0xff & ~(SPIFFS_PH_FLAG_FINAL); // finalize immediately - res = spiffs_page_allocate_data(fs, fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, - &p_hdr, &data[written], to_write, page_offs, 1, &data_page); - SPIFFS_DBG("append: "_SPIPRIid" store new data page, "_SPIPRIpg":"_SPIPRIsp" offset:"_SPIPRIi", len "_SPIPRIi", written "_SPIPRIi"\n", fd->obj_id, - data_page, data_spix, page_offs, to_write, written); + if (res != SPIFFS_OK) break; + + // update memory representation of object index page with new data page + if (cur_objix_spix == 0) { + // update object index header page + ((spiffs_page_ix *)((u8_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[data_spix] = data_page; + SPIFFS_DBG("append: "_SPIPRIid" wrote page "_SPIPRIpg" to objix_hdr entry "_SPIPRIsp" in mem\n", fd->obj_id + , data_page, data_spix); + objix_hdr->size = offset + written; + } else { + // update object index page + ((spiffs_page_ix *)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)] = data_page; + SPIFFS_DBG("append: "_SPIPRIid" wrote page "_SPIPRIpg" to objix entry "_SPIPRIsp" in mem\n", fd->obj_id + , data_page, (spiffs_span_ix)SPIFFS_OBJ_IX_ENTRY(fs, data_spix)); + } + + // update internals + page_offs = 0; + data_spix++; + written += to_write; + } // while all data + + fd->size = offset + written; + fd->offset = offset + written; + fd->cursor_objix_pix = cur_objix_pix; + fd->cursor_objix_spix = cur_objix_spix; + + // finalize updated object indices + s32_t res2 = SPIFFS_OK; + if (cur_objix_spix != 0) { + // wrote beyond object index header page + // write last modified object index page, unless object header index page + SPIFFS_DBG("append: "_SPIPRIid" store objix page, "_SPIPRIpg":"_SPIPRIsp", written "_SPIPRIi"\n", fd->obj_id, + cur_objix_pix, cur_objix_spix, written); + + res2 = spiffs_page_index_check(fs, fd, cur_objix_pix, cur_objix_spix); + SPIFFS_CHECK_RES(res2); + + res2 = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_UPDT, + fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, cur_objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); + SPIFFS_CHECK_RES(res2); + spiffs_cb_object_event(fs, (spiffs_page_object_ix *)fs->work, + SPIFFS_EV_IX_UPD, fd->obj_id, objix->p_hdr.span_ix, cur_objix_pix, 0); + + // update size in object header index page + res2 = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, + fd->objix_hdr_pix, 0, 0, 0, offset + written, &new_objix_hdr_page); + SPIFFS_DBG("append: "_SPIPRIid" store new size II "_SPIPRIi" in objix_hdr, "_SPIPRIpg":"_SPIPRIsp", written "_SPIPRIi", res "_SPIPRIi"\n", fd->obj_id + , offset + written, new_objix_hdr_page, 0, written, res2); + SPIFFS_CHECK_RES(res2); } else { - // append to existing page, fill out free data in existing page - if (cur_objix_spix == 0) { - // get data page from object index header page - data_page = ((spiffs_page_ix*)((u8_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[data_spix]; - } else { - // get data page from object index page - data_page = ((spiffs_page_ix*)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)]; - } + // wrote within object index header page + if (offset == 0) { + // wrote to empty object - simply update size and write whole page + objix_hdr->size = offset + written; + SPIFFS_DBG("append: "_SPIPRIid" store fresh objix_hdr page, "_SPIPRIpg":"_SPIPRIsp", written "_SPIPRIi"\n", fd->obj_id + , cur_objix_pix, cur_objix_spix, written); - res = spiffs_page_data_check(fs, fd, data_page, data_spix); - SPIFFS_CHECK_RES(res); + res2 = spiffs_page_index_check(fs, fd, cur_objix_pix, cur_objix_spix); + SPIFFS_CHECK_RES(res2); - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, - fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, data_page) + sizeof(spiffs_page_header) + page_offs, to_write, &data[written]); - SPIFFS_DBG("append: "_SPIPRIid" store to existing data page, "_SPIPRIpg":"_SPIPRIsp" offset:"_SPIPRIi", len "_SPIPRIi", written "_SPIPRIi"\n", fd->obj_id - , data_page, data_spix, page_offs, to_write, written); + res2 = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_UPDT, + fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, cur_objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); + SPIFFS_CHECK_RES(res2); + // callback on object index update + spiffs_cb_object_event(fs, (spiffs_page_object_ix *)fs->work, + SPIFFS_EV_IX_UPD_HDR, fd->obj_id, objix_hdr->p_hdr.span_ix, cur_objix_pix, objix_hdr->size); + } else { + // modifying object index header page, update size and make new copy + res2 = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, + fd->objix_hdr_pix, fs->work, 0, 0, offset + written, &new_objix_hdr_page); + SPIFFS_DBG("append: "_SPIPRIid" store modified objix_hdr page, "_SPIPRIpg":"_SPIPRIsp", written "_SPIPRIi"\n", fd->obj_id + , new_objix_hdr_page, 0, written); + SPIFFS_CHECK_RES(res2); + } } - if (res != SPIFFS_OK) break; - - // update memory representation of object index page with new data page - if (cur_objix_spix == 0) { - // update object index header page - ((spiffs_page_ix*)((u8_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[data_spix] = data_page; - SPIFFS_DBG("append: "_SPIPRIid" wrote page "_SPIPRIpg" to objix_hdr entry "_SPIPRIsp" in mem\n", fd->obj_id - , data_page, data_spix); - objix_hdr->size = offset+written; - } else { - // update object index page - ((spiffs_page_ix*)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)] = data_page; - SPIFFS_DBG("append: "_SPIPRIid" wrote page "_SPIPRIpg" to objix entry "_SPIPRIsp" in mem\n", fd->obj_id - , data_page, (spiffs_span_ix)SPIFFS_OBJ_IX_ENTRY(fs, data_spix)); - } - - // update internals - page_offs = 0; - data_spix++; - written += to_write; - } // while all data - - fd->size = offset+written; - fd->offset = offset+written; - fd->cursor_objix_pix = cur_objix_pix; - fd->cursor_objix_spix = cur_objix_spix; - - // finalize updated object indices - s32_t res2 = SPIFFS_OK; - if (cur_objix_spix != 0) { - // wrote beyond object index header page - // write last modified object index page, unless object header index page - SPIFFS_DBG("append: "_SPIPRIid" store objix page, "_SPIPRIpg":"_SPIPRIsp", written "_SPIPRIi"\n", fd->obj_id, - cur_objix_pix, cur_objix_spix, written); - - res2 = spiffs_page_index_check(fs, fd, cur_objix_pix, cur_objix_spix); - SPIFFS_CHECK_RES(res2); - - res2 = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_UPDT, - fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, cur_objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); - SPIFFS_CHECK_RES(res2); - spiffs_cb_object_event(fs, (spiffs_page_object_ix *)fs->work, - SPIFFS_EV_IX_UPD, fd->obj_id, objix->p_hdr.span_ix, cur_objix_pix, 0); - - // update size in object header index page - res2 = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, - fd->objix_hdr_pix, 0, 0, 0, offset+written, &new_objix_hdr_page); - SPIFFS_DBG("append: "_SPIPRIid" store new size II "_SPIPRIi" in objix_hdr, "_SPIPRIpg":"_SPIPRIsp", written "_SPIPRIi", res "_SPIPRIi"\n", fd->obj_id - , offset+written, new_objix_hdr_page, 0, written, res2); - SPIFFS_CHECK_RES(res2); - } else { - // wrote within object index header page - if (offset == 0) { - // wrote to empty object - simply update size and write whole page - objix_hdr->size = offset+written; - SPIFFS_DBG("append: "_SPIPRIid" store fresh objix_hdr page, "_SPIPRIpg":"_SPIPRIsp", written "_SPIPRIi"\n", fd->obj_id - , cur_objix_pix, cur_objix_spix, written); - - res2 = spiffs_page_index_check(fs, fd, cur_objix_pix, cur_objix_spix); - SPIFFS_CHECK_RES(res2); - - res2 = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_UPDT, - fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, cur_objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); - SPIFFS_CHECK_RES(res2); - // callback on object index update - spiffs_cb_object_event(fs, (spiffs_page_object_ix *)fs->work, - SPIFFS_EV_IX_UPD_HDR, fd->obj_id, objix_hdr->p_hdr.span_ix, cur_objix_pix, objix_hdr->size); - } else { - // modifying object index header page, update size and make new copy - res2 = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, - fd->objix_hdr_pix, fs->work, 0, 0, offset+written, &new_objix_hdr_page); - SPIFFS_DBG("append: "_SPIPRIid" store modified objix_hdr page, "_SPIPRIpg":"_SPIPRIsp", written "_SPIPRIi"\n", fd->obj_id - , new_objix_hdr_page, 0, written); - SPIFFS_CHECK_RES(res2); - } - } - - return res; + return res; } // spiffs_object_append #endif // !SPIFFS_READ_ONLY @@ -1458,204 +1457,204 @@ s32_t spiffs_object_append(spiffs_fd *fd, u32_t offset, u8_t *data, u32_t len) { // Modify object // keep current object index (header) page in fs->work buffer s32_t spiffs_object_modify(spiffs_fd *fd, u32_t offset, u8_t *data, u32_t len) { - spiffs *fs = fd->fs; - s32_t res = SPIFFS_OK; - u32_t written = 0; + spiffs *fs = fd->fs; + s32_t res = SPIFFS_OK; + u32_t written = 0; - res = spiffs_gc_check(fs, len + SPIFFS_DATA_PAGE_SIZE(fs)); - SPIFFS_CHECK_RES(res); + res = spiffs_gc_check(fs, len + SPIFFS_DATA_PAGE_SIZE(fs)); + SPIFFS_CHECK_RES(res); - spiffs_page_object_ix_header *objix_hdr = (spiffs_page_object_ix_header *)fs->work; - spiffs_page_object_ix *objix = (spiffs_page_object_ix *)fs->work; - spiffs_page_header p_hdr; + spiffs_page_object_ix_header *objix_hdr = (spiffs_page_object_ix_header *)fs->work; + spiffs_page_object_ix *objix = (spiffs_page_object_ix *)fs->work; + spiffs_page_header p_hdr; - spiffs_span_ix cur_objix_spix = 0; - spiffs_span_ix prev_objix_spix = (spiffs_span_ix)-1; - spiffs_page_ix cur_objix_pix = fd->objix_hdr_pix; - spiffs_page_ix new_objix_hdr_pix; + spiffs_span_ix cur_objix_spix = 0; + spiffs_span_ix prev_objix_spix = (spiffs_span_ix) - 1; + spiffs_page_ix cur_objix_pix = fd->objix_hdr_pix; + spiffs_page_ix new_objix_hdr_pix; - spiffs_span_ix data_spix = offset / SPIFFS_DATA_PAGE_SIZE(fs); - spiffs_page_ix data_pix; - u32_t page_offs = offset % SPIFFS_DATA_PAGE_SIZE(fs); + spiffs_span_ix data_spix = offset / SPIFFS_DATA_PAGE_SIZE(fs); + spiffs_page_ix data_pix; + u32_t page_offs = offset % SPIFFS_DATA_PAGE_SIZE(fs); - // write all data - while (res == SPIFFS_OK && written < len) { - // calculate object index page span index - cur_objix_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, data_spix); + // write all data + while (res == SPIFFS_OK && written < len) { + // calculate object index page span index + cur_objix_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, data_spix); - // handle storing and loading of object indices - if (cur_objix_spix != prev_objix_spix) { - // new object index page - // within this clause we return directly if something fails, object index mess-up - if (written > 0) { - // store previous object index (header) page, unless first pass - if (prev_objix_spix == 0) { - // store previous object index header page - res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, - fd->objix_hdr_pix, fs->work, 0, 0, 0, &new_objix_hdr_pix); - SPIFFS_DBG("modify: store modified objix_hdr page, "_SPIPRIpg":"_SPIPRIsp", written "_SPIPRIi"\n", new_objix_hdr_pix, 0, written); - SPIFFS_CHECK_RES(res); - } else { - // store new version of previous object index page - spiffs_page_ix new_objix_pix; + // handle storing and loading of object indices + if (cur_objix_spix != prev_objix_spix) { + // new object index page + // within this clause we return directly if something fails, object index mess-up + if (written > 0) { + // store previous object index (header) page, unless first pass + if (prev_objix_spix == 0) { + // store previous object index header page + res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, + fd->objix_hdr_pix, fs->work, 0, 0, 0, &new_objix_hdr_pix); + SPIFFS_DBG("modify: store modified objix_hdr page, "_SPIPRIpg":"_SPIPRIsp", written "_SPIPRIi"\n", new_objix_hdr_pix, 0, written); + SPIFFS_CHECK_RES(res); + } else { + // store new version of previous object index page + spiffs_page_ix new_objix_pix; - res = spiffs_page_index_check(fs, fd, cur_objix_pix, prev_objix_spix); - SPIFFS_CHECK_RES(res); + res = spiffs_page_index_check(fs, fd, cur_objix_pix, prev_objix_spix); + SPIFFS_CHECK_RES(res); - res = spiffs_page_move(fs, fd->file_nbr, (u8_t*)objix, fd->obj_id, 0, cur_objix_pix, &new_objix_pix); - SPIFFS_DBG("modify: store previous modified objix page, "_SPIPRIid":"_SPIPRIsp", written "_SPIPRIi"\n", new_objix_pix, objix->p_hdr.span_ix, written); - SPIFFS_CHECK_RES(res); - spiffs_cb_object_event(fs, (spiffs_page_object_ix *)objix, - SPIFFS_EV_IX_UPD, fd->obj_id, objix->p_hdr.span_ix, new_objix_pix, 0); + res = spiffs_page_move(fs, fd->file_nbr, (u8_t *)objix, fd->obj_id, 0, cur_objix_pix, &new_objix_pix); + SPIFFS_DBG("modify: store previous modified objix page, "_SPIPRIid":"_SPIPRIsp", written "_SPIPRIi"\n", new_objix_pix, objix->p_hdr.span_ix, written); + SPIFFS_CHECK_RES(res); + spiffs_cb_object_event(fs, (spiffs_page_object_ix *)objix, + SPIFFS_EV_IX_UPD, fd->obj_id, objix->p_hdr.span_ix, new_objix_pix, 0); + } + } + + // load next object index page + if (cur_objix_spix == 0) { + // load object index header page, must exist + SPIFFS_DBG("modify: load objixhdr page "_SPIPRIpg":"_SPIPRIsp"\n", cur_objix_pix, cur_objix_spix); + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, + fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, cur_objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); + SPIFFS_CHECK_RES(res); + SPIFFS_VALIDATE_OBJIX(objix_hdr->p_hdr, fd->obj_id, cur_objix_spix); + } else { + // load existing object index page on first pass + spiffs_page_ix pix; + SPIFFS_DBG("modify: find objix span_ix:"_SPIPRIsp"\n", cur_objix_spix); + if (fd->cursor_objix_spix == cur_objix_spix) { + pix = fd->cursor_objix_pix; + } else { + res = spiffs_obj_lu_find_id_and_span(fs, fd->obj_id | SPIFFS_OBJ_ID_IX_FLAG, cur_objix_spix, 0, &pix); + SPIFFS_CHECK_RES(res); + } + SPIFFS_DBG("modify: found object index at page "_SPIPRIpg"\n", pix); + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, + fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); + SPIFFS_CHECK_RES(res); + SPIFFS_VALIDATE_OBJIX(objix_hdr->p_hdr, fd->obj_id, cur_objix_spix); + cur_objix_pix = pix; + } + fd->cursor_objix_pix = cur_objix_pix; + fd->cursor_objix_spix = cur_objix_spix; + fd->offset = offset + written; + prev_objix_spix = cur_objix_spix; } - } - // load next object index page - if (cur_objix_spix == 0) { - // load object index header page, must exist - SPIFFS_DBG("modify: load objixhdr page "_SPIPRIpg":"_SPIPRIsp"\n", cur_objix_pix, cur_objix_spix); - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, - fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, cur_objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); - SPIFFS_CHECK_RES(res); - SPIFFS_VALIDATE_OBJIX(objix_hdr->p_hdr, fd->obj_id, cur_objix_spix); - } else { - // load existing object index page on first pass - spiffs_page_ix pix; - SPIFFS_DBG("modify: find objix span_ix:"_SPIPRIsp"\n", cur_objix_spix); - if (fd->cursor_objix_spix == cur_objix_spix) { - pix = fd->cursor_objix_pix; + // write partial data + u32_t to_write = MIN(len - written, SPIFFS_DATA_PAGE_SIZE(fs) - page_offs); + spiffs_page_ix orig_data_pix; + if (cur_objix_spix == 0) { + // get data page from object index header page + orig_data_pix = ((spiffs_page_ix *)((u8_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[data_spix]; } else { - res = spiffs_obj_lu_find_id_and_span(fs, fd->obj_id | SPIFFS_OBJ_ID_IX_FLAG, cur_objix_spix, 0, &pix); - SPIFFS_CHECK_RES(res); + // get data page from object index page + orig_data_pix = ((spiffs_page_ix *)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)]; } - SPIFFS_DBG("modify: found object index at page "_SPIPRIpg"\n", pix); - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, - fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); - SPIFFS_CHECK_RES(res); - SPIFFS_VALIDATE_OBJIX(objix_hdr->p_hdr, fd->obj_id, cur_objix_spix); - cur_objix_pix = pix; - } - fd->cursor_objix_pix = cur_objix_pix; - fd->cursor_objix_spix = cur_objix_spix; - fd->offset = offset+written; - prev_objix_spix = cur_objix_spix; - } - // write partial data - u32_t to_write = MIN(len-written, SPIFFS_DATA_PAGE_SIZE(fs) - page_offs); - spiffs_page_ix orig_data_pix; - if (cur_objix_spix == 0) { - // get data page from object index header page - orig_data_pix = ((spiffs_page_ix*)((u8_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[data_spix]; - } else { - // get data page from object index page - orig_data_pix = ((spiffs_page_ix*)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)]; - } + p_hdr.obj_id = fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG; + p_hdr.span_ix = data_spix; + p_hdr.flags = 0xff; + if (page_offs == 0 && to_write == SPIFFS_DATA_PAGE_SIZE(fs)) { + // a full page, allocate and write a new page of data + res = spiffs_page_allocate_data(fs, fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, + &p_hdr, &data[written], to_write, page_offs, 1, &data_pix); + SPIFFS_DBG("modify: store new data page, "_SPIPRIpg":"_SPIPRIsp" offset:"_SPIPRIi", len "_SPIPRIi", written "_SPIPRIi"\n", data_pix, data_spix, page_offs, to_write, written); + } else { + // write to existing page, allocate new and copy unmodified data - p_hdr.obj_id = fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG; - p_hdr.span_ix = data_spix; - p_hdr.flags = 0xff; - if (page_offs == 0 && to_write == SPIFFS_DATA_PAGE_SIZE(fs)) { - // a full page, allocate and write a new page of data - res = spiffs_page_allocate_data(fs, fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, - &p_hdr, &data[written], to_write, page_offs, 1, &data_pix); - SPIFFS_DBG("modify: store new data page, "_SPIPRIpg":"_SPIPRIsp" offset:"_SPIPRIi", len "_SPIPRIi", written "_SPIPRIi"\n", data_pix, data_spix, page_offs, to_write, written); - } else { - // write to existing page, allocate new and copy unmodified data + res = spiffs_page_data_check(fs, fd, orig_data_pix, data_spix); + SPIFFS_CHECK_RES(res); - res = spiffs_page_data_check(fs, fd, orig_data_pix, data_spix); - SPIFFS_CHECK_RES(res); + res = spiffs_page_allocate_data(fs, fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, + &p_hdr, 0, 0, 0, 0, &data_pix); + if (res != SPIFFS_OK) break; - res = spiffs_page_allocate_data(fs, fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, - &p_hdr, 0, 0, 0, 0, &data_pix); - if (res != SPIFFS_OK) break; + // copy unmodified data + if (page_offs > 0) { + // before modification + res = spiffs_phys_cpy(fs, fd->file_nbr, + SPIFFS_PAGE_TO_PADDR(fs, data_pix) + sizeof(spiffs_page_header), + SPIFFS_PAGE_TO_PADDR(fs, orig_data_pix) + sizeof(spiffs_page_header), + page_offs); + if (res != SPIFFS_OK) break; + } + if (page_offs + to_write < SPIFFS_DATA_PAGE_SIZE(fs)) { + // after modification + res = spiffs_phys_cpy(fs, fd->file_nbr, + SPIFFS_PAGE_TO_PADDR(fs, data_pix) + sizeof(spiffs_page_header) + page_offs + to_write, + SPIFFS_PAGE_TO_PADDR(fs, orig_data_pix) + sizeof(spiffs_page_header) + page_offs + to_write, + SPIFFS_DATA_PAGE_SIZE(fs) - (page_offs + to_write)); + if (res != SPIFFS_OK) break; + } - // copy unmodified data - if (page_offs > 0) { - // before modification - res = spiffs_phys_cpy(fs, fd->file_nbr, - SPIFFS_PAGE_TO_PADDR(fs, data_pix) + sizeof(spiffs_page_header), - SPIFFS_PAGE_TO_PADDR(fs, orig_data_pix) + sizeof(spiffs_page_header), - page_offs); + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, + fd->file_nbr, + SPIFFS_PAGE_TO_PADDR(fs, data_pix) + sizeof(spiffs_page_header) + page_offs, to_write, &data[written]); + if (res != SPIFFS_OK) break; + p_hdr.flags &= ~SPIFFS_PH_FLAG_FINAL; + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, + fd->file_nbr, + SPIFFS_PAGE_TO_PADDR(fs, data_pix) + offsetof(spiffs_page_header, flags), + sizeof(u8_t), + (u8_t *)&p_hdr.flags); + if (res != SPIFFS_OK) break; + + SPIFFS_DBG("modify: store to existing data page, src:"_SPIPRIpg", dst:"_SPIPRIpg":"_SPIPRIsp" offset:"_SPIPRIi", len "_SPIPRIi", written "_SPIPRIi"\n", orig_data_pix, data_pix, data_spix, page_offs, to_write, written); + } + + // delete original data page + res = spiffs_page_delete(fs, orig_data_pix); if (res != SPIFFS_OK) break; - } - if (page_offs + to_write < SPIFFS_DATA_PAGE_SIZE(fs)) { - // after modification - res = spiffs_phys_cpy(fs, fd->file_nbr, - SPIFFS_PAGE_TO_PADDR(fs, data_pix) + sizeof(spiffs_page_header) + page_offs + to_write, - SPIFFS_PAGE_TO_PADDR(fs, orig_data_pix) + sizeof(spiffs_page_header) + page_offs + to_write, - SPIFFS_DATA_PAGE_SIZE(fs) - (page_offs + to_write)); - if (res != SPIFFS_OK) break; - } + // update memory representation of object index page with new data page + if (cur_objix_spix == 0) { + // update object index header page + ((spiffs_page_ix *)((u8_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[data_spix] = data_pix; + SPIFFS_DBG("modify: wrote page "_SPIPRIpg" to objix_hdr entry "_SPIPRIsp" in mem\n", data_pix, data_spix); + } else { + // update object index page + ((spiffs_page_ix *)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)] = data_pix; + SPIFFS_DBG("modify: wrote page "_SPIPRIpg" to objix entry "_SPIPRIsp" in mem\n", data_pix, (spiffs_span_ix)SPIFFS_OBJ_IX_ENTRY(fs, data_spix)); + } - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, - fd->file_nbr, - SPIFFS_PAGE_TO_PADDR(fs, data_pix) + sizeof(spiffs_page_header) + page_offs, to_write, &data[written]); - if (res != SPIFFS_OK) break; - p_hdr.flags &= ~SPIFFS_PH_FLAG_FINAL; - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, - fd->file_nbr, - SPIFFS_PAGE_TO_PADDR(fs, data_pix) + offsetof(spiffs_page_header, flags), - sizeof(u8_t), - (u8_t *)&p_hdr.flags); - if (res != SPIFFS_OK) break; + // update internals + page_offs = 0; + data_spix++; + written += to_write; + } // while all data - SPIFFS_DBG("modify: store to existing data page, src:"_SPIPRIpg", dst:"_SPIPRIpg":"_SPIPRIsp" offset:"_SPIPRIi", len "_SPIPRIi", written "_SPIPRIi"\n", orig_data_pix, data_pix, data_spix, page_offs, to_write, written); - } - - // delete original data page - res = spiffs_page_delete(fs, orig_data_pix); - if (res != SPIFFS_OK) break; - // update memory representation of object index page with new data page - if (cur_objix_spix == 0) { - // update object index header page - ((spiffs_page_ix*)((u8_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[data_spix] = data_pix; - SPIFFS_DBG("modify: wrote page "_SPIPRIpg" to objix_hdr entry "_SPIPRIsp" in mem\n", data_pix, data_spix); - } else { - // update object index page - ((spiffs_page_ix*)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)] = data_pix; - SPIFFS_DBG("modify: wrote page "_SPIPRIpg" to objix entry "_SPIPRIsp" in mem\n", data_pix, (spiffs_span_ix)SPIFFS_OBJ_IX_ENTRY(fs, data_spix)); - } - - // update internals - page_offs = 0; - data_spix++; - written += to_write; - } // while all data - - fd->offset = offset+written; - fd->cursor_objix_pix = cur_objix_pix; - fd->cursor_objix_spix = cur_objix_spix; - - // finalize updated object indices - s32_t res2 = SPIFFS_OK; - if (cur_objix_spix != 0) { - // wrote beyond object index header page - // write last modified object index page - // move and update page - spiffs_page_ix new_objix_pix; - - res2 = spiffs_page_index_check(fs, fd, cur_objix_pix, cur_objix_spix); - SPIFFS_CHECK_RES(res2); - - res2 = spiffs_page_move(fs, fd->file_nbr, (u8_t*)objix, fd->obj_id, 0, cur_objix_pix, &new_objix_pix); - SPIFFS_DBG("modify: store modified objix page, "_SPIPRIpg":"_SPIPRIsp", written "_SPIPRIi"\n", new_objix_pix, cur_objix_spix, written); - fd->cursor_objix_pix = new_objix_pix; + fd->offset = offset + written; + fd->cursor_objix_pix = cur_objix_pix; fd->cursor_objix_spix = cur_objix_spix; - SPIFFS_CHECK_RES(res2); - spiffs_cb_object_event(fs, (spiffs_page_object_ix *)objix, - SPIFFS_EV_IX_UPD, fd->obj_id, objix->p_hdr.span_ix, new_objix_pix, 0); - } else { - // wrote within object index header page - res2 = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, - fd->objix_hdr_pix, fs->work, 0, 0, 0, &new_objix_hdr_pix); - SPIFFS_DBG("modify: store modified objix_hdr page, "_SPIPRIpg":"_SPIPRIsp", written "_SPIPRIi"\n", new_objix_hdr_pix, 0, written); - SPIFFS_CHECK_RES(res2); - } + // finalize updated object indices + s32_t res2 = SPIFFS_OK; + if (cur_objix_spix != 0) { + // wrote beyond object index header page + // write last modified object index page + // move and update page + spiffs_page_ix new_objix_pix; - return res; + res2 = spiffs_page_index_check(fs, fd, cur_objix_pix, cur_objix_spix); + SPIFFS_CHECK_RES(res2); + + res2 = spiffs_page_move(fs, fd->file_nbr, (u8_t *)objix, fd->obj_id, 0, cur_objix_pix, &new_objix_pix); + SPIFFS_DBG("modify: store modified objix page, "_SPIPRIpg":"_SPIPRIsp", written "_SPIPRIi"\n", new_objix_pix, cur_objix_spix, written); + fd->cursor_objix_pix = new_objix_pix; + fd->cursor_objix_spix = cur_objix_spix; + SPIFFS_CHECK_RES(res2); + spiffs_cb_object_event(fs, (spiffs_page_object_ix *)objix, + SPIFFS_EV_IX_UPD, fd->obj_id, objix->p_hdr.span_ix, new_objix_pix, 0); + + } else { + // wrote within object index header page + res2 = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, + fd->objix_hdr_pix, fs->work, 0, 0, 0, &new_objix_hdr_pix); + SPIFFS_DBG("modify: store modified objix_hdr page, "_SPIPRIpg":"_SPIPRIsp", written "_SPIPRIi"\n", new_objix_hdr_pix, 0, written); + SPIFFS_CHECK_RES(res2); + } + + return res; } // spiffs_object_modify #endif // !SPIFFS_READ_ONLY @@ -1666,26 +1665,26 @@ static s32_t spiffs_object_find_object_index_header_by_name_v( int ix_entry, const void *user_const_p, void *user_var_p) { - (void)user_var_p; - s32_t res; - spiffs_page_object_ix_header objix_hdr; - spiffs_page_ix pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, ix_entry); - if (obj_id == SPIFFS_OBJ_ID_FREE || obj_id == SPIFFS_OBJ_ID_DELETED || - (obj_id & SPIFFS_OBJ_ID_IX_FLAG) == 0) { - return SPIFFS_VIS_COUNTINUE; - } - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, - 0, SPIFFS_PAGE_TO_PADDR(fs, pix), sizeof(spiffs_page_object_ix_header), (u8_t *)&objix_hdr); - SPIFFS_CHECK_RES(res); - if (objix_hdr.p_hdr.span_ix == 0 && - (objix_hdr.p_hdr.flags & (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_IXDELE)) == - (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_IXDELE)) { - if (strcmp((const char*)user_const_p, (char*)objix_hdr.name) == 0) { - return SPIFFS_OK; + (void)user_var_p; + s32_t res; + spiffs_page_object_ix_header objix_hdr; + spiffs_page_ix pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, ix_entry); + if (obj_id == SPIFFS_OBJ_ID_FREE || obj_id == SPIFFS_OBJ_ID_DELETED || + (obj_id & SPIFFS_OBJ_ID_IX_FLAG) == 0) { + return SPIFFS_VIS_COUNTINUE; + } + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, + 0, SPIFFS_PAGE_TO_PADDR(fs, pix), sizeof(spiffs_page_object_ix_header), (u8_t *)&objix_hdr); + SPIFFS_CHECK_RES(res); + if (objix_hdr.p_hdr.span_ix == 0 && + (objix_hdr.p_hdr.flags & (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_IXDELE)) == + (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_IXDELE)) { + if (strcmp((const char *)user_const_p, (char *)objix_hdr.name) == 0) { + return SPIFFS_OK; + } } - } - return SPIFFS_VIS_COUNTINUE; + return SPIFFS_VIS_COUNTINUE; } // Finds object index header page by name @@ -1693,34 +1692,34 @@ s32_t spiffs_object_find_object_index_header_by_name( spiffs *fs, const u8_t name[SPIFFS_OBJ_NAME_LEN], spiffs_page_ix *pix) { - s32_t res; - spiffs_block_ix bix; - int entry; + s32_t res; + spiffs_block_ix bix; + int entry; - res = spiffs_obj_lu_find_entry_visitor(fs, - fs->cursor_block_ix, - fs->cursor_obj_lu_entry, - 0, - 0, - spiffs_object_find_object_index_header_by_name_v, - name, - 0, - &bix, - &entry); + res = spiffs_obj_lu_find_entry_visitor(fs, + fs->cursor_block_ix, + fs->cursor_obj_lu_entry, + 0, + 0, + spiffs_object_find_object_index_header_by_name_v, + name, + 0, + &bix, + &entry); - if (res == SPIFFS_VIS_END) { - res = SPIFFS_ERR_NOT_FOUND; - } - SPIFFS_CHECK_RES(res); + if (res == SPIFFS_VIS_END) { + res = SPIFFS_ERR_NOT_FOUND; + } + SPIFFS_CHECK_RES(res); - if (pix) { - *pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, entry); - } + if (pix) { + *pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, entry); + } - fs->cursor_block_ix = bix; - fs->cursor_obj_lu_entry = entry; + fs->cursor_block_ix = bix; + fs->cursor_obj_lu_entry = entry; - return res; + return res; } #if !SPIFFS_READ_ONLY @@ -1729,238 +1728,238 @@ s32_t spiffs_object_truncate( spiffs_fd *fd, u32_t new_size, u8_t remove_full) { - s32_t res = SPIFFS_OK; - spiffs *fs = fd->fs; + s32_t res = SPIFFS_OK; + spiffs *fs = fd->fs; - if ((fd->size == SPIFFS_UNDEFINED_LEN || fd->size == 0) && !remove_full) { - // no op - return res; - } + if ((fd->size == SPIFFS_UNDEFINED_LEN || fd->size == 0) && !remove_full) { + // no op + return res; + } - // need 2 pages if not removing: object index page + possibly chopped data page - if (remove_full == 0) { - res = spiffs_gc_check(fs, SPIFFS_DATA_PAGE_SIZE(fs) * 2); - SPIFFS_CHECK_RES(res); - } - - spiffs_page_ix objix_pix = fd->objix_hdr_pix; - spiffs_span_ix data_spix = (fd->size > 0 ? fd->size-1 : 0) / SPIFFS_DATA_PAGE_SIZE(fs); - u32_t cur_size = fd->size == (u32_t)SPIFFS_UNDEFINED_LEN ? 0 : fd->size ; - spiffs_span_ix cur_objix_spix = 0; - spiffs_span_ix prev_objix_spix = (spiffs_span_ix)-1; - spiffs_page_object_ix_header *objix_hdr = (spiffs_page_object_ix_header *)fs->work; - spiffs_page_object_ix *objix = (spiffs_page_object_ix *)fs->work; - spiffs_page_ix data_pix; - spiffs_page_ix new_objix_hdr_pix; - - // before truncating, check if object is to be fully removed and mark this - if (remove_full && new_size == 0) { - u8_t flags = ~( SPIFFS_PH_FLAG_USED | SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_IXDELE); - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_UPDT, - fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, fd->objix_hdr_pix) + offsetof(spiffs_page_header, flags), - sizeof(u8_t), - (u8_t *)&flags); - SPIFFS_CHECK_RES(res); - } - - // delete from end of object until desired len is reached - while (cur_size > new_size) { - cur_objix_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, data_spix); - - // put object index for current data span index in work buffer - if (prev_objix_spix != cur_objix_spix) { - if (prev_objix_spix != (spiffs_span_ix)-1) { - // remove previous object index page - SPIFFS_DBG("truncate: delete objix page "_SPIPRIpg":"_SPIPRIsp"\n", objix_pix, prev_objix_spix); - - res = spiffs_page_index_check(fs, fd, objix_pix, prev_objix_spix); + // need 2 pages if not removing: object index page + possibly chopped data page + if (remove_full == 0) { + res = spiffs_gc_check(fs, SPIFFS_DATA_PAGE_SIZE(fs) * 2); SPIFFS_CHECK_RES(res); + } - res = spiffs_page_delete(fs, objix_pix); + spiffs_page_ix objix_pix = fd->objix_hdr_pix; + spiffs_span_ix data_spix = (fd->size > 0 ? fd->size - 1 : 0) / SPIFFS_DATA_PAGE_SIZE(fs); + u32_t cur_size = fd->size == (u32_t)SPIFFS_UNDEFINED_LEN ? 0 : fd->size ; + spiffs_span_ix cur_objix_spix = 0; + spiffs_span_ix prev_objix_spix = (spiffs_span_ix) - 1; + spiffs_page_object_ix_header *objix_hdr = (spiffs_page_object_ix_header *)fs->work; + spiffs_page_object_ix *objix = (spiffs_page_object_ix *)fs->work; + spiffs_page_ix data_pix; + spiffs_page_ix new_objix_hdr_pix; + + // before truncating, check if object is to be fully removed and mark this + if (remove_full && new_size == 0) { + u8_t flags = ~(SPIFFS_PH_FLAG_USED | SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_IXDELE); + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_UPDT, + fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, fd->objix_hdr_pix) + offsetof(spiffs_page_header, flags), + sizeof(u8_t), + (u8_t *)&flags); SPIFFS_CHECK_RES(res); - spiffs_cb_object_event(fs, (spiffs_page_object_ix *)0, - SPIFFS_EV_IX_DEL, fd->obj_id, objix->p_hdr.span_ix, objix_pix, 0); - if (prev_objix_spix > 0) { - // Update object index header page, unless we totally want to remove the file. - // If fully removing, we're not keeping consistency as good as when storing the header between chunks, - // would we be aborted. But when removing full files, a crammed system may otherwise - // report ERR_FULL a la windows. We cannot have that. - // Hence, take the risk - if aborted, a file check would free the lost pages and mend things - // as the file is marked as fully deleted in the beginning. - if (remove_full == 0) { - SPIFFS_DBG("truncate: update objix hdr page "_SPIPRIpg":"_SPIPRIsp" to size "_SPIPRIi"\n", fd->objix_hdr_pix, prev_objix_spix, cur_size); - res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, - fd->objix_hdr_pix, 0, 0, 0, cur_size, &new_objix_hdr_pix); + } + + // delete from end of object until desired len is reached + while (cur_size > new_size) { + cur_objix_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, data_spix); + + // put object index for current data span index in work buffer + if (prev_objix_spix != cur_objix_spix) { + if (prev_objix_spix != (spiffs_span_ix) - 1) { + // remove previous object index page + SPIFFS_DBG("truncate: delete objix page "_SPIPRIpg":"_SPIPRIsp"\n", objix_pix, prev_objix_spix); + + res = spiffs_page_index_check(fs, fd, objix_pix, prev_objix_spix); + SPIFFS_CHECK_RES(res); + + res = spiffs_page_delete(fs, objix_pix); + SPIFFS_CHECK_RES(res); + spiffs_cb_object_event(fs, (spiffs_page_object_ix *)0, + SPIFFS_EV_IX_DEL, fd->obj_id, objix->p_hdr.span_ix, objix_pix, 0); + if (prev_objix_spix > 0) { + // Update object index header page, unless we totally want to remove the file. + // If fully removing, we're not keeping consistency as good as when storing the header between chunks, + // would we be aborted. But when removing full files, a crammed system may otherwise + // report ERR_FULL a la windows. We cannot have that. + // Hence, take the risk - if aborted, a file check would free the lost pages and mend things + // as the file is marked as fully deleted in the beginning. + if (remove_full == 0) { + SPIFFS_DBG("truncate: update objix hdr page "_SPIPRIpg":"_SPIPRIsp" to size "_SPIPRIi"\n", fd->objix_hdr_pix, prev_objix_spix, cur_size); + res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, + fd->objix_hdr_pix, 0, 0, 0, cur_size, &new_objix_hdr_pix); + SPIFFS_CHECK_RES(res); + } + fd->size = cur_size; + } + } + // load current object index (header) page + if (cur_objix_spix == 0) { + objix_pix = fd->objix_hdr_pix; + } else { + res = spiffs_obj_lu_find_id_and_span(fs, fd->obj_id | SPIFFS_OBJ_ID_IX_FLAG, cur_objix_spix, 0, &objix_pix); + SPIFFS_CHECK_RES(res); + } + + SPIFFS_DBG("truncate: load objix page "_SPIPRIpg":"_SPIPRIsp" for data spix:"_SPIPRIsp"\n", objix_pix, cur_objix_spix, data_spix); + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, + fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); SPIFFS_CHECK_RES(res); - } - fd->size = cur_size; + SPIFFS_VALIDATE_OBJIX(objix_hdr->p_hdr, fd->obj_id, cur_objix_spix); + fd->cursor_objix_pix = objix_pix; + fd->cursor_objix_spix = cur_objix_spix; + fd->offset = cur_size; + + prev_objix_spix = cur_objix_spix; } - } - // load current object index (header) page - if (cur_objix_spix == 0) { - objix_pix = fd->objix_hdr_pix; - } else { - res = spiffs_obj_lu_find_id_and_span(fs, fd->obj_id | SPIFFS_OBJ_ID_IX_FLAG, cur_objix_spix, 0, &objix_pix); - SPIFFS_CHECK_RES(res); - } - SPIFFS_DBG("truncate: load objix page "_SPIPRIpg":"_SPIPRIsp" for data spix:"_SPIPRIsp"\n", objix_pix, cur_objix_spix, data_spix); - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, - fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); - SPIFFS_CHECK_RES(res); - SPIFFS_VALIDATE_OBJIX(objix_hdr->p_hdr, fd->obj_id, cur_objix_spix); - fd->cursor_objix_pix = objix_pix; - fd->cursor_objix_spix = cur_objix_spix; - fd->offset = cur_size; + if (cur_objix_spix == 0) { + // get data page from object index header page + data_pix = ((spiffs_page_ix *)((u8_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[data_spix]; + ((spiffs_page_ix *)((u8_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[data_spix] = SPIFFS_OBJ_ID_FREE; + } else { + // get data page from object index page + data_pix = ((spiffs_page_ix *)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)]; + ((spiffs_page_ix *)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)] = SPIFFS_OBJ_ID_FREE; + } - prev_objix_spix = cur_objix_spix; - } + SPIFFS_DBG("truncate: got data pix "_SPIPRIpg"\n", data_pix); + if (new_size == 0 || remove_full || cur_size - new_size >= SPIFFS_DATA_PAGE_SIZE(fs)) { + // delete full data page + res = spiffs_page_data_check(fs, fd, data_pix, data_spix); + if (res != SPIFFS_ERR_DELETED && res != SPIFFS_OK && res != SPIFFS_ERR_INDEX_REF_FREE) { + SPIFFS_DBG("truncate: err validating data pix "_SPIPRIi"\n", res); + break; + } + + if (res == SPIFFS_OK) { + res = spiffs_page_delete(fs, data_pix); + if (res != SPIFFS_OK) { + SPIFFS_DBG("truncate: err deleting data pix "_SPIPRIi"\n", res); + break; + } + } else if (res == SPIFFS_ERR_DELETED || res == SPIFFS_ERR_INDEX_REF_FREE) { + res = SPIFFS_OK; + } + + // update current size + if (cur_size % SPIFFS_DATA_PAGE_SIZE(fs) == 0) { + cur_size -= SPIFFS_DATA_PAGE_SIZE(fs); + } else { + cur_size -= cur_size % SPIFFS_DATA_PAGE_SIZE(fs); + } + fd->size = cur_size; + fd->offset = cur_size; + SPIFFS_DBG("truncate: delete data page "_SPIPRIpg" for data spix:"_SPIPRIsp", cur_size:"_SPIPRIi"\n", data_pix, data_spix, cur_size); + } else { + // delete last page, partially + spiffs_page_header p_hdr; + spiffs_page_ix new_data_pix; + u32_t bytes_to_remove = SPIFFS_DATA_PAGE_SIZE(fs) - (new_size % SPIFFS_DATA_PAGE_SIZE(fs)); + SPIFFS_DBG("truncate: delete "_SPIPRIi" bytes from data page "_SPIPRIpg" for data spix:"_SPIPRIsp", cur_size:"_SPIPRIi"\n", bytes_to_remove, data_pix, data_spix, cur_size); + + res = spiffs_page_data_check(fs, fd, data_pix, data_spix); + if (res != SPIFFS_OK) break; + + p_hdr.obj_id = fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG; + p_hdr.span_ix = data_spix; + p_hdr.flags = 0xff; + // allocate new page and copy unmodified data + res = spiffs_page_allocate_data(fs, fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, + &p_hdr, 0, 0, 0, 0, &new_data_pix); + if (res != SPIFFS_OK) break; + res = spiffs_phys_cpy(fs, 0, + SPIFFS_PAGE_TO_PADDR(fs, new_data_pix) + sizeof(spiffs_page_header), + SPIFFS_PAGE_TO_PADDR(fs, data_pix) + sizeof(spiffs_page_header), + SPIFFS_DATA_PAGE_SIZE(fs) - bytes_to_remove); + if (res != SPIFFS_OK) break; + // delete original data page + res = spiffs_page_delete(fs, data_pix); + if (res != SPIFFS_OK) break; + p_hdr.flags &= ~SPIFFS_PH_FLAG_FINAL; + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, + fd->file_nbr, + SPIFFS_PAGE_TO_PADDR(fs, new_data_pix) + offsetof(spiffs_page_header, flags), + sizeof(u8_t), + (u8_t *)&p_hdr.flags); + if (res != SPIFFS_OK) break; + + // update memory representation of object index page with new data page + if (cur_objix_spix == 0) { + // update object index header page + ((spiffs_page_ix *)((u8_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[data_spix] = new_data_pix; + SPIFFS_DBG("truncate: wrote page "_SPIPRIpg" to objix_hdr entry "_SPIPRIsp" in mem\n", new_data_pix, (spiffs_span_ix)SPIFFS_OBJ_IX_ENTRY(fs, data_spix)); + } else { + // update object index page + ((spiffs_page_ix *)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)] = new_data_pix; + SPIFFS_DBG("truncate: wrote page "_SPIPRIpg" to objix entry "_SPIPRIsp" in mem\n", new_data_pix, (spiffs_span_ix)SPIFFS_OBJ_IX_ENTRY(fs, data_spix)); + } + cur_size = new_size; + fd->size = new_size; + fd->offset = cur_size; + break; + } + data_spix--; + } // while all data + + // update object indices if (cur_objix_spix == 0) { - // get data page from object index header page - data_pix = ((spiffs_page_ix*)((u8_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[data_spix]; - ((spiffs_page_ix*)((u8_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[data_spix] = SPIFFS_OBJ_ID_FREE; - } else { - // get data page from object index page - data_pix = ((spiffs_page_ix*)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)]; - ((spiffs_page_ix*)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)] = SPIFFS_OBJ_ID_FREE; - } - - SPIFFS_DBG("truncate: got data pix "_SPIPRIpg"\n", data_pix); - - if (new_size == 0 || remove_full || cur_size - new_size >= SPIFFS_DATA_PAGE_SIZE(fs)) { - // delete full data page - res = spiffs_page_data_check(fs, fd, data_pix, data_spix); - if (res != SPIFFS_ERR_DELETED && res != SPIFFS_OK && res != SPIFFS_ERR_INDEX_REF_FREE) { - SPIFFS_DBG("truncate: err validating data pix "_SPIPRIi"\n", res); - break; - } - - if (res == SPIFFS_OK) { - res = spiffs_page_delete(fs, data_pix); - if (res != SPIFFS_OK) { - SPIFFS_DBG("truncate: err deleting data pix "_SPIPRIi"\n", res); - break; - } - } else if (res == SPIFFS_ERR_DELETED || res == SPIFFS_ERR_INDEX_REF_FREE) { - res = SPIFFS_OK; - } - - // update current size - if (cur_size % SPIFFS_DATA_PAGE_SIZE(fs) == 0) { - cur_size -= SPIFFS_DATA_PAGE_SIZE(fs); - } else { - cur_size -= cur_size % SPIFFS_DATA_PAGE_SIZE(fs); - } - fd->size = cur_size; - fd->offset = cur_size; - SPIFFS_DBG("truncate: delete data page "_SPIPRIpg" for data spix:"_SPIPRIsp", cur_size:"_SPIPRIi"\n", data_pix, data_spix, cur_size); - } else { - // delete last page, partially - spiffs_page_header p_hdr; - spiffs_page_ix new_data_pix; - u32_t bytes_to_remove = SPIFFS_DATA_PAGE_SIZE(fs) - (new_size % SPIFFS_DATA_PAGE_SIZE(fs)); - SPIFFS_DBG("truncate: delete "_SPIPRIi" bytes from data page "_SPIPRIpg" for data spix:"_SPIPRIsp", cur_size:"_SPIPRIi"\n", bytes_to_remove, data_pix, data_spix, cur_size); - - res = spiffs_page_data_check(fs, fd, data_pix, data_spix); - if (res != SPIFFS_OK) break; - - p_hdr.obj_id = fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG; - p_hdr.span_ix = data_spix; - p_hdr.flags = 0xff; - // allocate new page and copy unmodified data - res = spiffs_page_allocate_data(fs, fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, - &p_hdr, 0, 0, 0, 0, &new_data_pix); - if (res != SPIFFS_OK) break; - res = spiffs_phys_cpy(fs, 0, - SPIFFS_PAGE_TO_PADDR(fs, new_data_pix) + sizeof(spiffs_page_header), - SPIFFS_PAGE_TO_PADDR(fs, data_pix) + sizeof(spiffs_page_header), - SPIFFS_DATA_PAGE_SIZE(fs) - bytes_to_remove); - if (res != SPIFFS_OK) break; - // delete original data page - res = spiffs_page_delete(fs, data_pix); - if (res != SPIFFS_OK) break; - p_hdr.flags &= ~SPIFFS_PH_FLAG_FINAL; - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, - fd->file_nbr, - SPIFFS_PAGE_TO_PADDR(fs, new_data_pix) + offsetof(spiffs_page_header, flags), - sizeof(u8_t), - (u8_t *)&p_hdr.flags); - if (res != SPIFFS_OK) break; - - // update memory representation of object index page with new data page - if (cur_objix_spix == 0) { // update object index header page - ((spiffs_page_ix*)((u8_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[data_spix] = new_data_pix; - SPIFFS_DBG("truncate: wrote page "_SPIPRIpg" to objix_hdr entry "_SPIPRIsp" in mem\n", new_data_pix, (spiffs_span_ix)SPIFFS_OBJ_IX_ENTRY(fs, data_spix)); - } else { - // update object index page - ((spiffs_page_ix*)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)] = new_data_pix; - SPIFFS_DBG("truncate: wrote page "_SPIPRIpg" to objix entry "_SPIPRIsp" in mem\n", new_data_pix, (spiffs_span_ix)SPIFFS_OBJ_IX_ENTRY(fs, data_spix)); - } - cur_size = new_size; - fd->size = new_size; - fd->offset = cur_size; - break; - } - data_spix--; - } // while all data + if (cur_size == 0) { + if (remove_full) { + // remove object altogether + SPIFFS_DBG("truncate: remove object index header page "_SPIPRIpg"\n", objix_pix); - // update object indices - if (cur_objix_spix == 0) { - // update object index header page - if (cur_size == 0) { - if (remove_full) { - // remove object altogether - SPIFFS_DBG("truncate: remove object index header page "_SPIPRIpg"\n", objix_pix); + res = spiffs_page_index_check(fs, fd, objix_pix, 0); + SPIFFS_CHECK_RES(res); - res = spiffs_page_index_check(fs, fd, objix_pix, 0); - SPIFFS_CHECK_RES(res); - - res = spiffs_page_delete(fs, objix_pix); - SPIFFS_CHECK_RES(res); - spiffs_cb_object_event(fs, (spiffs_page_object_ix *)0, - SPIFFS_EV_IX_DEL, fd->obj_id, 0, objix_pix, 0); - } else { - // make uninitialized object - SPIFFS_DBG("truncate: reset objix_hdr page "_SPIPRIpg"\n", objix_pix); - memset(fs->work + sizeof(spiffs_page_object_ix_header), 0xff, - SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_page_object_ix_header)); - res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, - objix_pix, fs->work, 0, 0, SPIFFS_UNDEFINED_LEN, &new_objix_hdr_pix); - SPIFFS_CHECK_RES(res); - } + res = spiffs_page_delete(fs, objix_pix); + SPIFFS_CHECK_RES(res); + spiffs_cb_object_event(fs, (spiffs_page_object_ix *)0, + SPIFFS_EV_IX_DEL, fd->obj_id, 0, objix_pix, 0); + } else { + // make uninitialized object + SPIFFS_DBG("truncate: reset objix_hdr page "_SPIPRIpg"\n", objix_pix); + memset(fs->work + sizeof(spiffs_page_object_ix_header), 0xff, + SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_page_object_ix_header)); + res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, + objix_pix, fs->work, 0, 0, SPIFFS_UNDEFINED_LEN, &new_objix_hdr_pix); + SPIFFS_CHECK_RES(res); + } + } else { + // update object index header page + SPIFFS_DBGF("truncate: update object index header page with indices and size\n"); + res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, + objix_pix, fs->work, 0, 0, cur_size, &new_objix_hdr_pix); + SPIFFS_CHECK_RES(res); + } } else { - // update object index header page - SPIFFS_DBGF("truncate: update object index header page with indices and size\n"); - res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, - objix_pix, fs->work, 0, 0, cur_size, &new_objix_hdr_pix); - SPIFFS_CHECK_RES(res); + // update both current object index page and object index header page + spiffs_page_ix new_objix_pix; + + res = spiffs_page_index_check(fs, fd, objix_pix, cur_objix_spix); + SPIFFS_CHECK_RES(res); + + // move and update object index page + res = spiffs_page_move(fs, fd->file_nbr, (u8_t *)objix_hdr, fd->obj_id, 0, objix_pix, &new_objix_pix); + SPIFFS_CHECK_RES(res); + spiffs_cb_object_event(fs, (spiffs_page_object_ix *)objix_hdr, + SPIFFS_EV_IX_UPD, fd->obj_id, objix->p_hdr.span_ix, new_objix_pix, 0); + SPIFFS_DBG("truncate: store modified objix page, "_SPIPRIpg":"_SPIPRIsp"\n", new_objix_pix, cur_objix_spix); + fd->cursor_objix_pix = new_objix_pix; + fd->cursor_objix_spix = cur_objix_spix; + fd->offset = cur_size; + // update object index header page with new size + res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, + fd->objix_hdr_pix, 0, 0, 0, cur_size, &new_objix_hdr_pix); + SPIFFS_CHECK_RES(res); } - } else { - // update both current object index page and object index header page - spiffs_page_ix new_objix_pix; + fd->size = cur_size; - res = spiffs_page_index_check(fs, fd, objix_pix, cur_objix_spix); - SPIFFS_CHECK_RES(res); - - // move and update object index page - res = spiffs_page_move(fs, fd->file_nbr, (u8_t*)objix_hdr, fd->obj_id, 0, objix_pix, &new_objix_pix); - SPIFFS_CHECK_RES(res); - spiffs_cb_object_event(fs, (spiffs_page_object_ix *)objix_hdr, - SPIFFS_EV_IX_UPD, fd->obj_id, objix->p_hdr.span_ix, new_objix_pix, 0); - SPIFFS_DBG("truncate: store modified objix page, "_SPIPRIpg":"_SPIPRIsp"\n", new_objix_pix, cur_objix_spix); - fd->cursor_objix_pix = new_objix_pix; - fd->cursor_objix_spix = cur_objix_spix; - fd->offset = cur_size; - // update object index header page with new size - res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, - fd->objix_hdr_pix, 0, 0, 0, cur_size, &new_objix_hdr_pix); - SPIFFS_CHECK_RES(res); - } - fd->size = cur_size; - - return res; + return res; } // spiffs_object_truncate #endif // !SPIFFS_READ_ONLY @@ -1969,162 +1968,162 @@ s32_t spiffs_object_read( u32_t offset, u32_t len, u8_t *dst) { - s32_t res = SPIFFS_OK; - spiffs *fs = fd->fs; - spiffs_page_ix objix_pix; - spiffs_page_ix data_pix; - spiffs_span_ix data_spix = offset / SPIFFS_DATA_PAGE_SIZE(fs); - u32_t cur_offset = offset; - spiffs_span_ix cur_objix_spix; - spiffs_span_ix prev_objix_spix = (spiffs_span_ix)-1; - spiffs_page_object_ix_header *objix_hdr = (spiffs_page_object_ix_header *)fs->work; - spiffs_page_object_ix *objix = (spiffs_page_object_ix *)fs->work; + s32_t res = SPIFFS_OK; + spiffs *fs = fd->fs; + spiffs_page_ix objix_pix; + spiffs_page_ix data_pix; + spiffs_span_ix data_spix = offset / SPIFFS_DATA_PAGE_SIZE(fs); + u32_t cur_offset = offset; + spiffs_span_ix cur_objix_spix; + spiffs_span_ix prev_objix_spix = (spiffs_span_ix) - 1; + spiffs_page_object_ix_header *objix_hdr = (spiffs_page_object_ix_header *)fs->work; + spiffs_page_object_ix *objix = (spiffs_page_object_ix *)fs->work; - while (cur_offset < offset + len) { + while (cur_offset < offset + len) { #if SPIFFS_IX_MAP - // check if we have a memory, index map and if so, if we're within index map's range - // and if so, if the entry is populated - if (fd->ix_map && data_spix >= fd->ix_map->start_spix && data_spix <= fd->ix_map->end_spix - && fd->ix_map->map_buf[data_spix - fd->ix_map->start_spix]) { - data_pix = fd->ix_map->map_buf[data_spix - fd->ix_map->start_spix]; - } else { -#endif - cur_objix_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, data_spix); - if (prev_objix_spix != cur_objix_spix) { - // load current object index (header) page - if (cur_objix_spix == 0) { - objix_pix = fd->objix_hdr_pix; + // check if we have a memory, index map and if so, if we're within index map's range + // and if so, if the entry is populated + if (fd->ix_map && data_spix >= fd->ix_map->start_spix && data_spix <= fd->ix_map->end_spix + && fd->ix_map->map_buf[data_spix - fd->ix_map->start_spix]) { + data_pix = fd->ix_map->map_buf[data_spix - fd->ix_map->start_spix]; } else { - SPIFFS_DBG("read: find objix "_SPIPRIid":"_SPIPRIsp"\n", fd->obj_id, cur_objix_spix); - if (fd->cursor_objix_spix == cur_objix_spix) { - objix_pix = fd->cursor_objix_pix; - } else { - res = spiffs_obj_lu_find_id_and_span(fs, fd->obj_id | SPIFFS_OBJ_ID_IX_FLAG, cur_objix_spix, 0, &objix_pix); - SPIFFS_CHECK_RES(res); - } - } - SPIFFS_DBG("read: load objix page "_SPIPRIpg":"_SPIPRIsp" for data spix:"_SPIPRIsp"\n", objix_pix, cur_objix_spix, data_spix); - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, - fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); - SPIFFS_CHECK_RES(res); - SPIFFS_VALIDATE_OBJIX(objix->p_hdr, fd->obj_id, cur_objix_spix); - - fd->offset = cur_offset; - fd->cursor_objix_pix = objix_pix; - fd->cursor_objix_spix = cur_objix_spix; - - prev_objix_spix = cur_objix_spix; - } - - if (cur_objix_spix == 0) { - // get data page from object index header page - data_pix = ((spiffs_page_ix*)((u8_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[data_spix]; - } else { - // get data page from object index page - data_pix = ((spiffs_page_ix*)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)]; - } -#if SPIFFS_IX_MAP - } #endif - // all remaining data - u32_t len_to_read = offset + len - cur_offset; - // remaining data in page - len_to_read = MIN(len_to_read, SPIFFS_DATA_PAGE_SIZE(fs) - (cur_offset % SPIFFS_DATA_PAGE_SIZE(fs))); - // remaining data in file - len_to_read = MIN(len_to_read, fd->size - cur_offset); - SPIFFS_DBG("read: offset:"_SPIPRIi" rd:"_SPIPRIi" data spix:"_SPIPRIsp" is data_pix:"_SPIPRIpg" addr:"_SPIPRIad"\n", cur_offset, len_to_read, data_spix, data_pix, - (u32_t)(SPIFFS_PAGE_TO_PADDR(fs, data_pix) + sizeof(spiffs_page_header) + (cur_offset % SPIFFS_DATA_PAGE_SIZE(fs)))); - if (len_to_read <= 0) { - res = SPIFFS_ERR_END_OF_OBJECT; - break; - } - res = spiffs_page_data_check(fs, fd, data_pix, data_spix); - SPIFFS_CHECK_RES(res); - res = _spiffs_rd( - fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_READ, - fd->file_nbr, - SPIFFS_PAGE_TO_PADDR(fs, data_pix) + sizeof(spiffs_page_header) + (cur_offset % SPIFFS_DATA_PAGE_SIZE(fs)), - len_to_read, - dst); - SPIFFS_CHECK_RES(res); - dst += len_to_read; - cur_offset += len_to_read; - fd->offset = cur_offset; - data_spix++; - } + cur_objix_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, data_spix); + if (prev_objix_spix != cur_objix_spix) { + // load current object index (header) page + if (cur_objix_spix == 0) { + objix_pix = fd->objix_hdr_pix; + } else { + SPIFFS_DBG("read: find objix "_SPIPRIid":"_SPIPRIsp"\n", fd->obj_id, cur_objix_spix); + if (fd->cursor_objix_spix == cur_objix_spix) { + objix_pix = fd->cursor_objix_pix; + } else { + res = spiffs_obj_lu_find_id_and_span(fs, fd->obj_id | SPIFFS_OBJ_ID_IX_FLAG, cur_objix_spix, 0, &objix_pix); + SPIFFS_CHECK_RES(res); + } + } + SPIFFS_DBG("read: load objix page "_SPIPRIpg":"_SPIPRIsp" for data spix:"_SPIPRIsp"\n", objix_pix, cur_objix_spix, data_spix); + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, + fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); + SPIFFS_CHECK_RES(res); + SPIFFS_VALIDATE_OBJIX(objix->p_hdr, fd->obj_id, cur_objix_spix); - return res; + fd->offset = cur_offset; + fd->cursor_objix_pix = objix_pix; + fd->cursor_objix_spix = cur_objix_spix; + + prev_objix_spix = cur_objix_spix; + } + + if (cur_objix_spix == 0) { + // get data page from object index header page + data_pix = ((spiffs_page_ix *)((u8_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[data_spix]; + } else { + // get data page from object index page + data_pix = ((spiffs_page_ix *)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)]; + } +#if SPIFFS_IX_MAP + } +#endif + // all remaining data + u32_t len_to_read = offset + len - cur_offset; + // remaining data in page + len_to_read = MIN(len_to_read, SPIFFS_DATA_PAGE_SIZE(fs) - (cur_offset % SPIFFS_DATA_PAGE_SIZE(fs))); + // remaining data in file + len_to_read = MIN(len_to_read, fd->size - cur_offset); + SPIFFS_DBG("read: offset:"_SPIPRIi" rd:"_SPIPRIi" data spix:"_SPIPRIsp" is data_pix:"_SPIPRIpg" addr:"_SPIPRIad"\n", cur_offset, len_to_read, data_spix, data_pix, + (u32_t)(SPIFFS_PAGE_TO_PADDR(fs, data_pix) + sizeof(spiffs_page_header) + (cur_offset % SPIFFS_DATA_PAGE_SIZE(fs)))); + if (len_to_read <= 0) { + res = SPIFFS_ERR_END_OF_OBJECT; + break; + } + res = spiffs_page_data_check(fs, fd, data_pix, data_spix); + SPIFFS_CHECK_RES(res); + res = _spiffs_rd( + fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_READ, + fd->file_nbr, + SPIFFS_PAGE_TO_PADDR(fs, data_pix) + sizeof(spiffs_page_header) + (cur_offset % SPIFFS_DATA_PAGE_SIZE(fs)), + len_to_read, + dst); + SPIFFS_CHECK_RES(res); + dst += len_to_read; + cur_offset += len_to_read; + fd->offset = cur_offset; + data_spix++; + } + + return res; } #if !SPIFFS_READ_ONLY typedef struct { - spiffs_obj_id min_obj_id; - spiffs_obj_id max_obj_id; - u32_t compaction; - const u8_t *conflicting_name; + spiffs_obj_id min_obj_id; + spiffs_obj_id max_obj_id; + u32_t compaction; + const u8_t *conflicting_name; } spiffs_free_obj_id_state; static s32_t spiffs_obj_lu_find_free_obj_id_bitmap_v(spiffs *fs, spiffs_obj_id id, spiffs_block_ix bix, int ix_entry, - const void *user_const_p, void *user_var_p) { - if (id != SPIFFS_OBJ_ID_FREE && id != SPIFFS_OBJ_ID_DELETED) { - spiffs_obj_id min_obj_id = *((spiffs_obj_id*)user_var_p); - const u8_t *conflicting_name = (const u8_t*)user_const_p; + const void *user_const_p, void *user_var_p) { + if (id != SPIFFS_OBJ_ID_FREE && id != SPIFFS_OBJ_ID_DELETED) { + spiffs_obj_id min_obj_id = *((spiffs_obj_id *)user_var_p); + const u8_t *conflicting_name = (const u8_t *)user_const_p; - // if conflicting name parameter is given, also check if this name is found in object index hdrs - if (conflicting_name && (id & SPIFFS_OBJ_ID_IX_FLAG)) { - spiffs_page_ix pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, ix_entry); - int res; - spiffs_page_object_ix_header objix_hdr; - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, - 0, SPIFFS_PAGE_TO_PADDR(fs, pix), sizeof(spiffs_page_object_ix_header), (u8_t *)&objix_hdr); - SPIFFS_CHECK_RES(res); - if (objix_hdr.p_hdr.span_ix == 0 && - (objix_hdr.p_hdr.flags & (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_IXDELE)) == - (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_IXDELE)) { - if (strcmp((const char*)user_const_p, (char*)objix_hdr.name) == 0) { - return SPIFFS_ERR_CONFLICTING_NAME; + // if conflicting name parameter is given, also check if this name is found in object index hdrs + if (conflicting_name && (id & SPIFFS_OBJ_ID_IX_FLAG)) { + spiffs_page_ix pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, ix_entry); + int res; + spiffs_page_object_ix_header objix_hdr; + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, + 0, SPIFFS_PAGE_TO_PADDR(fs, pix), sizeof(spiffs_page_object_ix_header), (u8_t *)&objix_hdr); + SPIFFS_CHECK_RES(res); + if (objix_hdr.p_hdr.span_ix == 0 && + (objix_hdr.p_hdr.flags & (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_IXDELE)) == + (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_IXDELE)) { + if (strcmp((const char *)user_const_p, (char *)objix_hdr.name) == 0) { + return SPIFFS_ERR_CONFLICTING_NAME; + } + } } - } - } - id &= ~SPIFFS_OBJ_ID_IX_FLAG; - u32_t bit_ix = (id-min_obj_id) & 7; - int byte_ix = (id-min_obj_id) >> 3; - if (byte_ix >= 0 && (u32_t)byte_ix < SPIFFS_CFG_LOG_PAGE_SZ(fs)) { - fs->work[byte_ix] |= (1<> 3; + if (byte_ix >= 0 && (u32_t)byte_ix < SPIFFS_CFG_LOG_PAGE_SZ(fs)) { + fs->work[byte_ix] |= (1 << bit_ix); + } } - } - return SPIFFS_VIS_COUNTINUE; + return SPIFFS_VIS_COUNTINUE; } static s32_t spiffs_obj_lu_find_free_obj_id_compact_v(spiffs *fs, spiffs_obj_id id, spiffs_block_ix bix, int ix_entry, - const void *user_const_p, void *user_var_p) { - (void)user_var_p; - if (id != SPIFFS_OBJ_ID_FREE && id != SPIFFS_OBJ_ID_DELETED && (id & SPIFFS_OBJ_ID_IX_FLAG)) { - s32_t res; - const spiffs_free_obj_id_state *state = (const spiffs_free_obj_id_state*)user_const_p; - spiffs_page_object_ix_header objix_hdr; + const void *user_const_p, void *user_var_p) { + (void)user_var_p; + if (id != SPIFFS_OBJ_ID_FREE && id != SPIFFS_OBJ_ID_DELETED && (id & SPIFFS_OBJ_ID_IX_FLAG)) { + s32_t res; + const spiffs_free_obj_id_state *state = (const spiffs_free_obj_id_state *)user_const_p; + spiffs_page_object_ix_header objix_hdr; - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, - 0, SPIFFS_OBJ_LOOKUP_ENTRY_TO_PADDR(fs, bix, ix_entry), sizeof(spiffs_page_object_ix_header), (u8_t*)&objix_hdr); - if (res == SPIFFS_OK && objix_hdr.p_hdr.span_ix == 0 && - ((objix_hdr.p_hdr.flags & (SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_DELET)) == - (SPIFFS_PH_FLAG_DELET))) { - // ok object look up entry - if (state->conflicting_name && strcmp((const char *)state->conflicting_name, (char *)objix_hdr.name) == 0) { - return SPIFFS_ERR_CONFLICTING_NAME; - } + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, + 0, SPIFFS_OBJ_LOOKUP_ENTRY_TO_PADDR(fs, bix, ix_entry), sizeof(spiffs_page_object_ix_header), (u8_t *)&objix_hdr); + if (res == SPIFFS_OK && objix_hdr.p_hdr.span_ix == 0 && + ((objix_hdr.p_hdr.flags & (SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_DELET)) == + (SPIFFS_PH_FLAG_DELET))) { + // ok object look up entry + if (state->conflicting_name && strcmp((const char *)state->conflicting_name, (char *)objix_hdr.name) == 0) { + return SPIFFS_ERR_CONFLICTING_NAME; + } - id &= ~SPIFFS_OBJ_ID_IX_FLAG; - if (id >= state->min_obj_id && id <= state->max_obj_id) { - u8_t *map = (u8_t *)fs->work; - int ix = (id - state->min_obj_id) / state->compaction; - //SPIFFS_DBG("free_obj_id: add ix "_SPIPRIi" for id "_SPIPRIid" min"_SPIPRIid" max"_SPIPRIid" comp:"_SPIPRIi"\n", ix, id, state->min_obj_id, state->max_obj_id, state->compaction); - map[ix]++; - } + id &= ~SPIFFS_OBJ_ID_IX_FLAG; + if (id >= state->min_obj_id && id <= state->max_obj_id) { + u8_t *map = (u8_t *)fs->work; + int ix = (id - state->min_obj_id) / state->compaction; + //SPIFFS_DBG("free_obj_id: add ix "_SPIPRIi" for id "_SPIPRIid" min"_SPIPRIid" max"_SPIPRIid" comp:"_SPIPRIi"\n", ix, id, state->min_obj_id, state->max_obj_id, state->compaction); + map[ix]++; + } + } } - } - return SPIFFS_VIS_COUNTINUE; + return SPIFFS_VIS_COUNTINUE; } // Scans thru all object lookup for object index header pages. If total possible number of @@ -2132,218 +2131,218 @@ static s32_t spiffs_obj_lu_find_free_obj_id_compact_v(spiffs *fs, spiffs_obj_id // object ids is found, the object lu is again scanned for object ids within group and bitmasked. // Finally, the bitmask is searched for a free id s32_t spiffs_obj_lu_find_free_obj_id(spiffs *fs, spiffs_obj_id *obj_id, const u8_t *conflicting_name) { - s32_t res = SPIFFS_OK; - u32_t max_objects = (fs->block_count * SPIFFS_OBJ_LOOKUP_MAX_ENTRIES(fs)) / 2; - spiffs_free_obj_id_state state; - spiffs_obj_id free_obj_id = SPIFFS_OBJ_ID_FREE; - state.min_obj_id = 1; - state.max_obj_id = max_objects + 1; - if (state.max_obj_id & SPIFFS_OBJ_ID_IX_FLAG) { - state.max_obj_id = ((spiffs_obj_id)-1) & ~SPIFFS_OBJ_ID_IX_FLAG; - } - state.compaction = 0; - state.conflicting_name = conflicting_name; - while (res == SPIFFS_OK && free_obj_id == SPIFFS_OBJ_ID_FREE) { - if (state.max_obj_id - state.min_obj_id <= (spiffs_obj_id)SPIFFS_CFG_LOG_PAGE_SZ(fs)*8) { - // possible to represent in bitmap - u32_t i, j; - SPIFFS_DBG("free_obj_id: BITM min:"_SPIPRIid" max:"_SPIPRIid"\n", state.min_obj_id, state.max_obj_id); - - memset(fs->work, 0, SPIFFS_CFG_LOG_PAGE_SZ(fs)); - res = spiffs_obj_lu_find_entry_visitor(fs, 0, 0, 0, 0, spiffs_obj_lu_find_free_obj_id_bitmap_v, - conflicting_name, &state.min_obj_id, 0, 0); - if (res == SPIFFS_VIS_END) res = SPIFFS_OK; - SPIFFS_CHECK_RES(res); - // traverse bitmask until found free obj_id - for (i = 0; i < SPIFFS_CFG_LOG_PAGE_SZ(fs); i++) { - u8_t mask = fs->work[i]; - if (mask == 0xff) { - continue; - } - for (j = 0; j < 8; j++) { - if ((mask & (1<work; - u8_t min_count = 0xff; - - for (i = 0; i < SPIFFS_CFG_LOG_PAGE_SZ(fs)/sizeof(u8_t); i++) { - if (map[i] < min_count) { - min_count = map[i]; - min_i = i; - if (min_count == 0) { - break; - } - } - } - - if (min_count == state.compaction) { - // there are no free objids! - SPIFFS_DBGF("free_obj_id: compacted table is full\n"); - return SPIFFS_ERR_FULL; - } - - SPIFFS_DBG("free_obj_id: COMP select index:"_SPIPRIi" min_count:"_SPIPRIi" min:"_SPIPRIid" max:"_SPIPRIid" compact:"_SPIPRIi"\n", min_i, min_count, state.min_obj_id, state.max_obj_id, state.compaction); - - if (min_count == 0) { - // no id in this range, skip compacting and use directly - *obj_id = min_i * state.compaction + state.min_obj_id; - return SPIFFS_OK; - } else { - SPIFFS_DBG("free_obj_id: COMP SEL chunk:"_SPIPRIi" min:"_SPIPRIid" -> "_SPIPRIid"\n", state.compaction, state.min_obj_id, state.min_obj_id + min_i * state.compaction); - state.min_obj_id += min_i * state.compaction; - state.max_obj_id = state.min_obj_id + state.compaction; - // decrease compaction - } - if ((state.max_obj_id - state.min_obj_id <= (spiffs_obj_id)SPIFFS_CFG_LOG_PAGE_SZ(fs)*8)) { - // no need for compacting, use bitmap - continue; - } - } - // in a work memory of log_page_size bytes, we may fit in log_page_size ids - // todo what if compaction is > 255 - then we cannot fit it in a byte - state.compaction = (state.max_obj_id-state.min_obj_id) / ((SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(u8_t))); - SPIFFS_DBG("free_obj_id: COMP min:"_SPIPRIid" max:"_SPIPRIid" compact:"_SPIPRIi"\n", state.min_obj_id, state.max_obj_id, state.compaction); - - memset(fs->work, 0, SPIFFS_CFG_LOG_PAGE_SZ(fs)); - res = spiffs_obj_lu_find_entry_visitor(fs, 0, 0, 0, 0, spiffs_obj_lu_find_free_obj_id_compact_v, &state, 0, 0, 0); - if (res == SPIFFS_VIS_END) res = SPIFFS_OK; - SPIFFS_CHECK_RES(res); - state.conflicting_name = 0; // searched for conflicting name once, no need to do it again + s32_t res = SPIFFS_OK; + u32_t max_objects = (fs->block_count * SPIFFS_OBJ_LOOKUP_MAX_ENTRIES(fs)) / 2; + spiffs_free_obj_id_state state; + spiffs_obj_id free_obj_id = SPIFFS_OBJ_ID_FREE; + state.min_obj_id = 1; + state.max_obj_id = max_objects + 1; + if (state.max_obj_id & SPIFFS_OBJ_ID_IX_FLAG) { + state.max_obj_id = ((spiffs_obj_id) - 1) & ~SPIFFS_OBJ_ID_IX_FLAG; } - } + state.compaction = 0; + state.conflicting_name = conflicting_name; + while (res == SPIFFS_OK && free_obj_id == SPIFFS_OBJ_ID_FREE) { + if (state.max_obj_id - state.min_obj_id <= (spiffs_obj_id)SPIFFS_CFG_LOG_PAGE_SZ(fs) * 8) { + // possible to represent in bitmap + u32_t i, j; + SPIFFS_DBG("free_obj_id: BITM min:"_SPIPRIid" max:"_SPIPRIid"\n", state.min_obj_id, state.max_obj_id); - return res; + memset(fs->work, 0, SPIFFS_CFG_LOG_PAGE_SZ(fs)); + res = spiffs_obj_lu_find_entry_visitor(fs, 0, 0, 0, 0, spiffs_obj_lu_find_free_obj_id_bitmap_v, + conflicting_name, &state.min_obj_id, 0, 0); + if (res == SPIFFS_VIS_END) res = SPIFFS_OK; + SPIFFS_CHECK_RES(res); + // traverse bitmask until found free obj_id + for (i = 0; i < SPIFFS_CFG_LOG_PAGE_SZ(fs); i++) { + u8_t mask = fs->work[i]; + if (mask == 0xff) { + continue; + } + for (j = 0; j < 8; j++) { + if ((mask & (1 << j)) == 0) { + *obj_id = (i << 3) + j + state.min_obj_id; + return SPIFFS_OK; + } + } + } + return SPIFFS_ERR_FULL; + } else { + // not possible to represent all ids in range in a bitmap, compact and count + if (state.compaction != 0) { + // select element in compacted table, decrease range and recompact + u32_t i, min_i = 0; + u8_t *map = (u8_t *)fs->work; + u8_t min_count = 0xff; + + for (i = 0; i < SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(u8_t); i++) { + if (map[i] < min_count) { + min_count = map[i]; + min_i = i; + if (min_count == 0) { + break; + } + } + } + + if (min_count == state.compaction) { + // there are no free objids! + SPIFFS_DBGF("free_obj_id: compacted table is full\n"); + return SPIFFS_ERR_FULL; + } + + SPIFFS_DBG("free_obj_id: COMP select index:"_SPIPRIi" min_count:"_SPIPRIi" min:"_SPIPRIid" max:"_SPIPRIid" compact:"_SPIPRIi"\n", min_i, min_count, state.min_obj_id, state.max_obj_id, state.compaction); + + if (min_count == 0) { + // no id in this range, skip compacting and use directly + *obj_id = min_i * state.compaction + state.min_obj_id; + return SPIFFS_OK; + } else { + SPIFFS_DBG("free_obj_id: COMP SEL chunk:"_SPIPRIi" min:"_SPIPRIid" -> "_SPIPRIid"\n", state.compaction, state.min_obj_id, state.min_obj_id + min_i * state.compaction); + state.min_obj_id += min_i * state.compaction; + state.max_obj_id = state.min_obj_id + state.compaction; + // decrease compaction + } + if ((state.max_obj_id - state.min_obj_id <= (spiffs_obj_id)SPIFFS_CFG_LOG_PAGE_SZ(fs) * 8)) { + // no need for compacting, use bitmap + continue; + } + } + // in a work memory of log_page_size bytes, we may fit in log_page_size ids + // todo what if compaction is > 255 - then we cannot fit it in a byte + state.compaction = (state.max_obj_id - state.min_obj_id) / ((SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(u8_t))); + SPIFFS_DBG("free_obj_id: COMP min:"_SPIPRIid" max:"_SPIPRIid" compact:"_SPIPRIi"\n", state.min_obj_id, state.max_obj_id, state.compaction); + + memset(fs->work, 0, SPIFFS_CFG_LOG_PAGE_SZ(fs)); + res = spiffs_obj_lu_find_entry_visitor(fs, 0, 0, 0, 0, spiffs_obj_lu_find_free_obj_id_compact_v, &state, 0, 0, 0); + if (res == SPIFFS_VIS_END) res = SPIFFS_OK; + SPIFFS_CHECK_RES(res); + state.conflicting_name = 0; // searched for conflicting name once, no need to do it again + } + } + + return res; } #endif // !SPIFFS_READ_ONLY #if SPIFFS_TEMPORAL_FD_CACHE // djb2 hash static u32_t spiffs_hash(spiffs *fs, const u8_t *name) { - (void)fs; - u32_t hash = 5381; - u8_t c; - int i = 0; - while ((c = name[i++]) && i < SPIFFS_OBJ_NAME_LEN) { - hash = (hash * 33) ^ c; - } - return hash; + (void)fs; + u32_t hash = 5381; + u8_t c; + int i = 0; + while ((c = name[i++]) && i < SPIFFS_OBJ_NAME_LEN) { + hash = (hash * 33) ^ c; + } + return hash; } #endif s32_t spiffs_fd_find_new(spiffs *fs, spiffs_fd **fd, const char *name) { #if SPIFFS_TEMPORAL_FD_CACHE - u32_t i; - u16_t min_score = 0xffff; - u32_t cand_ix = (u32_t)-1; - u32_t name_hash = name ? spiffs_hash(fs, (const u8_t *)name) : 0; - spiffs_fd *fds = (spiffs_fd *)fs->fd_space; + u32_t i; + u16_t min_score = 0xffff; + u32_t cand_ix = (u32_t) -1; + u32_t name_hash = name ? spiffs_hash(fs, (const u8_t *)name) : 0; + spiffs_fd *fds = (spiffs_fd *)fs->fd_space; - if (name) { - // first, decrease score of all closed descriptors - for (i = 0; i < fs->fd_count; i++) { - spiffs_fd *cur_fd = &fds[i]; - if (cur_fd->file_nbr == 0) { - if (cur_fd->score > 1) { // score == 0 indicates never used fd - cur_fd->score--; - } - } - } - } - - // find the free fd with least score or name match - for (i = 0; i < fs->fd_count; i++) { - spiffs_fd *cur_fd = &fds[i]; - if (cur_fd->file_nbr == 0) { - if (name && cur_fd->name_hash == name_hash) { - cand_ix = i; - break; - } - if (cur_fd->score < min_score) { - min_score = cur_fd->score; - cand_ix = i; - } - } - } - - if (cand_ix != (u32_t)-1) { - spiffs_fd *cur_fd = &fds[cand_ix]; if (name) { - if (cur_fd->name_hash == name_hash && cur_fd->score > 0) { - // opened an fd with same name hash, assume same file - // set search point to saved obj index page and hope we have a correct match directly - // when start searching - if not, we will just keep searching until it is found - fs->cursor_block_ix = SPIFFS_BLOCK_FOR_PAGE(fs, cur_fd->objix_hdr_pix); - fs->cursor_obj_lu_entry = SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(fs, cur_fd->objix_hdr_pix); - // update score - if (cur_fd->score < 0xffff-SPIFFS_TEMPORAL_CACHE_HIT_SCORE) { - cur_fd->score += SPIFFS_TEMPORAL_CACHE_HIT_SCORE; - } else { - cur_fd->score = 0xffff; + // first, decrease score of all closed descriptors + for (i = 0; i < fs->fd_count; i++) { + spiffs_fd *cur_fd = &fds[i]; + if (cur_fd->file_nbr == 0) { + if (cur_fd->score > 1) { // score == 0 indicates never used fd + cur_fd->score--; + } + } } - } else { - // no hash hit, restore this fd to initial state - cur_fd->score = SPIFFS_TEMPORAL_CACHE_HIT_SCORE; - cur_fd->name_hash = name_hash; - } } - cur_fd->file_nbr = cand_ix+1; - *fd = cur_fd; - return SPIFFS_OK; - } else { - return SPIFFS_ERR_OUT_OF_FILE_DESCS; - } + + // find the free fd with least score or name match + for (i = 0; i < fs->fd_count; i++) { + spiffs_fd *cur_fd = &fds[i]; + if (cur_fd->file_nbr == 0) { + if (name && cur_fd->name_hash == name_hash) { + cand_ix = i; + break; + } + if (cur_fd->score < min_score) { + min_score = cur_fd->score; + cand_ix = i; + } + } + } + + if (cand_ix != (u32_t) -1) { + spiffs_fd *cur_fd = &fds[cand_ix]; + if (name) { + if (cur_fd->name_hash == name_hash && cur_fd->score > 0) { + // opened an fd with same name hash, assume same file + // set search point to saved obj index page and hope we have a correct match directly + // when start searching - if not, we will just keep searching until it is found + fs->cursor_block_ix = SPIFFS_BLOCK_FOR_PAGE(fs, cur_fd->objix_hdr_pix); + fs->cursor_obj_lu_entry = SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(fs, cur_fd->objix_hdr_pix); + // update score + if (cur_fd->score < 0xffff - SPIFFS_TEMPORAL_CACHE_HIT_SCORE) { + cur_fd->score += SPIFFS_TEMPORAL_CACHE_HIT_SCORE; + } else { + cur_fd->score = 0xffff; + } + } else { + // no hash hit, restore this fd to initial state + cur_fd->score = SPIFFS_TEMPORAL_CACHE_HIT_SCORE; + cur_fd->name_hash = name_hash; + } + } + cur_fd->file_nbr = cand_ix + 1; + *fd = cur_fd; + return SPIFFS_OK; + } else { + return SPIFFS_ERR_OUT_OF_FILE_DESCS; + } #else - (void)name; - u32_t i; - spiffs_fd *fds = (spiffs_fd *)fs->fd_space; - for (i = 0; i < fs->fd_count; i++) { - spiffs_fd *cur_fd = &fds[i]; - if (cur_fd->file_nbr == 0) { - cur_fd->file_nbr = i+1; - *fd = cur_fd; - return SPIFFS_OK; + (void)name; + u32_t i; + spiffs_fd *fds = (spiffs_fd *)fs->fd_space; + for (i = 0; i < fs->fd_count; i++) { + spiffs_fd *cur_fd = &fds[i]; + if (cur_fd->file_nbr == 0) { + cur_fd->file_nbr = i + 1; + *fd = cur_fd; + return SPIFFS_OK; + } } - } - return SPIFFS_ERR_OUT_OF_FILE_DESCS; + return SPIFFS_ERR_OUT_OF_FILE_DESCS; #endif } s32_t spiffs_fd_return(spiffs *fs, spiffs_file f) { - if (f <= 0 || f > (s16_t)fs->fd_count) { - return SPIFFS_ERR_BAD_DESCRIPTOR; - } - spiffs_fd *fds = (spiffs_fd *)fs->fd_space; - spiffs_fd *fd = &fds[f-1]; - if (fd->file_nbr == 0) { - return SPIFFS_ERR_FILE_CLOSED; - } - fd->file_nbr = 0; + if (f <= 0 || f > (s16_t)fs->fd_count) { + return SPIFFS_ERR_BAD_DESCRIPTOR; + } + spiffs_fd *fds = (spiffs_fd *)fs->fd_space; + spiffs_fd *fd = &fds[f - 1]; + if (fd->file_nbr == 0) { + return SPIFFS_ERR_FILE_CLOSED; + } + fd->file_nbr = 0; #if SPIFFS_IX_MAP - fd->ix_map = 0; + fd->ix_map = 0; #endif - return SPIFFS_OK; + return SPIFFS_OK; } s32_t spiffs_fd_get(spiffs *fs, spiffs_file f, spiffs_fd **fd) { - if (f <= 0 || f > (s16_t)fs->fd_count) { - return SPIFFS_ERR_BAD_DESCRIPTOR; - } - spiffs_fd *fds = (spiffs_fd *)fs->fd_space; - *fd = &fds[f-1]; - if ((*fd)->file_nbr == 0) { - return SPIFFS_ERR_FILE_CLOSED; - } - return SPIFFS_OK; + if (f <= 0 || f > (s16_t)fs->fd_count) { + return SPIFFS_ERR_BAD_DESCRIPTOR; + } + spiffs_fd *fds = (spiffs_fd *)fs->fd_space; + *fd = &fds[f - 1]; + if ((*fd)->file_nbr == 0) { + return SPIFFS_ERR_FILE_CLOSED; + } + return SPIFFS_OK; } #if SPIFFS_TEMPORAL_FD_CACHE @@ -2351,15 +2350,15 @@ void spiffs_fd_temporal_cache_rehash( spiffs *fs, const char *old_path, const char *new_path) { - u32_t i; - u32_t old_hash = spiffs_hash(fs, (const u8_t *)old_path); - u32_t new_hash = spiffs_hash(fs, (const u8_t *)new_path); - spiffs_fd *fds = (spiffs_fd *)fs->fd_space; - for (i = 0; i < fs->fd_count; i++) { - spiffs_fd *cur_fd = &fds[i]; - if (cur_fd->score > 0 && cur_fd->name_hash == old_hash) { - cur_fd->name_hash = new_hash; + u32_t i; + u32_t old_hash = spiffs_hash(fs, (const u8_t *)old_path); + u32_t new_hash = spiffs_hash(fs, (const u8_t *)new_path); + spiffs_fd *fds = (spiffs_fd *)fs->fd_space; + for (i = 0; i < fs->fd_count; i++) { + spiffs_fd *cur_fd = &fds[i]; + if (cur_fd->score > 0 && cur_fd->name_hash == old_hash) { + cur_fd->name_hash = new_hash; + } } - } } #endif diff --git a/armsrc/spiffs_nucleus.h b/armsrc/spiffs_nucleus.h index 255c5aa08..c4a360384 100644 --- a/armsrc/spiffs_nucleus.h +++ b/armsrc/spiffs_nucleus.h @@ -144,15 +144,15 @@ #if defined(__GNUC__) || defined(__clang__) || defined(__TI_COMPILER_VERSION__) - /* For GCC, clang and TI compilers */ +/* For GCC, clang and TI compilers */ #define SPIFFS_PACKED __attribute__((packed)) #elif defined(__ICCARM__) || defined(__CC_ARM) - /* For IAR ARM and Keil MDK-ARM compilers */ -#define SPIFFS_PACKED +/* For IAR ARM and Keil MDK-ARM compilers */ +#define SPIFFS_PACKED #else - /* Unknown compiler */ -#define SPIFFS_PACKED +/* Unknown compiler */ +#define SPIFFS_PACKED #endif @@ -338,7 +338,7 @@ if (((ph).flags & SPIFFS_PH_FLAG_INDEX) != 0) return SPIFFS_ERR_NOT_INDEX; \ if (((objid) & SPIFFS_OBJ_ID_IX_FLAG) == 0) return SPIFFS_ERR_NOT_INDEX; \ if ((ph).span_ix != (spix)) return SPIFFS_ERR_INDEX_SPAN_MISMATCH; - //if ((spix) == 0 && ((ph).flags & SPIFFS_PH_FLAG_IXDELE) == 0) return SPIFFS_ERR_DELETED; +//if ((spix) == 0 && ((ph).flags & SPIFFS_PH_FLAG_IXDELE) == 0) return SPIFFS_ERR_DELETED; #define SPIFFS_VALIDATE_DATA(ph, objid, spix) \ if (((ph).flags & SPIFFS_PH_FLAG_USED) != 0) return SPIFFS_ERR_IS_FREE; \ @@ -399,39 +399,39 @@ // cache page struct typedef struct { - // cache flags - u8_t flags; - // cache page index - u8_t ix; - // last access of this cache page - u32_t last_access; - union { - // type read cache - struct spix { - // read cache page index - spiffs_page_ix pix; - } spix; + // cache flags + u8_t flags; + // cache page index + u8_t ix; + // last access of this cache page + u32_t last_access; + union { + // type read cache + struct spix { + // read cache page index + spiffs_page_ix pix; + } spix; #if SPIFFS_CACHE_WR - // type write cache - struct swrc { - // write cache - spiffs_obj_id obj_id; - // offset in cache page - u32_t offset; - // size of cache page - u16_t size; - } swrc; + // type write cache + struct swrc { + // write cache + spiffs_obj_id obj_id; + // offset in cache page + u32_t offset; + // size of cache page + u16_t size; + } swrc; #endif - } ucache; + } ucache; } spiffs_cache_page; // cache struct typedef struct { - u8_t cpage_count; - u32_t last_access; - u32_t cpage_use_map; - u32_t cpage_use_mask; - u8_t *cpages; + u8_t cpage_count; + u32_t last_access; + u32_t cpage_use_map; + u32_t cpage_use_mask; + u8_t *cpages; } spiffs_cache; #endif @@ -439,38 +439,38 @@ typedef struct { // spiffs nucleus file descriptor typedef struct { - // the filesystem of this descriptor - spiffs *fs; - // number of file descriptor - if 0, the file descriptor is closed - spiffs_file file_nbr; - // object id - if SPIFFS_OBJ_ID_ERASED, the file was deleted - spiffs_obj_id obj_id; - // size of the file - u32_t size; - // cached object index header page index - spiffs_page_ix objix_hdr_pix; - // cached offset object index page index - spiffs_page_ix cursor_objix_pix; - // cached offset object index span index - spiffs_span_ix cursor_objix_spix; - // current absolute offset - u32_t offset; - // current file descriptor offset (cached) - u32_t fdoffset; - // fd flags - spiffs_flags flags; + // the filesystem of this descriptor + spiffs *fs; + // number of file descriptor - if 0, the file descriptor is closed + spiffs_file file_nbr; + // object id - if SPIFFS_OBJ_ID_ERASED, the file was deleted + spiffs_obj_id obj_id; + // size of the file + u32_t size; + // cached object index header page index + spiffs_page_ix objix_hdr_pix; + // cached offset object index page index + spiffs_page_ix cursor_objix_pix; + // cached offset object index span index + spiffs_span_ix cursor_objix_spix; + // current absolute offset + u32_t offset; + // current file descriptor offset (cached) + u32_t fdoffset; + // fd flags + spiffs_flags flags; #if SPIFFS_CACHE_WR - spiffs_cache_page *cache_page; + spiffs_cache_page *cache_page; #endif #if SPIFFS_TEMPORAL_FD_CACHE - // djb2 hash of filename - u32_t name_hash; - // hit score (score == 0 indicates never used fd) - u16_t score; + // djb2 hash of filename + u32_t name_hash; + // hit score (score == 0 indicates never used fd) + u16_t score; #endif #if SPIFFS_IX_MAP - // spiffs index map, if 0 it means unmapped - spiffs_ix_map *ix_map; + // spiffs index map, if 0 it means unmapped + spiffs_ix_map *ix_map; #endif } spiffs_fd; @@ -481,45 +481,46 @@ typedef struct { // NB: this is always aligned when the data page is an object index, // as in this case struct spiffs_page_object_ix is used typedef struct SPIFFS_PACKED { - // object id - spiffs_obj_id obj_id; - // object span index - spiffs_span_ix span_ix; - // flags - u8_t flags; + // object id + spiffs_obj_id obj_id; + // object span index + spiffs_span_ix span_ix; + // flags + u8_t flags; } spiffs_page_header; // object index header page header typedef struct SPIFFS_PACKED #if SPIFFS_ALIGNED_OBJECT_INDEX_TABLES - __attribute(( aligned(sizeof(spiffs_page_ix)) )) +__attribute((aligned(sizeof(spiffs_page_ix)))) #endif { - // common page header - spiffs_page_header p_hdr; - // alignment - u8_t _align[4 - ((sizeof(spiffs_page_header)&3)==0 ? 4 : (sizeof(spiffs_page_header)&3))]; - // size of object - u32_t size; - // type of object - spiffs_obj_type type; - // name of object - u8_t name[SPIFFS_OBJ_NAME_LEN]; + // common page header + spiffs_page_header p_hdr; + // alignment + u8_t _align[4 - ((sizeof(spiffs_page_header) & 3) == 0 ? 4 : (sizeof(spiffs_page_header) & 3))]; + // size of object + u32_t size; + // type of object + spiffs_obj_type type; + // name of object + u8_t name[SPIFFS_OBJ_NAME_LEN]; #if SPIFFS_OBJ_META_LEN - // metadata. not interpreted by SPIFFS in any way. - u8_t meta[SPIFFS_OBJ_META_LEN]; + // metadata. not interpreted by SPIFFS in any way. + u8_t meta[SPIFFS_OBJ_META_LEN]; #endif -} spiffs_page_object_ix_header; +} +spiffs_page_object_ix_header; // object index page header typedef struct SPIFFS_PACKED { - spiffs_page_header p_hdr; - u8_t _align[4 - ((sizeof(spiffs_page_header)&3)==0 ? 4 : (sizeof(spiffs_page_header)&3))]; + spiffs_page_header p_hdr; + u8_t _align[4 - ((sizeof(spiffs_page_header) & 3) == 0 ? 4 : (sizeof(spiffs_page_header) & 3))]; } spiffs_page_object_ix; // callback func for object lookup visitor typedef s32_t (*spiffs_visitor_f)(spiffs *fs, spiffs_obj_id id, spiffs_block_ix bix, int ix_entry, - const void *user_const_p, void *user_var_p); + const void *user_const_p, void *user_var_p); #if SPIFFS_CACHE diff --git a/armsrc/string.c b/armsrc/string.c index 02392ec40..ea113680e 100644 --- a/armsrc/string.c +++ b/armsrc/string.c @@ -109,98 +109,89 @@ void itoa(int n, char s[]) { -char *strcpy(char *dst, const char *src) - { - char *save = dst; +char *strcpy(char *dst, const char *src) { + char *save = dst; - for (; (*dst = *src) != '\0'; ++src, ++dst); - return save; - } + for (; (*dst = *src) != '\0'; ++src, ++dst); + return save; +} -char *strncpy(char *dst, const char *src, size_t n) - { - if (n != 0) { - char *d = dst; - const char *s = src; +char *strncpy(char *dst, const char *src, size_t n) { + if (n != 0) { + char *d = dst; + const char *s = src; - do { - if ((*d++ = *s++) == 0) { - /* NUL pad the remaining n-1 bytes */ - while (--n) { + do { + if ((*d++ = *s++) == 0) { + /* NUL pad the remaining n-1 bytes */ + while (--n) { *d++ = 0; - } - break; - } - } while (--n); + } + break; + } + } while (--n); } - return dst; - } + return dst; +} -int strcmp(const char *s1, const char *s2) -{ +int strcmp(const char *s1, const char *s2) { while (*s1 == *s2++) { if (*s1++ == 0) { return (0); } } - return (*(unsigned char *) s1 - *(unsigned char *) --s2); + return (*(unsigned char *) s1 - * (unsigned char *) --s2); } -char* __strtok_r(char*, const char*, char**); +char *__strtok_r(char *, const char *, char **); -char* __strtok_r(char* s, const char* delim, char** last) -{ - char *spanp, *tok; - int c, sc; +char *__strtok_r(char *s, const char *delim, char **last) { + char *spanp, *tok; + int c, sc; - if(s == NULL && (s = *last) == NULL) - return (NULL); + if (s == NULL && (s = *last) == NULL) + return (NULL); -/* - * Skip (span) leading delimiters (s += strspn(s, delim), sort of). - */ + /* + * Skip (span) leading delimiters (s += strspn(s, delim), sort of). + */ cont: - c = *s++; - for(spanp = (char*)delim; (sc = *spanp++) != 0;) - { - if(c == sc) - goto cont; - } + c = *s++; + for (spanp = (char *)delim; (sc = *spanp++) != 0;) { + if (c == sc) + goto cont; + } - if(c == 0) - { /* no non-delimiter characters */ - *last = NULL; - return (NULL); - } - tok = s - 1; + if (c == 0) { + /* no non-delimiter characters */ + *last = NULL; + return (NULL); + } + tok = s - 1; - /* - * Scan token (scan for delimiters: s += strcspn(s, delim), sort of). - * Note that delim must have one NUL; we stop if we see that, too. - */ - for(;;) - { - c = *s++; - spanp = (char*)delim; - do - { - if((sc = *spanp++) == c) - { - if(c == 0) - s = NULL; - else - s[-1] = '\0'; - *last = s; - return (tok); - } - } while(sc != 0); - } - /* NOTREACHED */ + /* + * Scan token (scan for delimiters: s += strcspn(s, delim), sort of). + * Note that delim must have one NUL; we stop if we see that, too. + */ + for (;;) { + c = *s++; + spanp = (char *)delim; + do { + if ((sc = *spanp++) == c) { + if (c == 0) + s = NULL; + else + s[-1] = '\0'; + *last = s; + return (tok); + } + } while (sc != 0); + } + /* NOTREACHED */ } -char* strtok(char* s, const char* delim) -{ - static char* last; +char *strtok(char *s, const char *delim) { + static char *last; - return (__strtok_r(s, delim, &last)); + return (__strtok_r(s, delim, &last)); } diff --git a/armsrc/string.h b/armsrc/string.h index 9a899cfc7..c30293a2a 100644 --- a/armsrc/string.h +++ b/armsrc/string.h @@ -24,8 +24,8 @@ char *strcat(char *dest, const char *src); void strreverse(char s[]); void itoa(int n, char s[]); char *strcpy(char *dst, const char *src); -char* strncpy(char* destination, const char* source, size_t num); +char *strncpy(char *destination, const char *source, size_t num); int strcmp(const char *s1, const char *s2); -char* strtok(char* s, const char* delim); +char *strtok(char *s, const char *delim); #endif /* __STRING_H */ diff --git a/client/cmddata.c b/client/cmddata.c index 8a220a39d..7ade24586 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -865,7 +865,7 @@ static int CmdBitsamples(const char *Cmd) { int cnt = 0; uint8_t got[12288]; - if (!GetFromDevice(BIG_BUF, got, sizeof(got), 0,NULL,0, NULL, 2500, false)) { + if (!GetFromDevice(BIG_BUF, got, sizeof(got), 0, NULL, 0, NULL, 2500, false)) { PrintAndLogEx(WARNING, "command execution time out"); return PM3_ETIMEOUT; } @@ -1397,7 +1397,7 @@ static int CmdHexsamples(const char *Cmd) { return PM3_EINVARG; } - if (!GetFromDevice(BIG_BUF, got, requested, offset,NULL,0, NULL, 2500, false)) { + if (!GetFromDevice(BIG_BUF, got, requested, offset, NULL, 0, NULL, 2500, false)) { PrintAndLogEx(WARNING, "command execution time out"); return PM3_ESOFT; } @@ -1470,7 +1470,7 @@ int getSamples(uint32_t n, bool silent) { if (!silent) PrintAndLogEx(NORMAL, "Reading %d bytes from device memory\n", n); PacketResponseNG response; - if (!GetFromDevice(BIG_BUF, got, n, 0,NULL,0, &response, 10000, true)) { + if (!GetFromDevice(BIG_BUF, got, n, 0, NULL, 0, &response, 10000, true)) { PrintAndLogEx(WARNING, "timeout while waiting for reply."); return PM3_ETIMEOUT; } diff --git a/client/cmdflashmem.c b/client/cmdflashmem.c index a3a957552..cfe122c50 100644 --- a/client/cmdflashmem.c +++ b/client/cmdflashmem.c @@ -315,7 +315,7 @@ static int CmdFlashMemDump(const char *Cmd) { } PrintAndLogEx(INFO, "downloading "_YELLOW_("%u")"bytes from flashmem", len); - if (!GetFromDevice(FLASH_MEM, dump, len, start_index,NULL,0, NULL, -1, true)) { + if (!GetFromDevice(FLASH_MEM, dump, len, start_index, NULL, 0, NULL, -1, true)) { PrintAndLogEx(FAILED, "ERROR; downloading from flashmemory"); free(dump); return PM3_EFLASH; diff --git a/client/cmdflashmemspiffs.c b/client/cmdflashmemspiffs.c index e06f492a0..066bb6f3f 100644 --- a/client/cmdflashmemspiffs.c +++ b/client/cmdflashmemspiffs.c @@ -216,37 +216,37 @@ static int CmdFlashMemSpiFFSDump(const char *Cmd) { while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { - case 'h': - return usage_flashmemspiffs_dump(); - /*case 'l': - len = param_get32ex(Cmd, cmdp + 1, FLASH_MEM_MAX_SIZE, 10); - cmdp += 2; - break;*/ - case 'o': - param_getstr(Cmd, cmdp + 1, destfilename, 32); - cmdp += 2; - break; - case 'p': - print = true; - cmdp += 1; - break; - case 'e': - eml = true; - cmdp += 1; - break; - case 'f': - // File handling - if (param_getstr(Cmd, cmdp + 1, filename, FILE_PATH_SIZE) >= FILE_PATH_SIZE) { - PrintAndLogEx(FAILED, "Filename too long"); + case 'h': + return usage_flashmemspiffs_dump(); + /*case 'l': + len = param_get32ex(Cmd, cmdp + 1, FLASH_MEM_MAX_SIZE, 10); + cmdp += 2; + break;*/ + case 'o': + param_getstr(Cmd, cmdp + 1, destfilename, 32); + cmdp += 2; + break; + case 'p': + print = true; + cmdp += 1; + break; + case 'e': + eml = true; + cmdp += 1; + break; + case 'f': + // File handling + if (param_getstr(Cmd, cmdp + 1, filename, FILE_PATH_SIZE) >= FILE_PATH_SIZE) { + PrintAndLogEx(FAILED, "Filename too long"); + errors = true; + break; + } + cmdp += 2; + break; + default: + PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); errors = true; break; - } - cmdp += 2; - break; - default: - PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); - errors = true; - break; } } @@ -314,24 +314,24 @@ static int CmdFlashMemSpiFFSLoad(const char *Cmd) { while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { - case 'h': - return usage_flashmemspiffs_load(); - case 'f': - if (param_getstr(Cmd, cmdp + 1, filename, FILE_PATH_SIZE) >= FILE_PATH_SIZE) { - PrintAndLogEx(FAILED, "Filename too long"); + case 'h': + return usage_flashmemspiffs_load(); + case 'f': + if (param_getstr(Cmd, cmdp + 1, filename, FILE_PATH_SIZE) >= FILE_PATH_SIZE) { + PrintAndLogEx(FAILED, "Filename too long"); + errors = true; + break; + } + cmdp += 2; + break; + case 'o': + param_getstr(Cmd, cmdp + 1, destfilename, 32); + cmdp += 2; + break; + default: + PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); errors = true; break; - } - cmdp += 2; - break; - case 'o': - param_getstr(Cmd, cmdp + 1, destfilename, 32); - cmdp += 2; - break; - default: - PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); - errors = true; - break; } } @@ -432,8 +432,10 @@ static int CmdFlashMemSpiFFSLoad(const char *Cmd) { static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, - {"copy", CmdFlashMemSpiFFSCopy, IfPm3Flash, - "Copy a file to another (destructively) in SPIFFS FileSystem in FlashMEM (spiffs)"}, + { + "copy", CmdFlashMemSpiFFSCopy, IfPm3Flash, + "Copy a file to another (destructively) in SPIFFS FileSystem in FlashMEM (spiffs)" + }, {"dump", CmdFlashMemSpiFFSDump, IfPm3Flash, "Dump a file from SPIFFS FileSystem in FlashMEM (spiffs)"}, {"info", CmdFlashMemSpiFFSInfo, IfPm3Flash, "Print filesystem info and usage statistics (spiffs)"}, {"load", CmdFlashMemSpiFFSLoad, IfPm3Flash, "Upload file into SPIFFS Filesystem (spiffs)"}, @@ -443,7 +445,8 @@ static command_t CommandTable[] = { {"test", CmdFlashMemSpiFFSTest, IfPm3Flash, "Test SPIFFS Functionning (require wiping pages 0 and 1)"}, {"tree", CmdFlashMemSpiFFSTree, IfPm3Flash, "Print the Flash Memory FileSystem Tree (spiffs)"}, {"unmount", CmdFlashMemSpiFFSUnmount, IfPm3Flash, "Un-mount the SPIFFS Filesystem if not already mounted (spiffs)"}, - {NULL, NULL, NULL, NULL}}; + {NULL, NULL, NULL, NULL} +}; static int CmdHelp(const char *Cmd) { (void)Cmd; // Cmd is not used so far diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index 3e6001ee1..5a6f1d33a 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -383,7 +383,7 @@ static int CmdHFFelicaDumpLite(const char *Cmd) { return 1; } - if (!GetFromDevice(BIG_BUF, trace, tracelen, 0,NULL,0, NULL, 2500, false)) { + if (!GetFromDevice(BIG_BUF, trace, tracelen, 0, NULL, 0, NULL, 2500, false)) { PrintAndLogEx(WARNING, "command execution time out"); free(trace); return 0; diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 96b9a0ee5..91757bbd4 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -990,7 +990,7 @@ static int CmdHFiClassReader_Dump(const char *Cmd) { } // response ok - now get bigbuf content of the dump - if (!GetFromDevice(BIG_BUF, tag_data + (blockno * 8), blocksRead * 8, startindex,NULL,0, NULL, 2500, false)) { + if (!GetFromDevice(BIG_BUF, tag_data + (blockno * 8), blocksRead * 8, startindex, NULL, 0, NULL, 2500, false)) { PrintAndLogEx(WARNING, "command execution time out"); return 0; } @@ -1033,7 +1033,7 @@ static int CmdHFiClassReader_Dump(const char *Cmd) { blocksRead = (sizeof(tag_data) - gotBytes) / 8; } // get dumped data from bigbuf - if (!GetFromDevice(BIG_BUF, tag_data + gotBytes, blocksRead * 8, startindex,NULL,0, NULL, 2500, false)) { + if (!GetFromDevice(BIG_BUF, tag_data + gotBytes, blocksRead * 8, startindex, NULL, 0, NULL, 2500, false)) { PrintAndLogEx(WARNING, "command execution time out"); return 0; } diff --git a/client/cmdhflegic.c b/client/cmdhflegic.c index 031f5c95a..e8089c3d8 100644 --- a/client/cmdhflegic.c +++ b/client/cmdhflegic.c @@ -781,7 +781,7 @@ int legic_read_mem(uint32_t offset, uint32_t len, uint32_t iv, uint8_t *out, uin PrintAndLogEx(WARNING, "Fail, only managed to read %u bytes", *outlen); // copy data from device - if (!GetFromDevice(BIG_BUF_EML, out, *outlen, 0,NULL,0, NULL, 2500, false)) { + if (!GetFromDevice(BIG_BUF_EML, out, *outlen, 0, NULL, 0, NULL, 2500, false)) { PrintAndLogEx(WARNING, "Fail, transfer from device time-out"); return 4; } @@ -930,7 +930,7 @@ static int CmdLegicDump(const char *Cmd) { PrintAndLogEx(WARNING, "Fail, only managed to read 0x%02X bytes of 0x%02X", readlen, dumplen); // copy data from device - if (!GetFromDevice(BIG_BUF_EML, data, readlen, 0,NULL,0, NULL, 2500, false)) { + if (!GetFromDevice(BIG_BUF_EML, data, readlen, 0, NULL, 0, NULL, 2500, false)) { PrintAndLogEx(WARNING, "Fail, transfer from device time-out"); free(data); return 4; @@ -1200,7 +1200,7 @@ static int CmdLegicESave(const char *Cmd) { // download emulator memory PrintAndLogEx(SUCCESS, "Reading emulator memory..."); - if (!GetFromDevice(BIG_BUF_EML, data, numofbytes, 0,NULL,0, NULL, 2500, false)) { + if (!GetFromDevice(BIG_BUF_EML, data, numofbytes, 0, NULL, 0, NULL, 2500, false)) { PrintAndLogEx(WARNING, "Fail, transfer from device time-out"); free(data); return 4; diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index c227b1a83..6e2ca62f5 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -2693,7 +2693,7 @@ static int CmdHF14AMfESave(const char *Cmd) { memset(dump, 0, bytes); PrintAndLogEx(INFO, "downloading from emulator memory"); - if (!GetFromDevice(BIG_BUF_EML, dump, bytes, 0,NULL,0, NULL, 2500, false)) { + if (!GetFromDevice(BIG_BUF_EML, dump, bytes, 0, NULL, 0, NULL, 2500, false)) { PrintAndLogEx(WARNING, "Fail, transfer from device time-out"); free(dump); return PM3_ETIMEOUT; diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index 935c178f2..df760f187 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -1931,7 +1931,7 @@ static int CmdHF14AMfUDump(const char *Cmd) { bufferSize = sizeof(data); } - if (!GetFromDevice(BIG_BUF, data, bufferSize, startindex,NULL,0, NULL, 2500, false)) { + if (!GetFromDevice(BIG_BUF, data, bufferSize, startindex, NULL, 0, NULL, 2500, false)) { PrintAndLogEx(WARNING, "command execution time out"); return 1; } diff --git a/client/cmdlfcotag.c b/client/cmdlfcotag.c index fa6ff01a8..134d55c68 100644 --- a/client/cmdlfcotag.c +++ b/client/cmdlfcotag.c @@ -91,7 +91,7 @@ static int CmdCOTAGRead(const char *Cmd) { } case 1: { - if (!GetFromDevice(BIG_BUF, DemodBuffer, COTAG_BITS, 0,NULL,0, NULL, 1000, false)) { + if (!GetFromDevice(BIG_BUF, DemodBuffer, COTAG_BITS, 0, NULL, 0, NULL, 1000, false)) { PrintAndLogEx(WARNING, "timeout while waiting for reply."); return PM3_ETIMEOUT; } diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c index b594eb4bc..eb8de8f86 100644 --- a/client/cmdlfem4x.c +++ b/client/cmdlfem4x.c @@ -986,7 +986,7 @@ static bool downloadSamplesEM() { // 8 bit preamble + 32 bit word response (max clock (128) * 40bits = 5120 samples) uint8_t got[6000]; - if (!GetFromDevice(BIG_BUF, got, sizeof(got), 0,NULL,0, NULL, 2500, false)) { + if (!GetFromDevice(BIG_BUF, got, sizeof(got), 0, NULL, 0, NULL, 2500, false)) { PrintAndLogEx(WARNING, "command execution time out"); return false; } diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 1af8defe4..8acfc69c7 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -1804,7 +1804,7 @@ static int CmdResetRead(const char *Cmd) { } uint8_t got[BIGBUF_SIZE - 1]; - if (!GetFromDevice(BIG_BUF, got, sizeof(got), 0,NULL,0, NULL, 2500, false)) { + if (!GetFromDevice(BIG_BUF, got, sizeof(got), 0, NULL, 0, NULL, 2500, false)) { PrintAndLogEx(WARNING, "command execution time out"); return PM3_ETIMEOUT; } diff --git a/client/cmdtrace.c b/client/cmdtrace.c index e9a609184..3a2ea9aef 100644 --- a/client/cmdtrace.c +++ b/client/cmdtrace.c @@ -759,7 +759,7 @@ int CmdTraceList(const char *Cmd) { if (isOnline) { // Query for the size of the trace, downloading PM3_CMD_DATA_SIZE PacketResponseNG response; - if (!GetFromDevice(BIG_BUF, trace, PM3_CMD_DATA_SIZE, 0,NULL,0, &response, 4000, true)) { + if (!GetFromDevice(BIG_BUF, trace, PM3_CMD_DATA_SIZE, 0, NULL, 0, &response, 4000, true)) { PrintAndLogEx(WARNING, "timeout while waiting for reply."); return 1; } @@ -773,7 +773,7 @@ int CmdTraceList(const char *Cmd) { return 2; } trace = p; - if (!GetFromDevice(BIG_BUF, trace, traceLen, 0,NULL,0, NULL, 2500, false)) { + if (!GetFromDevice(BIG_BUF, trace, traceLen, 0, NULL, 0, NULL, 2500, false)) { PrintAndLogEx(WARNING, "command execution time out"); free(trace); return 3; diff --git a/client/comms.c b/client/comms.c index 45771c60d..00c6a0f20 100644 --- a/client/comms.c +++ b/client/comms.c @@ -761,9 +761,9 @@ bool GetFromDevice(DeviceMemType_t memtype, uint8_t *dest, uint32_t bytes, uint3 return dl_it(dest, bytes, start_index, response, ms_timeout, show_warning, CMD_DOWNLOADED_EML_BIGBUF); } case SPIFFS: { - SendCommandMIX(CMD_SPIFFS_DOWNLOAD, start_index, bytes, 0, data, datalen); + SendCommandMIX(CMD_SPIFFS_DOWNLOAD, start_index, bytes, 0, data, datalen); return dl_it(dest, bytes, start_index, response, ms_timeout, show_warning, CMD_SPIFFS_DOWNLOADED); - } + } case FLASH_MEM: { SendCommandMIX(CMD_FLASHMEM_DOWNLOAD, start_index, bytes, 0, NULL, 0); return dl_it(dest, bytes, start_index, response, ms_timeout, show_warning, CMD_FLASHMEM_DOWNLOADED); diff --git a/client/flash.c b/client/flash.c index 316b53066..f2f0b526a 100644 --- a/client/flash.c +++ b/client/flash.c @@ -415,7 +415,7 @@ int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t version = BL_VERSION_INVALID; PrintAndLogEx(ERR, _RED_("Note: Your bootloader reported an invalid version number")); flash_suggest_update_bootloader(); - // + // } else if (BL_VERSION_MAJOR(version) < BL_VERSION_MAJOR(FLASHER_VERSION)) { PrintAndLogEx(ERR, _RED_("Note: Your bootloader reported a version older than this flasher")); flash_suggest_update_bootloader(); @@ -448,7 +448,7 @@ int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t PrintAndLogEx(ERR, _RED_("Note: Your bootloader does not understand the new CHIP_INFO command")); flash_suggest_update_bootloader(); } - + if (enable_bl_writes) { PrintAndLogEx(INFO, "Permitted flash range: 0x%08x-0x%08x", FLASH_START, flash_end); } else { diff --git a/client/scripting.c b/client/scripting.c index 9e735b0db..e55aa507a 100644 --- a/client/scripting.c +++ b/client/scripting.c @@ -223,7 +223,7 @@ static int l_GetFromBigBuf(lua_State *L) { return returnToLuaWithError(L, "Allocating memory failed"); } - if (!GetFromDevice(BIG_BUF, data, len, startindex,NULL,0, NULL, 2500, false)) { + if (!GetFromDevice(BIG_BUF, data, len, startindex, NULL, 0, NULL, 2500, false)) { free(data); return returnToLuaWithError(L, "command execution time out"); } @@ -263,7 +263,7 @@ static int l_GetFromFlashMem(lua_State *L) { if (!data) return returnToLuaWithError(L, "Allocating memory failed"); - if (!GetFromDevice(FLASH_MEM, data, len, startindex,NULL,0, NULL, -1, false)) { + if (!GetFromDevice(FLASH_MEM, data, len, startindex, NULL, 0, NULL, -1, false)) { free(data); return returnToLuaWithError(L, "command execution time out"); } diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 99a858ff0..3de6688fd 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -238,8 +238,8 @@ typedef struct { #define CMD_FLASHMEM_INFO 0x0125 #define CMD_FLASHMEM_SET_SPIBAUDRATE 0x0126 -// RDV40, High level flashmem SPIFFS Manipulation -// ALL function will have a lazy or Safe version +// RDV40, High level flashmem SPIFFS Manipulation +// ALL function will have a lazy or Safe version // that will be handled as argument of safety level [0..2] respectiveley normal / lazy / safe // However as how design is, MOUNT and UNMOUNT only need/have lazy as safest level so a safe level will still execute a lazy version // see spiffs.c for more about the normal/lazy/safety information) From 544fb30ce68ed401792f3219d61b8a026e05e0ad Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 23 Jul 2019 21:40:01 +0200 Subject: [PATCH 0136/1854] typos --- armsrc/iso14443a.c | 2 +- armsrc/iso15693.c | 2 +- armsrc/spiffs.c | 6 +++--- armsrc/spiffs.h | 2 +- client/cmdflashmemspiffs.c | 2 +- client/scripts/legic.lua | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 734513b54..a09978d7a 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -93,7 +93,7 @@ static uint32_t LastProxToAirDuration; // Sequence D: 11110000 modulation with subcarrier during first half // Sequence E: 00001111 modulation with subcarrier during second half // Sequence F: 00000000 no modulation with subcarrier -// Sequence COLL: 11111111 load modulation over the full bitlenght. +// Sequence COLL: 11111111 load modulation over the full bitlength. // Tricks the reader to think that multiple cards answer (at least one card with 1 and at least one card with 0). // READER TO CARD - miller // Sequence X: 00001100 drop after half a period diff --git a/armsrc/iso15693.c b/armsrc/iso15693.c index 374b2be23..e74ca972d 100644 --- a/armsrc/iso15693.c +++ b/armsrc/iso15693.c @@ -695,7 +695,7 @@ static void BuildInventoryResponse(uint8_t *cmdout, uint8_t *uid) { // speed ... 0 low speed, 1 hi speed // **recv will return you a pointer to the received data // If you do not need the answer use NULL for *recv[] -// return: lenght of received data +// return: length of received data // logging enabled int SendDataTag(uint8_t *send, int sendlen, bool init, int speed, uint8_t *outdata) { diff --git a/armsrc/spiffs.c b/armsrc/spiffs.c index 0fecc556c..1439bfd20 100644 --- a/armsrc/spiffs.c +++ b/armsrc/spiffs.c @@ -208,7 +208,7 @@ rdv40_spiffs_fsinfo info_of_spiffs() { fsinfo.blockSize = SPIFFS_CFG_LOG_BLOCK_SZ; fsinfo.pageSize = LOG_PAGE_SIZE; fsinfo.maxOpenFiles = RDV40_SPIFFS_MAX_FD; - fsinfo.maxPathLenght = SPIFFS_OBJ_NAME_LEN; + fsinfo.maxPathLength = SPIFFS_OBJ_NAME_LEN; if (SPIFFS_info(&fs, &fsinfo.totalBytes, &fsinfo.usedBytes) < 0) Dbprintf("errno %i\n", SPIFFS_errno(&fs)); fsinfo.freeBytes = fsinfo.totalBytes - fsinfo.usedBytes; @@ -532,7 +532,7 @@ void rdv40_spiffs_safe_print_fsinfos() { Dbprintf("* Filesystem Logical Page Size..........%d bytes", fsinfo.pageSize); Dbprintf("--"); Dbprintf("* Filesystem Max Open Files.............%d file descriptors", fsinfo.maxOpenFiles); - Dbprintf("* Filesystem Max Path Lenght............%d chars", fsinfo.maxPathLenght); + Dbprintf("* Filesystem Max Path Length............%d chars", fsinfo.maxPathLength); Dbprintf("--"); Dbprintf("Filesystem\tSize\tUsed\tAvailable\tUse%\tMounted on"); Dbprintf("spiffs\t%dB\t%dB\t%dB\t\t%d%\t/", fsinfo.totalBytes, fsinfo.usedBytes, fsinfo.freeBytes, @@ -580,7 +580,7 @@ void rdv40_spiffs_safe_print_tree(uint8_t banner) { void test_spiffs() { Dbprintf("---------------------------"); - Dbprintf("Testing SPIFFS functionning"); + Dbprintf("Testing SPIFFS operations"); Dbprintf("---------------------------"); Dbprintf("(all test are made using lazy safetylevel)"); Dbprintf("* Mounting filesystem (lazy)......."); diff --git a/armsrc/spiffs.h b/armsrc/spiffs.h index b9308f4dd..e79783402 100644 --- a/armsrc/spiffs.h +++ b/armsrc/spiffs.h @@ -26,7 +26,7 @@ typedef struct rdv40_spiffs_fsinfo { uint32_t blockSize; uint32_t pageSize; uint32_t maxOpenFiles; - uint32_t maxPathLenght; + uint32_t maxPathLength; uint32_t totalBytes, usedBytes, freeBytes; uint32_t usedPercent, freePercent; } rdv40_spiffs_fsinfo; diff --git a/client/cmdflashmemspiffs.c b/client/cmdflashmemspiffs.c index 066bb6f3f..bc7a408bd 100644 --- a/client/cmdflashmemspiffs.c +++ b/client/cmdflashmemspiffs.c @@ -442,7 +442,7 @@ static command_t CommandTable[] = { {"mount", CmdFlashMemSpiFFSMount, IfPm3Flash, "Mount the SPIFFS Filesystem if not already mounted (spiffs)"}, {"remove", CmdFlashMemSpiFFSRemove, IfPm3Flash, "Remove a file from SPIFFS FileSystem in FlashMEM (spiffs)"}, {"rename", CmdFlashMemSpiFFSRename, IfPm3Flash, "Rename/move a file in SPIFFS FileSystem in FlashMEM (spiffs)"}, - {"test", CmdFlashMemSpiFFSTest, IfPm3Flash, "Test SPIFFS Functionning (require wiping pages 0 and 1)"}, + {"test", CmdFlashMemSpiFFSTest, IfPm3Flash, "Test SPIFFS Operations (require wiping pages 0 and 1)"}, {"tree", CmdFlashMemSpiFFSTree, IfPm3Flash, "Print the Flash Memory FileSystem Tree (spiffs)"}, {"unmount", CmdFlashMemSpiFFSUnmount, IfPm3Flash, "Un-mount the SPIFFS Filesystem if not already mounted (spiffs)"}, {NULL, NULL, NULL, NULL} diff --git a/client/scripts/legic.lua b/client/scripts/legic.lua index 9637ef6c8..7e0f8d3be 100644 --- a/client/scripts/legic.lua +++ b/client/scripts/legic.lua @@ -2654,7 +2654,7 @@ function modifyMode() local stamp=getSegmentStamp(inTAG.SEG[x]) print("Stamp : "..stamp) stamp=str2bytes(stamp) - print("lenght: "..#stamp) + print("length: "..#stamp) end, --- -- calculate crc16 From 7e84a546c5cbda12a9654094b4da6a6b7b163381 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 23 Jul 2019 21:45:06 +0200 Subject: [PATCH 0137/1854] GetFromDevice leftovers --- client/cmdlfhitag.c | 4 ++-- client/comms.c | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/client/cmdlfhitag.c b/client/cmdlfhitag.c index 69ba874c1..0fc4b053c 100644 --- a/client/cmdlfhitag.c +++ b/client/cmdlfhitag.c @@ -137,7 +137,7 @@ static int CmdLFHitagList(const char *Cmd) { // Query for the actual size of the trace PacketResponseNG response; - if (!GetFromDevice(BIG_BUF, got, PM3_CMD_DATA_SIZE, 0, &response, 2500, false)) { + if (!GetFromDevice(BIG_BUF, got, PM3_CMD_DATA_SIZE, 0, NULL, 0, &response, 2500, false)) { PrintAndLogEx(WARNING, "command execution time out"); free(got); return 2; @@ -152,7 +152,7 @@ static int CmdLFHitagList(const char *Cmd) { return 2; } got = p; - if (!GetFromDevice(BIG_BUF, got, traceLen, 0, NULL, 2500, false)) { + if (!GetFromDevice(BIG_BUF, got, traceLen, 0, NULL, 0, NULL, 2500, false)) { PrintAndLogEx(WARNING, "command execution time out"); free(got); return 2; diff --git a/client/comms.c b/client/comms.c index 00c6a0f20..ef00ebc44 100644 --- a/client/comms.c +++ b/client/comms.c @@ -734,6 +734,8 @@ bool WaitForResponse(uint32_t cmd, PacketResponseNG *response) { * @param dest Destination address for transfer * @param bytes number of bytes to be transferred * @param start_index offset into Proxmark3 BigBuf[] +* @param data used by SPIFFS to provide filename +* @param datalen used by SPIFFS to provide filename length * @param response struct to copy last command (CMD_ACK) into * @param ms_timeout timeout in milliseconds * @param show_warning display message after 2 seconds From 7f57879e4583cfc30546a09c1acbe66f8c3d3cbb Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 23 Jul 2019 21:48:09 +0200 Subject: [PATCH 0138/1854] typo --- armsrc/appmain.c | 2 +- armsrc/spiffs.c | 4 ++-- armsrc/spiffs.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 7128c4a2f..c47a96528 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1607,7 +1607,7 @@ static void PacketReceived(PacketCommandNG *packet) { break; } case CMD_SPIFFS_PRINT_FSINFO: { - rdv40_spiffs_safe_print_fsinfos(); + rdv40_spiffs_safe_print_fsinfo(); break; } case CMD_SPIFFS_DOWNLOAD: { diff --git a/armsrc/spiffs.c b/armsrc/spiffs.c index 1439bfd20..7fd712e7f 100644 --- a/armsrc/spiffs.c +++ b/armsrc/spiffs.c @@ -523,10 +523,10 @@ int rdv40_spiffs_read_as_filetype(char *filename, uint8_t *dst, uint32_t size, R ///////// MISC HIGH LEVEL FUNCTIONS //////////////////////////////////////////// -void rdv40_spiffs_safe_print_fsinfos() { +void rdv40_spiffs_safe_print_fsinfo() { rdv40_spiffs_fsinfo fsinfo; rdv40_spiffs_getfsinfo(&fsinfo, RDV40_SPIFFS_SAFETY_SAFE); - DbpString(_BLUE_("Flash Memory FileSystem Infos (SPIFFS)")); + DbpString(_BLUE_("Flash Memory FileSystem Info (SPIFFS)")); Dbprintf("-------------------------------------"); Dbprintf("* Filesystem Logical Block Size.........%d bytes", fsinfo.blockSize); Dbprintf("* Filesystem Logical Page Size..........%d bytes", fsinfo.pageSize); diff --git a/armsrc/spiffs.h b/armsrc/spiffs.h index e79783402..22d7434de 100644 --- a/armsrc/spiffs.h +++ b/armsrc/spiffs.h @@ -49,7 +49,7 @@ void rdv40_spiffs_safe_print_tree(uint8_t banner); int rdv40_spiffs_unmount(); int rdv40_spiffs_mount(); int rdv40_spiffs_is_symlink(const char *s); -void rdv40_spiffs_safe_print_fsinfos(); +void rdv40_spiffs_safe_print_fsinfo(); int rdv40_spiffs_make_symlink(char *linkdest, char *filename, RDV40SpiFFSSafetyLevel level); void append_to_spiffs(const char *filename, uint8_t *src, uint32_t size); int rdv40_spiffs_copy(char *src, char *dst, RDV40SpiFFSSafetyLevel level); From ac18114909cd70a711c9c432941a82cc1b69b32b Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 23 Jul 2019 22:46:58 +0200 Subject: [PATCH 0139/1854] Remove long unsigned int warning --- client/cmdlft55xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 7b8a77487..618ab8c7c 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -2606,7 +2606,7 @@ static int CmdT55xxSetDeviceConfig(const char *Cmd) { // printf ("DLmode %d\n",downlink_mode); t55xx_config conf = {0}; - printf ("Size conf %lld\n",sizeof(conf)); + printf ("Size conf %zu\n",sizeof(conf)); if (erase) { memset (&conf,0xff, sizeof(conf)); printf ("Conf.m[0] %x\n",conf.m[0].start_gap); From ee40840a141881fa3fecd0584573b10f389015ce Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 23 Jul 2019 23:12:18 +0200 Subject: [PATCH 0140/1854] changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 622293abf..76b3db976 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Add T55x7 Downlink mode support (@mwalker33) + - Add SPIFFS Flash filesystem support (@cjbrigato) - Fix support for flashing 512K units with old bootrom (@slurdge/@doegox) - Fix 'hf mf sim' - wrong access rights to write key B in trailer (@McEloff) - Add option -i to flasher to query Pm3 for its memory size (@doegox) From aeed5e3c26f7accaaf69f817961fd786fa2b2172 Mon Sep 17 00:00:00 2001 From: cjbrigato Date: Tue, 23 Jul 2019 23:26:26 +0200 Subject: [PATCH 0141/1854] FIX: Patch HF_BOG standalone for new SPIFFS compatibility --- armsrc/Standalone/hf_bog.c | 118 +++++++++++++++---------------------- 1 file changed, 46 insertions(+), 72 deletions(-) diff --git a/armsrc/Standalone/hf_bog.c b/armsrc/Standalone/hf_bog.c index ca0b0eeeb..08e0345c7 100644 --- a/armsrc/Standalone/hf_bog.c +++ b/armsrc/Standalone/hf_bog.c @@ -27,9 +27,11 @@ from the client to view the stored quadlets. // Maximum number of auth attempts per standalone session #define MAX_PWDS_PER_SESSION 64 +#define HF_BOG_LOGFILE "hf_bog.log" + uint8_t FindOffsetInFlash() { - uint8_t mem[4] = { 0x00, 0x00, 0x00, 0x00 }; - uint8_t eom[4] = { 0xFF, 0xFF, 0xFF, 0xFF }; + uint8_t mem[4] = {0x00, 0x00, 0x00, 0x00}; + uint8_t eom[4] = {0xFF, 0xFF, 0xFF, 0xFF}; uint8_t memcnt = 0; while (memcnt < 0xFF) { @@ -52,7 +54,8 @@ void EraseMemory() { Flash_WriteEnable(); Flash_Erase4k(0, 0); - if (DBGLEVEL > 1) Dbprintf("[!] Erased flash!"); + if (DBGLEVEL > 1) + Dbprintf("[!] Erased flash!"); FlashStop(); SpinDelay(100); } @@ -96,8 +99,9 @@ void RAMFUNC SniffAndStore(uint8_t param) { UartInit(receivedCmd, receivedCmdPar); // Setup and start DMA. - if (!FpgaSetupSscDma((uint8_t *) dmaBuf, DMA_BUFFER_SIZE)) { - if (DBGLEVEL > 1) Dbprintf("FpgaSetupSscDma failed. Exiting"); + if (!FpgaSetupSscDma((uint8_t *)dmaBuf, DMA_BUFFER_SIZE)) { + if (DBGLEVEL > 1) + Dbprintf("FpgaSetupSscDma failed. Exiting"); return; } @@ -134,17 +138,18 @@ void RAMFUNC SniffAndStore(uint8_t param) { Dbprintf("[!] blew circular buffer! | datalen %u", dataLen); break; } - if (dataLen < 1) continue; + if (dataLen < 1) + continue; // primary buffer was stopped( <-- we lost data! if (!AT91C_BASE_PDC_SSC->PDC_RCR) { - AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) dmaBuf; + AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t)dmaBuf; AT91C_BASE_PDC_SSC->PDC_RCR = DMA_BUFFER_SIZE; - //Dbprintf("[-] RxEmpty ERROR | data length %d", dataLen); // temporary + // Dbprintf("[-] RxEmpty ERROR | data length %d", dataLen); // temporary } // secondary buffer sets as primary, secondary buffer was stopped if (!AT91C_BASE_PDC_SSC->PDC_RNCR) { - AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dmaBuf; + AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t)dmaBuf; AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE; } @@ -159,23 +164,24 @@ void RAMFUNC SniffAndStore(uint8_t param) { LED_C_ON(); // check - if there is a short 7bit request from reader - if ((!triggered) && (param & 0x02) && (uart->len == 1) && (uart->bitCount == 7)) triggered = true; + if ((!triggered) && (param & 0x02) && (uart->len == 1) && (uart->bitCount == 7)) + triggered = true; if (triggered) { - if ((receivedCmd) && ((receivedCmd[0] == MIFARE_ULEV1_AUTH) || (receivedCmd[0] == MIFARE_ULC_AUTH_1))) { - if (DBGLEVEL > 1) Dbprintf("PWD-AUTH KEY: 0x%02x%02x%02x%02x", receivedCmd[1], receivedCmd[2], receivedCmd[3], receivedCmd[4]); + if ((receivedCmd) && + ((receivedCmd[0] == MIFARE_ULEV1_AUTH) || (receivedCmd[0] == MIFARE_ULC_AUTH_1))) { + if (DBGLEVEL > 1) + Dbprintf("PWD-AUTH KEY: 0x%02x%02x%02x%02x", receivedCmd[1], receivedCmd[2], + receivedCmd[3], receivedCmd[4]); // temporarily save the captured pwd in our array memcpy(&capturedPwds[4 * auth_attempts], receivedCmd + 1, 4); auth_attempts++; } - if (!LogTrace(receivedCmd, - uart->len, - uart->startTime * 16 - DELAY_READER_AIR2ARM_AS_SNIFFER, - uart->endTime * 16 - DELAY_READER_AIR2ARM_AS_SNIFFER, - uart->parity, - true)) break; + if (!LogTrace(receivedCmd, uart->len, uart->startTime * 16 - DELAY_READER_AIR2ARM_AS_SNIFFER, + uart->endTime * 16 - DELAY_READER_AIR2ARM_AS_SNIFFER, uart->parity, true)) + break; } /* ready to receive another command. */ UartReset(); @@ -193,20 +199,18 @@ void RAMFUNC SniffAndStore(uint8_t param) { if (ManchesterDecoding(tagdata, 0, (my_rsamples - 1) * 4)) { LED_B_ON(); - if (!LogTrace(receivedResp, - demod->len, - demod->startTime * 16 - DELAY_TAG_AIR2ARM_AS_SNIFFER, - demod->endTime * 16 - DELAY_TAG_AIR2ARM_AS_SNIFFER, - demod->parity, - false)) break; + if (!LogTrace(receivedResp, demod->len, demod->startTime * 16 - DELAY_TAG_AIR2ARM_AS_SNIFFER, + demod->endTime * 16 - DELAY_TAG_AIR2ARM_AS_SNIFFER, demod->parity, false)) + break; - if ((!triggered) && (param & 0x01)) triggered = true; + if ((!triggered) && (param & 0x01)) + triggered = true; // ready to receive another response. DemodReset(); // reset the Miller decoder including its (now outdated) input buffer UartReset(); - //UartInit(receivedCmd, receivedCmdPar); + // UartInit(receivedCmd, receivedCmdPar); LED_C_OFF(); } TagIsActive = (demod->state != DEMOD_UNSYNCD); @@ -228,57 +232,27 @@ void RAMFUNC SniffAndStore(uint8_t param) { SpinDelay(200); - // Write stuff to flash + // Write stuff to spiffs logfile if (auth_attempts > 0) { - if (DBGLEVEL > 1) Dbprintf("[!] Authentication attempts = %u", auth_attempts); + if (DBGLEVEL > 1) + Dbprintf("[!] Authentication attempts = %u", auth_attempts); - // Setting the SPI Baudrate to 48MHz to avoid the bit-flip issue (https://github.com/RfidResearchGroup/proxmark3/issues/34) - FlashmemSetSpiBaudrate(48000000); + if + size_t size = 4 * auth_attempts; + uint8_t *data = BigBuf_malloc(size); - // Find the offset in flash mem to continue writing the auth attempts - uint8_t memoffset = FindOffsetInFlash(); - if (DBGLEVEL > 1) Dbprintf("[!] Memory offset = %u", memoffset); - - if ((memoffset + 4 * auth_attempts) > 0xFF) { - // We opt to keep the new data only - memoffset = 0; - if (DBGLEVEL > 1) Dbprintf("[!] Size of total data > 256 bytes. Discarding the old data."); + if (!exists_in_spiffs((char *)HF_BOG_LOGFILE)) { + rdv40_spiffs_write((char *)HF_BOG_LOGFILE, (uint8_t *)data, size, RDV40_SPIFFS_SAFETY_SAFE); + } else { + rdv40_spiffs_append((char *)HF_BOG_LOGFILE, (uint8_t *)data, size, RDV40_SPIFFS_SAFETY_SAFE); } - - // Get previous data from flash mem - uint8_t *previousdata = BigBuf_malloc(memoffset); - if (memoffset > 0) { - uint16_t readlen = Flash_ReadData(0, previousdata, memoffset); - if (DBGLEVEL > 1) Dbprintf("[!] Read %u bytes from flash mem", readlen); - } - - // create new bigbuf to hold all data - size_t total_size = memoffset + 4 * auth_attempts; - uint8_t *total_data = BigBuf_malloc(total_size); - - // Add the previousdata array into total_data array - memcpy(total_data, previousdata, memoffset); - - // Copy bytes of capturedPwds immediately following bytes of previousdata - memcpy(total_data + memoffset, capturedPwds, 4 * auth_attempts); - - // Erase first page of flash mem - EraseMemory(); - - // Write total data to flash mem - uint16_t writelen = Flash_WriteData(0, total_data, memoffset + 4 * auth_attempts); - if (DBGLEVEL > 1) Dbprintf("[!] Wrote %u bytes into flash mem", writelen); - - // If pwd saved successfully, blink led A three times - if (writelen > 0) { - SpinErr(0, 200, 5); // blink led A - } - - SpinDelay(100); - - // Reset the SPI Baudrate to the default value (24MHz) - FlashmemSetSpiBaudrate(24000000); } + + if (DBGLEVEL > 1) + Dbprintf("[!] Wrote %u Authentification attempts into logfile", auth_attempts); + + SpinErr(0, 200, 5); // blink led A + SpinDelay(100); } void ModInfo(void) { From d3633b719f92f32c9c892b619702ce5ed93b196a Mon Sep 17 00:00:00 2001 From: cjbrigato Date: Tue, 23 Jul 2019 23:27:35 +0200 Subject: [PATCH 0142/1854] FIX: Patch HF_BOG standalone for new SPIFFS compatibility --- armsrc/Standalone/hf_bog.c | 31 ------------------------------- 1 file changed, 31 deletions(-) diff --git a/armsrc/Standalone/hf_bog.c b/armsrc/Standalone/hf_bog.c index 08e0345c7..eaa69cd47 100644 --- a/armsrc/Standalone/hf_bog.c +++ b/armsrc/Standalone/hf_bog.c @@ -29,37 +29,6 @@ from the client to view the stored quadlets. #define HF_BOG_LOGFILE "hf_bog.log" -uint8_t FindOffsetInFlash() { - uint8_t mem[4] = {0x00, 0x00, 0x00, 0x00}; - uint8_t eom[4] = {0xFF, 0xFF, 0xFF, 0xFF}; - uint8_t memcnt = 0; - - while (memcnt < 0xFF) { - Flash_ReadData(memcnt, mem, 4); - if (memcmp(mem, eom, 4) == 0) { - return memcnt; - } - memcnt += 4; - } - - return 0; // wrap-around -} - -void EraseMemory() { - if (!FlashInit()) { - return; - } - - Flash_CheckBusy(BUSY_TIMEOUT); - Flash_WriteEnable(); - Flash_Erase4k(0, 0); - - if (DBGLEVEL > 1) - Dbprintf("[!] Erased flash!"); - FlashStop(); - SpinDelay(100); -} - // This is actually copied from SniffIso14443a void RAMFUNC SniffAndStore(uint8_t param) { From e59e0f619443afc5defcd22e7a99eebd462637df Mon Sep 17 00:00:00 2001 From: "Colin J. Brigato" Date: Tue, 23 Jul 2019 23:42:48 +0200 Subject: [PATCH 0143/1854] Typo --- armsrc/Standalone/hf_bog.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/armsrc/Standalone/hf_bog.c b/armsrc/Standalone/hf_bog.c index eaa69cd47..5a950bddc 100644 --- a/armsrc/Standalone/hf_bog.c +++ b/armsrc/Standalone/hf_bog.c @@ -205,8 +205,7 @@ void RAMFUNC SniffAndStore(uint8_t param) { if (auth_attempts > 0) { if (DBGLEVEL > 1) Dbprintf("[!] Authentication attempts = %u", auth_attempts); - - if + size_t size = 4 * auth_attempts; uint8_t *data = BigBuf_malloc(size); From ac233a346a70a55832dfbe3365769b66eac6f486 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 23 Jul 2019 23:43:30 +0200 Subject: [PATCH 0144/1854] make style --- armsrc/appmain.c | 10 +- armsrc/apps.h | 2 +- armsrc/lfops.c | 676 +++++++++++++++++++++++--------------------- client/cmdlft55xx.c | 647 +++++++++++++++++++++--------------------- client/scripting.c | 6 +- include/pm3_cmd.h | 18 +- 6 files changed, 689 insertions(+), 670 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 80d0f9316..02829c20c 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -880,7 +880,7 @@ static void PacketReceived(PacketCommandNG *packet) { uint8_t downlink_mode; } PACKED; struct p *payload = (struct p *) packet->data.asBytes; - T55xxReadBlock(payload->page, payload->pwdmode, false, payload->blockno, payload->password,payload->downlink_mode); + T55xxReadBlock(payload->page, payload->pwdmode, false, payload->blockno, payload->password, payload->downlink_mode); break; } case CMD_T55XX_WRITE_BLOCK: { @@ -889,15 +889,15 @@ static void PacketReceived(PacketCommandNG *packet) { break; } case CMD_T55XX_WAKEUP: { - T55xxWakeUp(packet->oldarg[0],packet->oldarg[1]); - break; + T55xxWakeUp(packet->oldarg[0], packet->oldarg[1]); + break; } case CMD_T55XX_RESET_READ: { - T55xxResetRead(packet->data.asBytes[0]&0xff); + T55xxResetRead(packet->data.asBytes[0] & 0xff); break; } case CMD_T55XX_CHKPWDS: { - T55xx_ChkPwds(packet->data.asBytes[0]&0xff); + T55xx_ChkPwds(packet->data.asBytes[0] & 0xff); break; } case CMD_PCF7931_READ: { diff --git a/armsrc/apps.h b/armsrc/apps.h index a508b74b0..e3ea8048c 100644 --- a/armsrc/apps.h +++ b/armsrc/apps.h @@ -106,7 +106,7 @@ void T55xxResetRead(uint8_t flags); //id T55xxWriteBlock(uint32_t data, uint8_t blockno, uint32_t pwd, uint8_t flags); void T55xxWriteBlock(uint8_t *data); // void T55xxWriteBlockExt(uint32_t data, uint8_t blockno, uint32_t pwd, uint8_t flags); -void T55xxReadBlock(uint8_t page, bool pwd_mode, bool brute_mem, uint8_t block, uint32_t pwd,uint8_t downlink_mode); +void T55xxReadBlock(uint8_t page, bool pwd_mode, bool brute_mem, uint8_t block, uint32_t pwd, uint8_t downlink_mode); void T55xxWakeUp(uint32_t Pwd, uint8_t flags); void T55xx_ChkPwds(uint8_t flags); diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 17ac49dd2..26a494cf2 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -47,13 +47,13 @@ // 1fc = 8us = 12ticks /* ========================================================================================================== - T55x7 Timing + T55x7 Timing ========================================================================================================== // t55xx_config t_config = { 29 * 8, 17 * 8, 15 * 8, 47 * 8, 15 * 8 } ; - ATA5577 Downlink Protocol Timings. - Note: All absolute times assume TC = 1 / fC = 8 μs (fC = 125 kHz) + ATA5577 Downlink Protocol Timings. + Note: All absolute times assume TC = 1 / fC = 8 μs (fC = 125 kHz) ----------------------------------------------------------------------- Fixed-bit-length Protocol | Normal Downlink | Fast Downlink | ------------------------------+-----------------------------------+-----------------------------------+------ @@ -67,7 +67,7 @@ ------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------- - Long Leading Reference | Normal Downlink | Fast Downlink | + Long Leading Reference | Normal Downlink | Fast Downlink | ------------------------------+-----------------------------------+-----------------------------------+------ | Parameter | Remark | Symbol | Min. | Typ. | Max. | Min. | Typ. | Max. | Unit | |-----------+--------+---------+-----------+-----------+-----------+-----------+-----------+-----------+------| @@ -76,7 +76,7 @@ |-----------+--------+---------+-----------+-----------+-----------+-----------+-----------+-----------+------| | Write | Ref | | 152 | 160 | 168 | 140 | 144 | 148 | Tc | | data | Pulse | dref | 136 clocks + 0 data bit | 132 clocks + 0 data bit | Tc | -| coding |--------+---------+-----------------------------------+-----------------------------------+------| +| coding |--------+---------+-----------------------------------+-----------------------------------+------| | | 0 data | d0 |dref – 143 |dref – 136 |dref – 128 |dref – 135 |dref – 132 |dref – 124 | Tc | | | 1 data | d1 |dref – 111 |dref – 104 |dref – 96 |dref – 119 |dref – 116 |dref – 112 | Tc | ------------------------------------------------------------------------------------------------------------- @@ -113,16 +113,22 @@ /* // Note: Moved * 8 to apply when used. Saving 28 bytes here (- the *8) and 28 bytes flash. // StartGap WriteGap Bit 0/00 Bit 1/01 Bit 10 Bit 11 ReadGap -t55xx_config T55xx_Timing = {{{ 29 , 17 , 15 , 50 , 0 , 0 , 15 }, // Default Fixed - { 31 , 20 , 18 , 50 , 0 , 0 , 15 }, // Long Leading Ref. - { 31 , 20 , 18 , 40 , 0 , 0 , 15 }, // Leading 0 - { 29 , 17 , 15 , 31 , 47 , 63 , 15 } }}; // 1 of 4 +t55xx_config T55xx_Timing = {{ + { 29 , 17 , 15 , 50 , 0 , 0 , 15 }, // Default Fixed + { 31 , 20 , 18 , 50 , 0 , 0 , 15 }, // Long Leading Ref. + { 31 , 20 , 18 , 40 , 0 , 0 , 15 }, // Leading 0 + { 29 , 17 , 15 , 31 , 47 , 63 , 15 } // 1 of 4 + } +}; */ // StartGap WriteGap Bit 0/00 Bit 1/01 Bit 10 Bit 11 ReadGap -t55xx_config T55xx_Timing = {{{ 29 * 8 , 17 * 8 , 15 * 8 , 50 * 8 , 0 , 0 , 15 * 8 }, // Default Fixed - { 31 * 8 , 20 * 8 , 18 * 8 , 50 * 8 , 0 , 0 , 15 * 8 }, // Long Leading Ref. - { 31 * 8 , 20 * 8 , 18 * 8 , 40 * 8 , 0 , 0 , 15 * 8 }, // Leading 0 - { 29 * 8 , 17 * 8 , 15 * 8 , 31 * 8 , 47 * 8, 63 * 8, 15 * 8 } }}; // 1 of 4 +t55xx_config T55xx_Timing = {{ + { 29 * 8, 17 * 8, 15 * 8, 50 * 8, 0, 0, 15 * 8 }, // Default Fixed + { 31 * 8, 20 * 8, 18 * 8, 50 * 8, 0, 0, 15 * 8 }, // Long Leading Ref. + { 31 * 8, 20 * 8, 18 * 8, 40 * 8, 0, 0, 15 * 8 }, // Leading 0 + { 29 * 8, 17 * 8, 15 * 8, 31 * 8, 47 * 8, 63 * 8, 15 * 8 } // 1 of 4 + } +}; // Some defines for readability @@ -133,48 +139,55 @@ t55xx_config T55xx_Timing = {{{ 29 * 8 , 17 * 8 , 15 * 8 , 50 * 8 , 0 , 0 #define T55xx_LongLeadingReference 4 // Value to tell Write Bit to send long reference void printT55xxConfig(void) { - int DLMode; - + int DLMode; + DbpString(_BLUE_("LF T55XX config")); - for (DLMode = 0; DLMode < 4; DLMode++) { - switch (DLMode){ - case T55xx_DLMode_Fixed : Dbprintf("r 0 fixed bit length (default)"); break; - case T55xx_DLMode_LLR : Dbprintf("r 1 long leading reference"); break; - case T55xx_DLMode_Leading0 : Dbprintf("r 2 leading zero"); break; - case T55xx_DLMode_1of4 : Dbprintf("r 3 1 of 4 coding reference"); break; - } - Dbprintf(" [a] startgap............%d*8 (%d)", T55xx_Timing.m[DLMode].start_gap / 8, T55xx_Timing.m[DLMode].start_gap); - Dbprintf(" [b] writegap............%d*8 (%d)", T55xx_Timing.m[DLMode].write_gap / 8, T55xx_Timing.m[DLMode].write_gap); - Dbprintf(" [c] write_0.............%d*8 (%d)", T55xx_Timing.m[DLMode].write_0 / 8, T55xx_Timing.m[DLMode].write_0 ); - Dbprintf(" [d] write_1.............%d*8 (%d)", T55xx_Timing.m[DLMode].write_1 / 8, T55xx_Timing.m[DLMode].write_1 ); - if (DLMode == T55xx_DLMode_1of4) { - Dbprintf(" [e] write_2.............%d*8 (%d)", T55xx_Timing.m[DLMode].write_2 / 8, T55xx_Timing.m[DLMode].write_2); - Dbprintf(" [f] write_3.............%d*8 (%d)", T55xx_Timing.m[DLMode].write_3 / 8, T55xx_Timing.m[DLMode].write_3); - } - Dbprintf(" [g] readgap.............%d*8 (%d)", T55xx_Timing.m[DLMode].read_gap / 8, T55xx_Timing.m[DLMode].read_gap); - } + for (DLMode = 0; DLMode < 4; DLMode++) { + switch (DLMode) { + case T55xx_DLMode_Fixed : + Dbprintf("r 0 fixed bit length (default)"); + break; + case T55xx_DLMode_LLR : + Dbprintf("r 1 long leading reference"); + break; + case T55xx_DLMode_Leading0 : + Dbprintf("r 2 leading zero"); + break; + case T55xx_DLMode_1of4 : + Dbprintf("r 3 1 of 4 coding reference"); + break; + } + Dbprintf(" [a] startgap............%d*8 (%d)", T55xx_Timing.m[DLMode].start_gap / 8, T55xx_Timing.m[DLMode].start_gap); + Dbprintf(" [b] writegap............%d*8 (%d)", T55xx_Timing.m[DLMode].write_gap / 8, T55xx_Timing.m[DLMode].write_gap); + Dbprintf(" [c] write_0.............%d*8 (%d)", T55xx_Timing.m[DLMode].write_0 / 8, T55xx_Timing.m[DLMode].write_0); + Dbprintf(" [d] write_1.............%d*8 (%d)", T55xx_Timing.m[DLMode].write_1 / 8, T55xx_Timing.m[DLMode].write_1); + if (DLMode == T55xx_DLMode_1of4) { + Dbprintf(" [e] write_2.............%d*8 (%d)", T55xx_Timing.m[DLMode].write_2 / 8, T55xx_Timing.m[DLMode].write_2); + Dbprintf(" [f] write_3.............%d*8 (%d)", T55xx_Timing.m[DLMode].write_3 / 8, T55xx_Timing.m[DLMode].write_3); + } + Dbprintf(" [g] readgap.............%d*8 (%d)", T55xx_Timing.m[DLMode].read_gap / 8, T55xx_Timing.m[DLMode].read_gap); + } } void setT55xxConfig(uint8_t arg0, t55xx_config *c) { - uint8_t DLMode; -// uint8_t ClearT55Settings = c->m[0].start_gap & 0xffff; // all values will be ffff if clear requested - - - for (DLMode = 0; DLMode < 4; DLMode++) { - if (c->m[DLMode].start_gap != 0) T55xx_Timing.m[DLMode].start_gap = c->m[DLMode].start_gap;// * 8; - if (c->m[DLMode].write_gap != 0) T55xx_Timing.m[DLMode].write_gap = c->m[DLMode].write_gap;// * 8; - if (c->m[DLMode].write_0 != 0) T55xx_Timing.m[DLMode].write_0 = c->m[DLMode].write_0 ;// * 8; - if (c->m[DLMode].write_1 != 0) T55xx_Timing.m[DLMode].write_1 = c->m[DLMode].write_1 ;// * 8; - if (DLMode == T55xx_DLMode_1of4) { - if (c->m[DLMode].write_2 != 0) T55xx_Timing.m[DLMode].write_2 = c->m[DLMode].write_2;// * 8; - if (c->m[DLMode].write_3 != 0) T55xx_Timing.m[DLMode].write_3 = c->m[DLMode].write_3;// * 8 ; - } - else{ - T55xx_Timing.m[DLMode].write_2 = 0x00; - T55xx_Timing.m[DLMode].write_3 = 0x00; - } - if (c->m[DLMode].read_gap != 0) T55xx_Timing.m[DLMode].read_gap = c->m[DLMode].read_gap;//* 8; - } + uint8_t DLMode; +// uint8_t ClearT55Settings = c->m[0].start_gap & 0xffff; // all values will be ffff if clear requested + + + for (DLMode = 0; DLMode < 4; DLMode++) { + if (c->m[DLMode].start_gap != 0) T55xx_Timing.m[DLMode].start_gap = c->m[DLMode].start_gap;// * 8; + if (c->m[DLMode].write_gap != 0) T55xx_Timing.m[DLMode].write_gap = c->m[DLMode].write_gap;// * 8; + if (c->m[DLMode].write_0 != 0) T55xx_Timing.m[DLMode].write_0 = c->m[DLMode].write_0 ;// * 8; + if (c->m[DLMode].write_1 != 0) T55xx_Timing.m[DLMode].write_1 = c->m[DLMode].write_1 ;// * 8; + if (DLMode == T55xx_DLMode_1of4) { + if (c->m[DLMode].write_2 != 0) T55xx_Timing.m[DLMode].write_2 = c->m[DLMode].write_2;// * 8; + if (c->m[DLMode].write_3 != 0) T55xx_Timing.m[DLMode].write_3 = c->m[DLMode].write_3;// * 8 ; + } else { + T55xx_Timing.m[DLMode].write_2 = 0x00; + T55xx_Timing.m[DLMode].write_3 = 0x00; + } + if (c->m[DLMode].read_gap != 0) T55xx_Timing.m[DLMode].read_gap = c->m[DLMode].read_gap;//* 8; + } printT55xxConfig(); @@ -188,7 +201,7 @@ void setT55xxConfig(uint8_t arg0, t55xx_config *c) { return; } - + uint8_t *buf = BigBuf_malloc(T55XX_CONFIG_LEN); Flash_CheckBusy(BUSY_TIMEOUT); uint16_t res = Flash_ReadDataCont(T55XX_CONFIG_OFFSET, buf, T55XX_CONFIG_LEN); @@ -198,21 +211,21 @@ void setT55xxConfig(uint8_t arg0, t55xx_config *c) { return; } - // if ( ClearT55Settings) // dont copy over new timings + // if ( ClearT55Settings) // dont copy over new timings memcpy(buf, &T55xx_Timing, T55XX_CONFIG_LEN); - - Flash_CheckBusy(BUSY_TIMEOUT); + + Flash_CheckBusy(BUSY_TIMEOUT); Flash_WriteEnable(); Flash_Erase4k(3, 0xD); - // if not a settings erase, write data - // if ( ClearT55Settings) { - res = Flash_Write(T55XX_CONFIG_OFFSET, buf, T55XX_CONFIG_LEN); + // if not a settings erase, write data + // if ( ClearT55Settings) { + res = Flash_Write(T55XX_CONFIG_OFFSET, buf, T55XX_CONFIG_LEN); - if (res == T55XX_CONFIG_LEN && DBGLEVEL > 1) { + if (res == T55XX_CONFIG_LEN && DBGLEVEL > 1) { DbpString("T55XX Config save success"); - } -// } + } + // } BigBuf_free(); #endif @@ -246,8 +259,8 @@ void loadT55xxConfig(void) { return; } - if (buf[0] != 0xFF) // if not set for clear - memcpy((uint8_t *)&T55xx_Timing, buf, T55XX_CONFIG_LEN); + if (buf[0] != 0xFF) // if not set for clear + memcpy((uint8_t *)&T55xx_Timing, buf, T55XX_CONFIG_LEN); if (isok == T55XX_CONFIG_LEN) { if (DBGLEVEL > 1) DbpString("T55XX Config load success"); @@ -1470,7 +1483,7 @@ void TurnReadLF_off(uint32_t delay) { #define BitStream_Byte(X) ((X) >> 3) #define BitStream_Bit(X) ((X) & 7) #define t55_send_PwdMode (arg & 0x01) -#define t55_send_Page ((arg & 0x02) >> 1) +#define t55_send_Page ((arg & 0x02) >> 1) #define t55_send_TestMode ((arg & 0x04) >> 2) #define t55_send_RegReadMode ((arg & 0x20) >> 5) #define t55_send_ReadCmd ((arg & 0x40) >> 6) @@ -1479,18 +1492,28 @@ void TurnReadLF_off(uint32_t delay) { // Write one bit to chip void T55xxWriteBit(uint8_t bit, uint8_t downlink_idx) { - // Dbprintf ("%d",bit); - // If bit = 4 Send Long Leading Reference which is (138*8) + WRITE_0 - switch (bit){ - case 0 : TurnReadLFOn(T55xx_Timing.m[downlink_idx].write_0 ); break; // Send bit 0/00 - case 1 : TurnReadLFOn(T55xx_Timing.m[downlink_idx].write_1 ); break; // Send bit 1/01 - case 2 : TurnReadLFOn(T55xx_Timing.m[downlink_idx].write_2 ); break; // Send bits 10 (1 of 4) - case 3 : TurnReadLFOn(T55xx_Timing.m[downlink_idx].write_3 ); break; // Send bits 11 (1 of 4) - case 4 : TurnReadLFOn(T55xx_Timing.m[downlink_idx].write_0 + (136 * 8)); break; // Send Long Leading Reference - } + // Dbprintf ("%d",bit); + // If bit = 4 Send Long Leading Reference which is (138*8) + WRITE_0 + switch (bit) { + case 0 : + TurnReadLFOn(T55xx_Timing.m[downlink_idx].write_0); + break; // Send bit 0/00 + case 1 : + TurnReadLFOn(T55xx_Timing.m[downlink_idx].write_1); + break; // Send bit 1/01 + case 2 : + TurnReadLFOn(T55xx_Timing.m[downlink_idx].write_2); + break; // Send bits 10 (1 of 4) + case 3 : + TurnReadLFOn(T55xx_Timing.m[downlink_idx].write_3); + break; // Send bits 11 (1 of 4) + case 4 : + TurnReadLFOn(T55xx_Timing.m[downlink_idx].write_0 + (136 * 8)); + break; // Send Long Leading Reference + } - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - WaitUS(T55xx_Timing.m[downlink_idx].write_gap ); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + WaitUS(T55xx_Timing.m[downlink_idx].write_gap); } // Function to abstract an Arbitrary length byte array to store bit pattern. @@ -1500,152 +1523,147 @@ void T55xxWriteBit(uint8_t bit, uint8_t downlink_idx) { // num_bits - how many bits (low x bits of data) Max 32 bits at a time // max_len - how many bytes can the bit_array hold (ensure no buffer overflow) // returns "Next" bit offset / bits stored (for next store) -uint8_t T55xx_SetBits (uint8_t *BitStream, uint8_t start_offset, uint32_t data , uint8_t num_bits, uint8_t max_len) -{ - int8_t offset; - int8_t NextOffset = start_offset; +uint8_t T55xx_SetBits(uint8_t *BitStream, uint8_t start_offset, uint32_t data, uint8_t num_bits, uint8_t max_len) { + int8_t offset; + int8_t NextOffset = start_offset; - // Check if data will fit. - if ((start_offset + num_bits) <= (max_len*8)) { - // Loop through the data and store - for (offset = (num_bits-1); offset >= 0; offset--) { + // Check if data will fit. + if ((start_offset + num_bits) <= (max_len * 8)) { + // Loop through the data and store + for (offset = (num_bits - 1); offset >= 0; offset--) { - if ((data >> offset) & 1) BitStream[BitStream_Byte(NextOffset)] |= (1 << BitStream_Bit(NextOffset)); // Set the bit to 1 - else BitStream[BitStream_Byte(NextOffset)] &= (0xff ^ (1 << BitStream_Bit(NextOffset))); // Set the bit to 0 + if ((data >> offset) & 1) BitStream[BitStream_Byte(NextOffset)] |= (1 << BitStream_Bit(NextOffset)); // Set the bit to 1 + else BitStream[BitStream_Byte(NextOffset)] &= (0xff ^ (1 << BitStream_Bit(NextOffset))); // Set the bit to 0 - NextOffset++; - } - } - else { - // Note: This should never happen unless some code changes cause it. - // So short message for coders when testing. - Dbprintf ("T55 too many bits"); - } - return NextOffset; + NextOffset++; + } + } else { + // Note: This should never happen unless some code changes cause it. + // So short message for coders when testing. + Dbprintf("T55 too many bits"); + } + return NextOffset; } -// Send one downlink command to the card -// void T55xx_SendCMD (uint32_t Data, uint8_t Block, uint32_t Pwd, uint8_t arg) { -void T55xx_SendCMD (uint32_t Data, uint32_t Pwd, uint16_t arg) { +// Send one downlink command to the card +// void T55xx_SendCMD (uint32_t Data, uint8_t Block, uint32_t Pwd, uint8_t arg) { +void T55xx_SendCMD(uint32_t Data, uint32_t Pwd, uint16_t arg) { - /* - arg bits - xxxx xxxxxxx1 0x001 PwdMode - xxxx xxxxxx1x 0x002 Page - xxxx xxxxx1xx 0x004 testMode - xxxx xxx11xxx 0x018 downlink mode - xxxx xx1xxxxx 0x020 !reg_readmode - xxxx x1xxxxxx 0x040 called for a read, so no data packet - xxxx 1xxxxxxx 0x080 reset - xxx1 xxxxxxxx 0x100 brute force - 111x xxxxxxxx 0xE00 Block - - */ + /* + arg bits + xxxx xxxxxxx1 0x001 PwdMode + xxxx xxxxxx1x 0x002 Page + xxxx xxxxx1xx 0x004 testMode + xxxx xxx11xxx 0x018 downlink mode + xxxx xx1xxxxx 0x020 !reg_readmode + xxxx x1xxxxxx 0x040 called for a read, so no data packet + xxxx 1xxxxxxx 0x080 reset + xxx1 xxxxxxxx 0x100 brute force + 111x xxxxxxxx 0xE00 Block + */ - uint8_t downlink_mode = (arg >> 3) & 0x03; - uint8_t i = 0; - uint8_t BitStream[10]; // Max Downlink Command size ~74 bits, so 10 bytes (80 bits) - uint8_t BitStreamLen = 0; - uint8_t SendBits; - uint8_t start_wait = 4; - bool brute_mem = (arg & 0x100); - uint8_t Block = (arg >> 9) & 0x07; - - if (brute_mem) start_wait = 0; - - // Build Bit Stream to send. - memset (BitStream,0x00,sizeof(BitStream)); - - BitStreamLen = 0; // Ensure 0 bit index to start. - - // Add Leading 0 and 1 of 4 reference bit - if ((downlink_mode == T55xx_DLMode_Leading0) || (downlink_mode == T55xx_DLMode_1of4)) - BitStreamLen = T55xx_SetBits (BitStream, BitStreamLen, 0, 1,sizeof(BitStream)); + uint8_t downlink_mode = (arg >> 3) & 0x03; + uint8_t i = 0; + uint8_t BitStream[10]; // Max Downlink Command size ~74 bits, so 10 bytes (80 bits) + uint8_t BitStreamLen = 0; + uint8_t SendBits; + uint8_t start_wait = 4; + bool brute_mem = (arg & 0x100); + uint8_t Block = (arg >> 9) & 0x07; - // Add extra reference 0 for 1 of 4 - if (downlink_mode == T55xx_DLMode_1of4) - BitStreamLen = T55xx_SetBits (BitStream, BitStreamLen, 0, 1,sizeof(BitStream)); + if (brute_mem) start_wait = 0; - // Add Opcode - if (t55_send_Reset) { - // Reset : r*) 00 - BitStreamLen = T55xx_SetBits (BitStream, BitStreamLen, 0, 2,sizeof(BitStream)); - } - else { - if (t55_send_TestMode) Dbprintf("TestMODE"); - BitStreamLen = T55xx_SetBits (BitStream, BitStreamLen,t55_send_TestMode ? 0 : 1 , 1,sizeof(BitStream)); - BitStreamLen = T55xx_SetBits (BitStream, BitStreamLen,t55_send_TestMode ? 1 : t55_send_Page , 1,sizeof(BitStream)); - //if (PwdMode) { - if (t55_send_PwdMode) { - // Leading 0 and 1 of 4 00 fixed bits if passsword used - if ((downlink_mode == T55xx_DLMode_Leading0) || (downlink_mode == T55xx_DLMode_1of4)) { - BitStreamLen = T55xx_SetBits (BitStream, BitStreamLen, 0, 2,sizeof(BitStream)); - } - BitStreamLen = T55xx_SetBits (BitStream, BitStreamLen, Pwd, 32,sizeof(BitStream)); - } + // Build Bit Stream to send. + memset(BitStream, 0x00, sizeof(BitStream)); - // Add Lock bit 0 - if (!t55_send_RegReadMode) BitStreamLen = T55xx_SetBits (BitStream, BitStreamLen, 0, 1,sizeof(BitStream)); + BitStreamLen = 0; // Ensure 0 bit index to start. - // Add Data if a write command - if (!t55_send_ReadCmd) BitStreamLen = T55xx_SetBits (BitStream, BitStreamLen, Data, 32,sizeof(BitStream)); + // Add Leading 0 and 1 of 4 reference bit + if ((downlink_mode == T55xx_DLMode_Leading0) || (downlink_mode == T55xx_DLMode_1of4)) + BitStreamLen = T55xx_SetBits(BitStream, BitStreamLen, 0, 1, sizeof(BitStream)); - // Add Address - if (!t55_send_RegReadMode) BitStreamLen = T55xx_SetBits (BitStream, BitStreamLen, Block, 3,sizeof(BitStream)); - } + // Add extra reference 0 for 1 of 4 + if (downlink_mode == T55xx_DLMode_1of4) + BitStreamLen = T55xx_SetBits(BitStream, BitStreamLen, 0, 1, sizeof(BitStream)); - // Send Bits to T55xx - // Set up FPGA, 125kHz - LFSetupFPGAForADC(95, true); + // Add Opcode + if (t55_send_Reset) { + // Reset : r*) 00 + BitStreamLen = T55xx_SetBits(BitStream, BitStreamLen, 0, 2, sizeof(BitStream)); + } else { + if (t55_send_TestMode) Dbprintf("TestMODE"); + BitStreamLen = T55xx_SetBits(BitStream, BitStreamLen, t55_send_TestMode ? 0 : 1, 1, sizeof(BitStream)); + BitStreamLen = T55xx_SetBits(BitStream, BitStreamLen, t55_send_TestMode ? 1 : t55_send_Page, 1, sizeof(BitStream)); + //if (PwdMode) { + if (t55_send_PwdMode) { + // Leading 0 and 1 of 4 00 fixed bits if passsword used + if ((downlink_mode == T55xx_DLMode_Leading0) || (downlink_mode == T55xx_DLMode_1of4)) { + BitStreamLen = T55xx_SetBits(BitStream, BitStreamLen, 0, 2, sizeof(BitStream)); + } + BitStreamLen = T55xx_SetBits(BitStream, BitStreamLen, Pwd, 32, sizeof(BitStream)); + } - // make sure tag is fully powered up... - WaitMS(start_wait); + // Add Lock bit 0 + if (!t55_send_RegReadMode) BitStreamLen = T55xx_SetBits(BitStream, BitStreamLen, 0, 1, sizeof(BitStream)); - // Trigger T55x7 in mode. - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - WaitUS(T55xx_Timing.m[downlink_mode].start_gap * 8); + // Add Data if a write command + if (!t55_send_ReadCmd) BitStreamLen = T55xx_SetBits(BitStream, BitStreamLen, Data, 32, sizeof(BitStream)); - // If long leading 0 send long reference pulse - if (downlink_mode == T55xx_DLMode_LLR) - T55xxWriteBit (T55xx_LongLeadingReference,downlink_mode);//Timing); // Send Long Leading Start Reference + // Add Address + if (!t55_send_RegReadMode) BitStreamLen = T55xx_SetBits(BitStream, BitStreamLen, Block, 3, sizeof(BitStream)); + } - if ((downlink_mode == T55xx_DLMode_1of4) && (BitStreamLen > 0)) { // 1 of 4 need to send 2 bits at a time - for ( i = 0; i < BitStreamLen-1; i+=2 ) { - SendBits = (BitStream[BitStream_Byte(i )] >> (BitStream_Bit(i )) & 1) << 1; // Bit i - SendBits += (BitStream[BitStream_Byte(i+1)] >> (BitStream_Bit(i+1)) & 1); // Bit i+1; - T55xxWriteBit (SendBits & 3,downlink_mode);//Timing); - } - } - else { - for (i = 0; i < BitStreamLen; i++) { - SendBits = (BitStream[BitStream_Byte(i)] >> BitStream_Bit(i)); - T55xxWriteBit (SendBits & 1,downlink_mode);//Timing); - } - } + // Send Bits to T55xx + // Set up FPGA, 125kHz + LFSetupFPGAForADC(95, true); + + // make sure tag is fully powered up... + WaitMS(start_wait); + + // Trigger T55x7 in mode. + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + WaitUS(T55xx_Timing.m[downlink_mode].start_gap * 8); + + // If long leading 0 send long reference pulse + if (downlink_mode == T55xx_DLMode_LLR) + T55xxWriteBit(T55xx_LongLeadingReference, downlink_mode);//Timing); // Send Long Leading Start Reference + + if ((downlink_mode == T55xx_DLMode_1of4) && (BitStreamLen > 0)) { // 1 of 4 need to send 2 bits at a time + for (i = 0; i < BitStreamLen - 1; i += 2) { + SendBits = (BitStream[BitStream_Byte(i)] >> (BitStream_Bit(i)) & 1) << 1; // Bit i + SendBits += (BitStream[BitStream_Byte(i + 1)] >> (BitStream_Bit(i + 1)) & 1); // Bit i+1; + T55xxWriteBit(SendBits & 3, downlink_mode);//Timing); + } + } else { + for (i = 0; i < BitStreamLen; i++) { + SendBits = (BitStream[BitStream_Byte(i)] >> BitStream_Bit(i)); + T55xxWriteBit(SendBits & 1, downlink_mode);//Timing); + } + } } // Send T5577 reset command then read stream (see if we can identify the start of the stream) void T55xxResetRead(uint8_t flags) { - uint8_t downlink_mode = ((flags >> 3) & 3); - uint8_t arg = 0x80 | downlink_mode; - + uint8_t downlink_mode = ((flags >> 3) & 3); + uint8_t arg = 0x80 | downlink_mode; + LED_A_ON(); - + //clear buffer now so it does not interfere with timing later BigBuf_Clear_keep_EM(); - T55xx_SendCMD (0, 0, arg); + T55xx_SendCMD(0, 0, arg); TurnReadLFOn(T55xx_Timing.m[downlink_mode].read_gap); - + // Acquisition DoPartialAcquisition(0, true, BigBuf_max_traceLen(), 0); // Turn the field off FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off reply_mix(CMD_ACK, 0, 0, 0, 0, 0); - + LED_A_OFF(); } @@ -1653,60 +1671,60 @@ void T55xxResetRead(uint8_t flags) { //void T55xxWriteBlockExt(uint32_t data, uint8_t blockno, uint32_t pwd, uint8_t flags) { void T55xxWriteBlock(uint8_t *data) { - /* - flag bits - xxxxxxx1 0x01 PwdMode - xxxxxx1x 0x02 Page - xxxxx1xx 0x04 testMode - xxx11xxx 0x18 downlink mode - xx1xxxxx 0x20 !reg_readmode - x1xxxxxx 0x40 called for a read, so no data packet - 1xxxxxxx 0x80 reset - */ - - t55xx_write_block_t *c = (t55xx_write_block_t *)data; - // c->data, c->blockno, c->pwd, c->flags + /* + flag bits + xxxxxxx1 0x01 PwdMode + xxxxxx1x 0x02 Page + xxxxx1xx 0x04 testMode + xxx11xxx 0x18 downlink mode + xx1xxxxx 0x20 !reg_readmode + x1xxxxxx 0x40 called for a read, so no data packet + 1xxxxxxx 0x80 reset + */ - bool testMode = ((c->flags & 0x04) == 0x04); + t55xx_write_block_t *c = (t55xx_write_block_t *)data; + // c->data, c->blockno, c->pwd, c->flags - c->flags &= (0xff ^ 0x40); // Called for a write, so ensure it is clear/0 - - LED_A_ON (); - T55xx_SendCMD (c->data, c->pwd, c->flags | (c->blockno << 9)) ;//, false); + bool testMode = ((c->flags & 0x04) == 0x04); - // Perform write (nominal is 5.6 ms for T55x7 and 18ms for E5550, - // so wait a little more) + c->flags &= (0xff ^ 0x40); // Called for a write, so ensure it is clear/0 - // "there is a clock delay before programming" - // - programming takes ~5.6ms for t5577 ~18ms for E5550 or t5567 - // so we should wait 1 clock + 5.6ms then read response? - // but we need to know we are dealing with t5577 vs t5567 vs e5550 (or q5) marshmellow... - if (testMode) { - //TESTMODE TIMING TESTS: - // <566us does nothing - // 566-568 switches between wiping to 0s and doing nothing - // 5184 wipes and allows 1 block to be programmed. - // indefinite power on wipes and then programs all blocks with bitshifted data sent. - TurnReadLFOn(5184); + LED_A_ON(); + T55xx_SendCMD(c->data, c->pwd, c->flags | (c->blockno << 9)) ; //, false); - } else { - TurnReadLFOn(20 * 1000); - //could attempt to do a read to confirm write took - // as the tag should repeat back the new block - // until it is reset, but to confirm it we would - // need to know the current block 0 config mode for - // modulation clock an other details to demod the response... - // response should be (for t55x7) a 0 bit then (ST if on) - // block data written in on repeat until reset. + // Perform write (nominal is 5.6 ms for T55x7 and 18ms for E5550, + // so wait a little more) - //DoPartialAcquisition(20, true, 12000); - } - // turn field off - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + // "there is a clock delay before programming" + // - programming takes ~5.6ms for t5577 ~18ms for E5550 or t5567 + // so we should wait 1 clock + 5.6ms then read response? + // but we need to know we are dealing with t5577 vs t5567 vs e5550 (or q5) marshmellow... + if (testMode) { + //TESTMODE TIMING TESTS: + // <566us does nothing + // 566-568 switches between wiping to 0s and doing nothing + // 5184 wipes and allows 1 block to be programmed. + // indefinite power on wipes and then programs all blocks with bitshifted data sent. + TurnReadLFOn(5184); - // cmd_send(CMD_ACK,0,0,0,0,0); - reply_ng(CMD_T55XX_WRITE_BLOCK, PM3_SUCCESS, NULL, 0); - LED_A_OFF (); + } else { + TurnReadLFOn(20 * 1000); + //could attempt to do a read to confirm write took + // as the tag should repeat back the new block + // until it is reset, but to confirm it we would + // need to know the current block 0 config mode for + // modulation clock an other details to demod the response... + // response should be (for t55x7) a 0 bit then (ST if on) + // block data written in on repeat until reset. + + //DoPartialAcquisition(20, true, 12000); + } + // turn field off + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + + // cmd_send(CMD_ACK,0,0,0,0,0); + reply_ng(CMD_T55XX_WRITE_BLOCK, PM3_SUCCESS, NULL, 0); + LED_A_OFF(); } /* @@ -1719,49 +1737,49 @@ void T55xxWriteBlock(uint8_t *data) { */ /* // Read one card block in page [page] -void T55xxReadBlockExt (uint16_t flags, uint8_t block, uint32_t pwd) { - / * - flag bits - xxxx xxxxxxx1 0x0001 PwdMode - xxxx xxxxxx1x 0x0002 Page - xxxx xxxxx1xx 0x0004 testMode - xxxx xxx11xxx 0x0018 downlink mode - xxxx xx1xxxxx 0x0020 !reg_readmode - xxxx x1xxxxxx 0x0040 called for a read, so no data packet - xxxx 1xxxxxxx 0x0080 reset - xxx1 xxxxxxxx 0x0100 brute/leave field on - * / - size_t samples = 12000; - bool brute_mem = (flags & 0x0100) >> 8; - - LED_A_ON(); +void T55xxReadBlockExt(uint16_t flags, uint8_t block, uint32_t pwd) { + / * + flag bits + xxxx xxxxxxx1 0x0001 PwdMode + xxxx xxxxxx1x 0x0002 Page + xxxx xxxxx1xx 0x0004 testMode + xxxx xxx11xxx 0x0018 downlink mode + xxxx xx1xxxxx 0x0020 !reg_readmode + xxxx x1xxxxxx 0x0040 called for a read, so no data packet + xxxx 1xxxxxxx 0x0080 reset + xxx1 xxxxxxxx 0x0100 brute / leave field on + * / + size_t samples = 12000; +bool brute_mem = (flags & 0x0100) >> 8; - if (brute_mem) samples = 1024; - - // Set Read Flag to ensure SendCMD does not add "data" to the packet - flags |= 0x40; + LED_A_ON(); - // RegRead Mode true block = 0xff, so read without an address - if (block == 0xff) flags |= 0x20; - - //make sure block is at max 7 - block &= 0x7; + if (brute_mem) samples = 1024; - //clear buffer now so it does not interfere with timing later - BigBuf_Clear_keep_EM(); + // Set Read Flag to ensure SendCMD does not add "data" to the packet + flags |= 0x40; - T55xx_SendCMD (0, pwd, flags | (block << 9)); //, true); + // RegRead Mode true block = 0xff, so read without an address + if (block == 0xff) flags |= 0x20; - // Turn field on to read the response - // 137*8 seems to get to the start of data pretty well... - // but we want to go past the start and let the repeating data settle in... + //make sure block is at max 7 + block &= 0x7; - // TurnReadLFOn(210*8); // issues with block 1 reads so dropping down seemed to help - TurnReadLFOn(137*8); + //clear buffer now so it does not interfere with timing later + BigBuf_Clear_keep_EM(); - // Acquisition - // Now do the acquisition - DoPartialAcquisition(0, true, samples, 0); + T55xx_SendCMD(0, pwd, flags | (block << 9)); //, true); + + // Turn field on to read the response + // 137*8 seems to get to the start of data pretty well... + // but we want to go past the start and let the repeating data settle in... + + // TurnReadLFOn(210*8); // issues with block 1 reads so dropping down seemed to help + TurnReadLFOn(137 * 8); + + // Acquisition + // Now do the acquisition + DoPartialAcquisition(0, true, samples, 0); // Turn the field off if (!brute_mem) { @@ -1773,55 +1791,55 @@ void T55xxReadBlockExt (uint16_t flags, uint8_t block, uint32_t pwd) { */ // Read one card block in page [page] void T55xxReadBlock(uint8_t page, bool pwd_mode, bool brute_mem, uint8_t block, uint32_t pwd, uint8_t downlink_mode) { - /* - flag bits - xxxxxxx1 0x0001 PwdMode - xxxxxx1x 0x0002 Page - xxxxx1xx 0x0004 testMode - xxx11xxx 0x0018 downlink mode - xx1xxxxx 0x0020 !reg_readmode - x1xxxxxx 0x0040 called for a read, so no data packet - 1xxxxxxx 0x0080 reset - 1xxxxxxxx 0x0100 brute/leave field on - */ - uint16_t flags = 0x0040; // read packet - if (pwd_mode) flags |= 0x0001; - if (page) flags |= 0x0002; - flags |= (downlink_mode & 3) << 3; - if (brute_mem) flags |= 0x0100; - -// T55xxReadBlockExt (flags,block,pwd); - size_t samples = 12000; - // bool brute_mem = (flags & 0x0100) >> 8; - - LED_A_ON(); + /* + flag bits + xxxx xxxxxxx1 0x0001 PwdMode + xxxx xxxxxx1x 0x0002 Page + xxxx xxxxx1xx 0x0004 testMode + xxxx xxx11xxx 0x0018 downlink mode + xxxx xx1xxxxx 0x0020 !reg_readmode + xxxx x1xxxxxx 0x0040 called for a read, so no data packet + xxxx 1xxxxxxx 0x0080 reset + xxx1 xxxxxxxx 0x0100 brute / leave field on + */ + uint16_t flags = 0x0040; // read packet + if (pwd_mode) flags |= 0x0001; + if (page) flags |= 0x0002; + flags |= (downlink_mode & 3) << 3; + if (brute_mem) flags |= 0x0100; - if (brute_mem) samples = 1024; - - //-- Set Read Flag to ensure SendCMD does not add "data" to the packet - //-- flags |= 0x40; +// T55xxReadBlockExt (flags,block,pwd); + size_t samples = 12000; + // bool brute_mem = (flags & 0x0100) >> 8; - // RegRead Mode true block = 0xff, so read without an address - if (block == 0xff) flags |= 0x20; - - //make sure block is at max 7 - block &= 0x7; + LED_A_ON(); - //clear buffer now so it does not interfere with timing later - BigBuf_Clear_keep_EM(); + if (brute_mem) samples = 1024; - T55xx_SendCMD (0, pwd, flags | (block << 9)); //, true); + //-- Set Read Flag to ensure SendCMD does not add "data" to the packet + //-- flags |= 0x40; - // Turn field on to read the response - // 137*8 seems to get to the start of data pretty well... - // but we want to go past the start and let the repeating data settle in... + // RegRead Mode true block = 0xff, so read without an address + if (block == 0xff) flags |= 0x20; - // TurnReadLFOn(210*8); // issues with block 1 reads so dropping down seemed to help - TurnReadLFOn(137*8); + //make sure block is at max 7 + block &= 0x7; - // Acquisition - // Now do the acquisition - DoPartialAcquisition(0, true, samples, 0); + //clear buffer now so it does not interfere with timing later + BigBuf_Clear_keep_EM(); + + T55xx_SendCMD(0, pwd, flags | (block << 9)); //, true); + + // Turn field on to read the response + // 137*8 seems to get to the start of data pretty well... + // but we want to go past the start and let the repeating data settle in... + + // TurnReadLFOn(210*8); // issues with block 1 reads so dropping down seemed to help + TurnReadLFOn(137 * 8); + + // Acquisition + // Now do the acquisition + DoPartialAcquisition(0, true, samples, 0); // Turn the field off if (!brute_mem) { @@ -1841,13 +1859,13 @@ void T55xx_ChkPwds(uint8_t flags) { // tends to mess up BigBuf uint8_t *buf = BigBuf_get_addr(); uint32_t b1, baseline = 0; - uint8_t downlink_mode = (flags >> 3) & 0x03; - + uint8_t downlink_mode = (flags >> 3) & 0x03; + // collect baseline for failed attempt uint8_t x = 32; while (x--) { b1 = 0; - T55xxReadBlock(0, 0, true, 1, 0,downlink_mode); + T55xxReadBlock(0, 0, true, 1, 0, downlink_mode); for (uint16_t j = 0; j < 1024; ++j) b1 += buf[j]; @@ -1892,7 +1910,7 @@ void T55xx_ChkPwds(uint8_t flags) { pwd = bytes_to_num(pwds + i * 4, 4); - T55xxReadBlock(0, true, true, 0, pwd,downlink_mode); + T55xxReadBlock(0, true, true, 0, pwd, downlink_mode); // calc mean of BigBuf 1024 samples. uint32_t sum = 0; @@ -1909,7 +1927,7 @@ void T55xx_ChkPwds(uint8_t flags) { Dbprintf("[=] Pwd %08X | ABS %u", pwd, curr); if (curr > prev) { - Dbprintf("[=] --> ABS %u Candidate %08X <--", curr, pwd); + Dbprintf("[=] --> ABS %u Candidate %08X <--", curr, pwd); candidate = pwd; prev = curr; } @@ -1925,12 +1943,12 @@ OUT: } void T55xxWakeUp(uint32_t Pwd, uint8_t flags) { - - flags |= 0x01 | 0x40 | 0x20; //Password | Read Call (no data) | reg_read no block + + flags |= 0x01 | 0x40 | 0x20; //Password | Read Call (no data) | reg_read no block LED_B_ON(); - T55xx_SendCMD (0, Pwd, flags); - + T55xx_SendCMD(0, Pwd, flags); + //-- Turn and leave field on to let the begin repeating transmission TurnReadLFOn(20 * 1000); } @@ -1939,16 +1957,16 @@ void T55xxWakeUp(uint32_t Pwd, uint8_t flags) { /*-------------- Cloning routines -----------*/ void WriteT55xx(uint32_t *blockdata, uint8_t startblock, uint8_t numblocks) { - t55xx_write_block_t cmd; - cmd.pwd = 0; + t55xx_write_block_t cmd; + cmd.pwd = 0; cmd.flags = 0; - for (uint8_t i = numblocks + startblock; i > startblock; i--) { - cmd.data = blockdata[i - 1]; - cmd.blockno = i - 1; - T55xxWriteBlock ((uint8_t *)&cmd); - } - + for (uint8_t i = numblocks + startblock; i > startblock; i--) { + cmd.data = blockdata[i - 1]; + cmd.blockno = i - 1; + T55xxWriteBlock((uint8_t *)&cmd); + } + } // Copy HID id to card and setup block 0 config diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 618ab8c7c..69cd8251b 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -49,8 +49,8 @@ static int usage_t55xx_read() { PrintAndLogEx(NORMAL, " p - OPTIONAL password (8 hex characters)"); PrintAndLogEx(NORMAL, " o - OPTIONAL override safety check"); PrintAndLogEx(NORMAL, " 1 - OPTIONAL read Page 1 instead of Page 0"); - PrintAndLogEx(NORMAL, " r - downlink encoding '0' fixed bit length (default), '1' long leading ref."); - PrintAndLogEx(NORMAL, " '2' leading zero, '3' 1 of 4 coding ref."); + PrintAndLogEx(NORMAL, " r - downlink encoding '0' fixed bit length (default), '1' long leading ref."); + PrintAndLogEx(NORMAL, " '2' leading zero, '3' 1 of 4 coding ref."); PrintAndLogEx(NORMAL, " ****WARNING****"); PrintAndLogEx(NORMAL, " Use of read with password on a tag not configured for a pwd"); PrintAndLogEx(NORMAL, " can damage the tag"); @@ -70,8 +70,8 @@ static int usage_t55xx_write() { PrintAndLogEx(NORMAL, " p - OPTIONAL password 4bytes (8 hex characters)"); PrintAndLogEx(NORMAL, " 1 - OPTIONAL write Page 1 instead of Page 0"); PrintAndLogEx(NORMAL, " t - OPTIONAL test mode write - ****DANGER****"); - PrintAndLogEx(NORMAL, " r - downlink encoding '0' fixed bit length (default), '1' long leading ref."); - PrintAndLogEx(NORMAL, " '2' leading zero, '3' 1 of 4 coding ref."); + PrintAndLogEx(NORMAL, " r - downlink encoding '0' fixed bit length (default), '1' long leading ref."); + PrintAndLogEx(NORMAL, " '2' leading zero, '3' 1 of 4 coding ref."); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx write b 3 d 11223344 - write 11223344 to block 3"); @@ -82,10 +82,10 @@ static int usage_t55xx_write() { static int usage_t55xx_trace() { PrintAndLogEx(NORMAL, "Usage: lf t55xx trace [r mode]"); PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " r - downlink encoding '0' fixed bit length (default), '1' long leading ref."); - PrintAndLogEx(NORMAL, " '2' leading zero, '3' 1 of 4 coding ref."); + PrintAndLogEx(NORMAL, " r - downlink encoding '0' fixed bit length (default), '1' long leading ref."); + PrintAndLogEx(NORMAL, " '2' leading zero, '3' 1 of 4 coding ref."); // Command did not seem to support the 1 option (yet) so have removed the help lines - // PrintAndLogEx(NORMAL, " 1 - if set, use Graphbuffer otherwise read data from tag."); + // PrintAndLogEx(NORMAL, " 1 - if set, use Graphbuffer otherwise read data from tag."); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx trace"); @@ -101,8 +101,8 @@ static int usage_t55xx_info() { PrintAndLogEx(NORMAL, " d - 4 bytes of data (8 hex characters)"); PrintAndLogEx(NORMAL, " if set, use these data instead of reading tag."); PrintAndLogEx(NORMAL, " q - if set, provided data are interpreted as Q5 config."); - PrintAndLogEx(NORMAL, " r - downlink encoding '0' fixed bit length (default), '1' long leading ref."); - PrintAndLogEx(NORMAL, " '2' leading zero, '3' 1 of 4 coding ref."); + PrintAndLogEx(NORMAL, " r - downlink encoding '0' fixed bit length (default), '1' long leading ref."); + PrintAndLogEx(NORMAL, " '2' leading zero, '3' 1 of 4 coding ref."); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx info"); @@ -117,8 +117,8 @@ static int usage_t55xx_dump() { PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " - OPTIONAL password 4bytes (8 hex symbols)"); PrintAndLogEx(NORMAL, " o - OPTIONAL override, force pwd read despite danger to card"); - PrintAndLogEx(NORMAL, " r - downlink encoding '0' fixed bit length (default), '1' long leading ref."); - PrintAndLogEx(NORMAL, " '2' leading zero, '3' 1 of 4 coding ref."); + PrintAndLogEx(NORMAL, " r - downlink encoding '0' fixed bit length (default), '1' long leading ref."); + PrintAndLogEx(NORMAL, " '2' leading zero, '3' 1 of 4 coding ref."); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx dump"); @@ -131,9 +131,9 @@ static int usage_t55xx_detect() { PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " 1 - if set, use Graphbuffer otherwise read data from tag."); PrintAndLogEx(NORMAL, " p - downlink encoding '0' fixed bit length (default)"); - PrintAndLogEx(NORMAL, " '1' long leading ref., '2' leading zero "); - PrintAndLogEx(NORMAL, " '3' 1 of 4 coding ref., '4' try all modes"); + PrintAndLogEx(NORMAL, " r - downlink encoding '0' fixed bit length (default)"); + PrintAndLogEx(NORMAL, " '1' long leading ref., '2' leading zero "); + PrintAndLogEx(NORMAL, " '3' 1 of 4 coding ref., '4' try all modes"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx detect"); @@ -148,9 +148,9 @@ static int usage_t55xx_detectP1() { PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " 1 - if set, use Graphbuffer otherwise read data from tag."); PrintAndLogEx(NORMAL, " p - OPTIONAL password (8 hex characters)"); - PrintAndLogEx(NORMAL, " r - downlink encoding '0' fixed bit length (default)"); - PrintAndLogEx(NORMAL, " '1' long leading ref., '2' leading zero "); - PrintAndLogEx(NORMAL, " '3' 1 of 4 coding ref., '4' try all modes"); + PrintAndLogEx(NORMAL, " r - downlink encoding '0' fixed bit length (default)"); + PrintAndLogEx(NORMAL, " '1' long leading ref., '2' leading zero "); + PrintAndLogEx(NORMAL, " '3' 1 of 4 coding ref., '4' try all modes"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx p1detect"); @@ -165,8 +165,8 @@ static int usage_t55xx_wakup() { PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h - this help"); PrintAndLogEx(NORMAL, " p - password 4bytes (8 hex symbols)"); - PrintAndLogEx(NORMAL, " r - downlink encoding '0' fixed bit length (default), '1' long leading ref."); - PrintAndLogEx(NORMAL, " '2' leading zero, '3' 1 of 4 coding ref."); + PrintAndLogEx(NORMAL, " r - downlink encoding '0' fixed bit length (default), '1' long leading ref."); + PrintAndLogEx(NORMAL, " '2' leading zero, '3' 1 of 4 coding ref."); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx wakeup p 11223344 - send wakeup password"); @@ -181,9 +181,9 @@ static int usage_t55xx_chk() { PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h - this help"); PrintAndLogEx(NORMAL, " m - use dictionary from flashmemory\n"); - PrintAndLogEx(NORMAL, " r - downlink encoding '0' fixed bit length (default)"); - PrintAndLogEx(NORMAL, " '1' long leading ref., '2' leading zero "); - PrintAndLogEx(NORMAL, " '3' 1 of 4 coding ref., '4' try all modes"); + PrintAndLogEx(NORMAL, " r - downlink encoding '0' fixed bit length (default)"); + PrintAndLogEx(NORMAL, " '1' long leading ref., '2' leading zero "); + PrintAndLogEx(NORMAL, " '3' 1 of 4 coding ref., '4' try all modes"); PrintAndLogEx(NORMAL, " i <*.dic> - loads a default keys dictionary file <*.dic>"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); @@ -201,9 +201,9 @@ static int usage_t55xx_bruteforce() { PrintAndLogEx(NORMAL, " password must be 4 bytes (8 hex symbols)"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h - this help"); - PrintAndLogEx(NORMAL, " r - downlink encoding '0' fixed bit length (default)"); - PrintAndLogEx(NORMAL, " '1' long leading ref., '2' leading zero "); - PrintAndLogEx(NORMAL, " '3' 1 of 4 coding ref., '4' try all modes"); + PrintAndLogEx(NORMAL, " r - downlink encoding '0' fixed bit length (default)"); + PrintAndLogEx(NORMAL, " '1' long leading ref., '2' leading zero "); + PrintAndLogEx(NORMAL, " '3' 1 of 4 coding ref., '4' try all modes"); PrintAndLogEx(NORMAL, " - 4 byte hex value to start pwd search at"); PrintAndLogEx(NORMAL, " - 4 byte hex value to end pwd search at"); PrintAndLogEx(NORMAL, ""); @@ -222,9 +222,9 @@ static int usage_t55xx_recoverpw() { PrintAndLogEx(NORMAL, " default password is 51243648, used by many cloners"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h - this help"); - PrintAndLogEx(NORMAL, " r - downlink encoding '0' fixed bit length (default)"); - PrintAndLogEx(NORMAL, " '1' long leading ref., '2' leading zero "); - PrintAndLogEx(NORMAL, " '3' 1 of 4 coding ref., '4' try all modes"); + PrintAndLogEx(NORMAL, " r - downlink encoding '0' fixed bit length (default)"); + PrintAndLogEx(NORMAL, " '1' long leading ref., '2' leading zero "); + PrintAndLogEx(NORMAL, " '3' 1 of 4 coding ref., '4' try all modes"); PrintAndLogEx(NORMAL, " [password] - 4 byte hex value of password written by cloner"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); @@ -258,10 +258,10 @@ static int usage_lf_deviceconfig() { PrintAndLogEx(NORMAL, " f <8..255> - Set write THREE gap (1 of 4 only)"); PrintAndLogEx(NORMAL, " g <8..255> - Set read gap"); PrintAndLogEx(NORMAL, " p - persist to flashmemory"); - PrintAndLogEx(NORMAL, " r - downlink encoding '0' fixed bit length (default), '1' long leading ref."); - PrintAndLogEx(NORMAL, " '2' leading zero, '3' 1 of 4 coding ref."); - PrintAndLogEx(NORMAL, " z - erase t55x7 timings (needs p and reboot to load defaults)"); - PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, " r - downlink encoding '0' fixed bit length (default), '1' long leading ref."); + PrintAndLogEx(NORMAL, " '2' leading zero, '3' 1 of 4 coding ref."); + PrintAndLogEx(NORMAL, " z - erase t55x7 timings (needs p and reboot to load defaults)"); + PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx deviceconfig a 29 b 17 c 15 d 47 e 15 - default T55XX"); PrintAndLogEx(NORMAL, " lf t55xx deviceconfig a 55 b 14 c 21 d 30 - default EM4305"); @@ -397,7 +397,7 @@ int T55xxReadBlock(uint8_t block, bool page1, bool usepwd, uint8_t override, uin if (usepwd) { // try reading the config block and verify that PWD bit is set before doing this! if (!override) { - if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, false, 0,downlink_mode)) return PM3_ESOFT; + if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, false, 0, downlink_mode)) return PM3_ESOFT; if (!tryDetectModulation()) { PrintAndLogEx(NORMAL, "Safety Check: Could not detect if PWD bit is set in config block. Exits."); @@ -408,9 +408,9 @@ int T55xxReadBlock(uint8_t block, bool page1, bool usepwd, uint8_t override, uin page1 = false; } } else { - // Show only if first for command i.e. override = 1 (override and display) override = 2 (override and dont display) - if ((override & 2) != 2) - PrintAndLogEx(NORMAL, "Safety Check Overriden - proceeding despite risk"); + // Show only if first for command i.e. override = 1 (override and display) override = 2 (override and dont display) + if ((override & 2) != 2) + PrintAndLogEx(NORMAL, "Safety Check Overriden - proceeding despite risk"); } } @@ -430,8 +430,8 @@ static int CmdT55xxReadBlock(const char *Cmd) { bool page1 = false; bool errors = false; uint8_t cmdp = 0; - uint8_t downlink_mode = 0; - + uint8_t downlink_mode = 0; + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { case 'h': @@ -453,13 +453,13 @@ static int CmdT55xxReadBlock(const char *Cmd) { page1 = true; cmdp++; break; - case 'r': - case 'R': - downlink_mode = param_getchar(Cmd, cmdp+1) - '0'; - if (downlink_mode > 3) downlink_mode = 0; - cmdp +=2; - break; - + case 'r': + case 'R': + downlink_mode = param_getchar(Cmd, cmdp + 1) - '0'; + if (downlink_mode > 3) downlink_mode = 0; + cmdp += 2; + break; + default: PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); errors = true; @@ -556,34 +556,42 @@ static int SanityOfflineCheck(bool useGraphBuffer) { return PM3_SUCCESS; } -void T55xx_Print_DownlinkMode (uint8_t downlink_mode) -{ - char Msg[80]; - sprintf (Msg,"Downlink Mode used : "); - - switch (downlink_mode) { - case 0 : strcat (Msg,"default/fixed bit length"); break; - case 1 : strcat (Msg,"long leading reference (r 1)"); break; - case 2 : strcat (Msg,"leading zero reference (r 2)"); break; - case 3 : strcat (Msg,"1 of 4 coding reference (r 3)"); break; - default : - strcat (Msg,"default/fixed bit length"); break; - } - - PrintAndLogEx (NORMAL,Msg); +void T55xx_Print_DownlinkMode(uint8_t downlink_mode) { + char Msg[80]; + sprintf(Msg, "Downlink Mode used : "); + + switch (downlink_mode) { + case 0 : + strcat(Msg, "default/fixed bit length"); + break; + case 1 : + strcat(Msg, "long leading reference (r 1)"); + break; + case 2 : + strcat(Msg, "leading zero reference (r 2)"); + break; + case 3 : + strcat(Msg, "1 of 4 coding reference (r 3)"); + break; + default : + strcat(Msg, "default/fixed bit length"); + break; + } + + PrintAndLogEx(NORMAL, Msg); } -// +// static int CmdT55xxDetect(const char *Cmd) { bool errors = false; bool useGB = false; - bool usepwd = false; - bool try_all_dl_modes = false; - bool found = false; + bool usepwd = false; + bool try_all_dl_modes = false; + bool found = false; uint32_t password = 0; uint8_t cmdp = 0; - uint8_t downlink_mode = 0; - uint8_t dl_mode = 0; + uint8_t downlink_mode = 0; + uint8_t dl_mode = 0; while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { @@ -599,12 +607,12 @@ static int CmdT55xxDetect(const char *Cmd) { useGB = true; cmdp++; break; - case 'r': - downlink_mode = param_getchar(Cmd, cmdp+1) - '0'; - if (downlink_mode == 4) try_all_dl_modes = true; - if (downlink_mode > 3) downlink_mode = 0; - cmdp +=2; - break; + case 'r': + downlink_mode = param_getchar(Cmd, cmdp + 1) - '0'; + if (downlink_mode == 4) try_all_dl_modes = true; + if (downlink_mode > 3) downlink_mode = 0; + cmdp += 2; + break; default: PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); errors = true; @@ -617,44 +625,44 @@ static int CmdT55xxDetect(const char *Cmd) { if (SanityOfflineCheck(useGB) != PM3_SUCCESS) return PM3_ENODATA; if (!useGB) { - for (dl_mode = downlink_mode; dl_mode < 4; dl_mode++) { - found = AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password,dl_mode); + for (dl_mode = downlink_mode; dl_mode < 4; dl_mode++) { + found = AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, dl_mode); - // found = false if password is supplied but wrong d/l mode - // so keep trying other modes (if requested) - /* if (!found) { - printf ("Aquire not found"); - return PM3_ENODATA; - } - */ - if (tryDetectModulation()) - { - T55xx_Print_DownlinkMode (dl_mode); - dl_mode = 4; - found = true; - } - else found = false; + // found = false if password is supplied but wrong d/l mode + // so keep trying other modes (if requested) + /* + if (!found) { + printf ("Aquire not found"); + return PM3_ENODATA; + } + */ + if (tryDetectModulation()) { + T55xx_Print_DownlinkMode(dl_mode); + dl_mode = 4; + found = true; + } else found = false; - if (!try_all_dl_modes) dl_mode = 4; - } + if (!try_all_dl_modes) dl_mode = 4; + } } - - if (useGB) found = tryDetectModulation(); - - if (!found) - PrintAndLogEx(WARNING, "Could not detect modulation automatically. Try setting it manually with " _YELLOW_("\'lf t55xx config\'")); + + if (useGB) found = tryDetectModulation(); + + if (!found) + PrintAndLogEx(WARNING, "Could not detect modulation automatically. Try setting it manually with " _YELLOW_("\'lf t55xx config\'")); - /* if (!useGB) { + /* + if (!useGB) { if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password,downlink_mode)) return PM3_ENODATA; } if (!tryDetectModulation()) PrintAndLogEx(WARNING, "Could not detect modulation automatically. Try setting it manually with " _YELLOW_("\'lf t55xx config\'")); - else - T55xx_Print_DownlinkMode (downlink_mode); -*/ + else + T55xx_Print_DownlinkMode (downlink_mode); + */ return PM3_SUCCESS; } @@ -1101,14 +1109,14 @@ int printConfiguration(t55xx_conf_block_t b) { } static int CmdT55xxWakeUp(const char *Cmd) { - + uint32_t password = 0; uint8_t cmdp = 0; bool errors = false; uint8_t downlink_mode = 0; - uint8_t flags = 0; + uint8_t flags = 0; - while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { case 'h': return usage_t55xx_wakup(); @@ -1117,11 +1125,11 @@ static int CmdT55xxWakeUp(const char *Cmd) { cmdp += 2; errors = false; break; - case 'r': - downlink_mode = param_getchar(Cmd, cmdp+1) - '0'; - if (downlink_mode > 3) downlink_mode = 0; - cmdp +=2; - break; + case 'r': + downlink_mode = param_getchar(Cmd, cmdp + 1) - '0'; + if (downlink_mode > 3) downlink_mode = 0; + cmdp += 2; + break; default: PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); errors = true; @@ -1131,7 +1139,7 @@ static int CmdT55xxWakeUp(const char *Cmd) { if (errors) return usage_t55xx_wakup(); - flags = (downlink_mode & 3) << 3; + flags = (downlink_mode & 3) << 3; clearCommandBuffer(); SendCommandMIX(CMD_T55XX_WAKEUP, password, flags, 0, NULL, 0); PrintAndLogEx(SUCCESS, "Wake up command sent. Try read now"); @@ -1149,8 +1157,8 @@ static int CmdT55xxWriteBlock(const char *Cmd) { bool testMode = false; bool errors = false; uint8_t cmdp = 0; - uint32_t downlink_mode = 0; - + uint32_t downlink_mode = 0; + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { case 'h': @@ -1182,11 +1190,11 @@ static int CmdT55xxWriteBlock(const char *Cmd) { page1 = true; cmdp++; break; - case 'r': - downlink_mode = param_getchar(Cmd, cmdp+1) - '0'; - if (downlink_mode > 3) downlink_mode = 0; - cmdp +=2; - break; + case 'r': + downlink_mode = param_getchar(Cmd, cmdp + 1) - '0'; + if (downlink_mode > 3) downlink_mode = 0; + cmdp += 2; + break; default: PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); errors = true; @@ -1200,8 +1208,8 @@ static int CmdT55xxWriteBlock(const char *Cmd) { flags = (usepwd) ? 0x1 : 0; flags |= (page1) ? 0x2 : 0; flags |= (testMode) ? 0x4 : 0; - flags |= (downlink_mode << 3); - + flags |= (downlink_mode << 3); + char pwdStr[16] = {0}; snprintf(pwdStr, sizeof(pwdStr), "pwd: 0x%08X", password); @@ -1234,26 +1242,26 @@ static int CmdT55xxWriteBlock(const char *Cmd) { } static int CmdT55xxReadTrace(const char *Cmd) { - uint8_t cmd_len = 0; - uint8_t downlink_mode = 0; - + uint8_t cmd_len = 0; + uint8_t downlink_mode = 0; + char cmdp = tolower(param_getchar(Cmd, 0)); - if (cmdp == 'r') { - downlink_mode = param_getchar(Cmd, 1) - '0'; - if (downlink_mode > 3) downlink_mode = 0; - cmd_len = 3; - } + if (cmdp == 'r') { + downlink_mode = param_getchar(Cmd, 1) - '0'; + if (downlink_mode > 3) downlink_mode = 0; + cmd_len = 3; + } if ((strlen(Cmd) != cmd_len) || (cmdp == 'h')) return usage_t55xx_trace(); - + if (strlen(Cmd) == cmd_len) { // sanity check. if (SanityOfflineCheck(false) != PM3_SUCCESS) return PM3_ENODATA; bool pwdmode = false; uint32_t password = 0; -// REGULAR_READ_MODE_BLOCK - yeilds correct Page 1 Block 2 data i.e. + 32 bit offset. +// REGULAR_READ_MODE_BLOCK - yeilds correct Page 1 Block 2 data i.e. + 32 bit offset. // if (!AquireData(T55x7_PAGE1, T55x7_TRACE_BLOCK1, pwdmode, password,downlink_mode)) - if (!AquireData(T55x7_PAGE1, REGULAR_READ_MODE_BLOCK, pwdmode, password,downlink_mode)) + if (!AquireData(T55x7_PAGE1, REGULAR_READ_MODE_BLOCK, pwdmode, password, downlink_mode)) return PM3_ENODATA; } @@ -1497,9 +1505,9 @@ static int CmdT55xxInfo(const char *Cmd) { */ bool frombuff = false, gotdata = false, dataasq5 = false; uint8_t cmdp = 0; - uint8_t downlink_mode = 0; + uint8_t downlink_mode = 0; uint32_t block0 = 0; - + while (param_getchar(Cmd, cmdp) != 0x00) { switch (tolower(param_getchar(Cmd, cmdp))) { case 'h': @@ -1517,11 +1525,11 @@ static int CmdT55xxInfo(const char *Cmd) { dataasq5 = true; cmdp += 2; break; - case 'r': - downlink_mode = param_getchar(Cmd, cmdp+1)- '0'; - if (downlink_mode > 3) downlink_mode = 0; - cmdp += 2; - break; + case 'r': + downlink_mode = param_getchar(Cmd, cmdp + 1) - '0'; + if (downlink_mode > 3) downlink_mode = 0; + cmdp += 2; + break; default: PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); return usage_t55xx_info(); @@ -1540,7 +1548,7 @@ static int CmdT55xxInfo(const char *Cmd) { bool pwdmode = false; uint32_t password = 0; - if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, pwdmode, password,downlink_mode)) + if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, pwdmode, password, downlink_mode)) return PM3_ENODATA; } if (!gotdata) { @@ -1637,19 +1645,19 @@ static int CmdT55xxDump(const char *Cmd) { uint32_t password = 0; uint8_t override = false; - uint8_t cmd_opt_idx = 0; - uint8_t downlink_mode = 0; - uint8_t pwd_offset = 0; + uint8_t cmd_opt_idx = 0; + uint8_t downlink_mode = 0; + uint8_t pwd_offset = 0; char cmdp = tolower(param_getchar(Cmd, 0)); - + if (cmdp == 'h') return usage_t55xx_dump(); - if (cmdp == 'r') { - cmd_opt_idx++; - downlink_mode = param_getchar(Cmd, cmd_opt_idx++) - '0'; - if (downlink_mode > 3) downlink_mode = 0; - pwd_offset = 3; - } + if (cmdp == 'r') { + cmd_opt_idx++; + downlink_mode = param_getchar(Cmd, cmd_opt_idx++) - '0'; + if (downlink_mode > 3) downlink_mode = 0; + pwd_offset = 3; + } bool usepwd = (strlen(Cmd) > pwd_offset); if (usepwd) { password = param_get32ex(Cmd, cmd_opt_idx++, 0, 16); @@ -1659,14 +1667,14 @@ static int CmdT55xxDump(const char *Cmd) { printT5xxHeader(0); for (uint8_t i = 0; i < 8; ++i) { - T55xxReadBlock(i, 0, usepwd, override, password,downlink_mode); - // idea for better user experience and display. - // only show override warning on the first block read - if (override) override |= 2; // flag not to show safty for 2nd and on. - } + T55xxReadBlock(i, 0, usepwd, override, password, downlink_mode); + // idea for better user experience and display. + // only show override warning on the first block read + if (override) override |= 2; // flag not to show safty for 2nd and on. + } printT5xxHeader(1); for (uint8_t i = 0; i < 4; i++) - T55xxReadBlock(i, 1, usepwd, override, password,downlink_mode); + T55xxReadBlock(i, 1, usepwd, override, password, downlink_mode); return PM3_SUCCESS; } @@ -1683,14 +1691,14 @@ bool AquireData(uint8_t page, uint8_t block, bool pwdmode, uint32_t password, ui uint8_t blockno; uint8_t page; bool pwdmode; - uint8_t downlink_mode; + uint8_t downlink_mode; } PACKED; struct p payload; payload.password = password; payload.blockno = block; payload.page = page & 0x1; payload.pwdmode = pwdmode; - payload.downlink_mode = downlink_mode; + payload.downlink_mode = downlink_mode; clearCommandBuffer(); SendCommandNG(CMD_T55XX_READ_BLOCK, (uint8_t *)&payload, sizeof(payload)); @@ -1951,17 +1959,17 @@ static void t55x7_create_config_block(int tagtype) { static int CmdResetRead(const char *Cmd) { - uint8_t downlink_mode = 0; - uint8_t flags = 0; - - - if (strlen (Cmd) == 3) - downlink_mode = param_getchar(Cmd, 1) - '0'; - - if (downlink_mode > 3) downlink_mode = 0; - - printf ("DL : %d\n",downlink_mode); - flags = downlink_mode << 3; + uint8_t downlink_mode = 0; + uint8_t flags = 0; + + + if (strlen(Cmd) == 3) + downlink_mode = param_getchar(Cmd, 1) - '0'; + + if (downlink_mode > 3) downlink_mode = 0; + + printf("DL : %d\n", downlink_mode); + flags = downlink_mode << 3; clearCommandBuffer(); SendCommandNG(CMD_T55XX_RESET_READ, &flags, sizeof(flags)); if (!WaitForResponseTimeout(CMD_ACK, NULL, 2500)) { @@ -2019,44 +2027,44 @@ static bool IsCancelled(void) { // load a default pwd file. static int CmdT55xxChkPwds(const char *Cmd) { - char filename[FILE_PATH_SIZE] = {0}; - bool found = false; - uint8_t timeout = 0; - uint8_t *keyBlock = NULL; - bool from_flash = false; - bool try_all_dl_modes = false; - uint8_t downlink_mode = 0; - int len; - char cmdp; - bool use_pwd_file = false; - int dl_mode; // to try each downlink mode for each password - - - cmdp = tolower(param_getchar(Cmd,0)); - - if (cmdp == 'h') return usage_t55xx_chk(); - if (cmdp == 'm') { - from_flash = true; - Cmd +=2; - cmdp = tolower(param_getchar(Cmd,0)); - } - if (cmdp == 'r') { - Cmd += 2; - downlink_mode = param_getchar(Cmd,0 ) - '0'; // get 2nd option, as this is fixed order. - if (downlink_mode == 4) try_all_dl_modes = true; - if (downlink_mode > 3) downlink_mode = 0; - Cmd += 2; - cmdp = param_getchar(Cmd,0); - } - if (cmdp == 'i') { - Cmd+=2; - len = strlen(Cmd); - if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE; - memcpy(filename, Cmd, len); - use_pwd_file = true; - } - - + char filename[FILE_PATH_SIZE] = {0}; + bool found = false; + uint8_t timeout = 0; + uint8_t *keyBlock = NULL; + bool from_flash = false; + bool try_all_dl_modes = false; + uint8_t downlink_mode = 0; + int len; + char cmdp; + bool use_pwd_file = false; + int dl_mode; // to try each downlink mode for each password + + + cmdp = tolower(param_getchar(Cmd, 0)); + + if (cmdp == 'h') return usage_t55xx_chk(); + if (cmdp == 'm') { + from_flash = true; + Cmd += 2; + cmdp = tolower(param_getchar(Cmd, 0)); + } + if (cmdp == 'r') { + Cmd += 2; + downlink_mode = param_getchar(Cmd, 0) - '0'; // get 2nd option, as this is fixed order. + if (downlink_mode == 4) try_all_dl_modes = true; + if (downlink_mode > 3) downlink_mode = 0; + Cmd += 2; + cmdp = param_getchar(Cmd, 0); + } + if (cmdp == 'i') { + Cmd += 2; + len = strlen(Cmd); + if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE; + memcpy(filename, Cmd, len); + use_pwd_file = true; + } + + /* // block 7, page1 = false, usepwd = false, override = false, pwd = 00000000 @@ -2069,8 +2077,8 @@ static int CmdT55xxChkPwds(const char *Cmd) { */ uint64_t t1 = msclock(); - uint8_t flags = downlink_mode << 3; - + uint8_t flags = downlink_mode << 3; + if (from_flash) { clearCommandBuffer(); SendCommandNG(CMD_T55XX_CHKPWDS, &flags, sizeof(flags)); @@ -2089,11 +2097,11 @@ static int CmdT55xxChkPwds(const char *Cmd) { if (resp.oldarg[0]) { PrintAndLogEx(SUCCESS, "\nFound a candidate [ " _YELLOW_("%08X") " ]. Trying to validate", resp.oldarg[1]); - if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, resp.oldarg[1],downlink_mode)) { + if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, resp.oldarg[1], downlink_mode)) { found = tryDetectModulation(); if (found) { PrintAndLogEx(SUCCESS, "Found valid password: [ " _GREEN_("%08X") " ]", resp.oldarg[1]); - T55xx_Print_DownlinkMode (downlink_mode); + T55xx_Print_DownlinkMode(downlink_mode); } else { PrintAndLogEx(WARNING, "Check pwd failed"); @@ -2143,25 +2151,25 @@ static int CmdT55xxChkPwds(const char *Cmd) { curr_password = bytes_to_num(keyBlock + 4 * c, 4); PrintAndLogEx(INFO, "Testing %08X", curr_password); - for (dl_mode = downlink_mode; dl_mode <= 3; dl_mode++){ - - if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, curr_password,dl_mode)) { - continue; - } + for (dl_mode = downlink_mode; dl_mode <= 3; dl_mode++) { - found = tryDetectModulation(); - if (found) { - PrintAndLogEx(SUCCESS, "Found valid password: [ " _GREEN_("%08X") " ]", curr_password); - T55xx_Print_DownlinkMode (dl_mode); - dl_mode = 4; // Exit other downlink mode checks - c = keycount; // Exit loop - } - - if (!try_all_dl_modes) // Exit loop if not trying all downlink modes - dl_mode = 4; - } - } - if (!found) PrintAndLogEx(WARNING, "Check pwd failed"); + if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, curr_password, dl_mode)) { + continue; + } + + found = tryDetectModulation(); + if (found) { + PrintAndLogEx(SUCCESS, "Found valid password: [ " _GREEN_("%08X") " ]", curr_password); + T55xx_Print_DownlinkMode(dl_mode); + dl_mode = 4; // Exit other downlink mode checks + c = keycount; // Exit loop + } + + if (!try_all_dl_modes) // Exit loop if not trying all downlink modes + dl_mode = 4; + } + } + if (!found) PrintAndLogEx(WARNING, "Check pwd failed"); } free(keyBlock); @@ -2178,19 +2186,19 @@ static int CmdT55xxBruteForce(const char *Cmd) { uint32_t start_password = 0x00000000; //start password uint32_t end_password = 0xFFFFFFFF; //end password uint32_t curr = 0; - uint8_t downlink_mode = 0; - uint8_t cmd_opt_idx = 0; + uint8_t downlink_mode = 0; + uint8_t cmd_opt_idx = 0; uint8_t found = 0; // > 0 if found xx1 xx downlink needed, 1 found char cmdp = tolower(param_getchar(Cmd, cmd_opt_idx)); if (cmdp == 'h') return usage_t55xx_bruteforce(); - if (cmdp == 'r') { // downlink mode supplied - cmd_opt_idx++; // skip over 'r' - downlink_mode = param_getchar (Cmd,cmd_opt_idx++) - '0'; - if (downlink_mode > 4) downlink_mode = 0; - } - + if (cmdp == 'r') { // downlink mode supplied + cmd_opt_idx++; // skip over 'r' + downlink_mode = param_getchar(Cmd, cmd_opt_idx++) - '0'; + if (downlink_mode > 4) downlink_mode = 0; + } + uint64_t t1 = msclock(); @@ -2214,7 +2222,7 @@ static int CmdT55xxBruteForce(const char *Cmd) { return PM3_EOPABORTED; } - found = tryOnePassword(curr,downlink_mode); + found = tryOnePassword(curr, downlink_mode); if (curr == end_password) break; @@ -2225,10 +2233,9 @@ static int CmdT55xxBruteForce(const char *Cmd) { PrintAndLogEx(NORMAL, ""); if (found) { - PrintAndLogEx(SUCCESS, "Found valid password: [ " _GREEN_("%08X") "]", curr-1); - T55xx_Print_DownlinkMode ((found >> 1) & 3); - } - else + PrintAndLogEx(SUCCESS, "Found valid password: [ " _GREEN_("%08X") "]", curr - 1); + T55xx_Print_DownlinkMode((found >> 1) & 3); + } else PrintAndLogEx(WARNING, "Bruteforce failed, last tried: [ " _YELLOW_("%08X") " ]", curr); t1 = msclock() - t1; @@ -2237,31 +2244,30 @@ static int CmdT55xxBruteForce(const char *Cmd) { } uint8_t tryOnePassword(uint32_t password, uint8_t downlink_mode) { - - bool try_all_dl_modes = false; - uint8_t dl_mode = 0; - - PrintAndLogEx(INFO, "Trying password %08X", password); - if (downlink_mode == 4) try_all_dl_modes = true; - - downlink_mode = (downlink_mode & 3); // ensure 0-3 - - // check if dl mode 4 and loop if needed - for (dl_mode = downlink_mode; dl_mode < 4; dl_mode++){ + bool try_all_dl_modes = false; + uint8_t dl_mode = 0; - AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, password,dl_mode); + PrintAndLogEx(INFO, "Trying password %08X", password); - // if (getSignalProperties()->isnoise == false) { - // } else { - if (tryDetectModulation()) - { - return 1 + (dl_mode << 1); - } - // } - if (!try_all_dl_modes) dl_mode = 4; - } - return 0; + if (downlink_mode == 4) try_all_dl_modes = true; + + downlink_mode = (downlink_mode & 3); // ensure 0-3 + + // check if dl mode 4 and loop if needed + for (dl_mode = downlink_mode; dl_mode < 4; dl_mode++) { + + AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, password, dl_mode); + + // if (getSignalProperties()->isnoise == false) { + // } else { + if (tryDetectModulation()) { + return 1 + (dl_mode << 1); + } + // } + if (!try_all_dl_modes) dl_mode = 4; + } + return 0; } static int CmdT55xxRecoverPW(const char *Cmd) { @@ -2270,25 +2276,25 @@ static int CmdT55xxRecoverPW(const char *Cmd) { uint32_t curr_password = 0x0; uint32_t prev_password = 0xffffffff; uint32_t mask = 0x0; - uint8_t downlink_mode = 0; + uint8_t downlink_mode = 0; uint8_t found = 0; - uint8_t cmd_opt_idx = 0; - + uint8_t cmd_opt_idx = 0; + char cmdp = tolower(param_getchar(Cmd, cmd_opt_idx)); if (cmdp == 'h') return usage_t55xx_recoverpw(); - if (cmdp == 'r') { // downlink mode supplied - cmd_opt_idx++; // skip over 'r' - downlink_mode = param_getchar (Cmd,cmd_opt_idx++) - '0'; - if (downlink_mode > 4) downlink_mode = 0; - } + if (cmdp == 'r') { // downlink mode supplied + cmd_opt_idx++; // skip over 'r' + downlink_mode = param_getchar(Cmd, cmd_opt_idx++) - '0'; + if (downlink_mode > 4) downlink_mode = 0; + } orig_password = param_get32ex(Cmd, cmd_opt_idx++, 0x51243648, 16); //password used by handheld cloners // first try fliping each bit in the expected password while (bit < 32) { curr_password = orig_password ^ (1u << bit); - found = tryOnePassword(curr_password,downlink_mode); + found = tryOnePassword(curr_password, downlink_mode); if (found > 0) // xx1 for found xx = dl mode used goto out; @@ -2313,7 +2319,7 @@ static int CmdT55xxRecoverPW(const char *Cmd) { continue; } - found = tryOnePassword(curr_password,downlink_mode); + found = tryOnePassword(curr_password, downlink_mode); if (found > 0) goto out; @@ -2335,7 +2341,7 @@ static int CmdT55xxRecoverPW(const char *Cmd) { bit++; continue; } - found = tryOnePassword(curr_password,downlink_mode); + found = tryOnePassword(curr_password, downlink_mode); if (found > 0) goto out; @@ -2352,9 +2358,8 @@ out: if (found > 0) { PrintAndLogEx(SUCCESS, "Found valid password: [ " _GREEN_("%08X") "]", curr_password); - T55xx_Print_DownlinkMode ((found >> 1) & 3); - } - else + T55xx_Print_DownlinkMode((found >> 1) & 3); + } else PrintAndLogEx(WARNING, "Recover pwd failed"); return PM3_SUCCESS; @@ -2371,7 +2376,7 @@ bool tryDetectP1(bool getData) { bool st = true; if (getData) { - if (!AquireData(T55x7_PAGE1, T55x7_TRACE_BLOCK1, false, 0,0)) + if (!AquireData(T55x7_PAGE1, T55x7_TRACE_BLOCK1, false, 0, 0)) return false; } @@ -2477,12 +2482,12 @@ static int CmdT55xxDetectPage1(const char *Cmd) { bool errors = false; bool useGB = false; bool usepwd = false; - bool try_all_dl_modes = false; - uint8_t found = 0; + bool try_all_dl_modes = false; + uint8_t found = 0; uint32_t password = 0; uint8_t cmdp = 0; - uint8_t downlink_mode = 0; - uint8_t dl_mode = 0; + uint8_t downlink_mode = 0; + uint8_t dl_mode = 0; while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { @@ -2498,12 +2503,12 @@ static int CmdT55xxDetectPage1(const char *Cmd) { useGB = true; cmdp++; break; - case 'r': - downlink_mode = param_getchar(Cmd, cmdp+1) - '0'; - if (downlink_mode == 4) try_all_dl_modes = true; - if (downlink_mode > 3) downlink_mode = 0; - cmdp +=2; - break; + case 'r': + downlink_mode = param_getchar(Cmd, cmdp + 1) - '0'; + if (downlink_mode == 4) try_all_dl_modes = true; + if (downlink_mode > 3) downlink_mode = 0; + cmdp += 2; + break; default: PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); errors = true; @@ -2513,29 +2518,26 @@ static int CmdT55xxDetectPage1(const char *Cmd) { if (errors) return usage_t55xx_detectP1(); if (!useGB) { - for (dl_mode = downlink_mode; dl_mode < 4; dl_mode++) { - found = AquireData(T55x7_PAGE1, T55x7_TRACE_BLOCK1, usepwd, password,dl_mode); + for (dl_mode = downlink_mode; dl_mode < 4; dl_mode++) { + found = AquireData(T55x7_PAGE1, T55x7_TRACE_BLOCK1, usepwd, password, dl_mode); //return PM3_ENODATA; - if (tryDetectP1(false)) //tryDetectModulation()) - { - found = dl_mode; - dl_mode = 4; - } - else found = false; + if (tryDetectP1(false)) { //tryDetectModulation()) + found = dl_mode; + dl_mode = 4; + } else found = false; - if (!try_all_dl_modes) dl_mode = 4; - } - - } + if (!try_all_dl_modes) dl_mode = 4; + } + + } if (useGB) found = tryDetectP1(false); - if (found) { - PrintAndLogEx(SUCCESS, "T55xx chip found!"); - T55xx_Print_DownlinkMode (found); - } - else - PrintAndLogEx(WARNING, "Could not detect modulation automatically. Try setting it manually with " _YELLOW_("\'lf t55xx config\'")); + if (found) { + PrintAndLogEx(SUCCESS, "T55xx chip found!"); + T55xx_Print_DownlinkMode(found); + } else + PrintAndLogEx(WARNING, "Could not detect modulation automatically. Try setting it manually with " _YELLOW_("\'lf t55xx config\'")); return PM3_SUCCESS; @@ -2546,9 +2548,9 @@ static int CmdT55xxSetDeviceConfig(const char *Cmd) { uint8_t write0 = 0, write1 = 0, write2 = 0, write3 = 0; bool errors = false, shall_persist = false; uint8_t cmdp = 0; - uint8_t downlink_mode = 0; - bool erase = false; - + uint8_t downlink_mode = 0; + bool erase = false; + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { case 'h': @@ -2583,7 +2585,7 @@ static int CmdT55xxSetDeviceConfig(const char *Cmd) { break; case 'r': downlink_mode = param_getchar(Cmd, cmdp + 1) - '0'; - if (downlink_mode > 3) downlink_mode = 0; + if (downlink_mode > 3) downlink_mode = 0; cmdp += 2; break; case 'p': @@ -2604,23 +2606,22 @@ static int CmdT55xxSetDeviceConfig(const char *Cmd) { //Validations if (errors || cmdp == 0) return usage_lf_deviceconfig(); -// printf ("DLmode %d\n",downlink_mode); +// printf ("DLmode %d\n",downlink_mode); t55xx_config conf = {0}; - printf ("Size conf %zu\n",sizeof(conf)); - if (erase) { - memset (&conf,0xff, sizeof(conf)); - printf ("Conf.m[0] %x\n",conf.m[0].start_gap); - } - else { - - conf.m[downlink_mode].start_gap = startgap * 8; - conf.m[downlink_mode].write_gap = writegap * 8; - conf.m[downlink_mode].write_0 = write0 * 8; - conf.m[downlink_mode].write_1 = write1 * 8; - conf.m[downlink_mode].write_2 = write2 * 8; - conf.m[downlink_mode].write_3 = write3 * 8; - conf.m[downlink_mode].read_gap = readgap * 8; - } + printf("Size conf %zu\n", sizeof(conf)); + if (erase) { + memset(&conf, 0xff, sizeof(conf)); + printf("Conf.m[0] %x\n", conf.m[0].start_gap); + } else { + + conf.m[downlink_mode].start_gap = startgap * 8; + conf.m[downlink_mode].write_gap = writegap * 8; + conf.m[downlink_mode].write_0 = write0 * 8; + conf.m[downlink_mode].write_1 = write1 * 8; + conf.m[downlink_mode].write_2 = write2 * 8; + conf.m[downlink_mode].write_3 = write3 * 8; + conf.m[downlink_mode].read_gap = readgap * 8; + } clearCommandBuffer(); SendCommandOLD(CMD_SET_LF_T55XX_CONFIG, shall_persist, 0, 0, &conf, sizeof(t55xx_config)); return PM3_SUCCESS; diff --git a/client/scripting.c b/client/scripting.c index 703feffa4..4a2ff28d6 100644 --- a/client/scripting.c +++ b/client/scripting.c @@ -903,7 +903,7 @@ static int l_T55xx_readblock(lua_State *L) { // try reading the config block and verify that PWD bit is set before doing this! if (!override) { - if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, false, 0,0)) { + if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, false, 0, 0)) { return returnToLuaWithError(L, "Failed to read config block"); } @@ -920,7 +920,7 @@ static int l_T55xx_readblock(lua_State *L) { } } - if (!AquireData(usepage1, block, usepwd, password,0)) { + if (!AquireData(usepage1, block, usepwd, password, 0)) { return returnToLuaWithError(L, "Failed to aquire data from card"); } @@ -977,7 +977,7 @@ static int l_T55xx_detect(lua_State *L) { if (!useGB) { - isok = AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password,0); + isok = AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, 0); if (isok == false) { return returnToLuaWithError(L, "Failed to aquire LF signal data"); } diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index ded330e1e..63054d3a1 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -129,20 +129,20 @@ typedef struct { } t55xx_config; */ -// Extended to support 1 of 4 timing +// Extended to support 1 of 4 timing typedef struct { - uint16_t start_gap ; - uint16_t write_gap ; - uint16_t write_0 ; - uint16_t write_1 ; - uint16_t write_2 ; - uint16_t write_3 ; - uint16_t read_gap ; + uint16_t start_gap ; + uint16_t write_gap ; + uint16_t write_0 ; + uint16_t write_1 ; + uint16_t write_2 ; + uint16_t write_3 ; + uint16_t read_gap ; } t55xx_config_t; // This setup will allow for the 4 downlink modes "m" as well as other items if needed. // Given the one struct we can then read/write to flash/client in one go. typedef struct { - t55xx_config_t m[4]; // mode + t55xx_config_t m[4]; // mode } t55xx_config; /*typedef struct { From ab043a68b826adff61129fa4b26ea3df5fe88830 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 23 Jul 2019 23:44:41 +0200 Subject: [PATCH 0145/1854] remove space in filename --- .../loclass/{loclass information.txt => loclass_information.txt} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename client/loclass/{loclass information.txt => loclass_information.txt} (100%) diff --git a/client/loclass/loclass information.txt b/client/loclass/loclass_information.txt similarity index 100% rename from client/loclass/loclass information.txt rename to client/loclass/loclass_information.txt From 468f59684c46f6d7a6d5f7b4680dda56061a30a6 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 24 Jul 2019 00:11:03 +0200 Subject: [PATCH 0146/1854] unify changelog --- CHANGELOG.md | 702 +++++++++++++++++++++++++-------------------------- 1 file changed, 351 insertions(+), 351 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 76b3db976..4b83c91e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,7 +17,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Fix: timeout for mem wipe was too short, thanks @cjbrigato (@doegox) - Fix 'hf mf sim' - Mifare Classic simulation more flexible anti-collision check (@McEloff) - Change: 'hf mf sim' - Mifare Classic simulation not respond NACK on invalid authentication request (@McEloff) - - Change: 'read_pwd_mem.lua' now handles Mifare Classic dictionaries large than 4096 bytes (@iceman) + - Change: 'read_pwd_mem.lua' now handles Mifare Classic dictionaries large than 4096 bytes (@iceman1001) - Change: Don't clear trace log during 'hf mf chk', to save whole process history (@McEloff) - Add 'msleep' command, for pauses in scripts (@doegox) - Add support for WSL in proxmark.sh (@doegox) @@ -38,55 +38,55 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Add compiler info in client & ARM sections (@slurdge) - Add support for automatic COM detection on Windows (@slurdge) - Add support for compilation on RaspberryPiZero (armv6) (@doegox) - - Change: updates to README (@iceman) + - Change: updates to README (@iceman1001) - Change: 'hf mf/mfu dbg' => 'hw dbg' (@doegox) - Change: replace usb_poll_validate_length() by data_available() that supports USART too (@doegox) - Make sure standalone modes can be launched when connected on USB without client (@doegox) - Change: cleaner makefile execution, use 'make V=1' if you want to see full lines (@doegox) - Change: automate make clean when platform definitions are changed (@doegox) - Add STANDALONE option to Makefile.hal (@Fl0-0) - - Change: mem info - production public key to verify rdv4.0 flash signature (@iceman) + - Change: mem info - production public key to verify rdv4.0 flash signature (@iceman1001) - Fix specify that we need TCP and not UDP connection (@phcoder) - - Change: lf cotag demod - adjusted error trigger (@iceman) - - Add documentation on BT add-on (@iceman/@doegox) + - Change: lf cotag demod - adjusted error trigger (@iceman1001) + - Add documentation on BT add-on (@iceman1001/@doegox) - Change: new button behaviour in bootloader mode, no need to keep it pressed, press again to interrupt (@doegox) - - Change: new keys in dicts, new mem layout to accomodate them (@iceman/various) - - Fix lf sim - if called with empty graphbuffer all strange things happend, like turning on HF field (@iceman) + - Change: new keys in dicts, new mem layout to accomodate them (@iceman1001/various) + - Fix lf sim - if called with empty graphbuffer all strange things happend, like turning on HF field (@iceman1001) - Change: hf 14a sim / hf mf sim - check buttonpress/usb frame fewer times in order not to disrupt simulation (@McEloff) - - Change: data convertbitstream - converts bit to max/min in order to facilitate demodulation of simulation data (@iceman) - - Change: lf em 410x_demod - now can demod the simulation data (@iceman) + - Change: data convertbitstream - converts bit to max/min in order to facilitate demodulation of simulation data (@iceman1001) + - Change: lf em 410x_demod - now can demod the simulation data (@iceman1001) - Add HC-06 scripts for BT add-on (@doegox) - - Fix lf nedap sim - error when adding parity (@iceman) - - Add documentation on UART and baudrates (@doegox/@iceman) - - Change: prompt now shows which channel is used (@iceman) - - Change: USART baudrates computation, up to 6Mbps (@iceman/@doegox) + - Fix lf nedap sim - error when adding parity (@iceman1001) + - Add documentation on UART and baudrates (@doegox/@iceman1001) + - Change: prompt now shows which channel is used (@iceman1001) + - Change: USART baudrates computation, up to 6Mbps (@iceman1001/@doegox) - Change: hf mf nack - keep sync if started without card over antenna - Add usart btfactory - to reset a misconfigured BT add-on (@doegox) - - Change: hw status - now prints number of dictionary keys loaded (@iceman) + - Change: hw status - now prints number of dictionary keys loaded (@iceman1001) - Add home, end, pageup, and pagedown keybinds to the plot GUI. Also fix paged movement in GUI. (@mcd1992) - - Change legic.lua saves data in EML and BIN formats (@iceman) + - Change legic.lua saves data in EML and BIN formats (@iceman1001) - Change hf tune - is now synchronous (for BT add-on) and can be interrupted by kbd (@doegox) - Change: update macOS install instruction (@ Uli Heilmeier) - Add trace ouput in hexdump format for Wireshark import (@ Uli Heilmeier) - Add usart btpin - to change BT add-on PIN (@doegox) - - Add reconnection support (@iceman/@doegox) + - Add reconnection support (@iceman1001/@doegox) - Add usart tx/rx/... - USART developer commands (@doegox) - Add PLATFORM_EXTRAS, WITH_FPC_USART_HOST, BTADDON Makefile configuration (@doegox) - - Fix slow reconfigure on mingw of serial port (@iceman) - - Fix cross thread communictions of timeout variable (@iceman) + - Fix slow reconfigure on mingw of serial port (@iceman1001) + - Fix cross thread communictions of timeout variable (@iceman1001) - Change: client is now "universal", adapting to Proxmark3 capabilities (@doegox) - - Add disconnect support to Lua (@iceman) + - Add disconnect support to Lua (@iceman1001) - Change: handles FPC/FLASH FW more gracefully on non-RDV4 pm3 (@doegox) - Add JTAG support for Shikra (@NinjaStyle82) - Change: smart color handling: only if linux and on real term (@doegox) - - Change: reconfigure uart timeouts when compiled for FPC and connecting over USB (@iceman) - - Change: fast push for many commands (@iceman/@doegox) - - Add: fast push for Lua (@iceman) - - Add NDEF parser in Lua (@iceman) - - Change: improve NDEF parser (@iceman) - - Change: all commands got migrated to MIX/NG packet format (@iceman/@doegox) + - Change: reconfigure uart timeouts when compiled for FPC and connecting over USB (@iceman1001) + - Change: fast push for many commands (@iceman1001/@doegox) + - Add: fast push for Lua (@iceman1001) + - Add NDEF parser in Lua (@iceman1001) + - Change: improve NDEF parser (@iceman1001) + - Change: all commands got migrated to MIX/NG packet format (@iceman1001/@doegox) - Fix: Mifare Ultralight read block missing bytes (@doegox) - - Add support new frame format in all Lua scripts (@iceman) + - Add support new frame format in all Lua scripts (@iceman1001) - Add CMD_CAPABILITIES for pm3 to inform dynamically the client (@doegox) - Change baudrate handling, make it clear it's only indicative for USB-CDC & BT (@doegox) - Change: new progressive light scheme for 'hw detectreader' (@doegox) @@ -102,10 +102,10 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Add color support to Dbprintf & alike and rework Dbprintf flags (@doegox) - Change: archive (and fix) hid-flasher (@doegox) - Add standalone placeholder to simplify new standalone integration (@doegox) - - Change: refactor standalone mode info string (@iceman) - - Add iceman skeleton standalone mode for ppl to use as base for their new modes (@iceman) + - Change: refactor standalone mode info string (@iceman1001) + - Add iceman skeleton standalone mode for ppl to use as base for their new modes (@iceman1001) - Change: move compilation options to Makefile.hal (@doegox) - - Fix compilation under OSX (@iceman) + - Fix compilation under OSX (@iceman1001) - Add openocd config files for JLink (@doegox) - Fix compilation dependencies for recovery (@doegox) - Fix segfault when loading a file (@doegox) @@ -114,20 +114,20 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Fix/Add 'hf mf sim' bugs fix, RATS support, etc (@mceloff) - Fix serial of FPC. (@ryan) - Fix 'data shiftgraphzero' corrupting end of GraphBuffer (@doegox) - - Fix 'hf legic info' - unsegmented card now uses card size to calc remaining length (@iceman) - - Add 36bit HID format, extend calcWiegand() to include oem bits ((@davidbeauchamp) - - Fix 'hf mf hardnested' - not verify key when reading nonce file (@iceman) - - Change optimizations for ask/bi (@iceman) + - Fix 'hf legic info' - unsegmented card now uses card size to calc remaining length (@iceman1001) + - Add 36bit HID format, extend calcWiegand() to include oem bits (@davidbeauchamp) + - Fix 'hf mf hardnested' - not verify key when reading nonce file (@iceman1001) + - Change optimizations for ask/bi (@iceman1001) - Fix 'hf mf sim' - bugs fix, refactoring (@mceloff) - Add WRITE and COMPATIBLE_WRITE support to Mifare Ultralight/NTAG simulation (@mceloff) - Change installation instructions and add video links (@5w0rdfish) - Change 'hf mf sim' to support more types (@vratiskol) - - Change better strong wave detection for biphase (@iceman) - - Add 'script run test_t55x7' (@iceman) - - Add new lua scripting support for some t55xx commands (@iceman) + - Change better strong wave detection for biphase (@iceman1001) + - Add 'script run test_t55x7' (@iceman1001) + - Add new lua scripting support for some t55xx commands (@iceman1001) - Add FPC USART for BT add-on with pm3 client. (@doegox) - Add '-b baudrate' option to the pm3 client. (@doegox) - - Change 'lf t55xx info': tell if known configuration block0. (@iceman) + - Change 'lf t55xx info': tell if known configuration block0. (@iceman1001) - Fix/Add FPC usart: fix TX, bring RX, full speed. (@doegox) - Change 'lf t55xx config' options: allow to toggle on/off i/q5/st - Change 'lf t55xx info': support offline block0, Q5, fix extended, add warns. (@doegox) @@ -139,25 +139,25 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Add - dictionary key file for MFU. (not in use at the moment) (@mazodude) - Change 'lf fdx demod - better biphase maxerrors. (@MalteHillmann) - Change 'hf mf sim' - now works better against android (@mceloff) - - Fix 'lf t55xx brute' - now works after aquiredata adaptations (@iceman) - - Fix 'lf t55xx chk' - now works after aquiredata adaptations (@iceman) - - Fix 'lf t55xx recoverpwd' - now works after aquiredata adaptations (@iceman) - - Fix 'data detect p' - reverted bad clock detection (@iceman) - - Change 'data detect a' - better clock detection (@iceman) - - Add 'hf 14a info' - now detects some magic card Gen2 (@iceman) - - Removed 'LCD' code in armsrc compilation (@iceman) - - Change - Generic fixes of codestyle (@doegox) (@iceman) - - Change 'lf indala demod' - refactoring (@iceman) + - Fix 'lf t55xx brute' - now works after aquiredata adaptations (@iceman1001) + - Fix 'lf t55xx chk' - now works after aquiredata adaptations (@iceman1001) + - Fix 'lf t55xx recoverpwd' - now works after aquiredata adaptations (@iceman1001) + - Fix 'data detect p' - reverted bad clock detection (@iceman1001) + - Change 'data detect a' - better clock detection (@iceman1001) + - Add 'hf 14a info' - now detects some magic card Gen2 (@iceman1001) + - Removed 'LCD' code in armsrc compilation (@iceman1001) + - Change - Generic fixes of codestyle (@doegox) (@iceman1001) + - Change 'lf indala demod' - refactoring (@iceman1001) - Change - handling fault bit markers (7) and partial nibbles in hex printing (@doegox) - Change - printing of fault bit markers (7) using a dot (@doegox) - Change 'sc upgrade' - firmware file integrity check (@piwi) - Fix 'data rawdemod am' - last bit was missing (@doegox) - - Fix 'hf 15 dump f' - also selects tag first (@iceman) - - Fix 'hf iclass clone' - missing fileclose (@iceman) - - Add 'trace list hitag' - old hitag annotations now use the new trace (@iceman) - - Change 'lf hitag sim' - loads bin/eml/json (@iceman) - - Change 'lf hitag reader 21' - saves in bin/eml/json (@iceman) - - Change 'lf hitag' - refactoring (@iceman) + - Fix 'hf 15 dump f' - also selects tag first (@iceman1001) + - Fix 'hf iclass clone' - missing fileclose (@iceman1001) + - Add 'trace list hitag' - old hitag annotations now use the new trace (@iceman1001) + - Change 'lf hitag sim' - loads bin/eml/json (@iceman1001) + - Change 'lf hitag reader 21' - saves in bin/eml/json (@iceman1001) + - Change 'lf hitag' - refactoring (@iceman1001) - Change 'lf hitag' - refactoring (@piwi) - Fix 'lf hitag' - generic fix for missing clock init (@piwi) - Fix fsk sim operations on deviceside - avoid division by zero (@doegox) @@ -165,7 +165,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Fix 'lf t55xx recoverpw' - shift as u32 (@doegox) - Fix 'lf ti demod' - shift as u32 (@doegox) - Fix 'lf ti read' - shift as u32 (@doegox) - - Fix 'lf t55xx chk' - condition always false (@doegox) + - Fix 'lf t55xx chk' - condition always false (@doegox) - Change 'lf sim' - ledcontrol refactoring (@doegox) - Fix 'hf mf nack' - signedness bug (@doegox) - Fix 'hf epa cnonce' - check return value (@doegox) @@ -173,22 +173,22 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Fix 'mem write' - added extra check (@doegox) - Fix 'iso15693' - bad string cpy (@doegox) - Fix 'make style' - EOF LF support (@doegox) - - Add 'hf 14b raw' - added -t for timeout (@iceman) - - Rename 'lf hitag snoop' - renamed to 'lf hitag sniff' (@iceman) - - Rename 'lf snoop' - renamed to 'lf sniff' (@iceman) - - Rename 'hf snoop' - renamed to 'hf sniff' (@iceman) + - Add 'hf 14b raw' - added -t for timeout (@iceman1001) + - Rename 'lf hitag snoop' - renamed to 'lf hitag sniff' (@iceman1001) + - Rename 'lf snoop' - renamed to 'lf sniff' (@iceman1001) + - Rename 'hf snoop' - renamed to 'hf sniff' (@iceman1001) - Fix 'hf mfp wrbl' - more blocks available (@merlokk) - Add 'make platform' - compile for non-rdv4 devices made simpler (@doegox) - Change Makefiles optimizations when recompiling (@doegox) - - Fix 'data load' - loads TITEST.txt again (@iceman) - - Change 'lf search' - now detects TI (@iceman) + - Fix 'data load' - loads TITEST.txt again (@iceman1001) + - Change 'lf search' - now detects TI (@iceman1001) - Change fixing signal cleaning for LF (@doegox) - - Fix 'lf paradox demod' - wrong check (@iceman) - - Change 'lf t55xx' - aquiredata uses getsamples (@iceman) - - Fix 'lf search' - chipset detection restore demod buffer again (@iceman) + - Fix 'lf paradox demod' - wrong check (@iceman1001) + - Change 'lf t55xx' - aquiredata uses getsamples (@iceman1001) + - Fix 'lf search' - chipset detection restore demod buffer again (@iceman1001) - Add 'make style' (@doegox) - Fix mixed tabs vs spaces. Now only use 4 space as tab. (@doegox) - - Fix 'lf visa2000 read' - too few samples (@iceman) + - Fix 'lf visa2000 read' - too few samples (@iceman1001) - Fix 'lf t55xx bruteforce' - infinity loop (@doegox) - Fix 'analyse nuid' - correct crc (@doegox) - Add command history not repeating logged commands (@doegox) @@ -197,102 +197,102 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Fix '14b select card' - (@doegox) - Add 'hf mf ndef' - parsing of NDEF messages (@merlokk) - Add 'hf mf mad' - parsing of Mifare Application Directory (@merlokk) - - Rename 'lf snoop' -> 'lf sniff' (@iceman) - - Rename 'hf snoop' -> 'hf sniff' (@iceman) - - Change generally added more colors (@iceman) + - Rename 'lf snoop' -> 'lf sniff' (@iceman1001) + - Rename 'hf snoop' -> 'hf sniff' (@iceman1001) + - Change generally added more colors (@iceman1001) - Change 'sc upgrade' updated firmware v3.11 (RDV40) (@sentiprox) - - Change 'data autocorrelate' - better visual representation and added extra peak detection (@iceman) - - Fix 'lf search' - false positive indala identification fixed (@iceman) - - Add 'lf keri' - basic support for Keri tags (@iceman) - - Add 'hf mf list' - re-added it again (@iceman) - - Fix - A lot of bugfixes, like memory leaks (@iceman) + - Change 'data autocorrelate' - better visual representation and added extra peak detection (@iceman1001) + - Fix 'lf search' - false positive indala identification fixed (@iceman1001) + - Add 'lf keri' - basic support for Keri tags (@iceman1001) + - Add 'hf mf list' - re-added it again (@iceman1001) + - Fix - A lot of bugfixes, like memory leaks (@iceman1001) - Change 'hf 14a antifuzz' - original implementation (@asfabw), reworked a bit - - Fix 'hf mf fchk' (@iceman) + - Fix 'hf mf fchk' (@iceman1001) - Fix 'usb slow on posix based systems' (@fl0-0) - Change 'lf pcf7931' - improved read code (@sguerrini97) - - Change 'hf felica list' - started with some FeliCa annotations (@iceman) - - Fix 'hf tune' - now works as expected (@iceman) - - Add 'option to use flash memory to upload dictionary files' (RDV40) (@iceman) + - Change 'hf felica list' - started with some FeliCa annotations (@iceman1001) + - Fix 'hf tune' - now works as expected (@iceman1001) + - Add 'option to use flash memory to upload dictionary files' (RDV40) (@iceman1001) - Fix 'printing percentage now standard compliant' (@fabled) - - Add 'emv roca' - command to test for ROCA vuln in public RSA modulus (@merlokk / @iceman) + - Add 'emv roca' - command to test for ROCA vuln in public RSA modulus (@merlokk / @iceman1001) - Added TCP ports support (on linux) (@phcoder) - Added HF sniff standalone mode with optional storing of ULC/NTAG/ULEV1 authentication attempts (@bogiton) - Fix 'Lining up plot and control window' (@anticat) - Fix 'annoying focus behaviour' on OSX (@Anticat) - Implemented AppNap API, fixing #283 and #627 OSX USB comm issues (@AntiCat) - - Added 'sc brute' - a naive SFI bruteforcer for contact smartcards (RDV40) (@iceman) - - Change 'lf t55xx detectconfig' - now optional to persist settings to flashmem (RDV40) (@iceman) - - Change 'hf mf csave' - now saves both EML/BIN formats (@iceman) - - Change 'hf mf esave' - now saves both EML/BIN formats (@iceman) + - Added 'sc brute' - a naive SFI bruteforcer for contact smartcards (RDV40) (@iceman1001) + - Change 'lf t55xx detectconfig' - now optional to persist settings to flashmem (RDV40) (@iceman1001) + - Change 'hf mf csave' - now saves both EML/BIN formats (@iceman1001) + - Change 'hf mf esave' - now saves both EML/BIN formats (@iceman1001) - Fix 'compiler warning on macos and gcc7.1 or higher' (@TomHarkness) - Fix 'crash on Bionic libc if CloseProxmark is called twice' (@micolous) - Change 'lf hid' - got an updated to Kastle format (@xilni) - - Added 'lf t55xx deviceconfig' - enables custom t55xx timing settings. (RDV40) (@iceman) - - Chg adaptations for FPC communications (work in progress) (@iceman) + - Added 'lf t55xx deviceconfig' - enables custom t55xx timing settings. (RDV40) (@iceman1001) + - Chg adaptations for FPC communications (work in progress) (@iceman1001) - Fix 'stand-alone Colin' - remake to benefit from flashmem for persistence. (@cjbrigato) - Fix 'LEGIC SIM' - remake of legic sim (@drandreas) - Changed 'proxmark3 client threading' - remake from official repo (@micolous) - Add 'rem' - new command that adds a line to the log file (@didierStevens) - - Fix 'EM410xdemod empty tag id in lfops.c' (@Defensor7) + - Fix 'EM410xdemod empty tag id in lfops.c' (@Defensor7) - Fix 'usb device descriptor' - some android phones will enumerate better when iSerialnumber isn't a multiple of 8 (@micolous, @megabug) - Fix 'StandaloneMode LF' - when collecting signal, justNoise detection is needed (@didierStevens, @Megabug) - Fix 'StandAloneMode Colin' - mifare1ksim called with right params (@cjbrigato) - - Improved 'install.sh' to install dependencies for Ubuntu 18.04 and using max number of processors during compilation (@joanbono) - - Modified 'install.sh' script to work in macOS and Linux + added the 'update.sh' and 'proxmark3.sh' from joanbono (@TomHarkness) + - Improved 'install.sh' to install dependencies for Ubuntu 18.04 and using max number of processors during compilation (@joanbono) + - Modified 'install.sh' script to work in macOS and Linux + added the 'update.sh' and 'proxmark3.sh' from joanbono (@TomHarkness) - Fix 'hf emv' - some cards need to have Le=0x00, some don't need to have (@merlokk) - Fix 'hf legic' enhancement of rx / tx in legic commands (@drandreas) - - Fix 'data buffclear' - now frees bigbuff also (@iceman) + - Fix 'data buffclear' - now frees bigbuff also (@iceman1001) - Fix GET_TICKS and signess while shifting (@drandreas) - - Added 'hf 14b dump' - now dumps to file (bin & eml) (@iceman) + - Added 'hf 14b dump' - now dumps to file (bin & eml) (@iceman1001) - Fix fixed xcorrelation for strong signal (@drandreas) - Fix 'hf mf chk' - keytype was reversed (@TomHarkness) - - Added strange vid/pid found in wild. Could be pm3 easy clones. (@iceman) + - Added strange vid/pid found in wild. Could be pm3 easy clones. (@iceman1001) - Fix 'make udev' - udev filename could be in conflict, renamed. (@blshkv) - Fix 'lf t55xx config' - wrong sized array disabled FSK1a/FSK2a as options (@grauerfuchs) - - Added more default keys (@j8048188) (@iceman) - - Added 'sc list/info/raw/reader/upgrade' - (RDV40) smart card module functionality (@iceman) + - Added more default keys (@j8048188) (@iceman1001) + - Added 'sc list/info/raw/reader/upgrade' - (RDV40) smart card module functionality (@iceman1001) - Fix 'download eml buffer' (@drandreas) - Changed 'exclusion of floatingpoint lib' (@pwpiwi) - - Changed 'lua scripts bit32 calls' (@iceman) - - Changed 'hw version' (@pwpiwi), adapted to iceman fork ( @iceman) - - Added 'amiibo functionality' (@jamchamb), adapted to iceman fork ( @iceman) - - Fix 'hf legic' (RDV40) adaptations to FPGA HF enhanched reading distance (@iceman) Thanks to @drandreas! + - Changed 'lua scripts bit32 calls' (@iceman1001) + - Changed 'hw version' (@pwpiwi), adapted to iceman fork (@iceman1001) + - Added 'amiibo functionality' (@jamchamb), adapted to iceman fork (@iceman1001) + - Fix 'hf legic' (RDV40) adaptations to FPGA HF enhanched reading distance (@iceman1001) Thanks to @drandreas! - Added 'script run mifare_acces' - script to decode Mifare classic accessbits (@Neuromancer) - - Added 'mem load/save/wipe' - commands to upload / download to new RDV40 onboard flashmemory (@iceman) + - Added 'mem load/save/wipe' - commands to upload / download to new RDV40 onboard flashmemory (@iceman1001) - Added 'script run mifareplus" - script to communicate with a mifare plus tag (@dceliano) - - Added FlashMemory functionality (RDV40) (Thanks @willok) + - Added FlashMemory functionality (RDV40) (@willok) - Fix 'hf mfu dump' - partial reads lead to corrupt data (Thanks @elafargue for pointing it out) - Changed 'hf mfu dump / read' - now retries five times. (@jamchamb) - Added `hf list mf` - deciphers crypto1 stream and works with first authentication and weak nested authentications (@Merlok) - Adjusted `lf cmdread` to respond to client when complete and the client will then automatically call `data samples` (@marshmellow42) - Added a bitbang mode to `lf cmdread` if delay is 0 the cmd bits turn off and on the antenna with 0 and 1 respectively (@marshmellow42) - dump / restore now uses custom filenames (@brianpow) - - Removed 'hf mf sniff' , (@iceman), use HF 14A SNIFF instead - - Added 'hf iclass lookup' (@iceman) - - Added 'hf iclass chk' (@iceman) - - Fixed ADC mux all closed push-pull state (@iceman) + - Removed 'hf mf sniff' , (@iceman1001), use HF 14A SNIFF instead + - Added 'hf iclass lookup' (@iceman1001) + - Added 'hf iclass chk' (@iceman1001) + - Fixed ADC mux all closed push-pull state (@iceman1001) - Fix 'hf mf darkside' - speed fixes (@pwpiwi) - - Fix 'hw tune' - now compensates for 3% error in output, also measure full 140v using ADC channel 5 and 7. (@iceman) + - Fix 'hw tune' - now compensates for 3% error in output, also measure full 140v using ADC channel 5 and 7. (@iceman1001) - Updated loclass gpl license (@holiman) - - Fix Antenna on after changed FPGA Mode. (@iceman) - - Added 'hf mf nack' - Mifare NACK bug detection (@iceman) (@doegox) - - Fix 'hf mf mifare' - zero parity works, no more double runs for normal darkside (@iceman) - - Added 'hf mf fchk' - the fastest check keys implementation tothisday (@iceman) - - Fix 'hf iclass' - more stable demod (@iceman) - - Added 'hf iclass chk' - check keys from default_iclass_keys.dic file (@iceman) - - Fix 'hf 15 dump' - no more crc faults (@iceman) - - Fix 'hf 15 read' - no more crc faults (@iceman) - - Fix 'hf 15 readmulti' - no more crc faults (@iceman) + - Fix Antenna on after changed FPGA Mode. (@iceman1001) + - Added 'hf mf nack' - Mifare NACK bug detection (@iceman1001) (@doegox) + - Fix 'hf mf mifare' - zero parity works, no more double runs for normal darkside (@iceman1001) + - Added 'hf mf fchk' - the fastest check keys implementation tothisday (@iceman1001) + - Fix 'hf iclass' - more stable demod (@iceman1001) + - Added 'hf iclass chk' - check keys from default_iclass_keys.dic file (@iceman1001) + - Fix 'hf 15 dump' - no more crc faults (@iceman1001) + - Fix 'hf 15 read' - no more crc faults (@iceman1001) + - Fix 'hf 15 readmulti' - no more crc faults (@iceman1001) - Changed proxmark command line parameter `flush` to `-f` or `-flush` (@merlokk) - Added to proxmark command line parameters `w` - wait 20s for serial port (@merlokk) - Added to proxmark command line parameters `c` and `l` - execute command and lua script from command line (@merlokk) - - Added to proxmark ability to execute commands from stdin (pipe) ((@merlokk) + - Added to proxmark ability to execute commands from stdin (pipe) (@merlokk) - Added new standalone mode "HF Mifare ultra fast sniff/sim/clone - aka VIGIKPWN" (@cjbrigato) - Added to `hf 14a apdu` - exchange apdu via iso1443-4 (@merlokk) - Added to `hf 14a apdu` - apdu and tlv results parser (@merlokk) - Added 'hf emv' commands (@merlokk) - lots of bug fixes (many many) - - Changed hf mfp security. Now it works in all the modes. (drHatson) + - Changed hf mfp security. Now it works in all the modes. (@drHatson) - Added `hf fido` commands that work with FIDO U2F authenticators (@merlokk) - Added mbedtls instead of old polarssl (@merlokk) - Added jansson (@merlokk) @@ -302,19 +302,19 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Added trailer block decoding to `hf mf rdbl` and `hf mf cgetbl` (@merlokk) - Added `hf mf mad` and `hf mfp mad` MAD decode, check and print commands (@merlokk) - Added T55x7 downlink mode support r 0 Default, 1 Long Leading 0, 2 Leading 0, 3 1 of 4 and 4 (in some commands) try all. - + ### Fixed -- Changed driver file proxmark3.inf to support both old and new Product/Vendor IDs (piwi) -- Changed start sequence in Qt mode (fix: short commands hangs main Qt thread) (Merlok) + - Changed driver file proxmark3.inf to support both old and new Product/Vendor IDs (@pwpiwi) + - Changed start sequence in Qt mode (fix: short commands hangs main Qt thread) (@merlokk) ## [ice.3.1.0][2017-09-26] - - proxmark3 client can reconnect to device without restart (iceman) - - lots of bug fixes (many many) - - trace/securakey-64169.pm3 - trace of a scecurakey (atyppo) - - 'hf mf decrypt' - got some longer input and helptext parameter (iceman) - - Updated the Reveng 1.51 sourcecode to 1.52 from Reveng project homepage (iceman) - - 'hf 14a read' - disconnects when failing to read tag (iceman) - - 'hf mf csave' - renamed parameter 'i' to 'o' as in output (iceman) + - proxmark3 client can reconnect to device without restart (@iceman1001) + - lots of bug fixes (many many) + - trace/securakey-64169.pm3 - trace of a scecurakey (@atyppo) + - 'hf mf decrypt' - got some longer input and helptext parameter (@iceman1001) + - Updated the Reveng 1.51 sourcecode to 1.52 from Reveng project homepage (@iceman1001) + - 'hf 14a read' - disconnects when failing to read tag (@iceman1001) + - 'hf mf csave' - renamed parameter 'i' to 'o' as in output (@iceman1001) ## [3.0.0][2017-08-29] Notes on this release @@ -322,267 +322,267 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac There is a lot of changes, command breaking changes, which is the cause for the JUMP in version number. It is set to v3.0.0 to show that it is on par with PM3 Offical v3 release. - - Updated 'mkversion.pl' to write a date based on file when repo is downloaded as a zip file from github (iceman) - - Update 'readme.md' to fit GitHubs markup(joanbono) - - Added 'script run ul_uid', try to change UID on a magic UL-card. (iceman) - - Fixed 'hf snoop' bug, of wrong bool value (ikarus23) - - Fixed fullimage.s19, wrong offsets (doegox) - - Updated '77-mm-usb-device-blacklist.rules' for the pid/vid (iceman) - - 'hf 14a sim' now follows Mifare UL-EV1 protocol better (iceman) - - Updated 'fpga_hf.bit' file (piwi) - - Added more card detections to 'hf mfu info' (iceman) - - Fixed 'hf mfu restore/dump' to use the right struct values in special data in dumpfile. (iceman) - - Added 'hf mfu restore r' new parameter to use the new pwd for all further auths needed when executing (iceman) - - Added 'default_keys_dic2lua.awk' script to generate default_keys file in client/lualibs (iceman) - - Fixes to lots of lua scripts, among others - - 'mifare_autopwn', now uses PRNG detection (iceman) - - 'mfkeys', fixed bug which only tested the first key (iceman) - - 'dumptoemul', removed last newline (iceman) - - ... - - Added USB/SERIAL communication enhancements (micolous) - - Change 'hf 14a cuids', to be interrupted with keyboard press (iceman) - - Change debugstatements for LF to show which function more unified (iceman) - - Added 'script run calc_di' , to calculate some Mifare keys (iceman) - - Fixed iclass commands never shut down antenna afterwards (iceman) - - Change 512kb detection when flashing (iceman) - - Fixed compilation GCC4.9 or higher detection (winguru) - - Fixed compiler warnings in Ubuntu 17.04 (iceman) - - Ripped out 'standalone' code into separete folder to be continued. (iceman) - - 'hf mf nested', added key validation to entered key (merlokk) - - 'hf mf hardnested', added key validation to enterd key (iceman) - - Change a lot of help texts (iceman) - - Fixed 'hf mf chk' - keyblock bug, limited keys to 256. (iceman) - - Change 'hf mf dump' retries three times now before giving up (marshmellow) - - Fixed 'mfu authentication', with pack-len error (iceman) - - 'Script list', change sortorder to alphabetic order (iceman) - - Change 'hf mfu gen' to read taguid (iceman) - - Change 'hf mfu pwdgen' to read taguid (iceman) - - Added 'hf mf setmod' sets Mifare Classic EV1 load modulation strength to card (angelsl) - - Added 'hf 14a read' Mifare PRNG detection based on @doegox LIBNFC impl (iceman) - - Added 'hf mf nonces', collects Mifare Classic nonces for analysing of PRNG (iceman) - - Added new CSNS in 'hf iclass sim 2' attack (iceman) - - Added more default keys (iceman) - - Added analyse nuid, enable creation of Mifare NUID (iceman) - - Updated the Reveng 1.44 sourcecode to 1.51 from Reveng project homepage (iceman) - - script run formatMifare - got an option to execute the generate strings (iceman) - - Fix 'hf mf cgetsc' (iceman) - - Fix 'hf legic info' (iceman) - - Change version output (iceman) - - Added PAC/Stanley detection to lf search (marshmellow) - - Added lf pac demod and lf pac read - extracts the raw blocks from a PAC/Stanley tag (marshmellow) - - Added hf mf csave commands compatibity for 4k (Fl0-0) - - Added data fsktonrz, a fsk cleaning/demodulating routine for weak fsk signal. Note: follow this up with a `data rawdemod nr` to finish demoding your signal. (marshmellow) - - Added lf em 410xbrute, LF EM410x reader bruteforce attack by simulating UIDs from a file (Fl0-0) - - Compiles on OS X - - Compiles with gcc 4.9 - - Compiles for non-Intel CPUs - - Added lf hitag write 24, the command writes a block to hitag2 tags in crypto mode (henjo) - - Added the improved 'hf mf hardnested', an attack working for hardened Mifare cards (EV1, Mifare Plus SL1) - - Added experimental testmode write option for t55xx (danger) (marshmellow) - - Added t55xx p1detect to `lf search` chip detections (marshmellow) - - Added lf t55xx p1detect, detect page 1 of a t55xx tag based on E015 mfg code (marshmellow) - - Added lf noralsy demod, read, clone, sim commands (iceman) - - Added lf jablotron demod, read, clone, sim commands (iceman) - - Added lf nexwatch read - reads a nexwatch tag from the antenna - - Added lf paradox read - reads a paradox tag from the antenna - - Added lf fdx sim (iceman) - - Added lf fdx clone - clones an fdx-b animal tag to t55x7 or q5 (iceman) - - Added lf fdx read - reads a fdx-b tag from the antenna (iceman) - - Added lf gproxii read - reads a gproxii tag from the antenna (marshmellow) - - Added lf indala read - reads an indala tag from the antenna (marshmellow) - - Added lf visa2000 demod, read, clone, sim commands (iceman) + - Updated 'mkversion.pl' to write a date based on file when repo is downloaded as a zip file from github (@iceman1001) + - Update 'readme.md' to fit GitHubs markup(@joanbono) + - Added 'script run ul_uid', try to change UID on a magic UL-card. (@iceman1001) + - Fixed 'hf snoop' bug, of wrong bool value (@ikarus23) + - Fixed fullimage.s19, wrong offsets (@doegox) + - Updated '77-mm-usb-device-blacklist.rules' for the pid/vid (@iceman1001) + - 'hf 14a sim' now follows Mifare UL-EV1 protocol better (@iceman1001) + - Updated 'fpga_hf.bit' file (@pwpiwi) + - Added more card detections to 'hf mfu info' (@iceman1001) + - Fixed 'hf mfu restore/dump' to use the right struct values in special data in dumpfile. (@iceman1001) + - Added 'hf mfu restore r' new parameter to use the new pwd for all further auths needed when executing (@iceman1001) + - Added 'default_keys_dic2lua.awk' script to generate default_keys file in client/lualibs (@iceman1001) + - Fixes to lots of lua scripts, among others + - 'mifare_autopwn', now uses PRNG detection (@iceman1001) + - 'mfkeys', fixed bug which only tested the first key (@iceman1001) + - 'dumptoemul', removed last newline (@iceman1001) + - ... + - Added USB/SERIAL communication enhancements (@micolous) + - Change 'hf 14a cuids', to be interrupted with keyboard press (@iceman1001) + - Change debugstatements for LF to show which function more unified (@iceman1001) + - Added 'script run calc_di' , to calculate some Mifare keys (@iceman1001) + - Fixed iclass commands never shut down antenna afterwards (@iceman1001) + - Change 512kb detection when flashing (@iceman1001) + - Fixed compilation GCC4.9 or higher detection (@winguru) + - Fixed compiler warnings in Ubuntu 17.04 (@iceman1001) + - Ripped out 'standalone' code into separete folder to be continued. (@iceman1001) + - 'hf mf nested', added key validation to entered key (@merlokk) + - 'hf mf hardnested', added key validation to enterd key (@iceman1001) + - Change a lot of help texts (@iceman1001) + - Fixed 'hf mf chk' - keyblock bug, limited keys to 256. (@iceman1001) + - Change 'hf mf dump' retries three times now before giving up (@marshmellow42) + - Fixed 'mfu authentication', with pack-len error (@iceman1001) + - 'Script list', change sortorder to alphabetic order (@iceman1001) + - Change 'hf mfu gen' to read taguid (@iceman1001) + - Change 'hf mfu pwdgen' to read taguid (@iceman1001) + - Added 'hf mf setmod' sets Mifare Classic EV1 load modulation strength to card (@angelsl) + - Added 'hf 14a read' Mifare PRNG detection based on @doegox LIBNFC impl (@iceman1001) + - Added 'hf mf nonces', collects Mifare Classic nonces for analysing of PRNG (@iceman1001) + - Added new CSNS in 'hf iclass sim 2' attack (@iceman1001) + - Added more default keys (@iceman1001) + - Added analyse nuid, enable creation of Mifare NUID (@iceman1001) + - Updated the Reveng 1.44 sourcecode to 1.51 from Reveng project homepage (@iceman1001) + - script run formatMifare - got an option to execute the generate strings (@iceman1001) + - Fix 'hf mf cgetsc' (@iceman1001) + - Fix 'hf legic info' (@iceman1001) + - Change version output (@iceman1001) + - Added PAC/Stanley detection to lf search (@marshmellow42) + - Added lf pac demod and lf pac read - extracts the raw blocks from a PAC/Stanley tag (@marshmellow42) + - Added hf mf csave commands compatibity for 4k (@Fl0-0) + - Added data fsktonrz, a fsk cleaning/demodulating routine for weak fsk signal. Note: follow this up with a `data rawdemod nr` to finish demoding your signal. (@marshmellow42) + - Added lf em 410xbrute, LF EM410x reader bruteforce attack by simulating UIDs from a file (@Fl0-0) + - Compiles on OS X + - Compiles with gcc 4.9 + - Compiles for non-Intel CPUs + - Added lf hitag write 24, the command writes a block to hitag2 tags in crypto mode (@henjo) + - Added the improved 'hf mf hardnested', an attack working for hardened Mifare cards (EV1, Mifare Plus SL1) + - Added experimental testmode write option for t55xx (danger) (@marshmellow42) + - Added t55xx p1detect to `lf search` chip detections (@marshmellow42) + - Added lf t55xx p1detect, detect page 1 of a t55xx tag based on E015 mfg code (@marshmellow42) + - Added lf noralsy demod, read, clone, sim commands (@iceman1001) + - Added lf jablotron demod, read, clone, sim commands (@iceman1001) + - Added lf nexwatch read - reads a nexwatch tag from the antenna + - Added lf paradox read - reads a paradox tag from the antenna + - Added lf fdx sim (@iceman1001) + - Added lf fdx clone - clones an fdx-b animal tag to t55x7 or q5 (@iceman1001) + - Added lf fdx read - reads a fdx-b tag from the antenna (@iceman1001) + - Added lf gproxii read - reads a gproxii tag from the antenna (@marshmellow42) + - Added lf indala read - reads an indala tag from the antenna (@marshmellow42) + - Added lf visa2000 demod, read, clone, sim commands (@iceman1001) ## [1.7.0 iceman fork] [2017-03-07] - - hf mf dump - added retry loops to try each read attempt up to 3 times. makes getting a complete dump easier with many antennas. (marshmellow) + - hf mf dump - added retry loops to try each read attempt up to 3 times. makes getting a complete dump easier with many antennas. (@marshmellow42) - - Added markers in the graph around found Sequence Terminator after askmandemod. (marshmellow) - - Added data mtrim command to trim out samples between start and stop. (marshmellow) - - Added data setgraphmarkers command to set two extra markers on the graph (marshmellow) - - added json support in lua (vitorio) - - added a buspirate settings file for at91sam7s512 (adamlaurie) - - `lf read` timeouts is now depended on what threshold level you set in `lf config` (marshmellow) - - `hf mf sim` fixed a bug which made sim fail auths. (iceman) - - `hf 14a read` added magic tag generation 1a and 1b detection (iceman) - - correctly using stdtypes.h printf and scanf format string macros (PRIx64 et al) (pwpivi) - - fix linker warning re missing entry point when linking fullimage.elf (pwpivi) - - small changes to lf psk and fsk demods to improve results when the trace begins with noise or the chip isn't broadcasting yet (marshmellow) - - NOTE CHANGED ALL `lf em4x em*` cmds to simpler `lf em ` - example: `lf em4x em410xdemod` is now `lf em 410xdemod` - - Renamed and rebuilt `lf em readword` && readwordpwd to `lf em 4x05read` - it now demods and outputs the read block (marshmellow/iceman) - - Renamed and rebuilt `lf em writeword` && writewordpwd to `lf em 4x05write` - it now also reads validation output from the tag (marshmellow/iceman) - - Fixed bug in lf sim and continuous demods not turning off antenna when finished - - Added lua script path fixes (pwpivi) - - `lf search` - Added EM4x05/EM4x69 chip detection (marshmellow) - - Added lf em 4x05dump command to read and output all the blocks of the chip (marshmellow) - - Added lf em 4x05info command to read and display information about the chip (marshmellow) - - `lf em4x em4x50***` refactoring of em4x50 commands. (iceman) + - Added markers in the graph around found Sequence Terminator after askmandemod. (@marshmellow42) + - Added data mtrim command to trim out samples between start and stop. (@marshmellow42) + - Added data setgraphmarkers command to set two extra markers on the graph (@marshmellow42) + - added json support in lua (@vitorio) + - added a buspirate settings file for at91sam7s512 (@adamlaurie) + - `lf read` timeouts is now depended on what threshold level you set in `lf config` (@marshmellow42) + - `hf mf sim` fixed a bug which made sim fail auths. (@iceman1001) + - `hf 14a read` added magic tag generation 1a and 1b detection (@iceman1001) + - correctly using stdtypes.h printf and scanf format string macros (PRIx64 et al) (@pwpiwi) + - fix linker warning re missing entry point when linking fullimage.elf (@pwpiwi) + - small changes to lf psk and fsk demods to improve results when the trace begins with noise or the chip isn't broadcasting yet (@marshmellow42) + - NOTE CHANGED ALL `lf em4x em*` cmds to simpler `lf em ` - example: `lf em4x em410xdemod` is now `lf em 410xdemod` + - Renamed and rebuilt `lf em readword` && readwordpwd to `lf em 4x05read` - it now demods and outputs the read block (@marshmellow42/@iceman1001) + - Renamed and rebuilt `lf em writeword` && writewordpwd to `lf em 4x05write` - it now also reads validation output from the tag (@marshmellow42/@iceman1001) + - Fixed bug in lf sim and continuous demods not turning off antenna when finished + - Added lua script path fixes (@pwpiwi) + - `lf search` - Added EM4x05/EM4x69 chip detection (@marshmellow42) + - Added lf em 4x05dump command to read and output all the blocks of the chip (@marshmellow42) + - Added lf em 4x05info command to read and display information about the chip (@marshmellow42) + - `lf em4x em4x50***` refactoring of em4x50 commands. (@iceman1001) ## [1.6.9 iceman fork] [2017-02-06] - - Serial speedup, if possible 408600baud otherwise default to 115200baud (iceman) - - `hf emv` - Added Peter Fillmore's EMV branch now compiles on iceman fork. See seperate issue. (iceman) - - `hf 14a reader` - Aztek detection. (iceman) - - `standalone mode` - added more detection of tags and refactored (iceman) - - `script run ufodump` - dumps an Aztek tag. (iceman) - - `script run hard_autopwn` - runs hardnested attack against all sectors on tag (iceman) - - Added lf cotag read, and added it to lf search (iceman) - - Added hitag2 read UID only and added that to lf search (marshmellow) - - `lf search` - check for if signal is only noice (marshmellow) - - `hf 14a reader` - fixed a bug when card has sak 0x00 but still is not UL/NTAG etc. (iceman) - - `hf mf sim` / `hf 14a sim` - use random nonce. (micolous) - - `hw tune` - only prints out if voltage is detected from antenna. (iceman) - - `hf iclass decrypt` - only decrypt Application1 (iceman) - - `lf t55xx detect` - when finding multiple possible config blocks, see if a known configblock exists and select. (iceman) + - Serial speedup, if possible 408600baud otherwise default to 115200baud (@iceman1001) + - `hf emv` - Added Peter Fillmore's EMV branch now compiles on iceman fork. See seperate issue. (@iceman1001) + - `hf 14a reader` - Aztek detection. (@iceman1001) + - `standalone mode` - added more detection of tags and refactored (@iceman1001) + - `script run ufodump` - dumps an Aztek tag. (@iceman1001) + - `script run hard_autopwn` - runs hardnested attack against all sectors on tag (@iceman1001) + - Added lf cotag read, and added it to lf search (@iceman1001) + - Added hitag2 read UID only and added that to lf search (@marshmellow42) + - `lf search` - check for if signal is only noice (@marshmellow42) + - `hf 14a reader` - fixed a bug when card has sak 0x00 but still is not UL/NTAG etc. (@iceman1001) + - `hf mf sim` / `hf 14a sim` - use random nonce. (@micolous) + - `hw tune` - only prints out if voltage is detected from antenna. (@iceman1001) + - `hf iclass decrypt` - only decrypt Application1 (@iceman1001) + - `lf t55xx detect` - when finding multiple possible config blocks, see if a known configblock exists and select. (@iceman1001) ## [1.6.7 iceman fork] [2017-01-05] - - `lf animal` - FDX-B animal commands (iceman) - - Fixed bugs in `lf sim` and other lf continuous demods not turning off antenna when finished (marshmellow) - - `hf iclass write` - fixed bugs, added crc. (?) - - `hf iclass dump` - changed layout in dump (iceman) - - Changed - debug statements are more clear (iceman) - - `lf search` - fixed the silent option when acquire data. (iceman) - - `lf search` - added presco, visa2000, noralsy detection (iceman) - - `lf precso` - fixed some bitsgeneration in precso bits (iceman) - - Added `lf noralsy` - adds demod/clone/sime of Noralsy LF tags. (iceman) - - Added `lf visa2000` - adds demod/clone/sim of Visa2000 lF tags. (iceman) - - Added `hf mf key_brute` - adds J-Runs 2nd phase bruteforce ref: https://github.com/J-Run/mf_key_brute (iceman) - - Added `lf jablotron` - adds demod/clone/sim of Jablotron LF tags. (iceman) - - Added `lf t55xx recoverpw` - adds a new password recovery using bitflips and partial flips if password write went bad. (alexgrin) - - `hf legic` - added improved legic data mapping. (jason) - - `hf mf mifare` - added possibility to target key A|B (douniwan5788) - - Added `analyse lcr` - added a new main command group, to help analysing bytes & bits & nibbles. (iceman) - - Added `lf nedap` - added identification of a NEDAP tag. (iceman) - - `lf viking clone` - fixed a bug. (iceman) - - Added bitsliced bruteforce solver in `hf mf hardnested` (Aczid) - - `hf mf chk` speedup (iceman) - - `hf 14a/mf sim x` attack mode, now uses also moebius version of mfkey32 to try finding the key. (iceman) - - `hf 14a sim` Added emulation of Mifare cards with 10byte UID length. (iceman) - - `hf mf sim` Added emulation of Mifare cards with 10byte UID length. (iceman) - - Added `lf guard clone/sim` (iceman) - - Added `lf pyramd clone/sim` (iceman) - - trying to fix `hf 14b` command to be able to read CALYPSO card. (iceman) - - `hf legic load`, it now loads faster and a casting bug is gone. (iceman) - - Added `hf legic calccrc8` added a method to calculate the legic crc-8 value (iceman) - - `hf legic decode` fixed the output overflow bugs, better printing (iceman) - - Coverity Scan fixes a lot of resource leaks, etc (iceman) - - Added `lf presco *` commands started (iceman) - - Added `lf hid wiegand` added a method to calculate WIEGAND in different formats, (iceman) - - `hf mf chkkeys` better printing, same table output as nested, faster execution and added Adam Lauries "try to read Key B if Key A is found" (iceman) - - `hf mf nested` better printing and added Adam Lauries "try to read Key B if Key A is found" (iceman) - - `hf mf mifare` fixing the zero parity path, which doesn't got called. (iceman) - - Updated the @blapost's Crapto1 implementation to v3.3 (blapost) - - `hf mf c*` updated the calling structure and refactored of the chinese magic commands (iceman, marshmellow) - - Started to add Peter Fillmore's EMV fork into Iceman fork. ref: https://github.com/peterfillmore/proxmark3 (peter fillmore, iceman) - - Added Travis-CI automatic build integration with GitHub fork. (iceman) - - Updated the Reveng 1.30 sourcecode to 1.31 from Reveng project homepage (iceman) - - Updated the Reveng 1.31 sourcecode to 1.40 from Reveng project homepage (iceman) + - `lf animal` - FDX-B animal commands (@iceman1001) + - Fixed bugs in `lf sim` and other lf continuous demods not turning off antenna when finished (@marshmellow42) + - `hf iclass write` - fixed bugs, added crc. (?) + - `hf iclass dump` - changed layout in dump (@iceman1001) + - Changed - debug statements are more clear (@iceman1001) + - `lf search` - fixed the silent option when acquire data. (@iceman1001) + - `lf search` - added presco, visa2000, noralsy detection (@iceman1001) + - `lf precso` - fixed some bitsgeneration in precso bits (@iceman1001) + - Added `lf noralsy` - adds demod/clone/sime of Noralsy LF tags. (@iceman1001) + - Added `lf visa2000` - adds demod/clone/sim of Visa2000 lF tags. (@iceman1001) + - Added `hf mf key_brute` - adds J-Runs 2nd phase bruteforce ref: https://github.com/J-Run/mf_key_brute (@iceman1001) + - Added `lf jablotron` - adds demod/clone/sim of Jablotron LF tags. (@iceman1001) + - Added `lf t55xx recoverpw` - adds a new password recovery using bitflips and partial flips if password write went bad. (@alexgrin) + - `hf legic` - added improved legic data mapping. (jason) + - `hf mf mifare` - added possibility to target key A|B (@douniwan5788) + - Added `analyse lcr` - added a new main command group, to help analysing bytes & bits & nibbles. (@iceman1001) + - Added `lf nedap` - added identification of a NEDAP tag. (@iceman1001) + - `lf viking clone` - fixed a bug. (@iceman1001) + - Added bitsliced bruteforce solver in `hf mf hardnested` (@Aczid) + - `hf mf chk` speedup (@iceman1001) + - `hf 14a/mf sim x` attack mode, now uses also moebius version of mfkey32 to try finding the key. (@iceman1001) + - `hf 14a sim` Added emulation of Mifare cards with 10byte UID length. (@iceman1001) + - `hf mf sim` Added emulation of Mifare cards with 10byte UID length. (@iceman1001) + - Added `lf guard clone/sim` (@iceman1001) + - Added `lf pyramd clone/sim` (@iceman1001) + - trying to fix `hf 14b` command to be able to read CALYPSO card. (@iceman1001) + - `hf legic load`, it now loads faster and a casting bug is gone. (@iceman1001) + - Added `hf legic calccrc8` added a method to calculate the legic crc-8 value (@iceman1001) + - `hf legic decode` fixed the output overflow bugs, better printing (@iceman1001) + - Coverity Scan fixes a lot of resource leaks, etc (@iceman1001) + - Added `lf presco *` commands started (@iceman1001) + - Added `lf hid wiegand` added a method to calculate WIEGAND in different formats, (@iceman1001) + - `hf mf chkkeys` better printing, same table output as nested, faster execution and added Adam Lauries "try to read Key B if Key A is found" (@iceman1001) + - `hf mf nested` better printing and added Adam Lauries "try to read Key B if Key A is found" (@iceman1001) + - `hf mf mifare` fixing the zero parity path, which doesn't got called. (@iceman1001) + - Updated the @blapost's Crapto1 implementation to v3.3 (blapost) + - `hf mf c*` updated the calling structure and refactored of the chinese magic commands (@iceman1001, @marshmellow42) + - Started to add Peter Fillmore's EMV fork into Iceman fork. ref: https://github.com/peterfillmore/proxmark3 (@peterfillmore, @iceman1001) + - Added Travis-CI automatic build integration with GitHub fork. (@iceman1001) + - Updated the Reveng 1.30 sourcecode to 1.31 from Reveng project homepage (@iceman1001) + - Updated the Reveng 1.31 sourcecode to 1.40 from Reveng project homepage (@iceman1001) - - Added possibility to write direct to a Legic Prime Tag (MIM256/1024) without using values from the 'BigBuffer' -> 'hf legic writeRaw ' (icsom) - - Added possibility to decrease DCF values at address 0x05 & 0x06 on a Legic Prime Tag - DCF-value will be pulled from the BigBuffer (address 0x05 & 0x06) so you have to - load the data into the BigBuffer before with 'hf legic load ' & then - write the DCF-Values (both at once) with 'hf legic write 0x05 0x02' (icsom) - - Added script `legic.lua` for display and edit Data of Legic-Prime Tags (icsom) - - Added the experimental HITAG_S support (spenneb) - - Added topaz detection to `hf search` (iceman) - - Fixed the silent mode for 14b to be used inside `hf search` (iceman) + - Added possibility to write direct to a Legic Prime Tag (MIM256/1024) without using values from the 'BigBuffer' -> 'hf legic writeRaw ' (@icsom) + - Added possibility to decrease DCF values at address 0x05 & 0x06 on a Legic Prime Tag + DCF-value will be pulled from the BigBuffer (address 0x05 & 0x06) so you have to + load the data into the BigBuffer before with 'hf legic load ' & then + write the DCF-Values (both at once) with 'hf legic write 0x05 0x02' (@icsom) + - Added script `legic.lua` for display and edit Data of Legic-Prime Tags (@icsom) + - Added the experimental HITAG_S support (@spenneb) + - Added topaz detection to `hf search` (@iceman1001) + - Fixed the silent mode for 14b to be used inside `hf search` (@iceman1001) ### Added -- Added a LF ASK Sequence Terminator detection option to the standard ask demod - and applied it to `lf search u`, `lf t55xx detect`, and `data rawdemod am s` (marshmellow) -- `lf awid bruteforce ` - Simple bruteforce attack against a AWID reader. -- `lf t55xx bruteforce [i <*.dic>]` - Simple bruteforce attack to find password - (iceman and others) -- `lf viking clone`- clone viking tag to t55x7 or Q5 from 4byte hex ID input -- `lf viking sim` - sim full viking tag from 4byte hex ID input -- `lf viking read` - read viking tag and output ID -- `lf t55xx wipe` - sets t55xx back to factory defaults -- Added viking demod to `lf search` (marshmellow) -- `data askvikingdemod` demod viking id tag from graphbuffer (marshmellow) -- `lf t55xx resetread` added reset then read command - should allow determining start of stream transmissions (marshmellow) -- `lf t55xx wakeup` added wake with password (AOR) to allow lf search or standard lf read after (iceman, marshmellow) -- `hf mf eload u` added an ultralight/ntag option. (marshmellow) -- `hf iclass managekeys` to save, load and manage iclass keys. (adjusted most commands to accept a loaded key in memory) (marshmellow) -- `hf iclass readblk` to select, authenticate, and read 1 block from an iclass card (marshmellow) -- `hf iclass writeblk` to select, authenticate, and write 1 block to an iclass card (or picopass) (marshmellow + others) -- `hf iclass clone` to take a saved dump file and clone selected blocks to a new tag (marshmellow + others) -- `hf iclass calcnewkey` - to calculate the div_key change to change a key - (experimental) (marshmellow + others) -- `hf iclass encryptblk` - to encrypt a data block hex to prep for writing that block (marshmellow) -- ISO14443a stand-alone operation with ARM CFLAG="WITH_ISO14443a_StandAlone". This code can read & emulate two banks of 14a tag UIDs and write to "magic" cards (Craig Young) -- AWID26 command context added as 'lf awid' containing realtime demodulation as well as cloning/simulation based on tag numbers (Craig Young) -- Added 'hw status'. This command makes the ARM print out some runtime information. (holiman) -- Added 'hw ping'. This command just sends a usb packets and checks if the pm3 is responsive. Can be used to abort certain operations which supports abort over usb. (holiman) -- Added `data hex2bin` and `data bin2hex` for command line conversion between binary and hexadecimal (holiman) -- Added 'hf snoop'. This command take digitalized signal from FPGA and put in BigBuffer. (pwpiwi + enio) -- Added Topaz (NFC type 1) protocol support ('hf topaz reader', 'hf list topaz', 'hf 14a raw -T', 'hf topaz snoop'). (piwi) -- Added option c to 'hf list' (mark CRC bytes) (piwi) + - Added a LF ASK Sequence Terminator detection option to the standard ask demod - and applied it to `lf search u`, `lf t55xx detect`, and `data rawdemod am s` (@marshmellow42) + - `lf awid bruteforce ` - Simple bruteforce attack against a AWID reader. + - `lf t55xx bruteforce [i <*.dic>]` - Simple bruteforce attack to find password - (@iceman1001 and others) + - `lf viking clone`- clone viking tag to t55x7 or Q5 from 4byte hex ID input + - `lf viking sim` - sim full viking tag from 4byte hex ID input + - `lf viking read` - read viking tag and output ID + - `lf t55xx wipe` - sets t55xx back to factory defaults + - Added viking demod to `lf search` (@marshmellow42) + - `data askvikingdemod` demod viking id tag from graphbuffer (@marshmellow42) + - `lf t55xx resetread` added reset then read command - should allow determining start of stream transmissions (@marshmellow42) + - `lf t55xx wakeup` added wake with password (AOR) to allow lf search or standard lf read after (@iceman1001, @marshmellow42) + - `hf mf eload u` added an ultralight/ntag option. (@marshmellow42) + - `hf iclass managekeys` to save, load and manage iclass keys. (adjusted most commands to accept a loaded key in memory) (@marshmellow42) + - `hf iclass readblk` to select, authenticate, and read 1 block from an iclass card (@marshmellow42) + - `hf iclass writeblk` to select, authenticate, and write 1 block to an iclass card (or picopass) (@marshmellow42 + others) + - `hf iclass clone` to take a saved dump file and clone selected blocks to a new tag (@marshmellow42 + others) + - `hf iclass calcnewkey` - to calculate the div_key change to change a key - (experimental) (@marshmellow42 + others) + - `hf iclass encryptblk` - to encrypt a data block hex to prep for writing that block (@marshmellow42) + - ISO14443a stand-alone operation with ARM CFLAG="WITH_ISO14443a_StandAlone". This code can read & emulate two banks of 14a tag UIDs and write to "magic" cards (Craig Young) + - AWID26 command context added as 'lf awid' containing realtime demodulation as well as cloning/simulation based on tag numbers (Craig Young) + - Added 'hw status'. This command makes the ARM print out some runtime information. (@holiman) + - Added 'hw ping'. This command just sends a usb packets and checks if the pm3 is responsive. Can be used to abort certain operations which supports abort over usb. (@holiman) + - Added `data hex2bin` and `data bin2hex` for command line conversion between binary and hexadecimal (@holiman) + - Added 'hf snoop'. This command take digitalized signal from FPGA and put in BigBuffer. (@pwpiwi + enio) + - Added Topaz (NFC type 1) protocol support ('hf topaz reader', 'hf list topaz', 'hf 14a raw -T', 'hf topaz snoop'). (@pwpiwi) + - Added option c to 'hf list' (mark CRC bytes) (@pwpiwi) -### Changed -- Added `[l] ` option to data printdemodbuffer -- Adjusted lf awid clone to optionally clone to Q5 tags -- Adjusted lf t55xx detect to find Q5 tags (t5555) instead of just t55x7 -- Adjusted all lf NRZ demods - works more accurately and consistently (as long as you have strong signal) -- Adjusted lf pskindalademod to reduce false positive reads. -- Small adjustments to psk, nrz, and ask clock detect routines - more reliable. -- Adjusted lf em410x em410xsim to accept a clock argument -- Adjusted lf t55xx dump to allow overriding the safety check and warning text (marshmellow) -- Adjusted lf t55xx write input variables (marshmellow) -- Adjusted lf t55xx read with password safety check and warning text and adjusted the input variables (marshmellow & iceman) -- Adjusted LF FSK demod to account for cross threshold fluctuations (898 count waves will adjust the 9 to 8 now...) more accurate. (marshmellow) -- Adjusted timings for t55xx commands. more reliable now. (marshmellow & iceman) -- `lf cmdread` adjusted input methods and added help text (marshmellow & iceman) -- changed `lf config t ` to be 0 - 128 and will trigger on + or - threshold value (marshmellow) -- `hf iclass dump` cli options - can now dump AA1 and AA2 with different keys in one run (does not go to multiple pages for the larger tags yet) (marshmellow) -- Revised workflow for StandAloneMode14a (Craig Young) -- EPA functions (`hf epa`) now support both ISO 14443-A and 14443-B cards (frederikmoellers) -- 'hw version' only talks to ARM at startup, after that the info is cached. (pwpiwi) -- Added `r` option to iclass functions - allows key to be provided in raw block 3/4 format +### Changed + - Added `[l] ` option to data printdemodbuffer + - Adjusted lf awid clone to optionally clone to Q5 tags + - Adjusted lf t55xx detect to find Q5 tags (t5555) instead of just t55x7 + - Adjusted all lf NRZ demods - works more accurately and consistently (as long as you have strong signal) + - Adjusted lf pskindalademod to reduce false positive reads. + - Small adjustments to psk, nrz, and ask clock detect routines - more reliable. + - Adjusted lf em410x em410xsim to accept a clock argument + - Adjusted lf t55xx dump to allow overriding the safety check and warning text (@marshmellow42) + - Adjusted lf t55xx write input variables (@marshmellow42) + - Adjusted lf t55xx read with password safety check and warning text and adjusted the input variables (@marshmellow42 & @iceman1001) + - Adjusted LF FSK demod to account for cross threshold fluctuations (898 count waves will adjust the 9 to 8 now...) more accurate. (@marshmellow42) + - Adjusted timings for t55xx commands. more reliable now. (@marshmellow42 & @iceman1001) + - `lf cmdread` adjusted input methods and added help text (@marshmellow42 & @iceman1001) + - changed `lf config t ` to be 0 - 128 and will trigger on + or - threshold value (@marshmellow42) + - `hf iclass dump` cli options - can now dump AA1 and AA2 with different keys in one run (does not go to multiple pages for the larger tags yet) (@marshmellow42) + - Revised workflow for StandAloneMode14a (Craig Young) + - EPA functions (`hf epa`) now support both ISO 14443-A and 14443-B cards (@frederikmoellers) + - 'hw version' only talks to ARM at startup, after that the info is cached. (@pwpiwi) + - Added `r` option to iclass functions - allows key to be provided in raw block 3/4 format ## [2.2.0][2015-07-12] ### Changed -- Added `hf 14b raw -s` option to auto select a 14b std tag before raw command -- Changed `hf 14b write` to `hf 14b sriwrite` as it only applied to sri tags (marshmellow) -- Added `hf 14b info` to `hf search` (marshmellow) -- Added compression of fpga config and data, *BOOTROM REFLASH REQUIRED* (piwi) -- Implemented better detection of mifare-tags that are not vulnerable to classic attacks (`hf mf mifare`, `hf mf nested`) (piwi) + - Added `hf 14b raw -s` option to auto select a 14b std tag before raw command + - Changed `hf 14b write` to `hf 14b sriwrite` as it only applied to sri tags (@marshmellow42) + - Added `hf 14b info` to `hf search` (@marshmellow42) + - Added compression of fpga config and data, *BOOTROM REFLASH REQUIRED* (@pwpiwi) + - Implemented better detection of mifare-tags that are not vulnerable to classic attacks (`hf mf mifare`, `hf mf nested`) (@pwpiwi) ### Added -- Add `hf 14b reader` to find and print general info about known 14b tags (marshmellow) -- Add `hf 14b info` to find and print info about std 14b tags and sri tags (using 14b raw commands in the client) (marshmellow) -- Add PACE replay functionality (frederikmoellers) + - Add `hf 14b reader` to find and print general info about known 14b tags (@marshmellow42) + - Add `hf 14b info` to find and print info about std 14b tags and sri tags (using 14b raw commands in the client) (@marshmellow42) + - Add PACE replay functionality (@frederikmoellers) ### Fixed -- t55xx write timing (marshmellow) + - t55xx write timing (@marshmellow42) ## [2.1.0][2015-06-23] ### Changed -- Added ultralight/ntag tag type detection to `hf 14a read` (marshmellow) -- Improved ultralight dump command to auto detect tag type, take authentication, and dump full memory (or subset specified) of known tag types (iceman1001 / marshmellow) -- Combined ultralight read/write commands and added authentication (iceman1001) -- Improved LF manchester and biphase demodulation and ask clock detection especially for reads with heavy clipping. (marshmellow) -- Iclass read, `hf iclass read` now also reads tag config and prints configuration. (holiman) -- *bootrom* needs to be flashed, due to new address boundaries between os and fpga, after a size optimization (piwi) + - Added ultralight/ntag tag type detection to `hf 14a read` (@marshmellow42) + - Improved ultralight dump command to auto detect tag type, take authentication, and dump full memory (or subset specified) of known tag types (@iceman1001 / @marshmellow42) + - Combined ultralight read/write commands and added authentication (@iceman1001) + - Improved LF manchester and biphase demodulation and ask clock detection especially for reads with heavy clipping. (@marshmellow42) + - Iclass read, `hf iclass read` now also reads tag config and prints configuration. (@holiman) + - *bootrom* needs to be flashed, due to new address boundaries between os and fpga, after a size optimization (@pwpiwi) ### Fixed -- Fixed EM4x50 read/demod of the tags broadcasted memory blocks. 'lf em4x em4x50read' (not page read) (marshmellow) -- Fixed issue #19, problems with LF T55xx commands (iceman1001, marshmellow) -- Fixed various problems with iso14443b, issue #103 (piwi, marshmellow) + - Fixed EM4x50 read/demod of the tags broadcasted memory blocks. 'lf em4x em4x50read' (not page read) (@marshmellow42) + - Fixed issue #19, problems with LF T55xx commands (@iceman1001, @marshmellow42) + - Fixed various problems with iso14443b, issue #103 (@pwpiwi, @marshmellow42) ### Added -- Added `hf search` - currently tests for 14443a tags, iclass tags, and 15693 tags (marshmellow) -- Added `hf mfu info` Ultralight/NTAG info command - reads tag configuration and info, allows authentication if needed (iceman1001, marshmellow) -- Added Mifare Ultralight C and Ultralight EV1/NTAG authentication. (iceman1001) -- Added changelog -- Added `data fdxbdemod` - Demodulate a FDX-B ISO11784/85 Biphase tag from GraphBuffer aka ANIMAL TAG (marshmellow, iceman1001) + - Added `hf search` - currently tests for 14443a tags, iclass tags, and 15693 tags (@marshmellow42) + - Added `hf mfu info` Ultralight/NTAG info command - reads tag configuration and info, allows authentication if needed (@iceman1001, @marshmellow42) + - Added Mifare Ultralight C and Ultralight EV1/NTAG authentication. (@iceman1001) + - Added changelog + - Added `data fdxbdemod` - Demodulate a FDX-B ISO11784/85 Biphase tag from GraphBuffer aka ANIMAL TAG (@marshmellow42, @iceman1001) ## [2.0.0] - 2015-03-25 ### Changed -- LF sim operations now abort when new commands arrive over the USB - not required to push the device button anymore. + - LF sim operations now abort when new commands arrive over the USB - not required to push the device button anymore. ### Fixed -- Mifare simulation, `hf mf sim` (was broken a long time) (pwpiwi) -- Major improvements in LF area and data operations. (marshmellow, iceman1001) -- Issues regarding LF simulation (pwpiwi) + - Mifare simulation, `hf mf sim` (was broken a long time) (@pwpiwi) + - Major improvements in LF area and data operations. (@marshmellow42, @iceman1001) + - Issues regarding LF simulation (@pwpiwi) ### 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 don't seem to enforce update. (holiman). -- iClass decryption. Proxmark can now decrypt data on an iclass tag, but requires you to have the HID decryption key locally on your computer, as this is not bundled with the sourcecode. + - 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 don't seem to enforce update. (@holiman). + - iClass decryption. Proxmark can now decrypt data on an iclass tag, but requires you to have the HID decryption key locally on your computer, as this is not bundled with the sourcecode. From cdc3787008c3f95dd9563ae7100473c5ad07fa35 Mon Sep 17 00:00:00 2001 From: mwalker33 Date: Wed, 24 Jul 2019 08:12:25 +1000 Subject: [PATCH 0147/1854] clean --- armsrc/lfops.c | 2 ++ client/cmdlft55xx.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 17ac49dd2..75b5c934b 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -22,6 +22,8 @@ #include "pmflash.h" #include "flashmem.h" // persistence on mem + + //#define START_GAP 31*8 // was 250 // SPEC: 1*8 to 50*8 - typ 15*8 (15fc) //#define WRITE_GAP 8*8 // 17*8 // was 160 // SPEC: 1*8 to 20*8 - typ 10*8 (10fc) //#define WRITE_0 15*8 // 18*8 // was 144 // SPEC: 16*8 to 32*8 - typ 24*8 (24fc) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index bb8463692..ec98847db 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -2606,7 +2606,7 @@ static int CmdT55xxSetDeviceConfig(const char *Cmd) { // printf ("DLmode %d\n",downlink_mode); t55xx_config conf = {0}; - printf ("Size conf %lld\n",sizeof(conf)); +// printf ("Size conf %lld\n",sizeof(conf)); if (erase) { memset (&conf,0xff, sizeof(conf)); printf ("Conf.m[0] %x\n",conf.m[0].start_gap); From 6614995256a3e80eb429c1027d8fbad6a3d244c4 Mon Sep 17 00:00:00 2001 From: cjbrigato Date: Wed, 24 Jul 2019 00:20:00 +0200 Subject: [PATCH 0148/1854] HF_BOG make style --- armsrc/Standalone/hf_bog.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/armsrc/Standalone/hf_bog.c b/armsrc/Standalone/hf_bog.c index eaa69cd47..eaf27008b 100644 --- a/armsrc/Standalone/hf_bog.c +++ b/armsrc/Standalone/hf_bog.c @@ -138,7 +138,7 @@ void RAMFUNC SniffAndStore(uint8_t param) { if (triggered) { if ((receivedCmd) && - ((receivedCmd[0] == MIFARE_ULEV1_AUTH) || (receivedCmd[0] == MIFARE_ULC_AUTH_1))) { + ((receivedCmd[0] == MIFARE_ULEV1_AUTH) || (receivedCmd[0] == MIFARE_ULC_AUTH_1))) { if (DBGLEVEL > 1) Dbprintf("PWD-AUTH KEY: 0x%02x%02x%02x%02x", receivedCmd[1], receivedCmd[2], receivedCmd[3], receivedCmd[4]); @@ -207,8 +207,8 @@ void RAMFUNC SniffAndStore(uint8_t param) { Dbprintf("[!] Authentication attempts = %u", auth_attempts); if - size_t size = 4 * auth_attempts; - uint8_t *data = BigBuf_malloc(size); + size_t size = 4 * auth_attempts; + uint8_t *data = BigBuf_malloc(size); if (!exists_in_spiffs((char *)HF_BOG_LOGFILE)) { rdv40_spiffs_write((char *)HF_BOG_LOGFILE, (uint8_t *)data, size, RDV40_SPIFFS_SAFETY_SAFE); From c0eb19acb100669fef630a69a0f2c397e0246429 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 24 Jul 2019 00:52:24 +0200 Subject: [PATCH 0149/1854] remove tabs --- LICENSE.txt | 12 +- armsrc/iso14443a.h | 2 +- armsrc/ldscript | 86 +- armsrc/mifaresim.c | 194 +- armsrc/mifaresim.h | 4 +- armsrc/mifaresniff.c | 2 +- armsrc/mifareutil.c | 6 +- client/cmdlfem4x.c | 2 +- client/cmdsmartcard.h | 2 +- client/default_keys_dic2lua.awk | 29 +- client/deprecated-hid-flasher/unbind-proxmark | 22 +- client/loclass/loclass_information.txt | 2 +- client/scripts/ndef_dump.lua | 4 +- client/scripts/read_pwd_mem.lua | 10 +- doc/bt_manual_v10.md | 98 +- include/at91sam7s512.h | 2374 ++++++++--------- include/pm3_cmd.h | 14 +- tools/jtag_openocd/chip-at91sam7s.cfg | 24 +- tools/mfkey/example_trace.txt | 40 +- 19 files changed, 1480 insertions(+), 1447 deletions(-) diff --git a/LICENSE.txt b/LICENSE.txt index b26a158fa..7f48bec21 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,13 +1,13 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. - Preamble + Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public @@ -57,7 +57,7 @@ patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. - GNU GENERAL PUBLIC LICENSE + GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains @@ -256,7 +256,7 @@ make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. - NO WARRANTY + NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN @@ -278,4 +278,4 @@ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - END OF TERMS AND CONDITIONS + END OF TERMS AND CONDITIONS diff --git a/armsrc/iso14443a.h b/armsrc/iso14443a.h index 5ebc3e645..e5523c598 100644 --- a/armsrc/iso14443a.h +++ b/armsrc/iso14443a.h @@ -104,7 +104,7 @@ typedef struct { #endif #ifndef CheckCrc14A -# define CheckCrc14A(data, len) check_crc(CRC_14443_A, (data), (len)) +# define CheckCrc14A(data, len) check_crc(CRC_14443_A, (data), (len)) #endif void GetParity(const uint8_t *pbtCmd, uint16_t len, uint8_t *par); diff --git a/armsrc/ldscript b/armsrc/ldscript index 34da26bcd..80c2a4aed 100644 --- a/armsrc/ldscript +++ b/armsrc/ldscript @@ -11,57 +11,57 @@ INCLUDE ../common/ldscript.common PHDRS { - text PT_LOAD FLAGS(5); - data PT_LOAD; - bss PT_LOAD; + text PT_LOAD FLAGS(5); + data PT_LOAD; + bss PT_LOAD; } ENTRY(Vector) SECTIONS { - .start : { - *(.startos) - } >osimage :text + .start : { + *(.startos) + } >osimage :text - .text : { - KEEP(*(stage1_image)) - *(.text) - *(.text.*) - *(.eh_frame) - *(.glue_7) - *(.glue_7t) - } >osimage :text + .text : { + KEEP(*(stage1_image)) + *(.text) + *(.text.*) + *(.eh_frame) + *(.glue_7) + *(.glue_7t) + } >osimage :text - .rodata : { - *(.rodata) - *(.rodata.*) - *(fpga_all_bit.data) - KEEP(*(.version_information)) - . = ALIGN(8); - } >osimage :text + .rodata : { + *(.rodata) + *(.rodata.*) + *(fpga_all_bit.data) + KEEP(*(.version_information)) + . = ALIGN(8); + } >osimage :text - .data : { - KEEP(*(compressed_data)) - *(.data) - *(.data.*) - *(.ramfunc) - . = ALIGN(4); - } >ram AT>osimage :data + .data : { + KEEP(*(compressed_data)) + *(.data) + *(.data.*) + *(.ramfunc) + . = ALIGN(4); + } >ram AT>osimage :data - __data_src_start__ = LOADADDR(.data); - __data_start__ = ADDR(.data); - __data_end__ = __data_start__ + SIZEOF(.data); - __os_size__ = SIZEOF(.text) + SIZEOF(.data) + SIZEOF(.rodata); - - .bss : { - __bss_start__ = .; - *(.bss) - *(.bss.*) - . = ALIGN(4); - __bss_end__ = .; - } >ram AT>ram :bss + __data_src_start__ = LOADADDR(.data); + __data_start__ = ADDR(.data); + __data_end__ = __data_start__ + SIZEOF(.data); + __os_size__ = SIZEOF(.text) + SIZEOF(.data) + SIZEOF(.rodata); + + .bss : { + __bss_start__ = .; + *(.bss) + *(.bss.*) + . = ALIGN(4); + __bss_end__ = .; + } >ram AT>ram :bss - .commonarea (NOLOAD) : { - *(.commonarea) - } >commonarea :NONE + .commonarea (NOLOAD) : { + *(.commonarea) + } >commonarea :NONE } diff --git a/armsrc/mifaresim.c b/armsrc/mifaresim.c index 25abcb10a..0e64f00d1 100644 --- a/armsrc/mifaresim.c +++ b/armsrc/mifaresim.c @@ -42,30 +42,36 @@ static bool IsTrailerAccessAllowed(uint8_t blockNo, uint8_t keytype, uint8_t act | ((sector_trailer[8] >> 7) & 0x01); switch (action) { case AC_KEYA_READ: { - if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("IsTrailerAccessAllowed: AC_KEYA_READ"); + if (DBGLEVEL >= DBG_EXTENDED) + Dbprintf("IsTrailerAccessAllowed: AC_KEYA_READ"); return false; } case AC_KEYA_WRITE: { - if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("IsTrailerAccessAllowed: AC_KEYA_WRITE"); + if (DBGLEVEL >= DBG_EXTENDED) + Dbprintf("IsTrailerAccessAllowed: AC_KEYA_WRITE"); return ((keytype == AUTHKEYA && (AC == 0x00 || AC == 0x01)) || (keytype == AUTHKEYB && (AC == 0x04 || AC == 0x03))); } case AC_KEYB_READ: { - if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("IsTrailerAccessAllowed: AC_KEYB_READ"); + if (DBGLEVEL >= DBG_EXTENDED) + Dbprintf("IsTrailerAccessAllowed: AC_KEYB_READ"); return (keytype == AUTHKEYA && (AC == 0x00 || AC == 0x02 || AC == 0x01)); } case AC_KEYB_WRITE: { - if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("IsTrailerAccessAllowed: AC_KEYB_WRITE"); + if (DBGLEVEL >= DBG_EXTENDED) + Dbprintf("IsTrailerAccessAllowed: AC_KEYB_WRITE"); return ((keytype == AUTHKEYA && (AC == 0x00 || AC == 0x01)) || (keytype == AUTHKEYB && (AC == 0x04 || AC == 0x03))); } case AC_AC_READ: { - if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("IsTrailerAccessAllowed: AC_AC_READ"); + if (DBGLEVEL >= DBG_EXTENDED) + Dbprintf("IsTrailerAccessAllowed: AC_AC_READ"); return ((keytype == AUTHKEYA) || (keytype == AUTHKEYB && !(AC == 0x00 || AC == 0x02 || AC == 0x01))); } case AC_AC_WRITE: { - if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("IsTrailerAccessAllowed: AC_AC_WRITE"); + if (DBGLEVEL >= DBG_EXTENDED) + Dbprintf("IsTrailerAccessAllowed: AC_AC_WRITE"); return ((keytype == AUTHKEYA && (AC == 0x01)) || (keytype == AUTHKEYB && (AC == 0x03 || AC == 0x05))); } @@ -93,46 +99,54 @@ static bool IsDataAccessAllowed(uint8_t blockNo, uint8_t keytype, uint8_t action AC = ((sector_trailer[7] >> 2) & 0x04) | ((sector_trailer[8] << 1) & 0x02) | ((sector_trailer[8] >> 4) & 0x01); - if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("IsDataAccessAllowed: case 0x00 - %02x", AC); + if (DBGLEVEL >= DBG_EXTENDED) + Dbprintf("IsDataAccessAllowed: case 0x00 - %02x", AC); break; } case 0x01: { AC = ((sector_trailer[7] >> 3) & 0x04) | ((sector_trailer[8] >> 0) & 0x02) | ((sector_trailer[8] >> 5) & 0x01); - if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("IsDataAccessAllowed: case 0x01 - %02x", AC); + if (DBGLEVEL >= DBG_EXTENDED) + Dbprintf("IsDataAccessAllowed: case 0x01 - %02x", AC); break; } case 0x02: { AC = ((sector_trailer[7] >> 4) & 0x04) | ((sector_trailer[8] >> 1) & 0x02) | ((sector_trailer[8] >> 6) & 0x01); - if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("IsDataAccessAllowed: case 0x02 - %02x", AC); + if (DBGLEVEL >= DBG_EXTENDED) + Dbprintf("IsDataAccessAllowed: case 0x02 - %02x", AC); break; } default: - if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("IsDataAccessAllowed: Error"); + if (DBGLEVEL >= DBG_EXTENDED) + Dbprintf("IsDataAccessAllowed: Error"); return false; } switch (action) { case AC_DATA_READ: { - if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("IsDataAccessAllowed - AC_DATA_READ: OK"); + if (DBGLEVEL >= DBG_EXTENDED) + Dbprintf("IsDataAccessAllowed - AC_DATA_READ: OK"); return ((keytype == AUTHKEYA && !(AC == 0x03 || AC == 0x05 || AC == 0x07)) || (keytype == AUTHKEYB && !(AC == 0x07))); } case AC_DATA_WRITE: { - if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("IsDataAccessAllowed - AC_DATA_WRITE: OK"); + if (DBGLEVEL >= DBG_EXTENDED) + Dbprintf("IsDataAccessAllowed - AC_DATA_WRITE: OK"); return ((keytype == AUTHKEYA && (AC == 0x00)) || (keytype == AUTHKEYB && (AC == 0x00 || AC == 0x04 || AC == 0x06 || AC == 0x03))); } case AC_DATA_INC: { - if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("IsDataAccessAllowed - AC_DATA_INC: OK"); + if (DBGLEVEL >= DBG_EXTENDED) + Dbprintf("IsDataAccessAllowed - AC_DATA_INC: OK"); return ((keytype == AUTHKEYA && (AC == 0x00)) || (keytype == AUTHKEYB && (AC == 0x00 || AC == 0x06))); } case AC_DATA_DEC_TRANS_REST: { - if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("AC_DATA_DEC_TRANS_REST: OK"); + if (DBGLEVEL >= DBG_EXTENDED) + Dbprintf("AC_DATA_DEC_TRANS_REST: OK"); return ((keytype == AUTHKEYA && (AC == 0x00 || AC == 0x06 || AC == 0x01)) || (keytype == AUTHKEYB && (AC == 0x00 || AC == 0x06 || AC == 0x01))); } @@ -160,25 +174,25 @@ static bool MifareSimInit(uint16_t flags, uint8_t *datain, tag_response_info_t * // SAK static uint8_t rSAK_Mini = 0x09; // mifare Mini - static uint8_t rSAK_1k = 0x08; // mifare 1k - static uint8_t rSAK_2k = 0x08; // mifare 2k with RATS support - static uint8_t rSAK_4k = 0x18; // mifare 4k + static uint8_t rSAK_1k = 0x08; // mifare 1k + static uint8_t rSAK_2k = 0x08; // mifare 2k with RATS support + static uint8_t rSAK_4k = 0x18; // mifare 4k - static uint8_t rUIDBCC1[] = {0x00, 0x00, 0x00, 0x00, 0x00}; // UID 1st cascade level - static uint8_t rUIDBCC1b4[] = {0x00, 0x00, 0x00, 0x00}; // UID 1st cascade level, last 4 bytes - static uint8_t rUIDBCC1b3[] = {0x00, 0x00, 0x00}; // UID 1st cascade level, last 3 bytes - static uint8_t rUIDBCC1b2[] = {0x00, 0x00}; // UID 1st cascade level, last 2 bytes - static uint8_t rUIDBCC1b1[] = {0x00}; // UID 1st cascade level, last byte - static uint8_t rUIDBCC2[] = {0x00, 0x00, 0x00, 0x00, 0x00}; // UID 2nd cascade level - static uint8_t rUIDBCC2b4[] = {0x00, 0x00, 0x00, 0x00}; // UID 2st cascade level, last 4 bytes - static uint8_t rUIDBCC2b3[] = {0x00, 0x00, 0x00}; // UID 2st cascade level, last 3 bytes - static uint8_t rUIDBCC2b2[] = {0x00, 0x00}; // UID 2st cascade level, last 2 bytes - static uint8_t rUIDBCC2b1[] = {0x00}; // UID 2st cascade level, last byte - static uint8_t rUIDBCC3[] = {0x00, 0x00, 0x00, 0x00, 0x00}; // UID 3nd cascade level - static uint8_t rUIDBCC3b4[] = {0x00, 0x00, 0x00, 0x00}; // UID 3st cascade level, last 4 bytes - static uint8_t rUIDBCC3b3[] = {0x00, 0x00, 0x00}; // UID 3st cascade level, last 3 bytes - static uint8_t rUIDBCC3b2[] = {0x00, 0x00}; // UID 3st cascade level, last 2 bytes - static uint8_t rUIDBCC3b1[] = {0x00}; // UID 3st cascade level, last byte + static uint8_t rUIDBCC1[] = {0x00, 0x00, 0x00, 0x00, 0x00}; // UID 1st cascade level + static uint8_t rUIDBCC1b4[] = {0x00, 0x00, 0x00, 0x00}; // UID 1st cascade level, last 4 bytes + static uint8_t rUIDBCC1b3[] = {0x00, 0x00, 0x00}; // UID 1st cascade level, last 3 bytes + static uint8_t rUIDBCC1b2[] = {0x00, 0x00}; // UID 1st cascade level, last 2 bytes + static uint8_t rUIDBCC1b1[] = {0x00}; // UID 1st cascade level, last byte + static uint8_t rUIDBCC2[] = {0x00, 0x00, 0x00, 0x00, 0x00}; // UID 2nd cascade level + static uint8_t rUIDBCC2b4[] = {0x00, 0x00, 0x00, 0x00}; // UID 2st cascade level, last 4 bytes + static uint8_t rUIDBCC2b3[] = {0x00, 0x00, 0x00}; // UID 2st cascade level, last 3 bytes + static uint8_t rUIDBCC2b2[] = {0x00, 0x00}; // UID 2st cascade level, last 2 bytes + static uint8_t rUIDBCC2b1[] = {0x00}; // UID 2st cascade level, last byte + static uint8_t rUIDBCC3[] = {0x00, 0x00, 0x00, 0x00, 0x00}; // UID 3nd cascade level + static uint8_t rUIDBCC3b4[] = {0x00, 0x00, 0x00, 0x00}; // UID 3st cascade level, last 4 bytes + static uint8_t rUIDBCC3b3[] = {0x00, 0x00, 0x00}; // UID 3st cascade level, last 3 bytes + static uint8_t rUIDBCC3b2[] = {0x00, 0x00}; // UID 3st cascade level, last 2 bytes + static uint8_t rUIDBCC3b1[] = {0x00}; // UID 3st cascade level, last byte static uint8_t rATQA[] = {0x00, 0x00}; // Current ATQA static uint8_t rSAK[] = {0x00, 0x00, 0x00}; // Current SAK, CRC @@ -254,17 +268,18 @@ static bool MifareSimInit(uint16_t flags, uint8_t *datain, tag_response_info_t * } // Prepare UID arrays - if ((flags & FLAG_4B_UID_IN_DATA) == FLAG_4B_UID_IN_DATA) { // get UID from datain + if ((flags & FLAG_4B_UID_IN_DATA) == FLAG_4B_UID_IN_DATA) { // get UID from datain memcpy(rUIDBCC1, datain, 4); *uid_len = 4; - if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("MifareSimInit - FLAG_4B_UID_IN_DATA => Get UID from datain: %02X - Flag: %02X - UIDBCC1: %02X", FLAG_4B_UID_IN_DATA, flags, rUIDBCC1); + if (DBGLEVEL >= DBG_EXTENDED) + Dbprintf("MifareSimInit - FLAG_4B_UID_IN_DATA => Get UID from datain: %02X - Flag: %02X - UIDBCC1: %02X", FLAG_4B_UID_IN_DATA, flags, rUIDBCC1); // save CUID *cuid = bytes_to_num(rUIDBCC1, 4); // BCC rUIDBCC1[4] = rUIDBCC1[0] ^ rUIDBCC1[1] ^ rUIDBCC1[2] ^ rUIDBCC1[3]; - if (DBGLEVEL >= DBG_NONE) { + if (DBGLEVEL >= DBG_NONE) { Dbprintf("4B UID: %02x%02x%02x%02x", rUIDBCC1[0], rUIDBCC1[1], rUIDBCC1[2], rUIDBCC1[3]); } @@ -275,7 +290,8 @@ static bool MifareSimInit(uint16_t flags, uint8_t *datain, tag_response_info_t * memcpy(&rUIDBCC1[1], datain, 3); memcpy(rUIDBCC2, datain + 3, 4); *uid_len = 7; - if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("MifareSimInit - FLAG_7B_UID_IN_DATA => Get UID from datain: %02X - Flag: %02X - UIDBCC1: %02X", FLAG_7B_UID_IN_DATA, flags, rUIDBCC1); + if (DBGLEVEL >= DBG_EXTENDED) + Dbprintf("MifareSimInit - FLAG_7B_UID_IN_DATA => Get UID from datain: %02X - Flag: %02X - UIDBCC1: %02X", FLAG_7B_UID_IN_DATA, flags, rUIDBCC1); // save CUID *cuid = bytes_to_num(rUIDBCC2, 4); @@ -284,7 +300,7 @@ static bool MifareSimInit(uint16_t flags, uint8_t *datain, tag_response_info_t * // BCC rUIDBCC1[4] = rUIDBCC1[0] ^ rUIDBCC1[1] ^ rUIDBCC1[2] ^ rUIDBCC1[3]; rUIDBCC2[4] = rUIDBCC2[0] ^ rUIDBCC2[1] ^ rUIDBCC2[2] ^ rUIDBCC2[3]; - if (DBGLEVEL >= DBG_NONE) { + if (DBGLEVEL >= DBG_NONE) { Dbprintf("7B UID: %02x %02x %02x %02x %02x %02x %02x", rUIDBCC1[1], rUIDBCC1[2], rUIDBCC1[3], rUIDBCC2[0], rUIDBCC2[1], rUIDBCC2[2], rUIDBCC2[3]); } @@ -297,7 +313,8 @@ static bool MifareSimInit(uint16_t flags, uint8_t *datain, tag_response_info_t * memcpy(&rUIDBCC2[1], datain + 3, 3); memcpy(rUIDBCC3, datain + 6, 4); *uid_len = 10; - if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("MifareSimInit - FLAG_10B_UID_IN_DATA => Get UID from datain: %02X - Flag: %02X - UIDBCC1: %02X", FLAG_10B_UID_IN_DATA, flags, rUIDBCC1); + if (DBGLEVEL >= DBG_EXTENDED) + Dbprintf("MifareSimInit - FLAG_10B_UID_IN_DATA => Get UID from datain: %02X - Flag: %02X - UIDBCC1: %02X", FLAG_10B_UID_IN_DATA, flags, rUIDBCC1); // save CUID *cuid = bytes_to_num(rUIDBCC3, 4); @@ -309,7 +326,7 @@ static bool MifareSimInit(uint16_t flags, uint8_t *datain, tag_response_info_t * rUIDBCC2[4] = rUIDBCC2[0] ^ rUIDBCC2[1] ^ rUIDBCC2[2] ^ rUIDBCC2[3]; rUIDBCC3[4] = rUIDBCC3[0] ^ rUIDBCC3[1] ^ rUIDBCC3[2] ^ rUIDBCC3[3]; - if (DBGLEVEL >= DBG_NONE) { + if (DBGLEVEL >= DBG_NONE) { Dbprintf("10B UID: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", rUIDBCC1[1], rUIDBCC1[2], rUIDBCC1[3], rUIDBCC2[1], rUIDBCC2[2], rUIDBCC2[3], @@ -347,23 +364,23 @@ static bool MifareSimInit(uint16_t flags, uint8_t *datain, tag_response_info_t * #define TAG_RESPONSE_COUNT 18 static tag_response_info_t responses_init[TAG_RESPONSE_COUNT] = { - { .response = rATQA, .response_n = sizeof(rATQA) }, // Answer to request - respond with card type + { .response = rATQA, .response_n = sizeof(rATQA) }, // Answer to request - respond with card type { .response = rSAK, .response_n = sizeof(rSAK) }, // - { .response = rSAKuid, .response_n = sizeof(rSAKuid) }, // + { .response = rSAKuid, .response_n = sizeof(rSAKuid) }, // // Do not reorder. Block used via relative index of rUIDBCC1 - { .response = rUIDBCC1, .response_n = sizeof(rUIDBCC1) }, // Anticollision cascade1 - respond with first part of uid + { .response = rUIDBCC1, .response_n = sizeof(rUIDBCC1) }, // Anticollision cascade1 - respond with first part of uid { .response = rUIDBCC1b4, .response_n = sizeof(rUIDBCC1b4)}, { .response = rUIDBCC1b3, .response_n = sizeof(rUIDBCC1b3)}, { .response = rUIDBCC1b2, .response_n = sizeof(rUIDBCC1b2)}, { .response = rUIDBCC1b1, .response_n = sizeof(rUIDBCC1b1)}, // Do not reorder. Block used via relative index of rUIDBCC2 - { .response = rUIDBCC2, .response_n = sizeof(rUIDBCC2) }, // Anticollision cascade2 - respond with 2nd part of uid + { .response = rUIDBCC2, .response_n = sizeof(rUIDBCC2) }, // Anticollision cascade2 - respond with 2nd part of uid { .response = rUIDBCC2b4, .response_n = sizeof(rUIDBCC2b4)}, { .response = rUIDBCC2b3, .response_n = sizeof(rUIDBCC2b3)}, { .response = rUIDBCC2b2, .response_n = sizeof(rUIDBCC2b2)}, { .response = rUIDBCC2b1, .response_n = sizeof(rUIDBCC2b1)}, // Do not reorder. Block used via relative index of rUIDBCC3 - { .response = rUIDBCC3, .response_n = sizeof(rUIDBCC3) }, // Anticollision cascade3 - respond with 3th part of uid + { .response = rUIDBCC3, .response_n = sizeof(rUIDBCC3) }, // Anticollision cascade3 - respond with 3th part of uid { .response = rUIDBCC3b4, .response_n = sizeof(rUIDBCC3b4)}, { .response = rUIDBCC3b3, .response_n = sizeof(rUIDBCC3b3)}, { .response = rUIDBCC3b2, .response_n = sizeof(rUIDBCC3b2)}, @@ -407,11 +424,11 @@ static bool MifareSimInit(uint16_t flags, uint8_t *datain, tag_response_info_t * *MIFARE 1K simulate. * *@param flags : -* FLAG_INTERACTIVE - In interactive mode, we are expected to finish the operation with an ACK +* FLAG_INTERACTIVE - In interactive mode, we are expected to finish the operation with an ACK * FLAG_4B_UID_IN_DATA - means that there is a 4-byte UID in the data-section, we're expected to use that * FLAG_7B_UID_IN_DATA - means that there is a 7-byte UID in the data-section, we're expected to use that -* FLAG_10B_UID_IN_DATA - use 10-byte UID in the data-section not finished -* FLAG_NR_AR_ATTACK - means we should collect NR_AR responses for bruteforcing later +* FLAG_10B_UID_IN_DATA - use 10-byte UID in the data-section not finished +* FLAG_NR_AR_ATTACK - means we should collect NR_AR responses for bruteforcing later *@param exitAfterNReads, exit simulation after n blocks have been read, 0 is infinite ... * (unless reader attack mode enabled then it runs util it gets enough nonces to recover all keys attmpted) */ @@ -421,7 +438,7 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain) { uint8_t uid_len = 0; // 4,7, 10 uint32_t cuid = 0; - int vHf = 0; // in mV + int vHf = 0; // in mV uint32_t selTimer = 0; uint32_t authTimer = 0; @@ -445,7 +462,7 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain) { struct Crypto1State *pcs; pcs = &mpcs; - uint32_t numReads = 0; //Counts numer of times reader reads a block + uint32_t numReads = 0; //Counts numer of times reader reads a block uint8_t receivedCmd[MAX_MIFARE_FRAME_SIZE] = {0x00}; uint8_t receivedCmd_dec[MAX_MIFARE_FRAME_SIZE] = {0x00}; uint8_t receivedCmd_par[MAX_MIFARE_PARITY_SIZE] = {0x00}; @@ -467,11 +484,11 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain) { uint8_t ar_nr_collected[ATTACK_KEY_COUNT * 2]; //*2 for 2nd attack type (moebius) memset(ar_nr_collected, 0x00, sizeof(ar_nr_collected)); - uint8_t nonce1_count = 0; - uint8_t nonce2_count = 0; - uint8_t moebius_n_count = 0; + uint8_t nonce1_count = 0; + uint8_t nonce2_count = 0; + uint8_t moebius_n_count = 0; bool gettingMoebius = false; - uint8_t mM = 0; //moebius_modifier for collection storage + uint8_t mM = 0; //moebius_modifier for collection storage // Authenticate response - nonce uint8_t rAUTH_NT[4]; @@ -520,18 +537,21 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain) { if (res == 2) { //Field is off! LEDsoff(); cardSTATE = MFEMUL_NOFIELD; - if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("cardSTATE = MFEMUL_NOFIELD"); + if (DBGLEVEL >= DBG_EXTENDED) + Dbprintf("cardSTATE = MFEMUL_NOFIELD"); continue; } else if (res == 1) { // button pressed button_pushed = true; - if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("Button pressed"); + if (DBGLEVEL >= DBG_EXTENDED) + Dbprintf("Button pressed"); break; } // WUPA in HALTED state or REQA or WUPA in any other state if (receivedCmd_len == 1 && ((receivedCmd[0] == ISO14443A_CMD_REQA && cardSTATE != MFEMUL_HALTED) || receivedCmd[0] == ISO14443A_CMD_WUPA)) { selTimer = GetTickCount(); - if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("EmSendPrecompiledCmd(&responses[ATQA]);"); + if (DBGLEVEL >= DBG_EXTENDED) + Dbprintf("EmSendPrecompiledCmd(&responses[ATQA]);"); EmSendPrecompiledCmd(&responses[ATQA]); // init crypto block @@ -550,12 +570,15 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain) { switch (cardSTATE) { case MFEMUL_NOFIELD: - if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("MFEMUL_NOFIELD"); + if (DBGLEVEL >= DBG_EXTENDED) + Dbprintf("MFEMUL_NOFIELD"); case MFEMUL_HALTED: - if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("MFEMUL_HALTED"); + if (DBGLEVEL >= DBG_EXTENDED) + Dbprintf("MFEMUL_HALTED"); case MFEMUL_IDLE: { LogTrace(uart->output, uart->len, uart->startTime * 16 - DELAY_AIR2ARM_AS_TAG, uart->endTime * 16 - DELAY_AIR2ARM_AS_TAG, uart->parity, true); - if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("MFEMUL_IDLE"); + if (DBGLEVEL >= DBG_EXTENDED) + Dbprintf("MFEMUL_IDLE"); break; } @@ -649,7 +672,8 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain) { // WORK case MFEMUL_WORK: { - if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] Enter in case"); + if (DBGLEVEL >= DBG_EXTENDED) + Dbprintf("[MFEMUL_WORK] Enter in case"); if (receivedCmd_len == 0) { if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] NO CMD received"); @@ -799,20 +823,20 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain) { if (IsSectorTrailer(blockNo)) { if (!IsAccessAllowed(blockNo, cardAUTHKEY, AC_KEYA_READ)) { - memset(response, 0x00, 6); // keyA can never be read + memset(response, 0x00, 6); // keyA can never be read if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK - IsSectorTrailer] keyA can never be read - block %d (0x%02x)", blockNo, blockNo); } if (!IsAccessAllowed(blockNo, cardAUTHKEY, AC_KEYB_READ)) { - memset(response + 10, 0x00, 6); // keyB cannot be read + memset(response + 10, 0x00, 6); // keyB cannot be read if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK - IsSectorTrailer] keyB cannot be read - block %d (0x%02x)", blockNo, blockNo); } if (!IsAccessAllowed(blockNo, cardAUTHKEY, AC_AC_READ)) { - memset(response + 6, 0x00, 4); // AC bits cannot be read + memset(response + 6, 0x00, 4); // AC bits cannot be read if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK - IsAccessAllowed] AC bits cannot be read - block %d (0x%02x)", blockNo, blockNo); } } else { if (!IsAccessAllowed(blockNo, cardAUTHKEY, AC_DATA_READ)) { - memset(response, 0x00, 16); // datablock cannot be read + memset(response, 0x00, 16); // datablock cannot be read if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK - IsAccessAllowed] Data block %d (0x%02x) cannot be read", blockNo, blockNo); } } @@ -898,7 +922,8 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain) { LED_C_OFF(); cardSTATE = MFEMUL_HALTED; cardAUTHKEY = AUTHKEYNONE; - if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] cardSTATE = MFEMUL_HALTED"); + if (DBGLEVEL >= DBG_EXTENDED) + Dbprintf("[MFEMUL_WORK] cardSTATE = MFEMUL_HALTED"); break; } @@ -911,10 +936,12 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain) { EmSendCmdPar(response, rats_len, response_par); } else EmSendCmd(rats, rats_len); - if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] RCV RATS => ACK"); + if (DBGLEVEL >= DBG_EXTENDED) + Dbprintf("[MFEMUL_WORK] RCV RATS => ACK"); } else { EmSend4bit(encrypted_data ? mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA) : CARD_NACK_NA); - if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] RCV RATS => NACK"); + if (DBGLEVEL >= DBG_EXTENDED) + Dbprintf("[MFEMUL_WORK] RCV RATS => NACK"); } break; } @@ -929,28 +956,33 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain) { EmSendCmdPar(response, receivedCmd_len, response_par); } else EmSendCmd(receivedCmd_dec, receivedCmd_len); - if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] RCV NXP DESELECT => ACK"); + if (DBGLEVEL >= DBG_EXTENDED) + Dbprintf("[MFEMUL_WORK] RCV NXP DESELECT => ACK"); } else { EmSend4bit(encrypted_data ? mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA) : CARD_NACK_NA); - if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] RCV NXP DESELECT => NACK"); + if (DBGLEVEL >= DBG_EXTENDED) + Dbprintf("[MFEMUL_WORK] RCV NXP DESELECT => NACK"); } break; } // case MFEMUL_WORK => command not allowed - if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("Received command not allowed, nacking"); + if (DBGLEVEL >= DBG_EXTENDED) + Dbprintf("Received command not allowed, nacking"); EmSend4bit(encrypted_data ? mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA) : CARD_NACK_NA); break; } // AUTH1 case MFEMUL_AUTH1: { - if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("[MFEMUL_AUTH1] Enter case"); + if (DBGLEVEL >= DBG_EXTENDED) + Dbprintf("[MFEMUL_AUTH1] Enter case"); if (receivedCmd_len != 8) { cardSTATE_TO_IDLE(); LogTrace(uart->output, uart->len, uart->startTime * 16 - DELAY_AIR2ARM_AS_TAG, uart->endTime * 16 - DELAY_AIR2ARM_AS_TAG, uart->parity, true); - if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("MFEMUL_AUTH1: receivedCmd_len != 8 (%d) => cardSTATE_TO_IDLE())", receivedCmd_len); + if (DBGLEVEL >= DBG_EXTENDED) + Dbprintf("MFEMUL_AUTH1: receivedCmd_len != 8 (%d) => cardSTATE_TO_IDLE())", receivedCmd_len); break; } @@ -1034,7 +1066,7 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain) { , prng_successor(nonce, 64) ); } - cardAUTHKEY = AUTHKEYNONE; // not authenticated + cardAUTHKEY = AUTHKEYNONE; // not authenticated cardSTATE_TO_IDLE(); // Really tags not respond NACK on invalid authentication LogTrace(uart->output, uart->len, uart->startTime * 16 - DELAY_AIR2ARM_AS_TAG, uart->endTime * 16 - DELAY_AIR2ARM_AS_TAG, uart->parity, true); @@ -1067,21 +1099,21 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain) { if (IsSectorTrailer(cardWRBL)) { emlGetMem(response, cardWRBL, 1); if (!IsAccessAllowed(cardWRBL, cardAUTHKEY, AC_KEYA_WRITE)) { - memcpy(receivedCmd_dec, response, 6); // don't change KeyA + memcpy(receivedCmd_dec, response, 6); // don't change KeyA } if (!IsAccessAllowed(cardWRBL, cardAUTHKEY, AC_KEYB_WRITE)) { - memcpy(receivedCmd_dec + 10, response + 10, 6); // don't change KeyA + memcpy(receivedCmd_dec + 10, response + 10, 6); // don't change KeyA } if (!IsAccessAllowed(cardWRBL, cardAUTHKEY, AC_AC_WRITE)) { - memcpy(receivedCmd_dec + 6, response + 6, 4); // don't change AC bits + memcpy(receivedCmd_dec + 6, response + 6, 4); // don't change AC bits } } else { if (!IsAccessAllowed(cardWRBL, cardAUTHKEY, AC_DATA_WRITE)) { - memcpy(receivedCmd_dec, response, 16); // don't change anything + memcpy(receivedCmd_dec, response, 16); // don't change anything } } emlSetMem(receivedCmd_dec, cardWRBL, 1); - EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_ACK)); // always ACK? + EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_ACK)); // always ACK? cardSTATE = MFEMUL_WORK; if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("[MFEMUL_WRITEBL2] cardSTATE = MFEMUL_WORK"); break; @@ -1152,7 +1184,7 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain) { // NR AR ATTACK if (((flags & FLAG_NR_AR_ATTACK) == FLAG_NR_AR_ATTACK) && (DBGLEVEL >= DBG_INFO)) { - for (uint8_t i = 0; i < ATTACK_KEY_COUNT; i++) { + for (uint8_t i = 0; i < ATTACK_KEY_COUNT; i++) { if (ar_nr_collected[i] == 2) { Dbprintf("Collected two pairs of AR/NR which can be used to extract %s from reader for sector %d:", (i < ATTACK_KEY_COUNT / 2) ? "keyA" : "keyB", ar_nr_resp[i].sector); Dbprintf("../tools/mfkey/mfkey32 %08x %08x %08x %08x %08x %08x", @@ -1167,7 +1199,7 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain) { } } - for (uint8_t i = ATTACK_KEY_COUNT; i < ATTACK_KEY_COUNT * 2; i++) { + for (uint8_t i = ATTACK_KEY_COUNT; i < ATTACK_KEY_COUNT * 2; i++) { if (ar_nr_collected[i] == 2) { Dbprintf("Collected two pairs of AR/NR which can be used to extract %s from reader for sector %d:", (i < ATTACK_KEY_COUNT / 2) ? "keyA" : "keyB", ar_nr_resp[i].sector); Dbprintf("../tools/mfkey/mfkey32v2 %08x %08x %08x %08x %08x %08x %08x", @@ -1182,7 +1214,7 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain) { } } - if (DBGLEVEL >= DBG_ERROR) { + if (DBGLEVEL >= DBG_ERROR) { Dbprintf("Emulator stopped. Tracing: %d trace length: %d ", get_tracing(), BigBuf_get_traceLen()); } diff --git a/armsrc/mifaresim.h b/armsrc/mifaresim.h index 2dc9650cc..d05b730c9 100644 --- a/armsrc/mifaresim.h +++ b/armsrc/mifaresim.h @@ -16,7 +16,7 @@ #include #ifndef CheckCrc14A -# define CheckCrc14A(data, len) check_crc(CRC_14443_A, (data), (len)) +# define CheckCrc14A(data, len) check_crc(CRC_14443_A, (data), (len)) #endif void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain); @@ -24,7 +24,7 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain); #define AC_DATA_READ 0 #define AC_DATA_WRITE 1 #define AC_DATA_INC 2 -#define AC_DATA_DEC_TRANS_REST 3 +#define AC_DATA_DEC_TRANS_REST 3 #define AC_KEYA_READ 0 #define AC_KEYA_WRITE 1 #define AC_KEYB_READ 2 diff --git a/armsrc/mifaresniff.c b/armsrc/mifaresniff.c index 1d7f576af..4171ab572 100644 --- a/armsrc/mifaresniff.c +++ b/armsrc/mifaresniff.c @@ -11,7 +11,7 @@ #include "mifaresniff.h" #ifndef CheckCrc14A -# define CheckCrc14A(data, len) check_crc(CRC_14443_A, (data), (len)) +# define CheckCrc14A(data, len) check_crc(CRC_14443_A, (data), (len)) #endif //static int sniffState = SNF_INIT; diff --git a/armsrc/mifareutil.c b/armsrc/mifareutil.c index 6142198a5..b5f7567f9 100644 --- a/armsrc/mifareutil.c +++ b/armsrc/mifareutil.c @@ -602,10 +602,12 @@ void emlClearMem(void) { uint8_t SectorTrailer(uint8_t blockNo) { if (blockNo <= MIFARE_2K_MAXBLOCK) { - if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("Sector Trailer for block %d : %d", blockNo, (blockNo | 0x03)); + if (DBGLEVEL >= DBG_EXTENDED) + Dbprintf("Sector Trailer for block %d : %d", blockNo, (blockNo | 0x03)); return (blockNo | 0x03); } else { - if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("Sector Trailer for block %d : %d", blockNo, (blockNo | 0x0f)); + if (DBGLEVEL >= DBG_EXTENDED) + Dbprintf("Sector Trailer for block %d : %d", blockNo, (blockNo | 0x0f)); return (blockNo | 0x0f); } } diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c index eb8de8f86..165f22001 100644 --- a/client/cmdlfem4x.c +++ b/client/cmdlfem4x.c @@ -243,7 +243,7 @@ void printEM410x(uint32_t hi, uint64_t id) { if (!id && !hi) return; - PrintAndLogEx(SUCCESS, "EM410x%s pattern found", (hi) ? " XL " : ""); + PrintAndLogEx(SUCCESS, "EM410x%s pattern found", (hi) ? " XL" : ""); uint64_t n = 1; uint64_t id2lo = 0; diff --git a/client/cmdsmartcard.h b/client/cmdsmartcard.h index 9032ab265..6b960f311 100644 --- a/client/cmdsmartcard.h +++ b/client/cmdsmartcard.h @@ -25,7 +25,7 @@ #include "emv/emvcore.h" // decodeTVL #include "emv/apduinfo.h" // APDUcode description #include "emv/dump.h" // dump_buffer -#include "crypto/libpcrypto.h" // sha512hash +#include "crypto/libpcrypto.h" // sha512hash int CmdSmartcard(const char *Cmd); diff --git a/client/default_keys_dic2lua.awk b/client/default_keys_dic2lua.awk index 432ace8bf..47a4d5439 100644 --- a/client/default_keys_dic2lua.awk +++ b/client/default_keys_dic2lua.awk @@ -1,24 +1,23 @@ BEGIN { - print "--[[" - print "These are default_keys dictionary" - print "This file is automatically generated from default_keys.h - DON'T EDIT MANUALLY." - print "--]]" - print "local _keys = {" + print "--[[" + print "These are default_keys dictionary" + print "This file is automatically generated from default_keys.h - DON'T EDIT MANUALLY." + print "--]]" + print "local _keys = {" } $1 ~ /^[A-Fa-f0-9]+/ { sub(/\r/, ""); print " '"substr($1,1,12)"'," } END { - print "}" - - print "---" - print "-- The keys above have just been pasted in, for completeness sake. They contain duplicates. " - print "-- We need to weed the duplicates out before we expose the list to someone who actually wants to use them" - print "-- @param list a list to do 'uniq' on" - print "" - print "local function uniq(list)" + print "}" + print "---" + print "-- The keys above have just been pasted in, for completeness sake. They contain duplicates. " + print "-- We need to weed the duplicates out before we expose the list to someone who actually wants to use them" + print "-- @param list a list to do 'uniq' on" print "" - print " local foobar = {}" + print "local function uniq(list)" + print "" + print " local foobar = {}" print " for _, value in pairs(list) do" print " value = value:lower()" print " if not foobar[value] then" @@ -29,4 +28,4 @@ END { print " return foobar" print "end" print "return uniq(_keys)" -} \ No newline at end of file +} diff --git a/client/deprecated-hid-flasher/unbind-proxmark b/client/deprecated-hid-flasher/unbind-proxmark index 986c0015d..325607cb6 100755 --- a/client/deprecated-hid-flasher/unbind-proxmark +++ b/client/deprecated-hid-flasher/unbind-proxmark @@ -1,16 +1,16 @@ #!/bin/sh for i in /sys/bus/usb/devices/*; do - if grep "9ac4" "${i}/idVendor" >/dev/null 2>&1; then - echo "Found Proxmark..." - dev=`basename "${i}"` + if grep "9ac4" "${i}/idVendor" >/dev/null 2>&1; then + echo "Found Proxmark..." + dev=`basename "${i}"` - for j in /sys/bus/usb/drivers/usbhid/*; do - if basename "${j}"|grep "^${dev}" >/dev/null; then - bound="`basename "${j}"`" - echo "Unbinding ${bound}..." - echo -n "${bound}" >/sys/bus/usb/drivers/usbhid/unbind - fi - done - fi + for j in /sys/bus/usb/drivers/usbhid/*; do + if basename "${j}"|grep "^${dev}" >/dev/null; then + bound="`basename "${j}"`" + echo "Unbinding ${bound}..." + echo -n "${bound}" >/sys/bus/usb/drivers/usbhid/unbind + fi + done + fi done diff --git a/client/loclass/loclass_information.txt b/client/loclass/loclass_information.txt index b01e447b0..307d28203 100644 --- a/client/loclass/loclass_information.txt +++ b/client/loclass/loclass_information.txt @@ -4,7 +4,7 @@ iclass_dump.bin =============== The file iclass_dump.bin contains CSN's mac results from 128 CSNs. Hence when running the test mode, - 'hf iclass loclass t' + 'hf iclass loclass t' it shows a long output from the bruteforce test. iclass_key.bin diff --git a/client/scripts/ndef_dump.lua b/client/scripts/ndef_dump.lua index d162e35cf..856053207 100644 --- a/client/scripts/ndef_dump.lua +++ b/client/scripts/ndef_dump.lua @@ -239,9 +239,9 @@ local function main( args) for k,v in ipairs(blockData) do -- print(string.format('Block %02x: %02x %02x %02x %02x', k-1, string.byte(v, 1,4))) - print(string.format(' %02x | %s', k-1, v) ) + print(string.format(' %02x | %s', k-1, v) ) end - print('|---|-------------------|') + print('|---|-------------------|') local filename, err = utils.WriteDumpFile(info.uid, blockData) if err then return oops(err) end diff --git a/client/scripts/read_pwd_mem.lua b/client/scripts/read_pwd_mem.lua index 5f8edcc74..4a097d26d 100644 --- a/client/scripts/read_pwd_mem.lua +++ b/client/scripts/read_pwd_mem.lua @@ -82,11 +82,11 @@ local function main(args) -- num of bytes to read if o == 'l' then - length = tonumber(a) - if length < 0 or length > 256 then - return oops('Error: Length is not valid. Must be less than 256') - end - end + length = tonumber(a) + if length < 0 or length > 256 then + return oops('Error: Length is not valid. Must be less than 256') + end + end -- keylength if o == 'k' then keylength = tonumber(a); usedkey = true end diff --git a/doc/bt_manual_v10.md b/doc/bt_manual_v10.md index 032680cfa..1cc8d3690 100644 --- a/doc/bt_manual_v10.md +++ b/doc/bt_manual_v10.md @@ -2,14 +2,14 @@ ### Bluetooth / Battery add-on 'Blue Shark' _rev. v1.0 (draft)_ -### 1. FEATURES +### 1. FEATURES -* Built-in Bluetooth 2.0 with EDR Bluetooth module, default baud rate 115200. -* Built-in 400 mAh polymer lithium-ion battery, typical standby time up to 3.5 hours. -* Additional heat dissipating fins can significantly reduce the temperature when the HF antenna is in operation for a long time. -* Complete lithium charging management system, seamless switching power supply. Full overcharge and overdischarge protection. -* Bluetooth has an independent power switch that can be turned on or off. -* It's compact and easy to carry. The clamp structure is easy to install and replace. +* Built-in Bluetooth 2.0 with EDR Bluetooth module, default baud rate 115200. +* Built-in 400 mAh polymer lithium-ion battery, typical standby time up to 3.5 hours. +* Additional heat dissipating fins can significantly reduce the temperature when the HF antenna is in operation for a long time. +* Complete lithium charging management system, seamless switching power supply. Full overcharge and overdischarge protection. +* Bluetooth has an independent power switch that can be turned on or off. +* It's compact and easy to carry. The clamp structure is easy to install and replace. It can easily connect to Bluetooth mobile phone, portable computer, etc. Without USB cable, complicated permissions or driver settings. @@ -17,35 +17,35 @@ It can easily connect to Bluetooth mobile phone, portable computer, etc. Without Built-in battery can support standalone mode, off-line sniffing, off-line reading & simulation, etc. The temperature of the device is stable. -### 2. PARAMETERS +### 2. PARAMETERS -* Battery capacity: 400 mAh -* Standby time: 3.5h @ StandBy; 2.9h @ LF-On; 50min @ HF-On; -* Charging Current: 200mA (Plug in USB Default Charging) -* Charging time: 2.5h -* Num of charges: 400 -> 70% capacity (standard LIPO) -* Bluetooth power: 4dBm, -85 dBm @ 2Mbps -* Bluetooth distance: 6m (depending on the environment and device orientation) -* Size and weight: 54.4mm * 29.4mm * 13.5mm 24g +* Battery capacity: 400 mAh +* Standby time: 3.5h @ StandBy; 2.9h @ LF-On; 50min @ HF-On; +* Charging Current: 200mA (Plug in USB Default Charging) +* Charging time: 2.5h +* Num of charges: 400 -> 70% capacity (standard LIPO) +* Bluetooth power: 4dBm, -85 dBm @ 2Mbps +* Bluetooth distance: 6m (depending on the environment and device orientation) +* Size and weight: 54.4mm * 29.4mm * 13.5mm 24g -### 3. ASSEMBLY STEPS +### 3. ASSEMBLY STEPS -* Unplug your Proxmark3 RDV4.0 device from any usb cable. -* Remove the plastic upper case of Proxmark3 RDV4.0 with opener. -* Remove temporarily the antenna with a H5 (Hex/Allen) screwdriver to expose the FPC interface.

- Image of blue shark add-on fpc interface

-* Turn off all power switches, insert the FPC wire into the FPC connector, and lock the FPC connector.

- Image of blue shark add-on fpc wire

-* Tear off the blue film of heat conductive double-sided tape. Align the add-on to the hole positions and gently insert it into the case.

- Image of blue shark add-on blue film location

-* Assembly finished! +* Unplug your Proxmark3 RDV4.0 device from any usb cable. +* Remove the plastic upper case of Proxmark3 RDV4.0 with opener. +* Remove temporarily the antenna with a H5 (Hex/Allen) screwdriver to expose the FPC interface.

+ Image of blue shark add-on fpc interface

+* Turn off all power switches, insert the FPC wire into the FPC connector, and lock the FPC connector.

+ Image of blue shark add-on fpc wire

+* Tear off the blue film of heat conductive double-sided tape. Align the add-on to the hole positions and gently insert it into the case.

+ Image of blue shark add-on blue film location

+* Assembly finished!

Image of blue shark add-on open fitImage of blue shark add-on fitted

-### 4. COMPILATION / FLASHING +### 4. COMPILATION / FLASHING #### From Source @@ -69,7 +69,7 @@ From the [homebrew-proxmark3 readme](https://github.com/RfidResearchGroup/homebr 1. `brew tap rfidresearchgroup/proxmark3` 2. `brew install --with-blueshark proxmark3` -### 5. CONNECT WITH BLUETOOTH +### 5. CONNECT WITH BLUETOOTH You can have both USB cable connect and BT active at the same time and connect to either serial port. You can also switch serial port from inside the proxmark3 client using the new command `hw connect`. @@ -82,30 +82,30 @@ You can also switch serial port from inside the proxmark3 client using the new c #### Windows -#### (1) Connecting your RDV4.0 with Bluetooth on mobile phone or computer -* Open Bluetooth and search for a device named PM3_RDV4.0. -* Enter the paired password 1234 and establish the connection. -* The blue state LED on the add-on will keep blinking after the connection is established. Only when the mobile phone or computer opens the correct COM port, the blue LED turns on solid, indicating that the connection is successful. +#### (1) Connecting your RDV4.0 with Bluetooth on mobile phone or computer +* Open Bluetooth and search for a device named PM3_RDV4.0. +* Enter the paired password 1234 and establish the connection. +* The blue state LED on the add-on will keep blinking after the connection is established. Only when the mobile phone or computer opens the correct COM port, the blue LED turns on solid, indicating that the connection is successful. -#### (2) Fast connection using dedicated USB Bluetooth adapter under Windows +#### (2) Fast connection using dedicated USB Bluetooth adapter under Windows

Image of blue shark add-on HC-06 white dongle

-* Install driver: +* Install driver: http://www.silabs.com/products/development-tools/software/usb-to-uart-bridge-vcp-drivers -* Insert the adapter into the USB port. The adapter will search automatically and establish the connection. The adapter will remember the device that was first connected and after that the same device will be connected. -* The adapter button can be used to delete memory so that other add-on can be searched and connected.

- Image of blue shark add-on HC-06 white dongle button -* After the connection is established, the blue state LED on add-on will turn on solid. -* look for _CP2104 USB tp UART bridge controller_ under devices in order to get the assigned serial port +* Insert the adapter into the USB port. The adapter will search automatically and establish the connection. The adapter will remember the device that was first connected and after that the same device will be connected. +* The adapter button can be used to delete memory so that other add-on can be searched and connected.

+ Image of blue shark add-on HC-06 white dongle button +* After the connection is established, the blue state LED on add-on will turn on solid. +* look for _CP2104 USB tp UART bridge controller_ under devices in order to get the assigned serial port #### Linux #### (1) Connecting rdv4.0 with Bluetooth on Linux computer 1. Find the MAC address of the Bluetooth add-on, named PM3_RDV4.0. - + ```sh sudo hcitool scan Scanning ... @@ -161,8 +161,8 @@ be connected. 2. The adapter button can be used to delete memory so that other add-on can be searched and connected.

- Image of blue shark add-on HC-06 white dongle button -

+ Image of blue shark add-on HC-06 white dongle button +

3. After the connection is established, the blue state LED on add-on will turn on solid. @@ -195,22 +195,22 @@ After reboot you can go ahead to pairing your Proxmark3 RDV4 Blue Shark: ``` -### 6. OTHER NOTES +### 6. OTHER NOTES -#### (1) UART and LED behavior +#### (1) UART and LED behavior Bluetooth is connected to Proxmark3 RDV4.0 via UART. The USB and UART interfaces of RDV4.0 can coexist without conflict, and no special switching is required. The following link has helpful notes on UART usage and baud rates: https://github.com/RfidResearchGroup/proxmark3/blob/master/doc/uart_notes.md -#### (2) Disassembly +#### (2) Disassembly There is a heat conductive double-sided tape inside the add-on, which has strong adhesive force. Therefore, if add-on needs to be removed, it needs to be pulled out from the heat sink end with greater efforts. Each disassembly will reduce the viscidity of double-sided tape. When double-sided tape is well protected, it will not affect the second use. Thermal conductivity will be slightly worse and will therefore have a direct impact on the thermal performance of the heat sink. -#### (3) Battery charging +#### (3) Battery charging The battery charging circuit is turned on by default. Any time a USB cable is inserted, the battery will be automatically charged. The red LED will remain bright when charging. The red LED will be extinguished when charging is completed. -#### (4) Get better signals -For the better heat dissipation, we have used a cast metal enclosure for the add-on. As a result Bluetooth wireless signals are sacrificed. For example, if the back of add-on is facing the Bluetooth host, the signal is very bad and the distance will be reduced. The best signal strength can be obtained when the front glass faces the Bluetooth host. - If the Proxmark3 is not responding, it may be due to a poor Bluetooth connection. To improve performance, try repositioning the Proxmark3 so the glass face is directed toward the host. +#### (4) Get better signals +For the better heat dissipation, we have used a cast metal enclosure for the add-on. As a result Bluetooth wireless signals are sacrificed. For example, if the back of add-on is facing the Bluetooth host, the signal is very bad and the distance will be reduced. The best signal strength can be obtained when the front glass faces the Bluetooth host. +If the Proxmark3 is not responding, it may be due to a poor Bluetooth connection. To improve performance, try repositioning the Proxmark3 so the glass face is directed toward the host. diff --git a/include/at91sam7s512.h b/include/at91sam7s512.h index db27893e2..bca65bdf3 100644 --- a/include/at91sam7s512.h +++ b/include/at91sam7s512.h @@ -71,126 +71,126 @@ typedef volatile unsigned int AT91_REG;// Hardware register definition // ***************************************************************************** #ifndef __ASSEMBLY__ typedef struct _AT91S_SYS { - AT91_REG AIC_SMR[32]; // Source Mode Register - AT91_REG AIC_SVR[32]; // Source Vector Register - AT91_REG AIC_IVR; // IRQ Vector Register - AT91_REG AIC_FVR; // FIQ Vector Register - AT91_REG AIC_ISR; // Interrupt Status Register - AT91_REG AIC_IPR; // Interrupt Pending Register - AT91_REG AIC_IMR; // Interrupt Mask Register - AT91_REG AIC_CISR; // Core Interrupt Status Register - AT91_REG Reserved0[2]; // - AT91_REG AIC_IECR; // Interrupt Enable Command Register - AT91_REG AIC_IDCR; // Interrupt Disable Command Register - AT91_REG AIC_ICCR; // Interrupt Clear Command Register - AT91_REG AIC_ISCR; // Interrupt Set Command Register - AT91_REG AIC_EOICR; // End of Interrupt Command Register - AT91_REG AIC_SPU; // Spurious Vector Register - AT91_REG AIC_DCR; // Debug Control Register (Protect) - AT91_REG Reserved1[1]; // - AT91_REG AIC_FFER; // Fast Forcing Enable Register - AT91_REG AIC_FFDR; // Fast Forcing Disable Register - AT91_REG AIC_FFSR; // Fast Forcing Status Register - AT91_REG Reserved2[45]; // - AT91_REG DBGU_CR; // Control Register - AT91_REG DBGU_MR; // Mode Register - AT91_REG DBGU_IER; // Interrupt Enable Register - AT91_REG DBGU_IDR; // Interrupt Disable Register - AT91_REG DBGU_IMR; // Interrupt Mask Register - AT91_REG DBGU_CSR; // Channel Status Register - AT91_REG DBGU_RHR; // Receiver Holding Register - AT91_REG DBGU_THR; // Transmitter Holding Register - AT91_REG DBGU_BRGR; // Baud Rate Generator Register - AT91_REG Reserved3[7]; // - AT91_REG DBGU_CIDR; // Chip ID Register - AT91_REG DBGU_EXID; // Chip ID Extension Register - AT91_REG DBGU_FNTR; // Force NTRST Register - AT91_REG Reserved4[45]; // - AT91_REG DBGU_RPR; // Receive Pointer Register - AT91_REG DBGU_RCR; // Receive Counter Register - AT91_REG DBGU_TPR; // Transmit Pointer Register - AT91_REG DBGU_TCR; // Transmit Counter Register - AT91_REG DBGU_RNPR; // Receive Next Pointer Register - AT91_REG DBGU_RNCR; // Receive Next Counter Register - AT91_REG DBGU_TNPR; // Transmit Next Pointer Register - AT91_REG DBGU_TNCR; // Transmit Next Counter Register - AT91_REG DBGU_PTCR; // PDC Transfer Control Register - AT91_REG DBGU_PTSR; // PDC Transfer Status Register - AT91_REG Reserved5[54]; // - AT91_REG PIOA_PER; // PIO Enable Register - AT91_REG PIOA_PDR; // PIO Disable Register - AT91_REG PIOA_PSR; // PIO Status Register - AT91_REG Reserved6[1]; // - AT91_REG PIOA_OER; // Output Enable Register - AT91_REG PIOA_ODR; // Output Disable Registerr - AT91_REG PIOA_OSR; // Output Status Register - AT91_REG Reserved7[1]; // - AT91_REG PIOA_IFER; // Input Filter Enable Register - AT91_REG PIOA_IFDR; // Input Filter Disable Register - AT91_REG PIOA_IFSR; // Input Filter Status Register - AT91_REG Reserved8[1]; // - AT91_REG PIOA_SODR; // Set Output Data Register - AT91_REG PIOA_CODR; // Clear Output Data Register - AT91_REG PIOA_ODSR; // Output Data Status Register - AT91_REG PIOA_PDSR; // Pin Data Status Register - AT91_REG PIOA_IER; // Interrupt Enable Register - AT91_REG PIOA_IDR; // Interrupt Disable Register - AT91_REG PIOA_IMR; // Interrupt Mask Register - AT91_REG PIOA_ISR; // Interrupt Status Register - AT91_REG PIOA_MDER; // Multi-driver Enable Register - AT91_REG PIOA_MDDR; // Multi-driver Disable Register - AT91_REG PIOA_MDSR; // Multi-driver Status Register - AT91_REG Reserved9[1]; // - AT91_REG PIOA_PPUDR; // Pull-up Disable Register - AT91_REG PIOA_PPUER; // Pull-up Enable Register - AT91_REG PIOA_PPUSR; // Pull-up Status Register - AT91_REG Reserved10[1]; // - AT91_REG PIOA_ASR; // Select A Register - AT91_REG PIOA_BSR; // Select B Register - AT91_REG PIOA_ABSR; // AB Select Status Register - AT91_REG Reserved11[9]; // - AT91_REG PIOA_OWER; // Output Write Enable Register - AT91_REG PIOA_OWDR; // Output Write Disable Register - AT91_REG PIOA_OWSR; // Output Write Status Register - AT91_REG Reserved12[469]; // - AT91_REG PMC_SCER; // System Clock Enable Register - AT91_REG PMC_SCDR; // System Clock Disable Register - AT91_REG PMC_SCSR; // System Clock Status Register - AT91_REG Reserved13[1]; // - AT91_REG PMC_PCER; // Peripheral Clock Enable Register - AT91_REG PMC_PCDR; // Peripheral Clock Disable Register - AT91_REG PMC_PCSR; // Peripheral Clock Status Register - AT91_REG Reserved14[1]; // - AT91_REG PMC_MOR; // Main Oscillator Register - AT91_REG PMC_MCFR; // Main Clock Frequency Register - AT91_REG Reserved15[1]; // - AT91_REG PMC_PLLR; // PLL Register - AT91_REG PMC_MCKR; // Master Clock Register - AT91_REG Reserved16[3]; // - AT91_REG PMC_PCKR[3]; // Programmable Clock Register - AT91_REG Reserved17[5]; // - AT91_REG PMC_IER; // Interrupt Enable Register - AT91_REG PMC_IDR; // Interrupt Disable Register - AT91_REG PMC_SR; // Status Register - AT91_REG PMC_IMR; // Interrupt Mask Register - AT91_REG Reserved18[36]; // - AT91_REG RSTC_RCR; // Reset Control Register - AT91_REG RSTC_RSR; // Reset Status Register - AT91_REG RSTC_RMR; // Reset Mode Register - AT91_REG Reserved19[5]; // - AT91_REG RTTC_RTMR; // Real-time Mode Register - AT91_REG RTTC_RTAR; // Real-time Alarm Register - AT91_REG RTTC_RTVR; // Real-time Value Register - AT91_REG RTTC_RTSR; // Real-time Status Register - AT91_REG PITC_PIMR; // Period Interval Mode Register - AT91_REG PITC_PISR; // Period Interval Status Register - AT91_REG PITC_PIVR; // Period Interval Value Register - AT91_REG PITC_PIIR; // Period Interval Image Register - AT91_REG WDTC_WDCR; // Watchdog Control Register - AT91_REG WDTC_WDMR; // Watchdog Mode Register - AT91_REG WDTC_WDSR; // Watchdog Status Register - AT91_REG Reserved20[5]; // - AT91_REG VREG_MR; // Voltage Regulator Mode Register + AT91_REG AIC_SMR[32]; // Source Mode Register + AT91_REG AIC_SVR[32]; // Source Vector Register + AT91_REG AIC_IVR; // IRQ Vector Register + AT91_REG AIC_FVR; // FIQ Vector Register + AT91_REG AIC_ISR; // Interrupt Status Register + AT91_REG AIC_IPR; // Interrupt Pending Register + AT91_REG AIC_IMR; // Interrupt Mask Register + AT91_REG AIC_CISR; // Core Interrupt Status Register + AT91_REG Reserved0[2]; // + AT91_REG AIC_IECR; // Interrupt Enable Command Register + AT91_REG AIC_IDCR; // Interrupt Disable Command Register + AT91_REG AIC_ICCR; // Interrupt Clear Command Register + AT91_REG AIC_ISCR; // Interrupt Set Command Register + AT91_REG AIC_EOICR; // End of Interrupt Command Register + AT91_REG AIC_SPU; // Spurious Vector Register + AT91_REG AIC_DCR; // Debug Control Register (Protect) + AT91_REG Reserved1[1]; // + AT91_REG AIC_FFER; // Fast Forcing Enable Register + AT91_REG AIC_FFDR; // Fast Forcing Disable Register + AT91_REG AIC_FFSR; // Fast Forcing Status Register + AT91_REG Reserved2[45]; // + AT91_REG DBGU_CR; // Control Register + AT91_REG DBGU_MR; // Mode Register + AT91_REG DBGU_IER; // Interrupt Enable Register + AT91_REG DBGU_IDR; // Interrupt Disable Register + AT91_REG DBGU_IMR; // Interrupt Mask Register + AT91_REG DBGU_CSR; // Channel Status Register + AT91_REG DBGU_RHR; // Receiver Holding Register + AT91_REG DBGU_THR; // Transmitter Holding Register + AT91_REG DBGU_BRGR; // Baud Rate Generator Register + AT91_REG Reserved3[7]; // + AT91_REG DBGU_CIDR; // Chip ID Register + AT91_REG DBGU_EXID; // Chip ID Extension Register + AT91_REG DBGU_FNTR; // Force NTRST Register + AT91_REG Reserved4[45]; // + AT91_REG DBGU_RPR; // Receive Pointer Register + AT91_REG DBGU_RCR; // Receive Counter Register + AT91_REG DBGU_TPR; // Transmit Pointer Register + AT91_REG DBGU_TCR; // Transmit Counter Register + AT91_REG DBGU_RNPR; // Receive Next Pointer Register + AT91_REG DBGU_RNCR; // Receive Next Counter Register + AT91_REG DBGU_TNPR; // Transmit Next Pointer Register + AT91_REG DBGU_TNCR; // Transmit Next Counter Register + AT91_REG DBGU_PTCR; // PDC Transfer Control Register + AT91_REG DBGU_PTSR; // PDC Transfer Status Register + AT91_REG Reserved5[54]; // + AT91_REG PIOA_PER; // PIO Enable Register + AT91_REG PIOA_PDR; // PIO Disable Register + AT91_REG PIOA_PSR; // PIO Status Register + AT91_REG Reserved6[1]; // + AT91_REG PIOA_OER; // Output Enable Register + AT91_REG PIOA_ODR; // Output Disable Registerr + AT91_REG PIOA_OSR; // Output Status Register + AT91_REG Reserved7[1]; // + AT91_REG PIOA_IFER; // Input Filter Enable Register + AT91_REG PIOA_IFDR; // Input Filter Disable Register + AT91_REG PIOA_IFSR; // Input Filter Status Register + AT91_REG Reserved8[1]; // + AT91_REG PIOA_SODR; // Set Output Data Register + AT91_REG PIOA_CODR; // Clear Output Data Register + AT91_REG PIOA_ODSR; // Output Data Status Register + AT91_REG PIOA_PDSR; // Pin Data Status Register + AT91_REG PIOA_IER; // Interrupt Enable Register + AT91_REG PIOA_IDR; // Interrupt Disable Register + AT91_REG PIOA_IMR; // Interrupt Mask Register + AT91_REG PIOA_ISR; // Interrupt Status Register + AT91_REG PIOA_MDER; // Multi-driver Enable Register + AT91_REG PIOA_MDDR; // Multi-driver Disable Register + AT91_REG PIOA_MDSR; // Multi-driver Status Register + AT91_REG Reserved9[1]; // + AT91_REG PIOA_PPUDR; // Pull-up Disable Register + AT91_REG PIOA_PPUER; // Pull-up Enable Register + AT91_REG PIOA_PPUSR; // Pull-up Status Register + AT91_REG Reserved10[1]; // + AT91_REG PIOA_ASR; // Select A Register + AT91_REG PIOA_BSR; // Select B Register + AT91_REG PIOA_ABSR; // AB Select Status Register + AT91_REG Reserved11[9]; // + AT91_REG PIOA_OWER; // Output Write Enable Register + AT91_REG PIOA_OWDR; // Output Write Disable Register + AT91_REG PIOA_OWSR; // Output Write Status Register + AT91_REG Reserved12[469]; // + AT91_REG PMC_SCER; // System Clock Enable Register + AT91_REG PMC_SCDR; // System Clock Disable Register + AT91_REG PMC_SCSR; // System Clock Status Register + AT91_REG Reserved13[1]; // + AT91_REG PMC_PCER; // Peripheral Clock Enable Register + AT91_REG PMC_PCDR; // Peripheral Clock Disable Register + AT91_REG PMC_PCSR; // Peripheral Clock Status Register + AT91_REG Reserved14[1]; // + AT91_REG PMC_MOR; // Main Oscillator Register + AT91_REG PMC_MCFR; // Main Clock Frequency Register + AT91_REG Reserved15[1]; // + AT91_REG PMC_PLLR; // PLL Register + AT91_REG PMC_MCKR; // Master Clock Register + AT91_REG Reserved16[3]; // + AT91_REG PMC_PCKR[3]; // Programmable Clock Register + AT91_REG Reserved17[5]; // + AT91_REG PMC_IER; // Interrupt Enable Register + AT91_REG PMC_IDR; // Interrupt Disable Register + AT91_REG PMC_SR; // Status Register + AT91_REG PMC_IMR; // Interrupt Mask Register + AT91_REG Reserved18[36]; // + AT91_REG RSTC_RCR; // Reset Control Register + AT91_REG RSTC_RSR; // Reset Status Register + AT91_REG RSTC_RMR; // Reset Mode Register + AT91_REG Reserved19[5]; // + AT91_REG RTTC_RTMR; // Real-time Mode Register + AT91_REG RTTC_RTAR; // Real-time Alarm Register + AT91_REG RTTC_RTVR; // Real-time Value Register + AT91_REG RTTC_RTSR; // Real-time Status Register + AT91_REG PITC_PIMR; // Period Interval Mode Register + AT91_REG PITC_PISR; // Period Interval Status Register + AT91_REG PITC_PIVR; // Period Interval Value Register + AT91_REG PITC_PIIR; // Period Interval Image Register + AT91_REG WDTC_WDCR; // Watchdog Control Register + AT91_REG WDTC_WDMR; // Watchdog Mode Register + AT91_REG WDTC_WDSR; // Watchdog Status Register + AT91_REG Reserved20[5]; // + AT91_REG VREG_MR; // Voltage Regulator Mode Register } AT91S_SYS, *AT91PS_SYS; #else @@ -201,59 +201,59 @@ typedef struct _AT91S_SYS { // ***************************************************************************** #ifndef __ASSEMBLY__ typedef struct _AT91S_AIC { - AT91_REG AIC_SMR[32]; // Source Mode Register - AT91_REG AIC_SVR[32]; // Source Vector Register - AT91_REG AIC_IVR; // IRQ Vector Register - AT91_REG AIC_FVR; // FIQ Vector Register - AT91_REG AIC_ISR; // Interrupt Status Register - AT91_REG AIC_IPR; // Interrupt Pending Register - AT91_REG AIC_IMR; // Interrupt Mask Register - AT91_REG AIC_CISR; // Core Interrupt Status Register - AT91_REG Reserved0[2]; // - AT91_REG AIC_IECR; // Interrupt Enable Command Register - AT91_REG AIC_IDCR; // Interrupt Disable Command Register - AT91_REG AIC_ICCR; // Interrupt Clear Command Register - AT91_REG AIC_ISCR; // Interrupt Set Command Register - AT91_REG AIC_EOICR; // End of Interrupt Command Register - AT91_REG AIC_SPU; // Spurious Vector Register - AT91_REG AIC_DCR; // Debug Control Register (Protect) - AT91_REG Reserved1[1]; // - AT91_REG AIC_FFER; // Fast Forcing Enable Register - AT91_REG AIC_FFDR; // Fast Forcing Disable Register - AT91_REG AIC_FFSR; // Fast Forcing Status Register + AT91_REG AIC_SMR[32]; // Source Mode Register + AT91_REG AIC_SVR[32]; // Source Vector Register + AT91_REG AIC_IVR; // IRQ Vector Register + AT91_REG AIC_FVR; // FIQ Vector Register + AT91_REG AIC_ISR; // Interrupt Status Register + AT91_REG AIC_IPR; // Interrupt Pending Register + AT91_REG AIC_IMR; // Interrupt Mask Register + AT91_REG AIC_CISR; // Core Interrupt Status Register + AT91_REG Reserved0[2]; // + AT91_REG AIC_IECR; // Interrupt Enable Command Register + AT91_REG AIC_IDCR; // Interrupt Disable Command Register + AT91_REG AIC_ICCR; // Interrupt Clear Command Register + AT91_REG AIC_ISCR; // Interrupt Set Command Register + AT91_REG AIC_EOICR; // End of Interrupt Command Register + AT91_REG AIC_SPU; // Spurious Vector Register + AT91_REG AIC_DCR; // Debug Control Register (Protect) + AT91_REG Reserved1[1]; // + AT91_REG AIC_FFER; // Fast Forcing Enable Register + AT91_REG AIC_FFDR; // Fast Forcing Disable Register + AT91_REG AIC_FFSR; // Fast Forcing Status Register } AT91S_AIC, *AT91PS_AIC; #else -#define AIC_SMR (AT91_CAST(AT91_REG *) 0x00000000) // (AIC_SMR) Source Mode Register -#define AIC_SVR (AT91_CAST(AT91_REG *) 0x00000080) // (AIC_SVR) Source Vector Register -#define AIC_IVR (AT91_CAST(AT91_REG *) 0x00000100) // (AIC_IVR) IRQ Vector Register -#define AIC_FVR (AT91_CAST(AT91_REG *) 0x00000104) // (AIC_FVR) FIQ Vector Register -#define AIC_ISR (AT91_CAST(AT91_REG *) 0x00000108) // (AIC_ISR) Interrupt Status Register -#define AIC_IPR (AT91_CAST(AT91_REG *) 0x0000010C) // (AIC_IPR) Interrupt Pending Register -#define AIC_IMR (AT91_CAST(AT91_REG *) 0x00000110) // (AIC_IMR) Interrupt Mask Register -#define AIC_CISR (AT91_CAST(AT91_REG *) 0x00000114) // (AIC_CISR) Core Interrupt Status Register -#define AIC_IECR (AT91_CAST(AT91_REG *) 0x00000120) // (AIC_IECR) Interrupt Enable Command Register -#define AIC_IDCR (AT91_CAST(AT91_REG *) 0x00000124) // (AIC_IDCR) Interrupt Disable Command Register -#define AIC_ICCR (AT91_CAST(AT91_REG *) 0x00000128) // (AIC_ICCR) Interrupt Clear Command Register -#define AIC_ISCR (AT91_CAST(AT91_REG *) 0x0000012C) // (AIC_ISCR) Interrupt Set Command Register -#define AIC_EOICR (AT91_CAST(AT91_REG *) 0x00000130) // (AIC_EOICR) End of Interrupt Command Register -#define AIC_SPU (AT91_CAST(AT91_REG *) 0x00000134) // (AIC_SPU) Spurious Vector Register -#define AIC_DCR (AT91_CAST(AT91_REG *) 0x00000138) // (AIC_DCR) Debug Control Register (Protect) -#define AIC_FFER (AT91_CAST(AT91_REG *) 0x00000140) // (AIC_FFER) Fast Forcing Enable Register -#define AIC_FFDR (AT91_CAST(AT91_REG *) 0x00000144) // (AIC_FFDR) Fast Forcing Disable Register -#define AIC_FFSR (AT91_CAST(AT91_REG *) 0x00000148) // (AIC_FFSR) Fast Forcing Status Register +#define AIC_SMR (AT91_CAST(AT91_REG *) 0x00000000) // (AIC_SMR) Source Mode Register +#define AIC_SVR (AT91_CAST(AT91_REG *) 0x00000080) // (AIC_SVR) Source Vector Register +#define AIC_IVR (AT91_CAST(AT91_REG *) 0x00000100) // (AIC_IVR) IRQ Vector Register +#define AIC_FVR (AT91_CAST(AT91_REG *) 0x00000104) // (AIC_FVR) FIQ Vector Register +#define AIC_ISR (AT91_CAST(AT91_REG *) 0x00000108) // (AIC_ISR) Interrupt Status Register +#define AIC_IPR (AT91_CAST(AT91_REG *) 0x0000010C) // (AIC_IPR) Interrupt Pending Register +#define AIC_IMR (AT91_CAST(AT91_REG *) 0x00000110) // (AIC_IMR) Interrupt Mask Register +#define AIC_CISR (AT91_CAST(AT91_REG *) 0x00000114) // (AIC_CISR) Core Interrupt Status Register +#define AIC_IECR (AT91_CAST(AT91_REG *) 0x00000120) // (AIC_IECR) Interrupt Enable Command Register +#define AIC_IDCR (AT91_CAST(AT91_REG *) 0x00000124) // (AIC_IDCR) Interrupt Disable Command Register +#define AIC_ICCR (AT91_CAST(AT91_REG *) 0x00000128) // (AIC_ICCR) Interrupt Clear Command Register +#define AIC_ISCR (AT91_CAST(AT91_REG *) 0x0000012C) // (AIC_ISCR) Interrupt Set Command Register +#define AIC_EOICR (AT91_CAST(AT91_REG *) 0x00000130) // (AIC_EOICR) End of Interrupt Command Register +#define AIC_SPU (AT91_CAST(AT91_REG *) 0x00000134) // (AIC_SPU) Spurious Vector Register +#define AIC_DCR (AT91_CAST(AT91_REG *) 0x00000138) // (AIC_DCR) Debug Control Register (Protect) +#define AIC_FFER (AT91_CAST(AT91_REG *) 0x00000140) // (AIC_FFER) Fast Forcing Enable Register +#define AIC_FFDR (AT91_CAST(AT91_REG *) 0x00000144) // (AIC_FFDR) Fast Forcing Disable Register +#define AIC_FFSR (AT91_CAST(AT91_REG *) 0x00000148) // (AIC_FFSR) Fast Forcing Status Register #endif // -------- AIC_SMR : (AIC Offset: 0x0) Control Register -------- #define AT91C_AIC_PRIOR (0x7 << 0) // (AIC) Priority Level -#define AT91C_AIC_PRIOR_LOWEST (0x0) // (AIC) Lowest priority level -#define AT91C_AIC_PRIOR_HIGHEST (0x7) // (AIC) Highest priority level +#define AT91C_AIC_PRIOR_LOWEST (0x0) // (AIC) Lowest priority level +#define AT91C_AIC_PRIOR_HIGHEST (0x7) // (AIC) Highest priority level #define AT91C_AIC_SRCTYPE (0x3 << 5) // (AIC) Interrupt Source Type -#define AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL (0x0 << 5) // (AIC) Internal Sources Code Label High-level Sensitive -#define AT91C_AIC_SRCTYPE_EXT_LOW_LEVEL (0x0 << 5) // (AIC) External Sources Code Label Low-level Sensitive -#define AT91C_AIC_SRCTYPE_INT_POSITIVE_EDGE (0x1 << 5) // (AIC) Internal Sources Code Label Positive Edge triggered -#define AT91C_AIC_SRCTYPE_EXT_NEGATIVE_EDGE (0x1 << 5) // (AIC) External Sources Code Label Negative Edge triggered -#define AT91C_AIC_SRCTYPE_HIGH_LEVEL (0x2 << 5) // (AIC) Internal Or External Sources Code Label High-level Sensitive -#define AT91C_AIC_SRCTYPE_POSITIVE_EDGE (0x3 << 5) // (AIC) Internal Or External Sources Code Label Positive Edge triggered +#define AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL (0x0 << 5) // (AIC) Internal Sources Code Label High-level Sensitive +#define AT91C_AIC_SRCTYPE_EXT_LOW_LEVEL (0x0 << 5) // (AIC) External Sources Code Label Low-level Sensitive +#define AT91C_AIC_SRCTYPE_INT_POSITIVE_EDGE (0x1 << 5) // (AIC) Internal Sources Code Label Positive Edge triggered +#define AT91C_AIC_SRCTYPE_EXT_NEGATIVE_EDGE (0x1 << 5) // (AIC) External Sources Code Label Negative Edge triggered +#define AT91C_AIC_SRCTYPE_HIGH_LEVEL (0x2 << 5) // (AIC) Internal Or External Sources Code Label High-level Sensitive +#define AT91C_AIC_SRCTYPE_POSITIVE_EDGE (0x3 << 5) // (AIC) Internal Or External Sources Code Label Positive Edge triggered // -------- AIC_CISR : (AIC Offset: 0x114) AIC Core Interrupt Status Register -------- #define AT91C_AIC_NFIQ (0x1 << 0) // (AIC) NFIQ Status #define AT91C_AIC_NIRQ (0x1 << 1) // (AIC) NIRQ Status @@ -266,28 +266,28 @@ typedef struct _AT91S_AIC { // ***************************************************************************** #ifndef __ASSEMBLY__ typedef struct _AT91S_PDC { - AT91_REG PDC_RPR; // Receive Pointer Register - AT91_REG PDC_RCR; // Receive Counter Register - AT91_REG PDC_TPR; // Transmit Pointer Register - AT91_REG PDC_TCR; // Transmit Counter Register - AT91_REG PDC_RNPR; // Receive Next Pointer Register - AT91_REG PDC_RNCR; // Receive Next Counter Register - AT91_REG PDC_TNPR; // Transmit Next Pointer Register - AT91_REG PDC_TNCR; // Transmit Next Counter Register - AT91_REG PDC_PTCR; // PDC Transfer Control Register - AT91_REG PDC_PTSR; // PDC Transfer Status Register + AT91_REG PDC_RPR; // Receive Pointer Register + AT91_REG PDC_RCR; // Receive Counter Register + AT91_REG PDC_TPR; // Transmit Pointer Register + AT91_REG PDC_TCR; // Transmit Counter Register + AT91_REG PDC_RNPR; // Receive Next Pointer Register + AT91_REG PDC_RNCR; // Receive Next Counter Register + AT91_REG PDC_TNPR; // Transmit Next Pointer Register + AT91_REG PDC_TNCR; // Transmit Next Counter Register + AT91_REG PDC_PTCR; // PDC Transfer Control Register + AT91_REG PDC_PTSR; // PDC Transfer Status Register } AT91S_PDC, *AT91PS_PDC; #else -#define PDC_RPR (AT91_CAST(AT91_REG *) 0x00000000) // (PDC_RPR) Receive Pointer Register -#define PDC_RCR (AT91_CAST(AT91_REG *) 0x00000004) // (PDC_RCR) Receive Counter Register -#define PDC_TPR (AT91_CAST(AT91_REG *) 0x00000008) // (PDC_TPR) Transmit Pointer Register -#define PDC_TCR (AT91_CAST(AT91_REG *) 0x0000000C) // (PDC_TCR) Transmit Counter Register -#define PDC_RNPR (AT91_CAST(AT91_REG *) 0x00000010) // (PDC_RNPR) Receive Next Pointer Register -#define PDC_RNCR (AT91_CAST(AT91_REG *) 0x00000014) // (PDC_RNCR) Receive Next Counter Register -#define PDC_TNPR (AT91_CAST(AT91_REG *) 0x00000018) // (PDC_TNPR) Transmit Next Pointer Register -#define PDC_TNCR (AT91_CAST(AT91_REG *) 0x0000001C) // (PDC_TNCR) Transmit Next Counter Register -#define PDC_PTCR (AT91_CAST(AT91_REG *) 0x00000020) // (PDC_PTCR) PDC Transfer Control Register -#define PDC_PTSR (AT91_CAST(AT91_REG *) 0x00000024) // (PDC_PTSR) PDC Transfer Status Register +#define PDC_RPR (AT91_CAST(AT91_REG *) 0x00000000) // (PDC_RPR) Receive Pointer Register +#define PDC_RCR (AT91_CAST(AT91_REG *) 0x00000004) // (PDC_RCR) Receive Counter Register +#define PDC_TPR (AT91_CAST(AT91_REG *) 0x00000008) // (PDC_TPR) Transmit Pointer Register +#define PDC_TCR (AT91_CAST(AT91_REG *) 0x0000000C) // (PDC_TCR) Transmit Counter Register +#define PDC_RNPR (AT91_CAST(AT91_REG *) 0x00000010) // (PDC_RNPR) Receive Next Pointer Register +#define PDC_RNCR (AT91_CAST(AT91_REG *) 0x00000014) // (PDC_RNCR) Receive Next Counter Register +#define PDC_TNPR (AT91_CAST(AT91_REG *) 0x00000018) // (PDC_TNPR) Transmit Next Pointer Register +#define PDC_TNCR (AT91_CAST(AT91_REG *) 0x0000001C) // (PDC_TNCR) Transmit Next Counter Register +#define PDC_PTCR (AT91_CAST(AT91_REG *) 0x00000020) // (PDC_PTCR) PDC Transfer Control Register +#define PDC_PTSR (AT91_CAST(AT91_REG *) 0x00000024) // (PDC_PTSR) PDC Transfer Status Register #endif // -------- PDC_PTCR : (PDC Offset: 0x20) PDC Transfer Control Register -------- @@ -302,44 +302,44 @@ typedef struct _AT91S_PDC { // ***************************************************************************** #ifndef __ASSEMBLY__ typedef struct _AT91S_DBGU { - AT91_REG DBGU_CR; // Control Register - AT91_REG DBGU_MR; // Mode Register - AT91_REG DBGU_IER; // Interrupt Enable Register - AT91_REG DBGU_IDR; // Interrupt Disable Register - AT91_REG DBGU_IMR; // Interrupt Mask Register - AT91_REG DBGU_CSR; // Channel Status Register - AT91_REG DBGU_RHR; // Receiver Holding Register - AT91_REG DBGU_THR; // Transmitter Holding Register - AT91_REG DBGU_BRGR; // Baud Rate Generator Register - AT91_REG Reserved0[7]; // - AT91_REG DBGU_CIDR; // Chip ID Register - AT91_REG DBGU_EXID; // Chip ID Extension Register - AT91_REG DBGU_FNTR; // Force NTRST Register - AT91_REG Reserved1[45]; // - AT91_REG DBGU_RPR; // Receive Pointer Register - AT91_REG DBGU_RCR; // Receive Counter Register - AT91_REG DBGU_TPR; // Transmit Pointer Register - AT91_REG DBGU_TCR; // Transmit Counter Register - AT91_REG DBGU_RNPR; // Receive Next Pointer Register - AT91_REG DBGU_RNCR; // Receive Next Counter Register - AT91_REG DBGU_TNPR; // Transmit Next Pointer Register - AT91_REG DBGU_TNCR; // Transmit Next Counter Register - AT91_REG DBGU_PTCR; // PDC Transfer Control Register - AT91_REG DBGU_PTSR; // PDC Transfer Status Register + AT91_REG DBGU_CR; // Control Register + AT91_REG DBGU_MR; // Mode Register + AT91_REG DBGU_IER; // Interrupt Enable Register + AT91_REG DBGU_IDR; // Interrupt Disable Register + AT91_REG DBGU_IMR; // Interrupt Mask Register + AT91_REG DBGU_CSR; // Channel Status Register + AT91_REG DBGU_RHR; // Receiver Holding Register + AT91_REG DBGU_THR; // Transmitter Holding Register + AT91_REG DBGU_BRGR; // Baud Rate Generator Register + AT91_REG Reserved0[7]; // + AT91_REG DBGU_CIDR; // Chip ID Register + AT91_REG DBGU_EXID; // Chip ID Extension Register + AT91_REG DBGU_FNTR; // Force NTRST Register + AT91_REG Reserved1[45]; // + AT91_REG DBGU_RPR; // Receive Pointer Register + AT91_REG DBGU_RCR; // Receive Counter Register + AT91_REG DBGU_TPR; // Transmit Pointer Register + AT91_REG DBGU_TCR; // Transmit Counter Register + AT91_REG DBGU_RNPR; // Receive Next Pointer Register + AT91_REG DBGU_RNCR; // Receive Next Counter Register + AT91_REG DBGU_TNPR; // Transmit Next Pointer Register + AT91_REG DBGU_TNCR; // Transmit Next Counter Register + AT91_REG DBGU_PTCR; // PDC Transfer Control Register + AT91_REG DBGU_PTSR; // PDC Transfer Status Register } AT91S_DBGU, *AT91PS_DBGU; #else -#define DBGU_CR (AT91_CAST(AT91_REG *) 0x00000000) // (DBGU_CR) Control Register -#define DBGU_MR (AT91_CAST(AT91_REG *) 0x00000004) // (DBGU_MR) Mode Register -#define DBGU_IER (AT91_CAST(AT91_REG *) 0x00000008) // (DBGU_IER) Interrupt Enable Register -#define DBGU_IDR (AT91_CAST(AT91_REG *) 0x0000000C) // (DBGU_IDR) Interrupt Disable Register -#define DBGU_IMR (AT91_CAST(AT91_REG *) 0x00000010) // (DBGU_IMR) Interrupt Mask Register -#define DBGU_CSR (AT91_CAST(AT91_REG *) 0x00000014) // (DBGU_CSR) Channel Status Register -#define DBGU_RHR (AT91_CAST(AT91_REG *) 0x00000018) // (DBGU_RHR) Receiver Holding Register -#define DBGU_THR (AT91_CAST(AT91_REG *) 0x0000001C) // (DBGU_THR) Transmitter Holding Register -#define DBGU_BRGR (AT91_CAST(AT91_REG *) 0x00000020) // (DBGU_BRGR) Baud Rate Generator Register -//#define DBGU_CIDR (AT91_CAST(AT91_REG *) 0x00000040) // (DBGU_CIDR) Chip ID Register -#define DBGU_EXID (AT91_CAST(AT91_REG *) 0x00000044) // (DBGU_EXID) Chip ID Extension Register -#define DBGU_FNTR (AT91_CAST(AT91_REG *) 0x00000048) // (DBGU_FNTR) Force NTRST Register +#define DBGU_CR (AT91_CAST(AT91_REG *) 0x00000000) // (DBGU_CR) Control Register +#define DBGU_MR (AT91_CAST(AT91_REG *) 0x00000004) // (DBGU_MR) Mode Register +#define DBGU_IER (AT91_CAST(AT91_REG *) 0x00000008) // (DBGU_IER) Interrupt Enable Register +#define DBGU_IDR (AT91_CAST(AT91_REG *) 0x0000000C) // (DBGU_IDR) Interrupt Disable Register +#define DBGU_IMR (AT91_CAST(AT91_REG *) 0x00000010) // (DBGU_IMR) Interrupt Mask Register +#define DBGU_CSR (AT91_CAST(AT91_REG *) 0x00000014) // (DBGU_CSR) Channel Status Register +#define DBGU_RHR (AT91_CAST(AT91_REG *) 0x00000018) // (DBGU_RHR) Receiver Holding Register +#define DBGU_THR (AT91_CAST(AT91_REG *) 0x0000001C) // (DBGU_THR) Transmitter Holding Register +#define DBGU_BRGR (AT91_CAST(AT91_REG *) 0x00000020) // (DBGU_BRGR) Baud Rate Generator Register +//#define DBGU_CIDR (AT91_CAST(AT91_REG *) 0x00000040) // (DBGU_CIDR) Chip ID Register +#define DBGU_EXID (AT91_CAST(AT91_REG *) 0x00000044) // (DBGU_EXID) Chip ID Extension Register +#define DBGU_FNTR (AT91_CAST(AT91_REG *) 0x00000048) // (DBGU_FNTR) Force NTRST Register #endif // -------- DBGU_CR : (DBGU Offset: 0x0) Debug Unit Control Register -------- @@ -352,17 +352,17 @@ typedef struct _AT91S_DBGU { #define AT91C_US_RSTSTA (0x1 << 8) // (DBGU) Reset Status Bits // -------- DBGU_MR : (DBGU Offset: 0x4) Debug Unit Mode Register -------- #define AT91C_US_PAR (0x7 << 9) // (DBGU) Parity type -#define AT91C_US_PAR_EVEN (0x0 << 9) // (DBGU) Even Parity -#define AT91C_US_PAR_ODD (0x1 << 9) // (DBGU) Odd Parity -#define AT91C_US_PAR_SPACE (0x2 << 9) // (DBGU) Parity forced to 0 (Space) -#define AT91C_US_PAR_MARK (0x3 << 9) // (DBGU) Parity forced to 1 (Mark) -#define AT91C_US_PAR_NONE (0x4 << 9) // (DBGU) No Parity -#define AT91C_US_PAR_MULTI_DROP (0x6 << 9) // (DBGU) Multi-drop mode +#define AT91C_US_PAR_EVEN (0x0 << 9) // (DBGU) Even Parity +#define AT91C_US_PAR_ODD (0x1 << 9) // (DBGU) Odd Parity +#define AT91C_US_PAR_SPACE (0x2 << 9) // (DBGU) Parity forced to 0 (Space) +#define AT91C_US_PAR_MARK (0x3 << 9) // (DBGU) Parity forced to 1 (Mark) +#define AT91C_US_PAR_NONE (0x4 << 9) // (DBGU) No Parity +#define AT91C_US_PAR_MULTI_DROP (0x6 << 9) // (DBGU) Multi-drop mode #define AT91C_US_CHMODE (0x3 << 14) // (DBGU) Channel Mode -#define AT91C_US_CHMODE_NORMAL (0x0 << 14) // (DBGU) Normal Mode: The USART channel operates as an RX/TX USART. -#define AT91C_US_CHMODE_AUTO (0x1 << 14) // (DBGU) Automatic Echo: Receiver Data Input is connected to the TXD pin. -#define AT91C_US_CHMODE_LOCAL (0x2 << 14) // (DBGU) Local Loopback: Transmitter Output Signal is connected to Receiver Input Signal. -#define AT91C_US_CHMODE_REMOTE (0x3 << 14) // (DBGU) Remote Loopback: RXD pin is internally connected to TXD pin. +#define AT91C_US_CHMODE_NORMAL (0x0 << 14) // (DBGU) Normal Mode: The USART channel operates as an RX/TX USART. +#define AT91C_US_CHMODE_AUTO (0x1 << 14) // (DBGU) Automatic Echo: Receiver Data Input is connected to the TXD pin. +#define AT91C_US_CHMODE_LOCAL (0x2 << 14) // (DBGU) Local Loopback: Transmitter Output Signal is connected to Receiver Input Signal. +#define AT91C_US_CHMODE_REMOTE (0x3 << 14) // (DBGU) Remote Loopback: RXD pin is internally connected to TXD pin. // -------- DBGU_IER : (DBGU Offset: 0x8) Debug Unit Interrupt Enable Register -------- #define AT91C_US_RXRDY (0x1 << 0) // (DBGU) RXRDY Interrupt #define AT91C_US_TXRDY (0x1 << 1) // (DBGU) TXRDY Interrupt @@ -387,72 +387,72 @@ typedef struct _AT91S_DBGU { // ***************************************************************************** #ifndef __ASSEMBLY__ typedef struct _AT91S_PIO { - AT91_REG PIO_PER; // PIO Enable Register - AT91_REG PIO_PDR; // PIO Disable Register - AT91_REG PIO_PSR; // PIO Status Register - AT91_REG Reserved0[1]; // - AT91_REG PIO_OER; // Output Enable Register - AT91_REG PIO_ODR; // Output Disable Registerr - AT91_REG PIO_OSR; // Output Status Register - AT91_REG Reserved1[1]; // - AT91_REG PIO_IFER; // Input Filter Enable Register - AT91_REG PIO_IFDR; // Input Filter Disable Register - AT91_REG PIO_IFSR; // Input Filter Status Register - AT91_REG Reserved2[1]; // - AT91_REG PIO_SODR; // Set Output Data Register - AT91_REG PIO_CODR; // Clear Output Data Register - AT91_REG PIO_ODSR; // Output Data Status Register - AT91_REG PIO_PDSR; // Pin Data Status Register - AT91_REG PIO_IER; // Interrupt Enable Register - AT91_REG PIO_IDR; // Interrupt Disable Register - AT91_REG PIO_IMR; // Interrupt Mask Register - AT91_REG PIO_ISR; // Interrupt Status Register - AT91_REG PIO_MDER; // Multi-driver Enable Register - AT91_REG PIO_MDDR; // Multi-driver Disable Register - AT91_REG PIO_MDSR; // Multi-driver Status Register - AT91_REG Reserved3[1]; // - AT91_REG PIO_PPUDR; // Pull-up Disable Register - AT91_REG PIO_PPUER; // Pull-up Enable Register - AT91_REG PIO_PPUSR; // Pull-up Status Register - AT91_REG Reserved4[1]; // - AT91_REG PIO_ASR; // Select A Register - AT91_REG PIO_BSR; // Select B Register - AT91_REG PIO_ABSR; // AB Select Status Register - AT91_REG Reserved5[9]; // - AT91_REG PIO_OWER; // Output Write Enable Register - AT91_REG PIO_OWDR; // Output Write Disable Register - AT91_REG PIO_OWSR; // Output Write Status Register + AT91_REG PIO_PER; // PIO Enable Register + AT91_REG PIO_PDR; // PIO Disable Register + AT91_REG PIO_PSR; // PIO Status Register + AT91_REG Reserved0[1]; // + AT91_REG PIO_OER; // Output Enable Register + AT91_REG PIO_ODR; // Output Disable Registerr + AT91_REG PIO_OSR; // Output Status Register + AT91_REG Reserved1[1]; // + AT91_REG PIO_IFER; // Input Filter Enable Register + AT91_REG PIO_IFDR; // Input Filter Disable Register + AT91_REG PIO_IFSR; // Input Filter Status Register + AT91_REG Reserved2[1]; // + AT91_REG PIO_SODR; // Set Output Data Register + AT91_REG PIO_CODR; // Clear Output Data Register + AT91_REG PIO_ODSR; // Output Data Status Register + AT91_REG PIO_PDSR; // Pin Data Status Register + AT91_REG PIO_IER; // Interrupt Enable Register + AT91_REG PIO_IDR; // Interrupt Disable Register + AT91_REG PIO_IMR; // Interrupt Mask Register + AT91_REG PIO_ISR; // Interrupt Status Register + AT91_REG PIO_MDER; // Multi-driver Enable Register + AT91_REG PIO_MDDR; // Multi-driver Disable Register + AT91_REG PIO_MDSR; // Multi-driver Status Register + AT91_REG Reserved3[1]; // + AT91_REG PIO_PPUDR; // Pull-up Disable Register + AT91_REG PIO_PPUER; // Pull-up Enable Register + AT91_REG PIO_PPUSR; // Pull-up Status Register + AT91_REG Reserved4[1]; // + AT91_REG PIO_ASR; // Select A Register + AT91_REG PIO_BSR; // Select B Register + AT91_REG PIO_ABSR; // AB Select Status Register + AT91_REG Reserved5[9]; // + AT91_REG PIO_OWER; // Output Write Enable Register + AT91_REG PIO_OWDR; // Output Write Disable Register + AT91_REG PIO_OWSR; // Output Write Status Register } AT91S_PIO, *AT91PS_PIO; #else -#define PIO_PER (AT91_CAST(AT91_REG *) 0x00000000) // (PIO_PER) PIO Enable Register -#define PIO_PDR (AT91_CAST(AT91_REG *) 0x00000004) // (PIO_PDR) PIO Disable Register -#define PIO_PSR (AT91_CAST(AT91_REG *) 0x00000008) // (PIO_PSR) PIO Status Register -#define PIO_OER (AT91_CAST(AT91_REG *) 0x00000010) // (PIO_OER) Output Enable Register -#define PIO_ODR (AT91_CAST(AT91_REG *) 0x00000014) // (PIO_ODR) Output Disable Register -#define PIO_OSR (AT91_CAST(AT91_REG *) 0x00000018) // (PIO_OSR) Output Status Register -#define PIO_IFER (AT91_CAST(AT91_REG *) 0x00000020) // (PIO_IFER) Input Filter Enable Register -#define PIO_IFDR (AT91_CAST(AT91_REG *) 0x00000024) // (PIO_IFDR) Input Filter Disable Register -#define PIO_IFSR (AT91_CAST(AT91_REG *) 0x00000028) // (PIO_IFSR) Input Filter Status Register -#define PIO_SODR (AT91_CAST(AT91_REG *) 0x00000030) // (PIO_SODR) Set Output Data Register -#define PIO_CODR (AT91_CAST(AT91_REG *) 0x00000034) // (PIO_CODR) Clear Output Data Register -#define PIO_ODSR (AT91_CAST(AT91_REG *) 0x00000038) // (PIO_ODSR) Output Data Status Register -#define PIO_PDSR (AT91_CAST(AT91_REG *) 0x0000003C) // (PIO_PDSR) Pin Data Status Register -#define PIO_IER (AT91_CAST(AT91_REG *) 0x00000040) // (PIO_IER) Interrupt Enable Register -#define PIO_IDR (AT91_CAST(AT91_REG *) 0x00000044) // (PIO_IDR) Interrupt Disable Register -#define PIO_IMR (AT91_CAST(AT91_REG *) 0x00000048) // (PIO_IMR) Interrupt Mask Register -#define PIO_ISR (AT91_CAST(AT91_REG *) 0x0000004C) // (PIO_ISR) Interrupt Status Register -#define PIO_MDER (AT91_CAST(AT91_REG *) 0x00000050) // (PIO_MDER) Multi-driver Enable Register -#define PIO_MDDR (AT91_CAST(AT91_REG *) 0x00000054) // (PIO_MDDR) Multi-driver Disable Register -#define PIO_MDSR (AT91_CAST(AT91_REG *) 0x00000058) // (PIO_MDSR) Multi-driver Status Register -#define PIO_PPUDR (AT91_CAST(AT91_REG *) 0x00000060) // (PIO_PPUDR) Pull-up Disable Register -#define PIO_PPUER (AT91_CAST(AT91_REG *) 0x00000064) // (PIO_PPUER) Pull-up Enable Register -#define PIO_PPUSR (AT91_CAST(AT91_REG *) 0x00000068) // (PIO_PPUSR) Pull-up Status Register -#define PIO_ASR (AT91_CAST(AT91_REG *) 0x00000070) // (PIO_ASR) Select A Register -#define PIO_BSR (AT91_CAST(AT91_REG *) 0x00000074) // (PIO_BSR) Select B Register -#define PIO_ABSR (AT91_CAST(AT91_REG *) 0x00000078) // (PIO_ABSR) AB Select Status Register -#define PIO_OWER (AT91_CAST(AT91_REG *) 0x000000A0) // (PIO_OWER) Output Write Enable Register -#define PIO_OWDR (AT91_CAST(AT91_REG *) 0x000000A4) // (PIO_OWDR) Output Write Disable Register -#define PIO_OWSR (AT91_CAST(AT91_REG *) 0x000000A8) // (PIO_OWSR) Output Write Status Register +#define PIO_PER (AT91_CAST(AT91_REG *) 0x00000000) // (PIO_PER) PIO Enable Register +#define PIO_PDR (AT91_CAST(AT91_REG *) 0x00000004) // (PIO_PDR) PIO Disable Register +#define PIO_PSR (AT91_CAST(AT91_REG *) 0x00000008) // (PIO_PSR) PIO Status Register +#define PIO_OER (AT91_CAST(AT91_REG *) 0x00000010) // (PIO_OER) Output Enable Register +#define PIO_ODR (AT91_CAST(AT91_REG *) 0x00000014) // (PIO_ODR) Output Disable Register +#define PIO_OSR (AT91_CAST(AT91_REG *) 0x00000018) // (PIO_OSR) Output Status Register +#define PIO_IFER (AT91_CAST(AT91_REG *) 0x00000020) // (PIO_IFER) Input Filter Enable Register +#define PIO_IFDR (AT91_CAST(AT91_REG *) 0x00000024) // (PIO_IFDR) Input Filter Disable Register +#define PIO_IFSR (AT91_CAST(AT91_REG *) 0x00000028) // (PIO_IFSR) Input Filter Status Register +#define PIO_SODR (AT91_CAST(AT91_REG *) 0x00000030) // (PIO_SODR) Set Output Data Register +#define PIO_CODR (AT91_CAST(AT91_REG *) 0x00000034) // (PIO_CODR) Clear Output Data Register +#define PIO_ODSR (AT91_CAST(AT91_REG *) 0x00000038) // (PIO_ODSR) Output Data Status Register +#define PIO_PDSR (AT91_CAST(AT91_REG *) 0x0000003C) // (PIO_PDSR) Pin Data Status Register +#define PIO_IER (AT91_CAST(AT91_REG *) 0x00000040) // (PIO_IER) Interrupt Enable Register +#define PIO_IDR (AT91_CAST(AT91_REG *) 0x00000044) // (PIO_IDR) Interrupt Disable Register +#define PIO_IMR (AT91_CAST(AT91_REG *) 0x00000048) // (PIO_IMR) Interrupt Mask Register +#define PIO_ISR (AT91_CAST(AT91_REG *) 0x0000004C) // (PIO_ISR) Interrupt Status Register +#define PIO_MDER (AT91_CAST(AT91_REG *) 0x00000050) // (PIO_MDER) Multi-driver Enable Register +#define PIO_MDDR (AT91_CAST(AT91_REG *) 0x00000054) // (PIO_MDDR) Multi-driver Disable Register +#define PIO_MDSR (AT91_CAST(AT91_REG *) 0x00000058) // (PIO_MDSR) Multi-driver Status Register +#define PIO_PPUDR (AT91_CAST(AT91_REG *) 0x00000060) // (PIO_PPUDR) Pull-up Disable Register +#define PIO_PPUER (AT91_CAST(AT91_REG *) 0x00000064) // (PIO_PPUER) Pull-up Enable Register +#define PIO_PPUSR (AT91_CAST(AT91_REG *) 0x00000068) // (PIO_PPUSR) Pull-up Status Register +#define PIO_ASR (AT91_CAST(AT91_REG *) 0x00000070) // (PIO_ASR) Select A Register +#define PIO_BSR (AT91_CAST(AT91_REG *) 0x00000074) // (PIO_BSR) Select B Register +#define PIO_ABSR (AT91_CAST(AT91_REG *) 0x00000078) // (PIO_ABSR) AB Select Status Register +#define PIO_OWER (AT91_CAST(AT91_REG *) 0x000000A0) // (PIO_OWER) Output Write Enable Register +#define PIO_OWDR (AT91_CAST(AT91_REG *) 0x000000A4) // (PIO_OWDR) Output Write Disable Register +#define PIO_OWSR (AT91_CAST(AT91_REG *) 0x000000A8) // (PIO_OWSR) Output Write Status Register #endif @@ -461,15 +461,15 @@ typedef struct _AT91S_PIO { // ***************************************************************************** #ifndef __ASSEMBLY__ typedef struct _AT91S_CKGR { - AT91_REG CKGR_MOR; // Main Oscillator Register - AT91_REG CKGR_MCFR; // Main Clock Frequency Register - AT91_REG Reserved0[1]; // - AT91_REG CKGR_PLLR; // PLL Register + AT91_REG CKGR_MOR; // Main Oscillator Register + AT91_REG CKGR_MCFR; // Main Clock Frequency Register + AT91_REG Reserved0[1]; // + AT91_REG CKGR_PLLR; // PLL Register } AT91S_CKGR, *AT91PS_CKGR; #else -#define CKGR_MOR (AT91_CAST(AT91_REG *) 0x00000000) // (CKGR_MOR) Main Oscillator Register -#define CKGR_MCFR (AT91_CAST(AT91_REG *) 0x00000004) // (CKGR_MCFR) Main Clock Frequency Register -#define CKGR_PLLR (AT91_CAST(AT91_REG *) 0x0000000C) // (CKGR_PLLR) PLL Register +#define CKGR_MOR (AT91_CAST(AT91_REG *) 0x00000000) // (CKGR_MOR) Main Oscillator Register +#define CKGR_MCFR (AT91_CAST(AT91_REG *) 0x00000004) // (CKGR_MCFR) Main Clock Frequency Register +#define CKGR_PLLR (AT91_CAST(AT91_REG *) 0x0000000C) // (CKGR_PLLR) PLL Register #endif // -------- CKGR_MOR : (CKGR Offset: 0x0) Main Oscillator Register -------- @@ -481,59 +481,59 @@ typedef struct _AT91S_CKGR { #define AT91C_CKGR_MAINRDY (0x1 << 16) // (CKGR) Main Clock Ready // -------- CKGR_PLLR : (CKGR Offset: 0xc) PLL B Register -------- #define AT91C_CKGR_DIV (0xFF << 0) // (CKGR) Divider Selected -#define AT91C_CKGR_DIV_0 (0x0) // (CKGR) Divider output is 0 -#define AT91C_CKGR_DIV_BYPASS (0x1) // (CKGR) Divider is bypassed +#define AT91C_CKGR_DIV_0 (0x0) // (CKGR) Divider output is 0 +#define AT91C_CKGR_DIV_BYPASS (0x1) // (CKGR) Divider is bypassed #define AT91C_CKGR_PLLCOUNT (0x3F << 8) // (CKGR) PLL Counter #define AT91C_CKGR_OUT (0x3 << 14) // (CKGR) PLL Output Frequency Range -#define AT91C_CKGR_OUT_0 (0x0 << 14) // (CKGR) Please refer to the PLL datasheet -#define AT91C_CKGR_OUT_1 (0x1 << 14) // (CKGR) Please refer to the PLL datasheet -#define AT91C_CKGR_OUT_2 (0x2 << 14) // (CKGR) Please refer to the PLL datasheet -#define AT91C_CKGR_OUT_3 (0x3 << 14) // (CKGR) Please refer to the PLL datasheet +#define AT91C_CKGR_OUT_0 (0x0 << 14) // (CKGR) Please refer to the PLL datasheet +#define AT91C_CKGR_OUT_1 (0x1 << 14) // (CKGR) Please refer to the PLL datasheet +#define AT91C_CKGR_OUT_2 (0x2 << 14) // (CKGR) Please refer to the PLL datasheet +#define AT91C_CKGR_OUT_3 (0x3 << 14) // (CKGR) Please refer to the PLL datasheet #define AT91C_CKGR_MUL (0x7FF << 16) // (CKGR) PLL Multiplier #define AT91C_CKGR_USBDIV (0x3 << 28) // (CKGR) Divider for USB Clocks -#define AT91C_CKGR_USBDIV_0 (0x0 << 28) // (CKGR) Divider output is PLL clock output -#define AT91C_CKGR_USBDIV_1 (0x1 << 28) // (CKGR) Divider output is PLL clock output divided by 2 -#define AT91C_CKGR_USBDIV_2 (0x2 << 28) // (CKGR) Divider output is PLL clock output divided by 4 +#define AT91C_CKGR_USBDIV_0 (0x0 << 28) // (CKGR) Divider output is PLL clock output +#define AT91C_CKGR_USBDIV_1 (0x1 << 28) // (CKGR) Divider output is PLL clock output divided by 2 +#define AT91C_CKGR_USBDIV_2 (0x2 << 28) // (CKGR) Divider output is PLL clock output divided by 4 // ***************************************************************************** // SOFTWARE API DEFINITION FOR Power Management Controler // ***************************************************************************** #ifndef __ASSEMBLY__ typedef struct _AT91S_PMC { - AT91_REG PMC_SCER; // System Clock Enable Register - AT91_REG PMC_SCDR; // System Clock Disable Register - AT91_REG PMC_SCSR; // System Clock Status Register - AT91_REG Reserved0[1]; // - AT91_REG PMC_PCER; // Peripheral Clock Enable Register - AT91_REG PMC_PCDR; // Peripheral Clock Disable Register - AT91_REG PMC_PCSR; // Peripheral Clock Status Register - AT91_REG Reserved1[1]; // - AT91_REG PMC_MOR; // Main Oscillator Register - AT91_REG PMC_MCFR; // Main Clock Frequency Register - AT91_REG Reserved2[1]; // - AT91_REG PMC_PLLR; // PLL Register - AT91_REG PMC_MCKR; // Master Clock Register - AT91_REG Reserved3[3]; // - AT91_REG PMC_PCKR[3]; // Programmable Clock Register - AT91_REG Reserved4[5]; // - AT91_REG PMC_IER; // Interrupt Enable Register - AT91_REG PMC_IDR; // Interrupt Disable Register - AT91_REG PMC_SR; // Status Register - AT91_REG PMC_IMR; // Interrupt Mask Register + AT91_REG PMC_SCER; // System Clock Enable Register + AT91_REG PMC_SCDR; // System Clock Disable Register + AT91_REG PMC_SCSR; // System Clock Status Register + AT91_REG Reserved0[1]; // + AT91_REG PMC_PCER; // Peripheral Clock Enable Register + AT91_REG PMC_PCDR; // Peripheral Clock Disable Register + AT91_REG PMC_PCSR; // Peripheral Clock Status Register + AT91_REG Reserved1[1]; // + AT91_REG PMC_MOR; // Main Oscillator Register + AT91_REG PMC_MCFR; // Main Clock Frequency Register + AT91_REG Reserved2[1]; // + AT91_REG PMC_PLLR; // PLL Register + AT91_REG PMC_MCKR; // Master Clock Register + AT91_REG Reserved3[3]; // + AT91_REG PMC_PCKR[3]; // Programmable Clock Register + AT91_REG Reserved4[5]; // + AT91_REG PMC_IER; // Interrupt Enable Register + AT91_REG PMC_IDR; // Interrupt Disable Register + AT91_REG PMC_SR; // Status Register + AT91_REG PMC_IMR; // Interrupt Mask Register } AT91S_PMC, *AT91PS_PMC; #else -#define PMC_SCER (AT91_CAST(AT91_REG *) 0x00000000) // (PMC_SCER) System Clock Enable Register -#define PMC_SCDR (AT91_CAST(AT91_REG *) 0x00000004) // (PMC_SCDR) System Clock Disable Register -#define PMC_SCSR (AT91_CAST(AT91_REG *) 0x00000008) // (PMC_SCSR) System Clock Status Register -#define PMC_PCER (AT91_CAST(AT91_REG *) 0x00000010) // (PMC_PCER) Peripheral Clock Enable Register -#define PMC_PCDR (AT91_CAST(AT91_REG *) 0x00000014) // (PMC_PCDR) Peripheral Clock Disable Register -#define PMC_PCSR (AT91_CAST(AT91_REG *) 0x00000018) // (PMC_PCSR) Peripheral Clock Status Register -#define PMC_MCKR (AT91_CAST(AT91_REG *) 0x00000030) // (PMC_MCKR) Master Clock Register -#define PMC_PCKR (AT91_CAST(AT91_REG *) 0x00000040) // (PMC_PCKR) Programmable Clock Register -#define PMC_IER (AT91_CAST(AT91_REG *) 0x00000060) // (PMC_IER) Interrupt Enable Register -#define PMC_IDR (AT91_CAST(AT91_REG *) 0x00000064) // (PMC_IDR) Interrupt Disable Register -#define PMC_SR (AT91_CAST(AT91_REG *) 0x00000068) // (PMC_SR) Status Register -#define PMC_IMR (AT91_CAST(AT91_REG *) 0x0000006C) // (PMC_IMR) Interrupt Mask Register +#define PMC_SCER (AT91_CAST(AT91_REG *) 0x00000000) // (PMC_SCER) System Clock Enable Register +#define PMC_SCDR (AT91_CAST(AT91_REG *) 0x00000004) // (PMC_SCDR) System Clock Disable Register +#define PMC_SCSR (AT91_CAST(AT91_REG *) 0x00000008) // (PMC_SCSR) System Clock Status Register +#define PMC_PCER (AT91_CAST(AT91_REG *) 0x00000010) // (PMC_PCER) Peripheral Clock Enable Register +#define PMC_PCDR (AT91_CAST(AT91_REG *) 0x00000014) // (PMC_PCDR) Peripheral Clock Disable Register +#define PMC_PCSR (AT91_CAST(AT91_REG *) 0x00000018) // (PMC_PCSR) Peripheral Clock Status Register +#define PMC_MCKR (AT91_CAST(AT91_REG *) 0x00000030) // (PMC_MCKR) Master Clock Register +#define PMC_PCKR (AT91_CAST(AT91_REG *) 0x00000040) // (PMC_PCKR) Programmable Clock Register +#define PMC_IER (AT91_CAST(AT91_REG *) 0x00000060) // (PMC_IER) Interrupt Enable Register +#define PMC_IDR (AT91_CAST(AT91_REG *) 0x00000064) // (PMC_IDR) Interrupt Disable Register +#define PMC_SR (AT91_CAST(AT91_REG *) 0x00000068) // (PMC_SR) Status Register +#define PMC_IMR (AT91_CAST(AT91_REG *) 0x0000006C) // (PMC_IMR) Interrupt Mask Register #endif // -------- PMC_SCER : (PMC Offset: 0x0) System Clock Enable Register -------- @@ -549,17 +549,17 @@ typedef struct _AT91S_PMC { // -------- CKGR_PLLR : (PMC Offset: 0x2c) PLL B Register -------- // -------- PMC_MCKR : (PMC Offset: 0x30) Master Clock Register -------- #define AT91C_PMC_CSS (0x3 << 0) // (PMC) Programmable Clock Selection -#define AT91C_PMC_CSS_SLOW_CLK (0x0) // (PMC) Slow Clock is selected -#define AT91C_PMC_CSS_MAIN_CLK (0x1) // (PMC) Main Clock is selected -#define AT91C_PMC_CSS_PLL_CLK (0x3) // (PMC) Clock from PLL is selected +#define AT91C_PMC_CSS_SLOW_CLK (0x0) // (PMC) Slow Clock is selected +#define AT91C_PMC_CSS_MAIN_CLK (0x1) // (PMC) Main Clock is selected +#define AT91C_PMC_CSS_PLL_CLK (0x3) // (PMC) Clock from PLL is selected #define AT91C_PMC_PRES (0x7 << 2) // (PMC) Programmable Clock Prescaler -#define AT91C_PMC_PRES_CLK (0x0 << 2) // (PMC) Selected clock -#define AT91C_PMC_PRES_CLK_2 (0x1 << 2) // (PMC) Selected clock divided by 2 -#define AT91C_PMC_PRES_CLK_4 (0x2 << 2) // (PMC) Selected clock divided by 4 -#define AT91C_PMC_PRES_CLK_8 (0x3 << 2) // (PMC) Selected clock divided by 8 -#define AT91C_PMC_PRES_CLK_16 (0x4 << 2) // (PMC) Selected clock divided by 16 -#define AT91C_PMC_PRES_CLK_32 (0x5 << 2) // (PMC) Selected clock divided by 32 -#define AT91C_PMC_PRES_CLK_64 (0x6 << 2) // (PMC) Selected clock divided by 64 +#define AT91C_PMC_PRES_CLK (0x0 << 2) // (PMC) Selected clock +#define AT91C_PMC_PRES_CLK_2 (0x1 << 2) // (PMC) Selected clock divided by 2 +#define AT91C_PMC_PRES_CLK_4 (0x2 << 2) // (PMC) Selected clock divided by 4 +#define AT91C_PMC_PRES_CLK_8 (0x3 << 2) // (PMC) Selected clock divided by 8 +#define AT91C_PMC_PRES_CLK_16 (0x4 << 2) // (PMC) Selected clock divided by 16 +#define AT91C_PMC_PRES_CLK_32 (0x5 << 2) // (PMC) Selected clock divided by 32 +#define AT91C_PMC_PRES_CLK_64 (0x6 << 2) // (PMC) Selected clock divided by 64 // -------- PMC_PCKR : (PMC Offset: 0x40) Programmable Clock Register -------- // -------- PMC_IER : (PMC Offset: 0x60) PMC Interrupt Enable Register -------- #define AT91C_PMC_MOSCS (0x1 << 0) // (PMC) MOSC Status/Enable/Disable/Mask @@ -577,14 +577,14 @@ typedef struct _AT91S_PMC { // ***************************************************************************** #ifndef __ASSEMBLY__ typedef struct _AT91S_RSTC { - AT91_REG RSTC_RCR; // Reset Control Register - AT91_REG RSTC_RSR; // Reset Status Register - AT91_REG RSTC_RMR; // Reset Mode Register + AT91_REG RSTC_RCR; // Reset Control Register + AT91_REG RSTC_RSR; // Reset Status Register + AT91_REG RSTC_RMR; // Reset Mode Register } AT91S_RSTC, *AT91PS_RSTC; #else -#define RSTC_RCR (AT91_CAST(AT91_REG *) 0x00000000) // (RSTC_RCR) Reset Control Register -#define RSTC_RSR (AT91_CAST(AT91_REG *) 0x00000004) // (RSTC_RSR) Reset Status Register -#define RSTC_RMR (AT91_CAST(AT91_REG *) 0x00000008) // (RSTC_RMR) Reset Mode Register +#define RSTC_RCR (AT91_CAST(AT91_REG *) 0x00000000) // (RSTC_RCR) Reset Control Register +#define RSTC_RSR (AT91_CAST(AT91_REG *) 0x00000004) // (RSTC_RSR) Reset Status Register +#define RSTC_RMR (AT91_CAST(AT91_REG *) 0x00000008) // (RSTC_RMR) Reset Mode Register #endif // -------- RSTC_RCR : (RSTC Offset: 0x0) Reset Control Register -------- @@ -596,12 +596,12 @@ typedef struct _AT91S_RSTC { #define AT91C_RSTC_URSTS (0x1 << 0) // (RSTC) User Reset Status #define AT91C_RSTC_BODSTS (0x1 << 1) // (RSTC) Brownout Detection Status #define AT91C_RSTC_RSTTYP (0x7 << 8) // (RSTC) Reset Type -#define AT91C_RSTC_RSTTYP_POWERUP (0x0 << 8) // (RSTC) Power-up Reset. VDDCORE rising. -#define AT91C_RSTC_RSTTYP_WAKEUP (0x1 << 8) // (RSTC) WakeUp Reset. VDDCORE rising. -#define AT91C_RSTC_RSTTYP_WATCHDOG (0x2 << 8) // (RSTC) Watchdog Reset. Watchdog overflow occured. -#define AT91C_RSTC_RSTTYP_SOFTWARE (0x3 << 8) // (RSTC) Software Reset. Processor reset required by the software. -#define AT91C_RSTC_RSTTYP_USER (0x4 << 8) // (RSTC) User Reset. NRST pin detected low. -#define AT91C_RSTC_RSTTYP_BROWNOUT (0x5 << 8) // (RSTC) Brownout Reset occured. +#define AT91C_RSTC_RSTTYP_POWERUP (0x0 << 8) // (RSTC) Power-up Reset. VDDCORE rising. +#define AT91C_RSTC_RSTTYP_WAKEUP (0x1 << 8) // (RSTC) WakeUp Reset. VDDCORE rising. +#define AT91C_RSTC_RSTTYP_WATCHDOG (0x2 << 8) // (RSTC) Watchdog Reset. Watchdog overflow occured. +#define AT91C_RSTC_RSTTYP_SOFTWARE (0x3 << 8) // (RSTC) Software Reset. Processor reset required by the software. +#define AT91C_RSTC_RSTTYP_USER (0x4 << 8) // (RSTC) User Reset. NRST pin detected low. +#define AT91C_RSTC_RSTTYP_BROWNOUT (0x5 << 8) // (RSTC) Brownout Reset occured. #define AT91C_RSTC_NRSTL (0x1 << 16) // (RSTC) NRST pin level #define AT91C_RSTC_SRCMP (0x1 << 17) // (RSTC) Software Reset Command in Progress. // -------- RSTC_RMR : (RSTC Offset: 0x8) Reset Mode Register -------- @@ -615,16 +615,16 @@ typedef struct _AT91S_RSTC { // ***************************************************************************** #ifndef __ASSEMBLY__ typedef struct _AT91S_RTTC { - AT91_REG RTTC_RTMR; // Real-time Mode Register - AT91_REG RTTC_RTAR; // Real-time Alarm Register - AT91_REG RTTC_RTVR; // Real-time Value Register - AT91_REG RTTC_RTSR; // Real-time Status Register + AT91_REG RTTC_RTMR; // Real-time Mode Register + AT91_REG RTTC_RTAR; // Real-time Alarm Register + AT91_REG RTTC_RTVR; // Real-time Value Register + AT91_REG RTTC_RTSR; // Real-time Status Register } AT91S_RTTC, *AT91PS_RTTC; #else -#define RTTC_RTMR (AT91_CAST(AT91_REG *) 0x00000000) // (RTTC_RTMR) Real-time Mode Register -#define RTTC_RTAR (AT91_CAST(AT91_REG *) 0x00000004) // (RTTC_RTAR) Real-time Alarm Register -#define RTTC_RTVR (AT91_CAST(AT91_REG *) 0x00000008) // (RTTC_RTVR) Real-time Value Register -#define RTTC_RTSR (AT91_CAST(AT91_REG *) 0x0000000C) // (RTTC_RTSR) Real-time Status Register +#define RTTC_RTMR (AT91_CAST(AT91_REG *) 0x00000000) // (RTTC_RTMR) Real-time Mode Register +#define RTTC_RTAR (AT91_CAST(AT91_REG *) 0x00000004) // (RTTC_RTAR) Real-time Alarm Register +#define RTTC_RTVR (AT91_CAST(AT91_REG *) 0x00000008) // (RTTC_RTVR) Real-time Value Register +#define RTTC_RTSR (AT91_CAST(AT91_REG *) 0x0000000C) // (RTTC_RTSR) Real-time Status Register #endif // -------- RTTC_RTMR : (RTTC Offset: 0x0) Real-time Mode Register -------- @@ -645,16 +645,16 @@ typedef struct _AT91S_RTTC { // ***************************************************************************** #ifndef __ASSEMBLY__ typedef struct _AT91S_PITC { - AT91_REG PITC_PIMR; // Period Interval Mode Register - AT91_REG PITC_PISR; // Period Interval Status Register - AT91_REG PITC_PIVR; // Period Interval Value Register - AT91_REG PITC_PIIR; // Period Interval Image Register + AT91_REG PITC_PIMR; // Period Interval Mode Register + AT91_REG PITC_PISR; // Period Interval Status Register + AT91_REG PITC_PIVR; // Period Interval Value Register + AT91_REG PITC_PIIR; // Period Interval Image Register } AT91S_PITC, *AT91PS_PITC; #else -#define PITC_PIMR (AT91_CAST(AT91_REG *) 0x00000000) // (PITC_PIMR) Period Interval Mode Register -#define PITC_PISR (AT91_CAST(AT91_REG *) 0x00000004) // (PITC_PISR) Period Interval Status Register -#define PITC_PIVR (AT91_CAST(AT91_REG *) 0x00000008) // (PITC_PIVR) Period Interval Value Register -#define PITC_PIIR (AT91_CAST(AT91_REG *) 0x0000000C) // (PITC_PIIR) Period Interval Image Register +#define PITC_PIMR (AT91_CAST(AT91_REG *) 0x00000000) // (PITC_PIMR) Period Interval Mode Register +#define PITC_PISR (AT91_CAST(AT91_REG *) 0x00000004) // (PITC_PISR) Period Interval Status Register +#define PITC_PIVR (AT91_CAST(AT91_REG *) 0x00000008) // (PITC_PIVR) Period Interval Value Register +#define PITC_PIIR (AT91_CAST(AT91_REG *) 0x0000000C) // (PITC_PIIR) Period Interval Image Register #endif // -------- PITC_PIMR : (PITC Offset: 0x0) Periodic Interval Mode Register -------- @@ -673,14 +673,14 @@ typedef struct _AT91S_PITC { // ***************************************************************************** #ifndef __ASSEMBLY__ typedef struct _AT91S_WDTC { - AT91_REG WDTC_WDCR; // Watchdog Control Register - AT91_REG WDTC_WDMR; // Watchdog Mode Register - AT91_REG WDTC_WDSR; // Watchdog Status Register + AT91_REG WDTC_WDCR; // Watchdog Control Register + AT91_REG WDTC_WDMR; // Watchdog Mode Register + AT91_REG WDTC_WDSR; // Watchdog Status Register } AT91S_WDTC, *AT91PS_WDTC; #else -#define WDTC_WDCR (AT91_CAST(AT91_REG *) 0x00000000) // (WDTC_WDCR) Watchdog Control Register -#define WDTC_WDMR (AT91_CAST(AT91_REG *) 0x00000004) // (WDTC_WDMR) Watchdog Mode Register -#define WDTC_WDSR (AT91_CAST(AT91_REG *) 0x00000008) // (WDTC_WDSR) Watchdog Status Register +#define WDTC_WDCR (AT91_CAST(AT91_REG *) 0x00000000) // (WDTC_WDCR) Watchdog Control Register +#define WDTC_WDMR (AT91_CAST(AT91_REG *) 0x00000004) // (WDTC_WDMR) Watchdog Mode Register +#define WDTC_WDSR (AT91_CAST(AT91_REG *) 0x00000008) // (WDTC_WDSR) Watchdog Status Register #endif // -------- WDTC_WDCR : (WDTC Offset: 0x0) Periodic Interval Image Register -------- @@ -704,10 +704,10 @@ typedef struct _AT91S_WDTC { // ***************************************************************************** #ifndef __ASSEMBLY__ typedef struct _AT91S_VREG { - AT91_REG VREG_MR; // Voltage Regulator Mode Register + AT91_REG VREG_MR; // Voltage Regulator Mode Register } AT91S_VREG, *AT91PS_VREG; #else -#define VREG_MR (AT91_CAST(AT91_REG *) 0x00000000) // (VREG_MR) Voltage Regulator Mode Register +#define VREG_MR (AT91_CAST(AT91_REG *) 0x00000000) // (VREG_MR) Voltage Regulator Mode Register #endif // -------- VREG_MR : (VREG Offset: 0x0) Voltage Regulator Mode Register -------- @@ -718,16 +718,16 @@ typedef struct _AT91S_VREG { // ***************************************************************************** #ifndef __ASSEMBLY__ typedef struct _AT91S_EFC { - AT91_REG EFC_FMR; // MC Flash Mode Register - AT91_REG EFC_FCR; // MC Flash Command Register - AT91_REG EFC_FSR; // MC Flash Status Register - AT91_REG EFC_VR; // MC Flash Version Register + AT91_REG EFC_FMR; // MC Flash Mode Register + AT91_REG EFC_FCR; // MC Flash Command Register + AT91_REG EFC_FSR; // MC Flash Status Register + AT91_REG EFC_VR; // MC Flash Version Register } AT91S_EFC, *AT91PS_EFC; #else -#define MC_FMR (AT91_CAST(AT91_REG *) 0x00000000) // (MC_FMR) MC Flash Mode Register -#define MC_FCR (AT91_CAST(AT91_REG *) 0x00000004) // (MC_FCR) MC Flash Command Register -#define MC_FSR (AT91_CAST(AT91_REG *) 0x00000008) // (MC_FSR) MC Flash Status Register -#define MC_VR (AT91_CAST(AT91_REG *) 0x0000000C) // (MC_VR) MC Flash Version Register +#define MC_FMR (AT91_CAST(AT91_REG *) 0x00000000) // (MC_FMR) MC Flash Mode Register +#define MC_FCR (AT91_CAST(AT91_REG *) 0x00000004) // (MC_FCR) MC Flash Command Register +#define MC_FSR (AT91_CAST(AT91_REG *) 0x00000008) // (MC_FSR) MC Flash Status Register +#define MC_VR (AT91_CAST(AT91_REG *) 0x0000000C) // (MC_VR) MC Flash Version Register #endif // -------- MC_FMR : (EFC Offset: 0x0) MC Flash Mode Register -------- @@ -736,21 +736,21 @@ typedef struct _AT91S_EFC { #define AT91C_MC_PROGE (0x1 << 3) // (EFC) Programming Error #define AT91C_MC_NEBP (0x1 << 7) // (EFC) No Erase Before Programming #define AT91C_MC_FWS (0x3 << 8) // (EFC) Flash Wait State -#define AT91C_MC_FWS_0FWS (0x0 << 8) // (EFC) 1 cycle for Read, 2 for Write operations -#define AT91C_MC_FWS_1FWS (0x1 << 8) // (EFC) 2 cycles for Read, 3 for Write operations -#define AT91C_MC_FWS_2FWS (0x2 << 8) // (EFC) 3 cycles for Read, 4 for Write operations -#define AT91C_MC_FWS_3FWS (0x3 << 8) // (EFC) 4 cycles for Read, 4 for Write operations +#define AT91C_MC_FWS_0FWS (0x0 << 8) // (EFC) 1 cycle for Read, 2 for Write operations +#define AT91C_MC_FWS_1FWS (0x1 << 8) // (EFC) 2 cycles for Read, 3 for Write operations +#define AT91C_MC_FWS_2FWS (0x2 << 8) // (EFC) 3 cycles for Read, 4 for Write operations +#define AT91C_MC_FWS_3FWS (0x3 << 8) // (EFC) 4 cycles for Read, 4 for Write operations #define AT91C_MC_FMCN (0xFF << 16) // (EFC) Flash Microsecond Cycle Number // -------- MC_FCR : (EFC Offset: 0x4) MC Flash Command Register -------- #define AT91C_MC_FCMD (0xF << 0) // (EFC) Flash Command -#define AT91C_MC_FCMD_START_PROG (0x1) // (EFC) Starts the programming of th epage specified by PAGEN. -#define AT91C_MC_FCMD_LOCK (0x2) // (EFC) Starts a lock sequence of the sector defined by the bits 4 to 7 of the field PAGEN. -#define AT91C_MC_FCMD_PROG_AND_LOCK (0x3) // (EFC) The lock sequence automatically happens after the programming sequence is completed. -#define AT91C_MC_FCMD_UNLOCK (0x4) // (EFC) Starts an unlock sequence of the sector defined by the bits 4 to 7 of the field PAGEN. -#define AT91C_MC_FCMD_ERASE_ALL (0x8) // (EFC) Starts the erase of the entire flash.If at least a page is locked, the command is cancelled. -#define AT91C_MC_FCMD_SET_GP_NVM (0xB) // (EFC) Set General Purpose NVM bits. -#define AT91C_MC_FCMD_CLR_GP_NVM (0xD) // (EFC) Clear General Purpose NVM bits. -#define AT91C_MC_FCMD_SET_SECURITY (0xF) // (EFC) Set Security Bit. +#define AT91C_MC_FCMD_START_PROG (0x1) // (EFC) Starts the programming of th epage specified by PAGEN. +#define AT91C_MC_FCMD_LOCK (0x2) // (EFC) Starts a lock sequence of the sector defined by the bits 4 to 7 of the field PAGEN. +#define AT91C_MC_FCMD_PROG_AND_LOCK (0x3) // (EFC) The lock sequence automatically happens after the programming sequence is completed. +#define AT91C_MC_FCMD_UNLOCK (0x4) // (EFC) Starts an unlock sequence of the sector defined by the bits 4 to 7 of the field PAGEN. +#define AT91C_MC_FCMD_ERASE_ALL (0x8) // (EFC) Starts the erase of the entire flash.If at least a page is locked, the command is cancelled. +#define AT91C_MC_FCMD_SET_GP_NVM (0xB) // (EFC) Set General Purpose NVM bits. +#define AT91C_MC_FCMD_CLR_GP_NVM (0xD) // (EFC) Clear General Purpose NVM bits. +#define AT91C_MC_FCMD_SET_SECURITY (0xF) // (EFC) Set Security Bit. #define AT91C_MC_PAGEN (0x3FF << 8) // (EFC) Page Number #define AT91C_MC_KEY (0xFF << 24) // (EFC) Writing Protect Key // -------- MC_FSR : (EFC Offset: 0x8) MC Flash Command Register -------- @@ -788,30 +788,30 @@ typedef struct _AT91S_EFC { // ***************************************************************************** #ifndef __ASSEMBLY__ typedef struct _AT91S_MC { - AT91_REG MC_RCR; // MC Remap Control Register - AT91_REG MC_ASR; // MC Abort Status Register - AT91_REG MC_AASR; // MC Abort Address Status Register - AT91_REG Reserved0[1]; // - AT91_REG MC_PUIA[16]; // MC Protection Unit Area - AT91_REG MC_PUP; // MC Protection Unit Peripherals - AT91_REG MC_PUER; // MC Protection Unit Enable Register - AT91_REG Reserved1[2]; // - AT91_REG MC0_FMR; // MC Flash Mode Register - AT91_REG MC0_FCR; // MC Flash Command Register - AT91_REG MC0_FSR; // MC Flash Status Register - AT91_REG MC0_VR; // MC Flash Version Register - AT91_REG MC1_FMR; // MC Flash Mode Register - AT91_REG MC1_FCR; // MC Flash Command Register - AT91_REG MC1_FSR; // MC Flash Status Register - AT91_REG MC1_VR; // MC Flash Version Register + AT91_REG MC_RCR; // MC Remap Control Register + AT91_REG MC_ASR; // MC Abort Status Register + AT91_REG MC_AASR; // MC Abort Address Status Register + AT91_REG Reserved0[1]; // + AT91_REG MC_PUIA[16]; // MC Protection Unit Area + AT91_REG MC_PUP; // MC Protection Unit Peripherals + AT91_REG MC_PUER; // MC Protection Unit Enable Register + AT91_REG Reserved1[2]; // + AT91_REG MC0_FMR; // MC Flash Mode Register + AT91_REG MC0_FCR; // MC Flash Command Register + AT91_REG MC0_FSR; // MC Flash Status Register + AT91_REG MC0_VR; // MC Flash Version Register + AT91_REG MC1_FMR; // MC Flash Mode Register + AT91_REG MC1_FCR; // MC Flash Command Register + AT91_REG MC1_FSR; // MC Flash Status Register + AT91_REG MC1_VR; // MC Flash Version Register } AT91S_MC, *AT91PS_MC; #else -#define MC_RCR (AT91_CAST(AT91_REG *) 0x00000000) // (MC_RCR) MC Remap Control Register -#define MC_ASR (AT91_CAST(AT91_REG *) 0x00000004) // (MC_ASR) MC Abort Status Register -#define MC_AASR (AT91_CAST(AT91_REG *) 0x00000008) // (MC_AASR) MC Abort Address Status Register -#define MC_PUIA (AT91_CAST(AT91_REG *) 0x00000010) // (MC_PUIA) MC Protection Unit Area -#define MC_PUP (AT91_CAST(AT91_REG *) 0x00000050) // (MC_PUP) MC Protection Unit Peripherals -#define MC_PUER (AT91_CAST(AT91_REG *) 0x00000054) // (MC_PUER) MC Protection Unit Enable Register +#define MC_RCR (AT91_CAST(AT91_REG *) 0x00000000) // (MC_RCR) MC Remap Control Register +#define MC_ASR (AT91_CAST(AT91_REG *) 0x00000004) // (MC_ASR) MC Abort Status Register +#define MC_AASR (AT91_CAST(AT91_REG *) 0x00000008) // (MC_AASR) MC Abort Address Status Register +#define MC_PUIA (AT91_CAST(AT91_REG *) 0x00000010) // (MC_PUIA) MC Protection Unit Area +#define MC_PUP (AT91_CAST(AT91_REG *) 0x00000050) // (MC_PUP) MC Protection Unit Peripherals +#define MC_PUER (AT91_CAST(AT91_REG *) 0x00000054) // (MC_PUER) MC Protection Unit Enable Register #endif // -------- MC_RCR : (MC Offset: 0x0) MC Remap Control Register -------- @@ -821,40 +821,40 @@ typedef struct _AT91S_MC { #define AT91C_MC_MISADD (0x1 << 1) // (MC) Misaligned Addess Abort Status #define AT91C_MC_MPU (0x1 << 2) // (MC) Memory protection Unit Abort Status #define AT91C_MC_ABTSZ (0x3 << 8) // (MC) Abort Size Status -#define AT91C_MC_ABTSZ_BYTE (0x0 << 8) // (MC) Byte -#define AT91C_MC_ABTSZ_HWORD (0x1 << 8) // (MC) Half-word -#define AT91C_MC_ABTSZ_WORD (0x2 << 8) // (MC) Word +#define AT91C_MC_ABTSZ_BYTE (0x0 << 8) // (MC) Byte +#define AT91C_MC_ABTSZ_HWORD (0x1 << 8) // (MC) Half-word +#define AT91C_MC_ABTSZ_WORD (0x2 << 8) // (MC) Word #define AT91C_MC_ABTTYP (0x3 << 10) // (MC) Abort Type Status -#define AT91C_MC_ABTTYP_DATAR (0x0 << 10) // (MC) Data Read -#define AT91C_MC_ABTTYP_DATAW (0x1 << 10) // (MC) Data Write -#define AT91C_MC_ABTTYP_FETCH (0x2 << 10) // (MC) Code Fetch +#define AT91C_MC_ABTTYP_DATAR (0x0 << 10) // (MC) Data Read +#define AT91C_MC_ABTTYP_DATAW (0x1 << 10) // (MC) Data Write +#define AT91C_MC_ABTTYP_FETCH (0x2 << 10) // (MC) Code Fetch #define AT91C_MC_MST0 (0x1 << 16) // (MC) Master 0 Abort Source #define AT91C_MC_MST1 (0x1 << 17) // (MC) Master 1 Abort Source #define AT91C_MC_SVMST0 (0x1 << 24) // (MC) Saved Master 0 Abort Source #define AT91C_MC_SVMST1 (0x1 << 25) // (MC) Saved Master 1 Abort Source // -------- MC_PUIA : (MC Offset: 0x10) MC Protection Unit Area -------- #define AT91C_MC_PROT (0x3 << 0) // (MC) Protection -#define AT91C_MC_PROT_PNAUNA (0x0) // (MC) Privilege: No Access, User: No Access -#define AT91C_MC_PROT_PRWUNA (0x1) // (MC) Privilege: Read/Write, User: No Access -#define AT91C_MC_PROT_PRWURO (0x2) // (MC) Privilege: Read/Write, User: Read Only -#define AT91C_MC_PROT_PRWURW (0x3) // (MC) Privilege: Read/Write, User: Read/Write +#define AT91C_MC_PROT_PNAUNA (0x0) // (MC) Privilege: No Access, User: No Access +#define AT91C_MC_PROT_PRWUNA (0x1) // (MC) Privilege: Read/Write, User: No Access +#define AT91C_MC_PROT_PRWURO (0x2) // (MC) Privilege: Read/Write, User: Read Only +#define AT91C_MC_PROT_PRWURW (0x3) // (MC) Privilege: Read/Write, User: Read/Write #define AT91C_MC_SIZE (0xF << 4) // (MC) Internal Area Size -#define AT91C_MC_SIZE_1KB (0x0 << 4) // (MC) Area size 1KByte -#define AT91C_MC_SIZE_2KB (0x1 << 4) // (MC) Area size 2KByte -#define AT91C_MC_SIZE_4KB (0x2 << 4) // (MC) Area size 4KByte -#define AT91C_MC_SIZE_8KB (0x3 << 4) // (MC) Area size 8KByte -#define AT91C_MC_SIZE_16KB (0x4 << 4) // (MC) Area size 16KByte -#define AT91C_MC_SIZE_32KB (0x5 << 4) // (MC) Area size 32KByte -#define AT91C_MC_SIZE_64KB (0x6 << 4) // (MC) Area size 64KByte -#define AT91C_MC_SIZE_128KB (0x7 << 4) // (MC) Area size 128KByte -#define AT91C_MC_SIZE_256KB (0x8 << 4) // (MC) Area size 256KByte -#define AT91C_MC_SIZE_512KB (0x9 << 4) // (MC) Area size 512KByte -#define AT91C_MC_SIZE_1MB (0xA << 4) // (MC) Area size 1MByte -#define AT91C_MC_SIZE_2MB (0xB << 4) // (MC) Area size 2MByte -#define AT91C_MC_SIZE_4MB (0xC << 4) // (MC) Area size 4MByte -#define AT91C_MC_SIZE_8MB (0xD << 4) // (MC) Area size 8MByte -#define AT91C_MC_SIZE_16MB (0xE << 4) // (MC) Area size 16MByte -#define AT91C_MC_SIZE_64MB (0xF << 4) // (MC) Area size 64MByte +#define AT91C_MC_SIZE_1KB (0x0 << 4) // (MC) Area size 1KByte +#define AT91C_MC_SIZE_2KB (0x1 << 4) // (MC) Area size 2KByte +#define AT91C_MC_SIZE_4KB (0x2 << 4) // (MC) Area size 4KByte +#define AT91C_MC_SIZE_8KB (0x3 << 4) // (MC) Area size 8KByte +#define AT91C_MC_SIZE_16KB (0x4 << 4) // (MC) Area size 16KByte +#define AT91C_MC_SIZE_32KB (0x5 << 4) // (MC) Area size 32KByte +#define AT91C_MC_SIZE_64KB (0x6 << 4) // (MC) Area size 64KByte +#define AT91C_MC_SIZE_128KB (0x7 << 4) // (MC) Area size 128KByte +#define AT91C_MC_SIZE_256KB (0x8 << 4) // (MC) Area size 256KByte +#define AT91C_MC_SIZE_512KB (0x9 << 4) // (MC) Area size 512KByte +#define AT91C_MC_SIZE_1MB (0xA << 4) // (MC) Area size 1MByte +#define AT91C_MC_SIZE_2MB (0xB << 4) // (MC) Area size 2MByte +#define AT91C_MC_SIZE_4MB (0xC << 4) // (MC) Area size 4MByte +#define AT91C_MC_SIZE_8MB (0xD << 4) // (MC) Area size 8MByte +#define AT91C_MC_SIZE_16MB (0xE << 4) // (MC) Area size 16MByte +#define AT91C_MC_SIZE_64MB (0xF << 4) // (MC) Area size 64MByte #define AT91C_MC_BA (0x3FFFF << 10) // (MC) Internal Area Base Address // -------- MC_PUP : (MC Offset: 0x50) MC Protection Unit Peripheral -------- // -------- MC_PUER : (MC Offset: 0x54) MC Protection Unit Area -------- @@ -865,38 +865,38 @@ typedef struct _AT91S_MC { // ***************************************************************************** #ifndef __ASSEMBLY__ typedef struct _AT91S_SPI { - AT91_REG SPI_CR; // Control Register - AT91_REG SPI_MR; // Mode Register - AT91_REG SPI_RDR; // Receive Data Register - AT91_REG SPI_TDR; // Transmit Data Register - AT91_REG SPI_SR; // Status Register - AT91_REG SPI_IER; // Interrupt Enable Register - AT91_REG SPI_IDR; // Interrupt Disable Register - AT91_REG SPI_IMR; // Interrupt Mask Register - AT91_REG Reserved0[4]; // - AT91_REG SPI_CSR[4]; // Chip Select Register - AT91_REG Reserved1[48]; // - AT91_REG SPI_RPR; // Receive Pointer Register - AT91_REG SPI_RCR; // Receive Counter Register - AT91_REG SPI_TPR; // Transmit Pointer Register - AT91_REG SPI_TCR; // Transmit Counter Register - AT91_REG SPI_RNPR; // Receive Next Pointer Register - AT91_REG SPI_RNCR; // Receive Next Counter Register - AT91_REG SPI_TNPR; // Transmit Next Pointer Register - AT91_REG SPI_TNCR; // Transmit Next Counter Register - AT91_REG SPI_PTCR; // PDC Transfer Control Register - AT91_REG SPI_PTSR; // PDC Transfer Status Register + AT91_REG SPI_CR; // Control Register + AT91_REG SPI_MR; // Mode Register + AT91_REG SPI_RDR; // Receive Data Register + AT91_REG SPI_TDR; // Transmit Data Register + AT91_REG SPI_SR; // Status Register + AT91_REG SPI_IER; // Interrupt Enable Register + AT91_REG SPI_IDR; // Interrupt Disable Register + AT91_REG SPI_IMR; // Interrupt Mask Register + AT91_REG Reserved0[4]; // + AT91_REG SPI_CSR[4]; // Chip Select Register + AT91_REG Reserved1[48]; // + AT91_REG SPI_RPR; // Receive Pointer Register + AT91_REG SPI_RCR; // Receive Counter Register + AT91_REG SPI_TPR; // Transmit Pointer Register + AT91_REG SPI_TCR; // Transmit Counter Register + AT91_REG SPI_RNPR; // Receive Next Pointer Register + AT91_REG SPI_RNCR; // Receive Next Counter Register + AT91_REG SPI_TNPR; // Transmit Next Pointer Register + AT91_REG SPI_TNCR; // Transmit Next Counter Register + AT91_REG SPI_PTCR; // PDC Transfer Control Register + AT91_REG SPI_PTSR; // PDC Transfer Status Register } AT91S_SPI, *AT91PS_SPI; #else -#define SPI_CR (AT91_CAST(AT91_REG *) 0x00000000) // (SPI_CR) Control Register -#define SPI_MR (AT91_CAST(AT91_REG *) 0x00000004) // (SPI_MR) Mode Register -#define SPI_RDR (AT91_CAST(AT91_REG *) 0x00000008) // (SPI_RDR) Receive Data Register -#define SPI_TDR (AT91_CAST(AT91_REG *) 0x0000000C) // (SPI_TDR) Transmit Data Register -#define SPI_SR (AT91_CAST(AT91_REG *) 0x00000010) // (SPI_SR) Status Register -#define SPI_IER (AT91_CAST(AT91_REG *) 0x00000014) // (SPI_IER) Interrupt Enable Register -#define SPI_IDR (AT91_CAST(AT91_REG *) 0x00000018) // (SPI_IDR) Interrupt Disable Register -#define SPI_IMR (AT91_CAST(AT91_REG *) 0x0000001C) // (SPI_IMR) Interrupt Mask Register -#define SPI_CSR (AT91_CAST(AT91_REG *) 0x00000030) // (SPI_CSR) Chip Select Register +#define SPI_CR (AT91_CAST(AT91_REG *) 0x00000000) // (SPI_CR) Control Register +#define SPI_MR (AT91_CAST(AT91_REG *) 0x00000004) // (SPI_MR) Mode Register +#define SPI_RDR (AT91_CAST(AT91_REG *) 0x00000008) // (SPI_RDR) Receive Data Register +#define SPI_TDR (AT91_CAST(AT91_REG *) 0x0000000C) // (SPI_TDR) Transmit Data Register +#define SPI_SR (AT91_CAST(AT91_REG *) 0x00000010) // (SPI_SR) Status Register +#define SPI_IER (AT91_CAST(AT91_REG *) 0x00000014) // (SPI_IER) Interrupt Enable Register +#define SPI_IDR (AT91_CAST(AT91_REG *) 0x00000018) // (SPI_IDR) Interrupt Disable Register +#define SPI_IMR (AT91_CAST(AT91_REG *) 0x0000001C) // (SPI_IMR) Interrupt Mask Register +#define SPI_CSR (AT91_CAST(AT91_REG *) 0x00000030) // (SPI_CSR) Chip Select Register #endif // -------- SPI_CR : (SPI Offset: 0x0) SPI Control Register -------- @@ -907,8 +907,8 @@ typedef struct _AT91S_SPI { // -------- SPI_MR : (SPI Offset: 0x4) SPI Mode Register -------- #define AT91C_SPI_MSTR (0x1 << 0) // (SPI) Master/Slave Mode #define AT91C_SPI_PS (0x1 << 1) // (SPI) Peripheral Select -#define AT91C_SPI_PS_FIXED (0x0 << 1) // (SPI) Fixed Peripheral Select -#define AT91C_SPI_PS_VARIABLE (0x1 << 1) // (SPI) Variable Peripheral Select +#define AT91C_SPI_PS_FIXED (0x0 << 1) // (SPI) Fixed Peripheral Select +#define AT91C_SPI_PS_VARIABLE (0x1 << 1) // (SPI) Variable Peripheral Select #define AT91C_SPI_PCSDEC (0x1 << 2) // (SPI) Chip Select Decode #define AT91C_SPI_FDIV (0x1 << 3) // (SPI) Clock Selection #define AT91C_SPI_MODFDIS (0x1 << 4) // (SPI) Mode Fault Detection @@ -941,15 +941,15 @@ typedef struct _AT91S_SPI { #define AT91C_SPI_NCPHA (0x1 << 1) // (SPI) Clock Phase #define AT91C_SPI_CSAAT (0x1 << 3) // (SPI) Chip Select Active After Transfer #define AT91C_SPI_BITS (0xF << 4) // (SPI) Bits Per Transfer -#define AT91C_SPI_BITS_8 (0x0 << 4) // (SPI) 8 Bits Per transfer -#define AT91C_SPI_BITS_9 (0x1 << 4) // (SPI) 9 Bits Per transfer -#define AT91C_SPI_BITS_10 (0x2 << 4) // (SPI) 10 Bits Per transfer -#define AT91C_SPI_BITS_11 (0x3 << 4) // (SPI) 11 Bits Per transfer -#define AT91C_SPI_BITS_12 (0x4 << 4) // (SPI) 12 Bits Per transfer -#define AT91C_SPI_BITS_13 (0x5 << 4) // (SPI) 13 Bits Per transfer -#define AT91C_SPI_BITS_14 (0x6 << 4) // (SPI) 14 Bits Per transfer -#define AT91C_SPI_BITS_15 (0x7 << 4) // (SPI) 15 Bits Per transfer -#define AT91C_SPI_BITS_16 (0x8 << 4) // (SPI) 16 Bits Per transfer +#define AT91C_SPI_BITS_8 (0x0 << 4) // (SPI) 8 Bits Per transfer +#define AT91C_SPI_BITS_9 (0x1 << 4) // (SPI) 9 Bits Per transfer +#define AT91C_SPI_BITS_10 (0x2 << 4) // (SPI) 10 Bits Per transfer +#define AT91C_SPI_BITS_11 (0x3 << 4) // (SPI) 11 Bits Per transfer +#define AT91C_SPI_BITS_12 (0x4 << 4) // (SPI) 12 Bits Per transfer +#define AT91C_SPI_BITS_13 (0x5 << 4) // (SPI) 13 Bits Per transfer +#define AT91C_SPI_BITS_14 (0x6 << 4) // (SPI) 14 Bits Per transfer +#define AT91C_SPI_BITS_15 (0x7 << 4) // (SPI) 15 Bits Per transfer +#define AT91C_SPI_BITS_16 (0x8 << 4) // (SPI) 16 Bits Per transfer #define AT91C_SPI_SCBR (0xFF << 8) // (SPI) Serial Clock Baud Rate #define AT91C_SPI_DLYBS (0xFF << 16) // (SPI) Delay Before SPCK #define AT91C_SPI_DLYBCT (0xFF << 24) // (SPI) Delay Between Consecutive Transfers @@ -959,49 +959,49 @@ typedef struct _AT91S_SPI { // ***************************************************************************** #ifndef __ASSEMBLY__ typedef struct _AT91S_ADC { - AT91_REG ADC_CR; // ADC Control Register - AT91_REG ADC_MR; // ADC Mode Register - AT91_REG Reserved0[2]; // - AT91_REG ADC_CHER; // ADC Channel Enable Register - AT91_REG ADC_CHDR; // ADC Channel Disable Register - AT91_REG ADC_CHSR; // ADC Channel Status Register - AT91_REG ADC_SR; // ADC Status Register - AT91_REG ADC_LCDR; // ADC Last Converted Data Register - AT91_REG ADC_IER; // ADC Interrupt Enable Register - AT91_REG ADC_IDR; // ADC Interrupt Disable Register - AT91_REG ADC_IMR; // ADC Interrupt Mask Register - AT91_REG ADC_CDR[8]; // ADC Channel Data Register - AT91_REG Reserved1[44]; // - AT91_REG ADC_RPR; // Receive Pointer Register - AT91_REG ADC_RCR; // Receive Counter Register - AT91_REG ADC_TPR; // Transmit Pointer Register - AT91_REG ADC_TCR; // Transmit Counter Register - AT91_REG ADC_RNPR; // Receive Next Pointer Register - AT91_REG ADC_RNCR; // Receive Next Counter Register - AT91_REG ADC_TNPR; // Transmit Next Pointer Register - AT91_REG ADC_TNCR; // Transmit Next Counter Register - AT91_REG ADC_PTCR; // PDC Transfer Control Register - AT91_REG ADC_PTSR; // PDC Transfer Status Register + AT91_REG ADC_CR; // ADC Control Register + AT91_REG ADC_MR; // ADC Mode Register + AT91_REG Reserved0[2]; // + AT91_REG ADC_CHER; // ADC Channel Enable Register + AT91_REG ADC_CHDR; // ADC Channel Disable Register + AT91_REG ADC_CHSR; // ADC Channel Status Register + AT91_REG ADC_SR; // ADC Status Register + AT91_REG ADC_LCDR; // ADC Last Converted Data Register + AT91_REG ADC_IER; // ADC Interrupt Enable Register + AT91_REG ADC_IDR; // ADC Interrupt Disable Register + AT91_REG ADC_IMR; // ADC Interrupt Mask Register + AT91_REG ADC_CDR[8]; // ADC Channel Data Register + AT91_REG Reserved1[44]; // + AT91_REG ADC_RPR; // Receive Pointer Register + AT91_REG ADC_RCR; // Receive Counter Register + AT91_REG ADC_TPR; // Transmit Pointer Register + AT91_REG ADC_TCR; // Transmit Counter Register + AT91_REG ADC_RNPR; // Receive Next Pointer Register + AT91_REG ADC_RNCR; // Receive Next Counter Register + AT91_REG ADC_TNPR; // Transmit Next Pointer Register + AT91_REG ADC_TNCR; // Transmit Next Counter Register + AT91_REG ADC_PTCR; // PDC Transfer Control Register + AT91_REG ADC_PTSR; // PDC Transfer Status Register } AT91S_ADC, *AT91PS_ADC; #else -#define ADC_CR (AT91_CAST(AT91_REG *) 0x00000000) // (ADC_CR) ADC Control Register -#define ADC_MR (AT91_CAST(AT91_REG *) 0x00000004) // (ADC_MR) ADC Mode Register -#define ADC_CHER (AT91_CAST(AT91_REG *) 0x00000010) // (ADC_CHER) ADC Channel Enable Register -#define ADC_CHDR (AT91_CAST(AT91_REG *) 0x00000014) // (ADC_CHDR) ADC Channel Disable Register -#define ADC_CHSR (AT91_CAST(AT91_REG *) 0x00000018) // (ADC_CHSR) ADC Channel Status Register -#define ADC_SR (AT91_CAST(AT91_REG *) 0x0000001C) // (ADC_SR) ADC Status Register -#define ADC_LCDR (AT91_CAST(AT91_REG *) 0x00000020) // (ADC_LCDR) ADC Last Converted Data Register -#define ADC_IER (AT91_CAST(AT91_REG *) 0x00000024) // (ADC_IER) ADC Interrupt Enable Register -#define ADC_IDR (AT91_CAST(AT91_REG *) 0x00000028) // (ADC_IDR) ADC Interrupt Disable Register -#define ADC_IMR (AT91_CAST(AT91_REG *) 0x0000002C) // (ADC_IMR) ADC Interrupt Mask Register -#define ADC_CDR0 (AT91_CAST(AT91_REG *) 0x00000030) // (ADC_CDR0) ADC Channel Data Register 0 -#define ADC_CDR1 (AT91_CAST(AT91_REG *) 0x00000034) // (ADC_CDR1) ADC Channel Data Register 1 -#define ADC_CDR2 (AT91_CAST(AT91_REG *) 0x00000038) // (ADC_CDR2) ADC Channel Data Register 2 -#define ADC_CDR3 (AT91_CAST(AT91_REG *) 0x0000003C) // (ADC_CDR3) ADC Channel Data Register 3 -#define ADC_CDR4 (AT91_CAST(AT91_REG *) 0x00000040) // (ADC_CDR4) ADC Channel Data Register 4 -#define ADC_CDR5 (AT91_CAST(AT91_REG *) 0x00000044) // (ADC_CDR5) ADC Channel Data Register 5 -#define ADC_CDR6 (AT91_CAST(AT91_REG *) 0x00000048) // (ADC_CDR6) ADC Channel Data Register 6 -#define ADC_CDR7 (AT91_CAST(AT91_REG *) 0x0000004C) // (ADC_CDR7) ADC Channel Data Register 7 +#define ADC_CR (AT91_CAST(AT91_REG *) 0x00000000) // (ADC_CR) ADC Control Register +#define ADC_MR (AT91_CAST(AT91_REG *) 0x00000004) // (ADC_MR) ADC Mode Register +#define ADC_CHER (AT91_CAST(AT91_REG *) 0x00000010) // (ADC_CHER) ADC Channel Enable Register +#define ADC_CHDR (AT91_CAST(AT91_REG *) 0x00000014) // (ADC_CHDR) ADC Channel Disable Register +#define ADC_CHSR (AT91_CAST(AT91_REG *) 0x00000018) // (ADC_CHSR) ADC Channel Status Register +#define ADC_SR (AT91_CAST(AT91_REG *) 0x0000001C) // (ADC_SR) ADC Status Register +#define ADC_LCDR (AT91_CAST(AT91_REG *) 0x00000020) // (ADC_LCDR) ADC Last Converted Data Register +#define ADC_IER (AT91_CAST(AT91_REG *) 0x00000024) // (ADC_IER) ADC Interrupt Enable Register +#define ADC_IDR (AT91_CAST(AT91_REG *) 0x00000028) // (ADC_IDR) ADC Interrupt Disable Register +#define ADC_IMR (AT91_CAST(AT91_REG *) 0x0000002C) // (ADC_IMR) ADC Interrupt Mask Register +#define ADC_CDR0 (AT91_CAST(AT91_REG *) 0x00000030) // (ADC_CDR0) ADC Channel Data Register 0 +#define ADC_CDR1 (AT91_CAST(AT91_REG *) 0x00000034) // (ADC_CDR1) ADC Channel Data Register 1 +#define ADC_CDR2 (AT91_CAST(AT91_REG *) 0x00000038) // (ADC_CDR2) ADC Channel Data Register 2 +#define ADC_CDR3 (AT91_CAST(AT91_REG *) 0x0000003C) // (ADC_CDR3) ADC Channel Data Register 3 +#define ADC_CDR4 (AT91_CAST(AT91_REG *) 0x00000040) // (ADC_CDR4) ADC Channel Data Register 4 +#define ADC_CDR5 (AT91_CAST(AT91_REG *) 0x00000044) // (ADC_CDR5) ADC Channel Data Register 5 +#define ADC_CDR6 (AT91_CAST(AT91_REG *) 0x00000048) // (ADC_CDR6) ADC Channel Data Register 6 +#define ADC_CDR7 (AT91_CAST(AT91_REG *) 0x0000004C) // (ADC_CDR7) ADC Channel Data Register 7 #endif // -------- ADC_CR : (ADC Offset: 0x0) ADC Control Register -------- @@ -1009,26 +1009,26 @@ typedef struct _AT91S_ADC { #define AT91C_ADC_START (0x1 << 1) // (ADC) Start Conversion // -------- ADC_MR : (ADC Offset: 0x4) ADC Mode Register -------- #define AT91C_ADC_TRGEN (0x1 << 0) // (ADC) Trigger Enable -#define AT91C_ADC_TRGEN_DIS (0x0) // (ADC) Hradware triggers are disabled. Starting a conversion is only possible by software -#define AT91C_ADC_TRGEN_EN (0x1) // (ADC) Hardware trigger selected by TRGSEL field is enabled. +#define AT91C_ADC_TRGEN_DIS (0x0) // (ADC) Hradware triggers are disabled. Starting a conversion is only possible by software +#define AT91C_ADC_TRGEN_EN (0x1) // (ADC) Hardware trigger selected by TRGSEL field is enabled. #define AT91C_ADC_TRGSEL (0x7 << 1) // (ADC) Trigger Selection -#define AT91C_ADC_TRGSEL_TIOA0 (0x0 << 1) // (ADC) Selected TRGSEL = TIAO0 -#define AT91C_ADC_TRGSEL_TIOA1 (0x1 << 1) // (ADC) Selected TRGSEL = TIAO1 -#define AT91C_ADC_TRGSEL_TIOA2 (0x2 << 1) // (ADC) Selected TRGSEL = TIAO2 -#define AT91C_ADC_TRGSEL_TIOA3 (0x3 << 1) // (ADC) Selected TRGSEL = TIAO3 -#define AT91C_ADC_TRGSEL_TIOA4 (0x4 << 1) // (ADC) Selected TRGSEL = TIAO4 -#define AT91C_ADC_TRGSEL_TIOA5 (0x5 << 1) // (ADC) Selected TRGSEL = TIAO5 -#define AT91C_ADC_TRGSEL_EXT (0x6 << 1) // (ADC) Selected TRGSEL = External Trigger +#define AT91C_ADC_TRGSEL_TIOA0 (0x0 << 1) // (ADC) Selected TRGSEL = TIAO0 +#define AT91C_ADC_TRGSEL_TIOA1 (0x1 << 1) // (ADC) Selected TRGSEL = TIAO1 +#define AT91C_ADC_TRGSEL_TIOA2 (0x2 << 1) // (ADC) Selected TRGSEL = TIAO2 +#define AT91C_ADC_TRGSEL_TIOA3 (0x3 << 1) // (ADC) Selected TRGSEL = TIAO3 +#define AT91C_ADC_TRGSEL_TIOA4 (0x4 << 1) // (ADC) Selected TRGSEL = TIAO4 +#define AT91C_ADC_TRGSEL_TIOA5 (0x5 << 1) // (ADC) Selected TRGSEL = TIAO5 +#define AT91C_ADC_TRGSEL_EXT (0x6 << 1) // (ADC) Selected TRGSEL = External Trigger #define AT91C_ADC_LOWRES (0x1 << 4) // (ADC) Resolution. -#define AT91C_ADC_LOWRES_10_BIT (0x0 << 4) // (ADC) 10-bit resolution -#define AT91C_ADC_LOWRES_8_BIT (0x1 << 4) // (ADC) 8-bit resolution +#define AT91C_ADC_LOWRES_10_BIT (0x0 << 4) // (ADC) 10-bit resolution +#define AT91C_ADC_LOWRES_8_BIT (0x1 << 4) // (ADC) 8-bit resolution #define AT91C_ADC_SLEEP (0x1 << 5) // (ADC) Sleep Mode -#define AT91C_ADC_SLEEP_NORMAL_MODE (0x0 << 5) // (ADC) Normal Mode -#define AT91C_ADC_SLEEP_MODE (0x1 << 5) // (ADC) Sleep Mode +#define AT91C_ADC_SLEEP_NORMAL_MODE (0x0 << 5) // (ADC) Normal Mode +#define AT91C_ADC_SLEEP_MODE (0x1 << 5) // (ADC) Sleep Mode #define AT91C_ADC_PRESCAL (0x3F << 8) // (ADC) Prescaler rate selection #define AT91C_ADC_STARTUP (0x1F << 16) // (ADC) Startup Time #define AT91C_ADC_SHTIM (0xF << 24) // (ADC) Sample & Hold Time -// -------- ADC_CHER : (ADC Offset: 0x10) ADC Channel Enable Register -------- +// -------- ADC_CHER : (ADC Offset: 0x10) ADC Channel Enable Register -------- #define AT91C_ADC_CH0 (0x1 << 0) // (ADC) Channel 0 #define AT91C_ADC_CH1 (0x1 << 1) // (ADC) Channel 1 #define AT91C_ADC_CH2 (0x1 << 2) // (ADC) Channel 2 @@ -1037,8 +1037,8 @@ typedef struct _AT91S_ADC { #define AT91C_ADC_CH5 (0x1 << 5) // (ADC) Channel 5 #define AT91C_ADC_CH6 (0x1 << 6) // (ADC) Channel 6 #define AT91C_ADC_CH7 (0x1 << 7) // (ADC) Channel 7 -// -------- ADC_CHDR : (ADC Offset: 0x14) ADC Channel Disable Register -------- -// -------- ADC_CHSR : (ADC Offset: 0x18) ADC Channel Status Register -------- +// -------- ADC_CHDR : (ADC Offset: 0x14) ADC Channel Disable Register -------- +// -------- ADC_CHSR : (ADC Offset: 0x18) ADC Channel Status Register -------- // -------- ADC_SR : (ADC Offset: 0x1c) ADC Status Register -------- #define AT91C_ADC_EOC0 (0x1 << 0) // (ADC) End of Conversion #define AT91C_ADC_EOC1 (0x1 << 1) // (ADC) End of Conversion @@ -1080,50 +1080,50 @@ typedef struct _AT91S_ADC { // ***************************************************************************** #ifndef __ASSEMBLY__ typedef struct _AT91S_SSC { - AT91_REG SSC_CR; // Control Register - AT91_REG SSC_CMR; // Clock Mode Register - AT91_REG Reserved0[2]; // - AT91_REG SSC_RCMR; // Receive Clock ModeRegister - AT91_REG SSC_RFMR; // Receive Frame Mode Register - AT91_REG SSC_TCMR; // Transmit Clock Mode Register - AT91_REG SSC_TFMR; // Transmit Frame Mode Register - AT91_REG SSC_RHR; // Receive Holding Register - AT91_REG SSC_THR; // Transmit Holding Register - AT91_REG Reserved1[2]; // - AT91_REG SSC_RSHR; // Receive Sync Holding Register - AT91_REG SSC_TSHR; // Transmit Sync Holding Register - AT91_REG Reserved2[2]; // - AT91_REG SSC_SR; // Status Register - AT91_REG SSC_IER; // Interrupt Enable Register - AT91_REG SSC_IDR; // Interrupt Disable Register - AT91_REG SSC_IMR; // Interrupt Mask Register - AT91_REG Reserved3[44]; // - AT91_REG SSC_RPR; // Receive Pointer Register - AT91_REG SSC_RCR; // Receive Counter Register - AT91_REG SSC_TPR; // Transmit Pointer Register - AT91_REG SSC_TCR; // Transmit Counter Register - AT91_REG SSC_RNPR; // Receive Next Pointer Register - AT91_REG SSC_RNCR; // Receive Next Counter Register - AT91_REG SSC_TNPR; // Transmit Next Pointer Register - AT91_REG SSC_TNCR; // Transmit Next Counter Register - AT91_REG SSC_PTCR; // PDC Transfer Control Register - AT91_REG SSC_PTSR; // PDC Transfer Status Register + AT91_REG SSC_CR; // Control Register + AT91_REG SSC_CMR; // Clock Mode Register + AT91_REG Reserved0[2]; // + AT91_REG SSC_RCMR; // Receive Clock ModeRegister + AT91_REG SSC_RFMR; // Receive Frame Mode Register + AT91_REG SSC_TCMR; // Transmit Clock Mode Register + AT91_REG SSC_TFMR; // Transmit Frame Mode Register + AT91_REG SSC_RHR; // Receive Holding Register + AT91_REG SSC_THR; // Transmit Holding Register + AT91_REG Reserved1[2]; // + AT91_REG SSC_RSHR; // Receive Sync Holding Register + AT91_REG SSC_TSHR; // Transmit Sync Holding Register + AT91_REG Reserved2[2]; // + AT91_REG SSC_SR; // Status Register + AT91_REG SSC_IER; // Interrupt Enable Register + AT91_REG SSC_IDR; // Interrupt Disable Register + AT91_REG SSC_IMR; // Interrupt Mask Register + AT91_REG Reserved3[44]; // + AT91_REG SSC_RPR; // Receive Pointer Register + AT91_REG SSC_RCR; // Receive Counter Register + AT91_REG SSC_TPR; // Transmit Pointer Register + AT91_REG SSC_TCR; // Transmit Counter Register + AT91_REG SSC_RNPR; // Receive Next Pointer Register + AT91_REG SSC_RNCR; // Receive Next Counter Register + AT91_REG SSC_TNPR; // Transmit Next Pointer Register + AT91_REG SSC_TNCR; // Transmit Next Counter Register + AT91_REG SSC_PTCR; // PDC Transfer Control Register + AT91_REG SSC_PTSR; // PDC Transfer Status Register } AT91S_SSC, *AT91PS_SSC; #else -#define SSC_CR (AT91_CAST(AT91_REG *) 0x00000000) // (SSC_CR) Control Register -#define SSC_CMR (AT91_CAST(AT91_REG *) 0x00000004) // (SSC_CMR) Clock Mode Register -#define SSC_RCMR (AT91_CAST(AT91_REG *) 0x00000010) // (SSC_RCMR) Receive Clock ModeRegister -#define SSC_RFMR (AT91_CAST(AT91_REG *) 0x00000014) // (SSC_RFMR) Receive Frame Mode Register -#define SSC_TCMR (AT91_CAST(AT91_REG *) 0x00000018) // (SSC_TCMR) Transmit Clock Mode Register -#define SSC_TFMR (AT91_CAST(AT91_REG *) 0x0000001C) // (SSC_TFMR) Transmit Frame Mode Register -#define SSC_RHR (AT91_CAST(AT91_REG *) 0x00000020) // (SSC_RHR) Receive Holding Register -#define SSC_THR (AT91_CAST(AT91_REG *) 0x00000024) // (SSC_THR) Transmit Holding Register -#define SSC_RSHR (AT91_CAST(AT91_REG *) 0x00000030) // (SSC_RSHR) Receive Sync Holding Register -#define SSC_TSHR (AT91_CAST(AT91_REG *) 0x00000034) // (SSC_TSHR) Transmit Sync Holding Register -#define SSC_SR (AT91_CAST(AT91_REG *) 0x00000040) // (SSC_SR) Status Register -#define SSC_IER (AT91_CAST(AT91_REG *) 0x00000044) // (SSC_IER) Interrupt Enable Register -#define SSC_IDR (AT91_CAST(AT91_REG *) 0x00000048) // (SSC_IDR) Interrupt Disable Register -#define SSC_IMR (AT91_CAST(AT91_REG *) 0x0000004C) // (SSC_IMR) Interrupt Mask Register +#define SSC_CR (AT91_CAST(AT91_REG *) 0x00000000) // (SSC_CR) Control Register +#define SSC_CMR (AT91_CAST(AT91_REG *) 0x00000004) // (SSC_CMR) Clock Mode Register +#define SSC_RCMR (AT91_CAST(AT91_REG *) 0x00000010) // (SSC_RCMR) Receive Clock ModeRegister +#define SSC_RFMR (AT91_CAST(AT91_REG *) 0x00000014) // (SSC_RFMR) Receive Frame Mode Register +#define SSC_TCMR (AT91_CAST(AT91_REG *) 0x00000018) // (SSC_TCMR) Transmit Clock Mode Register +#define SSC_TFMR (AT91_CAST(AT91_REG *) 0x0000001C) // (SSC_TFMR) Transmit Frame Mode Register +#define SSC_RHR (AT91_CAST(AT91_REG *) 0x00000020) // (SSC_RHR) Receive Holding Register +#define SSC_THR (AT91_CAST(AT91_REG *) 0x00000024) // (SSC_THR) Transmit Holding Register +#define SSC_RSHR (AT91_CAST(AT91_REG *) 0x00000030) // (SSC_RSHR) Receive Sync Holding Register +#define SSC_TSHR (AT91_CAST(AT91_REG *) 0x00000034) // (SSC_TSHR) Transmit Sync Holding Register +#define SSC_SR (AT91_CAST(AT91_REG *) 0x00000040) // (SSC_SR) Status Register +#define SSC_IER (AT91_CAST(AT91_REG *) 0x00000044) // (SSC_IER) Interrupt Enable Register +#define SSC_IDR (AT91_CAST(AT91_REG *) 0x00000048) // (SSC_IDR) Interrupt Disable Register +#define SSC_IMR (AT91_CAST(AT91_REG *) 0x0000004C) // (SSC_IMR) Interrupt Mask Register #endif // -------- SSC_CR : (SSC Offset: 0x0) SSC Control Register -------- @@ -1134,24 +1134,24 @@ typedef struct _AT91S_SSC { #define AT91C_SSC_SWRST (0x1 << 15) // (SSC) Software Reset // -------- SSC_RCMR : (SSC Offset: 0x10) SSC Receive Clock Mode Register -------- #define AT91C_SSC_CKS (0x3 << 0) // (SSC) Receive/Transmit Clock Selection -#define AT91C_SSC_CKS_DIV (0x0) // (SSC) Divided Clock -#define AT91C_SSC_CKS_TK (0x1) // (SSC) TK Clock signal -#define AT91C_SSC_CKS_RK (0x2) // (SSC) RK pin +#define AT91C_SSC_CKS_DIV (0x0) // (SSC) Divided Clock +#define AT91C_SSC_CKS_TK (0x1) // (SSC) TK Clock signal +#define AT91C_SSC_CKS_RK (0x2) // (SSC) RK pin #define AT91C_SSC_CKO (0x7 << 2) // (SSC) Receive/Transmit Clock Output Mode Selection -#define AT91C_SSC_CKO_NONE (0x0 << 2) // (SSC) Receive/Transmit Clock Output Mode: None RK pin: Input-only -#define AT91C_SSC_CKO_CONTINOUS (0x1 << 2) // (SSC) Continuous Receive/Transmit Clock RK pin: Output -#define AT91C_SSC_CKO_DATA_TX (0x2 << 2) // (SSC) Receive/Transmit Clock only during data transfers RK pin: Output +#define AT91C_SSC_CKO_NONE (0x0 << 2) // (SSC) Receive/Transmit Clock Output Mode: None RK pin: Input-only +#define AT91C_SSC_CKO_CONTINOUS (0x1 << 2) // (SSC) Continuous Receive/Transmit Clock RK pin: Output +#define AT91C_SSC_CKO_DATA_TX (0x2 << 2) // (SSC) Receive/Transmit Clock only during data transfers RK pin: Output #define AT91C_SSC_CKI (0x1 << 5) // (SSC) Receive/Transmit Clock Inversion #define AT91C_SSC_START (0xF << 8) // (SSC) Receive/Transmit Start Selection -#define AT91C_SSC_START_CONTINOUS (0x0 << 8) // (SSC) Continuous, as soon as the receiver is enabled, and immediately after the end of transfer of the previous data. -#define AT91C_SSC_START_TX (0x1 << 8) // (SSC) Transmit/Receive start -#define AT91C_SSC_START_LOW_RF (0x2 << 8) // (SSC) Detection of a low level on RF input -#define AT91C_SSC_START_HIGH_RF (0x3 << 8) // (SSC) Detection of a high level on RF input -#define AT91C_SSC_START_FALL_RF (0x4 << 8) // (SSC) Detection of a falling edge on RF input -#define AT91C_SSC_START_RISE_RF (0x5 << 8) // (SSC) Detection of a rising edge on RF input -#define AT91C_SSC_START_LEVEL_RF (0x6 << 8) // (SSC) Detection of any level change on RF input -#define AT91C_SSC_START_EDGE_RF (0x7 << 8) // (SSC) Detection of any edge on RF input -#define AT91C_SSC_START_0 (0x8 << 8) // (SSC) Compare 0 +#define AT91C_SSC_START_CONTINOUS (0x0 << 8) // (SSC) Continuous, as soon as the receiver is enabled, and immediately after the end of transfer of the previous data. +#define AT91C_SSC_START_TX (0x1 << 8) // (SSC) Transmit/Receive start +#define AT91C_SSC_START_LOW_RF (0x2 << 8) // (SSC) Detection of a low level on RF input +#define AT91C_SSC_START_HIGH_RF (0x3 << 8) // (SSC) Detection of a high level on RF input +#define AT91C_SSC_START_FALL_RF (0x4 << 8) // (SSC) Detection of a falling edge on RF input +#define AT91C_SSC_START_RISE_RF (0x5 << 8) // (SSC) Detection of a rising edge on RF input +#define AT91C_SSC_START_LEVEL_RF (0x6 << 8) // (SSC) Detection of any level change on RF input +#define AT91C_SSC_START_EDGE_RF (0x7 << 8) // (SSC) Detection of any edge on RF input +#define AT91C_SSC_START_0 (0x8 << 8) // (SSC) Compare 0 #define AT91C_SSC_STTDLY (0xFF << 16) // (SSC) Receive/Transmit Start Delay #define AT91C_SSC_PERIOD (0xFF << 24) // (SSC) Receive/Transmit Period Divider Selection // -------- SSC_RFMR : (SSC Offset: 0x14) SSC Receive Frame Mode Register -------- @@ -1161,12 +1161,12 @@ typedef struct _AT91S_SSC { #define AT91C_SSC_DATNB (0xF << 8) // (SSC) Data Number per Frame #define AT91C_SSC_FSLEN (0xF << 16) // (SSC) Receive/Transmit Frame Sync length #define AT91C_SSC_FSOS (0x7 << 20) // (SSC) Receive/Transmit Frame Sync Output Selection -#define AT91C_SSC_FSOS_NONE (0x0 << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: None RK pin Input-only -#define AT91C_SSC_FSOS_NEGATIVE (0x1 << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: Negative Pulse -#define AT91C_SSC_FSOS_POSITIVE (0x2 << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: Positive Pulse -#define AT91C_SSC_FSOS_LOW (0x3 << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: Driver Low during data transfer -#define AT91C_SSC_FSOS_HIGH (0x4 << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: Driver High during data transfer -#define AT91C_SSC_FSOS_TOGGLE (0x5 << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: Toggling at each start of data transfer +#define AT91C_SSC_FSOS_NONE (0x0 << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: None RK pin Input-only +#define AT91C_SSC_FSOS_NEGATIVE (0x1 << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: Negative Pulse +#define AT91C_SSC_FSOS_POSITIVE (0x2 << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: Positive Pulse +#define AT91C_SSC_FSOS_LOW (0x3 << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: Driver Low during data transfer +#define AT91C_SSC_FSOS_HIGH (0x4 << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: Driver High during data transfer +#define AT91C_SSC_FSOS_TOGGLE (0x5 << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: Toggling at each start of data transfer #define AT91C_SSC_FSEDGE (0x1 << 24) // (SSC) Frame Sync Edge Detection // -------- SSC_TCMR : (SSC Offset: 0x18) SSC Transmit Clock Mode Register -------- // -------- SSC_TFMR : (SSC Offset: 0x1c) SSC Transmit Frame Mode Register -------- @@ -1194,49 +1194,49 @@ typedef struct _AT91S_SSC { // ***************************************************************************** #ifndef __ASSEMBLY__ typedef struct _AT91S_USART { - AT91_REG US_CR; // Control Register - AT91_REG US_MR; // Mode Register - AT91_REG US_IER; // Interrupt Enable Register - AT91_REG US_IDR; // Interrupt Disable Register - AT91_REG US_IMR; // Interrupt Mask Register - AT91_REG US_CSR; // Channel Status Register - AT91_REG US_RHR; // Receiver Holding Register - AT91_REG US_THR; // Transmitter Holding Register - AT91_REG US_BRGR; // Baud Rate Generator Register - AT91_REG US_RTOR; // Receiver Time-out Register - AT91_REG US_TTGR; // Transmitter Time-guard Register - AT91_REG Reserved0[5]; // - AT91_REG US_FIDI; // FI_DI_Ratio Register - AT91_REG US_NER; // Nb Errors Register - AT91_REG Reserved1[1]; // - AT91_REG US_IF; // IRDA_FILTER Register - AT91_REG Reserved2[44]; // - AT91_REG US_RPR; // Receive Pointer Register - AT91_REG US_RCR; // Receive Counter Register - AT91_REG US_TPR; // Transmit Pointer Register - AT91_REG US_TCR; // Transmit Counter Register - AT91_REG US_RNPR; // Receive Next Pointer Register - AT91_REG US_RNCR; // Receive Next Counter Register - AT91_REG US_TNPR; // Transmit Next Pointer Register - AT91_REG US_TNCR; // Transmit Next Counter Register - AT91_REG US_PTCR; // PDC Transfer Control Register - AT91_REG US_PTSR; // PDC Transfer Status Register + AT91_REG US_CR; // Control Register + AT91_REG US_MR; // Mode Register + AT91_REG US_IER; // Interrupt Enable Register + AT91_REG US_IDR; // Interrupt Disable Register + AT91_REG US_IMR; // Interrupt Mask Register + AT91_REG US_CSR; // Channel Status Register + AT91_REG US_RHR; // Receiver Holding Register + AT91_REG US_THR; // Transmitter Holding Register + AT91_REG US_BRGR; // Baud Rate Generator Register + AT91_REG US_RTOR; // Receiver Time-out Register + AT91_REG US_TTGR; // Transmitter Time-guard Register + AT91_REG Reserved0[5]; // + AT91_REG US_FIDI; // FI_DI_Ratio Register + AT91_REG US_NER; // Nb Errors Register + AT91_REG Reserved1[1]; // + AT91_REG US_IF; // IRDA_FILTER Register + AT91_REG Reserved2[44]; // + AT91_REG US_RPR; // Receive Pointer Register + AT91_REG US_RCR; // Receive Counter Register + AT91_REG US_TPR; // Transmit Pointer Register + AT91_REG US_TCR; // Transmit Counter Register + AT91_REG US_RNPR; // Receive Next Pointer Register + AT91_REG US_RNCR; // Receive Next Counter Register + AT91_REG US_TNPR; // Transmit Next Pointer Register + AT91_REG US_TNCR; // Transmit Next Counter Register + AT91_REG US_PTCR; // PDC Transfer Control Register + AT91_REG US_PTSR; // PDC Transfer Status Register } AT91S_USART, *AT91PS_USART; #else -#define US_CR (AT91_CAST(AT91_REG *) 0x00000000) // (US_CR) Control Register -#define US_MR (AT91_CAST(AT91_REG *) 0x00000004) // (US_MR) Mode Register -#define US_IER (AT91_CAST(AT91_REG *) 0x00000008) // (US_IER) Interrupt Enable Register -#define US_IDR (AT91_CAST(AT91_REG *) 0x0000000C) // (US_IDR) Interrupt Disable Register -#define US_IMR (AT91_CAST(AT91_REG *) 0x00000010) // (US_IMR) Interrupt Mask Register -#define US_CSR (AT91_CAST(AT91_REG *) 0x00000014) // (US_CSR) Channel Status Register -#define US_RHR (AT91_CAST(AT91_REG *) 0x00000018) // (US_RHR) Receiver Holding Register -#define US_THR (AT91_CAST(AT91_REG *) 0x0000001C) // (US_THR) Transmitter Holding Register -#define US_BRGR (AT91_CAST(AT91_REG *) 0x00000020) // (US_BRGR) Baud Rate Generator Register -#define US_RTOR (AT91_CAST(AT91_REG *) 0x00000024) // (US_RTOR) Receiver Time-out Register -#define US_TTGR (AT91_CAST(AT91_REG *) 0x00000028) // (US_TTGR) Transmitter Time-guard Register -#define US_FIDI (AT91_CAST(AT91_REG *) 0x00000040) // (US_FIDI) FI_DI_Ratio Register -#define US_NER (AT91_CAST(AT91_REG *) 0x00000044) // (US_NER) Nb Errors Register -#define US_IF (AT91_CAST(AT91_REG *) 0x0000004C) // (US_IF) IRDA_FILTER Register +#define US_CR (AT91_CAST(AT91_REG *) 0x00000000) // (US_CR) Control Register +#define US_MR (AT91_CAST(AT91_REG *) 0x00000004) // (US_MR) Mode Register +#define US_IER (AT91_CAST(AT91_REG *) 0x00000008) // (US_IER) Interrupt Enable Register +#define US_IDR (AT91_CAST(AT91_REG *) 0x0000000C) // (US_IDR) Interrupt Disable Register +#define US_IMR (AT91_CAST(AT91_REG *) 0x00000010) // (US_IMR) Interrupt Mask Register +#define US_CSR (AT91_CAST(AT91_REG *) 0x00000014) // (US_CSR) Channel Status Register +#define US_RHR (AT91_CAST(AT91_REG *) 0x00000018) // (US_RHR) Receiver Holding Register +#define US_THR (AT91_CAST(AT91_REG *) 0x0000001C) // (US_THR) Transmitter Holding Register +#define US_BRGR (AT91_CAST(AT91_REG *) 0x00000020) // (US_BRGR) Baud Rate Generator Register +#define US_RTOR (AT91_CAST(AT91_REG *) 0x00000024) // (US_RTOR) Receiver Time-out Register +#define US_TTGR (AT91_CAST(AT91_REG *) 0x00000028) // (US_TTGR) Transmitter Time-guard Register +#define US_FIDI (AT91_CAST(AT91_REG *) 0x00000040) // (US_FIDI) FI_DI_Ratio Register +#define US_NER (AT91_CAST(AT91_REG *) 0x00000044) // (US_NER) Nb Errors Register +#define US_IF (AT91_CAST(AT91_REG *) 0x0000004C) // (US_IF) IRDA_FILTER Register #endif // -------- US_CR : (USART Offset: 0x0) Debug Unit Control Register -------- @@ -1253,29 +1253,29 @@ typedef struct _AT91S_USART { #define AT91C_US_RTSDIS (0x1 << 19) // (USART) Request to Send Disable // -------- US_MR : (USART Offset: 0x4) Debug Unit Mode Register -------- #define AT91C_US_USMODE (0xF << 0) // (USART) Usart mode -#define AT91C_US_USMODE_NORMAL (0x0) // (USART) Normal -#define AT91C_US_USMODE_RS485 (0x1) // (USART) RS485 -#define AT91C_US_USMODE_HWHSH (0x2) // (USART) Hardware Handshaking -#define AT91C_US_USMODE_MODEM (0x3) // (USART) Modem -#define AT91C_US_USMODE_ISO7816_0 (0x4) // (USART) ISO7816 protocol: T = 0 -#define AT91C_US_USMODE_ISO7816_1 (0x6) // (USART) ISO7816 protocol: T = 1 -#define AT91C_US_USMODE_IRDA (0x8) // (USART) IrDA -#define AT91C_US_USMODE_SWHSH (0xC) // (USART) Software Handshaking +#define AT91C_US_USMODE_NORMAL (0x0) // (USART) Normal +#define AT91C_US_USMODE_RS485 (0x1) // (USART) RS485 +#define AT91C_US_USMODE_HWHSH (0x2) // (USART) Hardware Handshaking +#define AT91C_US_USMODE_MODEM (0x3) // (USART) Modem +#define AT91C_US_USMODE_ISO7816_0 (0x4) // (USART) ISO7816 protocol: T = 0 +#define AT91C_US_USMODE_ISO7816_1 (0x6) // (USART) ISO7816 protocol: T = 1 +#define AT91C_US_USMODE_IRDA (0x8) // (USART) IrDA +#define AT91C_US_USMODE_SWHSH (0xC) // (USART) Software Handshaking #define AT91C_US_CLKS (0x3 << 4) // (USART) Clock Selection (Baud Rate generator Input Clock -#define AT91C_US_CLKS_CLOCK (0x0 << 4) // (USART) Clock -#define AT91C_US_CLKS_FDIV1 (0x1 << 4) // (USART) fdiv1 -#define AT91C_US_CLKS_SLOW (0x2 << 4) // (USART) slow_clock (ARM) -#define AT91C_US_CLKS_EXT (0x3 << 4) // (USART) External (SCK) +#define AT91C_US_CLKS_CLOCK (0x0 << 4) // (USART) Clock +#define AT91C_US_CLKS_FDIV1 (0x1 << 4) // (USART) fdiv1 +#define AT91C_US_CLKS_SLOW (0x2 << 4) // (USART) slow_clock (ARM) +#define AT91C_US_CLKS_EXT (0x3 << 4) // (USART) External (SCK) #define AT91C_US_CHRL (0x3 << 6) // (USART) Clock Selection (Baud Rate generator Input Clock -#define AT91C_US_CHRL_5_BITS (0x0 << 6) // (USART) Character Length: 5 bits -#define AT91C_US_CHRL_6_BITS (0x1 << 6) // (USART) Character Length: 6 bits -#define AT91C_US_CHRL_7_BITS (0x2 << 6) // (USART) Character Length: 7 bits -#define AT91C_US_CHRL_8_BITS (0x3 << 6) // (USART) Character Length: 8 bits +#define AT91C_US_CHRL_5_BITS (0x0 << 6) // (USART) Character Length: 5 bits +#define AT91C_US_CHRL_6_BITS (0x1 << 6) // (USART) Character Length: 6 bits +#define AT91C_US_CHRL_7_BITS (0x2 << 6) // (USART) Character Length: 7 bits +#define AT91C_US_CHRL_8_BITS (0x3 << 6) // (USART) Character Length: 8 bits #define AT91C_US_SYNC (0x1 << 8) // (USART) Synchronous Mode Select #define AT91C_US_NBSTOP (0x3 << 12) // (USART) Number of Stop bits -#define AT91C_US_NBSTOP_1_BIT (0x0 << 12) // (USART) 1 stop bit -#define AT91C_US_NBSTOP_15_BIT (0x1 << 12) // (USART) Asynchronous (SYNC=0) 2 stop bits Synchronous (SYNC=1) 2 stop bits -#define AT91C_US_NBSTOP_2_BIT (0x2 << 12) // (USART) 2 stop bits +#define AT91C_US_NBSTOP_1_BIT (0x0 << 12) // (USART) 1 stop bit +#define AT91C_US_NBSTOP_15_BIT (0x1 << 12) // (USART) Asynchronous (SYNC=0) 2 stop bits Synchronous (SYNC=1) 2 stop bits +#define AT91C_US_NBSTOP_2_BIT (0x2 << 12) // (USART) 2 stop bits #define AT91C_US_MSBF (0x1 << 16) // (USART) Bit Order #define AT91C_US_MODE9 (0x1 << 17) // (USART) 9-bit Character length #define AT91C_US_CKLO (0x1 << 18) // (USART) Clock Output Select @@ -1306,41 +1306,41 @@ typedef struct _AT91S_USART { // ***************************************************************************** #ifndef __ASSEMBLY__ typedef struct _AT91S_TWI { - AT91_REG TWI_CR; // Control Register - AT91_REG TWI_MMR; // Master Mode Register - AT91_REG Reserved0[1]; // - AT91_REG TWI_IADR; // Internal Address Register - AT91_REG TWI_CWGR; // Clock Waveform Generator Register - AT91_REG Reserved1[3]; // - AT91_REG TWI_SR; // Status Register - AT91_REG TWI_IER; // Interrupt Enable Register - AT91_REG TWI_IDR; // Interrupt Disable Register - AT91_REG TWI_IMR; // Interrupt Mask Register - AT91_REG TWI_RHR; // Receive Holding Register - AT91_REG TWI_THR; // Transmit Holding Register - AT91_REG Reserved2[50]; // - AT91_REG TWI_RPR; // Receive Pointer Register - AT91_REG TWI_RCR; // Receive Counter Register - AT91_REG TWI_TPR; // Transmit Pointer Register - AT91_REG TWI_TCR; // Transmit Counter Register - AT91_REG TWI_RNPR; // Receive Next Pointer Register - AT91_REG TWI_RNCR; // Receive Next Counter Register - AT91_REG TWI_TNPR; // Transmit Next Pointer Register - AT91_REG TWI_TNCR; // Transmit Next Counter Register - AT91_REG TWI_PTCR; // PDC Transfer Control Register - AT91_REG TWI_PTSR; // PDC Transfer Status Register + AT91_REG TWI_CR; // Control Register + AT91_REG TWI_MMR; // Master Mode Register + AT91_REG Reserved0[1]; // + AT91_REG TWI_IADR; // Internal Address Register + AT91_REG TWI_CWGR; // Clock Waveform Generator Register + AT91_REG Reserved1[3]; // + AT91_REG TWI_SR; // Status Register + AT91_REG TWI_IER; // Interrupt Enable Register + AT91_REG TWI_IDR; // Interrupt Disable Register + AT91_REG TWI_IMR; // Interrupt Mask Register + AT91_REG TWI_RHR; // Receive Holding Register + AT91_REG TWI_THR; // Transmit Holding Register + AT91_REG Reserved2[50]; // + AT91_REG TWI_RPR; // Receive Pointer Register + AT91_REG TWI_RCR; // Receive Counter Register + AT91_REG TWI_TPR; // Transmit Pointer Register + AT91_REG TWI_TCR; // Transmit Counter Register + AT91_REG TWI_RNPR; // Receive Next Pointer Register + AT91_REG TWI_RNCR; // Receive Next Counter Register + AT91_REG TWI_TNPR; // Transmit Next Pointer Register + AT91_REG TWI_TNCR; // Transmit Next Counter Register + AT91_REG TWI_PTCR; // PDC Transfer Control Register + AT91_REG TWI_PTSR; // PDC Transfer Status Register } AT91S_TWI, *AT91PS_TWI; #else -#define TWI_CR (AT91_CAST(AT91_REG *) 0x00000000) // (TWI_CR) Control Register -#define TWI_MMR (AT91_CAST(AT91_REG *) 0x00000004) // (TWI_MMR) Master Mode Register -#define TWI_IADR (AT91_CAST(AT91_REG *) 0x0000000C) // (TWI_IADR) Internal Address Register -#define TWI_CWGR (AT91_CAST(AT91_REG *) 0x00000010) // (TWI_CWGR) Clock Waveform Generator Register -#define TWI_SR (AT91_CAST(AT91_REG *) 0x00000020) // (TWI_SR) Status Register -#define TWI_IER (AT91_CAST(AT91_REG *) 0x00000024) // (TWI_IER) Interrupt Enable Register -#define TWI_IDR (AT91_CAST(AT91_REG *) 0x00000028) // (TWI_IDR) Interrupt Disable Register -#define TWI_IMR (AT91_CAST(AT91_REG *) 0x0000002C) // (TWI_IMR) Interrupt Mask Register -#define TWI_RHR (AT91_CAST(AT91_REG *) 0x00000030) // (TWI_RHR) Receive Holding Register -#define TWI_THR (AT91_CAST(AT91_REG *) 0x00000034) // (TWI_THR) Transmit Holding Register +#define TWI_CR (AT91_CAST(AT91_REG *) 0x00000000) // (TWI_CR) Control Register +#define TWI_MMR (AT91_CAST(AT91_REG *) 0x00000004) // (TWI_MMR) Master Mode Register +#define TWI_IADR (AT91_CAST(AT91_REG *) 0x0000000C) // (TWI_IADR) Internal Address Register +#define TWI_CWGR (AT91_CAST(AT91_REG *) 0x00000010) // (TWI_CWGR) Clock Waveform Generator Register +#define TWI_SR (AT91_CAST(AT91_REG *) 0x00000020) // (TWI_SR) Status Register +#define TWI_IER (AT91_CAST(AT91_REG *) 0x00000024) // (TWI_IER) Interrupt Enable Register +#define TWI_IDR (AT91_CAST(AT91_REG *) 0x00000028) // (TWI_IDR) Interrupt Disable Register +#define TWI_IMR (AT91_CAST(AT91_REG *) 0x0000002C) // (TWI_IMR) Interrupt Mask Register +#define TWI_RHR (AT91_CAST(AT91_REG *) 0x00000030) // (TWI_RHR) Receive Holding Register +#define TWI_THR (AT91_CAST(AT91_REG *) 0x00000034) // (TWI_THR) Transmit Holding Register #endif // -------- TWI_CR : (TWI Offset: 0x0) TWI Control Register -------- @@ -1351,10 +1351,10 @@ typedef struct _AT91S_TWI { #define AT91C_TWI_SWRST (0x1 << 7) // (TWI) Software Reset // -------- TWI_MMR : (TWI Offset: 0x4) TWI Master Mode Register -------- #define AT91C_TWI_IADRSZ (0x3 << 8) // (TWI) Internal Device Address Size -#define AT91C_TWI_IADRSZ_NO (0x0 << 8) // (TWI) No internal device address -#define AT91C_TWI_IADRSZ_1_BYTE (0x1 << 8) // (TWI) One-byte internal device address -#define AT91C_TWI_IADRSZ_2_BYTE (0x2 << 8) // (TWI) Two-byte internal device address -#define AT91C_TWI_IADRSZ_3_BYTE (0x3 << 8) // (TWI) Three-byte internal device address +#define AT91C_TWI_IADRSZ_NO (0x0 << 8) // (TWI) No internal device address +#define AT91C_TWI_IADRSZ_1_BYTE (0x1 << 8) // (TWI) One-byte internal device address +#define AT91C_TWI_IADRSZ_2_BYTE (0x2 << 8) // (TWI) Two-byte internal device address +#define AT91C_TWI_IADRSZ_3_BYTE (0x3 << 8) // (TWI) Three-byte internal device address #define AT91C_TWI_MREAD (0x1 << 12) // (TWI) Master Read Direction #define AT91C_TWI_DADR (0x7F << 16) // (TWI) Device Address // -------- TWI_CWGR : (TWI Offset: 0x10) TWI Clock Waveform Generator Register -------- @@ -1381,29 +1381,29 @@ typedef struct _AT91S_TWI { // ***************************************************************************** #ifndef __ASSEMBLY__ typedef struct _AT91S_TC { - AT91_REG TC_CCR; // Channel Control Register - AT91_REG TC_CMR; // Channel Mode Register (Capture Mode / Waveform Mode) - AT91_REG Reserved0[2]; // - AT91_REG TC_CV; // Counter Value - AT91_REG TC_RA; // Register A - AT91_REG TC_RB; // Register B - AT91_REG TC_RC; // Register C - AT91_REG TC_SR; // Status Register - AT91_REG TC_IER; // Interrupt Enable Register - AT91_REG TC_IDR; // Interrupt Disable Register - AT91_REG TC_IMR; // Interrupt Mask Register + AT91_REG TC_CCR; // Channel Control Register + AT91_REG TC_CMR; // Channel Mode Register (Capture Mode / Waveform Mode) + AT91_REG Reserved0[2]; // + AT91_REG TC_CV; // Counter Value + AT91_REG TC_RA; // Register A + AT91_REG TC_RB; // Register B + AT91_REG TC_RC; // Register C + AT91_REG TC_SR; // Status Register + AT91_REG TC_IER; // Interrupt Enable Register + AT91_REG TC_IDR; // Interrupt Disable Register + AT91_REG TC_IMR; // Interrupt Mask Register } AT91S_TC, *AT91PS_TC; #else -#define TC_CCR (AT91_CAST(AT91_REG *) 0x00000000) // (TC_CCR) Channel Control Register -#define TC_CMR (AT91_CAST(AT91_REG *) 0x00000004) // (TC_CMR) Channel Mode Register (Capture Mode / Waveform Mode) -#define TC_CV (AT91_CAST(AT91_REG *) 0x00000010) // (TC_CV) Counter Value -#define TC_RA (AT91_CAST(AT91_REG *) 0x00000014) // (TC_RA) Register A -#define TC_RB (AT91_CAST(AT91_REG *) 0x00000018) // (TC_RB) Register B -#define TC_RC (AT91_CAST(AT91_REG *) 0x0000001C) // (TC_RC) Register C -#define TC_SR (AT91_CAST(AT91_REG *) 0x00000020) // (TC_SR) Status Register -#define TC_IER (AT91_CAST(AT91_REG *) 0x00000024) // (TC_IER) Interrupt Enable Register -#define TC_IDR (AT91_CAST(AT91_REG *) 0x00000028) // (TC_IDR) Interrupt Disable Register -#define TC_IMR (AT91_CAST(AT91_REG *) 0x0000002C) // (TC_IMR) Interrupt Mask Register +#define TC_CCR (AT91_CAST(AT91_REG *) 0x00000000) // (TC_CCR) Channel Control Register +#define TC_CMR (AT91_CAST(AT91_REG *) 0x00000004) // (TC_CMR) Channel Mode Register (Capture Mode / Waveform Mode) +#define TC_CV (AT91_CAST(AT91_REG *) 0x00000010) // (TC_CV) Counter Value +#define TC_RA (AT91_CAST(AT91_REG *) 0x00000014) // (TC_RA) Register A +#define TC_RB (AT91_CAST(AT91_REG *) 0x00000018) // (TC_RB) Register B +#define TC_RC (AT91_CAST(AT91_REG *) 0x0000001C) // (TC_RC) Register C +#define TC_SR (AT91_CAST(AT91_REG *) 0x00000020) // (TC_SR) Status Register +#define TC_IER (AT91_CAST(AT91_REG *) 0x00000024) // (TC_IER) Interrupt Enable Register +#define TC_IDR (AT91_CAST(AT91_REG *) 0x00000028) // (TC_IDR) Interrupt Disable Register +#define TC_IMR (AT91_CAST(AT91_REG *) 0x0000002C) // (TC_IMR) Interrupt Mask Register #endif // -------- TC_CCR : (TC Offset: 0x0) TC Channel Control Register -------- @@ -1525,65 +1525,65 @@ typedef struct _AT91S_TC { // ***************************************************************************** #ifndef __ASSEMBLY__ typedef struct _AT91S_TCB { - AT91S_TC TCB_TC0; // TC Channel 0 - AT91_REG Reserved0[4]; // - AT91S_TC TCB_TC1; // TC Channel 1 - AT91_REG Reserved1[4]; // - AT91S_TC TCB_TC2; // TC Channel 2 - AT91_REG Reserved2[4]; // - AT91_REG TCB_BCR; // TC Block Control Register - AT91_REG TCB_BMR; // TC Block Mode Register + AT91S_TC TCB_TC0; // TC Channel 0 + AT91_REG Reserved0[4]; // + AT91S_TC TCB_TC1; // TC Channel 1 + AT91_REG Reserved1[4]; // + AT91S_TC TCB_TC2; // TC Channel 2 + AT91_REG Reserved2[4]; // + AT91_REG TCB_BCR; // TC Block Control Register + AT91_REG TCB_BMR; // TC Block Mode Register } AT91S_TCB, *AT91PS_TCB; #else -#define TCB_BCR (AT91_CAST(AT91_REG *) 0x000000C0) // (TCB_BCR) TC Block Control Register -#define TCB_BMR (AT91_CAST(AT91_REG *) 0x000000C4) // (TCB_BMR) TC Block Mode Register +#define TCB_BCR (AT91_CAST(AT91_REG *) 0x000000C0) // (TCB_BCR) TC Block Control Register +#define TCB_BMR (AT91_CAST(AT91_REG *) 0x000000C4) // (TCB_BMR) TC Block Mode Register #endif // -------- TCB_BCR : (TCB Offset: 0xc0) TC Block Control Register -------- #define AT91C_TCB_SYNC (0x1 << 0) // (TCB) Synchro Command // -------- TCB_BMR : (TCB Offset: 0xc4) TC Block Mode Register -------- #define AT91C_TCB_TC0XC0S (0x3 << 0) // (TCB) External Clock Signal 0 Selection -#define AT91C_TCB_TC0XC0S_TCLK0 (0x0) // (TCB) TCLK0 connected to XC0 -#define AT91C_TCB_TC0XC0S_NONE (0x1) // (TCB) None signal connected to XC0 -#define AT91C_TCB_TC0XC0S_TIOA1 (0x2) // (TCB) TIOA1 connected to XC0 -#define AT91C_TCB_TC0XC0S_TIOA2 (0x3) // (TCB) TIOA2 connected to XC0 +#define AT91C_TCB_TC0XC0S_TCLK0 (0x0) // (TCB) TCLK0 connected to XC0 +#define AT91C_TCB_TC0XC0S_NONE (0x1) // (TCB) None signal connected to XC0 +#define AT91C_TCB_TC0XC0S_TIOA1 (0x2) // (TCB) TIOA1 connected to XC0 +#define AT91C_TCB_TC0XC0S_TIOA2 (0x3) // (TCB) TIOA2 connected to XC0 #define AT91C_TCB_TC1XC1S (0x3 << 2) // (TCB) External Clock Signal 1 Selection -#define AT91C_TCB_TC1XC1S_TCLK1 (0x0 << 2) // (TCB) TCLK1 connected to XC1 -#define AT91C_TCB_TC1XC1S_NONE (0x1 << 2) // (TCB) None signal connected to XC1 -#define AT91C_TCB_TC1XC1S_TIOA0 (0x2 << 2) // (TCB) TIOA0 connected to XC1 -#define AT91C_TCB_TC1XC1S_TIOA2 (0x3 << 2) // (TCB) TIOA2 connected to XC1 +#define AT91C_TCB_TC1XC1S_TCLK1 (0x0 << 2) // (TCB) TCLK1 connected to XC1 +#define AT91C_TCB_TC1XC1S_NONE (0x1 << 2) // (TCB) None signal connected to XC1 +#define AT91C_TCB_TC1XC1S_TIOA0 (0x2 << 2) // (TCB) TIOA0 connected to XC1 +#define AT91C_TCB_TC1XC1S_TIOA2 (0x3 << 2) // (TCB) TIOA2 connected to XC1 #define AT91C_TCB_TC2XC2S (0x3 << 4) // (TCB) External Clock Signal 2 Selection -#define AT91C_TCB_TC2XC2S_TCLK2 (0x0 << 4) // (TCB) TCLK2 connected to XC2 -#define AT91C_TCB_TC2XC2S_NONE (0x1 << 4) // (TCB) None signal connected to XC2 -#define AT91C_TCB_TC2XC2S_TIOA0 (0x2 << 4) // (TCB) TIOA0 connected to XC2 -#define AT91C_TCB_TC2XC2S_TIOA1 (0x3 << 4) // (TCB) TIOA2 connected to XC2 +#define AT91C_TCB_TC2XC2S_TCLK2 (0x0 << 4) // (TCB) TCLK2 connected to XC2 +#define AT91C_TCB_TC2XC2S_NONE (0x1 << 4) // (TCB) None signal connected to XC2 +#define AT91C_TCB_TC2XC2S_TIOA0 (0x2 << 4) // (TCB) TIOA0 connected to XC2 +#define AT91C_TCB_TC2XC2S_TIOA1 (0x3 << 4) // (TCB) TIOA2 connected to XC2 // ***************************************************************************** // SOFTWARE API DEFINITION FOR PWMC Channel Interface // ***************************************************************************** #ifndef __ASSEMBLY__ typedef struct _AT91S_PWMC_CH { - AT91_REG PWMC_CMR; // Channel Mode Register - AT91_REG PWMC_CDTYR; // Channel Duty Cycle Register - AT91_REG PWMC_CPRDR; // Channel Period Register - AT91_REG PWMC_CCNTR; // Channel Counter Register - AT91_REG PWMC_CUPDR; // Channel Update Register - AT91_REG PWMC_Reserved[3]; // Reserved + AT91_REG PWMC_CMR; // Channel Mode Register + AT91_REG PWMC_CDTYR; // Channel Duty Cycle Register + AT91_REG PWMC_CPRDR; // Channel Period Register + AT91_REG PWMC_CCNTR; // Channel Counter Register + AT91_REG PWMC_CUPDR; // Channel Update Register + AT91_REG PWMC_Reserved[3]; // Reserved } AT91S_PWMC_CH, *AT91PS_PWMC_CH; #else -#define PWMC_CMR (AT91_CAST(AT91_REG *) 0x00000000) // (PWMC_CMR) Channel Mode Register -#define PWMC_CDTYR (AT91_CAST(AT91_REG *) 0x00000004) // (PWMC_CDTYR) Channel Duty Cycle Register -#define PWMC_CPRDR (AT91_CAST(AT91_REG *) 0x00000008) // (PWMC_CPRDR) Channel Period Register -#define PWMC_CCNTR (AT91_CAST(AT91_REG *) 0x0000000C) // (PWMC_CCNTR) Channel Counter Register -#define PWMC_CUPDR (AT91_CAST(AT91_REG *) 0x00000010) // (PWMC_CUPDR) Channel Update Register -#define Reserved (AT91_CAST(AT91_REG *) 0x00000014) // (Reserved) Reserved +#define PWMC_CMR (AT91_CAST(AT91_REG *) 0x00000000) // (PWMC_CMR) Channel Mode Register +#define PWMC_CDTYR (AT91_CAST(AT91_REG *) 0x00000004) // (PWMC_CDTYR) Channel Duty Cycle Register +#define PWMC_CPRDR (AT91_CAST(AT91_REG *) 0x00000008) // (PWMC_CPRDR) Channel Period Register +#define PWMC_CCNTR (AT91_CAST(AT91_REG *) 0x0000000C) // (PWMC_CCNTR) Channel Counter Register +#define PWMC_CUPDR (AT91_CAST(AT91_REG *) 0x00000010) // (PWMC_CUPDR) Channel Update Register +#define Reserved (AT91_CAST(AT91_REG *) 0x00000014) // (Reserved) Reserved #endif // -------- PWMC_CMR : (PWMC_CH Offset: 0x0) PWMC Channel Mode Register -------- #define AT91C_PWMC_CPRE (0xF << 0) // (PWMC_CH) Channel Pre-scaler : PWMC_CLKx -#define AT91C_PWMC_CPRE_MCK (0x0) // (PWMC_CH) -#define AT91C_PWMC_CPRE_MCKA (0xB) // (PWMC_CH) -#define AT91C_PWMC_CPRE_MCKB (0xC) // (PWMC_CH) +#define AT91C_PWMC_CPRE_MCK (0x0) // (PWMC_CH) +#define AT91C_PWMC_CPRE_MCKA (0xB) // (PWMC_CH) +#define AT91C_PWMC_CPRE_MCKB (0xC) // (PWMC_CH) #define AT91C_PWMC_CALG (0x1 << 8) // (PWMC_CH) Channel Alignment #define AT91C_PWMC_CPOL (0x1 << 9) // (PWMC_CH) Channel Polarity #define AT91C_PWMC_CPD (0x1 << 10) // (PWMC_CH) Channel Update Period @@ -1601,38 +1601,38 @@ typedef struct _AT91S_PWMC_CH { // ***************************************************************************** #ifndef __ASSEMBLY__ typedef struct _AT91S_PWMC { - AT91_REG PWMC_MR; // PWMC Mode Register - AT91_REG PWMC_ENA; // PWMC Enable Register - AT91_REG PWMC_DIS; // PWMC Disable Register - AT91_REG PWMC_SR; // PWMC Status Register - AT91_REG PWMC_IER; // PWMC Interrupt Enable Register - AT91_REG PWMC_IDR; // PWMC Interrupt Disable Register - AT91_REG PWMC_IMR; // PWMC Interrupt Mask Register - AT91_REG PWMC_ISR; // PWMC Interrupt Status Register - AT91_REG Reserved0[55]; // - AT91_REG PWMC_VR; // PWMC Version Register - AT91_REG Reserved1[64]; // - AT91S_PWMC_CH PWMC_CH[4]; // PWMC Channel + AT91_REG PWMC_MR; // PWMC Mode Register + AT91_REG PWMC_ENA; // PWMC Enable Register + AT91_REG PWMC_DIS; // PWMC Disable Register + AT91_REG PWMC_SR; // PWMC Status Register + AT91_REG PWMC_IER; // PWMC Interrupt Enable Register + AT91_REG PWMC_IDR; // PWMC Interrupt Disable Register + AT91_REG PWMC_IMR; // PWMC Interrupt Mask Register + AT91_REG PWMC_ISR; // PWMC Interrupt Status Register + AT91_REG Reserved0[55]; // + AT91_REG PWMC_VR; // PWMC Version Register + AT91_REG Reserved1[64]; // + AT91S_PWMC_CH PWMC_CH[4]; // PWMC Channel } AT91S_PWMC, *AT91PS_PWMC; #else -#define PWMC_MR (AT91_CAST(AT91_REG *) 0x00000000) // (PWMC_MR) PWMC Mode Register -#define PWMC_ENA (AT91_CAST(AT91_REG *) 0x00000004) // (PWMC_ENA) PWMC Enable Register -#define PWMC_DIS (AT91_CAST(AT91_REG *) 0x00000008) // (PWMC_DIS) PWMC Disable Register -#define PWMC_SR (AT91_CAST(AT91_REG *) 0x0000000C) // (PWMC_SR) PWMC Status Register -#define PWMC_IER (AT91_CAST(AT91_REG *) 0x00000010) // (PWMC_IER) PWMC Interrupt Enable Register -#define PWMC_IDR (AT91_CAST(AT91_REG *) 0x00000014) // (PWMC_IDR) PWMC Interrupt Disable Register -#define PWMC_IMR (AT91_CAST(AT91_REG *) 0x00000018) // (PWMC_IMR) PWMC Interrupt Mask Register -#define PWMC_ISR (AT91_CAST(AT91_REG *) 0x0000001C) // (PWMC_ISR) PWMC Interrupt Status Register -#define PWMC_VR (AT91_CAST(AT91_REG *) 0x000000FC) // (PWMC_VR) PWMC Version Register +#define PWMC_MR (AT91_CAST(AT91_REG *) 0x00000000) // (PWMC_MR) PWMC Mode Register +#define PWMC_ENA (AT91_CAST(AT91_REG *) 0x00000004) // (PWMC_ENA) PWMC Enable Register +#define PWMC_DIS (AT91_CAST(AT91_REG *) 0x00000008) // (PWMC_DIS) PWMC Disable Register +#define PWMC_SR (AT91_CAST(AT91_REG *) 0x0000000C) // (PWMC_SR) PWMC Status Register +#define PWMC_IER (AT91_CAST(AT91_REG *) 0x00000010) // (PWMC_IER) PWMC Interrupt Enable Register +#define PWMC_IDR (AT91_CAST(AT91_REG *) 0x00000014) // (PWMC_IDR) PWMC Interrupt Disable Register +#define PWMC_IMR (AT91_CAST(AT91_REG *) 0x00000018) // (PWMC_IMR) PWMC Interrupt Mask Register +#define PWMC_ISR (AT91_CAST(AT91_REG *) 0x0000001C) // (PWMC_ISR) PWMC Interrupt Status Register +#define PWMC_VR (AT91_CAST(AT91_REG *) 0x000000FC) // (PWMC_VR) PWMC Version Register #endif // -------- PWMC_MR : (PWMC Offset: 0x0) PWMC Mode Register -------- #define AT91C_PWMC_DIVA (0xFF << 0) // (PWMC) CLKA divide factor. #define AT91C_PWMC_PREA (0xF << 8) // (PWMC) Divider Input Clock Prescaler A -#define AT91C_PWMC_PREA_MCK (0x0 << 8) // (PWMC) +#define AT91C_PWMC_PREA_MCK (0x0 << 8) // (PWMC) #define AT91C_PWMC_DIVB (0xFF << 16) // (PWMC) CLKB divide factor. #define AT91C_PWMC_PREB (0xF << 24) // (PWMC) Divider Input Clock Prescaler B -#define AT91C_PWMC_PREB_MCK (0x0 << 24) // (PWMC) +#define AT91C_PWMC_PREB_MCK (0x0 << 24) // (PWMC) // -------- PWMC_ENA : (PWMC Offset: 0x4) PWMC Enable Register -------- #define AT91C_PWMC_CHID0 (0x1 << 0) // (PWMC) Channel ID 0 #define AT91C_PWMC_CHID1 (0x1 << 1) // (PWMC) Channel ID 1 @@ -1650,37 +1650,37 @@ typedef struct _AT91S_PWMC { // ***************************************************************************** #ifndef __ASSEMBLY__ typedef struct _AT91S_UDP { - AT91_REG UDP_NUM; // Frame Number Register - AT91_REG UDP_GLBSTATE; // Global State Register - AT91_REG UDP_FADDR; // Function Address Register - AT91_REG Reserved0[1]; // - AT91_REG UDP_IER; // Interrupt Enable Register - AT91_REG UDP_IDR; // Interrupt Disable Register - AT91_REG UDP_IMR; // Interrupt Mask Register - AT91_REG UDP_ISR; // Interrupt Status Register - AT91_REG UDP_ICR; // Interrupt Clear Register - AT91_REG Reserved1[1]; // - AT91_REG UDP_RSTEP; // Reset Endpoint Register - AT91_REG Reserved2[1]; // - AT91_REG UDP_CSR[4]; // Endpoint Control and Status Register - AT91_REG Reserved3[4]; // - AT91_REG UDP_FDR[4]; // Endpoint FIFO Data Register - AT91_REG Reserved4[5]; // - AT91_REG UDP_TXVC; // Transceiver Control Register + AT91_REG UDP_NUM; // Frame Number Register + AT91_REG UDP_GLBSTATE; // Global State Register + AT91_REG UDP_FADDR; // Function Address Register + AT91_REG Reserved0[1]; // + AT91_REG UDP_IER; // Interrupt Enable Register + AT91_REG UDP_IDR; // Interrupt Disable Register + AT91_REG UDP_IMR; // Interrupt Mask Register + AT91_REG UDP_ISR; // Interrupt Status Register + AT91_REG UDP_ICR; // Interrupt Clear Register + AT91_REG Reserved1[1]; // + AT91_REG UDP_RSTEP; // Reset Endpoint Register + AT91_REG Reserved2[1]; // + AT91_REG UDP_CSR[4]; // Endpoint Control and Status Register + AT91_REG Reserved3[4]; // + AT91_REG UDP_FDR[4]; // Endpoint FIFO Data Register + AT91_REG Reserved4[5]; // + AT91_REG UDP_TXVC; // Transceiver Control Register } AT91S_UDP, *AT91PS_UDP; #else -#define UDP_FRM_NUM (AT91_CAST(AT91_REG *) 0x00000000) // (UDP_FRM_NUM) Frame Number Register -#define UDP_GLBSTATE (AT91_CAST(AT91_REG *) 0x00000004) // (UDP_GLBSTATE) Global State Register -#define UDP_FADDR (AT91_CAST(AT91_REG *) 0x00000008) // (UDP_FADDR) Function Address Register -#define UDP_IER (AT91_CAST(AT91_REG *) 0x00000010) // (UDP_IER) Interrupt Enable Register -#define UDP_IDR (AT91_CAST(AT91_REG *) 0x00000014) // (UDP_IDR) Interrupt Disable Register -#define UDP_IMR (AT91_CAST(AT91_REG *) 0x00000018) // (UDP_IMR) Interrupt Mask Register -#define UDP_ISR (AT91_CAST(AT91_REG *) 0x0000001C) // (UDP_ISR) Interrupt Status Register -#define UDP_ICR (AT91_CAST(AT91_REG *) 0x00000020) // (UDP_ICR) Interrupt Clear Register -#define UDP_RSTEP (AT91_CAST(AT91_REG *) 0x00000028) // (UDP_RSTEP) Reset Endpoint Register -#define UDP_CSR (AT91_CAST(AT91_REG *) 0x00000030) // (UDP_CSR) Endpoint Control and Status Register -#define UDP_FDR (AT91_CAST(AT91_REG *) 0x00000050) // (UDP_FDR) Endpoint FIFO Data Register -#define UDP_TXVC (AT91_CAST(AT91_REG *) 0x00000074) // (UDP_TXVC) Transceiver Control Register +#define UDP_FRM_NUM (AT91_CAST(AT91_REG *) 0x00000000) // (UDP_FRM_NUM) Frame Number Register +#define UDP_GLBSTATE (AT91_CAST(AT91_REG *) 0x00000004) // (UDP_GLBSTATE) Global State Register +#define UDP_FADDR (AT91_CAST(AT91_REG *) 0x00000008) // (UDP_FADDR) Function Address Register +#define UDP_IER (AT91_CAST(AT91_REG *) 0x00000010) // (UDP_IER) Interrupt Enable Register +#define UDP_IDR (AT91_CAST(AT91_REG *) 0x00000014) // (UDP_IDR) Interrupt Disable Register +#define UDP_IMR (AT91_CAST(AT91_REG *) 0x00000018) // (UDP_IMR) Interrupt Mask Register +#define UDP_ISR (AT91_CAST(AT91_REG *) 0x0000001C) // (UDP_ISR) Interrupt Status Register +#define UDP_ICR (AT91_CAST(AT91_REG *) 0x00000020) // (UDP_ICR) Interrupt Clear Register +#define UDP_RSTEP (AT91_CAST(AT91_REG *) 0x00000028) // (UDP_RSTEP) Reset Endpoint Register +#define UDP_CSR (AT91_CAST(AT91_REG *) 0x00000030) // (UDP_CSR) Endpoint Control and Status Register +#define UDP_FDR (AT91_CAST(AT91_REG *) 0x00000050) // (UDP_FDR) Endpoint FIFO Data Register +#define UDP_TXVC (AT91_CAST(AT91_REG *) 0x00000074) // (UDP_TXVC) Transceiver Control Register #endif // -------- UDP_FRM_NUM : (UDP Offset: 0x0) USB Frame Number Register -------- @@ -1745,362 +1745,362 @@ typedef struct _AT91S_UDP { // ***************************************************************************** // ========== Register definition for SYS peripheral ========== // ========== Register definition for AIC peripheral ========== -#define AT91C_AIC_IVR (AT91_CAST(AT91_REG *) 0xFFFFF100) // (AIC) IRQ Vector Register -#define AT91C_AIC_SMR (AT91_CAST(AT91_REG *) 0xFFFFF000) // (AIC) Source Mode Register -#define AT91C_AIC_FVR (AT91_CAST(AT91_REG *) 0xFFFFF104) // (AIC) FIQ Vector Register -#define AT91C_AIC_DCR (AT91_CAST(AT91_REG *) 0xFFFFF138) // (AIC) Debug Control Register (Protect) -#define AT91C_AIC_EOICR (AT91_CAST(AT91_REG *) 0xFFFFF130) // (AIC) End of Interrupt Command Register -#define AT91C_AIC_SVR (AT91_CAST(AT91_REG *) 0xFFFFF080) // (AIC) Source Vector Register -#define AT91C_AIC_FFSR (AT91_CAST(AT91_REG *) 0xFFFFF148) // (AIC) Fast Forcing Status Register -#define AT91C_AIC_ICCR (AT91_CAST(AT91_REG *) 0xFFFFF128) // (AIC) Interrupt Clear Command Register -#define AT91C_AIC_ISR (AT91_CAST(AT91_REG *) 0xFFFFF108) // (AIC) Interrupt Status Register -#define AT91C_AIC_IMR (AT91_CAST(AT91_REG *) 0xFFFFF110) // (AIC) Interrupt Mask Register -#define AT91C_AIC_IPR (AT91_CAST(AT91_REG *) 0xFFFFF10C) // (AIC) Interrupt Pending Register -#define AT91C_AIC_FFER (AT91_CAST(AT91_REG *) 0xFFFFF140) // (AIC) Fast Forcing Enable Register -#define AT91C_AIC_IECR (AT91_CAST(AT91_REG *) 0xFFFFF120) // (AIC) Interrupt Enable Command Register -#define AT91C_AIC_ISCR (AT91_CAST(AT91_REG *) 0xFFFFF12C) // (AIC) Interrupt Set Command Register -#define AT91C_AIC_FFDR (AT91_CAST(AT91_REG *) 0xFFFFF144) // (AIC) Fast Forcing Disable Register -#define AT91C_AIC_CISR (AT91_CAST(AT91_REG *) 0xFFFFF114) // (AIC) Core Interrupt Status Register -#define AT91C_AIC_IDCR (AT91_CAST(AT91_REG *) 0xFFFFF124) // (AIC) Interrupt Disable Command Register -#define AT91C_AIC_SPU (AT91_CAST(AT91_REG *) 0xFFFFF134) // (AIC) Spurious Vector Register +#define AT91C_AIC_IVR (AT91_CAST(AT91_REG *) 0xFFFFF100) // (AIC) IRQ Vector Register +#define AT91C_AIC_SMR (AT91_CAST(AT91_REG *) 0xFFFFF000) // (AIC) Source Mode Register +#define AT91C_AIC_FVR (AT91_CAST(AT91_REG *) 0xFFFFF104) // (AIC) FIQ Vector Register +#define AT91C_AIC_DCR (AT91_CAST(AT91_REG *) 0xFFFFF138) // (AIC) Debug Control Register (Protect) +#define AT91C_AIC_EOICR (AT91_CAST(AT91_REG *) 0xFFFFF130) // (AIC) End of Interrupt Command Register +#define AT91C_AIC_SVR (AT91_CAST(AT91_REG *) 0xFFFFF080) // (AIC) Source Vector Register +#define AT91C_AIC_FFSR (AT91_CAST(AT91_REG *) 0xFFFFF148) // (AIC) Fast Forcing Status Register +#define AT91C_AIC_ICCR (AT91_CAST(AT91_REG *) 0xFFFFF128) // (AIC) Interrupt Clear Command Register +#define AT91C_AIC_ISR (AT91_CAST(AT91_REG *) 0xFFFFF108) // (AIC) Interrupt Status Register +#define AT91C_AIC_IMR (AT91_CAST(AT91_REG *) 0xFFFFF110) // (AIC) Interrupt Mask Register +#define AT91C_AIC_IPR (AT91_CAST(AT91_REG *) 0xFFFFF10C) // (AIC) Interrupt Pending Register +#define AT91C_AIC_FFER (AT91_CAST(AT91_REG *) 0xFFFFF140) // (AIC) Fast Forcing Enable Register +#define AT91C_AIC_IECR (AT91_CAST(AT91_REG *) 0xFFFFF120) // (AIC) Interrupt Enable Command Register +#define AT91C_AIC_ISCR (AT91_CAST(AT91_REG *) 0xFFFFF12C) // (AIC) Interrupt Set Command Register +#define AT91C_AIC_FFDR (AT91_CAST(AT91_REG *) 0xFFFFF144) // (AIC) Fast Forcing Disable Register +#define AT91C_AIC_CISR (AT91_CAST(AT91_REG *) 0xFFFFF114) // (AIC) Core Interrupt Status Register +#define AT91C_AIC_IDCR (AT91_CAST(AT91_REG *) 0xFFFFF124) // (AIC) Interrupt Disable Command Register +#define AT91C_AIC_SPU (AT91_CAST(AT91_REG *) 0xFFFFF134) // (AIC) Spurious Vector Register // ========== Register definition for PDC_DBGU peripheral ========== -#define AT91C_DBGU_TCR (AT91_CAST(AT91_REG *) 0xFFFFF30C) // (PDC_DBGU) Transmit Counter Register -#define AT91C_DBGU_RNPR (AT91_CAST(AT91_REG *) 0xFFFFF310) // (PDC_DBGU) Receive Next Pointer Register -#define AT91C_DBGU_TNPR (AT91_CAST(AT91_REG *) 0xFFFFF318) // (PDC_DBGU) Transmit Next Pointer Register -#define AT91C_DBGU_TPR (AT91_CAST(AT91_REG *) 0xFFFFF308) // (PDC_DBGU) Transmit Pointer Register -#define AT91C_DBGU_RPR (AT91_CAST(AT91_REG *) 0xFFFFF300) // (PDC_DBGU) Receive Pointer Register -#define AT91C_DBGU_RCR (AT91_CAST(AT91_REG *) 0xFFFFF304) // (PDC_DBGU) Receive Counter Register -#define AT91C_DBGU_RNCR (AT91_CAST(AT91_REG *) 0xFFFFF314) // (PDC_DBGU) Receive Next Counter Register -#define AT91C_DBGU_PTCR (AT91_CAST(AT91_REG *) 0xFFFFF320) // (PDC_DBGU) PDC Transfer Control Register -#define AT91C_DBGU_PTSR (AT91_CAST(AT91_REG *) 0xFFFFF324) // (PDC_DBGU) PDC Transfer Status Register -#define AT91C_DBGU_TNCR (AT91_CAST(AT91_REG *) 0xFFFFF31C) // (PDC_DBGU) Transmit Next Counter Register +#define AT91C_DBGU_TCR (AT91_CAST(AT91_REG *) 0xFFFFF30C) // (PDC_DBGU) Transmit Counter Register +#define AT91C_DBGU_RNPR (AT91_CAST(AT91_REG *) 0xFFFFF310) // (PDC_DBGU) Receive Next Pointer Register +#define AT91C_DBGU_TNPR (AT91_CAST(AT91_REG *) 0xFFFFF318) // (PDC_DBGU) Transmit Next Pointer Register +#define AT91C_DBGU_TPR (AT91_CAST(AT91_REG *) 0xFFFFF308) // (PDC_DBGU) Transmit Pointer Register +#define AT91C_DBGU_RPR (AT91_CAST(AT91_REG *) 0xFFFFF300) // (PDC_DBGU) Receive Pointer Register +#define AT91C_DBGU_RCR (AT91_CAST(AT91_REG *) 0xFFFFF304) // (PDC_DBGU) Receive Counter Register +#define AT91C_DBGU_RNCR (AT91_CAST(AT91_REG *) 0xFFFFF314) // (PDC_DBGU) Receive Next Counter Register +#define AT91C_DBGU_PTCR (AT91_CAST(AT91_REG *) 0xFFFFF320) // (PDC_DBGU) PDC Transfer Control Register +#define AT91C_DBGU_PTSR (AT91_CAST(AT91_REG *) 0xFFFFF324) // (PDC_DBGU) PDC Transfer Status Register +#define AT91C_DBGU_TNCR (AT91_CAST(AT91_REG *) 0xFFFFF31C) // (PDC_DBGU) Transmit Next Counter Register // ========== Register definition for DBGU peripheral ========== -#define AT91C_DBGU_EXID (AT91_CAST(AT91_REG *) 0xFFFFF244) // (DBGU) Chip ID Extension Register -#define AT91C_DBGU_BRGR (AT91_CAST(AT91_REG *) 0xFFFFF220) // (DBGU) Baud Rate Generator Register -#define AT91C_DBGU_IDR (AT91_CAST(AT91_REG *) 0xFFFFF20C) // (DBGU) Interrupt Disable Register -#define AT91C_DBGU_CSR (AT91_CAST(AT91_REG *) 0xFFFFF214) // (DBGU) Channel Status Register -#define AT91C_DBGU_CIDR (AT91_CAST(AT91_REG *) 0xFFFFF240) // (DBGU) Chip ID Register -#define AT91C_DBGU_MR (AT91_CAST(AT91_REG *) 0xFFFFF204) // (DBGU) Mode Register -#define AT91C_DBGU_IMR (AT91_CAST(AT91_REG *) 0xFFFFF210) // (DBGU) Interrupt Mask Register -#define AT91C_DBGU_CR (AT91_CAST(AT91_REG *) 0xFFFFF200) // (DBGU) Control Register -#define AT91C_DBGU_FNTR (AT91_CAST(AT91_REG *) 0xFFFFF248) // (DBGU) Force NTRST Register -#define AT91C_DBGU_THR (AT91_CAST(AT91_REG *) 0xFFFFF21C) // (DBGU) Transmitter Holding Register -#define AT91C_DBGU_RHR (AT91_CAST(AT91_REG *) 0xFFFFF218) // (DBGU) Receiver Holding Register -#define AT91C_DBGU_IER (AT91_CAST(AT91_REG *) 0xFFFFF208) // (DBGU) Interrupt Enable Register +#define AT91C_DBGU_EXID (AT91_CAST(AT91_REG *) 0xFFFFF244) // (DBGU) Chip ID Extension Register +#define AT91C_DBGU_BRGR (AT91_CAST(AT91_REG *) 0xFFFFF220) // (DBGU) Baud Rate Generator Register +#define AT91C_DBGU_IDR (AT91_CAST(AT91_REG *) 0xFFFFF20C) // (DBGU) Interrupt Disable Register +#define AT91C_DBGU_CSR (AT91_CAST(AT91_REG *) 0xFFFFF214) // (DBGU) Channel Status Register +#define AT91C_DBGU_CIDR (AT91_CAST(AT91_REG *) 0xFFFFF240) // (DBGU) Chip ID Register +#define AT91C_DBGU_MR (AT91_CAST(AT91_REG *) 0xFFFFF204) // (DBGU) Mode Register +#define AT91C_DBGU_IMR (AT91_CAST(AT91_REG *) 0xFFFFF210) // (DBGU) Interrupt Mask Register +#define AT91C_DBGU_CR (AT91_CAST(AT91_REG *) 0xFFFFF200) // (DBGU) Control Register +#define AT91C_DBGU_FNTR (AT91_CAST(AT91_REG *) 0xFFFFF248) // (DBGU) Force NTRST Register +#define AT91C_DBGU_THR (AT91_CAST(AT91_REG *) 0xFFFFF21C) // (DBGU) Transmitter Holding Register +#define AT91C_DBGU_RHR (AT91_CAST(AT91_REG *) 0xFFFFF218) // (DBGU) Receiver Holding Register +#define AT91C_DBGU_IER (AT91_CAST(AT91_REG *) 0xFFFFF208) // (DBGU) Interrupt Enable Register // ========== Register definition for PIOA peripheral ========== -#define AT91C_PIOA_ODR (AT91_CAST(AT91_REG *) 0xFFFFF414) // (PIOA) Output Disable Registerr -#define AT91C_PIOA_SODR (AT91_CAST(AT91_REG *) 0xFFFFF430) // (PIOA) Set Output Data Register -#define AT91C_PIOA_ISR (AT91_CAST(AT91_REG *) 0xFFFFF44C) // (PIOA) Interrupt Status Register -#define AT91C_PIOA_ABSR (AT91_CAST(AT91_REG *) 0xFFFFF478) // (PIOA) AB Select Status Register -#define AT91C_PIOA_IER (AT91_CAST(AT91_REG *) 0xFFFFF440) // (PIOA) Interrupt Enable Register +#define AT91C_PIOA_ODR (AT91_CAST(AT91_REG *) 0xFFFFF414) // (PIOA) Output Disable Registerr +#define AT91C_PIOA_SODR (AT91_CAST(AT91_REG *) 0xFFFFF430) // (PIOA) Set Output Data Register +#define AT91C_PIOA_ISR (AT91_CAST(AT91_REG *) 0xFFFFF44C) // (PIOA) Interrupt Status Register +#define AT91C_PIOA_ABSR (AT91_CAST(AT91_REG *) 0xFFFFF478) // (PIOA) AB Select Status Register +#define AT91C_PIOA_IER (AT91_CAST(AT91_REG *) 0xFFFFF440) // (PIOA) Interrupt Enable Register #define AT91C_PIOA_PPUDR (AT91_CAST(AT91_REG *) 0xFFFFF460) // (PIOA) Pull-up Disable Register -#define AT91C_PIOA_IMR (AT91_CAST(AT91_REG *) 0xFFFFF448) // (PIOA) Interrupt Mask Register -#define AT91C_PIOA_PER (AT91_CAST(AT91_REG *) 0xFFFFF400) // (PIOA) PIO Enable Register -#define AT91C_PIOA_IFDR (AT91_CAST(AT91_REG *) 0xFFFFF424) // (PIOA) Input Filter Disable Register -#define AT91C_PIOA_OWDR (AT91_CAST(AT91_REG *) 0xFFFFF4A4) // (PIOA) Output Write Disable Register -#define AT91C_PIOA_MDSR (AT91_CAST(AT91_REG *) 0xFFFFF458) // (PIOA) Multi-driver Status Register -#define AT91C_PIOA_IDR (AT91_CAST(AT91_REG *) 0xFFFFF444) // (PIOA) Interrupt Disable Register -#define AT91C_PIOA_ODSR (AT91_CAST(AT91_REG *) 0xFFFFF438) // (PIOA) Output Data Status Register -#define AT91C_PIOA_PPUSR (AT91_CAST(AT91_REG *) 0xFFFFF468) // (PIOA) Pull-up Status Register -#define AT91C_PIOA_OWSR (AT91_CAST(AT91_REG *) 0xFFFFF4A8) // (PIOA) Output Write Status Register -#define AT91C_PIOA_BSR (AT91_CAST(AT91_REG *) 0xFFFFF474) // (PIOA) Select B Register -#define AT91C_PIOA_OWER (AT91_CAST(AT91_REG *) 0xFFFFF4A0) // (PIOA) Output Write Enable Register -#define AT91C_PIOA_IFER (AT91_CAST(AT91_REG *) 0xFFFFF420) // (PIOA) Input Filter Enable Register -#define AT91C_PIOA_PDSR (AT91_CAST(AT91_REG *) 0xFFFFF43C) // (PIOA) Pin Data Status Register -#define AT91C_PIOA_PPUER (AT91_CAST(AT91_REG *) 0xFFFFF464) // (PIOA) Pull-up Enable Register -#define AT91C_PIOA_OSR (AT91_CAST(AT91_REG *) 0xFFFFF418) // (PIOA) Output Status Register -#define AT91C_PIOA_ASR (AT91_CAST(AT91_REG *) 0xFFFFF470) // (PIOA) Select A Register -#define AT91C_PIOA_MDDR (AT91_CAST(AT91_REG *) 0xFFFFF454) // (PIOA) Multi-driver Disable Register -#define AT91C_PIOA_CODR (AT91_CAST(AT91_REG *) 0xFFFFF434) // (PIOA) Clear Output Data Register -#define AT91C_PIOA_MDER (AT91_CAST(AT91_REG *) 0xFFFFF450) // (PIOA) Multi-driver Enable Register -#define AT91C_PIOA_PDR (AT91_CAST(AT91_REG *) 0xFFFFF404) // (PIOA) PIO Disable Register -#define AT91C_PIOA_IFSR (AT91_CAST(AT91_REG *) 0xFFFFF428) // (PIOA) Input Filter Status Register -#define AT91C_PIOA_OER (AT91_CAST(AT91_REG *) 0xFFFFF410) // (PIOA) Output Enable Register -#define AT91C_PIOA_PSR (AT91_CAST(AT91_REG *) 0xFFFFF408) // (PIOA) PIO Status Register +#define AT91C_PIOA_IMR (AT91_CAST(AT91_REG *) 0xFFFFF448) // (PIOA) Interrupt Mask Register +#define AT91C_PIOA_PER (AT91_CAST(AT91_REG *) 0xFFFFF400) // (PIOA) PIO Enable Register +#define AT91C_PIOA_IFDR (AT91_CAST(AT91_REG *) 0xFFFFF424) // (PIOA) Input Filter Disable Register +#define AT91C_PIOA_OWDR (AT91_CAST(AT91_REG *) 0xFFFFF4A4) // (PIOA) Output Write Disable Register +#define AT91C_PIOA_MDSR (AT91_CAST(AT91_REG *) 0xFFFFF458) // (PIOA) Multi-driver Status Register +#define AT91C_PIOA_IDR (AT91_CAST(AT91_REG *) 0xFFFFF444) // (PIOA) Interrupt Disable Register +#define AT91C_PIOA_ODSR (AT91_CAST(AT91_REG *) 0xFFFFF438) // (PIOA) Output Data Status Register +#define AT91C_PIOA_PPUSR (AT91_CAST(AT91_REG *) 0xFFFFF468) // (PIOA) Pull-up Status Register +#define AT91C_PIOA_OWSR (AT91_CAST(AT91_REG *) 0xFFFFF4A8) // (PIOA) Output Write Status Register +#define AT91C_PIOA_BSR (AT91_CAST(AT91_REG *) 0xFFFFF474) // (PIOA) Select B Register +#define AT91C_PIOA_OWER (AT91_CAST(AT91_REG *) 0xFFFFF4A0) // (PIOA) Output Write Enable Register +#define AT91C_PIOA_IFER (AT91_CAST(AT91_REG *) 0xFFFFF420) // (PIOA) Input Filter Enable Register +#define AT91C_PIOA_PDSR (AT91_CAST(AT91_REG *) 0xFFFFF43C) // (PIOA) Pin Data Status Register +#define AT91C_PIOA_PPUER (AT91_CAST(AT91_REG *) 0xFFFFF464) // (PIOA) Pull-up Enable Register +#define AT91C_PIOA_OSR (AT91_CAST(AT91_REG *) 0xFFFFF418) // (PIOA) Output Status Register +#define AT91C_PIOA_ASR (AT91_CAST(AT91_REG *) 0xFFFFF470) // (PIOA) Select A Register +#define AT91C_PIOA_MDDR (AT91_CAST(AT91_REG *) 0xFFFFF454) // (PIOA) Multi-driver Disable Register +#define AT91C_PIOA_CODR (AT91_CAST(AT91_REG *) 0xFFFFF434) // (PIOA) Clear Output Data Register +#define AT91C_PIOA_MDER (AT91_CAST(AT91_REG *) 0xFFFFF450) // (PIOA) Multi-driver Enable Register +#define AT91C_PIOA_PDR (AT91_CAST(AT91_REG *) 0xFFFFF404) // (PIOA) PIO Disable Register +#define AT91C_PIOA_IFSR (AT91_CAST(AT91_REG *) 0xFFFFF428) // (PIOA) Input Filter Status Register +#define AT91C_PIOA_OER (AT91_CAST(AT91_REG *) 0xFFFFF410) // (PIOA) Output Enable Register +#define AT91C_PIOA_PSR (AT91_CAST(AT91_REG *) 0xFFFFF408) // (PIOA) PIO Status Register // ========== Register definition for CKGR peripheral ========== -#define AT91C_CKGR_MOR (AT91_CAST(AT91_REG *) 0xFFFFFC20) // (CKGR) Main Oscillator Register -#define AT91C_CKGR_PLLR (AT91_CAST(AT91_REG *) 0xFFFFFC2C) // (CKGR) PLL Register -#define AT91C_CKGR_MCFR (AT91_CAST(AT91_REG *) 0xFFFFFC24) // (CKGR) Main Clock Frequency Register +#define AT91C_CKGR_MOR (AT91_CAST(AT91_REG *) 0xFFFFFC20) // (CKGR) Main Oscillator Register +#define AT91C_CKGR_PLLR (AT91_CAST(AT91_REG *) 0xFFFFFC2C) // (CKGR) PLL Register +#define AT91C_CKGR_MCFR (AT91_CAST(AT91_REG *) 0xFFFFFC24) // (CKGR) Main Clock Frequency Register // ========== Register definition for PMC peripheral ========== -#define AT91C_PMC_IDR (AT91_CAST(AT91_REG *) 0xFFFFFC64) // (PMC) Interrupt Disable Register -#define AT91C_PMC_MOR (AT91_CAST(AT91_REG *) 0xFFFFFC20) // (PMC) Main Oscillator Register -#define AT91C_PMC_PLLR (AT91_CAST(AT91_REG *) 0xFFFFFC2C) // (PMC) PLL Register -#define AT91C_PMC_PCER (AT91_CAST(AT91_REG *) 0xFFFFFC10) // (PMC) Peripheral Clock Enable Register -#define AT91C_PMC_PCKR (AT91_CAST(AT91_REG *) 0xFFFFFC40) // (PMC) Programmable Clock Register -#define AT91C_PMC_MCKR (AT91_CAST(AT91_REG *) 0xFFFFFC30) // (PMC) Master Clock Register -#define AT91C_PMC_SCDR (AT91_CAST(AT91_REG *) 0xFFFFFC04) // (PMC) System Clock Disable Register -#define AT91C_PMC_PCDR (AT91_CAST(AT91_REG *) 0xFFFFFC14) // (PMC) Peripheral Clock Disable Register -#define AT91C_PMC_SCSR (AT91_CAST(AT91_REG *) 0xFFFFFC08) // (PMC) System Clock Status Register -#define AT91C_PMC_PCSR (AT91_CAST(AT91_REG *) 0xFFFFFC18) // (PMC) Peripheral Clock Status Register -#define AT91C_PMC_MCFR (AT91_CAST(AT91_REG *) 0xFFFFFC24) // (PMC) Main Clock Frequency Register -#define AT91C_PMC_SCER (AT91_CAST(AT91_REG *) 0xFFFFFC00) // (PMC) System Clock Enable Register -#define AT91C_PMC_IMR (AT91_CAST(AT91_REG *) 0xFFFFFC6C) // (PMC) Interrupt Mask Register -#define AT91C_PMC_IER (AT91_CAST(AT91_REG *) 0xFFFFFC60) // (PMC) Interrupt Enable Register -#define AT91C_PMC_SR (AT91_CAST(AT91_REG *) 0xFFFFFC68) // (PMC) Status Register +#define AT91C_PMC_IDR (AT91_CAST(AT91_REG *) 0xFFFFFC64) // (PMC) Interrupt Disable Register +#define AT91C_PMC_MOR (AT91_CAST(AT91_REG *) 0xFFFFFC20) // (PMC) Main Oscillator Register +#define AT91C_PMC_PLLR (AT91_CAST(AT91_REG *) 0xFFFFFC2C) // (PMC) PLL Register +#define AT91C_PMC_PCER (AT91_CAST(AT91_REG *) 0xFFFFFC10) // (PMC) Peripheral Clock Enable Register +#define AT91C_PMC_PCKR (AT91_CAST(AT91_REG *) 0xFFFFFC40) // (PMC) Programmable Clock Register +#define AT91C_PMC_MCKR (AT91_CAST(AT91_REG *) 0xFFFFFC30) // (PMC) Master Clock Register +#define AT91C_PMC_SCDR (AT91_CAST(AT91_REG *) 0xFFFFFC04) // (PMC) System Clock Disable Register +#define AT91C_PMC_PCDR (AT91_CAST(AT91_REG *) 0xFFFFFC14) // (PMC) Peripheral Clock Disable Register +#define AT91C_PMC_SCSR (AT91_CAST(AT91_REG *) 0xFFFFFC08) // (PMC) System Clock Status Register +#define AT91C_PMC_PCSR (AT91_CAST(AT91_REG *) 0xFFFFFC18) // (PMC) Peripheral Clock Status Register +#define AT91C_PMC_MCFR (AT91_CAST(AT91_REG *) 0xFFFFFC24) // (PMC) Main Clock Frequency Register +#define AT91C_PMC_SCER (AT91_CAST(AT91_REG *) 0xFFFFFC00) // (PMC) System Clock Enable Register +#define AT91C_PMC_IMR (AT91_CAST(AT91_REG *) 0xFFFFFC6C) // (PMC) Interrupt Mask Register +#define AT91C_PMC_IER (AT91_CAST(AT91_REG *) 0xFFFFFC60) // (PMC) Interrupt Enable Register +#define AT91C_PMC_SR (AT91_CAST(AT91_REG *) 0xFFFFFC68) // (PMC) Status Register // ========== Register definition for RSTC peripheral ========== -#define AT91C_RSTC_RCR (AT91_CAST(AT91_REG *) 0xFFFFFD00) // (RSTC) Reset Control Register -#define AT91C_RSTC_RMR (AT91_CAST(AT91_REG *) 0xFFFFFD08) // (RSTC) Reset Mode Register -#define AT91C_RSTC_RSR (AT91_CAST(AT91_REG *) 0xFFFFFD04) // (RSTC) Reset Status Register +#define AT91C_RSTC_RCR (AT91_CAST(AT91_REG *) 0xFFFFFD00) // (RSTC) Reset Control Register +#define AT91C_RSTC_RMR (AT91_CAST(AT91_REG *) 0xFFFFFD08) // (RSTC) Reset Mode Register +#define AT91C_RSTC_RSR (AT91_CAST(AT91_REG *) 0xFFFFFD04) // (RSTC) Reset Status Register // ========== Register definition for RTTC peripheral ========== -#define AT91C_RTTC_RTSR (AT91_CAST(AT91_REG *) 0xFFFFFD2C) // (RTTC) Real-time Status Register -#define AT91C_RTTC_RTMR (AT91_CAST(AT91_REG *) 0xFFFFFD20) // (RTTC) Real-time Mode Register -#define AT91C_RTTC_RTVR (AT91_CAST(AT91_REG *) 0xFFFFFD28) // (RTTC) Real-time Value Register -#define AT91C_RTTC_RTAR (AT91_CAST(AT91_REG *) 0xFFFFFD24) // (RTTC) Real-time Alarm Register +#define AT91C_RTTC_RTSR (AT91_CAST(AT91_REG *) 0xFFFFFD2C) // (RTTC) Real-time Status Register +#define AT91C_RTTC_RTMR (AT91_CAST(AT91_REG *) 0xFFFFFD20) // (RTTC) Real-time Mode Register +#define AT91C_RTTC_RTVR (AT91_CAST(AT91_REG *) 0xFFFFFD28) // (RTTC) Real-time Value Register +#define AT91C_RTTC_RTAR (AT91_CAST(AT91_REG *) 0xFFFFFD24) // (RTTC) Real-time Alarm Register // ========== Register definition for PITC peripheral ========== -#define AT91C_PITC_PIVR (AT91_CAST(AT91_REG *) 0xFFFFFD38) // (PITC) Period Interval Value Register -#define AT91C_PITC_PISR (AT91_CAST(AT91_REG *) 0xFFFFFD34) // (PITC) Period Interval Status Register -#define AT91C_PITC_PIIR (AT91_CAST(AT91_REG *) 0xFFFFFD3C) // (PITC) Period Interval Image Register -#define AT91C_PITC_PIMR (AT91_CAST(AT91_REG *) 0xFFFFFD30) // (PITC) Period Interval Mode Register +#define AT91C_PITC_PIVR (AT91_CAST(AT91_REG *) 0xFFFFFD38) // (PITC) Period Interval Value Register +#define AT91C_PITC_PISR (AT91_CAST(AT91_REG *) 0xFFFFFD34) // (PITC) Period Interval Status Register +#define AT91C_PITC_PIIR (AT91_CAST(AT91_REG *) 0xFFFFFD3C) // (PITC) Period Interval Image Register +#define AT91C_PITC_PIMR (AT91_CAST(AT91_REG *) 0xFFFFFD30) // (PITC) Period Interval Mode Register // ========== Register definition for WDTC peripheral ========== -#define AT91C_WDTC_WDCR (AT91_CAST(AT91_REG *) 0xFFFFFD40) // (WDTC) Watchdog Control Register -#define AT91C_WDTC_WDSR (AT91_CAST(AT91_REG *) 0xFFFFFD48) // (WDTC) Watchdog Status Register -#define AT91C_WDTC_WDMR (AT91_CAST(AT91_REG *) 0xFFFFFD44) // (WDTC) Watchdog Mode Register +#define AT91C_WDTC_WDCR (AT91_CAST(AT91_REG *) 0xFFFFFD40) // (WDTC) Watchdog Control Register +#define AT91C_WDTC_WDSR (AT91_CAST(AT91_REG *) 0xFFFFFD48) // (WDTC) Watchdog Status Register +#define AT91C_WDTC_WDMR (AT91_CAST(AT91_REG *) 0xFFFFFD44) // (WDTC) Watchdog Mode Register // ========== Register definition for VREG peripheral ========== -#define AT91C_VREG_MR (AT91_CAST(AT91_REG *) 0xFFFFFD60) // (VREG) Voltage Regulator Mode Register +#define AT91C_VREG_MR (AT91_CAST(AT91_REG *) 0xFFFFFD60) // (VREG) Voltage Regulator Mode Register // ========== Register definition for EFC0 peripheral ========== -#define AT91C_EFC0_FCR (AT91_CAST(AT91_REG *) 0xFFFFFF64) // (EFC0) MC Flash Command Register -#define AT91C_EFC0_FSR (AT91_CAST(AT91_REG *) 0xFFFFFF68) // (EFC0) MC Flash Status Register -#define AT91C_EFC0_VR (AT91_CAST(AT91_REG *) 0xFFFFFF6C) // (EFC0) MC Flash Version Register -#define AT91C_EFC0_FMR (AT91_CAST(AT91_REG *) 0xFFFFFF60) // (EFC0) MC Flash Mode Register +#define AT91C_EFC0_FCR (AT91_CAST(AT91_REG *) 0xFFFFFF64) // (EFC0) MC Flash Command Register +#define AT91C_EFC0_FSR (AT91_CAST(AT91_REG *) 0xFFFFFF68) // (EFC0) MC Flash Status Register +#define AT91C_EFC0_VR (AT91_CAST(AT91_REG *) 0xFFFFFF6C) // (EFC0) MC Flash Version Register +#define AT91C_EFC0_FMR (AT91_CAST(AT91_REG *) 0xFFFFFF60) // (EFC0) MC Flash Mode Register // ========== Register definition for EFC1 peripheral ========== -#define AT91C_EFC1_VR (AT91_CAST(AT91_REG *) 0xFFFFFF7C) // (EFC1) MC Flash Version Register -#define AT91C_EFC1_FCR (AT91_CAST(AT91_REG *) 0xFFFFFF74) // (EFC1) MC Flash Command Register -#define AT91C_EFC1_FSR (AT91_CAST(AT91_REG *) 0xFFFFFF78) // (EFC1) MC Flash Status Register -#define AT91C_EFC1_FMR (AT91_CAST(AT91_REG *) 0xFFFFFF70) // (EFC1) MC Flash Mode Register +#define AT91C_EFC1_VR (AT91_CAST(AT91_REG *) 0xFFFFFF7C) // (EFC1) MC Flash Version Register +#define AT91C_EFC1_FCR (AT91_CAST(AT91_REG *) 0xFFFFFF74) // (EFC1) MC Flash Command Register +#define AT91C_EFC1_FSR (AT91_CAST(AT91_REG *) 0xFFFFFF78) // (EFC1) MC Flash Status Register +#define AT91C_EFC1_FMR (AT91_CAST(AT91_REG *) 0xFFFFFF70) // (EFC1) MC Flash Mode Register // ========== Register definition for MC peripheral ========== -#define AT91C_MC_ASR (AT91_CAST(AT91_REG *) 0xFFFFFF04) // (MC) MC Abort Status Register -#define AT91C_MC_RCR (AT91_CAST(AT91_REG *) 0xFFFFFF00) // (MC) MC Remap Control Register -#define AT91C_MC_PUP (AT91_CAST(AT91_REG *) 0xFFFFFF50) // (MC) MC Protection Unit Peripherals -#define AT91C_MC_PUIA (AT91_CAST(AT91_REG *) 0xFFFFFF10) // (MC) MC Protection Unit Area -#define AT91C_MC_AASR (AT91_CAST(AT91_REG *) 0xFFFFFF08) // (MC) MC Abort Address Status Register -#define AT91C_MC_PUER (AT91_CAST(AT91_REG *) 0xFFFFFF54) // (MC) MC Protection Unit Enable Register +#define AT91C_MC_ASR (AT91_CAST(AT91_REG *) 0xFFFFFF04) // (MC) MC Abort Status Register +#define AT91C_MC_RCR (AT91_CAST(AT91_REG *) 0xFFFFFF00) // (MC) MC Remap Control Register +#define AT91C_MC_PUP (AT91_CAST(AT91_REG *) 0xFFFFFF50) // (MC) MC Protection Unit Peripherals +#define AT91C_MC_PUIA (AT91_CAST(AT91_REG *) 0xFFFFFF10) // (MC) MC Protection Unit Area +#define AT91C_MC_AASR (AT91_CAST(AT91_REG *) 0xFFFFFF08) // (MC) MC Abort Address Status Register +#define AT91C_MC_PUER (AT91_CAST(AT91_REG *) 0xFFFFFF54) // (MC) MC Protection Unit Enable Register // ========== Register definition for PDC_SPI peripheral ========== -#define AT91C_SPI_PTCR (AT91_CAST(AT91_REG *) 0xFFFE0120) // (PDC_SPI) PDC Transfer Control Register -#define AT91C_SPI_TPR (AT91_CAST(AT91_REG *) 0xFFFE0108) // (PDC_SPI) Transmit Pointer Register -#define AT91C_SPI_TCR (AT91_CAST(AT91_REG *) 0xFFFE010C) // (PDC_SPI) Transmit Counter Register -#define AT91C_SPI_RCR (AT91_CAST(AT91_REG *) 0xFFFE0104) // (PDC_SPI) Receive Counter Register -#define AT91C_SPI_PTSR (AT91_CAST(AT91_REG *) 0xFFFE0124) // (PDC_SPI) PDC Transfer Status Register -#define AT91C_SPI_RNPR (AT91_CAST(AT91_REG *) 0xFFFE0110) // (PDC_SPI) Receive Next Pointer Register -#define AT91C_SPI_RPR (AT91_CAST(AT91_REG *) 0xFFFE0100) // (PDC_SPI) Receive Pointer Register -#define AT91C_SPI_TNCR (AT91_CAST(AT91_REG *) 0xFFFE011C) // (PDC_SPI) Transmit Next Counter Register -#define AT91C_SPI_RNCR (AT91_CAST(AT91_REG *) 0xFFFE0114) // (PDC_SPI) Receive Next Counter Register -#define AT91C_SPI_TNPR (AT91_CAST(AT91_REG *) 0xFFFE0118) // (PDC_SPI) Transmit Next Pointer Register +#define AT91C_SPI_PTCR (AT91_CAST(AT91_REG *) 0xFFFE0120) // (PDC_SPI) PDC Transfer Control Register +#define AT91C_SPI_TPR (AT91_CAST(AT91_REG *) 0xFFFE0108) // (PDC_SPI) Transmit Pointer Register +#define AT91C_SPI_TCR (AT91_CAST(AT91_REG *) 0xFFFE010C) // (PDC_SPI) Transmit Counter Register +#define AT91C_SPI_RCR (AT91_CAST(AT91_REG *) 0xFFFE0104) // (PDC_SPI) Receive Counter Register +#define AT91C_SPI_PTSR (AT91_CAST(AT91_REG *) 0xFFFE0124) // (PDC_SPI) PDC Transfer Status Register +#define AT91C_SPI_RNPR (AT91_CAST(AT91_REG *) 0xFFFE0110) // (PDC_SPI) Receive Next Pointer Register +#define AT91C_SPI_RPR (AT91_CAST(AT91_REG *) 0xFFFE0100) // (PDC_SPI) Receive Pointer Register +#define AT91C_SPI_TNCR (AT91_CAST(AT91_REG *) 0xFFFE011C) // (PDC_SPI) Transmit Next Counter Register +#define AT91C_SPI_RNCR (AT91_CAST(AT91_REG *) 0xFFFE0114) // (PDC_SPI) Receive Next Counter Register +#define AT91C_SPI_TNPR (AT91_CAST(AT91_REG *) 0xFFFE0118) // (PDC_SPI) Transmit Next Pointer Register // ========== Register definition for SPI peripheral ========== -#define AT91C_SPI_IER (AT91_CAST(AT91_REG *) 0xFFFE0014) // (SPI) Interrupt Enable Register -#define AT91C_SPI_SR (AT91_CAST(AT91_REG *) 0xFFFE0010) // (SPI) Status Register -#define AT91C_SPI_IDR (AT91_CAST(AT91_REG *) 0xFFFE0018) // (SPI) Interrupt Disable Register -#define AT91C_SPI_CR (AT91_CAST(AT91_REG *) 0xFFFE0000) // (SPI) Control Register -#define AT91C_SPI_MR (AT91_CAST(AT91_REG *) 0xFFFE0004) // (SPI) Mode Register -#define AT91C_SPI_IMR (AT91_CAST(AT91_REG *) 0xFFFE001C) // (SPI) Interrupt Mask Register -#define AT91C_SPI_TDR (AT91_CAST(AT91_REG *) 0xFFFE000C) // (SPI) Transmit Data Register -#define AT91C_SPI_RDR (AT91_CAST(AT91_REG *) 0xFFFE0008) // (SPI) Receive Data Register -#define AT91C_SPI_CSR (AT91_CAST(AT91_REG *) 0xFFFE0030) // (SPI) Chip Select Register +#define AT91C_SPI_IER (AT91_CAST(AT91_REG *) 0xFFFE0014) // (SPI) Interrupt Enable Register +#define AT91C_SPI_SR (AT91_CAST(AT91_REG *) 0xFFFE0010) // (SPI) Status Register +#define AT91C_SPI_IDR (AT91_CAST(AT91_REG *) 0xFFFE0018) // (SPI) Interrupt Disable Register +#define AT91C_SPI_CR (AT91_CAST(AT91_REG *) 0xFFFE0000) // (SPI) Control Register +#define AT91C_SPI_MR (AT91_CAST(AT91_REG *) 0xFFFE0004) // (SPI) Mode Register +#define AT91C_SPI_IMR (AT91_CAST(AT91_REG *) 0xFFFE001C) // (SPI) Interrupt Mask Register +#define AT91C_SPI_TDR (AT91_CAST(AT91_REG *) 0xFFFE000C) // (SPI) Transmit Data Register +#define AT91C_SPI_RDR (AT91_CAST(AT91_REG *) 0xFFFE0008) // (SPI) Receive Data Register +#define AT91C_SPI_CSR (AT91_CAST(AT91_REG *) 0xFFFE0030) // (SPI) Chip Select Register // ========== Register definition for PDC_ADC peripheral ========== -#define AT91C_ADC_PTSR (AT91_CAST(AT91_REG *) 0xFFFD8124) // (PDC_ADC) PDC Transfer Status Register -#define AT91C_ADC_PTCR (AT91_CAST(AT91_REG *) 0xFFFD8120) // (PDC_ADC) PDC Transfer Control Register -#define AT91C_ADC_TNPR (AT91_CAST(AT91_REG *) 0xFFFD8118) // (PDC_ADC) Transmit Next Pointer Register -#define AT91C_ADC_TNCR (AT91_CAST(AT91_REG *) 0xFFFD811C) // (PDC_ADC) Transmit Next Counter Register -#define AT91C_ADC_RNPR (AT91_CAST(AT91_REG *) 0xFFFD8110) // (PDC_ADC) Receive Next Pointer Register -#define AT91C_ADC_RNCR (AT91_CAST(AT91_REG *) 0xFFFD8114) // (PDC_ADC) Receive Next Counter Register -#define AT91C_ADC_RPR (AT91_CAST(AT91_REG *) 0xFFFD8100) // (PDC_ADC) Receive Pointer Register -#define AT91C_ADC_TCR (AT91_CAST(AT91_REG *) 0xFFFD810C) // (PDC_ADC) Transmit Counter Register -#define AT91C_ADC_TPR (AT91_CAST(AT91_REG *) 0xFFFD8108) // (PDC_ADC) Transmit Pointer Register -#define AT91C_ADC_RCR (AT91_CAST(AT91_REG *) 0xFFFD8104) // (PDC_ADC) Receive Counter Register +#define AT91C_ADC_PTSR (AT91_CAST(AT91_REG *) 0xFFFD8124) // (PDC_ADC) PDC Transfer Status Register +#define AT91C_ADC_PTCR (AT91_CAST(AT91_REG *) 0xFFFD8120) // (PDC_ADC) PDC Transfer Control Register +#define AT91C_ADC_TNPR (AT91_CAST(AT91_REG *) 0xFFFD8118) // (PDC_ADC) Transmit Next Pointer Register +#define AT91C_ADC_TNCR (AT91_CAST(AT91_REG *) 0xFFFD811C) // (PDC_ADC) Transmit Next Counter Register +#define AT91C_ADC_RNPR (AT91_CAST(AT91_REG *) 0xFFFD8110) // (PDC_ADC) Receive Next Pointer Register +#define AT91C_ADC_RNCR (AT91_CAST(AT91_REG *) 0xFFFD8114) // (PDC_ADC) Receive Next Counter Register +#define AT91C_ADC_RPR (AT91_CAST(AT91_REG *) 0xFFFD8100) // (PDC_ADC) Receive Pointer Register +#define AT91C_ADC_TCR (AT91_CAST(AT91_REG *) 0xFFFD810C) // (PDC_ADC) Transmit Counter Register +#define AT91C_ADC_TPR (AT91_CAST(AT91_REG *) 0xFFFD8108) // (PDC_ADC) Transmit Pointer Register +#define AT91C_ADC_RCR (AT91_CAST(AT91_REG *) 0xFFFD8104) // (PDC_ADC) Receive Counter Register // ========== Register definition for ADC peripheral ========== -#define AT91C_ADC_CDR2 (AT91_CAST(AT91_REG *) 0xFFFD8038) // (ADC) ADC Channel Data Register 2 -#define AT91C_ADC_CDR3 (AT91_CAST(AT91_REG *) 0xFFFD803C) // (ADC) ADC Channel Data Register 3 -#define AT91C_ADC_CDR0 (AT91_CAST(AT91_REG *) 0xFFFD8030) // (ADC) ADC Channel Data Register 0 -#define AT91C_ADC_CDR5 (AT91_CAST(AT91_REG *) 0xFFFD8044) // (ADC) ADC Channel Data Register 5 -#define AT91C_ADC_CHDR (AT91_CAST(AT91_REG *) 0xFFFD8014) // (ADC) ADC Channel Disable Register -#define AT91C_ADC_SR (AT91_CAST(AT91_REG *) 0xFFFD801C) // (ADC) ADC Status Register -#define AT91C_ADC_CDR4 (AT91_CAST(AT91_REG *) 0xFFFD8040) // (ADC) ADC Channel Data Register 4 -#define AT91C_ADC_CDR1 (AT91_CAST(AT91_REG *) 0xFFFD8034) // (ADC) ADC Channel Data Register 1 -#define AT91C_ADC_LCDR (AT91_CAST(AT91_REG *) 0xFFFD8020) // (ADC) ADC Last Converted Data Register -#define AT91C_ADC_IDR (AT91_CAST(AT91_REG *) 0xFFFD8028) // (ADC) ADC Interrupt Disable Register -#define AT91C_ADC_CR (AT91_CAST(AT91_REG *) 0xFFFD8000) // (ADC) ADC Control Register -#define AT91C_ADC_CDR7 (AT91_CAST(AT91_REG *) 0xFFFD804C) // (ADC) ADC Channel Data Register 7 -#define AT91C_ADC_CDR6 (AT91_CAST(AT91_REG *) 0xFFFD8048) // (ADC) ADC Channel Data Register 6 -#define AT91C_ADC_IER (AT91_CAST(AT91_REG *) 0xFFFD8024) // (ADC) ADC Interrupt Enable Register -#define AT91C_ADC_CHER (AT91_CAST(AT91_REG *) 0xFFFD8010) // (ADC) ADC Channel Enable Register -#define AT91C_ADC_CHSR (AT91_CAST(AT91_REG *) 0xFFFD8018) // (ADC) ADC Channel Status Register -#define AT91C_ADC_MR (AT91_CAST(AT91_REG *) 0xFFFD8004) // (ADC) ADC Mode Register -#define AT91C_ADC_IMR (AT91_CAST(AT91_REG *) 0xFFFD802C) // (ADC) ADC Interrupt Mask Register +#define AT91C_ADC_CDR2 (AT91_CAST(AT91_REG *) 0xFFFD8038) // (ADC) ADC Channel Data Register 2 +#define AT91C_ADC_CDR3 (AT91_CAST(AT91_REG *) 0xFFFD803C) // (ADC) ADC Channel Data Register 3 +#define AT91C_ADC_CDR0 (AT91_CAST(AT91_REG *) 0xFFFD8030) // (ADC) ADC Channel Data Register 0 +#define AT91C_ADC_CDR5 (AT91_CAST(AT91_REG *) 0xFFFD8044) // (ADC) ADC Channel Data Register 5 +#define AT91C_ADC_CHDR (AT91_CAST(AT91_REG *) 0xFFFD8014) // (ADC) ADC Channel Disable Register +#define AT91C_ADC_SR (AT91_CAST(AT91_REG *) 0xFFFD801C) // (ADC) ADC Status Register +#define AT91C_ADC_CDR4 (AT91_CAST(AT91_REG *) 0xFFFD8040) // (ADC) ADC Channel Data Register 4 +#define AT91C_ADC_CDR1 (AT91_CAST(AT91_REG *) 0xFFFD8034) // (ADC) ADC Channel Data Register 1 +#define AT91C_ADC_LCDR (AT91_CAST(AT91_REG *) 0xFFFD8020) // (ADC) ADC Last Converted Data Register +#define AT91C_ADC_IDR (AT91_CAST(AT91_REG *) 0xFFFD8028) // (ADC) ADC Interrupt Disable Register +#define AT91C_ADC_CR (AT91_CAST(AT91_REG *) 0xFFFD8000) // (ADC) ADC Control Register +#define AT91C_ADC_CDR7 (AT91_CAST(AT91_REG *) 0xFFFD804C) // (ADC) ADC Channel Data Register 7 +#define AT91C_ADC_CDR6 (AT91_CAST(AT91_REG *) 0xFFFD8048) // (ADC) ADC Channel Data Register 6 +#define AT91C_ADC_IER (AT91_CAST(AT91_REG *) 0xFFFD8024) // (ADC) ADC Interrupt Enable Register +#define AT91C_ADC_CHER (AT91_CAST(AT91_REG *) 0xFFFD8010) // (ADC) ADC Channel Enable Register +#define AT91C_ADC_CHSR (AT91_CAST(AT91_REG *) 0xFFFD8018) // (ADC) ADC Channel Status Register +#define AT91C_ADC_MR (AT91_CAST(AT91_REG *) 0xFFFD8004) // (ADC) ADC Mode Register +#define AT91C_ADC_IMR (AT91_CAST(AT91_REG *) 0xFFFD802C) // (ADC) ADC Interrupt Mask Register // ========== Register definition for PDC_SSC peripheral ========== -#define AT91C_SSC_TNCR (AT91_CAST(AT91_REG *) 0xFFFD411C) // (PDC_SSC) Transmit Next Counter Register -#define AT91C_SSC_RPR (AT91_CAST(AT91_REG *) 0xFFFD4100) // (PDC_SSC) Receive Pointer Register -#define AT91C_SSC_RNCR (AT91_CAST(AT91_REG *) 0xFFFD4114) // (PDC_SSC) Receive Next Counter Register -#define AT91C_SSC_TPR (AT91_CAST(AT91_REG *) 0xFFFD4108) // (PDC_SSC) Transmit Pointer Register -#define AT91C_SSC_PTCR (AT91_CAST(AT91_REG *) 0xFFFD4120) // (PDC_SSC) PDC Transfer Control Register -#define AT91C_SSC_TCR (AT91_CAST(AT91_REG *) 0xFFFD410C) // (PDC_SSC) Transmit Counter Register -#define AT91C_SSC_RCR (AT91_CAST(AT91_REG *) 0xFFFD4104) // (PDC_SSC) Receive Counter Register -#define AT91C_SSC_RNPR (AT91_CAST(AT91_REG *) 0xFFFD4110) // (PDC_SSC) Receive Next Pointer Register -#define AT91C_SSC_TNPR (AT91_CAST(AT91_REG *) 0xFFFD4118) // (PDC_SSC) Transmit Next Pointer Register -#define AT91C_SSC_PTSR (AT91_CAST(AT91_REG *) 0xFFFD4124) // (PDC_SSC) PDC Transfer Status Register +#define AT91C_SSC_TNCR (AT91_CAST(AT91_REG *) 0xFFFD411C) // (PDC_SSC) Transmit Next Counter Register +#define AT91C_SSC_RPR (AT91_CAST(AT91_REG *) 0xFFFD4100) // (PDC_SSC) Receive Pointer Register +#define AT91C_SSC_RNCR (AT91_CAST(AT91_REG *) 0xFFFD4114) // (PDC_SSC) Receive Next Counter Register +#define AT91C_SSC_TPR (AT91_CAST(AT91_REG *) 0xFFFD4108) // (PDC_SSC) Transmit Pointer Register +#define AT91C_SSC_PTCR (AT91_CAST(AT91_REG *) 0xFFFD4120) // (PDC_SSC) PDC Transfer Control Register +#define AT91C_SSC_TCR (AT91_CAST(AT91_REG *) 0xFFFD410C) // (PDC_SSC) Transmit Counter Register +#define AT91C_SSC_RCR (AT91_CAST(AT91_REG *) 0xFFFD4104) // (PDC_SSC) Receive Counter Register +#define AT91C_SSC_RNPR (AT91_CAST(AT91_REG *) 0xFFFD4110) // (PDC_SSC) Receive Next Pointer Register +#define AT91C_SSC_TNPR (AT91_CAST(AT91_REG *) 0xFFFD4118) // (PDC_SSC) Transmit Next Pointer Register +#define AT91C_SSC_PTSR (AT91_CAST(AT91_REG *) 0xFFFD4124) // (PDC_SSC) PDC Transfer Status Register // ========== Register definition for SSC peripheral ========== -#define AT91C_SSC_RHR (AT91_CAST(AT91_REG *) 0xFFFD4020) // (SSC) Receive Holding Register -#define AT91C_SSC_RSHR (AT91_CAST(AT91_REG *) 0xFFFD4030) // (SSC) Receive Sync Holding Register -#define AT91C_SSC_TFMR (AT91_CAST(AT91_REG *) 0xFFFD401C) // (SSC) Transmit Frame Mode Register -#define AT91C_SSC_IDR (AT91_CAST(AT91_REG *) 0xFFFD4048) // (SSC) Interrupt Disable Register -#define AT91C_SSC_THR (AT91_CAST(AT91_REG *) 0xFFFD4024) // (SSC) Transmit Holding Register -#define AT91C_SSC_RCMR (AT91_CAST(AT91_REG *) 0xFFFD4010) // (SSC) Receive Clock ModeRegister -#define AT91C_SSC_IER (AT91_CAST(AT91_REG *) 0xFFFD4044) // (SSC) Interrupt Enable Register -#define AT91C_SSC_TSHR (AT91_CAST(AT91_REG *) 0xFFFD4034) // (SSC) Transmit Sync Holding Register -#define AT91C_SSC_SR (AT91_CAST(AT91_REG *) 0xFFFD4040) // (SSC) Status Register -#define AT91C_SSC_CMR (AT91_CAST(AT91_REG *) 0xFFFD4004) // (SSC) Clock Mode Register -#define AT91C_SSC_TCMR (AT91_CAST(AT91_REG *) 0xFFFD4018) // (SSC) Transmit Clock Mode Register -#define AT91C_SSC_CR (AT91_CAST(AT91_REG *) 0xFFFD4000) // (SSC) Control Register -#define AT91C_SSC_IMR (AT91_CAST(AT91_REG *) 0xFFFD404C) // (SSC) Interrupt Mask Register -#define AT91C_SSC_RFMR (AT91_CAST(AT91_REG *) 0xFFFD4014) // (SSC) Receive Frame Mode Register +#define AT91C_SSC_RHR (AT91_CAST(AT91_REG *) 0xFFFD4020) // (SSC) Receive Holding Register +#define AT91C_SSC_RSHR (AT91_CAST(AT91_REG *) 0xFFFD4030) // (SSC) Receive Sync Holding Register +#define AT91C_SSC_TFMR (AT91_CAST(AT91_REG *) 0xFFFD401C) // (SSC) Transmit Frame Mode Register +#define AT91C_SSC_IDR (AT91_CAST(AT91_REG *) 0xFFFD4048) // (SSC) Interrupt Disable Register +#define AT91C_SSC_THR (AT91_CAST(AT91_REG *) 0xFFFD4024) // (SSC) Transmit Holding Register +#define AT91C_SSC_RCMR (AT91_CAST(AT91_REG *) 0xFFFD4010) // (SSC) Receive Clock ModeRegister +#define AT91C_SSC_IER (AT91_CAST(AT91_REG *) 0xFFFD4044) // (SSC) Interrupt Enable Register +#define AT91C_SSC_TSHR (AT91_CAST(AT91_REG *) 0xFFFD4034) // (SSC) Transmit Sync Holding Register +#define AT91C_SSC_SR (AT91_CAST(AT91_REG *) 0xFFFD4040) // (SSC) Status Register +#define AT91C_SSC_CMR (AT91_CAST(AT91_REG *) 0xFFFD4004) // (SSC) Clock Mode Register +#define AT91C_SSC_TCMR (AT91_CAST(AT91_REG *) 0xFFFD4018) // (SSC) Transmit Clock Mode Register +#define AT91C_SSC_CR (AT91_CAST(AT91_REG *) 0xFFFD4000) // (SSC) Control Register +#define AT91C_SSC_IMR (AT91_CAST(AT91_REG *) 0xFFFD404C) // (SSC) Interrupt Mask Register +#define AT91C_SSC_RFMR (AT91_CAST(AT91_REG *) 0xFFFD4014) // (SSC) Receive Frame Mode Register // ========== Register definition for PDC_US1 peripheral ========== -#define AT91C_US1_RNCR (AT91_CAST(AT91_REG *) 0xFFFC4114) // (PDC_US1) Receive Next Counter Register -#define AT91C_US1_PTCR (AT91_CAST(AT91_REG *) 0xFFFC4120) // (PDC_US1) PDC Transfer Control Register -#define AT91C_US1_TCR (AT91_CAST(AT91_REG *) 0xFFFC410C) // (PDC_US1) Transmit Counter Register -#define AT91C_US1_PTSR (AT91_CAST(AT91_REG *) 0xFFFC4124) // (PDC_US1) PDC Transfer Status Register -#define AT91C_US1_TNPR (AT91_CAST(AT91_REG *) 0xFFFC4118) // (PDC_US1) Transmit Next Pointer Register -#define AT91C_US1_RCR (AT91_CAST(AT91_REG *) 0xFFFC4104) // (PDC_US1) Receive Counter Register -#define AT91C_US1_RNPR (AT91_CAST(AT91_REG *) 0xFFFC4110) // (PDC_US1) Receive Next Pointer Register -#define AT91C_US1_RPR (AT91_CAST(AT91_REG *) 0xFFFC4100) // (PDC_US1) Receive Pointer Register -#define AT91C_US1_TNCR (AT91_CAST(AT91_REG *) 0xFFFC411C) // (PDC_US1) Transmit Next Counter Register -#define AT91C_US1_TPR (AT91_CAST(AT91_REG *) 0xFFFC4108) // (PDC_US1) Transmit Pointer Register +#define AT91C_US1_RNCR (AT91_CAST(AT91_REG *) 0xFFFC4114) // (PDC_US1) Receive Next Counter Register +#define AT91C_US1_PTCR (AT91_CAST(AT91_REG *) 0xFFFC4120) // (PDC_US1) PDC Transfer Control Register +#define AT91C_US1_TCR (AT91_CAST(AT91_REG *) 0xFFFC410C) // (PDC_US1) Transmit Counter Register +#define AT91C_US1_PTSR (AT91_CAST(AT91_REG *) 0xFFFC4124) // (PDC_US1) PDC Transfer Status Register +#define AT91C_US1_TNPR (AT91_CAST(AT91_REG *) 0xFFFC4118) // (PDC_US1) Transmit Next Pointer Register +#define AT91C_US1_RCR (AT91_CAST(AT91_REG *) 0xFFFC4104) // (PDC_US1) Receive Counter Register +#define AT91C_US1_RNPR (AT91_CAST(AT91_REG *) 0xFFFC4110) // (PDC_US1) Receive Next Pointer Register +#define AT91C_US1_RPR (AT91_CAST(AT91_REG *) 0xFFFC4100) // (PDC_US1) Receive Pointer Register +#define AT91C_US1_TNCR (AT91_CAST(AT91_REG *) 0xFFFC411C) // (PDC_US1) Transmit Next Counter Register +#define AT91C_US1_TPR (AT91_CAST(AT91_REG *) 0xFFFC4108) // (PDC_US1) Transmit Pointer Register // ========== Register definition for US1 peripheral ========== -#define AT91C_US1_IF (AT91_CAST(AT91_REG *) 0xFFFC404C) // (US1) IRDA_FILTER Register -#define AT91C_US1_NER (AT91_CAST(AT91_REG *) 0xFFFC4044) // (US1) Nb Errors Register -#define AT91C_US1_RTOR (AT91_CAST(AT91_REG *) 0xFFFC4024) // (US1) Receiver Time-out Register -#define AT91C_US1_CSR (AT91_CAST(AT91_REG *) 0xFFFC4014) // (US1) Channel Status Register -#define AT91C_US1_IDR (AT91_CAST(AT91_REG *) 0xFFFC400C) // (US1) Interrupt Disable Register -#define AT91C_US1_IER (AT91_CAST(AT91_REG *) 0xFFFC4008) // (US1) Interrupt Enable Register -#define AT91C_US1_THR (AT91_CAST(AT91_REG *) 0xFFFC401C) // (US1) Transmitter Holding Register -#define AT91C_US1_TTGR (AT91_CAST(AT91_REG *) 0xFFFC4028) // (US1) Transmitter Time-guard Register -#define AT91C_US1_RHR (AT91_CAST(AT91_REG *) 0xFFFC4018) // (US1) Receiver Holding Register -#define AT91C_US1_BRGR (AT91_CAST(AT91_REG *) 0xFFFC4020) // (US1) Baud Rate Generator Register -#define AT91C_US1_IMR (AT91_CAST(AT91_REG *) 0xFFFC4010) // (US1) Interrupt Mask Register -#define AT91C_US1_FIDI (AT91_CAST(AT91_REG *) 0xFFFC4040) // (US1) FI_DI_Ratio Register -#define AT91C_US1_CR (AT91_CAST(AT91_REG *) 0xFFFC4000) // (US1) Control Register -#define AT91C_US1_MR (AT91_CAST(AT91_REG *) 0xFFFC4004) // (US1) Mode Register +#define AT91C_US1_IF (AT91_CAST(AT91_REG *) 0xFFFC404C) // (US1) IRDA_FILTER Register +#define AT91C_US1_NER (AT91_CAST(AT91_REG *) 0xFFFC4044) // (US1) Nb Errors Register +#define AT91C_US1_RTOR (AT91_CAST(AT91_REG *) 0xFFFC4024) // (US1) Receiver Time-out Register +#define AT91C_US1_CSR (AT91_CAST(AT91_REG *) 0xFFFC4014) // (US1) Channel Status Register +#define AT91C_US1_IDR (AT91_CAST(AT91_REG *) 0xFFFC400C) // (US1) Interrupt Disable Register +#define AT91C_US1_IER (AT91_CAST(AT91_REG *) 0xFFFC4008) // (US1) Interrupt Enable Register +#define AT91C_US1_THR (AT91_CAST(AT91_REG *) 0xFFFC401C) // (US1) Transmitter Holding Register +#define AT91C_US1_TTGR (AT91_CAST(AT91_REG *) 0xFFFC4028) // (US1) Transmitter Time-guard Register +#define AT91C_US1_RHR (AT91_CAST(AT91_REG *) 0xFFFC4018) // (US1) Receiver Holding Register +#define AT91C_US1_BRGR (AT91_CAST(AT91_REG *) 0xFFFC4020) // (US1) Baud Rate Generator Register +#define AT91C_US1_IMR (AT91_CAST(AT91_REG *) 0xFFFC4010) // (US1) Interrupt Mask Register +#define AT91C_US1_FIDI (AT91_CAST(AT91_REG *) 0xFFFC4040) // (US1) FI_DI_Ratio Register +#define AT91C_US1_CR (AT91_CAST(AT91_REG *) 0xFFFC4000) // (US1) Control Register +#define AT91C_US1_MR (AT91_CAST(AT91_REG *) 0xFFFC4004) // (US1) Mode Register // ========== Register definition for PDC_US0 peripheral ========== -#define AT91C_US0_TNPR (AT91_CAST(AT91_REG *) 0xFFFC0118) // (PDC_US0) Transmit Next Pointer Register -#define AT91C_US0_RNPR (AT91_CAST(AT91_REG *) 0xFFFC0110) // (PDC_US0) Receive Next Pointer Register -#define AT91C_US0_TCR (AT91_CAST(AT91_REG *) 0xFFFC010C) // (PDC_US0) Transmit Counter Register -#define AT91C_US0_PTCR (AT91_CAST(AT91_REG *) 0xFFFC0120) // (PDC_US0) PDC Transfer Control Register -#define AT91C_US0_PTSR (AT91_CAST(AT91_REG *) 0xFFFC0124) // (PDC_US0) PDC Transfer Status Register -#define AT91C_US0_TNCR (AT91_CAST(AT91_REG *) 0xFFFC011C) // (PDC_US0) Transmit Next Counter Register -#define AT91C_US0_TPR (AT91_CAST(AT91_REG *) 0xFFFC0108) // (PDC_US0) Transmit Pointer Register -#define AT91C_US0_RCR (AT91_CAST(AT91_REG *) 0xFFFC0104) // (PDC_US0) Receive Counter Register -#define AT91C_US0_RPR (AT91_CAST(AT91_REG *) 0xFFFC0100) // (PDC_US0) Receive Pointer Register -#define AT91C_US0_RNCR (AT91_CAST(AT91_REG *) 0xFFFC0114) // (PDC_US0) Receive Next Counter Register +#define AT91C_US0_TNPR (AT91_CAST(AT91_REG *) 0xFFFC0118) // (PDC_US0) Transmit Next Pointer Register +#define AT91C_US0_RNPR (AT91_CAST(AT91_REG *) 0xFFFC0110) // (PDC_US0) Receive Next Pointer Register +#define AT91C_US0_TCR (AT91_CAST(AT91_REG *) 0xFFFC010C) // (PDC_US0) Transmit Counter Register +#define AT91C_US0_PTCR (AT91_CAST(AT91_REG *) 0xFFFC0120) // (PDC_US0) PDC Transfer Control Register +#define AT91C_US0_PTSR (AT91_CAST(AT91_REG *) 0xFFFC0124) // (PDC_US0) PDC Transfer Status Register +#define AT91C_US0_TNCR (AT91_CAST(AT91_REG *) 0xFFFC011C) // (PDC_US0) Transmit Next Counter Register +#define AT91C_US0_TPR (AT91_CAST(AT91_REG *) 0xFFFC0108) // (PDC_US0) Transmit Pointer Register +#define AT91C_US0_RCR (AT91_CAST(AT91_REG *) 0xFFFC0104) // (PDC_US0) Receive Counter Register +#define AT91C_US0_RPR (AT91_CAST(AT91_REG *) 0xFFFC0100) // (PDC_US0) Receive Pointer Register +#define AT91C_US0_RNCR (AT91_CAST(AT91_REG *) 0xFFFC0114) // (PDC_US0) Receive Next Counter Register // ========== Register definition for US0 peripheral ========== -#define AT91C_US0_BRGR (AT91_CAST(AT91_REG *) 0xFFFC0020) // (US0) Baud Rate Generator Register -#define AT91C_US0_NER (AT91_CAST(AT91_REG *) 0xFFFC0044) // (US0) Nb Errors Register -#define AT91C_US0_CR (AT91_CAST(AT91_REG *) 0xFFFC0000) // (US0) Control Register -#define AT91C_US0_IMR (AT91_CAST(AT91_REG *) 0xFFFC0010) // (US0) Interrupt Mask Register -#define AT91C_US0_FIDI (AT91_CAST(AT91_REG *) 0xFFFC0040) // (US0) FI_DI_Ratio Register -#define AT91C_US0_TTGR (AT91_CAST(AT91_REG *) 0xFFFC0028) // (US0) Transmitter Time-guard Register -#define AT91C_US0_MR (AT91_CAST(AT91_REG *) 0xFFFC0004) // (US0) Mode Register -#define AT91C_US0_RTOR (AT91_CAST(AT91_REG *) 0xFFFC0024) // (US0) Receiver Time-out Register -#define AT91C_US0_CSR (AT91_CAST(AT91_REG *) 0xFFFC0014) // (US0) Channel Status Register -#define AT91C_US0_RHR (AT91_CAST(AT91_REG *) 0xFFFC0018) // (US0) Receiver Holding Register -#define AT91C_US0_IDR (AT91_CAST(AT91_REG *) 0xFFFC000C) // (US0) Interrupt Disable Register -#define AT91C_US0_THR (AT91_CAST(AT91_REG *) 0xFFFC001C) // (US0) Transmitter Holding Register -#define AT91C_US0_IF (AT91_CAST(AT91_REG *) 0xFFFC004C) // (US0) IRDA_FILTER Register -#define AT91C_US0_IER (AT91_CAST(AT91_REG *) 0xFFFC0008) // (US0) Interrupt Enable Register +#define AT91C_US0_BRGR (AT91_CAST(AT91_REG *) 0xFFFC0020) // (US0) Baud Rate Generator Register +#define AT91C_US0_NER (AT91_CAST(AT91_REG *) 0xFFFC0044) // (US0) Nb Errors Register +#define AT91C_US0_CR (AT91_CAST(AT91_REG *) 0xFFFC0000) // (US0) Control Register +#define AT91C_US0_IMR (AT91_CAST(AT91_REG *) 0xFFFC0010) // (US0) Interrupt Mask Register +#define AT91C_US0_FIDI (AT91_CAST(AT91_REG *) 0xFFFC0040) // (US0) FI_DI_Ratio Register +#define AT91C_US0_TTGR (AT91_CAST(AT91_REG *) 0xFFFC0028) // (US0) Transmitter Time-guard Register +#define AT91C_US0_MR (AT91_CAST(AT91_REG *) 0xFFFC0004) // (US0) Mode Register +#define AT91C_US0_RTOR (AT91_CAST(AT91_REG *) 0xFFFC0024) // (US0) Receiver Time-out Register +#define AT91C_US0_CSR (AT91_CAST(AT91_REG *) 0xFFFC0014) // (US0) Channel Status Register +#define AT91C_US0_RHR (AT91_CAST(AT91_REG *) 0xFFFC0018) // (US0) Receiver Holding Register +#define AT91C_US0_IDR (AT91_CAST(AT91_REG *) 0xFFFC000C) // (US0) Interrupt Disable Register +#define AT91C_US0_THR (AT91_CAST(AT91_REG *) 0xFFFC001C) // (US0) Transmitter Holding Register +#define AT91C_US0_IF (AT91_CAST(AT91_REG *) 0xFFFC004C) // (US0) IRDA_FILTER Register +#define AT91C_US0_IER (AT91_CAST(AT91_REG *) 0xFFFC0008) // (US0) Interrupt Enable Register // ========== Register definition for TWI peripheral ========== -#define AT91C_TWI_IER (AT91_CAST(AT91_REG *) 0xFFFB8024) // (TWI) Interrupt Enable Register -#define AT91C_TWI_CR (AT91_CAST(AT91_REG *) 0xFFFB8000) // (TWI) Control Register -#define AT91C_TWI_SR (AT91_CAST(AT91_REG *) 0xFFFB8020) // (TWI) Status Register -#define AT91C_TWI_IMR (AT91_CAST(AT91_REG *) 0xFFFB802C) // (TWI) Interrupt Mask Register -#define AT91C_TWI_THR (AT91_CAST(AT91_REG *) 0xFFFB8034) // (TWI) Transmit Holding Register -#define AT91C_TWI_IDR (AT91_CAST(AT91_REG *) 0xFFFB8028) // (TWI) Interrupt Disable Register -#define AT91C_TWI_IADR (AT91_CAST(AT91_REG *) 0xFFFB800C) // (TWI) Internal Address Register -#define AT91C_TWI_MMR (AT91_CAST(AT91_REG *) 0xFFFB8004) // (TWI) Master Mode Register -#define AT91C_TWI_CWGR (AT91_CAST(AT91_REG *) 0xFFFB8010) // (TWI) Clock Waveform Generator Register -#define AT91C_TWI_RHR (AT91_CAST(AT91_REG *) 0xFFFB8030) // (TWI) Receive Holding Register +#define AT91C_TWI_IER (AT91_CAST(AT91_REG *) 0xFFFB8024) // (TWI) Interrupt Enable Register +#define AT91C_TWI_CR (AT91_CAST(AT91_REG *) 0xFFFB8000) // (TWI) Control Register +#define AT91C_TWI_SR (AT91_CAST(AT91_REG *) 0xFFFB8020) // (TWI) Status Register +#define AT91C_TWI_IMR (AT91_CAST(AT91_REG *) 0xFFFB802C) // (TWI) Interrupt Mask Register +#define AT91C_TWI_THR (AT91_CAST(AT91_REG *) 0xFFFB8034) // (TWI) Transmit Holding Register +#define AT91C_TWI_IDR (AT91_CAST(AT91_REG *) 0xFFFB8028) // (TWI) Interrupt Disable Register +#define AT91C_TWI_IADR (AT91_CAST(AT91_REG *) 0xFFFB800C) // (TWI) Internal Address Register +#define AT91C_TWI_MMR (AT91_CAST(AT91_REG *) 0xFFFB8004) // (TWI) Master Mode Register +#define AT91C_TWI_CWGR (AT91_CAST(AT91_REG *) 0xFFFB8010) // (TWI) Clock Waveform Generator Register +#define AT91C_TWI_RHR (AT91_CAST(AT91_REG *) 0xFFFB8030) // (TWI) Receive Holding Register // ========== Register definition for TC0 peripheral ========== -#define AT91C_TC0_SR (AT91_CAST(AT91_REG *) 0xFFFA0020) // (TC0) Status Register -#define AT91C_TC0_RC (AT91_CAST(AT91_REG *) 0xFFFA001C) // (TC0) Register C -#define AT91C_TC0_RB (AT91_CAST(AT91_REG *) 0xFFFA0018) // (TC0) Register B -#define AT91C_TC0_CCR (AT91_CAST(AT91_REG *) 0xFFFA0000) // (TC0) Channel Control Register -#define AT91C_TC0_CMR (AT91_CAST(AT91_REG *) 0xFFFA0004) // (TC0) Channel Mode Register (Capture Mode / Waveform Mode) -#define AT91C_TC0_IER (AT91_CAST(AT91_REG *) 0xFFFA0024) // (TC0) Interrupt Enable Register -#define AT91C_TC0_RA (AT91_CAST(AT91_REG *) 0xFFFA0014) // (TC0) Register A -#define AT91C_TC0_IDR (AT91_CAST(AT91_REG *) 0xFFFA0028) // (TC0) Interrupt Disable Register -#define AT91C_TC0_CV (AT91_CAST(AT91_REG *) 0xFFFA0010) // (TC0) Counter Value -#define AT91C_TC0_IMR (AT91_CAST(AT91_REG *) 0xFFFA002C) // (TC0) Interrupt Mask Register +#define AT91C_TC0_SR (AT91_CAST(AT91_REG *) 0xFFFA0020) // (TC0) Status Register +#define AT91C_TC0_RC (AT91_CAST(AT91_REG *) 0xFFFA001C) // (TC0) Register C +#define AT91C_TC0_RB (AT91_CAST(AT91_REG *) 0xFFFA0018) // (TC0) Register B +#define AT91C_TC0_CCR (AT91_CAST(AT91_REG *) 0xFFFA0000) // (TC0) Channel Control Register +#define AT91C_TC0_CMR (AT91_CAST(AT91_REG *) 0xFFFA0004) // (TC0) Channel Mode Register (Capture Mode / Waveform Mode) +#define AT91C_TC0_IER (AT91_CAST(AT91_REG *) 0xFFFA0024) // (TC0) Interrupt Enable Register +#define AT91C_TC0_RA (AT91_CAST(AT91_REG *) 0xFFFA0014) // (TC0) Register A +#define AT91C_TC0_IDR (AT91_CAST(AT91_REG *) 0xFFFA0028) // (TC0) Interrupt Disable Register +#define AT91C_TC0_CV (AT91_CAST(AT91_REG *) 0xFFFA0010) // (TC0) Counter Value +#define AT91C_TC0_IMR (AT91_CAST(AT91_REG *) 0xFFFA002C) // (TC0) Interrupt Mask Register // ========== Register definition for TC1 peripheral ========== -#define AT91C_TC1_RB (AT91_CAST(AT91_REG *) 0xFFFA0058) // (TC1) Register B -#define AT91C_TC1_CCR (AT91_CAST(AT91_REG *) 0xFFFA0040) // (TC1) Channel Control Register -#define AT91C_TC1_IER (AT91_CAST(AT91_REG *) 0xFFFA0064) // (TC1) Interrupt Enable Register -#define AT91C_TC1_IDR (AT91_CAST(AT91_REG *) 0xFFFA0068) // (TC1) Interrupt Disable Register -#define AT91C_TC1_SR (AT91_CAST(AT91_REG *) 0xFFFA0060) // (TC1) Status Register -#define AT91C_TC1_CMR (AT91_CAST(AT91_REG *) 0xFFFA0044) // (TC1) Channel Mode Register (Capture Mode / Waveform Mode) -#define AT91C_TC1_RA (AT91_CAST(AT91_REG *) 0xFFFA0054) // (TC1) Register A -#define AT91C_TC1_RC (AT91_CAST(AT91_REG *) 0xFFFA005C) // (TC1) Register C -#define AT91C_TC1_IMR (AT91_CAST(AT91_REG *) 0xFFFA006C) // (TC1) Interrupt Mask Register -#define AT91C_TC1_CV (AT91_CAST(AT91_REG *) 0xFFFA0050) // (TC1) Counter Value +#define AT91C_TC1_RB (AT91_CAST(AT91_REG *) 0xFFFA0058) // (TC1) Register B +#define AT91C_TC1_CCR (AT91_CAST(AT91_REG *) 0xFFFA0040) // (TC1) Channel Control Register +#define AT91C_TC1_IER (AT91_CAST(AT91_REG *) 0xFFFA0064) // (TC1) Interrupt Enable Register +#define AT91C_TC1_IDR (AT91_CAST(AT91_REG *) 0xFFFA0068) // (TC1) Interrupt Disable Register +#define AT91C_TC1_SR (AT91_CAST(AT91_REG *) 0xFFFA0060) // (TC1) Status Register +#define AT91C_TC1_CMR (AT91_CAST(AT91_REG *) 0xFFFA0044) // (TC1) Channel Mode Register (Capture Mode / Waveform Mode) +#define AT91C_TC1_RA (AT91_CAST(AT91_REG *) 0xFFFA0054) // (TC1) Register A +#define AT91C_TC1_RC (AT91_CAST(AT91_REG *) 0xFFFA005C) // (TC1) Register C +#define AT91C_TC1_IMR (AT91_CAST(AT91_REG *) 0xFFFA006C) // (TC1) Interrupt Mask Register +#define AT91C_TC1_CV (AT91_CAST(AT91_REG *) 0xFFFA0050) // (TC1) Counter Value // ========== Register definition for TC2 peripheral ========== -#define AT91C_TC2_CMR (AT91_CAST(AT91_REG *) 0xFFFA0084) // (TC2) Channel Mode Register (Capture Mode / Waveform Mode) -#define AT91C_TC2_CCR (AT91_CAST(AT91_REG *) 0xFFFA0080) // (TC2) Channel Control Register -#define AT91C_TC2_CV (AT91_CAST(AT91_REG *) 0xFFFA0090) // (TC2) Counter Value -#define AT91C_TC2_RA (AT91_CAST(AT91_REG *) 0xFFFA0094) // (TC2) Register A -#define AT91C_TC2_RB (AT91_CAST(AT91_REG *) 0xFFFA0098) // (TC2) Register B -#define AT91C_TC2_IDR (AT91_CAST(AT91_REG *) 0xFFFA00A8) // (TC2) Interrupt Disable Register -#define AT91C_TC2_IMR (AT91_CAST(AT91_REG *) 0xFFFA00AC) // (TC2) Interrupt Mask Register -#define AT91C_TC2_RC (AT91_CAST(AT91_REG *) 0xFFFA009C) // (TC2) Register C -#define AT91C_TC2_IER (AT91_CAST(AT91_REG *) 0xFFFA00A4) // (TC2) Interrupt Enable Register -#define AT91C_TC2_SR (AT91_CAST(AT91_REG *) 0xFFFA00A0) // (TC2) Status Register +#define AT91C_TC2_CMR (AT91_CAST(AT91_REG *) 0xFFFA0084) // (TC2) Channel Mode Register (Capture Mode / Waveform Mode) +#define AT91C_TC2_CCR (AT91_CAST(AT91_REG *) 0xFFFA0080) // (TC2) Channel Control Register +#define AT91C_TC2_CV (AT91_CAST(AT91_REG *) 0xFFFA0090) // (TC2) Counter Value +#define AT91C_TC2_RA (AT91_CAST(AT91_REG *) 0xFFFA0094) // (TC2) Register A +#define AT91C_TC2_RB (AT91_CAST(AT91_REG *) 0xFFFA0098) // (TC2) Register B +#define AT91C_TC2_IDR (AT91_CAST(AT91_REG *) 0xFFFA00A8) // (TC2) Interrupt Disable Register +#define AT91C_TC2_IMR (AT91_CAST(AT91_REG *) 0xFFFA00AC) // (TC2) Interrupt Mask Register +#define AT91C_TC2_RC (AT91_CAST(AT91_REG *) 0xFFFA009C) // (TC2) Register C +#define AT91C_TC2_IER (AT91_CAST(AT91_REG *) 0xFFFA00A4) // (TC2) Interrupt Enable Register +#define AT91C_TC2_SR (AT91_CAST(AT91_REG *) 0xFFFA00A0) // (TC2) Status Register // ========== Register definition for TCB peripheral ========== -#define AT91C_TCB_BMR (AT91_CAST(AT91_REG *) 0xFFFA00C4) // (TCB) TC Block Mode Register -#define AT91C_TCB_BCR (AT91_CAST(AT91_REG *) 0xFFFA00C0) // (TCB) TC Block Control Register +#define AT91C_TCB_BMR (AT91_CAST(AT91_REG *) 0xFFFA00C4) // (TCB) TC Block Mode Register +#define AT91C_TCB_BCR (AT91_CAST(AT91_REG *) 0xFFFA00C0) // (TCB) TC Block Control Register // ========== Register definition for PWMC_CH3 peripheral ========== -#define AT91C_PWMC_CH3_CUPDR (AT91_CAST(AT91_REG *) 0xFFFCC270) // (PWMC_CH3) Channel Update Register -#define AT91C_PWMC_CH3_Reserved (AT91_CAST(AT91_REG *) 0xFFFCC274) // (PWMC_CH3) Reserved -#define AT91C_PWMC_CH3_CPRDR (AT91_CAST(AT91_REG *) 0xFFFCC268) // (PWMC_CH3) Channel Period Register -#define AT91C_PWMC_CH3_CDTYR (AT91_CAST(AT91_REG *) 0xFFFCC264) // (PWMC_CH3) Channel Duty Cycle Register -#define AT91C_PWMC_CH3_CCNTR (AT91_CAST(AT91_REG *) 0xFFFCC26C) // (PWMC_CH3) Channel Counter Register -#define AT91C_PWMC_CH3_CMR (AT91_CAST(AT91_REG *) 0xFFFCC260) // (PWMC_CH3) Channel Mode Register +#define AT91C_PWMC_CH3_CUPDR (AT91_CAST(AT91_REG *) 0xFFFCC270) // (PWMC_CH3) Channel Update Register +#define AT91C_PWMC_CH3_Reserved (AT91_CAST(AT91_REG *) 0xFFFCC274) // (PWMC_CH3) Reserved +#define AT91C_PWMC_CH3_CPRDR (AT91_CAST(AT91_REG *) 0xFFFCC268) // (PWMC_CH3) Channel Period Register +#define AT91C_PWMC_CH3_CDTYR (AT91_CAST(AT91_REG *) 0xFFFCC264) // (PWMC_CH3) Channel Duty Cycle Register +#define AT91C_PWMC_CH3_CCNTR (AT91_CAST(AT91_REG *) 0xFFFCC26C) // (PWMC_CH3) Channel Counter Register +#define AT91C_PWMC_CH3_CMR (AT91_CAST(AT91_REG *) 0xFFFCC260) // (PWMC_CH3) Channel Mode Register // ========== Register definition for PWMC_CH2 peripheral ========== -#define AT91C_PWMC_CH2_Reserved (AT91_CAST(AT91_REG *) 0xFFFCC254) // (PWMC_CH2) Reserved -#define AT91C_PWMC_CH2_CMR (AT91_CAST(AT91_REG *) 0xFFFCC240) // (PWMC_CH2) Channel Mode Register -#define AT91C_PWMC_CH2_CCNTR (AT91_CAST(AT91_REG *) 0xFFFCC24C) // (PWMC_CH2) Channel Counter Register -#define AT91C_PWMC_CH2_CPRDR (AT91_CAST(AT91_REG *) 0xFFFCC248) // (PWMC_CH2) Channel Period Register -#define AT91C_PWMC_CH2_CUPDR (AT91_CAST(AT91_REG *) 0xFFFCC250) // (PWMC_CH2) Channel Update Register -#define AT91C_PWMC_CH2_CDTYR (AT91_CAST(AT91_REG *) 0xFFFCC244) // (PWMC_CH2) Channel Duty Cycle Register +#define AT91C_PWMC_CH2_Reserved (AT91_CAST(AT91_REG *) 0xFFFCC254) // (PWMC_CH2) Reserved +#define AT91C_PWMC_CH2_CMR (AT91_CAST(AT91_REG *) 0xFFFCC240) // (PWMC_CH2) Channel Mode Register +#define AT91C_PWMC_CH2_CCNTR (AT91_CAST(AT91_REG *) 0xFFFCC24C) // (PWMC_CH2) Channel Counter Register +#define AT91C_PWMC_CH2_CPRDR (AT91_CAST(AT91_REG *) 0xFFFCC248) // (PWMC_CH2) Channel Period Register +#define AT91C_PWMC_CH2_CUPDR (AT91_CAST(AT91_REG *) 0xFFFCC250) // (PWMC_CH2) Channel Update Register +#define AT91C_PWMC_CH2_CDTYR (AT91_CAST(AT91_REG *) 0xFFFCC244) // (PWMC_CH2) Channel Duty Cycle Register // ========== Register definition for PWMC_CH1 peripheral ========== -#define AT91C_PWMC_CH1_Reserved (AT91_CAST(AT91_REG *) 0xFFFCC234) // (PWMC_CH1) Reserved -#define AT91C_PWMC_CH1_CUPDR (AT91_CAST(AT91_REG *) 0xFFFCC230) // (PWMC_CH1) Channel Update Register -#define AT91C_PWMC_CH1_CPRDR (AT91_CAST(AT91_REG *) 0xFFFCC228) // (PWMC_CH1) Channel Period Register -#define AT91C_PWMC_CH1_CCNTR (AT91_CAST(AT91_REG *) 0xFFFCC22C) // (PWMC_CH1) Channel Counter Register -#define AT91C_PWMC_CH1_CDTYR (AT91_CAST(AT91_REG *) 0xFFFCC224) // (PWMC_CH1) Channel Duty Cycle Register -#define AT91C_PWMC_CH1_CMR (AT91_CAST(AT91_REG *) 0xFFFCC220) // (PWMC_CH1) Channel Mode Register +#define AT91C_PWMC_CH1_Reserved (AT91_CAST(AT91_REG *) 0xFFFCC234) // (PWMC_CH1) Reserved +#define AT91C_PWMC_CH1_CUPDR (AT91_CAST(AT91_REG *) 0xFFFCC230) // (PWMC_CH1) Channel Update Register +#define AT91C_PWMC_CH1_CPRDR (AT91_CAST(AT91_REG *) 0xFFFCC228) // (PWMC_CH1) Channel Period Register +#define AT91C_PWMC_CH1_CCNTR (AT91_CAST(AT91_REG *) 0xFFFCC22C) // (PWMC_CH1) Channel Counter Register +#define AT91C_PWMC_CH1_CDTYR (AT91_CAST(AT91_REG *) 0xFFFCC224) // (PWMC_CH1) Channel Duty Cycle Register +#define AT91C_PWMC_CH1_CMR (AT91_CAST(AT91_REG *) 0xFFFCC220) // (PWMC_CH1) Channel Mode Register // ========== Register definition for PWMC_CH0 peripheral ========== -#define AT91C_PWMC_CH0_Reserved (AT91_CAST(AT91_REG *) 0xFFFCC214) // (PWMC_CH0) Reserved -#define AT91C_PWMC_CH0_CPRDR (AT91_CAST(AT91_REG *) 0xFFFCC208) // (PWMC_CH0) Channel Period Register -#define AT91C_PWMC_CH0_CDTYR (AT91_CAST(AT91_REG *) 0xFFFCC204) // (PWMC_CH0) Channel Duty Cycle Register -#define AT91C_PWMC_CH0_CMR (AT91_CAST(AT91_REG *) 0xFFFCC200) // (PWMC_CH0) Channel Mode Register -#define AT91C_PWMC_CH0_CUPDR (AT91_CAST(AT91_REG *) 0xFFFCC210) // (PWMC_CH0) Channel Update Register -#define AT91C_PWMC_CH0_CCNTR (AT91_CAST(AT91_REG *) 0xFFFCC20C) // (PWMC_CH0) Channel Counter Register +#define AT91C_PWMC_CH0_Reserved (AT91_CAST(AT91_REG *) 0xFFFCC214) // (PWMC_CH0) Reserved +#define AT91C_PWMC_CH0_CPRDR (AT91_CAST(AT91_REG *) 0xFFFCC208) // (PWMC_CH0) Channel Period Register +#define AT91C_PWMC_CH0_CDTYR (AT91_CAST(AT91_REG *) 0xFFFCC204) // (PWMC_CH0) Channel Duty Cycle Register +#define AT91C_PWMC_CH0_CMR (AT91_CAST(AT91_REG *) 0xFFFCC200) // (PWMC_CH0) Channel Mode Register +#define AT91C_PWMC_CH0_CUPDR (AT91_CAST(AT91_REG *) 0xFFFCC210) // (PWMC_CH0) Channel Update Register +#define AT91C_PWMC_CH0_CCNTR (AT91_CAST(AT91_REG *) 0xFFFCC20C) // (PWMC_CH0) Channel Counter Register // ========== Register definition for PWMC peripheral ========== -#define AT91C_PWMC_IDR (AT91_CAST(AT91_REG *) 0xFFFCC014) // (PWMC) PWMC Interrupt Disable Register -#define AT91C_PWMC_DIS (AT91_CAST(AT91_REG *) 0xFFFCC008) // (PWMC) PWMC Disable Register -#define AT91C_PWMC_IER (AT91_CAST(AT91_REG *) 0xFFFCC010) // (PWMC) PWMC Interrupt Enable Register -#define AT91C_PWMC_VR (AT91_CAST(AT91_REG *) 0xFFFCC0FC) // (PWMC) PWMC Version Register -#define AT91C_PWMC_ISR (AT91_CAST(AT91_REG *) 0xFFFCC01C) // (PWMC) PWMC Interrupt Status Register -#define AT91C_PWMC_SR (AT91_CAST(AT91_REG *) 0xFFFCC00C) // (PWMC) PWMC Status Register -#define AT91C_PWMC_IMR (AT91_CAST(AT91_REG *) 0xFFFCC018) // (PWMC) PWMC Interrupt Mask Register -#define AT91C_PWMC_MR (AT91_CAST(AT91_REG *) 0xFFFCC000) // (PWMC) PWMC Mode Register -#define AT91C_PWMC_ENA (AT91_CAST(AT91_REG *) 0xFFFCC004) // (PWMC) PWMC Enable Register +#define AT91C_PWMC_IDR (AT91_CAST(AT91_REG *) 0xFFFCC014) // (PWMC) PWMC Interrupt Disable Register +#define AT91C_PWMC_DIS (AT91_CAST(AT91_REG *) 0xFFFCC008) // (PWMC) PWMC Disable Register +#define AT91C_PWMC_IER (AT91_CAST(AT91_REG *) 0xFFFCC010) // (PWMC) PWMC Interrupt Enable Register +#define AT91C_PWMC_VR (AT91_CAST(AT91_REG *) 0xFFFCC0FC) // (PWMC) PWMC Version Register +#define AT91C_PWMC_ISR (AT91_CAST(AT91_REG *) 0xFFFCC01C) // (PWMC) PWMC Interrupt Status Register +#define AT91C_PWMC_SR (AT91_CAST(AT91_REG *) 0xFFFCC00C) // (PWMC) PWMC Status Register +#define AT91C_PWMC_IMR (AT91_CAST(AT91_REG *) 0xFFFCC018) // (PWMC) PWMC Interrupt Mask Register +#define AT91C_PWMC_MR (AT91_CAST(AT91_REG *) 0xFFFCC000) // (PWMC) PWMC Mode Register +#define AT91C_PWMC_ENA (AT91_CAST(AT91_REG *) 0xFFFCC004) // (PWMC) PWMC Enable Register // ========== Register definition for UDP peripheral ========== -#define AT91C_UDP_IMR (AT91_CAST(AT91_REG *) 0xFFFB0018) // (UDP) Interrupt Mask Register -#define AT91C_UDP_FADDR (AT91_CAST(AT91_REG *) 0xFFFB0008) // (UDP) Function Address Register -#define AT91C_UDP_NUM (AT91_CAST(AT91_REG *) 0xFFFB0000) // (UDP) Frame Number Register -#define AT91C_UDP_FDR (AT91_CAST(AT91_REG *) 0xFFFB0050) // (UDP) Endpoint FIFO Data Register -#define AT91C_UDP_ISR (AT91_CAST(AT91_REG *) 0xFFFB001C) // (UDP) Interrupt Status Register -#define AT91C_UDP_CSR (AT91_CAST(AT91_REG *) 0xFFFB0030) // (UDP) Endpoint Control and Status Register -#define AT91C_UDP_IDR (AT91_CAST(AT91_REG *) 0xFFFB0014) // (UDP) Interrupt Disable Register -#define AT91C_UDP_ICR (AT91_CAST(AT91_REG *) 0xFFFB0020) // (UDP) Interrupt Clear Register -#define AT91C_UDP_RSTEP (AT91_CAST(AT91_REG *) 0xFFFB0028) // (UDP) Reset Endpoint Register -#define AT91C_UDP_TXVC (AT91_CAST(AT91_REG *) 0xFFFB0074) // (UDP) Transceiver Control Register -#define AT91C_UDP_GLBSTATE (AT91_CAST(AT91_REG *) 0xFFFB0004) // (UDP) Global State Register -#define AT91C_UDP_IER (AT91_CAST(AT91_REG *) 0xFFFB0010) // (UDP) Interrupt Enable Register +#define AT91C_UDP_IMR (AT91_CAST(AT91_REG *) 0xFFFB0018) // (UDP) Interrupt Mask Register +#define AT91C_UDP_FADDR (AT91_CAST(AT91_REG *) 0xFFFB0008) // (UDP) Function Address Register +#define AT91C_UDP_NUM (AT91_CAST(AT91_REG *) 0xFFFB0000) // (UDP) Frame Number Register +#define AT91C_UDP_FDR (AT91_CAST(AT91_REG *) 0xFFFB0050) // (UDP) Endpoint FIFO Data Register +#define AT91C_UDP_ISR (AT91_CAST(AT91_REG *) 0xFFFB001C) // (UDP) Interrupt Status Register +#define AT91C_UDP_CSR (AT91_CAST(AT91_REG *) 0xFFFB0030) // (UDP) Endpoint Control and Status Register +#define AT91C_UDP_IDR (AT91_CAST(AT91_REG *) 0xFFFB0014) // (UDP) Interrupt Disable Register +#define AT91C_UDP_ICR (AT91_CAST(AT91_REG *) 0xFFFB0020) // (UDP) Interrupt Clear Register +#define AT91C_UDP_RSTEP (AT91_CAST(AT91_REG *) 0xFFFB0028) // (UDP) Reset Endpoint Register +#define AT91C_UDP_TXVC (AT91_CAST(AT91_REG *) 0xFFFB0074) // (UDP) Transceiver Control Register +#define AT91C_UDP_GLBSTATE (AT91_CAST(AT91_REG *) 0xFFFB0004) // (UDP) Global State Register +#define AT91C_UDP_IER (AT91_CAST(AT91_REG *) 0xFFFB0010) // (UDP) Interrupt Enable Register // ***************************************************************************** // PIO DEFINITIONS FOR AT91SAM7S512 @@ -2242,55 +2242,55 @@ typedef struct _AT91S_UDP { // ***************************************************************************** // BASE ADDRESS DEFINITIONS FOR AT91SAM7S512 // ***************************************************************************** -#define AT91C_BASE_SYS (AT91_CAST(AT91PS_SYS) 0xFFFFF000) // (SYS) Base Address -#define AT91C_BASE_AIC (AT91_CAST(AT91PS_AIC) 0xFFFFF000) // (AIC) Base Address -#define AT91C_BASE_PDC_DBGU (AT91_CAST(AT91PS_PDC) 0xFFFFF300) // (PDC_DBGU) Base Address -#define AT91C_BASE_DBGU (AT91_CAST(AT91PS_DBGU) 0xFFFFF200) // (DBGU) Base Address -#define AT91C_BASE_PIOA (AT91_CAST(AT91PS_PIO) 0xFFFFF400) // (PIOA) Base Address -#define AT91C_BASE_CKGR (AT91_CAST(AT91PS_CKGR) 0xFFFFFC20) // (CKGR) Base Address -#define AT91C_BASE_PMC (AT91_CAST(AT91PS_PMC) 0xFFFFFC00) // (PMC) Base Address -#define AT91C_BASE_RSTC (AT91_CAST(AT91PS_RSTC) 0xFFFFFD00) // (RSTC) Base Address -#define AT91C_BASE_RTTC (AT91_CAST(AT91PS_RTTC) 0xFFFFFD20) // (RTTC) Base Address -#define AT91C_BASE_PITC (AT91_CAST(AT91PS_PITC) 0xFFFFFD30) // (PITC) Base Address -#define AT91C_BASE_WDTC (AT91_CAST(AT91PS_WDTC) 0xFFFFFD40) // (WDTC) Base Address -#define AT91C_BASE_VREG (AT91_CAST(AT91PS_VREG) 0xFFFFFD60) // (VREG) Base Address -#define AT91C_BASE_EFC0 (AT91_CAST(AT91PS_EFC) 0xFFFFFF60) // (EFC0) Base Address -#define AT91C_BASE_EFC1 (AT91_CAST(AT91PS_EFC) 0xFFFFFF70) // (EFC1) Base Address -#define AT91C_BASE_MC (AT91_CAST(AT91PS_MC) 0xFFFFFF00) // (MC) Base Address -#define AT91C_BASE_PDC_SPI (AT91_CAST(AT91PS_PDC) 0xFFFE0100) // (PDC_SPI) Base Address -#define AT91C_BASE_SPI (AT91_CAST(AT91PS_SPI) 0xFFFE0000) // (SPI) Base Address -#define AT91C_BASE_PDC_ADC (AT91_CAST(AT91PS_PDC) 0xFFFD8100) // (PDC_ADC) Base Address -#define AT91C_BASE_ADC (AT91_CAST(AT91PS_ADC) 0xFFFD8000) // (ADC) Base Address -#define AT91C_BASE_PDC_SSC (AT91_CAST(AT91PS_PDC) 0xFFFD4100) // (PDC_SSC) Base Address -#define AT91C_BASE_SSC (AT91_CAST(AT91PS_SSC) 0xFFFD4000) // (SSC) Base Address -#define AT91C_BASE_PDC_US1 (AT91_CAST(AT91PS_PDC) 0xFFFC4100) // (PDC_US1) Base Address -#define AT91C_BASE_US1 (AT91_CAST(AT91PS_USART) 0xFFFC4000) // (US1) Base Address -#define AT91C_BASE_PDC_US0 (AT91_CAST(AT91PS_PDC) 0xFFFC0100) // (PDC_US0) Base Address -#define AT91C_BASE_US0 (AT91_CAST(AT91PS_USART) 0xFFFC0000) // (US0) Base Address -#define AT91C_BASE_TWI (AT91_CAST(AT91PS_TWI) 0xFFFB8000) // (TWI) Base Address -#define AT91C_BASE_TC0 (AT91_CAST(AT91PS_TC) 0xFFFA0000) // (TC0) Base Address -#define AT91C_BASE_TC1 (AT91_CAST(AT91PS_TC) 0xFFFA0040) // (TC1) Base Address -#define AT91C_BASE_TC2 (AT91_CAST(AT91PS_TC) 0xFFFA0080) // (TC2) Base Address -#define AT91C_BASE_TCB (AT91_CAST(AT91PS_TCB) 0xFFFA0000) // (TCB) Base Address +#define AT91C_BASE_SYS (AT91_CAST(AT91PS_SYS) 0xFFFFF000) // (SYS) Base Address +#define AT91C_BASE_AIC (AT91_CAST(AT91PS_AIC) 0xFFFFF000) // (AIC) Base Address +#define AT91C_BASE_PDC_DBGU (AT91_CAST(AT91PS_PDC) 0xFFFFF300) // (PDC_DBGU) Base Address +#define AT91C_BASE_DBGU (AT91_CAST(AT91PS_DBGU) 0xFFFFF200) // (DBGU) Base Address +#define AT91C_BASE_PIOA (AT91_CAST(AT91PS_PIO) 0xFFFFF400) // (PIOA) Base Address +#define AT91C_BASE_CKGR (AT91_CAST(AT91PS_CKGR) 0xFFFFFC20) // (CKGR) Base Address +#define AT91C_BASE_PMC (AT91_CAST(AT91PS_PMC) 0xFFFFFC00) // (PMC) Base Address +#define AT91C_BASE_RSTC (AT91_CAST(AT91PS_RSTC) 0xFFFFFD00) // (RSTC) Base Address +#define AT91C_BASE_RTTC (AT91_CAST(AT91PS_RTTC) 0xFFFFFD20) // (RTTC) Base Address +#define AT91C_BASE_PITC (AT91_CAST(AT91PS_PITC) 0xFFFFFD30) // (PITC) Base Address +#define AT91C_BASE_WDTC (AT91_CAST(AT91PS_WDTC) 0xFFFFFD40) // (WDTC) Base Address +#define AT91C_BASE_VREG (AT91_CAST(AT91PS_VREG) 0xFFFFFD60) // (VREG) Base Address +#define AT91C_BASE_EFC0 (AT91_CAST(AT91PS_EFC) 0xFFFFFF60) // (EFC0) Base Address +#define AT91C_BASE_EFC1 (AT91_CAST(AT91PS_EFC) 0xFFFFFF70) // (EFC1) Base Address +#define AT91C_BASE_MC (AT91_CAST(AT91PS_MC) 0xFFFFFF00) // (MC) Base Address +#define AT91C_BASE_PDC_SPI (AT91_CAST(AT91PS_PDC) 0xFFFE0100) // (PDC_SPI) Base Address +#define AT91C_BASE_SPI (AT91_CAST(AT91PS_SPI) 0xFFFE0000) // (SPI) Base Address +#define AT91C_BASE_PDC_ADC (AT91_CAST(AT91PS_PDC) 0xFFFD8100) // (PDC_ADC) Base Address +#define AT91C_BASE_ADC (AT91_CAST(AT91PS_ADC) 0xFFFD8000) // (ADC) Base Address +#define AT91C_BASE_PDC_SSC (AT91_CAST(AT91PS_PDC) 0xFFFD4100) // (PDC_SSC) Base Address +#define AT91C_BASE_SSC (AT91_CAST(AT91PS_SSC) 0xFFFD4000) // (SSC) Base Address +#define AT91C_BASE_PDC_US1 (AT91_CAST(AT91PS_PDC) 0xFFFC4100) // (PDC_US1) Base Address +#define AT91C_BASE_US1 (AT91_CAST(AT91PS_USART) 0xFFFC4000) // (US1) Base Address +#define AT91C_BASE_PDC_US0 (AT91_CAST(AT91PS_PDC) 0xFFFC0100) // (PDC_US0) Base Address +#define AT91C_BASE_US0 (AT91_CAST(AT91PS_USART) 0xFFFC0000) // (US0) Base Address +#define AT91C_BASE_TWI (AT91_CAST(AT91PS_TWI) 0xFFFB8000) // (TWI) Base Address +#define AT91C_BASE_TC0 (AT91_CAST(AT91PS_TC) 0xFFFA0000) // (TC0) Base Address +#define AT91C_BASE_TC1 (AT91_CAST(AT91PS_TC) 0xFFFA0040) // (TC1) Base Address +#define AT91C_BASE_TC2 (AT91_CAST(AT91PS_TC) 0xFFFA0080) // (TC2) Base Address +#define AT91C_BASE_TCB (AT91_CAST(AT91PS_TCB) 0xFFFA0000) // (TCB) Base Address #define AT91C_BASE_PWMC_CH3 (AT91_CAST(AT91PS_PWMC_CH) 0xFFFCC260) // (PWMC_CH3) Base Address #define AT91C_BASE_PWMC_CH2 (AT91_CAST(AT91PS_PWMC_CH) 0xFFFCC240) // (PWMC_CH2) Base Address #define AT91C_BASE_PWMC_CH1 (AT91_CAST(AT91PS_PWMC_CH) 0xFFFCC220) // (PWMC_CH1) Base Address #define AT91C_BASE_PWMC_CH0 (AT91_CAST(AT91PS_PWMC_CH) 0xFFFCC200) // (PWMC_CH0) Base Address -#define AT91C_BASE_PWMC (AT91_CAST(AT91PS_PWMC) 0xFFFCC000) // (PWMC) Base Address -#define AT91C_BASE_UDP (AT91_CAST(AT91PS_UDP) 0xFFFB0000) // (UDP) Base Address +#define AT91C_BASE_PWMC (AT91_CAST(AT91PS_PWMC) 0xFFFCC000) // (PWMC) Base Address +#define AT91C_BASE_UDP (AT91_CAST(AT91PS_UDP) 0xFFFB0000) // (UDP) Base Address // ***************************************************************************** // MEMORY MAPPING DEFINITIONS FOR AT91SAM7S512 // ***************************************************************************** // ISRAM -#define AT91C_ISRAM (0x00200000) // Internal SRAM base address -#define AT91C_ISRAM_SIZE (0x00010000) // Internal SRAM size in byte (64 Kbytes) +#define AT91C_ISRAM (0x00200000) // Internal SRAM base address +#define AT91C_ISRAM_SIZE (0x00010000) // Internal SRAM size in byte (64 Kbytes) // IFLASH -#define AT91C_IFLASH (0x00100000) // Internal FLASH base address -#define AT91C_IFLASH_SIZE (0x00080000) // Internal FLASH size in byte (512 Kbytes) -#define AT91C_IFLASH_PAGE_SIZE (256) // Internal FLASH Page Size: 256 bytes -#define AT91C_IFLASH_LOCK_REGION_SIZE (16384) // Internal FLASH Lock Region Size: 16 Kbytes -#define AT91C_IFLASH_NB_OF_PAGES (2048) // Internal FLASH Number of Pages: 2048 bytes -#define AT91C_IFLASH_NB_OF_LOCK_BITS (32) // Internal FLASH Number of Lock Bits: 32 bytes +#define AT91C_IFLASH (0x00100000) // Internal FLASH base address +#define AT91C_IFLASH_SIZE (0x00080000) // Internal FLASH size in byte (512 Kbytes) +#define AT91C_IFLASH_PAGE_SIZE (256) // Internal FLASH Page Size: 256 bytes +#define AT91C_IFLASH_LOCK_REGION_SIZE (16384) // Internal FLASH Lock Region Size: 16 Kbytes +#define AT91C_IFLASH_NB_OF_PAGES (2048) // Internal FLASH Number of Pages: 2048 bytes +#define AT91C_IFLASH_NB_OF_LOCK_BITS (32) // Internal FLASH Number of Lock Bits: 32 bytes #endif diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 63054d3a1..a3e5928a9 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -146,13 +146,13 @@ typedef struct { } t55xx_config; /*typedef struct { - uint16_t start_gap [4]; - uint16_t write_gap [4]; - uint16_t write_0 [4]; - uint16_t write_1 [4]; - uint16_t write_2 [4]; - uint16_t write_3 [4]; - uint16_t read_gap [4]; + uint16_t start_gap [4]; + uint16_t write_gap [4]; + uint16_t write_0 [4]; + uint16_t write_1 [4]; + uint16_t write_2 [4]; + uint16_t write_3 [4]; + uint16_t read_gap [4]; } t55xx_config; */ typedef struct { diff --git a/tools/jtag_openocd/chip-at91sam7s.cfg b/tools/jtag_openocd/chip-at91sam7s.cfg index a0787770a..7c546e45a 100644 --- a/tools/jtag_openocd/chip-at91sam7s.cfg +++ b/tools/jtag_openocd/chip-at91sam7s.cfg @@ -7,18 +7,18 @@ jtag newtap sam7x cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id 0x3f0f0f0 target create sam7x.cpu arm7tdmi -endian little -chain-position sam7x.cpu sam7x.cpu configure -event reset-init { - soft_reset_halt - mww 0xfffffd00 0xa5000004 # RSTC_CR: Reset peripherals - mww 0xfffffd44 0x00008000 # WDT_MR: disable watchdog - mww 0xfffffd08 0xa5000001 # RSTC_MR enable user reset - mww 0xfffffc20 0x00005001 # CKGR_MOR : enable the main oscillator - sleep 10 - mww 0xfffffc2c 0x000b1c02 # CKGR_PLLR: 16MHz * 12/2 = 96MHz - sleep 10 - mww 0xfffffc30 0x00000007 # PMC_MCKR : MCK = PLL / 2 = 48 MHz - sleep 10 - mww 0xffffff60 0x00480100 # MC_FMR: flash mode (FWS=1,FMCN=72) - sleep 100 + soft_reset_halt + mww 0xfffffd00 0xa5000004 # RSTC_CR: Reset peripherals + mww 0xfffffd44 0x00008000 # WDT_MR: disable watchdog + mww 0xfffffd08 0xa5000001 # RSTC_MR enable user reset + mww 0xfffffc20 0x00005001 # CKGR_MOR : enable the main oscillator + sleep 10 + mww 0xfffffc2c 0x000b1c02 # CKGR_PLLR: 16MHz * 12/2 = 96MHz + sleep 10 + mww 0xfffffc30 0x00000007 # PMC_MCKR : MCK = PLL / 2 = 48 MHz + sleep 10 + mww 0xffffff60 0x00480100 # MC_FMR: flash mode (FWS=1,FMCN=72) + sleep 100 } gdb_memory_map enable diff --git a/tools/mfkey/example_trace.txt b/tools/mfkey/example_trace.txt index 694a738f6..a236706b9 100644 --- a/tools/mfkey/example_trace.txt +++ b/tools/mfkey/example_trace.txt @@ -35,25 +35,25 @@ New functionality from @zhovner, ----------------------------------------------------------------------------------------------------- ### Communication decryption -RDR 26 -TAG 04 00 -RDR 93 20 -TAG 14 57 9f 69 b5 -RDR 93 70 14 57 9f 69 b5 2e 51 -TAG 08 b6 dd -RDR 60 14 50 2d -TAG ce 84 42 61 -RDR f8 04 9c cb 05 25 c8 4f -TAG 94 31 cc 40 -RDR 70 93 df 99 -TAG 99 72 42 8c e2 e8 52 3f 45 6b 99 c8 31 e7 69 dc ed 09 -RDR 8c a6 82 7b -TAG ab 79 7f d3 69 e8 b9 3a 86 77 6b 40 da e3 ef 68 6e fd -RDR c3 c3 81 ba -TAG 49 e2 c9 de f4 86 8d 17 77 67 0e 58 4c 27 23 02 86 f4 -RDR fb dc d7 c1 -TAG 4a bd 96 4b 07 d3 56 3a a0 66 ed 0a 2e ac 7f 63 12 bf -RDR 9f 91 49 ea +RDR 26 +TAG 04 00 +RDR 93 20 +TAG 14 57 9f 69 b5 +RDR 93 70 14 57 9f 69 b5 2e 51 +TAG 08 b6 dd +RDR 60 14 50 2d +TAG ce 84 42 61 +RDR f8 04 9c cb 05 25 c8 4f +TAG 94 31 cc 40 +RDR 70 93 df 99 +TAG 99 72 42 8c e2 e8 52 3f 45 6b 99 c8 31 e7 69 dc ed 09 +RDR 8c a6 82 7b +TAG ab 79 7f d3 69 e8 b9 3a 86 77 6b 40 da e3 ef 68 6e fd +RDR c3 c3 81 ba +TAG 49 e2 c9 de f4 86 8d 17 77 67 0e 58 4c 27 23 02 86 f4 +RDR fb dc d7 c1 +TAG 4a bd 96 4b 07 d3 56 3a a0 66 ed 0a 2e ac 7f 63 12 bf +RDR 9f 91 49 ea ./mfkey64 14579f69 ce844261 f8049ccb 0525c84f 9431cc40 7093df99 9972428ce2e8523f456b99c831e769dced09 8ca6827b ab797fd369e8b93a86776b40dae3ef686efd c3c381ba 49e2c9def4868d1777670e584c27230286f4 fbdcd7c1 4abd964b07d3563aa066ed0a2eac7f6312bf 9f9149ea @@ -93,4 +93,4 @@ Decrypted communication: {dec7}: 0000000000007e178869000000000000c4f2 {dec8}: 61148834 -Found Key: [091e639cb715] \ No newline at end of file +Found Key: [091e639cb715] From 2fee6f597dde5b2be95a3bdf65a554d93aa5f2ce Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 24 Jul 2019 00:56:01 +0200 Subject: [PATCH 0150/1854] add tab detection in Makefile --- Makefile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 64dbea4eb..587fdf09d 100644 --- a/Makefile +++ b/Makefile @@ -156,10 +156,13 @@ style: --style=google --pad-oper --unpad-paren --pad-header \ --align-pointer=name {} \; -# Detecting weird codepages. +# Detecting weird codepages and tabs. checks: find . \( -name "*.[ch]" -or -name "*.cpp" -or -name "*.lua" -or -name "*.py" -or -name "*.pl" -or -name "Makefile" \) \ -exec sh -c "cat {} |recode utf8.. >/dev/null || echo {}" \; + find . \( -name "*.[ch]" -or \( -name "*.cpp" -and -not -name "*.moc.cpp" \) -or -name "*.lua" -or -name "*.py" -or -name "*.pl" -or -name "*.md" -or -name "*.txt" -or -name "*.awk" \) \ + -exec grep -lP '\t' {} \; +# to remove tabs within lines, one can try with vi: :set tabstop=4 :set et|retab # Dummy target to test for GNU make availability _test: From 7d51f9f26609f9a96ca136f3a0218726fc93d45d Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 24 Jul 2019 01:04:06 +0200 Subject: [PATCH 0151/1854] fix hf_bog standalone mode compilation --- armsrc/Standalone/hf_bog.h | 1 + armsrc/spiffs.h | 1 + 2 files changed, 2 insertions(+) diff --git a/armsrc/Standalone/hf_bog.h b/armsrc/Standalone/hf_bog.h index 3dd68b3e2..50bdf2df8 100644 --- a/armsrc/Standalone/hf_bog.h +++ b/armsrc/Standalone/hf_bog.h @@ -21,6 +21,7 @@ #include "apps.h" #include "printf.h" #include "parity.h" +#include "spiffs.h" #endif /* __HF_BOG_H */ diff --git a/armsrc/spiffs.h b/armsrc/spiffs.h index 22d7434de..f36bde4b0 100644 --- a/armsrc/spiffs.h +++ b/armsrc/spiffs.h @@ -56,6 +56,7 @@ int rdv40_spiffs_copy(char *src, char *dst, RDV40SpiFFSSafetyLevel level); int rdv40_spiffs_append(char *filename, uint8_t *src, uint32_t size, RDV40SpiFFSSafetyLevel level); int rdv40_spiffs_stat(char *filename, uint32_t *buf, RDV40SpiFFSSafetyLevel level); uint32_t size_in_spiffs(const char *filename); +int exists_in_spiffs(const char *filename); #define SPIFFS_OK 0 #define SPIFFS_ERR_NOT_MOUNTED -10000 From e20d1ab7d21a6f299a2a9577db87f94baefda3f9 Mon Sep 17 00:00:00 2001 From: cjbrigato Date: Wed, 24 Jul 2019 01:42:33 +0200 Subject: [PATCH 0152/1854] HF_COLIN : Known Schemes now are in Struct form. This is 1/2 Pass for having Schemes dynamicly read from SPIFFS as json. --- armsrc/Standalone/hf_colin.c | 383 +++++++++++------------------------ 1 file changed, 116 insertions(+), 267 deletions(-) diff --git a/armsrc/Standalone/hf_colin.c b/armsrc/Standalone/hf_colin.c index bd184fad6..5eeb2a42a 100644 --- a/armsrc/Standalone/hf_colin.c +++ b/armsrc/Standalone/hf_colin.c @@ -27,39 +27,78 @@ int curlline; // Colin's VIGIKPWN sniff/simulate/clone repeat routine for HF Mifare -/* -void cjPrintBigArray(const char *bigar, int len, uint8_t newlines, uint8_t debug) -{ - uint32_t chunksize = (PM3_CMD_DATA_SIZE / 4); - uint8_t totalchunks = len / chunksize; - uint8_t last_chunksize = len - (totalchunks * chunksize); - char chunk[chunksize + 1]; - memset(chunk, 0x00, sizeof(chunk)); - if (debug > 0) - { - Dbprintf("len : %d", len); - Dbprintf("chunksize : %d bytes", chunksize); - Dbprintf("totalchunks : %d", totalchunks); - Dbprintf("last_chunksize: %d", last_chunksize); +typedef struct MFC1KSchema { + uint8_t name[32]; + uint64_t trigger; + uint64_t keysA[16]; + uint64_t keysB[16]; +} MFC1KSchema; + +#define MAX_SCHEMAS 4 + +MFC1KSchema Schemas[MAX_SCHEMAS]; + +MFC1KSchema Noralsy = { + .name = "Noralsy", + .trigger = 0x414c41524f4e, + .keysA = { + 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e, + 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e, + 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e + }, + .keysB = { + 0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e, + 0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e, + 0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e } - for (uint8_t i = 0; i < totalchunks; i++) - { - memset(chunk, 0x00, sizeof(chunk)); - memcpy(chunk, &bigar[i * chunksize], chunksize); - DbprintfEx(FLAG_RAWPRINT, "%s", chunk); +}; + +MFC1KSchema InfiHexact = {.name = "Infineon/Hexact", + .trigger = 0x484558414354, + .keysA = {0x484558414354, 0x484558414354, 0x484558414354, 0x484558414354, 0x484558414354, + 0x484558414354, 0x484558414354, 0x484558414354, 0x484558414354, 0x484558414354, + 0x484558414354, 0x484558414354, 0x484558414354, 0x484558414354, 0x484558414354, + 0x484558414354 + }, + .keysB = {0xa22ae129c013, 0x49fae4e3849f, 0x38fcf33072e0, 0x8ad5517b4b18, 0x509359f131b1, + 0x6c78928e1317, 0xaa0720018738, 0xa6cac2886412, 0x62d0c424ed8e, 0xe64a986a5d94, + 0x8fa1d601d0a2, 0x89347350bd36, 0x66d2b7dc39ef, 0x6bc1e1ae547d, 0x22729a9bd40f + } + }; + +MFC1KSchema UrmetCaptive = { + .name = "Urmet Captive", + .trigger = 0x8829da9daf76, + .keysA = { + 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, + 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, + 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76 + }, + .keysB = { + 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, + 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, + 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76 } - if (last_chunksize > 0) - { - memset(chunk, 0x00, sizeof(chunk)); - memcpy(chunk, &bigar[totalchunks * chunksize], last_chunksize); - DbprintfEx(FLAG_RAWPRINT, "%s", chunk); - } - if (newlines > 0) - { - DbprintfEx(FLAG_NEWLINE, " "); +}; + +int total_schemas = 0; + +void add_schema(MFC1KSchema *p, MFC1KSchema a, int *schemas_counter) { + if (*schemas_counter < MAX_SCHEMAS) { + p[*schemas_counter] = a; + *schemas_counter += 1; + } +} + +void delete_schema(MFC1KSchema *p, int *schemas_counter, int index) { + if (*schemas_counter > 0 && index < *schemas_counter && index > -1) { + int last_index = *schemas_counter - 1; + for (int i = index; i < last_index; i++) { + p[i] = p[i + 1]; + } + *schemas_counter -= 1; } } -*/ void cjSetCursFRight() { vtsend_cursor_position(NULL, 98, (currfline)); @@ -81,9 +120,8 @@ void cjTabulize() { DbprintfEx(FLAG_RAWPRINT, "\t\t\t"); } /* void cjPrintKey(uint64_t key, uint8_t *foundKey, uint16_t sectorNo, uint8_t type) { char tosendkey[13]; - sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[0], foundKey[1], foundKey[2], foundKey[3], foundKey[4], foundKey[5]); - cjSetCursRight(); - DbprintfEx(FLAG_NEWLINE, "SEC: %02x | KEY : %s | TYP: %d", sectorNo, tosendkey, type); + sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[0], foundKey[1], foundKey[2], foundKey[3], foundKey[4], +foundKey[5]); cjSetCursRight(); DbprintfEx(FLAG_NEWLINE, "SEC: %02x | KEY : %s | TYP: %d", sectorNo, tosendkey, type); } */ @@ -101,7 +139,7 @@ void ReadLastTagFromFlash() { uint8_t *mem = BigBuf_malloc(size); - //this one will handle filetype (symlink or not) and resolving by itself + // this one will handle filetype (symlink or not) and resolving by itself rdv40_spiffs_read_as_filetype((char *)HFCOLIN_LASTTAG_SYMLINK, (uint8_t *)mem, len, RDV40_SPIFFS_SAFETY_SAFE); emlSetMem(mem, 0, 64); @@ -129,8 +167,9 @@ void WriteTagToFlash(uint32_t uid, size_t size) { num_to_bytes(uid, 4, buid); sprintf(dest, "hf_colin/mf_%02x%02x%02x%02x.bin", buid[0], buid[1], buid[2], buid[3]); - // TODO : by using safe function for multiple writes we are both breaking cache mecanisms and making useless and unoptimized mount operations - // we should manage at out level the mount status before and after the whole standalone mode + // TODO : by using safe function for multiple writes we are both breaking cache mecanisms and making useless and + // unoptimized mount operations we should manage at out level the mount status before and after the whole standalone + // mode rdv40_spiffs_write((char *)dest, (uint8_t *)data, len, RDV40_SPIFFS_SAFETY_SAFE); // lastag will only contain filename/path to last written tag file so we don't loose time or space. rdv40_spiffs_make_symlink((char *)dest, (char *)HFCOLIN_LASTTAG_SYMLINK, RDV40_SPIFFS_SAFETY_SAFE); @@ -141,12 +180,15 @@ void WriteTagToFlash(uint32_t uid, size_t size) { return; } -void ModInfo(void) { - DbpString(" HF Mifare ultra fast sniff/sim/clone - aka VIGIKPWN (Colin Brigato)"); -} +void ModInfo(void) { DbpString(" HF Mifare ultra fast sniff/sim/clone - aka VIGIKPWN (Colin Brigato)"); } void RunMod() { StandAloneMode(); + + add_schema(Schemas, Noralsy, &total_schemas); + add_schema(Schemas, InfiHexact, &total_schemas); + add_schema(Schemas, UrmetCaptive, &total_schemas); + FpgaDownloadAndGo(FPGA_BITSTREAM_HF); currline = 20; @@ -155,7 +197,7 @@ void RunMod() { memset(cjuid, 0, sizeof(cjuid)); cjcuid = 0; uint8_t sectorsCnt = (MF1KSZ / MF1KSZSIZE); - uint64_t key64; // Defines current key + uint64_t key64; // Defines current key uint8_t *keyBlock; // Where the keys will be held in memory. /* VIGIK EXPIRED DUMP FOR STUDY @@ -194,11 +236,11 @@ void RunMod() { ACCBITS : 796788[00]+VALUE */ - //---------------------------- - // Set of keys to be used. - // This should cover ~98% of - // French VIGIK system @2017 - //---------------------------- +//---------------------------- +// Set of keys to be used. +// This should cover ~98% of +// French VIGIK system @2017 +//---------------------------- #define STKEYS 37 @@ -295,7 +337,7 @@ failtag: SpinOff(50); LED_A_ON(); uint8_t ticker = 0; - //while (!BUTTON_PRESS() && !iso14443a_select_card(cjuid, NULL, &cjcuid, true, 0, true)) + // while (!BUTTON_PRESS() && !iso14443a_select_card(cjuid, NULL, &cjcuid, true, 0, true)) while (!iso14443a_select_card(cjuid, &p_card, &cjcuid, true, 0, true)) { WDT_HIT(); @@ -377,8 +419,8 @@ failtag: if (key == -1) { err = 1; allKeysFound = false; - // used in portable imlementation on microcontroller: it reports back the fail and open the standalone lock - // reply_old(CMD_CJB_FSMSTATE_MENU, 0, 0, 0, 0, 0); + // used in portable imlementation on microcontroller: it reports back the fail and open the standalone + // lock reply_old(CMD_CJB_FSMSTATE_MENU, 0, 0, 0, 0, 0); break; } else if (key == -2) { err = 1; // Can't select card. @@ -393,10 +435,10 @@ failtag: cjSetCursRight(); DbprintfEx(FLAG_NEWLINE, "SEC: %02x ; KEY : %012" PRIx64 " ; TYP: %i", sec, key64, type); /*reply_old(CMD_CJB_INFORM_CLIENT_KEY, 12, sec, type, tosendkey, 12);*/ - switch (key64) { - ///////////////////////////////////////////////////////// - // COMMON SCHEME 1 : INFINITRON/HEXACT - case 0x484558414354: + + for (int i = 0; i < total_schemas; i++) { + if (key64 == Schemas[i].trigger) { + cjSetCursLeft(); DbprintfEx(FLAG_NEWLINE, "%s>>>>>>>>>>>>!*STOP*!<<<<<<<<<<<<<<%s", _XRED_, _XWHITE_); cjSetCursLeft(); @@ -404,232 +446,36 @@ failtag: DbprintfEx(FLAG_NEWLINE, " .TAG SEEMS %sDETERMINISTIC%s. ", _XGREEN_, _XWHITE_); cjSetCursLeft(); - DbprintfEx(FLAG_NEWLINE, "%sDetected: %s INFI_HEXACT_VIGIK_TAG%s", _XORANGE_, _XCYAN_, _XWHITE_); + DbprintfEx(FLAG_NEWLINE, "%sDetected: %s %s%s", _XORANGE_, _XCYAN_, Schemas[i].name, _XWHITE_); cjSetCursLeft(); - DbprintfEx(FLAG_NEWLINE, "...%s[%sKey_derivation_schemeTest%s]%s...", _XYELLOW_, _XGREEN_, _XYELLOW_, _XGREEN_); + DbprintfEx(FLAG_NEWLINE, "...%s[%sKey_derivation_schemeTest%s]%s...", _XYELLOW_, _XGREEN_, + _XYELLOW_, _XGREEN_); cjSetCursLeft(); DbprintfEx(FLAG_NEWLINE, "%s>>>>>>>>>>>>!*DONE*!<<<<<<<<<<<<<<%s", _XGREEN_, _XWHITE_); - ; - // Type 0 / A first + uint16_t t = 0; for (uint16_t s = 0; s < sectorsCnt; s++) { - num_to_bytes(0x484558414354, 6, foundKey[t][s]); - sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][s][0], foundKey[t][s][1], foundKey[t][s][2], - foundKey[t][s][3], foundKey[t][s][4], foundKey[t][s][5]); + num_to_bytes(Schemas[i].keysA[s], 6, foundKey[t][s]); + sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][s][0], foundKey[t][s][1], + foundKey[t][s][2], foundKey[t][s][3], foundKey[t][s][4], foundKey[t][s][5]); cjSetCursRight(); DbprintfEx(FLAG_NEWLINE, "SEC: %02x ; KEY : %s ; TYP: %d", s, tosendkey, t); } t = 1; - uint16_t sectorNo = 0; - num_to_bytes(0xa22ae129c013, 6, foundKey[t][sectorNo]); - sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2], - foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]); - cjSetCursRight(); - - DbprintfEx(FLAG_NEWLINE, "SEC: %02x ; KEY : %s ; TYP: %d", sectorNo, tosendkey, t); - sectorNo = 1; - num_to_bytes(0x49fae4e3849f, 6, foundKey[t][sectorNo]); - sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2], - foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]); - cjSetCursRight(); - - DbprintfEx(FLAG_NEWLINE, "SEC: %02x ; KEY : %s ; TYP: %d", sectorNo, tosendkey, t); - sectorNo = 2; - num_to_bytes(0x38fcf33072e0, 6, foundKey[t][sectorNo]); - sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2], - foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]); - cjSetCursRight(); - - DbprintfEx(FLAG_NEWLINE, "SEC: %02x ; KEY : %s ; TYP: %d", sectorNo, tosendkey, t); - sectorNo = 3; - num_to_bytes(0x8ad5517b4b18, 6, foundKey[t][sectorNo]); - sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2], - foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]); - cjSetCursRight(); - - DbprintfEx(FLAG_NEWLINE, "SEC: %02x ; KEY : %s ; TYP: %d", sectorNo, tosendkey, t); - sectorNo = 4; - num_to_bytes(0x509359f131b1, 6, foundKey[t][sectorNo]); - sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2], - foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]); - cjSetCursRight(); - - DbprintfEx(FLAG_NEWLINE, "SEC: %02x ; KEY : %s ; TYP: %d", sectorNo, tosendkey, t); - sectorNo = 5; - num_to_bytes(0x6c78928e1317, 6, foundKey[t][sectorNo]); - sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2], - foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]); - cjSetCursRight(); - - DbprintfEx(FLAG_NEWLINE, "SEC: %02x ; KEY : %s ; TYP: %d", sectorNo, tosendkey, t); - sectorNo = 6; - num_to_bytes(0xaa0720018738, 6, foundKey[t][sectorNo]); - sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2], - foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]); - cjSetCursRight(); - - DbprintfEx(FLAG_NEWLINE, "SEC: %02x ; KEY : %s ; TYP: %d", sectorNo, tosendkey, t); - sectorNo = 7; - num_to_bytes(0xa6cac2886412, 6, foundKey[t][sectorNo]); - sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2], - foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]); - cjSetCursRight(); - - DbprintfEx(FLAG_NEWLINE, "SEC: %02x ; KEY : %s ; TYP: %d", sectorNo, tosendkey, t); - sectorNo = 8; - num_to_bytes(0x62d0c424ed8e, 6, foundKey[t][sectorNo]); - sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2], - foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]); - cjSetCursRight(); - - DbprintfEx(FLAG_NEWLINE, "SEC: %02x ; KEY : %s ; TYP: %d", sectorNo, tosendkey, t); - sectorNo = 9; - num_to_bytes(0xe64a986a5d94, 6, foundKey[t][sectorNo]); - sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2], - foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]); - cjSetCursRight(); - - DbprintfEx(FLAG_NEWLINE, "SEC: %02x ; KEY : %s ; TYP: %d", sectorNo, tosendkey, t); - sectorNo = 10; - num_to_bytes(0x8fa1d601d0a2, 6, foundKey[t][sectorNo]); - sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2], - foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]); - cjSetCursRight(); - - DbprintfEx(FLAG_NEWLINE, "SEC: %02x ; KEY : %s ; TYP: %d", sectorNo, tosendkey, t); - sectorNo = 11; - num_to_bytes(0x89347350bd36, 6, foundKey[t][sectorNo]); - sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2], - foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]); - cjSetCursRight(); - - DbprintfEx(FLAG_NEWLINE, "SEC: %02x ; KEY : %s ; TYP: %d", sectorNo, tosendkey, t); - sectorNo = 12; - num_to_bytes(0x66d2b7dc39ef, 6, foundKey[t][sectorNo]); - sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2], - foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]); - cjSetCursRight(); - - DbprintfEx(FLAG_NEWLINE, "SEC: %02x ; KEY : %s ; TYP: %d", sectorNo, tosendkey, t); - sectorNo = 13; - num_to_bytes(0x6bc1e1ae547d, 6, foundKey[t][sectorNo]); - sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2], - foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]); - cjSetCursRight(); - - DbprintfEx(FLAG_NEWLINE, "SEC: %02x ; KEY : %s ; TYP: %d", sectorNo, tosendkey, t); - sectorNo = 14; - num_to_bytes(0x22729a9bd40f, 6, foundKey[t][sectorNo]); - sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2], - foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]); - cjSetCursRight(); - - DbprintfEx(FLAG_NEWLINE, "SEC: %02x ; KEY : %s ; TYP: %d", sectorNo, tosendkey, t); - sectorNo = 15; - num_to_bytes(0x484558414354, 6, foundKey[t][sectorNo]); - sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2], - foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]); - cjSetCursRight(); - - DbprintfEx(FLAG_NEWLINE, "SEC: %02x ; KEY : %s ; TYP: %d", sectorNo, tosendkey, t); - trapped = 1; - break; - ////////////////END OF SCHEME 1////////////////////////////// - - /////////////////////////////////////// - // COMMON SCHEME 2 : URMET CAPTIVE / COGELEC!/? - case 0x8829da9daf76: - cjSetCursLeft(); - - DbprintfEx(FLAG_NEWLINE, "%s>>>>>>>>>>>>!*STOP*!<<<<<<<<<<<<<<%s", _XRED_, _XWHITE_); - cjSetCursLeft(); - - DbprintfEx(FLAG_NEWLINE, " .TAG SEEMS %sDETERMINISTIC%s. ", _XGREEN_, _XWHITE_); - cjSetCursLeft(); - - DbprintfEx(FLAG_NEWLINE, "%sDetected :%sURMET_CAPTIVE_VIGIK_TAG%s", _XORANGE_, _XCYAN_, _XWHITE_); - cjSetCursLeft(); - - DbprintfEx(FLAG_NEWLINE, "...%s[%sKey_derivation_schemeTest%s]%s...", _XYELLOW_, _XGREEN_, _XYELLOW_, _XGREEN_); - cjSetCursLeft(); - - DbprintfEx(FLAG_NEWLINE, "%s>>>>>>>>>>>>!*DONE*!<<<<<<<<<<<<<<%s", _XGREEN_, _XWHITE_); - cjSetCursLeft(); - - // emlClearMem(); - // A very weak one... - for (uint16_t i = 0; i < 2; i++) { - for (uint16_t s = 0; s < sectorsCnt; s++) { - num_to_bytes(key64, 6, foundKey[i][s]); - sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", - foundKey[i][s][0], - foundKey[i][s][1], - foundKey[i][s][2], - foundKey[i][s][3], - foundKey[i][s][4], - foundKey[i][s][5] - ); - cjSetCursRight(); - DbprintfEx(FLAG_NEWLINE, "SEC: %02x ; KEY : %s ; TYP: %d", s, tosendkey, i); - } - } - trapped = 1; - break; - ////////////////END OF SCHEME 2////////////////////////////// - - /////////////////////////////////////// - // COMMON SCHEME 3 : NORALSY "A-LARON & B-LARON . . . NORAL-B & NORAL-A" - case 0x414c41524f4e: // Thumbs up to the guy who had the idea of such a "mnemotechnical" key pair - case 0x424c41524f4e: - cjSetCursLeft(); - - DbprintfEx(FLAG_NEWLINE, "%s>>>>>>>>>>>>!*STOP*!<<<<<<<<<<<<<<%s", _XRED_, _XWHITE_); - cjSetCursLeft(); - - DbprintfEx(FLAG_NEWLINE, " .TAG SEEMS %sDETERMINISTIC%s. ", _XGREEN_, _XWHITE_); - cjSetCursLeft(); - - DbprintfEx(FLAG_NEWLINE, "%s Detected :%sNORALSY_VIGIK_TAG %s", _XORANGE_, _XCYAN_, _XWHITE_); - cjSetCursLeft(); - - DbprintfEx(FLAG_NEWLINE, "...%s[%sKey_derivation_schemeTest%s]%s...", _XYELLOW_, _XGREEN_, _XYELLOW_, _XGREEN_); - cjSetCursLeft(); - - DbprintfEx(FLAG_NEWLINE, "%s>>>>>>>>>>>>!*DONE*!<<<<<<<<<<<<<<%s", _XGREEN_, _XWHITE_); - - t = 0; for (uint16_t s = 0; s < sectorsCnt; s++) { - num_to_bytes(0x414c41524f4e, 6, foundKey[t][s]); - sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", - foundKey[t][s][0], - foundKey[t][s][1], - foundKey[t][s][2], - foundKey[t][s][3], - foundKey[t][s][4], - foundKey[t][s][5]); - cjSetCursRight(); - DbprintfEx(FLAG_NEWLINE, "SEC: %02x ; KEY : %s ; TYP: %d", s, tosendkey, t); - } - - t = 1; - for (uint16_t s = 0; s < sectorsCnt; s++) { - num_to_bytes(0x424c41524f4e, 6, foundKey[t][s]); - sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", - foundKey[t][s][0], - foundKey[t][s][1], - foundKey[t][s][2], - foundKey[t][s][3], - foundKey[t][s][4], - foundKey[t][s][5]); + num_to_bytes(Schemas[i].keysB[s], 6, foundKey[t][s]); + sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][s][0], foundKey[t][s][1], + foundKey[t][s][2], foundKey[t][s][3], foundKey[t][s][4], foundKey[t][s][5]); cjSetCursRight(); DbprintfEx(FLAG_NEWLINE, "SEC: %02x ; KEY : %s ; TYP: %d", s, tosendkey, t); } trapped = 1; break; - ////////////////END OF SCHEME 3////////////////////////////// + } } + /* etc etc for testing schemes quick schemes */ } } @@ -685,7 +531,8 @@ failtag: delta_time = GetTickCountDelta(start_time); cjSetCursLeft(); - DbprintfEx(FLAG_NEWLINE, "%s>>%s Time for VIGIK break :%s%dms%s", _XGREEN_, _XWHITE_, _XYELLOW_, delta_time, _XWHITE_); + DbprintfEx(FLAG_NEWLINE, "%s>>%s Time for VIGIK break :%s%dms%s", _XGREEN_, _XWHITE_, _XYELLOW_, delta_time, + _XWHITE_); vtsend_cursor_position_save(NULL); vtsend_set_attribute(NULL, 1); @@ -706,8 +553,9 @@ readysim: DbprintfEx(FLAG_NEWLINE, "%s!> HOLD ON : %s When you'll click, simm will stop", _XRED_, _XWHITE_); cjSetCursLeft(); - DbprintfEx(FLAG_NEWLINE, "Then %s immediately %s we'll try to %s dump our emulator state%s \r\nin a %s chinese tag%s", _XRED_, _XWHITE_, _XYELLOW_, _XWHITE_, - _XCYAN_, _XWHITE_); + DbprintfEx(FLAG_NEWLINE, + "Then %s immediately %s we'll try to %s dump our emulator state%s \r\nin a %s chinese tag%s", _XRED_, + _XWHITE_, _XYELLOW_, _XWHITE_, _XCYAN_, _XWHITE_); cjSetCursLeft(); cjSetCursLeft(); @@ -736,7 +584,7 @@ readysim: } // Use UID, SAK, ATQA from EMUL, if uid not defined - //if ((flags & (FLAG_4B_UID_IN_DATA | FLAG_7B_UID_IN_DATA | FLAG_10B_UID_IN_DATA)) == 0) { + // if ((flags & (FLAG_4B_UID_IN_DATA | FLAG_7B_UID_IN_DATA | FLAG_10B_UID_IN_DATA)) == 0) { flags |= FLAG_UID_IN_EMUL; //} Mifare1ksim(flags | FLAG_MF_1K, 0, cjuid); @@ -856,7 +704,8 @@ int e_MifareECardLoad(uint32_t numofsectors, uint8_t keytype) { /* the chk function is a piwi'ed(tm) check that will try all keys for a particular sector. also no tracing no dbg */ -int cjat91_saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace, uint8_t keyCount, uint8_t *datain, uint64_t *key) { +int cjat91_saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace, uint8_t keyCount, uint8_t *datain, + uint64_t *key) { DBGLEVEL = DBG_NONE; iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); set_tracing(false); @@ -961,8 +810,7 @@ void saMifareMakeTag(void) { } } - -//TODO : make this work either for a Gen1a or for a block 0 direct write all transparently +// TODO : make this work either for a Gen1a or for a block 0 direct write all transparently //----------------------------------------------------------------------------- // Matt's StandAlone mod. // Work with "magic Chinese" card (email him: ouyangweidaxian@live.cn) @@ -1049,7 +897,8 @@ int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *data }; } - if ((mifare_sendcmd_short(NULL, 0, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 1) || (receivedAnswer[0] != 0x0a)) { + if ((mifare_sendcmd_short(NULL, 0, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 1) || + (receivedAnswer[0] != 0x0a)) { DbprintfEx(FLAG_NEWLINE, "write block send command error"); break; }; From cbdc4704adee294ecadc904351a18aaabe29e0cd Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 24 Jul 2019 08:50:39 +0200 Subject: [PATCH 0153/1854] More changelog changes --- CHANGELOG.md | 402 +++++++++++++++++++++++++-------------------------- 1 file changed, 200 insertions(+), 202 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b83c91e0..1e4cbdb8b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,20 +6,20 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Add T55x7 Downlink mode support (@mwalker33) - Add SPIFFS Flash filesystem support (@cjbrigato) - Fix support for flashing 512K units with old bootrom (@slurdge/@doegox) - - Fix 'hf mf sim' - wrong access rights to write key B in trailer (@McEloff) + - Fix `hf mf sim` - wrong access rights to write key B in trailer (@McEloff) - Add option -i to flasher to query Pm3 for its memory size (@doegox) - Add support for flashing 512K units (@slurdge) - Add a simple python tool to check the elf sizes (@slurdge) - Change: new keys for Vigik badges in default_keys.dict (@luminouw) - - Add 'hw standalone' to jump to standalone mode from command line or script (@doegox) - - Add to 'hf 14a apdu' print apdu and compose apdu (@merlokk) - - Change: buggy 'mem read' removed, 'mem save' renamed 'mem dump', can now display too (@doegox) + - Add `hw standalone` to jump to standalone mode from command line or script (@doegox) + - Add to `hf 14a apdu` print apdu and compose apdu (@merlokk) + - Change: buggy `mem read` removed, `mem save` renamed `mem dump`, can now display too (@doegox) - Fix: timeout for mem wipe was too short, thanks @cjbrigato (@doegox) - - Fix 'hf mf sim' - Mifare Classic simulation more flexible anti-collision check (@McEloff) - - Change: 'hf mf sim' - Mifare Classic simulation not respond NACK on invalid authentication request (@McEloff) - - Change: 'read_pwd_mem.lua' now handles Mifare Classic dictionaries large than 4096 bytes (@iceman1001) - - Change: Don't clear trace log during 'hf mf chk', to save whole process history (@McEloff) - - Add 'msleep' command, for pauses in scripts (@doegox) + - Fix `hf mf sim` - Mifare Classic simulation more flexible anti-collision check (@McEloff) + - Change: `hf mf sim` - Mifare Classic simulation not respond NACK on invalid authentication request (@McEloff) + - Change: `read_pwd_mem.lua` now handles Mifare Classic dictionaries large than 4096 bytes (@iceman1001) + - Change: Do not clear trace log during `hf mf chk`, to save whole process history (@McEloff) + - Add `msleep` command, for pauses in scripts (@doegox) - Add support for WSL in proxmark.sh (@doegox) - Add documentation for usage of Proxmark3 under WSL (@doegox) - Change: replace aes.c with mbedtls version (@slurdge) @@ -32,17 +32,17 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Fix EMVGPO bug (@matrix) - Add hitag2 write password auth (@ViRb3) - Add check if bootloader segment is within bounds (@slurdge) - - Add 'hf 15 csetuid' - set UID on ISO-15693 Magic tags (@t0m4-null) + - Add `hf 15 csetuid` - set UID on ISO-15693 Magic tags (@t0m4-null) - Change: Print help if unknown arg for hitag reader/writer (@ViRb3) - Fix clock deadlock in hitag sniff (@ViRb3) - Add compiler info in client & ARM sections (@slurdge) - Add support for automatic COM detection on Windows (@slurdge) - Add support for compilation on RaspberryPiZero (armv6) (@doegox) - Change: updates to README (@iceman1001) - - Change: 'hf mf/mfu dbg' => 'hw dbg' (@doegox) + - Change: `hf mf/mfu dbg` => `hw dbg` (@doegox) - Change: replace usb_poll_validate_length() by data_available() that supports USART too (@doegox) - Make sure standalone modes can be launched when connected on USB without client (@doegox) - - Change: cleaner makefile execution, use 'make V=1' if you want to see full lines (@doegox) + - Change: cleaner makefile execution, use `make V=1` if you want to see full lines (@doegox) - Change: automate make clean when platform definitions are changed (@doegox) - Add STANDALONE option to Makefile.hal (@Fl0-0) - Change: mem info - production public key to verify rdv4.0 flash signature (@iceman1001) @@ -88,8 +88,8 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Fix: Mifare Ultralight read block missing bytes (@doegox) - Add support new frame format in all Lua scripts (@iceman1001) - Add CMD_CAPABILITIES for pm3 to inform dynamically the client (@doegox) - - Change baudrate handling, make it clear it's only indicative for USB-CDC & BT (@doegox) - - Change: new progressive light scheme for 'hw detectreader' (@doegox) + - Change baudrate handling, make it clear it is only indicative for USB-CDC & BT (@doegox) + - Change: new progressive light scheme for `hw detectreader` (@doegox) - Add common error definitions system for retvals (@doegox) - Change USART RX & TX code and fix delays handling to make it more robust, especially over BT (@doegox) - Add support for new frames format, speedup & huge changes, see doc/new_frame_format.txt (@doegox) @@ -110,179 +110,179 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Fix compilation dependencies for recovery (@doegox) - Fix segfault when loading a file (@doegox) - Change/Add new dump format for Ultralight/NTAG, counters support, simulation (@mceloff) - - Add 'hf mf sim' full-byte split anticollision support (@mceloff) - - Fix/Add 'hf mf sim' bugs fix, RATS support, etc (@mceloff) + - Add `hf mf sim` full-byte split anticollision support (@mceloff) + - Fix/Add `hf mf sim` bugs fix, RATS support, etc (@mceloff) - Fix serial of FPC. (@ryan) - - Fix 'data shiftgraphzero' corrupting end of GraphBuffer (@doegox) - - Fix 'hf legic info' - unsegmented card now uses card size to calc remaining length (@iceman1001) + - Fix `data shiftgraphzero` corrupting end of GraphBuffer (@doegox) + - Fix `hf legic info` - unsegmented card now uses card size to calc remaining length (@iceman1001) - Add 36bit HID format, extend calcWiegand() to include oem bits (@davidbeauchamp) - - Fix 'hf mf hardnested' - not verify key when reading nonce file (@iceman1001) + - Fix `hf mf hardnested` - not verify key when reading nonce file (@iceman1001) - Change optimizations for ask/bi (@iceman1001) - - Fix 'hf mf sim' - bugs fix, refactoring (@mceloff) + - Fix `hf mf sim` - bugs fix, refactoring (@mceloff) - Add WRITE and COMPATIBLE_WRITE support to Mifare Ultralight/NTAG simulation (@mceloff) - Change installation instructions and add video links (@5w0rdfish) - - Change 'hf mf sim' to support more types (@vratiskol) + - Change `hf mf sim` to support more types (@vratiskol) - Change better strong wave detection for biphase (@iceman1001) - - Add 'script run test_t55x7' (@iceman1001) + - Add `script run test_t55x7` (@iceman1001) - Add new lua scripting support for some t55xx commands (@iceman1001) - Add FPC USART for BT add-on with pm3 client. (@doegox) - - Add '-b baudrate' option to the pm3 client. (@doegox) - - Change 'lf t55xx info': tell if known configuration block0. (@iceman1001) + - Add `-b baudrate` option to the pm3 client. (@doegox) + - Change `lf t55xx info`: tell if known configuration block0. (@iceman1001) - Fix/Add FPC usart: fix TX, bring RX, full speed. (@doegox) - - Change 'lf t55xx config' options: allow to toggle on/off i/q5/st - - Change 'lf t55xx info': support offline block0, Q5, fix extended, add warns. (@doegox) + - Change `lf t55xx config` options: allow to toggle on/off i/q5/st + - Change `lf t55xx info`: support offline block0, Q5, fix extended, add warns. (@doegox) - Avoid race condition when flasher finds the not yet closed pm3 port. (@doegox) - - Fix 'lf t55xx trace': read the proper block. (@doegox) + - Fix `lf t55xx trace`: read the proper block. (@doegox) - Fix Indala 64 on T55xx: use PSK1. (@doegox) - Force proper Linefeed (LF) handling in ProxSpace. (@vratiskol) - - Fix Makefiles race conditions to allow parallel compilation, e.g. 'make -j8'. (@doegox) + - Fix Makefiles race conditions to allow parallel compilation, e.g. `make -j8`. (@doegox) - Add - dictionary key file for MFU. (not in use at the moment) (@mazodude) - - Change 'lf fdx demod - better biphase maxerrors. (@MalteHillmann) - - Change 'hf mf sim' - now works better against android (@mceloff) - - Fix 'lf t55xx brute' - now works after aquiredata adaptations (@iceman1001) - - Fix 'lf t55xx chk' - now works after aquiredata adaptations (@iceman1001) - - Fix 'lf t55xx recoverpwd' - now works after aquiredata adaptations (@iceman1001) - - Fix 'data detect p' - reverted bad clock detection (@iceman1001) - - Change 'data detect a' - better clock detection (@iceman1001) - - Add 'hf 14a info' - now detects some magic card Gen2 (@iceman1001) - - Removed 'LCD' code in armsrc compilation (@iceman1001) + - Change `lf fdx demod` - better biphase maxerrors. (@MalteHillmann) + - Change `hf mf sim` - now works better against android (@mceloff) + - Fix `lf t55xx brute` - now works after aquiredata adaptations (@iceman1001) + - Fix `lf t55xx chk` - now works after aquiredata adaptations (@iceman1001) + - Fix `lf t55xx recoverpwd` - now works after aquiredata adaptations (@iceman1001) + - Fix `data detect p` - reverted bad clock detection (@iceman1001) + - Change `data detect a` - better clock detection (@iceman1001) + - Add `hf 14a info` - now detects some magic card Gen2 (@iceman1001) + - Removed `LCD` code in armsrc compilation (@iceman1001) - Change - Generic fixes of codestyle (@doegox) (@iceman1001) - - Change 'lf indala demod' - refactoring (@iceman1001) + - Change `lf indala demod` - refactoring (@iceman1001) - Change - handling fault bit markers (7) and partial nibbles in hex printing (@doegox) - Change - printing of fault bit markers (7) using a dot (@doegox) - - Change 'sc upgrade' - firmware file integrity check (@piwi) - - Fix 'data rawdemod am' - last bit was missing (@doegox) - - Fix 'hf 15 dump f' - also selects tag first (@iceman1001) - - Fix 'hf iclass clone' - missing fileclose (@iceman1001) - - Add 'trace list hitag' - old hitag annotations now use the new trace (@iceman1001) - - Change 'lf hitag sim' - loads bin/eml/json (@iceman1001) - - Change 'lf hitag reader 21' - saves in bin/eml/json (@iceman1001) - - Change 'lf hitag' - refactoring (@iceman1001) - - Change 'lf hitag' - refactoring (@piwi) - - Fix 'lf hitag' - generic fix for missing clock init (@piwi) + - Change `sc upgrade` - firmware file integrity check (@piwi) + - Fix `data rawdemod am` - last bit was missing (@doegox) + - Fix `hf 15 dump f` - also selects tag first (@iceman1001) + - Fix `hf iclass clone` - missing fileclose (@iceman1001) + - Add `trace list hitag` - old hitag annotations now use the new trace (@iceman1001) + - Change `lf hitag sim` - loads bin/eml/json (@iceman1001) + - Change `lf hitag reader 21` - saves in bin/eml/json (@iceman1001) + - Change `lf hitag` - refactoring (@iceman1001) + - Change `lf hitag` - refactoring (@piwi) + - Fix `lf hitag` - generic fix for missing clock init (@piwi) - Fix fsk sim operations on deviceside - avoid division by zero (@doegox) - - Fix 'hf mf fchk' - condition always false (@doegox) - - Fix 'lf t55xx recoverpw' - shift as u32 (@doegox) - - Fix 'lf ti demod' - shift as u32 (@doegox) - - Fix 'lf ti read' - shift as u32 (@doegox) - - Fix 'lf t55xx chk' - condition always false (@doegox) - - Change 'lf sim' - ledcontrol refactoring (@doegox) - - Fix 'hf mf nack' - signedness bug (@doegox) - - Fix 'hf epa cnonce' - check return value (@doegox) - - Fix 'lf hitag write' - condition always true (@doegox) - - Fix 'mem write' - added extra check (@doegox) - - Fix 'iso15693' - bad string cpy (@doegox) - - Fix 'make style' - EOF LF support (@doegox) - - Add 'hf 14b raw' - added -t for timeout (@iceman1001) - - Rename 'lf hitag snoop' - renamed to 'lf hitag sniff' (@iceman1001) - - Rename 'lf snoop' - renamed to 'lf sniff' (@iceman1001) - - Rename 'hf snoop' - renamed to 'hf sniff' (@iceman1001) - - Fix 'hf mfp wrbl' - more blocks available (@merlokk) - - Add 'make platform' - compile for non-rdv4 devices made simpler (@doegox) + - Fix `hf mf fchk` - condition always false (@doegox) + - Fix `lf t55xx recoverpw` - shift as u32 (@doegox) + - Fix `lf ti demod` - shift as u32 (@doegox) + - Fix `lf ti read` - shift as u32 (@doegox) + - Fix `lf t55xx chk` - condition always false (@doegox) + - Change `lf sim` - ledcontrol refactoring (@doegox) + - Fix `hf mf nack` - signedness bug (@doegox) + - Fix `hf epa cnonce` - check return value (@doegox) + - Fix `lf hitag write` - condition always true (@doegox) + - Fix `mem write` - added extra check (@doegox) + - Fix `iso15693` - bad string cpy (@doegox) + - Fix `make style` - EOF LF support (@doegox) + - Add `hf 14b raw` - added -t for timeout (@iceman1001) + - Rename `lf hitag snoop` - renamed to `lf hitag sniff` (@iceman1001) + - Rename `lf snoop` - renamed to `lf sniff` (@iceman1001) + - Rename `hf snoop` - renamed to `hf sniff` (@iceman1001) + - Fix `hf mfp wrbl` - more blocks available (@merlokk) + - Add `make platform` - compile for non-rdv4 devices made simpler (@doegox) - Change Makefiles optimizations when recompiling (@doegox) - - Fix 'data load' - loads TITEST.txt again (@iceman1001) - - Change 'lf search' - now detects TI (@iceman1001) + - Fix `data load` - loads TITEST.txt again (@iceman1001) + - Change `lf search` - now detects TI (@iceman1001) - Change fixing signal cleaning for LF (@doegox) - - Fix 'lf paradox demod' - wrong check (@iceman1001) - - Change 'lf t55xx' - aquiredata uses getsamples (@iceman1001) - - Fix 'lf search' - chipset detection restore demod buffer again (@iceman1001) - - Add 'make style' (@doegox) + - Fix `lf paradox demod` - wrong check (@iceman1001) + - Change `lf t55xx` - aquiredata uses getsamples (@iceman1001) + - Fix `lf search` - chipset detection restore demod buffer again (@iceman1001) + - Add `make style` (@doegox) - Fix mixed tabs vs spaces. Now only use 4 space as tab. (@doegox) - - Fix 'lf visa2000 read' - too few samples (@iceman1001) - - Fix 'lf t55xx bruteforce' - infinity loop (@doegox) - - Fix 'analyse nuid' - correct crc (@doegox) + - Fix `lf visa2000 read` - too few samples (@iceman1001) + - Fix `lf t55xx bruteforce` - infinity loop (@doegox) + - Fix `analyse nuid` - correct crc (@doegox) - Add command history not repeating logged commands (@doegox) - Fix path for aidjson (@doegox) - Fix missing init i2x (@doegox) - - Fix '14b select card' - (@doegox) - - Add 'hf mf ndef' - parsing of NDEF messages (@merlokk) - - Add 'hf mf mad' - parsing of Mifare Application Directory (@merlokk) - - Rename 'lf snoop' -> 'lf sniff' (@iceman1001) - - Rename 'hf snoop' -> 'hf sniff' (@iceman1001) + - Fix `14b select card` - (@doegox) + - Add `hf mf ndef` - parsing of NDEF messages (@merlokk) + - Add `hf mf mad` - parsing of Mifare Application Directory (@merlokk) + - Rename `lf snoop` -> `lf sniff` (@iceman1001) + - Rename `hf snoop` -> `hf sniff` (@iceman1001) - Change generally added more colors (@iceman1001) - - Change 'sc upgrade' updated firmware v3.11 (RDV40) (@sentiprox) - - Change 'data autocorrelate' - better visual representation and added extra peak detection (@iceman1001) - - Fix 'lf search' - false positive indala identification fixed (@iceman1001) - - Add 'lf keri' - basic support for Keri tags (@iceman1001) - - Add 'hf mf list' - re-added it again (@iceman1001) + - Change `sc upgrade` updated firmware v3.11 (RDV40) (@sentiprox) + - Change `data autocorrelate` - better visual representation and added extra peak detection (@iceman1001) + - Fix `lf search` - false positive indala identification fixed (@iceman1001) + - Add `lf keri` - basic support for Keri tags (@iceman1001) + - Add `hf mf list` - re-added it again (@iceman1001) - Fix - A lot of bugfixes, like memory leaks (@iceman1001) - - Change 'hf 14a antifuzz' - original implementation (@asfabw), reworked a bit - - Fix 'hf mf fchk' (@iceman1001) - - Fix 'usb slow on posix based systems' (@fl0-0) - - Change 'lf pcf7931' - improved read code (@sguerrini97) - - Change 'hf felica list' - started with some FeliCa annotations (@iceman1001) - - Fix 'hf tune' - now works as expected (@iceman1001) - - Add 'option to use flash memory to upload dictionary files' (RDV40) (@iceman1001) - - Fix 'printing percentage now standard compliant' (@fabled) - - Add 'emv roca' - command to test for ROCA vuln in public RSA modulus (@merlokk / @iceman1001) + - Change `hf 14a antifuzz` - original implementation (@asfabw), reworked a bit + - Fix `hf mf fchk` (@iceman1001) + - Fix `usb slow on posix based systems` (@fl0-0) + - Change `lf pcf7931` - improved read code (@sguerrini97) + - Change `hf felica list` - started with some FeliCa annotations (@iceman1001) + - Fix `hf tune` - now works as expected (@iceman1001) + - Add `option to use flash memory to upload dictionary files` (RDV40) (@iceman1001) + - Fix `printing percentage now standard compliant` (@fabled) + - Add `emv roca` - command to test for ROCA vuln in public RSA modulus (@merlokk / @iceman1001) - Added TCP ports support (on linux) (@phcoder) - Added HF sniff standalone mode with optional storing of ULC/NTAG/ULEV1 authentication attempts (@bogiton) - - Fix 'Lining up plot and control window' (@anticat) - - Fix 'annoying focus behaviour' on OSX (@Anticat) + - Fix `Lining up plot and control window` (@anticat) + - Fix `annoying focus behaviour` on OSX (@Anticat) - Implemented AppNap API, fixing #283 and #627 OSX USB comm issues (@AntiCat) - - Added 'sc brute' - a naive SFI bruteforcer for contact smartcards (RDV40) (@iceman1001) - - Change 'lf t55xx detectconfig' - now optional to persist settings to flashmem (RDV40) (@iceman1001) - - Change 'hf mf csave' - now saves both EML/BIN formats (@iceman1001) - - Change 'hf mf esave' - now saves both EML/BIN formats (@iceman1001) - - Fix 'compiler warning on macos and gcc7.1 or higher' (@TomHarkness) - - Fix 'crash on Bionic libc if CloseProxmark is called twice' (@micolous) - - Change 'lf hid' - got an updated to Kastle format (@xilni) - - Added 'lf t55xx deviceconfig' - enables custom t55xx timing settings. (RDV40) (@iceman1001) + - Added `sc brute` - a naive SFI bruteforcer for contact smartcards (RDV40) (@iceman1001) + - Change `lf t55xx detectconfig` - now optional to persist settings to flashmem (RDV40) (@iceman1001) + - Change `hf mf csave` - now saves both EML/BIN formats (@iceman1001) + - Change `hf mf esave` - now saves both EML/BIN formats (@iceman1001) + - Fix `compiler warning on macos and gcc7.1 or higher` (@TomHarkness) + - Fix `crash on Bionic libc if CloseProxmark is called twice` (@micolous) + - Change `lf hid` - got an updated to Kastle format (@xilni) + - Added `lf t55xx deviceconfig` - enables custom t55xx timing settings. (RDV40) (@iceman1001) - Chg adaptations for FPC communications (work in progress) (@iceman1001) - - Fix 'stand-alone Colin' - remake to benefit from flashmem for persistence. (@cjbrigato) - - Fix 'LEGIC SIM' - remake of legic sim (@drandreas) - - Changed 'proxmark3 client threading' - remake from official repo (@micolous) - - Add 'rem' - new command that adds a line to the log file (@didierStevens) - - Fix 'EM410xdemod empty tag id in lfops.c' (@Defensor7) - - Fix 'usb device descriptor' - some android phones will enumerate better when iSerialnumber isn't a multiple of 8 (@micolous, @megabug) - - Fix 'StandaloneMode LF' - when collecting signal, justNoise detection is needed (@didierStevens, @Megabug) - - Fix 'StandAloneMode Colin' - mifare1ksim called with right params (@cjbrigato) - - Improved 'install.sh' to install dependencies for Ubuntu 18.04 and using max number of processors during compilation (@joanbono) - - Modified 'install.sh' script to work in macOS and Linux + added the 'update.sh' and 'proxmark3.sh' from joanbono (@TomHarkness) - - Fix 'hf emv' - some cards need to have Le=0x00, some don't need to have (@merlokk) - - Fix 'hf legic' enhancement of rx / tx in legic commands (@drandreas) - - Fix 'data buffclear' - now frees bigbuff also (@iceman1001) + - Fix `stand-alone Colin` - remake to benefit from flashmem for persistence. (@cjbrigato) + - Fix `LEGIC SIM` - remake of legic sim (@drandreas) + - Changed `proxmark3 client threading` - remake from official repo (@micolous) + - Add `rem` - new command that adds a line to the log file (@didierStevens) + - Fix `EM410xdemod empty tag id in lfops.c` (@Defensor7) + - Fix `usb device descriptor` - some android phones will enumerate better when iSerialnumber is not a multiple of 8 (@micolous, @megabug) + - Fix `StandaloneMode LF` - when collecting signal, justNoise detection is needed (@didierStevens, @Megabug) + - Fix `StandAloneMode Colin` - mifare1ksim called with right params (@cjbrigato) + - Improved `install.sh` to install dependencies for Ubuntu 18.04 and using max number of processors during compilation (@joanbono) + - Modified `install.sh` script to work in macOS and Linux + added the `update.sh` and `proxmark3.sh` from joanbono (@TomHarkness) + - Fix `hf emv` - some cards need to have Le=0x00, some do not need to have (@merlokk) + - Fix `hf legic` enhancement of rx / tx in legic commands (@drandreas) + - Fix `data buffclear` - now frees bigbuff also (@iceman1001) - Fix GET_TICKS and signess while shifting (@drandreas) - - Added 'hf 14b dump' - now dumps to file (bin & eml) (@iceman1001) + - Added `hf 14b dump` - now dumps to file (bin & eml) (@iceman1001) - Fix fixed xcorrelation for strong signal (@drandreas) - - Fix 'hf mf chk' - keytype was reversed (@TomHarkness) + - Fix `hf mf chk` - keytype was reversed (@TomHarkness) - Added strange vid/pid found in wild. Could be pm3 easy clones. (@iceman1001) - - Fix 'make udev' - udev filename could be in conflict, renamed. (@blshkv) - - Fix 'lf t55xx config' - wrong sized array disabled FSK1a/FSK2a as options (@grauerfuchs) + - Fix `make udev` - udev filename could be in conflict, renamed. (@blshkv) + - Fix `lf t55xx config` - wrong sized array disabled FSK1a/FSK2a as options (@grauerfuchs) - Added more default keys (@j8048188) (@iceman1001) - - Added 'sc list/info/raw/reader/upgrade' - (RDV40) smart card module functionality (@iceman1001) - - Fix 'download eml buffer' (@drandreas) - - Changed 'exclusion of floatingpoint lib' (@pwpiwi) - - Changed 'lua scripts bit32 calls' (@iceman1001) - - Changed 'hw version' (@pwpiwi), adapted to iceman fork (@iceman1001) - - Added 'amiibo functionality' (@jamchamb), adapted to iceman fork (@iceman1001) - - Fix 'hf legic' (RDV40) adaptations to FPGA HF enhanched reading distance (@iceman1001) Thanks to @drandreas! - - Added 'script run mifare_acces' - script to decode Mifare classic accessbits (@Neuromancer) - - Added 'mem load/save/wipe' - commands to upload / download to new RDV40 onboard flashmemory (@iceman1001) - - Added 'script run mifareplus" - script to communicate with a mifare plus tag (@dceliano) + - Added `sc list/info/raw/reader/upgrade` - (RDV40) smart card module functionality (@iceman1001) + - Fix `download eml buffer` (@drandreas) + - Changed `exclusion of floatingpoint lib` (@pwpiwi) + - Changed `lua scripts bit32 calls` (@iceman1001) + - Changed `hw version` (@pwpiwi), adapted to iceman fork (@iceman1001) + - Added `amiibo functionality` (@jamchamb), adapted to iceman fork (@iceman1001) + - Fix `hf legic` (RDV40) adaptations to FPGA HF enhanched reading distance (@iceman1001) Thanks to @drandreas! + - Added `script run mifare_acces` - script to decode Mifare classic accessbits (@Neuromancer) + - Added `mem load/save/wipe` - commands to upload / download to new RDV40 onboard flashmemory (@iceman1001) + - Added `script run mifareplus` - script to communicate with a mifare plus tag (@dceliano) - Added FlashMemory functionality (RDV40) (@willok) - - Fix 'hf mfu dump' - partial reads lead to corrupt data (Thanks @elafargue for pointing it out) - - Changed 'hf mfu dump / read' - now retries five times. (@jamchamb) + - Fix `hf mfu dump` - partial reads lead to corrupt data (Thanks @elafargue for pointing it out) + - Changed `hf mfu dump / read` - now retries five times. (@jamchamb) - Added `hf list mf` - deciphers crypto1 stream and works with first authentication and weak nested authentications (@Merlok) - Adjusted `lf cmdread` to respond to client when complete and the client will then automatically call `data samples` (@marshmellow42) - Added a bitbang mode to `lf cmdread` if delay is 0 the cmd bits turn off and on the antenna with 0 and 1 respectively (@marshmellow42) - dump / restore now uses custom filenames (@brianpow) - - Removed 'hf mf sniff' , (@iceman1001), use HF 14A SNIFF instead - - Added 'hf iclass lookup' (@iceman1001) - - Added 'hf iclass chk' (@iceman1001) + - Removed `hf mf sniff` , (@iceman1001), use HF 14A SNIFF instead + - Added `hf iclass lookup` (@iceman1001) + - Added `hf iclass chk` (@iceman1001) - Fixed ADC mux all closed push-pull state (@iceman1001) - - Fix 'hf mf darkside' - speed fixes (@pwpiwi) - - Fix 'hw tune' - now compensates for 3% error in output, also measure full 140v using ADC channel 5 and 7. (@iceman1001) + - Fix `hf mf darkside` - speed fixes (@pwpiwi) + - Fix `hw tune` - now compensates for 3% error in output, also measure full 140v using ADC channel 5 and 7. (@iceman1001) - Updated loclass gpl license (@holiman) - Fix Antenna on after changed FPGA Mode. (@iceman1001) - - Added 'hf mf nack' - Mifare NACK bug detection (@iceman1001) (@doegox) - - Fix 'hf mf mifare' - zero parity works, no more double runs for normal darkside (@iceman1001) - - Added 'hf mf fchk' - the fastest check keys implementation tothisday (@iceman1001) - - Fix 'hf iclass' - more stable demod (@iceman1001) - - Added 'hf iclass chk' - check keys from default_iclass_keys.dic file (@iceman1001) - - Fix 'hf 15 dump' - no more crc faults (@iceman1001) - - Fix 'hf 15 read' - no more crc faults (@iceman1001) - - Fix 'hf 15 readmulti' - no more crc faults (@iceman1001) + - Added `hf mf nack` - Mifare NACK bug detection (@iceman1001) (@doegox) + - Fix `hf mf mifare` - zero parity works, no more double runs for normal darkside (@iceman1001) + - Added `hf mf fchk` - the fastest check keys implementation tothisday (@iceman1001) + - Fix `hf iclass` - more stable demod (@iceman1001) + - Added `hf iclass chk` - check keys from default_iclass_keys.dic file (@iceman1001) + - Fix `hf 15 dump` - no more crc faults (@iceman1001) + - Fix `hf 15 read` - no more crc faults (@iceman1001) + - Fix `hf 15 readmulti` - no more crc faults (@iceman1001) - Changed proxmark command line parameter `flush` to `-f` or `-flush` (@merlokk) - Added to proxmark command line parameters `w` - wait 20s for serial port (@merlokk) - Added to proxmark command line parameters `c` and `l` - execute command and lua script from command line (@merlokk) @@ -290,13 +290,13 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Added new standalone mode "HF Mifare ultra fast sniff/sim/clone - aka VIGIKPWN" (@cjbrigato) - Added to `hf 14a apdu` - exchange apdu via iso1443-4 (@merlokk) - Added to `hf 14a apdu` - apdu and tlv results parser (@merlokk) - - Added 'hf emv' commands (@merlokk) + - Added `hf emv` commands (@merlokk) - lots of bug fixes (many many) - Changed hf mfp security. Now it works in all the modes. (@drHatson) - Added `hf fido` commands that work with FIDO U2F authenticators (@merlokk) - Added mbedtls instead of old polarssl (@merlokk) - Added jansson (@merlokk) - - Added `hf emv scan` - save card's data to json file (@merlokk) + - Added `hf emv scan` - save card data to json file (@merlokk) - Added `hf emv` `gpo`, `readrec`, `genac`, `challenge`, `intauth` - separate commands from `hf emc exec` (@merlokk) - Added `hf fido` `assert` and `make` commands from fido2 protocol (authenticatorMakeCredential and authenticatorGetAssertion) (@merlokk) - Added trailer block decoding to `hf mf rdbl` and `hf mf cgetbl` (@merlokk) @@ -311,10 +311,10 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - proxmark3 client can reconnect to device without restart (@iceman1001) - lots of bug fixes (many many) - trace/securakey-64169.pm3 - trace of a scecurakey (@atyppo) - - 'hf mf decrypt' - got some longer input and helptext parameter (@iceman1001) + - `hf mf decrypt` - got some longer input and helptext parameter (@iceman1001) - Updated the Reveng 1.51 sourcecode to 1.52 from Reveng project homepage (@iceman1001) - - 'hf 14a read' - disconnects when failing to read tag (@iceman1001) - - 'hf mf csave' - renamed parameter 'i' to 'o' as in output (@iceman1001) + - `hf 14a read` - disconnects when failing to read tag (@iceman1001) + - `hf mf csave` - renamed parameter `i` to `o` as in output (@iceman1001) ## [3.0.0][2017-08-29] Notes on this release @@ -322,51 +322,51 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac There is a lot of changes, command breaking changes, which is the cause for the JUMP in version number. It is set to v3.0.0 to show that it is on par with PM3 Offical v3 release. - - Updated 'mkversion.pl' to write a date based on file when repo is downloaded as a zip file from github (@iceman1001) - - Update 'readme.md' to fit GitHubs markup(@joanbono) - - Added 'script run ul_uid', try to change UID on a magic UL-card. (@iceman1001) - - Fixed 'hf snoop' bug, of wrong bool value (@ikarus23) + - Updated `mkversion.pl` to write a date based on file when repo is downloaded as a zip file from github (@iceman1001) + - Update `readme.md` to fit GitHubs markup(@joanbono) + - Added `script run ul_uid`, try to change UID on a magic UL-card. (@iceman1001) + - Fixed `hf snoop` bug, of wrong bool value (@ikarus23) - Fixed fullimage.s19, wrong offsets (@doegox) - - Updated '77-mm-usb-device-blacklist.rules' for the pid/vid (@iceman1001) - - 'hf 14a sim' now follows Mifare UL-EV1 protocol better (@iceman1001) - - Updated 'fpga_hf.bit' file (@pwpiwi) - - Added more card detections to 'hf mfu info' (@iceman1001) - - Fixed 'hf mfu restore/dump' to use the right struct values in special data in dumpfile. (@iceman1001) - - Added 'hf mfu restore r' new parameter to use the new pwd for all further auths needed when executing (@iceman1001) - - Added 'default_keys_dic2lua.awk' script to generate default_keys file in client/lualibs (@iceman1001) + - Updated `77-mm-usb-device-blacklist.rules` for the pid/vid (@iceman1001) + - `hf 14a sim` now follows Mifare UL-EV1 protocol better (@iceman1001) + - Updated `fpga_hf.bit` file (@pwpiwi) + - Added more card detections to `hf mfu info` (@iceman1001) + - Fixed `hf mfu restore/dump` to use the right struct values in special data in dumpfile. (@iceman1001) + - Added `hf mfu restore r` new parameter to use the new pwd for all further auths needed when executing (@iceman1001) + - Added `default_keys_dic2lua.awk` script to generate default_keys file in client/lualibs (@iceman1001) - Fixes to lots of lua scripts, among others - - 'mifare_autopwn', now uses PRNG detection (@iceman1001) - - 'mfkeys', fixed bug which only tested the first key (@iceman1001) - - 'dumptoemul', removed last newline (@iceman1001) + - `mifare_autopwn`, now uses PRNG detection (@iceman1001) + - `mfkeys`, fixed bug which only tested the first key (@iceman1001) + - `dumptoemul`, removed last newline (@iceman1001) - ... - Added USB/SERIAL communication enhancements (@micolous) - - Change 'hf 14a cuids', to be interrupted with keyboard press (@iceman1001) + - Change `hf 14a cuids`, to be interrupted with keyboard press (@iceman1001) - Change debugstatements for LF to show which function more unified (@iceman1001) - - Added 'script run calc_di' , to calculate some Mifare keys (@iceman1001) + - Added `script run calc_di` , to calculate some Mifare keys (@iceman1001) - Fixed iclass commands never shut down antenna afterwards (@iceman1001) - Change 512kb detection when flashing (@iceman1001) - Fixed compilation GCC4.9 or higher detection (@winguru) - Fixed compiler warnings in Ubuntu 17.04 (@iceman1001) - - Ripped out 'standalone' code into separete folder to be continued. (@iceman1001) - - 'hf mf nested', added key validation to entered key (@merlokk) - - 'hf mf hardnested', added key validation to enterd key (@iceman1001) + - Ripped out `standalone` code into separete folder to be continued. (@iceman1001) + - `hf mf nested`, added key validation to entered key (@merlokk) + - `hf mf hardnested`, added key validation to enterd key (@iceman1001) - Change a lot of help texts (@iceman1001) - - Fixed 'hf mf chk' - keyblock bug, limited keys to 256. (@iceman1001) - - Change 'hf mf dump' retries three times now before giving up (@marshmellow42) - - Fixed 'mfu authentication', with pack-len error (@iceman1001) - - 'Script list', change sortorder to alphabetic order (@iceman1001) - - Change 'hf mfu gen' to read taguid (@iceman1001) - - Change 'hf mfu pwdgen' to read taguid (@iceman1001) - - Added 'hf mf setmod' sets Mifare Classic EV1 load modulation strength to card (@angelsl) - - Added 'hf 14a read' Mifare PRNG detection based on @doegox LIBNFC impl (@iceman1001) - - Added 'hf mf nonces', collects Mifare Classic nonces for analysing of PRNG (@iceman1001) - - Added new CSNS in 'hf iclass sim 2' attack (@iceman1001) + - Fixed `hf mf chk` - keyblock bug, limited keys to 256. (@iceman1001) + - Change `hf mf dump` retries three times now before giving up (@marshmellow42) + - Fixed `mfu authentication`, with pack-len error (@iceman1001) + - `Script list`, change sortorder to alphabetic order (@iceman1001) + - Change `hf mfu gen` to read taguid (@iceman1001) + - Change `hf mfu pwdgen` to read taguid (@iceman1001) + - Added `hf mf setmod` sets Mifare Classic EV1 load modulation strength to card (@angelsl) + - Added `hf 14a read` Mifare PRNG detection based on @doegox LIBNFC impl (@iceman1001) + - Added `hf mf nonces`, collects Mifare Classic nonces for analysing of PRNG (@iceman1001) + - Added new CSNS in `hf iclass sim 2` attack (@iceman1001) - Added more default keys (@iceman1001) - Added analyse nuid, enable creation of Mifare NUID (@iceman1001) - Updated the Reveng 1.44 sourcecode to 1.51 from Reveng project homepage (@iceman1001) - script run formatMifare - got an option to execute the generate strings (@iceman1001) - - Fix 'hf mf cgetsc' (@iceman1001) - - Fix 'hf legic info' (@iceman1001) + - Fix `hf mf cgetsc` (@iceman1001) + - Fix `hf legic info` (@iceman1001) - Change version output (@iceman1001) - Added PAC/Stanley detection to lf search (@marshmellow42) - Added lf pac demod and lf pac read - extracts the raw blocks from a PAC/Stanley tag (@marshmellow42) @@ -377,7 +377,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Compiles with gcc 4.9 - Compiles for non-Intel CPUs - Added lf hitag write 24, the command writes a block to hitag2 tags in crypto mode (@henjo) - - Added the improved 'hf mf hardnested', an attack working for hardened Mifare cards (EV1, Mifare Plus SL1) + - Added the improved `hf mf hardnested`, an attack working for hardened Mifare cards (EV1, Mifare Plus SL1) - Added experimental testmode write option for t55xx (danger) (@marshmellow42) - Added t55xx p1detect to `lf search` chip detections (@marshmellow42) - Added lf t55xx p1detect, detect page 1 of a t55xx tag based on E015 mfg code (@marshmellow42) @@ -394,7 +394,6 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac ## [1.7.0 iceman fork] [2017-03-07] - hf mf dump - added retry loops to try each read attempt up to 3 times. makes getting a complete dump easier with many antennas. (@marshmellow42) - - Added markers in the graph around found Sequence Terminator after askmandemod. (@marshmellow42) - Added data mtrim command to trim out samples between start and stop. (@marshmellow42) - Added data setgraphmarkers command to set two extra markers on the graph (@marshmellow42) @@ -405,7 +404,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - `hf 14a read` added magic tag generation 1a and 1b detection (@iceman1001) - correctly using stdtypes.h printf and scanf format string macros (PRIx64 et al) (@pwpiwi) - fix linker warning re missing entry point when linking fullimage.elf (@pwpiwi) - - small changes to lf psk and fsk demods to improve results when the trace begins with noise or the chip isn't broadcasting yet (@marshmellow42) + - small changes to lf psk and fsk demods to improve results when the trace begins with noise or the chip is not broadcasting yet (@marshmellow42) - NOTE CHANGED ALL `lf em4x em*` cmds to simpler `lf em ` - example: `lf em4x em410xdemod` is now `lf em 410xdemod` - Renamed and rebuilt `lf em readword` && readwordpwd to `lf em 4x05read` - it now demods and outputs the read block (@marshmellow42/@iceman1001) - Renamed and rebuilt `lf em writeword` && writewordpwd to `lf em 4x05write` - it now also reads validation output from the tag (@marshmellow42/@iceman1001) @@ -418,7 +417,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac ## [1.6.9 iceman fork] [2017-02-06] - Serial speedup, if possible 408600baud otherwise default to 115200baud (@iceman1001) - - `hf emv` - Added Peter Fillmore's EMV branch now compiles on iceman fork. See seperate issue. (@iceman1001) + - `hf emv` - Added Peter Fillmore EMV branch now compiles on iceman fork. See seperate issue. (@iceman1001) - `hf 14a reader` - Aztek detection. (@iceman1001) - `standalone mode` - added more detection of tags and refactored (@iceman1001) - `script run ufodump` - dumps an Aztek tag. (@iceman1001) @@ -467,19 +466,18 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Added `lf hid wiegand` added a method to calculate WIEGAND in different formats, (@iceman1001) - `hf mf chkkeys` better printing, same table output as nested, faster execution and added Adam Lauries "try to read Key B if Key A is found" (@iceman1001) - `hf mf nested` better printing and added Adam Lauries "try to read Key B if Key A is found" (@iceman1001) - - `hf mf mifare` fixing the zero parity path, which doesn't got called. (@iceman1001) - - Updated the @blapost's Crapto1 implementation to v3.3 (blapost) + - `hf mf mifare` fixing the zero parity path, which did not get called. (@iceman1001) + - Updated the @blapost Crapto1 implementation to v3.3 (blapost) - `hf mf c*` updated the calling structure and refactored of the chinese magic commands (@iceman1001, @marshmellow42) - - Started to add Peter Fillmore's EMV fork into Iceman fork. ref: https://github.com/peterfillmore/proxmark3 (@peterfillmore, @iceman1001) + - Started to add Peter Fillmore EMV fork into Iceman fork. ref: https://github.com/peterfillmore/proxmark3 (@peterfillmore, @iceman1001) - Added Travis-CI automatic build integration with GitHub fork. (@iceman1001) - Updated the Reveng 1.30 sourcecode to 1.31 from Reveng project homepage (@iceman1001) - Updated the Reveng 1.31 sourcecode to 1.40 from Reveng project homepage (@iceman1001) - - - Added possibility to write direct to a Legic Prime Tag (MIM256/1024) without using values from the 'BigBuffer' -> 'hf legic writeRaw ' (@icsom) + - Added possibility to write direct to a Legic Prime Tag (MIM256/1024) without using values from the `BigBuffer` -> `hf legic writeRaw ` (@icsom) - Added possibility to decrease DCF values at address 0x05 & 0x06 on a Legic Prime Tag DCF-value will be pulled from the BigBuffer (address 0x05 & 0x06) so you have to - load the data into the BigBuffer before with 'hf legic load ' & then - write the DCF-Values (both at once) with 'hf legic write 0x05 0x02' (@icsom) + load the data into the BigBuffer before with `hf legic load ` & then + write the DCF-Values (both at once) with `hf legic write 0x05 0x02` (@icsom) - Added script `legic.lua` for display and edit Data of Legic-Prime Tags (@icsom) - Added the experimental HITAG_S support (@spenneb) - Added topaz detection to `hf search` (@iceman1001) @@ -505,13 +503,13 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - `hf iclass calcnewkey` - to calculate the div_key change to change a key - (experimental) (@marshmellow42 + others) - `hf iclass encryptblk` - to encrypt a data block hex to prep for writing that block (@marshmellow42) - ISO14443a stand-alone operation with ARM CFLAG="WITH_ISO14443a_StandAlone". This code can read & emulate two banks of 14a tag UIDs and write to "magic" cards (Craig Young) - - AWID26 command context added as 'lf awid' containing realtime demodulation as well as cloning/simulation based on tag numbers (Craig Young) - - Added 'hw status'. This command makes the ARM print out some runtime information. (@holiman) - - Added 'hw ping'. This command just sends a usb packets and checks if the pm3 is responsive. Can be used to abort certain operations which supports abort over usb. (@holiman) + - AWID26 command context added as `lf awid` containing realtime demodulation as well as cloning/simulation based on tag numbers (Craig Young) + - Added `hw status`. This command makes the ARM print out some runtime information. (@holiman) + - Added `hw ping`. This command just sends a usb packets and checks if the pm3 is responsive. Can be used to abort certain operations which supports abort over usb. (@holiman) - Added `data hex2bin` and `data bin2hex` for command line conversion between binary and hexadecimal (@holiman) - - Added 'hf snoop'. This command take digitalized signal from FPGA and put in BigBuffer. (@pwpiwi + enio) - - Added Topaz (NFC type 1) protocol support ('hf topaz reader', 'hf list topaz', 'hf 14a raw -T', 'hf topaz snoop'). (@pwpiwi) - - Added option c to 'hf list' (mark CRC bytes) (@pwpiwi) + - Added `hf snoop`. This command take digitalized signal from FPGA and put in BigBuffer. (@pwpiwi + enio) + - Added Topaz (NFC type 1) protocol support (`hf topaz reader`, `hf list topaz`, `hf 14a raw -T`, `hf topaz snoop`). (@pwpiwi) + - Added option c to `hf list` (mark CRC bytes) (@pwpiwi) ### Changed - Added `[l] ` option to data printdemodbuffer @@ -531,7 +529,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - `hf iclass dump` cli options - can now dump AA1 and AA2 with different keys in one run (does not go to multiple pages for the larger tags yet) (@marshmellow42) - Revised workflow for StandAloneMode14a (Craig Young) - EPA functions (`hf epa`) now support both ISO 14443-A and 14443-B cards (@frederikmoellers) - - 'hw version' only talks to ARM at startup, after that the info is cached. (@pwpiwi) + - `hw version` only talks to ARM at startup, after that the info is cached. (@pwpiwi) - Added `r` option to iclass functions - allows key to be provided in raw block 3/4 format ## [2.2.0][2015-07-12] @@ -563,7 +561,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - *bootrom* needs to be flashed, due to new address boundaries between os and fpga, after a size optimization (@pwpiwi) ### Fixed - - Fixed EM4x50 read/demod of the tags broadcasted memory blocks. 'lf em4x em4x50read' (not page read) (@marshmellow42) + - Fixed EM4x50 read/demod of the tags broadcasted memory blocks. `lf em4x em4x50read` (not page read) (@marshmellow42) - Fixed issue #19, problems with LF T55xx commands (@iceman1001, @marshmellow42) - Fixed various problems with iso14443b, issue #103 (@pwpiwi, @marshmellow42) @@ -584,5 +582,5 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Issues regarding LF simulation (@pwpiwi) ### 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 don't 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). - iClass decryption. Proxmark can now decrypt data on an iclass tag, but requires you to have the HID decryption key locally on your computer, as this is not bundled with the sourcecode. From 4abb4b939f279ad98f9d0e7446642c6fa276b498 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 24 Jul 2019 13:37:09 +0200 Subject: [PATCH 0154/1854] Proper Makefile halting when using incompatible Standalone mode and Platform --- CHANGELOG.md | 1 + armsrc/Standalone/Makefile.hal | 9 +++++++++ armsrc/Standalone/readme.md | 7 +++++++ common/Makefile.hal | 3 +++ 4 files changed, 20 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1e4cbdb8b..be5b1875c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Add proper Makefile halting when using incompatible STANDALONE and PLATFORM vars (@doegox) - Add T55x7 Downlink mode support (@mwalker33) - Add SPIFFS Flash filesystem support (@cjbrigato) - Fix support for flashing 512K units with old bootrom (@slurdge/@doegox) diff --git a/armsrc/Standalone/Makefile.hal b/armsrc/Standalone/Makefile.hal index 6181b5072..0711bec0e 100644 --- a/armsrc/Standalone/Makefile.hal +++ b/armsrc/Standalone/Makefile.hal @@ -3,6 +3,7 @@ DEFAULT_STANDALONE=LF_SAMYRUN HELP_EXAMPLE_STANDALONE=HF_COLIN # (you can set explicitly STANDALONE= to disable standalone modes) STANDALONE?=$(DEFAULT_STANDALONE) +STANDALONE_REQ_DEFS= define KNOWN_STANDALONE_DEFINITIONS +==========================================================+ @@ -39,8 +40,16 @@ endef STANDALONE_MODES := LF_SAMYRUN LF_ICERUN LF_PROXBRUTE LF_HIDBRUTE STANDALONE_MODES += HF_YOUNG HF_MATTYRUN HF_COLIN HF_BOG +STANDALONE_MODES_REQ_SMARTCARD := +STANDALONE_MODES_REQ_FLASH := HF_COLIN HF_BOG ifneq ($(filter $(STANDALONE),$(STANDALONE_MODES)),) STANDALONE_PLATFORM_DEFS += -DWITH_STANDALONE_$(STANDALONE) + ifneq ($(filter $(STANDALONE),$(STANDALONE_MODES_REQ_SMARTCARD)),) + STANDALONE_REQ_DEFS += -DWITH_SMARTCARD + endif + ifneq ($(filter $(STANDALONE),$(STANDALONE_MODES_REQ_FLASH)),) + STANDALONE_REQ_DEFS += -DWITH_FLASH + endif else ifneq ($(STANDALONE),) $(error Invalid STANDALONE: $(STANDALONE). $(KNOWN_DEFINITIONS)) endif diff --git a/armsrc/Standalone/readme.md b/armsrc/Standalone/readme.md index 4ff83b9fd..9b9d45688 100644 --- a/armsrc/Standalone/readme.md +++ b/armsrc/Standalone/readme.md @@ -72,6 +72,13 @@ STANDALONE_MODES := LF_SAMYRUN LF_ICERUN LF_PROXBRUTE LF_HIDBRUTE LF_FOO STANDALONE_MODES += HF_YOUNG HF_MATTYRUN HF_COLIN HF_BOG ``` +If your mode is using one of the unique features of the RDV4, add it to the proper list: + +``` +STANDALONE_MODES_REQ_SMARTCARD := +STANDALONE_MODES_REQ_FLASH := HF_COLIN HF_BOG +``` + ## Update MAKEFILE.INC Add your source code files like the following sample in the `Makefile.inc` diff --git a/common/Makefile.hal b/common/Makefile.hal index bf9231f5c..46154d244 100644 --- a/common/Makefile.hal +++ b/common/Makefile.hal @@ -114,6 +114,9 @@ PLATFORM_DEFS += \ -DWITH_HFSNIFF # Standalone mode +ifneq ($(strip $(filter $(PLATFORM_DEFS),$(STANDALONE_REQ_DEFS))),$(strip $(STANDALONE_REQ_DEFS))) + $(error Chosen Standalone mode $(STANDALONE) requires $(strip $(STANDALONE_REQ_DEFS)), unsupported by $(PLTNAME)) +endif PLATFORM_DEFS+=$(STANDALONE_PLATFORM_DEFS) $(info $(findstring WITH_STANDALONE_*,$(PLATFORM_DEFS))) From 1229b358aa0daa568fc0fafde53c0ecebd20dce5 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 24 Jul 2019 19:32:06 +0200 Subject: [PATCH 0155/1854] clarify standalone table --- armsrc/Standalone/Makefile.hal | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/armsrc/Standalone/Makefile.hal b/armsrc/Standalone/Makefile.hal index 0711bec0e..5d3904794 100644 --- a/armsrc/Standalone/Makefile.hal +++ b/armsrc/Standalone/Makefile.hal @@ -9,10 +9,10 @@ define KNOWN_STANDALONE_DEFINITIONS +==========================================================+ | STANDALONE | DESCRIPTION | +==========================================================+ -| | No standalone mode | +| (empty) | No standalone mode | +----------------------------------------------------------+ -| LF_SAMYRUN (def)| HID26 read/clone/sim | -| | - Samy Kamkar | +| LF_SAMYRUN | HID26 read/clone/sim | +| (default) | - Samy Kamkar | +----------------------------------------------------------+ | LF_ICERUN | standalone mode skeleton | | | - iceman | @@ -30,10 +30,10 @@ define KNOWN_STANDALONE_DEFINITIONS | | - Matías A. Ré Medina | +----------------------------------------------------------+ | HF_COLIN | Mifare ultra fast sniff/sim/clone | -| | - Colin Brigato | +| (RDV4 only) | - Colin Brigato | +----------------------------------------------------------+ | HF_BOG | 14a sniff with ULC/ULEV1/NTAG auth | -| | storing in flashmem - Bogito | +| (RDV4 only) | storing in flashmem - Bogito | +----------------------------------------------------------+ endef From 77d96ff3b749cec6221ffa742c83894dd7b67a8b Mon Sep 17 00:00:00 2001 From: mwalker33 Date: Thu, 25 Jul 2019 20:01:03 +1000 Subject: [PATCH 0156/1854] Bug Fix Timing order Timing for backward compatibility --- CHANGELOG.md | 1 + armsrc/lfops.c | 23 ++++++++----------- client/cmdlft55xx.c | 16 ++++++------- .../2_Configuration-and-Verification.md | 3 +++ include/pm3_cmd.h | 3 ++- 5 files changed, 23 insertions(+), 23 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 76b3db976..b283ba462 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Fix T55x7 Downlink timings backward compatible (@mwalker33) - Add T55x7 Downlink mode support (@mwalker33) - Add SPIFFS Flash filesystem support (@cjbrigato) - Fix support for flashing 512K units with old bootrom (@slurdge/@doegox) diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 98896184e..f238e745c 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -123,12 +123,12 @@ t55xx_config T55xx_Timing = {{ } }; */ -// StartGap WriteGap Bit 0/00 Bit 1/01 Bit 10 Bit 11 ReadGap +// StartGap WriteGap Bit 0/00 Bit 1/01 ReadGap Bit 10 Bit 11 t55xx_config T55xx_Timing = {{ - { 29 * 8, 17 * 8, 15 * 8, 50 * 8, 0, 0, 15 * 8 }, // Default Fixed - { 31 * 8, 20 * 8, 18 * 8, 50 * 8, 0, 0, 15 * 8 }, // Long Leading Ref. - { 31 * 8, 20 * 8, 18 * 8, 40 * 8, 0, 0, 15 * 8 }, // Leading 0 - { 29 * 8, 17 * 8, 15 * 8, 31 * 8, 47 * 8, 63 * 8, 15 * 8 } // 1 of 4 + { 29 * 8, 17 * 8, 15 * 8, 50 * 8, 15 * 8, 0, 0 }, // Default Fixed + { 31 * 8, 20 * 8, 18 * 8, 50 * 8, 15 * 8, 0, 0 }, // Long Leading Ref. + { 31 * 8, 20 * 8, 18 * 8, 40 * 8, 15 * 8, 0, 0 }, // Leading 0 + { 29 * 8, 17 * 8, 15 * 8, 31 * 8, 15 * 8, 47 * 8, 63 * 8 } // 1 of 4 } }; @@ -163,11 +163,11 @@ void printT55xxConfig(void) { Dbprintf(" [b] writegap............%d*8 (%d)", T55xx_Timing.m[DLMode].write_gap / 8, T55xx_Timing.m[DLMode].write_gap); Dbprintf(" [c] write_0.............%d*8 (%d)", T55xx_Timing.m[DLMode].write_0 / 8, T55xx_Timing.m[DLMode].write_0); Dbprintf(" [d] write_1.............%d*8 (%d)", T55xx_Timing.m[DLMode].write_1 / 8, T55xx_Timing.m[DLMode].write_1); + Dbprintf(" [e] readgap.............%d*8 (%d)", T55xx_Timing.m[DLMode].read_gap / 8, T55xx_Timing.m[DLMode].read_gap); if (DLMode == T55xx_DLMode_1of4) { - Dbprintf(" [e] write_2.............%d*8 (%d)", T55xx_Timing.m[DLMode].write_2 / 8, T55xx_Timing.m[DLMode].write_2); - Dbprintf(" [f] write_3.............%d*8 (%d)", T55xx_Timing.m[DLMode].write_3 / 8, T55xx_Timing.m[DLMode].write_3); + Dbprintf(" [f] write_2.............%d*8 (%d)", T55xx_Timing.m[DLMode].write_2 / 8, T55xx_Timing.m[DLMode].write_2); + Dbprintf(" [g] write_3.............%d*8 (%d)", T55xx_Timing.m[DLMode].write_3 / 8, T55xx_Timing.m[DLMode].write_3); } - Dbprintf(" [g] readgap.............%d*8 (%d)", T55xx_Timing.m[DLMode].read_gap / 8, T55xx_Timing.m[DLMode].read_gap); } } @@ -213,21 +213,17 @@ void setT55xxConfig(uint8_t arg0, t55xx_config *c) { return; } - // if ( ClearT55Settings) // dont copy over new timings memcpy(buf, &T55xx_Timing, T55XX_CONFIG_LEN); Flash_CheckBusy(BUSY_TIMEOUT); Flash_WriteEnable(); Flash_Erase4k(3, 0xD); - // if not a settings erase, write data - // if ( ClearT55Settings) { res = Flash_Write(T55XX_CONFIG_OFFSET, buf, T55XX_CONFIG_LEN); if (res == T55XX_CONFIG_LEN && DBGLEVEL > 1) { DbpString("T55XX Config save success"); } - // } BigBuf_free(); #endif @@ -1484,6 +1480,7 @@ void TurnReadLF_off(uint32_t delay) { // Macro for code readability #define BitStream_Byte(X) ((X) >> 3) #define BitStream_Bit(X) ((X) & 7) +#define t55_llr_ref (136 * 8) #define t55_send_PwdMode (arg & 0x01) #define t55_send_Page ((arg & 0x02) >> 1) #define t55_send_TestMode ((arg & 0x04) >> 2) @@ -1510,7 +1507,7 @@ void T55xxWriteBit(uint8_t bit, uint8_t downlink_idx) { TurnReadLFOn(T55xx_Timing.m[downlink_idx].write_3); break; // Send bits 11 (1 of 4) case 4 : - TurnReadLFOn(T55xx_Timing.m[downlink_idx].write_0 + (136 * 8)); + TurnReadLFOn(T55xx_Timing.m[downlink_idx].write_0 + t55_llr_ref); break; // Send Long Leading Reference } diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 61383066c..cee13f5e1 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -254,9 +254,9 @@ static int usage_lf_deviceconfig() { PrintAndLogEx(NORMAL, " b <8..255> - Set write gap"); PrintAndLogEx(NORMAL, " c <8..255> - Set write ZERO gap"); PrintAndLogEx(NORMAL, " d <8..255> - Set write ONE gap"); - PrintAndLogEx(NORMAL, " e <8..255> - Set write TWO gap (1 of 4 only)"); - PrintAndLogEx(NORMAL, " f <8..255> - Set write THREE gap (1 of 4 only)"); - PrintAndLogEx(NORMAL, " g <8..255> - Set read gap"); + PrintAndLogEx(NORMAL, " e <8..255> - Set read gap"); + PrintAndLogEx(NORMAL, " f <8..255> - Set write TWO gap (1 of 4 only)"); + PrintAndLogEx(NORMAL, " g <8..255> - Set write THREE gap (1 of 4 only)"); PrintAndLogEx(NORMAL, " p - persist to flashmemory"); PrintAndLogEx(NORMAL, " r - downlink encoding '0' fixed bit length (default), '1' long leading ref."); PrintAndLogEx(NORMAL, " '2' leading zero, '3' 1 of 4 coding ref."); @@ -2572,15 +2572,15 @@ static int CmdT55xxSetDeviceConfig(const char *Cmd) { cmdp += 2; break; case 'e': - errors |= param_getdec(Cmd, cmdp + 1, &write2); + errors |= param_getdec(Cmd, cmdp + 1, &readgap); cmdp += 2; break; case 'f': - errors |= param_getdec(Cmd, cmdp + 1, &write3); + errors |= param_getdec(Cmd, cmdp + 1, &write2); cmdp += 2; break; case 'g': - errors |= param_getdec(Cmd, cmdp + 1, &readgap); + errors |= param_getdec(Cmd, cmdp + 1, &write3); cmdp += 2; break; case 'r': @@ -2606,9 +2606,7 @@ static int CmdT55xxSetDeviceConfig(const char *Cmd) { //Validations if (errors || cmdp == 0) return usage_lf_deviceconfig(); -// printf ("DLmode %d\n",downlink_mode); t55xx_config conf = {0}; -// printf ("Size conf %lld\n",sizeof(conf)); if (erase) { memset (&conf,0xff, sizeof(conf)); printf ("Conf.m[0] %x\n",conf.m[0].start_gap); @@ -2619,9 +2617,9 @@ static int CmdT55xxSetDeviceConfig(const char *Cmd) { conf.m[downlink_mode].write_gap = writegap * 8; conf.m[downlink_mode].write_0 = write0 * 8; conf.m[downlink_mode].write_1 = write1 * 8; + conf.m[downlink_mode].read_gap = readgap * 8; conf.m[downlink_mode].write_2 = write2 * 8; conf.m[downlink_mode].write_3 = write3 * 8; - conf.m[downlink_mode].read_gap = readgap * 8; } clearCommandBuffer(); SendCommandOLD(CMD_SET_LF_T55XX_CONFIG, shall_persist, 0, 0, &conf, sizeof(t55xx_config)); diff --git a/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md b/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md index 736ef70a5..5c8420d9d 100644 --- a/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md +++ b/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md @@ -5,6 +5,9 @@ pm3 --> mem load f default_keys m pm3 --> mem load f default_pwd t pm3 --> mem load f default_iclass_keys i pm3 --> lf t55xx deviceconfig a 29 b 17 c 15 d 47 e 15 p +pm3 --> lf t55xx deviceconfig r 1 a 31 b 20 c 18 d 50 e 15 p +pm3 --> lf t55xx deviceconfig r 2 a 31 b 20 c 18 d 40 e 15 p +pm3 --> lf t55xx deviceconfig r 3 a 29 b 17 c 15 d 31 e 15 f 47 g 63 p ``` ### Verify sim module firmware version diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 63054d3a1..c4cc05cee 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -135,9 +135,10 @@ typedef struct { uint16_t write_gap ; uint16_t write_0 ; uint16_t write_1 ; + uint16_t read_gap ; uint16_t write_2 ; uint16_t write_3 ; - uint16_t read_gap ; + } t55xx_config_t; // This setup will allow for the 4 downlink modes "m" as well as other items if needed. // Given the one struct we can then read/write to flash/client in one go. From 6c1ff4cef78e2fd792c38763b44477ac5d08117d Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 25 Jul 2019 12:22:24 +0200 Subject: [PATCH 0157/1854] minor alignment --- armsrc/flashmem.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/armsrc/flashmem.c b/armsrc/flashmem.c index c53169255..7bca9ddf9 100644 --- a/armsrc/flashmem.c +++ b/armsrc/flashmem.c @@ -567,21 +567,21 @@ void Flashmem_print_info(void) { if (isok == 2) { num = ((keysum[1] << 8) | keysum[0]); if (num != 0xFFFF && num != 0x0) - Dbprintf(" Mifare................"_YELLOW_("%d")"keys", num); + Dbprintf(" Mifare.................."_YELLOW_("%d")"keys", num); } 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")"keys", num); + Dbprintf(" T55x7..................."_YELLOW_("%d")"keys", num); } 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")"keys", num); + Dbprintf(" iClass.................."_YELLOW_("%d")"keys", num); } FlashStop(); From 3211f35062bf249c5c0869d99bf7d413cf232183 Mon Sep 17 00:00:00 2001 From: mwalker33 Date: Thu, 25 Jul 2019 21:00:30 +1000 Subject: [PATCH 0158/1854] Added set default timings --- armsrc/lfops.c | 4 +- client/cmdlft55xx.c | 55 +++++++++++++++++-- .../2_Configuration-and-Verification.md | 3 + 3 files changed, 56 insertions(+), 6 deletions(-) diff --git a/armsrc/lfops.c b/armsrc/lfops.c index f238e745c..af80e2f6c 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -116,7 +116,7 @@ // Note: Moved * 8 to apply when used. Saving 28 bytes here (- the *8) and 28 bytes flash. // StartGap WriteGap Bit 0/00 Bit 1/01 Bit 10 Bit 11 ReadGap t55xx_config T55xx_Timing = {{ - { 29 , 17 , 15 , 50 , 0 , 0 , 15 }, // Default Fixed + { 29 , 17 , 15 , 47 , 0 , 0 , 15 }, // Default Fixed { 31 , 20 , 18 , 50 , 0 , 0 , 15 }, // Long Leading Ref. { 31 , 20 , 18 , 40 , 0 , 0 , 15 }, // Leading 0 { 29 , 17 , 15 , 31 , 47 , 63 , 15 } // 1 of 4 @@ -125,7 +125,7 @@ t55xx_config T55xx_Timing = {{ */ // StartGap WriteGap Bit 0/00 Bit 1/01 ReadGap Bit 10 Bit 11 t55xx_config T55xx_Timing = {{ - { 29 * 8, 17 * 8, 15 * 8, 50 * 8, 15 * 8, 0, 0 }, // Default Fixed + { 29 * 8, 17 * 8, 15 * 8, 47 * 8, 15 * 8, 0, 0 }, // Default Fixed { 31 * 8, 20 * 8, 18 * 8, 50 * 8, 15 * 8, 0, 0 }, // Long Leading Ref. { 31 * 8, 20 * 8, 18 * 8, 40 * 8, 15 * 8, 0, 0 }, // Leading 0 { 29 * 8, 17 * 8, 15 * 8, 31 * 8, 15 * 8, 47 * 8, 63 * 8 } // 1 of 4 diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index cee13f5e1..3d0871893 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -14,6 +14,13 @@ #include "cmdlft55xx.h" +// Some defines for readability +#define T55xx_DLMode_Fixed 0 // Default Mode +#define T55xx_DLMode_LLR 1 // Long Leading Reference +#define T55xx_DLMode_Leading0 2 // Leading Zero +#define T55xx_DLMode_1of4 3 // 1 of 4 +#define T55xx_LongLeadingReference 4 // Value to tell Write Bit to send long reference + // Default configuration t55xx_conf_block_t config = { .modulation = DEMOD_ASK, .inverted = false, .offset = 0x00, .block0 = 0x00, .Q5 = false }; @@ -260,7 +267,7 @@ static int usage_lf_deviceconfig() { PrintAndLogEx(NORMAL, " p - persist to flashmemory"); PrintAndLogEx(NORMAL, " r - downlink encoding '0' fixed bit length (default), '1' long leading ref."); PrintAndLogEx(NORMAL, " '2' leading zero, '3' 1 of 4 coding ref."); - PrintAndLogEx(NORMAL, " z - erase t55x7 timings (needs p and reboot to load defaults)"); + PrintAndLogEx(NORMAL, " z - Set default t55x7 timings (use p to save if required)"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx deviceconfig a 29 b 17 c 15 d 47 e 15 - default T55XX"); @@ -2549,7 +2556,7 @@ static int CmdT55xxSetDeviceConfig(const char *Cmd) { bool errors = false, shall_persist = false; uint8_t cmdp = 0; uint8_t downlink_mode = 0; - bool erase = false; + bool set_defaults = false; while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { @@ -2593,7 +2600,7 @@ static int CmdT55xxSetDeviceConfig(const char *Cmd) { cmdp++; break; case 'z': - erase = true; + set_defaults = true; cmdp++; break; default: @@ -2607,9 +2614,48 @@ static int CmdT55xxSetDeviceConfig(const char *Cmd) { if (errors || cmdp == 0) return usage_lf_deviceconfig(); t55xx_config conf = {0}; - if (erase) { +/* if (erase) { memset (&conf,0xff, sizeof(conf)); printf ("Conf.m[0] %x\n",conf.m[0].start_gap); + */ + // + if (set_defaults){ + // fixed bit length + conf.m[T55xx_DLMode_Fixed].start_gap = 29 * 8; + conf.m[T55xx_DLMode_Fixed].write_gap = 17 * 8; + conf.m[T55xx_DLMode_Fixed].write_0 = 15 * 8; + conf.m[T55xx_DLMode_Fixed].write_1 = 47 * 8; + conf.m[T55xx_DLMode_Fixed].read_gap = 15 * 8; + conf.m[T55xx_DLMode_Fixed].write_2 = 0; + conf.m[T55xx_DLMode_Fixed].write_3 = 0; + + // long leading reference + conf.m[T55xx_DLMode_LLR].start_gap = 31 * 8; + conf.m[T55xx_DLMode_LLR].write_gap = 20 * 8; + conf.m[T55xx_DLMode_LLR].write_0 = 18 * 8; + conf.m[T55xx_DLMode_LLR].write_1 = 50 * 8; + conf.m[T55xx_DLMode_LLR].read_gap = 15 * 8; + conf.m[T55xx_DLMode_LLR].write_2 = 0; + conf.m[T55xx_DLMode_LLR].write_3 = 0; + + // leading zero + conf.m[T55xx_DLMode_Leading0].start_gap = 31 * 8; + conf.m[T55xx_DLMode_Leading0].write_gap = 20 * 8; + conf.m[T55xx_DLMode_Leading0].write_0 = 18 * 8; + conf.m[T55xx_DLMode_Leading0].write_1 = 40 * 8; + conf.m[T55xx_DLMode_Leading0].read_gap = 15 * 8; + conf.m[T55xx_DLMode_Leading0].write_2 = 0; + conf.m[T55xx_DLMode_Leading0].write_3 = 0; + + // 1 of 4 coding reference + conf.m[T55xx_DLMode_1of4].start_gap = 29 * 8; + conf.m[T55xx_DLMode_1of4].write_gap = 17 * 8; + conf.m[T55xx_DLMode_1of4].write_0 = 15 * 8; + conf.m[T55xx_DLMode_1of4].write_1 = 31 * 8; + conf.m[T55xx_DLMode_1of4].read_gap = 15 * 8; + conf.m[T55xx_DLMode_1of4].write_2 = 47 * 8; + conf.m[T55xx_DLMode_1of4].write_3 = 63 * 8; + } else { @@ -2621,6 +2667,7 @@ static int CmdT55xxSetDeviceConfig(const char *Cmd) { conf.m[downlink_mode].write_2 = write2 * 8; conf.m[downlink_mode].write_3 = write3 * 8; } + clearCommandBuffer(); SendCommandOLD(CMD_SET_LF_T55XX_CONFIG, shall_persist, 0, 0, &conf, sizeof(t55xx_config)); return PM3_SUCCESS; diff --git a/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md b/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md index 5c8420d9d..0d3665f37 100644 --- a/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md +++ b/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md @@ -8,6 +8,9 @@ pm3 --> lf t55xx deviceconfig a 29 b 17 c 15 d 47 e 15 p pm3 --> lf t55xx deviceconfig r 1 a 31 b 20 c 18 d 50 e 15 p pm3 --> lf t55xx deviceconfig r 2 a 31 b 20 c 18 d 40 e 15 p pm3 --> lf t55xx deviceconfig r 3 a 29 b 17 c 15 d 31 e 15 f 47 g 63 p + +Set all t55xx settings to defaults (will set all 4 at once) +pm3 --> lf t55xx deviceconfig z p ``` ### Verify sim module firmware version From ce0db262ca58c3317e87bb103cae80ae001a17c1 Mon Sep 17 00:00:00 2001 From: slurdge Date: Thu, 25 Jul 2019 14:41:52 +0200 Subject: [PATCH 0159/1854] Try to have a better travis --- .travis.yml | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/.travis.yml b/.travis.yml index 723d1c1a2..f42dd8f1c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,22 +8,18 @@ compiler: gcc matrix: include: - os: osx - osx_image: xcode9.2 # OS X 10.13 + osx_image: xcode11 - os: linux dist: xenial sudo: required -before_install: -## Install ARM toolchain on Linux. -## add our homebrew tap for MacOS -## Note: all dependencies on MacOS should be resolved by the brew install command - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then - sudo apt-get update -qq; - sudo apt-get install -y gcc-arm-none-eabi libnewlib-dev; - elif [[ "$TRAVIS_OS_NAME" == "osx" ]]; then - brew update; - brew tap RfidResearchGroup/proxmark3; - fi +addons: + apt: + packages: + - gcc-arm-none-eabi + - libnewlib-dev + homebrew: + taps: RfidResearchGroup/proxmark3 install: if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then @@ -34,8 +30,6 @@ install: make all; fi -before_script: - script: ## start and run a test script if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then From ee152657c6b587a2844c08ad960490d6d341b638 Mon Sep 17 00:00:00 2001 From: 3ldidi94 Date: Fri, 26 Jul 2019 11:43:21 +0200 Subject: [PATCH 0160/1854] Add one more key Found a new key that is not in this dic file, so I add it. --- client/default_keys.dic | 1 + 1 file changed, 1 insertion(+) diff --git a/client/default_keys.dic b/client/default_keys.dic index 4df09cb1c..81b03fe2c 100644 --- a/client/default_keys.dic +++ b/client/default_keys.dic @@ -950,3 +950,4 @@ A0004A000036 DFE73BE48AC6 # B069D0D03D17 +000131B93F28 From 54a18ebf2bf11997e6cb512e72d35e70bc823b23 Mon Sep 17 00:00:00 2001 From: netvader <5840601+netvader@users.noreply.github.com> Date: Fri, 26 Jul 2019 22:45:16 +0200 Subject: [PATCH 0161/1854] Update default_keys.dic added some keys from clever fit gym, hotel room turkey, and simonsvoss key card --- client/default_keys.dic | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/client/default_keys.dic b/client/default_keys.dic index 4df09cb1c..33fffa3fb 100644 --- a/client/default_keys.dic +++ b/client/default_keys.dic @@ -162,6 +162,10 @@ AAFB06045877, --EPI Envisionte# 3dprinter # gym 3e65e4fb65b3, --Fysiken A 25094df6f148, --Fysiken B +a05dbd98e0fc, -- CleverFit +# +d3b595e9dd63, -- Hotel KeyCard +6471a5ef2d1a, -- SimonsVoss # # 24-7 D21762B2DE3B, From e9b493ead6d6a90b9982b464d01764e18f522136 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 27 Jul 2019 02:39:30 -0400 Subject: [PATCH 0162/1854] style --- client/cmdlft55xx.c | 103 ++++++++++++++++++++++---------------------- 1 file changed, 51 insertions(+), 52 deletions(-) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 3d0871893..d226a7694 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -2614,60 +2614,59 @@ static int CmdT55xxSetDeviceConfig(const char *Cmd) { if (errors || cmdp == 0) return usage_lf_deviceconfig(); t55xx_config conf = {0}; -/* if (erase) { - memset (&conf,0xff, sizeof(conf)); - printf ("Conf.m[0] %x\n",conf.m[0].start_gap); - */ - // - if (set_defaults){ - // fixed bit length - conf.m[T55xx_DLMode_Fixed].start_gap = 29 * 8; - conf.m[T55xx_DLMode_Fixed].write_gap = 17 * 8; - conf.m[T55xx_DLMode_Fixed].write_0 = 15 * 8; - conf.m[T55xx_DLMode_Fixed].write_1 = 47 * 8; - conf.m[T55xx_DLMode_Fixed].read_gap = 15 * 8; - conf.m[T55xx_DLMode_Fixed].write_2 = 0; - conf.m[T55xx_DLMode_Fixed].write_3 = 0; - - // long leading reference - conf.m[T55xx_DLMode_LLR].start_gap = 31 * 8; - conf.m[T55xx_DLMode_LLR].write_gap = 20 * 8; - conf.m[T55xx_DLMode_LLR].write_0 = 18 * 8; - conf.m[T55xx_DLMode_LLR].write_1 = 50 * 8; - conf.m[T55xx_DLMode_LLR].read_gap = 15 * 8; - conf.m[T55xx_DLMode_LLR].write_2 = 0; - conf.m[T55xx_DLMode_LLR].write_3 = 0; - - // leading zero - conf.m[T55xx_DLMode_Leading0].start_gap = 31 * 8; - conf.m[T55xx_DLMode_Leading0].write_gap = 20 * 8; - conf.m[T55xx_DLMode_Leading0].write_0 = 18 * 8; - conf.m[T55xx_DLMode_Leading0].write_1 = 40 * 8; - conf.m[T55xx_DLMode_Leading0].read_gap = 15 * 8; - conf.m[T55xx_DLMode_Leading0].write_2 = 0; - conf.m[T55xx_DLMode_Leading0].write_3 = 0; + /* if (erase) { + memset (&conf,0xff, sizeof(conf)); + printf ("Conf.m[0] %x\n",conf.m[0].start_gap); + */ + // + if (set_defaults) { + // fixed bit length + conf.m[T55xx_DLMode_Fixed].start_gap = 29 * 8; + conf.m[T55xx_DLMode_Fixed].write_gap = 17 * 8; + conf.m[T55xx_DLMode_Fixed].write_0 = 15 * 8; + conf.m[T55xx_DLMode_Fixed].write_1 = 47 * 8; + conf.m[T55xx_DLMode_Fixed].read_gap = 15 * 8; + conf.m[T55xx_DLMode_Fixed].write_2 = 0; + conf.m[T55xx_DLMode_Fixed].write_3 = 0; - // 1 of 4 coding reference - conf.m[T55xx_DLMode_1of4].start_gap = 29 * 8; - conf.m[T55xx_DLMode_1of4].write_gap = 17 * 8; - conf.m[T55xx_DLMode_1of4].write_0 = 15 * 8; - conf.m[T55xx_DLMode_1of4].write_1 = 31 * 8; - conf.m[T55xx_DLMode_1of4].read_gap = 15 * 8; - conf.m[T55xx_DLMode_1of4].write_2 = 47 * 8; - conf.m[T55xx_DLMode_1of4].write_3 = 63 * 8; + // long leading reference + conf.m[T55xx_DLMode_LLR].start_gap = 31 * 8; + conf.m[T55xx_DLMode_LLR].write_gap = 20 * 8; + conf.m[T55xx_DLMode_LLR].write_0 = 18 * 8; + conf.m[T55xx_DLMode_LLR].write_1 = 50 * 8; + conf.m[T55xx_DLMode_LLR].read_gap = 15 * 8; + conf.m[T55xx_DLMode_LLR].write_2 = 0; + conf.m[T55xx_DLMode_LLR].write_3 = 0; + + // leading zero + conf.m[T55xx_DLMode_Leading0].start_gap = 31 * 8; + conf.m[T55xx_DLMode_Leading0].write_gap = 20 * 8; + conf.m[T55xx_DLMode_Leading0].write_0 = 18 * 8; + conf.m[T55xx_DLMode_Leading0].write_1 = 40 * 8; + conf.m[T55xx_DLMode_Leading0].read_gap = 15 * 8; + conf.m[T55xx_DLMode_Leading0].write_2 = 0; + conf.m[T55xx_DLMode_Leading0].write_3 = 0; + + // 1 of 4 coding reference + conf.m[T55xx_DLMode_1of4].start_gap = 29 * 8; + conf.m[T55xx_DLMode_1of4].write_gap = 17 * 8; + conf.m[T55xx_DLMode_1of4].write_0 = 15 * 8; + conf.m[T55xx_DLMode_1of4].write_1 = 31 * 8; + conf.m[T55xx_DLMode_1of4].read_gap = 15 * 8; + conf.m[T55xx_DLMode_1of4].write_2 = 47 * 8; + conf.m[T55xx_DLMode_1of4].write_3 = 63 * 8; + + } else { + + conf.m[downlink_mode].start_gap = startgap * 8; + conf.m[downlink_mode].write_gap = writegap * 8; + conf.m[downlink_mode].write_0 = write0 * 8; + conf.m[downlink_mode].write_1 = write1 * 8; + conf.m[downlink_mode].read_gap = readgap * 8; + conf.m[downlink_mode].write_2 = write2 * 8; + conf.m[downlink_mode].write_3 = write3 * 8; + } - } - else { - - conf.m[downlink_mode].start_gap = startgap * 8; - conf.m[downlink_mode].write_gap = writegap * 8; - conf.m[downlink_mode].write_0 = write0 * 8; - conf.m[downlink_mode].write_1 = write1 * 8; - conf.m[downlink_mode].read_gap = readgap * 8; - conf.m[downlink_mode].write_2 = write2 * 8; - conf.m[downlink_mode].write_3 = write3 * 8; - } - clearCommandBuffer(); SendCommandOLD(CMD_SET_LF_T55XX_CONFIG, shall_persist, 0, 0, &conf, sizeof(t55xx_config)); return PM3_SUCCESS; From a5973825308d5ba016d1a720704a1512ba39e7e3 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 27 Jul 2019 09:36:16 +0200 Subject: [PATCH 0163/1854] chg: 't55' - adapting to codestyle, added some colors to message outputs, change comments --- armsrc/apps.h | 2 +- armsrc/lfops.c | 317 +++++++++++++++++++++++++++---------------------- 2 files changed, 178 insertions(+), 141 deletions(-) diff --git a/armsrc/apps.h b/armsrc/apps.h index e3ea8048c..aa1170ec7 100644 --- a/armsrc/apps.h +++ b/armsrc/apps.h @@ -107,7 +107,7 @@ void T55xxResetRead(uint8_t flags); void T55xxWriteBlock(uint8_t *data); // void T55xxWriteBlockExt(uint32_t data, uint8_t blockno, uint32_t pwd, uint8_t flags); void T55xxReadBlock(uint8_t page, bool pwd_mode, bool brute_mem, uint8_t block, uint32_t pwd, uint8_t downlink_mode); -void T55xxWakeUp(uint32_t Pwd, uint8_t flags); +void T55xxWakeUp(uint32_t pwd, uint8_t flags); void T55xx_ChkPwds(uint8_t flags); void TurnReadLFOn(uint32_t delay); diff --git a/armsrc/lfops.c b/armsrc/lfops.c index af80e2f6c..a8f7c60ef 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -20,15 +20,16 @@ #include "usb_cdc.h" // for usb_poll_validate_length #include "common.h" #include "pmflash.h" -#include "flashmem.h" // persistence on mem +#include "flashmem.h" // persistence on flash +/* +Notes about EM4xxx timings. +The timing values differs between cards, we got EM410x, EM43x5, EM445x etc. +We are trying to unify and enable the Proxmark to easily detect and select correct timings automatic. +The measures from datasheets doesn't always match correct the hardware features of RDV4 antenans and we still wanted to let other devices with other custom antennas +still benefit from this repo. This is why its configurable and we use to set these dynamic settings in device external flash memory. -//#define START_GAP 31*8 // was 250 // SPEC: 1*8 to 50*8 - typ 15*8 (15fc) -//#define WRITE_GAP 8*8 // 17*8 // was 160 // SPEC: 1*8 to 20*8 - typ 10*8 (10fc) -//#define WRITE_0 15*8 // 18*8 // was 144 // SPEC: 16*8 to 32*8 - typ 24*8 (24fc) -//#define WRITE_1 47*8 // 50*8 // was 400 // SPEC: 48*8 to 64*8 - typ 56*8 (56fc) 432 for T55x7; 448 for E5550 -//#define READ_GAP 15*8 // VALUES TAKEN FROM EM4x function: SendForward // START_GAP = 440; (55*8) cycles at 125Khz (8us = 1cycle) @@ -38,24 +39,34 @@ // These timings work for 4469/4269/4305 (with the 55*8 above) // WRITE_0 = 23*8 , 9*8 -// Sam7s has several timers, we will use the source TIMER_CLOCK1 (aka AT91C_TC_CLKS_TIMER_DIV1_CLOCK) -// TIMER_CLOCK1 = MCK/2, MCK is running at 48 MHz, Timer is running at 48/2 = 24 MHz -// Hitag units (T0) have duration of 8 microseconds (us), which is 1/125000 per second (carrier) -// T0 = TIMER_CLOCK1 / 125000 = 192 -// 1 Cycle = 8 microseconds(us) == 1 field clock +Not about ARM TIMERS +Short note about timers on Proxmark device ARM. They are a bit differently implemented and gives decent correctness. + +SAM7S has several timers, we will use the source TIMER_CLOCK1 (aka AT91C_TC_CLKS_TIMER_DIV1_CLOCK) + TIMER_CLOCK1 = MCK/2, MCK is running at 48 MHz, Timer is running at 48/2 = 24 MHz + +New timer implemenation in ticks.c, which is used in LFOPS.c + 1us = 1.5ticks + 1fc = 8us = 12ticks + +Terms you find in different datasheets and how they match. +1 Cycle = 8 microseconds(us) == 1 field clock (fc) + +Note about HITAG timing +Hitag units (T0) have duration of 8 microseconds (us), which is 1/125000 per second (carrier) + T0 = TIMER_CLOCK1 / 125000 = 192 + -// new timer: -// = 1us = 1.5ticks -// 1fc = 8us = 12ticks -/* ========================================================================================================== T55x7 Timing ========================================================================================================== - // t55xx_config t_config = { 29 * 8, 17 * 8, 15 * 8, 47 * 8, 15 * 8 } ; - ATA5577 Downlink Protocol Timings. Note: All absolute times assume TC = 1 / fC = 8 μs (fC = 125 kHz) + + Note: These timings are from the datasheet and doesn't map the best to the features of the RVD4 LF antenna. + RDV4 LF antenna has high voltage and the drop of power when turning off the rf field takes about 1-2 TC longer. + ----------------------------------------------------------------------- Fixed-bit-length Protocol | Normal Downlink | Fast Downlink | ------------------------------+-----------------------------------+-----------------------------------+------ @@ -110,21 +121,23 @@ | |10 data | d10 | dref + 25 | dref + 32 | dref + 40 | dref + 13 | dref + 16 | dref + 20 | Tc | | |11 data | d11 | dref + 41 | dref + 48 | dref + 56 | dref + 21 | dref + 24 | dref + 28 | Tc | ------------------------------------------------------------------------------------------------------------- -*/ -// Initial values if not in flash -/* -// Note: Moved * 8 to apply when used. Saving 28 bytes here (- the *8) and 28 bytes flash. -// StartGap WriteGap Bit 0/00 Bit 1/01 Bit 10 Bit 11 ReadGap -t55xx_config T55xx_Timing = {{ + +Initial values if not in flash + + SG = Start gap + WG = Write gap + RG = Read gap + + Explainations for array T55xx_Timing below + SG WG Bit 0/00 Bit 1/01 Bit 10 Bit 11 RG + -------------------------------------------------------------------- { 29 , 17 , 15 , 47 , 0 , 0 , 15 }, // Default Fixed { 31 , 20 , 18 , 50 , 0 , 0 , 15 }, // Long Leading Ref. { 31 , 20 , 18 , 40 , 0 , 0 , 15 }, // Leading 0 { 29 , 17 , 15 , 31 , 47 , 63 , 15 } // 1 of 4 - } -}; */ -// StartGap WriteGap Bit 0/00 Bit 1/01 ReadGap Bit 10 Bit 11 -t55xx_config T55xx_Timing = {{ +t55xx_config T55xx_Timing = { + { { 29 * 8, 17 * 8, 15 * 8, 47 * 8, 15 * 8, 0, 0 }, // Default Fixed { 31 * 8, 20 * 8, 18 * 8, 50 * 8, 15 * 8, 0, 0 }, // Long Leading Ref. { 31 * 8, 20 * 8, 18 * 8, 40 * 8, 15 * 8, 0, 0 }, // Leading 0 @@ -134,61 +147,68 @@ t55xx_config T55xx_Timing = {{ // Some defines for readability -#define T55xx_DLMode_Fixed 0 // Default Mode -#define T55xx_DLMode_LLR 1 // Long Leading Reference -#define T55xx_DLMode_Leading0 2 // Leading Zero -#define T55xx_DLMode_1of4 3 // 1 of 4 -#define T55xx_LongLeadingReference 4 // Value to tell Write Bit to send long reference +#define T55XX_DLMODE_FIXED 0 // Default Mode +#define T55XX_DLMODE_LLR 1 // Long Leading Reference +#define T55XX_DLMODE_LEADING_ZERO 2 // Leading Zero +#define T55XX_DLMODE_1OF4 3 // 1 of 4 +#define T55XX_LONGLEADINGREFERENCE 4 // Value to tell Write Bit to send long reference void printT55xxConfig(void) { - int DLMode; - DbpString(_BLUE_("LF T55XX config")); - for (DLMode = 0; DLMode < 4; DLMode++) { - switch (DLMode) { - case T55xx_DLMode_Fixed : - Dbprintf("r 0 fixed bit length (default)"); + for (uint8_t i = 0; i < 4; i++) { + switch (i) { + case T55XX_DLMODE_FIXED : + Dbprintf(_YELLOW_("fixed bit length (default)")); break; - case T55xx_DLMode_LLR : - Dbprintf("r 1 long leading reference"); + case T55XX_DLMODE_LLR : + Dbprintf(_YELLOW_("long leading reference")); break; - case T55xx_DLMode_Leading0 : - Dbprintf("r 2 leading zero"); + case T55XX_DLMODE_LEADING_ZERO : + Dbprintf(_YELLOW_("leading zero")); break; - case T55xx_DLMode_1of4 : - Dbprintf("r 3 1 of 4 coding reference"); + case T55XX_DLMODE_1OF4 : + Dbprintf(_YELLOW_("1 of 4 coding reference")); break; } - Dbprintf(" [a] startgap............%d*8 (%d)", T55xx_Timing.m[DLMode].start_gap / 8, T55xx_Timing.m[DLMode].start_gap); - Dbprintf(" [b] writegap............%d*8 (%d)", T55xx_Timing.m[DLMode].write_gap / 8, T55xx_Timing.m[DLMode].write_gap); - Dbprintf(" [c] write_0.............%d*8 (%d)", T55xx_Timing.m[DLMode].write_0 / 8, T55xx_Timing.m[DLMode].write_0); - Dbprintf(" [d] write_1.............%d*8 (%d)", T55xx_Timing.m[DLMode].write_1 / 8, T55xx_Timing.m[DLMode].write_1); - Dbprintf(" [e] readgap.............%d*8 (%d)", T55xx_Timing.m[DLMode].read_gap / 8, T55xx_Timing.m[DLMode].read_gap); - if (DLMode == T55xx_DLMode_1of4) { - Dbprintf(" [f] write_2.............%d*8 (%d)", T55xx_Timing.m[DLMode].write_2 / 8, T55xx_Timing.m[DLMode].write_2); - Dbprintf(" [g] write_3.............%d*8 (%d)", T55xx_Timing.m[DLMode].write_3 / 8, T55xx_Timing.m[DLMode].write_3); + Dbprintf(" [a] startgap............%d*8 (%d)", T55xx_Timing.m[i].start_gap / 8, T55xx_Timing.m[i].start_gap); + Dbprintf(" [b] writegap............%d*8 (%d)", T55xx_Timing.m[i].write_gap / 8, T55xx_Timing.m[i].write_gap); + Dbprintf(" [c] write_0.............%d*8 (%d)", T55xx_Timing.m[i].write_0 / 8, T55xx_Timing.m[i].write_0); + Dbprintf(" [d] write_1.............%d*8 (%d)", T55xx_Timing.m[i].write_1 / 8, T55xx_Timing.m[i].write_1); + Dbprintf(" [e] readgap.............%d*8 (%d)", T55xx_Timing.m[i].read_gap / 8, T55xx_Timing.m[i].read_gap); + if (i == T55XX_DLMODE_1OF4) { + Dbprintf(" [f] write_2.............%d*8 (%d)", T55xx_Timing.m[i].write_2 / 8, T55xx_Timing.m[i].write_2); + Dbprintf(" [g] write_3.............%d*8 (%d)", T55xx_Timing.m[i].write_3 / 8, T55xx_Timing.m[i].write_3); } } } void setT55xxConfig(uint8_t arg0, t55xx_config *c) { - uint8_t DLMode; -// uint8_t ClearT55Settings = c->m[0].start_gap & 0xffff; // all values will be ffff if clear requested - - - for (DLMode = 0; DLMode < 4; DLMode++) { - if (c->m[DLMode].start_gap != 0) T55xx_Timing.m[DLMode].start_gap = c->m[DLMode].start_gap;// * 8; - if (c->m[DLMode].write_gap != 0) T55xx_Timing.m[DLMode].write_gap = c->m[DLMode].write_gap;// * 8; - if (c->m[DLMode].write_0 != 0) T55xx_Timing.m[DLMode].write_0 = c->m[DLMode].write_0 ;// * 8; - if (c->m[DLMode].write_1 != 0) T55xx_Timing.m[DLMode].write_1 = c->m[DLMode].write_1 ;// * 8; - if (DLMode == T55xx_DLMode_1of4) { - if (c->m[DLMode].write_2 != 0) T55xx_Timing.m[DLMode].write_2 = c->m[DLMode].write_2;// * 8; - if (c->m[DLMode].write_3 != 0) T55xx_Timing.m[DLMode].write_3 = c->m[DLMode].write_3;// * 8 ; + for (uint8_t i = 0; i < 4; i++) { + if (c->m[i].start_gap != 0) + T55xx_Timing.m[i].start_gap = c->m[i].start_gap; + + if (c->m[i].write_gap != 0) + T55xx_Timing.m[i].write_gap = c->m[i].write_gap; + + if (c->m[i].write_0 != 0) + T55xx_Timing.m[i].write_0 = c->m[i].write_0; + + if (c->m[i].write_1 != 0) + T55xx_Timing.m[i].write_1 = c->m[i].write_1; + + if (i == T55XX_DLMODE_1OF4) { + if (c->m[i].write_2 != 0) + T55xx_Timing.m[i].write_2 = c->m[i].write_2; + + if (c->m[i].write_3 != 0) + T55xx_Timing.m[i].write_3 = c->m[i].write_3; + } else { - T55xx_Timing.m[DLMode].write_2 = 0x00; - T55xx_Timing.m[DLMode].write_3 = 0x00; + T55xx_Timing.m[i].write_2 = 0x00; + T55xx_Timing.m[i].write_3 = 0x00; } - if (c->m[DLMode].read_gap != 0) T55xx_Timing.m[DLMode].read_gap = c->m[DLMode].read_gap;//* 8; + if (c->m[i].read_gap != 0) + T55xx_Timing.m[i].read_gap = c->m[i].read_gap; } printT55xxConfig(); @@ -203,7 +223,6 @@ void setT55xxConfig(uint8_t arg0, t55xx_config *c) { return; } - uint8_t *buf = BigBuf_malloc(T55XX_CONFIG_LEN); Flash_CheckBusy(BUSY_TIMEOUT); uint16_t res = Flash_ReadDataCont(T55XX_CONFIG_OFFSET, buf, T55XX_CONFIG_LEN); @@ -215,14 +234,16 @@ void setT55xxConfig(uint8_t arg0, t55xx_config *c) { memcpy(buf, &T55xx_Timing, T55XX_CONFIG_LEN); + // delete old configuration Flash_CheckBusy(BUSY_TIMEOUT); Flash_WriteEnable(); Flash_Erase4k(3, 0xD); + // write new res = Flash_Write(T55XX_CONFIG_OFFSET, buf, T55XX_CONFIG_LEN); if (res == T55XX_CONFIG_LEN && DBGLEVEL > 1) { - DbpString("T55XX Config save success"); + DbpString("T55XX Config save " _GREEN_("success") ); } BigBuf_free(); @@ -1478,37 +1499,35 @@ void TurnReadLF_off(uint32_t delay) { } // Macro for code readability -#define BitStream_Byte(X) ((X) >> 3) -#define BitStream_Bit(X) ((X) & 7) -#define t55_llr_ref (136 * 8) -#define t55_send_PwdMode (arg & 0x01) -#define t55_send_Page ((arg & 0x02) >> 1) -#define t55_send_TestMode ((arg & 0x04) >> 2) -#define t55_send_RegReadMode ((arg & 0x20) >> 5) -#define t55_send_ReadCmd ((arg & 0x40) >> 6) -#define t55_send_Reset ((arg & 0x80) >> 7) +#define BITSTREAM_BYTE(x) ((x) >> 3) // iceman note: isn't this NIBBLE??? +#define BITSTREAM_BIT(x) ((x) & 7) + +#define T55_LLR_REF (136 * 8) // Write one bit to chip void T55xxWriteBit(uint8_t bit, uint8_t downlink_idx) { - // Dbprintf ("%d",bit); - // If bit = 4 Send Long Leading Reference which is (138*8) + WRITE_0 switch (bit) { case 0 : + // send bit 0/00 TurnReadLFOn(T55xx_Timing.m[downlink_idx].write_0); - break; // Send bit 0/00 + break; case 1 : + // send bit 1/01 TurnReadLFOn(T55xx_Timing.m[downlink_idx].write_1); - break; // Send bit 1/01 + break; case 2 : + // send bits 10 (1 of 4) TurnReadLFOn(T55xx_Timing.m[downlink_idx].write_2); - break; // Send bits 10 (1 of 4) + break; case 3 : + // send bits 11 (1 of 4) TurnReadLFOn(T55xx_Timing.m[downlink_idx].write_3); - break; // Send bits 11 (1 of 4) + break; case 4 : - TurnReadLFOn(T55xx_Timing.m[downlink_idx].write_0 + t55_llr_ref); - break; // Send Long Leading Reference + // send Long Leading Reference + TurnReadLFOn(T55xx_Timing.m[downlink_idx].write_0 + T55_LLR_REF); + break; } FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); @@ -1522,31 +1541,32 @@ void T55xxWriteBit(uint8_t bit, uint8_t downlink_idx) { // num_bits - how many bits (low x bits of data) Max 32 bits at a time // max_len - how many bytes can the bit_array hold (ensure no buffer overflow) // returns "Next" bit offset / bits stored (for next store) -uint8_t T55xx_SetBits(uint8_t *BitStream, uint8_t start_offset, uint32_t data, uint8_t num_bits, uint8_t max_len) { +uint8_t T55xx_SetBits(uint8_t *bs, uint8_t start_offset, uint32_t data, uint8_t num_bits, uint8_t max_len) { int8_t offset; - int8_t NextOffset = start_offset; + int8_t next_offset = start_offset; // Check if data will fit. if ((start_offset + num_bits) <= (max_len * 8)) { // Loop through the data and store for (offset = (num_bits - 1); offset >= 0; offset--) { - if ((data >> offset) & 1) BitStream[BitStream_Byte(NextOffset)] |= (1 << BitStream_Bit(NextOffset)); // Set the bit to 1 - else BitStream[BitStream_Byte(NextOffset)] &= (0xff ^ (1 << BitStream_Bit(NextOffset))); // Set the bit to 0 + if ((data >> offset) & 1) + bs[BITSTREAM_BYTE(next_offset)] |= (1 << BITSTREAM_BIT(next_offset)); // Set 1 + else + bs[BITSTREAM_BYTE(next_offset)] &= (0xff ^ (1 << BITSTREAM_BIT(next_offset))); // Set 0 - NextOffset++; + next_offset++; } } else { // Note: This should never happen unless some code changes cause it. // So short message for coders when testing. - Dbprintf("T55 too many bits"); + Dbprintf(_RED_("T55 too many bits")); } - return NextOffset; + return next_offset; } // Send one downlink command to the card -// void T55xx_SendCMD (uint32_t Data, uint8_t Block, uint32_t Pwd, uint8_t arg) { -void T55xx_SendCMD(uint32_t Data, uint32_t Pwd, uint16_t arg) { +void T55xx_SendCMD(uint32_t data, uint32_t pwd, uint16_t arg) { /* arg bits @@ -1560,56 +1580,72 @@ void T55xx_SendCMD(uint32_t Data, uint32_t Pwd, uint16_t arg) { xxx1 xxxxxxxx 0x100 brute force 111x xxxxxxxx 0xE00 Block */ +bool t55_send_pwdmode = (arg & 0x1); +bool t55_send_page = ((arg >> 1) & 0x1); +bool t55_send_testmode = ((arg >> 2) & 0x1); +bool t55_send_regreadmode = ((arg >> 5) & 0x1); +bool t55_send_readcmd = ((arg >> 6) & 0x1); +bool t55_send_reset = ((arg >> 7) & 0x1); + // Max Downlink Command size ~74 bits, so 10 bytes (80 bits) + uint8_t bs[10]; + + uint8_t i = 0, len = 0; uint8_t downlink_mode = (arg >> 3) & 0x03; - uint8_t i = 0; - uint8_t BitStream[10]; // Max Downlink Command size ~74 bits, so 10 bytes (80 bits) - uint8_t BitStreamLen = 0; - uint8_t SendBits; - uint8_t start_wait = 4; - bool brute_mem = (arg & 0x100); - uint8_t Block = (arg >> 9) & 0x07; + uint8_t block = (arg >> 9) & 0x07; - if (brute_mem) start_wait = 0; + bool brute_mem = (arg & 0x100); - // Build Bit Stream to send. - memset(BitStream, 0x00, sizeof(BitStream)); + // no startup delay when in bruteforce command + uint8_t start_wait = (brute_mem) ? 0 : 4; - BitStreamLen = 0; // Ensure 0 bit index to start. + memset(bs, 0x00, sizeof(bs)); - // Add Leading 0 and 1 of 4 reference bit - if ((downlink_mode == T55xx_DLMode_Leading0) || (downlink_mode == T55xx_DLMode_1of4)) - BitStreamLen = T55xx_SetBits(BitStream, BitStreamLen, 0, 1, sizeof(BitStream)); + // build bit stream to send. + + // add Leading 0 + if (downlink_mode == T55XX_DLMODE_LEADING_ZERO) + len = T55xx_SetBits(bs, len, 0, 1, sizeof(bs)); - // Add extra reference 0 for 1 of 4 - if (downlink_mode == T55xx_DLMode_1of4) - BitStreamLen = T55xx_SetBits(BitStream, BitStreamLen, 0, 1, sizeof(BitStream)); - - // Add Opcode - if (t55_send_Reset) { - // Reset : r*) 00 - BitStreamLen = T55xx_SetBits(BitStream, BitStreamLen, 0, 2, sizeof(BitStream)); + // add 1 of 4 reference bit + if (downlink_mode == T55XX_DLMODE_1OF4) { + len = T55xx_SetBits(bs, len, 0, 1, sizeof(bs)); + // add extra zero + len = T55xx_SetBits(bs, len, 0, 1, sizeof(bs)); + } + + // add Opcode + if (t55_send_reset) { + // reset : r*) 00 + len = T55xx_SetBits(bs, len, 0, 2, sizeof(bs)); } else { - if (t55_send_TestMode) Dbprintf("TestMODE"); - BitStreamLen = T55xx_SetBits(BitStream, BitStreamLen, t55_send_TestMode ? 0 : 1, 1, sizeof(BitStream)); - BitStreamLen = T55xx_SetBits(BitStream, BitStreamLen, t55_send_TestMode ? 1 : t55_send_Page, 1, sizeof(BitStream)); - //if (PwdMode) { - if (t55_send_PwdMode) { + + if (t55_send_testmode) + Dbprintf(_YELLOW_("Using Test Mode")); + + len = T55xx_SetBits(bs, len, t55_send_testmode ? 0 : 1, 1, sizeof(bs)); + + len = T55xx_SetBits(bs, len, t55_send_testmode ? 1 : t55_send_page, 1, sizeof(bs)); + + if (t55_send_pwdmode) { // Leading 0 and 1 of 4 00 fixed bits if passsword used - if ((downlink_mode == T55xx_DLMode_Leading0) || (downlink_mode == T55xx_DLMode_1of4)) { - BitStreamLen = T55xx_SetBits(BitStream, BitStreamLen, 0, 2, sizeof(BitStream)); + if ((downlink_mode == T55XX_DLMODE_LEADING_ZERO) || (downlink_mode == T55XX_DLMODE_1OF4)) { + len = T55xx_SetBits(bs, len, 0, 2, sizeof(bs)); } - BitStreamLen = T55xx_SetBits(BitStream, BitStreamLen, Pwd, 32, sizeof(BitStream)); + len = T55xx_SetBits(bs, len, pwd, 32, sizeof(bs)); } // Add Lock bit 0 - if (!t55_send_RegReadMode) BitStreamLen = T55xx_SetBits(BitStream, BitStreamLen, 0, 1, sizeof(BitStream)); + if (t55_send_regreadmode == false) + len = T55xx_SetBits(bs, len, 0, 1, sizeof(bs)); // Add Data if a write command - if (!t55_send_ReadCmd) BitStreamLen = T55xx_SetBits(BitStream, BitStreamLen, Data, 32, sizeof(BitStream)); + if (t55_send_readcmd == false) + len = T55xx_SetBits(bs, len, data, 32, sizeof(bs)); // Add Address - if (!t55_send_RegReadMode) BitStreamLen = T55xx_SetBits(BitStream, BitStreamLen, Block, 3, sizeof(BitStream)); + if (t55_send_regreadmode == false) + len = T55xx_SetBits(bs, len, block, 3, sizeof(bs)); } // Send Bits to T55xx @@ -1624,19 +1660,20 @@ void T55xx_SendCMD(uint32_t Data, uint32_t Pwd, uint16_t arg) { WaitUS(T55xx_Timing.m[downlink_mode].start_gap * 8); // If long leading 0 send long reference pulse - if (downlink_mode == T55xx_DLMode_LLR) - T55xxWriteBit(T55xx_LongLeadingReference, downlink_mode);//Timing); // Send Long Leading Start Reference + if (downlink_mode == T55XX_DLMODE_LLR) + T55xxWriteBit(T55XX_LONGLEADINGREFERENCE, downlink_mode);//Timing); // Send Long Leading Start Reference - if ((downlink_mode == T55xx_DLMode_1of4) && (BitStreamLen > 0)) { // 1 of 4 need to send 2 bits at a time - for (i = 0; i < BitStreamLen - 1; i += 2) { - SendBits = (BitStream[BitStream_Byte(i)] >> (BitStream_Bit(i)) & 1) << 1; // Bit i - SendBits += (BitStream[BitStream_Byte(i + 1)] >> (BitStream_Bit(i + 1)) & 1); // Bit i+1; - T55xxWriteBit(SendBits & 3, downlink_mode);//Timing); + uint8_t sendbits; + if ((downlink_mode == T55XX_DLMODE_1OF4) && (len > 0)) { // 1 of 4 need to send 2 bits at a time + for (i = 0; i < len - 1; i += 2) { + sendbits = (bs[BITSTREAM_BYTE(i)] >> (BITSTREAM_BIT(i)) & 1) << 1; // Bit i + sendbits += (bs[BITSTREAM_BYTE(i + 1)] >> (BITSTREAM_BIT(i + 1)) & 1); // Bit i+1; + T55xxWriteBit(sendbits & 3, downlink_mode); } } else { - for (i = 0; i < BitStreamLen; i++) { - SendBits = (BitStream[BitStream_Byte(i)] >> BitStream_Bit(i)); - T55xxWriteBit(SendBits & 1, downlink_mode);//Timing); + for (i = 0; i < len; i++) { + sendbits = (bs[BITSTREAM_BYTE(i)] >> BITSTREAM_BIT(i)); + T55xxWriteBit(sendbits & 1, downlink_mode); } } } @@ -1941,12 +1978,12 @@ OUT: LEDsoff(); } -void T55xxWakeUp(uint32_t Pwd, uint8_t flags) { +void T55xxWakeUp(uint32_t pwd, uint8_t flags) { flags |= 0x01 | 0x40 | 0x20; //Password | Read Call (no data) | reg_read no block LED_B_ON(); - T55xx_SendCMD(0, Pwd, flags); + T55xx_SendCMD(0, pwd, flags); //-- Turn and leave field on to let the begin repeating transmission TurnReadLFOn(20 * 1000); From b4eb41ee6620ee4d49c7b5c8c221031b2b5e3909 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 27 Jul 2019 09:50:24 +0200 Subject: [PATCH 0164/1854] chg: 't55' more style --- armsrc/lfops.c | 55 +++++++++++++++++++++++++------------------------- 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/armsrc/lfops.c b/armsrc/lfops.c index a8f7c60ef..08ebdf2f7 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -1570,37 +1570,36 @@ void T55xx_SendCMD(uint32_t data, uint32_t pwd, uint16_t arg) { /* arg bits - xxxx xxxxxxx1 0x001 PwdMode - xxxx xxxxxx1x 0x002 Page - xxxx xxxxx1xx 0x004 testMode - xxxx xxx11xxx 0x018 downlink mode - xxxx xx1xxxxx 0x020 !reg_readmode - xxxx x1xxxxxx 0x040 called for a read, so no data packet - xxxx 1xxxxxxx 0x080 reset - xxx1 xxxxxxxx 0x100 brute force - 111x xxxxxxxx 0xE00 Block + xxxx xxxxxxx1 0x001 password mode (Y/N) + xxxx xxxxxx1x 0x002 page (0|1) + xxxx xxxxx1xx 0x004 test mode (Y/N) + xxxx xxx11xxx 0x018 selected downlink mode (0|1|2|3|) + xxxx xx1xxxxx 0x020 !reg_readmode (ICEMAN ?? Why use negative in the bool ??) + xxxx x1xxxxxx 0x040 called for a read, so no data packet (Y/N) + xxxx 1xxxxxxx 0x080 reset (Y/N) + xxx1 xxxxxxxx 0x100 brute force (Y/N) + 111x xxxxxxxx 0xE00 block to write (0-7) */ -bool t55_send_pwdmode = (arg & 0x1); -bool t55_send_page = ((arg >> 1) & 0x1); -bool t55_send_testmode = ((arg >> 2) & 0x1); -bool t55_send_regreadmode = ((arg >> 5) & 0x1); -bool t55_send_readcmd = ((arg >> 6) & 0x1); -bool t55_send_reset = ((arg >> 7) & 0x1); + bool t55_send_pwdmode = (arg & 0x1); + bool t55_send_page = ((arg >> 1) & 0x1); + bool t55_send_testmode = ((arg >> 2) & 0x1); + bool t55_send_regreadmode = ((arg >> 5) & 0x1); + bool t55_send_readcmd = ((arg >> 6) & 0x1); + bool t55_send_reset = ((arg >> 7) & 0x1); + bool t55_brute_mem = ((arg >> 8) & 0x1); - // Max Downlink Command size ~74 bits, so 10 bytes (80 bits) - uint8_t bs[10]; - - uint8_t i = 0, len = 0; - uint8_t downlink_mode = (arg >> 3) & 0x03; - uint8_t block = (arg >> 9) & 0x07; - - bool brute_mem = (arg & 0x100); + uint8_t downlink_mode = (arg >> 3) & 0x03; + uint8_t block_no = (arg >> 9) & 0x07; // no startup delay when in bruteforce command - uint8_t start_wait = (brute_mem) ? 0 : 4; - + uint8_t start_wait = (t55_brute_mem) ? 0 : 4; + + // Max Downlink Command size ~74 bits, so 10 bytes (80 bits) + uint8_t bs[10]; memset(bs, 0x00, sizeof(bs)); + uint8_t len = 0; + // build bit stream to send. // add Leading 0 @@ -1645,7 +1644,7 @@ bool t55_send_reset = ((arg >> 7) & 0x1); // Add Address if (t55_send_regreadmode == false) - len = T55xx_SetBits(bs, len, block, 3, sizeof(bs)); + len = T55xx_SetBits(bs, len, block_no, 3, sizeof(bs)); } // Send Bits to T55xx @@ -1665,13 +1664,13 @@ bool t55_send_reset = ((arg >> 7) & 0x1); uint8_t sendbits; if ((downlink_mode == T55XX_DLMODE_1OF4) && (len > 0)) { // 1 of 4 need to send 2 bits at a time - for (i = 0; i < len - 1; i += 2) { + for (uint8_t i = 0; i < len - 1; i += 2) { sendbits = (bs[BITSTREAM_BYTE(i)] >> (BITSTREAM_BIT(i)) & 1) << 1; // Bit i sendbits += (bs[BITSTREAM_BYTE(i + 1)] >> (BITSTREAM_BIT(i + 1)) & 1); // Bit i+1; T55xxWriteBit(sendbits & 3, downlink_mode); } } else { - for (i = 0; i < len; i++) { + for (uint8_t i = 0; i < len; i++) { sendbits = (bs[BITSTREAM_BYTE(i)] >> BITSTREAM_BIT(i)); T55xxWriteBit(sendbits & 1, downlink_mode); } From 548c2ed9989377799279e3198968f98138de7803 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 27 Jul 2019 03:54:01 -0400 Subject: [PATCH 0165/1854] make style --- armsrc/lfops.c | 52 +++++++++++++++++++++++++------------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 08ebdf2f7..2c9abbda1 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -63,10 +63,10 @@ Hitag units (T0) have duration of 8 microseconds (us), which is 1/125000 per sec ATA5577 Downlink Protocol Timings. Note: All absolute times assume TC = 1 / fC = 8 μs (fC = 125 kHz) - + Note: These timings are from the datasheet and doesn't map the best to the features of the RVD4 LF antenna. RDV4 LF antenna has high voltage and the drop of power when turning off the rf field takes about 1-2 TC longer. - + ----------------------------------------------------------------------- Fixed-bit-length Protocol | Normal Downlink | Fast Downlink | ------------------------------+-----------------------------------+-----------------------------------+------ @@ -184,25 +184,25 @@ void printT55xxConfig(void) { void setT55xxConfig(uint8_t arg0, t55xx_config *c) { for (uint8_t i = 0; i < 4; i++) { - if (c->m[i].start_gap != 0) + if (c->m[i].start_gap != 0) T55xx_Timing.m[i].start_gap = c->m[i].start_gap; - - if (c->m[i].write_gap != 0) + + if (c->m[i].write_gap != 0) T55xx_Timing.m[i].write_gap = c->m[i].write_gap; - - if (c->m[i].write_0 != 0) + + if (c->m[i].write_0 != 0) T55xx_Timing.m[i].write_0 = c->m[i].write_0; - - if (c->m[i].write_1 != 0) + + if (c->m[i].write_1 != 0) T55xx_Timing.m[i].write_1 = c->m[i].write_1; - + if (i == T55XX_DLMODE_1OF4) { if (c->m[i].write_2 != 0) T55xx_Timing.m[i].write_2 = c->m[i].write_2; - + if (c->m[i].write_3 != 0) T55xx_Timing.m[i].write_3 = c->m[i].write_3; - + } else { T55xx_Timing.m[i].write_2 = 0x00; T55xx_Timing.m[i].write_3 = 0x00; @@ -243,7 +243,7 @@ void setT55xxConfig(uint8_t arg0, t55xx_config *c) { res = Flash_Write(T55XX_CONFIG_OFFSET, buf, T55XX_CONFIG_LEN); if (res == T55XX_CONFIG_LEN && DBGLEVEL > 1) { - DbpString("T55XX Config save " _GREEN_("success") ); + DbpString("T55XX Config save " _GREEN_("success")); } BigBuf_free(); @@ -1527,7 +1527,7 @@ void T55xxWriteBit(uint8_t bit, uint8_t downlink_idx) { case 4 : // send Long Leading Reference TurnReadLFOn(T55xx_Timing.m[downlink_idx].write_0 + T55_LLR_REF); - break; + break; } FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); @@ -1550,7 +1550,7 @@ uint8_t T55xx_SetBits(uint8_t *bs, uint8_t start_offset, uint32_t data, uint8_t // Loop through the data and store for (offset = (num_bits - 1); offset >= 0; offset--) { - if ((data >> offset) & 1) + if ((data >> offset) & 1) bs[BITSTREAM_BYTE(next_offset)] |= (1 << BITSTREAM_BIT(next_offset)); // Set 1 else bs[BITSTREAM_BYTE(next_offset)] &= (0xff ^ (1 << BITSTREAM_BIT(next_offset))); // Set 0 @@ -1573,8 +1573,8 @@ void T55xx_SendCMD(uint32_t data, uint32_t pwd, uint16_t arg) { xxxx xxxxxxx1 0x001 password mode (Y/N) xxxx xxxxxx1x 0x002 page (0|1) xxxx xxxxx1xx 0x004 test mode (Y/N) - xxxx xxx11xxx 0x018 selected downlink mode (0|1|2|3|) - xxxx xx1xxxxx 0x020 !reg_readmode (ICEMAN ?? Why use negative in the bool ??) + xxxx xxx11xxx 0x018 selected downlink mode (0|1|2|3|) + xxxx xx1xxxxx 0x020 !reg_readmode (ICEMAN ?? Why use negative in the bool ??) xxxx x1xxxxxx 0x040 called for a read, so no data packet (Y/N) xxxx 1xxxxxxx 0x080 reset (Y/N) xxx1 xxxxxxxx 0x100 brute force (Y/N) @@ -1593,7 +1593,7 @@ void T55xx_SendCMD(uint32_t data, uint32_t pwd, uint16_t arg) { // no startup delay when in bruteforce command uint8_t start_wait = (t55_brute_mem) ? 0 : 4; - + // Max Downlink Command size ~74 bits, so 10 bytes (80 bits) uint8_t bs[10]; memset(bs, 0x00, sizeof(bs)); @@ -1601,7 +1601,7 @@ void T55xx_SendCMD(uint32_t data, uint32_t pwd, uint16_t arg) { uint8_t len = 0; // build bit stream to send. - + // add Leading 0 if (downlink_mode == T55XX_DLMODE_LEADING_ZERO) len = T55xx_SetBits(bs, len, 0, 1, sizeof(bs)); @@ -1612,20 +1612,20 @@ void T55xx_SendCMD(uint32_t data, uint32_t pwd, uint16_t arg) { // add extra zero len = T55xx_SetBits(bs, len, 0, 1, sizeof(bs)); } - + // add Opcode if (t55_send_reset) { // reset : r*) 00 len = T55xx_SetBits(bs, len, 0, 2, sizeof(bs)); } else { - - if (t55_send_testmode) + + if (t55_send_testmode) Dbprintf(_YELLOW_("Using Test Mode")); - + len = T55xx_SetBits(bs, len, t55_send_testmode ? 0 : 1, 1, sizeof(bs)); - + len = T55xx_SetBits(bs, len, t55_send_testmode ? 1 : t55_send_page, 1, sizeof(bs)); - + if (t55_send_pwdmode) { // Leading 0 and 1 of 4 00 fixed bits if passsword used if ((downlink_mode == T55XX_DLMODE_LEADING_ZERO) || (downlink_mode == T55XX_DLMODE_1OF4)) { @@ -1635,7 +1635,7 @@ void T55xx_SendCMD(uint32_t data, uint32_t pwd, uint16_t arg) { } // Add Lock bit 0 - if (t55_send_regreadmode == false) + if (t55_send_regreadmode == false) len = T55xx_SetBits(bs, len, 0, 1, sizeof(bs)); // Add Data if a write command From c951e54ff2db5ca61335e8212cb98d8f2900808f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 27 Jul 2019 10:06:38 +0200 Subject: [PATCH 0166/1854] chg: 'lf t55xx deviceconfig' - change text when not configured --- armsrc/lfops.c | 42 +++++++++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 2c9abbda1..132ebe53c 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -170,14 +170,42 @@ void printT55xxConfig(void) { Dbprintf(_YELLOW_("1 of 4 coding reference")); break; } - Dbprintf(" [a] startgap............%d*8 (%d)", T55xx_Timing.m[i].start_gap / 8, T55xx_Timing.m[i].start_gap); - Dbprintf(" [b] writegap............%d*8 (%d)", T55xx_Timing.m[i].write_gap / 8, T55xx_Timing.m[i].write_gap); - Dbprintf(" [c] write_0.............%d*8 (%d)", T55xx_Timing.m[i].write_0 / 8, T55xx_Timing.m[i].write_0); - Dbprintf(" [d] write_1.............%d*8 (%d)", T55xx_Timing.m[i].write_1 / 8, T55xx_Timing.m[i].write_1); - Dbprintf(" [e] readgap.............%d*8 (%d)", T55xx_Timing.m[i].read_gap / 8, T55xx_Timing.m[i].read_gap); + if ( T55xx_Timing.m[i].start_gap != 0xFFFF ) + Dbprintf(" [a] startgap............%d*8 (%d)", T55xx_Timing.m[i].start_gap / 8, T55xx_Timing.m[i].start_gap); + else + Dbprintf(" [a] startgap............" _RED_("unconfigured") ); + + if ( T55xx_Timing.m[i].write_gap != 0xFFFF ) + Dbprintf(" [b] writegap............%d*8 (%d)", T55xx_Timing.m[i].write_gap / 8, T55xx_Timing.m[i].write_gap); + else + Dbprintf(" [b] writegap............" _RED_("unconfigured") ); + + if ( T55xx_Timing.m[i].write_0 != 0xFFFF ) + Dbprintf(" [c] write_0.............%d*8 (%d)", T55xx_Timing.m[i].write_0 / 8, T55xx_Timing.m[i].write_0); + else + Dbprintf(" [c] write_0............." _RED_("unconfigured") ); + + if ( T55xx_Timing.m[i].write_1 != 0xFFFF ) + Dbprintf(" [d] write_1.............%d*8 (%d)", T55xx_Timing.m[i].write_1 / 8, T55xx_Timing.m[i].write_1); + else + Dbprintf(" [d] write_1............." _RED_("unconfigured") ); + + if ( T55xx_Timing.m[i].read_gap != 0xFFFF ) + Dbprintf(" [e] readgap.............%d*8 (%d)", T55xx_Timing.m[i].read_gap / 8, T55xx_Timing.m[i].read_gap); + else + Dbprintf(" [e] readgap............." _RED_("unconfigured") ); + if (i == T55XX_DLMODE_1OF4) { - Dbprintf(" [f] write_2.............%d*8 (%d)", T55xx_Timing.m[i].write_2 / 8, T55xx_Timing.m[i].write_2); - Dbprintf(" [g] write_3.............%d*8 (%d)", T55xx_Timing.m[i].write_3 / 8, T55xx_Timing.m[i].write_3); + + if ( T55xx_Timing.m[i].write_2 != 0xFFFF ) + Dbprintf(" [f] write_2.............%d*8 (%d)", T55xx_Timing.m[i].write_2 / 8, T55xx_Timing.m[i].write_2); + else + Dbprintf(" [f] write_2............." _RED_("unconfigured") ); + + if ( T55xx_Timing.m[i].write_3 != 0xFFFF ) + Dbprintf(" [g] write_3.............%d*8 (%d)", T55xx_Timing.m[i].write_3 / 8, T55xx_Timing.m[i].write_3); + else + Dbprintf(" [f] write_3............." _RED_("unconfigured") ); } } } From d7c967b65d0d11de3b989d297e465995ea3edbde Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 27 Jul 2019 10:25:03 +0200 Subject: [PATCH 0167/1854] chg: 'codestyle' --- client/cmdlft55xx.c | 111 +++++++++++++++++++++----------------------- 1 file changed, 52 insertions(+), 59 deletions(-) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index d226a7694..9b7837f15 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -15,11 +15,11 @@ #include "cmdlft55xx.h" // Some defines for readability -#define T55xx_DLMode_Fixed 0 // Default Mode -#define T55xx_DLMode_LLR 1 // Long Leading Reference -#define T55xx_DLMode_Leading0 2 // Leading Zero -#define T55xx_DLMode_1of4 3 // 1 of 4 -#define T55xx_LongLeadingReference 4 // Value to tell Write Bit to send long reference +#define T55XX_DLMODE_FIXED 0 // Default Mode +#define T55XX_DLMODE_LLR 1 // Long Leading Reference +#define T55XX_DLMODE_LEADING_ZERO 2 // Leading Zero +#define T55XX_DLMODE_1OF4 3 // 1 of 4 +#define T55XX_LONGLEADINGREFERENCE 4 // Value to tell Write Bit to send long reference // Default configuration t55xx_conf_block_t config = { .modulation = DEMOD_ASK, .inverted = false, .offset = 0x00, .block0 = 0x00, .Q5 = false }; @@ -55,9 +55,12 @@ static int usage_t55xx_read() { PrintAndLogEx(NORMAL, " b - block number to read. Between 0-7"); PrintAndLogEx(NORMAL, " p - OPTIONAL password (8 hex characters)"); PrintAndLogEx(NORMAL, " o - OPTIONAL override safety check"); - PrintAndLogEx(NORMAL, " 1 - OPTIONAL read Page 1 instead of Page 0"); - PrintAndLogEx(NORMAL, " r - downlink encoding '0' fixed bit length (default), '1' long leading ref."); - PrintAndLogEx(NORMAL, " '2' leading zero, '3' 1 of 4 coding ref."); + PrintAndLogEx(NORMAL, " 1 - OPTIONAL 0|1 read Page 1 instead of Page 0"); + PrintAndLogEx(NORMAL, " r - downlink encoding 0|1|2|3"); + PrintAndLogEx(NORMAL, " 0 - fixed bit length (default)"); + PrintAndLogEx(NORMAL, " 1 - long leading reference"); + PrintAndLogEx(NORMAL, " 2 - leading zero"); + PrintAndLogEx(NORMAL, " 3 - 1 of 4 coding reference"); PrintAndLogEx(NORMAL, " ****WARNING****"); PrintAndLogEx(NORMAL, " Use of read with password on a tag not configured for a pwd"); PrintAndLogEx(NORMAL, " can damage the tag"); @@ -564,28 +567,25 @@ static int SanityOfflineCheck(bool useGraphBuffer) { } void T55xx_Print_DownlinkMode(uint8_t downlink_mode) { - char Msg[80]; - sprintf(Msg, "Downlink Mode used : "); + char msg[80]; + sprintf(msg, "Downlink Mode used : "); switch (downlink_mode) { - case 0 : - strcat(Msg, "default/fixed bit length"); - break; case 1 : - strcat(Msg, "long leading reference (r 1)"); + strcat(msg, _YELLOW_("long leading reference")); break; case 2 : - strcat(Msg, "leading zero reference (r 2)"); + strcat(msg, _YELLOW_("leading zero reference")); break; case 3 : - strcat(Msg, "1 of 4 coding reference (r 3)"); + strcat(msg, _YELLOW_("1 of 4 coding reference")); break; default : - strcat(Msg, "default/fixed bit length"); + strcat(msg, _YELLOW_("default/fixed bit length")); break; } - PrintAndLogEx(NORMAL, Msg); + PrintAndLogEx(NORMAL, msg); } // static int CmdT55xxDetect(const char *Cmd) { @@ -2551,12 +2551,10 @@ static int CmdT55xxDetectPage1(const char *Cmd) { } static int CmdT55xxSetDeviceConfig(const char *Cmd) { - uint8_t startgap = 0, writegap = 0, readgap = 0; - uint8_t write0 = 0, write1 = 0, write2 = 0, write3 = 0; - bool errors = false, shall_persist = false; - uint8_t cmdp = 0; - uint8_t downlink_mode = 0; - bool set_defaults = false; + uint8_t startgap = 0, writegap = 0, readgap = 0; + uint8_t write0 = 0, write1 = 0, write2 = 0, write3 = 0; + uint8_t cmdp = 0, downlink_mode = 0; + bool errors = false, shall_persist = false, set_defaults = false; while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { @@ -2613,51 +2611,46 @@ static int CmdT55xxSetDeviceConfig(const char *Cmd) { //Validations if (errors || cmdp == 0) return usage_lf_deviceconfig(); - t55xx_config conf = {0}; - /* if (erase) { - memset (&conf,0xff, sizeof(conf)); - printf ("Conf.m[0] %x\n",conf.m[0].start_gap); - */ - // + t55xx_config conf = {{0}}; + if (set_defaults) { // fixed bit length - conf.m[T55xx_DLMode_Fixed].start_gap = 29 * 8; - conf.m[T55xx_DLMode_Fixed].write_gap = 17 * 8; - conf.m[T55xx_DLMode_Fixed].write_0 = 15 * 8; - conf.m[T55xx_DLMode_Fixed].write_1 = 47 * 8; - conf.m[T55xx_DLMode_Fixed].read_gap = 15 * 8; - conf.m[T55xx_DLMode_Fixed].write_2 = 0; - conf.m[T55xx_DLMode_Fixed].write_3 = 0; + conf.m[T55XX_DLMODE_FIXED].start_gap = 29 * 8; + conf.m[T55XX_DLMODE_FIXED].write_gap = 17 * 8; + conf.m[T55XX_DLMODE_FIXED].write_0 = 15 * 8; + conf.m[T55XX_DLMODE_FIXED].write_1 = 47 * 8; + conf.m[T55XX_DLMODE_FIXED].read_gap = 15 * 8; + conf.m[T55XX_DLMODE_FIXED].write_2 = 0; + conf.m[T55XX_DLMODE_FIXED].write_3 = 0; // long leading reference - conf.m[T55xx_DLMode_LLR].start_gap = 31 * 8; - conf.m[T55xx_DLMode_LLR].write_gap = 20 * 8; - conf.m[T55xx_DLMode_LLR].write_0 = 18 * 8; - conf.m[T55xx_DLMode_LLR].write_1 = 50 * 8; - conf.m[T55xx_DLMode_LLR].read_gap = 15 * 8; - conf.m[T55xx_DLMode_LLR].write_2 = 0; - conf.m[T55xx_DLMode_LLR].write_3 = 0; + conf.m[T55XX_DLMODE_LLR].start_gap = 31 * 8; + conf.m[T55XX_DLMODE_LLR].write_gap = 20 * 8; + conf.m[T55XX_DLMODE_LLR].write_0 = 18 * 8; + conf.m[T55XX_DLMODE_LLR].write_1 = 50 * 8; + conf.m[T55XX_DLMODE_LLR].read_gap = 15 * 8; + conf.m[T55XX_DLMODE_LLR].write_2 = 0; + conf.m[T55XX_DLMODE_LLR].write_3 = 0; // leading zero - conf.m[T55xx_DLMode_Leading0].start_gap = 31 * 8; - conf.m[T55xx_DLMode_Leading0].write_gap = 20 * 8; - conf.m[T55xx_DLMode_Leading0].write_0 = 18 * 8; - conf.m[T55xx_DLMode_Leading0].write_1 = 40 * 8; - conf.m[T55xx_DLMode_Leading0].read_gap = 15 * 8; - conf.m[T55xx_DLMode_Leading0].write_2 = 0; - conf.m[T55xx_DLMode_Leading0].write_3 = 0; + conf.m[T55XX_DLMODE_LEADING_ZERO].start_gap = 31 * 8; + conf.m[T55XX_DLMODE_LEADING_ZERO].write_gap = 20 * 8; + conf.m[T55XX_DLMODE_LEADING_ZERO].write_0 = 18 * 8; + conf.m[T55XX_DLMODE_LEADING_ZERO].write_1 = 40 * 8; + conf.m[T55XX_DLMODE_LEADING_ZERO].read_gap = 15 * 8; + conf.m[T55XX_DLMODE_LEADING_ZERO].write_2 = 0; + conf.m[T55XX_DLMODE_LEADING_ZERO].write_3 = 0; // 1 of 4 coding reference - conf.m[T55xx_DLMode_1of4].start_gap = 29 * 8; - conf.m[T55xx_DLMode_1of4].write_gap = 17 * 8; - conf.m[T55xx_DLMode_1of4].write_0 = 15 * 8; - conf.m[T55xx_DLMode_1of4].write_1 = 31 * 8; - conf.m[T55xx_DLMode_1of4].read_gap = 15 * 8; - conf.m[T55xx_DLMode_1of4].write_2 = 47 * 8; - conf.m[T55xx_DLMode_1of4].write_3 = 63 * 8; + conf.m[T55XX_DLMODE_1OF4].start_gap = 29 * 8; + conf.m[T55XX_DLMODE_1OF4].write_gap = 17 * 8; + conf.m[T55XX_DLMODE_1OF4].write_0 = 15 * 8; + conf.m[T55XX_DLMODE_1OF4].write_1 = 31 * 8; + conf.m[T55XX_DLMODE_1OF4].read_gap = 15 * 8; + conf.m[T55XX_DLMODE_1OF4].write_2 = 47 * 8; + conf.m[T55XX_DLMODE_1OF4].write_3 = 63 * 8; } else { - conf.m[downlink_mode].start_gap = startgap * 8; conf.m[downlink_mode].write_gap = writegap * 8; conf.m[downlink_mode].write_0 = write0 * 8; From e99910694b385b959cf35007a3a58aee1ff44c13 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 27 Jul 2019 15:06:58 +0200 Subject: [PATCH 0168/1854] chg: some more key, thanks @Ollibolli --- CHANGELOG.md | 1 + client/default_keys.dic | 3 +++ 2 files changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c9da6eba9..d35ed7a55 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Add some more default keys (@ollibolli) - Fix T55x7 Downlink timings backward compatible (@mwalker33) - Add proper Makefile halting when using incompatible STANDALONE and PLATFORM vars (@doegox) - Add T55x7 Downlink mode support (@mwalker33) diff --git a/client/default_keys.dic b/client/default_keys.dic index e1c2dd9d5..90e170d87 100644 --- a/client/default_keys.dic +++ b/client/default_keys.dic @@ -520,6 +520,9 @@ EC0A9B1A9E06,--Vingcard Mifare 4k Staff card BEDB604CC9D1, B8A1F613CF3D, B578F38A5C61, +B66AC040203A +6D0B6A2A0003 +2E641D99AD5B AD4FB33388BF, 69FB7B7CD8EE, 2A6D9205E7CA, From 283060f962177254b128b0fee4b25de07853c5bf Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 27 Jul 2019 21:15:43 +0200 Subject: [PATCH 0169/1854] chg: renaming a struct --- CHANGELOG.md | 2 +- armsrc/appmain.c | 2 +- armsrc/apps.h | 4 +-- armsrc/lfops.c | 6 ++-- client/cmdlft55xx.c | 74 ++++++++++++++++++++++----------------------- include/pm3_cmd.h | 20 ++++++------ include/pmflash.h | 2 +- 7 files changed, 55 insertions(+), 55 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d35ed7a55..3857b2a3d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] - - Add some more default keys (@ollibolli) + - Add some more default keys (ollibolli) - Fix T55x7 Downlink timings backward compatible (@mwalker33) - Add proper Makefile halting when using incompatible STANDALONE and PLATFORM vars (@doegox) - Add T55x7 Downlink mode support (@mwalker33) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 02829c20c..5cf0c5767 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -756,7 +756,7 @@ static void PacketReceived(PacketCommandNG *packet) { break; #ifdef WITH_LF case CMD_SET_LF_T55XX_CONFIG: { - setT55xxConfig(packet->oldarg[0], (t55xx_config *) packet->data.asBytes); + setT55xxConfig(packet->oldarg[0], (t55xx_configurations_t*) packet->data.asBytes); break; } case CMD_SET_LF_SAMPLING_CONFIG: { diff --git a/armsrc/apps.h b/armsrc/apps.h index aa1170ec7..d3fa44429 100644 --- a/armsrc/apps.h +++ b/armsrc/apps.h @@ -116,8 +116,8 @@ void EM4xReadWord(uint8_t addr, uint32_t pwd, uint8_t usepwd); void EM4xWriteWord(uint8_t addr, uint32_t data, uint32_t pwd, uint8_t usepwd); void Cotag(uint32_t arg0); -void setT55xxConfig(uint8_t arg0, t55xx_config *c); -t55xx_config *getT55xxConfig(void); +void setT55xxConfig(uint8_t arg0, t55xx_configurations_t *c); +t55xx_configurations_t *getT55xxConfig(void); void printT55xxConfig(void); void loadT55xxConfig(void); diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 132ebe53c..92414f748 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -136,7 +136,7 @@ Initial values if not in flash { 31 , 20 , 18 , 40 , 0 , 0 , 15 }, // Leading 0 { 29 , 17 , 15 , 31 , 47 , 63 , 15 } // 1 of 4 */ -t55xx_config T55xx_Timing = { +t55xx_configurations_t T55xx_Timing = { { { 29 * 8, 17 * 8, 15 * 8, 47 * 8, 15 * 8, 0, 0 }, // Default Fixed { 31 * 8, 20 * 8, 18 * 8, 50 * 8, 15 * 8, 0, 0 }, // Long Leading Ref. @@ -210,7 +210,7 @@ void printT55xxConfig(void) { } } -void setT55xxConfig(uint8_t arg0, t55xx_config *c) { +void setT55xxConfig(uint8_t arg0, t55xx_configurations_t *c) { for (uint8_t i = 0; i < 4; i++) { if (c->m[i].start_gap != 0) T55xx_Timing.m[i].start_gap = c->m[i].start_gap; @@ -278,7 +278,7 @@ void setT55xxConfig(uint8_t arg0, t55xx_config *c) { #endif } -t55xx_config *getT55xxConfig(void) { +t55xx_configurations_t *getT55xxConfig(void) { return &T55xx_Timing;//_FixedBit; } diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 9b7837f15..6a88116df 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -2611,57 +2611,57 @@ static int CmdT55xxSetDeviceConfig(const char *Cmd) { //Validations if (errors || cmdp == 0) return usage_lf_deviceconfig(); - t55xx_config conf = {{0}}; + t55xx_configurations_t configurations = {0}; if (set_defaults) { // fixed bit length - conf.m[T55XX_DLMODE_FIXED].start_gap = 29 * 8; - conf.m[T55XX_DLMODE_FIXED].write_gap = 17 * 8; - conf.m[T55XX_DLMODE_FIXED].write_0 = 15 * 8; - conf.m[T55XX_DLMODE_FIXED].write_1 = 47 * 8; - conf.m[T55XX_DLMODE_FIXED].read_gap = 15 * 8; - conf.m[T55XX_DLMODE_FIXED].write_2 = 0; - conf.m[T55XX_DLMODE_FIXED].write_3 = 0; + configurations.m[T55XX_DLMODE_FIXED].start_gap = 29 * 8; + configurations.m[T55XX_DLMODE_FIXED].write_gap = 17 * 8; + configurations.m[T55XX_DLMODE_FIXED].write_0 = 15 * 8; + configurations.m[T55XX_DLMODE_FIXED].write_1 = 47 * 8; + configurations.m[T55XX_DLMODE_FIXED].read_gap = 15 * 8; + configurations.m[T55XX_DLMODE_FIXED].write_2 = 0; + configurations.m[T55XX_DLMODE_FIXED].write_3 = 0; // long leading reference - conf.m[T55XX_DLMODE_LLR].start_gap = 31 * 8; - conf.m[T55XX_DLMODE_LLR].write_gap = 20 * 8; - conf.m[T55XX_DLMODE_LLR].write_0 = 18 * 8; - conf.m[T55XX_DLMODE_LLR].write_1 = 50 * 8; - conf.m[T55XX_DLMODE_LLR].read_gap = 15 * 8; - conf.m[T55XX_DLMODE_LLR].write_2 = 0; - conf.m[T55XX_DLMODE_LLR].write_3 = 0; + configurations.m[T55XX_DLMODE_LLR].start_gap = 31 * 8; + configurations.m[T55XX_DLMODE_LLR].write_gap = 20 * 8; + configurations.m[T55XX_DLMODE_LLR].write_0 = 18 * 8; + configurations.m[T55XX_DLMODE_LLR].write_1 = 50 * 8; + configurations.m[T55XX_DLMODE_LLR].read_gap = 15 * 8; + configurations.m[T55XX_DLMODE_LLR].write_2 = 0; + configurations.m[T55XX_DLMODE_LLR].write_3 = 0; // leading zero - conf.m[T55XX_DLMODE_LEADING_ZERO].start_gap = 31 * 8; - conf.m[T55XX_DLMODE_LEADING_ZERO].write_gap = 20 * 8; - conf.m[T55XX_DLMODE_LEADING_ZERO].write_0 = 18 * 8; - conf.m[T55XX_DLMODE_LEADING_ZERO].write_1 = 40 * 8; - conf.m[T55XX_DLMODE_LEADING_ZERO].read_gap = 15 * 8; - conf.m[T55XX_DLMODE_LEADING_ZERO].write_2 = 0; - conf.m[T55XX_DLMODE_LEADING_ZERO].write_3 = 0; + configurations.m[T55XX_DLMODE_LEADING_ZERO].start_gap = 31 * 8; + configurations.m[T55XX_DLMODE_LEADING_ZERO].write_gap = 20 * 8; + configurations.m[T55XX_DLMODE_LEADING_ZERO].write_0 = 18 * 8; + configurations.m[T55XX_DLMODE_LEADING_ZERO].write_1 = 40 * 8; + configurations.m[T55XX_DLMODE_LEADING_ZERO].read_gap = 15 * 8; + configurations.m[T55XX_DLMODE_LEADING_ZERO].write_2 = 0; + configurations.m[T55XX_DLMODE_LEADING_ZERO].write_3 = 0; // 1 of 4 coding reference - conf.m[T55XX_DLMODE_1OF4].start_gap = 29 * 8; - conf.m[T55XX_DLMODE_1OF4].write_gap = 17 * 8; - conf.m[T55XX_DLMODE_1OF4].write_0 = 15 * 8; - conf.m[T55XX_DLMODE_1OF4].write_1 = 31 * 8; - conf.m[T55XX_DLMODE_1OF4].read_gap = 15 * 8; - conf.m[T55XX_DLMODE_1OF4].write_2 = 47 * 8; - conf.m[T55XX_DLMODE_1OF4].write_3 = 63 * 8; + configurations.m[T55XX_DLMODE_1OF4].start_gap = 29 * 8; + configurations.m[T55XX_DLMODE_1OF4].write_gap = 17 * 8; + configurations.m[T55XX_DLMODE_1OF4].write_0 = 15 * 8; + configurations.m[T55XX_DLMODE_1OF4].write_1 = 31 * 8; + configurations.m[T55XX_DLMODE_1OF4].read_gap = 15 * 8; + configurations.m[T55XX_DLMODE_1OF4].write_2 = 47 * 8; + configurations.m[T55XX_DLMODE_1OF4].write_3 = 63 * 8; } else { - conf.m[downlink_mode].start_gap = startgap * 8; - conf.m[downlink_mode].write_gap = writegap * 8; - conf.m[downlink_mode].write_0 = write0 * 8; - conf.m[downlink_mode].write_1 = write1 * 8; - conf.m[downlink_mode].read_gap = readgap * 8; - conf.m[downlink_mode].write_2 = write2 * 8; - conf.m[downlink_mode].write_3 = write3 * 8; + configurations.m[downlink_mode].start_gap = startgap * 8; + configurations.m[downlink_mode].write_gap = writegap * 8; + configurations.m[downlink_mode].write_0 = write0 * 8; + configurations.m[downlink_mode].write_1 = write1 * 8; + configurations.m[downlink_mode].read_gap = readgap * 8; + configurations.m[downlink_mode].write_2 = write2 * 8; + configurations.m[downlink_mode].write_3 = write3 * 8; } clearCommandBuffer(); - SendCommandOLD(CMD_SET_LF_T55XX_CONFIG, shall_persist, 0, 0, &conf, sizeof(t55xx_config)); + SendCommandOLD(CMD_SET_LF_T55XX_CONFIG, shall_persist, 0, 0, &configurations, sizeof(t55xx_configurations_t)); return PM3_SUCCESS; } diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index be5d75b21..0c7a7d1e6 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -118,7 +118,7 @@ typedef struct { bool averaging; int divisor; int trigger_threshold; -} sample_config; +} PACKED sample_config; /* typedef struct { uint16_t start_gap; @@ -131,20 +131,20 @@ typedef struct { // Extended to support 1 of 4 timing typedef struct { - uint16_t start_gap ; - uint16_t write_gap ; - uint16_t write_0 ; - uint16_t write_1 ; - uint16_t read_gap ; - uint16_t write_2 ; - uint16_t write_3 ; - + uint16_t start_gap; + uint16_t write_gap; + uint16_t write_0; + uint16_t write_1; + uint16_t read_gap; + uint16_t write_2; + uint16_t write_3; } t55xx_config_t; + // This setup will allow for the 4 downlink modes "m" as well as other items if needed. // Given the one struct we can then read/write to flash/client in one go. typedef struct { t55xx_config_t m[4]; // mode -} t55xx_config; +} t55xx_configurations_t; /*typedef struct { uint16_t start_gap [4]; diff --git a/include/pmflash.h b/include/pmflash.h index b7bf39ddc..6e3a20e55 100644 --- a/include/pmflash.h +++ b/include/pmflash.h @@ -61,7 +61,7 @@ extern uint32_t FLASHMEM_SPIBAUDRATE; #endif #ifndef T55XX_CONFIG_LEN -# define T55XX_CONFIG_LEN sizeof( t55xx_config ) +# define T55XX_CONFIG_LEN sizeof( t55xx_configurations_t ) #endif #ifndef T55XX_CONFIG_OFFSET From f433e26e3b3cc69d7a4708c323572f3eef4b838d Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 27 Jul 2019 23:44:23 +0200 Subject: [PATCH 0170/1854] Add: 'hf mfu info' - now does orinality check against ECC. (@pwpivi) Adapted to prefered codestyle and added references. --- CHANGELOG.md | 7 +- client/cmdhffido.c | 24 ++--- client/cmdhfmfu.c | 160 +++++++++++++++++++--------------- client/crypto/libpcrypto.c | 132 ++++++++++++++++++++-------- client/crypto/libpcrypto.h | 10 ++- client/fido/fidocore.c | 8 +- common/mbedtls/check_config.h | 1 + common/mbedtls/config.h | 1 + common/mbedtls/ecdsa.c | 2 +- common/mbedtls/ecdsa.h | 2 + common/mbedtls/ecp.c | 6 +- common/mbedtls/ecp.h | 1 + common/mbedtls/ecp_curves.c | 41 +++++++++ 13 files changed, 264 insertions(+), 131 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3857b2a3d..b38c4eae9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Add ECC support / check for NID_secp128r1 (@pwpiwi) - Add some more default keys (ollibolli) - Fix T55x7 Downlink timings backward compatible (@mwalker33) - Add proper Makefile halting when using incompatible STANDALONE and PLATFORM vars (@doegox) @@ -153,7 +154,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Change `lf indala demod` - refactoring (@iceman1001) - Change - handling fault bit markers (7) and partial nibbles in hex printing (@doegox) - Change - printing of fault bit markers (7) using a dot (@doegox) - - Change `sc upgrade` - firmware file integrity check (@piwi) + - Change `sc upgrade` - firmware file integrity check (@pwpiwi) - Fix `data rawdemod am` - last bit was missing (@doegox) - Fix `hf 15 dump f` - also selects tag first (@iceman1001) - Fix `hf iclass clone` - missing fileclose (@iceman1001) @@ -161,8 +162,8 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Change `lf hitag sim` - loads bin/eml/json (@iceman1001) - Change `lf hitag reader 21` - saves in bin/eml/json (@iceman1001) - Change `lf hitag` - refactoring (@iceman1001) - - Change `lf hitag` - refactoring (@piwi) - - Fix `lf hitag` - generic fix for missing clock init (@piwi) + - Change `lf hitag` - refactoring (@pwpiwi) + - Fix `lf hitag` - generic fix for missing clock init (@pwpiwi) - Fix fsk sim operations on deviceside - avoid division by zero (@doegox) - Fix `hf mf fchk` - condition always false (@doegox) - Fix `lf t55xx recoverpw` - shift as u32 (@doegox) diff --git a/client/cmdhffido.c b/client/cmdhffido.c index 39b080dca..f7db54b00 100644 --- a/client/cmdhffido.c +++ b/client/cmdhffido.c @@ -209,7 +209,7 @@ static int CmdHFFidoRegister(const char *cmd) { if (paramsPlain) { memset(cdata, 0x00, 32); CLIGetStrWithReturn(6, cdata, &chlen); - if (chlen > 16) { + if (chlen && chlen > 16) { PrintAndLogEx(ERR, "ERROR: challenge parameter length in ASCII mode must be less than 16 chars instead of: %d", chlen); return 1; } @@ -227,7 +227,7 @@ static int CmdHFFidoRegister(const char *cmd) { if (paramsPlain) { memset(adata, 0x00, 32); CLIGetStrWithReturn(7, adata, &applen); - if (applen > 16) { + if (applen && applen > 16) { PrintAndLogEx(ERR, "ERROR: application parameter length in ASCII mode must be less than 16 chars instead of: %d", applen); return 1; } @@ -346,15 +346,15 @@ static int CmdHFFidoRegister(const char *cmd) { &buf[1], 65, // user public key NULL, 0); //PrintAndLogEx(NORMAL, "--xbuf(%d)[%d]: %s", res, xbuflen, sprint_hex(xbuf, xbuflen)); - res = ecdsa_signature_verify(public_key, xbuf, xbuflen, &buf[hashp], len - hashp); + res = ecdsa_signature_verify(MBEDTLS_ECP_DP_SECP256R1, public_key, xbuf, xbuflen, &buf[hashp], len - hashp, true); if (res) { - if (res == -0x4e00) { - PrintAndLogEx(WARNING, "Signature is NOT VALID."); + if (res == MBEDTLS_ERR_ECP_VERIFY_FAILED) { + PrintAndLogEx(WARNING, "Signature is" _RED_("NOT VALID") ); } else { PrintAndLogEx(WARNING, "Other signature check error: %x %s", (res < 0) ? -res : res, ecdsa_get_error(res)); } } else { - PrintAndLogEx(SUCCESS, "Signature is OK."); + PrintAndLogEx(SUCCESS, "Signature is" _GREEN_("OK")); } } else { @@ -473,7 +473,7 @@ static int CmdHFFidoAuthenticate(const char *cmd) { if (paramsPlain) { memset(hdata, 0x00, 32); CLIGetStrWithReturn(9, hdata, &hdatalen); - if (hdatalen > 16) { + if (hdatalen && hdatalen > 16) { PrintAndLogEx(ERR, "ERROR: challenge parameter length in ASCII mode must be less than 16 chars instead of: %d", hdatalen); return 1; } @@ -490,7 +490,7 @@ static int CmdHFFidoAuthenticate(const char *cmd) { if (paramsPlain) { memset(hdata, 0x00, 32); CLIGetStrWithReturn(11, hdata, &hdatalen); - if (hdatalen > 16) { + if (hdatalen && hdatalen > 16) { PrintAndLogEx(ERR, "ERROR: application parameter length in ASCII mode must be less than 16 chars instead of: %d", hdatalen); return 1; } @@ -572,15 +572,15 @@ static int CmdHFFidoAuthenticate(const char *cmd) { data, 32, // challenge parameter NULL, 0); //PrintAndLogEx(NORMAL, "--xbuf(%d)[%d]: %s", res, xbuflen, sprint_hex(xbuf, xbuflen)); - res = ecdsa_signature_verify(public_key, xbuf, xbuflen, &buf[5], len - 5); + res = ecdsa_signature_verify(MBEDTLS_ECP_DP_SECP256R1, public_key, xbuf, xbuflen, &buf[5], len - 5, true); if (res) { - if (res == -0x4e00) { - PrintAndLogEx(WARNING, "Signature is NOT VALID."); + if (res == MBEDTLS_ERR_ECP_VERIFY_FAILED) { + PrintAndLogEx(WARNING, "Signature is" _RED_("NOT VALID.") ); } else { PrintAndLogEx(WARNING, "Other signature check error: %x %s", (res < 0) ? -res : res, ecdsa_get_error(res)); } } else { - PrintAndLogEx(SUCCESS, "Signature is OK."); + PrintAndLogEx(SUCCESS, "Signature is" _GREEN_("OK") ); } } else { PrintAndLogEx(WARNING, "No public key provided. can't check signature."); diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index df760f187..e2f3565e3 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -42,7 +42,7 @@ static int usage_hf_mfu_info(void) { PrintAndLogEx(NORMAL, " hf mfu info"); PrintAndLogEx(NORMAL, " hf mfu info k 00112233445566778899AABBCCDDEEFF"); PrintAndLogEx(NORMAL, " hf mfu info k AABBCCDD"); - return 0; + return PM3_SUCCESS; } static int usage_hf_mfu_dump(void) { @@ -63,7 +63,7 @@ static int usage_hf_mfu_dump(void) { PrintAndLogEx(NORMAL, " hf mfu dump n myfile"); PrintAndLogEx(NORMAL, " hf mfu dump k 00112233445566778899AABBCCDDEEFF"); PrintAndLogEx(NORMAL, " hf mfu dump k AABBCCDD\n"); - return 0; + return PM3_SUCCESS; } static int usage_hf_mfu_restore(void) { @@ -81,7 +81,7 @@ static int usage_hf_mfu_restore(void) { PrintAndLogEx(NORMAL, " hf mfu restore s f myfile"); PrintAndLogEx(NORMAL, " hf mfu restore k AABBCCDD s f myfile\n"); PrintAndLogEx(NORMAL, " hf mfu restore k AABBCCDD s e r f myfile\n"); - return 0; + return PM3_SUCCESS; } static int usage_hf_mfu_rdbl(void) { @@ -96,7 +96,7 @@ static int usage_hf_mfu_rdbl(void) { PrintAndLogEx(NORMAL, " hf mfu rdbl b 0"); PrintAndLogEx(NORMAL, " hf mfu rdbl b 0 k 00112233445566778899AABBCCDDEEFF"); PrintAndLogEx(NORMAL, " hf mfu rdbl b 0 k AABBCCDD\n"); - return 0; + return PM3_SUCCESS; } static int usage_hf_mfu_wrbl(void) { @@ -111,7 +111,7 @@ static int usage_hf_mfu_wrbl(void) { PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf mfu wrbl b 0 d 01234567"); PrintAndLogEx(NORMAL, " hf mfu wrbl b 0 d 01234567 k AABBCCDD\n"); - return 0; + return PM3_SUCCESS; } static int usage_hf_mfu_eload(void) { @@ -126,7 +126,7 @@ static int usage_hf_mfu_eload(void) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, " sample: hf mfu eload u filename"); PrintAndLogEx(NORMAL, " hf mfu eload u filename 57"); - return 0; + return PM3_SUCCESS; } static int usage_hf_mfu_sim(void) { @@ -141,8 +141,7 @@ static int usage_hf_mfu_sim(void) { PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf mfu sim t 7"); PrintAndLogEx(NORMAL, " hf mfu sim t 7 u 1122344556677\n"); - - return 0; + return PM3_SUCCESS; } static int usage_hf_mfu_ucauth(void) { @@ -157,7 +156,7 @@ static int usage_hf_mfu_ucauth(void) { PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf mfu cauth k"); PrintAndLogEx(NORMAL, " hf mfu cauth k 3"); - return 0; + return PM3_SUCCESS; } static int usage_hf_mfu_ucsetpwd(void) { @@ -167,7 +166,7 @@ static int usage_hf_mfu_ucsetpwd(void) { PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf mfu setpwd 000102030405060708090a0b0c0d0e0f"); PrintAndLogEx(NORMAL, ""); - return 0; + return PM3_SUCCESS; } static int usage_hf_mfu_ucsetuid(void) { @@ -178,7 +177,7 @@ static int usage_hf_mfu_ucsetuid(void) { PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf mfu setuid 11223344556677"); PrintAndLogEx(NORMAL, ""); - return 0; + return PM3_SUCCESS; } static int usage_hf_mfu_gendiverse(void) { @@ -191,7 +190,7 @@ static int usage_hf_mfu_gendiverse(void) { PrintAndLogEx(NORMAL, " hf mfu gen r"); PrintAndLogEx(NORMAL, " hf mfu gen 11223344"); PrintAndLogEx(NORMAL, ""); - return 0; + return PM3_SUCCESS; } static int usage_hf_mfu_pwdgen(void) { @@ -206,17 +205,9 @@ static int usage_hf_mfu_pwdgen(void) { PrintAndLogEx(NORMAL, " hf mfu pwdgen 11223344556677"); PrintAndLogEx(NORMAL, " hf mfu pwdgen t"); PrintAndLogEx(NORMAL, ""); - return 0; + return PM3_SUCCESS; } -#define PUBLIC_ECDA_KEYLEN 33 -uint8_t public_ecda_key[PUBLIC_ECDA_KEYLEN] = { - 0x04, 0x49, 0x4e, 0x1a, 0x38, 0x6d, 0x3d, 0x3c, - 0xfe, 0x3d, 0xc1, 0x0e, 0x5d, 0xe6, 0x8a, 0x49, - 0x9b, 0x1c, 0x20, 0x2d, 0xb5, 0xb1, 0x32, 0x39, - 0x3e, 0x89, 0xed, 0x19, 0xfe, 0x5b, 0xe8, 0xbc, - 0x61 -}; #define KEYS_3DES_COUNT 7 uint8_t default_3des_keys[KEYS_3DES_COUNT][16] = { @@ -234,6 +225,27 @@ uint8_t default_pwd_pack[KEYS_PWD_COUNT][4] = { {0xFF, 0xFF, 0xFF, 0xFF}, // PACK 0x00,0x00 -- factory default }; +#define PUBLIC_ECDA_KEYLEN 33 + +// known public keys for the originality check (source: https://github.com/alexbatalov/node-nxp-originality-verifier) +// ref: AN11350 NTAG 21x Originality Signature Validation +// ref: AN11341 MIFARE Ultralight EV1 Originality Signature Validation +uint8_t public_keys[2][PUBLIC_ECDA_KEYLEN] = { + // UL, NTAG21x and NDEF + { 0x04,0x49,0x4e,0x1a,0x38,0x6d,0x3d,0x3c, + 0xfe,0x3d,0xc1,0x0e,0x5d,0xe6,0x8a,0x49, + 0x9b,0x1c,0x20,0x2d,0xb5,0xb1,0x32,0x39, + 0x3e,0x89,0xed,0x19,0xfe,0x5b,0xe8,0xbc,0x61 + }, + // UL EV1 + { 0x04,0x90,0x93,0x3b,0xdc,0xd6,0xe9,0x9b, + 0x4e,0x25,0x5e,0x3d,0xa5,0x53,0x89,0xa8, + 0x27,0x56,0x4e,0x11,0x71,0x8e,0x01,0x72, + 0x92,0xfa,0xf2,0x32,0x26,0xa9,0x66,0x14,0xb8 + } +}; + + #define MAX_UL_TYPES 22 uint32_t UL_TYPES_ARRAY[MAX_UL_TYPES] = { UNKNOWN, UL, UL_C, UL_EV1_48, UL_EV1_128, NTAG, @@ -555,20 +567,20 @@ static int ul_auth_select(iso14a_card_select_t *card, TagTypeUL_t tagtype, bool //will select card automatically and close connection on error if (!ulc_authentication(authkey, false)) { PrintAndLogEx(WARNING, "Authentication Failed UL-C"); - return 0; + return PM3_ESOFT; } } else { - if (!ul_select(card)) return 0; + if (!ul_select(card)) return PM3_ESOFT; if (hasAuthKey) { if (ulev1_requestAuthentication(authkey, pack, packSize) == -1) { DropField(); PrintAndLogEx(WARNING, "Authentication Failed UL-EV1/NTAG"); - return 0; + return PM3_ESOFT; } } } - return 1; + return PM3_SUCCESS; } static int ulev1_getVersion(uint8_t *response, uint16_t responseLength) { @@ -642,25 +654,25 @@ static int ul_print_default(uint8_t *data) { if (uid[0] == 0x05 && ((uid[1] & 0xf0) >> 4) == 2) { // is infineon and 66RxxP uint8_t chip = (data[8] & 0xC7); // 11000111 mask, bit 3,4,5 RFU switch (chip) { - case 0xc2: + case 0xC2: PrintAndLogEx(NORMAL, " IC type : SLE 66R04P 770 Bytes"); break; //77 pages - case 0xc4: + case 0xC4: PrintAndLogEx(NORMAL, " IC type : SLE 66R16P 2560 Bytes"); break; //256 pages - case 0xc6: + case 0xC6: PrintAndLogEx(NORMAL, " IC type : SLE 66R32P 5120 Bytes"); break; //512 pages /2 sectors } } // CT (cascade tag byte) 0x88 xor SN0 xor SN1 xor SN2 - int crc0 = 0x88 ^ data[0] ^ data[1] ^ data[2]; + int crc0 = 0x88 ^ uid[0] ^ uid[1] ^ uid[2]; if (data[3] == crc0) PrintAndLogEx(NORMAL, " BCC0 : %02X, Ok", data[3]); else PrintAndLogEx(NORMAL, " BCC0 : %02X, crc should be %02X", data[3], crc0); - int crc1 = data[4] ^ data[5] ^ data[6] ^ data[7]; + int crc1 = uid[3] ^ uid[4] ^ uid[5] ^ uid[6]; if (data[8] == crc1) PrintAndLogEx(NORMAL, " BCC1 : %02X, Ok", data[8]); else @@ -678,13 +690,13 @@ static int ul_print_default(uint8_t *data) { sprint_bin(data + 12, 4) ); - return 0; + return PM3_SUCCESS; } static int ndef_print_CC(uint8_t *data) { // no NDEF message if (data[0] != 0xE1) - return -1; + return PM3_ESOFT; //NFC Forum Type 1,2,3,4 // @@ -763,7 +775,7 @@ static int ndef_print_CC(uint8_t *data) { PrintAndLogEx(NORMAL, " x - %02X : %s lock block", lb, (lb) ? "support" : "don\'t support"); PrintAndLogEx(NORMAL, " xx - %02X : RFU (%s)", mlrule, (mlrule == 0) ? _GREEN_("OK") : _RED_("Fail")); PrintAndLogEx(NORMAL, " x - %02X : IC %s multiple block reads", mbread, (mbread) ? "support" : "don\'t support"); - return 0; + return PM3_SUCCESS; } int ul_print_type(uint32_t tagtype, uint8_t spaces) { @@ -823,7 +835,7 @@ int ul_print_type(uint32_t tagtype, uint8_t spaces) { PrintAndLogEx(NORMAL, "%sTYPE : FUDAN Ultralight Compatible (or other compatible) %s", spacer, (tagtype & MAGIC) ? "" : ""); else PrintAndLogEx(NORMAL, "%sTYPE : Unknown %06x", spacer, tagtype); - return 0; + return PM3_SUCCESS; } static int ulc_print_3deskey(uint8_t *data) { @@ -832,7 +844,7 @@ static int ulc_print_3deskey(uint8_t *data) { PrintAndLogEx(NORMAL, " deskey2 [46/0x2E] : %s [s]", sprint_hex(data + 8, 4), sprint_ascii(data + 8, 4)); PrintAndLogEx(NORMAL, " deskey2 [47/0x2F] : %s [s]", sprint_hex(data + 12, 4), sprint_ascii(data + 12, 4)); PrintAndLogEx(NORMAL, "\n 3des key : %s", sprint_hex(SwapEndian64(data, 16, 8), 16)); - return 0; + return PM3_SUCCESS; } static int ulc_print_configuration(uint8_t *data) { @@ -855,7 +867,7 @@ static int ulc_print_configuration(uint8_t *data) { sprint_hex(data + 12, 4), (data[12] & 1) ? "write access restricted" : "read and write access restricted" ); - return 0; + return PM3_SUCCESS; } static int ulev1_print_configuration(uint32_t tagtype, uint8_t *data, uint8_t startPage) { @@ -961,7 +973,7 @@ static int ulev1_print_configuration(uint32_t tagtype, uint8_t *data, uint8_t st PrintAndLogEx(NORMAL, " PWD [%u/0x%02X] : %s- (cannot be read)", startPage + 2, startPage + 2, sprint_hex(data + 8, 4)); PrintAndLogEx(NORMAL, " PACK [%u/0x%02X] : %s - (cannot be read)", startPage + 3, startPage + 3, sprint_hex(data + 12, 2)); PrintAndLogEx(NORMAL, " RFU [%u/0x%02X] : %s- (cannot be read)", startPage + 3, startPage + 3, sprint_hex(data + 14, 2)); - return 0; + return PM3_SUCCESS; } static int ulev1_print_counters() { @@ -980,16 +992,21 @@ static int ulev1_print_counters() { return len; } -static int ulev1_print_signature(uint8_t *data, uint8_t len) { +static int ulev1_print_signature(TagTypeUL_t tagtype, uint8_t *uid, uint8_t *signature, size_t signature_len){ + uint8_t public_key = 0; + if (tagtype == UL_EV1_48 || tagtype == UL_EV1_128) { + public_key = 1; + } + int res = ecdsa_signature_r_s_verify(MBEDTLS_ECP_DP_SECP128R1, public_keys[public_key], uid, 7, signature, signature_len, false); + bool is_valid = (res == 0); + PrintAndLogEx(NORMAL, "\n--- Tag Signature"); - PrintAndLogEx(NORMAL, "IC signature public key name : NXP NTAG21x (2013)"); - PrintAndLogEx(NORMAL, "IC signature public key value : %s", sprint_hex(public_ecda_key, PUBLIC_ECDA_KEYLEN)); - PrintAndLogEx(NORMAL, " Elliptic curve parameters : secp128r1"); - PrintAndLogEx(NORMAL, " Tag ECC Signature : %s", sprint_hex(data, len)); - //to do: verify if signature is valid - // only UID is signed. - //PrintAndLogEx(NORMAL, "IC signature status: %s valid", (iseccvalid() )?"":"not"); - return 0; + PrintAndLogEx(NORMAL, "IC signature public key name : NXP NTAG21x (2013)"); + PrintAndLogEx(NORMAL, "IC signature public key value : %s", sprint_hex(public_keys[public_key], PUBLIC_ECDA_KEYLEN)); + PrintAndLogEx(NORMAL, " Elliptic curve parameters : NID_secp128r1"); + PrintAndLogEx(NORMAL, " TAG IC Signature : %s", sprint_hex(signature, signature_len)); + PrintAndLogEx(NORMAL, "Signature verified %s", (is_valid) ? _GREEN_("successful") : _RED_("failed") ); + return PM3_SUCCESS; } static int ulev1_print_version(uint8_t *data) { @@ -1002,7 +1019,7 @@ static int ulev1_print_version(uint8_t *data) { PrintAndLogEx(NORMAL, " Minor version : %02X", data[5]); PrintAndLogEx(NORMAL, " Size : %s", getUlev1CardSizeStr(data[6])); PrintAndLogEx(NORMAL, " Protocol type : %02X %s", data[7], (data[7] == 0x3) ? "(ISO14443-3 Compliant)" : ""); - return 0; + return PM3_SUCCESS; } /* @@ -1185,6 +1202,8 @@ static int CmdHF14AMfUInfo(const char *Cmd) { uint8_t *key = pwd; uint8_t pack[4] = {0, 0, 0, 0}; int len; + uint8_t uid[7]; + char tempStr[50]; while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { @@ -1217,7 +1236,7 @@ static int CmdHF14AMfUInfo(const char *Cmd) { if (errors) return usage_hf_mfu_info(); TagTypeUL_t tagtype = GetHF14AMfU_Type(); - if (tagtype == UL_ERROR) return -1; + if (tagtype == UL_ERROR) return PM3_ESOFT; PrintAndLogEx(NORMAL, "\n--- Tag Information ---------"); PrintAndLogEx(NORMAL, "-------------------------------------------------------------"); @@ -1226,15 +1245,17 @@ static int CmdHF14AMfUInfo(const char *Cmd) { // Swap endianness if (swapEndian && hasAuthKey) authkeyptr = SwapEndian64(authenticationkey, dataLen, (dataLen == 16) ? 8 : 4); - if (!ul_auth_select(&card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack))) return -1; + if (ul_auth_select(&card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack)) == PM3_ESOFT) return PM3_ESOFT; // read pages 0,1,2,3 (should read 4pages) status = ul_read(0, data, sizeof(data)); if (status == -1) { DropField(); PrintAndLogEx(ERR, "Error: tag didn't answer to READ"); - return status; + return PM3_ESOFT; } else if (status == 16) { + memcpy(uid, data, 3); + memcpy(uid + 3, data + 4, 4); ul_print_default(data); ndef_print_CC(data + 12); } else { @@ -1250,7 +1271,7 @@ static int CmdHF14AMfUInfo(const char *Cmd) { if (status == -1) { PrintAndLogEx(ERR, "Error: tag didn't answer to READ UL-C"); DropField(); - return status; + return PM3_ESOFT; } if (status == 16) ulc_print_configuration(ulc_conf); @@ -1264,14 +1285,14 @@ static int CmdHF14AMfUInfo(const char *Cmd) { if (status == -1) { DropField(); PrintAndLogEx(ERR, "Error: tag didn't answer to READ magic"); - return status; + return PM3_ESOFT; } if (status == 16) ulc_print_3deskey(ulc_deskey); } else { DropField(); // if we called info with key, just return - if (hasAuthKey) return 1; + if (hasAuthKey) return PM3_SUCCESS; // also try to diversify default keys.. look into CmdHF14AMfGenDiverseKeys PrintAndLogEx(INFO, "Trying some default 3des keys"); @@ -1282,10 +1303,10 @@ static int CmdHF14AMfUInfo(const char *Cmd) { uint8_t keySwap[16]; memcpy(keySwap, SwapEndian64(key, 16, 8), 16); ulc_print_3deskey(keySwap); - return 1; + return PM3_SUCCESS; } } - return 1; + return PM3_SUCCESS; } } @@ -1295,7 +1316,7 @@ static int CmdHF14AMfUInfo(const char *Cmd) { if ((tagtype & (UL_EV1_48 | UL_EV1_128 | UL_EV1))) { if (ulev1_print_counters() != 3) { // failed - re-select - if (!ul_auth_select(&card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack))) return -1; + if (ul_auth_select(&card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack)) == PM3_ESOFT) return PM3_ESOFT; } } @@ -1308,12 +1329,13 @@ static int CmdHF14AMfUInfo(const char *Cmd) { if (status == -1) { PrintAndLogEx(ERR, "Error: tag didn't answer to READ SIGNATURE"); DropField(); - return status; + return PM3_ESOFT; } - if (status == 32) ulev1_print_signature(ulev1_signature, sizeof(ulev1_signature)); - else { + if (status == 32) { + ulev1_print_signature(tagtype, uid, ulev1_signature, sizeof(ulev1_signature)); + } else { // re-select - if (!ul_auth_select(&card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack))) return -1; + if (ul_auth_select(&card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack)) == PM3_ESOFT) return PM3_ESOFT; } } @@ -1324,12 +1346,12 @@ static int CmdHF14AMfUInfo(const char *Cmd) { if (status == -1) { PrintAndLogEx(ERR, "Error: tag didn't answer to GETVERSION"); DropField(); - return status; + return PM3_ESOFT; } else if (status == 10) { ulev1_print_version(version); } else { locked = true; - if (!ul_auth_select(&card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack))) return -1; + if (ul_auth_select(&card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack)) == PM3_ESOFT) return PM3_ESOFT; } uint8_t startconfigblock = 0; @@ -1348,7 +1370,7 @@ static int CmdHF14AMfUInfo(const char *Cmd) { if (status == -1) { PrintAndLogEx(ERR, "Error: tag didn't answer to READ EV1"); DropField(); - return status; + return PM3_ESOFT; } else if (status == 16) { // save AUTHENTICATION LIMITS for later: authlim = (ulev1_conf[4] & 0x07); @@ -1375,7 +1397,7 @@ static int CmdHF14AMfUInfo(const char *Cmd) { goto out; } - if (!ul_auth_select(&card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack))) return -1; + if (ul_auth_select(&card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack)) == PM3_ESOFT) return PM3_ESOFT; // test pwd gen B num_to_bytes(ul_ev1_pwdgenB(card.uid), 4, key); @@ -1385,7 +1407,7 @@ static int CmdHF14AMfUInfo(const char *Cmd) { goto out; } - if (!ul_auth_select(&card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack))) return -1; + if (ul_auth_select(&card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack)) == PM3_ESOFT) return PM3_ESOFT; // test pwd gen C num_to_bytes(ul_ev1_pwdgenC(card.uid), 4, key); @@ -1395,7 +1417,7 @@ static int CmdHF14AMfUInfo(const char *Cmd) { goto out; } - if (!ul_auth_select(&card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack))) return -1; + if (ul_auth_select(&card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack)) == PM3_ESOFT) return PM3_ESOFT; // test pwd gen D num_to_bytes(ul_ev1_pwdgenD(card.uid), 4, key); @@ -1405,7 +1427,7 @@ static int CmdHF14AMfUInfo(const char *Cmd) { goto out; } - if (!ul_auth_select(&card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack))) return -1; + if (ul_auth_select(&card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack)) == PM3_ESOFT) return PM3_ESOFT; for (uint8_t i = 0; i < KEYS_PWD_COUNT; ++i) { key = default_pwd_pack[i]; @@ -1414,7 +1436,7 @@ static int CmdHF14AMfUInfo(const char *Cmd) { PrintAndLogEx(SUCCESS, "Found a default password: %s || Pack: %02X %02X", sprint_hex(key, 4), pack[0], pack[1]); break; } else { - if (!ul_auth_select(&card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack))) return -1; + if (ul_auth_select(&card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack)) == PM3_ESOFT) return PM3_ESOFT; } } if (len < 1) PrintAndLogEx(WARNING, "password not known"); @@ -1424,7 +1446,7 @@ out: DropField(); if (locked) PrintAndLogEx(FAILED, "\nTag appears to be locked, try using the key to get more info"); PrintAndLogEx(NORMAL, ""); - return 1; + return PM3_SUCCESS; } // diff --git a/client/crypto/libpcrypto.c b/client/crypto/libpcrypto.c index 775080c42..3bdbb46ae 100644 --- a/client/crypto/libpcrypto.c +++ b/client/crypto/libpcrypto.c @@ -121,14 +121,14 @@ int sha512hash(uint8_t *input, int length, uint8_t *hash) { return 0; } -static int ecdsa_init_str(mbedtls_ecdsa_context *ctx, const char *key_d, const char *key_x, const char *key_y) { +static int ecdsa_init_str(mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id curveid, const char *key_d, const char *key_x, const char *key_y) { if (!ctx) return 1; int res; mbedtls_ecdsa_init(ctx); - res = mbedtls_ecp_group_load(&ctx->grp, MBEDTLS_ECP_DP_SECP256R1); // secp256r1 + res = mbedtls_ecp_group_load(&ctx->grp, curveid); if (res) return res; @@ -147,25 +147,26 @@ static int ecdsa_init_str(mbedtls_ecdsa_context *ctx, const char *key_d, const c return 0; } -static int ecdsa_init(mbedtls_ecdsa_context *ctx, uint8_t *key_d, uint8_t *key_xy) { +static int ecdsa_init(mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id curveid, uint8_t *key_d, uint8_t *key_xy) { if (!ctx) return 1; int res; mbedtls_ecdsa_init(ctx); - res = mbedtls_ecp_group_load(&ctx->grp, MBEDTLS_ECP_DP_SECP256R1); // secp256r1 + res = mbedtls_ecp_group_load(&ctx->grp, curveid); if (res) return res; + size_t keylen = (ctx->grp.nbits + 7 ) / 8; if (key_d) { - res = mbedtls_mpi_read_binary(&ctx->d, key_d, 32); + res = mbedtls_mpi_read_binary(&ctx->d, key_d, keylen); if (res) return res; } if (key_xy) { - res = mbedtls_ecp_point_read_binary(&ctx->grp, &ctx->Q, key_xy, 32 * 2 + 1); + res = mbedtls_ecp_point_read_binary(&ctx->grp, &ctx->Q, key_xy, keylen * 2 + 1); if (res) return res; } @@ -173,10 +174,10 @@ static int ecdsa_init(mbedtls_ecdsa_context *ctx, uint8_t *key_d, uint8_t *key_x return 0; } -int ecdsa_key_create(uint8_t *key_d, uint8_t *key_xy) { +int ecdsa_key_create(mbedtls_ecp_group_id curveid, uint8_t *key_d, uint8_t *key_xy) { int res; mbedtls_ecdsa_context ctx; - ecdsa_init(&ctx, NULL, NULL); + ecdsa_init(&ctx, curveid, NULL, NULL); mbedtls_entropy_context entropy; @@ -190,25 +191,26 @@ int ecdsa_key_create(uint8_t *key_d, uint8_t *key_xy) { if (res) goto exit; - res = mbedtls_ecdsa_genkey(&ctx, MBEDTLS_ECP_DP_SECP256R1, mbedtls_ctr_drbg_random, &ctr_drbg); + res = mbedtls_ecdsa_genkey(&ctx, curveid, mbedtls_ctr_drbg_random, &ctr_drbg); if (res) goto exit; - res = mbedtls_mpi_write_binary(&ctx.d, key_d, 32); + size_t keylen = (ctx.grp.nbits + 7) / 8; + res = mbedtls_mpi_write_binary(&ctx.d, key_d, keylen); if (res) goto exit; - size_t keylen = 0; + size_t public_keylen = 0; uint8_t public_key[200] = {0}; - res = mbedtls_ecp_point_write_binary(&ctx.grp, &ctx.Q, MBEDTLS_ECP_PF_UNCOMPRESSED, &keylen, public_key, sizeof(public_key)); + res = mbedtls_ecp_point_write_binary(&ctx.grp, &ctx.Q, MBEDTLS_ECP_PF_UNCOMPRESSED, &public_keylen, public_key, sizeof(public_key)); if (res) goto exit; - if (keylen != 65) { // 0x04 + if (public_keylen != 1 + 2 * keylen) { // 0x04 res = 1; goto exit; } - memcpy(key_xy, public_key, 65); + memcpy(key_xy, public_key, public_keylen); exit: mbedtls_entropy_free(&entropy); @@ -224,32 +226,36 @@ char *ecdsa_get_error(int ret) { return retstr; } -int ecdsa_public_key_from_pk(mbedtls_pk_context *pk, uint8_t *key, size_t keylen) { +int ecdsa_public_key_from_pk(mbedtls_pk_context *pk, mbedtls_ecp_group_id curveid, uint8_t *key, size_t keylen) { int res = 0; size_t realkeylen = 0; - if (keylen < 65) - return 1; mbedtls_ecdsa_context ctx; mbedtls_ecdsa_init(&ctx); - res = mbedtls_ecp_group_load(&ctx.grp, MBEDTLS_ECP_DP_SECP256R1); // secp256r1 + res = mbedtls_ecp_group_load(&ctx.grp, curveid); if (res) goto exit; + size_t private_keylen = (ctx.grp.nbits + 7) / 8; + if (keylen < 1 + 2 * private_keylen) { + res = 1; + goto exit; + } + res = mbedtls_ecdsa_from_keypair(&ctx, mbedtls_pk_ec(*pk)); if (res) goto exit; res = mbedtls_ecp_point_write_binary(&ctx.grp, &ctx.Q, MBEDTLS_ECP_PF_UNCOMPRESSED, &realkeylen, key, keylen); - if (realkeylen != 65) + if (realkeylen != 1 + 2 * private_keylen) res = 2; exit: mbedtls_ecdsa_free(&ctx); return res; } -int ecdsa_signature_create(uint8_t *key_d, uint8_t *key_xy, uint8_t *input, int length, uint8_t *signature, size_t *signaturelen) { +int ecdsa_signature_create(mbedtls_ecp_group_id curveid, uint8_t *key_d, uint8_t *key_xy, uint8_t *input, int length, uint8_t *signature, size_t *signaturelen, bool hash) { int res; *signaturelen = 0; @@ -270,8 +276,18 @@ int ecdsa_signature_create(uint8_t *key_d, uint8_t *key_xy, uint8_t *input, int goto exit; mbedtls_ecdsa_context ctx; - ecdsa_init(&ctx, key_d, key_xy); - res = mbedtls_ecdsa_write_signature(&ctx, MBEDTLS_MD_SHA256, shahash, sizeof(shahash), signature, signaturelen, mbedtls_ctr_drbg_random, &ctr_drbg); + ecdsa_init(&ctx, curveid, key_d, key_xy); + res = mbedtls_ecdsa_write_signature( + &ctx, + MBEDTLS_MD_SHA256, + hash ? shahash : input, + hash ? sizeof(shahash) : length, + signature, + signaturelen, + mbedtls_ctr_drbg_random, + &ctr_drbg + ); + exit: mbedtls_ctr_drbg_free(&ctr_drbg); @@ -279,7 +295,7 @@ exit: return res; } -static int ecdsa_signature_create_test(const char *key_d, const char *key_x, const char *key_y, const char *random, uint8_t *input, int length, uint8_t *signature, size_t *signaturelen) { +static int ecdsa_signature_create_test(mbedtls_ecp_group_id curveid, const char *key_d, const char *key_x, const char *key_y, const char *random, uint8_t *input, int length, uint8_t *signature, size_t *signaturelen) { int res; *signaturelen = 0; @@ -292,14 +308,14 @@ static int ecdsa_signature_create_test(const char *key_d, const char *key_x, con param_gethex_to_eol(random, 0, fixed_rand_value, sizeof(fixed_rand_value), &rndlen); mbedtls_ecdsa_context ctx; - ecdsa_init_str(&ctx, key_d, key_x, key_y); + ecdsa_init_str(&ctx, curveid, key_d, key_x, key_y); res = mbedtls_ecdsa_write_signature(&ctx, MBEDTLS_MD_SHA256, shahash, sizeof(shahash), signature, signaturelen, fixed_rand, NULL); mbedtls_ecdsa_free(&ctx); return res; } -static int ecdsa_signature_verify_keystr(const char *key_x, const char *key_y, uint8_t *input, int length, uint8_t *signature, size_t signaturelen) { +static int ecdsa_signature_verify_keystr(mbedtls_ecp_group_id curveid, const char *key_x, const char *key_y, uint8_t *input, int length, uint8_t *signature, size_t signaturelen, bool hash) { int res; uint8_t shahash[32] = {0}; res = sha256hash(input, length, shahash); @@ -307,28 +323,69 @@ static int ecdsa_signature_verify_keystr(const char *key_x, const char *key_y, u return res; mbedtls_ecdsa_context ctx; - ecdsa_init_str(&ctx, NULL, key_x, key_y); - res = mbedtls_ecdsa_read_signature(&ctx, shahash, sizeof(shahash), signature, signaturelen); + ecdsa_init_str(&ctx, curveid, NULL, key_x, key_y); + res = mbedtls_ecdsa_read_signature( + &ctx, + hash ? shahash : input, + hash ? sizeof(shahash) : length, + signature, + signaturelen + ); mbedtls_ecdsa_free(&ctx); return res; } -int ecdsa_signature_verify(uint8_t *key_xy, uint8_t *input, int length, uint8_t *signature, size_t signaturelen) { +int ecdsa_signature_verify(mbedtls_ecp_group_id curveid, uint8_t *key_xy, uint8_t *input, int length, uint8_t *signature, size_t signaturelen, bool hash) { int res; uint8_t shahash[32] = {0}; + if (hash) { res = sha256hash(input, length, shahash); if (res) return res; + } mbedtls_ecdsa_context ctx; - ecdsa_init(&ctx, NULL, key_xy); - res = mbedtls_ecdsa_read_signature(&ctx, shahash, sizeof(shahash), signature, signaturelen); + res = ecdsa_init(&ctx, curveid, NULL, key_xy); + res = mbedtls_ecdsa_read_signature( + &ctx, + hash ? shahash : input, + hash ? sizeof(shahash) : length, + signature, + signaturelen + ); mbedtls_ecdsa_free(&ctx); return res; } + +int ecdsa_signature_r_s_verify(mbedtls_ecp_group_id curveid, uint8_t *key_xy, uint8_t *input, int length, uint8_t *r_s, size_t r_s_len, bool hash) { + int res; + uint8_t signature[MBEDTLS_ECDSA_MAX_LEN]; + size_t signature_len; + + // convert r & s to ASN.1 signature + mbedtls_mpi r, s; + mbedtls_mpi_init(&r); + mbedtls_mpi_init(&s); + mbedtls_mpi_read_binary(&r, r_s, r_s_len/2); + mbedtls_mpi_read_binary(&s, r_s + r_s_len/2, r_s_len/2); + + res = ecdsa_signature_to_asn1(&r, &s, signature, &signature_len); + if (res < 0) { + return res; + } + + res = ecdsa_signature_verify(curveid, key_xy, input, length, signature, signature_len, hash); + + mbedtls_mpi_free(&r); + mbedtls_mpi_free(&s); + + return res; +} + + #define T_PRIVATE_KEY "C477F9F65C22CCE20657FAA5B2D1D8122336F851A508A1ED04E479C34985BF96" #define T_Q_X "B7E08AFDFE94BAD3F1DC8C734798BA1C62B3A0AD1E9EA2A38201CD0889BC7A19" #define T_Q_Y "3603F747959DBF7A4BB226E41928729063ADC7AE43529E61B563BBC606CC5E09" @@ -339,6 +396,7 @@ int ecdsa_signature_verify(uint8_t *key_xy, uint8_t *input, int length, uint8_t int ecdsa_nist_test(bool verbose) { int res; uint8_t input[] = "Example of ECDSA with P-256"; + mbedtls_ecp_group_id curveid = MBEDTLS_ECP_DP_SECP256R1; int length = strlen((char *)input); uint8_t signature[300] = {0}; size_t siglen = 0; @@ -347,7 +405,7 @@ int ecdsa_nist_test(bool verbose) { if (verbose) printf(" ECDSA NIST test: "); // make signature - res = ecdsa_signature_create_test(T_PRIVATE_KEY, T_Q_X, T_Q_Y, T_K, input, length, signature, &siglen); + res = ecdsa_signature_create_test(curveid, T_PRIVATE_KEY, T_Q_X, T_Q_Y, T_K, input, length, signature, &siglen); // printf("res: %x signature[%x]: %s\n", (res<0)?-res:res, siglen, sprint_hex(signature, siglen)); if (res) goto exit; @@ -371,13 +429,13 @@ int ecdsa_nist_test(bool verbose) { } // verify signature - res = ecdsa_signature_verify_keystr(T_Q_X, T_Q_Y, input, length, signature, siglen); + res = ecdsa_signature_verify_keystr(curveid, T_Q_X, T_Q_Y, input, length, signature, siglen, true); if (res) goto exit; // verify wrong signature input[0] ^= 0xFF; - res = ecdsa_signature_verify_keystr(T_Q_X, T_Q_Y, input, length, signature, siglen); + res = ecdsa_signature_verify_keystr(curveid, T_Q_X, T_Q_Y, input, length, signature, siglen, true); if (!res) { res = 1; goto exit; @@ -394,20 +452,20 @@ int ecdsa_nist_test(bool verbose) { memset(signature, 0x00, sizeof(signature)); siglen = 0; - res = ecdsa_key_create(key_d, key_xy); + res = ecdsa_key_create(curveid, key_d, key_xy); if (res) goto exit; - res = ecdsa_signature_create(key_d, key_xy, input, length, signature, &siglen); + res = ecdsa_signature_create(curveid, key_d, key_xy, input, length, signature, &siglen, true); if (res) goto exit; - res = ecdsa_signature_verify(key_xy, input, length, signature, siglen); + res = ecdsa_signature_verify(curveid, key_xy, input, length, signature, siglen, true); if (res) goto exit; input[0] ^= 0xFF; - res = ecdsa_signature_verify(key_xy, input, length, signature, siglen); + res = ecdsa_signature_verify(curveid, key_xy, input, length, signature, siglen, true); if (!res) goto exit; diff --git a/client/crypto/libpcrypto.h b/client/crypto/libpcrypto.h index 38d37b66a..90c389636 100644 --- a/client/crypto/libpcrypto.h +++ b/client/crypto/libpcrypto.h @@ -24,10 +24,12 @@ int aes_cmac8(uint8_t *iv, uint8_t *key, uint8_t *input, uint8_t *mac, int lengt int sha256hash(uint8_t *input, int length, uint8_t *hash); int sha512hash(uint8_t *input, int length, uint8_t *hash); -int ecdsa_key_create(uint8_t *key_d, uint8_t *key_xy); -int ecdsa_public_key_from_pk(mbedtls_pk_context *pk, uint8_t *key, size_t keylen); -int ecdsa_signature_create(uint8_t *key_d, uint8_t *key_xy, uint8_t *input, int length, uint8_t *signature, size_t *signaturelen); -int ecdsa_signature_verify(uint8_t *key_xy, uint8_t *input, int length, uint8_t *signature, size_t signaturelen); +int ecdsa_key_create(mbedtls_ecp_group_id curveid, uint8_t * key_d, uint8_t *key_xy); +int ecdsa_public_key_from_pk(mbedtls_pk_context *pk, mbedtls_ecp_group_id curveid, uint8_t *key, size_t keylen); +int ecdsa_signature_create(mbedtls_ecp_group_id curveid, uint8_t *key_d, uint8_t *key_xy, uint8_t *input, int length, uint8_t *signature, size_t *signaturelen, bool hash); +int ecdsa_signature_verify(mbedtls_ecp_group_id curveid, uint8_t *key_xy, uint8_t *input, int length, uint8_t *signature, size_t signaturelen, bool hash); +int ecdsa_signature_r_s_verify(mbedtls_ecp_group_id curveid, uint8_t *key_xy, uint8_t *input, int length, uint8_t *r_s, size_t r_s_len, bool hash); + char *ecdsa_get_error(int ret); int ecdsa_nist_test(bool verbose); diff --git a/client/fido/fidocore.c b/client/fido/fidocore.c index c356c3456..ecfefaa79 100644 --- a/client/fido/fidocore.c +++ b/client/fido/fidocore.c @@ -262,7 +262,7 @@ int FIDOCheckDERAndGetKey(uint8_t *der, size_t derLen, bool verbose, uint8_t *pu } // get public key - res = ecdsa_public_key_from_pk(&cert.pk, publicKey, publicKeyMaxLen); + res = ecdsa_public_key_from_pk(&cert.pk, MBEDTLS_ECP_DP_SECP256R1, publicKey, publicKeyMaxLen); if (res) { PrintAndLogEx(ERR, "ERROR: getting public key from certificate 0x%x - %s", (res < 0) ? -res : res, ecdsa_get_error(res)); } else { @@ -381,10 +381,10 @@ static int FIDO2CheckSignature(json_t *root, uint8_t *publickey, uint8_t *sign, clientDataHash, 32, // Hash of the serialized client data. "$.ClientDataHash" from json NULL, 0); //PrintAndLogEx(NORMAL, "--xbuf(%d)[%d]: %s", res, xbuflen, sprint_hex(xbuf, xbuflen)); - res = ecdsa_signature_verify(publickey, xbuf, xbuflen, sign, signLen); + res = ecdsa_signature_verify(MBEDTLS_ECP_DP_SECP256R1, publickey, xbuf, xbuflen, sign, signLen, true); if (res) { - if (res == -0x4e00) { - PrintAndLogEx(WARNING, "Signature is NOT VALID."); + if (res == MBEDTLS_ERR_ECP_VERIFY_FAILED) { + PrintAndLogEx(WARNING, "Signature is " _RED_("NOT VALID") ); } else { PrintAndLogEx(WARNING, "Other signature check error: %x %s", (res < 0) ? -res : res, ecdsa_get_error(res)); } diff --git a/common/mbedtls/check_config.h b/common/mbedtls/check_config.h index a4fa7bdde..b395844d5 100644 --- a/common/mbedtls/check_config.h +++ b/common/mbedtls/check_config.h @@ -115,6 +115,7 @@ #endif #if defined(MBEDTLS_ECP_C) && ( !defined(MBEDTLS_BIGNUM_C) || ( \ + !defined(MBEDTLS_ECP_DP_SECP128R1_ENABLED) && \ !defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) && \ !defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) && \ !defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) && \ diff --git a/common/mbedtls/config.h b/common/mbedtls/config.h index 9f4b19c5e..707c493d7 100644 --- a/common/mbedtls/config.h +++ b/common/mbedtls/config.h @@ -645,6 +645,7 @@ * * Comment macros to disable the curve and functions for it */ +#define MBEDTLS_ECP_DP_SECP128R1_ENABLED #define MBEDTLS_ECP_DP_SECP192R1_ENABLED #define MBEDTLS_ECP_DP_SECP224R1_ENABLED #define MBEDTLS_ECP_DP_SECP256R1_ENABLED diff --git a/common/mbedtls/ecdsa.c b/common/mbedtls/ecdsa.c index 2fac6d875..388466162 100644 --- a/common/mbedtls/ecdsa.c +++ b/common/mbedtls/ecdsa.c @@ -286,7 +286,7 @@ cleanup: /* * Convert a signature (given by context) to ASN.1 */ -static int ecdsa_signature_to_asn1(const mbedtls_mpi *r, const mbedtls_mpi *s, +int ecdsa_signature_to_asn1(const mbedtls_mpi *r, const mbedtls_mpi *s, unsigned char *sig, size_t *slen) { int ret; unsigned char buf[MBEDTLS_ECDSA_MAX_LEN]; diff --git a/common/mbedtls/ecdsa.h b/common/mbedtls/ecdsa.h index 0371e8c36..b3bf1b110 100644 --- a/common/mbedtls/ecdsa.h +++ b/common/mbedtls/ecdsa.h @@ -334,6 +334,8 @@ void mbedtls_ecdsa_init(mbedtls_ecdsa_context *ctx); */ void mbedtls_ecdsa_free(mbedtls_ecdsa_context *ctx); +int ecdsa_signature_to_asn1( const mbedtls_mpi *r, const mbedtls_mpi *s, unsigned char *sig, size_t *slen ); + #ifdef __cplusplus } #endif diff --git a/common/mbedtls/ecp.c b/common/mbedtls/ecp.c index 896801dd7..3a2b48804 100644 --- a/common/mbedtls/ecp.c +++ b/common/mbedtls/ecp.c @@ -84,7 +84,8 @@ static unsigned long add_count, dbl_count, mul_count; #endif -#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) || \ +#if defined(MBEDTLS_ECP_DP_SECP128R1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) || \ defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \ defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \ defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) || \ @@ -157,6 +158,9 @@ static const mbedtls_ecp_curve_info ecp_supported_curves[] = { #endif #if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) { MBEDTLS_ECP_DP_SECP192K1, 18, 192, "secp192k1" }, +#endif +#if defined(MBEDTLS_ECP_DP_SECP128R1_ENABLED) + { MBEDTLS_ECP_DP_SECP128R1, 0xFE00, 128, "secp128r1" }, #endif { MBEDTLS_ECP_DP_NONE, 0, 0, NULL }, }; diff --git a/common/mbedtls/ecp.h b/common/mbedtls/ecp.h index f7ca89493..4c2592a9e 100644 --- a/common/mbedtls/ecp.h +++ b/common/mbedtls/ecp.h @@ -81,6 +81,7 @@ typedef enum { MBEDTLS_ECP_DP_SECP224K1, /*!< Domain parameters for 224-bit "Koblitz" curve. */ MBEDTLS_ECP_DP_SECP256K1, /*!< Domain parameters for 256-bit "Koblitz" curve. */ MBEDTLS_ECP_DP_CURVE448, /*!< Domain parameters for Curve448. */ + MBEDTLS_ECP_DP_SECP128R1, /*!< Domain parameters for the 128-bit curve used for NXP originality check. */ } mbedtls_ecp_group_id; /** diff --git a/common/mbedtls/ecp_curves.c b/common/mbedtls/ecp_curves.c index 2fd9a2daf..dcb79aeba 100644 --- a/common/mbedtls/ecp_curves.c +++ b/common/mbedtls/ecp_curves.c @@ -84,6 +84,42 @@ * to be directly usable in MPIs */ +/* + * Domain parameters for secp128r1 + */ +#if defined(MBEDTLS_ECP_DP_SECP128R1_ENABLED) +static const mbedtls_mpi_uint secp128r1_p[] = { + // 2^128 - 2^97 - 1 // TODO + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF ), +}; +static const mbedtls_mpi_uint secp128r1_a[] = { + // FFFFFFFDFFFFFFFF FFFFFFFFFFFFFFFC + BYTES_TO_T_UINT_8( 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF ), +}; +static const mbedtls_mpi_uint secp128r1_b[] = { + // E87579C11079F43D D824993C2CEE5ED3 + BYTES_TO_T_UINT_8( 0xD3, 0x5E, 0xEE, 0x2C, 0x3C, 0x99, 0x24, 0xD8 ), + BYTES_TO_T_UINT_8( 0x3D, 0xF4, 0x79, 0x10, 0xC1, 0x79, 0x75, 0xE8 ), +}; +static const mbedtls_mpi_uint secp128r1_gx[] = { + // 161FF7528B899B2D 0C28607CA52C5B86 + BYTES_TO_T_UINT_8( 0x86, 0x5B, 0x2C, 0xA5, 0x7C, 0x60, 0x28, 0x0C ), + BYTES_TO_T_UINT_8( 0x2D, 0x9B, 0x89, 0x8B, 0x52, 0xF7, 0x1F, 0x16 ), +}; +static const mbedtls_mpi_uint secp128r1_gy[] = { + // CF5AC8395BAFEB13 C02DA292DDED7A83 + BYTES_TO_T_UINT_8( 0x83, 0x7A, 0xED, 0xDD, 0x92, 0xA2, 0x2D, 0xC0 ), + BYTES_TO_T_UINT_8( 0x13, 0xEB, 0xAF, 0x5B, 0x39, 0xC8, 0x5A, 0xCF ), +}; +static const mbedtls_mpi_uint secp128r1_n[] = { + // FFFFFFFE00000000 75A30D1B9038A115 + BYTES_TO_T_UINT_8( 0x15, 0xA1, 0x38, 0x90, 0x1B, 0x0D, 0xA3, 0x75 ), + BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0xFF ), +}; +#endif /* MBEDTLS_ECP_DP_SECP128R1_ENABLED */ + /* * Domain parameters for secp192r1 */ @@ -747,6 +783,11 @@ int mbedtls_ecp_group_load(mbedtls_ecp_group *grp, mbedtls_ecp_group_id id) { grp->id = id; switch (id) { +#if defined(MBEDTLS_ECP_DP_SECP128R1_ENABLED) + case MBEDTLS_ECP_DP_SECP128R1: + grp->modp = NULL; + return( LOAD_GROUP_A( secp128r1 ) ); +#endif /* MBEDTLS_ECP_DP_SECP128R1_ENABLED */ #if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) case MBEDTLS_ECP_DP_SECP192R1: NIST_MODP(p192); From 9f4620c92c57af2222a916db376b4a17745d1819 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 27 Jul 2019 17:48:52 -0400 Subject: [PATCH 0171/1854] make style --- armsrc/lfops.c | 42 +++++------ client/cmdhffido.c | 6 +- client/cmdhfmfu.c | 66 ++++++++--------- client/crypto/libpcrypto.c | 140 ++++++++++++++++++------------------ client/crypto/libpcrypto.h | 2 +- client/fido/fidocore.c | 4 +- common/mbedtls/ecdsa.c | 2 +- common/mbedtls/ecdsa.h | 2 +- common/mbedtls/ecp_curves.c | 38 +++++----- 9 files changed, 152 insertions(+), 150 deletions(-) diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 92414f748..6ab87fec0 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -170,42 +170,42 @@ void printT55xxConfig(void) { Dbprintf(_YELLOW_("1 of 4 coding reference")); break; } - if ( T55xx_Timing.m[i].start_gap != 0xFFFF ) + if (T55xx_Timing.m[i].start_gap != 0xFFFF) Dbprintf(" [a] startgap............%d*8 (%d)", T55xx_Timing.m[i].start_gap / 8, T55xx_Timing.m[i].start_gap); else - Dbprintf(" [a] startgap............" _RED_("unconfigured") ); - - if ( T55xx_Timing.m[i].write_gap != 0xFFFF ) + Dbprintf(" [a] startgap............" _RED_("unconfigured")); + + if (T55xx_Timing.m[i].write_gap != 0xFFFF) Dbprintf(" [b] writegap............%d*8 (%d)", T55xx_Timing.m[i].write_gap / 8, T55xx_Timing.m[i].write_gap); else - Dbprintf(" [b] writegap............" _RED_("unconfigured") ); - - if ( T55xx_Timing.m[i].write_0 != 0xFFFF ) + Dbprintf(" [b] writegap............" _RED_("unconfigured")); + + if (T55xx_Timing.m[i].write_0 != 0xFFFF) Dbprintf(" [c] write_0.............%d*8 (%d)", T55xx_Timing.m[i].write_0 / 8, T55xx_Timing.m[i].write_0); else - Dbprintf(" [c] write_0............." _RED_("unconfigured") ); - - if ( T55xx_Timing.m[i].write_1 != 0xFFFF ) + Dbprintf(" [c] write_0............." _RED_("unconfigured")); + + if (T55xx_Timing.m[i].write_1 != 0xFFFF) Dbprintf(" [d] write_1.............%d*8 (%d)", T55xx_Timing.m[i].write_1 / 8, T55xx_Timing.m[i].write_1); else - Dbprintf(" [d] write_1............." _RED_("unconfigured") ); - - if ( T55xx_Timing.m[i].read_gap != 0xFFFF ) + Dbprintf(" [d] write_1............." _RED_("unconfigured")); + + if (T55xx_Timing.m[i].read_gap != 0xFFFF) Dbprintf(" [e] readgap.............%d*8 (%d)", T55xx_Timing.m[i].read_gap / 8, T55xx_Timing.m[i].read_gap); else - Dbprintf(" [e] readgap............." _RED_("unconfigured") ); - + Dbprintf(" [e] readgap............." _RED_("unconfigured")); + if (i == T55XX_DLMODE_1OF4) { - - if ( T55xx_Timing.m[i].write_2 != 0xFFFF ) + + if (T55xx_Timing.m[i].write_2 != 0xFFFF) Dbprintf(" [f] write_2.............%d*8 (%d)", T55xx_Timing.m[i].write_2 / 8, T55xx_Timing.m[i].write_2); else - Dbprintf(" [f] write_2............." _RED_("unconfigured") ); - - if ( T55xx_Timing.m[i].write_3 != 0xFFFF ) + Dbprintf(" [f] write_2............." _RED_("unconfigured")); + + if (T55xx_Timing.m[i].write_3 != 0xFFFF) Dbprintf(" [g] write_3.............%d*8 (%d)", T55xx_Timing.m[i].write_3 / 8, T55xx_Timing.m[i].write_3); else - Dbprintf(" [f] write_3............." _RED_("unconfigured") ); + Dbprintf(" [f] write_3............." _RED_("unconfigured")); } } } diff --git a/client/cmdhffido.c b/client/cmdhffido.c index f7db54b00..3f0f259a4 100644 --- a/client/cmdhffido.c +++ b/client/cmdhffido.c @@ -349,7 +349,7 @@ static int CmdHFFidoRegister(const char *cmd) { res = ecdsa_signature_verify(MBEDTLS_ECP_DP_SECP256R1, public_key, xbuf, xbuflen, &buf[hashp], len - hashp, true); if (res) { if (res == MBEDTLS_ERR_ECP_VERIFY_FAILED) { - PrintAndLogEx(WARNING, "Signature is" _RED_("NOT VALID") ); + PrintAndLogEx(WARNING, "Signature is" _RED_("NOT VALID")); } else { PrintAndLogEx(WARNING, "Other signature check error: %x %s", (res < 0) ? -res : res, ecdsa_get_error(res)); } @@ -575,12 +575,12 @@ static int CmdHFFidoAuthenticate(const char *cmd) { res = ecdsa_signature_verify(MBEDTLS_ECP_DP_SECP256R1, public_key, xbuf, xbuflen, &buf[5], len - 5, true); if (res) { if (res == MBEDTLS_ERR_ECP_VERIFY_FAILED) { - PrintAndLogEx(WARNING, "Signature is" _RED_("NOT VALID.") ); + PrintAndLogEx(WARNING, "Signature is" _RED_("NOT VALID.")); } else { PrintAndLogEx(WARNING, "Other signature check error: %x %s", (res < 0) ? -res : res, ecdsa_get_error(res)); } } else { - PrintAndLogEx(SUCCESS, "Signature is" _GREEN_("OK") ); + PrintAndLogEx(SUCCESS, "Signature is" _GREEN_("OK")); } } else { PrintAndLogEx(WARNING, "No public key provided. can't check signature."); diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index e2f3565e3..696955b6e 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -226,24 +226,26 @@ uint8_t default_pwd_pack[KEYS_PWD_COUNT][4] = { }; #define PUBLIC_ECDA_KEYLEN 33 - + // known public keys for the originality check (source: https://github.com/alexbatalov/node-nxp-originality-verifier) // ref: AN11350 NTAG 21x Originality Signature Validation // ref: AN11341 MIFARE Ultralight EV1 Originality Signature Validation -uint8_t public_keys[2][PUBLIC_ECDA_KEYLEN] = { - // UL, NTAG21x and NDEF - { 0x04,0x49,0x4e,0x1a,0x38,0x6d,0x3d,0x3c, - 0xfe,0x3d,0xc1,0x0e,0x5d,0xe6,0x8a,0x49, - 0x9b,0x1c,0x20,0x2d,0xb5,0xb1,0x32,0x39, - 0x3e,0x89,0xed,0x19,0xfe,0x5b,0xe8,0xbc,0x61 - }, - // UL EV1 - { 0x04,0x90,0x93,0x3b,0xdc,0xd6,0xe9,0x9b, - 0x4e,0x25,0x5e,0x3d,0xa5,0x53,0x89,0xa8, - 0x27,0x56,0x4e,0x11,0x71,0x8e,0x01,0x72, - 0x92,0xfa,0xf2,0x32,0x26,0xa9,0x66,0x14,0xb8 - } -}; +uint8_t public_keys[2][PUBLIC_ECDA_KEYLEN] = { + // UL, NTAG21x and NDEF + { + 0x04, 0x49, 0x4e, 0x1a, 0x38, 0x6d, 0x3d, 0x3c, + 0xfe, 0x3d, 0xc1, 0x0e, 0x5d, 0xe6, 0x8a, 0x49, + 0x9b, 0x1c, 0x20, 0x2d, 0xb5, 0xb1, 0x32, 0x39, + 0x3e, 0x89, 0xed, 0x19, 0xfe, 0x5b, 0xe8, 0xbc, 0x61 + }, + // UL EV1 + { + 0x04, 0x90, 0x93, 0x3b, 0xdc, 0xd6, 0xe9, 0x9b, + 0x4e, 0x25, 0x5e, 0x3d, 0xa5, 0x53, 0x89, 0xa8, + 0x27, 0x56, 0x4e, 0x11, 0x71, 0x8e, 0x01, 0x72, + 0x92, 0xfa, 0xf2, 0x32, 0x26, 0xa9, 0x66, 0x14, 0xb8 + } +}; #define MAX_UL_TYPES 22 @@ -672,7 +674,7 @@ static int ul_print_default(uint8_t *data) { else PrintAndLogEx(NORMAL, " BCC0 : %02X, crc should be %02X", data[3], crc0); - int crc1 = uid[3] ^ uid[4] ^ uid[5] ^ uid[6]; + int crc1 = uid[3] ^ uid[4] ^ uid[5] ^ uid[6]; if (data[8] == crc1) PrintAndLogEx(NORMAL, " BCC1 : %02X, Ok", data[8]); else @@ -992,20 +994,20 @@ static int ulev1_print_counters() { return len; } -static int ulev1_print_signature(TagTypeUL_t tagtype, uint8_t *uid, uint8_t *signature, size_t signature_len){ - uint8_t public_key = 0; - if (tagtype == UL_EV1_48 || tagtype == UL_EV1_128) { - public_key = 1; - } - int res = ecdsa_signature_r_s_verify(MBEDTLS_ECP_DP_SECP128R1, public_keys[public_key], uid, 7, signature, signature_len, false); - bool is_valid = (res == 0); - +static int ulev1_print_signature(TagTypeUL_t tagtype, uint8_t *uid, uint8_t *signature, size_t signature_len) { + uint8_t public_key = 0; + if (tagtype == UL_EV1_48 || tagtype == UL_EV1_128) { + public_key = 1; + } + int res = ecdsa_signature_r_s_verify(MBEDTLS_ECP_DP_SECP128R1, public_keys[public_key], uid, 7, signature, signature_len, false); + bool is_valid = (res == 0); + PrintAndLogEx(NORMAL, "\n--- Tag Signature"); - PrintAndLogEx(NORMAL, "IC signature public key name : NXP NTAG21x (2013)"); + PrintAndLogEx(NORMAL, "IC signature public key name : NXP NTAG21x (2013)"); PrintAndLogEx(NORMAL, "IC signature public key value : %s", sprint_hex(public_keys[public_key], PUBLIC_ECDA_KEYLEN)); PrintAndLogEx(NORMAL, " Elliptic curve parameters : NID_secp128r1"); PrintAndLogEx(NORMAL, " TAG IC Signature : %s", sprint_hex(signature, signature_len)); - PrintAndLogEx(NORMAL, "Signature verified %s", (is_valid) ? _GREEN_("successful") : _RED_("failed") ); + PrintAndLogEx(NORMAL, "Signature verified %s", (is_valid) ? _GREEN_("successful") : _RED_("failed")); return PM3_SUCCESS; } @@ -1202,8 +1204,8 @@ static int CmdHF14AMfUInfo(const char *Cmd) { uint8_t *key = pwd; uint8_t pack[4] = {0, 0, 0, 0}; int len; - uint8_t uid[7]; - + uint8_t uid[7]; + char tempStr[50]; while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { @@ -1254,8 +1256,8 @@ static int CmdHF14AMfUInfo(const char *Cmd) { PrintAndLogEx(ERR, "Error: tag didn't answer to READ"); return PM3_ESOFT; } else if (status == 16) { - memcpy(uid, data, 3); - memcpy(uid + 3, data + 4, 4); + memcpy(uid, data, 3); + memcpy(uid + 3, data + 4, 4); ul_print_default(data); ndef_print_CC(data + 12); } else { @@ -1332,8 +1334,8 @@ static int CmdHF14AMfUInfo(const char *Cmd) { return PM3_ESOFT; } if (status == 32) { - ulev1_print_signature(tagtype, uid, ulev1_signature, sizeof(ulev1_signature)); - } else { + ulev1_print_signature(tagtype, uid, ulev1_signature, sizeof(ulev1_signature)); + } else { // re-select if (ul_auth_select(&card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack)) == PM3_ESOFT) return PM3_ESOFT; } diff --git a/client/crypto/libpcrypto.c b/client/crypto/libpcrypto.c index 3bdbb46ae..31c698dc7 100644 --- a/client/crypto/libpcrypto.c +++ b/client/crypto/libpcrypto.c @@ -128,7 +128,7 @@ static int ecdsa_init_str(mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id curv int res; mbedtls_ecdsa_init(ctx); - res = mbedtls_ecp_group_load(&ctx->grp, curveid); + res = mbedtls_ecp_group_load(&ctx->grp, curveid); if (res) return res; @@ -154,19 +154,19 @@ static int ecdsa_init(mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id curveid, int res; mbedtls_ecdsa_init(ctx); - res = mbedtls_ecp_group_load(&ctx->grp, curveid); + res = mbedtls_ecp_group_load(&ctx->grp, curveid); if (res) return res; - size_t keylen = (ctx->grp.nbits + 7 ) / 8; + size_t keylen = (ctx->grp.nbits + 7) / 8; if (key_d) { - res = mbedtls_mpi_read_binary(&ctx->d, key_d, keylen); + res = mbedtls_mpi_read_binary(&ctx->d, key_d, keylen); if (res) return res; } if (key_xy) { - res = mbedtls_ecp_point_read_binary(&ctx->grp, &ctx->Q, key_xy, keylen * 2 + 1); + res = mbedtls_ecp_point_read_binary(&ctx->grp, &ctx->Q, key_xy, keylen * 2 + 1); if (res) return res; } @@ -195,22 +195,22 @@ int ecdsa_key_create(mbedtls_ecp_group_id curveid, uint8_t *key_d, uint8_t *key_ if (res) goto exit; - size_t keylen = (ctx.grp.nbits + 7) / 8; - res = mbedtls_mpi_write_binary(&ctx.d, key_d, keylen); + size_t keylen = (ctx.grp.nbits + 7) / 8; + res = mbedtls_mpi_write_binary(&ctx.d, key_d, keylen); if (res) goto exit; - size_t public_keylen = 0; + size_t public_keylen = 0; uint8_t public_key[200] = {0}; - res = mbedtls_ecp_point_write_binary(&ctx.grp, &ctx.Q, MBEDTLS_ECP_PF_UNCOMPRESSED, &public_keylen, public_key, sizeof(public_key)); + res = mbedtls_ecp_point_write_binary(&ctx.grp, &ctx.Q, MBEDTLS_ECP_PF_UNCOMPRESSED, &public_keylen, public_key, sizeof(public_key)); if (res) goto exit; - if (public_keylen != 1 + 2 * keylen) { // 0x04 + if (public_keylen != 1 + 2 * keylen) { // 0x04 res = 1; goto exit; } - memcpy(key_xy, public_key, public_keylen); + memcpy(key_xy, public_key, public_keylen); exit: mbedtls_entropy_free(&entropy); @@ -233,22 +233,22 @@ int ecdsa_public_key_from_pk(mbedtls_pk_context *pk, mbedtls_ecp_group_id curve mbedtls_ecdsa_context ctx; mbedtls_ecdsa_init(&ctx); - res = mbedtls_ecp_group_load(&ctx.grp, curveid); + res = mbedtls_ecp_group_load(&ctx.grp, curveid); if (res) goto exit; - size_t private_keylen = (ctx.grp.nbits + 7) / 8; - if (keylen < 1 + 2 * private_keylen) { - res = 1; - goto exit; - } + size_t private_keylen = (ctx.grp.nbits + 7) / 8; + if (keylen < 1 + 2 * private_keylen) { + res = 1; + goto exit; + } res = mbedtls_ecdsa_from_keypair(&ctx, mbedtls_pk_ec(*pk)); if (res) goto exit; res = mbedtls_ecp_point_write_binary(&ctx.grp, &ctx.Q, MBEDTLS_ECP_PF_UNCOMPRESSED, &realkeylen, key, keylen); - if (realkeylen != 1 + 2 * private_keylen) + if (realkeylen != 1 + 2 * private_keylen) res = 2; exit: mbedtls_ecdsa_free(&ctx); @@ -277,16 +277,16 @@ int ecdsa_signature_create(mbedtls_ecp_group_id curveid, uint8_t *key_d, uint8_t mbedtls_ecdsa_context ctx; ecdsa_init(&ctx, curveid, key_d, key_xy); - res = mbedtls_ecdsa_write_signature( - &ctx, - MBEDTLS_MD_SHA256, - hash ? shahash : input, - hash ? sizeof(shahash) : length, - signature, - signaturelen, - mbedtls_ctr_drbg_random, - &ctr_drbg - ); + res = mbedtls_ecdsa_write_signature( + &ctx, + MBEDTLS_MD_SHA256, + hash ? shahash : input, + hash ? sizeof(shahash) : length, + signature, + signaturelen, + mbedtls_ctr_drbg_random, + &ctr_drbg + ); exit: @@ -323,14 +323,14 @@ static int ecdsa_signature_verify_keystr(mbedtls_ecp_group_id curveid, const cha return res; mbedtls_ecdsa_context ctx; - ecdsa_init_str(&ctx, curveid, NULL, key_x, key_y); - res = mbedtls_ecdsa_read_signature( - &ctx, - hash ? shahash : input, - hash ? sizeof(shahash) : length, - signature, - signaturelen - ); + ecdsa_init_str(&ctx, curveid, NULL, key_x, key_y); + res = mbedtls_ecdsa_read_signature( + &ctx, + hash ? shahash : input, + hash ? sizeof(shahash) : length, + signature, + signaturelen + ); mbedtls_ecdsa_free(&ctx); return res; @@ -339,21 +339,21 @@ static int ecdsa_signature_verify_keystr(mbedtls_ecp_group_id curveid, const cha int ecdsa_signature_verify(mbedtls_ecp_group_id curveid, uint8_t *key_xy, uint8_t *input, int length, uint8_t *signature, size_t signaturelen, bool hash) { int res; uint8_t shahash[32] = {0}; - if (hash) { - res = sha256hash(input, length, shahash); - if (res) - return res; - } + if (hash) { + res = sha256hash(input, length, shahash); + if (res) + return res; + } mbedtls_ecdsa_context ctx; - res = ecdsa_init(&ctx, curveid, NULL, key_xy); - res = mbedtls_ecdsa_read_signature( - &ctx, - hash ? shahash : input, - hash ? sizeof(shahash) : length, - signature, - signaturelen - ); + res = ecdsa_init(&ctx, curveid, NULL, key_xy); + res = mbedtls_ecdsa_read_signature( + &ctx, + hash ? shahash : input, + hash ? sizeof(shahash) : length, + signature, + signaturelen + ); mbedtls_ecdsa_free(&ctx); return res; @@ -362,27 +362,27 @@ int ecdsa_signature_verify(mbedtls_ecp_group_id curveid, uint8_t *key_xy, uint8_ int ecdsa_signature_r_s_verify(mbedtls_ecp_group_id curveid, uint8_t *key_xy, uint8_t *input, int length, uint8_t *r_s, size_t r_s_len, bool hash) { int res; - uint8_t signature[MBEDTLS_ECDSA_MAX_LEN]; - size_t signature_len; + uint8_t signature[MBEDTLS_ECDSA_MAX_LEN]; + size_t signature_len; - // convert r & s to ASN.1 signature + // convert r & s to ASN.1 signature mbedtls_mpi r, s; mbedtls_mpi_init(&r); mbedtls_mpi_init(&s); - mbedtls_mpi_read_binary(&r, r_s, r_s_len/2); - mbedtls_mpi_read_binary(&s, r_s + r_s_len/2, r_s_len/2); - - res = ecdsa_signature_to_asn1(&r, &s, signature, &signature_len); - if (res < 0) { - return res; - } - - res = ecdsa_signature_verify(curveid, key_xy, input, length, signature, signature_len, hash); + mbedtls_mpi_read_binary(&r, r_s, r_s_len / 2); + mbedtls_mpi_read_binary(&s, r_s + r_s_len / 2, r_s_len / 2); + + res = ecdsa_signature_to_asn1(&r, &s, signature, &signature_len); + if (res < 0) { + return res; + } + + res = ecdsa_signature_verify(curveid, key_xy, input, length, signature, signature_len, hash); mbedtls_mpi_free(&r); mbedtls_mpi_free(&s); - return res; + return res; } @@ -396,7 +396,7 @@ int ecdsa_signature_r_s_verify(mbedtls_ecp_group_id curveid, uint8_t *key_xy, ui int ecdsa_nist_test(bool verbose) { int res; uint8_t input[] = "Example of ECDSA with P-256"; - mbedtls_ecp_group_id curveid = MBEDTLS_ECP_DP_SECP256R1; + mbedtls_ecp_group_id curveid = MBEDTLS_ECP_DP_SECP256R1; int length = strlen((char *)input); uint8_t signature[300] = {0}; size_t siglen = 0; @@ -405,7 +405,7 @@ int ecdsa_nist_test(bool verbose) { if (verbose) printf(" ECDSA NIST test: "); // make signature - res = ecdsa_signature_create_test(curveid, T_PRIVATE_KEY, T_Q_X, T_Q_Y, T_K, input, length, signature, &siglen); + res = ecdsa_signature_create_test(curveid, T_PRIVATE_KEY, T_Q_X, T_Q_Y, T_K, input, length, signature, &siglen); // printf("res: %x signature[%x]: %s\n", (res<0)?-res:res, siglen, sprint_hex(signature, siglen)); if (res) goto exit; @@ -429,13 +429,13 @@ int ecdsa_nist_test(bool verbose) { } // verify signature - res = ecdsa_signature_verify_keystr(curveid, T_Q_X, T_Q_Y, input, length, signature, siglen, true); + res = ecdsa_signature_verify_keystr(curveid, T_Q_X, T_Q_Y, input, length, signature, siglen, true); if (res) goto exit; // verify wrong signature input[0] ^= 0xFF; - res = ecdsa_signature_verify_keystr(curveid, T_Q_X, T_Q_Y, input, length, signature, siglen, true); + res = ecdsa_signature_verify_keystr(curveid, T_Q_X, T_Q_Y, input, length, signature, siglen, true); if (!res) { res = 1; goto exit; @@ -452,20 +452,20 @@ int ecdsa_nist_test(bool verbose) { memset(signature, 0x00, sizeof(signature)); siglen = 0; - res = ecdsa_key_create(curveid, key_d, key_xy); + res = ecdsa_key_create(curveid, key_d, key_xy); if (res) goto exit; - res = ecdsa_signature_create(curveid, key_d, key_xy, input, length, signature, &siglen, true); + res = ecdsa_signature_create(curveid, key_d, key_xy, input, length, signature, &siglen, true); if (res) goto exit; - res = ecdsa_signature_verify(curveid, key_xy, input, length, signature, siglen, true); + res = ecdsa_signature_verify(curveid, key_xy, input, length, signature, siglen, true); if (res) goto exit; input[0] ^= 0xFF; - res = ecdsa_signature_verify(curveid, key_xy, input, length, signature, siglen, true); + res = ecdsa_signature_verify(curveid, key_xy, input, length, signature, siglen, true); if (!res) goto exit; diff --git a/client/crypto/libpcrypto.h b/client/crypto/libpcrypto.h index 90c389636..b4307f454 100644 --- a/client/crypto/libpcrypto.h +++ b/client/crypto/libpcrypto.h @@ -24,7 +24,7 @@ int aes_cmac8(uint8_t *iv, uint8_t *key, uint8_t *input, uint8_t *mac, int lengt int sha256hash(uint8_t *input, int length, uint8_t *hash); int sha512hash(uint8_t *input, int length, uint8_t *hash); -int ecdsa_key_create(mbedtls_ecp_group_id curveid, uint8_t * key_d, uint8_t *key_xy); +int ecdsa_key_create(mbedtls_ecp_group_id curveid, uint8_t *key_d, uint8_t *key_xy); int ecdsa_public_key_from_pk(mbedtls_pk_context *pk, mbedtls_ecp_group_id curveid, uint8_t *key, size_t keylen); int ecdsa_signature_create(mbedtls_ecp_group_id curveid, uint8_t *key_d, uint8_t *key_xy, uint8_t *input, int length, uint8_t *signature, size_t *signaturelen, bool hash); int ecdsa_signature_verify(mbedtls_ecp_group_id curveid, uint8_t *key_xy, uint8_t *input, int length, uint8_t *signature, size_t signaturelen, bool hash); diff --git a/client/fido/fidocore.c b/client/fido/fidocore.c index ecfefaa79..06188c5a4 100644 --- a/client/fido/fidocore.c +++ b/client/fido/fidocore.c @@ -262,7 +262,7 @@ int FIDOCheckDERAndGetKey(uint8_t *der, size_t derLen, bool verbose, uint8_t *pu } // get public key - res = ecdsa_public_key_from_pk(&cert.pk, MBEDTLS_ECP_DP_SECP256R1, publicKey, publicKeyMaxLen); + res = ecdsa_public_key_from_pk(&cert.pk, MBEDTLS_ECP_DP_SECP256R1, publicKey, publicKeyMaxLen); if (res) { PrintAndLogEx(ERR, "ERROR: getting public key from certificate 0x%x - %s", (res < 0) ? -res : res, ecdsa_get_error(res)); } else { @@ -384,7 +384,7 @@ static int FIDO2CheckSignature(json_t *root, uint8_t *publickey, uint8_t *sign, res = ecdsa_signature_verify(MBEDTLS_ECP_DP_SECP256R1, publickey, xbuf, xbuflen, sign, signLen, true); if (res) { if (res == MBEDTLS_ERR_ECP_VERIFY_FAILED) { - PrintAndLogEx(WARNING, "Signature is " _RED_("NOT VALID") ); + PrintAndLogEx(WARNING, "Signature is " _RED_("NOT VALID")); } else { PrintAndLogEx(WARNING, "Other signature check error: %x %s", (res < 0) ? -res : res, ecdsa_get_error(res)); } diff --git a/common/mbedtls/ecdsa.c b/common/mbedtls/ecdsa.c index 388466162..1d087f386 100644 --- a/common/mbedtls/ecdsa.c +++ b/common/mbedtls/ecdsa.c @@ -287,7 +287,7 @@ cleanup: * Convert a signature (given by context) to ASN.1 */ int ecdsa_signature_to_asn1(const mbedtls_mpi *r, const mbedtls_mpi *s, - unsigned char *sig, size_t *slen) { + unsigned char *sig, size_t *slen) { int ret; unsigned char buf[MBEDTLS_ECDSA_MAX_LEN]; unsigned char *p = buf + sizeof(buf); diff --git a/common/mbedtls/ecdsa.h b/common/mbedtls/ecdsa.h index b3bf1b110..5293c2376 100644 --- a/common/mbedtls/ecdsa.h +++ b/common/mbedtls/ecdsa.h @@ -334,7 +334,7 @@ void mbedtls_ecdsa_init(mbedtls_ecdsa_context *ctx); */ void mbedtls_ecdsa_free(mbedtls_ecdsa_context *ctx); -int ecdsa_signature_to_asn1( const mbedtls_mpi *r, const mbedtls_mpi *s, unsigned char *sig, size_t *slen ); +int ecdsa_signature_to_asn1(const mbedtls_mpi *r, const mbedtls_mpi *s, unsigned char *sig, size_t *slen); #ifdef __cplusplus } diff --git a/common/mbedtls/ecp_curves.c b/common/mbedtls/ecp_curves.c index dcb79aeba..8242c9076 100644 --- a/common/mbedtls/ecp_curves.c +++ b/common/mbedtls/ecp_curves.c @@ -89,34 +89,34 @@ */ #if defined(MBEDTLS_ECP_DP_SECP128R1_ENABLED) static const mbedtls_mpi_uint secp128r1_p[] = { - // 2^128 - 2^97 - 1 // TODO - BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF ), + // 2^128 - 2^97 - 1 // TODO + BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF), }; static const mbedtls_mpi_uint secp128r1_a[] = { - // FFFFFFFDFFFFFFFF FFFFFFFFFFFFFFFC - BYTES_TO_T_UINT_8( 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF ), + // FFFFFFFDFFFFFFFF FFFFFFFFFFFFFFFC + BYTES_TO_T_UINT_8(0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF), }; static const mbedtls_mpi_uint secp128r1_b[] = { - // E87579C11079F43D D824993C2CEE5ED3 - BYTES_TO_T_UINT_8( 0xD3, 0x5E, 0xEE, 0x2C, 0x3C, 0x99, 0x24, 0xD8 ), - BYTES_TO_T_UINT_8( 0x3D, 0xF4, 0x79, 0x10, 0xC1, 0x79, 0x75, 0xE8 ), + // E87579C11079F43D D824993C2CEE5ED3 + BYTES_TO_T_UINT_8(0xD3, 0x5E, 0xEE, 0x2C, 0x3C, 0x99, 0x24, 0xD8), + BYTES_TO_T_UINT_8(0x3D, 0xF4, 0x79, 0x10, 0xC1, 0x79, 0x75, 0xE8), }; static const mbedtls_mpi_uint secp128r1_gx[] = { - // 161FF7528B899B2D 0C28607CA52C5B86 - BYTES_TO_T_UINT_8( 0x86, 0x5B, 0x2C, 0xA5, 0x7C, 0x60, 0x28, 0x0C ), - BYTES_TO_T_UINT_8( 0x2D, 0x9B, 0x89, 0x8B, 0x52, 0xF7, 0x1F, 0x16 ), + // 161FF7528B899B2D 0C28607CA52C5B86 + BYTES_TO_T_UINT_8(0x86, 0x5B, 0x2C, 0xA5, 0x7C, 0x60, 0x28, 0x0C), + BYTES_TO_T_UINT_8(0x2D, 0x9B, 0x89, 0x8B, 0x52, 0xF7, 0x1F, 0x16), }; static const mbedtls_mpi_uint secp128r1_gy[] = { - // CF5AC8395BAFEB13 C02DA292DDED7A83 - BYTES_TO_T_UINT_8( 0x83, 0x7A, 0xED, 0xDD, 0x92, 0xA2, 0x2D, 0xC0 ), - BYTES_TO_T_UINT_8( 0x13, 0xEB, 0xAF, 0x5B, 0x39, 0xC8, 0x5A, 0xCF ), + // CF5AC8395BAFEB13 C02DA292DDED7A83 + BYTES_TO_T_UINT_8(0x83, 0x7A, 0xED, 0xDD, 0x92, 0xA2, 0x2D, 0xC0), + BYTES_TO_T_UINT_8(0x13, 0xEB, 0xAF, 0x5B, 0x39, 0xC8, 0x5A, 0xCF), }; static const mbedtls_mpi_uint secp128r1_n[] = { - // FFFFFFFE00000000 75A30D1B9038A115 - BYTES_TO_T_UINT_8( 0x15, 0xA1, 0x38, 0x90, 0x1B, 0x0D, 0xA3, 0x75 ), - BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0xFF ), + // FFFFFFFE00000000 75A30D1B9038A115 + BYTES_TO_T_UINT_8(0x15, 0xA1, 0x38, 0x90, 0x1B, 0x0D, 0xA3, 0x75), + BYTES_TO_T_UINT_8(0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0xFF), }; #endif /* MBEDTLS_ECP_DP_SECP128R1_ENABLED */ @@ -786,7 +786,7 @@ int mbedtls_ecp_group_load(mbedtls_ecp_group *grp, mbedtls_ecp_group_id id) { #if defined(MBEDTLS_ECP_DP_SECP128R1_ENABLED) case MBEDTLS_ECP_DP_SECP128R1: grp->modp = NULL; - return( LOAD_GROUP_A( secp128r1 ) ); + return (LOAD_GROUP_A(secp128r1)); #endif /* MBEDTLS_ECP_DP_SECP128R1_ENABLED */ #if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) case MBEDTLS_ECP_DP_SECP192R1: From ca53711b8d777764219728f6cf323bd48e989373 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 28 Jul 2019 09:21:02 +0200 Subject: [PATCH 0172/1854] chg: lf t55xx - helptext --- client/cmdlft55xx.c | 52 +++++++++++++++++---------------------------- 1 file changed, 20 insertions(+), 32 deletions(-) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 6a88116df..398aa6988 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -31,6 +31,14 @@ void Set_t55xx_Config(t55xx_conf_block_t conf) { config = conf; } +static void print_usage_t55xx_downloadlink(void) { + PrintAndLogEx(NORMAL, " r - downlink encoding 0|1|2|3"); + PrintAndLogEx(NORMAL, " 0 - fixed bit length (default)"); + PrintAndLogEx(NORMAL, " 1 - long leading reference"); + PrintAndLogEx(NORMAL, " 2 - leading zero"); + PrintAndLogEx(NORMAL, " 3 - 1 of 4 coding reference"); +} + static int usage_t55xx_config() { PrintAndLogEx(NORMAL, "Usage: lf t55xx config [d ] [i [0/1]] [o ] [Q5 [0/1]] [ST [0/1]]"); PrintAndLogEx(NORMAL, "Options:"); @@ -56,11 +64,7 @@ static int usage_t55xx_read() { PrintAndLogEx(NORMAL, " p - OPTIONAL password (8 hex characters)"); PrintAndLogEx(NORMAL, " o - OPTIONAL override safety check"); PrintAndLogEx(NORMAL, " 1 - OPTIONAL 0|1 read Page 1 instead of Page 0"); - PrintAndLogEx(NORMAL, " r - downlink encoding 0|1|2|3"); - PrintAndLogEx(NORMAL, " 0 - fixed bit length (default)"); - PrintAndLogEx(NORMAL, " 1 - long leading reference"); - PrintAndLogEx(NORMAL, " 2 - leading zero"); - PrintAndLogEx(NORMAL, " 3 - 1 of 4 coding reference"); + print_usage_t55xx_downloadlink(); PrintAndLogEx(NORMAL, " ****WARNING****"); PrintAndLogEx(NORMAL, " Use of read with password on a tag not configured for a pwd"); PrintAndLogEx(NORMAL, " can damage the tag"); @@ -80,8 +84,7 @@ static int usage_t55xx_write() { PrintAndLogEx(NORMAL, " p - OPTIONAL password 4bytes (8 hex characters)"); PrintAndLogEx(NORMAL, " 1 - OPTIONAL write Page 1 instead of Page 0"); PrintAndLogEx(NORMAL, " t - OPTIONAL test mode write - ****DANGER****"); - PrintAndLogEx(NORMAL, " r - downlink encoding '0' fixed bit length (default), '1' long leading ref."); - PrintAndLogEx(NORMAL, " '2' leading zero, '3' 1 of 4 coding ref."); + print_usage_t55xx_downloadlink(); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx write b 3 d 11223344 - write 11223344 to block 3"); @@ -92,8 +95,7 @@ static int usage_t55xx_write() { static int usage_t55xx_trace() { PrintAndLogEx(NORMAL, "Usage: lf t55xx trace [r mode]"); PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " r - downlink encoding '0' fixed bit length (default), '1' long leading ref."); - PrintAndLogEx(NORMAL, " '2' leading zero, '3' 1 of 4 coding ref."); + print_usage_t55xx_downloadlink(); // Command did not seem to support the 1 option (yet) so have removed the help lines // PrintAndLogEx(NORMAL, " 1 - if set, use Graphbuffer otherwise read data from tag."); PrintAndLogEx(NORMAL, ""); @@ -111,8 +113,7 @@ static int usage_t55xx_info() { PrintAndLogEx(NORMAL, " d - 4 bytes of data (8 hex characters)"); PrintAndLogEx(NORMAL, " if set, use these data instead of reading tag."); PrintAndLogEx(NORMAL, " q - if set, provided data are interpreted as Q5 config."); - PrintAndLogEx(NORMAL, " r - downlink encoding '0' fixed bit length (default), '1' long leading ref."); - PrintAndLogEx(NORMAL, " '2' leading zero, '3' 1 of 4 coding ref."); + print_usage_t55xx_downloadlink(); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx info"); @@ -127,8 +128,7 @@ static int usage_t55xx_dump() { PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " - OPTIONAL password 4bytes (8 hex symbols)"); PrintAndLogEx(NORMAL, " o - OPTIONAL override, force pwd read despite danger to card"); - PrintAndLogEx(NORMAL, " r - downlink encoding '0' fixed bit length (default), '1' long leading ref."); - PrintAndLogEx(NORMAL, " '2' leading zero, '3' 1 of 4 coding ref."); + print_usage_t55xx_downloadlink(); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx dump"); @@ -141,9 +141,7 @@ static int usage_t55xx_detect() { PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " 1 - if set, use Graphbuffer otherwise read data from tag."); PrintAndLogEx(NORMAL, " p - downlink encoding '0' fixed bit length (default)"); - PrintAndLogEx(NORMAL, " '1' long leading ref., '2' leading zero "); - PrintAndLogEx(NORMAL, " '3' 1 of 4 coding ref., '4' try all modes"); + print_usage_t55xx_downloadlink(); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx detect"); @@ -158,9 +156,7 @@ static int usage_t55xx_detectP1() { PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " 1 - if set, use Graphbuffer otherwise read data from tag."); PrintAndLogEx(NORMAL, " p - OPTIONAL password (8 hex characters)"); - PrintAndLogEx(NORMAL, " r - downlink encoding '0' fixed bit length (default)"); - PrintAndLogEx(NORMAL, " '1' long leading ref., '2' leading zero "); - PrintAndLogEx(NORMAL, " '3' 1 of 4 coding ref., '4' try all modes"); + print_usage_t55xx_downloadlink(); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx p1detect"); @@ -175,8 +171,7 @@ static int usage_t55xx_wakup() { PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h - this help"); PrintAndLogEx(NORMAL, " p - password 4bytes (8 hex symbols)"); - PrintAndLogEx(NORMAL, " r - downlink encoding '0' fixed bit length (default), '1' long leading ref."); - PrintAndLogEx(NORMAL, " '2' leading zero, '3' 1 of 4 coding ref."); + print_usage_t55xx_downloadlink(); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx wakeup p 11223344 - send wakeup password"); @@ -191,9 +186,7 @@ static int usage_t55xx_chk() { PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h - this help"); PrintAndLogEx(NORMAL, " m - use dictionary from flashmemory\n"); - PrintAndLogEx(NORMAL, " r - downlink encoding '0' fixed bit length (default)"); - PrintAndLogEx(NORMAL, " '1' long leading ref., '2' leading zero "); - PrintAndLogEx(NORMAL, " '3' 1 of 4 coding ref., '4' try all modes"); + print_usage_t55xx_downloadlink(); PrintAndLogEx(NORMAL, " i <*.dic> - loads a default keys dictionary file <*.dic>"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); @@ -211,9 +204,7 @@ static int usage_t55xx_bruteforce() { PrintAndLogEx(NORMAL, " password must be 4 bytes (8 hex symbols)"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h - this help"); - PrintAndLogEx(NORMAL, " r - downlink encoding '0' fixed bit length (default)"); - PrintAndLogEx(NORMAL, " '1' long leading ref., '2' leading zero "); - PrintAndLogEx(NORMAL, " '3' 1 of 4 coding ref., '4' try all modes"); + print_usage_t55xx_downloadlink(); PrintAndLogEx(NORMAL, " - 4 byte hex value to start pwd search at"); PrintAndLogEx(NORMAL, " - 4 byte hex value to end pwd search at"); PrintAndLogEx(NORMAL, ""); @@ -232,9 +223,7 @@ static int usage_t55xx_recoverpw() { PrintAndLogEx(NORMAL, " default password is 51243648, used by many cloners"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h - this help"); - PrintAndLogEx(NORMAL, " r - downlink encoding '0' fixed bit length (default)"); - PrintAndLogEx(NORMAL, " '1' long leading ref., '2' leading zero "); - PrintAndLogEx(NORMAL, " '3' 1 of 4 coding ref., '4' try all modes"); + print_usage_t55xx_downloadlink(); PrintAndLogEx(NORMAL, " [password] - 4 byte hex value of password written by cloner"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); @@ -268,8 +257,7 @@ static int usage_lf_deviceconfig() { PrintAndLogEx(NORMAL, " f <8..255> - Set write TWO gap (1 of 4 only)"); PrintAndLogEx(NORMAL, " g <8..255> - Set write THREE gap (1 of 4 only)"); PrintAndLogEx(NORMAL, " p - persist to flashmemory"); - PrintAndLogEx(NORMAL, " r - downlink encoding '0' fixed bit length (default), '1' long leading ref."); - PrintAndLogEx(NORMAL, " '2' leading zero, '3' 1 of 4 coding ref."); + print_usage_t55xx_downloadlink(); PrintAndLogEx(NORMAL, " z - Set default t55x7 timings (use p to save if required)"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); From 00350db2381da060a007e48f73442dac7c693787 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 28 Jul 2019 03:29:31 -0400 Subject: [PATCH 0173/1854] Chg: `hf tune` - increase timeout vaules. fix #265 --- client/cmdhf.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/cmdhf.c b/client/cmdhf.c index 03a5c1681..697aa9b62 100644 --- a/client/cmdhf.c +++ b/client/cmdhf.c @@ -102,7 +102,7 @@ int CmdHFTune(const char *Cmd) { clearCommandBuffer(); uint8_t mode[] = {1}; SendCommandNG(CMD_MEASURE_ANTENNA_TUNING_HF, mode, sizeof(mode)); - if (!WaitForResponseTimeout(CMD_MEASURE_ANTENNA_TUNING_HF, &resp, 1000)) { + if (!WaitForResponseTimeout(CMD_MEASURE_ANTENNA_TUNING_HF, &resp, 2000)) { PrintAndLogEx(WARNING, "Timeout while waiting for Proxmark HF initialization, aborting"); return PM3_ETIMEOUT; } @@ -113,7 +113,7 @@ int CmdHFTune(const char *Cmd) { break; } SendCommandNG(CMD_MEASURE_ANTENNA_TUNING_HF, mode, sizeof(mode)); - if (!WaitForResponseTimeout(CMD_MEASURE_ANTENNA_TUNING_HF, &resp, 1000)) { + if (!WaitForResponseTimeout(CMD_MEASURE_ANTENNA_TUNING_HF, &resp, 2000)) { PrintAndLogEx(WARNING, "Timeout while waiting for Proxmark HF measure, aborting"); return PM3_ETIMEOUT; } @@ -124,7 +124,7 @@ int CmdHFTune(const char *Cmd) { } mode[0] = 3; SendCommandNG(CMD_MEASURE_ANTENNA_TUNING_HF, mode, sizeof(mode)); - if (!WaitForResponseTimeout(CMD_MEASURE_ANTENNA_TUNING_HF, &resp, 1000)) { + if (!WaitForResponseTimeout(CMD_MEASURE_ANTENNA_TUNING_HF, &resp, 2000)) { PrintAndLogEx(WARNING, "Timeout while waiting for Proxmark HF shutdown, aborting"); return PM3_ETIMEOUT; } From a25814bda4e53f097dc51423222f205643bcf3cf Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 28 Jul 2019 14:23:30 +0200 Subject: [PATCH 0174/1854] ADD: 'trace list' - annotate nano signature --- client/cmdhflist.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/client/cmdhflist.c b/client/cmdhflist.c index 13766e299..1d7f0ec23 100644 --- a/client/cmdhflist.c +++ b/client/cmdhflist.c @@ -279,14 +279,26 @@ int applyIso14443a(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) { break; } case MIFARE_ULEV1_READSIG: - snprintf(exp, size, "READ_SIG"); + snprintf(exp, size, "READ SIG"); break; case MIFARE_ULEV1_CHECKTEAR: - snprintf(exp, size, "CHK_TEARING(%d)", cmd[1]); + snprintf(exp, size, "CHK TEARING(%d)", cmd[1]); break; case MIFARE_ULEV1_VCSL: snprintf(exp, size, "VCSL"); break; + case MIFARE_ULNANO_WRITESIG: + snprintf(exp, size, "WRITE SIG"); + break; + case MIFARE_ULNANO_LOCKSIF: { + if (cmd[1] == 0) + snprintf(exp, size, "UNLOCK SIG"); + else if ( cmd[1] == 2 ) + snprintf(exp, size, "LOCK SIG"); + else + snprintf(exp, size, "?"); + break; + } default: return 0; } From 5854ab19dd2bcb96e36c708671cddaabf0ac46c1 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 28 Jul 2019 19:23:37 +0200 Subject: [PATCH 0175/1854] client tells when over TCP --- client/comms.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/client/comms.c b/client/comms.c index ef00ebc44..86e6b2a79 100644 --- a/client/comms.c +++ b/client/comms.c @@ -622,7 +622,9 @@ int TestProxmark(void) { conn.send_via_fpc_usart = pm3_capabilities.via_fpc; conn.uart_speed = pm3_capabilities.baudrate; - PrintAndLogEx(INFO, "Communicating with PM3 over %s", conn.send_via_fpc_usart ? _YELLOW_("FPC UART") : _YELLOW_("USB-CDC")); + PrintAndLogEx(INFO, "Communicating with PM3 over %s%s", + conn.send_via_fpc_usart ? _YELLOW_("FPC UART") : _YELLOW_("USB-CDC"), + memcmp(conn.serial_port_name, "tcp:", 4) == 0 ? "over " _YELLOW_("TCP") : ""); if (conn.send_via_fpc_usart) { PrintAndLogEx(INFO, "PM3 UART serial baudrate: " _YELLOW_("%u") "\n", conn.uart_speed); From c83ff9da0f7975b6c682d1b32a8942255ffbf405 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 28 Jul 2019 19:24:00 +0200 Subject: [PATCH 0176/1854] make style --- armsrc/appmain.c | 2 +- client/cmdhflist.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 5cf0c5767..84a4748f0 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -756,7 +756,7 @@ static void PacketReceived(PacketCommandNG *packet) { break; #ifdef WITH_LF case CMD_SET_LF_T55XX_CONFIG: { - setT55xxConfig(packet->oldarg[0], (t55xx_configurations_t*) packet->data.asBytes); + setT55xxConfig(packet->oldarg[0], (t55xx_configurations_t *) packet->data.asBytes); break; } case CMD_SET_LF_SAMPLING_CONFIG: { diff --git a/client/cmdhflist.c b/client/cmdhflist.c index 1d7f0ec23..6aea59b89 100644 --- a/client/cmdhflist.c +++ b/client/cmdhflist.c @@ -293,7 +293,7 @@ int applyIso14443a(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) { case MIFARE_ULNANO_LOCKSIF: { if (cmd[1] == 0) snprintf(exp, size, "UNLOCK SIG"); - else if ( cmd[1] == 2 ) + else if (cmd[1] == 2) snprintf(exp, size, "LOCK SIG"); else snprintf(exp, size, "?"); From 9d8402933d5cca893301843e9481cde2e21d3645 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 28 Jul 2019 19:41:45 +0200 Subject: [PATCH 0177/1854] JTAG notes --- doc/jtag_notes.md | 79 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 doc/jtag_notes.md diff --git a/doc/jtag_notes.md b/doc/jtag_notes.md new file mode 100644 index 000000000..8e31f1112 --- /dev/null +++ b/doc/jtag_notes.md @@ -0,0 +1,79 @@ +Some notes on how to reflash a bricked Proxmark3 over JTAG. + +# Linux and OpenOCD + +## Using RDV4 scripts + +The RDV4 repository contains helper scripts for JTAG flashing. + +* Get OpenOCD, e.g.: `apt-get install openocd` +* Create `tools/jtag_openocd/openocd_configuration` by copying [`tools/jtag_openocd/openocd_configuration.sample`](/tools/jtag_openocd/openocd_configuration.sample) +* Tune it to fit your JTAG tool: adapt `CONFIG_IF` to refer to the `interface-*.cfg` file corresponding to your JTAG tool. By default `openocd_configuration.sample` is set up to work with the J-Link. +* Wire the Proxmark3 to the JTAG tool. How to do it depends on the tool. See below for examples. **Warning:** don't plug the Proxmark3 on USB if the tool delivers already the voltage to the Proxmark3, which is most probably the case. +* Then just run + +``` +cd tools/jtag_openocd/ +./openocd_flash_recovery.sh +``` + +In some rare situations, flashing the full image over JTAG may fail but the bootloader could be fixed. If it's the case, you can flash the image without JTAG by booting on your fresh bootloader (possibly forced by pressing the Proxmark3 button). + +For advanced usages there are also `openocd_flash_dump.sh` for dumping the content of the Proxmark3 and `openocd_interactive.sh` for an OpenOCD console. + +## RDV4 pinout + +The RDV4 JTAG header is quite smaller compared to other Proxmark3 platforms. +If you're using a J-Link, there is a [convenient adapter](https://github.com/RfidResearchGroup/proxmark3/wiki/Tools#jtag-adapter) made by Proxgrind. +You can also make yours with some 1.27mm headers (look for `1.27mm header` on Aliexpress) or Pogo pins. + +## JLink pinout + +J-Link [pinout](https://www.segger.com/interface-description.html): + +``` + --------- --------- + |1917151311 9 7 5 3 1| + |201816141210 8 6 4 2| + -------------------- +``` + +PM3 | JLink +--- | ----- +TMS | 7 +TDI | 5 +TDO |13 +TCK | 9 +GND | 6 +3.3 | 2 + +## Raspberry Pi pinout + +RPi [pinout](https://pinout.xyz/): + +PM3 | RPi +--- | ----- +TMS | 22 +TDI | 19 +TDO | 21 +TCK | 23 +GND | 6 +3.3 | 1 + +## Third party notes on using a BusPirate + +* https://github.com/Proxmark/proxmark3/wiki/Debricking-Proxmark3-with-buspirate + +## Third party notes on using a J-Link + +* http://wiki.yobi.be/wiki/Proxmark + +## Third party notes on using a RaspBerry Pi + +* http://www.lucasoldi.com/2017/01/17/unbrick-proxmark3-with-a-raspberry-pi-and-openocd/ + +# Windows + +## Third party notes on using a J-Link on Windows + +* https://github.com/Proxmark/proxmark3/wiki/De-Bricking-Segger From 925a9646c6684e24d4dd4cbd0e9235b8e3c081fa Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 28 Jul 2019 19:45:34 +0200 Subject: [PATCH 0178/1854] troubleshooting doc --- .../Troubleshooting.md | 128 ++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 doc/md/Installation_Instructions/Troubleshooting.md diff --git a/doc/md/Installation_Instructions/Troubleshooting.md b/doc/md/Installation_Instructions/Troubleshooting.md new file mode 100644 index 000000000..7370c7dc0 --- /dev/null +++ b/doc/md/Installation_Instructions/Troubleshooting.md @@ -0,0 +1,128 @@ +# Troubleshooting guide + +## First of all + +Always use the latest repository commits from *master* branch. There are always many fixes done almost daily. + +## `./proxmark.sh` or `./flash-*.sh` doesn't see my Proxmark + +Try using directly the client or flasher: + +``` +client/flasher ... +client/proxmark ... +``` + +Refer to the installation guide specific to your OS for details about ports. + +* [Linux](/doc/md/Installation_Instructions/Linux-Installation-Instructions.md) +* [Mac OSX](/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md) +* [Windows](/doc/md/Installation_Instructions/Windows-Installation-Instructions.md) + +Note that with the Bluetooth adapter, you *have to* use directly the client, and flasher over Bluetooth is not possible. + +* [Bluetooth](/doc/md/bt_manual_v10.md) + +## My Proxmark3 seems bricked + +### Maybe just a false alarm? + +The flasher refused to flash your Proxmark3? Are there any messages in *red*? The most common reason is that the Proxmark3 RDV4 firmware recently got a new bootloader able to handle larger firmwares and... the image grew over 256k almost at the same time. So your old bootloader can't flash such new images. But it's easy, you just need to flash *first* the bootloader *only*, then the image. + +``` +./flash-bootrom.sh +./flash-fullimage.sh +``` +or +``` +client/flasher -b bootrom/obj/bootrom.elf +client/flasher armsrc/obj/fullimage.elf +``` + +### Find out why it would be bricked + +The most common reason of a flashing failure is the interference of ModemManager, read carefully [how to avoid ModemManager-related issues](/doc/md/Installation_Instructions/ModemManager-Must-Be-Discarded.md) and fix your setup! + +Another possibility is if, when using the button for entering bootloader mode, the button was released during flashing (for old bootloaders) or the button was pressed again during flashing (for newer bootloaders). + +### Determine if the bootloader was damaged or only the main OS image + +Unplug, press the Proxmark3 button and keep it pressed when you plug it on USB. If the red LEDs show a "off/on/off/on" pattern, you're goot, you manually entered into the bootloader mode. +On new bootloaders, you can release the button. If the pattern disappears, you're on an older bootloader and you've to do it again and keep the button pressed during all the flashing operation. + +Once in bootloader mode, flash the main image. + +``` +./flash-fullimage.sh +``` +or +``` +client/flasher armsrc/obj/fullimage.elf +``` + +You should be back on tracks now. In case the flasher complains about bootloader version, you can follow the button procedure and flash first your bootloader. + +``` +./flash-bootrom.sh +``` +or +``` +client/flasher -b bootrom/obj/bootrom.elf +``` + +### Ok, my bootloader is definitively dead, now what? + +At this point, only reflashing via JTAG can revive your Proxmark3. + +See [details here](/doc/jtag_notes.md). + +## Slow to boot + +You're using another Proxmark3 than a RDV4? +The RDV4 firmware can run on other Proxmark3 as such but the booting procedure is a bit slower because of the absence of SIM and external flash. +Make sure to configure properly your `Makefile.platform` to get a firmware better tuned for your Proxmark3 hardware. +See [details here](/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md). + +## Troubles with SIM card reader + +(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). + +## Troubles with t5577 commands or MFC/iClass/T55x7 dictionaries + +(RDV4 only) Make sure you've set everything up according to the [configuration documentation](/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md#first-things-on-your-rdv40). + +Instructions evolve over time so check if you're still up to date! + +## File not found + +Depending how you launch the client, your working directory might be the root of the repository: + +``` +./proxmark.sh ... +client/proxmark ... +``` + +or the `client/` subdirectory: + +``` +cd client; ./proxmark ... +``` + +Therefore client commands referring to files of the repo must be adapted, e.g. + +``` +pm3 --> sc upgrade f tools/simmodule/SIM011.BIN +<> +pm3 --> sc upgrade f ../tools/simmodule/SIM011.BIN +``` + +``` +pm3 --> mem load f default_keys m +<> +pm3 --> mem load f client/default_keys m +``` + +etc. + +This also affects where your history and logfile will be read from and written to. + From b65baa2e5539ffff1868d028cc02c270a93b20c1 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 28 Jul 2019 21:01:27 +0200 Subject: [PATCH 0179/1854] fix link --- doc/md/Installation_Instructions/Troubleshooting.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/md/Installation_Instructions/Troubleshooting.md b/doc/md/Installation_Instructions/Troubleshooting.md index 7370c7dc0..b4ed877cb 100644 --- a/doc/md/Installation_Instructions/Troubleshooting.md +++ b/doc/md/Installation_Instructions/Troubleshooting.md @@ -21,7 +21,7 @@ Refer to the installation guide specific to your OS for details about ports. Note that with the Bluetooth adapter, you *have to* use directly the client, and flasher over Bluetooth is not possible. -* [Bluetooth](/doc/md/bt_manual_v10.md) +* [Bluetooth](/doc/bt_manual_v10.md) ## My Proxmark3 seems bricked From c6b8e199fdcb1aa9a9d26f7bc464b0afd2c911cf Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 28 Jul 2019 21:08:50 +0200 Subject: [PATCH 0180/1854] fix usart cmd descriptions --- client/cmdusart.c | 4 ++-- include/pm3_cmd.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/client/cmdusart.c b/client/cmdusart.c index 60b977430..5cb1a7b0c 100644 --- a/client/cmdusart.c +++ b/client/cmdusart.c @@ -47,7 +47,7 @@ static int usage_usart_tx(void) { PrintAndLogEx(NORMAL, "Send string over USART"); PrintAndLogEx(NORMAL, _RED_("WARNING: it will have side-effects if used in USART HOST mode!")); PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Usage: usart tx [h] \"string\""); + PrintAndLogEx(NORMAL, "Usage: usart tx [h] d \"string\""); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h This help"); PrintAndLogEx(NORMAL, " d string string to send"); @@ -106,7 +106,7 @@ static int usage_usart_txrx(void) { PrintAndLogEx(NORMAL, _YELLOW_("to add-on when BT connection is not established (LED needs to be blinking)")); PrintAndLogEx(NORMAL, _RED_("Any other usage in USART HOST mode will have side-effects!")); PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Usage: usart txrx [h] [t ] \"string\""); + PrintAndLogEx(NORMAL, "Usage: usart txrx [h] [t ] d \"string\""); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h This help"); PrintAndLogEx(NORMAL, " t timeout in ms, default is 1000ms"); diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 0c7a7d1e6..8c40a795d 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -577,7 +577,7 @@ typedef struct { // uart_windows.c & uart_posix.c # define UART_FPC_CLIENT_RX_TIMEOUT_MS 200 # define UART_USB_CLIENT_RX_TIMEOUT_MS 20 -# define UART_TCP_CLIENT_RX_TIMEOUT_MS 300 +# define UART_TCP_CLIENT_RX_TIMEOUT_MS 500 // CMD_DEVICE_INFO response packet has flags in arg[0], flag definitions: From 8abbbe4d5e369e0f7827bb3583dbbbd04944a5d8 Mon Sep 17 00:00:00 2001 From: netvader <5840601+netvader@users.noreply.github.com> Date: Mon, 29 Jul 2019 11:03:20 +0200 Subject: [PATCH 0181/1854] Update default_keys.dic add hotel key from alltours --- client/default_keys.dic | 1 + 1 file changed, 1 insertion(+) diff --git a/client/default_keys.dic b/client/default_keys.dic index 90e170d87..df9df6fbd 100644 --- a/client/default_keys.dic +++ b/client/default_keys.dic @@ -165,6 +165,7 @@ AAFB06045877, --EPI Envisionte# 3dprinter a05dbd98e0fc, -- CleverFit # d3b595e9dd63, -- Hotel KeyCard +afbecd121004, -- Hotel KeyCard 6471a5ef2d1a, -- SimonsVoss # # 24-7 From 4fad956699b496bcf2d513d329121709088c6b87 Mon Sep 17 00:00:00 2001 From: netvader <5840601+netvader@users.noreply.github.com> Date: Mon, 29 Jul 2019 17:59:19 +0200 Subject: [PATCH 0182/1854] Update termux_notes.md tested Termux sucessfully on Nexux 5X with LineageOS 15.1 which has USB_ACM enabled by default --- doc/termux_notes.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/termux_notes.md b/doc/termux_notes.md index f568c6f16..7e0bada28 100644 --- a/doc/termux_notes.md +++ b/doc/termux_notes.md @@ -19,6 +19,10 @@ ref : https://github.com/Proxmark/proxmark3/wiki/android - [OmniROM (Android 9)](https://www.omnirom.org/) - [OmniROM kernel](https://www.omnirom.org/) - [Magisk 19.3](https://github.com/topjohnwu/Magisk/) +- [Nexus 5X] (arm64, USB-C) +- [LineageOS (Android 8.1)](https://download.lineageos.org/) +- [LineageOS kernel](https://download.lineageos.org/) +- [Magisk 19.3](https://github.com/topjohnwu/Magisk/) ## Setup ### Getting ncurses with termcap From 77b7b614f64628d9cfc3a1441b3a2dd78cea0dc5 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 29 Jul 2019 18:08:42 +0200 Subject: [PATCH 0183/1854] style --- doc/termux_notes.md | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/doc/termux_notes.md b/doc/termux_notes.md index 7e0bada28..a2f883846 100644 --- a/doc/termux_notes.md +++ b/doc/termux_notes.md @@ -14,15 +14,19 @@ From official Proxmark3 wiki: > In any case, you would need a USB-C to A or USB-OTG cable to connect Proxmark3 to your Android device. Some Android devices may not supply enough power (USB-OTG = 100mA), and need a USB Y-cable and external battery, otherwise they will get strange failures. ref : https://github.com/Proxmark/proxmark3/wiki/android -## Tested setup +## Tested setups + - OnePlus 5 (arm64, USB-C) -- [OmniROM (Android 9)](https://www.omnirom.org/) -- [OmniROM kernel](https://www.omnirom.org/) -- [Magisk 19.3](https://github.com/topjohnwu/Magisk/) -- [Nexus 5X] (arm64, USB-C) -- [LineageOS (Android 8.1)](https://download.lineageos.org/) -- [LineageOS kernel](https://download.lineageos.org/) -- [Magisk 19.3](https://github.com/topjohnwu/Magisk/) + + - [OmniROM (Android 9)](https://www.omnirom.org/) + - [OmniROM kernel](https://www.omnirom.org/) + - [Magisk 19.3](https://github.com/topjohnwu/Magisk/) + +- Nexus 5X (arm64, USB-C) + + - [LineageOS (Android 8.1)](https://download.lineageos.org/) + - [LineageOS kernel](https://download.lineageos.org/) + - [Magisk 19.3](https://github.com/topjohnwu/Magisk/) ## Setup ### Getting ncurses with termcap From 6d1c996251ed5650684b505945bfbc9ac9cf51d4 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 30 Jul 2019 19:22:24 +0200 Subject: [PATCH 0184/1854] chg: flashing - test messages --- client/flash.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/client/flash.c b/client/flash.c index f2f0b526a..ab41e090d 100644 --- a/client/flash.c +++ b/client/flash.c @@ -378,12 +378,12 @@ static int wait_for_ack(PacketResponseNG *ack) { } static void flash_suggest_update_bootloader(void) { - PrintAndLogEx(ERR, _RED_("It is recommended that you first update your bootloader alone,")); + PrintAndLogEx(ERR, _RED_("It is recommended that you first" _YELLOW_("update your bootloader") " alone,")); PrintAndLogEx(ERR, _RED_("reboot the Proxmark3 then only update the main firmware") "\n"); } static void flash_suggest_update_flasher(void) { - PrintAndLogEx(ERR, _RED_("It is recommended that you first update your flasher")); + PrintAndLogEx(ERR, _RED_("It is recommended that you first" _YELLOW_("update your flasher") )); } // Go into flashing mode @@ -413,18 +413,22 @@ int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t if ((BL_VERSION_MAJOR(version) < BL_VERSION_FIRST_MAJOR) || (BL_VERSION_MAJOR(version) > BL_VERSION_LAST_MAJOR)) { // version info seems fishy version = BL_VERSION_INVALID; + PrintAndLogEx(ERR, _RED_("====================== OBS ! ===========================")); PrintAndLogEx(ERR, _RED_("Note: Your bootloader reported an invalid version number")); flash_suggest_update_bootloader(); // } else if (BL_VERSION_MAJOR(version) < BL_VERSION_MAJOR(FLASHER_VERSION)) { + PrintAndLogEx(ERR, _RED_("====================== OBS ! ===================================")); PrintAndLogEx(ERR, _RED_("Note: Your bootloader reported a version older than this flasher")); flash_suggest_update_bootloader(); } else if (BL_VERSION_MAJOR(version) > BL_VERSION_MAJOR(FLASHER_VERSION)) { + PrintAndLogEx(ERR, _RED_("====================== OBS ! =========================")); PrintAndLogEx(ERR, _RED_("Note: Your bootloader is more recent than this flasher")); flash_suggest_update_flasher(); } } else { - PrintAndLogEx(ERR, _RED_("Note: Your bootloader does not understand the new CMD_BL_VERSION command")); + PrintAndLogEx(ERR, _RED_("====================== OBS ! ===========================================")); + PrintAndLogEx(ERR, _RED_("Note: Your bootloader does not understand the new" _YELLOW_("CMD_BL_VERSION") " command")); flash_suggest_update_bootloader(); } @@ -436,6 +440,7 @@ int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t PrintAndLogEx(NORMAL, "Available memory on this board: %uK bytes\n", mem_avail); if (mem_avail > 256) { if (BL_VERSION_MAJOR(version) < BL_VERSION_MAJOR(BL_VERSION_1_0_0)) { + PrintAndLogEx(ERR, _RED_("====================== OBS ! ======================")); PrintAndLogEx(ERR, _RED_("Your bootloader does not support writing above 256k")); flash_suggest_update_bootloader(); } else { @@ -445,7 +450,8 @@ int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t } } else { PrintAndLogEx(NORMAL, "Available memory on this board: "_RED_("UNKNOWN")"\n"); - PrintAndLogEx(ERR, _RED_("Note: Your bootloader does not understand the new CHIP_INFO command")); + PrintAndLogEx(ERR, _RED_("====================== OBS ! ======================================")); + PrintAndLogEx(ERR, _RED_("Note: Your bootloader does not understand the new" _YELLOW_("CHIP_INFO") " command")); flash_suggest_update_bootloader(); } @@ -464,7 +470,8 @@ int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t } return wait_for_ack(&resp); } else { - PrintAndLogEx(ERR, _RED_("Note: Your bootloader does not understand the new START_FLASH command")); + PrintAndLogEx(ERR, _RED_("====================== OBS ! ========================================")); + PrintAndLogEx(ERR, _RED_("Note: Your bootloader does not understand the new" _YELLOW_("START_FLASH") " command")); flash_suggest_update_bootloader(); } return 0; From 4c9b95c2169a369bc1912fa03d9773a79b7c4c27 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 30 Jul 2019 14:31:10 -0400 Subject: [PATCH 0185/1854] chg: flash messge --- client/flash.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/client/flash.c b/client/flash.c index ab41e090d..732d0ef02 100644 --- a/client/flash.c +++ b/client/flash.c @@ -378,12 +378,12 @@ static int wait_for_ack(PacketResponseNG *ack) { } static void flash_suggest_update_bootloader(void) { - PrintAndLogEx(ERR, _RED_("It is recommended that you first" _YELLOW_("update your bootloader") " alone,")); + PrintAndLogEx(ERR, _RED_("It is recommended that you first " _YELLOW_("update your bootloader") _RED_("alone,"))); PrintAndLogEx(ERR, _RED_("reboot the Proxmark3 then only update the main firmware") "\n"); } static void flash_suggest_update_flasher(void) { - PrintAndLogEx(ERR, _RED_("It is recommended that you first" _YELLOW_("update your flasher") )); + PrintAndLogEx(ERR, _RED_("It is recommended that you first " _YELLOW_("update your flasher"))); } // Go into flashing mode @@ -418,17 +418,17 @@ int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t flash_suggest_update_bootloader(); // } else if (BL_VERSION_MAJOR(version) < BL_VERSION_MAJOR(FLASHER_VERSION)) { - PrintAndLogEx(ERR, _RED_("====================== OBS ! ===================================")); + PrintAndLogEx(ERR, _RED_("====================== OBS ! ===================================")); PrintAndLogEx(ERR, _RED_("Note: Your bootloader reported a version older than this flasher")); flash_suggest_update_bootloader(); } else if (BL_VERSION_MAJOR(version) > BL_VERSION_MAJOR(FLASHER_VERSION)) { - PrintAndLogEx(ERR, _RED_("====================== OBS ! =========================")); + PrintAndLogEx(ERR, _RED_("====================== OBS ! =========================")); PrintAndLogEx(ERR, _RED_("Note: Your bootloader is more recent than this flasher")); flash_suggest_update_flasher(); } } else { PrintAndLogEx(ERR, _RED_("====================== OBS ! ===========================================")); - PrintAndLogEx(ERR, _RED_("Note: Your bootloader does not understand the new" _YELLOW_("CMD_BL_VERSION") " command")); + PrintAndLogEx(ERR, _RED_("Note: Your bootloader does not understand the new " _YELLOW_("CMD_BL_VERSION") _RED_("command"))); flash_suggest_update_bootloader(); } @@ -437,10 +437,10 @@ int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t int mem_avail = chipid_to_mem_avail(chipinfo); if (mem_avail != 0) { - PrintAndLogEx(NORMAL, "Available memory on this board: %uK bytes\n", mem_avail); + PrintAndLogEx(NORMAL, "Available memory on this board: "_YELLOW_("%uK") "bytes\n", mem_avail); if (mem_avail > 256) { if (BL_VERSION_MAJOR(version) < BL_VERSION_MAJOR(BL_VERSION_1_0_0)) { - PrintAndLogEx(ERR, _RED_("====================== OBS ! ======================")); + PrintAndLogEx(ERR, _RED_("====================== OBS ! ======================")); PrintAndLogEx(ERR, _RED_("Your bootloader does not support writing above 256k")); flash_suggest_update_bootloader(); } else { @@ -451,7 +451,7 @@ int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t } else { PrintAndLogEx(NORMAL, "Available memory on this board: "_RED_("UNKNOWN")"\n"); PrintAndLogEx(ERR, _RED_("====================== OBS ! ======================================")); - PrintAndLogEx(ERR, _RED_("Note: Your bootloader does not understand the new" _YELLOW_("CHIP_INFO") " command")); + PrintAndLogEx(ERR, _RED_("Note: Your bootloader does not understand the new " _YELLOW_("CHIP_INFO") _RED_("command"))); flash_suggest_update_bootloader(); } @@ -471,7 +471,7 @@ int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t return wait_for_ack(&resp); } else { PrintAndLogEx(ERR, _RED_("====================== OBS ! ========================================")); - PrintAndLogEx(ERR, _RED_("Note: Your bootloader does not understand the new" _YELLOW_("START_FLASH") " command")); + PrintAndLogEx(ERR, _RED_("Note: Your bootloader does not understand the new " _YELLOW_("START_FLASH") _RED_("command"))); flash_suggest_update_bootloader(); } return 0; From cb439ef58b07c01d234564dbba96170b13ac8436 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 30 Jul 2019 22:47:23 +0200 Subject: [PATCH 0186/1854] style of .v files --- Makefile | 8 +- fpga/clk_divider.v | 24 +- fpga/fpga_hf.v | 110 ++--- fpga/fpga_lf.v | 110 ++--- fpga/hi_flite.v | 160 +++--- fpga/hi_iso14443a.v | 616 ++++++++++++------------ fpga/hi_read_rx_xcorr.v | 30 +- fpga/hi_read_tx.v | 4 +- fpga/hi_simulate.v | 2 +- fpga/lf_edge_detect.v | 112 ++--- fpga/lo_edge_detect.v | 12 +- fpga/lo_passthru.v | 14 +- fpga/lo_read.v | 36 +- fpga/lo_simulate.v | 38 +- fpga/lp20khz_1MSa_iir_filter.v | 92 ++-- fpga/min_max_tracker.v | 88 ++-- fpga/testbed_fpga.v | 48 +- fpga/testbed_hi_read_tx.v | 180 +++---- fpga/testbed_hi_simulate.v | 190 ++++---- fpga/testbed_lo_read.v | 168 +++---- fpga/testbed_lo_simulate.v | 162 +++---- fpga/tests/tb_lf_edge_detect.v | 146 +++--- fpga/tests/tb_lp20khz_1MSa_iir_filter.v | 66 +-- fpga/tests/tb_min_max_tracker.v | 98 ++-- 24 files changed, 1257 insertions(+), 1257 deletions(-) diff --git a/Makefile b/Makefile index 587fdf09d..5817b80bf 100644 --- a/Makefile +++ b/Makefile @@ -145,7 +145,7 @@ style: # Make sure astyle is installed @which astyle >/dev/null || ( echo "Please install 'astyle' package first" ; exit 1 ) # Remove spaces & tabs at EOL, add LF at EOF if needed on *.c, *.h, *.cpp. *.lua, *.py, *.pl, Makefile - find . \( -name "*.[ch]" -or \( -name "*.cpp" -and -not -name "*.moc.cpp" \) -or -name "*.lua" -or -name "*.py" -or -name "*.pl" -or -name "Makefile" \) \ + find . \( -name "*.[ch]" -or \( -name "*.cpp" -and -not -name "*.moc.cpp" \) -or -name "*.lua" -or -name "*.py" -or -name "*.pl" -or -name "Makefile" -or -name "*.v" \) \ -exec perl -pi -e 's/[ \t]+$$//' {} \; \ -exec sh -c "tail -c1 {} | xxd -p | tail -1 | grep -q -v 0a$$" \; \ -exec sh -c "echo >> {}" \; @@ -158,11 +158,11 @@ style: # Detecting weird codepages and tabs. checks: - find . \( -name "*.[ch]" -or -name "*.cpp" -or -name "*.lua" -or -name "*.py" -or -name "*.pl" -or -name "Makefile" \) \ + find . \( -name "*.[ch]" -or -name "*.cpp" -or -name "*.lua" -or -name "*.py" -or -name "*.pl" -or -name "Makefile" -or -name "*.v" \) \ -exec sh -c "cat {} |recode utf8.. >/dev/null || echo {}" \; - find . \( -name "*.[ch]" -or \( -name "*.cpp" -and -not -name "*.moc.cpp" \) -or -name "*.lua" -or -name "*.py" -or -name "*.pl" -or -name "*.md" -or -name "*.txt" -or -name "*.awk" \) \ + find . \( -name "*.[ch]" -or \( -name "*.cpp" -and -not -name "*.moc.cpp" \) -or -name "*.lua" -or -name "*.py" -or -name "*.pl" -or -name "*.md" -or -name "*.txt" -or -name "*.awk" -or -name "*.v" \) \ -exec grep -lP '\t' {} \; -# to remove tabs within lines, one can try with vi: :set tabstop=4 :set et|retab +# to remove tabs within lines, one can try with: vi $file -c ':set tabstop=4' -c ':set et|retab' -c ':wq' # Dummy target to test for GNU make availability _test: diff --git a/fpga/clk_divider.v b/fpga/clk_divider.v index 882af5cc8..9a57879b0 100644 --- a/fpga/clk_divider.v +++ b/fpga/clk_divider.v @@ -7,19 +7,19 @@ //----------------------------------------------------------------------------- module clk_divider(input clk, input [7:0] divisor, output [7:0] div_cnt, output div_clk); - reg [7:0] div_cnt_ = 0; - reg div_clk_; - assign div_cnt = div_cnt_; - assign div_clk = div_clk_; + reg [7:0] div_cnt_ = 0; + reg div_clk_; + assign div_cnt = div_cnt_; + assign div_clk = div_clk_; - always @(posedge clk) - begin - if(div_cnt == divisor) begin - div_cnt_ <= 8'd0; - div_clk_ = !div_clk_; - end else - div_cnt_ <= div_cnt_ + 1; - end + always @(posedge clk) + begin + if(div_cnt == divisor) begin + div_cnt_ <= 8'd0; + div_clk_ = !div_clk_; + end else + div_cnt_ <= div_cnt_ + 1; + end endmodule diff --git a/fpga/fpga_hf.v b/fpga/fpga_hf.v index 7593d8aeb..0dc26b6ec 100644 --- a/fpga/fpga_hf.v +++ b/fpga/fpga_hf.v @@ -22,14 +22,14 @@ `include "hi_flite.v" module fpga_hf( - input spck, output miso, input mosi, input ncs, - input pck0, input ck_1356meg, input ck_1356megb, - output pwr_lo, output pwr_hi, - output pwr_oe1, output pwr_oe2, output pwr_oe3, output pwr_oe4, - input [7:0] adc_d, output adc_clk, output adc_noe, - output ssp_frame, output ssp_din, input ssp_dout, output ssp_clk, - input cross_hi, input cross_lo, - output dbg + input spck, output miso, input mosi, input ncs, + input pck0, input ck_1356meg, input ck_1356megb, + output pwr_lo, output pwr_hi, + output pwr_oe1, output pwr_oe2, output pwr_oe3, output pwr_oe4, + input [7:0] adc_d, output adc_clk, output adc_noe, + output ssp_frame, output ssp_din, input ssp_dout, output ssp_clk, + input cross_hi, input cross_lo, + output dbg ); //----------------------------------------------------------------------------- @@ -47,18 +47,18 @@ reg [7:0] conf_word; // glitching, or else we will glitch the transmitted carrier. always @(posedge ncs) begin - case(shift_reg[15:12]) - 4'b0001: conf_word <= shift_reg[7:0]; // FPGA_CMD_SET_CONFREG - endcase + case(shift_reg[15:12]) + 4'b0001: conf_word <= shift_reg[7:0]; // FPGA_CMD_SET_CONFREG + endcase end always @(posedge spck) begin - if(~ncs) - begin - shift_reg[15:1] <= shift_reg[14:0]; - shift_reg[0] <= mosi; - end + if(~ncs) + begin + shift_reg[15:1] <= shift_reg[14:0]; + shift_reg[0] <= mosi; + end end wire [2:0] major_mode; @@ -87,43 +87,43 @@ wire [2:0] hi_simulate_mod_type = conf_word[2:0]; //----------------------------------------------------------------------------- hi_read_tx ht( - pck0, ck_1356meg, ck_1356megb, - ht_pwr_lo, ht_pwr_hi, ht_pwr_oe1, ht_pwr_oe2, ht_pwr_oe3, ht_pwr_oe4, - adc_d, ht_adc_clk, - ht_ssp_frame, ht_ssp_din, ssp_dout, ht_ssp_clk, - cross_hi, cross_lo, - ht_dbg, - hi_read_tx_shallow_modulation + pck0, ck_1356meg, ck_1356megb, + ht_pwr_lo, ht_pwr_hi, ht_pwr_oe1, ht_pwr_oe2, ht_pwr_oe3, ht_pwr_oe4, + adc_d, ht_adc_clk, + ht_ssp_frame, ht_ssp_din, ssp_dout, ht_ssp_clk, + cross_hi, cross_lo, + ht_dbg, + hi_read_tx_shallow_modulation ); hi_read_rx_xcorr hrxc( - pck0, ck_1356meg, ck_1356megb, - hrxc_pwr_lo, hrxc_pwr_hi, hrxc_pwr_oe1, hrxc_pwr_oe2, hrxc_pwr_oe3, hrxc_pwr_oe4, - adc_d, hrxc_adc_clk, - hrxc_ssp_frame, hrxc_ssp_din, ssp_dout, hrxc_ssp_clk, - cross_hi, cross_lo, - hrxc_dbg, - hi_read_rx_xcorr_848, hi_read_rx_xcorr_snoop, hi_read_rx_xcorr_quarter + pck0, ck_1356meg, ck_1356megb, + hrxc_pwr_lo, hrxc_pwr_hi, hrxc_pwr_oe1, hrxc_pwr_oe2, hrxc_pwr_oe3, hrxc_pwr_oe4, + adc_d, hrxc_adc_clk, + hrxc_ssp_frame, hrxc_ssp_din, ssp_dout, hrxc_ssp_clk, + cross_hi, cross_lo, + hrxc_dbg, + hi_read_rx_xcorr_848, hi_read_rx_xcorr_snoop, hi_read_rx_xcorr_quarter ); hi_simulate hs( - pck0, ck_1356meg, ck_1356megb, - hs_pwr_lo, hs_pwr_hi, hs_pwr_oe1, hs_pwr_oe2, hs_pwr_oe3, hs_pwr_oe4, - adc_d, hs_adc_clk, - hs_ssp_frame, hs_ssp_din, ssp_dout, hs_ssp_clk, - cross_hi, cross_lo, - hs_dbg, - hi_simulate_mod_type + pck0, ck_1356meg, ck_1356megb, + hs_pwr_lo, hs_pwr_hi, hs_pwr_oe1, hs_pwr_oe2, hs_pwr_oe3, hs_pwr_oe4, + adc_d, hs_adc_clk, + hs_ssp_frame, hs_ssp_din, ssp_dout, hs_ssp_clk, + cross_hi, cross_lo, + hs_dbg, + hi_simulate_mod_type ); hi_iso14443a hisn( - pck0, ck_1356meg, ck_1356megb, - hisn_pwr_lo, hisn_pwr_hi, hisn_pwr_oe1, hisn_pwr_oe2, hisn_pwr_oe3, hisn_pwr_oe4, - adc_d, hisn_adc_clk, - hisn_ssp_frame, hisn_ssp_din, ssp_dout, hisn_ssp_clk, - cross_hi, cross_lo, - hisn_dbg, - hi_simulate_mod_type + pck0, ck_1356meg, ck_1356megb, + hisn_pwr_lo, hisn_pwr_hi, hisn_pwr_oe1, hisn_pwr_oe2, hisn_pwr_oe3, hisn_pwr_oe4, + adc_d, hisn_adc_clk, + hisn_ssp_frame, hisn_ssp_din, ssp_dout, hisn_ssp_clk, + cross_hi, cross_lo, + hisn_dbg, + hi_simulate_mod_type ); hi_sniffer he( @@ -157,17 +157,17 @@ hi_flite hfl( // 110 -- none // 111 -- everything off -mux8 mux_ssp_clk (major_mode, ssp_clk, ht_ssp_clk, hrxc_ssp_clk, hs_ssp_clk, hisn_ssp_clk, he_ssp_clk, hfl_ssp_clk, 1'b0, 1'b0); -mux8 mux_ssp_din (major_mode, ssp_din, ht_ssp_din, hrxc_ssp_din, hs_ssp_din, hisn_ssp_din, he_ssp_din, hfl_ssp_din, 1'b0, 1'b0); -mux8 mux_ssp_frame (major_mode, ssp_frame, ht_ssp_frame, hrxc_ssp_frame, hs_ssp_frame, hisn_ssp_frame, he_ssp_frame, hfl_ssp_frame, 1'b0, 1'b0); -mux8 mux_pwr_oe1 (major_mode, pwr_oe1, ht_pwr_oe1, hrxc_pwr_oe1, hs_pwr_oe1, hisn_pwr_oe1, he_pwr_oe1, hfl_pwr_oe1, 1'b0, 1'b0); -mux8 mux_pwr_oe2 (major_mode, pwr_oe2, ht_pwr_oe2, hrxc_pwr_oe2, hs_pwr_oe2, hisn_pwr_oe2, he_pwr_oe2, hfl_pwr_oe2, 1'b0, 1'b0); -mux8 mux_pwr_oe3 (major_mode, pwr_oe3, ht_pwr_oe3, hrxc_pwr_oe3, hs_pwr_oe3, hisn_pwr_oe3, he_pwr_oe3, hfl_pwr_oe3, 1'b0, 1'b0); -mux8 mux_pwr_oe4 (major_mode, pwr_oe4, ht_pwr_oe4, hrxc_pwr_oe4, hs_pwr_oe4, hisn_pwr_oe4, he_pwr_oe4, hfl_pwr_oe4, 1'b0, 1'b0); -mux8 mux_pwr_lo (major_mode, pwr_lo, ht_pwr_lo, hrxc_pwr_lo, hs_pwr_lo, hisn_pwr_lo, he_pwr_lo, hfl_pwr_lo, 1'b0, 1'b0); -mux8 mux_pwr_hi (major_mode, pwr_hi, ht_pwr_hi, hrxc_pwr_hi, hs_pwr_hi, hisn_pwr_hi, he_pwr_hi, hfl_pwr_hi, 1'b0, 1'b0); -mux8 mux_adc_clk (major_mode, adc_clk, ht_adc_clk, hrxc_adc_clk, hs_adc_clk, hisn_adc_clk, he_adc_clk, hfl_adc_clk, 1'b0, 1'b0); -mux8 mux_dbg (major_mode, dbg, ht_dbg, hrxc_dbg, hs_dbg, hisn_dbg, he_dbg, hfl_dbg, 1'b0, 1'b0); +mux8 mux_ssp_clk (major_mode, ssp_clk, ht_ssp_clk, hrxc_ssp_clk, hs_ssp_clk, hisn_ssp_clk, he_ssp_clk, hfl_ssp_clk, 1'b0, 1'b0); +mux8 mux_ssp_din (major_mode, ssp_din, ht_ssp_din, hrxc_ssp_din, hs_ssp_din, hisn_ssp_din, he_ssp_din, hfl_ssp_din, 1'b0, 1'b0); +mux8 mux_ssp_frame (major_mode, ssp_frame, ht_ssp_frame, hrxc_ssp_frame, hs_ssp_frame, hisn_ssp_frame, he_ssp_frame, hfl_ssp_frame, 1'b0, 1'b0); +mux8 mux_pwr_oe1 (major_mode, pwr_oe1, ht_pwr_oe1, hrxc_pwr_oe1, hs_pwr_oe1, hisn_pwr_oe1, he_pwr_oe1, hfl_pwr_oe1, 1'b0, 1'b0); +mux8 mux_pwr_oe2 (major_mode, pwr_oe2, ht_pwr_oe2, hrxc_pwr_oe2, hs_pwr_oe2, hisn_pwr_oe2, he_pwr_oe2, hfl_pwr_oe2, 1'b0, 1'b0); +mux8 mux_pwr_oe3 (major_mode, pwr_oe3, ht_pwr_oe3, hrxc_pwr_oe3, hs_pwr_oe3, hisn_pwr_oe3, he_pwr_oe3, hfl_pwr_oe3, 1'b0, 1'b0); +mux8 mux_pwr_oe4 (major_mode, pwr_oe4, ht_pwr_oe4, hrxc_pwr_oe4, hs_pwr_oe4, hisn_pwr_oe4, he_pwr_oe4, hfl_pwr_oe4, 1'b0, 1'b0); +mux8 mux_pwr_lo (major_mode, pwr_lo, ht_pwr_lo, hrxc_pwr_lo, hs_pwr_lo, hisn_pwr_lo, he_pwr_lo, hfl_pwr_lo, 1'b0, 1'b0); +mux8 mux_pwr_hi (major_mode, pwr_hi, ht_pwr_hi, hrxc_pwr_hi, hs_pwr_hi, hisn_pwr_hi, he_pwr_hi, hfl_pwr_hi, 1'b0, 1'b0); +mux8 mux_adc_clk (major_mode, adc_clk, ht_adc_clk, hrxc_adc_clk, hs_adc_clk, hisn_adc_clk, he_adc_clk, hfl_adc_clk, 1'b0, 1'b0); +mux8 mux_dbg (major_mode, dbg, ht_dbg, hrxc_dbg, hs_dbg, hisn_dbg, he_dbg, hfl_dbg, 1'b0, 1'b0); // In all modes, let the ADC's outputs be enabled. assign adc_noe = 1'b0; diff --git a/fpga/fpga_lf.v b/fpga/fpga_lf.v index 2c0a498d0..eba43b32f 100644 --- a/fpga/fpga_lf.v +++ b/fpga/fpga_lf.v @@ -10,14 +10,14 @@ `include "clk_divider.v" module fpga_lf( - input spck, output miso, input mosi, input ncs, - input pck0, input ck_1356meg, input ck_1356megb, - output pwr_lo, output pwr_hi, - output pwr_oe1, output pwr_oe2, output pwr_oe3, output pwr_oe4, - input [7:0] adc_d, output adc_clk, output adc_noe, - output ssp_frame, output ssp_din, input ssp_dout, output ssp_clk, - input cross_hi, input cross_lo, - output dbg + input spck, output miso, input mosi, input ncs, + input pck0, input ck_1356meg, input ck_1356megb, + output pwr_lo, output pwr_hi, + output pwr_oe1, output pwr_oe2, output pwr_oe3, output pwr_oe4, + input [7:0] adc_d, output adc_clk, output adc_noe, + output ssp_frame, output ssp_din, input ssp_dout, output ssp_clk, + input cross_hi, input cross_lo, + output dbg ); //----------------------------------------------------------------------------- @@ -34,26 +34,26 @@ reg [7:0] user_byte1; always @(posedge ncs) begin - case(shift_reg[15:12]) - 4'b0001: - begin - conf_word <= shift_reg[7:0]; - if (shift_reg[7:0] == 8'b00000001) begin // LF edge detect - user_byte1 <= 127; // default threshold - end - end - 4'b0010: divisor <= shift_reg[7:0]; // FPGA_CMD_SET_DIVISOR - 4'b0011: user_byte1 <= shift_reg[7:0]; // FPGA_CMD_SET_USER_BYTE1 - endcase + case(shift_reg[15:12]) + 4'b0001: + begin + conf_word <= shift_reg[7:0]; + if (shift_reg[7:0] == 8'b00000001) begin // LF edge detect + user_byte1 <= 127; // default threshold + end + end + 4'b0010: divisor <= shift_reg[7:0]; // FPGA_CMD_SET_DIVISOR + 4'b0011: user_byte1 <= shift_reg[7:0]; // FPGA_CMD_SET_USER_BYTE1 + endcase end always @(posedge spck) begin - if(~ncs) - begin - shift_reg[15:1] <= shift_reg[14:0]; - shift_reg[0] <= mosi; - end + if(~ncs) + begin + shift_reg[15:1] <= shift_reg[14:0]; + shift_reg[0] <= mosi; + end end wire [2:0] major_mode = conf_word[7:5]; @@ -73,51 +73,51 @@ wire pck_divclk; clk_divider div_clk(pck0, divisor, pck_cnt, pck_divclk); lo_read lr( - pck0, pck_cnt, pck_divclk, - lr_pwr_lo, lr_pwr_hi, lr_pwr_oe1, lr_pwr_oe2, lr_pwr_oe3, lr_pwr_oe4, - adc_d, lr_adc_clk, - lr_ssp_frame, lr_ssp_din, lr_ssp_clk, - lr_dbg, lf_field + pck0, pck_cnt, pck_divclk, + lr_pwr_lo, lr_pwr_hi, lr_pwr_oe1, lr_pwr_oe2, lr_pwr_oe3, lr_pwr_oe4, + adc_d, lr_adc_clk, + lr_ssp_frame, lr_ssp_din, lr_ssp_clk, + lr_dbg, lf_field ); lo_passthru lp( - pck_divclk, - lp_pwr_lo, lp_pwr_hi, lp_pwr_oe1, lp_pwr_oe2, lp_pwr_oe3, lp_pwr_oe4, - lp_adc_clk, - lp_ssp_din, ssp_dout, - cross_lo, - lp_dbg + pck_divclk, + lp_pwr_lo, lp_pwr_hi, lp_pwr_oe1, lp_pwr_oe2, lp_pwr_oe3, lp_pwr_oe4, + lp_adc_clk, + lp_ssp_din, ssp_dout, + cross_lo, + lp_dbg ); lo_edge_detect le( - pck0, pck_divclk, - le_pwr_lo, le_pwr_hi, le_pwr_oe1, le_pwr_oe2, le_pwr_oe3, le_pwr_oe4, - adc_d, le_adc_clk, - le_ssp_frame, ssp_dout, le_ssp_clk, - cross_lo, - le_dbg, - lf_field, - lf_ed_toggle_mode, lf_ed_threshold + pck0, pck_divclk, + le_pwr_lo, le_pwr_hi, le_pwr_oe1, le_pwr_oe2, le_pwr_oe3, le_pwr_oe4, + adc_d, le_adc_clk, + le_ssp_frame, ssp_dout, le_ssp_clk, + cross_lo, + le_dbg, + lf_field, + lf_ed_toggle_mode, lf_ed_threshold ); // Major modes: // 000 -- LF reader (generic) // 001 -- LF edge detect (generic) // 010 -- LF passthrough -// 110 -- FPGA_MAJOR_MODE_OFF_LF (rdv40 specific) +// 110 -- FPGA_MAJOR_MODE_OFF_LF (rdv40 specific) // 111 -- FPGA_MAJOR_MODE_OFF // 000 001 010 011 100 101 110 111 -mux8 mux_ssp_clk (major_mode, ssp_clk, lr_ssp_clk, le_ssp_clk, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_ssp_din (major_mode, ssp_din, lr_ssp_din, 1'b0, lp_ssp_din, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_ssp_frame (major_mode, ssp_frame, lr_ssp_frame, le_ssp_frame, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_pwr_oe1 (major_mode, pwr_oe1, lr_pwr_oe1, le_pwr_oe1, lp_pwr_oe1, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_pwr_oe2 (major_mode, pwr_oe2, lr_pwr_oe2, le_pwr_oe2, lp_pwr_oe2, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_pwr_oe3 (major_mode, pwr_oe3, lr_pwr_oe3, le_pwr_oe3, lp_pwr_oe3, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_pwr_oe4 (major_mode, pwr_oe4, lr_pwr_oe4, le_pwr_oe4, lp_pwr_oe4, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_pwr_lo (major_mode, pwr_lo, lr_pwr_lo, le_pwr_lo, lp_pwr_lo, 1'b0, 1'b0, 1'b0, 1'b1, 1'b0); -mux8 mux_pwr_hi (major_mode, pwr_hi, lr_pwr_hi, le_pwr_hi, lp_pwr_hi, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_adc_clk (major_mode, adc_clk, lr_adc_clk, le_adc_clk, lp_adc_clk, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_dbg (major_mode, dbg, lr_dbg, le_dbg, lp_dbg, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0); +mux8 mux_ssp_clk (major_mode, ssp_clk, lr_ssp_clk, le_ssp_clk, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0); +mux8 mux_ssp_din (major_mode, ssp_din, lr_ssp_din, 1'b0, lp_ssp_din, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0); +mux8 mux_ssp_frame (major_mode, ssp_frame, lr_ssp_frame, le_ssp_frame, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0); +mux8 mux_pwr_oe1 (major_mode, pwr_oe1, lr_pwr_oe1, le_pwr_oe1, lp_pwr_oe1, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0); +mux8 mux_pwr_oe2 (major_mode, pwr_oe2, lr_pwr_oe2, le_pwr_oe2, lp_pwr_oe2, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0); +mux8 mux_pwr_oe3 (major_mode, pwr_oe3, lr_pwr_oe3, le_pwr_oe3, lp_pwr_oe3, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0); +mux8 mux_pwr_oe4 (major_mode, pwr_oe4, lr_pwr_oe4, le_pwr_oe4, lp_pwr_oe4, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0); +mux8 mux_pwr_lo (major_mode, pwr_lo, lr_pwr_lo, le_pwr_lo, lp_pwr_lo, 1'b0, 1'b0, 1'b0, 1'b1, 1'b0); +mux8 mux_pwr_hi (major_mode, pwr_hi, lr_pwr_hi, le_pwr_hi, lp_pwr_hi, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0); +mux8 mux_adc_clk (major_mode, adc_clk, lr_adc_clk, le_adc_clk, lp_adc_clk, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0); +mux8 mux_dbg (major_mode, dbg, lr_dbg, le_dbg, lp_dbg, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0); // In all modes, let the ADC's outputs be enabled. assign adc_noe = 1'b0; diff --git a/fpga/hi_flite.v b/fpga/hi_flite.v index 86f03c3ab..18d3a46ac 100644 --- a/fpga/hi_flite.v +++ b/fpga/hi_flite.v @@ -1,9 +1,9 @@ //this code demodulates and modulates signal as described in ISO/IEC 18092. That includes packets used for Felica, NFC Tag 3, etc. (which do overlap) -//simple envelope following algorithm is used (modification of fail0verflow LF one) is used to combat some nasty aliasing effect with testing phone (envelope looked like sine wave) +//simple envelope following algorithm is used (modification of fail0verflow LF one) is used to combat some nasty aliasing effect with testing phone (envelope looked like sine wave) // only 212 kbps (fc/64) for now 414 is relatively straightforward... though for reader, the selection has to come from ARM -// modulation waits for -//market sprocket -doesn't really mean anything ;) +// modulation waits for +//market sprocket -doesn't really mean anything ;) //redefining mod_type: bits 210: bit 2 - reader drive/power on/off, bit 1 - speed bit, 0:212, 1 -424 bit 0: listen or modulate @@ -15,7 +15,7 @@ module hi_flite( cross_hi, cross_lo, dbg, mod_type // used - + ); input pck0, ck_1356meg, ck_1356megb; output pwr_lo, pwr_hi, pwr_oe1, pwr_oe2, pwr_oe3, pwr_oe4; @@ -33,7 +33,7 @@ wire speed= mod_type[1]; wire disabl= mod_type[0]; // Most off, oe4 for modulation; -// Trying reader emulation (would presumably just require switching power on, but I am not sure) +// Trying reader emulation (would presumably just require switching power on, but I am not sure) //;// 1'b0; assign pwr_lo = 1'b0; @@ -55,7 +55,7 @@ assign adc_clk = ck_1356meg; //minimum values and corresponding thresholds reg [8:0] curmin=`imin; -reg [8:0] curminthres=`ithrmin; +reg [8:0] curminthres=`ithrmin; reg [8:0] curmaxthres=`ithrmax; reg [8:0] curmax=`imax; @@ -103,37 +103,37 @@ always @(posedge adc_clk) ssp_cnt <= (ssp_cnt + 1); //maybe change it so that ARM sends preamble as well. -//then: ready bits sent to ARM, 8 bits sent from ARM (all ones), then preamble (all zeros, presumably) - which starts modulation - +//then: ready bits sent to ARM, 8 bits sent from ARM (all ones), then preamble (all zeros, presumably) - which starts modulation + always @(negedge adc_clk) begin //count fc/64 - transfer bits to ARM at the rate they are received if( ((~speed) && (ssp_cnt[5:0] == 6'b000000)) || (speed &&(ssp_cnt[4:0] == 5'b00000))) begin - ssp_clk <= 1'b1; + ssp_clk <= 1'b1; // if(mod_type[2]) // begin // ssp_din<=outp[0];//after_hysteresis; - - //outp<={1'b0,outp[7:1]}; + + //outp<={1'b0,outp[7:1]}; // end // else - ssp_din <= curbit; - + ssp_din <= curbit; + //sample ssp_dout - + end - if( ( (~speed) && (ssp_cnt[5:0] == 6'b100000)) ||(speed && ssp_cnt[4:0] == 5'b10000)) - ssp_clk <= 1'b0; + if( ( (~speed) && (ssp_cnt[5:0] == 6'b100000)) ||(speed && ssp_cnt[4:0] == 5'b10000)) + ssp_clk <= 1'b0; //create frame pulses. TBH, I still don't know what they do exactly, but they are crucial for ARM->FPGA transfer. If the frame is in the beginning of the byte, transfer slows to a crawl for some reason - // took me a day to figure THAT out. + // took me a day to figure THAT out. if(( (~speed) && (ssp_cnt[8:0] == 9'd31))||(speed && ssp_cnt[7:0] == 8'd15)) begin - ssp_frame <= 1'b1; + ssp_frame <= 1'b1; end if(( (~speed) && (ssp_cnt[8:0] == 9'b1011111))||(speed &&ssp_cnt[7:0] == 8'b101111) ) begin - ssp_frame <= 1'b0; + ssp_frame <= 1'b0; end end @@ -141,23 +141,23 @@ end //send current bit (detected in SNIFF mode or the one being modulated in MOD mode, 0 otherwise) -reg ssp_din;//= outp[0]; - - +reg ssp_din;//= outp[0]; + + //previous signal value, mostly to detect SYNC reg prv =1'b1; -reg[7:0] mid=8'd128; //for simple error correction in mod/demod detection, use maximum of modded/demodded in given interval. Maybe 1 bit is extra? but better safe than sorry. +reg[7:0] mid=8'd128; //for simple error correction in mod/demod detection, use maximum of modded/demodded in given interval. Maybe 1 bit is extra? but better safe than sorry. // set TAGSIM__MODULATE on ARM if we want to write... (frame would get lost if done mid-frame...) // start sending over 1s on ssp->arm when we start sending preamble -reg counting_desync=1'b0; // are we counting bits since last frame? -reg sending=1'b0; // are we actively modulating? -reg [11:0] bit_counts=12'd0;///for timeslots... only support ts=0 for now, at 212 speed -512 fullbits from end of frame. One hopes. might remove those? +reg counting_desync=1'b0; // are we counting bits since last frame? +reg sending=1'b0; // are we actively modulating? +reg [11:0] bit_counts=12'd0;///for timeslots... only support ts=0 for now, at 212 speed -512 fullbits from end of frame. One hopes. might remove those? //reg [2:0]old_mod; @@ -166,19 +166,19 @@ reg [11:0] bit_counts=12'd0;///for timeslots... only support ts=0 for now, at 21 //begin //if (mod_type[2]==1&&old_mod[2]==0) // bit_counts=0; -//old_mod=mod_type; +//old_mod=mod_type; //end //we need some way to flush bit_counts triggers on mod_type changes don't compile reg dlay; -always @(negedge adc_clk) //every data ping? +always @(negedge adc_clk) //every data ping? begin - //envelope follow code... - //////////// + //envelope follow code... + //////////// //move the counter to the outside... - // if (adc_d>=curminthres||try_sync) + // if (adc_d>=curminthres||try_sync) if(fccount==bitmlen) - begin + begin if((~try_sync)&&(adc_d768) // should be over ts0 now, without ARM interference... stop counting... - begin + begin bit_counts<=0; // counting_desync<=0; end @@ -199,11 +199,11 @@ begin if((power)) bit_counts<=0; else - bit_counts<=bit_counts+1; - // end + bit_counts<=bit_counts+1; + // end end else - begin + begin if((~try_sync)&&(adc_dcurmaxthres) //rising edge begin case (state) @@ -230,38 +230,38 @@ begin 2: begin if (adc_d>curmax) curmax <= adc_d; - end + end default: begin - end + end endcase after_hysteresis <=1'b1; if(try_sync) tsinceedge<=0; end else if (adc_d>1)+(curmin>>2)+(curmin>>4)+(curmax>>3)+(curmax>>4)); curmaxthres <= ( (curmax>>1)+(curmax>>2)+(curmax>>4)+(curmin>>3)+(curmin>>4)); curmin <=adc_d<`imin? adc_d :`imin; - state <=1; - end + state <=1; + end default: begin - end - endcase + end + endcase after_hysteresis <=0; - if (~try_sync ) //begin modulation, lower edge... + if (~try_sync ) //begin modulation, lower edge... begin try_sync <=1; //counting_desync<=1'b0; @@ -271,7 +271,7 @@ begin mid <=8'd127; tsinceedge<=0; prv <=1; - end + end else begin tsinceedge<=0; @@ -282,12 +282,12 @@ begin curminthres <= ( (curmin>>1)+(curmin>>2)+(curmin>>4)+(curmax>>3)+(curmax>>4)); curmaxthres <= ( (curmax>>1)+(curmax>>2)+(curmax>>4)+(curmin>>3)+(curmin>>4)); state <=0; - + if (try_sync ) begin if (tsinceedge>=(128)) begin - //we might need to start counting... assuming ARM wants to reply to the frame. + //we might need to start counting... assuming ARM wants to reply to the frame. // counting_desync<=1'b1; bit_counts<=1;// i think? 128 is about 2 bits passed... but 1 also works try_sync<=0; @@ -295,7 +295,7 @@ begin curmin <=`imin; //reset envelope curmax <=`imax; curminthres <=`ithrmin; - curmaxthres <=`ithrmax; + curmaxthres <=`ithrmax; prv <=1; tsinceedge <=0; after_hysteresis <=1'b1; @@ -305,33 +305,33 @@ begin else tsinceedge<=(tsinceedge+1); end - end - - - - + end + + + + if (try_sync && tsinceedge<128) begin //detect bits in their middle ssp sampling is in sync, so it would sample all bits in order if (fccount==bithalf) begin if ((~did_sync) && ((prv==1&&(mid>128))||(prv==0&&(mid<=128)))) - begin + begin //sync the Zero, and set curbit roperly did_sync <=1'b1; zero <= ~prv;// 1-prv curbit <=1; - end - else + end + else curbit <= (mid>128) ? (~zero):zero; - - prv <=(mid>128) ?1:0; - - if(adc_d>curmaxthres) + + prv <=(mid>128) ?1:0; + + if(adc_d>curmaxthres) mid <=8'd129; - else if (adc_d128)?1:0; + prv <=(mid>128)?1:0; mid <=128; end else begin // minimum-maximum calc - if(adc_d>curmaxthres) + if(adc_d>curmaxthres) mid <=mid+1; - else if (adc_d PM3: -// detecting and shaping the reader's signal. Reader will modulate the carrier by 100% (signal is either on or off). Use a +// detecting and shaping the reader's signal. Reader will modulate the carrier by 100% (signal is either on or off). Use a // hysteresis (Schmitt Trigger) to avoid false triggers during slowly increasing or decreasing carrier amplitudes reg after_hysteresis; reg [11:0] has_been_low_for; always @(negedge adc_clk) begin - if(adc_d >= 16) after_hysteresis <= 1'b1; // U >= 1,14V -> after_hysteresis = 1 - else if(adc_d < 8) after_hysteresis <= 1'b0; // U < 1,04V -> after_hysteresis = 0 - // Note: was >= 3,53V and <= 1,19V. The new trigger values allow more reliable detection of the first bit - // (it might not reach 3,53V due to the high time constant of the high pass filter in the analogue RF part). - // In addition, the new values are more in line with ISO14443-2: "The PICC shall detect the ”End of Pause” after the field exceeds - // 5% of H_INITIAL and before it exceeds 60% of H_INITIAL." Depending on the signal strength, 60% might well be less than 3,53V. - - - // detecting a loss of reader's field (adc_d < 192 for 4096 clock cycles). If this is the case, - // set the detected reader signal (after_hysteresis) to '1' (unmodulated) - if(adc_d >= 192) + if(adc_d >= 16) after_hysteresis <= 1'b1; // U >= 1,14V -> after_hysteresis = 1 + else if(adc_d < 8) after_hysteresis <= 1'b0; // U < 1,04V -> after_hysteresis = 0 + // Note: was >= 3,53V and <= 1,19V. The new trigger values allow more reliable detection of the first bit + // (it might not reach 3,53V due to the high time constant of the high pass filter in the analogue RF part). + // In addition, the new values are more in line with ISO14443-2: "The PICC shall detect the ”End of Pause” after the field exceeds + // 5% of H_INITIAL and before it exceeds 60% of H_INITIAL." Depending on the signal strength, 60% might well be less than 3,53V. + + + // detecting a loss of reader's field (adc_d < 192 for 4096 clock cycles). If this is the case, + // set the detected reader signal (after_hysteresis) to '1' (unmodulated) + if(adc_d >= 192) begin has_been_low_for <= 12'd0; end @@ -65,43 +65,43 @@ begin after_hysteresis <= 1'b1; end else - begin + begin has_been_low_for <= has_been_low_for + 1; - end + end end - + end //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Reader -> PM3 -// detect when a reader is active (modulating). We assume that the reader is active, if we see the carrier off for at least 8 -// carrier cycles. We assume that the reader is inactive, if the carrier stayed high for at least 256 carrier cycles. +// detect when a reader is active (modulating). We assume that the reader is active, if we see the carrier off for at least 8 +// carrier cycles. We assume that the reader is inactive, if the carrier stayed high for at least 256 carrier cycles. reg deep_modulation; reg [2:0] deep_counter; reg [8:0] saw_deep_modulation; always @(negedge adc_clk) begin - if(~(| adc_d[7:0])) // if adc_d == 0 (U <= 0,94V) - begin - if(deep_counter == 3'd7) // adc_d == 0 for 8 adc_clk ticks -> deep_modulation (by reader) - begin - deep_modulation <= 1'b1; - saw_deep_modulation <= 8'd0; - end - else - deep_counter <= deep_counter + 1; - end - else - begin - deep_counter <= 3'd0; - if(saw_deep_modulation == 8'd255) // adc_d != 0 for 256 adc_clk ticks -> deep_modulation is over, probably waiting for tag's response - deep_modulation <= 1'b0; - else - saw_deep_modulation <= saw_deep_modulation + 1; - end + if(~(| adc_d[7:0])) // if adc_d == 0 (U <= 0,94V) + begin + if(deep_counter == 3'd7) // adc_d == 0 for 8 adc_clk ticks -> deep_modulation (by reader) + begin + deep_modulation <= 1'b1; + saw_deep_modulation <= 8'd0; + end + else + deep_counter <= deep_counter + 1; + end + else + begin + deep_counter <= 3'd0; + if(saw_deep_modulation == 8'd255) // adc_d != 0 for 256 adc_clk ticks -> deep_modulation is over, probably waiting for tag's response + deep_modulation <= 1'b0; + else + saw_deep_modulation <= saw_deep_modulation + 1; + end end @@ -115,16 +115,16 @@ reg [7:0] input_prev_4, input_prev_3, input_prev_2, input_prev_1; always @(negedge adc_clk) begin - input_prev_4 <= input_prev_3; - input_prev_3 <= input_prev_2; - input_prev_2 <= input_prev_1; - input_prev_1 <= adc_d; -end + input_prev_4 <= input_prev_3; + input_prev_3 <= input_prev_2; + input_prev_2 <= input_prev_1; + input_prev_1 <= adc_d; +end // adc_d_filtered = 2*input_prev4 + 1*input_prev3 + 0*input_prev2 - 1*input_prev1 - 2*input -// = (2*input_prev4 + input_prev3) - (2*input + input_prev1) +// = (2*input_prev4 + input_prev3) - (2*input + input_prev1) wire [8:0] input_prev_4_times_2 = input_prev_4 << 1; -wire [8:0] adc_d_times_2 = adc_d << 1; +wire [8:0] adc_d_times_2 = adc_d << 1; wire [9:0] tmp1 = input_prev_4_times_2 + input_prev_3; wire [9:0] tmp2 = adc_d_times_2 + input_prev_1; @@ -133,49 +133,49 @@ wire [9:0] tmp2 = adc_d_times_2 + input_prev_1; wire signed [10:0] adc_d_filtered = {1'b0, tmp1} - {1'b0, tmp2}; - + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// internal FPGA timing. Maximum required period is 128 carrier clock cycles for a full 8 Bit transfer to ARM. (i.e. we need a +// internal FPGA timing. Maximum required period is 128 carrier clock cycles for a full 8 Bit transfer to ARM. (i.e. we need a // 7 bit counter). Adjust its frequency to external reader's clock when simulating a tag or sniffing. -reg pre_after_hysteresis; +reg pre_after_hysteresis; reg [3:0] reader_falling_edge_time; reg [6:0] negedge_cnt; always @(negedge adc_clk) begin - // detect a reader signal's falling edge and remember its timing: - pre_after_hysteresis <= after_hysteresis; - if (pre_after_hysteresis && ~after_hysteresis) - begin - reader_falling_edge_time[3:0] <= negedge_cnt[3:0]; - end + // detect a reader signal's falling edge and remember its timing: + pre_after_hysteresis <= after_hysteresis; + if (pre_after_hysteresis && ~after_hysteresis) + begin + reader_falling_edge_time[3:0] <= negedge_cnt[3:0]; + end - // adjust internal timer counter if necessary: - if (negedge_cnt[3:0] == 4'd13 && (mod_type == `SNIFFER || mod_type == `TAGSIM_LISTEN) && deep_modulation) - begin - if (reader_falling_edge_time == 4'd1) // reader signal changes right after sampling. Better sample earlier next time. - begin - negedge_cnt <= negedge_cnt + 2; // time warp - end - else if (reader_falling_edge_time == 4'd0) // reader signal changes right before sampling. Better sample later next time. - begin - negedge_cnt <= negedge_cnt; // freeze time - end - else - begin - negedge_cnt <= negedge_cnt + 1; // Continue as usual - end - reader_falling_edge_time[3:0] <= 4'd8; // adjust only once per detected edge - end - else if (negedge_cnt == 7'd127) // normal operation: count from 0 to 127 - begin - negedge_cnt <= 0; - end - else - begin - negedge_cnt <= negedge_cnt + 1; - end -end + // adjust internal timer counter if necessary: + if (negedge_cnt[3:0] == 4'd13 && (mod_type == `SNIFFER || mod_type == `TAGSIM_LISTEN) && deep_modulation) + begin + if (reader_falling_edge_time == 4'd1) // reader signal changes right after sampling. Better sample earlier next time. + begin + negedge_cnt <= negedge_cnt + 2; // time warp + end + else if (reader_falling_edge_time == 4'd0) // reader signal changes right before sampling. Better sample later next time. + begin + negedge_cnt <= negedge_cnt; // freeze time + end + else + begin + negedge_cnt <= negedge_cnt + 1; // Continue as usual + end + reader_falling_edge_time[3:0] <= 4'd8; // adjust only once per detected edge + end + else if (negedge_cnt == 7'd127) // normal operation: count from 0 to 127 + begin + negedge_cnt <= 0; + end + else + begin + negedge_cnt <= negedge_cnt + 1; + end +end //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -185,28 +185,28 @@ reg [3:0] mod_detect_reset_time; always @(negedge adc_clk) begin - if (mod_type == `READER_LISTEN) - // (our) reader signal changes at negedge_cnt[3:0]=9, tag response expected to start n*16+4 ticks later, further delayed by - // 3 ticks ADC conversion. The maximum filter output (edge detected) will be detected after subcarrier zero crossing (+7 ticks). - // To allow some timing variances, we want to have the maximum filter outputs well within the detection window, i.e. - // at mod_detect_reset_time+4 and mod_detect_reset_time+12 (-4 ticks). - // 9 + 4 + 3 + 7 - 4 = 19. 19 mod 16 = 3 - begin - mod_detect_reset_time <= 4'd4; - end - else - if (mod_type == `SNIFFER) - begin - // detect a rising edge of reader's signal and sync modulation detector to the tag's answer: - if (~pre_after_hysteresis && after_hysteresis && deep_modulation) - // reader signal rising edge detected at negedge_cnt[3:0]. This signal had been delayed - // 9 ticks by the RF part + 3 ticks by the A/D converter + 1 tick to assign to after_hysteresis. - // Then the same as above. - // - 9 - 3 - 1 + 4 + 3 + 7 - 4 = -3 - begin - mod_detect_reset_time <= negedge_cnt[3:0] - 4'd3; - end - end + if (mod_type == `READER_LISTEN) + // (our) reader signal changes at negedge_cnt[3:0]=9, tag response expected to start n*16+4 ticks later, further delayed by + // 3 ticks ADC conversion. The maximum filter output (edge detected) will be detected after subcarrier zero crossing (+7 ticks). + // To allow some timing variances, we want to have the maximum filter outputs well within the detection window, i.e. + // at mod_detect_reset_time+4 and mod_detect_reset_time+12 (-4 ticks). + // 9 + 4 + 3 + 7 - 4 = 19. 19 mod 16 = 3 + begin + mod_detect_reset_time <= 4'd4; + end + else + if (mod_type == `SNIFFER) + begin + // detect a rising edge of reader's signal and sync modulation detector to the tag's answer: + if (~pre_after_hysteresis && after_hysteresis && deep_modulation) + // reader signal rising edge detected at negedge_cnt[3:0]. This signal had been delayed + // 9 ticks by the RF part + 3 ticks by the A/D converter + 1 tick to assign to after_hysteresis. + // Then the same as above. + // - 9 - 3 - 1 + 4 + 3 + 7 - 4 = -3 + begin + mod_detect_reset_time <= negedge_cnt[3:0] - 4'd3; + end + end end @@ -218,34 +218,34 @@ reg signed [10:0] rx_mod_falling_edge_max; reg signed [10:0] rx_mod_rising_edge_max; reg curbit; -`define EDGE_DETECT_THRESHOLD 5 +`define EDGE_DETECT_THRESHOLD 5 always @(negedge adc_clk) begin - if(negedge_cnt[3:0] == mod_detect_reset_time) - begin - // detect modulation signal: if modulating, there must have been a falling AND a rising edge - if ((rx_mod_falling_edge_max > `EDGE_DETECT_THRESHOLD) && (rx_mod_rising_edge_max < -`EDGE_DETECT_THRESHOLD)) - curbit <= 1'b1; // modulation - else - curbit <= 1'b0; // no modulation - // reset modulation detector - rx_mod_rising_edge_max <= 0; - rx_mod_falling_edge_max <= 0; - end - else // look for steepest edges (slopes) - begin - if (adc_d_filtered > 0) - begin - if (adc_d_filtered > rx_mod_falling_edge_max) - rx_mod_falling_edge_max <= adc_d_filtered; - end - else - begin - if (adc_d_filtered < rx_mod_rising_edge_max) - rx_mod_rising_edge_max <= adc_d_filtered; - end - end + if(negedge_cnt[3:0] == mod_detect_reset_time) + begin + // detect modulation signal: if modulating, there must have been a falling AND a rising edge + if ((rx_mod_falling_edge_max > `EDGE_DETECT_THRESHOLD) && (rx_mod_rising_edge_max < -`EDGE_DETECT_THRESHOLD)) + curbit <= 1'b1; // modulation + else + curbit <= 1'b0; // no modulation + // reset modulation detector + rx_mod_rising_edge_max <= 0; + rx_mod_falling_edge_max <= 0; + end + else // look for steepest edges (slopes) + begin + if (adc_d_filtered > 0) + begin + if (adc_d_filtered > rx_mod_falling_edge_max) + rx_mod_falling_edge_max <= adc_d_filtered; + end + else + begin + if (adc_d_filtered < rx_mod_rising_edge_max) + rx_mod_rising_edge_max <= adc_d_filtered; + end + end end @@ -260,11 +260,11 @@ reg [3:0] tag_data; always @(negedge adc_clk) begin if(negedge_cnt[3:0] == 4'd0) - begin + begin reader_data[3:0] <= {reader_data[2:0], after_hysteresis}; - tag_data[3:0] <= {tag_data[2:0], curbit}; - end -end + tag_data[3:0] <= {tag_data[2:0], curbit}; + end +end @@ -277,17 +277,17 @@ reg mod_sig; always @(negedge adc_clk) begin - if(negedge_cnt[3:0] == 4'd0) // sample data at rising edge of ssp_clk - ssp_dout changes at the falling edge. - begin - mod_sig_buf[31:2] <= mod_sig_buf[30:1]; // shift - if (~ssp_dout && ~mod_sig_buf[1]) - mod_sig_buf[1] <= 1'b0; // delete the correction bit (a single 1 preceded and succeeded by 0) - else - mod_sig_buf[1] <= mod_sig_buf[0]; - mod_sig_buf[0] <= ssp_dout; // add new data to the delay line + if(negedge_cnt[3:0] == 4'd0) // sample data at rising edge of ssp_clk - ssp_dout changes at the falling edge. + begin + mod_sig_buf[31:2] <= mod_sig_buf[30:1]; // shift + if (~ssp_dout && ~mod_sig_buf[1]) + mod_sig_buf[1] <= 1'b0; // delete the correction bit (a single 1 preceded and succeeded by 0) + else + mod_sig_buf[1] <= mod_sig_buf[0]; + mod_sig_buf[0] <= ssp_dout; // add new data to the delay line - mod_sig = mod_sig_buf[mod_sig_ptr]; // the delayed signal. - end + mod_sig = mod_sig_buf[mod_sig_ptr]; // the delayed signal. + end end @@ -297,7 +297,7 @@ end // a timer for the 1172 cycles fdt (Frame Delay Time). Start the timer with a rising edge of the reader's signal. // set fdt_elapsed when we no longer need to delay data. Set fdt_indicator when we can start sending data. // Note: the FPGA only takes care for the 1172 delay. To achieve an additional 1236-1172=64 ticks delay, the ARM must send -// a correction bit (before the start bit). The correction bit will be coded as 00010000, i.e. it adds 4 bits to the +// a correction bit (before the start bit). The correction bit will be coded as 00010000, i.e. it adds 4 bits to the // transmission stream, causing the required additional delay. reg [10:0] fdt_counter; reg fdt_indicator, fdt_elapsed; @@ -317,41 +317,41 @@ reg [3:0] sub_carrier_cnt; `define FDT_INDICATOR_COUNT 11'd647 // Note: worst case, assignment to sendbit takes 15 ticks more, and transfer to ARM needs 7*16 = 112 ticks more. // When the ARM's response then appears, the fdt_count is already 647 + 15 + 112 = 774, which still allows the ARM a possible -// response window of 1128 - 774 = 354 ticks. +// response window of 1128 - 774 = 354 ticks. // reset on a pause in listen mode. I.e. the counter starts when the pause is over: assign fdt_reset = ~after_hysteresis && mod_type == `TAGSIM_LISTEN; always @(negedge adc_clk) begin - if (fdt_reset) - begin - fdt_counter <= 11'd0; - fdt_elapsed <= 1'b0; - fdt_indicator <= 1'b0; - end - else - begin - if(fdt_counter == `FDT_COUNT) - begin - if(~fdt_elapsed) // just reached fdt. - begin - mod_sig_flip <= negedge_cnt[3:0]; // start modulation at this time - sub_carrier_cnt <= 4'd0; // subcarrier phase in sync with start of modulation - fdt_elapsed <= 1'b1; - end - else - begin - sub_carrier_cnt <= sub_carrier_cnt + 1; - end - end - else - begin - fdt_counter <= fdt_counter + 1; - end - end - - if(fdt_counter == `FDT_INDICATOR_COUNT) fdt_indicator <= 1'b1; + if (fdt_reset) + begin + fdt_counter <= 11'd0; + fdt_elapsed <= 1'b0; + fdt_indicator <= 1'b0; + end + else + begin + if(fdt_counter == `FDT_COUNT) + begin + if(~fdt_elapsed) // just reached fdt. + begin + mod_sig_flip <= negedge_cnt[3:0]; // start modulation at this time + sub_carrier_cnt <= 4'd0; // subcarrier phase in sync with start of modulation + fdt_elapsed <= 1'b1; + end + else + begin + sub_carrier_cnt <= sub_carrier_cnt + 1; + end + end + else + begin + fdt_counter <= fdt_counter + 1; + end + end + + if(fdt_counter == `FDT_INDICATOR_COUNT) fdt_indicator <= 1'b1; end @@ -363,24 +363,24 @@ reg mod_sig_coil; always @(negedge adc_clk) begin - if (mod_type == `TAGSIM_MOD) // need to take care of proper fdt timing - begin - if(fdt_counter == `FDT_COUNT) - begin - if(fdt_elapsed) - begin - if(negedge_cnt[3:0] == mod_sig_flip) mod_sig_coil <= mod_sig; - end - else - begin - mod_sig_coil <= mod_sig; // just reached fdt. Immediately assign signal to coil - end - end - end - else // other modes: don't delay - begin - mod_sig_coil <= ssp_dout; - end + if (mod_type == `TAGSIM_MOD) // need to take care of proper fdt timing + begin + if(fdt_counter == `FDT_COUNT) + begin + if(fdt_elapsed) + begin + if(negedge_cnt[3:0] == mod_sig_flip) mod_sig_coil <= mod_sig; + end + else + begin + mod_sig_coil <= mod_sig; // just reached fdt. Immediately assign signal to coil + end + end + end + else // other modes: don't delay + begin + mod_sig_coil <= ssp_dout; + end end @@ -392,39 +392,39 @@ reg temp_buffer_reset; always @(negedge adc_clk) begin - if(fdt_reset) - begin - mod_sig_ptr <= 5'd0; - temp_buffer_reset = 1'b0; - end - else - begin - if(fdt_counter == `FDT_COUNT && ~fdt_elapsed) // if we just reached fdt - if(~(| mod_sig_ptr[4:0])) - mod_sig_ptr <= 5'd8; // ... but didn't buffer a 1 yet, delay next 1 by n*128 ticks. - else - temp_buffer_reset = 1'b1; // else no need for further delays. + if(fdt_reset) + begin + mod_sig_ptr <= 5'd0; + temp_buffer_reset = 1'b0; + end + else + begin + if(fdt_counter == `FDT_COUNT && ~fdt_elapsed) // if we just reached fdt + if(~(| mod_sig_ptr[4:0])) + mod_sig_ptr <= 5'd8; // ... but didn't buffer a 1 yet, delay next 1 by n*128 ticks. + else + temp_buffer_reset = 1'b1; // else no need for further delays. - if(negedge_cnt[3:0] == 4'd0) // at rising edge of ssp_clk - ssp_dout changes at the falling edge. - begin - if((ssp_dout || (| mod_sig_ptr[4:0])) && ~fdt_elapsed) // buffer a 1 (and all subsequent data) until fdt is reached. - if (mod_sig_ptr == 5'd31) - mod_sig_ptr <= 5'd0; // buffer overflow - data loss. - else - mod_sig_ptr <= mod_sig_ptr + 1; // increase buffer (= increase delay by 16 adc_clk ticks). mod_sig_ptr always points ahead of first 1. - else if(fdt_elapsed && ~temp_buffer_reset) - begin - // wait for the next 1 after fdt_elapsed before fixing the delay and starting modulation. This ensures that the response can only happen - // at intervals of 8 * 16 = 128 adc_clk ticks (as defined in ISO14443-3) - if(ssp_dout) - temp_buffer_reset = 1'b1; - if(mod_sig_ptr == 5'd1) - mod_sig_ptr <= 5'd8; // still nothing received, need to go for the next interval - else - mod_sig_ptr <= mod_sig_ptr - 1; // decrease buffer. - end - end - end + if(negedge_cnt[3:0] == 4'd0) // at rising edge of ssp_clk - ssp_dout changes at the falling edge. + begin + if((ssp_dout || (| mod_sig_ptr[4:0])) && ~fdt_elapsed) // buffer a 1 (and all subsequent data) until fdt is reached. + if (mod_sig_ptr == 5'd31) + mod_sig_ptr <= 5'd0; // buffer overflow - data loss. + else + mod_sig_ptr <= mod_sig_ptr + 1; // increase buffer (= increase delay by 16 adc_clk ticks). mod_sig_ptr always points ahead of first 1. + else if(fdt_elapsed && ~temp_buffer_reset) + begin + // wait for the next 1 after fdt_elapsed before fixing the delay and starting modulation. This ensures that the response can only happen + // at intervals of 8 * 16 = 128 adc_clk ticks (as defined in ISO14443-3) + if(ssp_dout) + temp_buffer_reset = 1'b1; + if(mod_sig_ptr == 5'd1) + mod_sig_ptr <= 5'd8; // still nothing received, need to go for the next interval + else + mod_sig_ptr <= mod_sig_ptr - 1; // decrease buffer. + end + end + end end @@ -436,43 +436,43 @@ reg [7:0] to_arm; always @(negedge adc_clk) begin - if (negedge_cnt[5:0] == 6'd63) // fill the buffer - begin - if (mod_type == `SNIFFER) - begin - if(deep_modulation) // a reader is sending (or there's no field at all) - begin - to_arm <= {reader_data[3:0], 4'b0000}; // don't send tag data - end - else - begin - to_arm <= {reader_data[3:0], tag_data[3:0]}; - end - end - else - begin - to_arm[7:0] <= {mod_sig_ptr[4:0], mod_sig_flip[3:1]}; // feedback timing information - end - end + if (negedge_cnt[5:0] == 6'd63) // fill the buffer + begin + if (mod_type == `SNIFFER) + begin + if(deep_modulation) // a reader is sending (or there's no field at all) + begin + to_arm <= {reader_data[3:0], 4'b0000}; // don't send tag data + end + else + begin + to_arm <= {reader_data[3:0], tag_data[3:0]}; + end + end + else + begin + to_arm[7:0] <= {mod_sig_ptr[4:0], mod_sig_flip[3:1]}; // feedback timing information + end + end - if(negedge_cnt[2:0] == 3'b000 && mod_type == `SNIFFER) // shift at double speed - begin - // Don't shift if we just loaded new data, obviously. - if(negedge_cnt[5:0] != 6'd0) - begin - to_arm[7:1] <= to_arm[6:0]; - end - end + if(negedge_cnt[2:0] == 3'b000 && mod_type == `SNIFFER) // shift at double speed + begin + // Don't shift if we just loaded new data, obviously. + if(negedge_cnt[5:0] != 6'd0) + begin + to_arm[7:1] <= to_arm[6:0]; + end + end + + if(negedge_cnt[3:0] == 4'b0000 && mod_type != `SNIFFER) + begin + // Don't shift if we just loaded new data, obviously. + if(negedge_cnt[6:0] != 7'd0) + begin + to_arm[7:1] <= to_arm[6:0]; + end + end - if(negedge_cnt[3:0] == 4'b0000 && mod_type != `SNIFFER) - begin - // Don't shift if we just loaded new data, obviously. - if(negedge_cnt[6:0] != 7'd0) - begin - to_arm[7:1] <= to_arm[6:0]; - end - end - end @@ -484,32 +484,32 @@ reg ssp_frame; always @(negedge adc_clk) begin - if(mod_type == `SNIFFER) - // SNIFFER mode (ssp_clk = adc_clk / 8, ssp_frame clock = adc_clk / 64)): - begin - if(negedge_cnt[2:0] == 3'd0) - ssp_clk <= 1'b1; - if(negedge_cnt[2:0] == 3'd4) - ssp_clk <= 1'b0; + if(mod_type == `SNIFFER) + // SNIFFER mode (ssp_clk = adc_clk / 8, ssp_frame clock = adc_clk / 64)): + begin + if(negedge_cnt[2:0] == 3'd0) + ssp_clk <= 1'b1; + if(negedge_cnt[2:0] == 3'd4) + ssp_clk <= 1'b0; - if(negedge_cnt[5:0] == 6'd0) // ssp_frame rising edge indicates start of frame - ssp_frame <= 1'b1; - if(negedge_cnt[5:0] == 6'd8) - ssp_frame <= 1'b0; - end - else - // all other modes (ssp_clk = adc_clk / 16, ssp_frame clock = adc_clk / 128): - begin - if(negedge_cnt[3:0] == 4'd0) - ssp_clk <= 1'b1; - if(negedge_cnt[3:0] == 4'd8) - ssp_clk <= 1'b0; + if(negedge_cnt[5:0] == 6'd0) // ssp_frame rising edge indicates start of frame + ssp_frame <= 1'b1; + if(negedge_cnt[5:0] == 6'd8) + ssp_frame <= 1'b0; + end + else + // all other modes (ssp_clk = adc_clk / 16, ssp_frame clock = adc_clk / 128): + begin + if(negedge_cnt[3:0] == 4'd0) + ssp_clk <= 1'b1; + if(negedge_cnt[3:0] == 4'd8) + ssp_clk <= 1'b0; - if(negedge_cnt[6:0] == 7'd7) // ssp_frame rising edge indicates start of frame - ssp_frame <= 1'b1; - if(negedge_cnt[6:0] == 7'd23) - ssp_frame <= 1'b0; - end + if(negedge_cnt[6:0] == 7'd7) // ssp_frame rising edge indicates start of frame + ssp_frame <= 1'b1; + if(negedge_cnt[6:0] == 7'd23) + ssp_frame <= 1'b0; + end end @@ -522,31 +522,31 @@ reg sendbit; always @(negedge adc_clk) begin - if(negedge_cnt[3:0] == 4'd0) - begin - // What do we communicate to the ARM - if(mod_type == `TAGSIM_LISTEN) - sendbit = after_hysteresis; - else if(mod_type == `TAGSIM_MOD) - /* if(fdt_counter > 11'd772) sendbit = mod_sig_coil; // huh? - else */ - sendbit = fdt_indicator; - else if (mod_type == `READER_LISTEN) - sendbit = curbit; - else - sendbit = 1'b0; - end + if(negedge_cnt[3:0] == 4'd0) + begin + // What do we communicate to the ARM + if(mod_type == `TAGSIM_LISTEN) + sendbit = after_hysteresis; + else if(mod_type == `TAGSIM_MOD) + /* if(fdt_counter > 11'd772) sendbit = mod_sig_coil; // huh? + else */ + sendbit = fdt_indicator; + else if (mod_type == `READER_LISTEN) + sendbit = curbit; + else + sendbit = 1'b0; + end - if(mod_type == `SNIFFER) - // send sampled reader and tag data: - bit_to_arm = to_arm[7]; - else if (mod_type == `TAGSIM_MOD && fdt_elapsed && temp_buffer_reset) - // send timing information: - bit_to_arm = to_arm[7]; - else - // send data or fdt_indicator - bit_to_arm = sendbit; + if(mod_type == `SNIFFER) + // send sampled reader and tag data: + bit_to_arm = to_arm[7]; + else if (mod_type == `TAGSIM_MOD && fdt_elapsed && temp_buffer_reset) + // send timing information: + bit_to_arm = to_arm[7]; + else + // send data or fdt_indicator + bit_to_arm = sendbit; end @@ -559,7 +559,7 @@ wire sub_carrier; assign sub_carrier = ~sub_carrier_cnt[3]; // in READER_MOD: drop carrier for mod_sig_coil==1 (pause); in READER_LISTEN: carrier always on; in other modes: carrier always off -assign pwr_hi = (ck_1356megb & (((mod_type == `READER_MOD) & ~mod_sig_coil) || (mod_type == `READER_LISTEN))); +assign pwr_hi = (ck_1356megb & (((mod_type == `READER_MOD) & ~mod_sig_coil) || (mod_type == `READER_LISTEN))); // Enable HF antenna drivers: @@ -567,8 +567,8 @@ assign pwr_oe1 = 1'b0; assign pwr_oe3 = 1'b0; // TAGSIM_MOD: short circuit antenna with different resistances (modulated by sub_carrier modulated by mod_sig_coil) -// for pwr_oe4 = 1 (tristate): antenna load = 10k || 33 = 32,9 Ohms -// for pwr_oe4 = 0 (active): antenna load = 10k || 33 || 33 = 16,5 Ohms +// for pwr_oe4 = 1 (tristate): antenna load = 10k || 33 = 32,9 Ohms +// for pwr_oe4 = 0 (active): antenna load = 10k || 33 || 33 = 16,5 Ohms assign pwr_oe4 = mod_sig_coil & sub_carrier & (mod_type == `TAGSIM_MOD); // This is all LF, so doesn't matter. diff --git a/fpga/hi_read_rx_xcorr.v b/fpga/hi_read_rx_xcorr.v index 94a798a86..be70b97b0 100644 --- a/fpga/hi_read_rx_xcorr.v +++ b/fpga/hi_read_rx_xcorr.v @@ -32,16 +32,16 @@ reg [2:0] fc_div; always @(negedge ck_1356megb) fc_div <= fc_div + 1; -(* clock_signal = "yes" *) reg adc_clk; // sample frequency, always 16 * fc +(* clock_signal = "yes" *) reg adc_clk; // sample frequency, always 16 * fc always @(ck_1356megb, xcorr_is_848, xcorr_quarter_freq, fc_div) - if (xcorr_is_848 & ~xcorr_quarter_freq) // fc = 847.5 kHz, standard ISO14443B - adc_clk <= ck_1356megb; - else if (~xcorr_is_848 & ~xcorr_quarter_freq) // fc = 423.75 kHz - adc_clk <= fc_div[0]; - else if (xcorr_is_848 & xcorr_quarter_freq) // fc = 211.875 kHz - adc_clk <= fc_div[1]; - else // fc = 105.9375 kHz - adc_clk <= fc_div[2]; + if (xcorr_is_848 & ~xcorr_quarter_freq) // fc = 847.5 kHz, standard ISO14443B + adc_clk <= ck_1356megb; + else if (~xcorr_is_848 & ~xcorr_quarter_freq) // fc = 423.75 kHz + adc_clk <= fc_div[0]; + else if (xcorr_is_848 & xcorr_quarter_freq) // fc = 211.875 kHz + adc_clk <= fc_div[1]; + else // fc = 105.9375 kHz + adc_clk <= fc_div[2]; // When we're a reader, we just need to do the BPSK demod; but when we're an // eavesdropper, we also need to pick out the commands sent by the reader, @@ -94,9 +94,9 @@ reg ssp_frame; always @(negedge adc_clk) begin - corr_i_cnt <= corr_i_cnt + 1; -end - + corr_i_cnt <= corr_i_cnt + 1; +end + // ADC data appears on the rising edge, so sample it on the falling edge always @(negedge adc_clk) @@ -147,7 +147,7 @@ begin else corr_i_accum <= corr_i_accum + adc_d; - if(corr_i_cnt[3] == corr_i_cnt[2]) // phase shifted by pi/2 + if(corr_i_cnt[3] == corr_i_cnt[2]) // phase shifted by pi/2 corr_q_accum <= corr_q_accum + adc_d; else corr_q_accum <= corr_q_accum - adc_d; @@ -177,8 +177,8 @@ begin end end - // set ssp_frame signal for corr_i_cnt = 0..3 and corr_i_cnt = 32..35 - // (send two frames with 8 Bits each) + // set ssp_frame signal for corr_i_cnt = 0..3 and corr_i_cnt = 32..35 + // (send two frames with 8 Bits each) if(corr_i_cnt[5:2] == 4'b0000 || corr_i_cnt[5:2] == 4'b1000) ssp_frame = 1'b1; else diff --git a/fpga/hi_read_tx.v b/fpga/hi_read_tx.v index 756683cdd..f9550ed24 100644 --- a/fpga/hi_read_tx.v +++ b/fpga/hi_read_tx.v @@ -27,7 +27,7 @@ module hi_read_tx( // low frequency outputs, not relevant assign pwr_lo = 1'b0; assign pwr_oe2 = 1'b0; - + // The high-frequency stuff. For now, for testing, just bring out the carrier, // and allow the ARM to modulate it over the SSP. reg pwr_hi; @@ -75,4 +75,4 @@ assign ssp_din = 1'b0; assign dbg = ssp_frame; -endmodule \ No newline at end of file +endmodule diff --git a/fpga/hi_simulate.v b/fpga/hi_simulate.v index aea6b743b..0de34a1fd 100644 --- a/fpga/hi_simulate.v +++ b/fpga/hi_simulate.v @@ -1,7 +1,7 @@ //----------------------------------------------------------------------------- // Pretend to be an ISO 14443 tag. We will do this by alternately short- // circuiting and open-circuiting the antenna coil, with the tri-state -// pins. +// pins. // // We communicate over the SSP, as a bitstream (i.e., might as well be // unframed, though we still generate the word sync signal). The output diff --git a/fpga/lf_edge_detect.v b/fpga/lf_edge_detect.v index 573adf7bd..fee262e28 100644 --- a/fpga/lf_edge_detect.v +++ b/fpga/lf_edge_detect.v @@ -9,69 +9,69 @@ `include "min_max_tracker.v" module lf_edge_detect(input clk, input [7:0] adc_d, input [7:0] lf_ed_threshold, - output [7:0] max, output [7:0] min, - output [7:0] high_threshold, output [7:0] highz_threshold, - output [7:0] lowz_threshold, output [7:0] low_threshold, - output edge_state, output edge_toggle); + output [7:0] max, output [7:0] min, + output [7:0] high_threshold, output [7:0] highz_threshold, + output [7:0] lowz_threshold, output [7:0] low_threshold, + output edge_state, output edge_toggle); - min_max_tracker tracker(clk, adc_d, lf_ed_threshold, min, max); + min_max_tracker tracker(clk, adc_d, lf_ed_threshold, min, max); - // auto-tune - assign high_threshold = (max + min) / 2 + (max - min) / 4; - assign highz_threshold = (max + min) / 2 + (max - min) / 8; - assign lowz_threshold = (max + min) / 2 - (max - min) / 8; - assign low_threshold = (max + min) / 2 - (max - min) / 4; + // auto-tune + assign high_threshold = (max + min) / 2 + (max - min) / 4; + assign highz_threshold = (max + min) / 2 + (max - min) / 8; + assign lowz_threshold = (max + min) / 2 - (max - min) / 8; + assign low_threshold = (max + min) / 2 - (max - min) / 4; - // heuristic to see if it makes sense to try to detect an edge - wire enabled = - (high_threshold > highz_threshold) - & (highz_threshold > lowz_threshold) - & (lowz_threshold > low_threshold) - & ((high_threshold - highz_threshold) > 8) - & ((highz_threshold - lowz_threshold) > 16) - & ((lowz_threshold - low_threshold) > 8); + // heuristic to see if it makes sense to try to detect an edge + wire enabled = + (high_threshold > highz_threshold) + & (highz_threshold > lowz_threshold) + & (lowz_threshold > low_threshold) + & ((high_threshold - highz_threshold) > 8) + & ((highz_threshold - lowz_threshold) > 16) + & ((lowz_threshold - low_threshold) > 8); - // Toggle the output with hysteresis - // Set to high if the ADC value is above the threshold - // Set to low if the ADC value is below the threshold - reg is_high = 0; - reg is_low = 0; - reg is_zero = 0; - reg trigger_enabled = 1; - reg output_edge = 0; - reg output_state; + // Toggle the output with hysteresis + // Set to high if the ADC value is above the threshold + // Set to low if the ADC value is below the threshold + reg is_high = 0; + reg is_low = 0; + reg is_zero = 0; + reg trigger_enabled = 1; + reg output_edge = 0; + reg output_state; - always @(posedge clk) - begin - is_high <= (adc_d >= high_threshold); - is_low <= (adc_d <= low_threshold); - is_zero <= ((adc_d > lowz_threshold) & (adc_d < highz_threshold)); - end + always @(posedge clk) + begin + is_high <= (adc_d >= high_threshold); + is_low <= (adc_d <= low_threshold); + is_zero <= ((adc_d > lowz_threshold) & (adc_d < highz_threshold)); + end - // all edges detection - always @(posedge clk) - if (enabled) begin - // To enable detecting two consecutive peaks at the same level - // (low or high) we check whether or not we went back near 0 in-between. - // This extra check is necessary to prevent from noise artifacts - // around the threshold values. - if (trigger_enabled & (is_high | is_low)) begin - output_edge <= ~output_edge; - trigger_enabled <= 0; - end else - trigger_enabled <= trigger_enabled | is_zero; - end + // all edges detection + always @(posedge clk) + if (enabled) begin + // To enable detecting two consecutive peaks at the same level + // (low or high) we check whether or not we went back near 0 in-between. + // This extra check is necessary to prevent from noise artifacts + // around the threshold values. + if (trigger_enabled & (is_high | is_low)) begin + output_edge <= ~output_edge; + trigger_enabled <= 0; + end else + trigger_enabled <= trigger_enabled | is_zero; + end - // edge states - always @(posedge clk) - if (enabled) begin - if (is_high) - output_state <= 1'd1; - else if (is_low) - output_state <= 1'd0; - end + // edge states + always @(posedge clk) + if (enabled) begin + if (is_high) + output_state <= 1'd1; + else if (is_low) + output_state <= 1'd0; + end - assign edge_state = output_state; - assign edge_toggle = output_edge; + assign edge_state = output_state; + assign edge_toggle = output_edge; endmodule diff --git a/fpga/lo_edge_detect.v b/fpga/lo_edge_detect.v index bb1301574..5c73af96f 100644 --- a/fpga/lo_edge_detect.v +++ b/fpga/lo_edge_detect.v @@ -35,11 +35,11 @@ wire tag_modulation = ssp_dout & !lf_field; wire reader_modulation = !ssp_dout & lf_field & pck_divclk; // No logic, straight through. -assign pwr_oe1 = 1'b0; // not used in LF mode -assign pwr_oe3 = 1'b0; // base antenna load = 33 Ohms +assign pwr_oe1 = 1'b0; // not used in LF mode +assign pwr_oe3 = 1'b0; // base antenna load = 33 Ohms // when modulating, add another 33 Ohms and 10k Ohms in parallel: assign pwr_oe2 = tag_modulation; -assign pwr_oe4 = tag_modulation; +assign pwr_oe4 = tag_modulation; assign ssp_clk = cross_lo; assign pwr_lo = reader_modulation; @@ -56,9 +56,9 @@ wire [7:0] high_threshold, highz_threshold, lowz_threshold, low_threshold; wire [7:0] max, min; wire edge_state, edge_toggle; lf_edge_detect lf_ed(pck0, adc_filtered, lf_ed_threshold, - max, min, - high_threshold, highz_threshold, lowz_threshold, low_threshold, - edge_state, edge_toggle); + max, min, + high_threshold, highz_threshold, lowz_threshold, low_threshold, + edge_state, edge_toggle); assign dbg = lf_ed_toggle_mode ? edge_toggle : edge_state; diff --git a/fpga/lo_passthru.v b/fpga/lo_passthru.v index 3507f660e..f0f2847a0 100644 --- a/fpga/lo_passthru.v +++ b/fpga/lo_passthru.v @@ -5,13 +5,13 @@ // iZsh , June 2014 module lo_passthru( - input pck_divclk, - output pwr_lo, output pwr_hi, - output pwr_oe1, output pwr_oe2, output pwr_oe3, output pwr_oe4, - output adc_clk, - output ssp_din, input ssp_dout, - input cross_lo, - output dbg + input pck_divclk, + output pwr_lo, output pwr_hi, + output pwr_oe1, output pwr_oe2, output pwr_oe3, output pwr_oe4, + output adc_clk, + output ssp_din, input ssp_dout, + input cross_lo, + output dbg ); // the antenna is modulated when ssp_dout = 1, when 0 the diff --git a/fpga/lo_read.v b/fpga/lo_read.v index a6d077b99..c24a521a6 100644 --- a/fpga/lo_read.v +++ b/fpga/lo_read.v @@ -8,13 +8,13 @@ //----------------------------------------------------------------------------- module lo_read( - input pck0, input [7:0] pck_cnt, input pck_divclk, - output pwr_lo, output pwr_hi, - output pwr_oe1, output pwr_oe2, output pwr_oe3, output pwr_oe4, - input [7:0] adc_d, output adc_clk, - output ssp_frame, output ssp_din, output ssp_clk, - output dbg, - input lf_field + input pck0, input [7:0] pck_cnt, input pck_divclk, + output pwr_lo, output pwr_hi, + output pwr_oe1, output pwr_oe2, output pwr_oe3, output pwr_oe4, + input [7:0] adc_d, output adc_clk, + output ssp_frame, output ssp_din, output ssp_clk, + output dbg, + input lf_field ); reg [7:0] to_arm_shiftreg; @@ -27,17 +27,17 @@ reg [7:0] to_arm_shiftreg; // we read the ADC value when pck_cnt=7 and shift it out on counts 8..15 always @(posedge pck0) begin - if((pck_cnt == 8'd7) && !pck_divclk) - to_arm_shiftreg <= adc_d; - else begin - to_arm_shiftreg[7:1] <= to_arm_shiftreg[6:0]; - // simulation showed a glitch occuring due to the LSB of the shifter - // not being set as we shift bits out - // this ensures the ssp_din remains low after a transfer and suppresses - // the glitch that would occur when the last data shifted out ended in - // a 1 bit and the next data shifted out started with a 0 bit - to_arm_shiftreg[0] <= 1'b0; - end + if((pck_cnt == 8'd7) && !pck_divclk) + to_arm_shiftreg <= adc_d; + else begin + to_arm_shiftreg[7:1] <= to_arm_shiftreg[6:0]; + // simulation showed a glitch occuring due to the LSB of the shifter + // not being set as we shift bits out + // this ensures the ssp_din remains low after a transfer and suppresses + // the glitch that would occur when the last data shifted out ended in + // a 1 bit and the next data shifted out started with a 0 bit + to_arm_shiftreg[0] <= 1'b0; + end end // ADC samples on falling edge of adc_clk, data available on the rising edge diff --git a/fpga/lo_simulate.v b/fpga/lo_simulate.v index 687bed27c..c4edc3eeb 100644 --- a/fpga/lo_simulate.v +++ b/fpga/lo_simulate.v @@ -13,7 +13,7 @@ module lo_simulate( ssp_frame, ssp_din, ssp_dout, ssp_clk, cross_hi, cross_lo, dbg, - divisor + divisor ); input pck0, ck_1356meg, ck_1356megb; output pwr_lo, pwr_hi, pwr_oe1, pwr_oe2, pwr_oe3, pwr_oe4; @@ -23,7 +23,7 @@ module lo_simulate( output ssp_frame, ssp_din, ssp_clk; input cross_hi, cross_lo; output dbg; - input [7:0] divisor; + input [7:0] divisor; // No logic, straight through. assign pwr_oe3 = 1'b0; @@ -41,15 +41,15 @@ reg clk_state; always @(posedge pck0) begin - if(pck_divider == divisor[7:0]) - begin - pck_divider <= 8'd0; - clk_state = !clk_state; - end - else - begin - pck_divider <= pck_divider + 1; - end + if(pck_divider == divisor[7:0]) + begin + pck_divider <= 8'd0; + clk_state = !clk_state; + end + else + begin + pck_divider <= pck_divider + 1; + end end assign adc_clk = ~clk_state; @@ -63,18 +63,18 @@ reg output_state; always @(posedge pck0) begin - if((pck_divider == 8'd7) && !clk_state) begin - is_high = (adc_d >= 8'd191); - is_low = (adc_d <= 8'd64); - end + if((pck_divider == 8'd7) && !clk_state) begin + is_high = (adc_d >= 8'd191); + is_low = (adc_d <= 8'd64); + end end always @(posedge is_high or posedge is_low) begin - if(is_high) - output_state <= 1'd1; - else if(is_low) - output_state <= 1'd0; + if(is_high) + output_state <= 1'd1; + else if(is_low) + output_state <= 1'd0; end assign ssp_frame = output_state; diff --git a/fpga/lp20khz_1MSa_iir_filter.v b/fpga/lp20khz_1MSa_iir_filter.v index a227a902c..198f38022 100644 --- a/fpga/lp20khz_1MSa_iir_filter.v +++ b/fpga/lp20khz_1MSa_iir_filter.v @@ -28,54 +28,54 @@ // https://fail0verflow.com/blog/2014/proxmark3-fpga-iir-filter.html module lp20khz_1MSa_iir_filter(input clk, input [7:0] adc_d, output rdy, output [7:0] out); - // clk is 24Mhz, the IIR filter is designed for 1MS/s - // hence we need to divide it by 24 - // using a shift register takes less area than a counter - reg [23:0] cnt = 1; - assign rdy = cnt[0]; - always @(posedge clk) - cnt <= {cnt[22:0], cnt[23]}; + // clk is 24Mhz, the IIR filter is designed for 1MS/s + // hence we need to divide it by 24 + // using a shift register takes less area than a counter + reg [23:0] cnt = 1; + assign rdy = cnt[0]; + always @(posedge clk) + cnt <= {cnt[22:0], cnt[23]}; - reg [7:0] x0 = 0; - reg [7:0] x1 = 0; - reg [16:0] y0 = 0; - reg [16:0] y1 = 0; + reg [7:0] x0 = 0; + reg [7:0] x1 = 0; + reg [16:0] y0 = 0; + reg [16:0] y1 = 0; - always @(posedge clk) - begin - if (rdy) - begin - x0 <= x1; - x1 <= adc_d; - y0 <= y1; - y1 <= - // center the signal: - // input range is [0; 255] - // We want "128" to be at the center of the 17bit register - // (128+z)*gain = 17bit center - // z = (1<<16)/gain - 128 = 109 - // We could use 9bit x registers for that, but that would be - // a waste, let's just add the constant during the computation - // (x0+109) + 2*(x1+109) + (x2+109) = x0 + 2*x1 + x2 + 436 - x0 + {x1, 1'b0} + adc_d + 436 - // we want "- y0 * 0xd6 / 0x100" using only shift and add - // 0xd6 == 0b11010110 - // so *0xd6/0x100 is equivalent to - // ((x << 1) + (x << 2) + (x << 4) + (x << 6) + (x << 7)) >> 8 - // which is also equivalent to - // (x >> 7) + (x >> 6) + (x >> 4) + (x >> 2) + (x >> 1) - - ((y0 >> 7) + (y0 >> 6) + (y0 >> 4) + (y0 >> 2) + (y0 >> 1)) // - y0 * 0xd6 / 0x100 - // we want "+ y1 * 0x1d3 / 0x100" - // 0x1d3 == 0b111010011 - // so this is equivalent to - // ((x << 0) + (x << 1) + (x << 4) + (x << 6) + (x << 7) + (x << 8)) >> 8 - // which is also equivalent to - // (x >> 8) + (x >> 7) + (x >> 4) + (x >> 2) + (x >> 1) + (x >> 0) - + ((y1 >> 8) + (y1 >> 7) + (y1 >> 4) + (y1 >> 2) + (y1 >> 1) + y1); - end - end + always @(posedge clk) + begin + if (rdy) + begin + x0 <= x1; + x1 <= adc_d; + y0 <= y1; + y1 <= + // center the signal: + // input range is [0; 255] + // We want "128" to be at the center of the 17bit register + // (128+z)*gain = 17bit center + // z = (1<<16)/gain - 128 = 109 + // We could use 9bit x registers for that, but that would be + // a waste, let's just add the constant during the computation + // (x0+109) + 2*(x1+109) + (x2+109) = x0 + 2*x1 + x2 + 436 + x0 + {x1, 1'b0} + adc_d + 436 + // we want "- y0 * 0xd6 / 0x100" using only shift and add + // 0xd6 == 0b11010110 + // so *0xd6/0x100 is equivalent to + // ((x << 1) + (x << 2) + (x << 4) + (x << 6) + (x << 7)) >> 8 + // which is also equivalent to + // (x >> 7) + (x >> 6) + (x >> 4) + (x >> 2) + (x >> 1) + - ((y0 >> 7) + (y0 >> 6) + (y0 >> 4) + (y0 >> 2) + (y0 >> 1)) // - y0 * 0xd6 / 0x100 + // we want "+ y1 * 0x1d3 / 0x100" + // 0x1d3 == 0b111010011 + // so this is equivalent to + // ((x << 0) + (x << 1) + (x << 4) + (x << 6) + (x << 7) + (x << 8)) >> 8 + // which is also equivalent to + // (x >> 8) + (x >> 7) + (x >> 4) + (x >> 2) + (x >> 1) + (x >> 0) + + ((y1 >> 8) + (y1 >> 7) + (y1 >> 4) + (y1 >> 2) + (y1 >> 1) + y1); + end + end - // output: reduce to 8bit - assign out = y1[16:9]; + // output: reduce to 8bit + assign out = y1[16:9]; endmodule diff --git a/fpga/min_max_tracker.v b/fpga/min_max_tracker.v index 8abd40fba..06a395a70 100644 --- a/fpga/min_max_tracker.v +++ b/fpga/min_max_tracker.v @@ -14,52 +14,52 @@ // This algorithm therefore can't be used directly for realtime peak detections, // but it can be used as a simple envelope follower. module min_max_tracker(input clk, input [7:0] adc_d, input [7:0] threshold, - output [7:0] min, output [7:0] max); + output [7:0] min, output [7:0] max); - reg [7:0] min_val = 255; - reg [7:0] max_val = 0; - reg [7:0] cur_min_val = 255; - reg [7:0] cur_max_val = 0; - reg [1:0] state = 0; + reg [7:0] min_val = 255; + reg [7:0] max_val = 0; + reg [7:0] cur_min_val = 255; + reg [7:0] cur_max_val = 0; + reg [1:0] state = 0; - always @(posedge clk) - begin - case (state) - 0: - begin - if (cur_max_val >= ({1'b0, adc_d} + threshold)) - state <= 2; - else if (adc_d >= ({1'b0, cur_min_val} + threshold)) - state <= 1; - if (cur_max_val <= adc_d) - cur_max_val <= adc_d; - else if (adc_d <= cur_min_val) - cur_min_val <= adc_d; - end - 1: - begin - if (cur_max_val <= adc_d) - cur_max_val <= adc_d; - else if (({1'b0, adc_d} + threshold) <= cur_max_val) begin - state <= 2; - cur_min_val <= adc_d; - max_val <= cur_max_val; - end - end - 2: - begin - if (adc_d <= cur_min_val) - cur_min_val <= adc_d; - else if (adc_d >= ({1'b0, cur_min_val} + threshold)) begin - state <= 1; - cur_max_val <= adc_d; - min_val <= cur_min_val; - end - end - endcase - end + always @(posedge clk) + begin + case (state) + 0: + begin + if (cur_max_val >= ({1'b0, adc_d} + threshold)) + state <= 2; + else if (adc_d >= ({1'b0, cur_min_val} + threshold)) + state <= 1; + if (cur_max_val <= adc_d) + cur_max_val <= adc_d; + else if (adc_d <= cur_min_val) + cur_min_val <= adc_d; + end + 1: + begin + if (cur_max_val <= adc_d) + cur_max_val <= adc_d; + else if (({1'b0, adc_d} + threshold) <= cur_max_val) begin + state <= 2; + cur_min_val <= adc_d; + max_val <= cur_max_val; + end + end + 2: + begin + if (adc_d <= cur_min_val) + cur_min_val <= adc_d; + else if (adc_d >= ({1'b0, cur_min_val} + threshold)) begin + state <= 1; + cur_max_val <= adc_d; + min_val <= cur_min_val; + end + end + endcase + end - assign min = min_val; - assign max = max_val; + assign min = min_val; + assign max = max_val; endmodule diff --git a/fpga/testbed_fpga.v b/fpga/testbed_fpga.v index f62255db3..e33df789c 100644 --- a/fpga/testbed_fpga.v +++ b/fpga/testbed_fpga.v @@ -18,33 +18,33 @@ module testbed_fpga; ssp_frame, ssp_din, ssp_dout, ssp_clk ); - integer i; + integer i; - initial begin + initial begin - // init inputs - #5 ncs=1; - #5 spck = 1; - #5 mosi = 1; + // init inputs + #5 ncs=1; + #5 spck = 1; + #5 mosi = 1; - #50 ncs=0; - for (i = 0 ; i < 8 ; i = i + 1) begin - #5 mosi = $random; - #5 spck = 0; - #5 spck = 1; - end - #5 ncs=1; + #50 ncs=0; + for (i = 0 ; i < 8 ; i = i + 1) begin + #5 mosi = $random; + #5 spck = 0; + #5 spck = 1; + end + #5 ncs=1; - #50 ncs=0; - for (i = 0 ; i < 8 ; i = i + 1) begin - #5 mosi = $random; - #5 spck = 0; - #5 spck = 1; - end - #5 ncs=1; + #50 ncs=0; + for (i = 0 ; i < 8 ; i = i + 1) begin + #5 mosi = $random; + #5 spck = 0; + #5 spck = 1; + end + #5 ncs=1; + + #50 mosi=1; + $finish; + end - #50 mosi=1; - $finish; - end - endmodule // main diff --git a/fpga/testbed_hi_read_tx.v b/fpga/testbed_hi_read_tx.v index bd4f5b40e..050e6b1e4 100644 --- a/fpga/testbed_hi_read_tx.v +++ b/fpga/testbed_hi_read_tx.v @@ -1,109 +1,109 @@ `include "hi_read_tx.v" /* - pck0 - input main 24Mhz clock (PLL / 4) - [7:0] adc_d - input data from A/D converter - shallow_modulation - modulation type + pck0 - input main 24Mhz clock (PLL / 4) + [7:0] adc_d - input data from A/D converter + shallow_modulation - modulation type - pwr_lo - output to coil drivers (ssp_clk / 8) - adc_clk - output A/D clock signal - ssp_frame - output SSS frame indicator (goes high while the 8 bits are shifted) - ssp_din - output SSP data to ARM (shifts 8 bit A/D value serially to ARM MSB first) - ssp_clk - output SSP clock signal + pwr_lo - output to coil drivers (ssp_clk / 8) + adc_clk - output A/D clock signal + ssp_frame - output SSS frame indicator (goes high while the 8 bits are shifted) + ssp_din - output SSP data to ARM (shifts 8 bit A/D value serially to ARM MSB first) + ssp_clk - output SSP clock signal - ck_1356meg - input unused - ck_1356megb - input unused - ssp_dout - input unused - cross_hi - input unused - cross_lo - input unused + ck_1356meg - input unused + ck_1356megb - input unused + ssp_dout - input unused + cross_hi - input unused + cross_lo - input unused - pwr_hi - output unused, tied low - pwr_oe1 - output unused, undefined - pwr_oe2 - output unused, undefined - pwr_oe3 - output unused, undefined - pwr_oe4 - output unused, undefined - dbg - output alias for adc_clk + pwr_hi - output unused, tied low + pwr_oe1 - output unused, undefined + pwr_oe2 - output unused, undefined + pwr_oe3 - output unused, undefined + pwr_oe4 - output unused, undefined + dbg - output alias for adc_clk */ module testbed_hi_read_tx; - reg pck0; - reg [7:0] adc_d; - reg shallow_modulation; + reg pck0; + reg [7:0] adc_d; + reg shallow_modulation; - wire pwr_lo; - wire adc_clk; - reg ck_1356meg; - reg ck_1356megb; - wire ssp_frame; - wire ssp_din; - wire ssp_clk; - reg ssp_dout; - wire pwr_hi; - wire pwr_oe1; - wire pwr_oe2; - wire pwr_oe3; - wire pwr_oe4; - wire cross_lo; - wire cross_hi; - wire dbg; + wire pwr_lo; + wire adc_clk; + reg ck_1356meg; + reg ck_1356megb; + wire ssp_frame; + wire ssp_din; + wire ssp_clk; + reg ssp_dout; + wire pwr_hi; + wire pwr_oe1; + wire pwr_oe2; + wire pwr_oe3; + wire pwr_oe4; + wire cross_lo; + wire cross_hi; + wire dbg; - hi_read_tx #(5,200) dut( - .pck0(pck0), - .ck_1356meg(ck_1356meg), - .ck_1356megb(ck_1356megb), - .pwr_lo(pwr_lo), - .pwr_hi(pwr_hi), - .pwr_oe1(pwr_oe1), - .pwr_oe2(pwr_oe2), - .pwr_oe3(pwr_oe3), - .pwr_oe4(pwr_oe4), - .adc_d(adc_d), - .adc_clk(adc_clk), - .ssp_frame(ssp_frame), - .ssp_din(ssp_din), - .ssp_dout(ssp_dout), - .ssp_clk(ssp_clk), - .cross_hi(cross_hi), - .cross_lo(cross_lo), - .dbg(dbg), - .shallow_modulation(shallow_modulation) - ); + hi_read_tx #(5,200) dut( + .pck0(pck0), + .ck_1356meg(ck_1356meg), + .ck_1356megb(ck_1356megb), + .pwr_lo(pwr_lo), + .pwr_hi(pwr_hi), + .pwr_oe1(pwr_oe1), + .pwr_oe2(pwr_oe2), + .pwr_oe3(pwr_oe3), + .pwr_oe4(pwr_oe4), + .adc_d(adc_d), + .adc_clk(adc_clk), + .ssp_frame(ssp_frame), + .ssp_din(ssp_din), + .ssp_dout(ssp_dout), + .ssp_clk(ssp_clk), + .cross_hi(cross_hi), + .cross_lo(cross_lo), + .dbg(dbg), + .shallow_modulation(shallow_modulation) + ); - integer idx, i; + integer idx, i; - // main clock - always #5 begin - ck_1356megb = !ck_1356megb; - ck_1356meg = ck_1356megb; - end + // main clock + always #5 begin + ck_1356megb = !ck_1356megb; + ck_1356meg = ck_1356megb; + end - //crank DUT - task crank_dut; - begin - @(posedge ssp_clk) ; - ssp_dout = $random; - end - endtask + //crank DUT + task crank_dut; + begin + @(posedge ssp_clk) ; + ssp_dout = $random; + end + endtask - initial begin + initial begin - // init inputs - ck_1356megb = 0; - adc_d = 0; - ssp_dout=0; + // init inputs + ck_1356megb = 0; + adc_d = 0; + ssp_dout=0; - // shallow modulation off - shallow_modulation=0; - for (i = 0 ; i < 16 ; i = i + 1) begin - crank_dut; - end + // shallow modulation off + shallow_modulation=0; + for (i = 0 ; i < 16 ; i = i + 1) begin + crank_dut; + end + + // shallow modulation on + shallow_modulation=1; + for (i = 0 ; i < 16 ; i = i + 1) begin + crank_dut; + end + $finish; + end - // shallow modulation on - shallow_modulation=1; - for (i = 0 ; i < 16 ; i = i + 1) begin - crank_dut; - end - $finish; - end - endmodule // main diff --git a/fpga/testbed_hi_simulate.v b/fpga/testbed_hi_simulate.v index b06720165..541737202 100644 --- a/fpga/testbed_hi_simulate.v +++ b/fpga/testbed_hi_simulate.v @@ -1,116 +1,116 @@ `include "hi_simulate.v" /* - pck0 - input main 24Mhz clock (PLL / 4) - [7:0] adc_d - input data from A/D converter - mod_type - modulation type + pck0 - input main 24Mhz clock (PLL / 4) + [7:0] adc_d - input data from A/D converter + mod_type - modulation type - pwr_lo - output to coil drivers (ssp_clk / 8) - adc_clk - output A/D clock signal - ssp_frame - output SSS frame indicator (goes high while the 8 bits are shifted) - ssp_din - output SSP data to ARM (shifts 8 bit A/D value serially to ARM MSB first) - ssp_clk - output SSP clock signal + pwr_lo - output to coil drivers (ssp_clk / 8) + adc_clk - output A/D clock signal + ssp_frame - output SSS frame indicator (goes high while the 8 bits are shifted) + ssp_din - output SSP data to ARM (shifts 8 bit A/D value serially to ARM MSB first) + ssp_clk - output SSP clock signal - ck_1356meg - input unused - ck_1356megb - input unused - ssp_dout - input unused - cross_hi - input unused - cross_lo - input unused + ck_1356meg - input unused + ck_1356megb - input unused + ssp_dout - input unused + cross_hi - input unused + cross_lo - input unused - pwr_hi - output unused, tied low - pwr_oe1 - output unused, undefined - pwr_oe2 - output unused, undefined - pwr_oe3 - output unused, undefined - pwr_oe4 - output unused, undefined - dbg - output alias for adc_clk + pwr_hi - output unused, tied low + pwr_oe1 - output unused, undefined + pwr_oe2 - output unused, undefined + pwr_oe3 - output unused, undefined + pwr_oe4 - output unused, undefined + dbg - output alias for adc_clk */ module testbed_hi_simulate; - reg pck0; - reg [7:0] adc_d; - reg mod_type; + reg pck0; + reg [7:0] adc_d; + reg mod_type; - wire pwr_lo; - wire adc_clk; - reg ck_1356meg; - reg ck_1356megb; - wire ssp_frame; - wire ssp_din; - wire ssp_clk; - reg ssp_dout; - wire pwr_hi; - wire pwr_oe1; - wire pwr_oe2; - wire pwr_oe3; - wire pwr_oe4; - wire cross_lo; - wire cross_hi; - wire dbg; + wire pwr_lo; + wire adc_clk; + reg ck_1356meg; + reg ck_1356megb; + wire ssp_frame; + wire ssp_din; + wire ssp_clk; + reg ssp_dout; + wire pwr_hi; + wire pwr_oe1; + wire pwr_oe2; + wire pwr_oe3; + wire pwr_oe4; + wire cross_lo; + wire cross_hi; + wire dbg; - hi_simulate #(5,200) dut( - .pck0(pck0), - .ck_1356meg(ck_1356meg), - .ck_1356megb(ck_1356megb), - .pwr_lo(pwr_lo), - .pwr_hi(pwr_hi), - .pwr_oe1(pwr_oe1), - .pwr_oe2(pwr_oe2), - .pwr_oe3(pwr_oe3), - .pwr_oe4(pwr_oe4), - .adc_d(adc_d), - .adc_clk(adc_clk), - .ssp_frame(ssp_frame), - .ssp_din(ssp_din), - .ssp_dout(ssp_dout), - .ssp_clk(ssp_clk), - .cross_hi(cross_hi), - .cross_lo(cross_lo), - .dbg(dbg), - .mod_type(mod_type) - ); + hi_simulate #(5,200) dut( + .pck0(pck0), + .ck_1356meg(ck_1356meg), + .ck_1356megb(ck_1356megb), + .pwr_lo(pwr_lo), + .pwr_hi(pwr_hi), + .pwr_oe1(pwr_oe1), + .pwr_oe2(pwr_oe2), + .pwr_oe3(pwr_oe3), + .pwr_oe4(pwr_oe4), + .adc_d(adc_d), + .adc_clk(adc_clk), + .ssp_frame(ssp_frame), + .ssp_din(ssp_din), + .ssp_dout(ssp_dout), + .ssp_clk(ssp_clk), + .cross_hi(cross_hi), + .cross_lo(cross_lo), + .dbg(dbg), + .mod_type(mod_type) + ); - integer idx, i; + integer idx, i; - // main clock - always #5 begin - ck_1356megb = !ck_1356megb; - ck_1356meg = ck_1356megb; - end + // main clock + always #5 begin + ck_1356megb = !ck_1356megb; + ck_1356meg = ck_1356megb; + end - always begin - @(negedge adc_clk) ; - adc_d = $random; - end + always begin + @(negedge adc_clk) ; + adc_d = $random; + end - //crank DUT - task crank_dut; - begin - @(negedge ssp_clk) ; - ssp_dout = $random; - end - endtask + //crank DUT + task crank_dut; + begin + @(negedge ssp_clk) ; + ssp_dout = $random; + end + endtask - initial begin + initial begin - // init inputs - ck_1356megb = 0; - // random values - adc_d = 0; - ssp_dout=1; + // init inputs + ck_1356megb = 0; + // random values + adc_d = 0; + ssp_dout=1; - // shallow modulation off - mod_type=0; - for (i = 0 ; i < 16 ; i = i + 1) begin - crank_dut; - end + // shallow modulation off + mod_type=0; + for (i = 0 ; i < 16 ; i = i + 1) begin + crank_dut; + end + + // shallow modulation on + mod_type=1; + for (i = 0 ; i < 16 ; i = i + 1) begin + crank_dut; + end + $finish; + end - // shallow modulation on - mod_type=1; - for (i = 0 ; i < 16 ; i = i + 1) begin - crank_dut; - end - $finish; - end - endmodule // main diff --git a/fpga/testbed_lo_read.v b/fpga/testbed_lo_read.v index 370ed389e..78ca1e3bb 100644 --- a/fpga/testbed_lo_read.v +++ b/fpga/testbed_lo_read.v @@ -1,101 +1,101 @@ `include "lo_read.v" /* - pck0 - input main 24Mhz clock (PLL / 4) - [7:0] adc_d - input data from A/D converter - lo_is_125khz - input freq selector (1=125Khz, 0=136Khz) + pck0 - input main 24Mhz clock (PLL / 4) + [7:0] adc_d - input data from A/D converter + lo_is_125khz - input freq selector (1=125Khz, 0=136Khz) - pwr_lo - output to coil drivers (ssp_clk / 8) - adc_clk - output A/D clock signal - ssp_frame - output SSS frame indicator (goes high while the 8 bits are shifted) - ssp_din - output SSP data to ARM (shifts 8 bit A/D value serially to ARM MSB first) - ssp_clk - output SSP clock signal 1Mhz/1.09Mhz (pck0 / 2*(11+lo_is_125khz) ) + pwr_lo - output to coil drivers (ssp_clk / 8) + adc_clk - output A/D clock signal + ssp_frame - output SSS frame indicator (goes high while the 8 bits are shifted) + ssp_din - output SSP data to ARM (shifts 8 bit A/D value serially to ARM MSB first) + ssp_clk - output SSP clock signal 1Mhz/1.09Mhz (pck0 / 2*(11+lo_is_125khz) ) - ck_1356meg - input unused - ck_1356megb - input unused - ssp_dout - input unused - cross_hi - input unused - cross_lo - input unused + ck_1356meg - input unused + ck_1356megb - input unused + ssp_dout - input unused + cross_hi - input unused + cross_lo - input unused - pwr_hi - output unused, tied low - pwr_oe1 - output unused, undefined - pwr_oe2 - output unused, undefined - pwr_oe3 - output unused, undefined - pwr_oe4 - output unused, undefined - dbg - output alias for adc_clk + pwr_hi - output unused, tied low + pwr_oe1 - output unused, undefined + pwr_oe2 - output unused, undefined + pwr_oe3 - output unused, undefined + pwr_oe4 - output unused, undefined + dbg - output alias for adc_clk */ module testbed_lo_read; - reg pck0; - reg [7:0] adc_d; - reg lo_is_125khz; - reg [15:0] divisor; + reg pck0; + reg [7:0] adc_d; + reg lo_is_125khz; + reg [15:0] divisor; - wire pwr_lo; - wire adc_clk; - wire ck_1356meg; - wire ck_1356megb; - wire ssp_frame; - wire ssp_din; - wire ssp_clk; - reg ssp_dout; - wire pwr_hi; - wire pwr_oe1; - wire pwr_oe2; - wire pwr_oe3; - wire pwr_oe4; - wire cross_lo; - wire cross_hi; - wire dbg; + wire pwr_lo; + wire adc_clk; + wire ck_1356meg; + wire ck_1356megb; + wire ssp_frame; + wire ssp_din; + wire ssp_clk; + reg ssp_dout; + wire pwr_hi; + wire pwr_oe1; + wire pwr_oe2; + wire pwr_oe3; + wire pwr_oe4; + wire cross_lo; + wire cross_hi; + wire dbg; - lo_read #(5,10) dut( - .pck0(pck0), - .ck_1356meg(ck_1356meg), - .ck_1356megb(ck_1356megb), - .pwr_lo(pwr_lo), - .pwr_hi(pwr_hi), - .pwr_oe1(pwr_oe1), - .pwr_oe2(pwr_oe2), - .pwr_oe3(pwr_oe3), - .pwr_oe4(pwr_oe4), - .adc_d(adc_d), - .adc_clk(adc_clk), - .ssp_frame(ssp_frame), - .ssp_din(ssp_din), - .ssp_dout(ssp_dout), - .ssp_clk(ssp_clk), - .cross_hi(cross_hi), - .cross_lo(cross_lo), - .dbg(dbg), - .lo_is_125khz(lo_is_125khz), - .divisor(divisor) - ); + lo_read #(5,10) dut( + .pck0(pck0), + .ck_1356meg(ck_1356meg), + .ck_1356megb(ck_1356megb), + .pwr_lo(pwr_lo), + .pwr_hi(pwr_hi), + .pwr_oe1(pwr_oe1), + .pwr_oe2(pwr_oe2), + .pwr_oe3(pwr_oe3), + .pwr_oe4(pwr_oe4), + .adc_d(adc_d), + .adc_clk(adc_clk), + .ssp_frame(ssp_frame), + .ssp_din(ssp_din), + .ssp_dout(ssp_dout), + .ssp_clk(ssp_clk), + .cross_hi(cross_hi), + .cross_lo(cross_lo), + .dbg(dbg), + .lo_is_125khz(lo_is_125khz), + .divisor(divisor) + ); - integer idx, i, adc_val=8; + integer idx, i, adc_val=8; - // main clock - always #5 pck0 = !pck0; + // main clock + always #5 pck0 = !pck0; - task crank_dut; - begin - @(posedge adc_clk) ; - adc_d = adc_val; - adc_val = (adc_val *2) + 53; - end - endtask + task crank_dut; + begin + @(posedge adc_clk) ; + adc_d = adc_val; + adc_val = (adc_val *2) + 53; + end + endtask - initial begin + initial begin - // init inputs - pck0 = 0; - adc_d = 0; - ssp_dout = 0; - lo_is_125khz = 1; - divisor = 255; //min 16, 95=125Khz, max 255 + // init inputs + pck0 = 0; + adc_d = 0; + ssp_dout = 0; + lo_is_125khz = 1; + divisor = 255; //min 16, 95=125Khz, max 255 - // simulate 4 A/D cycles at 125Khz - for (i = 0 ; i < 8 ; i = i + 1) begin - crank_dut; - end - $finish; - end + // simulate 4 A/D cycles at 125Khz + for (i = 0 ; i < 8 ; i = i + 1) begin + crank_dut; + end + $finish; + end endmodule // main diff --git a/fpga/testbed_lo_simulate.v b/fpga/testbed_lo_simulate.v index 70b6331f9..e056202ad 100644 --- a/fpga/testbed_lo_simulate.v +++ b/fpga/testbed_lo_simulate.v @@ -1,101 +1,101 @@ `include "lo_simulate.v" /* - pck0 - input main 24Mhz clock (PLL / 4) - [7:0] adc_d - input data from A/D converter + pck0 - input main 24Mhz clock (PLL / 4) + [7:0] adc_d - input data from A/D converter - pwr_lo - output to coil drivers (ssp_clk / 8) - adc_clk - output A/D clock signal - ssp_frame - output SSS frame indicator (goes high while the 8 bits are shifted) - ssp_din - output SSP data to ARM (shifts 8 bit A/D value serially to ARM MSB first) - ssp_clk - output SSP clock signal + pwr_lo - output to coil drivers (ssp_clk / 8) + adc_clk - output A/D clock signal + ssp_frame - output SSS frame indicator (goes high while the 8 bits are shifted) + ssp_din - output SSP data to ARM (shifts 8 bit A/D value serially to ARM MSB first) + ssp_clk - output SSP clock signal - ck_1356meg - input unused - ck_1356megb - input unused - ssp_dout - input unused - cross_hi - input unused - cross_lo - input unused + ck_1356meg - input unused + ck_1356megb - input unused + ssp_dout - input unused + cross_hi - input unused + cross_lo - input unused - pwr_hi - output unused, tied low - pwr_oe1 - output unused, undefined - pwr_oe2 - output unused, undefined - pwr_oe3 - output unused, undefined - pwr_oe4 - output unused, undefined - dbg - output alias for adc_clk + pwr_hi - output unused, tied low + pwr_oe1 - output unused, undefined + pwr_oe2 - output unused, undefined + pwr_oe3 - output unused, undefined + pwr_oe4 - output unused, undefined + dbg - output alias for adc_clk */ module testbed_lo_simulate; - reg pck0; - reg [7:0] adc_d; + reg pck0; + reg [7:0] adc_d; - wire pwr_lo; - wire adc_clk; - wire ck_1356meg; - wire ck_1356megb; - wire ssp_frame; - wire ssp_din; - wire ssp_clk; - reg ssp_dout; - wire pwr_hi; - wire pwr_oe1; - wire pwr_oe2; - wire pwr_oe3; - wire pwr_oe4; - reg cross_lo; - wire cross_hi; - wire dbg; + wire pwr_lo; + wire adc_clk; + wire ck_1356meg; + wire ck_1356megb; + wire ssp_frame; + wire ssp_din; + wire ssp_clk; + reg ssp_dout; + wire pwr_hi; + wire pwr_oe1; + wire pwr_oe2; + wire pwr_oe3; + wire pwr_oe4; + reg cross_lo; + wire cross_hi; + wire dbg; - lo_simulate #(5,200) dut( - .pck0(pck0), - .ck_1356meg(ck_1356meg), - .ck_1356megb(ck_1356megb), - .pwr_lo(pwr_lo), - .pwr_hi(pwr_hi), - .pwr_oe1(pwr_oe1), - .pwr_oe2(pwr_oe2), - .pwr_oe3(pwr_oe3), - .pwr_oe4(pwr_oe4), - .adc_d(adc_d), - .adc_clk(adc_clk), - .ssp_frame(ssp_frame), - .ssp_din(ssp_din), - .ssp_dout(ssp_dout), - .ssp_clk(ssp_clk), - .cross_hi(cross_hi), - .cross_lo(cross_lo), - .dbg(dbg) - ); + lo_simulate #(5,200) dut( + .pck0(pck0), + .ck_1356meg(ck_1356meg), + .ck_1356megb(ck_1356megb), + .pwr_lo(pwr_lo), + .pwr_hi(pwr_hi), + .pwr_oe1(pwr_oe1), + .pwr_oe2(pwr_oe2), + .pwr_oe3(pwr_oe3), + .pwr_oe4(pwr_oe4), + .adc_d(adc_d), + .adc_clk(adc_clk), + .ssp_frame(ssp_frame), + .ssp_din(ssp_din), + .ssp_dout(ssp_dout), + .ssp_clk(ssp_clk), + .cross_hi(cross_hi), + .cross_lo(cross_lo), + .dbg(dbg) + ); - integer i, counter=0; + integer i, counter=0; - // main clock - always #5 pck0 = !pck0; + // main clock + always #5 pck0 = !pck0; - //cross_lo is not really synced to pck0 but it's roughly pck0/192 (24Mhz/192=125Khz) - task crank_dut; - begin - @(posedge pck0) ; - counter = counter + 1; - if (counter == 192) begin - counter = 0; - ssp_dout = $random; - cross_lo = 1; - end else begin - cross_lo = 0; - end - - end - endtask + //cross_lo is not really synced to pck0 but it's roughly pck0/192 (24Mhz/192=125Khz) + task crank_dut; + begin + @(posedge pck0) ; + counter = counter + 1; + if (counter == 192) begin + counter = 0; + ssp_dout = $random; + cross_lo = 1; + end else begin + cross_lo = 0; + end - initial begin - pck0 = 0; - for (i = 0 ; i < 4096 ; i = i + 1) begin - crank_dut; - end - $finish; - end + end + endtask + + initial begin + pck0 = 0; + for (i = 0 ; i < 4096 ; i = i + 1) begin + crank_dut; + end + $finish; + end endmodule // main diff --git a/fpga/tests/tb_lf_edge_detect.v b/fpga/tests/tb_lf_edge_detect.v index a9fccf8bd..f2a373be9 100644 --- a/fpga/tests/tb_lf_edge_detect.v +++ b/fpga/tests/tb_lf_edge_detect.v @@ -20,16 +20,16 @@ module lf_edge_detect_tb; - integer fin, fout_state, fout_toggle; - integer fout_high, fout_highz, fout_lowz, fout_low, fout_min, fout_max; - integer r; + integer fin, fout_state, fout_toggle; + integer fout_high, fout_highz, fout_lowz, fout_low, fout_min, fout_max; + integer r; - reg clk = 0; - reg [7:0] adc_d; - wire adc_clk; - wire data_rdy; - wire edge_state; - wire edge_toggle; + reg clk = 0; + reg [7:0] adc_d; + wire adc_clk; + wire data_rdy; + wire edge_state; + wire edge_toggle; wire [7:0] high_threshold; wire [7:0] highz_threshold; @@ -38,74 +38,74 @@ module lf_edge_detect_tb; wire [7:0] max; wire [7:0] min; - initial - begin - clk = 0; - fin = $fopen(`FIN, "r"); - if (!fin) begin - $display("ERROR: can't open the data file"); - $finish; - end - fout_min = $fopen(`FOUT_MIN, "w+"); - fout_max = $fopen(`FOUT_MAX, "w+"); - fout_state = $fopen(`FOUT_STATE, "w+"); - fout_toggle = $fopen(`FOUT_TOGGLE, "w+"); - fout_high = $fopen(`FOUT_HIGH, "w+"); - fout_highz = $fopen(`FOUT_HIGHZ, "w+"); - fout_lowz = $fopen(`FOUT_LOWZ, "w+"); - fout_low = $fopen(`FOUT_LOW, "w+"); - if (!$feof(fin)) - adc_d = $fgetc(fin); // read the first value - end + initial + begin + clk = 0; + fin = $fopen(`FIN, "r"); + if (!fin) begin + $display("ERROR: can't open the data file"); + $finish; + end + fout_min = $fopen(`FOUT_MIN, "w+"); + fout_max = $fopen(`FOUT_MAX, "w+"); + fout_state = $fopen(`FOUT_STATE, "w+"); + fout_toggle = $fopen(`FOUT_TOGGLE, "w+"); + fout_high = $fopen(`FOUT_HIGH, "w+"); + fout_highz = $fopen(`FOUT_HIGHZ, "w+"); + fout_lowz = $fopen(`FOUT_LOWZ, "w+"); + fout_low = $fopen(`FOUT_LOW, "w+"); + if (!$feof(fin)) + adc_d = $fgetc(fin); // read the first value + end - always - # 1 clk = !clk; + always + # 1 clk = !clk; - // input - initial - begin - while (!$feof(fin)) begin - @(negedge clk) adc_d <= $fgetc(fin); - end + // input + initial + begin + while (!$feof(fin)) begin + @(negedge clk) adc_d <= $fgetc(fin); + end - if ($feof(fin)) - begin - # 3 $fclose(fin); - $fclose(fout_state); - $fclose(fout_toggle); - $fclose(fout_high); - $fclose(fout_highz); - $fclose(fout_lowz); - $fclose(fout_low); - $fclose(fout_min); - $fclose(fout_max); - $finish; - end - end + if ($feof(fin)) + begin + # 3 $fclose(fin); + $fclose(fout_state); + $fclose(fout_toggle); + $fclose(fout_high); + $fclose(fout_highz); + $fclose(fout_lowz); + $fclose(fout_low); + $fclose(fout_min); + $fclose(fout_max); + $finish; + end + end - initial - begin - // $monitor("%d\t S: %b, E: %b", $time, edge_state, edge_toggle); - end + initial + begin + // $monitor("%d\t S: %b, E: %b", $time, edge_state, edge_toggle); + end - // output - always @(negedge clk) - if ($time > 2) begin - r = $fputc(min, fout_min); - r = $fputc(max, fout_max); - r = $fputc(edge_state, fout_state); - r = $fputc(edge_toggle, fout_toggle); - r = $fputc(high_threshold, fout_high); - r = $fputc(highz_threshold, fout_highz); - r = $fputc(lowz_threshold, fout_lowz); - r = $fputc(low_threshold, fout_low); - end + // output + always @(negedge clk) + if ($time > 2) begin + r = $fputc(min, fout_min); + r = $fputc(max, fout_max); + r = $fputc(edge_state, fout_state); + r = $fputc(edge_toggle, fout_toggle); + r = $fputc(high_threshold, fout_high); + r = $fputc(highz_threshold, fout_highz); + r = $fputc(lowz_threshold, fout_lowz); + r = $fputc(low_threshold, fout_low); + end - // module to test - lf_edge_detect detect(clk, adc_d, 8'd127, - max, min, - high_threshold, highz_threshold, - lowz_threshold, low_threshold, - edge_state, edge_toggle); + // module to test + lf_edge_detect detect(clk, adc_d, 8'd127, + max, min, + high_threshold, highz_threshold, + lowz_threshold, low_threshold, + edge_state, edge_toggle); -endmodule \ No newline at end of file +endmodule diff --git a/fpga/tests/tb_lp20khz_1MSa_iir_filter.v b/fpga/tests/tb_lp20khz_1MSa_iir_filter.v index ad0cfc6e6..e78c475e1 100644 --- a/fpga/tests/tb_lp20khz_1MSa_iir_filter.v +++ b/fpga/tests/tb_lp20khz_1MSa_iir_filter.v @@ -13,43 +13,43 @@ module lp20khz_1MSa_iir_filter_tb; - integer fin, fout, r; + integer fin, fout, r; - reg clk; - reg [7:0] adc_d; - wire data_rdy; - wire [7:0] adc_filtered; + reg clk; + reg [7:0] adc_d; + wire data_rdy; + wire [7:0] adc_filtered; - initial - begin - clk = 0; - fin = $fopen(`FIN, "r"); - if (!fin) begin - $display("ERROR: can't open the data file"); - $finish; - end - fout = $fopen(`FOUT, "w+"); - if (!$feof(fin)) - adc_d = $fgetc(fin); // read the first value - end + initial + begin + clk = 0; + fin = $fopen(`FIN, "r"); + if (!fin) begin + $display("ERROR: can't open the data file"); + $finish; + end + fout = $fopen(`FOUT, "w+"); + if (!$feof(fin)) + adc_d = $fgetc(fin); // read the first value + end - always - # 1 clk = !clk; + always + # 1 clk = !clk; - always @(posedge clk) - if (data_rdy) begin - if ($time > 1) - r = $fputc(adc_filtered, fout); - if (!$feof(fin)) - adc_d <= $fgetc(fin); - else begin - $fclose(fin); - $fclose(fout); - $finish; - end - end + always @(posedge clk) + if (data_rdy) begin + if ($time > 1) + r = $fputc(adc_filtered, fout); + if (!$feof(fin)) + adc_d <= $fgetc(fin); + else begin + $fclose(fin); + $fclose(fout); + $finish; + end + end - // module to test - lp20khz_1MSa_iir_filter filter(clk, adc_d, data_rdy, adc_filtered); + // module to test + lp20khz_1MSa_iir_filter filter(clk, adc_d, data_rdy, adc_filtered); endmodule diff --git a/fpga/tests/tb_min_max_tracker.v b/fpga/tests/tb_min_max_tracker.v index 4cccc3f1d..3bec6c7da 100644 --- a/fpga/tests/tb_min_max_tracker.v +++ b/fpga/tests/tb_min_max_tracker.v @@ -14,61 +14,61 @@ module min_max_tracker_tb; - integer fin; - integer fout_min, fout_max; - integer r; + integer fin; + integer fout_min, fout_max; + integer r; - reg clk; - reg [7:0] adc_d; - wire [7:0] min; - wire [7:0] max; + reg clk; + reg [7:0] adc_d; + wire [7:0] min; + wire [7:0] max; - initial - begin - clk = 0; - fin = $fopen(`FIN, "r"); - if (!fin) begin - $display("ERROR: can't open the data file"); - $finish; - end - fout_min = $fopen(`FOUT_MIN, "w+"); - fout_max = $fopen(`FOUT_MAX, "w+"); - if (!$feof(fin)) - adc_d = $fgetc(fin); // read the first value - end + initial + begin + clk = 0; + fin = $fopen(`FIN, "r"); + if (!fin) begin + $display("ERROR: can't open the data file"); + $finish; + end + fout_min = $fopen(`FOUT_MIN, "w+"); + fout_max = $fopen(`FOUT_MAX, "w+"); + if (!$feof(fin)) + adc_d = $fgetc(fin); // read the first value + end - always - # 1 clk = !clk; + always + # 1 clk = !clk; - // input - initial - begin - while (!$feof(fin)) begin - @(negedge clk) adc_d <= $fgetc(fin); - end + // input + initial + begin + while (!$feof(fin)) begin + @(negedge clk) adc_d <= $fgetc(fin); + end - if ($feof(fin)) - begin - # 3 $fclose(fin); - $fclose(fout_min); - $fclose(fout_max); - $finish; - end - end + if ($feof(fin)) + begin + # 3 $fclose(fin); + $fclose(fout_min); + $fclose(fout_max); + $finish; + end + end - initial - begin - // $monitor("%d\t min: %x, max: %x", $time, min, max); - end + initial + begin + // $monitor("%d\t min: %x, max: %x", $time, min, max); + end - // output - always @(negedge clk) - if ($time > 2) begin - r = $fputc(min, fout_min); - r = $fputc(max, fout_max); - end + // output + always @(negedge clk) + if ($time > 2) begin + r = $fputc(min, fout_min); + r = $fputc(max, fout_max); + end - // module to test - min_max_tracker tracker(clk, adc_d, 8'd127, min, max); + // module to test + min_max_tracker tracker(clk, adc_d, 8'd127, min, max); -endmodule \ No newline at end of file +endmodule From 3878f62168409c61fe805f0d084e223f7f3f8969 Mon Sep 17 00:00:00 2001 From: cjbrigato Date: Wed, 31 Jul 2019 01:32:16 +0200 Subject: [PATCH 0187/1854] HF_COLIN : Now able to read Known Mifare 1K key schemes from JSON Conf file from SPIFFS. BEWARE : DO NOT USE : Very Messy and early implementation --- armsrc/Standalone/Makefile.inc | 2 +- armsrc/Standalone/hf_colin.c | 240 ++++-- armsrc/frozen.c | 1473 ++++++++++++++++++++++++++++++++ armsrc/frozen.h | 329 +++++++ armsrc/nprintf.c | 914 ++++++++++++++++++++ armsrc/nprintf.h | 117 +++ armsrc/string.c | 154 ++++ armsrc/string.h | 11 + 8 files changed, 3162 insertions(+), 78 deletions(-) create mode 100644 armsrc/frozen.c create mode 100644 armsrc/frozen.h create mode 100644 armsrc/nprintf.c create mode 100644 armsrc/nprintf.h diff --git a/armsrc/Standalone/Makefile.inc b/armsrc/Standalone/Makefile.inc index cc7221a73..66dfc6da2 100644 --- a/armsrc/Standalone/Makefile.inc +++ b/armsrc/Standalone/Makefile.inc @@ -27,7 +27,7 @@ ifneq (,$(findstring WITH_STANDALONE_HF_MATTYRUN,$(APP_CFLAGS))) endif # WITH_STANDALONE_HF_COLIN ifneq (,$(findstring WITH_STANDALONE_HF_COLIN,$(APP_CFLAGS))) - SRC_STANDALONE = vtsend.c hf_colin.c + SRC_STANDALONE = vtsend.c hf_colin.c frozen.c nprintf.c endif # WITH_STANDALONE_HF_BOG ifneq (,$(findstring WITH_STANDALONE_HF_BOG,$(APP_CFLAGS))) diff --git a/armsrc/Standalone/hf_colin.c b/armsrc/Standalone/hf_colin.c index 5eeb2a42a..e280b858e 100644 --- a/armsrc/Standalone/hf_colin.c +++ b/armsrc/Standalone/hf_colin.c @@ -9,11 +9,13 @@ // main code for HF Mifare aka ColinRun by Colin Brigato //----------------------------------------------------------------------------- #include "hf_colin.h" +#include "frozen.h" #define MF1KSZ 1024 #define MF1KSZSIZE 64 #define AUTHENTICATION_TIMEOUT 848 #define HFCOLIN_LASTTAG_SYMLINK "hf_colin/lasttag.bin" +#define HFCOLIN_URMETCAPTIVE_JSON "hf_colin/urmetcaptive.json" uint8_t cjuid[10]; uint32_t cjcuid; @@ -27,6 +29,55 @@ int curlline; // Colin's VIGIKPWN sniff/simulate/clone repeat routine for HF Mifare +static const uint8_t is_hex[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 0, 0, 0, 0, 0, + 0, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + +static inline uint64_t hex2i(const char *s) { + uint64_t val = 0; + if (s == NULL || s[0] == 0) + return 0; + if (s[1] == 'x') + s += 2; + else if (*s == 'x') + s++; + while (is_hex[(uint8_t)*s]) + val = (val << 4) | (is_hex[(uint8_t) * (s++)] - 1); + return val; +} + +/*char *noralsy2test = + "{\"name\":\"noralsy2\",\"trigger\":\"0x414C41524F4E\",\"keysA\":[\"0x414C41524F4E\",\"0x414C41524F4E\"," + "\"0x414C41524F4E\"," + "\"0x414C41524F4E\",\"0x414C41524F4E\",\"0x414C41524F4E\",\"0x414C41524F4E\",\"0x414C41524F4E\"," + "\"0x414C41524F4E\",\"0x414C41524F4E\"," + "\"0x414C41524F4E\",\"0x414C41524F4E\",\"0x414C41524F4E\",\"0x414C41524F4E\",\"0x414C41524F4E\"," + "\"0x414C41524F4E\"],\"keysB\":[" + "\"0x424C41524F4E\",\"0x424C41524F4E\",\"0x424C41524F4E\",\"0x424C41524F4E\",\"0x424C41524F4E\"," + "\"0x424C41524F4E\",\"0x424C41524F4E\"," + "\"0x424C41524F4E\",\"0x424C41524F4E\",\"0x424C41524F4E\",\"0x424C41524F4E\",\"0x424C41524F4E\"," + "\"0x424C41524F4E\",\"0x424C41524F4E\"," + "\"0x424C41524F4E\",\"0x424C41524F4E\"]}";*/ + +/*char *urmetcaptive2test = + "{\"name\":\"urmetcaptive2\",\"trigger\":\"0x8829da9daf76\",\"keysA\":[\"0x8829da9daf76\",\"0x8829da9daf76\"," + "\"0x8829da9daf76\"," + "\"0x8829da9daf76\",\"0x8829da9daf76\",\"0x8829da9daf76\",\"0x8829da9daf76\",\"0x8829da9daf76\"," + "\"0x8829da9daf76\",\"0x8829da9daf76\"," + "\"0x8829da9daf76\",\"0x8829da9daf76\",\"0x8829da9daf76\",\"0x8829da9daf76\",\"0x8829da9daf76\"," + "\"0x8829da9daf76\"],\"keysB\":[" + "\"0x8829da9daf76\",\"0x8829da9daf76\",\"0x8829da9daf76\",\"0x8829da9daf76\",\"0x8829da9daf76\"," + "\"0x8829da9daf76\",\"0x8829da9daf76\"," + "\"0x8829da9daf76\",\"0x8829da9daf76\",\"0x8829da9daf76\",\"0x8829da9daf76\",\"0x8829da9daf76\"," + "\"0x8829da9daf76\",\"0x8829da9daf76\"," + "\"0x8829da9daf76\",\"0x8829da9daf76\"]}";*/ + typedef struct MFC1KSchema { uint8_t name[32]; uint64_t trigger; @@ -36,50 +87,48 @@ typedef struct MFC1KSchema { #define MAX_SCHEMAS 4 +static void scan_keys(const char *str, int len, uint64_t *user_data) { + struct json_token t; + int i; + char ks[32]; + for (i = 0; json_scanf_array_elem(str, len, "", i, &t) > 0; i++) { + sprintf(ks, "%.*s", t.len, t.ptr); + user_data[i] = hex2i(ks); + } +} + MFC1KSchema Schemas[MAX_SCHEMAS]; MFC1KSchema Noralsy = { .name = "Noralsy", .trigger = 0x414c41524f4e, - .keysA = { - 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e, - 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e, - 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e - }, - .keysB = { - 0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e, - 0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e, - 0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e - } -}; + .keysA = {0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e, + 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e, + 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e}, + .keysB = {0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e, + 0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e, + 0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e}}; MFC1KSchema InfiHexact = {.name = "Infineon/Hexact", .trigger = 0x484558414354, .keysA = {0x484558414354, 0x484558414354, 0x484558414354, 0x484558414354, 0x484558414354, 0x484558414354, 0x484558414354, 0x484558414354, 0x484558414354, 0x484558414354, 0x484558414354, 0x484558414354, 0x484558414354, 0x484558414354, 0x484558414354, - 0x484558414354 - }, + 0x484558414354}, .keysB = {0xa22ae129c013, 0x49fae4e3849f, 0x38fcf33072e0, 0x8ad5517b4b18, 0x509359f131b1, 0x6c78928e1317, 0xaa0720018738, 0xa6cac2886412, 0x62d0c424ed8e, 0xe64a986a5d94, - 0x8fa1d601d0a2, 0x89347350bd36, 0x66d2b7dc39ef, 0x6bc1e1ae547d, 0x22729a9bd40f - } - }; + 0x8fa1d601d0a2, 0x89347350bd36, 0x66d2b7dc39ef, 0x6bc1e1ae547d, 0x22729a9bd40f}}; -MFC1KSchema UrmetCaptive = { +/*MFC1KSchema UrmetCaptive = { .name = "Urmet Captive", .trigger = 0x8829da9daf76, - .keysA = { - 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, - 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, - 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76 - }, - .keysB = { - 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, - 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, - 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76 - } -}; + .keysA = {0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, + 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, + 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76}, + .keysB = {0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, + 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, + 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76}}; +*/ int total_schemas = 0; @@ -125,6 +174,31 @@ foundKey[5]); cjSetCursRight(); DbprintfEx(FLAG_NEWLINE, "SEC: %02x | KEY : %s | } */ +char *ReadSchemasFromSPIFFS() { + SpinOff(0); + LED_A_ON(); + LED_B_ON(); + LED_C_ON(); + LED_D_ON(); + + DbprintfEx(FLAG_NEWLINE, "Reading Json Configuration Files..."); + cjSetCursLeft(); + + int changed = rdv40_spiffs_lazy_mount(); + uint32_t size = size_in_spiffs((char *)HFCOLIN_URMETCAPTIVE_JSON); + uint8_t *mem = BigBuf_malloc(size); + // this one will handle filetype (symlink or not) and resolving by itself + rdv40_spiffs_read_as_filetype((char *)HFCOLIN_URMETCAPTIVE_JSON, (uint8_t *)mem, size, RDV40_SPIFFS_SAFETY_SAFE); + + if (changed) { + rdv40_spiffs_lazy_unmount(); + } + DbprintfEx(FLAG_NEWLINE, "[OK] Returning One config file"); + cjSetCursLeft(); + SpinOff(0); + return (char *)mem; +} + void ReadLastTagFromFlash() { SpinOff(0); LED_A_ON(); @@ -185,9 +259,21 @@ void ModInfo(void) { DbpString(" HF Mifare ultra fast sniff/sim/clone - aka VIG void RunMod() { StandAloneMode(); + char *tmpname; + char *tmptrigger; + MFC1KSchema tmpscheme; + char *urmetcaptive2test = ReadSchemasFromSPIFFS(); + json_scanf(urmetcaptive2test, strlen(urmetcaptive2test), "{ name:%Q, trigger:%Q, keysA:%M, keysB:%M}", &tmpname, + &tmptrigger, scan_keys, &tmpscheme.keysA, scan_keys, &tmpscheme.keysB); + + memcpy(tmpscheme.name, tmpname, 32); + tmpscheme.trigger = hex2i(tmptrigger); + + add_schema(Schemas, tmpscheme, &total_schemas); + add_schema(Schemas, Noralsy, &total_schemas); add_schema(Schemas, InfiHexact, &total_schemas); - add_schema(Schemas, UrmetCaptive, &total_schemas); + // add_schema(Schemas, UrmetCaptive, &total_schemas); FpgaDownloadAndGo(FPGA_BITSTREAM_HF); @@ -200,41 +286,41 @@ void RunMod() { uint64_t key64; // Defines current key uint8_t *keyBlock; // Where the keys will be held in memory. - /* VIGIK EXPIRED DUMP FOR STUDY - Sector 0 - 121C7F730208040001FA33F5CB2D021D - 44001049164916491649000000000000 - 00000000000000000000000000000000 - A0A1A2A3A4A579678800010203040506 - Sector 1 - 0F000000000000000000000000000000 - AA0700002102080000740C110600AF13 - 000000000000000001740C1108220000 - 314B4947495679678800010203040506 - Sector 2 - 24E572B923A3D243B402D60CAB576956 - 216D6501FC8618B6C426762511AC2DEE - 25BF4CEC3618D0BAB3A6E9210D887746 - 314B4947495679678800010203040506 - Sector 3 - 0FBC41A5D95398E76A1B2029E8EA9735 - 088BA2CE732653D0C1147596AFCF94D7 - 77B4D91F0442182273A29DEAF7A2D095 - 314B4947495679678800010203040506 - Sector 4 - 4CEE715866E508CDBC95C640EC9D1E58 - E800457CF8B079414E1B45DD3E6C9317 - 77B4D91F0442182273A29DEAF7A2D095 - 314B4947495679678800010203040506 - 010203040506 0 - Sector 5-0F - 00000000000000000000000000000000 - 00000000000000000000000000000000 - 00000000000000000000000000000000 - FFFFFFFFFFFFFF078069FFFFFFFFFFFF - KEY A : 1KGIV ; - ACCBITS : 796788[00]+VALUE - */ +/* VIGIK EXPIRED DUMP FOR STUDY +Sector 0 +121C7F730208040001FA33F5CB2D021D +44001049164916491649000000000000 +00000000000000000000000000000000 +A0A1A2A3A4A579678800010203040506 +Sector 1 +0F000000000000000000000000000000 +AA0700002102080000740C110600AF13 +000000000000000001740C1108220000 +314B4947495679678800010203040506 +Sector 2 +24E572B923A3D243B402D60CAB576956 +216D6501FC8618B6C426762511AC2DEE +25BF4CEC3618D0BAB3A6E9210D887746 +314B4947495679678800010203040506 +Sector 3 +0FBC41A5D95398E76A1B2029E8EA9735 +088BA2CE732653D0C1147596AFCF94D7 +77B4D91F0442182273A29DEAF7A2D095 +314B4947495679678800010203040506 +Sector 4 +4CEE715866E508CDBC95C640EC9D1E58 +E800457CF8B079414E1B45DD3E6C9317 +77B4D91F0442182273A29DEAF7A2D095 +314B4947495679678800010203040506 +010203040506 0 +Sector 5-0F +00000000000000000000000000000000 +00000000000000000000000000000000 +00000000000000000000000000000000 +FFFFFFFFFFFFFF078069FFFFFFFFFFFF +KEY A : 1KGIV ; +ACCBITS : 796788[00]+VALUE +*/ //---------------------------- // Set of keys to be used. @@ -569,18 +655,18 @@ readysim: uint16_t flags; switch (p_card.uidlen) { - case 10: - flags = FLAG_10B_UID_IN_DATA; - break; - case 7: - flags = FLAG_7B_UID_IN_DATA; - break; - case 4: - flags = FLAG_4B_UID_IN_DATA; - break; - default: - flags = FLAG_UID_IN_EMUL; - break; + case 10: + flags = FLAG_10B_UID_IN_DATA; + break; + case 7: + flags = FLAG_7B_UID_IN_DATA; + break; + case 4: + flags = FLAG_4B_UID_IN_DATA; + break; + default: + flags = FLAG_UID_IN_EMUL; + break; } // Use UID, SAK, ATQA from EMUL, if uid not defined @@ -898,7 +984,7 @@ int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *data } if ((mifare_sendcmd_short(NULL, 0, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 1) || - (receivedAnswer[0] != 0x0a)) { + (receivedAnswer[0] != 0x0a)) { DbprintfEx(FLAG_NEWLINE, "write block send command error"); break; }; diff --git a/armsrc/frozen.c b/armsrc/frozen.c new file mode 100644 index 000000000..f467f9554 --- /dev/null +++ b/armsrc/frozen.c @@ -0,0 +1,1473 @@ +/* + * Copyright (c) 2004-2013 Sergey Lyubka + * Copyright (c) 2018 Cesanta Software Limited + * All rights reserved + * + * Licensed under the Apache License, Version 2.0 (the ""License""); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an ""AS IS"" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define _CRT_SECURE_NO_WARNINGS /* Disable deprecation warning in VS2005+ */ + +#include "frozen.h" + +//#include +#include +#include +#include +#include +#include "nprintf.h" + +#include "BigBuf.h" +#define malloc(X) BigBuf_malloc(X) +#define free(X) + +#if !defined(WEAK) +#if (defined(__GNUC__) || defined(__TI_COMPILER_VERSION__)) && !defined(_WIN32) +#define WEAK __attribute__((weak)) +#else +#define WEAK +#endif +#endif + +#ifdef _WIN32 +#undef snprintf +#undef vsnprintf +#define snprintf cs_win_snprintf +#define vsnprintf cs_win_vsnprintf +int cs_win_snprintf(char *str, size_t size, const char *format, ...); +int cs_win_vsnprintf(char *str, size_t size, const char *format, va_list ap); +#if _MSC_VER >= 1700 +#include +#else +typedef _int64 int64_t; +typedef unsigned _int64 uint64_t; +#endif +#define PRId64 "I64d" +#define PRIu64 "I64u" +#else /* _WIN32 */ +/* wants this for C++ */ +#ifndef __STDC_FORMAT_MACROS +#define __STDC_FORMAT_MACROS +#endif +#include +#endif /* _WIN32 */ + +#ifndef INT64_FMT +#define INT64_FMT PRId64 +#endif +#ifndef UINT64_FMT +#define UINT64_FMT PRIu64 +#endif + +#ifndef va_copy +#define va_copy(x, y) x = y +#endif + +#ifndef JSON_ENABLE_ARRAY +#define JSON_ENABLE_ARRAY 1 +#endif + +struct frozen { + const char *end; + const char *cur; + + const char *cur_name; + size_t cur_name_len; + + /* For callback API */ + char path[JSON_MAX_PATH_LEN]; + size_t path_len; + void *callback_data; + json_walk_callback_t callback; +}; + +struct fstate { + const char *ptr; + size_t path_len; +}; + +#define SET_STATE(fr, ptr, str, len) \ + struct fstate fstate = {(ptr), (fr)->path_len}; \ + json_append_to_path((fr), (str), (len)); + +#define CALL_BACK(fr, tok, value, len) \ + do { \ + if ((fr)->callback && \ + ((fr)->path_len == 0 || (fr)->path[(fr)->path_len - 1] != '.')) { \ + struct json_token t = {(value), (int) (len), (tok)}; \ + \ + /* Call the callback with the given value and current name */ \ + (fr)->callback((fr)->callback_data, (fr)->cur_name, (fr)->cur_name_len, \ + (fr)->path, &t); \ + \ + /* Reset the name */ \ + (fr)->cur_name = NULL; \ + (fr)->cur_name_len = 0; \ + } \ + } while (0) + +static int json_append_to_path(struct frozen *f, const char *str, int size) { + int n = f->path_len; + int left = sizeof(f->path) - n - 1; + if (size > left) size = left; + memcpy(f->path + n, str, size); + f->path[n + size] = '\0'; + f->path_len += size; + return n; +} + +static void json_truncate_path(struct frozen *f, size_t len) { + f->path_len = len; + f->path[len] = '\0'; +} + +static int json_parse_object(struct frozen *f); +static int json_parse_value(struct frozen *f); + +#define EXPECT(cond, err_code) \ + do { \ + if (!(cond)) return (err_code); \ + } while (0) + +#define TRY(expr) \ + do { \ + int _n = expr; \ + if (_n < 0) return _n; \ + } while (0) + +#define END_OF_STRING (-1) + +static int json_left(const struct frozen *f) { + return f->end - f->cur; +} + +static int json_isspace(int ch) { + return ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n'; +} + +static void json_skip_whitespaces(struct frozen *f) { + while (f->cur < f->end && json_isspace(*f->cur)) f->cur++; +} + +static int json_cur(struct frozen *f) { + json_skip_whitespaces(f); + return f->cur >= f->end ? END_OF_STRING : *(unsigned char *) f->cur; +} + +static int json_test_and_skip(struct frozen *f, int expected) { + int ch = json_cur(f); + if (ch == expected) { + f->cur++; + return 0; + } + return ch == END_OF_STRING ? JSON_STRING_INCOMPLETE : JSON_STRING_INVALID; +} + +static int json_isalpha(int ch) { + return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'); +} + +static int json_isdigit(int ch) { + return ch >= '0' && ch <= '9'; +} + +static int json_isxdigit(int ch) { + return json_isdigit(ch) || (ch >= 'a' && ch <= 'f') || + (ch >= 'A' && ch <= 'F'); +} + +static int json_get_escape_len(const char *s, int len) { + switch (*s) { + case 'u': + return len < 6 ? JSON_STRING_INCOMPLETE + : json_isxdigit(s[1]) && json_isxdigit(s[2]) && + json_isxdigit(s[3]) && json_isxdigit(s[4]) + ? 5 + : JSON_STRING_INVALID; + case '"': + case '\\': + case '/': + case 'b': + case 'f': + case 'n': + case 'r': + case 't': + return len < 2 ? JSON_STRING_INCOMPLETE : 1; + default: + return JSON_STRING_INVALID; + } +} + +/* identifier = letter { letter | digit | '_' } */ +static int json_parse_identifier(struct frozen *f) { + EXPECT(json_isalpha(json_cur(f)), JSON_STRING_INVALID); + { + SET_STATE(f, f->cur, "", 0); + while (f->cur < f->end && + (*f->cur == '_' || json_isalpha(*f->cur) || json_isdigit(*f->cur))) { + f->cur++; + } + json_truncate_path(f, fstate.path_len); + CALL_BACK(f, JSON_TYPE_STRING, fstate.ptr, f->cur - fstate.ptr); + } + return 0; +} + +static int json_get_utf8_char_len(unsigned char ch) { + if ((ch & 0x80) == 0) return 1; + switch (ch & 0xf0) { + case 0xf0: + return 4; + case 0xe0: + return 3; + default: + return 2; + } +} + +/* string = '"' { quoted_printable_chars } '"' */ +static int json_parse_string(struct frozen *f) { + int n, ch = 0, len = 0; + TRY(json_test_and_skip(f, '"')); + { + SET_STATE(f, f->cur, "", 0); + for (; f->cur < f->end; f->cur += len) { + ch = *(unsigned char *) f->cur; + len = json_get_utf8_char_len((unsigned char) ch); + EXPECT(ch >= 32 && len > 0, JSON_STRING_INVALID); /* No control chars */ + EXPECT(len <= json_left(f), JSON_STRING_INCOMPLETE); + if (ch == '\\') { + EXPECT((n = json_get_escape_len(f->cur + 1, json_left(f))) > 0, n); + len += n; + } else if (ch == '"') { + json_truncate_path(f, fstate.path_len); + CALL_BACK(f, JSON_TYPE_STRING, fstate.ptr, f->cur - fstate.ptr); + f->cur++; + break; + }; + } + } + return ch == '"' ? 0 : JSON_STRING_INCOMPLETE; +} + +/* number = [ '-' ] digit+ [ '.' digit+ ] [ ['e'|'E'] ['+'|'-'] digit+ ] */ +static int json_parse_number(struct frozen *f) { + int ch = json_cur(f); + SET_STATE(f, f->cur, "", 0); + if (ch == '-') f->cur++; + EXPECT(f->cur < f->end, JSON_STRING_INCOMPLETE); + if (f->cur + 1 < f->end && f->cur[0] == '0' && f->cur[1] == 'x') { + f->cur += 2; + EXPECT(f->cur < f->end, JSON_STRING_INCOMPLETE); + EXPECT(json_isxdigit(f->cur[0]), JSON_STRING_INVALID); + while (f->cur < f->end && json_isxdigit(f->cur[0])) f->cur++; + } else { + EXPECT(json_isdigit(f->cur[0]), JSON_STRING_INVALID); + while (f->cur < f->end && json_isdigit(f->cur[0])) f->cur++; + if (f->cur < f->end && f->cur[0] == '.') { + f->cur++; + EXPECT(f->cur < f->end, JSON_STRING_INCOMPLETE); + EXPECT(json_isdigit(f->cur[0]), JSON_STRING_INVALID); + while (f->cur < f->end && json_isdigit(f->cur[0])) f->cur++; + } + if (f->cur < f->end && (f->cur[0] == 'e' || f->cur[0] == 'E')) { + f->cur++; + EXPECT(f->cur < f->end, JSON_STRING_INCOMPLETE); + if ((f->cur[0] == '+' || f->cur[0] == '-')) f->cur++; + EXPECT(f->cur < f->end, JSON_STRING_INCOMPLETE); + EXPECT(json_isdigit(f->cur[0]), JSON_STRING_INVALID); + while (f->cur < f->end && json_isdigit(f->cur[0])) f->cur++; + } + } + json_truncate_path(f, fstate.path_len); + CALL_BACK(f, JSON_TYPE_NUMBER, fstate.ptr, f->cur - fstate.ptr); + return 0; +} + +#if JSON_ENABLE_ARRAY +/* array = '[' [ value { ',' value } ] ']' */ +static int json_parse_array(struct frozen *f) { + int i = 0, current_path_len; + char buf[20]; + CALL_BACK(f, JSON_TYPE_ARRAY_START, NULL, 0); + TRY(json_test_and_skip(f, '[')); + { + { + SET_STATE(f, f->cur - 1, "", 0); + while (json_cur(f) != ']') { + snprintf(buf, sizeof(buf), "[%d]", i); + i++; + current_path_len = json_append_to_path(f, buf, strlen(buf)); + f->cur_name = + f->path + strlen(f->path) - strlen(buf) + 1 /*opening brace*/; + f->cur_name_len = strlen(buf) - 2 /*braces*/; + TRY(json_parse_value(f)); + json_truncate_path(f, current_path_len); + if (json_cur(f) == ',') f->cur++; + } + TRY(json_test_and_skip(f, ']')); + json_truncate_path(f, fstate.path_len); + CALL_BACK(f, JSON_TYPE_ARRAY_END, fstate.ptr, f->cur - fstate.ptr); + } + } + return 0; +} +#endif /* JSON_ENABLE_ARRAY */ + +static int json_expect(struct frozen *f, const char *s, int len, + enum json_token_type tok_type) { + int i, n = json_left(f); + SET_STATE(f, f->cur, "", 0); + for (i = 0; i < len; i++) { + if (i >= n) return JSON_STRING_INCOMPLETE; + if (f->cur[i] != s[i]) return JSON_STRING_INVALID; + } + f->cur += len; + json_truncate_path(f, fstate.path_len); + + CALL_BACK(f, tok_type, fstate.ptr, f->cur - fstate.ptr); + + return 0; +} + +/* value = 'null' | 'true' | 'false' | number | string | array | object */ +static int json_parse_value(struct frozen *f) { + int ch = json_cur(f); + + switch (ch) { + case '"': + TRY(json_parse_string(f)); + break; + case '{': + TRY(json_parse_object(f)); + break; +#if JSON_ENABLE_ARRAY + case '[': + TRY(json_parse_array(f)); + break; +#endif + case 'n': + TRY(json_expect(f, "null", 4, JSON_TYPE_NULL)); + break; + case 't': + TRY(json_expect(f, "true", 4, JSON_TYPE_TRUE)); + break; + case 'f': + TRY(json_expect(f, "false", 5, JSON_TYPE_FALSE)); + break; + case '-': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + TRY(json_parse_number(f)); + break; + default: + return ch == END_OF_STRING ? JSON_STRING_INCOMPLETE : JSON_STRING_INVALID; + } + + return 0; +} + +/* key = identifier | string */ +static int json_parse_key(struct frozen *f) { + int ch = json_cur(f); + if (json_isalpha(ch)) { + TRY(json_parse_identifier(f)); + } else if (ch == '"') { + TRY(json_parse_string(f)); + } else { + return ch == END_OF_STRING ? JSON_STRING_INCOMPLETE : JSON_STRING_INVALID; + } + return 0; +} + +/* pair = key ':' value */ +static int json_parse_pair(struct frozen *f) { + int current_path_len; + const char *tok; + json_skip_whitespaces(f); + tok = f->cur; + TRY(json_parse_key(f)); + { + f->cur_name = *tok == '"' ? tok + 1 : tok; + f->cur_name_len = *tok == '"' ? f->cur - tok - 2 : f->cur - tok; + current_path_len = json_append_to_path(f, f->cur_name, f->cur_name_len); + } + TRY(json_test_and_skip(f, ':')); + TRY(json_parse_value(f)); + json_truncate_path(f, current_path_len); + return 0; +} + +/* object = '{' pair { ',' pair } '}' */ +static int json_parse_object(struct frozen *f) { + CALL_BACK(f, JSON_TYPE_OBJECT_START, NULL, 0); + TRY(json_test_and_skip(f, '{')); + { + SET_STATE(f, f->cur - 1, ".", 1); + while (json_cur(f) != '}') { + TRY(json_parse_pair(f)); + if (json_cur(f) == ',') f->cur++; + } + TRY(json_test_and_skip(f, '}')); + json_truncate_path(f, fstate.path_len); + CALL_BACK(f, JSON_TYPE_OBJECT_END, fstate.ptr, f->cur - fstate.ptr); + } + return 0; +} + +static int json_doit(struct frozen *f) { + if (f->cur == 0 || f->end < f->cur) return JSON_STRING_INVALID; + if (f->end == f->cur) return JSON_STRING_INCOMPLETE; + return json_parse_value(f); +} + +int json_escape(struct json_out *out, const char *p, size_t len) WEAK; +int json_escape(struct json_out *out, const char *p, size_t len) { + size_t i, cl, n = 0; + const char *hex_digits = "0123456789abcdef"; + const char *specials = "btnvfr"; + + for (i = 0; i < len; i++) { + unsigned char ch = ((unsigned char *) p)[i]; + if (ch == '"' || ch == '\\') { + n += out->printer(out, "\\", 1); + n += out->printer(out, p + i, 1); + } else if (ch >= '\b' && ch <= '\r') { + n += out->printer(out, "\\", 1); + n += out->printer(out, &specials[ch - '\b'], 1); + } else if (c_isprint(ch)) { + n += out->printer(out, p + i, 1); + } else if ((cl = json_get_utf8_char_len(ch)) == 1) { + n += out->printer(out, "\\u00", 4); + n += out->printer(out, &hex_digits[(ch >> 4) % 0xf], 1); + n += out->printer(out, &hex_digits[ch % 0xf], 1); + } else { + n += out->printer(out, p + i, cl); + i += cl - 1; + } + } + + return n; +} + +int json_printer_buf(struct json_out *out, const char *buf, size_t len) WEAK; +int json_printer_buf(struct json_out *out, const char *buf, size_t len) { + size_t avail = out->u.buf.size - out->u.buf.len; + size_t n = len < avail ? len : avail; + memcpy(out->u.buf.buf + out->u.buf.len, buf, n); + out->u.buf.len += n; + if (out->u.buf.size > 0) { + size_t idx = out->u.buf.len; + if (idx >= out->u.buf.size) idx = out->u.buf.size - 1; + out->u.buf.buf[idx] = '\0'; + } + return len; +} + +int json_printer_file(struct json_out *out, const char *buf, size_t len) WEAK; +int json_printer_file(struct json_out *out, const char *buf, size_t len) { + return fwrite(buf, 1, len, out->u.fp); +} + +#if JSON_ENABLE_BASE64 +static int b64idx(int c) { + if (c < 26) { + return c + 'A'; + } else if (c < 52) { + return c - 26 + 'a'; + } else if (c < 62) { + return c - 52 + '0'; + } else { + return c == 62 ? '+' : '/'; + } +} + +static int b64rev(int c) { + if (c >= 'A' && c <= 'Z') { + return c - 'A'; + } else if (c >= 'a' && c <= 'z') { + return c + 26 - 'a'; + } else if (c >= '0' && c <= '9') { + return c + 52 - '0'; + } else if (c == '+') { + return 62; + } else if (c == '/') { + return 63; + } else { + return 64; + } +} + +static int b64enc(struct json_out *out, const unsigned char *p, int n) { + char buf[4]; + int i, len = 0; + for (i = 0; i < n; i += 3) { + int a = p[i], b = i + 1 < n ? p[i + 1] : 0, c = i + 2 < n ? p[i + 2] : 0; + buf[0] = b64idx(a >> 2); + buf[1] = b64idx((a & 3) << 4 | (b >> 4)); + buf[2] = b64idx((b & 15) << 2 | (c >> 6)); + buf[3] = b64idx(c & 63); + if (i + 1 >= n) buf[2] = '='; + if (i + 2 >= n) buf[3] = '='; + len += out->printer(out, buf, sizeof(buf)); + } + return len; +} + +static int b64dec(const char *src, int n, char *dst) { + const char *end = src + n; + int len = 0; + while (src + 3 < end) { + int a = b64rev(src[0]), b = b64rev(src[1]), c = b64rev(src[2]), + d = b64rev(src[3]); + dst[len++] = (a << 2) | (b >> 4); + if (src[2] != '=') { + dst[len++] = (b << 4) | (c >> 2); + if (src[3] != '=') { + dst[len++] = (c << 6) | d; + } + } + src += 4; + } + return len; +} +#endif /* JSON_ENABLE_BASE64 */ + +static unsigned char hexdec(const char *s) { +#define HEXTOI(x) (x >= '0' && x <= '9' ? x - '0' : x - 'W') + int a = c_tolower(*(const unsigned char *) s); + int b = c_tolower(*(const unsigned char *) (s + 1)); + return (HEXTOI(a) << 4) | HEXTOI(b); +} + +int json_vprintf(struct json_out *out, const char *fmt, va_list xap) WEAK; +int json_vprintf(struct json_out *out, const char *fmt, va_list xap) { + int len = 0; + const char *quote = "\"", *null = "null"; + va_list ap; + va_copy(ap, xap); + + while (*fmt != '\0') { + if (strchr(":, \r\n\t[]{}\"", *fmt) != NULL) { + len += out->printer(out, fmt, 1); + fmt++; + } else if (fmt[0] == '%') { + char buf[21]; + size_t skip = 2; + + if (fmt[1] == 'l' && fmt[2] == 'l' && (fmt[3] == 'd' || fmt[3] == 'u')) { + int64_t val = va_arg(ap, int64_t); + const char *fmt2 = fmt[3] == 'u' ? "%" UINT64_FMT : "%" INT64_FMT; + snprintf(buf, sizeof(buf), fmt2, val); + len += out->printer(out, buf, strlen(buf)); + skip += 2; + } else if (fmt[1] == 'z' && fmt[2] == 'u') { + size_t val = va_arg(ap, size_t); + snprintf(buf, sizeof(buf), "%lu", (unsigned long) val); + len += out->printer(out, buf, strlen(buf)); + skip += 1; + } else if (fmt[1] == 'M') { + json_printf_callback_t f = va_arg(ap, json_printf_callback_t); + len += f(out, &ap); + } else if (fmt[1] == 'B') { + int val = va_arg(ap, int); + const char *str = val ? "true" : "false"; + len += out->printer(out, str, strlen(str)); + } else if (fmt[1] == 'H') { +#if JSON_ENABLE_HEX + const char *hex = "0123456789abcdef"; + int i, n = va_arg(ap, int); + const unsigned char *p = va_arg(ap, const unsigned char *); + len += out->printer(out, quote, 1); + for (i = 0; i < n; i++) { + len += out->printer(out, &hex[(p[i] >> 4) & 0xf], 1); + len += out->printer(out, &hex[p[i] & 0xf], 1); + } + len += out->printer(out, quote, 1); +#endif /* JSON_ENABLE_HEX */ + } else if (fmt[1] == 'V') { +#if JSON_ENABLE_BASE64 + const unsigned char *p = va_arg(ap, const unsigned char *); + int n = va_arg(ap, int); + len += out->printer(out, quote, 1); + len += b64enc(out, p, n); + len += out->printer(out, quote, 1); +#endif /* JSON_ENABLE_BASE64 */ + } else if (fmt[1] == 'Q' || + (fmt[1] == '.' && fmt[2] == '*' && fmt[3] == 'Q')) { + size_t l = 0; + const char *p; + + if (fmt[1] == '.') { + l = (size_t) va_arg(ap, int); + skip += 2; + } + p = va_arg(ap, char *); + + if (p == NULL) { + len += out->printer(out, null, 4); + } else { + if (fmt[1] == 'Q') { + l = strlen(p); + } + len += out->printer(out, quote, 1); + len += json_escape(out, p, l); + len += out->printer(out, quote, 1); + } + } else { + /* + * we delegate printing to the system printf. + * The goal here is to delegate all modifiers parsing to the system + * printf, as you can see below we still have to parse the format + * types. + * + * Currently, %s with strings longer than 20 chars will require + * double-buffering (an auxiliary buffer will be allocated from heap). + * TODO(dfrank): reimplement %s and %.*s in order to avoid that. + */ + + const char *end_of_format_specifier = "sdfFeEgGlhuIcx.*-0123456789"; + int n = strspn(fmt + 1, end_of_format_specifier); + char *pbuf = buf; + int need_len, size = sizeof(buf); + char fmt2[20]; + va_list ap_copy; + strncpy(fmt2, fmt, + n + 1 > (int) sizeof(fmt2) ? sizeof(fmt2) : (size_t) n + 1); + fmt2[n + 1] = '\0'; + + va_copy(ap_copy, ap); + need_len = vsnprintf(pbuf, size, fmt2, ap_copy); + va_end(ap_copy); + + if (need_len < 0) { + /* + * Windows & eCos vsnprintf implementation return -1 on overflow + * instead of needed size. + */ + pbuf = NULL; + while (need_len < 0) { + free(pbuf); + size *= 2; + if ((pbuf = (char *) malloc(size)) == NULL) break; + va_copy(ap_copy, ap); + need_len = vsnprintf(pbuf, size, fmt2, ap_copy); + va_end(ap_copy); + } + } else if (need_len >= (int) sizeof(buf)) { + /* + * resulting string doesn't fit into a stack-allocated buffer `buf`, + * so we need to allocate a new buffer from heap and use it + */ + if ((pbuf = (char *) malloc(need_len + 1)) != NULL) { + va_copy(ap_copy, ap); + vsnprintf(pbuf, need_len + 1, fmt2, ap_copy); + va_end(ap_copy); + } + } + if (pbuf == NULL) { + buf[0] = '\0'; + pbuf = buf; + } + + /* + * however we need to parse the type ourselves in order to advance + * the va_list by the correct amount; there is no portable way to + * inherit the advancement made by vprintf. + * 32-bit (linux or windows) passes va_list by value. + */ + if ((n + 1 == strlen("%" PRId64) && strcmp(fmt2, "%" PRId64) == 0) || + (n + 1 == strlen("%" PRIu64) && strcmp(fmt2, "%" PRIu64) == 0)) { + (void) va_arg(ap, int64_t); + } else if (strcmp(fmt2, "%.*s") == 0) { + (void) va_arg(ap, int); + (void) va_arg(ap, char *); + } else { + switch (fmt2[n]) { + case 'u': + case 'd': + (void) va_arg(ap, int); + break; + case 'g': + case 'f': + (void) va_arg(ap, double); + break; + case 'p': + (void) va_arg(ap, void *); + break; + default: + /* many types are promoted to int */ + (void) va_arg(ap, int); + } + } + + len += out->printer(out, pbuf, strlen(pbuf)); + skip = n + 1; + + /* If buffer was allocated from heap, free it */ + if (pbuf != buf) { + free(pbuf); + pbuf = NULL; + } + } + fmt += skip; + } else if (*fmt == '_' || json_isalpha(*fmt)) { + len += out->printer(out, quote, 1); + while (*fmt == '_' || json_isalpha(*fmt) || json_isdigit(*fmt)) { + len += out->printer(out, fmt, 1); + fmt++; + } + len += out->printer(out, quote, 1); + } else { + len += out->printer(out, fmt, 1); + fmt++; + } + } + va_end(ap); + + return len; +} + +int json_printf(struct json_out *out, const char *fmt, ...) WEAK; +int json_printf(struct json_out *out, const char *fmt, ...) { + int n; + va_list ap; + va_start(ap, fmt); + n = json_vprintf(out, fmt, ap); + va_end(ap); + return n; +} + +int json_printf_array(struct json_out *out, va_list *ap) WEAK; +int json_printf_array(struct json_out *out, va_list *ap) { + int len = 0; + char *arr = va_arg(*ap, char *); + size_t i, arr_size = va_arg(*ap, size_t); + size_t elem_size = va_arg(*ap, size_t); + const char *fmt = va_arg(*ap, char *); + len += json_printf(out, "[", 1); + for (i = 0; arr != NULL && i < arr_size / elem_size; i++) { + union { + int64_t i; + double d; + } val; + memcpy(&val, arr + i * elem_size, + elem_size > sizeof(val) ? sizeof(val) : elem_size); + if (i > 0) len += json_printf(out, ", "); + if (strpbrk(fmt, "efg") != NULL) { + len += json_printf(out, fmt, val.d); + } else { + len += json_printf(out, fmt, val.i); + } + } + len += json_printf(out, "]", 1); + return len; +} + +#ifdef _WIN32 +int cs_win_vsnprintf(char *str, size_t size, const char *format, + va_list ap) WEAK; +int cs_win_vsnprintf(char *str, size_t size, const char *format, va_list ap) { + int res = _vsnprintf(str, size, format, ap); + va_end(ap); + if (res >= size) { + str[size - 1] = '\0'; + } + return res; +} + +int cs_win_snprintf(char *str, size_t size, const char *format, ...) WEAK; +int cs_win_snprintf(char *str, size_t size, const char *format, ...) { + int res; + va_list ap; + va_start(ap, format); + res = vsnprintf(str, size, format, ap); + va_end(ap); + return res; +} +#endif /* _WIN32 */ + +int json_walk(const char *json_string, int json_string_length, + json_walk_callback_t callback, void *callback_data) WEAK; +int json_walk(const char *json_string, int json_string_length, + json_walk_callback_t callback, void *callback_data) { + struct frozen frozen; + + memset(&frozen, 0, sizeof(frozen)); + frozen.end = json_string + json_string_length; + frozen.cur = json_string; + frozen.callback_data = callback_data; + frozen.callback = callback; + + TRY(json_doit(&frozen)); + + return frozen.cur - json_string; +} + +struct scan_array_info { + int found; + char path[JSON_MAX_PATH_LEN]; + struct json_token *token; +}; + +static void json_scanf_array_elem_cb(void *callback_data, const char *name, + size_t name_len, const char *path, + const struct json_token *token) { + struct scan_array_info *info = (struct scan_array_info *) callback_data; + + (void) name; + (void) name_len; + + if (strcmp(path, info->path) == 0) { + *info->token = *token; + info->found = 1; + } +} + +int json_scanf_array_elem(const char *s, int len, const char *path, int idx, + struct json_token *token) WEAK; +int json_scanf_array_elem(const char *s, int len, const char *path, int idx, + struct json_token *token) { + struct scan_array_info info; + info.token = token; + info.found = 0; + memset(token, 0, sizeof(*token)); + snprintf(info.path, sizeof(info.path), "%s[%d]", path, idx); + json_walk(s, len, json_scanf_array_elem_cb, &info); + return info.found ? token->len : -1; +} + +struct json_scanf_info { + int num_conversions; + char *path; + const char *fmt; + void *target; + void *user_data; + int type; +}; + +int json_unescape(const char *src, int slen, char *dst, int dlen) WEAK; +int json_unescape(const char *src, int slen, char *dst, int dlen) { + char *send = (char *) src + slen, *dend = dst + dlen, *orig_dst = dst, *p; + const char *esc1 = "\"\\/bfnrt", *esc2 = "\"\\/\b\f\n\r\t"; + + while (src < send) { + if (*src == '\\') { + if (++src >= send) return JSON_STRING_INCOMPLETE; + if (*src == 'u') { + if (send - src < 5) return JSON_STRING_INCOMPLETE; + /* Here we go: this is a \u.... escape. Process simple one-byte chars */ + if (src[1] == '0' && src[2] == '0') { + /* This is \u00xx character from the ASCII range */ + if (dst < dend) *dst = hexdec(src + 3); + src += 4; + } else { + /* Complex \uXXXX escapes drag utf8 lib... Do it at some stage */ + return JSON_STRING_INVALID; + } + } else if ((p = (char *) strchr(esc1, *src)) != NULL) { + if (dst < dend) *dst = esc2[p - esc1]; + } else { + return JSON_STRING_INVALID; + } + } else { + if (dst < dend) *dst = *src; + } + dst++; + src++; + } + + return dst - orig_dst; +} + +static void json_scanf_cb(void *callback_data, const char *name, + size_t name_len, const char *path, + const struct json_token *token) { + struct json_scanf_info *info = (struct json_scanf_info *) callback_data; + char buf[32]; /* Must be enough to hold numbers */ + + (void) name; + (void) name_len; + + if (token->ptr == NULL) { + /* + * We're not interested here in the events for which we have no value; + * namely, JSON_TYPE_OBJECT_START and JSON_TYPE_ARRAY_START + */ + return; + } + + if (strcmp(path, info->path) != 0) { + /* It's not the path we're looking for, so, just ignore this callback */ + return; + } + + switch (info->type) { + case 'B': + info->num_conversions++; + switch (sizeof(bool)) { + case sizeof(char): + *(char *) info->target = (token->type == JSON_TYPE_TRUE ? 1 : 0); + break; + case sizeof(int): + *(int *) info->target = (token->type == JSON_TYPE_TRUE ? 1 : 0); + break; + default: + /* should never be here */ + abort(); + } + break; + case 'M': { + union { + void *p; + json_scanner_t f; + } u = {info->target}; + info->num_conversions++; + u.f(token->ptr, token->len, info->user_data); + break; + } + case 'Q': { + char **dst = (char **) info->target; + if (token->type == JSON_TYPE_NULL) { + *dst = NULL; + } else { + int unescaped_len = json_unescape(token->ptr, token->len, NULL, 0); + if (unescaped_len >= 0 && + (*dst = (char *) malloc(unescaped_len + 1)) != NULL) { + info->num_conversions++; + if (json_unescape(token->ptr, token->len, *dst, unescaped_len) == + unescaped_len) { + (*dst)[unescaped_len] = '\0'; + } else { + free(*dst); + *dst = NULL; + } + } + } + break; + } + case 'H': { +#if JSON_ENABLE_HEX + char **dst = (char **) info->user_data; + int i, len = token->len / 2; + *(int *) info->target = len; + if ((*dst = (char *) malloc(len + 1)) != NULL) { + for (i = 0; i < len; i++) { + (*dst)[i] = hexdec(token->ptr + 2 * i); + } + (*dst)[len] = '\0'; + info->num_conversions++; + } +#endif /* JSON_ENABLE_HEX */ + break; + } + case 'V': { +#if JSON_ENABLE_BASE64 + char **dst = (char **) info->target; + int len = token->len * 4 / 3 + 2; + if ((*dst = (char *) malloc(len + 1)) != NULL) { + int n = b64dec(token->ptr, token->len, *dst); + (*dst)[n] = '\0'; + *(int *) info->user_data = n; + info->num_conversions++; + } +#endif /* JSON_ENABLE_BASE64 */ + break; + } + case 'T': + info->num_conversions++; + *(struct json_token *) info->target = *token; + break; + default: + if (token->len >= (int) sizeof(buf)) break; + /* Before converting, copy into tmp buffer in order to 0-terminate it */ + memcpy(buf, token->ptr, token->len); + buf[token->len] = '\0'; + /* NB: Use of base 0 for %d, %ld, %u and %lu is intentional. */ + if (info->fmt[1] == 'd' || (info->fmt[1] == 'l' && info->fmt[2] == 'd') || + info->fmt[1] == 'i') { + char *endptr = NULL; + long r = strtol(buf, &endptr, 0 /* base */); + if (*endptr == '\0') { + if (info->fmt[1] == 'l') { + *((long *) info->target) = r; + } else { + *((int *) info->target) = (int) r; + } + info->num_conversions++; + } + } else if (info->fmt[1] == 'u' || + (info->fmt[1] == 'l' && info->fmt[2] == 'u')) { + char *endptr = NULL; + unsigned long r = strtoul(buf, &endptr, 0 /* base */); + if (*endptr == '\0') { + if (info->fmt[1] == 'l') { + *((unsigned long *) info->target) = r; + } else { + *((unsigned int *) info->target) = (unsigned int) r; + } + info->num_conversions++; + } + } else { +#if !JSON_MINIMAL + info->num_conversions += sscanf(buf, info->fmt, info->target); +#endif + } + break; + } +} + +int json_vscanf(const char *s, int len, const char *fmt, va_list ap) WEAK; +int json_vscanf(const char *s, int len, const char *fmt, va_list ap) { + char path[JSON_MAX_PATH_LEN] = "", fmtbuf[20]; + int i = 0; + char *p = NULL; + struct json_scanf_info info = {0, path, fmtbuf, NULL, NULL, 0}; + + while (fmt[i] != '\0') { + if (fmt[i] == '{') { + strcat(path, "."); + i++; + } else if (fmt[i] == '}') { + if ((p = strrchr(path, '.')) != NULL) *p = '\0'; + i++; + } else if (fmt[i] == '%') { + info.target = va_arg(ap, void *); + info.type = fmt[i + 1]; + switch (fmt[i + 1]) { + case 'M': + case 'V': + case 'H': + info.user_data = va_arg(ap, void *); + /* FALLTHROUGH */ + case 'B': + case 'Q': + case 'T': + i += 2; + break; + default: { + const char *delims = ", \t\r\n]}"; + int conv_len = strcspn(fmt + i + 1, delims) + 1; + memcpy(fmtbuf, fmt + i, conv_len); + fmtbuf[conv_len] = '\0'; + i += conv_len; + i += strspn(fmt + i, delims); + break; + } + } + json_walk(s, len, json_scanf_cb, &info); + } else if (json_isalpha(fmt[i]) || json_get_utf8_char_len(fmt[i]) > 1) { + char *pe; + const char *delims = ": \r\n\t"; + int key_len = strcspn(&fmt[i], delims); + if ((p = strrchr(path, '.')) != NULL) p[1] = '\0'; + pe = path + strlen(path); + memcpy(pe, fmt + i, key_len); + pe[key_len] = '\0'; + i += key_len + strspn(fmt + i + key_len, delims); + } else { + i++; + } + } + return info.num_conversions; +} + +int json_scanf(const char *str, int len, const char *fmt, ...) WEAK; +int json_scanf(const char *str, int len, const char *fmt, ...) { + int result; + va_list ap; + va_start(ap, fmt); + result = json_vscanf(str, len, fmt, ap); + va_end(ap); + return result; +} + +int json_vfprintf(const char *file_name, const char *fmt, va_list ap) WEAK; +int json_vfprintf(const char *file_name, const char *fmt, va_list ap) { + int res = -1; + FILE *fp = fopen(file_name, "wb"); + if (fp != NULL) { + struct json_out out = JSON_OUT_FILE(fp); + res = json_vprintf(&out, fmt, ap); + fputc('\n', fp); + fclose(fp); + } + return res; +} + +int json_fprintf(const char *file_name, const char *fmt, ...) WEAK; +int json_fprintf(const char *file_name, const char *fmt, ...) { + int result; + va_list ap; + va_start(ap, fmt); + result = json_vfprintf(file_name, fmt, ap); + va_end(ap); + return result; +} + +char *json_fread(const char *path) WEAK; +char *json_fread(const char *path) { + FILE *fp; + char *data = NULL; + if ((fp = fopen(path, "rb")) == NULL) { + } else if (fseek(fp, 0, SEEK_END) != 0) { + fclose(fp); + } else { + long size = ftell(fp); + if (size > 0 && (data = (char *) malloc(size + 1)) != NULL) { + fseek(fp, 0, SEEK_SET); /* Some platforms might not have rewind(), Oo */ + if (fread(data, 1, size, fp) != (size_t) size) { + free(data); + data = NULL; + } else { + data[size] = '\0'; + } + } + fclose(fp); + } + return data; +} + +struct json_setf_data { + const char *json_path; + const char *base; /* Pointer to the source JSON string */ + int matched; /* Matched part of json_path */ + int pos; /* Offset of the mutated value begin */ + int end; /* Offset of the mutated value end */ + int prev; /* Offset of the previous token end */ +}; + +static int get_matched_prefix_len(const char *s1, const char *s2) { + int i = 0; + while (s1[i] && s2[i] && s1[i] == s2[i]) i++; + return i; +} + +static void json_vsetf_cb(void *userdata, const char *name, size_t name_len, + const char *path, const struct json_token *t) { + struct json_setf_data *data = (struct json_setf_data *) userdata; + int off, len = get_matched_prefix_len(path, data->json_path); + if (t->ptr == NULL) return; + off = t->ptr - data->base; + if (len > data->matched) data->matched = len; + + /* + * If there is no exact path match, set the mutation position to tbe end + * of the object or array + */ + if (len < data->matched && data->pos == 0 && + (t->type == JSON_TYPE_OBJECT_END || t->type == JSON_TYPE_ARRAY_END)) { + data->pos = data->end = data->prev; + } + + /* Exact path match. Set mutation position to the value of this token */ + if (strcmp(path, data->json_path) == 0 && t->type != JSON_TYPE_OBJECT_START && + t->type != JSON_TYPE_ARRAY_START) { + data->pos = off; + data->end = off + t->len; + } + + /* + * For deletion, we need to know where the previous value ends, because + * we don't know where matched value key starts. + * When the mutation position is not yet set, remember each value end. + * When the mutation position is already set, but it is at the beginning + * of the object/array, we catch the end of the object/array and see + * whether the object/array start is closer then previously stored prev. + */ + if (data->pos == 0) { + data->prev = off + t->len; /* pos is not yet set */ + } else if ((t->ptr[0] == '[' || t->ptr[0] == '{') && off + 1 < data->pos && + off + 1 > data->prev) { + data->prev = off + 1; + } + (void) name; + (void) name_len; +} + +int json_vsetf(const char *s, int len, struct json_out *out, + const char *json_path, const char *json_fmt, va_list ap) WEAK; +int json_vsetf(const char *s, int len, struct json_out *out, + const char *json_path, const char *json_fmt, va_list ap) { + struct json_setf_data data; + memset(&data, 0, sizeof(data)); + data.json_path = json_path; + data.base = s; + data.end = len; + json_walk(s, len, json_vsetf_cb, &data); + if (json_fmt == NULL) { + /* Deletion codepath */ + json_printf(out, "%.*s", data.prev, s); + /* Trim comma after the value that begins at object/array start */ + if (s[data.prev - 1] == '{' || s[data.prev - 1] == '[') { + int i = data.end; + while (i < len && json_isspace(s[i])) i++; + if (s[i] == ',') data.end = i + 1; /* Point after comma */ + } + json_printf(out, "%.*s", len - data.end, s + data.end); + } else { + /* Modification codepath */ + int n, off = data.matched, depth = 0; + + /* Print the unchanged beginning */ + json_printf(out, "%.*s", data.pos, s); + + /* Add missing keys */ + while ((n = strcspn(&json_path[off], ".[")) > 0) { + if (s[data.prev - 1] != '{' && s[data.prev - 1] != '[' && depth == 0) { + json_printf(out, ","); + } + if (off > 0 && json_path[off - 1] != '.') break; + json_printf(out, "%.*Q:", n, json_path + off); + off += n; + if (json_path[off] != '\0') { + json_printf(out, "%c", json_path[off] == '.' ? '{' : '['); + depth++; + off++; + } + } + /* Print the new value */ + json_vprintf(out, json_fmt, ap); + + /* Close brackets/braces of the added missing keys */ + for (; off > data.matched; off--) { + int ch = json_path[off]; + const char *p = ch == '.' ? "}" : ch == '[' ? "]" : ""; + json_printf(out, "%s", p); + } + + /* Print the rest of the unchanged string */ + json_printf(out, "%.*s", len - data.end, s + data.end); + } + return data.end > data.pos ? 1 : 0; +} + +int json_setf(const char *s, int len, struct json_out *out, + const char *json_path, const char *json_fmt, ...) WEAK; +int json_setf(const char *s, int len, struct json_out *out, + const char *json_path, const char *json_fmt, ...) { + int result; + va_list ap; + va_start(ap, json_fmt); + result = json_vsetf(s, len, out, json_path, json_fmt, ap); + va_end(ap); + return result; +} + +struct prettify_data { + struct json_out *out; + int level; + int last_token; +}; + +static void indent(struct json_out *out, int level) { + while (level-- > 0) out->printer(out, " ", 2); +} + +static void print_key(struct prettify_data *pd, const char *path, + const char *name, int name_len) { + if (pd->last_token != JSON_TYPE_INVALID && + pd->last_token != JSON_TYPE_ARRAY_START && + pd->last_token != JSON_TYPE_OBJECT_START) { + pd->out->printer(pd->out, ",", 1); + } + if (path[0] != '\0') pd->out->printer(pd->out, "\n", 1); + indent(pd->out, pd->level); + if (path[0] != '\0' && path[strlen(path) - 1] != ']') { + pd->out->printer(pd->out, "\"", 1); + pd->out->printer(pd->out, name, (int) name_len); + pd->out->printer(pd->out, "\"", 1); + pd->out->printer(pd->out, ": ", 2); + } +} + +static void prettify_cb(void *userdata, const char *name, size_t name_len, + const char *path, const struct json_token *t) { + struct prettify_data *pd = (struct prettify_data *) userdata; + switch (t->type) { + case JSON_TYPE_OBJECT_START: + case JSON_TYPE_ARRAY_START: + print_key(pd, path, name, name_len); + pd->out->printer(pd->out, t->type == JSON_TYPE_ARRAY_START ? "[" : "{", + 1); + pd->level++; + break; + case JSON_TYPE_OBJECT_END: + case JSON_TYPE_ARRAY_END: + pd->level--; + if (pd->last_token != JSON_TYPE_INVALID && + pd->last_token != JSON_TYPE_ARRAY_START && + pd->last_token != JSON_TYPE_OBJECT_START) { + pd->out->printer(pd->out, "\n", 1); + indent(pd->out, pd->level); + } + pd->out->printer(pd->out, t->type == JSON_TYPE_ARRAY_END ? "]" : "}", 1); + break; + case JSON_TYPE_NUMBER: + case JSON_TYPE_NULL: + case JSON_TYPE_TRUE: + case JSON_TYPE_FALSE: + case JSON_TYPE_STRING: + print_key(pd, path, name, name_len); + if (t->type == JSON_TYPE_STRING) pd->out->printer(pd->out, "\"", 1); + pd->out->printer(pd->out, t->ptr, t->len); + if (t->type == JSON_TYPE_STRING) pd->out->printer(pd->out, "\"", 1); + break; + default: + break; + } + pd->last_token = t->type; +} + +int json_prettify(const char *s, int len, struct json_out *out) WEAK; +int json_prettify(const char *s, int len, struct json_out *out) { + struct prettify_data pd = {out, 0, JSON_TYPE_INVALID}; + return json_walk(s, len, prettify_cb, &pd); +} + +int json_prettify_file(const char *file_name) WEAK; +int json_prettify_file(const char *file_name) { + int res = -1; + char *s = json_fread(file_name); + FILE *fp; + if (s != NULL && (fp = fopen(file_name, "wb")) != NULL) { + struct json_out out = JSON_OUT_FILE(fp); + res = json_prettify(s, strlen(s), &out); + if (res < 0) { + /* On error, restore the old content */ + fclose(fp); + fp = fopen(file_name, "wb"); + fseek(fp, 0, SEEK_SET); + fwrite(s, 1, strlen(s), fp); + } else { + fputc('\n', fp); + } + fclose(fp); + } + free(s); + return res; +} + +struct next_data { + void *handle; // Passed handle. Changed if a next entry is found + const char *path; // Path to the iterated object/array + int path_len; // Path length - optimisation + int found; // Non-0 if found the next entry + struct json_token *key; // Object's key + struct json_token *val; // Object's value + int *idx; // Array index +}; + +static void next_set_key(struct next_data *d, const char *name, int name_len, + int is_array) { + if (is_array) { + /* Array. Set index and reset key */ + if (d->key != NULL) { + d->key->len = 0; + d->key->ptr = NULL; + } + if (d->idx != NULL) *d->idx = atoi(name); + } else { + /* Object. Set key and make index -1 */ + if (d->key != NULL) { + d->key->ptr = name; + d->key->len = name_len; + } + if (d->idx != NULL) *d->idx = -1; + } +} + +static void json_next_cb(void *userdata, const char *name, size_t name_len, + const char *path, const struct json_token *t) { + struct next_data *d = (struct next_data *) userdata; + const char *p = path + d->path_len; + if (d->found) return; + if (d->path_len >= (int) strlen(path)) return; + if (strncmp(d->path, path, d->path_len) != 0) return; + if (strchr(p + 1, '.') != NULL) return; /* More nested objects - skip */ + if (strchr(p + 1, '[') != NULL) return; /* Ditto for arrays */ + // {OBJECT,ARRAY}_END types do not pass name, _START does. Save key. + if (t->type == JSON_TYPE_OBJECT_START || t->type == JSON_TYPE_ARRAY_START) { + next_set_key(d, name, name_len, p[0] == '['); + } else if (d->handle == NULL || d->handle < (void *) t->ptr) { + if (t->type != JSON_TYPE_OBJECT_END && t->type != JSON_TYPE_ARRAY_END) { + next_set_key(d, name, name_len, p[0] == '['); + } + if (d->val != NULL) *d->val = *t; + d->handle = (void *) t->ptr; + d->found = 1; + } +} + +static void *json_next(const char *s, int len, void *handle, const char *path, + struct json_token *key, struct json_token *val, int *i) { + struct json_token tmpval, *v = val == NULL ? &tmpval : val; + struct json_token tmpkey, *k = key == NULL ? &tmpkey : key; + int tmpidx, *pidx = i == NULL ? &tmpidx : i; + struct next_data data = {handle, path, (int) strlen(path), 0, k, v, pidx}; + json_walk(s, len, json_next_cb, &data); + return data.found ? data.handle : NULL; +} + +void *json_next_key(const char *s, int len, void *handle, const char *path, + struct json_token *key, struct json_token *val) WEAK; +void *json_next_key(const char *s, int len, void *handle, const char *path, + struct json_token *key, struct json_token *val) { + return json_next(s, len, handle, path, key, val, NULL); +} + +void *json_next_elem(const char *s, int len, void *handle, const char *path, + int *idx, struct json_token *val) WEAK; +void *json_next_elem(const char *s, int len, void *handle, const char *path, + int *idx, struct json_token *val) { + return json_next(s, len, handle, path, NULL, val, idx); +} + +static int json_sprinter(struct json_out *out, const char *str, size_t len) { + size_t old_len = out->u.buf.buf == NULL ? 0 : strlen(out->u.buf.buf); + size_t new_len = len + old_len; + char *p = (char *) realloc(out->u.buf.buf, new_len + 1); + if (p != NULL) { + memcpy(p + old_len, str, len); + p[new_len] = '\0'; + out->u.buf.buf = p; + } + return len; +} + +char *json_vasprintf(const char *fmt, va_list ap) WEAK; +char *json_vasprintf(const char *fmt, va_list ap) { + struct json_out out; + memset(&out, 0, sizeof(out)); + out.printer = json_sprinter; + json_vprintf(&out, fmt, ap); + return out.u.buf.buf; +} + +char *json_asprintf(const char *fmt, ...) WEAK; +char *json_asprintf(const char *fmt, ...) { + char *result = NULL; + va_list ap; + va_start(ap, fmt); + result = json_vasprintf(fmt, ap); + va_end(ap); + return result; +} diff --git a/armsrc/frozen.h b/armsrc/frozen.h new file mode 100644 index 000000000..cfe651e12 --- /dev/null +++ b/armsrc/frozen.h @@ -0,0 +1,329 @@ +/* + * Copyright (c) 2004-2013 Sergey Lyubka + * Copyright (c) 2018 Cesanta Software Limited + * All rights reserved + * + * Licensed under the Apache License, Version 2.0 (the ""License""); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an ""AS IS"" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CS_FROZEN_FROZEN_H_ +#define CS_FROZEN_FROZEN_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include +#include +#include + +#if defined(_WIN32) && _MSC_VER < 1700 +typedef int bool; +enum { false = 0, true = 1 }; +#else +#include +#endif + +/* JSON token type */ +enum json_token_type { + JSON_TYPE_INVALID = 0, /* memsetting to 0 should create INVALID value */ + JSON_TYPE_STRING, + JSON_TYPE_NUMBER, + JSON_TYPE_TRUE, + JSON_TYPE_FALSE, + JSON_TYPE_NULL, + JSON_TYPE_OBJECT_START, + JSON_TYPE_OBJECT_END, + JSON_TYPE_ARRAY_START, + JSON_TYPE_ARRAY_END, + + JSON_TYPES_CNT +}; + +/* + * Structure containing token type and value. Used in `json_walk()` and + * `json_scanf()` with the format specifier `%T`. + */ +struct json_token { + const char *ptr; /* Points to the beginning of the value */ + int len; /* Value length */ + enum json_token_type type; /* Type of the token, possible values are above */ +}; + +#define JSON_INVALID_TOKEN \ + { 0, 0, JSON_TYPE_INVALID } + +/* Error codes */ +#define JSON_STRING_INVALID -1 +#define JSON_STRING_INCOMPLETE -2 + +/* + * Callback-based SAX-like API. + * + * Property name and length is given only if it's available: i.e. if current + * event is an object's property. In other cases, `name` is `NULL`. For + * example, name is never given: + * - For the first value in the JSON string; + * - For events JSON_TYPE_OBJECT_END and JSON_TYPE_ARRAY_END + * + * E.g. for the input `{ "foo": 123, "bar": [ 1, 2, { "baz": true } ] }`, + * the sequence of callback invocations will be as follows: + * + * - type: JSON_TYPE_OBJECT_START, name: NULL, path: "", value: NULL + * - type: JSON_TYPE_NUMBER, name: "foo", path: ".foo", value: "123" + * - type: JSON_TYPE_ARRAY_START, name: "bar", path: ".bar", value: NULL + * - type: JSON_TYPE_NUMBER, name: "0", path: ".bar[0]", value: "1" + * - type: JSON_TYPE_NUMBER, name: "1", path: ".bar[1]", value: "2" + * - type: JSON_TYPE_OBJECT_START, name: "2", path: ".bar[2]", value: NULL + * - type: JSON_TYPE_TRUE, name: "baz", path: ".bar[2].baz", value: "true" + * - type: JSON_TYPE_OBJECT_END, name: NULL, path: ".bar[2]", value: "{ \"baz\": + *true }" + * - type: JSON_TYPE_ARRAY_END, name: NULL, path: ".bar", value: "[ 1, 2, { + *\"baz\": true } ]" + * - type: JSON_TYPE_OBJECT_END, name: NULL, path: "", value: "{ \"foo\": 123, + *\"bar\": [ 1, 2, { \"baz\": true } ] }" + */ +typedef void (*json_walk_callback_t)(void *callback_data, const char *name, + size_t name_len, const char *path, + const struct json_token *token); + +/* + * Parse `json_string`, invoking `callback` in a way similar to SAX parsers; + * see `json_walk_callback_t`. + * Return number of processed bytes, or a negative error code. + */ +int json_walk(const char *json_string, int json_string_length, + json_walk_callback_t callback, void *callback_data); + +/* + * JSON generation API. + * struct json_out abstracts output, allowing alternative printing plugins. + */ +struct json_out { + int (*printer)(struct json_out *, const char *str, size_t len); + union { + struct { + char *buf; + size_t size; + size_t len; + } buf; + void *data; + FILE *fp; + } u; +}; + +extern int json_printer_buf(struct json_out *, const char *, size_t); +extern int json_printer_file(struct json_out *, const char *, size_t); + +#define JSON_OUT_BUF(buf, len) \ + { \ + json_printer_buf, { \ + { buf, len, 0 } \ + } \ + } +#define JSON_OUT_FILE(fp) \ + { \ + json_printer_file, { \ + { (char *) fp, 0, 0 } \ + } \ + } + +typedef int (*json_printf_callback_t)(struct json_out *, va_list *ap); + +/* + * Generate formatted output into a given sting buffer. + * This is a superset of printf() function, with extra format specifiers: + * - `%B` print json boolean, `true` or `false`. Accepts an `int`. + * - `%Q` print quoted escaped string or `null`. Accepts a `const char *`. + * - `%.*Q` same as `%Q`, but with length. Accepts `int`, `const char *` + * - `%V` print quoted base64-encoded string. Accepts a `const char *`, `int`. + * - `%H` print quoted hex-encoded string. Accepts a `int`, `const char *`. + * - `%M` invokes a json_printf_callback_t function. That callback function + * can consume more parameters. + * + * Return number of bytes printed. If the return value is bigger than the + * supplied buffer, that is an indicator of overflow. In the overflow case, + * overflown bytes are not printed. + */ +int json_printf(struct json_out *, const char *fmt, ...); +int json_vprintf(struct json_out *, const char *fmt, va_list ap); + +/* + * Same as json_printf, but prints to a file. + * File is created if does not exist. File is truncated if already exists. + */ +int json_fprintf(const char *file_name, const char *fmt, ...); +int json_vfprintf(const char *file_name, const char *fmt, va_list ap); + +/* + * Print JSON into an allocated 0-terminated string. + * Return allocated string, or NULL on error. + * Example: + * + * ```c + * char *str = json_asprintf("{a:%H}", 3, "abc"); + * printf("%s\n", str); // Prints "616263" + * free(str); + * ``` + */ +char *json_asprintf(const char *fmt, ...); +char *json_vasprintf(const char *fmt, va_list ap); + +/* + * Helper %M callback that prints contiguous C arrays. + * Consumes void *array_ptr, size_t array_size, size_t elem_size, char *fmt + * Return number of bytes printed. + */ +int json_printf_array(struct json_out *, va_list *ap); + +/* + * Scan JSON string `str`, performing scanf-like conversions according to `fmt`. + * This is a `scanf()` - like function, with following differences: + * + * 1. Object keys in the format string may be not quoted, e.g. "{key: %d}" + * 2. Order of keys in an object is irrelevant. + * 3. Several extra format specifiers are supported: + * - %B: consumes `int *` (or `char *`, if `sizeof(bool) == sizeof(char)`), + * expects boolean `true` or `false`. + * - %Q: consumes `char **`, expects quoted, JSON-encoded string. Scanned + * string is malloc-ed, caller must free() the string. + * - %V: consumes `char **`, `int *`. Expects base64-encoded string. + * Result string is base64-decoded, malloced and NUL-terminated. + * The length of result string is stored in `int *` placeholder. + * Caller must free() the result. + * - %H: consumes `int *`, `char **`. + * Expects a hex-encoded string, e.g. "fa014f". + * Result string is hex-decoded, malloced and NUL-terminated. + * The length of the result string is stored in `int *` placeholder. + * Caller must free() the result. + * - %M: consumes custom scanning function pointer and + * `void *user_data` parameter - see json_scanner_t definition. + * - %T: consumes `struct json_token *`, fills it out with matched token. + * + * Return number of elements successfully scanned & converted. + * Negative number means scan error. + */ +int json_scanf(const char *str, int str_len, const char *fmt, ...); +int json_vscanf(const char *str, int str_len, const char *fmt, va_list ap); + +/* json_scanf's %M handler */ +typedef void (*json_scanner_t)(const char *str, int len, void *user_data); + +/* + * Helper function to scan array item with given path and index. + * Fills `token` with the matched JSON token. + * Return -1 if no array element found, otherwise non-negative token length. + */ +int json_scanf_array_elem(const char *s, int len, const char *path, int index, + struct json_token *token); + +/* + * Unescape JSON-encoded string src,slen into dst, dlen. + * src and dst may overlap. + * If destination buffer is too small (or zero-length), result string is not + * written but the length is counted nevertheless (similar to snprintf). + * Return the length of unescaped string in bytes. + */ +int json_unescape(const char *src, int slen, char *dst, int dlen); + +/* + * Escape a string `str`, `str_len` into the printer `out`. + * Return the number of bytes printed. + */ +int json_escape(struct json_out *out, const char *str, size_t str_len); + +/* + * Read the whole file in memory. + * Return malloc-ed file content, or NULL on error. The caller must free(). + */ +char *json_fread(const char *file_name); + +/* + * Update given JSON string `s,len` by changing the value at given `json_path`. + * The result is saved to `out`. If `json_fmt` == NULL, that deletes the key. + * If path is not present, missing keys are added. Array path without an + * index pushes a value to the end of an array. + * Return 1 if the string was changed, 0 otherwise. + * + * Example: s is a JSON string { "a": 1, "b": [ 2 ] } + * json_setf(s, len, out, ".a", "7"); // { "a": 7, "b": [ 2 ] } + * json_setf(s, len, out, ".b", "7"); // { "a": 1, "b": 7 } + * json_setf(s, len, out, ".b[]", "7"); // { "a": 1, "b": [ 2,7 ] } + * json_setf(s, len, out, ".b", NULL); // { "a": 1 } + */ +int json_setf(const char *s, int len, struct json_out *out, + const char *json_path, const char *json_fmt, ...); + +int json_vsetf(const char *s, int len, struct json_out *out, + const char *json_path, const char *json_fmt, va_list ap); + +/* + * Pretty-print JSON string `s,len` into `out`. + * Return number of processed bytes in `s`. + */ +int json_prettify(const char *s, int len, struct json_out *out); + +/* + * Prettify JSON file `file_name`. + * Return number of processed bytes, or negative number of error. + * On error, file content is not modified. + */ +int json_prettify_file(const char *file_name); + +/* + * Iterate over an object at given JSON `path`. + * On each iteration, fill the `key` and `val` tokens. It is OK to pass NULL + * for `key`, or `val`, in which case they won't be populated. + * Return an opaque value suitable for the next iteration, or NULL when done. + * + * Example: + * + * ```c + * void *h = NULL; + * struct json_token key, val; + * while ((h = json_next_key(s, len, h, ".foo", &key, &val)) != NULL) { + * printf("[%.*s] -> [%.*s]\n", key.len, key.ptr, val.len, val.ptr); + * } + * ``` + */ +void *json_next_key(const char *s, int len, void *handle, const char *path, + struct json_token *key, struct json_token *val); + +/* + * Iterate over an array at given JSON `path`. + * Similar to `json_next_key`, but fills array index `idx` instead of `key`. + */ +void *json_next_elem(const char *s, int len, void *handle, const char *path, + int *idx, struct json_token *val); + +#ifndef JSON_MAX_PATH_LEN +#define JSON_MAX_PATH_LEN 256 +#endif + +#ifndef JSON_MINIMAL +#define JSON_MINIMAL 1 +#endif + +#ifndef JSON_ENABLE_BASE64 +#define JSON_ENABLE_BASE64 !JSON_MINIMAL +#endif + +#ifndef JSON_ENABLE_HEX +#define JSON_ENABLE_HEX !JSON_MINIMAL +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* CS_FROZEN_FROZEN_H_ */ diff --git a/armsrc/nprintf.c b/armsrc/nprintf.c new file mode 100644 index 000000000..b6b200549 --- /dev/null +++ b/armsrc/nprintf.c @@ -0,0 +1,914 @@ +/////////////////////////////////////////////////////////////////////////////// +// \author (c) Marco Paland (info@paland.com) +// 2014-2019, PALANDesign Hannover, Germany +// +// \license The MIT License (MIT) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// \brief Tiny printf, sprintf and (v)snprintf implementation, optimized for speed on +// embedded systems with a very limited resources. These routines are thread +// safe and reentrant! +// Use this instead of the bloated standard/newlib printf cause these use +// malloc for printf (and may not be thread safe). +// +/////////////////////////////////////////////////////////////////////////////// + +#include +#include + +#include "nprintf.h" + + +// define this globally (e.g. gcc -DPRINTF_INCLUDE_CONFIG_H ...) to include the +// printf_config.h header file +// default: undefined +#ifdef PRINTF_INCLUDE_CONFIG_H +#include "printf_config.h" +#endif + + +// 'ntoa' conversion buffer size, this must be big enough to hold one converted +// numeric number including padded zeros (dynamically created on stack) +// default: 32 byte +#ifndef PRINTF_NTOA_BUFFER_SIZE +#define PRINTF_NTOA_BUFFER_SIZE 32U +#endif + +// 'ftoa' conversion buffer size, this must be big enough to hold one converted +// float number including padded zeros (dynamically created on stack) +// default: 32 byte +#ifndef PRINTF_FTOA_BUFFER_SIZE +#define PRINTF_FTOA_BUFFER_SIZE 32U +#endif + +// support for the floating point type (%f) +// default: activated +#ifndef PRINTF_DISABLE_SUPPORT_FLOAT +#define PRINTF_SUPPORT_FLOAT +#endif + +// support for exponential floating point notation (%e/%g) +// default: activated +#ifndef PRINTF_DISABLE_SUPPORT_EXPONENTIAL +#define PRINTF_SUPPORT_EXPONENTIAL +#endif + +// define the default floating point precision +// default: 6 digits +#ifndef PRINTF_DEFAULT_FLOAT_PRECISION +#define PRINTF_DEFAULT_FLOAT_PRECISION 6U +#endif + +// define the largest float suitable to print with %f +// default: 1e9 +#ifndef PRINTF_MAX_FLOAT +#define PRINTF_MAX_FLOAT 1e9 +#endif + +// support for the long long types (%llu or %p) +// default: activated +#ifndef PRINTF_DISABLE_SUPPORT_LONG_LONG +#define PRINTF_SUPPORT_LONG_LONG +#endif + +// support for the ptrdiff_t type (%t) +// ptrdiff_t is normally defined in as long or long long type +// default: activated +#ifndef PRINTF_DISABLE_SUPPORT_PTRDIFF_T +#define PRINTF_SUPPORT_PTRDIFF_T +#endif + +/////////////////////////////////////////////////////////////////////////////// + +// internal flag definitions +#define FLAGS_ZEROPAD (1U << 0U) +#define FLAGS_LEFT (1U << 1U) +#define FLAGS_PLUS (1U << 2U) +#define FLAGS_SPACE (1U << 3U) +#define FLAGS_HASH (1U << 4U) +#define FLAGS_UPPERCASE (1U << 5U) +#define FLAGS_CHAR (1U << 6U) +#define FLAGS_SHORT (1U << 7U) +#define FLAGS_LONG (1U << 8U) +#define FLAGS_LONG_LONG (1U << 9U) +#define FLAGS_PRECISION (1U << 10U) +#define FLAGS_ADAPT_EXP (1U << 11U) + + +// import float.h for DBL_MAX +#if defined(PRINTF_SUPPORT_FLOAT) +#include +#endif + + +// output function type +typedef void (*out_fct_type)(char character, void* buffer, size_t idx, size_t maxlen); + + +// wrapper (used as buffer) for output function type +typedef struct { + void (*fct)(char character, void* arg); + void* arg; +} out_fct_wrap_type; + + +// internal buffer output +static inline void _out_buffer(char character, void* buffer, size_t idx, size_t maxlen) +{ + if (idx < maxlen) { + ((char*)buffer)[idx] = character; + } +} + + +// internal null output +static inline void _out_null(char character, void* buffer, size_t idx, size_t maxlen) +{ + (void)character; (void)buffer; (void)idx; (void)maxlen; +} + + +// internal _putchar wrapper +static inline void _out_char(char character, void* buffer, size_t idx, size_t maxlen) +{ + (void)buffer; (void)idx; (void)maxlen; + if (character) { + _putchar(character); + } +} + + +// internal output function wrapper +static inline void _out_fct(char character, void* buffer, size_t idx, size_t maxlen) +{ + (void)idx; (void)maxlen; + if (character) { + // buffer is the output fct pointer + ((out_fct_wrap_type*)buffer)->fct(character, ((out_fct_wrap_type*)buffer)->arg); + } +} + + +// internal secure strlen +// \return The length of the string (excluding the terminating 0) limited by 'maxsize' +static inline unsigned int _strnlen_s(const char* str, size_t maxsize) +{ + const char* s; + for (s = str; *s && maxsize--; ++s); + return (unsigned int)(s - str); +} + + +// internal test if char is a digit (0-9) +// \return true if char is a digit +static inline bool _is_digit(char ch) +{ + return (ch >= '0') && (ch <= '9'); +} + + +// internal ASCII string to unsigned int conversion +static unsigned int _atoi(const char** str) +{ + unsigned int i = 0U; + while (_is_digit(**str)) { + i = i * 10U + (unsigned int)(*((*str)++) - '0'); + } + return i; +} + + +// output the specified string in reverse, taking care of any zero-padding +static size_t _out_rev(out_fct_type out, char* buffer, size_t idx, size_t maxlen, const char* buf, size_t len, unsigned int width, unsigned int flags) +{ + const size_t start_idx = idx; + + // pad spaces up to given width + if (!(flags & FLAGS_LEFT) && !(flags & FLAGS_ZEROPAD)) { + for (size_t i = len; i < width; i++) { + out(' ', buffer, idx++, maxlen); + } + } + + // reverse string + while (len) { + out(buf[--len], buffer, idx++, maxlen); + } + + // append pad spaces up to given width + if (flags & FLAGS_LEFT) { + while (idx - start_idx < width) { + out(' ', buffer, idx++, maxlen); + } + } + + return idx; +} + + +// internal itoa format +static size_t _ntoa_format(out_fct_type out, char* buffer, size_t idx, size_t maxlen, char* buf, size_t len, bool negative, unsigned int base, unsigned int prec, unsigned int width, unsigned int flags) +{ + // pad leading zeros + if (!(flags & FLAGS_LEFT)) { + if (width && (flags & FLAGS_ZEROPAD) && (negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) { + width--; + } + while ((len < prec) && (len < PRINTF_NTOA_BUFFER_SIZE)) { + buf[len++] = '0'; + } + while ((flags & FLAGS_ZEROPAD) && (len < width) && (len < PRINTF_NTOA_BUFFER_SIZE)) { + buf[len++] = '0'; + } + } + + // handle hash + if (flags & FLAGS_HASH) { + if (!(flags & FLAGS_PRECISION) && len && ((len == prec) || (len == width))) { + len--; + if (len && (base == 16U)) { + len--; + } + } + if ((base == 16U) && !(flags & FLAGS_UPPERCASE) && (len < PRINTF_NTOA_BUFFER_SIZE)) { + buf[len++] = 'x'; + } + else if ((base == 16U) && (flags & FLAGS_UPPERCASE) && (len < PRINTF_NTOA_BUFFER_SIZE)) { + buf[len++] = 'X'; + } + else if ((base == 2U) && (len < PRINTF_NTOA_BUFFER_SIZE)) { + buf[len++] = 'b'; + } + if (len < PRINTF_NTOA_BUFFER_SIZE) { + buf[len++] = '0'; + } + } + + if (len < PRINTF_NTOA_BUFFER_SIZE) { + if (negative) { + buf[len++] = '-'; + } + else if (flags & FLAGS_PLUS) { + buf[len++] = '+'; // ignore the space if the '+' exists + } + else if (flags & FLAGS_SPACE) { + buf[len++] = ' '; + } + } + + return _out_rev(out, buffer, idx, maxlen, buf, len, width, flags); +} + + +// internal itoa for 'long' type +static size_t _ntoa_long(out_fct_type out, char* buffer, size_t idx, size_t maxlen, unsigned long value, bool negative, unsigned long base, unsigned int prec, unsigned int width, unsigned int flags) +{ + char buf[PRINTF_NTOA_BUFFER_SIZE]; + size_t len = 0U; + + // no hash for 0 values + if (!value) { + flags &= ~FLAGS_HASH; + } + + // write if precision != 0 and value is != 0 + if (!(flags & FLAGS_PRECISION) || value) { + do { + const char digit = (char)(value % base); + buf[len++] = digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10; + value /= base; + } while (value && (len < PRINTF_NTOA_BUFFER_SIZE)); + } + + return _ntoa_format(out, buffer, idx, maxlen, buf, len, negative, (unsigned int)base, prec, width, flags); +} + + +// internal itoa for 'long long' type +#if defined(PRINTF_SUPPORT_LONG_LONG) +static size_t _ntoa_long_long(out_fct_type out, char* buffer, size_t idx, size_t maxlen, unsigned long long value, bool negative, unsigned long long base, unsigned int prec, unsigned int width, unsigned int flags) +{ + char buf[PRINTF_NTOA_BUFFER_SIZE]; + size_t len = 0U; + + // no hash for 0 values + if (!value) { + flags &= ~FLAGS_HASH; + } + + // write if precision != 0 and value is != 0 + if (!(flags & FLAGS_PRECISION) || value) { + do { + const char digit = (char)(value % base); + buf[len++] = digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10; + value /= base; + } while (value && (len < PRINTF_NTOA_BUFFER_SIZE)); + } + + return _ntoa_format(out, buffer, idx, maxlen, buf, len, negative, (unsigned int)base, prec, width, flags); +} +#endif // PRINTF_SUPPORT_LONG_LONG + + +#if defined(PRINTF_SUPPORT_FLOAT) + +#if defined(PRINTF_SUPPORT_EXPONENTIAL) +// forward declaration so that _ftoa can switch to exp notation for values > PRINTF_MAX_FLOAT +static size_t _etoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags); +#endif + + +// internal ftoa for fixed decimal floating point +static size_t _ftoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags) +{ + char buf[PRINTF_FTOA_BUFFER_SIZE]; + size_t len = 0U; + double diff = 0.0; + + // powers of 10 + static const double pow10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 }; + + // test for special values + if (value != value) + return _out_rev(out, buffer, idx, maxlen, "nan", 3, width, flags); + if (value < -DBL_MAX) + return _out_rev(out, buffer, idx, maxlen, "fni-", 4, width, flags); + if (value > DBL_MAX) + return _out_rev(out, buffer, idx, maxlen, (flags & FLAGS_PLUS) ? "fni+" : "fni", (flags & FLAGS_PLUS) ? 4U : 3U, width, flags); + + // test for very large values + // standard printf behavior is to print EVERY whole number digit -- which could be 100s of characters overflowing your buffers == bad + if ((value > PRINTF_MAX_FLOAT) || (value < -PRINTF_MAX_FLOAT)) { +#if defined(PRINTF_SUPPORT_EXPONENTIAL) + return _etoa(out, buffer, idx, maxlen, value, prec, width, flags); +#else + return 0U; +#endif + } + + // test for negative + bool negative = false; + if (value < 0) { + negative = true; + value = 0 - value; + } + + // set default precision, if not set explicitly + if (!(flags & FLAGS_PRECISION)) { + prec = PRINTF_DEFAULT_FLOAT_PRECISION; + } + // limit precision to 9, cause a prec >= 10 can lead to overflow errors + while ((len < PRINTF_FTOA_BUFFER_SIZE) && (prec > 9U)) { + buf[len++] = '0'; + prec--; + } + + int whole = (int)value; + double tmp = (value - whole) * pow10[prec]; + unsigned long frac = (unsigned long)tmp; + diff = tmp - frac; + + if (diff > 0.5) { + ++frac; + // handle rollover, e.g. case 0.99 with prec 1 is 1.0 + if (frac >= pow10[prec]) { + frac = 0; + ++whole; + } + } + else if (diff < 0.5) { + } + else if ((frac == 0U) || (frac & 1U)) { + // if halfway, round up if odd OR if last digit is 0 + ++frac; + } + + if (prec == 0U) { + diff = value - (double)whole; + if ((!(diff < 0.5) || (diff > 0.5)) && (whole & 1)) { + // exactly 0.5 and ODD, then round up + // 1.5 -> 2, but 2.5 -> 2 + ++whole; + } + } + else { + unsigned int count = prec; + // now do fractional part, as an unsigned number + while (len < PRINTF_FTOA_BUFFER_SIZE) { + --count; + buf[len++] = (char)(48U + (frac % 10U)); + if (!(frac /= 10U)) { + break; + } + } + // add extra 0s + while ((len < PRINTF_FTOA_BUFFER_SIZE) && (count-- > 0U)) { + buf[len++] = '0'; + } + if (len < PRINTF_FTOA_BUFFER_SIZE) { + // add decimal + buf[len++] = '.'; + } + } + + // do whole part, number is reversed + while (len < PRINTF_FTOA_BUFFER_SIZE) { + buf[len++] = (char)(48 + (whole % 10)); + if (!(whole /= 10)) { + break; + } + } + + // pad leading zeros + if (!(flags & FLAGS_LEFT) && (flags & FLAGS_ZEROPAD)) { + if (width && (negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) { + width--; + } + while ((len < width) && (len < PRINTF_FTOA_BUFFER_SIZE)) { + buf[len++] = '0'; + } + } + + if (len < PRINTF_FTOA_BUFFER_SIZE) { + if (negative) { + buf[len++] = '-'; + } + else if (flags & FLAGS_PLUS) { + buf[len++] = '+'; // ignore the space if the '+' exists + } + else if (flags & FLAGS_SPACE) { + buf[len++] = ' '; + } + } + + return _out_rev(out, buffer, idx, maxlen, buf, len, width, flags); +} + + +#if defined(PRINTF_SUPPORT_EXPONENTIAL) +// internal ftoa variant for exponential floating-point type, contributed by Martijn Jasperse +static size_t _etoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags) +{ + // check for NaN and special values + if ((value != value) || (value > DBL_MAX) || (value < -DBL_MAX)) { + return _ftoa(out, buffer, idx, maxlen, value, prec, width, flags); + } + + // determine the sign + const bool negative = value < 0; + if (negative) { + value = -value; + } + + // default precision + if (!(flags & FLAGS_PRECISION)) { + prec = PRINTF_DEFAULT_FLOAT_PRECISION; + } + + // determine the decimal exponent + // based on the algorithm by David Gay (https://www.ampl.com/netlib/fp/dtoa.c) + union { + uint64_t U; + double F; + } conv; + + conv.F = value; + int exp2 = (int)((conv.U >> 52U) & 0x07FFU) - 1023; // effectively log2 + conv.U = (conv.U & ((1ULL << 52U) - 1U)) | (1023ULL << 52U); // drop the exponent so conv.F is now in [1,2) + // now approximate log10 from the log2 integer part and an expansion of ln around 1.5 + int expval = (int)(0.1760912590558 + exp2 * 0.301029995663981 + (conv.F - 1.5) * 0.289529654602168); + // now we want to compute 10^expval but we want to be sure it won't overflow + exp2 = (int)(expval * 3.321928094887362 + 0.5); + const double z = expval * 2.302585092994046 - exp2 * 0.6931471805599453; + const double z2 = z * z; + conv.U = (uint64_t)(exp2 + 1023) << 52U; + // compute exp(z) using continued fractions, see https://en.wikipedia.org/wiki/Exponential_function#Continued_fractions_for_ex + conv.F *= 1 + 2 * z / (2 - z + (z2 / (6 + (z2 / (10 + z2 / 14))))); + // correct for rounding errors + if (value < conv.F) { + expval--; + conv.F /= 10; + } + + // the exponent format is "%+03d" and largest value is "307", so set aside 4-5 characters + unsigned int minwidth = ((expval < 100) && (expval > -100)) ? 4U : 5U; + + // in "%g" mode, "prec" is the number of *significant figures* not decimals + if (flags & FLAGS_ADAPT_EXP) { + // do we want to fall-back to "%f" mode? + if ((value >= 1e-4) && (value < 1e6)) { + if ((int)prec > expval) { + prec = (unsigned)((int)prec - expval - 1); + } + else { + prec = 0; + } + flags |= FLAGS_PRECISION; // make sure _ftoa respects precision + // no characters in exponent + minwidth = 0U; + expval = 0; + } + else { + // we use one sigfig for the whole part + if ((prec > 0) && (flags & FLAGS_PRECISION)) { + --prec; + } + } + } + + // will everything fit? + unsigned int fwidth = width; + if (width > minwidth) { + // we didn't fall-back so subtract the characters required for the exponent + fwidth -= minwidth; + } else { + // not enough characters, so go back to default sizing + fwidth = 0U; + } + if ((flags & FLAGS_LEFT) && minwidth) { + // if we're padding on the right, DON'T pad the floating part + fwidth = 0U; + } + + // rescale the float value + if (expval) { + value /= conv.F; + } + + // output the floating part + const size_t start_idx = idx; + idx = _ftoa(out, buffer, idx, maxlen, negative ? -value : value, prec, fwidth, flags & ~FLAGS_ADAPT_EXP); + + // output the exponent part + if (minwidth) { + // output the exponential symbol + out((flags & FLAGS_UPPERCASE) ? 'E' : 'e', buffer, idx++, maxlen); + // output the exponent value + idx = _ntoa_long(out, buffer, idx, maxlen, (expval < 0) ? -expval : expval, expval < 0, 10, 0, minwidth-1, FLAGS_ZEROPAD | FLAGS_PLUS); + // might need to right-pad spaces + if (flags & FLAGS_LEFT) { + while (idx - start_idx < width) out(' ', buffer, idx++, maxlen); + } + } + return idx; +} +#endif // PRINTF_SUPPORT_EXPONENTIAL +#endif // PRINTF_SUPPORT_FLOAT + + +// internal vsnprintf +static int _vsnprintf(out_fct_type out, char* buffer, const size_t maxlen, const char* format, va_list va) +{ + unsigned int flags, width, precision, n; + size_t idx = 0U; + + if (!buffer) { + // use null output function + out = _out_null; + } + + while (*format) + { + // format specifier? %[flags][width][.precision][length] + if (*format != '%') { + // no + out(*format, buffer, idx++, maxlen); + format++; + continue; + } + else { + // yes, evaluate it + format++; + } + + // evaluate flags + flags = 0U; + do { + switch (*format) { + case '0': flags |= FLAGS_ZEROPAD; format++; n = 1U; break; + case '-': flags |= FLAGS_LEFT; format++; n = 1U; break; + case '+': flags |= FLAGS_PLUS; format++; n = 1U; break; + case ' ': flags |= FLAGS_SPACE; format++; n = 1U; break; + case '#': flags |= FLAGS_HASH; format++; n = 1U; break; + default : n = 0U; break; + } + } while (n); + + // evaluate width field + width = 0U; + if (_is_digit(*format)) { + width = _atoi(&format); + } + else if (*format == '*') { + const int w = va_arg(va, int); + if (w < 0) { + flags |= FLAGS_LEFT; // reverse padding + width = (unsigned int)-w; + } + else { + width = (unsigned int)w; + } + format++; + } + + // evaluate precision field + precision = 0U; + if (*format == '.') { + flags |= FLAGS_PRECISION; + format++; + if (_is_digit(*format)) { + precision = _atoi(&format); + } + else if (*format == '*') { + const int prec = (int)va_arg(va, int); + precision = prec > 0 ? (unsigned int)prec : 0U; + format++; + } + } + + // evaluate length field + switch (*format) { + case 'l' : + flags |= FLAGS_LONG; + format++; + if (*format == 'l') { + flags |= FLAGS_LONG_LONG; + format++; + } + break; + case 'h' : + flags |= FLAGS_SHORT; + format++; + if (*format == 'h') { + flags |= FLAGS_CHAR; + format++; + } + break; +#if defined(PRINTF_SUPPORT_PTRDIFF_T) + case 't' : + flags |= (sizeof(ptrdiff_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); + format++; + break; +#endif + case 'j' : + flags |= (sizeof(intmax_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); + format++; + break; + case 'z' : + flags |= (sizeof(size_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); + format++; + break; + default : + break; + } + + // evaluate specifier + switch (*format) { + case 'd' : + case 'i' : + case 'u' : + case 'x' : + case 'X' : + case 'o' : + case 'b' : { + // set the base + unsigned int base; + if (*format == 'x' || *format == 'X') { + base = 16U; + } + else if (*format == 'o') { + base = 8U; + } + else if (*format == 'b') { + base = 2U; + } + else { + base = 10U; + flags &= ~FLAGS_HASH; // no hash for dec format + } + // uppercase + if (*format == 'X') { + flags |= FLAGS_UPPERCASE; + } + + // no plus or space flag for u, x, X, o, b + if ((*format != 'i') && (*format != 'd')) { + flags &= ~(FLAGS_PLUS | FLAGS_SPACE); + } + + // ignore '0' flag when precision is given + if (flags & FLAGS_PRECISION) { + flags &= ~FLAGS_ZEROPAD; + } + + // convert the integer + if ((*format == 'i') || (*format == 'd')) { + // signed + if (flags & FLAGS_LONG_LONG) { +#if defined(PRINTF_SUPPORT_LONG_LONG) + const long long value = va_arg(va, long long); + idx = _ntoa_long_long(out, buffer, idx, maxlen, (unsigned long long)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags); +#endif + } + else if (flags & FLAGS_LONG) { + const long value = va_arg(va, long); + idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned long)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags); + } + else { + const int value = (flags & FLAGS_CHAR) ? (char)va_arg(va, int) : (flags & FLAGS_SHORT) ? (short int)va_arg(va, int) : va_arg(va, int); + idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned int)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags); + } + } + else { + // unsigned + if (flags & FLAGS_LONG_LONG) { +#if defined(PRINTF_SUPPORT_LONG_LONG) + idx = _ntoa_long_long(out, buffer, idx, maxlen, va_arg(va, unsigned long long), false, base, precision, width, flags); +#endif + } + else if (flags & FLAGS_LONG) { + idx = _ntoa_long(out, buffer, idx, maxlen, va_arg(va, unsigned long), false, base, precision, width, flags); + } + else { + const unsigned int value = (flags & FLAGS_CHAR) ? (unsigned char)va_arg(va, unsigned int) : (flags & FLAGS_SHORT) ? (unsigned short int)va_arg(va, unsigned int) : va_arg(va, unsigned int); + idx = _ntoa_long(out, buffer, idx, maxlen, value, false, base, precision, width, flags); + } + } + format++; + break; + } +#if defined(PRINTF_SUPPORT_FLOAT) + case 'f' : + case 'F' : + if (*format == 'F') flags |= FLAGS_UPPERCASE; + idx = _ftoa(out, buffer, idx, maxlen, va_arg(va, double), precision, width, flags); + format++; + break; +#if defined(PRINTF_SUPPORT_EXPONENTIAL) + case 'e': + case 'E': + case 'g': + case 'G': + if ((*format == 'g')||(*format == 'G')) flags |= FLAGS_ADAPT_EXP; + if ((*format == 'E')||(*format == 'G')) flags |= FLAGS_UPPERCASE; + idx = _etoa(out, buffer, idx, maxlen, va_arg(va, double), precision, width, flags); + format++; + break; +#endif // PRINTF_SUPPORT_EXPONENTIAL +#endif // PRINTF_SUPPORT_FLOAT + case 'c' : { + unsigned int l = 1U; + // pre padding + if (!(flags & FLAGS_LEFT)) { + while (l++ < width) { + out(' ', buffer, idx++, maxlen); + } + } + // char output + out((char)va_arg(va, int), buffer, idx++, maxlen); + // post padding + if (flags & FLAGS_LEFT) { + while (l++ < width) { + out(' ', buffer, idx++, maxlen); + } + } + format++; + break; + } + + case 's' : { + const char* p = va_arg(va, char*); + unsigned int l = _strnlen_s(p, precision ? precision : (size_t)-1); + // pre padding + if (flags & FLAGS_PRECISION) { + l = (l < precision ? l : precision); + } + if (!(flags & FLAGS_LEFT)) { + while (l++ < width) { + out(' ', buffer, idx++, maxlen); + } + } + // string output + while ((*p != 0) && (!(flags & FLAGS_PRECISION) || precision--)) { + out(*(p++), buffer, idx++, maxlen); + } + // post padding + if (flags & FLAGS_LEFT) { + while (l++ < width) { + out(' ', buffer, idx++, maxlen); + } + } + format++; + break; + } + + case 'p' : { + width = sizeof(void*) * 2U; + flags |= FLAGS_ZEROPAD | FLAGS_UPPERCASE; +#if defined(PRINTF_SUPPORT_LONG_LONG) + const bool is_ll = sizeof(uintptr_t) == sizeof(long long); + if (is_ll) { + idx = _ntoa_long_long(out, buffer, idx, maxlen, (uintptr_t)va_arg(va, void*), false, 16U, precision, width, flags); + } + else { +#endif + idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned long)((uintptr_t)va_arg(va, void*)), false, 16U, precision, width, flags); +#if defined(PRINTF_SUPPORT_LONG_LONG) + } +#endif + format++; + break; + } + + case '%' : + out('%', buffer, idx++, maxlen); + format++; + break; + + default : + out(*format, buffer, idx++, maxlen); + format++; + break; + } + } + + // termination + out((char)0, buffer, idx < maxlen ? idx : maxlen - 1U, maxlen); + + // return written chars without terminating \0 + return (int)idx; +} + + +/////////////////////////////////////////////////////////////////////////////// + +int printf_(const char* format, ...) +{ + va_list va; + va_start(va, format); + char buffer[1]; + const int ret = _vsnprintf(_out_char, buffer, (size_t)-1, format, va); + va_end(va); + return ret; +} + + +int sprintf_(char* buffer, const char* format, ...) +{ + va_list va; + va_start(va, format); + const int ret = _vsnprintf(_out_buffer, buffer, (size_t)-1, format, va); + va_end(va); + return ret; +} + + +int snprintf_(char* buffer, size_t count, const char* format, ...) +{ + va_list va; + va_start(va, format); + const int ret = _vsnprintf(_out_buffer, buffer, count, format, va); + va_end(va); + return ret; +} + + +int vprintf_(const char* format, va_list va) +{ + char buffer[1]; + return _vsnprintf(_out_char, buffer, (size_t)-1, format, va); +} + + +int vsnprintf_(char* buffer, size_t count, const char* format, va_list va) +{ + return _vsnprintf(_out_buffer, buffer, count, format, va); +} + + +int fctprintf(void (*out)(char character, void* arg), void* arg, const char* format, ...) +{ + va_list va; + va_start(va, format); + const out_fct_wrap_type out_fct_wrap = { out, arg }; + const int ret = _vsnprintf(_out_fct, (char*)(uintptr_t)&out_fct_wrap, (size_t)-1, format, va); + va_end(va); + return ret; +} diff --git a/armsrc/nprintf.h b/armsrc/nprintf.h new file mode 100644 index 000000000..8f7a4c8fe --- /dev/null +++ b/armsrc/nprintf.h @@ -0,0 +1,117 @@ +/////////////////////////////////////////////////////////////////////////////// +// \author (c) Marco Paland (info@paland.com) +// 2014-2019, PALANDesign Hannover, Germany +// +// \license The MIT License (MIT) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// \brief Tiny printf, sprintf and snprintf implementation, optimized for speed on +// embedded systems with a very limited resources. +// Use this instead of bloated standard/newlib printf. +// These routines are thread safe and reentrant. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _PRINTF_H_ +#define _PRINTF_H_ + +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * Output a character to a custom device like UART, used by the printf() function + * This function is declared here only. You have to write your custom implementation somewhere + * \param character Character to output + */ +void _putchar(char character); + + +/** + * Tiny printf implementation + * You have to implement _putchar if you use printf() + * To avoid conflicts with the regular printf() API it is overridden by macro defines + * and internal underscore-appended functions like printf_() are used + * \param format A string that specifies the format of the output + * \return The number of characters that are written into the array, not counting the terminating null character + */ +#define printf printf_ +int printf_(const char* format, ...); + + +/** + * Tiny sprintf implementation + * Due to security reasons (buffer overflow) YOU SHOULD CONSIDER USING (V)SNPRINTF INSTEAD! + * \param buffer A pointer to the buffer where to store the formatted string. MUST be big enough to store the output! + * \param format A string that specifies the format of the output + * \return The number of characters that are WRITTEN into the buffer, not counting the terminating null character + */ +#define sprintf sprintf_ +int sprintf_(char* buffer, const char* format, ...); + + +/** + * Tiny snprintf/vsnprintf implementation + * \param buffer A pointer to the buffer where to store the formatted string + * \param count The maximum number of characters to store in the buffer, including a terminating null character + * \param format A string that specifies the format of the output + * \param va A value identifying a variable arguments list + * \return The number of characters that COULD have been written into the buffer, not counting the terminating + * null character. A value equal or larger than count indicates truncation. Only when the returned value + * is non-negative and less than count, the string has been completely written. + */ +#define snprintf snprintf_ +#define vsnprintf vsnprintf_ +int snprintf_(char* buffer, size_t count, const char* format, ...); +int vsnprintf_(char* buffer, size_t count, const char* format, va_list va); + + +/** + * Tiny vprintf implementation + * \param format A string that specifies the format of the output + * \param va A value identifying a variable arguments list + * \return The number of characters that are WRITTEN into the buffer, not counting the terminating null character + */ +#define vprintf vprintf_ +int vprintf_(const char* format, va_list va); + + +/** + * printf with output function + * You may use this as dynamic alternative to printf() with its fixed _putchar() output + * \param out An output function which takes one character and an argument pointer + * \param arg An argument pointer for user data passed to output function + * \param format A string that specifies the format of the output + * \return The number of characters that are sent to the output function, not counting the terminating null character + */ +int fctprintf(void (*out)(char character, void* arg), void* arg, const char* format, ...); + + +#ifdef __cplusplus +} +#endif + + +#endif // _PRINTF_H_ diff --git a/armsrc/string.c b/armsrc/string.c index ea113680e..7931b9a94 100644 --- a/armsrc/string.c +++ b/armsrc/string.c @@ -195,3 +195,157 @@ char *strtok(char *s, const char *delim) { return (__strtok_r(s, delim, &last)); } + + +char *strchr(const char *s, int c) +{ + while (*s != (char)c) + if (!*s++) + return 0; + return (char *)s; +} + +size_t strspn(const char *s1, const char *s2) +{ + size_t ret=0; + while(*s1 && strchr(s2,*s1++)) + ret++; + return ret; +} + +char *strrchr(const char *s, int c) +{ + const char* ret=0; + do { + if( *s == (char)c ) + ret=s; + } while(*s++); + return (char *)ret; +} + +size_t strcspn(const char *s1, const char *s2) +{ + size_t ret=0; + while(*s1) + if(strchr(s2,*s1)) + return ret; + else + s1++,ret++; + return ret; +} + +char *strpbrk(const char *s1, const char *s2) +{ + while(*s1) + if(strchr(s2, *s1++)) + return (char*)--s1; + return 0; +} + +int strncmp(const char* s1, const char* s2, size_t n) +{ + while(n--) + if(*s1++!=*s2++) + return *(unsigned char*)(s1 - 1) - *(unsigned char*)(s2 - 1); + return 0; +} + + + + +#define isspace(a) __extension__ ({ unsigned char bb__isspace = (a) - 9; bb__isspace == (' ' - 9) || bb__isspace <= (13 - 9); }) + +unsigned long strtoul(const char *p, char **out_p, int base) +{ + unsigned long v = 0; + + while (isspace(*p)) + p++; + if (((base == 16) || (base == 0)) && + ((*p == '0') && ((p[1] == 'x') || (p[1] == 'X')))) + { + p += 2; + base = 16; + } + if (base == 0) + { + if (*p == '0') + base = 8; + else + base = 10; + } + while (1) + { + char c = *p; + if ((c >= '0') && (c <= '9') && (c - '0' < base)) + v = (v * base) + (c - '0'); + else if ((c >= 'a') && (c <= 'z') && (c - 'a' + 10 < base)) + v = (v * base) + (c - 'a' + 10); + else if ((c >= 'A') && (c <= 'Z') && (c - 'A' + 10 < base)) + v = (v * base) + (c - 'A' + 10); + else + break; + p++; + } + + if (out_p) *out_p = (char*)p; + return v; +} + +long strtol(const char *p, char **out_p, int base) +{ + long v = 0; + int is_neg = 0; + + while (isspace(*p)) + p++; + if (*p == '-') + is_neg = 1, p++; + else if (*p == '+') + is_neg = 0; + if (((base == 16) || (base == 0)) && + ((*p == '0') && ((p[1] == 'x') || (p[1] == 'X')))) + { + p += 2; + base = 16; + } + if (base == 0) + { + if (*p == '0') + base = 8; + else + base = 10; + } + while (1) + { + char c = *p; + if ((c >= '0') && (c <= '9') && (c - '0' < base)) + v = (v * base) + (c - '0'); + else if ((c >= 'a') && (c <= 'z') && (c - 'a' + 10 < base)) + v = (v * base) + (c - 'a' + 10); + else if ((c >= 'A') && (c <= 'Z') && (c - 'A' + 10 < base)) + v = (v * base) + (c - 'A' + 10); + else + break; + p++; + } + if (is_neg) + v = -v; + if (out_p) *out_p = (char*)p; + return v; +} + +char c_tolower(int c) +{ + // (int)a = 97, (int)A = 65 + // (a)97 - (A)65 = 32 + // therefore 32 + 65 = a + return c > 64 && c < 91 ? c + 32 : c; +} + +char c_isprint (unsigned char c) +{ + if ( c >= 0x20 && c <= 0x7e ) + return 1; + return 0; +} diff --git a/armsrc/string.h b/armsrc/string.h index c30293a2a..5338ae6b3 100644 --- a/armsrc/string.h +++ b/armsrc/string.h @@ -27,5 +27,16 @@ char *strcpy(char *dst, const char *src); char *strncpy(char *destination, const char *source, size_t num); int strcmp(const char *s1, const char *s2); char *strtok(char *s, const char *delim); +char *strchr(const char *s, int c); +size_t strspn(const char *s1, const char *s2); +char *strrchr(const char *s, int c); +size_t strcspn(const char *s1, const char *s2); +char *strpbrk(const char *s1, const char *s2); +int strncmp(const char * s1, const char * s2, size_t n); +char c_tolower(int c); +char c_isprint (unsigned char c); + + + #endif /* __STRING_H */ From 23e9a3af349205e0419c73d526b70117849fd422 Mon Sep 17 00:00:00 2001 From: cjbrigato Date: Wed, 31 Jul 2019 01:36:58 +0200 Subject: [PATCH 0188/1854] HF_COLIN: Add example json scheme file --- armsrc/Standalone/hf_colin.c | 43 ++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/armsrc/Standalone/hf_colin.c b/armsrc/Standalone/hf_colin.c index e280b858e..e5114beed 100644 --- a/armsrc/Standalone/hf_colin.c +++ b/armsrc/Standalone/hf_colin.c @@ -17,6 +17,49 @@ #define HFCOLIN_LASTTAG_SYMLINK "hf_colin/lasttag.bin" #define HFCOLIN_URMETCAPTIVE_JSON "hf_colin/urmetcaptive.json" +/* Example jsonconfig file urmetcaptive.json : +{ + "name": "UrmetCaptive", + "trigger": "0x8829da9daf76", + "keysA": [ + "0x8829da9daf76", + "0x8829da9daf76", + "0x8829da9daf76", + "0x8829da9daf76", + "0x8829da9daf76", + "0x8829da9daf76", + "0x8829da9daf76", + "0x8829da9daf76", + "0x8829da9daf76", + "0x8829da9daf76", + "0x8829da9daf76", + "0x8829da9daf76", + "0x8829da9daf76", + "0x8829da9daf76", + "0x8829da9daf76", + "0x8829da9daf76" + ], + "keysB": [ + "0x8829da9daf76", + "0x8829da9daf76", + "0x8829da9daf76", + "0x8829da9daf76", + "0x8829da9daf76", + "0x8829da9daf76", + "0x8829da9daf76", + "0x8829da9daf76", + "0x8829da9daf76", + "0x8829da9daf76", + "0x8829da9daf76", + "0x8829da9daf76", + "0x8829da9daf76", + "0x8829da9daf76", + "0x8829da9daf76", + "0x8829da9daf76" + ] +} +*/ + uint8_t cjuid[10]; uint32_t cjcuid; iso14a_card_select_t p_card; From 902f520bcee563f35ae95bcfe7b96bdefbeabd66 Mon Sep 17 00:00:00 2001 From: cjbrigato Date: Wed, 31 Jul 2019 08:12:49 +0200 Subject: [PATCH 0189/1854] HF_COLIN: Now works with shemas.json, an array of schemes, dynamically loaded at runtime --- armsrc/Standalone/hf_colin.c | 80 +++++++++++++++++++----------------- 1 file changed, 43 insertions(+), 37 deletions(-) diff --git a/armsrc/Standalone/hf_colin.c b/armsrc/Standalone/hf_colin.c index e5114beed..a13ebca56 100644 --- a/armsrc/Standalone/hf_colin.c +++ b/armsrc/Standalone/hf_colin.c @@ -15,10 +15,10 @@ #define MF1KSZSIZE 64 #define AUTHENTICATION_TIMEOUT 848 #define HFCOLIN_LASTTAG_SYMLINK "hf_colin/lasttag.bin" -#define HFCOLIN_URMETCAPTIVE_JSON "hf_colin/urmetcaptive.json" +#define HFCOLIN_SCHEMAS_JSON "hf_colin/schemas.json" -/* Example jsonconfig file urmetcaptive.json : -{ +/* Example jsonconfig file schemas.json : (array !) +[{ "name": "UrmetCaptive", "trigger": "0x8829da9daf76", "keysA": [ @@ -57,7 +57,12 @@ "0x8829da9daf76", "0x8829da9daf76" ] -} +},{ + "name": "Noralsy", +... + +] + */ uint8_t cjuid[10]; @@ -142,7 +147,7 @@ static void scan_keys(const char *str, int len, uint64_t *user_data) { MFC1KSchema Schemas[MAX_SCHEMAS]; -MFC1KSchema Noralsy = { +/*MFC1KSchema Noralsy = { .name = "Noralsy", .trigger = 0x414c41524f4e, .keysA = {0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e, @@ -161,6 +166,7 @@ MFC1KSchema InfiHexact = {.name = "Infineon/Hexact", .keysB = {0xa22ae129c013, 0x49fae4e3849f, 0x38fcf33072e0, 0x8ad5517b4b18, 0x509359f131b1, 0x6c78928e1317, 0xaa0720018738, 0xa6cac2886412, 0x62d0c424ed8e, 0xe64a986a5d94, 0x8fa1d601d0a2, 0x89347350bd36, 0x66d2b7dc39ef, 0x6bc1e1ae547d, 0x22729a9bd40f}}; +*/ /*MFC1KSchema UrmetCaptive = { .name = "Urmet Captive", @@ -217,31 +223,41 @@ foundKey[5]); cjSetCursRight(); DbprintfEx(FLAG_NEWLINE, "SEC: %02x | KEY : %s | } */ -char *ReadSchemasFromSPIFFS() { +char *ReadSchemasFromSPIFFS(char *filename) { SpinOff(0); - LED_A_ON(); - LED_B_ON(); - LED_C_ON(); - LED_D_ON(); - - DbprintfEx(FLAG_NEWLINE, "Reading Json Configuration Files..."); - cjSetCursLeft(); int changed = rdv40_spiffs_lazy_mount(); - uint32_t size = size_in_spiffs((char *)HFCOLIN_URMETCAPTIVE_JSON); + uint32_t size = size_in_spiffs((char *)filename); uint8_t *mem = BigBuf_malloc(size); - // this one will handle filetype (symlink or not) and resolving by itself - rdv40_spiffs_read_as_filetype((char *)HFCOLIN_URMETCAPTIVE_JSON, (uint8_t *)mem, size, RDV40_SPIFFS_SAFETY_SAFE); + rdv40_spiffs_read_as_filetype((char *)filename, (uint8_t *)mem, size, RDV40_SPIFFS_SAFETY_SAFE); if (changed) { rdv40_spiffs_lazy_unmount(); } - DbprintfEx(FLAG_NEWLINE, "[OK] Returning One config file"); - cjSetCursLeft(); SpinOff(0); return (char *)mem; } +void add_schemas_from_json_in_spiffs(char *filename) { + + char *jsonfile = ReadSchemasFromSPIFFS((char *)filename); + + int i, len = strlen(jsonfile); + struct json_token t; + for (i = 0; json_scanf_array_elem(jsonfile, len, "", i, &t) > 0; i++) { + char *tmpname; + char *tmptrigger; + MFC1KSchema tmpscheme; + json_scanf(t.ptr, t.len, "{ name:%Q, trigger:%Q, keysA:%M, keysB:%M}", &tmpname, &tmptrigger, scan_keys, + &tmpscheme.keysA, scan_keys, &tmpscheme.keysB); + memcpy(tmpscheme.name, tmpname, 32); + tmpscheme.trigger = hex2i(tmptrigger); + add_schema(Schemas, tmpscheme, &total_schemas); + DbprintfEx(FLAG_NEWLINE, "Schema loaded : %s", tmpname); + cjSetCursLeft(); + } +} + void ReadLastTagFromFlash() { SpinOff(0); LED_A_ON(); @@ -285,8 +301,8 @@ void WriteTagToFlash(uint32_t uid, size_t size) { sprintf(dest, "hf_colin/mf_%02x%02x%02x%02x.bin", buid[0], buid[1], buid[2], buid[3]); // TODO : by using safe function for multiple writes we are both breaking cache mecanisms and making useless and - // unoptimized mount operations we should manage at out level the mount status before and after the whole standalone - // mode + // unoptimized mount operations we should manage at out level the mount status before and after the whole + // standalone mode rdv40_spiffs_write((char *)dest, (uint8_t *)data, len, RDV40_SPIFFS_SAFETY_SAFE); // lastag will only contain filename/path to last written tag file so we don't loose time or space. rdv40_spiffs_make_symlink((char *)dest, (char *)HFCOLIN_LASTTAG_SYMLINK, RDV40_SPIFFS_SAFETY_SAFE); @@ -302,22 +318,10 @@ void ModInfo(void) { DbpString(" HF Mifare ultra fast sniff/sim/clone - aka VIG void RunMod() { StandAloneMode(); - char *tmpname; - char *tmptrigger; - MFC1KSchema tmpscheme; - char *urmetcaptive2test = ReadSchemasFromSPIFFS(); - json_scanf(urmetcaptive2test, strlen(urmetcaptive2test), "{ name:%Q, trigger:%Q, keysA:%M, keysB:%M}", &tmpname, - &tmptrigger, scan_keys, &tmpscheme.keysA, scan_keys, &tmpscheme.keysB); - - memcpy(tmpscheme.name, tmpname, 32); - tmpscheme.trigger = hex2i(tmptrigger); - - add_schema(Schemas, tmpscheme, &total_schemas); - - add_schema(Schemas, Noralsy, &total_schemas); - add_schema(Schemas, InfiHexact, &total_schemas); + // add_schema(Schemas, Noralsy, &total_schemas); + // add_schema(Schemas, InfiHexact, &total_schemas); + // add_schema_from_json_in_spiffs((char *)HFCOLIN_URMETCAPTIVE_JSON); // add_schema(Schemas, UrmetCaptive, &total_schemas); - FpgaDownloadAndGo(FPGA_BITSTREAM_HF); currline = 20; @@ -454,6 +458,8 @@ ACCBITS : 796788[00]+VALUE currfline = 24; cjSetCursLeft(); + add_schemas_from_json_in_spiffs((char *)HFCOLIN_SCHEMAS_JSON); + failtag: vtsend_cursor_position_save(NULL); @@ -548,8 +554,8 @@ failtag: if (key == -1) { err = 1; allKeysFound = false; - // used in portable imlementation on microcontroller: it reports back the fail and open the standalone - // lock reply_old(CMD_CJB_FSMSTATE_MENU, 0, 0, 0, 0, 0); + // used in portable imlementation on microcontroller: it reports back the fail and open the + // standalone lock reply_old(CMD_CJB_FSMSTATE_MENU, 0, 0, 0, 0, 0); break; } else if (key == -2) { err = 1; // Can't select card. From 5edd342d4c35ad9d958400544623dd9600ac22d3 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 31 Jul 2019 12:04:32 +0200 Subject: [PATCH 0190/1854] Add NTAG_I2C_1K support to hf mfu, thanks JP Szikora --- client/cmdhfmfu.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index 696955b6e..b70a6db8f 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -19,6 +19,7 @@ #define MAX_NTAG_213 0x2C #define MAX_NTAG_215 0x86 #define MAX_NTAG_216 0xE6 +#define MAX_NTAG_I2C_1K 0xE9 #define MAX_MY_D_NFC 0xFF #define MAX_MY_D_MOVE 0x25 #define MAX_MY_D_MOVE_LEAN 0x0F @@ -248,19 +249,19 @@ uint8_t public_keys[2][PUBLIC_ECDA_KEYLEN] = { }; -#define MAX_UL_TYPES 22 +#define MAX_UL_TYPES 23 uint32_t UL_TYPES_ARRAY[MAX_UL_TYPES] = { UNKNOWN, UL, UL_C, UL_EV1_48, UL_EV1_128, NTAG, NTAG_203, NTAG_210, NTAG_212, NTAG_213, NTAG_215, NTAG_216, MY_D, MY_D_NFC, MY_D_MOVE, MY_D_MOVE_NFC, MY_D_MOVE_LEAN, FUDAN_UL, - UL_EV1, NTAG_213_F, NTAG_216_F, UL_NANO_40 + UL_EV1, NTAG_213_F, NTAG_216_F, UL_NANO_40, NTAG_I2C_1K }; uint8_t UL_MEMORY_ARRAY[MAX_UL_TYPES] = { MAX_UL_BLOCKS, MAX_UL_BLOCKS, MAX_ULC_BLOCKS, MAX_ULEV1a_BLOCKS, MAX_ULEV1b_BLOCKS, MAX_NTAG_203, MAX_NTAG_203, MAX_NTAG_210, MAX_NTAG_212, MAX_NTAG_213, MAX_NTAG_215, MAX_NTAG_216, MAX_UL_BLOCKS, MAX_MY_D_NFC, MAX_MY_D_MOVE, MAX_MY_D_MOVE, MAX_MY_D_MOVE_LEAN, MAX_UL_BLOCKS, - MAX_ULEV1a_BLOCKS, MAX_NTAG_213, MAX_NTAG_216, MAX_UL_NANO_40 + MAX_ULEV1a_BLOCKS, MAX_NTAG_213, MAX_NTAG_216, MAX_UL_NANO_40, MAX_NTAG_I2C_1K }; //------------------------------------ From f0c939b1bcb4096d90045eaa2d5c76ad8b7acfa7 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 31 Jul 2019 12:14:44 +0200 Subject: [PATCH 0191/1854] hf mfu: avoid hardcoded array size --- client/cmdhfmfu.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index b70a6db8f..fcdd2f149 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -249,15 +249,14 @@ uint8_t public_keys[2][PUBLIC_ECDA_KEYLEN] = { }; -#define MAX_UL_TYPES 23 -uint32_t UL_TYPES_ARRAY[MAX_UL_TYPES] = { +uint32_t UL_TYPES_ARRAY[] = { UNKNOWN, UL, UL_C, UL_EV1_48, UL_EV1_128, NTAG, NTAG_203, NTAG_210, NTAG_212, NTAG_213, NTAG_215, NTAG_216, MY_D, MY_D_NFC, MY_D_MOVE, MY_D_MOVE_NFC, MY_D_MOVE_LEAN, FUDAN_UL, UL_EV1, NTAG_213_F, NTAG_216_F, UL_NANO_40, NTAG_I2C_1K }; -uint8_t UL_MEMORY_ARRAY[MAX_UL_TYPES] = { +uint8_t UL_MEMORY_ARRAY[ARRAYLEN(UL_TYPES_ARRAY)] = { MAX_UL_BLOCKS, MAX_UL_BLOCKS, MAX_ULC_BLOCKS, MAX_ULEV1a_BLOCKS, MAX_ULEV1b_BLOCKS, MAX_NTAG_203, MAX_NTAG_203, MAX_NTAG_210, MAX_NTAG_212, MAX_NTAG_213, MAX_NTAG_215, MAX_NTAG_216, MAX_UL_BLOCKS, MAX_MY_D_NFC, MAX_MY_D_MOVE, MAX_MY_D_MOVE, MAX_MY_D_MOVE_LEAN, MAX_UL_BLOCKS, @@ -1361,7 +1360,7 @@ static int CmdHF14AMfUInfo(const char *Cmd) { uint8_t ulev1_conf[16] = {0x00}; // config blocks always are last 4 pages - for (uint8_t i = 0; i < MAX_UL_TYPES; i++) { + for (uint8_t i = 0; i < ARRAYLEN(UL_TYPES_ARRAY); i++) { if (tagtype & UL_TYPES_ARRAY[i]) { startconfigblock = UL_MEMORY_ARRAY[i] - 3; break; @@ -1529,7 +1528,7 @@ static int CmdHF14AMfUWrBl(const char *Cmd) { if (tagtype == UL_ERROR) return -1; uint8_t maxblockno = 0; - for (uint8_t idx = 0; idx < MAX_UL_TYPES; idx++) { + for (uint8_t idx = 0; idx < ARRAYLEN(UL_TYPES_ARRAY); idx++) { if (tagtype & UL_TYPES_ARRAY[idx]) { maxblockno = UL_MEMORY_ARRAY[idx]; break; @@ -1643,7 +1642,7 @@ static int CmdHF14AMfURdBl(const char *Cmd) { if (tagtype == UL_ERROR) return -1; uint8_t maxblockno = 0; - for (uint8_t idx = 0; idx < MAX_UL_TYPES; idx++) { + for (uint8_t idx = 0; idx < ARRAYLEN(UL_TYPES_ARRAY); idx++) { if (tagtype & UL_TYPES_ARRAY[idx]) { maxblockno = UL_MEMORY_ARRAY[idx]; break; @@ -1917,7 +1916,7 @@ static int CmdHF14AMfUDump(const char *Cmd) { //get number of pages to read if (!manualPages) { - for (uint8_t idx = 0; idx < MAX_UL_TYPES; idx++) { + for (uint8_t idx = 0; idx < ARRAYLEN(UL_TYPES_ARRAY); idx++) { if (tagtype & UL_TYPES_ARRAY[idx]) { //add one as maxblks starts at 0 card_mem_size = pages = UL_MEMORY_ARRAY[idx] + 1; From 98624037ade9162e435f2562337d90dcdea4b4ef Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 31 Jul 2019 12:43:15 +0200 Subject: [PATCH 0192/1854] hf mfu: please no extended ascii char --- client/cmdhfmfu.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index fcdd2f149..3f4c59115 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -816,13 +816,13 @@ int ul_print_type(uint32_t tagtype, uint8_t spaces) { else if (tagtype & NTAG_216_F) PrintAndLogEx(NORMAL, "%sTYPE : NTAG 216F 888bytes (NT2H1611F0DTL)", spacer); else if (tagtype & NTAG_I2C_1K) - PrintAndLogEx(NORMAL, "%sTYPE : NTAG I%sC 888bytes (NT3H1101FHK)", spacer, "\xFD"); + PrintAndLogEx(NORMAL, "%sTYPE : NTAG I2C 888bytes (NT3H1101FHK)", spacer); else if (tagtype & NTAG_I2C_2K) - PrintAndLogEx(NORMAL, "%sTYPE : NTAG I%sC 1904bytes (NT3H1201FHK)", spacer, "\xFD"); + PrintAndLogEx(NORMAL, "%sTYPE : NTAG I2C 1904bytes (NT3H1201FHK)", spacer); else if (tagtype & NTAG_I2C_1K_PLUS) - PrintAndLogEx(NORMAL, "%sTYPE : NTAG I%sC plus 888bytes (NT3H2111FHK)", spacer, "\xFD"); + PrintAndLogEx(NORMAL, "%sTYPE : NTAG I2C plus 888bytes (NT3H2111FHK)", spacer); else if (tagtype & NTAG_I2C_2K_PLUS) - PrintAndLogEx(NORMAL, "%sTYPE : NTAG I%sC plus 1912bytes (NT3H2211FHK)", spacer, "\xFD"); + PrintAndLogEx(NORMAL, "%sTYPE : NTAG I2C plus 1912bytes (NT3H2211FHK)", spacer); else if (tagtype & MY_D) PrintAndLogEx(NORMAL, "%sTYPE : INFINEON my-d\x99 (SLE 66RxxS)", spacer); else if (tagtype & MY_D_NFC) From 774c8dd6661bc326407f1745c1b098a05634f146 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 31 Jul 2019 15:50:10 +0200 Subject: [PATCH 0193/1854] Add: 'fpga LF ADC path' - a major mode for LF ADC path --- fpga/fpga_lf.v | 36 ++++++++++++++-------- fpga/lo_adc.v | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+), 12 deletions(-) create mode 100644 fpga/lo_adc.v diff --git a/fpga/fpga_lf.v b/fpga/fpga_lf.v index eba43b32f..20d2ca440 100644 --- a/fpga/fpga_lf.v +++ b/fpga/fpga_lf.v @@ -6,6 +6,7 @@ `include "lo_read.v" `include "lo_passthru.v" `include "lo_edge_detect.v" +`include "lo_adc.v" `include "util.v" `include "clk_divider.v" @@ -100,24 +101,35 @@ lo_edge_detect le( lf_ed_toggle_mode, lf_ed_threshold ); +lo_adc la( + pck0, + la_pwr_lo, la_pwr_hi, la_pwr_oe1, la_pwr_oe2, la_pwr_oe3, la_pwr_oe4, + adc_d, la_adc_clk, + la_ssp_frame, la_ssp_din, ssp_dout, la_ssp_clk, + cross_hi, cross_lo, + la_dbg, divisor, + lo_is_125khz, lf_field +); + // Major modes: // 000 -- LF reader (generic) // 001 -- LF edge detect (generic) // 010 -- LF passthrough +// 011 -- LF ADC (read/write) // 110 -- FPGA_MAJOR_MODE_OFF_LF (rdv40 specific) // 111 -- FPGA_MAJOR_MODE_OFF -// 000 001 010 011 100 101 110 111 -mux8 mux_ssp_clk (major_mode, ssp_clk, lr_ssp_clk, le_ssp_clk, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_ssp_din (major_mode, ssp_din, lr_ssp_din, 1'b0, lp_ssp_din, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_ssp_frame (major_mode, ssp_frame, lr_ssp_frame, le_ssp_frame, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_pwr_oe1 (major_mode, pwr_oe1, lr_pwr_oe1, le_pwr_oe1, lp_pwr_oe1, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_pwr_oe2 (major_mode, pwr_oe2, lr_pwr_oe2, le_pwr_oe2, lp_pwr_oe2, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_pwr_oe3 (major_mode, pwr_oe3, lr_pwr_oe3, le_pwr_oe3, lp_pwr_oe3, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_pwr_oe4 (major_mode, pwr_oe4, lr_pwr_oe4, le_pwr_oe4, lp_pwr_oe4, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_pwr_lo (major_mode, pwr_lo, lr_pwr_lo, le_pwr_lo, lp_pwr_lo, 1'b0, 1'b0, 1'b0, 1'b1, 1'b0); -mux8 mux_pwr_hi (major_mode, pwr_hi, lr_pwr_hi, le_pwr_hi, lp_pwr_hi, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_adc_clk (major_mode, adc_clk, lr_adc_clk, le_adc_clk, lp_adc_clk, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_dbg (major_mode, dbg, lr_dbg, le_dbg, lp_dbg, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0); +// 000 001 010 011 100 101 110 111 +mux8 mux_ssp_clk (major_mode, ssp_clk, lr_ssp_clk, le_ssp_clk, 1'b0, la_ssp_clk, 1'b0, 1'b0, 1'b0, 1'b0); +mux8 mux_ssp_din (major_mode, ssp_din, lr_ssp_din, 1'b0, lp_ssp_din, la_ssp_din, 1'b0, 1'b0, 1'b0, 1'b0); +mux8 mux_ssp_frame (major_mode, ssp_frame, lr_ssp_frame, le_ssp_frame, 1'b0, la_ssp_frame, 1'b0, 1'b0, 1'b0, 1'b0); +mux8 mux_pwr_oe1 (major_mode, pwr_oe1, lr_pwr_oe1, le_pwr_oe1, lp_pwr_oe1, la_pwr_oe1, 1'b0, 1'b0, 1'b0, 1'b0); +mux8 mux_pwr_oe2 (major_mode, pwr_oe2, lr_pwr_oe2, le_pwr_oe2, lp_pwr_oe2, la_pwr_oe2, 1'b0, 1'b0, 1'b0, 1'b0); +mux8 mux_pwr_oe3 (major_mode, pwr_oe3, lr_pwr_oe3, le_pwr_oe3, lp_pwr_oe3, la_pwr_oe3, 1'b0, 1'b0, 1'b0, 1'b0); +mux8 mux_pwr_oe4 (major_mode, pwr_oe4, lr_pwr_oe4, le_pwr_oe4, lp_pwr_oe4, la_pwr_oe4, 1'b0, 1'b0, 1'b0, 1'b0); +mux8 mux_pwr_lo (major_mode, pwr_lo, lr_pwr_lo, le_pwr_lo, lp_pwr_lo, la_pwr_lo, 1'b0, 1'b0, 1'b1, 1'b0); +mux8 mux_pwr_hi (major_mode, pwr_hi, lr_pwr_hi, le_pwr_hi, lp_pwr_hi, la_pwr_hi, 1'b0, 1'b0, 1'b0, 1'b0); +mux8 mux_adc_clk (major_mode, adc_clk, lr_adc_clk, le_adc_clk, lp_adc_clk, la_adc_clk, 1'b0, 1'b0, 1'b0, 1'b0); +mux8 mux_dbg (major_mode, dbg, lr_dbg, le_dbg, lp_dbg, la_dbg, 1'b0, 1'b0, 1'b0, 1'b0); // In all modes, let the ADC's outputs be enabled. assign adc_noe = 1'b0; diff --git a/fpga/lo_adc.v b/fpga/lo_adc.v new file mode 100644 index 000000000..f9b1470fc --- /dev/null +++ b/fpga/lo_adc.v @@ -0,0 +1,82 @@ +//----------------------------------------------------------------------------- +// The way that we connect things in low-frequency simulation mode. In this +// case just pass everything through to the ARM, which can bit-bang this +// (because it is so slow). +// +// Jonathan Westhues, April 2006 +//----------------------------------------------------------------------------- + +module lo_adc( + pck0, + pwr_lo, pwr_hi, pwr_oe1, pwr_oe2, pwr_oe3, pwr_oe4, + adc_d, adc_clk, + ssp_frame, ssp_din, ssp_dout, ssp_clk, + cross_hi, cross_lo, + dbg, divisor, + lo_is_125khz, lf_field +); + input pck0; + output pwr_lo, pwr_hi, pwr_oe1, pwr_oe2, pwr_oe3, pwr_oe4; + input [7:0] adc_d; + output adc_clk; + input ssp_dout; + output ssp_frame, ssp_din, ssp_clk; + input cross_hi, cross_lo; + output dbg; + input [7:0] divisor; + input lo_is_125khz; // redundant signal, no longer used anywhere + input lf_field; + +reg [7:0] to_arm_shiftreg; +reg [7:0] pck_divider; +reg clk_state; + +// Antenna logic, depending on "lf_field" (in arm defined as FPGA_LF_READER_FIELD) +wire tag_modulation; +assign tag_modulation = ssp_dout & !lf_field; +wire reader_modulation; +assign reader_modulation = !ssp_dout & lf_field & clk_state; +assign pwr_oe1 = 1'b0; // not used in LF mode +assign pwr_oe2 = 1'b0; //tag_modulation; +assign pwr_oe3 = tag_modulation; +assign pwr_oe4 = 1'b0; //tag_modulation; +assign pwr_lo = reader_modulation; +assign pwr_hi = 1'b0; +assign dbg = adc_clk; + +// ADC clock out of phase with antenna driver +assign adc_clk = ~clk_state; +// serialized SSP data is gated by clk_state to suppress unwanted signal +assign ssp_din = to_arm_shiftreg[7] && !clk_state; +// SSP clock always runs at 24Mhz +assign ssp_clk = pck0; +// SSP frame is gated by clk_state and goes high when pck_divider=8..15 +assign ssp_frame = (pck_divider[7:3] == 5'd1) && !clk_state; + +always @(posedge pck0) +begin + if(pck_divider == divisor[7:0]) + begin + pck_divider <= 8'd0; + clk_state = !clk_state; + end + else + begin + pck_divider <= pck_divider + 1; + end +end + +always @(posedge pck0) +begin + if((pck_divider == 8'd7) && !clk_state) + begin + to_arm_shiftreg <= adc_d; + end + else + begin + to_arm_shiftreg[7:1] <= to_arm_shiftreg[6:0]; + to_arm_shiftreg[0] <= 1'b0; + end +end + +endmodule From 73a4a30ecf1e8dcad8ed620f0a6583c5ddf68a90 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 31 Jul 2019 15:50:55 +0200 Subject: [PATCH 0194/1854] textual --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b38c4eae9..074367de1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Add FPGA LF adc path (@anon) - Add ECC support / check for NID_secp128r1 (@pwpiwi) - Add some more default keys (ollibolli) - Fix T55x7 Downlink timings backward compatible (@mwalker33) From 141ab65f7873faaee19d50d777b5e10cbd96ccf1 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 31 Jul 2019 16:14:50 +0200 Subject: [PATCH 0195/1854] chg: compiled binary fpga lf --- fpga/fpga_lf.bit | Bin 42175 -> 42175 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/fpga/fpga_lf.bit b/fpga/fpga_lf.bit index a668017bf5bd30773e80319dcf61b46028fa9333..f694ad4cf7e0cafa299260f536faa36113164ba4 100644 GIT binary patch literal 42175 zcmeIb4Rl=PbvC-sdyd4>%t&)A%T(d_Xe7v>j-;_E z+eK1^^!7S!+P?Y$kAH{ap=bwNY<7U+aWO zNXn8;rYDS2GlirsDc?P!+PD?x=)COCN9Xi&G(V(-w`pE>+tCwxK^x#k(t48~m#z8m ze(@&lCkUeu)RR$>H7&>op^!X#e7GU4Mcd6*ujRyUjz zvnJl-hO=Ut4p3_rZ!Q=qZbM6E=`3}*(VYGUolYrXn&zmBqEeqSRDbf?6Lg-s-Dp9d zqjy=zL-3!d_c+$W{(Fqmz03K933-OPoM;B`vH7beDiVHw=p$Opy*w*+(t-Zg2g3g# z-o^&PCttBPFs>a7Q@HZuA)a}OFq0oyyWbY4Lm6@iK zpQBy!I@S5olL9sjK7Domnm$K4$9BWEaCvblY~Vd=O=p&j5@r?OzW6og73W6o#*Fu5 zhknNUu0G1E6}&|1FI%@qu#_V@_84_j)YXr9d&9KUD0p?=be`ju6^HI(=ks^>zC~E$F3bP)I_PVyWy#!XS}t@8oPM6@VCE8|BmT}Fzt9x8fQHH zij&_4#f%) z>z7dah5lF&QlgIga~Q(w-aHc(b?}Sg1Yw!j=$&LiLMvTQzfxuWnqakpO$fR6o^;|< z;Yu;#t@|i!X3-wLyy~n#pR@W;`4 zXdxH>!Z|NHU_75*X2J3w+E&orUe#vMxU*yre=2jdoclaV`!lUpctqqKwdZBoX3o%e z?HFu$rCMc&+jwhXQlw-vC$MRo4q*d~@a~l`o<;ql$epEe@g8gEwMckRvbwAH^ZvLiU=xPDufZdqVXDSD{O#r_R(s}!aR5gIid10_SAD+_-LbWO3SIvIWN>9mH z59LH&q-CoePS+OaCxBmDX|L7fRwajK2M1ZvlHwIlze@OZORhFyJg(WUiTBWEqje}O zYm4~hl<|ufZn;~X!x9{&uBqtgh4@v&<0`_|Bm)^me+VFRcwA-t(q`#Pbd`Gvzh{D# zG5gz7hRtn!{Aw4o^wg9Gtn{pe#$|fmwj6G=0KfK*sNqb~*LW?g_rfoFG~JR4Z|HfO zMkIvw7vdLSYf=H(tq{Zy%}$D1u;J>n0Kd-HD}XN0IR>&Bj6KDTeEeFW^ZclFx9Kvn zvJv?n_yxsJLf;GG3A&pa9CP43@avnf8^GKRqSk&;Hri&NxEQ~%A+=aOoQr*rhWoN^ zJb590!Mu;cSnZUTWc6lx(P@{F?1lIR69))zx(sFOPV#z9ya#?w(_8XJr!u2A*+*;z zWEbNXpzY%^$IR3=(V)HaeejFEZZ$ihj95nZQlk@|T7X}?Gl2!PJ8nB63-;$;%n$HA zfL}$gDNiTt8|k+s(3^ow;g`~{0Desyr;X^E>idVMvu}9@|EHdQ)mIepYYK48KZ;}k z{zoVV;bQ!{6!@jxNpLo8N>hyD^1bkjcA)d7B@7zGdrT{K0e)Rxf_2qqlg1MzO8DjD zDWLx~(aPOuqC?c)3!#KxnvY-8Y*N;>0psYbebBizqnGf@D&rS`teqlqwaxlP+oX?Q z6-E3S9h#xXoMvfe7q73}tU-6O;sX4Fm4M$1dx)(Sp&@0=(Z;i58n!V*KtCX0U;4U9 z^RC!e()ZxWmH|=3uTh0xEeu;P8K=@qUypo6zsfo6A=-ubmC<1{ZJ3lthTm|{u4f=y zUBoXc;}`sS*`1HDWB)gq4i?C>hYG(+{dvS`ar*|)v3snBG3ZybhwlOWLZ7X+@esH9 zJ8E>zf`H4*x@?#5%c`BEJs9$3N%7n&z27dF*9+4~a+?5t&C&*#g4TlmW14bfg~$_n zvu6_m_%%xfr^~I%EuJ;7dl?iiz^|+4^m%LEV*JwQ?Mbs^EK(SzUiDo*e(e{t#sL@D zl&hVk*KdcRPS)BN;MaYynFom5KuA+F8*{seUq%tXEHP>9p_Gfot7yVg$(wLyT+(=F*&0F^?i{^a_c7C2#sy>5D{e>GH&}Zrf_%)1Q%Db3=OMG75 zV8f&^|H69VYdwF1@oPWOYD*eS>T!Y{V@J8-DO78n0errgfL^z$#yq#uWpt3*E!MM6rIPo zfL{)TQ*_>a%8hOa&w2ZY@#~D!m4Rn9YoE1lbRo>p+yLJ50N!Ks*cE=63bx*$$NOW1 z{!G*3&Q6}^c5f{hzjEn>0E=`%IpYK?HV%Uyo2(+SqU0Z5Wx{)Bv^oX~11z{*ylCtj zY{*yD3)6cK^RKrE{EKuK<67ZFlZ(gcY=3g1dYN8}9gWXI{Gx6NQ#r>ztqY`{s!VYk z#;*dk%S2Xxg`TC(EQDD$GH!J?-0ZEF$G;j}XwymB2p8S#7gMwk8fPX&tvAoizn+o} zg{lqWoV`)D|m*QV=iK~{17lwu@Vb^04v>b@Dd1Ga*x9-fp&dH_n z-ZvUgvzsv#0S%PQ$f{r0Z}h%P@h_{3Y7~AkY`Mx;SL`Opzq0M?VMW>C-{oMvAUHRs zB9<<^?*jiacMru2#?Jif0D1@{0%QxD^~=z9^Aig;!TYWy;9qv^HuC{-jod=9o^WQU ziFQ}2->UT1A`AR_E5D~d@j&>)fYJ8;=mWqnIKWQg8+zQ^KXGjrot8YD)o6^X%6R(Jy2dO2;z;7IMpzk)|=AdlMwPZ!eTMNa% z%*4rXGByeQvf0*6!U2wto5|4T3-D_IT;@@8ha2XN{U|lKRRbdKy~o2ZkAK-u$)yU& zz{qaOM^@qgTTrX&fuWQ1WPJxTuJ$|LJbU=n=m4#*(C(%-{HW)o{U|nDd|)VmUpXgR z8&8U;%u?i3)e7-E?RRW4+eO-2cZFXLtQP2r@vP{|NA~M)(pkCOHTMPaYtDkL+dce- zGpF&m7Gr>YUHypm1n}$Kba#Igutn!HonzI7;d%RA9x3pmH_7wE__g1;)@DeOF!*c+ zXK8v5~vcRu-T0%gplgbRL&OgBhq_BX0QAY{3x?R9=!J5q6kgss{0Di$@ z7hy}b9XIDio;KOBy!lutfM0tJTT`&bfyBOKj|*i45u?ou@C%T=Q_N-&CppxY6K@P{ zF@eiFh64BnT2Tww`iUABhLfiwQ_I}y$sm3Kwx(3f6Z>$iEeC9R5_Ue?7sRi3tac-M zpZ+q;`$t^7XPJcmJQ1B*Ql7a_fuOQo2>=DUu+_p4dT~c#~uqe4Lxt?3^U)i z>|2eF)a)Mu(aQM6SYQLT7{6Lx0Tx`UkI06X!wc~19m=`bQBY4>;YN~S6aGfdy*haT ze!;viF7yJnp4s+ueSS6KhvPMG1@TM86BxGUsQX0CBa5G?1W$1{PA$Z*7J^wue1qD? ztM3w5(7%`s?&Vexze+Jr>(P;xeDjx~J0tQsCSqm$GO&~shMPl4tm(It)>_JlxEp?A zD1cv#R^e>pjCqDyWlgpNK;}FqqqE^4e)+H^x~!;NE!{c$T8a+7C;x(x>AkbI@mlj) zss%`ehdfFI!}cbMIW-yRj>S6Y#Shz@@RSN0CVKi{@J9xz znZfR!l71PqJE5Y53|omcrd4BP2Wiv^F&6M^RQwQrlm}Z+P?s5zi|rv-yHShYt$)wc zFQ0$q7EfDewXQYMy2Yniarjf>towj-|X4LK>V-( ztV{s5#Ef+U!H)3VB7k3Bv@mv@LotA@%5m_ogaeHW@GnG4y|Htk6<{|_Uw2v&DHQ?y z@*(K}Kq|t4#3K$s>KpILzfRkotNu8rPfHa)yg!Iv^JcdheFm<`oO6``tZT6etz95E z95QU4L*N%Z=Co#R*#+2ojM`*+*XlpFHXC{tj$#16a!$emDRnh$w&SKPK0(7|!}^6n z7vUGf7TmD)L;pK%%r%Sw$O8EF3)zy5u1DCA1BrmGo9Tt@?uO_Yy?FtCIm(qiiw)Vf zYj~QTvSIM|1^L&zvO9(B3HMvPNJFa zd7hszqUAl?G6DZE%N`>MX-aHAKBISbbh2e zkMP<#Iz57giD@Zq-Lw0f!h!)6y0k){7N1viow34F7 z!{C+FJ&tkt{A*JEI^Zt?{)P8^RZjpo)ch3lUlWTmG=dAm@L~Qn+-r}S$)0K&{uGB1M8w&fR%;r_e~o36 z`y->nzbVJu_R+|9^k(y%vqvIO@8`b?V&3ky+FtO*8UEvp|Mn*74#B;RO)$`_D zOc9MY1NfzNIe+YR6%b${4)Cs*R4U__ID}C|tgs5xIgu&wo!7i^1@d2MBc@^d*;bk! zV*DZ_t;OgTKmXNN@vn5ZY;f1#F0K#=1-t1a;-Y_Fig_yis$cRgx>q(1^c@p7)Zd$G zOvSfjfd80kToo>mA3q$YBb4knx9iu?5x4zz#51p@*QAQm7UPHOHSjNt>(=f1w9NvR z;HUE62~QTp4=3#oGcvI_Y0gszd=i+8@l=Nia$U-QRm8>6*v^dE9IB!{hq9UQIsn<` z-Wa@{VEk~{;;q$FZSJ+R6XEulOHu;As2o4+q_64?wBD_?B2SnN65Dv5Hm+)LZ&?sO zgdNL9`t({lC6}&K`7c-QW<-0vgkM|f40SrN035QYu^`NdvxXXAnSY7Ha<6^ogx)U3 z2lv{EIS4Ndb)*oOD(AnP5vu`6RC^_Dv>Keyz|a*mVqG^9{$e@*^#pC@t@W1p3T>lC zX|59coQk!O-!lhK3vKbdEpuE^Sb+B$lN@oSgvJ~#_EOm;d-!}F6b9fkHgNO?QGEQ za<}FD{MVHyy!ghzbtld9v~pFA)5tm2zk-J!>gO{tEzozmbqI_&$C;OphBo z-EfxJsTVFN=eYfKQ#p!7{GuhZ#xc7+U2W^8yoD}3RGrgb7AKreCvm^-dhwRL_5_Uk z)y^eT;ZuUiNSI0S|A2!BfDXnFy~x0f`vP@LY|ZJfxo7&Z%Gol0CFp=enp?t6-PqqS zVSc~%Ke&Fw!devZi{pp8EqJ*kejpx_@hLNoG|Fz7u*0DeexZKDdStw1$1PtLFFOAK z3e&fqUhI2huqA)XhFTxL5I?k`JC;69KQZ@DG&K!RuKf~yMMjgu0sKO?3#0gr6ZGT$ z8{BAqaiM>HQFkxa%f~OMo@jTsjW&LPew;%1dUWx%=8+NDAE^iGH}+8jh5LbD!-R3! z`t5X&rW8L=zwx+KX!U>4-)8LTsu^*Wxe-rpS%6>rE!z&8FsH+s?N-^ssgs(rEdl&G zBll#ZqmAq3i((I4U_B1QGn5J9SDxk_RG}Qgj+!$%sYWg?81vd+2{6qve$nYHThU8k zJn2S9;TM>~D(GndzYa*HDbwH}F^^vqD>{7qYN98BU#NFEMIWJNZi5;IsaT1RUj}Gb zgR=!;LlgP0H7iv81_G^^v7&x?@xwiYSqi?WS1yrxEx z)QrF_~BlPJI$5~ zbs}`;#XQmH+k^QpgyoAvCfzZoYJb6F_i9&C+~;f^PcQm&Kiq>aQ_i^;*aR);N=3JW zf7#r|tKayZqi3{fS_;_05`a8XR}X}vFPQTNoa6}~zl^y2 zDk!;`6*F=(#US*|Sg7CFsql-x3LNcbVhQGzi?fTAzqhLhMvYMyQFQf4j_ zW~%2U`UkqsH3w*lmQf3Z9Z}S;xVfAT%kG)P`VSwYX}Q9V^l2|z|JR6$C>|~0*Dir@ z&2%(-$t3-Vmb<{OX$#QrUr@t=a$-K%ij5r_lznf;2X*S}(5OP~|8#Mw%m=^A23dq1Lp7U#6G; zigF5x^Y{^tv&|WQ$!p=lZsEi6!*ldk+-Fr9#IVKw{Y`GPpv_dKxDE1Ox4n_MX&`~L zSI=x_Z&S??{ZE}2^d9SamLlUpuI^zuD}`Qr6n}A#+50 zOAb5nWN1PC;oX3(_?g(js*&77c4&_N#@;wsmDe_u^o#RfKcP;ihIC2a9YA=vw(4Q= ztX7|H4e~GNJU!(`@6ta*KTfW6s|WP2;E77M2Jq`yEce>n>IB_FwG_#&PAozqOv45U z;MYd2!Ho~VSKp{z@5T$FlM`Vw;`1-ge{GZx<;|~zx@e=@m`BX>D%v>IlKs#E{2C@i zi916rnc#r(=KQ^-w%?l)6X%F~GlymR~`D z)5ResJaLfa4Dv5Jl5J1be0>;n07Ojjf+I4S0+5yQ%N#tkbHJ>-?8C<3;Lh9nwudTd z(2cDHNcs3>h)quHwoqp18t2<_yWgyp>zqyf%BuVLRS6%GvqC+F65pnk(8q`fqg@D)R3OO$OSX~ICkgACSh+-<HBCpXcBcmYseJ8|?VpTfv?l#! zYG0SgXcyFP{1alHf^oSm6P-3s(?JM}{rZiaG+EJYwz+yv%sP85;8)U_sB0IPpEX4s ztoTj(4mD@ie@h^-XvFsSJuKqlt8xb;+ELF}k5~Lw|M0}a5RRQ?OOlOE>o+>au}sJ4xV+xRGW`in8r{8EcOSpFegjauzxGW7fmjY3 zHeu#lUyBFvivYC~=<1k}k?ZWslcF~}WPn@M2l?0j=AC#CFcAbs8_5=LN*snA{ff;ppZ>ahWH^Khl4``6=fvOe2 zWdwR0vr`1}Uyo!G`83Kl=pNaSt@^UKs^{+Q4eOdW+;4hyjEr9e>U1Lw;9rL*=~O2X zP;&coy@_PF*3&Pp-#}f88=Y#LGtXH!$(n&icuiJ!@2!FOA?i2e9yglPJRh=p1=j0% zV~>l(ZlHbxZlMeBbc#l(fmnAC#AuN5fu2D9#zC;H%TczWJt{xXVZ%>p=zPJPgYi@! zRlnhISOXfDg<7piiWV_^%+8y3D3Jd;XSGXsdJ_gzhJ`QF^OtsH6E82Q-=I!-=Bo?z zApHha$VM)@?y_%PfM0AXBTNU5fPd9IpikR}cC-(GcbD;t4)he$I#`R_RDS2%PCOM4 z;8zo=)DQTVb1(g7e+W4sv8i_R4RjSiNj(C#d)v#_?2R|#b}j>0lA54 zB+S02mS?mVxc&PVe99W@2>CuWVpYKU(>J>UCfDQ>AzE}Ta5wA=SDjy zlGLBkQasV6{MRR>a1E#xnJ(A&QY?*~c|rZWX|*3W{u)%Vs$YydgR~RLJM>wt7}w7u zZQ)dba%%Td+bVNPjMJw2m=nKmLH%J$&GR({ubjZ#}5hR<@w0m z;&b$GgG=+(oSQ&mh2Im%e*uXYl72`d4)hE8FZnNjc)bL|7IRXneuLwp1K5YaFRJPj zC$)|AhxeF;AwU1ZuaS~(Ui02 zM0HMom!9ptQ6`=Y)^D7)!M}1)8N{Om+`?IU%f57|?STM(VIL|_7<{?@CW=n!Cy{UJ z$lW;=rV@VLNxNOd$8zF1P=DBGkR$86ZY*nFz99c4*>uNd%u&&-+7Lit5PQ}3)`IId zP+7!lI*v6(xW*Ebl{?5D1TqSZhpy@mi)HgJ&CrcZyH3&(ZRsHNi%R%4Pd_KvL*SRe zIXf2ki3AawsT|b@X;JwE82|1waQk`M0*0l$n^+uUBt ze+BC2C#{@RRFUX@LV^$HzclZ=yz^h2>6^9o+pUMf$(|;AiwT8&Fo<8OJ^^b1Aj6^* z^f)Wpbagt&ztnK%7oYb?aY27&}YuGbp*8_0=EyL!q z`}OnakK)4N0>-sPL$ojx#4n^Ec`Z;vW2;5co$ORXhV1};8LAfI%i<+^QmUZbWnecg zP2o8>R1SZafBtJJ@at{LA=$b*0wwCSq6_d#jq9z|r|6fZ^}@IalQ318;`ea<;X6E> z?U)u-KfhZ?T_q*uy;A=pQuFN9AMS7w&8RmXg%b$HKLMe^NDnNm-?%0p{*3UFci}%n z=l99RY}LFN@bnA#W$iVZTx>sK>>aV)Ej$T(rET|d9i!4O@BA0sjM4Dr_Bpd1#!5fq z9;95ZIxAwy={5g02{^9xTyL=FA z0e%7FcxO(V@6sM;+c%Im=ZZuOu+m$v5`Ntxdk{a=VmMw`YvX`qOhaTlP`|-t8(52R zHV#g>F2tjNkckOTzkpv>F`7Ef@t;*&z$+yRYk5CcdTYV;hwLZt^djb|=J^^ru&Vt} zqnC!`0sKOnTQjTC*kEDtPmzl}ct?0a{f3IB%3+&Ss0s>!iE6KhewFiI99fd#nW4Dx z2n$)L%vbY`EcpCuEvgNnU!9={ht62hOd7Vc1qj9XVOG1sRQ2;4;D#yTE^%2Ca!LKz z*fXAg7^pui9t8VyoZEU%F3oS-P|klnY$)4e>9d}Y(`N;8)odJs_?5Xj4>!KcctHun zXJ8@!YC6cj9;ELtY8emr>z_#-?}q^WQU}3q3Gy$mtF9ONaFH5Q2f<``V953Ki}6cE z)kypnWgIp3XK0UgXFA+j=3fs(%~cQKTK7UI0FoYayK>_h^>r}R5yCmCDF{CQQaKlw zp^dmkF`NT=+-xJhfHo!lV*J8zD8^-nYFs2xYb3FzKL5JY>ocI%QhhGyyno;T=gRpn zc<*o&);ZfcBhcK>L9%(*$Du`e3NvdFW zvJT^W4Zr7Ej2$nu%J_AlxApe$jmYaUA4E6iX>e<++q|HDez%iIAtJqv9-_D#;&H)I zbgFWp0RQ^__Lfw52B^1Hq9}rE(Scv`1O|6*^gYwh{0Konxu|O46CcIIv1=z z1lw|=FY70OUn}z%*L)1St~XeJ_&kc0V0I+%i(~ls^*0IeIvL3Y`4?z~3$?1FBL6xG z0S8t3gZTB=>4wzhedzOp^1s!CBNJJ3LkL8gv4Hv4*QA|CZF2-ehNFnFTXG^% z0PnuvTX)8<7isVQ=r!T%oEPbOS)B!*KA-R2ANfxBF(1FgOi$N`qT}$0)Ovx`2rqu9 zeTtOsl+G{XbVHNEuLuL#Y3g*=mhp?$LBA4?xqWdjsiRLGHnlpTjE`RxMgEoPS!Sr( zj8YpgpfY|{?Zx(s7sPFJFFoX#9w;Q7(8BsdO{JA>F`*&9gFbUirY=ztZq@sFez^Wn z`G*#Kk|O_l)p}QSe=<51;5 z9uPkNswJFOPDM8?t`+|#p*uJTM&q(GADIvT5#EiDd1aPYP{Ov%65?zwOeM}qnO$Qz z2sY&Thg6|%Z)jROvACAFunlJL96g`u&L`${pMPcOQ4M8~DC?D6l3@;rlZbGl(D#dF z{*|Hcn=L){h03Ic`VFrQpII{l_46(qBWRpCg!-sHE|h|Pp*Wy$-HP)0FZ5aBn2e#f z2u>V8&1aE$?4Cl${Q5(6Y`G8hhd;65wC8zT_$}o61M$NG%zMW~q_DVCf_Ax)0_@Lo zvfE9d-mkZaUn$C2Di2Gx(s#Dc-*s9Kp}NK{<-ctBBr%R`15Z7hIZK_Yu2X^B;p&o$w*LkD+5Corp zy~N|nciyFUiXTW2)wysx0hieWDL4bX?ykCj19_0SHC>>Jji=1f+GbWXRe$K&x(VQy z;=)Tq5r@Z)6iJ+7O3A)d7=T&yt~oYd0c4)&;kDSGrR{U6CW1O+U?_sClDu@_!Pef zaY)sl6B@c<+Y>cE7oFmtoyL5mMH~ikW~V{~>Ng&ul#6QKZ3t`FbD)!BB0~v~$I4>; zVF7lID<48%7BvoPA@b(!;w6U&M`2f=*WmYJT&3Ll z1kR_ZN~dMwiXo+6{o;h!DDL2Ttz+KUC4EzHsU&*%O>{mxgJa9bXkJPD$ zTawKle#LQARxK|4sN#EoU&c|?=^<=5Y96I_8OiIXo#&H#_=#VCh-??(WGm?|giZqZ z=Ba=u3;35f;_-rOC4}|nH}q@BtLP}l4|_qWTAlC%v1`R9(V7~q2VX8$bolu%WU{zT z20vmU#5v6ars5#acs7&Ie<=uP-^^w6i8X*fa2XtAhWAzU51D^)Srq&qTTX~BvqtJR zG5<`tM9PC+)jd$k~0MsH;g@Nh<6ilz9dfxiTABzxXn7 zct`=+QDO0SnM;cJl?zV`!0{@za9F`Z(cC3P{^cP5g;P;B&VMa8Ul{66p^WVpbbhEi zfAwj7%Jb((7i|ZgB8!LfU(SftGGgAr{0kks+~;2wZRZ*x1CVqD`kZh>z_^sE@fheS z>eu?Z3AULSSBwazl0t@Xx8eW=tWCLoV;58g-bGf2AB7EBGot^5{>)MK@MoUQ%pm^- zTz1=RK+;+2bgOg2z^|-olcyAqU0SF3<_ZTTVR1I^tf%|Mq}JhXE9i%MZPf<#z3?|+ z{hFHuifSDAbq1j@o9$tcf3be$kU~;zGGZ5fquy&n{rn!&sKK}rd5ps3abbWE?xQS^ zYs}y#ByoOO=??Pvz~wH+<%i)3D?1jb-+&wMZVS|JaIuiG^Tk+q;QVqsA*sZ$1uT#_ z?{F5LmC`|VetAftRV&UID&ZUpuc7cJXC%2l%)gW$CDGO0hFXG2hrL|0L$rJP#rJQ3 zmhx;|Q=BN^I}uK@?uQZoO-L?s*RJR8pOL-Z#f-UT-`ol+f}=S6X=3&Hqd zu8=r|XyFfB>3HKJ6{t@l7^2pT?~mFiTloCfnc5<3G5>1IgVc0-HnWufirT}IFrJ+* z9|RLmLqH{bApfO&+9_xX3K6~GbbISHRhi;>=J+AT!8W-?h2jn`f@yK%aqMH=kQn?(@*+Q|3otMQ#2r#xJ#|#-(nBlstA^ z6u@Ke%LU_yZ?jL^pwG})1VR=94l<8I<8Ji6%Znd^CcC)NW!9--2w)&ncQq`CA1-GL z*@TU)%qd&`E+>%*3q$QOb^eQD&Xx>x=RnGf9|EKj4q}6)_+bTpL?3p;;2_$QXskF0 z0~s#sDDyA0!EGB;fPg0{>j1XKu_$PBX~{qI;)l!8RfNUnsh#_rXGBB(E6Bf~gKP%J zRlzxgSJ8P`iTi^5i_0mMsVu^lH?C-=@mf#6y!fF)s{+dNl#r()5&Nn)cCJ5slCE>Y z$l0Ou*;P2o$9?9AVyM>BFV25GNsT-%uDvXeJ%vfQ$6E_^e%b2}hXlQOR)_{}^&b2y zecDt2jREpVE#Oy*_Xgt^_NvKiN^_2aEze7d$YB2Kv3^x;__}@2ZuR&VGcq`?KL1)< z++#yyR)LW&_wiDB;Z|{Iai8(|Lx48!a~roY$mafV{19b_$*PEW1{sCY*hQ*_Y|>w~-^vv27$5SA6vD0En)3Y{Se@}2q!Q%me!opuzAf2UuHRsj zLJ?P$K&V6*>^$DHHm4V3Xexe)Z#Q$G$@^V(f0SpR*XP11&zF#}nU8~Upv^2DNGsU# z+Te-pt%Y}fxs~|31GrdCup2;1Z%u1^G##(-pIJ8YMFI>I{n!(@-l*7HVlGkdS?)gkM>EOFVWozUOGG!1=FN z;<-?>0sK0Iu@~z%XvxpWb=obI3&QVpAs{Sf&$()(QziU*z$xbJyd}Vq1JQT z=U@Lw&pMcm{X8u_UE@)St6e4>REFe`N3(fc6BRb4?ZhIJdd6(z?CkK8o)23uRy4Zl zLYaT{lI%;=gLb(f*9pQ}5Df{CN5B3srQJvy?*m$WrROCFwGgMmuZhd8zX2mdAaTN5 z(>{|BE$qZy7VweYae!Z>lXO!cm<#F;aax&b+||WvzK(}a@UC;O{`s(vU(@ugOajgI z=f%@9mrvB|-?2atCZL0U{l@mth-e_Bxu;0Q4;}G<^)34R@yqWj#}DtP5qXX6(XOF8 zlID7G8J@JvgjR^8r(b<_vp}m|lkuhExzunyc;!-YkIiv_aB@vK|0RwVmggb~{b%N8 zw>=vf)o+r|)G8qJ@vDHiEK#z^)=y(ja&H@o5J%C?F1c$1I8NWPIqY^Zc%<3|J ziA@%KzXxz_)N4-bCqcwGK8E^)%$gE@X*k;@{>f@HG=(vBlSbqrqg%IUpCps0bgIeu%5>tAe8sOGI{LnR-c7>rkigtmBW!bZ$ zbm0DtX&|)?IIfI9^)MWq#e;E3IB|}7Dm|@V^7n)?q~7p-jPKkg6Z?mX1GaLcE6ezG z#BT44*6L02ElT!9E@S>>C`MMsuh406kn1=810`WyH*e!&`_r=10SX7=hZ9xpwg>By zCu;a7<^&=U+XDDyihJ^na?5M?&(K$8+fLA)Ir!K$3}gZP8fMRYnV1yAoCr(yOq2qN zW&Dx|Ba8vI&VkE(p7HB#FOb-dAdkbk4E(Y=+!yAs;SVJ6YrX!Wi9q69^v`|#s(u)d z4fCE|JxhNs)E4DSe!5<~dUpxGP(R;}Yd3t@n#OT}WAtO$&4}j54y^82=noa(&JhC82aqv*Tddy$XJufaZwPlS^2mP zEb#G*`4@H+C8WA0ZV%(~o2p_#;g0GL^DlS~1Qed5b6JJU;P?{jRaoug*Td>Pk=?@y z0|m@33_b%r_)Y-766j9?e7APzx}Af~r$VYf>?19RAM(t{O`+5M6HR#xXVTmYf|*Xn zit$75{@%8{`Dfyr4la_)hc@*5n3&xJ@hgJ3D6_4_X3sHm+1S>kKI!n2L=e9)E_fF` zi%&UkSRWY&9KY)nd8LnE-u%GJH9#j-+!z}hS_ys{sGmnPgIf50o8xr7YvS%2j&J-3 zzF*+{*Q2s6hHAquZJYeV{AC*|aeq`=^||2b7xS;Z)Kb5R1Q9}}ZYbFUMmEUtaJ)z9 zg;&4PDI<3HIx*%vCR>?*@tr)0i{ghx{JNAXBx8XxdO`eR*ouIE*+)#3j+sTxwt6z= zeV50-TAlTo%SI|UQC8I!(gCe?6|gA~KP=WC0?2TO5`Kj9O~m{QUarG-gX4$0330Y5 zu@48C)%}ND6p`pR7sL-)t-!Wy!EQ1pocTp3c4j$#2&+z=&aGC*wDFc;^S&6>hH>26 zgX)M%wO9H6C^ZTT>&0~`7~njf>|vo4Kjiy+4MwYQN~FaN2qgCK6BS5YP=AO~^w%!a z?$)m3%dfc4wxjy&eHZxG0nzHD@2mY2#|tFFwiL1ZnKFKHpA(m&{PhT}0KH|S=eDy@ zjLE3_!=ej;t}0TD`#0KLzR}jqLQTk;DiJn0H zJZu72p=9;E`FnIJ+sqk@Z32V<|6;ZknHuhLo-=Ww85_@HBFybox~%R$6tHZ&VvXh* zCno!H;%D}EVW?pbOYuYGToj^ZM4}EhT;fNsBWC5bDd|@P9=P!rWK24V9=Jrjs@#Cls!x};ywpaH26GnGy; z7lNNYe(f?Ir=2d2Pe*`@4X}f&_)ABk^NDzc{uzq8>AGD(L{%W}` zWxtK>_a^S&uv69h^}D>a$X7TRg&j{vYBd^m>?w1(I4p-#_U%{{KYn-87U8wnS>0q&|;wpQuL?Z0V*oWwI0~ndlzYs07?AJ`L$mQfFn<|4B7eMCMZ)~UM zS9RPUnI8TK0v#$5_WC_XjpSe?UydKXLUVSP)i!bq$_^dAKdMB;+#r4-T9`up2JYXm z+fxxsX9KJ3d>Oy$5G~vQi(T2YDP{M?Gqn{X#X^oUehEYi@uN`F&6{XvZ#olVAZui_ z^6{$)kvD~C5aK%>(5^bVTZbX)FXz9&zfjT?$?7&u*n9ZeLmP!0?by*}{Nl68E1f9U zAF8k+xE}BVc0O0euSs=W0+Bbqe62$yn(#R+kri}>~TbnnPRsV#_|3a(3mle~@nM@C5D{-*eKM3E-DtMux6>;0rj0fG5?N)dBuBS&vfy?r_qbHz7zp ziNs2Wh>Qp0hd`^e8IS!YAucM-o%$c8H)W*1!^N;h(Lg@wL*SY(Rqa#e*R%tNVgO}+}`{Bc9b1{ zN#IIDt%1T09K{iPM{g)_{|3hxIdosit|P7vm<@9&3!{I3?)8x-O<$UQ;9|3 zUr#roX3B+7Lo#jmBL)({FU03rW%$aPb|;+ETkQ!q)>{*(Kb*k!>&kfm^mvkF4IG5OznB7Ky@}0RK`|ULr9Z&c=R1k8xV|ehOh+K7M8CtOct+f@yg+34GtBx6o0o{g`@>&GR!+5tI9+?V322OIuvj z2<1fU$d4#?41!<3(L=dB+Tg?%yU>Sl_kIFaJ)6h4eEwBSeE*?&3u@67e$BwS`)0Ob z0skUciJTkn*b<374FUGqWZcoN2=K2QowHUN(bf7CmI-dgKzM%We3MFq`S_KmF^Q-n z;}_#QOrNP9KVCmdnXKWNv_z+YA8zuX}Ix}Ua5^bq`O(Z-QGUd2JMtBCKs z0%!F3mrGK!sfvA)hX`?O!j*JGZmb?-_xV?vj>vOb8Chh=!jUZl!{LTZhyJ^sg z^~3)u;}_klwe{i*?=k?{PSlwr*}BPV6TmNAsp`c0Ll5BCm%S!zAqTBaGza+?C<61Z z)hh@EDkjH!;T?09dg>o zBMbQ#>kjY>M^_L?+#HIDboQZaT$b^R*%sZ1K1IsfJJuQfE7V*L_piCv>G z{Y^6VJAhLQAjuE`;|5fl9DPk_t#djT2jXP(^yIhhIni1}9dQvOVp9BxN%*z^@sphO<`(U#6}RjLXNb zcj%niEg}=c;FSaelGj&==TW~A#IF=RmT$E}Pm1sL?|^-dr{KzN1>uD~Ea6v$O$Zwf zVXrnpWdH#nVg~pZahno;5g}|SLrJXrPKt9I10G{D#RK@2DxnqpL)bBF8 zetGqW?9Y4l(8Wb)il+qd3-QBvM}cWFaZ;&zPJdUvV5>l4F@DJPhuzYi09qkzC|ljo zesNN6ld&-zWG)y<4-1$JqYYC07L(#C{4D^&qnKYBx+ZBSli5x=1 z&p-6)H*Cf)gbgWXE1_7wQH&qI3VBjPFtoiD}@z52t0K7KXvxCF+HTjwP3i_b6rK<+&S<}y{{U*J~B9ULv>{s5a&V!n?HebFBu zzaGRg?Qn~2;2WdQg4=BI@hgS+A^ysMr(b(0mIu&J!cEHZ*iU$N)r%hjWpb;z&+V_k zEu4ov?BKwQk6$YPU1Cqr67sd}I@?XCM!A%tK>mW7xn!MhLC#sMm?|qj<{_C-Z z7*`|kwNW4%wn(79McL<~e#wdiQ)$nJqs>Gp3x8e_u>gKWEYzix#>F8xCf9g^aTWE8 z>ksD;Elhah>T+wc;ZF1!{Q>6cMgE2Q4Q18Q=U*`G%0sv?e(1p#XqR$4>?kMMCuyk@ zTz3q#_ZA zL?BTDzorajpVj$gr}a3r$?s1BL~N%7!UplHFOd&lBYt3Wx*SU&4C%r``uOGl{Yu=w zVLu{Uvf&k>T6^Rh4eNkk6J`8*$Lt(K$b#|fD}3#|Ar9eIl^}i<$MwTTTqVZ|zPI#K z0w=1~;sO4}_=Qx$F0}-l6UV{5qlEi67UCDz zLa6!;4dY^4hs*O>2;vtH$7*b1P=KH}Ift|)TiSB`(AzeEBnUNZmanBvPVTTqBa+8mQ~){kNDw2{NkmY3aR=HC;X|Qy6oNY>%6-x7`nat=fS_wL!0I}_O1%) z8#)%=ALVtGA;2^5<$#;dzq}u9^V@u5_}VNS`}L72J(&NZR@86A3cxQ2BjP&z4Yi#T zKo-b6?Pcu70d0l&3-C)Jk>BSE`gbSUk9mHt z{MP{wws4;Vgtm+x;9qKsVofD{egdg!5EITG3#uRT^ebM0`{$`OixmIQBm{;n+=%EX z{uT1{g7aVS)d}W;|L#)4tA3sDGoLZ(-{h`{}N$k~oaFH+eY9M~d_4Bwt z3iXF_C7=I-zRP45h}JCBng;IQD4F;08&d7wWC_1Geu(>svbgQAXc*`8Zcc<{69N9k z`gOgtMg4sT?+;nlLBFmafqn(>>j^^G5U}MbBga67@C0pq{>A#$#36z)dv7{1g|SD_ zrYVcD2jYkD=lQP#ykehCE2@})ezosseJ}ZJJyLX@pSs#cLXfAF4a^*_S9nEyjho6~^WBFNI&8-6+DA0$&MxSghZm z!>jZG=cM&vqxz5%eglHWPyTPC+Fh#FoeuX_d{O(1^SjoP@qj?;iMv!`B}t(nu5H(v z#?VEAw7vI8(o%FgaRT2LD)`Co;7PH~;l7Hyw9m-jwU`xJWv-Wg5OPq#1IRZS@(YHivK4KPiu= zuCK55gd12`G^n1GzU%PK6<-|uOzL;*mplXE3ME{!6i+@@kG<;6&qr_8zbH?pZm6$% zrYKZAL*A1s-9@D~!S{GCtXnE0{6cq;r(Yy4QmY|tV8mpNlh||WQ>on{Z%VK8d8Eh2*CrOL{ct&~0|FSwW?7=~};gTXIRH zVs$`}x7ka~3a8j-LWM9{N_|;?qM>FOipEb$O+MNqNJ`r_O~FFeM#Yt&L21WKv-DjU zdrD(#vqTon4)m+^q&Tj_j((wjv9X#^8dv%p2mvxhkh^lJ6o4Ll;88w{zbPLpVpQ*zOag) zd=yVg-(@!Rn223_i{C%A#J;<)_~hG(Q@3{R@Z(yovnvlmTVB)FwE@B1D`>f*;N!Lg6aMImMRZJLcWgSFY- z(M1;vrMI{dQl=}Zt-VNaissNIVmS73xhyyul#)ND>#L2YEzqB`;I}bS@GfqqMe<_7 zYh!7SNYQq>ma61M!jSqZaz6T=xa=Wy(e^rMdND5hPt=PXbTA1tR{{461y?mu-{r&T zg@W{KucN&uE_)t|^xo62^_1cGqW6@(%Q5=3I{GLrx>)G(zN?QaX_d56M!j~i;Jt?W zfN>Y%vj3#m#sQu#z-1qxAvi@$(QY;vjz3nv=$VTIx7cUxX7NS&VCuub<%@)3oBoe3 zz;_?$l`vME!}rAHh5F@S?03leRAs$(&qadt`a>U085IA1t^7qoaSrQH_1=E$Pqiv(GmL(O40E}Iik1ZeMxdXb~`F&r}rD_mY6$kKN? zz5R>ofWnL3Lny6Rz!wXy`B1<|x)7IrfQI0G73{_*^xt-lPhG#P`eMN;jjQh>2=GC{ zExw2tj%!P}yg*o0YVv{N@u-|A^5QIuELKSEOrJb1N2|X;t8qBSDQfjjBJ(C`ofy2_5 z@IwD1d6RW4*jp-|jwjyd{dSSFsIrWuoUPQr+m%0NaW8i)*woje z9uqzA+u-OMYLT60DffJoFL-w0|6cmYBj1!4KD^-nZLKNnZw&Rb?(^r*yDVKSsGq<0kGjwQmG@h} zvQ6>L|DUv3pv%5eE5Yv%E!5?bLn#qID7W#q77Jyi<^nGN^WN_vexd&CeJblGq7feRO_u>ZvWF8|5J!hhK|e#hQdKv}=W3!J2$kH2rDU;p6OGw|yf z`1K6@dIo+y1HYbuU(dk*k7q#nOK_OrFFEfy4LZ4Q#PnlF@7d-*@er@kDMHD}f1>TL zY9cgeNY<5OS--07ulgDK!|(ZD?hpMJn;+GmH~9g*=mXe4AJn)$sQrWYxR{^+ zWxe>I_Rj}3KmR4)^8xIiU)!HwWetg!{R6SjAJqO~v-)4j{(MmL^Fi4k^yk<3^((gY t|IGeLs$#weS0+hnc(tA+r|MUHh5w^s`-&uG`S-Z$0RKHyPD>SA{=f6eg$V!v literal 42175 zcmeIbeRx#YbuYZmK1cFlX2cvM;i?HCM32EJS_=pYuJYYct#7ow$ZKA#X*YNr4FMs@Zk|Z@Ex+$rp_`haSvo(_43zFpWpUMAzMw0Nn{AVpm4)sy% zC#l}z$2a&GQhib1cZ2Wwu_5t)L_+=l4gSxO>Wg=6LtdNu8@xh2Hr}f?>TTER9g~El z9K|Wb17Kl3g`_TNq4+~$& z_av-?M%&TeeWG9_xlN|#G##Xb8%~NqAj(sM(1iWNq`y#zfU2Zh5a~lXbJwb0~yWB`lA2n2e3fhx&jk?`vQJ?gLf?lMn)J@S*eS*|` z9P5$td-#PP%xz29Z<4D)=U{!KBUtD zn%@|N@UgYI^q5>w2yYTE`$BpyeM>eM!W+bh_nuxeLO-ESH=5K>DZJlrP!~m|?hD)XqTLzk7ExC}CCrQ%xVfGd?O#cxz!A2JNSWgRh1?p-(i@x2V~P_laZ5jL_k_sy@%(zSs_g~%rTHNj2D{J<2O5G{r;dIlt~AFEAq8)v#b)NiL3 zCEhckyWV>3o2FlVu}0?~MKhs4uX*!KG))IXjr0KRcH{kN*VC`m6#Y6HCQ+m9GVMll zNqWRv_kFOLo;_4HQyIqj^0{2B5IL;-za?p^O&HUEOjn)mQP{eIr(c@oo65juzNB~B z?_>|on_1M|l}R4^fU&V;mf7~gP;U=?NFJ6kf_*MH7PpZ#Q`;od^XLiFJ{Ce7Z!JuU zOtG0H49a8BSW{oW$lO?MpP^p~=vR_v=5^Q8uiOWw_Sx0X(xd@9U)0BI)t+bknv{#| z=!kxquE{6^S(ovmY%i=WHuTr4HXeS(D)1{KVw90>_O^F~?adG4*W+YM*aX+>d_I&A z1C)^AWY4{xeldO>abgbkGv>!^8xG4_o3>J0Z#Z9{^w!-0eoZ(X^-<`ujfETEmeURE z6m=D_7JX&>`WfTb75yECtwQt@4HNW^(QQZjS5)BFTTWLN>iG)2ZDQT`=s%zdyDJ?% zpl3b(V*FC}Q1!=cyAa+fUZW>c=+A`cupC}5#xG^-YylhI2Y|N3DG8)@!i&Y>l77vl zN9BTCc%3-Ipim5NsQ)e<8o-k!!t~a38h%ABeZ;;*ofJ(DKE%HS-2r}0G77sM9J|q1 z^eYYqI2OGG%uR6{#xG^(b2>Kd#z<}^H3;gVj#MNMJyq+)`1L3)kl{Wt%0ds+Y7X5` z&C>j%`ZJ#WnSx*KyF(+Q!+u15*f#$}RNxnTAW$o;X>Vf0Tr46q*c*4vWX}}*x=G=e z)0LUISC7+cv{b_1sKBpaTmUjF>V_|gPdMMO+JW8P{;9&Rx8(shn*Cy{`6hKZ(XTY5 zjU`i0ZPf3RWyg13@%IbGs7r*8+klAL2;77S)rZ;wlUn1db zvtq;M5lV5N7t@2lT&!}>b@A(Wo%d%$i^YSD|H_SPz5SD$UFs_P0Cqo9fHV1AON-CM%1nhN}S)NILZ%ZYs+ zkbUjC_;r9>Gav$?l_4`{3>*fMxWOIUH-&L?yY-7 zkK3oRu|x3du8Utz*O0#)hti&&~`&hI%IBCCQF3LqxdKU~njA!xs_?4P(hw?Go zJWNYz8&Ump0StY{g(>Pq+pEP(s% zz+5D(x9PJWEGw>$U&|P_iooHI5_n1lewF!G8p9dUJLvQS-Ocbfik^N==U<0Kg0{&v z*F1b<{*@CH%GGWpVD5!7epU0Y?92rH4dFcj|6=^|{0+9x1l$?YZ@{8~?g2H0p) z+>n2bi}EgYnDLFOPrS?$$9sRr8aD z-}0Q+GR}C>e{g8UHDfv^flT- zZT)6eOy^%d87Yd}#Dmm63XV2~e{HjbPijW3om4{$9K~f=1uO9@AR1t##xhFC8}l#N z`5ZdGYHbz&dWSL2#{w3v0KdAONLIfw|AL9jV4mNNe_7(RF+dx=J}bYaX&V1}2m{;# zUkme7;$I5Cs{1pB{&aDFO8krQtE$ht^fBQ-xgr0OdOCxMK2wo#4D>S@N2ukY^;js zd&X#s5xdvSQ!6td3TJx!_#xxhb6Hrwygp_=M@v$Pe9L+Z>*Yjq%@z3dHg%_>MQu_% zwFl$s2W(Bs&q?5NnSaT*t&Wv5_v??aophux?5H zL-gptg7sDLL;I4IbY~{@?evqrPNy#U3mLPhe@1S$V8hji`PVzf=desLaR`t)(c&+B znuX=j@hbc>y4||G{wjf%N;p&}=%`HE5xHmze*KsJo6i$qONKu!&LMUI|F85p3Kk-mss_wBH*(SBYN-6Ny#f0Ke+fXU*Gy zUo+N~^h@zCyDNjP0&_J4KhrG0K7X((eu(HUL(73kislSCI>dz-1rWO%G=e5Vo1;@gvbiltx*g{&^ho|WwEuIS{>z~c!-MAfYN(cN) z#pjdg^Hp(9CUc+9t++s&WLGkpDdU$~oe`+sMH(OIa%R{K7p*^~rN`Fh8&aNq)~pFw zl8-HiZJFc{oCIvmp%+aC1>ISxZ1{k&-Z^Zw$r(eihgdk!3d&(a&O|_fD)39WB3W@! zJ7TpF<*-*XqK)({1^7jZZO!1A)qZ?s=6W6xz%O^3eODEJEp-(xvs%I6!w+Y@$mx#W z#|AO?0nbX*x#;s1>V~a@-FT8CRHK#nHO$M@3rliUf?%JZU8uy)yq2TWF6H&!;b9VI=ou}?}^fZQZ^;Bm8tW z88yH%egU>RjEEd;wqfUcB45{AM^xM<;9uuzz=h4+X#B8fi>2MR38V>brLAsER`aiX z&Q6-95JuWfB+XqSL|gC9NsP#~)+ zJCYoXILFLRxjjE#s}ufxBP_TsRii$LO)JC$K9R^r$1GHhiK&N@X)+=Sv^o`>e+ z*9hW=n?;=q|8NdHkWyidyck0M3s3y~m!zlZ8xpX!3AF10_nu;ih0ST??5gr#yz9cr zP$ZOwqlhFb@8=w^X&Jxh)xxqpYYTc4ou);HX6E#`IOTLm?8A!q;e!BZ{2e6UMzkJ`< zvRhWhmcvj7_+@}`?CCQff(~w>*h&*|Hsf#K_hB~X0sm^nSGEJTHB5u^?N#Pz{Z5Xr zI3SD+EQ!yJ;B@B)2|Ib)FjI?Mae+0mz;W&LuZ_1jebi~C%KU)aV9 zza;#qQT?p(FLXO&Tor!BB-mC#WT>4?*;9Z`K>Sda@T<3m@oTqZt`l$2{TiSaowvR~ ztzMs%UNHZ9%4%`U@1PARC(|x~9U)?mv3tI{iXYyabRs)jj)Qi!Id$Mx=J&k*`1rL! z+skOx6V0~3Fy=bfM|ZA(Agb{zN0X^;0)8cFvS|@3noZ|y6=*Hv7aefga{K-+6gMB2 zv3z_?EOkCl(60*o`W24GpEZ|?new2Un=qG%b{ZV8k7AEi#19b$CwNw~plG|L`5Dm^ z+w3TIQ^CIwEo3`ZPgmsr^^uA2T;#3xb4IKJzb2^Dg~nY(4*E$eTEODI#x^rwjvu}S z*0#ud&*}6cJ24S{8t++DfIST2hr8$jr}<2#UwnWz_ul51j#x%JX!kJmE5NT^*ikL6 zSxkQhUo}g!fS4!t7;9w(eo51AGO?9yDO<og%(;^4{Ovae1Me(3o~mHbQNtSd&b%)I6zF8Yi568lAQ&m2lJnFI4aNk3x&on^1d z#gp+`wdcM3SGOHO{>!)~+fOBmt2^mM-jEa6nW~K+KSZ=J#`PN?Dw;nN%bd+lES^cC z;33I<=KL4DCWrA$W6o$MAByZ9Y>lVPq=@UBa-W=fjA{p5qwhWv5?B~B^c)R$q{iELYe+UODKA@?RN+UtY}#x;j^Gmfy@nNW%ZX zhwC?#Cmeys9W;1NIsYZ%XRw0x-ns|%8((kn;)jT1$Bk3;v0NgjFZF(l>o>6LXsz2) z#9r;BI)H*Pq20__FfD#KsGLbBkqx)fCF+2n3-7mr{MVm@3m-As*gm%!N1#m*a^?CB zpK(m$tF}IX6mxuxeV3^9)`IIdn7M506P*7_tTOAsP&r#HG(3|tSIbl@7uhLhHUrb>lUj8eVii}p{7uXi?3$%;z z3mXD*GR0aWk2JQMi2jen;P4@C8#$2VRz%NbZb2<0-)J=?Eu~rKp&ht~k zFVt_K8+W0HrT#RunkTi6doj=Bo?cYfZz?#t!}tO%yGYHHJ`q9T}i)6^&8<$*il#HvQ+f5gLCQI`wosLCiIY}UqStb zWZi)ixZ_aEMdO;?_0r7I5`H-~T*kI&EPArx4f?ZzZu_P;Te{_oI~Nt!jJH^xeyRG6 zrsm_}`_ku90M_9xe;DeN-&hDo(Gl~#Jx}y7Jwsn}SNGR?#5tU-pEEK@zdamEp*J>< zJ_Y?k+N%Jjd6Eto2{{A$Wqg%d$3t1sVABT>o*XyawEk-xcbz6{DZ}CCu~cH8+l8omCA-A8m)3$ zrqsVqKg_n-e+iyq0Hj=iukGi*G;RY^AjL%o$rl-B8?M^y1rby0h58LZz(zI~l5zkA zj2#h0VIMU~2v5IC^&2qnSPRkRhKmiI)-^ilMo1^2-V@YsxRj@h;)4{0Jv3ks-KeXN z-_*}@=+<1ePRm89$jAz$y(9w}jLfhX0S@wC$3$izmg>#adu1CV8SyG*WF`N~)VRp6 z!vYXiM{=l>VDzL=m|Nywv_Q4|q>~W-JuiIwEfLN4h3Wvln z*GIYVC4&6d?at zs`6i4m$J5>mkB{aUN7sKrG(Mi6tCC5ngWLn9hi&L*!5kxhzuv`AFvNGu8R2KW@Ew8 zaDUHvLYlxu;H63Bmtg@a>JK^F#a$%`MZi{6Y?i9e<@yaVXeEw@Zx^SnK`k*6Pl~97 zXT@U=_}5{2fjVV$On;kBWV*A+3%{RU&K;0b_!q$~lzJgGAr%oTAfBO~RN&XiTt|N- ztAB_fIMIi7)Wu0v=MeC(m9+!zp8gFDq1xIlyZ3;0y|2|6Fsk_%JR&F7!_Y=B-FJg} zBALAOclwj$L=^yc=ihr3IY|}VsS0k5g#0w#t@rw~Hz^}7nv+-3I z{Oc?N*k6S!f&qRRxU4v%(&eVvhd{epQs$-D73)D8!nsjXU78m^<#RwPqE00&f5~g!}>+Z&OgQ#;8&4e6v*N+{9U6(ZnS{CI>|z@#J>iN z-=j=(TYY?}zS#!=~vwHA%OXp zt)YYucGa^R0smSLwE|CpS}Fb&l`W{;qXXRMfPYPdK)c*%zkVM4tJ~c++Av8!rS7BX za|Qo;hheLTvW?F`z=nKBA`n!FjOs~E=>_wzBeE^k>-D+q6%^9HGqg{OU4Tz(dsx8y z3;rRQ$$2LFoS?t7#q$6%+wDz0uxD11ZGx&lwAxbe-doKl?6#BPY|lm7$M}A@Ctt!Z zuCME~6G^z=(47>57#Hc=BL@nJUE8u%{L8^8lrND(9AMIz`~nDzt8bzd{}$KJ!_Oql zMk2+2FNBM9y061sbEt}c$+jL0ry2g?JPC6#N#_RUyJoJwl7BTNV&R2p2gVCTjIds^ z5IbsSX_Mz~F#qy%N&nUPmb@jkdQ<(&^rh^rh2C?b*IQG?zo^p+FADcMm#K3o+>HJ_ zH>+c0jTOF2aF-STdPe}4@6!+UzC#~!qNBg`PU>3Y=bZLFJzK&rwuf!@jC}K}v`x%) zVNx#27lB`q{E7tmu+wme&`$2d^FxK9`fdy`PcoKcCUWJ2eKFBp!{&b zToS^bT>#c&nXMFPrLPT z@q+buZsY6vistS9f*SoN#Uj77SG4mx@_6VBI|kK*Gp^<+m#N7pgTl z8U{*b%wu89`erKT0IlpY|JtH)8-qDleqKcj>x*3Or7;mR_6^w7D=X^{pYpn@IHLpD z8m0j==k!{&!qZa~Ka`*B4TFDyh|O2?L*L{eYPPce@RGcp8KUYB_ZjnScBB%!K%AAn z$F;p`33g=le}k};eF-$))srkiw$6j2t{#POHK9~>qSB*`NTS$%N>Pu~E zFCxBy^+FqOEleywV?o@CkxF}kf1Rc;(0upSd`Z6u`sIb!!u*~t_eEZdH-V>X5NFf- zc>k30U)Wq{QY5j}W`2fGJ(7(r@LD*35-1G0W=vd_Pz~bEG6#jLgFEf1mLUT(` zirdZ=RWdfhrR7FOhTXP@K|h=zwT-;Y*bG*Q~!?xsB$bQsp5O z0#l4jRb}Zptqf_ zLiCT{|C%*veU1kh@UQz3Ej%Hda=E|e(XUtbYJvf2J{ zuQ*0SL(O*F4870TE~oG>8a!&dK(vVQ#V^DP=6*5Ll=ap8>zi~+cI;~ZyYLUwr*P~m z@kn^SJSD67*D<;>r(3+}J~wJ#G1ajz1QP9~z%RW5zkZlovZ2k=zn*5EVq^#B8E__@ z=+27#7i~$$Qmb}~d1A}*Jx)CPzIk*crx2}B#;?Dn4?CfATR}!71k}$vM;hBWM;7G2 zjNJY4=2i3W+S+*F{`jq{LU$c&%&F*HW&TT!+mD+w(|S&xvX`=ul$&TS_c`ESSD3JX;SX(*&W$`{lOvY}?z+YuS?aWI4 zbppNw;u}p^N^nLeZh@z4p;iX6V`co>q5-WQ5+9;%ZY*W)3eB6wzg~s)>-bb6tKUK= zosPRAH|wq9q=Wu&{IG;y={N1CQ_*aghx7DuHNZD5HPV28VfP|!k&q2`dc;Pea7ees zNUvJcApaFNwraLCKPi6EdSFIO&M$;a9Abz`IPIrO__YQmF2`OI6vTlmi)1Sey3nsB zW&Xw0>Gm-onpdX2^-~!84u`o+dc1^RGwE5dt;8nKrDx^-iO7=hT;tnAAFbkF3|n39 z-%G3)gwg1ugBR&CBU%Ojx=Nhws(W*F7lehy#KhJv6of3Q;$IIto2}c9#aHO-dNw2N zW!{&blYMNF;#NK_R*ls+9*^rC%c@{Q6sZF4u9X?$EXc_H)jnVq`*Vr=MV=fK~zjdO`lg#wZQ|<9@QY zb0m6T1qi0ybrcI1@UKaFUM5qCqW%#AJvj>DX864ybL%eYa%GbHgY#d4J-t;Vn(d6- z<7V<=FCp8-Kvs$$)+A_)y{FgA_rQ2I#@tX6Z8E?nw8@q5E26fjNeB{STqyVIF|f*N zT&4IS>JL>o0{aI<3^3Xc!g7k1x^;P7mhg+C8QsoW;1`I6GJ{t*^5(9s;$NtrPeqFQ zRroEST@!j2A%mI2lj{6e%6y8D{~DU#j6x0$B!2kI=48EH!Y{;f3EV0vSb)(>)@Gnz z_5<)GVxE4f^UIJaRz4*#EZC5s4hsZD%Bzlz8)~Ve@*a^UJbr zJaidu#uG;D6*JRQ=WKIZB!X!Hej&cmmwKEK>v2>mf) zagWIsoLdr~qV3t{+{mAZ5zFDpchXgfx|GW+Mr%{t#?ODb(ZlMvL>K3hu?{+Yz6S517fGs{B{?S8-}%gY}ltb$Edt4%w&rkY~(=EAn6LqOX;Ds&PU&?F~qp zFuSS3uK)|)tYQ4ZxK2{16UkQM7xFuIg?H}xfxTa|m)B**E%ZI7ZMm84slYFl1Ipe! zW*wnVGJf4g4>|}|f1v`uP!{{g@v_ zgh(&r7d^fTXq8Kkn~ziCNS&>3uwJ6Jf%u*Z{Gz;*BZM_TMu-a$@j>(n2BZ?do{@|W z^UiCJia&5?^n-|fi4x3r0{ogwhh%dqyiWhF^@dc195>T(xokX9Rlfn)lF^)|am#wRE*(<6b+e?&@CyrQ*Vp`TZdV)&*|- zzRLU;RBt8F>a2q{E>dHSSg&?B-XDTZ=TX{Tei`)=LKPx5g>Dz9PV~ke@UKUh{^z4| z#W?h<)5fvokT{h?CM&D^Tu8gRk8|0f55sMru#}8Hh%SM{=f`NFi+e`Yrlos;g>pHKF-I!aAwJzBTKGYv4nA)obFyfNJB;&T$(V&+myN|22OgloJWtBdT{5 zJ#3=cr@=1}4a?~!U<+_#Lr`^<7?;Q2QNLkcd#HPCM^WV+KH}7kwy1)09#_D>azJy` z?HtlEEfOz0fb(Dedq({}Yn+C&fgr-J&5Xu$a|nScpEzIka0m4p@S}1LTqCHJW7}{l zYT-*HTv&CVe-&Vf>tsvH92avln`KJ@__dV$pxlVZ3wlk&PqCFE%{m_!O(Ghn8}_r* z=|&fdGqpU0z^^RI*p|`El)g#60XUAP^m72R&tY6EMsG@S8^$lThgjut9J5+1BXJOL z_A0Rx{MbD>RV44dC0=^^NQyNy!GtF%LYs1WD+L;n^L z*PEYS#5Xt;Y^H?k$XPMN)C4&k7TZ*k@!h zcIIEerYnwzXl4B3u;Bvd);^ve+3d_`p~SyxczS~RjXJ3p;2(lkH~&iu~9248>(mcx{$Y0kCCL9AQJa zvN0R@WkX;@E9Jj>Yli8Fv{P|Qa5xl1EGrDeWR#USQ^K!ra3lv`rM-|T$^cr?Sn<<8N5AmdBEQERh0&IC;hc+*HZQ_(uD+n~_ z`RO8r4gEkX&VTuBYT|6ZWIQKEY9FBXX0uQ_zs&WA>f_aK!1}R|gabIzv_fsAJ$A~| zo!qQB?1qg1tNjA+XC%evd$OtD-xKN(FOSoK+*m$_;@hxrLTtiN8;_aAxt$E)Aya%biTFWM7*h~Z}%#%$jv6ez`Gm)4}l zl@Aew;9%#wWdb=Dc@3vQU^9=dv{f5p<1Ap43x2V2W~OzitjlAwJ)x;UVi~`TCk#fb zj??D0mbRfS*}LHU<8Og~6{wHjQ#!v4FLwGvEA6n(uDSi$`$wE%r*hf`6fGp0&x+$vBB}N(?Xp+<}n96ZM{g zmM7$i(ormd#RYp&#${FcP;9BdueT&3_Fo9Mx+C_1NJPSaevXm=`ZE8rVH1#6=CY{4 zOq`V{L8w0*HJ?hq;rSAU8iy?#{;~+ufMatqC<6RKY;$o5zih3Z9?dRTA6_SJb{>$o zwwfccdgf>a@VKkqdlFX9pPUSMdul6AI8?Y z>Y#puh0)p+&*8qB0=^>1}i|x+$jEsF0lMvKz@cEPu znSh%iP6_xMIk*t;94JwRUz7BVyxv_6!Y^9&VM;T^AkRP&0_a}^($-`sCsj@t3V=zNVcII zKQw;iRm+bF!12oH7hqeIkOzLL{loQ#3|nhuc;OJUbIcEq;(#5=l=+uQTkZDD>YTno zq}}G+0vmAi5`A-@`PaZN2isZIAEsquT{t)>hlkhX;N3+gvIiPN~@KGA0l zt!%LX3X}3n$y}wAZ~gW&FbVlxc_^uGq<^M8DLD4N ze#x2y9ky}uH?b8w-~?J?|naoBHG{3dN-688!o!V3xi9Kraey#eOqw{h?CvPGaA4{g7Y0Abf1M$9{%b_P-Qe>M z;LDvRvM>~_h#$U2s5a#DU-L>r8*czR{L{4UjXhH{4ya{%0{ntNri~aij{?Q6LHuw# zWh}hsp)`tEnq#iH4?OO$)0PHy`|(4X4J|NXB{FaeM zx=3n6dagZ`X|{m{Bc7i2nx+K*a!`#h?4W)_Mw=TVLScSo{UJOeX2&Z$$0O>lIB!o{ z-9yphO%?bBG%tYWBuW$pv2J+O(F5U%_#wjb(C+#U*-6roLJsvLz@cRXND~Z<~&qe=@tBo&woX~qQ5Fpf4Cv?6&;q= zR&{a0+hbfmzojR3&$fqSCqe^TbN%~viR0-llI!bGuxIg_^8Ha;-WPMW?NmG^=3tq| z7~{~UTtAOCWT(Owm%rjGsMT0*Aa1X!zCUUND6F~)L9%^LBhh2xAahW^aaR14o^qmn za0@w5kL`EGcqjghgF<@0{%}{#m;he5z%PUr71-T$vwYs;I~DOmW?QRszFkG`s+mxr z%ls?2Kk8*r=>-mK_*oNc>V!u{4e$$yRuMmZ6tLyro%NL6o(i86t&C`VQoAC4i2n2f zVF5`w9P-*3YDGqjFNq45>o*WVU`E!$bzj{TzrhKh}xZ8e!z`s6KfnU}Yxd8Qt@WYis`>lqX#R<8r5dF+x zfL}RiO4re~fGvXs1m)OU{w&8X0{*4^c^m$`FRar$w5!?fG4QW){Lp#K!LR=h@h|jP zY{6*Q0e-!~{pl~o4=r$GoK`*&{&Wnqi;r3t!5JUbR2x7SkDd8f-hqWQ*$|isdv!vX zi1pyeSzegloowN>Jb-F~fR*%!+J{&49mg_fOrMG*L&O5}gCA-c8>dT_4CGhR5i49td`p>V|&7B8wu}DPwCf5_tyOb=(Dni;3-NNZ7I%zqQOFz@r%=53ps39 zFO=Vci#X_tRD8MU`G?;5FR-M;D}LWXAhA%VF7ma#_@Ot?Tz`oB4+;2XDqmgsQ8+N= z!q#0V@vleFhDTbz9xfKnwdDm8YEp5}qUTFEvtf-TMv>dbRXHBN;6>rJ29h?tSzP+03NoWqR5Z0{n^)-%c5^!hGy2@8a0k zFems}sK|c-tz3i+%k?%GAS&D{_!q|yF|H)sct0HadPxZQ7sn5qDei=t1c&9JRw{_W z!WnO#Isf&f{A#fYj+?PLy`T`@6uU}(%(Lj}7uO#if=|*5{#A?md0xt4+A96{q0$SE zAELS@4?HzNyE-LcYn)!l;c!hA|3bJ%iypm+~$G{F*}uN61i7JVhv@bxq#S&)A$1OOJbN>fL{MTTZ2`PRRW> z(q1pq&)n+z`A1MczeFNzc$$3)HYsdvo^~;IAHS%E?ct)mxb3iu_&gC{i{pojUP1oL z&tItXU(_5yT-|a4{d&f_ZKZi%CI5Pcu$13PcM_nMSO=ZQdRw^juBTtjzfdaBXxcH& zz?~|rU;Lz%ZA(zU@dz+CnZ*FlOUO+M1KkLJg~n=Z1gD^%ha=f7e(WSkQg zj%K*{O4-a2^9#Z*=~sl?5SE*;?r{q7xRhND@Qe8uyl#S;Ct$u{(9~K$sH{I^^S+GW zh>fzdL{YELA8>9OE#nu5Ll@cGRoaUd<;?N&eap!beqAHxU#P2$(GEA3GWYewkk>*77- z`VGV7sFA7bwi;Jl=RimPXv8k_uSe+G%I;KjqycvhV{5~gC<+xw94+&&?NCqX=}x_s zp5-{dM1p2Sf{E`d<5wqQHn9S-lkLuqlzjmD{yG?0Te0rp3jDHUrZr}U;1&)#xE8xs z9G8Qs#F-gZx{P1qfh}L#w}J5s`7gxcYR?ege>h`9nSVvdwHK!&9fJ{j&`vrCxQ);; z>eTA23jC`58GZER+Wr6UBIxi~lYjDJN z5h<;+2Q@nj0Z9ri#rjndKRn^?-iK zW(eSWII$r|D)37v+OSOF{7U zw5i4rTg*L9{Gkx2M|=-1n-Vz83u7K0E#p^fPSLKcKnO0bV2cl#qL8Dn0>31}8WOXL z_=fEhF@;}lC4T)(Tjs1C1^;@JmN|f=G2@cf>7dUQ_=PGRhKXTu6nN3f@xx1$WCW?e zFN9(=Q{Gje3>!V!lLMl~DCCy%UuKO;Wx6K#mxo_{;%36XagYjepG){9)cLP7Jy%Q! z4q}XlceH)$#+nWInx~ha){8 z8w~0nkk4CnNn50+r zRpfYWenkvwIhgLy%rx}t6>~`sSU;&<7ot9HlhYz%NHlA!dxd2WnY+_S>|WNk^F;NE z4c>bgzfQ=7_70DKHOC^GR=g~}E%&DYWb*~TM%_P;QMkabi}a^_FL6#&&cDQl4DjnM zLfXqVo@?lU8^0(OJ*PjU;Rz#Sz`u48;+ezd|6R|Cx!nT%>tPzQ7xacI>gO}iIONFw za30!N%|qdT6tigaFE0@2v(LZm#t|AYH+ICSM^GL^em~LYNy@|pT)Uj{>?-1i;?&A6 z5y=eN>@eIHU92aTy0Wtv*g@M-z{*P-x_djVtwAF_bU9}pnT0Kb%dX8d|S%lwOB z%UYCo?Yr&-!0+@@8x}oYNgbFhH_H1BNL+BT-NQSZO zpqa8G}trn=j)0AerbIFd^hvuGZ0jn=y!Pq3$U31e!WhI z(~4~|U7F8j8@LFOz?)JN7PIh<_JMG}h+I`1K@BitfGWp^DqMz-3=3l=15km=yJ%AJQpD zz30dD9Q>9w{2rUvg5!rrMBAg`ePT?0um5)L&lu<9T=Vac@o=~e>Nl_i8+V6W)5q-r z>@kdM%+s&G7E3(+;`3jJE+`Q) zBjC#bvU{lccT zr`2z0{(6l$DnY}%01k{3nRfriwruQG^LtL4GczlGz!Am1P$PUlrC&{2D>%p>Fj`%q z2l@U(v=LjJSRXD2t1ao5LHkuK4kdgjJ9I)8_9_+DLOkZXE&^waM z=PSLAjoIp)-MiKwVu12#9z}p(;9rbiu3nV>n!bYhfk$0|U(CPuJ~n$6hBn?FSoNVvI|Irgg*Bfc1%Lw?MnPYG-C*=chSKy z2X3PnnTsbC_yv#AiNM1*k$hp>GC?n>L|B+sDqU9jFP#4}_rkL3`}uEtvmkxlu7U}-eb(axX(%;IEv%7{k-nDKgz;zjwMcpx(EWV*QE1ea*-S1#$Frs z?|-#l!msn0YgK^pj@;bea>bk!MMI5!1o1sEhw)2|OX66HKdy_MY(*@$ z-p8*A;MZf|8`zmFEMP2nfxaYL867$+>gPfK6FEJCupwd>2x6H3U@dkL2MF-%5$-CV zI`k$%2|uEx7}wxvZHoKj*Uz8A-}1&4Mq~GFyK5wRXwc_hTz`lZ$tWsy**|36={avd z*0A6#@&%VY{F1;g)o0|tRG(*Ty6a{0vHXH@biM$Cf{*(5zcf|JTrqaOND4-#f`7pj z$i$c)hriJ!>vEcJ6RP8fMkiovP`SGhbPzvq&+7aao7046=T$h1Ge>O>_OtNzn7Tho zYjaEsyvYxXje)=8NjAW*8vaT>X+{0Kx|#!R1nTE2@?VT!iB)*Qf(pS6=LX_@kA;7fEsc%i{S__eW{KrZd|Zzm$0|-+y>hO0}usuTU?F_#tv+ zXv~*Qom2*B_$KJa)s_Zz%loFc(kC^&9@! zk<#)@E{82#l+E)~!M`fznfrs_C+?4Owg>zxs6YHlx$KZf@gz5{sNdkLz!X3AU6F#x zC&I9}Rq;cV6moqO;}_i2abo;}aLUuK(*04mlPB0?r`cEMJysDv^{jwGe1HaDG4y)Nkd?Psj#X1Pxfey~{bWof}Fn>3sf1?*vP{)>kLlY+BCfvw{NAKOD8zfgZj ze5FsqyEaN;0q&SG4!Qt^LP@_iDzjW^5BZ>zI{)RzH@JR-ZMey$ZY;13hv2tSYf-8{ z>`jXDnqs7CP5t;h>JL>{k?l&9`ivgJK69S~{4%a-s;d=t9{&7M^tp^*6fDzJ!N)KE z{zIl+DqU42_+#h%SFi+Agu5wSA)*O+v5Hx{DOX6ckEN}3!Yv8 zTY>PFhn3U+{Yqc~vq-jeRrxQ^oCdt0BpfU0*ZPuK9-Afv@x#D$Pj7R=TMN#AF&2cG zc1;z0{VLZVmb)7Cxt#wh_0R(;#)8t53jS51Ii;_HHWl$hAGQi5{0fAi{&0F%gD2(q z;k0Q9CSeMGRdzM#PdWcJt*b$sO8!;irzQL1@|9bPj@Q#*Hkm;AsQU}s{Gdt^s5TLZqUZZFE9Uf1N|ED_B`{i zsphM!?{Od;cupB?UvCV|v>#*G@;n#K7)YmUB z|5Zs9D;C8K@C!WU27UJNi;geX`i^Pjj2xjRJ1SJvF8eZu)oYxZ!3 zK%a1a$(rph>{D%|&}`Xj*PBLqnjme}gd}MxYNDH|MnYJpgc^SG3wYwUIo@0IDeV*T zH|^OYWub%S@RQPS9e0TTRxN3=LeRV?r9Sr>oKfhptxQRfhV4C(r8cW-dItJ(cgJUk zN`lb(2Kw@MCuUJ;ToLWp>ErI~WX&2+=!fu|hqA;^8)TF6dn#=v)I_}h@wBMrNpxM$BoZ0fG^;)lbQtGp#r*K)w?NldA zLPkp=kik#<{v7Wyk^>QYg=xX^2ZB^jN^>X)8ym4OQ1G(QVR%n$hxmgvP0BTPgJ~Qq z3D4Gaxax^(t0r{3rzSP9&i)N^cDf`C)}&nZM3%~)~i-qF8flAO*OSt67a<0C*=1T<09$U zmT6Q7hWusQ>NQGjj^C;Onmn7jt*Nd;m^GlDlz!{@oi+Cjd?NLmO|wq~!cF&hPfEIT z$DR6p@_gzeO?4-f@Cy($@5u+;S>7Dpah>-xE|d{|vpdVvFA~$#Dy{VonXGZrdks;o zc8^?_y1A+5fk3G7p3E+_xx=aH*FHhNNwZxg{5my4Al}o#Z{5*DDcNM#np#>3YQv_m zUN`|L{XW<97&e~tm{wW|YT<0GpkrE6^Ez}#PmMFsXWwnk7Azz`9+};vIY%4uq=x)) zX}Z?u-kqEssaa7W$h+;?W{smc-itV^ZYlL;fmV`cBCMgFcnyf|Kn_Vt8`W5Xg&Z!F zfiR$+lzt0iPigCX{et~rMZ2l=#2?pjN1v)+Y^+9Re`)LwQBwozmd7}-dRoZ&gNMe7K}SJ2&q|3LwHht&mDcU?lwNI z&2mgPFneCK*%WUQ~Z^Yt5=!0;7FNC{UC^eywCM1fs|lqzOSA;wRGJN`y5*Aeo zL7R_#_E*3E#mB~e{3Z(zePryxH$S$i_e8_~v5S8kw9!PrgM$~wjH6S8#u;v@kx>E1 zQvf<>b3MDEkh;l`rS}kB2Tw}~>o+ouPib@HFWIw3rU>y_?*F^@OvPm%pi{Us)Bnsj zRt?nWR_>cMUGQ6&ZiJNSN@{DS36ABpa!YUwdsGe3jt1@IkLfxkwF&g6ECg+g6ugT& zX_lNWcx^1r5h>b5^Js>gCZyF*k#om&aoGcC*RzKXnoh^%;E8&XgAOKv=BStqPRIv> ztD30anvSRb6Y2k!c0FA7JrwD^r%$^cE|=a@`Yp%k(;Ddxnl)YM@qVk97>=!!(WFfm zyw^}KFm5_7`%nBf4)An3F8fcM5~kc~+&3^M^-E2&PD~SAzt7s8;y(Fs>O)O4PD~U0 zHhtH_pbOtPYr8!GX6R0#Uo%-CyWKBd{F->s1K0CmiN?Z;Angy>3 z@53rw4gi{k(r;?^pxLhSHFEx2jak(0fO91_6!Ea56#7q_^87zE2tneL1B;O3#AvCoJ`Jei3e)CAPCDGj%n&ismb-;bJJots{F#>Bd2XL z7haZf{=7D2&#=4$;e}=i45;)L({md+>7)EdCAjmFgad>8xA=oL@->MY$oBX8wo=W278~AyeA;H$YpTc`dCEGDA6++`I)5Md~dn~#sshy@j zq&aR$7`@5XhG{v?Ip%qq*MCoZA(@{F-b2?JRXsJrik0UF-I_MfmV`fV`pHx7cgeu| zW8nYTcxoamg{6de{ZDDkrEfbsOH%p2Nr~U*RgXr?52s4=oO#aFXH)(>_b>k9FXWVG z)BYH1t`9bb`m+1lwQDX*(*^bY^}h-l|EFzp9bGOdbnsJlsafr6-23a--0$3 zDh#8?DjYm1wYiQi2TJ{}y6nHuf6w)F8DDw2TVB&?x?G-lztMGcx%}5}tjpy#o^(B3 z4%)n%E(eX?Ya!6e=|b>R)4vLy{HJXbbnJ#g5?9;uHc3*?FW<1y&%gNj4E%fsem(;~ zpMjsxz|Uvk=QHsC;~7x?5*#M@OU`wtK_}OZm=!sl>$dt2AL2DSMJO5h4_m%_1ED!- z*;tNcy?g5$e~bR`d;X96gH+#ts`*jciGbaU-nND oSD+B(XD3PGzog@M){J-giQp^0eN7UlAo-#9o}=Zol;86I0aMIW=>Px# From 74288ad1281f9f7f3531efcc1a2821bd0e1f1da2 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 31 Jul 2019 15:43:00 -0400 Subject: [PATCH 0196/1854] chg: hf topaz - got some love --- client/cmdhftopaz.c | 143 +++++++++++++++++++++++++------------------- include/pm3_cmd.h | 2 + 2 files changed, 82 insertions(+), 63 deletions(-) diff --git a/client/cmdhftopaz.c b/client/cmdhftopaz.c index d604d4baf..ab3fcb69d 100644 --- a/client/cmdhftopaz.c +++ b/client/cmdhftopaz.c @@ -39,22 +39,28 @@ static void topaz_switch_off_field(void) { } // send a raw topaz command, returns the length of the response (0 in case of error) -static int topaz_send_cmd_raw(uint8_t *cmd, uint8_t len, uint8_t *response) { +static int topaz_send_cmd_raw(uint8_t *cmd, uint8_t len, uint8_t *response, uint16_t *response_len) { SendCommandOLD(CMD_READER_ISO_14443a, ISO14A_RAW | ISO14A_NO_DISCONNECT | ISO14A_TOPAZMODE | ISO14A_NO_RATS, len, 0, cmd, len); PacketResponseNG resp; - WaitForResponse(CMD_ACK, &resp); + + if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { + PrintAndLogEx(WARNING, "timeout while waiting for reply."); + return PM3_ETIMEOUT; + } + *response_len = resp.oldarg[0]; + PrintAndLogEx(INFO, "%s", sprint_hex(resp.data.asBytes, resp.oldarg[0])); if (resp.oldarg[0] > 0) { memcpy(response, resp.data.asBytes, resp.oldarg[0]); } - return resp.oldarg[0]; + return PM3_SUCCESS; } // calculate CRC bytes and send topaz command, returns the length of the response (0 in case of error) -static int topaz_send_cmd(uint8_t *cmd, uint8_t len, uint8_t *response) { +static int topaz_send_cmd(uint8_t *cmd, uint8_t len, uint8_t *response, uint16_t *response_len) { if (len > 1) { uint8_t b1, b2; compute_crc(CRC_14443_B, cmd, len - 2, &b1, &b2); @@ -62,7 +68,7 @@ static int topaz_send_cmd(uint8_t *cmd, uint8_t len, uint8_t *response) { cmd[len - 1] = b2; } - return topaz_send_cmd_raw(cmd, len, response); + return topaz_send_cmd_raw(cmd, len, response, response_len); } @@ -70,67 +76,73 @@ static int topaz_send_cmd(uint8_t *cmd, uint8_t len, uint8_t *response) { static int topaz_select(uint8_t *atqa, uint8_t *rid_response) { // ToDo: implement anticollision + uint16_t resp_len = 0; uint8_t wupa_cmd[] = {TOPAZ_WUPA}; uint8_t rid_cmd[] = {TOPAZ_RID, 0, 0, 0, 0, 0, 0, 0, 0}; topaz_switch_on_field(); - if (!topaz_send_cmd(wupa_cmd, sizeof(wupa_cmd), atqa)) { + if (topaz_send_cmd(wupa_cmd, sizeof(wupa_cmd), atqa, &resp_len) == PM3_ETIMEOUT) { topaz_switch_off_field(); - return -1; // WUPA failed + return PM3_ESOFT; // WUPA failed } - if (!topaz_send_cmd(rid_cmd, sizeof(rid_cmd), rid_response)) { + if (topaz_send_cmd(rid_cmd, sizeof(rid_cmd), rid_response, &resp_len) == PM3_ETIMEOUT) { topaz_switch_off_field(); - return -2; // RID failed + return PM3_EWRONGANSVER; // RID failed } - return 0; // OK + return PM3_SUCCESS; } // read all of the static memory of a selected Topaz tag. static int topaz_rall(uint8_t *uid, uint8_t *response) { + uint16_t resp_len = 0; uint8_t rall_cmd[] = {TOPAZ_RALL, 0, 0, 0, 0, 0, 0, 0, 0}; - memcpy(&rall_cmd[3], uid, 4); - if (!topaz_send_cmd(rall_cmd, sizeof(rall_cmd), response)) { + + if (topaz_send_cmd(rall_cmd, sizeof(rall_cmd), response, &resp_len) == PM3_ETIMEOUT) { topaz_switch_off_field(); - return -1; // RALL failed + return PM3_ESOFT; // RALL failed } - return 0; + return PM3_SUCCESS; } // read a block (8 Bytes) of a selected Topaz tag. static int topaz_read_block(uint8_t *uid, uint8_t blockno, uint8_t *block_data) { + uint16_t resp_len = 0; uint8_t read8_cmd[] = {TOPAZ_READ8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; uint8_t read8_response[11]; read8_cmd[1] = blockno; memcpy(&read8_cmd[10], uid, 4); - if (!topaz_send_cmd(read8_cmd, sizeof(read8_cmd), read8_response)) { + + if (topaz_send_cmd(read8_cmd, sizeof(read8_cmd), read8_response, &resp_len) == PM3_ETIMEOUT) { topaz_switch_off_field(); - return -1; // READ8 failed + return PM3_ESOFT; // READ8 failed } memcpy(block_data, &read8_response[1], 8); - return 0; + return PM3_SUCCESS; } // read a segment (16 blocks = 128 Bytes) of a selected Topaz tag. Works only for tags with dynamic memory. static int topaz_read_segment(uint8_t *uid, uint8_t segno, uint8_t *segment_data) { + uint16_t resp_len = 0; uint8_t rseg_cmd[] = {TOPAZ_RSEG, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; uint8_t rseg_response[131]; rseg_cmd[1] = segno << 4; memcpy(&rseg_cmd[10], uid, 4); - if (!topaz_send_cmd(rseg_cmd, sizeof(rseg_cmd), rseg_response)) { + + if (topaz_send_cmd(rseg_cmd, sizeof(rseg_cmd), rseg_response, &resp_len) == PM3_ETIMEOUT) { topaz_switch_off_field(); - return -1; // RSEG failed + return PM3_ESOFT; // RSEG failed } memcpy(segment_data, &rseg_response[1], 128); - return 0; + return PM3_SUCCESS; } // search for the lock area descriptor for the lockable area including byteno @@ -181,7 +193,7 @@ static bool topaz_byte_is_locked(uint16_t byteno) { static int topaz_print_CC(uint8_t *data) { if (data[0] != 0xe1) { topaz_tag.size = TOPAZ_STATIC_MEMORY; - return -1; // no NDEF message + return PM3_ESOFT; // no NDEF message } PrintAndLogEx(NORMAL, "Capability Container: %02x %02x %02x %02x", data[0], data[1], data[2], data[3]); @@ -194,7 +206,7 @@ static int topaz_print_CC(uint8_t *data) { PrintAndLogEx(NORMAL, " %02x: %s / %s", data[3], (data[3] & 0xF0) ? "(RFU)" : "Read access granted without any security", (data[3] & 0x0F) == 0 ? "Write access granted without any security" : (data[3] & 0x0F) == 0x0F ? "No write access granted at all" : "(RFU)"); - return 0; + return PM3_SUCCESS; } @@ -320,20 +332,20 @@ static void topaz_print_control_TLVs(uint8_t *memory) { // read all of the dynamic memory static int topaz_read_dynamic_data(void) { // first read the remaining block of segment 0 - if (topaz_read_block(topaz_tag.uid, 0x0f, &topaz_tag.dynamic_memory[0]) == -1) { - PrintAndLogEx(ERR, "Error while reading dynamic memory block %02x. Aborting...", 0x0f); - return -1; + if (topaz_read_block(topaz_tag.uid, 0x0F, &topaz_tag.dynamic_memory[0]) == PM3_ESOFT) { + PrintAndLogEx(ERR, "Error while reading dynamic memory block " _YELLOW_("%02x") ". Aborting...", 0x0F); + return PM3_ESOFT; } // read the remaining segments uint8_t max_segment = topaz_tag.size / 128 - 1; for (uint8_t segment = 1; segment <= max_segment; segment++) { - if (topaz_read_segment(topaz_tag.uid, segment, &topaz_tag.dynamic_memory[(segment - 1) * 128 + 8]) == -1) { - PrintAndLogEx(ERR, "Error while reading dynamic memory block %02x. Aborting...", 0x0f); - return -1; + if (topaz_read_segment(topaz_tag.uid, segment, &topaz_tag.dynamic_memory[(segment - 1) * 128 + 8]) == PM3_ESOFT) { + PrintAndLogEx(ERR, "Error while reading dynamic memory block " _YELLOW_("%02x") ". Aborting...", segment); + return PM3_ESOFT; } } - return 0; + return PM3_SUCCESS; } @@ -343,16 +355,17 @@ static void topaz_print_dynamic_data(void) { PrintAndLogEx(NORMAL, "Dynamic Data blocks:"); if (topaz_read_dynamic_data() == 0) { PrintAndLogEx(NORMAL, "block# | offset | Data | Locked(y/n)"); + PrintAndLogEx(NORMAL, "-------+--------+-------------------------+------------"); char line[80]; - for (uint16_t blockno = 0x0f; blockno < topaz_tag.size / 8; blockno++) { - uint8_t *block_data = &topaz_tag.dynamic_memory[(blockno - 0x0f) * 8]; + for (uint16_t blockno = 0x0F; blockno < topaz_tag.size / 8; blockno++) { + uint8_t *block_data = &topaz_tag.dynamic_memory[(blockno - 0x0F) * 8]; char lockbits[9]; for (uint16_t j = 0; j < 8; j++) { sprintf(&line[3 * j], "%02x ", block_data[j]); lockbits[j] = topaz_byte_is_locked(blockno * 8 + j) ? 'y' : 'n'; } lockbits[8] = '\0'; - PrintAndLogEx(NORMAL, " 0x%02x | 0x%04x | %s| %-3s", blockno, blockno * 8, line, lockbits); + PrintAndLogEx(NORMAL, " 0x%02x | 0x%04x | %s| %-3s", blockno, blockno * 8, line, lockbits); } } } @@ -375,45 +388,47 @@ static int CmdHFTopazReader(const char *Cmd) { uint8_t rall_response[124]; bool verbose = true; - char ctmp = param_getchar(Cmd, 0); - if (ctmp == 'S' || ctmp == 's') verbose = false; + char ctmp = tolower(param_getchar(Cmd, 0)); + if (ctmp == 's') verbose = false; status = topaz_select(atqa, rid_response); - if (status == -1) { + if (status == PM3_ESOFT) { if (verbose) PrintAndLogEx(ERR, "Error: couldn't receive ATQA"); - return -1; + return PM3_ESOFT; } PrintAndLogEx(NORMAL, "ATQA : %02x %02x", atqa[1], atqa[0]); if (atqa[1] != 0x0c && atqa[0] != 0x00) { - PrintAndLogEx(NORMAL, "Tag doesn't support the Topaz protocol."); + PrintAndLogEx(ERR, "Tag doesn't support the Topaz protocol."); topaz_switch_off_field(); - return -1; + return PM3_ESOFT; } - if (status == -2) { + if (status == PM3_EWRONGANSVER) { PrintAndLogEx(ERR, "Error: tag didn't answer to RID"); topaz_switch_off_field(); - return -1; + return PM3_ESOFT; } topaz_tag.HR01[0] = rid_response[0]; topaz_tag.HR01[1] = rid_response[1]; // ToDo: CRC check - PrintAndLogEx(NORMAL, "HR0 : %02x (%sa Topaz tag (%scapable of carrying a NDEF message), %s memory map)", rid_response[0], + PrintAndLogEx(NORMAL, "HR0 : %02x (%sa Topaz tag (%scapable of carrying a NDEF message), %s memory map)", + rid_response[0], (rid_response[0] & 0xF0) == 0x10 ? "" : "not ", (rid_response[0] & 0xF0) == 0x10 ? "" : "not ", (rid_response[0] & 0x0F) == 0x01 ? "static" : "dynamic"); + PrintAndLogEx(NORMAL, "HR1 : %02x", rid_response[1]); status = topaz_rall(uid_echo, rall_response); - if (status == -1) { + if (status == PM3_ESOFT) { PrintAndLogEx(ERR, "Error: tag didn't answer to RALL"); topaz_switch_off_field(); - return -1; + return PM3_ESOFT; } memcpy(topaz_tag.uid, rall_response + 2, 7); @@ -426,14 +441,15 @@ static int CmdHFTopazReader(const char *Cmd) { topaz_tag.uid[1], topaz_tag.uid[0]); - PrintAndLogEx(NORMAL, " UID[6] (Manufacturer Byte) = %02x, Manufacturer: %s", + PrintAndLogEx(NORMAL, " UID[6] (Manufacturer Byte) = " _YELLOW_("%02x")", Manufacturer: " _YELLOW_("%s"), topaz_tag.uid[6], getTagInfo(topaz_tag.uid[6])); memcpy(topaz_tag.data_blocks, rall_response + 2, 0x0f * 8); PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Static Data blocks 00 to 0c:"); + PrintAndLogEx(NORMAL, "Static Data blocks " _YELLOW_("0x00") "to " _YELLOW_("0x0C")":"); PrintAndLogEx(NORMAL, "block# | offset | Data | Locked"); + PrintAndLogEx(NORMAL, "-------+--------+-------------------------+------------"); char line[80]; for (uint16_t i = 0; i <= 0x0c; i++) { char lockbits[9]; @@ -442,31 +458,32 @@ static int CmdHFTopazReader(const char *Cmd) { lockbits[j] = topaz_byte_is_locked(i * 8 + j) ? 'y' : 'n'; } lockbits[8] = '\0'; - PrintAndLogEx(NORMAL, " 0x%02x | 0x%02x | %s| %-3s", i, i * 8, line, lockbits); + PrintAndLogEx(NORMAL, " 0x%02x | 0x%02x | %s| %-3s", i, i * 8, line, lockbits); } PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Static Reserved block 0d:"); + PrintAndLogEx(NORMAL, "Static Reserved block " _YELLOW_("0x0D")":"); for (uint16_t j = 0; j < 8; j++) { sprintf(&line[3 * j], "%02x ", topaz_tag.data_blocks[0x0d][j]); } - PrintAndLogEx(NORMAL, " 0x%02x | 0x%02x | %s| %-3s", 0x0d, 0x0d * 8, line, "n/a"); - + PrintAndLogEx(NORMAL, "-------+--------+-------------------------+------------"); + PrintAndLogEx(NORMAL, " 0x%02x | 0x%02x | %s| %-3s", 0x0d, 0x0d * 8, line, "n/a"); PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Static Lockbits and OTP Bytes:"); for (uint16_t j = 0; j < 8; j++) { sprintf(&line[3 * j], "%02x ", topaz_tag.data_blocks[0x0e][j]); } - PrintAndLogEx(NORMAL, " 0x%02x | 0x%02x | %s| %-3s", 0x0e, 0x0e * 8, line, "n/a"); - + PrintAndLogEx(NORMAL, "-------+--------+-------------------------+------------"); + PrintAndLogEx(NORMAL, " 0x%02x | 0x%02x | %s| %-3s", 0x0e, 0x0e * 8, line, "n/a"); PrintAndLogEx(NORMAL, ""); status = topaz_print_CC(&topaz_tag.data_blocks[1][0]); - if (status == -1) { + if (status == PM3_ESOFT) { PrintAndLogEx(NORMAL, "No NDEF message data present"); topaz_switch_off_field(); - return 0; + return PM3_SUCCESS; } PrintAndLogEx(NORMAL, ""); @@ -480,35 +497,35 @@ static int CmdHFTopazReader(const char *Cmd) { topaz_print_NDEF(&topaz_tag.data_blocks[1][0]); topaz_switch_off_field(); - return 0; + return PM3_SUCCESS; } static int CmdHFTopazSim(const char *Cmd) { (void)Cmd; // Cmd is not used so far PrintAndLogEx(NORMAL, "not yet implemented"); - return 0; + return PM3_SUCCESS; } static int CmdHFTopazCmdRaw(const char *Cmd) { (void)Cmd; // Cmd is not used so far PrintAndLogEx(NORMAL, "not yet implemented. Use hf 14 raw with option -T."); - return 0; + return PM3_SUCCESS; } static int CmdHFTopazList(const char *Cmd) { (void)Cmd; // Cmd is not used so far CmdTraceList("topaz"); - return 0; + return PM3_SUCCESS; } static int CmdHelp(const char *Cmd); static command_t CommandTable[] = { - {"help", CmdHelp, AlwaysAvailable, "This help"}, - {"reader", CmdHFTopazReader, IfPm3Iso14443a, "Act like a Topaz reader"}, - {"sim", CmdHFTopazSim, IfPm3Iso14443a, " -- Simulate Topaz tag"}, - {"sniff", CmdHF14ASniff, IfPm3Iso14443a, "Sniff Topaz reader-tag communication"}, - {"raw", CmdHFTopazCmdRaw, IfPm3Iso14443a, "Send raw hex data to tag"}, + {"help", CmdHelp, AlwaysAvailable, "This help"}, + {"reader", CmdHFTopazReader, IfPm3Iso14443a, "Act like a Topaz reader"}, + {"sim", CmdHFTopazSim, IfPm3Iso14443a, " -- Simulate Topaz tag"}, + {"sniff", CmdHF14ASniff, IfPm3Iso14443a, "Sniff Topaz reader-tag communication"}, + {"raw", CmdHFTopazCmdRaw, IfPm3Iso14443a, "Send raw hex data to tag"}, {"list", CmdHFTopazList, AlwaysAvailable, "List Topaz history"}, {NULL, NULL, 0, NULL} }; @@ -516,7 +533,7 @@ static command_t CommandTable[] = { static int CmdHelp(const char *Cmd) { (void)Cmd; // Cmd is not used so far CmdsHelp(CommandTable); - return 0; + return PM3_SUCCESS; } int CmdHFTopaz(const char *Cmd) { diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 8c40a795d..e8ff526d7 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -559,6 +559,8 @@ typedef struct { #define PM3_ENOTTY -14 // Initialization error pm3: error related to trying to initalize the pm3 / fpga for different operations #define PM3_EINIT -15 +// Expected a different answer error client/pm3: error when expecting one answer and got another one +#define PM3_EWRONGANSVER -16 // No data pm3: no data available, no host frame available (not really an error) #define PM3_ENODATA -98 // Quit program client: reserved, order to quit the program From f276dca3f1126b72d49f4fdd7e638d5535600022 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 31 Jul 2019 23:44:53 +0200 Subject: [PATCH 0197/1854] less hardcoded sizes and more ARRAYLEN --- armsrc/Standalone/hf_colin.c | 8 +++----- armsrc/Standalone/hf_mattyrun.c | 2 +- client/cmdhf14a.c | 5 ++--- client/cmdhflist.c | 2 +- client/cmdhfmf.c | 26 +++++++++++++------------- client/cmdhfmfu.c | 12 +++++------- client/cmdlfti.c | 4 ++-- client/emv/apduinfo.c | 7 +++---- client/emv/emv_tags.c | 3 ++- client/emv/emvcore.c | 6 ++---- client/emv/emvjson.c | 3 +-- client/emv/test/crypto_test.c | 3 ++- client/fido/fidocore.c | 4 ++-- client/mifare/mifare4.c | 3 +-- client/mifare/mifaredefault.h | 2 -- client/whereami.c | 6 +++--- 16 files changed, 43 insertions(+), 53 deletions(-) diff --git a/armsrc/Standalone/hf_colin.c b/armsrc/Standalone/hf_colin.c index 5eeb2a42a..509dd2685 100644 --- a/armsrc/Standalone/hf_colin.c +++ b/armsrc/Standalone/hf_colin.c @@ -242,9 +242,7 @@ void RunMod() { // French VIGIK system @2017 //---------------------------- -#define STKEYS 37 - - const uint64_t mfKeys[STKEYS] = { + const uint64_t mfKeys[] = { 0xffffffffffff, // TRANSPORTS 0x000000000000, // Blankkey 0x484558414354, // INFINEONON A / 0F SEC B / INTRATONE / HEXACT... @@ -285,8 +283,8 @@ void RunMod() { }; // Can remember something like that in case of Bigbuf - keyBlock = BigBuf_malloc(STKEYS * 6); - int mfKeysCnt = sizeof(mfKeys) / sizeof(uint64_t); + keyBlock = BigBuf_malloc(ARRAYLEN(mfKeys) * 6); + int mfKeysCnt = ARRAYLEN(mfKeys); for (int mfKeyCounter = 0; mfKeyCounter < mfKeysCnt; mfKeyCounter++) { num_to_bytes(mfKeys[mfKeyCounter], 6, (uint8_t *)(keyBlock + mfKeyCounter * 6)); diff --git a/armsrc/Standalone/hf_mattyrun.c b/armsrc/Standalone/hf_mattyrun.c index 9ea0ba524..1cf75888b 100644 --- a/armsrc/Standalone/hf_mattyrun.c +++ b/armsrc/Standalone/hf_mattyrun.c @@ -262,7 +262,7 @@ void RunMod() { keys in keyBlock's memory space . */ keyBlock = BigBuf_malloc(stKeyBlock * 6); - int mfKeysCnt = sizeof(mfKeys) / sizeof(uint64_t); + int mfKeysCnt = ARRAYLEN(mfKeys); for (int mfKeyCounter = 0; mfKeyCounter < mfKeysCnt; mfKeyCounter++) { num_to_bytes(mfKeys[mfKeyCounter], 6, (uint8_t *)(keyBlock + mfKeyCounter * 6)); diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index f92a35370..0b3749590 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -139,14 +139,13 @@ static const manufactureName manufactureMapping[] = { const char *getTagInfo(uint8_t uid) { int i; - int len = sizeof(manufactureMapping) / sizeof(manufactureName); - for (i = 0; i < len; ++i) + for (i = 0; i < ARRAYLEN(manufactureMapping); ++i) if (uid == manufactureMapping[i].uid) return manufactureMapping[i].desc; //No match, return default - return manufactureMapping[len - 1].desc; + return manufactureMapping[ARRAYLEN(manufactureMapping) - 1].desc; } // iso14a apdu input frame length diff --git a/client/cmdhflist.c b/client/cmdhflist.c index 6aea59b89..d583dedbb 100644 --- a/client/cmdhflist.c +++ b/client/cmdhflist.c @@ -1126,7 +1126,7 @@ bool DecodeMifareData(uint8_t *cmd, uint8_t cmdsize, uint8_t *parity, bool isRes // check default keys if (!traceCrypto1) { - for (int i = 0; i < MIFARE_DEFAULTKEYS_SIZE; i++) { + for (int i = 0; i < ARRAYLEN(g_mifare_default_keys); i++) { if (NestedCheckKey(g_mifare_default_keys[i], &AuthData, cmd, cmdsize, parity)) { PrintAndLogEx(NORMAL, " | | * |%61s %012"PRIx64"| |", "key", g_mifare_default_keys[i]); diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 6e2ca62f5..5fff42061 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -1069,7 +1069,7 @@ static int CmdHF14AMfNested(const char *Cmd) { uint8_t trgKeyType = 0; uint8_t SectorsCnt = 0; uint8_t key[6] = {0, 0, 0, 0, 0, 0}; - uint8_t keyBlock[(MIFARE_DEFAULTKEYS_SIZE + 1) * 6]; + uint8_t keyBlock[(ARRAYLEN(g_mifare_default_keys) + 1) * 6]; uint64_t key64 = 0; bool transferToEml = false; bool createDumpFile = false; @@ -1173,17 +1173,17 @@ static int CmdHF14AMfNested(const char *Cmd) { //test current key and additional standard keys first // add parameter key - memcpy(keyBlock + (MIFARE_DEFAULTKEYS_SIZE * 6), key, 6); + memcpy(keyBlock + (ARRAYLEN(g_mifare_default_keys) * 6), key, 6); - for (int cnt = 0; cnt < MIFARE_DEFAULTKEYS_SIZE; cnt++) { + for (int cnt = 0; cnt < ARRAYLEN(g_mifare_default_keys); cnt++) { num_to_bytes(g_mifare_default_keys[cnt], 6, (uint8_t *)(keyBlock + cnt * 6)); } PrintAndLogEx(SUCCESS, "Testing known keys. Sector count=%d", SectorsCnt); - mfCheckKeys_fast(SectorsCnt, true, true, 1, MIFARE_DEFAULTKEYS_SIZE + 1, keyBlock, e_sector, false); + mfCheckKeys_fast(SectorsCnt, true, true, 1, ARRAYLEN(g_mifare_default_keys) + 1, keyBlock, e_sector, false); uint64_t t2 = msclock() - t1; - PrintAndLogEx(SUCCESS, "Time to check %d known keys: %.0f seconds\n", MIFARE_DEFAULTKEYS_SIZE, (float)t2 / 1000.0); + PrintAndLogEx(SUCCESS, "Time to check %d known keys: %.0f seconds\n", ARRAYLEN(g_mifare_default_keys), (float)t2 / 1000.0); PrintAndLogEx(SUCCESS, "enter nested attack"); // nested sectors @@ -1554,15 +1554,15 @@ static int CmdHF14AMfChk_fast(const char *Cmd) { int i, keycnt = 0; int clen = 0; int transferToEml = 0, createDumpFile = 0; - uint32_t keyitems = MIFARE_DEFAULTKEYS_SIZE; + uint32_t keyitems = ARRAYLEN(g_mifare_default_keys); bool use_flashmemory = false; sector_t *e_sector = NULL; - keyBlock = calloc(MIFARE_DEFAULTKEYS_SIZE, 6); + keyBlock = calloc(ARRAYLEN(g_mifare_default_keys), 6); if (keyBlock == NULL) return 1; - for (int cnt = 0; cnt < MIFARE_DEFAULTKEYS_SIZE; cnt++) + for (int cnt = 0; cnt < ARRAYLEN(g_mifare_default_keys); cnt++) num_to_bytes(g_mifare_default_keys[cnt], 6, keyBlock + cnt * 6); // sectors @@ -1661,7 +1661,7 @@ static int CmdHF14AMfChk_fast(const char *Cmd) { if (keycnt == 0 && !use_flashmemory) { PrintAndLogEx(SUCCESS, "No key specified, trying default keys"); - for (; keycnt < MIFARE_DEFAULTKEYS_SIZE; keycnt++) + for (; keycnt < ARRAYLEN(g_mifare_default_keys); keycnt++) PrintAndLogEx(NORMAL, "[%2d] %02x%02x%02x%02x%02x%02x", keycnt, (keyBlock + 6 * keycnt)[0], (keyBlock + 6 * keycnt)[1], (keyBlock + 6 * keycnt)[2], (keyBlock + 6 * keycnt)[3], (keyBlock + 6 * keycnt)[4], (keyBlock + 6 * keycnt)[5]); @@ -1806,7 +1806,7 @@ static int CmdHF14AMfChk(const char *Cmd) { uint8_t blockNo = 0; uint8_t SectorsCnt = 1; uint8_t keyType = 0; - uint32_t keyitems = MIFARE_DEFAULTKEYS_SIZE; + uint32_t keyitems = ARRAYLEN(g_mifare_default_keys); uint64_t key64 = 0; uint8_t tempkey[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; char *fptr; @@ -1815,10 +1815,10 @@ static int CmdHF14AMfChk(const char *Cmd) { int createDumpFile = 0; int i, keycnt = 0; - keyBlock = calloc(MIFARE_DEFAULTKEYS_SIZE, 6); + keyBlock = calloc(ARRAYLEN(g_mifare_default_keys), 6); if (keyBlock == NULL) return PM3_EMALLOC; - for (int cnt = 0; cnt < MIFARE_DEFAULTKEYS_SIZE; cnt++) + for (int cnt = 0; cnt < ARRAYLEN(g_mifare_default_keys); cnt++) num_to_bytes(g_mifare_default_keys[cnt], 6, (uint8_t *)(keyBlock + cnt * 6)); if (param_getchar(Cmd, 0) == '*') { @@ -1928,7 +1928,7 @@ static int CmdHF14AMfChk(const char *Cmd) { if (keycnt == 0) { PrintAndLogEx(INFO, "No key specified, trying default keys"); - for (; keycnt < MIFARE_DEFAULTKEYS_SIZE; keycnt++) + for (; keycnt < ARRAYLEN(g_mifare_default_keys); keycnt++) PrintAndLogEx(NORMAL, "[%2d] %02x%02x%02x%02x%02x%02x", keycnt, (keyBlock + 6 * keycnt)[0], (keyBlock + 6 * keycnt)[1], (keyBlock + 6 * keycnt)[2], (keyBlock + 6 * keycnt)[3], (keyBlock + 6 * keycnt)[4], (keyBlock + 6 * keycnt)[5], 6); diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index 3f4c59115..b7d268884 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -210,8 +210,7 @@ static int usage_hf_mfu_pwdgen(void) { } -#define KEYS_3DES_COUNT 7 -uint8_t default_3des_keys[KEYS_3DES_COUNT][16] = { +uint8_t default_3des_keys[][16] = { { 0x42, 0x52, 0x45, 0x41, 0x4b, 0x4d, 0x45, 0x49, 0x46, 0x59, 0x4f, 0x55, 0x43, 0x41, 0x4e, 0x21 }, // 3des std key { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // all zeroes { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, // 0x00-0x0F @@ -221,8 +220,7 @@ uint8_t default_3des_keys[KEYS_3DES_COUNT][16] = { { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF } // 11 22 33 }; -#define KEYS_PWD_COUNT 1 -uint8_t default_pwd_pack[KEYS_PWD_COUNT][4] = { +uint8_t default_pwd_pack[][4] = { {0xFF, 0xFF, 0xFF, 0xFF}, // PACK 0x00,0x00 -- factory default }; @@ -1298,7 +1296,7 @@ static int CmdHF14AMfUInfo(const char *Cmd) { // also try to diversify default keys.. look into CmdHF14AMfGenDiverseKeys PrintAndLogEx(INFO, "Trying some default 3des keys"); - for (uint8_t i = 0; i < KEYS_3DES_COUNT; ++i) { + for (uint8_t i = 0; i < ARRAYLEN(default_3des_keys); ++i) { key = default_3des_keys[i]; if (ulc_authentication(key, true)) { PrintAndLogEx(SUCCESS, "Found default 3des key: "); @@ -1431,7 +1429,7 @@ static int CmdHF14AMfUInfo(const char *Cmd) { if (ul_auth_select(&card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack)) == PM3_ESOFT) return PM3_ESOFT; - for (uint8_t i = 0; i < KEYS_PWD_COUNT; ++i) { + for (uint8_t i = 0; i < ARRAYLEN(default_pwd_pack); ++i) { key = default_pwd_pack[i]; len = ulev1_requestAuthentication(key, pack, sizeof(pack)); if (len > -1) { @@ -2349,7 +2347,7 @@ static int CmdHF14AMfUCAuth(const char *Cmd) { //Change key to user defined one if (cmdp == 'k') { keyNo = param_get8(Cmd, 1); - if (keyNo >= KEYS_3DES_COUNT) + if (keyNo >= ARRAYLEN(default_3des_keys)) errors = true; } diff --git a/client/cmdlfti.c b/client/cmdlfti.c index 5236550b2..017df6e75 100644 --- a/client/cmdlfti.c +++ b/client/cmdlfti.c @@ -80,8 +80,8 @@ static int CmdTIDemod(const char *Cmd) { save_restoreGB(GRAPH_SAVE); - int lowLen = sizeof(LowTone) / sizeof(int); - int highLen = sizeof(HighTone) / sizeof(int); + int lowLen = ARRAYLEN(LowTone); + int highLen = ARRAYLEN(HighTone); int convLen = (highLen > lowLen) ? highLen : lowLen; uint16_t crc; int i, j, TagType; diff --git a/client/emv/apduinfo.c b/client/emv/apduinfo.c index 48e97622b..fd49eede8 100644 --- a/client/emv/apduinfo.c +++ b/client/emv/apduinfo.c @@ -257,7 +257,6 @@ const APDUCode APDUCodeTable[] = { {"9FXX", APDUCODE_TYPE_NONE, "Command successfully executed; 'xx' bytes of data are available and can be requested using GET RESPONSE."}, {"9XXX", APDUCODE_TYPE_NONE, "Application related status, (ISO 7816-3)"} }; -const size_t APDUCodeTableLen = sizeof(APDUCodeTable) / sizeof(APDUCode); static int CodeCmp(const char *code1, const char *code2) { int xsymb = 0; @@ -279,12 +278,12 @@ static int CodeCmp(const char *code1, const char *code2) { const APDUCode *GetAPDUCode(uint8_t sw1, uint8_t sw2) { char buf[6] = {0}; - int mineq = APDUCodeTableLen; + int mineq = ARRAYLEN(APDUCodeTable); int mineqindx = 0; sprintf(buf, "%02X%02X", sw1, sw2); - for (int i = 0; i < APDUCodeTableLen; i++) { + for (int i = 0; i < ARRAYLEN(APDUCodeTable); i++) { int res = CodeCmp(APDUCodeTable[i].ID, buf); // equal @@ -300,7 +299,7 @@ const APDUCode *GetAPDUCode(uint8_t sw1, uint8_t sw2) { } // if we have not equal, but with some 'X' - if (mineqindx < APDUCodeTableLen) { + if (mineqindx < ARRAYLEN(APDUCodeTable)) { return &APDUCodeTable[mineqindx]; } diff --git a/client/emv/emv_tags.c b/client/emv/emv_tags.c index 9ef049221..45202f9e6 100644 --- a/client/emv/emv_tags.c +++ b/client/emv/emv_tags.c @@ -17,6 +17,7 @@ #include #endif +#include "commonutil.h" #include "tlv.h" #include "emv_tags.h" @@ -437,7 +438,7 @@ static int emv_tlv_compare(const void *a, const void *b) { } static const struct emv_tag *emv_get_tag(const struct tlv *tlv) { - struct emv_tag *tag = bsearch(tlv, emv_tags, sizeof(emv_tags) / sizeof(emv_tags[0]), + struct emv_tag *tag = bsearch(tlv, emv_tags, ARRAYLEN(emv_tags), sizeof(emv_tags[0]), emv_tlv_compare); return tag ? tag : &emv_tags[0]; diff --git a/client/emv/emvcore.c b/client/emv/emvcore.c index c814eb11e..e44492078 100644 --- a/client/emv/emvcore.c +++ b/client/emv/emvcore.c @@ -18,7 +18,6 @@ static const char *PSElist [] = { "325041592E5359532E4444463031", // 2PAY.SYS.DDF01 - Visa Proximity Payment System Environment - PPSE "315041592E5359532E4444463031" // 1PAY.SYS.DDF01 - Visa Payment System Environment - PSE }; -//static const size_t PSElistLen = sizeof(PSElist)/sizeof(char*); const char *TransactionTypeStr[] = { "MSD", @@ -119,7 +118,6 @@ static const TAIDList AIDlist [] = { { CV_OTHER, "D5780000021010" }, // Bankaxept Norway Bankaxept Norwegian domestic debit card { CV_OTHER, "F0000000030001" }, // BRADESCO - Brazilian Bank Banco Bradesco }; -static const size_t AIDlistLen = sizeof(AIDlist) / sizeof(TAIDList); static bool APDULogging = false; void SetAPDULogging(bool logging) { @@ -133,7 +131,7 @@ enum CardPSVendor GetCardPSVendor(uint8_t *AID, size_t AIDlen) { hex_to_buffer((uint8_t *)buf, AID, AIDlen, sizeof(buf) - 1, 0, 0, true); - for (int i = 0; i < AIDlistLen; i ++) { + for (int i = 0; i < ARRAYLEN(AIDlist); i ++) { if (strncmp(AIDlist[i].aid, buf, strlen(AIDlist[i].aid)) == 0) { return AIDlist[i].vendor; } @@ -530,7 +528,7 @@ int EMVSearch(EMVCommandChannel channel, bool ActivateField, bool LeaveFieldON, int res = 0; int retrycnt = 0; - for (int i = 0; i < AIDlistLen; i ++) { + for (int i = 0; i < ARRAYLEN(AIDlist); i ++) { param_gethex_to_eol(AIDlist[i].aid, 0, aidbuf, sizeof(aidbuf), &aidlen); res = EMVSelect(channel, (i == 0) ? ActivateField : false, true, aidbuf, aidlen, data, sizeof(data), &datalen, &sw, tlv); // retry if error and not returned sw error diff --git a/client/emv/emvjson.c b/client/emv/emvjson.c index 54bd8846c..67de32701 100644 --- a/client/emv/emvjson.c +++ b/client/emv/emvjson.c @@ -57,10 +57,9 @@ static const ApplicationDataElm ApplicationData[] = { {0x00, "end..."} }; -int ApplicationDataLen = sizeof(ApplicationData) / sizeof(ApplicationDataElm); const char *GetApplicationDataName(tlv_tag_t tag) { - for (int i = 0; i < ApplicationDataLen; i++) + for (int i = 0; i < ARRAYLEN(ApplicationData); i++) if (ApplicationData[i].Tag == tag) return ApplicationData[i].Name; diff --git a/client/emv/test/crypto_test.c b/client/emv/test/crypto_test.c index 4220515df..dcac3f845 100644 --- a/client/emv/test/crypto_test.c +++ b/client/emv/test/crypto_test.c @@ -20,6 +20,7 @@ #include "../crypto.h" #include "../dump.h" #include "util_posix.h" +#include "commonutil.h" #include #include @@ -312,7 +313,7 @@ int exec_crypto_test(bool verbose) { } fprintf(stdout, "Crypto raw test: passed\n\n"); - for (i = 0; i < sizeof(keylengths) / sizeof(keylengths[0]); i++) { + for (i = 0; i < ARRAYLEN(keylengths); i++) { unsigned int kl = keylengths[i]; ret = test_genkey(kl, message, kl / 8, verbose); if (ret) { diff --git a/client/fido/fidocore.c b/client/fido/fidocore.c index 06188c5a4..1611748d8 100644 --- a/client/fido/fidocore.c +++ b/client/fido/fidocore.c @@ -150,7 +150,7 @@ fido2Desc_t fido2CmdGetInfoRespDesc[] = { }; const char *fido2GetCmdErrorDescription(uint8_t errorCode) { - for (size_t i = 0; i < sizeof(fido2Errors) / sizeof(fido2Error_t); i++) + for (size_t i = 0; i < ARRAYLEN(fido2Errors); i++) if (fido2Errors[i].ErrorCode == errorCode) return fido2Errors[i].Description; @@ -158,7 +158,7 @@ const char *fido2GetCmdErrorDescription(uint8_t errorCode) { } const char *fido2GetCmdMemberDescription(uint8_t cmdCode, bool isResponse, int memberNum) { - for (size_t i = 0; i < sizeof(fido2CmdGetInfoRespDesc) / sizeof(fido2Desc_t); i++) + for (size_t i = 0; i < ARRAYLEN(fido2CmdGetInfoRespDesc); i++) if (fido2CmdGetInfoRespDesc[i].Command == cmdCode && fido2CmdGetInfoRespDesc[i].PckType == (isResponse ? ptResponse : ptQuery) && fido2CmdGetInfoRespDesc[i].MemberNumber == memberNum) diff --git a/client/mifare/mifare4.c b/client/mifare/mifare4.c index b172e5131..486dfd371 100644 --- a/client/mifare/mifare4.c +++ b/client/mifare/mifare4.c @@ -40,10 +40,9 @@ static const PlusErrorsElm PlusErrors[] = { {0x0f, "General Manipulation Error. Failure in the operation of the PICC (cannot write to the data block), etc."}, {0x90, "OK"}, }; -int PlusErrorsLen = sizeof(PlusErrors) / sizeof(PlusErrorsElm); const char *mfpGetErrorDescription(uint8_t errorCode) { - for (int i = 0; i < PlusErrorsLen; i++) + for (int i = 0; i < ARRAYLEN(PlusErrors); i++) if (errorCode == PlusErrors[i].Code) return PlusErrors[i].Description; diff --git a/client/mifare/mifaredefault.h b/client/mifare/mifaredefault.h index 8debf3f65..4123fdf70 100644 --- a/client/mifare/mifaredefault.h +++ b/client/mifare/mifaredefault.h @@ -13,8 +13,6 @@ #include -#define MIFARE_DEFAULTKEYS_SIZE sizeof(g_mifare_default_keys) / sizeof(uint64_t) - static const uint64_t g_mifare_default_keys[] = { 0xffffffffffff, // Default key (first key used by program if no user defined key) 0x000000000000, // Blank key diff --git a/client/whereami.c b/client/whereami.c index a18d2d2f7..33d261f4d 100644 --- a/client/whereami.c +++ b/client/whereami.c @@ -69,11 +69,11 @@ static int WAI_PREFIX(getModulePath_)(HMODULE module, char *out, int capacity, i DWORD size; int length_, length__; - size = GetModuleFileNameW(module, buffer1, sizeof(buffer1) / sizeof(buffer1[0])); + size = GetModuleFileNameW(module, buffer1, ARRAYLEN(buffer1)); if (size == 0) break; - else if (size == (DWORD)(sizeof(buffer1) / sizeof(buffer1[0]))) { + else if (size == (DWORD)(ARRAYLEN(buffer1))) { DWORD size_ = size; do { wchar_t *path_; @@ -521,7 +521,7 @@ int WAI_PREFIX(getExecutablePath)(char *out, int capacity, int *dirname_length) #endif size_t size = sizeof(buffer1); - if (sysctl(mib, (u_int)(sizeof(mib) / sizeof(mib[0])), path, &size, NULL, 0) != 0) + if (sysctl(mib, (u_int)(ARRAYLEN(mib)), path, &size, NULL, 0) != 0) break; resolved = realpath(path, buffer2); From 733a7d836d8c3e5385e904dda52e641282474889 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 1 Aug 2019 00:14:09 +0200 Subject: [PATCH 0198/1854] more ARRAYLEN --- armsrc/epa.c | 4 ++-- armsrc/felica.c | 2 +- armsrc/mifarecmd.c | 2 +- client/cmddata.c | 2 +- client/cmdhfepa.c | 8 ++++---- client/cmdhficlass.c | 2 +- client/cmdhfmfp.c | 2 +- client/cmdhfmfu.c | 6 +++--- client/cmdlfhid.c | 4 ++-- client/cmdsmartcard.c | 2 +- client/loclass/cipherutils.c | 4 ++-- client/loclass/ikeys.c | 2 +- 12 files changed, 20 insertions(+), 20 deletions(-) diff --git a/armsrc/epa.c b/armsrc/epa.c index fabeec6d2..7ccb0a8f6 100644 --- a/armsrc/epa.c +++ b/armsrc/epa.c @@ -470,14 +470,14 @@ void EPA_PACE_Replay(PacketCommandNG *c) { uint8_t response_apdu[300] = {0}; // now replay the data and measure the timings - for (int i = 0; i < sizeof(apdu_lengths_replay); i++) { + for (int i = 0; i < ARRAYLEN(apdu_lengths_replay); i++) { StartCountUS(); func_return = EPA_APDU(apdus_replay[i].data, apdu_lengths_replay[i], response_apdu); timings[i] = GetCountUS(); // every step but the last one should succeed - if (i < sizeof(apdu_lengths_replay) - 1 + if (i < ARRAYLEN(apdu_lengths_replay) - 1 && (func_return < 6 || response_apdu[func_return - 4] != 0x90 || response_apdu[func_return - 3] != 0x00)) { diff --git a/armsrc/felica.c b/armsrc/felica.c index 48b6f4464..5420f56d4 100644 --- a/armsrc/felica.c +++ b/armsrc/felica.c @@ -746,7 +746,7 @@ void felica_dump_lite_s() { // for (c=0; c < 8; c++) // ndef[c] = FelicaFrame.framebytes[c+4]; - for (blknum = 0; blknum < sizeof(liteblks);) { + for (blknum = 0; blknum < ARRAYLEN(liteblks);) { // block to read. BuildFliteRdblk(ndef, 1, &liteblks[blknum]); diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 2d56a8a37..26ab16e03 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -1495,7 +1495,7 @@ OUT: uint16_t bar = 0; uint8_t j = 0; - for (uint8_t m = 64; m < sizeof(found); m++) { + for (uint8_t m = 64; m < ARRAYLEN(found); m++) { bar |= ((uint16_t)(found[m] & 1) << j++); } diff --git a/client/cmddata.c b/client/cmddata.c index 7ade24586..473c5f0b9 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -870,7 +870,7 @@ static int CmdBitsamples(const char *Cmd) { return PM3_ETIMEOUT; } - for (size_t j = 0; j < sizeof(got); j++) { + for (size_t j = 0; j < ARRAYLEN(got); j++) { for (uint8_t k = 0; k < 8; k++) { if (got[j] & (1 << (7 - k))) GraphBuffer[cnt++] = 1; diff --git a/client/cmdhfepa.c b/client/cmdhfepa.c index 9aeaabefd..a2a120764 100644 --- a/client/cmdhfepa.c +++ b/client/cmdhfepa.c @@ -75,7 +75,7 @@ static int CmdHFEPAPACEReplay(const char *Cmd) { int skip = 0, skip_add = 0, scan_return; // for each APDU - for (int i = 0; i < sizeof(apdu_lengths); i++) { + for (int i = 0; i < ARRAYLEN(apdu_lengths); i++) { // scan to next space or end of string while (Cmd[skip] != ' ' && Cmd[skip] != '\0') { // convert @@ -96,7 +96,7 @@ static int CmdHFEPAPACEReplay(const char *Cmd) { // break on EOF if (Cmd[skip] == '\0') { - if (i < sizeof(apdu_lengths) - 1) { + if (i < ARRAYLEN(apdu_lengths) - 1) { PrintAndLogEx(NORMAL, (char *)usage_msg); return 0; @@ -111,7 +111,7 @@ static int CmdHFEPAPACEReplay(const char *Cmd) { uint8_t data[PM3_CMD_DATA_SIZE]; // fast push mode conn.block_after_ACK = true; - for (int i = 0; i < sizeof(apdu_lengths); i++) { + for (int i = 0; i < ARRAYLEN(apdu_lengths); i++) { // transfer the APDU in several parts if necessary for (int j = 0; j * sizeof(data) < apdu_lengths[i]; j++) { // amount of data in this packet @@ -119,7 +119,7 @@ static int CmdHFEPAPACEReplay(const char *Cmd) { if (packet_length > sizeof(data)) { packet_length = sizeof(data); } - if ((i == sizeof(apdu_lengths) - 1) && (j * sizeof(data) >= apdu_lengths[i] - 1)) { + if ((i == ARRAYLEN(apdu_lengths) - 1) && (j * sizeof(data) >= apdu_lengths[i] - 1)) { // Disable fast mode on last packet conn.block_after_ACK = false; } diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 91757bbd4..17fd9f127 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -1570,7 +1570,7 @@ static void HFiClassCalcNewKey(uint8_t *CSN, uint8_t *OLDKEY, uint8_t *NEWKEY, u //get new div key HFiClassCalcDivKey(CSN, NEWKEY, new_div_key, elite); - for (uint8_t i = 0; i < sizeof(old_div_key); i++) { + for (uint8_t i = 0; i < ARRAYLEN(old_div_key); i++) { xor_div_key[i] = old_div_key[i] ^ new_div_key[i]; } if (verbose) { diff --git a/client/cmdhfmfp.c b/client/cmdhfmfp.c index fb1118b81..46ee6e680 100644 --- a/client/cmdhfmfp.c +++ b/client/cmdhfmfp.c @@ -227,7 +227,7 @@ static int CmdHFMFPInitPerso(const char *cmd) { } mfpSetVerboseMode(verbose); - for (int i = 0; i < sizeof(CardAddresses) / 2; i++) { + for (int i = 0; i < ARRAYLEN(CardAddresses); i++) { keyNum[0] = CardAddresses[i] >> 8; keyNum[1] = CardAddresses[i] & 0xff; res = MFPWritePerso(keyNum, key, false, true, data, sizeof(data), &datalen); diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index b7d268884..0158d3394 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -2298,7 +2298,7 @@ static int CmdHF14AMfURestore(const char *Cmd) { // otp, uid, lock, cfg1, cfg0, dynlockbits uint8_t blocks[] = {3, 0, 1, 2, pages - 5, pages - 4, pages - 3}; - for (uint8_t i = 0; i < sizeof(blocks); i++) { + for (uint8_t i = 0; i < ARRAYLEN(blocks); i++) { uint8_t b = blocks[i]; memcpy(data, mem->data + (b * 4), 4); clearCommandBuffer(); @@ -2635,12 +2635,12 @@ static int CmdHF14AMfUGenDiverseKeys(const char *Cmd) { PrintAndLogEx(NORMAL, "Message :\t %s", sprint_hex(mix, sizeof(mix))); PrintAndLogEx(NORMAL, "Diversified key: %s", sprint_hex(divkey + 1, 6)); - for (int i = 0; i < sizeof(mifarekeyA); ++i) { + for (int i = 0; i < ARRAYLEN(mifarekeyA); ++i) { dkeyA[i] = (mifarekeyA[i] << 1) & 0xff; dkeyA[6] |= ((mifarekeyA[i] >> 7) & 1) << (i + 1); } - for (int i = 0; i < sizeof(mifarekeyB); ++i) { + for (int i = 0; i < ARRAYLEN(mifarekeyB); ++i) { dkeyB[1] |= ((mifarekeyB[i] >> 7) & 1) << (i + 1); dkeyB[2 + i] = (mifarekeyB[i] << 1) & 0xff; } diff --git a/client/cmdlfhid.c b/client/cmdlfhid.c index cc395c8c5..56f9667a3 100644 --- a/client/cmdlfhid.c +++ b/client/cmdlfhid.c @@ -485,7 +485,7 @@ static int CmdHIDWiegand(const char *Cmd) { PrintAndLogEx(NORMAL, "HID | OEM | FC | CN | Wiegand | HID Formatted"); PrintAndLogEx(NORMAL, "----+-----+------+---------+-----------+--------------------"); - for (uint8_t i = 0; i < sizeof(fmtlen); i++) { + for (uint8_t i = 0; i < ARRAYLEN(fmtlen); i++) { memset(bits, 0x00, sizeof(bits)); calcWiegand(fmtlen[i], fc, cardnum, bs, oem); PrintAndLogEx(NORMAL, "ice:: %s \n", sprint_bin(bs, fmtlen[i])); @@ -545,7 +545,7 @@ static int CmdHIDBrute(const char *Cmd) { cmdp += 2; bool is_ftm_ok = false; uint8_t ftms[] = {26, 33, 34, 35, 37}; - for (uint8_t i = 0; i < sizeof(ftms); i++) { + for (uint8_t i = 0; i < ARRAYLEN(ftms); i++) { if (ftms[i] == fmtlen) { is_ftm_ok = true; } diff --git a/client/cmdsmartcard.c b/client/cmdsmartcard.c index c49f0d0e7..c2268fd2f 100644 --- a/client/cmdsmartcard.c +++ b/client/cmdsmartcard.c @@ -878,7 +878,7 @@ static void smart_brute_prim() { PrintAndLogEx(INFO, "Reading primitives"); - for (int i = 0; i < sizeof(get_card_data); i += 5) { + for (int i = 0; i < ARRAYLEN(get_card_data); i += 5) { clearCommandBuffer(); SendCommandOLD(CMD_SMART_RAW, SC_RAW_T0, 5, 0, get_card_data + i, 5); diff --git a/client/loclass/cipherutils.c b/client/loclass/cipherutils.c index c829574e9..b6bea6186 100644 --- a/client/loclass/cipherutils.c +++ b/client/loclass/cipherutils.c @@ -205,7 +205,7 @@ static int testBitStream() { } else { PrintAndLogDevice(FAILED, " Bitstream test 1 failed"); uint8_t i; - for (i = 0 ; i < sizeof(input) ; i++) { + for (i = 0 ; i < ARRAYLEN(input) ; i++) { PrintAndLogDevice(NORMAL, " IN %02x, OUT %02x", input[i], output[i]); } return 1; @@ -235,7 +235,7 @@ static int testReversedBitstream() { } else { PrintAndLogDevice(FAILED, " Bitstream test 2 failed"); uint8_t i; - for (i = 0 ; i < sizeof(input) ; i++) { + for (i = 0 ; i < ARRAYLEN(input) ; i++) { PrintAndLogDevice(NORMAL, " IN %02x, MIDDLE: %02x, OUT %02x", input[i], reverse[i], output[i]); } return 1; diff --git a/client/loclass/ikeys.c b/client/loclass/ikeys.c index 70605942f..67278e3b5 100644 --- a/client/loclass/ikeys.c +++ b/client/loclass/ikeys.c @@ -692,7 +692,7 @@ int doKeyTests(uint8_t debuglevel) { //Test if it's the right key... uint8_t i; uint8_t j = 0; - for (i = 0; i < sizeof(key); i++) + for (i = 0; i < ARRAYLEN(key); i++) j += key[i]; if (j != 185) { From b4e004abc23251dbc2a68794451f11f7a38471f6 Mon Sep 17 00:00:00 2001 From: "Colin J. Brigato" Date: Thu, 1 Aug 2019 01:56:30 +0200 Subject: [PATCH 0199/1854] Off by one in GetTickCountDelta (FIXes #301) FIXes #301 and prevent a `-1`aka`UINT_MAX` delta. --- armsrc/ticks.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/ticks.c b/armsrc/ticks.c index 7ece25b93..22c5d5be1 100644 --- a/armsrc/ticks.c +++ b/armsrc/ticks.c @@ -64,7 +64,7 @@ uint32_t RAMFUNC GetTickCount(void) { uint32_t RAMFUNC GetTickCountDelta(uint32_t start_ticks) { uint32_t stop_ticks = AT91C_BASE_RTTC->RTTC_RTVR; - if (stop_ticks > start_ticks) + if (stop_ticks >= start_ticks) return stop_ticks - start_ticks; return (UINT32_MAX - start_ticks) + stop_ticks; } From f6befc235fe65fa92dc603406d448f3eac07960a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 1 Aug 2019 00:51:53 -0400 Subject: [PATCH 0200/1854] chg: macro SRC_SPIFFS is dependent of WITH_FLASH --- armsrc/Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/armsrc/Makefile b/armsrc/Makefile index 105a880a7..a71c46dfc 100644 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@ -34,14 +34,16 @@ SRC_CRAPTO1 = crypto1.c des.c desfire_key.c desfire_crypto.c mifaredesfire.c aes SRC_CRC = crc.c crc16.c crc32.c SRC_ICLASS = iclass.c optimized_cipher.c SRC_LEGIC = legicrf.c legicrfsim.c legic_prng.c -SRC_SPIFFS = spiffs.c spiffs_cache.c spiffs_check.c spiffs_gc.c spiffs_nucleus.c spiffs_hydrogen.c + # SRC_BEE = bee.c # RDV40 related hardware support ifneq (,$(findstring WITH_FLASH,$(APP_CFLAGS))) SRC_FLASH = flashmem.c + SRC_SPIFFS = spiffs.c spiffs_cache.c spiffs_check.c spiffs_gc.c spiffs_nucleus.c spiffs_hydrogen.c else SRC_FLASH = + SRC_SPIFFS = endif ifneq (,$(findstring WITH_SMARTCARD,$(APP_CFLAGS))) From fbff51c88d6a3b9cb7ddb3124fb7b53c1a85be86 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 1 Aug 2019 09:39:33 -0400 Subject: [PATCH 0201/1854] Add: hf thinfilm info - support to read and decode Kovio Thinfilm NCT tags --- armsrc/Makefile | 2 +- armsrc/appmain.c | 5 ++ armsrc/iso14443a.c | 135 +++++++++++++++++++++++++++++++++++-- armsrc/iso14443a.h | 5 +- armsrc/thinfilm.c | 47 +++++++++++++ armsrc/thinfilm.h | 30 +++++++++ client/Makefile | 3 +- client/cmdhf.c | 6 ++ client/cmdhf.h | 1 + client/cmdhfthinfilm.c | 147 +++++++++++++++++++++++++++++++++++++++++ client/cmdhfthinfilm.h | 28 ++++++++ include/pm3_cmd.h | 3 + 12 files changed, 404 insertions(+), 8 deletions(-) create mode 100644 armsrc/thinfilm.c create mode 100644 armsrc/thinfilm.h create mode 100644 client/cmdhfthinfilm.c create mode 100644 client/cmdhfthinfilm.h diff --git a/armsrc/Makefile b/armsrc/Makefile index a71c46dfc..5475b57eb 100644 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@ -27,7 +27,7 @@ APP_CFLAGS = $(PLATFORM_DEFS) \ SRC_LF = lfops.c lfsampling.c pcf7931.c lfdemod.c SRC_ISO15693 = iso15693.c iso15693tools.c -SRC_ISO14443a = iso14443a.c mifareutil.c mifarecmd.c epa.c mifaresim.c +SRC_ISO14443a = iso14443a.c mifareutil.c mifarecmd.c epa.c mifaresim.c thinfilm.c SRC_ISO14443b = iso14443b.c SRC_FELICA = felica.c SRC_CRAPTO1 = crypto1.c des.c desfire_key.c desfire_crypto.c mifaredesfire.c aes.c platform_util.c diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 84a4748f0..4dcaac17a 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -26,6 +26,7 @@ #include "mifareutil.h" #include "mifaresim.h" #include "hitag.h" +#include "thinfilm.h" #define DEBUG 1 @@ -1278,6 +1279,10 @@ static void PacketReceived(PacketCommandNG *packet) { DetectNACKbug(); break; } + case CMD_THINFILM_READ: { + ReadThinFilm(); + break; + } #endif #ifdef WITH_ICLASS diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index a09978d7a..b6328ff19 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -463,6 +463,81 @@ RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non_real_t return false; // not finished yet, need more data } + +// Thinfilm, Kovio mangels ISO14443A in the way that they don't use start bit nor parity bits. +RAMFUNC int ManchesterDecoding_Thinfilm(uint8_t bit) { + Demod.twoBits = (Demod.twoBits << 8) | bit; + + if (Demod.state == DEMOD_UNSYNCD) { + + if (Demod.highCnt < 2) { // wait for a stable unmodulated signal + if (Demod.twoBits == 0x0000) { + Demod.highCnt++; + } else { + Demod.highCnt = 0; + } + } else { + Demod.syncBit = 0xFFFF; // not set + if ((Demod.twoBits & 0x7700) == 0x7000) Demod.syncBit = 7; + else if ((Demod.twoBits & 0x3B80) == 0x3800) Demod.syncBit = 6; + else if ((Demod.twoBits & 0x1DC0) == 0x1C00) Demod.syncBit = 5; + else if ((Demod.twoBits & 0x0EE0) == 0x0E00) Demod.syncBit = 4; + else if ((Demod.twoBits & 0x0770) == 0x0700) Demod.syncBit = 3; + else if ((Demod.twoBits & 0x03B8) == 0x0380) Demod.syncBit = 2; + else if ((Demod.twoBits & 0x01DC) == 0x01C0) Demod.syncBit = 1; + else if ((Demod.twoBits & 0x00EE) == 0x00E0) Demod.syncBit = 0; + if (Demod.syncBit != 0xFFFF) { + Demod.startTime = (GetCountSspClk() & 0xfffffff8); + Demod.startTime -= Demod.syncBit; + Demod.bitCount = 0; // number of decoded data bits + Demod.state = DEMOD_MANCHESTER_DATA; + } + } + } else { + + if (IsManchesterModulationNibble1(Demod.twoBits >> Demod.syncBit)) { // modulation in first half + if (IsManchesterModulationNibble2(Demod.twoBits >> Demod.syncBit)) { // ... and in second half = collision + if (!Demod.collisionPos) { + Demod.collisionPos = (Demod.len << 3) + Demod.bitCount; + } + } // modulation in first half only - Sequence D = 1 + Demod.bitCount++; + Demod.shiftReg = (Demod.shiftReg >> 1) | 0x100; // in both cases, add a 1 to the shiftreg + if (Demod.bitCount == 8) { // if we decoded a full byte + Demod.output[Demod.len++] = (Demod.shiftReg & 0xff); + Demod.bitCount = 0; + Demod.shiftReg = 0; + } + Demod.endTime = Demod.startTime + 8 * (8 * Demod.len + Demod.bitCount + 1) - 4; + } else { // no modulation in first half + if (IsManchesterModulationNibble2(Demod.twoBits >> Demod.syncBit)) { // and modulation in second half = Sequence E = 0 + Demod.bitCount++; + Demod.shiftReg = (Demod.shiftReg >> 1); // add a 0 to the shiftreg + if (Demod.bitCount >= 8) { // if we decoded a full byte + Demod.output[Demod.len++] = (Demod.shiftReg & 0xff); + Demod.bitCount = 0; + Demod.shiftReg = 0; + } + Demod.endTime = Demod.startTime + 8 * (8 * Demod.len + Demod.bitCount + 1); + } else { // no modulation in both halves - End of communication + if (Demod.bitCount > 0) { // there are some remaining data bits + Demod.shiftReg >>= (8 - Demod.bitCount); // right align the decoded bits + Demod.output[Demod.len++] = Demod.shiftReg & 0xff; // and add them to the output + return true; + } + if (Demod.len) { + return true; // we are finished with decoding the raw data sequence + } else { // nothing received. Start over + DemodReset(); + } + } + } + } + return false; // not finished yet, need more data +} + + + //============================================================================= // Finally, a `sniffer' for ISO 14443 Type A // Both sides of communication! @@ -579,7 +654,7 @@ void RAMFUNC SniffIso14443a(uint8_t param) { Uart.len, Uart.startTime * 16 - DELAY_READER_AIR2ARM_AS_SNIFFER, Uart.endTime * 16 - DELAY_READER_AIR2ARM_AS_SNIFFER, - Uart.parity, + Uart.parity, true)) break; } /* ready to receive another command. */ @@ -1930,6 +2005,55 @@ bool EmLogTrace(uint8_t *reader_data, uint16_t reader_len, uint32_t reader_Start } +//----------------------------------------------------------------------------- +// Kovio - Thinfilm barcode. TAG-TALK-FIRST - +// Wait a certain time for tag response +// If a response is captured return TRUE +// If it takes too long return FALSE +//----------------------------------------------------------------------------- +bool GetIso14443aAnswerFromTag_Thinfilm(uint8_t *receivedResponse, uint8_t *received_len) { + + if (!iso14443a_active) + return false; + + // Set FPGA mode to "reader listen mode", no modulation (listen + // only, since we are receiving, not transmitting). + // Signal field is on with the appropriate LED + LED_D_ON(); + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_LISTEN); + + // Now get the answer from the card + DemodInit(receivedResponse, NULL); + + // clear RXRDY: + uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + (void)b; + + uint32_t receive_timer = GetTickCount(); + for (;;) { + WDT_HIT(); + + if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { + b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + if (ManchesterDecoding_Thinfilm(b)) { + *received_len = Demod.len; + // log + LogTrace(receivedResponse, Demod.len, Demod.startTime * 16 - DELAY_AIR2ARM_AS_READER, Demod.endTime * 16 - DELAY_AIR2ARM_AS_READER, NULL, false); + return true; + } + } + + // timeout already in ms + 10ms guard time + if (GetTickCount() - receive_timer > 1160) + break; + } + *received_len = Demod.len; + // log + LogTrace(receivedResponse, Demod.len, Demod.startTime * 16 - DELAY_AIR2ARM_AS_READER, Demod.endTime * 16 - DELAY_AIR2ARM_AS_READER, NULL, false); + return false; +} + + //----------------------------------------------------------------------------- // Wait a certain time for tag response // If a response is captured return TRUE @@ -2018,6 +2142,7 @@ int ReaderReceive(uint8_t *receivedAnswer, uint8_t *par) { return Demod.len; } + // This function misstreats the ISO 14443a anticollision procedure. // by fooling the reader there is a collision and forceing the reader to // increase the uid bytes. The might be an overflow, DoS will occure. @@ -2363,8 +2488,7 @@ void iso14443a_setup(uint8_t fpga_minor_mode) { LED_D_OFF(); // Signal field is on with the appropriate LED - if (fpga_minor_mode == FPGA_HF_ISO14443A_READER_MOD || - fpga_minor_mode == FPGA_HF_ISO14443A_READER_LISTEN) + if (fpga_minor_mode == FPGA_HF_ISO14443A_READER_MOD || fpga_minor_mode == FPGA_HF_ISO14443A_READER_LISTEN) LED_D_ON(); FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | fpga_minor_mode); @@ -2382,7 +2506,8 @@ void iso14443a_setup(uint8_t fpga_minor_mode) { iso14443a_active = true; } -void iso14443a_off() { + +void iso14443a_off(void) { FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); iso14443a_active = false; @@ -2893,7 +3018,7 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) { * Mifare Classic NACK-bug detection * Thanks to @doegox for the feedback and new approaches. */ -void DetectNACKbug() { +void DetectNACKbug(void) { uint8_t mf_auth[] = {0x60, 0x00, 0xF5, 0x7B}; uint8_t mf_nr_ar[] = {0, 0, 0, 0, 0, 0, 0, 0}; uint8_t uid[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/armsrc/iso14443a.h b/armsrc/iso14443a.h index e5523c598..fab0dbdeb 100644 --- a/armsrc/iso14443a.h +++ b/armsrc/iso14443a.h @@ -132,6 +132,7 @@ int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, bool send_chaining, void *data, u int iso14443a_select_card(uint8_t *uid_ptr, iso14a_card_select_t *p_card, uint32_t *cuid_ptr, bool anticollision, uint8_t num_cascades, bool no_rats); int iso14443a_fast_select_card(uint8_t *uid_ptr, uint8_t num_cascades); void iso14a_set_trigger(bool enable); +void iso14443a_off(void); int EmSendCmd14443aRaw(uint8_t *resp, uint16_t respLen); int EmSend4bit(uint8_t resp); @@ -148,7 +149,9 @@ bool EmLogTrace(uint8_t *reader_data, uint16_t reader_len, uint32_t reader_Start uint8_t *tag_data, uint16_t tag_len, uint32_t tag_StartTime, uint32_t tag_EndTime, uint8_t *tag_Parity); void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype); -void DetectNACKbug(); +void DetectNACKbug(void); + +bool GetIso14443aAnswerFromTag_Thinfilm(uint8_t *receivedResponse, uint8_t *received_len); #ifdef __cplusplus } diff --git a/armsrc/thinfilm.c b/armsrc/thinfilm.c new file mode 100644 index 000000000..96cd062c6 --- /dev/null +++ b/armsrc/thinfilm.c @@ -0,0 +1,47 @@ +//----------------------------------------------------------------------------- +// Copyright (C) 2019 iceman +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// Routines to support a mangeled ISO 14443 type A for Thinfilm tags by Kovio +//----------------------------------------------------------------------------- + +#include "thinfilm.h" + +/** + * ref + * https://www.thinfilmnfc.com/wp-content/uploads/2017/09/Thinfilm-Kovio-NFC-Barcode-Protocol-Tag-Functional-Specification-v3.4-2017-05-26.pdf + * https://developer.android.com/reference/android/nfc/tech/NfcBarcode + * + */ + +void ReadThinFilm(void) { + + clear_trace(); + + set_tracing(true); + + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + + uint8_t len = 0; + uint8_t buf[36] = {0x00}; + + // power on and listen for answer. + bool status = GetIso14443aAnswerFromTag_Thinfilm(buf, &len); + + // lsb -> msb + for (uint8_t i = 0; i < len; i++) { + uint8_t b = buf[i]; + buf[i] = ((b * 0x0802LU & 0x22110LU) | (b * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16; + } + // Startbit is always set and used in byte + buf[0] |= 0x80; + + reply_ng(CMD_THINFILM_READ, status ? PM3_SUCCESS : PM3_ENODATA, buf, len); + + iso14443a_off(); + set_tracing(false); +} + diff --git a/armsrc/thinfilm.h b/armsrc/thinfilm.h new file mode 100644 index 000000000..cfbfd03c1 --- /dev/null +++ b/armsrc/thinfilm.h @@ -0,0 +1,30 @@ +//----------------------------------------------------------------------------- +// Iceman - August 2019 +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// Routines to support a mangeled ISO 14443 type A for Thinfilm tags by Kovio +//----------------------------------------------------------------------------- + +#ifndef __THINFILM_H +#define __THINFILM_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "pm3_cmd.h" +#include "cmd.h" +#include "apps.h" +//#include "util.h" +#include "iso14443a.h" + +void ReadThinFilm(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __ISO14443A_H */ diff --git a/client/Makefile b/client/Makefile index 440f2b888..b0544ced4 100644 --- a/client/Makefile +++ b/client/Makefile @@ -130,7 +130,7 @@ CORESRCS = uart_posix.c \ crc16.c \ comms.c -CMDSRCS = crapto1/crapto1.c \ +CMDSRCS = crapto1/crapto1.c \ crapto1/crypto1.c \ mifare/mfkey.c \ tea.c \ @@ -199,6 +199,7 @@ CMDSRCS = crapto1/crapto1.c \ cmdhftopaz.c \ cmdhffido.c \ cmdhffelica.c \ + cmdhfthinfilm.c \ cmdhw.c \ cmdlf.c \ cmdlfawid.c \ diff --git a/client/cmdhf.c b/client/cmdhf.c index 697aa9b62..2465641db 100644 --- a/client/cmdhf.c +++ b/client/cmdhf.c @@ -54,6 +54,11 @@ int CmdHFSearch(const char *Cmd) { PrintAndLogEx(INFO, "Checking for known tags...\n"); + if (infoThinFilm() == PM3_SUCCESS) { + PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Thinfilm tag") " found\n"); + return 1; + } + if (infoHF14A(false, false) > 0) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("ISO14443-A tag") " found\n"); return 1; @@ -160,6 +165,7 @@ static command_t CommandTable[] = { {"mfdes", CmdHFMFDes, AlwaysAvailable, "{ MIFARE Desfire RFIDs... }"}, {"topaz", CmdHFTopaz, AlwaysAvailable, "{ TOPAZ (NFC Type 1) RFIDs... }"}, {"fido", CmdHFFido, AlwaysAvailable, "{ FIDO and FIDO2 authenticators... }"}, + {"thinfilm", CmdHFThinfilm, AlwaysAvailable, "{ Thinfilm RFIDs... }"}, {"list", CmdTraceList, AlwaysAvailable, "List protocol data in trace buffer"}, {"tune", CmdHFTune, IfPm3Present, "Continuously measure HF antenna tuning"}, {"search", CmdHFSearch, AlwaysAvailable, "Search for known HF tags [preliminary]"}, diff --git a/client/cmdhf.h b/client/cmdhf.h index 4540caf3d..cd0ae5db5 100644 --- a/client/cmdhf.h +++ b/client/cmdhf.h @@ -31,6 +31,7 @@ #include "cmdhftopaz.h" // TOPAZ #include "cmdhffelica.h" // ISO18092 / FeliCa #include "cmdhffido.h" // FIDO authenticators +#include "cmdhfthinfilm.h" // Thinfilm #include "cmdtrace.h" // trace list int CmdHF(const char *Cmd); diff --git a/client/cmdhfthinfilm.c b/client/cmdhfthinfilm.c new file mode 100644 index 000000000..970ddfee5 --- /dev/null +++ b/client/cmdhfthinfilm.c @@ -0,0 +1,147 @@ +//----------------------------------------------------------------------------- +// Copyright (C) 2019 iceman +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// Thinfilm commands +//----------------------------------------------------------------------------- +#include "cmdhfthinfilm.h" + +static int CmdHelp(const char *Cmd); + +static int usage_thinfilm_info(void) { + PrintAndLogEx(NORMAL, "Usage: hf thin info [h]"); + PrintAndLogEx(NORMAL, "Options:"); + PrintAndLogEx(NORMAL, " h this help"); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Examples:"); + PrintAndLogEx(NORMAL, " hf thin info"); + return PM3_SUCCESS; +} + + +// Printing function based upon the code in libnfc +// ref +// https://github.com/nfc-tools/libnfc/blob/master/utils/nfc-barcode.c +static int print_barcode(uint8_t *barcode, const size_t barcode_len) { + + PrintAndLogEx(SUCCESS, " Manufacturer : "_YELLOW_("%s") "[0x%02X]", (barcode[0] == 0xB7) ? "Thinfilm" : "unknown", barcode[0] ); + PrintAndLogEx(SUCCESS, " Data format : "_YELLOW_("%02X"), barcode[1]); + PrintAndLogEx(SUCCESS, " Raw data : "_YELLOW_("%s"), sprint_hex(barcode, barcode_len) ); + + char s[45]; + memset(s, 0x00, sizeof(s)); + + switch (barcode[1]) { + case 0: + printf("Data Format Field: Reserved for allocation by tag manufacturer\n"); + return PM3_SUCCESS; + case 1: + snprintf(s, sizeof(s), "http://www." ); + break; + case 2: + snprintf(s, sizeof(s), "https://www."); + break; + case 3: + snprintf(s, sizeof(s), "http://"); + break; + case 4: + snprintf(s, sizeof(s), "https://"); + break; + case 5: + PrintAndLogEx(SUCCESS, "EPC: %s", sprint_hex(barcode + 2, 12) ); + return PM3_SUCCESS; + default: + PrintAndLogEx(SUCCESS, "Data Format Field: unknown (%02X)", barcode[1]); + PrintAndLogEx(SUCCESS, "Data:" _YELLOW_("%s"), sprint_hex(barcode + 2, barcode_len - 2) ); + return PM3_SUCCESS; + } + + snprintf(s + strlen(s), barcode_len - 1, (const char*)&barcode[2] , barcode_len - 2); + + for (uint8_t i = 0; i < strlen(s); i++) { + + // terminate string + if (s[i] == 0xFE) { + s[i] = 0; + break; + } + } + PrintAndLogEx(SUCCESS, " Decoded NFC URL : "_YELLOW_("%s"), s); + return PM3_SUCCESS; +} + + +static int CmdHfThinFilmInfo(const char *Cmd) { + + uint8_t cmdp = 0; + bool errors = false; + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { + case 'h': + return usage_thinfilm_info(); + default: + PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } + } + + //Validations + if (errors) { + usage_thinfilm_info(); + return PM3_EINVARG; + } + + return infoThinFilm(); +} + +int infoThinFilm(void) { + + clearCommandBuffer(); + SendCommandNG(CMD_THINFILM_READ, NULL, 0); + + PacketResponseNG resp; + if (!WaitForResponseTimeout(CMD_THINFILM_READ, &resp, 1500)) { + PrintAndLogEx(WARNING, "timeout while waiting for reply."); + return PM3_ETIMEOUT; + } + + if ( resp.status == PM3_SUCCESS ) { + print_barcode( resp.data.asBytes, resp.length - 2); + } + + return resp.status; +} + +static int CmdHfThinFilmSim(const char *Cmd) { + PrintAndLogEx(INFO, "To be implemented"); + return PM3_ENOTIMPL; +} + +static int CmdHfThinFilmList(const char *Cmd) { + (void)Cmd; // Cmd is not used so far + CmdTraceList("14a"); + return PM3_SUCCESS; +} + +static command_t CommandTable[] = { + {"help", CmdHelp, AlwaysAvailable, "This help"}, + {"info", CmdHfThinFilmInfo, IfPm3Flash, "Tag information"}, + {"list", CmdHfThinFilmList, AlwaysAvailable, "List ISO 14443A / Thinfilm history - not correct"}, + {"sim", CmdHfThinFilmSim, IfPm3Flash, "Fake Thinfilm tag"}, + {NULL, NULL, NULL, NULL} +}; + +static int CmdHelp(const char *Cmd) { + (void)Cmd; // Cmd is not used so far + CmdsHelp(CommandTable); + return PM3_SUCCESS; +} + +int CmdHFThinfilm(const char *Cmd) { + clearCommandBuffer(); + return CmdsParse(CommandTable, Cmd); +} diff --git a/client/cmdhfthinfilm.h b/client/cmdhfthinfilm.h new file mode 100644 index 000000000..f67084cbd --- /dev/null +++ b/client/cmdhfthinfilm.h @@ -0,0 +1,28 @@ +//----------------------------------------------------------------------------- +// Copyright (C) 2019 iceman +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// Thinfilm commands +//----------------------------------------------------------------------------- + +#ifndef CMDHFTHINFILM_H__ +#define CMDHFTHINFILM_H__ + +#include +#include +#include +#include "common.h" +#include "proxmark3.h" +#include "ui.h" +#include "cmdparser.h" +#include "util.h" +#include "cmdhf.h" // list cmd + +int infoThinFilm(void); + +int CmdHFThinfilm(const char *Cmd); + +#endif diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index e8ff526d7..de4a622e4 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -494,6 +494,9 @@ typedef struct { #define CMD_EMV_LOAD_VALUE 0x0707 #define CMD_EMV_DUMP_CARD 0x0708 +// For ThinFilm Kovio +#define CMD_THINFILM_READ 0x0810 + #define CMD_UNKNOWN 0xFFFF //Mifare simulation flags From fe90412bc00d022ffefadd237f8e0be6c336ac37 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 1 Aug 2019 09:42:27 -0400 Subject: [PATCH 0202/1854] textual --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 074367de1..a6edb72ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Add 'hf thinfilm info' - read / decode Kovio Thinfilm NFC barcode tags (@iceman1001) - Add FPGA LF adc path (@anon) - Add ECC support / check for NID_secp128r1 (@pwpiwi) - Add some more default keys (ollibolli) From 3fb442798d11cce16e50ec9ca6e71beb9543e7f6 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 1 Aug 2019 15:49:20 +0200 Subject: [PATCH 0203/1854] thinfilm usage typo --- client/cmdhfthinfilm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/cmdhfthinfilm.c b/client/cmdhfthinfilm.c index 970ddfee5..d75144feb 100644 --- a/client/cmdhfthinfilm.c +++ b/client/cmdhfthinfilm.c @@ -12,12 +12,12 @@ static int CmdHelp(const char *Cmd); static int usage_thinfilm_info(void) { - PrintAndLogEx(NORMAL, "Usage: hf thin info [h]"); + PrintAndLogEx(NORMAL, "Usage: hf thinfilm info [h]"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h this help"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf thin info"); + PrintAndLogEx(NORMAL, " hf thinfilm info"); return PM3_SUCCESS; } From 118c8478f00b5f86165f5e4befd655c090893f86 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 1 Aug 2019 16:55:20 +0200 Subject: [PATCH 0204/1854] fix ManchesterDecoding_Thinfilm (msb was always forced to 0) --- armsrc/iso14443a.c | 9 +++++---- armsrc/thinfilm.c | 9 --------- 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index b6328ff19..2618bec44 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -489,7 +489,8 @@ RAMFUNC int ManchesterDecoding_Thinfilm(uint8_t bit) { if (Demod.syncBit != 0xFFFF) { Demod.startTime = (GetCountSspClk() & 0xfffffff8); Demod.startTime -= Demod.syncBit; - Demod.bitCount = 0; // number of decoded data bits + Demod.bitCount = 1; // number of decoded data bits + Demod.shiftReg = 1; Demod.state = DEMOD_MANCHESTER_DATA; } } @@ -502,7 +503,7 @@ RAMFUNC int ManchesterDecoding_Thinfilm(uint8_t bit) { } } // modulation in first half only - Sequence D = 1 Demod.bitCount++; - Demod.shiftReg = (Demod.shiftReg >> 1) | 0x100; // in both cases, add a 1 to the shiftreg + Demod.shiftReg = (Demod.shiftReg << 1) | 0x1; // in both cases, add a 1 to the shiftreg if (Demod.bitCount == 8) { // if we decoded a full byte Demod.output[Demod.len++] = (Demod.shiftReg & 0xff); Demod.bitCount = 0; @@ -512,7 +513,7 @@ RAMFUNC int ManchesterDecoding_Thinfilm(uint8_t bit) { } else { // no modulation in first half if (IsManchesterModulationNibble2(Demod.twoBits >> Demod.syncBit)) { // and modulation in second half = Sequence E = 0 Demod.bitCount++; - Demod.shiftReg = (Demod.shiftReg >> 1); // add a 0 to the shiftreg + Demod.shiftReg = (Demod.shiftReg << 1); // add a 0 to the shiftreg if (Demod.bitCount >= 8) { // if we decoded a full byte Demod.output[Demod.len++] = (Demod.shiftReg & 0xff); Demod.bitCount = 0; @@ -521,7 +522,7 @@ RAMFUNC int ManchesterDecoding_Thinfilm(uint8_t bit) { Demod.endTime = Demod.startTime + 8 * (8 * Demod.len + Demod.bitCount + 1); } else { // no modulation in both halves - End of communication if (Demod.bitCount > 0) { // there are some remaining data bits - Demod.shiftReg >>= (8 - Demod.bitCount); // right align the decoded bits + Demod.shiftReg <<= (8 - Demod.bitCount); // left align the decoded bits Demod.output[Demod.len++] = Demod.shiftReg & 0xff; // and add them to the output return true; } diff --git a/armsrc/thinfilm.c b/armsrc/thinfilm.c index 96cd062c6..1d43ed10a 100644 --- a/armsrc/thinfilm.c +++ b/armsrc/thinfilm.c @@ -30,15 +30,6 @@ void ReadThinFilm(void) { // power on and listen for answer. bool status = GetIso14443aAnswerFromTag_Thinfilm(buf, &len); - - // lsb -> msb - for (uint8_t i = 0; i < len; i++) { - uint8_t b = buf[i]; - buf[i] = ((b * 0x0802LU & 0x22110LU) | (b * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16; - } - // Startbit is always set and used in byte - buf[0] |= 0x80; - reply_ng(CMD_THINFILM_READ, status ? PM3_SUCCESS : PM3_ENODATA, buf, len); iso14443a_off(); From 8f6c0484812ebd86c0f16b9aa011298f238c0ea0 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 1 Aug 2019 17:07:07 +0200 Subject: [PATCH 0205/1854] thinfilm: fix urls with 0xFE terminator --- client/cmdhfthinfilm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdhfthinfilm.c b/client/cmdhfthinfilm.c index d75144feb..f401969bd 100644 --- a/client/cmdhfthinfilm.c +++ b/client/cmdhfthinfilm.c @@ -64,7 +64,7 @@ static int print_barcode(uint8_t *barcode, const size_t barcode_len) { for (uint8_t i = 0; i < strlen(s); i++) { // terminate string - if (s[i] == 0xFE) { + if ((uint8_t) s[i] == 0xFE) { s[i] = 0; break; } From a331090c6a939d44152ab9fdf35fe097b7d58996 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 1 Aug 2019 11:09:51 -0400 Subject: [PATCH 0206/1854] Chg : 'hf thinfilm info' - added crc check --- client/cmdhfthinfilm.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/client/cmdhfthinfilm.c b/client/cmdhfthinfilm.c index d75144feb..38595f3f5 100644 --- a/client/cmdhfthinfilm.c +++ b/client/cmdhfthinfilm.c @@ -29,8 +29,17 @@ static int print_barcode(uint8_t *barcode, const size_t barcode_len) { PrintAndLogEx(SUCCESS, " Manufacturer : "_YELLOW_("%s") "[0x%02X]", (barcode[0] == 0xB7) ? "Thinfilm" : "unknown", barcode[0] ); PrintAndLogEx(SUCCESS, " Data format : "_YELLOW_("%02X"), barcode[1]); - PrintAndLogEx(SUCCESS, " Raw data : "_YELLOW_("%s"), sprint_hex(barcode, barcode_len) ); - + + uint8_t b1, b2; + compute_crc(CRC_14443_A, barcode, barcode_len - 2, &b1, &b2); + bool isok = (barcode[barcode_len - 1] == b1 && barcode[barcode_len - 2] == b2); + + PrintAndLogEx(SUCCESS, " checksum : "_YELLOW_("%02X %02X")"- %s", b2, b1, (isok) ? _GREEN_("OK") : _RED_("fail")); + PrintAndLogEx(SUCCESS, " Raw data : "_YELLOW_("%s"), + sprint_hex(barcode, barcode_len) + ); + + char s[45]; memset(s, 0x00, sizeof(s)); @@ -59,7 +68,7 @@ static int print_barcode(uint8_t *barcode, const size_t barcode_len) { return PM3_SUCCESS; } - snprintf(s + strlen(s), barcode_len - 1, (const char*)&barcode[2] , barcode_len - 2); + snprintf(s + strlen(s), barcode_len - 3, (const char*)&barcode[2] , barcode_len - 4); for (uint8_t i = 0; i < strlen(s); i++) { @@ -109,8 +118,8 @@ int infoThinFilm(void) { return PM3_ETIMEOUT; } - if ( resp.status == PM3_SUCCESS ) { - print_barcode( resp.data.asBytes, resp.length - 2); + if ( resp.status == PM3_SUCCESS ) { + print_barcode( resp.data.asBytes, resp.length ); } return resp.status; From 240041806792fd715799c0ef12e5104794591859 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 1 Aug 2019 11:15:39 -0400 Subject: [PATCH 0207/1854] style --- armsrc/Standalone/hf_colin.c | 99 +- armsrc/frozen.c | 2052 +++++++++++++++++----------------- armsrc/frozen.h | 48 +- armsrc/iso14443a.c | 68 +- armsrc/nprintf.c | 1247 ++++++++++----------- armsrc/nprintf.h | 16 +- armsrc/string.c | 214 ++-- armsrc/string.h | 4 +- client/cmdhfthinfilm.c | 30 +- client/cmdhftopaz.c | 14 +- fpga/lo_adc.v | 4 +- 11 files changed, 1882 insertions(+), 1914 deletions(-) diff --git a/armsrc/Standalone/hf_colin.c b/armsrc/Standalone/hf_colin.c index 64c5b35db..76e705afe 100644 --- a/armsrc/Standalone/hf_colin.c +++ b/armsrc/Standalone/hf_colin.c @@ -85,7 +85,8 @@ static const uint8_t is_hex[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; static inline uint64_t hex2i(const char *s) { uint64_t val = 0; @@ -333,41 +334,41 @@ void RunMod() { uint64_t key64; // Defines current key uint8_t *keyBlock; // Where the keys will be held in memory. -/* VIGIK EXPIRED DUMP FOR STUDY -Sector 0 -121C7F730208040001FA33F5CB2D021D -44001049164916491649000000000000 -00000000000000000000000000000000 -A0A1A2A3A4A579678800010203040506 -Sector 1 -0F000000000000000000000000000000 -AA0700002102080000740C110600AF13 -000000000000000001740C1108220000 -314B4947495679678800010203040506 -Sector 2 -24E572B923A3D243B402D60CAB576956 -216D6501FC8618B6C426762511AC2DEE -25BF4CEC3618D0BAB3A6E9210D887746 -314B4947495679678800010203040506 -Sector 3 -0FBC41A5D95398E76A1B2029E8EA9735 -088BA2CE732653D0C1147596AFCF94D7 -77B4D91F0442182273A29DEAF7A2D095 -314B4947495679678800010203040506 -Sector 4 -4CEE715866E508CDBC95C640EC9D1E58 -E800457CF8B079414E1B45DD3E6C9317 -77B4D91F0442182273A29DEAF7A2D095 -314B4947495679678800010203040506 -010203040506 0 -Sector 5-0F -00000000000000000000000000000000 -00000000000000000000000000000000 -00000000000000000000000000000000 -FFFFFFFFFFFFFF078069FFFFFFFFFFFF -KEY A : 1KGIV ; -ACCBITS : 796788[00]+VALUE -*/ + /* VIGIK EXPIRED DUMP FOR STUDY + Sector 0 + 121C7F730208040001FA33F5CB2D021D + 44001049164916491649000000000000 + 00000000000000000000000000000000 + A0A1A2A3A4A579678800010203040506 + Sector 1 + 0F000000000000000000000000000000 + AA0700002102080000740C110600AF13 + 000000000000000001740C1108220000 + 314B4947495679678800010203040506 + Sector 2 + 24E572B923A3D243B402D60CAB576956 + 216D6501FC8618B6C426762511AC2DEE + 25BF4CEC3618D0BAB3A6E9210D887746 + 314B4947495679678800010203040506 + Sector 3 + 0FBC41A5D95398E76A1B2029E8EA9735 + 088BA2CE732653D0C1147596AFCF94D7 + 77B4D91F0442182273A29DEAF7A2D095 + 314B4947495679678800010203040506 + Sector 4 + 4CEE715866E508CDBC95C640EC9D1E58 + E800457CF8B079414E1B45DD3E6C9317 + 77B4D91F0442182273A29DEAF7A2D095 + 314B4947495679678800010203040506 + 010203040506 0 + Sector 5-0F + 00000000000000000000000000000000 + 00000000000000000000000000000000 + 00000000000000000000000000000000 + FFFFFFFFFFFFFF078069FFFFFFFFFFFF + KEY A : 1KGIV ; + ACCBITS : 796788[00]+VALUE + */ //---------------------------- // Set of keys to be used. @@ -702,18 +703,18 @@ readysim: uint16_t flags; switch (p_card.uidlen) { - case 10: - flags = FLAG_10B_UID_IN_DATA; - break; - case 7: - flags = FLAG_7B_UID_IN_DATA; - break; - case 4: - flags = FLAG_4B_UID_IN_DATA; - break; - default: - flags = FLAG_UID_IN_EMUL; - break; + case 10: + flags = FLAG_10B_UID_IN_DATA; + break; + case 7: + flags = FLAG_7B_UID_IN_DATA; + break; + case 4: + flags = FLAG_4B_UID_IN_DATA; + break; + default: + flags = FLAG_UID_IN_EMUL; + break; } // Use UID, SAK, ATQA from EMUL, if uid not defined @@ -1031,7 +1032,7 @@ int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *data } if ((mifare_sendcmd_short(NULL, 0, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 1) || - (receivedAnswer[0] != 0x0a)) { + (receivedAnswer[0] != 0x0a)) { DbprintfEx(FLAG_NEWLINE, "write block send command error"); break; }; diff --git a/armsrc/frozen.c b/armsrc/frozen.c index f467f9554..5af6faad8 100644 --- a/armsrc/frozen.c +++ b/armsrc/frozen.c @@ -29,7 +29,7 @@ #include "BigBuf.h" #define malloc(X) BigBuf_malloc(X) -#define free(X) +#define free(X) #if !defined(WEAK) #if (defined(__GNUC__) || defined(__TI_COMPILER_VERSION__)) && !defined(_WIN32) @@ -78,22 +78,22 @@ typedef unsigned _int64 uint64_t; #endif struct frozen { - const char *end; - const char *cur; + const char *end; + const char *cur; - const char *cur_name; - size_t cur_name_len; + const char *cur_name; + size_t cur_name_len; - /* For callback API */ - char path[JSON_MAX_PATH_LEN]; - size_t path_len; - void *callback_data; - json_walk_callback_t callback; + /* For callback API */ + char path[JSON_MAX_PATH_LEN]; + size_t path_len; + void *callback_data; + json_walk_callback_t callback; }; struct fstate { - const char *ptr; - size_t path_len; + const char *ptr; + size_t path_len; }; #define SET_STATE(fr, ptr, str, len) \ @@ -117,18 +117,18 @@ struct fstate { } while (0) static int json_append_to_path(struct frozen *f, const char *str, int size) { - int n = f->path_len; - int left = sizeof(f->path) - n - 1; - if (size > left) size = left; - memcpy(f->path + n, str, size); - f->path[n + size] = '\0'; - f->path_len += size; - return n; + int n = f->path_len; + int left = sizeof(f->path) - n - 1; + if (size > left) size = left; + memcpy(f->path + n, str, size); + f->path[n + size] = '\0'; + f->path_len += size; + return n; } static void json_truncate_path(struct frozen *f, size_t len) { - f->path_len = len; - f->path[len] = '\0'; + f->path_len = len; + f->path[len] = '\0'; } static int json_parse_object(struct frozen *f); @@ -148,660 +148,660 @@ static int json_parse_value(struct frozen *f); #define END_OF_STRING (-1) static int json_left(const struct frozen *f) { - return f->end - f->cur; + return f->end - f->cur; } static int json_isspace(int ch) { - return ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n'; + return ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n'; } static void json_skip_whitespaces(struct frozen *f) { - while (f->cur < f->end && json_isspace(*f->cur)) f->cur++; + while (f->cur < f->end && json_isspace(*f->cur)) f->cur++; } static int json_cur(struct frozen *f) { - json_skip_whitespaces(f); - return f->cur >= f->end ? END_OF_STRING : *(unsigned char *) f->cur; + json_skip_whitespaces(f); + return f->cur >= f->end ? END_OF_STRING : *(unsigned char *) f->cur; } static int json_test_and_skip(struct frozen *f, int expected) { - int ch = json_cur(f); - if (ch == expected) { - f->cur++; - return 0; - } - return ch == END_OF_STRING ? JSON_STRING_INCOMPLETE : JSON_STRING_INVALID; + int ch = json_cur(f); + if (ch == expected) { + f->cur++; + return 0; + } + return ch == END_OF_STRING ? JSON_STRING_INCOMPLETE : JSON_STRING_INVALID; } static int json_isalpha(int ch) { - return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'); + return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'); } static int json_isdigit(int ch) { - return ch >= '0' && ch <= '9'; + return ch >= '0' && ch <= '9'; } static int json_isxdigit(int ch) { - return json_isdigit(ch) || (ch >= 'a' && ch <= 'f') || - (ch >= 'A' && ch <= 'F'); + return json_isdigit(ch) || (ch >= 'a' && ch <= 'f') || + (ch >= 'A' && ch <= 'F'); } static int json_get_escape_len(const char *s, int len) { - switch (*s) { - case 'u': - return len < 6 ? JSON_STRING_INCOMPLETE - : json_isxdigit(s[1]) && json_isxdigit(s[2]) && - json_isxdigit(s[3]) && json_isxdigit(s[4]) - ? 5 - : JSON_STRING_INVALID; - case '"': - case '\\': - case '/': - case 'b': - case 'f': - case 'n': - case 'r': - case 't': - return len < 2 ? JSON_STRING_INCOMPLETE : 1; - default: - return JSON_STRING_INVALID; - } + switch (*s) { + case 'u': + return len < 6 ? JSON_STRING_INCOMPLETE + : json_isxdigit(s[1]) && json_isxdigit(s[2]) && + json_isxdigit(s[3]) && json_isxdigit(s[4]) + ? 5 + : JSON_STRING_INVALID; + case '"': + case '\\': + case '/': + case 'b': + case 'f': + case 'n': + case 'r': + case 't': + return len < 2 ? JSON_STRING_INCOMPLETE : 1; + default: + return JSON_STRING_INVALID; + } } /* identifier = letter { letter | digit | '_' } */ static int json_parse_identifier(struct frozen *f) { - EXPECT(json_isalpha(json_cur(f)), JSON_STRING_INVALID); - { - SET_STATE(f, f->cur, "", 0); - while (f->cur < f->end && - (*f->cur == '_' || json_isalpha(*f->cur) || json_isdigit(*f->cur))) { - f->cur++; + EXPECT(json_isalpha(json_cur(f)), JSON_STRING_INVALID); + { + SET_STATE(f, f->cur, "", 0); + while (f->cur < f->end && + (*f->cur == '_' || json_isalpha(*f->cur) || json_isdigit(*f->cur))) { + f->cur++; + } + json_truncate_path(f, fstate.path_len); + CALL_BACK(f, JSON_TYPE_STRING, fstate.ptr, f->cur - fstate.ptr); } - json_truncate_path(f, fstate.path_len); - CALL_BACK(f, JSON_TYPE_STRING, fstate.ptr, f->cur - fstate.ptr); - } - return 0; + return 0; } static int json_get_utf8_char_len(unsigned char ch) { - if ((ch & 0x80) == 0) return 1; - switch (ch & 0xf0) { - case 0xf0: - return 4; - case 0xe0: - return 3; - default: - return 2; - } + if ((ch & 0x80) == 0) return 1; + switch (ch & 0xf0) { + case 0xf0: + return 4; + case 0xe0: + return 3; + default: + return 2; + } } /* string = '"' { quoted_printable_chars } '"' */ static int json_parse_string(struct frozen *f) { - int n, ch = 0, len = 0; - TRY(json_test_and_skip(f, '"')); - { - SET_STATE(f, f->cur, "", 0); - for (; f->cur < f->end; f->cur += len) { - ch = *(unsigned char *) f->cur; - len = json_get_utf8_char_len((unsigned char) ch); - EXPECT(ch >= 32 && len > 0, JSON_STRING_INVALID); /* No control chars */ - EXPECT(len <= json_left(f), JSON_STRING_INCOMPLETE); - if (ch == '\\') { - EXPECT((n = json_get_escape_len(f->cur + 1, json_left(f))) > 0, n); - len += n; - } else if (ch == '"') { - json_truncate_path(f, fstate.path_len); - CALL_BACK(f, JSON_TYPE_STRING, fstate.ptr, f->cur - fstate.ptr); - f->cur++; - break; - }; + int n, ch = 0, len = 0; + TRY(json_test_and_skip(f, '"')); + { + SET_STATE(f, f->cur, "", 0); + for (; f->cur < f->end; f->cur += len) { + ch = *(unsigned char *) f->cur; + len = json_get_utf8_char_len((unsigned char) ch); + EXPECT(ch >= 32 && len > 0, JSON_STRING_INVALID); /* No control chars */ + EXPECT(len <= json_left(f), JSON_STRING_INCOMPLETE); + if (ch == '\\') { + EXPECT((n = json_get_escape_len(f->cur + 1, json_left(f))) > 0, n); + len += n; + } else if (ch == '"') { + json_truncate_path(f, fstate.path_len); + CALL_BACK(f, JSON_TYPE_STRING, fstate.ptr, f->cur - fstate.ptr); + f->cur++; + break; + }; + } } - } - return ch == '"' ? 0 : JSON_STRING_INCOMPLETE; + return ch == '"' ? 0 : JSON_STRING_INCOMPLETE; } /* number = [ '-' ] digit+ [ '.' digit+ ] [ ['e'|'E'] ['+'|'-'] digit+ ] */ static int json_parse_number(struct frozen *f) { - int ch = json_cur(f); - SET_STATE(f, f->cur, "", 0); - if (ch == '-') f->cur++; - EXPECT(f->cur < f->end, JSON_STRING_INCOMPLETE); - if (f->cur + 1 < f->end && f->cur[0] == '0' && f->cur[1] == 'x') { - f->cur += 2; + int ch = json_cur(f); + SET_STATE(f, f->cur, "", 0); + if (ch == '-') f->cur++; EXPECT(f->cur < f->end, JSON_STRING_INCOMPLETE); - EXPECT(json_isxdigit(f->cur[0]), JSON_STRING_INVALID); - while (f->cur < f->end && json_isxdigit(f->cur[0])) f->cur++; - } else { - EXPECT(json_isdigit(f->cur[0]), JSON_STRING_INVALID); - while (f->cur < f->end && json_isdigit(f->cur[0])) f->cur++; - if (f->cur < f->end && f->cur[0] == '.') { - f->cur++; - EXPECT(f->cur < f->end, JSON_STRING_INCOMPLETE); - EXPECT(json_isdigit(f->cur[0]), JSON_STRING_INVALID); - while (f->cur < f->end && json_isdigit(f->cur[0])) f->cur++; + if (f->cur + 1 < f->end && f->cur[0] == '0' && f->cur[1] == 'x') { + f->cur += 2; + EXPECT(f->cur < f->end, JSON_STRING_INCOMPLETE); + EXPECT(json_isxdigit(f->cur[0]), JSON_STRING_INVALID); + while (f->cur < f->end && json_isxdigit(f->cur[0])) f->cur++; + } else { + EXPECT(json_isdigit(f->cur[0]), JSON_STRING_INVALID); + while (f->cur < f->end && json_isdigit(f->cur[0])) f->cur++; + if (f->cur < f->end && f->cur[0] == '.') { + f->cur++; + EXPECT(f->cur < f->end, JSON_STRING_INCOMPLETE); + EXPECT(json_isdigit(f->cur[0]), JSON_STRING_INVALID); + while (f->cur < f->end && json_isdigit(f->cur[0])) f->cur++; + } + if (f->cur < f->end && (f->cur[0] == 'e' || f->cur[0] == 'E')) { + f->cur++; + EXPECT(f->cur < f->end, JSON_STRING_INCOMPLETE); + if ((f->cur[0] == '+' || f->cur[0] == '-')) f->cur++; + EXPECT(f->cur < f->end, JSON_STRING_INCOMPLETE); + EXPECT(json_isdigit(f->cur[0]), JSON_STRING_INVALID); + while (f->cur < f->end && json_isdigit(f->cur[0])) f->cur++; + } } - if (f->cur < f->end && (f->cur[0] == 'e' || f->cur[0] == 'E')) { - f->cur++; - EXPECT(f->cur < f->end, JSON_STRING_INCOMPLETE); - if ((f->cur[0] == '+' || f->cur[0] == '-')) f->cur++; - EXPECT(f->cur < f->end, JSON_STRING_INCOMPLETE); - EXPECT(json_isdigit(f->cur[0]), JSON_STRING_INVALID); - while (f->cur < f->end && json_isdigit(f->cur[0])) f->cur++; - } - } - json_truncate_path(f, fstate.path_len); - CALL_BACK(f, JSON_TYPE_NUMBER, fstate.ptr, f->cur - fstate.ptr); - return 0; + json_truncate_path(f, fstate.path_len); + CALL_BACK(f, JSON_TYPE_NUMBER, fstate.ptr, f->cur - fstate.ptr); + return 0; } #if JSON_ENABLE_ARRAY /* array = '[' [ value { ',' value } ] ']' */ static int json_parse_array(struct frozen *f) { - int i = 0, current_path_len; - char buf[20]; - CALL_BACK(f, JSON_TYPE_ARRAY_START, NULL, 0); - TRY(json_test_and_skip(f, '[')); - { + int i = 0, current_path_len; + char buf[20]; + CALL_BACK(f, JSON_TYPE_ARRAY_START, NULL, 0); + TRY(json_test_and_skip(f, '[')); { - SET_STATE(f, f->cur - 1, "", 0); - while (json_cur(f) != ']') { - snprintf(buf, sizeof(buf), "[%d]", i); - i++; - current_path_len = json_append_to_path(f, buf, strlen(buf)); - f->cur_name = - f->path + strlen(f->path) - strlen(buf) + 1 /*opening brace*/; - f->cur_name_len = strlen(buf) - 2 /*braces*/; - TRY(json_parse_value(f)); - json_truncate_path(f, current_path_len); - if (json_cur(f) == ',') f->cur++; - } - TRY(json_test_and_skip(f, ']')); - json_truncate_path(f, fstate.path_len); - CALL_BACK(f, JSON_TYPE_ARRAY_END, fstate.ptr, f->cur - fstate.ptr); + { + SET_STATE(f, f->cur - 1, "", 0); + while (json_cur(f) != ']') { + snprintf(buf, sizeof(buf), "[%d]", i); + i++; + current_path_len = json_append_to_path(f, buf, strlen(buf)); + f->cur_name = + f->path + strlen(f->path) - strlen(buf) + 1 /*opening brace*/; + f->cur_name_len = strlen(buf) - 2 /*braces*/; + TRY(json_parse_value(f)); + json_truncate_path(f, current_path_len); + if (json_cur(f) == ',') f->cur++; + } + TRY(json_test_and_skip(f, ']')); + json_truncate_path(f, fstate.path_len); + CALL_BACK(f, JSON_TYPE_ARRAY_END, fstate.ptr, f->cur - fstate.ptr); + } } - } - return 0; + return 0; } #endif /* JSON_ENABLE_ARRAY */ static int json_expect(struct frozen *f, const char *s, int len, enum json_token_type tok_type) { - int i, n = json_left(f); - SET_STATE(f, f->cur, "", 0); - for (i = 0; i < len; i++) { - if (i >= n) return JSON_STRING_INCOMPLETE; - if (f->cur[i] != s[i]) return JSON_STRING_INVALID; - } - f->cur += len; - json_truncate_path(f, fstate.path_len); + int i, n = json_left(f); + SET_STATE(f, f->cur, "", 0); + for (i = 0; i < len; i++) { + if (i >= n) return JSON_STRING_INCOMPLETE; + if (f->cur[i] != s[i]) return JSON_STRING_INVALID; + } + f->cur += len; + json_truncate_path(f, fstate.path_len); - CALL_BACK(f, tok_type, fstate.ptr, f->cur - fstate.ptr); + CALL_BACK(f, tok_type, fstate.ptr, f->cur - fstate.ptr); - return 0; + return 0; } /* value = 'null' | 'true' | 'false' | number | string | array | object */ static int json_parse_value(struct frozen *f) { - int ch = json_cur(f); + int ch = json_cur(f); - switch (ch) { - case '"': - TRY(json_parse_string(f)); - break; - case '{': - TRY(json_parse_object(f)); - break; + switch (ch) { + case '"': + TRY(json_parse_string(f)); + break; + case '{': + TRY(json_parse_object(f)); + break; #if JSON_ENABLE_ARRAY - case '[': - TRY(json_parse_array(f)); - break; + case '[': + TRY(json_parse_array(f)); + break; #endif - case 'n': - TRY(json_expect(f, "null", 4, JSON_TYPE_NULL)); - break; - case 't': - TRY(json_expect(f, "true", 4, JSON_TYPE_TRUE)); - break; - case 'f': - TRY(json_expect(f, "false", 5, JSON_TYPE_FALSE)); - break; - case '-': - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - TRY(json_parse_number(f)); - break; - default: - return ch == END_OF_STRING ? JSON_STRING_INCOMPLETE : JSON_STRING_INVALID; - } + case 'n': + TRY(json_expect(f, "null", 4, JSON_TYPE_NULL)); + break; + case 't': + TRY(json_expect(f, "true", 4, JSON_TYPE_TRUE)); + break; + case 'f': + TRY(json_expect(f, "false", 5, JSON_TYPE_FALSE)); + break; + case '-': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + TRY(json_parse_number(f)); + break; + default: + return ch == END_OF_STRING ? JSON_STRING_INCOMPLETE : JSON_STRING_INVALID; + } - return 0; + return 0; } /* key = identifier | string */ static int json_parse_key(struct frozen *f) { - int ch = json_cur(f); - if (json_isalpha(ch)) { - TRY(json_parse_identifier(f)); - } else if (ch == '"') { - TRY(json_parse_string(f)); - } else { - return ch == END_OF_STRING ? JSON_STRING_INCOMPLETE : JSON_STRING_INVALID; - } - return 0; + int ch = json_cur(f); + if (json_isalpha(ch)) { + TRY(json_parse_identifier(f)); + } else if (ch == '"') { + TRY(json_parse_string(f)); + } else { + return ch == END_OF_STRING ? JSON_STRING_INCOMPLETE : JSON_STRING_INVALID; + } + return 0; } /* pair = key ':' value */ static int json_parse_pair(struct frozen *f) { - int current_path_len; - const char *tok; - json_skip_whitespaces(f); - tok = f->cur; - TRY(json_parse_key(f)); - { - f->cur_name = *tok == '"' ? tok + 1 : tok; - f->cur_name_len = *tok == '"' ? f->cur - tok - 2 : f->cur - tok; - current_path_len = json_append_to_path(f, f->cur_name, f->cur_name_len); - } - TRY(json_test_and_skip(f, ':')); - TRY(json_parse_value(f)); - json_truncate_path(f, current_path_len); - return 0; + int current_path_len; + const char *tok; + json_skip_whitespaces(f); + tok = f->cur; + TRY(json_parse_key(f)); + { + f->cur_name = *tok == '"' ? tok + 1 : tok; + f->cur_name_len = *tok == '"' ? f->cur - tok - 2 : f->cur - tok; + current_path_len = json_append_to_path(f, f->cur_name, f->cur_name_len); + } + TRY(json_test_and_skip(f, ':')); + TRY(json_parse_value(f)); + json_truncate_path(f, current_path_len); + return 0; } /* object = '{' pair { ',' pair } '}' */ static int json_parse_object(struct frozen *f) { - CALL_BACK(f, JSON_TYPE_OBJECT_START, NULL, 0); - TRY(json_test_and_skip(f, '{')); - { - SET_STATE(f, f->cur - 1, ".", 1); - while (json_cur(f) != '}') { - TRY(json_parse_pair(f)); - if (json_cur(f) == ',') f->cur++; + CALL_BACK(f, JSON_TYPE_OBJECT_START, NULL, 0); + TRY(json_test_and_skip(f, '{')); + { + SET_STATE(f, f->cur - 1, ".", 1); + while (json_cur(f) != '}') { + TRY(json_parse_pair(f)); + if (json_cur(f) == ',') f->cur++; + } + TRY(json_test_and_skip(f, '}')); + json_truncate_path(f, fstate.path_len); + CALL_BACK(f, JSON_TYPE_OBJECT_END, fstate.ptr, f->cur - fstate.ptr); } - TRY(json_test_and_skip(f, '}')); - json_truncate_path(f, fstate.path_len); - CALL_BACK(f, JSON_TYPE_OBJECT_END, fstate.ptr, f->cur - fstate.ptr); - } - return 0; + return 0; } static int json_doit(struct frozen *f) { - if (f->cur == 0 || f->end < f->cur) return JSON_STRING_INVALID; - if (f->end == f->cur) return JSON_STRING_INCOMPLETE; - return json_parse_value(f); + if (f->cur == 0 || f->end < f->cur) return JSON_STRING_INVALID; + if (f->end == f->cur) return JSON_STRING_INCOMPLETE; + return json_parse_value(f); } int json_escape(struct json_out *out, const char *p, size_t len) WEAK; int json_escape(struct json_out *out, const char *p, size_t len) { - size_t i, cl, n = 0; - const char *hex_digits = "0123456789abcdef"; - const char *specials = "btnvfr"; + size_t i, cl, n = 0; + const char *hex_digits = "0123456789abcdef"; + const char *specials = "btnvfr"; - for (i = 0; i < len; i++) { - unsigned char ch = ((unsigned char *) p)[i]; - if (ch == '"' || ch == '\\') { - n += out->printer(out, "\\", 1); - n += out->printer(out, p + i, 1); - } else if (ch >= '\b' && ch <= '\r') { - n += out->printer(out, "\\", 1); - n += out->printer(out, &specials[ch - '\b'], 1); - } else if (c_isprint(ch)) { - n += out->printer(out, p + i, 1); - } else if ((cl = json_get_utf8_char_len(ch)) == 1) { - n += out->printer(out, "\\u00", 4); - n += out->printer(out, &hex_digits[(ch >> 4) % 0xf], 1); - n += out->printer(out, &hex_digits[ch % 0xf], 1); - } else { - n += out->printer(out, p + i, cl); - i += cl - 1; + for (i = 0; i < len; i++) { + unsigned char ch = ((unsigned char *) p)[i]; + if (ch == '"' || ch == '\\') { + n += out->printer(out, "\\", 1); + n += out->printer(out, p + i, 1); + } else if (ch >= '\b' && ch <= '\r') { + n += out->printer(out, "\\", 1); + n += out->printer(out, &specials[ch - '\b'], 1); + } else if (c_isprint(ch)) { + n += out->printer(out, p + i, 1); + } else if ((cl = json_get_utf8_char_len(ch)) == 1) { + n += out->printer(out, "\\u00", 4); + n += out->printer(out, &hex_digits[(ch >> 4) % 0xf], 1); + n += out->printer(out, &hex_digits[ch % 0xf], 1); + } else { + n += out->printer(out, p + i, cl); + i += cl - 1; + } } - } - return n; + return n; } int json_printer_buf(struct json_out *out, const char *buf, size_t len) WEAK; int json_printer_buf(struct json_out *out, const char *buf, size_t len) { - size_t avail = out->u.buf.size - out->u.buf.len; - size_t n = len < avail ? len : avail; - memcpy(out->u.buf.buf + out->u.buf.len, buf, n); - out->u.buf.len += n; - if (out->u.buf.size > 0) { - size_t idx = out->u.buf.len; - if (idx >= out->u.buf.size) idx = out->u.buf.size - 1; - out->u.buf.buf[idx] = '\0'; - } - return len; + size_t avail = out->u.buf.size - out->u.buf.len; + size_t n = len < avail ? len : avail; + memcpy(out->u.buf.buf + out->u.buf.len, buf, n); + out->u.buf.len += n; + if (out->u.buf.size > 0) { + size_t idx = out->u.buf.len; + if (idx >= out->u.buf.size) idx = out->u.buf.size - 1; + out->u.buf.buf[idx] = '\0'; + } + return len; } int json_printer_file(struct json_out *out, const char *buf, size_t len) WEAK; int json_printer_file(struct json_out *out, const char *buf, size_t len) { - return fwrite(buf, 1, len, out->u.fp); + return fwrite(buf, 1, len, out->u.fp); } #if JSON_ENABLE_BASE64 static int b64idx(int c) { - if (c < 26) { - return c + 'A'; - } else if (c < 52) { - return c - 26 + 'a'; - } else if (c < 62) { - return c - 52 + '0'; - } else { - return c == 62 ? '+' : '/'; - } + if (c < 26) { + return c + 'A'; + } else if (c < 52) { + return c - 26 + 'a'; + } else if (c < 62) { + return c - 52 + '0'; + } else { + return c == 62 ? '+' : '/'; + } } static int b64rev(int c) { - if (c >= 'A' && c <= 'Z') { - return c - 'A'; - } else if (c >= 'a' && c <= 'z') { - return c + 26 - 'a'; - } else if (c >= '0' && c <= '9') { - return c + 52 - '0'; - } else if (c == '+') { - return 62; - } else if (c == '/') { - return 63; - } else { - return 64; - } + if (c >= 'A' && c <= 'Z') { + return c - 'A'; + } else if (c >= 'a' && c <= 'z') { + return c + 26 - 'a'; + } else if (c >= '0' && c <= '9') { + return c + 52 - '0'; + } else if (c == '+') { + return 62; + } else if (c == '/') { + return 63; + } else { + return 64; + } } static int b64enc(struct json_out *out, const unsigned char *p, int n) { - char buf[4]; - int i, len = 0; - for (i = 0; i < n; i += 3) { - int a = p[i], b = i + 1 < n ? p[i + 1] : 0, c = i + 2 < n ? p[i + 2] : 0; - buf[0] = b64idx(a >> 2); - buf[1] = b64idx((a & 3) << 4 | (b >> 4)); - buf[2] = b64idx((b & 15) << 2 | (c >> 6)); - buf[3] = b64idx(c & 63); - if (i + 1 >= n) buf[2] = '='; - if (i + 2 >= n) buf[3] = '='; - len += out->printer(out, buf, sizeof(buf)); - } - return len; + char buf[4]; + int i, len = 0; + for (i = 0; i < n; i += 3) { + int a = p[i], b = i + 1 < n ? p[i + 1] : 0, c = i + 2 < n ? p[i + 2] : 0; + buf[0] = b64idx(a >> 2); + buf[1] = b64idx((a & 3) << 4 | (b >> 4)); + buf[2] = b64idx((b & 15) << 2 | (c >> 6)); + buf[3] = b64idx(c & 63); + if (i + 1 >= n) buf[2] = '='; + if (i + 2 >= n) buf[3] = '='; + len += out->printer(out, buf, sizeof(buf)); + } + return len; } static int b64dec(const char *src, int n, char *dst) { - const char *end = src + n; - int len = 0; - while (src + 3 < end) { - int a = b64rev(src[0]), b = b64rev(src[1]), c = b64rev(src[2]), - d = b64rev(src[3]); - dst[len++] = (a << 2) | (b >> 4); - if (src[2] != '=') { - dst[len++] = (b << 4) | (c >> 2); - if (src[3] != '=') { - dst[len++] = (c << 6) | d; - } + const char *end = src + n; + int len = 0; + while (src + 3 < end) { + int a = b64rev(src[0]), b = b64rev(src[1]), c = b64rev(src[2]), + d = b64rev(src[3]); + dst[len++] = (a << 2) | (b >> 4); + if (src[2] != '=') { + dst[len++] = (b << 4) | (c >> 2); + if (src[3] != '=') { + dst[len++] = (c << 6) | d; + } + } + src += 4; } - src += 4; - } - return len; + return len; } #endif /* JSON_ENABLE_BASE64 */ static unsigned char hexdec(const char *s) { #define HEXTOI(x) (x >= '0' && x <= '9' ? x - '0' : x - 'W') - int a = c_tolower(*(const unsigned char *) s); - int b = c_tolower(*(const unsigned char *) (s + 1)); - return (HEXTOI(a) << 4) | HEXTOI(b); + int a = c_tolower(*(const unsigned char *) s); + int b = c_tolower(*(const unsigned char *)(s + 1)); + return (HEXTOI(a) << 4) | HEXTOI(b); } int json_vprintf(struct json_out *out, const char *fmt, va_list xap) WEAK; int json_vprintf(struct json_out *out, const char *fmt, va_list xap) { - int len = 0; - const char *quote = "\"", *null = "null"; - va_list ap; - va_copy(ap, xap); + int len = 0; + const char *quote = "\"", *null = "null"; + va_list ap; + va_copy(ap, xap); - while (*fmt != '\0') { - if (strchr(":, \r\n\t[]{}\"", *fmt) != NULL) { - len += out->printer(out, fmt, 1); - fmt++; - } else if (fmt[0] == '%') { - char buf[21]; - size_t skip = 2; + while (*fmt != '\0') { + if (strchr(":, \r\n\t[]{}\"", *fmt) != NULL) { + len += out->printer(out, fmt, 1); + fmt++; + } else if (fmt[0] == '%') { + char buf[21]; + size_t skip = 2; - if (fmt[1] == 'l' && fmt[2] == 'l' && (fmt[3] == 'd' || fmt[3] == 'u')) { - int64_t val = va_arg(ap, int64_t); - const char *fmt2 = fmt[3] == 'u' ? "%" UINT64_FMT : "%" INT64_FMT; - snprintf(buf, sizeof(buf), fmt2, val); - len += out->printer(out, buf, strlen(buf)); - skip += 2; - } else if (fmt[1] == 'z' && fmt[2] == 'u') { - size_t val = va_arg(ap, size_t); - snprintf(buf, sizeof(buf), "%lu", (unsigned long) val); - len += out->printer(out, buf, strlen(buf)); - skip += 1; - } else if (fmt[1] == 'M') { - json_printf_callback_t f = va_arg(ap, json_printf_callback_t); - len += f(out, &ap); - } else if (fmt[1] == 'B') { - int val = va_arg(ap, int); - const char *str = val ? "true" : "false"; - len += out->printer(out, str, strlen(str)); - } else if (fmt[1] == 'H') { + if (fmt[1] == 'l' && fmt[2] == 'l' && (fmt[3] == 'd' || fmt[3] == 'u')) { + int64_t val = va_arg(ap, int64_t); + const char *fmt2 = fmt[3] == 'u' ? "%" UINT64_FMT : "%" INT64_FMT; + snprintf(buf, sizeof(buf), fmt2, val); + len += out->printer(out, buf, strlen(buf)); + skip += 2; + } else if (fmt[1] == 'z' && fmt[2] == 'u') { + size_t val = va_arg(ap, size_t); + snprintf(buf, sizeof(buf), "%lu", (unsigned long) val); + len += out->printer(out, buf, strlen(buf)); + skip += 1; + } else if (fmt[1] == 'M') { + json_printf_callback_t f = va_arg(ap, json_printf_callback_t); + len += f(out, &ap); + } else if (fmt[1] == 'B') { + int val = va_arg(ap, int); + const char *str = val ? "true" : "false"; + len += out->printer(out, str, strlen(str)); + } else if (fmt[1] == 'H') { #if JSON_ENABLE_HEX - const char *hex = "0123456789abcdef"; - int i, n = va_arg(ap, int); - const unsigned char *p = va_arg(ap, const unsigned char *); - len += out->printer(out, quote, 1); - for (i = 0; i < n; i++) { - len += out->printer(out, &hex[(p[i] >> 4) & 0xf], 1); - len += out->printer(out, &hex[p[i] & 0xf], 1); - } - len += out->printer(out, quote, 1); + const char *hex = "0123456789abcdef"; + int i, n = va_arg(ap, int); + const unsigned char *p = va_arg(ap, const unsigned char *); + len += out->printer(out, quote, 1); + for (i = 0; i < n; i++) { + len += out->printer(out, &hex[(p[i] >> 4) & 0xf], 1); + len += out->printer(out, &hex[p[i] & 0xf], 1); + } + len += out->printer(out, quote, 1); #endif /* JSON_ENABLE_HEX */ - } else if (fmt[1] == 'V') { + } else if (fmt[1] == 'V') { #if JSON_ENABLE_BASE64 - const unsigned char *p = va_arg(ap, const unsigned char *); - int n = va_arg(ap, int); - len += out->printer(out, quote, 1); - len += b64enc(out, p, n); - len += out->printer(out, quote, 1); + const unsigned char *p = va_arg(ap, const unsigned char *); + int n = va_arg(ap, int); + len += out->printer(out, quote, 1); + len += b64enc(out, p, n); + len += out->printer(out, quote, 1); #endif /* JSON_ENABLE_BASE64 */ - } else if (fmt[1] == 'Q' || - (fmt[1] == '.' && fmt[2] == '*' && fmt[3] == 'Q')) { - size_t l = 0; - const char *p; + } else if (fmt[1] == 'Q' || + (fmt[1] == '.' && fmt[2] == '*' && fmt[3] == 'Q')) { + size_t l = 0; + const char *p; - if (fmt[1] == '.') { - l = (size_t) va_arg(ap, int); - skip += 2; - } - p = va_arg(ap, char *); + if (fmt[1] == '.') { + l = (size_t) va_arg(ap, int); + skip += 2; + } + p = va_arg(ap, char *); - if (p == NULL) { - len += out->printer(out, null, 4); + if (p == NULL) { + len += out->printer(out, null, 4); + } else { + if (fmt[1] == 'Q') { + l = strlen(p); + } + len += out->printer(out, quote, 1); + len += json_escape(out, p, l); + len += out->printer(out, quote, 1); + } + } else { + /* + * we delegate printing to the system printf. + * The goal here is to delegate all modifiers parsing to the system + * printf, as you can see below we still have to parse the format + * types. + * + * Currently, %s with strings longer than 20 chars will require + * double-buffering (an auxiliary buffer will be allocated from heap). + * TODO(dfrank): reimplement %s and %.*s in order to avoid that. + */ + + const char *end_of_format_specifier = "sdfFeEgGlhuIcx.*-0123456789"; + int n = strspn(fmt + 1, end_of_format_specifier); + char *pbuf = buf; + int need_len, size = sizeof(buf); + char fmt2[20]; + va_list ap_copy; + strncpy(fmt2, fmt, + n + 1 > (int) sizeof(fmt2) ? sizeof(fmt2) : (size_t) n + 1); + fmt2[n + 1] = '\0'; + + va_copy(ap_copy, ap); + need_len = vsnprintf(pbuf, size, fmt2, ap_copy); + va_end(ap_copy); + + if (need_len < 0) { + /* + * Windows & eCos vsnprintf implementation return -1 on overflow + * instead of needed size. + */ + pbuf = NULL; + while (need_len < 0) { + free(pbuf); + size *= 2; + if ((pbuf = (char *) malloc(size)) == NULL) break; + va_copy(ap_copy, ap); + need_len = vsnprintf(pbuf, size, fmt2, ap_copy); + va_end(ap_copy); + } + } else if (need_len >= (int) sizeof(buf)) { + /* + * resulting string doesn't fit into a stack-allocated buffer `buf`, + * so we need to allocate a new buffer from heap and use it + */ + if ((pbuf = (char *) malloc(need_len + 1)) != NULL) { + va_copy(ap_copy, ap); + vsnprintf(pbuf, need_len + 1, fmt2, ap_copy); + va_end(ap_copy); + } + } + if (pbuf == NULL) { + buf[0] = '\0'; + pbuf = buf; + } + + /* + * however we need to parse the type ourselves in order to advance + * the va_list by the correct amount; there is no portable way to + * inherit the advancement made by vprintf. + * 32-bit (linux or windows) passes va_list by value. + */ + if ((n + 1 == strlen("%" PRId64) && strcmp(fmt2, "%" PRId64) == 0) || + (n + 1 == strlen("%" PRIu64) && strcmp(fmt2, "%" PRIu64) == 0)) { + (void) va_arg(ap, int64_t); + } else if (strcmp(fmt2, "%.*s") == 0) { + (void) va_arg(ap, int); + (void) va_arg(ap, char *); + } else { + switch (fmt2[n]) { + case 'u': + case 'd': + (void) va_arg(ap, int); + break; + case 'g': + case 'f': + (void) va_arg(ap, double); + break; + case 'p': + (void) va_arg(ap, void *); + break; + default: + /* many types are promoted to int */ + (void) va_arg(ap, int); + } + } + + len += out->printer(out, pbuf, strlen(pbuf)); + skip = n + 1; + + /* If buffer was allocated from heap, free it */ + if (pbuf != buf) { + free(pbuf); + pbuf = NULL; + } + } + fmt += skip; + } else if (*fmt == '_' || json_isalpha(*fmt)) { + len += out->printer(out, quote, 1); + while (*fmt == '_' || json_isalpha(*fmt) || json_isdigit(*fmt)) { + len += out->printer(out, fmt, 1); + fmt++; + } + len += out->printer(out, quote, 1); } else { - if (fmt[1] == 'Q') { - l = strlen(p); - } - len += out->printer(out, quote, 1); - len += json_escape(out, p, l); - len += out->printer(out, quote, 1); + len += out->printer(out, fmt, 1); + fmt++; } - } else { - /* - * we delegate printing to the system printf. - * The goal here is to delegate all modifiers parsing to the system - * printf, as you can see below we still have to parse the format - * types. - * - * Currently, %s with strings longer than 20 chars will require - * double-buffering (an auxiliary buffer will be allocated from heap). - * TODO(dfrank): reimplement %s and %.*s in order to avoid that. - */ - - const char *end_of_format_specifier = "sdfFeEgGlhuIcx.*-0123456789"; - int n = strspn(fmt + 1, end_of_format_specifier); - char *pbuf = buf; - int need_len, size = sizeof(buf); - char fmt2[20]; - va_list ap_copy; - strncpy(fmt2, fmt, - n + 1 > (int) sizeof(fmt2) ? sizeof(fmt2) : (size_t) n + 1); - fmt2[n + 1] = '\0'; - - va_copy(ap_copy, ap); - need_len = vsnprintf(pbuf, size, fmt2, ap_copy); - va_end(ap_copy); - - if (need_len < 0) { - /* - * Windows & eCos vsnprintf implementation return -1 on overflow - * instead of needed size. - */ - pbuf = NULL; - while (need_len < 0) { - free(pbuf); - size *= 2; - if ((pbuf = (char *) malloc(size)) == NULL) break; - va_copy(ap_copy, ap); - need_len = vsnprintf(pbuf, size, fmt2, ap_copy); - va_end(ap_copy); - } - } else if (need_len >= (int) sizeof(buf)) { - /* - * resulting string doesn't fit into a stack-allocated buffer `buf`, - * so we need to allocate a new buffer from heap and use it - */ - if ((pbuf = (char *) malloc(need_len + 1)) != NULL) { - va_copy(ap_copy, ap); - vsnprintf(pbuf, need_len + 1, fmt2, ap_copy); - va_end(ap_copy); - } - } - if (pbuf == NULL) { - buf[0] = '\0'; - pbuf = buf; - } - - /* - * however we need to parse the type ourselves in order to advance - * the va_list by the correct amount; there is no portable way to - * inherit the advancement made by vprintf. - * 32-bit (linux or windows) passes va_list by value. - */ - if ((n + 1 == strlen("%" PRId64) && strcmp(fmt2, "%" PRId64) == 0) || - (n + 1 == strlen("%" PRIu64) && strcmp(fmt2, "%" PRIu64) == 0)) { - (void) va_arg(ap, int64_t); - } else if (strcmp(fmt2, "%.*s") == 0) { - (void) va_arg(ap, int); - (void) va_arg(ap, char *); - } else { - switch (fmt2[n]) { - case 'u': - case 'd': - (void) va_arg(ap, int); - break; - case 'g': - case 'f': - (void) va_arg(ap, double); - break; - case 'p': - (void) va_arg(ap, void *); - break; - default: - /* many types are promoted to int */ - (void) va_arg(ap, int); - } - } - - len += out->printer(out, pbuf, strlen(pbuf)); - skip = n + 1; - - /* If buffer was allocated from heap, free it */ - if (pbuf != buf) { - free(pbuf); - pbuf = NULL; - } - } - fmt += skip; - } else if (*fmt == '_' || json_isalpha(*fmt)) { - len += out->printer(out, quote, 1); - while (*fmt == '_' || json_isalpha(*fmt) || json_isdigit(*fmt)) { - len += out->printer(out, fmt, 1); - fmt++; - } - len += out->printer(out, quote, 1); - } else { - len += out->printer(out, fmt, 1); - fmt++; } - } - va_end(ap); + va_end(ap); - return len; + return len; } int json_printf(struct json_out *out, const char *fmt, ...) WEAK; int json_printf(struct json_out *out, const char *fmt, ...) { - int n; - va_list ap; - va_start(ap, fmt); - n = json_vprintf(out, fmt, ap); - va_end(ap); - return n; + int n; + va_list ap; + va_start(ap, fmt); + n = json_vprintf(out, fmt, ap); + va_end(ap); + return n; } int json_printf_array(struct json_out *out, va_list *ap) WEAK; int json_printf_array(struct json_out *out, va_list *ap) { - int len = 0; - char *arr = va_arg(*ap, char *); - size_t i, arr_size = va_arg(*ap, size_t); - size_t elem_size = va_arg(*ap, size_t); - const char *fmt = va_arg(*ap, char *); - len += json_printf(out, "[", 1); - for (i = 0; arr != NULL && i < arr_size / elem_size; i++) { - union { - int64_t i; - double d; - } val; - memcpy(&val, arr + i * elem_size, - elem_size > sizeof(val) ? sizeof(val) : elem_size); - if (i > 0) len += json_printf(out, ", "); - if (strpbrk(fmt, "efg") != NULL) { - len += json_printf(out, fmt, val.d); - } else { - len += json_printf(out, fmt, val.i); + int len = 0; + char *arr = va_arg(*ap, char *); + size_t i, arr_size = va_arg(*ap, size_t); + size_t elem_size = va_arg(*ap, size_t); + const char *fmt = va_arg(*ap, char *); + len += json_printf(out, "[", 1); + for (i = 0; arr != NULL && i < arr_size / elem_size; i++) { + union { + int64_t i; + double d; + } val; + memcpy(&val, arr + i * elem_size, + elem_size > sizeof(val) ? sizeof(val) : elem_size); + if (i > 0) len += json_printf(out, ", "); + if (strpbrk(fmt, "efg") != NULL) { + len += json_printf(out, fmt, val.d); + } else { + len += json_printf(out, fmt, val.i); + } } - } - len += json_printf(out, "]", 1); - return len; + len += json_printf(out, "]", 1); + return len; } #ifdef _WIN32 int cs_win_vsnprintf(char *str, size_t size, const char *format, va_list ap) WEAK; int cs_win_vsnprintf(char *str, size_t size, const char *format, va_list ap) { - int res = _vsnprintf(str, size, format, ap); - va_end(ap); - if (res >= size) { - str[size - 1] = '\0'; - } - return res; + int res = _vsnprintf(str, size, format, ap); + va_end(ap); + if (res >= size) { + str[size - 1] = '\0'; + } + return res; } int cs_win_snprintf(char *str, size_t size, const char *format, ...) WEAK; int cs_win_snprintf(char *str, size_t size, const char *format, ...) { - int res; - va_list ap; - va_start(ap, format); - res = vsnprintf(str, size, format, ap); - va_end(ap); - return res; + int res; + va_list ap; + va_start(ap, format); + res = vsnprintf(str, size, format, ap); + va_end(ap); + return res; } #endif /* _WIN32 */ @@ -809,665 +809,665 @@ int json_walk(const char *json_string, int json_string_length, json_walk_callback_t callback, void *callback_data) WEAK; int json_walk(const char *json_string, int json_string_length, json_walk_callback_t callback, void *callback_data) { - struct frozen frozen; + struct frozen frozen; - memset(&frozen, 0, sizeof(frozen)); - frozen.end = json_string + json_string_length; - frozen.cur = json_string; - frozen.callback_data = callback_data; - frozen.callback = callback; + memset(&frozen, 0, sizeof(frozen)); + frozen.end = json_string + json_string_length; + frozen.cur = json_string; + frozen.callback_data = callback_data; + frozen.callback = callback; - TRY(json_doit(&frozen)); + TRY(json_doit(&frozen)); - return frozen.cur - json_string; + return frozen.cur - json_string; } struct scan_array_info { - int found; - char path[JSON_MAX_PATH_LEN]; - struct json_token *token; + int found; + char path[JSON_MAX_PATH_LEN]; + struct json_token *token; }; static void json_scanf_array_elem_cb(void *callback_data, const char *name, size_t name_len, const char *path, const struct json_token *token) { - struct scan_array_info *info = (struct scan_array_info *) callback_data; + struct scan_array_info *info = (struct scan_array_info *) callback_data; - (void) name; - (void) name_len; + (void) name; + (void) name_len; - if (strcmp(path, info->path) == 0) { - *info->token = *token; - info->found = 1; - } + if (strcmp(path, info->path) == 0) { + *info->token = *token; + info->found = 1; + } } int json_scanf_array_elem(const char *s, int len, const char *path, int idx, struct json_token *token) WEAK; int json_scanf_array_elem(const char *s, int len, const char *path, int idx, struct json_token *token) { - struct scan_array_info info; - info.token = token; - info.found = 0; - memset(token, 0, sizeof(*token)); - snprintf(info.path, sizeof(info.path), "%s[%d]", path, idx); - json_walk(s, len, json_scanf_array_elem_cb, &info); - return info.found ? token->len : -1; + struct scan_array_info info; + info.token = token; + info.found = 0; + memset(token, 0, sizeof(*token)); + snprintf(info.path, sizeof(info.path), "%s[%d]", path, idx); + json_walk(s, len, json_scanf_array_elem_cb, &info); + return info.found ? token->len : -1; } struct json_scanf_info { - int num_conversions; - char *path; - const char *fmt; - void *target; - void *user_data; - int type; + int num_conversions; + char *path; + const char *fmt; + void *target; + void *user_data; + int type; }; int json_unescape(const char *src, int slen, char *dst, int dlen) WEAK; int json_unescape(const char *src, int slen, char *dst, int dlen) { - char *send = (char *) src + slen, *dend = dst + dlen, *orig_dst = dst, *p; - const char *esc1 = "\"\\/bfnrt", *esc2 = "\"\\/\b\f\n\r\t"; + char *send = (char *) src + slen, *dend = dst + dlen, *orig_dst = dst, *p; + const char *esc1 = "\"\\/bfnrt", *esc2 = "\"\\/\b\f\n\r\t"; - while (src < send) { - if (*src == '\\') { - if (++src >= send) return JSON_STRING_INCOMPLETE; - if (*src == 'u') { - if (send - src < 5) return JSON_STRING_INCOMPLETE; - /* Here we go: this is a \u.... escape. Process simple one-byte chars */ - if (src[1] == '0' && src[2] == '0') { - /* This is \u00xx character from the ASCII range */ - if (dst < dend) *dst = hexdec(src + 3); - src += 4; + while (src < send) { + if (*src == '\\') { + if (++src >= send) return JSON_STRING_INCOMPLETE; + if (*src == 'u') { + if (send - src < 5) return JSON_STRING_INCOMPLETE; + /* Here we go: this is a \u.... escape. Process simple one-byte chars */ + if (src[1] == '0' && src[2] == '0') { + /* This is \u00xx character from the ASCII range */ + if (dst < dend) *dst = hexdec(src + 3); + src += 4; + } else { + /* Complex \uXXXX escapes drag utf8 lib... Do it at some stage */ + return JSON_STRING_INVALID; + } + } else if ((p = (char *) strchr(esc1, *src)) != NULL) { + if (dst < dend) *dst = esc2[p - esc1]; + } else { + return JSON_STRING_INVALID; + } } else { - /* Complex \uXXXX escapes drag utf8 lib... Do it at some stage */ - return JSON_STRING_INVALID; + if (dst < dend) *dst = *src; } - } else if ((p = (char *) strchr(esc1, *src)) != NULL) { - if (dst < dend) *dst = esc2[p - esc1]; - } else { - return JSON_STRING_INVALID; - } - } else { - if (dst < dend) *dst = *src; + dst++; + src++; } - dst++; - src++; - } - return dst - orig_dst; + return dst - orig_dst; } static void json_scanf_cb(void *callback_data, const char *name, size_t name_len, const char *path, const struct json_token *token) { - struct json_scanf_info *info = (struct json_scanf_info *) callback_data; - char buf[32]; /* Must be enough to hold numbers */ + struct json_scanf_info *info = (struct json_scanf_info *) callback_data; + char buf[32]; /* Must be enough to hold numbers */ - (void) name; - (void) name_len; + (void) name; + (void) name_len; - if (token->ptr == NULL) { - /* - * We're not interested here in the events for which we have no value; - * namely, JSON_TYPE_OBJECT_START and JSON_TYPE_ARRAY_START - */ - return; - } - - if (strcmp(path, info->path) != 0) { - /* It's not the path we're looking for, so, just ignore this callback */ - return; - } - - switch (info->type) { - case 'B': - info->num_conversions++; - switch (sizeof(bool)) { - case sizeof(char): - *(char *) info->target = (token->type == JSON_TYPE_TRUE ? 1 : 0); - break; - case sizeof(int): - *(int *) info->target = (token->type == JSON_TYPE_TRUE ? 1 : 0); - break; - default: - /* should never be here */ - abort(); - } - break; - case 'M': { - union { - void *p; - json_scanner_t f; - } u = {info->target}; - info->num_conversions++; - u.f(token->ptr, token->len, info->user_data); - break; + if (token->ptr == NULL) { + /* + * We're not interested here in the events for which we have no value; + * namely, JSON_TYPE_OBJECT_START and JSON_TYPE_ARRAY_START + */ + return; } - case 'Q': { - char **dst = (char **) info->target; - if (token->type == JSON_TYPE_NULL) { - *dst = NULL; - } else { - int unescaped_len = json_unescape(token->ptr, token->len, NULL, 0); - if (unescaped_len >= 0 && - (*dst = (char *) malloc(unescaped_len + 1)) != NULL) { - info->num_conversions++; - if (json_unescape(token->ptr, token->len, *dst, unescaped_len) == - unescaped_len) { - (*dst)[unescaped_len] = '\0'; - } else { - free(*dst); - *dst = NULL; - } + + if (strcmp(path, info->path) != 0) { + /* It's not the path we're looking for, so, just ignore this callback */ + return; + } + + switch (info->type) { + case 'B': + info->num_conversions++; + switch (sizeof(bool)) { + case sizeof(char): + *(char *) info->target = (token->type == JSON_TYPE_TRUE ? 1 : 0); + break; + case sizeof(int): + *(int *) info->target = (token->type == JSON_TYPE_TRUE ? 1 : 0); + break; + default: + /* should never be here */ + abort(); + } + break; + case 'M': { + union { + void *p; + json_scanner_t f; + } u = {info->target}; + info->num_conversions++; + u.f(token->ptr, token->len, info->user_data); + break; } - } - break; - } - case 'H': { + case 'Q': { + char **dst = (char **) info->target; + if (token->type == JSON_TYPE_NULL) { + *dst = NULL; + } else { + int unescaped_len = json_unescape(token->ptr, token->len, NULL, 0); + if (unescaped_len >= 0 && + (*dst = (char *) malloc(unescaped_len + 1)) != NULL) { + info->num_conversions++; + if (json_unescape(token->ptr, token->len, *dst, unescaped_len) == + unescaped_len) { + (*dst)[unescaped_len] = '\0'; + } else { + free(*dst); + *dst = NULL; + } + } + } + break; + } + case 'H': { #if JSON_ENABLE_HEX - char **dst = (char **) info->user_data; - int i, len = token->len / 2; - *(int *) info->target = len; - if ((*dst = (char *) malloc(len + 1)) != NULL) { - for (i = 0; i < len; i++) { - (*dst)[i] = hexdec(token->ptr + 2 * i); - } - (*dst)[len] = '\0'; - info->num_conversions++; - } + char **dst = (char **) info->user_data; + int i, len = token->len / 2; + *(int *) info->target = len; + if ((*dst = (char *) malloc(len + 1)) != NULL) { + for (i = 0; i < len; i++) { + (*dst)[i] = hexdec(token->ptr + 2 * i); + } + (*dst)[len] = '\0'; + info->num_conversions++; + } #endif /* JSON_ENABLE_HEX */ - break; - } - case 'V': { + break; + } + case 'V': { #if JSON_ENABLE_BASE64 - char **dst = (char **) info->target; - int len = token->len * 4 / 3 + 2; - if ((*dst = (char *) malloc(len + 1)) != NULL) { - int n = b64dec(token->ptr, token->len, *dst); - (*dst)[n] = '\0'; - *(int *) info->user_data = n; - info->num_conversions++; - } + char **dst = (char **) info->target; + int len = token->len * 4 / 3 + 2; + if ((*dst = (char *) malloc(len + 1)) != NULL) { + int n = b64dec(token->ptr, token->len, *dst); + (*dst)[n] = '\0'; + *(int *) info->user_data = n; + info->num_conversions++; + } #endif /* JSON_ENABLE_BASE64 */ - break; - } - case 'T': - info->num_conversions++; - *(struct json_token *) info->target = *token; - break; - default: - if (token->len >= (int) sizeof(buf)) break; - /* Before converting, copy into tmp buffer in order to 0-terminate it */ - memcpy(buf, token->ptr, token->len); - buf[token->len] = '\0'; - /* NB: Use of base 0 for %d, %ld, %u and %lu is intentional. */ - if (info->fmt[1] == 'd' || (info->fmt[1] == 'l' && info->fmt[2] == 'd') || - info->fmt[1] == 'i') { - char *endptr = NULL; - long r = strtol(buf, &endptr, 0 /* base */); - if (*endptr == '\0') { - if (info->fmt[1] == 'l') { - *((long *) info->target) = r; - } else { - *((int *) info->target) = (int) r; - } - info->num_conversions++; + break; } - } else if (info->fmt[1] == 'u' || - (info->fmt[1] == 'l' && info->fmt[2] == 'u')) { - char *endptr = NULL; - unsigned long r = strtoul(buf, &endptr, 0 /* base */); - if (*endptr == '\0') { - if (info->fmt[1] == 'l') { - *((unsigned long *) info->target) = r; - } else { - *((unsigned int *) info->target) = (unsigned int) r; - } - info->num_conversions++; - } - } else { + case 'T': + info->num_conversions++; + *(struct json_token *) info->target = *token; + break; + default: + if (token->len >= (int) sizeof(buf)) break; + /* Before converting, copy into tmp buffer in order to 0-terminate it */ + memcpy(buf, token->ptr, token->len); + buf[token->len] = '\0'; + /* NB: Use of base 0 for %d, %ld, %u and %lu is intentional. */ + if (info->fmt[1] == 'd' || (info->fmt[1] == 'l' && info->fmt[2] == 'd') || + info->fmt[1] == 'i') { + char *endptr = NULL; + long r = strtol(buf, &endptr, 0 /* base */); + if (*endptr == '\0') { + if (info->fmt[1] == 'l') { + *((long *) info->target) = r; + } else { + *((int *) info->target) = (int) r; + } + info->num_conversions++; + } + } else if (info->fmt[1] == 'u' || + (info->fmt[1] == 'l' && info->fmt[2] == 'u')) { + char *endptr = NULL; + unsigned long r = strtoul(buf, &endptr, 0 /* base */); + if (*endptr == '\0') { + if (info->fmt[1] == 'l') { + *((unsigned long *) info->target) = r; + } else { + *((unsigned int *) info->target) = (unsigned int) r; + } + info->num_conversions++; + } + } else { #if !JSON_MINIMAL - info->num_conversions += sscanf(buf, info->fmt, info->target); + info->num_conversions += sscanf(buf, info->fmt, info->target); #endif - } - break; - } + } + break; + } } int json_vscanf(const char *s, int len, const char *fmt, va_list ap) WEAK; int json_vscanf(const char *s, int len, const char *fmt, va_list ap) { - char path[JSON_MAX_PATH_LEN] = "", fmtbuf[20]; - int i = 0; - char *p = NULL; - struct json_scanf_info info = {0, path, fmtbuf, NULL, NULL, 0}; + char path[JSON_MAX_PATH_LEN] = "", fmtbuf[20]; + int i = 0; + char *p = NULL; + struct json_scanf_info info = {0, path, fmtbuf, NULL, NULL, 0}; - while (fmt[i] != '\0') { - if (fmt[i] == '{') { - strcat(path, "."); - i++; - } else if (fmt[i] == '}') { - if ((p = strrchr(path, '.')) != NULL) *p = '\0'; - i++; - } else if (fmt[i] == '%') { - info.target = va_arg(ap, void *); - info.type = fmt[i + 1]; - switch (fmt[i + 1]) { - case 'M': - case 'V': - case 'H': - info.user_data = va_arg(ap, void *); - /* FALLTHROUGH */ - case 'B': - case 'Q': - case 'T': - i += 2; - break; - default: { - const char *delims = ", \t\r\n]}"; - int conv_len = strcspn(fmt + i + 1, delims) + 1; - memcpy(fmtbuf, fmt + i, conv_len); - fmtbuf[conv_len] = '\0'; - i += conv_len; - i += strspn(fmt + i, delims); - break; + while (fmt[i] != '\0') { + if (fmt[i] == '{') { + strcat(path, "."); + i++; + } else if (fmt[i] == '}') { + if ((p = strrchr(path, '.')) != NULL) * p = '\0'; + i++; + } else if (fmt[i] == '%') { + info.target = va_arg(ap, void *); + info.type = fmt[i + 1]; + switch (fmt[i + 1]) { + case 'M': + case 'V': + case 'H': + info.user_data = va_arg(ap, void *); + /* FALLTHROUGH */ + case 'B': + case 'Q': + case 'T': + i += 2; + break; + default: { + const char *delims = ", \t\r\n]}"; + int conv_len = strcspn(fmt + i + 1, delims) + 1; + memcpy(fmtbuf, fmt + i, conv_len); + fmtbuf[conv_len] = '\0'; + i += conv_len; + i += strspn(fmt + i, delims); + break; + } + } + json_walk(s, len, json_scanf_cb, &info); + } else if (json_isalpha(fmt[i]) || json_get_utf8_char_len(fmt[i]) > 1) { + char *pe; + const char *delims = ": \r\n\t"; + int key_len = strcspn(&fmt[i], delims); + if ((p = strrchr(path, '.')) != NULL) p[1] = '\0'; + pe = path + strlen(path); + memcpy(pe, fmt + i, key_len); + pe[key_len] = '\0'; + i += key_len + strspn(fmt + i + key_len, delims); + } else { + i++; } - } - json_walk(s, len, json_scanf_cb, &info); - } else if (json_isalpha(fmt[i]) || json_get_utf8_char_len(fmt[i]) > 1) { - char *pe; - const char *delims = ": \r\n\t"; - int key_len = strcspn(&fmt[i], delims); - if ((p = strrchr(path, '.')) != NULL) p[1] = '\0'; - pe = path + strlen(path); - memcpy(pe, fmt + i, key_len); - pe[key_len] = '\0'; - i += key_len + strspn(fmt + i + key_len, delims); - } else { - i++; } - } - return info.num_conversions; + return info.num_conversions; } int json_scanf(const char *str, int len, const char *fmt, ...) WEAK; int json_scanf(const char *str, int len, const char *fmt, ...) { - int result; - va_list ap; - va_start(ap, fmt); - result = json_vscanf(str, len, fmt, ap); - va_end(ap); - return result; + int result; + va_list ap; + va_start(ap, fmt); + result = json_vscanf(str, len, fmt, ap); + va_end(ap); + return result; } int json_vfprintf(const char *file_name, const char *fmt, va_list ap) WEAK; int json_vfprintf(const char *file_name, const char *fmt, va_list ap) { - int res = -1; - FILE *fp = fopen(file_name, "wb"); - if (fp != NULL) { - struct json_out out = JSON_OUT_FILE(fp); - res = json_vprintf(&out, fmt, ap); - fputc('\n', fp); - fclose(fp); - } - return res; + int res = -1; + FILE *fp = fopen(file_name, "wb"); + if (fp != NULL) { + struct json_out out = JSON_OUT_FILE(fp); + res = json_vprintf(&out, fmt, ap); + fputc('\n', fp); + fclose(fp); + } + return res; } int json_fprintf(const char *file_name, const char *fmt, ...) WEAK; int json_fprintf(const char *file_name, const char *fmt, ...) { - int result; - va_list ap; - va_start(ap, fmt); - result = json_vfprintf(file_name, fmt, ap); - va_end(ap); - return result; + int result; + va_list ap; + va_start(ap, fmt); + result = json_vfprintf(file_name, fmt, ap); + va_end(ap); + return result; } char *json_fread(const char *path) WEAK; char *json_fread(const char *path) { - FILE *fp; - char *data = NULL; - if ((fp = fopen(path, "rb")) == NULL) { - } else if (fseek(fp, 0, SEEK_END) != 0) { - fclose(fp); - } else { - long size = ftell(fp); - if (size > 0 && (data = (char *) malloc(size + 1)) != NULL) { - fseek(fp, 0, SEEK_SET); /* Some platforms might not have rewind(), Oo */ - if (fread(data, 1, size, fp) != (size_t) size) { - free(data); - data = NULL; - } else { - data[size] = '\0'; - } + FILE *fp; + char *data = NULL; + if ((fp = fopen(path, "rb")) == NULL) { + } else if (fseek(fp, 0, SEEK_END) != 0) { + fclose(fp); + } else { + long size = ftell(fp); + if (size > 0 && (data = (char *) malloc(size + 1)) != NULL) { + fseek(fp, 0, SEEK_SET); /* Some platforms might not have rewind(), Oo */ + if (fread(data, 1, size, fp) != (size_t) size) { + free(data); + data = NULL; + } else { + data[size] = '\0'; + } + } + fclose(fp); } - fclose(fp); - } - return data; + return data; } struct json_setf_data { - const char *json_path; - const char *base; /* Pointer to the source JSON string */ - int matched; /* Matched part of json_path */ - int pos; /* Offset of the mutated value begin */ - int end; /* Offset of the mutated value end */ - int prev; /* Offset of the previous token end */ + const char *json_path; + const char *base; /* Pointer to the source JSON string */ + int matched; /* Matched part of json_path */ + int pos; /* Offset of the mutated value begin */ + int end; /* Offset of the mutated value end */ + int prev; /* Offset of the previous token end */ }; static int get_matched_prefix_len(const char *s1, const char *s2) { - int i = 0; - while (s1[i] && s2[i] && s1[i] == s2[i]) i++; - return i; + int i = 0; + while (s1[i] && s2[i] && s1[i] == s2[i]) i++; + return i; } static void json_vsetf_cb(void *userdata, const char *name, size_t name_len, const char *path, const struct json_token *t) { - struct json_setf_data *data = (struct json_setf_data *) userdata; - int off, len = get_matched_prefix_len(path, data->json_path); - if (t->ptr == NULL) return; - off = t->ptr - data->base; - if (len > data->matched) data->matched = len; + struct json_setf_data *data = (struct json_setf_data *) userdata; + int off, len = get_matched_prefix_len(path, data->json_path); + if (t->ptr == NULL) return; + off = t->ptr - data->base; + if (len > data->matched) data->matched = len; - /* - * If there is no exact path match, set the mutation position to tbe end - * of the object or array - */ - if (len < data->matched && data->pos == 0 && - (t->type == JSON_TYPE_OBJECT_END || t->type == JSON_TYPE_ARRAY_END)) { - data->pos = data->end = data->prev; - } + /* + * If there is no exact path match, set the mutation position to tbe end + * of the object or array + */ + if (len < data->matched && data->pos == 0 && + (t->type == JSON_TYPE_OBJECT_END || t->type == JSON_TYPE_ARRAY_END)) { + data->pos = data->end = data->prev; + } - /* Exact path match. Set mutation position to the value of this token */ - if (strcmp(path, data->json_path) == 0 && t->type != JSON_TYPE_OBJECT_START && - t->type != JSON_TYPE_ARRAY_START) { - data->pos = off; - data->end = off + t->len; - } + /* Exact path match. Set mutation position to the value of this token */ + if (strcmp(path, data->json_path) == 0 && t->type != JSON_TYPE_OBJECT_START && + t->type != JSON_TYPE_ARRAY_START) { + data->pos = off; + data->end = off + t->len; + } - /* - * For deletion, we need to know where the previous value ends, because - * we don't know where matched value key starts. - * When the mutation position is not yet set, remember each value end. - * When the mutation position is already set, but it is at the beginning - * of the object/array, we catch the end of the object/array and see - * whether the object/array start is closer then previously stored prev. - */ - if (data->pos == 0) { - data->prev = off + t->len; /* pos is not yet set */ - } else if ((t->ptr[0] == '[' || t->ptr[0] == '{') && off + 1 < data->pos && - off + 1 > data->prev) { - data->prev = off + 1; - } - (void) name; - (void) name_len; + /* + * For deletion, we need to know where the previous value ends, because + * we don't know where matched value key starts. + * When the mutation position is not yet set, remember each value end. + * When the mutation position is already set, but it is at the beginning + * of the object/array, we catch the end of the object/array and see + * whether the object/array start is closer then previously stored prev. + */ + if (data->pos == 0) { + data->prev = off + t->len; /* pos is not yet set */ + } else if ((t->ptr[0] == '[' || t->ptr[0] == '{') && off + 1 < data->pos && + off + 1 > data->prev) { + data->prev = off + 1; + } + (void) name; + (void) name_len; } int json_vsetf(const char *s, int len, struct json_out *out, const char *json_path, const char *json_fmt, va_list ap) WEAK; int json_vsetf(const char *s, int len, struct json_out *out, const char *json_path, const char *json_fmt, va_list ap) { - struct json_setf_data data; - memset(&data, 0, sizeof(data)); - data.json_path = json_path; - data.base = s; - data.end = len; - json_walk(s, len, json_vsetf_cb, &data); - if (json_fmt == NULL) { - /* Deletion codepath */ - json_printf(out, "%.*s", data.prev, s); - /* Trim comma after the value that begins at object/array start */ - if (s[data.prev - 1] == '{' || s[data.prev - 1] == '[') { - int i = data.end; - while (i < len && json_isspace(s[i])) i++; - if (s[i] == ',') data.end = i + 1; /* Point after comma */ + struct json_setf_data data; + memset(&data, 0, sizeof(data)); + data.json_path = json_path; + data.base = s; + data.end = len; + json_walk(s, len, json_vsetf_cb, &data); + if (json_fmt == NULL) { + /* Deletion codepath */ + json_printf(out, "%.*s", data.prev, s); + /* Trim comma after the value that begins at object/array start */ + if (s[data.prev - 1] == '{' || s[data.prev - 1] == '[') { + int i = data.end; + while (i < len && json_isspace(s[i])) i++; + if (s[i] == ',') data.end = i + 1; /* Point after comma */ + } + json_printf(out, "%.*s", len - data.end, s + data.end); + } else { + /* Modification codepath */ + int n, off = data.matched, depth = 0; + + /* Print the unchanged beginning */ + json_printf(out, "%.*s", data.pos, s); + + /* Add missing keys */ + while ((n = strcspn(&json_path[off], ".[")) > 0) { + if (s[data.prev - 1] != '{' && s[data.prev - 1] != '[' && depth == 0) { + json_printf(out, ","); + } + if (off > 0 && json_path[off - 1] != '.') break; + json_printf(out, "%.*Q:", n, json_path + off); + off += n; + if (json_path[off] != '\0') { + json_printf(out, "%c", json_path[off] == '.' ? '{' : '['); + depth++; + off++; + } + } + /* Print the new value */ + json_vprintf(out, json_fmt, ap); + + /* Close brackets/braces of the added missing keys */ + for (; off > data.matched; off--) { + int ch = json_path[off]; + const char *p = ch == '.' ? "}" : ch == '[' ? "]" : ""; + json_printf(out, "%s", p); + } + + /* Print the rest of the unchanged string */ + json_printf(out, "%.*s", len - data.end, s + data.end); } - json_printf(out, "%.*s", len - data.end, s + data.end); - } else { - /* Modification codepath */ - int n, off = data.matched, depth = 0; - - /* Print the unchanged beginning */ - json_printf(out, "%.*s", data.pos, s); - - /* Add missing keys */ - while ((n = strcspn(&json_path[off], ".[")) > 0) { - if (s[data.prev - 1] != '{' && s[data.prev - 1] != '[' && depth == 0) { - json_printf(out, ","); - } - if (off > 0 && json_path[off - 1] != '.') break; - json_printf(out, "%.*Q:", n, json_path + off); - off += n; - if (json_path[off] != '\0') { - json_printf(out, "%c", json_path[off] == '.' ? '{' : '['); - depth++; - off++; - } - } - /* Print the new value */ - json_vprintf(out, json_fmt, ap); - - /* Close brackets/braces of the added missing keys */ - for (; off > data.matched; off--) { - int ch = json_path[off]; - const char *p = ch == '.' ? "}" : ch == '[' ? "]" : ""; - json_printf(out, "%s", p); - } - - /* Print the rest of the unchanged string */ - json_printf(out, "%.*s", len - data.end, s + data.end); - } - return data.end > data.pos ? 1 : 0; + return data.end > data.pos ? 1 : 0; } int json_setf(const char *s, int len, struct json_out *out, const char *json_path, const char *json_fmt, ...) WEAK; int json_setf(const char *s, int len, struct json_out *out, const char *json_path, const char *json_fmt, ...) { - int result; - va_list ap; - va_start(ap, json_fmt); - result = json_vsetf(s, len, out, json_path, json_fmt, ap); - va_end(ap); - return result; + int result; + va_list ap; + va_start(ap, json_fmt); + result = json_vsetf(s, len, out, json_path, json_fmt, ap); + va_end(ap); + return result; } struct prettify_data { - struct json_out *out; - int level; - int last_token; + struct json_out *out; + int level; + int last_token; }; static void indent(struct json_out *out, int level) { - while (level-- > 0) out->printer(out, " ", 2); + while (level-- > 0) out->printer(out, " ", 2); } static void print_key(struct prettify_data *pd, const char *path, const char *name, int name_len) { - if (pd->last_token != JSON_TYPE_INVALID && - pd->last_token != JSON_TYPE_ARRAY_START && - pd->last_token != JSON_TYPE_OBJECT_START) { - pd->out->printer(pd->out, ",", 1); - } - if (path[0] != '\0') pd->out->printer(pd->out, "\n", 1); - indent(pd->out, pd->level); - if (path[0] != '\0' && path[strlen(path) - 1] != ']') { - pd->out->printer(pd->out, "\"", 1); - pd->out->printer(pd->out, name, (int) name_len); - pd->out->printer(pd->out, "\"", 1); - pd->out->printer(pd->out, ": ", 2); - } + if (pd->last_token != JSON_TYPE_INVALID && + pd->last_token != JSON_TYPE_ARRAY_START && + pd->last_token != JSON_TYPE_OBJECT_START) { + pd->out->printer(pd->out, ",", 1); + } + if (path[0] != '\0') pd->out->printer(pd->out, "\n", 1); + indent(pd->out, pd->level); + if (path[0] != '\0' && path[strlen(path) - 1] != ']') { + pd->out->printer(pd->out, "\"", 1); + pd->out->printer(pd->out, name, (int) name_len); + pd->out->printer(pd->out, "\"", 1); + pd->out->printer(pd->out, ": ", 2); + } } static void prettify_cb(void *userdata, const char *name, size_t name_len, const char *path, const struct json_token *t) { - struct prettify_data *pd = (struct prettify_data *) userdata; - switch (t->type) { - case JSON_TYPE_OBJECT_START: - case JSON_TYPE_ARRAY_START: - print_key(pd, path, name, name_len); - pd->out->printer(pd->out, t->type == JSON_TYPE_ARRAY_START ? "[" : "{", - 1); - pd->level++; - break; - case JSON_TYPE_OBJECT_END: - case JSON_TYPE_ARRAY_END: - pd->level--; - if (pd->last_token != JSON_TYPE_INVALID && - pd->last_token != JSON_TYPE_ARRAY_START && - pd->last_token != JSON_TYPE_OBJECT_START) { - pd->out->printer(pd->out, "\n", 1); - indent(pd->out, pd->level); - } - pd->out->printer(pd->out, t->type == JSON_TYPE_ARRAY_END ? "]" : "}", 1); - break; - case JSON_TYPE_NUMBER: - case JSON_TYPE_NULL: - case JSON_TYPE_TRUE: - case JSON_TYPE_FALSE: - case JSON_TYPE_STRING: - print_key(pd, path, name, name_len); - if (t->type == JSON_TYPE_STRING) pd->out->printer(pd->out, "\"", 1); - pd->out->printer(pd->out, t->ptr, t->len); - if (t->type == JSON_TYPE_STRING) pd->out->printer(pd->out, "\"", 1); - break; - default: - break; - } - pd->last_token = t->type; + struct prettify_data *pd = (struct prettify_data *) userdata; + switch (t->type) { + case JSON_TYPE_OBJECT_START: + case JSON_TYPE_ARRAY_START: + print_key(pd, path, name, name_len); + pd->out->printer(pd->out, t->type == JSON_TYPE_ARRAY_START ? "[" : "{", + 1); + pd->level++; + break; + case JSON_TYPE_OBJECT_END: + case JSON_TYPE_ARRAY_END: + pd->level--; + if (pd->last_token != JSON_TYPE_INVALID && + pd->last_token != JSON_TYPE_ARRAY_START && + pd->last_token != JSON_TYPE_OBJECT_START) { + pd->out->printer(pd->out, "\n", 1); + indent(pd->out, pd->level); + } + pd->out->printer(pd->out, t->type == JSON_TYPE_ARRAY_END ? "]" : "}", 1); + break; + case JSON_TYPE_NUMBER: + case JSON_TYPE_NULL: + case JSON_TYPE_TRUE: + case JSON_TYPE_FALSE: + case JSON_TYPE_STRING: + print_key(pd, path, name, name_len); + if (t->type == JSON_TYPE_STRING) pd->out->printer(pd->out, "\"", 1); + pd->out->printer(pd->out, t->ptr, t->len); + if (t->type == JSON_TYPE_STRING) pd->out->printer(pd->out, "\"", 1); + break; + default: + break; + } + pd->last_token = t->type; } int json_prettify(const char *s, int len, struct json_out *out) WEAK; int json_prettify(const char *s, int len, struct json_out *out) { - struct prettify_data pd = {out, 0, JSON_TYPE_INVALID}; - return json_walk(s, len, prettify_cb, &pd); + struct prettify_data pd = {out, 0, JSON_TYPE_INVALID}; + return json_walk(s, len, prettify_cb, &pd); } int json_prettify_file(const char *file_name) WEAK; int json_prettify_file(const char *file_name) { - int res = -1; - char *s = json_fread(file_name); - FILE *fp; - if (s != NULL && (fp = fopen(file_name, "wb")) != NULL) { - struct json_out out = JSON_OUT_FILE(fp); - res = json_prettify(s, strlen(s), &out); - if (res < 0) { - /* On error, restore the old content */ - fclose(fp); - fp = fopen(file_name, "wb"); - fseek(fp, 0, SEEK_SET); - fwrite(s, 1, strlen(s), fp); - } else { - fputc('\n', fp); + int res = -1; + char *s = json_fread(file_name); + FILE *fp; + if (s != NULL && (fp = fopen(file_name, "wb")) != NULL) { + struct json_out out = JSON_OUT_FILE(fp); + res = json_prettify(s, strlen(s), &out); + if (res < 0) { + /* On error, restore the old content */ + fclose(fp); + fp = fopen(file_name, "wb"); + fseek(fp, 0, SEEK_SET); + fwrite(s, 1, strlen(s), fp); + } else { + fputc('\n', fp); + } + fclose(fp); } - fclose(fp); - } - free(s); - return res; + free(s); + return res; } struct next_data { - void *handle; // Passed handle. Changed if a next entry is found - const char *path; // Path to the iterated object/array - int path_len; // Path length - optimisation - int found; // Non-0 if found the next entry - struct json_token *key; // Object's key - struct json_token *val; // Object's value - int *idx; // Array index + void *handle; // Passed handle. Changed if a next entry is found + const char *path; // Path to the iterated object/array + int path_len; // Path length - optimisation + int found; // Non-0 if found the next entry + struct json_token *key; // Object's key + struct json_token *val; // Object's value + int *idx; // Array index }; static void next_set_key(struct next_data *d, const char *name, int name_len, int is_array) { - if (is_array) { - /* Array. Set index and reset key */ - if (d->key != NULL) { - d->key->len = 0; - d->key->ptr = NULL; + if (is_array) { + /* Array. Set index and reset key */ + if (d->key != NULL) { + d->key->len = 0; + d->key->ptr = NULL; + } + if (d->idx != NULL) *d->idx = atoi(name); + } else { + /* Object. Set key and make index -1 */ + if (d->key != NULL) { + d->key->ptr = name; + d->key->len = name_len; + } + if (d->idx != NULL) *d->idx = -1; } - if (d->idx != NULL) *d->idx = atoi(name); - } else { - /* Object. Set key and make index -1 */ - if (d->key != NULL) { - d->key->ptr = name; - d->key->len = name_len; - } - if (d->idx != NULL) *d->idx = -1; - } } static void json_next_cb(void *userdata, const char *name, size_t name_len, const char *path, const struct json_token *t) { - struct next_data *d = (struct next_data *) userdata; - const char *p = path + d->path_len; - if (d->found) return; - if (d->path_len >= (int) strlen(path)) return; - if (strncmp(d->path, path, d->path_len) != 0) return; - if (strchr(p + 1, '.') != NULL) return; /* More nested objects - skip */ - if (strchr(p + 1, '[') != NULL) return; /* Ditto for arrays */ - // {OBJECT,ARRAY}_END types do not pass name, _START does. Save key. - if (t->type == JSON_TYPE_OBJECT_START || t->type == JSON_TYPE_ARRAY_START) { - next_set_key(d, name, name_len, p[0] == '['); - } else if (d->handle == NULL || d->handle < (void *) t->ptr) { - if (t->type != JSON_TYPE_OBJECT_END && t->type != JSON_TYPE_ARRAY_END) { - next_set_key(d, name, name_len, p[0] == '['); + struct next_data *d = (struct next_data *) userdata; + const char *p = path + d->path_len; + if (d->found) return; + if (d->path_len >= (int) strlen(path)) return; + if (strncmp(d->path, path, d->path_len) != 0) return; + if (strchr(p + 1, '.') != NULL) return; /* More nested objects - skip */ + if (strchr(p + 1, '[') != NULL) return; /* Ditto for arrays */ + // {OBJECT,ARRAY}_END types do not pass name, _START does. Save key. + if (t->type == JSON_TYPE_OBJECT_START || t->type == JSON_TYPE_ARRAY_START) { + next_set_key(d, name, name_len, p[0] == '['); + } else if (d->handle == NULL || d->handle < (void *) t->ptr) { + if (t->type != JSON_TYPE_OBJECT_END && t->type != JSON_TYPE_ARRAY_END) { + next_set_key(d, name, name_len, p[0] == '['); + } + if (d->val != NULL) *d->val = *t; + d->handle = (void *) t->ptr; + d->found = 1; } - if (d->val != NULL) *d->val = *t; - d->handle = (void *) t->ptr; - d->found = 1; - } } static void *json_next(const char *s, int len, void *handle, const char *path, struct json_token *key, struct json_token *val, int *i) { - struct json_token tmpval, *v = val == NULL ? &tmpval : val; - struct json_token tmpkey, *k = key == NULL ? &tmpkey : key; - int tmpidx, *pidx = i == NULL ? &tmpidx : i; - struct next_data data = {handle, path, (int) strlen(path), 0, k, v, pidx}; - json_walk(s, len, json_next_cb, &data); - return data.found ? data.handle : NULL; + struct json_token tmpval, *v = val == NULL ? &tmpval : val; + struct json_token tmpkey, *k = key == NULL ? &tmpkey : key; + int tmpidx, *pidx = i == NULL ? &tmpidx : i; + struct next_data data = {handle, path, (int) strlen(path), 0, k, v, pidx}; + json_walk(s, len, json_next_cb, &data); + return data.found ? data.handle : NULL; } void *json_next_key(const char *s, int len, void *handle, const char *path, struct json_token *key, struct json_token *val) WEAK; void *json_next_key(const char *s, int len, void *handle, const char *path, struct json_token *key, struct json_token *val) { - return json_next(s, len, handle, path, key, val, NULL); + return json_next(s, len, handle, path, key, val, NULL); } void *json_next_elem(const char *s, int len, void *handle, const char *path, int *idx, struct json_token *val) WEAK; void *json_next_elem(const char *s, int len, void *handle, const char *path, int *idx, struct json_token *val) { - return json_next(s, len, handle, path, NULL, val, idx); + return json_next(s, len, handle, path, NULL, val, idx); } static int json_sprinter(struct json_out *out, const char *str, size_t len) { - size_t old_len = out->u.buf.buf == NULL ? 0 : strlen(out->u.buf.buf); - size_t new_len = len + old_len; - char *p = (char *) realloc(out->u.buf.buf, new_len + 1); - if (p != NULL) { - memcpy(p + old_len, str, len); - p[new_len] = '\0'; - out->u.buf.buf = p; - } - return len; + size_t old_len = out->u.buf.buf == NULL ? 0 : strlen(out->u.buf.buf); + size_t new_len = len + old_len; + char *p = (char *) realloc(out->u.buf.buf, new_len + 1); + if (p != NULL) { + memcpy(p + old_len, str, len); + p[new_len] = '\0'; + out->u.buf.buf = p; + } + return len; } char *json_vasprintf(const char *fmt, va_list ap) WEAK; char *json_vasprintf(const char *fmt, va_list ap) { - struct json_out out; - memset(&out, 0, sizeof(out)); - out.printer = json_sprinter; - json_vprintf(&out, fmt, ap); - return out.u.buf.buf; + struct json_out out; + memset(&out, 0, sizeof(out)); + out.printer = json_sprinter; + json_vprintf(&out, fmt, ap); + return out.u.buf.buf; } char *json_asprintf(const char *fmt, ...) WEAK; char *json_asprintf(const char *fmt, ...) { - char *result = NULL; - va_list ap; - va_start(ap, fmt); - result = json_vasprintf(fmt, ap); - va_end(ap); - return result; + char *result = NULL; + va_list ap; + va_start(ap, fmt); + result = json_vasprintf(fmt, ap); + va_end(ap); + return result; } diff --git a/armsrc/frozen.h b/armsrc/frozen.h index cfe651e12..49183ee7d 100644 --- a/armsrc/frozen.h +++ b/armsrc/frozen.h @@ -36,18 +36,18 @@ enum { false = 0, true = 1 }; /* JSON token type */ enum json_token_type { - JSON_TYPE_INVALID = 0, /* memsetting to 0 should create INVALID value */ - JSON_TYPE_STRING, - JSON_TYPE_NUMBER, - JSON_TYPE_TRUE, - JSON_TYPE_FALSE, - JSON_TYPE_NULL, - JSON_TYPE_OBJECT_START, - JSON_TYPE_OBJECT_END, - JSON_TYPE_ARRAY_START, - JSON_TYPE_ARRAY_END, + JSON_TYPE_INVALID = 0, /* memsetting to 0 should create INVALID value */ + JSON_TYPE_STRING, + JSON_TYPE_NUMBER, + JSON_TYPE_TRUE, + JSON_TYPE_FALSE, + JSON_TYPE_NULL, + JSON_TYPE_OBJECT_START, + JSON_TYPE_OBJECT_END, + JSON_TYPE_ARRAY_START, + JSON_TYPE_ARRAY_END, - JSON_TYPES_CNT + JSON_TYPES_CNT }; /* @@ -55,9 +55,9 @@ enum json_token_type { * `json_scanf()` with the format specifier `%T`. */ struct json_token { - const char *ptr; /* Points to the beginning of the value */ - int len; /* Value length */ - enum json_token_type type; /* Type of the token, possible values are above */ + const char *ptr; /* Points to the beginning of the value */ + int len; /* Value length */ + enum json_token_type type; /* Type of the token, possible values are above */ }; #define JSON_INVALID_TOKEN \ @@ -110,16 +110,16 @@ int json_walk(const char *json_string, int json_string_length, * struct json_out abstracts output, allowing alternative printing plugins. */ struct json_out { - int (*printer)(struct json_out *, const char *str, size_t len); - union { - struct { - char *buf; - size_t size; - size_t len; - } buf; - void *data; - FILE *fp; - } u; + int (*printer)(struct json_out *, const char *str, size_t len); + union { + struct { + char *buf; + size_t size; + size_t len; + } buf; + void *data; + FILE *fp; + } u; }; extern int json_printer_buf(struct json_out *, const char *, size_t); diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 2618bec44..b17df8424 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -464,7 +464,7 @@ RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non_real_t } -// Thinfilm, Kovio mangels ISO14443A in the way that they don't use start bit nor parity bits. +// Thinfilm, Kovio mangels ISO14443A in the way that they don't use start bit nor parity bits. RAMFUNC int ManchesterDecoding_Thinfilm(uint8_t bit) { Demod.twoBits = (Demod.twoBits << 8) | bit; @@ -496,44 +496,44 @@ RAMFUNC int ManchesterDecoding_Thinfilm(uint8_t bit) { } } else { - if (IsManchesterModulationNibble1(Demod.twoBits >> Demod.syncBit)) { // modulation in first half - if (IsManchesterModulationNibble2(Demod.twoBits >> Demod.syncBit)) { // ... and in second half = collision - if (!Demod.collisionPos) { - Demod.collisionPos = (Demod.len << 3) + Demod.bitCount; - } - } // modulation in first half only - Sequence D = 1 + if (IsManchesterModulationNibble1(Demod.twoBits >> Demod.syncBit)) { // modulation in first half + if (IsManchesterModulationNibble2(Demod.twoBits >> Demod.syncBit)) { // ... and in second half = collision + if (!Demod.collisionPos) { + Demod.collisionPos = (Demod.len << 3) + Demod.bitCount; + } + } // modulation in first half only - Sequence D = 1 + Demod.bitCount++; + Demod.shiftReg = (Demod.shiftReg << 1) | 0x1; // in both cases, add a 1 to the shiftreg + if (Demod.bitCount == 8) { // if we decoded a full byte + Demod.output[Demod.len++] = (Demod.shiftReg & 0xff); + Demod.bitCount = 0; + Demod.shiftReg = 0; + } + Demod.endTime = Demod.startTime + 8 * (8 * Demod.len + Demod.bitCount + 1) - 4; + } else { // no modulation in first half + if (IsManchesterModulationNibble2(Demod.twoBits >> Demod.syncBit)) { // and modulation in second half = Sequence E = 0 Demod.bitCount++; - Demod.shiftReg = (Demod.shiftReg << 1) | 0x1; // in both cases, add a 1 to the shiftreg - if (Demod.bitCount == 8) { // if we decoded a full byte + Demod.shiftReg = (Demod.shiftReg << 1); // add a 0 to the shiftreg + if (Demod.bitCount >= 8) { // if we decoded a full byte Demod.output[Demod.len++] = (Demod.shiftReg & 0xff); Demod.bitCount = 0; Demod.shiftReg = 0; } - Demod.endTime = Demod.startTime + 8 * (8 * Demod.len + Demod.bitCount + 1) - 4; - } else { // no modulation in first half - if (IsManchesterModulationNibble2(Demod.twoBits >> Demod.syncBit)) { // and modulation in second half = Sequence E = 0 - Demod.bitCount++; - Demod.shiftReg = (Demod.shiftReg << 1); // add a 0 to the shiftreg - if (Demod.bitCount >= 8) { // if we decoded a full byte - Demod.output[Demod.len++] = (Demod.shiftReg & 0xff); - Demod.bitCount = 0; - Demod.shiftReg = 0; - } - Demod.endTime = Demod.startTime + 8 * (8 * Demod.len + Demod.bitCount + 1); - } else { // no modulation in both halves - End of communication - if (Demod.bitCount > 0) { // there are some remaining data bits - Demod.shiftReg <<= (8 - Demod.bitCount); // left align the decoded bits - Demod.output[Demod.len++] = Demod.shiftReg & 0xff; // and add them to the output - return true; - } - if (Demod.len) { - return true; // we are finished with decoding the raw data sequence - } else { // nothing received. Start over - DemodReset(); - } + Demod.endTime = Demod.startTime + 8 * (8 * Demod.len + Demod.bitCount + 1); + } else { // no modulation in both halves - End of communication + if (Demod.bitCount > 0) { // there are some remaining data bits + Demod.shiftReg <<= (8 - Demod.bitCount); // left align the decoded bits + Demod.output[Demod.len++] = Demod.shiftReg & 0xff; // and add them to the output + return true; + } + if (Demod.len) { + return true; // we are finished with decoding the raw data sequence + } else { // nothing received. Start over + DemodReset(); } } } + } return false; // not finished yet, need more data } @@ -655,7 +655,7 @@ void RAMFUNC SniffIso14443a(uint8_t param) { Uart.len, Uart.startTime * 16 - DELAY_READER_AIR2ARM_AS_SNIFFER, Uart.endTime * 16 - DELAY_READER_AIR2ARM_AS_SNIFFER, - Uart.parity, + Uart.parity, true)) break; } /* ready to receive another command. */ @@ -2007,7 +2007,7 @@ bool EmLogTrace(uint8_t *reader_data, uint16_t reader_len, uint32_t reader_Start } //----------------------------------------------------------------------------- -// Kovio - Thinfilm barcode. TAG-TALK-FIRST - +// Kovio - Thinfilm barcode. TAG-TALK-FIRST - // Wait a certain time for tag response // If a response is captured return TRUE // If it takes too long return FALSE @@ -2041,7 +2041,7 @@ bool GetIso14443aAnswerFromTag_Thinfilm(uint8_t *receivedResponse, uint8_t *rec // log LogTrace(receivedResponse, Demod.len, Demod.startTime * 16 - DELAY_AIR2ARM_AS_READER, Demod.endTime * 16 - DELAY_AIR2ARM_AS_READER, NULL, false); return true; - } + } } // timeout already in ms + 10ms guard time diff --git a/armsrc/nprintf.c b/armsrc/nprintf.c index b6b200549..62e6ea8c0 100644 --- a/armsrc/nprintf.c +++ b/armsrc/nprintf.c @@ -119,210 +119,201 @@ // output function type -typedef void (*out_fct_type)(char character, void* buffer, size_t idx, size_t maxlen); +typedef void (*out_fct_type)(char character, void *buffer, size_t idx, size_t maxlen); // wrapper (used as buffer) for output function type typedef struct { - void (*fct)(char character, void* arg); - void* arg; + void (*fct)(char character, void *arg); + void *arg; } out_fct_wrap_type; // internal buffer output -static inline void _out_buffer(char character, void* buffer, size_t idx, size_t maxlen) -{ - if (idx < maxlen) { - ((char*)buffer)[idx] = character; - } +static inline void _out_buffer(char character, void *buffer, size_t idx, size_t maxlen) { + if (idx < maxlen) { + ((char *)buffer)[idx] = character; + } } // internal null output -static inline void _out_null(char character, void* buffer, size_t idx, size_t maxlen) -{ - (void)character; (void)buffer; (void)idx; (void)maxlen; +static inline void _out_null(char character, void *buffer, size_t idx, size_t maxlen) { + (void)character; + (void)buffer; + (void)idx; + (void)maxlen; } // internal _putchar wrapper -static inline void _out_char(char character, void* buffer, size_t idx, size_t maxlen) -{ - (void)buffer; (void)idx; (void)maxlen; - if (character) { - _putchar(character); - } +static inline void _out_char(char character, void *buffer, size_t idx, size_t maxlen) { + (void)buffer; + (void)idx; + (void)maxlen; + if (character) { + _putchar(character); + } } // internal output function wrapper -static inline void _out_fct(char character, void* buffer, size_t idx, size_t maxlen) -{ - (void)idx; (void)maxlen; - if (character) { - // buffer is the output fct pointer - ((out_fct_wrap_type*)buffer)->fct(character, ((out_fct_wrap_type*)buffer)->arg); - } +static inline void _out_fct(char character, void *buffer, size_t idx, size_t maxlen) { + (void)idx; + (void)maxlen; + if (character) { + // buffer is the output fct pointer + ((out_fct_wrap_type *)buffer)->fct(character, ((out_fct_wrap_type *)buffer)->arg); + } } // internal secure strlen // \return The length of the string (excluding the terminating 0) limited by 'maxsize' -static inline unsigned int _strnlen_s(const char* str, size_t maxsize) -{ - const char* s; - for (s = str; *s && maxsize--; ++s); - return (unsigned int)(s - str); +static inline unsigned int _strnlen_s(const char *str, size_t maxsize) { + const char *s; + for (s = str; *s && maxsize--; ++s); + return (unsigned int)(s - str); } // internal test if char is a digit (0-9) // \return true if char is a digit -static inline bool _is_digit(char ch) -{ - return (ch >= '0') && (ch <= '9'); +static inline bool _is_digit(char ch) { + return (ch >= '0') && (ch <= '9'); } // internal ASCII string to unsigned int conversion -static unsigned int _atoi(const char** str) -{ - unsigned int i = 0U; - while (_is_digit(**str)) { - i = i * 10U + (unsigned int)(*((*str)++) - '0'); - } - return i; +static unsigned int _atoi(const char **str) { + unsigned int i = 0U; + while (_is_digit(**str)) { + i = i * 10U + (unsigned int)(*((*str)++) - '0'); + } + return i; } // output the specified string in reverse, taking care of any zero-padding -static size_t _out_rev(out_fct_type out, char* buffer, size_t idx, size_t maxlen, const char* buf, size_t len, unsigned int width, unsigned int flags) -{ - const size_t start_idx = idx; +static size_t _out_rev(out_fct_type out, char *buffer, size_t idx, size_t maxlen, const char *buf, size_t len, unsigned int width, unsigned int flags) { + const size_t start_idx = idx; - // pad spaces up to given width - if (!(flags & FLAGS_LEFT) && !(flags & FLAGS_ZEROPAD)) { - for (size_t i = len; i < width; i++) { - out(' ', buffer, idx++, maxlen); + // pad spaces up to given width + if (!(flags & FLAGS_LEFT) && !(flags & FLAGS_ZEROPAD)) { + for (size_t i = len; i < width; i++) { + out(' ', buffer, idx++, maxlen); + } } - } - // reverse string - while (len) { - out(buf[--len], buffer, idx++, maxlen); - } - - // append pad spaces up to given width - if (flags & FLAGS_LEFT) { - while (idx - start_idx < width) { - out(' ', buffer, idx++, maxlen); + // reverse string + while (len) { + out(buf[--len], buffer, idx++, maxlen); } - } - return idx; + // append pad spaces up to given width + if (flags & FLAGS_LEFT) { + while (idx - start_idx < width) { + out(' ', buffer, idx++, maxlen); + } + } + + return idx; } // internal itoa format -static size_t _ntoa_format(out_fct_type out, char* buffer, size_t idx, size_t maxlen, char* buf, size_t len, bool negative, unsigned int base, unsigned int prec, unsigned int width, unsigned int flags) -{ - // pad leading zeros - if (!(flags & FLAGS_LEFT)) { - if (width && (flags & FLAGS_ZEROPAD) && (negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) { - width--; +static size_t _ntoa_format(out_fct_type out, char *buffer, size_t idx, size_t maxlen, char *buf, size_t len, bool negative, unsigned int base, unsigned int prec, unsigned int width, unsigned int flags) { + // pad leading zeros + if (!(flags & FLAGS_LEFT)) { + if (width && (flags & FLAGS_ZEROPAD) && (negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) { + width--; + } + while ((len < prec) && (len < PRINTF_NTOA_BUFFER_SIZE)) { + buf[len++] = '0'; + } + while ((flags & FLAGS_ZEROPAD) && (len < width) && (len < PRINTF_NTOA_BUFFER_SIZE)) { + buf[len++] = '0'; + } } - while ((len < prec) && (len < PRINTF_NTOA_BUFFER_SIZE)) { - buf[len++] = '0'; - } - while ((flags & FLAGS_ZEROPAD) && (len < width) && (len < PRINTF_NTOA_BUFFER_SIZE)) { - buf[len++] = '0'; - } - } - // handle hash - if (flags & FLAGS_HASH) { - if (!(flags & FLAGS_PRECISION) && len && ((len == prec) || (len == width))) { - len--; - if (len && (base == 16U)) { - len--; - } - } - if ((base == 16U) && !(flags & FLAGS_UPPERCASE) && (len < PRINTF_NTOA_BUFFER_SIZE)) { - buf[len++] = 'x'; - } - else if ((base == 16U) && (flags & FLAGS_UPPERCASE) && (len < PRINTF_NTOA_BUFFER_SIZE)) { - buf[len++] = 'X'; - } - else if ((base == 2U) && (len < PRINTF_NTOA_BUFFER_SIZE)) { - buf[len++] = 'b'; + // handle hash + if (flags & FLAGS_HASH) { + if (!(flags & FLAGS_PRECISION) && len && ((len == prec) || (len == width))) { + len--; + if (len && (base == 16U)) { + len--; + } + } + if ((base == 16U) && !(flags & FLAGS_UPPERCASE) && (len < PRINTF_NTOA_BUFFER_SIZE)) { + buf[len++] = 'x'; + } else if ((base == 16U) && (flags & FLAGS_UPPERCASE) && (len < PRINTF_NTOA_BUFFER_SIZE)) { + buf[len++] = 'X'; + } else if ((base == 2U) && (len < PRINTF_NTOA_BUFFER_SIZE)) { + buf[len++] = 'b'; + } + if (len < PRINTF_NTOA_BUFFER_SIZE) { + buf[len++] = '0'; + } } + if (len < PRINTF_NTOA_BUFFER_SIZE) { - buf[len++] = '0'; + if (negative) { + buf[len++] = '-'; + } else if (flags & FLAGS_PLUS) { + buf[len++] = '+'; // ignore the space if the '+' exists + } else if (flags & FLAGS_SPACE) { + buf[len++] = ' '; + } } - } - if (len < PRINTF_NTOA_BUFFER_SIZE) { - if (negative) { - buf[len++] = '-'; - } - else if (flags & FLAGS_PLUS) { - buf[len++] = '+'; // ignore the space if the '+' exists - } - else if (flags & FLAGS_SPACE) { - buf[len++] = ' '; - } - } - - return _out_rev(out, buffer, idx, maxlen, buf, len, width, flags); + return _out_rev(out, buffer, idx, maxlen, buf, len, width, flags); } // internal itoa for 'long' type -static size_t _ntoa_long(out_fct_type out, char* buffer, size_t idx, size_t maxlen, unsigned long value, bool negative, unsigned long base, unsigned int prec, unsigned int width, unsigned int flags) -{ - char buf[PRINTF_NTOA_BUFFER_SIZE]; - size_t len = 0U; +static size_t _ntoa_long(out_fct_type out, char *buffer, size_t idx, size_t maxlen, unsigned long value, bool negative, unsigned long base, unsigned int prec, unsigned int width, unsigned int flags) { + char buf[PRINTF_NTOA_BUFFER_SIZE]; + size_t len = 0U; - // no hash for 0 values - if (!value) { - flags &= ~FLAGS_HASH; - } + // no hash for 0 values + if (!value) { + flags &= ~FLAGS_HASH; + } - // write if precision != 0 and value is != 0 - if (!(flags & FLAGS_PRECISION) || value) { - do { - const char digit = (char)(value % base); - buf[len++] = digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10; - value /= base; - } while (value && (len < PRINTF_NTOA_BUFFER_SIZE)); - } + // write if precision != 0 and value is != 0 + if (!(flags & FLAGS_PRECISION) || value) { + do { + const char digit = (char)(value % base); + buf[len++] = digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10; + value /= base; + } while (value && (len < PRINTF_NTOA_BUFFER_SIZE)); + } - return _ntoa_format(out, buffer, idx, maxlen, buf, len, negative, (unsigned int)base, prec, width, flags); + return _ntoa_format(out, buffer, idx, maxlen, buf, len, negative, (unsigned int)base, prec, width, flags); } // internal itoa for 'long long' type #if defined(PRINTF_SUPPORT_LONG_LONG) -static size_t _ntoa_long_long(out_fct_type out, char* buffer, size_t idx, size_t maxlen, unsigned long long value, bool negative, unsigned long long base, unsigned int prec, unsigned int width, unsigned int flags) -{ - char buf[PRINTF_NTOA_BUFFER_SIZE]; - size_t len = 0U; +static size_t _ntoa_long_long(out_fct_type out, char *buffer, size_t idx, size_t maxlen, unsigned long long value, bool negative, unsigned long long base, unsigned int prec, unsigned int width, unsigned int flags) { + char buf[PRINTF_NTOA_BUFFER_SIZE]; + size_t len = 0U; - // no hash for 0 values - if (!value) { - flags &= ~FLAGS_HASH; - } + // no hash for 0 values + if (!value) { + flags &= ~FLAGS_HASH; + } - // write if precision != 0 and value is != 0 - if (!(flags & FLAGS_PRECISION) || value) { - do { - const char digit = (char)(value % base); - buf[len++] = digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10; - value /= base; - } while (value && (len < PRINTF_NTOA_BUFFER_SIZE)); - } + // write if precision != 0 and value is != 0 + if (!(flags & FLAGS_PRECISION) || value) { + do { + const char digit = (char)(value % base); + buf[len++] = digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10; + value /= base; + } while (value && (len < PRINTF_NTOA_BUFFER_SIZE)); + } - return _ntoa_format(out, buffer, idx, maxlen, buf, len, negative, (unsigned int)base, prec, width, flags); + return _ntoa_format(out, buffer, idx, maxlen, buf, len, negative, (unsigned int)base, prec, width, flags); } #endif // PRINTF_SUPPORT_LONG_LONG @@ -331,584 +322,576 @@ static size_t _ntoa_long_long(out_fct_type out, char* buffer, size_t idx, size_t #if defined(PRINTF_SUPPORT_EXPONENTIAL) // forward declaration so that _ftoa can switch to exp notation for values > PRINTF_MAX_FLOAT -static size_t _etoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags); +static size_t _etoa(out_fct_type out, char *buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags); #endif // internal ftoa for fixed decimal floating point -static size_t _ftoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags) -{ - char buf[PRINTF_FTOA_BUFFER_SIZE]; - size_t len = 0U; - double diff = 0.0; +static size_t _ftoa(out_fct_type out, char *buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags) { + char buf[PRINTF_FTOA_BUFFER_SIZE]; + size_t len = 0U; + double diff = 0.0; - // powers of 10 - static const double pow10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 }; + // powers of 10 + static const double pow10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 }; - // test for special values - if (value != value) - return _out_rev(out, buffer, idx, maxlen, "nan", 3, width, flags); - if (value < -DBL_MAX) - return _out_rev(out, buffer, idx, maxlen, "fni-", 4, width, flags); - if (value > DBL_MAX) - return _out_rev(out, buffer, idx, maxlen, (flags & FLAGS_PLUS) ? "fni+" : "fni", (flags & FLAGS_PLUS) ? 4U : 3U, width, flags); + // test for special values + if (value != value) + return _out_rev(out, buffer, idx, maxlen, "nan", 3, width, flags); + if (value < -DBL_MAX) + return _out_rev(out, buffer, idx, maxlen, "fni-", 4, width, flags); + if (value > DBL_MAX) + return _out_rev(out, buffer, idx, maxlen, (flags & FLAGS_PLUS) ? "fni+" : "fni", (flags & FLAGS_PLUS) ? 4U : 3U, width, flags); - // test for very large values - // standard printf behavior is to print EVERY whole number digit -- which could be 100s of characters overflowing your buffers == bad - if ((value > PRINTF_MAX_FLOAT) || (value < -PRINTF_MAX_FLOAT)) { + // test for very large values + // standard printf behavior is to print EVERY whole number digit -- which could be 100s of characters overflowing your buffers == bad + if ((value > PRINTF_MAX_FLOAT) || (value < -PRINTF_MAX_FLOAT)) { #if defined(PRINTF_SUPPORT_EXPONENTIAL) - return _etoa(out, buffer, idx, maxlen, value, prec, width, flags); + return _etoa(out, buffer, idx, maxlen, value, prec, width, flags); #else - return 0U; + return 0U; #endif - } - - // test for negative - bool negative = false; - if (value < 0) { - negative = true; - value = 0 - value; - } - - // set default precision, if not set explicitly - if (!(flags & FLAGS_PRECISION)) { - prec = PRINTF_DEFAULT_FLOAT_PRECISION; - } - // limit precision to 9, cause a prec >= 10 can lead to overflow errors - while ((len < PRINTF_FTOA_BUFFER_SIZE) && (prec > 9U)) { - buf[len++] = '0'; - prec--; - } - - int whole = (int)value; - double tmp = (value - whole) * pow10[prec]; - unsigned long frac = (unsigned long)tmp; - diff = tmp - frac; - - if (diff > 0.5) { - ++frac; - // handle rollover, e.g. case 0.99 with prec 1 is 1.0 - if (frac >= pow10[prec]) { - frac = 0; - ++whole; } - } - else if (diff < 0.5) { - } - else if ((frac == 0U) || (frac & 1U)) { - // if halfway, round up if odd OR if last digit is 0 - ++frac; - } - if (prec == 0U) { - diff = value - (double)whole; - if ((!(diff < 0.5) || (diff > 0.5)) && (whole & 1)) { - // exactly 0.5 and ODD, then round up - // 1.5 -> 2, but 2.5 -> 2 - ++whole; + // test for negative + bool negative = false; + if (value < 0) { + negative = true; + value = 0 - value; } - } - else { - unsigned int count = prec; - // now do fractional part, as an unsigned number + + // set default precision, if not set explicitly + if (!(flags & FLAGS_PRECISION)) { + prec = PRINTF_DEFAULT_FLOAT_PRECISION; + } + // limit precision to 9, cause a prec >= 10 can lead to overflow errors + while ((len < PRINTF_FTOA_BUFFER_SIZE) && (prec > 9U)) { + buf[len++] = '0'; + prec--; + } + + int whole = (int)value; + double tmp = (value - whole) * pow10[prec]; + unsigned long frac = (unsigned long)tmp; + diff = tmp - frac; + + if (diff > 0.5) { + ++frac; + // handle rollover, e.g. case 0.99 with prec 1 is 1.0 + if (frac >= pow10[prec]) { + frac = 0; + ++whole; + } + } else if (diff < 0.5) { + } else if ((frac == 0U) || (frac & 1U)) { + // if halfway, round up if odd OR if last digit is 0 + ++frac; + } + + if (prec == 0U) { + diff = value - (double)whole; + if ((!(diff < 0.5) || (diff > 0.5)) && (whole & 1)) { + // exactly 0.5 and ODD, then round up + // 1.5 -> 2, but 2.5 -> 2 + ++whole; + } + } else { + unsigned int count = prec; + // now do fractional part, as an unsigned number + while (len < PRINTF_FTOA_BUFFER_SIZE) { + --count; + buf[len++] = (char)(48U + (frac % 10U)); + if (!(frac /= 10U)) { + break; + } + } + // add extra 0s + while ((len < PRINTF_FTOA_BUFFER_SIZE) && (count-- > 0U)) { + buf[len++] = '0'; + } + if (len < PRINTF_FTOA_BUFFER_SIZE) { + // add decimal + buf[len++] = '.'; + } + } + + // do whole part, number is reversed while (len < PRINTF_FTOA_BUFFER_SIZE) { - --count; - buf[len++] = (char)(48U + (frac % 10U)); - if (!(frac /= 10U)) { - break; - } + buf[len++] = (char)(48 + (whole % 10)); + if (!(whole /= 10)) { + break; + } } - // add extra 0s - while ((len < PRINTF_FTOA_BUFFER_SIZE) && (count-- > 0U)) { - buf[len++] = '0'; + + // pad leading zeros + if (!(flags & FLAGS_LEFT) && (flags & FLAGS_ZEROPAD)) { + if (width && (negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) { + width--; + } + while ((len < width) && (len < PRINTF_FTOA_BUFFER_SIZE)) { + buf[len++] = '0'; + } } + if (len < PRINTF_FTOA_BUFFER_SIZE) { - // add decimal - buf[len++] = '.'; + if (negative) { + buf[len++] = '-'; + } else if (flags & FLAGS_PLUS) { + buf[len++] = '+'; // ignore the space if the '+' exists + } else if (flags & FLAGS_SPACE) { + buf[len++] = ' '; + } } - } - // do whole part, number is reversed - while (len < PRINTF_FTOA_BUFFER_SIZE) { - buf[len++] = (char)(48 + (whole % 10)); - if (!(whole /= 10)) { - break; - } - } - - // pad leading zeros - if (!(flags & FLAGS_LEFT) && (flags & FLAGS_ZEROPAD)) { - if (width && (negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) { - width--; - } - while ((len < width) && (len < PRINTF_FTOA_BUFFER_SIZE)) { - buf[len++] = '0'; - } - } - - if (len < PRINTF_FTOA_BUFFER_SIZE) { - if (negative) { - buf[len++] = '-'; - } - else if (flags & FLAGS_PLUS) { - buf[len++] = '+'; // ignore the space if the '+' exists - } - else if (flags & FLAGS_SPACE) { - buf[len++] = ' '; - } - } - - return _out_rev(out, buffer, idx, maxlen, buf, len, width, flags); + return _out_rev(out, buffer, idx, maxlen, buf, len, width, flags); } #if defined(PRINTF_SUPPORT_EXPONENTIAL) // internal ftoa variant for exponential floating-point type, contributed by Martijn Jasperse -static size_t _etoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags) -{ - // check for NaN and special values - if ((value != value) || (value > DBL_MAX) || (value < -DBL_MAX)) { - return _ftoa(out, buffer, idx, maxlen, value, prec, width, flags); - } - - // determine the sign - const bool negative = value < 0; - if (negative) { - value = -value; - } - - // default precision - if (!(flags & FLAGS_PRECISION)) { - prec = PRINTF_DEFAULT_FLOAT_PRECISION; - } - - // determine the decimal exponent - // based on the algorithm by David Gay (https://www.ampl.com/netlib/fp/dtoa.c) - union { - uint64_t U; - double F; - } conv; - - conv.F = value; - int exp2 = (int)((conv.U >> 52U) & 0x07FFU) - 1023; // effectively log2 - conv.U = (conv.U & ((1ULL << 52U) - 1U)) | (1023ULL << 52U); // drop the exponent so conv.F is now in [1,2) - // now approximate log10 from the log2 integer part and an expansion of ln around 1.5 - int expval = (int)(0.1760912590558 + exp2 * 0.301029995663981 + (conv.F - 1.5) * 0.289529654602168); - // now we want to compute 10^expval but we want to be sure it won't overflow - exp2 = (int)(expval * 3.321928094887362 + 0.5); - const double z = expval * 2.302585092994046 - exp2 * 0.6931471805599453; - const double z2 = z * z; - conv.U = (uint64_t)(exp2 + 1023) << 52U; - // compute exp(z) using continued fractions, see https://en.wikipedia.org/wiki/Exponential_function#Continued_fractions_for_ex - conv.F *= 1 + 2 * z / (2 - z + (z2 / (6 + (z2 / (10 + z2 / 14))))); - // correct for rounding errors - if (value < conv.F) { - expval--; - conv.F /= 10; - } - - // the exponent format is "%+03d" and largest value is "307", so set aside 4-5 characters - unsigned int minwidth = ((expval < 100) && (expval > -100)) ? 4U : 5U; - - // in "%g" mode, "prec" is the number of *significant figures* not decimals - if (flags & FLAGS_ADAPT_EXP) { - // do we want to fall-back to "%f" mode? - if ((value >= 1e-4) && (value < 1e6)) { - if ((int)prec > expval) { - prec = (unsigned)((int)prec - expval - 1); - } - else { - prec = 0; - } - flags |= FLAGS_PRECISION; // make sure _ftoa respects precision - // no characters in exponent - minwidth = 0U; - expval = 0; +static size_t _etoa(out_fct_type out, char *buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags) { + // check for NaN and special values + if ((value != value) || (value > DBL_MAX) || (value < -DBL_MAX)) { + return _ftoa(out, buffer, idx, maxlen, value, prec, width, flags); } - else { - // we use one sigfig for the whole part - if ((prec > 0) && (flags & FLAGS_PRECISION)) { - --prec; - } + + // determine the sign + const bool negative = value < 0; + if (negative) { + value = -value; } - } - // will everything fit? - unsigned int fwidth = width; - if (width > minwidth) { - // we didn't fall-back so subtract the characters required for the exponent - fwidth -= minwidth; - } else { - // not enough characters, so go back to default sizing - fwidth = 0U; - } - if ((flags & FLAGS_LEFT) && minwidth) { - // if we're padding on the right, DON'T pad the floating part - fwidth = 0U; - } - - // rescale the float value - if (expval) { - value /= conv.F; - } - - // output the floating part - const size_t start_idx = idx; - idx = _ftoa(out, buffer, idx, maxlen, negative ? -value : value, prec, fwidth, flags & ~FLAGS_ADAPT_EXP); - - // output the exponent part - if (minwidth) { - // output the exponential symbol - out((flags & FLAGS_UPPERCASE) ? 'E' : 'e', buffer, idx++, maxlen); - // output the exponent value - idx = _ntoa_long(out, buffer, idx, maxlen, (expval < 0) ? -expval : expval, expval < 0, 10, 0, minwidth-1, FLAGS_ZEROPAD | FLAGS_PLUS); - // might need to right-pad spaces - if (flags & FLAGS_LEFT) { - while (idx - start_idx < width) out(' ', buffer, idx++, maxlen); + // default precision + if (!(flags & FLAGS_PRECISION)) { + prec = PRINTF_DEFAULT_FLOAT_PRECISION; } - } - return idx; + + // determine the decimal exponent + // based on the algorithm by David Gay (https://www.ampl.com/netlib/fp/dtoa.c) + union { + uint64_t U; + double F; + } conv; + + conv.F = value; + int exp2 = (int)((conv.U >> 52U) & 0x07FFU) - 1023; // effectively log2 + conv.U = (conv.U & ((1ULL << 52U) - 1U)) | (1023ULL << 52U); // drop the exponent so conv.F is now in [1,2) + // now approximate log10 from the log2 integer part and an expansion of ln around 1.5 + int expval = (int)(0.1760912590558 + exp2 * 0.301029995663981 + (conv.F - 1.5) * 0.289529654602168); + // now we want to compute 10^expval but we want to be sure it won't overflow + exp2 = (int)(expval * 3.321928094887362 + 0.5); + const double z = expval * 2.302585092994046 - exp2 * 0.6931471805599453; + const double z2 = z * z; + conv.U = (uint64_t)(exp2 + 1023) << 52U; + // compute exp(z) using continued fractions, see https://en.wikipedia.org/wiki/Exponential_function#Continued_fractions_for_ex + conv.F *= 1 + 2 * z / (2 - z + (z2 / (6 + (z2 / (10 + z2 / 14))))); + // correct for rounding errors + if (value < conv.F) { + expval--; + conv.F /= 10; + } + + // the exponent format is "%+03d" and largest value is "307", so set aside 4-5 characters + unsigned int minwidth = ((expval < 100) && (expval > -100)) ? 4U : 5U; + + // in "%g" mode, "prec" is the number of *significant figures* not decimals + if (flags & FLAGS_ADAPT_EXP) { + // do we want to fall-back to "%f" mode? + if ((value >= 1e-4) && (value < 1e6)) { + if ((int)prec > expval) { + prec = (unsigned)((int)prec - expval - 1); + } else { + prec = 0; + } + flags |= FLAGS_PRECISION; // make sure _ftoa respects precision + // no characters in exponent + minwidth = 0U; + expval = 0; + } else { + // we use one sigfig for the whole part + if ((prec > 0) && (flags & FLAGS_PRECISION)) { + --prec; + } + } + } + + // will everything fit? + unsigned int fwidth = width; + if (width > minwidth) { + // we didn't fall-back so subtract the characters required for the exponent + fwidth -= minwidth; + } else { + // not enough characters, so go back to default sizing + fwidth = 0U; + } + if ((flags & FLAGS_LEFT) && minwidth) { + // if we're padding on the right, DON'T pad the floating part + fwidth = 0U; + } + + // rescale the float value + if (expval) { + value /= conv.F; + } + + // output the floating part + const size_t start_idx = idx; + idx = _ftoa(out, buffer, idx, maxlen, negative ? -value : value, prec, fwidth, flags & ~FLAGS_ADAPT_EXP); + + // output the exponent part + if (minwidth) { + // output the exponential symbol + out((flags & FLAGS_UPPERCASE) ? 'E' : 'e', buffer, idx++, maxlen); + // output the exponent value + idx = _ntoa_long(out, buffer, idx, maxlen, (expval < 0) ? -expval : expval, expval < 0, 10, 0, minwidth - 1, FLAGS_ZEROPAD | FLAGS_PLUS); + // might need to right-pad spaces + if (flags & FLAGS_LEFT) { + while (idx - start_idx < width) out(' ', buffer, idx++, maxlen); + } + } + return idx; } #endif // PRINTF_SUPPORT_EXPONENTIAL #endif // PRINTF_SUPPORT_FLOAT // internal vsnprintf -static int _vsnprintf(out_fct_type out, char* buffer, const size_t maxlen, const char* format, va_list va) -{ - unsigned int flags, width, precision, n; - size_t idx = 0U; +static int _vsnprintf(out_fct_type out, char *buffer, const size_t maxlen, const char *format, va_list va) { + unsigned int flags, width, precision, n; + size_t idx = 0U; - if (!buffer) { - // use null output function - out = _out_null; - } - - while (*format) - { - // format specifier? %[flags][width][.precision][length] - if (*format != '%') { - // no - out(*format, buffer, idx++, maxlen); - format++; - continue; - } - else { - // yes, evaluate it - format++; + if (!buffer) { + // use null output function + out = _out_null; } - // evaluate flags - flags = 0U; - do { - switch (*format) { - case '0': flags |= FLAGS_ZEROPAD; format++; n = 1U; break; - case '-': flags |= FLAGS_LEFT; format++; n = 1U; break; - case '+': flags |= FLAGS_PLUS; format++; n = 1U; break; - case ' ': flags |= FLAGS_SPACE; format++; n = 1U; break; - case '#': flags |= FLAGS_HASH; format++; n = 1U; break; - default : n = 0U; break; - } - } while (n); - - // evaluate width field - width = 0U; - if (_is_digit(*format)) { - width = _atoi(&format); - } - else if (*format == '*') { - const int w = va_arg(va, int); - if (w < 0) { - flags |= FLAGS_LEFT; // reverse padding - width = (unsigned int)-w; - } - else { - width = (unsigned int)w; - } - format++; - } - - // evaluate precision field - precision = 0U; - if (*format == '.') { - flags |= FLAGS_PRECISION; - format++; - if (_is_digit(*format)) { - precision = _atoi(&format); - } - else if (*format == '*') { - const int prec = (int)va_arg(va, int); - precision = prec > 0 ? (unsigned int)prec : 0U; - format++; - } - } - - // evaluate length field - switch (*format) { - case 'l' : - flags |= FLAGS_LONG; - format++; - if (*format == 'l') { - flags |= FLAGS_LONG_LONG; - format++; + while (*format) { + // format specifier? %[flags][width][.precision][length] + if (*format != '%') { + // no + out(*format, buffer, idx++, maxlen); + format++; + continue; + } else { + // yes, evaluate it + format++; } - break; - case 'h' : - flags |= FLAGS_SHORT; - format++; - if (*format == 'h') { - flags |= FLAGS_CHAR; - format++; + + // evaluate flags + flags = 0U; + do { + switch (*format) { + case '0': + flags |= FLAGS_ZEROPAD; + format++; + n = 1U; + break; + case '-': + flags |= FLAGS_LEFT; + format++; + n = 1U; + break; + case '+': + flags |= FLAGS_PLUS; + format++; + n = 1U; + break; + case ' ': + flags |= FLAGS_SPACE; + format++; + n = 1U; + break; + case '#': + flags |= FLAGS_HASH; + format++; + n = 1U; + break; + default : + n = 0U; + break; + } + } while (n); + + // evaluate width field + width = 0U; + if (_is_digit(*format)) { + width = _atoi(&format); + } else if (*format == '*') { + const int w = va_arg(va, int); + if (w < 0) { + flags |= FLAGS_LEFT; // reverse padding + width = (unsigned int) - w; + } else { + width = (unsigned int)w; + } + format++; } - break; + + // evaluate precision field + precision = 0U; + if (*format == '.') { + flags |= FLAGS_PRECISION; + format++; + if (_is_digit(*format)) { + precision = _atoi(&format); + } else if (*format == '*') { + const int prec = (int)va_arg(va, int); + precision = prec > 0 ? (unsigned int)prec : 0U; + format++; + } + } + + // evaluate length field + switch (*format) { + case 'l' : + flags |= FLAGS_LONG; + format++; + if (*format == 'l') { + flags |= FLAGS_LONG_LONG; + format++; + } + break; + case 'h' : + flags |= FLAGS_SHORT; + format++; + if (*format == 'h') { + flags |= FLAGS_CHAR; + format++; + } + break; #if defined(PRINTF_SUPPORT_PTRDIFF_T) - case 't' : - flags |= (sizeof(ptrdiff_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); - format++; - break; + case 't' : + flags |= (sizeof(ptrdiff_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); + format++; + break; #endif - case 'j' : - flags |= (sizeof(intmax_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); - format++; - break; - case 'z' : - flags |= (sizeof(size_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); - format++; - break; - default : - break; - } - - // evaluate specifier - switch (*format) { - case 'd' : - case 'i' : - case 'u' : - case 'x' : - case 'X' : - case 'o' : - case 'b' : { - // set the base - unsigned int base; - if (*format == 'x' || *format == 'X') { - base = 16U; - } - else if (*format == 'o') { - base = 8U; - } - else if (*format == 'b') { - base = 2U; - } - else { - base = 10U; - flags &= ~FLAGS_HASH; // no hash for dec format - } - // uppercase - if (*format == 'X') { - flags |= FLAGS_UPPERCASE; + case 'j' : + flags |= (sizeof(intmax_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); + format++; + break; + case 'z' : + flags |= (sizeof(size_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); + format++; + break; + default : + break; } - // no plus or space flag for u, x, X, o, b - if ((*format != 'i') && (*format != 'd')) { - flags &= ~(FLAGS_PLUS | FLAGS_SPACE); - } + // evaluate specifier + switch (*format) { + case 'd' : + case 'i' : + case 'u' : + case 'x' : + case 'X' : + case 'o' : + case 'b' : { + // set the base + unsigned int base; + if (*format == 'x' || *format == 'X') { + base = 16U; + } else if (*format == 'o') { + base = 8U; + } else if (*format == 'b') { + base = 2U; + } else { + base = 10U; + flags &= ~FLAGS_HASH; // no hash for dec format + } + // uppercase + if (*format == 'X') { + flags |= FLAGS_UPPERCASE; + } - // ignore '0' flag when precision is given - if (flags & FLAGS_PRECISION) { - flags &= ~FLAGS_ZEROPAD; - } + // no plus or space flag for u, x, X, o, b + if ((*format != 'i') && (*format != 'd')) { + flags &= ~(FLAGS_PLUS | FLAGS_SPACE); + } - // convert the integer - if ((*format == 'i') || (*format == 'd')) { - // signed - if (flags & FLAGS_LONG_LONG) { + // ignore '0' flag when precision is given + if (flags & FLAGS_PRECISION) { + flags &= ~FLAGS_ZEROPAD; + } + + // convert the integer + if ((*format == 'i') || (*format == 'd')) { + // signed + if (flags & FLAGS_LONG_LONG) { #if defined(PRINTF_SUPPORT_LONG_LONG) - const long long value = va_arg(va, long long); - idx = _ntoa_long_long(out, buffer, idx, maxlen, (unsigned long long)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags); + const long long value = va_arg(va, long long); + idx = _ntoa_long_long(out, buffer, idx, maxlen, (unsigned long long)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags); #endif - } - else if (flags & FLAGS_LONG) { - const long value = va_arg(va, long); - idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned long)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags); - } - else { - const int value = (flags & FLAGS_CHAR) ? (char)va_arg(va, int) : (flags & FLAGS_SHORT) ? (short int)va_arg(va, int) : va_arg(va, int); - idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned int)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags); - } - } - else { - // unsigned - if (flags & FLAGS_LONG_LONG) { + } else if (flags & FLAGS_LONG) { + const long value = va_arg(va, long); + idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned long)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags); + } else { + const int value = (flags & FLAGS_CHAR) ? (char)va_arg(va, int) : (flags & FLAGS_SHORT) ? (short int)va_arg(va, int) : va_arg(va, int); + idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned int)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags); + } + } else { + // unsigned + if (flags & FLAGS_LONG_LONG) { #if defined(PRINTF_SUPPORT_LONG_LONG) - idx = _ntoa_long_long(out, buffer, idx, maxlen, va_arg(va, unsigned long long), false, base, precision, width, flags); + idx = _ntoa_long_long(out, buffer, idx, maxlen, va_arg(va, unsigned long long), false, base, precision, width, flags); #endif - } - else if (flags & FLAGS_LONG) { - idx = _ntoa_long(out, buffer, idx, maxlen, va_arg(va, unsigned long), false, base, precision, width, flags); - } - else { - const unsigned int value = (flags & FLAGS_CHAR) ? (unsigned char)va_arg(va, unsigned int) : (flags & FLAGS_SHORT) ? (unsigned short int)va_arg(va, unsigned int) : va_arg(va, unsigned int); - idx = _ntoa_long(out, buffer, idx, maxlen, value, false, base, precision, width, flags); - } - } - format++; - break; - } + } else if (flags & FLAGS_LONG) { + idx = _ntoa_long(out, buffer, idx, maxlen, va_arg(va, unsigned long), false, base, precision, width, flags); + } else { + const unsigned int value = (flags & FLAGS_CHAR) ? (unsigned char)va_arg(va, unsigned int) : (flags & FLAGS_SHORT) ? (unsigned short int)va_arg(va, unsigned int) : va_arg(va, unsigned int); + idx = _ntoa_long(out, buffer, idx, maxlen, value, false, base, precision, width, flags); + } + } + format++; + break; + } #if defined(PRINTF_SUPPORT_FLOAT) - case 'f' : - case 'F' : - if (*format == 'F') flags |= FLAGS_UPPERCASE; - idx = _ftoa(out, buffer, idx, maxlen, va_arg(va, double), precision, width, flags); - format++; - break; + case 'f' : + case 'F' : + if (*format == 'F') flags |= FLAGS_UPPERCASE; + idx = _ftoa(out, buffer, idx, maxlen, va_arg(va, double), precision, width, flags); + format++; + break; #if defined(PRINTF_SUPPORT_EXPONENTIAL) - case 'e': - case 'E': - case 'g': - case 'G': - if ((*format == 'g')||(*format == 'G')) flags |= FLAGS_ADAPT_EXP; - if ((*format == 'E')||(*format == 'G')) flags |= FLAGS_UPPERCASE; - idx = _etoa(out, buffer, idx, maxlen, va_arg(va, double), precision, width, flags); - format++; - break; + case 'e': + case 'E': + case 'g': + case 'G': + if ((*format == 'g') || (*format == 'G')) flags |= FLAGS_ADAPT_EXP; + if ((*format == 'E') || (*format == 'G')) flags |= FLAGS_UPPERCASE; + idx = _etoa(out, buffer, idx, maxlen, va_arg(va, double), precision, width, flags); + format++; + break; #endif // PRINTF_SUPPORT_EXPONENTIAL #endif // PRINTF_SUPPORT_FLOAT - case 'c' : { - unsigned int l = 1U; - // pre padding - if (!(flags & FLAGS_LEFT)) { - while (l++ < width) { - out(' ', buffer, idx++, maxlen); - } - } - // char output - out((char)va_arg(va, int), buffer, idx++, maxlen); - // post padding - if (flags & FLAGS_LEFT) { - while (l++ < width) { - out(' ', buffer, idx++, maxlen); - } - } - format++; - break; - } + case 'c' : { + unsigned int l = 1U; + // pre padding + if (!(flags & FLAGS_LEFT)) { + while (l++ < width) { + out(' ', buffer, idx++, maxlen); + } + } + // char output + out((char)va_arg(va, int), buffer, idx++, maxlen); + // post padding + if (flags & FLAGS_LEFT) { + while (l++ < width) { + out(' ', buffer, idx++, maxlen); + } + } + format++; + break; + } - case 's' : { - const char* p = va_arg(va, char*); - unsigned int l = _strnlen_s(p, precision ? precision : (size_t)-1); - // pre padding - if (flags & FLAGS_PRECISION) { - l = (l < precision ? l : precision); - } - if (!(flags & FLAGS_LEFT)) { - while (l++ < width) { - out(' ', buffer, idx++, maxlen); - } - } - // string output - while ((*p != 0) && (!(flags & FLAGS_PRECISION) || precision--)) { - out(*(p++), buffer, idx++, maxlen); - } - // post padding - if (flags & FLAGS_LEFT) { - while (l++ < width) { - out(' ', buffer, idx++, maxlen); - } - } - format++; - break; - } + case 's' : { + const char *p = va_arg(va, char *); + unsigned int l = _strnlen_s(p, precision ? precision : (size_t) -1); + // pre padding + if (flags & FLAGS_PRECISION) { + l = (l < precision ? l : precision); + } + if (!(flags & FLAGS_LEFT)) { + while (l++ < width) { + out(' ', buffer, idx++, maxlen); + } + } + // string output + while ((*p != 0) && (!(flags & FLAGS_PRECISION) || precision--)) { + out(*(p++), buffer, idx++, maxlen); + } + // post padding + if (flags & FLAGS_LEFT) { + while (l++ < width) { + out(' ', buffer, idx++, maxlen); + } + } + format++; + break; + } - case 'p' : { - width = sizeof(void*) * 2U; - flags |= FLAGS_ZEROPAD | FLAGS_UPPERCASE; + case 'p' : { + width = sizeof(void *) * 2U; + flags |= FLAGS_ZEROPAD | FLAGS_UPPERCASE; #if defined(PRINTF_SUPPORT_LONG_LONG) - const bool is_ll = sizeof(uintptr_t) == sizeof(long long); - if (is_ll) { - idx = _ntoa_long_long(out, buffer, idx, maxlen, (uintptr_t)va_arg(va, void*), false, 16U, precision, width, flags); - } - else { + const bool is_ll = sizeof(uintptr_t) == sizeof(long long); + if (is_ll) { + idx = _ntoa_long_long(out, buffer, idx, maxlen, (uintptr_t)va_arg(va, void *), false, 16U, precision, width, flags); + } else { #endif - idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned long)((uintptr_t)va_arg(va, void*)), false, 16U, precision, width, flags); + idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned long)((uintptr_t)va_arg(va, void *)), false, 16U, precision, width, flags); #if defined(PRINTF_SUPPORT_LONG_LONG) - } + } #endif - format++; - break; - } + format++; + break; + } - case '%' : - out('%', buffer, idx++, maxlen); - format++; - break; + case '%' : + out('%', buffer, idx++, maxlen); + format++; + break; - default : - out(*format, buffer, idx++, maxlen); - format++; - break; + default : + out(*format, buffer, idx++, maxlen); + format++; + break; + } } - } - // termination - out((char)0, buffer, idx < maxlen ? idx : maxlen - 1U, maxlen); + // termination + out((char)0, buffer, idx < maxlen ? idx : maxlen - 1U, maxlen); - // return written chars without terminating \0 - return (int)idx; + // return written chars without terminating \0 + return (int)idx; } /////////////////////////////////////////////////////////////////////////////// -int printf_(const char* format, ...) -{ - va_list va; - va_start(va, format); - char buffer[1]; - const int ret = _vsnprintf(_out_char, buffer, (size_t)-1, format, va); - va_end(va); - return ret; +int printf_(const char *format, ...) { + va_list va; + va_start(va, format); + char buffer[1]; + const int ret = _vsnprintf(_out_char, buffer, (size_t) -1, format, va); + va_end(va); + return ret; } -int sprintf_(char* buffer, const char* format, ...) -{ - va_list va; - va_start(va, format); - const int ret = _vsnprintf(_out_buffer, buffer, (size_t)-1, format, va); - va_end(va); - return ret; +int sprintf_(char *buffer, const char *format, ...) { + va_list va; + va_start(va, format); + const int ret = _vsnprintf(_out_buffer, buffer, (size_t) -1, format, va); + va_end(va); + return ret; } -int snprintf_(char* buffer, size_t count, const char* format, ...) -{ - va_list va; - va_start(va, format); - const int ret = _vsnprintf(_out_buffer, buffer, count, format, va); - va_end(va); - return ret; +int snprintf_(char *buffer, size_t count, const char *format, ...) { + va_list va; + va_start(va, format); + const int ret = _vsnprintf(_out_buffer, buffer, count, format, va); + va_end(va); + return ret; } -int vprintf_(const char* format, va_list va) -{ - char buffer[1]; - return _vsnprintf(_out_char, buffer, (size_t)-1, format, va); +int vprintf_(const char *format, va_list va) { + char buffer[1]; + return _vsnprintf(_out_char, buffer, (size_t) -1, format, va); } -int vsnprintf_(char* buffer, size_t count, const char* format, va_list va) -{ - return _vsnprintf(_out_buffer, buffer, count, format, va); +int vsnprintf_(char *buffer, size_t count, const char *format, va_list va) { + return _vsnprintf(_out_buffer, buffer, count, format, va); } -int fctprintf(void (*out)(char character, void* arg), void* arg, const char* format, ...) -{ - va_list va; - va_start(va, format); - const out_fct_wrap_type out_fct_wrap = { out, arg }; - const int ret = _vsnprintf(_out_fct, (char*)(uintptr_t)&out_fct_wrap, (size_t)-1, format, va); - va_end(va); - return ret; +int fctprintf(void (*out)(char character, void *arg), void *arg, const char *format, ...) { + va_list va; + va_start(va, format); + const out_fct_wrap_type out_fct_wrap = { out, arg }; + const int ret = _vsnprintf(_out_fct, (char *)(uintptr_t)&out_fct_wrap, (size_t) -1, format, va); + va_end(va); + return ret; } diff --git a/armsrc/nprintf.h b/armsrc/nprintf.h index 8f7a4c8fe..3cfdb4134 100644 --- a/armsrc/nprintf.h +++ b/armsrc/nprintf.h @@ -10,10 +10,10 @@ // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: -// +// // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. -// +// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -58,7 +58,7 @@ void _putchar(char character); * \return The number of characters that are written into the array, not counting the terminating null character */ #define printf printf_ -int printf_(const char* format, ...); +int printf_(const char *format, ...); /** @@ -69,7 +69,7 @@ int printf_(const char* format, ...); * \return The number of characters that are WRITTEN into the buffer, not counting the terminating null character */ #define sprintf sprintf_ -int sprintf_(char* buffer, const char* format, ...); +int sprintf_(char *buffer, const char *format, ...); /** @@ -84,8 +84,8 @@ int sprintf_(char* buffer, const char* format, ...); */ #define snprintf snprintf_ #define vsnprintf vsnprintf_ -int snprintf_(char* buffer, size_t count, const char* format, ...); -int vsnprintf_(char* buffer, size_t count, const char* format, va_list va); +int snprintf_(char *buffer, size_t count, const char *format, ...); +int vsnprintf_(char *buffer, size_t count, const char *format, va_list va); /** @@ -95,7 +95,7 @@ int vsnprintf_(char* buffer, size_t count, const char* format, va_list va); * \return The number of characters that are WRITTEN into the buffer, not counting the terminating null character */ #define vprintf vprintf_ -int vprintf_(const char* format, va_list va); +int vprintf_(const char *format, va_list va); /** @@ -106,7 +106,7 @@ int vprintf_(const char* format, va_list va); * \param format A string that specifies the format of the output * \return The number of characters that are sent to the output function, not counting the terminating null character */ -int fctprintf(void (*out)(char character, void* arg), void* arg, const char* format, ...); +int fctprintf(void (*out)(char character, void *arg), void *arg, const char *format, ...); #ifdef __cplusplus diff --git a/armsrc/string.c b/armsrc/string.c index 7931b9a94..4caa027a2 100644 --- a/armsrc/string.c +++ b/armsrc/string.c @@ -197,56 +197,50 @@ char *strtok(char *s, const char *delim) { } -char *strchr(const char *s, int c) -{ +char *strchr(const char *s, int c) { while (*s != (char)c) if (!*s++) return 0; return (char *)s; } -size_t strspn(const char *s1, const char *s2) -{ - size_t ret=0; - while(*s1 && strchr(s2,*s1++)) +size_t strspn(const char *s1, const char *s2) { + size_t ret = 0; + while (*s1 && strchr(s2, *s1++)) ret++; - return ret; -} - -char *strrchr(const char *s, int c) -{ - const char* ret=0; - do { - if( *s == (char)c ) - ret=s; - } while(*s++); - return (char *)ret; -} - -size_t strcspn(const char *s1, const char *s2) -{ - size_t ret=0; - while(*s1) - if(strchr(s2,*s1)) - return ret; - else - s1++,ret++; return ret; } -char *strpbrk(const char *s1, const char *s2) -{ - while(*s1) - if(strchr(s2, *s1++)) - return (char*)--s1; +char *strrchr(const char *s, int c) { + const char *ret = 0; + do { + if (*s == (char)c) + ret = s; + } while (*s++); + return (char *)ret; +} + +size_t strcspn(const char *s1, const char *s2) { + size_t ret = 0; + while (*s1) + if (strchr(s2, *s1)) + return ret; + else + s1++, ret++; + return ret; +} + +char *strpbrk(const char *s1, const char *s2) { + while (*s1) + if (strchr(s2, *s1++)) + return (char *)--s1; return 0; } -int strncmp(const char* s1, const char* s2, size_t n) -{ - while(n--) - if(*s1++!=*s2++) - return *(unsigned char*)(s1 - 1) - *(unsigned char*)(s2 - 1); +int strncmp(const char *s1, const char *s2, size_t n) { + while (n--) + if (*s1++ != *s2++) + return *(unsigned char *)(s1 - 1) - *(unsigned char *)(s2 - 1); return 0; } @@ -255,97 +249,87 @@ int strncmp(const char* s1, const char* s2, size_t n) #define isspace(a) __extension__ ({ unsigned char bb__isspace = (a) - 9; bb__isspace == (' ' - 9) || bb__isspace <= (13 - 9); }) -unsigned long strtoul(const char *p, char **out_p, int base) -{ - unsigned long v = 0; +unsigned long strtoul(const char *p, char **out_p, int base) { + unsigned long v = 0; - while (isspace(*p)) - p++; - if (((base == 16) || (base == 0)) && - ((*p == '0') && ((p[1] == 'x') || (p[1] == 'X')))) - { - p += 2; - base = 16; - } - if (base == 0) - { - if (*p == '0') - base = 8; - else - base = 10; - } - while (1) - { - char c = *p; - if ((c >= '0') && (c <= '9') && (c - '0' < base)) - v = (v * base) + (c - '0'); - else if ((c >= 'a') && (c <= 'z') && (c - 'a' + 10 < base)) - v = (v * base) + (c - 'a' + 10); - else if ((c >= 'A') && (c <= 'Z') && (c - 'A' + 10 < base)) - v = (v * base) + (c - 'A' + 10); - else - break; - p++; - } + while (isspace(*p)) + p++; + if (((base == 16) || (base == 0)) && + ((*p == '0') && ((p[1] == 'x') || (p[1] == 'X')))) { + p += 2; + base = 16; + } + if (base == 0) { + if (*p == '0') + base = 8; + else + base = 10; + } + while (1) { + char c = *p; + if ((c >= '0') && (c <= '9') && (c - '0' < base)) + v = (v * base) + (c - '0'); + else if ((c >= 'a') && (c <= 'z') && (c - 'a' + 10 < base)) + v = (v * base) + (c - 'a' + 10); + else if ((c >= 'A') && (c <= 'Z') && (c - 'A' + 10 < base)) + v = (v * base) + (c - 'A' + 10); + else + break; + p++; + } - if (out_p) *out_p = (char*)p; - return v; + if (out_p) *out_p = (char *)p; + return v; } -long strtol(const char *p, char **out_p, int base) -{ - long v = 0; - int is_neg = 0; +long strtol(const char *p, char **out_p, int base) { + long v = 0; + int is_neg = 0; - while (isspace(*p)) - p++; - if (*p == '-') - is_neg = 1, p++; - else if (*p == '+') - is_neg = 0; - if (((base == 16) || (base == 0)) && - ((*p == '0') && ((p[1] == 'x') || (p[1] == 'X')))) - { - p += 2; - base = 16; - } - if (base == 0) - { - if (*p == '0') - base = 8; - else - base = 10; - } - while (1) - { - char c = *p; - if ((c >= '0') && (c <= '9') && (c - '0' < base)) - v = (v * base) + (c - '0'); - else if ((c >= 'a') && (c <= 'z') && (c - 'a' + 10 < base)) - v = (v * base) + (c - 'a' + 10); - else if ((c >= 'A') && (c <= 'Z') && (c - 'A' + 10 < base)) - v = (v * base) + (c - 'A' + 10); - else - break; - p++; - } - if (is_neg) - v = -v; - if (out_p) *out_p = (char*)p; - return v; + while (isspace(*p)) + p++; + if (*p == '-') + is_neg = 1, p++; + else if (*p == '+') + is_neg = 0; + if (((base == 16) || (base == 0)) && + ((*p == '0') && ((p[1] == 'x') || (p[1] == 'X')))) { + p += 2; + base = 16; + } + if (base == 0) { + if (*p == '0') + base = 8; + else + base = 10; + } + while (1) { + char c = *p; + if ((c >= '0') && (c <= '9') && (c - '0' < base)) + v = (v * base) + (c - '0'); + else if ((c >= 'a') && (c <= 'z') && (c - 'a' + 10 < base)) + v = (v * base) + (c - 'a' + 10); + else if ((c >= 'A') && (c <= 'Z') && (c - 'A' + 10 < base)) + v = (v * base) + (c - 'A' + 10); + else + break; + p++; + } + if (is_neg) + v = -v; + if (out_p) *out_p = (char *)p; + return v; } -char c_tolower(int c) -{ +char c_tolower(int c) { // (int)a = 97, (int)A = 65 // (a)97 - (A)65 = 32 // therefore 32 + 65 = a return c > 64 && c < 91 ? c + 32 : c; } -char c_isprint (unsigned char c) -{ - if ( c >= 0x20 && c <= 0x7e ) +char c_isprint(unsigned char c) { + if (c >= 0x20 && c <= 0x7e) return 1; return 0; } diff --git a/armsrc/string.h b/armsrc/string.h index 5338ae6b3..5e3e31137 100644 --- a/armsrc/string.h +++ b/armsrc/string.h @@ -32,9 +32,9 @@ size_t strspn(const char *s1, const char *s2); char *strrchr(const char *s, int c); size_t strcspn(const char *s1, const char *s2); char *strpbrk(const char *s1, const char *s2); -int strncmp(const char * s1, const char * s2, size_t n); +int strncmp(const char *s1, const char *s2, size_t n); char c_tolower(int c); -char c_isprint (unsigned char c); +char c_isprint(unsigned char c); diff --git a/client/cmdhfthinfilm.c b/client/cmdhfthinfilm.c index 336843b92..0b2642b1b 100644 --- a/client/cmdhfthinfilm.c +++ b/client/cmdhfthinfilm.c @@ -27,28 +27,28 @@ static int usage_thinfilm_info(void) { // https://github.com/nfc-tools/libnfc/blob/master/utils/nfc-barcode.c static int print_barcode(uint8_t *barcode, const size_t barcode_len) { - PrintAndLogEx(SUCCESS, " Manufacturer : "_YELLOW_("%s") "[0x%02X]", (barcode[0] == 0xB7) ? "Thinfilm" : "unknown", barcode[0] ); + PrintAndLogEx(SUCCESS, " Manufacturer : "_YELLOW_("%s") "[0x%02X]", (barcode[0] == 0xB7) ? "Thinfilm" : "unknown", barcode[0]); PrintAndLogEx(SUCCESS, " Data format : "_YELLOW_("%02X"), barcode[1]); uint8_t b1, b2; compute_crc(CRC_14443_A, barcode, barcode_len - 2, &b1, &b2); bool isok = (barcode[barcode_len - 1] == b1 && barcode[barcode_len - 2] == b2); - + PrintAndLogEx(SUCCESS, " checksum : "_YELLOW_("%02X %02X")"- %s", b2, b1, (isok) ? _GREEN_("OK") : _RED_("fail")); PrintAndLogEx(SUCCESS, " Raw data : "_YELLOW_("%s"), - sprint_hex(barcode, barcode_len) - ); + sprint_hex(barcode, barcode_len) + ); char s[45]; memset(s, 0x00, sizeof(s)); - + switch (barcode[1]) { case 0: printf("Data Format Field: Reserved for allocation by tag manufacturer\n"); return PM3_SUCCESS; case 1: - snprintf(s, sizeof(s), "http://www." ); + snprintf(s, sizeof(s), "http://www."); break; case 2: snprintf(s, sizeof(s), "https://www."); @@ -60,15 +60,15 @@ static int print_barcode(uint8_t *barcode, const size_t barcode_len) { snprintf(s, sizeof(s), "https://"); break; case 5: - PrintAndLogEx(SUCCESS, "EPC: %s", sprint_hex(barcode + 2, 12) ); + PrintAndLogEx(SUCCESS, "EPC: %s", sprint_hex(barcode + 2, 12)); return PM3_SUCCESS; default: PrintAndLogEx(SUCCESS, "Data Format Field: unknown (%02X)", barcode[1]); - PrintAndLogEx(SUCCESS, "Data:" _YELLOW_("%s"), sprint_hex(barcode + 2, barcode_len - 2) ); + PrintAndLogEx(SUCCESS, "Data:" _YELLOW_("%s"), sprint_hex(barcode + 2, barcode_len - 2)); return PM3_SUCCESS; } - - snprintf(s + strlen(s), barcode_len - 3, (const char*)&barcode[2] , barcode_len - 4); + + snprintf(s + strlen(s), barcode_len - 3, (const char *)&barcode[2], barcode_len - 4); for (uint8_t i = 0; i < strlen(s); i++) { @@ -108,8 +108,8 @@ static int CmdHfThinFilmInfo(const char *Cmd) { } int infoThinFilm(void) { - - clearCommandBuffer(); + + clearCommandBuffer(); SendCommandNG(CMD_THINFILM_READ, NULL, 0); PacketResponseNG resp; @@ -117,9 +117,9 @@ int infoThinFilm(void) { PrintAndLogEx(WARNING, "timeout while waiting for reply."); return PM3_ETIMEOUT; } - - if ( resp.status == PM3_SUCCESS ) { - print_barcode( resp.data.asBytes, resp.length ); + + if (resp.status == PM3_SUCCESS) { + print_barcode(resp.data.asBytes, resp.length); } return resp.status; diff --git a/client/cmdhftopaz.c b/client/cmdhftopaz.c index ab3fcb69d..3aebcd673 100644 --- a/client/cmdhftopaz.c +++ b/client/cmdhftopaz.c @@ -43,7 +43,7 @@ static int topaz_send_cmd_raw(uint8_t *cmd, uint8_t len, uint8_t *response, uint SendCommandOLD(CMD_READER_ISO_14443a, ISO14A_RAW | ISO14A_NO_DISCONNECT | ISO14A_TOPAZMODE | ISO14A_NO_RATS, len, 0, cmd, len); PacketResponseNG resp; - + if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { PrintAndLogEx(WARNING, "timeout while waiting for reply."); return PM3_ETIMEOUT; @@ -98,10 +98,10 @@ static int topaz_select(uint8_t *atqa, uint8_t *rid_response) { // read all of the static memory of a selected Topaz tag. static int topaz_rall(uint8_t *uid, uint8_t *response) { - uint16_t resp_len = 0; + uint16_t resp_len = 0; uint8_t rall_cmd[] = {TOPAZ_RALL, 0, 0, 0, 0, 0, 0, 0, 0}; memcpy(&rall_cmd[3], uid, 4); - + if (topaz_send_cmd(rall_cmd, sizeof(rall_cmd), response, &resp_len) == PM3_ETIMEOUT) { topaz_switch_off_field(); return PM3_ESOFT; // RALL failed @@ -119,7 +119,7 @@ static int topaz_read_block(uint8_t *uid, uint8_t blockno, uint8_t *block_data) read8_cmd[1] = blockno; memcpy(&read8_cmd[10], uid, 4); - + if (topaz_send_cmd(read8_cmd, sizeof(read8_cmd), read8_response, &resp_len) == PM3_ETIMEOUT) { topaz_switch_off_field(); return PM3_ESOFT; // READ8 failed @@ -136,7 +136,7 @@ static int topaz_read_segment(uint8_t *uid, uint8_t segno, uint8_t *segment_data rseg_cmd[1] = segno << 4; memcpy(&rseg_cmd[10], uid, 4); - + if (topaz_send_cmd(rseg_cmd, sizeof(rseg_cmd), rseg_response, &resp_len) == PM3_ETIMEOUT) { topaz_switch_off_field(); return PM3_ESOFT; // RSEG failed @@ -420,7 +420,7 @@ static int CmdHFTopazReader(const char *Cmd) { (rid_response[0] & 0xF0) == 0x10 ? "" : "not ", (rid_response[0] & 0xF0) == 0x10 ? "" : "not ", (rid_response[0] & 0x0F) == 0x01 ? "static" : "dynamic"); - + PrintAndLogEx(NORMAL, "HR1 : %02x", rid_response[1]); status = topaz_rall(uid_echo, rall_response); @@ -475,7 +475,7 @@ static int CmdHFTopazReader(const char *Cmd) { sprintf(&line[3 * j], "%02x ", topaz_tag.data_blocks[0x0e][j]); } PrintAndLogEx(NORMAL, "-------+--------+-------------------------+------------"); - PrintAndLogEx(NORMAL, " 0x%02x | 0x%02x | %s| %-3s", 0x0e, 0x0e * 8, line, "n/a"); + PrintAndLogEx(NORMAL, " 0x%02x | 0x%02x | %s| %-3s", 0x0e, 0x0e * 8, line, "n/a"); PrintAndLogEx(NORMAL, ""); status = topaz_print_CC(&topaz_tag.data_blocks[1][0]); diff --git a/fpga/lo_adc.v b/fpga/lo_adc.v index f9b1470fc..f97090628 100644 --- a/fpga/lo_adc.v +++ b/fpga/lo_adc.v @@ -32,9 +32,9 @@ reg [7:0] pck_divider; reg clk_state; // Antenna logic, depending on "lf_field" (in arm defined as FPGA_LF_READER_FIELD) -wire tag_modulation; +wire tag_modulation; assign tag_modulation = ssp_dout & !lf_field; -wire reader_modulation; +wire reader_modulation; assign reader_modulation = !ssp_dout & lf_field & clk_state; assign pwr_oe1 = 1'b0; // not used in LF mode assign pwr_oe2 = 1'b0; //tag_modulation; From 10c949a47ee5f47c23ce7d325e14be94e3c742eb Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 1 Aug 2019 11:33:00 -0400 Subject: [PATCH 0208/1854] chg: 'hf thinfilm info' - versbose mode and sanity checks --- client/cmdhf.c | 2 +- client/cmdhfthinfilm.c | 30 +++++++++++++++++------------- client/cmdhfthinfilm.h | 2 +- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/client/cmdhf.c b/client/cmdhf.c index 2465641db..a766388c9 100644 --- a/client/cmdhf.c +++ b/client/cmdhf.c @@ -54,7 +54,7 @@ int CmdHFSearch(const char *Cmd) { PrintAndLogEx(INFO, "Checking for known tags...\n"); - if (infoThinFilm() == PM3_SUCCESS) { + if (infoThinFilm(false) == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Thinfilm tag") " found\n"); return 1; } diff --git a/client/cmdhfthinfilm.c b/client/cmdhfthinfilm.c index 0b2642b1b..18a0804ef 100644 --- a/client/cmdhfthinfilm.c +++ b/client/cmdhfthinfilm.c @@ -25,20 +25,19 @@ static int usage_thinfilm_info(void) { // Printing function based upon the code in libnfc // ref // https://github.com/nfc-tools/libnfc/blob/master/utils/nfc-barcode.c -static int print_barcode(uint8_t *barcode, const size_t barcode_len) { +static int print_barcode(uint8_t *barcode, const size_t barcode_len, bool verbose) { PrintAndLogEx(SUCCESS, " Manufacturer : "_YELLOW_("%s") "[0x%02X]", (barcode[0] == 0xB7) ? "Thinfilm" : "unknown", barcode[0]); - PrintAndLogEx(SUCCESS, " Data format : "_YELLOW_("%02X"), barcode[1]); - uint8_t b1, b2; - compute_crc(CRC_14443_A, barcode, barcode_len - 2, &b1, &b2); - bool isok = (barcode[barcode_len - 1] == b1 && barcode[barcode_len - 2] == b2); - - PrintAndLogEx(SUCCESS, " checksum : "_YELLOW_("%02X %02X")"- %s", b2, b1, (isok) ? _GREEN_("OK") : _RED_("fail")); - PrintAndLogEx(SUCCESS, " Raw data : "_YELLOW_("%s"), - sprint_hex(barcode, barcode_len) - ); + if (verbose) { + uint8_t b1, b2; + compute_crc(CRC_14443_A, barcode, barcode_len - 2, &b1, &b2); + bool isok = (barcode[barcode_len - 1] == b1 && barcode[barcode_len - 2] == b2); + PrintAndLogEx(SUCCESS, " Data format : "_YELLOW_("%02X"), barcode[1]); + PrintAndLogEx(SUCCESS, " checksum : "_YELLOW_("%02X %02X")"- %s", b2, b1, (isok) ? _GREEN_("OK") : _RED_("fail")); + PrintAndLogEx(SUCCESS, " Raw data : "_YELLOW_("%s"), sprint_hex(barcode, barcode_len)); + } char s[45]; memset(s, 0x00, sizeof(s)); @@ -104,10 +103,10 @@ static int CmdHfThinFilmInfo(const char *Cmd) { return PM3_EINVARG; } - return infoThinFilm(); + return infoThinFilm(true); } -int infoThinFilm(void) { +int infoThinFilm(bool verbose) { clearCommandBuffer(); SendCommandNG(CMD_THINFILM_READ, NULL, 0); @@ -119,7 +118,12 @@ int infoThinFilm(void) { } if (resp.status == PM3_SUCCESS) { - print_barcode(resp.data.asBytes, resp.length); + if (resp.length == 16 || resp.length == 32) { + print_barcode(resp.data.asBytes, resp.length, verbose); + } else { + PrintAndLogEx(WARNING, "Response is wrong length. (%d)", resp.length); + return PM3_ESOFT; + } } return resp.status; diff --git a/client/cmdhfthinfilm.h b/client/cmdhfthinfilm.h index f67084cbd..defe674aa 100644 --- a/client/cmdhfthinfilm.h +++ b/client/cmdhfthinfilm.h @@ -21,7 +21,7 @@ #include "util.h" #include "cmdhf.h" // list cmd -int infoThinFilm(void); +int infoThinFilm(bool verbose); int CmdHFThinfilm(const char *Cmd); From 85c0f3e9e3fdf0eee362066d998805b30601f391 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 1 Aug 2019 17:49:35 +0200 Subject: [PATCH 0209/1854] thinfilm partial info when verbose --- armsrc/thinfilm.c | 4 ++-- client/cmdhfthinfilm.c | 22 ++++++++++++++++------ 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/armsrc/thinfilm.c b/armsrc/thinfilm.c index 1d43ed10a..e730842ad 100644 --- a/armsrc/thinfilm.c +++ b/armsrc/thinfilm.c @@ -14,11 +14,11 @@ * ref * https://www.thinfilmnfc.com/wp-content/uploads/2017/09/Thinfilm-Kovio-NFC-Barcode-Protocol-Tag-Functional-Specification-v3.4-2017-05-26.pdf * https://developer.android.com/reference/android/nfc/tech/NfcBarcode - * + * */ void ReadThinFilm(void) { - + clear_trace(); set_tracing(true); diff --git a/client/cmdhfthinfilm.c b/client/cmdhfthinfilm.c index 18a0804ef..8235756a4 100644 --- a/client/cmdhfthinfilm.c +++ b/client/cmdhfthinfilm.c @@ -30,13 +30,19 @@ static int print_barcode(uint8_t *barcode, const size_t barcode_len, bool verbos PrintAndLogEx(SUCCESS, " Manufacturer : "_YELLOW_("%s") "[0x%02X]", (barcode[0] == 0xB7) ? "Thinfilm" : "unknown", barcode[0]); if (verbose) { - uint8_t b1, b2; - compute_crc(CRC_14443_A, barcode, barcode_len - 2, &b1, &b2); - bool isok = (barcode[barcode_len - 1] == b1 && barcode[barcode_len - 2] == b2); - PrintAndLogEx(SUCCESS, " Data format : "_YELLOW_("%02X"), barcode[1]); - PrintAndLogEx(SUCCESS, " checksum : "_YELLOW_("%02X %02X")"- %s", b2, b1, (isok) ? _GREEN_("OK") : _RED_("fail")); + if (barcode_len > 2) { + uint8_t b1, b2; + compute_crc(CRC_14443_A, barcode, barcode_len - 2, &b1, &b2); + bool isok = (barcode[barcode_len - 1] == b1 && barcode[barcode_len - 2] == b2); + + PrintAndLogEx(SUCCESS, " checksum : "_YELLOW_("%02X %02X")"- %s", b2, b1, (isok) ? _GREEN_("OK") : _RED_("fail")); + } else { + PrintAndLogEx(SUCCESS, " checksum : "_YELLOW_("too few data for checksum")"- " _RED_("fail")); + } PrintAndLogEx(SUCCESS, " Raw data : "_YELLOW_("%s"), sprint_hex(barcode, barcode_len)); + if (barcode_len < 4) // too few to go to next decoding stages + return PM3_ESOFT; } char s[45]; @@ -59,6 +65,10 @@ static int print_barcode(uint8_t *barcode, const size_t barcode_len, bool verbos snprintf(s, sizeof(s), "https://"); break; case 5: + if (barcode_len < 16) { + PrintAndLogEx(WARNING, "EPC: (partial data) %s", sprint_hex(barcode + 2, barcode_len - 2)); + return PM3_ESOFT; + } PrintAndLogEx(SUCCESS, "EPC: %s", sprint_hex(barcode + 2, 12)); return PM3_SUCCESS; default: @@ -118,7 +128,7 @@ int infoThinFilm(bool verbose) { } if (resp.status == PM3_SUCCESS) { - if (resp.length == 16 || resp.length == 32) { + if (resp.length == 16 || resp.length == 32 || verbose) { print_barcode(resp.data.asBytes, resp.length, verbose); } else { PrintAndLogEx(WARNING, "Response is wrong length. (%d)", resp.length); From 7bdcf3cff538907344c29b013cf8e36be410ed4a Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 1 Aug 2019 18:03:41 +0200 Subject: [PATCH 0210/1854] thinfilm, show raw data if unknown encoding --- client/cmdhfthinfilm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/cmdhfthinfilm.c b/client/cmdhfthinfilm.c index 8235756a4..bf2260902 100644 --- a/client/cmdhfthinfilm.c +++ b/client/cmdhfthinfilm.c @@ -73,7 +73,8 @@ static int print_barcode(uint8_t *barcode, const size_t barcode_len, bool verbos return PM3_SUCCESS; default: PrintAndLogEx(SUCCESS, "Data Format Field: unknown (%02X)", barcode[1]); - PrintAndLogEx(SUCCESS, "Data:" _YELLOW_("%s"), sprint_hex(barcode + 2, barcode_len - 2)); + if (!verbose) + PrintAndLogEx(SUCCESS, "Raw data with CRC: "_YELLOW_("%s"), sprint_hex(barcode, barcode_len)); return PM3_SUCCESS; } From 2a054438ab2db50f3b40c4be9a8134eed51911e5 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 1 Aug 2019 12:16:33 -0400 Subject: [PATCH 0211/1854] chg: 'hf thinfilm info' - fixed manufacture lookup --- client/cmdhf14a.c | 2 +- client/cmdhfthinfilm.c | 4 +++- client/cmdhfthinfilm.h | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index 0b3749590..d46e9ba07 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -73,7 +73,7 @@ static const manufactureName manufactureMapping[] = { { 0x34, "Mikron JSC Russia" }, { 0x35, "Fraunhofer Institute for Photonic Microsystems Germany" }, { 0x36, "IDS Microchip AG Switzerland" }, - { 0x37, "Kovio USA" }, + { 0x37, "Thinfilm - Kovio USA" }, { 0x38, "HMT Microelectronic Ltd Switzerland" }, { 0x39, "Silicon Craft Technology Thailand" }, { 0x3A, "Advanced Film Device Inc. Japan" }, diff --git a/client/cmdhfthinfilm.c b/client/cmdhfthinfilm.c index bf2260902..9bd8eb3bb 100644 --- a/client/cmdhfthinfilm.c +++ b/client/cmdhfthinfilm.c @@ -27,7 +27,9 @@ static int usage_thinfilm_info(void) { // https://github.com/nfc-tools/libnfc/blob/master/utils/nfc-barcode.c static int print_barcode(uint8_t *barcode, const size_t barcode_len, bool verbose) { - PrintAndLogEx(SUCCESS, " Manufacturer : "_YELLOW_("%s") "[0x%02X]", (barcode[0] == 0xB7) ? "Thinfilm" : "unknown", barcode[0]); + // remove start bit + uint8_t mb = barcode[0] & ~0x80; + PrintAndLogEx(SUCCESS, " Manufacturer : "_YELLOW_("%s") "[0x%02X]", getTagInfo(mb), mb); if (verbose) { PrintAndLogEx(SUCCESS, " Data format : "_YELLOW_("%02X"), barcode[1]); diff --git a/client/cmdhfthinfilm.h b/client/cmdhfthinfilm.h index defe674aa..ed2b0dd89 100644 --- a/client/cmdhfthinfilm.h +++ b/client/cmdhfthinfilm.h @@ -20,6 +20,7 @@ #include "cmdparser.h" #include "util.h" #include "cmdhf.h" // list cmd +#include "cmdhf14a.h" // manufacture int infoThinFilm(bool verbose); From 5a2d0c4cc16be47cf88fd3702fc0ea167008ee02 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 1 Aug 2019 12:22:51 -0400 Subject: [PATCH 0212/1854] chg: 'hf thinfilm info' - print text --- client/cmdhfthinfilm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/cmdhfthinfilm.c b/client/cmdhfthinfilm.c index 9bd8eb3bb..bd4634476 100644 --- a/client/cmdhfthinfilm.c +++ b/client/cmdhfthinfilm.c @@ -52,7 +52,7 @@ static int print_barcode(uint8_t *barcode, const size_t barcode_len, bool verbos switch (barcode[1]) { case 0: - printf("Data Format Field: Reserved for allocation by tag manufacturer\n"); + PrintAndLogEx(SUCCESS, " Data format : Reserved for allocation by tag manufacturer"); return PM3_SUCCESS; case 1: snprintf(s, sizeof(s), "http://www."); @@ -74,7 +74,7 @@ static int print_barcode(uint8_t *barcode, const size_t barcode_len, bool verbos PrintAndLogEx(SUCCESS, "EPC: %s", sprint_hex(barcode + 2, 12)); return PM3_SUCCESS; default: - PrintAndLogEx(SUCCESS, "Data Format Field: unknown (%02X)", barcode[1]); + PrintAndLogEx(SUCCESS, " Data format : RFU Reserved for future use (%02X)", barcode[1]); if (!verbose) PrintAndLogEx(SUCCESS, "Raw data with CRC: "_YELLOW_("%s"), sprint_hex(barcode, barcode_len)); return PM3_SUCCESS; From 63a7f8a4c4748bb9acbd0aca32befd4b8f17bcfd Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 1 Aug 2019 12:36:50 -0400 Subject: [PATCH 0213/1854] fix: 'hf topaz reader' - not crashing when trying to read a thinfilm --- client/cmdhftopaz.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/client/cmdhftopaz.c b/client/cmdhftopaz.c index 3aebcd673..b50369a7d 100644 --- a/client/cmdhftopaz.c +++ b/client/cmdhftopaz.c @@ -49,12 +49,17 @@ static int topaz_send_cmd_raw(uint8_t *cmd, uint8_t len, uint8_t *response, uint return PM3_ETIMEOUT; } - *response_len = resp.oldarg[0]; - PrintAndLogEx(INFO, "%s", sprint_hex(resp.data.asBytes, resp.oldarg[0])); - if (resp.oldarg[0] > 0) { - memcpy(response, resp.data.asBytes, resp.oldarg[0]); - } + if (resp.oldarg[0] == *response_len) { + *response_len = resp.oldarg[0]; + PrintAndLogEx(INFO, "%s", sprint_hex(resp.data.asBytes, *response_len)); + if (*response_len > 0) { + memcpy(response, resp.data.asBytes, *response_len); + } + } else { + PrintAndLogEx(WARNING, "Wrong response length (%d != %d)", *response_len, resp.oldarg[0]); + return PM3_ESOFT; + } return PM3_SUCCESS; } @@ -73,21 +78,25 @@ static int topaz_send_cmd(uint8_t *cmd, uint8_t len, uint8_t *response, uint16_t // select a topaz tag. Send WUPA and RID. -static int topaz_select(uint8_t *atqa, uint8_t *rid_response) { +static int topaz_select(uint8_t *atqa, uint8_t atqa_len, uint8_t *rid_response, uint8_t rid_len) { // ToDo: implement anticollision - uint16_t resp_len = 0; + uint16_t resp_len; uint8_t wupa_cmd[] = {TOPAZ_WUPA}; uint8_t rid_cmd[] = {TOPAZ_RID, 0, 0, 0, 0, 0, 0, 0, 0}; topaz_switch_on_field(); - if (topaz_send_cmd(wupa_cmd, sizeof(wupa_cmd), atqa, &resp_len) == PM3_ETIMEOUT) { + resp_len = atqa_len; + int status = topaz_send_cmd(wupa_cmd, sizeof(wupa_cmd), atqa, &resp_len); + if (status == PM3_ETIMEOUT || status == PM3_ESOFT) { topaz_switch_off_field(); return PM3_ESOFT; // WUPA failed } - if (topaz_send_cmd(rid_cmd, sizeof(rid_cmd), rid_response, &resp_len) == PM3_ETIMEOUT) { + resp_len = rid_len; + status = topaz_send_cmd(rid_cmd, sizeof(rid_cmd), rid_response, &resp_len); + if (status == PM3_ETIMEOUT || status == PM3_ESOFT) { topaz_switch_off_field(); return PM3_EWRONGANSVER; // RID failed } @@ -391,7 +400,7 @@ static int CmdHFTopazReader(const char *Cmd) { char ctmp = tolower(param_getchar(Cmd, 0)); if (ctmp == 's') verbose = false; - status = topaz_select(atqa, rid_response); + status = topaz_select(atqa, sizeof(atqa), rid_response, sizeof(rid_response)); if (status == PM3_ESOFT) { if (verbose) PrintAndLogEx(ERR, "Error: couldn't receive ATQA"); From 87b4eda2f282f4a9a26358ff31b4498e6b1caf78 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 1 Aug 2019 12:38:03 -0400 Subject: [PATCH 0214/1854] textual --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a6edb72ca..37a61dab5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Fix 'hf topaz reader' - don't crash when trying to read a Thinfilm tag (@iceman1001) - Add 'hf thinfilm info' - read / decode Kovio Thinfilm NFC barcode tags (@iceman1001) - Add FPGA LF adc path (@anon) - Add ECC support / check for NID_secp128r1 (@pwpiwi) From 3bc5f7688d35eb08ef95628076da4fb1dcedd5b3 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 1 Aug 2019 20:06:07 +0200 Subject: [PATCH 0215/1854] thinfilm trace --- client/cmdtrace.c | 48 +++++++++++++++++++++++++++++++--------------- common/protocols.h | 1 + 2 files changed, 34 insertions(+), 15 deletions(-) diff --git a/client/cmdtrace.c b/client/cmdtrace.c index 3a2ea9aef..93342bdae 100644 --- a/client/cmdtrace.c +++ b/client/cmdtrace.c @@ -24,18 +24,19 @@ static int usage_trace_list() { PrintAndLogEx(NORMAL, " syntax to use: `text2pcap -t \"%%S.\" -l 264 -n `"); PrintAndLogEx(NORMAL, " <0|1> - use data from Tracebuffer, if not set, try reading data from tag."); PrintAndLogEx(NORMAL, "Supported values:"); - PrintAndLogEx(NORMAL, " raw - just show raw data without annotations"); - PrintAndLogEx(NORMAL, " 14a - interpret data as iso14443a communications"); - PrintAndLogEx(NORMAL, " mf - interpret data as iso14443a communications and decrypt crypto1 stream"); - PrintAndLogEx(NORMAL, " 14b - interpret data as iso14443b communications"); - PrintAndLogEx(NORMAL, " 15 - interpret data as iso15693 communications"); - PrintAndLogEx(NORMAL, " des - interpret data as DESFire communications"); - PrintAndLogEx(NORMAL, " iclass - interpret data as iclass communications"); - PrintAndLogEx(NORMAL, " topaz - interpret data as topaz communications"); - PrintAndLogEx(NORMAL, " 7816 - interpret data as iso7816-4 communications"); - PrintAndLogEx(NORMAL, " legic - interpret data as LEGIC communications"); - PrintAndLogEx(NORMAL, " felica - interpret data as ISO18092 / FeliCa communications"); - PrintAndLogEx(NORMAL, " hitag - interpret data as Hitag2 / HitagS communications"); + PrintAndLogEx(NORMAL, " raw - just show raw data without annotations"); + PrintAndLogEx(NORMAL, " 14a - interpret data as iso14443a communications"); + PrintAndLogEx(NORMAL, " thinfilm - interpret data as Thinfilm communications"); + PrintAndLogEx(NORMAL, " topaz - interpret data as Topaz communications"); + PrintAndLogEx(NORMAL, " mf - interpret data as iso14443a communications and decrypt crypto1 stream"); + PrintAndLogEx(NORMAL, " des - interpret data as DESFire communications"); + PrintAndLogEx(NORMAL, " 14b - interpret data as iso14443b communications"); + PrintAndLogEx(NORMAL, " 7816 - interpret data as iso7816-4 communications"); + PrintAndLogEx(NORMAL, " 15 - interpret data as iso15693 communications"); + PrintAndLogEx(NORMAL, " iclass - interpret data as iclass communications"); + PrintAndLogEx(NORMAL, " legic - interpret data as LEGIC communications"); + PrintAndLogEx(NORMAL, " felica - interpret data as ISO18092 / FeliCa communications"); + PrintAndLogEx(NORMAL, " hitag - interpret data as Hitag2 / HitagS communications"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " trace list 14a f"); @@ -254,6 +255,15 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr case MFDES: crcStatus = iso14443A_CRC_check(isResponse, frame, data_len); break; + case THINFILM: + frame[data_len-1] ^= frame[data_len-2]; + frame[data_len-2] ^= frame[data_len-1]; + frame[data_len-1] ^= frame[data_len-2]; + crcStatus = iso14443A_CRC_check(true, frame, data_len); + frame[data_len-1] ^= frame[data_len-2]; + frame[data_len-2] ^= frame[data_len-1]; + frame[data_len-1] ^= frame[data_len-2]; + break; case ISO_15693: crcStatus = iso15693_CRC_check(frame, data_len); break; @@ -277,6 +287,7 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr && protocol != ISO_14443B && protocol != ISO_7816_4 && protocol != PROTO_HITAG + && protocol != THINFILM && (isResponse || protocol == ISO_14443A) && (oddparity8(frame[j]) != ((parityBits >> (7 - (j & 0x0007))) & 0x01))) { @@ -727,7 +738,7 @@ int CmdTraceList(const char *Cmd) { str_lower(type); // validate type of output - if (strcmp(type, "iclass") == 0) protocol = ICLASS; + if (strcmp(type, "iclass") == 0) protocol = ICLASS; else if (strcmp(type, "14a") == 0) protocol = ISO_14443A; else if (strcmp(type, "14b") == 0) protocol = ISO_14443B; else if (strcmp(type, "topaz") == 0) protocol = TOPAZ; @@ -738,6 +749,7 @@ int CmdTraceList(const char *Cmd) { else if (strcmp(type, "felica") == 0) protocol = FELICA; else if (strcmp(type, "mf") == 0) protocol = PROTO_MIFARE; else if (strcmp(type, "hitag") == 0) protocol = PROTO_HITAG; + else if (strcmp(type, "thinfilm") == 0) protocol = THINFILM; else if (strcmp(type, "raw") == 0) protocol = -1; //No crc, no annotations else errors = true; @@ -791,17 +803,23 @@ int CmdTraceList(const char *Cmd) { } } else { PrintAndLogEx(NORMAL, "Start = Start of Start Bit, End = End of last modulation. Src = Source of Transfer"); - if (protocol == ISO_14443A || protocol == PROTO_MIFARE) - PrintAndLogEx(NORMAL, "iso14443a - All times are in carrier periods (1/13.56Mhz)"); + if (protocol == ISO_14443A || protocol == PROTO_MIFARE || protocol == MFDES || protocol == TOPAZ) + PrintAndLogEx(NORMAL, "ISO14443A - All times are in carrier periods (1/13.56Mhz)"); + if (protocol == THINFILM) + PrintAndLogEx(NORMAL, "Thinfilm - All times are in carrier periods (1/13.56Mhz)"); if (protocol == ICLASS) PrintAndLogEx(NORMAL, "iClass - Timings are not as accurate"); if (protocol == LEGIC) PrintAndLogEx(NORMAL, "LEGIC - Reader Mode: Timings are in ticks (1us == 1.5ticks)\n" " Tag Mode: Timings are in sub carrier periods (1/212 kHz == 4.7us)"); + if (protocol == ISO_14443B) + PrintAndLogEx(NORMAL, "ISO14443B"); // Timings ? if (protocol == ISO_15693) PrintAndLogEx(NORMAL, "ISO15693 - Timings are not as accurate"); if (protocol == ISO_7816_4) PrintAndLogEx(NORMAL, "ISO7816-4 / Smartcard - Timings N/A yet"); + if (protocol == FELICA) + PrintAndLogEx(NORMAL, "Felica"); // Timings ? if (protocol == PROTO_HITAG) PrintAndLogEx(NORMAL, "Hitag2 / HitagS - Timings in ETU (8us)"); diff --git a/common/protocols.h b/common/protocols.h index cef339dc4..71a758fbe 100644 --- a/common/protocols.h +++ b/common/protocols.h @@ -279,6 +279,7 @@ ISO 7816-4 Basic interindustry commands. For command APDU's. #define FELICA 8 #define PROTO_MIFARE 9 #define PROTO_HITAG 10 +#define THINFILM 11 //-- Picopass fuses #define FUSE_FPERS 0x80 From 824e0ae3e43db8f1c8191c10bf7a2c1fde4676ef Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 1 Aug 2019 20:15:46 +0200 Subject: [PATCH 0216/1854] use thinfilm trace with hf thinfilm list --- client/cmdhfthinfilm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdhfthinfilm.c b/client/cmdhfthinfilm.c index bd4634476..3864d0562 100644 --- a/client/cmdhfthinfilm.c +++ b/client/cmdhfthinfilm.c @@ -149,7 +149,7 @@ static int CmdHfThinFilmSim(const char *Cmd) { static int CmdHfThinFilmList(const char *Cmd) { (void)Cmd; // Cmd is not used so far - CmdTraceList("14a"); + CmdTraceList("thinfilm"); return PM3_SUCCESS; } From 01d1db89705b4bd084fd3707f1d53296bd0e29cb Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 1 Aug 2019 20:20:34 +0200 Subject: [PATCH 0217/1854] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 37a61dab5..0d45d52c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Add 'hf thinfilm list' specific trace decoding (Thinfilm NFC barcode tags) (@doegox) - Fix 'hf topaz reader' - don't crash when trying to read a Thinfilm tag (@iceman1001) - Add 'hf thinfilm info' - read / decode Kovio Thinfilm NFC barcode tags (@iceman1001) - Add FPGA LF adc path (@anon) From 865a7c3ad4635889fe56d52b78f437c11b70fc92 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 2 Aug 2019 00:00:37 +0200 Subject: [PATCH 0218/1854] Add thinfilm simulation --- armsrc/appmain.c | 4 ++ armsrc/thinfilm.c | 114 +++++++++++++++++++++++++++++++++++++++++ armsrc/thinfilm.h | 1 + client/cmdhfthinfilm.c | 62 +++++++++++++++++++++- include/pm3_cmd.h | 1 + 5 files changed, 180 insertions(+), 2 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 4dcaac17a..b980a3456 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1283,6 +1283,10 @@ static void PacketReceived(PacketCommandNG *packet) { ReadThinFilm(); break; } + case CMD_SIMULATE_TAG_THINFILM: { + SimulateThinFilm(packet->data.asBytes, packet->length); + break; + } #endif #ifdef WITH_ICLASS diff --git a/armsrc/thinfilm.c b/armsrc/thinfilm.c index e730842ad..f8cf2b0da 100644 --- a/armsrc/thinfilm.c +++ b/armsrc/thinfilm.c @@ -36,3 +36,117 @@ void ReadThinFilm(void) { set_tracing(false); } +#define SEC_D 0xf0 +#define SEC_E 0x0f +#define SEC_F 0x00 +uint16_t FpgaSendQueueDelay; + +uint16_t ReadReaderField(void) { + uint16_t hf_av = AvgAdc(ADC_CHAN_HF); + if (((MAX_ADC_HF_VOLTAGE * hf_av) >> 10) > MAX_ADC_HF_VOLTAGE - 300) + hf_av = AvgAdc(ADC_CHAN_HF_RDV40); + return hf_av; +} + +static void CodeThinfilmAsTag(const uint8_t *cmd, uint16_t len) { + ToSendReset(); + for (uint16_t i = 0; i < len; i++) { + uint8_t b = cmd[i]; + for (uint8_t j = 0; j < 8; j++) { + ToSend[++ToSendMax] = b & 0x80 ? SEC_D : SEC_E; + b <<= 1; + } + } + ToSendMax++; +} + +int EmSendCmdThinfilmRaw(uint8_t *resp, uint16_t respLen) { + volatile uint8_t b; + uint16_t i = 0; + uint32_t ThisTransferTime; + // wait for the FPGA to signal fdt_indicator == 1 (the FPGA is ready to queue new data in its delay line) + for (uint8_t j = 0; j < 5; j++) { // allow timeout - better late than never + while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY)); + if (AT91C_BASE_SSC->SSC_RHR) break; + } + while ((ThisTransferTime = GetCountSspClk()) & 0x00000007); + + + // Clear TXRDY: + AT91C_BASE_SSC->SSC_THR = SEC_F; + + // send cycle + for (; i < respLen;) { + if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { + AT91C_BASE_SSC->SSC_THR = resp[i++]; + FpgaSendQueueDelay = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + } + + if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { + b = (uint16_t)(AT91C_BASE_SSC->SSC_RHR); + (void)b; + } + if (BUTTON_PRESS()) break; + } + + // Ensure that the FPGA Delay Queue is empty + uint8_t fpga_queued_bits = FpgaSendQueueDelay >> 3; + for (i = 0; i <= fpga_queued_bits / 8 + 1;) { + if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { + AT91C_BASE_SSC->SSC_THR = SEC_F; + FpgaSendQueueDelay = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + i++; + } + } + + return 0; +} + +void SimulateThinFilm(uint8_t *data, size_t len) { + Dbprintf("Simulate %i-bit Thinfilm tag", len * 8); + Dbhexdump(len, data, true); + int16_t status = PM3_SUCCESS; + CodeThinfilmAsTag(data, len); + + FpgaDownloadAndGo(FPGA_BITSTREAM_HF); + // Set up the synchronous serial port + FpgaSetupSsc(); + // connect Demodulated Signal to ADC: + SetAdcMuxFor(GPIO_MUXSEL_HIPKD); + + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_TAGSIM_MOD); + SpinDelay(100); + uint16_t hf_baseline = ReadReaderField(); + + // Start the timer + StartCountSspClk(); + + bool reader_detected = false; + LED_A_ON(); + for (;;) { + WDT_HIT(); + if (BUTTON_PRESS() || data_available()) { + status = PM3_EOPABORTED; + break; + } + uint16_t hf_av = ReadReaderField(); + if (hf_av < hf_baseline) + hf_baseline = hf_av; + if (hf_av > hf_baseline + 10) { + EmSendCmdThinfilmRaw(ToSend, ToSendMax); + if (!reader_detected) { + LED_B_ON(); + Dbprintf("Reader detected, start beaming data"); + reader_detected = true; + } + } else { + if (reader_detected) { + LED_B_OFF(); + Dbprintf("Reader gone, stop beaming data"); + reader_detected = false; + } + } + } + LED_A_OFF(); + reply_ng(CMD_SIMULATE_TAG_THINFILM, status, NULL, 0); +} diff --git a/armsrc/thinfilm.h b/armsrc/thinfilm.h index cfbfd03c1..a9024338b 100644 --- a/armsrc/thinfilm.h +++ b/armsrc/thinfilm.h @@ -22,6 +22,7 @@ extern "C" { #include "iso14443a.h" void ReadThinFilm(void); +void SimulateThinFilm(uint8_t *data, size_t len); #ifdef __cplusplus } diff --git a/client/cmdhfthinfilm.c b/client/cmdhfthinfilm.c index 3864d0562..38d7a4c85 100644 --- a/client/cmdhfthinfilm.c +++ b/client/cmdhfthinfilm.c @@ -21,6 +21,17 @@ static int usage_thinfilm_info(void) { return PM3_SUCCESS; } +static int usage_thinfilm_sim(void) { + PrintAndLogEx(NORMAL, "Usage: hf thinfilm sim [h] [d ]"); + PrintAndLogEx(NORMAL, "Options:"); + PrintAndLogEx(NORMAL, " h this help"); + PrintAndLogEx(NORMAL, " d bytes to send, in hex"); + PrintAndLogEx(NORMAL, " r raw, provided bytes should include CRC"); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Examples:"); + PrintAndLogEx(NORMAL, " hf thinfilm sim d B70470726f786d61726b2e636f6d"); + return PM3_SUCCESS; +} // Printing function based upon the code in libnfc // ref @@ -143,8 +154,55 @@ int infoThinFilm(bool verbose) { } static int CmdHfThinFilmSim(const char *Cmd) { - PrintAndLogEx(INFO, "To be implemented"); - return PM3_ENOTIMPL; + uint8_t cmdp = 0; + uint8_t data[512]; + int datalen = 0; + + bool addcrc = true; + bool errors = false; + + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { + case 'h': + return usage_thinfilm_sim(); + case 'd': + // Retrieve the data + param_gethex_ex(Cmd, cmdp + 1, data, &datalen); + datalen >>= 1; + cmdp += 2; + break; + case 'r': + addcrc = false; + cmdp++; + break; + default: + PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } + } + + //Validations + if (errors || cmdp == 0 || datalen == 0 || datalen > 512) return usage_thinfilm_sim(); + if (addcrc && datalen <= 510) { + uint8_t b1, b2; + compute_crc(CRC_14443_A, data, datalen, &b1, &b2); + data[datalen++] = b2; + data[datalen++] = b1; + } + + clearCommandBuffer(); + SendCommandNG(CMD_SIMULATE_TAG_THINFILM, (uint8_t *)&data, datalen); + PacketResponseNG resp; + PrintAndLogEx(SUCCESS, "press pm3-button to abort simulation"); + + while (!kbd_enter_pressed()) { + if (WaitForResponseTimeout(CMD_SIMULATE_TAG_THINFILM, &resp, 1500) == 0) continue; + if (resp.status != PM3_SUCCESS) break; + } + + PrintAndLogEx(INFO, "Done"); + return PM3_SUCCESS; } static int CmdHfThinFilmList(const char *Cmd) { diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index de4a622e4..33e291d8c 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -496,6 +496,7 @@ typedef struct { // For ThinFilm Kovio #define CMD_THINFILM_READ 0x0810 +#define CMD_SIMULATE_TAG_THINFILM 0x0811 #define CMD_UNKNOWN 0xFFFF From 0eae1e25637871b7163deaa256b65533fe554d25 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 2 Aug 2019 00:26:48 +0200 Subject: [PATCH 0219/1854] make style --- client/cmdtrace.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/client/cmdtrace.c b/client/cmdtrace.c index 93342bdae..7eaa9c207 100644 --- a/client/cmdtrace.c +++ b/client/cmdtrace.c @@ -256,13 +256,13 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr crcStatus = iso14443A_CRC_check(isResponse, frame, data_len); break; case THINFILM: - frame[data_len-1] ^= frame[data_len-2]; - frame[data_len-2] ^= frame[data_len-1]; - frame[data_len-1] ^= frame[data_len-2]; + frame[data_len - 1] ^= frame[data_len - 2]; + frame[data_len - 2] ^= frame[data_len - 1]; + frame[data_len - 1] ^= frame[data_len - 2]; crcStatus = iso14443A_CRC_check(true, frame, data_len); - frame[data_len-1] ^= frame[data_len-2]; - frame[data_len-2] ^= frame[data_len-1]; - frame[data_len-1] ^= frame[data_len-2]; + frame[data_len - 1] ^= frame[data_len - 2]; + frame[data_len - 2] ^= frame[data_len - 1]; + frame[data_len - 1] ^= frame[data_len - 2]; break; case ISO_15693: crcStatus = iso15693_CRC_check(frame, data_len); From e0dcacb1966fd79dfdfacdd4290b91adfc9e1ac3 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 2 Aug 2019 00:30:17 +0200 Subject: [PATCH 0220/1854] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0d45d52c5..8b4ba9cef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Add 'hf thinfilm sim' simulating Thinfilm NFC barcode tags (@doegox) - Add 'hf thinfilm list' specific trace decoding (Thinfilm NFC barcode tags) (@doegox) - Fix 'hf topaz reader' - don't crash when trying to read a Thinfilm tag (@iceman1001) - Add 'hf thinfilm info' - read / decode Kovio Thinfilm NFC barcode tags (@iceman1001) From ab74d2b7983eb2145e33d482c443e6e1b9d4c7a8 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 2 Aug 2019 08:06:30 +0200 Subject: [PATCH 0221/1854] Revert ARRAYLEN on whereami.c, bag of bones... --- client/whereami.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/whereami.c b/client/whereami.c index 33d261f4d..a18d2d2f7 100644 --- a/client/whereami.c +++ b/client/whereami.c @@ -69,11 +69,11 @@ static int WAI_PREFIX(getModulePath_)(HMODULE module, char *out, int capacity, i DWORD size; int length_, length__; - size = GetModuleFileNameW(module, buffer1, ARRAYLEN(buffer1)); + size = GetModuleFileNameW(module, buffer1, sizeof(buffer1) / sizeof(buffer1[0])); if (size == 0) break; - else if (size == (DWORD)(ARRAYLEN(buffer1))) { + else if (size == (DWORD)(sizeof(buffer1) / sizeof(buffer1[0]))) { DWORD size_ = size; do { wchar_t *path_; @@ -521,7 +521,7 @@ int WAI_PREFIX(getExecutablePath)(char *out, int capacity, int *dirname_length) #endif size_t size = sizeof(buffer1); - if (sysctl(mib, (u_int)(ARRAYLEN(mib)), path, &size, NULL, 0) != 0) + if (sysctl(mib, (u_int)(sizeof(mib) / sizeof(mib[0])), path, &size, NULL, 0) != 0) break; resolved = realpath(path, buffer2); From 0747cf9ec07f12b48259269edcef036a4efa1642 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 2 Aug 2019 09:48:42 -0400 Subject: [PATCH 0222/1854] add more keys (@anon) --- CHANGELOG.md | 1 + client/default_keys.dic | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b4ba9cef..986105bff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Add some more default keys (@anon) - Add 'hf thinfilm sim' simulating Thinfilm NFC barcode tags (@doegox) - Add 'hf thinfilm list' specific trace decoding (Thinfilm NFC barcode tags) (@doegox) - Fix 'hf topaz reader' - don't crash when trying to read a Thinfilm tag (@iceman1001) diff --git a/client/default_keys.dic b/client/default_keys.dic index df9df6fbd..54c355de4 100644 --- a/client/default_keys.dic +++ b/client/default_keys.dic @@ -113,8 +113,13 @@ a9b43414F585,--Tehran Railway # Data from: http://irq5.io/2013/04/13/decoding-bcard-conference-badges/ f4a9ef2afc6d,--BCARD KeyB # +# Data from: ... +89eac97f8c2a // S0 B +43c7600dee6b // S4 A +0120bf672a64 // S6 A +fb0b20df1f34 // S6 B # -a9f953def0a3,-- +a9f953def0a3, # # Here be BIP keys... 3A42F33AF429, From 52065adcfae8d1d6ce00a9c804be569433a09d67 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 2 Aug 2019 11:37:35 -0400 Subject: [PATCH 0223/1854] chg: 'hf topaz reader' - more verbose --- client/cmdhftopaz.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/client/cmdhftopaz.c b/client/cmdhftopaz.c index b50369a7d..3c1cf8672 100644 --- a/client/cmdhftopaz.c +++ b/client/cmdhftopaz.c @@ -39,13 +39,13 @@ static void topaz_switch_off_field(void) { } // send a raw topaz command, returns the length of the response (0 in case of error) -static int topaz_send_cmd_raw(uint8_t *cmd, uint8_t len, uint8_t *response, uint16_t *response_len) { +static int topaz_send_cmd_raw(uint8_t *cmd, uint8_t len, uint8_t *response, uint16_t *response_len, bool verbose) { SendCommandOLD(CMD_READER_ISO_14443a, ISO14A_RAW | ISO14A_NO_DISCONNECT | ISO14A_TOPAZMODE | ISO14A_NO_RATS, len, 0, cmd, len); PacketResponseNG resp; if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { - PrintAndLogEx(WARNING, "timeout while waiting for reply."); + if (verbose) PrintAndLogEx(WARNING, "timeout while waiting for reply."); return PM3_ETIMEOUT; } @@ -57,7 +57,7 @@ static int topaz_send_cmd_raw(uint8_t *cmd, uint8_t len, uint8_t *response, uint memcpy(response, resp.data.asBytes, *response_len); } } else { - PrintAndLogEx(WARNING, "Wrong response length (%d != %d)", *response_len, resp.oldarg[0]); + if (verbose) PrintAndLogEx(WARNING, "Wrong response length (%d != %d)", *response_len, resp.oldarg[0]); return PM3_ESOFT; } return PM3_SUCCESS; @@ -65,7 +65,7 @@ static int topaz_send_cmd_raw(uint8_t *cmd, uint8_t len, uint8_t *response, uint // calculate CRC bytes and send topaz command, returns the length of the response (0 in case of error) -static int topaz_send_cmd(uint8_t *cmd, uint8_t len, uint8_t *response, uint16_t *response_len) { +static int topaz_send_cmd(uint8_t *cmd, uint8_t len, uint8_t *response, uint16_t *response_len, bool verbose) { if (len > 1) { uint8_t b1, b2; compute_crc(CRC_14443_B, cmd, len - 2, &b1, &b2); @@ -73,12 +73,12 @@ static int topaz_send_cmd(uint8_t *cmd, uint8_t len, uint8_t *response, uint16_t cmd[len - 1] = b2; } - return topaz_send_cmd_raw(cmd, len, response, response_len); + return topaz_send_cmd_raw(cmd, len, response, response_len, verbose); } // select a topaz tag. Send WUPA and RID. -static int topaz_select(uint8_t *atqa, uint8_t atqa_len, uint8_t *rid_response, uint8_t rid_len) { +static int topaz_select(uint8_t *atqa, uint8_t atqa_len, uint8_t *rid_response, uint8_t rid_len, bool verbose) { // ToDo: implement anticollision uint16_t resp_len; @@ -88,14 +88,14 @@ static int topaz_select(uint8_t *atqa, uint8_t atqa_len, uint8_t *rid_response, topaz_switch_on_field(); resp_len = atqa_len; - int status = topaz_send_cmd(wupa_cmd, sizeof(wupa_cmd), atqa, &resp_len); + int status = topaz_send_cmd(wupa_cmd, sizeof(wupa_cmd), atqa, &resp_len, verbose); if (status == PM3_ETIMEOUT || status == PM3_ESOFT) { topaz_switch_off_field(); return PM3_ESOFT; // WUPA failed } resp_len = rid_len; - status = topaz_send_cmd(rid_cmd, sizeof(rid_cmd), rid_response, &resp_len); + status = topaz_send_cmd(rid_cmd, sizeof(rid_cmd), rid_response, &resp_len, verbose); if (status == PM3_ETIMEOUT || status == PM3_ESOFT) { topaz_switch_off_field(); return PM3_EWRONGANSVER; // RID failed @@ -111,7 +111,7 @@ static int topaz_rall(uint8_t *uid, uint8_t *response) { uint8_t rall_cmd[] = {TOPAZ_RALL, 0, 0, 0, 0, 0, 0, 0, 0}; memcpy(&rall_cmd[3], uid, 4); - if (topaz_send_cmd(rall_cmd, sizeof(rall_cmd), response, &resp_len) == PM3_ETIMEOUT) { + if (topaz_send_cmd(rall_cmd, sizeof(rall_cmd), response, &resp_len, true) == PM3_ETIMEOUT) { topaz_switch_off_field(); return PM3_ESOFT; // RALL failed } @@ -129,7 +129,7 @@ static int topaz_read_block(uint8_t *uid, uint8_t blockno, uint8_t *block_data) read8_cmd[1] = blockno; memcpy(&read8_cmd[10], uid, 4); - if (topaz_send_cmd(read8_cmd, sizeof(read8_cmd), read8_response, &resp_len) == PM3_ETIMEOUT) { + if (topaz_send_cmd(read8_cmd, sizeof(read8_cmd), read8_response, &resp_len, true) == PM3_ETIMEOUT) { topaz_switch_off_field(); return PM3_ESOFT; // READ8 failed } @@ -146,7 +146,7 @@ static int topaz_read_segment(uint8_t *uid, uint8_t segno, uint8_t *segment_data rseg_cmd[1] = segno << 4; memcpy(&rseg_cmd[10], uid, 4); - if (topaz_send_cmd(rseg_cmd, sizeof(rseg_cmd), rseg_response, &resp_len) == PM3_ETIMEOUT) { + if (topaz_send_cmd(rseg_cmd, sizeof(rseg_cmd), rseg_response, &resp_len, true) == PM3_ETIMEOUT) { topaz_switch_off_field(); return PM3_ESOFT; // RSEG failed } @@ -400,26 +400,27 @@ static int CmdHFTopazReader(const char *Cmd) { char ctmp = tolower(param_getchar(Cmd, 0)); if (ctmp == 's') verbose = false; - status = topaz_select(atqa, sizeof(atqa), rid_response, sizeof(rid_response)); + status = topaz_select(atqa, sizeof(atqa), rid_response, sizeof(rid_response), verbose); if (status == PM3_ESOFT) { if (verbose) PrintAndLogEx(ERR, "Error: couldn't receive ATQA"); return PM3_ESOFT; } - PrintAndLogEx(NORMAL, "ATQA : %02x %02x", atqa[1], atqa[0]); if (atqa[1] != 0x0c && atqa[0] != 0x00) { - PrintAndLogEx(ERR, "Tag doesn't support the Topaz protocol."); + if (verbose) PrintAndLogEx(ERR, "Tag doesn't support the Topaz protocol."); topaz_switch_off_field(); return PM3_ESOFT; } if (status == PM3_EWRONGANSVER) { - PrintAndLogEx(ERR, "Error: tag didn't answer to RID"); + if (verbose) PrintAndLogEx(ERR, "Error: tag didn't answer to RID"); topaz_switch_off_field(); return PM3_ESOFT; } + PrintAndLogEx(NORMAL, "ATQA : %02x %02x", atqa[1], atqa[0]); + topaz_tag.HR01[0] = rid_response[0]; topaz_tag.HR01[1] = rid_response[1]; From 96ed9076050d9af2edb087aeab3136e72b0875f9 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 2 Aug 2019 20:48:38 +0200 Subject: [PATCH 0224/1854] Fix momentarily flash read/write of dicts --- CHANGELOG.md | 1 + armsrc/appmain.c | 51 ++++++++++------------------------------------- armsrc/flashmem.c | 3 +++ 3 files changed, 15 insertions(+), 40 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 986105bff..f7aad9983 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Fix momentarily flash read/write of dicts (@doegox/@cjbrigato) - Add some more default keys (@anon) - Add 'hf thinfilm sim' simulating Thinfilm NFC barcode tags (@doegox) - Add 'hf thinfilm list' specific trace decoding (Thinfilm NFC barcode tags) (@doegox) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index b980a3456..f08229783 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1740,58 +1740,29 @@ static void PacketReceived(PacketCommandNG *packet) { uint16_t len = packet->oldarg[1]; uint8_t *data = packet->data.asBytes; - uint32_t tmp = startidx + len; - if (!FlashInit()) { break; } - Flash_CheckBusy(BUSY_TIMEOUT); - Flash_WriteEnable(); - if (startidx == DEFAULT_T55XX_KEYS_OFFSET) { + Flash_CheckBusy(BUSY_TIMEOUT); + Flash_WriteEnable(); Flash_Erase4k(3, 0xC); } else if (startidx == DEFAULT_MF_KEYS_OFFSET) { + Flash_CheckBusy(BUSY_TIMEOUT); + Flash_WriteEnable(); Flash_Erase4k(3, 0x9); + Flash_CheckBusy(BUSY_TIMEOUT); + Flash_WriteEnable(); Flash_Erase4k(3, 0xA); } else if (startidx == DEFAULT_ICLASS_KEYS_OFFSET) { + Flash_CheckBusy(BUSY_TIMEOUT); + Flash_WriteEnable(); Flash_Erase4k(3, 0xB); } - Flash_CheckBusy(BUSY_TIMEOUT); - Flash_WriteEnable(); - - // inside 256b page? - if ((tmp & 0xFF) != 0) { - - // is offset+len larger than a page - tmp = (startidx & 0xFF) + len; - if (tmp > 0xFF) { - - // data spread over two pages. - - // offset xxxx10, - uint8_t first_len = (~startidx & 0xFF) + 1; - - // first mem page - res = Flash_WriteDataCont(startidx, data, first_len); - - isok = (res == first_len) ? 1 : 0; - - // second mem page - res = Flash_WriteDataCont(startidx + first_len, data + first_len, len - first_len); - - isok &= (res == (len - first_len)) ? 1 : 0; - - } else { - res = Flash_WriteDataCont(startidx, data, len); - isok = (res == len) ? 1 : 0; - } - } else { - res = Flash_WriteDataCont(startidx, data, len); - isok = (res == len) ? 1 : 0; - } - FlashStop(); + res = Flash_Write(startidx, data, len); + isok = (res == len) ? 1 : 0; reply_old(CMD_ACK, isok, 0, 0, 0, 0); LED_B_OFF(); @@ -1831,7 +1802,7 @@ static void PacketReceived(PacketCommandNG *packet) { for (size_t i = 0; i < numofbytes; i += PM3_CMD_DATA_SIZE) { size_t len = MIN((numofbytes - i), PM3_CMD_DATA_SIZE); - + Flash_CheckBusy(BUSY_TIMEOUT); bool isok = Flash_ReadDataCont(startidx + i, mem, len); if (!isok) Dbprintf("reading flash memory failed :: | bytes between %d - %d", i, len); diff --git a/armsrc/flashmem.c b/armsrc/flashmem.c index 7bca9ddf9..81e5f767d 100644 --- a/armsrc/flashmem.c +++ b/armsrc/flashmem.c @@ -563,6 +563,7 @@ void Flashmem_print_info(void) { 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]); @@ -570,6 +571,7 @@ void Flashmem_print_info(void) { Dbprintf(" Mifare.................."_YELLOW_("%d")"keys", num); } + Flash_CheckBusy(BUSY_TIMEOUT); isok = Flash_ReadDataCont(DEFAULT_T55XX_KEYS_OFFSET, keysum, 2); if (isok == 2) { num = ((keysum[1] << 8) | keysum[0]); @@ -577,6 +579,7 @@ void Flashmem_print_info(void) { Dbprintf(" T55x7..................."_YELLOW_("%d")"keys", num); } + Flash_CheckBusy(BUSY_TIMEOUT); isok = Flash_ReadDataCont(DEFAULT_ICLASS_KEYS_OFFSET, keysum, 2); if (isok == 2) { num = ((keysum[1] << 8) | keysum[0]); From f3c48466abbcaa3a52ecde43422e381688bb3b88 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 3 Aug 2019 10:22:08 +0200 Subject: [PATCH 0225/1854] chg: 'lf t55xx deviceconfig' - outputs in matrix style instead --- armsrc/lfops.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 6ab87fec0..066363164 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -383,7 +383,7 @@ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint } else { // if field already on leave alone (affects timing otherwise) if (off) { - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_ADC_READER_FIELD); LED_D_ON(); off = false; } @@ -407,7 +407,7 @@ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint FpgaSendCommand(FPGA_CMD_SET_DIVISOR, sc->divisor); } - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_ADC_READER_FIELD); // now do the read DoAcquisition_config(false, 0); @@ -1515,7 +1515,7 @@ void CmdIOdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol) { */ void TurnReadLFOn(uint32_t delay) { - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_ADC_READER_FIELD); // measure antenna strength. //int adcval = ((MAX_ADC_LF_VOLTAGE * AvgAdc(ADC_CHAN_LF)) >> 10); @@ -2451,7 +2451,7 @@ void Cotag(uint32_t arg0) { # define OFF(x) { FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); WaitUS((x)); } #endif #ifndef ON -# define ON(x) { FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); WaitUS((x)); } +# define ON(x) { FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_ADC_READER_FIELD); WaitUS((x)); } #endif uint8_t rawsignal = arg0 & 0xF; From bf2dc0304b4b915fb66265e484c69d7d552ccc8d Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 3 Aug 2019 04:43:01 -0400 Subject: [PATCH 0226/1854] revert last --- armsrc/lfops.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 6ab87fec0..066363164 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -383,7 +383,7 @@ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint } else { // if field already on leave alone (affects timing otherwise) if (off) { - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_ADC_READER_FIELD); LED_D_ON(); off = false; } @@ -407,7 +407,7 @@ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint FpgaSendCommand(FPGA_CMD_SET_DIVISOR, sc->divisor); } - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_ADC_READER_FIELD); // now do the read DoAcquisition_config(false, 0); @@ -1515,7 +1515,7 @@ void CmdIOdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol) { */ void TurnReadLFOn(uint32_t delay) { - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_ADC_READER_FIELD); // measure antenna strength. //int adcval = ((MAX_ADC_LF_VOLTAGE * AvgAdc(ADC_CHAN_LF)) >> 10); @@ -2451,7 +2451,7 @@ void Cotag(uint32_t arg0) { # define OFF(x) { FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); WaitUS((x)); } #endif #ifndef ON -# define ON(x) { FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); WaitUS((x)); } +# define ON(x) { FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_ADC_READER_FIELD); WaitUS((x)); } #endif uint8_t rawsignal = arg0 & 0xF; From 5061869efdc0651a6090a114230478e8d65efb36 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 3 Aug 2019 10:57:59 +0200 Subject: [PATCH 0227/1854] help iceman reverting last --- armsrc/lfops.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 066363164..6ab87fec0 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -383,7 +383,7 @@ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint } else { // if field already on leave alone (affects timing otherwise) if (off) { - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_ADC_READER_FIELD); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); LED_D_ON(); off = false; } @@ -407,7 +407,7 @@ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint FpgaSendCommand(FPGA_CMD_SET_DIVISOR, sc->divisor); } - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_ADC_READER_FIELD); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); // now do the read DoAcquisition_config(false, 0); @@ -1515,7 +1515,7 @@ void CmdIOdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol) { */ void TurnReadLFOn(uint32_t delay) { - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_ADC_READER_FIELD); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); // measure antenna strength. //int adcval = ((MAX_ADC_LF_VOLTAGE * AvgAdc(ADC_CHAN_LF)) >> 10); @@ -2451,7 +2451,7 @@ void Cotag(uint32_t arg0) { # define OFF(x) { FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); WaitUS((x)); } #endif #ifndef ON -# define ON(x) { FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_ADC_READER_FIELD); WaitUS((x)); } +# define ON(x) { FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); WaitUS((x)); } #endif uint8_t rawsignal = arg0 & 0xF; From f643a7a5a44c6213d9ad2648f8bfebb8e01f5303 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 3 Aug 2019 15:26:46 +0200 Subject: [PATCH 0228/1854] chg: 'lf t55xx deviceconfig' - matrix styled output --- armsrc/lfops.c | 62 +++++++++++++++++++++++++++++++------------------- 1 file changed, 39 insertions(+), 23 deletions(-) diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 6ab87fec0..5436e4d81 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -14,6 +14,7 @@ #include "hitag2.h" #include "crc16.h" #include "string.h" +#include "printf.h" #include "lfdemod.h" #include "lfsampling.h" #include "protocols.h" @@ -154,60 +155,75 @@ t55xx_configurations_t T55xx_Timing = { #define T55XX_LONGLEADINGREFERENCE 4 // Value to tell Write Bit to send long reference void printT55xxConfig(void) { + +#define PRN_NA sprintf(s + strlen(s), _RED_(" N/A |")); + DbpString(_BLUE_("LF T55XX config")); + Dbprintf(" [a] [b] [c] [d] [e] [f] [g]"); + Dbprintf(" Mode | startgap | writegap | write 0 | write 1 | readgap | write_2 | write_3"); + Dbprintf("---------------------------+------------+------------+------------+------------+------------+------------+-------------"); + for (uint8_t i = 0; i < 4; i++) { + + char s[160]; + memset(s, 0, sizeof(s)); + switch (i) { case T55XX_DLMODE_FIXED : - Dbprintf(_YELLOW_("fixed bit length (default)")); + sprintf(s, _YELLOW_("fixed bit length (default) |")); break; case T55XX_DLMODE_LLR : - Dbprintf(_YELLOW_("long leading reference")); + sprintf(s, _YELLOW_(" long leading reference |")); break; case T55XX_DLMODE_LEADING_ZERO : - Dbprintf(_YELLOW_("leading zero")); + sprintf(s, _YELLOW_(" leading zero |")); break; case T55XX_DLMODE_1OF4 : - Dbprintf(_YELLOW_("1 of 4 coding reference")); + sprintf(s, _YELLOW_(" 1 of 4 coding reference |")); + break; + default: break; } + if (T55xx_Timing.m[i].start_gap != 0xFFFF) - Dbprintf(" [a] startgap............%d*8 (%d)", T55xx_Timing.m[i].start_gap / 8, T55xx_Timing.m[i].start_gap); + sprintf(s + strlen(s), "%3d (%4d) | ", T55xx_Timing.m[i].start_gap / 8, T55xx_Timing.m[i].start_gap); else - Dbprintf(" [a] startgap............" _RED_("unconfigured")); + PRN_NA; if (T55xx_Timing.m[i].write_gap != 0xFFFF) - Dbprintf(" [b] writegap............%d*8 (%d)", T55xx_Timing.m[i].write_gap / 8, T55xx_Timing.m[i].write_gap); + sprintf(s + strlen(s), "%3d (%4d) | ", T55xx_Timing.m[i].write_gap / 8, T55xx_Timing.m[i].write_gap); else - Dbprintf(" [b] writegap............" _RED_("unconfigured")); + PRN_NA; if (T55xx_Timing.m[i].write_0 != 0xFFFF) - Dbprintf(" [c] write_0.............%d*8 (%d)", T55xx_Timing.m[i].write_0 / 8, T55xx_Timing.m[i].write_0); + sprintf(s + strlen(s), "%3d (%4d) | ", T55xx_Timing.m[i].write_0 / 8, T55xx_Timing.m[i].write_0); else - Dbprintf(" [c] write_0............." _RED_("unconfigured")); + PRN_NA; if (T55xx_Timing.m[i].write_1 != 0xFFFF) - Dbprintf(" [d] write_1.............%d*8 (%d)", T55xx_Timing.m[i].write_1 / 8, T55xx_Timing.m[i].write_1); + sprintf(s + strlen(s), "%3d (%4d) | ", T55xx_Timing.m[i].write_1 / 8, T55xx_Timing.m[i].write_1); else - Dbprintf(" [d] write_1............." _RED_("unconfigured")); + PRN_NA; if (T55xx_Timing.m[i].read_gap != 0xFFFF) - Dbprintf(" [e] readgap.............%d*8 (%d)", T55xx_Timing.m[i].read_gap / 8, T55xx_Timing.m[i].read_gap); + sprintf(s + strlen(s), "%3d (%4d) | ", T55xx_Timing.m[i].read_gap / 8, T55xx_Timing.m[i].read_gap); else - Dbprintf(" [e] readgap............." _RED_("unconfigured")); + PRN_NA; - if (i == T55XX_DLMODE_1OF4) { - - if (T55xx_Timing.m[i].write_2 != 0xFFFF) - Dbprintf(" [f] write_2.............%d*8 (%d)", T55xx_Timing.m[i].write_2 / 8, T55xx_Timing.m[i].write_2); + if (T55xx_Timing.m[i].write_2 != 0xFFFF && i == T55XX_DLMODE_1OF4 ) + sprintf(s + strlen(s), "%3d (%4d) | ", T55xx_Timing.m[i].write_2 / 8, T55xx_Timing.m[i].write_2); else - Dbprintf(" [f] write_2............." _RED_("unconfigured")); + PRN_NA - if (T55xx_Timing.m[i].write_3 != 0xFFFF) - Dbprintf(" [g] write_3.............%d*8 (%d)", T55xx_Timing.m[i].write_3 / 8, T55xx_Timing.m[i].write_3); + if (T55xx_Timing.m[i].write_3 != 0xFFFF && i == T55XX_DLMODE_1OF4) + sprintf(s + strlen(s), "%3d (%4d) | ", T55xx_Timing.m[i].write_3 / 8, T55xx_Timing.m[i].write_3); else - Dbprintf(" [f] write_3............." _RED_("unconfigured")); - } + PRN_NA; + + s[strlen(s)] = 0; + DbpString(s); } + DbpString(""); } void setT55xxConfig(uint8_t arg0, t55xx_configurations_t *c) { From 0320455090ad332fc58b4755f7d52830078823d4 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 3 Aug 2019 09:53:08 -0400 Subject: [PATCH 0229/1854] chg 'lf t55xx deviceconfig - color adaptations --- armsrc/lfops.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 5436e4d81..a789b8db7 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -156,11 +156,11 @@ t55xx_configurations_t T55xx_Timing = { void printT55xxConfig(void) { -#define PRN_NA sprintf(s + strlen(s), _RED_(" N/A |")); +#define PRN_NA sprintf(s + strlen(s), _RED_(" N/A ") "| "); DbpString(_BLUE_("LF T55XX config")); - Dbprintf(" [a] [b] [c] [d] [e] [f] [g]"); - Dbprintf(" Mode | startgap | writegap | write 0 | write 1 | readgap | write_2 | write_3"); + Dbprintf(" [r] [a] [b] [c] [d] [e] [f] [g]"); + Dbprintf(" mode | startgap | writegap | write 0 | write 1 | readgap | write_2 | write_3"); Dbprintf("---------------------------+------------+------------+------------+------------+------------+------------+-------------"); for (uint8_t i = 0; i < 4; i++) { @@ -170,23 +170,23 @@ void printT55xxConfig(void) { switch (i) { case T55XX_DLMODE_FIXED : - sprintf(s, _YELLOW_("fixed bit length (default) |")); + sprintf(s, _YELLOW_("fixed bit length") _GREEN_("(default)") "|"); break; case T55XX_DLMODE_LLR : - sprintf(s, _YELLOW_(" long leading reference |")); + sprintf(s, _YELLOW_(" long leading reference") "|"); break; case T55XX_DLMODE_LEADING_ZERO : - sprintf(s, _YELLOW_(" leading zero |")); + sprintf(s, _YELLOW_(" leading zero") "|"); break; case T55XX_DLMODE_1OF4 : - sprintf(s, _YELLOW_(" 1 of 4 coding reference |")); + sprintf(s, _YELLOW_(" 1 of 4 coding reference") "|"); break; default: break; } if (T55xx_Timing.m[i].start_gap != 0xFFFF) - sprintf(s + strlen(s), "%3d (%4d) | ", T55xx_Timing.m[i].start_gap / 8, T55xx_Timing.m[i].start_gap); + sprintf(s + strlen(s), " %3d (%4d) | ", T55xx_Timing.m[i].start_gap / 8, T55xx_Timing.m[i].start_gap); else PRN_NA; From 65feeeafc8adb458e56f4c4ba894cbff3d7b4fbc Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 3 Aug 2019 18:48:08 +0200 Subject: [PATCH 0230/1854] chg: 'lf t55xx deviceconfig - a compact output' --- armsrc/lfops.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/armsrc/lfops.c b/armsrc/lfops.c index a789b8db7..c84cb19c9 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -156,13 +156,14 @@ t55xx_configurations_t T55xx_Timing = { void printT55xxConfig(void) { -#define PRN_NA sprintf(s + strlen(s), _RED_(" N/A ") "| "); +#define PRN_NA sprintf(s + strlen(s), _RED_("N/A") "| "); DbpString(_BLUE_("LF T55XX config")); - Dbprintf(" [r] [a] [b] [c] [d] [e] [f] [g]"); - Dbprintf(" mode | startgap | writegap | write 0 | write 1 | readgap | write_2 | write_3"); - Dbprintf("---------------------------+------------+------------+------------+------------+------------+------------+-------------"); - + Dbprintf(" [r] [a] [b] [c] [d] [e] [f] [g]"); + Dbprintf(" mode |start|write|write|write| read|write|write"); + Dbprintf(" | gap | gap | 0 | 1 | gap | 2 | 3"); + Dbprintf("---------------------------+-----+-----+-----+-----+-----+-----+------"); + for (uint8_t i = 0; i < 4; i++) { char s[160]; @@ -186,37 +187,37 @@ void printT55xxConfig(void) { } if (T55xx_Timing.m[i].start_gap != 0xFFFF) - sprintf(s + strlen(s), " %3d (%4d) | ", T55xx_Timing.m[i].start_gap / 8, T55xx_Timing.m[i].start_gap); + sprintf(s + strlen(s), " %3d | ", T55xx_Timing.m[i].start_gap / 8); else PRN_NA; if (T55xx_Timing.m[i].write_gap != 0xFFFF) - sprintf(s + strlen(s), "%3d (%4d) | ", T55xx_Timing.m[i].write_gap / 8, T55xx_Timing.m[i].write_gap); + sprintf(s + strlen(s), "%3d | ", T55xx_Timing.m[i].write_gap / 8); else PRN_NA; if (T55xx_Timing.m[i].write_0 != 0xFFFF) - sprintf(s + strlen(s), "%3d (%4d) | ", T55xx_Timing.m[i].write_0 / 8, T55xx_Timing.m[i].write_0); + sprintf(s + strlen(s), "%3d | ", T55xx_Timing.m[i].write_0 / 8); else PRN_NA; if (T55xx_Timing.m[i].write_1 != 0xFFFF) - sprintf(s + strlen(s), "%3d (%4d) | ", T55xx_Timing.m[i].write_1 / 8, T55xx_Timing.m[i].write_1); + sprintf(s + strlen(s), "%3d | ", T55xx_Timing.m[i].write_1 / 8); else PRN_NA; if (T55xx_Timing.m[i].read_gap != 0xFFFF) - sprintf(s + strlen(s), "%3d (%4d) | ", T55xx_Timing.m[i].read_gap / 8, T55xx_Timing.m[i].read_gap); + sprintf(s + strlen(s), "%3d | ", T55xx_Timing.m[i].read_gap / 8); else PRN_NA; if (T55xx_Timing.m[i].write_2 != 0xFFFF && i == T55XX_DLMODE_1OF4 ) - sprintf(s + strlen(s), "%3d (%4d) | ", T55xx_Timing.m[i].write_2 / 8, T55xx_Timing.m[i].write_2); + sprintf(s + strlen(s), "%3d | ", T55xx_Timing.m[i].write_2 / 8); else PRN_NA if (T55xx_Timing.m[i].write_3 != 0xFFFF && i == T55XX_DLMODE_1OF4) - sprintf(s + strlen(s), "%3d (%4d) | ", T55xx_Timing.m[i].write_3 / 8, T55xx_Timing.m[i].write_3); + sprintf(s + strlen(s), "%3d | ", T55xx_Timing.m[i].write_3 / 8); else PRN_NA; @@ -1700,7 +1701,7 @@ void T55xx_SendCMD(uint32_t data, uint32_t pwd, uint16_t arg) { // Trigger T55x7 in mode. FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - WaitUS(T55xx_Timing.m[downlink_mode].start_gap * 8); + WaitUS(T55xx_Timing.m[downlink_mode].start_gap); // If long leading 0 send long reference pulse if (downlink_mode == T55XX_DLMODE_LLR) From 714280fad245b07db871b230d61e9ec08e6ae012 Mon Sep 17 00:00:00 2001 From: Victor Date: Sat, 3 Aug 2019 17:17:35 +0100 Subject: [PATCH 0231/1854] Fix password write offset by 1 --- armsrc/hitag2.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index 682dd950a..6a70f59e9 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -377,7 +377,7 @@ static bool hitag2_password(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t // Reset the transmission frame length *txlen = 0; - if (bPwd && write) { + if (bPwd && !bAuthenticating && write) { if (!hitag2_write_page(rx, rxlen, tx, txlen)) { return false; } @@ -399,21 +399,26 @@ static bool hitag2_password(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t // Received UID, tag password case 32: { if (!bPwd) { - *txlen = 32; - memcpy(tx, password, 4); bPwd = true; - memcpy(tag.sectors[blocknr], rx, 4); - blocknr++; - } else { - - if (blocknr == 1) { - //store password in block1, the TAG answers with Block3, but we need the password in memory - memcpy(tag.sectors[blocknr], tx, 4); - } else { + bAuthenticating = true; + memcpy(tx, password, 4); + *txlen = 32; + } + else { + if (bAuthenticating) { + bAuthenticating = false; + if (write) { + if (!hitag2_write_page(rx, rxlen, tx, txlen)) { + return false; + } + break; + } + } + else { memcpy(tag.sectors[blocknr], rx, 4); + blocknr++; } - blocknr++; if (blocknr > 7) { DbpString("Read succesful!"); bSuccessful = true; @@ -1104,6 +1109,7 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { memcpy(password, htd->pwd.password, 4); blocknr = 0; bPwd = false; + bAuthenticating = false; break; } case RHT2F_AUTHENTICATE: { @@ -1405,6 +1411,7 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) { Dbhexdump(4, password, false); blocknr = page; bPwd = false; + bAuthenticating = false; writestate = WRITE_STATE_START; } break; From 35d5cdc5380364ddb381d3d23bc412409008637f Mon Sep 17 00:00:00 2001 From: Victor Date: Sat, 3 Aug 2019 18:25:44 +0100 Subject: [PATCH 0232/1854] Add VSCode tasks --- .vscode/tasks.json | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 .vscode/tasks.json diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 000000000..ca3660980 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,27 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "build", + "type": "shell", + "command": "make clean && make all -j$(nproc --all)", + "problemMatcher": [ + "$gcc" + ] + }, + { + "label": "flash fullimage", + "type": "shell", + "command": "./flash-fullimage.sh", + "problemMatcher": [] + }, + { + "label": "FLASH BOOTROM", + "type": "shell", + "command": "./flash-bootrom.sh", + "problemMatcher": [] + } + ] +} \ No newline at end of file From a0193fa90341c7e675d197e39d6f89007fd5420f Mon Sep 17 00:00:00 2001 From: Victor Date: Sat, 3 Aug 2019 16:46:58 +0100 Subject: [PATCH 0233/1854] Better warn user of hardcoded hitag info --- client/cmdlfhitag.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/client/cmdlfhitag.c b/client/cmdlfhitag.c index 0fc4b053c..1a50b0ac3 100644 --- a/client/cmdlfhitag.c +++ b/client/cmdlfhitag.c @@ -478,15 +478,9 @@ static bool getHitagUid(uint32_t *uid) { } static int CmdLFHitagInfo(const char *Cmd) { - PrintAndLogEx(INFO, "Hitag2 tag information "); - PrintAndLogEx(INFO, "To be done!"); - PrintAndLogEx(INFO, "------------------------------------"); - char ctmp = tolower(param_getchar(Cmd, 0)); if (ctmp == 'h') return usage_hitag_info(); - // pwd or key - // read UID uint32_t uid = 0; if (getHitagUid(&uid) == false) @@ -495,8 +489,8 @@ static int CmdLFHitagInfo(const char *Cmd) { PrintAndLogEx(SUCCESS, "UID: %08X", uid); // how to detemine Hitag types? - // read block3, get configuration byte. + PrintAndLogEx(FAILED, _RED_("TODO: This is a hardcoded example!")); // common configurations. printHitagConfiguration(0x06); From 868469db0dae4f1eb6465419a2a3915924d5b747 Mon Sep 17 00:00:00 2001 From: Victor Date: Wed, 10 Jul 2019 23:22:51 +0100 Subject: [PATCH 0234/1854] Fix comment alignment --- armsrc/hitag2.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index 6a70f59e9..e25fbd91a 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -697,7 +697,7 @@ void SniffHitag(void) { StopTicks(); -// int frame_count; + // int frame_count; int response; int overflow; bool rising_edge; @@ -755,7 +755,7 @@ void SniffHitag(void) { // Reset the received frame, frame count and timing info memset(rx, 0x00, sizeof(rx)); -// frame_count = 0; + // frame_count = 0; response = 0; overflow = 0; reader_frame = false; @@ -862,7 +862,7 @@ void SniffHitag(void) { // Check if frame was captured if (rxlen > 0) { -// frame_count++; + // frame_count++; LogTrace(rx, nbytes(rxlen), response, 0, NULL, reader_frame); // Check if we recognize a valid authentication attempt @@ -912,7 +912,7 @@ void SimulateHitagTag(bool tag_mem_supplied, uint8_t *data) { StopTicks(); -// int frame_count = 0; + // int frame_count = 0; int response = 0, overflow = 0; uint8_t rx[HITAG_FRAME_LEN]; size_t rxlen = 0; @@ -1030,7 +1030,7 @@ void SimulateHitagTag(bool tag_mem_supplied, uint8_t *data) { // Check if frame was captured if (rxlen > 4) { -// frame_count++; + // frame_count++; LogTrace(rx, nbytes(rxlen), response, response, NULL, true); // Disable timer 1 with external trigger to avoid triggers during our own modulation @@ -1086,7 +1086,7 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { StopTicks(); -// int frame_count = 0; + // int frame_count = 0; int response = 0; uint8_t rx[HITAG_FRAME_LEN]; size_t rxlen = 0; @@ -1222,7 +1222,7 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { // Check if frame was captured and store it if (rxlen > 0) { -// frame_count++; + // frame_count++; LogTrace(rx, nbytes(rxlen), response, response, NULL, false); } @@ -1278,7 +1278,7 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { // Add transmitted frame to total count if (txlen > 0) { -// frame_count++; + // frame_count++; LogTrace(tx, nbytes(txlen), HITAG_T_WAIT_2, HITAG_T_WAIT_2, NULL, true); } @@ -1372,7 +1372,7 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) { StopTicks(); -// int frame_count = 0; + // int frame_count = 0; int response = 0; uint8_t rx[HITAG_FRAME_LEN]; size_t rxlen = 0; @@ -1493,7 +1493,7 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) { // Check if frame was captured and store it if (rxlen > 0) { -// frame_count++; + // frame_count++; LogTrace(rx, nbytes(rxlen), response, response, NULL, false); } @@ -1534,7 +1534,7 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) { // Add transmitted frame to total count if (txlen > 0) { -// frame_count++; + // frame_count++; LogTrace(tx, nbytes(txlen), HITAG_T_WAIT_2, HITAG_T_WAIT_2, NULL, true); } From 4bd03bb920c47ad6601c6e8cbad7319802c041b7 Mon Sep 17 00:00:00 2001 From: Victor Date: Wed, 10 Jul 2019 23:23:50 +0100 Subject: [PATCH 0235/1854] Fix more comment alignment --- armsrc/hitag2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index e25fbd91a..7ae3a2cf2 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -272,8 +272,8 @@ static void hitag2_handle_reader_command(uint8_t *rx, const size_t rxlen, uint8_ break; } -// LogTrace(rx, nbytes(rxlen), 0, 0, NULL, false); -// LogTrace(tx, nbytes(txlen), 0, 0, NULL, true); + // LogTrace(rx, nbytes(rxlen), 0, 0, NULL, false); + // LogTrace(tx, nbytes(txlen), 0, 0, NULL, true); if (tag.crypto_active) { hitag2_cipher_transcrypt(&(tag.cs), tx, *txlen / 8, *txlen % 8); From 835a8a3b03859aa1f9e47b26a5bafc4d6cea19a9 Mon Sep 17 00:00:00 2001 From: Victor Date: Wed, 10 Jul 2019 23:49:08 +0100 Subject: [PATCH 0236/1854] Add state comments --- armsrc/hitag2.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index 7ae3a2cf2..dd3ff3d79 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -27,8 +27,11 @@ #include "string.h" #include "BigBuf.h" +// Successful crypto auth static bool bCrypto; +// Is in auth stage static bool bAuthenticating; +// Successful password auth static bool bPwd; static bool bSuccessful; From 5913ee670a9f688c2ef5580c6715c40e7bd1b75a Mon Sep 17 00:00:00 2001 From: Victor Date: Sat, 3 Aug 2019 15:49:19 +0100 Subject: [PATCH 0237/1854] Add auth comments --- armsrc/hitag2.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index dd3ff3d79..c541e57ae 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -401,6 +401,7 @@ static bool hitag2_password(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t // Received UID, tag password case 32: { + // stage 1, got UID if (!bPwd) { bPwd = true; bAuthenticating = true; @@ -408,6 +409,7 @@ static bool hitag2_password(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t *txlen = 32; } else { + // stage 2, got config byte+password TAG, discard as will read later if (bAuthenticating) { bAuthenticating = false; if (write) { @@ -417,6 +419,7 @@ static bool hitag2_password(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t break; } } + // stage 2+, got data block else { memcpy(tag.sectors[blocknr], rx, 4); blocknr++; @@ -496,19 +499,22 @@ static bool hitag2_crypto(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t * } // Received UID, crypto tag answer case 32: { + // stage 1, got UID if (!bCrypto) { uint64_t ui64key = key[0] | ((uint64_t)key[1]) << 8 | ((uint64_t)key[2]) << 16 | ((uint64_t)key[3]) << 24 | ((uint64_t)key[4]) << 32 | ((uint64_t)key[5]) << 40; uint32_t ui32uid = rx[0] | ((uint32_t)rx[1]) << 8 | ((uint32_t)rx[2]) << 16 | ((uint32_t)rx[3]) << 24; Dbprintf("hitag2_crypto: key=0x%x%x uid=0x%x", (uint32_t)((REV64(ui64key)) >> 32), (uint32_t)((REV64(ui64key)) & 0xffffffff), REV32(ui32uid)); cipher_state = _hitag2_init(REV64(ui64key), REV32(ui32uid), 0); + // PRN memset(tx, 0x00, 4); + // Secret data memset(tx + 4, 0xff, 4); hitag2_cipher_transcrypt(&cipher_state, tx + 4, 4, 0); *txlen = 64; bCrypto = true; bAuthenticating = true; } else { - // Check if we received answer tag (at) + // stage 2, got config byte+password TAG, discard as will read later if (bAuthenticating) { bAuthenticating = false; if (write) { @@ -517,7 +523,9 @@ static bool hitag2_crypto(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t * } break; } - } else { + } + // stage 2+, got data block + else { // Store the received block memcpy(tag.sectors[blocknr], rx, 4); blocknr++; From cbf5c717f74b797493533f74b7d97ed0f070e2fa Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 3 Aug 2019 19:01:46 +0200 Subject: [PATCH 0238/1854] Remove unused CMD_* --- client/deprecated-hid-flasher/flasher/usb_cmd.h | 4 ---- include/pm3_cmd.h | 16 ---------------- 2 files changed, 20 deletions(-) diff --git a/client/deprecated-hid-flasher/flasher/usb_cmd.h b/client/deprecated-hid-flasher/flasher/usb_cmd.h index 60c359e5a..44cad2942 100644 --- a/client/deprecated-hid-flasher/flasher/usb_cmd.h +++ b/client/deprecated-hid-flasher/flasher/usb_cmd.h @@ -68,7 +68,6 @@ typedef struct { // For low-frequency tags #define CMD_READ_TI_TYPE 0x0202 #define CMD_WRITE_TI_TYPE 0x0203 -#define CMD_DOWNLOADED_RAW_BITS_TI_TYPE 0x0204 #define CMD_ACQUIRE_RAW_ADC_SAMPLES_125K 0x0205 #define CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K 0x0206 #define CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K 0x0207 @@ -118,7 +117,6 @@ typedef struct { #define CMD_SIMTAG_ISO_15693 0x0311 #define CMD_RECORD_RAW_ADC_SAMPLES_ISO_15693 0x0312 #define CMD_ISO_15693_COMMAND 0x0313 -#define CMD_ISO_15693_COMMAND_DONE 0x0314 #define CMD_ISO_15693_FIND_AFI 0x0315 #define CMD_LF_SNIFF_RAW_ADC_SAMPLES 0x0317 @@ -132,7 +130,6 @@ typedef struct { #define CMD_TEST_HITAGS_TRACES 0x0367 #define CMD_READ_HITAG_S 0x0373 #define CMD_WR_HITAG_S 0x0375 -#define CMD_EMU_HITAG_S 0x0376 #define CMD_ANTIFUZZ_ISO_14443a 0x0380 #define CMD_SIMULATE_TAG_ISO_14443B 0x0381 @@ -150,7 +147,6 @@ typedef struct { #define CMD_LEGIC_INFO 0x03BC #define CMD_LEGIC_ESET 0x03BD -#define CMD_LEGIC_EGET 0x03BE #define CMD_SNIFF_ICLASS 0x0392 #define CMD_SIMULATE_TAG_ICLASS 0x0393 diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 33e291d8c..6c80f56a3 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -317,7 +317,6 @@ typedef struct { // For low-frequency tags #define CMD_READ_TI_TYPE 0x0202 #define CMD_WRITE_TI_TYPE 0x0203 -#define CMD_DOWNLOADED_RAW_BITS_TI_TYPE 0x0204 #define CMD_ACQUIRE_RAW_ADC_SAMPLES_125K 0x0205 #define CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K 0x0206 #define CMD_DOWNLOAD_BIGBUF 0x0207 @@ -367,7 +366,6 @@ typedef struct { #define CMD_SIMTAG_ISO_15693 0x0311 #define CMD_RECORD_RAW_ADC_SAMPLES_ISO_15693 0x0312 #define CMD_ISO_15693_COMMAND 0x0313 -#define CMD_ISO_15693_COMMAND_DONE 0x0314 #define CMD_ISO_15693_FIND_AFI 0x0315 #define CMD_LF_SNIFF_RAW_ADC_SAMPLES 0x0317 @@ -381,7 +379,6 @@ typedef struct { #define CMD_SIMULATE_HITAG_S 0x0368 #define CMD_READ_HITAG_S 0x0373 #define CMD_WR_HITAG_S 0x0375 -#define CMD_EMU_HITAG_S 0x0376 #define CMD_ANTIFUZZ_ISO_14443a 0x0380 #define CMD_SIMULATE_TAG_ISO_14443B 0x0381 @@ -392,7 +389,6 @@ typedef struct { #define CMD_READER_ISO_14443a 0x0385 -#define CMD_RAW_WRITER_LEGIC_RF 0x0386 #define CMD_SIMULATE_TAG_LEGIC_RF 0x0387 #define CMD_READER_LEGIC_RF 0x0388 #define CMD_WRITER_LEGIC_RF 0x0389 @@ -402,7 +398,6 @@ typedef struct { #define CMD_LEGIC_INFO 0x03BC #define CMD_LEGIC_ESET 0x03BD -#define CMD_LEGIC_EGET 0x03BE #define CMD_ICLASS_READCHECK 0x038F #define CMD_ICLASS_CLONE 0x0390 @@ -483,17 +478,6 @@ typedef struct { #define CMD_HF_SNIFFER 0x0800 -// For EMV Commands -#define CMD_EMV_READ_RECORD 0x0700 -#define CMD_EMV_TRANSACTION 0x0701 -#define CMD_EMV_CLONE 0x0702 -#define CMD_EMV_SIM 0x0703 -#define CMD_EMV_TEST 0x0704 -#define CMD_EMV_FUZZ_RATS 0x0705 -#define CMD_EMV_GET_RANDOM_NUM 0x0706 -#define CMD_EMV_LOAD_VALUE 0x0707 -#define CMD_EMV_DUMP_CARD 0x0708 - // For ThinFilm Kovio #define CMD_THINFILM_READ 0x0810 #define CMD_SIMULATE_TAG_THINFILM 0x0811 From a0a232a98539fbf0ecc78761772410705c72e3b2 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 3 Aug 2019 19:17:00 +0200 Subject: [PATCH 0239/1854] rename few CMD_* to get some less diversity --- armsrc/Standalone/hf_young.c | 8 +- armsrc/appmain.c | 238 ++++++++--------- armsrc/iclass.c | 12 +- armsrc/iso14443a.c | 8 +- armsrc/lfops.c | 22 +- armsrc/mifarecmd.c | 12 +- armsrc/mifaresim.c | 2 +- armsrc/thinfilm.c | 4 +- client/cmdhf.c | 2 +- client/cmdhf14a.c | 36 +-- client/cmdhf14b.c | 34 +-- client/cmdhf15.c | 24 +- client/cmdhfepa.c | 6 +- client/cmdhffelica.c | 14 +- client/cmdhficlass.c | 32 +-- client/cmdhflegic.c | 16 +- client/cmdhfmf.c | 54 ++-- client/cmdhfmfdes.c | 36 +-- client/cmdhfmfhard.c | 4 +- client/cmdhfmfp.c | 2 +- client/cmdhfmfu.c | 40 +-- client/cmdhfthinfilm.c | 8 +- client/cmdhftopaz.c | 6 +- client/cmdhw.c | 2 +- client/cmdlf.c | 34 +-- client/cmdlfawid.c | 12 +- client/cmdlfcotag.c | 2 +- client/cmdlfem4x.c | 14 +- client/cmdlffdx.c | 8 +- client/cmdlfguard.c | 8 +- client/cmdlfhid.c | 10 +- client/cmdlfhitag.c | 20 +- client/cmdlfindala.c | 8 +- client/cmdlfio.c | 8 +- client/cmdlfjablotron.c | 8 +- client/cmdlfkeri.c | 8 +- client/cmdlfnedap.c | 8 +- client/cmdlfnoralsy.c | 8 +- client/cmdlfparadox.c | 4 +- client/cmdlfpcf7931.c | 4 +- client/cmdlfpresco.c | 8 +- client/cmdlfpyramid.c | 8 +- client/cmdlft55xx.c | 16 +- client/cmdlfti.c | 4 +- client/cmdlfviking.c | 6 +- client/cmdlfvisa2000.c | 8 +- .../deprecated-hid-flasher/flasher/usb_cmd.h | 198 +++++++-------- client/lualibs/emulator.lua | 6 +- client/lualibs/read14a.lua | 4 +- client/lualibs/read14b.lua | 6 +- client/lualibs/read15.lua | 4 +- client/mifare/mifarehost.c | 32 +-- client/scripting.c | 4 +- client/scripts/14araw.lua | 2 +- client/scripts/amiibo.lua | 4 +- client/scripts/calypso.lua | 2 +- client/scripts/didump.lua | 2 +- client/scripts/mfkeys.lua | 2 +- client/scripts/mifareplus.lua | 2 +- client/scripts/ndef_dump.lua | 4 +- client/scripts/test_t55x7.lua | 2 +- client/scripts/test_t55x7_ask.lua | 2 +- client/scripts/test_t55x7_bi.lua | 2 +- client/scripts/test_t55x7_fsk.lua | 2 +- client/scripts/test_t55x7_psk.lua | 2 +- client/scripts/tnp3clone.lua | 4 +- client/scripts/tnp3dump.lua | 6 +- client/scripts/tnp3sim.lua | 2 +- client/scripts/ufodump.lua | 2 +- client/util.h | 2 +- include/pm3_cmd.h | 240 +++++++++--------- 71 files changed, 687 insertions(+), 687 deletions(-) diff --git a/armsrc/Standalone/hf_young.c b/armsrc/Standalone/hf_young.c index 906d0b36c..7948400ff 100644 --- a/armsrc/Standalone/hf_young.c +++ b/armsrc/Standalone/hf_young.c @@ -138,18 +138,18 @@ void RunMod() { SpinDelay(500); // Begin clone function here: /* Example from client/mifarehost.c for commanding a block write for "magic Chinese" cards: - SendCommandOLD(CMD_MIFARE_CSETBLOCK, params & (0xFE | (uid == NULL ? 0:1)), blockNo, 0, data, 16); + SendCommandOLD(CMD_HF_MIFARE_CSETBL, params & (0xFE | (uid == NULL ? 0:1)), blockNo, 0, data, 16); Block read is similar: - SendCommandOLD(CMD_MIFARE_CGETBLOCK, params, blockNo, 0,...}; + SendCommandOLD(CMD_HF_MIFARE_CGETBL, params, blockNo, 0,...}; We need to imitate that call with blockNo 0 to set a uid. The get and set commands are handled in this file: // Work with "magic Chinese" card - case CMD_MIFARE_CSETBLOCK: + case CMD_HF_MIFARE_CSETBL: MifareCSetBlock(c->arg[0], c->arg[1], c->d.asBytes); break; - case CMD_MIFARE_CGETBLOCK: + case CMD_HF_MIFARE_CGETBL: MifareCGetBlock(c->arg[0], c->arg[1], c->d.asBytes); break; diff --git a/armsrc/appmain.c b/armsrc/appmain.c index f08229783..e372f2eec 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -756,25 +756,25 @@ static void PacketReceived(PacketCommandNG *packet) { reply_via_usb = false; break; #ifdef WITH_LF - case CMD_SET_LF_T55XX_CONFIG: { + case CMD_LF_T55XX_SET_CONFIG: { setT55xxConfig(packet->oldarg[0], (t55xx_configurations_t *) packet->data.asBytes); break; } - case CMD_SET_LF_SAMPLING_CONFIG: { + case CMD_LF_SAMPLING_SET_CONFIG: { setSamplingConfig((sample_config *) packet->data.asBytes); break; } - case CMD_ACQUIRE_RAW_ADC_SAMPLES_125K: { + case CMD_LF_ACQ_RAW_ADC: { struct p { uint8_t silent; uint32_t samples; } PACKED; struct p *payload = (struct p *)packet->data.asBytes; uint32_t bits = SampleLF(payload->silent, payload->samples); - reply_ng(CMD_ACQUIRE_RAW_ADC_SAMPLES_125K, PM3_SUCCESS, (uint8_t *)&bits, sizeof(bits)); + reply_ng(CMD_LF_ACQ_RAW_ADC, PM3_SUCCESS, (uint8_t *)&bits, sizeof(bits)); break; } - case CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K: { + case CMD_LF_MOD_THEN_ACQ_RAW_ADC: { struct p { uint32_t delay; uint16_t ones; @@ -784,67 +784,67 @@ static void PacketReceived(PacketCommandNG *packet) { ModThenAcquireRawAdcSamples125k(payload->delay, payload->zeros, payload->ones, packet->data.asBytes + 8); break; } - case CMD_LF_SNIFF_RAW_ADC_SAMPLES: { + case CMD_LF_SNIFF_RAW_ADC: { uint32_t bits = SniffLF(); reply_mix(CMD_ACK, bits, 0, 0, 0, 0); break; } - case CMD_HID_DEMOD_FSK: { + case CMD_LF_HID_DEMOD: { uint32_t high, low; CmdHIDdemodFSK(packet->oldarg[0], &high, &low, 1); break; } - case CMD_HID_SIM_TAG: { + case CMD_LF_HID_SIMULATE: { CmdHIDsimTAG(packet->oldarg[0], packet->oldarg[1], 1); break; } - case CMD_FSK_SIM_TAG: { + case CMD_LF_FSK_SIMULATE: { lf_fsksim_t *payload = (lf_fsksim_t *)packet->data.asBytes; CmdFSKsimTAG(payload->fchigh, payload->fclow, payload->separator, payload->clock, packet->length - sizeof(lf_fsksim_t), payload->data, true); break; } - case CMD_ASK_SIM_TAG: { + case CMD_LF_ASK_SIMULATE: { lf_asksim_t *payload = (lf_asksim_t *)packet->data.asBytes; CmdASKsimTAG(payload->encoding, payload->invert, payload->separator, payload->clock, packet->length - sizeof(lf_asksim_t), payload->data, true); break; } - case CMD_PSK_SIM_TAG: { + case CMD_LF_PSK_SIMULATE: { lf_psksim_t *payload = (lf_psksim_t *)packet->data.asBytes; CmdPSKsimTag(payload->carrier, payload->invert, payload->clock, packet->length - sizeof(lf_psksim_t), payload->data, true); break; } - case CMD_HID_CLONE_TAG: { + case CMD_LF_HID_CLONE: { CopyHIDtoT55x7(packet->oldarg[0], packet->oldarg[1], packet->oldarg[2], packet->data.asBytes[0]); break; } - case CMD_IO_DEMOD_FSK: { + case CMD_LF_IO_DEMOD: { uint32_t high, low; CmdIOdemodFSK(packet->oldarg[0], &high, &low, 1); break; } - case CMD_IO_CLONE_TAG: { + case CMD_LF_IO_CLONE: { CopyIOtoT55x7(packet->oldarg[0], packet->oldarg[1]); break; } - case CMD_EM410X_DEMOD: { + case CMD_LF_EM410X_DEMOD: { uint32_t high; uint64_t low; CmdEM410xdemod(packet->oldarg[0], &high, &low, 1); break; } - case CMD_EM410X_WRITE_TAG: { + case CMD_LF_EM410X_WRITE: { WriteEM410x(packet->oldarg[0], packet->oldarg[1], packet->oldarg[2]); break; } - case CMD_READ_TI_TYPE: { + case CMD_LF_TI_READ: { ReadTItag(); break; } - case CMD_WRITE_TI_TYPE: { + case CMD_LF_TI_WRITE: { WriteTItag(packet->oldarg[0], packet->oldarg[1], packet->oldarg[2]); break; } - case CMD_SIMULATE_TAG_125K: { + case CMD_LF_SIMULATE: { LED_A_ON(); struct p { uint16_t len; @@ -853,7 +853,7 @@ static void PacketReceived(PacketCommandNG *packet) { struct p *payload = (struct p *)packet->data.asBytes; // length, start gap, led control SimulateTagLowFrequency(payload->len, payload->gap, 1); - reply_ng(CMD_SIMULATE_TAG_125K, PM3_EOPABORTED, NULL, 0); + reply_ng(CMD_LF_SIMULATE, PM3_EOPABORTED, NULL, 0); LED_A_OFF(); break; } @@ -861,18 +861,18 @@ static void PacketReceived(PacketCommandNG *packet) { SimulateTagLowFrequencyBidir(packet->oldarg[0], packet->oldarg[1]); break; } - case CMD_INDALA_CLONE_TAG: { + case CMD_LF_INDALA_CLONE: { CopyIndala64toT55x7(packet->data.asDwords[0], packet->data.asDwords[1]); break; } - case CMD_INDALA_CLONE_TAG_L: { + case CMD_LF_INDALA224_CLONE: { CopyIndala224toT55x7( packet->data.asDwords[0], packet->data.asDwords[1], packet->data.asDwords[2], packet->data.asDwords[3], packet->data.asDwords[4], packet->data.asDwords[5], packet->data.asDwords[6] ); break; } - case CMD_T55XX_READ_BLOCK: { + case CMD_LF_T55XX_READBL: { struct p { uint32_t password; uint8_t blockno; @@ -884,28 +884,28 @@ static void PacketReceived(PacketCommandNG *packet) { T55xxReadBlock(payload->page, payload->pwdmode, false, payload->blockno, payload->password, payload->downlink_mode); break; } - case CMD_T55XX_WRITE_BLOCK: { + case CMD_LF_T55XX_WRITEBL: { // uses NG format T55xxWriteBlock(packet->data.asBytes); break; } - case CMD_T55XX_WAKEUP: { + case CMD_LF_T55XX_WAKEUP: { T55xxWakeUp(packet->oldarg[0], packet->oldarg[1]); break; } - case CMD_T55XX_RESET_READ: { + case CMD_LF_T55XX_RESET_READ: { T55xxResetRead(packet->data.asBytes[0] & 0xff); break; } - case CMD_T55XX_CHKPWDS: { + case CMD_LF_T55XX_CHK_PWDS: { T55xx_ChkPwds(packet->data.asBytes[0] & 0xff); break; } - case CMD_PCF7931_READ: { + case CMD_LF_PCF7931_READ: { ReadPCF7931(); break; } - case CMD_PCF7931_WRITE: { + case CMD_LF_PCF7931_WRITE: { WritePCF7931( packet->data.asBytes[0], packet->data.asBytes[1], packet->data.asBytes[2], packet->data.asBytes[3], packet->data.asBytes[4], packet->data.asBytes[5], packet->data.asBytes[6], packet->data.asBytes[9], @@ -916,7 +916,7 @@ static void PacketReceived(PacketCommandNG *packet) { ); break; } - case CMD_EM4X_READ_WORD: { + case CMD_LF_EM4X_READWORD: { struct p { uint32_t password; uint8_t address; @@ -926,7 +926,7 @@ static void PacketReceived(PacketCommandNG *packet) { EM4xReadWord(payload->address, payload->password, payload->usepwd); break; } - case CMD_EM4X_WRITE_WORD: { + case CMD_LF_EM4X_WRITEWORD: { struct p { uint32_t password; uint32_t data; @@ -937,48 +937,48 @@ static void PacketReceived(PacketCommandNG *packet) { EM4xWriteWord(payload->address, payload->data, payload->password, payload->usepwd); break; } - case CMD_AWID_DEMOD_FSK: { + case CMD_LF_AWID_DEMOD: { uint32_t high, low; // Set realtime AWID demodulation CmdAWIDdemodFSK(packet->oldarg[0], &high, &low, 1); break; } - case CMD_VIKING_CLONE_TAG: { + case CMD_LF_VIKING_CLONE: { CopyVikingtoT55xx(packet->oldarg[0], packet->oldarg[1], packet->oldarg[2]); break; } - case CMD_COTAG: { + case CMD_LF_COTAG_READ: { Cotag(packet->oldarg[0]); break; } #endif #ifdef WITH_HITAG - case CMD_SNIFF_HITAG: { // Eavesdrop Hitag tag, args = type + case CMD_LF_HITAG_SNIFF: { // Eavesdrop Hitag tag, args = type SniffHitag(); break; } - case CMD_SIMULATE_HITAG: { // Simulate Hitag tag, args = memory content + case CMD_LF_HITAG_SIMULATE: { // Simulate Hitag tag, args = memory content SimulateHitagTag((bool)packet->oldarg[0], packet->data.asBytes); break; } - case CMD_READER_HITAG: { // Reader for Hitag tags, args = type and function + case CMD_LF_HITAG_READER: { // Reader for Hitag tags, args = type and function ReaderHitag((hitag_function)packet->oldarg[0], (hitag_data *)packet->data.asBytes); break; } - case CMD_SIMULATE_HITAG_S: { // Simulate Hitag s tag, args = memory content + case CMD_LF_HITAGS_SIMULATE: { // Simulate Hitag s tag, args = memory content SimulateHitagSTag((bool)packet->oldarg[0], packet->data.asBytes); break; } - case CMD_TEST_HITAGS_TRACES: { // Tests every challenge within the given file + case CMD_LF_HITAGS_TEST_TRACES: { // Tests every challenge within the given file check_challenges((bool)packet->oldarg[0], packet->data.asBytes); break; } - case CMD_READ_HITAG_S: { //Reader for only Hitag S tags, args = key or challenge + case CMD_LF_HITAGS_READ: { //Reader for only Hitag S tags, args = key or challenge ReadHitagS((hitag_function)packet->oldarg[0], (hitag_data *)packet->data.asBytes); break; } - case CMD_WR_HITAG_S: { //writer for Hitag tags args=data to write,page and key or challenge + case CMD_LF_HITAGS_WRITE: { //writer for Hitag tags args=data to write,page and key or challenge if ((hitag_function)packet->oldarg[0] < 10) { WritePageHitagS((hitag_function)packet->oldarg[0], (hitag_data *)packet->data.asBytes, packet->oldarg[2]); } else { @@ -989,50 +989,50 @@ static void PacketReceived(PacketCommandNG *packet) { #endif #ifdef WITH_ISO15693 - case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693: { + case CMD_HF_ISO15693_ACQ_RAW_ADC: { AcquireRawAdcSamplesIso15693(); break; } - case CMD_RECORD_RAW_ADC_SAMPLES_ISO_15693: { + case CMD_HF_ISO15693_RAWADC: { RecordRawAdcSamplesIso15693(); break; } - case CMD_ISO_15693_COMMAND: { + case CMD_HF_ISO15693_COMMAND: { DirectTag15693Command(packet->oldarg[0], packet->oldarg[1], packet->oldarg[2], packet->data.asBytes); break; } - case CMD_ISO_15693_FIND_AFI: { + case CMD_HF_ISO15693_FINDAFI: { BruteforceIso15693Afi(packet->oldarg[0]); break; } - case CMD_READER_ISO_15693: { + case CMD_HF_ISO15693_READER: { ReaderIso15693(packet->oldarg[0]); break; } - case CMD_SIMTAG_ISO_15693: { + case CMD_HF_ISO15693_SIMULATE: { SimTagIso15693(packet->oldarg[0], packet->data.asBytes); break; } #endif #ifdef WITH_LEGICRF - case CMD_SIMULATE_TAG_LEGIC_RF: { + case CMD_HF_LEGIC_SIMULATE: { LegicRfSimulate(packet->oldarg[0]); break; } - case CMD_WRITER_LEGIC_RF: { + case CMD_HF_LEGIC_WRITER: { LegicRfWriter(packet->oldarg[0], packet->oldarg[1], packet->oldarg[2], packet->data.asBytes); break; } - case CMD_READER_LEGIC_RF: { + case CMD_HF_LEGIC_READER: { LegicRfReader(packet->oldarg[0], packet->oldarg[1], packet->oldarg[2]); break; } - case CMD_LEGIC_INFO: { + case CMD_HF_LEGIC_INFO: { LegicRfInfo(); break; } - case CMD_LEGIC_ESET: { + case CMD_HF_LEGIC_ESET: { //----------------------------------------------------------------------------- // Note: we call FpgaDownloadAndGo(FPGA_BITSTREAM_HF) here although FPGA is not // involved in dealing with emulator memory. But if it is called later, it might @@ -1047,19 +1047,19 @@ static void PacketReceived(PacketCommandNG *packet) { #endif #ifdef WITH_ISO14443b - case CMD_READ_SRI_TAG: { + case CMD_HF_SRI_READ: { ReadSTMemoryIso14443b(packet->oldarg[0]); break; } - case CMD_SNIFF_ISO_14443B: { + case CMD_HF_ISO14443B_SNIFF: { SniffIso14443b(); break; } - case CMD_SIMULATE_TAG_ISO_14443B: { + case CMD_HF_ISO14443B_SIMULATE: { SimulateIso14443bTag(packet->oldarg[0]); break; } - case CMD_ISO_14443B_COMMAND: { + case CMD_HF_ISO14443B_COMMAND: { //SendRawCommand14443B(packet->oldarg[0],packet->oldarg[1],packet->oldarg[2],packet->data.asBytes); SendRawCommand14443B_Ex(packet); break; @@ -1067,34 +1067,34 @@ static void PacketReceived(PacketCommandNG *packet) { #endif #ifdef WITH_FELICA - case CMD_FELICA_COMMAND: { + case CMD_HF_FELICA_COMMAND: { felica_sendraw(packet); break; } - case CMD_FELICA_LITE_SIM: { + case CMD_HF_FELICALITE_SIMULATE: { felica_sim_lite(packet->oldarg[0]); break; } - case CMD_FELICA_SNIFF: { + case CMD_HF_FELICA_SNIFF: { felica_sniff(packet->oldarg[0], packet->oldarg[1]); break; } - case CMD_FELICA_LITE_DUMP: { + case CMD_HF_FELICALITE_DUMP: { felica_dump_lite_s(); break; } #endif #ifdef WITH_ISO14443a - case CMD_SNIFF_ISO_14443a: { + case CMD_HF_ISO14443A_SNIFF: { SniffIso14443a(packet->data.asBytes[0]); break; } - case CMD_READER_ISO_14443a: { + case CMD_HF_ISO14443A_READER: { ReaderIso14443a(packet); break; } - case CMD_SIMULATE_TAG_ISO_14443a: { + case CMD_HF_ISO14443A_SIMULATE: { struct p { uint8_t tagtype; uint8_t flags; @@ -1104,80 +1104,80 @@ static void PacketReceived(PacketCommandNG *packet) { SimulateIso14443aTag(payload->tagtype, payload->flags, payload->uid); // ## Simulate iso14443a tag - pass tag type & UID break; } - case CMD_ANTIFUZZ_ISO_14443a: { + case CMD_HF_ISO14443A_ANTIFUZZ: { iso14443a_antifuzz(packet->oldarg[0]); break; } - case CMD_EPA_PACE_COLLECT_NONCE: { + case CMD_HF_EPA_COLLECT_NONCE: { EPA_PACE_Collect_Nonce(packet); break; } - case CMD_EPA_PACE_REPLAY: { + case CMD_HF_EPA_REPLAY: { EPA_PACE_Replay(packet); break; } - case CMD_READER_MIFARE: { + case CMD_HF_MIFARE_READER: { ReaderMifare(packet->oldarg[0], packet->oldarg[1], packet->oldarg[2]); break; } - case CMD_MIFARE_READBL: { + case CMD_HF_MIFARE_READBL: { mf_readblock_t *payload = (mf_readblock_t *)packet->data.asBytes; MifareReadBlock(payload->blockno, payload->keytype, payload->key); break; } - case CMD_MIFAREU_READBL: { + case CMD_HF_MIFAREU_READBL: { MifareUReadBlock(packet->oldarg[0], packet->oldarg[1], packet->data.asBytes); break; } - case CMD_MIFAREUC_AUTH: { + case CMD_HF_MIFAREUC_AUTH: { MifareUC_Auth(packet->oldarg[0], packet->data.asBytes); break; } - case CMD_MIFAREU_READCARD: { + case CMD_HF_MIFAREU_READCARD: { MifareUReadCard(packet->oldarg[0], packet->oldarg[1], packet->oldarg[2], packet->data.asBytes); break; } - case CMD_MIFAREUC_SETPWD: { + case CMD_HF_MIFAREUC_SETPWD: { MifareUSetPwd(packet->oldarg[0], packet->data.asBytes); break; } - case CMD_MIFARE_READSC: { + case CMD_HF_MIFARE_READSC: { MifareReadSector(packet->oldarg[0], packet->oldarg[1], packet->data.asBytes); break; } - case CMD_MIFARE_WRITEBL: { + case CMD_HF_MIFARE_WRITEBL: { MifareWriteBlock(packet->oldarg[0], packet->oldarg[1], packet->data.asBytes); break; } - //case CMD_MIFAREU_WRITEBL_COMPAT: { + //case CMD_HF_MIFAREU_WRITEBL_COMPAT: { //MifareUWriteBlockCompat(packet->oldarg[0], packet->data.asBytes); //break; //} - case CMD_MIFAREU_WRITEBL: { + case CMD_HF_MIFAREU_WRITEBL: { MifareUWriteBlock(packet->oldarg[0], packet->oldarg[1], packet->data.asBytes); break; } - case CMD_MIFARE_ACQUIRE_ENCRYPTED_NONCES: { + case CMD_HF_MIFARE_ACQ_ENCRYPTED_NONCES: { MifareAcquireEncryptedNonces(packet->oldarg[0], packet->oldarg[1], packet->oldarg[2], packet->data.asBytes); break; } - case CMD_MIFARE_ACQUIRE_NONCES: { + case CMD_HF_MIFARE_ACQ_NONCES: { MifareAcquireNonces(packet->oldarg[0], packet->oldarg[2]); break; } - case CMD_MIFARE_NESTED: { + case CMD_HF_MIFARE_NESTED: { MifareNested(packet->oldarg[0], packet->oldarg[1], packet->oldarg[2], packet->data.asBytes); break; } - case CMD_MIFARE_CHKKEYS: { + case CMD_HF_MIFARE_CHKKEYS: { MifareChkKeys(packet->data.asBytes); break; } - case CMD_MIFARE_CHKKEYS_FAST: { + case CMD_HF_MIFARE_CHKKEYS_FAST: { MifareChkKeys_fast(packet->oldarg[0], packet->oldarg[1], packet->oldarg[2], packet->data.asBytes); break; } - case CMD_SIMULATE_MIFARE_CARD: { + case CMD_HF_MIFARE_SIMULATE: { struct p { uint16_t flags; uint8_t exitAfter; @@ -1194,12 +1194,12 @@ static void PacketReceived(PacketCommandNG *packet) { reply_ng(CMD_SET_DBGMODE, PM3_SUCCESS, NULL, 0); break; } - case CMD_MIFARE_EML_MEMCLR: { + case CMD_HF_MIFARE_EML_MEMCLR: { MifareEMemClr(); - reply_ng(CMD_MIFARE_EML_MEMCLR, PM3_SUCCESS, NULL, 0); + reply_ng(CMD_HF_MIFARE_EML_MEMCLR, PM3_SUCCESS, NULL, 0); break; } - case CMD_MIFARE_EML_MEMSET: { + case CMD_HF_MIFARE_EML_MEMSET: { struct p { uint8_t blockno; uint8_t blockcnt; @@ -1210,7 +1210,7 @@ static void PacketReceived(PacketCommandNG *packet) { MifareEMemSet(payload->blockno, payload->blockcnt, payload->blockwidth, payload->data); break; } - case CMD_MIFARE_EML_MEMGET: { + case CMD_HF_MIFARE_EML_MEMGET: { struct p { uint8_t blockno; uint8_t blockcnt; @@ -1219,71 +1219,71 @@ static void PacketReceived(PacketCommandNG *packet) { MifareEMemGet(payload->blockno, payload->blockcnt); break; } - case CMD_MIFARE_EML_CARDLOAD: { + case CMD_HF_MIFARE_EML_LOAD: { MifareECardLoad(packet->oldarg[0], packet->oldarg[1]); break; } // Work with "magic Chinese" card - case CMD_MIFARE_CSETBLOCK: { + case CMD_HF_MIFARE_CSETBL: { MifareCSetBlock(packet->oldarg[0], packet->oldarg[1], packet->data.asBytes); break; } - case CMD_MIFARE_CGETBLOCK: { + case CMD_HF_MIFARE_CGETBL: { MifareCGetBlock(packet->oldarg[0], packet->oldarg[1], packet->data.asBytes); break; } - case CMD_MIFARE_CIDENT: { + case CMD_HF_MIFARE_CIDENT: { MifareCIdent(); break; } // mifare sniffer -// case CMD_MIFARE_SNIFFER: { +// case CMD_HF_MIFARE_SNIFF: { // SniffMifare(packet->oldarg[0]); // break; // } - case CMD_MIFARE_SETMOD: { + case CMD_HF_MIFARE_SETMOD: { MifareSetMod(packet->data.asBytes); break; } //mifare desfire - case CMD_MIFARE_DESFIRE_READBL: { + case CMD_HF_DESFIRE_READBL: { break; } - case CMD_MIFARE_DESFIRE_WRITEBL: { + case CMD_HF_DESFIRE_WRITEBL: { break; } - case CMD_MIFARE_DESFIRE_AUTH1: { + case CMD_HF_DESFIRE_AUTH1: { MifareDES_Auth1(packet->oldarg[0], packet->oldarg[1], packet->oldarg[2], packet->data.asBytes); break; } - case CMD_MIFARE_DESFIRE_AUTH2: { + case CMD_HF_DESFIRE_AUTH2: { //MifareDES_Auth2(packet->oldarg[0],packet->data.asBytes); break; } - case CMD_MIFARE_DES_READER: { + case CMD_HF_DESFIRE_READER: { //readermifaredes(packet->oldarg[0], packet->oldarg[1], packet->data.asBytes); break; } - case CMD_MIFARE_DESFIRE_INFO: { + case CMD_HF_DESFIRE_INFO: { MifareDesfireGetInformation(); break; } - case CMD_MIFARE_DESFIRE: { + case CMD_HF_DESFIRE_COMMAND: { MifareSendCommand(packet->oldarg[0], packet->oldarg[1], packet->data.asBytes); break; } - case CMD_MIFARE_COLLECT_NONCES: { + case CMD_HF_MIFARE_COLLECT_NONCES: { break; } - case CMD_MIFARE_NACK_DETECT: { + case CMD_HF_MIFARE_NACK_DETECT: { DetectNACKbug(); break; } - case CMD_THINFILM_READ: { + case CMD_HF_THINFILM_READ: { ReadThinFilm(); break; } - case CMD_SIMULATE_TAG_THINFILM: { + case CMD_HF_THINFILM_SIMULATE: { SimulateThinFilm(packet->data.asBytes, packet->length); break; } @@ -1291,60 +1291,60 @@ static void PacketReceived(PacketCommandNG *packet) { #ifdef WITH_ICLASS // Makes use of ISO14443a FPGA Firmware - case CMD_SNIFF_ICLASS: { + case CMD_HF_ICLASS_SNIFF: { SniffIClass(); break; } - case CMD_SIMULATE_TAG_ICLASS: { + case CMD_HF_ICLASS_SIMULATE: { SimulateIClass(packet->oldarg[0], packet->oldarg[1], packet->oldarg[2], packet->data.asBytes); break; } - case CMD_READER_ICLASS: { + case CMD_HF_ICLASS_READER: { ReaderIClass(packet->oldarg[0]); break; } - case CMD_READER_ICLASS_REPLAY: { + case CMD_HF_ICLASS_REPLAY: { ReaderIClass_Replay(packet->oldarg[0], packet->data.asBytes); break; } - case CMD_ICLASS_EML_MEMSET: { + case CMD_HF_ICLASS_EML_MEMSET: { //iceman, should call FPGADOWNLOAD before, since it corrupts BigBuf FpgaDownloadAndGo(FPGA_BITSTREAM_HF); emlSet(packet->data.asBytes, packet->oldarg[0], packet->oldarg[1]); break; } - case CMD_ICLASS_WRITEBLOCK: { + case CMD_HF_ICLASS_WRITEBL: { iClass_WriteBlock(packet->oldarg[0], packet->data.asBytes); break; } - case CMD_ICLASS_READCHECK: { // auth step 1 + case CMD_HF_ICLASS_READCHECK: { // auth step 1 iClass_ReadCheck(packet->oldarg[0], packet->oldarg[1]); break; } - case CMD_ICLASS_READBLOCK: { + case CMD_HF_ICLASS_READBL: { iClass_ReadBlk(packet->oldarg[0]); break; } - case CMD_ICLASS_AUTHENTICATION: { //check + case CMD_HF_ICLASS_AUTH: { //check iClass_Authentication(packet->data.asBytes); break; } - case CMD_ICLASS_CHECK_KEYS: { + case CMD_HF_ICLASS_CHKKEYS: { iClass_Authentication_fast(packet->oldarg[0], packet->oldarg[1], packet->data.asBytes); break; } - case CMD_ICLASS_DUMP: { + case CMD_HF_ICLASS_DUMP: { iClass_Dump(packet->oldarg[0], packet->oldarg[1]); break; } - case CMD_ICLASS_CLONE: { + case CMD_HF_ICLASS_CLONE: { iClass_Clone(packet->oldarg[0], packet->oldarg[1], packet->data.asBytes); break; } #endif #ifdef WITH_HFSNIFF - case CMD_HF_SNIFFER: { + case CMD_HF_SNIFF: { HfSniff(packet->oldarg[0], packet->oldarg[1]); break; } @@ -1546,7 +1546,7 @@ static void PacketReceived(PacketCommandNG *packet) { break; } #ifdef WITH_LF - case CMD_UPLOAD_SIM_SAMPLES_125K: { + case CMD_LF_UPLOAD_SIM_SAMPLES: { // iceman; since changing fpga_bitstreams clears bigbuff, Its better to call it before. // to be able to use this one for uploading data to device // flag = @@ -1568,7 +1568,7 @@ static void PacketReceived(PacketCommandNG *packet) { uint8_t *mem = BigBuf_get_addr(); memcpy(mem + payload->offset, &payload->data, PM3_CMD_DATA_SIZE - 3); - reply_ng(CMD_UPLOAD_SIM_SAMPLES_125K, PM3_SUCCESS, NULL, 0); + reply_ng(CMD_LF_UPLOAD_SIM_SAMPLES, PM3_SUCCESS, NULL, 0); break; } #endif @@ -1836,7 +1836,7 @@ static void PacketReceived(PacketCommandNG *packet) { break; } #endif - case CMD_SET_LF_DIVISOR: { + case CMD_LF_SET_DIVISOR: { FpgaDownloadAndGo(FPGA_BITSTREAM_LF); FpgaSendCommand(FPGA_CMD_SET_DIVISOR, packet->data.asBytes[0]); break; diff --git a/armsrc/iclass.c b/armsrc/iclass.c index 1662a963a..7c7864401 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -1195,11 +1195,11 @@ void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain if (doIClassSimulation(MODE_EXIT_AFTER_MAC, mac_responses + i * EPURSE_MAC_SIZE)) { // Button pressed - reply_old(CMD_ACK, CMD_SIMULATE_TAG_ICLASS, i, 0, mac_responses, i * EPURSE_MAC_SIZE); + reply_old(CMD_ACK, CMD_HF_ICLASS_SIMULATE, i, 0, mac_responses, i * EPURSE_MAC_SIZE); goto out; } } - reply_old(CMD_ACK, CMD_SIMULATE_TAG_ICLASS, i, 0, mac_responses, i * EPURSE_MAC_SIZE); + reply_old(CMD_ACK, CMD_HF_ICLASS_SIMULATE, i, 0, mac_responses, i * EPURSE_MAC_SIZE); } else if (simType == 3) { //This is 'full sim' mode, where we use the emulator storage for data. @@ -1226,20 +1226,20 @@ void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain // keyroll 1 if (doIClassSimulation(MODE_EXIT_AFTER_MAC, mac_responses + i * EPURSE_MAC_SIZE)) { - reply_old(CMD_ACK, CMD_SIMULATE_TAG_ICLASS, i * 2, 0, mac_responses, i * EPURSE_MAC_SIZE * 2); + reply_old(CMD_ACK, CMD_HF_ICLASS_SIMULATE, i * 2, 0, mac_responses, i * EPURSE_MAC_SIZE * 2); // Button pressed goto out; } // keyroll 2 if (doIClassSimulation(MODE_EXIT_AFTER_MAC, mac_responses + (i + numberOfCSNS) * EPURSE_MAC_SIZE)) { - reply_old(CMD_ACK, CMD_SIMULATE_TAG_ICLASS, i * 2, 0, mac_responses, i * EPURSE_MAC_SIZE * 2); + reply_old(CMD_ACK, CMD_HF_ICLASS_SIMULATE, i * 2, 0, mac_responses, i * EPURSE_MAC_SIZE * 2); // Button pressed goto out; } } // double the amount of collected data. - reply_old(CMD_ACK, CMD_SIMULATE_TAG_ICLASS, i * 2, 0, mac_responses, i * EPURSE_MAC_SIZE * 2); + reply_old(CMD_ACK, CMD_HF_ICLASS_SIMULATE, i * 2, 0, mac_responses, i * EPURSE_MAC_SIZE * 2); } else { // We may want a mode here where we hardcode the csns to use (from proxclone). @@ -2222,7 +2222,7 @@ void ReaderIClass_Replay(uint8_t arg0, uint8_t *mac) { switch_off(); } -// not used. ?!? ( CMD_ICLASS_READCHECK) +// not used. ?!? ( CMD_HF_ICLASS_READCHECK) // turn off afterwards void iClass_ReadCheck(uint8_t blockno, uint8_t keytype) { uint8_t readcheck[] = { keytype, blockno }; diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index b17df8424..554fe57fa 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -1149,7 +1149,7 @@ void SimulateIso14443aTag(uint8_t tagType, uint8_t flags, uint8_t *data) { if (SimulateIso14443aInit(tagType, flags, data, &responses, &cuid, counters, tearings, &pages) == false) { BigBuf_free_keep_EM(); - reply_ng(CMD_SIMULATE_MIFARE_CARD, PM3_EINIT, NULL, 0); + reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0); return; } @@ -1269,7 +1269,7 @@ void SimulateIso14443aTag(uint8_t tagType, uint8_t flags, uint8_t *data) { ar_nr_nonces[index].state = SECOND; // send to client (one struct nonces_t) - reply_ng(CMD_SIMULATE_MIFARE_CARD, PM3_SUCCESS, (uint8_t *)&ar_nr_nonces[index], sizeof(nonces_t)); + reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_SUCCESS, (uint8_t *)&ar_nr_nonces[index], sizeof(nonces_t)); ar_nr_nonces[index].state = EMPTY; ar_nr_nonces[index].sector = 0; @@ -1593,7 +1593,7 @@ void SimulateIso14443aTag(uint8_t tagType, uint8_t flags, uint8_t *data) { Dbprintf("-[ Num of moebius tries [%d]", moebius_count); } - reply_ng(CMD_SIMULATE_MIFARE_CARD, retval, NULL, 0); + reply_ng(CMD_HF_MIFARE_SIMULATE, retval, NULL, 0); } // prepare a delayed transfer. This simply shifts ToSend[] by a number @@ -3246,7 +3246,7 @@ void DetectNACKbug(void) { data[0] = isOK; data[1] = num_nacks; num_to_bytes(i, 2, data + 2); - reply_ng(CMD_MIFARE_NACK_DETECT, status, data, 4); + reply_ng(CMD_HF_MIFARE_NACK_DETECT, status, data, 4); //reply_mix(CMD_ACK, isOK, num_nacks, i, 0, 0); BigBuf_free(); diff --git a/armsrc/lfops.c b/armsrc/lfops.c index c84cb19c9..3b00188ea 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -432,7 +432,7 @@ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint // Turn off antenna FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // tell client we are done - reply_ng(CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K, PM3_SUCCESS, NULL, 0); + reply_ng(CMD_LF_MOD_THEN_ACQ_RAW_ADC, PM3_SUCCESS, NULL, 0); } /* blank r/w tag data stream @@ -1012,7 +1012,7 @@ void CmdHIDsimTAGEx(uint32_t hi, uint32_t lo, bool ledcontrol, int numcycles) { void CmdHIDsimTAG(uint32_t hi, uint32_t lo, bool ledcontrol) { CmdHIDsimTAGEx(hi, lo, ledcontrol, -1); - reply_ng(CMD_HID_SIM_TAG, PM3_EOPABORTED, NULL, 0); + reply_ng(CMD_LF_HID_SIMULATE, PM3_EOPABORTED, NULL, 0); } // prepare a waveform pattern in the buffer based on the ID given then @@ -1050,7 +1050,7 @@ void CmdFSKsimTAG(uint8_t fchigh, uint8_t fclow, uint8_t separator, uint8_t clk, if (ledcontrol) LED_A_ON(); SimulateTagLowFrequency(n, 0, ledcontrol); if (ledcontrol) LED_A_OFF(); - reply_ng(CMD_FSK_SIM_TAG, PM3_EOPABORTED, NULL, 0); + reply_ng(CMD_LF_FSK_SIMULATE, PM3_EOPABORTED, NULL, 0); } // compose ask waveform for one bit(ASK) @@ -1139,7 +1139,7 @@ void CmdASKsimTAG(uint8_t encoding, uint8_t invert, uint8_t separator, uint8_t c if (ledcontrol) LED_A_ON(); SimulateTagLowFrequency(n, 0, ledcontrol); if (ledcontrol) LED_A_OFF(); - reply_ng(CMD_ASK_SIM_TAG, PM3_EOPABORTED, NULL, 0); + reply_ng(CMD_LF_ASK_SIMULATE, PM3_EOPABORTED, NULL, 0); } //carrier can be 2,4 or 8 @@ -1186,7 +1186,7 @@ void CmdPSKsimTag(uint8_t carrier, uint8_t invert, uint8_t clk, uint16_t size, u if (ledcontrol) LED_A_ON(); SimulateTagLowFrequency(n, 0, ledcontrol); if (ledcontrol) LED_A_OFF(); - reply_ng(CMD_PSK_SIM_TAG, PM3_EOPABORTED, NULL, 0); + reply_ng(CMD_LF_PSK_SIMULATE, PM3_EOPABORTED, NULL, 0); } // loop to get raw HID waveform then FSK demodulate the TAG ID from it @@ -1803,7 +1803,7 @@ void T55xxWriteBlock(uint8_t *data) { FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // cmd_send(CMD_ACK,0,0,0,0,0); - reply_ng(CMD_T55XX_WRITE_BLOCK, PM3_SUCCESS, NULL, 0); + reply_ng(CMD_LF_T55XX_WRITEBL, PM3_SUCCESS, NULL, 0); LED_A_OFF(); } @@ -1812,7 +1812,7 @@ void T55xxWriteBlock(uint8_t *data) { void T55xxWriteBlock(uint8_t *data) { t55xx_write_block_t *c = (t55xx_write_block_t *)data; T55xxWriteBlockExt(c->data, c->blockno, c->pwd, c->flags); - // reply_ng(CMD_T55XX_WRITE_BLOCK, PM3_SUCCESS, NULL, 0); + // reply_ng(CMD_LF_T55XX_WRITEBL, PM3_SUCCESS, NULL, 0); } */ /* @@ -1864,7 +1864,7 @@ bool brute_mem = (flags & 0x0100) >> 8; // Turn the field off if (!brute_mem) { FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - reply_ng(CMD_T55XX_READ_BLOCK, PM3_SUCCESS, NULL, 0); + reply_ng(CMD_LF_T55XX_READBL, PM3_SUCCESS, NULL, 0); LED_A_OFF(); } } @@ -1924,7 +1924,7 @@ void T55xxReadBlock(uint8_t page, bool pwd_mode, bool brute_mem, uint8_t block, // Turn the field off if (!brute_mem) { FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - reply_ng(CMD_T55XX_READ_BLOCK, PM3_SUCCESS, NULL, 0); + reply_ng(CMD_LF_T55XX_READBL, PM3_SUCCESS, NULL, 0); LED_A_OFF(); } @@ -2412,7 +2412,7 @@ void EM4xReadWord(uint8_t addr, uint32_t pwd, uint8_t usepwd) { DoPartialAcquisition(20, true, 6000, 1000); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - reply_ng(CMD_EM4X_READ_WORD, PM3_SUCCESS, NULL, 0); + reply_ng(CMD_LF_EM4X_READWORD, PM3_SUCCESS, NULL, 0); LED_A_OFF(); } @@ -2445,7 +2445,7 @@ void EM4xWriteWord(uint8_t addr, uint32_t data, uint32_t pwd, uint8_t usepwd) { DoPartialAcquisition(20, true, 6000, 1000); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - reply_ng(CMD_EM4X_WRITE_WORD, PM3_SUCCESS, NULL, 0); + reply_ng(CMD_LF_EM4X_WRITEWORD, PM3_SUCCESS, NULL, 0); LED_A_OFF(); } diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 26ab16e03..3784f8feb 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -94,7 +94,7 @@ void MifareReadBlock(uint8_t blockNo, uint8_t keyType, uint8_t *datain) { if (DBGLEVEL >= 2) DbpString("READ BLOCK FINISHED"); LED_B_ON(); - reply_ng(CMD_MIFARE_READBL, status, dataoutbuf, 16); + reply_ng(CMD_HF_MIFARE_READBL, status, dataoutbuf, 16); LED_B_OFF(); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); @@ -1601,7 +1601,7 @@ void MifareChkKeys(uint8_t *datain) { LED_B_ON(); - reply_ng(CMD_MIFARE_CHKKEYS, PM3_SUCCESS, (uint8_t *)&keyresult, sizeof(keyresult)); + reply_ng(CMD_HF_MIFARE_CHKKEYS, PM3_SUCCESS, (uint8_t *)&keyresult, sizeof(keyresult)); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); @@ -1637,7 +1637,7 @@ void MifareEMemGet(uint8_t blockno, uint8_t blockcnt) { // size_t size = blockcnt * 16; if (size > PM3_CMD_DATA_SIZE) { - reply_ng(CMD_MIFARE_EML_MEMGET, PM3_EMALLOC, NULL, 0); + reply_ng(CMD_HF_MIFARE_EML_MEMGET, PM3_EMALLOC, NULL, 0); return; } @@ -1646,7 +1646,7 @@ void MifareEMemGet(uint8_t blockno, uint8_t blockcnt) { emlGetMem(buf, blockno, blockcnt); // data, block num, blocks count (max 4) LED_B_ON(); - reply_ng(CMD_MIFARE_EML_MEMGET, PM3_SUCCESS, buf, size); + reply_ng(CMD_HF_MIFARE_EML_MEMGET, PM3_SUCCESS, buf, size); LED_B_OFF(); BigBuf_free_keep_EM(); } @@ -1990,7 +1990,7 @@ TEST2: OUT: data[0] = isGen; - reply_ng(CMD_MIFARE_CIDENT, PM3_SUCCESS, data, sizeof(data)); + reply_ng(CMD_HF_MIFARE_CIDENT, PM3_SUCCESS, data, sizeof(data)); // turns off OnSuccessMagic(); BigBuf_free(); @@ -2059,7 +2059,7 @@ void MifareSetMod(uint8_t *datain) { crypto1_destroy(pcs); LED_B_ON(); - reply_ng(CMD_MIFARE_SETMOD, isOK, NULL, 0); + reply_ng(CMD_HF_MIFARE_SETMOD, isOK, NULL, 0); LED_B_OFF(); diff --git a/armsrc/mifaresim.c b/armsrc/mifaresim.c index 0e64f00d1..2e8203aa5 100644 --- a/armsrc/mifaresim.c +++ b/armsrc/mifaresim.c @@ -1221,7 +1221,7 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain) { if ((flags & FLAG_INTERACTIVE) == FLAG_INTERACTIVE) { // Interactive mode flag, means we need to send ACK //Send the collected ar_nr in the response - reply_old(CMD_ACK, CMD_SIMULATE_MIFARE_CARD, button_pushed, 0, &ar_nr_resp, sizeof(ar_nr_resp)); + reply_old(CMD_ACK, CMD_HF_MIFARE_SIMULATE, button_pushed, 0, &ar_nr_resp, sizeof(ar_nr_resp)); } FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); diff --git a/armsrc/thinfilm.c b/armsrc/thinfilm.c index f8cf2b0da..93d46e8a1 100644 --- a/armsrc/thinfilm.c +++ b/armsrc/thinfilm.c @@ -30,7 +30,7 @@ void ReadThinFilm(void) { // power on and listen for answer. bool status = GetIso14443aAnswerFromTag_Thinfilm(buf, &len); - reply_ng(CMD_THINFILM_READ, status ? PM3_SUCCESS : PM3_ENODATA, buf, len); + reply_ng(CMD_HF_THINFILM_READ, status ? PM3_SUCCESS : PM3_ENODATA, buf, len); iso14443a_off(); set_tracing(false); @@ -148,5 +148,5 @@ void SimulateThinFilm(uint8_t *data, size_t len) { } } LED_A_OFF(); - reply_ng(CMD_SIMULATE_TAG_THINFILM, status, NULL, 0); + reply_ng(CMD_HF_THINFILM_SIMULATE, status, NULL, 0); } diff --git a/client/cmdhf.c b/client/cmdhf.c index a766388c9..2ef54773d 100644 --- a/client/cmdhf.c +++ b/client/cmdhf.c @@ -146,7 +146,7 @@ int CmdHFSniff(const char *Cmd) { int skiptriggers = param_get32ex(Cmd, 1, 0, 10); clearCommandBuffer(); - SendCommandMIX(CMD_HF_SNIFFER, skippairs, skiptriggers, 0, NULL, 0); + SendCommandMIX(CMD_HF_SNIFF, skippairs, skiptriggers, 0, NULL, 0); return 0; } diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index d46e9ba07..3fbf022fd 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -227,7 +227,7 @@ static int CmdHF14AList(const char *Cmd) { } int Hf14443_4aGetCardData(iso14a_card_select_t *card) { - SendCommandMIX(CMD_READER_ISO_14443a, ISO14A_CONNECT, 0, 0, NULL, 0); + SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT, 0, 0, NULL, 0); PacketResponseNG resp; WaitForResponse(CMD_ACK, &resp); @@ -297,7 +297,7 @@ static int CmdHF14AReader(const char *Cmd) { cm |= ISO14A_NO_DISCONNECT; clearCommandBuffer(); - SendCommandMIX(CMD_READER_ISO_14443a, cm, 0, 0, NULL, 0); + SendCommandMIX(CMD_HF_ISO14443A_READER, cm, 0, 0, NULL, 0); if (ISO14A_CONNECT & cm) { PacketResponseNG resp; @@ -380,7 +380,7 @@ static int CmdHF14ACUIDs(const char *Cmd) { } // execute anticollision procedure - SendCommandMIX(CMD_READER_ISO_14443a, ISO14A_CONNECT | ISO14A_NO_RATS, 0, 0, NULL, 0); + SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT | ISO14A_NO_RATS, 0, 0, NULL, 0); PacketResponseNG resp; WaitForResponse(CMD_ACK, &resp); @@ -481,13 +481,13 @@ int CmdHF14ASim(const char *Cmd) { memcpy(payload.uid, uid, uidlen); clearCommandBuffer(); - SendCommandNG(CMD_SIMULATE_TAG_ISO_14443a, (uint8_t *)&payload, sizeof(payload)); + SendCommandNG(CMD_HF_ISO14443A_SIMULATE, (uint8_t *)&payload, sizeof(payload)); PacketResponseNG resp; PrintAndLogEx(SUCCESS, "press pm3-button to abort simulation"); while (!kbd_enter_pressed()) { - if (WaitForResponseTimeout(CMD_SIMULATE_MIFARE_CARD, &resp, 1500) == 0) continue; + if (WaitForResponseTimeout(CMD_HF_MIFARE_SIMULATE, &resp, 1500) == 0) continue; if (resp.status != PM3_SUCCESS) break; if ((flags & FLAG_NR_AR_ATTACK) != FLAG_NR_AR_ATTACK) break; @@ -511,7 +511,7 @@ int CmdHF14ASniff(const char *Cmd) { if (ctmp == 'r') param |= 0x02; } clearCommandBuffer(); - SendCommandNG(CMD_SNIFF_ISO_14443a, (uint8_t *)¶m, sizeof(uint8_t)); + SendCommandNG(CMD_HF_ISO14443A_SNIFF, (uint8_t *)¶m, sizeof(uint8_t)); return PM3_SUCCESS; } @@ -525,7 +525,7 @@ int ExchangeRAW14a(uint8_t *datain, int datainlen, bool activateField, bool leav PacketResponseNG resp; // Anticollision + SELECT card - SendCommandMIX(CMD_READER_ISO_14443a, ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0, NULL, 0); + SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0, NULL, 0); if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { PrintAndLogEx(ERR, "Proxmark3 connection timeout."); return 1; @@ -545,7 +545,7 @@ int ExchangeRAW14a(uint8_t *datain, int datainlen, bool activateField, bool leav if (resp.oldarg[0] == 2) { // 0: couldn't read, 1: OK, with ATS, 2: OK, no ATS, 3: proprietary Anticollision // get ATS uint8_t rats[] = { 0xE0, 0x80 }; // FSDI=8 (FSD=256), CID=0 - SendCommandOLD(CMD_READER_ISO_14443a, ISO14A_RAW | ISO14A_APPEND_CRC | ISO14A_NO_DISCONNECT, 2, 0, rats, 2); + SendCommandOLD(CMD_HF_ISO14443A_READER, ISO14A_RAW | ISO14A_APPEND_CRC | ISO14A_NO_DISCONNECT, 2, 0, rats, 2); if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { PrintAndLogEx(ERR, "Proxmark3 connection timeout."); return 1; @@ -564,7 +564,7 @@ int ExchangeRAW14a(uint8_t *datain, int datainlen, bool activateField, bool leav uint8_t data[PM3_CMD_DATA_SIZE] = { 0x0a | responseNum, 0x00}; responseNum ^= 1; memcpy(&data[2], datain, datainlen & 0xFFFF); - SendCommandOLD(CMD_READER_ISO_14443a, ISO14A_RAW | ISO14A_APPEND_CRC | cmdc, (datainlen & 0xFFFF) + 2, 0, data, (datainlen & 0xFFFF) + 2); + SendCommandOLD(CMD_HF_ISO14443A_READER, ISO14A_RAW | ISO14A_APPEND_CRC | cmdc, (datainlen & 0xFFFF) + 2, 0, data, (datainlen & 0xFFFF) + 2); uint8_t *recv; PacketResponseNG resp; @@ -619,7 +619,7 @@ static int SelectCard14443_4(bool disconnect, iso14a_card_select_t *card) { DropField(); // Anticollision + SELECT card - SendCommandMIX(CMD_READER_ISO_14443a, ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0, NULL, 0); + SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0, NULL, 0); if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { PrintAndLogEx(ERR, "Proxmark3 connection timeout."); return 1; @@ -639,7 +639,7 @@ static int SelectCard14443_4(bool disconnect, iso14a_card_select_t *card) { if (resp.oldarg[0] == 2) { // 0: couldn't read, 1: OK, with ATS, 2: OK, no ATS, 3: proprietary Anticollision // get ATS uint8_t rats[] = { 0xE0, 0x80 }; // FSDI=8 (FSD=256), CID=0 - SendCommandOLD(CMD_READER_ISO_14443a, ISO14A_RAW | ISO14A_APPEND_CRC | ISO14A_NO_DISCONNECT, sizeof(rats), 0, rats, sizeof(rats)); + SendCommandOLD(CMD_HF_ISO14443A_READER, ISO14A_RAW | ISO14A_APPEND_CRC | ISO14A_NO_DISCONNECT, sizeof(rats), 0, rats, sizeof(rats)); if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { PrintAndLogEx(ERR, "Proxmark3 connection timeout."); return 1; @@ -694,9 +694,9 @@ static int CmdExchangeAPDU(bool chainingin, uint8_t *datain, int datainlen, bool // here length PM3_CMD_DATA_SIZE=512 // timeout must be authomatically set by "get ATS" if (datain) - SendCommandOLD(CMD_READER_ISO_14443a, ISO14A_APDU | ISO14A_NO_DISCONNECT | cmdc, (datainlen & 0xFFFF), 0, datain, datainlen & 0xFFFF); + SendCommandOLD(CMD_HF_ISO14443A_READER, ISO14A_APDU | ISO14A_NO_DISCONNECT | cmdc, (datainlen & 0xFFFF), 0, datain, datainlen & 0xFFFF); else - SendCommandMIX(CMD_READER_ISO_14443a, ISO14A_APDU | ISO14A_NO_DISCONNECT | cmdc, 0, 0, NULL, 0); + SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_APDU | ISO14A_NO_DISCONNECT | cmdc, 0, 0, NULL, 0); PacketResponseNG resp; @@ -1086,7 +1086,7 @@ static int CmdHF14ACmdRaw(const char *Cmd) { datalen = (datalen > PM3_CMD_DATA_SIZE) ? PM3_CMD_DATA_SIZE : datalen; clearCommandBuffer(); - SendCommandOLD(CMD_READER_ISO_14443a, flags, (datalen & 0xFFFF) | ((uint32_t)(numbits << 16)), argtimeout, data, datalen & 0xFFFF); + SendCommandOLD(CMD_HF_ISO14443A_READER, flags, (datalen & 0xFFFF) | ((uint32_t)(numbits << 16)), argtimeout, data, datalen & 0xFFFF); if (reply) { int res = 0; @@ -1149,7 +1149,7 @@ static int CmdHF14AAntiFuzz(const char *Cmd) { CLIParserFree(); clearCommandBuffer(); - SendCommandMIX(CMD_ANTIFUZZ_ISO_14443a, arg0, 0, 0, NULL, 0); + SendCommandMIX(CMD_HF_ISO14443A_ANTIFUZZ, arg0, 0, 0, NULL, 0); return 0; } @@ -1212,7 +1212,7 @@ int CmdHF14A(const char *Cmd) { int infoHF14A(bool verbose, bool do_nack_test) { clearCommandBuffer(); - SendCommandMIX(CMD_READER_ISO_14443a, ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0, NULL, 0); + SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0, NULL, 0); PacketResponseNG resp; if (!WaitForResponseTimeout(CMD_ACK, &resp, 2500)) { if (verbose) PrintAndLogEx(WARNING, "iso14443a card select failed"); @@ -1264,7 +1264,7 @@ int infoHF14A(bool verbose, bool do_nack_test) { // reconnect for further tests clearCommandBuffer(); - SendCommandMIX(CMD_READER_ISO_14443a, ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0, NULL, 0); + SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0, NULL, 0); WaitForResponse(CMD_ACK, &resp); memcpy(&card, (iso14a_card_select_t *)resp.data.asBytes, sizeof(iso14a_card_select_t)); @@ -1334,7 +1334,7 @@ int infoHF14A(bool verbose, bool do_nack_test) { if (select_status == 2) { uint8_t rats[] = { 0xE0, 0x80 }; // FSDI=8 (FSD=256), CID=0 clearCommandBuffer(); - SendCommandOLD(CMD_READER_ISO_14443a, ISO14A_RAW | ISO14A_APPEND_CRC | ISO14A_NO_DISCONNECT, 2, 0, rats, sizeof(rats)); + SendCommandOLD(CMD_HF_ISO14443A_READER, ISO14A_RAW | ISO14A_APPEND_CRC | ISO14A_NO_DISCONNECT, 2, 0, rats, sizeof(rats)); WaitForResponse(CMD_ACK, &resp); memcpy(card.ats, resp.data.asBytes, resp.oldarg[0]); diff --git a/client/cmdhf14b.c b/client/cmdhf14b.c index c95494b7a..b02fe4d2f 100644 --- a/client/cmdhf14b.c +++ b/client/cmdhf14b.c @@ -109,13 +109,13 @@ static int usage_hf_14b_dump(void) { /* static void switch_on_field_14b(void) { clearCommandBuffer(); - SendCommandMIX(CMD_ISO_14443B_COMMAND, ISO14B_CONNECT, 0, 0, NULL, 0); + SendCommandMIX(CMD_HF_ISO14443B_COMMAND, ISO14B_CONNECT, 0, 0, NULL, 0); } */ static int switch_off_field_14b(void) { clearCommandBuffer(); - SendCommandMIX(CMD_ISO_14443B_COMMAND, ISO14B_DISCONNECT, 0, 0, NULL, 0); + SendCommandMIX(CMD_HF_ISO14443B_COMMAND, ISO14B_DISCONNECT, 0, 0, NULL, 0); return 0; } @@ -170,7 +170,7 @@ static int CmdHF14BSim(const char *Cmd) { } clearCommandBuffer(); - SendCommandMIX(CMD_SIMULATE_TAG_ISO_14443B, pupi, 0, 0, NULL, 0); + SendCommandMIX(CMD_HF_ISO14443B_SIMULATE, pupi, 0, 0, NULL, 0); return 0; } @@ -180,7 +180,7 @@ static int CmdHF14BSniff(const char *Cmd) { if (cmdp == 'h') return usage_hf_14b_sniff(); clearCommandBuffer(); - SendCommandNG(CMD_SNIFF_ISO_14443B, NULL, 0); + SendCommandNG(CMD_HF_ISO14443B_SNIFF, NULL, 0); return 0; } @@ -274,7 +274,7 @@ static int CmdHF14BCmdRaw(const char *Cmd) { datalen = (datalen > PM3_CMD_DATA_SIZE) ? PM3_CMD_DATA_SIZE : datalen; clearCommandBuffer(); - SendCommandOLD(CMD_ISO_14443B_COMMAND, flags, datalen, time_wait, data, datalen); + SendCommandOLD(CMD_HF_ISO14443B_COMMAND, flags, datalen, time_wait, data, datalen); if (!reply) return 1; @@ -301,7 +301,7 @@ static bool get_14b_UID(iso14b_card_select_t *card) { while (retry--) { clearCommandBuffer(); - SendCommandMIX(CMD_ISO_14443B_COMMAND, ISO14B_CONNECT | ISO14B_SELECT_SR | ISO14B_DISCONNECT, 0, 0, NULL, 0); + SendCommandMIX(CMD_HF_ISO14443B_COMMAND, ISO14B_CONNECT | ISO14B_SELECT_SR | ISO14B_DISCONNECT, 0, 0, NULL, 0); if (WaitForResponseTimeout(CMD_ACK, &resp, TIMEOUT)) { uint8_t status = resp.oldarg[0]; @@ -317,7 +317,7 @@ static bool get_14b_UID(iso14b_card_select_t *card) { while (retry--) { clearCommandBuffer(); - SendCommandMIX(CMD_ISO_14443B_COMMAND, ISO14B_CONNECT | ISO14B_SELECT_STD | ISO14B_DISCONNECT, 0, 0, NULL, 0); + SendCommandMIX(CMD_HF_ISO14443B_COMMAND, ISO14B_CONNECT | ISO14B_SELECT_STD | ISO14B_DISCONNECT, 0, 0, NULL, 0); if (WaitForResponseTimeout(CMD_ACK, &resp, TIMEOUT)) { uint8_t status = resp.oldarg[0]; @@ -501,7 +501,7 @@ static bool HF14B_Std_Info(bool verbose) { // 14b get and print UID only (general info) clearCommandBuffer(); - SendCommandMIX(CMD_ISO_14443B_COMMAND, ISO14B_CONNECT | ISO14B_SELECT_STD | ISO14B_DISCONNECT, 0, 0, NULL, 0); + SendCommandMIX(CMD_HF_ISO14443B_COMMAND, ISO14B_CONNECT | ISO14B_SELECT_STD | ISO14B_DISCONNECT, 0, 0, NULL, 0); PacketResponseNG resp; if (!WaitForResponseTimeout(CMD_ACK, &resp, TIMEOUT)) { @@ -541,7 +541,7 @@ static bool HF14B_Std_Info(bool verbose) { static bool HF14B_ST_Info(bool verbose) { clearCommandBuffer(); - SendCommandMIX(CMD_ISO_14443B_COMMAND, ISO14B_CONNECT | ISO14B_SELECT_SR | ISO14B_DISCONNECT, 0, 0, NULL, 0); + SendCommandMIX(CMD_HF_ISO14443B_COMMAND, ISO14B_CONNECT | ISO14B_SELECT_SR | ISO14B_DISCONNECT, 0, 0, NULL, 0); PacketResponseNG resp; if (!WaitForResponseTimeout(CMD_ACK, &resp, TIMEOUT)) { @@ -597,7 +597,7 @@ static bool HF14B_ST_Reader(bool verbose) { // SRx get and print general info about SRx chip from UID clearCommandBuffer(); - SendCommandMIX(CMD_ISO_14443B_COMMAND, ISO14B_CONNECT | ISO14B_SELECT_SR | ISO14B_DISCONNECT, 0, 0, NULL, 0); + SendCommandMIX(CMD_HF_ISO14443B_COMMAND, ISO14B_CONNECT | ISO14B_SELECT_SR | ISO14B_DISCONNECT, 0, 0, NULL, 0); PacketResponseNG resp; if (!WaitForResponseTimeout(CMD_ACK, &resp, TIMEOUT)) { if (verbose) PrintAndLogEx(WARNING, "command execution timeout"); @@ -636,7 +636,7 @@ static bool HF14B_Std_Reader(bool verbose) { // 14b get and print UID only (general info) clearCommandBuffer(); - SendCommandMIX(CMD_ISO_14443B_COMMAND, ISO14B_CONNECT | ISO14B_SELECT_STD | ISO14B_DISCONNECT, 0, 0, NULL, 0); + SendCommandMIX(CMD_HF_ISO14443B_COMMAND, ISO14B_CONNECT | ISO14B_SELECT_STD | ISO14B_DISCONNECT, 0, 0, NULL, 0); PacketResponseNG resp; if (!WaitForResponseTimeout(CMD_ACK, &resp, TIMEOUT)) { @@ -680,7 +680,7 @@ static bool HF14B_Other_Reader() { // uint32_t flags = ISO14B_CONNECT | ISO14B_SELECT_STD | ISO14B_RAW | ISO14B_APPEND_CRC; // clearCommandBuffer(); - // SendCommandOLD(CMD_ISO_14443B_COMMAND, flags, datalen, 0, data, datalen); + // SendCommandOLD(CMD_HF_ISO14443B_COMMAND, flags, datalen, 0, data, datalen); // PacketResponseNG resp; // WaitForResponse(CMD_ACK,&resp); @@ -694,7 +694,7 @@ static bool HF14B_Other_Reader() { // data[0] = ISO14443B_AUTHENTICATE; // clearCommandBuffer(); - // SendCommandOLD(CMD_ISO_14443B_COMMAND, flags, 1, 0, data, 1); + // SendCommandOLD(CMD_HF_ISO14443B_COMMAND, flags, 1, 0, data, 1); // PacketResponseNG resp; // WaitForResponse(CMD_ACK, &resp); @@ -708,7 +708,7 @@ static bool HF14B_Other_Reader() { // data[0] = ISO14443B_RESET; // clearCommandBuffer(); - // SendCommandOLD(CMD_ISO_14443B_COMMAND, flags, 1, 0, data, 1); + // SendCommandOLD(CMD_HF_ISO14443B_COMMAND, flags, 1, 0, data, 1); // PacketResponseNG resp; // WaitForResponse(CMD_ACK, &resp); @@ -745,7 +745,7 @@ static int CmdHF14BReadSri(const char *Cmd) { uint8_t blocks = (tagtype == 1) ? 0x7F : 0x0F; clearCommandBuffer(); - SendCommandMIX(CMD_READ_SRI_TAG, blocks, 0, 0, NULL, 0); + SendCommandMIX(CMD_HF_SRI_READ, blocks, 0, 0, NULL, 0); return 0; } // New command to write a SRI512/SRIX4K tag. @@ -884,7 +884,7 @@ static int CmdHF14BDump(const char *Cmd) { PacketResponseNG resp; clearCommandBuffer(); - SendCommandMIX(CMD_ISO_14443B_COMMAND, ISO14B_CONNECT | ISO14B_SELECT_SR, 0, 0, NULL, 0); + SendCommandMIX(CMD_HF_ISO14443B_COMMAND, ISO14B_CONNECT | ISO14B_SELECT_SR, 0, 0, NULL, 0); //select if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { @@ -901,7 +901,7 @@ static int CmdHF14BDump(const char *Cmd) { req[1] = blocknum; clearCommandBuffer(); - SendCommandOLD(CMD_ISO_14443B_COMMAND, ISO14B_APPEND_CRC | ISO14B_RAW, 2, 0, req, sizeof(req)); + SendCommandOLD(CMD_HF_ISO14443B_COMMAND, ISO14B_APPEND_CRC | ISO14B_RAW, 2, 0, req, sizeof(req)); if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { diff --git a/client/cmdhf15.c b/client/cmdhf15.c index 33c3957fe..f43b6d85c 100644 --- a/client/cmdhf15.c +++ b/client/cmdhf15.c @@ -212,7 +212,7 @@ static int getUID(uint8_t *buf) { for (retry = 0; retry < 3; retry++) { clearCommandBuffer(); - SendCommandOLD(CMD_ISO_15693_COMMAND, sizeof(data), 1, 1, data, sizeof(data)); + SendCommandOLD(CMD_HF_ISO15693_COMMAND, sizeof(data), 1, 1, data, sizeof(data)); if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { @@ -583,7 +583,7 @@ static int CmdHF15Samples(const char *Cmd) { if (cmdp == 'h') return usage_15_samples(); clearCommandBuffer(); - SendCommandNG(CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693, NULL, 0); + SendCommandNG(CMD_HF_ISO15693_ACQ_RAW_ADC, NULL, 0); getSamples(0, false); return 0; @@ -617,7 +617,7 @@ static int CmdHF15Info(const char *Cmd) { //PrintAndLogEx(NORMAL, "cmd %s", sprint_hex(req, reqlen) ); clearCommandBuffer(); - SendCommandOLD(CMD_ISO_15693_COMMAND, reqlen, arg1, 1, req, reqlen); + SendCommandOLD(CMD_HF_ISO15693_COMMAND, reqlen, arg1, 1, req, reqlen); if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { PrintAndLogEx(WARNING, "iso15693 card select failed"); @@ -680,7 +680,7 @@ static int CmdHF15Record(const char *Cmd) { if (cmdp == 'h') return usage_15_record(); clearCommandBuffer(); - SendCommandNG(CMD_RECORD_RAW_ADC_SAMPLES_ISO_15693, NULL, 0); + SendCommandNG(CMD_HF_ISO15693_RAWADC, NULL, 0); return 0; } @@ -707,7 +707,7 @@ static int CmdHF15Sim(const char *Cmd) { PrintAndLogEx(SUCCESS, "Starting simulating UID %s", sprint_hex(uid, sizeof(uid))); clearCommandBuffer(); - SendCommandOLD(CMD_SIMTAG_ISO_15693, 0, 0, 0, uid, 8); + SendCommandOLD(CMD_HF_ISO15693_SIMULATE, 0, 0, 0, uid, 8); return 0; } @@ -721,7 +721,7 @@ static int CmdHF15Afi(const char *Cmd) { PrintAndLogEx(SUCCESS, "press pm3-button to cancel"); clearCommandBuffer(); - SendCommandMIX(CMD_ISO_15693_FIND_AFI, strtol(Cmd, NULL, 0), 0, 0, NULL, 0); + SendCommandMIX(CMD_HF_ISO15693_FINDAFI, strtol(Cmd, NULL, 0), 0, 0, NULL, 0); return 0; } @@ -798,7 +798,7 @@ static int CmdHF15Dump(const char *Cmd) { AddCrc15(req, 11); clearCommandBuffer(); - SendCommandOLD(CMD_ISO_15693_COMMAND, sizeof(req), 1, 1, req, sizeof(req)); + SendCommandOLD(CMD_HF_ISO15693_COMMAND, sizeof(req), 1, 1, req, sizeof(req)); if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { @@ -915,7 +915,7 @@ static int CmdHF15Raw(const char *Cmd) { } clearCommandBuffer(); - SendCommandOLD(CMD_ISO_15693_COMMAND, datalen, fast, reply, data, datalen); + SendCommandOLD(CMD_HF_ISO15693_COMMAND, datalen, fast, reply, data, datalen); if (reply) { if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { @@ -970,7 +970,7 @@ static int CmdHF15Readmulti(const char *Cmd) { reqlen += 2; clearCommandBuffer(); - SendCommandOLD(CMD_ISO_15693_COMMAND, reqlen, arg1, 1, req, reqlen); + SendCommandOLD(CMD_HF_ISO15693_COMMAND, reqlen, arg1, 1, req, reqlen); if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { PrintAndLogEx(FAILED, "iso15693 card select failed"); @@ -1048,7 +1048,7 @@ static int CmdHF15Read(const char *Cmd) { reqlen += 2; clearCommandBuffer(); - SendCommandOLD(CMD_ISO_15693_COMMAND, reqlen, arg1, 1, req, reqlen); + SendCommandOLD(CMD_HF_ISO15693_COMMAND, reqlen, arg1, 1, req, reqlen); if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { PrintAndLogEx(NORMAL, "iso15693 card select failed"); @@ -1131,7 +1131,7 @@ static int CmdHF15Write(const char *Cmd) { PrintAndLogEx(NORMAL, "iso15693 writing to page %02d (0x%02X) | data ", pagenum, pagenum); clearCommandBuffer(); - SendCommandOLD(CMD_ISO_15693_COMMAND, reqlen, arg1, 1, req, reqlen); + SendCommandOLD(CMD_HF_ISO15693_COMMAND, reqlen, arg1, 1, req, reqlen); if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { PrintAndLogEx(FAILED, "iso15693 card timeout, data may be written anyway"); @@ -1352,7 +1352,7 @@ static int CmdHF15CSetUID(const char *Cmd) { AddCrc15(data[i], 7); clearCommandBuffer(); - SendCommandOLD(CMD_ISO_15693_COMMAND, sizeof(data[i]), fast, reply, data[i], sizeof(data[i])); + SendCommandOLD(CMD_HF_ISO15693_COMMAND, sizeof(data[i]), fast, reply, data[i], sizeof(data[i])); if (reply) { if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { diff --git a/client/cmdhfepa.c b/client/cmdhfepa.c index a2a120764..3370c05c9 100644 --- a/client/cmdhfepa.c +++ b/client/cmdhfepa.c @@ -32,7 +32,7 @@ static int CmdHFEPACollectPACENonces(const char *Cmd) { for (uint32_t i = 0; i < n; i++) { // execute PACE clearCommandBuffer(); - SendCommandMIX(CMD_EPA_PACE_COLLECT_NONCE, (int)m, 0, 0, NULL, 0); + SendCommandMIX(CMD_HF_EPA_COLLECT_NONCE, (int)m, 0, 0, NULL, 0); PacketResponseNG resp; WaitForResponse(CMD_ACK, &resp); @@ -130,7 +130,7 @@ static int CmdHFEPAPACEReplay(const char *Cmd) { clearCommandBuffer(); // arg0: APDU number // arg1: offset into the APDU - SendCommandOLD(CMD_EPA_PACE_REPLAY, i + 1, j * sizeof(data), packet_length, data, packet_length); + SendCommandOLD(CMD_HF_EPA_REPLAY, i + 1, j * sizeof(data), packet_length, data, packet_length); WaitForResponse(CMD_ACK, &resp); if (resp.oldarg[0] != 0) { PrintAndLogEx(WARNING, "Transfer of APDU #%d Part %d failed!", i, j); @@ -141,7 +141,7 @@ static int CmdHFEPAPACEReplay(const char *Cmd) { // now perform the replay clearCommandBuffer(); - SendCommandMIX(CMD_EPA_PACE_REPLAY, 0, 0, 0, NULL, 0); + SendCommandMIX(CMD_HF_EPA_REPLAY, 0, 0, 0, NULL, 0); WaitForResponse(CMD_ACK, &resp); if (resp.oldarg[0] != 0) { PrintAndLogEx(NORMAL, "\nPACE replay failed in step %u!", (uint32_t)resp.oldarg[0]); diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index 5a6f1d33a..1e97dd8b6 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -129,7 +129,7 @@ static int CmdHFFelicaSim(const char *Cmd) { if (errors || cmdp == 0) return usage_hf_felica_sim(); clearCommandBuffer(); - SendCommandOLD(CMD_FELICA_SIMULATE_TAG, tagtype, flags, 0, uid, uidlen >> 1); + SendCommandOLD(CMD_HF_FELICA_SIMULATE, tagtype, flags, 0, uid, uidlen >> 1); PacketResponseNG resp; if (verbose) @@ -173,7 +173,7 @@ static int CmdHFFelicaSniff(const char *Cmd) { if (errors || cmdp == 0) return usage_hf_felica_sniff(); clearCommandBuffer(); - SendCommandMIX(CMD_FELICA_SNIFF, samples2skip, triggers2skip, 0, NULL, 0); + SendCommandMIX(CMD_HF_FELICA_SNIFF, samples2skip, triggers2skip, 0, NULL, 0); return 0; } @@ -186,7 +186,7 @@ static int CmdHFFelicaSimLite(const char *Cmd) { return usage_hf_felica_simlite(); clearCommandBuffer(); - SendCommandMIX(CMD_FELICA_LITE_SIM, uid, 0, 0, NULL, 0); + SendCommandMIX(CMD_HF_FELICALITE_SIMULATE, uid, 0, 0, NULL, 0); return 0; } @@ -349,7 +349,7 @@ static int CmdHFFelicaDumpLite(const char *Cmd) { PrintAndLogEx(SUCCESS, "FeliCa lite - dump started"); PrintAndLogEx(SUCCESS, "press pm3-button to cancel"); clearCommandBuffer(); - SendCommandNG(CMD_FELICA_LITE_DUMP, NULL, 0); + SendCommandNG(CMD_HF_FELICALITE_DUMP, NULL, 0); PacketResponseNG resp; uint8_t timeout = 0; @@ -520,7 +520,7 @@ static int CmdHFFelicaCmdRaw(const char *Cmd) { datalen = (datalen > PM3_CMD_DATA_SIZE) ? PM3_CMD_DATA_SIZE : datalen; clearCommandBuffer(); - SendCommandOLD(CMD_FELICA_COMMAND, flags, (datalen & 0xFFFF) | (uint32_t)(numbits << 16), 0, data, datalen); + SendCommandOLD(CMD_HF_FELICA_COMMAND, flags, (datalen & 0xFFFF) | (uint32_t)(numbits << 16), 0, data, datalen); if (reply) { if (active_select) @@ -558,11 +558,11 @@ int CmdHFFelica(const char *Cmd) { int readFelicaUid(bool verbose) { clearCommandBuffer(); - SendCommandMIX(CMD_FELICA_COMMAND, FELICA_CONNECT, 0, 0, NULL, 0); + SendCommandMIX(CMD_HF_FELICA_COMMAND, FELICA_CONNECT, 0, 0, NULL, 0); PacketResponseNG resp; if (!WaitForResponseTimeout(CMD_ACK, &resp, 2500)) { if (verbose) PrintAndLogEx(WARNING, "FeliCa card select failed"); - //SendCommandMIX(CMD_FELICA_COMMAND, 0, 0, 0, NULL, 0); + //SendCommandMIX(CMD_HF_FELICA_COMMAND, 0, 0, 0, NULL, 0); return 0; } diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 17fd9f127..d87d26b67 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -281,7 +281,7 @@ static int CmdHFiClassList(const char *Cmd) { static int CmdHFiClassSniff(const char *Cmd) { char cmdp = tolower(param_getchar(Cmd, 0)); if (cmdp == 'h') return usage_hf_iclass_sniff(); - SendCommandNG(CMD_SNIFF_ICLASS, NULL, 0); + SendCommandNG(CMD_HF_ICLASS_SNIFF, NULL, 0); return PM3_SUCCESS; } @@ -379,7 +379,7 @@ static int CmdHFiClassSim(const char *Cmd) { PrintAndLogEx(INFO, "press Enter to cancel"); PacketResponseNG resp; clearCommandBuffer(); - SendCommandOLD(CMD_SIMULATE_TAG_ICLASS, simType, NUM_CSNS, 0, csns, 8 * NUM_CSNS); + SendCommandOLD(CMD_HF_ICLASS_SIMULATE, simType, NUM_CSNS, 0, csns, 8 * NUM_CSNS); while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { tries++; @@ -428,7 +428,7 @@ static int CmdHFiClassSim(const char *Cmd) { PrintAndLogEx(INFO, "press Enter to cancel"); PacketResponseNG resp; clearCommandBuffer(); - SendCommandOLD(CMD_SIMULATE_TAG_ICLASS, simType, NUM_CSNS, 0, csns, 8 * NUM_CSNS); + SendCommandOLD(CMD_HF_ICLASS_SIMULATE, simType, NUM_CSNS, 0, csns, 8 * NUM_CSNS); while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { tries++; @@ -491,7 +491,7 @@ static int CmdHFiClassSim(const char *Cmd) { default: { uint8_t numberOfCSNs = 0; clearCommandBuffer(); - SendCommandOLD(CMD_SIMULATE_TAG_ICLASS, simType, numberOfCSNs, 0, CSN, 8); + SendCommandOLD(CMD_HF_ICLASS_SIMULATE, simType, numberOfCSNs, 0, CSN, 8); break; } } @@ -519,7 +519,7 @@ static int CmdHFiClassReader_Replay(const char *Cmd) { } clearCommandBuffer(); - SendCommandMIX(CMD_READER_ICLASS_REPLAY, readerType, 0, 0, MAC, 4); + SendCommandMIX(CMD_HF_ICLASS_REPLAY, readerType, 0, 0, MAC, 4); return PM3_SUCCESS; } @@ -588,7 +588,7 @@ static int CmdHFiClassELoad(const char *Cmd) { conn.block_after_ACK = false; } clearCommandBuffer(); - SendCommandOLD(CMD_ICLASS_EML_MEMSET, bytes_sent, bytes_in_packet, 0, dump + bytes_sent, bytes_in_packet); + SendCommandOLD(CMD_HF_ICLASS_EML_MEMSET, bytes_sent, bytes_in_packet, 0, dump + bytes_sent, bytes_in_packet); bytes_remaining -= bytes_in_packet; bytes_sent += bytes_in_packet; } @@ -757,7 +757,7 @@ static bool select_only(uint8_t *CSN, uint8_t *CCNR, bool use_credit_key, bool v flags |= FLAG_ICLASS_READER_CEDITKEY; clearCommandBuffer(); - SendCommandMIX(CMD_READER_ICLASS, flags, 0, 0, NULL, 0); + SendCommandMIX(CMD_HF_ICLASS_READER, flags, 0, 0, NULL, 0); if (!WaitForResponseTimeout(CMD_ACK, &resp, 4000)) { PrintAndLogEx(WARNING, "command execute timeout"); return false; @@ -802,7 +802,7 @@ static bool select_and_auth(uint8_t *KEY, uint8_t *MAC, uint8_t *div_key, bool u doMAC(CCNR, div_key, MAC); PacketResponseNG resp; clearCommandBuffer(); - SendCommandOLD(CMD_ICLASS_AUTHENTICATION, 0, 0, 0, MAC, 4); + SendCommandOLD(CMD_HF_ICLASS_AUTH, 0, 0, 0, MAC, 4); if (!WaitForResponseTimeout(CMD_ACK, &resp, 4000)) { if (verbose) PrintAndLogEx(FAILED, "auth command execute timeout"); return false; @@ -923,7 +923,7 @@ static int CmdHFiClassReader_Dump(const char *Cmd) { uint8_t tag_data[255 * 8]; clearCommandBuffer(); - SendCommandMIX(CMD_READER_ICLASS, flags, 0, 0, NULL, 0); + SendCommandMIX(CMD_HF_ICLASS_READER, flags, 0, 0, NULL, 0); if (!WaitForResponseTimeout(CMD_ACK, &resp, 4500)) { PrintAndLogEx(WARNING, "command execute timeout"); DropField(); @@ -961,7 +961,7 @@ static int CmdHFiClassReader_Dump(const char *Cmd) { // begin dump clearCommandBuffer(); - SendCommandMIX(CMD_ICLASS_DUMP, blockno, numblks - blockno + 1, 0, NULL, 0); + SendCommandMIX(CMD_HF_ICLASS_DUMP, blockno, numblks - blockno + 1, 0, NULL, 0); while (true) { printf("."); fflush(stdout); @@ -1015,7 +1015,7 @@ static int CmdHFiClassReader_Dump(const char *Cmd) { if (maxBlk > blockno + numblks + 1) { // setup dump and start clearCommandBuffer(); - SendCommandMIX(CMD_ICLASS_DUMP, blockno + blocksRead, maxBlk - (blockno + blocksRead), 0, NULL, 0); + SendCommandMIX(CMD_HF_ICLASS_DUMP, blockno + blocksRead, maxBlk - (blockno + blocksRead), 0, NULL, 0); if (!WaitForResponseTimeout(CMD_ACK, &resp, 4500)) { PrintAndLogEx(WARNING, "command execute timeout 2"); return 0; @@ -1079,7 +1079,7 @@ static int WriteBlock(uint8_t blockno, uint8_t *bldata, uint8_t *KEY, bool use_c memcpy(data + 8, MAC, 4); clearCommandBuffer(); - SendCommandOLD(CMD_ICLASS_WRITEBLOCK, blockno, 0, 0, data, sizeof(data)); + SendCommandOLD(CMD_HF_ICLASS_WRITEBL, blockno, 0, 0, data, sizeof(data)); if (!WaitForResponseTimeout(CMD_ACK, &resp, 4500)) { if (verbose) PrintAndLogEx(WARNING, "Write Command execute timeout"); return 0; @@ -1317,7 +1317,7 @@ static int CmdHFiClassCloneTag(const char *Cmd) { PacketResponseNG resp; clearCommandBuffer(); - SendCommandOLD(CMD_ICLASS_CLONE, startblock, endblock, 0, data, (endblock - startblock) * 12); + SendCommandOLD(CMD_HF_ICLASS_CLONE, startblock, endblock, 0, data, (endblock - startblock) * 12); if (!WaitForResponseTimeout(CMD_ACK, &resp, 4500)) { PrintAndLogEx(WARNING, "command execute timeout"); return 0; @@ -1341,7 +1341,7 @@ static int ReadBlock(uint8_t *KEY, uint8_t blockno, uint8_t keyType, bool elite, PacketResponseNG resp; clearCommandBuffer(); - SendCommandMIX(CMD_ICLASS_READBLOCK, blockno, 0, 0, NULL, 0); + SendCommandMIX(CMD_HF_ICLASS_READBL, blockno, 0, 0, NULL, 0); if (!WaitForResponseTimeout(CMD_ACK, &resp, 4500)) { PrintAndLogEx(WARNING, "Command execute timeout"); return 0; @@ -1959,7 +1959,7 @@ static int CmdHFiClassCheckKeys(const char *Cmd) { flags |= (use_credit_key << 16); clearCommandBuffer(); - SendCommandOLD(CMD_ICLASS_CHECK_KEYS, flags, keys, 0, pre + i, 4 * keys); + SendCommandOLD(CMD_HF_ICLASS_CHKKEYS, flags, keys, 0, pre + i, 4 * keys); PacketResponseNG resp; while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { @@ -2441,7 +2441,7 @@ int readIclass(bool loop, bool verbose) { while (!kbd_enter_pressed()) { clearCommandBuffer(); - SendCommandMIX(CMD_READER_ICLASS, flags, 0, 0, NULL, 0); + SendCommandMIX(CMD_HF_ICLASS_READER, flags, 0, 0, NULL, 0); if (WaitForResponseTimeout(CMD_ACK, &resp, 4500)) { uint8_t readStatus = resp.oldarg[0] & 0xff; uint8_t *data = resp.data.asBytes; diff --git a/client/cmdhflegic.c b/client/cmdhflegic.c index e8089c3d8..9daad8387 100644 --- a/client/cmdhflegic.c +++ b/client/cmdhflegic.c @@ -527,7 +527,7 @@ static int CmdLegicRfSim(const char *Cmd) { uint64_t id = 1; sscanf(Cmd, " %" SCNi64, &id); clearCommandBuffer(); - SendCommandMIX(CMD_SIMULATE_TAG_LEGIC_RF, id, 0, 0, NULL, 0); + SendCommandMIX(CMD_HF_LEGIC_SIMULATE, id, 0, 0, NULL, 0); return 0; } @@ -644,7 +644,7 @@ static int CmdLegicRfWrite(const char *Cmd) { PacketResponseNG resp; clearCommandBuffer(); - SendCommandOLD(CMD_WRITER_LEGIC_RF, offset, len, IV, data, len); + SendCommandOLD(CMD_HF_LEGIC_WRITER, offset, len, IV, data, len); uint8_t timeout = 0; @@ -755,7 +755,7 @@ int legic_read_mem(uint32_t offset, uint32_t len, uint32_t iv, uint8_t *out, uin legic_chk_iv(&iv); clearCommandBuffer(); - SendCommandMIX(CMD_READER_LEGIC_RF, offset, len, iv, NULL, 0); + SendCommandMIX(CMD_HF_LEGIC_READER, offset, len, iv, NULL, 0); PacketResponseNG resp; uint8_t timeout = 0; @@ -808,7 +808,7 @@ int legic_get_type(legic_card_select_t *card) { if (card == NULL) return 1; clearCommandBuffer(); - SendCommandNG(CMD_LEGIC_INFO, NULL, 0); + SendCommandNG(CMD_HF_LEGIC_INFO, NULL, 0); PacketResponseNG resp; if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) return 2; @@ -842,7 +842,7 @@ void legic_seteml(uint8_t *src, uint32_t offset, uint32_t numofbytes) { conn.block_after_ACK = false; } clearCommandBuffer(); - SendCommandOLD(CMD_LEGIC_ESET, i, len, 0, src + i, len); + SendCommandOLD(CMD_HF_LEGIC_ESET, i, len, 0, src + i, len); } } @@ -898,7 +898,7 @@ static int CmdLegicDump(const char *Cmd) { PrintAndLogEx(SUCCESS, "Reading tag memory %d b...", dumplen); clearCommandBuffer(); - SendCommandMIX(CMD_READER_LEGIC_RF, 0x00, dumplen, 0x55, NULL, 0); + SendCommandMIX(CMD_HF_LEGIC_READER, 0x00, dumplen, 0x55, NULL, 0); PacketResponseNG resp; uint8_t timeout = 0; @@ -1057,7 +1057,7 @@ static int CmdLegicRestore(const char *Cmd) { conn.block_after_ACK = false; } clearCommandBuffer(); - SendCommandOLD(CMD_WRITER_LEGIC_RF, i, len, 0x55, data + i, len); + SendCommandOLD(CMD_HF_LEGIC_WRITER, i, len, 0x55, data + i, len); uint8_t timeout = 0; while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { @@ -1254,7 +1254,7 @@ static int CmdLegicWipe(const char *Cmd) { conn.block_after_ACK = false; } clearCommandBuffer(); - SendCommandOLD(CMD_WRITER_LEGIC_RF, i, len, 0x55, data + i, len); + SendCommandOLD(CMD_HF_LEGIC_WRITER, i, len, 0x55, data + i, len); uint8_t timeout = 0; while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 5fff42061..c3e36e33f 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -398,7 +398,7 @@ static int usage_hf14_nack(void) { static int GetHFMF14AUID(uint8_t *uid, int *uidlen) { clearCommandBuffer(); - SendCommandMIX(CMD_READER_ISO_14443a, ISO14A_CONNECT, 0, 0, NULL, 0); + SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT, 0, 0, NULL, 0); PacketResponseNG resp; if (!WaitForResponseTimeout(CMD_ACK, &resp, 2500)) { PrintAndLogEx(WARNING, "iso14443a card select failed"); @@ -511,7 +511,7 @@ static int CmdHF14AMfWrBl(const char *Cmd) { memcpy(data, key, 6); memcpy(data + 10, bldata, 16); clearCommandBuffer(); - SendCommandOLD(CMD_MIFARE_WRITEBL, blockNo, keyType, 0, data, sizeof(data)); + SendCommandOLD(CMD_HF_MIFARE_WRITEBL, blockNo, keyType, 0, data, sizeof(data)); PacketResponseNG resp; if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { @@ -559,10 +559,10 @@ static int CmdHF14AMfRdBl(const char *Cmd) { memcpy(payload.key, key, sizeof(payload.key)); clearCommandBuffer(); - SendCommandNG(CMD_MIFARE_READBL, (uint8_t *)&payload, sizeof(mf_readblock_t)); + SendCommandNG(CMD_HF_MIFARE_READBL, (uint8_t *)&payload, sizeof(mf_readblock_t)); PacketResponseNG resp; - if (WaitForResponseTimeout(CMD_MIFARE_READBL, &resp, 1500)) { + if (WaitForResponseTimeout(CMD_HF_MIFARE_READBL, &resp, 1500)) { uint8_t *data = resp.data.asBytes; if (resp.status == PM3_SUCCESS) { @@ -624,7 +624,7 @@ static int CmdHF14AMfRdSc(const char *Cmd) { PrintAndLogEx(NORMAL, "--sector no:%d key type:%c key:%s ", sectorNo, keyType ? 'B' : 'A', sprint_hex(key, 6)); clearCommandBuffer(); - SendCommandOLD(CMD_MIFARE_READSC, sectorNo, keyType, 0, key, 6); + SendCommandOLD(CMD_HF_MIFARE_READSC, sectorNo, keyType, 0, key, 6); PrintAndLogEx(NORMAL, ""); PacketResponseNG resp; @@ -797,9 +797,9 @@ static int CmdHF14AMfDump(const char *Cmd) { memcpy(payload.key, keyA[sectorNo], sizeof(payload.key)); clearCommandBuffer(); - SendCommandNG(CMD_MIFARE_READBL, (uint8_t *)&payload, sizeof(mf_readblock_t)); + SendCommandNG(CMD_HF_MIFARE_READBL, (uint8_t *)&payload, sizeof(mf_readblock_t)); - if (WaitForResponseTimeout(CMD_MIFARE_READBL, &resp, 1500)) { + if (WaitForResponseTimeout(CMD_HF_MIFARE_READBL, &resp, 1500)) { uint8_t *data = resp.data.asBytes; if (resp.status == PM3_SUCCESS) { @@ -836,8 +836,8 @@ static int CmdHF14AMfDump(const char *Cmd) { memcpy(payload.key, keyA[sectorNo], sizeof(payload.key)); clearCommandBuffer(); - SendCommandNG(CMD_MIFARE_READBL, (uint8_t *)&payload, sizeof(mf_readblock_t)); - received = WaitForResponseTimeout(CMD_MIFARE_READBL, &resp, 1500); + SendCommandNG(CMD_HF_MIFARE_READBL, (uint8_t *)&payload, sizeof(mf_readblock_t)); + received = WaitForResponseTimeout(CMD_HF_MIFARE_READBL, &resp, 1500); } else { // data block. Check if it can be read with key A or key B uint8_t data_area = (sectorNo < 32) ? blockNo : blockNo / 5; if ((rights[sectorNo][data_area] == 0x03) || (rights[sectorNo][data_area] == 0x05)) { // only key B would work @@ -847,8 +847,8 @@ static int CmdHF14AMfDump(const char *Cmd) { memcpy(payload.key, keyB[sectorNo], sizeof(payload.key)); clearCommandBuffer(); - SendCommandNG(CMD_MIFARE_READBL, (uint8_t *)&payload, sizeof(mf_readblock_t)); - received = WaitForResponseTimeout(CMD_MIFARE_READBL, &resp, 1500); + SendCommandNG(CMD_HF_MIFARE_READBL, (uint8_t *)&payload, sizeof(mf_readblock_t)); + received = WaitForResponseTimeout(CMD_HF_MIFARE_READBL, &resp, 1500); } else if (rights[sectorNo][data_area] == 0x07) { // no key would work PrintAndLogEx(WARNING, "access rights do not allow reading of sector %2d block %3d", sectorNo, blockNo); // where do you want to go?? Next sector or block? @@ -860,8 +860,8 @@ static int CmdHF14AMfDump(const char *Cmd) { memcpy(payload.key, keyA[sectorNo], sizeof(payload.key)); clearCommandBuffer(); - SendCommandNG(CMD_MIFARE_READBL, (uint8_t *)&payload, sizeof(mf_readblock_t)); - received = WaitForResponseTimeout(CMD_MIFARE_READBL, &resp, 1500); + SendCommandNG(CMD_HF_MIFARE_READBL, (uint8_t *)&payload, sizeof(mf_readblock_t)); + received = WaitForResponseTimeout(CMD_HF_MIFARE_READBL, &resp, 1500); } } if (received) { @@ -1046,7 +1046,7 @@ static int CmdHF14AMfRestore(const char *Cmd) { memcpy(data + 10, bldata, 16); clearCommandBuffer(); - SendCommandOLD(CMD_MIFARE_WRITEBL, FirstBlockOfSector(sectorNo) + blockNo, keyType, 0, data, sizeof(data)); + SendCommandOLD(CMD_HF_MIFARE_WRITEBL, FirstBlockOfSector(sectorNo) + blockNo, keyType, 0, data, sizeof(data)); PacketResponseNG resp; if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { @@ -1250,10 +1250,10 @@ static int CmdHF14AMfNested(const char *Cmd) { num_to_bytes(e_sector[i].Key[0], 6, payload.key); // KEY A clearCommandBuffer(); - SendCommandNG(CMD_MIFARE_READBL, (uint8_t *)&payload, sizeof(mf_readblock_t)); + SendCommandNG(CMD_HF_MIFARE_READBL, (uint8_t *)&payload, sizeof(mf_readblock_t)); PacketResponseNG resp; - if (!WaitForResponseTimeout(CMD_MIFARE_READBL, &resp, 1500)) continue; + if (!WaitForResponseTimeout(CMD_HF_MIFARE_READBL, &resp, 1500)) continue; if (resp.status != PM3_SUCCESS) continue; @@ -2014,10 +2014,10 @@ static int CmdHF14AMfChk(const char *Cmd) { num_to_bytes(e_sector[i].Key[0], 6, payload.key); // KEY A clearCommandBuffer(); - SendCommandNG(CMD_MIFARE_READBL, (uint8_t *)&payload, sizeof(mf_readblock_t)); + SendCommandNG(CMD_HF_MIFARE_READBL, (uint8_t *)&payload, sizeof(mf_readblock_t)); PacketResponseNG resp; - if (!WaitForResponseTimeout(CMD_MIFARE_READBL, &resp, 1500)) continue; + if (!WaitForResponseTimeout(CMD_HF_MIFARE_READBL, &resp, 1500)) continue; if (resp.status != PM3_SUCCESS) continue; @@ -2275,7 +2275,7 @@ static int CmdHF14AMfSim(const char *Cmd) { memcpy(payload.uid, uid, uidlen); clearCommandBuffer(); - SendCommandNG(CMD_SIMULATE_MIFARE_CARD, (uint8_t *)&payload, sizeof(payload)); + SendCommandNG(CMD_HF_MIFARE_SIMULATE, (uint8_t *)&payload, sizeof(payload)); PacketResponseNG resp; if (flags & FLAG_INTERACTIVE) { @@ -2284,7 +2284,7 @@ static int CmdHF14AMfSim(const char *Cmd) { while (!kbd_enter_pressed()) { if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) continue; if (!(flags & FLAG_NR_AR_ATTACK)) break; - if ((resp.oldarg[0] & 0xffff) != CMD_SIMULATE_MIFARE_CARD) break; + if ((resp.oldarg[0] & 0xffff) != CMD_HF_MIFARE_SIMULATE) break; memcpy(data, resp.data.asBytes, sizeof(data)); readerAttack(data[0], setEmulatorMem, verbose); @@ -2333,7 +2333,7 @@ static int CmdHF14AMfSniff(const char *Cmd) { PrintAndLogEx(NORMAL, "-------------------------------------------------------------------------\n"); clearCommandBuffer(); - SendCommandNG(CMD_MIFARE_SNIFFER, NULL, 0); + SendCommandNG(CMD_HF_MIFARE_SNIFF, NULL, 0); PacketResponseNG resp; @@ -2530,7 +2530,7 @@ static int CmdHF14AMfEClear(const char *Cmd) { if (c == 'h') return usage_hf14_eclr(); clearCommandBuffer(); - SendCommandNG(CMD_MIFARE_EML_MEMCLR, NULL, 0); + SendCommandNG(CMD_HF_MIFARE_EML_MEMCLR, NULL, 0); return PM3_SUCCESS; } @@ -2740,7 +2740,7 @@ static int CmdHF14AMfECFill(const char *Cmd) { PrintAndLogEx(NORMAL, "--params: numSectors: %d, keyType: %c\n", numSectors, (keyType == 0) ? 'A' : 'B'); clearCommandBuffer(); - SendCommandMIX(CMD_MIFARE_EML_CARDLOAD, numSectors, keyType, 0, NULL, 0); + SendCommandMIX(CMD_HF_MIFARE_EML_LOAD, numSectors, keyType, 0, NULL, 0); return PM3_SUCCESS; } @@ -3216,10 +3216,10 @@ static int CmdHf14AMfSetMod(const char *Cmd) { memcpy(data + 1, key, 6); clearCommandBuffer(); - SendCommandNG(CMD_MIFARE_SETMOD, data, sizeof(data)); + SendCommandNG(CMD_HF_MIFARE_SETMOD, data, sizeof(data)); PacketResponseNG resp; - if (WaitForResponseTimeout(CMD_MIFARE_SETMOD, &resp, 1500)) { + if (WaitForResponseTimeout(CMD_HF_MIFARE_SETMOD, &resp, 1500)) { if (resp.status == PM3_SUCCESS) PrintAndLogEx(SUCCESS, "Success"); @@ -3314,7 +3314,7 @@ static int CmdHF14AMfice(const char *Cmd) { flags |= initialize ? 0x0001 : 0; flags |= slow ? 0x0002 : 0; clearCommandBuffer(); - SendCommandMIX(CMD_MIFARE_ACQUIRE_NONCES, blockNo + keyType * 0x100, trgBlockNo + trgKeyType * 0x100, flags, NULL, 0); + SendCommandMIX(CMD_HF_MIFARE_ACQ_NONCES, blockNo + keyType * 0x100, trgBlockNo + trgKeyType * 0x100, flags, NULL, 0); if (!WaitForResponseTimeout(CMD_ACK, &resp, 3000)) goto out; if (resp.oldarg[0]) goto out; @@ -3346,7 +3346,7 @@ out: } clearCommandBuffer(); - SendCommandMIX(CMD_MIFARE_ACQUIRE_NONCES, blockNo + keyType * 0x100, trgBlockNo + trgKeyType * 0x100, 4, NULL, 0); + SendCommandMIX(CMD_HF_MIFARE_ACQ_NONCES, blockNo + keyType * 0x100, trgBlockNo + trgKeyType * 0x100, 4, NULL, 0); return PM3_SUCCESS; } diff --git a/client/cmdhfmfdes.c b/client/cmdhfmfdes.c index d9023da47..5dd4489f6 100644 --- a/client/cmdhfmfdes.c +++ b/client/cmdhfmfdes.c @@ -51,7 +51,7 @@ static int CmdHF14ADesWb(const char *Cmd) { uint8_t data[26]; memcpy(data, key, 6); memcpy(data + 10, bldata, 16); - SendCommandOLD(CMD_MIFARE_WRITEBL, blockNo, keyType, 0, data, sizeof(data)); + SendCommandOLD(CMD_HF_MIFARE_WRITEBL, blockNo, keyType, 0, data, sizeof(data)); PacketResponseNG resp; if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { @@ -92,10 +92,10 @@ static int CmdHF14ADesRb(const char *Cmd) { mf_readblock_t payload = { blockNo, keyType, key }; - SendCommandNG(CMD_MIFARE_READBL, (uint8_t *)payload, sizeof(mf_readblock_t) ); + SendCommandNG(CMD_HF_MIFARE_READBL, (uint8_t *)payload, sizeof(mf_readblock_t) ); PacketResponseNG resp; - if (WaitForResponseTimeout(CMD_MIFARE_READBL, &resp, 1500)) { + if (WaitForResponseTimeout(CMD_HF_MIFARE_READBL, &resp, 1500)) { uint8_t * data = resp.data.asBytes; if (resp.status == PM3_SUCCESS) @@ -112,7 +112,7 @@ static int CmdHF14ADesRb(const char *Cmd) { static int CmdHF14ADesInfo(const char *Cmd) { (void)Cmd; // Cmd is not used so far - SendCommandNG(CMD_MIFARE_DESFIRE_INFO, NULL, 0); + SendCommandNG(CMD_HF_DESFIRE_INFO, NULL, 0); PacketResponseNG resp; if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { @@ -164,7 +164,7 @@ static int CmdHF14ADesInfo(const char *Cmd) { // Free memory on card uint8_t data[1] = {GET_FREE_MEMORY}; - SendCommandOLD(CMD_MIFARE_DESFIRE, (INIT | DISCONNECT), 0x01, 0, data, sizeof(data)); + SendCommandOLD(CMD_HF_DESFIRE_COMMAND, (INIT | DISCONNECT), 0x01, 0, data, sizeof(data)); if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) return 0; @@ -256,7 +256,7 @@ void getKeySettings(uint8_t *aid) { PrintAndLogEx(NORMAL, ""); { uint8_t data[1] = {GET_KEY_SETTINGS}; // 0x45 - SendCommandOLD(CMD_MIFARE_DESFIRE, INIT | DISCONNECT, sizeof(data), 0, data, sizeof(data)); + SendCommandOLD(CMD_HF_DESFIRE_COMMAND, INIT | DISCONNECT, sizeof(data), 0, data, sizeof(data)); } if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)) {return;} isOK = resp.oldarg[0] & 0xff; @@ -275,7 +275,7 @@ void getKeySettings(uint8_t *aid) { PrintAndLogEx(NORMAL, " [0x01] CMK is changeable : %s", str); { uint8_t data[2] = {GET_KEY_VERSION, 0}; // 0x64 - SendCommandOLD(CMD_MIFARE_DESFIRE, INIT | DISCONNECT, sizeof(data), 0, data, sizeof(data)); + SendCommandOLD(CMD_HF_DESFIRE_COMMAND, INIT | DISCONNECT, sizeof(data), 0, data, sizeof(data)); } if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)) { return; } isOK = resp.oldarg[0] & 0xff; @@ -290,7 +290,7 @@ void getKeySettings(uint8_t *aid) { { uint8_t data[2] = {AUTHENTICATE, 0}; // 0x0A, KEY 0 - SendCommandOLD(CMD_MIFARE_DESFIRE, INIT | DISCONNECT, sizeof(data), 0, data, sizeof(data)); + SendCommandOLD(CMD_HF_DESFIRE_COMMAND, INIT | DISCONNECT, sizeof(data), 0, data, sizeof(data)); } if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)) {return;} isOK = resp.data.asBytes[2] & 0xff; @@ -298,7 +298,7 @@ void getKeySettings(uint8_t *aid) { { uint8_t data[2] = {AUTHENTICATE_ISO, 0}; // 0x1A, KEY 0 - SendCommandOLD(CMD_MIFARE_DESFIRE, INIT | DISCONNECT, sizeof(data), 0, data, sizeof(data)); + SendCommandOLD(CMD_HF_DESFIRE_COMMAND, INIT | DISCONNECT, sizeof(data), 0, data, sizeof(data)); } if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)) {return;} isOK = resp.data.asBytes[2] & 0xff; @@ -306,7 +306,7 @@ void getKeySettings(uint8_t *aid) { { uint8_t data[2] = {AUTHENTICATE_AES, 0}; // 0xAA, KEY 0 - SendCommandOLD(CMD_MIFARE_DESFIRE, INIT | DISCONNECT, sizeof(data), 0, data, sizeof(data)); + SendCommandOLD(CMD_HF_DESFIRE_COMMAND, INIT | DISCONNECT, sizeof(data), 0, data, sizeof(data)); } if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)) {return;} isOK = resp.data.asBytes[2] & 0xff; @@ -321,7 +321,7 @@ void getKeySettings(uint8_t *aid) { { uint8_t data[4] = {SELECT_APPLICATION}; // 0x5a memcpy(data + 1, aid, 3); - SendCommandOLD(CMD_MIFARE_DESFIRE, INIT | CLEARTRACE, sizeof(data), 0, data, sizeof(data)); + SendCommandOLD(CMD_HF_DESFIRE_COMMAND, INIT | CLEARTRACE, sizeof(data), 0, data, sizeof(data)); } if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { PrintAndLogEx(WARNING, " Timed-out"); @@ -336,7 +336,7 @@ void getKeySettings(uint8_t *aid) { // KEY SETTINGS { uint8_t data[1] = {GET_KEY_SETTINGS}; // 0x45 - SendCommandOLD(CMD_MIFARE_DESFIRE, NONE, sizeof(data), 0, data, sizeof(data)); + SendCommandOLD(CMD_HF_DESFIRE_COMMAND, NONE, sizeof(data), 0, data, sizeof(data)); } if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { return; @@ -378,7 +378,7 @@ void getKeySettings(uint8_t *aid) { // KEY VERSION - AMK { uint8_t data[2] = {GET_KEY_VERSION, 0}; // 0x64 - SendCommandOLD(CMD_MIFARE_DESFIRE, NONE, sizeof(data), 0, data, sizeof(data)); + SendCommandOLD(CMD_HF_DESFIRE_COMMAND, NONE, sizeof(data), 0, data, sizeof(data)); } if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { PrintAndLogEx(WARNING, " Timed-out"); @@ -417,7 +417,7 @@ static int CmdHF14ADesEnumApplications(const char *Cmd) { uint8_t aid[3]; { uint8_t data[1] = {GET_APPLICATION_IDS}; //0x6a - SendCommandOLD(CMD_MIFARE_DESFIRE, INIT | DISCONNECT, sizeof(data), 0, data, sizeof(data)); + SendCommandOLD(CMD_HF_DESFIRE_COMMAND, INIT | DISCONNECT, sizeof(data), 0, data, sizeof(data)); } PacketResponseNG resp; @@ -452,7 +452,7 @@ static int CmdHF14ADesEnumApplications(const char *Cmd) { { uint8_t data[4] = {SELECT_APPLICATION}; // 0x5a memcpy(data + 1, &resp.data.asBytes[i], 3); - SendCommandOLD(CMD_MIFARE_DESFIRE, INIT, sizeof(data), 0, data, sizeof(data)); + SendCommandOLD(CMD_HF_DESFIRE_COMMAND, INIT, sizeof(data), 0, data, sizeof(data)); } if (!WaitForResponseTimeout(CMD_ACK, &respAid, 1500)) { @@ -468,7 +468,7 @@ static int CmdHF14ADesEnumApplications(const char *Cmd) { // Get File IDs { uint8_t data[1] = {GET_FILE_IDS}; // 0x6f - SendCommandOLD(CMD_MIFARE_DESFIRE, NONE, sizeof(data), 0, data, sizeof(data)); + SendCommandOLD(CMD_HF_DESFIRE_COMMAND, NONE, sizeof(data), 0, data, sizeof(data)); } if (!WaitForResponseTimeout(CMD_ACK, &respFiles, 1500)) { @@ -489,7 +489,7 @@ static int CmdHF14ADesEnumApplications(const char *Cmd) { // Get ISO File IDs { uint8_t data[1] = {GET_ISOFILE_IDS}; // 0x61 - SendCommandOLD(CMD_MIFARE_DESFIRE, DISCONNECT, sizeof(data), 0, data, sizeof(data)); + SendCommandOLD(CMD_HF_DESFIRE_COMMAND, DISCONNECT, sizeof(data), 0, data, sizeof(data)); } if (!WaitForResponseTimeout(CMD_ACK, &respFiles, 1500)) { @@ -600,7 +600,7 @@ static int CmdHF14ADesAuth(const char *Cmd) { uint8_t data[25] = {keylength}; // max length: 1 + 24 (3k3DES) memcpy(data + 1, key, keylength); clearCommandBuffer(); - SendCommandOLD(CMD_MIFARE_DESFIRE_AUTH1, cmdAuthMode, cmdAuthAlgo, cmdKeyNo, data, keylength + 1); + SendCommandOLD(CMD_HF_DESFIRE_AUTH1, cmdAuthMode, cmdAuthAlgo, cmdKeyNo, data, keylength + 1); PacketResponseNG resp; if (!WaitForResponseTimeout(CMD_ACK, &resp, 3000)) { diff --git a/client/cmdhfmfhard.c b/client/cmdhfmfhard.c index 4de46d36a..a944f11ab 100644 --- a/client/cmdhfmfhard.c +++ b/client/cmdhfmfhard.c @@ -1379,7 +1379,7 @@ static int acquire_nonces(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_ flags |= field_off ? 0x0004 : 0; clearCommandBuffer(); - SendCommandMIX(CMD_MIFARE_ACQUIRE_ENCRYPTED_NONCES, blockNo + keyType * 0x100, trgBlockNo + trgKeyType * 0x100, flags, key, 6); + SendCommandMIX(CMD_HF_MIFARE_ACQ_ENCRYPTED_NONCES, blockNo + keyType * 0x100, trgBlockNo + trgKeyType * 0x100, flags, key, 6); if (field_off) break; @@ -1388,7 +1388,7 @@ static int acquire_nonces(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_ uint8_t nullkey[6] = {0}; //strange second call (iceman) clearCommandBuffer(); - SendCommandMIX(CMD_MIFARE_ACQUIRE_ENCRYPTED_NONCES, blockNo + keyType * 0x100, trgBlockNo + trgKeyType * 0x100, 4, nullkey, sizeof(nullkey)); + SendCommandMIX(CMD_HF_MIFARE_ACQ_ENCRYPTED_NONCES, blockNo + keyType * 0x100, trgBlockNo + trgKeyType * 0x100, 4, nullkey, sizeof(nullkey)); return 1; } if (resp.oldarg[0]) return resp.oldarg[0]; // error during nested_hard diff --git a/client/cmdhfmfp.c b/client/cmdhfmfp.c index 46ee6e680..e9dd245b6 100644 --- a/client/cmdhfmfp.c +++ b/client/cmdhfmfp.c @@ -42,7 +42,7 @@ static int CmdHFMFPInfo(const char *cmd) { infoHF14A(false, false); // Mifare Plus info - SendCommandMIX(CMD_READER_ISO_14443a, ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0, NULL, 0); + SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0, NULL, 0); PacketResponseNG resp; WaitForResponse(CMD_ACK, &resp); diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index 0158d3394..7367dfd66 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -471,12 +471,12 @@ static char *getUlev1CardSizeStr(uint8_t fsize) { static void ul_switch_on_field(void) { clearCommandBuffer(); - SendCommandMIX(CMD_READER_ISO_14443a, ISO14A_CONNECT | ISO14A_NO_DISCONNECT | ISO14A_NO_RATS, 0, 0, NULL, 0); + SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT | ISO14A_NO_DISCONNECT | ISO14A_NO_RATS, 0, 0, NULL, 0); } static int ul_send_cmd_raw(uint8_t *cmd, uint8_t cmdlen, uint8_t *response, uint16_t responseLength) { clearCommandBuffer(); - SendCommandOLD(CMD_READER_ISO_14443a, ISO14A_RAW | ISO14A_NO_DISCONNECT | ISO14A_APPEND_CRC | ISO14A_NO_RATS, cmdlen, 0, cmd, cmdlen); + SendCommandOLD(CMD_HF_ISO14443A_READER, ISO14A_RAW | ISO14A_NO_DISCONNECT | ISO14A_APPEND_CRC | ISO14A_NO_RATS, cmdlen, 0, cmd, cmdlen); PacketResponseNG resp; if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) return -1; if (!resp.oldarg[0] && responseLength) return -1; @@ -543,7 +543,7 @@ static int ulc_requestAuthentication(uint8_t *nonce, uint16_t nonceLength) { static int ulc_authentication(uint8_t *key, bool switch_off_field) { clearCommandBuffer(); - SendCommandOLD(CMD_MIFAREUC_AUTH, switch_off_field, 0, 0, key, 16); + SendCommandOLD(CMD_HF_MIFAREUC_AUTH, switch_off_field, 0, 0, key, 16); PacketResponseNG resp; if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) return 0; if (resp.oldarg[0] == 1) return 1; @@ -630,7 +630,7 @@ static int ul_fudan_check(void) { uint8_t cmd[4] = {0x30, 0x00, 0x02, 0xa7}; //wrong crc on purpose should be 0xa8 clearCommandBuffer(); - SendCommandOLD(CMD_READER_ISO_14443a, ISO14A_RAW | ISO14A_NO_DISCONNECT | ISO14A_NO_RATS, 4, 0, cmd, sizeof(cmd)); + SendCommandOLD(CMD_HF_ISO14443A_READER, ISO14A_RAW | ISO14A_NO_DISCONNECT | ISO14A_NO_RATS, 4, 0, cmd, sizeof(cmd)); PacketResponseNG resp; if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) return UL_ERROR; if (resp.oldarg[0] != 1) return UL_ERROR; @@ -1562,7 +1562,7 @@ static int CmdHF14AMfUWrBl(const char *Cmd) { } clearCommandBuffer(); - SendCommandOLD(CMD_MIFAREU_WRITEBL, blockNo, keytype, 0, cmddata, datalen); + SendCommandOLD(CMD_HF_MIFAREU_WRITEBL, blockNo, keytype, 0, cmddata, datalen); PacketResponseNG resp; if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { uint8_t isOK = resp.oldarg[0] & 0xff; @@ -1667,7 +1667,7 @@ static int CmdHF14AMfURdBl(const char *Cmd) { } clearCommandBuffer(); - SendCommandOLD(CMD_MIFAREU_READBL, blockNo, keytype, 0, authKeyPtr, datalen); + SendCommandOLD(CMD_HF_MIFAREU_READBL, blockNo, keytype, 0, authKeyPtr, datalen); PacketResponseNG resp; if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { uint8_t isOK = resp.oldarg[0] & 0xff; @@ -1933,7 +1933,7 @@ static int CmdHF14AMfUDump(const char *Cmd) { } clearCommandBuffer(); - SendCommandOLD(CMD_MIFAREU_READCARD, startPage, pages, keytype, authKeyPtr, dataLen); + SendCommandOLD(CMD_HF_MIFAREU_READCARD, startPage, pages, keytype, authKeyPtr, dataLen); PacketResponseNG resp; if (!WaitForResponseTimeout(CMD_ACK, &resp, 2500)) { @@ -2235,7 +2235,7 @@ static int CmdHF14AMfURestore(const char *Cmd) { PrintAndLogEx(NORMAL, "special PWD block written 0x%X - %s\n", MFU_NTAG_SPECIAL_PWD, sprint_hex(data, 4)); clearCommandBuffer(); - SendCommandOLD(CMD_MIFAREU_WRITEBL, MFU_NTAG_SPECIAL_PWD, keytype, 0, data, sizeof(data)); + SendCommandOLD(CMD_HF_MIFAREU_WRITEBL, MFU_NTAG_SPECIAL_PWD, keytype, 0, data, sizeof(data)); wait4response(MFU_NTAG_SPECIAL_PWD); @@ -2251,7 +2251,7 @@ static int CmdHF14AMfURestore(const char *Cmd) { data[3] = 0; PrintAndLogEx(NORMAL, "special PACK block written 0x%X - %s\n", MFU_NTAG_SPECIAL_PACK, sprint_hex(data, 4)); clearCommandBuffer(); - SendCommandOLD(CMD_MIFAREU_WRITEBL, MFU_NTAG_SPECIAL_PACK, keytype, 0, data, sizeof(data)); + SendCommandOLD(CMD_HF_MIFAREU_WRITEBL, MFU_NTAG_SPECIAL_PACK, keytype, 0, data, sizeof(data)); wait4response(MFU_NTAG_SPECIAL_PACK); // Signature @@ -2259,7 +2259,7 @@ static int CmdHF14AMfURestore(const char *Cmd) { memcpy(data, mem->signature + i, 4); PrintAndLogEx(NORMAL, "special SIG block written 0x%X - %s\n", s, sprint_hex(data, 4)); clearCommandBuffer(); - SendCommandOLD(CMD_MIFAREU_WRITEBL, s, keytype, 0, data, sizeof(data)); + SendCommandOLD(CMD_HF_MIFAREU_WRITEBL, s, keytype, 0, data, sizeof(data)); wait4response(s); } @@ -2268,7 +2268,7 @@ static int CmdHF14AMfURestore(const char *Cmd) { memcpy(data, mem->version + i, 4); PrintAndLogEx(NORMAL, "special VERSION block written 0x%X - %s\n", s, sprint_hex(data, 4)); clearCommandBuffer(); - SendCommandOLD(CMD_MIFAREU_WRITEBL, s, keytype, 0, data, sizeof(data)); + SendCommandOLD(CMD_HF_MIFAREU_WRITEBL, s, keytype, 0, data, sizeof(data)); wait4response(s); } } @@ -2282,7 +2282,7 @@ static int CmdHF14AMfURestore(const char *Cmd) { //Send write Block memcpy(data, mem->data + (b * 4), 4); clearCommandBuffer(); - SendCommandOLD(CMD_MIFAREU_WRITEBL, b, keytype, 0, data, sizeof(data)); + SendCommandOLD(CMD_HF_MIFAREU_WRITEBL, b, keytype, 0, data, sizeof(data)); wait4response(b); printf("."); fflush(stdout); @@ -2302,7 +2302,7 @@ static int CmdHF14AMfURestore(const char *Cmd) { uint8_t b = blocks[i]; memcpy(data, mem->data + (b * 4), 4); clearCommandBuffer(); - SendCommandOLD(CMD_MIFAREU_WRITEBL, b, keytype, 0, data, sizeof(data)); + SendCommandOLD(CMD_HF_MIFAREU_WRITEBL, b, keytype, 0, data, sizeof(data)); wait4response(b); PrintAndLogEx(NORMAL, "special block written %u - %s\n", b, sprint_hex(data, 4)); } @@ -2477,7 +2477,7 @@ static int CmdHF14AMfUCSetPwd(const char *Cmd) { } clearCommandBuffer(); - SendCommandOLD(CMD_MIFAREUC_SETPWD, 0, 0, 0, pwd, 16); + SendCommandOLD(CMD_HF_MIFAREUC_SETPWD, 0, 0, 0, pwd, 16); PacketResponseNG resp; if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { @@ -2512,7 +2512,7 @@ static int CmdHF14AMfUCSetUid(const char *Cmd) { // read block2. clearCommandBuffer(); - SendCommandMIX(CMD_MIFAREU_READBL, 2, 0, 0, NULL, 0); + SendCommandMIX(CMD_HF_MIFAREU_READBL, 2, 0, 0, NULL, 0); if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { PrintAndLogEx(WARNING, "Command execute timeout"); return 2; @@ -2529,7 +2529,7 @@ static int CmdHF14AMfUCSetUid(const char *Cmd) { data[2] = uid[2]; data[3] = 0x88 ^ uid[0] ^ uid[1] ^ uid[2]; clearCommandBuffer(); - SendCommandOLD(CMD_MIFAREU_WRITEBL, 0, 0, 0, data, sizeof(data)); + SendCommandOLD(CMD_HF_MIFAREU_WRITEBL, 0, 0, 0, data, sizeof(data)); if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { PrintAndLogEx(WARNING, "Command execute timeout"); return 3; @@ -2541,7 +2541,7 @@ static int CmdHF14AMfUCSetUid(const char *Cmd) { data[2] = uid[5]; data[3] = uid[6]; clearCommandBuffer(); - SendCommandOLD(CMD_MIFAREU_WRITEBL, 1, 0, 0, data, sizeof(data)); + SendCommandOLD(CMD_HF_MIFAREU_WRITEBL, 1, 0, 0, data, sizeof(data)); if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { PrintAndLogEx(WARNING, "Command execute timeout"); return 4; @@ -2553,7 +2553,7 @@ static int CmdHF14AMfUCSetUid(const char *Cmd) { data[2] = oldblock2[2]; data[3] = oldblock2[3]; clearCommandBuffer(); - SendCommandOLD(CMD_MIFAREU_WRITEBL, 2, 0, 0, data, sizeof(data)); + SendCommandOLD(CMD_HF_MIFAREU_WRITEBL, 2, 0, 0, data, sizeof(data)); if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { PrintAndLogEx(WARNING, "Command execute timeout"); return 5; @@ -2570,7 +2570,7 @@ static int CmdHF14AMfUGenDiverseKeys(const char *Cmd) { if (cmdp == 'r') { // read uid from tag clearCommandBuffer(); - SendCommandMIX(CMD_READER_ISO_14443a, ISO14A_CONNECT | ISO14A_NO_RATS, 0, 0, NULL, 0); + SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT | ISO14A_NO_RATS, 0, 0, NULL, 0); PacketResponseNG resp; WaitForResponse(CMD_ACK, &resp); iso14a_card_select_t card; @@ -2684,7 +2684,7 @@ static int CmdHF14AMfUPwdGen(const char *Cmd) { if (cmdp == 'r') { // read uid from tag clearCommandBuffer(); - SendCommandMIX(CMD_READER_ISO_14443a, ISO14A_CONNECT | ISO14A_NO_RATS, 0, 0, NULL, 0); + SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT | ISO14A_NO_RATS, 0, 0, NULL, 0); PacketResponseNG resp; WaitForResponse(CMD_ACK, &resp); iso14a_card_select_t card; diff --git a/client/cmdhfthinfilm.c b/client/cmdhfthinfilm.c index 38d7a4c85..928660c6e 100644 --- a/client/cmdhfthinfilm.c +++ b/client/cmdhfthinfilm.c @@ -133,10 +133,10 @@ static int CmdHfThinFilmInfo(const char *Cmd) { int infoThinFilm(bool verbose) { clearCommandBuffer(); - SendCommandNG(CMD_THINFILM_READ, NULL, 0); + SendCommandNG(CMD_HF_THINFILM_READ, NULL, 0); PacketResponseNG resp; - if (!WaitForResponseTimeout(CMD_THINFILM_READ, &resp, 1500)) { + if (!WaitForResponseTimeout(CMD_HF_THINFILM_READ, &resp, 1500)) { PrintAndLogEx(WARNING, "timeout while waiting for reply."); return PM3_ETIMEOUT; } @@ -192,12 +192,12 @@ static int CmdHfThinFilmSim(const char *Cmd) { } clearCommandBuffer(); - SendCommandNG(CMD_SIMULATE_TAG_THINFILM, (uint8_t *)&data, datalen); + SendCommandNG(CMD_HF_THINFILM_SIMULATE, (uint8_t *)&data, datalen); PacketResponseNG resp; PrintAndLogEx(SUCCESS, "press pm3-button to abort simulation"); while (!kbd_enter_pressed()) { - if (WaitForResponseTimeout(CMD_SIMULATE_TAG_THINFILM, &resp, 1500) == 0) continue; + if (WaitForResponseTimeout(CMD_HF_THINFILM_SIMULATE, &resp, 1500) == 0) continue; if (resp.status != PM3_SUCCESS) break; } diff --git a/client/cmdhftopaz.c b/client/cmdhftopaz.c index 3c1cf8672..b7be9a787 100644 --- a/client/cmdhftopaz.c +++ b/client/cmdhftopaz.c @@ -31,16 +31,16 @@ static struct { } topaz_tag; static void topaz_switch_on_field(void) { - SendCommandMIX(CMD_READER_ISO_14443a, ISO14A_CONNECT | ISO14A_NO_SELECT | ISO14A_NO_DISCONNECT | ISO14A_TOPAZMODE | ISO14A_NO_RATS, 0, 0, NULL, 0); + SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT | ISO14A_NO_SELECT | ISO14A_NO_DISCONNECT | ISO14A_TOPAZMODE | ISO14A_NO_RATS, 0, 0, NULL, 0); } static void topaz_switch_off_field(void) { - SendCommandMIX(CMD_READER_ISO_14443a, 0, 0, 0, NULL, 0); + SendCommandMIX(CMD_HF_ISO14443A_READER, 0, 0, 0, NULL, 0); } // send a raw topaz command, returns the length of the response (0 in case of error) static int topaz_send_cmd_raw(uint8_t *cmd, uint8_t len, uint8_t *response, uint16_t *response_len, bool verbose) { - SendCommandOLD(CMD_READER_ISO_14443a, ISO14A_RAW | ISO14A_NO_DISCONNECT | ISO14A_TOPAZMODE | ISO14A_NO_RATS, len, 0, cmd, len); + SendCommandOLD(CMD_HF_ISO14443A_READER, ISO14A_RAW | ISO14A_NO_DISCONNECT | ISO14A_TOPAZMODE | ISO14A_NO_RATS, len, 0, cmd, len); PacketResponseNG resp; diff --git a/client/cmdhw.c b/client/cmdhw.c index 1348f16b4..7ab33cadf 100644 --- a/client/cmdhw.c +++ b/client/cmdhw.c @@ -451,7 +451,7 @@ static int CmdSetDivisor(const char *Cmd) { } // 12 000 000 (12Mhz) clearCommandBuffer(); - SendCommandNG(CMD_SET_LF_DIVISOR, (uint8_t *)&arg, sizeof(arg)); + SendCommandNG(CMD_LF_SET_DIVISOR, (uint8_t *)&arg, sizeof(arg)); PrintAndLogEx(SUCCESS, "Divisor set, expected %.1f kHz", ((double)12000 / (arg + 1))); return PM3_SUCCESS; } diff --git a/client/cmdlf.c b/client/cmdlf.c index 42b26be0d..4831ede0f 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -201,11 +201,11 @@ int CmdLFCommandRead(const char *Cmd) { PrintAndLogEx(SUCCESS, "Sending"); clearCommandBuffer(); - SendCommandNG(CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K, (uint8_t *)&payload, 8 + datalen); + SendCommandNG(CMD_LF_MOD_THEN_ACQ_RAW_ADC, (uint8_t *)&payload, 8 + datalen); printf("\n"); uint8_t i = 10; - while (!WaitForResponseTimeout(CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K, NULL, 2000) && i != 0) { + while (!WaitForResponseTimeout(CMD_LF_MOD_THEN_ACQ_RAW_ADC, NULL, 2000) && i != 0) { printf("."); fflush(stdout); i--; @@ -361,7 +361,7 @@ int CmdLFSetConfig(const char *Cmd) { sample_config config = { decimation, bps, averaging, divisor, trigger_threshold }; clearCommandBuffer(); - SendCommandNG(CMD_SET_LF_SAMPLING_CONFIG, (uint8_t *)&config, sizeof(sample_config)); + SendCommandNG(CMD_LF_SAMPLING_SET_CONFIG, (uint8_t *)&config, sizeof(sample_config)); return PM3_SUCCESS; } @@ -378,13 +378,13 @@ int lf_read(bool silent, uint32_t samples) { payload.samples = samples; clearCommandBuffer(); - SendCommandNG(CMD_ACQUIRE_RAW_ADC_SAMPLES_125K, (uint8_t *)&payload, sizeof(payload)); + SendCommandNG(CMD_LF_ACQ_RAW_ADC, (uint8_t *)&payload, sizeof(payload)); PacketResponseNG resp; if (g_lf_threshold_set) { - WaitForResponse(CMD_ACQUIRE_RAW_ADC_SAMPLES_125K, &resp); + WaitForResponse(CMD_LF_ACQ_RAW_ADC, &resp); } else { - if (!WaitForResponseTimeout(CMD_ACQUIRE_RAW_ADC_SAMPLES_125K, &resp, 2500)) { + if (!WaitForResponseTimeout(CMD_LF_ACQ_RAW_ADC, &resp, 2500)) { PrintAndLogEx(WARNING, "command execution time out"); return PM3_ETIMEOUT; } @@ -438,7 +438,7 @@ int CmdLFSniff(const char *Cmd) { if (cmdp == 'h') return usage_lf_sniff(); clearCommandBuffer(); - SendCommandNG(CMD_LF_SNIFF_RAW_ADC_SAMPLES, NULL, 0); + SendCommandNG(CMD_LF_SNIFF_RAW_ADC, NULL, 0); WaitForResponse(CMD_ACK, NULL); getSamples(0, false); return PM3_SUCCESS; @@ -501,8 +501,8 @@ int CmdLFSim(const char *Cmd) { payload_up.data[j] = GraphBuffer[i + j]; - SendCommandNG(CMD_UPLOAD_SIM_SAMPLES_125K, (uint8_t *)&payload_up, sizeof(struct pupload)); - WaitForResponse(CMD_UPLOAD_SIM_SAMPLES_125K, NULL); + SendCommandNG(CMD_LF_UPLOAD_SIM_SAMPLES, (uint8_t *)&payload_up, sizeof(struct pupload)); + WaitForResponse(CMD_LF_UPLOAD_SIM_SAMPLES, NULL); printf("."); fflush(stdout); payload_up.flag = 0; @@ -522,10 +522,10 @@ int CmdLFSim(const char *Cmd) { payload.gap = gap; clearCommandBuffer(); - SendCommandNG(CMD_SIMULATE_TAG_125K, (uint8_t *)&payload, sizeof(payload)); + SendCommandNG(CMD_LF_SIMULATE, (uint8_t *)&payload, sizeof(payload)); PacketResponseNG resp; - WaitForResponse(CMD_SIMULATE_TAG_125K, &resp); + WaitForResponse(CMD_LF_SIMULATE, &resp); PrintAndLogEx(INFO, "Done"); if (resp.status != PM3_EOPABORTED) @@ -624,12 +624,12 @@ int CmdLFfskSim(const char *Cmd) { PrintAndLogEx(INFO, "Simulating"); clearCommandBuffer(); - SendCommandNG(CMD_FSK_SIM_TAG, (uint8_t *)payload, sizeof(lf_fsksim_t) + size); + SendCommandNG(CMD_LF_FSK_SIMULATE, (uint8_t *)payload, sizeof(lf_fsksim_t) + size); free(payload); setClockGrid(clk, 0); PacketResponseNG resp; - WaitForResponse(CMD_FSK_SIM_TAG, &resp); + WaitForResponse(CMD_LF_FSK_SIMULATE, &resp); PrintAndLogEx(INFO, "Done"); if (resp.status != PM3_EOPABORTED) @@ -726,11 +726,11 @@ int CmdLFaskSim(const char *Cmd) { PrintAndLogEx(INFO, "Simulating"); clearCommandBuffer(); - SendCommandNG(CMD_ASK_SIM_TAG, (uint8_t *)payload, sizeof(lf_asksim_t) + size); + SendCommandNG(CMD_LF_ASK_SIMULATE, (uint8_t *)payload, sizeof(lf_asksim_t) + size); free(payload); PacketResponseNG resp; - WaitForResponse(CMD_ASK_SIM_TAG, &resp); + WaitForResponse(CMD_LF_ASK_SIMULATE, &resp); PrintAndLogEx(INFO, "Done"); if (resp.status != PM3_EOPABORTED) @@ -845,11 +845,11 @@ int CmdLFpskSim(const char *Cmd) { PrintAndLogEx(INFO, "Simulating"); clearCommandBuffer(); - SendCommandNG(CMD_PSK_SIM_TAG, (uint8_t *)payload, sizeof(lf_psksim_t) + size); + SendCommandNG(CMD_LF_PSK_SIMULATE, (uint8_t *)payload, sizeof(lf_psksim_t) + size); free(payload); PacketResponseNG resp; - WaitForResponse(CMD_PSK_SIM_TAG, &resp); + WaitForResponse(CMD_LF_PSK_SIMULATE, &resp); PrintAndLogEx(INFO, "Done"); if (resp.status != PM3_EOPABORTED) diff --git a/client/cmdlfawid.c b/client/cmdlfawid.c index 386d14e5e..09a73aca5 100644 --- a/client/cmdlfawid.c +++ b/client/cmdlfawid.c @@ -115,7 +115,7 @@ static int sendTry(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint32_t delay, uin memcpy(payload->data, bits, bs_len); clearCommandBuffer(); - SendCommandNG(CMD_FSK_SIM_TAG, (uint8_t *)payload, sizeof(lf_fsksim_t) + bs_len); + SendCommandNG(CMD_LF_FSK_SIMULATE, (uint8_t *)payload, sizeof(lf_fsksim_t) + bs_len); free(payload); msleep(delay); @@ -172,7 +172,7 @@ static int CmdAWIDRead_device(const char *Cmd) { if (Cmd[0] == 'h' || Cmd[0] == 'H') return usage_lf_awid_read(); uint8_t findone = (Cmd[0] == '1') ? 1 : 0; clearCommandBuffer(); - SendCommandMIX(CMD_AWID_DEMOD_FSK, findone, 0, 0, NULL, 0); + SendCommandMIX(CMD_LF_AWID_DEMOD, findone, 0, 0, NULL, 0); return PM3_SUCCESS; } */ @@ -352,11 +352,11 @@ static int CmdAWIDSim(const char *Cmd) { memcpy(payload->data, bs, sizeof(bs)); clearCommandBuffer(); - SendCommandNG(CMD_FSK_SIM_TAG, (uint8_t *)payload, sizeof(lf_fsksim_t) + sizeof(bs)); + SendCommandNG(CMD_LF_FSK_SIMULATE, (uint8_t *)payload, sizeof(lf_fsksim_t) + sizeof(bs)); free(payload); PacketResponseNG resp; - WaitForResponse(CMD_FSK_SIM_TAG, &resp); + WaitForResponse(CMD_LF_FSK_SIMULATE, &resp); PrintAndLogEx(INFO, "Done"); if (resp.status != PM3_EOPABORTED) @@ -417,8 +417,8 @@ static int CmdAWIDClone(const char *Cmd) { ng.blockno = i; ng.flags = 0; - SendCommandNG(CMD_T55XX_WRITE_BLOCK, (uint8_t *)&ng, sizeof(ng)); - if (!WaitForResponseTimeout(CMD_T55XX_WRITE_BLOCK, &resp, T55XX_WRITE_TIMEOUT)) { + SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng)); + if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, T55XX_WRITE_TIMEOUT)) { PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); return PM3_ETIMEOUT; } diff --git a/client/cmdlfcotag.c b/client/cmdlfcotag.c index 134d55c68..338c0a6d6 100644 --- a/client/cmdlfcotag.c +++ b/client/cmdlfcotag.c @@ -75,7 +75,7 @@ static int CmdCOTAGRead(const char *Cmd) { sscanf(Cmd, "%u", &rawsignal); clearCommandBuffer(); - SendCommandMIX(CMD_COTAG, rawsignal, 0, 0, NULL, 0); + SendCommandMIX(CMD_LF_COTAG_READ, rawsignal, 0, 0, NULL, 0); if (!WaitForResponseTimeout(CMD_ACK, NULL, 7000)) { PrintAndLogEx(WARNING, "command execution time out"); return PM3_ETIMEOUT; diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c index 165f22001..77c653160 100644 --- a/client/cmdlfem4x.c +++ b/client/cmdlfem4x.c @@ -401,7 +401,7 @@ int AskEm410xDemod(const char *Cmd, uint32_t *hi, uint64_t *lo, bool verbose) { static int CmdEM410xRead_device(const char *Cmd) { char cmdp = tolower(param_getchar(Cmd, 0)); uint8_t findone = (cmdp == '1') ? 1 : 0; - SendCommandMIX(CMD_EM410X_DEMOD, findone, 0, 0, NULL, 0); + SendCommandMIX(CMD_LF_EM410X_DEMOD, findone, 0, 0, NULL, 0); return PM3_SUCCESS; } */ @@ -645,7 +645,7 @@ static int CmdEM410xWrite(const char *Cmd) { PrintAndLogEx(SUCCESS, "Writing %s tag with UID 0x%010" PRIx64 " (clock rate: %d)", "T55x7", id, clock1); // NOTE: We really should pass the clock in as a separate argument, but to // provide for backwards-compatibility for older firmware, and to avoid - // having to add another argument to CMD_EM410X_WRITE_TAG, we just store + // having to add another argument to CMD_LF_EM410X_WRITE, we just store // the clock rate in bits 8-15 of the card value card = (card & 0xFF) | ((clock1 << 8) & 0xFF00); } else if (card == 0) { @@ -656,7 +656,7 @@ static int CmdEM410xWrite(const char *Cmd) { return PM3_ESOFT; } - SendCommandMIX(CMD_EM410X_WRITE_TAG, card, (uint32_t)(id >> 32), (uint32_t)id, NULL, 0); + SendCommandMIX(CMD_LF_EM410X_WRITE, card, (uint32_t)(id >> 32), (uint32_t)id, NULL, 0); return PM3_SUCCESS; } @@ -1147,9 +1147,9 @@ static int EM4x05ReadWord_ext(uint8_t addr, uint32_t pwd, bool usePwd, uint32_t payload.usepwd = usePwd; clearCommandBuffer(); - SendCommandNG(CMD_EM4X_READ_WORD, (uint8_t *)&payload, sizeof(payload)); + SendCommandNG(CMD_LF_EM4X_READWORD, (uint8_t *)&payload, sizeof(payload)); PacketResponseNG resp; - if (!WaitForResponseTimeout(CMD_EM4X_READ_WORD, &resp, 2500)) { + if (!WaitForResponseTimeout(CMD_LF_EM4X_READWORD, &resp, 2500)) { PrintAndLogEx(DEBUG, "timeout while waiting for reply."); return PM3_ETIMEOUT; } @@ -1259,9 +1259,9 @@ static int CmdEM4x05Write(const char *Cmd) { payload.usepwd = usePwd; clearCommandBuffer(); - SendCommandNG(CMD_EM4X_WRITE_WORD, (uint8_t *)&payload, sizeof(payload)); + SendCommandNG(CMD_LF_EM4X_WRITEWORD, (uint8_t *)&payload, sizeof(payload)); PacketResponseNG resp; - if (!WaitForResponseTimeout(CMD_EM4X_WRITE_WORD, &resp, 2000)) { + if (!WaitForResponseTimeout(CMD_LF_EM4X_WRITEWORD, &resp, 2000)) { PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); return PM3_ETIMEOUT; } diff --git a/client/cmdlffdx.c b/client/cmdlffdx.c index 35f3216ad..a13c1e947 100644 --- a/client/cmdlffdx.c +++ b/client/cmdlffdx.c @@ -298,8 +298,8 @@ static int CmdFdxClone(const char *Cmd) { ng.blockno = i; ng.flags = 0; - SendCommandNG(CMD_T55XX_WRITE_BLOCK, (uint8_t *)&ng, sizeof(ng)); - if (!WaitForResponseTimeout(CMD_T55XX_WRITE_BLOCK, &resp, T55XX_WRITE_TIMEOUT)) { + SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng)); + if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, T55XX_WRITE_TIMEOUT)) { PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); return PM3_ETIMEOUT; } @@ -334,11 +334,11 @@ static int CmdFdxSim(const char *Cmd) { memcpy(payload->data, bs, sizeof(bs)); clearCommandBuffer(); - SendCommandNG(CMD_ASK_SIM_TAG, (uint8_t *)payload, sizeof(lf_asksim_t) + sizeof(bs)); + SendCommandNG(CMD_LF_ASK_SIMULATE, (uint8_t *)payload, sizeof(lf_asksim_t) + sizeof(bs)); free(payload); PacketResponseNG resp; - WaitForResponse(CMD_ASK_SIM_TAG, &resp); + WaitForResponse(CMD_LF_ASK_SIMULATE, &resp); PrintAndLogEx(INFO, "Done"); if (resp.status != PM3_EOPABORTED) diff --git a/client/cmdlfguard.c b/client/cmdlfguard.c index 1b09eb18d..19f23088e 100644 --- a/client/cmdlfguard.c +++ b/client/cmdlfguard.c @@ -187,8 +187,8 @@ static int CmdGuardClone(const char *Cmd) { ng.blockno = i; ng.flags = 0; - SendCommandNG(CMD_T55XX_WRITE_BLOCK, (uint8_t *)&ng, sizeof(ng)); - if (!WaitForResponseTimeout(CMD_T55XX_WRITE_BLOCK, &resp, T55XX_WRITE_TIMEOUT)) { + SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng)); + if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, T55XX_WRITE_TIMEOUT)) { PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); return PM3_ETIMEOUT; } @@ -228,11 +228,11 @@ static int CmdGuardSim(const char *Cmd) { memcpy(payload->data, bs, sizeof(bs)); clearCommandBuffer(); - SendCommandNG(CMD_ASK_SIM_TAG, (uint8_t *)payload, sizeof(lf_asksim_t) + sizeof(bs)); + SendCommandNG(CMD_LF_ASK_SIMULATE, (uint8_t *)payload, sizeof(lf_asksim_t) + sizeof(bs)); free(payload); PacketResponseNG resp; - WaitForResponse(CMD_ASK_SIM_TAG, &resp); + WaitForResponse(CMD_LF_ASK_SIMULATE, &resp); PrintAndLogEx(INFO, "Done"); if (resp.status != PM3_EOPABORTED) diff --git a/client/cmdlfhid.c b/client/cmdlfhid.c index 56f9667a3..57df08d5d 100644 --- a/client/cmdlfhid.c +++ b/client/cmdlfhid.c @@ -111,7 +111,7 @@ static int sendTry(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint32_t delay, uin calcWiegand(fmtlen, fc, cn, bits, 0); clearCommandBuffer(); - SendCommandMIX(CMD_HID_SIM_TAG, bytebits_to_byte(bits, 32), bytebits_to_byte(bits + 32, 32), 0, NULL, 0); + SendCommandMIX(CMD_LF_HID_SIMULATE, bytebits_to_byte(bits, 32), bytebits_to_byte(bits + 32, 32), 0, NULL, 0); msleep(delay); return sendPing(); @@ -240,7 +240,7 @@ static int CmdHIDRead_device(const char *Cmd) { if (Cmd[0] == 'h' || Cmd[0] == 'H') return usage_lf_hid_read(); uint8_t findone = (Cmd[0] == '1') ? 1 : 0; clearCommandBuffer(); - SendCommandMIX(CMD_HID_DEMOD_FSK, findone, 0, 0, NULL, 0); + SendCommandMIX(CMD_LF_HID_DEMOD, findone, 0, 0, NULL, 0); return PM3_SUCCESS; } */ @@ -260,9 +260,9 @@ static int CmdHIDSim(const char *Cmd) { PrintAndLogEx(SUCCESS, "Press pm3-button to abort simulation"); clearCommandBuffer(); - SendCommandMIX(CMD_HID_SIM_TAG, hi, lo, 0, NULL, 0); + SendCommandMIX(CMD_LF_HID_SIMULATE, hi, lo, 0, NULL, 0); PacketResponseNG resp; - WaitForResponse(CMD_HID_SIM_TAG, &resp); + WaitForResponse(CMD_LF_HID_SIMULATE, &resp); PrintAndLogEx(INFO, "Done"); if (resp.status != PM3_EOPABORTED) return resp.status; @@ -297,7 +297,7 @@ static int CmdHIDClone(const char *Cmd) { } clearCommandBuffer(); - SendCommandOLD(CMD_HID_CLONE_TAG, hi2, hi, lo, longid, sizeof(longid)); + SendCommandOLD(CMD_LF_HID_CLONE, hi2, hi, lo, longid, sizeof(longid)); return PM3_SUCCESS; } diff --git a/client/cmdlfhitag.c b/client/cmdlfhitag.c index 0fc4b053c..07b00839e 100644 --- a/client/cmdlfhitag.c +++ b/client/cmdlfhitag.c @@ -262,7 +262,7 @@ static int CmdLFHitagSniff(const char *Cmd) { if (ctmp == 'h') return usage_hitag_sniff(); clearCommandBuffer(); - SendCommandNG(CMD_SNIFF_HITAG, NULL, 0); + SendCommandNG(CMD_LF_HITAG_SNIFF, NULL, 0); return 0; } @@ -277,7 +277,7 @@ static int CmdLFHitagSim(const char *Cmd) { int res = 0; char filename[FILE_PATH_SIZE] = { 0x00 }; - uint16_t cmd = CMD_SIMULATE_HITAG; + uint16_t cmd = CMD_LF_HITAG_SIMULATE; while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { case 'h': @@ -288,7 +288,7 @@ static int CmdLFHitagSim(const char *Cmd) { cmdp++; break; case 's': - cmd = CMD_SIMULATE_HITAG_S; + cmd = CMD_LF_HITAGS_SIMULATE; maxdatalen = 4 * 64; cmdp++; break; @@ -459,7 +459,7 @@ static bool getHitagUid(uint32_t *uid) { hitag_data htd; memset(&htd, 0, sizeof(htd)); clearCommandBuffer(); - SendCommandMIX(CMD_READER_HITAG, RHT2F_UID_ONLY, 0, 0, &htd, sizeof(htd)); + SendCommandMIX(CMD_LF_HITAG_READER, RHT2F_UID_ONLY, 0, 0, &htd, sizeof(htd)); PacketResponseNG resp; if (!WaitForResponseTimeout(CMD_ACK, &resp, 2500)) { PrintAndLogEx(WARNING, "timeout while waiting for reply."); @@ -512,19 +512,19 @@ static int CmdLFHitagInfo(const char *Cmd) { // static int CmdLFHitagReader(const char *Cmd) { - uint16_t cmd = CMD_READER_HITAG; + uint16_t cmd = CMD_LF_HITAG_READER; hitag_data htd; hitag_function htf = param_get32ex(Cmd, 0, 0, 10); switch (htf) { case RHTSF_CHALLENGE: { - cmd = CMD_READ_HITAG_S; + cmd = CMD_LF_HITAGS_READ; num_to_bytes(param_get32ex(Cmd, 1, 0, 16), 4, htd.auth.NrAr); num_to_bytes(param_get32ex(Cmd, 2, 0, 16), 4, htd.auth.NrAr + 4); break; } case RHTSF_KEY: { - cmd = CMD_READ_HITAG_S; + cmd = CMD_LF_HITAGS_READ; num_to_bytes(param_get64ex(Cmd, 1, 0, 16), 6, htd.crypto.key); break; } @@ -633,9 +633,9 @@ static int CmdLFHitagCheckChallenges(const char *Cmd) { clearCommandBuffer(); if (file_given) - SendCommandOLD(CMD_TEST_HITAGS_TRACES, 1, 0, 0, data, datalen); + SendCommandOLD(CMD_LF_HITAGS_TEST_TRACES, 1, 0, 0, data, datalen); else - SendCommandMIX(CMD_TEST_HITAGS_TRACES, 0, 0, 0, NULL, 0); + SendCommandMIX(CMD_LF_HITAGS_TEST_TRACES, 0, 0, 0, NULL, 0); free(data); return 0; @@ -678,7 +678,7 @@ static int CmdLFHitagWriter(const char *Cmd) { } clearCommandBuffer(); - SendCommandOLD(CMD_WR_HITAG_S, htf, 0, arg2, &htd, sizeof(htd)); + SendCommandOLD(CMD_LF_HITAGS_WRITE, htf, 0, arg2, &htd, sizeof(htd)); PacketResponseNG resp; if (!WaitForResponseTimeout(CMD_ACK, &resp, 4000)) { PrintAndLogEx(WARNING, "timeout while waiting for reply."); diff --git a/client/cmdlfindala.c b/client/cmdlfindala.c index 41c292a5b..f7dc65271 100644 --- a/client/cmdlfindala.c +++ b/client/cmdlfindala.c @@ -411,11 +411,11 @@ static int CmdIndalaSim(const char *Cmd) { PrintAndLogEx(INFO, "Simulating"); clearCommandBuffer(); - SendCommandNG(CMD_PSK_SIM_TAG, (uint8_t *)payload, sizeof(lf_psksim_t) + sizeof(bs)); + SendCommandNG(CMD_LF_PSK_SIMULATE, (uint8_t *)payload, sizeof(lf_psksim_t) + sizeof(bs)); free(payload); PacketResponseNG resp; - WaitForResponse(CMD_PSK_SIM_TAG, &resp); + WaitForResponse(CMD_LF_PSK_SIMULATE, &resp); PrintAndLogEx(INFO, "Done"); if (resp.status != PM3_EOPABORTED) @@ -461,14 +461,14 @@ static int CmdIndalaClone(const char *Cmd) { datawords[5] = bytes_to_num(data + 20, 4); datawords[6] = bytes_to_num(data + 24, 4); clearCommandBuffer(); - SendCommandOLD(CMD_INDALA_CLONE_TAG_L, 0, 0, 0, datawords, sizeof(datawords)); + SendCommandOLD(CMD_LF_INDALA224_CLONE, 0, 0, 0, datawords, sizeof(datawords)); } else { PrintAndLogEx(INFO, "Preparing to clone Indala 64bit tag with RawID %s", sprint_hex(data, datalen)); uint32_t datawords[2] = {0}; datawords[0] = bytes_to_num(data, 4); datawords[1] = bytes_to_num(data + 4, 4); clearCommandBuffer(); - SendCommandOLD(CMD_INDALA_CLONE_TAG, 0, 0, 0, datawords, sizeof(datawords)); + SendCommandOLD(CMD_LF_INDALA_CLONE, 0, 0, 0, datawords, sizeof(datawords)); } return PM3_SUCCESS; diff --git a/client/cmdlfio.c b/client/cmdlfio.c index d187daaab..b1605ecfa 100644 --- a/client/cmdlfio.c +++ b/client/cmdlfio.c @@ -67,7 +67,7 @@ static int CmdIOProxRead_device(const char *Cmd) { if (Cmd[0] == 'h' || Cmd[0] == 'H') return usage_lf_io_read(); int findone = (Cmd[0] == '1') ? 1 : 0; clearCommandBuffer(); - SendCommandMIX(CMD_IO_DEMOD_FSK, findone, 0, 0, NULL, 0); + SendCommandMIX(CMD_LF_IO_DEMOD, findone, 0, 0, NULL, 0); return PM3_SUCCESS; } */ @@ -214,11 +214,11 @@ static int CmdIOProxSim(const char *Cmd) { memcpy(payload->data, bs, sizeof(bs)); clearCommandBuffer(); - SendCommandNG(CMD_FSK_SIM_TAG, (uint8_t *)payload, sizeof(lf_fsksim_t) + sizeof(bs)); + SendCommandNG(CMD_LF_FSK_SIMULATE, (uint8_t *)payload, sizeof(lf_fsksim_t) + sizeof(bs)); free(payload); PacketResponseNG resp; - WaitForResponse(CMD_FSK_SIM_TAG, &resp); + WaitForResponse(CMD_LF_FSK_SIMULATE, &resp); PrintAndLogEx(INFO, "Done"); if (resp.status != PM3_EOPABORTED) @@ -263,7 +263,7 @@ static int CmdIOProxClone(const char *Cmd) { print_blocks(blocks, 3); clearCommandBuffer(); - SendCommandMIX(CMD_IO_CLONE_TAG, blocks[1], blocks[2], 0, NULL, 0); + SendCommandMIX(CMD_LF_IO_CLONE, blocks[1], blocks[2], 0, NULL, 0); return PM3_SUCCESS; } diff --git a/client/cmdlfjablotron.c b/client/cmdlfjablotron.c index c2478705c..11370e286 100644 --- a/client/cmdlfjablotron.c +++ b/client/cmdlfjablotron.c @@ -172,8 +172,8 @@ static int CmdJablotronClone(const char *Cmd) { ng.blockno = i; ng.flags = 0; - SendCommandNG(CMD_T55XX_WRITE_BLOCK, (uint8_t *)&ng, sizeof(ng)); - if (!WaitForResponseTimeout(CMD_T55XX_WRITE_BLOCK, &resp, T55XX_WRITE_TIMEOUT)) { + SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng)); + if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, T55XX_WRITE_TIMEOUT)) { PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); return PM3_ETIMEOUT; } @@ -208,11 +208,11 @@ static int CmdJablotronSim(const char *Cmd) { memcpy(payload->data, bs, sizeof(bs)); clearCommandBuffer(); - SendCommandNG(CMD_ASK_SIM_TAG, (uint8_t *)payload, sizeof(lf_asksim_t) + sizeof(bs)); + SendCommandNG(CMD_LF_ASK_SIMULATE, (uint8_t *)payload, sizeof(lf_asksim_t) + sizeof(bs)); free(payload); PacketResponseNG resp; - WaitForResponse(CMD_ASK_SIM_TAG, &resp); + WaitForResponse(CMD_LF_ASK_SIMULATE, &resp); PrintAndLogEx(INFO, "Done"); if (resp.status != PM3_EOPABORTED) diff --git a/client/cmdlfkeri.c b/client/cmdlfkeri.c index b3761055f..a71687a62 100644 --- a/client/cmdlfkeri.c +++ b/client/cmdlfkeri.c @@ -162,8 +162,8 @@ static int CmdKeriClone(const char *Cmd) { ng.blockno = i; ng.flags = 0; - SendCommandNG(CMD_T55XX_WRITE_BLOCK, (uint8_t *)&ng, sizeof(ng)); - if (!WaitForResponseTimeout(CMD_T55XX_WRITE_BLOCK, &resp, T55XX_WRITE_TIMEOUT)) { + SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng)); + if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, T55XX_WRITE_TIMEOUT)) { PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); return PM3_ETIMEOUT; } @@ -201,11 +201,11 @@ static int CmdKeriSim(const char *Cmd) { PrintAndLogEx(INFO, "Simulating"); clearCommandBuffer(); - SendCommandNG(CMD_PSK_SIM_TAG, (uint8_t *)payload, sizeof(lf_psksim_t) + sizeof(bs)); + SendCommandNG(CMD_LF_PSK_SIMULATE, (uint8_t *)payload, sizeof(lf_psksim_t) + sizeof(bs)); free(payload); PacketResponseNG resp; - WaitForResponse(CMD_PSK_SIM_TAG, &resp); + WaitForResponse(CMD_LF_PSK_SIMULATE, &resp); PrintAndLogEx(INFO, "Done"); if (resp.status != PM3_EOPABORTED) diff --git a/client/cmdlfnedap.c b/client/cmdlfnedap.c index 0b998d716..c8a851ea6 100644 --- a/client/cmdlfnedap.c +++ b/client/cmdlfnedap.c @@ -218,8 +218,8 @@ static int CmdLFNedapClone(const char *Cmd) { ng.blockno = i; ng.flags = 0; - SendCommandNG(CMD_T55XX_WRITE_BLOCK, (uint8_t *)&ng, sizeof(ng)); - if (!WaitForResponseTimeout(CMD_T55XX_WRITE_BLOCK, &resp, T55XX_WRITE_TIMEOUT)) { + SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng)); + if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, T55XX_WRITE_TIMEOUT)) { PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); return PM3_ETIMEOUT; } @@ -259,11 +259,11 @@ static int CmdLFNedapSim(const char *Cmd) { memcpy(payload->data, bs, sizeof(bs)); clearCommandBuffer(); - SendCommandNG(CMD_ASK_SIM_TAG, (uint8_t *)payload, sizeof(lf_asksim_t) + sizeof(bs)); + SendCommandNG(CMD_LF_ASK_SIMULATE, (uint8_t *)payload, sizeof(lf_asksim_t) + sizeof(bs)); free(payload); PacketResponseNG resp; - WaitForResponse(CMD_ASK_SIM_TAG, &resp); + WaitForResponse(CMD_LF_ASK_SIMULATE, &resp); PrintAndLogEx(INFO, "Done"); if (resp.status != PM3_EOPABORTED) diff --git a/client/cmdlfnoralsy.c b/client/cmdlfnoralsy.c index 34ad1023f..a6c58a3ed 100644 --- a/client/cmdlfnoralsy.c +++ b/client/cmdlfnoralsy.c @@ -170,8 +170,8 @@ static int CmdNoralsyClone(const char *Cmd) { ng.blockno = i; ng.flags = 0; - SendCommandNG(CMD_T55XX_WRITE_BLOCK, (uint8_t *)&ng, sizeof(ng)); - if (!WaitForResponseTimeout(CMD_T55XX_WRITE_BLOCK, &resp, T55XX_WRITE_TIMEOUT)) { + SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng)); + if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, T55XX_WRITE_TIMEOUT)) { PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); return PM3_ETIMEOUT; } @@ -209,11 +209,11 @@ static int CmdNoralsySim(const char *Cmd) { memcpy(payload->data, bs, sizeof(bs)); clearCommandBuffer(); - SendCommandNG(CMD_ASK_SIM_TAG, (uint8_t *)payload, sizeof(lf_asksim_t) + sizeof(bs)); + SendCommandNG(CMD_LF_ASK_SIMULATE, (uint8_t *)payload, sizeof(lf_asksim_t) + sizeof(bs)); free(payload); PacketResponseNG resp; - WaitForResponse(CMD_ASK_SIM_TAG, &resp); + WaitForResponse(CMD_LF_ASK_SIMULATE, &resp); PrintAndLogEx(INFO, "Done"); if (resp.status != PM3_EOPABORTED) diff --git a/client/cmdlfparadox.c b/client/cmdlfparadox.c index c5c022d9b..d18c501ca 100644 --- a/client/cmdlfparadox.c +++ b/client/cmdlfparadox.c @@ -142,11 +142,11 @@ static int CmdParadoxSim(const char *Cmd) { memcpy(payload->data, bs, sizeof(bs)); clearCommandBuffer(); - SendCommandNG(CMD_FSK_SIM_TAG, (uint8_t *)payload, sizeof(lf_fsksim_t) + sizeof(bs)); + SendCommandNG(CMD_LF_FSK_SIMULATE, (uint8_t *)payload, sizeof(lf_fsksim_t) + sizeof(bs)); free(payload); PacketResponseNG resp; - WaitForResponse(CMD_FSK_SIM_TAG, &resp); + WaitForResponse(CMD_LF_FSK_SIMULATE, &resp); PrintAndLogEx(INFO, "Done"); if (resp.status != PM3_EOPABORTED) diff --git a/client/cmdlfpcf7931.c b/client/cmdlfpcf7931.c index c9f5711ef..a9ab9cf3e 100644 --- a/client/cmdlfpcf7931.c +++ b/client/cmdlfpcf7931.c @@ -101,7 +101,7 @@ static int CmdLFPCF7931Read(const char *Cmd) { PacketResponseNG resp; clearCommandBuffer(); - SendCommandNG(CMD_PCF7931_READ, NULL, 0); + SendCommandNG(CMD_LF_PCF7931_READ, NULL, 0); if (!WaitForResponseTimeout(CMD_ACK, &resp, 2500)) { PrintAndLogEx(WARNING, "command execution time out"); return 1; @@ -151,7 +151,7 @@ static int CmdLFPCF7931Write(const char *Cmd) { buf[9] = configPcf.InitDelay; clearCommandBuffer(); - SendCommandOLD(CMD_PCF7931_WRITE, block, bytepos, data, buf, sizeof(buf)); + SendCommandOLD(CMD_LF_PCF7931_WRITE, block, bytepos, data, buf, sizeof(buf)); //no ack? return 0; } diff --git a/client/cmdlfpresco.c b/client/cmdlfpresco.c index 3f1ce71f3..cbf919aef 100644 --- a/client/cmdlfpresco.c +++ b/client/cmdlfpresco.c @@ -136,8 +136,8 @@ static int CmdPrescoClone(const char *Cmd) { ng.blockno = i; ng.flags = 0; - SendCommandNG(CMD_T55XX_WRITE_BLOCK, (uint8_t *)&ng, sizeof(ng)); - if (!WaitForResponseTimeout(CMD_T55XX_WRITE_BLOCK, &resp, T55XX_WRITE_TIMEOUT)) { + SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng)); + if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, T55XX_WRITE_TIMEOUT)) { PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); return PM3_ETIMEOUT; } @@ -167,11 +167,11 @@ static int CmdPrescoSim(const char *Cmd) { memcpy(payload->data, bs, sizeof(bs)); clearCommandBuffer(); - SendCommandNG(CMD_ASK_SIM_TAG, (uint8_t *)payload, sizeof(lf_asksim_t) + sizeof(bs)); + SendCommandNG(CMD_LF_ASK_SIMULATE, (uint8_t *)payload, sizeof(lf_asksim_t) + sizeof(bs)); free(payload); PacketResponseNG resp; - WaitForResponse(CMD_ASK_SIM_TAG, &resp); + WaitForResponse(CMD_LF_ASK_SIMULATE, &resp); PrintAndLogEx(INFO, "Done"); if (resp.status != PM3_EOPABORTED) diff --git a/client/cmdlfpyramid.c b/client/cmdlfpyramid.c index 4e5588ec6..b36d386c9 100644 --- a/client/cmdlfpyramid.c +++ b/client/cmdlfpyramid.c @@ -247,8 +247,8 @@ static int CmdPyramidClone(const char *Cmd) { ng.blockno = i; ng.flags = 0; - SendCommandNG(CMD_T55XX_WRITE_BLOCK, (uint8_t *)&ng, sizeof(ng)); - if (!WaitForResponseTimeout(CMD_T55XX_WRITE_BLOCK, &resp, T55XX_WRITE_TIMEOUT)) { + SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng)); + if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, T55XX_WRITE_TIMEOUT)) { PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); return PM3_ETIMEOUT; } @@ -287,11 +287,11 @@ static int CmdPyramidSim(const char *Cmd) { memcpy(payload->data, bs, sizeof(bs)); clearCommandBuffer(); - SendCommandNG(CMD_FSK_SIM_TAG, (uint8_t *)payload, sizeof(lf_fsksim_t) + sizeof(bs)); + SendCommandNG(CMD_LF_FSK_SIMULATE, (uint8_t *)payload, sizeof(lf_fsksim_t) + sizeof(bs)); free(payload); PacketResponseNG resp; - WaitForResponse(CMD_FSK_SIM_TAG, &resp); + WaitForResponse(CMD_LF_FSK_SIMULATE, &resp); PrintAndLogEx(INFO, "Done"); if (resp.status != PM3_EOPABORTED) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 398aa6988..be24be976 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -1136,7 +1136,7 @@ static int CmdT55xxWakeUp(const char *Cmd) { flags = (downlink_mode & 3) << 3; clearCommandBuffer(); - SendCommandMIX(CMD_T55XX_WAKEUP, password, flags, 0, NULL, 0); + SendCommandMIX(CMD_LF_T55XX_WAKEUP, password, flags, 0, NULL, 0); PrintAndLogEx(SUCCESS, "Wake up command sent. Try read now"); return PM3_SUCCESS; @@ -1228,8 +1228,8 @@ static int CmdT55xxWriteBlock(const char *Cmd) { ng.blockno = block; ng.flags = flags; - SendCommandNG(CMD_T55XX_WRITE_BLOCK, (uint8_t *)&ng, sizeof(ng)); - if (!WaitForResponseTimeout(CMD_T55XX_WRITE_BLOCK, &resp, 2000)) { + SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng)); + if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, 2000)) { PrintAndLogEx(ERR, "Error occurred, device did not ACK write operation. (May be due to old firmware)"); return PM3_ETIMEOUT; } @@ -1696,8 +1696,8 @@ bool AquireData(uint8_t page, uint8_t block, bool pwdmode, uint32_t password, ui payload.downlink_mode = downlink_mode; clearCommandBuffer(); - SendCommandNG(CMD_T55XX_READ_BLOCK, (uint8_t *)&payload, sizeof(payload)); - if (!WaitForResponseTimeout(CMD_T55XX_READ_BLOCK, NULL, 2500)) { + SendCommandNG(CMD_LF_T55XX_READBL, (uint8_t *)&payload, sizeof(payload)); + if (!WaitForResponseTimeout(CMD_LF_T55XX_READBL, NULL, 2500)) { PrintAndLogEx(WARNING, "command execution time out"); return false; } @@ -1966,7 +1966,7 @@ static int CmdResetRead(const char *Cmd) { printf("DL : %d\n", downlink_mode); flags = downlink_mode << 3; clearCommandBuffer(); - SendCommandNG(CMD_T55XX_RESET_READ, &flags, sizeof(flags)); + SendCommandNG(CMD_LF_T55XX_RESET_READ, &flags, sizeof(flags)); if (!WaitForResponseTimeout(CMD_ACK, NULL, 2500)) { PrintAndLogEx(WARNING, "command execution time out"); return PM3_ETIMEOUT; @@ -2076,7 +2076,7 @@ static int CmdT55xxChkPwds(const char *Cmd) { if (from_flash) { clearCommandBuffer(); - SendCommandNG(CMD_T55XX_CHKPWDS, &flags, sizeof(flags)); + SendCommandNG(CMD_LF_T55XX_CHK_PWDS, &flags, sizeof(flags)); PacketResponseNG resp; while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { @@ -2649,7 +2649,7 @@ static int CmdT55xxSetDeviceConfig(const char *Cmd) { } clearCommandBuffer(); - SendCommandOLD(CMD_SET_LF_T55XX_CONFIG, shall_persist, 0, 0, &configurations, sizeof(t55xx_configurations_t)); + SendCommandOLD(CMD_LF_T55XX_SET_CONFIG, shall_persist, 0, 0, &configurations, sizeof(t55xx_configurations_t)); return PM3_SUCCESS; } diff --git a/client/cmdlfti.c b/client/cmdlfti.c index 017df6e75..9e07926f4 100644 --- a/client/cmdlfti.c +++ b/client/cmdlfti.c @@ -276,7 +276,7 @@ out: static int CmdTIRead(const char *Cmd) { (void)Cmd; // Cmd is not used so far clearCommandBuffer(); - SendCommandNG(CMD_READ_TI_TYPE, NULL, 0); + SendCommandNG(CMD_LF_TI_READ, NULL, 0); return PM3_SUCCESS; } @@ -294,7 +294,7 @@ static int CmdTIWrite(const char *Cmd) { return PM3_EINVARG; } clearCommandBuffer(); - SendCommandMIX(CMD_WRITE_TI_TYPE, arg0, arg1, arg2, NULL, 0); + SendCommandMIX(CMD_LF_TI_WRITE, arg0, arg1, arg2, NULL, 0); return PM3_SUCCESS; } diff --git a/client/cmdlfviking.c b/client/cmdlfviking.c index 41193ea12..1d2114e95 100644 --- a/client/cmdlfviking.c +++ b/client/cmdlfviking.c @@ -88,7 +88,7 @@ static int CmdVikingClone(const char *Cmd) { PrintAndLogEx(INFO, "Preparing to clone Viking tag - ID " _YELLOW_("%08X")" raw " _YELLOW_("%08X%08X"), id, (uint32_t)(rawID >> 32), (uint32_t)(rawID & 0xFFFFFFFF)); clearCommandBuffer(); - SendCommandMIX(CMD_VIKING_CLONE_TAG, rawID >> 32, rawID & 0xFFFFFFFF, Q5, NULL, 0); + SendCommandMIX(CMD_LF_VIKING_CLONE, rawID >> 32, rawID & 0xFFFFFFFF, Q5, NULL, 0); PacketResponseNG resp; if (!WaitForResponseTimeout(CMD_ACK, &resp, T55XX_WRITE_TIMEOUT)) { PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); @@ -121,11 +121,11 @@ static int CmdVikingSim(const char *Cmd) { memcpy(payload->data, bs, sizeof(bs)); clearCommandBuffer(); - SendCommandNG(CMD_ASK_SIM_TAG, (uint8_t *)payload, sizeof(lf_asksim_t) + sizeof(bs)); + SendCommandNG(CMD_LF_ASK_SIMULATE, (uint8_t *)payload, sizeof(lf_asksim_t) + sizeof(bs)); free(payload); PacketResponseNG resp; - WaitForResponse(CMD_ASK_SIM_TAG, &resp); + WaitForResponse(CMD_LF_ASK_SIMULATE, &resp); PrintAndLogEx(INFO, "Done"); if (resp.status != PM3_EOPABORTED) diff --git a/client/cmdlfvisa2000.c b/client/cmdlfvisa2000.c index 12d4ba1c6..d698535bf 100644 --- a/client/cmdlfvisa2000.c +++ b/client/cmdlfvisa2000.c @@ -183,8 +183,8 @@ static int CmdVisa2kClone(const char *Cmd) { ng.blockno = i; ng.flags = 0; - SendCommandNG(CMD_T55XX_WRITE_BLOCK, (uint8_t *)&ng, sizeof(ng)); - if (!WaitForResponseTimeout(CMD_T55XX_WRITE_BLOCK, &resp, T55XX_WRITE_TIMEOUT)) { + SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng)); + if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, T55XX_WRITE_TIMEOUT)) { PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); return PM3_ETIMEOUT; @@ -218,11 +218,11 @@ static int CmdVisa2kSim(const char *Cmd) { memcpy(payload->data, bs, sizeof(bs)); clearCommandBuffer(); - SendCommandNG(CMD_ASK_SIM_TAG, (uint8_t *)payload, sizeof(lf_asksim_t) + sizeof(bs)); + SendCommandNG(CMD_LF_ASK_SIMULATE, (uint8_t *)payload, sizeof(lf_asksim_t) + sizeof(bs)); free(payload); PacketResponseNG resp; - WaitForResponse(CMD_ASK_SIM_TAG, &resp); + WaitForResponse(CMD_LF_ASK_SIMULATE, &resp); PrintAndLogEx(INFO, "Done"); if (resp.status != PM3_EOPABORTED) diff --git a/client/deprecated-hid-flasher/flasher/usb_cmd.h b/client/deprecated-hid-flasher/flasher/usb_cmd.h index 44cad2942..58da5dd0a 100644 --- a/client/deprecated-hid-flasher/flasher/usb_cmd.h +++ b/client/deprecated-hid-flasher/flasher/usb_cmd.h @@ -66,94 +66,94 @@ typedef struct { #define CMD_FLASHMEM_INFO 0x0125 // For low-frequency tags -#define CMD_READ_TI_TYPE 0x0202 -#define CMD_WRITE_TI_TYPE 0x0203 -#define CMD_ACQUIRE_RAW_ADC_SAMPLES_125K 0x0205 -#define CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K 0x0206 +#define CMD_LF_TI_READ 0x0202 +#define CMD_LF_TI_WRITE 0x0203 +#define CMD_LF_ACQ_RAW_ADC 0x0205 +#define CMD_LF_MOD_THEN_ACQ_RAW_ADC 0x0206 #define CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K 0x0207 #define CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K 0x0208 -#define CMD_UPLOAD_SIM_SAMPLES_125K 0x0209 -#define CMD_SIMULATE_TAG_125K 0x020A -#define CMD_HID_DEMOD_FSK 0x020B -#define CMD_HID_SIM_TAG 0x020C -#define CMD_SET_LF_DIVISOR 0x020D +#define CMD_LF_UPLOAD_SIM_SAMPLES 0x0209 +#define CMD_LF_SIMULATE 0x020A +#define CMD_LF_HID_DEMOD 0x020B +#define CMD_LF_HID_SIMULATE 0x020C +#define CMD_LF_SET_DIVISOR 0x020D #define CMD_LF_SIMULATE_BIDIR 0x020E #define CMD_SET_ADC_MUX 0x020F -#define CMD_HID_CLONE_TAG 0x0210 -#define CMD_EM410X_WRITE_TAG 0x0211 -#define CMD_INDALA_CLONE_TAG 0x0212 +#define CMD_LF_HID_CLONE 0x0210 +#define CMD_LF_EM410X_WRITE 0x0211 +#define CMD_LF_INDALA_CLONE 0x0212 // for 224 bits UID -#define CMD_INDALA_CLONE_TAG_L 0x0213 -#define CMD_T55XX_READ_BLOCK 0x0214 -#define CMD_T55XX_WRITE_BLOCK 0x0215 -#define CMD_T55XX_RESET_READ 0x0216 -#define CMD_T55XX_WAKEUP 0x0224 +#define CMD_LF_INDALA224_CLONE 0x0213 +#define CMD_LF_T55XX_READBL 0x0214 +#define CMD_LF_T55XX_WRITEBL 0x0215 +#define CMD_LF_T55XX_RESET_READ 0x0216 +#define CMD_LF_T55XX_WAKEUP 0x0224 -#define CMD_PCF7931_READ 0x0217 -#define CMD_PCF7931_WRITE 0x0223 -#define CMD_EM4X_READ_WORD 0x0218 -#define CMD_EM4X_WRITE_WORD 0x0219 -#define CMD_IO_DEMOD_FSK 0x021A -#define CMD_IO_CLONE_TAG 0x021B -#define CMD_EM410X_DEMOD 0x021c +#define CMD_LF_PCF7931_READ 0x0217 +#define CMD_LF_PCF7931_WRITE 0x0223 +#define CMD_LF_EM4X_READWORD 0x0218 +#define CMD_LF_EM4X_WRITEWORD 0x0219 +#define CMD_LF_IO_DEMOD 0x021A +#define CMD_LF_IO_CLONE 0x021B +#define CMD_LF_EM410X_DEMOD 0x021c // Sampling configuration for LF reader/sniffer -#define CMD_SET_LF_SAMPLING_CONFIG 0x021d -#define CMD_FSK_SIM_TAG 0x021E -#define CMD_ASK_SIM_TAG 0x021F -#define CMD_PSK_SIM_TAG 0x0220 -#define CMD_AWID_DEMOD_FSK 0x0221 -#define CMD_VIKING_CLONE_TAG 0x0222 -#define CMD_T55XX_WAKEUP 0x0224 -#define CMD_COTAG 0x0225 -#define CMD_SET_LF_T55XX_CONFIG 0x0226 +#define CMD_LF_SAMPLING_SET_CONFIG 0x021d +#define CMD_LF_FSK_SIMULATE 0x021E +#define CMD_LF_ASK_SIMULATE 0x021F +#define CMD_LF_PSK_SIMULATE 0x0220 +#define CMD_LF_AWID_DEMOD 0x0221 +#define CMD_LF_VIKING_CLONE 0x0222 +#define CMD_LF_T55XX_WAKEUP 0x0224 +#define CMD_LF_COTAG_READ 0x0225 +#define CMD_LF_T55XX_SET_CONFIG 0x0226 /* CMD_SET_ADC_MUX: ext1 is 0 for lopkd, 1 for loraw, 2 for hipkd, 3 for hiraw */ // For the 13.56 MHz tags -#define CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693 0x0300 -#define CMD_READ_SRI_TAG 0x0303 -#define CMD_ISO_14443B_COMMAND 0x0305 -#define CMD_READER_ISO_15693 0x0310 -#define CMD_SIMTAG_ISO_15693 0x0311 -#define CMD_RECORD_RAW_ADC_SAMPLES_ISO_15693 0x0312 -#define CMD_ISO_15693_COMMAND 0x0313 -#define CMD_ISO_15693_FIND_AFI 0x0315 -#define CMD_LF_SNIFF_RAW_ADC_SAMPLES 0x0317 +#define CMD_HF_ISO15693_ACQ_RAW_ADC 0x0300 +#define CMD_HF_SRI_READ 0x0303 +#define CMD_HF_ISO14443B_COMMAND 0x0305 +#define CMD_HF_ISO15693_READER 0x0310 +#define CMD_HF_ISO15693_SIMULATE 0x0311 +#define CMD_HF_ISO15693_RAWADC 0x0312 +#define CMD_HF_ISO15693_COMMAND 0x0313 +#define CMD_HF_ISO15693_FINDAFI 0x0315 +#define CMD_LF_SNIFF_RAW_ADC 0x0317 // For Hitag2 transponders -#define CMD_SNIFF_HITAG 0x0370 -#define CMD_SIMULATE_HITAG 0x0371 -#define CMD_READER_HITAG 0x0372 +#define CMD_LF_HITAG_SNIFF 0x0370 +#define CMD_LF_HITAG_SIMULATE 0x0371 +#define CMD_LF_HITAG_READER 0x0372 // For HitagS -#define CMD_SIMULATE_HITAG_S 0x0368 -#define CMD_TEST_HITAGS_TRACES 0x0367 -#define CMD_READ_HITAG_S 0x0373 -#define CMD_WR_HITAG_S 0x0375 +#define CMD_LF_HITAGS_SIMULATE 0x0368 +#define CMD_LF_HITAGS_TEST_TRACES 0x0367 +#define CMD_LF_HITAGS_READ 0x0373 +#define CMD_LF_HITAGS_WRITE 0x0375 -#define CMD_ANTIFUZZ_ISO_14443a 0x0380 -#define CMD_SIMULATE_TAG_ISO_14443B 0x0381 -#define CMD_SNIFF_ISO_14443B 0x0382 -#define CMD_SNIFF_ISO_14443a 0x0383 -#define CMD_SIMULATE_TAG_ISO_14443a 0x0384 -#define CMD_READER_ISO_14443a 0x0385 +#define CMD_HF_ISO14443A_ANTIFUZZ 0x0380 +#define CMD_HF_ISO14443B_SIMULATE 0x0381 +#define CMD_HF_ISO14443B_SNIFF 0x0382 +#define CMD_HF_ISO14443A_SNIFF 0x0383 +#define CMD_HF_ISO14443A_SIMULATE 0x0384 +#define CMD_HF_ISO14443A_READER 0x0385 -#define CMD_SIMULATE_TAG_LEGIC_RF 0x0387 -#define CMD_READER_LEGIC_RF 0x0388 -#define CMD_WRITER_LEGIC_RF 0x0389 +#define CMD_HF_LEGIC_SIMULATE 0x0387 +#define CMD_HF_LEGIC_READER 0x0388 +#define CMD_HF_LEGIC_WRITER 0x0389 -#define CMD_EPA_PACE_COLLECT_NONCE 0x038A -#define CMD_EPA_PACE_REPLAY 0x038B +#define CMD_HF_EPA_COLLECT_NONCE 0x038A +#define CMD_HF_EPA_REPLAY 0x038B -#define CMD_LEGIC_INFO 0x03BC -#define CMD_LEGIC_ESET 0x03BD +#define CMD_HF_LEGIC_INFO 0x03BC +#define CMD_HF_LEGIC_ESET 0x03BD -#define CMD_SNIFF_ICLASS 0x0392 -#define CMD_SIMULATE_TAG_ICLASS 0x0393 -#define CMD_READER_ICLASS 0x0394 -#define CMD_READER_ICLASS_REPLAY 0x0395 +#define CMD_HF_ICLASS_SNIFF 0x0392 +#define CMD_HF_ICLASS_SIMULATE 0x0393 +#define CMD_HF_ICLASS_READER 0x0394 +#define CMD_HF_ICLASS_REPLAY 0x0395 #define CMD_ICLASS_ISO14443A_WRITE 0x0397 -#define CMD_ICLASS_EML_MEMSET 0x0398 +#define CMD_HF_ICLASS_EML_MEMSET 0x0398 // For measurements of the antenna tuning #define CMD_MEASURE_ANTENNA_TUNING 0x0400 @@ -166,53 +166,53 @@ typedef struct { // For mifare commands #define CMD_MIFARE_SET_DBGMODE 0x0600 -#define CMD_MIFARE_EML_MEMCLR 0x0601 -#define CMD_MIFARE_EML_MEMSET 0x0602 -#define CMD_MIFARE_EML_MEMGET 0x0603 -#define CMD_MIFARE_EML_CARDLOAD 0x0604 +#define CMD_HF_MIFARE_EML_MEMCLR 0x0601 +#define CMD_HF_MIFARE_EML_MEMSET 0x0602 +#define CMD_HF_MIFARE_EML_MEMGET 0x0603 +#define CMD_HF_MIFARE_EML_LOAD 0x0604 // magic chinese card commands -#define CMD_MIFARE_CSETBLOCK 0x0605 -#define CMD_MIFARE_CGETBLOCK 0x0606 -#define CMD_MIFARE_CIDENT 0x0607 +#define CMD_HF_MIFARE_CSETBL 0x0605 +#define CMD_HF_MIFARE_CGETBL 0x0606 +#define CMD_HF_MIFARE_CIDENT 0x0607 -#define CMD_SIMULATE_MIFARE_CARD 0x0610 +#define CMD_HF_MIFARE_SIMULATE 0x0610 -#define CMD_READER_MIFARE 0x0611 -#define CMD_MIFARE_NESTED 0x0612 -#define CMD_MIFARE_ACQUIRE_ENCRYPTED_NONCES 0x0613 +#define CMD_HF_MIFARE_READER 0x0611 +#define CMD_HF_MIFARE_NESTED 0x0612 +#define CMD_HF_MIFARE_ACQ_ENCRYPTED_NONCES 0x0613 -#define CMD_MIFARE_READBL 0x0620 -#define CMD_MIFAREU_READBL 0x0720 -#define CMD_MIFARE_READSC 0x0621 -#define CMD_MIFAREU_READCARD 0x0721 -#define CMD_MIFARE_WRITEBL 0x0622 -#define CMD_MIFAREU_WRITEBL 0x0722 -#define CMD_MIFAREU_WRITEBL_COMPAT 0x0723 +#define CMD_HF_MIFARE_READBL 0x0620 +#define CMD_HF_MIFAREU_READBL 0x0720 +#define CMD_HF_MIFARE_READSC 0x0621 +#define CMD_HF_MIFAREU_READCARD 0x0721 +#define CMD_HF_MIFARE_WRITEBL 0x0622 +#define CMD_HF_MIFAREU_WRITEBL 0x0722 +#define CMD_HF_MIFAREU_WRITEBL_COMPAT 0x0723 -#define CMD_MIFARE_CHKKEYS 0x0623 -#define CMD_MIFARE_SETMOD 0x0624 +#define CMD_HF_MIFARE_CHKKEYS 0x0623 +#define CMD_HF_MIFARE_SETMOD 0x0624 -#define CMD_MIFARE_SNIFFER 0x0630 +#define CMD_HF_MIFARE_SNIFF 0x0630 //ultralightC -#define CMD_MIFAREUC_AUTH 0x0724 +#define CMD_HF_MIFAREUC_AUTH 0x0724 //0x0725 and 0x0726 no longer used -#define CMD_MIFAREUC_SETPWD 0x0727 +#define CMD_HF_MIFAREUC_SETPWD 0x0727 // mifare desfire -#define CMD_MIFARE_DESFIRE_READBL 0x0728 -#define CMD_MIFARE_DESFIRE_WRITEBL 0x0729 -#define CMD_MIFARE_DESFIRE_AUTH1 0x072a -#define CMD_MIFARE_DESFIRE_AUTH2 0x072b -#define CMD_MIFARE_DES_READER 0x072c -#define CMD_MIFARE_DESFIRE_INFO 0x072d -#define CMD_MIFARE_DESFIRE 0x072e +#define CMD_HF_DESFIRE_READBL 0x0728 +#define CMD_HF_DESFIRE_WRITEBL 0x0729 +#define CMD_HF_DESFIRE_AUTH1 0x072a +#define CMD_HF_DESFIRE_AUTH2 0x072b +#define CMD_HF_DESFIRE_READER 0x072c +#define CMD_HF_DESFIRE_INFO 0x072d +#define CMD_HF_DESFIRE_COMMAND 0x072e -#define CMD_MIFARE_COLLECT_NONCES 0x072f +#define CMD_HF_MIFARE_COLLECT_NONCES 0x072f -#define CMD_HF_SNIFFER 0x0800 +#define CMD_HF_SNIFF 0x0800 #define CMD_UNKNOWN 0xFFFF diff --git a/client/lualibs/emulator.lua b/client/lualibs/emulator.lua index af92d5cf8..d43f5da92 100644 --- a/client/lualibs/emulator.lua +++ b/client/lualibs/emulator.lua @@ -12,7 +12,7 @@ local Emulator = { function Emulator:set_mem (data, clear_first) if clear_first then -- Clear out the emulator memory first - local memclrCmd = Command:newMIX{cmd = cmds.CMD_MIFARE_EML_MEMCLR} + local memclrCmd = Command:newMIX{cmd = cmds.CMD_HF_MIFARE_EML_MEMCLR} local _, err = memclrCmd:sendMIX() if err then @@ -30,7 +30,7 @@ function Emulator:set_mem (data, clear_first) -- arg1: start block number -- arg2: block count - local memsetCmd = Command:newMIX{cmd = cmds.CMD_MIFARE_EML_MEMSET, + local memsetCmd = Command:newMIX{cmd = cmds.CMD_HF_MIFARE_EML_MEMSET, data = utils.hexlify(cur_out_block), arg1 = i * self.BLOCK_COUNT, arg2 = self.BLOCK_COUNT} @@ -57,7 +57,7 @@ function Emulator:get_mem (size) for i = 0, (size / (MAX_BLOCKS * 16)) do -- arg1: start block number -- arg2: block count (max 4) - local getmemCmd = Command:newMIX{cmd = cmds.CMD_MIFARE_EML_MEMGET, + local getmemCmd = Command:newMIX{cmd = cmds.CMD_HF_MIFARE_EML_MEMGET, arg1 = i * MAX_BLOCKS, arg2 = MAX_BLOCKS, arg3 = 0} diff --git a/client/lualibs/read14a.lua b/client/lualibs/read14a.lua index 3bf243235..3f0d71dde 100644 --- a/client/lualibs/read14a.lua +++ b/client/lualibs/read14a.lua @@ -86,7 +86,7 @@ local function read14443a(dont_disconnect, no_rats) local command, result, info, err, data command = Command:newMIX{ - cmd = cmds.CMD_READER_ISO_14443a, + cmd = cmds.CMD_HF_ISO14443A_READER, arg1 = ISO14A_COMMAND.ISO14A_CONNECT } @@ -132,7 +132,7 @@ end -- Sends an instruction to do nothing, only disconnect local function disconnect14443a() - local c = Command:newMIX{cmd = cmds.CMD_READER_ISO_14443a} + local c = Command:newMIX{cmd = cmds.CMD_HF_ISO14443A_READER} -- We can ignore the response here, no ACK is returned for this command -- Check /armsrc/iso14443a.c, ReaderIso14443a() for details return c:sendMIX(true) diff --git a/client/lualibs/read14b.lua b/client/lualibs/read14b.lua index 67d2bd469..50c939f63 100644 --- a/client/lualibs/read14b.lua +++ b/client/lualibs/read14b.lua @@ -70,7 +70,7 @@ local function read14443b(disconnect) end command = Command:newMIX{ - cmd = cmds.CMD_ISO_14443B_COMMAND, + cmd = cmds.CMD_HF_ISO14443B_COMMAND, arg1 = flags } @@ -111,13 +111,13 @@ end --- -- turns on the HF field. local function connect14443b() - local c = Command:newMIX{cmd = cmds.CMD_ISO_14443B_COMMAND, arg1 = ISO14B_COMMAND.ISO14B_CONNECT} + local c = Command:newMIX{cmd = cmds.CMD_HF_ISO14443B_COMMAND, arg1 = ISO14B_COMMAND.ISO14B_CONNECT} return c:sendMIX(true) end --- -- Sends an instruction to do nothing, only disconnect local function disconnect14443b() - local c = Command:newMIX{cmd = cmds.CMD_ISO_14443B_COMMAND, arg1 = ISO14B_COMMAND.ISO14B_DISCONNECT} + local c = Command:newMIX{cmd = cmds.CMD_HF_ISO14443B_COMMAND, arg1 = ISO14B_COMMAND.ISO14B_DISCONNECT} -- We can ignore the response here, no ACK is returned for this command -- Check /armsrc/iso14443b.c, ReaderIso14443b() for details return c:sendMIX(true) diff --git a/client/lualibs/read15.lua b/client/lualibs/read15.lua index a70641186..112c12d94 100644 --- a/client/lualibs/read15.lua +++ b/client/lualibs/read15.lua @@ -95,7 +95,7 @@ local function read15693(slow, dont_readresponse) data = utils.Crc15("260100") command = Command:newMIX{ - cmd = cmds.CMD_ISO_15693_COMMAND, + cmd = cmds.CMD_HF_ISO15693_COMMAND, arg1 = #data / 2, arg2 = 1, arg3 = 1, @@ -144,7 +144,7 @@ end -- Sends an instruction to do nothing, only disconnect local function disconnect15693() - local c = Command:newMIX{cmd = cmds.CMD_ISO_15693_COMMAND} + local c = Command:newMIX{cmd = cmds.CMD_HF_ISO15693_COMMAND} -- We can ignore the response here, no ACK is returned for this command -- Check /armsrc/iso14443a.c, ReaderIso14443a() for details return c:sendMIX(true) diff --git a/client/mifare/mifarehost.c b/client/mifare/mifarehost.c index 100b595ce..ff63004e9 100644 --- a/client/mifare/mifarehost.c +++ b/client/mifare/mifarehost.c @@ -25,7 +25,7 @@ int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) { while (true) { clearCommandBuffer(); - SendCommandMIX(CMD_READER_MIFARE, arg0, blockno, key_type, NULL, 0); + SendCommandMIX(CMD_HF_MIFARE_READER, arg0, blockno, key_type, NULL, 0); //flush queue while (kbd_enter_pressed()) { @@ -125,10 +125,10 @@ int mfCheckKeys(uint8_t blockNo, uint8_t keyType, bool clear_trace, uint8_t keyc data[2] = clear_trace; data[3] = keycnt; memcpy(data + 4, keyBlock, 6 * keycnt); - SendCommandNG(CMD_MIFARE_CHKKEYS, data, (4 + 6 * keycnt)); + SendCommandNG(CMD_HF_MIFARE_CHKKEYS, data, (4 + 6 * keycnt)); PacketResponseNG resp; - if (!WaitForResponseTimeout(CMD_MIFARE_CHKKEYS, &resp, 2500)) return PM3_ETIMEOUT; + if (!WaitForResponseTimeout(CMD_HF_MIFARE_CHKKEYS, &resp, 2500)) return PM3_ETIMEOUT; if (resp.status != PM3_SUCCESS) return resp.status; struct kr { @@ -153,7 +153,7 @@ int mfCheckKeys_fast(uint8_t sectorsCnt, uint8_t firstChunk, uint8_t lastChunk, // send keychunk clearCommandBuffer(); - SendCommandOLD(CMD_MIFARE_CHKKEYS_FAST, (sectorsCnt | (firstChunk << 8) | (lastChunk << 12)), ((use_flashmemory << 8) | strategy), size, keyBlock, 6 * size); + SendCommandOLD(CMD_HF_MIFARE_CHKKEYS_FAST, (sectorsCnt | (firstChunk << 8) | (lastChunk << 12)), ((use_flashmemory << 8) | strategy), size, keyBlock, 6 * size); PacketResponseNG resp; while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { @@ -299,7 +299,7 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, struct Crypto1State *p1, *p2, *p3, *p4; clearCommandBuffer(); - SendCommandOLD(CMD_MIFARE_NESTED, blockNo + keyType * 0x100, trgBlockNo + trgKeyType * 0x100, calibrate, key, 6); + SendCommandOLD(CMD_HF_MIFARE_NESTED, blockNo + keyType * 0x100, trgBlockNo + trgKeyType * 0x100, calibrate, key, 6); if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) return PM3_ETIMEOUT; // error during nested @@ -419,7 +419,7 @@ out: int mfReadSector(uint8_t sectorNo, uint8_t keyType, uint8_t *key, uint8_t *data) { clearCommandBuffer(); - SendCommandOLD(CMD_MIFARE_READSC, sectorNo, keyType, 0, key, 6); + SendCommandOLD(CMD_HF_MIFARE_READSC, sectorNo, keyType, 0, key, 6); PacketResponseNG resp; if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { @@ -456,10 +456,10 @@ int mfEmlGetMem(uint8_t *data, int blockNum, int blocksCount) { payload.blockcnt = blocksCount; clearCommandBuffer(); - SendCommandNG(CMD_MIFARE_EML_MEMGET, (uint8_t *)&payload, sizeof(payload)); + SendCommandNG(CMD_HF_MIFARE_EML_MEMGET, (uint8_t *)&payload, sizeof(payload)); PacketResponseNG resp; - if (WaitForResponseTimeout(CMD_MIFARE_EML_MEMGET, &resp, 1500) == 0) { + if (WaitForResponseTimeout(CMD_HF_MIFARE_EML_MEMGET, &resp, 1500) == 0) { PrintAndLogEx(WARNING, "Command execute timeout"); return PM3_ETIMEOUT; } @@ -495,7 +495,7 @@ int mfEmlSetMem_xt(uint8_t *data, int blockNum, int blocksCount, int blockBtWidt memcpy(payload->data, data, size); clearCommandBuffer(); - SendCommandNG(CMD_MIFARE_EML_MEMSET, (uint8_t *)payload, sizeof(payload) + size); + SendCommandNG(CMD_HF_MIFARE_EML_MEMSET, (uint8_t *)payload, sizeof(payload) + size); return PM3_SUCCESS; } @@ -536,7 +536,7 @@ int mfCSetUID(uint8_t *uid, uint8_t *atqa, uint8_t *sak, uint8_t *oldUID, uint8_ int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, uint8_t params) { clearCommandBuffer(); - SendCommandOLD(CMD_MIFARE_CSETBLOCK, params, blockNo, 0, data, 16); + SendCommandOLD(CMD_HF_MIFARE_CSETBL, params, blockNo, 0, data, 16); PacketResponseNG resp; if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { uint8_t isOK = resp.oldarg[0] & 0xff; @@ -553,7 +553,7 @@ int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, uint8_t params) { int mfCGetBlock(uint8_t blockNo, uint8_t *data, uint8_t params) { clearCommandBuffer(); - SendCommandMIX(CMD_MIFARE_CGETBLOCK, params, blockNo, 0, NULL, 0); + SendCommandMIX(CMD_HF_MIFARE_CGETBL, params, blockNo, 0, NULL, 0); PacketResponseNG resp; if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { uint8_t isOK = resp.oldarg[0] & 0xff; @@ -905,7 +905,7 @@ int detect_classic_prng(void) { uint32_t flags = ISO14A_CONNECT | ISO14A_RAW | ISO14A_APPEND_CRC | ISO14A_NO_RATS; clearCommandBuffer(); - SendCommandMIX(CMD_READER_ISO_14443a, flags, sizeof(cmd), 0, cmd, sizeof(cmd)); + SendCommandMIX(CMD_HF_ISO14443A_READER, flags, sizeof(cmd), 0, cmd, sizeof(cmd)); if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { PrintAndLogEx(WARNING, "PRNG UID: Reply timeout."); @@ -942,7 +942,7 @@ returns: int detect_classic_nackbug(bool verbose) { clearCommandBuffer(); - SendCommandNG(CMD_MIFARE_NACK_DETECT, NULL, 0); + SendCommandNG(CMD_HF_MIFARE_NACK_DETECT, NULL, 0); PacketResponseNG resp; if (verbose) @@ -955,7 +955,7 @@ int detect_classic_nackbug(bool verbose) { return PM3_EOPABORTED; } - if (WaitForResponseTimeout(CMD_MIFARE_NACK_DETECT, &resp, 500)) { + if (WaitForResponseTimeout(CMD_HF_MIFARE_NACK_DETECT, &resp, 500)) { if (resp.status == PM3_EOPABORTED) { PrintAndLogEx(WARNING, "button pressed. Aborted."); @@ -1010,8 +1010,8 @@ void detect_classic_magic(void) { uint8_t isGeneration = 0; PacketResponseNG resp; clearCommandBuffer(); - SendCommandNG(CMD_MIFARE_CIDENT, NULL, 0); - if (WaitForResponseTimeout(CMD_MIFARE_CIDENT, &resp, 1500)) { + SendCommandNG(CMD_HF_MIFARE_CIDENT, NULL, 0); + if (WaitForResponseTimeout(CMD_HF_MIFARE_CIDENT, &resp, 1500)) { if (resp.status == PM3_SUCCESS) isGeneration = resp.data.asBytes[0]; } diff --git a/client/scripting.c b/client/scripting.c index 4a2ff28d6..718c4ed43 100644 --- a/client/scripting.c +++ b/client/scripting.c @@ -66,7 +66,7 @@ static int l_fast_push_mode(lua_State *L) { * @return */ static int l_SendCommandOLD(lua_State *L) { -// SendCommandMIX(CMD_HF_SNIFFER, skippairs, skiptriggers, 0, NULL, 0); +// SendCommandMIX(CMD_HF_SNIFF, skippairs, skiptriggers, 0, NULL, 0); // (uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len) uint64_t cmd, arg0, arg1, arg2; @@ -395,7 +395,7 @@ static int l_foobar(lua_State *L) { printf("Arguments discarded, stack now contains %d elements", lua_gettop(L)); // todo: this is not used, where was it intended for? - // PacketCommandOLD response = {CMD_MIFARE_READBL, {1337, 1338, 1339}, {{0}}}; + // PacketCommandOLD response = {CMD_HF_MIFARE_READBL, {1337, 1338, 1339}, {{0}}}; printf("Now returning a uint64_t as a string"); uint64_t x = 0xDEADC0DE; diff --git a/client/scripts/14araw.lua b/client/scripts/14araw.lua index 3bc5c060e..30ab5e497 100644 --- a/client/scripts/14araw.lua +++ b/client/scripts/14araw.lua @@ -166,7 +166,7 @@ function sendRaw(rawdata, options) flags = flags + lib14a.ISO14A_COMMAND.ISO14A_APPEND_CRC end - local command = Command:newMIX{cmd = cmds.CMD_READER_ISO_14443a, + local command = Command:newMIX{cmd = cmds.CMD_HF_ISO14443A_READER, arg1 = flags, -- Send raw -- arg2 contains the length, which is half the length -- of the ASCII-string rawdata diff --git a/client/scripts/amiibo.lua b/client/scripts/amiibo.lua index 73366de02..19866bd6f 100644 --- a/client/scripts/amiibo.lua +++ b/client/scripts/amiibo.lua @@ -16,7 +16,7 @@ local luamiibo = luamiibo_open() local function nfc_read_amiibo () local command = Command:newMIX{ - cmd = cmds.CMD_MIFAREU_READCARD, + cmd = cmds.CMD_HF_MIFAREU_READCARD, arg1 = 0, arg2 = 135 } @@ -90,7 +90,7 @@ local function emulate_amiibo (amiibo_data) -- Begin simulating NTAG215 local simCmd = Command:newMIX{ - cmd = cmds.CMD_SIMULATE_TAG_ISO_14443a, + cmd = cmds.CMD_HF_ISO14443A_SIMULATE, arg1 = 7, arg2 = uid_first, arg3 = uid_second diff --git a/client/scripts/calypso.lua b/client/scripts/calypso.lua index de512c5c8..afb466109 100644 --- a/client/scripts/calypso.lua +++ b/client/scripts/calypso.lua @@ -114,7 +114,7 @@ local function calypso_send_cmd_raw(data, ignoreresponse ) data = data or "00" command = Command:newMIX{ - cmd = cmds.CMD_ISO_14443B_COMMAND, + cmd = cmds.CMD_HF_ISO14443B_COMMAND, arg1 = flags, arg2 = #data/2, -- LEN of data, half the length of the ASCII-string hex string data = data} -- data bytes (commands etc) diff --git a/client/scripts/didump.lua b/client/scripts/didump.lua index d5ac6f873..a9228c7b5 100644 --- a/client/scripts/didump.lua +++ b/client/scripts/didump.lua @@ -475,7 +475,7 @@ local function readblock( blockno, key ) -- Read block N local keytype = '00' local data = ('%02x%s%s'):format(blockno, keytype, key) - local c = Command:newNG{cmd = cmds.CMD_MIFARE_READBL, data = data} + local c = Command:newNG{cmd = cmds.CMD_HF_MIFARE_READBL, data = data} local b, err = getblockdata(c:sendNG(false)) if not b then return oops(err) end return b diff --git a/client/scripts/mfkeys.lua b/client/scripts/mfkeys.lua index 65f50eb9c..f15bb6d5e 100644 --- a/client/scripts/mfkeys.lua +++ b/client/scripts/mfkeys.lua @@ -90,7 +90,7 @@ local function checkBlock(blockno, testkeys, keytype) print(("Testing block %d, keytype %d, with %d keys"):format(blockno, keytype, chunksize)) - local c = Command:newNG{cmd = cmds.CMD_MIFARE_CHKKEYS, data = d0..d1} + local c = Command:newNG{cmd = cmds.CMD_HF_MIFARE_CHKKEYS, data = d0..d1} key, err = checkCommand(c:sendNG(false)) if key then return key, blockno end diff --git a/client/scripts/mifareplus.lua b/client/scripts/mifareplus.lua index a81be26d8..f49ad95e5 100644 --- a/client/scripts/mifareplus.lua +++ b/client/scripts/mifareplus.lua @@ -74,7 +74,7 @@ local function sendRaw(rawdata, crc, power) flags = flags + lib14a.ISO14A_COMMAND.ISO14A_NO_DISCONNECT end - local command = Command:newMIX{cmd = cmds.CMD_READER_ISO_14443a, + local command = Command:newMIX{cmd = cmds.CMD_HF_ISO14443A_READER, arg1 = flags, -- Send raw arg2 = string.len(rawdata) / 2, -- arg2 contains the length, which is half the length of the ASCII-string rawdata data = rawdata diff --git a/client/scripts/ndef_dump.lua b/client/scripts/ndef_dump.lua index 856053207..85909bb91 100644 --- a/client/scripts/ndef_dump.lua +++ b/client/scripts/ndef_dump.lua @@ -69,7 +69,7 @@ end -- -- Sends an instruction to do nothing, only disconnect function disconnect() - local command = Command:newMIX{cmd = cmds.CMD_READER_ISO_14443a, arg1 = 0,} + local command = Command:newMIX{cmd = cmds.CMD_HF_ISO14443A_READER, arg1 = 0,} -- We can ignore the response here, no ACK is returned for this command -- Check /armsrc/iso14443a.c, ReaderIso14443a() for details return command:sendMIX(true) @@ -93,7 +93,7 @@ end -- @return nil, errormessage if unsuccessfull local function getBlock(blockno) local block, err - local c = Command:newMIX{cmd = cmds.CMD_MIFAREU_READBL, arg1 = blockno, data = 0} + local c = Command:newMIX{cmd = cmds.CMD_HF_MIFAREU_READBL, arg1 = blockno, data = 0} block, err = getblockdata(c:sendMIX(false)) if not block then return oops(err) end diff --git a/client/scripts/test_t55x7.lua b/client/scripts/test_t55x7.lua index c06d2848a..0fc112ea7 100644 --- a/client/scripts/test_t55x7.lua +++ b/client/scripts/test_t55x7.lua @@ -260,7 +260,7 @@ local function test(modulation) local data = ('%s%s%s%s'):format(utils.SwapEndiannessStr(p_config_cmd, 32), password, block, flags) - local wc = Command:newNG{cmd = cmds.CMD_T55XX_WRITE_BLOCK, data = data} + local wc = Command:newNG{cmd = cmds.CMD_LF_T55XX_WRITEBL, data = data} local response, err = wc:sendNG(false, TIMEOUT) if not response then return oops(err) end diff --git a/client/scripts/test_t55x7_ask.lua b/client/scripts/test_t55x7_ask.lua index ecf02346b..bb232a6fd 100644 --- a/client/scripts/test_t55x7_ask.lua +++ b/client/scripts/test_t55x7_ask.lua @@ -117,7 +117,7 @@ local function test() dbg(('lf t55xx write b 0 d %s'):format(config)) local data = ('%s%s%s%s'):format(utils.SwapEndiannessStr(config, 32), password, block, flags) - local wc = Command:newNG{cmd = cmds.CMD_T55XX_WRITE_BLOCK, data = data} + local wc = Command:newNG{cmd = cmds.CMD_LF_T55XX_WRITEBL, data = data} local response, err = wc:sendNG(false, TIMEOUT) if not response then return oops(err) end diff --git a/client/scripts/test_t55x7_bi.lua b/client/scripts/test_t55x7_bi.lua index 0b0239717..49ee4882a 100644 --- a/client/scripts/test_t55x7_bi.lua +++ b/client/scripts/test_t55x7_bi.lua @@ -112,7 +112,7 @@ local function test() local data = ('%s%s%s%s'):format(utils.SwapEndiannessStr(config, 32), password, block, flags) - local wc = Command:newNG{cmd = cmds.CMD_T55XX_WRITE_BLOCK, data = data} + local wc = Command:newNG{cmd = cmds.CMD_LF_T55XX_WRITEBL, data = data} local response, err = wc:sendNG(false, TIMEOUT) if not response then return oops(err) end diff --git a/client/scripts/test_t55x7_fsk.lua b/client/scripts/test_t55x7_fsk.lua index abf4692d7..c755042b1 100644 --- a/client/scripts/test_t55x7_fsk.lua +++ b/client/scripts/test_t55x7_fsk.lua @@ -113,7 +113,7 @@ local function test(modulation) dbg(('lf t55xx write b 0 d %s'):format(config)) local data = ('%s%s%s%s'):format(utils.SwapEndiannessStr(config, 32), password, block, flags) - local wc = Command:newNG{cmd = cmds.CMD_T55XX_WRITE_BLOCK, data = data} + local wc = Command:newNG{cmd = cmds.CMD_LF_T55XX_WRITEBL, data = data} local response, err = wc:sendNG(false, TIMEOUT) if not response then return oops(err) end else diff --git a/client/scripts/test_t55x7_psk.lua b/client/scripts/test_t55x7_psk.lua index 2c0efa163..10fecd549 100644 --- a/client/scripts/test_t55x7_psk.lua +++ b/client/scripts/test_t55x7_psk.lua @@ -119,7 +119,7 @@ local function test(modulation) local data = ('%s%s%s%s'):format(utils.SwapEndiannessStr(config, 32), password, block, flags) - local wc = Command:newNG{cmd = cmds.CMD_T55XX_WRITE_BLOCK, data = data} + local wc = Command:newNG{cmd = cmds.CMD_LF_T55XX_WRITEBL, data = data} local response, err = wc:sendNG(false, TIMEOUT) if not response then return oops(err) end else diff --git a/client/scripts/tnp3clone.lua b/client/scripts/tnp3clone.lua index 18dd6edfb..58bb5d338 100644 --- a/client/scripts/tnp3clone.lua +++ b/client/scripts/tnp3clone.lua @@ -77,7 +77,7 @@ local function readblock( blocknum, keyA ) -- Read block N local keytype = '00' local data = ('%02x%s%s'):format(blocknum, keytype, keyA) - local c = Command:newNG{cmd = cmds.CMD_MIFARE_READBL, data = data} + local c = Command:newNG{cmd = cmds.CMD_HF_MIFARE_READBL, data = data} local b, err = getblockdata(c:sendNG(false)) if not b then return oops(err) end return b @@ -88,7 +88,7 @@ local function readmagicblock( blocknum ) -- Read block N local CSETBLOCK_SINGLE_OPERATION = 0x1F local c = Command:newMIX{ - cmd = cmds.CMD_MIFARE_CGETBLOCK + cmd = cmds.CMD_HF_MIFARE_CGETBL , arg1 = CSETBLOCK_SINGLE_OPERATION , arg3 = blocknum } diff --git a/client/scripts/tnp3dump.lua b/client/scripts/tnp3dump.lua index 0faadecaf..488d2f5f9 100644 --- a/client/scripts/tnp3dump.lua +++ b/client/scripts/tnp3dump.lua @@ -169,7 +169,7 @@ local function main(args) local blockno = '00' local keytype = '00' local data = ('%s%s%s'):format(blockno, keytype, keyA) - cmd = Command:newNG{cmd = cmds.CMD_MIFARE_READBL, data = data} + cmd = Command:newNG{cmd = cmds.CMD_HF_MIFARE_READBL, data = data} block0, err = getblockdata(cmd:sendNG(false)) if not block0 then return oops(err) end @@ -179,7 +179,7 @@ local function main(args) dbg('Reading block 1') local blockno = '01' data = ('%s%s%s'):format(blockno, keytype, keyA) - cmd = Command:newNG{cmd = cmds.CMD_MIFARE_READBL, data = data} + cmd = Command:newNG{cmd = cmds.CMD_HF_MIFARE_READBL, data = data} block1, err = getblockdata(cmd:sendNG(false)) if not block1 then return oops(err) end @@ -208,7 +208,7 @@ local function main(args) pos = (math.floor( blockNo / 4 ) * 12)+1 key = akeys:sub(pos, pos + 11 ) data = ('%02x%s%s'):format(blockNo, keytype, key) - cmd = Command:newNG{cmd = cmds.CMD_MIFARE_READBL, data = data} + cmd = Command:newNG{cmd = cmds.CMD_HF_MIFARE_READBL, data = data} local blockdata, err = getblockdata(cmd:sendNG(false)) if not blockdata then return oops(err) end diff --git a/client/scripts/tnp3sim.lua b/client/scripts/tnp3sim.lua index f1b58f95e..014474416 100644 --- a/client/scripts/tnp3sim.lua +++ b/client/scripts/tnp3sim.lua @@ -246,7 +246,7 @@ local function LoadEmulator(uid, blocks) io.write( _..',') io.flush() core.clearCommandBuffer() - cmd = Command:newMIX{cmd = cmds.CMD_MIFARE_EML_MEMSET, arg1 = _ ,arg2 = 1,arg3 = 16, data = blockdata} + cmd = Command:newMIX{cmd = cmds.CMD_HF_MIFARE_EML_MEMSET, arg1 = _ ,arg2 = 1,arg3 = 16, data = blockdata} local err, msg = cmd:sendMIX(true) if err == nil then return err, msg end end diff --git a/client/scripts/ufodump.lua b/client/scripts/ufodump.lua index 0f6a51a76..140652492 100644 --- a/client/scripts/ufodump.lua +++ b/client/scripts/ufodump.lua @@ -96,7 +96,7 @@ function sendRaw(rawdata, options) + lib14a.ISO14A_COMMAND.ISO14A_APPEND_CRC + lib14a.ISO14A_COMMAND.ISO14A_NO_RATS - local command = Command:newMIX{cmd = cmds.CMD_READER_ISO_14443a, + local command = Command:newMIX{cmd = cmds.CMD_HF_ISO14443A_READER, arg1 = flags, -- Send raw -- arg2 contains the length, which is half the length -- of the ASCII-string rawdata diff --git a/client/util.h b/client/util.h index 3f677df7a..f1d55b140 100644 --- a/client/util.h +++ b/client/util.h @@ -33,7 +33,7 @@ #ifndef DropField #define DropField() { \ - clearCommandBuffer(); SendCommandMIX(CMD_READER_ISO_14443a, 0, 0, 0, NULL, 0); \ + clearCommandBuffer(); SendCommandMIX(CMD_HF_ISO14443A_READER, 0, 0, 0, NULL, 0); \ } #endif diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 6c80f56a3..bce5c28ed 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -188,7 +188,7 @@ typedef struct { #define CAPABILITIES_VERSION 2 extern capabilities_t pm3_capabilities; -// For CMD_T55XX_WRITE_BLOCK +// For CMD_LF_T55XX_WRITEBL typedef struct { uint32_t data; uint32_t pwd; @@ -196,7 +196,7 @@ typedef struct { uint8_t flags; } PACKED t55xx_write_block_t; -// For CMD_FSK_SIM_TAG (FSK) +// For CMD_LF_FSK_SIMULATE (FSK) typedef struct { uint8_t fchigh; uint8_t fclow; @@ -205,7 +205,7 @@ typedef struct { uint8_t data[]; } PACKED lf_fsksim_t; -// For CMD_ASK_SIM_TAG (ASK) +// For CMD_LF_ASK_SIMULATE (ASK) typedef struct { uint8_t encoding; uint8_t invert; @@ -214,7 +214,7 @@ typedef struct { uint8_t data[]; } PACKED lf_asksim_t; -// For CMD_PSK_SIM_TAG (PSK) +// For CMD_LF_PSK_SIMULATE (PSK) typedef struct { uint8_t carrier; uint8_t invert; @@ -315,110 +315,110 @@ typedef struct { #define CMD_USART_CONFIG 0x0163 // For low-frequency tags -#define CMD_READ_TI_TYPE 0x0202 -#define CMD_WRITE_TI_TYPE 0x0203 -#define CMD_ACQUIRE_RAW_ADC_SAMPLES_125K 0x0205 -#define CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K 0x0206 +#define CMD_LF_TI_READ 0x0202 +#define CMD_LF_TI_WRITE 0x0203 +#define CMD_LF_ACQ_RAW_ADC 0x0205 +#define CMD_LF_MOD_THEN_ACQ_RAW_ADC 0x0206 #define CMD_DOWNLOAD_BIGBUF 0x0207 #define CMD_DOWNLOADED_BIGBUF 0x0208 -#define CMD_UPLOAD_SIM_SAMPLES_125K 0x0209 -#define CMD_SIMULATE_TAG_125K 0x020A -#define CMD_HID_DEMOD_FSK 0x020B -#define CMD_HID_SIM_TAG 0x020C -#define CMD_SET_LF_DIVISOR 0x020D +#define CMD_LF_UPLOAD_SIM_SAMPLES 0x0209 +#define CMD_LF_SIMULATE 0x020A +#define CMD_LF_HID_DEMOD 0x020B +#define CMD_LF_HID_SIMULATE 0x020C +#define CMD_LF_SET_DIVISOR 0x020D #define CMD_LF_SIMULATE_BIDIR 0x020E #define CMD_SET_ADC_MUX 0x020F -#define CMD_HID_CLONE_TAG 0x0210 -#define CMD_EM410X_WRITE_TAG 0x0211 -#define CMD_INDALA_CLONE_TAG 0x0212 +#define CMD_LF_HID_CLONE 0x0210 +#define CMD_LF_EM410X_WRITE 0x0211 +#define CMD_LF_INDALA_CLONE 0x0212 // for 224 bits UID -#define CMD_INDALA_CLONE_TAG_L 0x0213 -#define CMD_T55XX_READ_BLOCK 0x0214 -#define CMD_T55XX_WRITE_BLOCK 0x0215 -#define CMD_T55XX_RESET_READ 0x0216 -#define CMD_PCF7931_READ 0x0217 -#define CMD_PCF7931_WRITE 0x0223 -#define CMD_EM4X_READ_WORD 0x0218 -#define CMD_EM4X_WRITE_WORD 0x0219 -#define CMD_IO_DEMOD_FSK 0x021A -#define CMD_IO_CLONE_TAG 0x021B -#define CMD_EM410X_DEMOD 0x021c +#define CMD_LF_INDALA224_CLONE 0x0213 +#define CMD_LF_T55XX_READBL 0x0214 +#define CMD_LF_T55XX_WRITEBL 0x0215 +#define CMD_LF_T55XX_RESET_READ 0x0216 +#define CMD_LF_PCF7931_READ 0x0217 +#define CMD_LF_PCF7931_WRITE 0x0223 +#define CMD_LF_EM4X_READWORD 0x0218 +#define CMD_LF_EM4X_WRITEWORD 0x0219 +#define CMD_LF_IO_DEMOD 0x021A +#define CMD_LF_IO_CLONE 0x021B +#define CMD_LF_EM410X_DEMOD 0x021c // Sampling configuration for LF reader/sniffer -#define CMD_SET_LF_SAMPLING_CONFIG 0x021d -#define CMD_FSK_SIM_TAG 0x021E -#define CMD_ASK_SIM_TAG 0x021F -#define CMD_PSK_SIM_TAG 0x0220 -#define CMD_AWID_DEMOD_FSK 0x0221 -#define CMD_VIKING_CLONE_TAG 0x0222 -#define CMD_T55XX_WAKEUP 0x0224 -#define CMD_COTAG 0x0225 -#define CMD_SET_LF_T55XX_CONFIG 0x0226 +#define CMD_LF_SAMPLING_SET_CONFIG 0x021d +#define CMD_LF_FSK_SIMULATE 0x021E +#define CMD_LF_ASK_SIMULATE 0x021F +#define CMD_LF_PSK_SIMULATE 0x0220 +#define CMD_LF_AWID_DEMOD 0x0221 +#define CMD_LF_VIKING_CLONE 0x0222 +#define CMD_LF_T55XX_WAKEUP 0x0224 +#define CMD_LF_COTAG_READ 0x0225 +#define CMD_LF_T55XX_SET_CONFIG 0x0226 -#define CMD_T55XX_CHKPWDS 0x0230 +#define CMD_LF_T55XX_CHK_PWDS 0x0230 /* CMD_SET_ADC_MUX: ext1 is 0 for lopkd, 1 for loraw, 2 for hipkd, 3 for hiraw */ // For the 13.56 MHz tags -#define CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693 0x0300 -#define CMD_READ_SRI_TAG 0x0303 -#define CMD_ISO_14443B_COMMAND 0x0305 -#define CMD_READER_ISO_15693 0x0310 -#define CMD_SIMTAG_ISO_15693 0x0311 -#define CMD_RECORD_RAW_ADC_SAMPLES_ISO_15693 0x0312 -#define CMD_ISO_15693_COMMAND 0x0313 -#define CMD_ISO_15693_FIND_AFI 0x0315 -#define CMD_LF_SNIFF_RAW_ADC_SAMPLES 0x0317 +#define CMD_HF_ISO15693_ACQ_RAW_ADC 0x0300 +#define CMD_HF_SRI_READ 0x0303 +#define CMD_HF_ISO14443B_COMMAND 0x0305 +#define CMD_HF_ISO15693_READER 0x0310 +#define CMD_HF_ISO15693_SIMULATE 0x0311 +#define CMD_HF_ISO15693_RAWADC 0x0312 +#define CMD_HF_ISO15693_COMMAND 0x0313 +#define CMD_HF_ISO15693_FINDAFI 0x0315 +#define CMD_LF_SNIFF_RAW_ADC 0x0317 // For Hitag2 transponders -#define CMD_SNIFF_HITAG 0x0370 -#define CMD_SIMULATE_HITAG 0x0371 -#define CMD_READER_HITAG 0x0372 +#define CMD_LF_HITAG_SNIFF 0x0370 +#define CMD_LF_HITAG_SIMULATE 0x0371 +#define CMD_LF_HITAG_READER 0x0372 // For HitagS -#define CMD_TEST_HITAGS_TRACES 0x0367 -#define CMD_SIMULATE_HITAG_S 0x0368 -#define CMD_READ_HITAG_S 0x0373 -#define CMD_WR_HITAG_S 0x0375 +#define CMD_LF_HITAGS_TEST_TRACES 0x0367 +#define CMD_LF_HITAGS_SIMULATE 0x0368 +#define CMD_LF_HITAGS_READ 0x0373 +#define CMD_LF_HITAGS_WRITE 0x0375 -#define CMD_ANTIFUZZ_ISO_14443a 0x0380 -#define CMD_SIMULATE_TAG_ISO_14443B 0x0381 -#define CMD_SNIFF_ISO_14443B 0x0382 +#define CMD_HF_ISO14443A_ANTIFUZZ 0x0380 +#define CMD_HF_ISO14443B_SIMULATE 0x0381 +#define CMD_HF_ISO14443B_SNIFF 0x0382 -#define CMD_SNIFF_ISO_14443a 0x0383 -#define CMD_SIMULATE_TAG_ISO_14443a 0x0384 +#define CMD_HF_ISO14443A_SNIFF 0x0383 +#define CMD_HF_ISO14443A_SIMULATE 0x0384 -#define CMD_READER_ISO_14443a 0x0385 +#define CMD_HF_ISO14443A_READER 0x0385 -#define CMD_SIMULATE_TAG_LEGIC_RF 0x0387 -#define CMD_READER_LEGIC_RF 0x0388 -#define CMD_WRITER_LEGIC_RF 0x0389 +#define CMD_HF_LEGIC_SIMULATE 0x0387 +#define CMD_HF_LEGIC_READER 0x0388 +#define CMD_HF_LEGIC_WRITER 0x0389 -#define CMD_EPA_PACE_COLLECT_NONCE 0x038A -#define CMD_EPA_PACE_REPLAY 0x038B +#define CMD_HF_EPA_COLLECT_NONCE 0x038A +#define CMD_HF_EPA_REPLAY 0x038B -#define CMD_LEGIC_INFO 0x03BC -#define CMD_LEGIC_ESET 0x03BD +#define CMD_HF_LEGIC_INFO 0x03BC +#define CMD_HF_LEGIC_ESET 0x03BD -#define CMD_ICLASS_READCHECK 0x038F -#define CMD_ICLASS_CLONE 0x0390 -#define CMD_ICLASS_DUMP 0x0391 -#define CMD_SNIFF_ICLASS 0x0392 -#define CMD_SIMULATE_TAG_ICLASS 0x0393 -#define CMD_READER_ICLASS 0x0394 -#define CMD_READER_ICLASS_REPLAY 0x0395 -#define CMD_ICLASS_READBLOCK 0x0396 -#define CMD_ICLASS_WRITEBLOCK 0x0397 -#define CMD_ICLASS_EML_MEMSET 0x0398 -#define CMD_ICLASS_AUTHENTICATION 0x0399 -#define CMD_ICLASS_CHECK_KEYS 0x039A +#define CMD_HF_ICLASS_READCHECK 0x038F +#define CMD_HF_ICLASS_CLONE 0x0390 +#define CMD_HF_ICLASS_DUMP 0x0391 +#define CMD_HF_ICLASS_SNIFF 0x0392 +#define CMD_HF_ICLASS_SIMULATE 0x0393 +#define CMD_HF_ICLASS_READER 0x0394 +#define CMD_HF_ICLASS_REPLAY 0x0395 +#define CMD_HF_ICLASS_READBL 0x0396 +#define CMD_HF_ICLASS_WRITEBL 0x0397 +#define CMD_HF_ICLASS_EML_MEMSET 0x0398 +#define CMD_HF_ICLASS_AUTH 0x0399 +#define CMD_HF_ICLASS_CHKKEYS 0x039A // For ISO1092 / FeliCa -#define CMD_FELICA_SIMULATE_TAG 0x03A0 -#define CMD_FELICA_SNIFF 0x03A1 -#define CMD_FELICA_COMMAND 0x03A2 +#define CMD_HF_FELICA_SIMULATE 0x03A0 +#define CMD_HF_FELICA_SNIFF 0x03A1 +#define CMD_HF_FELICA_COMMAND 0x03A2 //temp -#define CMD_FELICA_LITE_DUMP 0x03AA -#define CMD_FELICA_LITE_SIM 0x03AB +#define CMD_HF_FELICALITE_DUMP 0x03AA +#define CMD_HF_FELICALITE_SIMULATE 0x03AB // For measurements of the antenna tuning #define CMD_MEASURE_ANTENNA_TUNING 0x0400 @@ -429,58 +429,58 @@ typedef struct { #define CMD_FPGA_MAJOR_MODE_OFF 0x0500 // For mifare commands -#define CMD_MIFARE_EML_MEMCLR 0x0601 -#define CMD_MIFARE_EML_MEMSET 0x0602 -#define CMD_MIFARE_EML_MEMGET 0x0603 -#define CMD_MIFARE_EML_CARDLOAD 0x0604 +#define CMD_HF_MIFARE_EML_MEMCLR 0x0601 +#define CMD_HF_MIFARE_EML_MEMSET 0x0602 +#define CMD_HF_MIFARE_EML_MEMGET 0x0603 +#define CMD_HF_MIFARE_EML_LOAD 0x0604 // magic chinese card commands -#define CMD_MIFARE_CSETBLOCK 0x0605 -#define CMD_MIFARE_CGETBLOCK 0x0606 -#define CMD_MIFARE_CIDENT 0x0607 +#define CMD_HF_MIFARE_CSETBL 0x0605 +#define CMD_HF_MIFARE_CGETBL 0x0606 +#define CMD_HF_MIFARE_CIDENT 0x0607 -#define CMD_SIMULATE_MIFARE_CARD 0x0610 +#define CMD_HF_MIFARE_SIMULATE 0x0610 -#define CMD_READER_MIFARE 0x0611 -#define CMD_MIFARE_NESTED 0x0612 -#define CMD_MIFARE_ACQUIRE_ENCRYPTED_NONCES 0x0613 -#define CMD_MIFARE_ACQUIRE_NONCES 0x0614 +#define CMD_HF_MIFARE_READER 0x0611 +#define CMD_HF_MIFARE_NESTED 0x0612 +#define CMD_HF_MIFARE_ACQ_ENCRYPTED_NONCES 0x0613 +#define CMD_HF_MIFARE_ACQ_NONCES 0x0614 -#define CMD_MIFARE_READBL 0x0620 -#define CMD_MIFAREU_READBL 0x0720 -#define CMD_MIFARE_READSC 0x0621 -#define CMD_MIFAREU_READCARD 0x0721 -#define CMD_MIFARE_WRITEBL 0x0622 -#define CMD_MIFAREU_WRITEBL 0x0722 -#define CMD_MIFAREU_WRITEBL_COMPAT 0x0723 +#define CMD_HF_MIFARE_READBL 0x0620 +#define CMD_HF_MIFAREU_READBL 0x0720 +#define CMD_HF_MIFARE_READSC 0x0621 +#define CMD_HF_MIFAREU_READCARD 0x0721 +#define CMD_HF_MIFARE_WRITEBL 0x0622 +#define CMD_HF_MIFAREU_WRITEBL 0x0722 +#define CMD_HF_MIFAREU_WRITEBL_COMPAT 0x0723 -#define CMD_MIFARE_CHKKEYS 0x0623 -#define CMD_MIFARE_SETMOD 0x0624 -#define CMD_MIFARE_CHKKEYS_FAST 0x0625 +#define CMD_HF_MIFARE_CHKKEYS 0x0623 +#define CMD_HF_MIFARE_SETMOD 0x0624 +#define CMD_HF_MIFARE_CHKKEYS_FAST 0x0625 -#define CMD_MIFARE_SNIFFER 0x0630 +#define CMD_HF_MIFARE_SNIFF 0x0630 //ultralightC -#define CMD_MIFAREUC_AUTH 0x0724 +#define CMD_HF_MIFAREUC_AUTH 0x0724 //0x0725 and 0x0726 no longer used -#define CMD_MIFAREUC_SETPWD 0x0727 +#define CMD_HF_MIFAREUC_SETPWD 0x0727 // mifare desfire -#define CMD_MIFARE_DESFIRE_READBL 0x0728 -#define CMD_MIFARE_DESFIRE_WRITEBL 0x0729 -#define CMD_MIFARE_DESFIRE_AUTH1 0x072a -#define CMD_MIFARE_DESFIRE_AUTH2 0x072b -#define CMD_MIFARE_DES_READER 0x072c -#define CMD_MIFARE_DESFIRE_INFO 0x072d -#define CMD_MIFARE_DESFIRE 0x072e +#define CMD_HF_DESFIRE_READBL 0x0728 +#define CMD_HF_DESFIRE_WRITEBL 0x0729 +#define CMD_HF_DESFIRE_AUTH1 0x072a +#define CMD_HF_DESFIRE_AUTH2 0x072b +#define CMD_HF_DESFIRE_READER 0x072c +#define CMD_HF_DESFIRE_INFO 0x072d +#define CMD_HF_DESFIRE_COMMAND 0x072e -#define CMD_MIFARE_COLLECT_NONCES 0x072f -#define CMD_MIFARE_NACK_DETECT 0x0730 +#define CMD_HF_MIFARE_COLLECT_NONCES 0x072f +#define CMD_HF_MIFARE_NACK_DETECT 0x0730 -#define CMD_HF_SNIFFER 0x0800 +#define CMD_HF_SNIFF 0x0800 // For ThinFilm Kovio -#define CMD_THINFILM_READ 0x0810 -#define CMD_SIMULATE_TAG_THINFILM 0x0811 +#define CMD_HF_THINFILM_READ 0x0810 +#define CMD_HF_THINFILM_SIMULATE 0x0811 #define CMD_UNKNOWN 0xFFFF From 017b3357ed8c84c57936ba581faacce395db421d Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 3 Aug 2019 19:52:03 +0200 Subject: [PATCH 0240/1854] Comment Felica simulation in client, there is no corresponding code in ARM --- client/cmdhffelica.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index 1e97dd8b6..e873daaaf 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -11,6 +11,7 @@ static int CmdHelp(const char *Cmd); +/* static int usage_hf_felica_sim(void) { PrintAndLogEx(NORMAL, "\n Emulating ISO/18092 FeliCa tag \n"); PrintAndLogEx(NORMAL, "Usage: hf felica sim [h] t [v]"); @@ -23,6 +24,7 @@ static int usage_hf_felica_sim(void) { PrintAndLogEx(NORMAL, " hf felica sim t 1 "); return 0; } +*/ static int usage_hf_felica_sniff(void) { PrintAndLogEx(NORMAL, "It get data from the field and saves it into command buffer."); PrintAndLogEx(NORMAL, "Buffer accessible from command 'hf list felica'"); @@ -78,6 +80,8 @@ static int CmdHFFelicaReader(const char *Cmd) { } // simulate iso18092 / FeliCa tag +// Commented, there is no counterpart in ARM at the moment +/* static int CmdHFFelicaSim(const char *Cmd) { bool errors = false; uint8_t flags = 0; @@ -140,6 +144,7 @@ static int CmdHFFelicaSim(const char *Cmd) { } return 0; } +*/ static int CmdHFFelicaSniff(const char *Cmd) { @@ -535,7 +540,7 @@ static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, {"list", CmdHFFelicaList, AlwaysAvailable, "List ISO 18092/FeliCa history"}, {"reader", CmdHFFelicaReader, IfPm3Felica, "Act like an ISO18092/FeliCa reader"}, - {"sim", CmdHFFelicaSim, IfPm3Felica, " -- Simulate ISO 18092/FeliCa tag"}, +// {"sim", CmdHFFelicaSim, IfPm3Felica, " -- Simulate ISO 18092/FeliCa tag"}, {"sniff", CmdHFFelicaSniff, IfPm3Felica, "sniff ISO 18092/Felica traffic"}, {"raw", CmdHFFelicaCmdRaw, IfPm3Felica, "Send raw hex data to tag"}, From 517f0886ba66963225b9070fff2dd9a545a25738 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 3 Aug 2019 20:20:08 +0200 Subject: [PATCH 0241/1854] make style --- armsrc/hitag2.c | 3 +-- armsrc/lfops.c | 24 ++++++++++++------------ 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index c541e57ae..f1350f12a 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -407,8 +407,7 @@ static bool hitag2_password(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t bAuthenticating = true; memcpy(tx, password, 4); *txlen = 32; - } - else { + } else { // stage 2, got config byte+password TAG, discard as will read later if (bAuthenticating) { bAuthenticating = false; diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 3b00188ea..daae31bca 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -157,7 +157,7 @@ t55xx_configurations_t T55xx_Timing = { void printT55xxConfig(void) { #define PRN_NA sprintf(s + strlen(s), _RED_("N/A") "| "); - + DbpString(_BLUE_("LF T55XX config")); Dbprintf(" [r] [a] [b] [c] [d] [e] [f] [g]"); Dbprintf(" mode |start|write|write|write| read|write|write"); @@ -168,7 +168,7 @@ void printT55xxConfig(void) { char s[160]; memset(s, 0, sizeof(s)); - + switch (i) { case T55XX_DLMODE_FIXED : sprintf(s, _YELLOW_("fixed bit length") _GREEN_("(default)") "|"); @@ -185,7 +185,7 @@ void printT55xxConfig(void) { default: break; } - + if (T55xx_Timing.m[i].start_gap != 0xFFFF) sprintf(s + strlen(s), " %3d | ", T55xx_Timing.m[i].start_gap / 8); else @@ -194,33 +194,33 @@ void printT55xxConfig(void) { if (T55xx_Timing.m[i].write_gap != 0xFFFF) sprintf(s + strlen(s), "%3d | ", T55xx_Timing.m[i].write_gap / 8); else - PRN_NA; + PRN_NA; if (T55xx_Timing.m[i].write_0 != 0xFFFF) sprintf(s + strlen(s), "%3d | ", T55xx_Timing.m[i].write_0 / 8); else - PRN_NA; + PRN_NA; if (T55xx_Timing.m[i].write_1 != 0xFFFF) sprintf(s + strlen(s), "%3d | ", T55xx_Timing.m[i].write_1 / 8); else - PRN_NA; + PRN_NA; if (T55xx_Timing.m[i].read_gap != 0xFFFF) sprintf(s + strlen(s), "%3d | ", T55xx_Timing.m[i].read_gap / 8); else PRN_NA; - if (T55xx_Timing.m[i].write_2 != 0xFFFF && i == T55XX_DLMODE_1OF4 ) + if (T55xx_Timing.m[i].write_2 != 0xFFFF && i == T55XX_DLMODE_1OF4) sprintf(s + strlen(s), "%3d | ", T55xx_Timing.m[i].write_2 / 8); - else + else PRN_NA - if (T55xx_Timing.m[i].write_3 != 0xFFFF && i == T55XX_DLMODE_1OF4) - sprintf(s + strlen(s), "%3d | ", T55xx_Timing.m[i].write_3 / 8); + if (T55xx_Timing.m[i].write_3 != 0xFFFF && i == T55XX_DLMODE_1OF4) + sprintf(s + strlen(s), "%3d | ", T55xx_Timing.m[i].write_3 / 8); else - PRN_NA; - + PRN_NA; + s[strlen(s)] = 0; DbpString(s); } From 177546f74957eaaa49c23b4c5a66c4f2d76f885d Mon Sep 17 00:00:00 2001 From: Victor Date: Sat, 3 Aug 2019 19:53:26 +0100 Subject: [PATCH 0242/1854] Update CHANGELOG --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f7aad9983..d22975970 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,10 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Add VSCode tasks (@ViRb3) + - Better warn user of hardcoded hitag info (@ViRb3) + - Format and docs hitag (@ViRb3) + - Fix hitag password write offset by 1 (@ViRb3) - Fix momentarily flash read/write of dicts (@doegox/@cjbrigato) - Add some more default keys (@anon) - Add 'hf thinfilm sim' simulating Thinfilm NFC barcode tags (@doegox) From 4a3fb3ccf1d6bbe78c9059f119093c2a5b8c616f Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 3 Aug 2019 21:17:52 +0200 Subject: [PATCH 0243/1854] split nfcbarcode from iso14443a --- armsrc/Makefile | 4 +++- armsrc/appmain.c | 8 ++++++++ client/cmdhfthinfilm.c | 6 +++--- client/cmdparser.c | 6 ++++++ client/cmdparser.h | 1 + common/Makefile.hal | 2 ++ include/pm3_cmd.h | 3 ++- 7 files changed, 25 insertions(+), 5 deletions(-) diff --git a/armsrc/Makefile b/armsrc/Makefile index 5475b57eb..cd42ae13f 100644 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@ -27,13 +27,14 @@ APP_CFLAGS = $(PLATFORM_DEFS) \ SRC_LF = lfops.c lfsampling.c pcf7931.c lfdemod.c SRC_ISO15693 = iso15693.c iso15693tools.c -SRC_ISO14443a = iso14443a.c mifareutil.c mifarecmd.c epa.c mifaresim.c thinfilm.c +SRC_ISO14443a = iso14443a.c mifareutil.c mifarecmd.c epa.c mifaresim.c SRC_ISO14443b = iso14443b.c SRC_FELICA = felica.c SRC_CRAPTO1 = crypto1.c des.c desfire_key.c desfire_crypto.c mifaredesfire.c aes.c platform_util.c SRC_CRC = crc.c crc16.c crc32.c SRC_ICLASS = iclass.c optimized_cipher.c SRC_LEGIC = legicrf.c legicrfsim.c legic_prng.c +SRC_NFCBARCODE = thinfilm.c # SRC_BEE = bee.c @@ -114,6 +115,7 @@ THUMBSRC = start.c \ # These are to be compiled in ARM mode ARMSRC = fpgaloader.c \ $(SRC_ISO14443a) \ + $(SRC_NFCBARCODE) \ $(SRC_ISO14443b) \ $(SRC_CRAPTO1) \ $(SRC_ICLASS) \ diff --git a/armsrc/appmain.c b/armsrc/appmain.c index e372f2eec..5d2f2146b 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -527,6 +527,11 @@ void SendCapabilities(void) { #else capabilities.compiled_with_iclass = false; #endif +#ifdef WITH_NFCBARCODE + capabilities.compiled_with_nfcbarcode = true; +#else + capabilities.compiled_with_nfcbarcode = false; +#endif #ifdef WITH_LCD capabilities.compiled_with_lcd = true; #else @@ -1279,6 +1284,9 @@ static void PacketReceived(PacketCommandNG *packet) { DetectNACKbug(); break; } +#endif + +#ifdef WITH_NFCBARCODE case CMD_HF_THINFILM_READ: { ReadThinFilm(); break; diff --git a/client/cmdhfthinfilm.c b/client/cmdhfthinfilm.c index 928660c6e..665802d0e 100644 --- a/client/cmdhfthinfilm.c +++ b/client/cmdhfthinfilm.c @@ -213,9 +213,9 @@ static int CmdHfThinFilmList(const char *Cmd) { static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, - {"info", CmdHfThinFilmInfo, IfPm3Flash, "Tag information"}, - {"list", CmdHfThinFilmList, AlwaysAvailable, "List ISO 14443A / Thinfilm history - not correct"}, - {"sim", CmdHfThinFilmSim, IfPm3Flash, "Fake Thinfilm tag"}, + {"info", CmdHfThinFilmInfo, IfPm3NfcBarcode, "Tag information"}, + {"list", CmdHfThinFilmList, AlwaysAvailable, "List NFC Barcode / Thinfilm history - not correct"}, + {"sim", CmdHfThinFilmSim, IfPm3NfcBarcode, "Fake Thinfilm tag"}, {NULL, NULL, NULL, NULL} }; diff --git a/client/cmdparser.c b/client/cmdparser.c index 077ba8ac5..be0de1c50 100644 --- a/client/cmdparser.c +++ b/client/cmdparser.c @@ -133,6 +133,12 @@ bool IfPm3Iclass(void) { return pm3_capabilities.compiled_with_iclass; } +bool IfPm3NfcBarcode(void) { + if (!IfPm3Present()) + return false; + return pm3_capabilities.compiled_with_nfcbarcode; +} + bool IfPm3Lcd(void) { if (!IfPm3Present()) return false; diff --git a/client/cmdparser.h b/client/cmdparser.h index c5aa5460e..06eb02848 100644 --- a/client/cmdparser.h +++ b/client/cmdparser.h @@ -38,6 +38,7 @@ bool IfPm3Iso15693(void); bool IfPm3Felica(void); bool IfPm3Legicrf(void); bool IfPm3Iclass(void); +bool IfPm3NfcBarcode(void); bool IfPm3Lcd(void); // Print help for each command in the command array diff --git a/common/Makefile.hal b/common/Makefile.hal index 46154d244..68de2b154 100644 --- a/common/Makefile.hal +++ b/common/Makefile.hal @@ -111,8 +111,10 @@ PLATFORM_DEFS += \ -DWITH_ISO14443a \ -DWITH_ICLASS \ -DWITH_FELICA \ + -DWITH_NFCBARCODE \ -DWITH_HFSNIFF + # Standalone mode ifneq ($(strip $(filter $(PLATFORM_DEFS),$(STANDALONE_REQ_DEFS))),$(strip $(STANDALONE_REQ_DEFS))) $(error Chosen Standalone mode $(STANDALONE) requires $(strip $(STANDALONE_REQ_DEFS)), unsupported by $(PLTNAME)) diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index bce5c28ed..267ac749a 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -178,6 +178,7 @@ typedef struct { bool compiled_with_felica : 1; bool compiled_with_legicrf : 1; bool compiled_with_iclass : 1; + bool compiled_with_nfcbarcode : 1; // misc bool compiled_with_lcd : 1; @@ -185,7 +186,7 @@ typedef struct { bool hw_available_flash : 1; bool hw_available_smartcard : 1; } PACKED capabilities_t; -#define CAPABILITIES_VERSION 2 +#define CAPABILITIES_VERSION 3 extern capabilities_t pm3_capabilities; // For CMD_LF_T55XX_WRITEBL From 25f358955b917a2fc028ff413c29499dda81eee1 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 3 Aug 2019 22:14:04 +0200 Subject: [PATCH 0244/1854] make hf search robust to various HF configurations --- armsrc/appmain.c | 6 ++++ armsrc/iso14443a.c | 20 +++++++------- armsrc/iso14443a.h | 2 +- armsrc/thinfilm.c | 2 +- client/cmdhf.c | 69 +++++++++++++++++++++++++++++----------------- client/util.h | 2 +- include/pm3_cmd.h | 1 + 7 files changed, 63 insertions(+), 39 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 5d2f2146b..5c2788b53 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1090,6 +1090,12 @@ static void PacketReceived(PacketCommandNG *packet) { } #endif +// always available + case CMD_HF_DROPFIELD: { + hf_field_off(); + break; + } + #ifdef WITH_ISO14443a case CMD_HF_ISO14443A_SNIFF: { SniffIso14443a(packet->data.asBytes[0]); diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 554fe57fa..e5bf6487a 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -14,7 +14,7 @@ #define MAX_ISO14A_TIMEOUT 524288 static uint32_t iso14a_timeout; // if iso14443a not active - transmit/receive dont try to execute -static bool iso14443a_active = false; +static bool hf_field_active = false; uint8_t colpos = 0; int rsamples = 0; @@ -1629,7 +1629,7 @@ void PrepareDelayedTransfer(uint16_t delay) { //------------------------------------------------------------------------------------- static void TransmitFor14443a(const uint8_t *cmd, uint16_t len, uint32_t *timing) { - if (!iso14443a_active) + if (!hf_field_active) return; FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD); @@ -2014,7 +2014,7 @@ bool EmLogTrace(uint8_t *reader_data, uint16_t reader_len, uint32_t reader_Start //----------------------------------------------------------------------------- bool GetIso14443aAnswerFromTag_Thinfilm(uint8_t *receivedResponse, uint8_t *received_len) { - if (!iso14443a_active) + if (!hf_field_active) return false; // Set FPGA mode to "reader listen mode", no modulation (listen @@ -2063,7 +2063,7 @@ bool GetIso14443aAnswerFromTag_Thinfilm(uint8_t *receivedResponse, uint8_t *rec static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receivedResponsePar, uint16_t offset) { uint32_t c = 0; - if (!iso14443a_active) + if (!hf_field_active) return false; // Set FPGA mode to "reader listen mode", no modulation (listen @@ -2504,14 +2504,14 @@ void iso14443a_setup(uint8_t fpga_minor_mode) { NextTransferTime = 2 * DELAY_ARM2AIR_AS_READER; iso14a_set_timeout(1060); // 106 * 10ms default - iso14443a_active = true; + hf_field_active = true; } -void iso14443a_off(void) { +void hf_field_off(void) { FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); - iso14443a_active = false; + hf_field_active = false; } /* Peter Fillmore 2015 @@ -2716,7 +2716,7 @@ void ReaderIso14443a(PacketCommandNG *c) { return; OUT: - iso14443a_off(); + hf_field_off(); set_tracing(false); } @@ -3011,7 +3011,7 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) { reply_mix(CMD_ACK, isOK, 0, 0, buf, sizeof(buf)); - iso14443a_off(); + hf_field_off(); set_tracing(false); } @@ -3250,6 +3250,6 @@ void DetectNACKbug(void) { //reply_mix(CMD_ACK, isOK, num_nacks, i, 0, 0); BigBuf_free(); - iso14443a_off(); + hf_field_off(); set_tracing(false); } diff --git a/armsrc/iso14443a.h b/armsrc/iso14443a.h index fab0dbdeb..323fb8a97 100644 --- a/armsrc/iso14443a.h +++ b/armsrc/iso14443a.h @@ -132,7 +132,7 @@ int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, bool send_chaining, void *data, u int iso14443a_select_card(uint8_t *uid_ptr, iso14a_card_select_t *p_card, uint32_t *cuid_ptr, bool anticollision, uint8_t num_cascades, bool no_rats); int iso14443a_fast_select_card(uint8_t *uid_ptr, uint8_t num_cascades); void iso14a_set_trigger(bool enable); -void iso14443a_off(void); +void hf_field_off(void); int EmSendCmd14443aRaw(uint8_t *resp, uint16_t respLen); int EmSend4bit(uint8_t resp); diff --git a/armsrc/thinfilm.c b/armsrc/thinfilm.c index 93d46e8a1..9230642e0 100644 --- a/armsrc/thinfilm.c +++ b/armsrc/thinfilm.c @@ -32,7 +32,7 @@ void ReadThinFilm(void) { bool status = GetIso14443aAnswerFromTag_Thinfilm(buf, &len); reply_ng(CMD_HF_THINFILM_READ, status ? PM3_SUCCESS : PM3_ENODATA, buf, len); - iso14443a_off(); + hf_field_off(); set_tracing(false); } diff --git a/client/cmdhf.c b/client/cmdhf.c index 2ef54773d..6e1dcccdb 100644 --- a/client/cmdhf.c +++ b/client/cmdhf.c @@ -54,42 +54,59 @@ int CmdHFSearch(const char *Cmd) { PrintAndLogEx(INFO, "Checking for known tags...\n"); - if (infoThinFilm(false) == PM3_SUCCESS) { - PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Thinfilm tag") " found\n"); - return 1; + if (IfPm3NfcBarcode()) { + if (infoThinFilm(false) == PM3_SUCCESS) { + PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Thinfilm tag") " found\n"); + return 1; + } } - - if (infoHF14A(false, false) > 0) { - PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("ISO14443-A tag") " found\n"); - return 1; + if (IfPm3Iso14443a()) { + if (infoHF14A(false, false) > 0) { + PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("ISO14443-A tag") " found\n"); + return 1; + } } - if (readHF15Uid(false) == 1) { - PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("ISO15693 tag") " found\n"); - return 1; + if (IfPm3Iso15693()) { + if (readHF15Uid(false) == 1) { + PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("ISO15693 tag") " found\n"); + DropField(); + return 1; + } + DropField(); } - if (readLegicUid(false) == 0) { - PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("LEGIC tag") " found\n"); - return 1; + if (IfPm3Legicrf()) { + if (readLegicUid(false) == 0) { + PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("LEGIC tag") " found\n"); + return 1; + } } - if (readTopazUid() == 0) { - PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Topaz tag") " found\n"); - return 1; + if (IfPm3Iso14443a()) { + if (readTopazUid() == 0) { + PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Topaz tag") " found\n"); + return 1; + } } // 14b and iclass is the longest test (put last) - if (readHF14B(false) == 1) { - PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("ISO14443-B tag") " found\n"); - return 1; + if (IfPm3Iso14443a()) { + if (readHF14B(false) == 1) { + PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("ISO14443-B tag") " found\n"); + return 1; + } } - if (readIclass(false, false) == 1) { - PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("iClass tag / PicoPass tag") " found\n"); - return 1; + if (IfPm3Iclass()) { + if (readIclass(false, false) == 1) { + PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("iClass tag / PicoPass tag") " found\n"); + return 1; + } } /* - ans = CmdHFFelicaReader("s"); - if (ans) { - PrintAndLogEx(NORMAL, "\nValid " _GREEN_("ISO18092 / FeliCa tag") " found\n"); - return ans; + if (IfPm3Felica()) { + ans = CmdHFFelicaReader("s"); + if (ans) { + PrintAndLogEx(NORMAL, "\nValid " _GREEN_("ISO18092 / FeliCa tag") " found\n"); + return ans; + } } */ diff --git a/client/util.h b/client/util.h index f1d55b140..8861045d8 100644 --- a/client/util.h +++ b/client/util.h @@ -33,7 +33,7 @@ #ifndef DropField #define DropField() { \ - clearCommandBuffer(); SendCommandMIX(CMD_HF_ISO14443A_READER, 0, 0, 0, NULL, 0); \ + clearCommandBuffer(); SendCommandNG(CMD_HF_DROPFIELD, NULL, 0); \ } #endif diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 267ac749a..f3231fe5a 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -425,6 +425,7 @@ typedef struct { #define CMD_MEASURE_ANTENNA_TUNING 0x0400 #define CMD_MEASURE_ANTENNA_TUNING_HF 0x0401 #define CMD_LISTEN_READER_FIELD 0x0420 +#define CMD_HF_DROPFIELD 0x0430 // For direct FPGA control #define CMD_FPGA_MAJOR_MODE_OFF 0x0500 From 3dae7483142b8e3489bf7eae2516ec56ed700581 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 3 Aug 2019 22:28:58 +0200 Subject: [PATCH 0245/1854] thinfilm is ok with thumb --- armsrc/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/Makefile b/armsrc/Makefile index cd42ae13f..6619e259d 100644 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@ -94,6 +94,7 @@ THUMBSRC = start.c \ protocols.c \ $(SRC_LCD) \ $(SRC_ISO15693) \ + $(SRC_NFCBARCODE) \ $(SRC_LF) \ $(SRC_ZLIB) \ $(SRC_LEGIC) \ @@ -115,7 +116,6 @@ THUMBSRC = start.c \ # These are to be compiled in ARM mode ARMSRC = fpgaloader.c \ $(SRC_ISO14443a) \ - $(SRC_NFCBARCODE) \ $(SRC_ISO14443b) \ $(SRC_CRAPTO1) \ $(SRC_ICLASS) \ From 61538bd635ff77ad0f36a18cb142c0530040e790 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 3 Aug 2019 22:37:01 +0200 Subject: [PATCH 0246/1854] thinfilm simulation when on battery --- armsrc/thinfilm.c | 4 ++-- client/cmdhfthinfilm.c | 13 +++++++++---- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/armsrc/thinfilm.c b/armsrc/thinfilm.c index 9230642e0..735fdb041 100644 --- a/armsrc/thinfilm.c +++ b/armsrc/thinfilm.c @@ -136,13 +136,13 @@ void SimulateThinFilm(uint8_t *data, size_t len) { EmSendCmdThinfilmRaw(ToSend, ToSendMax); if (!reader_detected) { LED_B_ON(); - Dbprintf("Reader detected, start beaming data"); + //Dbprintf("Reader detected, start beaming data"); reader_detected = true; } } else { if (reader_detected) { LED_B_OFF(); - Dbprintf("Reader gone, stop beaming data"); + //Dbprintf("Reader gone, stop beaming data"); reader_detected = false; } } diff --git a/client/cmdhfthinfilm.c b/client/cmdhfthinfilm.c index 665802d0e..454641bd8 100644 --- a/client/cmdhfthinfilm.c +++ b/client/cmdhfthinfilm.c @@ -196,12 +196,17 @@ static int CmdHfThinFilmSim(const char *Cmd) { PacketResponseNG resp; PrintAndLogEx(SUCCESS, "press pm3-button to abort simulation"); - while (!kbd_enter_pressed()) { - if (WaitForResponseTimeout(CMD_HF_THINFILM_SIMULATE, &resp, 1500) == 0) continue; + int ret; + while (!(ret = kbd_enter_pressed())) { + if (WaitForResponseTimeout(CMD_HF_THINFILM_SIMULATE, &resp, 500) == 0) continue; if (resp.status != PM3_SUCCESS) break; } - - PrintAndLogEx(INFO, "Done"); + if (ret) { + PrintAndLogEx(INFO, "Client side interrupted"); + PrintAndLogEx(WARNING, "Simulation still running on Proxmark3 till next command or button press"); + } else { + PrintAndLogEx(INFO, "Done"); + } return PM3_SUCCESS; } From 60bfc37f352373598c88aba68b62c684dc059a94 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 3 Aug 2019 22:52:32 +0200 Subject: [PATCH 0247/1854] remove more dummy cmds --- armsrc/appmain.c | 7 ------- client/deprecated-hid-flasher/flasher/usb_cmd.h | 2 -- include/pm3_cmd.h | 2 -- 3 files changed, 11 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 5c2788b53..fd33c1ec8 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1160,10 +1160,6 @@ static void PacketReceived(PacketCommandNG *packet) { MifareWriteBlock(packet->oldarg[0], packet->oldarg[1], packet->data.asBytes); break; } - //case CMD_HF_MIFAREU_WRITEBL_COMPAT: { - //MifareUWriteBlockCompat(packet->oldarg[0], packet->data.asBytes); - //break; - //} case CMD_HF_MIFAREU_WRITEBL: { MifareUWriteBlock(packet->oldarg[0], packet->oldarg[1], packet->data.asBytes); break; @@ -1283,9 +1279,6 @@ static void PacketReceived(PacketCommandNG *packet) { MifareSendCommand(packet->oldarg[0], packet->oldarg[1], packet->data.asBytes); break; } - case CMD_HF_MIFARE_COLLECT_NONCES: { - break; - } case CMD_HF_MIFARE_NACK_DETECT: { DetectNACKbug(); break; diff --git a/client/deprecated-hid-flasher/flasher/usb_cmd.h b/client/deprecated-hid-flasher/flasher/usb_cmd.h index 58da5dd0a..75136c1f4 100644 --- a/client/deprecated-hid-flasher/flasher/usb_cmd.h +++ b/client/deprecated-hid-flasher/flasher/usb_cmd.h @@ -189,7 +189,6 @@ typedef struct { #define CMD_HF_MIFAREU_READCARD 0x0721 #define CMD_HF_MIFARE_WRITEBL 0x0622 #define CMD_HF_MIFAREU_WRITEBL 0x0722 -#define CMD_HF_MIFAREU_WRITEBL_COMPAT 0x0723 #define CMD_HF_MIFARE_CHKKEYS 0x0623 #define CMD_HF_MIFARE_SETMOD 0x0624 @@ -210,7 +209,6 @@ typedef struct { #define CMD_HF_DESFIRE_INFO 0x072d #define CMD_HF_DESFIRE_COMMAND 0x072e -#define CMD_HF_MIFARE_COLLECT_NONCES 0x072f #define CMD_HF_SNIFF 0x0800 diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index f3231fe5a..d59ba9589 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -454,7 +454,6 @@ typedef struct { #define CMD_HF_MIFAREU_READCARD 0x0721 #define CMD_HF_MIFARE_WRITEBL 0x0622 #define CMD_HF_MIFAREU_WRITEBL 0x0722 -#define CMD_HF_MIFAREU_WRITEBL_COMPAT 0x0723 #define CMD_HF_MIFARE_CHKKEYS 0x0623 #define CMD_HF_MIFARE_SETMOD 0x0624 @@ -475,7 +474,6 @@ typedef struct { #define CMD_HF_DESFIRE_INFO 0x072d #define CMD_HF_DESFIRE_COMMAND 0x072e -#define CMD_HF_MIFARE_COLLECT_NONCES 0x072f #define CMD_HF_MIFARE_NACK_DETECT 0x0730 #define CMD_HF_SNIFF 0x0800 From a90e5e1858587ba8c4b07369e0c4226f7746a980 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 3 Aug 2019 23:36:55 +0200 Subject: [PATCH 0248/1854] chg: legic cmds uses return macros. chg: hf search started to use macros --- armsrc/thinfilm.h | 1 - client/cmdhf.c | 31 ++++---- client/cmdhflegic.c | 144 +++++++++++++++++------------------ client/scripts/ndef_dump.lua | 3 +- include/pm3_cmd.h | 2 + 5 files changed, 92 insertions(+), 89 deletions(-) diff --git a/armsrc/thinfilm.h b/armsrc/thinfilm.h index a9024338b..15453e3c2 100644 --- a/armsrc/thinfilm.h +++ b/armsrc/thinfilm.h @@ -18,7 +18,6 @@ extern "C" { #include "pm3_cmd.h" #include "cmd.h" #include "apps.h" -//#include "util.h" #include "iso14443a.h" void ReadThinFilm(void); diff --git a/client/cmdhf.c b/client/cmdhf.c index 6e1dcccdb..4e88f19f6 100644 --- a/client/cmdhf.c +++ b/client/cmdhf.c @@ -18,7 +18,7 @@ static int usage_hf_search() { PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h - This help"); PrintAndLogEx(NORMAL, ""); - return 0; + return PM3_SUCCESS; } static int usage_hf_sniff() { @@ -34,7 +34,7 @@ static int usage_hf_sniff() { PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf sniff"); PrintAndLogEx(NORMAL, " hf sniff 1000 0"); - return 0; + return PM3_SUCCESS; } static int usage_hf_tune() { @@ -44,7 +44,7 @@ static int usage_hf_tune() { PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " - number of iterations (default: infinite)"); PrintAndLogEx(NORMAL, ""); - return 0; + return PM3_SUCCESS; } int CmdHFSearch(const char *Cmd) { @@ -57,46 +57,47 @@ int CmdHFSearch(const char *Cmd) { if (IfPm3NfcBarcode()) { if (infoThinFilm(false) == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Thinfilm tag") " found\n"); - return 1; + return PM3_SUCCESS; } } if (IfPm3Iso14443a()) { if (infoHF14A(false, false) > 0) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("ISO14443-A tag") " found\n"); - return 1; + return PM3_SUCCESS; } } if (IfPm3Iso15693()) { if (readHF15Uid(false) == 1) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("ISO15693 tag") " found\n"); DropField(); - return 1; + return PM3_SUCCESS; } + // until refactoring of ISO15693 cmds, this is needed. DropField(); } if (IfPm3Legicrf()) { - if (readLegicUid(false) == 0) { + if (readLegicUid(false) == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("LEGIC tag") " found\n"); - return 1; + return PM3_SUCCESS; } } if (IfPm3Iso14443a()) { - if (readTopazUid() == 0) { + if (readTopazUid() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Topaz tag") " found\n"); - return 1; + return PM3_SUCCESS; } } // 14b and iclass is the longest test (put last) if (IfPm3Iso14443a()) { if (readHF14B(false) == 1) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("ISO14443-B tag") " found\n"); - return 1; + return PM3_SUCCESS; } } if (IfPm3Iclass()) { if (readIclass(false, false) == 1) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("iClass tag / PicoPass tag") " found\n"); - return 1; + return PM3_SUCCESS; } } @@ -111,7 +112,7 @@ int CmdHFSearch(const char *Cmd) { */ PrintAndLogEx(FAILED, "\nno known/supported 13.56 MHz tags found\n"); - return 0; + return PM3_ESOFT; } int CmdHFTune(const char *Cmd) { @@ -164,7 +165,7 @@ int CmdHFSniff(const char *Cmd) { clearCommandBuffer(); SendCommandMIX(CMD_HF_SNIFF, skippairs, skiptriggers, 0, NULL, 0); - return 0; + return PM3_SUCCESS; } static command_t CommandTable[] = { @@ -198,5 +199,5 @@ int CmdHF(const char *Cmd) { int CmdHelp(const char *Cmd) { (void)Cmd; // Cmd is not used so far CmdsHelp(CommandTable); - return 0; + return PM3_SUCCESS; } diff --git a/client/cmdhflegic.c b/client/cmdhflegic.c index 9daad8387..20fba3781 100644 --- a/client/cmdhflegic.c +++ b/client/cmdhflegic.c @@ -26,7 +26,7 @@ static int usage_legic_calccrc(void) { PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf legic crc d deadbeef1122"); PrintAndLogEx(NORMAL, " hf legic crc d deadbeef1122 u 9A c 16"); - return 0; + return PM3_SUCCESS; } static int usage_legic_rdmem(void) { PrintAndLogEx(NORMAL, "Read data from a legic tag."); @@ -41,7 +41,7 @@ static int usage_legic_rdmem(void) { PrintAndLogEx(NORMAL, " hf legic rdmem 0 16 - reads from byte[0] 0x16 bytes(system header)"); PrintAndLogEx(NORMAL, " hf legic rdmem 0 4 55 - reads from byte[0] 0x4 bytes with IV 0x55"); PrintAndLogEx(NORMAL, " hf legic rdmem 0 100 55 - reads 0x100 bytes with IV 0x55"); - return 0; + return PM3_SUCCESS; } static int usage_legic_sim(void) { PrintAndLogEx(NORMAL, "Simulates a LEGIC Prime tag. MIM22, MIM256, MIM1024 types can be emulated"); @@ -55,7 +55,7 @@ static int usage_legic_sim(void) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf legic sim 2"); - return 0; + return PM3_SUCCESS; } static int usage_legic_write(void) { PrintAndLogEx(NORMAL, "Write data to a LEGIC Prime tag. It autodetects tagsize to make sure size"); @@ -68,7 +68,7 @@ static int usage_legic_write(void) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf legic write o 10 d 11223344 - Write 0x11223344 starting from offset 0x10"); - return 0; + return PM3_SUCCESS; } static int usage_legic_reader(void) { PrintAndLogEx(NORMAL, "Read UID and type information from a legic tag."); @@ -78,7 +78,7 @@ static int usage_legic_reader(void) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf legic reader"); - return 0; + return PM3_SUCCESS; } static int usage_legic_info(void) { PrintAndLogEx(NORMAL, "Reads information from a legic prime tag."); @@ -89,7 +89,7 @@ static int usage_legic_info(void) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf legic info"); - return 0; + return PM3_SUCCESS; } static int usage_legic_dump(void) { PrintAndLogEx(NORMAL, "Reads all pages from LEGIC Prime MIM22, MIM256, MIM1024"); @@ -103,7 +103,7 @@ static int usage_legic_dump(void) { PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf legic dump"); PrintAndLogEx(NORMAL, " hf legic dump o myfile"); - return 0; + return PM3_SUCCESS; } static int usage_legic_restore(void) { PrintAndLogEx(NORMAL, "Reads binary file and it autodetects card type and verifies that the file has the same size"); @@ -115,7 +115,7 @@ static int usage_legic_restore(void) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf legic restore i myfile"); - return 0; + return PM3_SUCCESS; } static int usage_legic_eload(void) { PrintAndLogEx(NORMAL, "It loads binary dump from the file `filename.bin`"); @@ -129,7 +129,7 @@ static int usage_legic_eload(void) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf legic eload 2 myfile"); - return 0; + return PM3_SUCCESS; } static int usage_legic_esave(void) { PrintAndLogEx(NORMAL, "It saves binary dump into the file `filename.bin` or `cardID.bin`"); @@ -143,7 +143,7 @@ static int usage_legic_esave(void) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf legic esave 2 myfile"); - return 0; + return PM3_SUCCESS; } static int usage_legic_wipe(void) { PrintAndLogEx(NORMAL, "Fills a legic tag memory with zeros. From byte7 and to the end."); @@ -153,7 +153,7 @@ static int usage_legic_wipe(void) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf legic wipe"); - return 0; + return PM3_SUCCESS; } /* * Output BigBuf and deobfuscate LEGIC RF tag data. @@ -175,9 +175,9 @@ static int CmdLegicInfo(const char *Cmd) { // tagtype legic_card_select_t card; - if (legic_get_type(&card)) { + if (legic_get_type(&card) != PM3_SUCCESS) { PrintAndLogEx(WARNING, "Failed to identify tagtype"); - return 1; + return PM3_ESOFT; } PrintAndLogEx(SUCCESS, "Reading full tag memory of %d bytes...", card.cardsize); @@ -186,14 +186,14 @@ static int CmdLegicInfo(const char *Cmd) { uint8_t *data = calloc(card.cardsize, sizeof(uint8_t)); if (!data) { PrintAndLogEx(WARNING, "Cannot allocate memory"); - return 2; + return PM3_EMALLOC; } int status = legic_read_mem(0, card.cardsize, 0x55, data, &datalen); - if (status > 0) { + if (status != PM3_SUCCESS) { PrintAndLogEx(WARNING, "Failed reading memory"); free(data); - return 3; + return status; } // Output CDF System area (9 bytes) plus remaining header area (12 bytes) @@ -479,7 +479,7 @@ static int CmdLegicInfo(const char *Cmd) { out: free(data); - return 0; + return PM3_SUCCESS; } // params: @@ -497,7 +497,7 @@ static int CmdLegicRdmem(const char *Cmd) { // sanity checks if (len + offset >= MAX_LENGTH) { PrintAndLogEx(WARNING, "Out-of-bounds, Cardsize = %d, [offset+len = %d ]", MAX_LENGTH, len + offset); - return -1; + return PM3_EOUTOFBOUND; } PrintAndLogEx(SUCCESS, "Reading %d bytes, from offset %d", len, offset); @@ -506,11 +506,11 @@ static int CmdLegicRdmem(const char *Cmd) { uint8_t *data = calloc(len, sizeof(uint8_t)); if (!data) { PrintAndLogEx(WARNING, "Cannot allocate memory"); - return -2; + return PM3_EMALLOC; } int status = legic_read_mem(offset, len, iv, data, &datalen); - if (status == 0) { + if (status == PM3_SUCCESS) { PrintAndLogEx(NORMAL, "\n ## | 0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F"); PrintAndLogEx(NORMAL, "-----+------------------------------------------------------------------------------------------------"); print_hex_break(data, datalen, 32); @@ -528,7 +528,7 @@ static int CmdLegicRfSim(const char *Cmd) { sscanf(Cmd, " %" SCNi64, &id); clearCommandBuffer(); SendCommandMIX(CMD_HF_LEGIC_SIMULATE, id, 0, 0, NULL, 0); - return 0; + return PM3_SUCCESS; } static int CmdLegicRfWrite(const char *Cmd) { @@ -607,9 +607,9 @@ static int CmdLegicRfWrite(const char *Cmd) { // tagtype legic_card_select_t card; - if (legic_get_type(&card)) { + if (legic_get_type(&card) != PM3_SUCCESS) { PrintAndLogEx(WARNING, "Failed to identify tagtype"); - return -1; + return PM3_ESOFT; } legic_print_type(card.cardsize, 0); @@ -618,12 +618,12 @@ static int CmdLegicRfWrite(const char *Cmd) { // UID 4+1 bytes can't be written to. if (offset < 5) { PrintAndLogEx(WARNING, "Out-of-bounds, bytes 0-1-2-3-4 can't be written to. Offset = %d", offset); - return -2; + return PM3_EOUTOFBOUND; } if (len + offset >= card.cardsize) { PrintAndLogEx(WARNING, "Out-of-bounds, Cardsize = %d, [offset+len = %d ]", card.cardsize, len + offset); - return -2; + return PM3_EOUTOFBOUND; } if (offset == 5 || offset == 6) { @@ -634,7 +634,7 @@ static int CmdLegicRfWrite(const char *Cmd) { bool overwrite = (answer[0] == 'y' || answer[0] == 'Y'); if (!overwrite) { PrintAndLogEx(NORMAL, "command cancelled"); - return 0; + return PM3_EOPABORTED; } } @@ -654,7 +654,7 @@ static int CmdLegicRfWrite(const char *Cmd) { fflush(stdout); if (timeout > 7) { PrintAndLogEx(WARNING, "\ncommand execution time out"); - return 1; + return PM3_ETIMEOUT; } } PrintAndLogEx(NORMAL, "\n"); @@ -662,10 +662,10 @@ static int CmdLegicRfWrite(const char *Cmd) { uint8_t isOK = resp.oldarg[0] & 0xFF; if (!isOK) { PrintAndLogEx(WARNING, "Failed writing tag"); - return 1; + return PM3_ERFTRANS; } - return 0; + return PM3_SUCCESS; } static int CmdLegicCalcCrc(const char *Cmd) { @@ -747,7 +747,7 @@ static int CmdLegicCalcCrc(const char *Cmd) { } if (data) free(data); - return 0; + return PM3_SUCCESS; } int legic_read_mem(uint32_t offset, uint32_t len, uint32_t iv, uint8_t *out, uint16_t *outlen) { @@ -765,7 +765,7 @@ int legic_read_mem(uint32_t offset, uint32_t len, uint32_t iv, uint8_t *out, uin fflush(stdout); if (timeout > 7) { PrintAndLogEx(WARNING, "\ncommand execution time out"); - return 1; + return PM3_ETIMEOUT; } } PrintAndLogEx(NORMAL, "\n"); @@ -774,7 +774,7 @@ int legic_read_mem(uint32_t offset, uint32_t len, uint32_t iv, uint8_t *out, uin *outlen = resp.oldarg[1]; if (!isOK) { PrintAndLogEx(WARNING, "Failed reading tag"); - return 2; + return PM3_ESOFT; } if (*outlen != len) @@ -783,9 +783,9 @@ int legic_read_mem(uint32_t offset, uint32_t len, uint32_t iv, uint8_t *out, uin // copy data from device if (!GetFromDevice(BIG_BUF_EML, out, *outlen, 0, NULL, 0, NULL, 2500, false)) { PrintAndLogEx(WARNING, "Fail, transfer from device time-out"); - return 4; + return PM3_ETIMEOUT; } - return 0; + return PM3_SUCCESS; } int legic_print_type(uint32_t tagtype, uint8_t spaces) { @@ -801,24 +801,24 @@ int legic_print_type(uint32_t tagtype, uint8_t spaces) { PrintAndLogEx(SUCCESS, "%sTYPE : MIM%d card (1002 bytes)", spacer, tagtype); else PrintAndLogEx(INFO, "%sTYPE : Unknown %06x", spacer, tagtype); - return 0; + return PM3_SUCCESS; } int legic_get_type(legic_card_select_t *card) { - if (card == NULL) return 1; + if (card == NULL) return PM3_EINVARG; clearCommandBuffer(); SendCommandNG(CMD_HF_LEGIC_INFO, NULL, 0); PacketResponseNG resp; if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) - return 2; + return PM3_ETIMEOUT; uint8_t isOK = resp.oldarg[0] & 0xFF; if (!isOK) - return 3; + return PM3_ESOFT; memcpy(card, (legic_card_select_t *)resp.data.asBytes, sizeof(legic_card_select_t)); - return 0; + return PM3_SUCCESS; } void legic_chk_iv(uint32_t *iv) { if ((*iv & 0x7F) != *iv) { @@ -888,9 +888,9 @@ static int CmdLegicDump(const char *Cmd) { // tagtype legic_card_select_t card; - if (legic_get_type(&card)) { + if (legic_get_type(&card) != PM3_SUCCESS) { PrintAndLogEx(WARNING, "Failed to identify tagtype"); - return -1; + return PM3_ESOFT; } dumplen = card.cardsize; @@ -908,7 +908,7 @@ static int CmdLegicDump(const char *Cmd) { fflush(stdout); if (timeout > 7) { PrintAndLogEx(WARNING, "\ncommand execution time out"); - return 1; + return PM3_ETIMEOUT; } } PrintAndLogEx(NORMAL, "\n"); @@ -916,14 +916,14 @@ static int CmdLegicDump(const char *Cmd) { uint8_t isOK = resp.oldarg[0] & 0xFF; if (!isOK) { PrintAndLogEx(WARNING, "Failed dumping tag data"); - return 2; + return PM3_ERFTRANS; } uint16_t readlen = resp.oldarg[1]; uint8_t *data = calloc(readlen, sizeof(uint8_t)); if (!data) { PrintAndLogEx(WARNING, "Fail, cannot allocate memory"); - return 3; + return PM3_EMALLOC; } if (readlen != dumplen) @@ -933,7 +933,7 @@ static int CmdLegicDump(const char *Cmd) { if (!GetFromDevice(BIG_BUF_EML, data, readlen, 0, NULL, 0, NULL, 2500, false)) { PrintAndLogEx(WARNING, "Fail, transfer from device time-out"); free(data); - return 4; + return PM3_ETIMEOUT; } // user supplied filename? @@ -994,9 +994,9 @@ static int CmdLegicRestore(const char *Cmd) { // tagtype legic_card_select_t card; - if (legic_get_type(&card)) { + if (legic_get_type(&card) != PM3_SUCCESS) { PrintAndLogEx(WARNING, "Failed to identify tagtype"); - return 1; + return PM3_ESOFT; } numofbytes = card.cardsize; @@ -1004,7 +1004,7 @@ static int CmdLegicRestore(const char *Cmd) { uint8_t *data = calloc(numofbytes, sizeof(uint8_t)); if (!data) { PrintAndLogEx(WARNING, "Fail, cannot allocate memory"); - return 2; + return PM3_EMALLOC; } legic_print_type(numofbytes, 0); @@ -1029,7 +1029,7 @@ static int CmdLegicRestore(const char *Cmd) { PrintAndLogEx(WARNING, "Fail, filesize and cardsize is not equal. [%u != %u]", filesize, numofbytes); free(data); fclose(f); - return 4; + return PM3_EFILE; } // load file @@ -1039,7 +1039,7 @@ static int CmdLegicRestore(const char *Cmd) { if (bytes_read == 0) { PrintAndLogEx(ERR, "File reading error"); free(data); - return 2; + return PM3_EFILE; } PrintAndLogEx(SUCCESS, "Restoring to card"); @@ -1067,7 +1067,7 @@ static int CmdLegicRestore(const char *Cmd) { if (timeout > 7) { PrintAndLogEx(WARNING, "\ncommand execution time out"); free(data); - return 1; + return PM3_ETIMEOUT; } } PrintAndLogEx(NORMAL, "\n"); @@ -1076,7 +1076,7 @@ static int CmdLegicRestore(const char *Cmd) { if (!isOK) { PrintAndLogEx(WARNING, "Failed writing tag [msg = %u]", resp.oldarg[1] & 0xFF); free(data); - return 1; + return PM3_ERFTRANS; } PrintAndLogEx(SUCCESS, "Wrote chunk [offset %d | len %d | total %d", i, len, i + len); } @@ -1118,7 +1118,7 @@ static int CmdLegicELoad(const char *Cmd) { uint8_t *data = calloc(numofbytes, sizeof(uint8_t)); if (!data) { PrintAndLogEx(WARNING, "Fail, cannot allocate memory"); - return 3; + return PM3_EMALLOC; } // set up file @@ -1143,7 +1143,7 @@ static int CmdLegicELoad(const char *Cmd) { free(data); fclose(f); f = NULL; - return 2; + return PM3_EFILE; } fclose(f); f = NULL; @@ -1195,7 +1195,7 @@ static int CmdLegicESave(const char *Cmd) { uint8_t *data = calloc(numofbytes, sizeof(uint8_t)); if (!data) { PrintAndLogEx(WARNING, "Fail, cannot allocate memory"); - return 3; + return PM3_EMALLOC; } // download emulator memory @@ -1203,7 +1203,7 @@ static int CmdLegicESave(const char *Cmd) { if (!GetFromDevice(BIG_BUF_EML, data, numofbytes, 0, NULL, 0, NULL, 2500, false)) { PrintAndLogEx(WARNING, "Fail, transfer from device time-out"); free(data); - return 4; + return PM3_ETIMEOUT; } // user supplied filename? if (fileNlen < 1) @@ -1213,7 +1213,7 @@ static int CmdLegicESave(const char *Cmd) { saveFileEML(filename, data, numofbytes, 8); saveFile(filename, ".bin", data, numofbytes); - return 0; + return PM3_SUCCESS; } static int CmdLegicWipe(const char *Cmd) { @@ -1224,16 +1224,16 @@ static int CmdLegicWipe(const char *Cmd) { // tagtype legic_card_select_t card; - if (legic_get_type(&card)) { + if (legic_get_type(&card) != PM3_SUCCESS) { PrintAndLogEx(WARNING, "Failed to identify tagtype"); - return 1; + return PM3_ESOFT; } // set up buffer uint8_t *data = calloc(card.cardsize, sizeof(uint8_t)); if (!data) { PrintAndLogEx(WARNING, "Fail, cannot allocate memory"); - return 2; + return PM3_EMALLOC; } legic_print_type(card.cardsize, 0); @@ -1264,7 +1264,7 @@ static int CmdLegicWipe(const char *Cmd) { if (timeout > 7) { PrintAndLogEx(WARNING, "\ncommand execution time out"); free(data); - return 3; + return PM3_ETIMEOUT; } } PrintAndLogEx(NORMAL, "\n"); @@ -1273,18 +1273,18 @@ static int CmdLegicWipe(const char *Cmd) { if (!isOK) { PrintAndLogEx(WARNING, "Failed writing tag [msg = %u]", resp.oldarg[1] & 0xFF); free(data); - return 4; + return PM3_ERFTRANS; } } PrintAndLogEx(SUCCESS, "ok\n"); free(data); - return 0; + return PM3_SUCCESS; } static int CmdLegicList(const char *Cmd) { (void)Cmd; // Cmd is not used so far CmdTraceList("legic"); - return 0; + return PM3_SUCCESS; } static command_t CommandTable[] = { @@ -1307,7 +1307,7 @@ static command_t CommandTable[] = { static int CmdHelp(const char *Cmd) { (void)Cmd; // Cmd is not used so far CmdsHelp(CommandTable); - return 0; + return PM3_SUCCESS; } int CmdHFLegic(const char *Cmd) { @@ -1319,18 +1319,18 @@ int readLegicUid(bool verbose) { legic_card_select_t card; switch (legic_get_type(&card)) { - case 1: - return 2; - case 2: + case PM3_EINVARG: + return PM3_EINVARG; + case PM3_ETIMEOUT: if (verbose) PrintAndLogEx(WARNING, "command execution time out"); - return 1; - case 3: + return PM3_ETIMEOUT; + case PM3_ESOFT: if (verbose) PrintAndLogEx(WARNING, "legic card select failed"); - return 2; + return PM3_ESOFT; default: break; } PrintAndLogEx(SUCCESS, " UID : %s", sprint_hex(card.uid, sizeof(card.uid))); legic_print_type(card.cardsize, 0); - return 0; + return PM3_SUCCESS; } diff --git a/client/scripts/ndef_dump.lua b/client/scripts/ndef_dump.lua index 85909bb91..cb4be467b 100644 --- a/client/scripts/ndef_dump.lua +++ b/client/scripts/ndef_dump.lua @@ -2,7 +2,8 @@ local getopt = require('getopt') local cmds = require('commands') local lib14a = require('read14a') local utils = require('utils') - +-- +-- Refactored iceman, 2019 copyright = '' author = 'Martin Holst Swende & Asper' version = 'v1.0.1' diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index d59ba9589..b83cd6819 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -549,6 +549,8 @@ typedef struct { #define PM3_EINIT -15 // Expected a different answer error client/pm3: error when expecting one answer and got another one #define PM3_EWRONGANSVER -16 +// Memory out-of-bounds error client/pm3: error when a read/write is outside the expected array +#define PM3_EOUTOFBOUND -17 // No data pm3: no data available, no host frame available (not really an error) #define PM3_ENODATA -98 // Quit program client: reserved, order to quit the program From 88d2a61c0bca6c6ee3cd8effdda69771b650b5c8 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 4 Aug 2019 12:58:36 +0200 Subject: [PATCH 0249/1854] typo --- CHANGELOG.md | 2 +- client/lualibs/read14b.lua | 6 +++--- client/scripts/amiibo.lua | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d22975970..8d1551d65 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -303,7 +303,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Added to proxmark command line parameters `c` and `l` - execute command and lua script from command line (@merlokk) - Added to proxmark ability to execute commands from stdin (pipe) (@merlokk) - Added new standalone mode "HF Mifare ultra fast sniff/sim/clone - aka VIGIKPWN" (@cjbrigato) - - Added to `hf 14a apdu` - exchange apdu via iso1443-4 (@merlokk) + - Added to `hf 14a apdu` - exchange apdu via iso14443-4 (@merlokk) - Added to `hf 14a apdu` - apdu and tlv results parser (@merlokk) - Added `hf emv` commands (@merlokk) - lots of bug fixes (many many) diff --git a/client/lualibs/read14b.lua b/client/lualibs/read14b.lua index 50c939f63..aace09827 100644 --- a/client/lualibs/read14b.lua +++ b/client/lualibs/read14b.lua @@ -28,7 +28,7 @@ local ISO14B_COMMAND = { ISO14B_SELECT_SR = 0x80, } -local function parse1443b(data) +local function parse14443b(data) --[[ Based on this struct : @@ -79,7 +79,7 @@ local function read14443b(disconnect) local count,cmd,arg0,arg1,arg2 = bin.unpack('LLLL',result) if arg0 == 0 then data = string.sub(result, count) - info, err = parse1443b(data) + info, err = parse14443b(data) else err = 'iso14443b card select failed' end @@ -126,7 +126,7 @@ end local library = { read = read14443b, waitFor14443b = waitFor14443b, - parse1443b = parse1443b, + parse14443b = parse14443b, connect = connect14443b, disconnect = disconnect14443b, ISO14B_COMMAND = ISO14B_COMMAND, diff --git a/client/scripts/amiibo.lua b/client/scripts/amiibo.lua index 19866bd6f..10ede4008 100644 --- a/client/scripts/amiibo.lua +++ b/client/scripts/amiibo.lua @@ -205,7 +205,7 @@ local function main(args) return end - parsed_tag = reader.parse1443a(tag) + parsed_tag = reader.parse14443a(tag) print('Tag type:', parsed_tag.name) print('Tag UID:', parsed_tag.uid) print('Tag len:', tag:len()) From 1cb039255e2440a1de53fba39ccba417d066ac7d Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 4 Aug 2019 15:34:18 +0200 Subject: [PATCH 0250/1854] Add client option `-i` to stay in interactive mode after a script or command From https://github.com/iceman1001/proxmark3/commit/5a3f47433115dc20a2e666b43ce94be66a2cb375 with some fix in the logical flow --- CHANGELOG.md | 1 + client/proxgui.cpp | 8 ++++---- client/proxgui.h | 2 +- client/proxguiqt.h | 3 ++- client/proxmark3.c | 27 +++++++++++++++++++-------- client/proxmark3.h | 2 +- 6 files changed, 28 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d1551d65..4f3745c56 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Add client option `-i` to stay in interactive mode after a script or command (@DidierStevens/@doegox) - Add VSCode tasks (@ViRb3) - Better warn user of hardcoded hitag info (@ViRb3) - Format and docs hitag (@ViRb3) diff --git a/client/proxgui.cpp b/client/proxgui.cpp index 120f2b26d..c21352861 100644 --- a/client/proxgui.cpp +++ b/client/proxgui.cpp @@ -15,14 +15,14 @@ static ProxGuiQT *gui = NULL; static WorkerThread *main_loop_thread = NULL; -WorkerThread::WorkerThread(char *script_cmds_file, char *script_cmd) : script_cmds_file(script_cmds_file), script_cmd(script_cmd) { +WorkerThread::WorkerThread(char *script_cmds_file, char *script_cmd, bool stayInCommandLoop) : script_cmds_file(script_cmds_file), script_cmd(script_cmd), stayInCommandLoop(stayInCommandLoop) { } WorkerThread::~WorkerThread() { } void WorkerThread::run() { - main_loop(script_cmds_file, script_cmd); + main_loop(script_cmds_file, script_cmd, stayInCommandLoop); } extern "C" void ShowGraphWindow(void) { @@ -53,12 +53,12 @@ extern "C" void MainGraphics(void) { gui->MainLoop(); } -extern "C" void InitGraphics(int argc, char **argv, char *script_cmds_file, char *script_cmd) { +extern "C" void InitGraphics(int argc, char **argv, char *script_cmds_file, char *script_cmd, bool stayInCommandLoop) { #ifdef Q_WS_X11 if (getenv("DISPLAY") == NULL) return; #endif - main_loop_thread = new WorkerThread(script_cmds_file, script_cmd); + main_loop_thread = new WorkerThread(script_cmds_file, script_cmd, stayInCommandLoop); gui = new ProxGuiQT(argc, argv, main_loop_thread); } diff --git a/client/proxgui.h b/client/proxgui.h index dfbddbc0c..06b5a919e 100644 --- a/client/proxgui.h +++ b/client/proxgui.h @@ -22,7 +22,7 @@ void ShowGraphWindow(void); void HideGraphWindow(void); void RepaintGraphWindow(void); void MainGraphics(void); -void InitGraphics(int argc, char **argv, char *script_cmds_file, char *script_cmd); +void InitGraphics(int argc, char **argv, char *script_cmds_file, char *script_cmd, bool stayInCommandLoop); void ExitGraphics(void); #ifndef MAX_GRAPH_TRACE_LEN #define MAX_GRAPH_TRACE_LEN (40000 * 8) diff --git a/client/proxguiqt.h b/client/proxguiqt.h index e50bfe073..80d9e1ef4 100644 --- a/client/proxguiqt.h +++ b/client/proxguiqt.h @@ -93,12 +93,13 @@ class ProxWidget : public QWidget { class WorkerThread : public QThread { Q_OBJECT; public: - WorkerThread(char *, char *); + WorkerThread(char *, char *, bool); ~WorkerThread(); void run(); private: char *script_cmds_file; char *script_cmd; + bool stayInCommandLoop; }; class ProxGuiQT : public QObject { diff --git a/client/proxmark3.c b/client/proxmark3.c index 1d3a0e8b5..c4cd81b25 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -70,7 +70,7 @@ void __attribute__((force_align_arg_pointer)) #endif #endif -main_loop(char *script_cmds_file, char *script_cmd) { +main_loop(char *script_cmds_file, char *script_cmd, bool stayInCommandLoop) { char *cmd = NULL; bool execCommand = (script_cmd != NULL); @@ -138,7 +138,7 @@ main_loop(char *script_cmds_file, char *script_cmd) { script_cmd_len -= len; } else { // exit after exec command - if (script_cmd) + if (script_cmd && !stayInCommandLoop) break; // if there is a pipe from stdin @@ -206,7 +206,10 @@ main_loop(char *script_cmds_file, char *script_cmd) { cmd = NULL; } else { PrintAndLogEx(NORMAL, "\n"); - break; + if (script_cmds_file && stayInCommandLoop) + stayInCommandLoop = false; + else + break; } } // end while @@ -266,7 +269,7 @@ static void show_help(bool showFullHelp, char *exec_name) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "syntax: %s [-h|-t|-m]\n", exec_name); - PrintAndLogEx(NORMAL, " %s [[-p] ] [-b] [-w] [-f] [-c ]|[-l ]|[-s ]\n", exec_name); + PrintAndLogEx(NORMAL, " %s [[-p] ] [-b] [-w] [-f] [-c ]|[-l ]|[-s ] [-i]\n", exec_name); if (showFullHelp) { PrintAndLogEx(NORMAL, "options:"); @@ -280,6 +283,7 @@ static void show_help(bool showFullHelp, char *exec_name) { PrintAndLogEx(NORMAL, " -c/--command execute one Proxmark3 command (or several separated by ';')."); PrintAndLogEx(NORMAL, " -l/--lua execute lua script."); PrintAndLogEx(NORMAL, " -s/--script-file script file with one Proxmark3 command per line"); + PrintAndLogEx(NORMAL, " -i/--interactive enter interactive mode after executing the script or the command"); PrintAndLogEx(NORMAL, "\nsamples:"); PrintAndLogEx(NORMAL, " %s -h\n", exec_name); PrintAndLogEx(NORMAL, " %s -m\n", exec_name); @@ -302,6 +306,7 @@ int main(int argc, char *argv[]) { session.help_dump_mode = false; bool waitCOMPort = false; bool addLuaExec = false; + bool stayInCommandLoop = false; char *script_cmds_file = NULL; char *script_cmd = NULL; char *port = NULL; @@ -438,6 +443,12 @@ int main(int argc, char *argv[]) { continue; } + // go to interactive instead of quitting after a script/command + if(strcmp(argv[i], "-i") == 0 || strcmp(argv[i], "--interactive") == 0){ + stayInCommandLoop = true; + continue; + } + // We got an unknown parameter PrintAndLogEx(ERR, _RED_("ERROR:") "invalid parameter: " _YELLOW_("%s") "\n", argv[i]); show_help(false, exec_name); @@ -512,21 +523,21 @@ int main(int argc, char *argv[]) { #ifdef HAVE_GUI # ifdef _WIN32 - InitGraphics(argc, argv, script_cmds_file, script_cmd); + InitGraphics(argc, argv, script_cmds_file, script_cmd, stayInCommandLoop); MainGraphics(); # else // for *nix distro's, check enviroment variable to verify a display char *display = getenv("DISPLAY"); if (display && strlen(display) > 1) { - InitGraphics(argc, argv, script_cmds_file, script_cmd); + InitGraphics(argc, argv, script_cmds_file, script_cmd, stayInCommandLoop); MainGraphics(); } else { - main_loop(script_cmds_file, script_cmd); + main_loop(script_cmds_file, script_cmd, stayInCommandLoop); } # endif #else - main_loop(script_cmds_file, script_cmd); + main_loop(script_cmds_file, script_cmd, stayInCommandLoop); #endif // Clean up the port diff --git a/client/proxmark3.h b/client/proxmark3.h index 7fea9a092..c669ebbfe 100644 --- a/client/proxmark3.h +++ b/client/proxmark3.h @@ -26,7 +26,7 @@ extern "C" { const char *get_my_executable_path(void); const char *get_my_executable_directory(void); -void main_loop(char *script_cmds_file, char *script_cmd); +void main_loop(char *script_cmds_file, char *script_cmd, bool stayInCommandLoop); #ifdef __cplusplus } From f40600f997f9b259f6944236ad7dbc9abae2ace9 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 4 Aug 2019 16:57:06 +0200 Subject: [PATCH 0251/1854] make style --- client/proxmark3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/proxmark3.c b/client/proxmark3.c index c4cd81b25..9d57eeb7e 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -444,7 +444,7 @@ int main(int argc, char *argv[]) { } // go to interactive instead of quitting after a script/command - if(strcmp(argv[i], "-i") == 0 || strcmp(argv[i], "--interactive") == 0){ + if (strcmp(argv[i], "-i") == 0 || strcmp(argv[i], "--interactive") == 0) { stayInCommandLoop = true; continue; } From 7cb696c5bc1bd956fe57c13d0504bd43e8bd112e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 4 Aug 2019 18:16:16 +0200 Subject: [PATCH 0252/1854] chg: 'hf iclass sim 3' - now supports READ4 cmd. --- armsrc/iclass.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/armsrc/iclass.c b/armsrc/iclass.c index 7c7864401..4f7840a3d 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -1382,12 +1382,12 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) { //This is used for responding to READ-block commands or other data which is dynamically generated //First the 'trace'-data, not encoded for FPGA - uint8_t *data_generic_trace = BigBuf_malloc(8 + 2);//8 bytes data + 2byte CRC is max tag answer + uint8_t *data_generic_trace = BigBuf_malloc((8 * 4) + 2);//8 bytes data + 2byte CRC is max tag answer //Then storage for the modulated data //Each bit is doubled when modulated for FPGA, and we also have SOF and EOF (2 bytes) - uint8_t *data_response = BigBuf_malloc((8 + 2) * 2 + 2); - + uint8_t *data_response = BigBuf_malloc(((8 * 4) + 2) * 2 + 2); + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_TAGSIM_LISTEN); SpinDelay(100); StartCountSspClk(); @@ -1544,7 +1544,7 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) { goto send; } else if (simulationMode == MODE_FULLSIM && receivedCmd[0] == ICLASS_CMD_READ_OR_IDENTIFY && len == 4) { // 0x0C //Read block - uint16_t blk = receivedCmd[1]; + uint8_t blk = receivedCmd[1]; //Take the data... memcpy(data_generic_trace, emulator + (blk << 3), 8); AddCrc(data_generic_trace, 8); @@ -1555,6 +1555,19 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) { modulated_response = data_response; modulated_response_size = ToSendMax; goto send; + } else if (simulationMode == MODE_FULLSIM && receivedCmd[0] == ICLASS_CMD_READ4 && len == 4) { // 0x06 + //Read block + uint8_t blk = receivedCmd[1]; + //Take the data... + memcpy(data_generic_trace, emulator + (blk << 3), 8 * 4); + AddCrc(data_generic_trace, 8 * 4); + trace_data = data_generic_trace; + trace_data_size = 34; + CodeIClassTagAnswer(trace_data, trace_data_size); + memcpy(data_response, ToSend, ToSendMax); + modulated_response = data_response; + modulated_response_size = ToSendMax; + goto send; } else if (simulationMode == MODE_FULLSIM && receivedCmd[0] == ICLASS_CMD_UPDATE) { //Probably the reader wants to update the nonce. Let's just ignore that for now. From 2cc24c87142f0efbae0bf07e9b4a40fef8ba39c4 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 4 Aug 2019 18:31:52 +0200 Subject: [PATCH 0253/1854] chg: 'hf iclass' generically, check button press fewer times to not interupt time critical parts too much --- armsrc/iclass.c | 67 +++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 59 insertions(+), 8 deletions(-) diff --git a/armsrc/iclass.c b/armsrc/iclass.c index 4f7840a3d..47e86673d 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -884,9 +884,17 @@ void RAMFUNC SniffIClass(void) { // contains LOW nibble = tag data // so two bytes are needed in order to get 1byte of either reader or tag data. (ie 2 sample bytes) // since reader data is manchester encoded, we need 2bytes of data in order to get one demoded byte. (ie: 4 sample bytes) - while (!BUTTON_PRESS()) { + uint16_t checked = 0; + for (;;) { WDT_HIT(); + if ( checked == 1000 ) { + if (BUTTON_PRESS() || data_available() ) break; + checked = 0; + } else { + checked++; + } + previous_data <<= 8; previous_data |= *data; @@ -996,8 +1004,17 @@ static bool GetIClassCommandFromReader(uint8_t *received, int *len, int maxLen) uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; (void)b; - while (!BUTTON_PRESS()) { + uint16_t checked = 0; + for (;;) { + WDT_HIT(); + + if ( checked == 1000 ) { + if( BUTTON_PRESS() || data_available() ) return false; + checked = 0; + } else { + checked++; + } // keep tx buffer in a defined state anyway. if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) @@ -1645,8 +1662,15 @@ static int SendIClassAnswer(uint8_t *resp, int respLen, uint16_t delay) { AT91C_BASE_SSC->SSC_THR = 0x00; - while (!BUTTON_PRESS()) { + uint16_t checked = 0; + for (;;) { + if ( checked == 1000 ) { + if ( BUTTON_PRESS() || data_available()) return 0; + checked = 0; + } else { + checked++; + } // Prevent rx holding register from overflowing if ((AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY)) { b = AT91C_BASE_SSC->SSC_RHR; @@ -1812,9 +1836,18 @@ static int GetIClassAnswer(uint8_t *receivedResponse, int maxLen, int *samples, // clear RXRDY: uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; (void)b; - - while (!BUTTON_PRESS()) { + + uint16_t checked = 0; + + for (;;) { WDT_HIT(); + + if ( checked == 1000 ) { + if (BUTTON_PRESS() || data_available()) return false; + checked = 0; + } else { + checked++; + } // keep tx buffer in a defined state anyway. if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { @@ -2006,6 +2039,7 @@ void ReaderIClass(uint8_t arg0) { setupIclassReader(); + uint16_t checked = 0; bool userCancelled = BUTTON_PRESS() || data_available(); while (!userCancelled) { @@ -2105,7 +2139,13 @@ void ReaderIClass(uint8_t arg0) { } } LED_B_OFF(); - userCancelled = BUTTON_PRESS() || data_available(); + + if ( checked == 1000 ) { + userCancelled = BUTTON_PRESS() || data_available(); + checked = 0; + } else { + checked++; + } } if (userCancelled) { @@ -2299,11 +2339,17 @@ void iClass_Authentication_fast(uint64_t arg0, uint64_t arg1, uint8_t *datain) { setupIclassReader(); + uint16_t checked = 0; int read_status = 0; uint8_t startup_limit = 10; while (read_status != 2) { - if (BUTTON_PRESS() && !data_available()) goto out; + if ( checked == 1000 ) { + if (BUTTON_PRESS() || !data_available()) goto out; + checked = 0; + } else { + checked++; + } read_status = handshakeIclassTag_ext(card_data, use_credit_key); if (startup_limit-- == 0) { @@ -2318,7 +2364,12 @@ void iClass_Authentication_fast(uint64_t arg0, uint64_t arg1, uint8_t *datain) { for (i = 0; i < keyCount; i++) { // Allow button press / usb cmd to interrupt device - if (BUTTON_PRESS() && !data_available()) break; + if ( checked == 1000 ) { + if (BUTTON_PRESS() || !data_available()) goto out; + checked = 0; + } else { + checked++; + } WDT_HIT(); LED_B_ON(); From 18d2c24e9e9d77f1344f1a4d6e48a54620042904 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 4 Aug 2019 19:13:54 +0200 Subject: [PATCH 0254/1854] chg: 'trace list' - abort when ENTER key is pressed --- client/cmdtrace.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/client/cmdtrace.c b/client/cmdtrace.c index 7eaa9c207..d7d62d0b0 100644 --- a/client/cmdtrace.c +++ b/client/cmdtrace.c @@ -830,6 +830,9 @@ int CmdTraceList(const char *Cmd) { ClearAuthData(); while (tracepos < traceLen) { tracepos = printTraceLine(tracepos, traceLen, trace, protocol, showWaitCycles, markCRCBytes); + + if (kbd_enter_pressed()) + break; } } return 0; From 2fecbb614160fc7e07965360836e0891455ca6da Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 4 Aug 2019 19:26:53 +0200 Subject: [PATCH 0255/1854] chg: return values. --- common/lfdemod.c | 7 ++++--- common/lfdemod.h | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/common/lfdemod.c b/common/lfdemod.c index f8daec079..ec960c91f 100644 --- a/common/lfdemod.c +++ b/common/lfdemod.c @@ -42,6 +42,7 @@ #include // for bool #include "parity.h" // for parity test #include "commonutil.h" // colors +#include "pm3_cmd.h" // error codes //********************************************************************************************** //---------------------------------Utilities Section-------------------------------------------- //********************************************************************************************** @@ -223,13 +224,13 @@ size_t addParity(uint8_t *src, uint8_t *dest, uint8_t sourceLen, uint8_t pLen, u } // array must be size dividable with 8 -uint8_t bits_to_array(const uint8_t *bits, size_t size, uint8_t *dest) { - if ((size == 0) || (size % 8) != 0) return 0; +int bits_to_array(const uint8_t *bits, size_t size, uint8_t *dest) { + if ((size == 0) || (size % 8) != 0) return PM3_EINVARG; for (uint32_t i = 0; i < (size / 8); i++) dest[i] = bytebits_to_byte((uint8_t *) bits + (i * 8), 8); - return 0; + return PM3_SUCCESS; } uint32_t bytebits_to_byte(uint8_t *src, size_t numbits) { diff --git a/common/lfdemod.h b/common/lfdemod.h index 4c9671ed4..0acb52063 100644 --- a/common/lfdemod.h +++ b/common/lfdemod.h @@ -49,7 +49,7 @@ int askdemod(uint8_t *bits, size_t *size, int *clk, int *invert, int maxErr int askdemod_ext(uint8_t *bits, size_t *size, int *clk, int *invert, int maxErr, uint8_t amp, uint8_t askType, int *startIdx); void askAmp(uint8_t *bits, size_t size); int BiphaseRawDecode(uint8_t *bits, size_t *size, int *offset, int invert); -uint8_t bits_to_array(const uint8_t *bits, size_t size, uint8_t *dest); +int bits_to_array(const uint8_t *bits, size_t size, uint8_t *dest); uint32_t bytebits_to_byte(uint8_t *src, size_t numbits); uint32_t bytebits_to_byteLSBF(uint8_t *src, size_t numbits); uint16_t countFC(uint8_t *bits, size_t size, bool fskAdj); From b43ea3be32658afae296633ea6afe470430fe5e8 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 4 Aug 2019 20:05:30 +0200 Subject: [PATCH 0256/1854] chg: xmodem --- common/crc16.c | 4 ++++ common/crc16.h | 1 + 2 files changed, 5 insertions(+) diff --git a/common/crc16.c b/common/crc16.c index 47d408660..f2a6558b8 100644 --- a/common/crc16.c +++ b/common/crc16.c @@ -31,6 +31,7 @@ void init_table(CrcType_t crctype) { generate_table(CRC16_POLY_CCITT, true); break; case CRC_FELICA: + case CRC_XMODEM: generate_table(CRC16_POLY_CCITT, false); break; case CRC_LEGIC: @@ -172,6 +173,7 @@ void compute_crc(CrcType_t ct, const uint8_t *d, size_t n, uint8_t *first, uint8 crc = crc16_iclass(d, n); break; case CRC_FELICA: + case CRC_XMODEM: crc = crc16_xmodem(d, n); break; case CRC_CCITT: @@ -204,6 +206,7 @@ uint16_t Crc16ex(CrcType_t ct, const uint8_t *d, size_t n) { case CRC_ICLASS: return crc16_iclass(d, n); case CRC_FELICA: + case CRC_XMODEM: return crc16_xmodem(d, n); case CRC_CCITT: return crc16_ccitt(d, n); @@ -244,6 +247,7 @@ bool check_crc(CrcType_t ct, const uint8_t *d, size_t n) { case CRC_ICLASS: return (crc16_iclass(d, n) == 0); case CRC_FELICA: + case CRC_XMODEM: return (crc16_xmodem(d, n) == 0); case CRC_CCITT: return (crc16_ccitt(d, n) == 0); diff --git a/common/crc16.h b/common/crc16.h index cc29d3ee0..9c9df1d1f 100644 --- a/common/crc16.h +++ b/common/crc16.h @@ -30,6 +30,7 @@ typedef enum { CRC_LEGIC, CRC_CCITT, CRC_KERMIT, + CRC_XMODEM, } CrcType_t; uint16_t update_crc16_ex(uint16_t crc, uint8_t c, uint16_t polynomial); From 45c27573b3ca6565d7304d8342cec4e49c7e1e95 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 4 Aug 2019 21:33:57 +0200 Subject: [PATCH 0257/1854] ARM Makefile: softer dependency on fpga_compress --- armsrc/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/armsrc/Makefile b/armsrc/Makefile index 6619e259d..2901d5a77 100644 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@ -147,7 +147,7 @@ version.c: default_version.c $(OBJDIR)/fpga_version_info.o $(OBJDIR)/fpga_all.o $(info [-] GEN $@) $(Q)perl ../tools/mkversion.pl .. > $@ || $(COPY) $^ $@ -fpga_version_info.c: $(FPGA_BITSTREAMS) $(FPGA_COMPRESSOR) +fpga_version_info.c: $(FPGA_BITSTREAMS) | $(FPGA_COMPRESSOR) $(info [-] GEN $@) $(Q)$(FPGA_COMPRESSOR) -v $(filter %.bit,$^) $@ @@ -155,7 +155,7 @@ $(OBJDIR)/fpga_all.o: $(OBJDIR)/fpga_all.bit.z $(info [-] GEN $@) $(Q)$(OBJCOPY) -O elf32-littlearm -I binary -B arm --prefix-sections=fpga_all_bit $^ $@ -$(OBJDIR)/fpga_all.bit.z: $(FPGA_BITSTREAMS) $(FPGA_COMPRESSOR) +$(OBJDIR)/fpga_all.bit.z: $(FPGA_BITSTREAMS) | $(FPGA_COMPRESSOR) $(info [-] GEN $@) ifeq ($(Q),@) @$(FPGA_COMPRESSOR) $(filter %.bit,$^) $@ >/dev/null @@ -183,7 +183,7 @@ $(OBJDIR)/fullimage.data.bin: $(OBJDIR)/fullimage.stage1.elf $(info [-] GEN $@) $(Q)$(OBJCOPY) -O binary -I elf32-littlearm --only-section .data $^ $@ -$(OBJDIR)/fullimage.data.bin.z: $(OBJDIR)/fullimage.data.bin $(FPGA_COMPRESSOR) +$(OBJDIR)/fullimage.data.bin.z: $(OBJDIR)/fullimage.data.bin | $(FPGA_COMPRESSOR) $(info [-] GEN $@) ifeq ($(Q),@) @$(FPGA_COMPRESSOR) $(filter %.bin,$^) $@ >/dev/null From 225d406d21bb1908d487b4f61cf80a8c6a124f24 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 5 Aug 2019 00:12:35 +0200 Subject: [PATCH 0258/1854] cppcheck fix: Checking if unsigned variable 'len_to_read' is less than zero. --- armsrc/spiffs_nucleus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/spiffs_nucleus.c b/armsrc/spiffs_nucleus.c index 7951a7952..8dd4b5629 100644 --- a/armsrc/spiffs_nucleus.c +++ b/armsrc/spiffs_nucleus.c @@ -2033,7 +2033,7 @@ s32_t spiffs_object_read( len_to_read = MIN(len_to_read, fd->size - cur_offset); SPIFFS_DBG("read: offset:"_SPIPRIi" rd:"_SPIPRIi" data spix:"_SPIPRIsp" is data_pix:"_SPIPRIpg" addr:"_SPIPRIad"\n", cur_offset, len_to_read, data_spix, data_pix, (u32_t)(SPIFFS_PAGE_TO_PADDR(fs, data_pix) + sizeof(spiffs_page_header) + (cur_offset % SPIFFS_DATA_PAGE_SIZE(fs)))); - if (len_to_read <= 0) { + if (len_to_read == 0) { res = SPIFFS_ERR_END_OF_OBJECT; break; } From 38e4e8d80c713f88ae3e52bfb371303387b56d11 Mon Sep 17 00:00:00 2001 From: "Colin J. Brigato" Date: Mon, 5 Aug 2019 00:27:15 +0200 Subject: [PATCH 0259/1854] FIXes OSX > 10.4 num_Cpus() the good and posix way MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit sysconf() is part of IEEE Std 1003.1-1988 (POSIX.1). Fortunately, it *is* available to OSX `>=10.5`. At least on `~10.14`, the old unposix `sysctl` osx way was lost, at least in portable environments. This fixes it, but will not be compatible with OSX > 10.4. So i'm sorry but here we loose compatibility with Macs olders than 2005. (🤣) --- client/util.c | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/client/util.c b/client/util.c index f6f89e0ff..3bb0a96fa 100644 --- a/client/util.c +++ b/client/util.c @@ -9,7 +9,7 @@ //----------------------------------------------------------------------------- // ensure gmtime_r is available even with -std=c99; must be included before -#if !defined(_WIN32) +#if !defined(_WIN32) && !defined(__APPLE__) #define _POSIX_C_SOURCE 200112L #endif @@ -807,24 +807,12 @@ int num_CPUs(void) { SYSTEM_INFO sysinfo; GetSystemInfo(&sysinfo); return sysinfo.dwNumberOfProcessors; -#elif defined(__linux__) && defined(_SC_NPROCESSORS_ONLN) +#else #include int count = sysconf(_SC_NPROCESSORS_ONLN); if (count <= 0) count = 1; return count; -#elif defined(__APPLE__) - /* - TODO ICEMAN 2019, its commented out until someone finds a better solution -#include "sys/sysctl.h" - uint32_t logicalcores = 0; - size_t size = sizeof( logicalcores ); - sysctlbyname( "hw.logicalcpu", &logicalcores, &size, NULL, 0 ); - return logicalcores; - */ - return 1; -#else - return 1; #endif } From 7a620ddaa7541f6b82ebbb7adec3afdaf62fc052 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 5 Aug 2019 00:31:51 +0200 Subject: [PATCH 0260/1854] remove redundant conditions --- client/cmdhffido.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/cmdhffido.c b/client/cmdhffido.c index 3f0f259a4..37f80d8e5 100644 --- a/client/cmdhffido.c +++ b/client/cmdhffido.c @@ -209,7 +209,7 @@ static int CmdHFFidoRegister(const char *cmd) { if (paramsPlain) { memset(cdata, 0x00, 32); CLIGetStrWithReturn(6, cdata, &chlen); - if (chlen && chlen > 16) { + if (chlen > 16) { PrintAndLogEx(ERR, "ERROR: challenge parameter length in ASCII mode must be less than 16 chars instead of: %d", chlen); return 1; } @@ -227,7 +227,7 @@ static int CmdHFFidoRegister(const char *cmd) { if (paramsPlain) { memset(adata, 0x00, 32); CLIGetStrWithReturn(7, adata, &applen); - if (applen && applen > 16) { + if (applen > 16) { PrintAndLogEx(ERR, "ERROR: application parameter length in ASCII mode must be less than 16 chars instead of: %d", applen); return 1; } @@ -473,7 +473,7 @@ static int CmdHFFidoAuthenticate(const char *cmd) { if (paramsPlain) { memset(hdata, 0x00, 32); CLIGetStrWithReturn(9, hdata, &hdatalen); - if (hdatalen && hdatalen > 16) { + if (hdatalen > 16) { PrintAndLogEx(ERR, "ERROR: challenge parameter length in ASCII mode must be less than 16 chars instead of: %d", hdatalen); return 1; } @@ -490,7 +490,7 @@ static int CmdHFFidoAuthenticate(const char *cmd) { if (paramsPlain) { memset(hdata, 0x00, 32); CLIGetStrWithReturn(11, hdata, &hdatalen); - if (hdatalen && hdatalen > 16) { + if (hdatalen > 16) { PrintAndLogEx(ERR, "ERROR: application parameter length in ASCII mode must be less than 16 chars instead of: %d", hdatalen); return 1; } From f317e3247a7f96ee68ac62b6201a32a6c66918a4 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 5 Aug 2019 17:43:53 +0200 Subject: [PATCH 0261/1854] chg: 'lf nedap' - decoding / encoding of Nedap. (anon) --- client/cmdlfnedap.c | 683 +++++++++++++++++++++++++----------------- client/cmdlfnoralsy.c | 9 +- 2 files changed, 417 insertions(+), 275 deletions(-) diff --git a/client/cmdlfnedap.c b/client/cmdlfnedap.c index c8a851ea6..d4cca1a30 100644 --- a/client/cmdlfnedap.c +++ b/client/cmdlfnedap.c @@ -8,137 +8,260 @@ //----------------------------------------------------------------------------- #include "cmdlfnedap.h" + +#define FIXED_71 0x71 +#define FIXED_40 0x40 +#define UNKNOWN_A 0x00 +#define UNKNOWN_B 0x00 + static int CmdHelp(const char *Cmd); -/* -static int usage_lf_nedap_clone(void) { - PrintAndLogEx(NORMAL, "clone a NEDAP tag to a T55x7 tag."); +static int usage_lf_nedap_gen(void) { + PrintAndLogEx(NORMAL, "generate Nedap bitstream in DemodBuffer"); PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Usage: lf nedap clone [h] "); - PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " h : This help"); - PrintAndLogEx(NORMAL, " : 24-bit value card number"); -// PrintAndLogEx(NORMAL, " Q5 : optional - clone to Q5 (T5555) instead of T55x7 chip"); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " lf nedap clone 112233"); - return PM3_SUCCESS; -} -*/ - -static int usage_lf_nedap_sim(void) { - PrintAndLogEx(NORMAL, "Enables simulation of NEDAP card with specified card number."); - PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued."); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Usage: lf nedap sim [h] "); + PrintAndLogEx(NORMAL, "Usage: lf nedap generate [h] [s ] c i [l]"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h : This help"); - PrintAndLogEx(NORMAL, " : 24-bit value card number"); + PrintAndLogEx(NORMAL, " s : optional, default=5"); + PrintAndLogEx(NORMAL, " c : customerCode"); + PrintAndLogEx(NORMAL, " i : ID (max 99999)"); + PrintAndLogEx(NORMAL, " l : optional - long (128), default to short (64)"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " lf nedap sim 112233"); + PrintAndLogEx(NORMAL, " lf nedap generate s 1 c 123 i 112233"); return PM3_SUCCESS; } +static int usage_lf_nedap_clone(void) { + PrintAndLogEx(NORMAL, "clone a Nedap tag to a T55x7 tag."); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Usage: lf nedap clone [h] [s ] c i [l]"); + PrintAndLogEx(NORMAL, "Options:"); + PrintAndLogEx(NORMAL, " h : This help"); + PrintAndLogEx(NORMAL, " s : optional, default=5"); + PrintAndLogEx(NORMAL, " c : customerCode"); + PrintAndLogEx(NORMAL, " i : ID (max 99999)"); + PrintAndLogEx(NORMAL, " l : optional - long (128), default to short (64)"); +// PrintAndLogEx(NORMAL, " Q5 : optional - clone to Q5 (T5555) instead of T55x7 chip"); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Examples:"); + PrintAndLogEx(NORMAL, " lf nedap clone s 1 c 123 i 112233"); + return PM3_SUCCESS; +} + +static int usage_lf_nedap_sim(void) { + PrintAndLogEx(NORMAL, "simulate Nedap card."); + PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued."); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Usage: lf nedap sim [h] [s ] c i [l]"); + PrintAndLogEx(NORMAL, "Options:"); + PrintAndLogEx(NORMAL, " h : This help"); + PrintAndLogEx(NORMAL, " s : subtype, default=5"); + PrintAndLogEx(NORMAL, " c : customerCode"); + PrintAndLogEx(NORMAL, " i : ID (max 99999)"); + PrintAndLogEx(NORMAL, " l : long (128), default to short (64)"); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Examples:"); +// TODO proper example? + PrintAndLogEx(NORMAL, " lf nedap sim s 1 c 7 i 1337"); + return PM3_SUCCESS; +} + +const uint8_t translateTable[10] = {8, 2, 1, 12, 4, 5, 10, 13, 0, 9}; +const uint8_t invTranslateTable[16] = {8, 2, 1, 0xff, 4, 5, 0xff, 0xff, 0, 9, 6, 0xff, 3, 7, 0xff, 0xff}; +const uint8_t preamble[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}; // zero inside + +static inline uint32_t bitcount(uint32_t a) { +#if defined __GNUC__ + return __builtin_popcountl(a); +#else + a = a - ((a >> 1) & 0x55555555); + a = (a & 0x33333333) + ((a >> 2) & 0x33333333); + return (((a + (a >> 4)) & 0x0f0f0f0f) * 0x01010101) >> 24; +#endif +} + +static uint8_t isEven_64_63(const uint8_t *data) { // 8 + return (bitcount(*(uint32_t *) data) + (bitcount((*(uint32_t *)(data + 4)) & 0xfeffffff))) & 1; +} + //NEDAP demod - ASK/Biphase (or Diphase), RF/64 with preamble of 1111111110 (always a 128 bit data stream) -//print NEDAP Prox ID, encoding, encrypted ID, static int CmdLFNedapDemod(const char *Cmd) { (void)Cmd; // Cmd is not used so far - //raw ask demod no start bit finding just get binary from wave + + uint8_t data[16], buffer[7], r0, r1, r2, r3, r4, r5, idxC1, idxC2, idxC3, idxC4, idxC5, fixed0, fixed1, unk1, unk2, subtype; // 4 bits + size_t size, offset = 0; + uint16_t checksum, customerCode; // 12 bits + uint32_t badgeId; // max 99999 + if (ASKbiphaseDemod("0 64 1 0", false) != PM3_SUCCESS) { - if (g_debugMode) PrintAndLogEx(DEBUG, "DEBUG: Error - Nedap ASKbiphaseDemod failed"); + if (g_debugMode) PrintAndLogEx(DEBUG, "DEBUG: Error - NEDAP: ASK/Biphase Demod failed"); return PM3_ESOFT; } - size_t size = DemodBufferLen; - int idx = detectNedap(DemodBuffer, &size); - if (idx < 0) { - if (g_debugMode) { - // if (idx == -5) - // PrintAndLogEx(DEBUG, "DEBUG: Error - not enough samples"); - // else if (idx == -1) - // PrintAndLogEx(DEBUG, "DEBUG: Error - only noise found"); - // else if (idx == -2) - // PrintAndLogEx(DEBUG, "DEBUG: Error - problem during ASK/Biphase demod"); - if (idx == -3) - PrintAndLogEx(DEBUG, "DEBUG: Error - Nedap Size not correct: %d", size); - else if (idx == -4) - PrintAndLogEx(DEBUG, "DEBUG: Error - Nedap preamble not found"); - else - PrintAndLogEx(DEBUG, "DEBUG: Error - Nedap idx: %d", idx); + + size = DemodBufferLen; + if (!preambleSearch(DemodBuffer, (uint8_t *) preamble, sizeof(preamble), &size, &offset)) { + PrintAndLogEx(DEBUG, "DEBUG: Error - NEDAP: preamble not found"); + return PM3_ESOFT; + } + + // set plot + setDemodBuff(DemodBuffer, size, offset); + setClockGrid(g_DemodClock, g_DemodStartIdx + (g_DemodClock * offset)); + + // sanity checks + if ((size != 128) && (size != 64)) { + PrintAndLogEx(DEBUG, "DEBUG: Error - NEDAP: Size not correct: %d", size); + return PM3_ESOFT; + } + + if (bits_to_array(DemodBuffer, size, data) != PM3_SUCCESS) { + PrintAndLogEx(DEBUG, "DEBUG: Error - NEDAP: bits_to_array error\n"); + return PM3_ESOFT; + } + + + int ret = PM3_SUCCESS; + + // first part + + // parity 1 check + if (isEven_64_63(data) != (data[7] & 0x01)) { + PrintAndLogEx(ERR, "Bad parity (%1u)", data[7] & 0x01); + ret = PM3_ESOFT; + } + + // header 1 check + // (1111111110 0 -- zero inside) + if ((data[0] != 0xFF) && ((data[1] & 0xE0) != 0x80)) { + PrintAndLogEx(ERR, "Bad header"); + ret = PM3_ESOFT; + } + + buffer[0] = (data[0] << 7) | (data[1] >> 1); + buffer[1] = (data[1] << 7) | (data[2] >> 1); + buffer[2] = (data[2] << 7) | (data[3] >> 1); + buffer[3] = ((data[4] & 0x1e) << 3) | ((data[5] & 0x1e) >> 1); + buffer[4] = ((data[6] & 0x1e) << 3) | ((data[7] & 0x1e) >> 1); + + // CHECKSUM + init_table(CRC_XMODEM); + checksum = crc16_xmodem(buffer, 5); + + buffer[6] = (data[3] << 7) | ((data[4] & 0xe0) >> 1) | ((data[4] & 0x01) << 3) | ((data[5] & 0xe0) >> 5); + buffer[5] = (data[5] << 7) | ((data[6] & 0xe0) >> 1) | ((data[6] & 0x01) << 3) | ((data[7] & 0xe0) >> 5); + + bool isValid = (checksum == *(uint16_t *)(buffer + 5)); + + subtype = (data[1] & 0x1e) >> 1; + customerCode = ((data[1] & 0x01) << 11) | (data[2] << 3) | ((data[3] & 0xe0) >> 5); + + if ( isValid == false ) { + PrintAndLogEx(ERR, "Checksum : %s (calc 0x%04X != 0x%04X)", _RED_("failed"), checksum, *(uint16_t *)(buffer + 5)); + ret = PM3_ESOFT; + } + + idxC1 = invTranslateTable[(data[3] & 0x1e) >> 1]; + idxC2 = invTranslateTable[(data[4] & 0x1e) >> 1]; + idxC3 = invTranslateTable[(data[5] & 0x1e) >> 1]; + idxC4 = invTranslateTable[(data[6] & 0x1e) >> 1]; + idxC5 = invTranslateTable[(data[7] & 0x1e) >> 1]; + + // validation + if ((idxC1 != 0xFF) && (idxC2 != 0xFF) && (idxC3 != 0xFF) && (idxC4 != 0xFF) && (idxC5 != 0xFF)) { + r1 = idxC1; + r2 = ((10 + idxC2) - (idxC1 + 1)) % 10; + r3 = ((10 + idxC3) - (idxC2 + 1)) % 10; + r4 = ((10 + idxC4) - (idxC3 + 1)) % 10; + r5 = ((10 + idxC5) - (idxC4 + 1)) % 10; + + badgeId = r1 * 10000 + r2 * 1000 + r3 * 100 + r4 * 10 + r5; + + PrintAndLogEx(SUCCESS, "NEDAP Tag Found: Card ID "_YELLOW_("%05u")" subtype: "_YELLOW_("%1u")" customer code: "_YELLOW_("%03x"), badgeId, subtype, customerCode); + PrintAndLogEx(SUCCESS, "Checksum is %s (0x%04X)", _GREEN_("OK"), checksum ); + PrintAndLogEx(SUCCESS, "Raw: %s", sprint_hex(data, size/8)); + } else { + PrintAndLogEx(ERR, "Invalid idx (1:%02x - 2:%02x - 3:%02x - 4:%02x - 5:%02x)", idxC1, idxC2, idxC3, idxC4, idxC5); + ret = PM3_ESOFT; + } + + if (size > 64) { + // second part + PrintAndLogEx(DEBUG, "NEDAP Tag, second part found"); + + if (isEven_64_63(data + 8) != (data[15] & 0x01)) { + PrintAndLogEx(ERR, "Bad parity (%1u)", data[15] & 0x01); + return ret; + } + + // validation + if ( (data[8] & 0x80) + && (data[9] & 0x40) + && (data[10] & 0x20) + && (data[11] & 0x10) + && (data[12] & 0x08) + && (data[13] & 0x04) + && (data[14] & 0x02)) { + PrintAndLogEx(ERR, "Bad zeros"); + return ret; + } + + // + r4 = (data[8] >> 3) & 0x0F; + r5 = ((data[8] << 1) & 0x0F) | (data[9] >> 7); + r2 = (data[9] >> 2) & 0x0F; + r3 = ((data[9] << 2) & 0x0F) | (data[10] >> 6); + r0 = ((data[10] >> 1) & 0x0F); + r1 = ((data[10] << 3) & 0x0F) | (data[11] >> 5); + + fixed0 = ((data[11] << 4) & 0xF0) | (data[12] >> 4); + fixed1 = ((data[12] << 5) & 0xE0) | (data[13] >> 3); + + unk1 = ((data[13] << 6) & 0xC0) | (data[14] >> 2); + unk2 = ((data[14] << 7) & 0xC0) | (data[15] >> 1); + + // validation 2 + if (!r0 && (r1 < 10) && (r2 < 10) && (r3 < 10) && (r4 < 10) && (r5 < 10)) { + + badgeId = r1 * 10000 + r2 * 1000 + r3 * 100 + r4 * 10 + r5; + PrintAndLogEx(SUCCESS, "Second Card Id " _YELLOW_("%05u"), badgeId); + + if ((fixed0 == FIXED_71) && (fixed1 == FIXED_40)) + PrintAndLogEx(DEBUG, "Fixed part {0 = 0x%02x, 1 = 0x%02x}", fixed0, fixed1); + else + PrintAndLogEx(DEBUG, "Bad fixed: {0 = 0x%02x (%0x02x), 1 = 0x%02x (%0x02x)}", fixed0, FIXED_71, fixed1, FIXED_40); + + PrintAndLogEx(DEBUG, "Unknown part {1 = 0x%02x, 2 = 0x%02x}", unk1, unk2); + } else { + PrintAndLogEx(ERR, "Bad digits (0:%1x - 1:%1x - 2:%1x - 3:%1x - 4:%1x - 5:%1x)", r0, r1, r2, r3, r4, r5); + return ret; } - return PM3_ESOFT; } - - /* Index map E E - preamble enc tag type encrypted uid P d 33 d 90 d 04 d 71 d 40 d 45 d E7 P - 1111111110 00101101000001011010001100100100001011010100110101100 1 0 00110011 0 10010000 0 00000100 0 01110001 0 01000000 0 01000101 0 11100111 1 - uid2 uid1 uid0 I I R R - 1111111110 00101101000001011010001100100100001011010100110101100 1 - - 0 00110011 - 0 10010000 - 0 00000100 - 0 01110001 - 0 01000000 - 0 01000101 - 0 11100111 - 1 - - Tag ID is 049033 - I = Identical on all tags - R = Random ? - UID2, UID1, UID0 == card number - - */ - //get raw ID before removing parities - uint32_t raw[4] = {0, 0, 0, 0}; - raw[0] = bytebits_to_byte(DemodBuffer + idx + 96, 32); - raw[1] = bytebits_to_byte(DemodBuffer + idx + 64, 32); - raw[2] = bytebits_to_byte(DemodBuffer + idx + 32, 32); - raw[3] = bytebits_to_byte(DemodBuffer + idx, 32); - setDemodBuff(DemodBuffer, 128, idx); - setClockGrid(g_DemodClock, g_DemodStartIdx + (idx * g_DemodClock)); - - uint8_t firstParity = GetParity(DemodBuffer, EVEN, 63); - if (firstParity != DemodBuffer[63]) { - PrintAndLogEx(DEBUG, "DEBUG: Error - Nedap 1st 64bit parity check failed: %d|%d ", DemodBuffer[63], firstParity); - return PM3_ESOFT; - } - - uint8_t secondParity = GetParity(DemodBuffer + 64, EVEN, 63); - if (secondParity != DemodBuffer[127]) { - PrintAndLogEx(DEBUG, "DEBUG: Error - Nedap 2st 64bit parity check failed: %d|%d ", DemodBuffer[127], secondParity); - return PM3_ESOFT; - } - - // ok valid card found! - uint32_t uid = 0; - uid = bytebits_to_byte(DemodBuffer + 65, 8); - uid |= bytebits_to_byte(DemodBuffer + 74, 8) << 8; - uid |= bytebits_to_byte(DemodBuffer + 83, 8) << 16; - - uint16_t two = 0; - two = bytebits_to_byte(DemodBuffer + 92, 8); - two |= bytebits_to_byte(DemodBuffer + 101, 8) << 8; - - uint16_t chksum2 = 0; - chksum2 = bytebits_to_byte(DemodBuffer + 110, 8); - chksum2 |= bytebits_to_byte(DemodBuffer + 119, 8) << 8; - - PrintAndLogEx(SUCCESS, "NEDAP ID Found - Raw: %08x%08x%08x%08x", raw[3], raw[2], raw[1], raw[0]); - PrintAndLogEx(SUCCESS, " - UID: %06X", uid); - PrintAndLogEx(SUCCESS, " - i: %04X", two); - PrintAndLogEx(SUCCESS, " - Checksum2 %04X", chksum2); - - if (g_debugMode) { - PrintAndLogEx(DEBUG, "DEBUG: idx: %d, Len: %d, Printing Demod Buffer:", idx, 128); - printDemodBuff(); - PrintAndLogEx(DEBUG, "BIN:\n%s", sprint_bin_break(DemodBuffer, 128, 64)); - } - + return PM3_SUCCESS; } -/* + +/* Index map E E + preamble enc tag type encrypted uid P d 33 d 90 d 04 d 71 d 40 d 45 d E7 P + 1111111110 00101101000001011010001100100100001011010100110101100 1 0 00110011 0 10010000 0 00000100 0 01110001 0 01000000 0 01000101 0 11100111 1 + uid2 uid1 uid0 I I R R + 1111111110 00101101000001011010001100100100001011010100110101100 1 + + 0 00110011 + 0 10010000 + 0 00000100 + 0 01110001 + 0 01000000 + 0 01000101 + 0 11100111 + 1 + + Tag ID is 049033 + I = Identical on all tags + R = Random ? + UID2, UID1, UID0 == card number + + configuration lf t55xx wr b 0 d 00170082 @@ -163,51 +286,181 @@ lf t55xx wr b 4 d 4c0003ff */ static int CmdLFNedapRead(const char *Cmd) { - lf_read(true, 12000); + lf_read(true, 16000); return CmdLFNedapDemod(Cmd); } -/* -static int CmdLFNedapClone(const char *Cmd) { - char cmdp = param_getchar(Cmd, 0); - if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_nedap_clone(); +static void NedapGen(uint8_t subType, uint16_t customerCode, uint32_t id, bool isLong, uint8_t *data) { // 8 or 16 + uint8_t buffer[7], r1, r2, r3, r4, r5, idxC1, idxC2, idxC3, idxC4, idxC5, i, tmp, carry, id2, id1, id0; + uint16_t checksum; - uint32_t cardnumber=0, cn = 0; - uint32_t blocks[5]; - uint8_t bits[128]; - memset(bits, 0x00, sizeof(bits)); + r1 = (uint8_t)(id / 10000); + r2 = (uint8_t)((id % 10000) / 1000); + r3 = (uint8_t)((id % 1000) / 100); + r4 = (uint8_t)((id % 100) / 10); + r5 = (uint8_t)(id % 10); - if (sscanf(Cmd, "%u", &cn ) != 1) return usage_lf_nedap_clone(); + // first part + idxC1 = r1; + idxC2 = (idxC1 + 1 + r2) % 10; + idxC3 = (idxC2 + 1 + r3) % 10; + idxC4 = (idxC3 + 1 + r4) % 10; + idxC5 = (idxC4 + 1 + r5) % 10; - cardnumber = (cn & 0x00FFFFFF); + buffer[0] = 0xc0 | (subType & 0x0F); + buffer[1] = (customerCode & 0x0FF0) >> 4; + buffer[2] = ((customerCode & 0x000F) << 4) | translateTable[idxC1]; + buffer[3] = (translateTable[idxC2] << 4) | translateTable[idxC3]; + buffer[4] = (translateTable[idxC4] << 4) | translateTable[idxC5]; - if ( getNedapBits(cardnumber, bits) == PM3_SUCCESS ) { + // checksum + init_table(CRC_XMODEM); + checksum = crc16_xmodem(buffer, 5); + + buffer[6] = ((checksum & 0x000F) << 4) | (buffer[4] & 0x0F); + buffer[5] = (checksum & 0x00F0) | ((buffer[4] & 0xF0) >> 4); + buffer[4] = ((checksum & 0x0F00) >> 4) | (buffer[3] & 0x0F); + buffer[3] = ((checksum & 0xF000) >> 8) | ((buffer[3] & 0xF0) >> 4); + + // carry calc + for (i = 0, carry = 0; i < sizeof(buffer); i++) { + tmp = buffer[sizeof(buffer) - 1 - i]; + data[7 - i] = ((tmp & 0x7F) << 1) | carry; + carry = (tmp & 0x80) >> 7; + } + data[0] = 0xFE | carry; + data[7] |= isEven_64_63(data); + + // second part + if (isLong) { + id0 = r1; + id1 = (r2 << 4) | r3; + id2 = (r4 << 4) | r5; + + data[8] = (id2 >> 1); + data[9] = ((id2 & 0x01) << 7) | (id1 >> 2); + data[10] = ((id1 & 0x03) << 6) | (id0 >> 3); + data[11] = ((id0 & 0x07) << 5) | (FIXED_71 >> 4); + data[12] = ((FIXED_71 & 0x0F) << 4) | (FIXED_40 >> 5); + data[13] = ((FIXED_40 & 0x1F) << 3) | (UNKNOWN_A >> 6); + data[14] = ((UNKNOWN_A & 0x3F) << 2) | (UNKNOWN_B >> 7); + data[15] = ((UNKNOWN_B & 0x7F) << 1); + data[15] |= isEven_64_63(data + 8); + } +} + +static int (*usage_to_be_displayed)(void) = NULL; + +static int CmdLfNedapGen(const char *Cmd) { + uint8_t cmdp = 0, subType = 5, data[16], i, bin[128]; + uint16_t customerCode = 0; + uint32_t id = 0; + bool isLong = false, errors = false; + + int (*usage)(void) = usage_lf_nedap_gen; + if (usage_to_be_displayed != NULL) { + usage = usage_to_be_displayed; + usage_to_be_displayed = NULL; + } + + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { + case 's': + subType = param_get8ex(Cmd, cmdp + 1, 5, 10); + cmdp += 2; + break; + case 'c': + customerCode = param_get32ex(Cmd, cmdp + 1, 0, 16); + cmdp += 2; + break; + case 'i': + id = param_get32ex(Cmd, cmdp + 1, 0, 10); + cmdp += 2; + break; + case 'l': + isLong = true; + cmdp++; + break; + default: + PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } + } + //Validations + if ((!customerCode) || (!id) || (subType > 0xF) || (customerCode > 0xFFF) || (id > 99999)) + errors = true; + + if (errors || cmdp == 0) { + usage(); + return PM3_EINVARG; + } + + PrintAndLogEx(SUCCESS, + "Tag (%s) ; subtype : %1u , customer : %03x , ID : %05u" + , isLong ? "long (128b)" : "short (64b)" + , subType + , customerCode + , id + ); + + NedapGen(subType, customerCode, id, isLong, data); + + for (i = 0; i < (isLong ? 16 : 8); i++) + num_to_bytebits(data[i], 8, bin + i * 8); + + setDemodBuff(bin, (isLong ? 128 : 64), 0); + return PM3_SUCCESS; +} + +int CmdLFNedapClone(const char *Cmd) { + uint8_t max; + uint32_t blocks[5] = {0}; + + char cmdp = tolower(param_getchar(Cmd, 0)); + if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_nedap_clone(); + + usage_to_be_displayed = usage_lf_nedap_clone; + + int ret = CmdLfNedapGen(Cmd); + if (ret != PM3_SUCCESS) + return ret; + + if ((DemodBufferLen != 128) && (DemodBufferLen != 64)) { PrintAndLogEx(ERR, "Error with tag bitstream generation."); return PM3_ESOFT; } + + CmdPrintDemodBuff("x"); - ((ASK/DIphase data rawdemod ab 0 64 1 0 +// What we had before in commented code: //NEDAP - compat mode, ASK/DIphase, data rate 64, 4 data blocks - // DI-pahse (CDP) T55x7_MODULATION_DIPHASE - blocks[0] = T55x7_MODULATION_DIPHASE | T55x7_BITRATE_RF_64 | 7 << T55x7_MAXBLOCK_SHIFT; + // DI-phase (CDP) T55x7_MODULATION_DIPHASE +// blocks[0] = T55x7_MODULATION_DIPHASE | T55x7_BITRATE_RF_64 | 7 << T55x7_MAXBLOCK_SHIFT; +// if (param_getchar(Cmd, 3) == 'Q' || param_getchar(Cmd, 3) == 'q') +// blocks[0] = T5555_MODULATION_BIPHASE | T5555_INVERT_OUTPUT | T5555_SET_BITRATE(64) | 7 <encoding = 2; payload->invert = 1; payload->separator = 0; payload->clock = 64; - memcpy(payload->data, bs, sizeof(bs)); + memcpy(payload->data, DemodBuffer, DemodBufferLen); clearCommandBuffer(); - SendCommandNG(CMD_LF_ASK_SIMULATE, (uint8_t *)payload, sizeof(lf_asksim_t) + sizeof(bs)); + SendCommandNG(CMD_LF_ASK_SIMULATE, (uint8_t *)payload, sizeof(lf_asksim_t) + DemodBufferLen); free(payload); PacketResponseNG resp; @@ -268,62 +520,17 @@ static int CmdLFNedapSim(const char *Cmd) { PrintAndLogEx(INFO, "Done"); if (resp.status != PM3_EOPABORTED) return resp.status; - return PM3_SUCCESS; -} - -static int CmdLFNedapChk(const char *Cmd) { - //301600714021BE - uint8_t data[256] = { 0x30, 0x16, 0x00, 0x71, 0x40, 0x21, 0xBE}; - int len = 0; - param_gethex_ex(Cmd, 0, data, &len); - - len = (len == 0) ? 5 : len >> 1; - - PrintAndLogEx(SUCCESS, "Input: [%d] %s", len, sprint_hex(data, len)); - - //uint8_t last = GetParity(data, EVEN, 62); - //PrintAndLogEx(NORMAL, "TEST PARITY:: %d | %d ", DemodBuffer[62], last); - - uint8_t cl = 0x1D, ch = 0x1D; - - for (int i = len; i >= 0; --i) { - uint8_t al = data[i]; - for (int j = 8; j > 0; --j) { - - uint8_t bl = al ^ ch; - //PrintAndLogEx(NORMAL, "BL %02x | CH %02x \n", al, ch); - - uint8_t carry = (cl & 0x80) ? 1 : 0; - cl <<= 1; - - uint8_t temp = (ch & 0x80) ? 1 : 0; - ch = (ch << 1) | carry; - carry = temp; - - carry = (al & 0x80) ? 1 : 0; - al <<= 1; - - carry = (bl & 0x80) ? 1 : 0; -// bl <<= 1; - - if (carry) { - cl ^= 0x21; - ch ^= 0x10; - } - } - } - - PrintAndLogEx(SUCCESS, "Nedap checksum: 0x%X", ((ch << 8) | cl)); + return PM3_SUCCESS; } static command_t CommandTable[] = { - {"help", CmdHelp, AlwaysAvailable, "this help"}, - {"demod", CmdLFNedapDemod, AlwaysAvailable, "demodulate an Nedap tag from the GraphBuffer"}, - {"read", CmdLFNedapRead, IfPm3Lf, "attempt to read and extract tag data"}, -// {"clone", CmdLFNedapClone, IfPm3Lf, " clone nedap tag"}, - {"sim", CmdLFNedapSim, IfPm3Lf, "simulate nedap tag"}, - {"chk", CmdLFNedapChk, AlwaysAvailable, "calculate Nedap Checksum "}, + {"help", CmdHelp, AlwaysAvailable, "This help"}, + {"demod", CmdLFNedapDemod, AlwaysAvailable, "Demodulate Nedap tag from the GraphBuffer"}, + {"generate", CmdLfNedapGen, AlwaysAvailable, "Generate Nedap bitstream in DemodBuffer"}, + {"read", CmdLFNedapRead, IfPm3Lf, "Attempt to read and extract tag data from the antenna"}, + {"clone", CmdLFNedapClone, IfPm3Lf, "Clone Nedap tag to T55x7"}, + {"sim", CmdLFNedapSim, IfPm3Lf, "Simulate Nedap tag"}, {NULL, NULL, NULL, NULL} }; @@ -338,72 +545,6 @@ int CmdLFNedap(const char *Cmd) { return CmdsParse(CommandTable, Cmd); } -// find nedap preamble in already demoded data -int detectNedap(uint8_t *dest, size_t *size) { - //make sure buffer has data - if (*size < 128) return -3; - - size_t startIdx = 0; - //uint8_t preamble[] = {1,1,1,1,1,1,1,1,1,0,0,0,1}; - uint8_t preamble[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 0}; - if (!preambleSearch(dest, preamble, sizeof(preamble), size, &startIdx)) - return -4; //preamble not found - return (int) startIdx; -} - -int getNedapBits(uint32_t cn, uint8_t *nedapBits) { - - uint8_t pre[128]; - memset(pre, 0x00, sizeof(pre)); - - // preamble 1111 1111 10 = 0xFF8 - num_to_bytebits(0xFF8, 12, pre); - - // fixed tagtype code? 0010 1101 = 0x2D - num_to_bytebits(0x2D, 8, pre + 10); - - // 46 encrypted bits - UNKNOWN ALGO - // -- 16 bits checksum. Should be 4x4 checksum, based on UID and 2 constant values. - // -- 30 bits undocumented? - //num_to_bytebits(cn, 46, pre+18); - - //----from this part, the UID in clear text, with a 1bit ZERO as separator between bytes. - pre[64] = 0; - pre[73] = 0; - pre[82] = 0; - pre[91] = 0; - pre[100] = 0; - pre[109] = 0; - pre[118] = 0; - - // cardnumber (uid) - num_to_bytebits((cn >> 0) & 0xFF, 8, pre + 65); - num_to_bytebits((cn >> 8) & 0xFF, 8, pre + 74); - num_to_bytebits((cn >> 16) & 0xFF, 8, pre + 83); - - // two ? - num_to_bytebits(0, 8, pre + 92); - num_to_bytebits(0, 8, pre + 101); - - // chksum - num_to_bytebits((0 >> 0) & 0xFF, 8, pre + 110); - num_to_bytebits((0 >> 8) & 0xFF, 8, pre + 119); - - pre[63] = GetParity(pre, EVEN, 63); - pre[127] = GetParity(pre + 64, EVEN, 63); - - memcpy(nedapBits, pre, 128); - - // 1111111110001011010000010110100011001001000010110101001101011001000110011010010000000000100001110001001000000001000101011100111 - return PM3_SUCCESS; -} -/* - - UID: 001630 - - i: 4071 - - Checksum2 BE21 -*/ -//GetParity( uint8_t *bits, uint8_t type, int length) - int demodNedap(void) { return CmdLFNedapDemod(""); } diff --git a/client/cmdlfnoralsy.c b/client/cmdlfnoralsy.c index a6c58a3ed..ec8da0bf9 100644 --- a/client/cmdlfnoralsy.c +++ b/client/cmdlfnoralsy.c @@ -131,8 +131,8 @@ static int CmdNoralsyClone(const char *Cmd) { uint8_t bits[96]; memset(bits, 0, sizeof(bits)); - char cmdp = param_getchar(Cmd, 0); - if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_noralsy_clone(); + char cmdp = tolower(param_getchar(Cmd, 0)); + if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_noralsy_clone(); id = param_get32ex(Cmd, 0, 0, 10); year = param_get32ex(Cmd, 1, 2000, 10); @@ -187,8 +187,8 @@ static int CmdNoralsySim(const char *Cmd) { uint16_t year = 0; uint32_t id = 0; - char cmdp = param_getchar(Cmd, 0); - if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') + char cmdp = tolower(param_getchar(Cmd, 0)); + if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_noralsy_sim(); id = param_get32ex(Cmd, 0, 0, 10); @@ -218,6 +218,7 @@ static int CmdNoralsySim(const char *Cmd) { PrintAndLogEx(INFO, "Done"); if (resp.status != PM3_EOPABORTED) return resp.status; + return PM3_SUCCESS; } From be6e46e4ea5c18bde905cb61c1c4132aa3eb6130 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 5 Aug 2019 17:45:20 +0200 Subject: [PATCH 0262/1854] textual --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f3745c56..32d7da93c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Add 'lf nedap' - encoding / decoding (anon) - Add client option `-i` to stay in interactive mode after a script or command (@DidierStevens/@doegox) - Add VSCode tasks (@ViRb3) - Better warn user of hardcoded hitag info (@ViRb3) From 25748b0746269253e9366124ffad6b57ad1795e3 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 5 Aug 2019 12:01:11 -0400 Subject: [PATCH 0263/1854] style --- armsrc/iclass.c | 32 +++++++++--------- client/cmdlfnedap.c | 82 ++++++++++++++++++++++----------------------- 2 files changed, 57 insertions(+), 57 deletions(-) diff --git a/armsrc/iclass.c b/armsrc/iclass.c index 47e86673d..bf3f562c1 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -888,8 +888,8 @@ void RAMFUNC SniffIClass(void) { for (;;) { WDT_HIT(); - if ( checked == 1000 ) { - if (BUTTON_PRESS() || data_available() ) break; + if (checked == 1000) { + if (BUTTON_PRESS() || data_available()) break; checked = 0; } else { checked++; @@ -1008,9 +1008,9 @@ static bool GetIClassCommandFromReader(uint8_t *received, int *len, int maxLen) for (;;) { WDT_HIT(); - - if ( checked == 1000 ) { - if( BUTTON_PRESS() || data_available() ) return false; + + if (checked == 1000) { + if (BUTTON_PRESS() || data_available()) return false; checked = 0; } else { checked++; @@ -1404,7 +1404,7 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) { //Then storage for the modulated data //Each bit is doubled when modulated for FPGA, and we also have SOF and EOF (2 bytes) uint8_t *data_response = BigBuf_malloc(((8 * 4) + 2) * 2 + 2); - + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_TAGSIM_LISTEN); SpinDelay(100); StartCountSspClk(); @@ -1665,8 +1665,8 @@ static int SendIClassAnswer(uint8_t *resp, int respLen, uint16_t delay) { uint16_t checked = 0; for (;;) { - if ( checked == 1000 ) { - if ( BUTTON_PRESS() || data_available()) return 0; + if (checked == 1000) { + if (BUTTON_PRESS() || data_available()) return 0; checked = 0; } else { checked++; @@ -1836,13 +1836,13 @@ static int GetIClassAnswer(uint8_t *receivedResponse, int maxLen, int *samples, // clear RXRDY: uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; (void)b; - + uint16_t checked = 0; - + for (;;) { WDT_HIT(); - - if ( checked == 1000 ) { + + if (checked == 1000) { if (BUTTON_PRESS() || data_available()) return false; checked = 0; } else { @@ -2139,8 +2139,8 @@ void ReaderIClass(uint8_t arg0) { } } LED_B_OFF(); - - if ( checked == 1000 ) { + + if (checked == 1000) { userCancelled = BUTTON_PRESS() || data_available(); checked = 0; } else { @@ -2344,7 +2344,7 @@ void iClass_Authentication_fast(uint64_t arg0, uint64_t arg1, uint8_t *datain) { uint8_t startup_limit = 10; while (read_status != 2) { - if ( checked == 1000 ) { + if (checked == 1000) { if (BUTTON_PRESS() || !data_available()) goto out; checked = 0; } else { @@ -2364,7 +2364,7 @@ void iClass_Authentication_fast(uint64_t arg0, uint64_t arg1, uint8_t *datain) { for (i = 0; i < keyCount; i++) { // Allow button press / usb cmd to interrupt device - if ( checked == 1000 ) { + if (checked == 1000) { if (BUTTON_PRESS() || !data_available()) goto out; checked = 0; } else { diff --git a/client/cmdlfnedap.c b/client/cmdlfnedap.c index d4cca1a30..dc8894971 100644 --- a/client/cmdlfnedap.c +++ b/client/cmdlfnedap.c @@ -58,7 +58,7 @@ static int usage_lf_nedap_sim(void) { PrintAndLogEx(NORMAL, " h : This help"); PrintAndLogEx(NORMAL, " s : subtype, default=5"); PrintAndLogEx(NORMAL, " c : customerCode"); - PrintAndLogEx(NORMAL, " i : ID (max 99999)"); + PrintAndLogEx(NORMAL, " i : ID (max 99999)"); PrintAndLogEx(NORMAL, " l : long (128), default to short (64)"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); @@ -88,7 +88,7 @@ static uint8_t isEven_64_63(const uint8_t *data) { // 8 //NEDAP demod - ASK/Biphase (or Diphase), RF/64 with preamble of 1111111110 (always a 128 bit data stream) static int CmdLFNedapDemod(const char *Cmd) { (void)Cmd; // Cmd is not used so far - + uint8_t data[16], buffer[7], r0, r1, r2, r3, r4, r5, idxC1, idxC2, idxC3, idxC4, idxC5, fixed0, fixed1, unk1, unk2, subtype; // 4 bits size_t size, offset = 0; uint16_t checksum, customerCode; // 12 bits @@ -104,11 +104,11 @@ static int CmdLFNedapDemod(const char *Cmd) { PrintAndLogEx(DEBUG, "DEBUG: Error - NEDAP: preamble not found"); return PM3_ESOFT; } - + // set plot setDemodBuff(DemodBuffer, size, offset); setClockGrid(g_DemodClock, g_DemodStartIdx + (g_DemodClock * offset)); - + // sanity checks if ((size != 128) && (size != 64)) { PrintAndLogEx(DEBUG, "DEBUG: Error - NEDAP: Size not correct: %d", size); @@ -124,7 +124,7 @@ static int CmdLFNedapDemod(const char *Cmd) { int ret = PM3_SUCCESS; // first part - + // parity 1 check if (isEven_64_63(data) != (data[7] & 0x01)) { PrintAndLogEx(ERR, "Bad parity (%1u)", data[7] & 0x01); @@ -137,7 +137,7 @@ static int CmdLFNedapDemod(const char *Cmd) { PrintAndLogEx(ERR, "Bad header"); ret = PM3_ESOFT; } - + buffer[0] = (data[0] << 7) | (data[1] >> 1); buffer[1] = (data[1] << 7) | (data[2] >> 1); buffer[2] = (data[2] << 7) | (data[3] >> 1); @@ -146,7 +146,7 @@ static int CmdLFNedapDemod(const char *Cmd) { // CHECKSUM init_table(CRC_XMODEM); - checksum = crc16_xmodem(buffer, 5); + checksum = crc16_xmodem(buffer, 5); buffer[6] = (data[3] << 7) | ((data[4] & 0xe0) >> 1) | ((data[4] & 0x01) << 3) | ((data[5] & 0xe0) >> 5); buffer[5] = (data[5] << 7) | ((data[6] & 0xe0) >> 1) | ((data[6] & 0x01) << 3) | ((data[7] & 0xe0) >> 5); @@ -156,11 +156,11 @@ static int CmdLFNedapDemod(const char *Cmd) { subtype = (data[1] & 0x1e) >> 1; customerCode = ((data[1] & 0x01) << 11) | (data[2] << 3) | ((data[3] & 0xe0) >> 5); - if ( isValid == false ) { - PrintAndLogEx(ERR, "Checksum : %s (calc 0x%04X != 0x%04X)", _RED_("failed"), checksum, *(uint16_t *)(buffer + 5)); - ret = PM3_ESOFT; + if (isValid == false) { + PrintAndLogEx(ERR, "Checksum : %s (calc 0x%04X != 0x%04X)", _RED_("failed"), checksum, *(uint16_t *)(buffer + 5)); + ret = PM3_ESOFT; } - + idxC1 = invTranslateTable[(data[3] & 0x1e) >> 1]; idxC2 = invTranslateTable[(data[4] & 0x1e) >> 1]; idxC3 = invTranslateTable[(data[5] & 0x1e) >> 1]; @@ -178,45 +178,45 @@ static int CmdLFNedapDemod(const char *Cmd) { badgeId = r1 * 10000 + r2 * 1000 + r3 * 100 + r4 * 10 + r5; PrintAndLogEx(SUCCESS, "NEDAP Tag Found: Card ID "_YELLOW_("%05u")" subtype: "_YELLOW_("%1u")" customer code: "_YELLOW_("%03x"), badgeId, subtype, customerCode); - PrintAndLogEx(SUCCESS, "Checksum is %s (0x%04X)", _GREEN_("OK"), checksum ); - PrintAndLogEx(SUCCESS, "Raw: %s", sprint_hex(data, size/8)); + PrintAndLogEx(SUCCESS, "Checksum is %s (0x%04X)", _GREEN_("OK"), checksum); + PrintAndLogEx(SUCCESS, "Raw: %s", sprint_hex(data, size / 8)); } else { PrintAndLogEx(ERR, "Invalid idx (1:%02x - 2:%02x - 3:%02x - 4:%02x - 5:%02x)", idxC1, idxC2, idxC3, idxC4, idxC5); ret = PM3_ESOFT; } if (size > 64) { - // second part + // second part PrintAndLogEx(DEBUG, "NEDAP Tag, second part found"); - + if (isEven_64_63(data + 8) != (data[15] & 0x01)) { PrintAndLogEx(ERR, "Bad parity (%1u)", data[15] & 0x01); return ret; } - - // validation - if ( (data[8] & 0x80) - && (data[9] & 0x40) - && (data[10] & 0x20) - && (data[11] & 0x10) - && (data[12] & 0x08) - && (data[13] & 0x04) - && (data[14] & 0x02)) { + + // validation + if ((data[8] & 0x80) + && (data[9] & 0x40) + && (data[10] & 0x20) + && (data[11] & 0x10) + && (data[12] & 0x08) + && (data[13] & 0x04) + && (data[14] & 0x02)) { PrintAndLogEx(ERR, "Bad zeros"); return ret; } - - // + + // r4 = (data[8] >> 3) & 0x0F; r5 = ((data[8] << 1) & 0x0F) | (data[9] >> 7); r2 = (data[9] >> 2) & 0x0F; r3 = ((data[9] << 2) & 0x0F) | (data[10] >> 6); r0 = ((data[10] >> 1) & 0x0F); r1 = ((data[10] << 3) & 0x0F) | (data[11] >> 5); - + fixed0 = ((data[11] << 4) & 0xF0) | (data[12] >> 4); fixed1 = ((data[12] << 5) & 0xE0) | (data[13] >> 3); - + unk1 = ((data[13] << 6) & 0xC0) | (data[14] >> 2); unk2 = ((data[14] << 7) & 0xC0) | (data[15] >> 1); @@ -228,7 +228,7 @@ static int CmdLFNedapDemod(const char *Cmd) { if ((fixed0 == FIXED_71) && (fixed1 == FIXED_40)) PrintAndLogEx(DEBUG, "Fixed part {0 = 0x%02x, 1 = 0x%02x}", fixed0, fixed1); - else + else PrintAndLogEx(DEBUG, "Bad fixed: {0 = 0x%02x (%0x02x), 1 = 0x%02x (%0x02x)}", fixed0, FIXED_71, fixed1, FIXED_40); PrintAndLogEx(DEBUG, "Unknown part {1 = 0x%02x, 2 = 0x%02x}", unk1, unk2); @@ -237,7 +237,7 @@ static int CmdLFNedapDemod(const char *Cmd) { return ret; } } - + return PM3_SUCCESS; } @@ -390,7 +390,7 @@ static int CmdLfNedapGen(const char *Cmd) { //Validations if ((!customerCode) || (!id) || (subType > 0xF) || (customerCode > 0xFFF) || (id > 99999)) errors = true; - + if (errors || cmdp == 0) { usage(); return PM3_EINVARG; @@ -402,13 +402,13 @@ static int CmdLfNedapGen(const char *Cmd) { , subType , customerCode , id - ); + ); NedapGen(subType, customerCode, id, isLong, data); - + for (i = 0; i < (isLong ? 16 : 8); i++) num_to_bytebits(data[i], 8, bin + i * 8); - + setDemodBuff(bin, (isLong ? 128 : 64), 0); return PM3_SUCCESS; } @@ -421,16 +421,16 @@ int CmdLFNedapClone(const char *Cmd) { if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_nedap_clone(); usage_to_be_displayed = usage_lf_nedap_clone; - + int ret = CmdLfNedapGen(Cmd); if (ret != PM3_SUCCESS) return ret; - + if ((DemodBufferLen != 128) && (DemodBufferLen != 64)) { PrintAndLogEx(ERR, "Error with tag bitstream generation."); return PM3_ESOFT; } - + CmdPrintDemodBuff("x"); // What we had before in commented code: @@ -479,7 +479,7 @@ int CmdLFNedapClone(const char *Cmd) { } // TODO info correct? PrintAndLogEx(INFO, "The block 0 was changed (eXtended) which can be hard to detect. Configure it manually with"); - PrintAndLogEx(INFO, _YELLOW_("`lf t55xx config b 64 d BI i 1 o 32`") ); + PrintAndLogEx(INFO, _YELLOW_("`lf t55xx config b 64 d BI i 1 o 32`")); return PM3_SUCCESS; } @@ -489,11 +489,11 @@ static int CmdLFNedapSim(const char *Cmd) { if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_nedap_sim(); usage_to_be_displayed = usage_lf_nedap_sim; - + int ret = CmdLfNedapGen(Cmd); if (ret != PM3_SUCCESS) return ret; - + if ((DemodBufferLen != 128) && (DemodBufferLen != 64)) { PrintAndLogEx(ERR, "Error with tag bitstream generation."); return PM3_ESOFT; @@ -520,7 +520,7 @@ static int CmdLFNedapSim(const char *Cmd) { PrintAndLogEx(INFO, "Done"); if (resp.status != PM3_EOPABORTED) return resp.status; - + return PM3_SUCCESS; } From ab856ab73d81724fc9533305099d5b37275fd14d Mon Sep 17 00:00:00 2001 From: Victor Date: Tue, 6 Aug 2019 02:00:26 +0100 Subject: [PATCH 0264/1854] Update Android Termux guide --- doc/termux_notes.md | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/doc/termux_notes.md b/doc/termux_notes.md index a2f883846..d86ec7f08 100644 --- a/doc/termux_notes.md +++ b/doc/termux_notes.md @@ -29,28 +29,15 @@ ref : https://github.com/Proxmark/proxmark3/wiki/android - [Magisk 19.3](https://github.com/topjohnwu/Magisk/) ## Setup -### Getting ncurses with termcap -You need `termcap` to build the Proxmark3 client. Unfortunately, the prebuilt `ncurses` package does not include it. Since [this PR](https://github.com/termux/termux-packages/pull/2131) hasn't been merged yet, you will have to build `ncurses` yourself - -1. Clone the [termux-packages](https://github.com/termux/termux-packages) repo -2. Apply [the PR](https://github.com/termux/termux-packages/pull/2131) -3. Build `ncurses`. Refer to the [build docs](https://github.com/termux/termux-packages/blob/master/docs/BUILD_ENVIRONMENT.md) for more information. The easiest way is to use Docker: - - `./scripts/run-docker.sh` - - `./build-package.sh ncurses` - - the built packages will be under the `debs` directory -4. Copy `ncurses_6.1.x-x_aarch64.deb` to your phone's `/sdcard` ### Setting up Termux 1. Install [Termux](https://play.google.com/store/apps/details?id=com.termux) and start it 2. Run the following commands: ``` -pkg install make, clang, clang++, readline-dev, libclang-dev, libc++, git, tsu -termux-setup-storage -dpkg -i /sdcard/ncurses_6.1.x-x_aarch64.deb +pkg install make clang clang++ readline libc++ git tsu git clone https://github.com/RfidResearchGroup/proxmark3.git ``` ### Building Proxmark3 client -1. Edit `proxmark3/client/Makefile` and append `-fPIC` to the `CFLAGS` variable (line 30) -2. `make clean && make client` +1. `make clean && make client` ### USB_ACM You need the `USB_ACM` driver enabled and working to communicate with the Proxmark3. To see if it's working, run `tsudo ls /dev/tty*` and it should list `/dev/ttyACM0` (or similar). If you see this, congratulations, skip this step! From 2cbe43f269e47cb36817d6b42bb2c76014364e53 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 6 Aug 2019 13:09:48 +0200 Subject: [PATCH 0265/1854] clarifications and minor changes in slow clock related operations: * SpinDelay and SpinDelayUs: now rounding applies instead of truncating * Document maximum duration of SpinDelay/SpinDelayUs/BUTTON_CLICK/BUTTON_HELD * Add argument check against max duration in SpinDelay/BUTTON_CLICK/BUTTON_HELD * Document why these functions don't need to take wrapping into acount as in GetTickCountDelta * Use >= in the spinning loops * Clarify StartTickCount calibration operations and use masks AT91C_CKGR_MAINRDY and AT91C_RTTC_RTPRES --- armsrc/ticks.c | 22 +++++++++++++++------- armsrc/util.c | 20 +++++++++++++++++--- common/usb_cdc.c | 4 +++- 3 files changed, 35 insertions(+), 11 deletions(-) diff --git a/armsrc/ticks.c b/armsrc/ticks.c index 22c5d5be1..ac76f99e3 100644 --- a/armsrc/ticks.c +++ b/armsrc/ticks.c @@ -9,12 +9,14 @@ // Timers, Clocks functions used in LF or Legic where you would need detailed time. //----------------------------------------------------------------------------- #include "ticks.h" -// attempt at high resolution microsecond timer -// beware: timer counts in 21.3uS increments (1024/48Mhz) + +// timer counts in 21.3uS increments (1024/48Mhz), rounding applies +// WARNING: timer can't measure more than 1.39s (21.3uS * 0xffff) void SpinDelayUs(int us) { - int ticks = (48 * us) >> 10; + int ticks = (48 * us + 512) >> 10; // Borrow a PWM unit for my real-time clock + // This resets PWMC_CPRDR as well AT91C_BASE_PWMC->PWMC_ENA = PWM_CHANNEL(0); // 48 MHz / 1024 gives 46.875 kHz @@ -26,14 +28,19 @@ void SpinDelayUs(int us) { for (;;) { uint16_t now = AT91C_BASE_PWMC_CH0->PWMC_CCNTR; - if (now == (uint16_t)(start + ticks)) + if (now >= (uint16_t)(start + ticks)) return; WDT_HIT(); } } +// WARNING: timer can't measure more than 1.39s (21.3uS * 0xffff) void SpinDelay(int ms) { + if (ms > 1390) { + Dbprintf(_RED_("Error, SpinDelay called with %i > 1390"), ms); + ms = 1390; + } // convert to uS and call microsecond delay function SpinDelayUs(ms * 1000); } @@ -49,9 +56,10 @@ void SpinDelay(int ms) { void StartTickCount(void) { // This timer is based on the slow clock. The slow clock frequency is between 22kHz and 40kHz. // We can determine the actual slow clock frequency by looking at the Main Clock Frequency Register. - uint16_t mainf = AT91C_BASE_PMC->PMC_MCFR & 0xffff; // = 16 * main clock frequency (16MHz) / slow clock frequency - // set RealTimeCounter divider to count at 1kHz: - AT91C_BASE_RTTC->RTTC_RTMR = AT91C_RTTC_RTTRST | ((256000 + (mainf / 2)) / mainf); + while ((AT91C_BASE_PMC->PMC_MCFR & AT91C_CKGR_MAINRDY) == 0); // Wait for MAINF value to become available... + uint16_t mainf = AT91C_BASE_PMC->PMC_MCFR & AT91C_CKGR_MAINF; // Get # main clocks within 16 slow clocks + // set RealTimeCounter divider to count at 1kHz, should be 32 if RC is exactly at 32kHz: + AT91C_BASE_RTTC->RTTC_RTMR = AT91C_RTTC_RTTRST | ((((16000000 / 1000 * 16) + (mainf / 2)) / mainf) & AT91C_RTTC_RTPRES); // note: worst case precision is approx 2.5% } diff --git a/armsrc/util.c b/armsrc/util.c index cad2d2ac5..3deb97b6d 100644 --- a/armsrc/util.c +++ b/armsrc/util.c @@ -176,6 +176,12 @@ void SpinUp(uint32_t speed) { // double click, otherwise it will waste 500ms -- use BUTTON_HELD instead int BUTTON_CLICKED(int ms) { // Up to 500ms in between clicks to mean a double click + // timer counts in 21.3uS increments (1024/48Mhz) + // WARNING: timer can't measure more than 1.39s (21.3uS * 0xffff) + if (ms > 1390) { + Dbprintf(_RED_("Error, BUTTON_CLICKED called with %i > 1390"), ms); + ms = 1390; + } int ticks = (48000 * (ms ? ms : 1000)) >> 10; // If we're not even pressed, forget about it! @@ -183,6 +189,7 @@ int BUTTON_CLICKED(int ms) { return BUTTON_NO_CLICK; // Borrow a PWM unit for my real-time clock + // This resets PWMC_CPRDR as well AT91C_BASE_PWMC->PWMC_ENA = PWM_CHANNEL(0); // 48 MHz / 1024 gives 46.875 kHz AT91C_BASE_PWMC_CH0->PWMC_CMR = PWM_CH_MODE_PRESCALER(10); @@ -209,7 +216,7 @@ int BUTTON_CLICKED(int ms) { // Still haven't let it off else // Have we held down a full second? - if (now == (uint16_t)(start + ticks)) + if (now >= (uint16_t)(start + ticks)) return BUTTON_HOLD; } @@ -220,7 +227,7 @@ int BUTTON_CLICKED(int ms) { return BUTTON_DOUBLE_CLICK; // Have we ran out of time to double click? - else if (now == (uint16_t)(start + ticks)) + else if (now >= (uint16_t)(start + ticks)) // At least we did a single click return BUTTON_SINGLE_CLICK; @@ -233,6 +240,12 @@ int BUTTON_CLICKED(int ms) { // Determine if a button is held down int BUTTON_HELD(int ms) { + // timer counts in 21.3uS increments (1024/48Mhz) + // WARNING: timer can't measure more than 1.39s (21.3uS * 0xffff) + if (ms > 1390) { + Dbprintf(_RED_("Error, BUTTON_HELD called with %i > 1390"), ms); + ms = 1390; + } // If button is held for one second int ticks = (48000 * (ms ? ms : 1000)) >> 10; @@ -241,6 +254,7 @@ int BUTTON_HELD(int ms) { return BUTTON_NO_CLICK; // Borrow a PWM unit for my real-time clock + // This resets PWMC_CPRDR as well AT91C_BASE_PWMC->PWMC_ENA = PWM_CHANNEL(0); // 48 MHz / 1024 gives 46.875 kHz AT91C_BASE_PWMC_CH0->PWMC_CMR = PWM_CH_MODE_PRESCALER(10); @@ -257,7 +271,7 @@ int BUTTON_HELD(int ms) { return BUTTON_SINGLE_CLICK; // Have we waited the full second? - else if (now == (uint16_t)(start + ticks)) + else if (now >= (uint16_t)(start + ticks)) return BUTTON_HOLD; WDT_HIT(); diff --git a/common/usb_cdc.c b/common/usb_cdc.c index 25a5d80d9..073fa80f2 100644 --- a/common/usb_cdc.c +++ b/common/usb_cdc.c @@ -446,9 +446,11 @@ AT91S_CDC_LINE_CODING line = { // purely informative, actual values don't matter 8 // 8 Data bits }; +// timer counts in 21.3uS increments (1024/48Mhz), rounding applies +// WARNING: timer can't measure more than 1.39s (21.3uS * 0xffff) static void SpinDelay(int ms) { int us = ms * 1000; - int ticks = (48 * us) >> 10; + int ticks = (48 * us + 512) >> 10; // Borrow a PWM unit for my real-time clock AT91C_BASE_PWMC->PWMC_ENA = PWM_CHANNEL(0); From 8b3159c83d4b96ae0dbf3520abfe4f75d2971c8a Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 6 Aug 2019 13:40:08 +0200 Subject: [PATCH 0266/1854] Use more defines when using main clock or master clock --- armsrc/flashmem.h | 1 - armsrc/ticks.c | 4 ++-- armsrc/util.c | 4 ++-- common/usart.c | 4 ++-- common/usb_cdc.c | 2 +- include/proxmark3.h | 4 ++++ 6 files changed, 11 insertions(+), 8 deletions(-) diff --git a/armsrc/flashmem.h b/armsrc/flashmem.h index 26d2d974d..b332ec3f5 100644 --- a/armsrc/flashmem.h +++ b/armsrc/flashmem.h @@ -102,7 +102,6 @@ #define MAX_BLOCKS 4 #define MAX_SECTORS 16 -#define MCK 48000000 //#define FLASH_BAUD 24000000 #define FLASH_MINFAST 24000000 //33000000 #define FLASH_BAUD MCK/2 diff --git a/armsrc/ticks.c b/armsrc/ticks.c index ac76f99e3..23e9e3d1d 100644 --- a/armsrc/ticks.c +++ b/armsrc/ticks.c @@ -13,7 +13,7 @@ // timer counts in 21.3uS increments (1024/48Mhz), rounding applies // WARNING: timer can't measure more than 1.39s (21.3uS * 0xffff) void SpinDelayUs(int us) { - int ticks = (48 * us + 512) >> 10; + int ticks = ((MCK / 1000000) * us + 512) >> 10; // Borrow a PWM unit for my real-time clock // This resets PWMC_CPRDR as well @@ -59,7 +59,7 @@ void StartTickCount(void) { while ((AT91C_BASE_PMC->PMC_MCFR & AT91C_CKGR_MAINRDY) == 0); // Wait for MAINF value to become available... uint16_t mainf = AT91C_BASE_PMC->PMC_MCFR & AT91C_CKGR_MAINF; // Get # main clocks within 16 slow clocks // set RealTimeCounter divider to count at 1kHz, should be 32 if RC is exactly at 32kHz: - AT91C_BASE_RTTC->RTTC_RTMR = AT91C_RTTC_RTTRST | ((((16000000 / 1000 * 16) + (mainf / 2)) / mainf) & AT91C_RTTC_RTPRES); + AT91C_BASE_RTTC->RTTC_RTMR = AT91C_RTTC_RTTRST | ((((MAINCK / 1000 * 16) + (mainf / 2)) / mainf) & AT91C_RTTC_RTPRES); // note: worst case precision is approx 2.5% } diff --git a/armsrc/util.c b/armsrc/util.c index 3deb97b6d..42d936450 100644 --- a/armsrc/util.c +++ b/armsrc/util.c @@ -182,7 +182,7 @@ int BUTTON_CLICKED(int ms) { Dbprintf(_RED_("Error, BUTTON_CLICKED called with %i > 1390"), ms); ms = 1390; } - int ticks = (48000 * (ms ? ms : 1000)) >> 10; + int ticks = ((MCK / 1000) * (ms ? ms : 1000)) >> 10; // If we're not even pressed, forget about it! if (!BUTTON_PRESS()) @@ -210,7 +210,7 @@ int BUTTON_CLICKED(int ms) { // reset our timer for 500ms start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR; - ticks = (48000 * (500)) >> 10; + ticks = ((MCK / 1000) * (500)) >> 10; } // Still haven't let it off diff --git a/common/usart.c b/common/usart.c index ced1e5e6b..cb52d0116 100644 --- a/common/usart.c +++ b/common/usart.c @@ -229,9 +229,9 @@ void usart_init(uint32_t baudrate, uint8_t parity) { // OVER = 1, -yes we are oversampling // baudrate == selected clock/8/CD --> this is ours // - uint32_t brgr = 48000000 / (usart_baudrate << 3); + uint32_t brgr = MCK / (usart_baudrate << 3); // doing fp = round((mck / (usart_baudrate << 3) - brgr) * 8) with integers: - uint32_t fp = ((16 * 48000000 / (usart_baudrate << 3) - 16 * brgr) + 1) / 2; + uint32_t fp = ((16 * MCK / (usart_baudrate << 3) - 16 * brgr) + 1) / 2; pUS1->US_BRGR = (fp << 16) | brgr; diff --git a/common/usb_cdc.c b/common/usb_cdc.c index 073fa80f2..7f8deb62d 100644 --- a/common/usb_cdc.c +++ b/common/usb_cdc.c @@ -450,7 +450,7 @@ AT91S_CDC_LINE_CODING line = { // purely informative, actual values don't matter // WARNING: timer can't measure more than 1.39s (21.3uS * 0xffff) static void SpinDelay(int ms) { int us = ms * 1000; - int ticks = (48 * us + 512) >> 10; + int ticks = ((MCK / 1000000) * us + 512) >> 10; // Borrow a PWM unit for my real-time clock AT91C_BASE_PWMC->PWMC_ENA = PWM_CHANNEL(0); diff --git a/include/proxmark3.h b/include/proxmark3.h index 469713b5b..ddda6826a 100644 --- a/include/proxmark3.h +++ b/include/proxmark3.h @@ -17,6 +17,10 @@ #include "pm3_cmd.h" #include "common.h" +// Check bootrom.c for actual clock settings +#define MAINCK 16000000 +#define MCK (4 * MAINCK) + #define WDT_HIT() AT91C_BASE_WDTC->WDTC_WDCR = 0xa5000001 #define PWM_CH_MODE_PRESCALER(x) ((x) << 0) From c74028fa10ddbeb8a567846a7f261d45602dc331 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 6 Aug 2019 13:42:17 +0200 Subject: [PATCH 0267/1854] show slow clock in hw status --- armsrc/appmain.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index fd33c1ec8..2978397d9 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -431,6 +431,9 @@ void SendStatus(void) { Dbprintf(" ToSendMax...............%d", ToSendMax); Dbprintf(" ToSendBit...............%d", ToSendBit); Dbprintf(" ToSend BUFFERSIZE.......%d", TOSEND_BUFFER_SIZE); + while ((AT91C_BASE_PMC->PMC_MCFR & AT91C_CKGR_MAINRDY) == 0); // Wait for MAINF value to become available... + uint16_t mainf = AT91C_BASE_PMC->PMC_MCFR & AT91C_CKGR_MAINF; // Get # main clocks within 16 slow clocks + Dbprintf(" Slow clock..............%d Hz", (16*MAINCK) / mainf); DbpString(_BLUE_("Installed StandAlone Mode")); ModInfo(); From 1354aec5567ff268936140c44134f8d3162b4d72 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 6 Aug 2019 13:51:10 +0200 Subject: [PATCH 0268/1854] typos --- armsrc/appmain.c | 8 ++++---- armsrc/felica.c | 2 +- armsrc/flashmem.c | 2 +- armsrc/fpgaloader.c | 4 ++-- armsrc/hitag2.c | 6 +++--- armsrc/hitagS.c | 8 ++++---- armsrc/iso14443a.c | 2 +- armsrc/iso15693.c | 4 ++-- armsrc/lfops.c | 28 ++++++++++++++-------------- armsrc/lfsampling.c | 6 +++--- armsrc/pcf7931.c | 2 +- armsrc/ticks.c | 8 ++++---- armsrc/util.c | 8 ++++---- bootrom/bootrom.c | 10 +++++----- client/cmddata.c | 2 +- client/cmdflashmem.c | 6 +++--- client/cmdhw.c | 4 ++-- client/cmdsmartcard.c | 8 ++++---- client/cmdtrace.c | 4 ++-- common/i2c.c | 4 ++-- common/iso15693tools.h | 8 ++++---- common/usb_cdc.c | 4 ++-- fpga/hi_simulate.v | 2 +- fpga/lf_edge_detect.v | 2 +- fpga/lo_adc.v | 2 +- fpga/lo_read.v | 4 ++-- fpga/lp20khz_1MSa_iir_filter.v | 2 +- fpga/testbed_hi_read_tx.v | 2 +- fpga/testbed_hi_simulate.v | 2 +- fpga/testbed_lo_read.v | 10 +++++----- fpga/testbed_lo_simulate.v | 4 ++-- 31 files changed, 84 insertions(+), 84 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 2978397d9..2529dc198 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -267,9 +267,9 @@ void MeasureAntennaTuning(void) { SpinDelay(20); uint32_t adcval = ((MAX_ADC_LF_VOLTAGE * AvgAdc(ADC_CHAN_LF)) >> 10); if (i == 95) - v_lf125 = adcval; // voltage at 125Khz + v_lf125 = adcval; // voltage at 125kHz if (i == 89) - v_lf134 = adcval; // voltage at 134Khz + v_lf134 = adcval; // voltage at 134kHz LF_Results[i] = adcval >> 9; // scale int to fit in byte for graphing purposes if (LF_Results[i] > peak) { @@ -1956,8 +1956,8 @@ void __attribute__((noreturn)) AppMain(void) { AT91C_BASE_PIOA->PIO_BSR = GPIO_PCK0; AT91C_BASE_PIOA->PIO_PDR = GPIO_PCK0; AT91C_BASE_PMC->PMC_SCER |= AT91C_PMC_PCK0; - // PCK0 is PLL clock / 4 = 96Mhz / 4 = 24Mhz - AT91C_BASE_PMC->PMC_PCKR[0] = AT91C_PMC_CSS_PLL_CLK | AT91C_PMC_PRES_CLK_4; // 4 for 24Mhz pck0, 2 for 48 MHZ pck0 + // PCK0 is PLL clock / 4 = 96MHz / 4 = 24MHz + AT91C_BASE_PMC->PMC_PCKR[0] = AT91C_PMC_CSS_PLL_CLK | AT91C_PMC_PRES_CLK_4; // 4 for 24MHz pck0, 2 for 48 MHZ pck0 AT91C_BASE_PIOA->PIO_OER = GPIO_PCK0; // Reset SPI diff --git a/armsrc/felica.c b/armsrc/felica.c index 5420f56d4..b732683e5 100644 --- a/armsrc/felica.c +++ b/armsrc/felica.c @@ -7,7 +7,7 @@ #include "crc16.h" // crc16 ccitt // FeliCa timings -// minimum time between the start bits of consecutive transfers from reader to tag: 6800 carrier (13.56Mhz) cycles +// minimum time between the start bits of consecutive transfers from reader to tag: 6800 carrier (13.56MHz) cycles #ifndef FELICA_REQUEST_GUARD_TIME # define FELICA_REQUEST_GUARD_TIME (6800/16 + 1) #endif diff --git a/armsrc/flashmem.c b/armsrc/flashmem.c index 81e5f767d..19c249ffe 100644 --- a/armsrc/flashmem.c +++ b/armsrc/flashmem.c @@ -16,7 +16,7 @@ uint32_t FLASHMEM_SPIBAUDRATE = FLASH_BAUD; void FlashmemSetSpiBaudrate(uint32_t baudrate) { FLASHMEM_SPIBAUDRATE = baudrate; - Dbprintf("Spi Baudrate : %dMhz", FLASHMEM_SPIBAUDRATE / 1000000); + Dbprintf("Spi Baudrate : %dMHz", FLASHMEM_SPIBAUDRATE / 1000000); } // initialize diff --git a/armsrc/fpgaloader.c b/armsrc/fpgaloader.c index 7e920a360..5b55325d7 100644 --- a/armsrc/fpgaloader.c +++ b/armsrc/fpgaloader.c @@ -81,7 +81,7 @@ void SetupSpi(int mode) { AT91C_BASE_SPI->SPI_CSR[0] = (1 << 24) | // Delay between Consecutive Transfers (32 MCK periods) (1 << 16) | // Delay Before SPCK (1 MCK period) - (6 << 8) | // Serial Clock Baud Rate (baudrate = MCK/6 = 24Mhz/6 = 4M baud + (6 << 8) | // Serial Clock Baud Rate (baudrate = MCK/6 = 24MHz/6 = 4M baud AT91C_SPI_BITS_16 | // Bits per Transfer (16 bits) (0 << 3) | // Chip Select inactive after transfer AT91C_SPI_NCPHA | // Clock Phase data captured on leading edge, changes on following edge @@ -101,7 +101,7 @@ void SetupSpi(int mode) { AT91C_BASE_SPI->SPI_CSR[2] = ( 1 << 24) | // Delay between Consecutive Transfers (32 MCK periods) ( 1 << 16) | // Delay Before SPCK (1 MCK period) - ( 6 << 8) | // Serial Clock Baud Rate (baudrate = MCK/6 = 24Mhz/6 = 4M baud + ( 6 << 8) | // Serial Clock Baud Rate (baudrate = MCK/6 = 24MHz/6 = 4M baud AT91C_SPI_BITS_9 | // Bits per Transfer (9 bits) ( 0 << 3) | // Chip Select inactive after transfer ( 1 << 1) | // Clock Phase data captured on leading edge, changes on following edge diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index f1350f12a..14db91e91 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -965,7 +965,7 @@ void SimulateHitagTag(bool tag_mem_supplied, uint8_t *data) { // Set up simulator mode, frequency divisor which will drive the FPGA // and analog mux selection. FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125kHz SetAdcMuxFor(GPIO_MUXSEL_LOPKD); // Configure output pin that is connected to the FPGA (for modulating) @@ -1171,7 +1171,7 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { // Set fpga in edge detect with reader field, we can modulate as reader now FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125kHz SetAdcMuxFor(GPIO_MUXSEL_LOPKD); // Configure output and enable pin that is connected to the FPGA (for modulating) @@ -1442,7 +1442,7 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) { // Set fpga in edge detect with reader field, we can modulate as reader now FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125kHz SetAdcMuxFor(GPIO_MUXSEL_LOPKD); // Disable modulation at default, which means enable the field diff --git a/armsrc/hitagS.c b/armsrc/hitagS.c index d52e18fd4..e3f1456aa 100644 --- a/armsrc/hitagS.c +++ b/armsrc/hitagS.c @@ -983,7 +983,7 @@ void SimulateHitagSTag(bool tag_mem_supplied, uint8_t *data) { // and analog mux selection. FpgaDownloadAndGo(FPGA_BITSTREAM_LF); FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125kHz SetAdcMuxFor(GPIO_MUXSEL_LOPKD); // Configure output pin that is connected to the FPGA (for modulating) @@ -1182,7 +1182,7 @@ void ReadHitagS(hitag_function htf, hitag_data *htd) { // Set fpga in edge detect with reader field, we can modulate as reader now FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125kHz SetAdcMuxFor(GPIO_MUXSEL_LOPKD); // Configure output and enable pin that is connected to the FPGA (for modulating) @@ -1517,7 +1517,7 @@ void WritePageHitagS(hitag_function htf, hitag_data *htd, int page) { // Set fpga in edge detect with reader field, we can modulate as reader now FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125kHz SetAdcMuxFor(GPIO_MUXSEL_LOPKD); // Disable modulation at default, which means enable the field @@ -1778,7 +1778,7 @@ void check_challenges(bool file_given, uint8_t *data) { // Set fpga in edge detect with reader field, we can modulate as reader now FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125kHz SetAdcMuxFor(GPIO_MUXSEL_LOPKD); // Disable modulation at default, which means enable the field diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index e5bf6487a..2e7aeebe3 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -25,7 +25,7 @@ static uint8_t iso14_pcb_blocknum = 0; // // ISO14443 timing: // -// minimum time between the start bits of consecutive transfers from reader to tag: 7000 carrier (13.56Mhz) cycles +// minimum time between the start bits of consecutive transfers from reader to tag: 7000 carrier (13.56MHz) cycles #define REQUEST_GUARD_TIME (7000/16 + 1) // minimum time between last modulation of tag and next start bit from reader to tag: 1172 carrier cycles #define FRAME_DELAY_TIME_PICC_TO_PCD (1172/16 + 1) diff --git a/armsrc/iso15693.c b/armsrc/iso15693.c index e74ca972d..c33230090 100644 --- a/armsrc/iso15693.c +++ b/armsrc/iso15693.c @@ -32,8 +32,8 @@ // // VICC (tag) -> VCD (reader) // Modulation: -// ASK / one subcarrier (423,75 khz) -// FSK / two subcarriers (423,75 khz && 484,28 khz) +// ASK / one subcarrier (423,75 kHz) +// FSK / two subcarriers (423,75 kHz && 484,28 kHz) // Data Rates / Modes: // low ASK: 6,62 kbit/s // low FSK: 6.67 kbit/s diff --git a/armsrc/lfops.c b/armsrc/lfops.c index daae31bca..1ef366cfb 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -33,7 +33,7 @@ still benefit from this repo. This is why its configurable and we use to set th // VALUES TAKEN FROM EM4x function: SendForward -// START_GAP = 440; (55*8) cycles at 125Khz (8us = 1cycle) +// START_GAP = 440; (55*8) cycles at 125kHz (8us = 1cycle) // WRITE_GAP = 128; (16*8) // WRITE_1 = 256 32*8; (32*8) @@ -374,7 +374,7 @@ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint } // hack2 needed--- it appears to take about 8-16us to turn the antenna back on - // leading to ~ 1 to 2 125khz samples extra in every off period + // leading to ~ 1 to 2 125kHz samples extra in every off period // so we should test for last 0 before next 1 and reduce period_0 by this extra amount... // but is this time different for every antenna or other hw builds??? more testing needed @@ -447,9 +447,9 @@ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint void ReadTItag(void) { StartTicks(); // some hardcoded initial params - // when we read a TI tag we sample the zerocross line at 2Mhz - // TI tags modulate a 1 as 16 cycles of 123.2Khz - // TI tags modulate a 0 as 16 cycles of 134.2Khz + // when we read a TI tag we sample the zerocross line at 2MHz + // TI tags modulate a 1 as 16 cycles of 123.2kHz + // TI tags modulate a 0 as 16 cycles of 134.2kHz #define FSAMPLE 2000000 #define FREQLO 123200 #define FREQHI 134200 @@ -465,9 +465,9 @@ void ReadTItag(void) { // when to tell if we're close enough to one freq or another uint32_t threshold = (sampleslo - sampleshi + 1) >> 1; - // TI tags charge at 134.2Khz + // TI tags charge at 134.2kHz FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8kHz // Place FPGA in passthrough mode, in this mode the CROSS_LO line // connects to SSP_DIN and the SSP_DOUT logic level controls @@ -693,8 +693,8 @@ void WriteTItag(uint32_t idhi, uint32_t idlo, uint16_t crc) { } Dbprintf("Writing to tag: %x%08x, crc=%x", idhi, idlo, crc); - // TI tags charge at 134.2Khz - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz + // TI tags charge at 134.2kHz + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8kHz // Place FPGA in passthrough mode, in this mode the CROSS_LO line // connects to SSP_DIN and the SSP_DOUT logic level controls // whether we're modulating the antenna (high) @@ -767,9 +767,9 @@ void SimulateTagLowFrequencyEx(int period, int gap, bool ledcontrol, int numcycl sample_config *sc = getSamplingConfig(); if ((sc->divisor == 1) || (sc->divisor < 0) || (sc->divisor > 255)) - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8kHz else if (sc->divisor == 0) - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125kHz else FpgaSendCommand(FPGA_CMD_SET_DIVISOR, sc->divisor); @@ -1195,7 +1195,7 @@ void CmdHIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol) size_t size; uint32_t hi2 = 0, hi = 0, lo = 0; int dummyIdx = 0; - // Configure to go in 125Khz listen mode + // Configure to go in 125kHz listen mode LFSetupFPGAForADC(95, true); //clear read buffer @@ -1446,7 +1446,7 @@ void CmdIOdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol) { BigBuf_Clear_keep_EM(); - // Configure to go in 125Khz listen mode + // Configure to go in 125kHz listen mode LFSetupFPGAForADC(95, true); while (!BUTTON_PRESS() && !data_available()) { @@ -2254,7 +2254,7 @@ uint8_t *fwd_write_ptr; //forwardlink bit pointer //==================================================================== //-------------------------------------------------------------------- // VALUES TAKEN FROM EM4x function: SendForward -// START_GAP = 440; (55*8) cycles at 125Khz (8us = 1cycle) +// START_GAP = 440; (55*8) cycles at 125kHz (8us = 1cycle) // WRITE_GAP = 128; (16*8) // WRITE_1 = 256 32*8; (32*8) diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index c88401229..2e6ed88a4 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -13,7 +13,7 @@ Default LF config is set to: decimation = 1 (we keep 1 out of 1 samples) bits_per_sample = 8 averaging = YES - divisor = 95 (125khz) + divisor = 95 (125kHz) trigger_threshold = 0 */ sample_config config = { 1, 8, 1, 95, 0 } ; @@ -83,9 +83,9 @@ void pushBit(BitstreamOut *stream, uint8_t bit) { void LFSetupFPGAForADC(int divisor, bool lf_field) { FpgaDownloadAndGo(FPGA_BITSTREAM_LF); if ((divisor == 1) || (divisor < 0) || (divisor > 255)) - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8kHz else if (divisor == 0) - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125kHz else FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor); diff --git a/armsrc/pcf7931.c b/armsrc/pcf7931.c index 942569a9c..a80e30927 100644 --- a/armsrc/pcf7931.c +++ b/armsrc/pcf7931.c @@ -404,7 +404,7 @@ void SendCmdPCF7931(uint32_t *tab) { Dbprintf("Sending data frame..."); FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125kHz FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU); LED_A_ON(); diff --git a/armsrc/ticks.c b/armsrc/ticks.c index 23e9e3d1d..b19c3b510 100644 --- a/armsrc/ticks.c +++ b/armsrc/ticks.c @@ -10,8 +10,8 @@ //----------------------------------------------------------------------------- #include "ticks.h" -// timer counts in 21.3uS increments (1024/48Mhz), rounding applies -// WARNING: timer can't measure more than 1.39s (21.3uS * 0xffff) +// timer counts in 21.3us increments (1024/48MHz), rounding applies +// WARNING: timer can't measure more than 1.39s (21.3us * 0xffff) void SpinDelayUs(int us) { int ticks = ((MCK / 1000000) * us + 512) >> 10; @@ -35,13 +35,13 @@ void SpinDelayUs(int us) { } } -// WARNING: timer can't measure more than 1.39s (21.3uS * 0xffff) +// WARNING: timer can't measure more than 1.39s (21.3us * 0xffff) void SpinDelay(int ms) { if (ms > 1390) { Dbprintf(_RED_("Error, SpinDelay called with %i > 1390"), ms); ms = 1390; } - // convert to uS and call microsecond delay function + // convert to us and call microsecond delay function SpinDelayUs(ms * 1000); } // ------------------------------------------------------------------------- diff --git a/armsrc/util.c b/armsrc/util.c index 42d936450..a5245e356 100644 --- a/armsrc/util.c +++ b/armsrc/util.c @@ -176,8 +176,8 @@ void SpinUp(uint32_t speed) { // double click, otherwise it will waste 500ms -- use BUTTON_HELD instead int BUTTON_CLICKED(int ms) { // Up to 500ms in between clicks to mean a double click - // timer counts in 21.3uS increments (1024/48Mhz) - // WARNING: timer can't measure more than 1.39s (21.3uS * 0xffff) + // timer counts in 21.3us increments (1024/48MHz) + // WARNING: timer can't measure more than 1.39s (21.3us * 0xffff) if (ms > 1390) { Dbprintf(_RED_("Error, BUTTON_CLICKED called with %i > 1390"), ms); ms = 1390; @@ -240,8 +240,8 @@ int BUTTON_CLICKED(int ms) { // Determine if a button is held down int BUTTON_HELD(int ms) { - // timer counts in 21.3uS increments (1024/48Mhz) - // WARNING: timer can't measure more than 1.39s (21.3uS * 0xffff) + // timer counts in 21.3us increments (1024/48MHz) + // WARNING: timer can't measure more than 1.39s (21.3us * 0xffff) if (ms > 1390) { Dbprintf(_RED_("Error, BUTTON_HELD called with %i > 1390"), ms); ms = 1390; diff --git a/bootrom/bootrom.c b/bootrom/bootrom.c index 1a3dafc12..31bb139ef 100644 --- a/bootrom/bootrom.c +++ b/bootrom/bootrom.c @@ -52,7 +52,7 @@ void DbpString(char *str) { static void ConfigClocks(void) { // we are using a 16 MHz crystal as the basis for everything - // slow clock runs at 32Khz typical regardless of crystal + // slow clock runs at 32kHz typical regardless of crystal // enable system clock and USB clock AT91C_BASE_PMC->PMC_SCER |= AT91C_PMC_PCK | AT91C_PMC_UDP; @@ -66,8 +66,8 @@ static void ConfigClocks(void) { (1 << AT91C_ID_PWMC) | (1 << AT91C_ID_UDP); - // worst case scenario, with MAINCK = 16Mhz xtal, startup delay is 1.4ms - // if SLCK slow clock runs at its worst case (max) frequency of 42khz + // worst case scenario, with MAINCK = 16MHz xtal, startup delay is 1.4ms + // if SLCK slow clock runs at its worst case (max) frequency of 42kHz // max startup delay = (1.4ms*42k)/8 = 7.356 so round up to 8 // enable main oscillator and set startup delay @@ -80,7 +80,7 @@ static void ConfigClocks(void) { // PLL output clock frequency in range 80 - 160 MHz needs CKGR_PLL = 00 // PLL output clock frequency in range 150 - 180 MHz needs CKGR_PLL = 10 - // PLL output is MAINCK * multiplier / divisor = 16Mhz * 12 / 2 = 96Mhz + // PLL output is MAINCK * multiplier / divisor = 16MHz * 12 / 2 = 96MHz AT91C_BASE_PMC->PMC_PLLR = PMC_PLL_DIVISOR(2) | //PMC_PLL_COUNT_BEFORE_LOCK(0x10) | @@ -92,7 +92,7 @@ static void ConfigClocks(void) { // wait for PLL to lock while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCK)) {}; - // we want a master clock (MCK) to be PLL clock / 2 = 96Mhz / 2 = 48Mhz + // we want a master clock (MCK) to be PLL clock / 2 = 96MHz / 2 = 48MHz // datasheet recommends that this register is programmed in two operations // when changing to PLL, program the prescaler first then the source AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_PRES_CLK_2; diff --git a/client/cmddata.c b/client/cmddata.c index 473c5f0b9..3887c6cb8 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -1611,7 +1611,7 @@ int CmdTuneSamples(const char *Cmd) { } if (test1 > 0) { - PrintAndLogEx(SUCCESS, "\nDisplaying LF tuning graph. Divisor 89 is 134khz, 95 is 125khz.\n\n"); + PrintAndLogEx(SUCCESS, "\nDisplaying LF tuning graph. Divisor 89 is 134kHz, 95 is 125kHz.\n\n"); GraphTraceLen = 256; ShowGraphWindow(); RepaintGraphWindow(); diff --git a/client/cmdflashmem.c b/client/cmdflashmem.c index cfe122c50..c639ab107 100644 --- a/client/cmdflashmem.c +++ b/client/cmdflashmem.c @@ -29,9 +29,9 @@ static int usage_flashmem_spibaud(void) { PrintAndLogEx(NORMAL, " h this help"); PrintAndLogEx(NORMAL, " SPI baudrate in MHz [24|48]"); PrintAndLogEx(NORMAL, " "); - PrintAndLogEx(NORMAL, " If >= 24Mhz, FASTREADS instead of READS instruction will be used."); - PrintAndLogEx(NORMAL, " Reading Flash ID will virtually always fail under 48Mhz setting"); - PrintAndLogEx(NORMAL, " Unless you know what you are doing, please stay at 24Mhz"); + PrintAndLogEx(NORMAL, " If >= 24MHz, FASTREADS instead of READS instruction will be used."); + PrintAndLogEx(NORMAL, " Reading Flash ID will virtually always fail under 48MHz setting"); + PrintAndLogEx(NORMAL, " Unless you know what you are doing, please stay at 24MHz"); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " mem spibaud 48"); return PM3_SUCCESS; diff --git a/client/cmdhw.c b/client/cmdhw.c index 7ab33cadf..0bfa583dc 100644 --- a/client/cmdhw.c +++ b/client/cmdhw.c @@ -449,7 +449,7 @@ static int CmdSetDivisor(const char *Cmd) { PrintAndLogEx(ERR, "divisor must be between 19 and 255"); return PM3_EINVARG; } - // 12 000 000 (12Mhz) + // 12 000 000 (12MHz) clearCommandBuffer(); SendCommandNG(CMD_LF_SET_DIVISOR, (uint8_t *)&arg, sizeof(arg)); PrintAndLogEx(SUCCESS, "Divisor set, expected %.1f kHz", ((double)12000 / (arg + 1))); @@ -596,7 +596,7 @@ static command_t CommandTable[] = { {"ping", CmdPing, IfPm3Present, "Test if the Proxmark3 is responsive"}, {"readmem", CmdReadmem, IfPm3Present, "[address] -- Read memory at decimal address from flash"}, {"reset", CmdReset, IfPm3Present, "Reset the Proxmark3"}, - {"setlfdivisor", CmdSetDivisor, IfPm3Present, "<19 - 255> -- Drive LF antenna at 12Mhz/(divisor+1)"}, + {"setlfdivisor", CmdSetDivisor, IfPm3Present, "<19 - 255> -- Drive LF antenna at 12MHz/(divisor+1)"}, {"setmux", CmdSetMux, IfPm3Present, "Set the ADC mux to a specific value"}, {"standalone", CmdStandalone, IfPm3Present, "Jump to the standalone mode"}, {"status", CmdStatus, IfPm3Present, "Show runtime status information about the connected Proxmark3"}, diff --git a/client/cmdsmartcard.c b/client/cmdsmartcard.c index c2268fd2f..5147dbd7e 100644 --- a/client/cmdsmartcard.c +++ b/client/cmdsmartcard.c @@ -61,7 +61,7 @@ static int usage_sm_upgrade(void) { static int usage_sm_setclock(void) { PrintAndLogEx(NORMAL, "Usage: sc setclock [h] c "); PrintAndLogEx(NORMAL, " h : this help"); - PrintAndLogEx(NORMAL, " c <> : clockspeed (0 = 16mhz, 1=8mhz, 2=4mhz) "); + PrintAndLogEx(NORMAL, " c <> : clockspeed (0 = 16MHz, 1=8MHz, 2=4MHz) "); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " sc setclock c 2"); @@ -843,13 +843,13 @@ static int CmdSmartSetClock(const char *Cmd) { switch (clock1) { case 0: - PrintAndLogEx(SUCCESS, "Clock changed to 16mhz giving 10800 baudrate"); + PrintAndLogEx(SUCCESS, "Clock changed to 16MHz giving 10800 baudrate"); break; case 1: - PrintAndLogEx(SUCCESS, "Clock changed to 8mhz giving 21600 baudrate"); + PrintAndLogEx(SUCCESS, "Clock changed to 8MHz giving 21600 baudrate"); break; case 2: - PrintAndLogEx(SUCCESS, "Clock changed to 4mhz giving 86400 baudrate"); + PrintAndLogEx(SUCCESS, "Clock changed to 4MHz giving 86400 baudrate"); break; default: break; diff --git a/client/cmdtrace.c b/client/cmdtrace.c index d7d62d0b0..0dd125c20 100644 --- a/client/cmdtrace.c +++ b/client/cmdtrace.c @@ -804,9 +804,9 @@ int CmdTraceList(const char *Cmd) { } else { PrintAndLogEx(NORMAL, "Start = Start of Start Bit, End = End of last modulation. Src = Source of Transfer"); if (protocol == ISO_14443A || protocol == PROTO_MIFARE || protocol == MFDES || protocol == TOPAZ) - PrintAndLogEx(NORMAL, "ISO14443A - All times are in carrier periods (1/13.56Mhz)"); + PrintAndLogEx(NORMAL, "ISO14443A - All times are in carrier periods (1/13.56MHz)"); if (protocol == THINFILM) - PrintAndLogEx(NORMAL, "Thinfilm - All times are in carrier periods (1/13.56Mhz)"); + PrintAndLogEx(NORMAL, "Thinfilm - All times are in carrier periods (1/13.56MHz)"); if (protocol == ICLASS) PrintAndLogEx(NORMAL, "iClass - Timings are not as accurate"); if (protocol == LEGIC) diff --git a/common/i2c.c b/common/i2c.c index d51cba4a3..62bd2bc56 100644 --- a/common/i2c.c +++ b/common/i2c.c @@ -26,7 +26,7 @@ volatile unsigned long c; -// Direct use the loop to delay. 6 instructions loop, Masterclock 48Mhz, +// Direct use the loop to delay. 6 instructions loop, Masterclock 48MHz, // delay=1 is about 200kbps // timer. // I2CSpinDelayClk(4) = 12.31us @@ -41,7 +41,7 @@ void __attribute__((optimize("O0"))) I2CSpinDelayClk(uint16_t delay) { #define ISO7618_MAX_FRAME 255 -// try i2c bus recovery at 100kHz = 5uS high, 5uS low +// try i2c bus recovery at 100kHz = 5us high, 5us low void I2C_recovery(void) { DbpString("Performing i2c bus recovery"); diff --git a/common/iso15693tools.h b/common/iso15693tools.h index 26a7a87a7..e59f6ca39 100644 --- a/common/iso15693tools.h +++ b/common/iso15693tools.h @@ -82,8 +82,8 @@ char *Iso15693sprintUID(char *target, uint8_t *uid); // SOF defined as // 1) Unmodulated time of 56.64us -// 2) 24 pulses of 423.75khz -// 3) logic '1' (unmodulated for 18.88us followed by 8 pulses of 423.75khz) +// 2) 24 pulses of 423.75kHz +// 3) logic '1' (unmodulated for 18.88us followed by 8 pulses of 423.75kHz) static const int Iso15693FrameSOF[] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, @@ -109,8 +109,8 @@ static const int Iso15693Logic1[] = { }; // EOF defined as -// 1) logic '0' (8 pulses of 423.75khz followed by unmodulated for 18.88us) -// 2) 24 pulses of 423.75khz +// 1) logic '0' (8 pulses of 423.75kHz followed by unmodulated for 18.88us) +// 2) 24 pulses of 423.75kHz // 3) Unmodulated time of 56.64us static const int Iso15693FrameEOF[] = { 1, 1, 1, 1, diff --git a/common/usb_cdc.c b/common/usb_cdc.c index 7f8deb62d..5768a99ab 100644 --- a/common/usb_cdc.c +++ b/common/usb_cdc.c @@ -446,8 +446,8 @@ AT91S_CDC_LINE_CODING line = { // purely informative, actual values don't matter 8 // 8 Data bits }; -// timer counts in 21.3uS increments (1024/48Mhz), rounding applies -// WARNING: timer can't measure more than 1.39s (21.3uS * 0xffff) +// timer counts in 21.3us increments (1024/48MHz), rounding applies +// WARNING: timer can't measure more than 1.39s (21.3us * 0xffff) static void SpinDelay(int ms) { int us = ms * 1000; int ticks = ((MCK / 1000000) * us + 512) >> 10; diff --git a/fpga/hi_simulate.v b/fpga/hi_simulate.v index 0de34a1fd..d336a5ddf 100644 --- a/fpga/hi_simulate.v +++ b/fpga/hi_simulate.v @@ -69,7 +69,7 @@ begin // Get next bit at 212kHz ssp_clk <= ssp_clk_divider[5]; else - // Get next bit at 424Khz + // Get next bit at 424kHz ssp_clk <= ssp_clk_divider[4]; end diff --git a/fpga/lf_edge_detect.v b/fpga/lf_edge_detect.v index fee262e28..d086f95fc 100644 --- a/fpga/lf_edge_detect.v +++ b/fpga/lf_edge_detect.v @@ -5,7 +5,7 @@ // at your option, any later version. See the LICENSE.txt file for the text of // the license. //----------------------------------------------------------------------------- -// input clk is 24Mhz +// input clk is 24MHz `include "min_max_tracker.v" module lf_edge_detect(input clk, input [7:0] adc_d, input [7:0] lf_ed_threshold, diff --git a/fpga/lo_adc.v b/fpga/lo_adc.v index f97090628..dff9fda3f 100644 --- a/fpga/lo_adc.v +++ b/fpga/lo_adc.v @@ -48,7 +48,7 @@ assign dbg = adc_clk; assign adc_clk = ~clk_state; // serialized SSP data is gated by clk_state to suppress unwanted signal assign ssp_din = to_arm_shiftreg[7] && !clk_state; -// SSP clock always runs at 24Mhz +// SSP clock always runs at 24MHz assign ssp_clk = pck0; // SSP frame is gated by clk_state and goes high when pck_divider=8..15 assign ssp_frame = (pck_divider[7:3] == 5'd1) && !clk_state; diff --git a/fpga/lo_read.v b/fpga/lo_read.v index c24a521a6..8f778309b 100644 --- a/fpga/lo_read.v +++ b/fpga/lo_read.v @@ -19,7 +19,7 @@ module lo_read( reg [7:0] to_arm_shiftreg; -// this task also runs at pck0 frequency (24Mhz) and is used to serialize +// this task also runs at pck0 frequency (24MHz) and is used to serialize // the ADC output which is then clocked into the ARM SSP. // because pck_divclk always transitions when pck_cnt = 0 we use the @@ -55,7 +55,7 @@ end // serialized SSP data is gated by ant_lo to suppress unwanted signal assign ssp_din = to_arm_shiftreg[7] && !pck_divclk; -// SSP clock always runs at 24Mhz +// SSP clock always runs at 24MHz assign ssp_clk = pck0; // SSP frame is gated by ant_lo and goes high when pck_divider=8..15 assign ssp_frame = (pck_cnt[7:3] == 5'd1) && !pck_divclk; diff --git a/fpga/lp20khz_1MSa_iir_filter.v b/fpga/lp20khz_1MSa_iir_filter.v index 198f38022..2dbfd6945 100644 --- a/fpga/lp20khz_1MSa_iir_filter.v +++ b/fpga/lp20khz_1MSa_iir_filter.v @@ -28,7 +28,7 @@ // https://fail0verflow.com/blog/2014/proxmark3-fpga-iir-filter.html module lp20khz_1MSa_iir_filter(input clk, input [7:0] adc_d, output rdy, output [7:0] out); - // clk is 24Mhz, the IIR filter is designed for 1MS/s + // clk is 24MHz, the IIR filter is designed for 1MS/s // hence we need to divide it by 24 // using a shift register takes less area than a counter reg [23:0] cnt = 1; diff --git a/fpga/testbed_hi_read_tx.v b/fpga/testbed_hi_read_tx.v index 050e6b1e4..ee28a0a61 100644 --- a/fpga/testbed_hi_read_tx.v +++ b/fpga/testbed_hi_read_tx.v @@ -1,7 +1,7 @@ `include "hi_read_tx.v" /* - pck0 - input main 24Mhz clock (PLL / 4) + pck0 - input main 24MHz clock (PLL / 4) [7:0] adc_d - input data from A/D converter shallow_modulation - modulation type diff --git a/fpga/testbed_hi_simulate.v b/fpga/testbed_hi_simulate.v index 541737202..2a2e2f799 100644 --- a/fpga/testbed_hi_simulate.v +++ b/fpga/testbed_hi_simulate.v @@ -1,7 +1,7 @@ `include "hi_simulate.v" /* - pck0 - input main 24Mhz clock (PLL / 4) + pck0 - input main 24MHz clock (PLL / 4) [7:0] adc_d - input data from A/D converter mod_type - modulation type diff --git a/fpga/testbed_lo_read.v b/fpga/testbed_lo_read.v index 78ca1e3bb..0536a403f 100644 --- a/fpga/testbed_lo_read.v +++ b/fpga/testbed_lo_read.v @@ -1,14 +1,14 @@ `include "lo_read.v" /* - pck0 - input main 24Mhz clock (PLL / 4) + pck0 - input main 24MHz clock (PLL / 4) [7:0] adc_d - input data from A/D converter - lo_is_125khz - input freq selector (1=125Khz, 0=136Khz) + lo_is_125khz - input freq selector (1=125kHz, 0=136kHz) pwr_lo - output to coil drivers (ssp_clk / 8) adc_clk - output A/D clock signal ssp_frame - output SSS frame indicator (goes high while the 8 bits are shifted) ssp_din - output SSP data to ARM (shifts 8 bit A/D value serially to ARM MSB first) - ssp_clk - output SSP clock signal 1Mhz/1.09Mhz (pck0 / 2*(11+lo_is_125khz) ) + ssp_clk - output SSP clock signal 1MHz/1.09MHz (pck0 / 2*(11+lo_is_125khz) ) ck_1356meg - input unused ck_1356megb - input unused @@ -90,9 +90,9 @@ module testbed_lo_read; adc_d = 0; ssp_dout = 0; lo_is_125khz = 1; - divisor = 255; //min 16, 95=125Khz, max 255 + divisor = 255; //min 16, 95=125kHz, max 255 - // simulate 4 A/D cycles at 125Khz + // simulate 4 A/D cycles at 125kHz for (i = 0 ; i < 8 ; i = i + 1) begin crank_dut; end diff --git a/fpga/testbed_lo_simulate.v b/fpga/testbed_lo_simulate.v index e056202ad..ec4bb73fe 100644 --- a/fpga/testbed_lo_simulate.v +++ b/fpga/testbed_lo_simulate.v @@ -1,7 +1,7 @@ `include "lo_simulate.v" /* - pck0 - input main 24Mhz clock (PLL / 4) + pck0 - input main 24MHz clock (PLL / 4) [7:0] adc_d - input data from A/D converter @@ -74,7 +74,7 @@ module testbed_lo_simulate; // main clock always #5 pck0 = !pck0; - //cross_lo is not really synced to pck0 but it's roughly pck0/192 (24Mhz/192=125Khz) + //cross_lo is not really synced to pck0 but it's roughly pck0/192 (24MHz/192=125kHz) task crank_dut; begin @(posedge pck0) ; From 0f9880b18f0322974797ec72f4d4a4d72c9d820f Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 6 Aug 2019 13:52:03 +0200 Subject: [PATCH 0269/1854] cleaning --- armsrc/ticks.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/ticks.c b/armsrc/ticks.c index b19c3b510..1a8d2f8a7 100644 --- a/armsrc/ticks.c +++ b/armsrc/ticks.c @@ -67,7 +67,7 @@ void StartTickCount(void) { * Get the current count. */ uint32_t RAMFUNC GetTickCount(void) { - return AT91C_BASE_RTTC->RTTC_RTVR;// was * 2; + return AT91C_BASE_RTTC->RTTC_RTVR; } uint32_t RAMFUNC GetTickCountDelta(uint32_t start_ticks) { From 67887a83d3e7966df2bad7f096e42ed7d04be239 Mon Sep 17 00:00:00 2001 From: Victor Date: Mon, 5 Aug 2019 19:16:57 +0100 Subject: [PATCH 0270/1854] Rework hitag2 read/write help --- client/cmdlfhitag.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/client/cmdlfhitag.c b/client/cmdlfhitag.c index 74664e2b8..b9b989966 100644 --- a/client/cmdlfhitag.c +++ b/client/cmdlfhitag.c @@ -84,13 +84,13 @@ static int usage_hitag_reader(void) { PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h This help"); PrintAndLogEx(NORMAL, " HitagS (0*)"); - PrintAndLogEx(NORMAL, " 01 Challenge, read all pages from a Hitag S tag"); - PrintAndLogEx(NORMAL, " 02 Set to 0 if no authentication is needed. Read all pages from a Hitag S tag"); + PrintAndLogEx(NORMAL, " 01 Read all pages, challenge mode"); + PrintAndLogEx(NORMAL, " 02 Read all pages, crypto mode. Set key=0 for no auth"); PrintAndLogEx(NORMAL, " Hitag1 (1*)"); PrintAndLogEx(NORMAL, " Hitag2 (2*)"); - PrintAndLogEx(NORMAL, " 21 Password mode"); - PrintAndLogEx(NORMAL, " 22 Authentication"); - PrintAndLogEx(NORMAL, " 23 Authentication, key is in format: ISK high + ISK low"); + PrintAndLogEx(NORMAL, " 21 Read all pages, password mode. Default: 4D494B52 (\"MIKR\")"); + PrintAndLogEx(NORMAL, " 22 Read all pages, challenge mode"); + PrintAndLogEx(NORMAL, " 23 Read all pages, crypto mode. Key format: ISK high + ISK low. Default: 4F4E4D494B52 (\"ONMIKR\")"); PrintAndLogEx(NORMAL, " 25 Test recorded authentications"); PrintAndLogEx(NORMAL, " 26 Just read UID"); return 0; @@ -99,14 +99,15 @@ static int usage_hitag_writer(void) { PrintAndLogEx(NORMAL, "Hitag writer functions"); PrintAndLogEx(NORMAL, "Usage: lf hitag write [h] "); PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " h This help"); + PrintAndLogEx(NORMAL, " h This help"); PrintAndLogEx(NORMAL, " HitagS (0*)"); - PrintAndLogEx(NORMAL, " 03 (Challenge) write page on a Hitag S tag"); - PrintAndLogEx(NORMAL, " 04 (set to 0 if no authentication is needed) write page on a Hitag S tag"); + PrintAndLogEx(NORMAL, " 03 Write page, challenge mode"); + PrintAndLogEx(NORMAL, " 04 Write page, crypto mode. Set key=0 for no auth"); PrintAndLogEx(NORMAL, " Hitag1 (1*)"); PrintAndLogEx(NORMAL, " Hitag2 (2*)"); - PrintAndLogEx(NORMAL, " 24 (set to 0 if no authentication is needed) write page on a Hitag2 tag"); - PrintAndLogEx(NORMAL, " 27 write page on a Hitag2 tag"); + PrintAndLogEx(NORMAL, " 24 Write page, crypto mode. Key format: ISK high + ISK low."); + PrintAndLogEx(NORMAL, " Default: 4F4E4D494B52 (\"ONMIKR\"). Set key=0 for no auth"); + PrintAndLogEx(NORMAL, " 27 Write page, password mode. Default: 4D494B52 (\"MIKR\")"); return 0; } static int usage_hitag_checkchallenges(void) { From f913f7156a2085007e9c38fbec5e09875fb07583 Mon Sep 17 00:00:00 2001 From: Victor Date: Mon, 5 Aug 2019 19:25:51 +0100 Subject: [PATCH 0271/1854] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 32d7da93c..90f193bd7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Rework hitag2 read/write help (@ViRb3) - Add 'lf nedap' - encoding / decoding (anon) - Add client option `-i` to stay in interactive mode after a script or command (@DidierStevens/@doegox) - Add VSCode tasks (@ViRb3) From d158ffebfde96489b9805bd06b8a89b6469a7108 Mon Sep 17 00:00:00 2001 From: Victor Date: Tue, 6 Aug 2019 19:13:38 +0100 Subject: [PATCH 0272/1854] Note that hitag1 read/write not yet implemented --- client/cmdlfhitag.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/cmdlfhitag.c b/client/cmdlfhitag.c index b9b989966..a1fb3415b 100644 --- a/client/cmdlfhitag.c +++ b/client/cmdlfhitag.c @@ -87,6 +87,7 @@ static int usage_hitag_reader(void) { PrintAndLogEx(NORMAL, " 01 Read all pages, challenge mode"); PrintAndLogEx(NORMAL, " 02 Read all pages, crypto mode. Set key=0 for no auth"); PrintAndLogEx(NORMAL, " Hitag1 (1*)"); + PrintAndLogEx(NORMAL, " Not implemented"); PrintAndLogEx(NORMAL, " Hitag2 (2*)"); PrintAndLogEx(NORMAL, " 21 Read all pages, password mode. Default: 4D494B52 (\"MIKR\")"); PrintAndLogEx(NORMAL, " 22 Read all pages, challenge mode"); @@ -104,6 +105,7 @@ static int usage_hitag_writer(void) { PrintAndLogEx(NORMAL, " 03 Write page, challenge mode"); PrintAndLogEx(NORMAL, " 04 Write page, crypto mode. Set key=0 for no auth"); PrintAndLogEx(NORMAL, " Hitag1 (1*)"); + PrintAndLogEx(NORMAL, " Not implemented"); PrintAndLogEx(NORMAL, " Hitag2 (2*)"); PrintAndLogEx(NORMAL, " 24 Write page, crypto mode. Key format: ISK high + ISK low."); PrintAndLogEx(NORMAL, " Default: 4F4E4D494B52 (\"ONMIKR\"). Set key=0 for no auth"); From 650dd5855fb4a3078530a8a75e9129a0a041ebaa Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 6 Aug 2019 23:10:02 +0200 Subject: [PATCH 0273/1854] ok it seems PMW CNTR is not reset as promised in the datasheet, let's fix this for now... --- armsrc/ticks.c | 2 +- armsrc/util.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/armsrc/ticks.c b/armsrc/ticks.c index 1a8d2f8a7..1a726975f 100644 --- a/armsrc/ticks.c +++ b/armsrc/ticks.c @@ -28,7 +28,7 @@ void SpinDelayUs(int us) { for (;;) { uint16_t now = AT91C_BASE_PWMC_CH0->PWMC_CCNTR; - if (now >= (uint16_t)(start + ticks)) + if (now == (uint16_t)(start + ticks)) return; WDT_HIT(); diff --git a/armsrc/util.c b/armsrc/util.c index a5245e356..2fe449942 100644 --- a/armsrc/util.c +++ b/armsrc/util.c @@ -216,7 +216,7 @@ int BUTTON_CLICKED(int ms) { // Still haven't let it off else // Have we held down a full second? - if (now >= (uint16_t)(start + ticks)) + if (now == (uint16_t)(start + ticks)) return BUTTON_HOLD; } @@ -227,7 +227,7 @@ int BUTTON_CLICKED(int ms) { return BUTTON_DOUBLE_CLICK; // Have we ran out of time to double click? - else if (now >= (uint16_t)(start + ticks)) + else if (now == (uint16_t)(start + ticks)) // At least we did a single click return BUTTON_SINGLE_CLICK; @@ -271,7 +271,7 @@ int BUTTON_HELD(int ms) { return BUTTON_SINGLE_CLICK; // Have we waited the full second? - else if (now >= (uint16_t)(start + ticks)) + else if (now == (uint16_t)(start + ticks)) return BUTTON_HOLD; WDT_HIT(); From 9f8e63a7c84aa8cc5ef6c953bc40fa6f78d39432 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 6 Aug 2019 23:19:59 +0200 Subject: [PATCH 0274/1854] print errors only if dbg level allows errors --- armsrc/ticks.c | 2 +- armsrc/util.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/armsrc/ticks.c b/armsrc/ticks.c index 1a726975f..18bca7f5a 100644 --- a/armsrc/ticks.c +++ b/armsrc/ticks.c @@ -38,7 +38,7 @@ void SpinDelayUs(int us) { // WARNING: timer can't measure more than 1.39s (21.3us * 0xffff) void SpinDelay(int ms) { if (ms > 1390) { - Dbprintf(_RED_("Error, SpinDelay called with %i > 1390"), ms); + if (DBGLEVEL >= DBG_ERROR) Dbprintf(_RED_("Error, SpinDelay called with %i > 1390"), ms); ms = 1390; } // convert to us and call microsecond delay function diff --git a/armsrc/util.c b/armsrc/util.c index 2fe449942..cb8668783 100644 --- a/armsrc/util.c +++ b/armsrc/util.c @@ -179,7 +179,7 @@ int BUTTON_CLICKED(int ms) { // timer counts in 21.3us increments (1024/48MHz) // WARNING: timer can't measure more than 1.39s (21.3us * 0xffff) if (ms > 1390) { - Dbprintf(_RED_("Error, BUTTON_CLICKED called with %i > 1390"), ms); + if (DBGLEVEL >= DBG_ERROR) Dbprintf(_RED_("Error, BUTTON_CLICKED called with %i > 1390"), ms); ms = 1390; } int ticks = ((MCK / 1000) * (ms ? ms : 1000)) >> 10; @@ -243,7 +243,7 @@ int BUTTON_HELD(int ms) { // timer counts in 21.3us increments (1024/48MHz) // WARNING: timer can't measure more than 1.39s (21.3us * 0xffff) if (ms > 1390) { - Dbprintf(_RED_("Error, BUTTON_HELD called with %i > 1390"), ms); + if (DBGLEVEL >= DBG_ERROR) Dbprintf(_RED_("Error, BUTTON_HELD called with %i > 1390"), ms); ms = 1390; } // If button is held for one second From 80941ed9e1ced3db09dadf6b9ea805542d7c5855 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 7 Aug 2019 00:02:00 +0200 Subject: [PATCH 0275/1854] Remove comments --- armsrc/ticks.c | 1 - armsrc/util.c | 2 -- 2 files changed, 3 deletions(-) diff --git a/armsrc/ticks.c b/armsrc/ticks.c index 18bca7f5a..610afb5a2 100644 --- a/armsrc/ticks.c +++ b/armsrc/ticks.c @@ -16,7 +16,6 @@ void SpinDelayUs(int us) { int ticks = ((MCK / 1000000) * us + 512) >> 10; // Borrow a PWM unit for my real-time clock - // This resets PWMC_CPRDR as well AT91C_BASE_PWMC->PWMC_ENA = PWM_CHANNEL(0); // 48 MHz / 1024 gives 46.875 kHz diff --git a/armsrc/util.c b/armsrc/util.c index cb8668783..a691766d0 100644 --- a/armsrc/util.c +++ b/armsrc/util.c @@ -189,7 +189,6 @@ int BUTTON_CLICKED(int ms) { return BUTTON_NO_CLICK; // Borrow a PWM unit for my real-time clock - // This resets PWMC_CPRDR as well AT91C_BASE_PWMC->PWMC_ENA = PWM_CHANNEL(0); // 48 MHz / 1024 gives 46.875 kHz AT91C_BASE_PWMC_CH0->PWMC_CMR = PWM_CH_MODE_PRESCALER(10); @@ -254,7 +253,6 @@ int BUTTON_HELD(int ms) { return BUTTON_NO_CLICK; // Borrow a PWM unit for my real-time clock - // This resets PWMC_CPRDR as well AT91C_BASE_PWMC->PWMC_ENA = PWM_CHANNEL(0); // 48 MHz / 1024 gives 46.875 kHz AT91C_BASE_PWMC_CH0->PWMC_CMR = PWM_CH_MODE_PRESCALER(10); From 46153548640f036e0fae6fbfaaf9c703a5bf5103 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 7 Aug 2019 00:47:32 +0200 Subject: [PATCH 0276/1854] mf sim: respect DBG_NONE and explicit ATQA/SAK usage --- armsrc/mifaresim.c | 17 ++++++++++------- client/cmdhfmf.c | 5 +++-- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/armsrc/mifaresim.c b/armsrc/mifaresim.c index 2e8203aa5..8eb4ba973 100644 --- a/armsrc/mifaresim.c +++ b/armsrc/mifaresim.c @@ -250,21 +250,21 @@ static bool MifareSimInit(uint16_t flags, uint8_t *datain, tag_response_info_t * if ((flags & FLAG_MF_MINI) == FLAG_MF_MINI) { memcpy(rATQA, rATQA_Mini, sizeof(rATQA)); rSAK[0] = rSAK_Mini; - Dbprintf("Mifare Mini"); + if (DBGLEVEL > DBG_NONE) Dbprintf("Enforcing Mifare Mini ATQA/SAK"); } else if ((flags & FLAG_MF_1K) == FLAG_MF_1K) { memcpy(rATQA, rATQA_1k, sizeof(rATQA)); rSAK[0] = rSAK_1k; - Dbprintf("Mifare 1K"); + if (DBGLEVEL > DBG_NONE) Dbprintf("Enforcing Mifare 1K ATQA/SAK"); } else if ((flags & FLAG_MF_2K) == FLAG_MF_2K) { memcpy(rATQA, rATQA_2k, sizeof(rATQA)); rSAK[0] = rSAK_2k; *rats = rRATS; *rats_len = sizeof(rRATS); - Dbprintf("Mifare 2K with RATS support"); + if (DBGLEVEL > DBG_NONE) Dbprintf("Enforcing Mifare 2K ATQA/SAK with RATS support"); } else if ((flags & FLAG_MF_4K) == FLAG_MF_4K) { memcpy(rATQA, rATQA_4k, sizeof(rATQA)); rSAK[0] = rSAK_4k; - Dbprintf("Mifare 4K"); + if (DBGLEVEL > DBG_NONE) Dbprintf("Enforcing Mifare 4K ATQA/SAK"); } // Prepare UID arrays @@ -279,7 +279,7 @@ static bool MifareSimInit(uint16_t flags, uint8_t *datain, tag_response_info_t * *cuid = bytes_to_num(rUIDBCC1, 4); // BCC rUIDBCC1[4] = rUIDBCC1[0] ^ rUIDBCC1[1] ^ rUIDBCC1[2] ^ rUIDBCC1[3]; - if (DBGLEVEL >= DBG_NONE) { + if (DBGLEVEL > DBG_NONE) { Dbprintf("4B UID: %02x%02x%02x%02x", rUIDBCC1[0], rUIDBCC1[1], rUIDBCC1[2], rUIDBCC1[3]); } @@ -300,7 +300,7 @@ static bool MifareSimInit(uint16_t flags, uint8_t *datain, tag_response_info_t * // BCC rUIDBCC1[4] = rUIDBCC1[0] ^ rUIDBCC1[1] ^ rUIDBCC1[2] ^ rUIDBCC1[3]; rUIDBCC2[4] = rUIDBCC2[0] ^ rUIDBCC2[1] ^ rUIDBCC2[2] ^ rUIDBCC2[3]; - if (DBGLEVEL >= DBG_NONE) { + if (DBGLEVEL > DBG_NONE) { Dbprintf("7B UID: %02x %02x %02x %02x %02x %02x %02x", rUIDBCC1[1], rUIDBCC1[2], rUIDBCC1[3], rUIDBCC2[0], rUIDBCC2[1], rUIDBCC2[2], rUIDBCC2[3]); } @@ -326,7 +326,7 @@ static bool MifareSimInit(uint16_t flags, uint8_t *datain, tag_response_info_t * rUIDBCC2[4] = rUIDBCC2[0] ^ rUIDBCC2[1] ^ rUIDBCC2[2] ^ rUIDBCC2[3]; rUIDBCC3[4] = rUIDBCC3[0] ^ rUIDBCC3[1] ^ rUIDBCC3[2] ^ rUIDBCC3[3]; - if (DBGLEVEL >= DBG_NONE) { + if (DBGLEVEL > DBG_NONE) { Dbprintf("10B UID: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", rUIDBCC1[1], rUIDBCC1[2], rUIDBCC1[3], rUIDBCC2[1], rUIDBCC2[2], rUIDBCC2[3], @@ -340,6 +340,9 @@ static bool MifareSimInit(uint16_t flags, uint8_t *datain, tag_response_info_t * Dbprintf("[-] ERROR: UID size not defined"); return false; } + if (DBGLEVEL > DBG_NONE) { + Dbprintf("ATQA = %02X %02X and SAK = %02X)", rATQA[1], rATQA[0], rSAK[0]); + } // clone UIDs for byte-frame anti-collision multiple tag selection procedure memcpy(rUIDBCC1b4, &rUIDBCC1[1], 4); diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index c3e36e33f..0fa28d5a9 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -68,8 +68,9 @@ static int usage_hf14_mfsim(void) { PrintAndLogEx(NORMAL, "Usage: hf mf sim [h] u n [i] [x] [e] [v]"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h this help"); - PrintAndLogEx(NORMAL, " u (Optional) UID 4,7 or 10bytes. If not specified, the UID 4b from emulator memory will be used"); - PrintAndLogEx(NORMAL, " t (Optional) 0 = MIFARE Mini"); + PrintAndLogEx(NORMAL, " u (Optional) UID 4,7 or 10bytes. If not specified, the UID 4b/7b from emulator memory will be used"); + PrintAndLogEx(NORMAL, " t (Optional) Enforce ATQA/SAK:"); + PrintAndLogEx(NORMAL, " 0 = MIFARE Mini"); PrintAndLogEx(NORMAL, " 1 = MIFARE Classic 1k (Default)"); PrintAndLogEx(NORMAL, " 2 = MIFARE Classic 2k plus in SL0 mode"); PrintAndLogEx(NORMAL, " 4 = MIFARE Classic 4k"); From 12a0540d91e621a4b0139e36eecf77ea826480f1 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 7 Aug 2019 01:32:37 +0200 Subject: [PATCH 0277/1854] mf sim: add option to pass explicitly atqa/sak and reject explicitly unknown vals for option t --- armsrc/appmain.c | 4 +++- armsrc/mifaresim.c | 16 ++++++++++++---- armsrc/mifaresim.h | 2 +- client/cmdhfmf.c | 39 ++++++++++++++++++++++++++++++++++++--- include/pm3_cmd.h | 2 ++ 5 files changed, 54 insertions(+), 9 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 2529dc198..98605e481 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1192,9 +1192,11 @@ static void PacketReceived(PacketCommandNG *packet) { uint16_t flags; uint8_t exitAfter; uint8_t uid[10]; + uint16_t atqa; + uint8_t sak; } PACKED; struct p *payload = (struct p *) packet->data.asBytes; - Mifare1ksim(payload->flags, payload->exitAfter, payload->uid); + Mifare1ksim(payload->flags, payload->exitAfter, payload->uid, payload->atqa, payload->sak); break; } // emulator diff --git a/armsrc/mifaresim.c b/armsrc/mifaresim.c index 8eb4ba973..5eadef0ea 100644 --- a/armsrc/mifaresim.c +++ b/armsrc/mifaresim.c @@ -163,7 +163,7 @@ static bool IsAccessAllowed(uint8_t blockNo, uint8_t keytype, uint8_t action) { } } -static bool MifareSimInit(uint16_t flags, uint8_t *datain, tag_response_info_t **responses, uint32_t *cuid, uint8_t *uid_len, uint8_t **rats, uint8_t *rats_len) { +static bool MifareSimInit(uint16_t flags, uint8_t *datain, uint16_t atqa, uint8_t sak, tag_response_info_t **responses, uint32_t *cuid, uint8_t *uid_len, uint8_t **rats, uint8_t *rats_len) { // SPEC: https://www.nxp.com/docs/en/application-note/AN10833.pdf // ATQA @@ -340,8 +340,16 @@ static bool MifareSimInit(uint16_t flags, uint8_t *datain, tag_response_info_t * Dbprintf("[-] ERROR: UID size not defined"); return false; } + if (flags & FLAG_FORCED_ATQA) { + rATQA[0] = atqa >> 8; + rATQA[1] = atqa & 0xff; + } + if (flags & FLAG_FORCED_SAK) { + rSAK[0] = sak; + } if (DBGLEVEL > DBG_NONE) { - Dbprintf("ATQA = %02X %02X and SAK = %02X)", rATQA[1], rATQA[0], rSAK[0]); + Dbprintf("ATQA : %02X %02X", rATQA[1], rATQA[0]); + Dbprintf("SAK : %02X", rSAK[0]); } // clone UIDs for byte-frame anti-collision multiple tag selection procedure @@ -435,7 +443,7 @@ static bool MifareSimInit(uint16_t flags, uint8_t *datain, tag_response_info_t * *@param exitAfterNReads, exit simulation after n blocks have been read, 0 is infinite ... * (unless reader attack mode enabled then it runs util it gets enough nonces to recover all keys attmpted) */ -void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain) { +void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint16_t atqa, uint8_t sak) { tag_response_info_t *responses; uint8_t cardSTATE = MFEMUL_NOFIELD; uint8_t uid_len = 0; // 4,7, 10 @@ -503,7 +511,7 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain) { // free eventually allocated BigBuf memory but keep Emulator Memory BigBuf_free_keep_EM(); - if (MifareSimInit(flags, datain, &responses, &cuid, &uid_len, &rats, &rats_len) == false) { + if (MifareSimInit(flags, datain, atqa, sak, &responses, &cuid, &uid_len, &rats, &rats_len) == false) { BigBuf_free_keep_EM(); return; } diff --git a/armsrc/mifaresim.h b/armsrc/mifaresim.h index d05b730c9..a161d2974 100644 --- a/armsrc/mifaresim.h +++ b/armsrc/mifaresim.h @@ -19,7 +19,7 @@ # define CheckCrc14A(data, len) check_crc(CRC_14443_A, (data), (len)) #endif -void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain); +void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint16_t atqa, uint8_t sak); #define AC_DATA_READ 0 #define AC_DATA_WRITE 1 diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 0fa28d5a9..16b6b9d49 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -74,6 +74,8 @@ static int usage_hf14_mfsim(void) { PrintAndLogEx(NORMAL, " 1 = MIFARE Classic 1k (Default)"); PrintAndLogEx(NORMAL, " 2 = MIFARE Classic 2k plus in SL0 mode"); PrintAndLogEx(NORMAL, " 4 = MIFARE Classic 4k"); + PrintAndLogEx(NORMAL, " a (Optional) Provide explicitly ATQA (2 bytes, override option t)"); + PrintAndLogEx(NORMAL, " s (Optional) Provide explicitly SAK (1 byte, override option t)"); PrintAndLogEx(NORMAL, " n (Optional) Automatically exit simulation after blocks have been read by reader. 0 = infinite"); PrintAndLogEx(NORMAL, " i (Optional) Interactive, means that console will not be returned until simulation finishes or is aborted"); PrintAndLogEx(NORMAL, " x (Optional) Crack, performs the 'reader attack', nr/ar attack against a reader"); @@ -2164,6 +2166,10 @@ void readerAttack(nonces_t data, bool setEmulatorMem, bool verbose) { static int CmdHF14AMfSim(const char *Cmd) { uint8_t uid[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + uint8_t atqa[2] = {0, 0}; + int atqalen = 0; + uint8_t sak[1] = {0}; + int saklen = 0; uint8_t exitAfterNReads = 0; uint16_t flags = 0; int uidlen = 0; @@ -2195,6 +2201,10 @@ static int CmdHF14AMfSim(const char *Cmd) { flags |= FLAG_MF_MINI; sprintf(csize, "MINI"); break; + case 1: + flags |= FLAG_MF_1K; + sprintf(csize, "1K"); + break; case 2: flags |= FLAG_MF_2K; sprintf(csize, "2K with RATS"); @@ -2203,14 +2213,33 @@ static int CmdHF14AMfSim(const char *Cmd) { flags |= FLAG_MF_4K; sprintf(csize, "4K"); break; - case 1: default: - flags |= FLAG_MF_1K; - sprintf(csize, "1K"); + PrintAndLogEx(WARNING, "Unknown parameter for option t"); + errors = true; break; } cmdp += 2; break; + case 'a': + param_gethex_ex(Cmd, cmdp + 1, atqa, &atqalen); + if (atqalen >> 1 != 2) { + PrintAndLogEx(WARNING, "Wrong ATQA length"); + errors = true; + break; + } + flags |= FLAG_FORCED_ATQA; + cmdp += 2; + break; + case 's': + param_gethex_ex(Cmd, cmdp + 1, sak, &saklen); + if (saklen >> 1 != 1) { + PrintAndLogEx(WARNING, "Wrong SAK length"); + errors = true; + break; + } + flags |= FLAG_FORCED_SAK; + cmdp += 2; + break; case 'u': param_gethex_ex(Cmd, cmdp + 1, uid, &uidlen); uidlen >>= 1; @@ -2269,11 +2298,15 @@ static int CmdHF14AMfSim(const char *Cmd) { uint16_t flags; uint8_t exitAfter; uint8_t uid[10]; + uint16_t atqa; + uint8_t sak; } PACKED payload; payload.flags = flags; payload.exitAfter = exitAfterNReads; memcpy(payload.uid, uid, uidlen); + payload.atqa = (atqa[1] << 8) | atqa[0]; + payload.sak = sak[0]; clearCommandBuffer(); SendCommandNG(CMD_HF_MIFARE_SIMULATE, (uint8_t *)&payload, sizeof(payload)); diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index b83cd6819..756e216e8 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -495,6 +495,8 @@ typedef struct { #define FLAG_MF_1K 0x100 #define FLAG_MF_2K 0x200 #define FLAG_MF_4K 0x400 +#define FLAG_FORCED_ATQA 0x800 +#define FLAG_FORCED_SAK 0x1000 //Iclass reader flags #define FLAG_ICLASS_READER_ONLY_ONCE 0x01 From 12d38bb6ac4829128d45f42267910abdbd3dfd90 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 7 Aug 2019 11:57:26 +0200 Subject: [PATCH 0278/1854] fix standalones after Mifare1ksim changes --- armsrc/Standalone/hf_colin.c | 2 +- armsrc/Standalone/hf_mattyrun.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/armsrc/Standalone/hf_colin.c b/armsrc/Standalone/hf_colin.c index 76e705afe..1a461fe21 100644 --- a/armsrc/Standalone/hf_colin.c +++ b/armsrc/Standalone/hf_colin.c @@ -721,7 +721,7 @@ readysim: // if ((flags & (FLAG_4B_UID_IN_DATA | FLAG_7B_UID_IN_DATA | FLAG_10B_UID_IN_DATA)) == 0) { flags |= FLAG_UID_IN_EMUL; //} - Mifare1ksim(flags | FLAG_MF_1K, 0, cjuid); + Mifare1ksim(flags | FLAG_MF_1K, 0, cjuid, 0, 0); LED_C_OFF(); SpinOff(50); vtsend_cursor_position_restore(NULL); diff --git a/armsrc/Standalone/hf_mattyrun.c b/armsrc/Standalone/hf_mattyrun.c index 1cf75888b..485a7c072 100644 --- a/armsrc/Standalone/hf_mattyrun.c +++ b/armsrc/Standalone/hf_mattyrun.c @@ -400,7 +400,7 @@ void RunMod() { simflags = FLAG_4B_UID_IN_DATA; break; } - Mifare1ksim(simflags | FLAG_MF_1K, 0, uid); + Mifare1ksim(simflags | FLAG_MF_1K, 0, uid, 0, 0); LED_B_OFF(); /* From 9b44590f8dd2e52d735031f3784f75a59c01fd5e Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 7 Aug 2019 12:12:44 +0200 Subject: [PATCH 0279/1854] make style --- armsrc/appmain.c | 2 +- client/cmdtrace.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 98605e481..591b67334 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -433,7 +433,7 @@ void SendStatus(void) { Dbprintf(" ToSend BUFFERSIZE.......%d", TOSEND_BUFFER_SIZE); while ((AT91C_BASE_PMC->PMC_MCFR & AT91C_CKGR_MAINRDY) == 0); // Wait for MAINF value to become available... uint16_t mainf = AT91C_BASE_PMC->PMC_MCFR & AT91C_CKGR_MAINF; // Get # main clocks within 16 slow clocks - Dbprintf(" Slow clock..............%d Hz", (16*MAINCK) / mainf); + Dbprintf(" Slow clock..............%d Hz", (16 * MAINCK) / mainf); DbpString(_BLUE_("Installed StandAlone Mode")); ModInfo(); diff --git a/client/cmdtrace.c b/client/cmdtrace.c index 0dd125c20..4f961b69e 100644 --- a/client/cmdtrace.c +++ b/client/cmdtrace.c @@ -830,7 +830,7 @@ int CmdTraceList(const char *Cmd) { ClearAuthData(); while (tracepos < traceLen) { tracepos = printTraceLine(tracepos, traceLen, trace, protocol, showWaitCycles, markCRCBytes); - + if (kbd_enter_pressed()) break; } From e057fa6fa062f84bd5350dcc282facca01143b07 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 7 Aug 2019 12:30:44 +0200 Subject: [PATCH 0280/1854] Add time measurements of recv packets on client side --- client/comms.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/client/comms.c b/client/comms.c index 86e6b2a79..21c469adc 100644 --- a/client/comms.c +++ b/client/comms.c @@ -53,6 +53,8 @@ static pthread_mutex_t rxBufferMutex = PTHREAD_MUTEX_INITIALIZER; // as sending lot of these packets can slow down things wuite a lot on slow links (e.g. hw status or lf read at 9600) static uint64_t timeout_start_time; +static uint64_t last_packet_time; + static bool dl_it(uint8_t *dest, uint32_t bytes, uint32_t start_index, PacketResponseNG *response, size_t ms_timeout, bool show_warning, uint32_t rec_cmd); // Simple alias to track usages linked to the Bootloader, these commands must not be migrated. @@ -248,11 +250,14 @@ static int getReply(PacketResponseNG *packet) { //----------------------------------------------------------------------------- static void PacketResponseReceived(PacketResponseNG *packet) { -// PrintAndLogEx(NORMAL, "RECV %s magic %08x length %04x status %04x crc %04x cmd %04x", -// packet->ng ? "NG" : "OLD", packet->magic, packet->length, packet->status, packet->crc, packet->cmd); - // we got a packet, reset WaitForResponseTimeout timeout - __atomic_store_n(&timeout_start_time, msclock(), __ATOMIC_SEQ_CST); + uint64_t prev_clk = __atomic_load_n(&last_packet_time, __ATOMIC_SEQ_CST); + uint64_t clk = msclock(); + __atomic_store_n(&timeout_start_time, clk, __ATOMIC_SEQ_CST); + __atomic_store_n(&last_packet_time, clk, __ATOMIC_SEQ_CST); + (void) prev_clk; +// PrintAndLogEx(NORMAL, "[%07"PRIu64"] RECV %s magic %08x length %04x status %04x crc %04x cmd %04x", +// clk - prev_clk, packet->ng ? "NG" : "OLD", packet->magic, packet->length, packet->status, packet->crc, packet->cmd); switch (packet->cmd) { // First check if we are handling a debug message @@ -585,6 +590,7 @@ int TestProxmark(void) { for (uint16_t i = 0; i < len; i++) data[i] = i & 0xFF; + __atomic_store_n(&last_packet_time, msclock(), __ATOMIC_SEQ_CST); clearCommandBuffer(); SendCommandNG(CMD_PING, data, len); From bc28eb04e437e65c94f86e94c4da7b0ef58cf92e Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 7 Aug 2019 12:41:53 +0200 Subject: [PATCH 0281/1854] Revert 00350db and add waiting time extension request mechanism, see issue #265 --- armsrc/appmain.c | 10 ++++++++++ armsrc/apps.h | 1 + armsrc/fpgaloader.c | 2 ++ client/cmdhf.c | 6 +++--- client/comms.c | 11 +++++++++++ include/pm3_cmd.h | 1 + 6 files changed, 28 insertions(+), 3 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 591b67334..8f65bc892 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -59,6 +59,7 @@ int ToSendMax = -1; static int ToSendBit; struct common_area common_area __attribute__((section(".commonarea"))); int button_status = BUTTON_NO_CLICK; +bool allow_send_wtx = false; void ToSendReset(void) { ToSendMax = -1; @@ -118,6 +119,12 @@ void print_result(char *name, uint8_t *buf, size_t len) { // Debug print functions, to go out over USB, to the usual PC-side client. //============================================================================= +inline void send_wtx(uint16_t wtx) { + if (allow_send_wtx) { + reply_ng(CMD_WTX, PM3_SUCCESS, (uint8_t *)&wtx, sizeof(wtx)); + } +} + void DbpStringEx(uint32_t flags, char *str) { #if DEBUG struct { @@ -1994,6 +2001,7 @@ void __attribute__((noreturn)) AppMain(void) { // against device such as http://www.hobbytronics.co.uk/usb-host-board-v2 usb_disable(); usb_enable(); + allow_send_wtx = true; #ifdef WITH_FLASH // If flash is not present, BUSY_TIMEOUT kicks in, let's do it after USB @@ -2023,7 +2031,9 @@ void __attribute__((noreturn)) AppMain(void) { * So this is the trigger to execute a standalone mod. Generic entrypoint by following the standalone/standalone.h headerfile * All standalone mod "main loop" should be the RunMod() function. */ + allow_send_wtx = false; RunMod(); + allow_send_wtx = true; } } } diff --git a/armsrc/apps.h b/armsrc/apps.h index d3fa44429..7cc401857 100644 --- a/armsrc/apps.h +++ b/armsrc/apps.h @@ -43,6 +43,7 @@ extern uint8_t trigger; /// appmain.h void ReadMem(int addr); void __attribute__((noreturn)) AppMain(void); +void send_wtx(uint16_t wtx); //void DbpIntegers(int a, int b, int c); void DbpString(char *str); void DbpStringEx(uint32_t flags, char *str); diff --git a/armsrc/fpgaloader.c b/armsrc/fpgaloader.c index 5b55325d7..b5543a7d2 100644 --- a/armsrc/fpgaloader.c +++ b/armsrc/fpgaloader.c @@ -395,6 +395,8 @@ void FpgaDownloadAndGo(int bitstream_version) { if (downloaded_bitstream == bitstream_version) return; + // Send waiting time extension request as this will take a while + send_wtx(1500); z_stream compressed_fpga_stream; uint8_t output_buffer[OUTPUT_BUFFER_LEN] = {0x00}; diff --git a/client/cmdhf.c b/client/cmdhf.c index 4e88f19f6..36c6d2e18 100644 --- a/client/cmdhf.c +++ b/client/cmdhf.c @@ -125,7 +125,7 @@ int CmdHFTune(const char *Cmd) { clearCommandBuffer(); uint8_t mode[] = {1}; SendCommandNG(CMD_MEASURE_ANTENNA_TUNING_HF, mode, sizeof(mode)); - if (!WaitForResponseTimeout(CMD_MEASURE_ANTENNA_TUNING_HF, &resp, 2000)) { + if (!WaitForResponseTimeout(CMD_MEASURE_ANTENNA_TUNING_HF, &resp, 1000)) { PrintAndLogEx(WARNING, "Timeout while waiting for Proxmark HF initialization, aborting"); return PM3_ETIMEOUT; } @@ -136,7 +136,7 @@ int CmdHFTune(const char *Cmd) { break; } SendCommandNG(CMD_MEASURE_ANTENNA_TUNING_HF, mode, sizeof(mode)); - if (!WaitForResponseTimeout(CMD_MEASURE_ANTENNA_TUNING_HF, &resp, 2000)) { + if (!WaitForResponseTimeout(CMD_MEASURE_ANTENNA_TUNING_HF, &resp, 1000)) { PrintAndLogEx(WARNING, "Timeout while waiting for Proxmark HF measure, aborting"); return PM3_ETIMEOUT; } @@ -147,7 +147,7 @@ int CmdHFTune(const char *Cmd) { } mode[0] = 3; SendCommandNG(CMD_MEASURE_ANTENNA_TUNING_HF, mode, sizeof(mode)); - if (!WaitForResponseTimeout(CMD_MEASURE_ANTENNA_TUNING_HF, &resp, 2000)) { + if (!WaitForResponseTimeout(CMD_MEASURE_ANTENNA_TUNING_HF, &resp, 1000)) { PrintAndLogEx(WARNING, "Timeout while waiting for Proxmark HF shutdown, aborting"); return PM3_ETIMEOUT; } diff --git a/client/comms.c b/client/comms.c index 21c469adc..22e5c7fa1 100644 --- a/client/comms.c +++ b/client/comms.c @@ -710,6 +710,12 @@ bool WaitForResponseTimeoutW(uint32_t cmd, PacketResponseNG *response, size_t ms if (cmd == CMD_UNKNOWN || response->cmd == cmd) { return true; } + if (response->cmd == CMD_WTX && response->length == sizeof(uint16_t)) { + uint16_t wtx = response->data.asDwords[0] & 0xFFFF; + PrintAndLogEx(DEBUG, "Got Waiting Time eXtension request %i ms", wtx); + if (ms_timeout != (size_t) - 1) + ms_timeout += wtx; + } } uint64_t tmp_clk = __atomic_load_n(&timeout_start_time, __ATOMIC_SEQ_CST); @@ -824,6 +830,11 @@ static bool dl_it(uint8_t *dest, uint32_t bytes, uint32_t start_index, PacketRes bytes_completed += copy_bytes; } else if (response->cmd == CMD_ACK) { return true; + } else if (response->cmd == CMD_WTX && response->length == sizeof(uint16_t)) { + uint16_t wtx = response->data.asDwords[0] & 0xFFFF; + PrintAndLogEx(DEBUG, "Got Waiting Time eXtension request %i ms", wtx); + if (ms_timeout != (size_t) - 1) + ms_timeout += wtx; } } diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 756e216e8..3d7b156bd 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -258,6 +258,7 @@ typedef struct { #define CMD_QUIT_SESSION 0x0113 #define CMD_SET_DBGMODE 0x0114 #define CMD_STANDALONE 0x0115 +#define CMD_WTX 0x0116 // RDV40, Flash memory operations #define CMD_FLASHMEM_WRITE 0x0121 From 5a6c9e786310ba6db99343aa0363663afa0739b8 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 7 Aug 2019 12:58:25 +0200 Subject: [PATCH 0282/1854] hf tune: mask 32b dword to 16b --- client/cmdhf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdhf.c b/client/cmdhf.c index 36c6d2e18..931737f1c 100644 --- a/client/cmdhf.c +++ b/client/cmdhf.c @@ -142,7 +142,7 @@ int CmdHFTune(const char *Cmd) { } if ((resp.status == PM3_EOPABORTED) || (resp.length != sizeof(uint16_t))) break; - uint16_t volt = resp.data.asDwords[0]; + uint16_t volt = resp.data.asDwords[0] & 0xFFFF; PrintAndLogEx(INPLACE, "%u mV / %5u V", volt, (uint16_t)(volt / 1000)); } mode[0] = 3; From d84a316b4c9ee27e9e9c6d619a1ad1c1819e5f48 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 7 Aug 2019 14:55:29 +0200 Subject: [PATCH 0283/1854] fix MCK, maths... facepalm --- include/proxmark3.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/proxmark3.h b/include/proxmark3.h index ddda6826a..f7903d24f 100644 --- a/include/proxmark3.h +++ b/include/proxmark3.h @@ -19,7 +19,7 @@ // Check bootrom.c for actual clock settings #define MAINCK 16000000 -#define MCK (4 * MAINCK) +#define MCK (3 * MAINCK) #define WDT_HIT() AT91C_BASE_WDTC->WDTC_WDCR = 0xa5000001 From c58937b5f5644b2aae84a50c7c6e7514ac7eebfe Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 9 Aug 2019 11:50:40 +0200 Subject: [PATCH 0284/1854] client: clean deps while cleaning objects --- armsrc/Makefile | 1 + client/Makefile | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/armsrc/Makefile b/armsrc/Makefile index 2901d5a77..488bb0cac 100644 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@ -204,6 +204,7 @@ tarbin: $(OBJS) $(Q)$(TAR) $(TARFLAGS) ../proxmark3-$(platform)-bin.tar $(OBJS:%=armsrc/%) $(OBJS:%.s19=armsrc/%.elf) clean: + $(Q)$(DELETE) $(DEPENDENCY_FILES) $(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.o $(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.elf $(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.s19 diff --git a/client/Makefile b/client/Makefile index b0544ced4..47a890d0a 100644 --- a/client/Makefile +++ b/client/Makefile @@ -292,7 +292,7 @@ ifeq "$(SUPPORTS_AVX512)" "True" endif BINS = proxmark3 flasher fpga_compress -CLEAN = $(BINS) $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(ZLIBOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(OBJDIR)/*.o *.moc.cpp ui/ui_overlays.h lualibs/pm3_cmd.lua lualibs/mf_default_keys.lua +CLEAN = $(BINS) $(DEPENDENCY_FILES) $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(ZLIBOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(OBJDIR)/*.o *.moc.cpp ui/ui_overlays.h lualibs/pm3_cmd.lua lualibs/mf_default_keys.lua # need to assign dependancies to build these first... all: lua_build jansson_build mbedtls_build cbor_build $(BINS) From 92122877d0678bfbfa9714b2960dd9c89380a80c Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 9 Aug 2019 12:04:22 +0200 Subject: [PATCH 0285/1854] fix nonce2key typo --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 5817b80bf..d3305bb5e 100644 --- a/Makefile +++ b/Makefile @@ -55,7 +55,7 @@ recovery/%: FORCE cleanifplatformchanged bootrom/% armsrc/% $(Q)$(MAKE) --no-print-directory -C recovery $(patsubst recovery/%,%,$@) FORCE: # Dummy target to force remake in the subdirectories, even if files exist (this Makefile doesn't know about the prerequisites) -.PHONY: all clean help _test bootrom flash-bootrom os flash-os flash-all recovery client mfkey nounce2key style checks FORCE udev accessrights cleanifplatformchanged +.PHONY: all clean help _test bootrom flash-bootrom os flash-os flash-all recovery client mfkey nonce2key style checks FORCE udev accessrights cleanifplatformchanged help: @echo "Multi-OS Makefile" @@ -73,7 +73,7 @@ help: @echo @echo "+ client - Make only the OS-specific host client" @echo "+ mfkey - Make tools/mfkey" - @echo "+ nounce2key - Make tools/nounce2key" + @echo "+ nonce2key - Make tools/nonce2key" @echo @echo "+ style - Apply some automated source code formatting rules" @echo "+ checks - Detect various encoding issues in source code" From 5051ea429d7d44d5a8ee7b46531e902f16fe2bc6 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 9 Aug 2019 13:02:10 +0200 Subject: [PATCH 0286/1854] typo --- client/cmdhfmfdes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdhfmfdes.c b/client/cmdhfmfdes.c index 5dd4489f6..c5a54735a 100644 --- a/client/cmdhfmfdes.c +++ b/client/cmdhfmfdes.c @@ -358,7 +358,7 @@ void getKeySettings(uint8_t *aid) { str = "All keys (except AMK,see Bit0) within this application are frozen"; break; default: - str = "Authentication with the specified key is necessary to change any ley. A change key and a PICC master key (CMK) can only be changed after authentication with the master key. For keys other then the master or change key, an authentication with the same key is needed."; + str = "Authentication with the specified key is necessary to change any key. A change key and a PICC master key (CMK) can only be changed after authentication with the master key. For keys other then the master or change key, an authentication with the same key is needed."; break; } PrintAndLogEx(NORMAL, "Changekey Access rights"); From 7722f3af992df1f0fb1822286863fe4c67bea3a4 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 9 Aug 2019 16:03:14 +0200 Subject: [PATCH 0287/1854] Guard Makefile.hal against Make trying to remake it --- common/Makefile.hal | 2 ++ 1 file changed, 2 insertions(+) diff --git a/common/Makefile.hal b/common/Makefile.hal index 68de2b154..af80bc6ac 100644 --- a/common/Makefile.hal +++ b/common/Makefile.hal @@ -2,6 +2,8 @@ PLATFORM?=PM3RDV4 # Standalone Mode info (path depends if make is called at top or from armsrc) +# Guard Makefile.hal against implicit rules: (with % to avoid being first goal) +%/Makefile.hal: ; -include armsrc/Standalone/Makefile.hal -include Standalone/Makefile.hal ifndef DEFAULT_STANDALONE From f02a02cb14c60e754a2f746a1fc8f2947bb1de4d Mon Sep 17 00:00:00 2001 From: netvader <5840601+netvader@users.noreply.github.com> Date: Fri, 9 Aug 2019 16:55:33 +0200 Subject: [PATCH 0288/1854] Update bt_manual_v10.md I've tried to write a blueshark tutorial for android, I hope that's fine? --- doc/bt_manual_v10.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/doc/bt_manual_v10.md b/doc/bt_manual_v10.md index 1cc8d3690..5f140976f 100644 --- a/doc/bt_manual_v10.md +++ b/doc/bt_manual_v10.md @@ -193,7 +193,17 @@ After reboot you can go ahead to pairing your Proxmark3 RDV4 Blue Shark: ```sh ./proxmark /dev/tty.PM3_RDV40-DevB ``` +#### Android +#### (2) Fast connection using dedicated Bluetooth (HC-06 Master + CP2102) adapter under Android with Termux + + 1. Make sure you already followed this tutorial https://github.com/RfidResearchGroup/proxmark3/blob/master/doc/termux_notes.md#setup and have Termux with an running Proxmark3 client ready. You need additional the `cp210x` serial usb driver enabled and working, like the `USB_ACM` driver to communicate wireless. + 2. Insert the Bluetooth adapter with an fitting USB-C/Micro-USB converter into your Android USB port and a serial port `/dev/ttyUSB0` will be created. To see if it's working, run `tsudo ls /dev/ttyU*` and it should list `/dev/ttyUSB0`. + 3. The adapter will search automatically and establish the connection to BlueShark. The adapter will remember the device that was first connected and after that the same device will be connected. After the connection is established, the blue state LED on add-on will turn on solid. + 4. If you see this, congratulations, you can run your Proxmark3 client in Termux with `tsudo proxmark3/client/proxmark3 /dev/ttyUSB0` + +##### Notes +If you bought your Bluetooth adapter somewhere else, make sure to set the baud rate to 115200 `AT+BAUD8` and PIN `AT+PIN1234` correctly ### 6. OTHER NOTES From b06274623f5338764f24ea93c0f1b689f48712fb Mon Sep 17 00:00:00 2001 From: Iceman Date: Sat, 10 Aug 2019 18:05:24 +0200 Subject: [PATCH 0289/1854] fix: hf iclass dump - now also save EML --- client/cmdhficlass.c | 1 + 1 file changed, 1 insertion(+) diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index d87d26b67..1f8aef9a5 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -1062,6 +1062,7 @@ static int CmdHFiClassReader_Dump(const char *Cmd) { // save the dump to .bin file PrintAndLogEx(SUCCESS, "saving dump file - %d blocks read", gotBytes / 8); saveFile(filename, ".bin", tag_data, gotBytes); + saveFileEML(filename, tag_data, gotBytes, 8); return 1; } From 3f9613b87fb1375a8e885dd288bae756cd1b12f4 Mon Sep 17 00:00:00 2001 From: Iceman Date: Sat, 10 Aug 2019 18:20:20 +0200 Subject: [PATCH 0290/1854] chg: script run dumptoemul - better fail messages --- client/scripts/dumptoemul.lua | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/client/scripts/dumptoemul.lua b/client/scripts/dumptoemul.lua index e364ccc8b..96164b92f 100644 --- a/client/scripts/dumptoemul.lua +++ b/client/scripts/dumptoemul.lua @@ -14,7 +14,7 @@ example = [[ script run dumptoemul -i dumpdata-foobar.bin ]] usage = [[ -script run dumptoemul [-i ] [-o ] +_script run dumptoemul [-i ] [-o ] Arguments: -h This help @@ -108,8 +108,11 @@ local function main(args) if infile == nil then return oops('Could not read file ', input) end - local dumpdata = readdump(infile) + + local dumpdata = readdump(infile) -- The hex-data is now in ascii-format, + if dumpdata == NIL then return oops('Dumpfle not loaded') end + -- But first, check the uid local uid = string.sub(dumpdata, 1, 8) @@ -117,6 +120,8 @@ local function main(args) -- Format some linebreaks dumpdata = convert_to_emulform(dumpdata) + if dumpdata == NIL then return oops('Dumpfle not loaded') end + local outfile = io.open(output, 'w') if outfile == nil then From a78b8a406c53ddeacf7bd92804061d3d3b84744f Mon Sep 17 00:00:00 2001 From: Iceman Date: Sat, 10 Aug 2019 18:33:06 +0200 Subject: [PATCH 0291/1854] fix: hf iclass sim 3 - reading now works... --- armsrc/iclass.c | 53 +++++++++++++++++++++++-------------------------- 1 file changed, 25 insertions(+), 28 deletions(-) diff --git a/armsrc/iclass.c b/armsrc/iclass.c index bf3f562c1..b1553f2df 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -1324,7 +1324,7 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) { // Reader 81 anticoll. CSN // Tag CSN - uint8_t *modulated_response; + uint8_t *modulated_response = NULL; int modulated_response_size = 0; uint8_t *trace_data = NULL; int trace_data_size = 0; @@ -1453,6 +1453,7 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) { trace_data_size = sizeof(anticoll_data); goto send; } + if (len == 4) { // block0,1,2,5 is always readable. switch (receivedCmd[1]) { @@ -1461,13 +1462,13 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) { modulated_response_size = resp_csn_len; trace_data = csn_data; trace_data_size = sizeof(csn_data); - break; + goto send; case 1: // configuration (0c 01) modulated_response = resp_conf; modulated_response_size = resp_conf_len; trace_data = conf_data; trace_data_size = sizeof(conf_data); - break; + goto send; case 2: // e-purse (0c 02) modulated_response = resp_cc; modulated_response_size = resp_cc_len; @@ -1477,19 +1478,30 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) { if (reader_mac_buf != NULL) { memcpy(reader_mac_buf, card_challenge_data, 8); } - break; + goto send; case 5:// Application Issuer Area (0c 05) modulated_response = resp_aia; modulated_response_size = resp_aia_len; trace_data = aia_data; trace_data_size = sizeof(aia_data); - break; - default: - break; - } - goto send; - } - + goto send; + default : { + if (simulationMode == MODE_FULLSIM) { // 0x0C + //Read block + //Take the data... + memcpy(data_generic_trace, emulator + (receivedCmd[1] << 3), 8); + AddCrc(data_generic_trace, 8); + trace_data = data_generic_trace; + trace_data_size = 10; + CodeIClassTagAnswer(trace_data, trace_data_size); + memcpy(modulated_response, ToSend, ToSendMax); + modulated_response_size = ToSendMax; + goto send; + } + break; + } + }//swith + }// if 4 } else if (receivedCmd[0] == ICLASS_CMD_SELECT) { // 0x81 // Reader selects anticollission CSN. // Tag sends the corresponding real CSN @@ -1559,30 +1571,15 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) { trace_data = NULL; trace_data_size = 0; goto send; - } else if (simulationMode == MODE_FULLSIM && receivedCmd[0] == ICLASS_CMD_READ_OR_IDENTIFY && len == 4) { // 0x0C - //Read block - uint8_t blk = receivedCmd[1]; - //Take the data... - memcpy(data_generic_trace, emulator + (blk << 3), 8); - AddCrc(data_generic_trace, 8); - trace_data = data_generic_trace; - trace_data_size = 10; - CodeIClassTagAnswer(trace_data, trace_data_size); - memcpy(data_response, ToSend, ToSendMax); - modulated_response = data_response; - modulated_response_size = ToSendMax; - goto send; } else if (simulationMode == MODE_FULLSIM && receivedCmd[0] == ICLASS_CMD_READ4 && len == 4) { // 0x06 //Read block - uint8_t blk = receivedCmd[1]; //Take the data... - memcpy(data_generic_trace, emulator + (blk << 3), 8 * 4); + memcpy(data_generic_trace, emulator + (receivedCmd[1] << 3), 8 * 4); AddCrc(data_generic_trace, 8 * 4); trace_data = data_generic_trace; trace_data_size = 34; CodeIClassTagAnswer(trace_data, trace_data_size); - memcpy(data_response, ToSend, ToSendMax); - modulated_response = data_response; + memcpy(modulated_response, ToSend, ToSendMax); modulated_response_size = ToSendMax; goto send; } else if (simulationMode == MODE_FULLSIM && receivedCmd[0] == ICLASS_CMD_UPDATE) { From a36b784ecd82a592823055b2206215d47aeb5a8c Mon Sep 17 00:00:00 2001 From: Iceman Date: Sat, 10 Aug 2019 18:34:02 +0200 Subject: [PATCH 0292/1854] chg: help text commands now green --- client/cmdparser.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdparser.c b/client/cmdparser.c index be0de1c50..fff0fabec 100644 --- a/client/cmdparser.c +++ b/client/cmdparser.c @@ -151,7 +151,7 @@ void CmdsHelp(const command_t Commands[]) { int i = 0; while (Commands[i].Name) { if (Commands[i].IsAvailable()) - PrintAndLogEx(NORMAL, "%-16s %s", Commands[i].Name, Commands[i].Help); + PrintAndLogEx(NORMAL, _GREEN_("%-16s")" %s", Commands[i].Name, Commands[i].Help); ++i; } } From d19754567d598692a5df650685ebaf5cc91aa729 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 8 Aug 2019 16:57:33 +0200 Subject: [PATCH 0293/1854] summer restructuring: * .h include only the strict minimum for their own parsing * this forces all files to include explicitment their needs and not count on far streched dependencies * this helps Makefile to rebuild only the minimum * according to this rule, most standalone .h are now gone * big app.h is gone * remove seldom __cplusplus, if c++ happens, everything will have to be done properly anyway * all unrequired include were removed * split common/ into common/ (client+arm) and common_arm/ (os+bootloader) * bring zlib to common/ * bring stuff not really/not yet used in common back to armsrc/ or client/ * bring liblua into client/ * bring uart into client/ * move some portions of code around (dbprint, protocols,...) * rename unused files into *_disabled.[ch] to make it explicit * rename soft Uarts between 14a, 14b and iclass, so a standalone could use several without clash * remove PrintAndLogDevice * move deprecated-hid-flasher from client to tools * Makefiles * treat deps in armsrc/ as in client/ * client: stop on warning (-Werror), same as for armsrc/ Tested on: * all standalone modes * Linux --- .gitignore | 1 + Makefile | 2 +- armsrc/BigBuf.c | 3 + armsrc/BigBuf.h | 6 +- armsrc/{LCD.c => LCD_disabled.c} | 0 armsrc/{LCD.h => LCD_disabled.h} | 4 - armsrc/Makefile | 16 +- armsrc/Standalone/hf_bog.c | 33 ++- armsrc/Standalone/hf_bog.h | 27 -- armsrc/Standalone/hf_colin.c | 19 ++ armsrc/Standalone/hf_colin.h | 16 -- armsrc/Standalone/hf_mattyrun.c | 16 +- armsrc/Standalone/hf_mattyrun.h | 23 -- armsrc/Standalone/hf_young.c | 17 +- armsrc/Standalone/hf_young.h | 22 -- armsrc/Standalone/lf_hidbrute.c | 11 + armsrc/Standalone/lf_hidbrute.h | 5 +- armsrc/Standalone/lf_icerun.c | 7 +- armsrc/Standalone/lf_proxbrute.c | 11 +- armsrc/Standalone/lf_samyrun.c | 11 +- armsrc/Standalone/lf_samyrun.h | 22 -- armsrc/Standalone/placeholder.c | 3 +- armsrc/Standalone/standalone.h | 3 - armsrc/appmain.c | 165 +++--------- armsrc/appmain.h | 45 ++++ armsrc/apps.h | 254 ------------------ armsrc/{buzzer.c => buzzer_disabled.c} | 0 armsrc/{buzzer.h => buzzer_disabled.h} | 26 +- {common => armsrc}/cmd.c | 3 + {common => armsrc}/cmd.h | 39 +-- armsrc/dbprint.c | 130 +++++++++ armsrc/dbprint.h | 53 ++++ armsrc/des.c | 1 + armsrc/des.h | 3 +- {common => armsrc}/desfire.h | 4 +- armsrc/desfire_crypto.h | 18 -- ...ire_crypto.c => desfire_crypto_disabled.c} | 8 + armsrc/desfire_crypto_disabled.h | 18 ++ armsrc/desfire_key.c | 1 + armsrc/desfire_key.h | 6 +- {common => armsrc}/emvtags.h | 3 +- armsrc/epa.c | 10 + armsrc/epa.h | 10 +- armsrc/felica.c | 11 +- .../{Standalone/lf_proxbrute.h => felica.h} | 23 +- armsrc/flashmem.c | 5 + armsrc/flashmem.h | 5 +- armsrc/fpgaloader.c | 12 +- armsrc/fpgaloader.h | 38 ++- armsrc/frozen.c | 3 - armsrc/frozen.h | 16 -- armsrc/hfsnoop.c | 7 +- armsrc/{Standalone/lf_icerun.h => hfsnoop.h} | 15 +- armsrc/hitag2.c | 10 +- armsrc/hitag2.h | 3 +- armsrc/hitag2_crypto.c | 3 + armsrc/hitag2_crypto.h | 10 +- armsrc/hitagS.c | 11 + armsrc/hitagS.h | 11 +- {common => armsrc}/i2c.c | 8 + {common => armsrc}/i2c.h | 7 +- armsrc/iclass.c | 130 +++++---- armsrc/iclass.h | 29 ++ armsrc/iso14443a.c | 109 ++++---- armsrc/iso14443a.h | 56 ++-- armsrc/iso14443b.c | 96 ++++--- armsrc/iso14443b.h | 24 +- armsrc/iso15693.c | 12 +- armsrc/iso15693.h | 26 ++ armsrc/ldscript | 2 +- armsrc/legicrf.c | 11 +- armsrc/legicrf.h | 2 +- armsrc/legicrfsim.c | 8 +- armsrc/legicrfsim.h | 2 +- armsrc/lfops.c | 39 ++- armsrc/lfops.h | 69 +++++ armsrc/lfsampling.c | 8 + armsrc/lfsampling.h | 9 +- armsrc/mifarecmd.c | 18 +- armsrc/mifarecmd.h | 55 ++-- armsrc/mifaredesfire.c | 15 ++ armsrc/mifaredesfire.h | 29 +- armsrc/mifaresim.c | 17 +- armsrc/mifaresim.h | 6 +- .../{mifaresniff.c => mifaresniff_disabled.c} | 20 +- .../{mifaresniff.h => mifaresniff_disabled.h} | 7 - armsrc/mifareutil.c | 11 + armsrc/mifareutil.h | 8 +- armsrc/nprintf.c | 3 - armsrc/nprintf.h | 16 +- armsrc/optimized_cipher.h | 4 +- armsrc/pcf7931.c | 10 + armsrc/pcf7931.h | 6 +- armsrc/printf.c | 2 + armsrc/printf.h | 5 +- {common => armsrc}/radixsort.c | 0 {common => armsrc}/radixsort.h | 5 +- armsrc/spiffs.c | 6 + armsrc/spiffs.h | 8 +- armsrc/spiffs_config.h | 17 +- armsrc/spiffs_nucleus.h | 5 + armsrc/start.c | 4 +- armsrc/string.h | 5 +- armsrc/thinfilm.c | 10 + armsrc/thinfilm.h | 13 +- armsrc/ticks.c | 3 + armsrc/ticks.h | 5 +- {common => armsrc}/usart.c | 4 +- {common => armsrc}/usart.h | 16 +- armsrc/util.c | 8 + armsrc/util.h | 5 - armsrc/vtsend.c | 3 +- armsrc/vtsend.h | 12 +- {common => armsrc}/wiegand.c | 0 {common => armsrc}/wiegand.h | 0 bootrom/Makefile | 6 +- bootrom/bootrom.c | 3 +- bootrom/ldscript-flash | 2 +- client/Makefile | 16 +- client/cliparser/cliparser.c | 1 - client/cliparser/cliparser.h | 1 - client/cmdanalyse.c | 13 + client/cmdanalyse.h | 15 +- client/cmdcrc.c | 17 ++ client/cmdcrc.h | 17 +- client/cmddata.c | 15 ++ client/cmddata.h | 21 +- client/cmdflashmem.c | 14 +- client/cmdflashmem.h | 13 - client/cmdflashmemspiffs.c | 13 +- client/cmdflashmemspiffs.h | 12 - client/cmdhf.c | 42 ++- client/cmdhf.h | 23 +- client/cmdhf14a.c | 15 ++ client/cmdhf14a.h | 20 +- client/cmdhf14b.c | 11 + client/cmdhf14b.h | 18 +- client/cmdhf15.c | 13 + client/cmdhf15.h | 15 +- client/cmdhfepa.c | 12 + client/cmdhfepa.h | 12 - client/cmdhffelica.c | 13 + client/cmdhffelica.h | 12 - client/cmdhffido.c | 22 +- client/cmdhffido.h | 3 +- client/cmdhficlass.c | 164 ++++++++++- client/cmdhficlass.h | 24 -- client/cmdhflegic.c | 10 + client/cmdhflegic.h | 15 +- client/cmdhflist.c | 13 + client/cmdhflist.h | 27 +- client/cmdhfmf.c | 16 +- client/cmdhfmf.h | 21 +- client/cmdhfmfdes.c | 9 + client/cmdhfmfdes.h | 14 +- ...fmfdesfire.c => cmdhfmfdesfire_disabled.c} | 7 + ...fmfdesfire.h => cmdhfmfdesfire_disabled.h} | 5 +- client/cmdhfmfhard.c | 10 +- client/cmdhfmfhard.h | 3 +- client/cmdhfmfp.c | 13 +- client/cmdhfmfp.h | 2 +- client/cmdhfmfu.c | 12 + client/cmdhfmfu.h | 12 +- client/cmdhfthinfilm.c | 11 + client/cmdhfthinfilm.h | 9 - client/cmdhftopaz.c | 14 + client/cmdhftopaz.h | 14 +- client/cmdhw.c | 9 +- client/cmdhw.h | 2 + client/cmdlf.c | 39 +++ client/cmdlf.h | 42 +-- client/cmdlfawid.c | 15 ++ client/cmdlfawid.h | 13 +- client/cmdlfcotag.c | 9 + client/cmdlfcotag.h | 8 +- client/cmdlfem4x.c | 17 ++ client/cmdlfem4x.h | 14 +- client/cmdlffdx.c | 15 ++ client/cmdlffdx.h | 12 +- client/cmdlfguard.c | 13 + client/cmdlfguard.h | 15 +- client/cmdlfhid.c | 16 ++ client/cmdlfhid.h | 13 +- client/cmdlfhitag.c | 20 +- client/cmdlfhitag.h | 2 + client/cmdlfindala.c | 16 ++ client/cmdlfindala.h | 13 +- client/cmdlfio.c | 15 ++ client/cmdlfio.h | 12 +- client/cmdlfjablotron.c | 15 ++ client/cmdlfjablotron.h | 15 +- client/cmdlfkeri.c | 14 + client/cmdlfkeri.h | 13 +- client/cmdlfnedap.c | 14 + client/cmdlfnedap.h | 15 +- client/cmdlfnexwatch.c | 7 + client/cmdlfnexwatch.h | 13 +- client/cmdlfnoralsy.c | 12 + client/cmdlfnoralsy.h | 15 +- client/cmdlfpac.c | 7 + client/cmdlfpac.h | 12 +- client/cmdlfparadox.c | 12 +- client/cmdlfparadox.h | 3 + client/cmdlfpcf7931.c | 16 +- client/cmdlfpcf7931.h | 2 + client/cmdlfpresco.c | 14 + client/cmdlfpresco.h | 14 +- client/cmdlfpyramid.c | 15 ++ client/cmdlfpyramid.h | 15 +- client/cmdlfsecurakey.c | 10 + client/cmdlfsecurakey.h | 15 +- client/cmdlft55xx.c | 17 +- client/cmdlft55xx.h | 18 +- client/cmdlfti.c | 7 +- client/cmdlfti.h | 2 + client/cmdlfviking.c | 11 + client/cmdlfviking.h | 14 +- client/cmdlfvisa2000.c | 13 + client/cmdlfvisa2000.h | 16 +- client/cmdmain.c | 20 ++ client/cmdmain.h | 26 +- client/cmdparser.c | 11 +- client/cmdparser.h | 2 + client/cmdscript.c | 18 +- client/cmdscript.h | 2 + client/cmdsmartcard.c | 15 +- client/cmdsmartcard.h | 15 +- client/cmdtrace.c | 9 + client/cmdtrace.h | 18 +- client/cmdusart.c | 12 + client/cmdusart.h | 9 +- client/comms.c | 12 +- client/comms.h | 25 +- client/crypto/asn1dump.c | 4 +- client/crypto/asn1utils.c | 3 + client/emv/apduinfo.c | 7 + client/emv/apduinfo.h | 8 +- client/emv/cmdemv.c | 18 +- client/emv/cmdemv.h | 14 - client/emv/crypto.c | 2 - client/emv/crypto.h | 3 +- client/emv/crypto_backend.h | 3 +- client/emv/crypto_polarssl.c | 3 - client/emv/dol.h | 1 - client/emv/dump.h | 6 +- client/emv/emv_pk.c | 12 +- client/emv/emv_pk.h | 3 +- client/emv/emv_pki.c | 8 +- client/emv/emv_pki.h | 2 - client/emv/emv_pki_priv.c | 1 - client/emv/emv_pki_priv.h | 4 +- client/emv/emv_roca.c | 3 + client/emv/emv_roca.h | 5 +- client/emv/emv_tags.c | 4 +- client/emv/emv_tags.h | 2 +- client/emv/emvcore.c | 12 + client/emv/emvcore.h | 18 +- client/emv/emvjson.c | 8 +- client/emv/emvjson.h | 2 + client/emv/test/crypto_test.c | 3 +- client/emv/tlv.c | 2 - client/emv/tlv.h | 4 +- client/fido/additional_ca.c | 1 - client/fido/additional_ca.h | 2 +- client/fido/cbortools.c | 4 +- client/fido/cbortools.h | 3 +- client/fido/cose.c | 5 +- client/fido/cose.h | 5 +- client/fido/fidocore.c | 15 +- client/fido/fidocore.h | 6 +- client/flash.c | 11 + client/flash.h | 15 +- client/flasher.c | 9 +- client/fpga_compress.c | 4 - client/graph.c | 6 + client/graph.h | 9 +- client/hardnested/hardnested_bf_core.c | 1 + client/hardnested/hardnested_bruteforce.c | 2 + {liblua => client/liblua}/Makefile | 0 {liblua => client/liblua}/lapi.c | 0 {liblua => client/liblua}/lapi.h | 0 {liblua => client/liblua}/lauxlib.c | 0 {liblua => client/liblua}/lauxlib.h | 0 {liblua => client/liblua}/lbaselib.c | 0 {liblua => client/liblua}/lbitlib.c | 0 {liblua => client/liblua}/lcode.c | 0 {liblua => client/liblua}/lcode.h | 0 {liblua => client/liblua}/lcorolib.c | 0 {liblua => client/liblua}/lctype.c | 0 {liblua => client/liblua}/lctype.h | 0 {liblua => client/liblua}/ldblib.c | 0 {liblua => client/liblua}/ldebug.c | 0 {liblua => client/liblua}/ldebug.h | 0 {liblua => client/liblua}/ldo.c | 0 {liblua => client/liblua}/ldo.h | 0 {liblua => client/liblua}/ldump.c | 0 {liblua => client/liblua}/lfunc.c | 0 {liblua => client/liblua}/lfunc.h | 0 {liblua => client/liblua}/lgc.c | 0 {liblua => client/liblua}/lgc.h | 0 {liblua => client/liblua}/linit.c | 0 {liblua => client/liblua}/liolib.c | 0 {liblua => client/liblua}/llex.c | 0 {liblua => client/liblua}/llex.h | 0 {liblua => client/liblua}/llimits.h | 0 {liblua => client/liblua}/lmathlib.c | 0 {liblua => client/liblua}/lmem.c | 0 {liblua => client/liblua}/lmem.h | 0 {liblua => client/liblua}/loadlib.c | 0 {liblua => client/liblua}/lobject.c | 0 {liblua => client/liblua}/lobject.h | 0 {liblua => client/liblua}/lopcodes.c | 0 {liblua => client/liblua}/lopcodes.h | 0 {liblua => client/liblua}/loslib.c | 0 {liblua => client/liblua}/lparser.c | 0 {liblua => client/liblua}/lparser.h | 0 {liblua => client/liblua}/lstate.c | 0 {liblua => client/liblua}/lstate.h | 0 {liblua => client/liblua}/lstring.c | 0 {liblua => client/liblua}/lstring.h | 0 {liblua => client/liblua}/lstrlib.c | 0 {liblua => client/liblua}/ltable.c | 0 {liblua => client/liblua}/ltable.h | 0 {liblua => client/liblua}/ltablib.c | 0 {liblua => client/liblua}/ltm.c | 0 {liblua => client/liblua}/ltm.h | 0 {liblua => client/liblua}/lua.c | 0 {liblua => client/liblua}/lua.h | 0 {liblua => client/liblua}/lua.hpp | 0 {liblua => client/liblua}/luac.c | 0 {liblua => client/liblua}/luaconf.h | 0 {liblua => client/liblua}/lualib.h | 0 {liblua => client/liblua}/lundump.c | 0 {liblua => client/liblua}/lundump.h | 0 {liblua => client/liblua}/lvm.c | 0 {liblua => client/liblua}/lvm.h | 0 {liblua => client/liblua}/lzio.c | 0 {liblua => client/liblua}/lzio.h | 0 client/loclass/cipher.c | 6 +- client/loclass/cipherutils.c | 25 +- client/loclass/elite_crack.c | 62 ++--- client/loclass/fileutils.c | 41 +-- client/loclass/fileutils.h | 4 +- client/loclass/ikeys.c | 57 ++-- client/mifare/mad.c | 2 + client/mifare/mad.h | 4 +- client/mifare/mfkey.c | 2 + client/mifare/mfkey.h | 5 +- client/mifare/mifare4.c | 4 +- client/mifare/mifare4.h | 4 +- client/mifare/mifaredefault.h | 2 +- client/mifare/mifarehost.c | 17 +- client/mifare/mifarehost.h | 15 +- client/mifare/ndef.c | 4 + client/mifare/ndef.h | 4 +- client/pm3_bit_limits.h | 2 + {common => client}/prng.c | 0 {common => client}/prng.h | 6 +- client/proxendian.h | 2 +- client/proxgui.cpp | 2 + client/proxgui.h | 3 +- client/proxmark3.c | 12 +- client/proxmark3.h | 3 +- client/scripting.c | 22 ++ client/scripting.h | 22 +- {common => client}/tea.c | 3 + {common => client}/tea.h | 6 +- {uart => client/uart}/README.md | 0 {uart => client/uart}/uart.h | 18 -- {uart => client/uart}/uart_posix.c | 14 +- {uart => client/uart}/uart_win32.c | 6 + client/ui.c | 9 + client/ui.h | 15 +- client/util.c | 10 + client/util.h | 24 -- client/util_posix.c | 4 +- client/util_posix.h | 6 +- common/bucketsort.h | 4 +- common/commonutil.h | 11 +- common/crapto1/crapto1.c | 2 + common/crapto1/crapto1.h | 12 +- common/crapto1/crypto1.c | 4 +- common/crc.c | 2 + common/crc.h | 27 +- common/crc16.c | 3 + common/crc16.h | 6 +- common/crc32.h | 11 +- common/crc64.c | 2 - common/crc64.h | 2 + common/fpga.h | 2 + common/iso15693tools.c | 2 + common/iso15693tools.h | 9 +- {include => common}/legic_prng.h | 4 +- common/lfdemod.c | 10 +- common/lfdemod.h | 9 +- common/parity.c | 1 - common/parity.h | 11 +- common/protocols.c | 150 ----------- {zlib => common/zlib}/ChangeLog | 0 {zlib => common/zlib}/FAQ | 0 {zlib => common/zlib}/README | 0 {zlib => common/zlib}/adler32.c | 0 {zlib => common/zlib}/deflate.c | 0 {zlib => common/zlib}/deflate.h | 0 {zlib => common/zlib}/inffast.c | 0 {zlib => common/zlib}/inffast.h | 0 {zlib => common/zlib}/inffixed.h | 0 {zlib => common/zlib}/inflate.c | 0 {zlib => common/zlib}/inflate.h | 0 {zlib => common/zlib}/inftrees.c | 0 {zlib => common/zlib}/inftrees.h | 0 {zlib => common/zlib}/trees.c | 0 {zlib => common/zlib}/trees.h | 0 {zlib => common/zlib}/zconf.h | 0 {zlib => common/zlib}/zlib.h | 0 {zlib => common/zlib}/zutil.c | 0 {zlib => common/zlib}/zutil.h | 0 {common => common_arm}/Makefile.common | 26 +- {common => common_arm}/Makefile.hal | 0 {common => common_arm}/default_version.c | 2 +- {common => common_arm}/ldscript.common | 0 {common => common_arm}/usb_cdc.c | 14 +- {common => common_arm}/usb_cdc.h | 7 +- fpga/Makefile | 3 - include/ansi.h | 11 + include/common.h | 20 +- include/pmflash.h | 12 - {common => include}/protocols.h | 33 +-- include/{proxmark3.h => proxmark3_arm.h} | 3 +- include/usart_defs.h | 26 ++ recovery/Makefile | 2 +- .../deprecated-hid-flasher/flasher/Info.plist | 0 .../deprecated-hid-flasher/flasher/Makefile | 0 .../deprecated-hid-flasher/flasher/elf.h | 0 .../deprecated-hid-flasher/flasher/flash.c | 0 .../deprecated-hid-flasher/flasher/flash.h | 0 .../deprecated-hid-flasher/flasher/flasher.c | 0 .../deprecated-hid-flasher/flasher/obj/.dummy | 0 .../flasher/proxendian.h | 0 .../flasher/proxmark3.h | 0 .../deprecated-hid-flasher/flasher/proxusb.c | 0 .../deprecated-hid-flasher/flasher/proxusb.h | 0 .../deprecated-hid-flasher/flasher/sleep.h | 0 .../deprecated-hid-flasher/flasher/usb_cmd.h | 0 .../deprecated-hid-flasher/unbind-proxmark | 0 tools/mkversion.pl | 2 +- tools/nonce2key/crapto1.h | 6 - 447 files changed, 2553 insertions(+), 2599 deletions(-) rename armsrc/{LCD.c => LCD_disabled.c} (100%) rename armsrc/{LCD.h => LCD_disabled.h} (98%) delete mode 100644 armsrc/Standalone/hf_bog.h delete mode 100644 armsrc/Standalone/hf_mattyrun.h delete mode 100644 armsrc/Standalone/hf_young.h delete mode 100644 armsrc/Standalone/lf_samyrun.h create mode 100644 armsrc/appmain.h delete mode 100644 armsrc/apps.h rename armsrc/{buzzer.c => buzzer_disabled.c} (100%) rename armsrc/{buzzer.h => buzzer_disabled.h} (84%) rename {common => armsrc}/cmd.c (99%) rename {common => armsrc}/cmd.h (71%) create mode 100644 armsrc/dbprint.c create mode 100644 armsrc/dbprint.h rename {common => armsrc}/desfire.h (98%) delete mode 100644 armsrc/desfire_crypto.h rename armsrc/{desfire_crypto.c => desfire_crypto_disabled.c} (99%) create mode 100644 armsrc/desfire_crypto_disabled.h rename {common => armsrc}/emvtags.h (99%) rename armsrc/{Standalone/lf_proxbrute.h => felica.h} (52%) rename armsrc/{Standalone/lf_icerun.h => hfsnoop.h} (65%) rename {common => armsrc}/i2c.c (99%) rename {common => armsrc}/i2c.h (95%) create mode 100644 armsrc/iclass.h create mode 100644 armsrc/iso15693.h create mode 100644 armsrc/lfops.h rename armsrc/{mifaresniff.c => mifaresniff_disabled.c} (96%) rename armsrc/{mifaresniff.h => mifaresniff_disabled.h} (87%) rename {common => armsrc}/radixsort.c (100%) rename {common => armsrc}/radixsort.h (87%) rename {common => armsrc}/usart.c (99%) rename {common => armsrc}/usart.h (58%) rename {common => armsrc}/wiegand.c (100%) rename {common => armsrc}/wiegand.h (100%) rename client/{cmdhfmfdesfire.c => cmdhfmfdesfire_disabled.c} (98%) rename client/{cmdhfmfdesfire.h => cmdhfmfdesfire_disabled.h} (52%) rename {liblua => client/liblua}/Makefile (100%) rename {liblua => client/liblua}/lapi.c (100%) rename {liblua => client/liblua}/lapi.h (100%) rename {liblua => client/liblua}/lauxlib.c (100%) rename {liblua => client/liblua}/lauxlib.h (100%) rename {liblua => client/liblua}/lbaselib.c (100%) rename {liblua => client/liblua}/lbitlib.c (100%) rename {liblua => client/liblua}/lcode.c (100%) rename {liblua => client/liblua}/lcode.h (100%) rename {liblua => client/liblua}/lcorolib.c (100%) rename {liblua => client/liblua}/lctype.c (100%) rename {liblua => client/liblua}/lctype.h (100%) rename {liblua => client/liblua}/ldblib.c (100%) rename {liblua => client/liblua}/ldebug.c (100%) rename {liblua => client/liblua}/ldebug.h (100%) rename {liblua => client/liblua}/ldo.c (100%) rename {liblua => client/liblua}/ldo.h (100%) rename {liblua => client/liblua}/ldump.c (100%) rename {liblua => client/liblua}/lfunc.c (100%) rename {liblua => client/liblua}/lfunc.h (100%) rename {liblua => client/liblua}/lgc.c (100%) rename {liblua => client/liblua}/lgc.h (100%) rename {liblua => client/liblua}/linit.c (100%) rename {liblua => client/liblua}/liolib.c (100%) rename {liblua => client/liblua}/llex.c (100%) rename {liblua => client/liblua}/llex.h (100%) rename {liblua => client/liblua}/llimits.h (100%) rename {liblua => client/liblua}/lmathlib.c (100%) rename {liblua => client/liblua}/lmem.c (100%) rename {liblua => client/liblua}/lmem.h (100%) rename {liblua => client/liblua}/loadlib.c (100%) rename {liblua => client/liblua}/lobject.c (100%) rename {liblua => client/liblua}/lobject.h (100%) rename {liblua => client/liblua}/lopcodes.c (100%) rename {liblua => client/liblua}/lopcodes.h (100%) rename {liblua => client/liblua}/loslib.c (100%) rename {liblua => client/liblua}/lparser.c (100%) rename {liblua => client/liblua}/lparser.h (100%) rename {liblua => client/liblua}/lstate.c (100%) rename {liblua => client/liblua}/lstate.h (100%) rename {liblua => client/liblua}/lstring.c (100%) rename {liblua => client/liblua}/lstring.h (100%) rename {liblua => client/liblua}/lstrlib.c (100%) rename {liblua => client/liblua}/ltable.c (100%) rename {liblua => client/liblua}/ltable.h (100%) rename {liblua => client/liblua}/ltablib.c (100%) rename {liblua => client/liblua}/ltm.c (100%) rename {liblua => client/liblua}/ltm.h (100%) rename {liblua => client/liblua}/lua.c (100%) rename {liblua => client/liblua}/lua.h (100%) rename {liblua => client/liblua}/lua.hpp (100%) rename {liblua => client/liblua}/luac.c (100%) rename {liblua => client/liblua}/luaconf.h (100%) rename {liblua => client/liblua}/lualib.h (100%) rename {liblua => client/liblua}/lundump.c (100%) rename {liblua => client/liblua}/lundump.h (100%) rename {liblua => client/liblua}/lvm.c (100%) rename {liblua => client/liblua}/lvm.h (100%) rename {liblua => client/liblua}/lzio.c (100%) rename {liblua => client/liblua}/lzio.h (100%) rename {common => client}/prng.c (100%) rename {common => client}/prng.h (94%) rename {common => client}/tea.c (97%) rename {common => client}/tea.h (90%) rename {uart => client/uart}/README.md (100%) rename {uart => client/uart}/uart.h (91%) rename {uart => client/uart}/uart_posix.c (98%) rename {uart => client/uart}/uart_win32.c (98%) rename {include => common}/legic_prng.h (96%) delete mode 100644 common/protocols.c rename {zlib => common/zlib}/ChangeLog (100%) rename {zlib => common/zlib}/FAQ (100%) rename {zlib => common/zlib}/README (100%) rename {zlib => common/zlib}/adler32.c (100%) rename {zlib => common/zlib}/deflate.c (100%) rename {zlib => common/zlib}/deflate.h (100%) rename {zlib => common/zlib}/inffast.c (100%) rename {zlib => common/zlib}/inffast.h (100%) rename {zlib => common/zlib}/inffixed.h (100%) rename {zlib => common/zlib}/inflate.c (100%) rename {zlib => common/zlib}/inflate.h (100%) rename {zlib => common/zlib}/inftrees.c (100%) rename {zlib => common/zlib}/inftrees.h (100%) rename {zlib => common/zlib}/trees.c (100%) rename {zlib => common/zlib}/trees.h (100%) rename {zlib => common/zlib}/zconf.h (100%) rename {zlib => common/zlib}/zlib.h (100%) rename {zlib => common/zlib}/zutil.c (100%) rename {zlib => common/zlib}/zutil.h (100%) rename {common => common_arm}/Makefile.common (81%) rename {common => common_arm}/Makefile.hal (100%) rename {common => common_arm}/default_version.c (93%) rename {common => common_arm}/ldscript.common (100%) rename {common => common_arm}/usb_cdc.c (98%) rename {common => common_arm}/usb_cdc.h (95%) create mode 100644 include/ansi.h rename {common => include}/protocols.h (96%) rename include/{proxmark3.h => proxmark3_arm.h} (99%) create mode 100644 include/usart_defs.h rename {client => tools}/deprecated-hid-flasher/flasher/Info.plist (100%) rename {client => tools}/deprecated-hid-flasher/flasher/Makefile (100%) rename {client => tools}/deprecated-hid-flasher/flasher/elf.h (100%) rename {client => tools}/deprecated-hid-flasher/flasher/flash.c (100%) rename {client => tools}/deprecated-hid-flasher/flasher/flash.h (100%) rename {client => tools}/deprecated-hid-flasher/flasher/flasher.c (100%) rename {client => tools}/deprecated-hid-flasher/flasher/obj/.dummy (100%) rename {client => tools}/deprecated-hid-flasher/flasher/proxendian.h (100%) rename {client => tools}/deprecated-hid-flasher/flasher/proxmark3.h (100%) rename {client => tools}/deprecated-hid-flasher/flasher/proxusb.c (100%) rename {client => tools}/deprecated-hid-flasher/flasher/proxusb.h (100%) rename {client => tools}/deprecated-hid-flasher/flasher/sleep.h (100%) rename {client => tools}/deprecated-hid-flasher/flasher/usb_cmd.h (100%) rename {client => tools}/deprecated-hid-flasher/unbind-proxmark (100%) diff --git a/.gitignore b/.gitignore index f5ee135e6..f61e85eb9 100644 --- a/.gitignore +++ b/.gitignore @@ -39,6 +39,7 @@ client/ui/ui_overlays.h hardnested_stats.txt proxmark3 flasher +!flasher/ lua luac fpga_compress diff --git a/Makefile b/Makefile index d3305bb5e..194b63b22 100644 --- a/Makefile +++ b/Makefile @@ -31,7 +31,7 @@ endif -include Makefile.platform -include .Makefile.options.cache -include common/Makefile.hal +include common_arm/Makefile.hal all clean: %: client/% bootrom/% armsrc/% recovery/% mfkey/% nonce2key/% diff --git a/armsrc/BigBuf.c b/armsrc/BigBuf.c index 7b199930a..a0a25d1fe 100644 --- a/armsrc/BigBuf.c +++ b/armsrc/BigBuf.c @@ -10,6 +10,9 @@ //----------------------------------------------------------------------------- #include "BigBuf.h" +#include "string.h" +#include "dbprint.h" + // BigBuf is the large multi-purpose buffer, typically used to hold A/D samples or traces. // Also used to hold various smaller buffers and the Mifare Emulator Memory. // declare it as uint32_t to achieve alignment to 4 Byte boundary diff --git a/armsrc/BigBuf.h b/armsrc/BigBuf.h index 12f2521c6..ad967c4c7 100644 --- a/armsrc/BigBuf.h +++ b/armsrc/BigBuf.h @@ -12,10 +12,7 @@ #ifndef __BIGBUF_H #define __BIGBUF_H -#include // for bool -#include "proxmark3.h" -#include "string.h" -#include "ticks.h" +#include "common.h" #define BIGBUF_SIZE 40000 #define MAX_FRAME_SIZE 256 // maximum allowed ISO14443 frame @@ -43,4 +40,5 @@ void set_tracelen(uint32_t value); bool get_tracing(void); bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag); uint8_t emlSet(uint8_t *data, uint32_t offset, uint32_t length); + #endif /* __BIGBUF_H */ diff --git a/armsrc/LCD.c b/armsrc/LCD_disabled.c similarity index 100% rename from armsrc/LCD.c rename to armsrc/LCD_disabled.c diff --git a/armsrc/LCD.h b/armsrc/LCD_disabled.h similarity index 98% rename from armsrc/LCD.h rename to armsrc/LCD_disabled.h index 968c90246..ed765298f 100644 --- a/armsrc/LCD.h +++ b/armsrc/LCD_disabled.h @@ -9,10 +9,6 @@ #ifndef __LCD_H #define __LCD_H -#include "proxmark3.h" -#include "apps.h" -#include "fonts.h" - // The resolution of the LCD #define LCD_XRES 132 #define LCD_YRES 132 diff --git a/armsrc/Makefile b/armsrc/Makefile index 488bb0cac..6a19f7a4d 100644 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@ -2,16 +2,14 @@ # at your option, any later version. See the LICENSE.txt file for the text of # the license. #----------------------------------------------------------------------------- -# Makefile for armsrc, see ../common/Makefile.common for common settings +# Makefile for armsrc, see ../common_arm/Makefile.common for common settings #----------------------------------------------------------------------------- -APP_INCLUDES = apps.h - # This Makefile might have been called directly, not via the root Makefile, so: ifeq ($(PLTNAME),) -include ../Makefile.platform -include ../.Makefile.options.cache - include ../common/Makefile.hal + include ../common_arm/Makefile.hal # detect if there were changes in the platform definitions, requiring a clean ifeq ($(PLATFORM_CHANGED), true) $(error platform definitions have been changed, please "make clean" at the root of the project) @@ -28,9 +26,10 @@ APP_CFLAGS = $(PLATFORM_DEFS) \ SRC_LF = lfops.c lfsampling.c pcf7931.c lfdemod.c SRC_ISO15693 = iso15693.c iso15693tools.c SRC_ISO14443a = iso14443a.c mifareutil.c mifarecmd.c epa.c mifaresim.c +#UNUSED: mifaresniff.c desfire_crypto.c SRC_ISO14443b = iso14443b.c SRC_FELICA = felica.c -SRC_CRAPTO1 = crypto1.c des.c desfire_key.c desfire_crypto.c mifaredesfire.c aes.c platform_util.c +SRC_CRAPTO1 = crypto1.c des.c desfire_key.c mifaredesfire.c aes.c platform_util.c SRC_CRC = crc.c crc16.c crc32.c SRC_ICLASS = iclass.c optimized_cipher.c SRC_LEGIC = legicrf.c legicrfsim.c legic_prng.c @@ -83,7 +82,7 @@ SRC_ZLIB = inflate.c inffast.c inftrees.c adler32.c zutil.c ZLIB_CFLAGS = -DZ_SOLO -DZ_PREFIX -DNO_GZIP -DZLIB_PM3_TUNED APP_CFLAGS += $(ZLIB_CFLAGS) # zlib includes: -APP_CFLAGS += -I../zlib +APP_CFLAGS += -I../common/zlib # stdint.h provided locally until GCC 4.5 becomes C99 compliant, # stack-protect , no-pie reduces size on Gentoo Hardened 8.2 gcc @@ -91,7 +90,6 @@ APP_CFLAGS += -I. -fno-stack-protector -fno-pie # Compile these in thumb mode (small size) THUMBSRC = start.c \ - protocols.c \ $(SRC_LCD) \ $(SRC_ISO15693) \ $(SRC_NFCBARCODE) \ @@ -105,6 +103,7 @@ THUMBSRC = start.c \ $(SRC_SPIFFS) \ appmain.c \ printf.c \ + dbprint.c \ commonutil.c \ util.c \ string.c \ @@ -131,7 +130,7 @@ VERSIONSRC = version.c \ fpga_version_info.c # Do not move this inclusion before the definition of {THUMB,ASM,ARM}SRC -include ../common/Makefile.common +include ../common_arm/Makefile.common COMMON_FLAGS = -Os @@ -220,3 +219,4 @@ help: @echo Possible targets: @echo + all - Build the full image $(OBJDIR)/fullimage.s19 @echo + clean - Clean $(OBJDIR) + diff --git a/armsrc/Standalone/hf_bog.c b/armsrc/Standalone/hf_bog.c index f8f832220..6580af7fd 100644 --- a/armsrc/Standalone/hf_bog.c +++ b/armsrc/Standalone/hf_bog.c @@ -19,7 +19,18 @@ you can simply run 'script run read_pwd_mem' or just 'mem dump p l 256' from the client to view the stored quadlets. */ -#include "hf_bog.h" +#include "standalone.h" // standalone definitions +#include "proxmark3_arm.h" +#include "iso14443a.h" +#include "protocols.h" +#include "util.h" +#include "spiffs.h" +#include "appmain.h" +#include "fpgaloader.h" +#include "dbprint.h" +#include "ticks.h" +#include "BigBuf.h" +#include "string.h" #define DELAY_READER_AIR2ARM_AS_SNIFFER (2 + 3 + 8) #define DELAY_TAG_AIR2ARM_AS_SNIFFER (3 + 14 + 8) @@ -62,10 +73,10 @@ void RAMFUNC SniffAndStore(uint8_t param) { bool ReaderIsActive = false; // Set up the demodulator for tag -> reader responses. - DemodInit(receivedResp, receivedRespPar); + Demod14aInit(receivedResp, receivedRespPar); // Set up the demodulator for the reader -> tag commands - UartInit(receivedCmd, receivedCmdPar); + Uart14aInit(receivedCmd, receivedCmdPar); // Setup and start DMA. if (!FpgaSetupSscDma((uint8_t *)dmaBuf, DMA_BUFFER_SIZE)) { @@ -74,8 +85,8 @@ void RAMFUNC SniffAndStore(uint8_t param) { return; } - tUart *uart = GetUart(); - tDemod *demod = GetDemod(); + tUart14a *uart = GetUart14a(); + tDemod14a *demod = GetDemod14a(); // We won't start recording the frames that we acquire until we trigger; // a good trigger condition to get started is probably when we see a @@ -153,13 +164,13 @@ void RAMFUNC SniffAndStore(uint8_t param) { break; } /* ready to receive another command. */ - UartReset(); + Uart14aReset(); /* reset the demod code, which might have been */ /* false-triggered by the commands from the reader. */ - DemodReset(); + Demod14aReset(); LED_B_OFF(); } - ReaderIsActive = (uart->state != STATE_UNSYNCD); + ReaderIsActive = (uart->state != STATE_14A_UNSYNCD); } // no need to try decoding tag data if the reader is sending - and we cannot afford the time @@ -176,13 +187,13 @@ void RAMFUNC SniffAndStore(uint8_t param) { triggered = true; // ready to receive another response. - DemodReset(); + Demod14aReset(); // reset the Miller decoder including its (now outdated) input buffer - UartReset(); + Uart14aReset(); // UartInit(receivedCmd, receivedCmdPar); LED_C_OFF(); } - TagIsActive = (demod->state != DEMOD_UNSYNCD); + TagIsActive = (demod->state != DEMOD_14A_UNSYNCD); } } diff --git a/armsrc/Standalone/hf_bog.h b/armsrc/Standalone/hf_bog.h deleted file mode 100644 index 50bdf2df8..000000000 --- a/armsrc/Standalone/hf_bog.h +++ /dev/null @@ -1,27 +0,0 @@ -//----------------------------------------------------------------------------- -// This code is licensed to you under the terms of the GNU GPL, version 2 or, -// at your option, any later version. See the LICENSE.txt file for the text of -// the license. -//----------------------------------------------------------------------------- -// StandAlone Mod -//----------------------------------------------------------------------------- - -#ifndef __HF_BOG_H -#define __HF_BOG_H - -#include "proxmark3.h" -#include "mifareutil.h" -#include "iso14443a.h" -#include "protocols.h" -#include "util.h" -#include "standalone.h" // standalone definitions -#include // for bool -#include -#include -#include "apps.h" -#include "printf.h" -#include "parity.h" -#include "spiffs.h" - - -#endif /* __HF_BOG_H */ diff --git a/armsrc/Standalone/hf_colin.c b/armsrc/Standalone/hf_colin.c index 1a461fe21..a45dd71c3 100644 --- a/armsrc/Standalone/hf_colin.c +++ b/armsrc/Standalone/hf_colin.c @@ -8,8 +8,27 @@ //----------------------------------------------------------------------------- // main code for HF Mifare aka ColinRun by Colin Brigato //----------------------------------------------------------------------------- +#include "standalone.h" // standalone definitions +#include // for bool +#include +#include #include "hf_colin.h" +#include "appmain.h" +#include "fpgaloader.h" +#include "dbprint.h" +#include "ticks.h" +#include "commonutil.h" +#include "crc16.h" +#include "BigBuf.h" #include "frozen.h" +#include "proxmark3_arm.h" +#include "mifaresim.h" // mifare1ksim +#include "mifareutil.h" +#include "iso14443a.h" +#include "util.h" +#include "vtsend.h" +#include "spiffs.h" +#include "string.h" #define MF1KSZ 1024 #define MF1KSZSIZE 64 diff --git a/armsrc/Standalone/hf_colin.h b/armsrc/Standalone/hf_colin.h index e669f0417..ca65a6df4 100644 --- a/armsrc/Standalone/hf_colin.h +++ b/armsrc/Standalone/hf_colin.h @@ -16,22 +16,6 @@ #ifndef __HF_COLIN_H #define __HF_COLIN_H -#include "proxmark3.h" -#include "mifaresim.h" // mifare1ksim -#include "mifareutil.h" -#include "iso14443a.h" -#include "protocols.h" -#include "util.h" -#include "pmflash.h" -#include "standalone.h" // standalone definitions -#include // for bool -#include -#include -#include "vtsend.h" -#include "apps.h" -#include "printf.h" -#include "spiffs.h" - #define _XRED_ "\x1b[31m" #define _XGREEN_ "\x1b[32m" #define _XYELLOW_ "\x1b[33m" diff --git a/armsrc/Standalone/hf_mattyrun.c b/armsrc/Standalone/hf_mattyrun.c index 485a7c072..bf13a39c0 100644 --- a/armsrc/Standalone/hf_mattyrun.c +++ b/armsrc/Standalone/hf_mattyrun.c @@ -33,7 +33,21 @@ on a blank card. ## Spanish full description of the project [here](http://bit.ly/2c9nZXR). */ -#include "hf_mattyrun.h" +#include "standalone.h" // standalone definitions +#include "proxmark3_arm.h" +#include "appmain.h" +#include "fpgaloader.h" +#include "util.h" +#include "dbprint.h" +#include "ticks.h" +#include "string.h" +#include "commonutil.h" +#include "iso14443a.h" +#include "mifarecmd.h" +#include "crc16.h" +#include "BigBuf.h" +#include "mifaresim.h" // mifare1ksim +#include "mifareutil.h" uint8_t uid[10]; uint32_t cuid; diff --git a/armsrc/Standalone/hf_mattyrun.h b/armsrc/Standalone/hf_mattyrun.h deleted file mode 100644 index 5577e298a..000000000 --- a/armsrc/Standalone/hf_mattyrun.h +++ /dev/null @@ -1,23 +0,0 @@ -//----------------------------------------------------------------------------- -// Matías A. Ré Medina 2016 -// Christian Herrmann, 2018 -// -// This code is licensed to you under the terms of the GNU GPL, version 2 or, -// at your option, any later version. See the LICENSE.txt file for the text of -// the license. -//----------------------------------------------------------------------------- -// StandAlone Mod -//----------------------------------------------------------------------------- - -#ifndef __HF_MATTYRUN_H -#define __HF_MATTYRUN_H - -#include "standalone.h" // standalone definitions -#include "apps.h" // debugstatements, lfops? -#include "pm3_cmd.h" // mifare1ksim flags -#include "mifaresim.h" // mifare1ksim -#include "mifareutil.h" - -#define OPTS 2 - -#endif /* __HF_MATTYRUN_H */ diff --git a/armsrc/Standalone/hf_young.c b/armsrc/Standalone/hf_young.c index 7948400ff..fcf964a5e 100644 --- a/armsrc/Standalone/hf_young.c +++ b/armsrc/Standalone/hf_young.c @@ -9,8 +9,21 @@ // main code for HF standalone mode Mifare /sniff/emulation by Craig Young //----------------------------------------------------------------------------- -#include "hf_young.h" -#include "common.h" +#include "standalone.h" // standalone definitions +#include +#include "proxmark3_arm.h" +#include "appmain.h" +#include "fpgaloader.h" +#include "util.h" +#include "dbprint.h" +#include "ticks.h" +#include "string.h" +#include "commonutil.h" +#include "mifarecmd.h" +#include "iso14443a.h" +#include "protocols.h" + +#define OPTS 2 typedef struct { uint8_t uid[10]; diff --git a/armsrc/Standalone/hf_young.h b/armsrc/Standalone/hf_young.h deleted file mode 100644 index dcd8b13e7..000000000 --- a/armsrc/Standalone/hf_young.h +++ /dev/null @@ -1,22 +0,0 @@ -//----------------------------------------------------------------------------- -// Craig Young 2014 -// Christian Herrmann, 2017 -// -// This code is licensed to you under the terms of the GNU GPL, version 2 or, -// at your option, any later version. See the LICENSE.txt file for the text of -// the license. -//----------------------------------------------------------------------------- -// StandAlone Mod -//----------------------------------------------------------------------------- - -#ifndef __HF_YOUNG_H -#define __HF_YOUNG_H - -#include // for bool -#include "standalone.h" // standalone definitions -#include "iso14443a.h" -#include "protocols.h" - -#define OPTS 2 - -#endif /* __HF_YOUNG_H */ diff --git a/armsrc/Standalone/lf_hidbrute.c b/armsrc/Standalone/lf_hidbrute.c index 2c784c31a..b659bbdf1 100644 --- a/armsrc/Standalone/lf_hidbrute.c +++ b/armsrc/Standalone/lf_hidbrute.c @@ -24,8 +24,19 @@ //----------------------------------------------------------------------------------- // main code for LF aka HID corporate brutefore by Federico Dotta & Maurizio Agazzini //----------------------------------------------------------------------------------- +#include "standalone.h" // standalone definitions #include "lf_hidbrute.h" +#include "proxmark3_arm.h" +#include "appmain.h" +#include "fpgaloader.h" +#include "util.h" +#include "dbprint.h" +#include "ticks.h" +#include "lfops.h" + +#define OPTS 3 + void ModInfo(void) { DbpString(" LF HID corporate 1000 bruteforce - aka Corporatebrute (Federico dotta & Maurizio Agazzini)"); } diff --git a/armsrc/Standalone/lf_hidbrute.h b/armsrc/Standalone/lf_hidbrute.h index 49b0af6c6..72e12d305 100644 --- a/armsrc/Standalone/lf_hidbrute.h +++ b/armsrc/Standalone/lf_hidbrute.h @@ -14,10 +14,7 @@ #ifndef __LF_HIDBRUTE_H #define __LF_HIDBRUTE_H -#include "standalone.h" // standalone definitions -#include "apps.h" // debugstatements, lfops? - -#define OPTS 3 +#include void hid_corporate_1000_calculate_checksum_and_set(uint32_t *high, uint32_t *low, uint32_t cardnum, uint32_t fc); diff --git a/armsrc/Standalone/lf_icerun.c b/armsrc/Standalone/lf_icerun.c index eafd4ca7d..dad74a75b 100644 --- a/armsrc/Standalone/lf_icerun.c +++ b/armsrc/Standalone/lf_icerun.c @@ -7,7 +7,12 @@ //----------------------------------------------------------------------------- // main code for skeleton aka IceRun by Iceman //----------------------------------------------------------------------------- -#include "lf_icerun.h" +#include "standalone.h" // standalone definitions +#include "proxmark3_arm.h" +#include "appmain.h" +#include "fpgaloader.h" +#include "util.h" +#include "dbprint.h" void ModInfo(void) { DbpString(" LF skeleton mode - aka IceRun (iceman)"); diff --git a/armsrc/Standalone/lf_proxbrute.c b/armsrc/Standalone/lf_proxbrute.c index 09ddb1989..8044cbde9 100644 --- a/armsrc/Standalone/lf_proxbrute.c +++ b/armsrc/Standalone/lf_proxbrute.c @@ -9,7 +9,16 @@ //----------------------------------------------------------------------------- // main code for LF aka Proxbrute by Brad antoniewicz //----------------------------------------------------------------------------- -#include "lf_proxbrute.h" +#include "standalone.h" // standalone definitions +#include "proxmark3_arm.h" +#include "appmain.h" +#include "fpgaloader.h" +#include "util.h" +#include "dbprint.h" +#include "ticks.h" +#include "lfops.h" + +#define OPTS 2 void ModInfo(void) { DbpString(" LF HID ProxII bruteforce - aka Proxbrute (Brad Antoniewicz)"); diff --git a/armsrc/Standalone/lf_samyrun.c b/armsrc/Standalone/lf_samyrun.c index 07fe8bae5..8228db512 100644 --- a/armsrc/Standalone/lf_samyrun.c +++ b/armsrc/Standalone/lf_samyrun.c @@ -8,7 +8,16 @@ //----------------------------------------------------------------------------- // main code for LF aka SamyRun by Samy Kamkar //----------------------------------------------------------------------------- -#include "lf_samyrun.h" +#include "standalone.h" // standalone definitions +#include "proxmark3_arm.h" +#include "appmain.h" +#include "fpgaloader.h" +#include "lfops.h" +#include "util.h" +#include "dbprint.h" +#include "ticks.h" + +#define OPTS 2 void ModInfo(void) { DbpString(" LF HID26 standalone - aka SamyRun (Samy Kamkar)"); diff --git a/armsrc/Standalone/lf_samyrun.h b/armsrc/Standalone/lf_samyrun.h deleted file mode 100644 index 52c0bb942..000000000 --- a/armsrc/Standalone/lf_samyrun.h +++ /dev/null @@ -1,22 +0,0 @@ -//----------------------------------------------------------------------------- -// Samy Kamkar 2012 -// Christian Herrmann, 2017 -// -// This code is licensed to you under the terms of the GNU GPL, version 2 or, -// at your option, any later version. See the LICENSE.txt file for the text of -// the license. -//----------------------------------------------------------------------------- -// StandAlone Mod -//----------------------------------------------------------------------------- - -#ifndef __LF_SAMYRUN_H -#define __LF_SAMYRUN_H - -//#include // for bool -#include "standalone.h" // standalone definitions -#include "apps.h" // debugstatements, lfops? - - -#define OPTS 2 - -#endif /* __LF_SAMYRUN_H */ diff --git a/armsrc/Standalone/placeholder.c b/armsrc/Standalone/placeholder.c index b8a426e37..84f724920 100644 --- a/armsrc/Standalone/placeholder.c +++ b/armsrc/Standalone/placeholder.c @@ -1,5 +1,6 @@ #include "standalone.h" // standalone definitions -#include "apps.h" // debug statements + +#include "dbprint.h" void ModInfo(void) { DbpString(" No standalone mode present"); diff --git a/armsrc/Standalone/standalone.h b/armsrc/Standalone/standalone.h index 217c7b4cf..2dd35e94a 100644 --- a/armsrc/Standalone/standalone.h +++ b/armsrc/Standalone/standalone.h @@ -11,9 +11,6 @@ #ifndef __STANDALONE_H #define __STANDALONE_H -#include // for bool -#include // PRIu64 - void RunMod(); void ModInfo(); diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 8f65bc892..f163e579b 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -9,26 +9,37 @@ // The main application code. This is the first thing called after start.c // executes. //----------------------------------------------------------------------------- -#include -#include +#include "appmain.h" + #include "usb_cdc.h" -#include "proxmark3.h" +#include "proxmark3_arm.h" +#include "dbprint.h" #include "pmflash.h" -#include "apps.h" #include "fpga.h" -#include "util.h" -#include "printf.h" +#include "fpgaloader.h" #include "string.h" #include "legicrf.h" -#include "legicrfsim.h" -#include "lfsampling.h" #include "BigBuf.h" -#include "mifareutil.h" -#include "mifaresim.h" -#include "hitag.h" +#include "iso14443a.h" +#include "iso14443b.h" +#include "iso15693.h" #include "thinfilm.h" - -#define DEBUG 1 +#include "felica.h" +#include "hitag2.h" +#include "hitagS.h" +#include "iclass.h" +#include "legicrfsim.h" +#include "epa.h" +#include "hfsnoop.h" +#include "lfops.h" +#include "lfsampling.h" +#include "mifarecmd.h" +#include "mifaredesfire.h" +#include "mifaresim.h" +#include "pcf7931.h" +#include "Standalone/standalone.h" +#include "util.h" +#include "ticks.h" #ifdef WITH_LCD #include "LCD.h" @@ -61,6 +72,12 @@ struct common_area common_area __attribute__((section(".commonarea"))); int button_status = BUTTON_NO_CLICK; bool allow_send_wtx = false; +inline void send_wtx(uint16_t wtx) { + if (allow_send_wtx) { + reply_ng(CMD_WTX, PM3_SUCCESS, (uint8_t *)&wtx, sizeof(wtx)); + } +} + void ToSendReset(void) { ToSendMax = -1; ToSendBit = 8; @@ -84,128 +101,6 @@ void ToSendStuffBit(int b) { } } -/* useful when debugging new protocol implementations like FeliCa -void PrintToSendBuffer(void) { - DbpString("Printing ToSendBuffer:"); - Dbhexdump(ToSendMax, ToSend, 0); -} -*/ - -void print_result(char *name, uint8_t *buf, size_t len) { - - uint8_t *p = buf; - uint16_t tmp = len & 0xFFF0; - - for (; p - buf < tmp; p += 16) { - Dbprintf("[%s: %02d/%02d] %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", - name, - p - buf, - len, - p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15] - ); - } - if (len % 16 != 0) { - char s[46] = {0}; - char *sp = s; - for (; p - buf < len; p++) { - sprintf(sp, "%02x ", p[0]); - sp += 3; - } - Dbprintf("[%s: %02d/%02d] %s", name, p - buf, len, s); - } -} - -//============================================================================= -// Debug print functions, to go out over USB, to the usual PC-side client. -//============================================================================= - -inline void send_wtx(uint16_t wtx) { - if (allow_send_wtx) { - reply_ng(CMD_WTX, PM3_SUCCESS, (uint8_t *)&wtx, sizeof(wtx)); - } -} - -void DbpStringEx(uint32_t flags, char *str) { -#if DEBUG - struct { - uint16_t flag; - uint8_t buf[PM3_CMD_DATA_SIZE - sizeof(uint16_t)]; - } PACKED data; - data.flag = flags; - uint16_t len = MIN(strlen(str), sizeof(data.buf)); - memcpy(data.buf, str, len); - reply_ng(CMD_DEBUG_PRINT_STRING, PM3_SUCCESS, (uint8_t *)&data, sizeof(data.flag) + len); -#endif -} - -void DbpString(char *str) { -#if DEBUG - DbpStringEx(FLAG_LOG, str); -#endif -} - -#if 0 -void DbpIntegers(int x1, int x2, int x3) { - reply_old(CMD_DEBUG_PRINT_INTEGERS, x1, x2, x3, 0, 0); -} -#endif -void DbprintfEx(uint32_t flags, const char *fmt, ...) { -#if DEBUG - // should probably limit size here; oh well, let's just use a big buffer - char output_string[128] = {0x00}; - va_list ap; - va_start(ap, fmt); - kvsprintf(fmt, output_string, 10, ap); - va_end(ap); - - DbpStringEx(flags, output_string); -#endif -} - -void Dbprintf(const char *fmt, ...) { -#if DEBUG - // should probably limit size here; oh well, let's just use a big buffer - char output_string[128] = {0x00}; - va_list ap; - - va_start(ap, fmt); - kvsprintf(fmt, output_string, 10, ap); - va_end(ap); - - DbpString(output_string); -#endif -} - -// prints HEX & ASCII -void Dbhexdump(int len, uint8_t *d, bool bAsci) { -#if DEBUG - char ascii[9]; - - while (len > 0) { - - int l = (len > 8) ? 8 : len; - - memcpy(ascii, d, l); - ascii[l] = 0; - - // filter safe ascii - for (int i = 0; i < l; i++) { - if (ascii[i] < 32 || ascii[i] > 126) { - ascii[i] = '.'; - } - } - - if (bAsci) - Dbprintf("%-8s %*D", ascii, l, d, " "); - else - Dbprintf("%*D", l, d, " "); - - len -= 8; - d += 8; - } -#endif -} - //----------------------------------------------------------------------------- // Read an ADC channel and block till it completes, then return the result // in ADC units (0 to 1023). Also a routine to average 32 samples and diff --git a/armsrc/appmain.h b/armsrc/appmain.h new file mode 100644 index 000000000..fa35714e3 --- /dev/null +++ b/armsrc/appmain.h @@ -0,0 +1,45 @@ +//----------------------------------------------------------------------------- +// Jonathan Westhues, Aug 2005 +// Gerhard de Koning Gans, April 2008, May 2011 +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// Definitions internal to the app source. +//----------------------------------------------------------------------------- +#ifndef __APPMAIN_H +#define __APPMAIN_H + +#include "common.h" + +extern const uint8_t OddByteParity[256]; +extern int rsamples; // = 0; +extern uint8_t trigger; +extern bool allow_send_wtx; + +// ADC Vref = 3300mV, and an (10M+1M):1M voltage divider on the HF input can measure voltages up to 36300 mV +#define MAX_ADC_HF_VOLTAGE 36300 +// ADC Vref = 3300mV, (240k-10M):240k voltage divider, 140800 mV +#define MAX_ADC_HF_VOLTAGE_RDV40 140800 +// ADC Vref = 3300mV, and an (10000k+240k):240k voltage divider on the LF input can measure voltages up to 140800 mV +#define MAX_ADC_LF_VOLTAGE 140800 + +extern int ToSendMax; +extern uint8_t ToSend[]; + +void send_wtx(uint16_t wtx); +void ReadMem(int addr); +void __attribute__((noreturn)) AppMain(void); + +uint16_t AvgAdc(int ch); + +void print_result(char *name, uint8_t *buf, size_t len); +//void PrintToSendBuffer(void); +void ToSendStuffBit(int b); +void ToSendReset(void); +void ListenReaderField(uint8_t limit); +void StandAloneMode(void); +void printStandAloneModes(void); + +#endif diff --git a/armsrc/apps.h b/armsrc/apps.h deleted file mode 100644 index 7cc401857..000000000 --- a/armsrc/apps.h +++ /dev/null @@ -1,254 +0,0 @@ -//----------------------------------------------------------------------------- -// Jonathan Westhues, Aug 2005 -// Gerhard de Koning Gans, April 2008, May 2011 -// -// This code is licensed to you under the terms of the GNU GPL, version 2 or, -// at your option, any later version. See the LICENSE.txt file for the text of -// the license. -//----------------------------------------------------------------------------- -// Definitions internal to the app source. -//----------------------------------------------------------------------------- -#ifndef __APPS_H -#define __APPS_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include -#include "common.h" -#include "usb_cdc.h" -#include "crc32.h" -#include "lfdemod.h" -#include "BigBuf.h" -#include "fpgaloader.h" -#include "hitag2.h" -#include "hitagS.h" -#include "mifare.h" -#include "pcf7931.h" -#include "desfire.h" -#include "iso14443b.h" -#include "Standalone/standalone.h" -#include "flashmem.h" - -extern const uint8_t OddByteParity[256]; -extern int rsamples; // = 0; -extern uint8_t trigger; - -// This may be used (sparingly) to declare a function to be copied to -// and executed from RAM -#define RAMFUNC __attribute((long_call, section(".ramfunc"))) - -/// appmain.h -void ReadMem(int addr); -void __attribute__((noreturn)) AppMain(void); -void send_wtx(uint16_t wtx); -//void DbpIntegers(int a, int b, int c); -void DbpString(char *str); -void DbpStringEx(uint32_t flags, char *str); -void Dbprintf(const char *fmt, ...); -void DbprintfEx(uint32_t flags, const char *fmt, ...); -void Dbhexdump(int len, uint8_t *d, bool bAsci); - -// ADC Vref = 3300mV, and an (10M+1M):1M voltage divider on the HF input can measure voltages up to 36300 mV -#define MAX_ADC_HF_VOLTAGE 36300 -// ADC Vref = 3300mV, (240k-10M):240k voltage divider, 140800 mV -#define MAX_ADC_HF_VOLTAGE_RDV40 140800 -// ADC Vref = 3300mV, and an (10000k+240k):240k voltage divider on the LF input can measure voltages up to 140800 mV -#define MAX_ADC_LF_VOLTAGE 140800 -uint16_t AvgAdc(int ch); - -void print_result(char *name, uint8_t *buf, size_t len); -//void PrintToSendBuffer(void); -void ToSendStuffBit(int b); -void ToSendReset(void); -void ListenReaderField(uint8_t limit); -extern int ToSendMax; -extern uint8_t ToSend[]; - -void StandAloneMode(void); -void printStandAloneModes(void); - -/// lfops.h -extern uint8_t decimation; -extern uint8_t bits_per_sample ; -extern bool averaging; - -void AcquireRawAdcSamples125k(int divisor); -void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint32_t period_1, uint8_t *command); -void ReadTItag(void); -void WriteTItag(uint32_t idhi, uint32_t idlo, uint16_t crc); - -void AcquireTiType(void); -void AcquireRawBitsTI(void); -void SimulateTagLowFrequencyEx(int period, int gap, bool ledcontrol, int numcycles); -void SimulateTagLowFrequency(int period, int gap, bool ledcontrol); -void SimulateTagLowFrequencyBidir(int divisor, int max_bitlen); - -void CmdHIDsimTAGEx(uint32_t hi, uint32_t lo, bool ledcontrol, int numcycles); -void CmdHIDsimTAG(uint32_t hi, uint32_t lo, bool ledcontrol); - -void CmdFSKsimTAG(uint8_t fchigh, uint8_t fclow, uint8_t separator, uint8_t clk, uint16_t bitslen, uint8_t *bits, bool ledcontrol); -void CmdASKsimTAG(uint8_t encoding, uint8_t invert, uint8_t separator, uint8_t clk, uint16_t size, uint8_t *bits, bool ledcontrol); -void CmdPSKsimTag(uint8_t carrier, uint8_t invert, uint8_t clk, uint16_t size, uint8_t *bits, bool ledcontrol); - -void CmdHIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol); -void CmdAWIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol); // Realtime demodulation mode for AWID26 -void CmdEM410xdemod(int findone, uint32_t *high, uint64_t *low, int ledcontrol); -void CmdIOdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol); -void CopyIOtoT55x7(uint32_t hi, uint32_t lo); // Clone an ioProx card to T5557/T5567 -void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT); // Clone an HID card to T5557/T5567 -void CopyVikingtoT55xx(uint32_t block1, uint32_t block2, uint8_t Q5); -void WriteEM410x(uint32_t card, uint32_t id_hi, uint32_t id_lo); -void CopyIndala64toT55x7(uint32_t hi, uint32_t lo); // Clone Indala 64-bit tag by UID to T55x7 -void CopyIndala224toT55x7(uint32_t uid1, uint32_t uid2, uint32_t uid3, uint32_t uid4, uint32_t uid5, uint32_t uid6, uint32_t uid7); // Clone Indala 224-bit tag by UID to T55x7 -void T55xxResetRead(uint8_t flags); -//id T55xxWriteBlock(uint32_t data, uint8_t blockno, uint32_t pwd, uint8_t flags); -void T55xxWriteBlock(uint8_t *data); -// void T55xxWriteBlockExt(uint32_t data, uint8_t blockno, uint32_t pwd, uint8_t flags); -void T55xxReadBlock(uint8_t page, bool pwd_mode, bool brute_mem, uint8_t block, uint32_t pwd, uint8_t downlink_mode); -void T55xxWakeUp(uint32_t pwd, uint8_t flags); -void T55xx_ChkPwds(uint8_t flags); - -void TurnReadLFOn(uint32_t delay); - -void EM4xReadWord(uint8_t addr, uint32_t pwd, uint8_t usepwd); -void EM4xWriteWord(uint8_t addr, uint32_t data, uint32_t pwd, uint8_t usepwd); - -void Cotag(uint32_t arg0); -void setT55xxConfig(uint8_t arg0, t55xx_configurations_t *c); -t55xx_configurations_t *getT55xxConfig(void); -void printT55xxConfig(void); -void loadT55xxConfig(void); - -/// iso14443b.h -void SimulateIso14443bTag(uint32_t pupi); -void AcquireRawAdcSamplesIso14443b(uint32_t parameter); -void ReadSTMemoryIso14443b(uint8_t numofblocks); -void RAMFUNC SniffIso14443b(void); -void SendRawCommand14443B(uint32_t, uint32_t, uint8_t, uint8_t[]); -void SendRawCommand14443B_Ex(PacketCommandNG *c); -void ClearFpgaShiftingRegisters(void); - -// iso14443a.h -void RAMFUNC SniffIso14443a(uint8_t param); -void ReaderIso14443a(PacketCommandNG *c); - -// Also used in iclass.c -//bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t len, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag); -void GetParity(const uint8_t *pbtCmd, uint16_t len, uint8_t *par); -void iso14a_set_trigger(bool enable); -// also used in emv -//bool prepare_allocated_tag_modulation(tag_response_info_t *response_info); -//int GetIso14443aCommandFromReader(uint8_t *received, uint8_t *parity, int *len); - -// epa.h -void EPA_PACE_Collect_Nonce(PacketCommandNG *c); -void EPA_PACE_Replay(PacketCommandNG *c); - -// mifarecmd.h -void MifareReadBlock(uint8_t blockNo, uint8_t keyType, uint8_t *datain); - -void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain); -void MifareUC_Auth(uint8_t arg0, uint8_t *keybytes); -void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain); -void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t *datain); -void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain); -//void MifareUWriteBlockCompat(uint8_t arg0,uint8_t *datain); -void MifareUWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain); -void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain); -void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, uint8_t *datain); -void MifareAcquireNonces(uint32_t arg0, uint32_t flags); -void MifareChkKeys(uint8_t *datain); -void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain); - -void MifareEMemClr(void); -void MifareEMemSet(uint8_t blockno, uint8_t blockcnt, uint8_t blockwidth, uint8_t *datain); -void MifareEMemGet(uint8_t blockno, uint8_t blockcnt); -int MifareECardLoad(uint32_t arg0, uint32_t arg1); - -void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain); // Work with "magic Chinese" card -void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain); -void MifareCIdent(); // is "magic chinese" card? - -void MifareSetMod(uint8_t *datain); -void MifareUSetPwd(uint8_t arg0, uint8_t *datain); -void OnSuccessMagic(); -void OnErrorMagic(uint8_t reason); - -int32_t dist_nt(uint32_t nt1, uint32_t nt2); -void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype); -//void RAMFUNC SniffMifare(uint8_t param); - -//desfire -void Mifare_DES_Auth1(uint8_t arg0, uint8_t *datain); -void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain); - -// mifaredesfire.h -bool InitDesfireCard(); -void MifareSendCommand(uint8_t arg0, uint8_t arg1, uint8_t *datain); -void MifareDesfireGetInformation(); -void MifareDES_Auth1(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain); -void ReaderMifareDES(uint32_t param, uint32_t param2, uint8_t *datain); -int DesfireAPDU(uint8_t *cmd, size_t cmd_len, uint8_t *dataout); -size_t CreateAPDU(uint8_t *datain, size_t len, uint8_t *dataout); -void OnSuccess(); -void OnError(uint8_t reason); - -// desfire_crypto.h -void *mifare_cryto_preprocess_data(desfiretag_t tag, void *data, size_t *nbytes, size_t offset, int communication_settings); -void *mifare_cryto_postprocess_data(desfiretag_t tag, void *data, size_t *nbytes, int communication_settings); -void mifare_cypher_single_block(desfirekey_t key, uint8_t *data, uint8_t *ivect, MifareCryptoDirection direction, MifareCryptoOperation operation, size_t block_size); -void mifare_cypher_blocks_chained(desfiretag_t tag, desfirekey_t key, uint8_t *ivect, uint8_t *data, size_t data_size, MifareCryptoDirection direction, MifareCryptoOperation operation); -size_t key_block_size(const desfirekey_t key); -size_t padded_data_length(const size_t nbytes, const size_t block_size); -size_t maced_data_length(const desfirekey_t key, const size_t nbytes); -size_t enciphered_data_length(const desfiretag_t tag, const size_t nbytes, int communication_settings); -void cmac_generate_subkeys(desfirekey_t key); -void cmac(const desfirekey_t key, uint8_t *ivect, const uint8_t *data, size_t len, uint8_t *cmac); - -// iso15693.h -void RecordRawAdcSamplesIso15693(void); -void AcquireRawAdcSamplesIso15693(void); -void ReaderIso15693(uint32_t parameter); // Simulate an ISO15693 reader - greg -void SimTagIso15693(uint32_t parameter, uint8_t *uid); // simulate an ISO15693 tag - greg -void BruteforceIso15693Afi(uint32_t speed); // find an AFI of a tag - atrox -void DirectTag15693Command(uint32_t datalen, uint32_t speed, uint32_t recv, uint8_t *data); // send arbitrary commands from CLI - atrox -void Iso15693InitReader(void); - -// iclass.h -void RAMFUNC SniffIClass(void); -void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain); -void ReaderIClass(uint8_t arg0); -void ReaderIClass_Replay(uint8_t arg0, uint8_t *mac); -void iClass_Authentication(uint8_t *mac); -void iClass_Authentication_fast(uint64_t arg0, uint64_t arg1, uint8_t *datain); -void iClass_WriteBlock(uint8_t blockno, uint8_t *data); -void iClass_ReadBlk(uint8_t blockno); -bool iClass_ReadBlock(uint8_t blockno, uint8_t *data, uint8_t len); -void iClass_Dump(uint8_t blockno, uint8_t numblks); -void iClass_Clone(uint8_t startblock, uint8_t endblock, uint8_t *data); -void iClass_ReadCheck(uint8_t blockno, uint8_t keytype); - -// cmd.h -int reply_old(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len); -int reply_mix(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len); -int reply_ng(uint16_t cmd, int16_t status, uint8_t *data, size_t len); -int receive_ng(PacketCommandNG *rx); - -// util.h -void HfSniff(int, int); - -//felica.c -void felica_sendraw(PacketCommandNG *c); -void felica_sniff(uint32_t samplesToSkip, uint32_t triggersToSkip); -void felica_sim_lite(uint64_t uid); -void felica_dump_lite_s(); - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/armsrc/buzzer.c b/armsrc/buzzer_disabled.c similarity index 100% rename from armsrc/buzzer.c rename to armsrc/buzzer_disabled.c diff --git a/armsrc/buzzer.h b/armsrc/buzzer_disabled.h similarity index 84% rename from armsrc/buzzer.h rename to armsrc/buzzer_disabled.h index 082450f04..c8b6e4472 100644 --- a/armsrc/buzzer.h +++ b/armsrc/buzzer_disabled.h @@ -5,10 +5,7 @@ #ifndef __BUZZER_H #define __BUZZER_H -#include -#include "proxmark3.h" -#include "apps.h" -#include "util.h" +#include "common.h" #define n_2_7khz 185 #define note_1 956 @@ -27,24 +24,3 @@ void Ring_ALL(uint16_t count); void Ring_Little_Star(uint16_t count); #endif - - - - - - - - - - - - - - - - - - - - - diff --git a/common/cmd.c b/armsrc/cmd.c similarity index 99% rename from common/cmd.c rename to armsrc/cmd.c index 6af0437d1..4b6dd3c1c 100644 --- a/common/cmd.c +++ b/armsrc/cmd.c @@ -30,7 +30,10 @@ * @brief */ #include "cmd.h" +#include "usb_cdc.h" +#include "usart.h" #include "crc16.h" +#include "string.h" // Flags to tell where to add CRC on sent replies bool reply_with_crc_on_usb = false; diff --git a/common/cmd.h b/armsrc/cmd.h similarity index 71% rename from common/cmd.h rename to armsrc/cmd.h index 261a1e1a0..e04f397a3 100644 --- a/common/cmd.h +++ b/armsrc/cmd.h @@ -35,14 +35,6 @@ #include "common.h" #include "pm3_cmd.h" -#include "usb_cdc.h" -#include "usart.h" -#include "proxmark3.h" - -int reply_old(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len); -int reply_ng(uint16_t cmd, int16_t status, uint8_t *data, size_t len); -int reply_mix(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len); -int receive_ng(PacketCommandNG *rx); // Flags to tell where to add CRC on sent replies extern bool reply_with_crc_on_usb; @@ -51,33 +43,10 @@ extern bool reply_with_crc_on_fpc; extern bool reply_via_fpc; extern bool reply_via_usb; -extern void Dbprintf(const char *fmt, ...); -#define Dbprintf_usb(...) {\ - bool tmpfpc = reply_via_fpc;\ - bool tmpusb = reply_via_usb;\ - reply_via_fpc = false;\ - reply_via_usb = true;\ - Dbprintf(__VA_ARGS__);\ - reply_via_fpc = tmpfpc;\ - reply_via_usb = tmpusb;} - -#define Dbprintf_fpc(...) {\ - bool tmpfpc = reply_via_fpc;\ - bool tmpusb = reply_via_usb;\ - reply_via_fpc = true;\ - reply_via_usb = false;\ - Dbprintf(__VA_ARGS__);\ - reply_via_fpc = tmpfpc;\ - reply_via_usb = tmpusb;} - -#define Dbprintf_all(...) {\ - bool tmpfpc = reply_via_fpc;\ - bool tmpusb = reply_via_usb;\ - reply_via_fpc = true;\ - reply_via_usb = true;\ - Dbprintf(__VA_ARGS__);\ - reply_via_fpc = tmpfpc;\ - reply_via_usb = tmpusb;} +int reply_old(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len); +int reply_ng(uint16_t cmd, int16_t status, uint8_t *data, size_t len); +int reply_mix(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len); +int receive_ng(PacketCommandNG *rx); #endif // _PROXMARK_CMD_H_ diff --git a/armsrc/dbprint.c b/armsrc/dbprint.c new file mode 100644 index 000000000..a26b7ba8b --- /dev/null +++ b/armsrc/dbprint.c @@ -0,0 +1,130 @@ +//----------------------------------------------------------------------------- +// Jonathan Westhues, Mar 2006 +// Edits by Gerhard de Koning Gans, Sep 2007 (##) +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// The main application code. This is the first thing called after start.c +// executes. +//----------------------------------------------------------------------------- + +#include "dbprint.h" + +#include "string.h" +#include "cmd.h" +#include "printf.h" + +#define DEBUG 1 + +//============================================================================= +// Debug print functions, to go out over USB, to the usual PC-side client. +//============================================================================= + +void DbpStringEx(uint32_t flags, char *str) { +#if DEBUG + struct { + uint16_t flag; + uint8_t buf[PM3_CMD_DATA_SIZE - sizeof(uint16_t)]; + } PACKED data; + data.flag = flags; + uint16_t len = MIN(strlen(str), sizeof(data.buf)); + memcpy(data.buf, str, len); + reply_ng(CMD_DEBUG_PRINT_STRING, PM3_SUCCESS, (uint8_t *)&data, sizeof(data.flag) + len); +#endif +} + +void DbpString(char *str) { +#if DEBUG + DbpStringEx(FLAG_LOG, str); +#endif +} + +void DbprintfEx(uint32_t flags, const char *fmt, ...) { +#if DEBUG + // should probably limit size here; oh well, let's just use a big buffer + char output_string[128] = {0x00}; + va_list ap; + va_start(ap, fmt); + kvsprintf(fmt, output_string, 10, ap); + va_end(ap); + + DbpStringEx(flags, output_string); +#endif +} + +void Dbprintf(const char *fmt, ...) { +#if DEBUG + // should probably limit size here; oh well, let's just use a big buffer + char output_string[128] = {0x00}; + va_list ap; + + va_start(ap, fmt); + kvsprintf(fmt, output_string, 10, ap); + va_end(ap); + + DbpString(output_string); +#endif +} + +// prints HEX & ASCII +void Dbhexdump(int len, uint8_t *d, bool bAsci) { +#if DEBUG + char ascii[9]; + + while (len > 0) { + + int l = (len > 8) ? 8 : len; + + memcpy(ascii, d, l); + ascii[l] = 0; + + // filter safe ascii + for (int i = 0; i < l; i++) { + if (ascii[i] < 32 || ascii[i] > 126) { + ascii[i] = '.'; + } + } + + if (bAsci) + Dbprintf("%-8s %*D", ascii, l, d, " "); + else + Dbprintf("%*D", l, d, " "); + + len -= 8; + d += 8; + } +#endif +} + +void print_result(char *name, uint8_t *buf, size_t len) { + + uint8_t *p = buf; + uint16_t tmp = len & 0xFFF0; + + for (; p - buf < tmp; p += 16) { + Dbprintf("[%s: %02d/%02d] %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", + name, + p - buf, + len, + p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15] + ); + } + if (len % 16 != 0) { + char s[46] = {0}; + char *sp = s; + for (; p - buf < len; p++) { + sprintf(sp, "%02x ", p[0]); + sp += 3; + } + Dbprintf("[%s: %02d/%02d] %s", name, p - buf, len, s); + } +} + +/* useful when debugging new protocol implementations like FeliCa +void PrintToSendBuffer(void) { + DbpString("Printing ToSendBuffer:"); + Dbhexdump(ToSendMax, ToSend, 0); +} +*/ diff --git a/armsrc/dbprint.h b/armsrc/dbprint.h new file mode 100644 index 000000000..54b813218 --- /dev/null +++ b/armsrc/dbprint.h @@ -0,0 +1,53 @@ +//----------------------------------------------------------------------------- +// Jonathan Westhues, Aug 2005 +// Gerhard de Koning Gans, April 2008, May 2011 +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// Definitions internal to the app source. +//----------------------------------------------------------------------------- +#ifndef __DBPRINT_H +#define __DBPRINT_H + +#include "common.h" +#include "ansi.h" + +#define Dbprintf_usb(...) {\ + bool tmpfpc = reply_via_fpc;\ + bool tmpusb = reply_via_usb;\ + reply_via_fpc = false;\ + reply_via_usb = true;\ + Dbprintf(__VA_ARGS__);\ + reply_via_fpc = tmpfpc;\ + reply_via_usb = tmpusb;} + +#define Dbprintf_fpc(...) {\ + bool tmpfpc = reply_via_fpc;\ + bool tmpusb = reply_via_usb;\ + reply_via_fpc = true;\ + reply_via_usb = false;\ + Dbprintf(__VA_ARGS__);\ + reply_via_fpc = tmpfpc;\ + reply_via_usb = tmpusb;} + +#define Dbprintf_all(...) {\ + bool tmpfpc = reply_via_fpc;\ + bool tmpusb = reply_via_usb;\ + reply_via_fpc = true;\ + reply_via_usb = true;\ + Dbprintf(__VA_ARGS__);\ + reply_via_fpc = tmpfpc;\ + reply_via_usb = tmpusb;} + + +void DbpString(char *str); +void DbpStringEx(uint32_t flags, char *str); +void Dbprintf(const char *fmt, ...); +void DbprintfEx(uint32_t flags, const char *fmt, ...); +void Dbhexdump(int len, uint8_t *d, bool bAsci); +void print_result(char *name, uint8_t *buf, size_t len); +//void PrintToSendBuffer(void); + +#endif diff --git a/armsrc/des.c b/armsrc/des.c index 41b30734c..b84bc4c30 100644 --- a/armsrc/des.c +++ b/armsrc/des.c @@ -27,6 +27,7 @@ */ #include "des.h" +#include "string.h" const uint8_t sbox[256] = { /* S-box 1 */ diff --git a/armsrc/des.h b/armsrc/des.h index 0d2cceefb..8cf41b8ae 100644 --- a/armsrc/des.h +++ b/armsrc/des.h @@ -27,8 +27,7 @@ #ifndef __DES_H_ #define __DES_H_ -#include -#include +#include "common.h" /* the FIPS 46-3 (1999-10-25) name for triple DES is triple data encryption algorithm so TDEA. * Also we only implement the three key mode */ diff --git a/common/desfire.h b/armsrc/desfire.h similarity index 98% rename from common/desfire.h rename to armsrc/desfire.h index 41e5b6e12..5fa7e8d48 100644 --- a/common/desfire.h +++ b/armsrc/desfire.h @@ -1,9 +1,7 @@ #ifndef __DESFIRE_H #define __DESFIRE_H -#include -#include -#include "mbedtls/aes.h" +#include "common.h" #include "mifare.h" #define MAX_CRYPTO_BLOCK_SIZE 16 diff --git a/armsrc/desfire_crypto.h b/armsrc/desfire_crypto.h deleted file mode 100644 index 9964d094f..000000000 --- a/armsrc/desfire_crypto.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef __DESFIRE_CRYPTO_H -#define __DESFIRE_CRYPTO_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include "crc32.h" -#include "printf.h" -#include "desfire.h" -#include "iso14443a.h" - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/armsrc/desfire_crypto.c b/armsrc/desfire_crypto_disabled.c similarity index 99% rename from armsrc/desfire_crypto.c rename to armsrc/desfire_crypto_disabled.c index 2e9d5a8d3..d835a55d4 100644 --- a/armsrc/desfire_crypto.c +++ b/armsrc/desfire_crypto_disabled.c @@ -25,8 +25,16 @@ * Recommendation for Block Cipher Modes of Operation: The CMAC Mode for Authentication * May 2005 */ +#include + #include "desfire_crypto.h" +#include "crc32.h" +#include "printf.h" +#include "desfire.h" +#include "iso14443a.h" +#include "mbedtls/aes.h" + static void xor(const uint8_t *ivect, uint8_t *data, const size_t len); static size_t key_macing_length(desfirekey_t key); diff --git a/armsrc/desfire_crypto_disabled.h b/armsrc/desfire_crypto_disabled.h new file mode 100644 index 000000000..23043b30d --- /dev/null +++ b/armsrc/desfire_crypto_disabled.h @@ -0,0 +1,18 @@ +#ifndef __DESFIRE_CRYPTO_H +#define __DESFIRE_CRYPTO_H + +#include "common.h" +#include "desfire.h" + +void *mifare_cryto_preprocess_data(desfiretag_t tag, void *data, size_t *nbytes, size_t offset, int communication_settings); +void *mifare_cryto_postprocess_data(desfiretag_t tag, void *data, size_t *nbytes, int communication_settings); +void mifare_cypher_single_block(desfirekey_t key, uint8_t *data, uint8_t *ivect, MifareCryptoDirection direction, MifareCryptoOperation operation, size_t block_size); +void mifare_cypher_blocks_chained(desfiretag_t tag, desfirekey_t key, uint8_t *ivect, uint8_t *data, size_t data_size, MifareCryptoDirection direction, MifareCryptoOperation operation); +size_t key_block_size(const desfirekey_t key); +size_t padded_data_length(const size_t nbytes, const size_t block_size); +size_t maced_data_length(const desfirekey_t key, const size_t nbytes); +size_t enciphered_data_length(const desfiretag_t tag, const size_t nbytes, int communication_settings); +void cmac_generate_subkeys(desfirekey_t key); +void cmac(const desfirekey_t key, uint8_t *ivect, const uint8_t *data, size_t len, uint8_t *cmac); + +#endif diff --git a/armsrc/desfire_key.c b/armsrc/desfire_key.c index e1f880c8b..272f18562 100644 --- a/armsrc/desfire_key.c +++ b/armsrc/desfire_key.c @@ -18,6 +18,7 @@ */ #include "desfire_key.h" +#include "string.h" static inline void update_key_schedules(desfirekey_t key); diff --git a/armsrc/desfire_key.h b/armsrc/desfire_key.h index 4fc02854e..603fd5663 100644 --- a/armsrc/desfire_key.h +++ b/armsrc/desfire_key.h @@ -1,11 +1,8 @@ #ifndef __DESFIRE_KEY_INCLUDED #define __DESFIRE_KEY_INCLUDED -#include -#include -#include "iso14443a.h" +#include "common.h" #include "desfire.h" -//#include "mifare.h" // iso14a_card_select_t struct void Desfire_des_key_new(const uint8_t value[8], desfirekey_t key); void Desfire_3des_key_new(const uint8_t value[16], desfirekey_t key); void Desfire_des_key_new_with_version(const uint8_t value[8], desfirekey_t key); @@ -17,4 +14,5 @@ void Desfire_aes_key_new_with_version(const uint8_t value[16], uint8_t version, uint8_t Desfire_key_get_version(desfirekey_t key); void Desfire_key_set_version(desfirekey_t key, uint8_t version); void Desfire_session_key_new(const uint8_t rnda[], const uint8_t rndb[], desfirekey_t authkey, desfirekey_t key); + #endif diff --git a/common/emvtags.h b/armsrc/emvtags.h similarity index 99% rename from common/emvtags.h rename to armsrc/emvtags.h index 9315258fc..c64b248a3 100644 --- a/common/emvtags.h +++ b/armsrc/emvtags.h @@ -12,8 +12,7 @@ #ifndef __EMVCARD_H #define __EMVCARD_H -#include -#include +#include "common.h" //structure to hold received/set tag values //variable data inputs have length specifiers diff --git a/armsrc/epa.c b/armsrc/epa.c index 7ccb0a8f6..c43b35c98 100644 --- a/armsrc/epa.c +++ b/armsrc/epa.c @@ -12,6 +12,16 @@ //----------------------------------------------------------------------------- #include "epa.h" +#include "cmd.h" +#include "fpgaloader.h" +#include "iso14443a.h" +#include "iso14443b.h" +#include "string.h" +#include "util.h" +#include "dbprint.h" +#include "commonutil.h" +#include "ticks.h" + // Protocol and Parameter Selection Request for ISO 14443 type A cards // use regular (1x) speed in both directions // CRC is already included diff --git a/armsrc/epa.h b/armsrc/epa.h index a0701ab57..66a95c059 100644 --- a/armsrc/epa.h +++ b/armsrc/epa.h @@ -11,9 +11,8 @@ #ifndef __EPA_H #define __EPA_H -#include "cmd.h" -#include "iso14443a.h" -#include "iso14443b.h" +#include "common.h" +#include "pm3_cmd.h" // this struct is used by EPA_Parse_CardAccess and contains info about the // PACE protocol supported by the chip @@ -23,8 +22,6 @@ typedef struct { uint8_t parameter_id; } pace_version_info_t; -// note: EPA_PACE_Collect_Nonce and EPA_PACE_Replay are declared in apps.h - // general functions void EPA_Finish(); size_t EPA_Parse_CardAccess(uint8_t *data, @@ -37,4 +34,7 @@ int EPA_Setup(); int EPA_PACE_MSE_Set_AT(pace_version_info_t pace_version_info, uint8_t password); int EPA_PACE_Get_Nonce(uint8_t requested_length, uint8_t *nonce); +void EPA_PACE_Collect_Nonce(PacketCommandNG *c); +void EPA_PACE_Replay(PacketCommandNG *c); + #endif /* __EPA_H */ diff --git a/armsrc/felica.c b/armsrc/felica.c index b732683e5..322d11327 100644 --- a/armsrc/felica.c +++ b/armsrc/felica.c @@ -1,10 +1,15 @@ -#include "proxmark3.h" -#include "apps.h" +#include "felica.h" +#include "proxmark3_arm.h" #include "BigBuf.h" #include "util.h" -#include "usb_cdc.h" // for usb_poll_validate_length #include "protocols.h" #include "crc16.h" // crc16 ccitt +#include "fpgaloader.h" +#include "string.h" +#include "commonutil.h" +#include "dbprint.h" +#include "ticks.h" +#include "mifare.h" // FeliCa timings // minimum time between the start bits of consecutive transfers from reader to tag: 6800 carrier (13.56MHz) cycles diff --git a/armsrc/Standalone/lf_proxbrute.h b/armsrc/felica.h similarity index 52% rename from armsrc/Standalone/lf_proxbrute.h rename to armsrc/felica.h index 3a9e1ce29..ef34dc108 100644 --- a/armsrc/Standalone/lf_proxbrute.h +++ b/armsrc/felica.h @@ -1,21 +1,22 @@ //----------------------------------------------------------------------------- -// Samy Kamkar, 2011, 2012 -// Brad antoniewicz 2011 -// Christian Herrmann, 2017 +// Jonathan Westhues, Aug 2005 +// Gerhard de Koning Gans, April 2008, May 2011 // // This code is licensed to you under the terms of the GNU GPL, version 2 or, // at your option, any later version. See the LICENSE.txt file for the text of // the license. //----------------------------------------------------------------------------- -// StandAlone Mod +// Definitions internal to the app source. //----------------------------------------------------------------------------- +#ifndef __FELICA_H +#define __FELICA_H -#ifndef __LF_PROXBRUTE_H -#define __LF_PROXBRUTE_H +#include "common.h" +#include "cmd.h" -#include "standalone.h" // standalone definitions -#include "apps.h" // debugstatements, lfops? +void felica_sendraw(PacketCommandNG *c); +void felica_sniff(uint32_t samplesToSkip, uint32_t triggersToSkip); +void felica_sim_lite(uint64_t uid); +void felica_dump_lite_s(); -#define OPTS 2 - -#endif /* __LF_PROXBRUTE_H */ +#endif diff --git a/armsrc/flashmem.c b/armsrc/flashmem.c index 19c249ffe..fb69dee01 100644 --- a/armsrc/flashmem.c +++ b/armsrc/flashmem.c @@ -1,6 +1,11 @@ #include "flashmem.h" #include "pmflash.h" +#include "proxmark3_arm.h" +#include "ticks.h" +#include "dbprint.h" +#include "string.h" + /* here: use NCPS2 @ PA10: */ #define SPI_CSR_NUM 2 #define SPI_PCS(npcs) ((~(1 << (npcs)) & 0xF) << 16) diff --git a/armsrc/flashmem.h b/armsrc/flashmem.h index b332ec3f5..42fc3d2f0 100644 --- a/armsrc/flashmem.h +++ b/armsrc/flashmem.h @@ -28,9 +28,7 @@ #ifndef __FLASHMEM_H #define __FLASHMEM_H -#include "proxmark3.h" -#include "apps.h" -#include "ticks.h" +#include "common.h" // Used Command #define ID 0x90 @@ -111,7 +109,6 @@ #define FASTFLASH (FLASHMEM_SPIBAUDRATE > FLASH_MINFAST) //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// -void Dbprintf(const char *fmt, ...); void FlashmemSetSpiBaudrate(uint32_t baudrate); bool FlashInit(); diff --git a/armsrc/fpgaloader.c b/armsrc/fpgaloader.c index b5543a7d2..87213df96 100644 --- a/armsrc/fpgaloader.c +++ b/armsrc/fpgaloader.c @@ -11,6 +11,15 @@ //----------------------------------------------------------------------------- #include "fpgaloader.h" +#include "proxmark3_arm.h" +#include "appmain.h" +#include "BigBuf.h" +#include "ticks.h" +#include "dbprint.h" +#include "util.h" +#include "zlib.h" +#include "fpga.h" +#include "string.h" // remember which version of the bitstream we have already downloaded to the FPGA static int downloaded_bitstream = 0; @@ -153,8 +162,7 @@ void FpgaSetupSsc(void) { //----------------------------------------------------------------------------- // Set up DMA to receive samples from the FPGA. We will use the PDC, with // a single buffer as a circular buffer (so that we just chain back to -// ourselves, not to another buffer). The stuff to manipulate those buffers -// is in apps.h, because it should be inlined, for speed. +// ourselves, not to another buffer). //----------------------------------------------------------------------------- bool FpgaSetupSscDma(uint8_t *buf, int len) { if (buf == NULL) return false; diff --git a/armsrc/fpgaloader.h b/armsrc/fpgaloader.h index f9b0e44b0..83c5bb2e4 100644 --- a/armsrc/fpgaloader.h +++ b/armsrc/fpgaloader.h @@ -12,32 +12,10 @@ #ifndef __FPGALOADER_H #define __FPGALOADER_H -#include -#include -#include "apps.h" -#include "fpga.h" -#include "common.h" // standard definitions -#include "proxmark3.h" // common area -#include "string.h" -#include "BigBuf.h" // bigbuf mem -#include "zlib.h" // uncompress +#include "common.h" - -void FpgaSendCommand(uint16_t cmd, uint16_t v); -void FpgaWriteConfWord(uint8_t v); -void FpgaDownloadAndGo(int bitstream_version); -// void FpgaGatherVersion(int bitstream_version, char *dst, int len); -void FpgaSetupSsc(void); -void SetupSpi(int mode); -bool FpgaSetupSscDma(uint8_t *buf, int len); -void Fpga_print_status(void); -int FpgaGetCurrent(void); #define FpgaDisableSscDma(void) AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS; #define FpgaEnableSscDma(void) AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTEN; -void SetAdcMuxFor(uint32_t whichGpio); - -// extern and generel turn off the antenna method -void switch_off(void); // definitions for multiple FPGA config files support #define FPGA_BITSTREAM_LF 1 @@ -97,4 +75,18 @@ void switch_off(void); #define FPGA_HF_ISO18092_FLAG_424K (2<<0) // 0010 should enable 414k mode (untested). No autodetect #define FPGA_HF_ISO18092_FLAG_READER (4<<0) // 0100 enables antenna power, to act as a reader instead of tag +void FpgaSendCommand(uint16_t cmd, uint16_t v); +void FpgaWriteConfWord(uint8_t v); +void FpgaDownloadAndGo(int bitstream_version); +// void FpgaGatherVersion(int bitstream_version, char *dst, int len); +void FpgaSetupSsc(void); +void SetupSpi(int mode); +bool FpgaSetupSscDma(uint8_t *buf, int len); +void Fpga_print_status(void); +int FpgaGetCurrent(void); +void SetAdcMuxFor(uint32_t whichGpio); + +// extern and generel turn off the antenna method +void switch_off(void); + #endif diff --git a/armsrc/frozen.c b/armsrc/frozen.c index 5af6faad8..220f51d6c 100644 --- a/armsrc/frozen.c +++ b/armsrc/frozen.c @@ -20,9 +20,6 @@ #include "frozen.h" -//#include -#include -#include #include #include #include "nprintf.h" diff --git a/armsrc/frozen.h b/armsrc/frozen.h index 49183ee7d..beb6c5f44 100644 --- a/armsrc/frozen.h +++ b/armsrc/frozen.h @@ -19,21 +19,9 @@ #ifndef CS_FROZEN_FROZEN_H_ #define CS_FROZEN_FROZEN_H_ -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - #include -#include #include -#if defined(_WIN32) && _MSC_VER < 1700 -typedef int bool; -enum { false = 0, true = 1 }; -#else -#include -#endif - /* JSON token type */ enum json_token_type { JSON_TYPE_INVALID = 0, /* memsetting to 0 should create INVALID value */ @@ -322,8 +310,4 @@ void *json_next_elem(const char *s, int len, void *handle, const char *path, #define JSON_ENABLE_HEX !JSON_MINIMAL #endif -#ifdef __cplusplus -} -#endif /* __cplusplus */ - #endif /* CS_FROZEN_FROZEN_H_ */ diff --git a/armsrc/hfsnoop.c b/armsrc/hfsnoop.c index bb5d8699c..994d76e51 100644 --- a/armsrc/hfsnoop.c +++ b/armsrc/hfsnoop.c @@ -1,8 +1,9 @@ -#include "proxmark3.h" -#include "apps.h" +#include "proxmark3_arm.h" #include "BigBuf.h" +#include "fpgaloader.h" +#include "ticks.h" +#include "dbprint.h" #include "util.h" -#include "usb_cdc.h" // for usb_poll_validate_length static void RAMFUNC optimizedSniff(void); diff --git a/armsrc/Standalone/lf_icerun.h b/armsrc/hfsnoop.h similarity index 65% rename from armsrc/Standalone/lf_icerun.h rename to armsrc/hfsnoop.h index 50427320a..b6fac7eb7 100644 --- a/armsrc/Standalone/lf_icerun.h +++ b/armsrc/hfsnoop.h @@ -1,17 +1,16 @@ //----------------------------------------------------------------------------- -// Iceman, Christian Herrmann, 2019 +// Jonathan Westhues, Aug 2005 +// Gerhard de Koning Gans, April 2008, May 2011 // // This code is licensed to you under the terms of the GNU GPL, version 2 or, // at your option, any later version. See the LICENSE.txt file for the text of // the license. //----------------------------------------------------------------------------- -// StandAlone Mod +// Definitions internal to the app source. //----------------------------------------------------------------------------- +#ifndef __HFSNOOP_H +#define __HFSNOOP_H -#ifndef __LF_ICERUN_H -#define __LF_ICERUN_H +void HfSniff(int, int); -#include "standalone.h" // standalone definitions -#include "apps.h" // debugstatements, lfops? - -#endif /* __LF_ICERUN_H */ +#endif diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index 14db91e91..c1fc7d8d4 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -20,12 +20,14 @@ #include "hitag2.h" #include "hitag2_crypto.h" -#include "hitag.h" -#include "proxmark3.h" -#include "apps.h" -#include "util.h" #include "string.h" +#include "proxmark3_arm.h" +#include "cmd.h" #include "BigBuf.h" +#include "fpgaloader.h" +#include "ticks.h" +#include "dbprint.h" +#include "util.h" // Successful crypto auth static bool bCrypto; diff --git a/armsrc/hitag2.h b/armsrc/hitag2.h index c62a2a221..9e0fb84e6 100644 --- a/armsrc/hitag2.h +++ b/armsrc/hitag2.h @@ -11,8 +11,7 @@ #ifndef _HITAG2_H_ #define _HITAG2_H_ -#include -#include +#include "common.h" #include "hitag.h" void SniffHitag(void); diff --git a/armsrc/hitag2_crypto.c b/armsrc/hitag2_crypto.c index 7d1e10d87..91c04ef43 100644 --- a/armsrc/hitag2_crypto.c +++ b/armsrc/hitag2_crypto.c @@ -11,6 +11,9 @@ //----------------------------------------------------------------------------- #include "hitag2_crypto.h" +#include "util.h" +#include "string.h" + /* Following is a modified version of cryptolib.com/ciphers/hitag2/ */ // Software optimized 48-bit Philips/NXP Mifare Hitag2 PCF7936/46/47/52 stream cipher algorithm by I.C. Wiener 2006-2007. // For educational purposes only. diff --git a/armsrc/hitag2_crypto.h b/armsrc/hitag2_crypto.h index d874955e0..8544c7e1c 100644 --- a/armsrc/hitag2_crypto.h +++ b/armsrc/hitag2_crypto.h @@ -1,12 +1,7 @@ #ifndef __HITAG2_CRYPTO_H #define __HITAG2_CRYPTO_H -#ifdef __cplusplus -extern "C" { -#endif - -#include "string.h" -#include "util.h" +#include "common.h" struct hitag2_tag { uint32_t uid; @@ -29,8 +24,5 @@ uint32_t _hitag2_byte(uint64_t *x); void hitag2_cipher_reset(struct hitag2_tag *tag, const uint8_t *iv); int hitag2_cipher_authenticate(uint64_t *cs, const uint8_t *authenticator_is); int hitag2_cipher_transcrypt(uint64_t *cs, uint8_t *data, uint16_t bytes, uint16_t bits) ; -#ifdef __cplusplus -} -#endif #endif diff --git a/armsrc/hitagS.c b/armsrc/hitagS.c index e3f1456aa..98c3844e2 100644 --- a/armsrc/hitagS.c +++ b/armsrc/hitagS.c @@ -13,6 +13,17 @@ #include "hitagS.h" +#include "proxmark3_arm.h" +#include "cmd.h" +#include "BigBuf.h" +#include "fpgaloader.h" +#include "ticks.h" +#include "dbprint.h" +#include "util.h" +#include "string.h" +#include "commonutil.h" +#include "hitag2_crypto.h" + #define CRC_PRESET 0xFF #define CRC_POLYNOM 0x1D diff --git a/armsrc/hitagS.h b/armsrc/hitagS.h index 49a885c4c..f4efd70a6 100644 --- a/armsrc/hitagS.h +++ b/armsrc/hitagS.h @@ -12,16 +12,9 @@ #ifndef _HITAGS_H_ #define _HITAGS_H_ -#include -#include -#include -#include "hitag2_crypto.h" +#include "common.h" + #include "hitag.h" -#include "proxmark3.h" -#include "apps.h" -#include "util.h" -#include "string.h" -#include "BigBuf.h" void SimulateHitagSTag(bool tag_mem_supplied, uint8_t *data); void ReadHitagS(hitag_function htf, hitag_data *htd); diff --git a/common/i2c.c b/armsrc/i2c.c similarity index 99% rename from common/i2c.c rename to armsrc/i2c.c index 62bd2bc56..2cd3c6f3e 100644 --- a/common/i2c.c +++ b/armsrc/i2c.c @@ -10,6 +10,14 @@ //----------------------------------------------------------------------------- #include "i2c.h" +#include "proxmark3_arm.h" +#include "cmd.h" +#include "BigBuf.h" +#include "ticks.h" +#include "dbprint.h" +#include "util.h" +#include "string.h" + #define GPIO_RST AT91C_PIO_PA1 #define GPIO_SCL AT91C_PIO_PA5 #define GPIO_SDA AT91C_PIO_PA7 diff --git a/common/i2c.h b/armsrc/i2c.h similarity index 95% rename from common/i2c.h rename to armsrc/i2c.h index 52be70ef0..7b1707502 100644 --- a/common/i2c.h +++ b/armsrc/i2c.h @@ -1,10 +1,7 @@ #ifndef __I2C_H #define __I2C_H -#include -#include "proxmark3.h" -#include "apps.h" -#include "BigBuf.h" +#include "common.h" #include "mifare.h" #define I2C_DEVICE_ADDRESS_BOOT 0xB0 @@ -18,7 +15,6 @@ #define I2C_DEVICE_CMD_GETVERSION 0x06 #define I2C_DEVICE_CMD_SEND_T0 0x07 - void I2C_recovery(void); void I2C_init(void); void I2C_Reset(void); @@ -48,4 +44,5 @@ void SmartCardSetBaud(uint64_t arg0); void SmartCardSetClock(uint64_t arg0); void I2C_print_status(void); int I2C_get_version(uint8_t *maj, uint8_t *min); + #endif diff --git a/armsrc/iclass.c b/armsrc/iclass.c index b1553f2df..26201842a 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -36,15 +36,24 @@ // //----------------------------------------------------------------------------- -#include "apps.h" +#include "iclass.h" + +#include "proxmark3_arm.h" #include "cmd.h" // Needed for CRC in emulation mode; // same construction as in ISO 14443; // different initial value (CRC_ICLASS) #include "crc16.h" -#include "protocols.h" #include "optimized_cipher.h" -#include "usb_cdc.h" // for usb_poll_validate_length + +#include "appmain.h" +#include "BigBuf.h" +#include "fpgaloader.h" +#include "string.h" +#include "util.h" +#include "dbprint.h" +#include "protocols.h" +#include "ticks.h" static int timeout = 4096; static int SendIClassAnswer(uint8_t *resp, int respLen, uint16_t delay); @@ -92,21 +101,21 @@ typedef struct { int bitBuffer; int dropPosition; uint8_t *output; -} tUart; +} tUartIc; */ typedef struct { enum { - DEMOD_UNSYNCD, - DEMOD_START_OF_COMMUNICATION, - DEMOD_START_OF_COMMUNICATION2, - DEMOD_START_OF_COMMUNICATION3, - DEMOD_SOF_COMPLETE, - DEMOD_MANCHESTER_D, - DEMOD_MANCHESTER_E, - DEMOD_END_OF_COMMUNICATION, - DEMOD_END_OF_COMMUNICATION2, - DEMOD_MANCHESTER_F, - DEMOD_ERROR_WAIT + DEMOD_IC_UNSYNCD, + DEMOD_IC_START_OF_COMMUNICATION, + DEMOD_IC_START_OF_COMMUNICATION2, + DEMOD_IC_START_OF_COMMUNICATION3, + DEMOD_IC_SOF_COMPLETE, + DEMOD_IC_MANCHESTER_D, + DEMOD_IC_MANCHESTER_E, + DEMOD_IC_END_OF_COMMUNICATION, + DEMOD_IC_END_OF_COMMUNICATION2, + DEMOD_IC_MANCHESTER_F, + DEMOD_IC_ERROR_WAIT } state; int bitCount; int posCount; @@ -125,7 +134,7 @@ typedef struct { SUB_BOTH } sub; uint8_t *output; -} tDemod; +} tDemodIc; /* * Abrasive's uart implementation @@ -138,8 +147,13 @@ typedef struct { bool frame_done; uint8_t *buf; int len; -} tUart; -static tUart Uart; +} tUartIc; +static tUartIc Uart; + +static void OnError(uint8_t reason) { + reply_old(CMD_ACK, 0, reason, 0, 0, 0); + switch_off(); +} static void uart_reset(void) { Uart.frame_done = false; @@ -499,8 +513,8 @@ static RAMFUNC int OutOfNDecoding(int bit) { //============================================================================= // Manchester //============================================================================= -static tDemod Demod; -static void DemodReset() { +static tDemodIc Demod; +static void DemodIcReset() { Demod.bitCount = 0; Demod.posCount = 0; Demod.syncBit = 0; @@ -512,11 +526,11 @@ static void DemodReset() { Demod.samples = 0; Demod.len = 0; Demod.sub = SUB_NONE; - Demod.state = DEMOD_UNSYNCD; + Demod.state = DEMOD_IC_UNSYNCD; } -static void DemodInit(uint8_t *data) { +static void DemodIcInit(uint8_t *data) { Demod.output = data; - DemodReset(); + DemodIcReset(); } // UART debug @@ -592,7 +606,7 @@ static RAMFUNC int ManchesterDecoding_iclass(uint32_t v) { return false; } - if (Demod.state == DEMOD_UNSYNCD) { + if (Demod.state == DEMOD_IC_UNSYNCD) { Demod.output[Demod.len] = 0xfa; Demod.syncBit = 0; //Demod.samples = 0; @@ -620,7 +634,7 @@ static RAMFUNC int ManchesterDecoding_iclass(uint32_t v) { if (Demod.syncBit) { Demod.len = 0; - Demod.state = DEMOD_START_OF_COMMUNICATION; + Demod.state = DEMOD_IC_START_OF_COMMUNICATION; Demod.sub = SUB_FIRST_HALF; Demod.bitCount = 0; Demod.shiftReg = 0; @@ -644,12 +658,12 @@ static RAMFUNC int ManchesterDecoding_iclass(uint32_t v) { } // SOF must be long burst... otherwise stay unsynced!!! if (!(Demod.buffer & Demod.syncBit) || !(Demod.buffer2 & Demod.syncBit)) - Demod.state = DEMOD_UNSYNCD; + Demod.state = DEMOD_IC_UNSYNCD; } else { // SOF must be long burst... otherwise stay unsynced!!! if (!(Demod.buffer2 & Demod.syncBit) || !(Demod.buffer3 & Demod.syncBit)) { - Demod.state = DEMOD_UNSYNCD; + Demod.state = DEMOD_IC_UNSYNCD; error = 0x88; uart_debug(error, bit); return false; @@ -682,74 +696,74 @@ static RAMFUNC int ManchesterDecoding_iclass(uint32_t v) { } if (Demod.sub == SUB_NONE) { - if (Demod.state == DEMOD_SOF_COMPLETE) { + if (Demod.state == DEMOD_IC_SOF_COMPLETE) { Demod.output[Demod.len] = 0x0f; Demod.len++; - Demod.state = DEMOD_UNSYNCD; + Demod.state = DEMOD_IC_UNSYNCD; return true; } else { - Demod.state = DEMOD_ERROR_WAIT; + Demod.state = DEMOD_IC_ERROR_WAIT; error = 0x33; } } switch (Demod.state) { - case DEMOD_START_OF_COMMUNICATION: + case DEMOD_IC_START_OF_COMMUNICATION: if (Demod.sub == SUB_BOTH) { - Demod.state = DEMOD_START_OF_COMMUNICATION2; + Demod.state = DEMOD_IC_START_OF_COMMUNICATION2; Demod.posCount = 1; Demod.sub = SUB_NONE; } else { Demod.output[Demod.len] = 0xab; - Demod.state = DEMOD_ERROR_WAIT; + Demod.state = DEMOD_IC_ERROR_WAIT; error = 0xd2; } break; - case DEMOD_START_OF_COMMUNICATION2: + case DEMOD_IC_START_OF_COMMUNICATION2: if (Demod.sub == SUB_SECOND_HALF) { - Demod.state = DEMOD_START_OF_COMMUNICATION3; + Demod.state = DEMOD_IC_START_OF_COMMUNICATION3; } else { Demod.output[Demod.len] = 0xab; - Demod.state = DEMOD_ERROR_WAIT; + Demod.state = DEMOD_IC_ERROR_WAIT; error = 0xd3; } break; - case DEMOD_START_OF_COMMUNICATION3: + case DEMOD_IC_START_OF_COMMUNICATION3: if (Demod.sub == SUB_SECOND_HALF) { - Demod.state = DEMOD_SOF_COMPLETE; + Demod.state = DEMOD_IC_SOF_COMPLETE; } else { Demod.output[Demod.len] = 0xab; - Demod.state = DEMOD_ERROR_WAIT; + Demod.state = DEMOD_IC_ERROR_WAIT; error = 0xd4; } break; - case DEMOD_SOF_COMPLETE: - case DEMOD_MANCHESTER_D: - case DEMOD_MANCHESTER_E: + case DEMOD_IC_SOF_COMPLETE: + case DEMOD_IC_MANCHESTER_D: + case DEMOD_IC_MANCHESTER_E: // OPPOSITE FROM ISO14443 - 11110000 = 0 (1 in 14443) // 00001111 = 1 (0 in 14443) if (Demod.sub == SUB_SECOND_HALF) { // SUB_FIRST_HALF Demod.bitCount++; Demod.shiftReg = (Demod.shiftReg >> 1) ^ 0x100; - Demod.state = DEMOD_MANCHESTER_D; + Demod.state = DEMOD_IC_MANCHESTER_D; } else if (Demod.sub == SUB_FIRST_HALF) { // SUB_SECOND_HALF Demod.bitCount++; Demod.shiftReg >>= 1; - Demod.state = DEMOD_MANCHESTER_E; + Demod.state = DEMOD_IC_MANCHESTER_E; } else if (Demod.sub == SUB_BOTH) { - Demod.state = DEMOD_MANCHESTER_F; + Demod.state = DEMOD_IC_MANCHESTER_F; } else { - Demod.state = DEMOD_ERROR_WAIT; + Demod.state = DEMOD_IC_ERROR_WAIT; error = 0x55; } break; - case DEMOD_MANCHESTER_F: + case DEMOD_IC_MANCHESTER_F: // Tag response does not need to be a complete byte! if (Demod.len > 0 || Demod.bitCount > 0) { if (Demod.bitCount > 1) { // was > 0, do not interpret last closing bit, is part of EOF @@ -758,22 +772,22 @@ static RAMFUNC int ManchesterDecoding_iclass(uint32_t v) { Demod.len++; } - Demod.state = DEMOD_UNSYNCD; + Demod.state = DEMOD_IC_UNSYNCD; return true; } else { Demod.output[Demod.len] = 0xad; - Demod.state = DEMOD_ERROR_WAIT; + Demod.state = DEMOD_IC_ERROR_WAIT; error = 0x03; } break; - case DEMOD_ERROR_WAIT: - Demod.state = DEMOD_UNSYNCD; + case DEMOD_IC_ERROR_WAIT: + Demod.state = DEMOD_IC_UNSYNCD; break; default: Demod.output[Demod.len] = 0xdd; - Demod.state = DEMOD_UNSYNCD; + Demod.state = DEMOD_IC_UNSYNCD; break; } @@ -818,10 +832,10 @@ static void iclass_setup_sniff(void) { set_tracing(true); // Initialize Demod and Uart structs - DemodInit(BigBuf_malloc(ICLASS_BUFFER_SIZE)); + DemodIcInit(BigBuf_malloc(ICLASS_BUFFER_SIZE)); uart_init(BigBuf_malloc(ICLASS_BUFFER_SIZE)); - //UartInit(BigBuf_malloc(ICLASS_BUFFER_SIZE)); + //UartIcInit(BigBuf_malloc(ICLASS_BUFFER_SIZE)); if (DBGLEVEL > 1) { // Print debug information about the buffer sizes @@ -927,7 +941,7 @@ void RAMFUNC SniffIClass(void) { if (Uart.frame_done) { time_stop = GetCountSspClk() - time_0; LogTrace(Uart.buf, Uart.len, time_start, time_stop, NULL, true); - DemodReset(); + DemodIcReset(); uart_reset(); } else { time_start = GetCountSspClk() - time_0; @@ -959,12 +973,12 @@ void RAMFUNC SniffIClass(void) { if (ManchesterDecoding_iclass(foo)) { time_stop = GetCountSspClk() - time_0; LogTrace(Demod.output, Demod.len, time_start, time_stop, NULL, false); - DemodReset(); + DemodIcReset(); uart_reset(); } else { time_start = GetCountSspClk() - time_0; } - TagIsActive = (Demod.state != DEMOD_UNSYNCD); + TagIsActive = (Demod.state != DEMOD_IC_UNSYNCD); } tag_byte = 0; foo = 0; @@ -1821,7 +1835,7 @@ static int GetIClassAnswer(uint8_t *receivedResponse, int maxLen, int *samples, bool skip = false; // Setup UART/DEMOD to receive - DemodInit(receivedResponse); + DemodIcInit(receivedResponse); if (elapsed) *elapsed = 0; diff --git a/armsrc/iclass.h b/armsrc/iclass.h new file mode 100644 index 000000000..a9edbdfed --- /dev/null +++ b/armsrc/iclass.h @@ -0,0 +1,29 @@ +//----------------------------------------------------------------------------- +// Jonathan Westhues, Aug 2005 +// Gerhard de Koning Gans, April 2008, May 2011 +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// Definitions internal to the app source. +//----------------------------------------------------------------------------- +#ifndef __ICLASS_H +#define __ICLASS_H + +#include "common.h" + +void RAMFUNC SniffIClass(void); +void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain); +void ReaderIClass(uint8_t arg0); +void ReaderIClass_Replay(uint8_t arg0, uint8_t *mac); +void iClass_Authentication(uint8_t *mac); +void iClass_Authentication_fast(uint64_t arg0, uint64_t arg1, uint8_t *datain); +void iClass_WriteBlock(uint8_t blockno, uint8_t *data); +void iClass_ReadBlk(uint8_t blockno); +bool iClass_ReadBlock(uint8_t blockno, uint8_t *data, uint8_t len); +void iClass_Dump(uint8_t blockno, uint8_t numblks); +void iClass_Clone(uint8_t startblock, uint8_t endblock, uint8_t *data); +void iClass_ReadCheck(uint8_t blockno, uint8_t keytype); + +#endif diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 2e7aeebe3..786db50dc 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -11,6 +11,21 @@ //----------------------------------------------------------------------------- #include "iso14443a.h" +#include "string.h" +#include "proxmark3_arm.h" +#include "cmd.h" +#include "appmain.h" +#include "BigBuf.h" +#include "fpgaloader.h" +#include "ticks.h" +#include "dbprint.h" +#include "util.h" +#include "parity.h" +#include "mifareutil.h" +#include "commonutil.h" +#include "crc16.h" +#include "protocols.h" + #define MAX_ISO14A_TIMEOUT 524288 static uint32_t iso14a_timeout; // if iso14443a not active - transmit/receive dont try to execute @@ -161,7 +176,7 @@ void GetParity(const uint8_t *pbtCmd, uint16_t len, uint8_t *par) { // Note 1: the bitstream may start at any time. We therefore need to sync. // Note 2: the interpretation of Sequence Y and Z depends on the preceding sequence. //----------------------------------------------------------------------------- -static tUart Uart; +static tUart14a Uart; // Lookup-Table to decide if 4 raw bits are a modulation. // We accept the following: @@ -176,12 +191,12 @@ const bool Mod_Miller_LUT[] = { #define IsMillerModulationNibble1(b) (Mod_Miller_LUT[(b & 0x000000F0) >> 4]) #define IsMillerModulationNibble2(b) (Mod_Miller_LUT[(b & 0x0000000F)]) -tUart *GetUart() { +tUart14a *GetUart14a() { return &Uart; } -void UartReset(void) { - Uart.state = STATE_UNSYNCD; +void Uart14aReset(void) { + Uart.state = STATE_14A_UNSYNCD; Uart.bitCount = 0; Uart.len = 0; // number of decoded data bytes Uart.parityLen = 0; // number of decoded parity bytes @@ -194,17 +209,17 @@ void UartReset(void) { Uart.syncBit = 9999; } -void UartInit(uint8_t *data, uint8_t *par) { +void Uart14aInit(uint8_t *data, uint8_t *par) { Uart.output = data; Uart.parity = par; - UartReset(); + Uart14aReset(); } // use parameter non_real_time to provide a timestamp. Set to 0 if the decoder should measure real time RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time) { Uart.fourBits = (Uart.fourBits << 8) | bit; - if (Uart.state == STATE_UNSYNCD) { // not yet synced + if (Uart.state == STATE_14A_UNSYNCD) { // not yet synced Uart.syncBit = 9999; // not set // 00x11111 2|3 ticks pause followed by 6|5 ticks unmodulated Sequence Z (a "0" or "start of communication") @@ -230,20 +245,20 @@ RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time) { Uart.startTime = non_real_time ? non_real_time : (GetCountSspClk() & 0xfffffff8); Uart.startTime -= Uart.syncBit; Uart.endTime = Uart.startTime; - Uart.state = STATE_START_OF_COMMUNICATION; + Uart.state = STATE_14A_START_OF_COMMUNICATION; } } else { if (IsMillerModulationNibble1(Uart.fourBits >> Uart.syncBit)) { if (IsMillerModulationNibble2(Uart.fourBits >> Uart.syncBit)) { // Modulation in both halves - error - UartReset(); + Uart14aReset(); } else { // Modulation in first half = Sequence Z = logic "0" - if (Uart.state == STATE_MILLER_X) { // error - must not follow after X - UartReset(); + if (Uart.state == STATE_14A_MILLER_X) { // error - must not follow after X + Uart14aReset(); } else { Uart.bitCount++; Uart.shiftReg = (Uart.shiftReg >> 1); // add a 0 to the shiftreg - Uart.state = STATE_MILLER_Z; + Uart.state = STATE_14A_MILLER_Z; Uart.endTime = Uart.startTime + 8 * (9 * Uart.len + Uart.bitCount + 1) - 6; if (Uart.bitCount >= 9) { // if we decoded a full byte (including parity) Uart.output[Uart.len++] = (Uart.shiftReg & 0xff); @@ -262,7 +277,7 @@ RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time) { if (IsMillerModulationNibble2(Uart.fourBits >> Uart.syncBit)) { // Modulation second half = Sequence X = logic "1" Uart.bitCount++; Uart.shiftReg = (Uart.shiftReg >> 1) | 0x100; // add a 1 to the shiftreg - Uart.state = STATE_MILLER_X; + Uart.state = STATE_14A_MILLER_X; Uart.endTime = Uart.startTime + 8 * (9 * Uart.len + Uart.bitCount + 1) - 2; if (Uart.bitCount >= 9) { // if we decoded a full byte (including parity) Uart.output[Uart.len++] = (Uart.shiftReg & 0xff); @@ -276,8 +291,8 @@ RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time) { } } } else { // no modulation in both halves - Sequence Y - if (Uart.state == STATE_MILLER_Z || Uart.state == STATE_MILLER_Y) { // Y after logic "0" - End of Communication - Uart.state = STATE_UNSYNCD; + if (Uart.state == STATE_14A_MILLER_Z || Uart.state == STATE_14A_MILLER_Y) { // Y after logic "0" - End of Communication + Uart.state = STATE_14A_UNSYNCD; Uart.bitCount--; // last "0" was part of EOC sequence Uart.shiftReg <<= 1; // drop it if (Uart.bitCount > 0) { // if we decoded some bits @@ -294,15 +309,15 @@ RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time) { if (Uart.len) { return true; // we are finished with decoding the raw data sequence } else { - UartReset(); // Nothing received - start over + Uart14aReset(); // Nothing received - start over } } - if (Uart.state == STATE_START_OF_COMMUNICATION) { // error - must not follow directly after SOC - UartReset(); + if (Uart.state == STATE_14A_START_OF_COMMUNICATION) { // error - must not follow directly after SOC + Uart14aReset(); } else { // a logic "0" Uart.bitCount++; Uart.shiftReg = (Uart.shiftReg >> 1); // add a 0 to the shiftreg - Uart.state = STATE_MILLER_Y; + Uart.state = STATE_14A_MILLER_Y; if (Uart.bitCount >= 9) { // if we decoded a full byte (including parity) Uart.output[Uart.len++] = (Uart.shiftReg & 0xff); Uart.parityBits <<= 1; // make room for the parity bit @@ -336,7 +351,7 @@ RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time) { // 8 ticks modulated: A collision. Save the collision position and treat as Sequence D // Note 1: the bitstream may start at any time. We therefore need to sync. // Note 2: parameter offset is used to determine the position of the parity bits (required for the anticollision command only) -tDemod Demod; +tDemod14a Demod; // Lookup-Table to decide if 4 raw bits are a modulation. // We accept three or four "1" in any position @@ -348,11 +363,11 @@ const bool Mod_Manchester_LUT[] = { #define IsManchesterModulationNibble1(b) (Mod_Manchester_LUT[(b & 0x00F0) >> 4]) #define IsManchesterModulationNibble2(b) (Mod_Manchester_LUT[(b & 0x000F)]) -tDemod *GetDemod() { +tDemod14a *GetDemod14a() { return &Demod; } -void DemodReset(void) { - Demod.state = DEMOD_UNSYNCD; +void Demod14aReset(void) { + Demod.state = DEMOD_14A_UNSYNCD; Demod.len = 0; // number of decoded data bytes Demod.parityLen = 0; Demod.shiftReg = 0; // shiftreg to hold decoded data bits @@ -367,17 +382,17 @@ void DemodReset(void) { Demod.samples = 0; } -void DemodInit(uint8_t *data, uint8_t *par) { +void Demod14aInit(uint8_t *data, uint8_t *par) { Demod.output = data; Demod.parity = par; - DemodReset(); + Demod14aReset(); } // use parameter non_real_time to provide a timestamp. Set to 0 if the decoder should measure real time RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non_real_time) { Demod.twoBits = (Demod.twoBits << 8) | bit; - if (Demod.state == DEMOD_UNSYNCD) { + if (Demod.state == DEMOD_14A_UNSYNCD) { if (Demod.highCnt < 2) { // wait for a stable unmodulated signal if (Demod.twoBits == 0x0000) { @@ -399,7 +414,7 @@ RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non_real_t Demod.startTime = non_real_time ? non_real_time : (GetCountSspClk() & 0xfffffff8); Demod.startTime -= Demod.syncBit; Demod.bitCount = offset; // number of decoded data bits - Demod.state = DEMOD_MANCHESTER_DATA; + Demod.state = DEMOD_14A_MANCHESTER_DATA; } } } else { @@ -455,7 +470,7 @@ RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non_real_t if (Demod.len) { return true; // we are finished with decoding the raw data sequence } else { // nothing received. Start over - DemodReset(); + Demod14aReset(); } } } @@ -468,7 +483,7 @@ RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non_real_t RAMFUNC int ManchesterDecoding_Thinfilm(uint8_t bit) { Demod.twoBits = (Demod.twoBits << 8) | bit; - if (Demod.state == DEMOD_UNSYNCD) { + if (Demod.state == DEMOD_14A_UNSYNCD) { if (Demod.highCnt < 2) { // wait for a stable unmodulated signal if (Demod.twoBits == 0x0000) { @@ -491,7 +506,7 @@ RAMFUNC int ManchesterDecoding_Thinfilm(uint8_t bit) { Demod.startTime -= Demod.syncBit; Demod.bitCount = 1; // number of decoded data bits Demod.shiftReg = 1; - Demod.state = DEMOD_MANCHESTER_DATA; + Demod.state = DEMOD_14A_MANCHESTER_DATA; } } } else { @@ -529,7 +544,7 @@ RAMFUNC int ManchesterDecoding_Thinfilm(uint8_t bit) { if (Demod.len) { return true; // we are finished with decoding the raw data sequence } else { // nothing received. Start over - DemodReset(); + Demod14aReset(); } } } @@ -582,10 +597,10 @@ void RAMFUNC SniffIso14443a(uint8_t param) { bool ReaderIsActive = false; // Set up the demodulator for tag -> reader responses. - DemodInit(receivedResp, receivedRespPar); + Demod14aInit(receivedResp, receivedRespPar); // Set up the demodulator for the reader -> tag commands - UartInit(receivedCmd, receivedCmdPar); + Uart14aInit(receivedCmd, receivedCmdPar); DbpString("Starting to sniff"); @@ -659,13 +674,13 @@ void RAMFUNC SniffIso14443a(uint8_t param) { true)) break; } /* ready to receive another command. */ - UartReset(); + Uart14aReset(); /* reset the demod code, which might have been */ /* false-triggered by the commands from the reader. */ - DemodReset(); + Demod14aReset(); LED_B_OFF(); } - ReaderIsActive = (Uart.state != STATE_UNSYNCD); + ReaderIsActive = (Uart.state != STATE_14A_UNSYNCD); } // no need to try decoding tag data if the reader is sending - and we cannot afford the time @@ -684,13 +699,13 @@ void RAMFUNC SniffIso14443a(uint8_t param) { if ((!triggered) && (param & 0x01)) triggered = true; // ready to receive another response. - DemodReset(); + Demod14aReset(); // reset the Miller decoder including its (now outdated) input buffer - UartReset(); - //UartInit(receivedCmd, receivedCmdPar); + Uart14aReset(); + //Uart14aInit(receivedCmd, receivedCmdPar); LED_C_OFF(); } - TagIsActive = (Demod.state != DEMOD_UNSYNCD); + TagIsActive = (Demod.state != DEMOD_14A_UNSYNCD); } } @@ -830,7 +845,7 @@ static bool GetIso14443aCommandFromReader(uint8_t *received, uint8_t *par, int * FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_TAGSIM_LISTEN); // Now run a `software UART` on the stream of incoming samples. - UartInit(received, par); + Uart14aInit(received, par); // clear RXRDY: uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; @@ -1795,7 +1810,7 @@ int EmGetCmd(uint8_t *received, uint16_t *len, uint8_t *par) { AT91C_BASE_ADC->ADC_CR = AT91C_ADC_START; // Now run a 'software UART' on the stream of incoming samples. - UartInit(received, par); + Uart14aInit(received, par); // Clear RXRDY: uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; @@ -2024,7 +2039,7 @@ bool GetIso14443aAnswerFromTag_Thinfilm(uint8_t *receivedResponse, uint8_t *rec FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_LISTEN); // Now get the answer from the card - DemodInit(receivedResponse, NULL); + Demod14aInit(receivedResponse, NULL); // clear RXRDY: uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; @@ -2073,7 +2088,7 @@ static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receive FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_LISTEN); // Now get the answer from the card - DemodInit(receivedResponse, receivedResponsePar); + Demod14aInit(receivedResponse, receivedResponsePar); // clear RXRDY: uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; @@ -2089,7 +2104,7 @@ static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receive if (ManchesterDecoding(b, offset, 0)) { NextTransferTime = MAX(NextTransferTime, Demod.endTime - (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER) / 16 + FRAME_DELAY_TIME_PICC_TO_PCD); return true; - } else if (c++ > timeout && Demod.state == DEMOD_UNSYNCD) { + } else if (c++ > timeout && Demod.state == DEMOD_14A_UNSYNCD) { return false; } } @@ -2499,8 +2514,8 @@ void iso14443a_setup(uint8_t fpga_minor_mode) { StartCountSspClk(); // Prepare the demodulation functions - DemodReset(); - UartReset(); + Demod14aReset(); + Uart14aReset(); NextTransferTime = 2 * DELAY_ARM2AIR_AS_READER; iso14a_set_timeout(1060); // 106 * 10ms default diff --git a/armsrc/iso14443a.h b/armsrc/iso14443a.h index 323fb8a97..e4ea7f0df 100644 --- a/armsrc/iso14443a.h +++ b/armsrc/iso14443a.h @@ -13,21 +13,9 @@ #ifndef __ISO14443A_H #define __ISO14443A_H -#ifdef __cplusplus -extern "C" { -#endif - +#include "common.h" +#include "mifare.h" // struct #include "pm3_cmd.h" -#include "cmd.h" -#include "apps.h" -#include "util.h" -#include "string.h" -#include "crc16.h" -#include "mifaresniff.h" -#include "crapto1/crapto1.h" -#include "mifareutil.h" -#include "parity.h" -#include "mifare.h" // structs // When the PM acts as tag and is receiving it takes // 2 ticks delay in the RF part (for the first falling edge), @@ -42,11 +30,11 @@ extern "C" { typedef struct { enum { - DEMOD_UNSYNCD, - // DEMOD_HALF_SYNCD, - // DEMOD_MOD_FIRST_HALF, - // DEMOD_NOMOD_FIRST_HALF, - DEMOD_MANCHESTER_DATA + DEMOD_14A_UNSYNCD, + // DEMOD_14A_HALF_SYNCD, + // DEMOD_14A_MOD_FIRST_HALF, + // DEMOD_14A_NOMOD_FIRST_HALF, + DEMOD_14A_MANCHESTER_DATA } state; uint16_t twoBits; uint16_t highCnt; @@ -61,7 +49,7 @@ typedef struct { uint32_t startTime, endTime; uint8_t *output; uint8_t *parity; -} tDemod; +} tDemod14a; /* typedef enum { MOD_NOMOD = 0, @@ -73,11 +61,11 @@ typedef enum { typedef struct { enum { - STATE_UNSYNCD, - STATE_START_OF_COMMUNICATION, - STATE_MILLER_X, - STATE_MILLER_Y, - STATE_MILLER_Z, + STATE_14A_UNSYNCD, + STATE_14A_START_OF_COMMUNICATION, + STATE_14A_MILLER_X, + STATE_14A_MILLER_Y, + STATE_14A_MILLER_Z, // DROP_NONE, // DROP_FIRST_HALF, } state; @@ -93,7 +81,7 @@ typedef struct { uint32_t startTime, endTime; uint8_t *output; uint8_t *parity; -} tUart; +} tUart14a; #ifndef AddCrc14A # define AddCrc14A(data, len) compute_crc(CRC_14443_A, (data), (len), (data)+(len), (data)+(len)+1) @@ -109,12 +97,12 @@ typedef struct { void GetParity(const uint8_t *pbtCmd, uint16_t len, uint8_t *par); -tDemod *GetDemod(void); -void DemodReset(void); -void DemodInit(uint8_t *data, uint8_t *par); -tUart *GetUart(void); -void UartReset(void); -void UartInit(uint8_t *data, uint8_t *par); +tDemod14a *GetDemod14a(void); +void Demod14aReset(void); +void Demod14aInit(uint8_t *data, uint8_t *par); +tUart14a *GetUart14a(void); +void Uart14aReset(void); +void Uart14aInit(uint8_t *data, uint8_t *par); RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time); RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non_real_time); @@ -153,8 +141,4 @@ void DetectNACKbug(void); bool GetIso14443aAnswerFromTag_Thinfilm(uint8_t *receivedResponse, uint8_t *received_len); -#ifdef __cplusplus -} -#endif - #endif /* __ISO14443A_H */ diff --git a/armsrc/iso14443b.c b/armsrc/iso14443b.c index 241484d01..6f19def06 100644 --- a/armsrc/iso14443b.c +++ b/armsrc/iso14443b.c @@ -10,6 +10,20 @@ //----------------------------------------------------------------------------- #include "iso14443b.h" +#include "proxmark3_arm.h" +#include "common.h" // access to global variable: DBGLEVEL +#include "util.h" +#include "string.h" +#include "crc16.h" +#include "protocols.h" +#include "appmain.h" +#include "BigBuf.h" +#include "cmd.h" +#include "fpgaloader.h" +#include "commonutil.h" +#include "dbprint.h" +#include "ticks.h" + #ifndef FWT_TIMEOUT_14B // defaults to 2000ms # define FWT_TIMEOUT_14B 35312 @@ -52,7 +66,7 @@ static uint32_t iso14b_timeout = FWT_TIMEOUT_14B; //============================================================================= // An ISO 14443 Type B tag. We listen for commands from the reader, using -// a UART kind of thing that's implemented in software. When we get a +// a kind of thing that's implemented in software. When we get a // frame (i.e., a group of bytes between SOF and EOF), we check the CRC. // If it's good, then we can do something appropriate with it, and send // a response. @@ -60,14 +74,14 @@ static uint32_t iso14b_timeout = FWT_TIMEOUT_14B; //----------------------------------------------------------------------------- -// The software UART that receives commands from the reader, and its state variables. +// The software that receives commands from the reader, and its state variables. //----------------------------------------------------------------------------- static struct { enum { - STATE_UNSYNCD, - STATE_GOT_FALLING_EDGE_OF_SOF, - STATE_AWAITING_START_BIT, - STATE_RECEIVING_DATA + STATE_14B_UNSYNCD, + STATE_14B_GOT_FALLING_EDGE_OF_SOF, + STATE_14B_AWAITING_START_BIT, + STATE_14B_RECEIVING_DATA } state; uint16_t shiftReg; int bitCnt; @@ -77,8 +91,8 @@ static struct { uint8_t *output; } Uart; -static void UartReset() { - Uart.state = STATE_UNSYNCD; +static void Uart14bReset() { + Uart.state = STATE_14B_UNSYNCD; Uart.shiftReg = 0; Uart.bitCnt = 0; Uart.byteCnt = 0; @@ -86,9 +100,9 @@ static void UartReset() { Uart.posCnt = 0; } -static void UartInit(uint8_t *data) { +static void Uart14bInit(uint8_t *data) { Uart.output = data; - UartReset(); + Uart14bReset(); // memset(Uart.output, 0x00, MAX_FRAME_SIZE); } @@ -120,7 +134,7 @@ static struct { } Demod; // Clear out the state of the "UART" that receives from the tag. -static void DemodReset() { +static void Demod14bReset() { Demod.state = DEMOD_UNSYNCD; Demod.bitCount = 0; Demod.posCount = 0; @@ -133,9 +147,9 @@ static void DemodReset() { Demod.endTime = 0; } -static void DemodInit(uint8_t *data) { +static void Demod14bInit(uint8_t *data) { Demod.output = data; - DemodReset(); + Demod14bReset(); // memset(Demod.output, 0x00, MAX_FRAME_SIZE); } @@ -315,16 +329,16 @@ static void CodeIso14443bAsTag(const uint8_t *cmd, int len) { */ static RAMFUNC int Handle14443bReaderUartBit(uint8_t bit) { switch (Uart.state) { - case STATE_UNSYNCD: + case STATE_14B_UNSYNCD: if (!bit) { // we went low, so this could be the beginning of an SOF - Uart.state = STATE_GOT_FALLING_EDGE_OF_SOF; + Uart.state = STATE_14B_GOT_FALLING_EDGE_OF_SOF; Uart.posCnt = 0; Uart.bitCnt = 0; } break; - case STATE_GOT_FALLING_EDGE_OF_SOF: + case STATE_14B_GOT_FALLING_EDGE_OF_SOF: Uart.posCnt++; if (Uart.posCnt == 2) { // sample every 4 1/fs in the middle of a bit if (bit) { @@ -333,11 +347,11 @@ static RAMFUNC int Handle14443bReaderUartBit(uint8_t bit) { // zeros that it's a valid SOF Uart.posCnt = 0; Uart.byteCnt = 0; - Uart.state = STATE_AWAITING_START_BIT; + Uart.state = STATE_14B_AWAITING_START_BIT; LED_A_ON(); // Indicate we got a valid SOF } else { // didn't stay down long enough before going high, error - Uart.state = STATE_UNSYNCD; + Uart.state = STATE_14B_UNSYNCD; } } else { // do nothing, keep waiting @@ -348,27 +362,27 @@ static RAMFUNC int Handle14443bReaderUartBit(uint8_t bit) { if (Uart.bitCnt > 12) { // Give up if we see too many zeros without a one, too. LED_A_OFF(); - Uart.state = STATE_UNSYNCD; + Uart.state = STATE_14B_UNSYNCD; } break; - case STATE_AWAITING_START_BIT: + case STATE_14B_AWAITING_START_BIT: Uart.posCnt++; if (bit) { if (Uart.posCnt > 50 / 2) { // max 57us between characters = 49 1/fs, max 3 etus after low phase of SOF = 24 1/fs // stayed high for too long between characters, error - Uart.state = STATE_UNSYNCD; + Uart.state = STATE_14B_UNSYNCD; } } else { // falling edge, this starts the data byte Uart.posCnt = 0; Uart.bitCnt = 0; Uart.shiftReg = 0; - Uart.state = STATE_RECEIVING_DATA; + Uart.state = STATE_14B_RECEIVING_DATA; } break; - case STATE_RECEIVING_DATA: + case STATE_14B_RECEIVING_DATA: Uart.posCnt++; if (Uart.posCnt == 2) { // time to sample a bit @@ -391,30 +405,30 @@ static RAMFUNC int Handle14443bReaderUartBit(uint8_t bit) { if (Uart.byteCnt >= Uart.byteCntMax) { // Buffer overflowed, give up LED_A_OFF(); - Uart.state = STATE_UNSYNCD; + Uart.state = STATE_14B_UNSYNCD; } else { // so get the next byte now Uart.posCnt = 0; - Uart.state = STATE_AWAITING_START_BIT; + Uart.state = STATE_14B_AWAITING_START_BIT; } } else if (Uart.shiftReg == 0x000) { // this is an EOF byte LED_A_OFF(); // Finished receiving - Uart.state = STATE_UNSYNCD; + Uart.state = STATE_14B_UNSYNCD; if (Uart.byteCnt != 0) return true; } else { // this is an error LED_A_OFF(); - Uart.state = STATE_UNSYNCD; + Uart.state = STATE_14B_UNSYNCD; } } break; default: LED_A_OFF(); - Uart.state = STATE_UNSYNCD; + Uart.state = STATE_14B_UNSYNCD; break; } return false; @@ -454,7 +468,7 @@ static int GetIso14443bCommandFromReader(uint8_t *received, uint16_t *len) { } */ // Now run a `software UART' on the stream of incoming samples. - UartInit(received); + Uart14bInit(received); uint8_t mask; while (!BUTTON_PRESS()) { @@ -949,7 +963,7 @@ static void GetTagSamplesFor14443bDemod() { BigBuf_free(); // Set up the demodulator for tag -> reader responses. - DemodInit(BigBuf_malloc(MAX_FRAME_SIZE)); + Demod14bInit(BigBuf_malloc(MAX_FRAME_SIZE)); // The DMA buffer, used to stream samples from the FPGA int8_t *dmaBuf = (int8_t *) BigBuf_malloc(ISO14443B_DMA_BUFFER_SIZE); @@ -1306,8 +1320,8 @@ void iso14443b_setup() { FpgaDownloadAndGo(FPGA_BITSTREAM_HF); // Initialize Demod and Uart structs - DemodInit(BigBuf_malloc(MAX_FRAME_SIZE)); - UartInit(BigBuf_malloc(MAX_FRAME_SIZE)); + Demod14bInit(BigBuf_malloc(MAX_FRAME_SIZE)); + Uart14bInit(BigBuf_malloc(MAX_FRAME_SIZE)); // connect Demodulated Signal to ADC: SetAdcMuxFor(GPIO_MUXSEL_HIPKD); @@ -1411,8 +1425,8 @@ static void iso1444b_setup_sniff(void) { set_tracing(true); // Initialize Demod and Uart structs - DemodInit(BigBuf_malloc(MAX_FRAME_SIZE)); - UartInit(BigBuf_malloc(MAX_FRAME_SIZE)); + Demod14bInit(BigBuf_malloc(MAX_FRAME_SIZE)); + Uart14bInit(BigBuf_malloc(MAX_FRAME_SIZE)); if (DBGLEVEL > 1) { // Print debug information about the buffer sizes @@ -1502,8 +1516,8 @@ void RAMFUNC SniffIso14443b(void) { if (Handle14443bReaderUartBit(ci & 0x01)) { time_stop = GetCountSspClk() - time_0; LogTrace(Uart.output, Uart.byteCnt, time_start, time_stop, NULL, true); - UartReset(); - DemodReset(); + Uart14bReset(); + Demod14bReset(); } else { time_start = GetCountSspClk() - time_0; } @@ -1511,12 +1525,12 @@ void RAMFUNC SniffIso14443b(void) { if (Handle14443bReaderUartBit(cq & 0x01)) { time_stop = GetCountSspClk() - time_0; LogTrace(Uart.output, Uart.byteCnt, time_start, time_stop, NULL, true); - UartReset(); - DemodReset(); + Uart14bReset(); + Demod14bReset(); } else { time_start = GetCountSspClk() - time_0; } - ReaderIsActive = (Uart.state > STATE_GOT_FALLING_EDGE_OF_SOF); + ReaderIsActive = (Uart.state > STATE_14B_GOT_FALLING_EDGE_OF_SOF); } // no need to try decoding tag data if the reader is sending - and we cannot afford the time @@ -1527,8 +1541,8 @@ void RAMFUNC SniffIso14443b(void) { if (Handle14443bTagSamplesDemod(ci, cq)) { time_stop = GetCountSspClk() - time_0; LogTrace(Demod.output, Demod.len, time_start, time_stop, NULL, false); - UartReset(); - DemodReset(); + Uart14bReset(); + Demod14bReset(); } else { time_start = GetCountSspClk() - time_0; } diff --git a/armsrc/iso14443b.h b/armsrc/iso14443b.h index 5ea3d530b..12ee316e9 100644 --- a/armsrc/iso14443b.h +++ b/armsrc/iso14443b.h @@ -13,18 +13,10 @@ #ifndef __ISO14443B_H #define __ISO14443B_H -#ifdef __cplusplus -extern "C" { -#endif +#include "common.h" -#include "proxmark3.h" -#include "common.h" // access to global variable: DBGLEVEL -#include "apps.h" -#include "util.h" -#include "string.h" -#include "crc16.h" #include "mifare.h" -#include "protocols.h" +#include "pm3_cmd.h" #ifndef AddCrc14A # define AddCrc14A(data, len) compute_crc(CRC_14443_A, (data), (len), (data)+(len), (data)+(len)+1) @@ -34,12 +26,18 @@ extern "C" { # define AddCrc14B(data, len) compute_crc(CRC_14443_B, (data), (len), (data)+(len), (data)+(len)+1) #endif -void SendRawCommand14443B_Ex(PacketCommandNG *c); void iso14443b_setup(); uint8_t iso14443b_apdu(uint8_t const *message, size_t message_length, uint8_t *response); uint8_t iso14443b_select_card(iso14b_card_select_t *card); uint8_t iso14443b_select_card_srx(iso14b_card_select_t *card); +void SimulateIso14443bTag(uint32_t pupi); +void AcquireRawAdcSamplesIso14443b(uint32_t parameter); +void ReadSTMemoryIso14443b(uint8_t numofblocks); +void RAMFUNC SniffIso14443b(void); +void SendRawCommand14443B(uint32_t, uint32_t, uint8_t, uint8_t[]); +void SendRawCommand14443B_Ex(PacketCommandNG *c); + // testfunctions void WaitForFpgaDelayQueueIsEmpty(uint16_t delay); void ClearFpgaShiftingRegisters(void); @@ -53,8 +51,4 @@ void ClearFpgaShiftingRegisters(void); #define SIM_ACKNOWLEDGE 5 #define SIM_WORK 6 -#ifdef __cplusplus -} -#endif - #endif /* __ISO14443B_H */ diff --git a/armsrc/iso15693.c b/armsrc/iso15693.c index c33230090..84de71021 100644 --- a/armsrc/iso15693.c +++ b/armsrc/iso15693.c @@ -58,12 +58,20 @@ // *) remove or refactor code under "depricated" // *) document all the functions -#include "proxmark3.h" +#include "iso15693.h" + +#include "proxmark3_arm.h" #include "util.h" -#include "apps.h" #include "string.h" #include "iso15693tools.h" #include "cmd.h" +#include "appmain.h" +#include "dbprint.h" +#include "fpgaloader.h" +#include "commonutil.h" +#include "ticks.h" +#include "BigBuf.h" +#include "crc16.h" /////////////////////////////////////////////////////////////////////// // ISO 15693 Part 2 - Air Interface diff --git a/armsrc/iso15693.h b/armsrc/iso15693.h new file mode 100644 index 000000000..2233ba9fd --- /dev/null +++ b/armsrc/iso15693.h @@ -0,0 +1,26 @@ +//----------------------------------------------------------------------------- +// Jonathan Westhues, Aug 2005 +// Gerhard de Koning Gans, April 2008, May 2011 +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// Definitions internal to the app source. +//----------------------------------------------------------------------------- +#ifndef __ISO15693_H +#define __ISO15693_H + +#include "common.h" + +#include "pm3_cmd.h" // struct + +void RecordRawAdcSamplesIso15693(void); +void AcquireRawAdcSamplesIso15693(void); +void ReaderIso15693(uint32_t parameter); // Simulate an ISO15693 reader - greg +void SimTagIso15693(uint32_t parameter, uint8_t *uid); // simulate an ISO15693 tag - greg +void BruteforceIso15693Afi(uint32_t speed); // find an AFI of a tag - atrox +void DirectTag15693Command(uint32_t datalen, uint32_t speed, uint32_t recv, uint8_t *data); // send arbitrary commands from CLI - atrox +void Iso15693InitReader(void); + +#endif diff --git a/armsrc/ldscript b/armsrc/ldscript index 80c2a4aed..4d48d9948 100644 --- a/armsrc/ldscript +++ b/armsrc/ldscript @@ -7,7 +7,7 @@ Linker script for the ARM binary ----------------------------------------------------------------------------- */ -INCLUDE ../common/ldscript.common +INCLUDE ../common_arm/ldscript.common PHDRS { diff --git a/armsrc/legicrf.c b/armsrc/legicrf.c index 1b689550d..0665705b6 100644 --- a/armsrc/legicrf.c +++ b/armsrc/legicrf.c @@ -11,11 +11,20 @@ //----------------------------------------------------------------------------- #include "legicrf.h" -#include "ticks.h" /* timers */ #include "crc.h" /* legic crc-4 */ #include "legic_prng.h" /* legic PRNG impl */ #include "legic.h" /* legic_card_select_t struct */ +#include "proxmark3_arm.h" +#include "cmd.h" +#include "BigBuf.h" +#include "fpgaloader.h" +#include "ticks.h" +#include "dbprint.h" +#include "util.h" +#include "string.h" +#include "protocols.h" + static uint8_t *legic_mem; /* card memory, used for read, write */ static legic_card_select_t card;/* metadata of currently selected card */ static crc_t legic_crc; diff --git a/armsrc/legicrf.h b/armsrc/legicrf.h index 76c392257..47a7f89d6 100644 --- a/armsrc/legicrf.h +++ b/armsrc/legicrf.h @@ -12,7 +12,7 @@ #ifndef __LEGICRF_H #define __LEGICRF_H -#include "proxmark3.h" +#include "common.h" void LegicRfInfo(void); void LegicRfReader(uint16_t offset, uint16_t len, uint8_t iv); diff --git a/armsrc/legicrfsim.c b/armsrc/legicrfsim.c index 0500e3e32..111c4940b 100644 --- a/armsrc/legicrfsim.c +++ b/armsrc/legicrfsim.c @@ -11,11 +11,17 @@ //----------------------------------------------------------------------------- #include "legicrf.h" -#include "ticks.h" /* timers */ #include "crc.h" /* legic crc-4 */ #include "legic_prng.h" /* legic PRNG impl */ #include "legic.h" /* legic_card_select_t struct */ +#include "proxmark3_arm.h" +#include "BigBuf.h" +#include "fpgaloader.h" +#include "ticks.h" +#include "dbprint.h" +#include "util.h" + static uint8_t *legic_mem; /* card memory, used for sim */ static legic_card_select_t card;/* metadata of currently selected card */ static crc_t legic_crc; diff --git a/armsrc/legicrfsim.h b/armsrc/legicrfsim.h index 27fce129b..3d25fae0c 100644 --- a/armsrc/legicrfsim.h +++ b/armsrc/legicrfsim.h @@ -12,7 +12,7 @@ #ifndef __LEGICRFSIM_H #define __LEGICRFSIM_H -#include "proxmark3.h" +#include "common.h" void LegicRfSimulate(uint8_t tagtype); diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 1ef366cfb..bee1413fc 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -8,18 +8,23 @@ // Also routines for raw mode reading/simulating of LF waveform //----------------------------------------------------------------------------- -#include "proxmark3.h" -#include "apps.h" +#include "lfops.h" + +#include "proxmark3_arm.h" +#include "cmd.h" +#include "BigBuf.h" +#include "fpgaloader.h" +#include "ticks.h" +#include "dbprint.h" #include "util.h" -#include "hitag2.h" +#include "commonutil.h" + #include "crc16.h" #include "string.h" #include "printf.h" #include "lfdemod.h" #include "lfsampling.h" #include "protocols.h" -#include "usb_cdc.h" // for usb_poll_validate_length -#include "common.h" #include "pmflash.h" #include "flashmem.h" // persistence on flash @@ -154,6 +159,30 @@ t55xx_configurations_t T55xx_Timing = { #define T55XX_DLMODE_1OF4 3 // 1 of 4 #define T55XX_LONGLEADINGREFERENCE 4 // Value to tell Write Bit to send long reference +// ATA55xx shared presets & routines +static uint32_t GetT55xxClockBit(uint32_t clock) { + switch (clock) { + case 128: + return T55x7_BITRATE_RF_128; + case 100: + return T55x7_BITRATE_RF_100; + case 64: + return T55x7_BITRATE_RF_64; + case 50: + return T55x7_BITRATE_RF_50; + case 40: + return T55x7_BITRATE_RF_40; + case 32: + return T55x7_BITRATE_RF_32; + case 16: + return T55x7_BITRATE_RF_16; + case 8: + return T55x7_BITRATE_RF_8; + default : + return 0; + } +} + void printT55xxConfig(void) { #define PRN_NA sprintf(s + strlen(s), _RED_("N/A") "| "); diff --git a/armsrc/lfops.h b/armsrc/lfops.h new file mode 100644 index 000000000..186b41f90 --- /dev/null +++ b/armsrc/lfops.h @@ -0,0 +1,69 @@ +//----------------------------------------------------------------------------- +// Jonathan Westhues, Aug 2005 +// Gerhard de Koning Gans, April 2008, May 2011 +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// Definitions internal to the app source. +//----------------------------------------------------------------------------- +#ifndef __LFOPS_H +#define __LFOPS_H + +#include "common.h" + +#include "pm3_cmd.h" // struct + +extern uint8_t decimation; +extern uint8_t bits_per_sample ; +extern bool averaging; + +void AcquireRawAdcSamples125k(int divisor); +void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint32_t period_1, uint8_t *command); +void ReadTItag(void); +void WriteTItag(uint32_t idhi, uint32_t idlo, uint16_t crc); + +void AcquireTiType(void); +void AcquireRawBitsTI(void); +void SimulateTagLowFrequencyEx(int period, int gap, bool ledcontrol, int numcycles); +void SimulateTagLowFrequency(int period, int gap, bool ledcontrol); +void SimulateTagLowFrequencyBidir(int divisor, int max_bitlen); + +void CmdHIDsimTAGEx(uint32_t hi, uint32_t lo, bool ledcontrol, int numcycles); +void CmdHIDsimTAG(uint32_t hi, uint32_t lo, bool ledcontrol); + +void CmdFSKsimTAG(uint8_t fchigh, uint8_t fclow, uint8_t separator, uint8_t clk, uint16_t bitslen, uint8_t *bits, bool ledcontrol); +void CmdASKsimTAG(uint8_t encoding, uint8_t invert, uint8_t separator, uint8_t clk, uint16_t size, uint8_t *bits, bool ledcontrol); +void CmdPSKsimTag(uint8_t carrier, uint8_t invert, uint8_t clk, uint16_t size, uint8_t *bits, bool ledcontrol); + +void CmdHIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol); +void CmdAWIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol); // Realtime demodulation mode for AWID26 +void CmdEM410xdemod(int findone, uint32_t *high, uint64_t *low, int ledcontrol); +void CmdIOdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol); +void CopyIOtoT55x7(uint32_t hi, uint32_t lo); // Clone an ioProx card to T5557/T5567 +void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT); // Clone an HID card to T5557/T5567 +void CopyVikingtoT55xx(uint32_t block1, uint32_t block2, uint8_t Q5); +void WriteEM410x(uint32_t card, uint32_t id_hi, uint32_t id_lo); +void CopyIndala64toT55x7(uint32_t hi, uint32_t lo); // Clone Indala 64-bit tag by UID to T55x7 +void CopyIndala224toT55x7(uint32_t uid1, uint32_t uid2, uint32_t uid3, uint32_t uid4, uint32_t uid5, uint32_t uid6, uint32_t uid7); // Clone Indala 224-bit tag by UID to T55x7 +void T55xxResetRead(uint8_t flags); +//id T55xxWriteBlock(uint32_t data, uint8_t blockno, uint32_t pwd, uint8_t flags); +void T55xxWriteBlock(uint8_t *data); +// void T55xxWriteBlockExt(uint32_t data, uint8_t blockno, uint32_t pwd, uint8_t flags); +void T55xxReadBlock(uint8_t page, bool pwd_mode, bool brute_mem, uint8_t block, uint32_t pwd, uint8_t downlink_mode); +void T55xxWakeUp(uint32_t pwd, uint8_t flags); +void T55xx_ChkPwds(uint8_t flags); + +void TurnReadLFOn(uint32_t delay); + +void EM4xReadWord(uint8_t addr, uint32_t pwd, uint8_t usepwd); +void EM4xWriteWord(uint8_t addr, uint32_t data, uint32_t pwd, uint8_t usepwd); + +void Cotag(uint32_t arg0); +void setT55xxConfig(uint8_t arg0, t55xx_configurations_t *c); +t55xx_configurations_t *getT55xxConfig(void); +void printT55xxConfig(void); +void loadT55xxConfig(void); + +#endif diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index 2e6ed88a4..498d8f747 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -8,6 +8,14 @@ #include "lfsampling.h" +#include "proxmark3_arm.h" +#include "BigBuf.h" +#include "fpgaloader.h" +#include "ticks.h" +#include "dbprint.h" +#include "util.h" +#include "lfdemod.h" + /* Default LF config is set to: decimation = 1 (we keep 1 out of 1 samples) diff --git a/armsrc/lfsampling.h b/armsrc/lfsampling.h index e3c7a0b4d..b17a871ba 100644 --- a/armsrc/lfsampling.h +++ b/armsrc/lfsampling.h @@ -1,12 +1,8 @@ #ifndef __LFSAMPLING_H #define __LFSAMPLING_H -#include "proxmark3.h" -#include "apps.h" -#include "util.h" -#include "string.h" -#include "usb_cdc.h" // for usb_poll_validate_length -#include "ticks.h" // for StartTicks +#include "common.h" +#include "pm3_cmd.h" typedef struct BitstreamOut BitstreamOut; @@ -82,5 +78,4 @@ sample_config *getSamplingConfig(); void printConfig(); - #endif // __LFSAMPLING_H diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 3784f8feb..5e9de52dd 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -15,9 +15,23 @@ #include "mifarecmd.h" -#include - #include "pmflash.h" +#include "proxmark3_arm.h" +#include "string.h" +#include "mifareutil.h" +#include "protocols.h" +#include "parity.h" +#include "BigBuf.h" +#include "cmd.h" +#include "flashmem.h" +#include "fpgaloader.h" +#include "iso14443a.h" +#include "mifaredesfire.h" +#include "util.h" +#include "commonutil.h" +#include "crc16.h" +#include "dbprint.h" +#include "ticks.h" #ifndef HARDNESTED_AUTHENTICATION_TIMEOUT # define HARDNESTED_AUTHENTICATION_TIMEOUT 848 // card times out 1ms after wrong authentication (according to NXP documentation) diff --git a/armsrc/mifarecmd.h b/armsrc/mifarecmd.h index 5e4a5cf97..445b04130 100644 --- a/armsrc/mifarecmd.h +++ b/armsrc/mifarecmd.h @@ -1,27 +1,52 @@ //----------------------------------------------------------------------------- -// Merlok - June 2011 -// Gerhard de Koning Gans - May 2008 -// Hagen Fritsch - June 2010 +// Jonathan Westhues, Aug 2005 +// Gerhard de Koning Gans, April 2008, May 2011 // // This code is licensed to you under the terms of the GNU GPL, version 2 or, // at your option, any later version. See the LICENSE.txt file for the text of // the license. //----------------------------------------------------------------------------- -// Routines to support ISO 14443 type A. +// Definitions internal to the app source. //----------------------------------------------------------------------------- - #ifndef __MIFARECMD_H #define __MIFARECMD_H -#include "proxmark3.h" -#include "apps.h" -#include "util.h" -#include "string.h" -#include "iso14443a.h" -#include "crapto1/crapto1.h" -#include "mifareutil.h" #include "common.h" -#include "crc.h" -#include "protocols.h" -#include "parity.h" + +void MifareReadBlock(uint8_t blockNo, uint8_t keyType, uint8_t *datain); + +void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain); +void MifareUC_Auth(uint8_t arg0, uint8_t *keybytes); +void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain); +void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t *datain); +void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain); +//void MifareUWriteBlockCompat(uint8_t arg0,uint8_t *datain); +void MifareUWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain); +void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain); +void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, uint8_t *datain); +void MifareAcquireNonces(uint32_t arg0, uint32_t flags); +void MifareChkKeys(uint8_t *datain); +void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain); + +void MifareEMemClr(void); +void MifareEMemSet(uint8_t blockno, uint8_t blockcnt, uint8_t blockwidth, uint8_t *datain); +void MifareEMemGet(uint8_t blockno, uint8_t blockcnt); +int MifareECardLoad(uint32_t arg0, uint32_t arg1); + +void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain); // Work with "magic Chinese" card +void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain); +void MifareCIdent(); // is "magic chinese" card? + +void MifareSetMod(uint8_t *datain); +void MifareUSetPwd(uint8_t arg0, uint8_t *datain); +void OnSuccessMagic(); +void OnErrorMagic(uint8_t reason); + +int32_t dist_nt(uint32_t nt1, uint32_t nt2); +void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype); +//void RAMFUNC SniffMifare(uint8_t param); + +void Mifare_DES_Auth1(uint8_t arg0, uint8_t *datain); +void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain); + #endif diff --git a/armsrc/mifaredesfire.c b/armsrc/mifaredesfire.c index c57fed866..e16c00ed1 100644 --- a/armsrc/mifaredesfire.c +++ b/armsrc/mifaredesfire.c @@ -1,5 +1,20 @@ #include "mifaredesfire.h" +#include "common.h" +#include "proxmark3_arm.h" +#include "string.h" +#include "BigBuf.h" +#include "desfire_key.h" +#include "mifareutil.h" +#include "des.h" +#include "cmd.h" +#include "dbprint.h" +#include "fpgaloader.h" +#include "iso14443a.h" +#include "crc16.h" +#include "mbedtls/aes.h" +#include "commonutil.h" + #define MAX_APPLICATION_COUNT 28 #define MAX_FILE_COUNT 16 #define MAX_DESFIRE_FRAME_SIZE 60 diff --git a/armsrc/mifaredesfire.h b/armsrc/mifaredesfire.h index 7547dfcb2..8daed69aa 100644 --- a/armsrc/mifaredesfire.h +++ b/armsrc/mifaredesfire.h @@ -1,13 +1,26 @@ +//----------------------------------------------------------------------------- +// Jonathan Westhues, Aug 2005 +// Gerhard de Koning Gans, April 2008, May 2011 +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// Definitions internal to the app source. +//----------------------------------------------------------------------------- #ifndef __MIFAREDESFIRE_H #define __MIFAREDESFIRE_H #include "common.h" -#include "proxmark3.h" -#include "apps.h" -#include "string.h" -#include "BigBuf.h" -#include "iso14443a.h" -#include "desfire_key.h" -#include "mifareutil.h" -#include "des.h" + +bool InitDesfireCard(); +void MifareSendCommand(uint8_t arg0, uint8_t arg1, uint8_t *datain); +void MifareDesfireGetInformation(); +void MifareDES_Auth1(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain); +void ReaderMifareDES(uint32_t param, uint32_t param2, uint8_t *datain); +int DesfireAPDU(uint8_t *cmd, size_t cmd_len, uint8_t *dataout); +size_t CreateAPDU(uint8_t *datain, size_t len, uint8_t *dataout); +void OnSuccess(); +void OnError(uint8_t reason); + #endif diff --git a/armsrc/mifaresim.c b/armsrc/mifaresim.c index 5eadef0ea..7edcec398 100644 --- a/armsrc/mifaresim.c +++ b/armsrc/mifaresim.c @@ -20,19 +20,24 @@ // /!\ Printing Debug message is disrupting emulation, // Only use with caution during debugging +#include "mifaresim.h" + +#include #include "iso14443a.h" -#include "mifaresim.h" -#include "crapto1/crapto1.h" #include "BigBuf.h" #include "string.h" #include "mifareutil.h" #include "fpgaloader.h" -#include "proxmark3.h" -#include "usb_cdc.h" +#include "proxmark3_arm.h" #include "cmd.h" #include "protocols.h" -#include "apps.h" +#include "appmain.h" +#include "util.h" +#include "commonutil.h" +#include "crc16.h" +#include "dbprint.h" +#include "ticks.h" static bool IsTrailerAccessAllowed(uint8_t blockNo, uint8_t keytype, uint8_t action) { uint8_t sector_trailer[16]; @@ -506,7 +511,7 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1 uint8_t rAUTH_NT_keystream[4]; uint32_t nonce = 0; - tUart *uart = GetUart(); + tUart14a *uart = GetUart14a(); // free eventually allocated BigBuf memory but keep Emulator Memory BigBuf_free_keep_EM(); diff --git a/armsrc/mifaresim.h b/armsrc/mifaresim.h index a161d2974..d8c15aee2 100644 --- a/armsrc/mifaresim.h +++ b/armsrc/mifaresim.h @@ -13,14 +13,12 @@ #ifndef __MIFARESIM_H #define __MIFARESIM_H -#include +#include "common.h" #ifndef CheckCrc14A # define CheckCrc14A(data, len) check_crc(CRC_14443_A, (data), (len)) #endif -void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint16_t atqa, uint8_t sak); - #define AC_DATA_READ 0 #define AC_DATA_WRITE 1 #define AC_DATA_INC 2 @@ -36,4 +34,6 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1 #define AUTHKEYB 1 #define AUTHKEYNONE 0xff +void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint16_t atqa, uint8_t sak); + #endif diff --git a/armsrc/mifaresniff.c b/armsrc/mifaresniff_disabled.c similarity index 96% rename from armsrc/mifaresniff.c rename to armsrc/mifaresniff_disabled.c index 4171ab572..799fd62be 100644 --- a/armsrc/mifaresniff.c +++ b/armsrc/mifaresniff_disabled.c @@ -68,10 +68,10 @@ void RAMFUNC SniffMifare(uint8_t param) { // Set up the demodulator for tag -> reader responses. - DemodInit(receivedResp, receivedRespPar); + Demod14aInit(receivedResp, receivedRespPar); // Set up the demodulator for the reader -> tag commands - UartInit(receivedCmd, receivedCmdPar); + Uart14aInit(receivedCmd, receivedCmdPar); // Setup and start DMA. // set transfer address and number of bytes. Start transfer. @@ -80,8 +80,8 @@ void RAMFUNC SniffMifare(uint8_t param) { return; } - tUart *uart = GetUart(); - tDemod *demod = GetDemod(); + tUart14a *uart = GetUart14a(); + tDemod14a *demod = GetDemod14a(); MfSniffInit(); @@ -149,10 +149,10 @@ void RAMFUNC SniffMifare(uint8_t param) { uint8_t readerbyte = (previous_data & 0xF0) | (*data >> 4); if (MillerDecoding(readerbyte, (sniffCounter - 1) * 4)) { LogTrace(receivedCmd, uart->len, 0, 0, NULL, true); - DemodReset(); - UartReset(); + Demod14aReset(); + Uart14aReset(); } - ReaderIsActive = (uart->state != STATE_UNSYNCD); + ReaderIsActive = (uart->state != STATE_14A_UNSYNCD); } // no need to try decoding tag data if the reader is sending @@ -160,10 +160,10 @@ void RAMFUNC SniffMifare(uint8_t param) { uint8_t tagbyte = (previous_data << 4) | (*data & 0x0F); if (ManchesterDecoding(tagbyte, 0, (sniffCounter - 1) * 4)) { LogTrace(receivedResp, demod->len, 0, 0, NULL, false); - DemodReset(); - UartReset(); + Demod14aReset(); + Uart14aReset(); } - TagIsActive = (demod->state != DEMOD_UNSYNCD); + TagIsActive = (demod->state != DEMOD_14A_UNSYNCD); } } previous_data = *data; diff --git a/armsrc/mifaresniff.h b/armsrc/mifaresniff_disabled.h similarity index 87% rename from armsrc/mifaresniff.h rename to armsrc/mifaresniff_disabled.h index 198d14daf..426e5ccfa 100644 --- a/armsrc/mifaresniff.h +++ b/armsrc/mifaresniff_disabled.h @@ -11,13 +11,6 @@ #ifndef __MIFARESNIFF_H #define __MIFARESNIFF_H -#include "proxmark3.h" -#include "apps.h" -#include "util.h" -#include "string.h" -#include "iso14443a.h" -#include "crapto1/crapto1.h" -#include "mifareutil.h" #include "common.h" #define SNF_INIT 0 diff --git a/armsrc/mifareutil.c b/armsrc/mifareutil.c index b5f7567f9..ca112f1f8 100644 --- a/armsrc/mifareutil.c +++ b/armsrc/mifareutil.c @@ -9,6 +9,17 @@ //----------------------------------------------------------------------------- #include "mifareutil.h" +#include "string.h" +#include "BigBuf.h" +#include "iso14443a.h" +#include "ticks.h" +#include "dbprint.h" +#include "parity.h" +#include "commonutil.h" +#include "crc16.h" +#include "protocols.h" +#include "des.h" + int DBGLEVEL = DBG_ERROR; // crypto1 helpers diff --git a/armsrc/mifareutil.h b/armsrc/mifareutil.h index a2086c5e7..64eb04545 100644 --- a/armsrc/mifareutil.h +++ b/armsrc/mifareutil.h @@ -12,14 +12,8 @@ #ifndef __MIFAREUTIL_H #define __MIFAREUTIL_H -#include "proxmark3.h" -#include "apps.h" -#include "parity.h" -#include "util.h" -#include "string.h" -#include "iso14443a.h" +#include "common.h" #include "crapto1/crapto1.h" -#include "des.h" // mifare authentication #define CRYPT_NONE 0 diff --git a/armsrc/nprintf.c b/armsrc/nprintf.c index 62e6ea8c0..b61ad794d 100644 --- a/armsrc/nprintf.c +++ b/armsrc/nprintf.c @@ -30,9 +30,6 @@ // /////////////////////////////////////////////////////////////////////////////// -#include -#include - #include "nprintf.h" diff --git a/armsrc/nprintf.h b/armsrc/nprintf.h index 3cfdb4134..5c83384b7 100644 --- a/armsrc/nprintf.h +++ b/armsrc/nprintf.h @@ -32,14 +32,10 @@ #ifndef _PRINTF_H_ #define _PRINTF_H_ -#include +#include +#include #include - - -#ifdef __cplusplus -extern "C" { -#endif - +#include /** * Output a character to a custom device like UART, used by the printf() function @@ -108,10 +104,4 @@ int vprintf_(const char *format, va_list va); */ int fctprintf(void (*out)(char character, void *arg), void *arg, const char *format, ...); - -#ifdef __cplusplus -} -#endif - - #endif // _PRINTF_H_ diff --git a/armsrc/optimized_cipher.h b/armsrc/optimized_cipher.h index 9bf0516de..893297ddd 100644 --- a/armsrc/optimized_cipher.h +++ b/armsrc/optimized_cipher.h @@ -1,9 +1,7 @@ #ifndef OPTIMIZED_CIPHER_H #define OPTIMIZED_CIPHER_H -#include -#include -#include +#include "common.h" /** * Definition 1 (Cipher state). A cipher state of iClass s is an element of F 40/2 diff --git a/armsrc/pcf7931.c b/armsrc/pcf7931.c index a80e30927..2c679b31f 100644 --- a/armsrc/pcf7931.c +++ b/armsrc/pcf7931.c @@ -1,5 +1,15 @@ #include "pcf7931.h" +#include "proxmark3_arm.h" +#include "cmd.h" +#include "BigBuf.h" +#include "fpgaloader.h" +#include "ticks.h" +#include "dbprint.h" +#include "util.h" +#include "lfsampling.h" +#include "string.h" + #define T0_PCF 8 //period for the pcf7931 in us #define ALLOC 16 diff --git a/armsrc/pcf7931.h b/armsrc/pcf7931.h index 5e3c5a8e4..67a11f5f8 100644 --- a/armsrc/pcf7931.h +++ b/armsrc/pcf7931.h @@ -1,11 +1,7 @@ #ifndef __PCF7931_H #define __PCF7931_H -#include "proxmark3.h" -#include "apps.h" -#include "lfsampling.h" -#include "pcf7931.h" -#include "string.h" +#include "common.h" size_t DemodPCF7931(uint8_t **outBlocks); bool IsBlock0PCF7931(uint8_t *block); diff --git a/armsrc/printf.c b/armsrc/printf.c index d0d873e7d..0dffbb037 100644 --- a/armsrc/printf.c +++ b/armsrc/printf.c @@ -35,6 +35,8 @@ */ #include "printf.h" +#include "string.h" + typedef unsigned char u_char; typedef unsigned int u_int; typedef unsigned long long u_quad_t; diff --git a/armsrc/printf.h b/armsrc/printf.h index ff0143790..bd0a6e2c9 100644 --- a/armsrc/printf.h +++ b/armsrc/printf.h @@ -11,9 +11,8 @@ #ifndef __PRINTF_H #define __PRINTF_H -#include -#include -#include "string.h" +#include "common.h" +#include // va_list int kvsprintf(const char *fmt, void *arg, int radix, va_list ap) __attribute__((format(printf, 1, 0))); int vsprintf(char *dest, const char *fmt, va_list ap) __attribute__((format(printf, 2, 0))); diff --git a/common/radixsort.c b/armsrc/radixsort.c similarity index 100% rename from common/radixsort.c rename to armsrc/radixsort.c diff --git a/common/radixsort.h b/armsrc/radixsort.h similarity index 87% rename from common/radixsort.h rename to armsrc/radixsort.h index 41a036461..fb2bcc044 100644 --- a/common/radixsort.h +++ b/armsrc/radixsort.h @@ -1,9 +1,7 @@ #ifndef RADIXSORT_H__ #define RADIXSORT_H__ -#include -#include -#include +#include "common.h" typedef union { struct { @@ -20,4 +18,5 @@ typedef union { } rscounts_t; uint64_t *radixSort(uint64_t *array, uint32_t size); + #endif // RADIXSORT_H__ diff --git a/armsrc/spiffs.c b/armsrc/spiffs.c index 7fd712e7f..de6e9e226 100644 --- a/armsrc/spiffs.c +++ b/armsrc/spiffs.c @@ -43,6 +43,12 @@ RDV40_SPIFFS_SAFE_FOOTER #include "spiffs.h" +#include "flashmem.h" +#include "dbprint.h" +#include "printf.h" +#include "common.h" +#include "string.h" +#include "BigBuf.h" ///// FLASH LEVEL R/W/E operations for feeding SPIFFS Driver///////////////// static s32_t rdv40_spiffs_llread(u32_t addr, u32_t size, u8_t *dst) { diff --git a/armsrc/spiffs.h b/armsrc/spiffs.h index f36bde4b0..29e8215b0 100644 --- a/armsrc/spiffs.h +++ b/armsrc/spiffs.h @@ -7,9 +7,8 @@ #ifndef SPIFFS_H_ #define SPIFFS_H_ -#if defined(__cplusplus) -extern "C" { -#endif + +#include "common.h" #include "spiffs_config.h" @@ -854,8 +853,5 @@ u32_t SPIFFS_buffer_bytes_for_cache(spiffs *fs, u32_t num_pages); #if SPIFFS_CACHE #endif -#if defined(__cplusplus) -} -#endif #endif /* SPIFFS_H_ */ diff --git a/armsrc/spiffs_config.h b/armsrc/spiffs_config.h index 99557f41f..6fe1f48c6 100644 --- a/armsrc/spiffs_config.h +++ b/armsrc/spiffs_config.h @@ -8,22 +8,7 @@ #ifndef SPIFFS_CONFIG_H_ #define SPIFFS_CONFIG_H_ -// ----------- 8< ------------ -// Following includes are for the linux test build of spiffs -// These may/should/must be removed/altered/replaced in your target -//#include -//#include -// -#include "printf.h" -#include "string.h" -#include "flashmem.h" - -void Dbprintf(const char *fmt, ...); - -//#include -//#include -// ----------- >8 ------------ - +#include "common.h" typedef int s32_t; typedef uint32_t u32_t; diff --git a/armsrc/spiffs_nucleus.h b/armsrc/spiffs_nucleus.h index c4a360384..c437faf30 100644 --- a/armsrc/spiffs_nucleus.h +++ b/armsrc/spiffs_nucleus.h @@ -110,6 +110,11 @@ #ifndef SPIFFS_NUCLEUS_H_ #define SPIFFS_NUCLEUS_H_ +#include "common.h" + +#include "string.h" +#include "spiffs.h" + #define _SPIFFS_ERR_CHECK_FIRST (SPIFFS_ERR_INTERNAL - 1) #define SPIFFS_ERR_CHECK_OBJ_ID_MISM (SPIFFS_ERR_INTERNAL - 1) #define SPIFFS_ERR_CHECK_SPIX_MISM (SPIFFS_ERR_INTERNAL - 2) diff --git a/armsrc/start.c b/armsrc/start.c index 94eb429ac..3e6f34702 100644 --- a/armsrc/start.c +++ b/armsrc/start.c @@ -12,8 +12,8 @@ #ifndef __START_H #define __START_H -#include "proxmark3.h" -#include "apps.h" +#include "proxmark3_arm.h" +#include "appmain.h" #include "zlib.h" #include "BigBuf.h" diff --git a/armsrc/string.h b/armsrc/string.h index 5e3e31137..781641fb9 100644 --- a/armsrc/string.h +++ b/armsrc/string.h @@ -12,7 +12,7 @@ #ifndef __STRING_H #define __STRING_H -#include +#include "common.h" int strlen(const char *str); void *memcpy(void *dest, const void *src, int len); @@ -36,7 +36,4 @@ int strncmp(const char *s1, const char *s2, size_t n); char c_tolower(int c); char c_isprint(unsigned char c); - - - #endif /* __STRING_H */ diff --git a/armsrc/thinfilm.c b/armsrc/thinfilm.c index 735fdb041..bd8e696fb 100644 --- a/armsrc/thinfilm.c +++ b/armsrc/thinfilm.c @@ -10,6 +10,16 @@ #include "thinfilm.h" +#include "proxmark3_arm.h" +#include "cmd.h" +#include "appmain.h" +#include "BigBuf.h" +#include "iso14443a.h" +#include "fpgaloader.h" +#include "ticks.h" +#include "dbprint.h" +#include "util.h" + /** * ref * https://www.thinfilmnfc.com/wp-content/uploads/2017/09/Thinfilm-Kovio-NFC-Barcode-Protocol-Tag-Functional-Specification-v3.4-2017-05-26.pdf diff --git a/armsrc/thinfilm.h b/armsrc/thinfilm.h index 15453e3c2..af1564482 100644 --- a/armsrc/thinfilm.h +++ b/armsrc/thinfilm.h @@ -11,20 +11,9 @@ #ifndef __THINFILM_H #define __THINFILM_H -#ifdef __cplusplus -extern "C" { -#endif - -#include "pm3_cmd.h" -#include "cmd.h" -#include "apps.h" -#include "iso14443a.h" +#include "common.h" void ReadThinFilm(void); void SimulateThinFilm(uint8_t *data, size_t len); -#ifdef __cplusplus -} -#endif - #endif /* __ISO14443A_H */ diff --git a/armsrc/ticks.c b/armsrc/ticks.c index 610afb5a2..43555b21b 100644 --- a/armsrc/ticks.c +++ b/armsrc/ticks.c @@ -10,6 +10,9 @@ //----------------------------------------------------------------------------- #include "ticks.h" +#include "proxmark3_arm.h" +#include "dbprint.h" + // timer counts in 21.3us increments (1024/48MHz), rounding applies // WARNING: timer can't measure more than 1.39s (21.3us * 0xffff) void SpinDelayUs(int us) { diff --git a/armsrc/ticks.h b/armsrc/ticks.h index 9ff0d6000..089501c87 100644 --- a/armsrc/ticks.h +++ b/armsrc/ticks.h @@ -12,11 +12,7 @@ #ifndef __TICKS_H #define __TICKS_H -#include -#include #include "common.h" -#include "apps.h" -#include "proxmark3.h" #ifndef GET_TICKS #define GET_TICKS GetTicks() @@ -45,4 +41,5 @@ void WaitUS(uint16_t us); void WaitMS(uint16_t ms); void StopTicks(void); + #endif diff --git a/common/usart.c b/armsrc/usart.c similarity index 99% rename from common/usart.c rename to armsrc/usart.c index cb52d0116..f3abb40a1 100644 --- a/common/usart.c +++ b/armsrc/usart.c @@ -8,10 +8,8 @@ //----------------------------------------------------------------------------- // The main USART code, for serial communications over FPC connector //----------------------------------------------------------------------------- -#include "cmd.h" #include "usart.h" -#include "string.h" -#include "../armsrc/ticks.h" // startcountus +#include "proxmark3_arm.h" volatile AT91PS_USART pUS1 = AT91C_BASE_US1; volatile AT91PS_PIO pPIO = AT91C_BASE_PIOA; diff --git a/common/usart.h b/armsrc/usart.h similarity index 58% rename from common/usart.h rename to armsrc/usart.h index ef0691df5..01ca0d809 100644 --- a/common/usart.h +++ b/armsrc/usart.h @@ -1,28 +1,20 @@ #ifndef __USART_H #define __USART_H -#include -#include "proxmark3.h" +#include "common.h" +#include "usart_defs.h" -//#define USART_BAUD_RATE 9600 -#define USART_BAUD_RATE 115200 - -// BT HC-06 physical layer runs at 128kbps -// so it's possible to gain a little bit by using 230400 -// with some risk to overflow its internal buffers: -//#define USART_BAUD_RATE 230400 +#define USART_BUFFLEN 512 +#define USART_FIFOLEN (2*USART_BUFFLEN) // Higher baudrates are pointless, only increasing overflow risk extern uint32_t usart_baudrate; -#define USART_PARITY 'N' extern uint8_t usart_parity; void usart_init(uint32_t baudrate, uint8_t parity); int usart_writebuffer_sync(uint8_t *data, size_t len); uint32_t usart_read_ng(uint8_t *data, size_t len); uint16_t usart_rxdata_available(void); -#define USART_BUFFLEN 512 -#define USART_FIFOLEN (2*USART_BUFFLEN) #endif diff --git a/armsrc/util.c b/armsrc/util.c index a691766d0..b855ab949 100644 --- a/armsrc/util.c +++ b/armsrc/util.c @@ -9,6 +9,14 @@ //----------------------------------------------------------------------------- #include "util.h" +#include "proxmark3_arm.h" +#include "ticks.h" +#include "commonutil.h" +#include "dbprint.h" +#include "string.h" +#include "usb_cdc.h" +#include "usart.h" + size_t nbytes(size_t nbits) { return (nbits >> 3) + ((nbits % 8) > 0); } diff --git a/armsrc/util.h b/armsrc/util.h index 8649f0431..9748152ef 100644 --- a/armsrc/util.h +++ b/armsrc/util.h @@ -12,11 +12,6 @@ #define __UTIL_H #include "common.h" -#include "commonutil.h" -#include "proxmark3.h" -#include "string.h" -#include "BigBuf.h" -#include "ticks.h" // Basic macros diff --git a/armsrc/vtsend.c b/armsrc/vtsend.c index e851d4334..f07793cce 100644 --- a/armsrc/vtsend.c +++ b/armsrc/vtsend.c @@ -31,7 +31,8 @@ */ #include "vtsend.h" -#include "apps.h" +#include "pm3_cmd.h" +#include "dbprint.h" #define ESC (0x1B) //#define UART_WRITE(P, BUF, SIZ) (P)->uart_write(BUF, SIZ, (P)->extobj) diff --git a/armsrc/vtsend.h b/armsrc/vtsend.h index 4dcb0c62b..63d3d2461 100644 --- a/armsrc/vtsend.h +++ b/armsrc/vtsend.h @@ -33,6 +33,8 @@ #ifndef VTSEND_H #define VTSEND_H +#include "common.h" + #define VTSEND_COLOR_BLACK (0) #define VTSEND_COLOR_RED (1) #define VTSEND_COLOR_GREEN (2) @@ -56,10 +58,6 @@ typedef struct { void *extobj; } vtsend_t; -#ifdef __cplusplus -extern "C" { -#endif - int vtsend_init(vtsend_t *p, VTSEND_SERIAL_WRITE uart_write, void *extobj); int vtsend_cursor_position(vtsend_t *p, const int column, const int line); int vtsend_cursor_up(vtsend_t *p, const int n); @@ -84,10 +82,4 @@ int vtsend_fill_box( vtsend_t *p, const int x1, const int y1, const int x2, const int y2); -#ifdef __cplusplus -} #endif - -#endif - - diff --git a/common/wiegand.c b/armsrc/wiegand.c similarity index 100% rename from common/wiegand.c rename to armsrc/wiegand.c diff --git a/common/wiegand.h b/armsrc/wiegand.h similarity index 100% rename from common/wiegand.h rename to armsrc/wiegand.h diff --git a/bootrom/Makefile b/bootrom/Makefile index afc4162a7..c4103b522 100644 --- a/bootrom/Makefile +++ b/bootrom/Makefile @@ -3,13 +3,13 @@ # at your option, any later version. See the LICENSE.txt file for the text of # the license. #----------------------------------------------------------------------------- -# Makefile for bootrom, see ../common/Makefile.common for common settings +# Makefile for bootrom, see ../common_arm/Makefile.common for common settings #----------------------------------------------------------------------------- # DO NOT use thumb mode in the phase 1 bootloader since that generates a section with glue code ARMSRC = THUMBSRC = usb_cdc.c \ - bootrom.c + bootrom.c ASMSRC = ram-reset.s flash-reset.s VERSIONSRC = version.c @@ -29,7 +29,7 @@ APP_CFLAGS += -fno-stack-protector -fno-pie # Do not move this inclusion before the definition of {THUMB,ASM,ARM}SRC -include ../common/Makefile.common +include ../common_arm/Makefile.common OBJS = $(OBJDIR)/bootrom.s19 diff --git a/bootrom/bootrom.c b/bootrom/bootrom.c index 31bb139ef..2c1a6f23a 100644 --- a/bootrom/bootrom.c +++ b/bootrom/bootrom.c @@ -6,9 +6,10 @@ // Main code for the bootloader //----------------------------------------------------------------------------- -#include #include "usb_cdc.h" +#include "proxmark3_arm.h" + struct common_area common_area __attribute__((section(".commonarea"))); unsigned int start_addr, end_addr, bootrom_unlocked; extern char _bootrom_start, _bootrom_end, _flash_start, _flash_end; diff --git a/bootrom/ldscript-flash b/bootrom/ldscript-flash index 26acf8242..c9174ffcd 100644 --- a/bootrom/ldscript-flash +++ b/bootrom/ldscript-flash @@ -8,7 +8,7 @@ ----------------------------------------------------------------------------- */ -INCLUDE ../common/ldscript.common +INCLUDE ../common_arm/ldscript.common PHDRS { diff --git a/client/Makefile b/client/Makefile index 47a890d0a..e1cb03102 100644 --- a/client/Makefile +++ b/client/Makefile @@ -28,7 +28,7 @@ ENV_CFLAGS := $(CFLAGS) platform = $(shell uname) -VPATH = ../common ../zlib ../uart +VPATH = ../common ../common/zlib uart OBJDIR = obj LDLIBS = @@ -44,18 +44,19 @@ ifneq ($(platform),Darwin) LDLIBS += -Wl,--as-needed -latomic -Wl,--no-as-needed endif -LUALIB = ../liblua/liblua.a +LUALIBPATH = ./liblua +LUALIB = $(LUALIBPATH)/liblua.a JANSSONLIBPATH = ./jansson JANSSONLIB = $(JANSSONLIBPATH)/libjansson.a MBEDTLSLIBPATH = ../common/mbedtls MBEDTLSLIB = $(MBEDTLSLIBPATH)/libmbedtls.a CBORLIBPATH = ./tinycbor CBORLIB = $(CBORLIBPATH)/tinycbor.a -LIBS = -I../zlib -I../uart -I../liblua -I$(MBEDTLSLIBPATH) -I$(JANSSONLIBPATH) -I$(CBORLIBPATH) +LIBS = -I../common/zlib -Iuart -I$(LUALIBPATH) -I$(MBEDTLSLIBPATH) -I$(JANSSONLIBPATH) -I$(CBORLIBPATH) INCLUDES_CLIENT = -I. -I../include -I../common -I/opt/local/include $(LIBS) LDFLAGS = $(ENV_LDFLAGS) -CFLAGS = $(ENV_CFLAGS) -std=c99 -D_ISOC99_SOURCE -DPRESETS $(INCLUDES_CLIENT) -Wall -g -O3 +CFLAGS = $(ENV_CFLAGS) -std=c99 -D_ISOC99_SOURCE -DPRESETS $(INCLUDES_CLIENT) -Wall -Werror -g -O3 ifneq (,$(findstring MINGW,$(platform))) CFLAGS += -mno-ms-bitfields endif @@ -117,7 +118,7 @@ endif # Flags to generate temporary dependency files DEPFLAGS = -MT $@ -MMD -MP -MF $(OBJDIR)/$*.Td -# make temporary to final dependeny files after successful compilation +# make temporary to final dependency files after successful compilation POSTCOMPILE = $(MV) -f $(OBJDIR)/$*.Td $(OBJDIR)/$*.d CORESRCS = uart_posix.c \ @@ -237,7 +238,6 @@ CMDSRCS = crapto1/crapto1.c \ scripting.c \ cmdscript.c \ pm3_bitlib.c \ - protocols.c \ cmdcrc.c \ reveng/preset.c \ reveng/reveng.c \ @@ -333,7 +333,7 @@ lualibs/mf_default_keys.lua : default_keys.dic clean: $(Q)$(RM) $(CLEAN) - $(Q)$(MAKE) --no-print-directory -C ../liblua clean + $(Q)$(MAKE) --no-print-directory -C $(LUALIBPATH) clean $(Q)$(MAKE) --no-print-directory -C $(JANSSONLIBPATH) clean $(Q)$(MAKE) --no-print-directory -C $(MBEDTLSLIBPATH) clean $(Q)$(MAKE) --no-print-directory -C $(CBORLIBPATH) clean @@ -344,7 +344,7 @@ tarbin: $(BINS) lua_build: $(info [*] MAKE liblua for $(LUAPLATFORM)) - $(Q)$(MAKE) --no-print-directory -C ../liblua $(LUAPLATFORM) + $(Q)$(MAKE) --no-print-directory -C $(LUALIBPATH) $(LUAPLATFORM) jansson_build: $(info [*] MAKE jansson) diff --git a/client/cliparser/cliparser.c b/client/cliparser/cliparser.c index ae2124085..02746c0f4 100644 --- a/client/cliparser/cliparser.c +++ b/client/cliparser/cliparser.c @@ -9,7 +9,6 @@ //----------------------------------------------------------------------------- #include "cliparser.h" -#include #include void **argtable = NULL; diff --git a/client/cliparser/cliparser.h b/client/cliparser/cliparser.h index 7da509757..c67488d59 100644 --- a/client/cliparser/cliparser.h +++ b/client/cliparser/cliparser.h @@ -12,7 +12,6 @@ #define __CLIPARSER_H #include "argtable3.h" #include "util.h" -#include #define arg_param_begin arg_lit0("hH", "help", "print this help and exit") #define arg_param_end arg_end(20) diff --git a/client/cmdanalyse.c b/client/cmdanalyse.c index 0821cc4d1..2e88f6e5b 100644 --- a/client/cmdanalyse.c +++ b/client/cmdanalyse.c @@ -9,6 +9,19 @@ //----------------------------------------------------------------------------- #include "cmdanalyse.h" +#include // size_t +#include +#include // tolower + +#include "commonutil.h" // reflect... +#include "comms.h" // clearCommandBuffer +#include "cmdparser.h" // command_t +#include "ui.h" // PrintAndLog +#include "crc.h" +#include "crc16.h" // crc16 ccitt +#include "tea.h" +#include "legic_prng.h" + static int CmdHelp(const char *Cmd); static int usage_analyse_lcr(void) { diff --git a/client/cmdanalyse.h b/client/cmdanalyse.h index 20dc58a7e..4d223be1b 100644 --- a/client/cmdanalyse.h +++ b/client/cmdanalyse.h @@ -11,20 +11,7 @@ #ifndef CMDANALYSE_H__ #define CMDANALYSE_H__ -#include // size_t -#include -#include -#include "cmdmain.h" -#include "proxmark3.h" -#include "ui.h" // PrintAndLog -#include "util.h" -#include "crc.h" -#include "crc16.h" // crc16 ccitt -#include "tea.h" -#include "legic_prng.h" -#include "loclass/elite_crack.h" -#include "mifare/mfkey.h" // nonce2key -#include "util_posix.h" // msclock +#include "common.h" int CmdAnalyse(const char *Cmd); #endif diff --git a/client/cmdcrc.c b/client/cmdcrc.c index af4baae45..7f41b90e3 100644 --- a/client/cmdcrc.c +++ b/client/cmdcrc.c @@ -9,6 +9,23 @@ //----------------------------------------------------------------------------- #include "cmdcrc.h" +#include +#include +#include +#include + +#ifdef _WIN32 +# include +# include +# ifndef STDIN_FILENO +# define STDIN_FILENO 0 +# endif /* STDIN_FILENO */ +#endif /* _WIN32 */ + +#include "reveng/reveng.h" +#include "ui.h" +#include "util.h" + #define MAX_ARGS 20 static int split(char *str, char *arr[MAX_ARGS]) { diff --git a/client/cmdcrc.h b/client/cmdcrc.h index e45c004f5..957cd1eec 100644 --- a/client/cmdcrc.h +++ b/client/cmdcrc.h @@ -11,22 +11,7 @@ #ifndef CMDCRC_H__ #define CMDCRC_H__ -#ifdef _WIN32 -# include -# include -# ifndef STDIN_FILENO -# define STDIN_FILENO 0 -# endif /* STDIN_FILENO */ -#endif /* _WIN32 */ - -#include -#include -#include -#include -#include "cmdmain.h" -#include "reveng/reveng.h" -#include "ui.h" -#include "util.h" +#include "common.h" int CmdCrc(const char *Cmd); diff --git a/client/cmddata.c b/client/cmddata.c index 3887c6cb8..81060cd59 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -9,6 +9,21 @@ //----------------------------------------------------------------------------- #include "cmddata.h" +#include +#include +#include // for CmdNorm INT_MIN && INT_MAX +#include // pow +#include // tolower + +#include "commonutil.h" // ARRAYLEN +#include "cmdparser.h" // for command_t +#include "ui.h" // for show graph controls +#include "graph.h" // for graph data +#include "comms.h" +#include "lfdemod.h" // for demod code +#include "loclass/cipherutils.h" // for decimating samples in getsamples +#include "cmdlfem4x.h" // askem410xdecode + uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN]; size_t DemodBufferLen = 0; size_t g_DemodStartIdx = 0; diff --git a/client/cmddata.h b/client/cmddata.h index 583af4dd1..a453fafb1 100644 --- a/client/cmddata.h +++ b/client/cmddata.h @@ -11,26 +11,9 @@ #ifndef CMDDATA_H__ #define CMDDATA_H__ -#include //size_t -#include //uint_32+ -#include //bool -#include "cmdparser.h" // for command_t +#include "common.h" -#include // also included in util.h -#include // also included in util.h -#include -#include // for CmdNorm INT_MIN && INT_MAX -#include "util.h" -#include "cmdmain.h" -#include "proxmark3.h"// sendcommand -#include "ui.h" // for show graph controls -#include "graph.h" // for graph data -#include "comms.h" -#include "lfdemod.h" // for demod code -#include "crc.h" // for pyramid checksum maxim -#include "crc16.h" // for FDXB demod checksum -#include "loclass/cipherutils.h" // for decimating samples in getsamples -#include "cmdlfem4x.h" // askem410xdecode +//#include //size_t int CmdData(const char *Cmd); diff --git a/client/cmdflashmem.c b/client/cmdflashmem.c index c639ab107..6bb6fbc3c 100644 --- a/client/cmdflashmem.c +++ b/client/cmdflashmem.c @@ -9,9 +9,17 @@ //----------------------------------------------------------------------------- #include "cmdflashmem.h" +#include + +#include "cmdparser.h" // command_t + +#include "pmflash.h" +#include "loclass/fileutils.h" //saveFile +#include "comms.h" //getfromdevice +#include "cmdflashmemspiffs.h" // spiffs commands + #include "mbedtls/rsa.h" #include "mbedtls/sha1.h" -#include "mbedtls/base64.h" #define MCK 48000000 #define FLASH_MINFAST 24000000 //33000000 @@ -209,7 +217,7 @@ static int CmdFlashMemLoad(const char *Cmd) { } if (datalen > FLASH_MEM_MAX_SIZE) { - PrintAndLogDevice(ERR, "error, filesize is larger than available memory"); + PrintAndLogEx(ERR, "error, filesize is larger than available memory"); free(data); return PM3_EOVFLOW; } @@ -310,7 +318,7 @@ static int CmdFlashMemDump(const char *Cmd) { uint8_t *dump = calloc(len, sizeof(uint8_t)); if (!dump) { - PrintAndLogDevice(ERR, "error, cannot allocate memory "); + PrintAndLogEx(ERR, "error, cannot allocate memory "); return PM3_EMALLOC; } diff --git a/client/cmdflashmem.h b/client/cmdflashmem.h index b08164837..011b57a14 100644 --- a/client/cmdflashmem.h +++ b/client/cmdflashmem.h @@ -11,20 +11,7 @@ #ifndef CMDFLASHMEM_H__ #define CMDFLASHMEM_H__ -#include -#include -#include -#include -#include "pmflash.h" #include "common.h" -#include "proxmark3.h" -#include "ui.h" -#include "cmdparser.h" -#include "util.h" -#include "util_posix.h" // msclock -#include "loclass/fileutils.h" //saveFile -#include "comms.h" //getfromdevice -#include "cmdflashmemspiffs.h" // spiffs commands typedef enum { DICTIONARY_NONE = 0, diff --git a/client/cmdflashmemspiffs.c b/client/cmdflashmemspiffs.c index bc7a408bd..a3f9b950a 100644 --- a/client/cmdflashmemspiffs.c +++ b/client/cmdflashmemspiffs.c @@ -9,9 +9,12 @@ //----------------------------------------------------------------------------- #include "cmdflashmemspiffs.h" -#include "mbedtls/base64.h" -#include "mbedtls/rsa.h" -#include "mbedtls/sha1.h" +#include + +#include "cmdparser.h" // command_t +#include "pmflash.h" +#include "loclass/fileutils.h" //saveFile +#include "comms.h" //getfromdevice static int CmdHelp(const char *Cmd); @@ -278,7 +281,7 @@ static int CmdFlashMemSpiFFSDump(const char *Cmd) { uint8_t *dump = calloc(len, sizeof(uint8_t)); if (!dump) { - PrintAndLogDevice(ERR, "error, cannot allocate memory "); + PrintAndLogEx(ERR, "error, cannot allocate memory "); return PM3_EMALLOC; } @@ -358,7 +361,7 @@ static int CmdFlashMemSpiFFSLoad(const char *Cmd) { } if (datalen > FLASH_MEM_MAX_SIZE) { - PrintAndLogDevice(ERR, "error, filesize is larger than available memory"); + PrintAndLogEx(ERR, "error, filesize is larger than available memory"); free(data); return PM3_EOVFLOW; } diff --git a/client/cmdflashmemspiffs.h b/client/cmdflashmemspiffs.h index b3589ce86..d2dee17ab 100644 --- a/client/cmdflashmemspiffs.h +++ b/client/cmdflashmemspiffs.h @@ -11,19 +11,7 @@ #ifndef CMDFLASHMEMSPIFFS_H__ #define CMDFLASHMEMSPIFFS_H__ -#include -#include -#include -#include -#include "pmflash.h" #include "common.h" -#include "proxmark3.h" -#include "ui.h" -#include "cmdparser.h" -#include "util.h" -#include "util_posix.h" // msclock -#include "loclass/fileutils.h" //saveFile -#include "comms.h" //getfromdevice int CmdFlashMemSpiFFS(const char *Cmd); diff --git a/client/cmdhf.c b/client/cmdhf.c index 931737f1c..7af98e46f 100644 --- a/client/cmdhf.c +++ b/client/cmdhf.c @@ -8,7 +8,29 @@ //----------------------------------------------------------------------------- // High frequency commands //----------------------------------------------------------------------------- -#include "cmdhf.h" +//#include "cmdhf.h" + +#include // tolower + +#include "cmdparser.h" // command_t +#include "comms.h" // clearCommandBuffer + +#include "cmdhf14a.h" // ISO14443-A +#include "cmdhf14b.h" // ISO14443-B +#include "cmdhf15.h" // ISO15693 +#include "cmdhfepa.h" +#include "cmdhflegic.h" // LEGIC +#include "cmdhficlass.h" // ICLASS +#include "cmdhfmf.h" // CLASSIC +#include "cmdhfmfu.h" // ULTRALIGHT/NTAG etc +#include "cmdhfmfp.h" // Mifare Plus +#include "cmdhfmfdes.h" // DESFIRE +#include "cmdhftopaz.h" // TOPAZ +#include "cmdhffelica.h" // ISO18092 / FeliCa +#include "cmdhffido.h" // FIDO authenticators +#include "cmdhfthinfilm.h" // Thinfilm +#include "cmdtrace.h" // trace list +#include "ui.h" static int CmdHelp(const char *Cmd); @@ -101,15 +123,15 @@ int CmdHFSearch(const char *Cmd) { } } - /* - if (IfPm3Felica()) { - ans = CmdHFFelicaReader("s"); - if (ans) { - PrintAndLogEx(NORMAL, "\nValid " _GREEN_("ISO18092 / FeliCa tag") " found\n"); - return ans; - } - } - */ + + //if (IfPm3Felica()) { + // ans = CmdHFFelicaReader("s"); + // if (ans) { + // PrintAndLogEx(NORMAL, "\nValid " _GREEN_("ISO18092 / FeliCa tag") " found\n"); + // return ans; + // } + //} + PrintAndLogEx(FAILED, "\nno known/supported 13.56 MHz tags found\n"); return PM3_ESOFT; diff --git a/client/cmdhf.h b/client/cmdhf.h index cd0ae5db5..14ded8e0e 100644 --- a/client/cmdhf.h +++ b/client/cmdhf.h @@ -11,28 +11,7 @@ #ifndef CMDHF_H__ #define CMDHF_H__ -#include -#include -#include -#include "proxmark3.h" -#include "graph.h" -#include "ui.h" -#include "cmdparser.h" -#include "cmdhf14a.h" // ISO14443-A -#include "cmdhf14b.h" // ISO14443-B -#include "cmdhf15.h" // ISO15693 -#include "cmdhfepa.h" -#include "cmdhflegic.h" // LEGIC -#include "cmdhficlass.h" // ICLASS -#include "cmdhfmf.h" // CLASSIC -#include "cmdhfmfu.h" // ULTRALIGHT/NTAG etc -#include "cmdhfmfp.h" // Mifare Plus -#include "cmdhfmfdes.h" // DESFIRE -#include "cmdhftopaz.h" // TOPAZ -#include "cmdhffelica.h" // ISO18092 / FeliCa -#include "cmdhffido.h" // FIDO authenticators -#include "cmdhfthinfilm.h" // Thinfilm -#include "cmdtrace.h" // trace list +#include "common.h" int CmdHF(const char *Cmd); int CmdHFTune(const char *Cmd); diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index 3fbf022fd..8aea8db6c 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -12,6 +12,21 @@ //----------------------------------------------------------------------------- #include "cmdhf14a.h" +#include +#include + +#include "cmdparser.h" // command_t +#include "commonutil.h" // ARRAYLEN +#include "comms.h" // clearCommandBuffer +#include "cmdtrace.h" +#include "cliparser/cliparser.h" +#include "cmdhfmf.h" +#include "cmdhfmfu.h" +#include "emv/emvcore.h" +#include "ui.h" +#include "crc16.h" +#include "util_posix.h" // msclock + bool APDUInFramingEnable = true; static int CmdHelp(const char *Cmd); diff --git a/client/cmdhf14a.h b/client/cmdhf14a.h index d5626d995..9c42b9afd 100644 --- a/client/cmdhf14a.h +++ b/client/cmdhf14a.h @@ -12,25 +12,9 @@ #ifndef CMDHF14A_H__ #define CMDHF14A_H__ -#include -#include -#include -#include -#include -#include -#include "proxmark3.h" #include "common.h" -#include "ui.h" -#include "util.h" -#include "cmdparser.h" -#include "cmdmain.h" -#include "mifare.h" -#include "cmdhfmf.h" -#include "cmdhfmfu.h" -#include "cmdhf.h" // list cmd -#include "mifare/mifarehost.h" -#include "emv/apduinfo.h" -#include "emv/emvcore.h" + +#include "mifare.h" // structs // structure and database for uid -> tagtype lookups typedef struct { diff --git a/client/cmdhf14b.c b/client/cmdhf14b.c index b02fe4d2f..c5a628835 100644 --- a/client/cmdhf14b.c +++ b/client/cmdhf14b.c @@ -11,6 +11,17 @@ #include "cmdhf14b.h" +#include +#include "loclass/fileutils.h" + +#include "cmdparser.h" // command_t +#include "comms.h" // clearCommandBuffer +#include "cmdtrace.h" + +#include "crc16.h" +#include "cmdhf14a.h" +#include "protocols.h" // definitions of ISO14B protocol + #define TIMEOUT 2000 static int CmdHelp(const char *Cmd); diff --git a/client/cmdhf14b.h b/client/cmdhf14b.h index 2180e2088..2058ea8ba 100644 --- a/client/cmdhf14b.h +++ b/client/cmdhf14b.h @@ -11,23 +11,7 @@ #ifndef CMDHF14B_H__ #define CMDHF14B_H__ -#include -#include -#include -#include -#include "crc16.h" -#include "proxmark3.h" -#include "graph.h" -#include "util.h" -#include "ui.h" -#include "cmdparser.h" -#include "cmdmain.h" -#include "cmdhf14a.h" -#include "cmdhf.h" -#include "prng.h" -#include "mbedtls/sha1.h" -#include "mifare.h" // structs/enum for ISO14B -#include "protocols.h" // definitions of ISO14B protocol +#include "common.h" int CmdHF14B(const char *Cmd); diff --git a/client/cmdhf15.c b/client/cmdhf15.c index f43b6d85c..2c788087e 100644 --- a/client/cmdhf15.c +++ b/client/cmdhf15.c @@ -24,6 +24,19 @@ // variant, but offers the possibility to analyze the waveforms directly. #include "cmdhf15.h" +#include + +#include "cmdparser.h" // command_t +#include "commonutil.h" // ARRAYLEN +#include "comms.h" // clearCommandBuffer +#include "cmdtrace.h" +#include "iso15693tools.h" + +#include "graph.h" +#include "crc16.h" // iso15 crc +#include "cmddata.h" // getsamples +#include "loclass/fileutils.h" // savefileEML + #define FrameSOF Iso15693FrameSOF #define Logic0 Iso15693Logic0 #define Logic1 Iso15693Logic1 diff --git a/client/cmdhf15.h b/client/cmdhf15.h index 049e9f68f..b3f64ac70 100644 --- a/client/cmdhf15.h +++ b/client/cmdhf15.h @@ -11,20 +11,7 @@ #ifndef CMDHF15_H__ #define CMDHF15_H__ -#include -#include -#include -#include - -#include "proxmark3.h" -#include "graph.h" -#include "ui.h" -#include "util.h" -#include "cmdparser.h" -#include "crc16.h" // iso15 crc -#include "cmdmain.h" -#include "cmddata.h" // getsamples -#include "loclass/fileutils.h" // savefileEML +#include "common.h" int CmdHF15(const char *Cmd); diff --git a/client/cmdhfepa.c b/client/cmdhfepa.c index 3370c05c9..b6329bef9 100644 --- a/client/cmdhfepa.c +++ b/client/cmdhfepa.c @@ -9,6 +9,18 @@ //----------------------------------------------------------------------------- #include "cmdhfepa.h" +#include +#include +#include +#include +#include + +#include "cmdparser.h" // command_t +#include "commonutil.h" // ARRAYLEN +#include "comms.h" // clearCommandBuffer +#include "ui.h" +#include "util_posix.h" + static int CmdHelp(const char *Cmd); // Perform (part of) the PACE protocol diff --git a/client/cmdhfepa.h b/client/cmdhfepa.h index c08fa8ea0..da21630cd 100644 --- a/client/cmdhfepa.h +++ b/client/cmdhfepa.h @@ -11,19 +11,7 @@ #ifndef CMDHFEPA_H__ #define CMDHFEPA_H__ -#include -#include -#include -#include -#include -#include "util.h" -#include "proxmark3.h" #include "common.h" -#include "ui.h" -#include "cmdparser.h" -#include "cmdmain.h" -#include "util_posix.h" - int CmdHFEPA(const char *Cmd); diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index e873daaaf..c3681bf60 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -9,6 +9,19 @@ //----------------------------------------------------------------------------- #include "cmdhffelica.h" +#include +#include +#include +#include + +#include "cmdparser.h" // command_t +#include "comms.h" +#include "cmdtrace.h" +#include "crc16.h" + +#include "ui.h" +#include "mifare.h" // felica_card_select_t struct + static int CmdHelp(const char *Cmd); /* diff --git a/client/cmdhffelica.h b/client/cmdhffelica.h index b495b80ec..4193235f5 100644 --- a/client/cmdhffelica.h +++ b/client/cmdhffelica.h @@ -11,19 +11,7 @@ #ifndef CMDHFFELICA_H__ #define CMDHFFELICA_H__ -#include -#include -#include -#include -#include -#include "proxmark3.h" #include "common.h" -#include "ui.h" -#include "util.h" -#include "cmdparser.h" -#include "comms.h" // getfromdevice -#include "cmdhf.h" // list cmd -#include "mifare.h" // felica_card_select_t struct int CmdHFFelica(const char *Cmd); diff --git a/client/cmdhffido.c b/client/cmdhffido.c index 37f80d8e5..e9b3376a9 100644 --- a/client/cmdhffido.c +++ b/client/cmdhffido.c @@ -21,31 +21,23 @@ #include "cmdhffido.h" -#include -#include -#include -#include -#include #include -#include -#include -#include -#include + +#include "cmdparser.h" // command_t +#include "commonutil.h" + #include "comms.h" -#include "cmdmain.h" -#include "util.h" -#include "ui.h" #include "proxmark3.h" -#include "mifare.h" #include "emv/emvcore.h" #include "emv/emvjson.h" -#include "emv/dump.h" #include "cliparser/cliparser.h" #include "crypto/asn1utils.h" #include "crypto/libpcrypto.h" #include "fido/cbortools.h" #include "fido/fidocore.h" -#include "fido/cose.h" +#include "emv/dump.h" +#include "ui.h" +#include "cmdhf14a.h" static int CmdHelp(const char *Cmd); diff --git a/client/cmdhffido.h b/client/cmdhffido.h index b54f53118..9aca8ecc8 100644 --- a/client/cmdhffido.h +++ b/client/cmdhffido.h @@ -21,7 +21,8 @@ #ifndef CMDHFFIDO_H__ #define CMDHFFIDO_H__ +#include "common.h" + int CmdHFFido(const char *Cmd); - #endif diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 1f8aef9a5..f58d5377c 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -13,6 +13,23 @@ #include "cmdhficlass.h" +#include + +#include "cmdparser.h" // command_t +#include "commonutil.h" // ARRAYLEN +#include "cmdtrace.h" +#include "util_posix.h" + +#include "comms.h" +#include "mbedtls/des.h" +#include "loclass/cipherutils.h" +#include "loclass/cipher.h" +#include "loclass/ikeys.h" +#include "loclass/elite_crack.h" +#include "loclass/fileutils.h" +#include "protocols.h" + + #define NUM_CSNS 9 #define ICLASS_KEYS_MAX 8 @@ -271,6 +288,145 @@ static int xorbits_8(uint8_t val) { return res & 1; } */ + +// iclass / picopass chip config structures and shared routines +typedef struct { + uint8_t app_limit; //[8] + uint8_t otp[2]; //[9-10] + uint8_t block_writelock;//[11] + uint8_t chip_config; //[12] + uint8_t mem_config; //[13] + uint8_t eas; //[14] + uint8_t fuses; //[15] +} picopass_conf_block; + + +typedef struct { + uint8_t csn[8]; + picopass_conf_block conf; + uint8_t epurse[8]; + uint8_t key_d[8]; + uint8_t key_c[8]; + uint8_t app_issuer_area[8]; +} picopass_hdr; + +static uint8_t isset(uint8_t val, uint8_t mask) { + return (val & mask); +} + +static uint8_t notset(uint8_t val, uint8_t mask) { + return !(val & mask); +} + +static void fuse_config(const picopass_hdr *hdr) { + uint8_t fuses = hdr->conf.fuses; + + if (isset(fuses, FUSE_FPERS)) + PrintAndLogEx(SUCCESS, "\tMode: Personalization [Programmable]"); + else + PrintAndLogEx(NORMAL, "\tMode: Application [Locked]"); + + if (isset(fuses, FUSE_CODING1)) { + PrintAndLogEx(NORMAL, "\tCoding: RFU"); + } else { + if (isset(fuses, FUSE_CODING0)) + PrintAndLogEx(NORMAL, "\tCoding: ISO 14443-2 B/ISO 15693"); + else + PrintAndLogEx(NORMAL, "\tCoding: ISO 14443B only"); + } + // 1 1 + if (isset(fuses, FUSE_CRYPT1) && isset(fuses, FUSE_CRYPT0)) PrintAndLogEx(SUCCESS, "\tCrypt: Secured page, keys not locked"); + // 1 0 + if (isset(fuses, FUSE_CRYPT1) && notset(fuses, FUSE_CRYPT0)) PrintAndLogEx(NORMAL, "\tCrypt: Secured page, keys locked"); + // 0 1 + if (notset(fuses, FUSE_CRYPT1) && isset(fuses, FUSE_CRYPT0)) PrintAndLogEx(SUCCESS, "\tCrypt: Non secured page"); + // 0 0 + if (notset(fuses, FUSE_CRYPT1) && notset(fuses, FUSE_CRYPT0)) PrintAndLogEx(NORMAL, "\tCrypt: No auth possible. Read only if RA is enabled"); + + if (isset(fuses, FUSE_RA)) + PrintAndLogEx(NORMAL, "\tRA: Read access enabled"); + else + PrintAndLogEx(WARNING, "\tRA: Read access not enabled"); +} + +static void getMemConfig(uint8_t mem_cfg, uint8_t chip_cfg, uint8_t *max_blk, uint8_t *app_areas, uint8_t *kb) { + // mem-bit 5, mem-bit 7, chip-bit 4: defines chip type + uint8_t k16 = isset(mem_cfg, 0x80); + //uint8_t k2 = isset(mem_cfg, 0x08); + uint8_t book = isset(mem_cfg, 0x20); + + if (isset(chip_cfg, 0x10) && !k16 && !book) { + *kb = 2; + *app_areas = 2; + *max_blk = 31; + } else if (isset(chip_cfg, 0x10) && k16 && !book) { + *kb = 16; + *app_areas = 2; + *max_blk = 255; //16kb + } else if (notset(chip_cfg, 0x10) && !k16 && !book) { + *kb = 16; + *app_areas = 16; + *max_blk = 255; //16kb + } else if (isset(chip_cfg, 0x10) && k16 && book) { + *kb = 32; + *app_areas = 3; + *max_blk = 255; //16kb + } else if (notset(chip_cfg, 0x10) && !k16 && book) { + *kb = 32; + *app_areas = 17; + *max_blk = 255; //16kb + } else { + *kb = 32; + *app_areas = 2; + *max_blk = 255; + } +} + +static void mem_app_config(const picopass_hdr *hdr) { + uint8_t mem = hdr->conf.mem_config; + uint8_t chip = hdr->conf.chip_config; + uint8_t applimit = hdr->conf.app_limit; + uint8_t kb = 2; + uint8_t app_areas = 2; + uint8_t max_blk = 31; + + getMemConfig(mem, chip, &max_blk, &app_areas, &kb); + + if (applimit < 6) applimit = 26; + if (kb == 2 && (applimit > 0x1f)) applimit = 26; + + PrintAndLogEx(NORMAL, " Mem: %u KBits/%u App Areas (%u * 8 bytes) [%02X]", kb, app_areas, max_blk, mem); + PrintAndLogEx(NORMAL, "\tAA1: blocks 06-%02X", applimit); + PrintAndLogEx(NORMAL, "\tAA2: blocks %02X-%02X", applimit + 1, max_blk); + PrintAndLogEx(NORMAL, "\tOTP: 0x%02X%02X", hdr->conf.otp[1], hdr->conf.otp[0]); + PrintAndLogEx(NORMAL, "\nKeyAccess:"); + + uint8_t book = isset(mem, 0x20); + if (book) { + PrintAndLogEx(NORMAL, "\tRead A - Kd"); + PrintAndLogEx(NORMAL, "\tRead B - Kc"); + PrintAndLogEx(NORMAL, "\tWrite A - Kd"); + PrintAndLogEx(NORMAL, "\tWrite B - Kc"); + PrintAndLogEx(NORMAL, "\tDebit - Kd or Kc"); + PrintAndLogEx(NORMAL, "\tCredit - Kc"); + } else { + PrintAndLogEx(NORMAL, "\tRead A - Kd or Kc"); + PrintAndLogEx(NORMAL, "\tRead B - Kd or Kc"); + PrintAndLogEx(NORMAL, "\tWrite A - Kc"); + PrintAndLogEx(NORMAL, "\tWrite B - Kc"); + PrintAndLogEx(NORMAL, "\tDebit - Kd or Kc"); + PrintAndLogEx(NORMAL, "\tCredit - Kc"); + } +} +static void print_picopass_info(const picopass_hdr *hdr) { + fuse_config(hdr); + mem_app_config(hdr); +} +static void printIclassDumpInfo(uint8_t *iclass_dump) { + print_picopass_info((picopass_hdr *) iclass_dump); +} + + static int CmdHFiClassList(const char *Cmd) { (void)Cmd; // Cmd is not used so far //PrintAndLogEx(NORMAL, "Deprecated command, use 'hf list iclass' instead"); @@ -550,14 +706,14 @@ static int CmdHFiClassELoad(const char *Cmd) { fseek(f, 0, SEEK_SET); if (fsize <= 0) { - PrintAndLogDevice(ERR, "error, when getting filesize"); + PrintAndLogEx(ERR, "error, when getting filesize"); fclose(f); return 1; } uint8_t *dump = calloc(fsize, sizeof(uint8_t)); if (!dump) { - PrintAndLogDevice(ERR, "error, cannot allocate memory "); + PrintAndLogEx(ERR, "error, cannot allocate memory "); fclose(f); return 1; } @@ -569,7 +725,7 @@ static int CmdHFiClassELoad(const char *Cmd) { //Validate if (bytes_read < fsize) { - PrintAndLogDevice(ERR, "error, could only read %d bytes (should be %d)", bytes_read, fsize); + PrintAndLogEx(ERR, "error, could only read %d bytes (should be %d)", bytes_read, fsize); free(dump); return 1; } @@ -1449,7 +1605,7 @@ static int CmdHFiClass_loclass(const char *Cmd) { errors += testMAC(); errors += doKeyTests(0); errors += testElite(); - if (errors) PrintAndLogDevice(ERR, "There were errors!!!"); + if (errors) PrintAndLogEx(ERR, "There were errors!!!"); return errors; } return PM3_SUCCESS; diff --git a/client/cmdhficlass.h b/client/cmdhficlass.h index aa29fae1e..9f2b5caac 100644 --- a/client/cmdhficlass.h +++ b/client/cmdhficlass.h @@ -11,31 +11,7 @@ #ifndef CMDHFICLASS_H__ #define CMDHFICLASS_H__ -#include -#include -#include -#include -//#include "iso14443crc.h" // Can also be used for iClass, using 0xE012 as CRC-type -#include "proxmark3.h" -#include "ui.h" -#include "cmdparser.h" #include "common.h" -#include "util.h" -#include "comms.h" -#include "mbedtls/des.h" -#include "loclass/cipherutils.h" -#include "loclass/cipher.h" -#include "loclass/ikeys.h" -#include "loclass/elite_crack.h" -#include "loclass/fileutils.h" -#include "protocols.h" -#include "pm3_cmd.h" -#include "cmdhfmfu.h" -#include "cmdhf.h" -#include "protocols.h" // picopass structs, -#include "usb_cdc.h" // for usb_poll_validate_length - - typedef struct iclass_block { uint8_t d[8]; diff --git a/client/cmdhflegic.c b/client/cmdhflegic.c index 20fba3781..af56807b1 100644 --- a/client/cmdhflegic.c +++ b/client/cmdhflegic.c @@ -9,6 +9,16 @@ //----------------------------------------------------------------------------- #include "cmdhflegic.h" +#include // for Mingw readline +#include + +#include "cmdparser.h" // command_t +#include "comms.h" // clearCommandBuffer +#include "cmdtrace.h" +#include "crc.h" +#include "crc16.h" +#include "loclass/fileutils.h" //saveFile + static int CmdHelp(const char *Cmd); #define MAX_LENGTH 1024 diff --git a/client/cmdhflegic.h b/client/cmdhflegic.h index b922420ec..9e9411a33 100644 --- a/client/cmdhflegic.h +++ b/client/cmdhflegic.h @@ -11,18 +11,9 @@ #ifndef CMDHFLEGIC_H__ #define CMDHFLEGIC_H__ -#include -#include -#include "proxmark3.h" -#include "ui.h" -#include "cmdparser.h" -#include "comms.h" -#include "util.h" -#include "crc.h" -#include "legic_prng.h" -#include "legic.h" // legic_card_select_t struct -#include "cmdhf.h" // "hf list" -#include "loclass/fileutils.h" //saveFile +#include "common.h" + +#include "legic.h" // struct int CmdHFLegic(const char *Cmd); diff --git a/client/cmdhflist.c b/client/cmdhflist.c index d583dedbb..5a2ff5248 100644 --- a/client/cmdhflist.c +++ b/client/cmdhflist.c @@ -11,6 +11,19 @@ #include "cmdhflist.h" +#include +#include +#include + +#include "commonutil.h" // ARRAYLEN +#include "mifare/mifarehost.h" +#include "mifare/mifaredefault.h" +#include "parity.h" // oddparity +#include "ui.h" +#include "crc16.h" +#include "crapto1/crapto1.h" +#include "protocols.h" + enum MifareAuthSeq { masNone, masNt, diff --git a/client/cmdhflist.h b/client/cmdhflist.h index ddc0ab00c..0dda4ea17 100644 --- a/client/cmdhflist.h +++ b/client/cmdhflist.h @@ -10,32 +10,7 @@ #ifndef CMDHFLIST_H #define CMDHFLIST_H -#include -#include -#include -#include -#include -#include "util.h" -#include "ui.h" -#include "cmdhf14a.h" // ISO14443-A -#include "cmdhf14b.h" // ISO14443-B -#include "cmdhf15.h" // ISO15693 -#include "cmdhfepa.h" -#include "cmdhflegic.h" // LEGIC -#include "cmdhficlass.h" // ICLASS -#include "cmdhfmf.h" // CLASSIC -#include "cmdhfmfu.h" // ULTRALIGHT/NTAG etc -#include "cmdhfmfdes.h" // DESFIRE -#include "cmdhftopaz.h" // TOPAZ -#include "cmdhffelica.h" // ISO18092 / FeliCa -#include "emv/cmdemv.h" // EMV -#include "protocols.h" -#include "crapto1/crapto1.h" -#include "mifare/mifarehost.h" -#include "mifare/mifaredefault.h" -#include "parity.h" // oddparity -#include "iso15693tools.h" // ISO15693 crc - +#include "common.h" typedef struct { uint32_t uid; // UID diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 16b6b9d49..affc53603 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -9,10 +9,22 @@ //----------------------------------------------------------------------------- #include "cmdhfmf.h" -#include "mifare/mifare4.h" + +#include + +#include "cmdparser.h" // command_t +#include "commonutil.h" // ARRAYLEN +#include "comms.h" // clearCommandBuffer +#include "loclass/fileutils.h" +#include "cmdtrace.h" +#include "emv/dump.h" +#include "mifare/mifaredefault.h" // mifare default key array +#include "cliparser/cliparser.h" // argtable +#include "hardnested/hardnested_bf_core.h" // SetSIMDInstr #include "mifare/mad.h" #include "mifare/ndef.h" - +#include "protocols.h" +#include "util_posix.h" // msclock #define MFBLOCK_SIZE 16 diff --git a/client/cmdhfmf.h b/client/cmdhfmf.h index 8b7e68a40..55997bd87 100644 --- a/client/cmdhfmf.h +++ b/client/cmdhfmf.h @@ -11,26 +11,9 @@ #ifndef CMDHFMF_H__ #define CMDHFMF_H__ -#include -#include -#include -#include -#include -#include -#include "proxmark3.h" -#include "ui.h" -#include "cmdparser.h" #include "common.h" -#include "util.h" -#include "mifare.h" // nonces_t struct -#include "mifare/mfkey.h" // mfkey32_moebious -#include "cmdhfmfhard.h" -#include "mifare/mifarehost.h" // icesector_t, sector_t -#include "util_posix.h" // msclock -#include "mifare/mifaredefault.h" // mifare default key array -#include "cmdhf14a.h" // dropfield -#include "cliparser/cliparser.h" // argtable -#include "hardnested/hardnested_bf_core.h" // SetSIMDInstr +#include "mifare/mfkey.h" +#include "mifare/mifarehost.h" // struct int CmdHFMF(const char *Cmd); int CmdHF14AMfELoad(const char *Cmd); // used by cmd hf mfu eload diff --git a/client/cmdhfmfdes.c b/client/cmdhfmfdes.c index c5a54735a..f46384d12 100644 --- a/client/cmdhfmfdes.c +++ b/client/cmdhfmfdes.c @@ -9,6 +9,15 @@ //----------------------------------------------------------------------------- #include "cmdhfmfdes.h" +#include +#include + +#include "cmdparser.h" // command_t +#include "comms.h" +#include "ui.h" +#include "cmdhf14a.h" +#include "mbedtls/des.h" + uint8_t key_zero_data[16] = { 0x00 }; uint8_t key_ones_data[16] = { 0x01 }; uint8_t key_defa_data[16] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }; diff --git a/client/cmdhfmfdes.h b/client/cmdhfmfdes.h index 70e61e757..3a19f6d83 100644 --- a/client/cmdhfmfdes.h +++ b/client/cmdhfmfdes.h @@ -10,19 +10,7 @@ #ifndef __MFDESFIRE_H #define __MFDESFIRE_H -#include -#include -#include -#include -#include "cmdmain.h" -#include "proxmark3.h" -#include "../include/common.h" -#include "../include/mifare.h" -#include "ui.h" -#include "cmdparser.h" -#include "util.h" -#include "cmdhf14a.h" -#include "mbedtls/des.h" +#include "common.h" int CmdHFMFDes(const char *Cmd); diff --git a/client/cmdhfmfdesfire.c b/client/cmdhfmfdesfire_disabled.c similarity index 98% rename from client/cmdhfmfdesfire.c rename to client/cmdhfmfdesfire_disabled.c index d09a56eea..fc123667b 100644 --- a/client/cmdhfmfdesfire.c +++ b/client/cmdhfmfdesfire_disabled.c @@ -10,6 +10,13 @@ #include "cmdhfmfdesfire.h" +#include "cmdparser.h" // command_t + +#include "cmdhfmf.h" +#include "util.h" +#include "mbedtls/des.h" +#include "mbedtls/aes.h" + static int CmdHelp(const char *Cmd); //DESFIRE diff --git a/client/cmdhfmfdesfire.h b/client/cmdhfmfdesfire_disabled.h similarity index 52% rename from client/cmdhfmfdesfire.h rename to client/cmdhfmfdesfire_disabled.h index bfa653dc3..1583bc395 100644 --- a/client/cmdhfmfdesfire.h +++ b/client/cmdhfmfdesfire_disabled.h @@ -1,10 +1,7 @@ #ifndef __MFDESFIRE_AD_H #define __MFDESFIRE_AD_H -#include "cmdhfmf.h" -#include "util.h" -#include "mbedtls/des.h" -#include "mbedtls/aes.h" +#include "common.h" int CmdHFMFDesfire(const char *Cmd); diff --git a/client/cmdhfmfhard.c b/client/cmdhfmfhard.c index a944f11ab..d66df7eae 100644 --- a/client/cmdhfmfhard.c +++ b/client/cmdhfmfhard.c @@ -21,18 +21,18 @@ #include #include #include -#include -#include #include #include +#include // MingW + +#include "commonutil.h" // ARRAYLEN +#include "comms.h" + #include "proxmark3.h" -#include "cmdmain.h" #include "ui.h" -#include "util.h" #include "util_posix.h" #include "crapto1/crapto1.h" #include "parity.h" -#include "hardnested/hardnested_bruteforce.h" #include "hardnested/hardnested_bf_core.h" #include "hardnested/hardnested_bitarray_core.h" #include "zlib.h" diff --git a/client/cmdhfmfhard.h b/client/cmdhfmfhard.h index 2f20986e2..d86a2005a 100644 --- a/client/cmdhfmfhard.h +++ b/client/cmdhfmfhard.h @@ -11,8 +11,7 @@ #ifndef CMDHFMFHARD_H__ #define CMDHFMFHARD_H__ -#include -#include +#include "common.h" #define NUM_SUMS 19 // number of possible sum property values diff --git a/client/cmdhfmfp.c b/client/cmdhfmfp.c index e9dd245b6..8c7cfcc5c 100644 --- a/client/cmdhfmfp.c +++ b/client/cmdhfmfp.c @@ -11,23 +11,20 @@ #include "cmdhfmfp.h" -#include #include -#include -#include -#include + +#include "cmdparser.h" // command_t +#include "commonutil.h" // ARRAYLEN + #include "comms.h" -#include "cmdmain.h" -#include "util.h" #include "ui.h" #include "cmdhf14a.h" -#include "mifare.h" #include "mifare/mifare4.h" #include "mifare/mad.h" #include "mifare/ndef.h" #include "cliparser/cliparser.h" -#include "crypto/libpcrypto.h" #include "emv/dump.h" +#include "mifare/mifaredefault.h" static const uint8_t DefaultKey[16] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; diff --git a/client/cmdhfmfp.h b/client/cmdhfmfp.h index 76917315b..6ba2af504 100644 --- a/client/cmdhfmfp.h +++ b/client/cmdhfmfp.h @@ -10,7 +10,7 @@ #ifndef CMDHFMFP_H__ #define CMDHFMFP_H__ -#include "mifare/mifaredefault.h" +#include "common.h" int CmdHFMFP(const char *Cmd); diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index 7367dfd66..e2c64a004 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -9,6 +9,18 @@ //----------------------------------------------------------------------------- #include "cmdhfmfu.h" +#include + +#include "cmdparser.h" +#include "commonutil.h" +#include "crypto/libpcrypto.h" +#include "mbedtls/des.h" +#include "cmdhfmf.h" +#include "cmdhf14a.h" +#include "comms.h" +#include "loclass/fileutils.h" +#include "protocols.h" + #define MAX_UL_BLOCKS 0x0F #define MAX_ULC_BLOCKS 0x2B #define MAX_ULEV1a_BLOCKS 0x13 diff --git a/client/cmdhfmfu.h b/client/cmdhfmfu.h index 6587cd538..85f6a8475 100644 --- a/client/cmdhfmfu.h +++ b/client/cmdhfmfu.h @@ -1,17 +1,9 @@ #ifndef CMDHFMFU_H__ #define CMDHFMFU_H__ -#include -#include -#include "mbedtls/des.h" -#include "cmdhfmf.h" -#include "cmdhf14a.h" -#include "mifare.h" -#include "util.h" -#include "protocols.h" -#include "comms.h" -#include "loclass/fileutils.h" +#include "common.h" +#include "mifare.h" // structs // Old Ultralight/NTAG dump file format // It is used only for converting diff --git a/client/cmdhfthinfilm.c b/client/cmdhfthinfilm.c index 454641bd8..2e9ab7a85 100644 --- a/client/cmdhfthinfilm.c +++ b/client/cmdhfthinfilm.c @@ -9,6 +9,17 @@ //----------------------------------------------------------------------------- #include "cmdhfthinfilm.h" +#include +#include +#include + +#include "cmdparser.h" // command_t +#include "comms.h" +#include "cmdtrace.h" +#include "crc16.h" +#include "ui.h" +#include "cmdhf14a.h" // manufacture + static int CmdHelp(const char *Cmd); static int usage_thinfilm_info(void) { diff --git a/client/cmdhfthinfilm.h b/client/cmdhfthinfilm.h index ed2b0dd89..ce7534759 100644 --- a/client/cmdhfthinfilm.h +++ b/client/cmdhfthinfilm.h @@ -11,16 +11,7 @@ #ifndef CMDHFTHINFILM_H__ #define CMDHFTHINFILM_H__ -#include -#include -#include #include "common.h" -#include "proxmark3.h" -#include "ui.h" -#include "cmdparser.h" -#include "util.h" -#include "cmdhf.h" // list cmd -#include "cmdhf14a.h" // manufacture int infoThinFilm(bool verbose); diff --git a/client/cmdhftopaz.c b/client/cmdhftopaz.c index b7be9a787..35b31d8ce 100644 --- a/client/cmdhftopaz.c +++ b/client/cmdhftopaz.c @@ -9,6 +9,20 @@ //----------------------------------------------------------------------------- #include "cmdhftopaz.h" +#include +#include +#include +#include + +#include "cmdparser.h" // command_t +#include "comms.h" +#include "cmdtrace.h" + +#include "cmdhf14a.h" +#include "ui.h" +#include "crc16.h" +#include "protocols.h" + #define TOPAZ_STATIC_MEMORY (0x0f * 8) // 15 blocks with 8 Bytes each // a struct to describe a memory area which contains lock bits and the corresponding lockable memory area diff --git a/client/cmdhftopaz.h b/client/cmdhftopaz.h index ed0b37a08..2cd2379b0 100644 --- a/client/cmdhftopaz.h +++ b/client/cmdhftopaz.h @@ -11,19 +11,7 @@ #ifndef CMDHFTOPAZ_H__ #define CMDHFTOPAZ_H__ -#include -#include -#include -#include -#include "cmdmain.h" -#include "cmdparser.h" -#include "cmdhf14a.h" -#include "ui.h" -#include "mifare.h" -#include "proxmark3.h" -#include "crc16.h" -#include "protocols.h" -#include "cmdhf.h" +#include "common.h" int CmdHFTopaz(const char *Cmd); diff --git a/client/cmdhw.c b/client/cmdhw.c index 0bfa583dc..7fec7a40c 100644 --- a/client/cmdhw.c +++ b/client/cmdhw.c @@ -12,12 +12,13 @@ #include #include #include -#include +#include + +#include "cmdparser.h" // command_t +#include "comms.h" +#include "usart_defs.h" #include "ui.h" -#include "proxmark3.h" -#include "cmdparser.h" #include "cmdhw.h" -#include "cmdmain.h" #include "cmddata.h" static int CmdHelp(const char *Cmd); diff --git a/client/cmdhw.h b/client/cmdhw.h index a1a3a4b8f..1a378e70f 100644 --- a/client/cmdhw.h +++ b/client/cmdhw.h @@ -11,6 +11,8 @@ #ifndef CMDHW_H__ #define CMDHW_H__ +#include "common.h" + int CmdHW(const char *Cmd); void pm3_version(bool verbose); diff --git a/client/cmdlf.c b/client/cmdlf.c index 4831ede0f..cf8e60f82 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -9,6 +9,45 @@ //----------------------------------------------------------------------------- #include "cmdlf.h" +#include +#include +#include +#include +#include + +#include "cmdparser.h" // command_t +#include "comms.h" +#include "commonutil.h" // ARRAYLEN + +#include "lfdemod.h" // device/client demods of LF signals +#include "ui.h" // for show graph controls +#include "graph.h" // for graph data +#include "cmddata.h" // for `lf search` +#include "cmdlfawid.h" // for awid menu +#include "cmdlfem4x.h" // for em4x menu +#include "cmdlfhid.h" // for hid menu +#include "cmdlfhitag.h" // for hitag menu +#include "cmdlfio.h" // for ioprox menu +#include "cmdlft55xx.h" // for t55xx menu +#include "cmdlfti.h" // for ti menu +#include "cmdlfpresco.h" // for presco menu +#include "cmdlfpcf7931.h" // for pcf7931 menu +#include "cmdlfpyramid.h" // for pyramid menu +#include "cmdlfviking.h" // for viking menu +#include "cmdlfnedap.h" // for NEDAP menu +#include "cmdlfjablotron.h" // for JABLOTRON menu +#include "cmdlfvisa2000.h" // for VISA2000 menu +#include "cmdlfnoralsy.h" // for NORALSY meny +#include "cmdlfcotag.h" // for COTAG meny +#include "cmdlfindala.h" // for indala menu +#include "cmdlfguard.h" // for gproxii menu +#include "cmdlffdx.h" // for fdx-b menu +#include "cmdlfparadox.h" // for paradox menu +#include "cmdlfnexwatch.h" // for nexwatch menu +#include "cmdlfsecurakey.h" // for securakey menu +#include "cmdlfpac.h" // for pac menu +#include "cmdlfkeri.h" // for keri menu + bool g_lf_threshold_set = false; static int CmdHelp(const char *Cmd); diff --git a/client/cmdlf.h b/client/cmdlf.h index 89299beaf..8c90d2d42 100644 --- a/client/cmdlf.h +++ b/client/cmdlf.h @@ -10,46 +10,8 @@ #ifndef CMDLF_H__ #define CMDLF_H__ -#include -#include -#include -#include -#include -#include -#include "proxmark3.h" -#include "lfdemod.h" // device/client demods of LF signals -#include "util.h" // for parsing cli command utils -#include "ui.h" // for show graph controls -#include "graph.h" // for graph data -#include "cmdparser.h" // for getting cli commands included in cmdmain.h -#include "cmdmain.h" // for sending cmds to device. GetFromBigBuf -#include "cmddata.h" // for `lf search` -#include "cmdlfawid.h" // for awid menu -#include "cmdlfem4x.h" // for em4x menu -#include "cmdlfhid.h" // for hid menu -#include "cmdlfhitag.h" // for hitag menu -#include "cmdlfio.h" // for ioprox menu -#include "cmdlft55xx.h" // for t55xx menu -#include "cmdlfti.h" // for ti menu -#include "cmdlfpresco.h" // for presco menu -#include "cmdlfpcf7931.h" // for pcf7931 menu -#include "cmdlfpyramid.h" // for pyramid menu -#include "cmdlfviking.h" // for viking menu -#include "cmdlfguard.h" // for GuardAll menu -#include "cmdlfnedap.h" // for NEDAP menu -#include "cmdlfjablotron.h" // for JABLOTRON menu -#include "cmdlfvisa2000.h" // for VISA2000 menu -#include "cmdlfnoralsy.h" // for NORALSY meny -#include "cmdlffdx.h" // for FDX-B meny -#include "cmdlfcotag.h" // for COTAG meny -#include "cmdlfindala.h" // for indala menu -#include "cmdlfguard.h" // for gproxii menu -#include "cmdlffdx.h" // for fdx-b menu -#include "cmdlfparadox.h" // for paradox menu -#include "cmdlfnexwatch.h" // for nexwatch menu -#include "cmdlfsecurakey.h" // for securakey menu -#include "cmdlfpac.h" // for pac menu -#include "cmdlfkeri.h" // for keri menu + +#include "common.h" #define T55XX_WRITE_TIMEOUT 1500 diff --git a/client/cmdlfawid.c b/client/cmdlfawid.c index 09a73aca5..b574af772 100644 --- a/client/cmdlfawid.c +++ b/client/cmdlfawid.c @@ -12,6 +12,21 @@ //----------------------------------------------------------------------------- #include "cmdlfawid.h" // AWID function declarations +#include +#include +#include + +#include "cmdparser.h" // command_t +#include "comms.h" +#include "graph.h" +#include "cmddata.h" + +#include "ui.h" // PrintAndLog +#include "lfdemod.h" // parityTest +#include "cmdlf.h" // lf read +#include "protocols.h" // for T55xx config register definitions +#include "util_posix.h" + static int CmdHelp(const char *Cmd); /* static int usage_lf_awid_read(void) { diff --git a/client/cmdlfawid.h b/client/cmdlfawid.h index e51e986a6..80645e9b9 100644 --- a/client/cmdlfawid.h +++ b/client/cmdlfawid.h @@ -11,18 +11,7 @@ #ifndef CMDLFAWID_H__ #define CMDLFAWID_H__ -#include // sscanf -#include // bool -#include "proxmark3.h" // Definitions, USB controls, etc -#include "ui.h" // PrintAndLog -#include "cmdparser.h" // CmdsParse, CmdsHelp -#include "lfdemod.h" // parityTest -#include "util.h" // weigandparity -#include "cmdlf.h" // lf read -#include "protocols.h" // for T55xx config register definitions -#include "cmdmain.h" -#include "util_posix.h" - +#include "common.h" int CmdLFAWID(const char *Cmd); diff --git a/client/cmdlfcotag.c b/client/cmdlfcotag.c index 338c0a6d6..96548fca9 100644 --- a/client/cmdlfcotag.c +++ b/client/cmdlfcotag.c @@ -9,6 +9,15 @@ //----------------------------------------------------------------------------- #include "cmdlfcotag.h" // COTAG function declarations +#include +#include + +#include "cmdparser.h" // command_t +#include "comms.h" +#include "lfdemod.h" +#include "cmddata.h" // getSamples +#include "ui.h" // PrintAndLog + static int CmdHelp(const char *Cmd); static int usage_lf_cotag_read(void) { diff --git a/client/cmdlfcotag.h b/client/cmdlfcotag.h index e4b12235d..01c4daa03 100644 --- a/client/cmdlfcotag.h +++ b/client/cmdlfcotag.h @@ -11,13 +11,7 @@ #ifndef CMDLFCOTAG_H__ #define CMDLFCOTAG_H__ -#include "proxmark3.h" // Definitions, USB controls, COTAG_BITS -#include "util.h" // FALSE / TRUE -#include "cmddata.h" // getSamples -#include "cmdparser.h" // CmdsParse, CmdsHelp -#include "comms.h" -#include "ui.h" // PrintAndLog -#include "cmdlf.h" // Setconfig +#include "common.h" #ifndef COTAG_BITS #define COTAG_BITS 264 diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c index 77c653160..a87fd46eb 100644 --- a/client/cmdlfem4x.c +++ b/client/cmdlfem4x.c @@ -10,6 +10,23 @@ #include "cmdlfem4x.h" +#include +#include +#include +#include +#include + +#include "cmdparser.h" // command_t +#include "comms.h" +#include "commonutil.h" +#include "util_posix.h" +#include "protocols.h" +#include "ui.h" +#include "graph.h" +#include "cmddata.h" +#include "cmdlf.h" +#include "lfdemod.h" + uint64_t g_em410xid = 0; static int CmdHelp(const char *Cmd); diff --git a/client/cmdlfem4x.h b/client/cmdlfem4x.h index 12f27c2c7..d727cb551 100644 --- a/client/cmdlfem4x.h +++ b/client/cmdlfem4x.h @@ -11,19 +11,7 @@ #ifndef CMDLFEM4X_H__ #define CMDLFEM4X_H__ -#include -#include // for bool -#include -#include -#include "proxmark3.h" -#include "ui.h" -#include "util.h" -#include "graph.h" -#include "cmdparser.h" -#include "cmddata.h" -#include "comms.h" -#include "cmdlf.h" -#include "lfdemod.h" +#include "common.h" int CmdLFEM4X(const char *Cmd); diff --git a/client/cmdlffdx.c b/client/cmdlffdx.c index a13c1e947..2e48918fb 100644 --- a/client/cmdlffdx.c +++ b/client/cmdlffdx.c @@ -10,6 +10,21 @@ #include "cmdlffdx.h" +#include +#include +#include + +#include "cmdparser.h" // command_t +#include "comms.h" +#include "commonutil.h" + +#include "ui.h" // PrintAndLog +#include "cmddata.h" +#include "cmdlf.h" // lf read +#include "crc16.h" // for checksum crc-16_ccitt +#include "protocols.h" // for T55xx config register definitions +#include "lfdemod.h" // parityTest + /* FDX-B ISO11784/85 demod (aka animal tag) BIPHASE, inverted, rf/32, with preamble of 00000000001 (128bits) 8 databits + 1 parity (1) diff --git a/client/cmdlffdx.h b/client/cmdlffdx.h index 5e6c5ab48..d8b666ccb 100644 --- a/client/cmdlffdx.h +++ b/client/cmdlffdx.h @@ -8,16 +8,8 @@ //----------------------------------------------------------------------------- #ifndef CMDLFFDX_H__ #define CMDLFFDX_H__ -#include "proxmark3.h" // Definitions, USB controls, etc -#include "ui.h" // PrintAndLog -#include "util.h" // weigandparity -#include "cmdparser.h" -#include "cmddata.h" -#include "cmdmain.h" -#include "cmdlf.h" // lf read -#include "crc16.h" // for checksum crc-16_ccitt -#include "protocols.h" // for T55xx config register definitions -#include "lfdemod.h" // parityTest + +#include "common.h" int CmdLFFdx(const char *Cmd); int detectFDXB(uint8_t *dest, size_t *size); diff --git a/client/cmdlfguard.c b/client/cmdlfguard.c index 19f23088e..22f7141fc 100644 --- a/client/cmdlfguard.c +++ b/client/cmdlfguard.c @@ -9,6 +9,19 @@ //----------------------------------------------------------------------------- #include "cmdlfguard.h" +#include +#include +#include +#include + +#include "cmdparser.h" // command_t +#include "comms.h" +#include "ui.h" +#include "cmddata.h" +#include "cmdlf.h" +#include "protocols.h" // for T55xx config register definitions +#include "lfdemod.h" // parityTest + static int CmdHelp(const char *Cmd); static int usage_lf_guard_clone(void) { diff --git a/client/cmdlfguard.h b/client/cmdlfguard.h index c6725ed07..3d923a7fe 100644 --- a/client/cmdlfguard.h +++ b/client/cmdlfguard.h @@ -8,19 +8,8 @@ //----------------------------------------------------------------------------- #ifndef CMDLFGUARD_H__ #define CMDLFGUARD_H__ -#include -#include -#include "proxmark3.h" -#include "ui.h" -#include "util.h" -#include "graph.h" -#include "cmdparser.h" -#include "cmddata.h" -#include "cmdmain.h" -#include "cmdlf.h" -#include "protocols.h" // for T55xx config register definitions -#include "lfdemod.h" // parityTest -#include "crc.h" + +#include "common.h" int CmdLFGuard(const char *Cmd); int detectGProxII(uint8_t *bits, size_t *size); diff --git a/client/cmdlfhid.c b/client/cmdlfhid.c index 57df08d5d..8e22654f4 100644 --- a/client/cmdlfhid.c +++ b/client/cmdlfhid.c @@ -10,6 +10,22 @@ #include "cmdlfhid.h" +#include +#include + +#include +#include + +#include "cmdparser.h" // command_t +#include "comms.h" +#include "commonutil.h" // ARRAYLEN +#include "ui.h" +#include "graph.h" +#include "cmddata.h" //for g_debugMode, demodbuff cmds +#include "cmdlf.h" // lf_read +#include "util_posix.h" +#include "lfdemod.h" + #ifndef BITS # define BITS 96 #endif diff --git a/client/cmdlfhid.h b/client/cmdlfhid.h index 8270b6469..2b61861ff 100644 --- a/client/cmdlfhid.h +++ b/client/cmdlfhid.h @@ -11,18 +11,7 @@ #ifndef CMDLFHID_H__ #define CMDLFHID_H__ -#include -#include -#include "proxmark3.h" -#include "ui.h" -#include "graph.h" -#include "cmdparser.h" -#include "util.h" // wiegand_add_parity etc -#include "cmddata.h" //for g_debugMode, demodbuff cmds -#include "cmdlf.h" // lf_read -#include "cmdmain.h" -#include "util_posix.h" -#include "lfdemod.h" +#include "common.h" int CmdLFHID(const char *Cmd); diff --git a/client/cmdlfhitag.c b/client/cmdlfhitag.c index a1fb3415b..190b84283 100644 --- a/client/cmdlfhitag.c +++ b/client/cmdlfhitag.c @@ -8,19 +8,13 @@ // Low frequency Hitag support //----------------------------------------------------------------------------- -#include -#include -#include -#include "proxmark3.h" -#include "ui.h" -#include "cmdparser.h" -#include "common.h" -#include "util.h" -#include "parity.h" -#include "hitag.h" -#include "util_posix.h" +#include + +#include "cmdparser.h" // command_t #include "comms.h" -#include "cmddata.h" +#include "cmdtrace.h" +#include "commonutil.h" +#include "hitag.h" #include "loclass/fileutils.h" // savefile static int CmdHelp(const char *Cmd); @@ -299,7 +293,7 @@ static int CmdLFHitagSim(const char *Cmd) { param_getstr(Cmd, cmdp + 1, filename, sizeof(filename)); res = loadFileEML(filename, data, &datalen); if (res > 0 || datalen != maxdatalen) { - PrintAndLogDevice(FAILED, "error, bytes read mismatch file size"); + PrintAndLogEx(FAILED, "error, bytes read mismatch file size"); errors = true; break; } diff --git a/client/cmdlfhitag.h b/client/cmdlfhitag.h index 264a245a1..c95c0e334 100644 --- a/client/cmdlfhitag.h +++ b/client/cmdlfhitag.h @@ -11,6 +11,8 @@ #ifndef CMDLFHITAG_H__ #define CMDLFHITAG_H__ +#include "common.h" + int CmdLFHitag(const char *Cmd); int readHitagUid(void); diff --git a/client/cmdlfindala.c b/client/cmdlfindala.c index f7dc65271..3fd3be59e 100644 --- a/client/cmdlfindala.c +++ b/client/cmdlfindala.c @@ -10,6 +10,22 @@ #include "cmdlfindala.h" +#include +#include + +#include +#include + +#include "cmdparser.h" // command_t +#include "comms.h" +#include "graph.h" +#include "cliparser/cliparser.h" +#include "commonutil.h" +#include "ui.h" // PrintAndLog +#include "lfdemod.h" // parityTest, bitbytes_to_byte +#include "cmddata.h" +#include "cmdlf.h" // lf_read + static int CmdHelp(const char *Cmd); //large 224 bit indala formats (different preamble too...) diff --git a/client/cmdlfindala.h b/client/cmdlfindala.h index 1de894bf7..830017117 100644 --- a/client/cmdlfindala.h +++ b/client/cmdlfindala.h @@ -10,18 +10,7 @@ #ifndef CMDLFINDALA_H__ #define CMDLFINDALA_H__ -#include // sscanf -#include -#include -#include "proxmark3.h" // Definitions, USB controls, etc -#include "ui.h" // PrintAndLog -#include "cmdparser.h" // CmdsParse, CmdsHelp -#include "lfdemod.h" // parityTest, bitbytes_to_byte -#include "util.h" // weigandparity -#include "protocols.h" // for T55xx config register definitions -#include "cmdmain.h" -#include "cmddata.h" -#include "cmdlf.h" // lf_read +#include "common.h" int CmdLFINDALA(const char *Cmd); diff --git a/client/cmdlfio.c b/client/cmdlfio.c index b1605ecfa..87fa17b02 100644 --- a/client/cmdlfio.c +++ b/client/cmdlfio.c @@ -10,6 +10,21 @@ #include "cmdlfio.h" +#include // sscanf +#include +#include + +#include + +#include "cmdparser.h" // command_t +#include "comms.h" +#include "graph.h" +#include "cmdlf.h" +#include "ui.h" // PrintAndLog +#include "lfdemod.h" // parityTest, bitbytes_to_byte +#include "protocols.h" // for T55xx config register definitions +#include "cmddata.h" + static int CmdHelp(const char *Cmd); /* static int usage_lf_io_read(void) { diff --git a/client/cmdlfio.h b/client/cmdlfio.h index 39abbc767..cb3a514be 100644 --- a/client/cmdlfio.h +++ b/client/cmdlfio.h @@ -4,17 +4,7 @@ #ifndef CMDLFIO_H__ #define CMDLFIO_H__ -#include // sscanf -#include -#include -#include "proxmark3.h" // Definitions, USB controls, etc -#include "ui.h" // PrintAndLog -#include "cmdparser.h" // CmdsParse, CmdsHelp -#include "lfdemod.h" // parityTest, bitbytes_to_byte -#include "util.h" // weigandparity -#include "protocols.h" // for T55xx config register definitions -#include "cmdmain.h" -#include "cmddata.h" +#include "common.h" int CmdLFIO(const char *Cmd); diff --git a/client/cmdlfjablotron.c b/client/cmdlfjablotron.c index 11370e286..9cc663895 100644 --- a/client/cmdlfjablotron.c +++ b/client/cmdlfjablotron.c @@ -10,6 +10,21 @@ #include "cmdlfjablotron.h" +#include +#include +#include +#include +#include + +#include "cmdparser.h" // command_t +#include "comms.h" +#include "commonutil.h" +#include "ui.h" +#include "cmddata.h" +#include "cmdlf.h" +#include "protocols.h" // for T55xx config register definitions +#include "lfdemod.h" // parityTest + static int CmdHelp(const char *Cmd); static int usage_lf_jablotron_clone(void) { diff --git a/client/cmdlfjablotron.h b/client/cmdlfjablotron.h index ae6186496..da4de291f 100644 --- a/client/cmdlfjablotron.h +++ b/client/cmdlfjablotron.h @@ -8,19 +8,8 @@ //----------------------------------------------------------------------------- #ifndef CMDLFJABLOTRON_H__ #define CMDLFJABLOTRON_H__ -#include -#include -#include -#include "proxmark3.h" -#include "ui.h" -#include "util.h" -#include "graph.h" -#include "cmdparser.h" -#include "cmddata.h" -#include "cmdmain.h" -#include "cmdlf.h" -#include "protocols.h" // for T55xx config register definitions -#include "lfdemod.h" // parityTest + +#include "common.h" int CmdLFJablotron(const char *Cmd); diff --git a/client/cmdlfkeri.c b/client/cmdlfkeri.c index a71687a62..384aad0b6 100644 --- a/client/cmdlfkeri.c +++ b/client/cmdlfkeri.c @@ -9,6 +9,20 @@ //----------------------------------------------------------------------------- #include "cmdlfkeri.h" +#include +#include + +#include +#include + +#include "cmdparser.h" // command_t +#include "comms.h" +#include "ui.h" +#include "cmddata.h" +#include "cmdlf.h" +#include "protocols.h" // for T55xx config register definitions +#include "lfdemod.h" // preamble test + static int CmdHelp(const char *Cmd); static int usage_lf_keri_clone(void) { diff --git a/client/cmdlfkeri.h b/client/cmdlfkeri.h index 78b087834..2e1ada11f 100644 --- a/client/cmdlfkeri.h +++ b/client/cmdlfkeri.h @@ -9,18 +9,7 @@ #ifndef CMDLFKERI_H__ #define CMDLFKERI_H__ -#include -#include -#include "proxmark3.h" -#include "ui.h" -#include "util.h" -#include "graph.h" -#include "cmdparser.h" -#include "cmddata.h" -#include "cmdmain.h" -#include "cmdlf.h" -#include "protocols.h" // for T55xx config register definitions -#include "lfdemod.h" // preamble test +#include "common.h" int CmdLFKeri(const char *Cmd); diff --git a/client/cmdlfnedap.c b/client/cmdlfnedap.c index dc8894971..b7f9891a5 100644 --- a/client/cmdlfnedap.c +++ b/client/cmdlfnedap.c @@ -9,6 +9,20 @@ #include "cmdlfnedap.h" +#include + +#include +#include + +#include "cmdparser.h" // command_t +#include "comms.h" +#include "crc16.h" +#include "cmdlft55xx.h" +#include "ui.h" +#include "cmddata.h" +#include "cmdlf.h" +#include "lfdemod.h" + #define FIXED_71 0x71 #define FIXED_40 0x40 #define UNKNOWN_A 0x00 diff --git a/client/cmdlfnedap.h b/client/cmdlfnedap.h index 8ba7c9908..fda0e130e 100644 --- a/client/cmdlfnedap.h +++ b/client/cmdlfnedap.h @@ -8,19 +8,8 @@ //----------------------------------------------------------------------------- #ifndef CMDLFNEDAP_H__ #define CMDLFNEDAP_H__ -#include -#include -#include "proxmark3.h" -#include "ui.h" -#include "util.h" -#include "graph.h" -#include "cmdparser.h" -#include "cmddata.h" -#include "cmdmain.h" -#include "cmdlf.h" -#include "protocols.h" // for T55xx config register definitions -#include "lfdemod.h" // parityTest -#include "crc.h" + +#include "common.h" int CmdLFNedap(const char *Cmd); diff --git a/client/cmdlfnexwatch.c b/client/cmdlfnexwatch.c index e543dd635..bad9dea4f 100644 --- a/client/cmdlfnexwatch.c +++ b/client/cmdlfnexwatch.c @@ -10,6 +10,13 @@ #include "cmdlfnexwatch.h" +#include "cmdparser.h" // command_t +#include "comms.h" +#include "ui.h" +#include "cmddata.h" // preamblesearch +#include "cmdlf.h" +#include "lfdemod.h" + static int CmdHelp(const char *Cmd); static int CmdNexWatchDemod(const char *Cmd) { diff --git a/client/cmdlfnexwatch.h b/client/cmdlfnexwatch.h index 4a70761a4..a282a320e 100644 --- a/client/cmdlfnexwatch.h +++ b/client/cmdlfnexwatch.h @@ -9,18 +9,7 @@ #ifndef CMDLFNEXWATCH_H__ #define CMDLFNEXWATCH_H__ -#include -#include -#include -#include -#include "proxmark3.h" -#include "ui.h" -#include "util.h" -#include "graph.h" -#include "cmdparser.h" -#include "cmddata.h" // preamblesearch -#include "cmdlf.h" -#include "lfdemod.h" +#include "common.h" int CmdLFNEXWATCH(const char *Cmd); diff --git a/client/cmdlfnoralsy.c b/client/cmdlfnoralsy.c index ec8da0bf9..cc1db82ca 100644 --- a/client/cmdlfnoralsy.c +++ b/client/cmdlfnoralsy.c @@ -9,6 +9,18 @@ //----------------------------------------------------------------------------- #include "cmdlfnoralsy.h" +#include +#include +#include + +#include "cmdparser.h" // command_t +#include "comms.h" +#include "ui.h" +#include "cmddata.h" +#include "cmdlf.h" +#include "protocols.h" // for T55xx config register definitions +#include "lfdemod.h" // parityTest + static int CmdHelp(const char *Cmd); static int usage_lf_noralsy_clone(void) { diff --git a/client/cmdlfnoralsy.h b/client/cmdlfnoralsy.h index b5a5cd914..f76accab7 100644 --- a/client/cmdlfnoralsy.h +++ b/client/cmdlfnoralsy.h @@ -8,19 +8,8 @@ //----------------------------------------------------------------------------- #ifndef CMDLFNORALSY_H__ #define CMDLFNORALSY_H__ -#include -#include -#include -#include "proxmark3.h" -#include "ui.h" -#include "util.h" -#include "graph.h" -#include "cmdparser.h" -#include "cmddata.h" -#include "cmdmain.h" -#include "cmdlf.h" -#include "protocols.h" // for T55xx config register definitions -#include "lfdemod.h" // parityTest + +#include "common.h" int CmdLFNoralsy(const char *Cmd); diff --git a/client/cmdlfpac.c b/client/cmdlfpac.c index b9d6f1449..864506089 100644 --- a/client/cmdlfpac.c +++ b/client/cmdlfpac.c @@ -9,6 +9,13 @@ //----------------------------------------------------------------------------- #include "cmdlfpac.h" +#include "cmdparser.h" // command_t +#include "comms.h" +#include "ui.h" +#include "cmddata.h" +#include "cmdlf.h" +#include "lfdemod.h" // preamble test + static int CmdHelp(const char *Cmd); //see NRZDemod for what args are accepted diff --git a/client/cmdlfpac.h b/client/cmdlfpac.h index f076121cd..3c9c4fbda 100644 --- a/client/cmdlfpac.h +++ b/client/cmdlfpac.h @@ -9,17 +9,7 @@ #ifndef CMDLFPAC_H__ #define CMDLFPAC_H__ -#include -#include -#include "proxmark3.h" -#include "ui.h" -#include "util.h" -#include "graph.h" -#include "cmdparser.h" -#include "cmddata.h" -#include "cmdmain.h" -#include "cmdlf.h" -#include "lfdemod.h" // preamble test +#include "common.h" int CmdLFPac(const char *Cmd); diff --git a/client/cmdlfparadox.c b/client/cmdlfparadox.c index d18c501ca..8a1a940c5 100644 --- a/client/cmdlfparadox.c +++ b/client/cmdlfparadox.c @@ -7,15 +7,17 @@ // Low frequency Paradox tag commands // FSK2a, rf/50, 96 bits (completely known) //----------------------------------------------------------------------------- +#include "cmdlfparadox.h" + #include #include -#include -#include "cmdlfparadox.h" -#include "proxmark3.h" +#include +#include + +#include "cmdparser.h" // command_t +#include "comms.h" #include "ui.h" -#include "util.h" #include "graph.h" -#include "cmdparser.h" #include "cmddata.h" #include "cmdlf.h" #include "lfdemod.h" diff --git a/client/cmdlfparadox.h b/client/cmdlfparadox.h index f7f4a4ffe..34c3cb6cd 100644 --- a/client/cmdlfparadox.h +++ b/client/cmdlfparadox.h @@ -8,6 +8,9 @@ //----------------------------------------------------------------------------- #ifndef CMDLFPARADOX_H__ #define CMDLFPARADOX_H__ + +#include "common.h" + int CmdLFParadox(const char *Cmd); int demodParadox(void); diff --git a/client/cmdlfpcf7931.c b/client/cmdlfpcf7931.c index a9ab9cf3e..e4a14a47e 100644 --- a/client/cmdlfpcf7931.c +++ b/client/cmdlfpcf7931.c @@ -8,18 +8,14 @@ //----------------------------------------------------------------------------- // Low frequency PCF7931 commands //----------------------------------------------------------------------------- -#include -#include -#include "proxmark3.h" -#include "ui.h" -#include "util.h" -#include "graph.h" -#include "cmdparser.h" -#include "cmddata.h" -#include "cmdmain.h" -#include "cmdlf.h" #include "cmdlfpcf7931.h" +#include + +#include "cmdparser.h" // command_t +#include "comms.h" +#include "ui.h" + static int CmdHelp(const char *Cmd); #define PCF7931_DEFAULT_INITDELAY 17500 diff --git a/client/cmdlfpcf7931.h b/client/cmdlfpcf7931.h index 419386956..4f84085b2 100644 --- a/client/cmdlfpcf7931.h +++ b/client/cmdlfpcf7931.h @@ -12,6 +12,8 @@ #ifndef CMDLFPCF7931_H__ #define CMDLFPCF7931_H__ +#include "common.h" + struct pcf7931_config { uint8_t Pwd[7]; uint16_t InitDelay; diff --git a/client/cmdlfpresco.c b/client/cmdlfpresco.c index cbf919aef..14d87648e 100644 --- a/client/cmdlfpresco.c +++ b/client/cmdlfpresco.c @@ -8,6 +8,20 @@ //----------------------------------------------------------------------------- #include "cmdlfpresco.h" + +#include +#include +#include +#include + +#include "cmdparser.h" // command_t +#include "comms.h" +#include "ui.h" +#include "cmddata.h" +#include "cmdlf.h" +#include "protocols.h" // for T55xx config register definitions +#include "lfdemod.h" // parityTest + static int CmdHelp(const char *Cmd); static int usage_lf_presco_clone(void) { diff --git a/client/cmdlfpresco.h b/client/cmdlfpresco.h index 1f101a13c..098a98342 100644 --- a/client/cmdlfpresco.h +++ b/client/cmdlfpresco.h @@ -8,18 +8,8 @@ //----------------------------------------------------------------------------- #ifndef CMDLFPRESCO_H__ #define CMDLFPRESCO_H__ -#include -#include -#include "proxmark3.h" -#include "ui.h" -#include "util.h" -#include "graph.h" -#include "cmdparser.h" -#include "cmddata.h" -#include "cmdmain.h" -#include "cmdlf.h" -#include "protocols.h" // for T55xx config register definitions -#include "lfdemod.h" // parityTest + +#include "common.h" int CmdLFPresco(const char *Cmd); diff --git a/client/cmdlfpyramid.c b/client/cmdlfpyramid.c index b36d386c9..d5c3076a9 100644 --- a/client/cmdlfpyramid.c +++ b/client/cmdlfpyramid.c @@ -9,6 +9,21 @@ //----------------------------------------------------------------------------- #include "cmdlfpyramid.h" +#include +#include +#include +#include + +#include "cmdparser.h" // command_t +#include "comms.h" +#include "ui.h" +#include "graph.h" +#include "cmddata.h" +#include "cmdlf.h" +#include "protocols.h" // for T55xx config register definitions +#include "lfdemod.h" // parityTest +#include "crc.h" + static int CmdHelp(const char *Cmd); static int usage_lf_pyramid_clone(void) { diff --git a/client/cmdlfpyramid.h b/client/cmdlfpyramid.h index 009bec3ce..2d717fbb3 100644 --- a/client/cmdlfpyramid.h +++ b/client/cmdlfpyramid.h @@ -8,19 +8,8 @@ //----------------------------------------------------------------------------- #ifndef CMDLFPYRAMID_H__ #define CMDLFPYRAMID_H__ -#include -#include -#include "proxmark3.h" -#include "ui.h" -#include "util.h" -#include "graph.h" -#include "cmdparser.h" -#include "cmddata.h" -#include "cmdmain.h" -#include "cmdlf.h" -#include "protocols.h" // for T55xx config register definitions -#include "lfdemod.h" // parityTest -#include "crc.h" + +#include "common.h" int CmdLFPyramid(const char *Cmd); diff --git a/client/cmdlfsecurakey.c b/client/cmdlfsecurakey.c index 82df3b659..0ee22524f 100644 --- a/client/cmdlfsecurakey.c +++ b/client/cmdlfsecurakey.c @@ -9,6 +9,16 @@ //----------------------------------------------------------------------------- #include "cmdlfsecurakey.h" +#include + +#include "cmdparser.h" // command_t +#include "comms.h" +#include "ui.h" +#include "cmddata.h" +#include "cmdlf.h" +#include "lfdemod.h" // preamble test +#include "parity.h" // for wiegand parity test + static int CmdHelp(const char *Cmd); //see ASKDemod for what args are accepted diff --git a/client/cmdlfsecurakey.h b/client/cmdlfsecurakey.h index 6a84d2046..229fd0047 100644 --- a/client/cmdlfsecurakey.h +++ b/client/cmdlfsecurakey.h @@ -9,20 +9,7 @@ #ifndef CMDLFSECURAKEY_H__ #define CMDLFSECURAKEY_H__ -#include -#include -#include -#include "proxmark3.h" -#include "ui.h" -#include "util.h" -#include "graph.h" -#include "cmdparser.h" -#include "cmddata.h" -#include "cmdmain.h" -#include "cmdlf.h" -#include "protocols.h" // for T55xx config register definitions -#include "lfdemod.h" // preamble test -#include "parity.h" // for wiegand parity test +#include "common.h" int CmdLFSecurakey(const char *Cmd); diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index be24be976..72838e73b 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -14,6 +14,21 @@ #include "cmdlft55xx.h" +#include +#include // MingW + +#include "cmdparser.h" // command_t +#include "comms.h" +#include "commonutil.h" +#include "protocols.h" +#include "graph.h" +#include "cmddata.h" +#include "lfdemod.h" +#include "cmdhf14a.h" // for getTagInfo +#include "loclass/fileutils.h" // loadDictionary +#include "util_posix.h" + + // Some defines for readability #define T55XX_DLMODE_FIXED 0 // Default Mode #define T55XX_DLMODE_LLR 1 // Long Leading Reference @@ -2117,7 +2132,7 @@ static int CmdT55xxChkPwds(const char *Cmd) { // TODO, a way of reallocating memory if file was larger keyBlock = calloc(4 * 200, sizeof(uint8_t)); if (keyBlock == NULL) { - PrintAndLogDevice(ERR, "error, cannot allocate memory "); + PrintAndLogEx(ERR, "error, cannot allocate memory "); return PM3_ESOFT; } diff --git a/client/cmdlft55xx.h b/client/cmdlft55xx.h index c61ef137d..668b23be3 100644 --- a/client/cmdlft55xx.h +++ b/client/cmdlft55xx.h @@ -10,23 +10,7 @@ #ifndef CMDLFT55XX_H__ #define CMDLFT55XX_H__ -#include -#include -#include -#include -#include -#include "proxmark3.h" -#include "ui.h" -#include "graph.h" -#include "comms.h" -#include "cmdparser.h" -#include "cmddata.h" -#include "cmdlf.h" -#include "util.h" -#include "lfdemod.h" -#include "cmdhf14a.h" // for getTagInfo -#include "loclass/fileutils.h" // loadDictionary - +#include "common.h" #define T55x7_CONFIGURATION_BLOCK 0x00 #define T55x7_TRACE_BLOCK1 0x01 diff --git a/client/cmdlfti.c b/client/cmdlfti.c index 9e07926f4..cf01abb73 100644 --- a/client/cmdlfti.c +++ b/client/cmdlfti.c @@ -11,13 +11,14 @@ #include #include #include + +#include "cmdparser.h" // command_t +#include "commonutil.h" +#include "comms.h" #include "crc16.h" -#include "proxmark3.h" #include "ui.h" #include "graph.h" -#include "cmdparser.h" #include "cmdlfti.h" -#include "cmdmain.h" static int CmdHelp(const char *Cmd); diff --git a/client/cmdlfti.h b/client/cmdlfti.h index bb4922f78..e185a1403 100644 --- a/client/cmdlfti.h +++ b/client/cmdlfti.h @@ -11,6 +11,8 @@ #ifndef CMDLFTI_H__ #define CMDLFTI_H__ +#include "common.h" + int CmdLFTI(const char *Cmd); int demodTI(void); diff --git a/client/cmdlfviking.c b/client/cmdlfviking.c index 1d2114e95..ef88cc169 100644 --- a/client/cmdlfviking.c +++ b/client/cmdlfviking.c @@ -9,6 +9,17 @@ //----------------------------------------------------------------------------- #include "cmdlfviking.h" +#include +#include +#include + +#include "cmdparser.h" // command_t +#include "comms.h" +#include "ui.h" +#include "cmddata.h" +#include "cmdlf.h" +#include "lfdemod.h" + static int CmdHelp(const char *Cmd); static int usage_lf_viking_clone(void) { diff --git a/client/cmdlfviking.h b/client/cmdlfviking.h index 8789515d6..156d57c7d 100644 --- a/client/cmdlfviking.h +++ b/client/cmdlfviking.h @@ -8,18 +8,8 @@ //----------------------------------------------------------------------------- #ifndef CMDLFVIKING_H__ #define CMDLFVIKING_H__ -#include -#include -#include -#include "proxmark3.h" -#include "ui.h" -#include "util.h" -#include "graph.h" -#include "cmdparser.h" -#include "cmddata.h" -#include "cmdmain.h" -#include "cmdlf.h" -#include "lfdemod.h" + +#include "common.h" int CmdLFViking(const char *Cmd); diff --git a/client/cmdlfvisa2000.c b/client/cmdlfvisa2000.c index d698535bf..ed181d991 100644 --- a/client/cmdlfvisa2000.c +++ b/client/cmdlfvisa2000.c @@ -11,6 +11,19 @@ #include "cmdlfvisa2000.h" +#include +#include +#include + +#include "cmdparser.h" // command_t +#include "comms.h" +#include "ui.h" +#include "graph.h" +#include "cmddata.h" +#include "cmdlf.h" +#include "protocols.h" // for T55xx config register definitions +#include "lfdemod.h" // parityTest + #define BL0CK1 0x56495332 static int CmdHelp(const char *Cmd); diff --git a/client/cmdlfvisa2000.h b/client/cmdlfvisa2000.h index 15d626f6c..63e7fdc67 100644 --- a/client/cmdlfvisa2000.h +++ b/client/cmdlfvisa2000.h @@ -8,19 +8,9 @@ //----------------------------------------------------------------------------- #ifndef CMDLFVISA2000_H__ #define CMDLFVISA2000_H__ -#include -#include -#include -#include "proxmark3.h" -#include "ui.h" -#include "util.h" -#include "graph.h" -#include "cmdparser.h" -#include "cmddata.h" -#include "cmdmain.h" -#include "cmdlf.h" -#include "protocols.h" // for T55xx config register definitions -#include "lfdemod.h" // parityTest + +#include "common.h" + int CmdLFVisa2k(const char *Cmd); int getvisa2kBits(uint64_t fullcode, uint8_t *bits); diff --git a/client/cmdmain.c b/client/cmdmain.c index 6748f81f0..618f04c73 100644 --- a/client/cmdmain.c +++ b/client/cmdmain.c @@ -15,6 +15,26 @@ #endif #include "cmdmain.h" +#include +#include +#include // MingW + +#include "comms.h" +#include "cmdhf.h" +#include "cmddata.h" +#include "cmdhw.h" +#include "cmdlf.h" +#include "cmdtrace.h" +#include "cmdscript.h" +#include "cmdcrc.h" +#include "cmdanalyse.h" +#include "emv/cmdemv.h" // EMV +#include "cmdflashmem.h" // rdv40 flashmem commands +#include "cmdsmartcard.h" // rdv40 smart card ISO7816 commands +#include "cmdusart.h" // rdv40 FPC USART commands +#include "ui.h" +#include "util_posix.h" + static int CmdHelp(const char *Cmd); static int CmdRem(const char *Cmd) { diff --git a/client/cmdmain.h b/client/cmdmain.h index e3c513550..8b440143e 100644 --- a/client/cmdmain.h +++ b/client/cmdmain.h @@ -11,30 +11,8 @@ #ifndef CMDMAIN_H__ #define CMDMAIN_H__ -#include -#include -#include -#include -#include -#include -#include "util_posix.h" -#include "proxmark3.h" -#include "pm3_cmd.h" -#include "util.h" -#include "ui.h" -#include "cmdparser.h" -#include "cmdhf.h" -#include "cmddata.h" -#include "cmdhw.h" -#include "cmdlf.h" -#include "cmdtrace.h" -#include "cmdscript.h" -#include "cmdcrc.h" -#include "cmdanalyse.h" -#include "emv/cmdemv.h" // EMV -#include "cmdflashmem.h" // rdv40 flashmem commands -#include "cmdsmartcard.h" // rdv40 smart card ISO7816 commands -#include "cmdusart.h" // rdv40 FPC USART commands +#include "common.h" +#include "cmdparser.h" // command_t int CommandReceived(char *Cmd); command_t *getTopLevelCommandTable(void); diff --git a/client/cmdparser.c b/client/cmdparser.c index fff0fabec..d9ece2310 100644 --- a/client/cmdparser.c +++ b/client/cmdparser.c @@ -8,13 +8,12 @@ // Command parser //----------------------------------------------------------------------------- -#include -#include -#include -#include "util.h" -#include "ui.h" #include "cmdparser.h" -#include "proxmark3.h" + +#include +#include + +#include "ui.h" #include "comms.h" bool AlwaysAvailable(void) { diff --git a/client/cmdparser.h b/client/cmdparser.h index 06eb02848..284142780 100644 --- a/client/cmdparser.h +++ b/client/cmdparser.h @@ -11,6 +11,8 @@ #ifndef CMDPARSER_H__ #define CMDPARSER_H__ +#include "common.h" + typedef struct command_s { const char *Name; int (*Parse)(const char *Cmd); diff --git a/client/cmdscript.c b/client/cmdscript.c index 8880e18fd..28dd8608f 100644 --- a/client/cmdscript.c +++ b/client/cmdscript.c @@ -11,27 +11,21 @@ // this define is needed for scandir/alphasort to work #define _GNU_SOURCE -#include +#include #include #include -#include -#include -#include -#include "proxmark3.h" +#include "cmdparser.h" // command_t #include "scripting.h" -#include "ui.h" -#include "graph.h" -#include "cmdparser.h" -#include "cmdmain.h" #include "comms.h" #include "cmdscript.h" #include "cmdhfmf.h" #include "pm3_binlib.h" #include "pm3_bitlib.h" -#include -#include -#include +#include "lualib.h" +#include "lauxlib.h" +#include "proxmark3.h" +#include "ui.h" #ifdef _WIN32 #include "scandir.h" diff --git a/client/cmdscript.h b/client/cmdscript.h index 866b09e99..37384db20 100644 --- a/client/cmdscript.h +++ b/client/cmdscript.h @@ -11,6 +11,8 @@ #ifndef CMDSCRIPT_H__ #define CMDSCRIPT_H__ +#include "common.h" + int CmdScript(const char *Cmd); #endif diff --git a/client/cmdsmartcard.c b/client/cmdsmartcard.c index 5147dbd7e..f1fd2b917 100644 --- a/client/cmdsmartcard.c +++ b/client/cmdsmartcard.c @@ -8,7 +8,20 @@ // Proxmark3 RDV40 Smartcard module commands //----------------------------------------------------------------------------- #include "cmdsmartcard.h" -#include "../emv/emvjson.h" + +#include +#include + +#include "cmdparser.h" // command_t +#include "commonutil.h" // ARRAYLEN +#include "protocols.h" +#include "cmdtrace.h" +#include "proxmark3.h" +#include "comms.h" // getfromdevice +#include "emv/emvcore.h" // decodeTVL +#include "crypto/libpcrypto.h" // sha512hash +#include "emv/dump.h" +#include "ui.h" static int CmdHelp(const char *Cmd); diff --git a/client/cmdsmartcard.h b/client/cmdsmartcard.h index 6b960f311..74c305a0d 100644 --- a/client/cmdsmartcard.h +++ b/client/cmdsmartcard.h @@ -11,21 +11,8 @@ #ifndef CMDSMARTCARD_H__ #define CMDSMARTCARD_H__ -#include -#include -#include -#include -#include "proxmark3.h" -#include "ui.h" -#include "cmdparser.h" #include "common.h" -#include "util.h" -#include "loclass/fileutils.h" // saveFile -#include "comms.h" // getfromdevice -#include "emv/emvcore.h" // decodeTVL -#include "emv/apduinfo.h" // APDUcode description -#include "emv/dump.h" // dump_buffer -#include "crypto/libpcrypto.h" // sha512hash +#include "mifare.h" // structs int CmdSmartcard(const char *Cmd); diff --git a/client/cmdtrace.c b/client/cmdtrace.c index 4f961b69e..15416a8a6 100644 --- a/client/cmdtrace.c +++ b/client/cmdtrace.c @@ -9,6 +9,15 @@ //----------------------------------------------------------------------------- #include "cmdtrace.h" +#include + +#include "cmdparser.h" // command_t +#include "protocols.h" +#include "parity.h" // oddparity +#include "cmdhflist.h" // annotations +#include "comms.h" // for sending cmds to device. GetFromBigBuf +#include "loclass/fileutils.h" // for saveFile + static int CmdHelp(const char *Cmd); // trace pointer diff --git a/client/cmdtrace.h b/client/cmdtrace.h index 2f0125664..acef66884 100644 --- a/client/cmdtrace.h +++ b/client/cmdtrace.h @@ -10,22 +10,8 @@ #ifndef CMDTRACE_H__ #define CMDTRACE_H__ -#include -#include -#include -#include -#include -#include -#include "proxmark3.h" -#include "protocols.h" -#include "parity.h" // oddparity -#include "cmdhflist.h" // annotations -#include "iso15693tools.h" // ISO15693 crc -#include "util.h" // for parsing cli command utils -#include "ui.h" // for show graph controls -#include "cmdparser.h" // for getting cli commands included in cmdmain.h -#include "comms.h" // for sending cmds to device. GetFromBigBuf -#include "loclass/fileutils.h" // for saveFile + +#include "common.h" int CmdTrace(const char *Cmd); int CmdTraceList(const char *Cmd); diff --git a/client/cmdusart.c b/client/cmdusart.c index 5cb1a7b0c..0b668bbe7 100644 --- a/client/cmdusart.c +++ b/client/cmdusart.c @@ -9,6 +9,18 @@ //----------------------------------------------------------------------------- #include "cmdusart.h" +#include // size_t +#include +#include +#include + +#include "cmdparser.h" // command_t +#include "commonutil.h" // ARRAYLEN +#include "comms.h" +#include "util_posix.h" +#include "usart_defs.h" +#include "ui.h" // PrintAndLog + static int CmdHelp(const char *Cmd); static int usage_usart_bt_pin(void) { diff --git a/client/cmdusart.h b/client/cmdusart.h index f2e4d02dd..1ee21e060 100644 --- a/client/cmdusart.h +++ b/client/cmdusart.h @@ -11,14 +11,7 @@ #ifndef CMDUSART_H__ #define CMDUSART_H__ -#include // size_t -#include -#include -#include "cmdmain.h" -#include "proxmark3.h" -#include "ui.h" // PrintAndLog -#include "util.h" -//#include "util_posix.h" // msclock +#include "common.h" int CmdUsart(const char *Cmd); #endif diff --git a/client/comms.c b/client/comms.c index 22e5c7fa1..d42bd09fb 100644 --- a/client/comms.c +++ b/client/comms.c @@ -10,11 +10,15 @@ //----------------------------------------------------------------------------- #include "comms.h" + +#include +#include +#include + +#include "uart.h" +#include "ui.h" #include "crc16.h" -#if defined(__linux__) || (__APPLE__) -#include -#include -#endif +#include "util_posix.h" // msclock //#define COMMS_DEBUG //#define COMMS_DEBUG_RAW diff --git a/client/comms.h b/client/comms.h index bc036f008..b49ff6d11 100644 --- a/client/comms.h +++ b/client/comms.h @@ -12,19 +12,22 @@ #ifndef COMMS_H_ #define COMMS_H_ -#include -#include - -#include "pm3_cmd.h" -#include "uart.h" -#include "ui.h" #include "common.h" -#include "util_posix.h" -#include "util.h" -#include "util_darwin.h" +#include "pm3_cmd.h" // Packet structs +#include "util.h" // FILE_PATH_SIZE -#if defined(__linux__) && !defined(NO_UNLINK) -#include // for unlink() +#ifndef DropField +#define DropField() { \ + clearCommandBuffer(); SendCommandNG(CMD_HF_DROPFIELD, NULL, 0); \ + } +#endif + +#ifndef DropFieldEx +#define DropFieldEx(x) { \ + if ( (x) == ECC_CONTACTLESS) { \ + DropField(); \ + } \ + } #endif //For storing command that are received from the device diff --git a/client/crypto/asn1dump.c b/client/crypto/asn1dump.c index 2c720ad04..356dd3591 100644 --- a/client/crypto/asn1dump.c +++ b/client/crypto/asn1dump.c @@ -8,8 +8,10 @@ // asn.1 dumping //----------------------------------------------------------------------------- #define _POSIX_C_SOURCE 200809L // need for strnlen() - #include "asn1dump.h" + +#include "commonutil.h" // ARRAYLEN + #include #include #include diff --git a/client/crypto/asn1utils.c b/client/crypto/asn1utils.c index c82f4aac8..1b2c78212 100644 --- a/client/crypto/asn1utils.c +++ b/client/crypto/asn1utils.c @@ -12,6 +12,9 @@ #include #include #include + +#include "ui.h" // Print... + #include "emv/tlv.h" #include "emv/dump.h" #include "asn1dump.h" diff --git a/client/emv/apduinfo.c b/client/emv/apduinfo.c index fd49eede8..cf43615cb 100644 --- a/client/emv/apduinfo.c +++ b/client/emv/apduinfo.c @@ -10,6 +10,13 @@ #include "apduinfo.h" +#include // memmove +#include + +#include "ui.h" // Print... +#include "util.h" +#include "commonutil.h" // ARRAYLEN + const APDUCode APDUCodeTable[] = { // ID Type Description {"XXXX", APDUCODE_TYPE_NONE, ""}, // blank string diff --git a/client/emv/apduinfo.h b/client/emv/apduinfo.h index 25d062dcf..590c72885 100644 --- a/client/emv/apduinfo.h +++ b/client/emv/apduinfo.h @@ -11,13 +11,7 @@ #ifndef APDUINFO_H__ #define APDUINFO_H__ -#include -#include -#include -#include -#include - -#include "util.h" +#include "common.h" #define APDUCODE_TYPE_NONE 0 #define APDUCODE_TYPE_INFO 1 diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c index 0cf177620..3891bdb48 100644 --- a/client/emv/cmdemv.c +++ b/client/emv/cmdemv.c @@ -8,14 +8,24 @@ // EMV commands //----------------------------------------------------------------------------- -#include -#include "mifare.h" #include "cmdemv.h" + +#include + +#include "comms.h" // DropField +#include "cmdsmartcard.h" // smart_select +#include "cmdtrace.h" #include "emvjson.h" -#include "emv_pki.h" #include "test/cryptotest.h" #include "cliparser/cliparser.h" -#include +#include "cmdparser.h" +#include "proxmark3.h" +#include "emv_roca.h" +#include "emvcore.h" +#include "cmdhf14a.h" +#include "dol.h" +#include "ui.h" +#include "emv_tags.h" static int CmdHelp(const char *Cmd); diff --git a/client/emv/cmdemv.h b/client/emv/cmdemv.h index 8cdcdf990..ca1f9fc5a 100644 --- a/client/emv/cmdemv.h +++ b/client/emv/cmdemv.h @@ -11,21 +11,7 @@ #ifndef CMDEMV_H__ #define CMDEMV_H__ -#include -#include -#include -#include -#include -#include "proxmark3.h" -#include "ui.h" -#include "cmdparser.h" #include "common.h" -#include "util.h" -#include "util_posix.h" -#include "cmdmain.h" -#include "emvcore.h" -#include "apduinfo.h" -#include "emv_roca.h" int CmdEMV(const char *Cmd); diff --git a/client/emv/crypto.c b/client/emv/crypto.c index ccf668477..f7fc60c80 100644 --- a/client/emv/crypto.c +++ b/client/emv/crypto.c @@ -20,8 +20,6 @@ #include "crypto.h" #include "crypto_backend.h" -#include - static struct crypto_backend *crypto_backend; static bool crypto_init(void) { diff --git a/client/emv/crypto.h b/client/emv/crypto.h index 4eacca0b8..32252b4cc 100644 --- a/client/emv/crypto.h +++ b/client/emv/crypto.h @@ -16,8 +16,7 @@ #ifndef CRYPTO_H #define CRYPTO_H -#include -#include +#include "common.h" enum crypto_algo_hash { HASH_INVALID, diff --git a/client/emv/crypto_backend.h b/client/emv/crypto_backend.h index 1113cf341..3a38cc772 100644 --- a/client/emv/crypto_backend.h +++ b/client/emv/crypto_backend.h @@ -18,8 +18,7 @@ #include "crypto.h" -#include -#include +#include // va_list struct crypto_hash { enum crypto_algo_hash algo; diff --git a/client/emv/crypto_polarssl.c b/client/emv/crypto_polarssl.c index 13f093aa4..b87dd9ee0 100644 --- a/client/emv/crypto_polarssl.c +++ b/client/emv/crypto_polarssl.c @@ -18,11 +18,8 @@ #include #endif -#include "crypto.h" #include "crypto_backend.h" -#include -#include #include #include diff --git a/client/emv/dol.h b/client/emv/dol.h index 496ae66f5..8e65f679d 100644 --- a/client/emv/dol.h +++ b/client/emv/dol.h @@ -17,7 +17,6 @@ #define DOL_H #include "emv/tlv.h" -#include struct tlv *dol_process(const struct tlv *tlv, const struct tlvdb *tlvdb, tlv_tag_t tag); struct tlvdb *dol_parse(const struct tlv *tlv, const unsigned char *data, size_t data_len); diff --git a/client/emv/dump.h b/client/emv/dump.h index fd6e16018..5a71b9519 100644 --- a/client/emv/dump.h +++ b/client/emv/dump.h @@ -16,9 +16,9 @@ #ifndef DUMP_H #define DUMP_H -#include -#include -#include +#include "common.h" + +#include // FILE void dump_buffer_simple(const unsigned char *ptr, size_t len, FILE *f); void dump_buffer(const unsigned char *ptr, size_t len, FILE *f, int level); diff --git a/client/emv/emv_pk.c b/client/emv/emv_pk.c index b03567440..e273480c8 100644 --- a/client/emv/emv_pk.c +++ b/client/emv/emv_pk.c @@ -19,16 +19,16 @@ /* For asprintf */ #define _GNU_SOURCE -#include #include "emv_pk.h" -#include "crypto.h" -#include "proxmark3.h" -#include "util.h" -#include + +#include #include #include -#include + +#include "ui.h" +#include "crypto.h" +#include "proxmark3.h" #define BCD(c) (((c) >= '0' && (c) <= '9') ? ((c) - '0') : \ -1) diff --git a/client/emv/emv_pk.h b/client/emv/emv_pk.h index ed8000dc0..dfc249710 100644 --- a/client/emv/emv_pk.h +++ b/client/emv/emv_pk.h @@ -16,8 +16,7 @@ #ifndef EMV_PK_H #define EMV_PK_H -#include -#include +#include "common.h" struct emv_pk { unsigned char rid[5]; diff --git a/client/emv/emv_pki.c b/client/emv/emv_pki.c index cb2486bb4..bbdb321b3 100644 --- a/client/emv/emv_pki.c +++ b/client/emv/emv_pki.c @@ -18,15 +18,15 @@ #endif #include "emv_pki.h" -#include "crypto.h" -#include "dump.h" -#include "util.h" -#include #include #include #include +#include "crypto.h" +#include "dump.h" +#include "util.h" + static bool strictExecution = true; void PKISetStrictExecution(bool se) { strictExecution = se; diff --git a/client/emv/emv_pki.h b/client/emv/emv_pki.h index 91ff60166..05506f02c 100644 --- a/client/emv/emv_pki.h +++ b/client/emv/emv_pki.h @@ -19,8 +19,6 @@ #include "emv_pk.h" #include "tlv.h" -#include - void PKISetStrictExecution(bool se); unsigned char *emv_pki_sdatl_fill(const struct tlvdb *db, size_t *sdatl_len); diff --git a/client/emv/emv_pki_priv.c b/client/emv/emv_pki_priv.c index 5256b4e37..f10c5352b 100644 --- a/client/emv/emv_pki_priv.c +++ b/client/emv/emv_pki_priv.c @@ -18,7 +18,6 @@ #endif #include "emv_pki_priv.h" -#include "crypto.h" #include #include diff --git a/client/emv/emv_pki_priv.h b/client/emv/emv_pki_priv.h index 8c8d1a813..b85b1176b 100644 --- a/client/emv/emv_pki_priv.h +++ b/client/emv/emv_pki_priv.h @@ -16,12 +16,12 @@ #ifndef EMV_PKI_PRIV_H #define EMV_PKI_PRIV_H +#include "common.h" + #include "crypto.h" #include "emv_pk.h" #include "tlv.h" -#include - struct emv_pk *emv_pki_make_ca(const struct crypto_pk *cp, const unsigned char *rid, unsigned char index, unsigned int expire, enum crypto_algo_hash hash_algo); diff --git a/client/emv/emv_roca.c b/client/emv/emv_roca.c index a3a8cb7fe..521120b05 100644 --- a/client/emv/emv_roca.c +++ b/client/emv/emv_roca.c @@ -23,6 +23,9 @@ #include "emv_roca.h" +#include "ui.h" // Print... +#include "mbedtls/bignum.h" + static uint8_t g_primes[ROCA_PRINTS_LENGTH] = { 11, 13, 17, 19, 37, 53, 61, 71, 73, 79, 97, 103, 107, 109, 127, 151, 157 }; diff --git a/client/emv/emv_roca.h b/client/emv/emv_roca.h index 6663ce710..8c8ea86e4 100644 --- a/client/emv/emv_roca.h +++ b/client/emv/emv_roca.h @@ -24,10 +24,7 @@ #ifndef EMV_ROCA_H__ #define EMV_ROCA_H__ -#include -#include -#include "mbedtls/bignum.h" -#include "util.h" +#include "common.h" #define ROCA_PRINTS_LENGTH 17 diff --git a/client/emv/emv_tags.c b/client/emv/emv_tags.c index 45202f9e6..72c1fe78e 100644 --- a/client/emv/emv_tags.c +++ b/client/emv/emv_tags.c @@ -17,13 +17,13 @@ #include #endif -#include "commonutil.h" -#include "tlv.h" #include "emv_tags.h" #include #include +#include "commonutil.h" + #ifndef PRINT_INDENT # define PRINT_INDENT(level) {for (int myi = 0; myi < (level); myi++) fprintf(f, " ");} #endif diff --git a/client/emv/emv_tags.h b/client/emv/emv_tags.h index 51905e75e..235048b20 100644 --- a/client/emv/emv_tags.h +++ b/client/emv/emv_tags.h @@ -17,7 +17,7 @@ #define TAGS_H #include "tlv.h" -#include +#include // FILE // AC # define EMVAC_AC_MASK 0xC0 diff --git a/client/emv/emvcore.c b/client/emv/emvcore.c index e44492078..09dc7883e 100644 --- a/client/emv/emvcore.c +++ b/client/emv/emvcore.c @@ -9,6 +9,18 @@ //----------------------------------------------------------------------------- #include "emvcore.h" + +#include + +#include "commonutil.h" // ARRAYLEN +#include "comms.h" // DropField +#include "cmdparser.h" +#include "cmdsmartcard.h" // ExchangeAPDUSC +#include "ui.h" +#include "cmdhf14a.h" +#include "dol.h" +#include "dump.h" +#include "emv_tags.h" #include "emvjson.h" #include "util_posix.h" diff --git a/client/emv/emvcore.h b/client/emv/emvcore.h index 3faae283d..a520a2d5f 100644 --- a/client/emv/emvcore.h +++ b/client/emv/emvcore.h @@ -11,22 +11,12 @@ #ifndef EMVCORE_H__ #define EMVCORE_H__ -#include -#include -#include -#include -#include -#include -#include "util.h" #include "common.h" -#include "ui.h" -#include "cmdhf14a.h" + +#include +#include + #include "apduinfo.h" -#include "tlv.h" -#include "dol.h" -#include "dump.h" -#include "emv_tags.h" -#include "emv_pk.h" #include "emv_pki.h" #define APDU_RES_LEN 260 diff --git a/client/emv/emvjson.c b/client/emv/emvjson.c index 67de32701..88d886c6e 100644 --- a/client/emv/emvjson.c +++ b/client/emv/emvjson.c @@ -9,12 +9,12 @@ //----------------------------------------------------------------------------- #include "emvjson.h" -#include -#include -#include -#include + #include + +#include "commonutil.h" // ARRAYLEN #include "ui.h" +#include "util.h" #include "proxmark3.h" #include "emv_tags.h" diff --git a/client/emv/emvjson.h b/client/emv/emvjson.h index 6bcf8243d..54d97ada8 100644 --- a/client/emv/emvjson.h +++ b/client/emv/emvjson.h @@ -10,6 +10,8 @@ #ifndef EMVJSON_H__ #define EMVJSON_H__ +#include "common.h" + #include #include "tlv.h" diff --git a/client/emv/test/crypto_test.c b/client/emv/test/crypto_test.c index dcac3f845..cdf22a995 100644 --- a/client/emv/test/crypto_test.c +++ b/client/emv/test/crypto_test.c @@ -17,10 +17,11 @@ #include #endif +#include "commonutil.h" // ARRAYLEN + #include "../crypto.h" #include "../dump.h" #include "util_posix.h" -#include "commonutil.h" #include #include diff --git a/client/emv/tlv.c b/client/emv/tlv.c index f3961c7a6..6e840f928 100644 --- a/client/emv/tlv.c +++ b/client/emv/tlv.c @@ -22,8 +22,6 @@ #include "tlv.h" #include -#include -#include #include #define TLV_TAG_CLASS_MASK 0xc0 diff --git a/client/emv/tlv.h b/client/emv/tlv.h index 053b31362..06a836876 100644 --- a/client/emv/tlv.h +++ b/client/emv/tlv.h @@ -18,9 +18,7 @@ #ifndef TLV_H #define TLV_H -#include -#include -#include +#include "common.h" typedef uint32_t tlv_tag_t; diff --git a/client/fido/additional_ca.c b/client/fido/additional_ca.c index 550847e10..21d9d80f6 100644 --- a/client/fido/additional_ca.c +++ b/client/fido/additional_ca.c @@ -10,7 +10,6 @@ // #include "additional_ca.h" -#include "mbedtls/certs.h" #define GLOBALSIGN_CA \ "-----BEGIN CERTIFICATE-----\r\n" \ diff --git a/client/fido/additional_ca.h b/client/fido/additional_ca.h index d0f642e46..689e5f059 100644 --- a/client/fido/additional_ca.h +++ b/client/fido/additional_ca.h @@ -12,7 +12,7 @@ #ifndef __ADDITIONAL_CA_H__ #define __ADDITIONAL_CA_H__ -#include +#include "common.h" // Concatenation of all CA certificates in PEM format if available extern const char additional_ca_pem[]; diff --git a/client/fido/cbortools.c b/client/fido/cbortools.c index 7cb7fc456..72cccf429 100644 --- a/client/fido/cbortools.c +++ b/client/fido/cbortools.c @@ -11,7 +11,9 @@ // #include "cbortools.h" -#include + +#include + #include "emv/emvjson.h" #include "util.h" #include "fidocore.h" diff --git a/client/fido/cbortools.h b/client/fido/cbortools.h index 99b3536c1..96c39ca3b 100644 --- a/client/fido/cbortools.h +++ b/client/fido/cbortools.h @@ -13,8 +13,7 @@ #ifndef __CBORTOOLS_H__ #define __CBORTOOLS_H__ -#include -#include +#include "common.h" #include #include diff --git a/client/fido/cose.c b/client/fido/cose.c index c62d6cfb3..f6f20852b 100644 --- a/client/fido/cose.c +++ b/client/fido/cose.c @@ -11,8 +11,11 @@ // #include "cose.h" -#include + #include "cbortools.h" +#include "commonutil.h" // ARRAYLEN +#include "ui.h" // Print... +#include "util.h" static const char COSEEmptyStr[] = ""; diff --git a/client/fido/cose.h b/client/fido/cose.h index e62054646..b78f27421 100644 --- a/client/fido/cose.h +++ b/client/fido/cose.h @@ -13,10 +13,7 @@ #ifndef __COSE_H__ #define __COSE_H__ -#include -#include -#include -#include "util.h" +#include "common.h" const char *GetCOSEAlgName(int id); const char *GetCOSEAlgDescription(int id); diff --git a/client/fido/fidocore.c b/client/fido/fidocore.c index 1611748d8..8093f45c8 100644 --- a/client/fido/fidocore.c +++ b/client/fido/fidocore.c @@ -11,17 +11,20 @@ // #include "fidocore.h" + +#include "commonutil.h" // ARRAYLEN + #include "emv/emvcore.h" #include "emv/emvjson.h" -#include #include "cbortools.h" -#include -#include -#include +#include "mbedtls/x509_crt.h" #include "crypto/asn1utils.h" #include "crypto/libpcrypto.h" -#include "fido/additional_ca.h" -#include "fido/cose.h" +#include "additional_ca.h" +#include "cose.h" +#include "emv/dump.h" +#include "ui.h" +#include "util.h" typedef struct { uint8_t ErrorCode; diff --git a/client/fido/fidocore.h b/client/fido/fidocore.h index d54dc5b88..56c563120 100644 --- a/client/fido/fidocore.h +++ b/client/fido/fidocore.h @@ -12,10 +12,10 @@ #ifndef __FIDOCORE_H__ #define __FIDOCORE_H__ -#include -#include +#include "common.h" + #include -#include "cmdhf14a.h" +#include "emv/apduinfo.h" // sAPDU typedef enum { fido2CmdMakeCredential = 0x01, diff --git a/client/flash.c b/client/flash.c index 732d0ef02..ca2f012bb 100644 --- a/client/flash.c +++ b/client/flash.c @@ -10,6 +10,17 @@ #include "flash.h" +#include +#include +#include + +#include "ui.h" +#include "elf.h" +#include "proxendian.h" +#include "at91sam7s512.h" +#include "util_posix.h" +#include "comms.h" + #define FLASH_START 0x100000 #define BOOTLOADER_SIZE 0x2000 diff --git a/client/flash.h b/client/flash.h index 4f05029dc..eca4d9ccc 100644 --- a/client/flash.h +++ b/client/flash.h @@ -9,20 +9,7 @@ #ifndef __FLASH_H__ #define __FLASH_H__ -#include -#include -#include -#include -#include - -#include "proxmark3.h" -#include "elf.h" -#include "proxendian.h" -#include "pm3_cmd.h" -#include "at91sam7s512.h" -#include "util_posix.h" -#include "util.h" -#include "comms.h" +#include "common.h" typedef struct { void *data; diff --git a/client/flasher.c b/client/flasher.c index 97e3d7a1c..931976997 100644 --- a/client/flasher.c +++ b/client/flasher.c @@ -6,18 +6,11 @@ // Flasher frontend tool //----------------------------------------------------------------------------- -#include -#include #include -#include -#include #include -#include "util_posix.h" -#include "proxmark3.h" -#include "util.h" +#include "usart_defs.h" #include "flash.h" #include "comms.h" -#include "pm3_cmd.h" #include "ui.h" #define MAX_FILES 4 diff --git a/client/fpga_compress.c b/client/fpga_compress.c index a030afe81..dfe62d0c8 100644 --- a/client/fpga_compress.c +++ b/client/fpga_compress.c @@ -15,14 +15,10 @@ #include #include #include -#include -#include #include #include "fpga.h" #include "zlib.h" -#define MAX(a,b) ((a)>(b)?(a):(b)) - // zlib configuration #define COMPRESS_LEVEL 9 // use best possible compression #define COMPRESS_WINDOW_BITS 15 // default = max = 15 for a window of 2^15 = 32KBytes diff --git a/client/graph.c b/client/graph.c index 4af3261d2..fc0ceab2d 100644 --- a/client/graph.c +++ b/client/graph.c @@ -9,6 +9,12 @@ //----------------------------------------------------------------------------- #include "graph.h" +#include +#include "ui.h" +#include "util.h" //param_get32ex +#include "lfdemod.h" +#include "cmddata.h" //for g_debugmode + int GraphBuffer[MAX_GRAPH_TRACE_LEN]; size_t GraphTraceLen; int s_Buff[MAX_GRAPH_TRACE_LEN]; diff --git a/client/graph.h b/client/graph.h index fca93a889..01b20c7e2 100644 --- a/client/graph.h +++ b/client/graph.h @@ -10,13 +10,8 @@ #ifndef GRAPH_H__ #define GRAPH_H__ -#include -#include -#include -#include -#include "ui.h" -#include "lfdemod.h" -#include "cmddata.h" //for g_debugmode + +#include "common.h" void AppendGraph(bool redraw, uint16_t clock, int bit); size_t ClearGraph(bool redraw); diff --git a/client/hardnested/hardnested_bf_core.c b/client/hardnested/hardnested_bf_core.c index da9e19db4..adc203f61 100644 --- a/client/hardnested/hardnested_bf_core.c +++ b/client/hardnested/hardnested_bf_core.c @@ -60,6 +60,7 @@ THE SOFTWARE. #include "crapto1/crapto1.h" #include "parity.h" #include "util.h" +#include "common.h" // bitslice type // while AVX supports 256 bit vector floating point operations, we need integer operations for boolean logic diff --git a/client/hardnested/hardnested_bruteforce.c b/client/hardnested/hardnested_bruteforce.c index 9ecec900a..5f93d4811 100644 --- a/client/hardnested/hardnested_bruteforce.c +++ b/client/hardnested/hardnested_bruteforce.c @@ -55,6 +55,8 @@ THE SOFTWARE. #include #include #include + +#include "common.h" #include "proxmark3.h" #include "cmdhfmfhard.h" #include "hardnested_bf_core.h" diff --git a/liblua/Makefile b/client/liblua/Makefile similarity index 100% rename from liblua/Makefile rename to client/liblua/Makefile diff --git a/liblua/lapi.c b/client/liblua/lapi.c similarity index 100% rename from liblua/lapi.c rename to client/liblua/lapi.c diff --git a/liblua/lapi.h b/client/liblua/lapi.h similarity index 100% rename from liblua/lapi.h rename to client/liblua/lapi.h diff --git a/liblua/lauxlib.c b/client/liblua/lauxlib.c similarity index 100% rename from liblua/lauxlib.c rename to client/liblua/lauxlib.c diff --git a/liblua/lauxlib.h b/client/liblua/lauxlib.h similarity index 100% rename from liblua/lauxlib.h rename to client/liblua/lauxlib.h diff --git a/liblua/lbaselib.c b/client/liblua/lbaselib.c similarity index 100% rename from liblua/lbaselib.c rename to client/liblua/lbaselib.c diff --git a/liblua/lbitlib.c b/client/liblua/lbitlib.c similarity index 100% rename from liblua/lbitlib.c rename to client/liblua/lbitlib.c diff --git a/liblua/lcode.c b/client/liblua/lcode.c similarity index 100% rename from liblua/lcode.c rename to client/liblua/lcode.c diff --git a/liblua/lcode.h b/client/liblua/lcode.h similarity index 100% rename from liblua/lcode.h rename to client/liblua/lcode.h diff --git a/liblua/lcorolib.c b/client/liblua/lcorolib.c similarity index 100% rename from liblua/lcorolib.c rename to client/liblua/lcorolib.c diff --git a/liblua/lctype.c b/client/liblua/lctype.c similarity index 100% rename from liblua/lctype.c rename to client/liblua/lctype.c diff --git a/liblua/lctype.h b/client/liblua/lctype.h similarity index 100% rename from liblua/lctype.h rename to client/liblua/lctype.h diff --git a/liblua/ldblib.c b/client/liblua/ldblib.c similarity index 100% rename from liblua/ldblib.c rename to client/liblua/ldblib.c diff --git a/liblua/ldebug.c b/client/liblua/ldebug.c similarity index 100% rename from liblua/ldebug.c rename to client/liblua/ldebug.c diff --git a/liblua/ldebug.h b/client/liblua/ldebug.h similarity index 100% rename from liblua/ldebug.h rename to client/liblua/ldebug.h diff --git a/liblua/ldo.c b/client/liblua/ldo.c similarity index 100% rename from liblua/ldo.c rename to client/liblua/ldo.c diff --git a/liblua/ldo.h b/client/liblua/ldo.h similarity index 100% rename from liblua/ldo.h rename to client/liblua/ldo.h diff --git a/liblua/ldump.c b/client/liblua/ldump.c similarity index 100% rename from liblua/ldump.c rename to client/liblua/ldump.c diff --git a/liblua/lfunc.c b/client/liblua/lfunc.c similarity index 100% rename from liblua/lfunc.c rename to client/liblua/lfunc.c diff --git a/liblua/lfunc.h b/client/liblua/lfunc.h similarity index 100% rename from liblua/lfunc.h rename to client/liblua/lfunc.h diff --git a/liblua/lgc.c b/client/liblua/lgc.c similarity index 100% rename from liblua/lgc.c rename to client/liblua/lgc.c diff --git a/liblua/lgc.h b/client/liblua/lgc.h similarity index 100% rename from liblua/lgc.h rename to client/liblua/lgc.h diff --git a/liblua/linit.c b/client/liblua/linit.c similarity index 100% rename from liblua/linit.c rename to client/liblua/linit.c diff --git a/liblua/liolib.c b/client/liblua/liolib.c similarity index 100% rename from liblua/liolib.c rename to client/liblua/liolib.c diff --git a/liblua/llex.c b/client/liblua/llex.c similarity index 100% rename from liblua/llex.c rename to client/liblua/llex.c diff --git a/liblua/llex.h b/client/liblua/llex.h similarity index 100% rename from liblua/llex.h rename to client/liblua/llex.h diff --git a/liblua/llimits.h b/client/liblua/llimits.h similarity index 100% rename from liblua/llimits.h rename to client/liblua/llimits.h diff --git a/liblua/lmathlib.c b/client/liblua/lmathlib.c similarity index 100% rename from liblua/lmathlib.c rename to client/liblua/lmathlib.c diff --git a/liblua/lmem.c b/client/liblua/lmem.c similarity index 100% rename from liblua/lmem.c rename to client/liblua/lmem.c diff --git a/liblua/lmem.h b/client/liblua/lmem.h similarity index 100% rename from liblua/lmem.h rename to client/liblua/lmem.h diff --git a/liblua/loadlib.c b/client/liblua/loadlib.c similarity index 100% rename from liblua/loadlib.c rename to client/liblua/loadlib.c diff --git a/liblua/lobject.c b/client/liblua/lobject.c similarity index 100% rename from liblua/lobject.c rename to client/liblua/lobject.c diff --git a/liblua/lobject.h b/client/liblua/lobject.h similarity index 100% rename from liblua/lobject.h rename to client/liblua/lobject.h diff --git a/liblua/lopcodes.c b/client/liblua/lopcodes.c similarity index 100% rename from liblua/lopcodes.c rename to client/liblua/lopcodes.c diff --git a/liblua/lopcodes.h b/client/liblua/lopcodes.h similarity index 100% rename from liblua/lopcodes.h rename to client/liblua/lopcodes.h diff --git a/liblua/loslib.c b/client/liblua/loslib.c similarity index 100% rename from liblua/loslib.c rename to client/liblua/loslib.c diff --git a/liblua/lparser.c b/client/liblua/lparser.c similarity index 100% rename from liblua/lparser.c rename to client/liblua/lparser.c diff --git a/liblua/lparser.h b/client/liblua/lparser.h similarity index 100% rename from liblua/lparser.h rename to client/liblua/lparser.h diff --git a/liblua/lstate.c b/client/liblua/lstate.c similarity index 100% rename from liblua/lstate.c rename to client/liblua/lstate.c diff --git a/liblua/lstate.h b/client/liblua/lstate.h similarity index 100% rename from liblua/lstate.h rename to client/liblua/lstate.h diff --git a/liblua/lstring.c b/client/liblua/lstring.c similarity index 100% rename from liblua/lstring.c rename to client/liblua/lstring.c diff --git a/liblua/lstring.h b/client/liblua/lstring.h similarity index 100% rename from liblua/lstring.h rename to client/liblua/lstring.h diff --git a/liblua/lstrlib.c b/client/liblua/lstrlib.c similarity index 100% rename from liblua/lstrlib.c rename to client/liblua/lstrlib.c diff --git a/liblua/ltable.c b/client/liblua/ltable.c similarity index 100% rename from liblua/ltable.c rename to client/liblua/ltable.c diff --git a/liblua/ltable.h b/client/liblua/ltable.h similarity index 100% rename from liblua/ltable.h rename to client/liblua/ltable.h diff --git a/liblua/ltablib.c b/client/liblua/ltablib.c similarity index 100% rename from liblua/ltablib.c rename to client/liblua/ltablib.c diff --git a/liblua/ltm.c b/client/liblua/ltm.c similarity index 100% rename from liblua/ltm.c rename to client/liblua/ltm.c diff --git a/liblua/ltm.h b/client/liblua/ltm.h similarity index 100% rename from liblua/ltm.h rename to client/liblua/ltm.h diff --git a/liblua/lua.c b/client/liblua/lua.c similarity index 100% rename from liblua/lua.c rename to client/liblua/lua.c diff --git a/liblua/lua.h b/client/liblua/lua.h similarity index 100% rename from liblua/lua.h rename to client/liblua/lua.h diff --git a/liblua/lua.hpp b/client/liblua/lua.hpp similarity index 100% rename from liblua/lua.hpp rename to client/liblua/lua.hpp diff --git a/liblua/luac.c b/client/liblua/luac.c similarity index 100% rename from liblua/luac.c rename to client/liblua/luac.c diff --git a/liblua/luaconf.h b/client/liblua/luaconf.h similarity index 100% rename from liblua/luaconf.h rename to client/liblua/luaconf.h diff --git a/liblua/lualib.h b/client/liblua/lualib.h similarity index 100% rename from liblua/lualib.h rename to client/liblua/lualib.h diff --git a/liblua/lundump.c b/client/liblua/lundump.c similarity index 100% rename from liblua/lundump.c rename to client/liblua/lundump.c diff --git a/liblua/lundump.h b/client/liblua/lundump.h similarity index 100% rename from liblua/lundump.h rename to client/liblua/lundump.h diff --git a/liblua/lvm.c b/client/liblua/lvm.c similarity index 100% rename from liblua/lvm.c rename to client/liblua/lvm.c diff --git a/liblua/lvm.h b/client/liblua/lvm.h similarity index 100% rename from liblua/lvm.h rename to client/liblua/lvm.h diff --git a/liblua/lzio.c b/client/liblua/lzio.c similarity index 100% rename from liblua/lzio.c rename to client/liblua/lzio.c diff --git a/liblua/lzio.h b/client/liblua/lzio.h similarity index 100% rename from liblua/lzio.h rename to client/liblua/lzio.h diff --git a/client/loclass/cipher.c b/client/loclass/cipher.c index fe676e83d..931f0c845 100644 --- a/client/loclass/cipher.c +++ b/client/loclass/cipher.c @@ -250,7 +250,7 @@ void doMAC_N(uint8_t *address_data_p, uint8_t address_data_size, uint8_t *div_ke #ifndef ON_DEVICE int testMAC() { - PrintAndLogDevice(SUCCESS, "Testing MAC calculation..."); + PrintAndLogEx(SUCCESS, "Testing MAC calculation..."); //From the "dismantling.IClass" paper: uint8_t cc_nr[] = {0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0}; @@ -262,9 +262,9 @@ int testMAC() { doMAC(cc_nr, div_key, calculated_mac); if (memcmp(calculated_mac, correct_MAC, 4) == 0) { - PrintAndLogDevice(SUCCESS, "MAC calculation OK!"); + PrintAndLogEx(SUCCESS, "MAC calculation OK!"); } else { - PrintAndLogDevice(FAILED, "FAILED: MAC calculation failed:"); + PrintAndLogEx(FAILED, "FAILED: MAC calculation failed:"); printarr(" Calculated_MAC", calculated_mac, 4); printarr(" Correct_MAC ", correct_MAC, 4); return 1; diff --git a/client/loclass/cipherutils.c b/client/loclass/cipherutils.c index b6bea6186..b11f6883a 100644 --- a/client/loclass/cipherutils.c +++ b/client/loclass/cipherutils.c @@ -34,12 +34,15 @@ * * ****************************************************************************/ +#include "cipherutils.h" #include #include #include + +#include "commonutil.h" // ARRAYLEN + #include "fileutils.h" -#include "cipherutils.h" /** * * @brief Return and remove the first bit (x0) in the stream : @@ -152,7 +155,7 @@ void printarr(const char *name, uint8_t *arr, int len) { cx += snprintf(output + cx, outsize - cx, "0x%02x,", *(arr + i)); //5 bytes per byte } snprintf(output + cx, outsize - cx, "};"); - PrintAndLogDevice(NORMAL, output); + PrintAndLogEx(NORMAL, output); free(output); } @@ -165,7 +168,7 @@ void printvar(const char *name, uint8_t *arr, int len) { cx += snprintf(output + cx, outsize - cx, "%02x", *(arr + i)); //2 bytes per byte } - PrintAndLogDevice(NORMAL, output); + PrintAndLogEx(NORMAL, output); free(output); } @@ -179,7 +182,7 @@ void printarr_human_readable(const char *title, uint8_t *arr, int len) { cx += snprintf(output + cx, outsize - cx, "\n%02x| ", i); cx += snprintf(output + cx, outsize - cx, "%02x ", *(arr + i)); } - PrintAndLogDevice(NORMAL, output); + PrintAndLogEx(NORMAL, output); free(output); } @@ -201,12 +204,12 @@ static int testBitStream() { } if (memcmp(input, output, sizeof(input)) == 0) { - PrintAndLogDevice(SUCCESS, " Bitstream test 1 ok"); + PrintAndLogEx(SUCCESS, " Bitstream test 1 ok"); } else { - PrintAndLogDevice(FAILED, " Bitstream test 1 failed"); + PrintAndLogEx(FAILED, " Bitstream test 1 failed"); uint8_t i; for (i = 0 ; i < ARRAYLEN(input) ; i++) { - PrintAndLogDevice(NORMAL, " IN %02x, OUT %02x", input[i], output[i]); + PrintAndLogEx(NORMAL, " IN %02x, OUT %02x", input[i], output[i]); } return 1; } @@ -231,12 +234,12 @@ static int testReversedBitstream() { } if (memcmp(input, output, sizeof(input)) == 0) { - PrintAndLogDevice(SUCCESS, " Bitstream test 2 ok"); + PrintAndLogEx(SUCCESS, " Bitstream test 2 ok"); } else { - PrintAndLogDevice(FAILED, " Bitstream test 2 failed"); + PrintAndLogEx(FAILED, " Bitstream test 2 failed"); uint8_t i; for (i = 0 ; i < ARRAYLEN(input) ; i++) { - PrintAndLogDevice(NORMAL, " IN %02x, MIDDLE: %02x, OUT %02x", input[i], reverse[i], output[i]); + PrintAndLogEx(NORMAL, " IN %02x, MIDDLE: %02x, OUT %02x", input[i], reverse[i], output[i]); } return 1; } @@ -245,7 +248,7 @@ static int testReversedBitstream() { int testCipherUtils(void) { - PrintAndLogDevice(INFO, "Testing some internals..."); + PrintAndLogEx(INFO, "Testing some internals..."); int retval = 0; retval |= testBitStream(); retval |= testReversedBitstream(); diff --git a/client/loclass/elite_crack.c b/client/loclass/elite_crack.c index 5b019d8e0..a4296f476 100644 --- a/client/loclass/elite_crack.c +++ b/client/loclass/elite_crack.c @@ -221,7 +221,7 @@ void hash2(uint8_t *key64, uint8_t *outp_keytable) { // Once again, key is on iclass-format desencrypt_iclass(key64, key64_negated, z[0]); -// PrintAndLogDevice(NORMAL, "\n"); PrintAndLogDevice(NORMAL, "High security custom key (Kcus):"); +// PrintAndLogEx(NORMAL, "\n"); PrintAndLogEx(NORMAL, "High security custom key (Kcus):"); // printvar("z0 ", z[0],8); uint8_t y[8][8] = {{0}, {0}}; @@ -325,10 +325,10 @@ int bruteforceItem(dumpdata item, uint16_t keytable[]) { keytable[key_index[i]] |= BEING_CRACKED; if (numbytes_to_recover > 3) { - PrintAndLogDevice(FAILED, "The CSN requires > 3 byte bruteforce, not supported"); + PrintAndLogEx(FAILED, "The CSN requires > 3 byte bruteforce, not supported"); printvar("[-] CSN", item.csn, 8); printvar("[-] HASH1", key_index, 8); - PrintAndLogDevice(NORMAL, ""); + PrintAndLogEx(NORMAL, ""); //Before we exit, reset the 'BEING_CRACKED' to zero keytable[bytes_to_recover[0]] &= ~BEING_CRACKED; keytable[bytes_to_recover[1]] &= ~BEING_CRACKED; @@ -351,9 +351,9 @@ int bruteforceItem(dumpdata item, uint16_t keytable[]) { */ uint32_t endmask = 1 << 8 * numbytes_to_recover; - PrintAndLogDevice(NORMAL, "----------------------------"); + PrintAndLogEx(NORMAL, "----------------------------"); for (i = 0 ; i < numbytes_to_recover && numbytes_to_recover > 1; i++) - PrintAndLogDevice(INFO, "Bruteforcing byte %d", bytes_to_recover[i]); + PrintAndLogEx(INFO, "Bruteforcing byte %d", bytes_to_recover[i]); while (!found && !(brute & endmask)) { @@ -384,7 +384,7 @@ int bruteforceItem(dumpdata item, uint16_t keytable[]) { if (memcmp(calculated_MAC, item.mac, 4) == 0) { printf("\r\n"); for (i = 0 ; i < numbytes_to_recover; i++) { - PrintAndLogDevice(INFO, "%d: 0x%02x", bytes_to_recover[i], 0xFF & keytable[bytes_to_recover[i]]); + PrintAndLogEx(INFO, "%d: 0x%02x", bytes_to_recover[i], 0xFF & keytable[bytes_to_recover[i]]); } found = true; break; @@ -400,8 +400,8 @@ int bruteforceItem(dumpdata item, uint16_t keytable[]) { } if (!found) { - PrintAndLogDevice(NORMAL, "\n"); - PrintAndLogDevice(WARNING, "Failed to recover %d bytes using the following CSN", numbytes_to_recover); + PrintAndLogEx(NORMAL, "\n"); + PrintAndLogEx(WARNING, "Failed to recover %d bytes using the following CSN", numbytes_to_recover); printvar("[!] CSN", item.csn, 8); errors++; @@ -411,7 +411,7 @@ int bruteforceItem(dumpdata item, uint16_t keytable[]) { keytable[bytes_to_recover[i]] |= CRACK_FAILED; } } else { - //PrintAndLogDevice(SUCCESS, "DES calcs: %u", brute); + //PrintAndLogEx(SUCCESS, "DES calcs: %u", brute); for (i = 0; i < numbytes_to_recover; i++) { keytable[bytes_to_recover[i]] &= 0xFF; keytable[bytes_to_recover[i]] |= CRACKED; @@ -466,8 +466,8 @@ int calculateMasterKey(uint8_t first16bytes[], uint64_t master_key[]) { mbedtls_des_setkey_enc(&ctx_e, key64_stdformat); mbedtls_des_crypt_ecb(&ctx_e, key64_negated, result); - PrintAndLogDevice(NORMAL, "\n"); - PrintAndLogDevice(SUCCESS, "-- High security custom key (Kcus) --"); + PrintAndLogEx(NORMAL, "\n"); + PrintAndLogEx(SUCCESS, "-- High security custom key (Kcus) --"); printvar("[+] Standard format ", key64_stdformat, 8); printvar("[+] iClass format ", key64, 8); @@ -475,11 +475,11 @@ int calculateMasterKey(uint8_t first16bytes[], uint64_t master_key[]) { memcpy(master_key, key64, 8); if (memcmp(z_0, result, 4) != 0) { - PrintAndLogDevice(WARNING, "Failed to verify calculated master key (k_cus)! Something is wrong."); + PrintAndLogEx(WARNING, "Failed to verify calculated master key (k_cus)! Something is wrong."); return 1; } else { - PrintAndLogDevice(NORMAL, "\n"); - PrintAndLogDevice(SUCCESS, "Key verified ok!\n"); + PrintAndLogEx(NORMAL, "\n"); + PrintAndLogEx(SUCCESS, "Key verified ok!\n"); } return 0; } @@ -505,7 +505,7 @@ int bruteforceDump(uint8_t dump[], size_t dumpsize, uint16_t keytable[]) { } free(attack); t1 = msclock() - t1; - PrintAndLogDevice(SUCCESS, "time: %" PRIu64 " seconds", t1 / 1000); + PrintAndLogEx(SUCCESS, "time: %" PRIu64 " seconds", t1 / 1000); // Pick out the first 16 bytes of the keytable. // The keytable is now in 16-bit ints, where the upper 8 bits @@ -517,7 +517,7 @@ int bruteforceDump(uint8_t dump[], size_t dumpsize, uint16_t keytable[]) { first16bytes[i] = keytable[i] & 0xFF; if (!(keytable[i] & CRACKED)) - PrintAndLogDevice(WARNING, "Warning: we are missing byte %d, custom key calculation will fail...", i); + PrintAndLogEx(WARNING, "Warning: we are missing byte %d, custom key calculation will fail...", i); } errors += calculateMasterKey(first16bytes, NULL); return errors; @@ -532,7 +532,7 @@ int bruteforceDump(uint8_t dump[], size_t dumpsize, uint16_t keytable[]) { int bruteforceFile(const char *filename, uint16_t keytable[]) { FILE *f = fopen(filename, "rb"); if (!f) { - PrintAndLogDevice(WARNING, "Failed to read from file '%s'", filename); + PrintAndLogEx(WARNING, "Failed to read from file '%s'", filename); return 1; } @@ -541,14 +541,14 @@ int bruteforceFile(const char *filename, uint16_t keytable[]) { fseek(f, 0, SEEK_SET); if (fsize <= 0) { - PrintAndLogDevice(ERR, "Error, when getting filesize"); + PrintAndLogEx(ERR, "Error, when getting filesize"); fclose(f); return 1; } uint8_t *dump = calloc(fsize, sizeof(uint8_t)); if (!dump) { - PrintAndLogDevice(WARNING, "Failed to allocate memory"); + PrintAndLogEx(WARNING, "Failed to allocate memory"); fclose(f); return 2; } @@ -557,7 +557,7 @@ int bruteforceFile(const char *filename, uint16_t keytable[]) { fclose(f); if (bytes_read < fsize) { - PrintAndLogDevice(WARNING, "Warning: could only read %d bytes (should be %d)", bytes_read, fsize); + PrintAndLogEx(WARNING, "Warning: could only read %d bytes (should be %d)", bytes_read, fsize); } uint8_t res = bruteforceDump(dump, fsize, keytable); @@ -585,7 +585,7 @@ static int _testBruteforce() { int errors = 0; if (true) { // First test - PrintAndLogDevice(INFO, "Testing crack from dumpfile..."); + PrintAndLogEx(INFO, "Testing crack from dumpfile..."); /** Expected values for the dumpfile: @@ -612,7 +612,7 @@ static int _testBruteforce() { } else if (fileExists("client/loclass/iclass_dump.bin")) { errors |= bruteforceFile("client/loclass/iclass_dump.bin", keytable); } else { - PrintAndLogDevice(ERR, "Error: The file iclass_dump.bin was not found!"); + PrintAndLogEx(ERR, "Error: The file iclass_dump.bin was not found!"); } } return errors; @@ -627,20 +627,20 @@ static int _test_iclass_key_permutation() { permutekey_rev(testcase_output, testcase_output_rev); if (memcmp(testcase_output, testcase_output_correct, 8) != 0) { - PrintAndLogDevice(ERR, "Error with iclass key permute!"); + PrintAndLogEx(ERR, "Error with iclass key permute!"); printarr("testcase_output", testcase_output, 8); printarr("testcase_output_correct", testcase_output_correct, 8); return 1; } if (memcmp(testcase, testcase_output_rev, 8) != 0) { - PrintAndLogDevice(ERR, "Error with reverse iclass key permute"); + PrintAndLogEx(ERR, "Error with reverse iclass key permute"); printarr("testcase", testcase, 8); printarr("testcase_output_rev", testcase_output_rev, 8); return 1; } - PrintAndLogDevice(SUCCESS, "Iclass key permutation OK!"); + PrintAndLogEx(SUCCESS, "Iclass key permutation OK!"); return 0; } @@ -651,7 +651,7 @@ static int _testHash1() { hash1(csn, k); if (memcmp(k, expected, 8) != 0) { - PrintAndLogDevice(ERR, "Error with hash1!"); + PrintAndLogEx(ERR, "Error with hash1!"); printarr("calculated", k, 8); printarr("expected", expected, 8); return 1; @@ -660,8 +660,8 @@ static int _testHash1() { } int testElite() { - PrintAndLogDevice(INFO, "Testing iClass Elite functinality..."); - PrintAndLogDevice(INFO, "Testing hash2"); + PrintAndLogEx(INFO, "Testing iClass Elite functinality..."); + PrintAndLogEx(INFO, "Testing hash2"); uint8_t k_cus[8] = {0x5B, 0x7C, 0x62, 0xC4, 0x91, 0xC1, 0x1B, 0x39}; /** @@ -683,13 +683,13 @@ int testElite() { hash2(k_cus, keytable); printarr_human_readable("Hash2", keytable, 128); if (keytable[3] == 0xA1 && keytable[0x30] == 0xA3 && keytable[0x6F] == 0x95) { - PrintAndLogDevice(SUCCESS, "Hash2 looks fine..."); + PrintAndLogEx(SUCCESS, "Hash2 looks fine..."); } int errors = 0 ; - PrintAndLogDevice(INFO, "Testing hash1..."); + PrintAndLogEx(INFO, "Testing hash1..."); errors += _testHash1(); - PrintAndLogDevice(INFO, "Testing key diversification ..."); + PrintAndLogEx(INFO, "Testing key diversification ..."); errors += _test_iclass_key_permutation(); errors += _testBruteforce(); return errors; diff --git a/client/loclass/fileutils.c b/client/loclass/fileutils.c index cb16a7fa3..b89925334 100644 --- a/client/loclass/fileutils.c +++ b/client/loclass/fileutils.c @@ -36,6 +36,13 @@ ****************************************************************************/ #include "fileutils.h" +#include + +#include "pm3_cmd.h" +#include "commonutil.h" +#include "util.h" + + #ifndef ON_DEVICE #define PATH_MAX_LENGTH 100 @@ -100,14 +107,14 @@ int saveFile(const char *preferredName, const char *suffix, const void *data, si /*Opening file for writing in binary mode*/ FILE *f = fopen(fileName, "wb"); if (!f) { - PrintAndLogDevice(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", fileName); + PrintAndLogEx(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", fileName); free(fileName); return PM3_EFILE; } fwrite(data, 1, datalen, f); fflush(f); fclose(f); - PrintAndLogDevice(SUCCESS, "saved %u bytes to binary file " _YELLOW_("%s"), datalen, fileName); + PrintAndLogEx(SUCCESS, "saved %u bytes to binary file " _YELLOW_("%s"), datalen, fileName); free(fileName); return PM3_SUCCESS; } @@ -127,7 +134,7 @@ int saveFileEML(const char *preferredName, uint8_t *data, size_t datalen, size_t /*Opening file for writing in text mode*/ FILE *f = fopen(fileName, "w+"); if (!f) { - PrintAndLogDevice(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", fileName); + PrintAndLogEx(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", fileName); retval = PM3_EFILE; goto out; } @@ -150,7 +157,7 @@ int saveFileEML(const char *preferredName, uint8_t *data, size_t datalen, size_t } fflush(f); fclose(f); - PrintAndLogDevice(SUCCESS, "saved %d blocks to text file " _YELLOW_("%s"), blocks, fileName); + PrintAndLogEx(SUCCESS, "saved %d blocks to text file " _YELLOW_("%s"), blocks, fileName); out: free(fileName); @@ -273,12 +280,12 @@ int saveFileJSON(const char *preferredName, JSONFileType ftype, uint8_t *data, s int res = json_dump_file(root, fileName, JSON_INDENT(2)); if (res) { - PrintAndLogDevice(FAILED, "error: can't save the file: " _YELLOW_("%s"), fileName); + PrintAndLogEx(FAILED, "error: can't save the file: " _YELLOW_("%s"), fileName); json_decref(root); retval = 200; goto out; } - PrintAndLogDevice(SUCCESS, "saved to json file " _YELLOW_("%s"), fileName); + PrintAndLogEx(SUCCESS, "saved to json file " _YELLOW_("%s"), fileName); json_decref(root); out: @@ -296,7 +303,7 @@ int loadFile(const char *preferredName, const char *suffix, void *data, size_t m FILE *f = fopen(fileName, "rb"); if (!f) { - PrintAndLogDevice(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", fileName); + PrintAndLogEx(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", fileName); free(fileName); return PM3_EFILE; } @@ -307,14 +314,14 @@ int loadFile(const char *preferredName, const char *suffix, void *data, size_t m fseek(f, 0, SEEK_SET); if (fsize <= 0) { - PrintAndLogDevice(FAILED, "error, when getting filesize"); + PrintAndLogEx(FAILED, "error, when getting filesize"); retval = 1; goto out; } uint8_t *dump = calloc(fsize, sizeof(uint8_t)); if (!dump) { - PrintAndLogDevice(FAILED, "error, cannot allocate memory"); + PrintAndLogEx(FAILED, "error, cannot allocate memory"); retval = 2; goto out; } @@ -322,21 +329,21 @@ int loadFile(const char *preferredName, const char *suffix, void *data, size_t m size_t bytes_read = fread(dump, 1, fsize, f); if (bytes_read != fsize) { - PrintAndLogDevice(FAILED, "error, bytes read mismatch file size"); + PrintAndLogEx(FAILED, "error, bytes read mismatch file size"); free(dump); retval = 3; goto out; } if (bytes_read > maxdatalen) { - PrintAndLogDevice(WARNING, "Warning, bytes read exceed calling array limit. Max bytes is %d bytes", maxdatalen); + PrintAndLogEx(WARNING, "Warning, bytes read exceed calling array limit. Max bytes is %d bytes", maxdatalen); bytes_read = maxdatalen; } memcpy((data), dump, bytes_read); free(dump); - PrintAndLogDevice(SUCCESS, "loaded %d bytes from binary file " _YELLOW_("%s"), bytes_read, fileName); + PrintAndLogEx(SUCCESS, "loaded %d bytes from binary file " _YELLOW_("%s"), bytes_read, fileName); *datalen = bytes_read; @@ -358,7 +365,7 @@ int loadFileEML(const char *preferredName, void *data, size_t *datalen) { FILE *f = fopen(fileName, "r"); if (!f) { - PrintAndLogDevice(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", fileName); + PrintAndLogEx(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", fileName); retval = PM3_EFILE; goto out; } @@ -391,7 +398,7 @@ int loadFileEML(const char *preferredName, void *data, size_t *datalen) { } } fclose(f); - PrintAndLogDevice(SUCCESS, "loaded %d bytes from text file " _YELLOW_("%s"), counter, fileName); + PrintAndLogEx(SUCCESS, "loaded %d bytes from text file " _YELLOW_("%s"), counter, fileName); if (datalen) *datalen = counter; @@ -532,7 +539,7 @@ int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, u FILE *f = fopen(fileName, "r"); if (!f) { - PrintAndLogDevice(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", fileName); + PrintAndLogEx(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", fileName); retval = PM3_EFILE; goto out; } @@ -564,7 +571,7 @@ int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, u counter += (keylen >> 1); } fclose(f); - PrintAndLogDevice(SUCCESS, "loaded " _GREEN_("%2d") "keys from dictionary file " _YELLOW_("%s"), *keycnt, fileName); + PrintAndLogEx(SUCCESS, "loaded " _GREEN_("%2d") "keys from dictionary file " _YELLOW_("%s"), *keycnt, fileName); if (datalen) *datalen = counter; @@ -601,7 +608,7 @@ int convertOldMfuDump(uint8_t **dump, size_t *dumplen) { *dumplen = new_dump_len; free(*dump); *dump = (uint8_t *) mfu_dump; - PrintAndLogDevice(SUCCESS, "old mfu dump format, was converted on load to " _GREEN_("%d") " pages", mfu_dump->pages + 1); + PrintAndLogEx(SUCCESS, "old mfu dump format, was converted on load to " _GREEN_("%d") " pages", mfu_dump->pages + 1); return PM3_SUCCESS; } diff --git a/client/loclass/fileutils.h b/client/loclass/fileutils.h index dae23a1b1..74d54000b 100644 --- a/client/loclass/fileutils.h +++ b/client/loclass/fileutils.h @@ -162,7 +162,7 @@ int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, u */ int convertOldMfuDump(uint8_t **dump, size_t *dumplen); -#define PrintAndLogDevice(level, format, args...) PrintAndLogEx(level, format , ## args) +#define PrintAndLogEx(level, format, args...) PrintAndLogEx(level, format , ## args) #else /** @@ -172,7 +172,7 @@ int convertOldMfuDump(uint8_t **dump, size_t *dumplen); * write also to a logfile. When doing so, just point this function to use PrintAndLog * @param fmt */ -#define PrintAndLogDevice(level, format, args...) { } +#define PrintAndLogEx(level, format, args...) { } diff --git a/client/loclass/ikeys.c b/client/loclass/ikeys.c index 67278e3b5..53f7848de 100644 --- a/client/loclass/ikeys.c +++ b/client/loclass/ikeys.c @@ -63,6 +63,9 @@ From "Dismantling iclass": #include #include #include + +#include "commonutil.h" // ARRAYLEN + #include "fileutils.h" #include "cipherutils.h" #include "mbedtls/des.h" @@ -218,7 +221,7 @@ static void printbegin() { if (debug_print < 2) return; - PrintAndLogDevice(NORMAL, " | x| y|z0|z1|z2|z3|z4|z5|z6|z7|"); + PrintAndLogEx(NORMAL, " | x| y|z0|z1|z2|z3|z4|z5|z6|z7|"); } static void printState(const char *desc, uint64_t c) { @@ -281,7 +284,7 @@ void hash0(uint64_t c, uint8_t k[8]) { if (x & 1) //Check if x7 is 1 p = ~p; - if (debug_print >= 2) PrintAndLogDevice(DEBUG, "p:%02x", p); + if (debug_print >= 2) PrintAndLogEx(DEBUG, "p:%02x", p); BitstreamIn p_in = { &p, 8, 0 }; uint8_t outbuffer[] = {0, 0, 0, 0, 0, 0, 0, 0}; @@ -426,7 +429,7 @@ static int testDES(Testcase testcase, mbedtls_des_context ctx_enc, mbedtls_des_c if (memcmp(testcase.uid, decrypted, 8) != 0) { //Decryption fail - PrintAndLogDevice(FAILED, "Encryption <-> Decryption FAIL"); + PrintAndLogEx(FAILED, "Encryption <-> Decryption FAIL"); printarr("Input", testcase.uid, 8); printarr("Decrypted", decrypted, 8); retval = 1; @@ -434,7 +437,7 @@ static int testDES(Testcase testcase, mbedtls_des_context ctx_enc, mbedtls_des_c if (memcmp(des_encrypted_csn, testcase.t_key, 8) != 0) { //Encryption fail - PrintAndLogDevice(FAILED, "Encryption != Expected result"); + PrintAndLogEx(FAILED, "Encryption != Expected result"); printarr("Output", des_encrypted_csn, 8); printarr("Expected", testcase.t_key, 8); retval = 1; @@ -444,7 +447,7 @@ static int testDES(Testcase testcase, mbedtls_des_context ctx_enc, mbedtls_des_c if (memcmp(div_key, testcase.div_key, 8) != 0) { //Key diversification fail - PrintAndLogDevice(FAILED, "Div key != expected result"); + PrintAndLogEx(FAILED, "Div key != expected result"); printarr(" csn ", testcase.uid, 8); printarr("{csn} ", des_encrypted_csn, 8); printarr("hash0 ", div_key, 8); @@ -469,13 +472,13 @@ static void des_checkParity(uint8_t *key) { bool parity = des_getParityBitFromKey(key[i]); if (parity != (key[i] & 0x1)) { fails++; - PrintAndLogDevice(FAILED, "parity1 fail, byte %d [%02x] was %d, should be %d", i, key[i], (key[i] & 0x1), parity); + PrintAndLogEx(FAILED, "parity1 fail, byte %d [%02x] was %d, should be %d", i, key[i], (key[i] & 0x1), parity); } } if (fails) { - PrintAndLogDevice(FAILED, "parity fails: %d", fails); + PrintAndLogEx(FAILED, "parity fails: %d", fails); } else { - PrintAndLogDevice(SUCCESS, "Key syntax is with parity bits inside each byte"); + PrintAndLogEx(SUCCESS, "Key syntax is with parity bits inside each byte"); } } @@ -554,15 +557,15 @@ static int testKeyDiversificationWithMasterkeyTestcases() { int i, error = 0; uint8_t empty[8] = {0}; - PrintAndLogDevice(INFO, "Testing encryption/decryption"); + PrintAndLogEx(INFO, "Testing encryption/decryption"); for (i = 0; memcmp(testcases + i, empty, 8); i++) error += testDES(testcases[i], ctx_enc, ctx_dec); if (error) - PrintAndLogDevice(FAILED, "%d errors occurred (%d testcases)", error, i); + PrintAndLogEx(FAILED, "%d errors occurred (%d testcases)", error, i); else - PrintAndLogDevice(SUCCESS, "Hashing seems to work (%d testcases)", i); + PrintAndLogEx(SUCCESS, "Hashing seems to work (%d testcases)", i); return error; } @@ -573,7 +576,7 @@ static void print64bits(const char *name, uint64_t val) { static uint64_t testCryptedCSN(uint64_t crypted_csn, uint64_t expected) { int retval = 0; uint8_t result[8] = {0}; - if (debug_print) PrintAndLogDevice(DEBUG, "debug_print %d", debug_print); + if (debug_print) PrintAndLogEx(DEBUG, "debug_print %d", debug_print); if (debug_print) print64bits(" {csn} ", crypted_csn); uint64_t crypted_csn_swapped = swapZvalues(crypted_csn); @@ -586,13 +589,13 @@ static uint64_t testCryptedCSN(uint64_t crypted_csn, uint64_t expected) { if (resultbyte != expected) { if (debug_print) { - PrintAndLogDevice(NORMAL, "\n"); - PrintAndLogDevice(FAILED, "FAIL!"); + PrintAndLogEx(NORMAL, "\n"); + PrintAndLogEx(FAILED, "FAIL!"); print64bits(" expected ", expected); } retval = 1; } else { - if (debug_print) PrintAndLogDevice(SUCCESS, "[OK]"); + if (debug_print) PrintAndLogEx(SUCCESS, "[OK]"); } return retval; } @@ -611,7 +614,7 @@ static int testDES2(uint64_t csn, uint64_t expected) { print64bits(" expected ", expected); if (expected == crypt_csn) { - PrintAndLogDevice(SUCCESS, "OK"); + PrintAndLogEx(SUCCESS, "OK"); return 0; } else { return 1; @@ -626,13 +629,13 @@ static int testDES2(uint64_t csn, uint64_t expected) { static int doTestsWithKnownInputs() { // KSel from http://www.proxmark.org/forum/viewtopic.php?pid=10977#p10977 int errors = 0; - PrintAndLogDevice(SUCCESS, "Testing DES encryption"); + PrintAndLogEx(SUCCESS, "Testing DES encryption"); uint8_t key[8] = {0x6c, 0x8d, 0x44, 0xf9, 0x2a, 0x2d, 0x01, 0xbf}; mbedtls_des_setkey_enc(&ctx_enc, key); testDES2(0xbbbbaaaabbbbeeee, 0xd6ad3ca619659e6b); - PrintAndLogDevice(SUCCESS, "Testing hashing algorithm"); + PrintAndLogEx(SUCCESS, "Testing hashing algorithm"); errors += testCryptedCSN(0x0102030405060708, 0x0bdd6512073c460a); errors += testCryptedCSN(0x1020304050607080, 0x0208211405f3381f); @@ -645,9 +648,9 @@ static int doTestsWithKnownInputs() { errors += testCryptedCSN(0x14e2adfc5bb7e134, 0x6ac90c6508bd9ea3); if (errors) - PrintAndLogDevice(FAILED, "%d errors occurred (9 testcases)", errors); + PrintAndLogEx(FAILED, "%d errors occurred (9 testcases)", errors); else - PrintAndLogDevice(SUCCESS, "Hashing seems to work (9 testcases)"); + PrintAndLogEx(SUCCESS, "Hashing seems to work (9 testcases)"); return errors; } @@ -683,10 +686,10 @@ static bool readKeyFile(uint8_t key[8]) { int doKeyTests(uint8_t debuglevel) { debug_print = debuglevel; - PrintAndLogDevice(INFO, "Checking if the master key is present (iclass_key.bin)..."); + PrintAndLogEx(INFO, "Checking if the master key is present (iclass_key.bin)..."); uint8_t key[8] = {0}; if (!readKeyFile(key)) { - PrintAndLogDevice(FAILED, "Master key not present, will not be able to do all testcases"); + PrintAndLogEx(FAILED, "Master key not present, will not be able to do all testcases"); } else { //Test if it's the right key... @@ -696,19 +699,19 @@ int doKeyTests(uint8_t debuglevel) { j += key[i]; if (j != 185) { - PrintAndLogDevice(INFO, "A key was loaded, but it does not seem to be the correct one. Aborting these tests"); + PrintAndLogEx(INFO, "A key was loaded, but it does not seem to be the correct one. Aborting these tests"); } else { - PrintAndLogDevice(SUCCESS, "Key present"); - PrintAndLogDevice(SUCCESS, "Checking key parity..."); + PrintAndLogEx(SUCCESS, "Key present"); + PrintAndLogEx(SUCCESS, "Checking key parity..."); des_checkParity(key); mbedtls_des_setkey_enc(&ctx_enc, key); mbedtls_des_setkey_dec(&ctx_dec, key); // Test hashing functions - PrintAndLogDevice(SUCCESS, "The following tests require the correct 8-byte master key"); + PrintAndLogEx(SUCCESS, "The following tests require the correct 8-byte master key"); testKeyDiversificationWithMasterkeyTestcases(); } } - PrintAndLogDevice(SUCCESS, "Testing key diversification with non-sensitive keys..."); + PrintAndLogEx(SUCCESS, "Testing key diversification with non-sensitive keys..."); doTestsWithKnownInputs(); return 0; } diff --git a/client/mifare/mad.c b/client/mifare/mad.c index 47b7cb70a..5cf3e1852 100644 --- a/client/mifare/mad.c +++ b/client/mifare/mad.c @@ -10,6 +10,8 @@ #include "mad.h" #include "ui.h" +#include "commonutil.h" // ARRAYLEN + #include "crc.h" #include "util.h" diff --git a/client/mifare/mad.h b/client/mifare/mad.h index d1028e06a..ce5ed4131 100644 --- a/client/mifare/mad.h +++ b/client/mifare/mad.h @@ -11,9 +11,7 @@ #ifndef _MAD_H_ #define _MAD_H_ -#include -#include -#include +#include "common.h" typedef struct { uint16_t AID; diff --git a/client/mifare/mfkey.c b/client/mifare/mfkey.c index 178da7fe4..bdccd302e 100644 --- a/client/mifare/mfkey.c +++ b/client/mifare/mfkey.c @@ -11,6 +11,8 @@ //----------------------------------------------------------------------------- #include "mfkey.h" +#include "crapto1/crapto1.h" + // MIFARE int compare_uint64(const void *a, const void *b) { if (*(uint64_t *)b == *(uint64_t *)a) return 0; diff --git a/client/mifare/mfkey.h b/client/mifare/mfkey.h index 4af5175a1..36ca8ed11 100644 --- a/client/mifare/mfkey.h +++ b/client/mifare/mfkey.h @@ -13,11 +13,8 @@ #ifndef MFKEY_H #define MFKEY_H -#include -#include -#include +#include "common.h" #include "mifare.h" -#include "crapto1/crapto1.h" uint32_t nonce2key(uint32_t uid, uint32_t nt, uint32_t nr, uint32_t ar, uint64_t par_info, uint64_t ks_info, uint64_t **keys); bool mfkey32(nonces_t data, uint64_t *outputkey); diff --git a/client/mifare/mifare4.c b/client/mifare/mifare4.c index 486dfd371..5cdca2e14 100644 --- a/client/mifare/mifare4.c +++ b/client/mifare/mifare4.c @@ -10,10 +10,10 @@ //----------------------------------------------------------------------------- #include "mifare4.h" -#include #include +#include "commonutil.h" // ARRAYLEN +#include "comms.h" // DropField #include "cmdhf14a.h" -#include "util.h" #include "ui.h" #include "crypto/libpcrypto.h" diff --git a/client/mifare/mifare4.h b/client/mifare/mifare4.h index 330c6d9f9..31eac1fdb 100644 --- a/client/mifare/mifare4.h +++ b/client/mifare/mifare4.h @@ -12,9 +12,7 @@ #ifndef MIFARE4_H #define MIFARE4_H -#include -#include -#include +#include "common.h" typedef struct { bool Authenticated; diff --git a/client/mifare/mifaredefault.h b/client/mifare/mifaredefault.h index 4123fdf70..7232510a0 100644 --- a/client/mifare/mifaredefault.h +++ b/client/mifare/mifaredefault.h @@ -11,7 +11,7 @@ #ifndef MIFAREDEFAULT_H__ #define MIFAREDEFAULT_H__ -#include +#include "common.h" static const uint64_t g_mifare_default_keys[] = { 0xffffffffffff, // Default key (first key used by program if no user defined key) diff --git a/client/mifare/mifarehost.c b/client/mifare/mifarehost.c index ff63004e9..f7c7ce4f2 100644 --- a/client/mifare/mifarehost.c +++ b/client/mifare/mifarehost.c @@ -8,7 +8,22 @@ // mifare commands //----------------------------------------------------------------------------- #include "mifarehost.h" -#include "cmdmain.h" + +#include +#include +#include +#include + +#include "comms.h" +#include "commonutil.h" +#include "mifare4.h" +#include "ui.h" // PrintAndLog... +#include "crapto1/crapto1.h" +#include "crc16.h" +#include "protocols.h" +#include "mfkey.h" +#include "util_posix.h" // msclock + int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) { uint32_t uid = 0; diff --git a/client/mifare/mifarehost.h b/client/mifare/mifarehost.h index 90837bcf7..11bd3f29c 100644 --- a/client/mifare/mifarehost.h +++ b/client/mifare/mifarehost.h @@ -10,22 +10,9 @@ #ifndef __MIFARE_HOST_H #define __MIFARE_HOST_H -#include -#include -#include -#include -#include - -#include "proxmark3.h" // time_t #include "common.h" + #include "util.h" // FILE_PATH_SIZE -#include "ui.h" // PrintAndLog... -#include "crapto1/crapto1.h" -#include "crc16.h" -#include "protocols.h" -#include "mifare.h" -#include "mfkey.h" -#include "util_posix.h" // msclock #define MIFARE_SECTOR_RETRY 10 diff --git a/client/mifare/ndef.c b/client/mifare/ndef.c index 7d0100d70..95c66bd72 100644 --- a/client/mifare/ndef.c +++ b/client/mifare/ndef.c @@ -9,7 +9,11 @@ //----------------------------------------------------------------------------- #include "ndef.h" + +#include + #include "ui.h" +#include "util.h" // sprint_hex... #include "emv/dump.h" #include "crypto/asn1utils.h" diff --git a/client/mifare/ndef.h b/client/mifare/ndef.h index 1737a6082..7d9ca2fbf 100644 --- a/client/mifare/ndef.h +++ b/client/mifare/ndef.h @@ -11,9 +11,7 @@ #ifndef _NDEF_H_ #define _NDEF_H_ -#include -#include -#include +#include "common.h" typedef enum { tnfEmptyRecord = 0x00, diff --git a/client/pm3_bit_limits.h b/client/pm3_bit_limits.h index 9bf06e16e..a2deda4c8 100644 --- a/client/pm3_bit_limits.h +++ b/client/pm3_bit_limits.h @@ -1,7 +1,9 @@ #ifndef __BITLIB_LIMITS_H #define __BITLIB_LIMITS_H + #define BITLIB_FLOAT_BITS 53 #define BITLIB_FLOAT_MAX 0xfffffffffffffL #define BITLIB_FLOAT_MIN (-0x10000000000000L) #define BITLIB_FLOAT_UMAX 0x1fffffffffffffUL + #endif diff --git a/common/prng.c b/client/prng.c similarity index 100% rename from common/prng.c rename to client/prng.c diff --git a/common/prng.h b/client/prng.h similarity index 94% rename from common/prng.h rename to client/prng.h index b9f49c6b6..3762f9f72 100644 --- a/common/prng.h +++ b/client/prng.h @@ -6,8 +6,9 @@ #ifndef __PRNG_H #define __PRNG_H -#include -#include + +#include "common.h" + typedef struct prng_ctx { uint32_t a; uint32_t b; @@ -21,4 +22,5 @@ void burtle_init_mod(prng_ctx *x, uint32_t seed); void burtle_init(prng_ctx *x, uint32_t seed); uint32_t GetSimplePrng(uint32_t seed); + #endif /* __PRNG_H */ diff --git a/client/proxendian.h b/client/proxendian.h index 44e099547..fde5126b1 100644 --- a/client/proxendian.h +++ b/client/proxendian.h @@ -11,7 +11,7 @@ #ifndef PROXENDIAN_H__ #define PROXENDIAN_H__ -#include +#include "common.h" #ifdef _WIN32 # define HOST_LITTLE_ENDIAN diff --git a/client/proxgui.cpp b/client/proxgui.cpp index c21352861..d5f82ffe9 100644 --- a/client/proxgui.cpp +++ b/client/proxgui.cpp @@ -9,6 +9,8 @@ //----------------------------------------------------------------------------- #include "proxgui.h" + +#include #include "proxguiqt.h" #include "proxmark3.h" diff --git a/client/proxgui.h b/client/proxgui.h index 06b5a919e..c4adbeb01 100644 --- a/client/proxgui.h +++ b/client/proxgui.h @@ -16,7 +16,8 @@ extern "C" { #endif #include -#include +#include +#include void ShowGraphWindow(void); void HideGraphWindow(void); diff --git a/client/proxmark3.c b/client/proxmark3.c index 9d57eeb7e..de6fe43af 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -10,24 +10,24 @@ //----------------------------------------------------------------------------- #include "proxmark3.h" -#include +#include + +#include // for Mingw readline #include -#include -#include #include #include #include +#include "usart_defs.h" + #include "util_posix.h" #include "proxgui.h" #include "cmdmain.h" #include "ui.h" -#include "util.h" -#include "cmdparser.h" #include "cmdhw.h" #include "whereami.h" #include "comms.h" -#include "usart.h" +//#include "usart.h" static void showBanner(void) { PrintAndLogEx(NORMAL, "\n"); diff --git a/client/proxmark3.h b/client/proxmark3.h index c669ebbfe..6d245da10 100644 --- a/client/proxmark3.h +++ b/client/proxmark3.h @@ -12,8 +12,7 @@ #ifndef PROXMARK3_H__ #define PROXMARK3_H__ -#include "pm3_cmd.h" -#include "cmdscript.h" // CmdScriptRun +#include "common.h" #define PROXPROMPT "pm3 --> " #define PROXPROMPT_USB "[usb] pm3 --> " diff --git a/client/scripting.c b/client/scripting.c index 718c4ed43..429d96fac 100644 --- a/client/scripting.c +++ b/client/scripting.c @@ -10,6 +10,28 @@ //----------------------------------------------------------------------------- #include "scripting.h" +#include +#include + +#include "lauxlib.h" +#include "cmdmain.h" +#include "comms.h" +#include "mifare/mifarehost.h" +#include "crc.h" +#include "crc64.h" +#include "mbedtls/sha1.h" +#include "mbedtls/aes.h" +#include "cmdcrc.h" +#include "cmdhfmfhard.h" +#include "cmdhfmfu.h" +#include "cmdlft55xx.h" // read t55xx etc +#include "mifare/ndef.h" // ndef parsing +#include "commonutil.h" +#include "ui.h" +#include "proxmark3.h" +#include "crc16.h" +#include "protocols.h" + static int returnToLuaWithError(lua_State *L, const char *fmt, ...) { char buffer[200]; va_list args; diff --git a/client/scripting.h b/client/scripting.h index 5b8c15ddd..07b07aa67 100644 --- a/client/scripting.h +++ b/client/scripting.h @@ -10,27 +10,9 @@ #ifndef SCRIPTING_H__ #define SCRIPTING_H__ -#include #include -#include -#include -#include "proxmark3.h" -#include "pm3_cmd.h" -#include "cmdmain.h" -#include "comms.h" -#include "util.h" -#include "mifare/mifarehost.h" -#include "crc.h" -#include "crc16.h" -#include "crc64.h" -#include "mbedtls/sha1.h" -#include "mbedtls/aes.h" -#include "cmdcrc.h" -#include "cmdhfmfhard.h" -#include "cmdhfmfu.h" -#include "protocols.h" -#include "cmdlft55xx.h" // read t55xx etc -#include "mifare/ndef.h" // ndef parsing +//#include +//#include #define LUA_LIBRARIES_DIRECTORY "lualibs/" #define LUA_SCRIPTS_DIRECTORY "scripts/" diff --git a/common/tea.c b/client/tea.c similarity index 97% rename from common/tea.c rename to client/tea.c index 187f8a3bc..b2a425e11 100644 --- a/common/tea.c +++ b/client/tea.c @@ -7,6 +7,9 @@ // ref: http://143.53.36.235:8080/source.htm#ansi //----------------------------------------------------------------------------- #include "tea.h" + +#include "commonutil.h" // bytes_to_num etc + #define ROUNDS 32 #define DELTA 0x9E3779B9 #define SUM 0xC6EF3720 diff --git a/common/tea.h b/client/tea.h similarity index 90% rename from common/tea.h rename to client/tea.h index 57be7e834..3390b9d92 100644 --- a/common/tea.h +++ b/client/tea.h @@ -10,9 +10,9 @@ #ifndef __TEA_H #define __TEA_H -#include "commonutil.h" -#include -#include +#include "common.h" + void tea_encrypt(uint8_t *v, uint8_t *key); void tea_decrypt(uint8_t *v, uint8_t *key); + #endif /* __TEA_H */ diff --git a/uart/README.md b/client/uart/README.md similarity index 100% rename from uart/README.md rename to client/uart/README.md diff --git a/uart/uart.h b/client/uart/uart.h similarity index 91% rename from uart/uart.h rename to client/uart/uart.h index a4f2f1f85..172e7db0d 100644 --- a/uart/uart.h +++ b/client/uart/uart.h @@ -32,25 +32,7 @@ #ifndef _UART_H_ #define _UART_H_ -#include -#include -#include - -#include -#include #include "common.h" -#include "comms.h" -#include "util_posix.h" // msclock - - - -#if defined (_WIN32) -#define SERIAL_PORT_EXAMPLE_H "com3" -#elif defined(__APPLE__) -#define SERIAL_PORT_EXAMPLE_H "/dev/cu.usbmodem" -#else -#define SERIAL_PORT_EXAMPLE_H "/dev/ttyACM0" -#endif /* serial_port is declared as a void*, which you should cast to whatever type * makes sense to your connection method. Both the posix and win32 diff --git a/uart/uart_posix.c b/client/uart/uart_posix.c similarity index 98% rename from uart/uart_posix.c rename to client/uart/uart_posix.c index ea535fd73..0077924cf 100644 --- a/uart/uart_posix.c +++ b/client/uart/uart_posix.c @@ -39,22 +39,18 @@ #include "uart.h" +#include +#include +#include #include #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include #include +#include "comms.h" + // Taken from https://github.com/unbit/uwsgi/commit/b608eb1772641d525bfde268fe9d6d8d0d5efde7 #ifndef SOL_TCP # define SOL_TCP IPPROTO_TCP diff --git a/uart/uart_win32.c b/client/uart/uart_win32.c similarity index 98% rename from uart/uart_win32.c rename to client/uart/uart_win32.c index 5a5f8b9d3..bbb5bfcfa 100644 --- a/uart/uart_win32.c +++ b/client/uart/uart_win32.c @@ -38,6 +38,12 @@ #include "uart.h" +#include +#include +#include + +#include "comms.h" + // The windows serial port implementation #ifdef _WIN32 #include diff --git a/client/ui.c b/client/ui.c index 0dcaca9e6..9927fd6d6 100644 --- a/client/ui.c +++ b/client/ui.c @@ -16,6 +16,15 @@ #endif #include "ui.h" +#include "commonutil.h" // ARRAYLEN + +#include // for Mingw readline +#include +#include +#include +#include +#include "util.h" + session_arg_t session; double CursorScaleFactor = 1; diff --git a/client/ui.h b/client/ui.h index 6e70b053d..648dce4c4 100644 --- a/client/ui.h +++ b/client/ui.h @@ -11,18 +11,11 @@ #ifndef UI_H__ #define UI_H__ -#define _USE_MATH_DEFINES -#include -#include -#include -#include -#include -#include -#include +#include "common.h" #include -#include -#include -#include "util.h" +#include "ansi.h" + +#define _USE_MATH_DEFINES typedef struct { bool stdinOnTTY; diff --git a/client/util.c b/client/util.c index 3bb0a96fa..52321689b 100644 --- a/client/util.c +++ b/client/util.c @@ -15,6 +15,16 @@ #include "util.h" +#include +#include +#include +#include +#include +#include +#include // Mingw + +#include "ui.h" // PrintAndLog + #define UTIL_BUFFER_SIZE_SPRINT 4097 // global client debug variable uint8_t g_debugMode = 0; diff --git a/client/util.h b/client/util.h index 8861045d8..09aeeaecb 100644 --- a/client/util.h +++ b/client/util.h @@ -10,16 +10,6 @@ #ifndef __UTIL_H_ #define __UTIL_H_ -#include //included in data.h -#include -#include -#include -#include -#include -#include -#include -#include "ui.h" // PrintAndLog -#include "commonutil.h" #include "common.h" #ifdef ANDROID @@ -31,20 +21,6 @@ # define FILE_PATH_SIZE 1000 #endif -#ifndef DropField -#define DropField() { \ - clearCommandBuffer(); SendCommandNG(CMD_HF_DROPFIELD, NULL, 0); \ - } -#endif - -#ifndef DropFieldEx -#define DropFieldEx(x) { \ - if ( (x) == ECC_CONTACTLESS) { \ - DropField(); \ - } \ - } -#endif - uint8_t g_debugMode; int kbd_enter_pressed(void); diff --git a/client/util_posix.c b/client/util_posix.c index ca54d2ae4..050040a32 100644 --- a/client/util_posix.c +++ b/client/util_posix.c @@ -8,8 +8,10 @@ // utilities requiring Posix library functions //----------------------------------------------------------------------------- +// ensure availability even with -std=c99; must be included before #if !defined(_WIN32) -#define _POSIX_C_SOURCE 199309L // need nanosleep() +//#define _POSIX_C_SOURCE 199309L // need nanosleep() +#define _POSIX_C_SOURCE 200112L // need localtime_r() #else #include #endif diff --git a/client/util_posix.h b/client/util_posix.h index a0a8c8638..546b4ea35 100644 --- a/client/util_posix.h +++ b/client/util_posix.h @@ -11,16 +11,16 @@ #ifndef UTIL_POSIX_H__ #define UTIL_POSIX_H__ -#include +#include "common.h" #ifdef _WIN32 # include # define sleep(n) Sleep(1000 *(n)) # define msleep(n) Sleep((n)) #else -extern void msleep(uint32_t n); // sleep n milliseconds +void msleep(uint32_t n); // sleep n milliseconds #endif // _WIN32 -extern uint64_t msclock(void); // a milliseconds clock +uint64_t msclock(void); // a milliseconds clock #endif diff --git a/common/bucketsort.h b/common/bucketsort.h index 0a56509c1..9e5123e1a 100644 --- a/common/bucketsort.h +++ b/common/bucketsort.h @@ -1,8 +1,7 @@ #ifndef BUCKETSORT_H__ #define BUCKETSORT_H__ -#include -#include +#include "common.h" typedef struct bucket { uint32_t *head; @@ -21,4 +20,5 @@ typedef struct bucket_info { void bucket_sort_intersect(uint32_t *const estart, uint32_t *const estop, uint32_t *const ostart, uint32_t *const ostop, bucket_info_t *bucket_info, bucket_array_t bucket); + #endif diff --git a/common/commonutil.h b/common/commonutil.h index 9504abd5b..a22486fff 100644 --- a/common/commonutil.h +++ b/common/commonutil.h @@ -11,8 +11,8 @@ #ifndef __COMMONUTIL_H #define __COMMONUTIL_H -#include -#include +#include "common.h" + // endian change for 16bit #ifdef __GNUC__ #ifndef BSWAP_16 @@ -53,11 +53,4 @@ void lsl(uint8_t *data, size_t len); int32_t le24toh(uint8_t data[3]); void htole24(uint32_t val, uint8_t data[3]); -# define _BLUE_(s) "\x1b[34m" s "\x1b[0m " -# define _RED_(s) "\x1b[31m" s "\x1b[0m " -# define _GREEN_(s) "\x1b[32m" s "\x1b[0m " -# define _YELLOW_(s) "\x1b[33m" s "\x1b[0m " -# define _MAGENTA_(s) "\x1b[35m" s "\x1b[0m " -# define _CYAN_(s) "\x1b[36m" s "\x1b[0m " - #endif diff --git a/common/crapto1/crapto1.c b/common/crapto1/crapto1.c index ba55227b5..66af2f41c 100644 --- a/common/crapto1/crapto1.c +++ b/common/crapto1/crapto1.c @@ -19,6 +19,8 @@ */ #include "crapto1.h" +#include "bucketsort.h" + #include #include "parity.h" diff --git a/common/crapto1/crapto1.h b/common/crapto1/crapto1.h index 49a784cf9..ab061e2e7 100644 --- a/common/crapto1/crapto1.h +++ b/common/crapto1/crapto1.h @@ -19,13 +19,10 @@ */ #ifndef CRAPTO1_INCLUDED #define CRAPTO1_INCLUDED -#include -#include -#include "bucketsort.h" -#ifdef __cplusplus -extern "C" { -#endif +#include +#include +#include struct Crypto1State {uint32_t odd, even;}; #if defined(__arm__) && !defined(__linux__) && !defined(_WIN32) && !defined(__APPLE__) // bare metal ARM Proxmark lacks malloc()/free() @@ -77,7 +74,4 @@ static inline int filter(uint32_t const x) { f |= 0x0d938 >> (x >> 16 & 0xf) & 1; return BIT(0xEC57E80A, f); } -#ifdef __cplusplus -} -#endif #endif diff --git a/common/crapto1/crypto1.c b/common/crapto1/crypto1.c index 7d6bb6e7d..9df30b356 100644 --- a/common/crapto1/crypto1.c +++ b/common/crapto1/crypto1.c @@ -17,9 +17,9 @@ Copyright (C) 2008-2008 bla */ -#include "crapto1.h" - #include + +#include "crapto1.h" #include "parity.h" #define SWAPENDIAN(x)\ diff --git a/common/crc.c b/common/crc.c index e197c0eee..0237fb36a 100644 --- a/common/crc.c +++ b/common/crc.c @@ -9,6 +9,8 @@ // #include "crc.h" +#include "commonutil.h" + void crc_init_ref(crc_t *crc, int order, uint32_t polynom, uint32_t initial_value, uint32_t final_xor, bool refin, bool refout) { crc_init(crc, order, polynom, initial_value, final_xor); crc->refin = refin; diff --git a/common/crc.h b/common/crc.h index f0fa91194..6dcfe918f 100644 --- a/common/crc.h +++ b/common/crc.h @@ -9,8 +9,7 @@ #ifndef __CRC_H #define __CRC_H -#include "common.h" //stdint, stddef, stdbool -#include "commonutil.h" // reflect, bswap_16 +#include "common.h" typedef struct crc_ctx { uint32_t state; @@ -24,6 +23,18 @@ typedef struct crc_ctx { bool refout; /* Parameter: Reflect output CRC? */ } crc_t; +/* Static initialization of a crc structure */ +#define CRC_INITIALIZER(_order, _polynom, _initial_value, _final_xor) { \ + .state = ((_initial_value) & ((1L<<(_order))-1)), \ + .order = (_order), \ + .polynom = (_polynom), \ + .initial_value = (_initial_value), \ + .final_xor = (_final_xor), \ + .mask = ((1L<<(_order))-1) \ + .refin = false, \ + .refout = false \ +} + /* Initialize a crc structure. order is the order of the polynom, e.g. 32 for a CRC-32 * polynom is the CRC polynom. initial_value is the initial value of a clean state. * final_xor is XORed onto the state before returning it from crc_result(). @@ -62,16 +73,4 @@ uint32_t CRC4Legic(uint8_t *buff, size_t size); // Calculate CRC-8/Legic checksum uint32_t CRC8Legic(uint8_t *buff, size_t size); -/* Static initialization of a crc structure */ -#define CRC_INITIALIZER(_order, _polynom, _initial_value, _final_xor) { \ - .state = ((_initial_value) & ((1L<<(_order))-1)), \ - .order = (_order), \ - .polynom = (_polynom), \ - .initial_value = (_initial_value), \ - .final_xor = (_final_xor), \ - .mask = ((1L<<(_order))-1) \ - .refin = false, \ - .refout = false \ -} - #endif /* __CRC_H */ diff --git a/common/crc16.c b/common/crc16.c index f2a6558b8..729c15cf4 100644 --- a/common/crc16.c +++ b/common/crc16.c @@ -7,6 +7,9 @@ //----------------------------------------------------------------------------- #include "crc16.h" +#include +#include "commonutil.h" + static uint16_t crc_table[256]; static bool crc_table_init = false; static CrcType_t current_crc_type = CRC_NONE; diff --git a/common/crc16.h b/common/crc16.h index 9c9df1d1f..6989af22e 100644 --- a/common/crc16.h +++ b/common/crc16.h @@ -8,11 +8,7 @@ #ifndef __CRC16_H #define __CRC16_H -#include -#include -#include -#include -#include "commonutil.h" +#include "common.h" #define CRC16_POLY_CCITT 0x1021 #define CRC16_POLY_LEGIC 0xc6c6 //0x6363 diff --git a/common/crc32.h b/common/crc32.h index 308b3a077..a6bbee16a 100644 --- a/common/crc32.h +++ b/common/crc32.h @@ -9,18 +9,9 @@ #ifndef __CRC32_H #define __CRC32_H -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif +#include "common.h" void crc32_ex(const uint8_t *data, const size_t len, uint8_t *crc); void crc32_append(uint8_t *data, const size_t len); -#ifdef __cplusplus -} -#endif - #endif diff --git a/common/crc64.c b/common/crc64.c index 23360f6bd..3bdc596ac 100644 --- a/common/crc64.c +++ b/common/crc64.c @@ -1,5 +1,3 @@ -#include -#include #include "crc64.h" #define CRC64_ISO_PRESET 0xFFFFFFFFFFFFFFFF diff --git a/common/crc64.h b/common/crc64.h index 3782bdbae..af6417cb3 100644 --- a/common/crc64.h +++ b/common/crc64.h @@ -9,6 +9,8 @@ #ifndef __CRC64_H #define __CRC64_H +#include "common.h" + void crc64(const uint8_t *data, const size_t len, uint64_t *crc) ; #endif diff --git a/common/fpga.h b/common/fpga.h index eb26d0ccb..e0704d95c 100644 --- a/common/fpga.h +++ b/common/fpga.h @@ -7,6 +7,8 @@ #ifndef __FPGA_H #define __FPGA_H +#include "common.h" + #define FPGA_BITSTREAM_FIXED_HEADER_SIZE sizeof(bitparse_fixed_header) #define FPGA_INTERLEAVE_SIZE 288 #define FPGA_CONFIG_SIZE 42336L // our current fpga_[lh]f.bit files are 42175 bytes. Rounded up to next multiple of FPGA_INTERLEAVE_SIZE diff --git a/common/iso15693tools.c b/common/iso15693tools.c index 795d1be60..66a0f81da 100644 --- a/common/iso15693tools.c +++ b/common/iso15693tools.c @@ -7,6 +7,8 @@ //----------------------------------------------------------------------------- #include "iso15693tools.h" +#include + // returns a string representation of the UID // UID is transmitted and stored LSB first, displayed MSB first // target char* buffer, where to put the UID, if NULL a static buffer is returned diff --git a/common/iso15693tools.h b/common/iso15693tools.h index e59f6ca39..42b2152cc 100644 --- a/common/iso15693tools.h +++ b/common/iso15693tools.h @@ -11,10 +11,7 @@ #ifndef ISO15693_H__ #define ISO15693_H__ -#include "proxmark3.h" -#include -#include -#include "crc16.h" +#include "common.h" // REQUEST FLAGS #define ISO15_REQ_SUBCARRIER_SINGLE 0x00 // Tag should respond using one subcarrier (ASK) @@ -70,8 +67,6 @@ #define ISO15_CMD_SYSINFO 0x2B #define ISO15_CMD_SECSTATUS 0x2C -char *Iso15693sprintUID(char *target, uint8_t *uid); - //----------------------------------------------------------------------------- // Map a sequence of octets (~layer 2 command) into the set of bits to feed // to the FPGA, to transmit that command to the tag. @@ -123,4 +118,6 @@ static const int Iso15693FrameEOF[] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; +char *Iso15693sprintUID(char *target, uint8_t *uid); + #endif diff --git a/include/legic_prng.h b/common/legic_prng.h similarity index 96% rename from include/legic_prng.h rename to common/legic_prng.h index c34455c4c..b72c6d8ed 100644 --- a/include/legic_prng.h +++ b/common/legic_prng.h @@ -9,10 +9,12 @@ #ifndef __LEGIC_PRNG_H #define __LEGIC_PRNG_H -#include +#include "common.h" + void legic_prng_init(uint8_t iv); void legic_prng_forward(int count); uint8_t legic_prng_get_bit(void); uint32_t legic_prng_get_bits(uint8_t len); + #endif diff --git a/common/lfdemod.c b/common/lfdemod.c index ec960c91f..b0b30a1c8 100644 --- a/common/lfdemod.c +++ b/common/lfdemod.c @@ -36,12 +36,9 @@ // marshmellow //----------------------------------------------------------------------------- -#include // for memset, memcmp and size_t #include "lfdemod.h" -#include // for uint_32+ -#include // for bool +#include // for memset, memcmp and size_t #include "parity.h" // for parity test -#include "commonutil.h" // colors #include "pm3_cmd.h" // error codes //********************************************************************************************** //---------------------------------Utilities Section-------------------------------------------- @@ -51,15 +48,12 @@ //to allow debug print calls when used not on dev -//void dummy(char *fmt, ...){} -void Dbprintf(const char *fmt, ...); - #ifndef ON_DEVICE #include "ui.h" -# include "cmdparser.h" # include "cmddata.h" # define prnt(args...) PrintAndLogEx(DEBUG, ## args ); #else +# include "dbprint.h" uint8_t g_debugMode = 0; # define prnt Dbprintf #endif diff --git a/common/lfdemod.h b/common/lfdemod.h index 0acb52063..50d769c6b 100644 --- a/common/lfdemod.h +++ b/common/lfdemod.h @@ -13,12 +13,8 @@ #ifndef LFDEMOD_H__ #define LFDEMOD_H__ -#include // for uint_32+ -#include // for bool -#include // for strcmp, memset, memcmp and size_t -#include // for -#include // for bool -#include "parity.h" // for parity test + +#include "common.h" //might not be high enough for noisy environments #define NOISE_AMPLITUDE_THRESHOLD 8 @@ -83,4 +79,5 @@ int Em410xDecode(uint8_t *bits, size_t *size, size_t *start_idx, uint32_t *hi, u int HIDdemodFSK(uint8_t *dest, size_t *size, uint32_t *hi2, uint32_t *hi, uint32_t *lo, int *waveStartIdx); int detectIdteck(uint8_t *dest, size_t *size); int detectIOProx(uint8_t *dest, size_t *size, int *waveStartIdx); + #endif diff --git a/common/parity.c b/common/parity.c index 2a1d6281c..1db224f37 100644 --- a/common/parity.c +++ b/common/parity.c @@ -6,7 +6,6 @@ // parity functions (all defined in parity.h) //----------------------------------------------------------------------------- #include -#include const uint8_t OddByteParity[256] = { 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, diff --git a/common/parity.h b/common/parity.h index e42616917..a768f51fb 100644 --- a/common/parity.h +++ b/common/parity.h @@ -11,12 +11,7 @@ #ifndef __PARITY_H #define __PARITY_H -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include +#include "common.h" extern const uint8_t OddByteParity[256]; @@ -52,8 +47,4 @@ static inline bool oddparity32(uint32_t x) { #endif } -#ifdef __cplusplus -} -#endif - #endif /* __PARITY_H */ diff --git a/common/protocols.c b/common/protocols.c deleted file mode 100644 index 809c31704..000000000 --- a/common/protocols.c +++ /dev/null @@ -1,150 +0,0 @@ -#include "protocols.h" - -// ATA55xx shared presets & routines -uint32_t GetT55xxClockBit(uint32_t clock) { - switch (clock) { - case 128: - return T55x7_BITRATE_RF_128; - case 100: - return T55x7_BITRATE_RF_100; - case 64: - return T55x7_BITRATE_RF_64; - case 50: - return T55x7_BITRATE_RF_50; - case 40: - return T55x7_BITRATE_RF_40; - case 32: - return T55x7_BITRATE_RF_32; - case 16: - return T55x7_BITRATE_RF_16; - case 8: - return T55x7_BITRATE_RF_8; - default : - return 0; - } -} - -#ifndef ON_DEVICE -#include "ui.h" -#define PrintAndLogDevice(level, format, args...) PrintAndLogEx(level, format , ## args) - -static uint8_t isset(uint8_t val, uint8_t mask) { - return (val & mask); -} - -static uint8_t notset(uint8_t val, uint8_t mask) { - return !(val & mask); -} - -static void fuse_config(const picopass_hdr *hdr) { - uint8_t fuses = hdr->conf.fuses; - - if (isset(fuses, FUSE_FPERS)) - PrintAndLogDevice(SUCCESS, "\tMode: Personalization [Programmable]"); - else - PrintAndLogDevice(NORMAL, "\tMode: Application [Locked]"); - - if (isset(fuses, FUSE_CODING1)) { - PrintAndLogDevice(NORMAL, "\tCoding: RFU"); - } else { - if (isset(fuses, FUSE_CODING0)) - PrintAndLogDevice(NORMAL, "\tCoding: ISO 14443-2 B/ISO 15693"); - else - PrintAndLogDevice(NORMAL, "\tCoding: ISO 14443B only"); - } - // 1 1 - if (isset(fuses, FUSE_CRYPT1) && isset(fuses, FUSE_CRYPT0)) PrintAndLogDevice(SUCCESS, "\tCrypt: Secured page, keys not locked"); - // 1 0 - if (isset(fuses, FUSE_CRYPT1) && notset(fuses, FUSE_CRYPT0)) PrintAndLogDevice(NORMAL, "\tCrypt: Secured page, keys locked"); - // 0 1 - if (notset(fuses, FUSE_CRYPT1) && isset(fuses, FUSE_CRYPT0)) PrintAndLogDevice(SUCCESS, "\tCrypt: Non secured page"); - // 0 0 - if (notset(fuses, FUSE_CRYPT1) && notset(fuses, FUSE_CRYPT0)) PrintAndLogDevice(NORMAL, "\tCrypt: No auth possible. Read only if RA is enabled"); - - if (isset(fuses, FUSE_RA)) - PrintAndLogDevice(NORMAL, "\tRA: Read access enabled"); - else - PrintAndLogDevice(WARNING, "\tRA: Read access not enabled"); -} - -void getMemConfig(uint8_t mem_cfg, uint8_t chip_cfg, uint8_t *max_blk, uint8_t *app_areas, uint8_t *kb) { - // mem-bit 5, mem-bit 7, chip-bit 4: defines chip type - uint8_t k16 = isset(mem_cfg, 0x80); - //uint8_t k2 = isset(mem_cfg, 0x08); - uint8_t book = isset(mem_cfg, 0x20); - - if (isset(chip_cfg, 0x10) && !k16 && !book) { - *kb = 2; - *app_areas = 2; - *max_blk = 31; - } else if (isset(chip_cfg, 0x10) && k16 && !book) { - *kb = 16; - *app_areas = 2; - *max_blk = 255; //16kb - } else if (notset(chip_cfg, 0x10) && !k16 && !book) { - *kb = 16; - *app_areas = 16; - *max_blk = 255; //16kb - } else if (isset(chip_cfg, 0x10) && k16 && book) { - *kb = 32; - *app_areas = 3; - *max_blk = 255; //16kb - } else if (notset(chip_cfg, 0x10) && !k16 && book) { - *kb = 32; - *app_areas = 17; - *max_blk = 255; //16kb - } else { - *kb = 32; - *app_areas = 2; - *max_blk = 255; - } -} - -static void mem_app_config(const picopass_hdr *hdr) { - uint8_t mem = hdr->conf.mem_config; - uint8_t chip = hdr->conf.chip_config; - uint8_t applimit = hdr->conf.app_limit; - uint8_t kb = 2; - uint8_t app_areas = 2; - uint8_t max_blk = 31; - - getMemConfig(mem, chip, &max_blk, &app_areas, &kb); - - if (applimit < 6) applimit = 26; - if (kb == 2 && (applimit > 0x1f)) applimit = 26; - - PrintAndLogDevice(NORMAL, " Mem: %u KBits/%u App Areas (%u * 8 bytes) [%02X]", kb, app_areas, max_blk, mem); - PrintAndLogDevice(NORMAL, "\tAA1: blocks 06-%02X", applimit); - PrintAndLogDevice(NORMAL, "\tAA2: blocks %02X-%02X", applimit + 1, max_blk); - PrintAndLogDevice(NORMAL, "\tOTP: 0x%02X%02X", hdr->conf.otp[1], hdr->conf.otp[0]); - PrintAndLogDevice(NORMAL, "\nKeyAccess:"); - - uint8_t book = isset(mem, 0x20); - if (book) { - PrintAndLogDevice(NORMAL, "\tRead A - Kd"); - PrintAndLogDevice(NORMAL, "\tRead B - Kc"); - PrintAndLogDevice(NORMAL, "\tWrite A - Kd"); - PrintAndLogDevice(NORMAL, "\tWrite B - Kc"); - PrintAndLogDevice(NORMAL, "\tDebit - Kd or Kc"); - PrintAndLogDevice(NORMAL, "\tCredit - Kc"); - } else { - PrintAndLogDevice(NORMAL, "\tRead A - Kd or Kc"); - PrintAndLogDevice(NORMAL, "\tRead B - Kd or Kc"); - PrintAndLogDevice(NORMAL, "\tWrite A - Kc"); - PrintAndLogDevice(NORMAL, "\tWrite B - Kc"); - PrintAndLogDevice(NORMAL, "\tDebit - Kd or Kc"); - PrintAndLogDevice(NORMAL, "\tCredit - Kc"); - } -} -static void print_picopass_info(const picopass_hdr *hdr) { - fuse_config(hdr); - mem_app_config(hdr); -} -void printIclassDumpInfo(uint8_t *iclass_dump) { - print_picopass_info((picopass_hdr *) iclass_dump); -} - -#else -#define PrintAndLogDevice(level, format, ...) { } -#endif -//ON_DEVICE diff --git a/zlib/ChangeLog b/common/zlib/ChangeLog similarity index 100% rename from zlib/ChangeLog rename to common/zlib/ChangeLog diff --git a/zlib/FAQ b/common/zlib/FAQ similarity index 100% rename from zlib/FAQ rename to common/zlib/FAQ diff --git a/zlib/README b/common/zlib/README similarity index 100% rename from zlib/README rename to common/zlib/README diff --git a/zlib/adler32.c b/common/zlib/adler32.c similarity index 100% rename from zlib/adler32.c rename to common/zlib/adler32.c diff --git a/zlib/deflate.c b/common/zlib/deflate.c similarity index 100% rename from zlib/deflate.c rename to common/zlib/deflate.c diff --git a/zlib/deflate.h b/common/zlib/deflate.h similarity index 100% rename from zlib/deflate.h rename to common/zlib/deflate.h diff --git a/zlib/inffast.c b/common/zlib/inffast.c similarity index 100% rename from zlib/inffast.c rename to common/zlib/inffast.c diff --git a/zlib/inffast.h b/common/zlib/inffast.h similarity index 100% rename from zlib/inffast.h rename to common/zlib/inffast.h diff --git a/zlib/inffixed.h b/common/zlib/inffixed.h similarity index 100% rename from zlib/inffixed.h rename to common/zlib/inffixed.h diff --git a/zlib/inflate.c b/common/zlib/inflate.c similarity index 100% rename from zlib/inflate.c rename to common/zlib/inflate.c diff --git a/zlib/inflate.h b/common/zlib/inflate.h similarity index 100% rename from zlib/inflate.h rename to common/zlib/inflate.h diff --git a/zlib/inftrees.c b/common/zlib/inftrees.c similarity index 100% rename from zlib/inftrees.c rename to common/zlib/inftrees.c diff --git a/zlib/inftrees.h b/common/zlib/inftrees.h similarity index 100% rename from zlib/inftrees.h rename to common/zlib/inftrees.h diff --git a/zlib/trees.c b/common/zlib/trees.c similarity index 100% rename from zlib/trees.c rename to common/zlib/trees.c diff --git a/zlib/trees.h b/common/zlib/trees.h similarity index 100% rename from zlib/trees.h rename to common/zlib/trees.h diff --git a/zlib/zconf.h b/common/zlib/zconf.h similarity index 100% rename from zlib/zconf.h rename to common/zlib/zconf.h diff --git a/zlib/zlib.h b/common/zlib/zlib.h similarity index 100% rename from zlib/zlib.h rename to common/zlib/zlib.h diff --git a/zlib/zutil.c b/common/zlib/zutil.c similarity index 100% rename from zlib/zutil.c rename to common/zlib/zutil.c diff --git a/zlib/zutil.h b/common/zlib/zutil.h similarity index 100% rename from zlib/zutil.h rename to common/zlib/zutil.h diff --git a/common/Makefile.common b/common_arm/Makefile.common similarity index 81% rename from common/Makefile.common rename to common_arm/Makefile.common index 282f242d9..30f0f679e 100644 --- a/common/Makefile.common +++ b/common_arm/Makefile.common @@ -31,10 +31,11 @@ AS = $(CROSS)as LD = $(CROSS)ld OBJCOPY = $(CROSS)objcopy GZIP=gzip +MV=mv OBJDIR = obj -INCLUDE = -I../include -I../common -I. +INCLUDE = -I../include -I../common_arm -I../common -I. TAR=tar TARFLAGS = -C .. -rvf @@ -63,14 +64,19 @@ DETECTED_OS=Windows endif # Also search prerequisites in the common directory (for usb.c), the fpga directory (for fpga.bit), and the zlib directory -VPATH = . ../common ../common/crapto1 ../common/mbedtls ../fpga ../zlib ../armsrc/Standalone ../uart +VPATH = . ../common_arm ../common ../common/crapto1 ../common/mbedtls ../common/zlib ../fpga ../armsrc/Standalone -INCLUDES = ../include/proxmark3.h ../include/at91sam7s512.h ../include/config_gpio.h ../include/pm3_cmd.h $(APP_INCLUDES) +INCLUDES = ../include/proxmark3_arm.h ../include/at91sam7s512.h ../include/config_gpio.h ../include/pm3_cmd.h CFLAGS = -c $(INCLUDE) -Wall -Werror -pedantic -Wunused -std=c99 $(APP_CFLAGS) -Os LDFLAGS = -nostartfiles -nodefaultlibs -Wl,-gc-sections -n LIBS = -lgcc +# Flags to generate temporary dependency files +DEPFLAGS = -MT $@ -MMD -MP -MF $(OBJDIR)/$*.Td +# make temporary to final dependency files after successful compilation +POSTCOMPILE = $(MV) -f $(OBJDIR)/$*.Td $(OBJDIR)/$*.d + THUMBOBJ = $(patsubst %.c,$(OBJDIR)/%.o,$(notdir $(THUMBSRC))) ARMOBJ = $(patsubst %.c,$(OBJDIR)/%.o,$(notdir $(ARMSRC))) ASMOBJ = $(patsubst %.s,$(OBJDIR)/%.o,$(notdir $(ASMSRC))) @@ -78,11 +84,13 @@ VERSIONOBJ = $(patsubst %.c,$(OBJDIR)/%.o,$(notdir $(VERSIONSRC))) $(THUMBOBJ): $(OBJDIR)/%.o: %.c $(INCLUDES) $(info [-] CC $<) - $(Q)$(CC) $(CFLAGS) -mthumb -mthumb-interwork -o $@ $< + $(Q)$(CC) $(CFLAGS) $(DEPFLAGS) -mthumb -mthumb-interwork -o $@ $< + $(Q)$(POSTCOMPILE) $(ARMOBJ): $(OBJDIR)/%.o: %.c $(INCLUDES) $(info [-] CC $<) - $(Q)$(CC) $(CFLAGS) -mthumb-interwork -o $@ $< + $(Q)$(CC) $(CFLAGS) $(DEPFLAGS) -mthumb-interwork -o $@ $< + $(Q)$(POSTCOMPILE) $(ASMOBJ): $(OBJDIR)/%.o: %.s $(info [-] CC $<) @@ -111,11 +119,7 @@ DEPENDENCY_FILES = $(patsubst %.c,$(OBJDIR)/%.d,$(notdir $(THUMBSRC))) \ $(patsubst %.c,$(OBJDIR)/%.d,$(notdir $(ARMSRC))) \ $(patsubst %.s,$(OBJDIR)/%.d,$(notdir $(ASMSRC))) -$(DEPENDENCY_FILES): Makefile ../common/Makefile.common - -$(patsubst %.o,%.d,$(THUMBOBJ) $(ARMOBJ)): $(OBJDIR)/%.d: %.c - @$(CC) -MM -MT "$(@) $(@:.d=.o)" $(CFLAGS) $< > $@ -$(patsubst %.o,%.d,$(ASMOBJ)):$(OBJDIR)/%.d: %.s - @$(CC) -MM -MT "$(@) $(@:.d=.o)" $(CFLAGS) $< > $@ +$(DEPENDENCY_FILES): Makefile ../common_arm/Makefile.common +.PRECIOUS: $(DEPENDENCY_FILES) -include $(DEPENDENCY_FILES) diff --git a/common/Makefile.hal b/common_arm/Makefile.hal similarity index 100% rename from common/Makefile.hal rename to common_arm/Makefile.hal diff --git a/common/default_version.c b/common_arm/default_version.c similarity index 93% rename from common/default_version.c rename to common_arm/default_version.c index b586e4ad1..e1e5dc64c 100644 --- a/common/default_version.c +++ b/common_arm/default_version.c @@ -1,4 +1,4 @@ -#include "proxmark3.h" +#include "proxmark3_arm.h" /* This is the default version.c file that Makefile.common falls back to if perl is not available */ const struct version_information __attribute__((section(".version_information"))) version_information = { VERSION_INFORMATION_MAGIC, diff --git a/common/ldscript.common b/common_arm/ldscript.common similarity index 100% rename from common/ldscript.common rename to common_arm/ldscript.common diff --git a/common/usb_cdc.c b/common_arm/usb_cdc.c similarity index 98% rename from common/usb_cdc.c rename to common_arm/usb_cdc.c index 5768a99ab..dd8d2f7c4 100644 --- a/common/usb_cdc.c +++ b/common_arm/usb_cdc.c @@ -33,6 +33,9 @@ */ #include "usb_cdc.h" +#include "proxmark3_arm.h" +#include "usart_defs.h" + /* AT91SAM7S256 USB Device Port • Embedded 328-byte dual-port RAM for endpoints @@ -448,17 +451,16 @@ AT91S_CDC_LINE_CODING line = { // purely informative, actual values don't matter // timer counts in 21.3us increments (1024/48MHz), rounding applies // WARNING: timer can't measure more than 1.39s (21.3us * 0xffff) -static void SpinDelay(int ms) { - int us = ms * 1000; +static void SpinDelayUs(int us) { int ticks = ((MCK / 1000000) * us + 512) >> 10; // Borrow a PWM unit for my real-time clock AT91C_BASE_PWMC->PWMC_ENA = PWM_CHANNEL(0); // 48 MHz / 1024 gives 46.875 kHz - AT91C_BASE_PWMC_CH0->PWMC_CMR = PWM_CH_MODE_PRESCALER(10); - AT91C_BASE_PWMC_CH0->PWMC_CDTYR = 0; - AT91C_BASE_PWMC_CH0->PWMC_CPRDR = 0xffff; + AT91C_BASE_PWMC_CH0->PWMC_CMR = PWM_CH_MODE_PRESCALER(10); // Channel Mode Register + AT91C_BASE_PWMC_CH0->PWMC_CDTYR = 0; // Channel Duty Cycle Register + AT91C_BASE_PWMC_CH0->PWMC_CPRDR = 0xffff; // Channel Period Register uint16_t start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR; @@ -512,7 +514,7 @@ void usb_enable() { // Disconnect and reconnect USB controller for 100ms usb_disable(); - SpinDelay(100); + SpinDelayUs(100 * 1000); // Wait for a short while //for (volatile size_t i=0; i<0x100000; i++) {}; diff --git a/common/usb_cdc.h b/common_arm/usb_cdc.h similarity index 95% rename from common/usb_cdc.h rename to common_arm/usb_cdc.h index 64dfbcd4d..b5ec2e8d7 100644 --- a/common/usb_cdc.h +++ b/common_arm/usb_cdc.h @@ -35,12 +35,8 @@ #ifndef _USB_CDC_H_ #define _USB_CDC_H_ -#include -#include "at91sam7s512.h" -#include "usart.h" -#include "config_gpio.h" -#include "proxmark3.h" // USB_CONNECT() #include "common.h" +#include "at91sam7s512.h" void usb_disable(void); void usb_enable(void); @@ -62,4 +58,3 @@ void AT91F_USB_SendStall(AT91PS_UDP pUdp); void AT91F_CDC_Enumerate(void); #endif // _USB_CDC_H_ - diff --git a/fpga/Makefile b/fpga/Makefile index ba9fec28b..b28c27db9 100644 --- a/fpga/Makefile +++ b/fpga/Makefile @@ -1,5 +1,3 @@ -include ../common/Makefile.common # for $(DETECTED_OS) - all: fpga_lf.bit fpga_hf.bit clean: $(Q)$(DELETE) *.bgn *.drc *.ncd *.ngd *_par.xrpt *-placed.* *-placed_pad.* *_usage.xml xst_hf.srp xst_lf.srp @@ -38,7 +36,6 @@ fpga_lf.ngc: fpga_lf.v fpga.ucf xst_lf.scr util.v clk_divider.v lo_edge_detect.v .PHONY: all clean help help: - @echo Multi-OS Makefile, you are running on $(DETECTED_OS) @echo Possible targets: @echo + all - Make fpga.bit, the FPGA bitstream @echo + clean - Clean intermediate files, does not clean fpga.bit diff --git a/include/ansi.h b/include/ansi.h new file mode 100644 index 000000000..29df618a1 --- /dev/null +++ b/include/ansi.h @@ -0,0 +1,11 @@ +#ifndef __ANSI_H +#define __ANSI_H + +#define _BLUE_(s) "\x1b[34m" s "\x1b[0m " +#define _RED_(s) "\x1b[31m" s "\x1b[0m " +#define _GREEN_(s) "\x1b[32m" s "\x1b[0m " +#define _YELLOW_(s) "\x1b[33m" s "\x1b[0m " +#define _MAGENTA_(s) "\x1b[35m" s "\x1b[0m " +#define _CYAN_(s) "\x1b[36m" s "\x1b[0m " + +#endif diff --git a/include/common.h b/include/common.h index dec2261ec..f427cb221 100644 --- a/include/common.h +++ b/include/common.h @@ -12,26 +12,11 @@ #ifndef __COMMON_H #define __COMMON_H -#ifdef __cplusplus -extern "C" { -#endif - +#include #include -#include #include -typedef unsigned char byte_t; - -#ifdef _MSC_VER -typedef DWORD uint32_t; -typedef BYTE uint8_t; -#define PACKED -// stuff -#else -#include -#include #define PACKED __attribute__((packed)) -#endif // debug #define DBG_NONE 0 // no messages @@ -138,7 +123,4 @@ extern int DBGLEVEL; # define DEC2BCD(dec) HornerScheme(dec, 10, 0x10) #endif -#ifdef __cplusplus -} -#endif #endif diff --git a/include/pmflash.h b/include/pmflash.h index 6e3a20e55..d61b5647d 100644 --- a/include/pmflash.h +++ b/include/pmflash.h @@ -12,14 +12,6 @@ #ifndef __PMFLASH_H #define __PMFLASH_H -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include -#include - #include "common.h" // Flashmem spi baudrate @@ -90,8 +82,4 @@ typedef struct { uint8_t signature[FLASH_MEM_SIGNATURE_LEN]; } PACKED rdv40_validation_t; -#ifdef __cplusplus -} -#endif - #endif // __PMFLASH_H diff --git a/common/protocols.h b/include/protocols.h similarity index 96% rename from common/protocols.h rename to include/protocols.h index 71a758fbe..5a1e56f4e 100644 --- a/common/protocols.h +++ b/include/protocols.h @@ -1,10 +1,7 @@ #ifndef PROTOCOLS_H #define PROTOCOLS_H -#include -#include -#include - +#include "common.h" //The following data is taken from http://www.proxmark.org/forum/viewtopic.php?pid=13501#p13501 /* @@ -361,9 +358,6 @@ ISO 7816-4 Basic interindustry commands. For command APDU's. #define LEGIC_READ 0x01 #define LEGIC_WRITE 0x00 -void printIclassDumpInfo(uint8_t *iclass_dump); -void getMemConfig(uint8_t mem_cfg, uint8_t chip_cfg, uint8_t *max_blk, uint8_t *app_areas, uint8_t *kb); - /* T55x7 configuration register definitions */ #define T55x7_POR_DELAY 0x00000001 #define T55x7_ST_TERMINATOR 0x00000008 @@ -420,9 +414,6 @@ void getMemConfig(uint8_t mem_cfg, uint8_t chip_cfg, uint8_t *max_blk, uint8_t * #define T55XX_WRITE_TIMEOUT 1500 -uint32_t GetT55xxClockBit(uint32_t clock); - - // em4x05 & em4x69 chip configuration register definitions #define EM4x05_GET_BITRATE(x) (((x & 0x3F)*2)+2) #define EM4x05_SET_BITRATE(x) ((x-2)/2) @@ -551,27 +542,5 @@ uint32_t GetT55xxClockBit(uint32_t clock); #define CALYPSO_SAM_SV_DEBIT 0x54 #define CALYPSO_SAM_SV_RELOAD 0x56 -// iclass / picopass chip config structures and shared routines -typedef struct { - uint8_t app_limit; //[8] - uint8_t otp[2]; //[9-10] - uint8_t block_writelock;//[11] - uint8_t chip_config; //[12] - uint8_t mem_config; //[13] - uint8_t eas; //[14] - uint8_t fuses; //[15] -} picopass_conf_block; - - -typedef struct { - uint8_t csn[8]; - picopass_conf_block conf; - uint8_t epurse[8]; - uint8_t key_d[8]; - uint8_t key_c[8]; - uint8_t app_issuer_area[8]; -} picopass_hdr; - - #endif // PROTOCOLS_H diff --git a/include/proxmark3.h b/include/proxmark3_arm.h similarity index 99% rename from include/proxmark3.h rename to include/proxmark3_arm.h index f7903d24f..a2f76e93d 100644 --- a/include/proxmark3.h +++ b/include/proxmark3_arm.h @@ -11,11 +11,12 @@ #ifndef __PROXMARK3_H #define __PROXMARK3_H +#include "common.h" + // Might as well have the hardware-specific defines everywhere. #include "at91sam7s512.h" #include "config_gpio.h" #include "pm3_cmd.h" -#include "common.h" // Check bootrom.c for actual clock settings #define MAINCK 16000000 diff --git a/include/usart_defs.h b/include/usart_defs.h new file mode 100644 index 000000000..232e80276 --- /dev/null +++ b/include/usart_defs.h @@ -0,0 +1,26 @@ +#ifndef __USART_DEFS_H +#define __USART_DEFS_H + +//#define USART_BAUD_RATE 9600 +#define USART_BAUD_RATE 115200 +// BT HC-06 physical layer runs at 128kbps +// so it's possible to gain a little bit by using 230400 +// with some risk to overflow its internal buffers: +//#define USART_BAUD_RATE 230400 + +#define USART_BUFFLEN 512 +#define USART_FIFOLEN (2*USART_BUFFLEN) + +// Higher baudrates are pointless, only increasing overflow risk + +#define USART_PARITY 'N' + +#if defined (_WIN32) +#define SERIAL_PORT_EXAMPLE_H "com3" +#elif defined(__APPLE__) +#define SERIAL_PORT_EXAMPLE_H "/dev/cu.usbmodem" +#else +#define SERIAL_PORT_EXAMPLE_H "/dev/ttyACM0" +#endif + +#endif diff --git a/recovery/Makefile b/recovery/Makefile index 601f93055..59f7f37c8 100644 --- a/recovery/Makefile +++ b/recovery/Makefile @@ -1,4 +1,4 @@ -include ../common/Makefile.common +include ../common_arm/Makefile.common BINS = bootrom.bin fullimage.bin proxmark3_recovery.bin diff --git a/client/deprecated-hid-flasher/flasher/Info.plist b/tools/deprecated-hid-flasher/flasher/Info.plist similarity index 100% rename from client/deprecated-hid-flasher/flasher/Info.plist rename to tools/deprecated-hid-flasher/flasher/Info.plist diff --git a/client/deprecated-hid-flasher/flasher/Makefile b/tools/deprecated-hid-flasher/flasher/Makefile similarity index 100% rename from client/deprecated-hid-flasher/flasher/Makefile rename to tools/deprecated-hid-flasher/flasher/Makefile diff --git a/client/deprecated-hid-flasher/flasher/elf.h b/tools/deprecated-hid-flasher/flasher/elf.h similarity index 100% rename from client/deprecated-hid-flasher/flasher/elf.h rename to tools/deprecated-hid-flasher/flasher/elf.h diff --git a/client/deprecated-hid-flasher/flasher/flash.c b/tools/deprecated-hid-flasher/flasher/flash.c similarity index 100% rename from client/deprecated-hid-flasher/flasher/flash.c rename to tools/deprecated-hid-flasher/flasher/flash.c diff --git a/client/deprecated-hid-flasher/flasher/flash.h b/tools/deprecated-hid-flasher/flasher/flash.h similarity index 100% rename from client/deprecated-hid-flasher/flasher/flash.h rename to tools/deprecated-hid-flasher/flasher/flash.h diff --git a/client/deprecated-hid-flasher/flasher/flasher.c b/tools/deprecated-hid-flasher/flasher/flasher.c similarity index 100% rename from client/deprecated-hid-flasher/flasher/flasher.c rename to tools/deprecated-hid-flasher/flasher/flasher.c diff --git a/client/deprecated-hid-flasher/flasher/obj/.dummy b/tools/deprecated-hid-flasher/flasher/obj/.dummy similarity index 100% rename from client/deprecated-hid-flasher/flasher/obj/.dummy rename to tools/deprecated-hid-flasher/flasher/obj/.dummy diff --git a/client/deprecated-hid-flasher/flasher/proxendian.h b/tools/deprecated-hid-flasher/flasher/proxendian.h similarity index 100% rename from client/deprecated-hid-flasher/flasher/proxendian.h rename to tools/deprecated-hid-flasher/flasher/proxendian.h diff --git a/client/deprecated-hid-flasher/flasher/proxmark3.h b/tools/deprecated-hid-flasher/flasher/proxmark3.h similarity index 100% rename from client/deprecated-hid-flasher/flasher/proxmark3.h rename to tools/deprecated-hid-flasher/flasher/proxmark3.h diff --git a/client/deprecated-hid-flasher/flasher/proxusb.c b/tools/deprecated-hid-flasher/flasher/proxusb.c similarity index 100% rename from client/deprecated-hid-flasher/flasher/proxusb.c rename to tools/deprecated-hid-flasher/flasher/proxusb.c diff --git a/client/deprecated-hid-flasher/flasher/proxusb.h b/tools/deprecated-hid-flasher/flasher/proxusb.h similarity index 100% rename from client/deprecated-hid-flasher/flasher/proxusb.h rename to tools/deprecated-hid-flasher/flasher/proxusb.h diff --git a/client/deprecated-hid-flasher/flasher/sleep.h b/tools/deprecated-hid-flasher/flasher/sleep.h similarity index 100% rename from client/deprecated-hid-flasher/flasher/sleep.h rename to tools/deprecated-hid-flasher/flasher/sleep.h diff --git a/client/deprecated-hid-flasher/flasher/usb_cmd.h b/tools/deprecated-hid-flasher/flasher/usb_cmd.h similarity index 100% rename from client/deprecated-hid-flasher/flasher/usb_cmd.h rename to tools/deprecated-hid-flasher/flasher/usb_cmd.h diff --git a/client/deprecated-hid-flasher/unbind-proxmark b/tools/deprecated-hid-flasher/unbind-proxmark similarity index 100% rename from client/deprecated-hid-flasher/unbind-proxmark rename to tools/deprecated-hid-flasher/unbind-proxmark diff --git a/tools/mkversion.pl b/tools/mkversion.pl index aaac146f8..997c2081b 100644 --- a/tools/mkversion.pl +++ b/tools/mkversion.pl @@ -64,7 +64,7 @@ $fullgitinfo =~ s/(\s)//g; $fullgitinfo = substr $fullgitinfo, 0, 49; print < -#ifdef __cplusplus -extern "C" { -#endif struct Crypto1State {uint32_t odd, even;}; struct Crypto1State *crypto1_create(uint64_t); @@ -87,7 +84,4 @@ static inline int filter(uint32_t const x) { f |= 0x0d938 >> (x >> 16 & 0xf) & 1; return BIT(0xEC57E80A, f); } -#ifdef __cplusplus -} -#endif #endif From 80b4e81130fe42231aee63731d854573eb3c56db Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 9 Aug 2019 14:41:44 +0200 Subject: [PATCH 0294/1854] Fix fpga_compress race condition and isolate it in tools --- Makefile | 10 ++- armsrc/Makefile | 6 +- client/Makefile | 10 +-- common_arm/Makefile.common | 2 +- {common => common_fpga}/fpga.h | 3 +- tools/fpga_compress/Makefile | 69 +++++++++++++++++++ .../fpga_compress}/fpga_compress.c | 2 +- tools/fpga_compress/obj/.dummy | 0 8 files changed, 87 insertions(+), 15 deletions(-) rename {common => common_fpga}/fpga.h (95%) create mode 100644 tools/fpga_compress/Makefile rename {client => tools/fpga_compress}/fpga_compress.c (99%) create mode 100644 tools/fpga_compress/obj/.dummy diff --git a/Makefile b/Makefile index 194b63b22..58c61281f 100644 --- a/Makefile +++ b/Makefile @@ -33,7 +33,7 @@ endif -include .Makefile.options.cache include common_arm/Makefile.hal -all clean: %: client/% bootrom/% armsrc/% recovery/% mfkey/% nonce2key/% +all clean: %: client/% bootrom/% armsrc/% recovery/% mfkey/% nonce2key/% fpga_compress/% mfkey/%: FORCE $(info [*] MAKE $@) @@ -41,10 +41,13 @@ mfkey/%: FORCE nonce2key/%: FORCE $(info [*] MAKE $@) $(Q)$(MAKE) --no-print-directory -C tools/nonce2key $(patsubst nonce2key/%,%,$@) +fpga_compress/%: FORCE + $(info [*] MAKE $@) + $(Q)$(MAKE) --no-print-directory -C tools/fpga_compress $(patsubst fpga_compress/%,%,$@) bootrom/%: FORCE cleanifplatformchanged $(info [*] MAKE $@) $(Q)$(MAKE) --no-print-directory -C bootrom $(patsubst bootrom/%,%,$@) -armsrc/%: FORCE cleanifplatformchanged +armsrc/%: FORCE cleanifplatformchanged fpga_compress/% $(info [*] MAKE $@) $(Q)$(MAKE) --no-print-directory -C armsrc $(patsubst armsrc/%,%,$@) client/%: FORCE @@ -74,6 +77,7 @@ help: @echo "+ client - Make only the OS-specific host client" @echo "+ mfkey - Make tools/mfkey" @echo "+ nonce2key - Make tools/nonce2key" + @echo "+ fpga_compress - Make tools/fpga_compress" @echo @echo "+ style - Apply some automated source code formatting rules" @echo "+ checks - Detect various encoding issues in source code" @@ -93,6 +97,8 @@ mfkey: mfkey/all nonce2key: nonce2key/all +fpga_compress: fpga_compress/all + flash-bootrom: bootrom/obj/bootrom.elf $(FLASH_TOOL) $(FLASH_TOOL) $(FLASH_PORT) -b $(subst /,$(PATHSEP),$<) diff --git a/armsrc/Makefile b/armsrc/Makefile index 6a19f7a4d..665c91005 100644 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@ -135,7 +135,7 @@ include ../common_arm/Makefile.common COMMON_FLAGS = -Os OBJS = $(OBJDIR)/fullimage.s19 -FPGA_COMPRESSOR = ../client/fpga_compress +FPGA_COMPRESSOR = ../tools/fpga_compress/fpga_compress all: $(OBJS) @@ -163,8 +163,8 @@ else endif $(FPGA_COMPRESSOR): - $(info [*] MAKE $@) - $(Q)$(MAKE) --no-print-directory -C ../client $(notdir $(FPGA_COMPRESSOR)) + $(error [!] MISSING $@ => To build it, go the root of the repo and do "make $(notdir $@)") + $(error [!] MISSING $@) $(OBJDIR)/fullimage.stage1.elf: $(VERSIONOBJ) $(OBJDIR)/fpga_all.o $(THUMBOBJ) $(ARMOBJ) $(info [=] LD $@) diff --git a/client/Makefile b/client/Makefile index e1cb03102..adf83cb18 100644 --- a/client/Makefile +++ b/client/Makefile @@ -291,14 +291,14 @@ ifeq "$(SUPPORTS_AVX512)" "True" MULTIARCHOBJS += $(MULTIARCHSRCS:%.c=$(OBJDIR)/%_AVX512.o) endif -BINS = proxmark3 flasher fpga_compress +BINS = proxmark3 flasher CLEAN = $(BINS) $(DEPENDENCY_FILES) $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(ZLIBOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(OBJDIR)/*.o *.moc.cpp ui/ui_overlays.h lualibs/pm3_cmd.lua lualibs/mf_default_keys.lua # need to assign dependancies to build these first... all: lua_build jansson_build mbedtls_build cbor_build $(BINS) all-static: LDLIBS:=-static $(LDLIBS) -all-static: proxmark3 flasher fpga_compress +all-static: $(BINS) proxmark3: LDLIBS+=$(LUALIB) $(JANSSONLIB) $(MBEDTLSLIB) $(CBORLIB) $(QTLDLIBS) proxmark3: $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(ZLIBOBJS) lualibs/pm3_cmd.lua lualibs/mf_default_keys.lua @@ -309,10 +309,6 @@ flasher: $(OBJDIR)/flash.o $(OBJDIR)/flasher.o $(COREOBJS) $(OBJCOBJS) $(info [=] LD $@) $(Q)$(LD) $(LDFLAGS) $^ $(LDLIBS) -o $@ -fpga_compress: $(OBJDIR)/fpga_compress.o $(ZLIBOBJS) - $(info [=] LD $@) - $(Q)$(LD) $(LDFLAGS) $(ZLIBFLAGS) $^ $(LDLIBS) -o $@ - proxgui.cpp: ui/ui_overlays.h proxguiqt.moc.cpp: proxguiqt.h @@ -427,7 +423,7 @@ DEPENDENCY_FILES = $(patsubst %.c, $(OBJDIR)/%.d, $(CORESRCS) $(CMDSRCS) $(ZLIBS $(patsubst %.o, %.d, $(MULTIARCHOBJS)) \ $(patsubst %.cpp, $(OBJDIR)/%.d, $(QTGUISRCS)) \ $(patsubst %.m, $(OBJDIR)/%.d, $(OBJCSRCS)) \ - $(OBJDIR)/proxmark3.d $(OBJDIR)/flash.d $(OBJDIR)/flasher.d $(OBJDIR)/fpga_compress.d + $(OBJDIR)/proxmark3.d $(OBJDIR)/flash.d $(OBJDIR)/flasher.d $(DEPENDENCY_FILES): ; .PRECIOUS: $(DEPENDENCY_FILES) diff --git a/common_arm/Makefile.common b/common_arm/Makefile.common index 30f0f679e..cf4405d6a 100644 --- a/common_arm/Makefile.common +++ b/common_arm/Makefile.common @@ -35,7 +35,7 @@ MV=mv OBJDIR = obj -INCLUDE = -I../include -I../common_arm -I../common -I. +INCLUDE = -I../include -I../common_arm -I../common_fpga -I../common -I. TAR=tar TARFLAGS = -C .. -rvf diff --git a/common/fpga.h b/common_fpga/fpga.h similarity index 95% rename from common/fpga.h rename to common_fpga/fpga.h index e0704d95c..5ab015f57 100644 --- a/common/fpga.h +++ b/common_fpga/fpga.h @@ -7,7 +7,8 @@ #ifndef __FPGA_H #define __FPGA_H -#include "common.h" +#include +#include #define FPGA_BITSTREAM_FIXED_HEADER_SIZE sizeof(bitparse_fixed_header) #define FPGA_INTERLEAVE_SIZE 288 diff --git a/tools/fpga_compress/Makefile b/tools/fpga_compress/Makefile new file mode 100644 index 000000000..c76a4c4eb --- /dev/null +++ b/tools/fpga_compress/Makefile @@ -0,0 +1,69 @@ +# Hide full compilation line: +ifneq ($(V),1) + Q?=@ +endif +# To see full command lines, use make V=1 + +CC = gcc +CXX = g++ +LD = g++ +RM = rm -f +MV = mv + +VPATH = ../../common/zlib +OBJDIR = obj + +# RPi Zero gcc requires -latomic +# but MacOSX /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld +# doesn't recognize option --as-needed +ifneq ($(platform),Darwin) + LDLIBS += -Wl,--as-needed -latomic -Wl,--no-as-needed +endif + +LIBS = -I../../common/zlib +INCLUDES_CLIENT = -I../../common_fpga $(LIBS) + +CFLAGS += -std=c99 -D_ISOC99_SOURCE -DPRESETS $(INCLUDES_CLIENT) -Wall -Werror -g -O3 + +# Flags to generate temporary dependency files +DEPFLAGS = -MT $@ -MMD -MP -MF $(OBJDIR)/$*.Td +# make temporary to final dependency files after successful compilation +POSTCOMPILE = $(MV) -f $(OBJDIR)/$*.Td $(OBJDIR)/$*.d + +ZLIBSRCS = deflate.c adler32.c trees.c zutil.c inflate.c inffast.c inftrees.c +ZLIBFLAGS = -DZ_SOLO -DZ_PREFIX -DNO_GZIP -DZLIB_PM3_TUNED +#-DDEBUG -Dverbose=1 + +ZLIBOBJS = $(ZLIBSRCS:%.c=$(OBJDIR)/%.o) + +BINS = fpga_compress +CLEAN = $(BINS) $(DEPENDENCY_FILES) $(ZLIBOBJS) $(OBJDIR)/*.o + +# need to assign dependancies to build these first... +all: $(BINS) + +all-static: LDLIBS:=-static $(LDLIBS) +all-static: $(BINS) + +fpga_compress: $(OBJDIR)/fpga_compress.o $(ZLIBOBJS) + $(info [=] LD $@) + $(Q)$(LD) $(LDFLAGS) $(ZLIBFLAGS) $^ $(LDLIBS) -o $@ + +clean: + $(Q)$(RM) $(CLEAN) + +.PHONY: all clean + +%.o: %.c +$(OBJDIR)/%.o : %.c $(OBJDIR)/%.d + $(info [-] CC $<) + $(Q)$(CC) $(DEPFLAGS) $(CFLAGS) $(ZLIBFLAGS) -c -o $@ $< + $(Q)$(POSTCOMPILE) + +DEPENDENCY_FILES = $(patsubst %.c, $(OBJDIR)/%.d, $(ZLIBSRCS)) $(OBJDIR)/fpga_compress.d + +$(DEPENDENCY_FILES): ; +.PRECIOUS: $(DEPENDENCY_FILES) + +-include $(DEPENDENCY_FILES) + diff --git a/client/fpga_compress.c b/tools/fpga_compress/fpga_compress.c similarity index 99% rename from client/fpga_compress.c rename to tools/fpga_compress/fpga_compress.c index dfe62d0c8..7777b6d51 100644 --- a/client/fpga_compress.c +++ b/tools/fpga_compress/fpga_compress.c @@ -15,7 +15,6 @@ #include #include #include -#include #include "fpga.h" #include "zlib.h" @@ -23,6 +22,7 @@ #define COMPRESS_LEVEL 9 // use best possible compression #define COMPRESS_WINDOW_BITS 15 // default = max = 15 for a window of 2^15 = 32KBytes #define COMPRESS_MEM_LEVEL 9 // determines the amount of memory allocated during compression. Default = 8. + /* COMPRESS_STRATEGY can be Z_DEFAULT_STRATEGY (the default), Z_FILTERED (more huffmann, less string matching), diff --git a/tools/fpga_compress/obj/.dummy b/tools/fpga_compress/obj/.dummy new file mode 100644 index 000000000..e69de29bb From 3e96c27c18dc54d8ba694eea31ae8d4065943f8e Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 9 Aug 2019 21:37:31 +0200 Subject: [PATCH 0295/1854] remove clang warning --- client/cmdlft55xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 72838e73b..5d26228e2 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -2614,7 +2614,7 @@ static int CmdT55xxSetDeviceConfig(const char *Cmd) { //Validations if (errors || cmdp == 0) return usage_lf_deviceconfig(); - t55xx_configurations_t configurations = {0}; + t55xx_configurations_t configurations = {{{0},{0},{0},{0}}}; if (set_defaults) { // fixed bit length From 8b0a80ec98e50ec620bcafb4b09a49a440191532 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 9 Aug 2019 22:11:03 +0200 Subject: [PATCH 0296/1854] add missing include for whereami.c in android --- client/whereami.c | 1 + 1 file changed, 1 insertion(+) diff --git a/client/whereami.c b/client/whereami.c index a18d2d2f7..9b154c628 100644 --- a/client/whereami.c +++ b/client/whereami.c @@ -213,6 +213,7 @@ int WAI_PREFIX(getExecutablePath)(char *out, int capacity, int *dirname_length) #if defined(__ANDROID__) || defined(ANDROID) #include #include +#include #endif WAI_NOINLINE From 47bcee05ad6e0cc8d71d292392fa103631428651 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 11 Aug 2019 22:30:04 +0200 Subject: [PATCH 0297/1854] Missing platform in fpga_compress Makefile --- tools/fpga_compress/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/fpga_compress/Makefile b/tools/fpga_compress/Makefile index c76a4c4eb..fccb94b41 100644 --- a/tools/fpga_compress/Makefile +++ b/tools/fpga_compress/Makefile @@ -10,6 +10,8 @@ LD = g++ RM = rm -f MV = mv +platform = $(shell uname) + VPATH = ../../common/zlib OBJDIR = obj From 0ab23426d6c59a3fa7114b49956d52790c46bd2e Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 11 Aug 2019 22:52:11 +0200 Subject: [PATCH 0298/1854] OSX workaround to get universal pm3 homebrew formula still working --- tools/fpga_compress/Makefile | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tools/fpga_compress/Makefile b/tools/fpga_compress/Makefile index fccb94b41..8798ace1e 100644 --- a/tools/fpga_compress/Makefile +++ b/tools/fpga_compress/Makefile @@ -9,6 +9,7 @@ CXX = g++ LD = g++ RM = rm -f MV = mv +CP = cp -a platform = $(shell uname) @@ -40,6 +41,10 @@ ZLIBOBJS = $(ZLIBSRCS:%.c=$(OBJDIR)/%.o) BINS = fpga_compress CLEAN = $(BINS) $(DEPENDENCY_FILES) $(ZLIBOBJS) $(OBJDIR)/*.o +# OSX Brew is expecting fpga_compress in client folder, some workaround for now: +ifeq ($(platform),Darwin) +CLEAN += $(foreach bin,$(BINS),../../client/$(bin)) +endif # need to assign dependancies to build these first... all: $(BINS) @@ -50,6 +55,10 @@ all-static: $(BINS) fpga_compress: $(OBJDIR)/fpga_compress.o $(ZLIBOBJS) $(info [=] LD $@) $(Q)$(LD) $(LDFLAGS) $(ZLIBFLAGS) $^ $(LDLIBS) -o $@ +# OSX Brew is expecting fpga_compress in client folder, some workaround for now: +ifeq ($(platform),Darwin) + $(Q)$(CP) $@ ../../client/ +endif clean: $(Q)$(RM) $(CLEAN) From 47b60d84de4d9211f0a0ae0a25deb35147c5fbe9 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 11 Aug 2019 23:53:45 +0200 Subject: [PATCH 0299/1854] make style --- armsrc/iclass.c | 30 +++++++++++++++--------------- client/cmdhf.c | 2 +- client/cmdlft55xx.c | 2 +- client/scripts/dumptoemul.lua | 2 +- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/armsrc/iclass.c b/armsrc/iclass.c index 26201842a..c8504e5ed 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -1501,21 +1501,21 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) { goto send; default : { if (simulationMode == MODE_FULLSIM) { // 0x0C - //Read block - //Take the data... - memcpy(data_generic_trace, emulator + (receivedCmd[1] << 3), 8); - AddCrc(data_generic_trace, 8); - trace_data = data_generic_trace; - trace_data_size = 10; - CodeIClassTagAnswer(trace_data, trace_data_size); - memcpy(modulated_response, ToSend, ToSendMax); - modulated_response_size = ToSendMax; - goto send; - } - break; - } - }//swith - }// if 4 + //Read block + //Take the data... + memcpy(data_generic_trace, emulator + (receivedCmd[1] << 3), 8); + AddCrc(data_generic_trace, 8); + trace_data = data_generic_trace; + trace_data_size = 10; + CodeIClassTagAnswer(trace_data, trace_data_size); + memcpy(modulated_response, ToSend, ToSendMax); + modulated_response_size = ToSendMax; + goto send; + } + break; + } + }//swith + }// if 4 } else if (receivedCmd[0] == ICLASS_CMD_SELECT) { // 0x81 // Reader selects anticollission CSN. // Tag sends the corresponding real CSN diff --git a/client/cmdhf.c b/client/cmdhf.c index 7af98e46f..a6c5ea11e 100644 --- a/client/cmdhf.c +++ b/client/cmdhf.c @@ -123,7 +123,7 @@ int CmdHFSearch(const char *Cmd) { } } - + //if (IfPm3Felica()) { // ans = CmdHFFelicaReader("s"); // if (ans) { diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 5d26228e2..d5f66496d 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -2614,7 +2614,7 @@ static int CmdT55xxSetDeviceConfig(const char *Cmd) { //Validations if (errors || cmdp == 0) return usage_lf_deviceconfig(); - t55xx_configurations_t configurations = {{{0},{0},{0},{0}}}; + t55xx_configurations_t configurations = {{{0}, {0}, {0}, {0}}}; if (set_defaults) { // fixed bit length diff --git a/client/scripts/dumptoemul.lua b/client/scripts/dumptoemul.lua index 96164b92f..80653a14a 100644 --- a/client/scripts/dumptoemul.lua +++ b/client/scripts/dumptoemul.lua @@ -108,7 +108,7 @@ local function main(args) if infile == nil then return oops('Could not read file ', input) end - + local dumpdata = readdump(infile) -- The hex-data is now in ascii-format, if dumpdata == NIL then return oops('Dumpfle not loaded') end From cb39be8c47e1d391a74a259aee97bbee3dd0a6a4 Mon Sep 17 00:00:00 2001 From: "Colin J. Brigato" Date: Mon, 12 Aug 2019 12:39:16 +0200 Subject: [PATCH 0300/1854] Fixes Compilation on OSX --- client/comms.c | 1 + 1 file changed, 1 insertion(+) diff --git a/client/comms.c b/client/comms.c index d42bd09fb..8d2c8f733 100644 --- a/client/comms.c +++ b/client/comms.c @@ -19,6 +19,7 @@ #include "ui.h" #include "crc16.h" #include "util_posix.h" // msclock +#include "util_darwin.h" // en/dis-ableNapp(); //#define COMMS_DEBUG //#define COMMS_DEBUG_RAW From 01ce580e7b535ae3c5da1f656c4a0d5aa5639123 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 12 Aug 2019 18:58:16 +0200 Subject: [PATCH 0301/1854] make btpin & btfactory accessible in BTADDON builds --- client/cmdmain.c | 2 +- client/cmdparser.c | 5 +++++ client/cmdparser.h | 1 + 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/client/cmdmain.c b/client/cmdmain.c index 618f04c73..eba34b2ca 100644 --- a/client/cmdmain.c +++ b/client/cmdmain.c @@ -102,7 +102,7 @@ static command_t CommandTable[] = { {"sc", CmdSmartcard, IfPm3Smartcard, "{ Smart card ISO7816 commands... }"}, {"script", CmdScript, AlwaysAvailable, "{ Scripting commands }"}, {"trace", CmdTrace, AlwaysAvailable, "{ Trace manipulation... }"}, - {"usart", CmdUsart, IfPm3FpcUsartDevFromUsb, "{ USART commands... }"}, + {"usart", CmdUsart, IfPm3FpcUsartFromUsb, "{ USART commands... }"}, {"quit", CmdQuit, AlwaysAvailable, ""}, {"exit", CmdQuit, AlwaysAvailable, "Exit program"}, {NULL, NULL, NULL, NULL} diff --git a/client/cmdparser.c b/client/cmdparser.c index d9ece2310..768941e10 100644 --- a/client/cmdparser.c +++ b/client/cmdparser.c @@ -72,6 +72,11 @@ bool IfPm3FpcUsartDevFromUsb(void) { return !conn.send_via_fpc_usart; } +bool IfPm3FpcUsartFromUsb(void) { + // true if FPC USART Host or developer support and if talking from USB-CDC interface + return IfPm3FpcUsartHostFromUsb() || IfPm3FpcUsartDevFromUsb(); +} + bool IfPm3Lf(void) { if (!IfPm3Present()) return false; diff --git a/client/cmdparser.h b/client/cmdparser.h index 284142780..b98aef9d4 100644 --- a/client/cmdparser.h +++ b/client/cmdparser.h @@ -30,6 +30,7 @@ bool IfPm3FpcUsart(void); bool IfPm3FpcUsartHost(void); bool IfPm3FpcUsartHostFromUsb(void); bool IfPm3FpcUsartDevFromUsb(void); +bool IfPm3FpcUsartFromUsb(void); bool IfPm3Lf(void); bool IfPm3Hitag(void); bool IfPm3Hfsniff(void); From ce76d34fa763a446a0a46389df9d0a6e18f051b7 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 12 Aug 2019 16:24:33 -0400 Subject: [PATCH 0302/1854] add: cheatsheet (@scund00r) --- doc/cheatsheet.md | 227 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 227 insertions(+) create mode 100644 doc/cheatsheet.md diff --git a/doc/cheatsheet.md b/doc/cheatsheet.md new file mode 100644 index 000000000..30dfa5b6b --- /dev/null +++ b/doc/cheatsheet.md @@ -0,0 +1,227 @@ +# Cheatsheet + +## Generic + +Identify High Frequency cards +``` +pm3 --> hf search +``` + +Identify Low Frequency cards +``` +pm3 --> lf search +``` + +Measure antenna characteristics, LF/HF voltage should be around 20-45+ V +``` +pm3 --> hw tune +``` + +Check versioning +``` +pm3 --> hw version +``` + +## iClass + +Reverse permute iClass master key +``` +Options +--- +r reverse permuted key + +pm3 --> hf iclass permute r 3F90EBF0910F7B6F +``` + +iClass Reader +``` +pm3 --> hf iclass reader +``` + +Dump iClass card contents +``` +Options +--- +k : *Access Key as 16 hex symbols or 1 hex to select key from memory + +pm3 --> hf iclass dump k AFA785A7DAB33378 +``` + +Read iClass Block +``` +Options +--- +b : The block number as 2 hex symbols +k : Access Key as 16 hex symbols or 1 hex to select key from memory + +pm3 --> hf iclass readblk b 7 k AFA785A7DAB33378 +``` + +Write to iClass Block +``` +Options +--- +b : The block number as 2 hex symbols +d : Set the Data to write as 16 hex symbols +k : Access Key as 16 hex symbols or 1 hex to select key from memory + +pm3 --> hf iclass writeblk b 07 d 6ce099fe7e614fd0 k AFA785A7DAB33378 +``` + +Print keystore +``` +Options +--- +p : print keys loaded into memory + +pm3 --> hf iclass managekeys p +``` + +Add key to keystore [0-7] +``` +Options +--- +n : specify the keyNbr to set in memory +k : set a key in memory + +pm3 --> hf iclass managekeys n 0 k AFA785A7DAB33378 +``` + +Encrypt iClass Block +``` +pm3 --> hf iclass encryptblk 0000000f2aa3dba8 +``` + +Load iClass dump into memory for simulation +``` +Options +--- +f : load iclass tag-dump filename + +pm3 --> hf iclass eload f iclass_tagdump-db883702f8ff12e0.bin +``` + +Simulate iClass +``` +Options +--- +0 simulate the given CSN +1 simulate default CSN +3 Full simulation using emulator memory (see 'hf iclass eload') + +pm3 --> hf iclass sim 3 +``` + +Clone iClass Legacy Sequence +``` +pm3 --> hf iclass readblk b 7 k AFA785A7DAB33378 +pm3 --> hf iclass writeblk b 07 d 6ce099fe7e614fd0 k AFA785A7DAB33378 +``` + +Simulate iClass Sequence +``` +pm3 --> hf iclass dump k AFA785A7DAB33378 +pm3 --> hf iclass eload f iclass_tagdump-db883702f8ff12e0.bin +pm3 --> hf iclass sim 3 +``` + +Extract custom iClass key (loclass attack) +``` +Options +--- +f : specify a filename to clone from +k : Access Key as 16 hex symbols or 1 hex to select key from memory +e : If 'e' is specified, elite computations applied to key + +pm3 --> hf iclass sim 2 +pm3 --> hf iclass loclass f iclass_mac_attack.bin +pm3 --> hf iclass dump k e +``` + +## Mifare + +Check for default keys +``` +Options +--- +<*card memory> [t|d|s|ss] +* - all sectors +card memory - 0 - MINI(320 bytes), 1 - 1K, 2 - 2K, 4 - 4K +d - write keys to binary file + +pm3 --> hf mf chk *1 ? d default_keys.dic +``` + +Dump Mifare card contents +``` +Options +--- +: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K +k : key filename, if no given, UID will be used as filename" +f : data filename, if no given, UID will be used as filename + +pm3 --> hf mf dump 1 +pm3 --> hf mf dump 1 k hf-mf-A29558E4-key.bin f hf-mf-A29558E4-data.bin +``` + +Convert .bin to .eml +``` +Options +--- +i ????????????? + +pm3 --> script run dumptoemul -i dumpdata.bin +``` + +Write to Mifare block +``` +Options +--- + + +pm3 --> hf mf wrbl 0 A FFFFFFFFFFFF d3a2859f6b880400c801002000000016 +``` + +Run Hardnested attack +``` +Options +--- + [known target key (12 hex symbols)] [w] [s] +w : Acquire nonces and write them to binary file nonces.bin + +pm3 --> hf mf hardnested 0 A 8829da9daf76 0 A w +``` + +Load Mifare emul dump file into memory for simulation +``` +Options +--- + +[card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K, u = UL + +pm3 --> hf mf eload 353C2AA6 +pm3 --> hf mf eload 1 353C2AA6 +``` + +Simulate Mifare +``` +u : (Optional) UID 4,7 or 10 bytes. If not specified, the UID 4B from emulator memory will be used + +pm3 --> hf mf sim u 353c2aa6 +``` + +Simulate Mifare Sequence +``` +pm3 --> hf mf chk *1 ? d default_keys.dic +pm3 --> hf mf dump 1 +pm3 --> script run dumptoemul -i dumpdata.bin +pm3 --> hf mf eload 353C2AA6 +pm3 --> hf mf sim u 353c2aa6 +``` + +Clone Mifare 1K Sequence +``` +pm3 --> hf mf chk *1 ? d default_keys.dic +pm3 --> hf mf dump +pm3 --> hf mf restore 1 u 4A6CE843 k hf-mf-A29558E4-key.bin f hf-mf-A29558E4-data.bin +``` From 0cd8dbb10acb0ed752d6128c8ddd2bfbc32fb600 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 12 Aug 2019 16:30:43 -0400 Subject: [PATCH 0303/1854] textual --- CHANGELOG.md | 5 +++++ README.md | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 90f193bd7..a6aab7919 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,11 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Add cheat sheet for easy operations of the Proxmark3 (scund00r) + - Chg commands are now in green in the helptext list (@iceman1001) + - Fix 'script run ndefdump' - better exit messages when failing (@iceman1001) + - Fix 'hf iclass dump' - now also saves in EML format (@iceman1001) + - Fix 'hf iclass sim 3' - now works on legacy readers and legacy SE readers (@iceman1001) - Rework hitag2 read/write help (@ViRb3) - Add 'lf nedap' - encoding / decoding (anon) - Add client option `-i` to stay in interactive mode after a script or command (@DidierStevens/@doegox) diff --git a/README.md b/README.md index 50813868e..1af5d2157 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ Note that it also supports other Proxmark3 platforms as well! |[Why didn't you base it on official PM3 Master?](#why-didnt-you-base-it-on-official-pm3-master)| [Homebrew (Mac OS X) & Upgrading HomeBrew Tap Formula](/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md) | [First Use and Verification](/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md)| |[PM3 GUI](#pm3-gui)|[Setup and build for Windows](/doc/md/Installation_Instructions/Windows-Installation-Instructions.md)|[Commands & Features](/doc/md/Use_of_Proxmark/3_Commands-and-Features.md)| |[Issues](#issues)|[Blue shark manual](/doc/bt_manual_v10.md) |[Advanced compilation parameters](/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md)| -|[Notes on UART](/doc/uart_notes.md)||| +|[Notes on UART](/doc/uart_notes.md)||[Command Cheat sheet](/doc/cheatsheet.md)| |[Notes on Frame format](/doc/new_frame_format.md)||| |[Notes on external flash](/doc/ext_flash_notes.md)||| |[Notes on Termux / Android](/doc/termux_notes.md)||| From d4f2edef43dd9a7805058c2512e05f04a1d38627 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 12 Aug 2019 16:31:27 -0400 Subject: [PATCH 0304/1854] follow status pattern --- proxmark3.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/proxmark3.sh b/proxmark3.sh index 4cd6d76bc..07d2a27d5 100755 --- a/proxmark3.sh +++ b/proxmark3.sh @@ -7,7 +7,7 @@ PM3PATH=$(dirname "$0") cd "$PM3PATH" || exit 1 function wait4proxmark_Linux { - echo >&2 "Waiting for Proxmark to appear..." + echo >&2 "[=] Waiting for Proxmark to appear..." while true; do PM3=$(find /dev/pm3-* /dev/ttyACM* 2>/dev/null | head -1) if [[ $PM3 != "" ]]; then @@ -19,7 +19,7 @@ function wait4proxmark_Linux { } function wait4proxmark_macOS { - echo >&2 "Waiting for Proxmark to appear..." + echo >&2 "[=] Waiting for Proxmark to appear..." while true; do PM3=$(find /dev/pm3-* /dev/cu.usbmodem* 2>/dev/null | head -1) if [[ $PM3 != "" ]]; then @@ -31,7 +31,7 @@ function wait4proxmark_macOS { } function wait4proxmark_Windows { - echo >&2 "Waiting for Proxmark to appear..." + echo >&2 "[=] Waiting for Proxmark to appear..." while true; do device=$(wmic path Win32_SerialPort where "PNPDeviceID like '%VID_9AC4&PID_4B8F%'" get DeviceID,PNPDeviceID 2>/dev/null | awk 'NR==2') if [[ $device != "" ]]; then @@ -44,7 +44,7 @@ function wait4proxmark_Windows { } function wait4proxmark_WSL { - echo >&2 "Waiting for Proxmark to appear..." + echo >&2 "[=] Waiting for Proxmark to appear..." while true; do device=$(wmic.exe path Win32_SerialPort where "PNPDeviceID like '%VID_9AC4&PID_4B8F%'" get DeviceID,PNPDeviceID 2>/dev/null | awk 'NR==2') if [[ $device != "" ]]; then @@ -55,7 +55,7 @@ function wait4proxmark_WSL { sleep .1 done if [ -e "$PM3" ] && [ ! -w "$PM3" ]; then - echo "We need to give current user read/write access to $PM3" + echo "[!!] We need to give current user read/write access to $PM3" sudo chmod 666 "$PM3" fi echo "$PM3" @@ -72,7 +72,7 @@ elif [ "$SCRIPT" = "flash-fullimage.sh" ]; then elif [ "$SCRIPT" = "flash-bootrom.sh" ]; then CMD() { client/flasher "$1" -b "$BOOTIMAGE"; } else - echo "Script ran under unknown name, abort: $SCRIPT" + echo "[!!] Script ran under unknown name, abort: $SCRIPT" exit 1 fi HOSTOS=$(uname | awk '{print toupper($0)}') @@ -87,11 +87,11 @@ elif [ "$HOSTOS" = "DARWIN" ]; then elif [[ "$HOSTOS" =~ MINGW(32|64)_NT* ]]; then PORT=$(wait4proxmark_Windows) else - echo "Host OS not recognized, abort: $HOSTOS" + echo "[!!] Host OS not recognized, abort: $HOSTOS" exit 1 fi if [ "$PORT" = "" ]; then - echo "No port, abort" + echo "[!!] No port, abort" exit 1 fi From bbc324f9fe467220378cfa380285f33ded0c5c7f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 12 Aug 2019 16:31:57 -0400 Subject: [PATCH 0305/1854] follow status pattern --- client/flash.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/flash.c b/client/flash.c index ca2f012bb..84e1d687b 100644 --- a/client/flash.c +++ b/client/flash.c @@ -448,7 +448,7 @@ int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t int mem_avail = chipid_to_mem_avail(chipinfo); if (mem_avail != 0) { - PrintAndLogEx(NORMAL, "Available memory on this board: "_YELLOW_("%uK") "bytes\n", mem_avail); + PrintAndLogEx(INFO, "Available memory on this board: "_YELLOW_("%uK") "bytes\n", mem_avail); if (mem_avail > 256) { if (BL_VERSION_MAJOR(version) < BL_VERSION_MAJOR(BL_VERSION_1_0_0)) { PrintAndLogEx(ERR, _RED_("====================== OBS ! ======================")); @@ -460,7 +460,7 @@ int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t } } } else { - PrintAndLogEx(NORMAL, "Available memory on this board: "_RED_("UNKNOWN")"\n"); + PrintAndLogEx(INFO, "Available memory on this board: "_RED_("UNKNOWN")"\n"); PrintAndLogEx(ERR, _RED_("====================== OBS ! ======================================")); PrintAndLogEx(ERR, _RED_("Note: Your bootloader does not understand the new " _YELLOW_("CHIP_INFO") _RED_("command"))); flash_suggest_update_bootloader(); From de1093d5d911d8cb4951e70ad129178c3d76fc43 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 12 Aug 2019 16:32:27 -0400 Subject: [PATCH 0306/1854] textual --- client/cmdlfnedap.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/client/cmdlfnedap.c b/client/cmdlfnedap.c index b7f9891a5..3a4ebd131 100644 --- a/client/cmdlfnedap.c +++ b/client/cmdlfnedap.c @@ -411,11 +411,11 @@ static int CmdLfNedapGen(const char *Cmd) { } PrintAndLogEx(SUCCESS, - "Tag (%s) ; subtype : %1u , customer : %03x , ID : %05u" - , isLong ? "long (128b)" : "short (64b)" + "Tag - subtype: %1u , customer code: %03x , ID: %05u | %s" , subType , customerCode , id + , isLong ? "(128b)" : "(64b)" ); NedapGen(subType, customerCode, id, isLong, data); @@ -467,7 +467,7 @@ int CmdLFNedapClone(const char *Cmd) { } PrintAndLogEx(SUCCESS, "Preparing to clone NEDAP to T55x7"); - print_blocks(blocks, 5); + print_blocks(blocks, max); PacketResponseNG resp; @@ -491,9 +491,9 @@ int CmdLFNedapClone(const char *Cmd) { return PM3_ETIMEOUT; } } - // TODO info correct? - PrintAndLogEx(INFO, "The block 0 was changed (eXtended) which can be hard to detect. Configure it manually with"); - PrintAndLogEx(INFO, _YELLOW_("`lf t55xx config b 64 d BI i 1 o 32`")); + PrintAndLogEx(NORMAL, "\n"); + PrintAndLogEx(INFO, "The block 0 was changed (eXtended) which can be hard to detect."); + PrintAndLogEx(INFO, " Configure it manually " _YELLOW_("`lf t55xx config b 64 d BI i 1 o 32`")); return PM3_SUCCESS; } From 5acc77bc9556b807fae016326a19e2587020bfd7 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 12 Aug 2019 16:33:27 -0400 Subject: [PATCH 0307/1854] chg: mem spiffs info - text output --- armsrc/spiffs.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/armsrc/spiffs.c b/armsrc/spiffs.c index de6e9e226..df827b4e3 100644 --- a/armsrc/spiffs.c +++ b/armsrc/spiffs.c @@ -533,16 +533,21 @@ void rdv40_spiffs_safe_print_fsinfo() { rdv40_spiffs_fsinfo fsinfo; rdv40_spiffs_getfsinfo(&fsinfo, RDV40_SPIFFS_SAFETY_SAFE); DbpString(_BLUE_("Flash Memory FileSystem Info (SPIFFS)")); - Dbprintf("-------------------------------------"); - Dbprintf("* Filesystem Logical Block Size.........%d bytes", fsinfo.blockSize); - Dbprintf("* Filesystem Logical Page Size..........%d bytes", fsinfo.pageSize); - Dbprintf("--"); - Dbprintf("* Filesystem Max Open Files.............%d file descriptors", fsinfo.maxOpenFiles); - Dbprintf("* Filesystem Max Path Length............%d chars", fsinfo.maxPathLength); - Dbprintf("--"); - Dbprintf("Filesystem\tSize\tUsed\tAvailable\tUse%\tMounted on"); - Dbprintf("spiffs\t%dB\t%dB\t%dB\t\t%d%\t/", fsinfo.totalBytes, fsinfo.usedBytes, fsinfo.freeBytes, - fsinfo.usedPercent); +// Dbprintf("-------------------------------------"); + Dbprintf(" Logical Block Size........." _YELLOW_("%d")"bytes", fsinfo.blockSize); + Dbprintf(" Logical Page Size.........." _YELLOW_("%d")"bytes", fsinfo.pageSize); + Dbprintf(""); + Dbprintf(" Max Open Files............." _YELLOW_("%d")"file descriptors", fsinfo.maxOpenFiles); + Dbprintf(" Max Path Length............" _YELLOW_("%d")"chars", fsinfo.maxPathLength); +// DbpString(_BLUE_("Details")); + DbpString(""); + Dbprintf(" Filesystem\tSize\tUsed\tAvailable\tUse%\tMounted on"); + Dbprintf(" spiffs \t%d B\t%d B\t%d B\t\t"_YELLOW_("%d%")"\t/" + , fsinfo.totalBytes + , fsinfo.usedBytes + , fsinfo.freeBytes + , fsinfo.usedPercent + ); } // this function is safe and WILL rollback since it is only a PRINTING function, From 3fa7992940015bf8b61fa0ba76c2774c60052226 Mon Sep 17 00:00:00 2001 From: Alex Dib Date: Tue, 13 Aug 2019 18:48:56 +1000 Subject: [PATCH 0308/1854] Updated Cheatsheet --- doc/cheatsheet.md | 228 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 228 insertions(+) diff --git a/doc/cheatsheet.md b/doc/cheatsheet.md index 30dfa5b6b..8770b7551 100644 --- a/doc/cheatsheet.md +++ b/doc/cheatsheet.md @@ -138,6 +138,19 @@ pm3 --> hf iclass loclass f iclass_mac_attack.bin pm3 --> hf iclass dump k e ``` +Verify custom iClass key +``` +Options +--- +f : Dictionary file with default iclass keys +u : CSN +p : EPURSE +m : macs +e : elite + +pm3 --> hf iclass lookup u 010a0ffff7ff12e0 p feffffffffffffff m 66348979153c41b9 f default_iclass_keys.dic e +``` + ## Mifare Check for default keys @@ -225,3 +238,218 @@ pm3 --> hf mf chk *1 ? d default_keys.dic pm3 --> hf mf dump pm3 --> hf mf restore 1 u 4A6CE843 k hf-mf-A29558E4-key.bin f hf-mf-A29558E4-data.bin ``` + +## HID Prox + +Read HID Prox card +``` +pm3 --> lf hid read +``` + +Demodulate HID Prox card +``` +pm3 --> lf hid demod +``` + +Convert Site & Facility code to Wiegand +``` +Options +--- + +OEM : OEM number / site code +FC : facility code +CN : card number + +pm3 --> lf hid wiegand 0 56 150 +``` + +Simulate Prox card +``` + +pm3 --> lf hid sim 200670012d +``` + +Clone Prox to T5577 card +``` +pm3 --> lf hid clone 200670012d +``` + +Brute force HID reader +``` +Options +--- +a : 26|33|34|35|37|40|44|84"); +f : 8-bit value HID facility code"); +c : (optional) cardnumber to start with, max 65535"); +d : delay betweens attempts in ms. Default 1000ms"); +v : verbose logging, show all tries"); + +pm3 --> lf hid brute a 26 f 224 +pm3 --> lf hid brute v a 26 f 21 c 200 d 2000 +``` + +## Indala + +Read Indala card +``` +pm3 --> lf indala read +``` + +Demodulate Indala card +``` +pm3 --> lf indala demod +``` + +Simulate Indala card +``` +Options +--- + : 64/224 UID + +pm3 --> lf indala sim a0000000c2c436c1 +``` + +Clone to T55x7 card +``` +Options +--- + : 64/224 UID + +pm3 --> lf indala clone a0000000c2c436c1 +``` + +## Hitag + +Read Hitag information +``` +pm3 --> lf hitag info +``` + +Act as Hitag reader +``` +Options +--- +HitagS: +01 : Read all pages, challenge mode +02 : Read all pages, crypto mode. Set key=0 for no auth + +Hitag2: +21 : Read all pages, password mode. Default: 4D494B52 (\"MIKR\") +22 : Read all pages, challenge mode +23 : Read all pages, crypto mode. Key format: ISK high + ISK low. Default: 4F4E4D494B52 ("ONMIKR") +25 : Test recorded authentications +26 : Just read UID + +pm3 --> lf hitag 26 +pm3 --> lf hitag 21 4D494B52 +``` + +Sniff Hitag traffic +``` +pm3 --> lf hitag sniff +pm3 --> lf hitag list +``` + +Simulate Hitag +``` +pm3 --> lf hitag sim c378181c_a8f7.ht2 +``` + +Write to Hitag block +``` +Options +--- +HitagS: +03 : Write page, challenge mode +04 : Write page, crypto mode. Set key=0 for no auth + +Hitag2: +24 : Write page, crypto mode. Key format: ISK high + ISK low. +27 : Write page, password mode. Default: 4D494B52 ("MIKR") + +pm3 --> lf hitag writer 24 499602D2 1 00000000 +``` + +Simulate Hitag2 sequence +``` +pm3 --> lf hitag reader 21 56713368 +pm3 --> lf hitag sim c378181c_a8f7.ht2 +``` + +## T55XX + +Detect T55XX card +``` +pm3 --> lf t55xx detect +``` + +Configure demodulation +``` +Options +--- + : Set demodulation +EM is ASK +HID Prox is FSK +Indala is PSK + +pm3 --> lf t55xx config FSK +``` + +Write to T55xx block +``` +b : block number to write. Between 0-7 +d : 4 bytes of data to write (8 hex characters) + +pm3 --> lf t55xx wr b 0 d 00081040 +``` + +Wipe a T55xx tag and set defaults +``` +lf t55xx wipe +``` + +## Data + +Get raw samples [512-40000] +``` +data samples +``` + +Save samples to file +``` +data save +``` + +Load samples from file +``` +data load +``` + +## Lua Scripts + +List Lua Scripts + +``` +script list +``` + +Convert .bin to .eml +``` +Options +--- +i : Specifies the dump-file (input). If omitted, 'dumpdata.bin' is used + +script run dumptoemul -i xxxxxxxxxxxxxx.bin +``` + +Format Mifare card +``` +Options +--- +k : the current six byte key with write access +n : the new key that will be written to the card +a : the new access bytes that will be written to the card +x : execute the commands aswell. + +script run formatMifare -k FFFFFFFFFFFF -n FFFFFFFFFFFF -x +``` From 91db687bfe05651c23a7b7a08a6ec6f091d6a1b8 Mon Sep 17 00:00:00 2001 From: Iceman Date: Tue, 13 Aug 2019 15:58:37 +0200 Subject: [PATCH 0309/1854] Update cheatsheet.md --- doc/cheatsheet.md | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/doc/cheatsheet.md b/doc/cheatsheet.md index 8770b7551..65f2d3d79 100644 --- a/doc/cheatsheet.md +++ b/doc/cheatsheet.md @@ -1,6 +1,17 @@ # Cheatsheet -## Generic +[Generic](#generic-id) +[iClass](#iclass-id) +[Mifare](#mifare-id) +[HID Prox](#prox-id) +[Indala](#indala-id) +[Hitag](#hitag-id) +[T55XX](#t55xx-id) +[Data](#data-id) +[Lua Scripts](#lua-id) + + +## Generic {#generic-id} Identify High Frequency cards ``` @@ -22,7 +33,7 @@ Check versioning pm3 --> hw version ``` -## iClass +## iClass {#iclass-id} Reverse permute iClass master key ``` @@ -151,7 +162,7 @@ e : elite pm3 --> hf iclass lookup u 010a0ffff7ff12e0 p feffffffffffffff m 66348979153c41b9 f default_iclass_keys.dic e ``` -## Mifare +## Mifare {#mifare-id} Check for default keys ``` @@ -239,7 +250,7 @@ pm3 --> hf mf dump pm3 --> hf mf restore 1 u 4A6CE843 k hf-mf-A29558E4-key.bin f hf-mf-A29558E4-data.bin ``` -## HID Prox +## HID Prox {#prox-id} Read HID Prox card ``` @@ -288,7 +299,7 @@ pm3 --> lf hid brute a 26 f 224 pm3 --> lf hid brute v a 26 f 21 c 200 d 2000 ``` -## Indala +## Indala {#indala-id} Read Indala card ``` @@ -318,7 +329,7 @@ Options pm3 --> lf indala clone a0000000c2c436c1 ``` -## Hitag +## Hitag {#hitag-id} Read Hitag information ``` @@ -376,7 +387,7 @@ pm3 --> lf hitag reader 21 56713368 pm3 --> lf hitag sim c378181c_a8f7.ht2 ``` -## T55XX +## T55XX {#t55xx-id} Detect T55XX card ``` @@ -408,7 +419,7 @@ Wipe a T55xx tag and set defaults lf t55xx wipe ``` -## Data +## Data {#data-id} Get raw samples [512-40000] ``` @@ -425,7 +436,7 @@ Load samples from file data load ``` -## Lua Scripts +## Lua Scripts {#lua-id} List Lua Scripts From c3cb746a7e4296983296156670f2df3ceb62e952 Mon Sep 17 00:00:00 2001 From: Iceman Date: Tue, 13 Aug 2019 16:02:22 +0200 Subject: [PATCH 0310/1854] Update cheatsheet.md --- doc/cheatsheet.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/doc/cheatsheet.md b/doc/cheatsheet.md index 65f2d3d79..5221def92 100644 --- a/doc/cheatsheet.md +++ b/doc/cheatsheet.md @@ -1,17 +1,17 @@ # Cheatsheet -[Generic](#generic-id) -[iClass](#iclass-id) -[Mifare](#mifare-id) +[Generic](#Generic) +[iClass](#iClass) +[Mifare](#Mifare) [HID Prox](#prox-id) [Indala](#indala-id) [Hitag](#hitag-id) -[T55XX](#t55xx-id) -[Data](#data-id) -[Lua Scripts](#lua-id) +[T55XX](#T55XX) +[Data](#Data) +[Lua Scripts](#Lua Scripts) -## Generic {#generic-id} +## Generic Identify High Frequency cards ``` @@ -33,7 +33,7 @@ Check versioning pm3 --> hw version ``` -## iClass {#iclass-id} +## iClass Reverse permute iClass master key ``` @@ -162,7 +162,7 @@ e : elite pm3 --> hf iclass lookup u 010a0ffff7ff12e0 p feffffffffffffff m 66348979153c41b9 f default_iclass_keys.dic e ``` -## Mifare {#mifare-id} +## Mifare Check for default keys ``` @@ -387,7 +387,7 @@ pm3 --> lf hitag reader 21 56713368 pm3 --> lf hitag sim c378181c_a8f7.ht2 ``` -## T55XX {#t55xx-id} +## T55XX Detect T55XX card ``` @@ -419,7 +419,7 @@ Wipe a T55xx tag and set defaults lf t55xx wipe ``` -## Data {#data-id} +## Data Get raw samples [512-40000] ``` @@ -436,7 +436,7 @@ Load samples from file data load ``` -## Lua Scripts {#lua-id} +## Lua Scripts List Lua Scripts From 084ea32d11bc6e66ef49b1b35969119bb1402ab8 Mon Sep 17 00:00:00 2001 From: Iceman Date: Tue, 13 Aug 2019 16:03:54 +0200 Subject: [PATCH 0311/1854] Update cheatsheet.md --- doc/cheatsheet.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/doc/cheatsheet.md b/doc/cheatsheet.md index 5221def92..6a0ce2581 100644 --- a/doc/cheatsheet.md +++ b/doc/cheatsheet.md @@ -1,14 +1,14 @@ # Cheatsheet -[Generic](#Generic) -[iClass](#iClass) -[Mifare](#Mifare) -[HID Prox](#prox-id) -[Indala](#indala-id) -[Hitag](#hitag-id) -[T55XX](#T55XX) -[Data](#Data) -[Lua Scripts](#Lua Scripts) +- [Generic](#Generic) +- [iClass](#iClass) +- [Mifare](#Mifare) +- [HID Prox](#HID-Prox) +- [Indala](#Indala) +- [Hitag](#Hitag) +- [T55XX](#T55XX) +- [Data](#Data) +- [Lua Scripts](#Lua-Scripts) ## Generic From 1da98c7aa6f72c1424069256534bc87a8512b1d2 Mon Sep 17 00:00:00 2001 From: Iceman Date: Tue, 13 Aug 2019 16:04:47 +0200 Subject: [PATCH 0312/1854] Update cheatsheet.md --- doc/cheatsheet.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/cheatsheet.md b/doc/cheatsheet.md index 6a0ce2581..3fcaf9876 100644 --- a/doc/cheatsheet.md +++ b/doc/cheatsheet.md @@ -250,7 +250,7 @@ pm3 --> hf mf dump pm3 --> hf mf restore 1 u 4A6CE843 k hf-mf-A29558E4-key.bin f hf-mf-A29558E4-data.bin ``` -## HID Prox {#prox-id} +## HID Prox Read HID Prox card ``` @@ -299,7 +299,7 @@ pm3 --> lf hid brute a 26 f 224 pm3 --> lf hid brute v a 26 f 21 c 200 d 2000 ``` -## Indala {#indala-id} +## Indala Read Indala card ``` @@ -329,7 +329,7 @@ Options pm3 --> lf indala clone a0000000c2c436c1 ``` -## Hitag {#hitag-id} +## Hitag Read Hitag information ``` From 961f98c125e6cce26fd593987b209c21669df245 Mon Sep 17 00:00:00 2001 From: cjbrigato Date: Tue, 13 Aug 2019 15:58:08 +0200 Subject: [PATCH 0313/1854] SPIFFS : FIXES FS corruption against high numbero f current losses, high number of files manipulation. FIXES LOG_BLOCK erasing handlers. FIXES Garbage Collector. Overall, SPIFFS should now be WAY MORE resilient to any form of misbehavior. In case of corrupted filesystem (should still be readable !), spamming 'mem spiffs check' from the client will ensure at least 2 new free 4k blocks each tile (if number of LOG_PAGE available is enough) and in the same pass will move/reorganize the LOG_PAGES of contextual blocks. Yiha --- armsrc/Standalone/hf_colin.c | 41 +++++++++------------ armsrc/appmain.c | 9 +++++ armsrc/spiffs.c | 71 ++++++++++++++++++------------------ armsrc/spiffs.h | 10 +++-- armsrc/spiffs_cache.c | 8 ++-- armsrc/spiffs_config.h | 21 +++++++++-- client/cmdflashmemspiffs.c | 8 ++++ include/pm3_cmd.h | 1 + 8 files changed, 100 insertions(+), 69 deletions(-) diff --git a/armsrc/Standalone/hf_colin.c b/armsrc/Standalone/hf_colin.c index a45dd71c3..4fe898a18 100644 --- a/armsrc/Standalone/hf_colin.c +++ b/armsrc/Standalone/hf_colin.c @@ -8,27 +8,8 @@ //----------------------------------------------------------------------------- // main code for HF Mifare aka ColinRun by Colin Brigato //----------------------------------------------------------------------------- -#include "standalone.h" // standalone definitions -#include // for bool -#include -#include #include "hf_colin.h" -#include "appmain.h" -#include "fpgaloader.h" -#include "dbprint.h" -#include "ticks.h" -#include "commonutil.h" -#include "crc16.h" -#include "BigBuf.h" #include "frozen.h" -#include "proxmark3_arm.h" -#include "mifaresim.h" // mifare1ksim -#include "mifareutil.h" -#include "iso14443a.h" -#include "util.h" -#include "vtsend.h" -#include "spiffs.h" -#include "string.h" #define MF1KSZ 1024 #define MF1KSZSIZE 64 @@ -720,8 +701,10 @@ readysim: SpinOff(100); LED_C_ON(); - uint16_t flags; - switch (p_card.uidlen) { + DBGLEVEL = DBG_NONE; + + //uint16_t flags=0; + /*switch (p_card.uidlen) { case 10: flags = FLAG_10B_UID_IN_DATA; break; @@ -734,13 +717,23 @@ readysim: default: flags = FLAG_UID_IN_EMUL; break; - } + }*/ // Use UID, SAK, ATQA from EMUL, if uid not defined // if ((flags & (FLAG_4B_UID_IN_DATA | FLAG_7B_UID_IN_DATA | FLAG_10B_UID_IN_DATA)) == 0) { - flags |= FLAG_UID_IN_EMUL; + //flags |= FLAG_UID_IN_EMUL; //} - Mifare1ksim(flags | FLAG_MF_1K, 0, cjuid, 0, 0); + //flags |= FLAG_MF_1K; + //if ((flags & (FLAG_4B_UID_IN_DATA | FLAG_7B_UID_IN_DATA | FLAG_10B_UID_IN_DATA)) == 0) { + // flags |= FLAG_UID_IN_EMUL; + //} + //flags = 0x10; + uint16_t flags = 0; + flags = 16; + DbprintfEx(FLAG_NEWLINE,"\n\n\n\n\n\n\n\nn\n\nn\n\n\nflags: %d (0x%02x)",flags,flags); + cjSetCursLeft(); + SpinOff(1000); + Mifare1ksim(flags , 0, cjuid); LED_C_OFF(); SpinOff(50); vtsend_cursor_position_restore(NULL); diff --git a/armsrc/appmain.c b/armsrc/appmain.c index f163e579b..c54ff7255 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1518,6 +1518,10 @@ static void PacketReceived(PacketCommandNG *packet) { test_spiffs(); break; } + case CMD_SPIFFS_CHECK: { + rdv40_spiffs_check(); + break; + } case CMD_SPIFFS_MOUNT: { rdv40_spiffs_lazy_mount(); break; @@ -1901,6 +1905,11 @@ void __attribute__((noreturn)) AppMain(void) { #ifdef WITH_FLASH // If flash is not present, BUSY_TIMEOUT kicks in, let's do it after USB loadT55xxConfig(); + + // + // Enforce a spiffs check/garbage collection at boot so we are likely to never + // fall under the 2 contigous free blocks availables + rdv40_spiffs_check(); #endif for (;;) { diff --git a/armsrc/spiffs.c b/armsrc/spiffs.c index df827b4e3..18f20187c 100644 --- a/armsrc/spiffs.c +++ b/armsrc/spiffs.c @@ -22,9 +22,11 @@ // case, will ensure a flush by rollbacking to previous Unmounted state #define RDV40_SPIFFS_CACHE_SZ ((LOG_PAGE_SIZE + 32) * 4) #define SPIFFS_FD_SIZE (32) -#define RDV40_SPIFFS_MAX_FD (2) +#define RDV40_SPIFFS_MAX_FD (3) #define RDV40_SPIFFS_FDBUF_SZ (SPIFFS_FD_SIZE * RDV40_SPIFFS_MAX_FD) +#define RDV40_LLERASE_BLOCKSIZE (64*1024) + #define RDV40_SPIFFS_LAZY_HEADER \ int changed = 0; \ if ((level == RDV40_SPIFFS_SAFETY_LAZY) || (level == RDV40_SPIFFS_SAFETY_SAFE)) { \ @@ -43,12 +45,6 @@ RDV40_SPIFFS_SAFE_FOOTER #include "spiffs.h" -#include "flashmem.h" -#include "dbprint.h" -#include "printf.h" -#include "common.h" -#include "string.h" -#include "BigBuf.h" ///// FLASH LEVEL R/W/E operations for feeding SPIFFS Driver///////////////// static s32_t rdv40_spiffs_llread(u32_t addr, u32_t size, u8_t *dst) { @@ -70,28 +66,29 @@ static s32_t rdv40_spiffs_llwrite(u32_t addr, u32_t size, u8_t *src) { static s32_t rdv40_spiffs_llerase(u32_t addr, u32_t size) { + + uint8_t erased = 0; + if (!FlashInit()) { return 130; } - - uint32_t bytes_erased = 0, bytes_remaining = size; - while (bytes_remaining > 0) { - - addr += bytes_erased; + if (DBGLEVEL > 2) Dbprintf("LLERASEDBG : Orig addr : %d\n", addr); + uint8_t block, sector = 0; + block = addr / RDV40_LLERASE_BLOCKSIZE; + if (block){ + addr = addr - (block*RDV40_LLERASE_BLOCKSIZE); + } + if (DBGLEVEL > 2) Dbprintf("LLERASEDBG : Result addr : %d\n", addr); + sector = addr / SPIFFS_CFG_LOG_BLOCK_SZ; Flash_CheckBusy(BUSY_TIMEOUT); Flash_WriteEnable(); - FlashSendByte(SECTORERASE); - Flash_TransferAdresse(addr); - FlashSendLastByte(0); - - bytes_remaining -= 4096; - bytes_erased += 4096; - } + if (DBGLEVEL > 2) Dbprintf("LLERASEDBG : block : %d, sector : %d \n", block, sector); + erased = Flash_Erase4k(block, sector); Flash_CheckBusy(BUSY_TIMEOUT); FlashStop(); - return SPIFFS_OK; + return SPIFFS_OK == erased ; } //////////////////////////////////////////////////////////////////////////////// @@ -162,6 +159,15 @@ int rdv40_spiffs_unmount() { } return ret; } + +int rdv40_spiffs_check() { + rdv40_spiffs_lazy_mount(); + SPIFFS_check(&fs); + SPIFFS_gc_quick(&fs,0); + rdv40_spiffs_lazy_unmount(); + rdv40_spiffs_lazy_mount(); + return SPIFFS_gc(&fs,8192) == SPIFFS_OK; +} //////////////////////////////////////////////////////////////////////////////// ///// Base RDV40_SPIFFS_SAFETY_NORMAL operations//////////////////////////////// @@ -533,21 +539,16 @@ void rdv40_spiffs_safe_print_fsinfo() { rdv40_spiffs_fsinfo fsinfo; rdv40_spiffs_getfsinfo(&fsinfo, RDV40_SPIFFS_SAFETY_SAFE); DbpString(_BLUE_("Flash Memory FileSystem Info (SPIFFS)")); -// Dbprintf("-------------------------------------"); - Dbprintf(" Logical Block Size........." _YELLOW_("%d")"bytes", fsinfo.blockSize); - Dbprintf(" Logical Page Size.........." _YELLOW_("%d")"bytes", fsinfo.pageSize); - Dbprintf(""); - Dbprintf(" Max Open Files............." _YELLOW_("%d")"file descriptors", fsinfo.maxOpenFiles); - Dbprintf(" Max Path Length............" _YELLOW_("%d")"chars", fsinfo.maxPathLength); -// DbpString(_BLUE_("Details")); - DbpString(""); - Dbprintf(" Filesystem\tSize\tUsed\tAvailable\tUse%\tMounted on"); - Dbprintf(" spiffs \t%d B\t%d B\t%d B\t\t"_YELLOW_("%d%")"\t/" - , fsinfo.totalBytes - , fsinfo.usedBytes - , fsinfo.freeBytes - , fsinfo.usedPercent - ); + Dbprintf("-------------------------------------"); + Dbprintf("* Filesystem Logical Block Size.........%d bytes", fsinfo.blockSize); + Dbprintf("* Filesystem Logical Page Size..........%d bytes", fsinfo.pageSize); + Dbprintf("--"); + Dbprintf("* Filesystem Max Open Files.............%d file descriptors", fsinfo.maxOpenFiles); + Dbprintf("* Filesystem Max Path Length............%d chars", fsinfo.maxPathLength); + Dbprintf("--"); + Dbprintf("Filesystem\tSize\tUsed\tAvailable\tUse%\tMounted on"); + Dbprintf("spiffs\t%dB\t%dB\t%dB\t\t%d%\t/", fsinfo.totalBytes, fsinfo.usedBytes, fsinfo.freeBytes, + fsinfo.usedPercent); } // this function is safe and WILL rollback since it is only a PRINTING function, diff --git a/armsrc/spiffs.h b/armsrc/spiffs.h index 29e8215b0..d75335e40 100644 --- a/armsrc/spiffs.h +++ b/armsrc/spiffs.h @@ -7,8 +7,9 @@ #ifndef SPIFFS_H_ #define SPIFFS_H_ - -#include "common.h" +#if defined(__cplusplus) +extern "C" { +#endif #include "spiffs_config.h" @@ -32,7 +33,7 @@ typedef struct rdv40_spiffs_fsinfo { int rdv40_spiffs_read_as_filetype(char *filename, uint8_t *dst, uint32_t size, RDV40SpiFFSSafetyLevel level); - +int rdv40_spiffs_check(); int rdv40_spiffs_lazy_unmount(); int rdv40_spiffs_lazy_mount(); int rdv40_spiffs_lazy_mount_rollback(int changed); @@ -853,5 +854,8 @@ u32_t SPIFFS_buffer_bytes_for_cache(spiffs *fs, u32_t num_pages); #if SPIFFS_CACHE #endif +#if defined(__cplusplus) +} +#endif #endif /* SPIFFS_H_ */ diff --git a/armsrc/spiffs_cache.c b/armsrc/spiffs_cache.c index f86133be4..98acc4c2f 100644 --- a/armsrc/spiffs_cache.c +++ b/armsrc/spiffs_cache.c @@ -39,17 +39,17 @@ static s32_t spiffs_cache_page_free(spiffs *fs, int ix, u8_t write_back) { (cp->flags & SPIFFS_CACHE_FLAG_TYPE_WR) == 0 && (cp->flags & SPIFFS_CACHE_FLAG_DIRTY)) { u8_t *mem = spiffs_get_cache_page(fs, cache, ix); - SPIFFS_CACHE_DBG("CACHE_FREE: write cache page "_SPIPRIi" pix "_SPIPRIpg"\n", ix, cp->pix); + SPIFFS_CACHE_DBG("CACHE_FREE: write cache page "_SPIPRIi" pix "_SPIPRIpg"\n", ix, cp->ucache.spix.pix); res = SPIFFS_HAL_WRITE(fs, SPIFFS_PAGE_TO_PADDR(fs, cp->ucache.spix.pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), mem); } #if SPIFFS_CACHE_WR if (cp->flags & SPIFFS_CACHE_FLAG_TYPE_WR) { - SPIFFS_CACHE_DBG("CACHE_FREE: free cache page "_SPIPRIi" objid "_SPIPRIid"\n", ix, cp->obj_id); + SPIFFS_CACHE_DBG("CACHE_FREE: free cache page "_SPIPRIi" objid "_SPIPRIid"\n", ix, cp->ucache.swrc.obj_id); } else #endif { - SPIFFS_CACHE_DBG("CACHE_FREE: free cache page "_SPIPRIi" pix "_SPIPRIpg"\n", ix, cp->pix); + SPIFFS_CACHE_DBG("CACHE_FREE: free cache page "_SPIPRIi" pix "_SPIPRIpg"\n", ix, cp->ucache.spix.pix); } cache->cpage_use_map &= ~(1 << ix); cp->flags = 0; @@ -156,7 +156,7 @@ s32_t spiffs_phys_rd( if (cp) { cp->flags = SPIFFS_CACHE_FLAG_WRTHRU; cp->ucache.spix.pix = SPIFFS_PADDR_TO_PAGE(fs, addr); - SPIFFS_CACHE_DBG("CACHE_ALLO: allocated cache page "_SPIPRIi" for pix "_SPIPRIpg "\n", cp->ix, cp->pix); + SPIFFS_CACHE_DBG("CACHE_ALLO: allocated cache page "_SPIPRIi" for pix "_SPIPRIpg "\n", cp->ix, cp->ucache.spix.pix); s32_t res2 = SPIFFS_HAL_READ(fs, addr - SPIFFS_PADDR_TO_PAGE_OFFSET(fs, addr), diff --git a/armsrc/spiffs_config.h b/armsrc/spiffs_config.h index 6fe1f48c6..7710a65a8 100644 --- a/armsrc/spiffs_config.h +++ b/armsrc/spiffs_config.h @@ -8,7 +8,22 @@ #ifndef SPIFFS_CONFIG_H_ #define SPIFFS_CONFIG_H_ -#include "common.h" +// ----------- 8< ------------ +// Following includes are for the linux test build of spiffs +// These may/should/must be removed/altered/replaced in your target +//#include +//#include +// +#include "printf.h" +#include "string.h" +#include "flashmem.h" + +void Dbprintf(const char *fmt, ...); + +//#include +//#include +// ----------- >8 ------------ + typedef int s32_t; typedef uint32_t u32_t; @@ -26,7 +41,7 @@ typedef uint8_t u8_t; #endif // Set spiffs debug output call for garbage collecting. #ifndef SPIFFS_GC_DBG -#define SPIFFS_GC_DBG(_f, ...) +#define SPIFFS_GC_DBG(_f, ...) //Dbprintf(_f, ## __VA_ARGS__) #define SPIFFS_GC_DBGF(str) SPIFFS_GC_DBG(str,NULL) #endif // Set spiffs debug output call for caching. @@ -36,7 +51,7 @@ typedef uint8_t u8_t; #endif // Set spiffs debug output call for system consistency checks. #ifndef SPIFFS_CHECK_DBG -#define SPIFFS_CHECK_DBG(_f, ...) //SPIFFS_CHECK_DBG(_f, ## __VA_ARGS__) +#define SPIFFS_CHECK_DBG(_f, ...) //Dbprintf(_f, ## __VA_ARGS__) #define SPIFFS_CHECK_DBGF(str) SPIFFS_CHECK_DBG(str,NULL) #endif // Set spiffs debug output call for all api invocations. diff --git a/client/cmdflashmemspiffs.c b/client/cmdflashmemspiffs.c index a3f9b950a..f53e17915 100644 --- a/client/cmdflashmemspiffs.c +++ b/client/cmdflashmemspiffs.c @@ -39,6 +39,13 @@ static int CmdFlashMemSpiFFSTest(const char *Cmd) { return PM3_SUCCESS; } +static int CmdFlashMemSpiFFSCheck(const char *Cmd) { + (void)Cmd; // Cmd is not used so far + clearCommandBuffer(); + SendCommandNG(CMD_SPIFFS_CHECK, NULL, 0); + return PM3_SUCCESS; +} + static int CmdFlashMemSpiFFSTree(const char *Cmd) { (void)Cmd; // Cmd is not used so far clearCommandBuffer(); @@ -439,6 +446,7 @@ static command_t CommandTable[] = { "copy", CmdFlashMemSpiFFSCopy, IfPm3Flash, "Copy a file to another (destructively) in SPIFFS FileSystem in FlashMEM (spiffs)" }, + {"check", CmdFlashMemSpiFFSCheck, IfPm3Flash, "Check/try to defrag faulty/fragmented Filesystem"}, {"dump", CmdFlashMemSpiFFSDump, IfPm3Flash, "Dump a file from SPIFFS FileSystem in FlashMEM (spiffs)"}, {"info", CmdFlashMemSpiFFSInfo, IfPm3Flash, "Print filesystem info and usage statistics (spiffs)"}, {"load", CmdFlashMemSpiFFSLoad, IfPm3Flash, "Upload file into SPIFFS Filesystem (spiffs)"}, diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 3d7b156bd..742f45f6e 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -299,6 +299,7 @@ typedef struct { #define CMD_SPIFFS_PRINT_FSINFO 0x2133 #define CMD_SPIFFS_DOWNLOAD 0x2134 #define CMD_SPIFFS_DOWNLOADED 0x2135 +#define CMD_SPIFFS_CHECK 0x3000 // more ? From 0ace6bffb821c13b07cabd95ec74f69308cace17 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 13 Aug 2019 17:16:43 +0200 Subject: [PATCH 0314/1854] missing includes for spiffs --- armsrc/appmain.h | 1 - armsrc/spiffs.c | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/armsrc/appmain.h b/armsrc/appmain.h index fa35714e3..141c943f9 100644 --- a/armsrc/appmain.h +++ b/armsrc/appmain.h @@ -34,7 +34,6 @@ void __attribute__((noreturn)) AppMain(void); uint16_t AvgAdc(int ch); -void print_result(char *name, uint8_t *buf, size_t len); //void PrintToSendBuffer(void); void ToSendStuffBit(int b); void ToSendReset(void); diff --git a/armsrc/spiffs.c b/armsrc/spiffs.c index 18f20187c..e642a0e29 100644 --- a/armsrc/spiffs.c +++ b/armsrc/spiffs.c @@ -45,6 +45,8 @@ RDV40_SPIFFS_SAFE_FOOTER #include "spiffs.h" +#include "BigBuf.h" +#include "dbprint.h" ///// FLASH LEVEL R/W/E operations for feeding SPIFFS Driver///////////////// static s32_t rdv40_spiffs_llread(u32_t addr, u32_t size, u8_t *dst) { From 763c94334b7f61dc06e962f9386f3d72650736e2 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 13 Aug 2019 17:27:52 +0200 Subject: [PATCH 0315/1854] add missing includes and fix mf1ksim usage in hf_colin standalone mode --- armsrc/Standalone/hf_colin.c | 18 +++++++++++++++++- armsrc/Standalone/hf_colin.h | 4 ++++ armsrc/iso14443a.h | 1 + 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/armsrc/Standalone/hf_colin.c b/armsrc/Standalone/hf_colin.c index 4fe898a18..21df29b9d 100644 --- a/armsrc/Standalone/hf_colin.c +++ b/armsrc/Standalone/hf_colin.c @@ -8,7 +8,23 @@ //----------------------------------------------------------------------------- // main code for HF Mifare aka ColinRun by Colin Brigato //----------------------------------------------------------------------------- + +#include "standalone.h" // standalone definitions + #include "hf_colin.h" +#include "proxmark3_arm.h" +#include "appmain.h" +#include "fpgaloader.h" +#include "dbprint.h" +#include "ticks.h" +#include "util.h" +#include "commonutil.h" +#include "BigBuf.h" +#include "iso14443a.h" +#include "mifareutil.h" +#include "mifaresim.h" +#include "vtsend.h" +#include "spiffs.h" #include "frozen.h" #define MF1KSZ 1024 @@ -733,7 +749,7 @@ readysim: DbprintfEx(FLAG_NEWLINE,"\n\n\n\n\n\n\n\nn\n\nn\n\n\nflags: %d (0x%02x)",flags,flags); cjSetCursLeft(); SpinOff(1000); - Mifare1ksim(flags , 0, cjuid); + Mifare1ksim(flags , 0, cjuid, 0, 0); LED_C_OFF(); SpinOff(50); vtsend_cursor_position_restore(NULL); diff --git a/armsrc/Standalone/hf_colin.h b/armsrc/Standalone/hf_colin.h index ca65a6df4..a4b870abc 100644 --- a/armsrc/Standalone/hf_colin.h +++ b/armsrc/Standalone/hf_colin.h @@ -9,6 +9,10 @@ // StandAlone Mod //----------------------------------------------------------------------------- +#include +#include +#include + #ifndef FALSE #define FALSE 0 #endif diff --git a/armsrc/iso14443a.h b/armsrc/iso14443a.h index e4ea7f0df..1bea3a1b9 100644 --- a/armsrc/iso14443a.h +++ b/armsrc/iso14443a.h @@ -16,6 +16,7 @@ #include "common.h" #include "mifare.h" // struct #include "pm3_cmd.h" +#include "crc16.h" // compute_crc // When the PM acts as tag and is receiving it takes // 2 ticks delay in the RF part (for the first falling edge), From 3771c150f0345b85e1109197306bf2269db9c1b6 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 13 Aug 2019 17:42:03 +0200 Subject: [PATCH 0316/1854] make style --- armsrc/Standalone/hf_colin.c | 4 ++-- armsrc/appmain.c | 2 +- armsrc/spiffs.c | 36 ++++++++++++++++++------------------ 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/armsrc/Standalone/hf_colin.c b/armsrc/Standalone/hf_colin.c index 21df29b9d..265b7e3c9 100644 --- a/armsrc/Standalone/hf_colin.c +++ b/armsrc/Standalone/hf_colin.c @@ -746,10 +746,10 @@ readysim: //flags = 0x10; uint16_t flags = 0; flags = 16; - DbprintfEx(FLAG_NEWLINE,"\n\n\n\n\n\n\n\nn\n\nn\n\n\nflags: %d (0x%02x)",flags,flags); + DbprintfEx(FLAG_NEWLINE, "\n\n\n\n\n\n\n\nn\n\nn\n\n\nflags: %d (0x%02x)", flags, flags); cjSetCursLeft(); SpinOff(1000); - Mifare1ksim(flags , 0, cjuid, 0, 0); + Mifare1ksim(flags, 0, cjuid, 0, 0); LED_C_OFF(); SpinOff(50); vtsend_cursor_position_restore(NULL); diff --git a/armsrc/appmain.c b/armsrc/appmain.c index c54ff7255..b593c826b 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1906,7 +1906,7 @@ void __attribute__((noreturn)) AppMain(void) { // If flash is not present, BUSY_TIMEOUT kicks in, let's do it after USB loadT55xxConfig(); - // + // // Enforce a spiffs check/garbage collection at boot so we are likely to never // fall under the 2 contigous free blocks availables rdv40_spiffs_check(); diff --git a/armsrc/spiffs.c b/armsrc/spiffs.c index e642a0e29..cb4412264 100644 --- a/armsrc/spiffs.c +++ b/armsrc/spiffs.c @@ -74,18 +74,18 @@ static s32_t rdv40_spiffs_llerase(u32_t addr, u32_t size) { if (!FlashInit()) { return 130; } - if (DBGLEVEL > 2) Dbprintf("LLERASEDBG : Orig addr : %d\n", addr); - uint8_t block, sector = 0; - block = addr / RDV40_LLERASE_BLOCKSIZE; - if (block){ - addr = addr - (block*RDV40_LLERASE_BLOCKSIZE); - } - if (DBGLEVEL > 2) Dbprintf("LLERASEDBG : Result addr : %d\n", addr); - sector = addr / SPIFFS_CFG_LOG_BLOCK_SZ; - Flash_CheckBusy(BUSY_TIMEOUT); - Flash_WriteEnable(); - if (DBGLEVEL > 2) Dbprintf("LLERASEDBG : block : %d, sector : %d \n", block, sector); - erased = Flash_Erase4k(block, sector); + if (DBGLEVEL > 2) Dbprintf("LLERASEDBG : Orig addr : %d\n", addr); + uint8_t block, sector = 0; + block = addr / RDV40_LLERASE_BLOCKSIZE; + if (block) { + addr = addr - (block * RDV40_LLERASE_BLOCKSIZE); + } + if (DBGLEVEL > 2) Dbprintf("LLERASEDBG : Result addr : %d\n", addr); + sector = addr / SPIFFS_CFG_LOG_BLOCK_SZ; + Flash_CheckBusy(BUSY_TIMEOUT); + Flash_WriteEnable(); + if (DBGLEVEL > 2) Dbprintf("LLERASEDBG : block : %d, sector : %d \n", block, sector); + erased = Flash_Erase4k(block, sector); Flash_CheckBusy(BUSY_TIMEOUT); FlashStop(); @@ -163,12 +163,12 @@ int rdv40_spiffs_unmount() { } int rdv40_spiffs_check() { - rdv40_spiffs_lazy_mount(); - SPIFFS_check(&fs); - SPIFFS_gc_quick(&fs,0); - rdv40_spiffs_lazy_unmount(); - rdv40_spiffs_lazy_mount(); - return SPIFFS_gc(&fs,8192) == SPIFFS_OK; + rdv40_spiffs_lazy_mount(); + SPIFFS_check(&fs); + SPIFFS_gc_quick(&fs, 0); + rdv40_spiffs_lazy_unmount(); + rdv40_spiffs_lazy_mount(); + return SPIFFS_gc(&fs, 8192) == SPIFFS_OK; } //////////////////////////////////////////////////////////////////////////////// From 847b6bcc3370e89894ca6236caeec434752a76de Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 13 Aug 2019 17:51:11 +0200 Subject: [PATCH 0317/1854] remove tabs --- Makefile | 11 ++++++++--- doc/cheatsheet.md | 2 +- fpga/fpga_lf.v | 14 +++++++------- fpga/lo_adc.v | 20 ++++++++++---------- include/pm3_cmd.h | 2 +- 5 files changed, 27 insertions(+), 22 deletions(-) diff --git a/Makefile b/Makefile index 58c61281f..9be67311b 100644 --- a/Makefile +++ b/Makefile @@ -164,11 +164,16 @@ style: # Detecting weird codepages and tabs. checks: - find . \( -name "*.[ch]" -or -name "*.cpp" -or -name "*.lua" -or -name "*.py" -or -name "*.pl" -or -name "Makefile" -or -name "*.v" \) \ + @echo "Files with suspicious chars:" + @find . \( -name "*.[ch]" -or -name "*.cpp" -or -name "*.lua" -or -name "*.py" -or -name "*.pl" -or -name "Makefile" -or -name "*.v" \) \ -exec sh -c "cat {} |recode utf8.. >/dev/null || echo {}" \; - find . \( -name "*.[ch]" -or \( -name "*.cpp" -and -not -name "*.moc.cpp" \) -or -name "*.lua" -or -name "*.py" -or -name "*.pl" -or -name "*.md" -or -name "*.txt" -or -name "*.awk" -or -name "*.v" \) \ - -exec grep -lP '\t' {} \; + @echo "Files with tabs:" # to remove tabs within lines, one can try with: vi $file -c ':set tabstop=4' -c ':set et|retab' -c ':wq' + @find . \( -name "*.[ch]" -or \( -name "*.cpp" -and -not -name "*.moc.cpp" \) -or -name "*.lua" -or -name "*.py" -or -name "*.pl" -or -name "*.md" -or -name "*.txt" -or -name "*.awk" -or -name "*.v" \) \ + -exec grep -lP '\t' {} \; +# @echo "Files with printf \\\\t:" +# @find . \( -name "*.[ch]" -or \( -name "*.cpp" -and -not -name "*.moc.cpp" \) -or -name "*.lua" -or -name "*.py" -or -name "*.pl" -or -name "*.md" -or -name "*.txt" -or -name "*.awk" -or -name "*.v" \) \ +# -exec grep -lP '\\t' {} \; # Dummy target to test for GNU make availability _test: diff --git a/doc/cheatsheet.md b/doc/cheatsheet.md index 3fcaf9876..ecef56d9d 100644 --- a/doc/cheatsheet.md +++ b/doc/cheatsheet.md @@ -448,7 +448,7 @@ Convert .bin to .eml ``` Options --- -i : Specifies the dump-file (input). If omitted, 'dumpdata.bin' is used +i : Specifies the dump-file (input). If omitted, 'dumpdata.bin' is used script run dumptoemul -i xxxxxxxxxxxxxx.bin ``` diff --git a/fpga/fpga_lf.v b/fpga/fpga_lf.v index 20d2ca440..88b22b7ca 100644 --- a/fpga/fpga_lf.v +++ b/fpga/fpga_lf.v @@ -102,13 +102,13 @@ lo_edge_detect le( ); lo_adc la( - pck0, - la_pwr_lo, la_pwr_hi, la_pwr_oe1, la_pwr_oe2, la_pwr_oe3, la_pwr_oe4, - adc_d, la_adc_clk, - la_ssp_frame, la_ssp_din, ssp_dout, la_ssp_clk, - cross_hi, cross_lo, - la_dbg, divisor, - lo_is_125khz, lf_field + pck0, + la_pwr_lo, la_pwr_hi, la_pwr_oe1, la_pwr_oe2, la_pwr_oe3, la_pwr_oe4, + adc_d, la_adc_clk, + la_ssp_frame, la_ssp_din, ssp_dout, la_ssp_clk, + cross_hi, cross_lo, + la_dbg, divisor, + lo_is_125khz, lf_field ); // Major modes: diff --git a/fpga/lo_adc.v b/fpga/lo_adc.v index dff9fda3f..57e9eebc8 100644 --- a/fpga/lo_adc.v +++ b/fpga/lo_adc.v @@ -55,28 +55,28 @@ assign ssp_frame = (pck_divider[7:3] == 5'd1) && !clk_state; always @(posedge pck0) begin - if(pck_divider == divisor[7:0]) + if(pck_divider == divisor[7:0]) begin - pck_divider <= 8'd0; - clk_state = !clk_state; + pck_divider <= 8'd0; + clk_state = !clk_state; end - else - begin - pck_divider <= pck_divider + 1; - end + else + begin + pck_divider <= pck_divider + 1; + end end always @(posedge pck0) begin - if((pck_divider == 8'd7) && !clk_state) + if((pck_divider == 8'd7) && !clk_state) begin to_arm_shiftreg <= adc_d; end else - begin + begin to_arm_shiftreg[7:1] <= to_arm_shiftreg[6:0]; to_arm_shiftreg[0] <= 1'b0; - end + end end endmodule diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 742f45f6e..035e85405 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -299,7 +299,7 @@ typedef struct { #define CMD_SPIFFS_PRINT_FSINFO 0x2133 #define CMD_SPIFFS_DOWNLOAD 0x2134 #define CMD_SPIFFS_DOWNLOADED 0x2135 -#define CMD_SPIFFS_CHECK 0x3000 +#define CMD_SPIFFS_CHECK 0x3000 // more ? From 252929bed4d318fb50a882dc93344035cc4c0ac2 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 13 Aug 2019 20:30:19 +0200 Subject: [PATCH 0318/1854] fix lf read command parsing bug --- client/cmdlf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdlf.c b/client/cmdlf.c index cf8e60f82..366f2ed0e 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -453,7 +453,7 @@ int CmdLFRead(const char *Cmd) { cmdp++; break; case 'd': - samples = param_get32ex(Cmd, cmdp, 0, 10); + samples = param_get32ex(Cmd, cmdp + 1, 0, 10); cmdp += 2; break; default: From db0ac1639b5d811a6f22c8bddc5a7219f3f2dce3 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 13 Aug 2019 22:57:54 +0200 Subject: [PATCH 0319/1854] em4x watch & read: collect enough samples to cover EM XL tags --- client/cmdlfem4x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c index a87fd46eb..c04e64c00 100644 --- a/client/cmdlfem4x.c +++ b/client/cmdlfem4x.c @@ -442,7 +442,7 @@ static int CmdEM410xDemod(const char *Cmd) { // this read is the "normal" read, which download lf signal and tries to demod here. static int CmdEM410xRead(const char *Cmd) { - lf_read(true, 8192); + lf_read(true, 12288); return CmdEM410xDemod(Cmd); } @@ -599,7 +599,7 @@ static int CmdEM410xWatch(const char *Cmd) { PrintAndLogEx(WARNING, "\naborted via keyboard!\n"); break; } - lf_read(true, 8201); + lf_read(true, 12288); } while (CmdEM410xRead("") != PM3_SUCCESS); return PM3_SUCCESS; From ea601f4052d044915782b5adf0a321018a9c6f70 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 14 Aug 2019 21:52:20 +0200 Subject: [PATCH 0320/1854] fix reveng for all platforms else than WIN32 --- CHANGELOG.md | 1 + client/Makefile | 33 +++++++++++++++++++++------------ client/reveng/bmpbit.c | 2 +- client/reveng/config.h | 34 ++++++++++++++++++++++------------ 4 files changed, 45 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a6aab7919..b5f7d8d76 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Fix reveng integration for all platforms else than WIN32 (@doegox) - Add cheat sheet for easy operations of the Proxmark3 (scund00r) - Chg commands are now in green in the helptext list (@iceman1001) - Fix 'script run ndefdump' - better exit messages when failing (@iceman1001) diff --git a/client/Makefile b/client/Makefile index adf83cb18..89f8cfb44 100644 --- a/client/Makefile +++ b/client/Makefile @@ -22,6 +22,8 @@ TAR = tar TARFLAGS = -C .. --ignore-failed-read -rvf RM = rm -f MV = mv +TOUCH = touch +FALSE = false ENV_LDFLAGS := $(LDFLAGS) ENV_CFLAGS := $(CFLAGS) @@ -52,11 +54,11 @@ MBEDTLSLIBPATH = ../common/mbedtls MBEDTLSLIB = $(MBEDTLSLIBPATH)/libmbedtls.a CBORLIBPATH = ./tinycbor CBORLIB = $(CBORLIBPATH)/tinycbor.a +REVENGFLAGS = -DPRESETS LIBS = -I../common/zlib -Iuart -I$(LUALIBPATH) -I$(MBEDTLSLIBPATH) -I$(JANSSONLIBPATH) -I$(CBORLIBPATH) INCLUDES_CLIENT = -I. -I../include -I../common -I/opt/local/include $(LIBS) LDFLAGS = $(ENV_LDFLAGS) - -CFLAGS = $(ENV_CFLAGS) -std=c99 -D_ISOC99_SOURCE -DPRESETS $(INCLUDES_CLIENT) -Wall -Werror -g -O3 +CFLAGS = $(ENV_CFLAGS) -std=c99 -D_ISOC99_SOURCE $(REVENGFLAGS) $(INCLUDES_CLIENT) -Wall -Werror -g -O3 ifneq (,$(findstring MINGW,$(platform))) CFLAGS += -mno-ms-bitfields endif @@ -239,12 +241,6 @@ CMDSRCS = crapto1/crapto1.c \ cmdscript.c \ pm3_bitlib.c \ cmdcrc.c \ - reveng/preset.c \ - reveng/reveng.c \ - reveng/cli.c \ - reveng/bmpbit.c \ - reveng/model.c \ - reveng/poly.c \ bucketsort.c cpu_arch = $(shell uname -m) @@ -262,12 +258,20 @@ ZLIBSRCS = deflate.c adler32.c trees.c zutil.c inflate.c inffast.c inftrees.c ZLIBFLAGS = -DZ_SOLO -DZ_PREFIX -DNO_GZIP -DZLIB_PM3_TUNED #-DDEBUG -Dverbose=1 +REVENGSRCS = reveng/preset.c \ + reveng/reveng.c \ + reveng/cli.c \ + reveng/bmpbit.c \ + reveng/model.c \ + reveng/poly.c + QTGUISRCS = proxgui.cpp proxguiqt.cpp proxguiqt.moc.cpp guidummy.cpp COREOBJS = $(CORESRCS:%.c=$(OBJDIR)/%.o) CMDOBJS = $(CMDSRCS:%.c=$(OBJDIR)/%.o) OBJCOBJS = $(OBJCSRCS:%.m=$(OBJDIR)/%.o) ZLIBOBJS = $(ZLIBSRCS:%.c=$(OBJDIR)/%.o) +REVENGOBJS = $(REVENGSRCS:%.c=$(OBJDIR)/%.o) MULTIARCHOBJS = $(MULTIARCHSRCS:%.c=$(OBJDIR)/%_NOSIMD.o) \ $(MULTIARCHSRCS:%.c=$(OBJDIR)/%_MMX.o) \ $(MULTIARCHSRCS:%.c=$(OBJDIR)/%_SSE2.o) \ @@ -292,7 +296,7 @@ ifeq "$(SUPPORTS_AVX512)" "True" endif BINS = proxmark3 flasher -CLEAN = $(BINS) $(DEPENDENCY_FILES) $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(ZLIBOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(OBJDIR)/*.o *.moc.cpp ui/ui_overlays.h lualibs/pm3_cmd.lua lualibs/mf_default_keys.lua +CLEAN = $(BINS) $(DEPENDENCY_FILES) $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(ZLIBOBJS) $(REVENGOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(OBJDIR)/*.o *.moc.cpp ui/ui_overlays.h lualibs/pm3_cmd.lua lualibs/mf_default_keys.lua reveng/bmptst # need to assign dependancies to build these first... all: lua_build jansson_build mbedtls_build cbor_build $(BINS) @@ -301,9 +305,9 @@ all-static: LDLIBS:=-static $(LDLIBS) all-static: $(BINS) proxmark3: LDLIBS+=$(LUALIB) $(JANSSONLIB) $(MBEDTLSLIB) $(CBORLIB) $(QTLDLIBS) -proxmark3: $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(ZLIBOBJS) lualibs/pm3_cmd.lua lualibs/mf_default_keys.lua +proxmark3: reveng/bmptst $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(ZLIBOBJS) $(REVENGOBJS) lualibs/pm3_cmd.lua lualibs/mf_default_keys.lua $(info [=] LD $@) - $(Q)$(LD) $(LDFLAGS) $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(ZLIBOBJS) $(LDLIBS) -o $@ + $(Q)$(LD) $(LDFLAGS) $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(ZLIBOBJS) $(REVENGOBJS) $(LDLIBS) -o $@ flasher: $(OBJDIR)/flash.o $(OBJDIR)/flasher.o $(COREOBJS) $(OBJCOBJS) $(info [=] LD $@) @@ -354,6 +358,11 @@ cbor_build: $(info [*] MAKE tinycbor) $(Q)$(MAKE) --no-print-directory -C $(CBORLIBPATH) all + +reveng/bmptst: reveng/bmpbit.c reveng/config.h reveng/reveng.h + $(CC) $(CFLAGS) $(REVENGFLAGS) -DBMPTST -o $@ $< + ( ./$@ && $(TOUCH) $@ ) || ( $(RM) $@ && $(FALSE) ) + .PHONY: all clean # easy printing of MAKE VARIABLES @@ -419,7 +428,7 @@ $(OBJDIR)/%.o : %.m $(OBJDIR)/%.d # $(CXX) $(DEPFLAGS) $(CXXFLAGS) -c -o $@ $< # $(POSTCOMPILE) -DEPENDENCY_FILES = $(patsubst %.c, $(OBJDIR)/%.d, $(CORESRCS) $(CMDSRCS) $(ZLIBSRCS)) \ +DEPENDENCY_FILES = $(patsubst %.c, $(OBJDIR)/%.d, $(CORESRCS) $(CMDSRCS) $(ZLIBSRCS) $(REVENGSRCS)) \ $(patsubst %.o, %.d, $(MULTIARCHOBJS)) \ $(patsubst %.cpp, $(OBJDIR)/%.d, $(QTGUISRCS)) \ $(patsubst %.m, $(OBJDIR)/%.d, $(OBJCSRCS)) \ diff --git a/client/reveng/bmpbit.c b/client/reveng/bmpbit.c index d529b0e96..e44ddb250 100644 --- a/client/reveng/bmpbit.c +++ b/client/reveng/bmpbit.c @@ -67,7 +67,7 @@ main(int argc, char *argv[]) { setbmp(); if (BMP_BIT != bmpbit || BMP_SUB != bmpsub) { fprintf(stderr, "reveng: configuration fault. Update " - "config.h with these definitions and " + "reveng/config.h with these definitions and " "recompile:\n" "\t#define BMP_BIT %d\n" "\t#define BMP_SUB %d\n", diff --git a/client/reveng/config.h b/client/reveng/config.h index a4d46e9f2..55038b55a 100644 --- a/client/reveng/config.h +++ b/client/reveng/config.h @@ -57,33 +57,43 @@ /* #define ALWPCK 1 */ -/* Define PRESETS to compile CRC RevEng with the preset models from the +/* #define PRESETS 1 + * Define PRESETS to compile CRC RevEng with the preset models from the * CRC Catalogue. This implies BMPMACRO and so makes the code platform- * specific. */ -#ifdef _WIN32 -#define PRESETS 1 // -#endif - - -/* Macros defining the size of a bmp_t. +/* #define BMP_BIT 32 + * Macros defining the size of a bmp_t. * Their values only matter if PRESETS and/or BMPMACRO are defined, in * which case edit the macros below to suit your architecture. * Otherwise, BMP_BIT and BMP_SUB will be redefined as aliases of bmpbit * and bmpsub, global objects initialised at run time. */ -/* Size in bits of a bmp_t. Not necessarily a power of two. */ - -#define BMP_BIT 32 - -/* The highest power of two that is strictly less than BMP_BIT. +/* #define BMP_SUB 16 + * The highest power of two that is strictly less than BMP_BIT. * Initialises the index of a binary search for set bits in a bmp_t. */ + +#if UINTMAX_MAX == UINT64_MAX +// 64-bit +#define PRESETS 1 +#define BMP_BIT 64 +#define BMP_SUB 32 + +//#elif INTPTR_MAX == INT32_MAX +#elif UINTMAX_MAX == UINT32_MAX +// 32-bit +#define PRESETS 1 +#define BMP_BIT 32 #define BMP_SUB 16 +#else +#error Cannot determine automatically REVENG PRESETS Macros for your platform, you need to set them manually +#endif + /***************************************** * * * End of user configuration options * From 2f029d0d9db70caedef0e972c8a5841d9a5c3358 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 14 Aug 2019 21:54:43 +0200 Subject: [PATCH 0321/1854] remove comment --- client/reveng/config.h | 1 - 1 file changed, 1 deletion(-) diff --git a/client/reveng/config.h b/client/reveng/config.h index 55038b55a..b5498c5db 100644 --- a/client/reveng/config.h +++ b/client/reveng/config.h @@ -83,7 +83,6 @@ #define BMP_BIT 64 #define BMP_SUB 32 -//#elif INTPTR_MAX == INT32_MAX #elif UINTMAX_MAX == UINT32_MAX // 32-bit #define PRESETS 1 From a187968967a353fe70b751c812fa3018e9a9cca1 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 14 Aug 2019 22:19:52 +0200 Subject: [PATCH 0322/1854] Hmm, let's try to fix reveng on 32b --- client/reveng/config.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/reveng/config.h b/client/reveng/config.h index b5498c5db..ab7eb9aaa 100644 --- a/client/reveng/config.h +++ b/client/reveng/config.h @@ -77,13 +77,13 @@ */ -#if UINTMAX_MAX == UINT64_MAX +#if UINTPTR_MAX == UINT64_MAX // 64-bit #define PRESETS 1 #define BMP_BIT 64 #define BMP_SUB 32 -#elif UINTMAX_MAX == UINT32_MAX +#elif UINTPTR_MAX == UINT32_MAX // 32-bit #define PRESETS 1 #define BMP_BIT 32 From d770e4c57a8e5e95b679af00b3e0f9a6890096d9 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 14 Aug 2019 22:59:14 +0200 Subject: [PATCH 0323/1854] remove debugstatements --- client/reveng/poly.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/client/reveng/poly.c b/client/reveng/poly.c index 0fc6555d9..44f5709f4 100644 --- a/client/reveng/poly.c +++ b/client/reveng/poly.c @@ -600,9 +600,6 @@ plast(const poly_t poly) { idx = size - 1UL; while (idx && !(accu = poly.bitmap[idx])) --idx; - if (poly.length == 24) - printf("ICE plast B - poly.length %lu vs size %lu idx %lu bitmap %ld\n", poly.length, size, idx, poly.bitmap[idx]); - if (!idx && !(accu = poly.bitmap[idx])) return (0UL); /* now accu == poly.bitmap[idx] and contains last significant term */ @@ -1080,10 +1077,6 @@ praloc(poly_t *poly, unsigned long length) { if (poly->bitmap) { - if (poly->length == 24) - printf("ICE praloc - poly->length %lu\n", poly->length); - - if (poly->length < length) { /* poly->length >= 0, length > 0, size > 0. * poly expanded. clear old last word and all new words @@ -1094,15 +1087,11 @@ praloc(poly_t *poly, unsigned long length) { while (oldsize < size) poly->bitmap[oldsize++] = BMP_C(0); - if (poly->length == 24) printf("ICE praloc MISS A\n"); - } else if (LOFS(length)) { /* poly->length >= length > 0. * poly shrunk. clear new last word */ poly->bitmap[size - 1UL] &= ~(~BMP_C(0) >> LOFS(length)); - - if (poly->length == 24) printf("ICE praloc B size %lu, bm %lu \n", size, poly->bitmap[size - 1UL]); } poly->length = length; From f008b965d5b77e173c3f9718ee10481b221ec793 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 14 Aug 2019 23:06:14 +0200 Subject: [PATCH 0324/1854] missing include --- client/reveng/config.h | 1 + 1 file changed, 1 insertion(+) diff --git a/client/reveng/config.h b/client/reveng/config.h index ab7eb9aaa..ecf17773f 100644 --- a/client/reveng/config.h +++ b/client/reveng/config.h @@ -77,6 +77,7 @@ */ +#include #if UINTPTR_MAX == UINT64_MAX // 64-bit #define PRESETS 1 From 4d16f3e7d2404ad28642b2bc947d541b5eb1235d Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 15 Aug 2019 19:24:50 +0200 Subject: [PATCH 0325/1854] fix reveng: unsigned long on Mingw64 is only 32b, hopefully limits.h can help --- client/reveng/config.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/client/reveng/config.h b/client/reveng/config.h index ecf17773f..94d3c4da5 100644 --- a/client/reveng/config.h +++ b/client/reveng/config.h @@ -78,14 +78,15 @@ #include -#if UINTPTR_MAX == UINT64_MAX -// 64-bit +#include +#if ULONG_MAX == UINT64_MAX +// most 64-bit platforms #define PRESETS 1 #define BMP_BIT 64 #define BMP_SUB 32 -#elif UINTPTR_MAX == UINT32_MAX -// 32-bit +#elif ULONG_MAX == UINT32_MAX +// 32-bit platforms and Mingw64 #define PRESETS 1 #define BMP_BIT 32 #define BMP_SUB 16 From 271011911349af981a1a1c4b04ac2d44ce0ab9c7 Mon Sep 17 00:00:00 2001 From: Iceman Date: Thu, 15 Aug 2019 21:28:45 +0200 Subject: [PATCH 0326/1854] Update README.md --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1af5d2157..6829fdff1 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,9 @@ -# Proxmark3 RDV4.0 Dedicated Github +# RRG / Iceman repo, dedicated to Proxmark3 RDV4.0 This repo is based on iceman fork for Proxmark3. It is dedicated to bringing the most out of the new features for Proxmark3 RDV4.0 new hardware and design. -Note that it also supports other Proxmark3 platforms as well! + +_Note that it also supports other Proxmark3 platforms as well!_ + | Releases | Linux & OSX CI | Windows CI | | ------------------- |:-------------------:| -------------------:| From ca5fbc843882dfa1dbb19c49fcbb021b4ea358dc Mon Sep 17 00:00:00 2001 From: Iceman Date: Thu, 15 Aug 2019 21:32:00 +0200 Subject: [PATCH 0327/1854] Update README.md --- README.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 6829fdff1..23d412ff2 100644 --- a/README.md +++ b/README.md @@ -49,11 +49,14 @@ This fork now compiles just fine on If you intend to contribute to the code, please read the [coding style notes](HACKING.md) first. - Internal notes on [Coverity Scan Config & Run](/doc/md/Development/Coverity-Scan-Config-%26-Run.md). -- Internal notes on UART -- Internal notes on Frame format -- Internal notes on standalone mode - +- Internal notes on [UART](/doc/uart_notes.md) +- Internal notes on [Frame format](/doc/new_frame_format.md) +- Internal notes on [external flash](/doc/ext_flash_notes.md) +- Internal notes on [standalone mode](https://github.com/RfidResearchGroup/proxmark3/wiki/Standalone-mode) +- Internal notes on [Termux / Android](/doc/termux_notes.md) +## Cheat sheet +Thanks to Alex Dibs, you can enjoy a [command cheat sheet](/doc/cheatsheet.md) ## Why didn't you base it on official Proxmark3 Master? From d12b3c35f18e76c84b34fe9954d5e791b63b94da Mon Sep 17 00:00:00 2001 From: Iceman Date: Thu, 15 Aug 2019 21:32:54 +0200 Subject: [PATCH 0328/1854] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 23d412ff2..81c676b8d 100644 --- a/README.md +++ b/README.md @@ -42,8 +42,8 @@ This fork now compiles just fine on - Windows/mingw environment with Qt5.6.1 & GCC 4.8 - Ubuntu 1404, 1510, 1604, 1804, 1904 - Mac OS X / Homebrew - - ParrotOS - - WSL (Windows subsystem linux) on Windows 10 + - ParrotOS, Gentoo, Pentoo + - WSL, WSL2 (Windows subsystem linux) on Windows 10 - Docker container If you intend to contribute to the code, please read the [coding style notes](HACKING.md) first. From d99911a03d2bc7ce2acc849943fefa227bf2b29b Mon Sep 17 00:00:00 2001 From: Alex Dib Date: Fri, 16 Aug 2019 09:20:57 +1000 Subject: [PATCH 0329/1854] Cheatsheet update - Added commands & fixed typos --- doc/cheatsheet.md | 156 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 133 insertions(+), 23 deletions(-) diff --git a/doc/cheatsheet.md b/doc/cheatsheet.md index 8770b7551..06af60d56 100644 --- a/doc/cheatsheet.md +++ b/doc/cheatsheet.md @@ -1,5 +1,18 @@ # Cheatsheet +- [Generic](#Generic) +- [iClass](#iClass) +- [Mifare](#Mifare) +- [HID Prox](#HID-Prox) +- [Indala](#Indala) +- [Hitag](#Hitag) +- [T55XX](#T55XX) +- [Data](#Data) +- [Lua Scripts](#Lua-Scripts) +- [Memory](#Memory) +- [Sim Module](#Sim-Module) +- [Smart Card](#Smart-Card) + ## Generic Identify High Frequency cards @@ -22,6 +35,11 @@ Check versioning pm3 --> hw version ``` +Check overall status +``` +pm3 --> hw status +``` + ## iClass Reverse permute iClass master key @@ -158,20 +176,30 @@ Check for default keys Options --- <*card memory> [t|d|s|ss] -* - all sectors -card memory - 0 - MINI(320 bytes), 1 - 1K, 2 - 2K, 4 - 4K -d - write keys to binary file +* : all sectors +card memory : 0 - MINI(320 bytes), 1 - 1K, 2 - 2K, 4 - 4K +d : write keys to binary file pm3 --> hf mf chk *1 ? d default_keys.dic ``` +Check for default keys from local memory +``` +Options +--- +card memory : 0 - MINI(320 bytes), 1 - 1K, 2 - 2K, 4 - 4K +m : use dictionary from flashmemory + +pm3 --> hf mf fchk 1 m +``` + Dump Mifare card contents ``` Options --- -: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K -k : key filename, if no given, UID will be used as filename" -f : data filename, if no given, UID will be used as filename + : 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K +k : key filename, if no given, UID will be used as filename" +f : data filename, if no given, UID will be used as filename pm3 --> hf mf dump 1 pm3 --> hf mf dump 1 k hf-mf-A29558E4-key.bin f hf-mf-A29558E4-data.bin @@ -181,7 +209,7 @@ Convert .bin to .eml ``` Options --- -i ????????????? +i : Specifies the dump-file (input). If omitted, 'dumpdata.bin' is used pm3 --> script run dumptoemul -i dumpdata.bin ``` @@ -278,11 +306,11 @@ Brute force HID reader ``` Options --- -a : 26|33|34|35|37|40|44|84"); -f : 8-bit value HID facility code"); -c : (optional) cardnumber to start with, max 65535"); -d : delay betweens attempts in ms. Default 1000ms"); -v : verbose logging, show all tries"); +a : 26|33|34|35|37|40|44|84 +f : 8-bit value HID facility code +c : (optional) cardnumber to start with, max 65535 +d : delay betweens attempts in ms. Default 1000ms +v : verbose logging, show all tries pm3 --> lf hid brute a 26 f 224 pm3 --> lf hid brute v a 26 f 21 c 200 d 2000 @@ -334,7 +362,7 @@ HitagS: 02 : Read all pages, crypto mode. Set key=0 for no auth Hitag2: -21 : Read all pages, password mode. Default: 4D494B52 (\"MIKR\") +21 : Read all pages, password mode. Default: 4D494B52 ("MIKR") 22 : Read all pages, challenge mode 23 : Read all pages, crypto mode. Key format: ISK high + ISK low. Default: 4F4E4D494B52 ("ONMIKR") 25 : Test recorded authentications @@ -383,11 +411,11 @@ Detect T55XX card pm3 --> lf t55xx detect ``` -Configure demodulation +Configure modulation ``` Options --- - : Set demodulation + : Set modulation EM is ASK HID Prox is FSK Indala is PSK @@ -395,6 +423,16 @@ Indala is PSK pm3 --> lf t55xx config FSK ``` +Set timings to default +``` +Options +--- +p : persist to flashmemory +z : Set default t55x7 timings (use p to save if required) + +pm3 --> lf t55xx deviceconfig z p +``` + Write to T55xx block ``` b : block number to write. Between 0-7 @@ -405,24 +443,24 @@ pm3 --> lf t55xx wr b 0 d 00081040 Wipe a T55xx tag and set defaults ``` -lf t55xx wipe +pm3 --> lf t55xx wipe ``` ## Data Get raw samples [512-40000] ``` -data samples +pm3 --> data samples ``` Save samples to file ``` -data save +pm3 --> data save ``` Load samples from file ``` -data load +pm3 --> data load ``` ## Lua Scripts @@ -430,16 +468,16 @@ data load List Lua Scripts ``` -script list +pm3 --> script list ``` Convert .bin to .eml ``` Options --- -i : Specifies the dump-file (input). If omitted, 'dumpdata.bin' is used +i : Specifies the dump-file (input). If omitted, 'dumpdata.bin' is used -script run dumptoemul -i xxxxxxxxxxxxxx.bin +pm3 --> script run dumptoemul -i xxxxxxxxxxxxxx.bin ``` Format Mifare card @@ -451,5 +489,77 @@ n : the new key that will be written to the card a : the new access bytes that will be written to the card x : execute the commands aswell. -script run formatMifare -k FFFFFFFFFFFF -n FFFFFFFFFFFF -x +pm3 --> script run formatMifare -k FFFFFFFFFFFF -n FFFFFFFFFFFF -x +``` + +## Memory + +Load default keys into memory +``` +Options +--- +o : offset in memory +f : file name +m : upload 6 bytes keys (mifare key dictionary) +i : upload 8 bytes keys (iClass key dictionary) +t : upload 4 bytes keys (pwd dictionary) + +pm3 --> mem load f default_keys m +pm3 --> mem load f default_pwd t +pm3 --> mem load f default_iclass_keys i +``` + +## Sim Module + +Upgrade Sim Module firmware +``` +pm3 --> sc upgrade f ../tools/simmodule/SIM011.BIN +``` + +## Smart Card + +Get Smart Card Information +``` +pm3 --> sc info +``` + +Act like an IS07816 reader +``` +pm3 --> sc reader +``` + +Set clock speed +``` +Options +--- +c : clockspeed (0 = 16MHz, 1=8MHz, 2=4MHz) + +pm3 --> sc setclock c 2 +``` + +Send raw hex data +``` +Options +--- +r : do not read response +a : active smartcard without select (reset sc module) +s : active smartcard with select (get ATR) +t : executes TLV decoder if it possible +0 : use protocol T=0 +d : bytes to send + +pm3 --> sc raw s 0 d 00a404000e315041592e5359532e4444463031 : 1PAY.SYS.DDF01 PPSE directory with get ATR +pm3 --> sc raw 0 d 00a404000e325041592e5359532e4444463031 : 2PAY.SYS.DDF01 PPSE directory +pm3 --> sc raw 0 t d 00a4040007a0000000041010 : Mastercard +pm3 --> sc raw 0 t d 00a4040007a0000000031010 : Visa +```` + +Bruteforce SPI +``` +Options +--- +t : executes TLV decoder if it possible + +pm3 --> sc brute +pm3 --> sc brute t ``` From b8e054698ab3848f72813440462ab470f6e888fb Mon Sep 17 00:00:00 2001 From: Iceman Date: Fri, 16 Aug 2019 11:20:06 +0200 Subject: [PATCH 0330/1854] Update cheatsheet.md --- doc/cheatsheet.md | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/doc/cheatsheet.md b/doc/cheatsheet.md index 06af60d56..32068ce0e 100644 --- a/doc/cheatsheet.md +++ b/doc/cheatsheet.md @@ -1,17 +1,11 @@ # Cheatsheet +|||| +|---|---|---| +|[Generic](#Generic)|[iClass](#iClass)|[Mifare](#Mifare)| +|[HID Prox](#HID-Prox)|[Indala](#Indala)|[Hitag](#Hitag)| +|[T55XX](#T55XX)|[Data](#Data)|[Lua Scripts](#Lua-Scripts)| +|[Memory](#Memory)|[Sim Module](#Sim-Module)|[Smart Card](#Smart-Card)| -- [Generic](#Generic) -- [iClass](#iClass) -- [Mifare](#Mifare) -- [HID Prox](#HID-Prox) -- [Indala](#Indala) -- [Hitag](#Hitag) -- [T55XX](#T55XX) -- [Data](#Data) -- [Lua Scripts](#Lua-Scripts) -- [Memory](#Memory) -- [Sim Module](#Sim-Module) -- [Smart Card](#Smart-Card) ## Generic From 3408e31633500dc36011a5c1173c945870e35a2a Mon Sep 17 00:00:00 2001 From: Iceman Date: Fri, 16 Aug 2019 11:22:47 +0200 Subject: [PATCH 0331/1854] Update cheatsheet.md --- doc/cheatsheet.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/doc/cheatsheet.md b/doc/cheatsheet.md index 32068ce0e..78a080dd9 100644 --- a/doc/cheatsheet.md +++ b/doc/cheatsheet.md @@ -1,10 +1,12 @@ # Cheatsheet -|||| +|Genrice|LF|HF| |---|---|---| -|[Generic](#Generic)|[iClass](#iClass)|[Mifare](#Mifare)| -|[HID Prox](#HID-Prox)|[Indala](#Indala)|[Hitag](#Hitag)| -|[T55XX](#T55XX)|[Data](#Data)|[Lua Scripts](#Lua-Scripts)| -|[Memory](#Memory)|[Sim Module](#Sim-Module)|[Smart Card](#Smart-Card)| +|[Generic](#Generic)|[T55XX](#T55XX)|[Mifare](#Mifare)| +|[Data](#Data)|[HID Prox](#HID-Prox)|[iClass](#iClass)| +|[Memory](#Memory)|[Indala](#Indala)|| +|[Sim Module](#Sim-Module)|[Hitag](#Hitag)|| +|[Lua Scripts](#Lua-Scripts)||| +|[Smart Card](#Smart-Card)||| ## Generic From f2e77bfbe436c40930d548ac21886e7140d24165 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 17 Aug 2019 15:59:11 +0200 Subject: [PATCH 0332/1854] chg: some tabs converted --- client/cmdhficlass.c | 64 ++++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index f58d5377c..7badc7c86 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -322,31 +322,31 @@ static void fuse_config(const picopass_hdr *hdr) { uint8_t fuses = hdr->conf.fuses; if (isset(fuses, FUSE_FPERS)) - PrintAndLogEx(SUCCESS, "\tMode: Personalization [Programmable]"); + PrintAndLogEx(SUCCESS, " Mode: Personalization [Programmable]"); else - PrintAndLogEx(NORMAL, "\tMode: Application [Locked]"); + PrintAndLogEx(NORMAL, " Mode: Application [Locked]"); if (isset(fuses, FUSE_CODING1)) { - PrintAndLogEx(NORMAL, "\tCoding: RFU"); + PrintAndLogEx(NORMAL, " Coding: RFU"); } else { if (isset(fuses, FUSE_CODING0)) - PrintAndLogEx(NORMAL, "\tCoding: ISO 14443-2 B/ISO 15693"); + PrintAndLogEx(NORMAL, " Coding: ISO 14443-2 B/ISO 15693"); else - PrintAndLogEx(NORMAL, "\tCoding: ISO 14443B only"); + PrintAndLogEx(NORMAL, " Coding: ISO 14443B only"); } // 1 1 - if (isset(fuses, FUSE_CRYPT1) && isset(fuses, FUSE_CRYPT0)) PrintAndLogEx(SUCCESS, "\tCrypt: Secured page, keys not locked"); + if (isset(fuses, FUSE_CRYPT1) && isset(fuses, FUSE_CRYPT0)) PrintAndLogEx(SUCCESS, " Crypt: Secured page, keys not locked"); // 1 0 - if (isset(fuses, FUSE_CRYPT1) && notset(fuses, FUSE_CRYPT0)) PrintAndLogEx(NORMAL, "\tCrypt: Secured page, keys locked"); + if (isset(fuses, FUSE_CRYPT1) && notset(fuses, FUSE_CRYPT0)) PrintAndLogEx(NORMAL, " Crypt: Secured page, keys locked"); // 0 1 - if (notset(fuses, FUSE_CRYPT1) && isset(fuses, FUSE_CRYPT0)) PrintAndLogEx(SUCCESS, "\tCrypt: Non secured page"); + if (notset(fuses, FUSE_CRYPT1) && isset(fuses, FUSE_CRYPT0)) PrintAndLogEx(SUCCESS, " Crypt: Non secured page"); // 0 0 - if (notset(fuses, FUSE_CRYPT1) && notset(fuses, FUSE_CRYPT0)) PrintAndLogEx(NORMAL, "\tCrypt: No auth possible. Read only if RA is enabled"); + if (notset(fuses, FUSE_CRYPT1) && notset(fuses, FUSE_CRYPT0)) PrintAndLogEx(NORMAL, " Crypt: No auth possible. Read only if RA is enabled"); if (isset(fuses, FUSE_RA)) - PrintAndLogEx(NORMAL, "\tRA: Read access enabled"); + PrintAndLogEx(NORMAL, " RA: Read access enabled"); else - PrintAndLogEx(WARNING, "\tRA: Read access not enabled"); + PrintAndLogEx(WARNING, " RA: Read access not enabled"); } static void getMemConfig(uint8_t mem_cfg, uint8_t chip_cfg, uint8_t *max_blk, uint8_t *app_areas, uint8_t *kb) { @@ -396,26 +396,26 @@ static void mem_app_config(const picopass_hdr *hdr) { if (kb == 2 && (applimit > 0x1f)) applimit = 26; PrintAndLogEx(NORMAL, " Mem: %u KBits/%u App Areas (%u * 8 bytes) [%02X]", kb, app_areas, max_blk, mem); - PrintAndLogEx(NORMAL, "\tAA1: blocks 06-%02X", applimit); - PrintAndLogEx(NORMAL, "\tAA2: blocks %02X-%02X", applimit + 1, max_blk); - PrintAndLogEx(NORMAL, "\tOTP: 0x%02X%02X", hdr->conf.otp[1], hdr->conf.otp[0]); - PrintAndLogEx(NORMAL, "\nKeyAccess:"); + PrintAndLogEx(NORMAL, " AA1: blocks 06-%02X", applimit); + PrintAndLogEx(NORMAL, " AA2: blocks %02X-%02X", applimit + 1, max_blk); + PrintAndLogEx(NORMAL, " OTP: 0x%02X%02X", hdr->conf.otp[1], hdr->conf.otp[0]); + PrintAndLogEx(NORMAL, " KeyAccess:"); uint8_t book = isset(mem, 0x20); if (book) { - PrintAndLogEx(NORMAL, "\tRead A - Kd"); - PrintAndLogEx(NORMAL, "\tRead B - Kc"); - PrintAndLogEx(NORMAL, "\tWrite A - Kd"); - PrintAndLogEx(NORMAL, "\tWrite B - Kc"); - PrintAndLogEx(NORMAL, "\tDebit - Kd or Kc"); - PrintAndLogEx(NORMAL, "\tCredit - Kc"); + PrintAndLogEx(NORMAL, " Read A - Kd"); + PrintAndLogEx(NORMAL, " Read B - Kc"); + PrintAndLogEx(NORMAL, " Write A - Kd"); + PrintAndLogEx(NORMAL, " Write B - Kc"); + PrintAndLogEx(NORMAL, " Debit - Kd or Kc"); + PrintAndLogEx(NORMAL, " Credit - Kc"); } else { - PrintAndLogEx(NORMAL, "\tRead A - Kd or Kc"); - PrintAndLogEx(NORMAL, "\tRead B - Kd or Kc"); - PrintAndLogEx(NORMAL, "\tWrite A - Kc"); - PrintAndLogEx(NORMAL, "\tWrite B - Kc"); - PrintAndLogEx(NORMAL, "\tDebit - Kd or Kc"); - PrintAndLogEx(NORMAL, "\tCredit - Kc"); + PrintAndLogEx(NORMAL, " Read A - Kd or Kc"); + PrintAndLogEx(NORMAL, " Read B - Kd or Kc"); + PrintAndLogEx(NORMAL, " Write A - Kc"); + PrintAndLogEx(NORMAL, " Write B - Kc"); + PrintAndLogEx(NORMAL, " Debit - Kd or Kc"); + PrintAndLogEx(NORMAL, " Credit - Kc"); } } static void print_picopass_info(const picopass_hdr *hdr) { @@ -453,14 +453,14 @@ static int CmdHFiClassSim(const char *Cmd) { if (simType == 0) { if (param_gethex(Cmd, 1, CSN, 16)) { - PrintAndLogEx(WARNING, "A CSN should consist of 16 HEX symbols"); + PrintAndLogEx(ERR, "A CSN should consist of 16 HEX symbols"); return usage_hf_iclass_sim(); } - PrintAndLogEx(NORMAL, "--simtype:%02x csn:%s", simType, sprint_hex(CSN, 8)); + PrintAndLogEx(NORMAL, " simtype: %02x csn: %s", simType, sprint_hex(CSN, 8)); } if (simType > 4) { - PrintAndLogEx(WARNING, "Undefined simptype %d", simType); + PrintAndLogEx(ERR, "Undefined simptype %d", simType); return usage_hf_iclass_sim(); } @@ -1903,7 +1903,7 @@ static int CmdHFiClassManageKeys(const char *Cmd) { case 'f': fileNameLen = param_getstr(Cmd, cmdp + 1, filename, sizeof(filename)); if (fileNameLen < 1) { - PrintAndLogEx(WARNING, "No filename found after f"); + PrintAndLogEx(ERR, "No filename found"); errors = true; } cmdp += 2; @@ -1911,7 +1911,7 @@ static int CmdHFiClassManageKeys(const char *Cmd) { case 'n': keyNbr = param_get8(Cmd, cmdp + 1); if (keyNbr >= ICLASS_KEYS_MAX) { - PrintAndLogEx(WARNING, "Invalid block number"); + PrintAndLogEx(ERR, "Invalid block number, MAX is "_YELLOW_("%d"), ICLASS_KEYS_MAX); errors = true; } cmdp += 2; From 25507a6244cd41c52a59add4d4ae4b45a3fb6ea9 Mon Sep 17 00:00:00 2001 From: Iceman Date: Sat, 17 Aug 2019 22:59:01 +0200 Subject: [PATCH 0333/1854] Update cheatsheet.md --- doc/cheatsheet.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/cheatsheet.md b/doc/cheatsheet.md index 78a080dd9..cf5a328c1 100644 --- a/doc/cheatsheet.md +++ b/doc/cheatsheet.md @@ -1,5 +1,5 @@ # Cheatsheet -|Genrice|LF|HF| +|Generic|LF|HF| |---|---|---| |[Generic](#Generic)|[T55XX](#T55XX)|[Mifare](#Mifare)| |[Data](#Data)|[HID Prox](#HID-Prox)|[iClass](#iClass)| From b4ac11a10ed3a0a67b428b10af06447511e7f138 Mon Sep 17 00:00:00 2001 From: Iceman Date: Sat, 17 Aug 2019 23:01:08 +0200 Subject: [PATCH 0334/1854] Update cheatsheet.md --- doc/cheatsheet.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/cheatsheet.md b/doc/cheatsheet.md index cf5a328c1..7a3cb81e4 100644 --- a/doc/cheatsheet.md +++ b/doc/cheatsheet.md @@ -1,5 +1,5 @@ -# Cheatsheet -|Generic|LF|HF| +# command Cheat Sheet +|Generic|Low Frequence 125kHz|High Frequence 13.56MHz| |---|---|---| |[Generic](#Generic)|[T55XX](#T55XX)|[Mifare](#Mifare)| |[Data](#Data)|[HID Prox](#HID-Prox)|[iClass](#iClass)| From 4a817588bac60ae363a7990528952f242ca6a042 Mon Sep 17 00:00:00 2001 From: Iceman Date: Sat, 17 Aug 2019 23:01:31 +0200 Subject: [PATCH 0335/1854] Update cheatsheet.md --- doc/cheatsheet.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/cheatsheet.md b/doc/cheatsheet.md index 7a3cb81e4..63c74d1a3 100644 --- a/doc/cheatsheet.md +++ b/doc/cheatsheet.md @@ -1,5 +1,5 @@ -# command Cheat Sheet -|Generic|Low Frequence 125kHz|High Frequence 13.56MHz| +# Command Cheat Sheet +|Generic|Low Frequence 125 kHz|High Frequence 13.56 MHz| |---|---|---| |[Generic](#Generic)|[T55XX](#T55XX)|[Mifare](#Mifare)| |[Data](#Data)|[HID Prox](#HID-Prox)|[iClass](#iClass)| From 655d46993b04fa88c7983e9149d3417da1b61f21 Mon Sep 17 00:00:00 2001 From: Oleg Moiseenko <807634+merlokk@users.noreply.github.com> Date: Sun, 18 Aug 2019 00:41:27 +0300 Subject: [PATCH 0336/1854] Travis (#333) change travis config to make branches --- .travis.yml | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index f42dd8f1c..3c12e6d3c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,12 @@ language: c #default linux build env is: xenial compiler: gcc +# move some env variables to homebrew env +env: + global: + - HOMEBREW_TRAVIS_BRANCH=$TRAVIS_BRANCH + - HOMEBREW_TRAVIS_COMMIT=$TRAVIS_COMMIT + # Test on Linux and MacOS matrix: include: @@ -19,8 +25,16 @@ addons: - gcc-arm-none-eabi - libnewlib-dev homebrew: + packages: + - readline + - p7zip + - libusb-compat + - perl + - qt5 + - wget + - RfidResearchGroup/proxmark3/arm-none-eabi-gcc taps: RfidResearchGroup/proxmark3 - + install: if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew info proxmark3; From fbbbe98022109520aa8c9b343c8e10413c0f264c Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sun, 18 Aug 2019 12:21:33 +0300 Subject: [PATCH 0337/1854] add make clean for linux --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 3c12e6d3c..079ae5a33 100644 --- a/.travis.yml +++ b/.travis.yml @@ -41,6 +41,7 @@ install: brew options proxmark3; brew install --HEAD proxmark3; elif [[ "$TRAVIS_OS_NAME" == "linux" ]]; then + make clean; make all; fi From 3ae3adf0a817ac2c3009eace0ed2d7f05c235753 Mon Sep 17 00:00:00 2001 From: Iceman Date: Sun, 18 Aug 2019 11:53:20 +0200 Subject: [PATCH 0338/1854] Update cheatsheet.md --- doc/cheatsheet.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/doc/cheatsheet.md b/doc/cheatsheet.md index 63c74d1a3..f143438c4 100644 --- a/doc/cheatsheet.md +++ b/doc/cheatsheet.md @@ -1,4 +1,6 @@ # Command Cheat Sheet + + |Generic|Low Frequence 125 kHz|High Frequence 13.56 MHz| |---|---|---| |[Generic](#Generic)|[T55XX](#T55XX)|[Mifare](#Mifare)| @@ -10,6 +12,7 @@ ## Generic +^[Top](#top) Identify High Frequency cards ``` @@ -37,6 +40,7 @@ pm3 --> hw status ``` ## iClass +^[Top](#top) Reverse permute iClass master key ``` @@ -166,6 +170,7 @@ pm3 --> hf iclass lookup u 010a0ffff7ff12e0 p feffffffffffffff m 66348979153c41b ``` ## Mifare +^[Top](#top) Check for default keys ``` @@ -264,6 +269,7 @@ pm3 --> hf mf restore 1 u 4A6CE843 k hf-mf-A29558E4-key.bin f hf-mf-A29558E4-dat ``` ## HID Prox +^[Top](#top) Read HID Prox card ``` @@ -313,6 +319,7 @@ pm3 --> lf hid brute v a 26 f 21 c 200 d 2000 ``` ## Indala +^[Top](#top) Read Indala card ``` @@ -343,6 +350,7 @@ pm3 --> lf indala clone a0000000c2c436c1 ``` ## Hitag +^[Top](#top) Read Hitag information ``` @@ -401,6 +409,7 @@ pm3 --> lf hitag sim c378181c_a8f7.ht2 ``` ## T55XX +^[Top](#top) Detect T55XX card ``` @@ -443,6 +452,7 @@ pm3 --> lf t55xx wipe ``` ## Data +^[Top](#top) Get raw samples [512-40000] ``` @@ -460,6 +470,7 @@ pm3 --> data load ``` ## Lua Scripts +^[Top](#top) List Lua Scripts @@ -489,6 +500,7 @@ pm3 --> script run formatMifare -k FFFFFFFFFFFF -n FFFFFFFFFFFF -x ``` ## Memory +^[Top](#top) Load default keys into memory ``` @@ -506,6 +518,7 @@ pm3 --> mem load f default_iclass_keys i ``` ## Sim Module +^[Top](#top) Upgrade Sim Module firmware ``` @@ -513,6 +526,7 @@ pm3 --> sc upgrade f ../tools/simmodule/SIM011.BIN ``` ## Smart Card +^[Top](#top) Get Smart Card Information ``` From fb6d2fdee84ea92e5e46e344638cbf4a9f9cb566 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sun, 18 Aug 2019 17:31:57 +0300 Subject: [PATCH 0339/1854] add test script --- .travis.yml | 2 +- pm3test.sh | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 pm3test.sh diff --git a/.travis.yml b/.travis.yml index 079ae5a33..d260b9b47 100644 --- a/.travis.yml +++ b/.travis.yml @@ -50,5 +50,5 @@ script: if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then proxmark3 -h ; elif [[ "$TRAVIS_OS_NAME" == "linux" ]]; then - ./client/proxmark3 -h ; + ./pm3test.sh; fi \ No newline at end of file diff --git a/pm3test.sh b/pm3test.sh new file mode 100644 index 000000000..3ff3aa5ac --- /dev/null +++ b/pm3test.sh @@ -0,0 +1,40 @@ +#!/bin/bash + +PM3PATH=$(dirname "$0") +cd "$PM3PATH" || exit 1 + +C_RED='\033[0;31m' +C_GREEN='\033[0;32m' +C_BLUE='\033[0;34m' +C_NC='\033[0m' # No Color + +function CheckFileExist() { + + if [ -f "$2" ]; then + echo "$1 [OK]" + return 0 + fi + + if ls $2 1> /dev/null 2>&1; then + echo "$1 [OK]" + return 0 + fi + + echo "$1 [Fail]" + return 1 +} + +printf "\n${C_BLUE}RRG Proxmark3 test tool ${C_NC}\n\n" + +while true; do + if ! CheckFileExist "proxmark3 exists" "client/proxmark3"; then break; fi + if ! CheckFileExist "arm image exists" "armsrc/obj/fullimage.elf"; then break; fi + if ! CheckFileExist "bootrom exists" "bootrom/obj/bootrom.elf"; then break; fi + if ! CheckFileExist "hardnested tables exists" "client/hardnested/tables/*.z"; then break; fi + + printf "\n${C_GREEN}Tests [OK]${C_NC}\n\n" + exit 0 +done + +printf "\n${C_RED}Tests [FAIL]${C_NC}\n\n" +exit 1 \ No newline at end of file From d84fd0f7d15cc34c698554bfa79da87d2050b8b6 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sun, 18 Aug 2019 17:36:21 +0300 Subject: [PATCH 0340/1854] del spaces --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index d260b9b47..dd4b42898 100644 --- a/.travis.yml +++ b/.travis.yml @@ -34,7 +34,7 @@ addons: - wget - RfidResearchGroup/proxmark3/arm-none-eabi-gcc taps: RfidResearchGroup/proxmark3 - + install: if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew info proxmark3; @@ -51,4 +51,4 @@ script: proxmark3 -h ; elif [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ./pm3test.sh; - fi \ No newline at end of file + fi From 6452c395833a322a37ee24b1eb9fbee65b900b8a Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sun, 18 Aug 2019 17:43:34 +0300 Subject: [PATCH 0341/1854] small fix --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index dd4b42898..e272ea9cc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -50,5 +50,6 @@ script: if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then proxmark3 -h ; elif [[ "$TRAVIS_OS_NAME" == "linux" ]]; then + chmod a+w ./pm3test.sh; ./pm3test.sh; fi From 2510caff4628f0b0e52be9fc234f8925ebd72598 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sun, 18 Aug 2019 18:07:23 +0300 Subject: [PATCH 0342/1854] add exec tests --- pm3test.sh | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/pm3test.sh b/pm3test.sh index 3ff3aa5ac..d9d103910 100644 --- a/pm3test.sh +++ b/pm3test.sh @@ -24,17 +24,37 @@ function CheckFileExist() { return 1 } +function CheckExecute() { + + if eval "$2 | grep -q $3"; then + echo "$1 [OK]" + return 0 + fi + + echo "$1 [Fail]" + return 1 +} + printf "\n${C_BLUE}RRG Proxmark3 test tool ${C_NC}\n\n" while true; do - if ! CheckFileExist "proxmark3 exists" "client/proxmark3"; then break; fi - if ! CheckFileExist "arm image exists" "armsrc/obj/fullimage.elf"; then break; fi - if ! CheckFileExist "bootrom exists" "bootrom/obj/bootrom.elf"; then break; fi - if ! CheckFileExist "hardnested tables exists" "client/hardnested/tables/*.z"; then break; fi + if ! CheckFileExist "proxmark3 exists" "./client/proxmark3"; then break; fi + if ! CheckFileExist "arm image exists" "./armsrc/obj/fullimage.elf"; then break; fi + if ! CheckFileExist "bootrom exists" "./bootrom/obj/bootrom.elf"; then break; fi + if ! CheckFileExist "hardnested tables exists" "./client/hardnested/tables/*.z"; then break; fi + if ! CheckExecute "proxmark help" "./client/proxmark3 -h" "wait"; then break; fi + if ! CheckExecute "proxmark help text ISO7816" "./client/proxmark3 -t 2>&1" "ISO7816"; then break; fi + if ! CheckExecute "proxmark help text hardnested" "./client/proxmark3 -t 2>&1" "hardnested"; then break; fi + + if ! CheckExecute "hf mf offline text" "./client/proxmark3 -c 'hf mf'" "at_enc"; then break; fi + + if ! CheckExecute "hf mf hardnested test" "./client/proxmark3 -c 'hf mf hardnested t 1 000000000000'" "found:"; then break; fi + #if ! CheckExecute "emv test" "./client/proxmark3 -c 'emv test'" "Test?s? ? OK"; then break; fi + printf "\n${C_GREEN}Tests [OK]${C_NC}\n\n" exit 0 done printf "\n${C_RED}Tests [FAIL]${C_NC}\n\n" -exit 1 \ No newline at end of file +exit 1 From 7eb14b015e9601ce285e2b0f72552d9d6ecc96f5 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sun, 18 Aug 2019 18:12:18 +0300 Subject: [PATCH 0343/1854] travis fix --- .travis.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index e272ea9cc..a533910d8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -45,11 +45,13 @@ install: make all; fi +before_script: + - chmod +x pm3test.sh + script: ## start and run a test script if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then proxmark3 -h ; elif [[ "$TRAVIS_OS_NAME" == "linux" ]]; then - chmod a+w ./pm3test.sh; ./pm3test.sh; fi From 0cfaaf266fce00989ed242e3d816162c422bcfa7 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sun, 18 Aug 2019 18:26:08 +0300 Subject: [PATCH 0344/1854] added `emv test` and some colors --- pm3test.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/pm3test.sh b/pm3test.sh index d9d103910..385ba7579 100644 --- a/pm3test.sh +++ b/pm3test.sh @@ -11,27 +11,27 @@ C_NC='\033[0m' # No Color function CheckFileExist() { if [ -f "$2" ]; then - echo "$1 [OK]" + echo -e "$1 ${C_GREEN}[OK]${C_NC}" return 0 fi if ls $2 1> /dev/null 2>&1; then - echo "$1 [OK]" + echo -e "$1 ${C_GREEN}[OK]${C_NC}" return 0 fi - echo "$1 [Fail]" + echo -e "$1 ${C_RED}[Fail]${C_NC}" return 1 } function CheckExecute() { - if eval "$2 | grep -q $3"; then - echo "$1 [OK]" + if eval "$2 | grep -q '$3'"; then + echo -e "$1 ${C_GREEN}[OK]${C_NC}" return 0 fi - echo "$1 [Fail]" + echo -e "$1 ${C_RED}[Fail]${C_NC}" return 1 } @@ -50,7 +50,7 @@ while true; do if ! CheckExecute "hf mf offline text" "./client/proxmark3 -c 'hf mf'" "at_enc"; then break; fi if ! CheckExecute "hf mf hardnested test" "./client/proxmark3 -c 'hf mf hardnested t 1 000000000000'" "found:"; then break; fi - #if ! CheckExecute "emv test" "./client/proxmark3 -c 'emv test'" "Test?s? ? OK"; then break; fi + if ! CheckExecute "emv test" "./client/proxmark3 -c 'emv test'" "Test(s) \[ OK"; then break; fi printf "\n${C_GREEN}Tests [OK]${C_NC}\n\n" exit 0 From 7fc5fe6dd58cace814972d09db3785e7007e12fe Mon Sep 17 00:00:00 2001 From: root Date: Sun, 18 Aug 2019 17:43:54 +0200 Subject: [PATCH 0345/1854] chg: unifed the dateformat --- tools/fpga_compress/fpga_compress.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/fpga_compress/fpga_compress.c b/tools/fpga_compress/fpga_compress.c index 7777b6d51..bac6a1670 100644 --- a/tools/fpga_compress/fpga_compress.c +++ b/tools/fpga_compress/fpga_compress.c @@ -337,6 +337,8 @@ static int FpgaGatherVersion(FILE *infile, char *infile_name, char *dst, int len for (uint16_t i = 0; i < fpga_info_len; i++) { char c = (char)fgetc(infile); if (i < sizeof(tempstr)) { + if ( c == '/' ) c = '-'; + if ( c == ' ' ) c = '0'; tempstr[i] = c; } } From cc9f2127b124ca3215f086f2b0adcb7173d9592b Mon Sep 17 00:00:00 2001 From: RFID Research Group Date: Sun, 18 Aug 2019 17:58:35 +0200 Subject: [PATCH 0346/1854] Create FUNDING.yml --- .github/FUNDING.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 000000000..2f13a259a --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,12 @@ +# These are supported funding model platforms + +github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] +patreon: iceman1001 +open_collective: # Replace with a single Open Collective username +ko_fi: # Replace with a single Ko-fi username +tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: # Replace with a single Liberapay username +issuehunt: # Replace with a single IssueHunt username +otechie: # Replace with a single Otechie username +custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] From 512e28c62e4610183427512fa9b88778bc5938ae Mon Sep 17 00:00:00 2001 From: Oleg Moiseenko <807634+merlokk@users.noreply.github.com> Date: Sun, 18 Aug 2019 19:29:26 +0300 Subject: [PATCH 0347/1854] add some info (#336) add some info --- pm3test.sh | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/pm3test.sh b/pm3test.sh index 385ba7579..09cc6b6cc 100644 --- a/pm3test.sh +++ b/pm3test.sh @@ -37,6 +37,20 @@ function CheckExecute() { printf "\n${C_BLUE}RRG Proxmark3 test tool ${C_NC}\n\n" +if [ "$TRAVIS_COMMIT" ]; then + if [ "$TRAVIS_PULL_REQUEST" == "false" ]; then + echo "Travis branch: $TRAVIS_BRANCH slug: $TRAVIS_REPO_SLUG commit: $TRAVIS_COMMIT" + else + echo "Travis pull request: $TRAVIS_PULL_REQUEST branch: $TRAVIS_BRANCH slug: $TRAVIS_PULL_REQUEST_SLUG commit: $TRAVIS_COMMIT" + fi +fi + +printf "git branch: " +git describe --all +printf "git sha: " +git rev-parse HEAD +echo "" + while true; do if ! CheckFileExist "proxmark3 exists" "./client/proxmark3"; then break; fi if ! CheckFileExist "arm image exists" "./armsrc/obj/fullimage.elf"; then break; fi From 00cc43ec7e48397d9bcfb5cf60ed3f91573dc45b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 18 Aug 2019 19:25:09 +0200 Subject: [PATCH 0348/1854] textual --- proxmark3.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/proxmark3.sh b/proxmark3.sh index 07d2a27d5..be3cfd690 100755 --- a/proxmark3.sh +++ b/proxmark3.sh @@ -7,7 +7,7 @@ PM3PATH=$(dirname "$0") cd "$PM3PATH" || exit 1 function wait4proxmark_Linux { - echo >&2 "[=] Waiting for Proxmark to appear..." + echo >&2 "[=] Waiting for Proxmark3 to appear..." while true; do PM3=$(find /dev/pm3-* /dev/ttyACM* 2>/dev/null | head -1) if [[ $PM3 != "" ]]; then @@ -19,7 +19,7 @@ function wait4proxmark_Linux { } function wait4proxmark_macOS { - echo >&2 "[=] Waiting for Proxmark to appear..." + echo >&2 "[=] Waiting for Proxmark3 to appear..." while true; do PM3=$(find /dev/pm3-* /dev/cu.usbmodem* 2>/dev/null | head -1) if [[ $PM3 != "" ]]; then @@ -31,7 +31,7 @@ function wait4proxmark_macOS { } function wait4proxmark_Windows { - echo >&2 "[=] Waiting for Proxmark to appear..." + echo >&2 "[=] Waiting for Proxmark3 to appear..." while true; do device=$(wmic path Win32_SerialPort where "PNPDeviceID like '%VID_9AC4&PID_4B8F%'" get DeviceID,PNPDeviceID 2>/dev/null | awk 'NR==2') if [[ $device != "" ]]; then @@ -44,7 +44,7 @@ function wait4proxmark_Windows { } function wait4proxmark_WSL { - echo >&2 "[=] Waiting for Proxmark to appear..." + echo >&2 "[=] Waiting for Proxmark3 to appear..." while true; do device=$(wmic.exe path Win32_SerialPort where "PNPDeviceID like '%VID_9AC4&PID_4B8F%'" get DeviceID,PNPDeviceID 2>/dev/null | awk 'NR==2') if [[ $device != "" ]]; then From 6647c407af9084a0b20fedf750a2d6c8b07361ad Mon Sep 17 00:00:00 2001 From: Oleg Moiseenko <807634+merlokk@users.noreply.github.com> Date: Sun, 18 Aug 2019 20:56:38 +0300 Subject: [PATCH 0349/1854] ios (#337) retry for hardnested added `make all v=1` for linux --- .travis.yml | 12 ++++++++++-- pm3test.sh | 26 +++++++++++++++++++------- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/.travis.yml b/.travis.yml index a533910d8..a1c5a6866 100644 --- a/.travis.yml +++ b/.travis.yml @@ -42,7 +42,7 @@ install: brew install --HEAD proxmark3; elif [[ "$TRAVIS_OS_NAME" == "linux" ]]; then make clean; - make all; + make all V=1; fi before_script: @@ -50,8 +50,16 @@ before_script: script: ## start and run a test script - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then + if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then proxmark3 -h ; +# cd /Users/travis/Library/Caches/Homebrew/proxmark3--git; +# chmod +x pm3test.sh; +# pwd; +# ls -la; +# cd client; +# ls-la; +# cd ..; +# ./pm3test.sh; elif [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ./pm3test.sh; fi diff --git a/pm3test.sh b/pm3test.sh index 09cc6b6cc..e127944f6 100644 --- a/pm3test.sh +++ b/pm3test.sh @@ -8,34 +8,46 @@ C_GREEN='\033[0;32m' C_BLUE='\033[0;34m' C_NC='\033[0m' # No Color +# title, file name or file wildcard to check function CheckFileExist() { if [ -f "$2" ]; then echo -e "$1 ${C_GREEN}[OK]${C_NC}" - return 0 + return 0 fi if ls $2 1> /dev/null 2>&1; then echo -e "$1 ${C_GREEN}[OK]${C_NC}" - return 0 + return 0 fi echo -e "$1 ${C_RED}[Fail]${C_NC}" return 1 } +# title, command line, check result, repeat several times if failed function CheckExecute() { - if eval "$2 | grep -q '$3'"; then - echo -e "$1 ${C_GREEN}[OK]${C_NC}" - return 0 + if [ $4 ]; then + local RETRY="1 2 3 e" + else + local RETRY="e" fi + for I in $RETRY + do + if eval "$2 | grep -q '$3'"; then + echo -e "$1 ${C_GREEN}[OK]${C_NC}" + return 0 + fi + if [ ! $I == "e" ]; then echo "retry $I"; fi + done + echo -e "$1 ${C_RED}[Fail]${C_NC}" return 1 } -printf "\n${C_BLUE}RRG Proxmark3 test tool ${C_NC}\n\n" +printf "\n${C_BLUE}RRG/Iceman Proxmark3 test tool ${C_NC}\n\n" if [ "$TRAVIS_COMMIT" ]; then if [ "$TRAVIS_PULL_REQUEST" == "false" ]; then @@ -63,7 +75,7 @@ while true; do if ! CheckExecute "hf mf offline text" "./client/proxmark3 -c 'hf mf'" "at_enc"; then break; fi - if ! CheckExecute "hf mf hardnested test" "./client/proxmark3 -c 'hf mf hardnested t 1 000000000000'" "found:"; then break; fi + if ! CheckExecute "hf mf hardnested test" "./client/proxmark3 -c 'hf mf hardnested t 1 000000000000'" "found:" "repeat"; then break; fi if ! CheckExecute "emv test" "./client/proxmark3 -c 'emv test'" "Test(s) \[ OK"; then break; fi printf "\n${C_GREEN}Tests [OK]${C_NC}\n\n" From a4010900eaa29fd86c114af869594b81bf8a6e14 Mon Sep 17 00:00:00 2001 From: Uli Heilmeier Date: Sun, 18 Aug 2019 20:06:15 +0200 Subject: [PATCH 0350/1854] Doc: Add notes about trace to Wireshark export Adding some notes how to bring trace output into Wireshark. --- doc/trace_wireshark_notes.md | 60 ++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 doc/trace_wireshark_notes.md diff --git a/doc/trace_wireshark_notes.md b/doc/trace_wireshark_notes.md new file mode 100644 index 000000000..50dd9d082 --- /dev/null +++ b/doc/trace_wireshark_notes.md @@ -0,0 +1,60 @@ +# Trace command notes + +The `trace` command lists the data exchange by the proxmark3 and a tag or a reader in human readable form. + +With `trace list` a table is shown which gives timing information, the src of the data bytes, the transmitted/received bytes itself, a check if the CRC was correct and some decoding of the command. + +To get a more detailed explanation of the transmitted data for ISO14443A traces the output can be converted to a pcapng file to read it with [Wireshark](https://www.wireshark.org/). + +To do so + +* use `trace list 14a x` +* copy the output (starting with the timestamp) into a textfile +* run `text2pcap -t "%S." -l 264 -n ` +* now open your pcapng file in Wireshark or read it with the CLI version `tshark` + +An example frame + +with `trace list 14a`: + +``` +19072 | 29536 | Rdr |93 70 88 04 cf ff bc 7f bb | ok | SELECT_UID +``` + +the same data with `tshark -r foo.pcapng -V -x`: + +``` +Frame 5: 13 bytes on wire (104 bits), 13 bytes captured (104 bits) on interface 0 + Interface id: 0 (unknown) + Interface name: unknown + Encapsulation type: ISO 14443 contactless smartcard standards (177) + Arrival Time: Aug 17, 2019 23:17:00.000002606 CEST + [Time shift for this packet: 0.000000000 seconds] + Epoch Time: 1566076620.000002606 seconds + [Time delta from previous captured frame: 0.000000840 seconds] + [Time delta from previous displayed frame: 0.000000840 seconds] + [Time since reference or first frame: 0.000001907 seconds] + Frame Number: 5 + Frame Length: 13 bytes (104 bits) + Capture Length: 13 bytes (104 bits) + [Frame is marked: False] + [Frame is ignored: False] + [Protocols in frame: iso14443] +ISO 14443 + Pseudo header + Version: 0x00 + Event: Data transfer PCD -> PICC (0xfe) + Length field: 9 + Message: Select + SEL: 0x93 + NVB: 0x70 + CT: 0x88 + UID_CLn: 04cfff + BCC: 0xbc + CRC: 0xbb7f [correct] + [CRC Status: Good] + +0000 00 fe 00 09 93 70 88 04 cf ff bc 7f bb .....p....... +``` + +If the Wireshark ISO14443a dissector is missing some commands or needs some other rework please [file a bug](https://bugs.wireshark.org/bugzilla/). From b98cb5d47cbd118d272695a2961e34e118aeca63 Mon Sep 17 00:00:00 2001 From: Iceman Date: Sun, 18 Aug 2019 21:32:30 +0200 Subject: [PATCH 0351/1854] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 81c676b8d..0968b1f06 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,7 @@ _Note that it also supports other Proxmark3 platforms as well!_ |[Notes on Frame format](/doc/new_frame_format.md)||| |[Notes on external flash](/doc/ext_flash_notes.md)||| |[Notes on Termux / Android](/doc/termux_notes.md)||| +|[Notes on Wireshark / tracedata](/doc/trace_wireshark_notes.md)||| |[Developing standalone mode](/armsrc/Standalone/readme.md)|[Wiki about standalone mode](https://github.com/RfidResearchGroup/proxmark3/wiki/Standalone-mode) || |[Donations](#Donations)||| @@ -54,6 +55,7 @@ If you intend to contribute to the code, please read the [coding style notes](HA - Internal notes on [external flash](/doc/ext_flash_notes.md) - Internal notes on [standalone mode](https://github.com/RfidResearchGroup/proxmark3/wiki/Standalone-mode) - Internal notes on [Termux / Android](/doc/termux_notes.md) +- Internal notes on [Wireshark / tracedata](/doc/trace_wireshark_notes.md) ## Cheat sheet Thanks to Alex Dibs, you can enjoy a [command cheat sheet](/doc/cheatsheet.md) From 71c5ae1e1e66bb459ffc87c910f6f0ee69e75274 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 18 Aug 2019 23:35:14 +0200 Subject: [PATCH 0352/1854] make travis great again (yml parsing failure) --- .travis.yml | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/.travis.yml b/.travis.yml index a1c5a6866..334b8c890 100644 --- a/.travis.yml +++ b/.travis.yml @@ -36,30 +36,22 @@ addons: taps: RfidResearchGroup/proxmark3 install: - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then + if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew info proxmark3; - brew options proxmark3; - brew install --HEAD proxmark3; - elif [[ "$TRAVIS_OS_NAME" == "linux" ]]; then + brew options proxmark3; + brew install --verbose --HEAD proxmark3; + elif [[ "$TRAVIS_OS_NAME" == "linux" ]]; then make clean; make all V=1; fi before_script: - chmod +x pm3test.sh - -script: + +script: ## start and run a test script if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then proxmark3 -h ; -# cd /Users/travis/Library/Caches/Homebrew/proxmark3--git; -# chmod +x pm3test.sh; -# pwd; -# ls -la; -# cd client; -# ls-la; -# cd ..; -# ./pm3test.sh; - elif [[ "$TRAVIS_OS_NAME" == "linux" ]]; then + elif [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ./pm3test.sh; fi From 6f9ec6dd2426ead3eda737918ff00771700a939b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 19 Aug 2019 15:18:17 +0200 Subject: [PATCH 0353/1854] FIX: 'spiffs : fixes the device going rouge with bad memory reading' Thanks @megabug --- armsrc/spiffs.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/armsrc/spiffs.c b/armsrc/spiffs.c index cb4412264..0296b7620 100644 --- a/armsrc/spiffs.c +++ b/armsrc/spiffs.c @@ -96,9 +96,9 @@ static s32_t rdv40_spiffs_llerase(u32_t addr, u32_t size) { //////////////////////////////////////////////////////////////////////////////// ////// SPIFFS LOW LEVEL OPERATIONS ///////////////////////////////////////////// -static u8_t spiffs_work_buf[RDV40_SPIFFS_WORKBUF_SZ]; -static u8_t spiffs_fds[RDV40_SPIFFS_FDBUF_SZ]; -static u8_t spiffs_cache_buf[RDV40_SPIFFS_CACHE_SZ]; +static u8_t spiffs_work_buf[RDV40_SPIFFS_WORKBUF_SZ] __attribute__((aligned)); +static u8_t spiffs_fds[RDV40_SPIFFS_FDBUF_SZ] __attribute__((aligned)); +static u8_t spiffs_cache_buf[RDV40_SPIFFS_CACHE_SZ] __attribute__((aligned)); static spiffs fs; From a6e5f9922fbfaaa25f17fc50b60dfdaddb56ebd7 Mon Sep 17 00:00:00 2001 From: sguerrini97 Date: Mon, 19 Aug 2019 17:10:25 +0200 Subject: [PATCH 0354/1854] PCF7931: Print found single/consecutive block(s), fixes to block 1 check and some comments Printing blocks makes it easier to manually reorder blocks when block 0 and 1 are not transmitted --- armsrc/pcf7931.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/armsrc/pcf7931.c b/armsrc/pcf7931.c index 2c679b31f..9f1283b8c 100644 --- a/armsrc/pcf7931.c +++ b/armsrc/pcf7931.c @@ -146,16 +146,24 @@ bool IsBlock0PCF7931(uint8_t *block) { bool IsBlock1PCF7931(uint8_t *block) { // assuming all RFU bits are set to 0 + + uint8_t rb1 = block[14] & 0x80; + uint8_t rfb = block[14] & 0x7f; + uint8_t rlb = block[15]; + if (block[10] == 0 && block[11] == 0 && block[12] == 0 && block[13] == 0) { - - if ((block[14] & 0x7f) <= 9 - && block[15] <= 9) { + // block 1 is sent only if (RLB >= 1 && RFB <= 1) or RB1 enabled + if (rfb <= rlb + && rfb <= 9 + && rlb <= 9 + && ((rfb <= 1 && rlb >= 1) || rb1)) { return true; } } + return false; } @@ -200,9 +208,11 @@ void ReadPCF7931() { // our logic breaks if we don't get at least two blocks if (n < 2) { + // skip if all 0s block or no blocks if (n == 0 || !memcmp(tmp_blocks[0], "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16)) continue; + // add block to single blocks list if (single_blocks_cnt < max_blocks) { for (i = 0; i < single_blocks_cnt; ++i) { if (!memcmp(single_blocks[i], tmp_blocks[0], 16)) { @@ -212,6 +222,7 @@ void ReadPCF7931() { } if (j != 1) { memcpy(single_blocks[single_blocks_cnt], tmp_blocks[0], 16); + print_result("got single block", single_blocks[single_blocks_cnt], 16); single_blocks_cnt++; } j = 0; @@ -221,6 +232,10 @@ void ReadPCF7931() { } Dbprintf("(dbg) got %d blocks (%d/%d found) (%d tries, %d errors)", n, found_blocks, (max_blocks == 0 ? found_blocks : max_blocks), tries, errors); + for (i = 0; i < n; ++i) + { + print_result("got consecutive blocks", tmp_blocks[i], 16); + } i = 0; if (!found_0_1) { @@ -282,7 +297,7 @@ void ReadPCF7931() { Dbprintf("Button pressed, stopping."); goto end; } - } while (found_blocks != max_blocks); + } while (found_blocks < max_blocks); end: Dbprintf("-----------------------------------------"); From e12db2bb5324b02c7bb20332be83df492daa68ca Mon Sep 17 00:00:00 2001 From: Oleg Moiseenko <807634+merlokk@users.noreply.github.com> Date: Mon, 19 Aug 2019 18:43:01 +0300 Subject: [PATCH 0355/1854] travis osx (#339) changed homebrew install to make all. added pwd to twst script --- .travis.yml | 5 +++-- pm3test.sh | 3 +++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 334b8c890..5357326c6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -39,7 +39,8 @@ install: if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew info proxmark3; brew options proxmark3; - brew install --verbose --HEAD proxmark3; + make clean; + make all V=1; elif [[ "$TRAVIS_OS_NAME" == "linux" ]]; then make clean; make all V=1; @@ -51,7 +52,7 @@ before_script: script: ## start and run a test script if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then - proxmark3 -h ; + ./pm3test.sh; elif [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ./pm3test.sh; fi diff --git a/pm3test.sh b/pm3test.sh index e127944f6..6c7328475 100644 --- a/pm3test.sh +++ b/pm3test.sh @@ -49,6 +49,9 @@ function CheckExecute() { printf "\n${C_BLUE}RRG/Iceman Proxmark3 test tool ${C_NC}\n\n" +printf "work directory: " +pwd + if [ "$TRAVIS_COMMIT" ]; then if [ "$TRAVIS_PULL_REQUEST" == "false" ]; then echo "Travis branch: $TRAVIS_BRANCH slug: $TRAVIS_REPO_SLUG commit: $TRAVIS_COMMIT" From ab2100879ed2cd50c614f4afa7fc337d82a339f6 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 19 Aug 2019 17:47:11 +0200 Subject: [PATCH 0356/1854] Get btpin/btfactory available in FPC DEV builds --- client/cmdusart.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/cmdusart.c b/client/cmdusart.c index 0b668bbe7..26b972f82 100644 --- a/client/cmdusart.c +++ b/client/cmdusart.c @@ -763,8 +763,8 @@ static int CmdUsartRXhex(const char *Cmd) { static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, - {"btpin", CmdUsartBtPin, IfPm3FpcUsartHostFromUsb, "Change BT add-on PIN"}, - {"btfactory", CmdUsartBtFactory, IfPm3FpcUsartHostFromUsb, "Reset BT add-on to factory settings"}, + {"btpin", CmdUsartBtPin, IfPm3FpcUsartFromUsb, "Change BT add-on PIN"}, + {"btfactory", CmdUsartBtFactory, IfPm3FpcUsartFromUsb, "Reset BT add-on to factory settings"}, {"tx", CmdUsartTX, IfPm3FpcUsartDevFromUsb, "Send string over USART"}, {"rx", CmdUsartRX, IfPm3FpcUsartDevFromUsb, "Receive string over USART"}, {"txrx", CmdUsartTXRX, IfPm3FpcUsartDevFromUsb, "Send string over USART and wait for response"}, From a97c811dd18629741d8b0cf9b27d6dfb41baecd8 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 19 Aug 2019 17:50:53 +0200 Subject: [PATCH 0357/1854] pm3test +x --- pm3test.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 pm3test.sh diff --git a/pm3test.sh b/pm3test.sh old mode 100644 new mode 100755 From 5be53281dae5e014c305c41e37eef25c203bcba0 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 19 Aug 2019 18:56:00 +0300 Subject: [PATCH 0358/1854] check get rid of chmod --- .travis.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5357326c6..17b15fa55 100644 --- a/.travis.yml +++ b/.travis.yml @@ -46,9 +46,6 @@ install: make all V=1; fi -before_script: - - chmod +x pm3test.sh - script: ## start and run a test script if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then From da279dec3b5317c1ab581094241dc5cb0e93cc3c Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 19 Aug 2019 19:01:08 +0300 Subject: [PATCH 0359/1854] ignore test if fail --- pm3test.sh | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/pm3test.sh b/pm3test.sh index 6c7328475..881c17f23 100755 --- a/pm3test.sh +++ b/pm3test.sh @@ -5,6 +5,7 @@ cd "$PM3PATH" || exit 1 C_RED='\033[0;31m' C_GREEN='\033[0;32m' +C_YELLOW='\033[0;33m' C_BLUE='\033[0;34m' C_NC='\033[0m' # No Color @@ -25,7 +26,7 @@ function CheckFileExist() { return 1 } -# title, command line, check result, repeat several times if failed +# title, command line, check result, repeat several times if failed, ignore if fail function CheckExecute() { if [ $4 ]; then @@ -43,6 +44,12 @@ function CheckExecute() { if [ ! $I == "e" ]; then echo "retry $I"; fi done + + if [ $5 ]; then + echo -e "$1 ${C_YELLOW}[Ignored]${C_NC}" + return 0 + fi + echo -e "$1 ${C_RED}[Fail]${C_NC}" return 1 } @@ -78,7 +85,7 @@ while true; do if ! CheckExecute "hf mf offline text" "./client/proxmark3 -c 'hf mf'" "at_enc"; then break; fi - if ! CheckExecute "hf mf hardnested test" "./client/proxmark3 -c 'hf mf hardnested t 1 000000000000'" "found:" "repeat"; then break; fi + if ! CheckExecute "hf mf hardnested test" "./client/proxmark3 -c 'hf mf hardnested t 1 000000000000'" "found:" "repeat" "ignore"; then break; fi if ! CheckExecute "emv test" "./client/proxmark3 -c 'emv test'" "Test(s) \[ OK"; then break; fi printf "\n${C_GREEN}Tests [OK]${C_NC}\n\n" From 5a603e296c4358381d4eadf76319dca739141570 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 19 Aug 2019 19:09:28 +0300 Subject: [PATCH 0360/1854] add iclass test --- pm3test.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/pm3test.sh b/pm3test.sh index 881c17f23..beb8e29c6 100755 --- a/pm3test.sh +++ b/pm3test.sh @@ -86,6 +86,7 @@ while true; do if ! CheckExecute "hf mf offline text" "./client/proxmark3 -c 'hf mf'" "at_enc"; then break; fi if ! CheckExecute "hf mf hardnested test" "./client/proxmark3 -c 'hf mf hardnested t 1 000000000000'" "found:" "repeat" "ignore"; then break; fi + if ! CheckExecute "hf mf iclass test" "./client/proxmark3 -c 'hf iclass loclass t'" "found:"; then break; fi if ! CheckExecute "emv test" "./client/proxmark3 -c 'emv test'" "Test(s) \[ OK"; then break; fi printf "\n${C_GREEN}Tests [OK]${C_NC}\n\n" From 48fdf62c09acec5bdde4fe3186e36de993e13ed1 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 19 Aug 2019 19:20:02 +0300 Subject: [PATCH 0361/1854] iclass test fix --- pm3test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pm3test.sh b/pm3test.sh index beb8e29c6..18e693fbe 100755 --- a/pm3test.sh +++ b/pm3test.sh @@ -86,7 +86,7 @@ while true; do if ! CheckExecute "hf mf offline text" "./client/proxmark3 -c 'hf mf'" "at_enc"; then break; fi if ! CheckExecute "hf mf hardnested test" "./client/proxmark3 -c 'hf mf hardnested t 1 000000000000'" "found:" "repeat" "ignore"; then break; fi - if ! CheckExecute "hf mf iclass test" "./client/proxmark3 -c 'hf iclass loclass t'" "found:"; then break; fi + if ! CheckExecute "hf mf iclass test" "./client/proxmark3 -c 'hf iclass loclass t'" "verified ok"; then break; fi if ! CheckExecute "emv test" "./client/proxmark3 -c 'emv test'" "Test(s) \[ OK"; then break; fi printf "\n${C_GREEN}Tests [OK]${C_NC}\n\n" From 2b1f6217d5501405296128b2d1d8a44df951a57a Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 19 Aug 2019 19:35:14 +0300 Subject: [PATCH 0362/1854] appveyor add test --- appveyor.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/appveyor.yml b/appveyor.yml index 3b937c197..4d47bd30f 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -321,6 +321,8 @@ test_script: ExecTest "hf mf hardnested" "hf mf hardnested" {bash -lc "cd ~/client;./proxmark3 -c 'hf mf hardnested t 1 000000000000'"} "found:" + ExecTest "hf mf iclass" "hf mf iclass" {bash -lc "cd ~/client;./proxmark3 -c 'hf iclass loclass t'"} "verified ok" + #proxmark crypto tests From dbfe3c277d039b33f6c608095a6c5bb8cebb57dd Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 19 Aug 2019 19:53:59 +0300 Subject: [PATCH 0363/1854] add V=1 to make --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 4d47bd30f..a1276ca1e 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -113,7 +113,7 @@ build_script: #make - bash -c -i 'pwd;make clean;make all' + bash -c -i 'pwd;make clean;make all V=1' #some checks From 2a91310bf505ba35dc8824e5fc87e3352a1afb21 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 19 Aug 2019 18:33:43 +0200 Subject: [PATCH 0364/1854] pm3test: remove spurious spaces --- pm3test.sh | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/pm3test.sh b/pm3test.sh index 18e693fbe..071cecaea 100755 --- a/pm3test.sh +++ b/pm3test.sh @@ -11,17 +11,17 @@ C_NC='\033[0m' # No Color # title, file name or file wildcard to check function CheckFileExist() { - + if [ -f "$2" ]; then echo -e "$1 ${C_GREEN}[OK]${C_NC}" return 0 - fi - + fi + if ls $2 1> /dev/null 2>&1; then echo -e "$1 ${C_GREEN}[OK]${C_NC}" return 0 fi - + echo -e "$1 ${C_RED}[Fail]${C_NC}" return 1 } @@ -34,8 +34,8 @@ function CheckExecute() { else local RETRY="e" fi - - for I in $RETRY + + for I in $RETRY do if eval "$2 | grep -q '$3'"; then echo -e "$1 ${C_GREEN}[OK]${C_NC}" @@ -43,13 +43,13 @@ function CheckExecute() { fi if [ ! $I == "e" ]; then echo "retry $I"; fi done - - + + if [ $5 ]; then echo -e "$1 ${C_YELLOW}[Ignored]${C_NC}" return 0 fi - + echo -e "$1 ${C_RED}[Fail]${C_NC}" return 1 } @@ -67,9 +67,9 @@ if [ "$TRAVIS_COMMIT" ]; then fi fi -printf "git branch: " +printf "git branch: " git describe --all -printf "git sha: " +printf "git sha: " git rev-parse HEAD echo "" @@ -88,7 +88,7 @@ while true; do if ! CheckExecute "hf mf hardnested test" "./client/proxmark3 -c 'hf mf hardnested t 1 000000000000'" "found:" "repeat" "ignore"; then break; fi if ! CheckExecute "hf mf iclass test" "./client/proxmark3 -c 'hf iclass loclass t'" "verified ok"; then break; fi if ! CheckExecute "emv test" "./client/proxmark3 -c 'emv test'" "Test(s) \[ OK"; then break; fi - + printf "\n${C_GREEN}Tests [OK]${C_NC}\n\n" exit 0 done From e2e8cecc304d0fd3b71ee3d35d0599db7f8829f6 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 19 Aug 2019 18:40:25 +0200 Subject: [PATCH 0365/1854] pm3test: show output in case of failure --- pm3test.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pm3test.sh b/pm3test.sh index 071cecaea..ac0624fdf 100755 --- a/pm3test.sh +++ b/pm3test.sh @@ -37,7 +37,8 @@ function CheckExecute() { for I in $RETRY do - if eval "$2 | grep -q '$3'"; then + RES=$(eval "$2") + if echo "$RES" | grep -q "$3"; then echo -e "$1 ${C_GREEN}[OK]${C_NC}" return 0 fi @@ -51,6 +52,7 @@ function CheckExecute() { fi echo -e "$1 ${C_RED}[Fail]${C_NC}" + echo -e "Execution trace:\n$RES" return 1 } From 6e64f67fe32b29a8213b301f508322bd87129972 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 19 Aug 2019 19:09:17 +0200 Subject: [PATCH 0366/1854] pm3test: more tests --- pm3test.sh | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/pm3test.sh b/pm3test.sh index ac0624fdf..119fffbb8 100755 --- a/pm3test.sh +++ b/pm3test.sh @@ -76,21 +76,35 @@ git rev-parse HEAD echo "" while true; do + printf "\n${C_BLUE}Testing files:${C_NC}\n" if ! CheckFileExist "proxmark3 exists" "./client/proxmark3"; then break; fi if ! CheckFileExist "arm image exists" "./armsrc/obj/fullimage.elf"; then break; fi if ! CheckFileExist "bootrom exists" "./bootrom/obj/bootrom.elf"; then break; fi if ! CheckFileExist "hardnested tables exists" "./client/hardnested/tables/*.z"; then break; fi + printf "\n${C_BLUE}Testing basic help:${C_NC}\n" if ! CheckExecute "proxmark help" "./client/proxmark3 -h" "wait"; then break; fi if ! CheckExecute "proxmark help text ISO7816" "./client/proxmark3 -t 2>&1" "ISO7816"; then break; fi if ! CheckExecute "proxmark help text hardnested" "./client/proxmark3 -t 2>&1" "hardnested"; then break; fi - if ! CheckExecute "hf mf offline text" "./client/proxmark3 -c 'hf mf'" "at_enc"; then break; fi + printf "\n${C_BLUE}Testing data manipulation:${C_NC}\n" + if ! CheckExecute "reveng test" "./client/proxmark3 -c 'reveng -w 8 -s 01020304e3 010204039d'" "CRC-8/SMBUS"; then break; fi + printf "\n${C_BLUE}Testing LF:${C_NC}\n" + if ! CheckExecute "lf em4x05 test" "./client/proxmark3 -c 'data load traces/em4x05.pm3;lf search'" "FDX-B ID found"; then break; fi + + printf "\n${C_BLUE}Testing HF:${C_NC}\n" + if ! CheckExecute "hf mf offline text" "./client/proxmark3 -c 'hf mf'" "at_enc"; then break; fi if ! CheckExecute "hf mf hardnested test" "./client/proxmark3 -c 'hf mf hardnested t 1 000000000000'" "found:" "repeat" "ignore"; then break; fi - if ! CheckExecute "hf mf iclass test" "./client/proxmark3 -c 'hf iclass loclass t'" "verified ok"; then break; fi + if ! CheckExecute "hf iclass test" "./client/proxmark3 -c 'hf iclass loclass t'" "verified ok"; then break; fi if ! CheckExecute "emv test" "./client/proxmark3 -c 'emv test'" "Test(s) \[ OK"; then break; fi + printf "\n${C_BLUE}Testing tools:${C_NC}\n" + # Need a decent example for mfkey32... + if ! CheckExecute "mfkey32v2 test" "tools/mfkey/mfkey32v2 12345678 1AD8DF2B 1D316024 620EF048 30D6CB07 C52077E2 837AC61A" "Found Key: \[a0a1a2a3a4a5\]"; then break; fi + if ! CheckExecute "mfkey64 test" "tools/mfkey/mfkey64 9c599b32 82a4166c a1e458ce 6eea41e0 5cadf439" "Found Key: \[ffffffffffff\]"; then break; fi + if ! CheckExecute "mfkey64 long trace test" "tools/mfkey/./mfkey64 14579f69 ce844261 f8049ccb 0525c84f 9431cc40 7093df99 9972428ce2e8523f456b99c831e769dced09 8ca6827b ab797fd369e8b93a86776b40dae3ef686efd c3c381ba 49e2c9def4868d1777670e584c27230286f4 fbdcd7c1 4abd964b07d3563aa066ed0a2eac7f6312bf 9f9149ea" "Found Key: \[091e639cb715\]"; then break; fi + if ! CheckExecute "nonce2key test" "tools/nonce2key/nonce2key e9cadd9c a8bf4a12 a020a8285858b090 050f010607060e07 5693be6c00000000" "key recovered: fc00018778f7"; then break; fi printf "\n${C_GREEN}Tests [OK]${C_NC}\n\n" exit 0 done From f06846e2d06b57cdaf1e3e1413e5369cfbf97fc1 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 19 Aug 2019 20:24:08 +0200 Subject: [PATCH 0367/1854] chg: 'hf iclass loclass' - break attack earlier if one csn byte recovery fails. No need to try run it. and some colors... --- client/loclass/cipherutils.c | 13 ++++++++----- client/loclass/elite_crack.c | 18 ++++++++++++++---- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/client/loclass/cipherutils.c b/client/loclass/cipherutils.c index b11f6883a..80364d4e1 100644 --- a/client/loclass/cipherutils.c +++ b/client/loclass/cipherutils.c @@ -39,7 +39,7 @@ #include #include #include - +#include "util.h" // sprint_hex #include "commonutil.h" // ARRAYLEN #include "fileutils.h" @@ -160,23 +160,26 @@ void printarr(const char *name, uint8_t *arr, int len) { } void printvar(const char *name, uint8_t *arr, int len) { - int cx, i; +/* + int cx, i; size_t outsize = 40 + strlen(name) + len * 2; char *output = calloc(outsize, sizeof(char)); cx = snprintf(output, outsize, "%s = ", name); for (i = 0; i < len; i++) { cx += snprintf(output + cx, outsize - cx, "%02x", *(arr + i)); //2 bytes per byte } - PrintAndLogEx(NORMAL, output); free(output); + */ + PrintAndLogEx(NORMAL, "%s = " _YELLOW_("%s"), name, sprint_hex(arr, len) ); + } void printarr_human_readable(const char *title, uint8_t *arr, int len) { - int cx, i; + int cx = 0, i; size_t outsize = 100 + strlen(title) + len * 4; char *output = calloc(outsize, sizeof(char)); - cx = snprintf(output, outsize, "\n\t%s\n", title); + PrintAndLogEx(NORMAL, "\n %s", title); for (i = 0; i < len; i++) { if (i % 16 == 0) cx += snprintf(output + cx, outsize - cx, "\n%02x| ", i); diff --git a/client/loclass/elite_crack.c b/client/loclass/elite_crack.c index a4296f476..74ebfe608 100644 --- a/client/loclass/elite_crack.c +++ b/client/loclass/elite_crack.c @@ -479,7 +479,7 @@ int calculateMasterKey(uint8_t first16bytes[], uint64_t master_key[]) { return 1; } else { PrintAndLogEx(NORMAL, "\n"); - PrintAndLogEx(SUCCESS, "Key verified ok!\n"); + PrintAndLogEx(SUCCESS, _GREEN_("Key verified ok!") ); } return 0; } @@ -502,11 +502,19 @@ int bruteforceDump(uint8_t dump[], size_t dumpsize, uint16_t keytable[]) { for (i = 0 ; i * itemsize < dumpsize ; i++) { memcpy(attack, dump + i * itemsize, itemsize); errors += bruteforceItem(*attack, keytable); + if ( errors ) + break; } free(attack); t1 = msclock() - t1; PrintAndLogEx(SUCCESS, "time: %" PRIu64 " seconds", t1 / 1000); + + if ( errors ) { + PrintAndLogEx(ERR, "loclass exiting. Try run " _YELLOW_("`hf iclass sim 2`") "again and collect new data"); + return 1; + } + // Pick out the first 16 bytes of the keytable. // The keytable is now in 16-bit ints, where the upper 8 bits // indicate crack-status. Those must be discarded for the @@ -516,8 +524,10 @@ int bruteforceDump(uint8_t dump[], size_t dumpsize, uint16_t keytable[]) { for (i = 0 ; i < 16 ; i++) { first16bytes[i] = keytable[i] & 0xFF; - if (!(keytable[i] & CRACKED)) + if (!(keytable[i] & CRACKED)) { PrintAndLogEx(WARNING, "Warning: we are missing byte %d, custom key calculation will fail...", i); + return 1; + } } errors += calculateMasterKey(first16bytes, NULL); return errors; @@ -532,7 +542,7 @@ int bruteforceDump(uint8_t dump[], size_t dumpsize, uint16_t keytable[]) { int bruteforceFile(const char *filename, uint16_t keytable[]) { FILE *f = fopen(filename, "rb"); if (!f) { - PrintAndLogEx(WARNING, "Failed to read from file '%s'", filename); + PrintAndLogEx(WARNING, "Failed to read from file " _YELLOW_("%s"), filename); return 1; } @@ -612,7 +622,7 @@ static int _testBruteforce() { } else if (fileExists("client/loclass/iclass_dump.bin")) { errors |= bruteforceFile("client/loclass/iclass_dump.bin", keytable); } else { - PrintAndLogEx(ERR, "Error: The file iclass_dump.bin was not found!"); + PrintAndLogEx(ERR, "Error: The file " _YELLOW_("iclass_dump.bin") "was not found!"); } } return errors; From f4c810f83bbed7e9fbc332646210ac9d46a5bedd Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 16 Aug 2019 22:49:34 +0200 Subject: [PATCH 0368/1854] allow override of CFLAG & alike, remove /opt paths --- client/Makefile | 63 +++++++++++++++++++------------------------------ 1 file changed, 24 insertions(+), 39 deletions(-) diff --git a/client/Makefile b/client/Makefile index 89f8cfb44..bf047ff7d 100644 --- a/client/Makefile +++ b/client/Makefile @@ -19,25 +19,20 @@ CC = gcc CXX = g++ LD = g++ TAR = tar -TARFLAGS = -C .. --ignore-failed-read -rvf +TARFLAGS ?= -v --ignore-failed-read -r +TARFLAGS += -C .. -f RM = rm -f MV = mv TOUCH = touch FALSE = false -ENV_LDFLAGS := $(LDFLAGS) -ENV_CFLAGS := $(CFLAGS) - platform = $(shell uname) VPATH = ../common ../common/zlib uart OBJDIR = obj -LDLIBS = -ifneq ($(platform),Darwin) - LDLIBS += -L/opt/local/lib -endif -LDLIBS += -L/usr/local/lib -lreadline -lpthread -lm +LDLIBS ?= -L/usr/local/lib +LDLIBS += -lreadline -lpthread -lm # RPi Zero gcc requires -latomic # but MacOSX /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld @@ -55,14 +50,16 @@ MBEDTLSLIB = $(MBEDTLSLIBPATH)/libmbedtls.a CBORLIBPATH = ./tinycbor CBORLIB = $(CBORLIBPATH)/tinycbor.a REVENGFLAGS = -DPRESETS -LIBS = -I../common/zlib -Iuart -I$(LUALIBPATH) -I$(MBEDTLSLIBPATH) -I$(JANSSONLIBPATH) -I$(CBORLIBPATH) -INCLUDES_CLIENT = -I. -I../include -I../common -I/opt/local/include $(LIBS) -LDFLAGS = $(ENV_LDFLAGS) -CFLAGS = $(ENV_CFLAGS) -std=c99 -D_ISOC99_SOURCE $(REVENGFLAGS) $(INCLUDES_CLIENT) -Wall -Werror -g -O3 +LIBS = -I../common/zlib -I$(LUALIBPATH) -I$(MBEDTLSLIBPATH) -I$(JANSSONLIBPATH) -I$(CBORLIBPATH) +INCLUDES_CLIENT = -I. -I../include -I../common -Iuart $(LIBS) +CFLAGS ?= -Wall -Werror -g -O3 +# We cannot just use CFLAGS+=... because it has impact on sub-makes if CFLAGS is defined in env: +PM3CFLAGS = $(CFLAGS) -std=c99 -D_ISOC99_SOURCE $(REVENGFLAGS) $(INCLUDES_CLIENT) ifneq (,$(findstring MINGW,$(platform))) - CFLAGS += -mno-ms-bitfields + PM3CFLAGS += -mno-ms-bitfields endif -CXXFLAGS = -I../include -Wall -O3 +CXXFLAGS ?= -Wall -Werror -O3 +PM3CXXFLAGS = $(CXXFLAGS) -I../include LUAPLATFORM = generic ifneq (,$(findstring MINGW,$(platform))) @@ -93,7 +90,7 @@ ifeq ($(QTINCLUDES), ) MOC = $(shell pkg-config --variable=moc_location QtCore) UIC = $(shell pkg-config --variable=uic_location QtCore) else - CXXFLAGS += -std=c++11 -fPIC + PM3CXXFLAGS += -std=c++11 -fPIC endif ifeq ($(QTINCLUDES), ) # if both pkg-config commands failed, search in common places @@ -103,7 +100,7 @@ ifeq ($(QTINCLUDES), ) ifneq ($(wildcard $(QTDIR)/include/QtWidgets),) QTINCLUDES += -I$(QTDIR)/include/QtWidgets QTLDLIBS = -L$(QTDIR)/lib -lQt5Widgets -lQt5Gui -lQt5Core - CXXFLAGS += -std=c++11 -fPIC + PM3CXXFLAGS += -std=c++11 -fPIC endif MOC = $(QTDIR)/bin/moc UIC = $(QTDIR)/bin/uic @@ -113,7 +110,7 @@ endif ifneq ($(QTLDLIBS),) QTGUIOBJS = $(OBJDIR)/proxgui.o $(OBJDIR)/proxguiqt.o $(OBJDIR)/proxguiqt.moc.o - CFLAGS += -DHAVE_GUI + PM3CFLAGS += -DHAVE_GUI else QTGUIOBJS = $(OBJDIR)/guidummy.o endif @@ -370,64 +367,52 @@ print-%: ; @echo $* = $($*) $(OBJDIR)/%_NOSIMD.o : %.c $(OBJDIR)/%_NOSIMD.d $(info [-] CC(NOSIMD) $<) - $(Q)$(CC) $(DEPFLAGS:%.Td=%_NOSIMD.Td) $(CFLAGS) $(HARD_SWITCH_NOSIMD) -c -o $@ $< + $(Q)$(CC) $(DEPFLAGS:%.Td=%_NOSIMD.Td) $(PM3CFLAGS) $(HARD_SWITCH_NOSIMD) -c -o $@ $< $(Q)$(MV) -f $(OBJDIR)/$*_NOSIMD.Td $(OBJDIR)/$*_NOSIMD.d $(OBJDIR)/%_MMX.o : %.c $(OBJDIR)/%_MMX.d $(info [-] CC(MMX) $<) - $(Q)$(CC) $(DEPFLAGS:%.Td=%_MMX.Td) $(CFLAGS) $(HARD_SWITCH_MMX) -c -o $@ $< + $(Q)$(CC) $(DEPFLAGS:%.Td=%_MMX.Td) $(PM3CFLAGS) $(HARD_SWITCH_MMX) -c -o $@ $< $(Q)$(MV) -f $(OBJDIR)/$*_MMX.Td $(OBJDIR)/$*_MMX.d $(OBJDIR)/%_SSE2.o : %.c $(OBJDIR)/%_SSE2.d $(info [-] CC(SSE2) $<) - $(Q)$(CC) $(DEPFLAGS:%.Td=%_SSE2.Td) $(CFLAGS) $(HARD_SWITCH_SSE2) -c -o $@ $< + $(Q)$(CC) $(DEPFLAGS:%.Td=%_SSE2.Td) $(PM3CFLAGS) $(HARD_SWITCH_SSE2) -c -o $@ $< $(Q)$(MV) -f $(OBJDIR)/$*_SSE2.Td $(OBJDIR)/$*_SSE2.d $(OBJDIR)/%_AVX.o : %.c $(OBJDIR)/%_AVX.d $(info [-] CC(AVX) $<) - $(Q)$(CC) $(DEPFLAGS:%.Td=%_AVX.Td) $(CFLAGS) $(HARD_SWITCH_AVX) -c -o $@ $< + $(Q)$(CC) $(DEPFLAGS:%.Td=%_AVX.Td) $(PM3CFLAGS) $(HARD_SWITCH_AVX) -c -o $@ $< $(Q)$(MV) -f $(OBJDIR)/$*_AVX.Td $(OBJDIR)/$*_AVX.d $(OBJDIR)/%_AVX2.o : %.c $(OBJDIR)/%_AVX2.d $(info [-] CC(AVX2) $<) - $(Q)$(CC) $(DEPFLAGS:%.Td=%_AVX2.Td) $(CFLAGS) $(HARD_SWITCH_AVX2) -c -o $@ $< + $(Q)$(CC) $(DEPFLAGS:%.Td=%_AVX2.Td) $(PM3CFLAGS) $(HARD_SWITCH_AVX2) -c -o $@ $< $(Q)$(MV) -f $(OBJDIR)/$*_AVX2.Td $(OBJDIR)/$*_AVX2.d $(OBJDIR)/%_AVX512.o : %.c $(OBJDIR)/%_AVX512.d $(info [-] CC(AVX512) $<) - $(Q)$(CC) $(DEPFLAGS:%.Td=%_AVX512.Td) $(CFLAGS) $(HARD_SWITCH_AVX512) -c -o $@ $< + $(Q)$(CC) $(DEPFLAGS:%.Td=%_AVX512.Td) $(PM3CFLAGS) $(HARD_SWITCH_AVX512) -c -o $@ $< $(Q)$(MV) -f $(OBJDIR)/$*_AVX512.Td $(OBJDIR)/$*_AVX512.d %.o: %.c $(OBJDIR)/%.o : %.c $(OBJDIR)/%.d $(info [-] CC $<) - $(Q)$(CC) $(DEPFLAGS) $(CFLAGS) $(ZLIBFLAGS) -c -o $@ $< + $(Q)$(CC) $(DEPFLAGS) $(PM3CFLAGS) $(ZLIBFLAGS) -c -o $@ $< $(Q)$(POSTCOMPILE) %.o: %.cpp $(OBJDIR)/%.o : %.cpp $(OBJDIR)/%.d $(info [-] CXX $<) - $(Q)$(CXX) $(DEPFLAGS) $(CXXFLAGS) $(QTINCLUDES) -c -o $@ $< + $(Q)$(CXX) $(DEPFLAGS) $(PM3CXXFLAGS) $(QTINCLUDES) -c -o $@ $< $(Q)$(POSTCOMPILE) %.o: %.m $(OBJDIR)/%.o : %.m $(OBJDIR)/%.d $(info [-] CC $<) - $(Q)$(CC) $(DEPFLAGS) $(CFLAGS) -c -o $@ $< + $(Q)$(CC) $(DEPFLAGS) $(PM3CFLAGS) -c -o $@ $< $(Q)$(POSTCOMPILE) -#$(CMDOBJS) $(COREOBJS): $(notdir $(%.c)) %.d -# $(CC) $(DEPFLAGS) $(CFLAGS) -c -o $@ $< -# $(POSTCOMPILE) - -#$(ZLIBOBJS): $(notdir $(%.c)) %.d -# $(CC) $(DEPFLAGS) $(CFLAGS) $(ZLIBFLAGS) -c -o $@ $< -# $(POSTCOMPILE) - -#$(QTGUIOBJS): $(notdir $(%.cpp)) %.d -# $(CXX) $(DEPFLAGS) $(CXXFLAGS) -c -o $@ $< -# $(POSTCOMPILE) - DEPENDENCY_FILES = $(patsubst %.c, $(OBJDIR)/%.d, $(CORESRCS) $(CMDSRCS) $(ZLIBSRCS) $(REVENGSRCS)) \ $(patsubst %.o, %.d, $(MULTIARCHOBJS)) \ $(patsubst %.cpp, $(OBJDIR)/%.d, $(QTGUISRCS)) \ From cce92d7431aa0df312c17ac4c2aeb882d3d510b1 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 17 Aug 2019 23:40:38 +0200 Subject: [PATCH 0369/1854] Attempt to unify host makefiles with a Makefile.host --- Makefile.host | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 Makefile.host diff --git a/Makefile.host b/Makefile.host new file mode 100644 index 000000000..9ab7ce8ca --- /dev/null +++ b/Makefile.host @@ -0,0 +1,72 @@ +# Hide full compilation line: +ifneq ($(V),1) + Q?=@ +endif +# To see full command lines, use make V=1 + +CC = gcc +LD = gcc +RM = rm -f +MV = mv +CP = cp -a +MKDIR = mkdir + +CFLAGS ?= -Wall -Werror -O3 +CFLAGS += $(MYDEFS) $(MYCFLAGS) $(MYINCLUDES) + +platform = $(shell uname) + +ifeq ($(platform),Darwin) +AR= /usr/bin/ar rcs +RANLIB= /usr/bin/ranlib +else +AR= ar rcs +RANLIB= ranlib +endif +RM= rm -f +RMDIR= rm -rf + +vpath %.c $(MYSRCPATHS) + +# Flags to generate temporary dependency files +DEPFLAGS = -MT $@ -MMD -MP -MF $(OBJDIR)/$*.Td +# make temporary to final dependency files after successful compilation +POSTCOMPILE = $(MV) -f $(OBJDIR)/$*.Td $(OBJDIR)/$*.d + +BINDIR := . +OBJDIR := obj + +MYOBJS = $(MYSRCS:%.c=$(OBJDIR)/%.o) +CLEAN = $(foreach bin,$(MYLIBS) $(BINS) $(LIB_A),$(BINDIR)/$(bin)) + +all: $(foreach bin,$(MYLIBS) $(BINS) $(LIB_A),$(BINDIR)/$(bin)) + +clean: + $(Q)$(RM) $(CLEAN) + $(Q)$(RMDIR) $(OBJDIR) + +.PHONY: all clean + +$(BINDIR)/$(LIB_A): $(MYOBJS) + $(info [=] AR $(notdir $@)) + $(Q)$(AR) $@ $(MYOBJS) + $(Q)$(RANLIB) $@ + +$(BINDIR)/% : $(OBJDIR)/%.o $(MYOBJS) $(MYLIBS) + $(info [=] LD $(notdir $@)) + $(Q)$(LD) $(LDFLAGS) $(MYOBJS) $< -o $@ $(MYLIBS) + +$(OBJDIR)/%.o : %.c | $(OBJDIR) + $(info [-] CC $<) + $(Q)$(CC) $(DEPFLAGS) $(CFLAGS) -c -o $@ $< + $(Q)$(POSTCOMPILE) + +$(OBJDIR): + $(Q)$(MKDIR) $(OBJDIR) + +DEPENDENCY_FILES = $(MYOBJS:%.o=%.d) $(BINS:%=$(OBJDIR)/%.d) + +$(DEPENDENCY_FILES): ; +.PRECIOUS: $(DEPENDENCY_FILES) + +-include $(DEPENDENCY_FILES) From 9767c075d90ea8027f6761410dbb1aedc54731d0 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 16 Aug 2019 22:06:04 +0200 Subject: [PATCH 0370/1854] rework jansson Makefile, use Makefile.host --- client/jansson/Makefile | 74 ++++------------------------------------- 1 file changed, 7 insertions(+), 67 deletions(-) diff --git a/client/jansson/Makefile b/client/jansson/Makefile index e06ffbc76..dc4ae230b 100644 --- a/client/jansson/Makefile +++ b/client/jansson/Makefile @@ -1,81 +1,21 @@ -# Hide full compilation line: -ifneq ($(V),1) - Q?=@ -endif -# To see full command lines, use make V=1 - -include_HEADERS = jansson.h -nodist_include_HEADERS = jansson_config.h - -LIB_A = libjansson.a -libjansson_la_SOURCES = \ +MYSRCPATHS = +MYINCLUDES = -I. +MYCFLAGS = -std=c99 -D_ISOC99_SOURCE -Wno-unused-function +MYDEFS = -DHAVE_STDINT_H +MYSRCS = \ dump.c \ error.c \ hashtable.c \ - hashtable.h \ hashtable_seed.c \ - jansson_private.h \ load.c \ - lookup3.h \ memory.c \ pack_unpack.c \ strbuffer.c \ - strbuffer.h \ strconv.c \ utf.c \ - utf.h \ path.c \ value.c -libjansson_la_LDFLAGS = \ - -no-undefined \ - -export-symbols-regex '^json_' \ - -version-info 15:0:11 +LIB_A = libjansson.a -CFILES = $(filter %.c, $(libjansson_la_SOURCES)) -CMDOBJS = $(CFILES:%.c=%.o) -CLEAN = $(CMDOBJS) - -platform = $(shell uname) - -CC= gcc -CFLAGS= -O2 -Wall -Wno-unused-variable -Wno-unused-function - -LDFLAGS= $(SYSLDFLAGS) $(libjansson_la_LDFLAGS) -LIBS= $(SYSLIBS) $(MYLIBS) -DEFAULT_INCLUDES = -I. -DEFS = -DHAVE_STDINT_H - -ifeq ($(platform),Darwin) -AR= /usr/bin/ar rcs -RANLIB= /usr/bin/ranlib -else -AR= ar rcs -RANLIB= ranlib -endif -RM= rm -f -TST= echo - -SYSLDFLAGS= -SYSLIBS= - -MYLIBS= -MYOBJS= - -$(LIB_A): $(CMDOBJS) - $(info [=] AR $@) - $(Q)$(AR) $(LIB_A) $(CMDOBJS) - $(Q)$(RANLIB) $(LIB_A) - -all: $(LIB_A) - -clean: - $(Q)$(RM) $(CLEAN) - $(Q)$(RM) $(LIB_A) - -%.o: %.c - $(info [-] CC $<) - $(Q)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(CFLAGS) -c -o $@ $< $(LIBS) - -.PHONY: all clean - +include ../../Makefile.host From 7b7883380056262a45a489fd081c7b747be9c23b Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 16 Aug 2019 22:06:25 +0200 Subject: [PATCH 0371/1854] rework liblua Makefile and skip clients compilation, use Makefile.host --- client/liblua/Makefile | 190 +++++------------------------------------ 1 file changed, 22 insertions(+), 168 deletions(-) diff --git a/client/liblua/Makefile b/client/liblua/Makefile index 2b3d7614f..250f4b7ee 100644 --- a/client/liblua/Makefile +++ b/client/liblua/Makefile @@ -1,106 +1,27 @@ -# Makefile for building Lua -# See ../doc/readme.html for installation and customization instructions. +MYSRCPATHS = +MYINCLUDES = -I. +# Lua lib is not ready for C99 style... +#MYCFLAGS = -std=c99 -D_ISOC99_SOURCE +MYCFLAGS = +MYDEFS = -DLUA_COMPAT_ALL $(SYSCFLAGS) +MYSRCS = lapi.c lcode.c lctype.c ldebug.c ldo.c ldump.c lfunc.c lgc.c llex.c \ + lmem.c lobject.c lopcodes.c lparser.c lstate.c lstring.c ltable.c \ + ltm.c lundump.c lvm.c lzio.c \ + lauxlib.c lbaselib.c lbitlib.c lcorolib.c ldblib.c liolib.c \ + lmathlib.c loslib.c lstrlib.c ltablib.c loadlib.c linit.c -# == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT ======================= +SYSCFLAGS= -# Hide full compilation line: -ifneq ($(V),1) - Q?=@ -endif -# To see full command lines, use make V=1 +LIB_A= liblua.a # Your platform. See PLATS for possible values. PLAT= none -platform= $(shell uname) - -CC= gcc -CFLAGS= -O3 -Wall -DLUA_COMPAT_ALL $(SYSCFLAGS) $(MYCFLAGS) -LDFLAGS= $(SYSLDFLAGS) $(MYLDFLAGS) -LIBS= -lm $(SYSLIBS) $(MYLIBS) - -ifeq ($(platform),Darwin) -AR= /usr/bin/ar rc -RANLIB= /usr/bin/ranlib -else -AR= ar rc -RANLIB= ranlib -endif -RM= rm -f - -SYSCFLAGS= -SYSLDFLAGS= -SYSLIBS= - -MYCFLAGS= -MYLDFLAGS= -MYLIBS= -MYOBJS= - -# == END OF USER SETTINGS -- NO NEED TO CHANGE ANYTHING BELOW THIS LINE ======= - -%.o: %.c - $(info [-] CC $<) - $(Q)$(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $< - PLATS= aix ansi bsd freebsd generic linux macosx mingw posix solaris -LUA_A= liblua.a -CORE_O= lapi.o lcode.o lctype.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o \ - lmem.o lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o \ - ltm.o lundump.o lvm.o lzio.o -LIB_O= lauxlib.o lbaselib.o lbitlib.o lcorolib.o ldblib.o liolib.o \ - lmathlib.o loslib.o lstrlib.o ltablib.o loadlib.o linit.o -BASE_O= $(CORE_O) $(LIB_O) $(MYOBJS) - -LUA_T= lua -LUA_O= lua.o - -LUAC_T= luac -LUAC_O= luac.o - -ALL_O= $(BASE_O) $(LUA_O) $(LUAC_O) -ALL_T= $(LUA_A) $(LUA_T) $(LUAC_T) -ALL_A= $(LUA_A) - -# Targets start here. default: $(PLAT) -all: $(ALL_T) - -o: $(ALL_O) - -a: $(ALL_A) - -$(LUA_A): $(BASE_O) - $(info [=] AR $@) - $(Q)$(AR) $@ $(BASE_O) - $(Q)$(RANLIB) $@ - -$(LUA_T): $(LUA_O) $(LUA_A) - $(info [=] LD $@) - $(Q)$(CC) -o $@ $(LDFLAGS) $(LUA_O) $(LUA_A) $(LIBS) - -$(LUAC_T): $(LUAC_O) $(LUA_A) - $(info [=] LD $@) - $(Q)$(CC) -o $@ $(LDFLAGS) $(LUAC_O) $(LUA_A) $(LIBS) - -clean: - $(Q)$(RM) $(ALL_T) $(ALL_O) - -depend: - $(info GEN DEPS) - $(Q)$(CC) $(CFLAGS) -MM l*.c - -echo: - @echo "PLAT= $(PLAT)" - @echo "CC= $(CC)" - @echo "CFLAGS= $(CFLAGS)" - @echo "LDFLAGS= $(SYSLDFLAGS)" - @echo "LIBS= $(LIBS)" - @echo "AR= $(AR)" - @echo "RANLIB= $(RANLIB)" - @echo "RM= $(RM)" +include ../../Makefile.host # Convenience targets for popular platforms ALL= all @@ -110,99 +31,32 @@ none: @echo " $(PLATS)" aix: - $(Q)$(MAKE) $(ALL) CC="xlc" CFLAGS="-O2 -DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-ldl" SYSLDFLAGS="-brtl -bexpall" + $(Q)$(MAKE) $(ALL) CC="xlc" CFLAGS="-O2 -DLUA_USE_POSIX -DLUA_USE_DLOPEN" ansi: $(Q)$(MAKE) $(ALL) SYSCFLAGS="-DLUA_ANSI" bsd: - $(Q)$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-Wl,-E" + $(Q)$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" freebsd: - $(Q)$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -lreadline" + $(Q)$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" generic: $(ALL) linux: - $(Q)$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -ldl -lreadline -ltermcap -lncurses" + $(Q)$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" macosx: - $(Q)$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_MACOSX" SYSLIBS="-lreadline" + $(Q)$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_MACOSX" mingw: - $(Q)$(MAKE) "LUA_A=lua52.dll" "LUA_T=lua.exe" \ - "AR=$(CC) -shared -o" "RANLIB=strip --strip-unneeded" \ - "SYSCFLAGS=-DLUA_BUILD_AS_DLL" "SYSLIBS=" "SYSLDFLAGS=-s" lua.exe - $(Q)$(MAKE) "LUAC_T=luac.exe" luac.exe + $(Q)$(MAKE) $(ALL) posix: $(Q)$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX" solaris: - $(Q)$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-ldl" - -# list targets that do not create files (but not all makes understand .PHONY) -.PHONY: all $(PLATS) default o a clean depend echo none - -# DO NOT DELETE - -lapi.o: lapi.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h ltm.h \ - lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lstring.h ltable.h lundump.h \ - lvm.h -lauxlib.o: lauxlib.c lua.h luaconf.h lauxlib.h -lbaselib.o: lbaselib.c lua.h luaconf.h lauxlib.h lualib.h -lbitlib.o: lbitlib.c lua.h luaconf.h lauxlib.h lualib.h -lcode.o: lcode.c lua.h luaconf.h lcode.h llex.h lobject.h llimits.h \ - lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h lgc.h \ - lstring.h ltable.h lvm.h -lcorolib.o: lcorolib.c lua.h luaconf.h lauxlib.h lualib.h -lctype.o: lctype.c lctype.h lua.h luaconf.h llimits.h -ldblib.o: ldblib.c lua.h luaconf.h lauxlib.h lualib.h -ldebug.o: ldebug.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h \ - ltm.h lzio.h lmem.h lcode.h llex.h lopcodes.h lparser.h ldebug.h ldo.h \ - lfunc.h lstring.h lgc.h ltable.h lvm.h -ldo.o: ldo.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h ltm.h \ - lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lopcodes.h lparser.h \ - lstring.h ltable.h lundump.h lvm.h -ldump.o: ldump.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h \ - lzio.h lmem.h lundump.h -lfunc.o: lfunc.c lua.h luaconf.h lfunc.h lobject.h llimits.h lgc.h \ - lstate.h ltm.h lzio.h lmem.h -lgc.o: lgc.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \ - lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h -linit.o: linit.c lua.h luaconf.h lualib.h lauxlib.h -liolib.o: liolib.c lua.h luaconf.h lauxlib.h lualib.h -llex.o: llex.c lua.h luaconf.h lctype.h llimits.h ldo.h lobject.h \ - lstate.h ltm.h lzio.h lmem.h llex.h lparser.h lstring.h lgc.h ltable.h -lmathlib.o: lmathlib.c lua.h luaconf.h lauxlib.h lualib.h -lmem.o: lmem.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \ - ltm.h lzio.h lmem.h ldo.h lgc.h -loadlib.o: loadlib.c lua.h luaconf.h lauxlib.h lualib.h -lobject.o: lobject.c lua.h luaconf.h lctype.h llimits.h ldebug.h lstate.h \ - lobject.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h lvm.h -lopcodes.o: lopcodes.c lopcodes.h llimits.h lua.h luaconf.h -loslib.o: loslib.c lua.h luaconf.h lauxlib.h lualib.h -lparser.o: lparser.c lua.h luaconf.h lcode.h llex.h lobject.h llimits.h \ - lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h lfunc.h \ - lstring.h lgc.h ltable.h -lstate.o: lstate.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h \ - ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h llex.h lstring.h \ - ltable.h -lstring.o: lstring.c lua.h luaconf.h lmem.h llimits.h lobject.h lstate.h \ - ltm.h lzio.h lstring.h lgc.h -lstrlib.o: lstrlib.c lua.h luaconf.h lauxlib.h lualib.h -ltable.o: ltable.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \ - ltm.h lzio.h lmem.h ldo.h lgc.h lstring.h ltable.h lvm.h -ltablib.o: ltablib.c lua.h luaconf.h lauxlib.h lualib.h -ltm.o: ltm.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h lzio.h \ - lmem.h lstring.h lgc.h ltable.h -lua.o: lua.c lua.h luaconf.h lauxlib.h lualib.h -luac.o: luac.c lua.h luaconf.h lauxlib.h lobject.h llimits.h lstate.h \ - ltm.h lzio.h lmem.h lundump.h ldebug.h lopcodes.h -lundump.o: lundump.c lua.h luaconf.h ldebug.h lstate.h lobject.h \ - llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lstring.h lgc.h lundump.h -lvm.o: lvm.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \ - lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lstring.h ltable.h lvm.h -lzio.o: lzio.c lua.h luaconf.h llimits.h lmem.h lstate.h lobject.h ltm.h \ - lzio.h + $(Q)$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" +.PHONY: all $(PLATS) default clean depend none From 829934886fea392454f80fd47205253b1b7dc0e1 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 16 Aug 2019 22:32:22 +0200 Subject: [PATCH 0372/1854] rework tinycbor Makefile, use Makefile.host --- client/tinycbor/Makefile | 62 +++++++--------------------------------- 1 file changed, 11 insertions(+), 51 deletions(-) diff --git a/client/tinycbor/Makefile b/client/tinycbor/Makefile index af22846e9..6470246d4 100644 --- a/client/tinycbor/Makefile +++ b/client/tinycbor/Makefile @@ -1,11 +1,10 @@ -# Hide full compilation line: -ifneq ($(V),1) - Q?=@ -endif -# To see full command lines, use make V=1 - -LIB_A = tinycbor.a -tinycbor_SOURCES = \ +MYSRCPATHS = +MYINCLUDES = +# Strange errors on Mingw when compiling with C99 +#MYCFLAGS = -std=c99 -D_ISOC99_SOURCE +MYCFLAGS = +MYDEFS = +MYSRCS = \ cborencoder.c \ cborencoder_close_container_checked.c \ cborerrorstrings.c \ @@ -15,48 +14,9 @@ tinycbor_SOURCES = \ cbortojson.c \ cborvalidation.c \ -CFILES = $(filter %.c, $(tinycbor_SOURCES)) -CMDOBJS = $(CFILES:%.c=%.o) -CLEAN = $(CMDOBJS) +LIB_A = tinycbor.a -platform = $(shell uname) - -CC= gcc -CFLAGS= -O2 -Wall -Wno-unused-variable -Wno-unused-function -LIBS= $(SYSLIBS) $(MYLIBS) -DEFAULT_INCLUDES = -I. -I.. -DEFS = -DHAVE_STDINT_H - -ifeq ($(platform),Darwin) -AR= /usr/bin/ar rcs -RANLIB= /usr/bin/ranlib -else -AR= ar rcs -RANLIB= ranlib -endif -RM= rm -f -TST= echo - -SYSLDFLAGS= -SYSLIBS= - -MYLIBS= -MYOBJS= - -$(LIB_A): $(CMDOBJS) - $(info [=] AR $@) - $(Q)$(AR) $(LIB_A) $(CMDOBJS) - $(Q)$(RANLIB) $(LIB_A) - -all: $(LIB_A) - -clean: - $(Q)$(RM) $(CLEAN) - $(Q)$(RM) $(LIB_A) - -%.o: %.c - $(info [-] CC $<) - $(Q)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(CFLAGS) -c -o $@ $< $(LIBS) - -.PHONY: all clean +# Strange errors on Mingw when compiling with -O3 +CFLAGS ?= -Wall -Werror -O2 +include ../../Makefile.host From 5d699610c95ca2f71eb472db1de5bb33ad7e1fd5 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 17 Aug 2019 11:03:15 +0200 Subject: [PATCH 0373/1854] rework hid-flasher Makefile --- tools/deprecated-hid-flasher/flasher/Makefile | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/tools/deprecated-hid-flasher/flasher/Makefile b/tools/deprecated-hid-flasher/flasher/Makefile index bff511459..52b1229fe 100644 --- a/tools/deprecated-hid-flasher/flasher/Makefile +++ b/tools/deprecated-hid-flasher/flasher/Makefile @@ -5,30 +5,27 @@ #----------------------------------------------------------------------------- CC=gcc -CXX=g++ -#COMMON_FLAGS = -m32 +LD=gcc OBJDIR = obj -LDLIBS = -lreadline -lpthread -CFLAGS = -std=gnu99 -Wall -Wno-unused-function $(COMMON_FLAGS) -g -O3 +LDLIBS = +CFLAGS ?= -Wall -Werror -g -O3 +CFLAGS += -std=gnu99 ifeq ($(platform),Darwin) LDLIBS += -lusb-1.0 else LDLIBS += -lusb endif -LDFLAGS = $(COMMON_FLAGS) -CXXFLAGS = - RM = rm -f -BINS = flasher -CLEAN = flasher flasher.exe $(OBJDIR)/*.o *.o +BINS = pm3-hid-flasher +CLEAN = pm3-hid-flasher pm3-hid-flasher.exe $(OBJDIR)/*.o all: $(BINS) -flasher: $(OBJDIR)/flash.o $(OBJDIR)/flasher.o $(OBJDIR)/proxusb.o - $(CXX) $(CXXFLAGS) $^ $(LDLIBS) -o $@ +pm3-hid-flasher: $(OBJDIR)/flash.o $(OBJDIR)/flasher.o $(OBJDIR)/proxusb.o + $(LD) $(LDFLAGS) $^ $(LDLIBS) -o $@ $(OBJDIR)/%.o: %.c $(CC) $(CFLAGS) -c -o $@ $< From aebfe0af1909ad655a81897190ba981d2fd0da1d Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 17 Aug 2019 11:23:48 +0200 Subject: [PATCH 0374/1854] rework mfkey Makefile and move util_posix to common, use Makefile.host --- {client => common}/util_posix.c | 0 {client => common}/util_posix.h | 0 tools/mfkey/Makefile | 34 ++++++++++----------------------- 3 files changed, 10 insertions(+), 24 deletions(-) rename {client => common}/util_posix.c (100%) rename {client => common}/util_posix.h (100%) diff --git a/client/util_posix.c b/common/util_posix.c similarity index 100% rename from client/util_posix.c rename to common/util_posix.c diff --git a/client/util_posix.h b/common/util_posix.h similarity index 100% rename from client/util_posix.h rename to common/util_posix.h diff --git a/tools/mfkey/Makefile b/tools/mfkey/Makefile index 24508265a..27fa95aa0 100644 --- a/tools/mfkey/Makefile +++ b/tools/mfkey/Makefile @@ -1,27 +1,13 @@ -# Hide full compilation line: -ifneq ($(V),1) - Q?=@ -endif -# To see full command lines, use make V=1 +MYSRCPATHS = ../../common ../../common/crapto1 +MYSRCS = crypto1.c crapto1.c bucketsort.c +MYINCLUDES = -I../../include -I../../common +MYCFLAGS = -std=c99 -D_ISOC99_SOURCE +MYDEFS = -VPATH = ../../common ../../common/crapto1 ../../client -CC = gcc -LD = gcc -CFLAGS += -std=c99 -D_ISOC99_SOURCE -I../../include -I../../common -I../../client -Wall -O3 -LDFLAGS += +BINS = mfkey32 mfkey32v2 mfkey64 -OBJS = crypto1.o crapto1.o parity.o util_posix.o bucketsort.o -EXES = mfkey32 mfkey32v2 mfkey64 +include ../../Makefile.host -all: $(OBJS) $(EXES) - -%.o : %.c - $(info [-] CC $<) - $(Q)$(CC) $(CFLAGS) -c -o $@ $< - -% : %.c $(OBJS) - $(info [=] LD $@) - $(Q)$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJS) $< - -clean: - $(Q)rm -f $(OBJS) $(EXES) +mfkey32 : $(OBJDIR)/mfkey32.o $(MYOBJS) +mfkey32v2 : $(OBJDIR)/mfkey32v2.o $(MYOBJS) +mfkey64 : $(OBJDIR)/mfkey64.o $(MYOBJS) From 43ffed1a261f7a5af1480ff0009b9961e63551bd Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 17 Aug 2019 13:07:27 +0200 Subject: [PATCH 0375/1854] rework nonce2key Makefile, use common crapto1, use Makefile.host --- tools/nonce2key/Makefile | 39 +-- tools/nonce2key/crapto1.c | 549 ------------------------------------ tools/nonce2key/crapto1.h | 87 ------ tools/nonce2key/crypto1.c | 125 -------- tools/nonce2key/nonce2key.c | 4 +- 5 files changed, 10 insertions(+), 794 deletions(-) delete mode 100644 tools/nonce2key/crapto1.c delete mode 100644 tools/nonce2key/crapto1.h delete mode 100644 tools/nonce2key/crypto1.c diff --git a/tools/nonce2key/Makefile b/tools/nonce2key/Makefile index 481c3e275..8b5d05278 100644 --- a/tools/nonce2key/Makefile +++ b/tools/nonce2key/Makefile @@ -1,34 +1,11 @@ -# Hide full compilation line: -ifneq ($(V),1) - Q?=@ -endif -# To see full command lines, use make V=1 +MYSRCPATHS = ../../common ../../common/crapto1 +MYSRCS = crypto1.c crapto1.c bucketsort.c +MYINCLUDES = -I../../include -I../../common +MYCFLAGS = -std=c99 -D_ISOC99_SOURCE +MYDEFS = -CC = gcc -CFLAGS = -std=c99 -Wall -O3 -I. -LDFLAGS = -std=c99 -Wall -SRC := $(wildcard *.c) -OBJ := $(SRC:.c=.o) -DEP := $(SRC:.c=.d) -PROG := nonce2key +BINS = nonce2key -all: $(PROG) +include ../../Makefile.host -$(PROG): $(OBJ) - $(info [=] LD $@) - $(Q)$(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@ - -clean: - $(Q)$(RM) $(DEP) $(OBJ) $(PROG) - -ifneq ($(filter clean,$(MAKECMDGOALS)),clean) --include $(DEP) -endif - -%.d: %.c - $(info [-] GEN $@) - $(Q)$(CC) -MM $(CFLAGS) $< | sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@ - -%.o: %.c - $(info [-] CC $<) - $(Q)$(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $< +nonce2key : $(OBJDIR)/nonce2key.o $(MYOBJS) diff --git a/tools/nonce2key/crapto1.c b/tools/nonce2key/crapto1.c deleted file mode 100644 index 3be92c0f2..000000000 --- a/tools/nonce2key/crapto1.c +++ /dev/null @@ -1,549 +0,0 @@ -/* crapto1.c - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, US$ - - Copyright (C) 2008-2014 bla -*/ -#include "crapto1.h" -#include - -#if !defined LOWMEM && defined __GNUC__ -static uint8_t filterlut[1 << 20]; -static void __attribute__((constructor)) fill_lut() { - uint32_t i; - for (i = 0; i < 1 << 20; ++i) - filterlut[i] = filter(i); -} -#define filter(x) (filterlut[(x) & 0xfffff]) -#endif - - - -typedef struct bucket { - uint32_t *head; - uint32_t *bp; -} bucket_t; - -typedef bucket_t bucket_array_t[2][0x100]; - -typedef struct bucket_info { - struct { - uint32_t *head, *tail; - } bucket_info[2][0x100]; - uint32_t numbuckets; -} bucket_info_t; - - -static void bucket_sort_intersect(uint32_t *const estart, uint32_t *const estop, - uint32_t *const ostart, uint32_t *const ostop, - bucket_info_t *bucket_info, bucket_array_t bucket) { - uint32_t *p1, *p2; - uint32_t *start[2]; - uint32_t *stop[2]; - - start[0] = estart; - stop[0] = estop; - start[1] = ostart; - stop[1] = ostop; - - // init buckets to be empty - for (uint32_t i = 0; i < 2; i++) { - for (uint32_t j = 0x00; j <= 0xff; j++) { - bucket[i][j].bp = bucket[i][j].head; - } - } - - // sort the lists into the buckets based on the MSB (contribution bits) - for (uint32_t i = 0; i < 2; i++) { - for (p1 = start[i]; p1 <= stop[i]; p1++) { - uint32_t bucket_index = (*p1 & 0xff000000) >> 24; - *(bucket[i][bucket_index].bp++) = *p1; - } - } - - - // write back intersecting buckets as sorted list. - // fill in bucket_info with head and tail of the bucket contents in the list and number of non-empty buckets. - for (uint32_t i = 0; i < 2; i++) { - p1 = start[i]; - uint32_t nonempty_bucket = 0; - for (uint32_t j = 0x00; j <= 0xff; j++) { - if (bucket[0][j].bp != bucket[0][j].head && bucket[1][j].bp != bucket[1][j].head) { // non-empty intersecting buckets only - bucket_info->bucket_info[i][nonempty_bucket].head = p1; - for (p2 = bucket[i][j].head; p2 < bucket[i][j].bp; *p1++ = *p2++); - bucket_info->bucket_info[i][nonempty_bucket].tail = p1 - 1; - nonempty_bucket++; - } - } - bucket_info->numbuckets = nonempty_bucket; - } -} - -/** update_contribution - * helper, calculates the partial linear feedback contributions and puts in MSB - */ -static inline void update_contribution(uint32_t *item, const uint32_t mask1, const uint32_t mask2) { - uint32_t p = *item >> 25; - - p = p << 1 | parity(*item & mask1); - p = p << 1 | parity(*item & mask2); - *item = p << 24 | (*item & 0xffffff); -} - -/** extend_table - * using a bit of the keystream extend the table of possible lfsr states - */ -static inline void extend_table(uint32_t *tbl, uint32_t **end, int bit, int m1, int m2, uint32_t in) { - in <<= 24; - for (*tbl <<= 1; tbl <= *end; *++tbl <<= 1) - if (filter(*tbl) ^ filter(*tbl | 1)) { - *tbl |= filter(*tbl) ^ bit; - update_contribution(tbl, m1, m2); - *tbl ^= in; - } else if (filter(*tbl) == bit) { - *++*end = tbl[1]; - tbl[1] = tbl[0] | 1; - update_contribution(tbl, m1, m2); - *tbl++ ^= in; - update_contribution(tbl, m1, m2); - *tbl ^= in; - } else - *tbl-- = *(*end)--; -} -/** extend_table_simple - * using a bit of the keystream extend the table of possible lfsr states - */ -static inline void extend_table_simple(uint32_t *tbl, uint32_t **end, int bit) { - for (*tbl <<= 1; tbl <= *end; *++tbl <<= 1) { - if (filter(*tbl) ^ filter(*tbl | 1)) { // replace - *tbl |= filter(*tbl) ^ bit; - } else if (filter(*tbl) == bit) { // insert - *++*end = *++tbl; - *tbl = tbl[-1] | 1; - } else { // drop - *tbl-- = *(*end)--; - } - } -} -/** recover - * recursively narrow down the search space, 4 bits of keystream at a time - */ -static struct Crypto1State * -recover(uint32_t *o_head, uint32_t *o_tail, uint32_t oks, - uint32_t *e_head, uint32_t *e_tail, uint32_t eks, int rem, - struct Crypto1State *sl, uint32_t in, bucket_array_t bucket) { - bucket_info_t bucket_info; - - if (rem == -1) { - for (uint32_t *e = e_head; e <= e_tail; ++e) { - *e = *e << 1 ^ parity(*e & LF_POLY_EVEN) ^ (!!(in & 4)); - for (uint32_t *o = o_head; o <= o_tail; ++o, ++sl) { - sl->even = *o; - sl->odd = *e ^ parity(*o & LF_POLY_ODD); - sl[1].odd = sl[1].even = 0; - } - } - return sl; - } - - for (uint32_t i = 0; i < 4 && rem--; i++) { - oks >>= 1; - eks >>= 1; - in >>= 2; - extend_table(o_head, &o_tail, oks & 1, LF_POLY_EVEN << 1 | 1, LF_POLY_ODD << 1, 0); - if (o_head > o_tail) - return sl; - - extend_table(e_head, &e_tail, eks & 1, LF_POLY_ODD, LF_POLY_EVEN << 1 | 1, in & 3); - if (e_head > e_tail) - return sl; - } - - bucket_sort_intersect(e_head, e_tail, o_head, o_tail, &bucket_info, bucket); - - for (int i = bucket_info.numbuckets - 1; i >= 0; i--) { - sl = recover(bucket_info.bucket_info[1][i].head, bucket_info.bucket_info[1][i].tail, oks, - bucket_info.bucket_info[0][i].head, bucket_info.bucket_info[0][i].tail, eks, - rem, sl, in, bucket); - } - - return sl; -} -/** lfsr_recovery - * recover the state of the lfsr given 32 bits of the keystream - * additionally you can use the in parameter to specify the value - * that was fed into the lfsr at the time the keystream was generated - */ -struct Crypto1State *lfsr_recovery32(uint32_t ks2, uint32_t in) { - struct Crypto1State *statelist; - uint32_t *odd_head = 0, *odd_tail = 0, oks = 0; - uint32_t *even_head = 0, *even_tail = 0, eks = 0; - - // split the keystream into an odd and even part - for (int i = 31; i >= 0; i -= 2) - oks = oks << 1 | BEBIT(ks2, i); - for (int i = 30; i >= 0; i -= 2) - eks = eks << 1 | BEBIT(ks2, i); - - odd_head = odd_tail = malloc(sizeof(uint32_t) << 21); - even_head = even_tail = malloc(sizeof(uint32_t) << 21); - statelist = malloc(sizeof(struct Crypto1State) << 18); - if (!odd_tail-- || !even_tail-- || !statelist) { - free(statelist); - statelist = 0; - goto out; - } - - statelist->odd = statelist->even = 0; - - // allocate memory for out of place bucket_sort - bucket_array_t bucket; - - for (uint32_t i = 0; i < 2; i++) { - for (uint32_t j = 0; j <= 0xff; j++) { - bucket[i][j].head = malloc(sizeof(uint32_t) << 14); - if (!bucket[i][j].head) { - goto out; - } - } - } - - // initialize statelists: add all possible states which would result into the rightmost 2 bits of the keystream - for (int i = 1 << 20; i >= 0; --i) { - if (filter(i) == (oks & 1)) - *++odd_tail = i; - if (filter(i) == (eks & 1)) - *++even_tail = i; - } - - // extend the statelists. Look at the next 8 Bits of the keystream (4 Bit each odd and even): - for (uint8_t i = 0; i < 4; i++) { - extend_table_simple(odd_head, &odd_tail, (oks >>= 1) & 1); - extend_table_simple(even_head, &even_tail, (eks >>= 1) & 1); - } - - // the statelists now contain all states which could have generated the last 10 Bits of the keystream. - // 22 bits to go to recover 32 bits in total. From now on, we need to take the "in" - // parameter into account. - in = (in >> 16 & 0xff) | (in << 16) | (in & 0xff00); // Byte swapping - recover(odd_head, odd_tail, oks, even_head, even_tail, eks, 11, statelist, in << 1, bucket); - -out: - for (uint32_t i = 0; i < 2; i++) - for (uint32_t j = 0; j <= 0xff; j++) - free(bucket[i][j].head); - free(odd_head); - free(even_head); - return statelist; -} - -static const uint32_t S1[] = { 0x62141, 0x310A0, 0x18850, 0x0C428, 0x06214, - 0x0310A, 0x85E30, 0xC69AD, 0x634D6, 0xB5CDE, 0xDE8DA, 0x6F46D, 0xB3C83, - 0x59E41, 0xA8995, 0xD027F, 0x6813F, 0x3409F, 0x9E6FA - }; -static const uint32_t S2[] = { 0x3A557B00, 0x5D2ABD80, 0x2E955EC0, 0x174AAF60, - 0x0BA557B0, 0x05D2ABD8, 0x0449DE68, 0x048464B0, 0x42423258, 0x278192A8, - 0x156042D0, 0x0AB02168, 0x43F89B30, 0x61FC4D98, 0x765EAD48, 0x7D8FDD20, - 0x7EC7EE90, 0x7F63F748, 0x79117020 - }; -static const uint32_t T1[] = { - 0x4F37D, 0x279BE, 0x97A6A, 0x4BD35, 0x25E9A, 0x12F4D, 0x097A6, 0x80D66, - 0xC4006, 0x62003, 0xB56B4, 0x5AB5A, 0xA9318, 0xD0F39, 0x6879C, 0xB057B, - 0x582BD, 0x2C15E, 0x160AF, 0x8F6E2, 0xC3DC4, 0xE5857, 0x72C2B, 0x39615, - 0x98DBF, 0xC806A, 0xE0680, 0x70340, 0x381A0, 0x98665, 0x4C332, 0xA272C -}; -static const uint32_t T2[] = { 0x3C88B810, 0x5E445C08, 0x2982A580, 0x14C152C0, - 0x4A60A960, 0x253054B0, 0x52982A58, 0x2FEC9EA8, 0x1156C4D0, 0x08AB6268, - 0x42F53AB0, 0x217A9D58, 0x161DC528, 0x0DAE6910, 0x46D73488, 0x25CB11C0, - 0x52E588E0, 0x6972C470, 0x34B96238, 0x5CFC3A98, 0x28DE96C8, 0x12CFC0E0, - 0x4967E070, 0x64B3F038, 0x74F97398, 0x7CDC3248, 0x38CE92A0, 0x1C674950, - 0x0E33A4A8, 0x01B959D0, 0x40DCACE8, 0x26CEDDF0 - }; -static const uint32_t C1[] = { 0x846B5, 0x4235A, 0x211AD}; -static const uint32_t C2[] = { 0x1A822E0, 0x21A822E0, 0x21A822E0}; -/** Reverse 64 bits of keystream into possible cipher states - * Variation mentioned in the paper. Somewhat optimized version - */ -struct Crypto1State *lfsr_recovery64(uint32_t ks2, uint32_t ks3) { - struct Crypto1State *statelist, *sl; - uint8_t oks[32], eks[32], hi[32]; - uint32_t low = 0, win = 0; - uint32_t *tail, table[1 << 16]; - int i, j; - - sl = statelist = malloc(sizeof(struct Crypto1State) << 4); - if (!sl) - return 0; - sl->odd = sl->even = 0; - - for (i = 30; i >= 0; i -= 2) { - oks[i >> 1] = BEBIT(ks2, i); - oks[16 + (i >> 1)] = BEBIT(ks3, i); - } - for (i = 31; i >= 0; i -= 2) { - eks[i >> 1] = BEBIT(ks2, i); - eks[16 + (i >> 1)] = BEBIT(ks3, i); - } - - for (i = 0xfffff; i >= 0; --i) { - if (filter(i) != oks[0]) - continue; - - *(tail = table) = i; - for (j = 1; tail >= table && j < 29; ++j) - extend_table_simple(table, &tail, oks[j]); - - if (tail < table) - continue; - - for (j = 0; j < 19; ++j) - low = low << 1 | parity(i & S1[j]); - for (j = 0; j < 32; ++j) - hi[j] = parity(i & T1[j]); - - for (; tail >= table; --tail) { - for (j = 0; j < 3; ++j) { - *tail = *tail << 1; - *tail |= parity((i & C1[j]) ^ (*tail & C2[j])); - if (filter(*tail) != oks[29 + j]) - goto continue2; - } - - for (j = 0; j < 19; ++j) - win = win << 1 | parity(*tail & S2[j]); - - win ^= low; - for (j = 0; j < 32; ++j) { - win = win << 1 ^ hi[j] ^ parity(*tail & T2[j]); - if (filter(win) != eks[j]) - goto continue2; - } - - *tail = *tail << 1 | parity(LF_POLY_EVEN & *tail); - sl->odd = *tail ^ parity(LF_POLY_ODD & win); - sl->even = win; - ++sl; - sl->odd = sl->even = 0; -continue2: - ; - } - } - return statelist; -} - -/** lfsr_rollback_bit - * Rollback the shift register in order to get previous states - */ -uint8_t lfsr_rollback_bit(struct Crypto1State *s, uint32_t in, int fb) { - int out; - uint8_t ret; - uint32_t t; - - s->odd &= 0xffffff; - t = s->odd, s->odd = s->even, s->even = t; - - out = s->even & 1; - out ^= LF_POLY_EVEN & (s->even >>= 1); - out ^= LF_POLY_ODD & s->odd; - out ^= !!in; - out ^= (ret = filter(s->odd)) & (!!fb); - - s->even |= parity(out) << 23; - return ret; -} -/** lfsr_rollback_byte - * Rollback the shift register in order to get previous states - */ -uint8_t lfsr_rollback_byte(struct Crypto1State *s, uint32_t in, int fb) { - uint8_t ret = 0; - ret |= lfsr_rollback_bit(s, BIT(in, 7), fb) << 7; - ret |= lfsr_rollback_bit(s, BIT(in, 6), fb) << 6; - ret |= lfsr_rollback_bit(s, BIT(in, 5), fb) << 5; - ret |= lfsr_rollback_bit(s, BIT(in, 4), fb) << 4; - ret |= lfsr_rollback_bit(s, BIT(in, 3), fb) << 3; - ret |= lfsr_rollback_bit(s, BIT(in, 2), fb) << 2; - ret |= lfsr_rollback_bit(s, BIT(in, 1), fb) << 1; - ret |= lfsr_rollback_bit(s, BIT(in, 0), fb) << 0; - return ret; -} -/** lfsr_rollback_word - * Rollback the shift register in order to get previous states - */ -uint32_t lfsr_rollback_word(struct Crypto1State *s, uint32_t in, int fb) { - - uint32_t ret = 0; - ret |= lfsr_rollback_bit(s, BEBIT(in, 31), fb) << (31 ^ 24); - ret |= lfsr_rollback_bit(s, BEBIT(in, 30), fb) << (30 ^ 24); - ret |= lfsr_rollback_bit(s, BEBIT(in, 29), fb) << (29 ^ 24); - ret |= lfsr_rollback_bit(s, BEBIT(in, 28), fb) << (28 ^ 24); - ret |= lfsr_rollback_bit(s, BEBIT(in, 27), fb) << (27 ^ 24); - ret |= lfsr_rollback_bit(s, BEBIT(in, 26), fb) << (26 ^ 24); - ret |= lfsr_rollback_bit(s, BEBIT(in, 25), fb) << (25 ^ 24); - ret |= lfsr_rollback_bit(s, BEBIT(in, 24), fb) << (24 ^ 24); - - ret |= lfsr_rollback_bit(s, BEBIT(in, 23), fb) << (23 ^ 24); - ret |= lfsr_rollback_bit(s, BEBIT(in, 22), fb) << (22 ^ 24); - ret |= lfsr_rollback_bit(s, BEBIT(in, 21), fb) << (21 ^ 24); - ret |= lfsr_rollback_bit(s, BEBIT(in, 20), fb) << (20 ^ 24); - ret |= lfsr_rollback_bit(s, BEBIT(in, 19), fb) << (19 ^ 24); - ret |= lfsr_rollback_bit(s, BEBIT(in, 18), fb) << (18 ^ 24); - ret |= lfsr_rollback_bit(s, BEBIT(in, 17), fb) << (17 ^ 24); - ret |= lfsr_rollback_bit(s, BEBIT(in, 16), fb) << (16 ^ 24); - - ret |= lfsr_rollback_bit(s, BEBIT(in, 15), fb) << (15 ^ 24); - ret |= lfsr_rollback_bit(s, BEBIT(in, 14), fb) << (14 ^ 24); - ret |= lfsr_rollback_bit(s, BEBIT(in, 13), fb) << (13 ^ 24); - ret |= lfsr_rollback_bit(s, BEBIT(in, 12), fb) << (12 ^ 24); - ret |= lfsr_rollback_bit(s, BEBIT(in, 11), fb) << (11 ^ 24); - ret |= lfsr_rollback_bit(s, BEBIT(in, 10), fb) << (10 ^ 24); - ret |= lfsr_rollback_bit(s, BEBIT(in, 9), fb) << (9 ^ 24); - ret |= lfsr_rollback_bit(s, BEBIT(in, 8), fb) << (8 ^ 24); - - ret |= lfsr_rollback_bit(s, BEBIT(in, 7), fb) << (7 ^ 24); - ret |= lfsr_rollback_bit(s, BEBIT(in, 6), fb) << (6 ^ 24); - ret |= lfsr_rollback_bit(s, BEBIT(in, 5), fb) << (5 ^ 24); - ret |= lfsr_rollback_bit(s, BEBIT(in, 4), fb) << (4 ^ 24); - ret |= lfsr_rollback_bit(s, BEBIT(in, 3), fb) << (3 ^ 24); - ret |= lfsr_rollback_bit(s, BEBIT(in, 2), fb) << (2 ^ 24); - ret |= lfsr_rollback_bit(s, BEBIT(in, 1), fb) << (1 ^ 24); - ret |= lfsr_rollback_bit(s, BEBIT(in, 0), fb) << (0 ^ 24); - return ret; -} - -/** nonce_distance - * x,y valid tag nonces, then prng_successor(x, nonce_distance(x, y)) = y - */ -static uint16_t *dist = 0; -int nonce_distance(uint32_t from, uint32_t to) { - if (!dist) { - dist = calloc(2 << 16, sizeof(uint8_t)); - if (!dist) - return -1; - uint16_t x = 1; - for (uint16_t i = 1; i; ++i) { - dist[(x & 0xff) << 8 | x >> 8] = i; - x = x >> 1 | (x ^ x >> 2 ^ x >> 3 ^ x >> 5) << 15; - } - } - return (65535 + dist[to >> 16] - dist[from >> 16]) % 65535; -} - - -static uint32_t fastfwd[2][8] = { - { 0, 0x4BC53, 0xECB1, 0x450E2, 0x25E29, 0x6E27A, 0x2B298, 0x60ECB}, - { 0, 0x1D962, 0x4BC53, 0x56531, 0xECB1, 0x135D3, 0x450E2, 0x58980} -}; - - -/** lfsr_prefix_ks - * - * Is an exported helper function from the common prefix attack - * Described in the "dark side" paper. It returns an -1 terminated array - * of possible partial(21 bit) secret state. - * The required keystream(ks) needs to contain the keystream that was used to - * encrypt the NACK which is observed when varying only the 3 last bits of Nr - * only correct iff [NR_3] ^ NR_3 does not depend on Nr_3 - */ -uint32_t *lfsr_prefix_ks(uint8_t ks[8], int isodd) { - uint32_t *candidates = calloc(4 << 10, sizeof(uint8_t)); - if (!candidates) return 0; - - uint32_t c, entry; - int size = 0, i, good; - - for (i = 0; i < 1 << 21; ++i) { - for (c = 0, good = 1; good && c < 8; ++c) { - entry = i ^ fastfwd[isodd][c]; - good &= (BIT(ks[c], isodd) == filter(entry >> 1)); - good &= (BIT(ks[c], isodd + 2) == filter(entry)); - } - if (good) - candidates[size++] = i; - } - - candidates[size] = -1; - - return candidates; -} - -/** check_pfx_parity - * helper function which eliminates possible secret states using parity bits - */ -static struct Crypto1State *check_pfx_parity(uint32_t prefix, uint32_t rresp, uint8_t parities[8][8], uint32_t odd, uint32_t even, struct Crypto1State *sl) { - uint32_t good = 1; - - for (uint32_t c = 0; good && c < 8; ++c) { - sl->odd = odd ^ fastfwd[1][c]; - sl->even = even ^ fastfwd[0][c]; - - lfsr_rollback_bit(sl, 0, 0); - lfsr_rollback_bit(sl, 0, 0); - - uint32_t ks3 = lfsr_rollback_bit(sl, 0, 0); - uint32_t ks2 = lfsr_rollback_word(sl, 0, 0); - uint32_t ks1 = lfsr_rollback_word(sl, prefix | c << 5, 1); - - uint32_t nr = ks1 ^ (prefix | c << 5); - uint32_t rr = ks2 ^ rresp; - - good &= parity(nr & 0x000000ff) ^ parities[c][3] ^ BIT(ks2, 24); - good &= parity(rr & 0xff000000) ^ parities[c][4] ^ BIT(ks2, 16); - good &= parity(rr & 0x00ff0000) ^ parities[c][5] ^ BIT(ks2, 8); - good &= parity(rr & 0x0000ff00) ^ parities[c][6] ^ BIT(ks2, 0); - good &= parity(rr & 0x000000ff) ^ parities[c][7] ^ ks3; - } - - return sl + good; -} - -/** lfsr_common_prefix - * Implentation of the common prefix attack. - * Requires the 28 bit constant prefix used as reader nonce (pfx) - * The reader response used (rr) - * The keystream used to encrypt the observed NACK's (ks) - * The parity bits (par) - * It returns a zero terminated list of possible cipher states after the - * tag nonce was fed in - */ - -struct Crypto1State *lfsr_common_prefix(uint32_t pfx, uint32_t rr, uint8_t ks[8], uint8_t par[8][8]) { - struct Crypto1State *statelist, *s; - uint32_t *odd, *even, *o, *e, top; - - odd = lfsr_prefix_ks(ks, 1); - even = lfsr_prefix_ks(ks, 0); - - s = statelist = malloc((sizeof * statelist) << 24); // was << 20. Need more for no_par special attack. Enough??? - if (!s || !odd || !even) { - free(statelist); - statelist = 0; - goto out; - } - - for (o = odd; *o + 1; ++o) - for (e = even; *e + 1; ++e) - for (top = 0; top < 64; ++top) { - *o += 1 << 21; - *e += (!(top & 7) + 1) << 21; - s = check_pfx_parity(pfx, rr, par, *o, *e, s); - } - - s->odd = s->even = 0; -out: - free(odd); - free(even); - return statelist; -} diff --git a/tools/nonce2key/crapto1.h b/tools/nonce2key/crapto1.h deleted file mode 100644 index e1f9c7570..000000000 --- a/tools/nonce2key/crapto1.h +++ /dev/null @@ -1,87 +0,0 @@ -/* crapto1.h - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - MA 02110-1301, US$ - - Copyright (C) 2008-2014 bla -*/ -#ifndef CRAPTO1_H__ -#define CRAPTO1_H__ -#include - -struct Crypto1State {uint32_t odd, even;}; -struct Crypto1State *crypto1_create(uint64_t); -void crypto1_destroy(struct Crypto1State *); -void crypto1_get_lfsr(struct Crypto1State *, uint64_t *); -uint8_t crypto1_bit(struct Crypto1State *, uint8_t, int); -uint8_t crypto1_byte(struct Crypto1State *, uint8_t, int); -uint32_t crypto1_word(struct Crypto1State *, uint32_t, int); -uint32_t prng_successor(uint32_t x, uint32_t n); - -struct Crypto1State *lfsr_recovery32(uint32_t ks2, uint32_t in); -struct Crypto1State *lfsr_recovery64(uint32_t ks2, uint32_t ks3); -uint32_t *lfsr_prefix_ks(uint8_t ks[8], int isodd); -struct Crypto1State *lfsr_common_prefix(uint32_t pfx, uint32_t rr, uint8_t ks[8], uint8_t par[8][8]); - -uint8_t lfsr_rollback_bit(struct Crypto1State *s, uint32_t in, int fb); -uint8_t lfsr_rollback_byte(struct Crypto1State *s, uint32_t in, int fb); -uint32_t lfsr_rollback_word(struct Crypto1State *s, uint32_t in, int fb); -int nonce_distance(uint32_t from, uint32_t to); -#define SWAPENDIAN(x)\ - (x = (x >> 8 & 0xff00ff) | (x & 0xff00ff) << 8, x = x >> 16 | x << 16) - -#define FOREACH_VALID_NONCE(N, FILTER, FSIZE)\ - uint32_t __n = 0,__M = 0, N = 0;\ - int __i;\ - for(; __n < 1 << 16; N = prng_successor(__M = ++__n, 16))\ - for(__i = FSIZE - 1; __i >= 0; __i--)\ - if(BIT(FILTER, __i) ^ parity(__M & 0xFF01))\ - break;\ - else if(__i)\ - __M = prng_successor(__M, (__i == 7) ? 48 : 8);\ - else - -#define LF_POLY_ODD (0x29CE5C) -#define LF_POLY_EVEN (0x870804) -#define BIT(x, n) ((x) >> (n) & 1) -#define BEBIT(x, n) BIT(x, (n) ^ 24) -static inline int parity(uint32_t x) { -#if !defined __i386__ || !defined __GNUC__ - x ^= x >> 16; - x ^= x >> 8; - x ^= x >> 4; - return BIT(0x6996, x & 0xf); -#else - __asm__("movl %1, %%eax\n" - "mov %%ax, %%cx\n" - "shrl $0x10, %%eax\n" - "xor %%ax, %%cx\n" - "xor %%ch, %%cl\n" - "setpo %%al\n" - "movzx %%al, %0\n": "=r"(x) : "r"(x): "eax", "ecx"); - return x; -#endif -} -static inline int filter(uint32_t const x) { - uint32_t f; - - f = 0xf22c0 >> (x & 0xf) & 16; - f |= 0x6c9c0 >> (x >> 4 & 0xf) & 8; - f |= 0x3c8b0 >> (x >> 8 & 0xf) & 4; - f |= 0x1e458 >> (x >> 12 & 0xf) & 2; - f |= 0x0d938 >> (x >> 16 & 0xf) & 1; - return BIT(0xEC57E80A, f); -} -#endif diff --git a/tools/nonce2key/crypto1.c b/tools/nonce2key/crypto1.c deleted file mode 100644 index f6f4642e2..000000000 --- a/tools/nonce2key/crypto1.c +++ /dev/null @@ -1,125 +0,0 @@ -/* crypto1.c - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - MA 02110-1301, US - - Copyright (C) 2008-2008 bla -*/ -#include "crapto1.h" -#include - -struct Crypto1State *crypto1_create(uint64_t key) { - struct Crypto1State *s = malloc(sizeof(*s)); - if (!s) return NULL; - - s->odd = s->even = 0; - - int i; - //for(i = 47;s && i > 0; i -= 2) { - for (i = 47; i > 0; i -= 2) { - s->odd = s->odd << 1 | BIT(key, (i - 1) ^ 7); - s->even = s->even << 1 | BIT(key, i ^ 7); - } - return s; -} -void crypto1_destroy(struct Crypto1State *state) { - free(state); -} -void crypto1_get_lfsr(struct Crypto1State *state, uint64_t *lfsr) { - int i; - for (*lfsr = 0, i = 23; i >= 0; --i) { - *lfsr = *lfsr << 1 | BIT(state->odd, i ^ 3); - *lfsr = *lfsr << 1 | BIT(state->even, i ^ 3); - } -} -uint8_t crypto1_bit(struct Crypto1State *s, uint8_t in, int is_encrypted) { - uint32_t feedin; - uint32_t tmp; - uint8_t ret = filter(s->odd); - - feedin = ret & (!!is_encrypted); - feedin ^= !!in; - feedin ^= LF_POLY_ODD & s->odd; - feedin ^= LF_POLY_EVEN & s->even; - s->even = s->even << 1 | parity(feedin); - - tmp = s->odd; - s->odd = s->even; - s->even = tmp; - - return ret; -} -uint8_t crypto1_byte(struct Crypto1State *s, uint8_t in, int is_encrypted) { - uint8_t ret = 0; - ret |= crypto1_bit(s, BIT(in, 0), is_encrypted) << 0; - ret |= crypto1_bit(s, BIT(in, 1), is_encrypted) << 1; - ret |= crypto1_bit(s, BIT(in, 2), is_encrypted) << 2; - ret |= crypto1_bit(s, BIT(in, 3), is_encrypted) << 3; - ret |= crypto1_bit(s, BIT(in, 4), is_encrypted) << 4; - ret |= crypto1_bit(s, BIT(in, 5), is_encrypted) << 5; - ret |= crypto1_bit(s, BIT(in, 6), is_encrypted) << 6; - ret |= crypto1_bit(s, BIT(in, 7), is_encrypted) << 7; - return ret; -} -uint32_t crypto1_word(struct Crypto1State *s, uint32_t in, int is_encrypted) { - uint32_t ret = 0; - ret |= crypto1_bit(s, BEBIT(in, 0), is_encrypted) << (0 ^ 24); - ret |= crypto1_bit(s, BEBIT(in, 1), is_encrypted) << (1 ^ 24); - ret |= crypto1_bit(s, BEBIT(in, 2), is_encrypted) << (2 ^ 24); - ret |= crypto1_bit(s, BEBIT(in, 3), is_encrypted) << (3 ^ 24); - ret |= crypto1_bit(s, BEBIT(in, 4), is_encrypted) << (4 ^ 24); - ret |= crypto1_bit(s, BEBIT(in, 5), is_encrypted) << (5 ^ 24); - ret |= crypto1_bit(s, BEBIT(in, 6), is_encrypted) << (6 ^ 24); - ret |= crypto1_bit(s, BEBIT(in, 7), is_encrypted) << (7 ^ 24); - - ret |= crypto1_bit(s, BEBIT(in, 8), is_encrypted) << (8 ^ 24); - ret |= crypto1_bit(s, BEBIT(in, 9), is_encrypted) << (9 ^ 24); - ret |= crypto1_bit(s, BEBIT(in, 10), is_encrypted) << (10 ^ 24); - ret |= crypto1_bit(s, BEBIT(in, 11), is_encrypted) << (11 ^ 24); - ret |= crypto1_bit(s, BEBIT(in, 12), is_encrypted) << (12 ^ 24); - ret |= crypto1_bit(s, BEBIT(in, 13), is_encrypted) << (13 ^ 24); - ret |= crypto1_bit(s, BEBIT(in, 14), is_encrypted) << (14 ^ 24); - ret |= crypto1_bit(s, BEBIT(in, 15), is_encrypted) << (15 ^ 24); - - ret |= crypto1_bit(s, BEBIT(in, 16), is_encrypted) << (16 ^ 24); - ret |= crypto1_bit(s, BEBIT(in, 17), is_encrypted) << (17 ^ 24); - ret |= crypto1_bit(s, BEBIT(in, 18), is_encrypted) << (18 ^ 24); - ret |= crypto1_bit(s, BEBIT(in, 19), is_encrypted) << (19 ^ 24); - ret |= crypto1_bit(s, BEBIT(in, 20), is_encrypted) << (20 ^ 24); - ret |= crypto1_bit(s, BEBIT(in, 21), is_encrypted) << (21 ^ 24); - ret |= crypto1_bit(s, BEBIT(in, 22), is_encrypted) << (22 ^ 24); - ret |= crypto1_bit(s, BEBIT(in, 23), is_encrypted) << (23 ^ 24); - - ret |= crypto1_bit(s, BEBIT(in, 24), is_encrypted) << (24 ^ 24); - ret |= crypto1_bit(s, BEBIT(in, 25), is_encrypted) << (25 ^ 24); - ret |= crypto1_bit(s, BEBIT(in, 26), is_encrypted) << (26 ^ 24); - ret |= crypto1_bit(s, BEBIT(in, 27), is_encrypted) << (27 ^ 24); - ret |= crypto1_bit(s, BEBIT(in, 28), is_encrypted) << (28 ^ 24); - ret |= crypto1_bit(s, BEBIT(in, 29), is_encrypted) << (29 ^ 24); - ret |= crypto1_bit(s, BEBIT(in, 30), is_encrypted) << (30 ^ 24); - ret |= crypto1_bit(s, BEBIT(in, 31), is_encrypted) << (31 ^ 24); - return ret; -} - -/* prng_successor - * helper used to obscure the keystream during authentication - */ -uint32_t prng_successor(uint32_t x, uint32_t n) { - SWAPENDIAN(x); - while (n--) - x = x >> 1 | (x >> 16 ^ x >> 18 ^ x >> 19 ^ x >> 21) << 31; - - return SWAPENDIAN(x); -} diff --git a/tools/nonce2key/nonce2key.c b/tools/nonce2key/nonce2key.c index f4cb10e62..d7ccec0bb 100644 --- a/tools/nonce2key/nonce2key.c +++ b/tools/nonce2key/nonce2key.c @@ -1,4 +1,4 @@ -#include "crapto1.h" +#include "crapto1/crapto1.h" #define __STDC_FORMAT_MACROS #include #include @@ -48,7 +48,7 @@ int main(const int argc, const char *argv[]) { } printf("+----+--------+---+-----+---------------+\n"); - state = lfsr_common_prefix(nr, rr, ks3x, par); + state = lfsr_common_prefix(nr, rr, ks3x, par, false); lfsr_rollback_word(state, uid ^ nt, 0); crypto1_get_lfsr(state, &key_recovered); printf("\nkey recovered: %012" PRIx64 "\n\n", key_recovered); From 6ebae499aad9c751835241633cb77d020789d926 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 16 Aug 2019 22:50:03 +0200 Subject: [PATCH 0376/1854] rework fpga_compress & isolate zlib: use Makefile.host --- client/Makefile | 30 +++++++----- common/zlib/Makefile | 10 ++++ tools/fpga_compress/Makefile | 89 ++++++---------------------------- tools/fpga_compress/obj/.dummy | 0 4 files changed, 42 insertions(+), 87 deletions(-) create mode 100644 common/zlib/Makefile delete mode 100644 tools/fpga_compress/obj/.dummy diff --git a/client/Makefile b/client/Makefile index bf047ff7d..73a1d1250 100644 --- a/client/Makefile +++ b/client/Makefile @@ -28,7 +28,7 @@ FALSE = false platform = $(shell uname) -VPATH = ../common ../common/zlib uart +VPATH = ../common uart OBJDIR = obj LDLIBS ?= -L/usr/local/lib @@ -49,8 +49,10 @@ MBEDTLSLIBPATH = ../common/mbedtls MBEDTLSLIB = $(MBEDTLSLIBPATH)/libmbedtls.a CBORLIBPATH = ./tinycbor CBORLIB = $(CBORLIBPATH)/tinycbor.a +ZLIBPATH = ../common/zlib +ZLIB = $(ZLIBPATH)/libz.a REVENGFLAGS = -DPRESETS -LIBS = -I../common/zlib -I$(LUALIBPATH) -I$(MBEDTLSLIBPATH) -I$(JANSSONLIBPATH) -I$(CBORLIBPATH) +LIBS = -I$(ZLIBPATH) -I$(LUALIBPATH) -I$(MBEDTLSLIBPATH) -I$(JANSSONLIBPATH) -I$(CBORLIBPATH) INCLUDES_CLIENT = -I. -I../include -I../common -Iuart $(LIBS) CFLAGS ?= -Wall -Werror -g -O3 # We cannot just use CFLAGS+=... because it has impact on sub-makes if CFLAGS is defined in env: @@ -251,9 +253,6 @@ ifeq ($(MULTIARCHSRCS), ) CMDSRCS += hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c endif -ZLIBSRCS = deflate.c adler32.c trees.c zutil.c inflate.c inffast.c inftrees.c -ZLIBFLAGS = -DZ_SOLO -DZ_PREFIX -DNO_GZIP -DZLIB_PM3_TUNED -#-DDEBUG -Dverbose=1 REVENGSRCS = reveng/preset.c \ reveng/reveng.c \ @@ -267,7 +266,6 @@ QTGUISRCS = proxgui.cpp proxguiqt.cpp proxguiqt.moc.cpp guidummy.cpp COREOBJS = $(CORESRCS:%.c=$(OBJDIR)/%.o) CMDOBJS = $(CMDSRCS:%.c=$(OBJDIR)/%.o) OBJCOBJS = $(OBJCSRCS:%.m=$(OBJDIR)/%.o) -ZLIBOBJS = $(ZLIBSRCS:%.c=$(OBJDIR)/%.o) REVENGOBJS = $(REVENGSRCS:%.c=$(OBJDIR)/%.o) MULTIARCHOBJS = $(MULTIARCHSRCS:%.c=$(OBJDIR)/%_NOSIMD.o) \ $(MULTIARCHSRCS:%.c=$(OBJDIR)/%_MMX.o) \ @@ -293,18 +291,18 @@ ifeq "$(SUPPORTS_AVX512)" "True" endif BINS = proxmark3 flasher -CLEAN = $(BINS) $(DEPENDENCY_FILES) $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(ZLIBOBJS) $(REVENGOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(OBJDIR)/*.o *.moc.cpp ui/ui_overlays.h lualibs/pm3_cmd.lua lualibs/mf_default_keys.lua reveng/bmptst +CLEAN = $(BINS) $(DEPENDENCY_FILES) $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(REVENGOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(OBJDIR)/*.o *.moc.cpp ui/ui_overlays.h lualibs/pm3_cmd.lua lualibs/mf_default_keys.lua reveng/bmptst # need to assign dependancies to build these first... -all: lua_build jansson_build mbedtls_build cbor_build $(BINS) +all: zlib_build lua_build jansson_build mbedtls_build cbor_build $(BINS) all-static: LDLIBS:=-static $(LDLIBS) all-static: $(BINS) -proxmark3: LDLIBS+=$(LUALIB) $(JANSSONLIB) $(MBEDTLSLIB) $(CBORLIB) $(QTLDLIBS) -proxmark3: reveng/bmptst $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(ZLIBOBJS) $(REVENGOBJS) lualibs/pm3_cmd.lua lualibs/mf_default_keys.lua +proxmark3: LDLIBS+=$(ZLIB) $(LUALIB) $(JANSSONLIB) $(MBEDTLSLIB) $(CBORLIB) $(QTLDLIBS) +proxmark3: reveng/bmptst $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(REVENGOBJS) lualibs/pm3_cmd.lua lualibs/mf_default_keys.lua $(info [=] LD $@) - $(Q)$(LD) $(LDFLAGS) $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(ZLIBOBJS) $(REVENGOBJS) $(LDLIBS) -o $@ + $(Q)$(LD) $(LDFLAGS) $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(REVENGOBJS) $(LDLIBS) -o $@ flasher: $(OBJDIR)/flash.o $(OBJDIR)/flasher.o $(COREOBJS) $(OBJCOBJS) $(info [=] LD $@) @@ -330,6 +328,7 @@ lualibs/mf_default_keys.lua : default_keys.dic clean: $(Q)$(RM) $(CLEAN) + $(Q)$(MAKE) --no-print-directory -C $(ZLIBPATH) clean $(Q)$(MAKE) --no-print-directory -C $(LUALIBPATH) clean $(Q)$(MAKE) --no-print-directory -C $(JANSSONLIBPATH) clean $(Q)$(MAKE) --no-print-directory -C $(MBEDTLSLIBPATH) clean @@ -339,6 +338,10 @@ tarbin: $(BINS) $(info [=] TAR ../proxmark3-$(platform)-bin.tar) $(Q)$(TAR) $(TARFLAGS) ../proxmark3-$(platform)-bin.tar $(BINS:%=client/%) $(WINBINS:%=client/%) +zlib_build: + $(info [*] MAKE zlib) + $(Q)$(MAKE) --no-print-directory -C $(ZLIBPATH) all + lua_build: $(info [*] MAKE liblua for $(LUAPLATFORM)) $(Q)$(MAKE) --no-print-directory -C $(LUALIBPATH) $(LUAPLATFORM) @@ -395,10 +398,11 @@ $(OBJDIR)/%_AVX512.o : %.c $(OBJDIR)/%_AVX512.d $(Q)$(CC) $(DEPFLAGS:%.Td=%_AVX512.Td) $(PM3CFLAGS) $(HARD_SWITCH_AVX512) -c -o $@ $< $(Q)$(MV) -f $(OBJDIR)/$*_AVX512.Td $(OBJDIR)/$*_AVX512.d + %.o: %.c $(OBJDIR)/%.o : %.c $(OBJDIR)/%.d $(info [-] CC $<) - $(Q)$(CC) $(DEPFLAGS) $(PM3CFLAGS) $(ZLIBFLAGS) -c -o $@ $< + $(Q)$(CC) $(DEPFLAGS) $(PM3CFLAGS) -c -o $@ $< $(Q)$(POSTCOMPILE) %.o: %.cpp @@ -413,7 +417,7 @@ $(OBJDIR)/%.o : %.m $(OBJDIR)/%.d $(Q)$(CC) $(DEPFLAGS) $(PM3CFLAGS) -c -o $@ $< $(Q)$(POSTCOMPILE) -DEPENDENCY_FILES = $(patsubst %.c, $(OBJDIR)/%.d, $(CORESRCS) $(CMDSRCS) $(ZLIBSRCS) $(REVENGSRCS)) \ +DEPENDENCY_FILES = $(patsubst %.c, $(OBJDIR)/%.d, $(CORESRCS) $(CMDSRCS) $(REVENGSRCS)) \ $(patsubst %.o, %.d, $(MULTIARCHOBJS)) \ $(patsubst %.cpp, $(OBJDIR)/%.d, $(QTGUISRCS)) \ $(patsubst %.m, $(OBJDIR)/%.d, $(OBJCSRCS)) \ diff --git a/common/zlib/Makefile b/common/zlib/Makefile new file mode 100644 index 000000000..b62071d5d --- /dev/null +++ b/common/zlib/Makefile @@ -0,0 +1,10 @@ +MYSRCPATHS = ../../common/zlib +MYSRCS = deflate.c adler32.c trees.c zutil.c inflate.c inffast.c inftrees.c +MYINCLUDES = -I../../common/zlib +MYCFLAGS = -std=c99 -D_ISOC99_SOURCE +MYDEFS = -DZ_SOLO -DNO_GZIP -DZLIB_PM3_TUNED +#-DDEBUG -Dverbose=1 + +LIB_A = libz.a + +include ../../Makefile.host diff --git a/tools/fpga_compress/Makefile b/tools/fpga_compress/Makefile index 8798ace1e..86c995924 100644 --- a/tools/fpga_compress/Makefile +++ b/tools/fpga_compress/Makefile @@ -1,80 +1,21 @@ -# Hide full compilation line: -ifneq ($(V),1) - Q?=@ -endif -# To see full command lines, use make V=1 +MYSRCPATHS = +MYINCLUDES = -I../../common_fpga +MYCFLAGS = -std=c99 -D_ISOC99_SOURCE +MYDEFS = +MYSRCS = +MYLIBS = -CC = gcc -CXX = g++ -LD = g++ -RM = rm -f -MV = mv -CP = cp -a - -platform = $(shell uname) - -VPATH = ../../common/zlib -OBJDIR = obj - -# RPi Zero gcc requires -latomic -# but MacOSX /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld -# doesn't recognize option --as-needed -ifneq ($(platform),Darwin) - LDLIBS += -Wl,--as-needed -latomic -Wl,--no-as-needed -endif - -LIBS = -I../../common/zlib -INCLUDES_CLIENT = -I../../common_fpga $(LIBS) - -CFLAGS += -std=c99 -D_ISOC99_SOURCE -DPRESETS $(INCLUDES_CLIENT) -Wall -Werror -g -O3 - -# Flags to generate temporary dependency files -DEPFLAGS = -MT $@ -MMD -MP -MF $(OBJDIR)/$*.Td -# make temporary to final dependency files after successful compilation -POSTCOMPILE = $(MV) -f $(OBJDIR)/$*.Td $(OBJDIR)/$*.d - -ZLIBSRCS = deflate.c adler32.c trees.c zutil.c inflate.c inffast.c inftrees.c -ZLIBFLAGS = -DZ_SOLO -DZ_PREFIX -DNO_GZIP -DZLIB_PM3_TUNED -#-DDEBUG -Dverbose=1 - -ZLIBOBJS = $(ZLIBSRCS:%.c=$(OBJDIR)/%.o) +ZLIBPATH = ../../common/zlib +MYINCLUDES += -I$(ZLIBPATH) +MYLIBS += $(OBJDIR)/libz.a BINS = fpga_compress -CLEAN = $(BINS) $(DEPENDENCY_FILES) $(ZLIBOBJS) $(OBJDIR)/*.o -# OSX Brew is expecting fpga_compress in client folder, some workaround for now: -ifeq ($(platform),Darwin) -CLEAN += $(foreach bin,$(BINS),../../client/$(bin)) -endif -# need to assign dependancies to build these first... -all: $(BINS) +ROOT_DIR:=$(dir $(realpath $(lastword $(MAKEFILE_LIST)))) -all-static: LDLIBS:=-static $(LDLIBS) -all-static: $(BINS) - -fpga_compress: $(OBJDIR)/fpga_compress.o $(ZLIBOBJS) - $(info [=] LD $@) - $(Q)$(LD) $(LDFLAGS) $(ZLIBFLAGS) $^ $(LDLIBS) -o $@ -# OSX Brew is expecting fpga_compress in client folder, some workaround for now: -ifeq ($(platform),Darwin) - $(Q)$(CP) $@ ../../client/ -endif - -clean: - $(Q)$(RM) $(CLEAN) - -.PHONY: all clean - -%.o: %.c -$(OBJDIR)/%.o : %.c $(OBJDIR)/%.d - $(info [-] CC $<) - $(Q)$(CC) $(DEPFLAGS) $(CFLAGS) $(ZLIBFLAGS) -c -o $@ $< - $(Q)$(POSTCOMPILE) - -DEPENDENCY_FILES = $(patsubst %.c, $(OBJDIR)/%.d, $(ZLIBSRCS)) $(OBJDIR)/fpga_compress.d - -$(DEPENDENCY_FILES): ; -.PRECIOUS: $(DEPENDENCY_FILES) - --include $(DEPENDENCY_FILES) +include ../../Makefile.host +fpga_compress: $(OBJDIR)/fpga_compress.o $(MYOBJS) +$(OBJDIR)/libz.a: + $(info [*] MAKE zlib) + $(Q)$(MAKE) --no-print-directory -C $(ZLIBPATH) OBJDIR=$(ROOT_DIR)$(OBJDIR) BINDIR=$(ROOT_DIR)$(OBJDIR) all diff --git a/tools/fpga_compress/obj/.dummy b/tools/fpga_compress/obj/.dummy deleted file mode 100644 index e69de29bb..000000000 From 8ebad97c3d36659b24ad43f2d35a02fd88f93e74 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 16 Aug 2019 22:32:34 +0200 Subject: [PATCH 0377/1854] rework mbedtls Makefile, use Makefile.host --- common/mbedtls/Makefile | 65 +++++------------------------------------ 1 file changed, 7 insertions(+), 58 deletions(-) diff --git a/common/mbedtls/Makefile b/common/mbedtls/Makefile index a16b2cfd9..52663d67e 100644 --- a/common/mbedtls/Makefile +++ b/common/mbedtls/Makefile @@ -1,11 +1,8 @@ -# Hide full compilation line: -ifneq ($(V),1) - Q?=@ -endif -# To see full command lines, use make V=1 - -LIB_A = libmbedtls.a -mbedtls_SOURCES = \ +MYSRCPATHS = +MYINCLUDES = -I. -I.. +MYCFLAGS = -std=c99 -D_ISOC99_SOURCE +MYDEFS = +MYSRCS = \ aes.c \ asn1parse.c \ asn1write.c \ @@ -49,55 +46,7 @@ mbedtls_SOURCES = \ x509.c \ x509_crl.c \ x509_crt.c -mbedtls_LDFLAGS = \ - -no-undefined \ - -export-symbols-regex '^mbedtls_' \ - -version-info 15:0:11 +LIB_A = libmbedtls.a -CFILES = $(filter %.c, $(mbedtls_SOURCES)) -CMDOBJS = $(CFILES:%.c=%.o) -CLEAN = $(CMDOBJS) - -platform = $(shell uname) - -CC= gcc -CFLAGS= -O2 -Wall -Wno-unused-variable -Wno-unused-function -LDFLAGS= $(SYSLDFLAGS) $(mbedtls_LDFLAGS) -LIBS= $(SYSLIBS) $(MYLIBS) -DEFAULT_INCLUDES = -I. -I.. -DEFS = -DHAVE_STDINT_H - -ifeq ($(platform),Darwin) -AR= /usr/bin/ar rcs -RANLIB= /usr/bin/ranlib -else -AR= ar rcs -RANLIB= ranlib -endif -RM= rm -f -TST= echo - -SYSLDFLAGS= -SYSLIBS= - -MYLIBS= -MYOBJS= - -$(LIB_A): $(CMDOBJS) - $(info [=] AR $@) - $(Q)$(AR) $(LIB_A) $(CMDOBJS) - $(Q)$(RANLIB) $(LIB_A) - -all: $(LIB_A) - -clean: - $(Q)$(RM) $(CLEAN) - $(Q)$(RM) $(LIB_A) - -%.o: %.c - $(info [-] CC $<) - $(Q)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(CFLAGS) -c -o $@ $< $(LIBS) - -.PHONY: all clean - +include ../../Makefile.host From 0115efe190931d1456d33d1fb6c2373d4d8e523f Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 16 Aug 2019 21:33:01 +0200 Subject: [PATCH 0378/1854] isolate reveng, use Makefile.host --- client/Makefile | 42 +++++++++++++++++------------------------- client/reveng/Makefile | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 25 deletions(-) create mode 100644 client/reveng/Makefile diff --git a/client/Makefile b/client/Makefile index 73a1d1250..a4384e3e9 100644 --- a/client/Makefile +++ b/client/Makefile @@ -51,12 +51,13 @@ CBORLIBPATH = ./tinycbor CBORLIB = $(CBORLIBPATH)/tinycbor.a ZLIBPATH = ../common/zlib ZLIB = $(ZLIBPATH)/libz.a -REVENGFLAGS = -DPRESETS -LIBS = -I$(ZLIBPATH) -I$(LUALIBPATH) -I$(MBEDTLSLIBPATH) -I$(JANSSONLIBPATH) -I$(CBORLIBPATH) +REVENGPATH = ./reveng +REVENGLIB = $(REVENGPATH)/libreveng.a +LIBS = -I$(LUALIBPATH) -I$(MBEDTLSLIBPATH) -I$(JANSSONLIBPATH) -I$(CBORLIBPATH) -I$(ZLIBPATH) -I$(REVENGPATH) INCLUDES_CLIENT = -I. -I../include -I../common -Iuart $(LIBS) CFLAGS ?= -Wall -Werror -g -O3 # We cannot just use CFLAGS+=... because it has impact on sub-makes if CFLAGS is defined in env: -PM3CFLAGS = $(CFLAGS) -std=c99 -D_ISOC99_SOURCE $(REVENGFLAGS) $(INCLUDES_CLIENT) +PM3CFLAGS = $(CFLAGS) -std=c99 -D_ISOC99_SOURCE $(INCLUDES_CLIENT) ifneq (,$(findstring MINGW,$(platform))) PM3CFLAGS += -mno-ms-bitfields endif @@ -253,20 +254,11 @@ ifeq ($(MULTIARCHSRCS), ) CMDSRCS += hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c endif - -REVENGSRCS = reveng/preset.c \ - reveng/reveng.c \ - reveng/cli.c \ - reveng/bmpbit.c \ - reveng/model.c \ - reveng/poly.c - QTGUISRCS = proxgui.cpp proxguiqt.cpp proxguiqt.moc.cpp guidummy.cpp COREOBJS = $(CORESRCS:%.c=$(OBJDIR)/%.o) CMDOBJS = $(CMDSRCS:%.c=$(OBJDIR)/%.o) OBJCOBJS = $(OBJCSRCS:%.m=$(OBJDIR)/%.o) -REVENGOBJS = $(REVENGSRCS:%.c=$(OBJDIR)/%.o) MULTIARCHOBJS = $(MULTIARCHSRCS:%.c=$(OBJDIR)/%_NOSIMD.o) \ $(MULTIARCHSRCS:%.c=$(OBJDIR)/%_MMX.o) \ $(MULTIARCHSRCS:%.c=$(OBJDIR)/%_SSE2.o) \ @@ -291,18 +283,18 @@ ifeq "$(SUPPORTS_AVX512)" "True" endif BINS = proxmark3 flasher -CLEAN = $(BINS) $(DEPENDENCY_FILES) $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(REVENGOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(OBJDIR)/*.o *.moc.cpp ui/ui_overlays.h lualibs/pm3_cmd.lua lualibs/mf_default_keys.lua reveng/bmptst +CLEAN = $(BINS) $(DEPENDENCY_FILES) $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(OBJDIR)/*.o *.moc.cpp ui/ui_overlays.h lualibs/pm3_cmd.lua lualibs/mf_default_keys.lua # need to assign dependancies to build these first... -all: zlib_build lua_build jansson_build mbedtls_build cbor_build $(BINS) +all: lua_build jansson_build mbedtls_build cbor_build zlib_build reveng_build $(BINS) all-static: LDLIBS:=-static $(LDLIBS) all-static: $(BINS) -proxmark3: LDLIBS+=$(ZLIB) $(LUALIB) $(JANSSONLIB) $(MBEDTLSLIB) $(CBORLIB) $(QTLDLIBS) -proxmark3: reveng/bmptst $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(REVENGOBJS) lualibs/pm3_cmd.lua lualibs/mf_default_keys.lua +proxmark3: LDLIBS+=$(LUALIB) $(JANSSONLIB) $(MBEDTLSLIB) $(CBORLIB) $(ZLIB) $(REVENGLIB) $(QTLDLIBS) +proxmark3: $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) lualibs/pm3_cmd.lua lualibs/mf_default_keys.lua $(info [=] LD $@) - $(Q)$(LD) $(LDFLAGS) $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(REVENGOBJS) $(LDLIBS) -o $@ + $(Q)$(LD) $(LDFLAGS) $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(LDLIBS) -o $@ flasher: $(OBJDIR)/flash.o $(OBJDIR)/flasher.o $(COREOBJS) $(OBJCOBJS) $(info [=] LD $@) @@ -328,20 +320,17 @@ lualibs/mf_default_keys.lua : default_keys.dic clean: $(Q)$(RM) $(CLEAN) - $(Q)$(MAKE) --no-print-directory -C $(ZLIBPATH) clean $(Q)$(MAKE) --no-print-directory -C $(LUALIBPATH) clean $(Q)$(MAKE) --no-print-directory -C $(JANSSONLIBPATH) clean $(Q)$(MAKE) --no-print-directory -C $(MBEDTLSLIBPATH) clean $(Q)$(MAKE) --no-print-directory -C $(CBORLIBPATH) clean + $(Q)$(MAKE) --no-print-directory -C $(ZLIBPATH) clean + $(Q)$(MAKE) --no-print-directory -C $(REVENGPATH) clean tarbin: $(BINS) $(info [=] TAR ../proxmark3-$(platform)-bin.tar) $(Q)$(TAR) $(TARFLAGS) ../proxmark3-$(platform)-bin.tar $(BINS:%=client/%) $(WINBINS:%=client/%) -zlib_build: - $(info [*] MAKE zlib) - $(Q)$(MAKE) --no-print-directory -C $(ZLIBPATH) all - lua_build: $(info [*] MAKE liblua for $(LUAPLATFORM)) $(Q)$(MAKE) --no-print-directory -C $(LUALIBPATH) $(LUAPLATFORM) @@ -358,10 +347,13 @@ cbor_build: $(info [*] MAKE tinycbor) $(Q)$(MAKE) --no-print-directory -C $(CBORLIBPATH) all +zlib_build: + $(info [*] MAKE zlib) + $(Q)$(MAKE) --no-print-directory -C $(ZLIBPATH) all -reveng/bmptst: reveng/bmpbit.c reveng/config.h reveng/reveng.h - $(CC) $(CFLAGS) $(REVENGFLAGS) -DBMPTST -o $@ $< - ( ./$@ && $(TOUCH) $@ ) || ( $(RM) $@ && $(FALSE) ) +reveng_build: + $(info [*] MAKE reveng) + $(Q)$(MAKE) --no-print-directory -C $(REVENGPATH) all .PHONY: all clean diff --git a/client/reveng/Makefile b/client/reveng/Makefile new file mode 100644 index 000000000..52fd1bcec --- /dev/null +++ b/client/reveng/Makefile @@ -0,0 +1,36 @@ +# reveng will compile without macros, but these may be useful: +# Add -DBMPMACRO to use bitmap size constant macros (edit config.h) +# Add -DNOFORCE to disable the -F switch +# Add -DPRESETS to compile with preset models (edit config.h) + +MYSRCPATHS = +MYINCLUDES = -I. -I.. +MYCFLAGS = -std=c99 -D_ISOC99_SOURCE +MYDEFS = -DPRESETS +MYSRCS = \ + bmpbit.c \ + cli.c \ + getopt.c \ + model.c \ + poly.c \ + preset.c \ + reveng.c + +LIB_A = libreveng.a + +TOUCH = touch +FALSE = false + +include ../../Makefile.host + +CLEAN += bmptst + +$(BINDIR)/$(LIB_A): $(BINDIR)/bmptst + +$(BINDIR)/bmptst: bmpbit.c config.h reveng.h + $(info [-] CC $<) + $(Q)$(CC) $(CFLAGS) -DBMPTST -o $@ $< + $(info [=] TEST $@) + $(Q)( ./$@ && $(TOUCH) $@ ) || ( $(RM) $@ && $(FALSE) ) + +.PHONY: all clean From 0449527e2aae99d483405fc18de346fb7613ff9c Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 18 Aug 2019 00:09:42 +0200 Subject: [PATCH 0379/1854] adapt client/Makefile to new mbedtls & zlib way of working, remove unneeded dirs --- client/Makefile | 51 +++++++++++++++++++++++------------- client/obj/.dummy | 0 client/obj/amiitool/.dummy | 0 client/obj/cliparser/.dummy | 0 client/obj/crapto1/.dummy | 0 client/obj/crypto/.dummy | 0 client/obj/emv/.dummy | 0 client/obj/emv/test/.dummy | 0 client/obj/fido/.dummy | 0 client/obj/hardnested/.dummy | 0 client/obj/jansson/.dummy | 0 client/obj/loclass/.dummy | 0 client/obj/mifare/.dummy | 0 client/obj/nonce2key/.dummy | 0 client/obj/reveng/.gitignore | 35 ------------------------- client/platforms/.gitignore | 35 ------------------------- 16 files changed, 33 insertions(+), 88 deletions(-) delete mode 100644 client/obj/.dummy delete mode 100644 client/obj/amiitool/.dummy delete mode 100644 client/obj/cliparser/.dummy delete mode 100644 client/obj/crapto1/.dummy delete mode 100644 client/obj/crypto/.dummy delete mode 100644 client/obj/emv/.dummy delete mode 100644 client/obj/emv/test/.dummy delete mode 100644 client/obj/fido/.dummy delete mode 100644 client/obj/hardnested/.dummy delete mode 100644 client/obj/jansson/.dummy delete mode 100644 client/obj/loclass/.dummy delete mode 100644 client/obj/mifare/.dummy delete mode 100644 client/obj/nonce2key/.dummy delete mode 100644 client/obj/reveng/.gitignore delete mode 100644 client/platforms/.gitignore diff --git a/client/Makefile b/client/Makefile index a4384e3e9..a556a7451 100644 --- a/client/Makefile +++ b/client/Makefile @@ -22,11 +22,14 @@ TAR = tar TARFLAGS ?= -v --ignore-failed-read -r TARFLAGS += -C .. -f RM = rm -f +RMDIR= rm -rf +MKDIR = mkdir -p MV = mv TOUCH = touch FALSE = false platform = $(shell uname) +ROOT_DIR:=$(dir $(realpath $(lastword $(MAKEFILE_LIST)))) VPATH = ../common uart OBJDIR = obj @@ -41,18 +44,22 @@ ifneq ($(platform),Darwin) LDLIBS += -Wl,--as-needed -latomic -Wl,--no-as-needed endif +# local libraries LUALIBPATH = ./liblua LUALIB = $(LUALIBPATH)/liblua.a JANSSONLIBPATH = ./jansson JANSSONLIB = $(JANSSONLIBPATH)/libjansson.a -MBEDTLSLIBPATH = ../common/mbedtls -MBEDTLSLIB = $(MBEDTLSLIBPATH)/libmbedtls.a CBORLIBPATH = ./tinycbor CBORLIB = $(CBORLIBPATH)/tinycbor.a -ZLIBPATH = ../common/zlib -ZLIB = $(ZLIBPATH)/libz.a REVENGPATH = ./reveng REVENGLIB = $(REVENGPATH)/libreveng.a + +# common libraries +MBEDTLSLIBPATH = ../common/mbedtls +MBEDTLSLIB = $(OBJDIR)/libmbedtls.a +ZLIBPATH = ../common/zlib +ZLIB = $(OBJDIR)/libz.a + LIBS = -I$(LUALIBPATH) -I$(MBEDTLSLIBPATH) -I$(JANSSONLIBPATH) -I$(CBORLIBPATH) -I$(ZLIBPATH) -I$(REVENGPATH) INCLUDES_CLIENT = -I. -I../include -I../common -Iuart $(LIBS) CFLAGS ?= -Wall -Werror -g -O3 @@ -283,10 +290,10 @@ ifeq "$(SUPPORTS_AVX512)" "True" endif BINS = proxmark3 flasher -CLEAN = $(BINS) $(DEPENDENCY_FILES) $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(OBJDIR)/*.o *.moc.cpp ui/ui_overlays.h lualibs/pm3_cmd.lua lualibs/mf_default_keys.lua +CLEAN = $(BINS) *.moc.cpp ui/ui_overlays.h lualibs/pm3_cmd.lua lualibs/mf_default_keys.lua # need to assign dependancies to build these first... -all: lua_build jansson_build mbedtls_build cbor_build zlib_build reveng_build $(BINS) +all: lua_build jansson_build cbor_build reveng_build mbedtls_build zlib_build $(BINS) all-static: LDLIBS:=-static $(LDLIBS) all-static: $(BINS) @@ -320,17 +327,17 @@ lualibs/mf_default_keys.lua : default_keys.dic clean: $(Q)$(RM) $(CLEAN) + $(Q)$(RMDIR) $(OBJDIR) $(Q)$(MAKE) --no-print-directory -C $(LUALIBPATH) clean $(Q)$(MAKE) --no-print-directory -C $(JANSSONLIBPATH) clean - $(Q)$(MAKE) --no-print-directory -C $(MBEDTLSLIBPATH) clean $(Q)$(MAKE) --no-print-directory -C $(CBORLIBPATH) clean - $(Q)$(MAKE) --no-print-directory -C $(ZLIBPATH) clean $(Q)$(MAKE) --no-print-directory -C $(REVENGPATH) clean tarbin: $(BINS) $(info [=] TAR ../proxmark3-$(platform)-bin.tar) $(Q)$(TAR) $(TARFLAGS) ../proxmark3-$(platform)-bin.tar $(BINS:%=client/%) $(WINBINS:%=client/%) +# local libraries: lua_build: $(info [*] MAKE liblua for $(LUAPLATFORM)) $(Q)$(MAKE) --no-print-directory -C $(LUALIBPATH) $(LUAPLATFORM) @@ -339,22 +346,23 @@ jansson_build: $(info [*] MAKE jansson) $(Q)$(MAKE) --no-print-directory -C $(JANSSONLIBPATH) all -mbedtls_build: - $(info [*] MAKE mbedtls) - $(Q)$(MAKE) --no-print-directory -C $(MBEDTLSLIBPATH) all - cbor_build: $(info [*] MAKE tinycbor) $(Q)$(MAKE) --no-print-directory -C $(CBORLIBPATH) all -zlib_build: - $(info [*] MAKE zlib) - $(Q)$(MAKE) --no-print-directory -C $(ZLIBPATH) all - reveng_build: $(info [*] MAKE reveng) $(Q)$(MAKE) --no-print-directory -C $(REVENGPATH) all +# common libraries: +mbedtls_build: + $(info [*] MAKE mbedtls) + $(Q)$(MAKE) --no-print-directory -C $(MBEDTLSLIBPATH) OBJDIR=$(ROOT_DIR)$(OBJDIR) BINDIR=$(ROOT_DIR)$(OBJDIR) all + +zlib_build: + $(info [*] MAKE zlib) + $(Q)$(MAKE) --no-print-directory -C $(ZLIBPATH) OBJDIR=$(ROOT_DIR)$(OBJDIR) BINDIR=$(ROOT_DIR)$(OBJDIR) all + .PHONY: all clean # easy printing of MAKE VARIABLES @@ -362,50 +370,58 @@ print-%: ; @echo $* = $($*) $(OBJDIR)/%_NOSIMD.o : %.c $(OBJDIR)/%_NOSIMD.d $(info [-] CC(NOSIMD) $<) + $(Q)$(MKDIR) $(dir $@) $(Q)$(CC) $(DEPFLAGS:%.Td=%_NOSIMD.Td) $(PM3CFLAGS) $(HARD_SWITCH_NOSIMD) -c -o $@ $< $(Q)$(MV) -f $(OBJDIR)/$*_NOSIMD.Td $(OBJDIR)/$*_NOSIMD.d $(OBJDIR)/%_MMX.o : %.c $(OBJDIR)/%_MMX.d $(info [-] CC(MMX) $<) + $(Q)$(MKDIR) $(dir $@) $(Q)$(CC) $(DEPFLAGS:%.Td=%_MMX.Td) $(PM3CFLAGS) $(HARD_SWITCH_MMX) -c -o $@ $< $(Q)$(MV) -f $(OBJDIR)/$*_MMX.Td $(OBJDIR)/$*_MMX.d $(OBJDIR)/%_SSE2.o : %.c $(OBJDIR)/%_SSE2.d $(info [-] CC(SSE2) $<) + $(Q)$(MKDIR) $(dir $@) $(Q)$(CC) $(DEPFLAGS:%.Td=%_SSE2.Td) $(PM3CFLAGS) $(HARD_SWITCH_SSE2) -c -o $@ $< $(Q)$(MV) -f $(OBJDIR)/$*_SSE2.Td $(OBJDIR)/$*_SSE2.d $(OBJDIR)/%_AVX.o : %.c $(OBJDIR)/%_AVX.d $(info [-] CC(AVX) $<) + $(Q)$(MKDIR) $(dir $@) $(Q)$(CC) $(DEPFLAGS:%.Td=%_AVX.Td) $(PM3CFLAGS) $(HARD_SWITCH_AVX) -c -o $@ $< $(Q)$(MV) -f $(OBJDIR)/$*_AVX.Td $(OBJDIR)/$*_AVX.d $(OBJDIR)/%_AVX2.o : %.c $(OBJDIR)/%_AVX2.d $(info [-] CC(AVX2) $<) + $(Q)$(MKDIR) $(dir $@) $(Q)$(CC) $(DEPFLAGS:%.Td=%_AVX2.Td) $(PM3CFLAGS) $(HARD_SWITCH_AVX2) -c -o $@ $< $(Q)$(MV) -f $(OBJDIR)/$*_AVX2.Td $(OBJDIR)/$*_AVX2.d $(OBJDIR)/%_AVX512.o : %.c $(OBJDIR)/%_AVX512.d $(info [-] CC(AVX512) $<) + $(Q)$(MKDIR) $(dir $@) $(Q)$(CC) $(DEPFLAGS:%.Td=%_AVX512.Td) $(PM3CFLAGS) $(HARD_SWITCH_AVX512) -c -o $@ $< $(Q)$(MV) -f $(OBJDIR)/$*_AVX512.Td $(OBJDIR)/$*_AVX512.d - %.o: %.c $(OBJDIR)/%.o : %.c $(OBJDIR)/%.d $(info [-] CC $<) + $(Q)$(MKDIR) $(dir $@) $(Q)$(CC) $(DEPFLAGS) $(PM3CFLAGS) -c -o $@ $< $(Q)$(POSTCOMPILE) %.o: %.cpp $(OBJDIR)/%.o : %.cpp $(OBJDIR)/%.d $(info [-] CXX $<) + $(Q)$(MKDIR) $(dir $@) $(Q)$(CXX) $(DEPFLAGS) $(PM3CXXFLAGS) $(QTINCLUDES) -c -o $@ $< $(Q)$(POSTCOMPILE) %.o: %.m $(OBJDIR)/%.o : %.m $(OBJDIR)/%.d $(info [-] CC $<) + $(Q)$(MKDIR) $(dir $@) $(Q)$(CC) $(DEPFLAGS) $(PM3CFLAGS) -c -o $@ $< $(Q)$(POSTCOMPILE) @@ -419,4 +435,3 @@ $(DEPENDENCY_FILES): ; .PRECIOUS: $(DEPENDENCY_FILES) -include $(DEPENDENCY_FILES) - diff --git a/client/obj/.dummy b/client/obj/.dummy deleted file mode 100644 index e69de29bb..000000000 diff --git a/client/obj/amiitool/.dummy b/client/obj/amiitool/.dummy deleted file mode 100644 index e69de29bb..000000000 diff --git a/client/obj/cliparser/.dummy b/client/obj/cliparser/.dummy deleted file mode 100644 index e69de29bb..000000000 diff --git a/client/obj/crapto1/.dummy b/client/obj/crapto1/.dummy deleted file mode 100644 index e69de29bb..000000000 diff --git a/client/obj/crypto/.dummy b/client/obj/crypto/.dummy deleted file mode 100644 index e69de29bb..000000000 diff --git a/client/obj/emv/.dummy b/client/obj/emv/.dummy deleted file mode 100644 index e69de29bb..000000000 diff --git a/client/obj/emv/test/.dummy b/client/obj/emv/test/.dummy deleted file mode 100644 index e69de29bb..000000000 diff --git a/client/obj/fido/.dummy b/client/obj/fido/.dummy deleted file mode 100644 index e69de29bb..000000000 diff --git a/client/obj/hardnested/.dummy b/client/obj/hardnested/.dummy deleted file mode 100644 index e69de29bb..000000000 diff --git a/client/obj/jansson/.dummy b/client/obj/jansson/.dummy deleted file mode 100644 index e69de29bb..000000000 diff --git a/client/obj/loclass/.dummy b/client/obj/loclass/.dummy deleted file mode 100644 index e69de29bb..000000000 diff --git a/client/obj/mifare/.dummy b/client/obj/mifare/.dummy deleted file mode 100644 index e69de29bb..000000000 diff --git a/client/obj/nonce2key/.dummy b/client/obj/nonce2key/.dummy deleted file mode 100644 index e69de29bb..000000000 diff --git a/client/obj/reveng/.gitignore b/client/obj/reveng/.gitignore deleted file mode 100644 index 07669e14a..000000000 --- a/client/obj/reveng/.gitignore +++ /dev/null @@ -1,35 +0,0 @@ -# .gitignore -# don't push these files to the repository - -*.log -*.eml -*.o -*.a -*.d -*.elf -*.s19 -*.map -*.bin -*.dll -*.moc.cpp -*.exe -proxmark -proxmark3 -flasher -version.c -lua -luac - -fpga/* -!fpga/tests -!fpga/fpga_lf.bit -!fpga/fpga_hf.bit -!fpga/*.v -!fpga/Makefile -!fpga/fpga.ucf -!fpga/xst_lf.scr -!fpga/xst_hf.scr -!fpga/go.bat -!fpga/sim.tcl - - diff --git a/client/platforms/.gitignore b/client/platforms/.gitignore deleted file mode 100644 index 07669e14a..000000000 --- a/client/platforms/.gitignore +++ /dev/null @@ -1,35 +0,0 @@ -# .gitignore -# don't push these files to the repository - -*.log -*.eml -*.o -*.a -*.d -*.elf -*.s19 -*.map -*.bin -*.dll -*.moc.cpp -*.exe -proxmark -proxmark3 -flasher -version.c -lua -luac - -fpga/* -!fpga/tests -!fpga/fpga_lf.bit -!fpga/fpga_hf.bit -!fpga/*.v -!fpga/Makefile -!fpga/fpga.ucf -!fpga/xst_lf.scr -!fpga/xst_hf.scr -!fpga/go.bat -!fpga/sim.tcl - - From 589f1e9d3e18c9c56558c92f3120b5a994057ff7 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 18 Aug 2019 00:10:04 +0200 Subject: [PATCH 0380/1854] client/Makefile: add missing deps --- client/Makefile | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/client/Makefile b/client/Makefile index a556a7451..9f8dacb3d 100644 --- a/client/Makefile +++ b/client/Makefile @@ -293,13 +293,13 @@ BINS = proxmark3 flasher CLEAN = $(BINS) *.moc.cpp ui/ui_overlays.h lualibs/pm3_cmd.lua lualibs/mf_default_keys.lua # need to assign dependancies to build these first... -all: lua_build jansson_build cbor_build reveng_build mbedtls_build zlib_build $(BINS) +all: $(BINS) all-static: LDLIBS:=-static $(LDLIBS) all-static: $(BINS) proxmark3: LDLIBS+=$(LUALIB) $(JANSSONLIB) $(MBEDTLSLIB) $(CBORLIB) $(ZLIB) $(REVENGLIB) $(QTLDLIBS) -proxmark3: $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) lualibs/pm3_cmd.lua lualibs/mf_default_keys.lua +proxmark3: $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(LUALIB) $(JANSSONLIB) $(CBORLIB) $(REVENGLIB) $(MBEDTLSLIB) $(ZLIB) lualibs/pm3_cmd.lua lualibs/mf_default_keys.lua $(info [=] LD $@) $(Q)$(LD) $(LDFLAGS) $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(LDLIBS) -o $@ @@ -338,28 +338,28 @@ tarbin: $(BINS) $(Q)$(TAR) $(TARFLAGS) ../proxmark3-$(platform)-bin.tar $(BINS:%=client/%) $(WINBINS:%=client/%) # local libraries: -lua_build: +$(LUALIB): $(info [*] MAKE liblua for $(LUAPLATFORM)) $(Q)$(MAKE) --no-print-directory -C $(LUALIBPATH) $(LUAPLATFORM) -jansson_build: +$(JANSSONLIB): $(info [*] MAKE jansson) $(Q)$(MAKE) --no-print-directory -C $(JANSSONLIBPATH) all -cbor_build: +$(CBORLIB): $(info [*] MAKE tinycbor) $(Q)$(MAKE) --no-print-directory -C $(CBORLIBPATH) all -reveng_build: +$(REVENGLIB): $(info [*] MAKE reveng) $(Q)$(MAKE) --no-print-directory -C $(REVENGPATH) all # common libraries: -mbedtls_build: +$(MBEDTLSLIB): $(info [*] MAKE mbedtls) $(Q)$(MAKE) --no-print-directory -C $(MBEDTLSLIBPATH) OBJDIR=$(ROOT_DIR)$(OBJDIR) BINDIR=$(ROOT_DIR)$(OBJDIR) all -zlib_build: +$(ZLIB): $(info [*] MAKE zlib) $(Q)$(MAKE) --no-print-directory -C $(ZLIBPATH) OBJDIR=$(ROOT_DIR)$(OBJDIR) BINDIR=$(ROOT_DIR)$(OBJDIR) all From d773f4ba2e529b743d0d4e3010a27039614bc3d6 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Tue, 20 Aug 2019 00:25:18 +0300 Subject: [PATCH 0381/1854] add matrix build with BTADDON --- .travis.yml | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 17b15fa55..7ccdce078 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,9 +15,18 @@ matrix: include: - os: osx osx_image: xcode11 + env: MAKE_PARAMS='PLATFORM_EXTRAS=' + - os: osx + osx_image: xcode11 + env: MAKE_PARAMS='PLATFORM_EXTRAS=BTADDON' - os: linux dist: xenial sudo: required + env: MAKE_PARAMS='PLATFORM_EXTRAS=' + - os: linux + dist: xenial + sudo: required + env: MAKE_PARAMS='PLATFORM_EXTRAS=BTADDON' addons: apt: @@ -37,19 +46,20 @@ addons: install: if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then + brew update; brew info proxmark3; brew options proxmark3; make clean; - make all V=1; + make all V=1 "$MAKE_PARAMS"; elif [[ "$TRAVIS_OS_NAME" == "linux" ]]; then make clean; - make all V=1; + make all V=1 "$MAKE_PARAMS"; fi script: ## start and run a test script if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then - ./pm3test.sh; + ./pm3test.sh; elif [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ./pm3test.sh; fi From dd8e12271bd4578c65c8dce5c13d24d57bf4d766 Mon Sep 17 00:00:00 2001 From: soffchen Date: Tue, 20 Aug 2019 12:12:34 +0800 Subject: [PATCH 0382/1854] Add Proxmark3 rdv3 Easy with AT91SAM7S512 platform --- common_arm/Makefile.hal | 5 +++++ doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md | 1 + 2 files changed, 6 insertions(+) diff --git a/common_arm/Makefile.hal b/common_arm/Makefile.hal index af80bc6ac..794acdc1a 100644 --- a/common_arm/Makefile.hal +++ b/common_arm/Makefile.hal @@ -23,6 +23,8 @@ Known definitions: +----------------------------------------------------------+ | PM3EASY | Proxmark3 rdv3 Easy with AT91SAM7S256 | +----------------------------------------------------------+ +| PM3EASY512 | Proxmark3 rdv3 Easy with AT91SAM7S512 | ++----------------------------------------------------------+ | PM3RDV2 | Proxmark3 rdv2 with AT91SAM7S512 | +----------------------------------------------------------+ | PM3OLD256 | Proxmark3 V1 with AT91SAM7S256 | @@ -73,6 +75,9 @@ else ifeq ($(PLATFORM),PM3EVO) else ifeq ($(PLATFORM),PM3EASY) MCU = AT91SAM7S256 PLTNAME = Proxmark3 rdv3 Easy +else ifeq ($(PLATFORM),PM3EASY512) + MCU = AT91SAM7S512 + PLTNAME = Proxmark3 rdv3 Easy 512 else ifeq ($(PLATFORM),PM3RDV2) MCU = AT91SAM7S512 PLTNAME = Proxmark3 rdv2 diff --git a/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md b/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md index aea5b5e30..c1ac92fc4 100644 --- a/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md +++ b/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md @@ -33,6 +33,7 @@ Here are the supported values you can assign to `PLATFORM` in `Makefile.platform | PM3RDV4 (def) | Proxmark3 rdv4 with AT91SAM7S512 | | PM3EVO | Proxmark3 EVO with AT91SAM7S512 | | PM3EASY | Proxmark3 rdv3 Easy with AT91SAM7S256 | +| PM3EASY512 | Proxmark3 rdv3 Easy with AT91SAM7S512 | | PM3RDV2 | Proxmark3 rdv2 with AT91SAM7S512 | | PM3OLD256 | Proxmark3 V1 with AT91SAM7S256 | | PM3OLD512 | Proxmark3 V1 with AT91SAM7S512 | From 88186be47fcc7dfee036a2822137b0116a93e566 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Tue, 20 Aug 2019 09:20:50 +0300 Subject: [PATCH 0383/1854] delete update. for new cores it not needs (slow down aprox 1-2min) --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 7ccdce078..501a85fcd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -46,7 +46,6 @@ addons: install: if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then - brew update; brew info proxmark3; brew options proxmark3; make clean; From fea5d882788eb26c84a5572021cfc63eb36342dd Mon Sep 17 00:00:00 2001 From: Iceman Date: Tue, 20 Aug 2019 14:53:52 +0200 Subject: [PATCH 0384/1854] add: detect unfused / write once magic tags, from https://github.com/nfc-tools/libnfc/pull/554 --- armsrc/mifarecmd.c | 7 +++++++ client/mifare/mifarehost.c | 3 +++ 2 files changed, 10 insertions(+) diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 5e9de52dd..985a787ca 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -1955,6 +1955,8 @@ void MifareCIdent() { #define GEN_1A 1 #define GEN_1B 2 #define GEN_2 4 +#define GEN_UNFUSED 5 + // variables uint8_t isGen = 0; uint8_t rec[1] = {0x00}; @@ -1990,6 +1992,11 @@ TEST2: int res = iso14443a_select_card(uid, NULL, &cuid, true, 0, true); if (res == 2) { + if (cuid == 0xAA55C396 ) { + isGen = GEN_UNFUSED; + goto OUT; + } + ReaderTransmit(rats, sizeof(rats), NULL); res = ReaderReceive(buf, par); if (memcmp(buf, "\x09\x78\x00\x91\x02\xDA\xBC\x19\x10\xF0\x05", 11) == 0) { diff --git a/client/mifare/mifarehost.c b/client/mifare/mifarehost.c index f7c7ce4f2..d22073d02 100644 --- a/client/mifare/mifarehost.c +++ b/client/mifare/mifarehost.c @@ -1041,6 +1041,9 @@ void detect_classic_magic(void) { case 4: PrintAndLogEx(SUCCESS, "Answers to magic commands (GEN 2 / CUID): " _GREEN_("YES")); break; + case 5: + PrintAndLogEx(SUCCESS, "Answers to magic commands (Write Once / FUID): " _GREEN_("YES")); + break; default: PrintAndLogEx(INFO, "Answers to magic commands: " _YELLOW_("NO")); break; From bd5a6094e7229f05c70392b43a252ca6436c4c93 Mon Sep 17 00:00:00 2001 From: Iceman Date: Tue, 20 Aug 2019 15:03:03 +0200 Subject: [PATCH 0385/1854] Create emv_notes.md converting @merlokk 's emv wiki to doc. --- doc/emv_notes.md | 141 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 doc/emv_notes.md diff --git a/doc/emv_notes.md b/doc/emv_notes.md new file mode 100644 index 000000000..a289d8ea5 --- /dev/null +++ b/doc/emv_notes.md @@ -0,0 +1,141 @@ +# EMV commands + + +### EMV Implemented parts: + +- Get ATR|ATS +- Get AID by PSE (`emv pse`) +- Get AID by appliation list (`emv search`) +- Select application (`emv select`) +- Format PDOL (look at next part) +- Execute GPO (`emv gpo` this step and format PDOL) +- Get records from AFL (`emv readrec`) +- Make SDA (check records from GPO) +- Make DDA (`emv challenge` `emv intauth`) +- Check PIN (`not implemented`) +- Fill CDOL1 and CDOL2 (look at next part) +- Execute AC1 (with CDA support) (`emv genac`) +- Check ARQC (bank part) (`not implemented`) +- Make ARPC (bank part) (`not implemented`) +- Execute external authenticate (`not implemented`) +- Execute AC2 (with CDA support) (`not implemented`) +- Check ARQC cryptogram (`not implemented`) +- Issuer scripts processing (`not implemented`) + +### Working parts of qVSDC: +^[Top](#top) + +- Get ATR|ATS +- Get AID by PSE (`emv pse`) +- Get AID by appliation list (`emv search`) +- Select application (`emv select`) +- Format PDOL (look at next part) +- Execute GPO (`emv gpo` this step and format PDOL) +- Get records from AFL (`emv readrec`) +- Make fDDA (`emv challenge` `emv intauth`) +- External authenticate command (`not implemented`) +- Issuer scripts processing (`not implemented`) + +### `not implemented` parts of EMV +^[Top](#top) + +They can be implemented, but it needs to know issuer's card keys (usually 3DES) and now this parts can be tested only on special test cards. + +### Commands +^[Top](#top) + +All this commands are parts of command `emv exec`. +command `emv exec` executes EMV transaction. it have parameters: +``` + -j, -J, --jload Load transaction parameters from `emv/defparams.json` file. + -f, -F, --forceaid Force search AID. Search AID instead of execute PPSE. + By default: Transaction type - MSD + -v, -V, --qvsdc Transaction type - qVSDC or M/Chip. + -c, -C, --qvsdccda Transaction type - qVSDC or M/Chip plus CDA (SDAD generation). + -x, -X, --vsdc Transaction type - VSDC. + -g, -G, --acgpo VISA. generate AC from GPO. + -w, -W, --wired Send data via contact (iso7816) interface. Contactless interface set by default. +``` +It works for VISA(r) and Mastercard(r) transactions. It may work with other EMV payment system's card (and it works in general cases that is described in EMV). + +### VISA(r) transactions: +^[Top](#top) + +MSD - Magnetic Stripe mode +VSDC - contact transacion +qVSDC - contactless transaction + +### Mastercard(r) transactions +^[Top](#top) + +MSD - Magnetic Stripe mode +M/Chip - contact and contactless transaction + +Different cards have different modes on/of and different behavior in them. So needs to check card in all this modes. +MSD - compatibility mode. Now it work always. But it less secure and in near future it will be slowly) disabled. + +### all commands: +^[Top](#top) + +``` +exec Executes EMV contactless transaction. +pse Execute PPSE. It selects 2PAY.SYS.DDF01 or 1PAY.SYS.DDF01 directory. +search Try to select all applets from applets list and print installed applets. +select Select applet. +gpo Execute GetProcessingOptions. +readrec Read files from card. +genac Generate ApplicationCryptogram. +challenge Generate challenge. +intauth Internal authentication. +scan Scan EMV card and save it contents to json file for emulator. +test Crypto logic test. +list List ISO7816 history +roca Extract public keys and run ROCA test +``` + +All main commands are parts of EMV specification. Commands than not described there: + +`emv scan` - scans card and saves all records to json file. Can be executed with or without tags disassembly. + +`emv roca` - extract public keys from cards (part of `emv scan`) + +`emv test` - test all crypto code from emv part of proxmark. + +### Useful links: +^[Top](#top) + +EMV specifications +http://www.emvco.com/specifications.aspx?id=155 + +Excelent explanation of EMV +http://www.openscdp.org/scripts/emv/index.html + +Fully working terminal written in Ruby. +https://code.google.com/p/ruby-pboc2-lib/source/browse/trunk/lib/pboc.rb + +EMV kernel written in C++ +https://github.com/ntufar/EMV/tree/master/EMV_Library + +C EMV library (part of this library uses proxmark) +https://github.com/lumag/emv-tools + +Resources (keys, country codes, etc): +https://github.com/binaryfoo/emv-bertlv/tree/master/src/main/resources + +### EMV kernels +^[Top](#top) + +POS terminal checks card and selects one of EMV kernels and launches it for EMV transaction. Different kernels have different rules to make EMV transaction. + +This list from: + +EMVco Architecture and General Requirement V2.4 volume A. +EMVco Entry Point specification V2.4 volume B + +- EMVco C-1 Kernel 1 V2.4 for some cards with JCB AIDs and some cards with Visa AIDs +- EMVco C-2 Kernel 2 V2.4 for MasterCards AIDs +- EMVco C-3 Kernel 3 V2.4 for Visa AIDs +- EMVco C-4 Kernel 4 V2.4 for American Express AIDs +- EMVco C-5 Kernel 5 V2.4 for JCB AIDs +- EMVco C-6 Kernel 6 V2.4 for Discover AIDs +- EMVco C-7 Kernel 7 V2.4 for UnionPay AIDs From 1ac5211601b50b82b41737dce0c3a72d9e0374ac Mon Sep 17 00:00:00 2001 From: Iceman Date: Tue, 20 Aug 2019 15:46:08 +0200 Subject: [PATCH 0386/1854] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0968b1f06..68ef01492 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ _Note that it also supports other Proxmark3 platforms as well!_ |[PM3 GUI](#pm3-gui)|[Setup and build for Windows](/doc/md/Installation_Instructions/Windows-Installation-Instructions.md)|[Commands & Features](/doc/md/Use_of_Proxmark/3_Commands-and-Features.md)| |[Issues](#issues)|[Blue shark manual](/doc/bt_manual_v10.md) |[Advanced compilation parameters](/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md)| |[Notes on UART](/doc/uart_notes.md)||[Command Cheat sheet](/doc/cheatsheet.md)| -|[Notes on Frame format](/doc/new_frame_format.md)||| +|[Notes on Frame format](/doc/new_frame_format.md)||[More cheat sheets](https://github.com/RfidResearchGroup/proxmark3/wiki/More-cheat-sheets)| |[Notes on external flash](/doc/ext_flash_notes.md)||| |[Notes on Termux / Android](/doc/termux_notes.md)||| |[Notes on Wireshark / tracedata](/doc/trace_wireshark_notes.md)||| From 08841481cd0efb9e35b9b920d0b3c1d7819943b9 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Tue, 20 Aug 2019 19:38:47 +0300 Subject: [PATCH 0387/1854] get rid of some commands --- .travis.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 501a85fcd..8952df259 100644 --- a/.travis.yml +++ b/.travis.yml @@ -46,8 +46,6 @@ addons: install: if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then - brew info proxmark3; - brew options proxmark3; make clean; make all V=1 "$MAKE_PARAMS"; elif [[ "$TRAVIS_OS_NAME" == "linux" ]]; then From 9535ce459e7d2f3d1e913f9d5c30d305d1f68277 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 20 Aug 2019 19:39:24 +0200 Subject: [PATCH 0388/1854] PLATFORM defs --- common_arm/Makefile.hal | 5 +++++ doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md | 3 +++ 2 files changed, 8 insertions(+) diff --git a/common_arm/Makefile.hal b/common_arm/Makefile.hal index 794acdc1a..411744037 100644 --- a/common_arm/Makefile.hal +++ b/common_arm/Makefile.hal @@ -21,6 +21,8 @@ Known definitions: +----------------------------------------------------------+ | PM3EVO | Proxmark3 EVO with AT91SAM7S512 | +----------------------------------------------------------+ +| PM3V40 | Proxmark3 V4.0 with AT91SAM7S512 | ++----------------------------------------------------------+ | PM3EASY | Proxmark3 rdv3 Easy with AT91SAM7S256 | +----------------------------------------------------------+ | PM3EASY512 | Proxmark3 rdv3 Easy with AT91SAM7S512 | @@ -72,6 +74,9 @@ ifeq ($(PLATFORM),PM3RDV4) else ifeq ($(PLATFORM),PM3EVO) MCU = AT91SAM7S512 PLTNAME = Proxmark3 EVO +else ifeq ($(PLATFORM),PM3V40) + MCU = AT91SAM7S512 + PLTNAME = Proxmark3 V4.0 else ifeq ($(PLATFORM),PM3EASY) MCU = AT91SAM7S256 PLTNAME = Proxmark3 rdv3 Easy diff --git a/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md b/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md index c1ac92fc4..270682696 100644 --- a/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md +++ b/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md @@ -32,6 +32,7 @@ Here are the supported values you can assign to `PLATFORM` in `Makefile.platform |-----------------|----------------------------------------| | PM3RDV4 (def) | Proxmark3 rdv4 with AT91SAM7S512 | | PM3EVO | Proxmark3 EVO with AT91SAM7S512 | +| PM3V40 | Proxmark3 V4.0 with AT91SAM7S512 | | PM3EASY | Proxmark3 rdv3 Easy with AT91SAM7S256 | | PM3EASY512 | Proxmark3 rdv3 Easy with AT91SAM7S512 | | PM3RDV2 | Proxmark3 rdv2 with AT91SAM7S512 | @@ -40,6 +41,8 @@ Here are the supported values you can assign to `PLATFORM` in `Makefile.platform By default `PLATFORM=PM3RDV4`. +Note that besides `PM3RDV4` and its unique features, all other platforms are equivalent and the MCU version (256 or 512) will be detected automatically during flashing. + Known issues: * 256kb Arm chip devices: The compiled firmware image from this repo may/will be too large for your device. From fdcc885aa945e05edd9dde071c8b2c74201a37e4 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 20 Aug 2019 23:21:18 +0200 Subject: [PATCH 0389/1854] Use /dev/tty on OSX rather than /dev/cu See https://stackoverflow.com/questions/8632586/macos-whats-the-difference-between-dev-tty-and-dev-cu/8632603 --- include/usart_defs.h | 2 +- proxmark3.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/usart_defs.h b/include/usart_defs.h index 232e80276..cf6630e83 100644 --- a/include/usart_defs.h +++ b/include/usart_defs.h @@ -18,7 +18,7 @@ #if defined (_WIN32) #define SERIAL_PORT_EXAMPLE_H "com3" #elif defined(__APPLE__) -#define SERIAL_PORT_EXAMPLE_H "/dev/cu.usbmodem" +#define SERIAL_PORT_EXAMPLE_H "/dev/tty.usbmodemiceman1" #else #define SERIAL_PORT_EXAMPLE_H "/dev/ttyACM0" #endif diff --git a/proxmark3.sh b/proxmark3.sh index be3cfd690..89e7e960b 100755 --- a/proxmark3.sh +++ b/proxmark3.sh @@ -21,7 +21,7 @@ function wait4proxmark_Linux { function wait4proxmark_macOS { echo >&2 "[=] Waiting for Proxmark3 to appear..." while true; do - PM3=$(find /dev/pm3-* /dev/cu.usbmodem* 2>/dev/null | head -1) + PM3=$(find /dev/pm3-* /dev/tty.usbmodem* 2>/dev/null | head -1) if [[ $PM3 != "" ]]; then break fi From 4e627f09c017ea3ac22c66933eec3de5a7eb94ea Mon Sep 17 00:00:00 2001 From: Iceman Date: Wed, 21 Aug 2019 12:52:59 +0200 Subject: [PATCH 0390/1854] add: proxmark3 -v/--version - for easiness to detect version in offline mode and installs --- client/cmdhw.c | 19 +++++++++++++++++-- client/cmdhw.h | 2 +- client/proxmark3.c | 11 +++++++++-- 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/client/cmdhw.c b/client/cmdhw.c index 7fec7a40c..b6cb2bd87 100644 --- a/client/cmdhw.c +++ b/client/cmdhw.c @@ -493,7 +493,7 @@ static int CmdTune(const char *Cmd) { static int CmdVersion(const char *Cmd) { (void)Cmd; // Cmd is not used so far - pm3_version(true); + pm3_version(true, false); return PM3_SUCCESS; } @@ -617,7 +617,21 @@ int CmdHW(const char *Cmd) { return CmdsParse(CommandTable, Cmd); } -void pm3_version(bool verbose) { +void pm3_version(bool verbose, bool oneliner) { + + if (oneliner) { + char msg[70]; + memset(msg, 0x00, sizeof(msg)); + strcat(msg, "Client: RRG/Iceman compiled with "); +#if defined(__clang__) + strcat(msg + strlen(msg), _YELLOW_("Clang/LLVM "__VERSION__)); +#elif defined(__GNUC__) || defined(__GNUG__) + strcat(msg + strlen(msg), _YELLOW_("GCC "__VERSION__)); +#endif + PrintAndLogEx(NORMAL, "%s", msg); + return; + } + if (!verbose) return; @@ -635,6 +649,7 @@ void pm3_version(bool verbose) { #elif defined(__GNUC__) || defined(__GNUG__) PrintAndLogEx(NORMAL, " compiled with GCC "__VERSION__); #endif + PrintAndLogEx(NORMAL, "\n [ PROXMARK RDV4 ]"); PrintAndLogEx(NORMAL, " external flash: %s", IfPm3Flash() ? _GREEN_("present") : _YELLOW_("absent")); PrintAndLogEx(NORMAL, " smartcard reader: %s", IfPm3Smartcard() ? _GREEN_("present") : _YELLOW_("absent")); diff --git a/client/cmdhw.h b/client/cmdhw.h index 1a378e70f..bf40b70a8 100644 --- a/client/cmdhw.h +++ b/client/cmdhw.h @@ -15,6 +15,6 @@ int CmdHW(const char *Cmd); -void pm3_version(bool verbose); +void pm3_version(bool verbose, bool oneliner); #endif diff --git a/client/proxmark3.c b/client/proxmark3.c index de6fe43af..6555ac0f2 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -88,9 +88,9 @@ main_loop(char *script_cmds_file, char *script_cmd, bool stayInCommandLoop) { if (session.pm3_present) { // cache Version information now: if (execCommand || script_cmds_file || stdinOnPipe) - pm3_version(false); + pm3_version(false, false); else - pm3_version(true); + pm3_version(true, false); } if (script_cmds_file) { @@ -284,6 +284,7 @@ static void show_help(bool showFullHelp, char *exec_name) { PrintAndLogEx(NORMAL, " -l/--lua execute lua script."); PrintAndLogEx(NORMAL, " -s/--script-file script file with one Proxmark3 command per line"); PrintAndLogEx(NORMAL, " -i/--interactive enter interactive mode after executing the script or the command"); + PrintAndLogEx(NORMAL, " -v/--version print client version"); PrintAndLogEx(NORMAL, "\nsamples:"); PrintAndLogEx(NORMAL, " %s -h\n", exec_name); PrintAndLogEx(NORMAL, " %s -m\n", exec_name); @@ -378,6 +379,12 @@ int main(int argc, char *argv[]) { dumpAllHelp(1); return 0; } + // pritn client version + if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--version") == 0) { + pm3_version(true, true); + return 0; + } + // flush output if (strcmp(argv[i], "-f") == 0 || strcmp(argv[i], "--flush") == 0) { From a0f261c1e049b352be9f84dfb1a614477dab50fb Mon Sep 17 00:00:00 2001 From: Iceman Date: Wed, 21 Aug 2019 14:41:33 +0200 Subject: [PATCH 0391/1854] chg: moved fileutils from loclass --- client/Makefile | 2 +- client/cmdflashmem.c | 2 +- client/cmdflashmemspiffs.c | 2 +- client/cmdhf14b.c | 2 +- client/cmdhf15.c | 2 +- client/cmdhficlass.c | 2 +- client/cmdhflegic.c | 2 +- client/cmdhfmf.c | 2 +- client/cmdhfmfu.c | 2 +- client/cmdlfhitag.c | 2 +- client/cmdlft55xx.c | 2 +- client/cmdtrace.c | 2 +- client/loclass/fileutils.c | 618 ------------------------------------- client/loclass/fileutils.h | 181 ----------- 14 files changed, 12 insertions(+), 811 deletions(-) delete mode 100644 client/loclass/fileutils.c delete mode 100644 client/loclass/fileutils.h diff --git a/client/Makefile b/client/Makefile index 9f8dacb3d..9711d29ed 100644 --- a/client/Makefile +++ b/client/Makefile @@ -157,7 +157,7 @@ CMDSRCS = crapto1/crapto1.c \ loclass/cipherutils.c \ loclass/ikeys.c \ loclass/elite_crack.c \ - loclass/fileutils.c \ + fileutils.c \ whereami.c \ mifare/mifarehost.c \ parity.c \ diff --git a/client/cmdflashmem.c b/client/cmdflashmem.c index 6bb6fbc3c..a89d2eae6 100644 --- a/client/cmdflashmem.c +++ b/client/cmdflashmem.c @@ -14,7 +14,7 @@ #include "cmdparser.h" // command_t #include "pmflash.h" -#include "loclass/fileutils.h" //saveFile +#include "fileutils.h" //saveFile #include "comms.h" //getfromdevice #include "cmdflashmemspiffs.h" // spiffs commands diff --git a/client/cmdflashmemspiffs.c b/client/cmdflashmemspiffs.c index f53e17915..5783e2705 100644 --- a/client/cmdflashmemspiffs.c +++ b/client/cmdflashmemspiffs.c @@ -13,7 +13,7 @@ #include "cmdparser.h" // command_t #include "pmflash.h" -#include "loclass/fileutils.h" //saveFile +#include "fileutils.h" //saveFile #include "comms.h" //getfromdevice static int CmdHelp(const char *Cmd); diff --git a/client/cmdhf14b.c b/client/cmdhf14b.c index c5a628835..57f275a31 100644 --- a/client/cmdhf14b.c +++ b/client/cmdhf14b.c @@ -12,7 +12,7 @@ #include "cmdhf14b.h" #include -#include "loclass/fileutils.h" +#include "fileutils.h" #include "cmdparser.h" // command_t #include "comms.h" // clearCommandBuffer diff --git a/client/cmdhf15.c b/client/cmdhf15.c index 2c788087e..eb8cb6f87 100644 --- a/client/cmdhf15.c +++ b/client/cmdhf15.c @@ -35,7 +35,7 @@ #include "graph.h" #include "crc16.h" // iso15 crc #include "cmddata.h" // getsamples -#include "loclass/fileutils.h" // savefileEML +#include "fileutils.h" // savefileEML #define FrameSOF Iso15693FrameSOF #define Logic0 Iso15693Logic0 diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 7badc7c86..3cbbd1a67 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -26,7 +26,7 @@ #include "loclass/cipher.h" #include "loclass/ikeys.h" #include "loclass/elite_crack.h" -#include "loclass/fileutils.h" +#include "fileutils.h" #include "protocols.h" diff --git a/client/cmdhflegic.c b/client/cmdhflegic.c index af56807b1..fe1f53785 100644 --- a/client/cmdhflegic.c +++ b/client/cmdhflegic.c @@ -17,7 +17,7 @@ #include "cmdtrace.h" #include "crc.h" #include "crc16.h" -#include "loclass/fileutils.h" //saveFile +#include "fileutils.h" //saveFile static int CmdHelp(const char *Cmd); diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index affc53603..aaaeafb99 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -15,7 +15,7 @@ #include "cmdparser.h" // command_t #include "commonutil.h" // ARRAYLEN #include "comms.h" // clearCommandBuffer -#include "loclass/fileutils.h" +#include "fileutils.h" #include "cmdtrace.h" #include "emv/dump.h" #include "mifare/mifaredefault.h" // mifare default key array diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index e2c64a004..23eac5504 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -18,7 +18,7 @@ #include "cmdhfmf.h" #include "cmdhf14a.h" #include "comms.h" -#include "loclass/fileutils.h" +#include "fileutils.h" #include "protocols.h" #define MAX_UL_BLOCKS 0x0F diff --git a/client/cmdlfhitag.c b/client/cmdlfhitag.c index 190b84283..2bcd476ea 100644 --- a/client/cmdlfhitag.c +++ b/client/cmdlfhitag.c @@ -15,7 +15,7 @@ #include "cmdtrace.h" #include "commonutil.h" #include "hitag.h" -#include "loclass/fileutils.h" // savefile +#include "fileutils.h" // savefile static int CmdHelp(const char *Cmd); diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index d5f66496d..3c88a23ea 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -25,7 +25,7 @@ #include "cmddata.h" #include "lfdemod.h" #include "cmdhf14a.h" // for getTagInfo -#include "loclass/fileutils.h" // loadDictionary +#include "fileutils.h" // loadDictionary #include "util_posix.h" diff --git a/client/cmdtrace.c b/client/cmdtrace.c index 15416a8a6..ecb3fc158 100644 --- a/client/cmdtrace.c +++ b/client/cmdtrace.c @@ -16,7 +16,7 @@ #include "parity.h" // oddparity #include "cmdhflist.h" // annotations #include "comms.h" // for sending cmds to device. GetFromBigBuf -#include "loclass/fileutils.h" // for saveFile +#include "fileutils.h" // for saveFile static int CmdHelp(const char *Cmd); diff --git a/client/loclass/fileutils.c b/client/loclass/fileutils.c deleted file mode 100644 index b89925334..000000000 --- a/client/loclass/fileutils.c +++ /dev/null @@ -1,618 +0,0 @@ -/***************************************************************************** - * WARNING - * - * THIS CODE IS CREATED FOR EXPERIMENTATION AND EDUCATIONAL USE ONLY. - * - * USAGE OF THIS CODE IN OTHER WAYS MAY INFRINGE UPON THE INTELLECTUAL - * PROPERTY OF OTHER PARTIES, SUCH AS INSIDE SECURE AND HID GLOBAL, - * AND MAY EXPOSE YOU TO AN INFRINGEMENT ACTION FROM THOSE PARTIES. - * - * THIS CODE SHOULD NEVER BE USED TO INFRINGE PATENTS OR INTELLECTUAL PROPERTY RIGHTS. - * - ***************************************************************************** - * - * This file is part of loclass. It is a reconstructon of the cipher engine - * used in iClass, and RFID techology. - * - * The implementation is based on the work performed by - * Flavio D. Garcia, Gerhard de Koning Gans, Roel Verdult and - * Milosch Meriac in the paper "Dismantling IClass". - * - * Copyright (C) 2014 Martin Holst Swende - * - * This is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation, or, at your option, any later version. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with loclass. If not, see . - * - * - ****************************************************************************/ -#include "fileutils.h" - -#include - -#include "pm3_cmd.h" -#include "commonutil.h" -#include "util.h" - - -#ifndef ON_DEVICE - -#define PATH_MAX_LENGTH 100 - -/** - * @brief checks if a file exists - * @param filename - * @return - */ -int fileExists(const char *filename) { - -#ifdef _WIN32 - struct _stat st; - int result = _stat(filename, &st); -#else - struct stat st; - int result = stat(filename, &st); -#endif - return result == 0; -} - -static char *filenamemcopy(const char *preferredName, const char *suffix) { - if (preferredName == NULL) return NULL; - if (suffix == NULL) return NULL; - char *fileName = (char *) calloc(strlen(preferredName) + strlen(suffix) + 1, sizeof(uint8_t)); - if (fileName == NULL) - return NULL; - strcpy(fileName, preferredName); - if (str_endswith(fileName, suffix)) - return fileName; - strcat(fileName, suffix); - return fileName; -} - -static char *newfilenamemcopy(const char *preferredName, const char *suffix) { - if (preferredName == NULL) return NULL; - if (suffix == NULL) return NULL; - uint16_t preferredNameLen = strlen(preferredName); - if (str_endswith(preferredName, suffix)) - preferredNameLen -= strlen(suffix); - char *fileName = (char *) calloc(preferredNameLen + strlen(suffix) + 1 + 10, sizeof(uint8_t)); // 10: room for filenum to ensure new filename - if (fileName == NULL) { - return NULL; - } - int num = 1; - sprintf(fileName, "%.*s%s", preferredNameLen, preferredName, suffix); - while (fileExists(fileName)) { - sprintf(fileName, "%.*s-%d%s", preferredNameLen, preferredName, num, suffix); - num++; - } - return fileName; -} - -int saveFile(const char *preferredName, const char *suffix, const void *data, size_t datalen) { - - if (data == NULL) return 1; - char *fileName = newfilenamemcopy(preferredName, suffix); - if (fileName == NULL) return 1; - - /* We should have a valid filename now, e.g. dumpdata-3.bin */ - - /*Opening file for writing in binary mode*/ - FILE *f = fopen(fileName, "wb"); - if (!f) { - PrintAndLogEx(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", fileName); - free(fileName); - return PM3_EFILE; - } - fwrite(data, 1, datalen, f); - fflush(f); - fclose(f); - PrintAndLogEx(SUCCESS, "saved %u bytes to binary file " _YELLOW_("%s"), datalen, fileName); - free(fileName); - return PM3_SUCCESS; -} - -int saveFileEML(const char *preferredName, uint8_t *data, size_t datalen, size_t blocksize) { - - if (data == NULL) return 1; - char *fileName = newfilenamemcopy(preferredName, ".eml"); - if (fileName == NULL) return 1; - - int retval = PM3_SUCCESS; - int blocks = datalen / blocksize; - uint16_t currblock = 1; - - /* We should have a valid filename now, e.g. dumpdata-3.bin */ - - /*Opening file for writing in text mode*/ - FILE *f = fopen(fileName, "w+"); - if (!f) { - PrintAndLogEx(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", fileName); - retval = PM3_EFILE; - goto out; - } - - for (size_t i = 0; i < datalen; i++) { - fprintf(f, "%02X", data[i]); - - // no extra line in the end - if ((i + 1) % blocksize == 0 && currblock != blocks) { - fprintf(f, "\n"); - currblock++; - } - } - // left overs - if (datalen % blocksize != 0) { - int index = blocks * blocksize; - for (size_t j = 0; j < datalen % blocksize; j++) { - fprintf(f, "%02X", data[index + j]); - } - } - fflush(f); - fclose(f); - PrintAndLogEx(SUCCESS, "saved %d blocks to text file " _YELLOW_("%s"), blocks, fileName); - -out: - free(fileName); - return retval; -} - -int saveFileJSON(const char *preferredName, JSONFileType ftype, uint8_t *data, size_t datalen) { - - if (data == NULL) return 1; - char *fileName = newfilenamemcopy(preferredName, ".json"); - if (fileName == NULL) return 1; - - int retval = PM3_SUCCESS; - - json_t *root = json_object(); - JsonSaveStr(root, "Created", "proxmark3"); - switch (ftype) { - case jsfRaw: { - JsonSaveStr(root, "FileType", "raw"); - JsonSaveBufAsHexCompact(root, "raw", data, datalen); - break; - } - case jsfCardMemory: { - JsonSaveStr(root, "FileType", "mfcard"); - for (size_t i = 0; i < (datalen / 16); i++) { - char path[PATH_MAX_LENGTH] = {0}; - sprintf(path, "$.blocks.%zu", i); - JsonSaveBufAsHexCompact(root, path, &data[i * 16], 16); - - if (i == 0) { - JsonSaveBufAsHexCompact(root, "$.Card.UID", &data[0], 4); - JsonSaveBufAsHexCompact(root, "$.Card.SAK", &data[5], 1); - JsonSaveBufAsHexCompact(root, "$.Card.ATQA", &data[6], 2); - } - - if (mfIsSectorTrailer(i)) { - memset(path, 0x00, sizeof(path)); - sprintf(path, "$.SectorKeys.%d.KeyA", mfSectorNum(i)); - JsonSaveBufAsHexCompact(root, path, &data[i * 16], 6); - - memset(path, 0x00, sizeof(path)); - sprintf(path, "$.SectorKeys.%d.KeyB", mfSectorNum(i)); - JsonSaveBufAsHexCompact(root, path, &data[i * 16 + 10], 6); - - memset(path, 0x00, sizeof(path)); - uint8_t *adata = &data[i * 16 + 6]; - sprintf(path, "$.SectorKeys.%d.AccessConditions", mfSectorNum(i)); - JsonSaveBufAsHexCompact(root, path, &data[i * 16 + 6], 4); - - memset(path, 0x00, sizeof(path)); - sprintf(path, "$.SectorKeys.%d.AccessConditionsText.block%zu", mfSectorNum(i), i - 3); - JsonSaveStr(root, path, mfGetAccessConditionsDesc(0, adata)); - - memset(path, 0x00, sizeof(path)); - sprintf(path, "$.SectorKeys.%d.AccessConditionsText.block%zu", mfSectorNum(i), i - 2); - JsonSaveStr(root, path, mfGetAccessConditionsDesc(1, adata)); - - memset(path, 0x00, sizeof(path)); - sprintf(path, "$.SectorKeys.%d.AccessConditionsText.block%zu", mfSectorNum(i), i - 1); - JsonSaveStr(root, path, mfGetAccessConditionsDesc(2, adata)); - - memset(path, 0x00, sizeof(path)); - sprintf(path, "$.SectorKeys.%d.AccessConditionsText.block%zu", mfSectorNum(i), i); - JsonSaveStr(root, path, mfGetAccessConditionsDesc(3, adata)); - - memset(path, 0x00, sizeof(path)); - sprintf(path, "$.SectorKeys.%d.AccessConditionsText.UserData", mfSectorNum(i)); - JsonSaveBufAsHexCompact(root, path, &adata[3], 1); - } - } - break; - } - case jsfMfuMemory: { - JsonSaveStr(root, "FileType", "mfu"); - - mfu_dump_t *tmp = (mfu_dump_t *)data; - - uint8_t uid[7] = {0}; - memcpy(uid, tmp->data, 3); - memcpy(uid + 3, tmp->data + 4, 4); - - char path[PATH_MAX_LENGTH] = {0}; - - JsonSaveBufAsHexCompact(root, "$.Card.UID", uid, sizeof(uid)); - JsonSaveBufAsHexCompact(root, "$.Card.Version", tmp->version, sizeof(tmp->version)); - JsonSaveBufAsHexCompact(root, "$.Card.TBO_0", tmp->tbo, sizeof(tmp->tbo)); - JsonSaveBufAsHexCompact(root, "$.Card.TBO_1", tmp->tbo1, sizeof(tmp->tbo1)); - JsonSaveBufAsHexCompact(root, "$.Card.Signature", tmp->signature, sizeof(tmp->signature)); - for (uint8_t i = 0; i < 3; i ++) { - sprintf(path, "$.Card.Counter%d", i); - JsonSaveBufAsHexCompact(root, path, tmp->counter_tearing[i], 3); - sprintf(path, "$.Card.Tearing%d", i); - JsonSaveBufAsHexCompact(root, path, tmp->counter_tearing[i] + 3, 1); - } - - // size of header 56b - size_t len = (datalen - MFU_DUMP_PREFIX_LENGTH) / 4; - - for (size_t i = 0; i < len; i++) { - sprintf(path, "$.blocks.%zu", i); - JsonSaveBufAsHexCompact(root, path, tmp->data + (i * 4), 4); - } - break; - } - case jsfHitag: { - JsonSaveStr(root, "FileType", "hitag"); - uint8_t uid[4] = {0}; - memcpy(uid, data, 4); - - JsonSaveBufAsHexCompact(root, "$.Card.UID", uid, sizeof(uid)); - - for (size_t i = 0; i < (datalen / 4); i++) { - char path[PATH_MAX_LENGTH] = {0}; - sprintf(path, "$.blocks.%zu", i); - JsonSaveBufAsHexCompact(root, path, data + (i * 4), 4); - } - break; - } - } - - int res = json_dump_file(root, fileName, JSON_INDENT(2)); - if (res) { - PrintAndLogEx(FAILED, "error: can't save the file: " _YELLOW_("%s"), fileName); - json_decref(root); - retval = 200; - goto out; - } - PrintAndLogEx(SUCCESS, "saved to json file " _YELLOW_("%s"), fileName); - json_decref(root); - -out: - free(fileName); - return retval; -} - -int loadFile(const char *preferredName, const char *suffix, void *data, size_t maxdatalen, size_t *datalen) { - - if (data == NULL) return 1; - char *fileName = filenamemcopy(preferredName, suffix); - if (fileName == NULL) return 1; - - int retval = PM3_SUCCESS; - - FILE *f = fopen(fileName, "rb"); - if (!f) { - PrintAndLogEx(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", fileName); - free(fileName); - return PM3_EFILE; - } - - // get filesize in order to malloc memory - fseek(f, 0, SEEK_END); - long fsize = ftell(f); - fseek(f, 0, SEEK_SET); - - if (fsize <= 0) { - PrintAndLogEx(FAILED, "error, when getting filesize"); - retval = 1; - goto out; - } - - uint8_t *dump = calloc(fsize, sizeof(uint8_t)); - if (!dump) { - PrintAndLogEx(FAILED, "error, cannot allocate memory"); - retval = 2; - goto out; - } - - size_t bytes_read = fread(dump, 1, fsize, f); - - if (bytes_read != fsize) { - PrintAndLogEx(FAILED, "error, bytes read mismatch file size"); - free(dump); - retval = 3; - goto out; - } - - if (bytes_read > maxdatalen) { - PrintAndLogEx(WARNING, "Warning, bytes read exceed calling array limit. Max bytes is %d bytes", maxdatalen); - bytes_read = maxdatalen; - } - - memcpy((data), dump, bytes_read); - free(dump); - - PrintAndLogEx(SUCCESS, "loaded %d bytes from binary file " _YELLOW_("%s"), bytes_read, fileName); - - *datalen = bytes_read; - -out: - fclose(f); - free(fileName); - - return retval; -} - -int loadFileEML(const char *preferredName, void *data, size_t *datalen) { - - if (data == NULL) return 1; - char *fileName = filenamemcopy(preferredName, ".eml"); - if (fileName == NULL) return 1; - - size_t counter = 0; - int retval = PM3_SUCCESS, hexlen = 0; - - FILE *f = fopen(fileName, "r"); - if (!f) { - PrintAndLogEx(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", fileName); - retval = PM3_EFILE; - goto out; - } - - // 128 + 2 newline chars + 1 null terminator - char line[131]; - memset(line, 0, sizeof(line)); - uint8_t buf[64] = {0x00}; - - while (!feof(f)) { - - memset(line, 0, sizeof(line)); - - if (fgets(line, sizeof(line), f) == NULL) { - if (feof(f)) - break; - fclose(f); - PrintAndLogEx(FAILED, "File reading error."); - retval = 2; - goto out; - } - - if (line[0] == '#') - continue; - - int res = param_gethex_to_eol(line, 0, buf, sizeof(buf), &hexlen); - if (res == 0 || res == 1) { - memcpy(data + counter, buf, hexlen); - counter += hexlen; - } - } - fclose(f); - PrintAndLogEx(SUCCESS, "loaded %d bytes from text file " _YELLOW_("%s"), counter, fileName); - - if (datalen) - *datalen = counter; - -out: - free(fileName); - return retval; -} - -int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_t *datalen) { - - if (data == NULL) return 1; - char *fileName = filenamemcopy(preferredName, ".json"); - if (fileName == NULL) return 1; - - *datalen = 0; - json_t *root; - json_error_t error; - - int retval = PM3_SUCCESS; - - root = json_load_file(fileName, 0, &error); - if (!root) { - PrintAndLogEx(ERR, "ERROR: json " _YELLOW_("%s") " error on line %d: %s", fileName, error.line, error.text); - retval = 2; - goto out; - } - - if (!json_is_object(root)) { - PrintAndLogEx(ERR, "ERROR: Invalid json " _YELLOW_("%s") " format. root must be an object.", fileName); - retval = 3; - goto out; - } - - uint8_t *udata = (uint8_t *)data; - char ctype[100] = {0}; - JsonLoadStr(root, "$.FileType", ctype); - - if (!strcmp(ctype, "raw")) { - JsonLoadBufAsHex(root, "$.raw", udata, maxdatalen, datalen); - } - - if (!strcmp(ctype, "mfcard")) { - size_t sptr = 0; - for (int i = 0; i < 256; i++) { - if (sptr + 16 > maxdatalen) { - retval = 5; - goto out; - } - - char path[30] = {0}; - sprintf(path, "$.blocks.%d", i); - - size_t len = 0; - JsonLoadBufAsHex(root, path, &udata[sptr], 16, &len); - if (!len) - break; - - sptr += len; - } - - *datalen = sptr; - } - - if (!strcmp(ctype, "mfu")) { - size_t sptr = 0; - for (int i = 0; i < 256; i++) { - if (sptr + 4 > maxdatalen) { - retval = 5; - goto out; - } - - char path[30] = {0}; - sprintf(path, "$.blocks.%d", i); - - size_t len = 0; - JsonLoadBufAsHex(root, path, &udata[sptr], 4, &len); - if (!len) - break; - - sptr += len; - } - - *datalen = sptr; - } - - if (!strcmp(ctype, "hitag")) { - size_t sptr = 0; - for (size_t i = 0; i < (maxdatalen / 4); i++) { - if (sptr + 4 > maxdatalen) { - retval = 5; - goto out; - } - - char path[30] = {0}; - sprintf(path, "$.blocks.%zu", i); - - size_t len = 0; - JsonLoadBufAsHex(root, path, &udata[sptr], 4, &len); - if (!len) - break; - - sptr += len; - } - - *datalen = sptr; - } - - PrintAndLogEx(SUCCESS, "loaded from JSON file " _YELLOW_("%s"), fileName); -out: - json_decref(root); - free(fileName); - return retval; -} - -int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, uint8_t keylen, uint16_t *keycnt) { - - - if (data == NULL) return 1; - char *fileName = filenamemcopy(preferredName, ".dic"); - if (fileName == NULL) return 1; - - // t5577 == 4bytes - // mifare == 6 bytes - // iclass == 8 bytes - // default to 6 bytes. - if (keylen != 4 && keylen != 6 && keylen != 8) { - keylen = 6; - } - - // double up since its chars - keylen <<= 1; - - char line[255]; - - size_t counter = 0; - int retval = PM3_SUCCESS; - - FILE *f = fopen(fileName, "r"); - if (!f) { - PrintAndLogEx(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", fileName); - retval = PM3_EFILE; - goto out; - } - - // read file - while (fgets(line, sizeof(line), f)) { - - // add null terminator - line[keylen] = 0; - - // smaller keys than expected is skipped - if (strlen(line) < keylen) - continue; - - // The line start with # is comment, skip - if (line[0] == '#') - continue; - - if (!isxdigit(line[0])) { - PrintAndLogEx(FAILED, "file content error. '%s' must include " _BLUE_("%2d") "HEX symbols", line, keylen); - continue; - } - - uint64_t key = strtoull(line, NULL, 16); - - num_to_bytes(key, keylen >> 1, data + counter); - (*keycnt)++; - memset(line, 0, sizeof(line)); - counter += (keylen >> 1); - } - fclose(f); - PrintAndLogEx(SUCCESS, "loaded " _GREEN_("%2d") "keys from dictionary file " _YELLOW_("%s"), *keycnt, fileName); - - if (datalen) - *datalen = counter; -out: - free(fileName); - return retval; -} - -int convertOldMfuDump(uint8_t **dump, size_t *dumplen) { - if (!dump || !dumplen || *dumplen < OLD_MFU_DUMP_PREFIX_LENGTH) - return 1; - // try to check new file format - mfu_dump_t *mfu_dump = (mfu_dump_t *) *dump; - if ((*dumplen - MFU_DUMP_PREFIX_LENGTH) / 4 - 1 == mfu_dump->pages) - return 0; - // convert old format - old_mfu_dump_t *old_mfu_dump = (old_mfu_dump_t *) *dump; - - size_t old_data_len = *dumplen - OLD_MFU_DUMP_PREFIX_LENGTH; - size_t new_dump_len = old_data_len + MFU_DUMP_PREFIX_LENGTH; - - mfu_dump = (mfu_dump_t *) calloc(new_dump_len, sizeof(uint8_t)); - - memcpy(mfu_dump->version, old_mfu_dump->version, 8); - memcpy(mfu_dump->tbo, old_mfu_dump->tbo, 2); - mfu_dump->tbo1[0] = old_mfu_dump->tbo1[0]; - memcpy(mfu_dump->signature, old_mfu_dump->signature, 32); - for (int i = 0; i < 3; i++) - mfu_dump->counter_tearing[i][3] = old_mfu_dump->tearing[i]; - - memcpy(mfu_dump->data, old_mfu_dump->data, old_data_len); - mfu_dump->pages = old_data_len / 4 - 1; - // free old buffer, return new buffer - *dumplen = new_dump_len; - free(*dump); - *dump = (uint8_t *) mfu_dump; - PrintAndLogEx(SUCCESS, "old mfu dump format, was converted on load to " _GREEN_("%d") " pages", mfu_dump->pages + 1); - return PM3_SUCCESS; -} - - -#else //if we're on ARM - -#endif diff --git a/client/loclass/fileutils.h b/client/loclass/fileutils.h deleted file mode 100644 index 74d54000b..000000000 --- a/client/loclass/fileutils.h +++ /dev/null @@ -1,181 +0,0 @@ -/***************************************************************************** - * WARNING - * - * THIS CODE IS CREATED FOR EXPERIMENTATION AND EDUCATIONAL USE ONLY. - * - * USAGE OF THIS CODE IN OTHER WAYS MAY INFRINGE UPON THE INTELLECTUAL - * PROPERTY OF OTHER PARTIES, SUCH AS INSIDE SECURE AND HID GLOBAL, - * AND MAY EXPOSE YOU TO AN INFRINGEMENT ACTION FROM THOSE PARTIES. - * - * THIS CODE SHOULD NEVER BE USED TO INFRINGE PATENTS OR INTELLECTUAL PROPERTY RIGHTS. - * - ***************************************************************************** - * - * This file is part of loclass. It is a reconstructon of the cipher engine - * used in iClass, and RFID techology. - * - * The implementation is based on the work performed by - * Flavio D. Garcia, Gerhard de Koning Gans, Roel Verdult and - * Milosch Meriac in the paper "Dismantling IClass". - * - * Copyright (C) 2014 Martin Holst Swende - * - * This is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation, or, at your option, any later version. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with loclass. If not, see . - * - * - ****************************************************************************/ - -#ifndef FILEUTILS_H -#define FILEUTILS_H - -#ifndef ON_DEVICE - -#include -#include -#include -#include -#include -#include -#include "../ui.h" -#include "../emv/emvjson.h" -#include "mifare/mifare4.h" -#include "cmdhfmfu.h" - -typedef enum { - jsfRaw, - jsfCardMemory, - jsfMfuMemory, - jsfHitag, -// jsf14b, -// jsf15, -// jsfLegic, -// jsfT55xx, -} JSONFileType; - -int fileExists(const char *filename); - -/** - * @brief Utility function to save data to a binary file. This method takes a preferred name, but if that - * file already exists, it tries with another name until it finds something suitable. - * E.g. dumpdata-15.txt - * - * @param preferredName - * @param suffix the file suffix. Including the ".". - * @param data The binary data to write to the file - * @param datalen the length of the data - * @return 0 for ok, 1 for failz - */ -int saveFile(const char *preferredName, const char *suffix, const void *data, size_t datalen); - -/** - * @brief Utility function to save data to a textfile (EML). This method takes a preferred name, but if that - * file already exists, it tries with another name until it finds something suitable. - * E.g. dumpdata-15.txt - * - * @param preferredName - * @param data The binary data to write to the file - * @param datalen the length of the data - * @param blocksize the length of one row - * @return 0 for ok, 1 for failz -*/ -int saveFileEML(const char *preferredName, uint8_t *data, size_t datalen, size_t blocksize); - -/** STUB - * @brief Utility function to save JSON data to a file. This method takes a preferred name, but if that - * file already exists, it tries with another name until it finds something suitable. - * E.g. dumpdata-15.json - * - * @param preferredName - * @param ftype type of file. - * @param data The binary data to write to the file - * @param datalen the length of the data - * @return 0 for ok, 1 for failz - */ -int saveFileJSON(const char *preferredName, JSONFileType ftype, uint8_t *data, size_t datalen); - -/** STUB - * @brief Utility function to load data from a binary file. This method takes a preferred name. - * E.g. dumpdata-15.bin - * - * @param preferredName - * @param suffix the file suffix. Including the ".". - * @param data The data array to store the loaded bytes from file - * @param maxdatalen the number of bytes that your data array has - * @param datalen the number of bytes loaded from file - * @return 0 for ok, 1 for failz -*/ -int loadFile(const char *preferredName, const char *suffix, void *data, size_t maxdatalen, size_t *datalen); - -/** - * @brief Utility function to load data from a textfile (EML). This method takes a preferred name. - * E.g. dumpdata-15.txt - * - * @param preferredName - * @param data The data array to store the loaded bytes from file - * @param datalen the number of bytes loaded from file - * @return 0 for ok, 1 for failz -*/ -int loadFileEML(const char *preferredName, void *data, size_t *datalen); - -/** - * @brief Utility function to load data from a JSON textfile. This method takes a preferred name. - * E.g. dumpdata-15.json - * - * @param preferredName - * @param data The data array to store the loaded bytes from file - * @param maxdatalen maximum size of data array in bytes - * @param datalen the number of bytes loaded from file - * @return 0 for ok, 1 for failz -*/ -int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_t *datalen); - - -/** - * @brief Utility function to load data from a DICTIONARY textfile. This method takes a preferred name. - * E.g. default_keys.dic - * - * @param preferredName - * @param data The data array to store the loaded bytes from file - * @param maxdatalen maximum size of data array in bytes - * @param datalen the number of bytes loaded from file - * @param keylen the number of bytes a key per row is - * @return 0 for ok, 1 for failz -*/ -int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, uint8_t keylen, uint16_t *keycnt); - -/** - * @brief Utility function to check and convert old mfu dump format to new - * - * @param dump pointer to loaded dump to check and convert format - * @param dumplen the number of bytes loaded dump and converted - * @return 0 for ok, 1 for fails -*/ -int convertOldMfuDump(uint8_t **dump, size_t *dumplen); - -#define PrintAndLogEx(level, format, args...) PrintAndLogEx(level, format , ## args) -#else - -/** -* Utility function to print to console. This is used consistently within the library instead -* of printf, but it actually only calls printf. The reason to have this method is to -*make it simple to plug this library into proxmark, which has this function already to -* write also to a logfile. When doing so, just point this function to use PrintAndLog -* @param fmt -*/ -#define PrintAndLogEx(level, format, args...) { } - - - -#endif //ON_DEVICE - -#endif // FILEUTILS_H From 56267ea6235d704f4385599ea7c6bede6bf21df7 Mon Sep 17 00:00:00 2001 From: Iceman Date: Wed, 21 Aug 2019 14:43:22 +0200 Subject: [PATCH 0392/1854] readd fileutils --- client/fileutils.c | 618 +++++++++++++++++++++++++++++++++++++++++++++ client/fileutils.h | 181 +++++++++++++ 2 files changed, 799 insertions(+) create mode 100644 client/fileutils.c create mode 100644 client/fileutils.h diff --git a/client/fileutils.c b/client/fileutils.c new file mode 100644 index 000000000..b89925334 --- /dev/null +++ b/client/fileutils.c @@ -0,0 +1,618 @@ +/***************************************************************************** + * WARNING + * + * THIS CODE IS CREATED FOR EXPERIMENTATION AND EDUCATIONAL USE ONLY. + * + * USAGE OF THIS CODE IN OTHER WAYS MAY INFRINGE UPON THE INTELLECTUAL + * PROPERTY OF OTHER PARTIES, SUCH AS INSIDE SECURE AND HID GLOBAL, + * AND MAY EXPOSE YOU TO AN INFRINGEMENT ACTION FROM THOSE PARTIES. + * + * THIS CODE SHOULD NEVER BE USED TO INFRINGE PATENTS OR INTELLECTUAL PROPERTY RIGHTS. + * + ***************************************************************************** + * + * This file is part of loclass. It is a reconstructon of the cipher engine + * used in iClass, and RFID techology. + * + * The implementation is based on the work performed by + * Flavio D. Garcia, Gerhard de Koning Gans, Roel Verdult and + * Milosch Meriac in the paper "Dismantling IClass". + * + * Copyright (C) 2014 Martin Holst Swende + * + * This is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation, or, at your option, any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with loclass. If not, see . + * + * + ****************************************************************************/ +#include "fileutils.h" + +#include + +#include "pm3_cmd.h" +#include "commonutil.h" +#include "util.h" + + +#ifndef ON_DEVICE + +#define PATH_MAX_LENGTH 100 + +/** + * @brief checks if a file exists + * @param filename + * @return + */ +int fileExists(const char *filename) { + +#ifdef _WIN32 + struct _stat st; + int result = _stat(filename, &st); +#else + struct stat st; + int result = stat(filename, &st); +#endif + return result == 0; +} + +static char *filenamemcopy(const char *preferredName, const char *suffix) { + if (preferredName == NULL) return NULL; + if (suffix == NULL) return NULL; + char *fileName = (char *) calloc(strlen(preferredName) + strlen(suffix) + 1, sizeof(uint8_t)); + if (fileName == NULL) + return NULL; + strcpy(fileName, preferredName); + if (str_endswith(fileName, suffix)) + return fileName; + strcat(fileName, suffix); + return fileName; +} + +static char *newfilenamemcopy(const char *preferredName, const char *suffix) { + if (preferredName == NULL) return NULL; + if (suffix == NULL) return NULL; + uint16_t preferredNameLen = strlen(preferredName); + if (str_endswith(preferredName, suffix)) + preferredNameLen -= strlen(suffix); + char *fileName = (char *) calloc(preferredNameLen + strlen(suffix) + 1 + 10, sizeof(uint8_t)); // 10: room for filenum to ensure new filename + if (fileName == NULL) { + return NULL; + } + int num = 1; + sprintf(fileName, "%.*s%s", preferredNameLen, preferredName, suffix); + while (fileExists(fileName)) { + sprintf(fileName, "%.*s-%d%s", preferredNameLen, preferredName, num, suffix); + num++; + } + return fileName; +} + +int saveFile(const char *preferredName, const char *suffix, const void *data, size_t datalen) { + + if (data == NULL) return 1; + char *fileName = newfilenamemcopy(preferredName, suffix); + if (fileName == NULL) return 1; + + /* We should have a valid filename now, e.g. dumpdata-3.bin */ + + /*Opening file for writing in binary mode*/ + FILE *f = fopen(fileName, "wb"); + if (!f) { + PrintAndLogEx(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", fileName); + free(fileName); + return PM3_EFILE; + } + fwrite(data, 1, datalen, f); + fflush(f); + fclose(f); + PrintAndLogEx(SUCCESS, "saved %u bytes to binary file " _YELLOW_("%s"), datalen, fileName); + free(fileName); + return PM3_SUCCESS; +} + +int saveFileEML(const char *preferredName, uint8_t *data, size_t datalen, size_t blocksize) { + + if (data == NULL) return 1; + char *fileName = newfilenamemcopy(preferredName, ".eml"); + if (fileName == NULL) return 1; + + int retval = PM3_SUCCESS; + int blocks = datalen / blocksize; + uint16_t currblock = 1; + + /* We should have a valid filename now, e.g. dumpdata-3.bin */ + + /*Opening file for writing in text mode*/ + FILE *f = fopen(fileName, "w+"); + if (!f) { + PrintAndLogEx(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", fileName); + retval = PM3_EFILE; + goto out; + } + + for (size_t i = 0; i < datalen; i++) { + fprintf(f, "%02X", data[i]); + + // no extra line in the end + if ((i + 1) % blocksize == 0 && currblock != blocks) { + fprintf(f, "\n"); + currblock++; + } + } + // left overs + if (datalen % blocksize != 0) { + int index = blocks * blocksize; + for (size_t j = 0; j < datalen % blocksize; j++) { + fprintf(f, "%02X", data[index + j]); + } + } + fflush(f); + fclose(f); + PrintAndLogEx(SUCCESS, "saved %d blocks to text file " _YELLOW_("%s"), blocks, fileName); + +out: + free(fileName); + return retval; +} + +int saveFileJSON(const char *preferredName, JSONFileType ftype, uint8_t *data, size_t datalen) { + + if (data == NULL) return 1; + char *fileName = newfilenamemcopy(preferredName, ".json"); + if (fileName == NULL) return 1; + + int retval = PM3_SUCCESS; + + json_t *root = json_object(); + JsonSaveStr(root, "Created", "proxmark3"); + switch (ftype) { + case jsfRaw: { + JsonSaveStr(root, "FileType", "raw"); + JsonSaveBufAsHexCompact(root, "raw", data, datalen); + break; + } + case jsfCardMemory: { + JsonSaveStr(root, "FileType", "mfcard"); + for (size_t i = 0; i < (datalen / 16); i++) { + char path[PATH_MAX_LENGTH] = {0}; + sprintf(path, "$.blocks.%zu", i); + JsonSaveBufAsHexCompact(root, path, &data[i * 16], 16); + + if (i == 0) { + JsonSaveBufAsHexCompact(root, "$.Card.UID", &data[0], 4); + JsonSaveBufAsHexCompact(root, "$.Card.SAK", &data[5], 1); + JsonSaveBufAsHexCompact(root, "$.Card.ATQA", &data[6], 2); + } + + if (mfIsSectorTrailer(i)) { + memset(path, 0x00, sizeof(path)); + sprintf(path, "$.SectorKeys.%d.KeyA", mfSectorNum(i)); + JsonSaveBufAsHexCompact(root, path, &data[i * 16], 6); + + memset(path, 0x00, sizeof(path)); + sprintf(path, "$.SectorKeys.%d.KeyB", mfSectorNum(i)); + JsonSaveBufAsHexCompact(root, path, &data[i * 16 + 10], 6); + + memset(path, 0x00, sizeof(path)); + uint8_t *adata = &data[i * 16 + 6]; + sprintf(path, "$.SectorKeys.%d.AccessConditions", mfSectorNum(i)); + JsonSaveBufAsHexCompact(root, path, &data[i * 16 + 6], 4); + + memset(path, 0x00, sizeof(path)); + sprintf(path, "$.SectorKeys.%d.AccessConditionsText.block%zu", mfSectorNum(i), i - 3); + JsonSaveStr(root, path, mfGetAccessConditionsDesc(0, adata)); + + memset(path, 0x00, sizeof(path)); + sprintf(path, "$.SectorKeys.%d.AccessConditionsText.block%zu", mfSectorNum(i), i - 2); + JsonSaveStr(root, path, mfGetAccessConditionsDesc(1, adata)); + + memset(path, 0x00, sizeof(path)); + sprintf(path, "$.SectorKeys.%d.AccessConditionsText.block%zu", mfSectorNum(i), i - 1); + JsonSaveStr(root, path, mfGetAccessConditionsDesc(2, adata)); + + memset(path, 0x00, sizeof(path)); + sprintf(path, "$.SectorKeys.%d.AccessConditionsText.block%zu", mfSectorNum(i), i); + JsonSaveStr(root, path, mfGetAccessConditionsDesc(3, adata)); + + memset(path, 0x00, sizeof(path)); + sprintf(path, "$.SectorKeys.%d.AccessConditionsText.UserData", mfSectorNum(i)); + JsonSaveBufAsHexCompact(root, path, &adata[3], 1); + } + } + break; + } + case jsfMfuMemory: { + JsonSaveStr(root, "FileType", "mfu"); + + mfu_dump_t *tmp = (mfu_dump_t *)data; + + uint8_t uid[7] = {0}; + memcpy(uid, tmp->data, 3); + memcpy(uid + 3, tmp->data + 4, 4); + + char path[PATH_MAX_LENGTH] = {0}; + + JsonSaveBufAsHexCompact(root, "$.Card.UID", uid, sizeof(uid)); + JsonSaveBufAsHexCompact(root, "$.Card.Version", tmp->version, sizeof(tmp->version)); + JsonSaveBufAsHexCompact(root, "$.Card.TBO_0", tmp->tbo, sizeof(tmp->tbo)); + JsonSaveBufAsHexCompact(root, "$.Card.TBO_1", tmp->tbo1, sizeof(tmp->tbo1)); + JsonSaveBufAsHexCompact(root, "$.Card.Signature", tmp->signature, sizeof(tmp->signature)); + for (uint8_t i = 0; i < 3; i ++) { + sprintf(path, "$.Card.Counter%d", i); + JsonSaveBufAsHexCompact(root, path, tmp->counter_tearing[i], 3); + sprintf(path, "$.Card.Tearing%d", i); + JsonSaveBufAsHexCompact(root, path, tmp->counter_tearing[i] + 3, 1); + } + + // size of header 56b + size_t len = (datalen - MFU_DUMP_PREFIX_LENGTH) / 4; + + for (size_t i = 0; i < len; i++) { + sprintf(path, "$.blocks.%zu", i); + JsonSaveBufAsHexCompact(root, path, tmp->data + (i * 4), 4); + } + break; + } + case jsfHitag: { + JsonSaveStr(root, "FileType", "hitag"); + uint8_t uid[4] = {0}; + memcpy(uid, data, 4); + + JsonSaveBufAsHexCompact(root, "$.Card.UID", uid, sizeof(uid)); + + for (size_t i = 0; i < (datalen / 4); i++) { + char path[PATH_MAX_LENGTH] = {0}; + sprintf(path, "$.blocks.%zu", i); + JsonSaveBufAsHexCompact(root, path, data + (i * 4), 4); + } + break; + } + } + + int res = json_dump_file(root, fileName, JSON_INDENT(2)); + if (res) { + PrintAndLogEx(FAILED, "error: can't save the file: " _YELLOW_("%s"), fileName); + json_decref(root); + retval = 200; + goto out; + } + PrintAndLogEx(SUCCESS, "saved to json file " _YELLOW_("%s"), fileName); + json_decref(root); + +out: + free(fileName); + return retval; +} + +int loadFile(const char *preferredName, const char *suffix, void *data, size_t maxdatalen, size_t *datalen) { + + if (data == NULL) return 1; + char *fileName = filenamemcopy(preferredName, suffix); + if (fileName == NULL) return 1; + + int retval = PM3_SUCCESS; + + FILE *f = fopen(fileName, "rb"); + if (!f) { + PrintAndLogEx(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", fileName); + free(fileName); + return PM3_EFILE; + } + + // get filesize in order to malloc memory + fseek(f, 0, SEEK_END); + long fsize = ftell(f); + fseek(f, 0, SEEK_SET); + + if (fsize <= 0) { + PrintAndLogEx(FAILED, "error, when getting filesize"); + retval = 1; + goto out; + } + + uint8_t *dump = calloc(fsize, sizeof(uint8_t)); + if (!dump) { + PrintAndLogEx(FAILED, "error, cannot allocate memory"); + retval = 2; + goto out; + } + + size_t bytes_read = fread(dump, 1, fsize, f); + + if (bytes_read != fsize) { + PrintAndLogEx(FAILED, "error, bytes read mismatch file size"); + free(dump); + retval = 3; + goto out; + } + + if (bytes_read > maxdatalen) { + PrintAndLogEx(WARNING, "Warning, bytes read exceed calling array limit. Max bytes is %d bytes", maxdatalen); + bytes_read = maxdatalen; + } + + memcpy((data), dump, bytes_read); + free(dump); + + PrintAndLogEx(SUCCESS, "loaded %d bytes from binary file " _YELLOW_("%s"), bytes_read, fileName); + + *datalen = bytes_read; + +out: + fclose(f); + free(fileName); + + return retval; +} + +int loadFileEML(const char *preferredName, void *data, size_t *datalen) { + + if (data == NULL) return 1; + char *fileName = filenamemcopy(preferredName, ".eml"); + if (fileName == NULL) return 1; + + size_t counter = 0; + int retval = PM3_SUCCESS, hexlen = 0; + + FILE *f = fopen(fileName, "r"); + if (!f) { + PrintAndLogEx(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", fileName); + retval = PM3_EFILE; + goto out; + } + + // 128 + 2 newline chars + 1 null terminator + char line[131]; + memset(line, 0, sizeof(line)); + uint8_t buf[64] = {0x00}; + + while (!feof(f)) { + + memset(line, 0, sizeof(line)); + + if (fgets(line, sizeof(line), f) == NULL) { + if (feof(f)) + break; + fclose(f); + PrintAndLogEx(FAILED, "File reading error."); + retval = 2; + goto out; + } + + if (line[0] == '#') + continue; + + int res = param_gethex_to_eol(line, 0, buf, sizeof(buf), &hexlen); + if (res == 0 || res == 1) { + memcpy(data + counter, buf, hexlen); + counter += hexlen; + } + } + fclose(f); + PrintAndLogEx(SUCCESS, "loaded %d bytes from text file " _YELLOW_("%s"), counter, fileName); + + if (datalen) + *datalen = counter; + +out: + free(fileName); + return retval; +} + +int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_t *datalen) { + + if (data == NULL) return 1; + char *fileName = filenamemcopy(preferredName, ".json"); + if (fileName == NULL) return 1; + + *datalen = 0; + json_t *root; + json_error_t error; + + int retval = PM3_SUCCESS; + + root = json_load_file(fileName, 0, &error); + if (!root) { + PrintAndLogEx(ERR, "ERROR: json " _YELLOW_("%s") " error on line %d: %s", fileName, error.line, error.text); + retval = 2; + goto out; + } + + if (!json_is_object(root)) { + PrintAndLogEx(ERR, "ERROR: Invalid json " _YELLOW_("%s") " format. root must be an object.", fileName); + retval = 3; + goto out; + } + + uint8_t *udata = (uint8_t *)data; + char ctype[100] = {0}; + JsonLoadStr(root, "$.FileType", ctype); + + if (!strcmp(ctype, "raw")) { + JsonLoadBufAsHex(root, "$.raw", udata, maxdatalen, datalen); + } + + if (!strcmp(ctype, "mfcard")) { + size_t sptr = 0; + for (int i = 0; i < 256; i++) { + if (sptr + 16 > maxdatalen) { + retval = 5; + goto out; + } + + char path[30] = {0}; + sprintf(path, "$.blocks.%d", i); + + size_t len = 0; + JsonLoadBufAsHex(root, path, &udata[sptr], 16, &len); + if (!len) + break; + + sptr += len; + } + + *datalen = sptr; + } + + if (!strcmp(ctype, "mfu")) { + size_t sptr = 0; + for (int i = 0; i < 256; i++) { + if (sptr + 4 > maxdatalen) { + retval = 5; + goto out; + } + + char path[30] = {0}; + sprintf(path, "$.blocks.%d", i); + + size_t len = 0; + JsonLoadBufAsHex(root, path, &udata[sptr], 4, &len); + if (!len) + break; + + sptr += len; + } + + *datalen = sptr; + } + + if (!strcmp(ctype, "hitag")) { + size_t sptr = 0; + for (size_t i = 0; i < (maxdatalen / 4); i++) { + if (sptr + 4 > maxdatalen) { + retval = 5; + goto out; + } + + char path[30] = {0}; + sprintf(path, "$.blocks.%zu", i); + + size_t len = 0; + JsonLoadBufAsHex(root, path, &udata[sptr], 4, &len); + if (!len) + break; + + sptr += len; + } + + *datalen = sptr; + } + + PrintAndLogEx(SUCCESS, "loaded from JSON file " _YELLOW_("%s"), fileName); +out: + json_decref(root); + free(fileName); + return retval; +} + +int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, uint8_t keylen, uint16_t *keycnt) { + + + if (data == NULL) return 1; + char *fileName = filenamemcopy(preferredName, ".dic"); + if (fileName == NULL) return 1; + + // t5577 == 4bytes + // mifare == 6 bytes + // iclass == 8 bytes + // default to 6 bytes. + if (keylen != 4 && keylen != 6 && keylen != 8) { + keylen = 6; + } + + // double up since its chars + keylen <<= 1; + + char line[255]; + + size_t counter = 0; + int retval = PM3_SUCCESS; + + FILE *f = fopen(fileName, "r"); + if (!f) { + PrintAndLogEx(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", fileName); + retval = PM3_EFILE; + goto out; + } + + // read file + while (fgets(line, sizeof(line), f)) { + + // add null terminator + line[keylen] = 0; + + // smaller keys than expected is skipped + if (strlen(line) < keylen) + continue; + + // The line start with # is comment, skip + if (line[0] == '#') + continue; + + if (!isxdigit(line[0])) { + PrintAndLogEx(FAILED, "file content error. '%s' must include " _BLUE_("%2d") "HEX symbols", line, keylen); + continue; + } + + uint64_t key = strtoull(line, NULL, 16); + + num_to_bytes(key, keylen >> 1, data + counter); + (*keycnt)++; + memset(line, 0, sizeof(line)); + counter += (keylen >> 1); + } + fclose(f); + PrintAndLogEx(SUCCESS, "loaded " _GREEN_("%2d") "keys from dictionary file " _YELLOW_("%s"), *keycnt, fileName); + + if (datalen) + *datalen = counter; +out: + free(fileName); + return retval; +} + +int convertOldMfuDump(uint8_t **dump, size_t *dumplen) { + if (!dump || !dumplen || *dumplen < OLD_MFU_DUMP_PREFIX_LENGTH) + return 1; + // try to check new file format + mfu_dump_t *mfu_dump = (mfu_dump_t *) *dump; + if ((*dumplen - MFU_DUMP_PREFIX_LENGTH) / 4 - 1 == mfu_dump->pages) + return 0; + // convert old format + old_mfu_dump_t *old_mfu_dump = (old_mfu_dump_t *) *dump; + + size_t old_data_len = *dumplen - OLD_MFU_DUMP_PREFIX_LENGTH; + size_t new_dump_len = old_data_len + MFU_DUMP_PREFIX_LENGTH; + + mfu_dump = (mfu_dump_t *) calloc(new_dump_len, sizeof(uint8_t)); + + memcpy(mfu_dump->version, old_mfu_dump->version, 8); + memcpy(mfu_dump->tbo, old_mfu_dump->tbo, 2); + mfu_dump->tbo1[0] = old_mfu_dump->tbo1[0]; + memcpy(mfu_dump->signature, old_mfu_dump->signature, 32); + for (int i = 0; i < 3; i++) + mfu_dump->counter_tearing[i][3] = old_mfu_dump->tearing[i]; + + memcpy(mfu_dump->data, old_mfu_dump->data, old_data_len); + mfu_dump->pages = old_data_len / 4 - 1; + // free old buffer, return new buffer + *dumplen = new_dump_len; + free(*dump); + *dump = (uint8_t *) mfu_dump; + PrintAndLogEx(SUCCESS, "old mfu dump format, was converted on load to " _GREEN_("%d") " pages", mfu_dump->pages + 1); + return PM3_SUCCESS; +} + + +#else //if we're on ARM + +#endif diff --git a/client/fileutils.h b/client/fileutils.h new file mode 100644 index 000000000..74d54000b --- /dev/null +++ b/client/fileutils.h @@ -0,0 +1,181 @@ +/***************************************************************************** + * WARNING + * + * THIS CODE IS CREATED FOR EXPERIMENTATION AND EDUCATIONAL USE ONLY. + * + * USAGE OF THIS CODE IN OTHER WAYS MAY INFRINGE UPON THE INTELLECTUAL + * PROPERTY OF OTHER PARTIES, SUCH AS INSIDE SECURE AND HID GLOBAL, + * AND MAY EXPOSE YOU TO AN INFRINGEMENT ACTION FROM THOSE PARTIES. + * + * THIS CODE SHOULD NEVER BE USED TO INFRINGE PATENTS OR INTELLECTUAL PROPERTY RIGHTS. + * + ***************************************************************************** + * + * This file is part of loclass. It is a reconstructon of the cipher engine + * used in iClass, and RFID techology. + * + * The implementation is based on the work performed by + * Flavio D. Garcia, Gerhard de Koning Gans, Roel Verdult and + * Milosch Meriac in the paper "Dismantling IClass". + * + * Copyright (C) 2014 Martin Holst Swende + * + * This is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation, or, at your option, any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with loclass. If not, see . + * + * + ****************************************************************************/ + +#ifndef FILEUTILS_H +#define FILEUTILS_H + +#ifndef ON_DEVICE + +#include +#include +#include +#include +#include +#include +#include "../ui.h" +#include "../emv/emvjson.h" +#include "mifare/mifare4.h" +#include "cmdhfmfu.h" + +typedef enum { + jsfRaw, + jsfCardMemory, + jsfMfuMemory, + jsfHitag, +// jsf14b, +// jsf15, +// jsfLegic, +// jsfT55xx, +} JSONFileType; + +int fileExists(const char *filename); + +/** + * @brief Utility function to save data to a binary file. This method takes a preferred name, but if that + * file already exists, it tries with another name until it finds something suitable. + * E.g. dumpdata-15.txt + * + * @param preferredName + * @param suffix the file suffix. Including the ".". + * @param data The binary data to write to the file + * @param datalen the length of the data + * @return 0 for ok, 1 for failz + */ +int saveFile(const char *preferredName, const char *suffix, const void *data, size_t datalen); + +/** + * @brief Utility function to save data to a textfile (EML). This method takes a preferred name, but if that + * file already exists, it tries with another name until it finds something suitable. + * E.g. dumpdata-15.txt + * + * @param preferredName + * @param data The binary data to write to the file + * @param datalen the length of the data + * @param blocksize the length of one row + * @return 0 for ok, 1 for failz +*/ +int saveFileEML(const char *preferredName, uint8_t *data, size_t datalen, size_t blocksize); + +/** STUB + * @brief Utility function to save JSON data to a file. This method takes a preferred name, but if that + * file already exists, it tries with another name until it finds something suitable. + * E.g. dumpdata-15.json + * + * @param preferredName + * @param ftype type of file. + * @param data The binary data to write to the file + * @param datalen the length of the data + * @return 0 for ok, 1 for failz + */ +int saveFileJSON(const char *preferredName, JSONFileType ftype, uint8_t *data, size_t datalen); + +/** STUB + * @brief Utility function to load data from a binary file. This method takes a preferred name. + * E.g. dumpdata-15.bin + * + * @param preferredName + * @param suffix the file suffix. Including the ".". + * @param data The data array to store the loaded bytes from file + * @param maxdatalen the number of bytes that your data array has + * @param datalen the number of bytes loaded from file + * @return 0 for ok, 1 for failz +*/ +int loadFile(const char *preferredName, const char *suffix, void *data, size_t maxdatalen, size_t *datalen); + +/** + * @brief Utility function to load data from a textfile (EML). This method takes a preferred name. + * E.g. dumpdata-15.txt + * + * @param preferredName + * @param data The data array to store the loaded bytes from file + * @param datalen the number of bytes loaded from file + * @return 0 for ok, 1 for failz +*/ +int loadFileEML(const char *preferredName, void *data, size_t *datalen); + +/** + * @brief Utility function to load data from a JSON textfile. This method takes a preferred name. + * E.g. dumpdata-15.json + * + * @param preferredName + * @param data The data array to store the loaded bytes from file + * @param maxdatalen maximum size of data array in bytes + * @param datalen the number of bytes loaded from file + * @return 0 for ok, 1 for failz +*/ +int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_t *datalen); + + +/** + * @brief Utility function to load data from a DICTIONARY textfile. This method takes a preferred name. + * E.g. default_keys.dic + * + * @param preferredName + * @param data The data array to store the loaded bytes from file + * @param maxdatalen maximum size of data array in bytes + * @param datalen the number of bytes loaded from file + * @param keylen the number of bytes a key per row is + * @return 0 for ok, 1 for failz +*/ +int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, uint8_t keylen, uint16_t *keycnt); + +/** + * @brief Utility function to check and convert old mfu dump format to new + * + * @param dump pointer to loaded dump to check and convert format + * @param dumplen the number of bytes loaded dump and converted + * @return 0 for ok, 1 for fails +*/ +int convertOldMfuDump(uint8_t **dump, size_t *dumplen); + +#define PrintAndLogEx(level, format, args...) PrintAndLogEx(level, format , ## args) +#else + +/** +* Utility function to print to console. This is used consistently within the library instead +* of printf, but it actually only calls printf. The reason to have this method is to +*make it simple to plug this library into proxmark, which has this function already to +* write also to a logfile. When doing so, just point this function to use PrintAndLog +* @param fmt +*/ +#define PrintAndLogEx(level, format, args...) { } + + + +#endif //ON_DEVICE + +#endif // FILEUTILS_H From c69d599a3f7cca1eb86c00ef042e840b5a2a0a9d Mon Sep 17 00:00:00 2001 From: Iceman Date: Wed, 21 Aug 2019 14:49:55 +0200 Subject: [PATCH 0393/1854] Update protocols.h From https://github.com/Proxmark/proxmark3/pull/855 (@pwpiwi) --- include/protocols.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/include/protocols.h b/include/protocols.h index 5a1e56f4e..cb38d9c84 100644 --- a/include/protocols.h +++ b/include/protocols.h @@ -542,5 +542,26 @@ ISO 7816-4 Basic interindustry commands. For command APDU's. #define CALYPSO_SAM_SV_DEBIT 0x54 #define CALYPSO_SAM_SV_RELOAD 0x56 +// HITAG1 commands +#define HITAG1_SET_CCNEW 0xC2 // left 5 bits only +#define HITAG1_READ_ID 0x00 // not a real command, consists of 5 bits length, bits partial SN, 8 bits CRC +#define HITAG1_SELECT 0x00 // left 5 bits only, followed by 32 bits SN and 8 bits CRC +#define HITAG1_WRPPAGE 0x80 // left 4 bits only, followed by 8 bits page and 8 bits CRC +#define HITAG1_WRPBLK 0x90 // left 4 bits only, followed by 8 bits block and 8 bits CRC +#define HITAG1_WRCPAGE 0xA0 // left 4 bits only, followed by 8 bits page or key information and 8 bits CRC +#define HITAG1_WRCBLK 0xB0 // left 4 bits only, followed by 8 bits block and 8 bits CRC +#define HITAG1_RDPPAGE 0xC0 // left 4 bits only, followed by 8 bits page and 8 bits CRC +#define HITAG1_RDPBLK 0xD0 // left 4 bits only, followed by 8 bits block and 8 bits CRC +#define HITAG1_RDCPAGE 0xE0 // left 4 bits only, followed by 8 bits page and 8 bits CRC +#define HITAG1_RDCBLK 0xF0 // left 4 bits only, followed by 8 bits block and 8 bits CRC +#define HITAG1_HALT 0x70 // left 4 bits only, followed by 8 bits (dummy) page and 8 bits CRC + +// HITAG2 commands +#define HITAG2_START_AUTH 0xC0 // left 5 bits only +#define HITAG2_READ_PAGE 0xC0 // page number in bits 5 to 3, page number inverted in bit 0 and following 2 bits +#define HITAG2_READ_PAGE_INVERTED 0x44 // page number in bits 5 to 3, page number inverted in bit 0 and following 2 bits +#define HITAG2_WRITE_PAGE 0x82 // page number in bits 5 to 3, page number inverted in bit 0 and following 2 bits +#define HITAG2_HALT 0x00 // left 5 bits only + #endif // PROTOCOLS_H From 3cf64f9f23712830fbeaef2028ca46b9224f1030 Mon Sep 17 00:00:00 2001 From: Iceman Date: Wed, 21 Aug 2019 16:49:32 +0200 Subject: [PATCH 0394/1854] fix: some mkdir stuff.. --- Makefile.host | 2 +- fpga/tests/Makefile | 4 ++-- tools/Makefile | 21 +++++++++++++-------- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/Makefile.host b/Makefile.host index 9ab7ce8ca..e2d3b3f6f 100644 --- a/Makefile.host +++ b/Makefile.host @@ -9,7 +9,7 @@ LD = gcc RM = rm -f MV = mv CP = cp -a -MKDIR = mkdir +MKDIR = mkdir -p CFLAGS ?= -Wall -Werror -O3 CFLAGS += $(MYDEFS) $(MYCFLAGS) $(MYINCLUDES) diff --git a/fpga/tests/Makefile b/fpga/tests/Makefile index 79ed20816..f2ae6d729 100644 --- a/fpga/tests/Makefile +++ b/fpga/tests/Makefile @@ -5,7 +5,7 @@ # at your option, any later version. See the LICENSE.txt file for the text of # the license. #----------------------------------------------------------------------------- - +MKDIR = mkdir -p TEST_OUTDIR = tb_tmp TB_SOURCES = \ @@ -62,7 +62,7 @@ tb_lf_edge_detect: tb_lf_edge_detect.vvp | test_dir rm -f $(TEST_OUTDIR)/data.* test_dir: - @if [ ! -d $(TEST_OUTDIR) ] ; then mkdir $(TEST_OUTDIR) ; fi + @if [ ! -d $(TEST_OUTDIR) ] ; then $(MKDIR) $(TEST_OUTDIR) ; fi .PHONY: all clean diff --git a/tools/Makefile b/tools/Makefile index 3b1dc1b0f..5f2355f20 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -1,18 +1,23 @@ +MKDIR = mkdir -p +WGET = wget -N +TAR = tar Jxvf +GIT = git clone + get_craptev1: - wget -N http://crapto1.netgarage.org/craptev1-v1.1.tar.xz - tar Jxvf craptev1-v1.1.tar.xz -C craptev1-v1.1 + $(WGET) http://crapto1.netgarage.org/craptev1-v1.1.tar.xz + $(TAR) craptev1-v1.1.tar.xz -C craptev1-v1.1 get_crapto1: - wget -N http://crapto1.netgarage.org/crapto1-v3.3.tar.xz - tar Jxvf crapto1-v3.3.tar.xz -C crapto1-v3.3 + $(WGET) http://crapto1.netgarage.org/crapto1-v3.3.tar.xz + $(TAR) Jxvf crapto1-v3.3.tar.xz -C crapto1-v3.3 get_nonce_bf: -# git clone https://github.com/J-Run/mf_key_brute.git mf_key_brute - git clone https://github.com/iceman1001/mf_nonce_brute mf_nonce_brute +# $(GIT) https://github.com/J-Run/mf_key_brute.git mf_key_brute + $(GIT) https://github.com/iceman1001/mf_nonce_brute mf_nonce_brute get_xorsearch: - mkdir xorsearch - wget -N https://didierstevens.com/files/software/XORSearch_V1_11_2.zip + $(MKDIR) xorsearch + $(WGET) https://didierstevens.com/files/software/XORSearch_V1_11_2.zip # Mingw # unzzip-big XORSearch_V1_11_2.zip # linux From da313732587fbed698b88022d6d08967be310487 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 21 Aug 2019 20:06:14 +0200 Subject: [PATCH 0395/1854] non-rdv4 PLATFORM must now use the generic PM3OTHER, simpler --- CHANGELOG.md | 1 + common_arm/Makefile.hal | 69 +++++-------------- .../4_Advanced-compilation-parameters.md | 18 ++--- 3 files changed, 25 insertions(+), 63 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b5f7d8d76..b8d19d065 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Change non-rdv4 PLATFORM must now use the generic PM3OTHER, simpler (@doegox) - Fix reveng integration for all platforms else than WIN32 (@doegox) - Add cheat sheet for easy operations of the Proxmark3 (scund00r) - Chg commands are now in green in the helptext list (@iceman1001) diff --git a/common_arm/Makefile.hal b/common_arm/Makefile.hal index 411744037..22ae385c3 100644 --- a/common_arm/Makefile.hal +++ b/common_arm/Makefile.hal @@ -14,41 +14,29 @@ define KNOWN_PLATFORM_DEFINITIONS Known definitions: -+==========================================================+ -| PLATFORM | DESCRIPTION | -+==========================================================+ -| PM3RDV4 (def) | Proxmark3 rdv4 with AT91SAM7S512 | -+----------------------------------------------------------+ -| PM3EVO | Proxmark3 EVO with AT91SAM7S512 | -+----------------------------------------------------------+ -| PM3V40 | Proxmark3 V4.0 with AT91SAM7S512 | -+----------------------------------------------------------+ -| PM3EASY | Proxmark3 rdv3 Easy with AT91SAM7S256 | -+----------------------------------------------------------+ -| PM3EASY512 | Proxmark3 rdv3 Easy with AT91SAM7S512 | -+----------------------------------------------------------+ -| PM3RDV2 | Proxmark3 rdv2 with AT91SAM7S512 | -+----------------------------------------------------------+ -| PM3OLD256 | Proxmark3 V1 with AT91SAM7S256 | -+----------------------------------------------------------+ -| PM3OLD512 | Proxmark3 V1 with AT91SAM7S512 | -+----------------------------------------------------------+ ++============================================+ +| PLATFORM | DESCRIPTION | ++============================================+ +| PM3RDV4 (def) | Proxmark3 rdv4 | ++--------------------------------------------+ +| PM3OTHER | Proxmark3 Generic target | ++--------------------------------------------+ -+==========================================================+ -| PLATFORM_EXTRAS | DESCRIPTION | -+==========================================================+ -| BTADDON | Proxmark3 rdv4 BT add-on | -+----------------------------------------------------------+ ++============================================+ +| PLATFORM_EXTRAS | DESCRIPTION | ++============================================+ +| BTADDON | Proxmark3 rdv4 BT add-on | ++--------------------------------------------+ endef define HELP_DEFINITIONS Options to define platform, platform extras and/or standalone mode: -(1) Run make with PLATFORM, PLATFORM_EXTRAS and/or STANDALONE as follows: -make PLATFORM=PM3EASY STANDALONE=$(HELP_EXAMPLE_STANDALONE) +(1) Run make with your PLATFORM, PLATFORM_EXTRAS and/or STANDALONE choices as follows: +make PLATFORM=PM3OTHER STANDALONE=$(HELP_EXAMPLE_STANDALONE) -(2) Save a file called Makefile.platform with contents: -PLATFORM=PM3EASY +(2) Save a file called Makefile.platform with contents, e.g.: +PLATFORM=PM3OTHER or if you have a Proxmark 3 RDV4 with the BT add-on: PLATFORM=PM3RDV4 @@ -68,30 +56,10 @@ endef PLTNAME = Unknown Platform ifeq ($(PLATFORM),PM3RDV4) - MCU = AT91SAM7S512 PLATFORM_DEFS = -DWITH_SMARTCARD -DWITH_FLASH PLTNAME = Proxmark3 rdv4 -else ifeq ($(PLATFORM),PM3EVO) - MCU = AT91SAM7S512 - PLTNAME = Proxmark3 EVO -else ifeq ($(PLATFORM),PM3V40) - MCU = AT91SAM7S512 - PLTNAME = Proxmark3 V4.0 -else ifeq ($(PLATFORM),PM3EASY) - MCU = AT91SAM7S256 - PLTNAME = Proxmark3 rdv3 Easy -else ifeq ($(PLATFORM),PM3EASY512) - MCU = AT91SAM7S512 - PLTNAME = Proxmark3 rdv3 Easy 512 -else ifeq ($(PLATFORM),PM3RDV2) - MCU = AT91SAM7S512 - PLTNAME = Proxmark3 rdv2 -else ifeq ($(PLATFORM),PM3OLD256) - MCU = AT91SAM7S256 - PLTNAME = Proxmark3 V1 with AT91SAM7S256 -else ifeq ($(PLATFORM),PM3OLD512) - MCU = AT91SAM7S512 - PLTNAME = Proxmark3 V1 with AT91SAM7S512 +else ifeq ($(PLATFORM),PM3OTHER) + PLTNAME = Proxmark3 Generic target else $(error Invalid or empty PLATFORM: $(PLATFORM). $(KNOWN_DEFINITIONS)) endif @@ -178,7 +146,6 @@ export PLATFORM export PLATFORM_EXTRAS export PLATFORM_EXTRAS_INFO export PLTNAME -export MCU export PLATFORM_DEFS export PLATFORM_DEFS_INFO export PLATFORM_DEFS_INFO_STANDALONE diff --git a/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md b/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md index 270682696..b4fb4384a 100644 --- a/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md +++ b/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md @@ -19,7 +19,7 @@ These features make it very different from all other devices, there is non other **Recommendation**: if you don't have a RDV4, we strongly recommend your device to have at least a 512kb arm chip, since this repo is on the very edge of 256kb limit. -A firmware built for the RDV4 can still run on the other platforms as it will auto-detect during boot that external SPI and Sim are not present, still it will boot faster if it's tuned to the platform. +A firmware built for the RDV4 can still run on the other platforms as it will auto-detect during boot that external SPI and Sim are not present, still it will boot faster if it's tuned to the platform, which solves USB enumeration issues on some OSes. If you need to tune things and save the configuration, create a file `Makefile.platform` in the root directory of the repository, see `Makefile.platform.sample`. For an up-to-date exhaustive list of options, you can run `make PLATFORM=`. @@ -28,20 +28,14 @@ For an up-to-date exhaustive list of options, you can run `make PLATFORM=`. Here are the supported values you can assign to `PLATFORM` in `Makefile.platform`: -| PLATFORM | DESCRIPTION | -|-----------------|----------------------------------------| -| PM3RDV4 (def) | Proxmark3 rdv4 with AT91SAM7S512 | -| PM3EVO | Proxmark3 EVO with AT91SAM7S512 | -| PM3V40 | Proxmark3 V4.0 with AT91SAM7S512 | -| PM3EASY | Proxmark3 rdv3 Easy with AT91SAM7S256 | -| PM3EASY512 | Proxmark3 rdv3 Easy with AT91SAM7S512 | -| PM3RDV2 | Proxmark3 rdv2 with AT91SAM7S512 | -| PM3OLD256 | Proxmark3 V1 with AT91SAM7S256 | -| PM3OLD512 | Proxmark3 V1 with AT91SAM7S512 | +| PLATFORM | DESCRIPTION | +|-----------------|--------------------------| +| PM3RDV4 (def) | Proxmark3 rdv4 | +| PM3OTHER | Proxmark3 generic target | By default `PLATFORM=PM3RDV4`. -Note that besides `PM3RDV4` and its unique features, all other platforms are equivalent and the MCU version (256 or 512) will be detected automatically during flashing. +The MCU version (256 or 512) will be detected automatically during flashing. Known issues: From a95a962651b5dfef5a0692c988af4a45ae34f0bf Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 20 Aug 2019 21:30:43 +0200 Subject: [PATCH 0396/1854] OSX instructions: developer mode --- ...OS-X-Homebrew-Installation-Instructions.md | 61 ++++++++++++++++++- 1 file changed, 58 insertions(+), 3 deletions(-) diff --git a/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md b/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md index 34b9c3aa5..22868121c 100644 --- a/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md @@ -1,4 +1,7 @@ -# Homebrew (Mac OS X) +# Homebrew (Mac OS X), automatic installation + +## Install Proxmark3 tools + These instructions comes from @Chrisfu, where we got the proxmark3.rb scriptfile from. For further questions about Mac & Homebrew, contact @Chrisfu (https://github.com/chrisfu/) @@ -8,7 +11,7 @@ For further questions about Mac & Homebrew, contact @Chrisfu (https://github.c 3. Install Proxmark3: `brew install proxmark3` for stable release or `brew install --HEAD proxmark3` for latest non-stable from GitHub. -## Upgrading HomeBrew tap formula +## Upgrade HomeBrew tap formula *This method is useful for those looking to run bleeding-edge versions of RRG/iceman's client. Keep this in mind when attempting to update your HomeBrew tap formula as this procedure could easily cause a build to break if an update is unstable on macOS.* @@ -24,7 +27,7 @@ brew upgrade --fetch-HEAD proxmark3 ## Flash the BOOTROM & FULLIMAGE -With your Proxmark3 unplugged from your machine, press and hold the button on your Proxmark3 as you plug it into a USB port. Continue to hold the button until after this step is complete and the `proxmark3-flasher` command outputs "Have a nice day!" +With your Proxmark3 unplugged from your machine, press and hold the button on your Proxmark3 as you plug it into a USB port. You can release the button, two of the four LEDs should stay on. You're un bootloader mode, ready for the next step. In case the two LEDs don't stay on when you're releasing the button, you've an old bootloader, start over and keep the button pressed during the whole flashing procedure. ```sh sudo proxmark3-flasher /dev/tty.usbmodemiceman1 -b /usr/local/Cellar/proxmark3/HEAD-/share/firmware/bootrom.elf /usr/local/Cellar/proxmark3/HEAD-/share/firmware/fullimage.elf @@ -50,3 +53,55 @@ For the next steps, please read the following pages: * [Commands & Features](/doc/md/Use_of_Proxmark/3_Commands-and-Features.md)| + + +# Homebrew (Mac OS X), developer installation + +These instructions will show how to setup the environment on OSX to the point where you'll be able to clone and compile the repo by yourself, as on Linux, Windows, etc. + +1. Install homebrew if you haven't yet already done so: http://brew.sh/ + +2. Install dependencies: + +``` +brew install readline +brew install p7zip +brew install libusb-compat +brew install perl +brew install qt5 +brew install wget +brew install RfidResearchGroup/proxmark3/arm-none-eabi-gcc +``` + +## Compile and use the project + +Now you're ready to follow the [compilation instructions](/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md). + +To use the compiled client and flasher, the only difference is that the Proxmark3 port is `/dev/tty.usbmodemiceman1`. + +To flash: With your Proxmark3 unplugged from your machine, press and hold the button on your Proxmark3 as you plug it into a USB port. You can release the button, two of the four LEDs should stay on. You're un bootloader mode, ready for the next step. In case the two LEDs don't stay on when you're releasing the button, you've an old bootloader, start over and keep the button pressed during the whole flashing procedure. + +In principle, the helper script `flash-all.sh` should auto-detect your port, so you can just try: + +```sh +./flash-all.sh +``` + +If port detection failed, you'll have to call the flasher manually and specify the correct port: + +```sh +client/flasher /dev/tty.usbmodemiceman1 -b bootrom/obj/bootrom.elf armsrc/obj/fullimage.elf +``` + +Similarly, to run the client, you may try: + +```sh +./proxmark3.sh +``` + +Or, by specifying the port manually: + +```sh +client/proxmark3 /dev/tty.usbmodemiceman1 +``` + From e4222968555c426349a908d174b8dcf5db8e7345 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 21 Aug 2019 20:38:56 +0200 Subject: [PATCH 0397/1854] removed install.sh, better to stick to the install docs --- install.sh | 68 ------------------------------------------------------ 1 file changed, 68 deletions(-) delete mode 100755 install.sh diff --git a/install.sh b/install.sh deleted file mode 100755 index 8dc3e5317..000000000 --- a/install.sh +++ /dev/null @@ -1,68 +0,0 @@ -#!/bin/bash -set -x -# This is for linux ppl and it works on Ubuntu distros. Don't know about Kali. -function installProxmark_Linux { - # install dependencies for Proxmark3 source code. - sudo apt-get install p7zip git build-essential libreadline5 libreadline-dev gcc-arm-none-eabi - sudo apt-get install libusb-0.1-4 libusb-dev libqt4-dev libncurses5-dev perl pkg-config wget - #cleaning up - sudo apt-get install -f -y - sudo apt-get autoremove -y - sudo apt-get autoclean -y - sudo apt-get clean -y - sudo apt-get update - - # Install libcanberragtk in Ubuntu 18.04 - if [[ $(cat /etc/issue | awk '{print $2}') = *"18.04"* ]]; then - apt-get install libcanberra-gtk-module - fi - -# install RDV40 - proxmark3 - git clone https://github.com/RfidResearchGroup/proxmark3.git . - ( - cd proxmark3 || exit 1 - git reset --hard - git clean -dfx - make clean - make -j$(nproc) all - # Copy blacklist rules into /etc/udev/rules.d - # check the Makefile for details - sudo make udev - ) -} -function installProxmark_macOS { - # Install dependencies for Proxmark3 source code. - brew tap nitsky/stm32 - brew install readline libusb p7zip libusb-compat wget qt5 pkgconfig arm-none-eabi-gcc - brew link --force readline - # add moc_location in Qt5Core.pc file. -local qtDir=$(ls /usr/local/Cellar/qt/ 2>/dev/null | head -1) -local qt5Core=$(find /usr -name Qt5Core.pc 2>/dev/null) - ( - export PKG_CONFIG_PATH=/usr/local/Cellar/qt/$qtDir/lib/pkgconfig/ - export QT_PKG_CONFIG_QT5CORE=$qt5Core - chmod 666 $QT_PKG_CONFIG_QT5CORE - echo "moc_location=\${prefix}/bin/moc" >> $QT_PKG_CONFIG_QT5CORE - chmod 444 $QT_PKG_CONFIG_QT5CORE - ) - # install RDV40 - proxmark3 - git clone https://github.com/RfidResearchGroup/proxmark3.git - ( - cd proxmark3 || exit 1 - git reset --hard - git clean -dfx - make clean - make -j$(sysctl -n hw.physicalcpu) - ) - } -# Where is my device? -#dmesg | tail -10 -# Detect OS and install libraries and proxmark3 client -if [[ $(uname | awk '{print toupper($0)}') == "LINUX" ]]; then - echo >&2 "Linux Detected - Updating your system..." - $(installProxmark_Linux) -elif [[ $(uname | awk '{print toupper($0)}') == "DARWIN" ]]; then - echo >&2 "MAC OS X Detected - Updating your system..." - $(installProxmark_macOS) 2>/dev/null -fi -echo >&2 "Done." From 1e97acdf5e8ec5c1c903d88c2037c189ebc9bbe4 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 21 Aug 2019 21:39:21 +0200 Subject: [PATCH 0398/1854] remove old arm toolchain installation script --- tools/install-gnuarm4.sh | 277 --------------------------------------- 1 file changed, 277 deletions(-) delete mode 100755 tools/install-gnuarm4.sh diff --git a/tools/install-gnuarm4.sh b/tools/install-gnuarm4.sh deleted file mode 100755 index a5d92c5d5..000000000 --- a/tools/install-gnuarm4.sh +++ /dev/null @@ -1,277 +0,0 @@ -#!/bin/bash - -# Some things for you to configure -BINUTILS_VER="2.19.1a" -GCC_VER="4.3.3" -GDB_VER="6.8a" -NEWLIB_VER="1.17.0" -GMP_VER="4.2.4" -MPFR_VER="2.4.2" -INSIGHT_VER="6.8a" - -# Where you want to install the tools -if [ "${1}" = "" ]; then - echo "Syntax: ${0} [download & build directory (default ${PWD})]" - exit 1 -else - DESTDIR="${1}" -fi - -# Where do you want to build the tools. This is where the log files -# will be written (which you can monitor with 'tail' during compilation). -# You can delete this directory after everything is done. -if [ ! "${2}" = "" ]; then - SRCDIR="${2}" -else - SRCDIR="${PWD}" -fi -BUILDDIR=${SRCDIR}/build-gnuarm4 - -# Where to get each of the toolchain components -BINUTILS=http://ftp.gnu.org/gnu/binutils/binutils-${BINUTILS_VER}.tar.bz2 -BINUTILS_TAR=binutils-${BINUTILS_VER}.tar.bz2 -GCCCORE=http://ftp.gnu.org/gnu/gcc/gcc-${GCC_VER}/gcc-core-${GCC_VER}.tar.bz2 -GCCCORE_TAR=gcc-core-${GCC_VER}.tar.bz2 -GPP=http://ftp.gnu.org/gnu/gcc/gcc-${GCC_VER}/gcc-g++-${GCC_VER}.tar.bz2 -GPP_TAR=gcc-g++-${GCC_VER}.tar.bz2 -NEWLIB=ftp://sources.redhat.com/pub/newlib/newlib-${NEWLIB_VER}.tar.gz -NEWLIB_TAR=newlib-${NEWLIB_VER}.tar.gz -#INSIGHT=ftp://sourceware.org/pub/insight/releases/insight-${INSIGHT_VER}.tar.bz2 -INSIGHT=http://mirrors.kernel.org/sources.redhat.com/insight/releases/insight-${INSIGHT_VER}.tar.bz2 -INSIGHT_TAR=insight-${INSIGHT_VER}.tar.bz2 -#INSIGHT=http://www.mirrorservice.org/sites/sources.redhat.com/pub/insight/releases/insight-${INSIGHT_VER}.tar.bz2 -GDB=http://ftp.gnu.org/gnu/gdb/gdb-${GDB_VER}.tar.bz2 -GDB_TAR=gdb-${GDB_VER}.tar.bz2 -GMP=http://ftp.sunet.se/pub/gnu/gmp/gmp-${GMP_VER}.tar.bz2 -GMP_TAR=gmp-${GMP_VER}.tar.bz2 -MPFR=http://ftp.gnu.org/gnu/mpfr/mpfr-${MPFR_VER}.tar.bz2 -MPFR_TAR=mpfr-${MPFR_VER}.tar.bz2 -GNU_KEYRING_GPG=gnu-keyring.gpg -GNU_KEYRING=ftp://ftp.gnu.org/gnu/${GNU_KEYRING_GPG} - -# Common configuration options (i.e., things to pass to 'configure') -COMMON_CFG="--enable-interwork --target=arm-eabi --program-prefix=arm-none-eabi- --prefix=${DESTDIR} --disable-werror --enable-languages=c,c++ --enable-multilib --disable-shared" - -# Extra configuration options for each toolchain component -BINUTILS_CFG= -GCCCORE_CFG="--disable-nls --disable-threads --with-gcc --with-gnu-ld --with-gnu-as --with-dwarf2 --with-newlib --with-headers=${BUILDDIR}/newlib-${NEWLIB_VER}/newlib/libc/include --disable-libssp --disable-libstdcxx-pch --disable-libmudflap --disable-libgomp -v" -NEWLIB_CFG= -INSIGHT_CFG= -GDB_CFG= - -# Make flags -MAKEFLAGS="-j 4" - -# wget options -# -nv: non-verbose but not too quiet (still print errors/warnings) -# -nc: no-clobber, do not download a file that already exists -# -t 0: retry indefinitely -# -a wget.log: append errors/warnings to wget.log file -# -c continue -#WGET_OPTS="-nv -nc -t 0 -a wget.log" -WGET_OPTS="-c -t 0" - -# Compiler flags for compiling Newlib (-O2 is already hard-coded) -NEWLIB_FLAGS="-march=armv4t -mcpu=arm7tdmi -g" - -# GPG options to avoid polluting the user's keyring -GPG_OPTS="--keyring ${GNU_KEYRING_GPG} --no-default-keyring --homedir ." - -############################################################################ -# End of configuration section. You shouldn't have to modify anything below. -############################################################################ - -if [[ "$USER" != "root" ]]; then - echo "*** Warning! Not running as root!" - echo "Installation may fail if you do not have appropriate permissions!" -fi - -mkdir -p ${BUILDDIR} -cd ${SRCDIR} - -if [[ -f all.downloaded ]]; then - echo Looks like all downloads are complete, skipping downloads -else - wget ${WGET_OPTS} ${GNU_KEYRING} - - # TODO: guess it's better to have a function that "downloads, checks file-presence and signature, and returns true/false" whether the file is ok - # Function will check if file exists (otherwise try to download the file - if failed and file still doesn't exist, complain and exit the script) - # Check if signature file exists (otherwise download the signature file as well - if download fail, warn the user and return function) - # Check the signature. If failed, backup-by-renaming current files, redownload both file & signature, run the function body one more time - if still no success, warn and return from function - - function download_lib { - echo Now downloading $1 - wget ${WGET_OPTS} $2 - } - - function download_signed_lib { - download_lib $1 $2 - wget -N ${WGET_OPTS} $2.sig - gpg $GPG_OPTS --verify $3.sig 2> /dev/null - if [[ $? != 0 ]]; then - echo "Failed signature check for:" $3.sig - exit 1 - fi - } - - # NOTE: If new downloads are added here, please see the IMPORTANT note below - download_signed_lib BINUTILS ${BINUTILS} ${BINUTILS_TAR} || exit 1 - download_signed_lib GCC ${GCCCORE} ${GCCCORE_TAR} || exit 1 - download_signed_lib G++ ${GPP} ${GPP_TAR} || exit 1 - download_lib NEWLIB ${NEWLIB} - # TODO: signature/hash check - download_lib INSIGHT ${INSIGHT} - # TODO: signature/hash check - download_signed_lib GDB ${GDB} ${GDB_TAR} || exit 1 - download_signed_lib GMP ${GMP} ${GMP_TAR} || exit 1 - download_signed_lib MPFR ${MPFR} ${MPFR_TAR} || exit 1 - - # IMPORTANT: Here is the number of .tar. archives downloaded above. Please update if new .tar. are added to download list. - if [[ `ls -1 *.tar.bz2 *.tar.gz | wc -l` != 8 ]]; then - echo "Seems like not all prerequisite files downloaded... Exiting." - exit 1 - else - touch all.downloaded - fi -fi - -cd ${BUILDDIR} -if [[ -f binutils.built ]]; then - echo Looks like BINUTILS was already built. -else - echo Building BINUTILS... - tar -xjf ../`basename ${BINUTILS}` - echo ___________________ > make.log - echo Building binutils... >> make.log - cd `find . -maxdepth 1 -type d -name 'binutils*'` - mkdir gnuarm - cd gnuarm - ../configure ${COMMON_CFG} ${BINUTILS_CFG} >> ../../make.log 2>&1 - make ${MAKEFLAGS} MAKEINFO=`which makeinfo` >> ../../make.log 2>&1 - make install >> ../../make.log 2>&1 - cd ../.. - touch binutils.built -fi - - echo ___________________ >> make.log - echo Adding ${DESTDIR}/bin to PATH >> make.log -export PATH; PATH=${DESTDIR}/bin:$PATH - echo ___________________ >> make.log - -if [[ -f gcc.built ]]; then - echo Looks like GCC was already built. -else - echo Building GCC... - tar -xjf ../`basename ${GCCCORE}` - tar -xjf ../`basename ${GPP}` - tar -xjf ../`basename ${GMP}` - ln -s "${BUILDDIR}/gmp-${GMP_VER}" "${BUILDDIR}/gcc-${GCC_VER}/gmp" - tar -xjf ../`basename ${MPFR}` - ln -s "${BUILDDIR}/mpfr-${MPFR_VER}" "${BUILDDIR}/gcc-${GCC_VER}/mpfr" - tar -xzf ../`basename ${NEWLIB}` - - echo ___________________ >> make.log - -cat << EOF > gcc.patch ---- gcc-4.3.3.orig/gcc/config/arm/t-arm-elf -+++ gcc-4.3.3.mod/gcc/config/arm/t-arm-elf -@@ -33,8 +33,8 @@ - # MULTILIB_DIRNAMES += fpu soft - # MULTILIB_EXCEPTIONS += *mthumb/*mhard-float* - # --# MULTILIB_OPTIONS += mno-thumb-interwork/mthumb-interwork --# MULTILIB_DIRNAMES += normal interwork -+MULTILIB_OPTIONS += mno-thumb-interwork/mthumb-interwork -+MULTILIB_DIRNAMES += normal interwork - # - # MULTILIB_OPTIONS += fno-leading-underscore/fleading-underscore - # MULTILIB_DIRNAMES += elf under -EOF - - echo Patching GCC >> make.log - cd `find . -maxdepth 1 -type d -name 'gcc*'` - patch -p1 < ../gcc.patch - echo Building gcc... >> make.log - mkdir gnuarm - cd gnuarm - ../configure ${COMMON_CFG} ${GCCCORE_CFG} >> ../../make.log 2>&1 - make ${MAKEFLAGS} all-gcc >> ../../make.log 2>&1 - make install >> ../../make.log 2>&1 - cd ../.. - touch gcc.built -fi - -if [[ -f newlib.built ]]; then - echo Looks like NEWLIB was already built. -else - echo Building NEWLIB... - echo ___________________ >> make.log - echo Building newlib... >> make.log - cd `find . -maxdepth 1 -type d -name 'newlib*'` - mkdir gnuarm - cd gnuarm - ../configure ${COMMON_CFG} ${NEWLIB_CFG} >> ../../make.log 2>&1 - - # This line adds our NEWLIB_CFLAGS to the configure.host file in the - # newlib subdirectory. This is the only way I could find to tell Newlib to - # compile itself with the -mmarch=armv4t and -mcpu=arm7tdmi flags. -# sed -i "/^newlib_cflags=/s/=.*\$/=\"${NEWLIB_FLAGS}\"/" ../newlib/configure.host - make ${MAKEFLAGS} >> ../../make.log 2>&1 - make install >> ../../make.log 2>&1 - cd ../.. - touch newlib.built -fi - - echo ___________________ >> make.log - echo "Now that newlib is built, second pass for GCC..." >> make.log - cd `find . -maxdepth 1 -type d -name 'gcc*'` - cd gnuarm - make ${MAKEFLAGS} >> ../../make.log 2>&1 - make install >> ../../make.log 2>&1 - cd ../.. - - -if [[ -f insight.built ]]; then - echo Looks like INSIGHT was already built. -else - echo Building INSIGHT... - tar -xjf ../`basename ${INSIGHT}` - echo ___________________ >> make.log - echo Building insight... >> make.log - cd `find . -maxdepth 1 -type d -name 'insight*'` - mkdir gnuarm - cd gnuarm - ../configure ${COMMON_CFG} ${INSIGHT_CFG} >> ../../make.log 2>&1 - make ${MAKEFLAGS} >> ../../make.log 2>&1 - make install >> ../../make.log 2>&1 - cd ../.. - touch insight.built -fi - -if [[ -f gdb.built ]]; then - echo Looks like GDB was already built. -else - echo Building GDB... - tar -xjf ../`basename ${GDB}` - echo ___________________ >> make.log - echo Building insight... >> make.log - cd `find . -maxdepth 1 -type d -name 'gdb*'` - mkdir gnuarm - cd gnuarm - ../configure ${COMMON_CFG} ${GDB_CFG} >> ../../make.log 2>&1 - make ${MAKEFLAGS} >> ../../make.log 2>&1 - make install >> ../../make.log 2>&1 - cd ../.. - touch gdb.built -fi - -echo ___________________ >> make.log -echo Build complete. >> make.log - -cd ${DESTDIR} -chmod -R a+rX . - -echo Downloaded archives are in ${SRCDIR} -echo build driectory: ${BUILDDIR} -echo set environment variable ARMLIB to ${DESTDIR}/lib/gcc/arm-eabi/4.3.3/interwork for Makefile.linux -exit 0 From fb006909576ea4ad6f25cc326623e4c6aba50d82 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 21 Aug 2019 22:44:28 +0200 Subject: [PATCH 0399/1854] rename and +x few eml helper scripts --- client/{eml2lower.sh => pm3_eml2lower.sh} | 2 +- client/{eml2UPPER.sh => pm3_eml2upper.sh} | 2 +- client/pm3_mfdread.py | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename client/{eml2lower.sh => pm3_eml2lower.sh} (97%) mode change 100644 => 100755 rename client/{eml2UPPER.sh => pm3_eml2upper.sh} (97%) mode change 100644 => 100755 mode change 100644 => 100755 client/pm3_mfdread.py diff --git a/client/eml2lower.sh b/client/pm3_eml2lower.sh old mode 100644 new mode 100755 similarity index 97% rename from client/eml2lower.sh rename to client/pm3_eml2lower.sh index ddb3354db..086439c3c --- a/client/eml2lower.sh +++ b/client/pm3_eml2lower.sh @@ -1,7 +1,7 @@ #!/bin/bash # Andrei Costin , 2011 -# eml2lower.sh +# pm3_eml2lower.sh # Converts PM3 Mifare Classic emulator EML file to lower case (for easier comparison in some text-comparison tools) # http://www.linuxquestions.org/questions/programming-9/bash-script-parsing-optional-parameters-621728/ diff --git a/client/eml2UPPER.sh b/client/pm3_eml2upper.sh old mode 100644 new mode 100755 similarity index 97% rename from client/eml2UPPER.sh rename to client/pm3_eml2upper.sh index a28ae22a0..73b8646b7 --- a/client/eml2UPPER.sh +++ b/client/pm3_eml2upper.sh @@ -1,7 +1,7 @@ #!/bin/bash # Andrei Costin , 2011 -# eml2UPPER.sh +# pm3_eml2upper.sh # Converts PM3 Mifare Classic emulator EML file to UPPER case (for easier comparison in some text-comparison tools) # http://www.linuxquestions.org/questions/programming-9/bash-script-parsing-optional-parameters-621728/ diff --git a/client/pm3_mfdread.py b/client/pm3_mfdread.py old mode 100644 new mode 100755 From a8ee33baf4138141e76645cfe95c25d0698595f6 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 21 Aug 2019 23:17:01 +0200 Subject: [PATCH 0400/1854] change scripts/ to luascripts/ --- appveyor.yml | 4 ++-- client/cmdhfmfp.c | 2 +- client/cmdscript.c | 4 ++-- client/{scripts => luascripts}/14araw.lua | 0 client/{scripts => luascripts}/Legic_clone.lua | 0 client/{scripts => luascripts}/amiibo.lua | 0 client/{scripts => luascripts}/brutesim.lua | 0 client/{scripts => luascripts}/calc_di.lua | 0 client/{scripts => luascripts}/calc_ev1_it.lua | 0 client/{scripts => luascripts}/calc_mizip.lua | 0 client/{scripts => luascripts}/calypso.lua | 0 client/{scripts => luascripts}/cmdline.lua | 0 client/{scripts => luascripts}/didump.lua | 0 client/{scripts => luascripts}/dumptoemul-mfu.lua | 0 client/{scripts => luascripts}/dumptoemul.lua | 0 client/{scripts => luascripts}/e.lua | 0 client/{scripts => luascripts}/emul2dump.lua | 0 client/{scripts => luascripts}/emul2html.lua | 0 client/{scripts => luascripts}/formatMifare.lua | 0 client/{scripts => luascripts}/hf_read.lua | 0 client/{scripts => luascripts}/htmldump.lua | 0 client/{scripts => luascripts}/iso15_magic.lua | 0 client/{scripts => luascripts}/legic.lua | 0 client/{scripts => luascripts}/legic_buffer2card.lua | 0 client/{scripts => luascripts}/lf_bulk.lua | 0 client/{scripts => luascripts}/mfkeys.lua | 0 client/{scripts => luascripts}/mifare_access.lua | 0 client/{scripts => luascripts}/mifare_autopwn.lua | 0 client/{scripts => luascripts}/mifareplus.lua | 0 client/{scripts => luascripts}/ndef_dump.lua | 0 client/{scripts => luascripts}/ntag_3d.lua | 2 +- client/{scripts => luascripts}/parameters.lua | 0 client/{scripts => luascripts}/read_pwd_mem.lua | 0 client/{scripts => luascripts}/remagic.lua | 0 client/{scripts => luascripts}/test_t55x7.lua | 0 client/{scripts => luascripts}/test_t55x7_ask.lua | 0 client/{scripts => luascripts}/test_t55x7_bi.lua | 0 client/{scripts => luascripts}/test_t55x7_fsk.lua | 0 client/{scripts => luascripts}/test_t55x7_psk.lua | 0 client/{scripts => luascripts}/tnp3clone.lua | 0 client/{scripts => luascripts}/tnp3dump.lua | 0 client/{scripts => luascripts}/tnp3sim.lua | 0 client/{scripts => luascripts}/tracetest.lua | 0 client/{scripts => luascripts}/ufodump.lua | 0 client/{scripts => luascripts}/ul_uid.lua | 0 client/scripting.c | 2 +- client/scripting.h | 2 +- 47 files changed, 8 insertions(+), 8 deletions(-) rename client/{scripts => luascripts}/14araw.lua (100%) rename client/{scripts => luascripts}/Legic_clone.lua (100%) rename client/{scripts => luascripts}/amiibo.lua (100%) rename client/{scripts => luascripts}/brutesim.lua (100%) rename client/{scripts => luascripts}/calc_di.lua (100%) rename client/{scripts => luascripts}/calc_ev1_it.lua (100%) rename client/{scripts => luascripts}/calc_mizip.lua (100%) rename client/{scripts => luascripts}/calypso.lua (100%) rename client/{scripts => luascripts}/cmdline.lua (100%) rename client/{scripts => luascripts}/didump.lua (100%) rename client/{scripts => luascripts}/dumptoemul-mfu.lua (100%) rename client/{scripts => luascripts}/dumptoemul.lua (100%) rename client/{scripts => luascripts}/e.lua (100%) rename client/{scripts => luascripts}/emul2dump.lua (100%) rename client/{scripts => luascripts}/emul2html.lua (100%) rename client/{scripts => luascripts}/formatMifare.lua (100%) rename client/{scripts => luascripts}/hf_read.lua (100%) rename client/{scripts => luascripts}/htmldump.lua (100%) rename client/{scripts => luascripts}/iso15_magic.lua (100%) rename client/{scripts => luascripts}/legic.lua (100%) rename client/{scripts => luascripts}/legic_buffer2card.lua (100%) rename client/{scripts => luascripts}/lf_bulk.lua (100%) rename client/{scripts => luascripts}/mfkeys.lua (100%) rename client/{scripts => luascripts}/mifare_access.lua (100%) rename client/{scripts => luascripts}/mifare_autopwn.lua (100%) rename client/{scripts => luascripts}/mifareplus.lua (100%) rename client/{scripts => luascripts}/ndef_dump.lua (100%) rename client/{scripts => luascripts}/ntag_3d.lua (99%) rename client/{scripts => luascripts}/parameters.lua (100%) rename client/{scripts => luascripts}/read_pwd_mem.lua (100%) rename client/{scripts => luascripts}/remagic.lua (100%) rename client/{scripts => luascripts}/test_t55x7.lua (100%) rename client/{scripts => luascripts}/test_t55x7_ask.lua (100%) rename client/{scripts => luascripts}/test_t55x7_bi.lua (100%) rename client/{scripts => luascripts}/test_t55x7_fsk.lua (100%) rename client/{scripts => luascripts}/test_t55x7_psk.lua (100%) rename client/{scripts => luascripts}/tnp3clone.lua (100%) rename client/{scripts => luascripts}/tnp3dump.lua (100%) rename client/{scripts => luascripts}/tnp3sim.lua (100%) rename client/{scripts => luascripts}/tracetest.lua (100%) rename client/{scripts => luascripts}/ufodump.lua (100%) rename client/{scripts => luascripts}/ul_uid.lua (100%) diff --git a/appveyor.yml b/appveyor.yml index a1276ca1e..a0c261b2b 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -151,9 +151,9 @@ build_script: Copy-Item C:\ProxSpace\pm3\bootrom\obj\*.elf C:\ProxSpace\Release\arm - New-Item -ItemType Directory -Force -Path C:\ProxSpace\Release\scripts + New-Item -ItemType Directory -Force -Path C:\ProxSpace\Release\luascripts - Copy-Item C:\ProxSpace\pm3\client\scripts\*.lua C:\ProxSpace\Release\scripts + Copy-Item C:\ProxSpace\pm3\client\luascripts\*.lua C:\ProxSpace\Release\luascripts New-Item -ItemType Directory -Force -Path C:\ProxSpace\Release\hardnested\tables diff --git a/client/cmdhfmfp.c b/client/cmdhfmfp.c index 8c7cfcc5c..58eb5db1a 100644 --- a/client/cmdhfmfp.c +++ b/client/cmdhfmfp.c @@ -86,7 +86,7 @@ static int CmdHFMFPInfo(const char *cmd) { // check SL0 uint8_t data[250] = {0}; int datalen = 0; - // https://github.com/Proxmark/proxmark3/blob/master/client/scripts/mifarePlus.lua#L161 + // https://github.com/Proxmark/proxmark3/blob/master/client/luascripts/mifarePlus.lua#L161 uint8_t cmd[3 + 16] = {0xa8, 0x90, 0x90, 0x00}; int res = ExchangeRAW14a(cmd, sizeof(cmd), false, false, data, sizeof(data), &datalen); if (!res && datalen > 1 && data[0] == 0x09) { diff --git a/client/cmdscript.c b/client/cmdscript.c index 28dd8608f..16539b020 100644 --- a/client/cmdscript.c +++ b/client/cmdscript.c @@ -77,7 +77,7 @@ static int CmdScriptList(const char *Cmd) { n = scandir(script_directory_path, &namelist, NULL, alphasort); if (n == -1) { - PrintAndLogEx(FAILED, "Couldn't open the scripts-directory"); + PrintAndLogEx(FAILED, "Couldn't open the luascripts-directory"); return 1; } @@ -175,7 +175,7 @@ static command_t CommandTable[] = { */ static int CmdHelp(const char *Cmd) { (void)Cmd; // Cmd is not used so far - PrintAndLogEx(NORMAL, "This is a feature to run Lua-scripts. You can place lua-scripts within the scripts/-folder. "); + PrintAndLogEx(NORMAL, "This is a feature to run Lua-scripts. You can place Lua-scripts within the luascripts/-folder. "); return 0; } diff --git a/client/scripts/14araw.lua b/client/luascripts/14araw.lua similarity index 100% rename from client/scripts/14araw.lua rename to client/luascripts/14araw.lua diff --git a/client/scripts/Legic_clone.lua b/client/luascripts/Legic_clone.lua similarity index 100% rename from client/scripts/Legic_clone.lua rename to client/luascripts/Legic_clone.lua diff --git a/client/scripts/amiibo.lua b/client/luascripts/amiibo.lua similarity index 100% rename from client/scripts/amiibo.lua rename to client/luascripts/amiibo.lua diff --git a/client/scripts/brutesim.lua b/client/luascripts/brutesim.lua similarity index 100% rename from client/scripts/brutesim.lua rename to client/luascripts/brutesim.lua diff --git a/client/scripts/calc_di.lua b/client/luascripts/calc_di.lua similarity index 100% rename from client/scripts/calc_di.lua rename to client/luascripts/calc_di.lua diff --git a/client/scripts/calc_ev1_it.lua b/client/luascripts/calc_ev1_it.lua similarity index 100% rename from client/scripts/calc_ev1_it.lua rename to client/luascripts/calc_ev1_it.lua diff --git a/client/scripts/calc_mizip.lua b/client/luascripts/calc_mizip.lua similarity index 100% rename from client/scripts/calc_mizip.lua rename to client/luascripts/calc_mizip.lua diff --git a/client/scripts/calypso.lua b/client/luascripts/calypso.lua similarity index 100% rename from client/scripts/calypso.lua rename to client/luascripts/calypso.lua diff --git a/client/scripts/cmdline.lua b/client/luascripts/cmdline.lua similarity index 100% rename from client/scripts/cmdline.lua rename to client/luascripts/cmdline.lua diff --git a/client/scripts/didump.lua b/client/luascripts/didump.lua similarity index 100% rename from client/scripts/didump.lua rename to client/luascripts/didump.lua diff --git a/client/scripts/dumptoemul-mfu.lua b/client/luascripts/dumptoemul-mfu.lua similarity index 100% rename from client/scripts/dumptoemul-mfu.lua rename to client/luascripts/dumptoemul-mfu.lua diff --git a/client/scripts/dumptoemul.lua b/client/luascripts/dumptoemul.lua similarity index 100% rename from client/scripts/dumptoemul.lua rename to client/luascripts/dumptoemul.lua diff --git a/client/scripts/e.lua b/client/luascripts/e.lua similarity index 100% rename from client/scripts/e.lua rename to client/luascripts/e.lua diff --git a/client/scripts/emul2dump.lua b/client/luascripts/emul2dump.lua similarity index 100% rename from client/scripts/emul2dump.lua rename to client/luascripts/emul2dump.lua diff --git a/client/scripts/emul2html.lua b/client/luascripts/emul2html.lua similarity index 100% rename from client/scripts/emul2html.lua rename to client/luascripts/emul2html.lua diff --git a/client/scripts/formatMifare.lua b/client/luascripts/formatMifare.lua similarity index 100% rename from client/scripts/formatMifare.lua rename to client/luascripts/formatMifare.lua diff --git a/client/scripts/hf_read.lua b/client/luascripts/hf_read.lua similarity index 100% rename from client/scripts/hf_read.lua rename to client/luascripts/hf_read.lua diff --git a/client/scripts/htmldump.lua b/client/luascripts/htmldump.lua similarity index 100% rename from client/scripts/htmldump.lua rename to client/luascripts/htmldump.lua diff --git a/client/scripts/iso15_magic.lua b/client/luascripts/iso15_magic.lua similarity index 100% rename from client/scripts/iso15_magic.lua rename to client/luascripts/iso15_magic.lua diff --git a/client/scripts/legic.lua b/client/luascripts/legic.lua similarity index 100% rename from client/scripts/legic.lua rename to client/luascripts/legic.lua diff --git a/client/scripts/legic_buffer2card.lua b/client/luascripts/legic_buffer2card.lua similarity index 100% rename from client/scripts/legic_buffer2card.lua rename to client/luascripts/legic_buffer2card.lua diff --git a/client/scripts/lf_bulk.lua b/client/luascripts/lf_bulk.lua similarity index 100% rename from client/scripts/lf_bulk.lua rename to client/luascripts/lf_bulk.lua diff --git a/client/scripts/mfkeys.lua b/client/luascripts/mfkeys.lua similarity index 100% rename from client/scripts/mfkeys.lua rename to client/luascripts/mfkeys.lua diff --git a/client/scripts/mifare_access.lua b/client/luascripts/mifare_access.lua similarity index 100% rename from client/scripts/mifare_access.lua rename to client/luascripts/mifare_access.lua diff --git a/client/scripts/mifare_autopwn.lua b/client/luascripts/mifare_autopwn.lua similarity index 100% rename from client/scripts/mifare_autopwn.lua rename to client/luascripts/mifare_autopwn.lua diff --git a/client/scripts/mifareplus.lua b/client/luascripts/mifareplus.lua similarity index 100% rename from client/scripts/mifareplus.lua rename to client/luascripts/mifareplus.lua diff --git a/client/scripts/ndef_dump.lua b/client/luascripts/ndef_dump.lua similarity index 100% rename from client/scripts/ndef_dump.lua rename to client/luascripts/ndef_dump.lua diff --git a/client/scripts/ntag_3d.lua b/client/luascripts/ntag_3d.lua similarity index 99% rename from client/scripts/ntag_3d.lua rename to client/luascripts/ntag_3d.lua index ff2c68d0f..869590cf2 100644 --- a/client/scripts/ntag_3d.lua +++ b/client/luascripts/ntag_3d.lua @@ -223,7 +223,7 @@ local function configure_magic_ntag(uid) -- -p == set pwd -- -a == set pack args =('-t 12 -u %s -p %08X -a %04X'):format(uid, pwd, pack) - require('../scripts/mfu_magic') + require('mfu_magic') -- Set back args. Not that it's used, just for the karma... args = myargs diff --git a/client/scripts/parameters.lua b/client/luascripts/parameters.lua similarity index 100% rename from client/scripts/parameters.lua rename to client/luascripts/parameters.lua diff --git a/client/scripts/read_pwd_mem.lua b/client/luascripts/read_pwd_mem.lua similarity index 100% rename from client/scripts/read_pwd_mem.lua rename to client/luascripts/read_pwd_mem.lua diff --git a/client/scripts/remagic.lua b/client/luascripts/remagic.lua similarity index 100% rename from client/scripts/remagic.lua rename to client/luascripts/remagic.lua diff --git a/client/scripts/test_t55x7.lua b/client/luascripts/test_t55x7.lua similarity index 100% rename from client/scripts/test_t55x7.lua rename to client/luascripts/test_t55x7.lua diff --git a/client/scripts/test_t55x7_ask.lua b/client/luascripts/test_t55x7_ask.lua similarity index 100% rename from client/scripts/test_t55x7_ask.lua rename to client/luascripts/test_t55x7_ask.lua diff --git a/client/scripts/test_t55x7_bi.lua b/client/luascripts/test_t55x7_bi.lua similarity index 100% rename from client/scripts/test_t55x7_bi.lua rename to client/luascripts/test_t55x7_bi.lua diff --git a/client/scripts/test_t55x7_fsk.lua b/client/luascripts/test_t55x7_fsk.lua similarity index 100% rename from client/scripts/test_t55x7_fsk.lua rename to client/luascripts/test_t55x7_fsk.lua diff --git a/client/scripts/test_t55x7_psk.lua b/client/luascripts/test_t55x7_psk.lua similarity index 100% rename from client/scripts/test_t55x7_psk.lua rename to client/luascripts/test_t55x7_psk.lua diff --git a/client/scripts/tnp3clone.lua b/client/luascripts/tnp3clone.lua similarity index 100% rename from client/scripts/tnp3clone.lua rename to client/luascripts/tnp3clone.lua diff --git a/client/scripts/tnp3dump.lua b/client/luascripts/tnp3dump.lua similarity index 100% rename from client/scripts/tnp3dump.lua rename to client/luascripts/tnp3dump.lua diff --git a/client/scripts/tnp3sim.lua b/client/luascripts/tnp3sim.lua similarity index 100% rename from client/scripts/tnp3sim.lua rename to client/luascripts/tnp3sim.lua diff --git a/client/scripts/tracetest.lua b/client/luascripts/tracetest.lua similarity index 100% rename from client/scripts/tracetest.lua rename to client/luascripts/tracetest.lua diff --git a/client/scripts/ufodump.lua b/client/luascripts/ufodump.lua similarity index 100% rename from client/scripts/ufodump.lua rename to client/luascripts/ufodump.lua diff --git a/client/scripts/ul_uid.lua b/client/luascripts/ul_uid.lua similarity index 100% rename from client/scripts/ul_uid.lua rename to client/luascripts/ul_uid.lua diff --git a/client/scripting.c b/client/scripting.c index 429d96fac..f090efbd7 100644 --- a/client/scripting.c +++ b/client/scripting.c @@ -1133,7 +1133,7 @@ int set_pm3_libraries(lua_State *L) { //--add to the LUA_PATH (package.path in lua) - // so we can load scripts from the ./scripts/ - directory + // so we can load scripts from the ./luascripts/ - directory char scripts_path[strlen(get_my_executable_directory()) + strlen(LUA_SCRIPTS_DIRECTORY) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; strcpy(scripts_path, get_my_executable_directory()); strcat(scripts_path, LUA_SCRIPTS_DIRECTORY); diff --git a/client/scripting.h b/client/scripting.h index 07b07aa67..1a7b5a7e3 100644 --- a/client/scripting.h +++ b/client/scripting.h @@ -15,7 +15,7 @@ //#include #define LUA_LIBRARIES_DIRECTORY "lualibs/" -#define LUA_SCRIPTS_DIRECTORY "scripts/" +#define LUA_SCRIPTS_DIRECTORY "luascripts/" #define LUA_LIBRARIES_WILDCARD "?.lua" /** From 3c6500a1b2b8589478256cafbf06664d2a436646 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 21 Aug 2019 23:50:41 +0200 Subject: [PATCH 0401/1854] Lua: look for scripts also in ~/.proxmark/{luascripts,lualibs} and /usr/local/share/proxmark3/... --- CHANGELOG.md | 3 +++ client/scripting.c | 63 ++++++++++++++++++++++++++++++++++------------ client/scripting.h | 2 ++ 3 files changed, 52 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b8d19d065..b8434cc84 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,9 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + + - Add Lua paths: look for scripts also in ~/.proxmark/lua{scripts,libs} and /usr/local/share/proxmark3/lua{scripts,libs} (@doegox) + - Change Lua directory scripts/ to luascript/ (@doegox) - Change non-rdv4 PLATFORM must now use the generic PM3OTHER, simpler (@doegox) - Fix reveng integration for all platforms else than WIN32 (@doegox) - Add cheat sheet for easy operations of the Proxmark3 (scund00r) diff --git a/client/scripting.c b/client/scripting.c index f090efbd7..54ed2aa2c 100644 --- a/client/scripting.c +++ b/client/scripting.c @@ -1131,21 +1131,52 @@ int set_pm3_libraries(lua_State *L) { //-- remove the global environment table from the stack lua_pop(L, 1); - //--add to the LUA_PATH (package.path in lua) - // so we can load scripts from the ./luascripts/ - directory - char scripts_path[strlen(get_my_executable_directory()) + strlen(LUA_SCRIPTS_DIRECTORY) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; - strcpy(scripts_path, get_my_executable_directory()); - strcat(scripts_path, LUA_SCRIPTS_DIRECTORY); - strcat(scripts_path, LUA_LIBRARIES_WILDCARD); - setLuaPath(L, scripts_path); - - //-- Last but not least, add to the LUA_PATH (package.path in lua) - // so we can load libraries from the ./lualib/ - directory - char libraries_path[strlen(get_my_executable_directory()) + strlen(LUA_LIBRARIES_DIRECTORY) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; - strcpy(libraries_path, get_my_executable_directory()); - strcat(libraries_path, LUA_LIBRARIES_DIRECTORY); - strcat(libraries_path, LUA_LIBRARIES_WILDCARD); - setLuaPath(L, libraries_path); - return 1; + // so we can load scripts from various places: + { + // from the ./luascripts/ directory + char scripts_path[strlen(get_my_executable_directory()) + strlen(LUA_SCRIPTS_DIRECTORY) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; + strcpy(scripts_path, get_my_executable_directory()); + strcat(scripts_path, LUA_SCRIPTS_DIRECTORY); + strcat(scripts_path, LUA_LIBRARIES_WILDCARD); + setLuaPath(L, scripts_path); + // from the ./lualib/ directory + char libraries_path[strlen(get_my_executable_directory()) + strlen(LUA_LIBRARIES_DIRECTORY) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; + strcpy(libraries_path, get_my_executable_directory()); + strcat(libraries_path, LUA_LIBRARIES_DIRECTORY); + strcat(libraries_path, LUA_LIBRARIES_WILDCARD); + setLuaPath(L, libraries_path); + } + char *userpath = getenv("HOME"); + if (userpath != NULL) { + // from the ~/.proxmark3/luascripts/ directory + char scripts_path[strlen(userpath) + strlen(LUA_PM3_USER_DIRECTORY) + strlen(LUA_SCRIPTS_DIRECTORY) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; + strcpy(scripts_path, userpath); + strcat(scripts_path, LUA_PM3_USER_DIRECTORY); + strcat(scripts_path, LUA_SCRIPTS_DIRECTORY); + strcat(scripts_path, LUA_LIBRARIES_WILDCARD); + setLuaPath(L, scripts_path); + // from the ~/.proxmark3/lualib/ directory + char libraries_path[strlen(userpath) + strlen(LUA_PM3_USER_DIRECTORY) + strlen(LUA_LIBRARIES_DIRECTORY) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; + strcpy(libraries_path, userpath); + strcat(libraries_path, LUA_PM3_USER_DIRECTORY); + strcat(libraries_path, LUA_LIBRARIES_DIRECTORY); + strcat(libraries_path, LUA_LIBRARIES_WILDCARD); + setLuaPath(L, libraries_path); + } + { + // from the /usr/local/share/proxmark3/luascripts/ directory + char scripts_path[strlen(LUA_PM3_SYSTEM_DIRECTORY) + strlen(LUA_SCRIPTS_DIRECTORY) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; + strcpy(scripts_path, LUA_PM3_SYSTEM_DIRECTORY); + strcat(scripts_path, LUA_SCRIPTS_DIRECTORY); + strcat(scripts_path, LUA_LIBRARIES_WILDCARD); + setLuaPath(L, scripts_path); + // from the /usr/local/share/proxmark3/lualib/ directory + char libraries_path[strlen(LUA_PM3_SYSTEM_DIRECTORY) + strlen(LUA_LIBRARIES_DIRECTORY) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; + strcpy(libraries_path, LUA_PM3_SYSTEM_DIRECTORY); + strcat(libraries_path, LUA_LIBRARIES_DIRECTORY); + strcat(libraries_path, LUA_LIBRARIES_WILDCARD); + setLuaPath(L, libraries_path); + return 1; + } } diff --git a/client/scripting.h b/client/scripting.h index 1a7b5a7e3..12d6f1f0b 100644 --- a/client/scripting.h +++ b/client/scripting.h @@ -14,6 +14,8 @@ //#include //#include +#define LUA_PM3_SYSTEM_DIRECTORY "/usr/local/share/proxmark3/" +#define LUA_PM3_USER_DIRECTORY "/.proxmark3/" #define LUA_LIBRARIES_DIRECTORY "lualibs/" #define LUA_SCRIPTS_DIRECTORY "luascripts/" #define LUA_LIBRARIES_WILDCARD "?.lua" From 9ae27cd73cc42d16ffe6eaf95d8c8482764b6f64 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 22 Aug 2019 00:32:15 +0200 Subject: [PATCH 0402/1854] scripts list / scripts run: look also in the new lua scripts paths --- client/cmdscript.c | 115 ++++++++++++++++++++++++++++++++++----------- client/scripting.c | 4 +- 2 files changed, 89 insertions(+), 30 deletions(-) diff --git a/client/cmdscript.c b/client/cmdscript.c index 16539b020..f97e8fe9c 100644 --- a/client/cmdscript.c +++ b/client/cmdscript.c @@ -56,29 +56,13 @@ static bool endsWith(const char *base, const char *str) { return (blen >= slen) && (0 == strcmp(base + blen - slen, str)); } -/** -* Generate a sorted list of available commands, what it does is -* generate a file listing of the script-directory for files -* ending with .lua -*/ -static int CmdScriptList(const char *Cmd) { - (void)Cmd; // Cmd is not used so far - - char const *exedir = get_my_executable_directory(); - if (exedir == NULL) - return 0; - char script_directory_path[strlen(exedir) + strlen(LUA_SCRIPTS_DIRECTORY) + 1]; - strcpy(script_directory_path, exedir); - strcpy(script_directory_path, get_my_executable_directory()); - strcat(script_directory_path, LUA_SCRIPTS_DIRECTORY); - +static int scriptlist(const char *path) { struct dirent **namelist; int n; - n = scandir(script_directory_path, &namelist, NULL, alphasort); + n = scandir(path, &namelist, NULL, alphasort); if (n == -1) { - PrintAndLogEx(FAILED, "Couldn't open the luascripts-directory"); - return 1; + return PM3_EFILE; } for (uint16_t i = 0; i < n; i++) { @@ -87,6 +71,37 @@ static int CmdScriptList(const char *Cmd) { free(namelist[i]); } free(namelist); + return PM3_SUCCESS; +} + +/** +* Generate a sorted list of available commands, what it does is +* generate a file listing of the script-directory for files +* ending with .lua +*/ +static int CmdScriptList(const char *Cmd) { + (void)Cmd; // Cmd is not used so far + + if (get_my_executable_directory() != NULL) { + char script_directory_path[strlen(get_my_executable_directory()) + strlen(LUA_SCRIPTS_DIRECTORY) + 1]; + strcpy(script_directory_path, get_my_executable_directory()); + strcat(script_directory_path, LUA_SCRIPTS_DIRECTORY); + scriptlist(script_directory_path); + } + char *userpath = getenv("HOME"); + if (userpath != NULL) { + char script_directory_path[strlen(userpath) + strlen(LUA_PM3_USER_DIRECTORY) + strlen(LUA_SCRIPTS_DIRECTORY) + 1]; + strcpy(script_directory_path, userpath); + strcat(script_directory_path, LUA_PM3_USER_DIRECTORY); + strcat(script_directory_path, LUA_SCRIPTS_DIRECTORY); + scriptlist(script_directory_path); + } + { + char script_directory_path[strlen(LUA_PM3_SYSTEM_DIRECTORY) + strlen(LUA_SCRIPTS_DIRECTORY) + 1]; + strcpy(script_directory_path, LUA_PM3_SYSTEM_DIRECTORY); + strcat(script_directory_path, LUA_SCRIPTS_DIRECTORY); + scriptlist(script_directory_path); + } return 0; } @@ -125,16 +140,60 @@ static int CmdScriptRun(const char *Cmd) { suffix = ".lua"; } - char script_path[strlen(get_my_executable_directory()) + strlen(LUA_SCRIPTS_DIRECTORY) + strlen(script_name) + strlen(suffix) + 1]; - strcpy(script_path, get_my_executable_directory()); - strcat(script_path, LUA_SCRIPTS_DIRECTORY); - strcat(script_path, script_name); - strcat(script_path, suffix); + bool found = false; + int error; + if (get_my_executable_directory() != NULL) { + char script_path[strlen(get_my_executable_directory()) + strlen(LUA_SCRIPTS_DIRECTORY) + strlen(script_name) + strlen(suffix) + 1]; + strcpy(script_path, get_my_executable_directory()); + strcat(script_path, LUA_SCRIPTS_DIRECTORY); + strcat(script_path, script_name); + strcat(script_path, suffix); + FILE *file; + if ((file = fopen(script_path, "r"))) + { + fclose(file); + PrintAndLogEx(SUCCESS, "Executing: %s, args '%s'\n", script_path, arguments); + found = true; + error = luaL_loadfile(lua_state, script_path); + } + } + char *userpath = getenv("HOME"); + if ((!found) && (userpath != NULL)) { + char script_path[strlen(userpath) + strlen(LUA_PM3_USER_DIRECTORY) + strlen(LUA_SCRIPTS_DIRECTORY) + strlen(script_name) + strlen(suffix) + 1]; + strcpy(script_path, userpath); + strcat(script_path, LUA_PM3_USER_DIRECTORY); + strcat(script_path, LUA_SCRIPTS_DIRECTORY); + strcat(script_path, script_name); + strcat(script_path, suffix); + FILE *file; + if ((file = fopen(script_path, "r"))) + { + fclose(file); + PrintAndLogEx(SUCCESS, "Executing: %s, args '%s'\n", script_path, arguments); + found = true; + error = luaL_loadfile(lua_state, script_path); + } + } + if (!found) { + char script_path[strlen(LUA_PM3_SYSTEM_DIRECTORY) + strlen(LUA_SCRIPTS_DIRECTORY) + strlen(script_name) + strlen(suffix) + 1]; + strcpy(script_path, LUA_PM3_SYSTEM_DIRECTORY); + strcat(script_path, LUA_SCRIPTS_DIRECTORY); + strcat(script_path, script_name); + strcat(script_path, suffix); + FILE *file; + if ((file = fopen(script_path, "r"))) + { + fclose(file); + PrintAndLogEx(SUCCESS, "Executing: %s, args '%s'\n", script_path, arguments); + found = true; + error = luaL_loadfile(lua_state, script_path); + } + } + if (!found) { + PrintAndLogEx(FAILED, "Error - can't find script %s%s", script_name, suffix); + return PM3_EFILE; + } - PrintAndLogEx(SUCCESS, "Executing: %s%s, args '%s'\n", script_name, suffix, arguments); - - // run the Lua script - int error = luaL_loadfile(lua_state, script_path); if (!error) { lua_pushstring(lua_state, arguments); lua_setglobal(lua_state, "args"); diff --git a/client/scripting.c b/client/scripting.c index 54ed2aa2c..1c021e591 100644 --- a/client/scripting.c +++ b/client/scripting.c @@ -1133,7 +1133,7 @@ int set_pm3_libraries(lua_State *L) { //--add to the LUA_PATH (package.path in lua) // so we can load scripts from various places: - { + if (get_my_executable_directory() != NULL) { // from the ./luascripts/ directory char scripts_path[strlen(get_my_executable_directory()) + strlen(LUA_SCRIPTS_DIRECTORY) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; strcpy(scripts_path, get_my_executable_directory()); @@ -1177,6 +1177,6 @@ int set_pm3_libraries(lua_State *L) { strcat(libraries_path, LUA_LIBRARIES_DIRECTORY); strcat(libraries_path, LUA_LIBRARIES_WILDCARD); setLuaPath(L, libraries_path); - return 1; } + return 1; } From 9a21bf8b2d8a77233f29fdd62a8c23974ee0c069 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Thu, 22 Aug 2019 13:26:05 +0300 Subject: [PATCH 0403/1854] add check arm-none-eabi-gcc and unify install step for linux and macos --- .travis.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8952df259..0b108b4f1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -45,13 +45,13 @@ addons: taps: RfidResearchGroup/proxmark3 install: - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then - make clean; - make all V=1 "$MAKE_PARAMS"; - elif [[ "$TRAVIS_OS_NAME" == "linux" ]]; then - make clean; - make all V=1 "$MAKE_PARAMS"; + if ! arm-none-eabi-gccx -v; then + echo "arm-none-eabi-gcc [ERROR]"; + travis_terminate 1; fi + + make clean; + make all V=1 "$MAKE_PARAMS"; script: ## start and run a test script From 34a389a4ac45ad56c94f439a458efe6f51a228c7 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Thu, 22 Aug 2019 13:30:01 +0300 Subject: [PATCH 0404/1854] small fix --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 0b108b4f1..ac39433f8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -45,7 +45,7 @@ addons: taps: RfidResearchGroup/proxmark3 install: - if ! arm-none-eabi-gccx -v; then + if ! arm-none-eabi-gcc -v; then echo "arm-none-eabi-gcc [ERROR]"; travis_terminate 1; fi From 407078d90a9d6ec7b040adbccd662d14db65d2c6 Mon Sep 17 00:00:00 2001 From: Matthias Konrath Date: Thu, 22 Aug 2019 12:49:26 +0200 Subject: [PATCH 0405/1854] Experimental hardautopwn implementation. --- client/cmdhfmf.c | 425 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 425 insertions(+) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index aaaeafb99..6c5424568 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -166,6 +166,34 @@ static int usage_hf14_hardnested(void) { PrintAndLogEx(NORMAL, " hf mf hardnested 0 A A0A1A2A3A4A5 4 A FFFFFFFFFFFF"); return 0; } +static int usage_hf14_hardautopwn(void) { + PrintAndLogEx(NORMAL, "Usage:"); + PrintAndLogEx(NORMAL, " hf mf hardautopwn [k] "); + PrintAndLogEx(NORMAL, " [d] [f] [s] [t] [i]"); + PrintAndLogEx(NORMAL, " (card memory - 0 - MINI(320 bytes), 1 - 1K, 2 - 2K, 4 - 4K, - 1K)"); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Options:"); + PrintAndLogEx(NORMAL, " h this help"); + PrintAndLogEx(NORMAL, " k if a known key for a block is supplied"); + PrintAndLogEx(NORMAL, " d write keys to binary file"); + PrintAndLogEx(NORMAL, " f keys to test (speed up the cracking, if some keys are known)"); + PrintAndLogEx(NORMAL, " s slower acquisition (required by some non standard cards)"); + PrintAndLogEx(NORMAL, " t tests?"); + PrintAndLogEx(NORMAL, " i set type of SIMD instructions. Without this flag programs autodetect it."); + PrintAndLogEx(NORMAL, " i 5 = AVX512"); + PrintAndLogEx(NORMAL, " i 2 = AVX2"); + PrintAndLogEx(NORMAL, " i a = AVX"); + PrintAndLogEx(NORMAL, " i s = SSE2"); + PrintAndLogEx(NORMAL, " i m = MMX"); + PrintAndLogEx(NORMAL, " i n = none (use CPU regular instruction set)"); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Examples:"); + PrintAndLogEx(NORMAL, " hf mf hardautopwn b 0 A FFFFFFFFFFFF 1 d"); + PrintAndLogEx(NORMAL, " hf mf hardautopwn 0 A FFFFFFFFFFFF 1 d f default_keys.dic"); + PrintAndLogEx(NORMAL, " hf mf hardautopwn 0 A FFFFFFFFFFFF 4 A f nonces.bin w s"); + PrintAndLogEx(NORMAL, ""); + return 0; +} static int usage_hf14_chk(void) { PrintAndLogEx(NORMAL, "Usage: hf mf chk [h] |<*card memory> [t|d] [] []"); PrintAndLogEx(NORMAL, "Options:"); @@ -1530,6 +1558,402 @@ static int CmdHF14AMfNestedHard(const char *Cmd) { return 0; } + +static int CmdHF14AMfHardAuto(const char *Cmd) { + uint8_t blockNo = 0; + uint8_t keyType = 0; + uint8_t *keyBlock, *p; + uint8_t sectorsCnt = 1; + uint8_t key[6] = {0, 0, 0, 0, 0, 0}; + uint8_t trgkey[6] = {0, 0, 0, 0, 0, 0}; + uint8_t cmdp = 0; + uint64_t key64 = 0; + char filename[FILE_PATH_SIZE] = {0}, *fptr; + char ctmp; + + keyBlock = calloc(ARRAYLEN(g_mifare_default_keys), 6); + if (keyBlock == NULL) return 1; + + for (int cnt = 0; cnt < ARRAYLEN(g_mifare_default_keys); cnt++) + num_to_bytes(g_mifare_default_keys[cnt], 6, keyBlock + cnt * 6); + + bool slow = false; + bool nonce_file_read = false; + bool nonce_file_write = false; + bool createDumpFile = false; + bool know_target_key = false; + int tests = 0; + + ctmp = tolower(param_getchar(Cmd, 0)); + if (strlen(Cmd) < 1 || ctmp == 'h') return usage_hf14_hardautopwn(); + + + while ((ctmp = param_getchar(Cmd, cmdp))) { + switch (tolower(ctmp)) { + case 'h': + return usage_hf14_hardautopwn(); + case 'f': + if (param_getstr(Cmd, cmdp +1, filename, FILE_PATH_SIZE) >= FILE_PATH_SIZE) { + PrintAndLogEx(FAILED, "Filename too long"); + } + cmdp ++; + break; + case 'd': + createDumpFile = true; + break; + case '*': + // sectors + switch (param_getchar(Cmd, cmdp + 1)) { + case '0': + sectorsCnt = MIFARE_MINI_MAXSECTOR; + break; + case '1': + sectorsCnt = MIFARE_1K_MAXSECTOR; + break; + case '2': + sectorsCnt = MIFARE_2K_MAXSECTOR; + break; + case '4': + sectorsCnt = MIFARE_4K_MAXSECTOR; + break; + default: + sectorsCnt = MIFARE_1K_MAXSECTOR; + } + cmdp ++; + break; + case 'k': + // Get the known block number + if (param_getchar(Cmd, cmdp + 1) == 0x00) { + PrintAndLogEx(WARNING, "Block number is missing"); + return 1; + } + blockNo = param_get8(Cmd, cmdp + 1); + // Get the knonwn block type + ctmp = tolower(param_getchar(Cmd, cmdp + 2)); + if (ctmp != 'a' && ctmp != 'b') { + PrintAndLogEx(WARNING, "Key type must be A or B"); + return 1; + } + if (ctmp != 'a') { + keyType = 1; + } + // Get the known block key + if (param_gethex(Cmd, cmdp + 3, key, 12)) { + PrintAndLogEx(WARNING, "Key must include 12 HEX symbols"); + return 1; + } + know_target_key = true; + cmdp += 3; + case 's': + slow = true; + break; + case 'i': + SetSIMDInstr(SIMD_AUTO); + ctmp = tolower(param_getchar(Cmd, cmdp + 1)); + switch (ctmp) { + case '5': + SetSIMDInstr(SIMD_AVX512); + break; + case '2': + SetSIMDInstr(SIMD_AVX2); + break; + case 'a': + SetSIMDInstr(SIMD_AVX); + break; + case 's': + SetSIMDInstr(SIMD_SSE2); + break; + case 'm': + SetSIMDInstr(SIMD_MMX); + break; + case 'n': + SetSIMDInstr(SIMD_NONE); + break; + default: + PrintAndLogEx(WARNING, "Unknown SIMD type. %c", ctmp); + return 1; + } + cmdp += 2; + break; + default: + PrintAndLogEx(WARNING, "Unknown parameter '%c'\n", ctmp); + usage_hf14_hardnested(); + return 1; + } + cmdp++; + } + + // Print parameters + PrintAndLogEx(NORMAL, "Used Parameters:"); + PrintAndLogEx(NORMAL, "\t[+] Dumping the found keys: %d", createDumpFile); + PrintAndLogEx(NORMAL, "\t[+] Card sectors: %d", sectorsCnt); + PrintAndLogEx(NORMAL, "\t[+] Key supplied: %d", know_target_key); + PrintAndLogEx(NORMAL, "\t[+] Known block: %d", blockNo); + PrintAndLogEx(NORMAL, "\t[+] Keytype: %c", keyType ? 'B' : 'A'); + PrintAndLogEx(NORMAL, "\t[+] Kown key: 0x%02x%02x%02x%02x%02x%02x", key[0], key[1], key[2], key[3], key[4], key[5]); + PrintAndLogEx(NORMAL, "\t[+] Dictionary: %s", filename); + + + if (know_target_key) { + // check if we can authenticate to sector + if (mfCheckKeys(blockNo, keyType, true, 1, key, &key64) != PM3_SUCCESS) { + PrintAndLogEx(WARNING, "Key is wrong. Can't authenticate to block:%3d key type:%c", blockNo, keyType ? 'B' : 'A'); + return 3; + } + } else { + PrintAndLogEx(WARNING, "No known key was supplied, if no usable key is found in the dictionary, then this attack will fail!"); + } + + + // General stuff + // Add check for the hardnested attack!! + uint64_t foundkey = 0; + int16_t isOK = 0; + + // Bruteforce stuff + FILE* f; + sector_t *e_sector = calloc(sectorsCnt, sizeof(sector_t)); + uint8_t arr[80]; + uint8_t tmpKey[6]; + char buf[13] = {0}; + int i, i2, keycnt = 0;; + int current_sector_i, current_key_type_i, default_keys_i, found_keys_i; + uint32_t keyitems = ARRAYLEN(g_mifare_default_keys); + + + // Clear the datastructures + for (i=0; i<80; i++) { + arr[i] = 0; + } + for (i=0; i 0xffffffffffff has been inserted for unknown keys.", fptr); + } + + free(e_sector); + + DropField(); + if (isOK) { + switch (isOK) { + case 1 : + PrintAndLogEx(ERR, "Error: No response from Proxmark3.\n"); + break; + case 2 : + PrintAndLogEx(NORMAL, "Button pressed. Aborted.\n"); + break; + default : + break; + } + return 2; + } + + + return 0; +} + /* static int randInRange(int min, int max) { return min + (int)(rand() / (double)(RAND_MAX) * (max - min + 1)); @@ -3638,6 +4062,7 @@ static command_t CommandTable[] = { {"darkside", CmdHF14AMfDarkside, IfPm3Iso14443a, "Darkside attack. read parity error messages."}, {"nested", CmdHF14AMfNested, IfPm3Iso14443a, "Nested attack. Test nested authentication"}, {"hardnested", CmdHF14AMfNestedHard, AlwaysAvailable, "Nested attack for hardened Mifare cards"}, + {"hardautopwn", CmdHF14AMfHardAuto, AlwaysAvailable, "Nested attack for hardened Mifare cards that breaks all sector keys autmatically"}, {"keybrute", CmdHF14AMfKeyBrute, IfPm3Iso14443a, "J_Run's 2nd phase of multiple sector nested authentication key recovery"}, {"nack", CmdHf14AMfNack, IfPm3Iso14443a, "Test for Mifare NACK bug"}, {"chk", CmdHF14AMfChk, IfPm3Iso14443a, "Check keys"}, From abb69e2dc9fe7a7e114955b6543e35f396718735 Mon Sep 17 00:00:00 2001 From: Matthias Konrath Date: Thu, 22 Aug 2019 14:55:06 +0200 Subject: [PATCH 0406/1854] Further improved the hardautopwn feature. --- client/cmdhfmf.c | 162 ++++++++++++++++++++++++++--------------------- 1 file changed, 91 insertions(+), 71 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 6c5424568..c68daa9f3 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -168,17 +168,16 @@ static int usage_hf14_hardnested(void) { } static int usage_hf14_hardautopwn(void) { PrintAndLogEx(NORMAL, "Usage:"); - PrintAndLogEx(NORMAL, " hf mf hardautopwn [k] "); - PrintAndLogEx(NORMAL, " [d] [f] [s] [t] [i]"); + PrintAndLogEx(NORMAL, " hf mf hardautopwn [k] "); + PrintAndLogEx(NORMAL, " * [d] [f] [s] [t] [i]"); PrintAndLogEx(NORMAL, " (card memory - 0 - MINI(320 bytes), 1 - 1K, 2 - 2K, 4 - 4K, - 1K)"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h this help"); - PrintAndLogEx(NORMAL, " k if a known key for a block is supplied"); + PrintAndLogEx(NORMAL, " k if a known key for a block is supplied"); PrintAndLogEx(NORMAL, " d write keys to binary file"); PrintAndLogEx(NORMAL, " f keys to test (speed up the cracking, if some keys are known)"); PrintAndLogEx(NORMAL, " s slower acquisition (required by some non standard cards)"); - PrintAndLogEx(NORMAL, " t tests?"); PrintAndLogEx(NORMAL, " i set type of SIMD instructions. Without this flag programs autodetect it."); PrintAndLogEx(NORMAL, " i 5 = AVX512"); PrintAndLogEx(NORMAL, " i 2 = AVX2"); @@ -188,9 +187,9 @@ static int usage_hf14_hardautopwn(void) { PrintAndLogEx(NORMAL, " i n = none (use CPU regular instruction set)"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf mf hardautopwn b 0 A FFFFFFFFFFFF 1 d"); - PrintAndLogEx(NORMAL, " hf mf hardautopwn 0 A FFFFFFFFFFFF 1 d f default_keys.dic"); - PrintAndLogEx(NORMAL, " hf mf hardautopwn 0 A FFFFFFFFFFFF 4 A f nonces.bin w s"); + PrintAndLogEx(NORMAL, " hf mf hardautopwn k 0 A FFFFFFFFFFFF d"); + PrintAndLogEx(NORMAL, " hf mf hardautopwn k 0 A FFFFFFFFFFFF * 1 d f default_keys.dic"); + PrintAndLogEx(NORMAL, " hf mf hardautopwn k 0 A FFFFFFFFFFFF * 4 s i 5"); PrintAndLogEx(NORMAL, ""); return 0; } @@ -1560,22 +1559,45 @@ static int CmdHF14AMfNestedHard(const char *Cmd) { static int CmdHF14AMfHardAuto(const char *Cmd) { + /* + Author: Matthias Konrath + Company: Trustworks GmbH + Email: m.konrath@trustworks.at + */ + uint8_t blockNo = 0; uint8_t keyType = 0; uint8_t *keyBlock, *p; - uint8_t sectorsCnt = 1; + uint8_t sectorsCnt = MIFARE_1K_MAXSECTOR; + sector_t *e_sector; + uint8_t arr[80]; uint8_t key[6] = {0, 0, 0, 0, 0, 0}; - uint8_t trgkey[6] = {0, 0, 0, 0, 0, 0}; - uint8_t cmdp = 0; + uint8_t tmpKey[6]; uint64_t key64 = 0; - char filename[FILE_PATH_SIZE] = {0}, *fptr; - char ctmp; + + uint64_t t1; + uint8_t foundKeysDictionary = 0; + uint8_t foundKeysReuse = 0; + uint8_t foundKeysHardnested = 0; keyBlock = calloc(ARRAYLEN(g_mifare_default_keys), 6); if (keyBlock == NULL) return 1; for (int cnt = 0; cnt < ARRAYLEN(g_mifare_default_keys); cnt++) num_to_bytes(g_mifare_default_keys[cnt], 6, keyBlock + cnt * 6); + + FILE* f; + char buf[13] = {0}; + char filename[FILE_PATH_SIZE] = {0}, *fptr; + uint8_t cmdp = 0; + char ctmp; + + uint64_t foundkey = 0; + int16_t isOK = 0; + + int i, i2, keycnt = 0;; + int current_sector_i, current_key_type_i, default_keys_i, found_keys_i; + uint32_t keyitems = ARRAYLEN(g_mifare_default_keys); bool slow = false; bool nonce_file_read = false; @@ -1624,7 +1646,7 @@ static int CmdHF14AMfHardAuto(const char *Cmd) { case 'k': // Get the known block number if (param_getchar(Cmd, cmdp + 1) == 0x00) { - PrintAndLogEx(WARNING, "Block number is missing"); + PrintAndLogEx(WARNING, "Sector number is missing"); return 1; } blockNo = param_get8(Cmd, cmdp + 1); @@ -1685,42 +1707,27 @@ static int CmdHF14AMfHardAuto(const char *Cmd) { // Print parameters PrintAndLogEx(NORMAL, "Used Parameters:"); - PrintAndLogEx(NORMAL, "\t[+] Dumping the found keys: %d", createDumpFile); - PrintAndLogEx(NORMAL, "\t[+] Card sectors: %d", sectorsCnt); - PrintAndLogEx(NORMAL, "\t[+] Key supplied: %d", know_target_key); - PrintAndLogEx(NORMAL, "\t[+] Known block: %d", blockNo); - PrintAndLogEx(NORMAL, "\t[+] Keytype: %c", keyType ? 'B' : 'A'); - PrintAndLogEx(NORMAL, "\t[+] Kown key: 0x%02x%02x%02x%02x%02x%02x", key[0], key[1], key[2], key[3], key[4], key[5]); - PrintAndLogEx(NORMAL, "\t[+] Dictionary: %s", filename); + PrintAndLogEx(NORMAL, "[+] Dumping the found keys: %s", createDumpFile ? "True" : "False"); + PrintAndLogEx(NORMAL, "[+] Card sectors: %d", sectorsCnt); + PrintAndLogEx(NORMAL, "[+] Key supplied: %s", know_target_key ? "True" : "False"); + PrintAndLogEx(NORMAL, "[+] Known sector: %d", blockNo); + PrintAndLogEx(NORMAL, "[+] Keytype: %c", keyType ? 'B' : 'A'); + PrintAndLogEx(NORMAL, "[+] Kown key: 0x%02x%02x%02x%02x%02x%02x", key[0], key[1], key[2], key[3], key[4], key[5]); + PrintAndLogEx(NORMAL, "[+] Dictionary: %s", filename); + e_sector = calloc(sectorsCnt, sizeof(sector_t)); if (know_target_key) { // check if we can authenticate to sector if (mfCheckKeys(blockNo, keyType, true, 1, key, &key64) != PM3_SUCCESS) { - PrintAndLogEx(WARNING, "Key is wrong. Can't authenticate to block:%3d key type:%c", blockNo, keyType ? 'B' : 'A'); + PrintAndLogEx(WARNING, "Key is wrong. Can't authenticate to sector:%3d key type:%c", blockNo, keyType ? 'B' : 'A'); + free(e_sector); return 3; } } else { PrintAndLogEx(WARNING, "No known key was supplied, if no usable key is found in the dictionary, then this attack will fail!"); } - - // General stuff - // Add check for the hardnested attack!! - uint64_t foundkey = 0; - int16_t isOK = 0; - - // Bruteforce stuff - FILE* f; - sector_t *e_sector = calloc(sectorsCnt, sizeof(sector_t)); - uint8_t arr[80]; - uint8_t tmpKey[6]; - char buf[13] = {0}; - int i, i2, keycnt = 0;; - int current_sector_i, current_key_type_i, default_keys_i, found_keys_i; - uint32_t keyitems = ARRAYLEN(g_mifare_default_keys); - - // Clear the datastructures for (i=0; i<80; i++) { arr[i] = 0; @@ -1737,6 +1744,7 @@ static int CmdHF14AMfHardAuto(const char *Cmd) { f = fopen(filename, "r"); if (!f) { PrintAndLogEx(FAILED, "File: " _YELLOW_("%s") ": not found or locked.", filename); + free(e_sector); return 1; } @@ -1760,6 +1768,7 @@ static int CmdHF14AMfHardAuto(const char *Cmd) { PrintAndLogEx(FAILED, "Cannot allocate memory for default keys"); free(keyBlock); fclose(f); + free(e_sector); return 2; } keyBlock = p; @@ -1774,8 +1783,9 @@ static int CmdHF14AMfHardAuto(const char *Cmd) { PrintAndLogEx(SUCCESS, "Loaded %2d keys from " _YELLOW_("%s"), keycnt, filename); } + t1 = msclock(); - // If no key is supplied by the user brute force with the dictionary + // If no key is supplied by the user, brute force with the dictionary if (know_target_key == false) { for (current_sector_i=0; current_sector_i < sectorsCnt; current_sector_i++) { for (current_key_type_i=0; current_key_type_i < 2; current_key_type_i++) { @@ -1786,7 +1796,8 @@ static int CmdHF14AMfHardAuto(const char *Cmd) { } if (mfCheckKeys(current_sector_i*4, current_key_type_i, true, 1, tmpKey, &key64) == PM3_SUCCESS) { - PrintAndLogEx(SUCCESS, "[ KEY ENUM ] Valid KEY FOUND: block:%3d key type:%c key: " _YELLOW_("0x%02x%02x%02x%02x%02x%02x"), + PrintAndLogEx(SUCCESS, "Jackpot, we found a key! Now let the fun begin!"); + PrintAndLogEx(SUCCESS, "[Dictio. KEYS] Valid KEY FOUND: sector:%3d key type:%c key: " _YELLOW_("0x%02x%02x%02x%02x%02x%02x"), current_sector_i, current_key_type_i ? 'B' : 'A', tmpKey[0], tmpKey[1], tmpKey[2], tmpKey[3], tmpKey[4], tmpKey[5]); @@ -1797,6 +1808,7 @@ static int CmdHF14AMfHardAuto(const char *Cmd) { know_target_key = true; blockNo = current_sector_i; keyType = current_key_type_i; + foundKeysDictionary++; // Exit the loop current_sector_i = sectorsCnt; @@ -1809,17 +1821,17 @@ static int CmdHF14AMfHardAuto(const char *Cmd) { } } - // Set the user defined key + // Set the user defined / bruteforced key if (know_target_key) { e_sector[blockNo].Key[keyType] = bytes_to_num(key, 6); arr[blockNo + (keyType * sectorsCnt)] = 1; } else { PrintAndLogEx(FAILED, "No usable key was found!"); - return 1; + free(e_sector); + return 1; } - - // Iterate over each sector and key + // Iterate over each sector and key(A/B) for (current_sector_i=0; current_sector_i < sectorsCnt; current_sector_i++) { for (current_key_type_i=0; current_key_type_i < 2; current_key_type_i++) { @@ -1827,29 +1839,29 @@ static int CmdHF14AMfHardAuto(const char *Cmd) { // Try the found keys if (foundkey == 0) { - for (found_keys_i=0; found_keys_i < current_sector_i; found_keys_i++) { + for (found_keys_i=0; found_keys_i < sectorsCnt; found_keys_i++) { // Iterate over the keys if (arr[found_keys_i + (current_key_type_i * sectorsCnt)] == 1) { num_to_bytes(e_sector[found_keys_i].Key[current_key_type_i], 6, tmpKey); if (mfCheckKeys(current_sector_i*4, current_key_type_i, true, 1, tmpKey, &key64) == PM3_SUCCESS) { - PrintAndLogEx(SUCCESS, "[FOUND KEYS %c] Valid KEY FOUND: block:%3d key type:%c key: " _YELLOW_("0x%02x%02x%02x%02x%02x%02x"), - current_key_type_i ? 'B' : 'A', + PrintAndLogEx(SUCCESS, "[REUSED KEYS] Valid KEY FOUND: sector:%3d key type:%c key: " _YELLOW_("0x%02x%02x%02x%02x%02x%02x"), current_sector_i, current_key_type_i ? 'B' : 'A', tmpKey[0], tmpKey[1], tmpKey[2], tmpKey[3], tmpKey[4], tmpKey[5]); foundkey = bytes_to_num(tmpKey, 6); + foundKeysReuse++; break; } } if (arr[found_keys_i + (((current_key_type_i+1)%2) * sectorsCnt)] == 1) { num_to_bytes(e_sector[found_keys_i].Key[(current_key_type_i+1)%2], 6, tmpKey); if (mfCheckKeys(current_sector_i*4, current_key_type_i, true, 1, tmpKey, &key64) == PM3_SUCCESS) { - PrintAndLogEx(SUCCESS, "[FOUND KEYS %c] Valid KEY FOUND: block:%3d key type:%c key: " _YELLOW_("0x%02x%02x%02x%02x%02x%02x"), - (current_key_type_i+1)%2 ? 'B' : 'A', + PrintAndLogEx(SUCCESS, "[REUSED KEYS] Valid KEY FOUND: sector:%3d key type:%c key: " _YELLOW_("0x%02x%02x%02x%02x%02x%02x"), current_sector_i, current_key_type_i ? 'B' : 'A', tmpKey[0], tmpKey[1], tmpKey[2], tmpKey[3], tmpKey[4], tmpKey[5]); foundkey = bytes_to_num(tmpKey, 6); + foundKeysReuse++; break; } } @@ -1864,29 +1876,48 @@ static int CmdHF14AMfHardAuto(const char *Cmd) { } if (mfCheckKeys(current_sector_i*4, current_key_type_i, true, 1, tmpKey, &key64) == PM3_SUCCESS) { - PrintAndLogEx(SUCCESS, "[DEFAULT KEYS] Valid KEY FOUND: block:%3d key type:%c key: " _YELLOW_("0x%02x%02x%02x%02x%02x%02x"), + PrintAndLogEx(SUCCESS, "[Dictio. KEYS] Valid KEY FOUND: sector:%3d key type:%c key: " _YELLOW_("0x%02x%02x%02x%02x%02x%02x"), current_sector_i, current_key_type_i ? 'B' : 'A', tmpKey[0], tmpKey[1], tmpKey[2], tmpKey[3], tmpKey[4], tmpKey[5]); foundkey = bytes_to_num(tmpKey, 6); + foundKeysDictionary++; break; } } } // Bruteforce with hardnested if (foundkey == 0) { - PrintAndLogEx(SUCCESS, "[ BRUTEFORCE ] block no:%3d, target key type:%c, Slow: %s, Tests: %d ", + PrintAndLogEx(SUCCESS, "[ BRUTEFORCE ] sector no:%3d, target key type:%c, Slow: %s, Tests: %d ", current_sector_i, current_key_type_i ? 'B' : 'A', slow ? "Yes" : "No", tests); - isOK = mfnestedhard(blockNo, keyType, key, current_sector_i*4, current_key_type_i, know_target_key ? trgkey : NULL, nonce_file_read, nonce_file_write, slow, tests, &foundkey, filename); + isOK = mfnestedhard(blockNo, keyType, key, current_sector_i*4, current_key_type_i, NULL, nonce_file_read, nonce_file_write, slow, tests, &foundkey, NULL); + + DropField(); + if (isOK) { + switch (isOK) { + case 1 : + PrintAndLogEx(ERR, "Error: No response from Proxmark3.\n"); + break; + case 2 : + PrintAndLogEx(NORMAL, "Button pressed. Aborted.\n"); + break; + default : + break; + } + free(e_sector); + return 2; + } + num_to_bytes(foundkey, 6, tmpKey); - PrintAndLogEx(SUCCESS, "[CRACKED KEY] Valid KEY FOUND: block:%3d key type:%c key: " _YELLOW_("0x%02x%02x%02x%02x%02x%02x"), + PrintAndLogEx(SUCCESS, "[CRACKED KEY] Valid KEY FOUND: sector:%3d key type:%c key: " _YELLOW_("0x%02x%02x%02x%02x%02x%02x"), current_sector_i, current_key_type_i ? 'B' : 'A', tmpKey[0], tmpKey[1], tmpKey[2], tmpKey[3], tmpKey[4], tmpKey[5]); + foundKeysHardnested++; } // Add the key if (foundkey != 0) { @@ -1908,8 +1939,10 @@ static int CmdHF14AMfHardAuto(const char *Cmd) { if (createDumpFile) { fptr = GenerateFilename("hf-mf-", "-key.bin"); - if (fptr == NULL) + if (fptr == NULL) { + free(e_sector); return 1; + } FILE *fkeys = fopen(fptr, "wb"); if (fkeys == NULL) { @@ -1933,24 +1966,11 @@ static int CmdHF14AMfHardAuto(const char *Cmd) { PrintAndLogEx(SUCCESS, "Found keys have been dumped to " _YELLOW_("%s")" --> 0xffffffffffff has been inserted for unknown keys.", fptr); } + t1 = msclock() - t1; + PrintAndLogEx(SUCCESS, "Key statistics: Dictionary: " _GREEN_("%d") ", Reuse: " _YELLOW_("%d") ", Bruteforce: " _MAGENTA_("%d") ", Total: " _YELLOW_("%d"), foundKeysDictionary, foundKeysReuse, foundKeysHardnested, sectorsCnt*2); + PrintAndLogEx(SUCCESS, "Required time for the hardautopwn attack: " _YELLOW_("%.0f") " seconds\n", (float)t1 / 1000.0); + free(e_sector); - - DropField(); - if (isOK) { - switch (isOK) { - case 1 : - PrintAndLogEx(ERR, "Error: No response from Proxmark3.\n"); - break; - case 2 : - PrintAndLogEx(NORMAL, "Button pressed. Aborted.\n"); - break; - default : - break; - } - return 2; - } - - return 0; } From ab38130c3e5869ea1013e59bf7cfaeda872a7b6f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 22 Aug 2019 17:44:08 +0200 Subject: [PATCH 0407/1854] chg: some more checks in pathing --- client/cmdscript.c | 8 +++++--- client/scripting.c | 29 ++++++++++++++++------------- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/client/cmdscript.c b/client/cmdscript.c index f97e8fe9c..e506b1a37 100644 --- a/client/cmdscript.c +++ b/client/cmdscript.c @@ -142,9 +142,11 @@ static int CmdScriptRun(const char *Cmd) { bool found = false; int error; - if (get_my_executable_directory() != NULL) { - char script_path[strlen(get_my_executable_directory()) + strlen(LUA_SCRIPTS_DIRECTORY) + strlen(script_name) + strlen(suffix) + 1]; - strcpy(script_path, get_my_executable_directory()); + const char* exec_path = get_my_executable_directory(); + + if (exec_path != NULL) { + char script_path[strlen(exec_path) + strlen(LUA_SCRIPTS_DIRECTORY) + strlen(script_name) + strlen(suffix) + 1]; + strcpy(script_path, exec_path); strcat(script_path, LUA_SCRIPTS_DIRECTORY); strcat(script_path, script_name); strcat(script_path, suffix); diff --git a/client/scripting.c b/client/scripting.c index 1c021e591..a823df8d7 100644 --- a/client/scripting.c +++ b/client/scripting.c @@ -1133,38 +1133,41 @@ int set_pm3_libraries(lua_State *L) { //--add to the LUA_PATH (package.path in lua) // so we can load scripts from various places: - if (get_my_executable_directory() != NULL) { + const char *exec_path = get_my_executable_directory(); + if (exec_path != NULL) { // from the ./luascripts/ directory - char scripts_path[strlen(get_my_executable_directory()) + strlen(LUA_SCRIPTS_DIRECTORY) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; - strcpy(scripts_path, get_my_executable_directory()); + char scripts_path[strlen(exec_path) + strlen(LUA_SCRIPTS_DIRECTORY) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; + strcpy(scripts_path, exec_path); strcat(scripts_path, LUA_SCRIPTS_DIRECTORY); strcat(scripts_path, LUA_LIBRARIES_WILDCARD); setLuaPath(L, scripts_path); // from the ./lualib/ directory - char libraries_path[strlen(get_my_executable_directory()) + strlen(LUA_LIBRARIES_DIRECTORY) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; - strcpy(libraries_path, get_my_executable_directory()); + char libraries_path[strlen(exec_path) + strlen(LUA_LIBRARIES_DIRECTORY) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; + strcpy(libraries_path, exec_path); strcat(libraries_path, LUA_LIBRARIES_DIRECTORY); strcat(libraries_path, LUA_LIBRARIES_WILDCARD); setLuaPath(L, libraries_path); } - char *userpath = getenv("HOME"); - if (userpath != NULL) { + char *user_path = getenv("HOME"); + if (user_path != NULL) { // from the ~/.proxmark3/luascripts/ directory - char scripts_path[strlen(userpath) + strlen(LUA_PM3_USER_DIRECTORY) + strlen(LUA_SCRIPTS_DIRECTORY) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; - strcpy(scripts_path, userpath); + char scripts_path[strlen(user_path) + strlen(LUA_PM3_USER_DIRECTORY) + strlen(LUA_SCRIPTS_DIRECTORY) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; + strcpy(scripts_path, user_path); strcat(scripts_path, LUA_PM3_USER_DIRECTORY); strcat(scripts_path, LUA_SCRIPTS_DIRECTORY); strcat(scripts_path, LUA_LIBRARIES_WILDCARD); setLuaPath(L, scripts_path); - // from the ~/.proxmark3/lualib/ directory - char libraries_path[strlen(userpath) + strlen(LUA_PM3_USER_DIRECTORY) + strlen(LUA_LIBRARIES_DIRECTORY) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; - strcpy(libraries_path, userpath); + + // from the ~/.proxmark3/lualib/ directory + char libraries_path[strlen(user_path) + strlen(LUA_PM3_USER_DIRECTORY) + strlen(LUA_LIBRARIES_DIRECTORY) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; + strcpy(libraries_path, user_path); strcat(libraries_path, LUA_PM3_USER_DIRECTORY); strcat(libraries_path, LUA_LIBRARIES_DIRECTORY); strcat(libraries_path, LUA_LIBRARIES_WILDCARD); setLuaPath(L, libraries_path); } - { + + if (strlen(LUA_PM3_SYSTEM_DIRECTORY) != 0 || strlen(LUA_SCRIPTS_DIRECTORY) != 0 || strlen(LUA_LIBRARIES_WILDCARD) != 0 ) { // from the /usr/local/share/proxmark3/luascripts/ directory char scripts_path[strlen(LUA_PM3_SYSTEM_DIRECTORY) + strlen(LUA_SCRIPTS_DIRECTORY) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; strcpy(scripts_path, LUA_PM3_SYSTEM_DIRECTORY); From 595b8a1885c131b3d3d9dbe79aa27518592e47b6 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 22 Aug 2019 19:36:20 +0200 Subject: [PATCH 0408/1854] introduce PREFIX for pm3 system directory and move to common.h --- client/cmdscript.c | 16 ++++++++-------- client/scripting.c | 18 +++++++++--------- client/scripting.h | 2 -- include/common.h | 6 ++++++ 4 files changed, 23 insertions(+), 19 deletions(-) diff --git a/client/cmdscript.c b/client/cmdscript.c index e506b1a37..9fdc3c0af 100644 --- a/client/cmdscript.c +++ b/client/cmdscript.c @@ -90,15 +90,15 @@ static int CmdScriptList(const char *Cmd) { } char *userpath = getenv("HOME"); if (userpath != NULL) { - char script_directory_path[strlen(userpath) + strlen(LUA_PM3_USER_DIRECTORY) + strlen(LUA_SCRIPTS_DIRECTORY) + 1]; + char script_directory_path[strlen(userpath) + strlen(PM3_USER_DIRECTORY) + strlen(LUA_SCRIPTS_DIRECTORY) + 1]; strcpy(script_directory_path, userpath); - strcat(script_directory_path, LUA_PM3_USER_DIRECTORY); + strcat(script_directory_path, PM3_USER_DIRECTORY); strcat(script_directory_path, LUA_SCRIPTS_DIRECTORY); scriptlist(script_directory_path); } { - char script_directory_path[strlen(LUA_PM3_SYSTEM_DIRECTORY) + strlen(LUA_SCRIPTS_DIRECTORY) + 1]; - strcpy(script_directory_path, LUA_PM3_SYSTEM_DIRECTORY); + char script_directory_path[strlen(PM3_SYSTEM_DIRECTORY) + strlen(LUA_SCRIPTS_DIRECTORY) + 1]; + strcpy(script_directory_path, PM3_SYSTEM_DIRECTORY); strcat(script_directory_path, LUA_SCRIPTS_DIRECTORY); scriptlist(script_directory_path); } @@ -161,9 +161,9 @@ static int CmdScriptRun(const char *Cmd) { } char *userpath = getenv("HOME"); if ((!found) && (userpath != NULL)) { - char script_path[strlen(userpath) + strlen(LUA_PM3_USER_DIRECTORY) + strlen(LUA_SCRIPTS_DIRECTORY) + strlen(script_name) + strlen(suffix) + 1]; + char script_path[strlen(userpath) + strlen(PM3_USER_DIRECTORY) + strlen(LUA_SCRIPTS_DIRECTORY) + strlen(script_name) + strlen(suffix) + 1]; strcpy(script_path, userpath); - strcat(script_path, LUA_PM3_USER_DIRECTORY); + strcat(script_path, PM3_USER_DIRECTORY); strcat(script_path, LUA_SCRIPTS_DIRECTORY); strcat(script_path, script_name); strcat(script_path, suffix); @@ -177,8 +177,8 @@ static int CmdScriptRun(const char *Cmd) { } } if (!found) { - char script_path[strlen(LUA_PM3_SYSTEM_DIRECTORY) + strlen(LUA_SCRIPTS_DIRECTORY) + strlen(script_name) + strlen(suffix) + 1]; - strcpy(script_path, LUA_PM3_SYSTEM_DIRECTORY); + char script_path[strlen(PM3_SYSTEM_DIRECTORY) + strlen(LUA_SCRIPTS_DIRECTORY) + strlen(script_name) + strlen(suffix) + 1]; + strcpy(script_path, PM3_SYSTEM_DIRECTORY); strcat(script_path, LUA_SCRIPTS_DIRECTORY); strcat(script_path, script_name); strcat(script_path, suffix); diff --git a/client/scripting.c b/client/scripting.c index a823df8d7..1f6c61ff8 100644 --- a/client/scripting.c +++ b/client/scripting.c @@ -1151,32 +1151,32 @@ int set_pm3_libraries(lua_State *L) { char *user_path = getenv("HOME"); if (user_path != NULL) { // from the ~/.proxmark3/luascripts/ directory - char scripts_path[strlen(user_path) + strlen(LUA_PM3_USER_DIRECTORY) + strlen(LUA_SCRIPTS_DIRECTORY) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; + char scripts_path[strlen(user_path) + strlen(PM3_USER_DIRECTORY) + strlen(LUA_SCRIPTS_DIRECTORY) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; strcpy(scripts_path, user_path); - strcat(scripts_path, LUA_PM3_USER_DIRECTORY); + strcat(scripts_path, PM3_USER_DIRECTORY); strcat(scripts_path, LUA_SCRIPTS_DIRECTORY); strcat(scripts_path, LUA_LIBRARIES_WILDCARD); setLuaPath(L, scripts_path); // from the ~/.proxmark3/lualib/ directory - char libraries_path[strlen(user_path) + strlen(LUA_PM3_USER_DIRECTORY) + strlen(LUA_LIBRARIES_DIRECTORY) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; + char libraries_path[strlen(user_path) + strlen(PM3_USER_DIRECTORY) + strlen(LUA_LIBRARIES_DIRECTORY) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; strcpy(libraries_path, user_path); - strcat(libraries_path, LUA_PM3_USER_DIRECTORY); + strcat(libraries_path, PM3_USER_DIRECTORY); strcat(libraries_path, LUA_LIBRARIES_DIRECTORY); strcat(libraries_path, LUA_LIBRARIES_WILDCARD); setLuaPath(L, libraries_path); } - if (strlen(LUA_PM3_SYSTEM_DIRECTORY) != 0 || strlen(LUA_SCRIPTS_DIRECTORY) != 0 || strlen(LUA_LIBRARIES_WILDCARD) != 0 ) { + if (strlen(PM3_SYSTEM_DIRECTORY) != 0 || strlen(LUA_SCRIPTS_DIRECTORY) != 0 || strlen(LUA_LIBRARIES_WILDCARD) != 0 ) { // from the /usr/local/share/proxmark3/luascripts/ directory - char scripts_path[strlen(LUA_PM3_SYSTEM_DIRECTORY) + strlen(LUA_SCRIPTS_DIRECTORY) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; - strcpy(scripts_path, LUA_PM3_SYSTEM_DIRECTORY); + char scripts_path[strlen(PM3_SYSTEM_DIRECTORY) + strlen(LUA_SCRIPTS_DIRECTORY) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; + strcpy(scripts_path, PM3_SYSTEM_DIRECTORY); strcat(scripts_path, LUA_SCRIPTS_DIRECTORY); strcat(scripts_path, LUA_LIBRARIES_WILDCARD); setLuaPath(L, scripts_path); // from the /usr/local/share/proxmark3/lualib/ directory - char libraries_path[strlen(LUA_PM3_SYSTEM_DIRECTORY) + strlen(LUA_LIBRARIES_DIRECTORY) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; - strcpy(libraries_path, LUA_PM3_SYSTEM_DIRECTORY); + char libraries_path[strlen(PM3_SYSTEM_DIRECTORY) + strlen(LUA_LIBRARIES_DIRECTORY) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; + strcpy(libraries_path, PM3_SYSTEM_DIRECTORY); strcat(libraries_path, LUA_LIBRARIES_DIRECTORY); strcat(libraries_path, LUA_LIBRARIES_WILDCARD); setLuaPath(L, libraries_path); diff --git a/client/scripting.h b/client/scripting.h index 12d6f1f0b..1a7b5a7e3 100644 --- a/client/scripting.h +++ b/client/scripting.h @@ -14,8 +14,6 @@ //#include //#include -#define LUA_PM3_SYSTEM_DIRECTORY "/usr/local/share/proxmark3/" -#define LUA_PM3_USER_DIRECTORY "/.proxmark3/" #define LUA_LIBRARIES_DIRECTORY "lualibs/" #define LUA_SCRIPTS_DIRECTORY "luascripts/" #define LUA_LIBRARIES_WILDCARD "?.lua" diff --git a/include/common.h b/include/common.h index f427cb221..d70bc484f 100644 --- a/include/common.h +++ b/include/common.h @@ -16,6 +16,12 @@ #include #include +#ifndef PREFIX +# define PREFIX "/usr/local/" +#endif +#define PM3_SYSTEM_DIRECTORY PREFIX "share/proxmark3/" +#define PM3_USER_DIRECTORY "/.proxmark3/" + #define PACKED __attribute__((packed)) // debug From 40b6956a22e4cf957259efe88c7a39f919aea3c6 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 22 Aug 2019 19:53:23 +0200 Subject: [PATCH 0409/1854] script list: print dir tree --- client/cmdscript.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/client/cmdscript.c b/client/cmdscript.c index 9fdc3c0af..90cd65532 100644 --- a/client/cmdscript.c +++ b/client/cmdscript.c @@ -56,18 +56,21 @@ static bool endsWith(const char *base, const char *str) { return (blen >= slen) && (0 == strcmp(base + blen - slen, str)); } -static int scriptlist(const char *path) { +static int scriptlist(const char *path, bool last) { struct dirent **namelist; int n; n = scandir(path, &namelist, NULL, alphasort); if (n == -1) { + PrintAndLogEx(NORMAL, "%s── %s => NOT FOUND", last ? "└" : "├", path); return PM3_EFILE; } + PrintAndLogEx(NORMAL, "%s── %s", last ? "└" : "├", path); for (uint16_t i = 0; i < n; i++) { - if (str_ends_with(namelist[i]->d_name, ".lua")) - PrintAndLogEx(NORMAL, "%-21s", namelist[i]->d_name); + if (str_ends_with(namelist[i]->d_name, ".lua")) { + PrintAndLogEx(NORMAL, "%s   %s── %-21s", last ? " ":"│", i == n-1 ? "└" : "├", namelist[i]->d_name); + } free(namelist[i]); } free(namelist); @@ -86,7 +89,7 @@ static int CmdScriptList(const char *Cmd) { char script_directory_path[strlen(get_my_executable_directory()) + strlen(LUA_SCRIPTS_DIRECTORY) + 1]; strcpy(script_directory_path, get_my_executable_directory()); strcat(script_directory_path, LUA_SCRIPTS_DIRECTORY); - scriptlist(script_directory_path); + scriptlist(script_directory_path, false); } char *userpath = getenv("HOME"); if (userpath != NULL) { @@ -94,13 +97,13 @@ static int CmdScriptList(const char *Cmd) { strcpy(script_directory_path, userpath); strcat(script_directory_path, PM3_USER_DIRECTORY); strcat(script_directory_path, LUA_SCRIPTS_DIRECTORY); - scriptlist(script_directory_path); + scriptlist(script_directory_path, false); } { char script_directory_path[strlen(PM3_SYSTEM_DIRECTORY) + strlen(LUA_SCRIPTS_DIRECTORY) + 1]; strcpy(script_directory_path, PM3_SYSTEM_DIRECTORY); strcat(script_directory_path, LUA_SCRIPTS_DIRECTORY); - scriptlist(script_directory_path); + scriptlist(script_directory_path, true); } return 0; } From 9825f521b45d84bb5d27022c791ae33bfba68f76 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 22 Aug 2019 21:05:45 +0200 Subject: [PATCH 0410/1854] Fix clang issue where generated .d are sometimes newer than .o --- Makefile.host | 4 +++- client/Makefile | 14 +++++++------- client/reveng/Makefile | 3 --- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/Makefile.host b/Makefile.host index e2d3b3f6f..5bf662d9a 100644 --- a/Makefile.host +++ b/Makefile.host @@ -10,6 +10,8 @@ RM = rm -f MV = mv CP = cp -a MKDIR = mkdir -p +TOUCH = touch +FALSE = false CFLAGS ?= -Wall -Werror -O3 CFLAGS += $(MYDEFS) $(MYCFLAGS) $(MYINCLUDES) @@ -31,7 +33,7 @@ vpath %.c $(MYSRCPATHS) # Flags to generate temporary dependency files DEPFLAGS = -MT $@ -MMD -MP -MF $(OBJDIR)/$*.Td # make temporary to final dependency files after successful compilation -POSTCOMPILE = $(MV) -f $(OBJDIR)/$*.Td $(OBJDIR)/$*.d +POSTCOMPILE = $(MV) -f $(OBJDIR)/$*.Td $(OBJDIR)/$*.d && $(TOUCH) $@ BINDIR := . OBJDIR := obj diff --git a/client/Makefile b/client/Makefile index 9711d29ed..e54e708e6 100644 --- a/client/Makefile +++ b/client/Makefile @@ -128,7 +128,7 @@ endif # Flags to generate temporary dependency files DEPFLAGS = -MT $@ -MMD -MP -MF $(OBJDIR)/$*.Td # make temporary to final dependency files after successful compilation -POSTCOMPILE = $(MV) -f $(OBJDIR)/$*.Td $(OBJDIR)/$*.d +POSTCOMPILE = $(MV) -f $(OBJDIR)/$*.Td $(OBJDIR)/$*.d && $(TOUCH) $@ CORESRCS = uart_posix.c \ uart_win32.c \ @@ -372,37 +372,37 @@ $(OBJDIR)/%_NOSIMD.o : %.c $(OBJDIR)/%_NOSIMD.d $(info [-] CC(NOSIMD) $<) $(Q)$(MKDIR) $(dir $@) $(Q)$(CC) $(DEPFLAGS:%.Td=%_NOSIMD.Td) $(PM3CFLAGS) $(HARD_SWITCH_NOSIMD) -c -o $@ $< - $(Q)$(MV) -f $(OBJDIR)/$*_NOSIMD.Td $(OBJDIR)/$*_NOSIMD.d + $(Q)$(MV) -f $(OBJDIR)/$*_NOSIMD.Td $(OBJDIR)/$*_NOSIMD.d && $(TOUCH) $@ $(OBJDIR)/%_MMX.o : %.c $(OBJDIR)/%_MMX.d $(info [-] CC(MMX) $<) $(Q)$(MKDIR) $(dir $@) $(Q)$(CC) $(DEPFLAGS:%.Td=%_MMX.Td) $(PM3CFLAGS) $(HARD_SWITCH_MMX) -c -o $@ $< - $(Q)$(MV) -f $(OBJDIR)/$*_MMX.Td $(OBJDIR)/$*_MMX.d + $(Q)$(MV) -f $(OBJDIR)/$*_MMX.Td $(OBJDIR)/$*_MMX.d && $(TOUCH) $@ $(OBJDIR)/%_SSE2.o : %.c $(OBJDIR)/%_SSE2.d $(info [-] CC(SSE2) $<) $(Q)$(MKDIR) $(dir $@) $(Q)$(CC) $(DEPFLAGS:%.Td=%_SSE2.Td) $(PM3CFLAGS) $(HARD_SWITCH_SSE2) -c -o $@ $< - $(Q)$(MV) -f $(OBJDIR)/$*_SSE2.Td $(OBJDIR)/$*_SSE2.d + $(Q)$(MV) -f $(OBJDIR)/$*_SSE2.Td $(OBJDIR)/$*_SSE2.d && $(TOUCH) $@ $(OBJDIR)/%_AVX.o : %.c $(OBJDIR)/%_AVX.d $(info [-] CC(AVX) $<) $(Q)$(MKDIR) $(dir $@) $(Q)$(CC) $(DEPFLAGS:%.Td=%_AVX.Td) $(PM3CFLAGS) $(HARD_SWITCH_AVX) -c -o $@ $< - $(Q)$(MV) -f $(OBJDIR)/$*_AVX.Td $(OBJDIR)/$*_AVX.d + $(Q)$(MV) -f $(OBJDIR)/$*_AVX.Td $(OBJDIR)/$*_AVX.d && $(TOUCH) $@ $(OBJDIR)/%_AVX2.o : %.c $(OBJDIR)/%_AVX2.d $(info [-] CC(AVX2) $<) $(Q)$(MKDIR) $(dir $@) $(Q)$(CC) $(DEPFLAGS:%.Td=%_AVX2.Td) $(PM3CFLAGS) $(HARD_SWITCH_AVX2) -c -o $@ $< - $(Q)$(MV) -f $(OBJDIR)/$*_AVX2.Td $(OBJDIR)/$*_AVX2.d + $(Q)$(MV) -f $(OBJDIR)/$*_AVX2.Td $(OBJDIR)/$*_AVX2.d && $(TOUCH) $@ $(OBJDIR)/%_AVX512.o : %.c $(OBJDIR)/%_AVX512.d $(info [-] CC(AVX512) $<) $(Q)$(MKDIR) $(dir $@) $(Q)$(CC) $(DEPFLAGS:%.Td=%_AVX512.Td) $(PM3CFLAGS) $(HARD_SWITCH_AVX512) -c -o $@ $< - $(Q)$(MV) -f $(OBJDIR)/$*_AVX512.Td $(OBJDIR)/$*_AVX512.d + $(Q)$(MV) -f $(OBJDIR)/$*_AVX512.Td $(OBJDIR)/$*_AVX512.d && $(TOUCH) $@ %.o: %.c $(OBJDIR)/%.o : %.c $(OBJDIR)/%.d diff --git a/client/reveng/Makefile b/client/reveng/Makefile index 52fd1bcec..c29538fa5 100644 --- a/client/reveng/Makefile +++ b/client/reveng/Makefile @@ -18,9 +18,6 @@ MYSRCS = \ LIB_A = libreveng.a -TOUCH = touch -FALSE = false - include ../../Makefile.host CLEAN += bmptst From 72392ab305a7bdee029279818c4f913bc9747f47 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 22 Aug 2019 21:18:14 +0200 Subject: [PATCH 0411/1854] fileutils: fix rel path to includes --- client/fileutils.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/fileutils.h b/client/fileutils.h index 74d54000b..79b053fc2 100644 --- a/client/fileutils.h +++ b/client/fileutils.h @@ -46,8 +46,8 @@ #include #include #include -#include "../ui.h" -#include "../emv/emvjson.h" +#include "ui.h" +#include "emv/emvjson.h" #include "mifare/mifare4.h" #include "cmdhfmfu.h" From 915c200ebcd8903652ef7b867e0f89568ac00529 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 22 Aug 2019 21:18:37 +0200 Subject: [PATCH 0412/1854] luascript: use fileExists --- client/cmdscript.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/client/cmdscript.c b/client/cmdscript.c index 90cd65532..eb7979a00 100644 --- a/client/cmdscript.c +++ b/client/cmdscript.c @@ -26,6 +26,7 @@ #include "lauxlib.h" #include "proxmark3.h" #include "ui.h" +#include "fileutils.h" #ifdef _WIN32 #include "scandir.h" @@ -153,10 +154,8 @@ static int CmdScriptRun(const char *Cmd) { strcat(script_path, LUA_SCRIPTS_DIRECTORY); strcat(script_path, script_name); strcat(script_path, suffix); - FILE *file; - if ((file = fopen(script_path, "r"))) + if (fileExists(script_path)) { - fclose(file); PrintAndLogEx(SUCCESS, "Executing: %s, args '%s'\n", script_path, arguments); found = true; error = luaL_loadfile(lua_state, script_path); @@ -170,10 +169,8 @@ static int CmdScriptRun(const char *Cmd) { strcat(script_path, LUA_SCRIPTS_DIRECTORY); strcat(script_path, script_name); strcat(script_path, suffix); - FILE *file; - if ((file = fopen(script_path, "r"))) + if (fileExists(script_path)) { - fclose(file); PrintAndLogEx(SUCCESS, "Executing: %s, args '%s'\n", script_path, arguments); found = true; error = luaL_loadfile(lua_state, script_path); @@ -185,10 +182,8 @@ static int CmdScriptRun(const char *Cmd) { strcat(script_path, LUA_SCRIPTS_DIRECTORY); strcat(script_path, script_name); strcat(script_path, suffix); - FILE *file; - if ((file = fopen(script_path, "r"))) + if (fileExists(script_path)) { - fclose(file); PrintAndLogEx(SUCCESS, "Executing: %s, args '%s'\n", script_path, arguments); found = true; error = luaL_loadfile(lua_state, script_path); From 23044c00d065c3d04fa42f402d52ac49362c80b1 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 22 Aug 2019 22:16:33 +0200 Subject: [PATCH 0413/1854] rename and move dict files --- .gitignore | 2 +- client/Makefile | 7 ++++--- client/cmdflashmem.c | 6 +++--- client/cmdhficlass.c | 8 ++++---- client/cmdlft55xx.c | 2 +- .../iclass_default_keys.dic} | 0 .../mfc_default_keys.dic} | 2 +- .../{bmp_sort_keys.dic => mfc_keys_bmp_sorted.dic} | 0 ...bpm_sort_keys.dic => mfc_keys_icbmp_sorted.dic} | 0 ...mrzd_sort_keys.dic => mfc_keys_mrzd_sorted.dic} | 0 .../mfulc_default_keys.dic} | 0 .../t55xx_default_pwds.dic} | 0 client/luascripts/{mfkeys.lua => mfckeys.lua} | 10 +++++----- client/scripting.c | 2 +- doc/cheatsheet.md | 14 +++++++------- .../2_Configuration-and-Verification.md | 6 +++--- 16 files changed, 30 insertions(+), 29 deletions(-) rename client/{default_iclass_keys.dic => dictionaries/iclass_default_keys.dic} (100%) rename client/{default_keys.dic => dictionaries/mfc_default_keys.dic} (99%) rename client/dictionaries/{bmp_sort_keys.dic => mfc_keys_bmp_sorted.dic} (100%) rename client/dictionaries/{icbpm_sort_keys.dic => mfc_keys_icbmp_sorted.dic} (100%) rename client/dictionaries/{mrzd_sort_keys.dic => mfc_keys_mrzd_sorted.dic} (100%) rename client/{default_ultralight_keys.dic => dictionaries/mfulc_default_keys.dic} (100%) rename client/{default_pwd.dic => dictionaries/t55xx_default_pwds.dic} (100%) rename client/luascripts/{mfkeys.lua => mfckeys.lua} (96%) diff --git a/.gitignore b/.gitignore index f61e85eb9..5b45564b3 100644 --- a/.gitignore +++ b/.gitignore @@ -71,7 +71,7 @@ tools/jtag_openocd/openocd_configuration ppls patches/* *- Copy.* -client/lualibs/mf_default_keys.lua +client/lualibs/mfc_default_keys.lua client/lualibs/pm3_cmd.lua # recompiled fpga_version_info.c diff --git a/client/Makefile b/client/Makefile index e54e708e6..f33c1ae9e 100644 --- a/client/Makefile +++ b/client/Makefile @@ -32,6 +32,7 @@ platform = $(shell uname) ROOT_DIR:=$(dir $(realpath $(lastword $(MAKEFILE_LIST)))) VPATH = ../common uart +vpath %.dic dictionaries OBJDIR = obj LDLIBS ?= -L/usr/local/lib @@ -290,7 +291,7 @@ ifeq "$(SUPPORTS_AVX512)" "True" endif BINS = proxmark3 flasher -CLEAN = $(BINS) *.moc.cpp ui/ui_overlays.h lualibs/pm3_cmd.lua lualibs/mf_default_keys.lua +CLEAN = $(BINS) *.moc.cpp ui/ui_overlays.h lualibs/pm3_cmd.lua lualibs/mfc_default_keys.lua # need to assign dependancies to build these first... all: $(BINS) @@ -299,7 +300,7 @@ all-static: LDLIBS:=-static $(LDLIBS) all-static: $(BINS) proxmark3: LDLIBS+=$(LUALIB) $(JANSSONLIB) $(MBEDTLSLIB) $(CBORLIB) $(ZLIB) $(REVENGLIB) $(QTLDLIBS) -proxmark3: $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(LUALIB) $(JANSSONLIB) $(CBORLIB) $(REVENGLIB) $(MBEDTLSLIB) $(ZLIB) lualibs/pm3_cmd.lua lualibs/mf_default_keys.lua +proxmark3: $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(LUALIB) $(JANSSONLIB) $(CBORLIB) $(REVENGLIB) $(MBEDTLSLIB) $(ZLIB) lualibs/pm3_cmd.lua lualibs/mfc_default_keys.lua $(info [=] LD $@) $(Q)$(LD) $(LDFLAGS) $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(LDLIBS) -o $@ @@ -321,7 +322,7 @@ lualibs/pm3_cmd.lua: ../include/pm3_cmd.h $(info [=] GEN $@) $(Q)awk -f pm3_cmd_h2lua.awk $^ > $@ -lualibs/mf_default_keys.lua : default_keys.dic +lualibs/mfc_default_keys.lua : mfc_default_keys.dic $(info [=] GEN $@) $(Q)awk -f default_keys_dic2lua.awk $^ > $@ diff --git a/client/cmdflashmem.c b/client/cmdflashmem.c index a89d2eae6..905e6c6c8 100644 --- a/client/cmdflashmem.c +++ b/client/cmdflashmem.c @@ -59,9 +59,9 @@ static int usage_flashmem_load(void) { PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " mem load f myfile"); // upload file myfile at default offset 0 PrintAndLogEx(NORMAL, " mem load f myfile o 1024"); // upload file myfile at offset 1024 - PrintAndLogEx(NORMAL, " mem load f default_keys m"); - PrintAndLogEx(NORMAL, " mem load f default_pwd t"); - PrintAndLogEx(NORMAL, " mem load f default_iclass_keys i"); + PrintAndLogEx(NORMAL, " mem load f dictionaries/mfc_default_keys m"); + PrintAndLogEx(NORMAL, " mem load f dictionaries/t55xx_default_pwds t"); + PrintAndLogEx(NORMAL, " mem load f dictionaries/iclass_default_keys i"); return PM3_SUCCESS; } static int usage_flashmem_dump(void) { diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 3cbbd1a67..4b815355b 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -244,8 +244,8 @@ static int usage_hf_iclass_chk(void) { PrintAndLogEx(NORMAL, " e elite"); PrintAndLogEx(NORMAL, " c credit key (if not use, default is debit)"); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf iclass chk f default_iclass_keys.dic"); - PrintAndLogEx(NORMAL, " hf iclass chk f default_iclass_keys.dic e"); + PrintAndLogEx(NORMAL, " hf iclass chk f dictionaries/iclass_default_keys.dic"); + PrintAndLogEx(NORMAL, " hf iclass chk f dictionaries/iclass_default_keys.dic e"); return 0; } static int usage_hf_iclass_lookup(void) { @@ -260,8 +260,8 @@ static int usage_hf_iclass_lookup(void) { PrintAndLogEx(NORMAL, " r raw"); PrintAndLogEx(NORMAL, " e elite"); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf iclass lookup u 9655a400f8ff12e0 p f0ffffffffffffff m 0000000089cb984b f default_iclass_keys.dic"); - PrintAndLogEx(NORMAL, " hf iclass lookup u 9655a400f8ff12e0 p f0ffffffffffffff m 0000000089cb984b f default_iclass_keys.dic e"); + PrintAndLogEx(NORMAL, " hf iclass lookup u 9655a400f8ff12e0 p f0ffffffffffffff m 0000000089cb984b f dictionaries/iclass_default_keys.dic"); + PrintAndLogEx(NORMAL, " hf iclass lookup u 9655a400f8ff12e0 p f0ffffffffffffff m 0000000089cb984b f dictionaries/iclass_default_keys.dic e"); return 0; } static int usage_hf_iclass_permutekey(void) { diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 3c88a23ea..058645320 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -206,7 +206,7 @@ static int usage_t55xx_chk() { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx chk m"); - PrintAndLogEx(NORMAL, " lf t55xx chk i default_pwd.dic"); + PrintAndLogEx(NORMAL, " lf t55xx chk i dictionaries/t55xx_default_pwds.dic"); PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } diff --git a/client/default_iclass_keys.dic b/client/dictionaries/iclass_default_keys.dic similarity index 100% rename from client/default_iclass_keys.dic rename to client/dictionaries/iclass_default_keys.dic diff --git a/client/default_keys.dic b/client/dictionaries/mfc_default_keys.dic similarity index 99% rename from client/default_keys.dic rename to client/dictionaries/mfc_default_keys.dic index 54c355de4..c33736806 100644 --- a/client/default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -22,7 +22,7 @@ a0478cc39091, # d2ece8b9395e, //lib # -# more Keys from mf_default_keys.lua +# more Keys from mfc_default_keys.lua 000000000001, 000000000002, 00000000000a, diff --git a/client/dictionaries/bmp_sort_keys.dic b/client/dictionaries/mfc_keys_bmp_sorted.dic similarity index 100% rename from client/dictionaries/bmp_sort_keys.dic rename to client/dictionaries/mfc_keys_bmp_sorted.dic diff --git a/client/dictionaries/icbpm_sort_keys.dic b/client/dictionaries/mfc_keys_icbmp_sorted.dic similarity index 100% rename from client/dictionaries/icbpm_sort_keys.dic rename to client/dictionaries/mfc_keys_icbmp_sorted.dic diff --git a/client/dictionaries/mrzd_sort_keys.dic b/client/dictionaries/mfc_keys_mrzd_sorted.dic similarity index 100% rename from client/dictionaries/mrzd_sort_keys.dic rename to client/dictionaries/mfc_keys_mrzd_sorted.dic diff --git a/client/default_ultralight_keys.dic b/client/dictionaries/mfulc_default_keys.dic similarity index 100% rename from client/default_ultralight_keys.dic rename to client/dictionaries/mfulc_default_keys.dic diff --git a/client/default_pwd.dic b/client/dictionaries/t55xx_default_pwds.dic similarity index 100% rename from client/default_pwd.dic rename to client/dictionaries/t55xx_default_pwds.dic diff --git a/client/luascripts/mfkeys.lua b/client/luascripts/mfckeys.lua similarity index 96% rename from client/luascripts/mfkeys.lua rename to client/luascripts/mfckeys.lua index f15bb6d5e..128967c37 100644 --- a/client/luascripts/mfkeys.lua +++ b/client/luascripts/mfckeys.lua @@ -9,7 +9,7 @@ Copyright (C) 2013 m h swende --]] local cmds = require('commands') -local keylist = require('mf_default_keys') +local keylist = require('mfc_default_keys') local lib14a = require('read14a') local getopt = require('getopt') local utils = require('utils') @@ -19,9 +19,9 @@ author = "Holiman" version = 'v1.0.1' desc = ("This script implements Mifare check keys.\ It utilises a large list of default keys (currently %d keys).\ -If you want to add more, just put them inside /lualibs/mf_default_keys.lua\n"):format(#keylist) +If you want to add more, just put them inside /lualibs/mfc_default_keys.lua\n"):format(#keylist) example = [[ - 1. script run mfkeys + 1. script run mfckeys ]] usage = [[ Arguments: @@ -54,7 +54,7 @@ end -- waits for answer from pm3 device local function checkCommand(response) if not response then - print("Timeout while waiting for response. Increase TIMEOUT in mfkeys.lua to wait longer") + print("Timeout while waiting for response. Increase TIMEOUT in mfckeys.lua to wait longer") return nil, "Timeout while waiting for device to respond" end @@ -230,7 +230,7 @@ local function perform_check(numsectors) local end_time = os.time() print('') - print('[+] mfkeys - Checkkey execution time: '..os.difftime(end_time, start_time)..' sec') + print('[+] mfckeys - Checkkey execution time: '..os.difftime(end_time, start_time)..' sec') core.fast_push_mode(false) diff --git a/client/scripting.c b/client/scripting.c index 1f6c61ff8..596b535fa 100644 --- a/client/scripting.c +++ b/client/scripting.c @@ -50,7 +50,7 @@ static int l_clearCommandBuffer(lua_State *L) { } /** - * Enable / Disable fast push mode for lua scripts like mfkeys + * Enable / Disable fast push mode for lua scripts like mfckeys * The following params expected: * *@brief l_fast_push_mode diff --git a/doc/cheatsheet.md b/doc/cheatsheet.md index f143438c4..75c554e94 100644 --- a/doc/cheatsheet.md +++ b/doc/cheatsheet.md @@ -166,7 +166,7 @@ p : EPURSE m : macs e : elite -pm3 --> hf iclass lookup u 010a0ffff7ff12e0 p feffffffffffffff m 66348979153c41b9 f default_iclass_keys.dic e +pm3 --> hf iclass lookup u 010a0ffff7ff12e0 p feffffffffffffff m 66348979153c41b9 f dictionaries/iclass_default_keys.dic e ``` ## Mifare @@ -181,7 +181,7 @@ Options card memory : 0 - MINI(320 bytes), 1 - 1K, 2 - 2K, 4 - 4K d : write keys to binary file -pm3 --> hf mf chk *1 ? d default_keys.dic +pm3 --> hf mf chk *1 ? d dictionaries/mfc_default_keys.dic ``` Check for default keys from local memory @@ -254,7 +254,7 @@ pm3 --> hf mf sim u 353c2aa6 Simulate Mifare Sequence ``` -pm3 --> hf mf chk *1 ? d default_keys.dic +pm3 --> hf mf chk *1 ? d dictionaries/mfc_default_keys.dic pm3 --> hf mf dump 1 pm3 --> script run dumptoemul -i dumpdata.bin pm3 --> hf mf eload 353C2AA6 @@ -263,7 +263,7 @@ pm3 --> hf mf sim u 353c2aa6 Clone Mifare 1K Sequence ``` -pm3 --> hf mf chk *1 ? d default_keys.dic +pm3 --> hf mf chk *1 ? d dictionaries/mfc_default_keys.dic pm3 --> hf mf dump pm3 --> hf mf restore 1 u 4A6CE843 k hf-mf-A29558E4-key.bin f hf-mf-A29558E4-data.bin ``` @@ -512,9 +512,9 @@ m : upload 6 bytes keys (mifare key dictionary) i : upload 8 bytes keys (iClass key dictionary) t : upload 4 bytes keys (pwd dictionary) -pm3 --> mem load f default_keys m -pm3 --> mem load f default_pwd t -pm3 --> mem load f default_iclass_keys i +pm3 --> mem load f dictionaries/mfc_default_keys m +pm3 --> mem load f dictionaries/t55xx_default_pwds t +pm3 --> mem load f dictionaries/iclass_default_keys i ``` ## Sim Module diff --git a/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md b/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md index 0d3665f37..84f64821c 100644 --- a/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md +++ b/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md @@ -1,9 +1,9 @@ ### First things on your RDV40 You will need to run these commands to make sure your rdv4 is prepared ``` -pm3 --> mem load f default_keys m -pm3 --> mem load f default_pwd t -pm3 --> mem load f default_iclass_keys i +pm3 --> mem load f dictionaries/mfc_default_keys m +pm3 --> mem load f dictionaries/t55xx_default_pwds t +pm3 --> mem load f dictionaries/iclass_default_keys i pm3 --> lf t55xx deviceconfig a 29 b 17 c 15 d 47 e 15 p pm3 --> lf t55xx deviceconfig r 1 a 31 b 20 c 18 d 50 e 15 p pm3 --> lf t55xx deviceconfig r 2 a 31 b 20 c 18 d 40 e 15 p From 77c86099cc19a9ae974dc8b3984c6031b24df248 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 22 Aug 2019 22:58:16 +0200 Subject: [PATCH 0414/1854] clean and uniformise dic files --- client/dictionaries/iclass_default_keys.dic | 15 +- client/dictionaries/mfc_default_keys.dic | 1584 ++++++------- client/dictionaries/mfc_keys_bmp_sorted.dic | 2000 ++++++++-------- client/dictionaries/mfc_keys_icbmp_sorted.dic | 2001 ++++++++--------- client/dictionaries/mfc_keys_mrzd_sorted.dic | 114 +- client/dictionaries/mfulc_default_keys.dic | 3 +- client/dictionaries/t55xx_default_pwds.dic | 222 +- 7 files changed, 2970 insertions(+), 2969 deletions(-) diff --git a/client/dictionaries/iclass_default_keys.dic b/client/dictionaries/iclass_default_keys.dic index 829ba521e..22e1ee653 100644 --- a/client/dictionaries/iclass_default_keys.dic +++ b/client/dictionaries/iclass_default_keys.dic @@ -2,10 +2,11 @@ # iClass Default Keys # -- iceman fork version -- # -- contribute to this list, sharing is caring -- -AEA684A6DAB23278 -- AA1 -7665544332211000 -- key1/Kc from PicoPass 2k documentation -0123456789ABCDEF -- SAGEM -5b7c62c491c11b39 -- from loclass demo file. -F0E1D2C3B4A59687 -- Kd from PicoPass 2k documentation -5CBCF1DA45D5FB4F -- PicoPass Default Exchange Key -31ad7ebd2f282168 -- From HID multiclassSE reader +# +AEA684A6DAB23278 # AA1 +7665544332211000 # key1/Kc from PicoPass 2k documentation +0123456789ABCDEF # SAGEM +5b7c62c491c11b39 # from loclass demo file. +F0E1D2C3B4A59687 # Kd from PicoPass 2k documentation +5CBCF1DA45D5FB4F # PicoPass Default Exchange Key +31ad7ebd2f282168 # From HID multiclassSE reader diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index c33736806..4b1430c2f 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -3,922 +3,922 @@ # -- iceman fork version -- # -- contribute to this list, sharing is caring -- # -ffffffffffff,//Defaultkey(firstkeyusedbyprogramifnouserdefinedkey) -000000000000,//Blankkey -a0a1a2a3a4a5,//NFCForumMADkey -b0b1b2b3b4b5, -c0c1c2c3c4c5, -d0d1d2d3d4d5, -aabbccddeeff, -4d3a99c351dd, -1a982c7e459a, -d3f7d3f7d3f7,// key A Wien -5a1b85fce20a,// key B Wien -714c5c886e97, -587ee5f9350f, -a0478cc39091, -533cb6c723f6, -8fd0a4f256e9, +ffffffffffff # Defaultkey(firstkeyusedbyprogramifnouserdefinedkey) +000000000000 # Blankkey +a0a1a2a3a4a5 # NFCForumMADkey +b0b1b2b3b4b5 +c0c1c2c3c4c5 +d0d1d2d3d4d5 +aabbccddeeff +4d3a99c351dd +1a982c7e459a +d3f7d3f7d3f7 # key A Wien +5a1b85fce20a # key B Wien +714c5c886e97 +587ee5f9350f +a0478cc39091 +533cb6c723f6 +8fd0a4f256e9 # -d2ece8b9395e, //lib +d2ece8b9395e # lib # # more Keys from mfc_default_keys.lua -000000000001, -000000000002, -00000000000a, -00000000000b, -00000ffe2488,--VästtrafikenKeyB -010203040506, -0123456789ab, -0297927c0f77,--VästtrafikenKeyA -100000000000, -111111111111, -123456789abc, -12f2ee3478c1, -14d446e33363, -1999a3554a55, -200000000000, -222222222222, -26940b21ff5d,--RKFSLKeyA -27dd91f1fcf1, -2BA9621E0A36,--DirectoryandeventlogKeyB -333333333333, -33f974b42769, -34d1df9934c5, -434f4d4d4f41,--RKFJOJOGROUPKeyA -434f4d4d4f42,--RKFJOJOGROUPKeyB -43ab19ef5c31, -444444444444, -47524f555041,--RKFJOJOGROUPKeyA -47524f555042,--RKFJOJOGROUPKeyB -4AF9D7ADEBE4,--DirectoryandeventlogKeyA -4b0b20107ccb,--TNP3xxx -505249564141,--RKFJOJOPRIVAKeyA -505249564142,--RKFJOJOPRIVAKeyB -505249565441, -505249565442, -54726176656c,--VästtrafikenKeyA -555555555555, -55f5a5dd38c9, -569369c5a0e5,--kiev -5c598c9c58b5,--RKFSLKeyB -632193be1c3c,--kiev -644672bd4afe,--kiev -666666666666, -722bfcc5375f,--RKFRejskortDanmarkKeyA -776974687573,--VästtrafikenKeyB -777777777777, -888888888888, -8fe644038790,--kiev -999999999999, -99c636334433, -9de89e070277,--kiev -a00000000000, -a053a292a4af, -a64598a77478,--RKFSLKeyA -a94133013401, -aaaaaaaaaaaa, -abcdef123456,--Keyfromladyada.net -b00000000000, -b127c6f41436, -b5ff67cba951,--kiev -bbbbbbbbbbbb, -bd493a3962b6, -c934fe34d934, -cccccccccccc, -dddddddddddd, -e4d2770a89be,--RKFSLKeyB -ee0042f88840,--VästtrafikenKeyB -eeeeeeeeeeee, -eff603e1efe9,--kiev -f14ee7cae863,--kiev -f1a97341a9fc, -f1d83f964314,--RKFRejskortDanmarkKeyB -fc00018778f7,--VästtrafikenKeyA, RKFÖstgötaTrafikenKeyA -44ab09010845,-- hotel system -85fed980ea5a,-- hotel system -314B49474956 --VIGIK1 A -564c505f4d41 --VIGIK1 B -ba5b895da162 --VIGIK1 B +000000000001 +000000000002 +00000000000a +00000000000b +00000ffe2488 # VästtrafikenKeyB +010203040506 +0123456789ab +0297927c0f77 # VästtrafikenKeyA +100000000000 +111111111111 +123456789abc +12f2ee3478c1 +14d446e33363 +1999a3554a55 +200000000000 +222222222222 +26940b21ff5d # RKFSLKeyA +27dd91f1fcf1 +2BA9621E0A36 # DirectoryandeventlogKeyB +333333333333 +33f974b42769 +34d1df9934c5 +434f4d4d4f41 # RKFJOJOGROUPKeyA +434f4d4d4f42 # RKFJOJOGROUPKeyB +43ab19ef5c31 +444444444444 +47524f555041 # RKFJOJOGROUPKeyA +47524f555042 # RKFJOJOGROUPKeyB +4AF9D7ADEBE4 # DirectoryandeventlogKeyA +4b0b20107ccb # TNP3xxx +505249564141 # RKFJOJOPRIVAKeyA +505249564142 # RKFJOJOPRIVAKeyB +505249565441 +505249565442 +54726176656c # VästtrafikenKeyA +555555555555 +55f5a5dd38c9 +569369c5a0e5 # kiev +5c598c9c58b5 # RKFSLKeyB +632193be1c3c # kiev +644672bd4afe # kiev +666666666666 +722bfcc5375f # RKFRejskortDanmarkKeyA +776974687573 # VästtrafikenKeyB +777777777777 +888888888888 +8fe644038790 # kiev +999999999999 +99c636334433 +9de89e070277 # kiev +a00000000000 +a053a292a4af +a64598a77478 # RKFSLKeyA +a94133013401 +aaaaaaaaaaaa +abcdef123456 # Keyfromladyada.net +b00000000000 +b127c6f41436 +b5ff67cba951 # kiev +bbbbbbbbbbbb +bd493a3962b6 +c934fe34d934 +cccccccccccc +dddddddddddd +e4d2770a89be # RKFSLKeyB +ee0042f88840 # VästtrafikenKeyB +eeeeeeeeeeee +eff603e1efe9 # kiev +f14ee7cae863 # kiev +f1a97341a9fc +f1d83f964314 # RKFRejskortDanmarkKeyB +fc00018778f7 # VästtrafikenKeyA, RKFÖstgötaTrafikenKeyA +44ab09010845 # hotel system +85fed980ea5a # hotel system +314B49474956 # VIGIK1 A +564c505f4d41 # VIGIK1 B +ba5b895da162 # VIGIK1 B # Vigik mystery Keys Mifare 1k EV1 (S50) -5c8ff9990da2, 16 A -75ccb59c9bed, 17 A -d01afeeb890a, 16 B -4b791bea7bcc, 17 B +5c8ff9990da2 # 16 A +75ccb59c9bed # 17 A +d01afeeb890a # 16 B +4b791bea7bcc # 17 B # -4143414F5250, -a9b43414F585,--Tehran Railway -1FB235AC1388,--Tehran Railway +4143414F5250 +a9b43414F585 # Tehran Railway +1FB235AC1388 # Tehran Railway # -# Data from: http://irq5.io/2013/04/13/decoding-bcard-conference-badges/ -f4a9ef2afc6d,--BCARD KeyB +# Data from http://irq5.io/2013/04/13/decoding-bcard-conference-badges/ +f4a9ef2afc6d # BCARD KeyB # -# Data from: ... -89eac97f8c2a // S0 B -43c7600dee6b // S4 A -0120bf672a64 // S6 A -fb0b20df1f34 // S6 B +# Data from ... +89eac97f8c2a # S0 B +43c7600dee6b # S4 A +0120bf672a64 # S6 A +fb0b20df1f34 # S6 B # -a9f953def0a3, +a9f953def0a3 # # Here be BIP keys... -3A42F33AF429, -1FC235AC1309, -6338A371C0ED, -243F160918D1, -F124C2578AD0, -9AFC42372AF1, -32AC3B90AC13, -682D401ABB09, -4AD1E273EAF1, -067DB45454A9, -E2C42591368A, -15FC4C7613FE, -2A3C347A1200, -68D30288910A, -16F3D5AB1139, -F59A36A2546D, -937A4FFF3011, -64E3C10394C2, -35C3D2CAEE88, -B736412614AF, -693143F10368, -324F5DF65310, -A3F97428DD01, -643FB6DE2217, -63F17A449AF0, -82F435DEDF01, -C4652C54261C, -0263DE1278F3, -D49E2826664F, -51284C3686A6, -3DF14C8000A1, -6A470D54127C, +3A42F33AF429 +1FC235AC1309 +6338A371C0ED +243F160918D1 +F124C2578AD0 +9AFC42372AF1 +32AC3B90AC13 +682D401ABB09 +4AD1E273EAF1 +067DB45454A9 +E2C42591368A +15FC4C7613FE +2A3C347A1200 +68D30288910A +16F3D5AB1139 +F59A36A2546D +937A4FFF3011 +64E3C10394C2 +35C3D2CAEE88 +B736412614AF +693143F10368 +324F5DF65310 +A3F97428DD01 +643FB6DE2217 +63F17A449AF0 +82F435DEDF01 +C4652C54261C +0263DE1278F3 +D49E2826664F +51284C3686A6 +3DF14C8000A1 +6A470D54127C # -# Data from: http://pastebin.com/AK9Bftpw -48ffe71294a0, -- Länstrafiken i Västerbotten -e3429281efc1, -- Länstrafiken i Västerbotten -16f21a82ec84, -- Länstrafiken i Västerbotten -460722122510, -- Länstrafiken i Västerbotten +# Data from http://pastebin.com/AK9Bftpw +48ffe71294a0 # Länstrafiken i Västerbotten +e3429281efc1 # Länstrafiken i Västerbotten +16f21a82ec84 # Länstrafiken i Västerbotten +460722122510 # Länstrafiken i Västerbotten # # 3dprinter -AAFB06045877, --EPI Envisionte# 3dprinter +AAFB06045877 # EPI Envisionte# 3dprinter # # gym -3e65e4fb65b3, --Fysiken A -25094df6f148, --Fysiken B -a05dbd98e0fc, -- CleverFit +3e65e4fb65b3 # Fysiken A +25094df6f148 # Fysiken B +a05dbd98e0fc # CleverFit # -d3b595e9dd63, -- Hotel KeyCard -afbecd121004, -- Hotel KeyCard -6471a5ef2d1a, -- SimonsVoss +d3b595e9dd63 # Hotel KeyCard +afbecd121004 # Hotel KeyCard +6471a5ef2d1a # SimonsVoss # # 24-7 -D21762B2DE3B, -0E83A374B513, -1F1FFE000000, -A10F303FC879, -1322285230b8, -0C71BCFB7E72, -C3C88C6340B8, -F101622750B7, -1F107328DC8D, -710732200D34, -7C335FB121B5, -B39AE17435DC, +D21762B2DE3B +0E83A374B513 +1F1FFE000000 +A10F303FC879 +1322285230b8 +0C71BCFB7E72 +C3C88C6340B8 +F101622750B7 +1F107328DC8D +710732200D34 +7C335FB121B5 +B39AE17435DC # # -454841585443, -- key A +454841585443 # key A # -# Data from: http://pastebin.com/gQ6nk38G -D39BB83F5297, -85675B200017, -528C9DFFE28C, -C82EC29E3235, -3E3554AF0E12, -491CDCFB7752, -22C1BAE1AACD, -5F146716E373, -740E9A4F9AAF, -AC0E24C75527, -97184D136233, -E444D53D359F, -17758856B182, -A8966C7CC54B, -C6AD00254562, -AE3FF4EEA0DB, -5EB8F884C8D1, -FEE470A4CB58, -75D8690F21B6, -871B8C085997, -97D1101F18B0, -75EDE6A84460, -DF27A8F1CB8E, -B0C9DD55DD4D, +# Data from http://pastebin.com/gQ6nk38G +D39BB83F5297 +85675B200017 +528C9DFFE28C +C82EC29E3235 +3E3554AF0E12 +491CDCFB7752 +22C1BAE1AACD +5F146716E373 +740E9A4F9AAF +AC0E24C75527 +97184D136233 +E444D53D359F +17758856B182 +A8966C7CC54B +C6AD00254562 +AE3FF4EEA0DB +5EB8F884C8D1 +FEE470A4CB58 +75D8690F21B6 +871B8C085997 +97D1101F18B0 +75EDE6A84460 +DF27A8F1CB8E +B0C9DD55DD4D # -# Data from: http://bit.ly/1bdSbJl -A0B0C0D0E0F0, -A1B1C1D1E1F1, +# Data from http://bit.ly/1bdSbJl +A0B0C0D0E0F0 +A1B1C1D1E1F1 # -# Data from: msk social -2735fc181807, -2aba9519f574, -84fd7f7a12b6, -186d8c4b93f9, -3a4bba8adaf0, -8765b17968a2, -40ead80721ce, -0db5e6523f7c, -51119dae5216, -83e3549ce42d, -136bdb246cac, -7de02a7f6025, -bf23a53c1f63, -cb9a1f2d7368, -c7c0adb3284f, -9f131d8c2057, -67362d90f973, -6202a38f69e2, -100533b89331, -653a87594079, -d8a274b2e026, -b20b83cb145c, -9afa6cb4fc3d, +# Data from msk social +2735fc181807 +2aba9519f574 +84fd7f7a12b6 +186d8c4b93f9 +3a4bba8adaf0 +8765b17968a2 +40ead80721ce +0db5e6523f7c +51119dae5216 +83e3549ce42d +136bdb246cac +7de02a7f6025 +bf23a53c1f63 +cb9a1f2d7368 +c7c0adb3284f +9f131d8c2057 +67362d90f973 +6202a38f69e2 +100533b89331 +653a87594079 +d8a274b2e026 +b20b83cb145c +9afa6cb4fc3d # # Data from http://pastebin.com/RRJUEDCM -0d258fe90296, -e55a3ca71826, -a4f204203f56, -eeb420209d0c, -911e52fd7ce4, -752fbb5b7b45, -66b03aca6ee9, -48734389edc3, -17193709adf4, -1acc3189578c, -c2b7ec7d4eb1, -369a4663acd2, +0d258fe90296 +e55a3ca71826 +a4f204203f56 +eeb420209d0c +911e52fd7ce4 +752fbb5b7b45 +66b03aca6ee9 +48734389edc3 +17193709adf4 +1acc3189578c +c2b7ec7d4eb1 +369a4663acd2 # # Data from https://github.com/zhangjingye03/zxcardumper # zxcard Key A/B -668770666644, -003003003003, +668770666644 +003003003003 # -# Data from: http://phreakerclub.com/forum/showthread.php?p=41266 -26973ea74321, -71f3a315ad26, -51044efb5aab, -ac70ca327a04, -eb0a8ff88ade, +# Data from http://phreakerclub.com/forum/showthread.php?p=41266 +26973ea74321 +71f3a315ad26 +51044efb5aab +ac70ca327a04 +eb0a8ff88ade # -# Data from: https://github.com/RadioWar/NFCGUI -44dd5a385aaf, -21a600056cb0, -b1aca33180a5, -dd61eb6bce22, -1565a172770f, -3e84d2612e2a, -f23442436765, -79674f96c771, -87df99d496cb, -c5132c8980bc, -a21680c27773, -f26e21edcee2, -675557ecc92e, -f4396e468114, -6db17c16b35b, -4186562a5bb2, -2feae851c199, -db1a3338b2eb, -157b10d84c6b, -a643f952ea57, -df37dcb6afb3, -4c32baf326e0, -91ce16c07ac5, -3c5d1c2bcd18, -c3f19ec592a2, -f72a29005459, -185fa3438949, -321a695bd266, -d327083a60a7, -45635ef66ef3, -5481986d2d62, -cba6ae869ad5, -645a166b1eeb, -a7abbc77cc9e, -f792c4c76a5c, -bfb6796a11db, +# Data from https://github.com/RadioWar/NFCGUI +44dd5a385aaf +21a600056cb0 +b1aca33180a5 +dd61eb6bce22 +1565a172770f +3e84d2612e2a +f23442436765 +79674f96c771 +87df99d496cb +c5132c8980bc +a21680c27773 +f26e21edcee2 +675557ecc92e +f4396e468114 +6db17c16b35b +4186562a5bb2 +2feae851c199 +db1a3338b2eb +157b10d84c6b +a643f952ea57 +df37dcb6afb3 +4c32baf326e0 +91ce16c07ac5 +3c5d1c2bcd18 +c3f19ec592a2 +f72a29005459 +185fa3438949 +321a695bd266 +d327083a60a7 +45635ef66ef3 +5481986d2d62 +cba6ae869ad5 +645a166b1eeb +a7abbc77cc9e +f792c4c76a5c +bfb6796a11db # # Data from Salto A/B -6A1987C40A21, -7F33625BC129, +6A1987C40A21 +7F33625BC129 # # Data from forum -2338b4913111, +2338b4913111 # # Data from stoye -cb779c50e1bd, -a27d3804c259, -003cc420001a, -f9861526130f, -381ece050fbd, -a57186bdd2b9, -48c739e21a04, -36abf5874ed7, -649d2abbbd20, -bbe8fffcf363, -ab4e7045e97d, -340e40f81cd8, -e4f65c0ef32c, -d2a597d76936, -a920f32fe93a, -86afd95200f7, -9b832a9881ff, -26643965b16e, -0c669993c776, -b468d1991af9, -d9a37831dce5, -2fc1f32f51b1, -0ffbf65b5a14, -c5cfe06d9ea3, -c0dece673829, +cb779c50e1bd +a27d3804c259 +003cc420001a +f9861526130f +381ece050fbd +a57186bdd2b9 +48c739e21a04 +36abf5874ed7 +649d2abbbd20 +bbe8fffcf363 +ab4e7045e97d +340e40f81cd8 +e4f65c0ef32c +d2a597d76936 +a920f32fe93a +86afd95200f7 +9b832a9881ff +26643965b16e +0c669993c776 +b468d1991af9 +d9a37831dce5 +2fc1f32f51b1 +0ffbf65b5a14 +c5cfe06d9ea3 +c0dece673829 # -a56c2df9a26d, +a56c2df9a26d # -# Data from: https://pastebin.com/vbwast74 +# Data from https://pastebin.com/vbwast74 # -68d3f7307c89, -568c9083f71c,--Smart Rider. Western Australian Public Transport Cards +68d3f7307c89 +568c9083f71c # Smart Rider. Western Australian Public Transport Cards # Vigik Keys # Various sources : # * https://github.com/DumpDos/Vigik # * http://newffr.com/viewtopic.php?&forum=235&topic=11559 # * Own dumps -021209197591, // BTCINO UNDETERMINED SPREAKD 0x01->0x13 key -2ef720f2af76, -414c41524f4e, -424c41524f4e, -4a6352684677, -bf1f4424af76, -536653644c65, +021209197591 # BTCINO UNDETERMINED SPREAKD 0x01->0x13 key +2ef720f2af76 +414c41524f4e +424c41524f4e +4a6352684677 +bf1f4424af76 +536653644c65 # # Intratone Cogelec # Data from http://bouzdeck.com/rfid/32-cloning-a-mifare-classic-1k-tag.html -484558414354, -a22ae129c013, -49fae4e3849f, -38fcf33072e0, -8ad5517b4b18, -509359f131b1, -6c78928e1317, -aa0720018738, -a6cac2886412, -62d0c424ed8e, -e64a986a5d94, -8fa1d601d0a2, -89347350bd36, -66d2b7dc39ef, -6bc1e1ae547d, -22729a9bd40f, +484558414354 +a22ae129c013 +49fae4e3849f +38fcf33072e0 +8ad5517b4b18 +509359f131b1 +6c78928e1317 +aa0720018738 +a6cac2886412 +62d0c424ed8e +e64a986a5d94 +8fa1d601d0a2 +89347350bd36 +66d2b7dc39ef +6bc1e1ae547d +22729a9bd40f # # Data from https://dfir.lu/blog/cloning-a-mifare-classic-1k-tag.html -925b158f796f, -fad63ecb5891, -bba840ba1c57, -cc6b3b3cd263, -6245e47352e6, -8ed41e8b8056, -2dd39a54e1f3, -6d4c5b3658d2, -1877ed29435a, -52264716efde, -961c0db4a7ed, -703140fd6d86, -157c9a513fa5, -e2a5dc8e066f, +925b158f796f +fad63ecb5891 +bba840ba1c57 +cc6b3b3cd263 +6245e47352e6 +8ed41e8b8056 +2dd39a54e1f3 +6d4c5b3658d2 +1877ed29435a +52264716efde +961c0db4a7ed +703140fd6d86 +157c9a513fa5 +e2a5dc8e066f # # Data from a oyster card -374bf468607f, -bfc8e353af63, -15cafd6159f6, -62efd80ab715, -987a7f7f1a35, -c4104fa3c526, -4c961f23e6be, -67546972bc69, -f4cd5d4c13ff, -94414c1a07dc, -16551d52fd20, -9cb290282f7d, -77a84170b574, -ed646c83a4f3, -e703589db50b, -513c85d06cde, -95093f0b2e22, -543b01b27a95, -c6d375b99972, -ee4cc572b40e, -5106ca7e4a69, -c96bd1ce607f, -167a1be102e0, -a8d0d850a606, -a2abb693ce34, -7b296c40c486, -91f93a5564c9, -e10623e7a016, -b725f9cbf183, +374bf468607f +bfc8e353af63 +15cafd6159f6 +62efd80ab715 +987a7f7f1a35 +c4104fa3c526 +4c961f23e6be +67546972bc69 +f4cd5d4c13ff +94414c1a07dc +16551d52fd20 +9cb290282f7d +77a84170b574 +ed646c83a4f3 +e703589db50b +513c85d06cde +95093f0b2e22 +543b01b27a95 +c6d375b99972 +ee4cc572b40e +5106ca7e4a69 +c96bd1ce607f +167a1be102e0 +a8d0d850a606 +a2abb693ce34 +7b296c40c486 +91f93a5564c9 +e10623e7a016 +b725f9cbf183 # # Data from FDi tag -8829da9daf76, +8829da9daf76 # # Data from GitHub issue -0A7932DC7E65, -11428B5BCE06, -11428B5BCE07, -11428B5BCE08, -11428B5BCE09, -11428B5BCE0A, -11428B5BCE0F, -18971D893494, -25D60050BF6E, -3FA7217EC575, -44F0B5FBE344, -7B296F353C6B, -8553263F4FF0, -8E5D33A6ED51, -9F42971E8322, -C620318EF179, -D4FE03CE5B06, -D4FE03CE5B07, -D4FE03CE5B08, -D4FE03CE5B09, -D4FE03CE5B0A, -D4FE03CE5B0F, -E241E8AFCBAF, +0A7932DC7E65 +11428B5BCE06 +11428B5BCE07 +11428B5BCE08 +11428B5BCE09 +11428B5BCE0A +11428B5BCE0F +18971D893494 +25D60050BF6E +3FA7217EC575 +44F0B5FBE344 +7B296F353C6B +8553263F4FF0 +8E5D33A6ED51 +9F42971E8322 +C620318EF179 +D4FE03CE5B06 +D4FE03CE5B07 +D4FE03CE5B08 +D4FE03CE5B09 +D4FE03CE5B0A +D4FE03CE5B0F +E241E8AFCBAF # # Data from forum post -123F8888F322, -050908080008, +123F8888F322 +050908080008 # # Data from hoist -4f9f59c9c875, +4f9f59c9c875 # # Data from pastebin -66f3ed00fed7, -f7a39753d018, +66f3ed00fed7 +f7a39753d018 # # Data from https://pastebin.com/Z7pEeZif -386B4D634A65, -666E564F4A44, -564777315276, -476242304C53, -6A696B646631, -4D3248735131, -425A73484166, -57784A533069, -345547514B4D, -4C6B69723461, -4E4175623670, -4D5076656D58, -686A736A356E, -484A57696F4A, -6F4B6D644178, -744E326B3441, -70564650584F, -584F66326877, -6D4E334B6C48, -6A676C315142, -77494C526339, -623055724556, -356D46474348, -4E32336C6E38, -57734F6F6974, -436A46587552, -5544564E6E67, -6F506F493353, -31646241686C, -77646B633657, +386B4D634A65 +666E564F4A44 +564777315276 +476242304C53 +6A696B646631 +4D3248735131 +425A73484166 +57784A533069 +345547514B4D +4C6B69723461 +4E4175623670 +4D5076656D58 +686A736A356E +484A57696F4A +6F4B6D644178 +744E326B3441 +70564650584F +584F66326877 +6D4E334B6C48 +6A676C315142 +77494C526339 +623055724556 +356D46474348 +4E32336C6E38 +57734F6F6974 +436A46587552 +5544564E6E67 +6F506F493353 +31646241686C +77646B633657 # # Data from TransPert -2031d1e57a3b, -53c11f90822a, -9189449ea24e, +2031d1e57a3b +53c11f90822a +9189449ea24e # # data from Github -410b9b40b872, -2cb1a90071c8, +410b9b40b872 +2cb1a90071c8 # # data from -8697389ACA26, -1AB23CD45EF6, -013889343891, +8697389ACA26 +1AB23CD45EF6 +013889343891 # # -0000000018de, -16ddcb6b3f24, +0000000018de +16ddcb6b3f24 # # Data from https://pastebin.com/vwDRZW7d -EC0A9B1A9E06,--Vingcard Mifare 4k Staff card -6C94E1CED026,--Vingcard Mifare 4k Staff card -0F230695923F,--Vingcard Mifare 4k Staff card -0000014B5C31,--Vingcard Mifare 4k Staff card +EC0A9B1A9E06 # Vingcard Mifare 4k Staff card +6C94E1CED026 # Vingcard Mifare 4k Staff card +0F230695923F # Vingcard Mifare 4k Staff card +0000014B5C31 # Vingcard Mifare 4k Staff card # -BEDB604CC9D1, -B8A1F613CF3D, -B578F38A5C61, +BEDB604CC9D1 +B8A1F613CF3D +B578F38A5C61 B66AC040203A 6D0B6A2A0003 -2E641D99AD5B -AD4FB33388BF, -69FB7B7CD8EE, -2A6D9205E7CA, -2a2c13cc242a, -27FBC86A00D0, -01FA3FC68349, +2E641D99AD5B +AD4FB33388BF +69FB7B7CD8EE +2A6D9205E7CA +2a2c13cc242a +27FBC86A00D0 +01FA3FC68349 # -6D44B5AAF464,--Smart Rider. Western Australian Public Transport Cards -1717E34A7A8A,--Smart Rider. Western Australian Public Transport Cards +6D44B5AAF464 # Smart Rider. Western Australian Public Transport Cards +1717E34A7A8A # Smart Rider. Western Australian Public Transport Cards # -6B6579737472,--RFIDeas +6B6579737472 # RFIDeas # -484944204953,--HID MIFARE Classic 1k Key -204752454154,--HID MIFARE Classic 1k Key -3B7E4FD575AD,--HID MIFARE SO -11496F97752A,--HID MIFARE SO +484944204953 # HID MIFARE Classic 1k Key +204752454154 # HID MIFARE Classic 1k Key +3B7E4FD575AD # HID MIFARE SO +11496F97752A # HID MIFARE SO # -415A54454B4D,--Luxeo/Aztek cashless vending +415A54454B4D # Luxeo/Aztek cashless vending # -321958042333,--BQT +321958042333 # BQT # -160A91D29A9C,--Aperio KEY_A Sector 1, 12, 13, 14, 15 Data Start 0 Length 48 +160A91D29A9C # Aperio KEY_A Sector 1, 12, 13, 14, 15 Data Start 0 Length 48 # -b7bf0c13066e,--Gallagher +b7bf0c13066e # Gallagher # # Boston, MA, USA Transit - MBTA Charlie Card -3060206f5b0a,-- charlie -5ec39b022f2b,-- charlie -3a09594c8587,-- charlie -f1b9f5669cc8,-- charlie -f662248e7e89,-- charlie -62387b8d250d,-- charlie -f238d78ff48f,-- charlie -9dc282d46217,-- charlie -afd0ba94d624,-- charlie -92ee4dc87191,-- charlie -b35a0e4acc09,-- charlie -756ef55e2507,-- charlie -447ab7fd5a6b,-- charlie -932b9cb730ef,-- charlie -1f1a0a111b5b,-- charlie -ad9e0a1ca2f7,-- charlie -d58023ba2bdc,-- charlie -62ced42a6d87,-- charlie -2548a443df28,-- charlie -2ed3b15e7c0f,-- charlie +3060206f5b0a # charlie +5ec39b022f2b # charlie +3a09594c8587 # charlie +f1b9f5669cc8 # charlie +f662248e7e89 # charlie +62387b8d250d # charlie +f238d78ff48f # charlie +9dc282d46217 # charlie +afd0ba94d624 # charlie +92ee4dc87191 # charlie +b35a0e4acc09 # charlie +756ef55e2507 # charlie +447ab7fd5a6b # charlie +932b9cb730ef # charlie +1f1a0a111b5b # charlie +ad9e0a1ca2f7 # charlie +d58023ba2bdc # charlie +62ced42a6d87 # charlie +2548a443df28 # charlie +2ed3b15e7c0f # charlie # -60012e9ba3fa, +60012e9ba3fa # -de1fcbec764b, -81bfbe8cacba, -bff123126c9b, -2f47741062a0, -b4166b0a27ea, -a170d9b59f95, -400bc9be8976, -d80511fc2ab4, -1fcef3005bcf, -bb467463acd6, -e67c8010502d, -ff58ba1b4478, +de1fcbec764b +81bfbe8cacba +bff123126c9b +2f47741062a0 +b4166b0a27ea +a170d9b59f95 +400bc9be8976 +d80511fc2ab4 +1fcef3005bcf +bb467463acd6 +e67c8010502d +ff58ba1b4478 # Data from https://pastebin.com/Kz8xp4ev -fbf225dc5d58, +fbf225dc5d58 # # Data https://pastebin.com/BEm6bdAE # vingcard.txt -4708111c8604, -3d50d902ea48, -96a301bce267, -6700f10fec09, -7a09cc1db70a, -560f7cff2d81, -66b31e64ca4b, -9e53491f685b, -3a09911d860c, -8a036920ac0c, -361f69d2c462, -d9bcde7fc489, -0c03a720f208, -6018522fac02, +4708111c8604 +3d50d902ea48 +96a301bce267 +6700f10fec09 +7a09cc1db70a +560f7cff2d81 +66b31e64ca4b +9e53491f685b +3a09911d860c +8a036920ac0c +361f69d2c462 +d9bcde7fc489 +0c03a720f208 +6018522fac02 # # Data from https://pastebin.com/4t2yFMgt # Mifare technische Universität Graz TUG -D58660D1ACDE, -50A11381502C, -C01FC822C6E5, -0854BF31111E, +D58660D1ACDE +50A11381502C +C01FC822C6E5 +0854BF31111E # More keys: -8a19d40cf2b5, -ae8587108640, +8a19d40cf2b5 +ae8587108640 135b88a94b8b, SafLock standalone door locks. # # Russian Troika card -08B386463229, -0E8F64340BA4, -0F1C63013DBA, -2AA05ED1856F, -2B7F3253FAC5, -69A32F1C2F19, -73068F118C13, -9BECDF3D9273, -A73F5DC1D333, -A82607B01C0D, -AE3D65A3DAD4, -CD4C61C26E3D, -D3EAFB5DF46D, -E35173494A81, -FBC2793D540B, -5125974CD391, -ECF751084A80, -7545DF809202, -AB16584C972A, -7A38E3511A38, -C8454C154CB5, -04C297B91308, -EFCB0E689DB3, -07894FFEC1D6, -FBA88F109B32, -2FE3CB83EA43, -B90DE525CEB6, -1CC219E9FEC1, -A74332F74994, -764CD061F1E6, -8F79C4FD8A01, -CD64E567ABCD, -CE26ECB95252, -ABA208516740, -9868925175BA, -16A27AF45407, -372CC880F216, -3EBCE0925B2F, -73E5B9D9D3A4, -0DB520C78C1C, -70D901648CB9, -C11F4597EFB5, -B39D19A280DF, -403D706BA880, -7038CD25C408, -6B02733BB6EC, -EAAC88E5DC99, -4ACEC1205D75, -2910989B6880, -31C7610DE3B0, -5EFBAECEF46B, -F8493407799D, -6B8BD9860763, -D3A297DC2698, +08B386463229 +0E8F64340BA4 +0F1C63013DBA +2AA05ED1856F +2B7F3253FAC5 +69A32F1C2F19 +73068F118C13 +9BECDF3D9273 +A73F5DC1D333 +A82607B01C0D +AE3D65A3DAD4 +CD4C61C26E3D +D3EAFB5DF46D +E35173494A81 +FBC2793D540B +5125974CD391 +ECF751084A80 +7545DF809202 +AB16584C972A +7A38E3511A38 +C8454C154CB5 +04C297B91308 +EFCB0E689DB3 +07894FFEC1D6 +FBA88F109B32 +2FE3CB83EA43 +B90DE525CEB6 +1CC219E9FEC1 +A74332F74994 +764CD061F1E6 +8F79C4FD8A01 +CD64E567ABCD +CE26ECB95252 +ABA208516740 +9868925175BA +16A27AF45407 +372CC880F216 +3EBCE0925B2F +73E5B9D9D3A4 +0DB520C78C1C +70D901648CB9 +C11F4597EFB5 +B39D19A280DF +403D706BA880 +7038CD25C408 +6B02733BB6EC +EAAC88E5DC99 +4ACEC1205D75 +2910989B6880 +31C7610DE3B0 +5EFBAECEF46B +F8493407799D +6B8BD9860763 +D3A297DC2698 # # Keys from MifareClassicTool project -044CE1872BC3, -045CECA15535, -0BE5FAC8B06A, -0CE7CD2CC72B, -0EB23CC8110B, -0F01CEFF2742, -0F318130ED18, -114D6BE9440C, -18E3A02B5EFF, -19FC84A3784B, -1B61B2E78C75, -22052B480D11, -3367BFAA91DB, -3A8A139C20B4, -42E9B54E51AB, -46D78E850A7E, -4B609876BBA3, -518DC6EEA089, -6B07877E2C5C, -7259FA0197C6, -72F96BDD3714, -7413B599C4EA, -77DABC9825E1, -7A396F0D633D, -7A86AA203788, -8791B2CCB5C4, -8A8D88151A00, -8C97CD7A0E56, -8E26E45E7D65, -9D993C5D4EF4, -9EA3387A63C1, -A3FAA6DAFF67, -A7141147D430, -AAFB06045877, -ACFFFFFFFFFF, -AFCEF64C9913, -B27ADDFB64B0, -B81F2B0C2F66, -B9F8A7D83978, -BAFF3053B496, -BB52F8CCE07F, -BC2D1791DEC1, -BC4580B7F20B, -C65D4EAA645B, -C76BF71A2509, -D5524F591EED, -E328A1C7156D, -E4821A377B75, -E56AC127DD45, -EA0FD73CB149, -FC0001877BF7, -FD8705E721B0, -00ada2cd516d, +044CE1872BC3 +045CECA15535 +0BE5FAC8B06A +0CE7CD2CC72B +0EB23CC8110B +0F01CEFF2742 +0F318130ED18 +114D6BE9440C +18E3A02B5EFF +19FC84A3784B +1B61B2E78C75 +22052B480D11 +3367BFAA91DB +3A8A139C20B4 +42E9B54E51AB +46D78E850A7E +4B609876BBA3 +518DC6EEA089 +6B07877E2C5C +7259FA0197C6 +72F96BDD3714 +7413B599C4EA +77DABC9825E1 +7A396F0D633D +7A86AA203788 +8791B2CCB5C4 +8A8D88151A00 +8C97CD7A0E56 +8E26E45E7D65 +9D993C5D4EF4 +9EA3387A63C1 +A3FAA6DAFF67 +A7141147D430 +AAFB06045877 +ACFFFFFFFFFF +AFCEF64C9913 +B27ADDFB64B0 +B81F2B0C2F66 +B9F8A7D83978 +BAFF3053B496 +BB52F8CCE07F +BC2D1791DEC1 +BC4580B7F20B +C65D4EAA645B +C76BF71A2509 +D5524F591EED +E328A1C7156D +E4821A377B75 +E56AC127DD45 +EA0FD73CB149 +FC0001877BF7 +FD8705E721B0 +00ada2cd516d # # D3F7D3F7D3F7 ## -237a4d0d9119, -0ed7846c2bc9, -FFFFD06F83E3, -FFFFAE82366C, -F89C86B2A961, -F83466888612, -ED3A7EFBFF56, -E96246531342, -E1DD284379D4, -DFED39FFBB76, -DB5181C92CBE, -CFC738403AB0, -BCFE01BCFE01, -BA28CFD15EE8, -B0699AD03D17, -AABBCC660429, -A4EF6C3BB692, -A2B2C9D187FB, -9B1DD7C030A1, -9AEDF9931EC1, -8F9B229047AC, -872B71F9D15A, -833FBD3CFE51, -5D293AFC8D7E, -5554AAA96321, -474249437569, -435330666666, -1A2B3C4D5E6F, -123456ABCDEF, -83BAB5ACAD62, -64E2283FCF5E, -64A2EE93B12B, -46868F6D5677, -40E5EA1EFC00, -37D4DCA92451, -2012053082AD, -2011092119F1, -200306202033, -1795902DBAF9, -17505586EF02, -022FE48B3072, -013940233313, +237a4d0d9119 +0ed7846c2bc9 +FFFFD06F83E3 +FFFFAE82366C +F89C86B2A961 +F83466888612 +ED3A7EFBFF56 +E96246531342 +E1DD284379D4 +DFED39FFBB76 +DB5181C92CBE +CFC738403AB0 +BCFE01BCFE01 +BA28CFD15EE8 +B0699AD03D17 +AABBCC660429 +A4EF6C3BB692 +A2B2C9D187FB +9B1DD7C030A1 +9AEDF9931EC1 +8F9B229047AC +872B71F9D15A +833FBD3CFE51 +5D293AFC8D7E +5554AAA96321 +474249437569 +435330666666 +1A2B3C4D5E6F +123456ABCDEF +83BAB5ACAD62 +64E2283FCF5E +64A2EE93B12B +46868F6D5677 +40E5EA1EFC00 +37D4DCA92451 +2012053082AD +2011092119F1 +200306202033 +1795902DBAF9 +17505586EF02 +022FE48B3072 +013940233313 # # Hotel Adina -9EBC3EB37130, +9EBC3EB37130 # -# mostlikely diverised individual keys. -# data from: https://github.com/korsehindi/proxmark3/commit/24fdbfa9a1d5c996aaa5c192bc07e4ab28db4c5c -491CDC863104, -A2F63A485632, -98631ED2B229, -19F1FFE02563, -563A22C01FC8, -- Argentina -43CA22C13091, -- Argentina -25094DF2C1BD, -- Argentina +# most likely diversed individual keys. +# data from https://github.com/korsehindi/proxmark3/commit/24fdbfa9a1d5c996aaa5c192bc07e4ab28db4c5c +491CDC863104 +A2F63A485632 +98631ED2B229 +19F1FFE02563 +563A22C01FC8 # Argentina +43CA22C13091 # Argentina +25094DF2C1BD # Argentina # # OMNITEC.ES HOTEL TIMECARD / MAINTENANCECARD -AFBECD120454, +AFBECD120454 # # OMNITEC.ES HOTEL EMERGENCYCARD -842146108088, +842146108088 # # TAPCARD PUBLIC TRANSPORT LA # -EA1B88DF0A76, -D1991E71E2C5, -05F89678CFCF, -D31463A7AB6D, -C38197C36420, -772219470B38, -1C1532A6F1BC, -FA38F70215AD, -E907470D31CC, -160F4B7AB806, -1D28C58BBE8A, -B3830B95CA34, -6A0E215D1EEB, -E41E6199318F, -C4F271F5F0B3, -1E352F9E19E5, -0E0E8C6D8EB6, -C342F825B01B, -CB911A1A1929, -E65B66089AFC, -B81846F06EDF, -37FC71221B46, -880C09CFA23C, -6476FA0746E7, -419A13811554, -2C60E904539C, -4ECCA6236400, -10F2BBAA4D1C, -4857DD68ECD9, -C6A76CB2F3B5, -E3AD9E9BA5D4, -6C9EC046C1A4, +EA1B88DF0A76 +D1991E71E2C5 +05F89678CFCF +D31463A7AB6D +C38197C36420 +772219470B38 +1C1532A6F1BC +FA38F70215AD +E907470D31CC +160F4B7AB806 +1D28C58BBE8A +B3830B95CA34 +6A0E215D1EEB +E41E6199318F +C4F271F5F0B3 +1E352F9E19E5 +0E0E8C6D8EB6 +C342F825B01B +CB911A1A1929 +E65B66089AFC +B81846F06EDF +37FC71221B46 +880C09CFA23C +6476FA0746E7 +419A13811554 +2C60E904539C +4ECCA6236400 +10F2BBAA4D1C +4857DD68ECD9 +C6A76CB2F3B5 +E3AD9E9BA5D4 +6C9EC046C1A4 # # ROC HIGHSCHOOL ACCESSCARD # -B021669B44BB, -B18CDCDE52B7, -A22647F422AE, -B268F7C9CA63, -A37A30004AC9, -B3630C9F11C8, -A4CDFF3B1848, -B42C4DFD7A90, -A541538F1416, -B5F454568271, -A6C028A12FBB, -B6323F550F54, -A7D71AC06DC2, -B7C344A36D88, -A844F4F52385, -B8457ACC5F5D, -A9A4045DCE77, -B9B8B7B6B5B3, -AA4D051954AC, -BA729428E808, -AB28A44AD5F5, -BB320A757099, -AC45AD2D620D, -BCF5A6B5E13F, -AD5645062534, -BDF837787A71, -AE43F36C1A9A, -BE7C4F6C7A9A, -5EC7938F140A, -82D58AA49CCB, +B021669B44BB +B18CDCDE52B7 +A22647F422AE +B268F7C9CA63 +A37A30004AC9 +B3630C9F11C8 +A4CDFF3B1848 +B42C4DFD7A90 +A541538F1416 +B5F454568271 +A6C028A12FBB +B6323F550F54 +A7D71AC06DC2 +B7C344A36D88 +A844F4F52385 +B8457ACC5F5D +A9A4045DCE77 +B9B8B7B6B5B3 +AA4D051954AC +BA729428E808 +AB28A44AD5F5 +BB320A757099 +AC45AD2D620D +BCF5A6B5E13F +AD5645062534 +BDF837787A71 +AE43F36C1A9A +BE7C4F6C7A9A +5EC7938F140A +82D58AA49CCB # -# MELONCARD +# MELONCARD # -323334353637, +323334353637 # # -CEE3632EEFF5, -827ED62B31A7, -03EA4053C6ED, -C0BEEFEC850B, -F57F410E18FF, -0AF7DB99AEE4, -A7FB4824ACBF, -207FFED492FD, -1CFA22DBDFC3, -30FFB6B056F5, -39CF885474DD, -00F0BD116D70, -4CFF128FA3EF, -10F3BEBC01DF, +CEE3632EEFF5 +827ED62B31A7 +03EA4053C6ED +C0BEEFEC850B +F57F410E18FF +0AF7DB99AEE4 +A7FB4824ACBF +207FFED492FD +1CFA22DBDFC3 +30FFB6B056F5 +39CF885474DD +00F0BD116D70 +4CFF128FA3EF +10F3BEBC01DF # # Transportes Insular La Palma # -0172066b2f03, -0000085f0000, -1a80b93f7107, -70172066b2f0, -b1a80c94f710, -0b0172066b2f, -0f1a81c95071, -f0f0172066b2, -1131a81d9507, -2f130172066b, -71171a82d951, -b2f170172066, -1711b1a82e96, -6b2f1b017206, -62711f1a83e9, -66b2f1f01720, -97271231a83f, -066b2f230172, -f97371271a84, -2066b2f27017, -50983712b1a8, -72066b2f2b01, -850984712f1a, -172066b2f2f0, -a85198481331, -0172066b2f33, -1a8619858137, -70172066b2f3, -b1a862985913, -3b0172066b2f, -3f1a87298691, -f3f0172066b2, +0172066b2f03 +0000085f0000 +1a80b93f7107 +70172066b2f0 +b1a80c94f710 +0b0172066b2f +0f1a81c95071 +f0f0172066b2 +1131a81d9507 +2f130172066b +71171a82d951 +b2f170172066 +1711b1a82e96 +6b2f1b017206 +62711f1a83e9 +66b2f1f01720 +97271231a83f +066b2f230172 +f97371271a84 +2066b2f27017 +50983712b1a8 +72066b2f2b01 +850984712f1a +172066b2f2f0 +a85198481331 +0172066b2f33 +1a8619858137 +70172066b2f3 +b1a862985913 +3b0172066b2f +3f1a87298691 +f3f0172066b2 # # Tehran ezpay # diff --git a/client/dictionaries/mfc_keys_bmp_sorted.dic b/client/dictionaries/mfc_keys_bmp_sorted.dic index 0f8acdcf3..85ab141e0 100644 --- a/client/dictionaries/mfc_keys_bmp_sorted.dic +++ b/client/dictionaries/mfc_keys_bmp_sorted.dic @@ -1,1000 +1,1000 @@ -002DE0301481, -004173272D18, -0058A4884CA5, -00BAC32761D8, -00BB79731B00, -00E8C85DB172, -02096124DA70, -024988BC4D5E, -0271B7C4B015, -028137A705DB, -02827C286AB4, -02C10DA600D0, -0340643D5E27, -037A5DA4682B, -037AC43CBD9D, -037B9B8AA219, -037EE3DE21B7, -0380A9A3CBDE, -03D10A75B56A, -03E8CD22E691, -04109ED8EA79, -04361330B35C, -043D8B66D569, -045E5588845C, -048DE5148DE7, -0490921D0194, -04B717BD92EB, -04D49C76623B, -051518B3301E, -0529E8827A52, -052B16064085, -05DC4016B500, -06124317A9A6, -06147D199266, -0670AEB833CE, -0686A9E6D6E0, -06A34E5E6639, -06B78AD0C4BB, -0710E7818AB8, -07121B8C633A, -07176713C0ED, -0793533A5087, -081D1B1C3110, -0849495E1CCA, -09429512046E, -0966C3B28E04, -098A92C3660A, -098B48278122, -099672009EEA, -0A7632943926, -0AEE126549DA, -0B3B8C2833BC, -0B733C13E2C9, -0B764247D00E, -0BE811559D69, -0C208AD4E4B3, -0C270BC0BDDC, -0C5D782CB183, -0C82C94EB11B, -0CCDE948878A, -0CCE39820AAE, -0CDE3E716B32, -0CE06C96DB4C, -0CE87813E389, -0D3385CEA152, -0D5C5B8BCC5B, -0DB0A87AB882, -0DE247593B93, -0E0AD1796003, -0E62E6CAC3D3, -106E2D6E55E6, -1096A7830C82, -11549C141AD9, -116A92C793D6, -116C31526819, -11C68052AAE9, -1234B5BE8E78, -1268C7D104E1, -12A21B5671A8, -13359D5AE9A5, -1426EC62BB6C, -144489B1056E, -14A22C112090, -14C9BBB5361B, -14EB6286AC57, -14EE72B27223, -153BB53ACE71, -157B03405B38, -15A45083D24E, -15DACCE8D5EC, -16124677BBC5, -16373A44D5D7, -1663659384DC, -167828B6105C, -16B25A453093, -1706B1BE25C7, -171B15888483, -17BC8EED9A0C, -17C6299D5A37, -17E9C4C416EB, -1804087C7166, -1841CC4E3E79, -18AB05761CC5, -18ADAAC2B08B, -18E566417E5C, -191390328752, -1A47959E7DB4, -1A9A970CC370, -1B095E78BB33, -1B1717043D2B, -1B1A054566D9, -1B4654AE9454, -1B9CD1ED3420, -1B9E00780953, -1BB6A9CE71E2, -1C1250A36A13, -1C2316079532, -1C2855ED7A10, -1CD1AE73CA8C, -1CD3D4E690B7, -1D0322005969, -1D09B23EB116, -1D67A32045ED, -1D89D900968A, -1DAE8D2CEA5C, -1E1873799CD7, -1E60CE7C5179, -1E6A67909B8D, -1E8516585792, -1EB0864E9134, -1ECE3D04A020, -2009828E4A21, -200A6A3AA65D, -20188A599582, -20267CB20256, -20628CA7D92D, -2077C980EB2E, -2089B5D68B27, -209481EC6256, -20B6691C64B1, -20CC5A00C677, -211473555436, -2170E9D0D448, -219529A90EDD, -21A5B6481B7D, -224A308017D1, -227D16EA455A, -22A1245CA266, -22A95CB798DC, -230E26964171, -231173B68E46, -2332BB9A2452, -234323BC2992, -234E50256146, -235C9338D5B6, -23789D9ADD0D, -23997DD240AB, -23A5BA53AD4D, -23BB58853461, -24CAD4153036, -24CE79506842, -25228ED714BC, -257377227B34, -2584287A0174, -2616192EEB22, -265C03B50877, -26D641E834DC, -27073B57132B, -279060E3DEE9, -284BA0A0A29C, -285C6604C5B4, -28B20331245A, -28D042242A83, -28DDD4C3E9C4, -292C2CCD157E, -299ABB519354, -2A41BE015C1D, -2A4A55052A51, -2A94CBCD7A6E, -2AB6536187C7, -2B2D2DC3D319, -2BD607CA70B2, -2C6C7957EB3E, -2C9E9E4D0895, -2D2A97DD45E3, -2D41850A8AA6, -2DAC030D1AB9, -2E12426D8847, -2E25AD1D6D8D, -2E2E85E0E6C9, -2E4340CC1C63, -2E6803BE2E11, -2EB24B573DCD, -2EC6450A47C7, -2ECDA9A5EA96, -2EDE1C155023, -302D5D37342B, -303645E47667, -303B30A460E8, -3048EBB8A18E, -30BD652BED24, -30CCE5ECB397, -310241E1CB36, -312670228372, -319E8895EAB5, -31E3A933BC4A, -3250D2E661DA, -32560224418D, -32589E221D10, -326657A8E9C0, -329AC7C59311, -32A091B89995, -3312C094BD20, -336C8CBA5AE2, -34240649314A, -3493D84E6317, -349A347186D7, -349BEAC5210E, -34A939B49EDC, -34CC7E36C8C4, -34D71347877E, -34DC25B4D0CE, -35895EB472C4, -358A6A398211, -360A08C66042, -36306A9CA571, -37284428A250, -377EC8A78B8D, -37BD90A68613, -37E602347133, -382DE6AB2D1A, -385D498B5390, -38B67589E47D, -393CCCCCDA4A, -39682B3E10B5, -397619525709, -39A83A32909B, -3A5834C46513, -3A70C7A4BCE4, -3A818D01E093, -3AA5AC1CDC21, -3AAE07339954, -3B4497052B42, -3B784087DB2D, -3B86A20C16EA, -3B8E321AB1B4, -3BC4A3099B0D, -3BC741376E71, -3C4C95D0A0C7, -3C84B55A5E54, -3C888A88C59D, -3D5C8240B2D2, -3DB004172BE7, -3E23271C1C15, -3E3188294ED1, -3E84144A770E, -3EA227893101, -3EB914E70076, -3EE6D4A85643, -40DABA780B41, -4119340759A2, -415210E0C6BB, -416D21717779, -41B1839829A9, -4201A36DE766, -4261A795D5A7, -42AA0B29626E, -430265958BEB, -4317C5C16EAD, -431D799E0C89, -4342794AD7BB, -4387ADE263DB, -43982124C310, -4436CB060568, -44449507B736, -44E858C82975, -459BC12982B1, -45AE5DDA9830, -45C414CDC347, -45CE4E504C06, -461744C8EABD, -46D012CA3BEC, -47170BD112B6, -47C43D5DD234, -47CD4AC26271, -47D410D1C7C4, -4808C5AD0115, -485BEEDBC293, -486001404A80, -488CCC60B70A, -49204E3CA169, -495657C78147, -4970714D53D9, -4AA715A0BBB4, -4B9901AEC16E, -4BE0B912A5A3, -4CBC34D10D83, -4CD3ACABC6A3, -4CE00134DE1E, -4CEB27151C49, -4D02A3D7CE48, -4D13683C7960, -4D1A263BA48B, -4D23919463A3, -4D9763C083D9, -4DAC8EE52C68, -4DCB89C7B2E6, -4DD9D9B637C4, -4DE6CB63A920, -4DEBA10CC85D, -4E232A8C2E30, -4E2879A411E7, -4EA7B0BED74B, -4EB8761372EA, -4EC2B23135AB, -4EC71DB088DE, -4EC9AB4B5519, -50179E461EE6, -50265ED9D468, -5047DC2975BE, -508357498162, -508BE54D326E, -510A8C52AAC4, -511335CC92CD, -518229589A81, -5184D04315D7, -51B4AE31B246, -526EDB918BEE, -529CE44BEBCC, -52A843082BB3, -52AE9A909674, -5313E9079489, -532DE5E7E0E9, -535508AA6C91, -53691569B669, -540A5B789761, -547B86E57596, -54C649075B57, -552249203848, -55430B5318E9, -5570D22DC66B, -55710879E113, -55D2E4AC0446, -56207539825A, -564664475726, -566441C5C28C, -56A7930913C3, -56C944B04618, -56D455A8BBEA, -5726991C8C28, -5726AA3BE37B, -573314090BA5, -577C31903867, -577C528E786C, -57AD9604ED24, -580C377283C7, -587329CE3EBE, -587C34557B36, -58B11E803B58, -5902E4DCC95D, -5A060A64C535, -5A36898CA7C5, -5A4740D952EC, -5A6ED7966868, -5A99578CAA13, -5AAD6814E68B, -5B065568048A, -5B6CE0B3AD0A, -5B70E0B11758, -5B926E3751EB, -5B9CA63C4267, -5BDC1391B289, -5C1D3898D537, -5C34B8E4A456, -5C36456EA1E5, -5C43A75C65A0, -5C5752328A47, -5C9D20250D74, -5CBA3CEE351A, -5CD5E98A2864, -5CE0EB9C01B6, -5D384E6A4145, -5D9DB8445155, -5DE8717BB640, -5E1A4EE98748, -5E45A227B391, -5E8E50B3048B, -5EB0EA0A9412, -6032C47B7676, -60E0C84ADDEE, -612A447A2149, -612D81821854, -616B820EAD01, -616D75A4A022, -61DE2B085AC9, -62312EC272A0, -6232C5262CC6, -62B7C7C9B0D0, -62C531C6E29C, -63E6AAAB4433, -644ABCC3DD12, -64AE7BEA1784, -6515B38077D6, -65972038CC25, -65E120DE5E55, -66141DDE8320, -66718BD91332, -668082242328, -668920AEE063, -6696C4332D46, -66C9880D1DC2, -67150CB11E95, -671737BA0054, -673551D0A99E, -676D682C4336, -678B98AA2E86, -6847808E63EE, -6887A122AA62, -6888C514DEAD, -688BD5B7B4E9, -68A99E258692, -68C312391560, -68C9D33E3735, -6900A069E3D7, -690155BE8D8E, -69174742042D, -69B9CE233517, -6A0B123D7595, -6AB8E2B49E25, -6ABD4C4A72D9, -6B1CC539A1B2, -6B30B6B0925D, -6B638C1C950D, -6BAAAB1D4589, -6BAD01EBE736, -6BB4ED5E1682, -6CA178E036DA, -6CE210B529C4, -6D23D505D2B1, -6D3CBD12BC6D, -6D83563EB521, -6D98AB9CCC71, -6E3D7366E78C, -6E5582237608, -6E6602904925, -6E77B8EB6444, -6E978A7B16C6, -6EEC05EB651C, -70284824B26C, -702CDACE0C14, -704E1B85BED8, -70BB123776D6, -70CCC3A2D7C0, -716A747CB931, -7173E199A420, -71BC9C9E31E4, -71CAEEA3B771, -71D8BA423D55, -72253C7DD951, -7260377CD286, -7280858E8B20, -72913BDAB647, -72B5B87BBC6E, -72C83B1D098A, -72DA8050A38E, -735C2AB60A97, -736B602A93D9, -738D7833E7DE, -73E7B22D6E54, -74133B1E2DED, -74A929877793, -74E3670C045A, -7531E3E2A41C, -7542A9B65EB4, -7564993C91C7, -760ED0AB626E, -762E0E021E38, -763D7E6BB40E, -764B38E2903D, -768016001C8D, -76A616C3D42C, -76AE99D9A294, -76BAAA710D25, -76E3B23696BC, -77322DD2E184, -77B40902B6D9, -77C0AC14972D, -77C1CE0E7674, -77D7B7E2C8BA, -78279397A68E, -7836593AB838, -783859EB51A6, -78CCDB50C193, -7932684154AE, -79604362370E, -796630ED27B3, -799E4E270953, -79A00573947A, -79B798D66B01, -7A0455D0A7EC, -7A33D19B7248, -7B0A8AE18817, -7B0BA045AB35, -7B0DE8504D57, -7B21781EC649, -7B7224C1AB79, -7B90C2BA9B23, -7BB90D382672, -7BBC9DC92836, -7C09DC408C47, -7C418B493454, -7C491D518242, -7C7A86CC727C, -7CE836EBD228, -7D49042C530D, -7E5744EC286C, -7E680A48C383, -7EC45CCEC35A, -7EDADA19EB57, -8005BD088847, -8022E705B640, -8031E3565825, -80499BAA5959, -807466CCBAB5, -810518578380, -810D24CB13CC, -812B02C34A64, -8163A5DDE1CD, -8186CE2B363E, -81DE6062B9D7, -822017D8929A, -8247C78188C5, -8270D538D5E8, -82D8E8DDE296, -831207CA6E8A, -83378A077357, -83A05B477535, -840160379EEE, -84044BAB78A7, -84366C6D7781, -8442CC9AA777, -8470AAD30447, -8498740493BB, -84A35A698E93, -84ABDE484425, -84B24DBB9A67, -84B723B2A237, -852BEB133D74, -854501E98239, -854A0ED2E77D, -85A066D39785, -8619557091AA, -86228C3742A4, -8637BB3BA795, -8642D9310B46, -86538085966D, -86EE9C410811, -870A042C1B34, -873B47C457E6, -873CE44DDC6B, -874D123262E7, -87513C960770, -877641436923, -878A091B74B7, -87927467808B, -88C2E39B5990, -88D252AC1A8A, -891EDA20BDEA, -89267DEE07ED, -892CB89ACCC6, -8A2423E9D100, -8A6BC2E3811B, -8A8EB5771EE9, -8A906B4B3211, -8AB21B524C5C, -8AB823BDC2AE, -8AC3B2ADE77B, -8AC4317D049B, -8ACD6B86EC44, -8AD966CA3B4D, -8B0A3B3DCDD4, -8B1B6C705C1A, -8B1C75E27153, -8B2A5E0332A1, -8B6216E412DB, -8B7CCA9DB004, -8B9999AE9703, -8BABAD9A65C6, -8C32D0AE3DB7, -8C99807368A5, -8CC1133D7D5B, -8CD2C872187A, -8D0563B86DD4, -8D43D81E37B4, -8D96A800B21A, -8D97B475C957, -8DA62EC0C524, -8DACA1BC0636, -8DE3B131D728, -8E55316D3B3D, -8EE497C9A869, -90210DDAB57D, -9026977EB8A6, -903AA4305025, -9083158A49A1, -9092D12E7967, -90D8713352D1, -911E097A27A9, -9140EC087241, -918A67D05479, -919B1D357E91, -9210BBA2AB26, -9224B6555E30, -9226D4D1236A, -922E7955CC67, -929CC86B1B26, -929E1556110E, -9302DEB79C5A, -9384841B4702, -93B4BD1CB47C, -93D985D55712, -940B37939AC6, -94673AE73823, -947A8147E0AE, -94CD6A4B6391, -94CEEAC5A8D7, -95ABD3A7C631, -95E1C233EDE2, -9607AE17AD09, -960C98566E52, -96435BD1D29B, -965D66E19245, -965D72659982, -9695167B4149, -96D0C3996714, -97274C21BD6C, -973186B345BB, -973A28C983A3, -979686C51AB6, -97992CE2DD31, -97E9D0C89DA8, -97EB8A44C49D, -98314DC363C5, -9860DC044565, -988D023C15A5, -9917BDA7B4D7, -9996A233442A, -9A2132B5B625, -9A694755A978, -9A7911ECC275, -9AA1E6CE588C, -9ABCCD2AE7C7, -9B39A60D3841, -9C0630361CC5, -9C4E19AB64B1, -9CE96BADE4D8, -9D442B28BD11, -9D4C35AE1A08, -9E02910C691A, -9E46407C9024, -9E74D104ACEA, -9EDD416A7912, -A026642D13AD, -A12908B38536, -A16EE9666D5A, -A199132A4043, -A1AEC2B58BBA, -A1BE42A15EDE, -A1D0844C2C63, -A1E0103A1879, -A253602B9445, -A2B019B46CB9, -A2BBCC3B546C, -A2C325A73A9C, -A2CB60E815A0, -A314B97C1A6A, -A3647146C335, -A3A580799BB4, -A3D30CC8EB97, -A402B5137D86, -A42158CC74B5, -A435DD64AD17, -A4693D21013B, -A479A91EED49, -A4B30D146A01, -A5142D626200, -A54056E87CBB, -A57DBD287491, -A588C918E327, -A593071D4758, -A5CC0EE7B9E3, -A6375E98A5B5, -A666347B3B4B, -A6A203994202, -A6BAE1A1520D, -A6E9885AA49D, -A705087E89A8, -A7072D4324C7, -A745AD7D6789, -A750456E7C5E, -A783A8774651, -A787C822020C, -A78BB575EAC5, -A7905680A254, -A805534D84E9, -A86C2595A1C3, -A89903B6ADDB, -A9182707A219, -A9391782A846, -A96B08E3A50B, -A98DEB0733C9, -A9C37CE71D23, -AA2D69C757D9, -AA4E4558A9EE, -AA6C835C9124, -AAC0C35C43EB, -AB30CB2CB354, -AB6191DB240A, -AB8953D3560C, -ABBB521319E6, -AC47461358D7, -AC58C25A1559, -AC7D4B201D92, -AD061A23287D, -AD105D52DB36, -AD4EA84D7185, -AD5038D15490, -AD97523144B2, -ADB24E78784B, -ADCBD453B232, -AE516A187825, -AE52116C234C, -AE817239CAB5, -AEA5A5A0E46B, -AECC93678543, -B0452769A83C, -B04D71906C60, -B0805C191424, -B09172DDBE43, -B13AE369390C, -B14080E570D1, -B1419B62772C, -B14775DEA2E2, -B188BA649EA1, -B1BB0DB95C67, -B1BB19BDD424, -B1E8B5054DAD, -B1EBB537CC0D, -B2174092CDC5, -B2554CC8AD6E, -B2C5A2E88304, -B312E56ED250, -B37B48D8C1C5, -B39C699CD208, -B3B121208E34, -B3C3C6E4395B, -B410B958C3B8, -B4204546A74E, -B45171C5A67D, -B4B103E693ED, -B4DACABCAB07, -B506567A2B84, -B51083D5C2BD, -B54D7674CB90, -B570E5EA1DA3, -B598984AD584, -B5D7E1135821, -B60D053A36D9, -B63957593E23, -B64558CAC0C9, -B68175BCA864, -B6CD1A3EC5BC, -B72468A7710D, -B75176C82A8B, -B7AA0CA5D94A, -B7B9D7E523B8, -B808D87AB75C, -B93A6432E51A, -B941A9D99B6C, -B9DA40920237, -BA6C2E10086A, -BA7384AB949E, -BA8DEEE045E8, -BADC2149EC42, -BB1924266B36, -BB41640E6340, -BBB475DB2B03, -BBD4C4699719, -BC0B2C897267, -BC7BEE6B71C4, -BC8B21AD8802, -BCA2D8118631, -BCB7A7006400, -BCBC6637499B, -BCBD2B8BE4B3, -BD213E28C568, -BD32E4EC7080, -BD401D63C3E9, -BD463C3693A4, -BD749E85586A, -BD7CA11B9551, -BD96355CBE36, -BD9E6EB7B524, -BDADE6111218, -BDB576D1E88C, -BDB5DC09C522, -BE19C75D6B7E, -BE5B3ED935AC, -BEA20C972E70, -BEEB4A159B37, -C01E8740DE38, -C0411C28857D, -C045544AD1E4, -C04660B76831, -C0C4CA21B876, -C0E0E092C8B4, -C0EE394D3D95, -C14601C6B411, -C16EBAE928B2, -C189A791A85B, -C1ACDB8C1890, -C1C55A7A99EA, -C1D72A47755A, -C1D8B91D65AA, -C1E6149B386D, -C22D8E2B1E37, -C23E999B6298, -C314E31A670D, -C3D275A9B8C7, -C3EE19B61C89, -C427B93DC2ED, -C443EEC4330D, -C477B966D328, -C4C6CAE4784C, -C55875BCB82C, -C581CA998910, -C5ABC0A455C5, -C5BE33E6B1E2, -C629E0D34581, -C65194543D6B, -C67B8E869D90, -C6BC3B9CCB41, -C7034BC581A6, -C748500B6947, -C757C15E9E0D, -C798A8465ACB, -C7B6702AC17B, -C849133B7CCC, -C870C98A4E91, -C90B7AD266D3, -C90D996C3A2D, -C953797CCE61, -C9639352EEC8, -C983685AA86B, -C9CCA6D095A3, -C9CE81D47EDB, -C9D449AD9970, -CA0D9CCC4C38, -CA277AC09859, -CA56EB045188, -CAB92B865BAD, -CAE8572C2657, -CB1CE185575C, -CB2ECC3D9C22, -CB642A081A89, -CBBAD2DA0EC5, -CC1B5BD45315, -CC2C02300D34, -CC559969D0CC, -CC5646BD7AEB, -CC6A93BD93D1, -CC726DD08765, -CCBBAB6504A4, -CCC1EA3E27B8, -CD16EAB946E9, -CDB4EEE02E14, -CDC21E1E1EC7, -CE09B3870EA2, -CE5AA0C8B5A8, -CE63DE29E069, -D0368B24CA49, -D0489010A72C, -D075379A21A6, -D09893B4EE04, -D0A7A2787570, -D0B8C06C02E4, -D106E94A4C3B, -D11E7D1BBEEA, -D12B25B8DDE2, -D1972D6CE2C3, -D1B91D224946, -D2752E53679D, -D35B2B75CC52, -D40E935117A2, -D4C37528DC05, -D4C818A5455E, -D4CD56DB8AEB, -D5190BD5CED6, -D55E5AA3406D, -D576E9D856D9, -D5E444E9D82D, -D61A3231790D, -D669B3AE1E11, -D6C075899D06, -D6C3503456C4, -D7AC70A05A0C, -D80A37B6D7ED, -D82E6938C58C, -D85E51344EB6, -D8809EB9BA7D, -D8913C2D48E9, -D9109460D912, -D94E36427E20, -D97E55B1816A, -D99425130C1A, -D99C3222A190, -D9A207103ED7, -D9C70CC5818A, -DA3379D12773, -DA705702248C, -DA818C56CE43, -DAE1888DCC0B, -DBA0A2DCA8E0, -DBD9799E15B1, -DC242193D7E3, -DCB5AC62946C, -DCB75AEC61A0, -DD6E0587A821, -DD7B1A7C6A82, -DDA22A189095, -DDDAE53AA711, -DDE7304E78B6, -DE1B4DA681B9, -DEAC67E2D7C1, -DEB7D7E4C62B, -E127434AB3B7, -E1ACC6742AB7, -E1E59574ADBC, -E1EA6BAA03D9, -E222553A59A2, -E2230B8E84C9, -E33E807EC3BA, -E341574B2E32, -E42868808B70, -E43562C624B0, -E43D54DC3511, -E466090D2123, -E47069DA0C44, -E49DD6062901, -E4ACA0ADBA0D, -E4B976AD6687, -E526BB7888DB, -E53354B71B10, -E57581CE8617, -E61A1DA5A60E, -E6293BDA5EDC, -E64C2A07CA9B, -E6600C4D6A44, -E6655B6425DC, -E6BADC631036, -E70143BE0091, -E75E07A010D1, -E76962E3B8B4, -E8028A6DCC90, -E80C5E3E8227, -E8779E40450E, -E8A9E2D87D36, -E8B5A0BDD993, -E933DA9735C4, -E93A2E63189D, -E9447637E40D, -E94836269887, -E94D82A564BA, -E98DC3B561B5, -E9EB2DE57AE9, -EA490920877D, -EA4C494C9353, -EA9B1695DD91, -EAD0E31A6834, -EB16B6462B66, -EB276C9AB68D, -EB3C9732C3BA, -EB44DDC408CE, -EB8536C958B2, -EBC825C186B3, -EC1A55BB58EB, -EC2B12107313, -EC8CB5758097, -ECD4C42EA3D1, -ED22B7115435, -ED2CE17A590C, -ED65A9B6469C, -ED6748113E0D, -ED8CEB8B7102, -EDCE0890472D, -EDD4A2EA7493, -EE17C426D25E, -EE487A4C806E, -EE5931913A8D, -EED56840AEBA, +002DE0301481 +004173272D18 +0058A4884CA5 +00BAC32761D8 +00BB79731B00 +00E8C85DB172 +02096124DA70 +024988BC4D5E +0271B7C4B015 +028137A705DB +02827C286AB4 +02C10DA600D0 +0340643D5E27 +037A5DA4682B +037AC43CBD9D +037B9B8AA219 +037EE3DE21B7 +0380A9A3CBDE +03D10A75B56A +03E8CD22E691 +04109ED8EA79 +04361330B35C +043D8B66D569 +045E5588845C +048DE5148DE7 +0490921D0194 +04B717BD92EB +04D49C76623B +051518B3301E +0529E8827A52 +052B16064085 +05DC4016B500 +06124317A9A6 +06147D199266 +0670AEB833CE +0686A9E6D6E0 +06A34E5E6639 +06B78AD0C4BB +0710E7818AB8 +07121B8C633A +07176713C0ED +0793533A5087 +081D1B1C3110 +0849495E1CCA +09429512046E +0966C3B28E04 +098A92C3660A +098B48278122 +099672009EEA +0A7632943926 +0AEE126549DA +0B3B8C2833BC +0B733C13E2C9 +0B764247D00E +0BE811559D69 +0C208AD4E4B3 +0C270BC0BDDC +0C5D782CB183 +0C82C94EB11B +0CCDE948878A +0CCE39820AAE +0CDE3E716B32 +0CE06C96DB4C +0CE87813E389 +0D3385CEA152 +0D5C5B8BCC5B +0DB0A87AB882 +0DE247593B93 +0E0AD1796003 +0E62E6CAC3D3 +106E2D6E55E6 +1096A7830C82 +11549C141AD9 +116A92C793D6 +116C31526819 +11C68052AAE9 +1234B5BE8E78 +1268C7D104E1 +12A21B5671A8 +13359D5AE9A5 +1426EC62BB6C +144489B1056E +14A22C112090 +14C9BBB5361B +14EB6286AC57 +14EE72B27223 +153BB53ACE71 +157B03405B38 +15A45083D24E +15DACCE8D5EC +16124677BBC5 +16373A44D5D7 +1663659384DC +167828B6105C +16B25A453093 +1706B1BE25C7 +171B15888483 +17BC8EED9A0C +17C6299D5A37 +17E9C4C416EB +1804087C7166 +1841CC4E3E79 +18AB05761CC5 +18ADAAC2B08B +18E566417E5C +191390328752 +1A47959E7DB4 +1A9A970CC370 +1B095E78BB33 +1B1717043D2B +1B1A054566D9 +1B4654AE9454 +1B9CD1ED3420 +1B9E00780953 +1BB6A9CE71E2 +1C1250A36A13 +1C2316079532 +1C2855ED7A10 +1CD1AE73CA8C +1CD3D4E690B7 +1D0322005969 +1D09B23EB116 +1D67A32045ED +1D89D900968A +1DAE8D2CEA5C +1E1873799CD7 +1E60CE7C5179 +1E6A67909B8D +1E8516585792 +1EB0864E9134 +1ECE3D04A020 +2009828E4A21 +200A6A3AA65D +20188A599582 +20267CB20256 +20628CA7D92D +2077C980EB2E +2089B5D68B27 +209481EC6256 +20B6691C64B1 +20CC5A00C677 +211473555436 +2170E9D0D448 +219529A90EDD +21A5B6481B7D +224A308017D1 +227D16EA455A +22A1245CA266 +22A95CB798DC +230E26964171 +231173B68E46 +2332BB9A2452 +234323BC2992 +234E50256146 +235C9338D5B6 +23789D9ADD0D +23997DD240AB +23A5BA53AD4D +23BB58853461 +24CAD4153036 +24CE79506842 +25228ED714BC +257377227B34 +2584287A0174 +2616192EEB22 +265C03B50877 +26D641E834DC +27073B57132B +279060E3DEE9 +284BA0A0A29C +285C6604C5B4 +28B20331245A +28D042242A83 +28DDD4C3E9C4 +292C2CCD157E +299ABB519354 +2A41BE015C1D +2A4A55052A51 +2A94CBCD7A6E +2AB6536187C7 +2B2D2DC3D319 +2BD607CA70B2 +2C6C7957EB3E +2C9E9E4D0895 +2D2A97DD45E3 +2D41850A8AA6 +2DAC030D1AB9 +2E12426D8847 +2E25AD1D6D8D +2E2E85E0E6C9 +2E4340CC1C63 +2E6803BE2E11 +2EB24B573DCD +2EC6450A47C7 +2ECDA9A5EA96 +2EDE1C155023 +302D5D37342B +303645E47667 +303B30A460E8 +3048EBB8A18E +30BD652BED24 +30CCE5ECB397 +310241E1CB36 +312670228372 +319E8895EAB5 +31E3A933BC4A +3250D2E661DA +32560224418D +32589E221D10 +326657A8E9C0 +329AC7C59311 +32A091B89995 +3312C094BD20 +336C8CBA5AE2 +34240649314A +3493D84E6317 +349A347186D7 +349BEAC5210E +34A939B49EDC +34CC7E36C8C4 +34D71347877E +34DC25B4D0CE +35895EB472C4 +358A6A398211 +360A08C66042 +36306A9CA571 +37284428A250 +377EC8A78B8D +37BD90A68613 +37E602347133 +382DE6AB2D1A +385D498B5390 +38B67589E47D +393CCCCCDA4A +39682B3E10B5 +397619525709 +39A83A32909B +3A5834C46513 +3A70C7A4BCE4 +3A818D01E093 +3AA5AC1CDC21 +3AAE07339954 +3B4497052B42 +3B784087DB2D +3B86A20C16EA +3B8E321AB1B4 +3BC4A3099B0D +3BC741376E71 +3C4C95D0A0C7 +3C84B55A5E54 +3C888A88C59D +3D5C8240B2D2 +3DB004172BE7 +3E23271C1C15 +3E3188294ED1 +3E84144A770E +3EA227893101 +3EB914E70076 +3EE6D4A85643 +40DABA780B41 +4119340759A2 +415210E0C6BB +416D21717779 +41B1839829A9 +4201A36DE766 +4261A795D5A7 +42AA0B29626E +430265958BEB +4317C5C16EAD +431D799E0C89 +4342794AD7BB +4387ADE263DB +43982124C310 +4436CB060568 +44449507B736 +44E858C82975 +459BC12982B1 +45AE5DDA9830 +45C414CDC347 +45CE4E504C06 +461744C8EABD +46D012CA3BEC +47170BD112B6 +47C43D5DD234 +47CD4AC26271 +47D410D1C7C4 +4808C5AD0115 +485BEEDBC293 +486001404A80 +488CCC60B70A +49204E3CA169 +495657C78147 +4970714D53D9 +4AA715A0BBB4 +4B9901AEC16E +4BE0B912A5A3 +4CBC34D10D83 +4CD3ACABC6A3 +4CE00134DE1E +4CEB27151C49 +4D02A3D7CE48 +4D13683C7960 +4D1A263BA48B +4D23919463A3 +4D9763C083D9 +4DAC8EE52C68 +4DCB89C7B2E6 +4DD9D9B637C4 +4DE6CB63A920 +4DEBA10CC85D +4E232A8C2E30 +4E2879A411E7 +4EA7B0BED74B +4EB8761372EA +4EC2B23135AB +4EC71DB088DE +4EC9AB4B5519 +50179E461EE6 +50265ED9D468 +5047DC2975BE +508357498162 +508BE54D326E +510A8C52AAC4 +511335CC92CD +518229589A81 +5184D04315D7 +51B4AE31B246 +526EDB918BEE +529CE44BEBCC +52A843082BB3 +52AE9A909674 +5313E9079489 +532DE5E7E0E9 +535508AA6C91 +53691569B669 +540A5B789761 +547B86E57596 +54C649075B57 +552249203848 +55430B5318E9 +5570D22DC66B +55710879E113 +55D2E4AC0446 +56207539825A +564664475726 +566441C5C28C +56A7930913C3 +56C944B04618 +56D455A8BBEA +5726991C8C28 +5726AA3BE37B +573314090BA5 +577C31903867 +577C528E786C +57AD9604ED24 +580C377283C7 +587329CE3EBE +587C34557B36 +58B11E803B58 +5902E4DCC95D +5A060A64C535 +5A36898CA7C5 +5A4740D952EC +5A6ED7966868 +5A99578CAA13 +5AAD6814E68B +5B065568048A +5B6CE0B3AD0A +5B70E0B11758 +5B926E3751EB +5B9CA63C4267 +5BDC1391B289 +5C1D3898D537 +5C34B8E4A456 +5C36456EA1E5 +5C43A75C65A0 +5C5752328A47 +5C9D20250D74 +5CBA3CEE351A +5CD5E98A2864 +5CE0EB9C01B6 +5D384E6A4145 +5D9DB8445155 +5DE8717BB640 +5E1A4EE98748 +5E45A227B391 +5E8E50B3048B +5EB0EA0A9412 +6032C47B7676 +60E0C84ADDEE +612A447A2149 +612D81821854 +616B820EAD01 +616D75A4A022 +61DE2B085AC9 +62312EC272A0 +6232C5262CC6 +62B7C7C9B0D0 +62C531C6E29C +63E6AAAB4433 +644ABCC3DD12 +64AE7BEA1784 +6515B38077D6 +65972038CC25 +65E120DE5E55 +66141DDE8320 +66718BD91332 +668082242328 +668920AEE063 +6696C4332D46 +66C9880D1DC2 +67150CB11E95 +671737BA0054 +673551D0A99E +676D682C4336 +678B98AA2E86 +6847808E63EE +6887A122AA62 +6888C514DEAD +688BD5B7B4E9 +68A99E258692 +68C312391560 +68C9D33E3735 +6900A069E3D7 +690155BE8D8E +69174742042D +69B9CE233517 +6A0B123D7595 +6AB8E2B49E25 +6ABD4C4A72D9 +6B1CC539A1B2 +6B30B6B0925D +6B638C1C950D +6BAAAB1D4589 +6BAD01EBE736 +6BB4ED5E1682 +6CA178E036DA +6CE210B529C4 +6D23D505D2B1 +6D3CBD12BC6D +6D83563EB521 +6D98AB9CCC71 +6E3D7366E78C +6E5582237608 +6E6602904925 +6E77B8EB6444 +6E978A7B16C6 +6EEC05EB651C +70284824B26C +702CDACE0C14 +704E1B85BED8 +70BB123776D6 +70CCC3A2D7C0 +716A747CB931 +7173E199A420 +71BC9C9E31E4 +71CAEEA3B771 +71D8BA423D55 +72253C7DD951 +7260377CD286 +7280858E8B20 +72913BDAB647 +72B5B87BBC6E +72C83B1D098A +72DA8050A38E +735C2AB60A97 +736B602A93D9 +738D7833E7DE +73E7B22D6E54 +74133B1E2DED +74A929877793 +74E3670C045A +7531E3E2A41C +7542A9B65EB4 +7564993C91C7 +760ED0AB626E +762E0E021E38 +763D7E6BB40E +764B38E2903D +768016001C8D +76A616C3D42C +76AE99D9A294 +76BAAA710D25 +76E3B23696BC +77322DD2E184 +77B40902B6D9 +77C0AC14972D +77C1CE0E7674 +77D7B7E2C8BA +78279397A68E +7836593AB838 +783859EB51A6 +78CCDB50C193 +7932684154AE +79604362370E +796630ED27B3 +799E4E270953 +79A00573947A +79B798D66B01 +7A0455D0A7EC +7A33D19B7248 +7B0A8AE18817 +7B0BA045AB35 +7B0DE8504D57 +7B21781EC649 +7B7224C1AB79 +7B90C2BA9B23 +7BB90D382672 +7BBC9DC92836 +7C09DC408C47 +7C418B493454 +7C491D518242 +7C7A86CC727C +7CE836EBD228 +7D49042C530D +7E5744EC286C +7E680A48C383 +7EC45CCEC35A +7EDADA19EB57 +8005BD088847 +8022E705B640 +8031E3565825 +80499BAA5959 +807466CCBAB5 +810518578380 +810D24CB13CC +812B02C34A64 +8163A5DDE1CD +8186CE2B363E +81DE6062B9D7 +822017D8929A +8247C78188C5 +8270D538D5E8 +82D8E8DDE296 +831207CA6E8A +83378A077357 +83A05B477535 +840160379EEE +84044BAB78A7 +84366C6D7781 +8442CC9AA777 +8470AAD30447 +8498740493BB +84A35A698E93 +84ABDE484425 +84B24DBB9A67 +84B723B2A237 +852BEB133D74 +854501E98239 +854A0ED2E77D +85A066D39785 +8619557091AA +86228C3742A4 +8637BB3BA795 +8642D9310B46 +86538085966D +86EE9C410811 +870A042C1B34 +873B47C457E6 +873CE44DDC6B +874D123262E7 +87513C960770 +877641436923 +878A091B74B7 +87927467808B +88C2E39B5990 +88D252AC1A8A +891EDA20BDEA +89267DEE07ED +892CB89ACCC6 +8A2423E9D100 +8A6BC2E3811B +8A8EB5771EE9 +8A906B4B3211 +8AB21B524C5C +8AB823BDC2AE +8AC3B2ADE77B +8AC4317D049B +8ACD6B86EC44 +8AD966CA3B4D +8B0A3B3DCDD4 +8B1B6C705C1A +8B1C75E27153 +8B2A5E0332A1 +8B6216E412DB +8B7CCA9DB004 +8B9999AE9703 +8BABAD9A65C6 +8C32D0AE3DB7 +8C99807368A5 +8CC1133D7D5B +8CD2C872187A +8D0563B86DD4 +8D43D81E37B4 +8D96A800B21A +8D97B475C957 +8DA62EC0C524 +8DACA1BC0636 +8DE3B131D728 +8E55316D3B3D +8EE497C9A869 +90210DDAB57D +9026977EB8A6 +903AA4305025 +9083158A49A1 +9092D12E7967 +90D8713352D1 +911E097A27A9 +9140EC087241 +918A67D05479 +919B1D357E91 +9210BBA2AB26 +9224B6555E30 +9226D4D1236A +922E7955CC67 +929CC86B1B26 +929E1556110E +9302DEB79C5A +9384841B4702 +93B4BD1CB47C +93D985D55712 +940B37939AC6 +94673AE73823 +947A8147E0AE +94CD6A4B6391 +94CEEAC5A8D7 +95ABD3A7C631 +95E1C233EDE2 +9607AE17AD09 +960C98566E52 +96435BD1D29B +965D66E19245 +965D72659982 +9695167B4149 +96D0C3996714 +97274C21BD6C +973186B345BB +973A28C983A3 +979686C51AB6 +97992CE2DD31 +97E9D0C89DA8 +97EB8A44C49D +98314DC363C5 +9860DC044565 +988D023C15A5 +9917BDA7B4D7 +9996A233442A +9A2132B5B625 +9A694755A978 +9A7911ECC275 +9AA1E6CE588C +9ABCCD2AE7C7 +9B39A60D3841 +9C0630361CC5 +9C4E19AB64B1 +9CE96BADE4D8 +9D442B28BD11 +9D4C35AE1A08 +9E02910C691A +9E46407C9024 +9E74D104ACEA +9EDD416A7912 +A026642D13AD +A12908B38536 +A16EE9666D5A +A199132A4043 +A1AEC2B58BBA +A1BE42A15EDE +A1D0844C2C63 +A1E0103A1879 +A253602B9445 +A2B019B46CB9 +A2BBCC3B546C +A2C325A73A9C +A2CB60E815A0 +A314B97C1A6A +A3647146C335 +A3A580799BB4 +A3D30CC8EB97 +A402B5137D86 +A42158CC74B5 +A435DD64AD17 +A4693D21013B +A479A91EED49 +A4B30D146A01 +A5142D626200 +A54056E87CBB +A57DBD287491 +A588C918E327 +A593071D4758 +A5CC0EE7B9E3 +A6375E98A5B5 +A666347B3B4B +A6A203994202 +A6BAE1A1520D +A6E9885AA49D +A705087E89A8 +A7072D4324C7 +A745AD7D6789 +A750456E7C5E +A783A8774651 +A787C822020C +A78BB575EAC5 +A7905680A254 +A805534D84E9 +A86C2595A1C3 +A89903B6ADDB +A9182707A219 +A9391782A846 +A96B08E3A50B +A98DEB0733C9 +A9C37CE71D23 +AA2D69C757D9 +AA4E4558A9EE +AA6C835C9124 +AAC0C35C43EB +AB30CB2CB354 +AB6191DB240A +AB8953D3560C +ABBB521319E6 +AC47461358D7 +AC58C25A1559 +AC7D4B201D92 +AD061A23287D +AD105D52DB36 +AD4EA84D7185 +AD5038D15490 +AD97523144B2 +ADB24E78784B +ADCBD453B232 +AE516A187825 +AE52116C234C +AE817239CAB5 +AEA5A5A0E46B +AECC93678543 +B0452769A83C +B04D71906C60 +B0805C191424 +B09172DDBE43 +B13AE369390C +B14080E570D1 +B1419B62772C +B14775DEA2E2 +B188BA649EA1 +B1BB0DB95C67 +B1BB19BDD424 +B1E8B5054DAD +B1EBB537CC0D +B2174092CDC5 +B2554CC8AD6E +B2C5A2E88304 +B312E56ED250 +B37B48D8C1C5 +B39C699CD208 +B3B121208E34 +B3C3C6E4395B +B410B958C3B8 +B4204546A74E +B45171C5A67D +B4B103E693ED +B4DACABCAB07 +B506567A2B84 +B51083D5C2BD +B54D7674CB90 +B570E5EA1DA3 +B598984AD584 +B5D7E1135821 +B60D053A36D9 +B63957593E23 +B64558CAC0C9 +B68175BCA864 +B6CD1A3EC5BC +B72468A7710D +B75176C82A8B +B7AA0CA5D94A +B7B9D7E523B8 +B808D87AB75C +B93A6432E51A +B941A9D99B6C +B9DA40920237 +BA6C2E10086A +BA7384AB949E +BA8DEEE045E8 +BADC2149EC42 +BB1924266B36 +BB41640E6340 +BBB475DB2B03 +BBD4C4699719 +BC0B2C897267 +BC7BEE6B71C4 +BC8B21AD8802 +BCA2D8118631 +BCB7A7006400 +BCBC6637499B +BCBD2B8BE4B3 +BD213E28C568 +BD32E4EC7080 +BD401D63C3E9 +BD463C3693A4 +BD749E85586A +BD7CA11B9551 +BD96355CBE36 +BD9E6EB7B524 +BDADE6111218 +BDB576D1E88C +BDB5DC09C522 +BE19C75D6B7E +BE5B3ED935AC +BEA20C972E70 +BEEB4A159B37 +C01E8740DE38 +C0411C28857D +C045544AD1E4 +C04660B76831 +C0C4CA21B876 +C0E0E092C8B4 +C0EE394D3D95 +C14601C6B411 +C16EBAE928B2 +C189A791A85B +C1ACDB8C1890 +C1C55A7A99EA +C1D72A47755A +C1D8B91D65AA +C1E6149B386D +C22D8E2B1E37 +C23E999B6298 +C314E31A670D +C3D275A9B8C7 +C3EE19B61C89 +C427B93DC2ED +C443EEC4330D +C477B966D328 +C4C6CAE4784C +C55875BCB82C +C581CA998910 +C5ABC0A455C5 +C5BE33E6B1E2 +C629E0D34581 +C65194543D6B +C67B8E869D90 +C6BC3B9CCB41 +C7034BC581A6 +C748500B6947 +C757C15E9E0D +C798A8465ACB +C7B6702AC17B +C849133B7CCC +C870C98A4E91 +C90B7AD266D3 +C90D996C3A2D +C953797CCE61 +C9639352EEC8 +C983685AA86B +C9CCA6D095A3 +C9CE81D47EDB +C9D449AD9970 +CA0D9CCC4C38 +CA277AC09859 +CA56EB045188 +CAB92B865BAD +CAE8572C2657 +CB1CE185575C +CB2ECC3D9C22 +CB642A081A89 +CBBAD2DA0EC5 +CC1B5BD45315 +CC2C02300D34 +CC559969D0CC +CC5646BD7AEB +CC6A93BD93D1 +CC726DD08765 +CCBBAB6504A4 +CCC1EA3E27B8 +CD16EAB946E9 +CDB4EEE02E14 +CDC21E1E1EC7 +CE09B3870EA2 +CE5AA0C8B5A8 +CE63DE29E069 +D0368B24CA49 +D0489010A72C +D075379A21A6 +D09893B4EE04 +D0A7A2787570 +D0B8C06C02E4 +D106E94A4C3B +D11E7D1BBEEA +D12B25B8DDE2 +D1972D6CE2C3 +D1B91D224946 +D2752E53679D +D35B2B75CC52 +D40E935117A2 +D4C37528DC05 +D4C818A5455E +D4CD56DB8AEB +D5190BD5CED6 +D55E5AA3406D +D576E9D856D9 +D5E444E9D82D +D61A3231790D +D669B3AE1E11 +D6C075899D06 +D6C3503456C4 +D7AC70A05A0C +D80A37B6D7ED +D82E6938C58C +D85E51344EB6 +D8809EB9BA7D +D8913C2D48E9 +D9109460D912 +D94E36427E20 +D97E55B1816A +D99425130C1A +D99C3222A190 +D9A207103ED7 +D9C70CC5818A +DA3379D12773 +DA705702248C +DA818C56CE43 +DAE1888DCC0B +DBA0A2DCA8E0 +DBD9799E15B1 +DC242193D7E3 +DCB5AC62946C +DCB75AEC61A0 +DD6E0587A821 +DD7B1A7C6A82 +DDA22A189095 +DDDAE53AA711 +DDE7304E78B6 +DE1B4DA681B9 +DEAC67E2D7C1 +DEB7D7E4C62B +E127434AB3B7 +E1ACC6742AB7 +E1E59574ADBC +E1EA6BAA03D9 +E222553A59A2 +E2230B8E84C9 +E33E807EC3BA +E341574B2E32 +E42868808B70 +E43562C624B0 +E43D54DC3511 +E466090D2123 +E47069DA0C44 +E49DD6062901 +E4ACA0ADBA0D +E4B976AD6687 +E526BB7888DB +E53354B71B10 +E57581CE8617 +E61A1DA5A60E +E6293BDA5EDC +E64C2A07CA9B +E6600C4D6A44 +E6655B6425DC +E6BADC631036 +E70143BE0091 +E75E07A010D1 +E76962E3B8B4 +E8028A6DCC90 +E80C5E3E8227 +E8779E40450E +E8A9E2D87D36 +E8B5A0BDD993 +E933DA9735C4 +E93A2E63189D +E9447637E40D +E94836269887 +E94D82A564BA +E98DC3B561B5 +E9EB2DE57AE9 +EA490920877D +EA4C494C9353 +EA9B1695DD91 +EAD0E31A6834 +EB16B6462B66 +EB276C9AB68D +EB3C9732C3BA +EB44DDC408CE +EB8536C958B2 +EBC825C186B3 +EC1A55BB58EB +EC2B12107313 +EC8CB5758097 +ECD4C42EA3D1 +ED22B7115435 +ED2CE17A590C +ED65A9B6469C +ED6748113E0D +ED8CEB8B7102 +EDCE0890472D +EDD4A2EA7493 +EE17C426D25E +EE487A4C806E +EE5931913A8D +EED56840AEBA diff --git a/client/dictionaries/mfc_keys_icbmp_sorted.dic b/client/dictionaries/mfc_keys_icbmp_sorted.dic index b4a635d44..2fe3c0235 100644 --- a/client/dictionaries/mfc_keys_icbmp_sorted.dic +++ b/client/dictionaries/mfc_keys_icbmp_sorted.dic @@ -1,1001 +1,1000 @@ - -00383D96411D, -005307DB7853, -009A4C4C6C49, -00C447B8A2D2, -01124119AB54, -0117BAE4D8D9, -018861488381, -0267B4922681, -02974B9786C9, -02A46AC9233A, -02BED876BD48, -02D8A7729ED3, -02EB32B92D30, -03C34821DE9A, -03D87397E9A8, -042CDEE5D0BA, -044ED79417E1, -04524659496E, -04602A40C037, -048451A79DA1, -0490AD0C9283, -04E16965C142, -05138E278443, -052B99EC186E, -056D4B5D2915, -0578E317C419, -05865124E5CA, -0599E014139E, -05DB68DB9364, -066C127C208D, -06966B31A285, -06B577E0E480, -071B57D258CE, -072B300309C9, -0759955331EE, -0769855EEC13, -079B8DA54DB1, -082B68A67491, -0832E4783600, -08506533E741, -0853A982D793, -08629D1DD0D6, -087C0CDA3B46, -08AE4ECD7CE3, -0965220D2ECE, -09A14A80754E, -09ACEA48DD0D, -09DB8EE5458C, -09E6CB76C080, -0A44A754B592, -0A7328887DC2, -0A906663EE1C, -0AB08938E3DA, -0AD8AD0739A6, -0B00220EAE75, -0B1960681E79, -0B31815E6A7C, -0B3690D4B122, -0BB8414CB6EA, -0BEC525E3463, -0C296648344D, -0CB6CC83AC45, -0CCAD03DDBC6, -0D6C26AB25CD, -0DC9143735D1, -0DE8A36CBBCC, -0E175033BD77, -0E6478123917, -0E7D4AC83133, -0E8420B04083, -0EA607E1C4E3, -105743704432, -107A6AB6B305, -110BB6D5539D, -1114A47CC39A, -116AA873ACC8, -120616C6208E, -120C83C06317, -12343D71106C, -123A082E2AEA, -12E50BE60524, -133DC845505E, -138153A4351A, -1395C108B6B6, -1428C04BAAD1, -147D93848C70, -14A353C60820, -1504C1846399, -1523A1E39D03, -1532A2511A8B, -157308368E8E, -16065CC411E0, -1637D8ACA71E, -1639134699C7, -167358BB268E, -168DE72B3B5A, -16A05D5C31C3, -16B4442EAE97, -17197B247A4A, -1774DB1A8CA1, -17820DAA47B2, -1782BEDBD347, -17B561AA82B4, -17C548CBC3A6, -17DA5C873BC5, -18025130661E, -184B95B4E3C6, -18A3196D364B, -18A97BD26818, -18BE810A83DD, -18C3AC2A7E90, -194D4E1DE89D, -196E279BE9A9, -1A2C8D855336, -1A3A76ED470A, -1A55D4849951, -1A9872D00EC9, -1ACD5433BBDD, -1ADC527D5BDA, -1AE29C8CD672, -1B14CAC3D0C2, -1B20A6E1D06B, -1B30A7825B23, -1B3E45AEE657, -1B75E7B007DB, -1B9DABDEBAE0, -1BAB19D01495, -1BD3119E0363, -1BDA0D87A575, -1CD38D77090B, -1D12BBB575B1, -1E1A0DB8729C, -1E2DE60A477A, -1E3C71643766, -1E6ED46CE258, -1EE60A4A8D22, -200D45263629, -2013899194BB, -206CE78E0C6C, -20B51C977E54, -2142B57D369D, -2172D827D3E2, -2178ED80D581, -21B4BE97AE07, -21B91A26133A, -21C7650673CD, -220D815D366A, -22C2176E1CD6, -22C3AB41B123, -233D7B324CEE, -2340CBD61A71, -2348251AD23E, -2381B8214025, -23BAE8DA1AC5, -23C317B8D6DA, -243A41574A39, -248EA5E91987, -2491457885A7, -255A9E590BCC, -257192699E32, -25892216C620, -2595E5B1DE76, -25AE69DED1B4, -25BA8775B3C4, -25D967D4DD35, -25DB996D56ED, -25EE21CDE4B9, -2625E408276B, -26B744C673DB, -26C6D38B8257, -26D787613684, -27689527E201, -27743B5A5736, -27D1635ED1B3, -27D5B8D2642E, -28035CA5B300, -2812EB6A427C, -28133B46730A, -281499DD16A0, -281DD9E6C98E, -2870E08CEDBA, -28B8685B1B22, -28C3D17E4DEC, -2953C63E9E58, -295D3C9A8B28, -297B74853CAA, -29ACACC2828E, -29EA97BC4A6B, -29EB3CA1C0DE, -2A079CC2AD37, -2A27E0602400, -2A45A0D8D6EE, -2A47CDD3A322, -2A4C4DB1D71D, -2AA82B4B6711, -2ABD68BDC5A3, -2AE7BDB10CB4, -2B051C90BE82, -2B490231E063, -2BAB94372644, -2C03252C10E7, -2C3EE5E98804, -2CB671E6365D, -2CC55B46705B, -2CD09D3C0A1B, -2CECBC323E31, -2D302827C9B4, -2D716C9C467B, -2D8856109732, -2E15681A4355, -2E79209B9519, -2EEE063290C1, -301C9AA3DECA, -30C520D6A2B9, -30D6324910AB, -3113AADC9D6B, -3124ACA5491C, -315AD0D6E6D2, -31A16DAC864D, -31EC44581294, -32DE3CD81C24, -32E532232C29, -33256E443128, -33293485AD61, -33305B0365AA, -3343B72BAA71, -3372C9C5D4AE, -33754E0D1687, -33A444334869, -33B54345C32E, -34002AAEE45D, -343C556CEE59, -3444DDE6D7E5, -345B62452538, -3495A04A9270, -34EB673C863B, -35123500C1EA, -353A7167576B, -3599856810B2, -35E7DE9899EE, -35EDABB506D8, -36C54912D10E, -36CA0101B6DC, -36D268442846, -373E5827E0B8, -376D6C446746, -37E2EAE635B5, -381B0A70E135, -3862B259DC71, -386676C44A13, -3905679DEEC4, -39070618BB17, -394181105544, -395D38815892, -39A00E856381, -39C0E2ED99B5, -3A1E82E2CDB7, -3A5D13E05B6A, -3A6DE2081CDD, -3A8498924010, -3A9D49E8BEB2, -3AD0EE1031A9, -3B052E65D40A, -3B4986981212, -3B4C51ACC53D, -3B99486097C6, -3BB36BC22CE4, -3BB4B3025B79, -3BBB7BD8D7B7, -3C09C971D835, -3C4A12E7A107, -3C633B3474DD, -3CB9E31D6022, -3CD344A7EB21, -3CD8C6705954, -3CE887B9D091, -3D5EA1C71953, -3D89120EB993, -3D9C3245AE76, -3DED9D496478, -3E0913A96E74, -3E34909990B5, -3E7DD7953DDD, -3EEB33434C1A, -4015D16B5C1C, -401C81A72C56, -40E7B8D60242, -41016C0CB8DE, -4124864B0D40, -415BAA0CAB15, -418184DBB4A0, -419513740558, -4195EE7238CC, -41B727883B27, -41BC44A8C3C6, -41DDC3A48EEA, -420445087613, -42068108DE36, -4245921D73CA, -42A959953C45, -430E67734C18, -4314D9D03B95, -43166BCA83EB, -43400A093A7E, -434CE764DE91, -43595AC786EE, -438099331C1E, -43814087A7B5, -438C3CD95B58, -43B3E895B281, -44074C461042, -444D37149B20, -44A04DAA30CB, -4537282554C5, -4584EACB6087, -45DB3799C150, -45E599AE38EA, -462305611C4A, -4636195CDA2D, -46752993E2E9, -4684316440D6, -46C7246C1958, -4751A5274848, -4761E34CB054, -476388408D8E, -478947735B45, -47AD81972D5B, -47C23398EA52, -47E9D4D4BE35, -4812AEC4B01A, -48276645A4EA, -48644467A214, -489C783B3514, -48C860AA4B74, -495C6639575B, -49681C20A00D, -49E8249DD677, -49E93C110AA1, -4A24470C19C5, -4A4755BC4A2A, -4A4D5E3A9011, -4A65D627625C, -4A6B36C5BCCC, -4AB725ED89B5, -4B39E3923D0D, -4B59316C10E0, -4C275C8BB2DA, -4C2E9455D296, -4C44DB1D0C3A, -4C67059B0006, -4CA30E1A298A, -4CA74DAC7C01, -4CB212D72D57, -4CD3B228EBB4, -4CE1972E090C, -4CEE1794E0EA, -4D06DBCA167E, -4D2CC85EB338, -4D40BC7A44DB, -4D769DA515D3, -4D79C95DAD2D, -4DBAC8ECE167, -4E3CB839E87D, -4E3D548E1267, -4E8250E29617, -4E94C7962769, -5038884E4178, -505B5A8EB20A, -50642C36DA00, -5083664D8C09, -50B77DA96DE2, -511E269A9BAE, -51798AEAAE9E, -51ED5833AB6D, -525335E4CD34, -5261CDDA279E, -526E55542A54, -529C16A720AB, -52A230B1C50E, -52AADA374811, -52D20D6E3E35, -534BB4A6984E, -5352CCC3DCD2, -540B15E8019D, -54AA2915E815, -558DB8891A90, -55A691710B48, -55D1E91B1D35, -55D95774E9A0, -563C6B96D59D, -567032E13B54, -56741B108D22, -57029D991123, -5714E9D33034, -5734CD8A65DA, -5785EE00049E, -57B8B111491D, -57CC9D0AA32B, -57D7D4D746DA, -583C936DCB4B, -586B470A43B3, -5876E1D34183, -58B6AE62DB88, -58C35C8BC9AB, -597E98000ED4, -59DB4DBB5D7A, -5A150653E624, -5A211CE57C4B, -5A6272CDBE9C, -5ACB8043C10C, -5B41CEBC2213, -5B59BCC4321E, -5BA03479BB8C, -5BC64C42281C, -5C9B1A8E31CD, -5C9BD0AC1DB1, -5D223E990AD8, -5D8C3A5C5761, -5DA57EACA38C, -5E41DD5D1154, -5E6ABB51EC75, -5E7CC04C3A58, -5E810C48C8D8, -5E8943D9A836, -5ED616273468, -60100DD0E023, -6033A1C0E431, -6088A566CC60, -60B20ADA0471, -60B8411D876E, -60C742D8D9C0, -6135433CC5EA, -6153ADD80A15, -61718ED2C94D, -6175241B035A, -61780BCB0C57, -61B701698050, -61C4E56629A3, -61D59C284952, -61E57B490A55, -622E5E0812D7, -6251CE7E547A, -62953A89B137, -62D6EAA06CD6, -630228659A47, -632931BE8EC7, -63539BB89DEE, -636CB69BB10C, -63783393E20D, -639DB16995B7, -63AA2A5B076C, -63B636458E94, -6443E64DCC4B, -64695084C575, -6493D06D5710, -649B302A97C5, -64B8632B54D4, -654BACB21C3B, -65A3D5823819, -65DEDABD1B34, -6608944EE186, -665B8B24C20D, -6685D0BE19E0, -66933A9E7982, -674C7BB59A16, -675E35EE359E, -67AA98E362C9, -67D47C1B6425, -67DE22850162, -67E8B986B2A7, -681EA28BA6CD, -6828B52B6507, -6874E54471E8, -6879B1CA44A3, -68C00A810D41, -68C9E8AA5C3E, -697A8ED07418, -69B5357A617A, -6A7B3A7B6735, -6AA40421D23C, -6AB676B4DB9D, -6B00420BE41C, -6B0B7B967871, -6B9D041136B4, -6BB1A14768A8, -6BCAE24D9700, -6C0458728774, -6C57CBD51995, -6C5E10B86CDE, -6CA491A8C7B8, -6CBC25C1DA2E, -6CD430D99958, -6CEC27647CC0, -6D4D29CEB9B5, -6D6E9A6B725D, -6D801AC74572, -6D97408C6D60, -6DDE6E871C64, -6DEA848B6195, -6E05B5C44A54, -6E751666AE9A, -6E7DBCDA05B3, -7004BA1763ED, -7016ECD01559, -7076D48D5E49, -7091621EA016, -709311997549, -70984C14D3DB, -70D73BE22CDD, -70D9461C5E90, -712BC18422CB, -712E6CAA74A4, -7164042BA89E, -7175E14A4D62, -718B39561350, -718BDA352E28, -719B1418323E, -71A8D54D82B3, -71DC30168C27, -7221E016597B, -7234CC6BD65D, -727A80DD5296, -72B393D6E8A9, -732C9BE4DDBA, -736B4A835B2B, -73EA81968900, -740AB5126199, -741A31054E6B, -74498C1D4B3D, -745276053CB6, -74684B0B4B1D, -74772915E24C, -74A24BE33BE2, -74A778236D5A, -74AA58008A31, -74C27A96CB3A, -754AD5773746, -756C15E54212, -759403A563D8, -759D2130312B, -75A0E10D8C84, -75A807E46B96, -75E454785C6C, -76078A25C088, -76140285B768, -763D835BD5ED, -767C33468C72, -76962C07EC9E, -76984E62CCE4, -769AE4646931, -76E5DA67A1EC, -7708D5CAD58B, -77383BAA4D90, -7789E646A556, -779A248E098C, -77DB71037644, -77E0A57DD456, -7853D464E2A4, -78EA6EB04463, -7909427EC8B9, -7910A31ECD19, -79271963B6E8, -793D98517D33, -79B7A4C58DE0, -79B9148761B3, -7A2893B75AD1, -7A4C61A1B48D, -7A7469B69C6A, -7AA84B1A527D, -7B00211CA416, -7B118EABC7BB, -7B1D9A2E22AA, -7B583D350740, -7B9D3A6BD061, -7C2DAC2CC775, -7C4CBBD2DDE1, -7CD52B5B8E77, -7D412100532B, -7D46C149DAD9, -7D4CA630E229, -7DAC0E83D335, -7DC935E220A0, -7DCA66BACA13, -7E30778792D2, -7E43C3BAB3CB, -7E475BA186E6, -7EE2A624851A, -80CED5362B2C, -80D2CC78E10B, -80D62251E20C, -816875D55ED1, -81950D0517AC, -81B519418C3E, -8211571B9D16, -823C7CC6E06A, -826DD63B9032, -827303C574B5, -82C5ADED4B81, -82E344329D34, -83588E140165, -835D33B48113, -8384148AE52D, -8394B57153D6, -83A0184757C0, -83D86835B48B, -8502EE9A7E85, -852C2B72659D, -8534A6CE0911, -85ABD94CD7A9, -85DA8099CD7E, -85E0B6B26945, -864CA2A6BE93, -868A33A44447, -86EDEABCC357, -87DDD5A188EE, -8830379B50B7, -883803A3360C, -883DA78EC87D, -88482A12C2C6, -888EBD3DB945, -88D026793359, -88DD4B7C5991, -8931DC3733D4, -894D8E2DCDEE, -897B845C2680, -89B638BD909E, -89D2C28BE578, -8A1869848D1A, -8A39D09508C9, -8ACCC7290C8C, -8AD8B41EC218, -8B028B7E6D60, -8B6A95C7D2E2, -8BA1226EBA21, -8BD586B21ABC, -8C0EA504B635, -8CA939DC6DE4, -8CAE5D688443, -8CEC639E64DC, -8DECE0DD29DE, -8E0EC762E883, -8E958D8B8C52, -8EB64D710C88, -8ED4A17717D9, -8EE9D9C03A0D, -9014E1430AEB, -90965DEBC8B9, -90E56E616DDD, -912CD8E04437, -912E33563E1B, -918048032247, -919402EC39CB, -91D28E2B126D, -9216EEE5B677, -9232215296B2, -925A070E9096, -925A5521D48D, -92CC200886A2, -932035869655, -937144459949, -93B260DBC70A, -94552B863E37, -95327A0A3600, -954275CDD7E0, -957E6EE3EB55, -95B920CACC84, -96382E1C8E12, -964E8E5338BD, -96706C8D6ECC, -96759A0D5566, -96D5213C5DDB, -97300764797A, -973BDDBE7434, -974838AE17A0, -9752A6B316D5, -97926543783B, -97EB373096CA, -982D6054B83D, -989D127BD496, -98A54AD58A43, -98A92128364C, -98CD5AA2A4DB, -98E8C543688E, -99207A00AA4A, -99243E754CB8, -9925893ABAC7, -9937553A965E, -9976E6ADE0C9, -9982E3E6A4A0, -9984C1A3229E, -99C487AB85EC, -99E2A19C9673, -9A05EBE41D7D, -9A138D1A5CB7, -9A179148B824, -9A6EC0A9ECB8, -9A720CBD7BB1, -9AB22BBDDD87, -9AC43B5A06D8, -9AD8150BE648, -9AD97423190D, -9B4ADDDEB749, -9B7603341727, -9C45237377BE, -9D090AE1A15E, -9D59641E40A5, -9DA4528CEB8C, -9DA728164176, -9DAC62A346B7, -9E0E9D983B9A, -9E5271763D3D, -9EE95586D024, -9EEE39E00CBB, -A04671256EE2, -A091485B4B5D, -A1B5577ED36E, -A1EB280E3901, -A2789E1DD888, -A293A90AE72C, -A309E3AEBDB9, -A3196E77B072, -A31E72DCC826, -A34DEA01690E, -A36031D6ECB2, -A38044A3E18E, -A421D7A04C4B, -A424C686CA39, -A44590A779A5, -A47AD3895C63, -A5041E8B8E22, -A50DC0830AA5, -A52B8929D665, -A5BCBA6BE592, -A61D5137E6B3, -A6344C0418DC, -A690A817B9D9, -A7E3B3459240, -A81E6D3C8E11, -A8C0BE436685, -A8DE205120A8, -A91E2BE6C308, -A9258D6B06B5, -A992B5E070C1, -AAC6E3205D48, -AB101546634E, -AB6EE0761ACA, -AB9BCA200547, -AC4BC5B2D3C0, -AC7A0B47B03E, -AC88B26AC1D0, -ACAEB3456AD9, -ACB906631D8A, -ACE07B45C0C5, -AD1992AE37CA, -AD5586744A60, -AD674E4ADB79, -ADA093B06831, -AE7C3AE5334A, -AE9EB8CAB2C3, -AEAE9E5CE65D, -B002D1BDC29B, -B0463E703098, -B063B209BB20, -B0788BE3BAA4, -B0C3B3299090, -B128298D9073, -B160677E7035, -B19D3D57176A, -B1CCDB7999B9, -B231AA398B90, -B250E9590215, -B28BE0D819ED, -B292C9554CBA, -B2D8485C2460, -B31763D9D0DE, -B328014DDD6A, -B378C424C9E2, -B3D8C03C78E0, -B41D18E3B980, -B46824B972E9, -B50383A32302, -B509D631967C, -B56CA847A7C3, -B56EC9A20D28, -B5B763215C82, -B6550EAC573A, -B66060201705, -B6614EBEAAA2, -B6A18CBD4DA6, -B6ABB62E437E, -B6C6558E58CA, -B7009204D512, -B71D5B22B1C2, -B7392DD1E497, -B7709ED7CE60, -B7A26320A491, -B7A9DA22E9C6, -B7DEC863369D, -B7E9A91174CB, -B8178A34E2DC, -B83092098A7D, -B84C50E56DEC, -B89BD135E935, -B8E87380D361, -B9485A9648C6, -B9ED829C22AE, -BA227EE91818, -BA7BBD9683B1, -BA8224EA7A80, -BA84C974B356, -BAD293A45C8A, -BB850C7E4934, -BBC1256810A4, -BC1CD369549E, -BC5C76E5909C, -BC66E9270049, -BC6AB08B03CC, -BC74CA2C2B06, -BC7C64828C1D, -BCCC3A719013, -BD06E96EB7D7, -BD196D0A74E0, -BE02790E84AC, -BE1266314B9D, -BE518C742B74, -BE5695316117, -BE5D8EBA120D, -BE8286DA7D12, -BE9CE00EE4DD, -C003962B3462, -C0067E095049, -C015A21E0146, -C03BC03AD437, -C06CE7D57A0D, -C07EE1E10B56, -C0885A29251E, -C198163ABECE, -C1EB7337A035, -C225479C7064, -C2740E1665A8, -C27924128A00, -C2A701656B8B, -C2C30D21C53E, -C2CBB2ACD38D, -C38D19A9C8D1, -C3B1BB7E7492, -C3BA2438A981, -C3CD74758DE2, -C4033B3BB1D7, -C404D280640E, -C4467DE80B2D, -C46A048C88DD, -C52877867C05, -C56D005E258E, -C56D052D5533, -C5BB2CCCB9C3, -C5C272694A1E, -C6121BC4A29C, -C65EEAE02433, -C661C4AE1DD1, -C76C94B495CA, -C7BD49777A79, -C7CD131E9B60, -C7E35D6294BA, -C8E173DB04CC, -C95855AE08E8, -C98147E69033, -C99A004E6133, -C9E893C4090B, -CA119C79A197, -CA309D2CBC41, -CA4BAA390BC4, -CA92DD257E21, -CA968EBEB9C7, -CADED0C50AC4, -CB18774EA550, -CB1999D19E10, -CB75C1BAE669, -CC2517AB2346, -CC2AC1AD29CA, -CD11359C7A90, -CD14C8553CB9, -CD333295BBE2, -CD3DB8C27E5C, -CDA811AD5055, -CDABDCA23986, -CDCA8BD7B002, -CE0456AB0DCE, -CE58AE1C51E9, -CE76E8A600DC, -CE95875316C8, -CEB105E65289, -CEB651752D4C, -CEE02D97E5BD, -D023DB35ED05, -D0BE546CC06B, -D0CE7EB0D379, -D10329D366C8, -D15C004DBC8D, -D16E6B668254, -D1CEEC977644, -D1DC0E1CC09E, -D2550925679B, -D28B2D42DE1A, -D2926519AC09, -D313116A45B4, -D3DC10453857, -D431C8C73BDC, -D4C67846791C, -D5629384CE7D, -D5ABE7180600, -D62A4A0E57C2, -D660CE9E3080, -D66AE9282140, -D6A91C14AC47, -D6E23B4E75C6, -D726C4979654, -D76DE12943B4, -D7A405AD9E4E, -D7BD3AE48E93, -D7D49700BBCC, -D7E8A5089E7A, -D84C81EE910D, -D8545199A949, -D86243C1380E, -D88A12EB3622, -D89B5EA419C1, -D8A3690B0115, -D94646A4C65B, -D982B4846A96, -DA303BADB013, -DAD9A48A8C33, -DAEB5D63920B, -DB01A99DD94C, -DB22BB7D6818, -DB37160CBB4B, -DB7E3687E450, -DC7697E37A9B, -DCC44C4E9269, -DCCE477E785E, -DD68DE9CDA5A, -DE1B08C6D94B, -DE41BBD7E68D, -DE6E04AE4475, -DE8CD4277A9E, -DEA8098D6E51, -DEB2BEE8858A, -DEB550958AD9, -E045E6309471, -E0E21213C611, -E0E457054B62, -E1097C69DA4A, -E1EA831EA514, -E20716902884, -E2C9CB14C06C, -E33B66EA2705, -E34C5B12BABA, -E38A1C654E82, -E3905BA54194, -E3E3919444CA, -E4450EC1010C, -E49A03306224, -E5100AC4C6C3, -E5124DB665A6, -E5491B5E3DD6, -E5BE9C989A29, -E5C3A9A27D3E, -E65111EB1E40, -E65792427D4C, -E7004C5EA94A, -E705087DECBB, -E7CB93E68155, -E81512343BAD, -E8428C8B0740, -E859EBC22318, -E87267A508DB, -E886AE7D1BE0, -E8B008239600, -E8C4B4A4E482, -E8D53410B736, -E902964DA28D, -E9203D5BD2DA, -E9526CACA8B2, -E9C11D763BEC, -EA3BDAA4E498, -EA61AC8B4969, -EA8E8ADC26B9, -EB5588EAE5E8, -EBA964C07075, -EC71B679D3AA, -ECB4019ADD97, -ED14D0A14B0C, -ED296C79266C, -EDBA3C943EA8, -EDC7CEBD4000, -EDE2747DA6C3, -EE3029556CEB, -EE49610E6121, -EEB704D69BCA, -EED69A391464, +00383D96411D +005307DB7853 +009A4C4C6C49 +00C447B8A2D2 +01124119AB54 +0117BAE4D8D9 +018861488381 +0267B4922681 +02974B9786C9 +02A46AC9233A +02BED876BD48 +02D8A7729ED3 +02EB32B92D30 +03C34821DE9A +03D87397E9A8 +042CDEE5D0BA +044ED79417E1 +04524659496E +04602A40C037 +048451A79DA1 +0490AD0C9283 +04E16965C142 +05138E278443 +052B99EC186E +056D4B5D2915 +0578E317C419 +05865124E5CA +0599E014139E +05DB68DB9364 +066C127C208D +06966B31A285 +06B577E0E480 +071B57D258CE +072B300309C9 +0759955331EE +0769855EEC13 +079B8DA54DB1 +082B68A67491 +0832E4783600 +08506533E741 +0853A982D793 +08629D1DD0D6 +087C0CDA3B46 +08AE4ECD7CE3 +0965220D2ECE +09A14A80754E +09ACEA48DD0D +09DB8EE5458C +09E6CB76C080 +0A44A754B592 +0A7328887DC2 +0A906663EE1C +0AB08938E3DA +0AD8AD0739A6 +0B00220EAE75 +0B1960681E79 +0B31815E6A7C +0B3690D4B122 +0BB8414CB6EA +0BEC525E3463 +0C296648344D +0CB6CC83AC45 +0CCAD03DDBC6 +0D6C26AB25CD +0DC9143735D1 +0DE8A36CBBCC +0E175033BD77 +0E6478123917 +0E7D4AC83133 +0E8420B04083 +0EA607E1C4E3 +105743704432 +107A6AB6B305 +110BB6D5539D +1114A47CC39A +116AA873ACC8 +120616C6208E +120C83C06317 +12343D71106C +123A082E2AEA +12E50BE60524 +133DC845505E +138153A4351A +1395C108B6B6 +1428C04BAAD1 +147D93848C70 +14A353C60820 +1504C1846399 +1523A1E39D03 +1532A2511A8B +157308368E8E +16065CC411E0 +1637D8ACA71E +1639134699C7 +167358BB268E +168DE72B3B5A +16A05D5C31C3 +16B4442EAE97 +17197B247A4A +1774DB1A8CA1 +17820DAA47B2 +1782BEDBD347 +17B561AA82B4 +17C548CBC3A6 +17DA5C873BC5 +18025130661E +184B95B4E3C6 +18A3196D364B +18A97BD26818 +18BE810A83DD +18C3AC2A7E90 +194D4E1DE89D +196E279BE9A9 +1A2C8D855336 +1A3A76ED470A +1A55D4849951 +1A9872D00EC9 +1ACD5433BBDD +1ADC527D5BDA +1AE29C8CD672 +1B14CAC3D0C2 +1B20A6E1D06B +1B30A7825B23 +1B3E45AEE657 +1B75E7B007DB +1B9DABDEBAE0 +1BAB19D01495 +1BD3119E0363 +1BDA0D87A575 +1CD38D77090B +1D12BBB575B1 +1E1A0DB8729C +1E2DE60A477A +1E3C71643766 +1E6ED46CE258 +1EE60A4A8D22 +200D45263629 +2013899194BB +206CE78E0C6C +20B51C977E54 +2142B57D369D +2172D827D3E2 +2178ED80D581 +21B4BE97AE07 +21B91A26133A +21C7650673CD +220D815D366A +22C2176E1CD6 +22C3AB41B123 +233D7B324CEE +2340CBD61A71 +2348251AD23E +2381B8214025 +23BAE8DA1AC5 +23C317B8D6DA +243A41574A39 +248EA5E91987 +2491457885A7 +255A9E590BCC +257192699E32 +25892216C620 +2595E5B1DE76 +25AE69DED1B4 +25BA8775B3C4 +25D967D4DD35 +25DB996D56ED +25EE21CDE4B9 +2625E408276B +26B744C673DB +26C6D38B8257 +26D787613684 +27689527E201 +27743B5A5736 +27D1635ED1B3 +27D5B8D2642E +28035CA5B300 +2812EB6A427C +28133B46730A +281499DD16A0 +281DD9E6C98E +2870E08CEDBA +28B8685B1B22 +28C3D17E4DEC +2953C63E9E58 +295D3C9A8B28 +297B74853CAA +29ACACC2828E +29EA97BC4A6B +29EB3CA1C0DE +2A079CC2AD37 +2A27E0602400 +2A45A0D8D6EE +2A47CDD3A322 +2A4C4DB1D71D +2AA82B4B6711 +2ABD68BDC5A3 +2AE7BDB10CB4 +2B051C90BE82 +2B490231E063 +2BAB94372644 +2C03252C10E7 +2C3EE5E98804 +2CB671E6365D +2CC55B46705B +2CD09D3C0A1B +2CECBC323E31 +2D302827C9B4 +2D716C9C467B +2D8856109732 +2E15681A4355 +2E79209B9519 +2EEE063290C1 +301C9AA3DECA +30C520D6A2B9 +30D6324910AB +3113AADC9D6B +3124ACA5491C +315AD0D6E6D2 +31A16DAC864D +31EC44581294 +32DE3CD81C24 +32E532232C29 +33256E443128 +33293485AD61 +33305B0365AA +3343B72BAA71 +3372C9C5D4AE +33754E0D1687 +33A444334869 +33B54345C32E +34002AAEE45D +343C556CEE59 +3444DDE6D7E5 +345B62452538 +3495A04A9270 +34EB673C863B +35123500C1EA +353A7167576B +3599856810B2 +35E7DE9899EE +35EDABB506D8 +36C54912D10E +36CA0101B6DC +36D268442846 +373E5827E0B8 +376D6C446746 +37E2EAE635B5 +381B0A70E135 +3862B259DC71 +386676C44A13 +3905679DEEC4 +39070618BB17 +394181105544 +395D38815892 +39A00E856381 +39C0E2ED99B5 +3A1E82E2CDB7 +3A5D13E05B6A +3A6DE2081CDD +3A8498924010 +3A9D49E8BEB2 +3AD0EE1031A9 +3B052E65D40A +3B4986981212 +3B4C51ACC53D +3B99486097C6 +3BB36BC22CE4 +3BB4B3025B79 +3BBB7BD8D7B7 +3C09C971D835 +3C4A12E7A107 +3C633B3474DD +3CB9E31D6022 +3CD344A7EB21 +3CD8C6705954 +3CE887B9D091 +3D5EA1C71953 +3D89120EB993 +3D9C3245AE76 +3DED9D496478 +3E0913A96E74 +3E34909990B5 +3E7DD7953DDD +3EEB33434C1A +4015D16B5C1C +401C81A72C56 +40E7B8D60242 +41016C0CB8DE +4124864B0D40 +415BAA0CAB15 +418184DBB4A0 +419513740558 +4195EE7238CC +41B727883B27 +41BC44A8C3C6 +41DDC3A48EEA +420445087613 +42068108DE36 +4245921D73CA +42A959953C45 +430E67734C18 +4314D9D03B95 +43166BCA83EB +43400A093A7E +434CE764DE91 +43595AC786EE +438099331C1E +43814087A7B5 +438C3CD95B58 +43B3E895B281 +44074C461042 +444D37149B20 +44A04DAA30CB +4537282554C5 +4584EACB6087 +45DB3799C150 +45E599AE38EA +462305611C4A +4636195CDA2D +46752993E2E9 +4684316440D6 +46C7246C1958 +4751A5274848 +4761E34CB054 +476388408D8E +478947735B45 +47AD81972D5B +47C23398EA52 +47E9D4D4BE35 +4812AEC4B01A +48276645A4EA +48644467A214 +489C783B3514 +48C860AA4B74 +495C6639575B +49681C20A00D +49E8249DD677 +49E93C110AA1 +4A24470C19C5 +4A4755BC4A2A +4A4D5E3A9011 +4A65D627625C +4A6B36C5BCCC +4AB725ED89B5 +4B39E3923D0D +4B59316C10E0 +4C275C8BB2DA +4C2E9455D296 +4C44DB1D0C3A +4C67059B0006 +4CA30E1A298A +4CA74DAC7C01 +4CB212D72D57 +4CD3B228EBB4 +4CE1972E090C +4CEE1794E0EA +4D06DBCA167E +4D2CC85EB338 +4D40BC7A44DB +4D769DA515D3 +4D79C95DAD2D +4DBAC8ECE167 +4E3CB839E87D +4E3D548E1267 +4E8250E29617 +4E94C7962769 +5038884E4178 +505B5A8EB20A +50642C36DA00 +5083664D8C09 +50B77DA96DE2 +511E269A9BAE +51798AEAAE9E +51ED5833AB6D +525335E4CD34 +5261CDDA279E +526E55542A54 +529C16A720AB +52A230B1C50E +52AADA374811 +52D20D6E3E35 +534BB4A6984E +5352CCC3DCD2 +540B15E8019D +54AA2915E815 +558DB8891A90 +55A691710B48 +55D1E91B1D35 +55D95774E9A0 +563C6B96D59D +567032E13B54 +56741B108D22 +57029D991123 +5714E9D33034 +5734CD8A65DA +5785EE00049E +57B8B111491D +57CC9D0AA32B +57D7D4D746DA +583C936DCB4B +586B470A43B3 +5876E1D34183 +58B6AE62DB88 +58C35C8BC9AB +597E98000ED4 +59DB4DBB5D7A +5A150653E624 +5A211CE57C4B +5A6272CDBE9C +5ACB8043C10C +5B41CEBC2213 +5B59BCC4321E +5BA03479BB8C +5BC64C42281C +5C9B1A8E31CD +5C9BD0AC1DB1 +5D223E990AD8 +5D8C3A5C5761 +5DA57EACA38C +5E41DD5D1154 +5E6ABB51EC75 +5E7CC04C3A58 +5E810C48C8D8 +5E8943D9A836 +5ED616273468 +60100DD0E023 +6033A1C0E431 +6088A566CC60 +60B20ADA0471 +60B8411D876E +60C742D8D9C0 +6135433CC5EA +6153ADD80A15 +61718ED2C94D +6175241B035A +61780BCB0C57 +61B701698050 +61C4E56629A3 +61D59C284952 +61E57B490A55 +622E5E0812D7 +6251CE7E547A +62953A89B137 +62D6EAA06CD6 +630228659A47 +632931BE8EC7 +63539BB89DEE +636CB69BB10C +63783393E20D +639DB16995B7 +63AA2A5B076C +63B636458E94 +6443E64DCC4B +64695084C575 +6493D06D5710 +649B302A97C5 +64B8632B54D4 +654BACB21C3B +65A3D5823819 +65DEDABD1B34 +6608944EE186 +665B8B24C20D +6685D0BE19E0 +66933A9E7982 +674C7BB59A16 +675E35EE359E +67AA98E362C9 +67D47C1B6425 +67DE22850162 +67E8B986B2A7 +681EA28BA6CD +6828B52B6507 +6874E54471E8 +6879B1CA44A3 +68C00A810D41 +68C9E8AA5C3E +697A8ED07418 +69B5357A617A +6A7B3A7B6735 +6AA40421D23C +6AB676B4DB9D +6B00420BE41C +6B0B7B967871 +6B9D041136B4 +6BB1A14768A8 +6BCAE24D9700 +6C0458728774 +6C57CBD51995 +6C5E10B86CDE +6CA491A8C7B8 +6CBC25C1DA2E +6CD430D99958 +6CEC27647CC0 +6D4D29CEB9B5 +6D6E9A6B725D +6D801AC74572 +6D97408C6D60 +6DDE6E871C64 +6DEA848B6195 +6E05B5C44A54 +6E751666AE9A +6E7DBCDA05B3 +7004BA1763ED +7016ECD01559 +7076D48D5E49 +7091621EA016 +709311997549 +70984C14D3DB +70D73BE22CDD +70D9461C5E90 +712BC18422CB +712E6CAA74A4 +7164042BA89E +7175E14A4D62 +718B39561350 +718BDA352E28 +719B1418323E +71A8D54D82B3 +71DC30168C27 +7221E016597B +7234CC6BD65D +727A80DD5296 +72B393D6E8A9 +732C9BE4DDBA +736B4A835B2B +73EA81968900 +740AB5126199 +741A31054E6B +74498C1D4B3D +745276053CB6 +74684B0B4B1D +74772915E24C +74A24BE33BE2 +74A778236D5A +74AA58008A31 +74C27A96CB3A +754AD5773746 +756C15E54212 +759403A563D8 +759D2130312B +75A0E10D8C84 +75A807E46B96 +75E454785C6C +76078A25C088 +76140285B768 +763D835BD5ED +767C33468C72 +76962C07EC9E +76984E62CCE4 +769AE4646931 +76E5DA67A1EC +7708D5CAD58B +77383BAA4D90 +7789E646A556 +779A248E098C +77DB71037644 +77E0A57DD456 +7853D464E2A4 +78EA6EB04463 +7909427EC8B9 +7910A31ECD19 +79271963B6E8 +793D98517D33 +79B7A4C58DE0 +79B9148761B3 +7A2893B75AD1 +7A4C61A1B48D +7A7469B69C6A +7AA84B1A527D +7B00211CA416 +7B118EABC7BB +7B1D9A2E22AA +7B583D350740 +7B9D3A6BD061 +7C2DAC2CC775 +7C4CBBD2DDE1 +7CD52B5B8E77 +7D412100532B +7D46C149DAD9 +7D4CA630E229 +7DAC0E83D335 +7DC935E220A0 +7DCA66BACA13 +7E30778792D2 +7E43C3BAB3CB +7E475BA186E6 +7EE2A624851A +80CED5362B2C +80D2CC78E10B +80D62251E20C +816875D55ED1 +81950D0517AC +81B519418C3E +8211571B9D16 +823C7CC6E06A +826DD63B9032 +827303C574B5 +82C5ADED4B81 +82E344329D34 +83588E140165 +835D33B48113 +8384148AE52D +8394B57153D6 +83A0184757C0 +83D86835B48B +8502EE9A7E85 +852C2B72659D +8534A6CE0911 +85ABD94CD7A9 +85DA8099CD7E +85E0B6B26945 +864CA2A6BE93 +868A33A44447 +86EDEABCC357 +87DDD5A188EE +8830379B50B7 +883803A3360C +883DA78EC87D +88482A12C2C6 +888EBD3DB945 +88D026793359 +88DD4B7C5991 +8931DC3733D4 +894D8E2DCDEE +897B845C2680 +89B638BD909E +89D2C28BE578 +8A1869848D1A +8A39D09508C9 +8ACCC7290C8C +8AD8B41EC218 +8B028B7E6D60 +8B6A95C7D2E2 +8BA1226EBA21 +8BD586B21ABC +8C0EA504B635 +8CA939DC6DE4 +8CAE5D688443 +8CEC639E64DC +8DECE0DD29DE +8E0EC762E883 +8E958D8B8C52 +8EB64D710C88 +8ED4A17717D9 +8EE9D9C03A0D +9014E1430AEB +90965DEBC8B9 +90E56E616DDD +912CD8E04437 +912E33563E1B +918048032247 +919402EC39CB +91D28E2B126D +9216EEE5B677 +9232215296B2 +925A070E9096 +925A5521D48D +92CC200886A2 +932035869655 +937144459949 +93B260DBC70A +94552B863E37 +95327A0A3600 +954275CDD7E0 +957E6EE3EB55 +95B920CACC84 +96382E1C8E12 +964E8E5338BD +96706C8D6ECC +96759A0D5566 +96D5213C5DDB +97300764797A +973BDDBE7434 +974838AE17A0 +9752A6B316D5 +97926543783B +97EB373096CA +982D6054B83D +989D127BD496 +98A54AD58A43 +98A92128364C +98CD5AA2A4DB +98E8C543688E +99207A00AA4A +99243E754CB8 +9925893ABAC7 +9937553A965E +9976E6ADE0C9 +9982E3E6A4A0 +9984C1A3229E +99C487AB85EC +99E2A19C9673 +9A05EBE41D7D +9A138D1A5CB7 +9A179148B824 +9A6EC0A9ECB8 +9A720CBD7BB1 +9AB22BBDDD87 +9AC43B5A06D8 +9AD8150BE648 +9AD97423190D +9B4ADDDEB749 +9B7603341727 +9C45237377BE +9D090AE1A15E +9D59641E40A5 +9DA4528CEB8C +9DA728164176 +9DAC62A346B7 +9E0E9D983B9A +9E5271763D3D +9EE95586D024 +9EEE39E00CBB +A04671256EE2 +A091485B4B5D +A1B5577ED36E +A1EB280E3901 +A2789E1DD888 +A293A90AE72C +A309E3AEBDB9 +A3196E77B072 +A31E72DCC826 +A34DEA01690E +A36031D6ECB2 +A38044A3E18E +A421D7A04C4B +A424C686CA39 +A44590A779A5 +A47AD3895C63 +A5041E8B8E22 +A50DC0830AA5 +A52B8929D665 +A5BCBA6BE592 +A61D5137E6B3 +A6344C0418DC +A690A817B9D9 +A7E3B3459240 +A81E6D3C8E11 +A8C0BE436685 +A8DE205120A8 +A91E2BE6C308 +A9258D6B06B5 +A992B5E070C1 +AAC6E3205D48 +AB101546634E +AB6EE0761ACA +AB9BCA200547 +AC4BC5B2D3C0 +AC7A0B47B03E +AC88B26AC1D0 +ACAEB3456AD9 +ACB906631D8A +ACE07B45C0C5 +AD1992AE37CA +AD5586744A60 +AD674E4ADB79 +ADA093B06831 +AE7C3AE5334A +AE9EB8CAB2C3 +AEAE9E5CE65D +B002D1BDC29B +B0463E703098 +B063B209BB20 +B0788BE3BAA4 +B0C3B3299090 +B128298D9073 +B160677E7035 +B19D3D57176A +B1CCDB7999B9 +B231AA398B90 +B250E9590215 +B28BE0D819ED +B292C9554CBA +B2D8485C2460 +B31763D9D0DE +B328014DDD6A +B378C424C9E2 +B3D8C03C78E0 +B41D18E3B980 +B46824B972E9 +B50383A32302 +B509D631967C +B56CA847A7C3 +B56EC9A20D28 +B5B763215C82 +B6550EAC573A +B66060201705 +B6614EBEAAA2 +B6A18CBD4DA6 +B6ABB62E437E +B6C6558E58CA +B7009204D512 +B71D5B22B1C2 +B7392DD1E497 +B7709ED7CE60 +B7A26320A491 +B7A9DA22E9C6 +B7DEC863369D +B7E9A91174CB +B8178A34E2DC +B83092098A7D +B84C50E56DEC +B89BD135E935 +B8E87380D361 +B9485A9648C6 +B9ED829C22AE +BA227EE91818 +BA7BBD9683B1 +BA8224EA7A80 +BA84C974B356 +BAD293A45C8A +BB850C7E4934 +BBC1256810A4 +BC1CD369549E +BC5C76E5909C +BC66E9270049 +BC6AB08B03CC +BC74CA2C2B06 +BC7C64828C1D +BCCC3A719013 +BD06E96EB7D7 +BD196D0A74E0 +BE02790E84AC +BE1266314B9D +BE518C742B74 +BE5695316117 +BE5D8EBA120D +BE8286DA7D12 +BE9CE00EE4DD +C003962B3462 +C0067E095049 +C015A21E0146 +C03BC03AD437 +C06CE7D57A0D +C07EE1E10B56 +C0885A29251E +C198163ABECE +C1EB7337A035 +C225479C7064 +C2740E1665A8 +C27924128A00 +C2A701656B8B +C2C30D21C53E +C2CBB2ACD38D +C38D19A9C8D1 +C3B1BB7E7492 +C3BA2438A981 +C3CD74758DE2 +C4033B3BB1D7 +C404D280640E +C4467DE80B2D +C46A048C88DD +C52877867C05 +C56D005E258E +C56D052D5533 +C5BB2CCCB9C3 +C5C272694A1E +C6121BC4A29C +C65EEAE02433 +C661C4AE1DD1 +C76C94B495CA +C7BD49777A79 +C7CD131E9B60 +C7E35D6294BA +C8E173DB04CC +C95855AE08E8 +C98147E69033 +C99A004E6133 +C9E893C4090B +CA119C79A197 +CA309D2CBC41 +CA4BAA390BC4 +CA92DD257E21 +CA968EBEB9C7 +CADED0C50AC4 +CB18774EA550 +CB1999D19E10 +CB75C1BAE669 +CC2517AB2346 +CC2AC1AD29CA +CD11359C7A90 +CD14C8553CB9 +CD333295BBE2 +CD3DB8C27E5C +CDA811AD5055 +CDABDCA23986 +CDCA8BD7B002 +CE0456AB0DCE +CE58AE1C51E9 +CE76E8A600DC +CE95875316C8 +CEB105E65289 +CEB651752D4C +CEE02D97E5BD +D023DB35ED05 +D0BE546CC06B +D0CE7EB0D379 +D10329D366C8 +D15C004DBC8D +D16E6B668254 +D1CEEC977644 +D1DC0E1CC09E +D2550925679B +D28B2D42DE1A +D2926519AC09 +D313116A45B4 +D3DC10453857 +D431C8C73BDC +D4C67846791C +D5629384CE7D +D5ABE7180600 +D62A4A0E57C2 +D660CE9E3080 +D66AE9282140 +D6A91C14AC47 +D6E23B4E75C6 +D726C4979654 +D76DE12943B4 +D7A405AD9E4E +D7BD3AE48E93 +D7D49700BBCC +D7E8A5089E7A +D84C81EE910D +D8545199A949 +D86243C1380E +D88A12EB3622 +D89B5EA419C1 +D8A3690B0115 +D94646A4C65B +D982B4846A96 +DA303BADB013 +DAD9A48A8C33 +DAEB5D63920B +DB01A99DD94C +DB22BB7D6818 +DB37160CBB4B +DB7E3687E450 +DC7697E37A9B +DCC44C4E9269 +DCCE477E785E +DD68DE9CDA5A +DE1B08C6D94B +DE41BBD7E68D +DE6E04AE4475 +DE8CD4277A9E +DEA8098D6E51 +DEB2BEE8858A +DEB550958AD9 +E045E6309471 +E0E21213C611 +E0E457054B62 +E1097C69DA4A +E1EA831EA514 +E20716902884 +E2C9CB14C06C +E33B66EA2705 +E34C5B12BABA +E38A1C654E82 +E3905BA54194 +E3E3919444CA +E4450EC1010C +E49A03306224 +E5100AC4C6C3 +E5124DB665A6 +E5491B5E3DD6 +E5BE9C989A29 +E5C3A9A27D3E +E65111EB1E40 +E65792427D4C +E7004C5EA94A +E705087DECBB +E7CB93E68155 +E81512343BAD +E8428C8B0740 +E859EBC22318 +E87267A508DB +E886AE7D1BE0 +E8B008239600 +E8C4B4A4E482 +E8D53410B736 +E902964DA28D +E9203D5BD2DA +E9526CACA8B2 +E9C11D763BEC +EA3BDAA4E498 +EA61AC8B4969 +EA8E8ADC26B9 +EB5588EAE5E8 +EBA964C07075 +EC71B679D3AA +ECB4019ADD97 +ED14D0A14B0C +ED296C79266C +EDBA3C943EA8 +EDC7CEBD4000 +EDE2747DA6C3 +EE3029556CEB +EE49610E6121 +EEB704D69BCA +EED69A391464 diff --git a/client/dictionaries/mfc_keys_mrzd_sorted.dic b/client/dictionaries/mfc_keys_mrzd_sorted.dic index 025f1b995..f2ebafc10 100644 --- a/client/dictionaries/mfc_keys_mrzd_sorted.dic +++ b/client/dictionaries/mfc_keys_mrzd_sorted.dic @@ -1,57 +1,57 @@ -010203040506, -013940233313, -022FE48B3072, -123456789ABC, -123456ABCDEF, -17505586EF02, -1795902DBAF9, -1A2B3C4D5E6F, -1A982C7E459A, -200306202033, -2011092119F1, -2012053082AD, -37D4DCA92451, -40E5EA1EFC00, -435330666666, -46868F6D5677, -474249437569, -4D3A99C351DD, -533CB6C723F6, -5554AAA96321, -587EE5F9350F, -5A1B85FCE20A, -5D293AFC8D7E, -64A2EE93B12B, -64E2283FCF5E, -714C5C886E97, -833FBD3CFE51, -83BAB5ACAD62, -872B71F9D15A, -8F9B229047AC, -8FD0A4F256E9, -9AEDF9931EC1, -9B1DD7C030A1, -A0478CC39091, -A0A1A2A3A4A5, -A2B2C9D187FB, -A4EF6C3BB692, -AABBCC660429, -AABBCCDDEEFF, -ABCDEF123456, -B0699AD03D17, -B0B1B2B3B4B5, -BA28CFD15EE8, -BCFE01BCFE01, -C0C1C2C3C4C5, -CFC738403AB0, -D0D1D2D3D4D5, -D3F7D3F7D3F7, -DB5181C92CBE, -DFED39FFBB76, -E1DD284379D4, -E96246531342, -ED3A7EFBFF56, -F83466888612, -F89C86B2A961, -FFFFAE82366C, -FFFFD06F83E3, +010203040506 +013940233313 +022FE48B3072 +123456789ABC +123456ABCDEF +17505586EF02 +1795902DBAF9 +1A2B3C4D5E6F +1A982C7E459A +200306202033 +2011092119F1 +2012053082AD +37D4DCA92451 +40E5EA1EFC00 +435330666666 +46868F6D5677 +474249437569 +4D3A99C351DD +533CB6C723F6 +5554AAA96321 +587EE5F9350F +5A1B85FCE20A +5D293AFC8D7E +64A2EE93B12B +64E2283FCF5E +714C5C886E97 +833FBD3CFE51 +83BAB5ACAD62 +872B71F9D15A +8F9B229047AC +8FD0A4F256E9 +9AEDF9931EC1 +9B1DD7C030A1 +A0478CC39091 +A0A1A2A3A4A5 +A2B2C9D187FB +A4EF6C3BB692 +AABBCC660429 +AABBCCDDEEFF +ABCDEF123456 +B0699AD03D17 +B0B1B2B3B4B5 +BA28CFD15EE8 +BCFE01BCFE01 +C0C1C2C3C4C5 +CFC738403AB0 +D0D1D2D3D4D5 +D3F7D3F7D3F7 +DB5181C92CBE +DFED39FFBB76 +E1DD284379D4 +E96246531342 +ED3A7EFBFF56 +F83466888612 +F89C86B2A961 +FFFFAE82366C +FFFFD06F83E3 diff --git a/client/dictionaries/mfulc_default_keys.dic b/client/dictionaries/mfulc_default_keys.dic index 3c0c01acd..51b4b9365 100644 --- a/client/dictionaries/mfulc_default_keys.dic +++ b/client/dictionaries/mfulc_default_keys.dic @@ -2,4 +2,5 @@ # Mifare Ultralight Default Keys # -- iceman fork version -- # -- contribute to this list, sharing is caring -- -425245414B4D454946594F5543414E21 -- Sample Key (BREAKMEIFYOUCAN!) +# +425245414B4D454946594F5543414E21 # Sample Key (BREAKMEIFYOUCAN!) diff --git a/client/dictionaries/t55xx_default_pwds.dic b/client/dictionaries/t55xx_default_pwds.dic index aa2b23719..511be26d1 100644 --- a/client/dictionaries/t55xx_default_pwds.dic +++ b/client/dictionaries/t55xx_default_pwds.dic @@ -1,123 +1,123 @@ # known cloners # ref. http://www.proxmark.org/forum/viewtopic.php?id=2022 -51243648, -000D8787, -19920427, -65857569, //chinese "handheld RFID writer" blue cloner from circa 2013 (also sold by xfpga.com) +51243648 +000D8787 +19920427 +65857569 //chinese "handheld RFID writer" blue cloner from circa 2013 (also sold by xfpga.com) # ref. http://kazus.ru/forums/showpost.php?p=1045937&postcount=77 -05D73B9F, +05D73B9F # ref. http://www.proxmark.org/forum/viewtopic.php?= -89A69E60, +89A69E60 # ref lock -314159E0, +314159E0 # ref. http://www.proxmark.org/forum/viewtopic.php?pid=28115#p28115 -AA55BBBB, +AA55BBBB # ref. http://www.proxmark.org/forum/viewtopic.php?pid=33376#p33376 -A5B4C3D2, -# ref. http://www.proxmark.org/forum/viewtopic.php?pid=30379#p30379 -1C0B5848, -# http://www.proxmark.org/forum/viewtopic.php?pid=35075#p35075 -00434343, -44B44CAE, -88661858, +A5B4C3D2 +# ref. http://www.proxmark.org/forum/viewtopic.php?pid=30379#p30379 +1C0B5848 +# ref. http://www.proxmark.org/forum/viewtopic.php?pid=35075#p35075 +00434343 +44B44CAE +88661858 # paxton bullit? -575F4F4B, +575F4F4B # -50520901, +50520901 # Default pwd, simple: -00000000, -11111111, -22222222, -33333333, -44444444, -55555555, -66666666, -77777777, -88888888, -99999999, -AAAAAAAA, -BBBBBBBB, -CCCCCCCC, -DDDDDDDD, -EEEEEEEE, -FFFFFFFF, -a0a1a2a3, -b0b1b2b3, -aabbccdd, -bbccddee, -ccddeeff, -50415353, -00000001, -00000002, -0000000a, -0000000b, -01020304, -02030405, -03040506, -04050607, -05060708, -06070809, -0708090A, -08090A0B, -090A0B0C, -0A0B0C0D, -0B0C0D0E, -0C0D0E0F, -01234567, -12345678, -10000000, -20000000, -30000000, -40000000, -50000000, -60000000, -70000000, -80000000, -90000000, -A0000000, -B0000000, -C0000000, -D0000000, -E0000000, -F0000000, -10101010, -01010101, -11223344, -22334455, -33445566, -44556677, -55667788, -66778899, -778899AA, -8899AABB, -99AABBCC, -AABBCCDD, -BBCCDDEE, -CCDDEEFF, -0CB7E7FC, //rfidler? -FABADA11, //china? +00000000 +11111111 +22222222 +33333333 +44444444 +55555555 +66666666 +77777777 +88888888 +99999999 +AAAAAAAA +BBBBBBBB +CCCCCCCC +DDDDDDDD +EEEEEEEE +FFFFFFFF +a0a1a2a3 +b0b1b2b3 +aabbccdd +bbccddee +ccddeeff +50415353 +00000001 +00000002 +0000000a +0000000b +01020304 +02030405 +03040506 +04050607 +05060708 +06070809 +0708090A +08090A0B +090A0B0C +0A0B0C0D +0B0C0D0E +0C0D0E0F +01234567 +12345678 +10000000 +20000000 +30000000 +40000000 +50000000 +60000000 +70000000 +80000000 +90000000 +A0000000 +B0000000 +C0000000 +D0000000 +E0000000 +F0000000 +10101010 +01010101 +11223344 +22334455 +33445566 +44556677 +55667788 +66778899 +778899AA +8899AABB +99AABBCC +AABBCCDD +BBCCDDEE +CCDDEEFF +0CB7E7FC # rfidler? +FABADA11 # china? # 20 most common len==8 -87654321, -12341234, -69696969, -12121212, -12344321, -1234ABCD, -11112222, -13131313, -10041004, +87654321 +12341234 +69696969 +12121212 +12344321 +1234ABCD +11112222 +13131313 +10041004 # -31415926, //pii -abcd1234, -20002000, -19721972, -aa55aa55, // amiboo -55aa55aa, // rev amiboo -4f271149, // seeds ul-ev1 -07d7bb0b, // seeds ul-ev1 -9636ef8f, // seeds ul-ev1 -b5f44686, // seeds ul-ev1 -9E3779B9, // TEA -C6EF3720, // TEA -7854794A, // xbox tea constant :) -F1EA5EED, // burtle +31415926 # pii +abcd1234 +20002000 +19721972 +aa55aa55 # amiboo +55aa55aa # rev amiboo +4f271149 # seeds ul-ev1 +07d7bb0b # seeds ul-ev1 +9636ef8f # seeds ul-ev1 +b5f44686 # seeds ul-ev1 +9E3779B9 # TEA +C6EF3720 # TEA +7854794A # xbox tea constant :) +F1EA5EED # burtle From e8efeacc57340f5ee72479931fb6148b9693c8f9 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 22 Aug 2019 23:06:18 +0200 Subject: [PATCH 0415/1854] remove ON_DEVICE from fileutils --- client/fileutils.c | 7 ------- client/fileutils.h | 18 ------------------ 2 files changed, 25 deletions(-) diff --git a/client/fileutils.c b/client/fileutils.c index b89925334..1bbcd890c 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -42,9 +42,6 @@ #include "commonutil.h" #include "util.h" - -#ifndef ON_DEVICE - #define PATH_MAX_LENGTH 100 /** @@ -612,7 +609,3 @@ int convertOldMfuDump(uint8_t **dump, size_t *dumplen) { return PM3_SUCCESS; } - -#else //if we're on ARM - -#endif diff --git a/client/fileutils.h b/client/fileutils.h index 79b053fc2..f5e51f470 100644 --- a/client/fileutils.h +++ b/client/fileutils.h @@ -38,8 +38,6 @@ #ifndef FILEUTILS_H #define FILEUTILS_H -#ifndef ON_DEVICE - #include #include #include @@ -162,20 +160,4 @@ int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, u */ int convertOldMfuDump(uint8_t **dump, size_t *dumplen); -#define PrintAndLogEx(level, format, args...) PrintAndLogEx(level, format , ## args) -#else - -/** -* Utility function to print to console. This is used consistently within the library instead -* of printf, but it actually only calls printf. The reason to have this method is to -*make it simple to plug this library into proxmark, which has this function already to -* write also to a logfile. When doing so, just point this function to use PrintAndLog -* @param fmt -*/ -#define PrintAndLogEx(level, format, args...) { } - - - -#endif //ON_DEVICE - #endif // FILEUTILS_H From 3ebc00854ba9cb6a6abbf62e38239c6cd56ae445 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 22 Aug 2019 23:55:37 +0200 Subject: [PATCH 0416/1854] Add searchAndList & searchFile in fileutils --- client/cmdscript.c | 135 +++------------------------------------------ client/fileutils.c | 96 ++++++++++++++++++++++++++++++++ client/fileutils.h | 3 + 3 files changed, 107 insertions(+), 127 deletions(-) diff --git a/client/cmdscript.c b/client/cmdscript.c index eb7979a00..8a748b8ab 100644 --- a/client/cmdscript.c +++ b/client/cmdscript.c @@ -8,10 +8,6 @@ // Some lua scripting glue to proxmark core. //----------------------------------------------------------------------------- -// this define is needed for scandir/alphasort to work -#define _GNU_SOURCE - -#include #include #include @@ -28,56 +24,8 @@ #include "ui.h" #include "fileutils.h" -#ifdef _WIN32 -#include "scandir.h" -#endif - static int CmdHelp(const char *Cmd); -static int str_ends_with(const char *str, const char *suffix) { - - if (str == NULL || suffix == NULL) - return 0; - - size_t str_len = strlen(str); - size_t suffix_len = strlen(suffix); - - if (suffix_len > str_len) - return 0; - - return 0 == strncmp(str + str_len - suffix_len, suffix, suffix_len); -} - -/** - * Utility to check the ending of a string (used to check file suffix) - */ -static bool endsWith(const char *base, const char *str) { - int blen = strlen(base); - int slen = strlen(str); - return (blen >= slen) && (0 == strcmp(base + blen - slen, str)); -} - -static int scriptlist(const char *path, bool last) { - struct dirent **namelist; - int n; - - n = scandir(path, &namelist, NULL, alphasort); - if (n == -1) { - PrintAndLogEx(NORMAL, "%s── %s => NOT FOUND", last ? "└" : "├", path); - return PM3_EFILE; - } - - PrintAndLogEx(NORMAL, "%s── %s", last ? "└" : "├", path); - for (uint16_t i = 0; i < n; i++) { - if (str_ends_with(namelist[i]->d_name, ".lua")) { - PrintAndLogEx(NORMAL, "%s   %s── %-21s", last ? " ":"│", i == n-1 ? "└" : "├", namelist[i]->d_name); - } - free(namelist[i]); - } - free(namelist); - return PM3_SUCCESS; -} - /** * Generate a sorted list of available commands, what it does is * generate a file listing of the script-directory for files @@ -85,28 +33,7 @@ static int scriptlist(const char *path, bool last) { */ static int CmdScriptList(const char *Cmd) { (void)Cmd; // Cmd is not used so far - - if (get_my_executable_directory() != NULL) { - char script_directory_path[strlen(get_my_executable_directory()) + strlen(LUA_SCRIPTS_DIRECTORY) + 1]; - strcpy(script_directory_path, get_my_executable_directory()); - strcat(script_directory_path, LUA_SCRIPTS_DIRECTORY); - scriptlist(script_directory_path, false); - } - char *userpath = getenv("HOME"); - if (userpath != NULL) { - char script_directory_path[strlen(userpath) + strlen(PM3_USER_DIRECTORY) + strlen(LUA_SCRIPTS_DIRECTORY) + 1]; - strcpy(script_directory_path, userpath); - strcat(script_directory_path, PM3_USER_DIRECTORY); - strcat(script_directory_path, LUA_SCRIPTS_DIRECTORY); - scriptlist(script_directory_path, false); - } - { - char script_directory_path[strlen(PM3_SYSTEM_DIRECTORY) + strlen(LUA_SCRIPTS_DIRECTORY) + 1]; - strcpy(script_directory_path, PM3_SYSTEM_DIRECTORY); - strcat(script_directory_path, LUA_SCRIPTS_DIRECTORY); - scriptlist(script_directory_path, true); - } - return 0; + return searchAndList(LUA_SCRIPTS_DIRECTORY, ".lua"); } /** @@ -139,61 +66,15 @@ static int CmdScriptRun(const char *Cmd) { int arg_len = 0; sscanf(Cmd, "%127s%n %255[^\n\r]%n", script_name, &name_len, arguments, &arg_len); - const char *suffix = ""; - if (!endsWith(script_name, ".lua")) { - suffix = ".lua"; - } - - bool found = false; - int error; - const char* exec_path = get_my_executable_directory(); - - if (exec_path != NULL) { - char script_path[strlen(exec_path) + strlen(LUA_SCRIPTS_DIRECTORY) + strlen(script_name) + strlen(suffix) + 1]; - strcpy(script_path, exec_path); - strcat(script_path, LUA_SCRIPTS_DIRECTORY); - strcat(script_path, script_name); - strcat(script_path, suffix); - if (fileExists(script_path)) - { - PrintAndLogEx(SUCCESS, "Executing: %s, args '%s'\n", script_path, arguments); - found = true; - error = luaL_loadfile(lua_state, script_path); - } - } - char *userpath = getenv("HOME"); - if ((!found) && (userpath != NULL)) { - char script_path[strlen(userpath) + strlen(PM3_USER_DIRECTORY) + strlen(LUA_SCRIPTS_DIRECTORY) + strlen(script_name) + strlen(suffix) + 1]; - strcpy(script_path, userpath); - strcat(script_path, PM3_USER_DIRECTORY); - strcat(script_path, LUA_SCRIPTS_DIRECTORY); - strcat(script_path, script_name); - strcat(script_path, suffix); - if (fileExists(script_path)) - { - PrintAndLogEx(SUCCESS, "Executing: %s, args '%s'\n", script_path, arguments); - found = true; - error = luaL_loadfile(lua_state, script_path); - } - } - if (!found) { - char script_path[strlen(PM3_SYSTEM_DIRECTORY) + strlen(LUA_SCRIPTS_DIRECTORY) + strlen(script_name) + strlen(suffix) + 1]; - strcpy(script_path, PM3_SYSTEM_DIRECTORY); - strcat(script_path, LUA_SCRIPTS_DIRECTORY); - strcat(script_path, script_name); - strcat(script_path, suffix); - if (fileExists(script_path)) - { - PrintAndLogEx(SUCCESS, "Executing: %s, args '%s'\n", script_path, arguments); - found = true; - error = luaL_loadfile(lua_state, script_path); - } - } - if (!found) { - PrintAndLogEx(FAILED, "Error - can't find script %s%s", script_name, suffix); + char *script_path = searchFile(LUA_SCRIPTS_DIRECTORY, ".lua", script_name); + if (script_path == NULL) { + PrintAndLogEx(FAILED, "Error - can't find script %s", script_name); return PM3_EFILE; } - + int error; + PrintAndLogEx(SUCCESS, "Executing: %s, args '%s'\n", script_path, arguments); + error = luaL_loadfile(lua_state, script_path); + free(script_path); if (!error) { lua_pushstring(lua_state, arguments); lua_setglobal(lua_state, "args"); diff --git a/client/fileutils.c b/client/fileutils.c index 1bbcd890c..403f7fc27 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -34,13 +34,21 @@ * * ****************************************************************************/ + +// this define is needed for scandir/alphasort to work +#define _GNU_SOURCE #include "fileutils.h" +#include #include #include "pm3_cmd.h" #include "commonutil.h" +#include "proxmark3.h" #include "util.h" +#ifdef _WIN32 +#include "scandir.h" +#endif #define PATH_MAX_LENGTH 100 @@ -609,3 +617,91 @@ int convertOldMfuDump(uint8_t **dump, size_t *dumplen) { return PM3_SUCCESS; } +static int filelist(const char *path, const char *ext, bool last) { + struct dirent **namelist; + int n; + + n = scandir(path, &namelist, NULL, alphasort); + if (n == -1) { + PrintAndLogEx(NORMAL, "%s── %s => NOT FOUND", last ? "└" : "├", path); + return PM3_EFILE; + } + + PrintAndLogEx(NORMAL, "%s── %s", last ? "└" : "├", path); + for (uint16_t i = 0; i < n; i++) { + if (((ext == NULL) && (namelist[i]->d_name[0] != '.')) || (str_endswith(namelist[i]->d_name, ext))) { + PrintAndLogEx(NORMAL, "%s   %s── %-21s", last ? " ":"│", i == n-1 ? "└" : "├", namelist[i]->d_name); + } + free(namelist[i]); + } + free(namelist); + return PM3_SUCCESS; +} + +int searchAndList(const char *pm3dir, const char *ext) { + if (get_my_executable_directory() != NULL) { + char script_directory_path[strlen(get_my_executable_directory()) + strlen(pm3dir) + 1]; + strcpy(script_directory_path, get_my_executable_directory()); + strcat(script_directory_path, pm3dir); + filelist(script_directory_path, ext, false); + } + char *userpath = getenv("HOME"); + if (userpath != NULL) { + char script_directory_path[strlen(userpath) + strlen(PM3_USER_DIRECTORY) + strlen(pm3dir) + 1]; + strcpy(script_directory_path, userpath); + strcat(script_directory_path, PM3_USER_DIRECTORY); + strcat(script_directory_path, pm3dir); + filelist(script_directory_path, ext, false); + } + { + char script_directory_path[strlen(PM3_SYSTEM_DIRECTORY) + strlen(pm3dir) + 1]; + strcpy(script_directory_path, PM3_SYSTEM_DIRECTORY); + strcat(script_directory_path, pm3dir); + filelist(script_directory_path, ext, true); + } + return PM3_SUCCESS; +} + +char *searchFile(const char *pm3dir, const char *ext, const char *filename) { + const char *suffix = ""; + if (!str_endswith(filename, ext)) { + suffix = ext; + } + const char *exec_path = get_my_executable_directory(); + if (exec_path != NULL) { + char *path = malloc(strlen(exec_path) + strlen(pm3dir) + strlen(filename) + strlen(suffix) + 1); + strcpy(path, exec_path); + strcat(path, pm3dir); + strcat(path, filename); + strcat(path, suffix); + if (fileExists(path)) + return path; + else + free(path); + } + char *user_path = getenv("HOME"); + if (user_path != NULL) { + char *path = malloc(strlen(user_path) + strlen(PM3_USER_DIRECTORY) + strlen(pm3dir) + strlen(filename) + strlen(suffix) + 1); + strcpy(path, user_path); + strcat(path, PM3_USER_DIRECTORY); + strcat(path, pm3dir); + strcat(path, filename); + strcat(path, suffix); + if (fileExists(path)) + return path; + else + free(path); + } + { + char *path = malloc(strlen(PM3_SYSTEM_DIRECTORY) + strlen(pm3dir) + strlen(filename) + strlen(suffix) + 1); + strcpy(path, PM3_SYSTEM_DIRECTORY); + strcat(path, pm3dir); + strcat(path, filename); + strcat(path, suffix); + if (fileExists(path)) + return path; + else + free(path); + } + return NULL; +} diff --git a/client/fileutils.h b/client/fileutils.h index f5e51f470..99c3c4d1d 100644 --- a/client/fileutils.h +++ b/client/fileutils.h @@ -160,4 +160,7 @@ int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, u */ int convertOldMfuDump(uint8_t **dump, size_t *dumplen); +int searchAndList(const char *pm3dir, const char *ext); +char *searchFile(const char *pm3dir, const char *ext, const char *filename); + #endif // FILEUTILS_H From 440c05cdfa46145229cabdd479a0647c1451140e Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 23 Aug 2019 00:08:19 +0200 Subject: [PATCH 0417/1854] searchFile accepts also explicit absolute or relative path --- client/fileutils.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/client/fileutils.c b/client/fileutils.c index 403f7fc27..7500ea8dd 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -667,6 +667,22 @@ char *searchFile(const char *pm3dir, const char *ext, const char *filename) { if (!str_endswith(filename, ext)) { suffix = ext; } + + // explicit absolute (/) or relative path (./) => try only to match it directly + if (((strlen(filename) > 1) && (filename[0] == '/')) || + ((strlen(filename) > 2) && (filename[0] == '.') && (filename[1] == '/'))) + { + char *path = malloc(strlen(filename) + strlen(suffix) + 1); + strcpy(path, filename); + strcat(path, suffix); + if (fileExists(path)) + return path; + else + free(path); + return NULL; + } + // else + // try pm3 dirs in current workdir (dev mode) const char *exec_path = get_my_executable_directory(); if (exec_path != NULL) { char *path = malloc(strlen(exec_path) + strlen(pm3dir) + strlen(filename) + strlen(suffix) + 1); @@ -679,6 +695,7 @@ char *searchFile(const char *pm3dir, const char *ext, const char *filename) { else free(path); } + // try pm3 dirs in user .proxmark3 (user mode) char *user_path = getenv("HOME"); if (user_path != NULL) { char *path = malloc(strlen(user_path) + strlen(PM3_USER_DIRECTORY) + strlen(pm3dir) + strlen(filename) + strlen(suffix) + 1); @@ -692,6 +709,7 @@ char *searchFile(const char *pm3dir, const char *ext, const char *filename) { else free(path); } + // try pm3 dirs in pm3 installation dir (install mode) { char *path = malloc(strlen(PM3_SYSTEM_DIRECTORY) + strlen(pm3dir) + strlen(filename) + strlen(suffix) + 1); strcpy(path, PM3_SYSTEM_DIRECTORY); From 4b2b103e80ffec00722262427dd2b79733a5ad24 Mon Sep 17 00:00:00 2001 From: Iceman Date: Fri, 23 Aug 2019 15:23:55 +0200 Subject: [PATCH 0418/1854] Update mfc_default_keys.dic data from forum, --- client/dictionaries/mfc_default_keys.dic | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index 4b1430c2f..ff63a0a83 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -964,3 +964,21 @@ DFE73BE48AC6 # B069D0D03D17 000131B93F28 +# +# From the DFW Area, TX, USA +# +a506370e7c0f +26396f2042e7 +70758fdd31e0 +9f9d8eeddcce +06ff5f03aa1a +4098653289d3 +904735f00f9e +b4c36c79da8d +68f9a1f0b424 +5a85536395b3 +7dd399d4e897 +ef4c5a7ac6fc +b47058139187 +8268046cd154 +67cc03b7d577 From 87cbf3aa70cc974810467435c2a7ef6988c960df Mon Sep 17 00:00:00 2001 From: Matthias Konrath Date: Fri, 23 Aug 2019 17:17:17 +0200 Subject: [PATCH 0419/1854] Improved the reliability, speed and redability. Ready for a pull mr. iceman ;) --- client/cmdhfmf.c | 479 ++++++++++++++++++--------------------------- client/fileutils.c | 30 +++ client/fileutils.h | 11 ++ 3 files changed, 233 insertions(+), 287 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index c68daa9f3..e968548b6 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -169,15 +169,16 @@ static int usage_hf14_hardnested(void) { static int usage_hf14_hardautopwn(void) { PrintAndLogEx(NORMAL, "Usage:"); PrintAndLogEx(NORMAL, " hf mf hardautopwn [k] "); - PrintAndLogEx(NORMAL, " * [d] [f] [s] [t] [i]"); + PrintAndLogEx(NORMAL, " * [d] [f] [s] [i] [l]"); PrintAndLogEx(NORMAL, " (card memory - 0 - MINI(320 bytes), 1 - 1K, 2 - 2K, 4 - 4K, - 1K)"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h this help"); PrintAndLogEx(NORMAL, " k if a known key for a block is supplied"); PrintAndLogEx(NORMAL, " d write keys to binary file"); - PrintAndLogEx(NORMAL, " f keys to test (speed up the cracking, if some keys are known)"); + PrintAndLogEx(NORMAL, " f .dic dictionary file for key discovery (the file has to end in .dic)"); PrintAndLogEx(NORMAL, " s slower acquisition (required by some non standard cards)"); + PrintAndLogEx(NORMAL, " l legacy mode (use the slow mfchk for the key enumeration)"); PrintAndLogEx(NORMAL, " i set type of SIMD instructions. Without this flag programs autodetect it."); PrintAndLogEx(NORMAL, " i 5 = AVX512"); PrintAndLogEx(NORMAL, " i 2 = AVX2"); @@ -187,9 +188,12 @@ static int usage_hf14_hardautopwn(void) { PrintAndLogEx(NORMAL, " i n = none (use CPU regular instruction set)"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); + PrintAndLogEx(NORMAL, " hf mf hardautopwn d"); + PrintAndLogEx(NORMAL, " hf mf hardautopwn * 1 d f default_keys"); PrintAndLogEx(NORMAL, " hf mf hardautopwn k 0 A FFFFFFFFFFFF d"); - PrintAndLogEx(NORMAL, " hf mf hardautopwn k 0 A FFFFFFFFFFFF * 1 d f default_keys.dic"); + PrintAndLogEx(NORMAL, " hf mf hardautopwn k 0 A FFFFFFFFFFFF * 1 d f default_keys"); PrintAndLogEx(NORMAL, " hf mf hardautopwn k 0 A FFFFFFFFFFFF * 4 s i 5"); + PrintAndLogEx(NORMAL, ""); return 0; } @@ -1559,57 +1563,44 @@ static int CmdHF14AMfNestedHard(const char *Cmd) { static int CmdHF14AMfHardAuto(const char *Cmd) { - /* - Author: Matthias Konrath - Company: Trustworks GmbH - Email: m.konrath@trustworks.at - */ - uint8_t blockNo = 0; uint8_t keyType = 0; - uint8_t *keyBlock, *p; + uint8_t *keyBlock; uint8_t sectorsCnt = MIFARE_1K_MAXSECTOR; sector_t *e_sector; - uint8_t arr[80]; - uint8_t key[6] = {0, 0, 0, 0, 0, 0}; - uint8_t tmpKey[6]; + uint8_t key[6] = {0}; + uint8_t tmpKey[6] = {0}; uint64_t key64 = 0; + uint16_t keycnt = 0; + size_t datalen = 0; + uint32_t chunksize; - uint64_t t1; + uint64_t t1; // For the timier uint8_t foundKeysDictionary = 0; - uint8_t foundKeysReuse = 0; + uint8_t foundKeysReused = 0; uint8_t foundKeysHardnested = 0; - keyBlock = calloc(ARRAYLEN(g_mifare_default_keys), 6); - if (keyBlock == NULL) return 1; - - for (int cnt = 0; cnt < ARRAYLEN(g_mifare_default_keys); cnt++) - num_to_bytes(g_mifare_default_keys[cnt], 6, keyBlock + cnt * 6); - - FILE* f; - char buf[13] = {0}; - char filename[FILE_PATH_SIZE] = {0}, *fptr; + char filename[FILE_PATH_SIZE] = {0}; uint8_t cmdp = 0; char ctmp; uint64_t foundkey = 0; int16_t isOK = 0; - int i, i2, keycnt = 0;; - int current_sector_i, current_key_type_i, default_keys_i, found_keys_i; - uint32_t keyitems = ARRAYLEN(g_mifare_default_keys); + int i, i2, i3; // Loop counter + int current_sector_i = 0, current_key_type_i = 0; bool slow = false; bool nonce_file_read = false; bool nonce_file_write = false; bool createDumpFile = false; bool know_target_key = false; - int tests = 0; + bool legacy_mfchk = false; + bool firstChunk = 0, lastChunk = 0; ctmp = tolower(param_getchar(Cmd, 0)); if (strlen(Cmd) < 1 || ctmp == 'h') return usage_hf14_hardautopwn(); - while ((ctmp = param_getchar(Cmd, cmdp))) { switch (tolower(ctmp)) { case 'h': @@ -1623,24 +1614,12 @@ static int CmdHF14AMfHardAuto(const char *Cmd) { case 'd': createDumpFile = true; break; + case 'l': + legacy_mfchk = true; + break; case '*': - // sectors - switch (param_getchar(Cmd, cmdp + 1)) { - case '0': - sectorsCnt = MIFARE_MINI_MAXSECTOR; - break; - case '1': - sectorsCnt = MIFARE_1K_MAXSECTOR; - break; - case '2': - sectorsCnt = MIFARE_2K_MAXSECTOR; - break; - case '4': - sectorsCnt = MIFARE_4K_MAXSECTOR; - break; - default: - sectorsCnt = MIFARE_1K_MAXSECTOR; - } + // Get the number of sectors + sectorsCnt = NumOfSectors(param_getchar(Cmd, cmdp + 1)); cmdp ++; break; case 'k': @@ -1707,31 +1686,22 @@ static int CmdHF14AMfHardAuto(const char *Cmd) { // Print parameters PrintAndLogEx(NORMAL, "Used Parameters:"); - PrintAndLogEx(NORMAL, "[+] Dumping the found keys: %s", createDumpFile ? "True" : "False"); - PrintAndLogEx(NORMAL, "[+] Card sectors: %d", sectorsCnt); - PrintAndLogEx(NORMAL, "[+] Key supplied: %s", know_target_key ? "True" : "False"); - PrintAndLogEx(NORMAL, "[+] Known sector: %d", blockNo); - PrintAndLogEx(NORMAL, "[+] Keytype: %c", keyType ? 'B' : 'A'); - PrintAndLogEx(NORMAL, "[+] Kown key: 0x%02x%02x%02x%02x%02x%02x", key[0], key[1], key[2], key[3], key[4], key[5]); - PrintAndLogEx(NORMAL, "[+] Dictionary: %s", filename); - - e_sector = calloc(sectorsCnt, sizeof(sector_t)); - - if (know_target_key) { - // check if we can authenticate to sector - if (mfCheckKeys(blockNo, keyType, true, 1, key, &key64) != PM3_SUCCESS) { - PrintAndLogEx(WARNING, "Key is wrong. Can't authenticate to sector:%3d key type:%c", blockNo, keyType ? 'B' : 'A'); - free(e_sector); - return 3; - } - } else { + PrintAndLogEx(SUCCESS, "Dumping the found keys: %s", createDumpFile ? "True" : "False"); + PrintAndLogEx(SUCCESS, "Card sectors: %d", sectorsCnt); + PrintAndLogEx(SUCCESS, "Key supplied: %s", know_target_key ? "True" : "False"); + PrintAndLogEx(SUCCESS, "Known sector: %d", blockNo); + PrintAndLogEx(SUCCESS, "Keytype: %c", keyType ? 'B' : 'A'); + PrintAndLogEx(SUCCESS, "Kown key: 0x%02x%02x%02x%02x%02x%02x", key[0], key[1], key[2], key[3], key[4], key[5]); + PrintAndLogEx(SUCCESS, "Dictionary: %s", filename); + PrintAndLogEx(SUCCESS, "Legacy mode (mfchk): %s", legacy_mfchk ? "True" : "False"); + PrintAndLogEx(WARNING, "Starting attack!"); + if (know_target_key == false) PrintAndLogEx(WARNING, "No known key was supplied, if no usable key is found in the dictionary, then this attack will fail!"); - } - - // Clear the datastructures - for (i=0; i<80; i++) { - arr[i] = 0; - } + + // Create the key storage stucture + e_sector = calloc(sectorsCnt, sizeof(sector_t)); + if (e_sector == NULL) return PM3_EMALLOC; + // Clear the key storage datastructure for (i=0; i (PM3_CMD_DATA_SIZE / 6) ? (PM3_CMD_DATA_SIZE / 6) : keycnt; + firstChunk = true; lastChunk = false; + for (uint8_t strategy = 1; strategy < 3; strategy++) { + PrintAndLogEx(SUCCESS, "Running strategy %u", strategy); + // main keychunk loop + for (i = 0; i < keycnt; i += chunksize) { + + if (kbd_enter_pressed()) { + PrintAndLogEx(WARNING, "\naborted via keyboard!\n"); + i = keycnt; strategy = 3; break; // Exit the loop + } + uint32_t size = ((keycnt - i) > chunksize) ? chunksize : keycnt - i; + // last chunk? + if (size == keycnt - i) + lastChunk = true; + int res = mfCheckKeys_fast(sectorsCnt, firstChunk, lastChunk, strategy, size, keyBlock + (i * 6), e_sector, false); + if (firstChunk) + firstChunk = false; + // all keys, aborted + if (res == 0 || res == 2) { + i = keycnt; strategy = 3; break; // Exit the loop + } + } // end chunks of keys + firstChunk = true; + lastChunk = false; + } // end strategy } - // Set the user defined / bruteforced key + // Check if at least one key was recovered + for (i=0; i 0xffffffffffff has been inserted for unknown keys.", fptr); + PrintAndLogEx(SUCCESS, "\nDumping the found keys:"); + createKeyDump(sectorsCnt, e_sector, GenerateFilename("hf-mf-", "-key.bin")); } - + // Generate and show statistics t1 = msclock() - t1; - PrintAndLogEx(SUCCESS, "Key statistics: Dictionary: " _GREEN_("%d") ", Reuse: " _YELLOW_("%d") ", Bruteforce: " _MAGENTA_("%d") ", Total: " _YELLOW_("%d"), foundKeysDictionary, foundKeysReuse, foundKeysHardnested, sectorsCnt*2); + PrintAndLogEx(SUCCESS, "Keys statistics (total: %d):" + "\n\t(*) Broken with hardnested attack: " _MAGENTA_("%d") + "\n\t(*) Reused keys: " _YELLOW_("%d") + "\n\t(*) Discovered with the dictionary: " _YELLOW_("%d") + , sectorsCnt*2, foundKeysHardnested, foundKeysReused, foundKeysDictionary); PrintAndLogEx(SUCCESS, "Required time for the hardautopwn attack: " _YELLOW_("%.0f") " seconds\n", (float)t1 / 1000.0); free(e_sector); + free(keyBlock); return 0; } @@ -2007,7 +1936,6 @@ static int CmdHF14AMfChk_fast(const char *Cmd) { char filename[FILE_PATH_SIZE] = {0}; char buf[13]; char *fptr; - uint8_t tempkey[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; uint8_t *keyBlock, *p; uint8_t sectorsCnt = 1; int i, keycnt = 0; @@ -2218,30 +2146,7 @@ out: if (createDumpFile) { fptr = GenerateFilename("hf-mf-", "-key.bin"); - if (fptr == NULL) - return 1; - - FILE *fkeys = fopen(fptr, "wb"); - if (fkeys == NULL) { - PrintAndLogEx(WARNING, "Could not create file " _YELLOW_("%s"), fptr); - free(keyBlock); - free(e_sector); - return 1; - } - PrintAndLogEx(SUCCESS, "Printing keys to binary file " _YELLOW_("%s")"...", fptr); - - for (i = 0; i < sectorsCnt; i++) { - num_to_bytes(e_sector[i].Key[0], 6, tempkey); - fwrite(tempkey, 1, 6, fkeys); - } - - for (i = 0; i < sectorsCnt; i++) { - num_to_bytes(e_sector[i].Key[1], 6, tempkey); - fwrite(tempkey, 1, 6, fkeys); - } - - fclose(fkeys); - PrintAndLogEx(SUCCESS, "Found keys have been dumped to " _YELLOW_("%s")" --> 0xffffffffffff has been inserted for unknown keys.", fptr); + createKeyDump(sectorsCnt, e_sector, fptr); } } diff --git a/client/fileutils.c b/client/fileutils.c index b89925334..124a51edc 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -293,6 +293,36 @@ out: return retval; } +int createKeyDump(uint8_t sectorsCnt, sector_t *e_sector, char* fptr) { + uint8_t tmpKey[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + int i; + + if (fptr == NULL) { + return 1; + } + + FILE *fkeys = fopen(fptr, "wb"); + if (fkeys == NULL) { + PrintAndLogEx(WARNING, "Could not create file " _YELLOW_("%s"), fptr); + return 1; + } + PrintAndLogEx(SUCCESS, "Printing keys to binary file " _YELLOW_("%s")"...", fptr); + + for (i = 0; i < sectorsCnt; i++) { + num_to_bytes(e_sector[i].Key[0], 6, tmpKey); + fwrite(tmpKey, 1, 6, fkeys); + } + + for (i = 0; i < sectorsCnt; i++) { + num_to_bytes(e_sector[i].Key[1], 6, tmpKey); + fwrite(tmpKey, 1, 6, fkeys); + } + + fclose(fkeys); + PrintAndLogEx(SUCCESS, "Found keys have been dumped to " _YELLOW_("%s")" --> 0xffffffffffff has been inserted for unknown keys.", fptr); + return 0; +} + int loadFile(const char *preferredName, const char *suffix, void *data, size_t maxdatalen, size_t *datalen) { if (data == NULL) return 1; diff --git a/client/fileutils.h b/client/fileutils.h index 74d54000b..61b7b0468 100644 --- a/client/fileutils.h +++ b/client/fileutils.h @@ -49,6 +49,7 @@ #include "../ui.h" #include "../emv/emvjson.h" #include "mifare/mifare4.h" +#include "mifare/mifarehost.h" #include "cmdhfmfu.h" typedef enum { @@ -103,6 +104,16 @@ int saveFileEML(const char *preferredName, uint8_t *data, size_t datalen, size_t */ int saveFileJSON(const char *preferredName, JSONFileType ftype, uint8_t *data, size_t datalen); +/** + * @brief Utility function to save a keydump. + * + * @param sectorsCnt the used sectors + * @param e_sector the keys in question + * @param fptr string pointer to the filename + * @return 0 for ok, 1 for failz + */ +int createKeyDump(uint8_t sectorsCnt, sector_t *e_sector, char* fptr); + /** STUB * @brief Utility function to load data from a binary file. This method takes a preferred name. * E.g. dumpdata-15.bin From c709ee7c1067978d5286861c33108befdffeefae Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 23 Aug 2019 20:55:50 +0200 Subject: [PATCH 0420/1854] rework PREFIX for future make install --- client/fileutils.c | 8 ++++---- client/scripting.c | 10 +++++----- .../Mac-OS-X-Homebrew-Installation-Instructions.md | 7 +------ include/common.h | 10 +++++++--- 4 files changed, 17 insertions(+), 18 deletions(-) diff --git a/client/fileutils.c b/client/fileutils.c index 7500ea8dd..6556a9a1b 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -654,8 +654,8 @@ int searchAndList(const char *pm3dir, const char *ext) { filelist(script_directory_path, ext, false); } { - char script_directory_path[strlen(PM3_SYSTEM_DIRECTORY) + strlen(pm3dir) + 1]; - strcpy(script_directory_path, PM3_SYSTEM_DIRECTORY); + char script_directory_path[strlen(PM3_SHARE_PATH) + strlen(pm3dir) + 1]; + strcpy(script_directory_path, PM3_SHARE_PATH); strcat(script_directory_path, pm3dir); filelist(script_directory_path, ext, true); } @@ -711,8 +711,8 @@ char *searchFile(const char *pm3dir, const char *ext, const char *filename) { } // try pm3 dirs in pm3 installation dir (install mode) { - char *path = malloc(strlen(PM3_SYSTEM_DIRECTORY) + strlen(pm3dir) + strlen(filename) + strlen(suffix) + 1); - strcpy(path, PM3_SYSTEM_DIRECTORY); + char *path = malloc(strlen(PM3_SHARE_PATH) + strlen(pm3dir) + strlen(filename) + strlen(suffix) + 1); + strcpy(path, PM3_SHARE_PATH); strcat(path, pm3dir); strcat(path, filename); strcat(path, suffix); diff --git a/client/scripting.c b/client/scripting.c index 596b535fa..664b0080f 100644 --- a/client/scripting.c +++ b/client/scripting.c @@ -1167,16 +1167,16 @@ int set_pm3_libraries(lua_State *L) { setLuaPath(L, libraries_path); } - if (strlen(PM3_SYSTEM_DIRECTORY) != 0 || strlen(LUA_SCRIPTS_DIRECTORY) != 0 || strlen(LUA_LIBRARIES_WILDCARD) != 0 ) { + if (strlen(PM3_SHARE_PATH) != 0 || strlen(LUA_SCRIPTS_DIRECTORY) != 0 || strlen(LUA_LIBRARIES_WILDCARD) != 0 ) { // from the /usr/local/share/proxmark3/luascripts/ directory - char scripts_path[strlen(PM3_SYSTEM_DIRECTORY) + strlen(LUA_SCRIPTS_DIRECTORY) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; - strcpy(scripts_path, PM3_SYSTEM_DIRECTORY); + char scripts_path[strlen(PM3_SHARE_PATH) + strlen(LUA_SCRIPTS_DIRECTORY) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; + strcpy(scripts_path, PM3_SHARE_PATH); strcat(scripts_path, LUA_SCRIPTS_DIRECTORY); strcat(scripts_path, LUA_LIBRARIES_WILDCARD); setLuaPath(L, scripts_path); // from the /usr/local/share/proxmark3/lualib/ directory - char libraries_path[strlen(PM3_SYSTEM_DIRECTORY) + strlen(LUA_LIBRARIES_DIRECTORY) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; - strcpy(libraries_path, PM3_SYSTEM_DIRECTORY); + char libraries_path[strlen(PM3_SHARE_PATH) + strlen(LUA_LIBRARIES_DIRECTORY) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; + strcpy(libraries_path, PM3_SHARE_PATH); strcat(libraries_path, LUA_LIBRARIES_DIRECTORY); strcat(libraries_path, LUA_LIBRARIES_WILDCARD); setLuaPath(L, libraries_path); diff --git a/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md b/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md index 22868121c..fd336104d 100644 --- a/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md @@ -64,12 +64,7 @@ These instructions will show how to setup the environment on OSX to the point wh 2. Install dependencies: ``` -brew install readline -brew install p7zip -brew install libusb-compat -brew install perl -brew install qt5 -brew install wget +brew install readline p7zip libusb-compat perl qt5 wget brew install RfidResearchGroup/proxmark3/arm-none-eabi-gcc ``` diff --git a/include/common.h b/include/common.h index d70bc484f..fc1d688f0 100644 --- a/include/common.h +++ b/include/common.h @@ -16,10 +16,14 @@ #include #include -#ifndef PREFIX -# define PREFIX "/usr/local/" +// brew prefixes are a bit weird so we've to split bin & share to be prepared: +#ifndef PM3_BIN_PATH +# define PM3_BIN_PATH "/usr/local/bin/" #endif -#define PM3_SYSTEM_DIRECTORY PREFIX "share/proxmark3/" +#ifndef PM3_SHARE_PATH +# define PM3_SHARE_PATH "/usr/local/share/proxmark3/" +#endif +// PM3_USER_DIRECTORY will be expanded as if with a "~" upfront, e.g. ~/.proxmark3/ #define PM3_USER_DIRECTORY "/.proxmark3/" #define PACKED __attribute__((packed)) From e0cdb5d7a7308b17aa936db51aaf999e4d7fda77 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 23 Aug 2019 21:07:20 +0200 Subject: [PATCH 0421/1854] makefile: allow override of install paths --- Makefile.host | 6 ++++++ client/Makefile | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/Makefile.host b/Makefile.host index 5bf662d9a..3220f7add 100644 --- a/Makefile.host +++ b/Makefile.host @@ -15,6 +15,12 @@ FALSE = false CFLAGS ?= -Wall -Werror -O3 CFLAGS += $(MYDEFS) $(MYCFLAGS) $(MYINCLUDES) +ifneq (,$(PM3_BIN_PATH)) + CFLAGS += -DPM3_BIN_PATH=\"$(PM3_BIN_PATH)\" +endif +ifneq (,$(PM3_SHARE_PATH)) + CFLAGS += -DPM3_SHARE_PATH=\"$(PM3_SHARE_PATH)\" +endif platform = $(shell uname) diff --git a/client/Makefile b/client/Makefile index f33c1ae9e..d9e43d445 100644 --- a/client/Makefile +++ b/client/Makefile @@ -66,6 +66,12 @@ INCLUDES_CLIENT = -I. -I../include -I../common -Iuart $(LIBS) CFLAGS ?= -Wall -Werror -g -O3 # We cannot just use CFLAGS+=... because it has impact on sub-makes if CFLAGS is defined in env: PM3CFLAGS = $(CFLAGS) -std=c99 -D_ISOC99_SOURCE $(INCLUDES_CLIENT) +ifneq (,$(PM3_BIN_PATH)) + PM3CFLAGS += -DPM3_BIN_PATH=\"$(PM3_BIN_PATH)\" +endif +ifneq (,$(PM3_SHARE_PATH)) + PM3CFLAGS += -DPM3_SHARE_PATH=\"$(PM3_SHARE_PATH)\" +endif ifneq (,$(findstring MINGW,$(platform))) PM3CFLAGS += -mno-ms-bitfields endif From 31e430744bb0948e73596aa5d4c42612857661b0 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 23 Aug 2019 21:49:58 +0200 Subject: [PATCH 0422/1854] searchFile: use filenamemcopy --- client/fileutils.c | 45 ++++++++++++++++++++++----------------------- client/fileutils.h | 2 +- 2 files changed, 23 insertions(+), 24 deletions(-) diff --git a/client/fileutils.c b/client/fileutils.c index 6556a9a1b..426ee3b6e 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -662,64 +662,63 @@ int searchAndList(const char *pm3dir, const char *ext) { return PM3_SUCCESS; } -char *searchFile(const char *pm3dir, const char *ext, const char *filename) { - const char *suffix = ""; - if (!str_endswith(filename, ext)) { - suffix = ext; - } +char *searchFile(const char *pm3dir, const char *suffix, const char *preferredName) { + char *filename = filenamemcopy(preferredName, suffix); + if (filename == NULL) return NULL; // explicit absolute (/) or relative path (./) => try only to match it directly if (((strlen(filename) > 1) && (filename[0] == '/')) || ((strlen(filename) > 2) && (filename[0] == '.') && (filename[1] == '/'))) { - char *path = malloc(strlen(filename) + strlen(suffix) + 1); - strcpy(path, filename); - strcat(path, suffix); - if (fileExists(path)) - return path; + if (fileExists(filename)) + return filename; else - free(path); + free(filename); return NULL; } // else // try pm3 dirs in current workdir (dev mode) const char *exec_path = get_my_executable_directory(); if (exec_path != NULL) { - char *path = malloc(strlen(exec_path) + strlen(pm3dir) + strlen(filename) + strlen(suffix) + 1); + char *path = malloc(strlen(exec_path) + strlen(pm3dir) + strlen(filename) + 1); strcpy(path, exec_path); strcat(path, pm3dir); strcat(path, filename); - strcat(path, suffix); - if (fileExists(path)) + if (fileExists(path)) { + free(filename); return path; - else + } else { free(path); + } } // try pm3 dirs in user .proxmark3 (user mode) char *user_path = getenv("HOME"); if (user_path != NULL) { - char *path = malloc(strlen(user_path) + strlen(PM3_USER_DIRECTORY) + strlen(pm3dir) + strlen(filename) + strlen(suffix) + 1); + char *path = malloc(strlen(user_path) + strlen(PM3_USER_DIRECTORY) + strlen(pm3dir) + strlen(filename) + 1); strcpy(path, user_path); strcat(path, PM3_USER_DIRECTORY); strcat(path, pm3dir); strcat(path, filename); - strcat(path, suffix); - if (fileExists(path)) + if (fileExists(path)) { + free(filename); return path; - else + } else { free(path); + } } // try pm3 dirs in pm3 installation dir (install mode) { - char *path = malloc(strlen(PM3_SHARE_PATH) + strlen(pm3dir) + strlen(filename) + strlen(suffix) + 1); + char *path = malloc(strlen(PM3_SHARE_PATH) + strlen(pm3dir) + strlen(filename) + 1); strcpy(path, PM3_SHARE_PATH); strcat(path, pm3dir); strcat(path, filename); - strcat(path, suffix); - if (fileExists(path)) + if (fileExists(path)) { + free(filename); return path; - else + } else { free(path); + } } + free(filename); return NULL; } diff --git a/client/fileutils.h b/client/fileutils.h index 99c3c4d1d..ed36d3771 100644 --- a/client/fileutils.h +++ b/client/fileutils.h @@ -161,6 +161,6 @@ int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, u int convertOldMfuDump(uint8_t **dump, size_t *dumplen); int searchAndList(const char *pm3dir, const char *ext); -char *searchFile(const char *pm3dir, const char *ext, const char *filename); +char *searchFile(const char *pm3dir, const char *suffix, const char *preferredName); #endif // FILEUTILS_H From 34a0fdb9d69fe67e14afcabfb83f6e5642f94752 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 23 Aug 2019 22:07:45 +0200 Subject: [PATCH 0423/1854] reorganize lua script dir defs --- client/cmdscript.c | 4 ++-- client/scripting.c | 26 +++++++++++++------------- client/scripting.h | 2 -- include/common.h | 4 ++++ 4 files changed, 19 insertions(+), 17 deletions(-) diff --git a/client/cmdscript.c b/client/cmdscript.c index 8a748b8ab..889259922 100644 --- a/client/cmdscript.c +++ b/client/cmdscript.c @@ -33,7 +33,7 @@ static int CmdHelp(const char *Cmd); */ static int CmdScriptList(const char *Cmd) { (void)Cmd; // Cmd is not used so far - return searchAndList(LUA_SCRIPTS_DIRECTORY, ".lua"); + return searchAndList(LUA_SCRIPTS_SUBDIR, ".lua"); } /** @@ -66,7 +66,7 @@ static int CmdScriptRun(const char *Cmd) { int arg_len = 0; sscanf(Cmd, "%127s%n %255[^\n\r]%n", script_name, &name_len, arguments, &arg_len); - char *script_path = searchFile(LUA_SCRIPTS_DIRECTORY, ".lua", script_name); + char *script_path = searchFile(LUA_SCRIPTS_SUBDIR, ".lua", script_name); if (script_path == NULL) { PrintAndLogEx(FAILED, "Error - can't find script %s", script_name); return PM3_EFILE; diff --git a/client/scripting.c b/client/scripting.c index 664b0080f..dc3051207 100644 --- a/client/scripting.c +++ b/client/scripting.c @@ -1136,48 +1136,48 @@ int set_pm3_libraries(lua_State *L) { const char *exec_path = get_my_executable_directory(); if (exec_path != NULL) { // from the ./luascripts/ directory - char scripts_path[strlen(exec_path) + strlen(LUA_SCRIPTS_DIRECTORY) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; + char scripts_path[strlen(exec_path) + strlen(LUA_SCRIPTS_SUBDIR) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; strcpy(scripts_path, exec_path); - strcat(scripts_path, LUA_SCRIPTS_DIRECTORY); + strcat(scripts_path, LUA_SCRIPTS_SUBDIR); strcat(scripts_path, LUA_LIBRARIES_WILDCARD); setLuaPath(L, scripts_path); // from the ./lualib/ directory - char libraries_path[strlen(exec_path) + strlen(LUA_LIBRARIES_DIRECTORY) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; + char libraries_path[strlen(exec_path) + strlen(LUA_LIBRARIES_SUBDIR) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; strcpy(libraries_path, exec_path); - strcat(libraries_path, LUA_LIBRARIES_DIRECTORY); + strcat(libraries_path, LUA_LIBRARIES_SUBDIR); strcat(libraries_path, LUA_LIBRARIES_WILDCARD); setLuaPath(L, libraries_path); } char *user_path = getenv("HOME"); if (user_path != NULL) { // from the ~/.proxmark3/luascripts/ directory - char scripts_path[strlen(user_path) + strlen(PM3_USER_DIRECTORY) + strlen(LUA_SCRIPTS_DIRECTORY) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; + char scripts_path[strlen(user_path) + strlen(PM3_USER_DIRECTORY) + strlen(LUA_SCRIPTS_SUBDIR) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; strcpy(scripts_path, user_path); strcat(scripts_path, PM3_USER_DIRECTORY); - strcat(scripts_path, LUA_SCRIPTS_DIRECTORY); + strcat(scripts_path, LUA_SCRIPTS_SUBDIR); strcat(scripts_path, LUA_LIBRARIES_WILDCARD); setLuaPath(L, scripts_path); // from the ~/.proxmark3/lualib/ directory - char libraries_path[strlen(user_path) + strlen(PM3_USER_DIRECTORY) + strlen(LUA_LIBRARIES_DIRECTORY) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; + char libraries_path[strlen(user_path) + strlen(PM3_USER_DIRECTORY) + strlen(LUA_LIBRARIES_SUBDIR) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; strcpy(libraries_path, user_path); strcat(libraries_path, PM3_USER_DIRECTORY); - strcat(libraries_path, LUA_LIBRARIES_DIRECTORY); + strcat(libraries_path, LUA_LIBRARIES_SUBDIR); strcat(libraries_path, LUA_LIBRARIES_WILDCARD); setLuaPath(L, libraries_path); } - if (strlen(PM3_SHARE_PATH) != 0 || strlen(LUA_SCRIPTS_DIRECTORY) != 0 || strlen(LUA_LIBRARIES_WILDCARD) != 0 ) { + if (strlen(PM3_SHARE_PATH) != 0 || strlen(LUA_SCRIPTS_SUBDIR) != 0 || strlen(LUA_LIBRARIES_WILDCARD) != 0 ) { // from the /usr/local/share/proxmark3/luascripts/ directory - char scripts_path[strlen(PM3_SHARE_PATH) + strlen(LUA_SCRIPTS_DIRECTORY) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; + char scripts_path[strlen(PM3_SHARE_PATH) + strlen(LUA_SCRIPTS_SUBDIR) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; strcpy(scripts_path, PM3_SHARE_PATH); - strcat(scripts_path, LUA_SCRIPTS_DIRECTORY); + strcat(scripts_path, LUA_SCRIPTS_SUBDIR); strcat(scripts_path, LUA_LIBRARIES_WILDCARD); setLuaPath(L, scripts_path); // from the /usr/local/share/proxmark3/lualib/ directory - char libraries_path[strlen(PM3_SHARE_PATH) + strlen(LUA_LIBRARIES_DIRECTORY) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; + char libraries_path[strlen(PM3_SHARE_PATH) + strlen(LUA_LIBRARIES_SUBDIR) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; strcpy(libraries_path, PM3_SHARE_PATH); - strcat(libraries_path, LUA_LIBRARIES_DIRECTORY); + strcat(libraries_path, LUA_LIBRARIES_SUBDIR); strcat(libraries_path, LUA_LIBRARIES_WILDCARD); setLuaPath(L, libraries_path); } diff --git a/client/scripting.h b/client/scripting.h index 1a7b5a7e3..b23ce3a9a 100644 --- a/client/scripting.h +++ b/client/scripting.h @@ -14,8 +14,6 @@ //#include //#include -#define LUA_LIBRARIES_DIRECTORY "lualibs/" -#define LUA_SCRIPTS_DIRECTORY "luascripts/" #define LUA_LIBRARIES_WILDCARD "?.lua" /** diff --git a/include/common.h b/include/common.h index fc1d688f0..580170b31 100644 --- a/include/common.h +++ b/include/common.h @@ -26,6 +26,10 @@ // PM3_USER_DIRECTORY will be expanded as if with a "~" upfront, e.g. ~/.proxmark3/ #define PM3_USER_DIRECTORY "/.proxmark3/" +// PM3 subdirectories: +#define LUA_LIBRARIES_SUBDIR "lualibs/" +#define LUA_SCRIPTS_SUBDIR "luascripts/" + #define PACKED __attribute__((packed)) // debug From 8c26e07ceb7cd15a605cc46d825609edb0c16ab9 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 23 Aug 2019 22:08:36 +0200 Subject: [PATCH 0424/1854] use searchFile to find dictionaries --- client/fileutils.c | 2 +- include/common.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/client/fileutils.c b/client/fileutils.c index 426ee3b6e..8e9ceb228 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -523,7 +523,7 @@ int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, u if (data == NULL) return 1; - char *fileName = filenamemcopy(preferredName, ".dic"); + char *fileName = searchFile(DICTIONARIES_SUBDIR, ".dic", preferredName); if (fileName == NULL) return 1; // t5577 == 4bytes diff --git a/include/common.h b/include/common.h index 580170b31..a2850ef32 100644 --- a/include/common.h +++ b/include/common.h @@ -27,6 +27,7 @@ #define PM3_USER_DIRECTORY "/.proxmark3/" // PM3 subdirectories: +#define DICTIONARIES_SUBDIR "dictionaries/" #define LUA_LIBRARIES_SUBDIR "lualibs/" #define LUA_SCRIPTS_SUBDIR "luascripts/" From 4b95be1b3925825e573cd302a1391df4431aae7f Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 23 Aug 2019 22:09:54 +0200 Subject: [PATCH 0425/1854] searchFile: search also implicit relative path --- client/fileutils.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/client/fileutils.c b/client/fileutils.c index 8e9ceb228..86835babd 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -677,6 +677,12 @@ char *searchFile(const char *pm3dir, const char *suffix, const char *preferredNa return NULL; } // else + + // try implicit relative path + { + if (fileExists(filename)) + return filename; + } // try pm3 dirs in current workdir (dev mode) const char *exec_path = get_my_executable_directory(); if (exec_path != NULL) { From b09849c91b85df25b46c6ed64a879e662542a56b Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 23 Aug 2019 23:07:05 +0200 Subject: [PATCH 0426/1854] pull filenamemcopy out of searchFile --- client/cmdscript.c | 11 ++++++++--- client/fileutils.c | 43 +++++++++++++++++++++++++++---------------- client/fileutils.h | 3 ++- 3 files changed, 37 insertions(+), 20 deletions(-) diff --git a/client/cmdscript.c b/client/cmdscript.c index 889259922..37778d52e 100644 --- a/client/cmdscript.c +++ b/client/cmdscript.c @@ -59,18 +59,23 @@ static int CmdScriptRun(const char *Cmd) { //Add the 'bit' library set_bit_library(lua_state); - char script_name[128] = {0}; + char preferredName[128] = {0}; char arguments[256] = {0}; int name_len = 0; int arg_len = 0; - sscanf(Cmd, "%127s%n %255[^\n\r]%n", script_name, &name_len, arguments, &arg_len); + sscanf(Cmd, "%127s%n %255[^\n\r]%n", preferredName, &name_len, arguments, &arg_len); + + char *script_name = filenamemcopy(preferredName, ".lua"); + if (script_name == NULL) return PM3_EMALLOC; + char *script_path = searchFile(LUA_SCRIPTS_SUBDIR, script_name); - char *script_path = searchFile(LUA_SCRIPTS_SUBDIR, ".lua", script_name); if (script_path == NULL) { PrintAndLogEx(FAILED, "Error - can't find script %s", script_name); + free(script_name); return PM3_EFILE; } + free(script_name); int error; PrintAndLogEx(SUCCESS, "Executing: %s, args '%s'\n", script_path, arguments); error = luaL_loadfile(lua_state, script_path); diff --git a/client/fileutils.c b/client/fileutils.c index 86835babd..52fd1539f 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -69,7 +69,7 @@ int fileExists(const char *filename) { return result == 0; } -static char *filenamemcopy(const char *preferredName, const char *suffix) { +char *filenamemcopy(const char *preferredName, const char *suffix) { if (preferredName == NULL) return NULL; if (suffix == NULL) return NULL; char *fileName = (char *) calloc(strlen(preferredName) + strlen(suffix) + 1, sizeof(uint8_t)); @@ -521,11 +521,16 @@ out: int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, uint8_t keylen, uint16_t *keycnt) { - - if (data == NULL) return 1; - char *fileName = searchFile(DICTIONARIES_SUBDIR, ".dic", preferredName); - if (fileName == NULL) return 1; - + if (data == NULL) return PM3_ESOFT; + char *fileName = filenamemcopy(preferredName, ".dic"); + if (fileName == NULL) return PM3_EMALLOC; + char *path = searchFile(DICTIONARIES_SUBDIR, fileName); + if (path == NULL) { + PrintAndLogEx(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", fileName); + free(fileName); + return PM3_EFILE; + } + free(fileName); // t5577 == 4bytes // mifare == 6 bytes // iclass == 8 bytes @@ -542,9 +547,9 @@ int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, u size_t counter = 0; int retval = PM3_SUCCESS; - FILE *f = fopen(fileName, "r"); + FILE *f = fopen(path, "r"); if (!f) { - PrintAndLogEx(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", fileName); + PrintAndLogEx(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", path); retval = PM3_EFILE; goto out; } @@ -576,12 +581,12 @@ int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, u counter += (keylen >> 1); } fclose(f); - PrintAndLogEx(SUCCESS, "loaded " _GREEN_("%2d") "keys from dictionary file " _YELLOW_("%s"), *keycnt, fileName); + PrintAndLogEx(SUCCESS, "loaded " _GREEN_("%2d") "keys from dictionary file " _YELLOW_("%s"), *keycnt, path); if (datalen) *datalen = counter; out: - free(fileName); + free(path); return retval; } @@ -662,19 +667,18 @@ int searchAndList(const char *pm3dir, const char *ext) { return PM3_SUCCESS; } -char *searchFile(const char *pm3dir, const char *suffix, const char *preferredName) { - char *filename = filenamemcopy(preferredName, suffix); - if (filename == NULL) return NULL; - +char *searchFile(const char *pm3dir, const char *searchname) { // explicit absolute (/) or relative path (./) => try only to match it directly + char *filename = malloc(strlen(searchname) + 1); + if (filename == NULL) return NULL; + strcpy(filename, searchname); if (((strlen(filename) > 1) && (filename[0] == '/')) || ((strlen(filename) > 2) && (filename[0] == '.') && (filename[1] == '/'))) { if (fileExists(filename)) return filename; else - free(filename); - return NULL; + goto out; } // else @@ -687,6 +691,8 @@ char *searchFile(const char *pm3dir, const char *suffix, const char *preferredNa const char *exec_path = get_my_executable_directory(); if (exec_path != NULL) { char *path = malloc(strlen(exec_path) + strlen(pm3dir) + strlen(filename) + 1); + if (path == NULL) + goto out; strcpy(path, exec_path); strcat(path, pm3dir); strcat(path, filename); @@ -701,6 +707,8 @@ char *searchFile(const char *pm3dir, const char *suffix, const char *preferredNa char *user_path = getenv("HOME"); if (user_path != NULL) { char *path = malloc(strlen(user_path) + strlen(PM3_USER_DIRECTORY) + strlen(pm3dir) + strlen(filename) + 1); + if (path == NULL) + goto out; strcpy(path, user_path); strcat(path, PM3_USER_DIRECTORY); strcat(path, pm3dir); @@ -715,6 +723,8 @@ char *searchFile(const char *pm3dir, const char *suffix, const char *preferredNa // try pm3 dirs in pm3 installation dir (install mode) { char *path = malloc(strlen(PM3_SHARE_PATH) + strlen(pm3dir) + strlen(filename) + 1); + if (path == NULL) + goto out; strcpy(path, PM3_SHARE_PATH); strcat(path, pm3dir); strcat(path, filename); @@ -725,6 +735,7 @@ char *searchFile(const char *pm3dir, const char *suffix, const char *preferredNa free(path); } } +out: free(filename); return NULL; } diff --git a/client/fileutils.h b/client/fileutils.h index ed36d3771..bb229efb5 100644 --- a/client/fileutils.h +++ b/client/fileutils.h @@ -160,7 +160,8 @@ int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, u */ int convertOldMfuDump(uint8_t **dump, size_t *dumplen); +char *filenamemcopy(const char *preferredName, const char *suffix); int searchAndList(const char *pm3dir, const char *ext); -char *searchFile(const char *pm3dir, const char *suffix, const char *preferredName); +char *searchFile(const char *pm3dir, const char *searchname); #endif // FILEUTILS_H From 9d05628c3cb87a06cc0458909c4d3a7eb3f22745 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 23 Aug 2019 23:21:20 +0200 Subject: [PATCH 0427/1854] mem load: update examples --- client/cmdflashmem.c | 6 +++--- doc/cheatsheet.md | 6 +++--- doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/client/cmdflashmem.c b/client/cmdflashmem.c index 905e6c6c8..7f1fa103e 100644 --- a/client/cmdflashmem.c +++ b/client/cmdflashmem.c @@ -59,9 +59,9 @@ static int usage_flashmem_load(void) { PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " mem load f myfile"); // upload file myfile at default offset 0 PrintAndLogEx(NORMAL, " mem load f myfile o 1024"); // upload file myfile at offset 1024 - PrintAndLogEx(NORMAL, " mem load f dictionaries/mfc_default_keys m"); - PrintAndLogEx(NORMAL, " mem load f dictionaries/t55xx_default_pwds t"); - PrintAndLogEx(NORMAL, " mem load f dictionaries/iclass_default_keys i"); + PrintAndLogEx(NORMAL, " mem load f mfc_default_keys m"); + PrintAndLogEx(NORMAL, " mem load f t55xx_default_pwds t"); + PrintAndLogEx(NORMAL, " mem load f iclass_default_keys i"); return PM3_SUCCESS; } static int usage_flashmem_dump(void) { diff --git a/doc/cheatsheet.md b/doc/cheatsheet.md index 75c554e94..02628a9bc 100644 --- a/doc/cheatsheet.md +++ b/doc/cheatsheet.md @@ -512,9 +512,9 @@ m : upload 6 bytes keys (mifare key dictionary) i : upload 8 bytes keys (iClass key dictionary) t : upload 4 bytes keys (pwd dictionary) -pm3 --> mem load f dictionaries/mfc_default_keys m -pm3 --> mem load f dictionaries/t55xx_default_pwds t -pm3 --> mem load f dictionaries/iclass_default_keys i +pm3 --> mem load f mfc_default_keys m +pm3 --> mem load f t55xx_default_pwds t +pm3 --> mem load f iclass_default_keys i ``` ## Sim Module diff --git a/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md b/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md index 84f64821c..8b5244cf6 100644 --- a/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md +++ b/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md @@ -1,9 +1,9 @@ ### First things on your RDV40 You will need to run these commands to make sure your rdv4 is prepared ``` -pm3 --> mem load f dictionaries/mfc_default_keys m -pm3 --> mem load f dictionaries/t55xx_default_pwds t -pm3 --> mem load f dictionaries/iclass_default_keys i +pm3 --> mem load f mfc_default_keys m +pm3 --> mem load f t55xx_default_pwds t +pm3 --> mem load f iclass_default_keys i pm3 --> lf t55xx deviceconfig a 29 b 17 c 15 d 47 e 15 p pm3 --> lf t55xx deviceconfig r 1 a 31 b 20 c 18 d 50 e 15 p pm3 --> lf t55xx deviceconfig r 2 a 31 b 20 c 18 d 40 e 15 p From c6145a81c2f628c88e26a5637e91b83e76aac5b9 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 24 Aug 2019 05:08:03 +0200 Subject: [PATCH 0428/1854] chg: iclass commands --- client/cmdhficlass.c | 179 ++++++++++++++++++++++++++----------------- 1 file changed, 108 insertions(+), 71 deletions(-) diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 4b815355b..51bc323fc 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -60,14 +60,14 @@ static int usage_hf_iclass_sim(void) { PrintAndLogEx(NORMAL, " hf iclass eload 'tagdump.bin'"); PrintAndLogEx(NORMAL, " hf iclass sim 3"); PrintAndLogEx(NORMAL, " hf iclass sim 4"); - return 0; + return PM3_SUCCESS; } static int usage_hf_iclass_eload(void) { PrintAndLogEx(NORMAL, "Loads iclass tag-dump into emulator memory on device"); PrintAndLogEx(NORMAL, "Usage: hf iclass eload f "); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf iclass eload f iclass_tagdump-aa162d30f8ff12f1.bin"); - return 0; + return PM3_SUCCESS; } static int usage_hf_iclass_decrypt(void) { PrintAndLogEx(NORMAL, "This is simple implementation, it tries to decrypt every block after block 6."); @@ -80,7 +80,7 @@ static int usage_hf_iclass_decrypt(void) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, "S hf iclass decrypt f tagdump_12312342343.bin"); - return 0; + return PM3_SUCCESS; } static int usage_hf_iclass_encrypt(void) { PrintAndLogEx(NORMAL, "OBS! In order to use this function, the file 'iclass_decryptionkey.bin' must reside"); @@ -91,7 +91,7 @@ static int usage_hf_iclass_encrypt(void) { PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf iclass encrypt 0102030405060708"); PrintAndLogEx(NORMAL, ""); - return 0; + return PM3_SUCCESS; } static int usage_hf_iclass_dump(void) { PrintAndLogEx(NORMAL, "Usage: hf iclass dump f k c [e|r|v]\n"); @@ -107,23 +107,23 @@ static int usage_hf_iclass_dump(void) { PrintAndLogEx(NORMAL, " hf iclass dump k 001122334455667B"); PrintAndLogEx(NORMAL, " hf iclass dump k AAAAAAAAAAAAAAAA c 001122334455667B"); PrintAndLogEx(NORMAL, " hf iclass dump k AAAAAAAAAAAAAAAA e"); - return 0; + return PM3_SUCCESS; } static int usage_hf_iclass_clone(void) { PrintAndLogEx(NORMAL, "Usage: hf iclass clone f b l k c e|r"); PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " f : specify a filename to clone from"); - PrintAndLogEx(NORMAL, " b : The first block to clone as 2 hex symbols"); - PrintAndLogEx(NORMAL, " l : Set the Data to write as 16 hex symbols"); - PrintAndLogEx(NORMAL, " k : Access Key as 16 hex symbols or 1 hex to select key from memory"); - PrintAndLogEx(NORMAL, " c : If 'c' is specified, the key set is assumed to be the credit key\n"); - PrintAndLogEx(NORMAL, " e : If 'e' is specified, elite computations applied to key"); - PrintAndLogEx(NORMAL, " r : If 'r' is specified, no computations applied to key"); + PrintAndLogEx(NORMAL, " f : specify a filename to clone from"); + PrintAndLogEx(NORMAL, " b : The first block to clone as 2 hex symbols"); + PrintAndLogEx(NORMAL, " l : Set the Data to write as 16 hex symbols"); + PrintAndLogEx(NORMAL, " k : Access Key as 16 hex symbols or 1 hex to select key from memory"); + PrintAndLogEx(NORMAL, " c : If 'c' is specified, the key set is assumed to be the credit key\n"); + PrintAndLogEx(NORMAL, " e : If 'e' is specified, elite computations applied to key"); + PrintAndLogEx(NORMAL, " r : If 'r' is specified, no computations applied to key"); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf iclass clone f iclass_tagdump-121345.bin b 06 l 1A k 1122334455667788 e"); PrintAndLogEx(NORMAL, " hf iclass clone f iclass_tagdump-121345.bin b 05 l 19 k 0"); PrintAndLogEx(NORMAL, " hf iclass clone f iclass_tagdump-121345.bin b 06 l 19 k 0 e"); - return 0; + return PM3_SUCCESS; } static int usage_hf_iclass_writeblock(void) { PrintAndLogEx(NORMAL, "Usage: hf iclass writeblk b d k [c|e|r|v]\n"); @@ -138,7 +138,7 @@ static int usage_hf_iclass_writeblock(void) { PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf iclass writeblk b 0A d AAAAAAAAAAAAAAAA k 001122334455667B"); PrintAndLogEx(NORMAL, " hf iclass writeblk b 1B d AAAAAAAAAAAAAAAA k 001122334455667B c"); - return 0; + return PM3_SUCCESS; } static int usage_hf_iclass_readblock(void) { PrintAndLogEx(NORMAL, "Usage: hf iclass readblk b k [c|e|r|v]\n"); @@ -153,11 +153,11 @@ static int usage_hf_iclass_readblock(void) { PrintAndLogEx(NORMAL, " hf iclass readblk b 06 k 0011223344556677"); PrintAndLogEx(NORMAL, " hf iclass readblk b 1B k 0011223344556677 c"); PrintAndLogEx(NORMAL, " hf iclass readblk b 0A k 0"); - return 0; + return PM3_SUCCESS; } static int usage_hf_iclass_readtagfile() { PrintAndLogEx(NORMAL, "Usage: hf iclass readtagfile [startblock] [endblock]"); - return 0; + return PM3_SUCCESS; } static int usage_hf_iclass_calc_newkey(void) { PrintAndLogEx(NORMAL, "Calculate new key for updating\n"); @@ -173,24 +173,24 @@ static int usage_hf_iclass_calc_newkey(void) { PrintAndLogEx(NORMAL, " std key to e key read csn : hf iclass calcnewkey o 1122334455667788 n 2233445566778899 e"); PrintAndLogEx(NORMAL, " std to std read csn : hf iclass calcnewkey o 1122334455667788 n 2233445566778899"); PrintAndLogEx(NORMAL, "\nNOTE: * = required\n"); - return 0; + return PM3_SUCCESS;; } static int usage_hf_iclass_managekeys(void) { PrintAndLogEx(NORMAL, "HELP : Manage iClass Keys in client memory:\n"); PrintAndLogEx(NORMAL, "Usage: hf iclass managekeys n [keynbr] k [key] f [filename] s l p\n"); PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " n : specify the keyNbr to set in memory"); - PrintAndLogEx(NORMAL, " k : set a key in memory"); - PrintAndLogEx(NORMAL, " f : specify a filename to use with load or save operations"); - PrintAndLogEx(NORMAL, " s : save keys in memory to file specified by filename"); - PrintAndLogEx(NORMAL, " l : load keys to memory from file specified by filename"); - PrintAndLogEx(NORMAL, " p : print keys loaded into memory\n"); + PrintAndLogEx(NORMAL, " n : specify the keyNbr to set in memory"); + PrintAndLogEx(NORMAL, " k : set a key in memory"); + PrintAndLogEx(NORMAL, " f : specify a filename to use with load or save operations"); + PrintAndLogEx(NORMAL, " s : save keys in memory to file specified by filename"); + PrintAndLogEx(NORMAL, " l : load keys to memory from file specified by filename"); + PrintAndLogEx(NORMAL, " p : print keys loaded into memory\n"); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " set key : hf iclass managekeys n 0 k 1122334455667788"); - PrintAndLogEx(NORMAL, " save key file: hf iclass managekeys f mykeys.bin s"); - PrintAndLogEx(NORMAL, " load key file: hf iclass managekeys f mykeys.bin l"); - PrintAndLogEx(NORMAL, " print keys : hf iclass managekeys p\n"); - return 0; + PrintAndLogEx(NORMAL, " set key : hf iclass managekeys n 0 k 1122334455667788"); + PrintAndLogEx(NORMAL, " save key file : hf iclass managekeys f mykeys.bin s"); + PrintAndLogEx(NORMAL, " load key file : hf iclass managekeys f mykeys.bin l"); + PrintAndLogEx(NORMAL, " print keys : hf iclass managekeys p\n"); + return PM3_SUCCESS; } static int usage_hf_iclass_reader(void) { PrintAndLogEx(NORMAL, "Act as a Iclass reader. Look for iClass tags until Enter or the pm3 button is pressed\n"); @@ -200,7 +200,7 @@ static int usage_hf_iclass_reader(void) { PrintAndLogEx(NORMAL, " 1 read only 1 tag"); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf iclass reader 1"); - return 0; + return PM3_SUCCESS; } static int usage_hf_iclass_replay(void) { PrintAndLogEx(NORMAL, "Replay a collected mac message"); @@ -210,29 +210,29 @@ static int usage_hf_iclass_replay(void) { PrintAndLogEx(NORMAL, " Mac bytes to replay (8 hexsymbols)"); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf iclass replay 00112233"); - return 0; + return PM3_SUCCESS; } static int usage_hf_iclass_sniff(void) { PrintAndLogEx(NORMAL, "Sniff the communication between reader and tag"); PrintAndLogEx(NORMAL, "Usage: hf iclass sniff [h]"); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf iclass sniff"); - return 0; + return PM3_SUCCESS; } static int usage_hf_iclass_loclass(void) { PrintAndLogEx(NORMAL, "Usage: hf iclass loclass [options]"); PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, "h Show this help"); - PrintAndLogEx(NORMAL, "t Perform self-test"); - PrintAndLogEx(NORMAL, "f Bruteforce iclass dumpfile"); - PrintAndLogEx(NORMAL, " An iclass dumpfile is assumed to consist of an arbitrary number of"); - PrintAndLogEx(NORMAL, " malicious CSNs, and their protocol responses"); - PrintAndLogEx(NORMAL, " The binary format of the file is expected to be as follows: "); - PrintAndLogEx(NORMAL, " <8 byte CSN><8 byte CC><4 byte NR><4 byte MAC>"); - PrintAndLogEx(NORMAL, " <8 byte CSN><8 byte CC><4 byte NR><4 byte MAC>"); - PrintAndLogEx(NORMAL, " <8 byte CSN><8 byte CC><4 byte NR><4 byte MAC>"); - PrintAndLogEx(NORMAL, " ... totalling N*24 bytes"); - return 0; + PrintAndLogEx(NORMAL, " h Show this help"); + PrintAndLogEx(NORMAL, " t Perform self-test"); + PrintAndLogEx(NORMAL, " f Bruteforce iclass dumpfile"); + PrintAndLogEx(NORMAL, " An iclass dumpfile is assumed to consist of an arbitrary number of"); + PrintAndLogEx(NORMAL, " malicious CSNs, and their protocol responses"); + PrintAndLogEx(NORMAL, " The binary format of the file is expected to be as follows: "); + PrintAndLogEx(NORMAL, " <8 byte CSN><8 byte CC><4 byte NR><4 byte MAC>"); + PrintAndLogEx(NORMAL, " <8 byte CSN><8 byte CC><4 byte NR><4 byte MAC>"); + PrintAndLogEx(NORMAL, " <8 byte CSN><8 byte CC><4 byte NR><4 byte MAC>"); + PrintAndLogEx(NORMAL, " ... totalling N*24 bytes"); + return PM3_SUCCESS; } static int usage_hf_iclass_chk(void) { PrintAndLogEx(NORMAL, "Checkkeys loads a dictionary text file with 8byte hex keys to test authenticating against a iClass tag"); @@ -246,7 +246,7 @@ static int usage_hf_iclass_chk(void) { PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf iclass chk f dictionaries/iclass_default_keys.dic"); PrintAndLogEx(NORMAL, " hf iclass chk f dictionaries/iclass_default_keys.dic e"); - return 0; + return PM3_SUCCESS;; } static int usage_hf_iclass_lookup(void) { PrintAndLogEx(NORMAL, "Lookup keys takes some sniffed trace data and tries to verify what key was used against a dictionary file"); @@ -262,7 +262,7 @@ static int usage_hf_iclass_lookup(void) { PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf iclass lookup u 9655a400f8ff12e0 p f0ffffffffffffff m 0000000089cb984b f dictionaries/iclass_default_keys.dic"); PrintAndLogEx(NORMAL, " hf iclass lookup u 9655a400f8ff12e0 p f0ffffffffffffff m 0000000089cb984b f dictionaries/iclass_default_keys.dic e"); - return 0; + return PM3_SUCCESS; } static int usage_hf_iclass_permutekey(void) { PrintAndLogEx(NORMAL, "Permute function from 'heart of darkness' paper."); @@ -276,7 +276,7 @@ static int usage_hf_iclass_permutekey(void) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf iclass permute r 0123456789abcdef"); - return 0; + return PM3_SUCCESS; } /* @@ -860,6 +860,7 @@ static int CmdHFiClassDecrypt(const char *Cmd) { } saveFile(outfilename, ".bin", decrypted, fsize); + saveFileEML(outfilename, decrypted, fsize, 8); printIclassDumpContents(decrypted, 1, (fsize / 8), fsize); free(decrypted); return PM3_SUCCESS; @@ -1511,6 +1512,7 @@ static int ReadBlock(uint8_t *KEY, uint8_t blockno, uint8_t keyType, bool elite, } //data read is stored in: resp.data.asBytes[0-15] PrintAndLogEx(NORMAL, "block %02X: %s\n", blockno, sprint_hex(resp.data.asBytes, 8)); + // should decrypt it if file is accessable. return 1; } @@ -1583,6 +1585,7 @@ static int CmdHFiClass_ReadBlock(const char *Cmd) { if (!auth) PrintAndLogEx(FAILED, "warning: no authentication used with read, only a few specific blocks can be read accurately without authentication."); + return ReadBlock(KEY, blockno, keyType, elite, rawkey, verbose, auth); } @@ -1856,7 +1859,7 @@ static int loadKeys(char *filename) { memcpy(iClass_Key_Table[i], dump + (i * 8), 8); free(dump); - PrintAndLogEx(SUCCESS, "%u keys loaded", i); + PrintAndLogEx(SUCCESS, "Loaded " _GREEN_("%2d") "keys from %s", i, filename); return PM3_SUCCESS; } @@ -1879,8 +1882,12 @@ static int saveKeys(char *filename) { static int printKeys(void) { PrintAndLogEx(NORMAL, ""); - for (uint8_t i = 0; i < ICLASS_KEYS_MAX; i++) - PrintAndLogEx(NORMAL, "%u: %s", i, sprint_hex(iClass_Key_Table[i], 8)); + for (uint8_t i = 0; i < ICLASS_KEYS_MAX; i++) { + if ( memcmp(iClass_Key_Table[i], "\x00\x00\x00\x00\x00\x00\x00\x00", 8) == 0) + PrintAndLogEx(NORMAL, "%u: %s", i, sprint_hex(iClass_Key_Table[i], 8)); + else + PrintAndLogEx(NORMAL, "%u: "_YELLOW_("%s"), i, sprint_hex(iClass_Key_Table[i], 8)); + } PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } @@ -1963,14 +1970,13 @@ static int CmdHFiClassManageKeys(const char *Cmd) { switch (operation) { case 3: memcpy(iClass_Key_Table[keyNbr], KEY, 8); - return 1; + return PM3_SUCCESS; case 4: return printKeys(); case 5: return loadKeys(filename); case 6: return saveKeys(filename); - break; } return PM3_SUCCESS; } @@ -2010,7 +2016,7 @@ static int CmdHFiClassCheckKeys(const char *Cmd) { case 'f': fileNameLen = param_getstr(Cmd, cmdp + 1, filename, sizeof(filename)); if (fileNameLen < 1) { - PrintAndLogEx(WARNING, "no filename found after f"); + PrintAndLogEx(WARNING, _RED_("no filename found after f")); errors = true; } cmdp += 2; @@ -2048,29 +2054,29 @@ static int CmdHFiClassCheckKeys(const char *Cmd) { if (!got_csn) { PrintAndLogEx(WARNING, "can't select card, aborting..."); - return 1; + return PM3_ESOFT; } // load keys into keyblock int res = LoadDictionaryKeyFile(filename, &keyBlock, &keycnt); if (res > 0) { free(keyBlock); - return 1; + return PM3_EFILE; } pre = calloc(keycnt, sizeof(iclass_premac_t)); if (!pre) { free(keyBlock); - return 1; + return PM3_EMALLOC; } PrintAndLogEx(SUCCESS, "Generating diversified keys, MAC"); if (use_elite) - PrintAndLogEx(SUCCESS, "Using elite algo"); + PrintAndLogEx(SUCCESS, "Using " _YELLOW_("elite algo")); if (use_raw) - PrintAndLogEx(SUCCESS, "Using raw mode"); + PrintAndLogEx(SUCCESS, "Using " _YELLOW_(" raw mode")); - PrintAndLogEx(SUCCESS, "Searching for %s key", (use_credit_key) ? "CREDIT" : "DEBIT"); + PrintAndLogEx(SUCCESS, "Searching for " _YELLOW_("%s") "key", (use_credit_key) ? "CREDIT" : "DEBIT"); PrintAndLogEx(SUCCESS, "Tag info"); PrintAndLogEx(SUCCESS, "CSN | %s", sprint_hex(CSN, sizeof(CSN))); PrintAndLogEx(SUCCESS, "CCNR | %s", sprint_hex(CCNR, sizeof(CCNR))); @@ -2078,7 +2084,7 @@ static int CmdHFiClassCheckKeys(const char *Cmd) { if (res > 0) { free(keyBlock); free(pre); - return 1; + return PM3_ESOFT; } //PrintPreCalcMac(keyBlock, keycnt, pre); @@ -2090,8 +2096,11 @@ static int CmdHFiClassCheckKeys(const char *Cmd) { // fast push mode conn.block_after_ACK = true; + // keep track of position of found key + uint8_t found_offset = 0; + uint32_t key_offset = 0; // main keychunk loop - for (uint32_t i = 0; i < keycnt; i += chunksize) { + for (uint32_t key_offset = 0; key_offset < keycnt; key_offset += chunksize) { uint64_t t2 = msclock(); uint8_t timeout = 0; @@ -2101,10 +2110,10 @@ static int CmdHFiClassCheckKeys(const char *Cmd) { goto out; } - uint32_t keys = ((keycnt - i) > chunksize) ? chunksize : keycnt - i; + uint32_t keys = ((keycnt - key_offset) > chunksize) ? chunksize : keycnt - key_offset; // last chunk? - if (keys == keycnt - i) { + if (keys == keycnt - key_offset) { lastChunk = true; // Disable fast mode on last command conn.block_after_ACK = false; @@ -2116,7 +2125,7 @@ static int CmdHFiClassCheckKeys(const char *Cmd) { flags |= (use_credit_key << 16); clearCommandBuffer(); - SendCommandOLD(CMD_HF_ICLASS_CHKKEYS, flags, keys, 0, pre + i, 4 * keys); + SendCommandOLD(CMD_HF_ICLASS_CHKKEYS, flags, keys, 0, pre + key_offset, 4 * keys); PacketResponseNG resp; while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { @@ -2129,7 +2138,7 @@ static int CmdHFiClassCheckKeys(const char *Cmd) { } } - uint8_t found = resp.oldarg[1] & 0xFF; + found_offset = resp.oldarg[1] & 0xFF; uint8_t isOK = resp.oldarg[0] & 0xFF; t2 = msclock() - t2; @@ -2138,18 +2147,18 @@ static int CmdHFiClassCheckKeys(const char *Cmd) { found_debit = true; PrintAndLogEx(NORMAL, "\n[-] Chunk [%d/%d]: %.1fs [%s] found key %s (index %u)" - , i + , key_offset , keycnt , (float)(t2 / 1000.0) , (use_credit_key) ? "credit" : "debit" - , sprint_hex(keyBlock + (i + found) * 8, 8) - , found + , sprint_hex(keyBlock + (key_offset + found_offset) * 8, 8) + , found_offset ); break; } case 0: { PrintAndLogEx(NORMAL, "\n[-] Chunk [%d/%d] : %.1fs [%s]" - , i + , key_offset , keycnt , (float)(t2 / 1000.0) , (use_credit_key) ? "credit" : "debit" @@ -2174,8 +2183,22 @@ out: t1 = msclock() - t1; PrintAndLogEx(SUCCESS, "\nTime in iclass checkkeys: %.0f seconds\n", (float)t1 / 1000.0); - DropField(); + + // add to managekeys + if ( found_debit ) { + for (uint8_t i=0; i< ICLASS_KEYS_MAX; i++) { + // simple check for preexistences + if ( memcmp(iClass_Key_Table[i], keyBlock + (key_offset + found_offset) * 8, 8) == 0 ) break; + + if ( memcmp(iClass_Key_Table[i], "\x00\x00\x00\x00\x00\x00\x00\x00", 8) == 0 ) { + memcpy(iClass_Key_Table[i], keyBlock + (key_offset + found_offset) * 8, 8); + PrintAndLogEx(SUCCESS, "Added found key to keyslot [%d] - "_YELLOW_("`hf iclass managekeys p`")" to view", i); + break; + } + } + } + free(pre); free(keyBlock); return PM3_SUCCESS; @@ -2322,11 +2345,25 @@ static int CmdHFiClassLookUp(const char *Cmd) { // binsearch item = (iclass_prekey_t *) bsearch(&lookup, prekey, keycnt, sizeof(iclass_prekey_t), cmp_uint32); - if (item != NULL) - PrintAndLogEx(SUCCESS, "\n[debit] found key %s", sprint_hex(item->key, 8)); t1 = msclock() - t1; PrintAndLogEx(NORMAL, "\nTime in iclass : %.0f seconds\n", (float)t1 / 1000.0); + + // foudn + if (item != NULL) { + PrintAndLogEx(SUCCESS, "\n[debit] found key %s", sprint_hex(item->key, 8)); + for (uint8_t i=0; i< ICLASS_KEYS_MAX; i++) { + // simple check for preexistences + if ( memcmp(item->key, iClass_Key_Table[i], 8) == 0 ) break; + + if ( memcmp(iClass_Key_Table[i] , "\x00\x00\x00\x00\x00\x00\x00\x00", 8) == 0 ) { + memcpy(iClass_Key_Table[i], item->key, 8); + PrintAndLogEx(SUCCESS, "Added found key to keyslot [%d] - "_YELLOW_("`hf iclass managekeys p`")"to view", i); + break; + } + } + } + free(prekey); free(keyBlock); PrintAndLogEx(NORMAL, ""); @@ -2379,7 +2416,7 @@ int LoadDictionaryKeyFile(char *filename, uint8_t **keys, int *keycnt) { memset(buf, 0, sizeof(buf)); } fclose(f); - PrintAndLogEx(SUCCESS, "Loaded " _GREEN_("%2d") " keys from %s", *keycnt, filename); + PrintAndLogEx(SUCCESS, "Loaded " _GREEN_("%2d") "keys from %s", *keycnt, filename); return PM3_SUCCESS; } From 7ab7d68a26d3b31d72b33a04e58793f27f2ac94d Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 24 Aug 2019 07:15:21 +0200 Subject: [PATCH 0429/1854] calloc in fileutils --- client/fileutils.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/fileutils.c b/client/fileutils.c index 52fd1539f..31e48601d 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -669,7 +669,7 @@ int searchAndList(const char *pm3dir, const char *ext) { char *searchFile(const char *pm3dir, const char *searchname) { // explicit absolute (/) or relative path (./) => try only to match it directly - char *filename = malloc(strlen(searchname) + 1); + char *filename = calloc(strlen(searchname) + 1, sizeof(char)); if (filename == NULL) return NULL; strcpy(filename, searchname); if (((strlen(filename) > 1) && (filename[0] == '/')) || @@ -690,7 +690,7 @@ char *searchFile(const char *pm3dir, const char *searchname) { // try pm3 dirs in current workdir (dev mode) const char *exec_path = get_my_executable_directory(); if (exec_path != NULL) { - char *path = malloc(strlen(exec_path) + strlen(pm3dir) + strlen(filename) + 1); + char *path = calloc(strlen(exec_path) + strlen(pm3dir) + strlen(filename) + 1, sizeof(char)); if (path == NULL) goto out; strcpy(path, exec_path); @@ -706,7 +706,7 @@ char *searchFile(const char *pm3dir, const char *searchname) { // try pm3 dirs in user .proxmark3 (user mode) char *user_path = getenv("HOME"); if (user_path != NULL) { - char *path = malloc(strlen(user_path) + strlen(PM3_USER_DIRECTORY) + strlen(pm3dir) + strlen(filename) + 1); + char *path = calloc(strlen(user_path) + strlen(PM3_USER_DIRECTORY) + strlen(pm3dir) + strlen(filename) + 1, sizeof(char)); if (path == NULL) goto out; strcpy(path, user_path); @@ -722,7 +722,7 @@ char *searchFile(const char *pm3dir, const char *searchname) { } // try pm3 dirs in pm3 installation dir (install mode) { - char *path = malloc(strlen(PM3_SHARE_PATH) + strlen(pm3dir) + strlen(filename) + 1); + char *path = calloc(strlen(PM3_SHARE_PATH) + strlen(pm3dir) + strlen(filename) + 1, sizeof(char)); if (path == NULL) goto out; strcpy(path, PM3_SHARE_PATH); From ec174a72328efa7beeef03a85543fdff7cdacc26 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 24 Aug 2019 07:51:24 +0200 Subject: [PATCH 0430/1854] better searchFile api --- client/cmdscript.c | 13 ++++------- client/fileutils.c | 58 ++++++++++++++++++++++++++++++---------------- client/fileutils.h | 3 +-- 3 files changed, 43 insertions(+), 31 deletions(-) diff --git a/client/cmdscript.c b/client/cmdscript.c index 37778d52e..318cc1dd4 100644 --- a/client/cmdscript.c +++ b/client/cmdscript.c @@ -66,16 +66,11 @@ static int CmdScriptRun(const char *Cmd) { int arg_len = 0; sscanf(Cmd, "%127s%n %255[^\n\r]%n", preferredName, &name_len, arguments, &arg_len); - char *script_name = filenamemcopy(preferredName, ".lua"); - if (script_name == NULL) return PM3_EMALLOC; - char *script_path = searchFile(LUA_SCRIPTS_SUBDIR, script_name); + char *script_path; + int res = searchFile(&script_path, LUA_SCRIPTS_SUBDIR, preferredName, ".lua"); + if (res != PM3_SUCCESS) + return res; - if (script_path == NULL) { - PrintAndLogEx(FAILED, "Error - can't find script %s", script_name); - free(script_name); - return PM3_EFILE; - } - free(script_name); int error; PrintAndLogEx(SUCCESS, "Executing: %s, args '%s'\n", script_path, arguments); error = luaL_loadfile(lua_state, script_path); diff --git a/client/fileutils.c b/client/fileutils.c index 31e48601d..622bb88de 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -69,7 +69,7 @@ int fileExists(const char *filename) { return result == 0; } -char *filenamemcopy(const char *preferredName, const char *suffix) { +static char *filenamemcopy(const char *preferredName, const char *suffix) { if (preferredName == NULL) return NULL; if (suffix == NULL) return NULL; char *fileName = (char *) calloc(strlen(preferredName) + strlen(suffix) + 1, sizeof(uint8_t)); @@ -522,15 +522,10 @@ out: int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, uint8_t keylen, uint16_t *keycnt) { if (data == NULL) return PM3_ESOFT; - char *fileName = filenamemcopy(preferredName, ".dic"); - if (fileName == NULL) return PM3_EMALLOC; - char *path = searchFile(DICTIONARIES_SUBDIR, fileName); - if (path == NULL) { - PrintAndLogEx(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", fileName); - free(fileName); + char *path; + if (searchFile(&path, DICTIONARIES_SUBDIR, preferredName, ".dic") != PM3_SUCCESS) return PM3_EFILE; - } - free(fileName); + // t5577 == 4bytes // mifare == 6 bytes // iclass == 8 bytes @@ -667,25 +662,31 @@ int searchAndList(const char *pm3dir, const char *ext) { return PM3_SUCCESS; } -char *searchFile(const char *pm3dir, const char *searchname) { +static int searchFinalFile(char **foundpath, const char *pm3dir, const char *searchname) { + if ((foundpath == NULL)||(pm3dir == NULL)||(searchname == NULL)) return PM3_ESOFT; // explicit absolute (/) or relative path (./) => try only to match it directly char *filename = calloc(strlen(searchname) + 1, sizeof(char)); - if (filename == NULL) return NULL; + if (filename == NULL) return PM3_EMALLOC; strcpy(filename, searchname); if (((strlen(filename) > 1) && (filename[0] == '/')) || ((strlen(filename) > 2) && (filename[0] == '.') && (filename[1] == '/'))) { - if (fileExists(filename)) - return filename; - else + if (fileExists(filename)) { + *foundpath = filename; + return PM3_SUCCESS; + } + else { goto out; + } } // else // try implicit relative path { - if (fileExists(filename)) - return filename; + if (fileExists(filename)) { + *foundpath = filename; + return PM3_SUCCESS; + } } // try pm3 dirs in current workdir (dev mode) const char *exec_path = get_my_executable_directory(); @@ -698,7 +699,8 @@ char *searchFile(const char *pm3dir, const char *searchname) { strcat(path, filename); if (fileExists(path)) { free(filename); - return path; + *foundpath = path; + return PM3_SUCCESS; } else { free(path); } @@ -715,7 +717,8 @@ char *searchFile(const char *pm3dir, const char *searchname) { strcat(path, filename); if (fileExists(path)) { free(filename); - return path; + *foundpath = path; + return PM3_SUCCESS; } else { free(path); } @@ -730,12 +733,27 @@ char *searchFile(const char *pm3dir, const char *searchname) { strcat(path, filename); if (fileExists(path)) { free(filename); - return path; + *foundpath = path; + return PM3_SUCCESS; } else { free(path); } } out: free(filename); - return NULL; + return PM3_EFILE; +} + +int searchFile(char **foundpath, const char *pm3dir, const char *searchname, const char *suffix) { + char *filename = filenamemcopy(searchname, suffix); + if (filename == NULL) return PM3_EMALLOC; + int res = searchFinalFile(foundpath, pm3dir, filename); + if (res != PM3_SUCCESS) { + if (res == PM3_EFILE) + PrintAndLogEx(FAILED, "Error - can't find %s", filename); + free(filename); + return res; + } + free(filename); + return PM3_SUCCESS; } diff --git a/client/fileutils.h b/client/fileutils.h index bb229efb5..1e912a899 100644 --- a/client/fileutils.h +++ b/client/fileutils.h @@ -160,8 +160,7 @@ int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, u */ int convertOldMfuDump(uint8_t **dump, size_t *dumplen); -char *filenamemcopy(const char *preferredName, const char *suffix); int searchAndList(const char *pm3dir, const char *ext); -char *searchFile(const char *pm3dir, const char *searchname); +int searchFile(char **foundpath, const char *pm3dir, const char *searchname, const char *suffix); #endif // FILEUTILS_H From f9d8d56317a455b55fe994533458fa1d80e41caa Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 24 Aug 2019 13:16:28 +0200 Subject: [PATCH 0431/1854] add iclass json dump format --- client/fileutils.c | 34 ++++++++++++++++++++++++++++++++++ client/fileutils.h | 1 + 2 files changed, 35 insertions(+) diff --git a/client/fileutils.c b/client/fileutils.c index 622bb88de..83744cc6f 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -281,6 +281,19 @@ int saveFileJSON(const char *preferredName, JSONFileType ftype, uint8_t *data, s } break; } + case jsfIclass: { + JsonSaveStr(root, "FileType", "iclass"); + uint8_t uid[8] = {0}; + memcpy(uid, data, 8); + JsonSaveBufAsHexCompact(root, "$.Card.UID", uid, sizeof(uid)); + + for (size_t i = 0; i < (datalen / 8 ); i++) { + char path[PATH_MAX_LENGTH] = {0}; + sprintf(path, "$blocks.%zu", i); + JsonSaveBufAsHexCompact(root, path, data + (i * 8), 8); + } + break; + } } int res = json_dump_file(root, fileName, JSON_INDENT(2)); @@ -512,6 +525,27 @@ int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_ *datalen = sptr; } + if (!strcmp(ctype, "iclass")) { + size_t sptr = 0; + for (size_t i = 0; i < (maxdatalen / 8); i++) { + if (sptr + 8 > maxdatalen) { + retval = 5; + goto out; + } + + char path[30] = {0}; + sprintf(path, "$.blocks.%zu", i); + + size_t len = 0; + JsonLoadBufAsHex(root, path, &udata[sptr], 8, &len); + if (!len) + break; + + sptr += len; + } + *datalen = sptr; + } + PrintAndLogEx(SUCCESS, "loaded from JSON file " _YELLOW_("%s"), fileName); out: json_decref(root); diff --git a/client/fileutils.h b/client/fileutils.h index 1e912a899..d23472867 100644 --- a/client/fileutils.h +++ b/client/fileutils.h @@ -54,6 +54,7 @@ typedef enum { jsfCardMemory, jsfMfuMemory, jsfHitag, + jsfIclass, // jsf14b, // jsf15, // jsfLegic, From 7dbb5427eaf0b92d49be89ffed341d4fb5f46324 Mon Sep 17 00:00:00 2001 From: Matthias Konrath Date: Sat, 24 Aug 2019 18:11:03 +0200 Subject: [PATCH 0432/1854] Transformation from hardautopwn to autopwn, now are all the mifare classic attacks automated. --- client/cmdhfmf.c | 397 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 271 insertions(+), 126 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index e968548b6..460089151 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -166,20 +166,24 @@ static int usage_hf14_hardnested(void) { PrintAndLogEx(NORMAL, " hf mf hardnested 0 A A0A1A2A3A4A5 4 A FFFFFFFFFFFF"); return 0; } -static int usage_hf14_hardautopwn(void) { +static int usage_hf14_autopwn(void) { PrintAndLogEx(NORMAL, "Usage:"); - PrintAndLogEx(NORMAL, " hf mf hardautopwn [k] "); - PrintAndLogEx(NORMAL, " * [d] [f] [s] [i] [l]"); + PrintAndLogEx(NORMAL, " hf mf autopwn [k] "); + PrintAndLogEx(NORMAL, " [*] [f] .dic [s] [i] [l]"); PrintAndLogEx(NORMAL, " (card memory - 0 - MINI(320 bytes), 1 - 1K, 2 - 2K, 4 - 4K, - 1K)"); PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Description:"); + PrintAndLogEx(NORMAL, " This command is used to automate the attack process on mifare classic nfc cards."); + PrintAndLogEx(NORMAL, " The program tries to identify the prng type and then automatically attack it with the best algorithm."); + PrintAndLogEx(NORMAL, " If all the sector keys are broken, they will be dumped to a file."); + PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h this help"); PrintAndLogEx(NORMAL, " k if a known key for a block is supplied"); - PrintAndLogEx(NORMAL, " d write keys to binary file"); PrintAndLogEx(NORMAL, " f .dic dictionary file for key discovery (the file has to end in .dic)"); - PrintAndLogEx(NORMAL, " s slower acquisition (required by some non standard cards)"); + PrintAndLogEx(NORMAL, " s slower acquisition (required by some non standard cards) for hardnested"); PrintAndLogEx(NORMAL, " l legacy mode (use the slow mfchk for the key enumeration)"); - PrintAndLogEx(NORMAL, " i set type of SIMD instructions. Without this flag programs autodetect it."); + PrintAndLogEx(NORMAL, " i set type of SIMD instructions. Without this flag programs autodetect it. (for hardnested)"); PrintAndLogEx(NORMAL, " i 5 = AVX512"); PrintAndLogEx(NORMAL, " i 2 = AVX2"); PrintAndLogEx(NORMAL, " i a = AVX"); @@ -188,13 +192,11 @@ static int usage_hf14_hardautopwn(void) { PrintAndLogEx(NORMAL, " i n = none (use CPU regular instruction set)"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf mf hardautopwn d"); - PrintAndLogEx(NORMAL, " hf mf hardautopwn * 1 d f default_keys"); - PrintAndLogEx(NORMAL, " hf mf hardautopwn k 0 A FFFFFFFFFFFF d"); - PrintAndLogEx(NORMAL, " hf mf hardautopwn k 0 A FFFFFFFFFFFF * 1 d f default_keys"); - PrintAndLogEx(NORMAL, " hf mf hardautopwn k 0 A FFFFFFFFFFFF * 4 s i 5"); - - PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, " hf mf autopwn"); + PrintAndLogEx(NORMAL, " hf mf autopwn * 1 f default_keys"); + PrintAndLogEx(NORMAL, " hf mf autopwn k 0 A FFFFFFFFFFFF"); + PrintAndLogEx(NORMAL, " hf mf autopwn k 0 A FFFFFFFFFFFF * 1 f default_keys"); + PrintAndLogEx(NORMAL, " hf mf autopwn k 0 A FFFFFFFFFFFF * 4 i 5"); return 0; } static int usage_hf14_chk(void) { @@ -1562,58 +1564,52 @@ static int CmdHF14AMfNestedHard(const char *Cmd) { } -static int CmdHF14AMfHardAuto(const char *Cmd) { +static int CmdHF14AMfAutoPWN(const char *Cmd) { + // Nested and Hardnested parameter uint8_t blockNo = 0; uint8_t keyType = 0; - uint8_t *keyBlock; - uint8_t sectorsCnt = MIFARE_1K_MAXSECTOR; - sector_t *e_sector; uint8_t key[6] = {0}; - uint8_t tmpKey[6] = {0}; uint64_t key64 = 0; + // Attack key storage variables + uint8_t *keyBlock; uint16_t keycnt = 0; + sector_t *e_sector; + uint8_t sectorsCnt = MIFARE_1K_MAXSECTOR; + uint8_t tmpKey[6] = {0}; size_t datalen = 0; - uint32_t chunksize; - - uint64_t t1; // For the timier - uint8_t foundKeysDictionary = 0; - uint8_t foundKeysReused = 0; - uint8_t foundKeysHardnested = 0; - + // For the timier + uint64_t t1; + // Parameters and dictionary file char filename[FILE_PATH_SIZE] = {0}; uint8_t cmdp = 0; char ctmp; - + // Nested and Hardnested returned status uint64_t foundkey = 0; int16_t isOK = 0; - - int i, i2, i3; // Loop counter + // Loop counter + int i, i2, i3; int current_sector_i = 0, current_key_type_i = 0; - + // Settings bool slow = false; bool nonce_file_read = false; bool nonce_file_write = false; - bool createDumpFile = false; bool know_target_key = false; bool legacy_mfchk = false; - bool firstChunk = 0, lastChunk = 0; + bool prng_type = false; + bool calibrate = true; + // Parse the options given by the user ctmp = tolower(param_getchar(Cmd, 0)); - if (strlen(Cmd) < 1 || ctmp == 'h') return usage_hf14_hardautopwn(); - while ((ctmp = param_getchar(Cmd, cmdp))) { switch (tolower(ctmp)) { case 'h': - return usage_hf14_hardautopwn(); + return usage_hf14_autopwn(); case 'f': if (param_getstr(Cmd, cmdp +1, filename, FILE_PATH_SIZE) >= FILE_PATH_SIZE) { PrintAndLogEx(FAILED, "Filename too long"); } cmdp ++; break; - case 'd': - createDumpFile = true; - break; case 'l': legacy_mfchk = true; break; @@ -1684,20 +1680,6 @@ static int CmdHF14AMfHardAuto(const char *Cmd) { cmdp++; } - // Print parameters - PrintAndLogEx(NORMAL, "Used Parameters:"); - PrintAndLogEx(SUCCESS, "Dumping the found keys: %s", createDumpFile ? "True" : "False"); - PrintAndLogEx(SUCCESS, "Card sectors: %d", sectorsCnt); - PrintAndLogEx(SUCCESS, "Key supplied: %s", know_target_key ? "True" : "False"); - PrintAndLogEx(SUCCESS, "Known sector: %d", blockNo); - PrintAndLogEx(SUCCESS, "Keytype: %c", keyType ? 'B' : 'A'); - PrintAndLogEx(SUCCESS, "Kown key: 0x%02x%02x%02x%02x%02x%02x", key[0], key[1], key[2], key[3], key[4], key[5]); - PrintAndLogEx(SUCCESS, "Dictionary: %s", filename); - PrintAndLogEx(SUCCESS, "Legacy mode (mfchk): %s", legacy_mfchk ? "True" : "False"); - PrintAndLogEx(WARNING, "Starting attack!"); - if (know_target_key == false) - PrintAndLogEx(WARNING, "No known key was supplied, if no usable key is found in the dictionary, then this attack will fail!"); - // Create the key storage stucture e_sector = calloc(sectorsCnt, sizeof(sector_t)); if (e_sector == NULL) return PM3_EMALLOC; @@ -1709,9 +1691,74 @@ static int CmdHF14AMfHardAuto(const char *Cmd) { } } + // Get the card prng type (weak=true / hard=false) + prng_type = detect_classic_prng(); + + // Print operating parameters + PrintAndLogEx(SUCCESS, "[ SETTINGS ] Card sectors .. " _YELLOW_("%d"), sectorsCnt); + PrintAndLogEx(SUCCESS, "[ SETTINGS ] Key supplied .. " _YELLOW_("%s"), know_target_key ? "True" : "False"); + PrintAndLogEx(SUCCESS, "[ SETTINGS ] Known sector .. " _YELLOW_("%d"), blockNo); + PrintAndLogEx(SUCCESS, "[ SETTINGS ] Keytype ....... " _YELLOW_("%c"), keyType ? 'B' : 'A'); + PrintAndLogEx(SUCCESS, "[ SETTINGS ] Kown key ...... " _YELLOW_("0x%02x%02x%02x%02x%02x%02x"), key[0], key[1], key[2], key[3], key[4], key[5]); + PrintAndLogEx(SUCCESS, "[ SETTINGS ] Card PRNG ..... " _YELLOW_("%s"), prng_type ? "WEAK" : "HARD"); + PrintAndLogEx(SUCCESS, "[ SETTINGS ] Dictionary .... " _YELLOW_("%s"), strlen(filename) ? filename : "NONE"); + PrintAndLogEx(SUCCESS, "[ SETTINGS ] Legacy mode ... " _YELLOW_("%s"), legacy_mfchk ? "True" : "False"); + PrintAndLogEx(WARNING, "Starting attack!"); + + // Check the user supplied key + if (know_target_key == false) + PrintAndLogEx(WARNING, "No known key was supplied, the following attacks might fail!"); + else { + if (mfCheckKeys(FirstBlockOfSector(blockNo), keyType, true, 1, key, &key64) == PM3_SUCCESS) { + PrintAndLogEx(SUCCESS, "[ SETTINGS ] The following key will be used to the nested / hardnested attack: Sector:" + _RED_("%3d") " key type:"_RED_("%c") " key: " _RED_("0x%02x%02x%02x%02x%02x%02x"), + blockNo, + keyType ? 'B' : 'A', + key[0], key[1], key[2], key[3], key[4], key[5]); + + // Store the key for the nested / hardnested attack (if supplied by the user) + e_sector[blockNo].Key[keyType] = bytes_to_num(key, 6); + e_sector[blockNo].foundKey[keyType] = 3; + } else { + know_target_key = false; + PrintAndLogEx(FAILED, "Key is wrong. Can't authenticate to sector:"_RED_("%3d") " key type:"_RED_("%c") " key: " _RED_("0x%02x%02x%02x%02x%02x%02x"), + blockNo, + keyType ? 'B' : 'A', + key[0], key[1], key[2], key[3], key[4], key[5]); + PrintAndLogEx(WARNING, "Let's see if just the sector or keytype are not correct, and then we also give the dictionary a try ;)"); + } + // Check if the user supplied key is used by other sectors + for (i=0; i just be nice and correct it ;) + if (know_target_key == false) { + num_to_bytes(e_sector[i].Key[i2], 6, key); + know_target_key = true; + blockNo = i; keyType = i2; + PrintAndLogEx(SUCCESS, "[ SETTINGS ] The following key will be used to the nested / hardnested attack: Sector:" + _RED_("%3d") " key type:"_RED_("%c") " key: " _RED_("0x%02x%02x%02x%02x%02x%02x"), + blockNo, + keyType ? 'B' : 'A', + key[0], key[1], key[2], key[3], key[4], key[5]); + } + } + } + } + } + } + // Load the dictionary if (strlen(filename) != 0) { - keyBlock = calloc(6 * 1000, sizeof(uint8_t)); + keyBlock = calloc(6 * 2000, sizeof(uint8_t)); loadFileDICTIONARY(filename, keyBlock, &datalen, 6, &keycnt); } else { keyBlock = calloc(ARRAYLEN(g_mifare_default_keys), 6); @@ -1726,6 +1773,7 @@ static int CmdHF14AMfHardAuto(const char *Cmd) { // Start the timer t1 = msclock(); + // Use the dictionary to find sector keys on the card PrintAndLogEx(SUCCESS, "Enumerating the card keys with the dictionary!"); if (legacy_mfchk) { // Check all the sectors @@ -1735,7 +1783,7 @@ static int CmdHF14AMfHardAuto(const char *Cmd) { if (e_sector[i].foundKey[i2] == 0) { for (i3=0; i3 (PM3_CMD_DATA_SIZE / 6) ? (PM3_CMD_DATA_SIZE / 6) : keycnt; - firstChunk = true; lastChunk = false; + int chunksize = keycnt > (PM3_CMD_DATA_SIZE / 6) ? (PM3_CMD_DATA_SIZE / 6) : keycnt; + bool firstChunk = true, lastChunk = false; for (uint8_t strategy = 1; strategy < 3; strategy++) { PrintAndLogEx(SUCCESS, "Running strategy %u", strategy); // main keychunk loop @@ -1774,45 +1822,82 @@ static int CmdHF14AMfHardAuto(const char *Cmd) { } // end strategy } - // Check if at least one key was recovered + // Analyse the dictionary attack for (i=0; i The fast check --> mfCheckKeys_fast(sectorsCnt, true, true, 2, 1, tmpKey, e_sector, false); + // Returns false keys, so we just stick to the slower mfchk. for (i=0; i try hardnested instead!"); + goto tryHardnested; + break; + case -4 : //key not found + calibrate = false; + PrintAndLogEx(FAILED, "Nested attack failed --> try hardnested instead!"); + goto tryHardnested; + break; + case -5 : + calibrate = false; + e_sector[current_sector_i].Key[current_key_type_i] = bytes_to_num(tmpKey, 6); + e_sector[current_sector_i].foundKey[current_key_type_i] = 5; break; default : + PrintAndLogEx(ERR, "unknown Error.\n"); + return 1; break; } - free(e_sector); - return 2; - } + } else { + tryHardnested: // If the nested attack failes then we try the hardnested attack + PrintAndLogEx(SUCCESS, "[ HARDNESTED ] Sector no:%3d, target key type:%c, Slow: %s", + current_sector_i, + current_key_type_i ? 'B' : 'A', + slow ? "Yes" : "No"); - // Copy the found key to the tmpKey variale (for the following print statement, and the mfCheckKeys above) - num_to_bytes(foundkey, 6, tmpKey); - e_sector[current_sector_i].Key[current_key_type_i] = foundkey; - e_sector[current_sector_i].foundKey[current_key_type_i] = 1; - PrintAndLogEx(SUCCESS, "[HARDNE. KEYS] Valid KEY FOUND: sector:%3d key type:%c key: " _YELLOW_("0x%02x%02x%02x%02x%02x%02x"), - current_sector_i, - current_key_type_i ? 'B' : 'A', - tmpKey[0], tmpKey[1], tmpKey[2], tmpKey[3], tmpKey[4], tmpKey[5]); - foundKeysHardnested++; + isOK = mfnestedhard(FirstBlockOfSector(blockNo), keyType, key, FirstBlockOfSector(current_sector_i), current_key_type_i, NULL, nonce_file_read, nonce_file_write, slow, 0, &foundkey, NULL); + DropField(); + if (isOK) { + switch (isOK) { + case 1 : + PrintAndLogEx(ERR, "Error: No response from Proxmark3.\n"); + break; + case 2 : + PrintAndLogEx(NORMAL, "Button pressed. Aborted.\n"); + break; + default : + break; + } + free(e_sector); + return 2; + } + + // Copy the found key to the tmpKey variale (for the following print statement, and the mfCheckKeys above) + num_to_bytes(foundkey, 6, tmpKey); + e_sector[current_sector_i].Key[current_key_type_i] = foundkey; + e_sector[current_sector_i].foundKey[current_key_type_i] = 6; + } + // Check if the key was found + if (e_sector[current_sector_i].foundKey[current_key_type_i] != 0) { + PrintAndLogEx(SUCCESS, "[BROCKEN KEY] Valid KEY FOUND: sector:%3d key type:%c key: " _YELLOW_("0x%02x%02x%02x%02x%02x%02x"), + current_sector_i, + current_key_type_i ? 'B' : 'A', + tmpKey[0], tmpKey[1], tmpKey[2], tmpKey[3], tmpKey[4], tmpKey[5]); + } else { + PrintAndLogEx(FAILED, "[BROCKEN KEY] Valid KEY NOT FOUND: sector:%3d key type:%c key: " _YELLOW_("0x%02x%02x%02x%02x%02x%02x"), + current_sector_i, + current_key_type_i ? 'B' : 'A', + tmpKey[0], tmpKey[1], tmpKey[2], tmpKey[3], tmpKey[4], tmpKey[5]); + } } } } } + // Show the results to the user + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(SUCCESS, "Found KEYS:"); printKeyTable(sectorsCnt, e_sector); - // Create a dumpfile - if (createDumpFile) { - PrintAndLogEx(SUCCESS, "\nDumping the found keys:"); - createKeyDump(sectorsCnt, e_sector, GenerateFilename("hf-mf-", "-key.bin")); - } + PrintAndLogEx(SUCCESS, "[ INFO ] Key res types:"); + PrintAndLogEx(SUCCESS, " 1: Dictionary"); + PrintAndLogEx(SUCCESS, " 2: Darkside attack"); + PrintAndLogEx(SUCCESS, " 3: User supplied"); + PrintAndLogEx(SUCCESS, " 4: Reused"); + PrintAndLogEx(SUCCESS, " 5: Nested"); + PrintAndLogEx(SUCCESS, " 6: Hardnested"); + // Generate and show statistics t1 = msclock() - t1; - PrintAndLogEx(SUCCESS, "Keys statistics (total: %d):" - "\n\t(*) Broken with hardnested attack: " _MAGENTA_("%d") - "\n\t(*) Reused keys: " _YELLOW_("%d") - "\n\t(*) Discovered with the dictionary: " _YELLOW_("%d") - , sectorsCnt*2, foundKeysHardnested, foundKeysReused, foundKeysDictionary); - PrintAndLogEx(SUCCESS, "Required time for the hardautopwn attack: " _YELLOW_("%.0f") " seconds\n", (float)t1 / 1000.0); + PrintAndLogEx(SUCCESS, "Required time for the autopwn attack: " _YELLOW_("%.0f") " seconds", (float)t1 / 1000.0); + + // Create a dumpfile if all keys are known + for (current_sector_i=0; current_sector_i < sectorsCnt; current_sector_i++) { + for (current_key_type_i=0; current_key_type_i < 2; current_key_type_i++) { + // If the key is already known, just skip it + if (e_sector[current_sector_i].foundKey[current_key_type_i] == 0) { + PrintAndLogEx(FAILED, "Not all keys were discovered --> no dump file will be created!"); + goto notAllKeysFound; + } + } + } + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(SUCCESS, "All keys were discovered, dumping them now:"); + createKeyDump(sectorsCnt, e_sector, GenerateFilename("hf-mf-", "-key.bin")); + notAllKeysFound: free(e_sector); - free(keyBlock); return 0; } @@ -3987,7 +4132,7 @@ static command_t CommandTable[] = { {"darkside", CmdHF14AMfDarkside, IfPm3Iso14443a, "Darkside attack. read parity error messages."}, {"nested", CmdHF14AMfNested, IfPm3Iso14443a, "Nested attack. Test nested authentication"}, {"hardnested", CmdHF14AMfNestedHard, AlwaysAvailable, "Nested attack for hardened Mifare cards"}, - {"hardautopwn", CmdHF14AMfHardAuto, AlwaysAvailable, "Nested attack for hardened Mifare cards that breaks all sector keys autmatically"}, + {"autopwn", CmdHF14AMfAutoPWN, AlwaysAvailable, "Automatic attack tool, to extrackt the nfc keys (with dicrionaries, nested and hardnested attacks)"}, {"keybrute", CmdHF14AMfKeyBrute, IfPm3Iso14443a, "J_Run's 2nd phase of multiple sector nested authentication key recovery"}, {"nack", CmdHf14AMfNack, IfPm3Iso14443a, "Test for Mifare NACK bug"}, {"chk", CmdHF14AMfChk, IfPm3Iso14443a, "Check keys"}, From bd01b7bd96859abf5b9f6035e0a81ff1ba407af3 Mon Sep 17 00:00:00 2001 From: Matthias Konrath Date: Sun, 25 Aug 2019 11:13:53 +0200 Subject: [PATCH 0433/1854] Now the keys are transfered to the simulator memory and the whole card gets dumped at the end. --- client/cmdhfmf.c | 111 ++++++++++++++++++++++++++++++----------------- 1 file changed, 72 insertions(+), 39 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 460089151..473d4b297 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -169,13 +169,13 @@ static int usage_hf14_hardnested(void) { static int usage_hf14_autopwn(void) { PrintAndLogEx(NORMAL, "Usage:"); PrintAndLogEx(NORMAL, " hf mf autopwn [k] "); - PrintAndLogEx(NORMAL, " [*] [f] .dic [s] [i] [l]"); + PrintAndLogEx(NORMAL, " [*] [f] .dic [s] [i] [l] [t] [d]"); PrintAndLogEx(NORMAL, " (card memory - 0 - MINI(320 bytes), 1 - 1K, 2 - 2K, 4 - 4K, - 1K)"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Description:"); PrintAndLogEx(NORMAL, " This command is used to automate the attack process on mifare classic nfc cards."); PrintAndLogEx(NORMAL, " The program tries to identify the prng type and then automatically attack it with the best algorithm."); - PrintAndLogEx(NORMAL, " If all the sector keys are broken, they will be dumped to a file."); + PrintAndLogEx(NORMAL, " After the program is done, the keys and card data is dumped."); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h this help"); @@ -1575,6 +1575,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { uint16_t keycnt = 0; sector_t *e_sector; uint8_t sectorsCnt = MIFARE_1K_MAXSECTOR; + int blockCnt = MIFARE_1K_MAXBLOCK; uint8_t tmpKey[6] = {0}; size_t datalen = 0; // For the timier @@ -1589,6 +1590,11 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { // Loop counter int i, i2, i3; int current_sector_i = 0, current_key_type_i = 0; + // Dumping and transfere to simulater memory + uint8_t block[16] = {0x00}; + uint8_t *dump; + int bytes; + char* fnameptr = filename; // Settings bool slow = false; bool nonce_file_read = false; @@ -1616,6 +1622,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { case '*': // Get the number of sectors sectorsCnt = NumOfSectors(param_getchar(Cmd, cmdp + 1)); + blockCnt = NumOfBlocks(param_getchar(Cmd, cmdp + 1)); cmdp ++; break; case 'k': @@ -1695,14 +1702,14 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { prng_type = detect_classic_prng(); // Print operating parameters - PrintAndLogEx(SUCCESS, "[ SETTINGS ] Card sectors .. " _YELLOW_("%d"), sectorsCnt); - PrintAndLogEx(SUCCESS, "[ SETTINGS ] Key supplied .. " _YELLOW_("%s"), know_target_key ? "True" : "False"); - PrintAndLogEx(SUCCESS, "[ SETTINGS ] Known sector .. " _YELLOW_("%d"), blockNo); - PrintAndLogEx(SUCCESS, "[ SETTINGS ] Keytype ....... " _YELLOW_("%c"), keyType ? 'B' : 'A'); - PrintAndLogEx(SUCCESS, "[ SETTINGS ] Kown key ...... " _YELLOW_("0x%02x%02x%02x%02x%02x%02x"), key[0], key[1], key[2], key[3], key[4], key[5]); - PrintAndLogEx(SUCCESS, "[ SETTINGS ] Card PRNG ..... " _YELLOW_("%s"), prng_type ? "WEAK" : "HARD"); - PrintAndLogEx(SUCCESS, "[ SETTINGS ] Dictionary .... " _YELLOW_("%s"), strlen(filename) ? filename : "NONE"); - PrintAndLogEx(SUCCESS, "[ SETTINGS ] Legacy mode ... " _YELLOW_("%s"), legacy_mfchk ? "True" : "False"); + PrintAndLogEx(INFO, "[ SETTINGS ] Card sectors .. " _YELLOW_("%d"), sectorsCnt); + PrintAndLogEx(INFO, "[ SETTINGS ] Key supplied .. " _YELLOW_("%s"), know_target_key ? "True" : "False"); + PrintAndLogEx(INFO, "[ SETTINGS ] Known sector .. " _YELLOW_("%d"), blockNo); + PrintAndLogEx(INFO, "[ SETTINGS ] Keytype ....... " _YELLOW_("%c"), keyType ? 'B' : 'A'); + PrintAndLogEx(INFO, "[ SETTINGS ] Kown key ...... " _YELLOW_("0x%02x%02x%02x%02x%02x%02x"), key[0], key[1], key[2], key[3], key[4], key[5]); + PrintAndLogEx(INFO, "[ SETTINGS ] Card PRNG ..... " _YELLOW_("%s"), prng_type ? "WEAK" : "HARD"); + PrintAndLogEx(INFO, "[ SETTINGS ] Dictionary .... " _YELLOW_("%s"), strlen(filename) ? filename : "NONE"); + PrintAndLogEx(INFO, "[ SETTINGS ] Legacy mode ... " _YELLOW_("%s"), legacy_mfchk ? "True" : "False"); PrintAndLogEx(WARNING, "Starting attack!"); // Check the user supplied key @@ -1710,7 +1717,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { PrintAndLogEx(WARNING, "No known key was supplied, the following attacks might fail!"); else { if (mfCheckKeys(FirstBlockOfSector(blockNo), keyType, true, 1, key, &key64) == PM3_SUCCESS) { - PrintAndLogEx(SUCCESS, "[ SETTINGS ] The following key will be used to the nested / hardnested attack: Sector:" + PrintAndLogEx(INFO, "[ SETTINGS ] The following key will be used to the nested / hardnested attack: Sector:" _RED_("%3d") " key type:"_RED_("%c") " key: " _RED_("0x%02x%02x%02x%02x%02x%02x"), blockNo, keyType ? 'B' : 'A', @@ -1774,7 +1781,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { t1 = msclock(); // Use the dictionary to find sector keys on the card - PrintAndLogEx(SUCCESS, "Enumerating the card keys with the dictionary!"); + PrintAndLogEx(INFO, "Enumerating the card keys with the dictionary!"); if (legacy_mfchk) { // Check all the sectors for (i=0; i (PM3_CMD_DATA_SIZE / 6) ? (PM3_CMD_DATA_SIZE / 6) : keycnt; bool firstChunk = true, lastChunk = false; for (uint8_t strategy = 1; strategy < 3; strategy++) { - PrintAndLogEx(SUCCESS, "Running strategy %u", strategy); + PrintAndLogEx(INFO, "Running strategy %u", strategy); // main keychunk loop for (i = 0; i < keycnt; i += chunksize) { @@ -1851,7 +1858,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { if (know_target_key == false) { // Check if the darkside attack can be used if (prng_type) { - PrintAndLogEx(WARNING, "No key was found ... time to go to the dark side ;)"); + PrintAndLogEx(INFO, "No key was found ... time to go to the dark side ;)"); int isOK = mfDarkside(FirstBlockOfSector(blockNo), keyType, &key64); switch (isOK) { case -1 : @@ -1933,7 +1940,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { // Use the nested / hardnested attack if (e_sector[current_sector_i].foundKey[current_key_type_i] == 0) { if (prng_type) { - PrintAndLogEx(SUCCESS, "[ NESTED ] Sector no:%3d, target key type:%c", + PrintAndLogEx(INFO, "[ NESTED ] Sector no:%3d, target key type:%c", current_sector_i, current_key_type_i ? 'B' : 'A'); @@ -1969,7 +1976,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { } } else { tryHardnested: // If the nested attack failes then we try the hardnested attack - PrintAndLogEx(SUCCESS, "[ HARDNESTED ] Sector no:%3d, target key type:%c, Slow: %s", + PrintAndLogEx(INFO, "[ HARDNESTED ] Sector no:%3d, target key type:%c, Slow: %s", current_sector_i, current_key_type_i ? 'B' : 'A', slow ? "Yes" : "No"); @@ -1998,12 +2005,12 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { } // Check if the key was found if (e_sector[current_sector_i].foundKey[current_key_type_i] != 0) { - PrintAndLogEx(SUCCESS, "[BROCKEN KEY] Valid KEY FOUND: sector:%3d key type:%c key: " _YELLOW_("0x%02x%02x%02x%02x%02x%02x"), + PrintAndLogEx(SUCCESS, "[BROCKEN KEY] Valid KEY FOUND: sector:%3d key type:%c key: " _YELLOW_("0x%02x%02x%02x%02x%02x%02x"), current_sector_i, current_key_type_i ? 'B' : 'A', tmpKey[0], tmpKey[1], tmpKey[2], tmpKey[3], tmpKey[4], tmpKey[5]); } else { - PrintAndLogEx(FAILED, "[BROCKEN KEY] Valid KEY NOT FOUND: sector:%3d key type:%c key: " _YELLOW_("0x%02x%02x%02x%02x%02x%02x"), + PrintAndLogEx(FAILED, "[BROCKEN KEY] Valid KEY NOT FOUND: sector:%3d key type:%c key: " _YELLOW_("0x%02x%02x%02x%02x%02x%02x"), current_sector_i, current_key_type_i ? 'B' : 'A', tmpKey[0], tmpKey[1], tmpKey[2], tmpKey[3], tmpKey[4], tmpKey[5]); @@ -2015,35 +2022,61 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { // Show the results to the user PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(SUCCESS, "Found KEYS:"); + PrintAndLogEx(INFO, "Found KEYS:"); printKeyTable(sectorsCnt, e_sector); - PrintAndLogEx(SUCCESS, "[ INFO ] Key res types:"); - PrintAndLogEx(SUCCESS, " 1: Dictionary"); - PrintAndLogEx(SUCCESS, " 2: Darkside attack"); - PrintAndLogEx(SUCCESS, " 3: User supplied"); - PrintAndLogEx(SUCCESS, " 4: Reused"); - PrintAndLogEx(SUCCESS, " 5: Nested"); - PrintAndLogEx(SUCCESS, " 6: Hardnested"); + PrintAndLogEx(INFO, "[ INFO ] Key res types:"); + PrintAndLogEx(INFO, " 1: Dictionary"); + PrintAndLogEx(INFO, " 2: Darkside attack"); + PrintAndLogEx(INFO, " 3: User supplied"); + PrintAndLogEx(INFO, " 4: Reused"); + PrintAndLogEx(INFO, " 5: Nested"); + PrintAndLogEx(INFO, " 6: Hardnested"); // Generate and show statistics t1 = msclock() - t1; - PrintAndLogEx(SUCCESS, "Required time for the autopwn attack: " _YELLOW_("%.0f") " seconds", (float)t1 / 1000.0); + PrintAndLogEx(INFO, "Required time for the autopwn attack: " _YELLOW_("%.0f") " seconds", (float)t1 / 1000.0); - // Create a dumpfile if all keys are known - for (current_sector_i=0; current_sector_i < sectorsCnt; current_sector_i++) { - for (current_key_type_i=0; current_key_type_i < 2; current_key_type_i++) { - // If the key is already known, just skip it - if (e_sector[current_sector_i].foundKey[current_key_type_i] == 0) { - PrintAndLogEx(FAILED, "Not all keys were discovered --> no dump file will be created!"); - goto notAllKeysFound; - } - } - } + // Transfere the found keys to the simulator and dump the keys and card data PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(SUCCESS, "All keys were discovered, dumping them now:"); + PrintAndLogEx(INFO, "Dumping the keys:"); createKeyDump(sectorsCnt, e_sector, GenerateFilename("hf-mf-", "-key.bin")); - notAllKeysFound: + PrintAndLogEx(SUCCESS, "Transfering the found keys to the simulator memory"); + for (current_sector_i=0; current_sector_i < sectorsCnt; current_sector_i++) { + mfEmlGetMem(block, current_sector_i, 1); + if (e_sector[current_sector_i].foundKey[0]) + num_to_bytes(e_sector[current_sector_i].Key[0], 6, block); + if (e_sector[current_sector_i].foundKey[1]) + num_to_bytes(e_sector[current_sector_i].Key[1], 6, block + 10); + mfEmlSetMem(block, FirstBlockOfSector(current_sector_i) + NumBlocksPerSector(current_sector_i) - 1, 1); + } + + clearCommandBuffer(); + SendCommandMIX(CMD_HF_MIFARE_EML_LOAD, sectorsCnt, 0, 0, NULL, 0); + + bytes = blockCnt * MFBLOCK_SIZE; + dump = calloc(bytes, sizeof(uint8_t)); + if (!dump) { + PrintAndLogEx(WARNING, "Fail, cannot allocate memory"); + return PM3_EMALLOC; + } + memset(dump, 0, bytes); + + PrintAndLogEx(INFO, "Downloading the card content from emulator memory"); + if (!GetFromDevice(BIG_BUF_EML, dump, bytes, 0, NULL, 0, NULL, 2500, false)) { + PrintAndLogEx(WARNING, "Fail, transfer from device time-out"); + free(dump); + return PM3_ETIMEOUT; + } + + fnameptr += sprintf(fnameptr, "hf-mf-"); + FillFileNameByUID(fnameptr, dump, "-dump", 4); + + saveFile(filename, ".bin", dump, bytes); + saveFileEML(filename, dump, bytes, MFBLOCK_SIZE); + saveFileJSON(filename, jsfCardMemory, dump, bytes); + free(dump); + free(e_sector); return 0; } From 47b2c5ddc62b28ef366843fc5cb3d0b0e127f2c8 Mon Sep 17 00:00:00 2001 From: Matthias Konrath Date: Sun, 25 Aug 2019 11:16:10 +0200 Subject: [PATCH 0434/1854] Removed old command options. --- client/cmdhfmf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 473d4b297..067cdb212 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -169,7 +169,7 @@ static int usage_hf14_hardnested(void) { static int usage_hf14_autopwn(void) { PrintAndLogEx(NORMAL, "Usage:"); PrintAndLogEx(NORMAL, " hf mf autopwn [k] "); - PrintAndLogEx(NORMAL, " [*] [f] .dic [s] [i] [l] [t] [d]"); + PrintAndLogEx(NORMAL, " [*] [f] .dic [s] [i] [l]"); PrintAndLogEx(NORMAL, " (card memory - 0 - MINI(320 bytes), 1 - 1K, 2 - 2K, 4 - 4K, - 1K)"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Description:"); From 13641771baefae4b0cb8b176dcdcbe1549b4279c Mon Sep 17 00:00:00 2001 From: Matthias Konrath Date: Sun, 25 Aug 2019 22:24:52 +0200 Subject: [PATCH 0435/1854] Improved help message, implementation of a verbose option (to reduce the output), corrected some spelling mistakes and cleaned up variable names. --- client/cmdhfmf.c | 206 ++++++++++++++++++++++++++--------------------- 1 file changed, 112 insertions(+), 94 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 067cdb212..4cd1a02a7 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -169,8 +169,7 @@ static int usage_hf14_hardnested(void) { static int usage_hf14_autopwn(void) { PrintAndLogEx(NORMAL, "Usage:"); PrintAndLogEx(NORMAL, " hf mf autopwn [k] "); - PrintAndLogEx(NORMAL, " [*] [f] .dic [s] [i] [l]"); - PrintAndLogEx(NORMAL, " (card memory - 0 - MINI(320 bytes), 1 - 1K, 2 - 2K, 4 - 4K, - 1K)"); + PrintAndLogEx(NORMAL, " [*] [f] .dic [s] [i] [l] [v]"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Description:"); PrintAndLogEx(NORMAL, " This command is used to automate the attack process on mifare classic nfc cards."); @@ -182,7 +181,13 @@ static int usage_hf14_autopwn(void) { PrintAndLogEx(NORMAL, " k if a known key for a block is supplied"); PrintAndLogEx(NORMAL, " f .dic dictionary file for key discovery (the file has to end in .dic)"); PrintAndLogEx(NORMAL, " s slower acquisition (required by some non standard cards) for hardnested"); + PrintAndLogEx(NORMAL, " v verbose output (statistcs)"); PrintAndLogEx(NORMAL, " l legacy mode (use the slow mfchk for the key enumeration)"); + PrintAndLogEx(NORMAL, " * all sectors based on card memory, other values then below defaults to 1k"); + PrintAndLogEx(NORMAL, " * 0 = MINI(320 bytes)"); + PrintAndLogEx(NORMAL, " * 1 = 1K"); + PrintAndLogEx(NORMAL, " * 2 = 2K"); + PrintAndLogEx(NORMAL, " * 4 = 4K"); PrintAndLogEx(NORMAL, " i set type of SIMD instructions. Without this flag programs autodetect it. (for hardnested)"); PrintAndLogEx(NORMAL, " i 5 = AVX512"); PrintAndLogEx(NORMAL, " i 2 = AVX2"); @@ -1570,14 +1575,16 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { uint8_t keyType = 0; uint8_t key[6] = {0}; uint64_t key64 = 0; + bool calibrate = true; // Attack key storage variables uint8_t *keyBlock; uint16_t keycnt = 0; - sector_t *e_sector; + sector_t *eSector; uint8_t sectorsCnt = MIFARE_1K_MAXSECTOR; int blockCnt = MIFARE_1K_MAXBLOCK; uint8_t tmpKey[6] = {0}; size_t datalen = 0; + bool knowTargetKey = false; // For the timier uint64_t t1; // Parameters and dictionary file @@ -1597,12 +1604,9 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { char* fnameptr = filename; // Settings bool slow = false; - bool nonce_file_read = false; - bool nonce_file_write = false; - bool know_target_key = false; bool legacy_mfchk = false; bool prng_type = false; - bool calibrate = true; + bool verbose = false; // Parse the options given by the user ctmp = tolower(param_getchar(Cmd, 0)); @@ -1619,6 +1623,9 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { case 'l': legacy_mfchk = true; break; + case 'v': + verbose = true; + break; case '*': // Get the number of sectors sectorsCnt = NumOfSectors(param_getchar(Cmd, cmdp + 1)); @@ -1646,7 +1653,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { PrintAndLogEx(WARNING, "Key must include 12 HEX symbols"); return 1; } - know_target_key = true; + knowTargetKey = true; cmdp += 3; case 's': slow = true; @@ -1688,13 +1695,13 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { } // Create the key storage stucture - e_sector = calloc(sectorsCnt, sizeof(sector_t)); - if (e_sector == NULL) return PM3_EMALLOC; + eSector = calloc(sectorsCnt, sizeof(sector_t)); + if (eSector == NULL) return PM3_EMALLOC; // Clear the key storage datastructure for (i=0; i just be nice and correct it ;) - if (know_target_key == false) { - num_to_bytes(e_sector[i].Key[i2], 6, key); - know_target_key = true; + if (knowTargetKey == false) { + num_to_bytes(eSector[i].Key[i2], 6, key); + knowTargetKey = true; blockNo = i; keyType = i2; - PrintAndLogEx(SUCCESS, "[ SETTINGS ] The following key will be used to the nested / hardnested attack: Sector:" + PrintAndLogEx(SUCCESS, "[ SETTINGS ] The following key will be used for the nested / hardnested attack: sector:" _RED_("%3d") " key type:"_RED_("%c") " key: " _RED_("0x%02x%02x%02x%02x%02x%02x"), blockNo, keyType ? 'B' : 'A', @@ -1769,7 +1777,10 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { loadFileDICTIONARY(filename, keyBlock, &datalen, 6, &keycnt); } else { keyBlock = calloc(ARRAYLEN(g_mifare_default_keys), 6); - if (keyBlock == NULL) return 1; + if (keyBlock == NULL) { + free(eSector); + return 1; + } for (int cnt = 0; cnt < ARRAYLEN(g_mifare_default_keys); cnt++) { num_to_bytes(g_mifare_default_keys[cnt], 6, keyBlock + cnt * 6); @@ -1787,12 +1798,12 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { for (i=0; i The fast check --> mfCheckKeys_fast(sectorsCnt, true, true, 2, 1, tmpKey, e_sector, false); + // The fast check --> mfCheckKeys_fast(sectorsCnt, true, true, 2, 1, tmpKey, eSector, false); // Returns false keys, so we just stick to the slower mfchk. for (i=0; i try hardnested instead!"); goto tryHardnested; break; @@ -1966,11 +1979,12 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { break; case -5 : calibrate = false; - e_sector[current_sector_i].Key[current_key_type_i] = bytes_to_num(tmpKey, 6); - e_sector[current_sector_i].foundKey[current_key_type_i] = 5; + eSector[current_sector_i].Key[current_key_type_i] = bytes_to_num(tmpKey, 6); + eSector[current_sector_i].foundKey[current_key_type_i] = 5; break; default : PrintAndLogEx(ERR, "unknown Error.\n"); + free(eSector); return 1; break; } @@ -1981,30 +1995,30 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { current_key_type_i ? 'B' : 'A', slow ? "Yes" : "No"); - isOK = mfnestedhard(FirstBlockOfSector(blockNo), keyType, key, FirstBlockOfSector(current_sector_i), current_key_type_i, NULL, nonce_file_read, nonce_file_write, slow, 0, &foundkey, NULL); + isOK = mfnestedhard(FirstBlockOfSector(blockNo), keyType, key, FirstBlockOfSector(current_sector_i), current_key_type_i, NULL, false, false, slow, 0, &foundkey, NULL); DropField(); if (isOK) { switch (isOK) { case 1 : - PrintAndLogEx(ERR, "Error: No response from Proxmark3.\n"); + PrintAndLogEx(ERR, "\nError: No response from Proxmark3."); break; case 2 : - PrintAndLogEx(NORMAL, "Button pressed. Aborted.\n"); + PrintAndLogEx(NORMAL, "\nButton pressed. Aborted."); break; default : break; } - free(e_sector); + free(eSector); return 2; } // Copy the found key to the tmpKey variale (for the following print statement, and the mfCheckKeys above) num_to_bytes(foundkey, 6, tmpKey); - e_sector[current_sector_i].Key[current_key_type_i] = foundkey; - e_sector[current_sector_i].foundKey[current_key_type_i] = 6; + eSector[current_sector_i].Key[current_key_type_i] = foundkey; + eSector[current_sector_i].foundKey[current_key_type_i] = 6; } // Check if the key was found - if (e_sector[current_sector_i].foundKey[current_key_type_i] != 0) { + if (eSector[current_sector_i].foundKey[current_key_type_i] != 0) { PrintAndLogEx(SUCCESS, "[BROCKEN KEY] Valid KEY FOUND: sector:%3d key type:%c key: " _YELLOW_("0x%02x%02x%02x%02x%02x%02x"), current_sector_i, current_key_type_i ? 'B' : 'A', @@ -2022,32 +2036,30 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { // Show the results to the user PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(INFO, "Found KEYS:"); - printKeyTable(sectorsCnt, e_sector); - PrintAndLogEx(INFO, "[ INFO ] Key res types:"); - PrintAndLogEx(INFO, " 1: Dictionary"); - PrintAndLogEx(INFO, " 2: Darkside attack"); - PrintAndLogEx(INFO, " 3: User supplied"); - PrintAndLogEx(INFO, " 4: Reused"); - PrintAndLogEx(INFO, " 5: Nested"); - PrintAndLogEx(INFO, " 6: Hardnested"); + PrintAndLogEx(INFO, "Found Keys:"); + printKeyTable(sectorsCnt, eSector); + if (verbose) { + PrintAndLogEx(INFO, "[ INFO ] Key res types:"); + PrintAndLogEx(INFO, " 1: Dictionary"); + PrintAndLogEx(INFO, " 2: Darkside attack"); + PrintAndLogEx(INFO, " 3: User supplied"); + PrintAndLogEx(INFO, " 4: Reused"); + PrintAndLogEx(INFO, " 5: Nested"); + PrintAndLogEx(INFO, " 6: Hardnested"); + } - // Generate and show statistics - t1 = msclock() - t1; - PrintAndLogEx(INFO, "Required time for the autopwn attack: " _YELLOW_("%.0f") " seconds", (float)t1 / 1000.0); - // Transfere the found keys to the simulator and dump the keys and card data PrintAndLogEx(NORMAL, ""); PrintAndLogEx(INFO, "Dumping the keys:"); - createKeyDump(sectorsCnt, e_sector, GenerateFilename("hf-mf-", "-key.bin")); + createKeyDump(sectorsCnt, eSector, GenerateFilename("hf-mf-", "-key.bin")); PrintAndLogEx(SUCCESS, "Transfering the found keys to the simulator memory"); for (current_sector_i=0; current_sector_i < sectorsCnt; current_sector_i++) { mfEmlGetMem(block, current_sector_i, 1); - if (e_sector[current_sector_i].foundKey[0]) - num_to_bytes(e_sector[current_sector_i].Key[0], 6, block); - if (e_sector[current_sector_i].foundKey[1]) - num_to_bytes(e_sector[current_sector_i].Key[1], 6, block + 10); + if (eSector[current_sector_i].foundKey[0]) + num_to_bytes(eSector[current_sector_i].Key[0], 6, block); + if (eSector[current_sector_i].foundKey[1]) + num_to_bytes(eSector[current_sector_i].Key[1], 6, block + 10); mfEmlSetMem(block, FirstBlockOfSector(current_sector_i) + NumBlocksPerSector(current_sector_i) - 1, 1); } @@ -2058,6 +2070,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { dump = calloc(bytes, sizeof(uint8_t)); if (!dump) { PrintAndLogEx(WARNING, "Fail, cannot allocate memory"); + free(eSector); return PM3_EMALLOC; } memset(dump, 0, bytes); @@ -2065,6 +2078,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { PrintAndLogEx(INFO, "Downloading the card content from emulator memory"); if (!GetFromDevice(BIG_BUF_EML, dump, bytes, 0, NULL, 0, NULL, 2500, false)) { PrintAndLogEx(WARNING, "Fail, transfer from device time-out"); + free(eSector); free(dump); return PM3_ETIMEOUT; } @@ -2075,9 +2089,13 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { saveFile(filename, ".bin", dump, bytes); saveFileEML(filename, dump, bytes, MFBLOCK_SIZE); saveFileJSON(filename, jsfCardMemory, dump, bytes); - free(dump); - free(e_sector); + // Generate and show statistics + t1 = msclock() - t1; + PrintAndLogEx(INFO, "Required time for the autopwn attack: " _YELLOW_("%.0f") " seconds", (float)t1 / 1000.0); + + free(dump); + free(eSector); return 0; } From ccb85067d52dbb031bd58f99b4b760edaeb8a1df Mon Sep 17 00:00:00 2001 From: Iceman Date: Mon, 26 Aug 2019 09:12:26 +0200 Subject: [PATCH 0436/1854] Update README.md --- README.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 68ef01492..9bf18de1a 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ -# RRG / Iceman repo, dedicated to Proxmark3 RDV4.0 +# RRG / Iceman repo - Proxmark3 RDV4.0 and other Proxmark3 platforms. -This repo is based on iceman fork for Proxmark3. It is dedicated to bringing the most out of the new features for Proxmark3 RDV4.0 new hardware and design. +This repo is based on iceman fork for Proxmark3. It supports other Proxmark3 platforms as well. -_Note that it also supports other Proxmark3 platforms as well!_ +It is dedicated to bringing the most out of the new features for Proxmark3 RDV4.0 new hardware and design. | Releases | Linux & OSX CI | Windows CI | @@ -28,6 +28,9 @@ _Note that it also supports other Proxmark3 platforms as well!_ |[Developing standalone mode](/armsrc/Standalone/readme.md)|[Wiki about standalone mode](https://github.com/RfidResearchGroup/proxmark3/wiki/Standalone-mode) || |[Donations](#Donations)||| +## Support on other Proxmark3 platforms +In order to build this repo for other Proxmark3 platforms we urge you to read [Advanced compilation parameters](/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md) + ## What has changed? On the hardware side: From 2e4c7f4f8d7ed4fbb3e4b5a489716903c3bce828 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 26 Aug 2019 10:52:07 +0200 Subject: [PATCH 0437/1854] chg: reuse code --- client/loclass/cipherutils.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/client/loclass/cipherutils.c b/client/loclass/cipherutils.c index 80364d4e1..52ac82f94 100644 --- a/client/loclass/cipherutils.c +++ b/client/loclass/cipherutils.c @@ -160,19 +160,7 @@ void printarr(const char *name, uint8_t *arr, int len) { } void printvar(const char *name, uint8_t *arr, int len) { -/* - int cx, i; - size_t outsize = 40 + strlen(name) + len * 2; - char *output = calloc(outsize, sizeof(char)); - cx = snprintf(output, outsize, "%s = ", name); - for (i = 0; i < len; i++) { - cx += snprintf(output + cx, outsize - cx, "%02x", *(arr + i)); //2 bytes per byte - } - PrintAndLogEx(NORMAL, output); - free(output); - */ PrintAndLogEx(NORMAL, "%s = " _YELLOW_("%s"), name, sprint_hex(arr, len) ); - } void printarr_human_readable(const char *title, uint8_t *arr, int len) { From 2edee59837f0903c5db1a7ceb3e7addcd910e87c Mon Sep 17 00:00:00 2001 From: Matthias Konrath Date: Mon, 26 Aug 2019 12:27:40 +0200 Subject: [PATCH 0438/1854] Changed the variable names, added aditional dictionary size checks, fixed a corner case with the key transferes. --- client/cmdhfmf.c | 204 +++++++++++++++++++++++++---------------------- 1 file changed, 107 insertions(+), 97 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 4cd1a02a7..1fb2d48ff 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -179,7 +179,7 @@ static int usage_hf14_autopwn(void) { PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h this help"); PrintAndLogEx(NORMAL, " k if a known key for a block is supplied"); - PrintAndLogEx(NORMAL, " f .dic dictionary file for key discovery (the file has to end in .dic)"); + PrintAndLogEx(NORMAL, " f .dic dictionary file for key discovery (the file has to end in .dic) max 2000 entries allowed"); PrintAndLogEx(NORMAL, " s slower acquisition (required by some non standard cards) for hardnested"); PrintAndLogEx(NORMAL, " v verbose output (statistcs)"); PrintAndLogEx(NORMAL, " l legacy mode (use the slow mfchk for the key enumeration)"); @@ -1578,13 +1578,13 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { bool calibrate = true; // Attack key storage variables uint8_t *keyBlock; - uint16_t keycnt = 0; - sector_t *eSector; - uint8_t sectorsCnt = MIFARE_1K_MAXSECTOR; - int blockCnt = MIFARE_1K_MAXBLOCK; - uint8_t tmpKey[6] = {0}; - size_t datalen = 0; - bool knowTargetKey = false; + uint16_t key_cnt = 0; + sector_t *e_sector; + uint8_t sectors_cnt = MIFARE_1K_MAXSECTOR; + int block_cnt = MIFARE_1K_MAXBLOCK; + uint8_t tmp_key[6] = {0}; + size_t data_length = 0; + bool know_target_key = false; // For the timier uint64_t t1; // Parameters and dictionary file @@ -1607,6 +1607,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { bool legacy_mfchk = false; bool prng_type = false; bool verbose = false; + int max_dictionary_size = 2000; // Parse the options given by the user ctmp = tolower(param_getchar(Cmd, 0)); @@ -1628,8 +1629,8 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { break; case '*': // Get the number of sectors - sectorsCnt = NumOfSectors(param_getchar(Cmd, cmdp + 1)); - blockCnt = NumOfBlocks(param_getchar(Cmd, cmdp + 1)); + sectors_cnt = NumOfSectors(param_getchar(Cmd, cmdp + 1)); + block_cnt = NumOfBlocks(param_getchar(Cmd, cmdp + 1)); cmdp ++; break; case 'k': @@ -1653,7 +1654,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { PrintAndLogEx(WARNING, "Key must include 12 HEX symbols"); return 1; } - knowTargetKey = true; + know_target_key = true; cmdp += 3; case 's': slow = true; @@ -1695,13 +1696,13 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { } // Create the key storage stucture - eSector = calloc(sectorsCnt, sizeof(sector_t)); - if (eSector == NULL) return PM3_EMALLOC; + e_sector = calloc(sectors_cnt, sizeof(sector_t)); + if (e_sector == NULL) return PM3_EMALLOC; // Clear the key storage datastructure - for (i=0; i just be nice and correct it ;) - if (knowTargetKey == false) { - num_to_bytes(eSector[i].Key[i2], 6, key); - knowTargetKey = true; + if (know_target_key == false) { + num_to_bytes(e_sector[i].Key[i2], 6, key); + know_target_key = true; blockNo = i; keyType = i2; PrintAndLogEx(SUCCESS, "[ SETTINGS ] The following key will be used for the nested / hardnested attack: sector:" _RED_("%3d") " key type:"_RED_("%c") " key: " _RED_("0x%02x%02x%02x%02x%02x%02x"), @@ -1773,19 +1774,26 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { // Load the dictionary if (strlen(filename) != 0) { - keyBlock = calloc(6 * 2000, sizeof(uint8_t)); - loadFileDICTIONARY(filename, keyBlock, &datalen, 6, &keycnt); + keyBlock = calloc(6 * max_dictionary_size, sizeof(uint8_t)); + loadFileDICTIONARY(filename, keyBlock, &data_length, 6, &key_cnt); + if ((data_length / 6) > max_dictionary_size) { + // This is not a good solution (loadFileDICTIONARY needs a maxdatalen)! + PrintAndLogEx(FAILED, "The loaded dictionary is too large: %d (allowed: %d)", data_length, max_dictionary_size); + free(keyBlock); // This won't work too well, because data on the stack is already overflown !!! + free(e_sector); + return 1; + } } else { keyBlock = calloc(ARRAYLEN(g_mifare_default_keys), 6); if (keyBlock == NULL) { - free(eSector); + free(e_sector); return 1; } for (int cnt = 0; cnt < ARRAYLEN(g_mifare_default_keys); cnt++) { num_to_bytes(g_mifare_default_keys[cnt], 6, keyBlock + cnt * 6); } - keycnt = ARRAYLEN(g_mifare_default_keys); + key_cnt = ARRAYLEN(g_mifare_default_keys); } // Start the timer @@ -1795,15 +1803,15 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { PrintAndLogEx(INFO, "Enumerating the card keys with the dictionary!"); if (legacy_mfchk) { // Check all the sectors - for (i=0; i (PM3_CMD_DATA_SIZE / 6) ? (PM3_CMD_DATA_SIZE / 6) : keycnt; + int chunksize = key_cnt > (PM3_CMD_DATA_SIZE / 6) ? (PM3_CMD_DATA_SIZE / 6) : key_cnt; bool firstChunk = true, lastChunk = false; for (uint8_t strategy = 1; strategy < 3; strategy++) { PrintAndLogEx(INFO, "Running strategy %u", strategy); // main keychunk loop - for (i = 0; i < keycnt; i += chunksize) { + for (i = 0; i < key_cnt; i += chunksize) { if (kbd_enter_pressed()) { PrintAndLogEx(WARNING, "\naborted via keyboard!\n"); - i = keycnt; strategy = 3; break; // Exit the loop + i = key_cnt; strategy = 3; break; // Exit the loop } - uint32_t size = ((keycnt - i) > chunksize) ? chunksize : keycnt - i; + uint32_t size = ((key_cnt - i) > chunksize) ? chunksize : key_cnt - i; // last chunk? - if (size == keycnt - i) + if (size == key_cnt - i) lastChunk = true; - int res = mfCheckKeys_fast(sectorsCnt, firstChunk, lastChunk, strategy, size, keyBlock + (i * 6), eSector, false); + int res = mfCheckKeys_fast(sectors_cnt, firstChunk, lastChunk, strategy, size, keyBlock + (i * 6), e_sector, false); if (firstChunk) firstChunk = false; // all keys, aborted if (res == 0 || res == 2) { - i = keycnt; strategy = 3; break; // Exit the loop + i = key_cnt; strategy = 3; break; // Exit the loop } } // end chunks of keys firstChunk = true; @@ -1841,19 +1849,19 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { } // Analyse the dictionary attack - for (i=0; i The fast check --> mfCheckKeys_fast(sectorsCnt, true, true, 2, 1, tmpKey, eSector, false); + if (bytes_to_num(tmp_key, 6) != 0) { + // The fast check --> mfCheckKeys_fast(sectors_cnt, true, true, 2, 1, tmp_key, e_sector, false); // Returns false keys, so we just stick to the slower mfchk. - for (i=0; i Date: Mon, 26 Aug 2019 12:50:10 +0200 Subject: [PATCH 0439/1854] typo --- tools/analyzesize.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/analyzesize.py b/tools/analyzesize.py index 4a5211c67..889222c01 100755 --- a/tools/analyzesize.py +++ b/tools/analyzesize.py @@ -16,7 +16,7 @@ except FileNotFoundError: db = dict() if len(sys.argv) < 3: - print("Usage: analazysize.py ") + print("Usage: analyzesize.py ") exit(-1) action, name = sys.argv[1:3] currentdata = subprocess.run(["arm-none-eabi-size","armsrc/obj/fullimage.stage1.elf"], stdout=subprocess.PIPE).stdout From 4ddc3d61d5250b6691603e949b784b7b76a104b4 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 26 Aug 2019 13:03:11 +0200 Subject: [PATCH 0440/1854] hf mf chk/fchk: load dic with searchFile and fail when errors in args --- client/cmdhfmf.c | 74 ++++++++++++++++++++++++++++++---------------- client/fileutils.h | 2 +- doc/cheatsheet.md | 6 ++-- 3 files changed, 53 insertions(+), 29 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index aaaeafb99..b2e4b9855 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -179,10 +179,10 @@ static int usage_hf14_chk(void) { PrintAndLogEx(NORMAL, " t write keys to emulator memory\n"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf mf chk 0 A 1234567890ab -- target block 0, Key A using key 1234567890ab"); - PrintAndLogEx(NORMAL, " hf mf chk 0 A default_keys.dic -- target block 0, Key A using default dictionary file"); - PrintAndLogEx(NORMAL, " hf mf chk *1 ? t -- target all blocks, all keys, 1K, write to emulator memory"); - PrintAndLogEx(NORMAL, " hf mf chk *1 ? d -- target all blocks, all keys, 1K, write to file"); + PrintAndLogEx(NORMAL, " hf mf chk 0 A 1234567890ab -- target block 0, Key A using key 1234567890ab"); + PrintAndLogEx(NORMAL, " hf mf chk 0 A mfc_default_keys.dic -- target block 0, Key A using default dictionary file"); + PrintAndLogEx(NORMAL, " hf mf chk *1 ? t -- target all blocks, all keys, 1K, write to emulator memory"); + PrintAndLogEx(NORMAL, " hf mf chk *1 ? d -- target all blocks, all keys, 1K, write to file"); return 0; } static int usage_hf14_chk_fast(void) { @@ -200,12 +200,12 @@ static int usage_hf14_chk_fast(void) { PrintAndLogEx(NORMAL, " m use dictionary from flashmemory\n"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf mf fchk 1 1234567890ab -- target 1K using key 1234567890ab"); - PrintAndLogEx(NORMAL, " hf mf fchk 1 default_keys.dic -- target 1K using default dictionary file"); - PrintAndLogEx(NORMAL, " hf mf fchk 1 t -- target 1K, write to emulator memory"); - PrintAndLogEx(NORMAL, " hf mf fchk 1 d -- target 1K, write to file"); + PrintAndLogEx(NORMAL, " hf mf fchk 1 1234567890ab -- target 1K using key 1234567890ab"); + PrintAndLogEx(NORMAL, " hf mf fchk 1 mfc_default_keys.dic -- target 1K using default dictionary file"); + PrintAndLogEx(NORMAL, " hf mf fchk 1 t -- target 1K, write to emulator memory"); + PrintAndLogEx(NORMAL, " hf mf fchk 1 d -- target 1K, write to file"); if (IfPm3Flash()) - PrintAndLogEx(NORMAL, " hf mf fchk 1 m -- target 1K, use dictionary from flashmemory"); + PrintAndLogEx(NORMAL, " hf mf fchk 1 m -- target 1K, use dictionary from flashmemory"); return 0; } static int usage_hf14_keybrute(void) { @@ -1575,7 +1575,7 @@ static int CmdHF14AMfChk_fast(const char *Cmd) { sector_t *e_sector = NULL; keyBlock = calloc(ARRAYLEN(g_mifare_default_keys), 6); - if (keyBlock == NULL) return 1; + if (keyBlock == NULL) return PM3_EMALLOC; for (int cnt = 0; cnt < ARRAYLEN(g_mifare_default_keys); cnt++) num_to_bytes(g_mifare_default_keys[cnt], 6, keyBlock + cnt * 6); @@ -1615,7 +1615,7 @@ static int CmdHF14AMfChk_fast(const char *Cmd) { if (!p) { PrintAndLogEx(FAILED, "Cannot allocate memory for Keys"); free(keyBlock); - return 2; + return PM3_EMALLOC; } keyBlock = p; } @@ -1629,14 +1629,24 @@ static int CmdHF14AMfChk_fast(const char *Cmd) { // May be a dic file if (param_getstr(Cmd, i, filename, FILE_PATH_SIZE) >= FILE_PATH_SIZE) { PrintAndLogEx(FAILED, "Filename too long"); - continue; + free(keyBlock); + return PM3_EINVARG; } - f = fopen(filename, "r"); - if (!f) { - PrintAndLogEx(FAILED, "File: " _YELLOW_("%s") ": not found or locked.", filename); - continue; + char *dict_path; + int res = searchFile(&dict_path, DICTIONARIES_SUBDIR, filename, ".dic"); + if (res != PM3_SUCCESS) { + free(keyBlock); + return res; } + f = fopen(dict_path, "r"); + if (!f) { + PrintAndLogEx(FAILED, "File: " _YELLOW_("%s") ": not found or locked.", dict_path); + free(dict_path); + free(keyBlock); + return PM3_EFILE; + } + free(dict_path); // read file while (fgets(buf, sizeof(buf), f)) { @@ -1649,7 +1659,9 @@ static int CmdHF14AMfChk_fast(const char *Cmd) { if (!isxdigit(buf[0])) { PrintAndLogEx(FAILED, "File content error. '" _YELLOW_("%s")"' must include 12 HEX symbols", buf); - continue; + free(keyBlock); + fclose(f); + return PM3_EFILE; } buf[12] = 0; @@ -1659,7 +1671,7 @@ static int CmdHF14AMfChk_fast(const char *Cmd) { PrintAndLogEx(FAILED, "Cannot allocate memory for default keys"); free(keyBlock); fclose(f); - return 2; + return PM3_EMALLOC; } keyBlock = p; } @@ -1686,7 +1698,7 @@ static int CmdHF14AMfChk_fast(const char *Cmd) { e_sector = calloc(sectorsCnt, sizeof(sector_t)); if (e_sector == NULL) { free(keyBlock); - return 1; + return PM3_EMALLOC; } uint32_t chunksize = keycnt > (PM3_CMD_DATA_SIZE / 6) ? (PM3_CMD_DATA_SIZE / 6) : keycnt; @@ -1894,14 +1906,24 @@ static int CmdHF14AMfChk(const char *Cmd) { // May be a dic file if (param_getstr(Cmd, i, filename, sizeof(filename)) >= FILE_PATH_SIZE) { PrintAndLogEx(FAILED, "File name too long"); - continue; + free(keyBlock); + return PM3_EINVARG; } - f = fopen(filename, "r"); - if (!f) { - PrintAndLogEx(FAILED, "File: " _YELLOW_("%s") ": not found or locked.", filename); - continue; + char *dict_path; + int res = searchFile(&dict_path, DICTIONARIES_SUBDIR, filename, ".dic"); + if (res != PM3_SUCCESS) { + free(keyBlock); + return PM3_EFILE; } + f = fopen(dict_path, "r"); + if (!f) { + PrintAndLogEx(FAILED, "File: " _YELLOW_("%s") ": not found or locked.", dict_path); + free(dict_path); + free(keyBlock); + return PM3_EFILE; + } + free(dict_path); // load keys from dictionary file while (fgets(buf, sizeof(buf), f)) { @@ -1915,7 +1937,9 @@ static int CmdHF14AMfChk(const char *Cmd) { // codesmell, only checks first char? if (!isxdigit(buf[0])) { PrintAndLogEx(FAILED, "File content error. '" _YELLOW_("%s")"' must include 12 HEX symbols", buf); - continue; + free(keyBlock); + fclose(f); + return PM3_EFILE; } buf[12] = 0; diff --git a/client/fileutils.h b/client/fileutils.h index d23472867..eea3329c5 100644 --- a/client/fileutils.h +++ b/client/fileutils.h @@ -141,7 +141,7 @@ int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_ /** * @brief Utility function to load data from a DICTIONARY textfile. This method takes a preferred name. - * E.g. default_keys.dic + * E.g. mfc_default_keys.dic * * @param preferredName * @param data The data array to store the loaded bytes from file diff --git a/doc/cheatsheet.md b/doc/cheatsheet.md index 02628a9bc..dbd48d548 100644 --- a/doc/cheatsheet.md +++ b/doc/cheatsheet.md @@ -181,7 +181,7 @@ Options card memory : 0 - MINI(320 bytes), 1 - 1K, 2 - 2K, 4 - 4K d : write keys to binary file -pm3 --> hf mf chk *1 ? d dictionaries/mfc_default_keys.dic +pm3 --> hf mf chk *1 ? d mfc_default_keys ``` Check for default keys from local memory @@ -254,7 +254,7 @@ pm3 --> hf mf sim u 353c2aa6 Simulate Mifare Sequence ``` -pm3 --> hf mf chk *1 ? d dictionaries/mfc_default_keys.dic +pm3 --> hf mf chk *1 ? d mfc_default_keys pm3 --> hf mf dump 1 pm3 --> script run dumptoemul -i dumpdata.bin pm3 --> hf mf eload 353C2AA6 @@ -263,7 +263,7 @@ pm3 --> hf mf sim u 353c2aa6 Clone Mifare 1K Sequence ``` -pm3 --> hf mf chk *1 ? d dictionaries/mfc_default_keys.dic +pm3 --> hf mf chk *1 ? d mfc_default_keys pm3 --> hf mf dump pm3 --> hf mf restore 1 u 4A6CE843 k hf-mf-A29558E4-key.bin f hf-mf-A29558E4-data.bin ``` From 2a1e6dff80f9ea96d4fb260a0f8fe6f2683f590e Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 26 Aug 2019 13:36:37 +0200 Subject: [PATCH 0441/1854] hf iclass chk/lookup: load dic with searchFile and fail when errors in args --- client/cmdhficlass.c | 48 ++++++++++++++++------------ doc/cheatsheet.md | 74 ++++++++++++++++++++++---------------------- 2 files changed, 66 insertions(+), 56 deletions(-) diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 51bc323fc..862dad13c 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -244,8 +244,8 @@ static int usage_hf_iclass_chk(void) { PrintAndLogEx(NORMAL, " e elite"); PrintAndLogEx(NORMAL, " c credit key (if not use, default is debit)"); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf iclass chk f dictionaries/iclass_default_keys.dic"); - PrintAndLogEx(NORMAL, " hf iclass chk f dictionaries/iclass_default_keys.dic e"); + PrintAndLogEx(NORMAL, " hf iclass chk f iclass_default_keys"); + PrintAndLogEx(NORMAL, " hf iclass chk f iclass_default_keys e"); return PM3_SUCCESS;; } static int usage_hf_iclass_lookup(void) { @@ -260,8 +260,8 @@ static int usage_hf_iclass_lookup(void) { PrintAndLogEx(NORMAL, " r raw"); PrintAndLogEx(NORMAL, " e elite"); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf iclass lookup u 9655a400f8ff12e0 p f0ffffffffffffff m 0000000089cb984b f dictionaries/iclass_default_keys.dic"); - PrintAndLogEx(NORMAL, " hf iclass lookup u 9655a400f8ff12e0 p f0ffffffffffffff m 0000000089cb984b f dictionaries/iclass_default_keys.dic e"); + PrintAndLogEx(NORMAL, " hf iclass lookup u 9655a400f8ff12e0 p f0ffffffffffffff m 0000000089cb984b f iclass_default_keys"); + PrintAndLogEx(NORMAL, " hf iclass lookup u 9655a400f8ff12e0 p f0ffffffffffffff m 0000000089cb984b f iclass_default_keys e"); return PM3_SUCCESS; } static int usage_hf_iclass_permutekey(void) { @@ -2059,9 +2059,9 @@ static int CmdHFiClassCheckKeys(const char *Cmd) { // load keys into keyblock int res = LoadDictionaryKeyFile(filename, &keyBlock, &keycnt); - if (res > 0) { + if (res != PM3_SUCCESS) { free(keyBlock); - return PM3_EFILE; + return res; } pre = calloc(keycnt, sizeof(iclass_premac_t)); @@ -2312,33 +2312,33 @@ static int CmdHFiClassLookUp(const char *Cmd) { PrintAndLogEx(SUCCESS, "MAC_TAG | %s", sprint_hex(MAC_TAG, sizeof(MAC_TAG))); int res = LoadDictionaryKeyFile(filename, &keyBlock, &keycnt); - if (res > 0) { + if (res != PM3_SUCCESS) { free(keyBlock); - return 1; + return res; } //iclass_prekey_t prekey = calloc(keycnt, sizeof(iclass_prekey_t)); if (!prekey) { free(keyBlock); - return 1; + return PM3_EMALLOC; } - PrintAndLogEx(FAILED, "Generating diversified keys and MAC"); + PrintAndLogEx(INFO, "Generating diversified keys and MAC"); res = GenerateFromKeyFile(CSN, CCNR, use_raw, use_elite, keyBlock, keycnt, prekey); - if (res > 0) { + if (res != PM3_SUCCESS) { free(keyBlock); free(prekey); - return 1; + return PM3_ESOFT; } - PrintAndLogEx(FAILED, "Sorting"); + PrintAndLogEx(INFO, "Sorting"); // sort mac list. qsort(prekey, keycnt, sizeof(iclass_prekey_t), cmp_uint32); //PrintPreCalc(prekey, keycnt); - PrintAndLogEx(FAILED, "Searching"); + PrintAndLogEx(INFO, "Searching"); iclass_prekey_t *item; iclass_prekey_t lookup; memcpy(lookup.mac, MAC_TAG, 4); @@ -2377,10 +2377,19 @@ int LoadDictionaryKeyFile(char *filename, uint8_t **keys, int *keycnt) { uint8_t *p; int keyitems = 0; - if (!(f = fopen(filename, "r"))) { - PrintAndLogEx(FAILED, "File: " _YELLOW_("%s") ": not found or locked.", filename); - return 1; + + char *dict_path; + int res = searchFile(&dict_path, DICTIONARIES_SUBDIR, filename, ".dic"); + if (res != PM3_SUCCESS) { + return res; } + f = fopen(dict_path, "r"); + if (!f) { + PrintAndLogEx(FAILED, "File: " _YELLOW_("%s") ": not found or locked.", dict_path); + free(dict_path); + return PM3_EFILE; + } + free(dict_path); while (fgets(buf, sizeof(buf), f)) { if (strlen(buf) < 16 || buf[15] == '\n') @@ -2396,7 +2405,8 @@ int LoadDictionaryKeyFile(char *filename, uint8_t **keys, int *keycnt) { // doesn't this only test first char only? if (!isxdigit(buf[0])) { PrintAndLogEx(ERR, "file content error. '%s' must include 16 HEX symbols", buf); - continue; + fclose(f); + return PM3_EFILE; } // null terminator (skip the rest of the line) @@ -2406,7 +2416,7 @@ int LoadDictionaryKeyFile(char *filename, uint8_t **keys, int *keycnt) { if (!p) { PrintAndLogEx(ERR, "cannot allocate memory for default keys"); fclose(f); - return 2; + return PM3_EMALLOC; } *keys = p; diff --git a/doc/cheatsheet.md b/doc/cheatsheet.md index dbd48d548..670ae1979 100644 --- a/doc/cheatsheet.md +++ b/doc/cheatsheet.md @@ -46,7 +46,7 @@ Reverse permute iClass master key ``` Options --- -r reverse permuted key +r reverse permuted key pm3 --> hf iclass permute r 3F90EBF0910F7B6F ``` @@ -166,7 +166,7 @@ p : EPURSE m : macs e : elite -pm3 --> hf iclass lookup u 010a0ffff7ff12e0 p feffffffffffffff m 66348979153c41b9 f dictionaries/iclass_default_keys.dic e +pm3 --> hf iclass lookup u 010a0ffff7ff12e0 p feffffffffffffff m 66348979153c41b9 f iclass_default_keys e ``` ## Mifare @@ -188,7 +188,7 @@ Check for default keys from local memory ``` Options --- -card memory : 0 - MINI(320 bytes), 1 - 1K, 2 - 2K, 4 - 4K +card memory : 0 - MINI(320 bytes), 1 - 1K, 2 - 2K, 4 - 4K m : use dictionary from flashmemory pm3 --> hf mf fchk 1 m @@ -245,7 +245,7 @@ pm3 --> hf mf eload 353C2AA6 pm3 --> hf mf eload 1 353C2AA6 ``` -Simulate Mifare +Simulate Mifare ``` u : (Optional) UID 4,7 or 10 bytes. If not specified, the UID 4B from emulator memory will be used @@ -285,10 +285,10 @@ Convert Site & Facility code to Wiegand ``` Options --- - -OEM : OEM number / site code -FC : facility code -CN : card number + +OEM : OEM number / site code +FC : facility code +CN : card number pm3 --> lf hid wiegand 0 56 150 ``` @@ -376,7 +376,7 @@ pm3 --> lf hitag 26 pm3 --> lf hitag 21 4D494B52 ``` -Sniff Hitag traffic +Sniff Hitag traffic ``` pm3 --> lf hitag sniff pm3 --> lf hitag list @@ -384,7 +384,7 @@ pm3 --> lf hitag list Simulate Hitag ``` -pm3 --> lf hitag sim c378181c_a8f7.ht2 +pm3 --> lf hitag sim c378181c_a8f7.ht2 ``` Write to Hitag block @@ -405,7 +405,7 @@ pm3 --> lf hitag writer 24 499602D2 1 00000000 Simulate Hitag2 sequence ``` pm3 --> lf hitag reader 21 56713368 -pm3 --> lf hitag sim c378181c_a8f7.ht2 +pm3 --> lf hitag sim c378181c_a8f7.ht2 ``` ## T55XX @@ -432,16 +432,16 @@ Set timings to default ``` Options --- -p : persist to flashmemory -z : Set default t55x7 timings (use p to save if required) +p : persist to flashmemory +z : Set default t55x7 timings (use p to save if required) pm3 --> lf t55xx deviceconfig z p ``` Write to T55xx block ``` -b : block number to write. Between 0-7 -d : 4 bytes of data to write (8 hex characters) +b : block number to write. Between 0-7 +d : 4 bytes of data to write (8 hex characters) pm3 --> lf t55xx wr b 0 d 00081040 ``` @@ -506,11 +506,11 @@ Load default keys into memory ``` Options --- -o : offset in memory -f : file name -m : upload 6 bytes keys (mifare key dictionary) -i : upload 8 bytes keys (iClass key dictionary) -t : upload 4 bytes keys (pwd dictionary) +o : offset in memory +f : file name +m : upload 6 bytes keys (mifare key dictionary) +i : upload 8 bytes keys (iClass key dictionary) +t : upload 4 bytes keys (pwd dictionary) pm3 --> mem load f mfc_default_keys m pm3 --> mem load f t55xx_default_pwds t @@ -522,7 +522,7 @@ pm3 --> mem load f iclass_default_keys i Upgrade Sim Module firmware ``` -pm3 --> sc upgrade f ../tools/simmodule/SIM011.BIN +pm3 --> sc upgrade f ../tools/simmodule/SIM011.BIN ``` ## Smart Card @@ -542,26 +542,26 @@ Set clock speed ``` Options --- -c : clockspeed (0 = 16MHz, 1=8MHz, 2=4MHz) - -pm3 --> sc setclock c 2 +c : clockspeed (0 = 16MHz, 1=8MHz, 2=4MHz) + +pm3 --> sc setclock c 2 ``` Send raw hex data ``` Options ---- -r : do not read response -a : active smartcard without select (reset sc module) -s : active smartcard with select (get ATR) -t : executes TLV decoder if it possible -0 : use protocol T=0 -d : bytes to send - -pm3 --> sc raw s 0 d 00a404000e315041592e5359532e4444463031 : 1PAY.SYS.DDF01 PPSE directory with get ATR -pm3 --> sc raw 0 d 00a404000e325041592e5359532e4444463031 : 2PAY.SYS.DDF01 PPSE directory -pm3 --> sc raw 0 t d 00a4040007a0000000041010 : Mastercard -pm3 --> sc raw 0 t d 00a4040007a0000000031010 : Visa +--- +r : do not read response +a : active smartcard without select (reset sc module) +s : active smartcard with select (get ATR) +t : executes TLV decoder if it possible +0 : use protocol T=0 +d : bytes to send + +pm3 --> sc raw s 0 d 00a404000e315041592e5359532e4444463031 : 1PAY.SYS.DDF01 PPSE directory with get ATR +pm3 --> sc raw 0 d 00a404000e325041592e5359532e4444463031 : 2PAY.SYS.DDF01 PPSE directory +pm3 --> sc raw 0 t d 00a4040007a0000000041010 : Mastercard +pm3 --> sc raw 0 t d 00a4040007a0000000031010 : Visa ```` Bruteforce SPI @@ -570,6 +570,6 @@ Options --- t : executes TLV decoder if it possible -pm3 --> sc brute +pm3 --> sc brute pm3 --> sc brute t ``` From 6ac9d2f0fbf5c20da4b22db6698f9e22c9ea006a Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 26 Aug 2019 13:46:53 +0200 Subject: [PATCH 0442/1854] lf t55xx chk: load dic with searchFile --- client/cmdlft55xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 058645320..80954dddb 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -206,7 +206,7 @@ static int usage_t55xx_chk() { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx chk m"); - PrintAndLogEx(NORMAL, " lf t55xx chk i dictionaries/t55xx_default_pwds.dic"); + PrintAndLogEx(NORMAL, " lf t55xx chk i t55xx_default_pwds"); PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } From 7076df0e18455e21bb037abd89d039348934c235 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 26 Aug 2019 13:53:23 +0200 Subject: [PATCH 0443/1854] hf mf chk/fchk: don't stop on line errors when parsing dict --- client/cmdhfmf.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index b2e4b9855..afb369de3 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -1659,9 +1659,7 @@ static int CmdHF14AMfChk_fast(const char *Cmd) { if (!isxdigit(buf[0])) { PrintAndLogEx(FAILED, "File content error. '" _YELLOW_("%s")"' must include 12 HEX symbols", buf); - free(keyBlock); - fclose(f); - return PM3_EFILE; + continue; } buf[12] = 0; @@ -1937,9 +1935,7 @@ static int CmdHF14AMfChk(const char *Cmd) { // codesmell, only checks first char? if (!isxdigit(buf[0])) { PrintAndLogEx(FAILED, "File content error. '" _YELLOW_("%s")"' must include 12 HEX symbols", buf); - free(keyBlock); - fclose(f); - return PM3_EFILE; + continue; } buf[12] = 0; From 1628ac8e6217a3dcf2690e885202bba077ca7023 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 26 Aug 2019 13:55:42 +0200 Subject: [PATCH 0444/1854] revert temporarily hf iclass chk/lookup 2a1e6dff --- client/cmdhficlass.c | 48 ++++++++++++++++++-------------------------- 1 file changed, 19 insertions(+), 29 deletions(-) diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 862dad13c..51bc323fc 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -244,8 +244,8 @@ static int usage_hf_iclass_chk(void) { PrintAndLogEx(NORMAL, " e elite"); PrintAndLogEx(NORMAL, " c credit key (if not use, default is debit)"); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf iclass chk f iclass_default_keys"); - PrintAndLogEx(NORMAL, " hf iclass chk f iclass_default_keys e"); + PrintAndLogEx(NORMAL, " hf iclass chk f dictionaries/iclass_default_keys.dic"); + PrintAndLogEx(NORMAL, " hf iclass chk f dictionaries/iclass_default_keys.dic e"); return PM3_SUCCESS;; } static int usage_hf_iclass_lookup(void) { @@ -260,8 +260,8 @@ static int usage_hf_iclass_lookup(void) { PrintAndLogEx(NORMAL, " r raw"); PrintAndLogEx(NORMAL, " e elite"); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf iclass lookup u 9655a400f8ff12e0 p f0ffffffffffffff m 0000000089cb984b f iclass_default_keys"); - PrintAndLogEx(NORMAL, " hf iclass lookup u 9655a400f8ff12e0 p f0ffffffffffffff m 0000000089cb984b f iclass_default_keys e"); + PrintAndLogEx(NORMAL, " hf iclass lookup u 9655a400f8ff12e0 p f0ffffffffffffff m 0000000089cb984b f dictionaries/iclass_default_keys.dic"); + PrintAndLogEx(NORMAL, " hf iclass lookup u 9655a400f8ff12e0 p f0ffffffffffffff m 0000000089cb984b f dictionaries/iclass_default_keys.dic e"); return PM3_SUCCESS; } static int usage_hf_iclass_permutekey(void) { @@ -2059,9 +2059,9 @@ static int CmdHFiClassCheckKeys(const char *Cmd) { // load keys into keyblock int res = LoadDictionaryKeyFile(filename, &keyBlock, &keycnt); - if (res != PM3_SUCCESS) { + if (res > 0) { free(keyBlock); - return res; + return PM3_EFILE; } pre = calloc(keycnt, sizeof(iclass_premac_t)); @@ -2312,33 +2312,33 @@ static int CmdHFiClassLookUp(const char *Cmd) { PrintAndLogEx(SUCCESS, "MAC_TAG | %s", sprint_hex(MAC_TAG, sizeof(MAC_TAG))); int res = LoadDictionaryKeyFile(filename, &keyBlock, &keycnt); - if (res != PM3_SUCCESS) { + if (res > 0) { free(keyBlock); - return res; + return 1; } //iclass_prekey_t prekey = calloc(keycnt, sizeof(iclass_prekey_t)); if (!prekey) { free(keyBlock); - return PM3_EMALLOC; + return 1; } - PrintAndLogEx(INFO, "Generating diversified keys and MAC"); + PrintAndLogEx(FAILED, "Generating diversified keys and MAC"); res = GenerateFromKeyFile(CSN, CCNR, use_raw, use_elite, keyBlock, keycnt, prekey); - if (res != PM3_SUCCESS) { + if (res > 0) { free(keyBlock); free(prekey); - return PM3_ESOFT; + return 1; } - PrintAndLogEx(INFO, "Sorting"); + PrintAndLogEx(FAILED, "Sorting"); // sort mac list. qsort(prekey, keycnt, sizeof(iclass_prekey_t), cmp_uint32); //PrintPreCalc(prekey, keycnt); - PrintAndLogEx(INFO, "Searching"); + PrintAndLogEx(FAILED, "Searching"); iclass_prekey_t *item; iclass_prekey_t lookup; memcpy(lookup.mac, MAC_TAG, 4); @@ -2377,19 +2377,10 @@ int LoadDictionaryKeyFile(char *filename, uint8_t **keys, int *keycnt) { uint8_t *p; int keyitems = 0; - - char *dict_path; - int res = searchFile(&dict_path, DICTIONARIES_SUBDIR, filename, ".dic"); - if (res != PM3_SUCCESS) { - return res; + if (!(f = fopen(filename, "r"))) { + PrintAndLogEx(FAILED, "File: " _YELLOW_("%s") ": not found or locked.", filename); + return 1; } - f = fopen(dict_path, "r"); - if (!f) { - PrintAndLogEx(FAILED, "File: " _YELLOW_("%s") ": not found or locked.", dict_path); - free(dict_path); - return PM3_EFILE; - } - free(dict_path); while (fgets(buf, sizeof(buf), f)) { if (strlen(buf) < 16 || buf[15] == '\n') @@ -2405,8 +2396,7 @@ int LoadDictionaryKeyFile(char *filename, uint8_t **keys, int *keycnt) { // doesn't this only test first char only? if (!isxdigit(buf[0])) { PrintAndLogEx(ERR, "file content error. '%s' must include 16 HEX symbols", buf); - fclose(f); - return PM3_EFILE; + continue; } // null terminator (skip the rest of the line) @@ -2416,7 +2406,7 @@ int LoadDictionaryKeyFile(char *filename, uint8_t **keys, int *keycnt) { if (!p) { PrintAndLogEx(ERR, "cannot allocate memory for default keys"); fclose(f); - return PM3_EMALLOC; + return 2; } *keys = p; From 236c2eb1d067f93a9df1608ac8ecd41d18f9b69a Mon Sep 17 00:00:00 2001 From: Matthias Konrath Date: Mon, 26 Aug 2019 14:29:21 +0200 Subject: [PATCH 0445/1854] Changed createKeyDump to a less generic name (createMfcKeyDump). --- client/cmdhfmf.c | 31 +++---------------------------- client/fileutils.c | 2 +- client/fileutils.h | 2 +- 3 files changed, 5 insertions(+), 30 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 1fb2d48ff..33f29f4d5 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -2059,7 +2059,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { // Transfere the found keys to the simulator and dump the keys and card data PrintAndLogEx(NORMAL, ""); PrintAndLogEx(INFO, "Dumping the keys:"); - createKeyDump(sectors_cnt, e_sector, GenerateFilename("hf-mf-", "-key.bin")); + createMfcKeyDump(sectors_cnt, e_sector, GenerateFilename("hf-mf-", "-key.bin")); PrintAndLogEx(SUCCESS, "Transfering the found keys to the simulator memory (Cmd Error: 04 can occour, but this shouldn't be a problem)"); for (current_sector_i=0; current_sector_i < sectors_cnt; current_sector_i++) { @@ -2352,7 +2352,7 @@ out: if (createDumpFile) { fptr = GenerateFilename("hf-mf-", "-key.bin"); - createKeyDump(sectorsCnt, e_sector, fptr); + createMfcKeyDump(sectorsCnt, e_sector, fptr); } } @@ -2378,7 +2378,6 @@ static int CmdHF14AMfChk(const char *Cmd) { uint8_t keyType = 0; uint32_t keyitems = ARRAYLEN(g_mifare_default_keys); uint64_t key64 = 0; - uint8_t tempkey[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; char *fptr; int clen = 0; int transferToEml = 0; @@ -2633,31 +2632,7 @@ out: if (createDumpFile) { fptr = GenerateFilename("hf-mf-", "-key.bin"); - if (fptr == NULL) { - free(keyBlock); - free(e_sector); - return PM3_EFILE; - } - - FILE *fkeys = fopen(fptr, "wb"); - if (fkeys == NULL) { - PrintAndLogEx(WARNING, "Could not create file " _YELLOW_("%s"), fptr); - free(keyBlock); - free(e_sector); - return PM3_EFILE; - } - PrintAndLogEx(INFO, "Printing keys to binary file " _YELLOW_("%s")"...", fptr); - - for (i = 0; i < SectorsCnt; i++) { - num_to_bytes(e_sector[i].Key[0], 6, tempkey); - fwrite(tempkey, 1, 6, fkeys); - } - for (i = 0; i < SectorsCnt; i++) { - num_to_bytes(e_sector[i].Key[1], 6, tempkey); - fwrite(tempkey, 1, 6, fkeys); - } - fclose(fkeys); - PrintAndLogEx(SUCCESS, "Found keys have been dumped to file " _YELLOW_("%s")". 0xffffffffffff has been inserted for unknown keys.", fptr); + createMfcKeyDump(SectorsCnt, e_sector, fptr); } free(keyBlock); diff --git a/client/fileutils.c b/client/fileutils.c index 124a51edc..3128fd451 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -293,7 +293,7 @@ out: return retval; } -int createKeyDump(uint8_t sectorsCnt, sector_t *e_sector, char* fptr) { +int createMfcKeyDump(uint8_t sectorsCnt, sector_t *e_sector, char* fptr) { uint8_t tmpKey[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; int i; diff --git a/client/fileutils.h b/client/fileutils.h index 61b7b0468..c0dad645b 100644 --- a/client/fileutils.h +++ b/client/fileutils.h @@ -112,7 +112,7 @@ int saveFileJSON(const char *preferredName, JSONFileType ftype, uint8_t *data, s * @param fptr string pointer to the filename * @return 0 for ok, 1 for failz */ -int createKeyDump(uint8_t sectorsCnt, sector_t *e_sector, char* fptr); +int createMfcKeyDump(uint8_t sectorsCnt, sector_t *e_sector, char* fptr); /** STUB * @brief Utility function to load data from a binary file. This method takes a preferred name. From 917d76bcc1b3f3868387ec3602903abf32622d64 Mon Sep 17 00:00:00 2001 From: Matthias Konrath Date: Mon, 26 Aug 2019 14:58:24 +0200 Subject: [PATCH 0446/1854] Added changelog message for the autopwn feature. --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b8434cc84..253d981f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] - + - Add autopwn command to break mifare classic cards completely automatic (breaks all sector keys and dumps them and the card content) - Add Lua paths: look for scripts also in ~/.proxmark/lua{scripts,libs} and /usr/local/share/proxmark3/lua{scripts,libs} (@doegox) - Change Lua directory scripts/ to luascript/ (@doegox) - Change non-rdv4 PLATFORM must now use the generic PM3OTHER, simpler (@doegox) From bdd6ef98b5d4608fc413fe02e856646aba287b60 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 26 Aug 2019 20:34:16 +0200 Subject: [PATCH 0447/1854] fix autopwn help --- client/cmdhfmf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 003fa0cf2..a1fe25457 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -1689,7 +1689,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { break; default: PrintAndLogEx(WARNING, "Unknown parameter '%c'\n", ctmp); - usage_hf14_hardnested(); + usage_hf14_autopwn(); return 1; } cmdp++; From 1368595be11f8f035ea331b56457c4646b1251e3 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 26 Aug 2019 20:37:33 +0200 Subject: [PATCH 0448/1854] hf mf nested: swap loops for faster results (try harder to break keyA first) --- client/cmdhfmf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index a1fe25457..d3199c429 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -1243,9 +1243,9 @@ static int CmdHF14AMfNested(const char *Cmd) { // int iterations = 0; bool calibrate = true; - for (int i = 0; i < MIFARE_SECTOR_RETRY; i++) { + for (trgKeyType = 0; trgKeyType < 2; ++trgKeyType) { for (uint8_t sectorNo = 0; sectorNo < SectorsCnt; ++sectorNo) { - for (trgKeyType = 0; trgKeyType < 2; ++trgKeyType) { + for (int i = 0; i < MIFARE_SECTOR_RETRY; i++) { if (e_sector[sectorNo].foundKey[trgKeyType]) continue; From d838c816014fe947803c2fdb5cf7a92f470d6247 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 26 Aug 2019 20:57:23 +0200 Subject: [PATCH 0449/1854] hf mf attacks: rewordings --- client/cmdhfmf.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index d3199c429..26fffaf42 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -41,7 +41,7 @@ static int CmdHelp(const char *Cmd); static int usage_hf14_ice(void) { - PrintAndLogEx(NORMAL, "Usage: hf mf ice [l] [f] "); + PrintAndLogEx(NORMAL, "Usage: hf mf ice [l ] [f ]"); PrintAndLogEx(NORMAL, " h this help"); PrintAndLogEx(NORMAL, " l nonces to be collected"); PrintAndLogEx(NORMAL, " f save nonces to instead of hf-mf--nonces.bin"); @@ -53,7 +53,7 @@ static int usage_hf14_ice(void) { } static int usage_hf14_dump(void) { - PrintAndLogEx(NORMAL, "Usage: hf mf dump [card memory] k f "); + PrintAndLogEx(NORMAL, "Usage: hf mf dump [card memory] [k ] [f ]"); PrintAndLogEx(NORMAL, " [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K"); PrintAndLogEx(NORMAL, " k : key filename, if no given, UID will be used as filename"); PrintAndLogEx(NORMAL, " f : data filename, if no given, UID will be used as filename"); @@ -65,7 +65,7 @@ static int usage_hf14_dump(void) { } static int usage_hf14_mifare(void) { - PrintAndLogEx(NORMAL, "Usage: hf mf darkside [h] "); + PrintAndLogEx(NORMAL, "Usage: hf mf darkside "); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h this help"); PrintAndLogEx(NORMAL, " (Optional) target other block"); @@ -77,7 +77,7 @@ static int usage_hf14_mifare(void) { return 0; } static int usage_hf14_mfsim(void) { - PrintAndLogEx(NORMAL, "Usage: hf mf sim [h] u n [i] [x] [e] [v]"); + PrintAndLogEx(NORMAL, "Usage: hf mf sim [u ] [n ] [t] [a ] [s ] [i] [x] [e] [v]"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h this help"); PrintAndLogEx(NORMAL, " u (Optional) UID 4,7 or 10bytes. If not specified, the UID 4b/7b from emulator memory will be used"); @@ -169,26 +169,26 @@ static int usage_hf14_hardnested(void) { static int usage_hf14_autopwn(void) { PrintAndLogEx(NORMAL, "Usage:"); PrintAndLogEx(NORMAL, " hf mf autopwn [k] "); - PrintAndLogEx(NORMAL, " [*] [f] .dic [s] [i] [l] [v]"); + PrintAndLogEx(NORMAL, " [* ] [f [.dic]] [s] [i ] [l] [v]"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Description:"); - PrintAndLogEx(NORMAL, " This command is used to automate the attack process on mifare classic nfc cards."); + PrintAndLogEx(NORMAL, " This command is used to automate the attack process on mifare classic cards."); PrintAndLogEx(NORMAL, " The program tries to identify the prng type and then automatically attack it with the best algorithm."); - PrintAndLogEx(NORMAL, " After the program is done, the keys and card data is dumped."); + PrintAndLogEx(NORMAL, " At the end, the keys and card data are dumped."); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h this help"); - PrintAndLogEx(NORMAL, " k if a known key for a block is supplied"); - PrintAndLogEx(NORMAL, " f .dic dictionary file for key discovery (the file has to end in .dic) max 2000 entries allowed"); - PrintAndLogEx(NORMAL, " s slower acquisition (required by some non standard cards) for hardnested"); - PrintAndLogEx(NORMAL, " v verbose output (statistcs)"); + PrintAndLogEx(NORMAL, " k if a known key for a block is supplied"); + PrintAndLogEx(NORMAL, " f [.dic] dictionary file for key discovery (the file has to end in .dic, max 2000 entries allowed)"); + PrintAndLogEx(NORMAL, " s slower acquisition for hardnested (required by some non standard cards)"); + PrintAndLogEx(NORMAL, " v verbose output (statistics)"); PrintAndLogEx(NORMAL, " l legacy mode (use the slow mfchk for the key enumeration)"); - PrintAndLogEx(NORMAL, " * all sectors based on card memory, other values then below defaults to 1k"); + PrintAndLogEx(NORMAL, " * all sectors based on card memory. Default: 1K"); PrintAndLogEx(NORMAL, " * 0 = MINI(320 bytes)"); PrintAndLogEx(NORMAL, " * 1 = 1K"); PrintAndLogEx(NORMAL, " * 2 = 2K"); PrintAndLogEx(NORMAL, " * 4 = 4K"); - PrintAndLogEx(NORMAL, " i set type of SIMD instructions. Without this flag programs autodetect it. (for hardnested)"); + PrintAndLogEx(NORMAL, " i set type of SIMD instructions for hardnested. Default: autodetection."); PrintAndLogEx(NORMAL, " i 5 = AVX512"); PrintAndLogEx(NORMAL, " i 2 = AVX2"); PrintAndLogEx(NORMAL, " i a = AVX"); @@ -198,9 +198,9 @@ static int usage_hf14_autopwn(void) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf mf autopwn"); - PrintAndLogEx(NORMAL, " hf mf autopwn * 1 f default_keys"); + PrintAndLogEx(NORMAL, " hf mf autopwn * 1 f mfc_default_keys"); PrintAndLogEx(NORMAL, " hf mf autopwn k 0 A FFFFFFFFFFFF"); - PrintAndLogEx(NORMAL, " hf mf autopwn k 0 A FFFFFFFFFFFF * 1 f default_keys"); + PrintAndLogEx(NORMAL, " hf mf autopwn k 0 A FFFFFFFFFFFF * 1 f mfc_default_keys"); PrintAndLogEx(NORMAL, " hf mf autopwn k 0 A FFFFFFFFFFFF * 4 i 5"); return 0; } @@ -2027,12 +2027,12 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { } // Check if the key was found if (e_sector[current_sector_i].foundKey[current_key_type_i] != 0) { - PrintAndLogEx(SUCCESS, "[BROCKEN KEY] Valid KEY FOUND: sector:%3d key type:%c key: " _YELLOW_("0x%02x%02x%02x%02x%02x%02x"), + PrintAndLogEx(SUCCESS, "[TESTING KEY] Valid KEY FOUND: sector:%3d key type:%c key: " _YELLOW_("0x%02x%02x%02x%02x%02x%02x"), current_sector_i, current_key_type_i ? 'B' : 'A', tmp_key[0], tmp_key[1], tmp_key[2], tmp_key[3], tmp_key[4], tmp_key[5]); } else { - PrintAndLogEx(FAILED, "[BROCKEN KEY] Valid KEY NOT FOUND: sector:%3d key type:%c key: " _YELLOW_("0x%02x%02x%02x%02x%02x%02x"), + PrintAndLogEx(FAILED, "[TESTING KEY] Valid KEY NOT FOUND: sector:%3d key type:%c key: " _YELLOW_("0x%02x%02x%02x%02x%02x%02x"), current_sector_i, current_key_type_i ? 'B' : 'A', tmp_key[0], tmp_key[1], tmp_key[2], tmp_key[3], tmp_key[4], tmp_key[5]); From 9c677e045e04224e00b036a15f407f34ff607b79 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 26 Aug 2019 22:21:23 +0200 Subject: [PATCH 0450/1854] mf autopwn: try nested harder before hardnested; typos --- client/cmdhfmf.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 26fffaf42..32aa03c73 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -1858,7 +1858,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { i2 ? 'B' : 'A', tmp_key[0], tmp_key[1], tmp_key[2], tmp_key[3], tmp_key[4], tmp_key[5]); - // Store vaild credentials for the nested / hardnested attack if none exist + // Store valid credentials for the nested / hardnested attack if none exist if (know_target_key == false) { num_to_bytes(e_sector[i].Key[i2], 6, key); know_target_key = true; @@ -1901,9 +1901,9 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { break; } num_to_bytes(key64, 6, key); - // Check if the darkside key is vaild + // Check if the darkside key is valid if (mfCheckKeys(FirstBlockOfSector(blockNo), keyType, true, 1, key, &key64) != PM3_SUCCESS) { - PrintAndLogEx(FAILED, "The key generated by the darkside attack is not vaild!" + PrintAndLogEx(FAILED, "The key generated by the darkside attack is not valid!" _RED_("%3d") " key type:"_RED_("%c") " key: " _RED_("0x%02x%02x%02x%02x%02x%02x"), blockNo, keyType ? 'B' : 'A', @@ -1924,6 +1924,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { free(keyBlock); // Clear the needed variables num_to_bytes(0, 6, tmp_key); + bool nested_failed = false; // Iterate over each sector and key(A/B) for (current_sector_i=0; current_sector_i < sectors_cnt; current_sector_i++) { @@ -1958,7 +1959,9 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { // Use the nested / hardnested attack if (e_sector[current_sector_i].foundKey[current_key_type_i] == 0) { - if (prng_type) { + if (prng_type && (! nested_failed)) { + uint8_t retries = 0; +tryNested: PrintAndLogEx(INFO, "[ NESTED ] Sector no:%3d, target key type:%c", current_sector_i, current_key_type_i ? 'B' : 'A'); @@ -1982,8 +1985,15 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { break; case -4 : //key not found calibrate = false; - PrintAndLogEx(FAILED, "Nested attack failed --> try hardnested instead!"); - goto tryHardnested; + // this can happen on some old cards, it's worth trying some more before switching to slower hardnested + if (retries++ < MIFARE_SECTOR_RETRY) { + PrintAndLogEx(FAILED, "Nested attack failed, trying again (%i/%i)", retries, MIFARE_SECTOR_RETRY); + goto tryNested; + } else { + PrintAndLogEx(FAILED, "Nested attack failed, moving to hardnested"); + nested_failed = true; + goto tryHardnested; + } break; case -5 : calibrate = false; @@ -1997,7 +2007,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { break; } } else { - tryHardnested: // If the nested attack failes then we try the hardnested attack +tryHardnested: // If the nested attack fails then we try the hardnested attack PrintAndLogEx(INFO, "[ HARDNESTED ] Sector no:%3d, target key type:%c, Slow: %s", current_sector_i, current_key_type_i ? 'B' : 'A', @@ -2061,7 +2071,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { PrintAndLogEx(INFO, "Dumping the keys:"); createMfcKeyDump(sectors_cnt, e_sector, GenerateFilename("hf-mf-", "-key.bin")); - PrintAndLogEx(SUCCESS, "Transfering the found keys to the simulator memory (Cmd Error: 04 can occour, but this shouldn't be a problem)"); + PrintAndLogEx(SUCCESS, "Transferring the found keys to the simulator memory (Cmd Error: 04 can occur, but this shouldn't be a problem)"); for (current_sector_i=0; current_sector_i < sectors_cnt; current_sector_i++) { mfEmlGetMem(block, current_sector_i, 1); if (e_sector[current_sector_i].foundKey[0]) From 16a7cfd7b2066c46ba2a6e527e4721677127a596 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 26 Aug 2019 22:28:39 +0200 Subject: [PATCH 0451/1854] make style (excepted cmdhficlass...) --- armsrc/mifarecmd.c | 6 +- armsrc/pcf7931.c | 3 +- client/cmdhfmf.c | 176 +++++++++++++++------------- client/fileutils.c | 18 ++- client/fileutils.h | 2 +- client/loclass/cipherutils.c | 2 +- client/loclass/elite_crack.c | 20 ++-- client/scripting.c | 4 +- tools/fpga_compress/fpga_compress.c | 4 +- 9 files changed, 120 insertions(+), 115 deletions(-) diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 985a787ca..63cf1128d 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -1992,9 +1992,9 @@ TEST2: int res = iso14443a_select_card(uid, NULL, &cuid, true, 0, true); if (res == 2) { - if (cuid == 0xAA55C396 ) { - isGen = GEN_UNFUSED; - goto OUT; + if (cuid == 0xAA55C396) { + isGen = GEN_UNFUSED; + goto OUT; } ReaderTransmit(rats, sizeof(rats), NULL); diff --git a/armsrc/pcf7931.c b/armsrc/pcf7931.c index 9f1283b8c..82865b311 100644 --- a/armsrc/pcf7931.c +++ b/armsrc/pcf7931.c @@ -232,8 +232,7 @@ void ReadPCF7931() { } Dbprintf("(dbg) got %d blocks (%d/%d found) (%d tries, %d errors)", n, found_blocks, (max_blocks == 0 ? found_blocks : max_blocks), tries, errors); - for (i = 0; i < n; ++i) - { + for (i = 0; i < n; ++i) { print_result("got consecutive blocks", tmp_blocks[i], 16); } diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 32aa03c73..0783f5d3f 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -1601,7 +1601,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { uint8_t block[16] = {0x00}; uint8_t *dump; int bytes; - char* fnameptr = filename; + char *fnameptr = filename; // Settings bool slow = false; bool legacy_mfchk = false; @@ -1616,7 +1616,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { case 'h': return usage_hf14_autopwn(); case 'f': - if (param_getstr(Cmd, cmdp +1, filename, FILE_PATH_SIZE) >= FILE_PATH_SIZE) { + if (param_getstr(Cmd, cmdp + 1, filename, FILE_PATH_SIZE) >= FILE_PATH_SIZE) { PrintAndLogEx(FAILED, "Filename too long"); } cmdp ++; @@ -1699,8 +1699,8 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { e_sector = calloc(sectors_cnt, sizeof(sector_t)); if (e_sector == NULL) return PM3_EMALLOC; // Clear the key storage datastructure - for (i=0; i just be nice and correct it ;) if (know_target_key == false) { num_to_bytes(e_sector[i].Key[i2], 6, key); know_target_key = true; - blockNo = i; keyType = i2; + blockNo = i; + keyType = i2; PrintAndLogEx(SUCCESS, "[ SETTINGS ] The following key will be used for the nested / hardnested attack: sector:" - _RED_("%3d") " key type:"_RED_("%c") " key: " _RED_("0x%02x%02x%02x%02x%02x%02x"), - blockNo, - keyType ? 'B' : 'A', - key[0], key[1], key[2], key[3], key[4], key[5]); + _RED_("%3d") " key type:"_RED_("%c") " key: " _RED_("0x%02x%02x%02x%02x%02x%02x"), + blockNo, + keyType ? 'B' : 'A', + key[0], key[1], key[2], key[3], key[4], key[5]); } - } + } } } } @@ -1793,24 +1794,25 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { for (int cnt = 0; cnt < ARRAYLEN(g_mifare_default_keys); cnt++) { num_to_bytes(g_mifare_default_keys[cnt], 6, keyBlock + cnt * 6); } - key_cnt = ARRAYLEN(g_mifare_default_keys); - } - + key_cnt = ARRAYLEN(g_mifare_default_keys); + } + // Start the timer t1 = msclock(); // Use the dictionary to find sector keys on the card PrintAndLogEx(INFO, "Enumerating the card keys with the dictionary!"); if (legacy_mfchk) { - // Check all the sectors - for (i=0; i (PM3_CMD_DATA_SIZE / 6) ? (PM3_CMD_DATA_SIZE / 6) : key_cnt; bool firstChunk = true, lastChunk = false; @@ -1829,7 +1832,9 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { if (kbd_enter_pressed()) { PrintAndLogEx(WARNING, "\naborted via keyboard!\n"); - i = key_cnt; strategy = 3; break; // Exit the loop + i = key_cnt; + strategy = 3; + break; // Exit the loop } uint32_t size = ((key_cnt - i) > chunksize) ? chunksize : key_cnt - i; // last chunk? @@ -1840,7 +1845,9 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { firstChunk = false; // all keys, aborted if (res == 0 || res == 2) { - i = key_cnt; strategy = 3; break; // Exit the loop + i = key_cnt; + strategy = 3; + break; // Exit the loop } } // end chunks of keys firstChunk = true; @@ -1849,25 +1856,26 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { } // Analyse the dictionary attack - for (i=0; i The fast check --> mfCheckKeys_fast(sectors_cnt, true, true, 2, 1, tmp_key, e_sector, false); // Returns false keys, so we just stick to the slower mfchk. - for (i=0; id_name[0] != '.')) || (str_endswith(namelist[i]->d_name, ext))) { - PrintAndLogEx(NORMAL, "%s   %s── %-21s", last ? " ":"│", i == n-1 ? "└" : "├", namelist[i]->d_name); + PrintAndLogEx(NORMAL, "%s   %s── %-21s", last ? " " : "│", i == n - 1 ? "└" : "├", namelist[i]->d_name); } free(namelist[i]); } @@ -727,19 +727,17 @@ int searchAndList(const char *pm3dir, const char *ext) { } static int searchFinalFile(char **foundpath, const char *pm3dir, const char *searchname) { - if ((foundpath == NULL)||(pm3dir == NULL)||(searchname == NULL)) return PM3_ESOFT; + if ((foundpath == NULL) || (pm3dir == NULL) || (searchname == NULL)) return PM3_ESOFT; // explicit absolute (/) or relative path (./) => try only to match it directly char *filename = calloc(strlen(searchname) + 1, sizeof(char)); if (filename == NULL) return PM3_EMALLOC; strcpy(filename, searchname); if (((strlen(filename) > 1) && (filename[0] == '/')) || - ((strlen(filename) > 2) && (filename[0] == '.') && (filename[1] == '/'))) - { + ((strlen(filename) > 2) && (filename[0] == '.') && (filename[1] == '/'))) { if (fileExists(filename)) { *foundpath = filename; return PM3_SUCCESS; - } - else { + } else { goto out; } } diff --git a/client/fileutils.h b/client/fileutils.h index 25fe0a885..03a47112e 100644 --- a/client/fileutils.h +++ b/client/fileutils.h @@ -111,7 +111,7 @@ int saveFileJSON(const char *preferredName, JSONFileType ftype, uint8_t *data, s * @param fptr string pointer to the filename * @return 0 for ok, 1 for failz */ -int createMfcKeyDump(uint8_t sectorsCnt, sector_t *e_sector, char* fptr); +int createMfcKeyDump(uint8_t sectorsCnt, sector_t *e_sector, char *fptr); /** STUB * @brief Utility function to load data from a binary file. This method takes a preferred name. diff --git a/client/loclass/cipherutils.c b/client/loclass/cipherutils.c index 52ac82f94..ee440fb73 100644 --- a/client/loclass/cipherutils.c +++ b/client/loclass/cipherutils.c @@ -160,7 +160,7 @@ void printarr(const char *name, uint8_t *arr, int len) { } void printvar(const char *name, uint8_t *arr, int len) { - PrintAndLogEx(NORMAL, "%s = " _YELLOW_("%s"), name, sprint_hex(arr, len) ); + PrintAndLogEx(NORMAL, "%s = " _YELLOW_("%s"), name, sprint_hex(arr, len)); } void printarr_human_readable(const char *title, uint8_t *arr, int len) { diff --git a/client/loclass/elite_crack.c b/client/loclass/elite_crack.c index 74ebfe608..69b17c50f 100644 --- a/client/loclass/elite_crack.c +++ b/client/loclass/elite_crack.c @@ -479,7 +479,7 @@ int calculateMasterKey(uint8_t first16bytes[], uint64_t master_key[]) { return 1; } else { PrintAndLogEx(NORMAL, "\n"); - PrintAndLogEx(SUCCESS, _GREEN_("Key verified ok!") ); + PrintAndLogEx(SUCCESS, _GREEN_("Key verified ok!")); } return 0; } @@ -502,18 +502,18 @@ int bruteforceDump(uint8_t dump[], size_t dumpsize, uint16_t keytable[]) { for (i = 0 ; i * itemsize < dumpsize ; i++) { memcpy(attack, dump + i * itemsize, itemsize); errors += bruteforceItem(*attack, keytable); - if ( errors ) - break; + if (errors) + break; } free(attack); t1 = msclock() - t1; PrintAndLogEx(SUCCESS, "time: %" PRIu64 " seconds", t1 / 1000); - - if ( errors ) { - PrintAndLogEx(ERR, "loclass exiting. Try run " _YELLOW_("`hf iclass sim 2`") "again and collect new data"); - return 1; - } + + if (errors) { + PrintAndLogEx(ERR, "loclass exiting. Try run " _YELLOW_("`hf iclass sim 2`") "again and collect new data"); + return 1; + } // Pick out the first 16 bytes of the keytable. // The keytable is now in 16-bit ints, where the upper 8 bits @@ -526,8 +526,8 @@ int bruteforceDump(uint8_t dump[], size_t dumpsize, uint16_t keytable[]) { if (!(keytable[i] & CRACKED)) { PrintAndLogEx(WARNING, "Warning: we are missing byte %d, custom key calculation will fail...", i); - return 1; - } + return 1; + } } errors += calculateMasterKey(first16bytes, NULL); return errors; diff --git a/client/scripting.c b/client/scripting.c index dc3051207..5a3eaed61 100644 --- a/client/scripting.c +++ b/client/scripting.c @@ -1158,7 +1158,7 @@ int set_pm3_libraries(lua_State *L) { strcat(scripts_path, LUA_LIBRARIES_WILDCARD); setLuaPath(L, scripts_path); - // from the ~/.proxmark3/lualib/ directory + // from the ~/.proxmark3/lualib/ directory char libraries_path[strlen(user_path) + strlen(PM3_USER_DIRECTORY) + strlen(LUA_LIBRARIES_SUBDIR) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; strcpy(libraries_path, user_path); strcat(libraries_path, PM3_USER_DIRECTORY); @@ -1167,7 +1167,7 @@ int set_pm3_libraries(lua_State *L) { setLuaPath(L, libraries_path); } - if (strlen(PM3_SHARE_PATH) != 0 || strlen(LUA_SCRIPTS_SUBDIR) != 0 || strlen(LUA_LIBRARIES_WILDCARD) != 0 ) { + if (strlen(PM3_SHARE_PATH) != 0 || strlen(LUA_SCRIPTS_SUBDIR) != 0 || strlen(LUA_LIBRARIES_WILDCARD) != 0) { // from the /usr/local/share/proxmark3/luascripts/ directory char scripts_path[strlen(PM3_SHARE_PATH) + strlen(LUA_SCRIPTS_SUBDIR) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; strcpy(scripts_path, PM3_SHARE_PATH); diff --git a/tools/fpga_compress/fpga_compress.c b/tools/fpga_compress/fpga_compress.c index bac6a1670..54d2438d2 100644 --- a/tools/fpga_compress/fpga_compress.c +++ b/tools/fpga_compress/fpga_compress.c @@ -337,8 +337,8 @@ static int FpgaGatherVersion(FILE *infile, char *infile_name, char *dst, int len for (uint16_t i = 0; i < fpga_info_len; i++) { char c = (char)fgetc(infile); if (i < sizeof(tempstr)) { - if ( c == '/' ) c = '-'; - if ( c == ' ' ) c = '0'; + if (c == '/') c = '-'; + if (c == ' ') c = '0'; tempstr[i] = c; } } From 1e648088b1ed45b864ea566e9b9107d0670ec246 Mon Sep 17 00:00:00 2001 From: Matthias Konrath Date: Mon, 26 Aug 2019 21:24:29 +0200 Subject: [PATCH 0452/1854] Improved the help message of the autopwn command. --- client/cmdhfmf.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 0783f5d3f..af2db10ab 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -173,8 +173,7 @@ static int usage_hf14_autopwn(void) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Description:"); PrintAndLogEx(NORMAL, " This command is used to automate the attack process on mifare classic cards."); - PrintAndLogEx(NORMAL, " The program tries to identify the prng type and then automatically attack it with the best algorithm."); - PrintAndLogEx(NORMAL, " At the end, the keys and card data are dumped."); + PrintAndLogEx(NORMAL, " It uses the darkside, nested and hardnested attack to extract the keys and card content."); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h this help"); @@ -197,11 +196,10 @@ static int usage_hf14_autopwn(void) { PrintAndLogEx(NORMAL, " i n = none (use CPU regular instruction set)"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf mf autopwn"); - PrintAndLogEx(NORMAL, " hf mf autopwn * 1 f mfc_default_keys"); - PrintAndLogEx(NORMAL, " hf mf autopwn k 0 A FFFFFFFFFFFF"); - PrintAndLogEx(NORMAL, " hf mf autopwn k 0 A FFFFFFFFFFFF * 1 f mfc_default_keys"); - PrintAndLogEx(NORMAL, " hf mf autopwn k 0 A FFFFFFFFFFFF * 4 i 5"); + PrintAndLogEx(NORMAL, " hf mf autopwn -- attack a mifare classic card with the default keys"); + PrintAndLogEx(NORMAL, " hf mf autopwn * 1 f mfc_default_keys -- attack a mifare classic card (size 1K) with the default dictionary"); + PrintAndLogEx(NORMAL, " hf mf autopwn k 0 A FFFFFFFFFFFF -- attack a mifare classic card with the known key 'FFFFFFFFFFFF' for sector 0 and key type A"); + PrintAndLogEx(NORMAL, " hf mf autopwn k 0 A FFFFFFFFFFFF * 1 f mfc_default_keys -- this command combines the two above (reduce the need for nested / hardnested attacks, by using a dictionary)"); return 0; } static int usage_hf14_chk(void) { From 48d3802d3595dc223ee19f95074aca7cd8bdc27c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 27 Aug 2019 10:51:52 +0200 Subject: [PATCH 0453/1854] chg: optimization of iclass mac calculations on deviceside (@pwpiwi) see https://github.com/Proxmark/proxmark3/pull/861 chg: some textual --- CHANGELOG.md | 3 +- armsrc/frozen.c | 2 +- armsrc/optimized_cipher.c | 209 ++++++++++++++++++++--------------- armsrc/optimized_cipher.h | 2 +- client/loclass/elite_crack.c | 2 +- 5 files changed, 125 insertions(+), 93 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 253d981f7..e3db619fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,8 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] - - Add autopwn command to break mifare classic cards completely automatic (breaks all sector keys and dumps them and the card content) + - Chg optimization of iclass mac calculations on deviceside (@pwpiwi) + - Add 'hf mf autopwn' - Autopwn function for Mifare Classic, extract all keys and dump card memory (@matthiaskonrath) - Add Lua paths: look for scripts also in ~/.proxmark/lua{scripts,libs} and /usr/local/share/proxmark3/lua{scripts,libs} (@doegox) - Change Lua directory scripts/ to luascript/ (@doegox) - Change non-rdv4 PLATFORM must now use the generic PM3OTHER, simpler (@doegox) diff --git a/armsrc/frozen.c b/armsrc/frozen.c index 220f51d6c..a43300319 100644 --- a/armsrc/frozen.c +++ b/armsrc/frozen.c @@ -44,7 +44,7 @@ int cs_win_snprintf(char *str, size_t size, const char *format, ...); int cs_win_vsnprintf(char *str, size_t size, const char *format, va_list ap); #if _MSC_VER >= 1700 -#include +#include "stdint.h" #else typedef _int64 int64_t; typedef unsigned _int64 uint64_t; diff --git a/armsrc/optimized_cipher.c b/armsrc/optimized_cipher.c index 4894bf6bc..b03facf93 100644 --- a/armsrc/optimized_cipher.c +++ b/armsrc/optimized_cipher.c @@ -60,11 +60,59 @@ -- MHS 2015 **/ +/** + + The runtime of opt_doTagMAC_2() with the MHS optimized version was 403 microseconds on Proxmark3. + This was still to slow for some newer readers which didn't want to wait that long. + + Further optimizations to speedup the MAC calculations: + * Optimized opt_Tt logic + * Look up table for opt_select + * Removing many unnecessary bit maskings (& 0x1) + * updating state in place instead of alternating use of a second state structure + * remove the necessity to reverse bits of input and output bytes + + opt_doTagMAC_2() now completes in 270 microseconds. + + -- piwi 2019 +**/ + #include "optimized_cipher.h" -#define opt_T(s) (0x1 & ((s->t >> 15) ^ (s->t >> 14)^ (s->t >> 10)^ (s->t >> 8)^ (s->t >> 5)^ (s->t >> 4)^ (s->t >> 1)^ s->t)) +static const uint8_t opt_select_LUT[256] = { + 00, 03, 02, 01, 02, 03, 00, 01, 04, 07, 07, 04, 06, 07, 05, 04, + 01, 02, 03, 00, 02, 03, 00, 01, 05, 06, 06, 05, 06, 07, 05, 04, + 06, 05, 04, 07, 04, 05, 06, 07, 06, 05, 05, 06, 04, 05, 07, 06, + 07, 04, 05, 06, 04, 05, 06, 07, 07, 04, 04, 07, 04, 05, 07, 06, + 06, 05, 04, 07, 04, 05, 06, 07, 02, 01, 01, 02, 00, 01, 03, 02, + 03, 00, 01, 02, 00, 01, 02, 03, 07, 04, 04, 07, 04, 05, 07, 06, + 00, 03, 02, 01, 02, 03, 00, 01, 00, 03, 03, 00, 02, 03, 01, 00, + 05, 06, 07, 04, 06, 07, 04, 05, 05, 06, 06, 05, 06, 07, 05, 04, + 02, 01, 00, 03, 00, 01, 02, 03, 06, 05, 05, 06, 04, 05, 07, 06, + 03, 00, 01, 02, 00, 01, 02, 03, 07, 04, 04, 07, 04, 05, 07, 06, + 02, 01, 00, 03, 00, 01, 02, 03, 02, 01, 01, 02, 00, 01, 03, 02, + 03, 00, 01, 02, 00, 01, 02, 03, 03, 00, 00, 03, 00, 01, 03, 02, + 04, 07, 06, 05, 06, 07, 04, 05, 00, 03, 03, 00, 02, 03, 01, 00, + 01, 02, 03, 00, 02, 03, 00, 01, 05, 06, 06, 05, 06, 07, 05, 04, + 04, 07, 06, 05, 06, 07, 04, 05, 04, 07, 07, 04, 06, 07, 05, 04, + 01, 02, 03, 00, 02, 03, 00, 01, 01, 02, 02, 01, 02, 03, 01, 00 +}; -#define opt_B(s) (((s->b >> 6) ^ (s->b >> 5) ^ (s->b >> 4) ^ (s->b)) & 0x1) +/********************** the table above has been generated with this code: ******** +#include "util.h" +static void init_opt_select_LUT(void) { + for (int r = 0; r < 256; r++) { + uint8_t r_ls2 = r << 2; + uint8_t r_and_ls2 = r & r_ls2; + uint8_t r_or_ls2 = r | r_ls2; + uint8_t z0 = (r_and_ls2 >> 5) ^ ((r & ~r_ls2) >> 4) ^ ( r_or_ls2 >> 3); + uint8_t z1 = (r_or_ls2 >> 6) ^ ( r_or_ls2 >> 1) ^ (r >> 5) ^ r; + uint8_t z2 = ((r & ~r_ls2) >> 4) ^ (r_and_ls2 >> 3) ^ r; + opt_select_LUT[r] = (z0 & 4) | (z1 & 2) | (z2 & 1); + } + print_result("", opt_select_LUT, 256); +} +***********************************************************************************/ #define opt__select(x,y,r) (4 & (((r & (r << 2)) >> 5) ^ ((r & ~(r << 2)) >> 4) ^ ( (r | r << 2) >> 3)))\ |(2 & (((r | r << 2) >> 6) ^ ( (r | r << 2) >> 1) ^ (r >> 5) ^ r ^ ((x^y) << 1)))\ @@ -74,9 +122,6 @@ * Some background on the expression above can be found here... uint8_t xopt__select(bool x, bool y, uint8_t r) { - uint8_t r_ls2 = r << 2; - uint8_t r_and_ls2 = r & r_ls2; - uint8_t r_or_ls2 = r | r_ls2; //r: r0 r1 r2 r3 r4 r5 r6 r7 //r_ls2: r2 r3 r4 r5 r6 r7 0 0 @@ -96,82 +141,95 @@ uint8_t xopt__select(bool x, bool y, uint8_t r) } */ -void opt_successor(const uint8_t *k, State *s, bool y, State *successor) { - uint8_t Tt = 1 & opt_T(s); +static void opt_successor(const uint8_t *k, State *s, uint8_t y) { +// #define opt_T(s) (0x1 & ((s->t >> 15) ^ (s->t >> 14) ^ (s->t >> 10) ^ (s->t >> 8) ^ (s->t >> 5) ^ (s->t >> 4)^ (s->t >> 1) ^ s->t)) + // uint8_t Tt = opt_T(s); + uint16_t Tt = s->t & 0xc533; + Tt = Tt ^ (Tt >> 1); + Tt = Tt ^ (Tt >> 4); + Tt = Tt ^ (Tt >> 10); + Tt = Tt ^ (Tt >> 8); - successor->t = (s->t >> 1); - successor->t |= (Tt ^ (s->r >> 7 & 0x1) ^ (s->r >> 3 & 0x1)) << 15; + s->t = (s->t >> 1); + s->t |= (Tt ^ (s->r >> 7) ^ (s->r >> 3)) << 15; - successor->b = s->b >> 1; - successor->b |= (opt_B(s) ^ (s->r & 0x1)) << 7; + uint8_t opt_B = s->b; + opt_B ^= s->b >> 6; + opt_B ^= s->b >> 5; + opt_B ^= s->b >> 4; - successor->r = (k[opt__select(Tt, y, s->r)] ^ successor->b) + s->l ; - successor->l = successor->r + s->r; + s->b = s->b >> 1; + s->b |= (opt_B ^ s->r) << 7; + + uint8_t opt_select = opt_select_LUT[s->r] & 0x04; + opt_select |= (opt_select_LUT[s->r] ^ ((Tt ^ y) << 1)) & 0x02; + opt_select |= (opt_select_LUT[s->r] ^ Tt) & 0x01; + + uint8_t r = s->r; + s->r = (k[opt_select] ^ s->b) + s->l ; + s->l = s->r + r; } -void opt_suc(const uint8_t *k, State *s, uint8_t *in, uint8_t length, bool add32Zeroes) { - State x2; +static void opt_suc(const uint8_t *k, State *s, uint8_t *in, uint8_t length, bool add32Zeroes) { for (int i = 0; i < length; i++) { uint8_t head; - head = 1 & (in[i] >> 7); - opt_successor(k, s, head, &x2); + head = in[i]; + opt_successor(k, s, head); - head = 1 & (in[i] >> 6); - opt_successor(k, &x2, head, s); + head >>= 1; + opt_successor(k, s, head); - head = 1 & (in[i] >> 5); - opt_successor(k, s, head, &x2); + head >>= 1; + opt_successor(k, s, head); - head = 1 & (in[i] >> 4); - opt_successor(k, &x2, head, s); + head >>= 1; + opt_successor(k, s, head); - head = 1 & (in[i] >> 3); - opt_successor(k, s, head, &x2); + head >>= 1; + opt_successor(k, s, head); - head = 1 & (in[i] >> 2); - opt_successor(k, &x2, head, s); + head >>= 1; + opt_successor(k, s, head); - head = 1 & (in[i] >> 1); - opt_successor(k, s, head, &x2); + head >>= 1; + opt_successor(k, s, head); - head = 1 & in[i]; - opt_successor(k, &x2, head, s); + head >>= 1; + opt_successor(k, s, head); } - //For tag MAC, an additional 32 zeroes if (add32Zeroes) { for (int i = 0; i < 16; i++) { - opt_successor(k, s, 0, &x2); - opt_successor(k, &x2, 0, s); + opt_successor(k, s, 0); + opt_successor(k, s, 0); } } } -void opt_output(const uint8_t *k, State *s, uint8_t *buffer) { - State temp = {0, 0, 0, 0}; +static void opt_output(const uint8_t *k, State *s, uint8_t *buffer) { for (uint8_t times = 0; times < 4; times++) { uint8_t bout = 0; - bout |= (s->r & 0x4) << 5; - opt_successor(k, s, 0, &temp); - bout |= (temp.r & 0x4) << 4; - opt_successor(k, &temp, 0, s); - bout |= (s->r & 0x4) << 3; - opt_successor(k, s, 0, &temp); - bout |= (temp.r & 0x4) << 2; - opt_successor(k, &temp, 0, s); - bout |= (s->r & 0x4) << 1; - opt_successor(k, s, 0, &temp); - bout |= (temp.r & 0x4) ; - opt_successor(k, &temp, 0, s); + bout |= (s->r & 0x4) >> 2; + opt_successor(k, s, 0); bout |= (s->r & 0x4) >> 1; - opt_successor(k, s, 0, &temp); - bout |= (temp.r & 0x4) >> 2; - opt_successor(k, &temp, 0, s); + opt_successor(k, s, 0); + bout |= (s->r & 0x4); + opt_successor(k, s, 0); + bout |= (s->r & 0x4) << 1; + opt_successor(k, s, 0); + bout |= (s->r & 0x4) << 2; + opt_successor(k, s, 0); + bout |= (s->r & 0x4) << 3; + opt_successor(k, s, 0); + bout |= (s->r & 0x4) << 4; + opt_successor(k, s, 0); + bout |= (s->r & 0x4) << 5; + opt_successor(k, s, 0); buffer[times] = bout; } } -void opt_MAC(uint8_t *k, uint8_t *input, uint8_t *out) { +static void opt_MAC(uint8_t *k, uint8_t *input, uint8_t *out) { State _init = { ((k[0] ^ 0x4c) + 0xEC) & 0xFF,// l ((k[0] ^ 0x4c) + 0x21) & 0xFF,// r @@ -183,45 +241,25 @@ void opt_MAC(uint8_t *k, uint8_t *input, uint8_t *out) { opt_output(k, &_init, out); } -uint8_t rev_byte(uint8_t b) { - b = (b & 0xF0) >> 4 | (b & 0x0F) << 4; - b = (b & 0xCC) >> 2 | (b & 0x33) << 2; - b = (b & 0xAA) >> 1 | (b & 0x55) << 1; - return b; -} - -void opt_reverse_arraybytecpy(uint8_t *dest, uint8_t *src, size_t len) { - uint8_t i; - for (i = 0; i < len ; i++) - dest[i] = rev_byte(src[i]); -} - void opt_doReaderMAC(uint8_t *cc_nr_p, uint8_t *div_key_p, uint8_t mac[4]) { - static uint8_t cc_nr[12]; - opt_reverse_arraybytecpy(cc_nr, cc_nr_p, 12); uint8_t dest [] = {0, 0, 0, 0, 0, 0, 0, 0}; - opt_MAC(div_key_p, cc_nr, dest); - //The output MAC must also be reversed - opt_reverse_arraybytecpy(mac, dest, 4); + opt_MAC(div_key_p, cc_nr_p, dest); + memcpy(mac, dest, 4); return; } + void opt_doTagMAC(uint8_t *cc_p, const uint8_t *div_key_p, uint8_t mac[4]) { - static uint8_t cc_nr[8 + 4 + 4]; - opt_reverse_arraybytecpy(cc_nr, cc_p, 12); State _init = { ((div_key_p[0] ^ 0x4c) + 0xEC) & 0xFF,// l ((div_key_p[0] ^ 0x4c) + 0x21) & 0xFF,// r 0x4c, // b 0xE012 // t }; - opt_suc(div_key_p, &_init, cc_nr, 12, true); - uint8_t dest [] = {0, 0, 0, 0}; - opt_output(div_key_p, &_init, dest); - //The output MAC must also be reversed - opt_reverse_arraybytecpy(mac, dest, 4); + opt_suc(div_key_p, &_init, cc_p, 12, true); + opt_output(div_key_p, &_init, mac); return; - } + /** * The tag MAC can be divided (both can, but no point in dividing the reader mac) into * two functions, since the first 8 bytes are known, we can pre-calculate the state @@ -231,17 +269,16 @@ void opt_doTagMAC(uint8_t *cc_p, const uint8_t *div_key_p, uint8_t mac[4]) { * @return the cipher state */ State opt_doTagMAC_1(uint8_t *cc_p, const uint8_t *div_key_p) { - static uint8_t cc_nr[8]; - opt_reverse_arraybytecpy(cc_nr, cc_p, 8); State _init = { ((div_key_p[0] ^ 0x4c) + 0xEC) & 0xFF,// l ((div_key_p[0] ^ 0x4c) + 0x21) & 0xFF,// r 0x4c, // b 0xE012 // t }; - opt_suc(div_key_p, &_init, cc_nr, 8, false); + opt_suc(div_key_p, &_init, cc_p, 8, false); return _init; } + /** * The second part of the tag MAC calculation, since the CC is already calculated into the state, * this function is fed only the NR, and internally feeds the remaining 32 0-bits to generate the tag @@ -252,13 +289,7 @@ State opt_doTagMAC_1(uint8_t *cc_p, const uint8_t *div_key_p) { * @param div_key_p - the key to use */ void opt_doTagMAC_2(State _init, uint8_t *nr, uint8_t mac[4], const uint8_t *div_key_p) { - static uint8_t _nr[4]; - opt_reverse_arraybytecpy(_nr, nr, 4); - opt_suc(div_key_p, &_init, _nr, 4, true); - - uint8_t dest [] = {0, 0, 0, 0}; - opt_output(div_key_p, &_init, dest); - //The output MAC must also be reversed - opt_reverse_arraybytecpy(mac, dest, 4); + opt_suc(div_key_p, &_init, nr, 4, true); + opt_output(div_key_p, &_init, mac); return; } diff --git a/armsrc/optimized_cipher.h b/armsrc/optimized_cipher.h index 893297ddd..c6df25ab8 100644 --- a/armsrc/optimized_cipher.h +++ b/armsrc/optimized_cipher.h @@ -2,7 +2,7 @@ #define OPTIMIZED_CIPHER_H #include "common.h" - +#include "string.h" /** * Definition 1 (Cipher state). A cipher state of iClass s is an element of F 40/2 * consisting of the following four components: diff --git a/client/loclass/elite_crack.c b/client/loclass/elite_crack.c index 69b17c50f..adf87fb89 100644 --- a/client/loclass/elite_crack.c +++ b/client/loclass/elite_crack.c @@ -475,7 +475,7 @@ int calculateMasterKey(uint8_t first16bytes[], uint64_t master_key[]) { memcpy(master_key, key64, 8); if (memcmp(z_0, result, 4) != 0) { - PrintAndLogEx(WARNING, "Failed to verify calculated master key (k_cus)! Something is wrong."); + PrintAndLogEx(WARNING, _RED_("Failed to verify") "calculated master key (k_cus)! Something is wrong."); return 1; } else { PrintAndLogEx(NORMAL, "\n"); From 703329faca57d8f115ab94d8c31dbe02b321508b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 27 Aug 2019 11:08:03 +0200 Subject: [PATCH 0454/1854] chg: add used known key to found list :) --- client/cmdhfmf.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index af2db10ab..d2004d142 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -751,7 +751,12 @@ static uint8_t NumBlocksPerSector(uint8_t sectorNo) { return 16; } } - +static uint8_t GetSectorFromBlockNo(uint8_t blockNo) { + if ( blockNo < 128 ) + return blockNo / 4; + else + return 32 + ((128 - blockNo) / 16); +} static int CmdHF14AMfDump(const char *Cmd) { uint64_t t1 = msclock(); @@ -1222,6 +1227,10 @@ static int CmdHF14AMfNested(const char *Cmd) { e_sector = calloc(SectorsCnt, sizeof(sector_t)); if (e_sector == NULL) return PM3_EMALLOC; + // add our known key + e_sector[GetSectorFromBlockNo(blockNo)].foundKey[keyType] = 1; + e_sector[GetSectorFromBlockNo(blockNo)].Key[keyType] = key64; + //test current key and additional standard keys first // add parameter key memcpy(keyBlock + (ARRAYLEN(g_mifare_default_keys) * 6), key, 6); From 13aa4ee6ab9fd761e2704b4b8e6565588557f562 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 27 Aug 2019 17:15:42 +0200 Subject: [PATCH 0455/1854] fix: cleaning up 'hf mf autopwn' - reused the fix from below aswell. Add: 'hf mf dump' rename filenames (@mohemiv) see https://github.com/RfidResearchGroup/proxmark3/pull/360 --- client/cmdhfmf.c | 294 ++++++++++++++++++++++++----------------------- 1 file changed, 153 insertions(+), 141 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index d2004d142..030da5a8d 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -172,21 +172,21 @@ static int usage_hf14_autopwn(void) { PrintAndLogEx(NORMAL, " [* ] [f [.dic]] [s] [i ] [l] [v]"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Description:"); - PrintAndLogEx(NORMAL, " This command is used to automate the attack process on mifare classic cards."); + PrintAndLogEx(NORMAL, " This command automates the key recovery process on Mifare classic cards."); PrintAndLogEx(NORMAL, " It uses the darkside, nested and hardnested attack to extract the keys and card content."); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h this help"); - PrintAndLogEx(NORMAL, " k if a known key for a block is supplied"); - PrintAndLogEx(NORMAL, " f [.dic] dictionary file for key discovery (the file has to end in .dic, max 2000 entries allowed)"); + PrintAndLogEx(NORMAL, " k known key is supplied"); + PrintAndLogEx(NORMAL, " f [.dic] key dictionary file"); PrintAndLogEx(NORMAL, " s slower acquisition for hardnested (required by some non standard cards)"); PrintAndLogEx(NORMAL, " v verbose output (statistics)"); - PrintAndLogEx(NORMAL, " l legacy mode (use the slow mfchk for the key enumeration)"); - PrintAndLogEx(NORMAL, " * all sectors based on card memory. Default: 1K"); + PrintAndLogEx(NORMAL, " l legacy mode (use the slow 'mf chk' for the key enumeration)"); + PrintAndLogEx(NORMAL, " * all sectors based on card memory"); PrintAndLogEx(NORMAL, " * 0 = MINI(320 bytes)"); - PrintAndLogEx(NORMAL, " * 1 = 1K"); - PrintAndLogEx(NORMAL, " * 2 = 2K"); - PrintAndLogEx(NORMAL, " * 4 = 4K"); + PrintAndLogEx(NORMAL, " * 1 = 1k (default)"); + PrintAndLogEx(NORMAL, " * 2 = 2k"); + PrintAndLogEx(NORMAL, " * 4 = 4k"); PrintAndLogEx(NORMAL, " i set type of SIMD instructions for hardnested. Default: autodetection."); PrintAndLogEx(NORMAL, " i 5 = AVX512"); PrintAndLogEx(NORMAL, " i 2 = AVX2"); @@ -196,9 +196,9 @@ static int usage_hf14_autopwn(void) { PrintAndLogEx(NORMAL, " i n = none (use CPU regular instruction set)"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf mf autopwn -- attack a mifare classic card with the default keys"); - PrintAndLogEx(NORMAL, " hf mf autopwn * 1 f mfc_default_keys -- attack a mifare classic card (size 1K) with the default dictionary"); - PrintAndLogEx(NORMAL, " hf mf autopwn k 0 A FFFFFFFFFFFF -- attack a mifare classic card with the known key 'FFFFFFFFFFFF' for sector 0 and key type A"); + PrintAndLogEx(NORMAL, " hf mf autopwn -- target Mifare classic card with default keys"); + PrintAndLogEx(NORMAL, " hf mf autopwn * 1 f mfc_default_keys -- target Mifare classic card (size 1k) with default dictionary"); + PrintAndLogEx(NORMAL, " hf mf autopwn k 0 A FFFFFFFFFFFF -- target Mifare classic card with Sector0 typeA with known key 'FFFFFFFFFFFF'"); PrintAndLogEx(NORMAL, " hf mf autopwn k 0 A FFFFFFFFFFFF * 1 f mfc_default_keys -- this command combines the two above (reduce the need for nested / hardnested attacks, by using a dictionary)"); return 0; } @@ -963,9 +963,11 @@ static int CmdHF14AMfDump(const char *Cmd) { PrintAndLogEx(SUCCESS, "\nSucceded in dumping all blocks"); if (strlen(dataFilename) < 1) { - fptr = dataFilename; - fptr += sprintf(fptr, "hf-mf-"); - FillFileNameByUID(fptr, (uint8_t *)carddata, "-data", 4); + fptr = GenerateFilename("hf-mf-", "-data"); + if (fptr == NULL) + return PM3_ESOFT; + + strcpy(dataFilename, fptr); } uint16_t bytes = 16 * (FirstBlockOfSector(numSectors - 1) + NumBlocksPerSector(numSectors - 1)); @@ -1575,7 +1577,6 @@ static int CmdHF14AMfNestedHard(const char *Cmd) { return 0; } - static int CmdHF14AMfAutoPWN(const char *Cmd) { // Nested and Hardnested parameter uint8_t blockNo = 0; @@ -1601,8 +1602,6 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { // Nested and Hardnested returned status uint64_t foundkey = 0; int16_t isOK = 0; - // Loop counter - int i, i2, i3; int current_sector_i = 0, current_key_type_i = 0; // Dumping and transfere to simulater memory uint8_t block[16] = {0x00}; @@ -1644,14 +1643,14 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { // Get the known block number if (param_getchar(Cmd, cmdp + 1) == 0x00) { PrintAndLogEx(WARNING, "Sector number is missing"); - return 1; + return PM3_EINVARG; } blockNo = param_get8(Cmd, cmdp + 1); // Get the knonwn block type ctmp = tolower(param_getchar(Cmd, cmdp + 2)); if (ctmp != 'a' && ctmp != 'b') { PrintAndLogEx(WARNING, "Key type must be A or B"); - return 1; + return PM3_EINVARG; } if (ctmp != 'a') { keyType = 1; @@ -1659,7 +1658,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { // Get the known block key if (param_gethex(Cmd, cmdp + 3, key, 12)) { PrintAndLogEx(WARNING, "Key must include 12 HEX symbols"); - return 1; + return PM3_EINVARG; } know_target_key = true; cmdp += 3; @@ -1690,14 +1689,13 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { break; default: PrintAndLogEx(WARNING, "Unknown SIMD type. %c", ctmp); - return 1; + return PM3_EINVARG; } cmdp += 2; break; default: PrintAndLogEx(WARNING, "Unknown parameter '%c'\n", ctmp); - usage_hf14_autopwn(); - return 1; + return usage_hf14_autopwn(); } cmdp++; } @@ -1705,74 +1703,82 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { // Create the key storage stucture e_sector = calloc(sectors_cnt, sizeof(sector_t)); if (e_sector == NULL) return PM3_EMALLOC; - // Clear the key storage datastructure - for (i = 0; i < sectors_cnt; i++) { - for (i2 = 0; i2 < 2; i2++) { - e_sector[i].Key[i2] = 0; - e_sector[i].foundKey[i2] = 0; + + // clear the key storage + for (int i = 0; i < sectors_cnt; i++) { + for (int j = 0; j < 2; j++) { + e_sector[i].Key[j] = 0; + e_sector[i].foundKey[j] = 0; } } - // Get the card prng type (weak=true / hard=false) + // card prng type (weak=true / hard=false) prng_type = detect_classic_prng(); - // Print operating parameters + // print parameters if (verbose) { - PrintAndLogEx(INFO, "[ SETTINGS ] Card sectors .. " _YELLOW_("%d"), sectors_cnt); - PrintAndLogEx(INFO, "[ SETTINGS ] Key supplied .. " _YELLOW_("%s"), know_target_key ? "True" : "False"); - PrintAndLogEx(INFO, "[ SETTINGS ] Known sector .. " _YELLOW_("%d"), blockNo); - PrintAndLogEx(INFO, "[ SETTINGS ] Keytype ....... " _YELLOW_("%c"), keyType ? 'B' : 'A'); - PrintAndLogEx(INFO, "[ SETTINGS ] Kown key ...... " _YELLOW_("0x%02x%02x%02x%02x%02x%02x"), key[0], key[1], key[2], key[3], key[4], key[5]); - PrintAndLogEx(INFO, "[ SETTINGS ] Card PRNG ..... " _YELLOW_("%s"), prng_type ? "WEAK" : "HARD"); - PrintAndLogEx(INFO, "[ SETTINGS ] Dictionary .... " _YELLOW_("%s"), strlen(filename) ? filename : "NONE"); - PrintAndLogEx(INFO, "[ SETTINGS ] Legacy mode ... " _YELLOW_("%s"), legacy_mfchk ? "True" : "False"); + PrintAndLogEx(INFO, " card sectors .. " _YELLOW_("%d"), sectors_cnt); + PrintAndLogEx(INFO, " key supplied .. " _YELLOW_("%s"), know_target_key ? "True" : "False"); + PrintAndLogEx(INFO, " known sector .. " _YELLOW_("%d"), blockNo); + PrintAndLogEx(INFO, " keytype ....... " _YELLOW_("%c"), keyType ? 'B' : 'A'); + PrintAndLogEx(INFO, " known key ..... " _YELLOW_("%s"), sprint_hex(key, sizeof(key))); + PrintAndLogEx(INFO, " card PRNG ..... " _YELLOW_("%s"), prng_type ? "WEAK" : "HARD"); + PrintAndLogEx(INFO, " dictionary .... " _YELLOW_("%s"), strlen(filename) ? filename : "NONE"); + PrintAndLogEx(INFO, " legacy mode ... " _YELLOW_("%s"), legacy_mfchk ? "True" : "False"); } - // Check the user supplied key + // Start the timer + t1 = msclock(); + + // check the user supplied key if (know_target_key == false) - PrintAndLogEx(WARNING, "No known key was supplied, the following attacks might fail!"); + PrintAndLogEx(WARNING, "No known key was supplied, key recovery might fail"); else { if (mfCheckKeys(FirstBlockOfSector(blockNo), keyType, true, 1, key, &key64) == PM3_SUCCESS) { - PrintAndLogEx(INFO, "[ SETTINGS ] The following key will be used for the nested / hardnested attack: sector:" - _RED_("%3d") " key type:"_RED_("%c") " key: " _RED_("0x%02x%02x%02x%02x%02x%02x"), + PrintAndLogEx(INFO, "Using key for the nested / hardnested | sector:" + _RED_("%3d") " key type: "_RED_("%c") " key: " _RED_("%s"), blockNo, keyType ? 'B' : 'A', - key[0], key[1], key[2], key[3], key[4], key[5]); + sprint_hex(key, sizeof(key)) + ); // Store the key for the nested / hardnested attack (if supplied by the user) e_sector[blockNo].Key[keyType] = bytes_to_num(key, 6); e_sector[blockNo].foundKey[keyType] = 3; } else { know_target_key = false; - PrintAndLogEx(FAILED, "Key is wrong. Can't authenticate to sector:"_RED_("%3d") " key type:"_RED_("%c") " key: " _RED_("0x%02x%02x%02x%02x%02x%02x"), + PrintAndLogEx(FAILED, "Key is wrong. Can't authenticate to sector:"_RED_("%3d") " key type:"_RED_("%c") " key: " _RED_("%s"), blockNo, keyType ? 'B' : 'A', - key[0], key[1], key[2], key[3], key[4], key[5]); - PrintAndLogEx(WARNING, "Let's see if just the sector or key type are not correct, and then we also give the dictionary a try ;)"); + sprint_hex(key, sizeof(key)) + ); + PrintAndLogEx(WARNING, "Falling back to dictionary"); } // Check if the user supplied key is used by other sectors - for (i = 0; i < sectors_cnt; i++) { - for (i2 = 0; i2 < 2; i2++) { - if (e_sector[i].foundKey[i2] == 0) { - if (mfCheckKeys(FirstBlockOfSector(i), i2, true, 1, key, &key64) == PM3_SUCCESS) { - e_sector[i].Key[i2] = bytes_to_num(key, 6); - e_sector[i].foundKey[i2] = 4; - PrintAndLogEx(SUCCESS, "[ REUSED KEY ] Valid KEY FOUND: sector:%3d key type:%c key: " _YELLOW_("0x%02x%02x%02x%02x%02x%02x"), + for (int i = 0; i < sectors_cnt; i++) { + for (int j = 0; j < 2; j++) { + if (e_sector[i].foundKey[j] == 0) { + if (mfCheckKeys(FirstBlockOfSector(i), j, true, 1, key, &key64) == PM3_SUCCESS) { + e_sector[i].Key[j] = bytes_to_num(key, 6); + e_sector[i].foundKey[j] = 4; + PrintAndLogEx(SUCCESS, "Found valid key: sector: %3d key type: %c key: " _YELLOW_("%s"), i, - i2 ? 'B' : 'A', - key[0], key[1], key[2], key[3], key[4], key[5]); + j ? 'B' : 'A', + sprint_hex(key, sizeof(key)) + ); // If the user supplied secctor / keytype was wrong --> just be nice and correct it ;) if (know_target_key == false) { - num_to_bytes(e_sector[i].Key[i2], 6, key); + num_to_bytes(e_sector[i].Key[j], 6, key); know_target_key = true; blockNo = i; - keyType = i2; - PrintAndLogEx(SUCCESS, "[ SETTINGS ] The following key will be used for the nested / hardnested attack: sector:" - _RED_("%3d") " key type:"_RED_("%c") " key: " _RED_("0x%02x%02x%02x%02x%02x%02x"), + keyType = j; + PrintAndLogEx(SUCCESS, "using key nested / hardnested attack: sector:" + _RED_("%3d") " key type: "_RED_("%c") " key: " _RED_("%s"), blockNo, keyType ? 'B' : 'A', - key[0], key[1], key[2], key[3], key[4], key[5]); + sprint_hex(key, sizeof(key)) + ); } } } @@ -1786,16 +1792,17 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { loadFileDICTIONARY(filename, keyBlock, &data_length, 6, &key_cnt); if ((data_length / 6) > max_dictionary_size) { // This is not a good solution (loadFileDICTIONARY needs a maxdatalen)! - PrintAndLogEx(FAILED, "The loaded dictionary is too large: %d (allowed: %d)", data_length, max_dictionary_size); - free(keyBlock); // This won't work too well, because data on the stack is already overflown !!! + // loadfiledictionary will reallocate to correct size. + PrintAndLogEx(FAILED, "Dictionary is too large: %d (allowed: %d)", data_length, max_dictionary_size); + free(keyBlock); free(e_sector); - return 1; + return PM3_EMALLOC; } } else { keyBlock = calloc(ARRAYLEN(g_mifare_default_keys), 6); if (keyBlock == NULL) { free(e_sector); - return 1; + return PM3_EMALLOC; } for (int cnt = 0; cnt < ARRAYLEN(g_mifare_default_keys); cnt++) { @@ -1804,23 +1811,21 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { key_cnt = ARRAYLEN(g_mifare_default_keys); } - // Start the timer - t1 = msclock(); - // Use the dictionary to find sector keys on the card - PrintAndLogEx(INFO, "Enumerating the card keys with the dictionary!"); + PrintAndLogEx(INFO, "Enter dictionary run..."); + if (legacy_mfchk) { // Check all the sectors - for (i = 0; i < sectors_cnt; i++) { - for (i2 = 0; i2 < 2; i2++) { + for (int i = 0; i < sectors_cnt; i++) { + for (int j = 0; j < 2; j++) { // Check if the key is known - if (e_sector[i].foundKey[i2] == 0) { - for (i3 = 0; i3 < key_cnt; i3++) { + if (e_sector[i].foundKey[j] == 0) { + for (int k = 0; k < key_cnt; k++) { printf("."); fflush(stdout); - if (mfCheckKeys(FirstBlockOfSector(i), i2, true, 1, (keyBlock + (6 * i3)), &key64) == PM3_SUCCESS) { - e_sector[i].Key[i2] = bytes_to_num((keyBlock + (6 * i3)), 6); - e_sector[i].foundKey[i2] = 1; + if (mfCheckKeys(FirstBlockOfSector(i), j, true, 1, (keyBlock + (6 * k)), &key64) == PM3_SUCCESS) { + e_sector[i].Key[j] = bytes_to_num((keyBlock + (6 * k)), 6); + e_sector[i].foundKey[j] = 1; break; } } @@ -1835,7 +1840,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { for (uint8_t strategy = 1; strategy < 3; strategy++) { PrintAndLogEx(INFO, "Running strategy %u", strategy); // main keychunk loop - for (i = 0; i < key_cnt; i += chunksize) { + for (int i = 0; i < key_cnt; i += chunksize) { if (kbd_enter_pressed()) { PrintAndLogEx(WARNING, "\naborted via keyboard!\n"); @@ -1847,6 +1852,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { // last chunk? if (size == key_cnt - i) lastChunk = true; + int res = mfCheckKeys_fast(sectors_cnt, firstChunk, lastChunk, strategy, size, keyBlock + (i * 6), e_sector, false); if (firstChunk) firstChunk = false; @@ -1863,26 +1869,28 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { } // Analyse the dictionary attack - for (i = 0; i < sectors_cnt; i++) { - for (i2 = 0; i2 < 2; i2++) { - if (e_sector[i].foundKey[i2] == 1) { - num_to_bytes(e_sector[i].Key[i2], 6, tmp_key); - PrintAndLogEx(SUCCESS, "[ DICT. KEY ] Valid KEY FOUND: sector:%3d key type:%c key: " _YELLOW_("0x%02x%02x%02x%02x%02x%02x"), + for (int i = 0; i < sectors_cnt; i++) { + for (int j = 0; j < 2; j++) { + if (e_sector[i].foundKey[j] == 1) { + num_to_bytes(e_sector[i].Key[j], 6, tmp_key); + PrintAndLogEx(SUCCESS, "Found valid key: sector:%3d key type:%c key: " _YELLOW_("%s"), i, - i2 ? 'B' : 'A', - tmp_key[0], tmp_key[1], tmp_key[2], tmp_key[3], tmp_key[4], tmp_key[5]); + j ? 'B' : 'A', + sprint_hex(tmp_key, sizeof(tmp_key)) + ); // Store valid credentials for the nested / hardnested attack if none exist if (know_target_key == false) { - num_to_bytes(e_sector[i].Key[i2], 6, key); + num_to_bytes(e_sector[i].Key[j], 6, key); know_target_key = true; blockNo = i; - keyType = i2; - PrintAndLogEx(SUCCESS, "[ SETTINGS ] The following key will be used for the nested / hardnested attack: sector:" - _RED_("%3d") " key type:"_RED_("%c") " key: " _RED_("0x%02x%02x%02x%02x%02x%02x"), + keyType = j; + PrintAndLogEx(SUCCESS, "Using key nested / hardnested attack: sector:" + _RED_("%3d") " key type:"_RED_("%c") " key: " _RED_("%s"), blockNo, keyType ? 'B' : 'A', - key[0], key[1], key[2], key[3], key[4], key[5]); + sprint_hex(key, sizeof(key)) + ); } } } @@ -1892,7 +1900,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { if (know_target_key == false) { // Check if the darkside attack can be used if (prng_type) { - PrintAndLogEx(INFO, "No key was found ... time to go to the dark side ;)"); + PrintAndLogEx(INFO, "Enter darkside run..."); int isOK = mfDarkside(FirstBlockOfSector(blockNo), keyType, &key64); switch (isOK) { case -1 : @@ -1919,10 +1927,11 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { // Check if the darkside key is valid if (mfCheckKeys(FirstBlockOfSector(blockNo), keyType, true, 1, key, &key64) != PM3_SUCCESS) { PrintAndLogEx(FAILED, "The key generated by the darkside attack is not valid!" - _RED_("%3d") " key type:"_RED_("%c") " key: " _RED_("0x%02x%02x%02x%02x%02x%02x"), + _RED_("%3d") " key type: "_RED_("%c") " key: " _RED_("%s"), blockNo, keyType ? 'B' : 'A', - key[0], key[1], key[2], key[3], key[4], key[5]); + sprint_hex(key, sizeof(key)) + ); goto noValidKeyFound; } // Store the keys @@ -1933,7 +1942,7 @@ noValidKeyFound: PrintAndLogEx(FAILED, "No usable key was found!"); free(keyBlock); free(e_sector); - return 1; + return PM3_ESOFT; } } free(keyBlock); @@ -1952,19 +1961,21 @@ noValidKeyFound: if (bytes_to_num(tmp_key, 6) != 0) { // The fast check --> mfCheckKeys_fast(sectors_cnt, true, true, 2, 1, tmp_key, e_sector, false); // Returns false keys, so we just stick to the slower mfchk. - for (i = 0; i < sectors_cnt; i++) { - for (i2 = 0; i2 < 2; i2++) { + for (int i = 0; i < sectors_cnt; i++) { + for (int j = 0; j < 2; j++) { // Check if the sector key is already broken - if (e_sector[i].foundKey[i2] == 0) { - // Check if the key works - if (mfCheckKeys(FirstBlockOfSector(i), i2, true, 1, tmp_key, &key64) == PM3_SUCCESS) { - e_sector[i].Key[i2] = bytes_to_num(tmp_key, 6); - e_sector[i].foundKey[i2] = 4; - PrintAndLogEx(SUCCESS, "[ REUSED KEY ] Valid KEY FOUND: sector:%3d key type:%c key: " _YELLOW_("0x%02x%02x%02x%02x%02x%02x"), - i, - i2 ? 'B' : 'A', - tmp_key[0], tmp_key[1], tmp_key[2], tmp_key[3], tmp_key[4], tmp_key[5]); - } + if (e_sector[i].foundKey[j]) + continue; + + // Check if the key works + if (mfCheckKeys(FirstBlockOfSector(i), j, true, 1, tmp_key, &key64) == PM3_SUCCESS) { + e_sector[i].Key[j] = bytes_to_num(tmp_key, 6); + e_sector[i].foundKey[j] = 4; + PrintAndLogEx(SUCCESS, "Found valid key: sector: %3d key type: %c key: " _YELLOW_("%s"), + i, + j ? 'B' : 'A', + sprint_hex(tmp_key, sizeof(tmp_key)) + ); } } } @@ -1977,7 +1988,7 @@ noValidKeyFound: if (prng_type && (! nested_failed)) { uint8_t retries = 0; tryNested: - PrintAndLogEx(INFO, "[ NESTED ] Sector no:%3d, target key type:%c", + PrintAndLogEx(INFO, "Sector no: %3d, target key type: %c", current_sector_i, current_key_type_i ? 'B' : 'A'); @@ -1986,18 +1997,15 @@ tryNested: case -1 : PrintAndLogEx(ERR, "\nError: No response from Proxmark3."); free(e_sector); - return 1; - break; + return PM3_ESOFT; case -2 : PrintAndLogEx(WARNING, "\nButton pressed. Aborted."); free(e_sector); - return 1; - break; + return PM3_ESOFT; case -3 : PrintAndLogEx(FAILED, "Tag isn't vulnerable to Nested Attack (PRNG is probably not predictable)."); - PrintAndLogEx(FAILED, "Nested attack failed --> try hardnested instead!"); + PrintAndLogEx(FAILED, "Nested attack failed --> try hardnested"); goto tryHardnested; - break; case -4 : //key not found calibrate = false; // this can happen on some old cards, it's worth trying some more before switching to slower hardnested @@ -2018,12 +2026,11 @@ tryNested: default : PrintAndLogEx(ERR, "unknown Error.\n"); free(e_sector); - return 1; - break; + return PM3_ESOFT; } } else { tryHardnested: // If the nested attack fails then we try the hardnested attack - PrintAndLogEx(INFO, "[ HARDNESTED ] Sector no:%3d, target key type:%c, Slow: %s", + PrintAndLogEx(INFO, "Sector no: %3d, target key type: %c, Slow: %s", current_sector_i, current_key_type_i ? 'B' : 'A', slow ? "Yes" : "No"); @@ -2042,7 +2049,7 @@ tryHardnested: // If the nested attack fails then we try the hardnested attack break; } free(e_sector); - return 2; + return PM3_ESOFT; } // Copy the found key to the tmp_key variale (for the following print statement, and the mfCheckKeys above) @@ -2051,16 +2058,12 @@ tryHardnested: // If the nested attack fails then we try the hardnested attack e_sector[current_sector_i].foundKey[current_key_type_i] = 6; } // Check if the key was found - if (e_sector[current_sector_i].foundKey[current_key_type_i] != 0) { - PrintAndLogEx(SUCCESS, "[TESTING KEY] Valid KEY FOUND: sector:%3d key type:%c key: " _YELLOW_("0x%02x%02x%02x%02x%02x%02x"), + if (e_sector[current_sector_i].foundKey[current_key_type_i]) { + PrintAndLogEx(SUCCESS, "Found valid key: sector: %3d key type: %c key: " _YELLOW_("%s"), current_sector_i, current_key_type_i ? 'B' : 'A', - tmp_key[0], tmp_key[1], tmp_key[2], tmp_key[3], tmp_key[4], tmp_key[5]); - } else { - PrintAndLogEx(FAILED, "[TESTING KEY] Valid KEY NOT FOUND: sector:%3d key type:%c key: " _YELLOW_("0x%02x%02x%02x%02x%02x%02x"), - current_sector_i, - current_key_type_i ? 'B' : 'A', - tmp_key[0], tmp_key[1], tmp_key[2], tmp_key[3], tmp_key[4], tmp_key[5]); + sprint_hex(tmp_key, sizeof(tmp_key)) + ); } } } @@ -2072,39 +2075,43 @@ tryHardnested: // If the nested attack fails then we try the hardnested attack PrintAndLogEx(INFO, "Found Keys:"); printKeyTable(sectors_cnt, e_sector); if (verbose) { - PrintAndLogEx(INFO, "[ INFO ] Key res types:"); - PrintAndLogEx(INFO, " 1: Dictionary"); - PrintAndLogEx(INFO, " 2: Darkside attack"); - PrintAndLogEx(INFO, " 3: User supplied"); - PrintAndLogEx(INFO, " 4: Reused"); - PrintAndLogEx(INFO, " 5: Nested"); - PrintAndLogEx(INFO, " 6: Hardnested"); + PrintAndLogEx(INFO, " Key res types:"); + PrintAndLogEx(INFO, " 1: Dictionary"); + PrintAndLogEx(INFO, " 2: Darkside attack"); + PrintAndLogEx(INFO, " 3: User supplied"); + PrintAndLogEx(INFO, " 4: Reused"); + PrintAndLogEx(INFO, " 5: Nested"); + PrintAndLogEx(INFO, " 6: Hardnested"); } - // Transfere the found keys to the simulator and dump the keys and card data - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(INFO, "Dumping the keys:"); + PrintAndLogEx(INFO, "\nSaving keys"); + createMfcKeyDump(sectors_cnt, e_sector, GenerateFilename("hf-mf-", "-key.bin")); - PrintAndLogEx(SUCCESS, "Transferring the found keys to the simulator memory (Cmd Error: 04 can occur, but this shouldn't be a problem)"); + PrintAndLogEx(SUCCESS, "Transferring keys to simulator memory (Cmd Error: 04 can occur)"); + for (current_sector_i = 0; current_sector_i < sectors_cnt; current_sector_i++) { mfEmlGetMem(block, current_sector_i, 1); if (e_sector[current_sector_i].foundKey[0]) num_to_bytes(e_sector[current_sector_i].Key[0], 6, block); if (e_sector[current_sector_i].foundKey[1]) num_to_bytes(e_sector[current_sector_i].Key[1], 6, block + 10); + mfEmlSetMem(block, FirstBlockOfSector(current_sector_i) + NumBlocksPerSector(current_sector_i) - 1, 1); } + // using ecfill trick, keys already in emulator mem, load data using Key A clearCommandBuffer(); SendCommandMIX(CMD_HF_MIFARE_EML_LOAD, sectors_cnt, 0, 0, NULL, 0); + + // using ecfill trick, keys already in emulator mem, load data using Key B clearCommandBuffer(); SendCommandMIX(CMD_HF_MIFARE_EML_LOAD, sectors_cnt, 1, 0, NULL, 0); bytes = block_cnt * MFBLOCK_SIZE; dump = calloc(bytes, sizeof(uint8_t)); if (!dump) { - PrintAndLogEx(WARNING, "Fail, cannot allocate memory"); + PrintAndLogEx(ERR, "Fail, cannot allocate memory"); free(e_sector); return PM3_EMALLOC; } @@ -2112,26 +2119,31 @@ tryHardnested: // If the nested attack fails then we try the hardnested attack PrintAndLogEx(INFO, "Downloading the card content from emulator memory"); if (!GetFromDevice(BIG_BUF_EML, dump, bytes, 0, NULL, 0, NULL, 2500, false)) { - PrintAndLogEx(WARNING, "Fail, transfer from device time-out"); + PrintAndLogEx(ERR, "Fail, transfer from device time-out"); free(e_sector); free(dump); return PM3_ETIMEOUT; } - fnameptr += sprintf(fnameptr, "hf-mf-"); - FillFileNameByUID(fnameptr, dump, "-dump", 4); - + fnameptr = GenerateFilename("hf-mf-", "-data"); + if (fnameptr == NULL) { + free(dump); + free(e_sector); + return PM3_ESOFT; + } + strcpy(filename, fnameptr); + saveFile(filename, ".bin", dump, bytes); saveFileEML(filename, dump, bytes, MFBLOCK_SIZE); saveFileJSON(filename, jsfCardMemory, dump, bytes); // Generate and show statistics t1 = msclock() - t1; - PrintAndLogEx(INFO, "Required time for the autopwn attack: " _YELLOW_("%.0f") " seconds", (float)t1 / 1000.0); + PrintAndLogEx(INFO, "Autopwn execution time: " _YELLOW_("%.0f") " seconds", (float)t1 / 1000.0); free(dump); free(e_sector); - return 0; + return PM3_SUCCESS; } /* From d88b76bedab0362b26f0bc36a635b6fba05679d8 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 27 Aug 2019 17:28:08 +0200 Subject: [PATCH 0456/1854] partial make style --- armsrc/optimized_cipher.c | 154 +++++++++++++++++++------------------- client/cmdhfmf.c | 84 ++++++++++----------- 2 files changed, 119 insertions(+), 119 deletions(-) diff --git a/armsrc/optimized_cipher.c b/armsrc/optimized_cipher.c index b03facf93..a54aebc61 100644 --- a/armsrc/optimized_cipher.c +++ b/armsrc/optimized_cipher.c @@ -71,7 +71,7 @@ * Removing many unnecessary bit maskings (& 0x1) * updating state in place instead of alternating use of a second state structure * remove the necessity to reverse bits of input and output bytes - + opt_doTagMAC_2() now completes in 270 microseconds. -- piwi 2019 @@ -80,22 +80,22 @@ #include "optimized_cipher.h" static const uint8_t opt_select_LUT[256] = { - 00, 03, 02, 01, 02, 03, 00, 01, 04, 07, 07, 04, 06, 07, 05, 04, - 01, 02, 03, 00, 02, 03, 00, 01, 05, 06, 06, 05, 06, 07, 05, 04, - 06, 05, 04, 07, 04, 05, 06, 07, 06, 05, 05, 06, 04, 05, 07, 06, - 07, 04, 05, 06, 04, 05, 06, 07, 07, 04, 04, 07, 04, 05, 07, 06, - 06, 05, 04, 07, 04, 05, 06, 07, 02, 01, 01, 02, 00, 01, 03, 02, - 03, 00, 01, 02, 00, 01, 02, 03, 07, 04, 04, 07, 04, 05, 07, 06, - 00, 03, 02, 01, 02, 03, 00, 01, 00, 03, 03, 00, 02, 03, 01, 00, - 05, 06, 07, 04, 06, 07, 04, 05, 05, 06, 06, 05, 06, 07, 05, 04, - 02, 01, 00, 03, 00, 01, 02, 03, 06, 05, 05, 06, 04, 05, 07, 06, - 03, 00, 01, 02, 00, 01, 02, 03, 07, 04, 04, 07, 04, 05, 07, 06, - 02, 01, 00, 03, 00, 01, 02, 03, 02, 01, 01, 02, 00, 01, 03, 02, - 03, 00, 01, 02, 00, 01, 02, 03, 03, 00, 00, 03, 00, 01, 03, 02, - 04, 07, 06, 05, 06, 07, 04, 05, 00, 03, 03, 00, 02, 03, 01, 00, - 01, 02, 03, 00, 02, 03, 00, 01, 05, 06, 06, 05, 06, 07, 05, 04, - 04, 07, 06, 05, 06, 07, 04, 05, 04, 07, 07, 04, 06, 07, 05, 04, - 01, 02, 03, 00, 02, 03, 00, 01, 01, 02, 02, 01, 02, 03, 01, 00 + 00, 03, 02, 01, 02, 03, 00, 01, 04, 07, 07, 04, 06, 07, 05, 04, + 01, 02, 03, 00, 02, 03, 00, 01, 05, 06, 06, 05, 06, 07, 05, 04, + 06, 05, 04, 07, 04, 05, 06, 07, 06, 05, 05, 06, 04, 05, 07, 06, + 07, 04, 05, 06, 04, 05, 06, 07, 07, 04, 04, 07, 04, 05, 07, 06, + 06, 05, 04, 07, 04, 05, 06, 07, 02, 01, 01, 02, 00, 01, 03, 02, + 03, 00, 01, 02, 00, 01, 02, 03, 07, 04, 04, 07, 04, 05, 07, 06, + 00, 03, 02, 01, 02, 03, 00, 01, 00, 03, 03, 00, 02, 03, 01, 00, + 05, 06, 07, 04, 06, 07, 04, 05, 05, 06, 06, 05, 06, 07, 05, 04, + 02, 01, 00, 03, 00, 01, 02, 03, 06, 05, 05, 06, 04, 05, 07, 06, + 03, 00, 01, 02, 00, 01, 02, 03, 07, 04, 04, 07, 04, 05, 07, 06, + 02, 01, 00, 03, 00, 01, 02, 03, 02, 01, 01, 02, 00, 01, 03, 02, + 03, 00, 01, 02, 00, 01, 02, 03, 03, 00, 00, 03, 00, 01, 03, 02, + 04, 07, 06, 05, 06, 07, 04, 05, 00, 03, 03, 00, 02, 03, 01, 00, + 01, 02, 03, 00, 02, 03, 00, 01, 05, 06, 06, 05, 06, 07, 05, 04, + 04, 07, 06, 05, 06, 07, 04, 05, 04, 07, 07, 04, 06, 07, 05, 04, + 01, 02, 03, 00, 02, 03, 00, 01, 01, 02, 02, 01, 02, 03, 01, 00 }; /********************** the table above has been generated with this code: ******** @@ -143,65 +143,65 @@ uint8_t xopt__select(bool x, bool y, uint8_t r) static void opt_successor(const uint8_t *k, State *s, uint8_t y) { // #define opt_T(s) (0x1 & ((s->t >> 15) ^ (s->t >> 14) ^ (s->t >> 10) ^ (s->t >> 8) ^ (s->t >> 5) ^ (s->t >> 4)^ (s->t >> 1) ^ s->t)) - // uint8_t Tt = opt_T(s); - uint16_t Tt = s->t & 0xc533; - Tt = Tt ^ (Tt >> 1); - Tt = Tt ^ (Tt >> 4); - Tt = Tt ^ (Tt >> 10); - Tt = Tt ^ (Tt >> 8); + // uint8_t Tt = opt_T(s); + uint16_t Tt = s->t & 0xc533; + Tt = Tt ^ (Tt >> 1); + Tt = Tt ^ (Tt >> 4); + Tt = Tt ^ (Tt >> 10); + Tt = Tt ^ (Tt >> 8); - s->t = (s->t >> 1); - s->t |= (Tt ^ (s->r >> 7) ^ (s->r >> 3)) << 15; + s->t = (s->t >> 1); + s->t |= (Tt ^ (s->r >> 7) ^ (s->r >> 3)) << 15; - uint8_t opt_B = s->b; - opt_B ^= s->b >> 6; - opt_B ^= s->b >> 5; - opt_B ^= s->b >> 4; + uint8_t opt_B = s->b; + opt_B ^= s->b >> 6; + opt_B ^= s->b >> 5; + opt_B ^= s->b >> 4; - s->b = s->b >> 1; - s->b |= (opt_B ^ s->r) << 7; + s->b = s->b >> 1; + s->b |= (opt_B ^ s->r) << 7; - uint8_t opt_select = opt_select_LUT[s->r] & 0x04; - opt_select |= (opt_select_LUT[s->r] ^ ((Tt ^ y) << 1)) & 0x02; - opt_select |= (opt_select_LUT[s->r] ^ Tt) & 0x01; + uint8_t opt_select = opt_select_LUT[s->r] & 0x04; + opt_select |= (opt_select_LUT[s->r] ^ ((Tt ^ y) << 1)) & 0x02; + opt_select |= (opt_select_LUT[s->r] ^ Tt) & 0x01; - uint8_t r = s->r; - s->r = (k[opt_select] ^ s->b) + s->l ; - s->l = s->r + r; + uint8_t r = s->r; + s->r = (k[opt_select] ^ s->b) + s->l ; + s->l = s->r + r; } static void opt_suc(const uint8_t *k, State *s, uint8_t *in, uint8_t length, bool add32Zeroes) { for (int i = 0; i < length; i++) { uint8_t head; - head = in[i]; - opt_successor(k, s, head); + head = in[i]; + opt_successor(k, s, head); - head >>= 1; - opt_successor(k, s, head); + head >>= 1; + opt_successor(k, s, head); - head >>= 1; - opt_successor(k, s, head); + head >>= 1; + opt_successor(k, s, head); - head >>= 1; - opt_successor(k, s, head); + head >>= 1; + opt_successor(k, s, head); - head >>= 1; - opt_successor(k, s, head); + head >>= 1; + opt_successor(k, s, head); - head >>= 1; - opt_successor(k, s, head); + head >>= 1; + opt_successor(k, s, head); - head >>= 1; - opt_successor(k, s, head); + head >>= 1; + opt_successor(k, s, head); - head >>= 1; - opt_successor(k, s, head); + head >>= 1; + opt_successor(k, s, head); } //For tag MAC, an additional 32 zeroes if (add32Zeroes) { for (int i = 0; i < 16; i++) { - opt_successor(k, s, 0); - opt_successor(k, s, 0); + opt_successor(k, s, 0); + opt_successor(k, s, 0); } } } @@ -209,22 +209,22 @@ static void opt_suc(const uint8_t *k, State *s, uint8_t *in, uint8_t length, boo static void opt_output(const uint8_t *k, State *s, uint8_t *buffer) { for (uint8_t times = 0; times < 4; times++) { uint8_t bout = 0; - bout |= (s->r & 0x4) >> 2; - opt_successor(k, s, 0); + bout |= (s->r & 0x4) >> 2; + opt_successor(k, s, 0); bout |= (s->r & 0x4) >> 1; - opt_successor(k, s, 0); - bout |= (s->r & 0x4); - opt_successor(k, s, 0); - bout |= (s->r & 0x4) << 1; - opt_successor(k, s, 0); - bout |= (s->r & 0x4) << 2; - opt_successor(k, s, 0); - bout |= (s->r & 0x4) << 3; - opt_successor(k, s, 0); - bout |= (s->r & 0x4) << 4; - opt_successor(k, s, 0); - bout |= (s->r & 0x4) << 5; - opt_successor(k, s, 0); + opt_successor(k, s, 0); + bout |= (s->r & 0x4); + opt_successor(k, s, 0); + bout |= (s->r & 0x4) << 1; + opt_successor(k, s, 0); + bout |= (s->r & 0x4) << 2; + opt_successor(k, s, 0); + bout |= (s->r & 0x4) << 3; + opt_successor(k, s, 0); + bout |= (s->r & 0x4) << 4; + opt_successor(k, s, 0); + bout |= (s->r & 0x4) << 5; + opt_successor(k, s, 0); buffer[times] = bout; } } @@ -243,8 +243,8 @@ static void opt_MAC(uint8_t *k, uint8_t *input, uint8_t *out) { void opt_doReaderMAC(uint8_t *cc_nr_p, uint8_t *div_key_p, uint8_t mac[4]) { uint8_t dest [] = {0, 0, 0, 0, 0, 0, 0, 0}; - opt_MAC(div_key_p, cc_nr_p, dest); - memcpy(mac, dest, 4); + opt_MAC(div_key_p, cc_nr_p, dest); + memcpy(mac, dest, 4); return; } @@ -255,8 +255,8 @@ void opt_doTagMAC(uint8_t *cc_p, const uint8_t *div_key_p, uint8_t mac[4]) { 0x4c, // b 0xE012 // t }; - opt_suc(div_key_p, &_init, cc_p, 12, true); - opt_output(div_key_p, &_init, mac); + opt_suc(div_key_p, &_init, cc_p, 12, true); + opt_output(div_key_p, &_init, mac); return; } @@ -275,7 +275,7 @@ State opt_doTagMAC_1(uint8_t *cc_p, const uint8_t *div_key_p) { 0x4c, // b 0xE012 // t }; - opt_suc(div_key_p, &_init, cc_p, 8, false); + opt_suc(div_key_p, &_init, cc_p, 8, false); return _init; } @@ -289,7 +289,7 @@ State opt_doTagMAC_1(uint8_t *cc_p, const uint8_t *div_key_p) { * @param div_key_p - the key to use */ void opt_doTagMAC_2(State _init, uint8_t *nr, uint8_t mac[4], const uint8_t *div_key_p) { - opt_suc(div_key_p, &_init, nr, 4, true); - opt_output(div_key_p, &_init, mac); + opt_suc(div_key_p, &_init, nr, 4, true); + opt_output(div_key_p, &_init, mac); return; } diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 030da5a8d..82aba722e 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -752,10 +752,10 @@ static uint8_t NumBlocksPerSector(uint8_t sectorNo) { } } static uint8_t GetSectorFromBlockNo(uint8_t blockNo) { - if ( blockNo < 128 ) - return blockNo / 4; - else - return 32 + ((128 - blockNo) / 16); + if (blockNo < 128) + return blockNo / 4; + else + return 32 + ((128 - blockNo) / 16); } static int CmdHF14AMfDump(const char *Cmd) { @@ -963,11 +963,11 @@ static int CmdHF14AMfDump(const char *Cmd) { PrintAndLogEx(SUCCESS, "\nSucceded in dumping all blocks"); if (strlen(dataFilename) < 1) { - fptr = GenerateFilename("hf-mf-", "-data"); - if (fptr == NULL) - return PM3_ESOFT; + fptr = GenerateFilename("hf-mf-", "-data"); + if (fptr == NULL) + return PM3_ESOFT; - strcpy(dataFilename, fptr); + strcpy(dataFilename, fptr); } uint16_t bytes = 16 * (FirstBlockOfSector(numSectors - 1) + NumBlocksPerSector(numSectors - 1)); @@ -1229,9 +1229,9 @@ static int CmdHF14AMfNested(const char *Cmd) { e_sector = calloc(SectorsCnt, sizeof(sector_t)); if (e_sector == NULL) return PM3_EMALLOC; - // add our known key - e_sector[GetSectorFromBlockNo(blockNo)].foundKey[keyType] = 1; - e_sector[GetSectorFromBlockNo(blockNo)].Key[keyType] = key64; + // add our known key + e_sector[GetSectorFromBlockNo(blockNo)].foundKey[keyType] = 1; + e_sector[GetSectorFromBlockNo(blockNo)].Key[keyType] = key64; //test current key and additional standard keys first // add parameter key @@ -1703,7 +1703,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { // Create the key storage stucture e_sector = calloc(sectors_cnt, sizeof(sector_t)); if (e_sector == NULL) return PM3_EMALLOC; - + // clear the key storage for (int i = 0; i < sectors_cnt; i++) { for (int j = 0; j < 2; j++) { @@ -1740,7 +1740,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { blockNo, keyType ? 'B' : 'A', sprint_hex(key, sizeof(key)) - ); + ); // Store the key for the nested / hardnested attack (if supplied by the user) e_sector[blockNo].Key[keyType] = bytes_to_num(key, 6); @@ -1751,7 +1751,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { blockNo, keyType ? 'B' : 'A', sprint_hex(key, sizeof(key)) - ); + ); PrintAndLogEx(WARNING, "Falling back to dictionary"); } // Check if the user supplied key is used by other sectors @@ -1765,7 +1765,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { i, j ? 'B' : 'A', sprint_hex(key, sizeof(key)) - ); + ); // If the user supplied secctor / keytype was wrong --> just be nice and correct it ;) if (know_target_key == false) { @@ -1778,7 +1778,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { blockNo, keyType ? 'B' : 'A', sprint_hex(key, sizeof(key)) - ); + ); } } } @@ -1792,7 +1792,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { loadFileDICTIONARY(filename, keyBlock, &data_length, 6, &key_cnt); if ((data_length / 6) > max_dictionary_size) { // This is not a good solution (loadFileDICTIONARY needs a maxdatalen)! - // loadfiledictionary will reallocate to correct size. + // loadfiledictionary will reallocate to correct size. PrintAndLogEx(FAILED, "Dictionary is too large: %d (allowed: %d)", data_length, max_dictionary_size); free(keyBlock); free(e_sector); @@ -1813,7 +1813,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { // Use the dictionary to find sector keys on the card PrintAndLogEx(INFO, "Enter dictionary run..."); - + if (legacy_mfchk) { // Check all the sectors for (int i = 0; i < sectors_cnt; i++) { @@ -1877,7 +1877,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { i, j ? 'B' : 'A', sprint_hex(tmp_key, sizeof(tmp_key)) - ); + ); // Store valid credentials for the nested / hardnested attack if none exist if (know_target_key == false) { @@ -1890,7 +1890,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { blockNo, keyType ? 'B' : 'A', sprint_hex(key, sizeof(key)) - ); + ); } } } @@ -1931,7 +1931,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { blockNo, keyType ? 'B' : 'A', sprint_hex(key, sizeof(key)) - ); + ); goto noValidKeyFound; } // Store the keys @@ -1965,17 +1965,17 @@ noValidKeyFound: for (int j = 0; j < 2; j++) { // Check if the sector key is already broken if (e_sector[i].foundKey[j]) - continue; - - // Check if the key works - if (mfCheckKeys(FirstBlockOfSector(i), j, true, 1, tmp_key, &key64) == PM3_SUCCESS) { - e_sector[i].Key[j] = bytes_to_num(tmp_key, 6); - e_sector[i].foundKey[j] = 4; - PrintAndLogEx(SUCCESS, "Found valid key: sector: %3d key type: %c key: " _YELLOW_("%s"), - i, - j ? 'B' : 'A', - sprint_hex(tmp_key, sizeof(tmp_key)) - ); + continue; + + // Check if the key works + if (mfCheckKeys(FirstBlockOfSector(i), j, true, 1, tmp_key, &key64) == PM3_SUCCESS) { + e_sector[i].Key[j] = bytes_to_num(tmp_key, 6); + e_sector[i].foundKey[j] = 4; + PrintAndLogEx(SUCCESS, "Found valid key: sector: %3d key type: %c key: " _YELLOW_("%s"), + i, + j ? 'B' : 'A', + sprint_hex(tmp_key, sizeof(tmp_key)) + ); } } } @@ -2063,7 +2063,7 @@ tryHardnested: // If the nested attack fails then we try the hardnested attack current_sector_i, current_key_type_i ? 'B' : 'A', sprint_hex(tmp_key, sizeof(tmp_key)) - ); + ); } } } @@ -2089,7 +2089,7 @@ tryHardnested: // If the nested attack fails then we try the hardnested attack createMfcKeyDump(sectors_cnt, e_sector, GenerateFilename("hf-mf-", "-key.bin")); PrintAndLogEx(SUCCESS, "Transferring keys to simulator memory (Cmd Error: 04 can occur)"); - + for (current_sector_i = 0; current_sector_i < sectors_cnt; current_sector_i++) { mfEmlGetMem(block, current_sector_i, 1); if (e_sector[current_sector_i].foundKey[0]) @@ -2100,11 +2100,11 @@ tryHardnested: // If the nested attack fails then we try the hardnested attack mfEmlSetMem(block, FirstBlockOfSector(current_sector_i) + NumBlocksPerSector(current_sector_i) - 1, 1); } - // using ecfill trick, keys already in emulator mem, load data using Key A + // using ecfill trick, keys already in emulator mem, load data using Key A clearCommandBuffer(); SendCommandMIX(CMD_HF_MIFARE_EML_LOAD, sectors_cnt, 0, 0, NULL, 0); - // using ecfill trick, keys already in emulator mem, load data using Key B + // using ecfill trick, keys already in emulator mem, load data using Key B clearCommandBuffer(); SendCommandMIX(CMD_HF_MIFARE_EML_LOAD, sectors_cnt, 1, 0, NULL, 0); @@ -2126,13 +2126,13 @@ tryHardnested: // If the nested attack fails then we try the hardnested attack } fnameptr = GenerateFilename("hf-mf-", "-data"); - if (fnameptr == NULL) { - free(dump); - free(e_sector); - return PM3_ESOFT; + if (fnameptr == NULL) { + free(dump); + free(e_sector); + return PM3_ESOFT; } - strcpy(filename, fnameptr); - + strcpy(filename, fnameptr); + saveFile(filename, ".bin", dump, bytes); saveFileEML(filename, dump, bytes, MFBLOCK_SIZE); saveFileJSON(filename, jsfCardMemory, dump, bytes); From 02c1657594ef0091e652648ad59c7b208e3ee805 Mon Sep 17 00:00:00 2001 From: Matthias Konrath Date: Tue, 27 Aug 2019 19:17:52 +0200 Subject: [PATCH 0457/1854] Added some found keys to the dictionary. --- client/dictionaries/mfc_default_keys.dic | 33 ++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index ff63a0a83..924f75488 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -982,3 +982,36 @@ ef4c5a7ac6fc b47058139187 8268046cd154 67cc03b7d577 +# +# From the HTL Mödling, NÖ, AT +# +a5524645cd91 +d964406e67b4 +99858a49c119 +7b7e752b6a2d +c27d999912ea +66a163ba82b4 +4c60f4b15ba8 +# +# CAFE + CO, AT +# +35d850d10a24 +4b511f4d28dd +e45230e7a9e8 +535f47d35e39 +fb6c88b7e279 +# +# Metro Card, AT +# +223C3427108A +# +# Unknown, AT +# +23d4cdff8da3 +e6849fcc324b +12fd3a94df0e +# +# Unknown, AT +# +0b83797a9c64 +39ad2963d3d1 From c9a02adc70945d8879bdbfcdf800d66861360719 Mon Sep 17 00:00:00 2001 From: Matthias Konrath Date: Tue, 27 Aug 2019 19:45:37 +0200 Subject: [PATCH 0458/1854] Added the read B key with known A key feature, and minor changes to the UI (alignment). --- client/cmdhfmf.c | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 82aba722e..d122837e3 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -1873,7 +1873,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { for (int j = 0; j < 2; j++) { if (e_sector[i].foundKey[j] == 1) { num_to_bytes(e_sector[i].Key[j], 6, tmp_key); - PrintAndLogEx(SUCCESS, "Found valid key: sector:%3d key type:%c key: " _YELLOW_("%s"), + PrintAndLogEx(SUCCESS, "Found valid key: sector: %3d key type: %c key: " _YELLOW_("%s"), i, j ? 'B' : 'A', sprint_hex(tmp_key, sizeof(tmp_key)) @@ -1983,6 +1983,43 @@ noValidKeyFound: // Clear the last found key num_to_bytes(0, 6, tmp_key); + if (current_key_type_i == 1) { + if (e_sector[current_sector_i].foundKey[0] && !e_sector[current_sector_i].foundKey[1]) { + PrintAndLogEx(INFO, "Reading B key: sector: %3d", current_sector_i); + uint8_t sectrail = (FirstBlockOfSector(current_sector_i) + NumBlocksPerSector(current_sector_i) - 1); + + mf_readblock_t payload; + payload.blockno = sectrail; + payload.keytype = 0; + + num_to_bytes(e_sector[current_sector_i].Key[0], 6, payload.key); // KEY A + + clearCommandBuffer(); + SendCommandNG(CMD_HF_MIFARE_READBL, (uint8_t *)&payload, sizeof(mf_readblock_t)); + + PacketResponseNG resp; + if (!WaitForResponseTimeout(CMD_HF_MIFARE_READBL, &resp, 1500)) continue; + + if (resp.status != PM3_SUCCESS) continue; + + uint8_t *data = resp.data.asBytes; + key64 = bytes_to_num(data + 10, 6); + if (verbose){ + num_to_bytes(key64, 6, tmp_key); + PrintAndLogEx(INFO, "Discovered key: sector: %3d key type: %c key: " _YELLOW_("%s"), + current_sector_i, + current_key_type_i ? 'B' : 'A', + sprint_hex(tmp_key, sizeof(tmp_key)) + ); + } + if (key64) { + e_sector[current_sector_i].foundKey[current_key_type_i] = 7; + e_sector[current_sector_i].Key[current_key_type_i] = key64; + num_to_bytes(key64, 6, tmp_key); + } + } + } + // Use the nested / hardnested attack if (e_sector[current_sector_i].foundKey[current_key_type_i] == 0) { if (prng_type && (! nested_failed)) { @@ -2082,6 +2119,7 @@ tryHardnested: // If the nested attack fails then we try the hardnested attack PrintAndLogEx(INFO, " 4: Reused"); PrintAndLogEx(INFO, " 5: Nested"); PrintAndLogEx(INFO, " 6: Hardnested"); + PrintAndLogEx(INFO, " 7: Read B key with A key"); } PrintAndLogEx(INFO, "\nSaving keys"); From 42d58cbced52b093de0f6376e180204d3ddf0fb7 Mon Sep 17 00:00:00 2001 From: Matthias Konrath Date: Tue, 27 Aug 2019 19:55:45 +0200 Subject: [PATCH 0459/1854] fixed the read B key features error handling. --- client/cmdhfmf.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index d122837e3..2f738af2c 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -1998,9 +1998,9 @@ noValidKeyFound: SendCommandNG(CMD_HF_MIFARE_READBL, (uint8_t *)&payload, sizeof(mf_readblock_t)); PacketResponseNG resp; - if (!WaitForResponseTimeout(CMD_HF_MIFARE_READBL, &resp, 1500)) continue; + if (!WaitForResponseTimeout(CMD_HF_MIFARE_READBL, &resp, 1500)) goto skipReadBKey; - if (resp.status != PM3_SUCCESS) continue; + if (resp.status != PM3_SUCCESS) goto skipReadBKey; uint8_t *data = resp.data.asBytes; key64 = bytes_to_num(data + 10, 6); @@ -2021,6 +2021,7 @@ noValidKeyFound: } // Use the nested / hardnested attack +skipReadBKey: if (e_sector[current_sector_i].foundKey[current_key_type_i] == 0) { if (prng_type && (! nested_failed)) { uint8_t retries = 0; From a0c2de5602442110a73078a153280730fbc5c760 Mon Sep 17 00:00:00 2001 From: Matthias Konrath Date: Tue, 27 Aug 2019 20:28:28 +0200 Subject: [PATCH 0460/1854] Added an key found message to the read b key with a key feature. --- client/cmdhfmf.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 2f738af2c..99d6afd97 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -2016,6 +2016,11 @@ noValidKeyFound: e_sector[current_sector_i].foundKey[current_key_type_i] = 7; e_sector[current_sector_i].Key[current_key_type_i] = key64; num_to_bytes(key64, 6, tmp_key); + PrintAndLogEx(SUCCESS, "Found valid key: sector: %3d key type: %c key: " _YELLOW_("%s"), + current_sector_i, + current_key_type_i ? 'B' : 'A', + sprint_hex(tmp_key, sizeof(tmp_key)) + ); } } } From a64aa99b74c78ee38aa1a7e2a8823dfc15de9fa5 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 27 Aug 2019 21:19:44 +0200 Subject: [PATCH 0461/1854] remove tabs --- armsrc/optimized_cipher.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/armsrc/optimized_cipher.c b/armsrc/optimized_cipher.c index a54aebc61..0f762a8d6 100644 --- a/armsrc/optimized_cipher.c +++ b/armsrc/optimized_cipher.c @@ -101,16 +101,16 @@ static const uint8_t opt_select_LUT[256] = { /********************** the table above has been generated with this code: ******** #include "util.h" static void init_opt_select_LUT(void) { - for (int r = 0; r < 256; r++) { - uint8_t r_ls2 = r << 2; - uint8_t r_and_ls2 = r & r_ls2; - uint8_t r_or_ls2 = r | r_ls2; - uint8_t z0 = (r_and_ls2 >> 5) ^ ((r & ~r_ls2) >> 4) ^ ( r_or_ls2 >> 3); - uint8_t z1 = (r_or_ls2 >> 6) ^ ( r_or_ls2 >> 1) ^ (r >> 5) ^ r; - uint8_t z2 = ((r & ~r_ls2) >> 4) ^ (r_and_ls2 >> 3) ^ r; - opt_select_LUT[r] = (z0 & 4) | (z1 & 2) | (z2 & 1); - } - print_result("", opt_select_LUT, 256); + for (int r = 0; r < 256; r++) { + uint8_t r_ls2 = r << 2; + uint8_t r_and_ls2 = r & r_ls2; + uint8_t r_or_ls2 = r | r_ls2; + uint8_t z0 = (r_and_ls2 >> 5) ^ ((r & ~r_ls2) >> 4) ^ ( r_or_ls2 >> 3); + uint8_t z1 = (r_or_ls2 >> 6) ^ ( r_or_ls2 >> 1) ^ (r >> 5) ^ r; + uint8_t z2 = ((r & ~r_ls2) >> 4) ^ (r_and_ls2 >> 3) ^ r; + opt_select_LUT[r] = (z0 & 4) | (z1 & 2) | (z2 & 1); + } + print_result("", opt_select_LUT, 256); } ***********************************************************************************/ From 4b8c80ec33dd48eba9e7cc8edad4f0b311332a79 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 27 Aug 2019 21:56:03 +0200 Subject: [PATCH 0462/1854] return values.. --- client/loclass/cipher.c | 7 +++---- client/loclass/cipher.h | 1 + client/loclass/cipherutils.c | 11 +++++++---- client/loclass/cipherutils.h | 1 + 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/client/loclass/cipher.c b/client/loclass/cipher.c index 931f0c845..13f686b51 100644 --- a/client/loclass/cipher.c +++ b/client/loclass/cipher.c @@ -226,8 +226,8 @@ void doMAC(uint8_t *cc_nr_p, uint8_t *div_key_p, uint8_t mac[4]) { reverse_arraybytes(dest, sizeof(dest)); memcpy(mac, dest, 4); //free(cc_nr); - return; } + void doMAC_N(uint8_t *address_data_p, uint8_t address_data_size, uint8_t *div_key_p, uint8_t mac[4]) { uint8_t *address_data; uint8_t div_key[8]; @@ -245,7 +245,6 @@ void doMAC_N(uint8_t *address_data_p, uint8_t address_data_size, uint8_t *div_ke reverse_arraybytes(dest, sizeof(dest)); memcpy(mac, dest, 4); free(address_data); - return; } #ifndef ON_DEVICE @@ -267,8 +266,8 @@ int testMAC() { PrintAndLogEx(FAILED, "FAILED: MAC calculation failed:"); printarr(" Calculated_MAC", calculated_mac, 4); printarr(" Correct_MAC ", correct_MAC, 4); - return 1; + return PM3_ESOFT; } - return 0; + return PM3_SUCCESS; } #endif diff --git a/client/loclass/cipher.h b/client/loclass/cipher.h index b79dc47cd..7b1257aa5 100644 --- a/client/loclass/cipher.h +++ b/client/loclass/cipher.h @@ -39,6 +39,7 @@ #ifndef CIPHER_H #define CIPHER_H #include +#include "pm3_cmd.h" void doMAC(uint8_t *cc_nr_p, uint8_t *div_key_p, uint8_t mac[4]); void doMAC_N(uint8_t *address_data_p, uint8_t address_data_size, uint8_t *div_key_p, uint8_t mac[4]); diff --git a/client/loclass/cipherutils.c b/client/loclass/cipherutils.c index ee440fb73..b50268697 100644 --- a/client/loclass/cipherutils.c +++ b/client/loclass/cipherutils.c @@ -127,18 +127,21 @@ uint64_t x_bytes_to_num(uint8_t *src, size_t len) { } return num; } + uint8_t reversebytes(uint8_t b) { b = (b & 0xF0) >> 4 | (b & 0x0F) << 4; b = (b & 0xCC) >> 2 | (b & 0x33) << 2; b = (b & 0xAA) >> 1 | (b & 0x55) << 1; return b; } + void reverse_arraybytes(uint8_t *arr, size_t len) { uint8_t i; for (i = 0; i < len ; i++) { arr[i] = reversebytes(arr[i]); } } + void reverse_arraycopy(uint8_t *arr, uint8_t *dest, size_t len) { uint8_t i; for (i = 0; i < len ; i++) { @@ -202,9 +205,9 @@ static int testBitStream() { for (i = 0 ; i < ARRAYLEN(input) ; i++) { PrintAndLogEx(NORMAL, " IN %02x, OUT %02x", input[i], output[i]); } - return 1; + return PM3_ESOFT; } - return 0; + return PM3_SUCCESS; } static int testReversedBitstream() { @@ -232,9 +235,9 @@ static int testReversedBitstream() { for (i = 0 ; i < ARRAYLEN(input) ; i++) { PrintAndLogEx(NORMAL, " IN %02x, MIDDLE: %02x, OUT %02x", input[i], reverse[i], output[i]); } - return 1; + return PM3_ESOFT; } - return 0; + return PM3_SUCCESS; } diff --git a/client/loclass/cipherutils.h b/client/loclass/cipherutils.h index 70438d33b..6c90326a6 100644 --- a/client/loclass/cipherutils.h +++ b/client/loclass/cipherutils.h @@ -41,6 +41,7 @@ #include #include #include +#include "pm3_cmd.h" typedef struct { uint8_t *buffer; From 4fe7c7c9fa276120553679268db5489cb31ffb27 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 27 Aug 2019 23:17:02 +0200 Subject: [PATCH 0463/1854] remove utf8 dashes --- client/cmdhf14a.c | 2 +- client/emv/emv_tags.c | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index 8aea8db6c..b21e8dbd7 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -133,7 +133,7 @@ static const manufactureName manufactureMapping[] = { { 0x61, "Wearlinks Technology Inc. China" }, { 0x62, "Userstar Information Systems Co., Ltd Taiwan" }, { 0x63, "Pragmatic Printing Ltd. UK" }, - { 0x64, "Associacao do Laboratorio de Sistemas Integraveis Tecnologico – LSI-TEC Brazil" }, + { 0x64, "Associacao do Laboratorio de Sistemas Integraveis Tecnologico - LSI-TEC Brazil" }, { 0x65, "Tendyron Corporation China" }, { 0x66, "MUTO Smart Co., Ltd. Korea" }, { 0x67, "ON Semiconductor USA" }, diff --git a/client/emv/emv_tags.c b/client/emv/emv_tags.c index 72c1fe78e..296dcdf82 100644 --- a/client/emv/emv_tags.c +++ b/client/emv/emv_tags.c @@ -401,11 +401,11 @@ static const struct emv_tag emv_tags[] = { { 0xdf811b, "Kernel Configuration", EMV_TAG_GENERIC, NULL }, { 0xdf811c, "Max Lifetime of Torn Transaction Log Record", EMV_TAG_GENERIC, NULL }, { 0xdf811d, "Max Number of Torn Transaction Log Records", EMV_TAG_GENERIC, NULL }, - { 0xdf811e, "Mag-stripe CVM Capability – CVM Required", EMV_TAG_GENERIC, NULL }, + { 0xdf811e, "Mag-stripe CVM Capability - CVM Required", EMV_TAG_GENERIC, NULL }, { 0xdf811f, "Security Capability", EMV_TAG_GENERIC, NULL }, - { 0xdf8120, "Terminal Action Code – Default", EMV_TAG_GENERIC, NULL }, - { 0xdf8121, "Terminal Action Code – Denial", EMV_TAG_GENERIC, NULL }, - { 0xdf8122, "Terminal Action Code – Online", EMV_TAG_GENERIC, NULL }, + { 0xdf8120, "Terminal Action Code - Default", EMV_TAG_GENERIC, NULL }, + { 0xdf8121, "Terminal Action Code - Denial", EMV_TAG_GENERIC, NULL }, + { 0xdf8122, "Terminal Action Code - Online", EMV_TAG_GENERIC, NULL }, { 0xdf8123, "Reader Contactless Floor Limit", EMV_TAG_GENERIC, NULL }, { 0xdf8124, "Reader Contactless Transaction Limit (No On-device CVM)", EMV_TAG_GENERIC, NULL }, { 0xdf8125, "Reader Contactless Transaction Limit (On-device CVM)", EMV_TAG_GENERIC, NULL }, @@ -415,7 +415,7 @@ static const struct emv_tag emv_tags[] = { { 0xdf8129, "Outcome Parameter Set", EMV_TAG_GENERIC, NULL }, { 0xdf812a, "DD Card (Track1)", EMV_TAG_GENERIC, NULL }, { 0xdf812b, "DD Card (Track2)", EMV_TAG_GENERIC, NULL }, - { 0xdf812c, "Mag-stripe CVM Capability – No CVM Required", EMV_TAG_GENERIC, NULL }, + { 0xdf812c, "Mag-stripe CVM Capability - No CVM Required", EMV_TAG_GENERIC, NULL }, { 0xdf812d, "Message Hold Time", EMV_TAG_GENERIC, NULL }, { 0xff8101, "Torn Record", EMV_TAG_GENERIC, NULL }, From 254beefda2b3a466293edf9ae98bc1402f43a070 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 28 Aug 2019 00:03:27 +0200 Subject: [PATCH 0464/1854] Fix mingw utf8->cp850 support --- client/Makefile | 2 +- client/proxmark3.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/client/Makefile b/client/Makefile index d9e43d445..fc7fa520b 100644 --- a/client/Makefile +++ b/client/Makefile @@ -73,7 +73,7 @@ ifneq (,$(PM3_SHARE_PATH)) PM3CFLAGS += -DPM3_SHARE_PATH=\"$(PM3_SHARE_PATH)\" endif ifneq (,$(findstring MINGW,$(platform))) - PM3CFLAGS += -mno-ms-bitfields + PM3CFLAGS += -mno-ms-bitfields -fexec-charset=cp850 endif CXXFLAGS ?= -Wall -Werror -O3 PM3CXXFLAGS = $(CXXFLAGS) -I../include diff --git a/client/proxmark3.c b/client/proxmark3.c index 6555ac0f2..6a23f4804 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -31,7 +31,7 @@ static void showBanner(void) { PrintAndLogEx(NORMAL, "\n"); -#if defined(__linux__) || (__APPLE__) +#if defined(__linux__) || (__APPLE__) || (_WIN32) PrintAndLogEx(NORMAL, _BLUE_("██████╗ ███╗ ███╗ ████╗ ") " ...iceman fork"); PrintAndLogEx(NORMAL, _BLUE_("██╔══██╗████╗ ████║ ══█║") " ...dedicated to " _BLUE_("RDV40")); PrintAndLogEx(NORMAL, _BLUE_("██████╔╝██╔████╔██║ ████╔╝")); From 225b18d5fc048d08807b4928c5a2a2448de752ab Mon Sep 17 00:00:00 2001 From: Matthias Konrath Date: Wed, 28 Aug 2019 09:34:46 +0200 Subject: [PATCH 0465/1854] Implemented a function to safely load dictionaries. --- client/cmdhfmf.c | 17 ++++------- client/cmdlft55xx.c | 3 +- client/fileutils.c | 73 +++++++++++++++++++++++++++++++++++++++++++++ client/fileutils.h | 12 +++++++- 4 files changed, 91 insertions(+), 14 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 99d6afd97..87fa500a8 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -1591,7 +1591,6 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { uint8_t sectors_cnt = MIFARE_1K_MAXSECTOR; int block_cnt = MIFARE_1K_MAXBLOCK; uint8_t tmp_key[6] = {0}; - size_t data_length = 0; bool know_target_key = false; // For the timier uint64_t t1; @@ -1613,7 +1612,6 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { bool legacy_mfchk = false; bool prng_type = false; bool verbose = false; - int max_dictionary_size = 2000; // Parse the options given by the user ctmp = tolower(param_getchar(Cmd, 0)); @@ -1788,17 +1786,14 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { // Load the dictionary if (strlen(filename) != 0) { - keyBlock = calloc(6 * max_dictionary_size, sizeof(uint8_t)); - loadFileDICTIONARY(filename, keyBlock, &data_length, 6, &key_cnt); - if ((data_length / 6) > max_dictionary_size) { - // This is not a good solution (loadFileDICTIONARY needs a maxdatalen)! - // loadfiledictionary will reallocate to correct size. - PrintAndLogEx(FAILED, "Dictionary is too large: %d (allowed: %d)", data_length, max_dictionary_size); - free(keyBlock); - free(e_sector); - return PM3_EMALLOC; + int res = loadFileDICTIONARY_safe(filename, &keyBlock, 6, &key_cnt); + if (res != PM3_SUCCESS || key_cnt <= 0) { + PrintAndLogEx(FAILED, "An error occurred while loading the dictionary! (we will use the default keys now)"); + free(keyBlock); // free the memory, just in case an allocation happened + goto useDefaultKeys; } } else { +useDefaultKeys: keyBlock = calloc(ARRAYLEN(g_mifare_default_keys), 6); if (keyBlock == NULL) { free(e_sector); diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 80954dddb..3802beab9 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -2127,7 +2127,6 @@ static int CmdT55xxChkPwds(const char *Cmd) { if (use_pwd_file) { uint16_t keycount = 0; - size_t datalen = 0; // TODO, a way of reallocating memory if file was larger keyBlock = calloc(4 * 200, sizeof(uint8_t)); @@ -2136,7 +2135,7 @@ static int CmdT55xxChkPwds(const char *Cmd) { return PM3_ESOFT; } - int res = loadFileDICTIONARY(filename, keyBlock, &datalen, 4, &keycount); + int res = loadFileDICTIONARY_safe(filename, &keyBlock, 4, &keycount); if (res || keycount == 0) { PrintAndLogEx(WARNING, "No keys found in file"); free(keyBlock); diff --git a/client/fileutils.c b/client/fileutils.c index 15c6efec6..ff2dc510f 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -649,6 +649,79 @@ out: return retval; } +int loadFileDICTIONARY_safe(const char *preferredName, uint8_t **data, uint8_t keylen, uint16_t *keycnt) { + + int block_size = 512; + int allocation_size = block_size; + size_t counter = 0; + int retval = PM3_SUCCESS; + char *path; + if (searchFile(&path, DICTIONARIES_SUBDIR, preferredName, ".dic") != PM3_SUCCESS) + return PM3_EFILE; + + // t5577 == 4bytes + // mifare == 6 bytes + // iclass == 8 bytes + // default to 6 bytes. + if (keylen != 4 && keylen != 6 && keylen != 8) { + keylen = 6; + } + + // double up since its chars + keylen <<= 1; + + char line[255]; + + // allocate some space for the dictionary + *data = (uint8_t*) malloc(keylen * allocation_size * sizeof(uint8_t)); + if (*data == NULL) return PM3_EFILE; + + FILE *f = fopen(path, "r"); + if (!f) { + PrintAndLogEx(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", path); + retval = PM3_EFILE; + goto out; } + + // read file + while (fgets(line, sizeof(line), f)) { + // check if we have enough space (if not allocate more) + if ((*keycnt) >= allocation_size) { + allocation_size += block_size; + *data = (uint8_t*) realloc((void*) *data, keylen * allocation_size * sizeof(uint8_t)); + if (*data == NULL) return PM3_EFILE; + } + + // add null terminator + line[keylen] = 0; + + // smaller keys than expected is skipped + if (strlen(line) < keylen) + continue; + + // The line start with # is comment, skip + if (line[0] == '#') + continue; + + if (!isxdigit(line[0])) { + PrintAndLogEx(FAILED, "file content error. '%s' must include " _BLUE_("%2d") "HEX symbols", line, keylen); + continue; + } + + uint64_t key = strtoull(line, NULL, 16); + + num_to_bytes(key, keylen >> 1, *data + counter); + (*keycnt)++; + memset(line, 0, sizeof(line)); + counter += (keylen >> 1); + } + fclose(f); + PrintAndLogEx(SUCCESS, "loaded " _GREEN_("%2d") "keys from dictionary file " _YELLOW_("%s"), *keycnt, path); + +out: + free(path); + return retval; +} + int convertOldMfuDump(uint8_t **dump, size_t *dumplen) { if (!dump || !dumplen || *dumplen < OLD_MFU_DUMP_PREFIX_LENGTH) return 1; diff --git a/client/fileutils.h b/client/fileutils.h index 03a47112e..b2c16c282 100644 --- a/client/fileutils.h +++ b/client/fileutils.h @@ -149,7 +149,6 @@ int loadFileEML(const char *preferredName, void *data, size_t *datalen); */ int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_t *datalen); - /** * @brief Utility function to load data from a DICTIONARY textfile. This method takes a preferred name. * E.g. mfc_default_keys.dic @@ -163,6 +162,17 @@ int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_ */ int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, uint8_t keylen, uint16_t *keycnt); +/** + * @brief Utility function to load data from a DICTIONARY safely into a textfile. This method takes a preferred name. + * E.g. mfc_default_keys.dic + * + * @param preferredName + * @param data The data array to store the loaded bytes from file + * @param keylen the number of bytes a key per row is + * @return 0 for ok, 1 for failz +*/ +int loadFileDICTIONARY_safe(const char *preferredName, uint8_t **data, uint8_t keylen, uint16_t *keycnt); + /** * @brief Utility function to check and convert old mfu dump format to new * From 9dc3c39a95c0d06abfd5524339060c220ba56fba Mon Sep 17 00:00:00 2001 From: Matthias Konrath Date: Wed, 28 Aug 2019 09:45:11 +0200 Subject: [PATCH 0466/1854] Added additional checks to the from load dictionary returned data points. --- client/cmdhfmf.c | 6 +++--- client/cmdlft55xx.c | 11 ++--------- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 87fa500a8..66aca7421 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -1585,7 +1585,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { uint64_t key64 = 0; bool calibrate = true; // Attack key storage variables - uint8_t *keyBlock; + uint8_t *keyBlock = NULL; uint16_t key_cnt = 0; sector_t *e_sector; uint8_t sectors_cnt = MIFARE_1K_MAXSECTOR; @@ -1787,9 +1787,9 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { // Load the dictionary if (strlen(filename) != 0) { int res = loadFileDICTIONARY_safe(filename, &keyBlock, 6, &key_cnt); - if (res != PM3_SUCCESS || key_cnt <= 0) { + if (res != PM3_SUCCESS || key_cnt <= 0 || keyBlock == NULL) { PrintAndLogEx(FAILED, "An error occurred while loading the dictionary! (we will use the default keys now)"); - free(keyBlock); // free the memory, just in case an allocation happened + if (keyBlock != NULL) free(keyBlock); goto useDefaultKeys; } } else { diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 3802beab9..f256a5ee3 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -2128,17 +2128,10 @@ static int CmdT55xxChkPwds(const char *Cmd) { if (use_pwd_file) { uint16_t keycount = 0; - // TODO, a way of reallocating memory if file was larger - keyBlock = calloc(4 * 200, sizeof(uint8_t)); - if (keyBlock == NULL) { - PrintAndLogEx(ERR, "error, cannot allocate memory "); - return PM3_ESOFT; - } - int res = loadFileDICTIONARY_safe(filename, &keyBlock, 4, &keycount); - if (res || keycount == 0) { + if (res || keycount == 0 || keyBlock == NULL) { PrintAndLogEx(WARNING, "No keys found in file"); - free(keyBlock); + if (keyBlock != NULL) free(keyBlock); return PM3_ESOFT; } From ae7b0de2c9965156c3bb692cf627c3a428792430 Mon Sep 17 00:00:00 2001 From: Matthias Konrath Date: Wed, 28 Aug 2019 09:49:21 +0200 Subject: [PATCH 0467/1854] Fixed a typo and added and improved the checks for the returned data of loadFileDICTIONARY_safe. --- client/cmdlft55xx.c | 2 +- client/fileutils.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index f256a5ee3..48baea594 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -2129,7 +2129,7 @@ static int CmdT55xxChkPwds(const char *Cmd) { uint16_t keycount = 0; int res = loadFileDICTIONARY_safe(filename, &keyBlock, 4, &keycount); - if (res || keycount == 0 || keyBlock == NULL) { + if (res || keycount <= 0 || keyBlock == NULL) { PrintAndLogEx(WARNING, "No keys found in file"); if (keyBlock != NULL) free(keyBlock); return PM3_ESOFT; diff --git a/client/fileutils.h b/client/fileutils.h index b2c16c282..1428c0d8c 100644 --- a/client/fileutils.h +++ b/client/fileutils.h @@ -163,7 +163,7 @@ int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_ int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, uint8_t keylen, uint16_t *keycnt); /** - * @brief Utility function to load data from a DICTIONARY safely into a textfile. This method takes a preferred name. + * @brief Utility function to load data safely from a DICTIONARY textfile. This method takes a preferred name. * E.g. mfc_default_keys.dic * * @param preferredName From 1ce10cfea6da4d278c93203e7318f17a9d6bfaf5 Mon Sep 17 00:00:00 2001 From: Matthias Konrath Date: Wed, 28 Aug 2019 10:09:01 +0200 Subject: [PATCH 0468/1854] Added additional checks (loadFileDICTIONARY_safe). --- client/cmdlft55xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 48baea594..f17c8e192 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -2129,7 +2129,7 @@ static int CmdT55xxChkPwds(const char *Cmd) { uint16_t keycount = 0; int res = loadFileDICTIONARY_safe(filename, &keyBlock, 4, &keycount); - if (res || keycount <= 0 || keyBlock == NULL) { + if (res != PM3_SUCCESS || keycount <= 0 || keyBlock == NULL) { PrintAndLogEx(WARNING, "No keys found in file"); if (keyBlock != NULL) free(keyBlock); return PM3_ESOFT; From 7eb79732ff862ab7cb33db55259ec457c349590d Mon Sep 17 00:00:00 2001 From: Matthias Konrath Date: Wed, 28 Aug 2019 10:38:56 +0200 Subject: [PATCH 0469/1854] Added security features to the loadFileDICTIONARY_safe function (memset after a realloc). --- client/fileutils.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/client/fileutils.c b/client/fileutils.c index ff2dc510f..787ce0cfb 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -673,7 +673,7 @@ int loadFileDICTIONARY_safe(const char *preferredName, uint8_t **data, uint8_t k char line[255]; // allocate some space for the dictionary - *data = (uint8_t*) malloc(keylen * allocation_size * sizeof(uint8_t)); + *data = (uint8_t*) calloc(keylen * allocation_size, sizeof(uint8_t)); if (*data == NULL) return PM3_EFILE; FILE *f = fopen(path, "r"); @@ -688,7 +688,12 @@ int loadFileDICTIONARY_safe(const char *preferredName, uint8_t **data, uint8_t k if ((*keycnt) >= allocation_size) { allocation_size += block_size; *data = (uint8_t*) realloc((void*) *data, keylen * allocation_size * sizeof(uint8_t)); - if (*data == NULL) return PM3_EFILE; + if (*data == NULL) { + return PM3_EFILE; + } else { + // zero the new memeory (safety first) + memset(*data + counter, 0, block_size); + } } // add null terminator From e259b26d60b281ad5d25aaa63b34e4611c5d434b Mon Sep 17 00:00:00 2001 From: Matthias Konrath Date: Wed, 28 Aug 2019 10:45:45 +0200 Subject: [PATCH 0470/1854] Streamlined the naming conventen and types. --- client/cmdhfmf.c | 6 +++++- client/cmdlft55xx.c | 2 +- client/fileutils.c | 14 +++++++------- client/fileutils.h | 2 +- 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 66aca7421..11aded711 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -1786,7 +1786,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { // Load the dictionary if (strlen(filename) != 0) { - int res = loadFileDICTIONARY_safe(filename, &keyBlock, 6, &key_cnt); + int res = loadFileDICTIONARY_safe(filename, (void**) &keyBlock, 6, &key_cnt); if (res != PM3_SUCCESS || key_cnt <= 0 || keyBlock == NULL) { PrintAndLogEx(FAILED, "An error occurred while loading the dictionary! (we will use the default keys now)"); if (keyBlock != NULL) free(keyBlock); @@ -1806,6 +1806,10 @@ useDefaultKeys: key_cnt = ARRAYLEN(g_mifare_default_keys); } + for (int k = 0; k < key_cnt; k++) { + PrintAndLogEx(SUCCESS, "ID: %d KEY: %s", k, sprint_hex((keyBlock + (6 * k)), sizeof(key))); + } + // Use the dictionary to find sector keys on the card PrintAndLogEx(INFO, "Enter dictionary run..."); diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index f17c8e192..965a5db0b 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -2128,7 +2128,7 @@ static int CmdT55xxChkPwds(const char *Cmd) { if (use_pwd_file) { uint16_t keycount = 0; - int res = loadFileDICTIONARY_safe(filename, &keyBlock, 4, &keycount); + int res = loadFileDICTIONARY_safe(filename, (void**) &keyBlock, 4, &keycount); if (res != PM3_SUCCESS || keycount <= 0 || keyBlock == NULL) { PrintAndLogEx(WARNING, "No keys found in file"); if (keyBlock != NULL) free(keyBlock); diff --git a/client/fileutils.c b/client/fileutils.c index 787ce0cfb..1b2073ed2 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -649,7 +649,7 @@ out: return retval; } -int loadFileDICTIONARY_safe(const char *preferredName, uint8_t **data, uint8_t keylen, uint16_t *keycnt) { +int loadFileDICTIONARY_safe(const char *preferredName, void **pdata, uint8_t keylen, uint16_t *keycnt) { int block_size = 512; int allocation_size = block_size; @@ -673,8 +673,8 @@ int loadFileDICTIONARY_safe(const char *preferredName, uint8_t **data, uint8_t k char line[255]; // allocate some space for the dictionary - *data = (uint8_t*) calloc(keylen * allocation_size, sizeof(uint8_t)); - if (*data == NULL) return PM3_EFILE; + *pdata = calloc(keylen * allocation_size, sizeof(uint8_t)); + if (*pdata == NULL) return PM3_EFILE; FILE *f = fopen(path, "r"); if (!f) { @@ -687,12 +687,12 @@ int loadFileDICTIONARY_safe(const char *preferredName, uint8_t **data, uint8_t k // check if we have enough space (if not allocate more) if ((*keycnt) >= allocation_size) { allocation_size += block_size; - *data = (uint8_t*) realloc((void*) *data, keylen * allocation_size * sizeof(uint8_t)); - if (*data == NULL) { + *pdata = realloc(*pdata, keylen * allocation_size * sizeof(uint8_t)); + if (*pdata == NULL) { return PM3_EFILE; } else { // zero the new memeory (safety first) - memset(*data + counter, 0, block_size); + memset(*pdata + counter, 0, block_size); } } @@ -714,7 +714,7 @@ int loadFileDICTIONARY_safe(const char *preferredName, uint8_t **data, uint8_t k uint64_t key = strtoull(line, NULL, 16); - num_to_bytes(key, keylen >> 1, *data + counter); + num_to_bytes(key, keylen >> 1, *pdata + counter); (*keycnt)++; memset(line, 0, sizeof(line)); counter += (keylen >> 1); diff --git a/client/fileutils.h b/client/fileutils.h index 1428c0d8c..d6392c6b1 100644 --- a/client/fileutils.h +++ b/client/fileutils.h @@ -171,7 +171,7 @@ int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, u * @param keylen the number of bytes a key per row is * @return 0 for ok, 1 for failz */ -int loadFileDICTIONARY_safe(const char *preferredName, uint8_t **data, uint8_t keylen, uint16_t *keycnt); +int loadFileDICTIONARY_safe(const char *preferredName, void **pdata, uint8_t keylen, uint16_t *keycnt); /** * @brief Utility function to check and convert old mfu dump format to new From 7237a9638b16d89ca481febec7d197f86b9bdf02 Mon Sep 17 00:00:00 2001 From: Matthias Konrath Date: Wed, 28 Aug 2019 11:19:54 +0200 Subject: [PATCH 0471/1854] Removed debugging stuff. --- client/cmdhfmf.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 11aded711..0b7727031 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -1806,10 +1806,6 @@ useDefaultKeys: key_cnt = ARRAYLEN(g_mifare_default_keys); } - for (int k = 0; k < key_cnt; k++) { - PrintAndLogEx(SUCCESS, "ID: %d KEY: %s", k, sprint_hex((keyBlock + (6 * k)), sizeof(key))); - } - // Use the dictionary to find sector keys on the card PrintAndLogEx(INFO, "Enter dictionary run..."); From 2290b2bd880df92d730493955230889c3835f64c Mon Sep 17 00:00:00 2001 From: Matthias Konrath Date: Wed, 28 Aug 2019 11:30:30 +0200 Subject: [PATCH 0472/1854] Fixed the description of the loadFileDICTIONARY_safe function. --- client/fileutils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/fileutils.h b/client/fileutils.h index d6392c6b1..113cac222 100644 --- a/client/fileutils.h +++ b/client/fileutils.h @@ -167,7 +167,7 @@ int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, u * E.g. mfc_default_keys.dic * * @param preferredName - * @param data The data array to store the loaded bytes from file + * @param pdata A pointer to a pointer (for reverencing the loaded dictionary) * @param keylen the number of bytes a key per row is * @return 0 for ok, 1 for failz */ From 5167507a831fb411844aab99ba8888b20e416209 Mon Sep 17 00:00:00 2001 From: Matthias Konrath Date: Wed, 28 Aug 2019 12:14:40 +0200 Subject: [PATCH 0473/1854] Fixed the loadFileDICTIONARY_safe memset alignment. Thanks to @doegox for pointing that out. --- client/fileutils.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/fileutils.c b/client/fileutils.c index 1b2073ed2..500bb7ef8 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -691,8 +691,8 @@ int loadFileDICTIONARY_safe(const char *preferredName, void **pdata, uint8_t key if (*pdata == NULL) { return PM3_EFILE; } else { - // zero the new memeory (safety first) - memset(*pdata + counter, 0, block_size); + // zero the new memory (safety first) + memset(*pdata + allocation_size - block_size, 0, block_size); } } From 6c76e2ed5b99da876572572fc1937fde16bfb22d Mon Sep 17 00:00:00 2001 From: Matthias Konrath Date: Wed, 28 Aug 2019 14:20:52 +0200 Subject: [PATCH 0474/1854] Restyled to the autopwn command output. --- client/cmdhfmf.c | 66 ++++++++++++++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 25 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 0b7727031..ff0324b34 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -1733,8 +1733,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { PrintAndLogEx(WARNING, "No known key was supplied, key recovery might fail"); else { if (mfCheckKeys(FirstBlockOfSector(blockNo), keyType, true, 1, key, &key64) == PM3_SUCCESS) { - PrintAndLogEx(INFO, "Using key for the nested / hardnested | sector:" - _RED_("%3d") " key type: "_RED_("%c") " key: " _RED_("%s"), + PrintAndLogEx(INFO, "Using valid key: sector: %3d key type: %c key: " _YELLOW_("%s") "(used for nested / hardnested attack)", blockNo, keyType ? 'B' : 'A', sprint_hex(key, sizeof(key)) @@ -1745,7 +1744,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { e_sector[blockNo].foundKey[keyType] = 3; } else { know_target_key = false; - PrintAndLogEx(FAILED, "Key is wrong. Can't authenticate to sector:"_RED_("%3d") " key type:"_RED_("%c") " key: " _RED_("%s"), + PrintAndLogEx(FAILED, "Key is wrong. Can't authenticate to sector:"_RED_("%3d") " key type: "_RED_("%c") " key: " _RED_("%s"), blockNo, keyType ? 'B' : 'A', sprint_hex(key, sizeof(key)) @@ -1759,11 +1758,6 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { if (mfCheckKeys(FirstBlockOfSector(i), j, true, 1, key, &key64) == PM3_SUCCESS) { e_sector[i].Key[j] = bytes_to_num(key, 6); e_sector[i].foundKey[j] = 4; - PrintAndLogEx(SUCCESS, "Found valid key: sector: %3d key type: %c key: " _YELLOW_("%s"), - i, - j ? 'B' : 'A', - sprint_hex(key, sizeof(key)) - ); // If the user supplied secctor / keytype was wrong --> just be nice and correct it ;) if (know_target_key == false) { @@ -1771,10 +1765,15 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { know_target_key = true; blockNo = i; keyType = j; - PrintAndLogEx(SUCCESS, "using key nested / hardnested attack: sector:" - _RED_("%3d") " key type: "_RED_("%c") " key: " _RED_("%s"), - blockNo, - keyType ? 'B' : 'A', + PrintAndLogEx(SUCCESS, "Found valid key: sector: %3d key type: %c key: " _YELLOW_("%s") "(used for nested / hardnested attack)", + i, + j ? 'B' : 'A', + sprint_hex(key, sizeof(key)) + ); + } else { + PrintAndLogEx(SUCCESS, "Found valid key: sector: %3d key type: %c key: " _YELLOW_("%s"), + i, + j ? 'B' : 'A', sprint_hex(key, sizeof(key)) ); } @@ -1807,7 +1806,7 @@ useDefaultKeys: } // Use the dictionary to find sector keys on the card - PrintAndLogEx(INFO, "Enter dictionary run..."); + PrintAndLogEx(INFO, _YELLOW_("======================= START DICTIONARY ATTACK =======================")); if (legacy_mfchk) { // Check all the sectors @@ -1862,17 +1861,15 @@ useDefaultKeys: lastChunk = false; } // end strategy } + PrintAndLogEx(INFO, _YELLOW_("======================= STOP DICTIONARY ATTACK =======================")); + // Analyse the dictionary attack for (int i = 0; i < sectors_cnt; i++) { for (int j = 0; j < 2; j++) { if (e_sector[i].foundKey[j] == 1) { num_to_bytes(e_sector[i].Key[j], 6, tmp_key); - PrintAndLogEx(SUCCESS, "Found valid key: sector: %3d key type: %c key: " _YELLOW_("%s"), - i, - j ? 'B' : 'A', - sprint_hex(tmp_key, sizeof(tmp_key)) - ); + // Store valid credentials for the nested / hardnested attack if none exist if (know_target_key == false) { @@ -1880,11 +1877,16 @@ useDefaultKeys: know_target_key = true; blockNo = i; keyType = j; - PrintAndLogEx(SUCCESS, "Using key nested / hardnested attack: sector:" - _RED_("%3d") " key type:"_RED_("%c") " key: " _RED_("%s"), - blockNo, - keyType ? 'B' : 'A', - sprint_hex(key, sizeof(key)) + PrintAndLogEx(SUCCESS, "Found valid key: sector: %3d key type: %c key: " _YELLOW_("%s") "(used for nested / hardnested attack)", + i, + j ? 'B' : 'A', + sprint_hex(tmp_key, sizeof(tmp_key)) + ); + } else { + PrintAndLogEx(SUCCESS, "Found valid key: sector: %3d key type: %c key: " _YELLOW_("%s"), + i, + j ? 'B' : 'A', + sprint_hex(tmp_key, sizeof(tmp_key)) ); } } @@ -1895,8 +1897,9 @@ useDefaultKeys: if (know_target_key == false) { // Check if the darkside attack can be used if (prng_type) { - PrintAndLogEx(INFO, "Enter darkside run..."); + PrintAndLogEx(INFO, _YELLOW_("======================= START DARKSIDE ATTACK =======================")); int isOK = mfDarkside(FirstBlockOfSector(blockNo), keyType, &key64); + PrintAndLogEx(INFO, _YELLOW_("======================= STOP DARKSIDE ATTACK =======================")); switch (isOK) { case -1 : PrintAndLogEx(WARNING, "\nButton pressed. Aborted."); @@ -1932,6 +1935,11 @@ useDefaultKeys: // Store the keys e_sector[blockNo].Key[keyType] = bytes_to_num(key, 6); e_sector[blockNo].foundKey[keyType] = 2; + PrintAndLogEx(SUCCESS, "Found valid key: sector: %3d key type: %c key: " _YELLOW_("%s") "(used for nested / hardnested attack)", + blockNo, + keyType ? 'B' : 'A', + sprint_hex(key, sizeof(key)) + ); } else { noValidKeyFound: PrintAndLogEx(FAILED, "No usable key was found!"); @@ -1980,7 +1988,10 @@ noValidKeyFound: if (current_key_type_i == 1) { if (e_sector[current_sector_i].foundKey[0] && !e_sector[current_sector_i].foundKey[1]) { - PrintAndLogEx(INFO, "Reading B key: sector: %3d", current_sector_i); + PrintAndLogEx(INFO, "Reading B key: sector: %3d key type: %c key: ?? ?? ?? ?? ?? ??", + current_sector_i, + current_key_type_i ? 'B' : 'A' + ); uint8_t sectrail = (FirstBlockOfSector(current_sector_i) + NumBlocksPerSector(current_sector_i) - 1); mf_readblock_t payload; @@ -2026,6 +2037,7 @@ skipReadBKey: if (prng_type && (! nested_failed)) { uint8_t retries = 0; tryNested: + PrintAndLogEx(INFO, _YELLOW_("======================= START NESTED ATTACK =======================")); PrintAndLogEx(INFO, "Sector no: %3d, target key type: %c", current_sector_i, current_key_type_i ? 'B' : 'A'); @@ -2066,8 +2078,10 @@ tryNested: free(e_sector); return PM3_ESOFT; } + PrintAndLogEx(INFO, _YELLOW_("======================= STOP NESTED ATTACK =======================")); } else { tryHardnested: // If the nested attack fails then we try the hardnested attack + PrintAndLogEx(INFO, _YELLOW_("======================= START HARDNESTED ATTACK =======================")); PrintAndLogEx(INFO, "Sector no: %3d, target key type: %c, Slow: %s", current_sector_i, current_key_type_i ? 'B' : 'A', @@ -2094,6 +2108,8 @@ tryHardnested: // If the nested attack fails then we try the hardnested attack num_to_bytes(foundkey, 6, tmp_key); e_sector[current_sector_i].Key[current_key_type_i] = foundkey; e_sector[current_sector_i].foundKey[current_key_type_i] = 6; + + PrintAndLogEx(INFO, _YELLOW_("======================= STOP HARDNESTED ATTACK =======================")); } // Check if the key was found if (e_sector[current_sector_i].foundKey[current_key_type_i]) { From 2e29b361c540609976f6ad2f3d25e4ec14094937 Mon Sep 17 00:00:00 2001 From: Matthias Konrath Date: Wed, 28 Aug 2019 15:57:21 +0200 Subject: [PATCH 0475/1854] Restyled the autopwn command output according to @doegox --- client/cmdhfmf.c | 85 +++++++++++++++++++++++++++++++----------------- client/cmdhfmf.h | 1 + 2 files changed, 56 insertions(+), 30 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index ff0324b34..66c50758f 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -1741,7 +1741,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { // Store the key for the nested / hardnested attack (if supplied by the user) e_sector[blockNo].Key[keyType] = bytes_to_num(key, 6); - e_sector[blockNo].foundKey[keyType] = 3; + e_sector[blockNo].foundKey[keyType] = 'U'; } else { know_target_key = false; PrintAndLogEx(FAILED, "Key is wrong. Can't authenticate to sector:"_RED_("%3d") " key type: "_RED_("%c") " key: " _RED_("%s"), @@ -1757,7 +1757,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { if (e_sector[i].foundKey[j] == 0) { if (mfCheckKeys(FirstBlockOfSector(i), j, true, 1, key, &key64) == PM3_SUCCESS) { e_sector[i].Key[j] = bytes_to_num(key, 6); - e_sector[i].foundKey[j] = 4; + e_sector[i].foundKey[j] = 'U'; // If the user supplied secctor / keytype was wrong --> just be nice and correct it ;) if (know_target_key == false) { @@ -1819,7 +1819,7 @@ useDefaultKeys: fflush(stdout); if (mfCheckKeys(FirstBlockOfSector(i), j, true, 1, (keyBlock + (6 * k)), &key64) == PM3_SUCCESS) { e_sector[i].Key[j] = bytes_to_num((keyBlock + (6 * k)), 6); - e_sector[i].foundKey[j] = 1; + e_sector[i].foundKey[j] = 'D'; break; } } @@ -1868,6 +1868,7 @@ useDefaultKeys: for (int i = 0; i < sectors_cnt; i++) { for (int j = 0; j < 2; j++) { if (e_sector[i].foundKey[j] == 1) { + e_sector[i].foundKey[j] = 'D'; num_to_bytes(e_sector[i].Key[j], 6, tmp_key); @@ -1934,7 +1935,7 @@ useDefaultKeys: } // Store the keys e_sector[blockNo].Key[keyType] = bytes_to_num(key, 6); - e_sector[blockNo].foundKey[keyType] = 2; + e_sector[blockNo].foundKey[keyType] = 'S'; PrintAndLogEx(SUCCESS, "Found valid key: sector: %3d key type: %c key: " _YELLOW_("%s") "(used for nested / hardnested attack)", blockNo, keyType ? 'B' : 'A', @@ -1973,7 +1974,7 @@ noValidKeyFound: // Check if the key works if (mfCheckKeys(FirstBlockOfSector(i), j, true, 1, tmp_key, &key64) == PM3_SUCCESS) { e_sector[i].Key[j] = bytes_to_num(tmp_key, 6); - e_sector[i].foundKey[j] = 4; + e_sector[i].foundKey[j] = 'R'; PrintAndLogEx(SUCCESS, "Found valid key: sector: %3d key type: %c key: " _YELLOW_("%s"), i, j ? 'B' : 'A', @@ -1988,7 +1989,7 @@ noValidKeyFound: if (current_key_type_i == 1) { if (e_sector[current_sector_i].foundKey[0] && !e_sector[current_sector_i].foundKey[1]) { - PrintAndLogEx(INFO, "Reading B key: sector: %3d key type: %c key: ?? ?? ?? ?? ?? ??", + PrintAndLogEx(INFO, "Reading B key: sector: %3d key type: %c", current_sector_i, current_key_type_i ? 'B' : 'A' ); @@ -2010,16 +2011,8 @@ noValidKeyFound: uint8_t *data = resp.data.asBytes; key64 = bytes_to_num(data + 10, 6); - if (verbose){ - num_to_bytes(key64, 6, tmp_key); - PrintAndLogEx(INFO, "Discovered key: sector: %3d key type: %c key: " _YELLOW_("%s"), - current_sector_i, - current_key_type_i ? 'B' : 'A', - sprint_hex(tmp_key, sizeof(tmp_key)) - ); - } if (key64) { - e_sector[current_sector_i].foundKey[current_key_type_i] = 7; + e_sector[current_sector_i].foundKey[current_key_type_i] = 'A'; e_sector[current_sector_i].Key[current_key_type_i] = key64; num_to_bytes(key64, 6, tmp_key); PrintAndLogEx(SUCCESS, "Found valid key: sector: %3d key type: %c key: " _YELLOW_("%s"), @@ -2027,6 +2020,11 @@ noValidKeyFound: current_key_type_i ? 'B' : 'A', sprint_hex(tmp_key, sizeof(tmp_key)) ); + } else { + PrintAndLogEx(WARNING, "Unknown B key: sector: %3d key type: %c (reading the B key was not possible, maybe due to insufficient access rights) ", + current_sector_i, + current_key_type_i ? 'B' : 'A' + ); } } } @@ -2036,8 +2034,9 @@ skipReadBKey: if (e_sector[current_sector_i].foundKey[current_key_type_i] == 0) { if (prng_type && (! nested_failed)) { uint8_t retries = 0; -tryNested: PrintAndLogEx(INFO, _YELLOW_("======================= START NESTED ATTACK =======================")); + +tryNested: PrintAndLogEx(INFO, "Sector no: %3d, target key type: %c", current_sector_i, current_key_type_i ? 'B' : 'A'); @@ -2071,7 +2070,7 @@ tryNested: case -5 : calibrate = false; e_sector[current_sector_i].Key[current_key_type_i] = bytes_to_num(tmp_key, 6); - e_sector[current_sector_i].foundKey[current_key_type_i] = 5; + e_sector[current_sector_i].foundKey[current_key_type_i] = 'N'; break; default : PrintAndLogEx(ERR, "unknown Error.\n"); @@ -2107,7 +2106,7 @@ tryHardnested: // If the nested attack fails then we try the hardnested attack // Copy the found key to the tmp_key variale (for the following print statement, and the mfCheckKeys above) num_to_bytes(foundkey, 6, tmp_key); e_sector[current_sector_i].Key[current_key_type_i] = foundkey; - e_sector[current_sector_i].foundKey[current_key_type_i] = 6; + e_sector[current_sector_i].foundKey[current_key_type_i] = 'H'; PrintAndLogEx(INFO, _YELLOW_("======================= STOP HARDNESTED ATTACK =======================")); } @@ -2127,20 +2126,9 @@ tryHardnested: // If the nested attack fails then we try the hardnested attack // Show the results to the user PrintAndLogEx(NORMAL, ""); PrintAndLogEx(INFO, "Found Keys:"); - printKeyTable(sectors_cnt, e_sector); - if (verbose) { - PrintAndLogEx(INFO, " Key res types:"); - PrintAndLogEx(INFO, " 1: Dictionary"); - PrintAndLogEx(INFO, " 2: Darkside attack"); - PrintAndLogEx(INFO, " 3: User supplied"); - PrintAndLogEx(INFO, " 4: Reused"); - PrintAndLogEx(INFO, " 5: Nested"); - PrintAndLogEx(INFO, " 6: Hardnested"); - PrintAndLogEx(INFO, " 7: Read B key with A key"); - } + printKeyTableAutopwn(sectors_cnt, e_sector); PrintAndLogEx(INFO, "\nSaving keys"); - createMfcKeyDump(sectors_cnt, e_sector, GenerateFilename("hf-mf-", "-key.bin")); PrintAndLogEx(SUCCESS, "Transferring keys to simulator memory (Cmd Error: 04 can occur)"); @@ -3198,6 +3186,43 @@ void printKeyTable(uint8_t sectorscnt, sector_t *e_sector) { PrintAndLogEx(NORMAL, "|---|----------------|---|----------------|---|"); } +void printKeyTableAutopwn(uint8_t sectorscnt, sector_t *e_sector) { + char strA[12 + 1] = {0}; + char strB[12 + 1] = {0}; + PrintAndLogEx(NORMAL, "|---|----------------|---|----------------|---|"); + PrintAndLogEx(NORMAL, "|sec|key A |res|key B |res|"); + PrintAndLogEx(NORMAL, "|---|----------------|---|----------------|---|"); + for (uint8_t i = 0; i < sectorscnt; ++i) { + + snprintf(strA, sizeof(strA), "------------"); + snprintf(strB, sizeof(strB), "------------"); + + if (e_sector[i].foundKey[0]) + snprintf(strA, sizeof(strA), "%012" PRIx64, e_sector[i].Key[0]); + + if (e_sector[i].foundKey[1]) + snprintf(strB, sizeof(strB), "%012" PRIx64, e_sector[i].Key[1]); + + + PrintAndLogEx(NORMAL, "|%03d| %s | " _YELLOW_("%c")"| %s | " _YELLOW_("%c")"|" + , i + , strA, e_sector[i].foundKey[0] + , strB, e_sector[i].foundKey[1] + ); + } + PrintAndLogEx(NORMAL, "|---|----------------|---|----------------|---|"); + PrintAndLogEx(NORMAL, "( " + _YELLOW_("D") ":Dictionary / " + _YELLOW_("S") ":darkSide / " + _YELLOW_("U") ":User / " + _YELLOW_("R") ":Reused / " + _YELLOW_("N") ":Nested / " + _YELLOW_("H") ":Hardnested / " + _YELLOW_("A") ":keyA " + ")" + ); +} + // EMULATOR COMMANDS static int CmdHF14AMfEGet(const char *Cmd) { char c = tolower(param_getchar(Cmd, 0)); diff --git a/client/cmdhfmf.h b/client/cmdhfmf.h index 55997bd87..e9970cfb2 100644 --- a/client/cmdhfmf.h +++ b/client/cmdhfmf.h @@ -22,5 +22,6 @@ int CmdHF14AMfDbg(const char *Cmd); // used by cmd hf mfu dbg void showSectorTable(void); void readerAttack(nonces_t data, bool setEmulatorMem, bool verbose); void printKeyTable(uint8_t sectorscnt, sector_t *e_sector); +void printKeyTableAutopwn(uint8_t sectorscnt, sector_t *e_sector); void printKeyTable_fast(uint8_t sectorscnt, icesector_t *e_sector, uint64_t bar, uint64_t foo); #endif From e4159b7cb3f5ae57d62aeb8cb9c43648ed8f7582 Mon Sep 17 00:00:00 2001 From: Matthias Konrath Date: Wed, 28 Aug 2019 18:39:01 +0200 Subject: [PATCH 0476/1854] Cleaned up the ouput to be as minimalistic as possible. Now the verbose flag output is realy verbose. --- client/cmdhfmf.c | 127 +++++++++++++++++++++++++---------------------- client/cmdhfmf.h | 1 - 2 files changed, 67 insertions(+), 61 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 66c50758f..aed756278 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -1715,6 +1715,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { // print parameters if (verbose) { + PrintAndLogEx(INFO, _YELLOW_("======================= SETTINGS =======================")); PrintAndLogEx(INFO, " card sectors .. " _YELLOW_("%d"), sectors_cnt); PrintAndLogEx(INFO, " key supplied .. " _YELLOW_("%s"), know_target_key ? "True" : "False"); PrintAndLogEx(INFO, " known sector .. " _YELLOW_("%d"), blockNo); @@ -1723,6 +1724,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { PrintAndLogEx(INFO, " card PRNG ..... " _YELLOW_("%s"), prng_type ? "WEAK" : "HARD"); PrintAndLogEx(INFO, " dictionary .... " _YELLOW_("%s"), strlen(filename) ? filename : "NONE"); PrintAndLogEx(INFO, " legacy mode ... " _YELLOW_("%s"), legacy_mfchk ? "True" : "False"); + PrintAndLogEx(INFO, _YELLOW_("======================= SETTINGS =======================")); } // Start the timer @@ -1732,6 +1734,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { if (know_target_key == false) PrintAndLogEx(WARNING, "No known key was supplied, key recovery might fail"); else { + if (verbose) PrintAndLogEx(INFO, _YELLOW_("======================= START KNOWN KEY ATTACK =======================")); if (mfCheckKeys(FirstBlockOfSector(blockNo), keyType, true, 1, key, &key64) == PM3_SUCCESS) { PrintAndLogEx(INFO, "Using valid key: sector: %3d key type: %c key: " _YELLOW_("%s") "(used for nested / hardnested attack)", blockNo, @@ -1781,6 +1784,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { } } } + if (verbose) PrintAndLogEx(INFO, _YELLOW_("======================= STOP KNOWN KEY ATTACK =======================")); } // Load the dictionary @@ -1806,7 +1810,7 @@ useDefaultKeys: } // Use the dictionary to find sector keys on the card - PrintAndLogEx(INFO, _YELLOW_("======================= START DICTIONARY ATTACK =======================")); + if (verbose) PrintAndLogEx(INFO, _YELLOW_("======================= START DICTIONARY ATTACK =======================")); if (legacy_mfchk) { // Check all the sectors @@ -1861,7 +1865,7 @@ useDefaultKeys: lastChunk = false; } // end strategy } - PrintAndLogEx(INFO, _YELLOW_("======================= STOP DICTIONARY ATTACK =======================")); + if (verbose) PrintAndLogEx(INFO, _YELLOW_("======================= STOP DICTIONARY ATTACK =======================")); // Analyse the dictionary attack @@ -1898,9 +1902,9 @@ useDefaultKeys: if (know_target_key == false) { // Check if the darkside attack can be used if (prng_type) { - PrintAndLogEx(INFO, _YELLOW_("======================= START DARKSIDE ATTACK =======================")); + if (verbose) PrintAndLogEx(INFO, _YELLOW_("======================= START DARKSIDE ATTACK =======================")); int isOK = mfDarkside(FirstBlockOfSector(blockNo), keyType, &key64); - PrintAndLogEx(INFO, _YELLOW_("======================= STOP DARKSIDE ATTACK =======================")); + if (verbose) PrintAndLogEx(INFO, _YELLOW_("======================= STOP DARKSIDE ATTACK =======================")); switch (isOK) { case -1 : PrintAndLogEx(WARNING, "\nButton pressed. Aborted."); @@ -1989,10 +1993,12 @@ noValidKeyFound: if (current_key_type_i == 1) { if (e_sector[current_sector_i].foundKey[0] && !e_sector[current_sector_i].foundKey[1]) { - PrintAndLogEx(INFO, "Reading B key: sector: %3d key type: %c", - current_sector_i, - current_key_type_i ? 'B' : 'A' - ); + if (verbose) { + PrintAndLogEx(INFO, _YELLOW_("======================= START READ B KEY ATTACK =======================")); + PrintAndLogEx(INFO, "Reading B key: sector: %3d key type: %c", + current_sector_i, + current_key_type_i ? 'B' : 'A'); + } uint8_t sectrail = (FirstBlockOfSector(current_sector_i) + NumBlocksPerSector(current_sector_i) - 1); mf_readblock_t payload; @@ -2021,11 +2027,12 @@ noValidKeyFound: sprint_hex(tmp_key, sizeof(tmp_key)) ); } else { - PrintAndLogEx(WARNING, "Unknown B key: sector: %3d key type: %c (reading the B key was not possible, maybe due to insufficient access rights) ", + if (verbose) PrintAndLogEx(WARNING, "Unknown B key: sector: %3d key type: %c (reading the B key was not possible, maybe due to insufficient access rights) ", current_sector_i, current_key_type_i ? 'B' : 'A' ); } + if (verbose) PrintAndLogEx(INFO, _YELLOW_("======================= STOP READ B KEY ATTACK =======================")); } } @@ -2034,13 +2041,13 @@ skipReadBKey: if (e_sector[current_sector_i].foundKey[current_key_type_i] == 0) { if (prng_type && (! nested_failed)) { uint8_t retries = 0; - PrintAndLogEx(INFO, _YELLOW_("======================= START NESTED ATTACK =======================")); - + if (verbose) { + PrintAndLogEx(INFO, _YELLOW_("======================= START NESTED ATTACK =======================")); + PrintAndLogEx(INFO, "Sector no: %3d, target key type: %c", + current_sector_i, + current_key_type_i ? 'B' : 'A'); + } tryNested: - PrintAndLogEx(INFO, "Sector no: %3d, target key type: %c", - current_sector_i, - current_key_type_i ? 'B' : 'A'); - isOK = mfnested(FirstBlockOfSector(blockNo), keyType, key, FirstBlockOfSector(current_sector_i), current_key_type_i, tmp_key, calibrate); switch (isOK) { case -1 : @@ -2077,14 +2084,16 @@ tryNested: free(e_sector); return PM3_ESOFT; } - PrintAndLogEx(INFO, _YELLOW_("======================= STOP NESTED ATTACK =======================")); + if (verbose) PrintAndLogEx(INFO, _YELLOW_("======================= STOP NESTED ATTACK =======================")); } else { tryHardnested: // If the nested attack fails then we try the hardnested attack - PrintAndLogEx(INFO, _YELLOW_("======================= START HARDNESTED ATTACK =======================")); - PrintAndLogEx(INFO, "Sector no: %3d, target key type: %c, Slow: %s", - current_sector_i, - current_key_type_i ? 'B' : 'A', - slow ? "Yes" : "No"); + if (verbose) { + PrintAndLogEx(INFO, _YELLOW_("======================= START HARDNESTED ATTACK =======================")); + PrintAndLogEx(INFO, "Sector no: %3d, target key type: %c, Slow: %s", + current_sector_i, + current_key_type_i ? 'B' : 'A', + slow ? "Yes" : "No"); + } isOK = mfnestedhard(FirstBlockOfSector(blockNo), keyType, key, FirstBlockOfSector(current_sector_i), current_key_type_i, NULL, false, false, slow, 0, &foundkey, NULL); DropField(); @@ -2108,7 +2117,7 @@ tryHardnested: // If the nested attack fails then we try the hardnested attack e_sector[current_sector_i].Key[current_key_type_i] = foundkey; e_sector[current_sector_i].foundKey[current_key_type_i] = 'H'; - PrintAndLogEx(INFO, _YELLOW_("======================= STOP HARDNESTED ATTACK =======================")); + if (verbose) PrintAndLogEx(INFO, _YELLOW_("======================= STOP HARDNESTED ATTACK =======================")); } // Check if the key was found if (e_sector[current_sector_i].foundKey[current_key_type_i]) { @@ -2126,8 +2135,43 @@ tryHardnested: // If the nested attack fails then we try the hardnested attack // Show the results to the user PrintAndLogEx(NORMAL, ""); PrintAndLogEx(INFO, "Found Keys:"); - printKeyTableAutopwn(sectors_cnt, e_sector); + char strA[12 + 1] = {0}; + char strB[12 + 1] = {0}; + PrintAndLogEx(NORMAL, "|---|----------------|---|----------------|---|"); + PrintAndLogEx(NORMAL, "|sec|key A |res|key B |res|"); + PrintAndLogEx(NORMAL, "|---|----------------|---|----------------|---|"); + for (uint8_t i = 0; i < sectors_cnt; ++i) { + + snprintf(strA, sizeof(strA), "------------"); + snprintf(strB, sizeof(strB), "------------"); + + if (e_sector[i].foundKey[0]) + snprintf(strA, sizeof(strA), "%012" PRIx64, e_sector[i].Key[0]); + + if (e_sector[i].foundKey[1]) + snprintf(strB, sizeof(strB), "%012" PRIx64, e_sector[i].Key[1]); + + + PrintAndLogEx(NORMAL, "|%03d| %s | " _YELLOW_("%c")"| %s | " _YELLOW_("%c")"|" + , i + , strA, e_sector[i].foundKey[0] + , strB, e_sector[i].foundKey[1] + ); + } + PrintAndLogEx(NORMAL, "|---|----------------|---|----------------|---|"); + PrintAndLogEx(NORMAL, "( " + _YELLOW_("D") ":Dictionary / " + _YELLOW_("S") ":darkSide / " + _YELLOW_("U") ":User / " + _YELLOW_("R") ":Reused / " + _YELLOW_("N") ":Nested / " + _YELLOW_("H") ":Hardnested / " + _YELLOW_("A") ":keyA " + ")" + ); + + // Dump the keys PrintAndLogEx(INFO, "\nSaving keys"); createMfcKeyDump(sectors_cnt, e_sector, GenerateFilename("hf-mf-", "-key.bin")); @@ -3186,43 +3230,6 @@ void printKeyTable(uint8_t sectorscnt, sector_t *e_sector) { PrintAndLogEx(NORMAL, "|---|----------------|---|----------------|---|"); } -void printKeyTableAutopwn(uint8_t sectorscnt, sector_t *e_sector) { - char strA[12 + 1] = {0}; - char strB[12 + 1] = {0}; - PrintAndLogEx(NORMAL, "|---|----------------|---|----------------|---|"); - PrintAndLogEx(NORMAL, "|sec|key A |res|key B |res|"); - PrintAndLogEx(NORMAL, "|---|----------------|---|----------------|---|"); - for (uint8_t i = 0; i < sectorscnt; ++i) { - - snprintf(strA, sizeof(strA), "------------"); - snprintf(strB, sizeof(strB), "------------"); - - if (e_sector[i].foundKey[0]) - snprintf(strA, sizeof(strA), "%012" PRIx64, e_sector[i].Key[0]); - - if (e_sector[i].foundKey[1]) - snprintf(strB, sizeof(strB), "%012" PRIx64, e_sector[i].Key[1]); - - - PrintAndLogEx(NORMAL, "|%03d| %s | " _YELLOW_("%c")"| %s | " _YELLOW_("%c")"|" - , i - , strA, e_sector[i].foundKey[0] - , strB, e_sector[i].foundKey[1] - ); - } - PrintAndLogEx(NORMAL, "|---|----------------|---|----------------|---|"); - PrintAndLogEx(NORMAL, "( " - _YELLOW_("D") ":Dictionary / " - _YELLOW_("S") ":darkSide / " - _YELLOW_("U") ":User / " - _YELLOW_("R") ":Reused / " - _YELLOW_("N") ":Nested / " - _YELLOW_("H") ":Hardnested / " - _YELLOW_("A") ":keyA " - ")" - ); -} - // EMULATOR COMMANDS static int CmdHF14AMfEGet(const char *Cmd) { char c = tolower(param_getchar(Cmd, 0)); diff --git a/client/cmdhfmf.h b/client/cmdhfmf.h index e9970cfb2..55997bd87 100644 --- a/client/cmdhfmf.h +++ b/client/cmdhfmf.h @@ -22,6 +22,5 @@ int CmdHF14AMfDbg(const char *Cmd); // used by cmd hf mfu dbg void showSectorTable(void); void readerAttack(nonces_t data, bool setEmulatorMem, bool verbose); void printKeyTable(uint8_t sectorscnt, sector_t *e_sector); -void printKeyTableAutopwn(uint8_t sectorscnt, sector_t *e_sector); void printKeyTable_fast(uint8_t sectorscnt, icesector_t *e_sector, uint64_t bar, uint64_t foo); #endif From cbca61f6ba3e0e301c07abed6cd405150a230661 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 28 Aug 2019 19:25:15 +0200 Subject: [PATCH 0477/1854] searchAndList: hide temptative repo path --- client/fileutils.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/client/fileutils.c b/client/fileutils.c index 500bb7ef8..31e0aeed5 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -759,13 +759,14 @@ int convertOldMfuDump(uint8_t **dump, size_t *dumplen) { return PM3_SUCCESS; } -static int filelist(const char *path, const char *ext, bool last) { +static int filelist(const char *path, const char *ext, bool last, bool tentative) { struct dirent **namelist; int n; n = scandir(path, &namelist, NULL, alphasort); if (n == -1) { - PrintAndLogEx(NORMAL, "%s── %s => NOT FOUND", last ? "└" : "├", path); + if (!tentative) + PrintAndLogEx(NORMAL, "%s── %s", last ? "└" : "├", path); return PM3_EFILE; } @@ -781,25 +782,29 @@ static int filelist(const char *path, const char *ext, bool last) { } int searchAndList(const char *pm3dir, const char *ext) { + // display in same order as searched by searchFile + // try pm3 dirs in current workdir (dev mode) if (get_my_executable_directory() != NULL) { char script_directory_path[strlen(get_my_executable_directory()) + strlen(pm3dir) + 1]; strcpy(script_directory_path, get_my_executable_directory()); strcat(script_directory_path, pm3dir); - filelist(script_directory_path, ext, false); + filelist(script_directory_path, ext, false, true); } + // try pm3 dirs in user .proxmark3 (user mode) char *userpath = getenv("HOME"); if (userpath != NULL) { char script_directory_path[strlen(userpath) + strlen(PM3_USER_DIRECTORY) + strlen(pm3dir) + 1]; strcpy(script_directory_path, userpath); strcat(script_directory_path, PM3_USER_DIRECTORY); strcat(script_directory_path, pm3dir); - filelist(script_directory_path, ext, false); + filelist(script_directory_path, ext, false, false); } + // try pm3 dirs in pm3 installation dir (install mode) { char script_directory_path[strlen(PM3_SHARE_PATH) + strlen(pm3dir) + 1]; strcpy(script_directory_path, PM3_SHARE_PATH); strcat(script_directory_path, pm3dir); - filelist(script_directory_path, ext, true); + filelist(script_directory_path, ext, true, false); } return PM3_SUCCESS; } From 94f6a402e8d457130d6654953527d490e48a4671 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 28 Aug 2019 21:12:18 +0200 Subject: [PATCH 0478/1854] chg. prep for eload.. --- include/pm3_cmd.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 035e85405..dc48bd110 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -229,6 +229,10 @@ typedef struct { uint8_t key[6]; } PACKED mf_readblock_t; +typedef struct { + uint8_t sectorcnt; + uint8_t keytype; +} PACKED mfc_eload_t; // For the bootloader #define CMD_DEVICE_INFO 0x0000 From f3ab9632f058618720f006e8095639ef2ecc89ef Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 28 Aug 2019 21:12:32 +0200 Subject: [PATCH 0479/1854] return values --- client/mifare/mifarehost.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/client/mifare/mifarehost.c b/client/mifare/mifarehost.c index d22073d02..54de89046 100644 --- a/client/mifare/mifarehost.c +++ b/client/mifare/mifarehost.c @@ -209,7 +209,8 @@ int mfCheckKeys_fast(uint8_t sectorsCnt, uint8_t firstChunk, uint8_t lastChunk, // initialize storage for found keys icesector_t *tmp = calloc(sectorsCnt, sizeof(icesector_t)); if (tmp == NULL) - return 1; + return PM3_EMALLOC; + memcpy(tmp, resp.data.asBytes, sectorsCnt * sizeof(icesector_t)); for (int i = 0; i < sectorsCnt; i++) { @@ -227,11 +228,11 @@ int mfCheckKeys_fast(uint8_t sectorsCnt, uint8_t firstChunk, uint8_t lastChunk, free(tmp); if (curr_keys == sectorsCnt * 2) - return 0; + return PM3_SUCCESS; if (lastChunk) - return 1; + return PM3_ESOFT; } - return 1; + return PM3_ESOFT; } // PM3 imp of J-Run mf_key_brute (part 2) From ad3fe38b45fe808fdb9fa9c6d888da3975f32d51 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 28 Aug 2019 21:15:32 +0200 Subject: [PATCH 0480/1854] fix: loaddictionary_save, now with correct mem clear. --- client/fileutils.c | 68 +++++++++++++++++++++++++--------------------- client/fileutils.h | 7 +++++ 2 files changed, 44 insertions(+), 31 deletions(-) diff --git a/client/fileutils.c b/client/fileutils.c index 31e0aeed5..c3c9f5acc 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -283,9 +283,9 @@ int saveFileJSON(const char *preferredName, JSONFileType ftype, uint8_t *data, s } case jsfIclass: { JsonSaveStr(root, "FileType", "iclass"); - uint8_t uid[8] = {0}; - memcpy(uid, data, 8); - JsonSaveBufAsHexCompact(root, "$.Card.UID", uid, sizeof(uid)); + uint8_t csn[8] = {0}; + memcpy(csn, data, 8); + JsonSaveBufAsHexCompact(root, "$.Card.CSN", csn, sizeof(csn)); for (size_t i = 0; i < (datalen / 8); i++) { char path[PATH_MAX_LENGTH] = {0}; @@ -316,13 +316,13 @@ int createMfcKeyDump(uint8_t sectorsCnt, sector_t *e_sector, char *fptr) { int i; if (fptr == NULL) { - return 1; + return PM3_EINVARG; } FILE *fkeys = fopen(fptr, "wb"); if (fkeys == NULL) { PrintAndLogEx(WARNING, "Could not create file " _YELLOW_("%s"), fptr); - return 1; + return PM3_EFILE; } PrintAndLogEx(SUCCESS, "Printing keys to binary file " _YELLOW_("%s")"...", fptr); @@ -338,14 +338,14 @@ int createMfcKeyDump(uint8_t sectorsCnt, sector_t *e_sector, char *fptr) { fclose(fkeys); PrintAndLogEx(SUCCESS, "Found keys have been dumped to " _YELLOW_("%s")" --> 0xffffffffffff has been inserted for unknown keys.", fptr); - return 0; + return PM3_SUCCESS; } int loadFile(const char *preferredName, const char *suffix, void *data, size_t maxdatalen, size_t *datalen) { if (data == NULL) return 1; char *fileName = filenamemcopy(preferredName, suffix); - if (fileName == NULL) return 1; + if (fileName == NULL) return PM3_EINVARG; int retval = PM3_SUCCESS; @@ -363,23 +363,24 @@ int loadFile(const char *preferredName, const char *suffix, void *data, size_t m if (fsize <= 0) { PrintAndLogEx(FAILED, "error, when getting filesize"); - retval = 1; + retval = PM3_EFILE; goto out; } uint8_t *dump = calloc(fsize, sizeof(uint8_t)); if (!dump) { PrintAndLogEx(FAILED, "error, cannot allocate memory"); - retval = 2; + retval = PM3_EMALLOC; goto out; } size_t bytes_read = fread(dump, 1, fsize, f); + fclose(f); if (bytes_read != fsize) { PrintAndLogEx(FAILED, "error, bytes read mismatch file size"); free(dump); - retval = 3; + retval = PM3_EFILE; goto out; } @@ -396,9 +397,7 @@ int loadFile(const char *preferredName, const char *suffix, void *data, size_t m *datalen = bytes_read; out: - fclose(f); free(fileName); - return retval; } @@ -432,7 +431,7 @@ int loadFileEML(const char *preferredName, void *data, size_t *datalen) { break; fclose(f); PrintAndLogEx(FAILED, "File reading error."); - retval = 2; + retval = PM3_EFILE; goto out; } @@ -471,13 +470,13 @@ int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_ root = json_load_file(fileName, 0, &error); if (!root) { PrintAndLogEx(ERR, "ERROR: json " _YELLOW_("%s") " error on line %d: %s", fileName, error.line, error.text); - retval = 2; + retval = PM3_ESOFT; goto out; } if (!json_is_object(root)) { PrintAndLogEx(ERR, "ERROR: Invalid json " _YELLOW_("%s") " format. root must be an object.", fileName); - retval = 3; + retval = PM3_ESOFT; goto out; } @@ -493,7 +492,7 @@ int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_ size_t sptr = 0; for (int i = 0; i < 256; i++) { if (sptr + 16 > maxdatalen) { - retval = 5; + retval = PM3_EMALLOC; goto out; } @@ -515,7 +514,7 @@ int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_ size_t sptr = 0; for (int i = 0; i < 256; i++) { if (sptr + 4 > maxdatalen) { - retval = 5; + retval = PM3_EMALLOC; goto out; } @@ -537,7 +536,7 @@ int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_ size_t sptr = 0; for (size_t i = 0; i < (maxdatalen / 4); i++) { if (sptr + 4 > maxdatalen) { - retval = 5; + retval = PM3_EMALLOC; goto out; } @@ -559,7 +558,7 @@ int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_ size_t sptr = 0; for (size_t i = 0; i < (maxdatalen / 8); i++) { if (sptr + 8 > maxdatalen) { - retval = 5; + retval = PM3_EMALLOC; goto out; } @@ -651,10 +650,8 @@ out: int loadFileDICTIONARY_safe(const char *preferredName, void **pdata, uint8_t keylen, uint16_t *keycnt) { - int block_size = 512; - int allocation_size = block_size; - size_t counter = 0; int retval = PM3_SUCCESS; + char *path; if (searchFile(&path, DICTIONARIES_SUBDIR, preferredName, ".dic") != PM3_SUCCESS) return PM3_EFILE; @@ -667,14 +664,20 @@ int loadFileDICTIONARY_safe(const char *preferredName, void **pdata, uint8_t key keylen = 6; } + size_t mem_size; + size_t block_size = 10 * keylen; + // double up since its chars keylen <<= 1; char line[255]; // allocate some space for the dictionary - *pdata = calloc(keylen * allocation_size, sizeof(uint8_t)); - if (*pdata == NULL) return PM3_EFILE; + *pdata = calloc( block_size , sizeof(uint8_t)); + if (*pdata == NULL) + return PM3_EFILE; + + mem_size = block_size; FILE *f = fopen(path, "r"); if (!f) { @@ -684,15 +687,17 @@ int loadFileDICTIONARY_safe(const char *preferredName, void **pdata, uint8_t key // read file while (fgets(line, sizeof(line), f)) { + // check if we have enough space (if not allocate more) - if ((*keycnt) >= allocation_size) { - allocation_size += block_size; - *pdata = realloc(*pdata, keylen * allocation_size * sizeof(uint8_t)); + if ( (*keycnt * (keylen >> 1) ) >= mem_size ) { + + mem_size += block_size; + *pdata = realloc(*pdata, mem_size); + if (*pdata == NULL) { return PM3_EFILE; } else { - // zero the new memory (safety first) - memset(*pdata + allocation_size - block_size, 0, block_size); + memset(*pdata + (mem_size - block_size), 0, block_size); } } @@ -714,10 +719,11 @@ int loadFileDICTIONARY_safe(const char *preferredName, void **pdata, uint8_t key uint64_t key = strtoull(line, NULL, 16); - num_to_bytes(key, keylen >> 1, *pdata + counter); + num_to_bytes(key, keylen >> 1, *pdata + (*keycnt * (keylen >> 1)) ); + (*keycnt)++; + memset(line, 0, sizeof(line)); - counter += (keylen >> 1); } fclose(f); PrintAndLogEx(SUCCESS, "loaded " _GREEN_("%2d") "keys from dictionary file " _YELLOW_("%s"), *keycnt, path); diff --git a/client/fileutils.h b/client/fileutils.h index 113cac222..7bfc7c138 100644 --- a/client/fileutils.h +++ b/client/fileutils.h @@ -62,6 +62,13 @@ typedef enum { // jsfT55xx, } JSONFileType; +typedef enum { + BIN = 0, + EML, + JSON, + DICTIONARY, +} DumpFileType_t; + int fileExists(const char *filename); /** From 8d9751ebe42fc2912e86c01109e417e1ead5a09f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 28 Aug 2019 21:16:09 +0200 Subject: [PATCH 0481/1854] fix: uint cant be negative.. --- client/cmdlft55xx.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 965a5db0b..46cc3e017 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -2129,9 +2129,11 @@ static int CmdT55xxChkPwds(const char *Cmd) { uint16_t keycount = 0; int res = loadFileDICTIONARY_safe(filename, (void**) &keyBlock, 4, &keycount); - if (res != PM3_SUCCESS || keycount <= 0 || keyBlock == NULL) { + if (res != PM3_SUCCESS || keycount == 0 || keyBlock == NULL) { PrintAndLogEx(WARNING, "No keys found in file"); - if (keyBlock != NULL) free(keyBlock); + if (keyBlock != NULL) + free(keyBlock); + return PM3_ESOFT; } From 117ebf0beb618732e797dd3752638bc9e5c1ed6b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 28 Aug 2019 21:21:27 +0200 Subject: [PATCH 0482/1854] chg: 'hf mf ecfill' - now uses NG format. chg: 'hf mf eload' - now uses NG format. chg: 'hf mf fchk m' - now uses ecfill trick, if fchk got all keys, it will dump the card directly. sample: hf mf fchk 1 m (must have dictionaries uploaded to device) if all keys are found, you can now run hf mf esave to get a complete dump. --- client/cmdhfmf.c | 160 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 119 insertions(+), 41 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 0b7727031..cc435cb07 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -751,12 +751,56 @@ static uint8_t NumBlocksPerSector(uint8_t sectorNo) { return 16; } } + static uint8_t GetSectorFromBlockNo(uint8_t blockNo) { if (blockNo < 128) return blockNo / 4; else return 32 + ((128 - blockNo) / 16); } + +static char GetFormatFromSector(uint8_t sectorNo) { + switch (sectorNo) { + case MIFARE_MINI_MAXSECTOR: + return '0'; + case MIFARE_1K_MAXSECTOR: + return '1'; + case MIFARE_2K_MAXSECTOR: + return '2'; + case MIFARE_4K_MAXSECTOR: + return '4'; + default : + return ' '; + } +} + +static int FastDumpWithEcFill(uint8_t numsectors){ + PacketResponseNG resp; + + mfc_eload_t payload; + payload.sectorcnt = numsectors; + payload.keytype = 0; + + // ecfill key A + clearCommandBuffer(); + SendCommandNG(CMD_HF_MIFARE_EML_LOAD, (uint8_t *)&payload, sizeof(payload)); + + int res = WaitForResponseTimeout(CMD_HF_MIFARE_EML_LOAD, &resp, 2000); + if ( res != PM3_SUCCESS) { + } + + // ecfill key B + payload.keytype = 1; + + clearCommandBuffer(); + SendCommandNG(CMD_HF_MIFARE_EML_LOAD, (uint8_t *)&payload, sizeof(payload)); + res = WaitForResponseTimeout(CMD_HF_MIFARE_EML_LOAD, &resp, 2000); + if ( res != PM3_SUCCESS) { + + } + return PM3_SUCCESS; +} + static int CmdHF14AMfDump(const char *Cmd) { uint64_t t1 = msclock(); @@ -1242,7 +1286,12 @@ static int CmdHF14AMfNested(const char *Cmd) { } PrintAndLogEx(SUCCESS, "Testing known keys. Sector count=%d", SectorsCnt); - mfCheckKeys_fast(SectorsCnt, true, true, 1, ARRAYLEN(g_mifare_default_keys) + 1, keyBlock, e_sector, false); + int res = mfCheckKeys_fast(SectorsCnt, true, true, 1, ARRAYLEN(g_mifare_default_keys) + 1, keyBlock, e_sector, false); + if ( res == PM3_SUCCESS ) { + // all keys found + PrintAndLogEx(SUCCESS, "Fast check found all keys"); + goto jumptoend; + } uint64_t t2 = msclock() - t1; PrintAndLogEx(SUCCESS, "Time to check %d known keys: %.0f seconds\n", ARRAYLEN(g_mifare_default_keys), (float)t2 / 1000.0); @@ -1329,6 +1378,7 @@ static int CmdHF14AMfNested(const char *Cmd) { } } +jumptoend: //print them printKeyTable(SectorsCnt, e_sector); @@ -1612,56 +1662,69 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { bool legacy_mfchk = false; bool prng_type = false; bool verbose = false; + bool has_filename = false; + bool errors = false; // Parse the options given by the user - ctmp = tolower(param_getchar(Cmd, 0)); - while ((ctmp = param_getchar(Cmd, cmdp))) { + while ( (ctmp = param_getchar(Cmd, cmdp)) && !errors ) { switch (tolower(ctmp)) { case 'h': return usage_hf14_autopwn(); case 'f': if (param_getstr(Cmd, cmdp + 1, filename, FILE_PATH_SIZE) >= FILE_PATH_SIZE) { PrintAndLogEx(FAILED, "Filename too long"); + errors = true; + } else { + has_filename = true; } - cmdp ++; + cmdp += 2; break; case 'l': legacy_mfchk = true; + cmdp++; break; case 'v': verbose = true; + cmdp++; break; case '*': // Get the number of sectors sectors_cnt = NumOfSectors(param_getchar(Cmd, cmdp + 1)); block_cnt = NumOfBlocks(param_getchar(Cmd, cmdp + 1)); - cmdp ++; + cmdp += 2; break; case 'k': // Get the known block number if (param_getchar(Cmd, cmdp + 1) == 0x00) { - PrintAndLogEx(WARNING, "Sector number is missing"); - return PM3_EINVARG; + errors = true; + break; } + blockNo = param_get8(Cmd, cmdp + 1); + // Get the knonwn block type ctmp = tolower(param_getchar(Cmd, cmdp + 2)); if (ctmp != 'a' && ctmp != 'b') { PrintAndLogEx(WARNING, "Key type must be A or B"); - return PM3_EINVARG; + errors = true; + break; } + if (ctmp != 'a') { keyType = 1; } + // Get the known block key if (param_gethex(Cmd, cmdp + 3, key, 12)) { PrintAndLogEx(WARNING, "Key must include 12 HEX symbols"); + errors = true; return PM3_EINVARG; } know_target_key = true; cmdp += 3; case 's': slow = true; + cmdp++; break; case 'i': SetSIMDInstr(SIMD_AUTO); @@ -1695,7 +1758,10 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { PrintAndLogEx(WARNING, "Unknown parameter '%c'\n", ctmp); return usage_hf14_autopwn(); } - cmdp++; + } + + if ( errors ) { + return usage_hf14_autopwn(); } // Create the key storage stucture @@ -1732,6 +1798,8 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { if (know_target_key == false) PrintAndLogEx(WARNING, "No known key was supplied, key recovery might fail"); else { + + PrintAndLogEx(INFO, "Validating known key"); if (mfCheckKeys(FirstBlockOfSector(blockNo), keyType, true, 1, key, &key64) == PM3_SUCCESS) { PrintAndLogEx(INFO, "Using key for the nested / hardnested | sector:" _RED_("%3d") " key type: "_RED_("%c") " key: " _RED_("%s"), @@ -1741,7 +1809,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { ); // Store the key for the nested / hardnested attack (if supplied by the user) - e_sector[blockNo].Key[keyType] = bytes_to_num(key, 6); + e_sector[blockNo].Key[keyType] = key64; e_sector[blockNo].foundKey[keyType] = 3; } else { know_target_key = false; @@ -1752,6 +1820,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { ); PrintAndLogEx(WARNING, "Falling back to dictionary"); } + // Check if the user supplied key is used by other sectors for (int i = 0; i < sectors_cnt; i++) { for (int j = 0; j < 2; j++) { @@ -1759,7 +1828,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { if (mfCheckKeys(FirstBlockOfSector(i), j, true, 1, key, &key64) == PM3_SUCCESS) { e_sector[i].Key[j] = bytes_to_num(key, 6); e_sector[i].foundKey[j] = 4; - PrintAndLogEx(SUCCESS, "Found valid key: sector: %3d key type: %c key: " _YELLOW_("%s"), + PrintAndLogEx(SUCCESS, "target sector:%3u key type: %c -- found valid key [" _YELLOW_("%s") "]", i, j ? 'B' : 'A', sprint_hex(key, sizeof(key)) @@ -1784,16 +1853,21 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { } } + bool load_success = true; // Load the dictionary - if (strlen(filename) != 0) { + if (has_filename) { int res = loadFileDICTIONARY_safe(filename, (void**) &keyBlock, 6, &key_cnt); - if (res != PM3_SUCCESS || key_cnt <= 0 || keyBlock == NULL) { + if (res != PM3_SUCCESS || key_cnt == 0 || keyBlock == NULL) { PrintAndLogEx(FAILED, "An error occurred while loading the dictionary! (we will use the default keys now)"); - if (keyBlock != NULL) free(keyBlock); - goto useDefaultKeys; + if (keyBlock != NULL) + free(keyBlock); + + load_success = false; } - } else { -useDefaultKeys: + + } + + if ( has_filename == false || load_success == false ) { keyBlock = calloc(ARRAYLEN(g_mifare_default_keys), 6); if (keyBlock == NULL) { free(e_sector); @@ -1804,6 +1878,7 @@ useDefaultKeys: num_to_bytes(g_mifare_default_keys[cnt], 6, keyBlock + cnt * 6); } key_cnt = ARRAYLEN(g_mifare_default_keys); + PrintAndLogEx(SUCCESS, "loaded " _GREEN_("%2d") "keys from hardcoded default array", key_cnt); } // Use the dictionary to find sector keys on the card @@ -1830,8 +1905,10 @@ useDefaultKeys: printf("\n"); fflush(stdout); } else { + int chunksize = key_cnt > (PM3_CMD_DATA_SIZE / 6) ? (PM3_CMD_DATA_SIZE / 6) : key_cnt; bool firstChunk = true, lastChunk = false; + for (uint8_t strategy = 1; strategy < 3; strategy++) { PrintAndLogEx(INFO, "Running strategy %u", strategy); // main keychunk loop @@ -1852,7 +1929,7 @@ useDefaultKeys: if (firstChunk) firstChunk = false; // all keys, aborted - if (res == 0 || res == 2) { + if (res == PM3_SUCCESS) { i = key_cnt; strategy = 3; break; // Exit the loop @@ -1866,9 +1943,9 @@ useDefaultKeys: // Analyse the dictionary attack for (int i = 0; i < sectors_cnt; i++) { for (int j = 0; j < 2; j++) { - if (e_sector[i].foundKey[j] == 1) { + if (e_sector[i].foundKey[j] > 0) { num_to_bytes(e_sector[i].Key[j], 6, tmp_key); - PrintAndLogEx(SUCCESS, "Found valid key: sector: %3d key type: %c key: " _YELLOW_("%s"), + PrintAndLogEx(SUCCESS, "target sector:%3u key type: %c -- found valid key [" _YELLOW_("%s") "]", i, j ? 'B' : 'A', sprint_hex(tmp_key, sizeof(tmp_key)) @@ -1918,19 +1995,9 @@ useDefaultKeys: PrintAndLogEx(SUCCESS, "\nFound valid key: %012" PRIx64 "\n", key64); break; } - num_to_bytes(key64, 6, key); - // Check if the darkside key is valid - if (mfCheckKeys(FirstBlockOfSector(blockNo), keyType, true, 1, key, &key64) != PM3_SUCCESS) { - PrintAndLogEx(FAILED, "The key generated by the darkside attack is not valid!" - _RED_("%3d") " key type: "_RED_("%c") " key: " _RED_("%s"), - blockNo, - keyType ? 'B' : 'A', - sprint_hex(key, sizeof(key)) - ); - goto noValidKeyFound; - } + // Store the keys - e_sector[blockNo].Key[keyType] = bytes_to_num(key, 6); + e_sector[blockNo].Key[keyType] = key64; e_sector[blockNo].foundKey[keyType] = 2; } else { noValidKeyFound: @@ -1940,6 +2007,7 @@ noValidKeyFound: return PM3_ESOFT; } } + free(keyBlock); // Clear the needed variables num_to_bytes(0, 6, tmp_key); @@ -2139,13 +2207,8 @@ tryHardnested: // If the nested attack fails then we try the hardnested attack mfEmlSetMem(block, FirstBlockOfSector(current_sector_i) + NumBlocksPerSector(current_sector_i) - 1, 1); } - // using ecfill trick, keys already in emulator mem, load data using Key A - clearCommandBuffer(); - SendCommandMIX(CMD_HF_MIFARE_EML_LOAD, sectors_cnt, 0, 0, NULL, 0); - - // using ecfill trick, keys already in emulator mem, load data using Key B - clearCommandBuffer(); - SendCommandMIX(CMD_HF_MIFARE_EML_LOAD, sectors_cnt, 1, 0, NULL, 0); + // use ecfill trick + FastDumpWithEcFill(sectors_cnt); bytes = block_cnt * MFBLOCK_SIZE; dump = calloc(bytes, sizeof(uint8_t)); @@ -2388,7 +2451,7 @@ static int CmdHF14AMfChk_fast(const char *Cmd) { firstChunk = false; // all keys, aborted - if (res == 0 || res == 2) + if (res == PM3_SUCCESS || res == 2) goto out; } // end chunks of keys firstChunk = true; @@ -2416,6 +2479,13 @@ out: printKeyTable(sectorsCnt, e_sector); + if ( use_flashmemory && found_keys == (sectorsCnt << 1) ) { + PrintAndLogEx(SUCCESS, "Card dumped aswell. run " _YELLOW_("`%s %c`"), + "hf mf esave", + GetFormatFromSector(sectorsCnt) + ); + } + if (transferToEml) { // fast push mode conn.block_after_ACK = true; @@ -2434,6 +2504,10 @@ out: mfEmlSetMem(block, blockno, 1); } PrintAndLogEx(SUCCESS, "Found keys have been transferred to the emulator memory"); + + if ( found_keys == (sectorsCnt << 1) ) { + FastDumpWithEcFill(sectorsCnt); + } } if (createDumpFile) { @@ -3411,8 +3485,12 @@ static int CmdHF14AMfECFill(const char *Cmd) { } PrintAndLogEx(NORMAL, "--params: numSectors: %d, keyType: %c\n", numSectors, (keyType == 0) ? 'A' : 'B'); + + mfc_eload_t payload; + payload.sectorcnt = numSectors; + payload.keytype = keyType; clearCommandBuffer(); - SendCommandMIX(CMD_HF_MIFARE_EML_LOAD, numSectors, keyType, 0, NULL, 0); + SendCommandNG(CMD_HF_MIFARE_EML_LOAD, (uint8_t *)&payload, sizeof(payload)); return PM3_SUCCESS; } From 28d703d6df0f839b33992cab4c3e0233be81596a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 28 Aug 2019 21:21:52 +0200 Subject: [PATCH 0483/1854] chg: eload NG --- armsrc/appmain.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index b593c826b..13aa6bc84 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1134,7 +1134,8 @@ static void PacketReceived(PacketCommandNG *packet) { break; } case CMD_HF_MIFARE_EML_LOAD: { - MifareECardLoad(packet->oldarg[0], packet->oldarg[1]); + mfc_eload_t *payload = (mfc_eload_t *) packet->data.asBytes; + MifareECardLoadExt(payload->sectorcnt, payload->keytype); break; } // Work with "magic Chinese" card From 501182ca06b6c58bbd9bf1565331bfe3ed0448d2 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 28 Aug 2019 21:23:31 +0200 Subject: [PATCH 0484/1854] chg: ecload NG, fchk use ecfill trick --- armsrc/mifarecmd.c | 89 +++++++++++++++++++++++++++++----------------- armsrc/mifarecmd.h | 3 +- 2 files changed, 59 insertions(+), 33 deletions(-) diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 63cf1128d..17570e680 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -1342,8 +1342,6 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da for (uint16_t i = s_point; i < keyCount; ++i) { - //if ( i % 100 == 0) Dbprintf("ChkKeys_fast: sector %d | checking %d | %d found | s_point %d", s, i, foundkeys, s_point); - // Allow button press / usb cmd to interrupt device if (BUTTON_PRESS() && !data_available()) { goto OUT; @@ -1525,6 +1523,33 @@ OUT: FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); BigBuf_free(); BigBuf_Clear_ext(false); + + // special trick ecfill + if (use_flashmem && foundkeys == allkeys) { + + uint8_t block[16] = {0}; + for (int i = 0; i < sectorcnt; i++) { + + uint8_t blockno; + if (i < 32) { + blockno = (i * 4) ^ 0x3; + } else { + blockno = (32 * 4 + (i - 32) * 16) ^ 0xF; + } + // get ST + emlGetMem(block, blockno, 1); + + memcpy(block, k_sector[i].keyA, 6); + memcpy(block + 10, k_sector[i].keyB, 6); + + emlSetMem_xt(block, blockno, 1, sizeof(block)); + } + int oldbg = DBGLEVEL; + DBGLEVEL = DBG_NONE; + MifareECardLoad(sectorcnt, 0); + MifareECardLoad(sectorcnt, 1); + DBGLEVEL = oldbg; + } } else { // partial/none keys found reply_mix(CMD_ACK, foundkeys, 0, 0, 0, 0); @@ -1669,10 +1694,15 @@ void MifareEMemGet(uint8_t blockno, uint8_t blockcnt) { // Load a card into the emulator memory // //----------------------------------------------------------------------------- -int MifareECardLoad(uint32_t arg0, uint32_t arg1) { +int MifareECardLoadExt(uint8_t numSectors, uint8_t keyType) { + int retval = MifareECardLoad(numSectors, keyType); + reply_ng(CMD_HF_MIFARE_EML_LOAD, retval, NULL, 0); + return retval; +} + +int MifareECardLoad(uint8_t numSectors, uint8_t keyType) { + uint32_t cuid = 0; - uint8_t numSectors = arg0; - uint8_t keyType = arg1; struct Crypto1State mpcs = {0, 0}; struct Crypto1State *pcs; pcs = &mpcs; @@ -1683,42 +1713,40 @@ int MifareECardLoad(uint32_t arg0, uint32_t arg1) { uint8_t uid[10] = {0x00}; LED_A_ON(); - LED_B_OFF(); - LED_C_OFF(); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); clear_trace(); set_tracing(true); - bool isOK = true; + int retval; if (!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) { - isOK = false; - if (DBGLEVEL >= 1) Dbprintf("Can't select card"); + retval = PM3_ESOFT; + if (DBGLEVEL > DBG_ERROR) Dbprintf("Can't select card"); + goto out; } - for (uint8_t sectorNo = 0; isOK && sectorNo < numSectors; sectorNo++) { + for (uint8_t sectorNo = 0; sectorNo < numSectors; sectorNo++) { uint64_t ui64Key = emlGetKey(sectorNo, keyType); if (sectorNo == 0) { - if (isOK && mifare_classic_auth(pcs, cuid, FirstBlockOfSector(sectorNo), keyType, ui64Key, AUTH_FIRST)) { - if (DBGLEVEL >= 1) Dbprintf("Sector[%2d]. Auth error", sectorNo); + if (mifare_classic_auth(pcs, cuid, FirstBlockOfSector(sectorNo), keyType, ui64Key, AUTH_FIRST)) { + if (DBGLEVEL > DBG_ERROR) Dbprintf("Sector[%2d]. Auth error", sectorNo); break; } } else { - if (isOK && mifare_classic_auth(pcs, cuid, FirstBlockOfSector(sectorNo), keyType, ui64Key, AUTH_NESTED)) { - isOK = false; - if (DBGLEVEL >= 1) Dbprintf("Sector[%2d]. Auth nested error", sectorNo); - break; + if (mifare_classic_auth(pcs, cuid, FirstBlockOfSector(sectorNo), keyType, ui64Key, AUTH_NESTED)) { + retval = PM3_ESOFT; + if (DBGLEVEL > DBG_ERROR) Dbprintf("Sector[%2d]. Auth nested error", sectorNo); + goto out; } } - for (uint8_t blockNo = 0; isOK && blockNo < NumBlocksPerSector(sectorNo); blockNo++) { - if (isOK && mifare_classic_readblock(pcs, cuid, FirstBlockOfSector(sectorNo) + blockNo, dataoutbuf)) { - isOK = false; - if (DBGLEVEL >= 1) Dbprintf("Error reading sector %2d block %2d", sectorNo, blockNo); + for (uint8_t blockNo = 0; blockNo < NumBlocksPerSector(sectorNo); blockNo++) { + if (mifare_classic_readblock(pcs, cuid, FirstBlockOfSector(sectorNo) + blockNo, dataoutbuf)) { + retval = PM3_ESOFT; + if (DBGLEVEL > DBG_ERROR) Dbprintf("Error reading sector %2d block %2d", sectorNo, blockNo); break; } - if (isOK) { if (blockNo < NumBlocksPerSector(sectorNo) - 1) { emlSetMem(dataoutbuf, FirstBlockOfSector(sectorNo) + blockNo, 1); } else { // sector trailer, keep the keys, set only the AC @@ -1729,22 +1757,19 @@ int MifareECardLoad(uint32_t arg0, uint32_t arg1) { } } - } - - if (mifare_classic_halt(pcs, cuid)) - if (DBGLEVEL >= 1) + if (mifare_classic_halt(pcs, cuid)) { + if (DBGLEVEL > DBG_ERROR) Dbprintf("Halt error"); + } - // ----------------------------- crypto1 destroy + if (DBGLEVEL >= DBG_INFO) DbpString("Emulator fill sectors finished"); + +out: crypto1_destroy(pcs); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); - - if (DBGLEVEL >= 2) DbpString("EMUL FILL SECTORS FINISHED"); - set_tracing(false); - return (isOK) ? PM3_SUCCESS : PM3_EUNDEF; + return retval; } diff --git a/armsrc/mifarecmd.h b/armsrc/mifarecmd.h index 445b04130..d563e37a8 100644 --- a/armsrc/mifarecmd.h +++ b/armsrc/mifarecmd.h @@ -31,7 +31,8 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da void MifareEMemClr(void); void MifareEMemSet(uint8_t blockno, uint8_t blockcnt, uint8_t blockwidth, uint8_t *datain); void MifareEMemGet(uint8_t blockno, uint8_t blockcnt); -int MifareECardLoad(uint32_t arg0, uint32_t arg1); +int MifareECardLoad(uint8_t sectorcnt, uint8_t keytype); +int MifareECardLoadExt(uint8_t numSectors, uint8_t keyType); void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain); // Work with "magic Chinese" card void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain); From 03867018f1098deb12edcd96b7241f243cc7e084 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 28 Aug 2019 21:29:08 +0200 Subject: [PATCH 0485/1854] chg: iclass fixes. better timings, to get 280us vs 330us (default) time before card response. --- armsrc/iclass.c | 57 ++++++++++++++++++++++++++++++++++--------------- 1 file changed, 40 insertions(+), 17 deletions(-) diff --git a/armsrc/iclass.c b/armsrc/iclass.c index c8504e5ed..b550158cc 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -55,7 +55,13 @@ #include "protocols.h" #include "ticks.h" -static int timeout = 4096; +static int g_wait = 300; +static int timeout = 2900; +static uint32_t time_rdr = 0; +static uint32_t time_delta = 0; +static uint32_t time_delta_wait = 0; +static uint32_t time_response = 0; + static int SendIClassAnswer(uint8_t *resp, int respLen, uint16_t delay); int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf); @@ -151,7 +157,7 @@ typedef struct { static tUartIc Uart; static void OnError(uint8_t reason) { - reply_old(CMD_ACK, 0, reason, 0, 0, 0); + reply_mix(CMD_ACK, 0, reason, 0, 0, 0); switch_off(); } @@ -160,10 +166,12 @@ static void uart_reset(void) { Uart.synced = false; Uart.frame = false; } + static void uart_init(uint8_t *data) { Uart.buf = data; uart_reset(); } + static void uart_bit(uint8_t bit) { static uint8_t buf = 0xff; static uint8_t n_buf; @@ -1427,7 +1435,6 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) { uint32_t time_0 = GetCountSspClk(); uint32_t t2r_stime = 0, t2r_etime = 0; uint32_t r2t_stime, r2t_etime = 0; - LED_A_ON(); bool buttonPressed = false; @@ -1717,6 +1724,8 @@ static void TransmitIClassCommand(const uint8_t *cmd, int len, int *samples, int bool firstpart = true; uint8_t sendbyte; + time_rdr = 0; + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD); AT91C_BASE_SSC->SSC_THR = 0x00; @@ -1755,6 +1764,8 @@ static void TransmitIClassCommand(const uint8_t *cmd, int len, int *samples, int } } + time_rdr = GetCountSspClk(); + if (samples) { if (wait) *samples = (c + *wait) << 3; @@ -1827,7 +1838,7 @@ void ReaderTransmitIClass(uint8_t *frame, int len) { // If a response is captured return TRUE // If it takes too long return FALSE //----------------------------------------------------------------------------- -static int GetIClassAnswer(uint8_t *receivedResponse, int maxLen, int *samples, int *elapsed) { +static int GetIClassAnswer(uint8_t *receivedResponse, int maxLen, int *samples, int *wait) { // buffer needs to be 512 bytes // maxLen is not used... @@ -1837,13 +1848,16 @@ static int GetIClassAnswer(uint8_t *receivedResponse, int maxLen, int *samples, // Setup UART/DEMOD to receive DemodIcInit(receivedResponse); - if (elapsed) *elapsed = 0; - // Set FPGA mode to "reader listen mode", no modulation (listen // only, since we are receiving, not transmitting). FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_LISTEN); - SpinDelayUs(320); //310 Tout= 330us (iso15603-2) (330/21.3) take consideration for clock increments. + time_delta = GetCountSspClk() - time_rdr; + + SpinDelayUs(g_wait); //310 Tout= 330us (iso15603-2) (330/21.3) take consideration for clock increments. + time_delta_wait = GetCountSspClk() - time_rdr - time_delta; + + uint32_t foo = GetCountSspClk(); // clear RXRDY: uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; (void)b; @@ -1861,15 +1875,16 @@ static int GetIClassAnswer(uint8_t *receivedResponse, int maxLen, int *samples, } // keep tx buffer in a defined state anyway. +/* if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { AT91C_BASE_SSC->SSC_THR = 0x00; - // To make use of exact timing of next command from reader!! - if (elapsed)(*elapsed)++; } - +*/ // Wait for byte be become available in rx holding register if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { - if (c >= timeout) return false; + + if ( GetCountSspClk() - foo > timeout) return false; +// if (c >= timeout) return false; c++; @@ -1881,25 +1896,28 @@ static int GetIClassAnswer(uint8_t *receivedResponse, int maxLen, int *samples, if (ManchesterDecoding_iclass(b & 0x0f)) { if (samples) *samples = c << 3; + + time_response = GetCountSspClk() - foo; return true; } } } + return false; } int ReaderReceiveIClass(uint8_t *receivedAnswer) { int samples = 0; - if (!GetIClassAnswer(receivedAnswer, 0, &samples, NULL)) - return false; + if (GetIClassAnswer(receivedAnswer, 0, &samples, NULL) == false) + return 0; rsamples += samples; LogTrace(receivedAnswer, Demod.len, rsamples, rsamples, NULL, false); if (samples == 0) - return false; + return 0; return Demod.len; } @@ -1924,7 +1942,7 @@ void setupIclassReader() { // Now give it time to spin up. // Signal field is on with the appropriate LED FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD); - SpinDelay(300); + SpinDelay(500); StartCountSspClk(); @@ -1936,13 +1954,20 @@ bool sendCmdGetResponseWithRetries(uint8_t *command, size_t cmdsize, uint8_t *re ReaderTransmitIClass(command, cmdsize); + //iceman - if received size is bigger than expected, we smash the stack here // since its called with fixed sized arrays + + // update/write commadn takes 4ms to 15ms before responding + if ( command[0] == ICLASS_CMD_UPDATE ) + g_wait = 15000; + uint8_t got_n = ReaderReceiveIClass(resp); // 0xBB is the internal debug separator byte.. if (expected_size != got_n || (resp[0] == 0xBB || resp[7] == 0xBB || resp[2] == 0xBB)) { //try again + SpinDelayUs(400); continue; } @@ -2396,8 +2421,6 @@ void iClass_Authentication_fast(uint64_t arg0, uint64_t arg1, uint8_t *datain) { if (isOK) goto out; - SpinDelayUs(400); //iClass (iso15693-2) should timeout after 330us. - // Auth Sequence MUST begin with reading e-purse. (block2) // Card selected, now read e-purse (cc) (block2) (only 8 bytes no CRC) ReaderTransmitIClass(readcheck_cc, sizeof(readcheck_cc)); From d2d58db98528ace9b5bddb912f5baa98b5fd5a31 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 28 Aug 2019 21:15:11 +0200 Subject: [PATCH 0486/1854] Move history and logfile to ~/.proxmark3 --- client/fileutils.c | 2 ++ client/proxmark3.c | 15 ++++++++--- client/proxmark3.h | 2 ++ client/ui.c | 65 ++++++++++++++++++++++++++++++++++++++++------ client/ui.h | 3 ++- 5 files changed, 74 insertions(+), 13 deletions(-) diff --git a/client/fileutils.c b/client/fileutils.c index c3c9f5acc..72771f900 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -896,6 +896,8 @@ out: } int searchFile(char **foundpath, const char *pm3dir, const char *searchname, const char *suffix) { + if (foundpath == NULL) + return PM3_EINVARG; char *filename = filenamemcopy(searchname, suffix); if (filename == NULL) return PM3_EMALLOC; int res = searchFinalFile(foundpath, pm3dir, filename); diff --git a/client/proxmark3.c b/client/proxmark3.c index 6a23f4804..913f3735f 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -102,8 +102,13 @@ main_loop(char *script_cmds_file, char *script_cmd, bool stayInCommandLoop) { PrintAndLogEx(ERR, "could not open " _YELLOW_("%s") "...", script_cmds_file); } - read_history(".history"); - + char *my_history_path = NULL; + if (searchHomeFilePath(&my_history_path, PROXHISTORY, true) != PM3_SUCCESS) { + PrintAndLogEx(ERR, "could not create $HOME/" PROXHISTORY ", no history will be recorded"); + my_history_path = NULL; + } else { + read_history(my_history_path); + } // loops every time enter is pressed... while (1) { bool printprompt = false; @@ -220,8 +225,10 @@ main_loop(char *script_cmds_file, char *script_cmd, bool stayInCommandLoop) { if (sf) fclose(sf); - write_history(".history"); - + if (my_history_path) { + write_history(my_history_path); + free(my_history_path); + } if (cmd) { free(cmd); cmd = NULL; diff --git a/client/proxmark3.h b/client/proxmark3.h index 6d245da10..3da261c31 100644 --- a/client/proxmark3.h +++ b/client/proxmark3.h @@ -18,6 +18,8 @@ #define PROXPROMPT_USB "[usb] pm3 --> " #define PROXPROMPT_FPC "[fpc] pm3 --> " #define PROXPROMPT_OFFLINE "[offline] pm3 --> " +#define PROXHISTORY "history.txt" +#define PROXLOG "log_%Y%m%d.txt" #ifdef __cplusplus extern "C" { diff --git a/client/ui.c b/client/ui.c index 9927fd6d6..86f32e2bd 100644 --- a/client/ui.c +++ b/client/ui.c @@ -24,6 +24,9 @@ #include #include #include "util.h" +#include "proxmark3.h" // PROXLOG +#include "fileutils.h" +#include "pm3_cmd.h" session_arg_t session; @@ -36,9 +39,45 @@ bool GridLocked = false; bool showDemod = true; pthread_mutex_t print_lock = PTHREAD_MUTEX_INITIALIZER; -static const char *logfilename = "proxmark3.log"; + static void fPrintAndLog(FILE *stream, const char *fmt, ...); +// needed by flasher, so let's put it here instead of fileutils.c +int searchHomeFilePath(char **foundpath, const char *filename, bool create_home) { + if (foundpath == NULL) + return PM3_EINVARG; + char *user_path = getenv("HOME"); + if (user_path == NULL) + return PM3_EFILE; + char *path = calloc(strlen(user_path) + strlen(PM3_USER_DIRECTORY) + 1, sizeof(char)); + if (path == NULL) + return PM3_EMALLOC; + strcpy(path, user_path); + strcat(path, PM3_USER_DIRECTORY); + +#ifdef _WIN32 + struct _stat st; + int result = _stat(path, &st); +#else + struct stat st; + int result = stat(path, &st); +#endif + if ((result != 0) && create_home) { + if (mkdir(path, 0700)) { + free(path); + return PM3_EFILE; + } + } + if (filename == NULL) { + *foundpath = path; + return PM3_SUCCESS; + } + path = realloc(path, (strlen(user_path) + strlen(PM3_USER_DIRECTORY) + strlen(filename) + 1) * sizeof(char)); + strcat(path, filename); + *foundpath = path; + return PM3_SUCCESS; +} + void PrintAndLogOptions(const char *str[][2], size_t size, size_t space) { char buff[2000] = "Options:\n"; char format[2000] = ""; @@ -166,10 +205,24 @@ static void fPrintAndLog(FILE *stream, const char *fmt, ...) { pthread_mutex_lock(&print_lock); if (logging && !logfile) { - logfile = fopen(logfilename, "a"); - if (!logfile) { - fprintf(stderr, "Can't open logfile, logging disabled!\n"); + char *my_logfile_path = NULL; + char filename[40]; + struct tm *timenow; + time_t now = time(NULL); + timenow = gmtime(&now); + strftime(filename, sizeof(filename), PROXLOG, timenow); + if (searchHomeFilePath(&my_logfile_path, filename, true) != PM3_SUCCESS) { + fprintf(stderr, "Could not create $HOME/.proxmark3/%s, no log will be recorded\n", filename); + my_logfile_path = NULL; logging = 0; + } else { + logfile = fopen(my_logfile_path, "a"); + if (logfile == NULL) { + fprintf(stderr, "Can't open logfile %s, logging disabled!\n", my_logfile_path); + logging = 0; + } + printf("Session is logged into %s\n", my_logfile_path); + free(my_logfile_path); } } @@ -228,10 +281,6 @@ static void fPrintAndLog(FILE *stream, const char *fmt, ...) { pthread_mutex_unlock(&print_lock); } -void SetLogFilename(char *fn) { - logfilename = fn; -} - void SetFlushAfterWrite(bool value) { flushAfterWrite = value; } diff --git a/client/ui.h b/client/ui.h index 648dce4c4..7e00ab52b 100644 --- a/client/ui.h +++ b/client/ui.h @@ -39,7 +39,6 @@ void ShowGraphWindow(void); void RepaintGraphWindow(void); void PrintAndLogOptions(const char *str[][2], size_t size, size_t space); void PrintAndLogEx(logLevel_t level, const char *fmt, ...); -void SetLogFilename(char *fn); void SetFlushAfterWrite(bool value); void memcpy_filter_ansi(void *dest, const void *src, size_t n, bool filter); @@ -49,6 +48,8 @@ extern uint32_t CursorCPos, CursorDPos; extern bool GridLocked; extern bool showDemod; +int searchHomeFilePath(char **foundpath, const char *filename, bool create_home); + extern pthread_mutex_t print_lock; void iceIIR_Butterworth(int *data, const size_t len); From 11c7db352349d4d88ded9b6446dcdd275018c4d2 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 28 Aug 2019 23:07:23 +0200 Subject: [PATCH 0487/1854] Get ~/.proxmark3 working on Mingw --- client/ui.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/client/ui.c b/client/ui.c index 86f32e2bd..e6edb4369 100644 --- a/client/ui.c +++ b/client/ui.c @@ -27,7 +27,10 @@ #include "proxmark3.h" // PROXLOG #include "fileutils.h" #include "pm3_cmd.h" - +#ifdef _WIN32 +# include // _mkdir +#endif +#include session_arg_t session; double CursorScaleFactor = 1; @@ -55,15 +58,16 @@ int searchHomeFilePath(char **foundpath, const char *filename, bool create_home) strcpy(path, user_path); strcat(path, PM3_USER_DIRECTORY); -#ifdef _WIN32 - struct _stat st; - int result = _stat(path, &st); -#else +// Mingw: _stat fails on mangled HOME path /pm3 => C:\ProxSpace\pm3, while stat works fine struct stat st; int result = stat(path, &st); -#endif if ((result != 0) && create_home) { + +#ifdef _WIN32 + if (_mkdir(path)) { +#else if (mkdir(path, 0700)) { +#endif free(path); return PM3_EFILE; } From 37243a47294c7e74e5f708e4de2368857c6e903a Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 28 Aug 2019 23:09:59 +0200 Subject: [PATCH 0488/1854] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e3db619fd..f7dc5d6a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Chg history and logfile are now saved into $HOME/.proxmark3/ (@doegox) - Chg optimization of iclass mac calculations on deviceside (@pwpiwi) - Add 'hf mf autopwn' - Autopwn function for Mifare Classic, extract all keys and dump card memory (@matthiaskonrath) - Add Lua paths: look for scripts also in ~/.proxmark/lua{scripts,libs} and /usr/local/share/proxmark3/lua{scripts,libs} (@doegox) From aa77f7298c18c22dda15673d518093b6f0f0e55e Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 28 Aug 2019 23:28:28 +0200 Subject: [PATCH 0489/1854] Fix buffer allocation for showing compiler version --- client/cmdhw.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/client/cmdhw.c b/client/cmdhw.c index b6cb2bd87..68a5390c6 100644 --- a/client/cmdhw.c +++ b/client/cmdhw.c @@ -619,15 +619,18 @@ int CmdHW(const char *Cmd) { void pm3_version(bool verbose, bool oneliner) { - if (oneliner) { - char msg[70]; - memset(msg, 0x00, sizeof(msg)); - strcat(msg, "Client: RRG/Iceman compiled with "); +#define PM3CLIENTONELINER "Client: RRG/Iceman compiled with " #if defined(__clang__) - strcat(msg + strlen(msg), _YELLOW_("Clang/LLVM "__VERSION__)); +# define PM3CLIENTCOMPILER "Clang/LLVM " #elif defined(__GNUC__) || defined(__GNUG__) - strcat(msg + strlen(msg), _YELLOW_("GCC "__VERSION__)); +# define PM3CLIENTCOMPILER "GCC " #endif + + if (oneliner) { + char msg[sizeof(PM3CLIENTONELINER)+sizeof(PM3CLIENTCOMPILER)+sizeof(__VERSION__)]; + memset(msg, 0x00, sizeof(msg)); + strcat(msg, PM3CLIENTONELINER); + strcat(msg + strlen(msg), _YELLOW_(PM3CLIENTCOMPILER __VERSION__)); PrintAndLogEx(NORMAL, "%s", msg); return; } @@ -644,12 +647,7 @@ void pm3_version(bool verbose, bool oneliner) { PrintAndLogEx(NORMAL, "\n" _BLUE_(" [ Proxmark3 RFID instrument ]") "\n"); PrintAndLogEx(NORMAL, "\n [ CLIENT ]"); PrintAndLogEx(NORMAL, " client: RRG/Iceman"); // TODO version info? -#if defined(__clang__) - PrintAndLogEx(NORMAL, " compiled with Clang/LLVM "__VERSION__); -#elif defined(__GNUC__) || defined(__GNUG__) - PrintAndLogEx(NORMAL, " compiled with GCC "__VERSION__); -#endif - + PrintAndLogEx(NORMAL, " compiled with " PM3CLIENTCOMPILER __VERSION__); PrintAndLogEx(NORMAL, "\n [ PROXMARK RDV4 ]"); PrintAndLogEx(NORMAL, " external flash: %s", IfPm3Flash() ? _GREEN_("present") : _YELLOW_("absent")); PrintAndLogEx(NORMAL, " smartcard reader: %s", IfPm3Smartcard() ? _GREEN_("present") : _YELLOW_("absent")); From 430c53a7ac0985526188ea02798a2c69ffd8a23d Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 28 Aug 2019 23:51:52 +0200 Subject: [PATCH 0490/1854] Fix buffer allocation again, just getting rid of it --- client/cmdhw.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/client/cmdhw.c b/client/cmdhw.c index 68a5390c6..1d65f5d1d 100644 --- a/client/cmdhw.c +++ b/client/cmdhw.c @@ -619,7 +619,6 @@ int CmdHW(const char *Cmd) { void pm3_version(bool verbose, bool oneliner) { -#define PM3CLIENTONELINER "Client: RRG/Iceman compiled with " #if defined(__clang__) # define PM3CLIENTCOMPILER "Clang/LLVM " #elif defined(__GNUC__) || defined(__GNUG__) @@ -627,11 +626,7 @@ void pm3_version(bool verbose, bool oneliner) { #endif if (oneliner) { - char msg[sizeof(PM3CLIENTONELINER)+sizeof(PM3CLIENTCOMPILER)+sizeof(__VERSION__)]; - memset(msg, 0x00, sizeof(msg)); - strcat(msg, PM3CLIENTONELINER); - strcat(msg + strlen(msg), _YELLOW_(PM3CLIENTCOMPILER __VERSION__)); - PrintAndLogEx(NORMAL, "%s", msg); + PrintAndLogEx(NORMAL, "Client: RRG/Iceman compiled with " _YELLOW_(PM3CLIENTCOMPILER __VERSION__)); return; } From 199c1b3c9bba1a5ba6833d252b8a9274b66e38e6 Mon Sep 17 00:00:00 2001 From: Oleg Moiseenko <807634+merlokk@users.noreply.github.com> Date: Thu, 29 Aug 2019 02:38:35 +0300 Subject: [PATCH 0491/1854] Appveyour (#369) appveyour fix --- appveyor.yml | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 56 insertions(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index a0c261b2b..a0a4b18a9 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -76,10 +76,64 @@ clone_script: Write-Host "Update msys2 packages..." -NoNewLine $env:Path = "C:\ProxSpace\msys2\usr\bin;C:\ProxSpace\msys2\mingw32\bin;C:\ProxSpace\gcc-arm-none-eabi\bin;$env:Path" + + Function ExecUpdate($Name, $Cmd, $ErrorLine) { - C:\ProxSpace\msys2\msys2_shell.cmd -mingw32 -defterm -no-start /dev/null 1> msys1.txt 2>&1 + #--- begin Job + + $Job = Start-Job -Name "$Name" -ScriptBlock { + $env:Path = "C:\ProxSpace\msys\bin;$env:Path" + Set-Location $using:PWD - C:\ProxSpace\msys2\msys2_shell.cmd -mingw32 -defterm -no-start /dev/null 1> msys1.txt 2>&1 + $sb=[scriptblock]::Create("$using:Cmd") + #execute scriptblock + $Cond=&$sb + + return $Cond + } + + #--- end Job + + $JobTime=[System.Environment]::TickCount + while($true) { + Receive-Job -Job $Job -Keep -OutVariable Res 2>&1 6>&1 | Out-Null + + if ($Res -is "String" -and $Res -like "*$ErrorLine*"){ + Write-host "Exit by stop phrase" + break + } + + if ($Res -is [Object]){ + [bool]$needexit = $false + ForEach($line in $Res){ + if ($line -like "*$ErrorLine*"){ + Write-host "Exit by stop phrase [obj]" + $needexit = $true + break + } + } + if ($needexit) { + break + } + } + + if(Wait-Job $Job -Timeout 5){ + Write-host "Exit by end job" + break + } + + if ([System.Environment]::TickCount-$JobTime -gt 600000) { + Write-host "Exit by timeout" + break + } + } + + Remove-Job -Force $Job + } + + ExecUpdate "update1" "C:\ProxSpace\msys2\msys2_shell.cmd -mingw32 -defterm -no-start /dev/null" "terminate?MSYS2" + + ExecUpdate "update2" "C:\ProxSpace\msys2\msys2_shell.cmd -mingw32 -defterm -no-start /dev/null" "terminate?MSYS2" Write-Host "[ OK ]" -ForegroundColor Green install: From 3683cd88c66e4889935009c38d65faf4d3eed17e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 29 Aug 2019 07:45:09 +0200 Subject: [PATCH 0492/1854] chg: 'hw version' - simple os detection. --- client/cmdhw.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/client/cmdhw.c b/client/cmdhw.c index 1d65f5d1d..fe6dc2b4d 100644 --- a/client/cmdhw.c +++ b/client/cmdhw.c @@ -625,8 +625,55 @@ void pm3_version(bool verbose, bool oneliner) { # define PM3CLIENTCOMPILER "GCC " #endif +#if defined(__APPLE__) || defined(__MACH__) +#ifndef PM3HOSTOS +# define PM3HOSTOS "OS X" +#endif + +#elif defined(_MINGW_) +#ifndef PM3HOSTOS +# define PM3HOSTOS "MingW" +#endif + +#elif defined(__LINUX__) +#ifndef PM3HOSTOS +# define PM3HOSTOS "linux" +#endif + +#elif defined(__FreeBSd__) +#ifndef PM3HOSTOS +# define PM3HOSTOS "FreeBSD" +#endif + +#elif defined(__NetBSD__) +#ifndef PM3HOSTOS +# define PM3HOSTOS "NetBSD" +#endif + +#elif defined(__OpenBSD__) +#ifndef PM3HOSTOS +# define PM3HOSTOS "OpenBSD" +#endif + +#elif defined(_WIN32) | defined(__WIN32__) +#ifndef PM3HOSTOS +# define PM3HOSTOS "Windows (32b)" +#endif + +#elif defined(_WIN64) | defined(__WIN64__) +#ifndef PM3HOSTOS +# define PM3HOSTOS "Windows (64b)" +#endif + +#elif defined(__ANDROID__) || defined(ANDROID) +#ifndef PM3HOSTOS +# define PM3HOSTOS "Android" +#endif +#endif + + if (oneliner) { - PrintAndLogEx(NORMAL, "Client: RRG/Iceman compiled with " _YELLOW_(PM3CLIENTCOMPILER __VERSION__)); + PrintAndLogEx(NORMAL, "Client: RRG/Iceman compiled with " _YELLOW_(PM3CLIENTCOMPILER __VERSION__) " on " _YELLOW_(PM3HOSTOS)); return; } @@ -642,7 +689,7 @@ void pm3_version(bool verbose, bool oneliner) { PrintAndLogEx(NORMAL, "\n" _BLUE_(" [ Proxmark3 RFID instrument ]") "\n"); PrintAndLogEx(NORMAL, "\n [ CLIENT ]"); PrintAndLogEx(NORMAL, " client: RRG/Iceman"); // TODO version info? - PrintAndLogEx(NORMAL, " compiled with " PM3CLIENTCOMPILER __VERSION__); + PrintAndLogEx(NORMAL, " compiled with " PM3CLIENTCOMPILER __VERSION__ " on " PM3HOSTOS); PrintAndLogEx(NORMAL, "\n [ PROXMARK RDV4 ]"); PrintAndLogEx(NORMAL, " external flash: %s", IfPm3Flash() ? _GREEN_("present") : _YELLOW_("absent")); PrintAndLogEx(NORMAL, " smartcard reader: %s", IfPm3Smartcard() ? _GREEN_("present") : _YELLOW_("absent")); From 979f3aba2eb24a6c9c66d6cd2b2c8a425834a2ca Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 29 Aug 2019 07:47:17 +0200 Subject: [PATCH 0493/1854] chg: 'hf iclass chk' chg: 'hf iclass lookup' - use fileutils load dictionary instead. chg: 'hf iclass encrypt' - start w change to allow for key parameter --- client/cmdhficlass.c | 401 ++++++++++++++++++++++--------------------- client/cmdhficlass.h | 6 +- 2 files changed, 204 insertions(+), 203 deletions(-) diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 51bc323fc..30b2a0560 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -76,20 +76,25 @@ static int usage_hf_iclass_decrypt(void) { PrintAndLogEx(NORMAL, "OBS! In order to use this function, the file 'iclass_decryptionkey.bin' must reside"); PrintAndLogEx(NORMAL, "in the working directory. The file should be 16 bytes binary data"); PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Usage: hf iclass decrypt f "); + PrintAndLogEx(NORMAL, "Usage: hf iclass decrypt f k "); + PrintAndLogEx(NORMAL, " options"); + PrintAndLogEx(NORMAL, " f filename of dump"); + PrintAndLogEx(NORMAL, " k 16 bytes hex"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, "S hf iclass decrypt f tagdump_12312342343.bin"); + PrintAndLogEx(NORMAL, "S hf iclass decrypt f tagdump_1.bin"); + PrintAndLogEx(NORMAL, "S hf iclass decrypt f tagdump_1.bin k 000102030405060708090a0b0c0d0e0f"); return PM3_SUCCESS; } static int usage_hf_iclass_encrypt(void) { PrintAndLogEx(NORMAL, "OBS! In order to use this function, the file 'iclass_decryptionkey.bin' must reside"); PrintAndLogEx(NORMAL, "in the working directory. The file should be 16 bytes binary data"); PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Usage: hf iclass encrypt "); + PrintAndLogEx(NORMAL, "Usage: hf iclass encrypt d k "); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf iclass encrypt 0102030405060708"); + PrintAndLogEx(NORMAL, " hf iclass encrypt d 0102030405060708"); + PrintAndLogEx(NORMAL, " hf iclass encrypt d 0102030405060708 k 00112233445566778899AABBCCDDEEFF"); PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } @@ -541,11 +546,11 @@ static int CmdHFiClassSim(const char *Cmd) { tries++; if (kbd_enter_pressed()) { PrintAndLogEx(WARNING, "\naborted via keyboard."); - return 0; + return PM3_EOPABORTED; } if (tries > 20) { PrintAndLogEx(WARNING, "\ntimeout while waiting for reply."); - return 0; + return PM3_ETIMEOUT; } } uint8_t num_mac = resp.oldarg[1]; @@ -559,7 +564,7 @@ static int CmdHFiClassSim(const char *Cmd) { uint8_t *dump = calloc(datalen, sizeof(uint8_t)); if (!dump) { PrintAndLogEx(WARNING, "Failed to allocate memory"); - return 2; + return PM3_EMALLOC; } memset(dump, 0, datalen);//<-- Need zeroes for the EPURSE - field (offical) @@ -590,11 +595,11 @@ static int CmdHFiClassSim(const char *Cmd) { tries++; if (kbd_enter_pressed()) { PrintAndLogEx(WARNING, "\naborted via keyboard."); - return 0; + return PM3_EOPABORTED; } if (tries > 20) { PrintAndLogEx(WARNING, "\ntimeout while waiting for reply."); - return 0; + return PM3_ETIMEOUT; } } uint8_t num_mac = resp.oldarg[1]; @@ -608,7 +613,7 @@ static int CmdHFiClassSim(const char *Cmd) { uint8_t *dump = calloc(datalen, sizeof(uint8_t)); if (!dump) { PrintAndLogEx(WARNING, "Failed to allocate memory"); - return 2; + return PM3_EMALLOC; } #define MAC_ITEM_SIZE 24 @@ -681,54 +686,85 @@ static int CmdHFiClassReader_Replay(const char *Cmd) { static int CmdHFiClassELoad(const char *Cmd) { - char ctmp = tolower(param_getchar(Cmd, 0)); - if (strlen(Cmd) < 1 || ctmp == 'h') return usage_hf_iclass_eload(); - - if (ctmp != 'f') return usage_hf_iclass_eload(); - - //File handling and reading - char filename[FILE_PATH_SIZE]; - - if (param_getstr(Cmd, 1, filename, FILE_PATH_SIZE) >= FILE_PATH_SIZE) { + DumpFileType_t dftype = BIN; + char filename[FILE_PATH_SIZE] = {0}; + bool errors = false; + uint8_t cmdp = 0; + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { + case 'h': + return usage_hf_iclass_eload(); + case 'f': + if (param_getstr(Cmd, cmdp + 1, filename, FILE_PATH_SIZE) >= FILE_PATH_SIZE) { PrintAndLogEx(FAILED, "Filename too long"); - return 1; + errors = true; + break; + } + cmdp += 2; + break; + case 'j': + dftype = JSON; + cmdp++; + break; + case 'e': + dftype = EML; + cmdp++; + break; + default: + PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } } - FILE *f = fopen(filename, "rb"); - if (!f) { - PrintAndLogEx(FAILED, "File: " _YELLOW_("%s") ": not found or locked.", filename); + //Validations + if (errors || cmdp == 0) { + usage_hf_iclass_eload(); + return PM3_EINVARG; + } + + + uint8_t *dump = calloc(2048, sizeof(uint8_t)); + if (!dump) { + PrintAndLogEx(ERR, "error, cannot allocate memory "); + return PM3_EMALLOC; + } + + size_t bytes_read = 2048; + int res = 0; + + switch ( dftype ) { + case BIN: { + res = loadFile(filename, ".bin", (void*)&dump, 2048, &bytes_read); + break; + } + case EML: { + res = loadFileEML(filename, dump, &bytes_read); + break; + } + case JSON: { + res = loadFileJSON(filename, dump, 2048, &bytes_read); + break; + } + default: + PrintAndLogEx(ERR, "No dictionary loaded"); + return PM3_ESOFT; + } + + if ( res != PM3_SUCCESS ) { + free(dump); return PM3_EFILE; } - // get filesize in order to malloc memory - fseek(f, 0, SEEK_END); - long fsize = ftell(f); - fseek(f, 0, SEEK_SET); - - if (fsize <= 0) { - PrintAndLogEx(ERR, "error, when getting filesize"); - fclose(f); - return 1; + uint8_t *newdump = realloc(dump, bytes_read); + if (newdump == NULL) { + free(dump); + return PM3_EMALLOC; + } else { + dump = newdump; } - uint8_t *dump = calloc(fsize, sizeof(uint8_t)); - if (!dump) { - PrintAndLogEx(ERR, "error, cannot allocate memory "); - fclose(f); - return 1; - } - - size_t bytes_read = fread(dump, 1, fsize, f); - fclose(f); - printIclassDumpInfo(dump); - //Validate - - if (bytes_read < fsize) { - PrintAndLogEx(ERR, "error, could only read %d bytes (should be %d)", bytes_read, fsize); - free(dump); - return 1; - } // fast push mode conn.block_after_ACK = true; @@ -754,26 +790,23 @@ static int CmdHFiClassELoad(const char *Cmd) { return PM3_SUCCESS; } -static int readKeyfile(const char *filename, size_t len, uint8_t *buffer) { - FILE *f = fopen(filename, "rb"); - if (!f) { - PrintAndLogEx(FAILED, "File: " _YELLOW_("%s") ": not found or locked.", filename); +static int readKeyfile(const char *filename, size_t len, uint8_t **buffer) { + + char *path; + int res = searchFile(&path, PM3_USER_DIRECTORY, filename, ".bin"); + if (res != PM3_SUCCESS) { + PrintAndLogEx(INFO, "res: %d Curr path:: %s", res, path); return PM3_EFILE; } - fseek(f, 0, SEEK_END); - long fsize = ftell(f); - fseek(f, 0, SEEK_SET); - size_t bytes_read = fread(buffer, 1, len, f); - fclose(f); - if (fsize != len) { - PrintAndLogEx(WARNING, "Warning, file size is %d, expected %d", fsize, len); - return 1; - } + size_t datalen = 0; + res = loadFile(path, ".bin", (void*)*buffer, len, &datalen); + if ( res != PM3_SUCCESS ) + return res; - if (bytes_read != len) { - PrintAndLogEx(WARNING, "Warning, could only read %d bytes, expected %d", bytes_read, len); - return 1; + if (datalen != len) { + PrintAndLogEx(ERR, "ERROR, Wrong filesize. Got %d bytes, expected %d", datalen, len); + return PM3_EFILE; } return PM3_SUCCESS; } @@ -784,7 +817,9 @@ static int CmdHFiClassDecrypt(const char *Cmd) { if (strlen(Cmd) < 1 || opt == 'h') return usage_hf_iclass_decrypt(); uint8_t key[16] = { 0 }; - if (readKeyfile("iclass_decryptionkey.bin", 16, key)) return usage_hf_iclass_decrypt(); + uint8_t *keyptr = key; + if (readKeyfile("iclass_decryptionkey", sizeof(key), &keyptr) != PM3_SUCCESS) + return usage_hf_iclass_decrypt(); PrintAndLogEx(SUCCESS, "decryption key loaded from file"); @@ -861,41 +896,69 @@ static int CmdHFiClassDecrypt(const char *Cmd) { saveFile(outfilename, ".bin", decrypted, fsize); saveFileEML(outfilename, decrypted, fsize, 8); + saveFileJSON(outfilename, jsfIclass, decrypted, fsize); + printIclassDumpContents(decrypted, 1, (fsize / 8), fsize); free(decrypted); return PM3_SUCCESS; } -static int iClassEncryptBlkData(uint8_t *blkData) { - uint8_t key[16] = { 0 }; - if (readKeyfile("iclass_decryptionkey.bin", 16, key)) { - usage_hf_iclass_encrypt(); - return 1; - } - PrintAndLogEx(SUCCESS, "decryption file found"); - uint8_t encryptedData[16]; - uint8_t *encrypted = encryptedData; +static void iClassEncryptBlkData(uint8_t *blk_data, uint8_t *key) { + uint8_t encrypted_data[16]; + uint8_t *encrypted = encrypted_data; mbedtls_des3_context ctx; mbedtls_des3_set2key_enc(&ctx, key); - - mbedtls_des3_crypt_ecb(&ctx, blkData, encrypted); - memcpy(blkData, encrypted, 8); - return 1; + mbedtls_des3_crypt_ecb(&ctx, blk_data, encrypted); + memcpy(blk_data, encrypted, 8); } static int CmdHFiClassEncryptBlk(const char *Cmd) { - uint8_t blkData[8] = {0}; - char opt = tolower(param_getchar(Cmd, 0)); - if (strlen(Cmd) < 1 || opt == 'h') return usage_hf_iclass_encrypt(); + bool errors = false; + bool have_key = false; + uint8_t blk_data[8] = {0}; + uint8_t key[16] = {0}; + uint8_t *keyptr = key; + uint8_t cmdp = 0; + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { + case 'h': + return usage_hf_iclass_encrypt(); + case 'd': //get the bytes to encrypt - if (param_gethex(Cmd, 0, blkData, 16)) { - PrintAndLogEx(NORMAL, "BlockData must include 16 HEX symbols"); - return 0; + if (param_gethex(Cmd, cmdp + 1, blk_data, 16) != PM3_SUCCESS) { + PrintAndLogEx(ERR, "Block data must include 16 HEX symbols"); + errors = true;; + } + cmdp += 2; + break; + case 'k': + if (param_gethex(Cmd, cmdp + 1, key, 32) != PM3_SUCCESS) { + PrintAndLogEx(ERR, "Transport key must include 32 HEX symbols"); + errors = true;; + } + have_key = true; + cmdp += 2; + break; + default: + PrintAndLogEx(WARNING, "Unknown parameter '%c'\n", param_getchar(Cmd, cmdp)); + errors = true; + break; + } } - if (!iClassEncryptBlkData(blkData)) return 0; - printvar("encrypted block", blkData, 8); + if (errors || cmdp < 1) return usage_hf_iclass_encrypt(); + + if ( have_key == false ) { + if (readKeyfile("./iclass_decryptionkey", sizeof(key), &keyptr) != PM3_SUCCESS) { + return usage_hf_iclass_encrypt(); + } + PrintAndLogEx(SUCCESS, "Loaded transport key from decryption file"); + } + + iClassEncryptBlkData(blk_data, key); + + printvar("encrypted block", blk_data, 8); return PM3_SUCCESS; } @@ -1593,7 +1656,7 @@ static int CmdHFiClass_loclass(const char *Cmd) { char opt = tolower(param_getchar(Cmd, 0)); if (strlen(Cmd) < 1 || opt == 'h') - usage_hf_iclass_loclass(); + return usage_hf_iclass_loclass(); if (opt == 'f') { char fileName[FILE_PATH_SIZE] = {0}; @@ -1601,7 +1664,7 @@ static int CmdHFiClass_loclass(const char *Cmd) { return bruteforceFileNoKeys(fileName); } else { PrintAndLogEx(WARNING, "You must specify a filename"); - return 0; + return PM3_EFILE; } } else if (opt == 't') { int errors = testCipherUtils(); @@ -2001,10 +2064,7 @@ static int CmdHFiClassCheckKeys(const char *Cmd) { char filename[FILE_PATH_SIZE] = {0}; uint8_t fileNameLen = 0; - - uint8_t *keyBlock = NULL; iclass_premac_t *pre = NULL; - int keycnt = 0; // time uint64_t t1 = msclock(); @@ -2042,35 +2102,36 @@ static int CmdHFiClassCheckKeys(const char *Cmd) { if (errors) return usage_hf_iclass_chk(); + uint8_t *keyBlock = NULL; + uint16_t keycount = 0; + + // load keys + int res = loadFileDICTIONARY_safe(filename, (void**)&keyBlock, 8, &keycount); + if (res != PM3_SUCCESS || keycount == 0) { + free(keyBlock); + return res; + } + // Get CSN / UID and CCNR PrintAndLogEx(SUCCESS, "Reading tag CSN"); for (uint8_t i = 0; i < 10 && !got_csn; i++) { - if (select_only(CSN, CCNR, false, false)) { - got_csn = true; - } else { + got_csn = select_only(CSN, CCNR, false, false); + if ( got_csn == false ) PrintAndLogEx(WARNING, "one more try\n"); } - } - if (!got_csn) { - PrintAndLogEx(WARNING, "can't select card, aborting..."); + if ( got_csn == false ) { + PrintAndLogEx(WARNING, "Tried 10 times. Can't select card, aborting..."); return PM3_ESOFT; } - // load keys into keyblock - int res = LoadDictionaryKeyFile(filename, &keyBlock, &keycnt); - if (res > 0) { - free(keyBlock); - return PM3_EFILE; - } - - pre = calloc(keycnt, sizeof(iclass_premac_t)); + pre = calloc(keycount, sizeof(iclass_premac_t)); if (!pre) { free(keyBlock); return PM3_EMALLOC; } - PrintAndLogEx(SUCCESS, "Generating diversified keys, MAC"); + PrintAndLogEx(SUCCESS, "Generating diversified keys"); if (use_elite) PrintAndLogEx(SUCCESS, "Using " _YELLOW_("elite algo")); if (use_raw) @@ -2080,17 +2141,13 @@ static int CmdHFiClassCheckKeys(const char *Cmd) { PrintAndLogEx(SUCCESS, "Tag info"); PrintAndLogEx(SUCCESS, "CSN | %s", sprint_hex(CSN, sizeof(CSN))); PrintAndLogEx(SUCCESS, "CCNR | %s", sprint_hex(CCNR, sizeof(CCNR))); - res = GenerateMacFromKeyFile(CSN, CCNR, use_raw, use_elite, keyBlock, keycnt, pre); - if (res > 0) { - free(keyBlock); - free(pre); - return PM3_ESOFT; - } + + GenerateMacFrom(CSN, CCNR, use_raw, use_elite, keyBlock, keycount, pre); //PrintPreCalcMac(keyBlock, keycnt, pre); // max 42 keys inside USB_COMMAND. 512/4 = 103 mac - uint32_t chunksize = keycnt > (PM3_CMD_DATA_SIZE / 4) ? (PM3_CMD_DATA_SIZE / 4) : keycnt; + uint32_t chunksize = keycount > (PM3_CMD_DATA_SIZE / 4) ? (PM3_CMD_DATA_SIZE / 4) : keycount; bool lastChunk = false; // fast push mode @@ -2100,7 +2157,7 @@ static int CmdHFiClassCheckKeys(const char *Cmd) { uint8_t found_offset = 0; uint32_t key_offset = 0; // main keychunk loop - for (uint32_t key_offset = 0; key_offset < keycnt; key_offset += chunksize) { + for (uint32_t key_offset = 0; key_offset < keycount; key_offset += chunksize) { uint64_t t2 = msclock(); uint8_t timeout = 0; @@ -2110,10 +2167,10 @@ static int CmdHFiClassCheckKeys(const char *Cmd) { goto out; } - uint32_t keys = ((keycnt - key_offset) > chunksize) ? chunksize : keycnt - key_offset; + uint32_t keys = ((keycount - key_offset) > chunksize) ? chunksize : keycount - key_offset; // last chunk? - if (keys == keycnt - key_offset) { + if (keys == keycount - key_offset) { lastChunk = true; // Disable fast mode on last command conn.block_after_ACK = false; @@ -2146,20 +2203,20 @@ static int CmdHFiClassCheckKeys(const char *Cmd) { case 1: { found_debit = true; - PrintAndLogEx(NORMAL, "\n[-] Chunk [%d/%d]: %.1fs [%s] found key %s (index %u)" + PrintAndLogEx(NORMAL, "\n[-] Chunk [%d/%d]: %.1fs [%s] idx [%u] - found key "_YELLOW_("%s") , key_offset - , keycnt + , keycount , (float)(t2 / 1000.0) , (use_credit_key) ? "credit" : "debit" - , sprint_hex(keyBlock + (key_offset + found_offset) * 8, 8) , found_offset + , sprint_hex(keyBlock + (key_offset + found_offset) * 8, 8) ); break; } case 0: { PrintAndLogEx(NORMAL, "\n[-] Chunk [%d/%d] : %.1fs [%s]" , key_offset - , keycnt + , keycount , (float)(t2 / 1000.0) , (use_credit_key) ? "credit" : "debit" ); @@ -2193,7 +2250,7 @@ out: if ( memcmp(iClass_Key_Table[i], "\x00\x00\x00\x00\x00\x00\x00\x00", 8) == 0 ) { memcpy(iClass_Key_Table[i], keyBlock + (key_offset + found_offset) * 8, 8); - PrintAndLogEx(SUCCESS, "Added found key to keyslot [%d] - "_YELLOW_("`hf iclass managekeys p`")" to view", i); + PrintAndLogEx(SUCCESS, "Added key to keyslot [%d] - "_YELLOW_("`hf iclass managekeys p`")" to view", i); break; } } @@ -2235,12 +2292,9 @@ static int CmdHFiClassLookUp(const char *Cmd) { uint8_t cmdp = 0x00; char filename[FILE_PATH_SIZE] = {0}; - uint8_t fileNameLen = 0; - uint8_t *keyBlock = NULL; iclass_prekey_t *prekey = NULL; - int keycnt = 0, len = 0; - + int len = 0; // if empty string if (strlen(Cmd) == 0) errors = true; // time @@ -2251,8 +2305,7 @@ static int CmdHFiClassLookUp(const char *Cmd) { case 'h': return usage_hf_iclass_lookup(); case 'f': - fileNameLen = param_getstr(Cmd, cmdp + 1, filename, sizeof(filename)); - if (fileNameLen < 1) { + if ( param_getstr(Cmd, cmdp + 1, filename, sizeof(filename)) < 1 ) { PrintAndLogEx(WARNING, "No filename found after f"); errors = true; } @@ -2311,54 +2364,54 @@ static int CmdHFiClassLookUp(const char *Cmd) { PrintAndLogEx(SUCCESS, "CCNR | %s", sprint_hex(CCNR, sizeof(CCNR))); PrintAndLogEx(SUCCESS, "MAC_TAG | %s", sprint_hex(MAC_TAG, sizeof(MAC_TAG))); - int res = LoadDictionaryKeyFile(filename, &keyBlock, &keycnt); - if (res > 0) { + uint8_t *keyBlock = NULL; + uint16_t keycount = 0; + + // load keys + int res = loadFileDICTIONARY_safe(filename, (void**)&keyBlock, 8, &keycount); + if (res != PM3_SUCCESS || keycount == 0) { free(keyBlock); - return 1; + return res; } + //iclass_prekey_t - prekey = calloc(keycnt, sizeof(iclass_prekey_t)); + prekey = calloc(keycount, sizeof(iclass_prekey_t)); if (!prekey) { free(keyBlock); - return 1; + return PM3_EMALLOC; } - PrintAndLogEx(FAILED, "Generating diversified keys and MAC"); - res = GenerateFromKeyFile(CSN, CCNR, use_raw, use_elite, keyBlock, keycnt, prekey); - if (res > 0) { - free(keyBlock); - free(prekey); - return 1; - } + PrintAndLogEx(INFO, "Generating diversified keys"); + GenerateMacKeyFrom(CSN, CCNR, use_raw, use_elite, keyBlock, keycount, prekey); - PrintAndLogEx(FAILED, "Sorting"); + PrintAndLogEx(INFO, "Sorting"); // sort mac list. - qsort(prekey, keycnt, sizeof(iclass_prekey_t), cmp_uint32); + qsort(prekey, keycount, sizeof(iclass_prekey_t), cmp_uint32); //PrintPreCalc(prekey, keycnt); - PrintAndLogEx(FAILED, "Searching"); + PrintAndLogEx(INFO, "Searching"); iclass_prekey_t *item; iclass_prekey_t lookup; memcpy(lookup.mac, MAC_TAG, 4); // binsearch - item = (iclass_prekey_t *) bsearch(&lookup, prekey, keycnt, sizeof(iclass_prekey_t), cmp_uint32); + item = (iclass_prekey_t *) bsearch(&lookup, prekey, keycount, sizeof(iclass_prekey_t), cmp_uint32); t1 = msclock() - t1; PrintAndLogEx(NORMAL, "\nTime in iclass : %.0f seconds\n", (float)t1 / 1000.0); // foudn if (item != NULL) { - PrintAndLogEx(SUCCESS, "\n[debit] found key %s", sprint_hex(item->key, 8)); + PrintAndLogEx(SUCCESS, "[debit] found key " _YELLOW_("%s"), sprint_hex(item->key, 8)); for (uint8_t i=0; i< ICLASS_KEYS_MAX; i++) { // simple check for preexistences if ( memcmp(item->key, iClass_Key_Table[i], 8) == 0 ) break; if ( memcmp(iClass_Key_Table[i] , "\x00\x00\x00\x00\x00\x00\x00\x00", 8) == 0 ) { memcpy(iClass_Key_Table[i], item->key, 8); - PrintAndLogEx(SUCCESS, "Added found key to keyslot [%d] - "_YELLOW_("`hf iclass managekeys p`")"to view", i); + PrintAndLogEx(SUCCESS, "Added key to keyslot [%d] - "_YELLOW_("`hf iclass managekeys p`")"to view", i); break; } } @@ -2370,58 +2423,8 @@ static int CmdHFiClassLookUp(const char *Cmd) { return PM3_SUCCESS; } -int LoadDictionaryKeyFile(char *filename, uint8_t **keys, int *keycnt) { - - char buf[17]; - FILE *f; - uint8_t *p; - int keyitems = 0; - - if (!(f = fopen(filename, "r"))) { - PrintAndLogEx(FAILED, "File: " _YELLOW_("%s") ": not found or locked.", filename); - return 1; - } - - while (fgets(buf, sizeof(buf), f)) { - if (strlen(buf) < 16 || buf[15] == '\n') - continue; - - //goto next line - while (fgetc(f) != '\n' && !feof(f)) {}; - - //The line start with # is comment, skip - if (buf[0] == '#') - continue; - - // doesn't this only test first char only? - if (!isxdigit(buf[0])) { - PrintAndLogEx(ERR, "file content error. '%s' must include 16 HEX symbols", buf); - continue; - } - - // null terminator (skip the rest of the line) - buf[16] = 0; - - p = realloc(*keys, 8 * (keyitems += 64)); - if (!p) { - PrintAndLogEx(ERR, "cannot allocate memory for default keys"); - fclose(f); - return 2; - } - *keys = p; - - memset(*keys + 8 * (*keycnt), 0, 8); - num_to_bytes(strtoull(buf, NULL, 16), 8, *keys + 8 * (*keycnt)); - (*keycnt)++; - memset(buf, 0, sizeof(buf)); - } - fclose(f); - PrintAndLogEx(SUCCESS, "Loaded " _GREEN_("%2d") "keys from %s", *keycnt, filename); - return PM3_SUCCESS; -} - // precalc diversified keys and their MAC -int GenerateMacFromKeyFile(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elite, uint8_t *keys, int keycnt, iclass_premac_t *list) { +void GenerateMacFrom(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elite, uint8_t *keys, int keycnt, iclass_premac_t *list) { uint8_t key[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; uint8_t div_key[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; @@ -2436,10 +2439,9 @@ int GenerateMacFromKeyFile(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_e doMAC(CCNR, div_key, list[i].mac); } - return PM3_SUCCESS; } -int GenerateFromKeyFile(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elite, uint8_t *keys, int keycnt, iclass_prekey_t *list) { +void GenerateMacKeyFrom(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elite, uint8_t *keys, int keycnt, iclass_prekey_t *list) { uint8_t div_key[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; @@ -2456,7 +2458,6 @@ int GenerateFromKeyFile(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elit // generate MAC doMAC(CCNR, div_key, list[i].mac); } - return PM3_SUCCESS; } // print diversified keys diff --git a/client/cmdhficlass.h b/client/cmdhficlass.h index 9f2b5caac..73304d4d0 100644 --- a/client/cmdhficlass.h +++ b/client/cmdhficlass.h @@ -12,6 +12,7 @@ #define CMDHFICLASS_H__ #include "common.h" +#include "fileutils.h" typedef struct iclass_block { uint8_t d[8]; @@ -32,9 +33,8 @@ int readIclass(bool loop, bool verbose); void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t endblock, size_t filesize); void HFiClassCalcDivKey(uint8_t *CSN, uint8_t *KEY, uint8_t *div_key, bool elite); -int LoadDictionaryKeyFile(char *filename, uint8_t **keys, int *keycnt); -int GenerateMacFromKeyFile(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elite, uint8_t *keys, int keycnt, iclass_premac_t *list); -int GenerateFromKeyFile(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elite, uint8_t *keys, int keycnt, iclass_prekey_t *list); +void GenerateMacFrom(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elite, uint8_t *keys, int keycnt, iclass_premac_t *list); +void GenerateMacKeyFrom(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elite, uint8_t *keys, int keycnt, iclass_prekey_t *list); void PrintPreCalcMac(uint8_t *keys, int keycnt, iclass_premac_t *pre_list); void PrintPreCalc(iclass_prekey_t *list, int itemcnt); #endif From 6e54adcb7cf1a53148816f689a70fdd0e0ec2a24 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 29 Aug 2019 09:53:28 +0200 Subject: [PATCH 0494/1854] fix: 'hw version' - identifing os on unknown.. --- client/cmdhw.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/client/cmdhw.c b/client/cmdhw.c index fe6dc2b4d..4ef55dab9 100644 --- a/client/cmdhw.c +++ b/client/cmdhw.c @@ -627,53 +627,58 @@ void pm3_version(bool verbose, bool oneliner) { #if defined(__APPLE__) || defined(__MACH__) #ifndef PM3HOSTOS -# define PM3HOSTOS "OS X" +# define PM3HOSTOS "on OS X" #endif #elif defined(_MINGW_) #ifndef PM3HOSTOS -# define PM3HOSTOS "MingW" +# define PM3HOSTOS "on MingW" #endif #elif defined(__LINUX__) #ifndef PM3HOSTOS -# define PM3HOSTOS "linux" +# define PM3HOSTOS "on linux" #endif #elif defined(__FreeBSd__) #ifndef PM3HOSTOS -# define PM3HOSTOS "FreeBSD" +# define PM3HOSTOS "on FreeBSD" #endif #elif defined(__NetBSD__) #ifndef PM3HOSTOS -# define PM3HOSTOS "NetBSD" +# define PM3HOSTOS "on NetBSD" #endif #elif defined(__OpenBSD__) #ifndef PM3HOSTOS -# define PM3HOSTOS "OpenBSD" +# define PM3HOSTOS "on OpenBSD" #endif #elif defined(_WIN32) | defined(__WIN32__) #ifndef PM3HOSTOS -# define PM3HOSTOS "Windows (32b)" +# define PM3HOSTOS "on Windows (32b)" #endif #elif defined(_WIN64) | defined(__WIN64__) #ifndef PM3HOSTOS -# define PM3HOSTOS "Windows (64b)" +# define PM3HOSTOS "on Windows (64b)" #endif #elif defined(__ANDROID__) || defined(ANDROID) #ifndef PM3HOSTOS -# define PM3HOSTOS "Android" +# define PM3HOSTOS "on Android" #endif #endif +#ifndef PM3HOSTOS +# define PM3HOSTOS "" +#endif + + if (oneliner) { - PrintAndLogEx(NORMAL, "Client: RRG/Iceman compiled with " _YELLOW_(PM3CLIENTCOMPILER __VERSION__) " on " _YELLOW_(PM3HOSTOS)); + PrintAndLogEx(NORMAL, "Client: RRG/Iceman compiled with " _YELLOW_(PM3CLIENTCOMPILER __VERSION__) " %s", _YELLOW_(PM3HOSTOS)); return; } From fcd9b42dca5fa3023ccfaa98a6f4929a8dddcd54 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 29 Aug 2019 10:07:40 +0200 Subject: [PATCH 0495/1854] reintroduce _stat on mingw, needed to strip path --- client/ui.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/client/ui.c b/client/ui.c index e6edb4369..5e33c7eaf 100644 --- a/client/ui.c +++ b/client/ui.c @@ -58,9 +58,21 @@ int searchHomeFilePath(char **foundpath, const char *filename, bool create_home) strcpy(path, user_path); strcat(path, PM3_USER_DIRECTORY); -// Mingw: _stat fails on mangled HOME path /pm3 => C:\ProxSpace\pm3, while stat works fine + int result; +#ifdef _WIN32 + struct _stat st; + // Mingw _stat fails if path ends with /, so let's use a stripped path + if (path[strlen(path)-1]=='/') { + path[strlen(path)-1]='\0'; + result = _stat(path, &st); + path[strlen(path)]='/'; + } else { + result = _stat(path, &st); + } +#else struct stat st; - int result = stat(path, &st); + result = stat(path, &st); +#endif if ((result != 0) && create_home) { #ifdef _WIN32 @@ -216,7 +228,7 @@ static void fPrintAndLog(FILE *stream, const char *fmt, ...) { timenow = gmtime(&now); strftime(filename, sizeof(filename), PROXLOG, timenow); if (searchHomeFilePath(&my_logfile_path, filename, true) != PM3_SUCCESS) { - fprintf(stderr, "Could not create $HOME/.proxmark3/%s, no log will be recorded\n", filename); + fprintf(stderr, "Could not create $HOME" PM3_USER_DIRECTORY "%s, no log will be recorded\n", filename); my_logfile_path = NULL; logging = 0; } else { @@ -224,8 +236,9 @@ static void fPrintAndLog(FILE *stream, const char *fmt, ...) { if (logfile == NULL) { fprintf(stderr, "Can't open logfile %s, logging disabled!\n", my_logfile_path); logging = 0; + } else { + printf("Session is logged into %s\n", my_logfile_path); } - printf("Session is logged into %s\n", my_logfile_path); free(my_logfile_path); } } From b10edbaddc1b0239afaabf4aabcce66510a377cc Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 29 Aug 2019 10:31:37 +0200 Subject: [PATCH 0496/1854] user dir: rework err msgs --- client/proxmark3.c | 2 +- client/ui.c | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/client/proxmark3.c b/client/proxmark3.c index 913f3735f..cb3444ad7 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -104,7 +104,7 @@ main_loop(char *script_cmds_file, char *script_cmd, bool stayInCommandLoop) { char *my_history_path = NULL; if (searchHomeFilePath(&my_history_path, PROXHISTORY, true) != PM3_SUCCESS) { - PrintAndLogEx(ERR, "could not create $HOME/" PROXHISTORY ", no history will be recorded"); + PrintAndLogEx(ERR, "No history will be recorded"); my_history_path = NULL; } else { read_history(my_history_path); diff --git a/client/ui.c b/client/ui.c index 5e33c7eaf..dfd0c2b04 100644 --- a/client/ui.c +++ b/client/ui.c @@ -50,8 +50,10 @@ int searchHomeFilePath(char **foundpath, const char *filename, bool create_home) if (foundpath == NULL) return PM3_EINVARG; char *user_path = getenv("HOME"); - if (user_path == NULL) + if (user_path == NULL) { + fprintf(stderr, "Could not retrieve $HOME from the environment\n"); return PM3_EFILE; + } char *path = calloc(strlen(user_path) + strlen(PM3_USER_DIRECTORY) + 1, sizeof(char)); if (path == NULL) return PM3_EMALLOC; @@ -80,6 +82,7 @@ int searchHomeFilePath(char **foundpath, const char *filename, bool create_home) #else if (mkdir(path, 0700)) { #endif + fprintf(stderr, "Could not create user directory %s\n", path); free(path); return PM3_EFILE; } @@ -228,7 +231,7 @@ static void fPrintAndLog(FILE *stream, const char *fmt, ...) { timenow = gmtime(&now); strftime(filename, sizeof(filename), PROXLOG, timenow); if (searchHomeFilePath(&my_logfile_path, filename, true) != PM3_SUCCESS) { - fprintf(stderr, "Could not create $HOME" PM3_USER_DIRECTORY "%s, no log will be recorded\n", filename); + fprintf(stderr, "Logging disabled!\n\n"); my_logfile_path = NULL; logging = 0; } else { From c3c5011e1dbccf3736ed0a7abd0b4a3467b102cd Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 29 Aug 2019 10:36:48 +0200 Subject: [PATCH 0497/1854] textual --- client/cmdhw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdhw.c b/client/cmdhw.c index 4ef55dab9..3817de3c8 100644 --- a/client/cmdhw.c +++ b/client/cmdhw.c @@ -694,7 +694,7 @@ void pm3_version(bool verbose, bool oneliner) { PrintAndLogEx(NORMAL, "\n" _BLUE_(" [ Proxmark3 RFID instrument ]") "\n"); PrintAndLogEx(NORMAL, "\n [ CLIENT ]"); PrintAndLogEx(NORMAL, " client: RRG/Iceman"); // TODO version info? - PrintAndLogEx(NORMAL, " compiled with " PM3CLIENTCOMPILER __VERSION__ " on " PM3HOSTOS); + PrintAndLogEx(NORMAL, " compiled with " PM3CLIENTCOMPILER __VERSION__ PM3HOSTOS); PrintAndLogEx(NORMAL, "\n [ PROXMARK RDV4 ]"); PrintAndLogEx(NORMAL, " external flash: %s", IfPm3Flash() ? _GREEN_("present") : _YELLOW_("absent")); PrintAndLogEx(NORMAL, " smartcard reader: %s", IfPm3Smartcard() ? _GREEN_("present") : _YELLOW_("absent")); From 74f96be6bebb9dc01c00343d9ce3043fc4a13542 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 29 Aug 2019 10:46:57 +0200 Subject: [PATCH 0498/1854] textual --- client/cmdhw.c | 20 ++++++++++---------- client/ui.c | 6 +++--- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/client/cmdhw.c b/client/cmdhw.c index 3817de3c8..ac7d4cbd0 100644 --- a/client/cmdhw.c +++ b/client/cmdhw.c @@ -627,47 +627,47 @@ void pm3_version(bool verbose, bool oneliner) { #if defined(__APPLE__) || defined(__MACH__) #ifndef PM3HOSTOS -# define PM3HOSTOS "on OS X" +# define PM3HOSTOS " on OS X" #endif #elif defined(_MINGW_) #ifndef PM3HOSTOS -# define PM3HOSTOS "on MingW" +# define PM3HOSTOS " on MingW" #endif #elif defined(__LINUX__) #ifndef PM3HOSTOS -# define PM3HOSTOS "on linux" +# define PM3HOSTOS " on linux" #endif #elif defined(__FreeBSd__) #ifndef PM3HOSTOS -# define PM3HOSTOS "on FreeBSD" +# define PM3HOSTOS " on FreeBSD" #endif #elif defined(__NetBSD__) #ifndef PM3HOSTOS -# define PM3HOSTOS "on NetBSD" +# define PM3HOSTOS " on NetBSD" #endif #elif defined(__OpenBSD__) #ifndef PM3HOSTOS -# define PM3HOSTOS "on OpenBSD" +# define PM3HOSTOS " on OpenBSD" #endif #elif defined(_WIN32) | defined(__WIN32__) #ifndef PM3HOSTOS -# define PM3HOSTOS "on Windows (32b)" +# define PM3HOSTOS " on Windows (32b)" #endif #elif defined(_WIN64) | defined(__WIN64__) #ifndef PM3HOSTOS -# define PM3HOSTOS "on Windows (64b)" +# define PM3HOSTOS " on Windows (64b)" #endif #elif defined(__ANDROID__) || defined(ANDROID) #ifndef PM3HOSTOS -# define PM3HOSTOS "on Android" +# define PM3HOSTOS " on Android" #endif #endif @@ -678,7 +678,7 @@ void pm3_version(bool verbose, bool oneliner) { if (oneliner) { - PrintAndLogEx(NORMAL, "Client: RRG/Iceman compiled with " _YELLOW_(PM3CLIENTCOMPILER __VERSION__) " %s", _YELLOW_(PM3HOSTOS)); + PrintAndLogEx(NORMAL, "Client: RRG/Iceman compiled with " _YELLOW_(PM3CLIENTCOMPILER __VERSION__ PM3HOSTOS)); return; } diff --git a/client/ui.c b/client/ui.c index dfd0c2b04..6f177078d 100644 --- a/client/ui.c +++ b/client/ui.c @@ -231,16 +231,16 @@ static void fPrintAndLog(FILE *stream, const char *fmt, ...) { timenow = gmtime(&now); strftime(filename, sizeof(filename), PROXLOG, timenow); if (searchHomeFilePath(&my_logfile_path, filename, true) != PM3_SUCCESS) { - fprintf(stderr, "Logging disabled!\n\n"); + fprintf(stderr, "[-] Logging disabled!\n\n"); my_logfile_path = NULL; logging = 0; } else { logfile = fopen(my_logfile_path, "a"); if (logfile == NULL) { - fprintf(stderr, "Can't open logfile %s, logging disabled!\n", my_logfile_path); + fprintf(stderr, "[-] Can't open logfile %s, logging disabled!\n", my_logfile_path); logging = 0; } else { - printf("Session is logged into %s\n", my_logfile_path); + printf("[=] Session log %s\n", my_logfile_path); } free(my_logfile_path); } From 0d6a29197b81e8568d94b8633c4b33e47022dd89 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 29 Aug 2019 11:10:54 +0200 Subject: [PATCH 0499/1854] rework OS/ARCH info --- client/cmdhw.c | 93 ++++++++++++++++++++++++-------------------------- 1 file changed, 44 insertions(+), 49 deletions(-) diff --git a/client/cmdhw.c b/client/cmdhw.c index ac7d4cbd0..c81efda9e 100644 --- a/client/cmdhw.c +++ b/client/cmdhw.c @@ -619,66 +619,61 @@ int CmdHW(const char *Cmd) { void pm3_version(bool verbose, bool oneliner) { -#if defined(__clang__) +#if defined(__MINGW64__) +# define PM3CLIENTCOMPILER "MinGW-w64 " +#elif defined(__MINGW32__) +# define PM3CLIENTCOMPILER "MinGW " +#elif defined(__clang__) # define PM3CLIENTCOMPILER "Clang/LLVM " #elif defined(__GNUC__) || defined(__GNUG__) # define PM3CLIENTCOMPILER "GCC " +#else +# define PM3CLIENTCOMPILER "unknown compiler " #endif #if defined(__APPLE__) || defined(__MACH__) -#ifndef PM3HOSTOS -# define PM3HOSTOS " on OS X" -#endif - -#elif defined(_MINGW_) -#ifndef PM3HOSTOS -# define PM3HOSTOS " on MingW" -#endif - -#elif defined(__LINUX__) -#ifndef PM3HOSTOS -# define PM3HOSTOS " on linux" -#endif - -#elif defined(__FreeBSd__) -#ifndef PM3HOSTOS -# define PM3HOSTOS " on FreeBSD" -#endif - -#elif defined(__NetBSD__) -#ifndef PM3HOSTOS -# define PM3HOSTOS " on NetBSD" -#endif - -#elif defined(__OpenBSD__) -#ifndef PM3HOSTOS -# define PM3HOSTOS " on OpenBSD" -#endif - -#elif defined(_WIN32) | defined(__WIN32__) -#ifndef PM3HOSTOS -# define PM3HOSTOS " on Windows (32b)" -#endif - -#elif defined(_WIN64) | defined(__WIN64__) -#ifndef PM3HOSTOS -# define PM3HOSTOS " on Windows (64b)" -#endif - +# define PM3HOSTOS " OS:OSX" #elif defined(__ANDROID__) || defined(ANDROID) -#ifndef PM3HOSTOS -# define PM3HOSTOS " on Android" -#endif +// must be tested before __linux__ +# define PM3HOSTOS " OS:Android" +#elif defined(__linux__) +# define PM3HOSTOS " OS:Linux" +#elif defined(__FreeBSD__) +# define PM3HOSTOS " OS:FreeBSD" +#elif defined(__NetBSD__) +# define PM3HOSTOS " OS:NetBSD" +#elif defined(__OpenBSD__) +# define PM3HOSTOS " OS:OpenBSD" +#elif defined(__CYGWIN__) +# define PM3HOSTOS " OS:Cygwin" +#elif defined(_WIN64) | defined(__WIN64__) +// must be tested before _WIN32 +# define PM3HOSTOS " OS:Windows (64b)" +#elif defined(_WIN32) | defined(__WIN32__) +# define PM3HOSTOS " OS:Windows (32b)" +#else +# define PM3HOSTOS " OS:unknown" #endif -#ifndef PM3HOSTOS -# define PM3HOSTOS "" +#if defined(__x86_64__) +# define PM3HOSTARCH " ARCH:x86_64" +#elif defined(__i386__) +# define PM3HOSTARCH " ARCH:x86" +#elif defined(__aarch64__) +# define PM3HOSTARCH " ARCH:aarch64" +#elif defined(__arm__) +# define PM3HOSTARCH " ARCH:arm" +#elif defined(__powerpc64__) +# define PM3HOSTARCH " ARCH:powerpc64" +#elif defined(__mips__) +# define PM3HOSTARCH " ARCH:mips" +#else +# define PM3HOSTARCH " ARCH:unknown" #endif - - if (oneliner) { - PrintAndLogEx(NORMAL, "Client: RRG/Iceman compiled with " _YELLOW_(PM3CLIENTCOMPILER __VERSION__ PM3HOSTOS)); + // For "proxmark3 -v", simple printf, avoid logging + printf("Client: RRG/Iceman compiled with " PM3CLIENTCOMPILER __VERSION__ PM3HOSTOS PM3HOSTARCH "\n"); return; } @@ -694,7 +689,7 @@ void pm3_version(bool verbose, bool oneliner) { PrintAndLogEx(NORMAL, "\n" _BLUE_(" [ Proxmark3 RFID instrument ]") "\n"); PrintAndLogEx(NORMAL, "\n [ CLIENT ]"); PrintAndLogEx(NORMAL, " client: RRG/Iceman"); // TODO version info? - PrintAndLogEx(NORMAL, " compiled with " PM3CLIENTCOMPILER __VERSION__ PM3HOSTOS); + PrintAndLogEx(NORMAL, " compiled with " PM3CLIENTCOMPILER __VERSION__ PM3HOSTOS PM3HOSTARCH); PrintAndLogEx(NORMAL, "\n [ PROXMARK RDV4 ]"); PrintAndLogEx(NORMAL, " external flash: %s", IfPm3Flash() ? _GREEN_("present") : _YELLOW_("absent")); PrintAndLogEx(NORMAL, " smartcard reader: %s", IfPm3Smartcard() ? _GREEN_("present") : _YELLOW_("absent")); From f0d73dc3d1907efcc6c9b39b099663aa6c2b71e0 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 29 Aug 2019 14:17:39 +0200 Subject: [PATCH 0500/1854] chg: 'hf iclass decrypt' - now takes transport key as param. also search for key / dump. Also saves decrypted to bin/eml/json_decref chg: 'hf iclass encrypt' - now takes transport key as param. --- client/cmdhficlass.c | 154 ++++++++++++++++++++----------------------- client/fileutils.c | 53 ++++++++++++++- client/fileutils.h | 16 ++++- 3 files changed, 136 insertions(+), 87 deletions(-) diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 30b2a0560..efb70c69c 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -790,75 +790,61 @@ static int CmdHFiClassELoad(const char *Cmd) { return PM3_SUCCESS; } -static int readKeyfile(const char *filename, size_t len, uint8_t **buffer) { - - char *path; - int res = searchFile(&path, PM3_USER_DIRECTORY, filename, ".bin"); - if (res != PM3_SUCCESS) { - PrintAndLogEx(INFO, "res: %d Curr path:: %s", res, path); - return PM3_EFILE; - } - - size_t datalen = 0; - res = loadFile(path, ".bin", (void*)*buffer, len, &datalen); - if ( res != PM3_SUCCESS ) - return res; - - if (datalen != len) { - PrintAndLogEx(ERR, "ERROR, Wrong filesize. Got %d bytes, expected %d", datalen, len); - return PM3_EFILE; - } - return PM3_SUCCESS; -} +#define ICLASS_DECRYPTION_BIN "iclass_decryptionkey.bin" static int CmdHFiClassDecrypt(const char *Cmd) { - - char opt = tolower(param_getchar(Cmd, 0)); - if (strlen(Cmd) < 1 || opt == 'h') return usage_hf_iclass_decrypt(); - - uint8_t key[16] = { 0 }; - uint8_t *keyptr = key; - if (readKeyfile("iclass_decryptionkey", sizeof(key), &keyptr) != PM3_SUCCESS) - return usage_hf_iclass_decrypt(); - - PrintAndLogEx(SUCCESS, "decryption key loaded from file"); - - //Open the tagdump-file - FILE *f; + + bool errors = false; + bool have_key = false; + uint8_t cmdp = 0; + + size_t keylen = 0; + uint8_t key[32] = {0}; + uint8_t *keyptr = NULL; + + size_t decryptedlen = 0; + uint8_t *decrypted = NULL; char filename[FILE_PATH_SIZE]; - if (opt == 'f' && param_getstr(Cmd, 1, filename, sizeof(filename)) > 0) { - f = fopen(filename, "rb"); - if (!f) { - PrintAndLogEx(FAILED, "File: " _YELLOW_("%s") ": not found or locked.", filename); - return PM3_EFILE; + + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { + case 'h': + return usage_hf_iclass_decrypt(); + case 'f': + if ( param_getstr(Cmd, cmdp + 1, filename, sizeof(filename) ) == 0){ + errors = true; + break; + } + + if ( loadFile_safe(filename, "", (void**)&decrypted, &decryptedlen) != PM3_SUCCESS ) { + errors = true; + break; + } + cmdp += 2; + break; + case 'k': + if (param_gethex(Cmd, cmdp + 1, key, 32)) { + PrintAndLogEx(ERR, "Transport key must include 32 HEX symbols"); + errors = true; + } + have_key = true; + cmdp += 2; + break; + default: + PrintAndLogEx(WARNING, "Unknown parameter '%c'\n", param_getchar(Cmd, cmdp)); + errors = true; + break; } - } else { - return usage_hf_iclass_decrypt(); } - fseek(f, 0, SEEK_END); - long fsize = ftell(f); - fseek(f, 0, SEEK_SET); + if (errors || cmdp < 1) return usage_hf_iclass_decrypt(); - if (fsize <= 0) { - PrintAndLogEx(ERR, "error, when getting filesize"); - fclose(f); - return 2; - } - - uint8_t *decrypted = calloc(fsize, sizeof(uint8_t)); - if (!decrypted) { - PrintAndLogEx(WARNING, "Failed to allocate memory"); - fclose(f); - return 1; - } - - size_t bytes_read = fread(decrypted, 1, fsize, f); - fclose(f); - if (bytes_read == 0) { - PrintAndLogEx(ERR, "file reading error"); - free(decrypted); - return 3; + if ( have_key == false ) { + int res = loadFile_safe(ICLASS_DECRYPTION_BIN, "", (void**)&keyptr, &keylen); + if (res != PM3_SUCCESS) + return PM3_EINVARG; + + memcpy(key, keyptr, sizeof(key)); } picopass_hdr *hdr = (picopass_hdr *)decrypted; @@ -870,13 +856,7 @@ static int CmdHFiClassDecrypt(const char *Cmd) { uint8_t app_areas = 2; uint8_t max_blk = 31; getMemConfig(mem, chip, &max_blk, &app_areas, &kb); - - //Use the first block (CSN) for filename - char outfilename[FILE_PATH_SIZE] = {0}; - snprintf(outfilename, FILE_PATH_SIZE, "iclass_tagdump-%02x%02x%02x%02x%02x%02x%02x%02x-decrypted", - hdr->csn[0], hdr->csn[1], hdr->csn[2], hdr->csn[3], - hdr->csn[4], hdr->csn[5], hdr->csn[6], hdr->csn[7]); - + // tripledes mbedtls_des3_context ctx; mbedtls_des3_set2key_dec(&ctx, key); @@ -894,12 +874,18 @@ static int CmdHFiClassDecrypt(const char *Cmd) { } } - saveFile(outfilename, ".bin", decrypted, fsize); - saveFileEML(outfilename, decrypted, fsize, 8); - saveFileJSON(outfilename, jsfIclass, decrypted, fsize); + //Use the first block (CSN) for filename + char *fptr = calloc(42, sizeof(uint8_t)); + strcat(fptr, "hf-iclass-"); + FillFileNameByUID(fptr, hdr->csn, "-data-decrypted", sizeof(hdr->csn) ); + + saveFile(fptr, ".bin", decrypted, decryptedlen); + saveFileEML(fptr, decrypted, decryptedlen, 8); + saveFileJSON(fptr, jsfIclass, decrypted, decryptedlen); - printIclassDumpContents(decrypted, 1, (fsize / 8), fsize); + printIclassDumpContents(decrypted, 1, (decryptedlen / 8), decryptedlen); free(decrypted); + free(fptr); return PM3_SUCCESS; } @@ -917,7 +903,7 @@ static int CmdHFiClassEncryptBlk(const char *Cmd) { bool have_key = false; uint8_t blk_data[8] = {0}; uint8_t key[16] = {0}; - uint8_t *keyptr = key; + uint8_t *keyptr = NULL; uint8_t cmdp = 0; while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { @@ -925,17 +911,16 @@ static int CmdHFiClassEncryptBlk(const char *Cmd) { case 'h': return usage_hf_iclass_encrypt(); case 'd': - //get the bytes to encrypt - if (param_gethex(Cmd, cmdp + 1, blk_data, 16) != PM3_SUCCESS) { + if (param_gethex(Cmd, cmdp + 1, blk_data, 16)) { PrintAndLogEx(ERR, "Block data must include 16 HEX symbols"); - errors = true;; + errors = true; } cmdp += 2; break; case 'k': - if (param_gethex(Cmd, cmdp + 1, key, 32) != PM3_SUCCESS) { + if (param_gethex(Cmd, cmdp + 1, key, 32)) { PrintAndLogEx(ERR, "Transport key must include 32 HEX symbols"); - errors = true;; + errors = true; } have_key = true; cmdp += 2; @@ -950,10 +935,12 @@ static int CmdHFiClassEncryptBlk(const char *Cmd) { if (errors || cmdp < 1) return usage_hf_iclass_encrypt(); if ( have_key == false ) { - if (readKeyfile("./iclass_decryptionkey", sizeof(key), &keyptr) != PM3_SUCCESS) { - return usage_hf_iclass_encrypt(); - } - PrintAndLogEx(SUCCESS, "Loaded transport key from decryption file"); + size_t keylen = 0; + int res = loadFile_safe(ICLASS_DECRYPTION_BIN, "", (void**)&keyptr, &keylen); + if (res != PM3_SUCCESS) + return PM3_EINVARG; + + memcpy(key, keyptr, sizeof(key)); } iClassEncryptBlkData(blk_data, key); @@ -1283,6 +1270,7 @@ static int CmdHFiClassReader_Dump(const char *Cmd) { PrintAndLogEx(SUCCESS, "saving dump file - %d blocks read", gotBytes / 8); saveFile(filename, ".bin", tag_data, gotBytes); saveFileEML(filename, tag_data, gotBytes, 8); + saveFileJSON(filename, jsfIclass, tag_data, gotBytes); return 1; } diff --git a/client/fileutils.c b/client/fileutils.c index 72771f900..1a6b40e53 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -50,7 +50,7 @@ #include "scandir.h" #endif -#define PATH_MAX_LENGTH 100 +#define PATH_MAX_LENGTH 200 /** * @brief checks if a file exists @@ -289,7 +289,7 @@ int saveFileJSON(const char *preferredName, JSONFileType ftype, uint8_t *data, s for (size_t i = 0; i < (datalen / 8); i++) { char path[PATH_MAX_LENGTH] = {0}; - sprintf(path, "$blocks.%zu", i); + sprintf(path, "$.blocks.%zu", i); JsonSaveBufAsHexCompact(root, path, data + (i * 8), 8); } break; @@ -341,6 +341,7 @@ int createMfcKeyDump(uint8_t sectorsCnt, sector_t *e_sector, char *fptr) { return PM3_SUCCESS; } + int loadFile(const char *preferredName, const char *suffix, void *data, size_t maxdatalen, size_t *datalen) { if (data == NULL) return 1; @@ -401,6 +402,54 @@ out: return retval; } +int loadFile_safe(const char *preferredName, const char *suffix, void **pdata, size_t *datalen) { + + char *path; + int res = searchFile(&path, "", preferredName, suffix); + if (res != PM3_SUCCESS) { + PrintAndLogEx(INFO, "res: %d Curr path:: %s", res, path); + return PM3_EFILE; + } + + int retval = PM3_SUCCESS; + + FILE *f = fopen(path, "rb"); + if (!f) { + PrintAndLogEx(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", path); + return PM3_EFILE; + } + + // get filesize in order to malloc memory + fseek(f, 0, SEEK_END); + long fsize = ftell(f); + fseek(f, 0, SEEK_SET); + + if (fsize <= 0) { + PrintAndLogEx(FAILED, "error, when getting filesize"); + return PM3_EFILE; + } + + *pdata = calloc(fsize, sizeof(uint8_t)); + if (!pdata) { + PrintAndLogEx(FAILED, "error, cannot allocate memory"); + return PM3_EMALLOC; + } + + size_t bytes_read = fread(*pdata, 1, fsize, f); + + fclose(f); + + if (bytes_read != fsize) { + PrintAndLogEx(FAILED, "error, bytes read mismatch file size"); + return PM3_EFILE; + } + + *datalen = bytes_read; + + PrintAndLogEx(SUCCESS, "loaded %d bytes from binary file " _YELLOW_("%s"), bytes_read, preferredName); + return retval; +} + int loadFileEML(const char *preferredName, void *data, size_t *datalen) { if (data == NULL) return 1; diff --git a/client/fileutils.h b/client/fileutils.h index 7bfc7c138..d7fdb13a3 100644 --- a/client/fileutils.h +++ b/client/fileutils.h @@ -120,7 +120,7 @@ int saveFileJSON(const char *preferredName, JSONFileType ftype, uint8_t *data, s */ int createMfcKeyDump(uint8_t sectorsCnt, sector_t *e_sector, char *fptr); -/** STUB +/** * @brief Utility function to load data from a binary file. This method takes a preferred name. * E.g. dumpdata-15.bin * @@ -129,10 +129,22 @@ int createMfcKeyDump(uint8_t sectorsCnt, sector_t *e_sector, char *fptr); * @param data The data array to store the loaded bytes from file * @param maxdatalen the number of bytes that your data array has * @param datalen the number of bytes loaded from file - * @return 0 for ok, 1 for failz + * @return PM3_SUCCESS for ok, PM3_E* for failz */ int loadFile(const char *preferredName, const char *suffix, void *data, size_t maxdatalen, size_t *datalen); + +/** + * @brief Utility function to load data from a binary file. This method takes a preferred name. + * E.g. dumpdata-15.bin, tries to search for it, and allocated memory. + * + * @param preferredName + * @param suffix the file suffix. Including the ".". + * @param data The data array to store the loaded bytes from file + * @param datalen the number of bytes loaded from file + * @return PM3_SUCCESS for ok, PM3_E* for failz +*/ +int loadFile_safe(const char *preferredName, const char *suffix, void **pdata, size_t *datalen); /** * @brief Utility function to load data from a textfile (EML). This method takes a preferred name. * E.g. dumpdata-15.txt From 00f82304e2298e2f2e742421e6893eff3e0da4e2 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 29 Aug 2019 14:33:09 +0200 Subject: [PATCH 0501/1854] chg: 'hf iclass loclass t' - now uses loadfile_safe --- client/cmdhficlass.c | 12 +++++++----- client/loclass/elite_crack.c | 35 ++++++----------------------------- 2 files changed, 13 insertions(+), 34 deletions(-) diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index efb70c69c..52c3ff21c 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -811,7 +811,8 @@ static int CmdHFiClassDecrypt(const char *Cmd) { case 'h': return usage_hf_iclass_decrypt(); case 'f': - if ( param_getstr(Cmd, cmdp + 1, filename, sizeof(filename) ) == 0){ + if ( param_getstr(Cmd, cmdp + 1, filename, sizeof(filename) ) == 0) { + PrintAndLogEx(WARNING, "no filename found after f"); errors = true; break; } @@ -1261,9 +1262,10 @@ static int CmdHFiClassReader_Dump(const char *Cmd) { printIclassDumpContents(tag_data, 1, (gotBytes / 8), gotBytes); if (filename[0] == 0) { - snprintf(filename, FILE_PATH_SIZE, "iclass_tagdump-%02x%02x%02x%02x%02x%02x%02x%02x", - tag_data[0], tag_data[1], tag_data[2], tag_data[3], - tag_data[4], tag_data[5], tag_data[6], tag_data[7]); + + //Use the first block (CSN) for filename + strcat(filename, "hf-iclass-"); + FillFileNameByUID(filename, tag_data, "-data", 8 ); } // save the dump to .bin file @@ -1271,7 +1273,7 @@ static int CmdHFiClassReader_Dump(const char *Cmd) { saveFile(filename, ".bin", tag_data, gotBytes); saveFileEML(filename, tag_data, gotBytes, 8); saveFileJSON(filename, jsfIclass, tag_data, gotBytes); - return 1; + return PM3_SUCCESS; } static int WriteBlock(uint8_t blockno, uint8_t *bldata, uint8_t *KEY, bool use_credit_key, bool elite, bool rawkey, bool verbose) { diff --git a/client/loclass/elite_crack.c b/client/loclass/elite_crack.c index adf87fb89..735e3c3df 100644 --- a/client/loclass/elite_crack.c +++ b/client/loclass/elite_crack.c @@ -540,37 +540,14 @@ int bruteforceDump(uint8_t dump[], size_t dumpsize, uint16_t keytable[]) { * @return */ int bruteforceFile(const char *filename, uint16_t keytable[]) { - FILE *f = fopen(filename, "rb"); - if (!f) { - PrintAndLogEx(WARNING, "Failed to read from file " _YELLOW_("%s"), filename); - return 1; + + size_t dumplen = 0; + uint8_t *dump = NULL; + if ( loadFile_safe(filename, "", (void**)&dump, &dumplen) != PM3_SUCCESS ) { + return PM3_EFILE; } - fseek(f, 0, SEEK_END); - long fsize = ftell(f); - fseek(f, 0, SEEK_SET); - - if (fsize <= 0) { - PrintAndLogEx(ERR, "Error, when getting filesize"); - fclose(f); - return 1; - } - - uint8_t *dump = calloc(fsize, sizeof(uint8_t)); - if (!dump) { - PrintAndLogEx(WARNING, "Failed to allocate memory"); - fclose(f); - return 2; - } - size_t bytes_read = fread(dump, 1, fsize, f); - - fclose(f); - - if (bytes_read < fsize) { - PrintAndLogEx(WARNING, "Warning: could only read %d bytes (should be %d)", bytes_read, fsize); - } - - uint8_t res = bruteforceDump(dump, fsize, keytable); + uint8_t res = bruteforceDump(dump, dumplen, keytable); free(dump); return res; } From d3124d7f4b72d64a69d5c213ebaff9e9230ecd03 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Thu, 29 Aug 2019 15:55:30 +0300 Subject: [PATCH 0502/1854] needs to off v=1 option because of too long log in appveyour --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index a0a4b18a9..b8e3636f2 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -167,7 +167,7 @@ build_script: #make - bash -c -i 'pwd;make clean;make all V=1' + bash -c -i 'pwd;make clean;make all' #some checks From f3a63767ed22d34afc6e914f9ee6e2351b93a6f1 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 29 Aug 2019 15:55:52 +0200 Subject: [PATCH 0503/1854] chg: 'hf iclass loclass t' - now uses loadfile_safe. However the iclass_key.bin and iclass_dump.bin must be in the new folder structure --- client/cmdhficlass.c | 4 +-- client/loclass/elite_crack.c | 47 +++++++++++++++--------------------- client/loclass/ikeys.c | 38 ++++++++++------------------- 3 files changed, 34 insertions(+), 55 deletions(-) diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 52c3ff21c..bd937fe17 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -1662,7 +1662,7 @@ static int CmdHFiClass_loclass(const char *Cmd) { errors += doKeyTests(0); errors += testElite(); if (errors) PrintAndLogEx(ERR, "There were errors!!!"); - return errors; + return PM3_ESOFT; } return PM3_SUCCESS; } @@ -1971,7 +1971,7 @@ static int CmdHFiClassManageKeys(const char *Cmd) { case 'n': keyNbr = param_get8(Cmd, cmdp + 1); if (keyNbr >= ICLASS_KEYS_MAX) { - PrintAndLogEx(ERR, "Invalid block number, MAX is "_YELLOW_("%d"), ICLASS_KEYS_MAX); + PrintAndLogEx(ERR, "Invalid block number, MAX is " _YELLOW_("%d"), ICLASS_KEYS_MAX); errors = true; } cmdp += 2; diff --git a/client/loclass/elite_crack.c b/client/loclass/elite_crack.c index 735e3c3df..bc474fc21 100644 --- a/client/loclass/elite_crack.c +++ b/client/loclass/elite_crack.c @@ -569,39 +569,30 @@ int bruteforceFileNoKeys(const char *filename) { // TEST CODE BELOW // ---------------------------------------------------------------------------- static int _testBruteforce() { - int errors = 0; - if (true) { - // First test - PrintAndLogEx(INFO, "Testing crack from dumpfile..."); - /** - Expected values for the dumpfile: - High Security Key Table + PrintAndLogEx(INFO, "Testing crack from dumpfile..."); - 00 F1 35 59 A1 0D 5A 26 7F 18 60 0B 96 8A C0 25 C1 - 10 BF A1 3B B0 FF 85 28 75 F2 1F C6 8F 0E 74 8F 21 - 20 14 7A 55 16 C8 A9 7D B3 13 0C 5D C9 31 8D A9 B2 - 30 A3 56 83 0F 55 7E DE 45 71 21 D2 6D C1 57 1C 9C - 40 78 2F 64 51 42 7B 64 30 FA 26 51 76 D3 E0 FB B6 - 50 31 9F BF 2F 7E 4F 94 B4 BD 4F 75 91 E3 1B EB 42 - 60 3F 88 6F B8 6C 2C 93 0D 69 2C D5 20 3C C1 61 95 - 70 43 08 A0 2F FE B3 26 D7 98 0B 34 7B 47 70 A0 AB + /** + Expected values for the dumpfile: + High Security Key Table - **** The 64-bit HS Custom Key Value = 5B7C62C491C11B39 **** - **/ - uint16_t keytable[128] = {0}; + 00 F1 35 59 A1 0D 5A 26 7F 18 60 0B 96 8A C0 25 C1 + 10 BF A1 3B B0 FF 85 28 75 F2 1F C6 8F 0E 74 8F 21 + 20 14 7A 55 16 C8 A9 7D B3 13 0C 5D C9 31 8D A9 B2 + 30 A3 56 83 0F 55 7E DE 45 71 21 D2 6D C1 57 1C 9C + 40 78 2F 64 51 42 7B 64 30 FA 26 51 76 D3 E0 FB B6 + 50 31 9F BF 2F 7E 4F 94 B4 BD 4F 75 91 E3 1B EB 42 + 60 3F 88 6F B8 6C 2C 93 0D 69 2C D5 20 3C C1 61 95 + 70 43 08 A0 2F FE B3 26 D7 98 0B 34 7B 47 70 A0 AB - //Test a few variants - if (fileExists("iclass_dump.bin")) { - errors |= bruteforceFile("iclass_dump.bin", keytable); - } else if (fileExists("loclass/iclass_dump.bin")) { - errors |= bruteforceFile("loclass/iclass_dump.bin", keytable); - } else if (fileExists("client/loclass/iclass_dump.bin")) { - errors |= bruteforceFile("client/loclass/iclass_dump.bin", keytable); - } else { - PrintAndLogEx(ERR, "Error: The file " _YELLOW_("iclass_dump.bin") "was not found!"); - } + **** The 64-bit HS Custom Key Value = 5B7C62C491C11B39 **** + **/ + uint16_t keytable[128] = {0}; + int errors = bruteforceFile("iclass_dump.bin", keytable); + if (errors) { + PrintAndLogEx(ERR, "Error: The file " _YELLOW_("iclass_dump.bin") "was not found!"); } + return errors; } diff --git a/client/loclass/ikeys.c b/client/loclass/ikeys.c index 53f7848de..f53f80221 100644 --- a/client/loclass/ikeys.c +++ b/client/loclass/ikeys.c @@ -654,33 +654,21 @@ static int doTestsWithKnownInputs() { return errors; } -static bool readKeyFile(uint8_t key[8]) { - bool retval = false; - //Test a few variants - char filename[30] = {0}; +static bool readKeyFile(uint8_t* key, size_t keylen) { - if (fileExists("iclass_key.bin")) { - sprintf(filename, "%s.bin", "iclass_key"); - } else if (fileExists("loclass/iclass_key.bin")) { - sprintf(filename, "%s.bin", "loclass/iclass_key"); - } else if (fileExists("client/loclass/iclass_key.bin")) { - sprintf(filename, "%s.bin", "client/loclass/iclass_key"); + size_t len = 0; + uint8_t *keyptr = NULL; + if ( loadFile_safe("iclass_key.bin", "", (void**)&keyptr, &len) != PM3_SUCCESS ) { + return false; } - - if (strlen(filename) == 0) - return retval; - - FILE *f = fopen(filename, "rb"); - if (!f) - return retval; - - size_t bytes_read = fread(key, sizeof(uint8_t), 8, f); - if (bytes_read == 8) - retval = true; - - fclose(f); - return retval; + + if ( keylen != len ) { + return false; + } + + memcpy(key, keyptr, keylen ); + return true; } int doKeyTests(uint8_t debuglevel) { @@ -688,7 +676,7 @@ int doKeyTests(uint8_t debuglevel) { PrintAndLogEx(INFO, "Checking if the master key is present (iclass_key.bin)..."); uint8_t key[8] = {0}; - if (!readKeyFile(key)) { + if (readKeyFile(key, sizeof(key)) == false) { PrintAndLogEx(FAILED, "Master key not present, will not be able to do all testcases"); } else { From 6529c9616fbb238feb2513eae817c747501d5507 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 29 Aug 2019 16:56:22 +0200 Subject: [PATCH 0504/1854] chg: remove termcap and use pkg-config for ncurses (@ZeroChaos-) --- client/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/Makefile b/client/Makefile index fc7fa520b..1ca87678a 100644 --- a/client/Makefile +++ b/client/Makefile @@ -90,7 +90,7 @@ else LIBS := -I/usr/local/opt/readline/include $(LIBS) else LUALIB += -ldl - LDLIBS += -ltermcap -lncurses + LDLIBS += $(shell pkg-config --libs ncurses 2>/dev/null) LUAPLATFORM = linux endif endif From 420ef35c5c07b9f522d83968ad6884960805d473 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 29 Aug 2019 17:01:33 +0200 Subject: [PATCH 0505/1854] textual --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f7dc5d6a9..999d08676 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,10 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Chg remove deprecated termcap, use ncurses instead (@ZeroChaos-) + - Chg 'hf iclass encrypt' - now takes transport key as param. (@iceman1001) + - Chg 'hf iclass decrypt' - now takes transport key as param. (@iceman1001) + - Chg 'hf mf fchk m' - now secretly dumps card to emul, if all keys are found (@iceman1001) - Chg history and logfile are now saved into $HOME/.proxmark3/ (@doegox) - Chg optimization of iclass mac calculations on deviceside (@pwpiwi) - Add 'hf mf autopwn' - Autopwn function for Mifare Classic, extract all keys and dump card memory (@matthiaskonrath) From 0a81a72758785bd1698f5bfc968f7bda8e42c680 Mon Sep 17 00:00:00 2001 From: Oleg Moiseenko <807634+merlokk@users.noreply.github.com> Date: Thu, 29 Aug 2019 19:21:51 +0300 Subject: [PATCH 0506/1854] appveyour next fix (#373) --- appveyor.yml | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index b8e3636f2..b77cef02d 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -73,12 +73,13 @@ clone_script: Write-Host "[ OK ]" -ForegroundColor Green - Write-Host "Update msys2 packages..." -NoNewLine + Write-Host "Update msys2 packages..." $env:Path = "C:\ProxSpace\msys2\usr\bin;C:\ProxSpace\msys2\mingw32\bin;C:\ProxSpace\gcc-arm-none-eabi\bin;$env:Path" Function ExecUpdate($Name, $Cmd, $ErrorLine) { + Write-Host "Exec [$Name]... " -NoNewLine #--- begin Job $Job = Start-Job -Name "$Name" -ScriptBlock { @@ -96,10 +97,16 @@ clone_script: $JobTime=[System.Environment]::TickCount while($true) { - Receive-Job -Job $Job -Keep -OutVariable Res 2>&1 6>&1 | Out-Null + Try { + $Res = Receive-Job -Job $Job -Keep 2>&1 6>&1 + } + Catch { + $Res = "" + Write-host "error in Receive-Job" + } if ($Res -is "String" -and $Res -like "*$ErrorLine*"){ - Write-host "Exit by stop phrase" + Write-host "Exit by stop phrase" -ForegroundColor Green break } @@ -107,7 +114,7 @@ clone_script: [bool]$needexit = $false ForEach($line in $Res){ if ($line -like "*$ErrorLine*"){ - Write-host "Exit by stop phrase [obj]" + Write-host "Exit by stop phrase [obj]" -ForegroundColor Green $needexit = $true break } @@ -118,12 +125,12 @@ clone_script: } if(Wait-Job $Job -Timeout 5){ - Write-host "Exit by end job" + Write-host "Exit by end job" -ForegroundColor Green break } - if ([System.Environment]::TickCount-$JobTime -gt 600000) { - Write-host "Exit by timeout" + if ([System.Environment]::TickCount-$JobTime -gt 1000000) { + Write-host "Exit by timeout" -ForegroundColor Yellow break } } @@ -135,6 +142,7 @@ clone_script: ExecUpdate "update2" "C:\ProxSpace\msys2\msys2_shell.cmd -mingw32 -defterm -no-start /dev/null" "terminate?MSYS2" + Write-Host "Update " -NoNewLine Write-Host "[ OK ]" -ForegroundColor Green install: - ps: >- @@ -341,6 +349,7 @@ test_script: Remove-Job -Force $Job if(!$res){ + Write-host "--------------------- tests fail" -ForegroundColor Red $global:TestsPassed=$false } } @@ -364,11 +373,11 @@ test_script: #proxmark logic tests - ExecTest "proxmark help" "proxmark3 -h" {bash -lc 'cd ~/client;./proxmark3 -h | grep -q wait && echo Passed || echo Failed'} + ExecTest "proxmark help" "proxmark3 -h" {bash -lc 'cd ~/client;./proxmark3 -h | grep -q wait && echo passed || echo failed'} - ExecTest "proxmark help text ISO7816" "proxmark3 -t" {bash -lc 'cd ~/client;./proxmark3 -t 2>&1 | grep -q ISO7816 && echo Passed || echo Failed'} + ExecTest "proxmark help text ISO7816" "proxmark3 -t" {bash -lc 'cd ~/client;./proxmark3 -t | grep -q ISO7816 && echo passed || echo failed'} - ExecTest "proxmark help text hardnested" "proxmark3 -t" {bash -lc 'cd ~/client;./proxmark3 -t 2>&1 | grep -q hardnested && echo Passed || echo Failed'} + ExecTest "proxmark help text hardnested" "proxmark3 -t" {bash -lc 'cd ~/client;./proxmark3 -t | grep -q hardnested && echo passed || echo failed'} ExecTest "hf mf offline text" "hf mf" {bash -lc "cd ~/client;./proxmark3 -c 'hf mf'"} "at_enc" From 73cefedd61736a117a8fcf8d4f4cff96bd712580 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 29 Aug 2019 18:22:00 +0200 Subject: [PATCH 0507/1854] remove entirely ncurses, not needed nowadays --- CHANGELOG.md | 1 + COMPILING.txt | 4 +++- client/Makefile | 1 - .../Linux-Installation-Instructions.md | 8 ++------ .../Windows-Installation-Instructions.md | 2 +- 5 files changed, 7 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 999d08676..9a3df33cc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Chg remove entirely ncurses, not needed nowadays (@doegox) - Chg remove deprecated termcap, use ncurses instead (@ZeroChaos-) - Chg 'hf iclass encrypt' - now takes transport key as param. (@iceman1001) - Chg 'hf iclass decrypt' - now takes transport key as param. (@iceman1001) diff --git a/COMPILING.txt b/COMPILING.txt index 04ff1d8bf..b1f5cb960 100644 --- a/COMPILING.txt +++ b/COMPILING.txt @@ -1,3 +1,6 @@ + +** BEWARE the instructions here might be outdated, better refer to doc/md/Installation_Instructions/ ** + The project compiles on Linux, Mac OS X and Windows (MinGW/MSYS). it requires: @@ -7,7 +10,6 @@ it requires: - libusb - perl - an ARM cross-compiler to compile the firmware -- libncurses5-dev and optionally QT for the GUI diff --git a/client/Makefile b/client/Makefile index 1ca87678a..ccf7d5ab8 100644 --- a/client/Makefile +++ b/client/Makefile @@ -90,7 +90,6 @@ else LIBS := -I/usr/local/opt/readline/include $(LIBS) else LUALIB += -ldl - LDLIBS += $(shell pkg-config --libs ncurses 2>/dev/null) LUAPLATFORM = linux endif endif diff --git a/doc/md/Installation_Instructions/Linux-Installation-Instructions.md b/doc/md/Installation_Instructions/Linux-Installation-Instructions.md index fe23db001..476309fb6 100644 --- a/doc/md/Installation_Instructions/Linux-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Linux-Installation-Instructions.md @@ -25,7 +25,7 @@ Install the requirements ```sh sudo apt-get install p7zip git ca-certificates build-essential libreadline5 libreadline-dev \ -libusb-0.1-4 libusb-dev perl pkg-config wget libncurses5-dev gcc-arm-none-eabi libnewlib-dev libqt4-dev +libusb-0.1-4 libusb-dev perl pkg-config wget gcc-arm-none-eabi libnewlib-dev libqt4-dev ``` If you don't need the graphical components of the Proxmark3 client, you can skip the installation of `libqt4-dev`. @@ -35,11 +35,7 @@ If you get some (non blocking) error at runtime such as _Gtk-Message: Failed to ## On ArchLinux ```sh -sudo pacman -Sy base-devel p7zip libusb readline ncurses arm-none-eabi-gcc arm-none-eabi-newlib git --needed -``` -Additional AUR packages: -```sh -yaourt -S termcap +sudo pacman -Sy base-devel p7zip libusb readline arm-none-eabi-gcc arm-none-eabi-newlib git --needed ``` If you want graphical output (such as in `hw tune`): ```sh diff --git a/doc/md/Installation_Instructions/Windows-Installation-Instructions.md b/doc/md/Installation_Instructions/Windows-Installation-Instructions.md index db9a9084f..e2895f73a 100644 --- a/doc/md/Installation_Instructions/Windows-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Windows-Installation-Instructions.md @@ -99,7 +99,7 @@ Enter WSL prompt (`wsl`) and from there, follow the [Linux Installation Instruct ```sh sudo apt-get update sudo apt-get install p7zip git ca-certificates build-essential libreadline5 libreadline-dev libusb-0.1-4 \ -libusb-dev perl pkg-config wget libncurses5-dev gcc-arm-none-eabi libstdc++-arm-none-eabi-newlib \ +libusb-dev perl pkg-config wget gcc-arm-none-eabi libstdc++-arm-none-eabi-newlib \ libqt4-dev ``` From e6f2644c1be504c312fdb1d366fe2ecf66c60770 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 29 Aug 2019 18:53:54 +0200 Subject: [PATCH 0508/1854] remove srecswap.pl, never seen modern jtag requiring it --- tools/srecswap.pl | 35 ----------------------------------- 1 file changed, 35 deletions(-) delete mode 100644 tools/srecswap.pl diff --git a/tools/srecswap.pl b/tools/srecswap.pl deleted file mode 100644 index 47db8e687..000000000 --- a/tools/srecswap.pl +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/perl - -# endian-swap S records; we need this because the JTAG tools we're using -# expect the memory image in byte-swapped format -# -# Jonathan Westhues, April 2004 - -if(@ARGV == 0) { - die "usage: $0 file-to-endian-swap.s19 > out.s19\n"; -} - -while(<>) { - chomp; - - if(/^S0/) { - next; - } - if(/^S7/) { - print "$_\n"; - next; - } - - if(not /^S3(..)(........)(.*)(..)$/) { - die "bad S record at line $.\n"; - } - - $data = $3; - $checksum = $4; - - print "S3$1$2"; - while($data =~ m#(..)(..)(..)(..)#g) { - print "$4$3$2$1"; - } - print "$checksum\n"; -} From 04f3cbe58c77cf7ba68cd05bdd2c9fbe1eaa5b6e Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 29 Aug 2019 19:06:11 +0200 Subject: [PATCH 0509/1854] Update COMPILING.txt to point to the docs, update some instructions --- COMPILING.txt | 133 +----------------- ...OS-X-Homebrew-Installation-Instructions.md | 4 +- .../Windows-Installation-Instructions.md | 2 +- 3 files changed, 5 insertions(+), 134 deletions(-) diff --git a/COMPILING.txt b/COMPILING.txt index b1f5cb960..58ee40c08 100644 --- a/COMPILING.txt +++ b/COMPILING.txt @@ -1,133 +1,2 @@ -** BEWARE the instructions here might be outdated, better refer to doc/md/Installation_Instructions/ ** - -The project compiles on Linux, Mac OS X and Windows (MinGW/MSYS). - -it requires: -- gcc >= 4.8 -- libpthread -- libreadline -- libusb -- perl -- an ARM cross-compiler to compile the firmware - -and optionally QT for the GUI - - -To compile, just run "make". - -=========== -= Windows = -=========== - -Rather than download and install every one of these packages, a new ProxSpace -environment archive file will be made available for download on the project -page at @Gator96100's repo - -Afterwards just clone the iceman repo or download someone elses. Read instructions on @Gator96100 repo page. (https://github.com/Gator96100/ProxSpace/) - -Download the ProxSpace environment archive and extract it to C:\ - -Links - https://github.com/Gator96100/ProxSpace/archive/master.zip - - -============ -= Mac OS X = -============ - -Installing from HomeBrew tap ---------------------------- -This method is recommended and tested on macOS Sierra 10.12.3 - -1. Install homebrew if you haven't yet already done so: http://brew.sh/ - -2. Tap proxmark repo: - brew tap iceman1001/proxmark3 - -3. Install Proxmark3: - -Stable release - brew install proxmark3 - -Latest non-stable from GitHub (use this if previous command fails) - brew install --HEAD proxmark3 - -For more information go to https://github.com/iceman1001/homebrew-proxmark3 - -Upgrading HomeBrew tap formula ------------------------------ -*This method is useful for those looking to run bleeding-edge versions of iceman's client. Keep this in mind when attempting to update your HomeBrew tap formula as this procedure could easily cause a build to break if an update is unstable on macOS.* - -Tested on macOS Sierra 10.12.6 - -*Note: This assumes you have already installed iceman's fork from HomeBrew as mentioned above* - -1. Force HomeBrew to pull the latest source from github -`brew upgrade --fetch-HEAD iceman1001/proxmark3/proxmark3` - -2. Flash the bootloader - * With your Proxmark3 unplugged from your machine, press and hold the button on your Proxmark 3 as you plug it into a USB port. After about 5 seconds let go of the button and run this command - `$ sudo proxmark3-flasher /dev/tty.usbmodem881 /usr/local/Cellar/proxmark3/HEAD-ccfdd60/share/firmware/fullimage.elf` - * After the bootloader finishes flashing, unplug your Proxmark3 from your machine - -3. Flash fullimage.elf - * Press and hold the button on your Proxmark 3 and keep it held as you plug the Proxmark 3 back into the USB port; continue to hold the button until after this step is complete and the `proxmark3-flasher` command outputs "Have a nice day!"* - -`$ sudo proxmark3-flasher /dev/tty.usbmodem881 /usr/local/Cellar/proxmark3/HEAD-ccfdd60/share/firmware/fullimage.elf` - -4. Enjoy the update - -Compilling from source manually (Legacy) ---------------------------- - -Tested on OSX 10.10 Yosemite - -1 - Install Xcode and Xcode Command Line Tools - -2 - Install Homebrew and dependencies - brew install readline libusb p7zip libusb-compat wget qt5 pkgconfig - -3 - Download DevKitARM for OSX - http://sourceforge.net/projects/devkitpro/files/devkitARM/devkitARM_r44/ - Unpack devkitARM_r44-osx.tar.bz2 to proxmark3 directory. - -4 - Edit proxmark3/client/Makefile adding path to readline and qt5 - - LDLIBS = -L/usr/local/opt/readline/lib -L/usr/local/opt/qt5/lib -L/opt/local/lib -L/usr/local/lib ../liblua/liblua.a -lreadline -lpthread -lm - CFLAGS = -std=c99 -I/usr/local/opt/qt5/include -I/usr/local/opt/readline/include -I. -I../include -I../common -I../zlib -I/opt/local/include -I../liblua -Wall $(COMMON_FLAGS) -g -O4 - - If your old brew intallation use /usr/local/Cellar/ path replace /usr/local/opt/readline/lib with your actuall readline and qt5 path. See homebrew manuals. - -5 - Set Environment - - export DEVKITPRO=$HOME/proxmark3/ - export DEVKITARM=$DEVKITPRO/devkitARM - export PATH=${PATH}:${DEVKITARM}/bin - - -============ -= Linux = -============ - -1 - Download - -A precompiled DevKitARM cross compiler tool chain package can be found at -http://sourceforge.net/projects/devkitpro/files/devkitARM -Select the one you need (32bit or 64bit) and unpack to a convinient place, eg -$HOME/proxmark3/. It will create a devkitARM/ subdirectory. - -You will also need a general compiling environment on your computer for -the client and the libusb headers. In most distributions you will get all you -need with the lsb-package (Linux Standard Base). In debian/ubuntu you simply -call `aptitude install lsb libusb-dev libreadline-dev libreadline6`. - -For the graphical plot view, you might need the qtlibs (debian/ubuntu: -libqt4-dev), too. - -2 - Set Environment - -export DEVKITPRO=$HOME/proxmark3/ -export DEVKITARM=$DEVKITPRO/devkitARM -export PATH=${PATH}:${DEVKITARM}/bin - +Refer to doc/md/Installation_Instructions/ for up-to-date intructions for various platforms. diff --git a/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md b/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md index fd336104d..f38d2056c 100644 --- a/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md @@ -11,6 +11,8 @@ For further questions about Mac & Homebrew, contact @Chrisfu (https://github.c 3. Install Proxmark3: `brew install proxmark3` for stable release or `brew install --HEAD proxmark3` for latest non-stable from GitHub. +For more info, go to https://github.com/RfidResearchGroup/homebrew-proxmark3 + ## Upgrade HomeBrew tap formula *This method is useful for those looking to run bleeding-edge versions of RRG/iceman's client. Keep this in mind when attempting to update your HomeBrew tap formula as this procedure could easily cause a build to break if an update is unstable on macOS.* @@ -64,7 +66,7 @@ These instructions will show how to setup the environment on OSX to the point wh 2. Install dependencies: ``` -brew install readline p7zip libusb-compat perl qt5 wget +brew install readline p7zip libusb-compat perl qt5 wget pkgconfig brew install RfidResearchGroup/proxmark3/arm-none-eabi-gcc ``` diff --git a/doc/md/Installation_Instructions/Windows-Installation-Instructions.md b/doc/md/Installation_Instructions/Windows-Installation-Instructions.md index e2895f73a..631b864c1 100644 --- a/doc/md/Installation_Instructions/Windows-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Windows-Installation-Instructions.md @@ -19,7 +19,7 @@ Step by step guides are online such as [RiscCorps](https://store.ryscc.com/blogs ## Download / clone ProxSpace repo -Download the Gator96100 ProxSpace package from https://github.com/Gator96100/ProxSpace/ +Download the Gator96100 ProxSpace package from https://github.com/Gator96100/ProxSpace/releases If you prefer, you can clone it, provided that you installed Github for Windows https://desktop.github.com/. From 3408d75ac90f9af3e8cf45558cb39369dc4db31f Mon Sep 17 00:00:00 2001 From: Iceman Date: Thu, 29 Aug 2019 21:25:06 +0200 Subject: [PATCH 0510/1854] Update Makefile.hal fix https://github.com/RfidResearchGroup/proxmark3/issues/375 --- armsrc/Standalone/Makefile.hal | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/Standalone/Makefile.hal b/armsrc/Standalone/Makefile.hal index 5d3904794..f082dd117 100644 --- a/armsrc/Standalone/Makefile.hal +++ b/armsrc/Standalone/Makefile.hal @@ -1,6 +1,6 @@ # Default standalone if no standalone specified DEFAULT_STANDALONE=LF_SAMYRUN -HELP_EXAMPLE_STANDALONE=HF_COLIN +HELP_EXAMPLE_STANDALONE=HF_YOUNG # (you can set explicitly STANDALONE= to disable standalone modes) STANDALONE?=$(DEFAULT_STANDALONE) STANDALONE_REQ_DEFS= From 4d073ae19d703116f3ff5007c101c8c4c9e608c8 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 29 Aug 2019 21:49:54 +0200 Subject: [PATCH 0511/1854] mv iclass_dump.bin one folder up --- client/{loclass => }/iclass_dump.bin | Bin 1 file changed, 0 insertions(+), 0 deletions(-) rename client/{loclass => }/iclass_dump.bin (100%) diff --git a/client/loclass/iclass_dump.bin b/client/iclass_dump.bin similarity index 100% rename from client/loclass/iclass_dump.bin rename to client/iclass_dump.bin From 0d986ab212ede35caf0b7a21da3afd4ac30064fa Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 29 Aug 2019 21:57:01 +0200 Subject: [PATCH 0512/1854] Delete unused hash files --- tools/simmodule/SIM010.md5.txt | 1 - tools/simmodule/SIM011.md5.txt | 1 - 2 files changed, 2 deletions(-) delete mode 100644 tools/simmodule/SIM010.md5.txt delete mode 100644 tools/simmodule/SIM011.md5.txt diff --git a/tools/simmodule/SIM010.md5.txt b/tools/simmodule/SIM010.md5.txt deleted file mode 100644 index c790101f7..000000000 --- a/tools/simmodule/SIM010.md5.txt +++ /dev/null @@ -1 +0,0 @@ -136e157364609e5c395540dc8dadbfd6 *SIM010.BIN diff --git a/tools/simmodule/SIM011.md5.txt b/tools/simmodule/SIM011.md5.txt deleted file mode 100644 index 2a564eeb6..000000000 --- a/tools/simmodule/SIM011.md5.txt +++ /dev/null @@ -1 +0,0 @@ -e0be612fd3e68681ef0ee4706b4f28e2 *SIM011.BIN From 8987e956acb59fe07848931182be0f37a5d2103b Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 29 Aug 2019 20:58:36 +0200 Subject: [PATCH 0513/1854] POSIX sh version of mkversion Most targeted platforms have "sh" and don't need Perl as requirement. Still Perl script is present as fallback. --- CHANGELOG.md | 1 + armsrc/Makefile | 2 +- bootrom/Makefile | 2 +- common_arm/default_version.c | 2 +- .../Linux-Installation-Instructions.md | 2 +- ...OS-X-Homebrew-Installation-Instructions.md | 2 +- .../Windows-Installation-Instructions.md | 2 +- tools/mkversion.sh | 60 +++++++++++++++++++ 8 files changed, 67 insertions(+), 6 deletions(-) create mode 100755 tools/mkversion.sh diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a3df33cc..6fcbc68d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Chg posix sh version of mkversion (@doegox) - Chg remove entirely ncurses, not needed nowadays (@doegox) - Chg remove deprecated termcap, use ncurses instead (@ZeroChaos-) - Chg 'hf iclass encrypt' - now takes transport key as param. (@iceman1001) diff --git a/armsrc/Makefile b/armsrc/Makefile index 665c91005..048879d96 100644 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@ -144,7 +144,7 @@ all: $(OBJS) # version.c should be remade on every time fullimage.stage1.elf should be remade version.c: default_version.c $(OBJDIR)/fpga_version_info.o $(OBJDIR)/fpga_all.o $(THUMBOBJ) $(ARMOBJ) $(info [-] GEN $@) - $(Q)perl ../tools/mkversion.pl .. > $@ || $(COPY) $^ $@ + $(Q)sh ../tools/mkversion.sh > $@ || perl ../tools/mkversion.pl > $@ || $(COPY) $^ $@ fpga_version_info.c: $(FPGA_BITSTREAMS) | $(FPGA_COMPRESSOR) $(info [-] GEN $@) diff --git a/bootrom/Makefile b/bootrom/Makefile index c4103b522..884f01757 100644 --- a/bootrom/Makefile +++ b/bootrom/Makefile @@ -36,7 +36,7 @@ OBJS = $(OBJDIR)/bootrom.s19 # version.c should be remade on every compilation version.c: default_version.c $(info [=] GEN $@) - $(Q)perl ../tools/mkversion.pl .. > $@ || $(COPY) $^ $@ + $(Q)sh ../tools/mkversion.sh > $@ || perl ../tools/mkversion.pl > $@ || $(COPY) $^ $@ all: $(OBJS) diff --git a/common_arm/default_version.c b/common_arm/default_version.c index e1e5dc64c..b4b8ae17d 100644 --- a/common_arm/default_version.c +++ b/common_arm/default_version.c @@ -1,5 +1,5 @@ #include "proxmark3_arm.h" -/* This is the default version.c file that Makefile.common falls back to if perl is not available */ +/* This is the default version.c file that Makefile.common falls back to if neither sh nor perl are available */ const struct version_information __attribute__((section(".version_information"))) version_information = { VERSION_INFORMATION_MAGIC, 1, /* version 1 */ diff --git a/doc/md/Installation_Instructions/Linux-Installation-Instructions.md b/doc/md/Installation_Instructions/Linux-Installation-Instructions.md index 476309fb6..aa3ce9272 100644 --- a/doc/md/Installation_Instructions/Linux-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Linux-Installation-Instructions.md @@ -25,7 +25,7 @@ Install the requirements ```sh sudo apt-get install p7zip git ca-certificates build-essential libreadline5 libreadline-dev \ -libusb-0.1-4 libusb-dev perl pkg-config wget gcc-arm-none-eabi libnewlib-dev libqt4-dev +libusb-0.1-4 libusb-dev pkg-config wget gcc-arm-none-eabi libnewlib-dev libqt4-dev ``` If you don't need the graphical components of the Proxmark3 client, you can skip the installation of `libqt4-dev`. diff --git a/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md b/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md index f38d2056c..f2d87aa66 100644 --- a/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md @@ -66,7 +66,7 @@ These instructions will show how to setup the environment on OSX to the point wh 2. Install dependencies: ``` -brew install readline p7zip libusb-compat perl qt5 wget pkgconfig +brew install readline p7zip libusb-compat qt5 wget pkgconfig brew install RfidResearchGroup/proxmark3/arm-none-eabi-gcc ``` diff --git a/doc/md/Installation_Instructions/Windows-Installation-Instructions.md b/doc/md/Installation_Instructions/Windows-Installation-Instructions.md index 631b864c1..1df9e541b 100644 --- a/doc/md/Installation_Instructions/Windows-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Windows-Installation-Instructions.md @@ -99,7 +99,7 @@ Enter WSL prompt (`wsl`) and from there, follow the [Linux Installation Instruct ```sh sudo apt-get update sudo apt-get install p7zip git ca-certificates build-essential libreadline5 libreadline-dev libusb-0.1-4 \ -libusb-dev perl pkg-config wget gcc-arm-none-eabi libstdc++-arm-none-eabi-newlib \ +libusb-dev pkg-config wget gcc-arm-none-eabi libstdc++-arm-none-eabi-newlib \ libqt4-dev ``` diff --git a/tools/mkversion.sh b/tools/mkversion.sh new file mode 100755 index 000000000..b91eab8af --- /dev/null +++ b/tools/mkversion.sh @@ -0,0 +1,60 @@ +#!/bin/sh + +# Output a version.c file that includes information about the current build +# From mkversion.pl +# pure sh POSIX as now even on Windows we use WSL or ProxSpace with sh available + +# Clear environment locale so that git will not use localized strings +export LC_ALL="C" +export LANG="C" + +# if you are making your own fork, change this line to reflect your fork-name +fullgitinfo="RRG/Iceman" +# GIT status 0 = dirty, 1 = clean , 2 = undecided +clean=2 + +# Do we have acces to git command? +commandGIT=$(env which git) + +if [ "$commandGIT" != "" ]; then + + # now avoiding the "fatal: No names found, cannot describe anything." error by fallbacking to abbrev hash in such case + gitversion=$(git describe --dirty --always) + gitbranch=$(git rev-parse --abbrev-ref HEAD) + if [ "$gitversion" != "${gitversion%-dirty}" ]; then + clean=0 + else + clean=1 + fi + if [ "$gitbranch" != "" ] && [ "$gitversion" != "" ]; then + fullgitinfo="${fullgitinfo}/${gitbranch}/${gitversion}" + ctime="$(date '+%Y-%m-%d %H:%M:%S')" + else + fullgitinfo="${fullgitinfo}/master/release (git)" + fi +else + fullgitinfo="${fullgitinfo}/master/release (no_git)" + dl_time=$(stat --printf="%y" ../README.md) + # POSIX way... + ctime=${dl_time%.*} +fi + +# Crop so it fits within 50 characters C string, so max 49 chars +# POSIX way +fullgitinfoextra="${fullgitinfo#??????????????????????????????????????????????}" +if [ "$fullgitinfoextra" != "$fullgitinfo" ]; then + fullgitinfo46="${fullgitinfo%"${fullgitinfoextra}"}" + fullgitinfo="${fullgitinfo46}..." +fi +cat < Date: Thu, 29 Aug 2019 23:43:48 +0200 Subject: [PATCH 0514/1854] migrate simmodule/readme.txt content to 2_Configuration-and-Verification.md --- .../2_Configuration-and-Verification.md | 20 +++++++++++- tools/simmodule/readme.txt | 32 ------------------- 2 files changed, 19 insertions(+), 33 deletions(-) delete mode 100644 tools/simmodule/readme.txt diff --git a/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md b/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md index 8b5244cf6..503c4b988 100644 --- a/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md +++ b/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md @@ -30,8 +30,20 @@ Find version in the long output, look for these two lines #db# version.................v2.06 ``` -This version is obsolete. The following command upgrades your device sim module firmware. +This version is obsolete. + +If you didn't download SIM011.bin from the RRG Repo be aware that it might be corrupted or faulty. +You find a hash text file in this folder. It was generated with the following linux command. + +``` +sha512sum -b SIM011.bin > SIM011.sha512.txt +``` + +You should validate the SIM011.bin file against this hash file in order to be sure the file is not corrupted or faulty. + +The following command upgrades your device sim module firmware. Don't not turn off your device during the execution of this command!! +Even its a quite fast command you should be warned. You may brick it if you interrupt it. ``` pm3 --> sc upgrade f ../tools/simmodule/SIM011.BIN @@ -54,6 +66,12 @@ You get the following output if the execution was successful: [+] Smartcard socket firmware upgraded successful ``` +Run hw status command to verify that the upgrade went well. + +``` +pm3 --> hw status +``` + ## Next steps For the next steps, please read the following page: diff --git a/tools/simmodule/readme.txt b/tools/simmodule/readme.txt deleted file mode 100644 index 5dad9cd85..000000000 --- a/tools/simmodule/readme.txt +++ /dev/null @@ -1,32 +0,0 @@ - -2018-12-20 Iceman -2019-03-11 Iceman chg -======================================= - -The latest firmware for the SIM MODULE is : SIM011.bin - -You can use it to upgrade you sim module via the pm3 client. - -pm3 --> sc upgrade -h -pm3 --> sc upgrade f ../tools/simmodule/SIM011.bin - - -Even its a quite fast command you should be warned. You may brick it if you interrupt it. - - -Run hw status command to verify that the upgrade went well. - -pm3 --> hw status - - - -If you didn't download this file from the RRG Repo be aware that it might be corrupt or faulty. - -You find to hash text files in this folder. They were generated with the following linux commands. - - -md5sum -b SIM011.bin > SIM011.md5.txt -sha512sum -b SIM011.bin > SIM011.sha512.txt - - -You should validate the SIM011.bin file against these hash files in order to be sure the file is not corrupt or faulty. \ No newline at end of file From de5c5df732398980f72bc6e51bdfa1d52de79d4b Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 30 Aug 2019 00:08:31 +0200 Subject: [PATCH 0515/1854] remove debug print --- client/fileutils.c | 1 - 1 file changed, 1 deletion(-) diff --git a/client/fileutils.c b/client/fileutils.c index 1a6b40e53..62671952e 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -407,7 +407,6 @@ int loadFile_safe(const char *preferredName, const char *suffix, void **pdata, s char *path; int res = searchFile(&path, "", preferredName, suffix); if (res != PM3_SUCCESS) { - PrintAndLogEx(INFO, "res: %d Curr path:: %s", res, path); return PM3_EFILE; } From ca8aee33ea5ea7e594dc439a3278801b71573591 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 30 Aug 2019 01:23:10 +0200 Subject: [PATCH 0516/1854] move iclass_dump.bin in resources/ --- client/fileutils.c | 2 +- client/{ => resources}/iclass_dump.bin | Bin include/common.h | 1 + 3 files changed, 2 insertions(+), 1 deletion(-) rename client/{ => resources}/iclass_dump.bin (100%) diff --git a/client/fileutils.c b/client/fileutils.c index 62671952e..bff8771ad 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -405,7 +405,7 @@ out: int loadFile_safe(const char *preferredName, const char *suffix, void **pdata, size_t *datalen) { char *path; - int res = searchFile(&path, "", preferredName, suffix); + int res = searchFile(&path, RESOURCES_SUBDIR, preferredName, suffix); if (res != PM3_SUCCESS) { return PM3_EFILE; } diff --git a/client/iclass_dump.bin b/client/resources/iclass_dump.bin similarity index 100% rename from client/iclass_dump.bin rename to client/resources/iclass_dump.bin diff --git a/include/common.h b/include/common.h index a2850ef32..830a99e79 100644 --- a/include/common.h +++ b/include/common.h @@ -30,6 +30,7 @@ #define DICTIONARIES_SUBDIR "dictionaries/" #define LUA_LIBRARIES_SUBDIR "lualibs/" #define LUA_SCRIPTS_SUBDIR "luascripts/" +#define RESOURCES_SUBDIR "resources/" #define PACKED __attribute__((packed)) From af65beb9879d393b072a9cdc7ff8aab4d2dd6022 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 30 Aug 2019 01:23:50 +0200 Subject: [PATCH 0517/1854] move aidlist.json to resources/ --- client/cmdsmartcard.c | 31 ++++++++++++++++------------- client/{ => resources}/aidlist.json | 0 2 files changed, 17 insertions(+), 14 deletions(-) rename client/{ => resources}/aidlist.json (100%) diff --git a/client/cmdsmartcard.c b/client/cmdsmartcard.c index f1fd2b917..4ea67be95 100644 --- a/client/cmdsmartcard.c +++ b/client/cmdsmartcard.c @@ -22,6 +22,7 @@ #include "crypto/libpcrypto.h" // sha512hash #include "emv/dump.h" #include "ui.h" +#include "fileutils.h" static int CmdHelp(const char *Cmd); @@ -92,33 +93,35 @@ static int usage_sm_brute(void) { return 0; } -static int smart_loadjson(const char *preferredName, const char *suffix, json_t **root) { +static int smart_loadjson(const char *preferredName, json_t **root) { json_error_t error; if (preferredName == NULL) return 1; - if (suffix == NULL) return 1; - int retval = 0; - int size = sizeof(char) * (strlen(get_my_executable_directory()) + strlen(preferredName) + strlen(suffix) + 10); - char *fileName = calloc(size, sizeof(char)); - sprintf(fileName, "%s%s.%s", get_my_executable_directory(), preferredName, suffix); - *root = json_load_file(fileName, 0, &error); + char *path; + int res = searchFile(&path, RESOURCES_SUBDIR, preferredName, ".json"); + if (res != PM3_SUCCESS) { + return PM3_EFILE; + } + + int retval = PM3_SUCCESS; + *root = json_load_file(path, 0, &error); if (!*root) { - PrintAndLogEx(ERR, "json (%s) error on line %d: %s", fileName, error.line, error.text); - retval = 2; + PrintAndLogEx(ERR, "json (%s) error on line %d: %s", path, error.line, error.text); + retval = PM3_ESOFT; goto out; } if (!json_is_array(*root)) { - PrintAndLogEx(ERR, "Invalid json (%s) format. root must be an array.", fileName); - retval = 3; + PrintAndLogEx(ERR, "Invalid json (%s) format. root must be an array.", path); + retval = PM3_ESOFT; goto out; } - PrintAndLogEx(SUCCESS, "Loaded file (%s) OK.", fileName); + PrintAndLogEx(SUCCESS, "Loaded file (%s) OK.", path); out: - free(fileName); + free(path); return retval; } @@ -1035,7 +1038,7 @@ static int CmdSmartBruteforceSFI(const char *Cmd) { PrintAndLogEx(INFO, "Importing AID list"); json_t *root = NULL; - smart_loadjson("aidlist", "json", &root); + smart_loadjson("aidlist", &root); uint8_t *buf = calloc(PM3_CMD_DATA_SIZE, sizeof(uint8_t)); if (!buf) diff --git a/client/aidlist.json b/client/resources/aidlist.json similarity index 100% rename from client/aidlist.json rename to client/resources/aidlist.json From 5b6af929ab89eaef235f920baceae43ed29d2f26 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 30 Aug 2019 02:00:41 +0200 Subject: [PATCH 0518/1854] move oid.json to resources/ --- client/crypto/asn1dump.c | 20 +++++++------------- client/{crypto => resources}/oids.json | 0 2 files changed, 7 insertions(+), 13 deletions(-) rename client/{crypto => resources}/oids.json (100%) diff --git a/client/crypto/asn1dump.c b/client/crypto/asn1dump.c index 356dd3591..140b0d2e2 100644 --- a/client/crypto/asn1dump.c +++ b/client/crypto/asn1dump.c @@ -25,6 +25,8 @@ #include "emv/emvjson.h" #include "util.h" #include "proxmark3.h" +#include "fileutils.h" +#include "pm3_cmd.h" #ifndef PRINT_INDENT # define PRINT_INDENT(level) {for (int myi = 0; myi < (level); myi++) fprintf(f, " ");} @@ -235,25 +237,17 @@ static void asn1_tag_dump_integer(const struct tlv *tlv, const struct asn1_tag * static char *asn1_oid_description(const char *oid, bool with_group_desc) { json_error_t error; json_t *root = NULL; - char fname[300] = {0}; static char res[300]; memset(res, 0x00, sizeof(res)); - size_t len = strlen(get_my_executable_directory()); - if (len >= 300) len = 299; - - strncpy(fname, get_my_executable_directory(), len); - strcat(fname, "crypto/oids.json"); - if (access(fname, F_OK) < 0) { - strncpy(fname, get_my_executable_directory(), len); - strcat(fname, "oids.json"); - if (access(fname, F_OK) < 0) { - goto error; // file not found - } + char *path; + if (searchFile(&path, RESOURCES_SUBDIR, "oids", ".json") != PM3_SUCCESS) { + return NULL; } // load `oids.json` - root = json_load_file(fname, 0, &error); + root = json_load_file(path, 0, &error); + free(path); if (!root || !json_is_object(root)) { goto error; diff --git a/client/crypto/oids.json b/client/resources/oids.json similarity index 100% rename from client/crypto/oids.json rename to client/resources/oids.json From c6ac4056d3541b0eebebca4f1e7e1c534206c1ee Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 30 Aug 2019 02:01:14 +0200 Subject: [PATCH 0519/1854] fix iclass txt --- client/cmdhficlass.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index bd937fe17..f5406e8e7 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -74,7 +74,7 @@ static int usage_hf_iclass_decrypt(void) { PrintAndLogEx(NORMAL, "Correct behaviour would be to decrypt only the application areas where the key is valid,"); PrintAndLogEx(NORMAL, "which is defined by the configuration block."); PrintAndLogEx(NORMAL, "OBS! In order to use this function, the file 'iclass_decryptionkey.bin' must reside"); - PrintAndLogEx(NORMAL, "in the working directory. The file should be 16 bytes binary data"); + PrintAndLogEx(NORMAL, "in the resources directory. The file should be 16 bytes binary data"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Usage: hf iclass decrypt f k "); PrintAndLogEx(NORMAL, " options"); @@ -88,7 +88,7 @@ static int usage_hf_iclass_decrypt(void) { } static int usage_hf_iclass_encrypt(void) { PrintAndLogEx(NORMAL, "OBS! In order to use this function, the file 'iclass_decryptionkey.bin' must reside"); - PrintAndLogEx(NORMAL, "in the working directory. The file should be 16 bytes binary data"); + PrintAndLogEx(NORMAL, "in the resources directory. The file should be 16 bytes binary data"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Usage: hf iclass encrypt d k "); PrintAndLogEx(NORMAL, ""); From 382129205f01c63408923cb7d4f71a194d0a1e02 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 30 Aug 2019 02:10:55 +0200 Subject: [PATCH 0520/1854] move capk.txt to resources/ --- client/emv/emv_pk.c | 15 ++++++++------- client/{emv => resources}/capk.txt | 0 2 files changed, 8 insertions(+), 7 deletions(-) rename client/{emv => resources}/capk.txt (100%) diff --git a/client/emv/emv_pk.c b/client/emv/emv_pk.c index e273480c8..bb124c63c 100644 --- a/client/emv/emv_pk.c +++ b/client/emv/emv_pk.c @@ -29,6 +29,8 @@ #include "ui.h" #include "crypto.h" #include "proxmark3.h" +#include "fileutils.h" +#include "pm3_cmd.h" #define BCD(c) (((c) >= '0' && (c) <= '9') ? ((c) - '0') : \ -1) @@ -483,13 +485,12 @@ struct emv_pk *emv_pk_get_ca_pk(const unsigned char *rid, unsigned char idx) { } } */ - const char *relfname = "emv/capk.txt"; - - char fname[strlen(get_my_executable_directory()) + strlen(relfname) + 1]; - strcpy(fname, get_my_executable_directory()); - strcat(fname, relfname); - - pk = emv_pk_get_ca_pk_from_file(fname, rid, idx); + char *path; + if (searchFile(&path, RESOURCES_SUBDIR, "capk", ".txt") != PM3_SUCCESS) { + return NULL; + } + pk = emv_pk_get_ca_pk_from_file(path, rid, idx); + free(path); if (!pk) return NULL; diff --git a/client/emv/capk.txt b/client/resources/capk.txt similarity index 100% rename from client/emv/capk.txt rename to client/resources/capk.txt From 40709f45365f21ba831eec3b523952de5bb5fabf Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 30 Aug 2019 02:18:14 +0200 Subject: [PATCH 0521/1854] move defparams.json to resources/emv_defparams.json --- client/emv/cmdemv.c | 10 +++++----- client/emv/emvjson.c | 15 ++++++++------- .../emv_defparams.json} | 0 3 files changed, 13 insertions(+), 12 deletions(-) rename client/{emv/defparams.json => resources/emv_defparams.json} (100%) diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c index 3891bdb48..348840cb3 100644 --- a/client/emv/cmdemv.c +++ b/client/emv/cmdemv.c @@ -232,7 +232,7 @@ static int CmdEMVGPO(const char *Cmd) { void *argtable[] = { arg_param_begin, arg_lit0("kK", "keep", "keep field ON for next command"), - arg_lit0("pP", "params", "load parameters from `emv/defparams.json` file for PDOLdata making from PDOL and parameters"), + arg_lit0("pP", "params", "load parameters from `emv_defparams.json` file for PDOLdata making from PDOL and parameters"), arg_lit0("mM", "make", "make PDOLdata from PDOL (tag 9F38) and parameters (by default uses default parameters)"), arg_lit0("aA", "apdu", "show APDU reqests and responses"), arg_lit0("tT", "tlv", "TLV decode results of selected applets"), @@ -398,7 +398,7 @@ static int CmdEMVAC(const char *Cmd) { arg_lit0("kK", "keep", "keep field ON for next command"), arg_lit0("cC", "cda", "executes CDA transaction. Needs to get SDAD in results."), arg_str0("dD", "decision", "", "Terminal decision. aac - declined, tc - approved, arqc - online authorisation requested"), - arg_lit0("pP", "params", "load parameters from `emv/defparams.json` file for CDOLdata making from CDOL and parameters"), + arg_lit0("pP", "params", "load parameters from `emv_defparams.json` file for CDOLdata making from CDOL and parameters"), arg_lit0("mM", "make", "make CDOLdata from CDOL (tag 8C and 8D) and parameters (by default uses default parameters)"), arg_lit0("aA", "apdu", "show APDU reqests and responses"), arg_lit0("tT", "tlv", "TLV decode results of selected applets"), @@ -564,7 +564,7 @@ static int CmdEMVInternalAuthenticate(const char *Cmd) { void *argtable[] = { arg_param_begin, arg_lit0("kK", "keep", "keep field ON for next command"), - arg_lit0("pP", "params", "load parameters from `emv/defparams.json` file for DDOLdata making from DDOL and parameters"), + arg_lit0("pP", "params", "load parameters from `emv_defparams.json` file for DDOLdata making from DDOL and parameters"), arg_lit0("mM", "make", "make DDOLdata from DDOL (tag 9F49) and parameters (by default uses default parameters)"), arg_lit0("aA", "apdu", "show APDU reqests and responses"), arg_lit0("tT", "tlv", "TLV decode results of selected applets"), @@ -785,7 +785,7 @@ static int CmdEMVExec(const char *Cmd) { arg_lit0("sS", "select", "activate field and select card."), arg_lit0("aA", "apdu", "show APDU reqests and responses."), arg_lit0("tT", "tlv", "TLV decode results."), - arg_lit0("jJ", "jload", "Load transaction parameters from `emv/defparams.json` file."), + arg_lit0("jJ", "jload", "Load transaction parameters from `emv_defparams.json` file."), arg_lit0("fF", "forceaid", "Force search AID. Search AID instead of execute PPSE."), arg_rem("By default:", "Transaction type - MSD"), arg_lit0("vV", "qvsdc", "Transaction type - qVSDC or M/Chip."), @@ -1376,7 +1376,7 @@ static int CmdEMVScan(const char *Cmd) { arg_lit0("aA", "apdu", "show APDU reqests and responses."), arg_lit0("tT", "tlv", "TLV decode results."), arg_lit0("eE", "extract", "Extract TLV elements and fill Application Data"), - arg_lit0("jJ", "jload", "Load transaction parameters from `emv/defparams.json` file."), + arg_lit0("jJ", "jload", "Load transaction parameters from `emv_defparams.json` file."), arg_rem("By default:", "Transaction type - MSD"), arg_lit0("vV", "qvsdc", "Transaction type - qVSDC or M/Chip."), arg_lit0("cC", "qvsdccda", "Transaction type - qVSDC or M/Chip plus CDA (SDAD generation)."), diff --git a/client/emv/emvjson.c b/client/emv/emvjson.c index 88d886c6e..715407a23 100644 --- a/client/emv/emvjson.c +++ b/client/emv/emvjson.c @@ -17,6 +17,8 @@ #include "util.h" #include "proxmark3.h" #include "emv_tags.h" +#include "fileutils.h" +#include "pm3_cmd.h" static const ApplicationDataElm ApplicationData[] = { {0x82, "AIP"}, @@ -303,13 +305,12 @@ bool ParamLoadFromJson(struct tlvdb *tlv) { return false; } - // current path + file name - const char *relfname = "emv/defparams.json"; - char fname[strlen(get_my_executable_directory()) + strlen(relfname) + 1]; - strcpy(fname, get_my_executable_directory()); - strcat(fname, relfname); - - root = json_load_file(fname, 0, &error); + char *path; + if (searchFile(&path, RESOURCES_SUBDIR, "emv_defparams", ".json") != PM3_SUCCESS) { + return false; + } + root = json_load_file(path, 0, &error); + free(path); if (!root) { PrintAndLogEx(ERR, "Load params: json error on line " _YELLOW_("%d") ": %s", error.line, error.text); return false; diff --git a/client/emv/defparams.json b/client/resources/emv_defparams.json similarity index 100% rename from client/emv/defparams.json rename to client/resources/emv_defparams.json From 08a5de1f0edea2531c5393ab945873d9447d6db6 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 30 Aug 2019 08:32:34 +0200 Subject: [PATCH 0522/1854] searchFile traces --- client/cmddata.c | 14 +++++++++++--- client/fileutils.c | 42 ++++++++++++++++++++++++++++++++++++++++-- include/common.h | 1 + 3 files changed, 52 insertions(+), 5 deletions(-) diff --git a/client/cmddata.c b/client/cmddata.c index 81060cd59..817a63930 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -23,6 +23,7 @@ #include "lfdemod.h" // for demod code #include "loclass/cipherutils.h" // for decimating samples in getsamples #include "cmdlfem4x.h" // askem410xdecode +#include "fileutils.h" // searchFile uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN]; size_t DemodBufferLen = 0; @@ -1646,12 +1647,19 @@ static int CmdLoad(const char *Cmd) { if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE; memcpy(filename, Cmd, len); - FILE *f = fopen(filename, "r"); - if (!f) { - PrintAndLogEx(WARNING, "couldn't open '%s'", filename); + char *path; + if (searchFile(&path, TRACES_SUBDIR, filename, "") != PM3_SUCCESS) { return PM3_EFILE; } + FILE *f = fopen(path, "r"); + if (!f) { + PrintAndLogEx(WARNING, "couldn't open '%s'", path); + free(path); + return PM3_EFILE; + } + free(path); + GraphTraceLen = 0; char line[80]; while (fgets(line, sizeof(line), f)) { diff --git a/client/fileutils.c b/client/fileutils.c index bff8771ad..ae7531771 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -869,6 +869,9 @@ static int searchFinalFile(char **foundpath, const char *pm3dir, const char *sea char *filename = calloc(strlen(searchname) + 1, sizeof(char)); if (filename == NULL) return PM3_EMALLOC; strcpy(filename, searchname); + if (g_debugMode == 2) { + PrintAndLogEx(INFO, "Searching %s", filename); + } if (((strlen(filename) > 1) && (filename[0] == '/')) || ((strlen(filename) > 2) && (filename[0] == '.') && (filename[1] == '/'))) { if (fileExists(filename)) { @@ -887,15 +890,44 @@ static int searchFinalFile(char **foundpath, const char *pm3dir, const char *sea return PM3_SUCCESS; } } - // try pm3 dirs in current workdir (dev mode) + // try pm3 dirs in current client workdir (dev mode) const char *exec_path = get_my_executable_directory(); - if (exec_path != NULL) { + if ((exec_path != NULL) && + ((strcmp(DICTIONARIES_SUBDIR, pm3dir) == 0) || + (strcmp(LUA_LIBRARIES_SUBDIR, pm3dir) == 0) || + (strcmp(LUA_SCRIPTS_SUBDIR, pm3dir) == 0) || + (strcmp(RESOURCES_SUBDIR, pm3dir) == 0))) { char *path = calloc(strlen(exec_path) + strlen(pm3dir) + strlen(filename) + 1, sizeof(char)); if (path == NULL) goto out; strcpy(path, exec_path); strcat(path, pm3dir); strcat(path, filename); + if (g_debugMode == 2) { + PrintAndLogEx(INFO, "Searching %s", path); + } + if (fileExists(path)) { + free(filename); + *foundpath = path; + return PM3_SUCCESS; + } else { + free(path); + } + } + // try pm3 dirs in current repo workdir (dev mode) + if ((exec_path != NULL) && + ((strcmp(TRACES_SUBDIR, pm3dir) == 0))) { + char *above = "../"; + char *path = calloc(strlen(exec_path) + strlen(above) + strlen(pm3dir) + strlen(filename) + 1, sizeof(char)); + if (path == NULL) + goto out; + strcpy(path, exec_path); + strcat(path, above); + strcat(path, pm3dir); + strcat(path, filename); + if (g_debugMode == 2) { + PrintAndLogEx(INFO, "Searching %s", path); + } if (fileExists(path)) { free(filename); *foundpath = path; @@ -914,6 +946,9 @@ static int searchFinalFile(char **foundpath, const char *pm3dir, const char *sea strcat(path, PM3_USER_DIRECTORY); strcat(path, pm3dir); strcat(path, filename); + if (g_debugMode == 2) { + PrintAndLogEx(INFO, "Searching %s", path); + } if (fileExists(path)) { free(filename); *foundpath = path; @@ -930,6 +965,9 @@ static int searchFinalFile(char **foundpath, const char *pm3dir, const char *sea strcpy(path, PM3_SHARE_PATH); strcat(path, pm3dir); strcat(path, filename); + if (g_debugMode == 2) { + PrintAndLogEx(INFO, "Searching %s", path); + } if (fileExists(path)) { free(filename); *foundpath = path; diff --git a/include/common.h b/include/common.h index 830a99e79..c4c5d6370 100644 --- a/include/common.h +++ b/include/common.h @@ -31,6 +31,7 @@ #define LUA_LIBRARIES_SUBDIR "lualibs/" #define LUA_SCRIPTS_SUBDIR "luascripts/" #define RESOURCES_SUBDIR "resources/" +#define TRACES_SUBDIR "traces/" #define PACKED __attribute__((packed)) From 5bb12724aee538716af9596d53ccf6c4b3bee2b4 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 30 Aug 2019 08:51:31 +0200 Subject: [PATCH 0523/1854] add: updated the loclass document --- doc/loclass_notes.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 doc/loclass_notes.md diff --git a/doc/loclass_notes.md b/doc/loclass_notes.md new file mode 100644 index 000000000..d77e8ba57 --- /dev/null +++ b/doc/loclass_notes.md @@ -0,0 +1,22 @@ +# About LOCLASS attack + +This document is primarily intended for understanding `hf iclass loclass` and used files with it. + +LOCLASS aim is to recoved the used masterkey for that specific reader configued in Elite mode / High Security mode. + +LOCLASS, is a two part attack. First is the online part where you gather needed information from the reader by presenting a carefully selected CSN and save the responses to file. For the first part you run `hf iclass sim 2` and take notice of the saved filename. + +The second part is offline, where the information gathered from the first step is used in a series of DES operations to figure out the used +masterkey. run `hf iclass loclass f abc.bin' + +If you don't have access to a iClass SE reader configured in Elite mode there is a test file which you can use. +`hf iclass loclass f iclass_dump.bin` + + +# Unit testing +In order to verify that loclass is actually working, there is a "unit" test mode. run `hf iclass loclass t`. +This test mode uses two files. +- iclass_dump.bin + this is a sample file from `hf iclass sim 2`, with complete keytable recovery, using 128 carefully selected CSN and the file contains the MAC results from reader. +- iclass_key.bin + this is file shall contain the legacy masterkey, AA1 key. loclass uses it to verify that permution / reversing / generation of key is correct. \ No newline at end of file From f6fa2c465174c189e4b880e9a255b2e126fd1cb0 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 30 Aug 2019 08:51:55 +0200 Subject: [PATCH 0524/1854] moved to docs --- client/loclass/loclass_information.txt | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 client/loclass/loclass_information.txt diff --git a/client/loclass/loclass_information.txt b/client/loclass/loclass_information.txt deleted file mode 100644 index 307d28203..000000000 --- a/client/loclass/loclass_information.txt +++ /dev/null @@ -1,12 +0,0 @@ -2017-08-19 iceman, - -iclass_dump.bin -=============== -The file iclass_dump.bin contains CSN's mac results from 128 CSNs. -Hence when running the test mode, - 'hf iclass loclass t' -it shows a long output from the bruteforce test. - -iclass_key.bin -============== -The file iclass_key.bin is where you add the AA1 master key in order for the proxmark3 client to use it with the loclass commands From eba13925e437fce57107bd751d78004f4bbfb5b6 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 30 Aug 2019 08:53:04 +0200 Subject: [PATCH 0525/1854] move bf_bench_data.bin to resources/hardnested_* --- client/hardnested/hardnested_bruteforce.c | 29 ++++++++++++------ .../hardnested_bf_bench_data.bin} | Bin 2 files changed, 19 insertions(+), 10 deletions(-) rename client/{hardnested/bf_bench_data.bin => resources/hardnested_bf_bench_data.bin} (100%) diff --git a/client/hardnested/hardnested_bruteforce.c b/client/hardnested/hardnested_bruteforce.c index 5f93d4811..96211f47f 100644 --- a/client/hardnested/hardnested_bruteforce.c +++ b/client/hardnested/hardnested_bruteforce.c @@ -65,11 +65,13 @@ THE SOFTWARE. #include "util_posix.h" #include "crapto1/crapto1.h" #include "parity.h" +#include "fileutils.h" +#include "pm3_cmd.h" #define NUM_BRUTE_FORCE_THREADS (num_CPUs()) #define DEFAULT_BRUTE_FORCE_RATE (120000000.0) // if benchmark doesn't succeed #define TEST_BENCH_SIZE (6000) // number of odd and even states for brute force benchmark -#define TEST_BENCH_FILENAME "hardnested/bf_bench_data.bin" +#define TEST_BENCH_FILENAME "hardnested_bf_bench_data.bin" //#define WRITE_BENCH_FILE // debugging options @@ -265,8 +267,12 @@ void prepare_bf_test_nonces(noncelist_t *nonces, uint8_t best_first_byte) { #if defined (WRITE_BENCH_FILE) static void write_benchfile(statelist_t *candidates) { - printf("Writing brute force benchmark data..."); - FILE *benchfile = fopen(TEST_BENCH_FILENAME, "wb"); + PrintAndLogEx(NORMAL, "Writing brute force benchmark data in " RESOURCES_SUBDIR " subdirectory..."); + FILE *benchfile = fopen(RESOURCES_SUBDIR TEST_BENCH_FILENAME, "wb"); + if (benchfile == NULL) { + PrintAndLogEx(ERR, "Can't write " RESOURCES_SUBDIR TEST_BENCH_FILENAME", abort!"); + return; + } fwrite(&nonces_to_bruteforce, 1, sizeof(nonces_to_bruteforce), benchfile); for (uint32_t i = 0; i < nonces_to_bruteforce; i++) { fwrite(&(bf_test_nonce[i]), 1, sizeof(bf_test_nonce[i]), benchfile); @@ -283,7 +289,7 @@ static void write_benchfile(statelist_t *candidates) { fwrite(&(candidates->states[ODD_STATE][i]), 1, sizeof(uint32_t), benchfile); } fclose(benchfile); - printf("done.\n"); + PrintAndLogEx(NORMAL, "Done"); } #endif @@ -360,14 +366,17 @@ static bool read_bench_data(statelist_t *test_candidates) { uint32_t num_states = 0; uint32_t states_read = 0; - char bench_file_path[strlen(get_my_executable_directory()) + strlen(TEST_BENCH_FILENAME) + 1]; - strcpy(bench_file_path, get_my_executable_directory()); - strcat(bench_file_path, TEST_BENCH_FILENAME); - - FILE *benchfile = fopen(bench_file_path, "rb"); - if (benchfile == NULL) { + char *path; + if (searchFile(&path, RESOURCES_SUBDIR, TEST_BENCH_FILENAME, "") != PM3_SUCCESS) { return false; } + + FILE *benchfile = fopen(path, "rb"); + if (benchfile == NULL) { + free(path); + return false; + } + free(path); bytes_read = fread(&nonces_to_bruteforce, 1, sizeof(nonces_to_bruteforce), benchfile); if (bytes_read != sizeof(nonces_to_bruteforce)) { fclose(benchfile); diff --git a/client/hardnested/bf_bench_data.bin b/client/resources/hardnested_bf_bench_data.bin similarity index 100% rename from client/hardnested/bf_bench_data.bin rename to client/resources/hardnested_bf_bench_data.bin From 491e8925bb7fe52493e5d817e313ea256aa0cac6 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 30 Aug 2019 08:54:23 +0200 Subject: [PATCH 0526/1854] linked in --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9bf18de1a..8f2bf4b5a 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,7 @@ It is dedicated to bringing the most out of the new features for Proxmark3 RDV4. |[Notes on external flash](/doc/ext_flash_notes.md)||| |[Notes on Termux / Android](/doc/termux_notes.md)||| |[Notes on Wireshark / tracedata](/doc/trace_wireshark_notes.md)||| +|[Notes on loclass](/doc/loclass_notes.md)||| |[Developing standalone mode](/armsrc/Standalone/readme.md)|[Wiki about standalone mode](https://github.com/RfidResearchGroup/proxmark3/wiki/Standalone-mode) || |[Donations](#Donations)||| @@ -46,7 +47,7 @@ This fork now compiles just fine on - Windows/mingw environment with Qt5.6.1 & GCC 4.8 - Ubuntu 1404, 1510, 1604, 1804, 1904 - Mac OS X / Homebrew - - ParrotOS, Gentoo, Pentoo + - ParrotOS, Gentoo, Pentoo, Kali, Nethunter, Archlinux - WSL, WSL2 (Windows subsystem linux) on Windows 10 - Docker container @@ -59,6 +60,7 @@ If you intend to contribute to the code, please read the [coding style notes](HA - Internal notes on [standalone mode](https://github.com/RfidResearchGroup/proxmark3/wiki/Standalone-mode) - Internal notes on [Termux / Android](/doc/termux_notes.md) - Internal notes on [Wireshark / tracedata](/doc/trace_wireshark_notes.md) +- Internal notes on [loclass](/doc/loclass_notes.md) ## Cheat sheet Thanks to Alex Dibs, you can enjoy a [command cheat sheet](/doc/cheatsheet.md) From 54a58cde4e3f873bd18c952f4f93c3f41f6f33f2 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 30 Aug 2019 08:57:04 +0200 Subject: [PATCH 0527/1854] textual --- doc/loclass_notes.md | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/doc/loclass_notes.md b/doc/loclass_notes.md index d77e8ba57..2684ae433 100644 --- a/doc/loclass_notes.md +++ b/doc/loclass_notes.md @@ -1,22 +1,26 @@ # About LOCLASS attack -This document is primarily intended for understanding `hf iclass loclass` and used files with it. +This document is primarily intended for understanding `hf iclass loclass` and files used with it. LOCLASS aim is to recoved the used masterkey for that specific reader configued in Elite mode / High Security mode. LOCLASS, is a two part attack. First is the online part where you gather needed information from the reader by presenting a carefully selected CSN and save the responses to file. For the first part you run `hf iclass sim 2` and take notice of the saved filename. The second part is offline, where the information gathered from the first step is used in a series of DES operations to figure out the used -masterkey. run `hf iclass loclass f abc.bin' +masterkey. + run `hf iclass loclass f abc.bin` If you don't have access to a iClass SE reader configured in Elite mode there is a test file which you can use. -`hf iclass loclass f iclass_dump.bin` + `hf iclass loclass f iclass_dump.bin` # Unit testing -In order to verify that loclass is actually working, there is a "unit" test mode. run `hf iclass loclass t`. +In order to verify that loclass is actually working, there is a "unit" test mode. +run `hf iclass loclass t`. + This test mode uses two files. -- iclass_dump.bin - this is a sample file from `hf iclass sim 2`, with complete keytable recovery, using 128 carefully selected CSN and the file contains the MAC results from reader. -- iclass_key.bin - this is file shall contain the legacy masterkey, AA1 key. loclass uses it to verify that permution / reversing / generation of key is correct. \ No newline at end of file + +- `iclass_dump.bin` + this is a sample file from `hf iclass sim 2`, with complete keytable recovery, using 128 carefully selected CSN and the file contains the MAC results from reader. +- `iclass_key.bin` + this is file shall contain the legacy masterkey, AA1 key. loclass uses it to verify that permution / reversing / generation of key is correct. \ No newline at end of file From f227cebc3b6c90ff0baea5f6909b52ffc8524e64 Mon Sep 17 00:00:00 2001 From: Iceman Date: Fri, 30 Aug 2019 09:22:32 +0200 Subject: [PATCH 0528/1854] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 8f2bf4b5a..f02deabf6 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,7 @@ On the software side: quite a lot, see the [Changelog file](CHANGELOG.md). ## Development This fork now compiles just fine on + - Proxspace v3.2 - Windows/mingw environment with Qt5.6.1 & GCC 4.8 - Ubuntu 1404, 1510, 1604, 1804, 1904 - Mac OS X / Homebrew From 2c853d94ea78356509f71f608670fd820ce508a1 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 30 Aug 2019 09:02:01 +0200 Subject: [PATCH 0529/1854] move hardnested tables to resources/ --- client/cmddata.c | 2 +- client/cmdhfmf.c | 4 +- client/cmdhfmfhard.c | 14 ++++-- client/cmdscript.c | 2 +- client/cmdsmartcard.c | 2 +- client/crypto/asn1dump.c | 2 +- client/emv/emv_pk.c | 2 +- client/emv/emvjson.c | 2 +- client/fileutils.c | 42 +++++++++++++----- client/fileutils.h | 2 +- client/hardnested/hardnested_bruteforce.c | 2 +- .../bitflip_0_001_states.bin.z | Bin .../bitflip_0_003_states.bin.z | Bin .../bitflip_0_005_states.bin.z | Bin .../bitflip_0_007_states.bin.z | Bin .../bitflip_0_009_states.bin.z | Bin .../bitflip_0_00b_states.bin.z | Bin .../bitflip_0_00d_states.bin.z | Bin .../bitflip_0_00f_states.bin.z | Bin .../bitflip_0_010_states.bin.z | Bin .../bitflip_0_014_states.bin.z | Bin .../bitflip_0_01c_states.bin.z | Bin .../bitflip_0_021_states.bin.z | Bin .../bitflip_0_023_states.bin.z | Bin .../bitflip_0_025_states.bin.z | 0 .../bitflip_0_027_states.bin.z | Bin .../bitflip_0_029_states.bin.z | Bin .../bitflip_0_02b_states.bin.z | Bin .../bitflip_0_02d_states.bin.z | Bin .../bitflip_0_02f_states.bin.z | Bin .../bitflip_0_030_states.bin.z | Bin .../bitflip_0_034_states.bin.z | Bin .../bitflip_0_03c_states.bin.z | Bin .../bitflip_0_040_states.bin.z | Bin .../bitflip_0_044_states.bin.z | Bin .../bitflip_0_04c_states.bin.z | Bin .../bitflip_0_051_states.bin.z | Bin .../bitflip_0_053_states.bin.z | Bin .../bitflip_0_055_states.bin.z | Bin .../bitflip_0_057_states.bin.z | Bin .../bitflip_0_059_states.bin.z | Bin .../bitflip_0_05b_states.bin.z | Bin .../bitflip_0_05d_states.bin.z | Bin .../bitflip_0_05f_states.bin.z | Bin .../bitflip_0_064_states.bin.z | Bin .../bitflip_0_06c_states.bin.z | Bin .../bitflip_0_071_states.bin.z | Bin .../bitflip_0_073_states.bin.z | Bin .../bitflip_0_075_states.bin.z | Bin .../bitflip_0_077_states.bin.z | Bin .../bitflip_0_079_states.bin.z | Bin .../bitflip_0_07b_states.bin.z | Bin .../bitflip_0_07f_states.bin.z | Bin .../bitflip_0_081_states.bin.z | Bin .../bitflip_0_083_states.bin.z | Bin .../bitflip_0_085_states.bin.z | Bin .../bitflip_0_087_states.bin.z | Bin .../bitflip_0_089_states.bin.z | Bin .../bitflip_0_08b_states.bin.z | Bin .../bitflip_0_08d_states.bin.z | Bin .../bitflip_0_08f_states.bin.z | Bin .../bitflip_0_090_states.bin.z | Bin .../bitflip_0_094_states.bin.z | Bin .../bitflip_0_09c_states.bin.z | Bin .../bitflip_0_0a1_states.bin.z | Bin .../bitflip_0_0a3_states.bin.z | Bin .../bitflip_0_0a5_states.bin.z | Bin .../bitflip_0_0a7_states.bin.z | Bin .../bitflip_0_0a9_states.bin.z | Bin .../bitflip_0_0ab_states.bin.z | Bin .../bitflip_0_0ad_states.bin.z | Bin .../bitflip_0_0af_states.bin.z | Bin .../bitflip_0_0b0_states.bin.z | Bin .../bitflip_0_0b4_states.bin.z | Bin .../bitflip_0_0bc_states.bin.z | Bin .../bitflip_0_0c0_states.bin.z | Bin .../bitflip_0_0c4_states.bin.z | Bin .../bitflip_0_0cc_states.bin.z | Bin .../bitflip_0_0d1_states.bin.z | Bin .../bitflip_0_0d3_states.bin.z | Bin .../bitflip_0_0d5_states.bin.z | Bin .../bitflip_0_0d7_states.bin.z | Bin .../bitflip_0_0d9_states.bin.z | Bin .../bitflip_0_0db_states.bin.z | Bin .../bitflip_0_0dd_states.bin.z | Bin .../bitflip_0_0df_states.bin.z | Bin .../bitflip_0_0e4_states.bin.z | Bin .../bitflip_0_0ec_states.bin.z | Bin .../bitflip_0_0f1_states.bin.z | 0 .../bitflip_0_0f3_states.bin.z | Bin .../bitflip_0_0f5_states.bin.z | Bin .../bitflip_0_0f7_states.bin.z | Bin .../bitflip_0_0f9_states.bin.z | Bin .../bitflip_0_0fb_states.bin.z | Bin .../bitflip_0_0fd_states.bin.z | Bin .../bitflip_0_0ff_states.bin.z | Bin .../bitflip_0_104_states.bin.z | Bin .../bitflip_0_10c_states.bin.z | Bin .../bitflip_0_111_states.bin.z | Bin .../bitflip_0_113_states.bin.z | Bin .../bitflip_0_115_states.bin.z | Bin .../bitflip_0_117_states.bin.z | Bin .../bitflip_0_119_states.bin.z | Bin .../bitflip_0_11b_states.bin.z | Bin .../bitflip_0_11d_states.bin.z | Bin .../bitflip_0_11f_states.bin.z | Bin .../bitflip_0_124_states.bin.z | Bin .../bitflip_0_12c_states.bin.z | Bin .../bitflip_0_131_states.bin.z | Bin .../bitflip_0_133_states.bin.z | Bin .../bitflip_0_135_states.bin.z | Bin .../bitflip_0_137_states.bin.z | Bin .../bitflip_0_139_states.bin.z | Bin .../bitflip_0_13b_states.bin.z | Bin .../bitflip_0_13d_states.bin.z | Bin .../bitflip_0_13f_states.bin.z | Bin .../bitflip_0_141_states.bin.z | Bin .../bitflip_0_143_states.bin.z | Bin .../bitflip_0_145_states.bin.z | Bin .../bitflip_0_147_states.bin.z | Bin .../bitflip_0_149_states.bin.z | Bin .../bitflip_0_14b_states.bin.z | Bin .../bitflip_0_14d_states.bin.z | Bin .../bitflip_0_14f_states.bin.z | Bin .../bitflip_0_150_states.bin.z | Bin .../bitflip_0_154_states.bin.z | Bin .../bitflip_0_15c_states.bin.z | Bin .../bitflip_0_161_states.bin.z | Bin .../bitflip_0_163_states.bin.z | Bin .../bitflip_0_165_states.bin.z | 0 .../bitflip_0_167_states.bin.z | Bin .../bitflip_0_169_states.bin.z | Bin .../bitflip_0_16b_states.bin.z | Bin .../bitflip_0_16d_states.bin.z | Bin .../bitflip_0_16f_states.bin.z | Bin .../bitflip_0_170_states.bin.z | Bin .../bitflip_0_174_states.bin.z | Bin .../bitflip_0_17c_states.bin.z | Bin .../bitflip_0_184_states.bin.z | Bin .../bitflip_0_18c_states.bin.z | Bin .../bitflip_0_191_states.bin.z | Bin .../bitflip_0_193_states.bin.z | Bin .../bitflip_0_195_states.bin.z | Bin .../bitflip_0_197_states.bin.z | Bin .../bitflip_0_199_states.bin.z | Bin .../bitflip_0_19b_states.bin.z | Bin .../bitflip_0_19d_states.bin.z | Bin .../bitflip_0_19f_states.bin.z | Bin .../bitflip_0_1a4_states.bin.z | Bin .../bitflip_0_1ac_states.bin.z | Bin .../bitflip_0_1b1_states.bin.z | Bin .../bitflip_0_1b3_states.bin.z | Bin .../bitflip_0_1b5_states.bin.z | Bin .../bitflip_0_1b7_states.bin.z | Bin .../bitflip_0_1b9_states.bin.z | Bin .../bitflip_0_1bb_states.bin.z | Bin .../bitflip_0_1bd_states.bin.z | Bin .../bitflip_0_1bf_states.bin.z | Bin .../bitflip_0_1c1_states.bin.z | Bin .../bitflip_0_1c3_states.bin.z | Bin .../bitflip_0_1c5_states.bin.z | Bin .../bitflip_0_1c9_states.bin.z | Bin .../bitflip_0_1cb_states.bin.z | Bin .../bitflip_0_1d0_states.bin.z | Bin .../bitflip_0_1d4_states.bin.z | Bin .../bitflip_0_1dc_states.bin.z | Bin .../bitflip_0_1e1_states.bin.z | Bin .../bitflip_0_1e3_states.bin.z | Bin .../bitflip_0_1e5_states.bin.z | Bin .../bitflip_0_1e7_states.bin.z | Bin .../bitflip_0_1e9_states.bin.z | Bin .../bitflip_0_1eb_states.bin.z | Bin .../bitflip_0_1ed_states.bin.z | Bin .../bitflip_0_1ef_states.bin.z | Bin .../bitflip_0_1f0_states.bin.z | Bin .../bitflip_0_1f4_states.bin.z | Bin .../bitflip_0_1fc_states.bin.z | Bin .../bitflip_0_210_states.bin.z | 0 .../bitflip_0_225_states.bin.z | Bin .../bitflip_0_227_states.bin.z | Bin .../bitflip_0_22d_states.bin.z | Bin .../bitflip_0_22f_states.bin.z | Bin .../bitflip_0_240_states.bin.z | 0 .../bitflip_0_275_states.bin.z | Bin .../bitflip_0_277_states.bin.z | Bin .../bitflip_0_27f_states.bin.z | Bin .../bitflip_0_294_states.bin.z | 0 .../bitflip_0_2a1_states.bin.z | Bin .../bitflip_0_2a3_states.bin.z | Bin .../bitflip_0_2a9_states.bin.z | Bin .../bitflip_0_2ab_states.bin.z | Bin .../bitflip_0_2c4_states.bin.z | 0 .../bitflip_0_2f1_states.bin.z | Bin .../bitflip_0_2f3_states.bin.z | Bin .../bitflip_0_2f9_states.bin.z | Bin .../bitflip_0_2fb_states.bin.z | Bin .../bitflip_0_335_states.bin.z | Bin .../bitflip_0_337_states.bin.z | Bin .../bitflip_0_33d_states.bin.z | Bin .../bitflip_0_33f_states.bin.z | Bin .../bitflip_0_350_states.bin.z | 0 .../bitflip_0_365_states.bin.z | Bin .../bitflip_0_367_states.bin.z | Bin .../bitflip_0_36d_states.bin.z | Bin .../bitflip_0_36f_states.bin.z | Bin .../bitflip_0_384_states.bin.z | 0 .../bitflip_0_3b1_states.bin.z | Bin .../bitflip_0_3b3_states.bin.z | Bin .../bitflip_0_3b9_states.bin.z | Bin .../bitflip_0_3bb_states.bin.z | Bin .../bitflip_0_3d4_states.bin.z | 0 .../bitflip_0_3e1_states.bin.z | Bin .../bitflip_0_3e3_states.bin.z | Bin .../bitflip_0_3e9_states.bin.z | Bin .../bitflip_0_3eb_states.bin.z | Bin .../bitflip_1_002_states.bin.z | Bin .../bitflip_1_008_states.bin.z | Bin .../bitflip_1_00a_states.bin.z | Bin .../bitflip_1_012_states.bin.z | Bin .../bitflip_1_018_states.bin.z | Bin .../bitflip_1_01a_states.bin.z | Bin .../bitflip_1_020_states.bin.z | Bin .../bitflip_1_028_states.bin.z | Bin .../bitflip_1_02a_states.bin.z | Bin .../bitflip_1_02e_states.bin.z | Bin .../bitflip_1_032_states.bin.z | Bin .../bitflip_1_036_states.bin.z | Bin .../bitflip_1_038_states.bin.z | Bin .../bitflip_1_03a_states.bin.z | Bin .../bitflip_1_03e_states.bin.z | Bin .../bitflip_1_040_states.bin.z | Bin .../bitflip_1_042_states.bin.z | Bin .../bitflip_1_046_states.bin.z | Bin .../bitflip_1_048_states.bin.z | Bin .../bitflip_1_04a_states.bin.z | Bin .../bitflip_1_04e_states.bin.z | Bin .../bitflip_1_052_states.bin.z | Bin .../bitflip_1_056_states.bin.z | Bin .../bitflip_1_058_states.bin.z | Bin .../bitflip_1_05a_states.bin.z | Bin .../bitflip_1_05e_states.bin.z | Bin .../bitflip_1_060_states.bin.z | Bin .../bitflip_1_062_states.bin.z | Bin .../bitflip_1_066_states.bin.z | Bin .../bitflip_1_068_states.bin.z | Bin .../bitflip_1_06a_states.bin.z | Bin .../bitflip_1_06e_states.bin.z | Bin .../bitflip_1_072_states.bin.z | Bin .../bitflip_1_076_states.bin.z | Bin .../bitflip_1_078_states.bin.z | Bin .../bitflip_1_07a_states.bin.z | Bin .../bitflip_1_07e_states.bin.z | Bin .../bitflip_1_080_states.bin.z | Bin .../bitflip_1_082_states.bin.z | Bin .../bitflip_1_086_states.bin.z | Bin .../bitflip_1_088_states.bin.z | Bin .../bitflip_1_08a_states.bin.z | Bin .../bitflip_1_08e_states.bin.z | Bin .../bitflip_1_092_states.bin.z | Bin .../bitflip_1_096_states.bin.z | Bin .../bitflip_1_098_states.bin.z | Bin .../bitflip_1_09a_states.bin.z | Bin .../bitflip_1_09e_states.bin.z | Bin .../bitflip_1_0a0_states.bin.z | Bin .../bitflip_1_0a2_states.bin.z | Bin .../bitflip_1_0a6_states.bin.z | Bin .../bitflip_1_0a8_states.bin.z | Bin .../bitflip_1_0aa_states.bin.z | Bin .../bitflip_1_0ae_states.bin.z | Bin .../bitflip_1_0b2_states.bin.z | Bin .../bitflip_1_0b6_states.bin.z | Bin .../bitflip_1_0b8_states.bin.z | Bin .../bitflip_1_0ba_states.bin.z | Bin .../bitflip_1_0be_states.bin.z | Bin .../bitflip_1_0c0_states.bin.z | Bin .../bitflip_1_0c2_states.bin.z | Bin .../bitflip_1_0c6_states.bin.z | Bin .../bitflip_1_0c8_states.bin.z | Bin .../bitflip_1_0ca_states.bin.z | Bin .../bitflip_1_0ce_states.bin.z | Bin .../bitflip_1_0d2_states.bin.z | Bin .../bitflip_1_0d6_states.bin.z | Bin .../bitflip_1_0d8_states.bin.z | Bin .../bitflip_1_0da_states.bin.z | Bin .../bitflip_1_0de_states.bin.z | Bin .../bitflip_1_0e0_states.bin.z | Bin .../bitflip_1_0e8_states.bin.z | Bin .../bitflip_1_0f8_states.bin.z | Bin .../bitflip_1_108_states.bin.z | Bin .../bitflip_1_111_states.bin.z | Bin .../bitflip_1_113_states.bin.z | Bin .../bitflip_1_115_states.bin.z | Bin .../bitflip_1_117_states.bin.z | Bin .../bitflip_1_118_states.bin.z | Bin .../bitflip_1_11a_states.bin.z | Bin .../bitflip_1_11b_states.bin.z | Bin .../bitflip_1_120_states.bin.z | Bin .../bitflip_1_122_states.bin.z | Bin .../bitflip_1_128_states.bin.z | Bin .../bitflip_1_131_states.bin.z | Bin .../bitflip_1_135_states.bin.z | Bin .../bitflip_1_138_states.bin.z | Bin .../bitflip_1_145_states.bin.z | Bin .../bitflip_1_147_states.bin.z | Bin .../bitflip_1_148_states.bin.z | Bin .../bitflip_1_158_states.bin.z | Bin .../bitflip_1_160_states.bin.z | Bin .../bitflip_1_161_states.bin.z | Bin .../bitflip_1_163_states.bin.z | Bin .../bitflip_1_165_states.bin.z | Bin .../bitflip_1_168_states.bin.z | Bin .../bitflip_1_178_states.bin.z | Bin .../bitflip_1_180_states.bin.z | Bin .../bitflip_1_188_states.bin.z | Bin .../bitflip_1_191_states.bin.z | Bin .../bitflip_1_198_states.bin.z | Bin .../bitflip_1_199_states.bin.z | Bin .../bitflip_1_19d_states.bin.z | Bin .../bitflip_1_19f_states.bin.z | Bin .../bitflip_1_1a0_states.bin.z | 0 .../bitflip_1_1a8_states.bin.z | Bin .../bitflip_1_1b3_states.bin.z | Bin .../bitflip_1_1b5_states.bin.z | Bin .../bitflip_1_1b7_states.bin.z | Bin .../bitflip_1_1b8_states.bin.z | Bin .../bitflip_1_1b9_states.bin.z | Bin .../bitflip_1_1bd_states.bin.z | Bin .../bitflip_1_1c1_states.bin.z | Bin .../bitflip_1_1c3_states.bin.z | Bin .../bitflip_1_1c8_states.bin.z | Bin .../bitflip_1_1c9_states.bin.z | Bin .../bitflip_1_1cd_states.bin.z | Bin .../bitflip_1_1cf_states.bin.z | Bin .../bitflip_1_1d8_states.bin.z | Bin .../bitflip_1_1e0_states.bin.z | 0 .../bitflip_1_1e1_states.bin.z | Bin .../bitflip_1_1e5_states.bin.z | Bin .../bitflip_1_1e7_states.bin.z | Bin .../bitflip_1_1e8_states.bin.z | Bin .../bitflip_1_1e9_states.bin.z | Bin .../bitflip_1_1eb_states.bin.z | Bin .../bitflip_1_1ed_states.bin.z | Bin .../bitflip_1_1f8_states.bin.z | Bin .../bitflip_1_208_states.bin.z | 0 .../bitflip_1_220_states.bin.z | 0 .../bitflip_1_24a_states.bin.z | Bin .../bitflip_1_24e_states.bin.z | Bin .../bitflip_1_25a_states.bin.z | Bin .../bitflip_1_25e_states.bin.z | Bin .../bitflip_1_262_states.bin.z | Bin .../bitflip_1_266_states.bin.z | Bin .../bitflip_1_272_states.bin.z | Bin .../bitflip_1_276_states.bin.z | Bin .../bitflip_1_280_states.bin.z | 0 .../bitflip_1_2a8_states.bin.z | 0 .../bitflip_1_2c2_states.bin.z | Bin .../bitflip_1_2c6_states.bin.z | Bin .../bitflip_1_2d2_states.bin.z | Bin .../bitflip_1_2d6_states.bin.z | Bin .../bitflip_1_328_states.bin.z | 0 .../bitflip_1_388_states.bin.z | 0 .../bitflip_1_3a0_states.bin.z | 0 362 files changed, 50 insertions(+), 26 deletions(-) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_001_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_003_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_005_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_007_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_009_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_00b_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_00d_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_00f_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_010_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_014_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_01c_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_021_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_023_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_025_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_027_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_029_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_02b_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_02d_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_02f_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_030_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_034_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_03c_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_040_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_044_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_04c_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_051_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_053_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_055_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_057_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_059_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_05b_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_05d_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_05f_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_064_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_06c_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_071_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_073_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_075_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_077_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_079_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_07b_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_07f_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_081_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_083_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_085_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_087_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_089_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_08b_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_08d_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_08f_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_090_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_094_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_09c_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_0a1_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_0a3_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_0a5_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_0a7_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_0a9_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_0ab_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_0ad_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_0af_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_0b0_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_0b4_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_0bc_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_0c0_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_0c4_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_0cc_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_0d1_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_0d3_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_0d5_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_0d7_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_0d9_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_0db_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_0dd_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_0df_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_0e4_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_0ec_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_0f1_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_0f3_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_0f5_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_0f7_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_0f9_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_0fb_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_0fd_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_0ff_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_104_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_10c_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_111_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_113_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_115_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_117_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_119_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_11b_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_11d_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_11f_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_124_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_12c_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_131_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_133_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_135_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_137_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_139_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_13b_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_13d_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_13f_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_141_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_143_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_145_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_147_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_149_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_14b_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_14d_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_14f_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_150_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_154_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_15c_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_161_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_163_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_165_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_167_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_169_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_16b_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_16d_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_16f_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_170_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_174_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_17c_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_184_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_18c_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_191_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_193_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_195_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_197_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_199_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_19b_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_19d_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_19f_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_1a4_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_1ac_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_1b1_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_1b3_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_1b5_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_1b7_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_1b9_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_1bb_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_1bd_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_1bf_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_1c1_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_1c3_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_1c5_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_1c9_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_1cb_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_1d0_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_1d4_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_1dc_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_1e1_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_1e3_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_1e5_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_1e7_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_1e9_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_1eb_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_1ed_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_1ef_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_1f0_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_1f4_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_1fc_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_210_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_225_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_227_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_22d_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_22f_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_240_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_275_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_277_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_27f_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_294_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_2a1_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_2a3_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_2a9_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_2ab_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_2c4_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_2f1_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_2f3_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_2f9_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_2fb_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_335_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_337_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_33d_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_33f_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_350_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_365_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_367_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_36d_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_36f_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_384_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_3b1_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_3b3_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_3b9_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_3bb_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_3d4_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_3e1_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_3e3_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_3e9_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_0_3eb_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_002_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_008_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_00a_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_012_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_018_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_01a_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_020_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_028_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_02a_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_02e_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_032_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_036_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_038_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_03a_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_03e_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_040_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_042_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_046_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_048_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_04a_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_04e_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_052_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_056_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_058_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_05a_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_05e_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_060_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_062_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_066_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_068_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_06a_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_06e_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_072_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_076_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_078_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_07a_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_07e_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_080_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_082_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_086_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_088_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_08a_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_08e_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_092_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_096_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_098_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_09a_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_09e_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_0a0_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_0a2_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_0a6_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_0a8_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_0aa_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_0ae_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_0b2_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_0b6_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_0b8_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_0ba_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_0be_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_0c0_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_0c2_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_0c6_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_0c8_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_0ca_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_0ce_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_0d2_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_0d6_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_0d8_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_0da_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_0de_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_0e0_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_0e8_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_0f8_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_108_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_111_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_113_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_115_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_117_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_118_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_11a_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_11b_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_120_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_122_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_128_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_131_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_135_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_138_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_145_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_147_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_148_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_158_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_160_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_161_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_163_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_165_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_168_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_178_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_180_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_188_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_191_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_198_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_199_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_19d_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_19f_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_1a0_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_1a8_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_1b3_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_1b5_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_1b7_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_1b8_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_1b9_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_1bd_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_1c1_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_1c3_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_1c8_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_1c9_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_1cd_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_1cf_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_1d8_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_1e0_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_1e1_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_1e5_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_1e7_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_1e8_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_1e9_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_1eb_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_1ed_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_1f8_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_208_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_220_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_24a_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_24e_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_25a_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_25e_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_262_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_266_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_272_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_276_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_280_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_2a8_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_2c2_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_2c6_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_2d2_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_2d6_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_328_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_388_states.bin.z (100%) rename client/{hardnested/tables => resources/hardnested_tables}/bitflip_1_3a0_states.bin.z (100%) diff --git a/client/cmddata.c b/client/cmddata.c index 817a63930..91bf4b65a 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -1648,7 +1648,7 @@ static int CmdLoad(const char *Cmd) { memcpy(filename, Cmd, len); char *path; - if (searchFile(&path, TRACES_SUBDIR, filename, "") != PM3_SUCCESS) { + if (searchFile(&path, TRACES_SUBDIR, filename, "", false) != PM3_SUCCESS) { return PM3_EFILE; } diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 7a1d2f4b2..538ec0569 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -2398,7 +2398,7 @@ static int CmdHF14AMfChk_fast(const char *Cmd) { } char *dict_path; - int res = searchFile(&dict_path, DICTIONARIES_SUBDIR, filename, ".dic"); + int res = searchFile(&dict_path, DICTIONARIES_SUBDIR, filename, ".dic", false); if (res != PM3_SUCCESS) { free(keyBlock); return res; @@ -2660,7 +2660,7 @@ static int CmdHF14AMfChk(const char *Cmd) { } char *dict_path; - int res = searchFile(&dict_path, DICTIONARIES_SUBDIR, filename, ".dic"); + int res = searchFile(&dict_path, DICTIONARIES_SUBDIR, filename, ".dic", false); if (res != PM3_SUCCESS) { free(keyBlock); return PM3_EFILE; diff --git a/client/cmdhfmfhard.c b/client/cmdhfmfhard.c index d66df7eae..c38c4022e 100644 --- a/client/cmdhfmfhard.c +++ b/client/cmdhfmfhard.c @@ -36,13 +36,14 @@ #include "hardnested/hardnested_bf_core.h" #include "hardnested/hardnested_bitarray_core.h" #include "zlib.h" +#include "fileutils.h" #define NUM_CHECK_BITFLIPS_THREADS (num_CPUs()) #define NUM_REDUCTION_WORKING_THREADS (num_CPUs()) #define IGNORE_BITFLIP_THRESHOLD 0.99 // ignore bitflip arrays which have nearly only valid states -#define STATE_FILES_DIRECTORY "hardnested/tables/" +#define STATE_FILES_DIRECTORY "hardnested_tables/" #define STATE_FILE_TEMPLATE "bitflip_%d_%03" PRIx16 "_states.bin.z" #define DEBUG_KEY_ELIMINATION @@ -248,10 +249,15 @@ static void init_bitflip_bitarrays(void) { bitflip_bitarrays[odd_even][bitflip] = NULL; count_bitflip_bitarrays[odd_even][bitflip] = 1 << 24; sprintf(state_file_name, STATE_FILE_TEMPLATE, odd_even, bitflip); - strcpy(state_files_path, get_my_executable_directory()); - strcat(state_files_path, STATE_FILES_DIRECTORY); + strcpy(state_files_path, STATE_FILES_DIRECTORY); strcat(state_files_path, state_file_name); - FILE *statesfile = fopen(state_files_path, "rb"); + char *path; + if (searchFile(&path, RESOURCES_SUBDIR, state_files_path, "", true) != PM3_SUCCESS) { + continue; + } + + FILE *statesfile = fopen(path, "rb"); + free(path); if (statesfile == NULL) { continue; } else { diff --git a/client/cmdscript.c b/client/cmdscript.c index 318cc1dd4..473477228 100644 --- a/client/cmdscript.c +++ b/client/cmdscript.c @@ -67,7 +67,7 @@ static int CmdScriptRun(const char *Cmd) { sscanf(Cmd, "%127s%n %255[^\n\r]%n", preferredName, &name_len, arguments, &arg_len); char *script_path; - int res = searchFile(&script_path, LUA_SCRIPTS_SUBDIR, preferredName, ".lua"); + int res = searchFile(&script_path, LUA_SCRIPTS_SUBDIR, preferredName, ".lua", false); if (res != PM3_SUCCESS) return res; diff --git a/client/cmdsmartcard.c b/client/cmdsmartcard.c index 4ea67be95..d6606ad19 100644 --- a/client/cmdsmartcard.c +++ b/client/cmdsmartcard.c @@ -100,7 +100,7 @@ static int smart_loadjson(const char *preferredName, json_t **root) { if (preferredName == NULL) return 1; char *path; - int res = searchFile(&path, RESOURCES_SUBDIR, preferredName, ".json"); + int res = searchFile(&path, RESOURCES_SUBDIR, preferredName, ".json", false); if (res != PM3_SUCCESS) { return PM3_EFILE; } diff --git a/client/crypto/asn1dump.c b/client/crypto/asn1dump.c index 140b0d2e2..91b04216a 100644 --- a/client/crypto/asn1dump.c +++ b/client/crypto/asn1dump.c @@ -241,7 +241,7 @@ static char *asn1_oid_description(const char *oid, bool with_group_desc) { memset(res, 0x00, sizeof(res)); char *path; - if (searchFile(&path, RESOURCES_SUBDIR, "oids", ".json") != PM3_SUCCESS) { + if (searchFile(&path, RESOURCES_SUBDIR, "oids", ".json", false) != PM3_SUCCESS) { return NULL; } diff --git a/client/emv/emv_pk.c b/client/emv/emv_pk.c index bb124c63c..8465a6e95 100644 --- a/client/emv/emv_pk.c +++ b/client/emv/emv_pk.c @@ -486,7 +486,7 @@ struct emv_pk *emv_pk_get_ca_pk(const unsigned char *rid, unsigned char idx) { } */ char *path; - if (searchFile(&path, RESOURCES_SUBDIR, "capk", ".txt") != PM3_SUCCESS) { + if (searchFile(&path, RESOURCES_SUBDIR, "capk", ".txt", false) != PM3_SUCCESS) { return NULL; } pk = emv_pk_get_ca_pk_from_file(path, rid, idx); diff --git a/client/emv/emvjson.c b/client/emv/emvjson.c index 715407a23..785b6b8e7 100644 --- a/client/emv/emvjson.c +++ b/client/emv/emvjson.c @@ -306,7 +306,7 @@ bool ParamLoadFromJson(struct tlvdb *tlv) { } char *path; - if (searchFile(&path, RESOURCES_SUBDIR, "emv_defparams", ".json") != PM3_SUCCESS) { + if (searchFile(&path, RESOURCES_SUBDIR, "emv_defparams", ".json", false) != PM3_SUCCESS) { return false; } root = json_load_file(path, 0, &error); diff --git a/client/fileutils.c b/client/fileutils.c index ae7531771..427ebd9da 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -405,7 +405,7 @@ out: int loadFile_safe(const char *preferredName, const char *suffix, void **pdata, size_t *datalen) { char *path; - int res = searchFile(&path, RESOURCES_SUBDIR, preferredName, suffix); + int res = searchFile(&path, RESOURCES_SUBDIR, preferredName, suffix, false); if (res != PM3_SUCCESS) { return PM3_EFILE; } @@ -634,7 +634,7 @@ int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, u if (data == NULL) return PM3_ESOFT; char *path; - if (searchFile(&path, DICTIONARIES_SUBDIR, preferredName, ".dic") != PM3_SUCCESS) + if (searchFile(&path, DICTIONARIES_SUBDIR, preferredName, ".dic", false) != PM3_SUCCESS) return PM3_EFILE; // t5577 == 4bytes @@ -701,7 +701,7 @@ int loadFileDICTIONARY_safe(const char *preferredName, void **pdata, uint8_t key int retval = PM3_SUCCESS; char *path; - if (searchFile(&path, DICTIONARIES_SUBDIR, preferredName, ".dic") != PM3_SUCCESS) + if (searchFile(&path, DICTIONARIES_SUBDIR, preferredName, ".dic", false) != PM3_SUCCESS) return PM3_EFILE; // t5577 == 4bytes @@ -863,19 +863,22 @@ int searchAndList(const char *pm3dir, const char *ext) { return PM3_SUCCESS; } -static int searchFinalFile(char **foundpath, const char *pm3dir, const char *searchname) { +static int searchFinalFile(char **foundpath, const char *pm3dir, const char *searchname, bool silent) { if ((foundpath == NULL) || (pm3dir == NULL) || (searchname == NULL)) return PM3_ESOFT; // explicit absolute (/) or relative path (./) => try only to match it directly char *filename = calloc(strlen(searchname) + 1, sizeof(char)); if (filename == NULL) return PM3_EMALLOC; strcpy(filename, searchname); - if (g_debugMode == 2) { + if ((g_debugMode == 2) && (!silent)) { PrintAndLogEx(INFO, "Searching %s", filename); } if (((strlen(filename) > 1) && (filename[0] == '/')) || ((strlen(filename) > 2) && (filename[0] == '.') && (filename[1] == '/'))) { if (fileExists(filename)) { *foundpath = filename; + if ((g_debugMode == 2) && (!silent)) { + PrintAndLogEx(INFO, "Found %s", *foundpath); + } return PM3_SUCCESS; } else { goto out; @@ -887,6 +890,9 @@ static int searchFinalFile(char **foundpath, const char *pm3dir, const char *sea { if (fileExists(filename)) { *foundpath = filename; + if ((g_debugMode == 2) && (!silent)) { + PrintAndLogEx(INFO, "Found %s", *foundpath); + } return PM3_SUCCESS; } } @@ -903,12 +909,15 @@ static int searchFinalFile(char **foundpath, const char *pm3dir, const char *sea strcpy(path, exec_path); strcat(path, pm3dir); strcat(path, filename); - if (g_debugMode == 2) { + if ((g_debugMode == 2) && (!silent)) { PrintAndLogEx(INFO, "Searching %s", path); } if (fileExists(path)) { free(filename); *foundpath = path; + if ((g_debugMode == 2) && (!silent)) { + PrintAndLogEx(INFO, "Found %s", *foundpath); + } return PM3_SUCCESS; } else { free(path); @@ -925,12 +934,15 @@ static int searchFinalFile(char **foundpath, const char *pm3dir, const char *sea strcat(path, above); strcat(path, pm3dir); strcat(path, filename); - if (g_debugMode == 2) { + if ((g_debugMode == 2) && (!silent)) { PrintAndLogEx(INFO, "Searching %s", path); } if (fileExists(path)) { free(filename); *foundpath = path; + if ((g_debugMode == 2) && (!silent)) { + PrintAndLogEx(INFO, "Found %s", *foundpath); + } return PM3_SUCCESS; } else { free(path); @@ -946,12 +958,15 @@ static int searchFinalFile(char **foundpath, const char *pm3dir, const char *sea strcat(path, PM3_USER_DIRECTORY); strcat(path, pm3dir); strcat(path, filename); - if (g_debugMode == 2) { + if ((g_debugMode == 2) && (!silent)) { PrintAndLogEx(INFO, "Searching %s", path); } if (fileExists(path)) { free(filename); *foundpath = path; + if ((g_debugMode == 2) && (!silent)) { + PrintAndLogEx(INFO, "Found %s", *foundpath); + } return PM3_SUCCESS; } else { free(path); @@ -965,12 +980,15 @@ static int searchFinalFile(char **foundpath, const char *pm3dir, const char *sea strcpy(path, PM3_SHARE_PATH); strcat(path, pm3dir); strcat(path, filename); - if (g_debugMode == 2) { + if ((g_debugMode == 2) && (!silent)) { PrintAndLogEx(INFO, "Searching %s", path); } if (fileExists(path)) { free(filename); *foundpath = path; + if ((g_debugMode == 2) && (!silent)) { + PrintAndLogEx(INFO, "Found %s", *foundpath); + } return PM3_SUCCESS; } else { free(path); @@ -981,14 +999,14 @@ out: return PM3_EFILE; } -int searchFile(char **foundpath, const char *pm3dir, const char *searchname, const char *suffix) { +int searchFile(char **foundpath, const char *pm3dir, const char *searchname, const char *suffix, bool silent) { if (foundpath == NULL) return PM3_EINVARG; char *filename = filenamemcopy(searchname, suffix); if (filename == NULL) return PM3_EMALLOC; - int res = searchFinalFile(foundpath, pm3dir, filename); + int res = searchFinalFile(foundpath, pm3dir, filename, silent); if (res != PM3_SUCCESS) { - if (res == PM3_EFILE) + if ((res == PM3_EFILE) && (!silent)) PrintAndLogEx(FAILED, "Error - can't find %s", filename); free(filename); return res; diff --git a/client/fileutils.h b/client/fileutils.h index d7fdb13a3..5432aa816 100644 --- a/client/fileutils.h +++ b/client/fileutils.h @@ -202,6 +202,6 @@ int loadFileDICTIONARY_safe(const char *preferredName, void **pdata, uint8_t key int convertOldMfuDump(uint8_t **dump, size_t *dumplen); int searchAndList(const char *pm3dir, const char *ext); -int searchFile(char **foundpath, const char *pm3dir, const char *searchname, const char *suffix); +int searchFile(char **foundpath, const char *pm3dir, const char *searchname, const char *suffix, bool silent); #endif // FILEUTILS_H diff --git a/client/hardnested/hardnested_bruteforce.c b/client/hardnested/hardnested_bruteforce.c index 96211f47f..3aea34a96 100644 --- a/client/hardnested/hardnested_bruteforce.c +++ b/client/hardnested/hardnested_bruteforce.c @@ -367,7 +367,7 @@ static bool read_bench_data(statelist_t *test_candidates) { uint32_t states_read = 0; char *path; - if (searchFile(&path, RESOURCES_SUBDIR, TEST_BENCH_FILENAME, "") != PM3_SUCCESS) { + if (searchFile(&path, RESOURCES_SUBDIR, TEST_BENCH_FILENAME, "", false) != PM3_SUCCESS) { return false; } diff --git a/client/hardnested/tables/bitflip_0_001_states.bin.z b/client/resources/hardnested_tables/bitflip_0_001_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_001_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_001_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_003_states.bin.z b/client/resources/hardnested_tables/bitflip_0_003_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_003_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_003_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_005_states.bin.z b/client/resources/hardnested_tables/bitflip_0_005_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_005_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_005_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_007_states.bin.z b/client/resources/hardnested_tables/bitflip_0_007_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_007_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_007_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_009_states.bin.z b/client/resources/hardnested_tables/bitflip_0_009_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_009_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_009_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_00b_states.bin.z b/client/resources/hardnested_tables/bitflip_0_00b_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_00b_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_00b_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_00d_states.bin.z b/client/resources/hardnested_tables/bitflip_0_00d_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_00d_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_00d_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_00f_states.bin.z b/client/resources/hardnested_tables/bitflip_0_00f_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_00f_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_00f_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_010_states.bin.z b/client/resources/hardnested_tables/bitflip_0_010_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_010_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_010_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_014_states.bin.z b/client/resources/hardnested_tables/bitflip_0_014_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_014_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_014_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_01c_states.bin.z b/client/resources/hardnested_tables/bitflip_0_01c_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_01c_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_01c_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_021_states.bin.z b/client/resources/hardnested_tables/bitflip_0_021_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_021_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_021_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_023_states.bin.z b/client/resources/hardnested_tables/bitflip_0_023_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_023_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_023_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_025_states.bin.z b/client/resources/hardnested_tables/bitflip_0_025_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_025_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_025_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_027_states.bin.z b/client/resources/hardnested_tables/bitflip_0_027_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_027_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_027_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_029_states.bin.z b/client/resources/hardnested_tables/bitflip_0_029_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_029_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_029_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_02b_states.bin.z b/client/resources/hardnested_tables/bitflip_0_02b_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_02b_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_02b_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_02d_states.bin.z b/client/resources/hardnested_tables/bitflip_0_02d_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_02d_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_02d_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_02f_states.bin.z b/client/resources/hardnested_tables/bitflip_0_02f_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_02f_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_02f_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_030_states.bin.z b/client/resources/hardnested_tables/bitflip_0_030_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_030_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_030_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_034_states.bin.z b/client/resources/hardnested_tables/bitflip_0_034_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_034_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_034_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_03c_states.bin.z b/client/resources/hardnested_tables/bitflip_0_03c_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_03c_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_03c_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_040_states.bin.z b/client/resources/hardnested_tables/bitflip_0_040_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_040_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_040_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_044_states.bin.z b/client/resources/hardnested_tables/bitflip_0_044_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_044_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_044_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_04c_states.bin.z b/client/resources/hardnested_tables/bitflip_0_04c_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_04c_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_04c_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_051_states.bin.z b/client/resources/hardnested_tables/bitflip_0_051_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_051_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_051_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_053_states.bin.z b/client/resources/hardnested_tables/bitflip_0_053_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_053_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_053_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_055_states.bin.z b/client/resources/hardnested_tables/bitflip_0_055_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_055_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_055_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_057_states.bin.z b/client/resources/hardnested_tables/bitflip_0_057_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_057_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_057_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_059_states.bin.z b/client/resources/hardnested_tables/bitflip_0_059_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_059_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_059_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_05b_states.bin.z b/client/resources/hardnested_tables/bitflip_0_05b_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_05b_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_05b_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_05d_states.bin.z b/client/resources/hardnested_tables/bitflip_0_05d_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_05d_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_05d_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_05f_states.bin.z b/client/resources/hardnested_tables/bitflip_0_05f_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_05f_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_05f_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_064_states.bin.z b/client/resources/hardnested_tables/bitflip_0_064_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_064_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_064_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_06c_states.bin.z b/client/resources/hardnested_tables/bitflip_0_06c_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_06c_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_06c_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_071_states.bin.z b/client/resources/hardnested_tables/bitflip_0_071_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_071_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_071_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_073_states.bin.z b/client/resources/hardnested_tables/bitflip_0_073_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_073_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_073_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_075_states.bin.z b/client/resources/hardnested_tables/bitflip_0_075_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_075_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_075_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_077_states.bin.z b/client/resources/hardnested_tables/bitflip_0_077_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_077_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_077_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_079_states.bin.z b/client/resources/hardnested_tables/bitflip_0_079_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_079_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_079_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_07b_states.bin.z b/client/resources/hardnested_tables/bitflip_0_07b_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_07b_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_07b_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_07f_states.bin.z b/client/resources/hardnested_tables/bitflip_0_07f_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_07f_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_07f_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_081_states.bin.z b/client/resources/hardnested_tables/bitflip_0_081_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_081_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_081_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_083_states.bin.z b/client/resources/hardnested_tables/bitflip_0_083_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_083_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_083_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_085_states.bin.z b/client/resources/hardnested_tables/bitflip_0_085_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_085_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_085_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_087_states.bin.z b/client/resources/hardnested_tables/bitflip_0_087_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_087_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_087_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_089_states.bin.z b/client/resources/hardnested_tables/bitflip_0_089_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_089_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_089_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_08b_states.bin.z b/client/resources/hardnested_tables/bitflip_0_08b_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_08b_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_08b_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_08d_states.bin.z b/client/resources/hardnested_tables/bitflip_0_08d_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_08d_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_08d_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_08f_states.bin.z b/client/resources/hardnested_tables/bitflip_0_08f_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_08f_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_08f_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_090_states.bin.z b/client/resources/hardnested_tables/bitflip_0_090_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_090_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_090_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_094_states.bin.z b/client/resources/hardnested_tables/bitflip_0_094_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_094_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_094_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_09c_states.bin.z b/client/resources/hardnested_tables/bitflip_0_09c_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_09c_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_09c_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0a1_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0a1_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0a1_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0a1_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0a3_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0a3_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0a3_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0a3_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0a5_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0a5_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0a5_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0a5_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0a7_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0a7_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0a7_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0a7_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0a9_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0a9_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0a9_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0a9_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0ab_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0ab_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0ab_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0ab_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0ad_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0ad_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0ad_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0ad_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0af_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0af_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0af_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0af_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0b0_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0b0_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0b0_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0b0_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0b4_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0b4_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0b4_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0b4_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0bc_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0bc_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0bc_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0bc_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0c0_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0c0_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0c0_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0c0_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0c4_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0c4_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0c4_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0c4_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0cc_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0cc_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0cc_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0cc_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0d1_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0d1_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0d1_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0d1_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0d3_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0d3_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0d3_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0d3_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0d5_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0d5_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0d5_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0d5_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0d7_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0d7_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0d7_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0d7_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0d9_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0d9_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0d9_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0d9_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0db_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0db_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0db_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0db_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0dd_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0dd_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0dd_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0dd_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0df_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0df_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0df_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0df_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0e4_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0e4_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0e4_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0e4_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0ec_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0ec_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0ec_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0ec_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0f1_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0f1_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0f1_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0f1_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0f3_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0f3_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0f3_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0f3_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0f5_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0f5_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0f5_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0f5_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0f7_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0f7_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0f7_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0f7_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0f9_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0f9_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0f9_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0f9_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0fb_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0fb_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0fb_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0fb_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0fd_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0fd_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0fd_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0fd_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0ff_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0ff_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0ff_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0ff_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_104_states.bin.z b/client/resources/hardnested_tables/bitflip_0_104_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_104_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_104_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_10c_states.bin.z b/client/resources/hardnested_tables/bitflip_0_10c_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_10c_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_10c_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_111_states.bin.z b/client/resources/hardnested_tables/bitflip_0_111_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_111_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_111_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_113_states.bin.z b/client/resources/hardnested_tables/bitflip_0_113_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_113_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_113_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_115_states.bin.z b/client/resources/hardnested_tables/bitflip_0_115_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_115_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_115_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_117_states.bin.z b/client/resources/hardnested_tables/bitflip_0_117_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_117_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_117_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_119_states.bin.z b/client/resources/hardnested_tables/bitflip_0_119_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_119_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_119_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_11b_states.bin.z b/client/resources/hardnested_tables/bitflip_0_11b_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_11b_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_11b_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_11d_states.bin.z b/client/resources/hardnested_tables/bitflip_0_11d_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_11d_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_11d_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_11f_states.bin.z b/client/resources/hardnested_tables/bitflip_0_11f_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_11f_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_11f_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_124_states.bin.z b/client/resources/hardnested_tables/bitflip_0_124_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_124_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_124_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_12c_states.bin.z b/client/resources/hardnested_tables/bitflip_0_12c_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_12c_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_12c_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_131_states.bin.z b/client/resources/hardnested_tables/bitflip_0_131_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_131_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_131_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_133_states.bin.z b/client/resources/hardnested_tables/bitflip_0_133_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_133_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_133_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_135_states.bin.z b/client/resources/hardnested_tables/bitflip_0_135_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_135_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_135_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_137_states.bin.z b/client/resources/hardnested_tables/bitflip_0_137_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_137_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_137_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_139_states.bin.z b/client/resources/hardnested_tables/bitflip_0_139_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_139_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_139_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_13b_states.bin.z b/client/resources/hardnested_tables/bitflip_0_13b_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_13b_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_13b_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_13d_states.bin.z b/client/resources/hardnested_tables/bitflip_0_13d_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_13d_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_13d_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_13f_states.bin.z b/client/resources/hardnested_tables/bitflip_0_13f_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_13f_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_13f_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_141_states.bin.z b/client/resources/hardnested_tables/bitflip_0_141_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_141_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_141_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_143_states.bin.z b/client/resources/hardnested_tables/bitflip_0_143_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_143_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_143_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_145_states.bin.z b/client/resources/hardnested_tables/bitflip_0_145_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_145_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_145_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_147_states.bin.z b/client/resources/hardnested_tables/bitflip_0_147_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_147_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_147_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_149_states.bin.z b/client/resources/hardnested_tables/bitflip_0_149_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_149_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_149_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_14b_states.bin.z b/client/resources/hardnested_tables/bitflip_0_14b_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_14b_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_14b_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_14d_states.bin.z b/client/resources/hardnested_tables/bitflip_0_14d_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_14d_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_14d_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_14f_states.bin.z b/client/resources/hardnested_tables/bitflip_0_14f_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_14f_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_14f_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_150_states.bin.z b/client/resources/hardnested_tables/bitflip_0_150_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_150_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_150_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_154_states.bin.z b/client/resources/hardnested_tables/bitflip_0_154_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_154_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_154_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_15c_states.bin.z b/client/resources/hardnested_tables/bitflip_0_15c_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_15c_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_15c_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_161_states.bin.z b/client/resources/hardnested_tables/bitflip_0_161_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_161_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_161_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_163_states.bin.z b/client/resources/hardnested_tables/bitflip_0_163_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_163_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_163_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_165_states.bin.z b/client/resources/hardnested_tables/bitflip_0_165_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_165_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_165_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_167_states.bin.z b/client/resources/hardnested_tables/bitflip_0_167_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_167_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_167_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_169_states.bin.z b/client/resources/hardnested_tables/bitflip_0_169_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_169_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_169_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_16b_states.bin.z b/client/resources/hardnested_tables/bitflip_0_16b_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_16b_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_16b_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_16d_states.bin.z b/client/resources/hardnested_tables/bitflip_0_16d_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_16d_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_16d_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_16f_states.bin.z b/client/resources/hardnested_tables/bitflip_0_16f_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_16f_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_16f_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_170_states.bin.z b/client/resources/hardnested_tables/bitflip_0_170_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_170_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_170_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_174_states.bin.z b/client/resources/hardnested_tables/bitflip_0_174_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_174_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_174_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_17c_states.bin.z b/client/resources/hardnested_tables/bitflip_0_17c_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_17c_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_17c_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_184_states.bin.z b/client/resources/hardnested_tables/bitflip_0_184_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_184_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_184_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_18c_states.bin.z b/client/resources/hardnested_tables/bitflip_0_18c_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_18c_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_18c_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_191_states.bin.z b/client/resources/hardnested_tables/bitflip_0_191_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_191_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_191_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_193_states.bin.z b/client/resources/hardnested_tables/bitflip_0_193_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_193_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_193_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_195_states.bin.z b/client/resources/hardnested_tables/bitflip_0_195_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_195_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_195_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_197_states.bin.z b/client/resources/hardnested_tables/bitflip_0_197_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_197_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_197_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_199_states.bin.z b/client/resources/hardnested_tables/bitflip_0_199_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_199_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_199_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_19b_states.bin.z b/client/resources/hardnested_tables/bitflip_0_19b_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_19b_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_19b_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_19d_states.bin.z b/client/resources/hardnested_tables/bitflip_0_19d_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_19d_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_19d_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_19f_states.bin.z b/client/resources/hardnested_tables/bitflip_0_19f_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_19f_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_19f_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_1a4_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1a4_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_1a4_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_1a4_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_1ac_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1ac_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_1ac_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_1ac_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_1b1_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1b1_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_1b1_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_1b1_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_1b3_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1b3_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_1b3_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_1b3_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_1b5_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1b5_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_1b5_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_1b5_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_1b7_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1b7_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_1b7_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_1b7_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_1b9_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1b9_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_1b9_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_1b9_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_1bb_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1bb_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_1bb_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_1bb_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_1bd_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1bd_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_1bd_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_1bd_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_1bf_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1bf_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_1bf_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_1bf_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_1c1_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1c1_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_1c1_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_1c1_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_1c3_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1c3_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_1c3_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_1c3_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_1c5_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1c5_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_1c5_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_1c5_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_1c9_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1c9_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_1c9_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_1c9_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_1cb_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1cb_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_1cb_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_1cb_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_1d0_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1d0_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_1d0_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_1d0_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_1d4_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1d4_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_1d4_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_1d4_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_1dc_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1dc_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_1dc_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_1dc_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_1e1_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1e1_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_1e1_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_1e1_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_1e3_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1e3_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_1e3_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_1e3_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_1e5_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1e5_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_1e5_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_1e5_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_1e7_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1e7_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_1e7_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_1e7_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_1e9_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1e9_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_1e9_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_1e9_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_1eb_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1eb_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_1eb_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_1eb_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_1ed_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1ed_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_1ed_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_1ed_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_1ef_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1ef_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_1ef_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_1ef_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_1f0_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1f0_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_1f0_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_1f0_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_1f4_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1f4_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_1f4_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_1f4_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_1fc_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1fc_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_1fc_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_1fc_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_210_states.bin.z b/client/resources/hardnested_tables/bitflip_0_210_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_210_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_210_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_225_states.bin.z b/client/resources/hardnested_tables/bitflip_0_225_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_225_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_225_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_227_states.bin.z b/client/resources/hardnested_tables/bitflip_0_227_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_227_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_227_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_22d_states.bin.z b/client/resources/hardnested_tables/bitflip_0_22d_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_22d_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_22d_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_22f_states.bin.z b/client/resources/hardnested_tables/bitflip_0_22f_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_22f_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_22f_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_240_states.bin.z b/client/resources/hardnested_tables/bitflip_0_240_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_240_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_240_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_275_states.bin.z b/client/resources/hardnested_tables/bitflip_0_275_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_275_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_275_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_277_states.bin.z b/client/resources/hardnested_tables/bitflip_0_277_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_277_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_277_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_27f_states.bin.z b/client/resources/hardnested_tables/bitflip_0_27f_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_27f_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_27f_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_294_states.bin.z b/client/resources/hardnested_tables/bitflip_0_294_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_294_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_294_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_2a1_states.bin.z b/client/resources/hardnested_tables/bitflip_0_2a1_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_2a1_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_2a1_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_2a3_states.bin.z b/client/resources/hardnested_tables/bitflip_0_2a3_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_2a3_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_2a3_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_2a9_states.bin.z b/client/resources/hardnested_tables/bitflip_0_2a9_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_2a9_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_2a9_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_2ab_states.bin.z b/client/resources/hardnested_tables/bitflip_0_2ab_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_2ab_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_2ab_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_2c4_states.bin.z b/client/resources/hardnested_tables/bitflip_0_2c4_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_2c4_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_2c4_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_2f1_states.bin.z b/client/resources/hardnested_tables/bitflip_0_2f1_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_2f1_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_2f1_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_2f3_states.bin.z b/client/resources/hardnested_tables/bitflip_0_2f3_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_2f3_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_2f3_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_2f9_states.bin.z b/client/resources/hardnested_tables/bitflip_0_2f9_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_2f9_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_2f9_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_2fb_states.bin.z b/client/resources/hardnested_tables/bitflip_0_2fb_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_2fb_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_2fb_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_335_states.bin.z b/client/resources/hardnested_tables/bitflip_0_335_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_335_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_335_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_337_states.bin.z b/client/resources/hardnested_tables/bitflip_0_337_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_337_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_337_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_33d_states.bin.z b/client/resources/hardnested_tables/bitflip_0_33d_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_33d_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_33d_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_33f_states.bin.z b/client/resources/hardnested_tables/bitflip_0_33f_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_33f_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_33f_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_350_states.bin.z b/client/resources/hardnested_tables/bitflip_0_350_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_350_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_350_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_365_states.bin.z b/client/resources/hardnested_tables/bitflip_0_365_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_365_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_365_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_367_states.bin.z b/client/resources/hardnested_tables/bitflip_0_367_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_367_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_367_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_36d_states.bin.z b/client/resources/hardnested_tables/bitflip_0_36d_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_36d_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_36d_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_36f_states.bin.z b/client/resources/hardnested_tables/bitflip_0_36f_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_36f_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_36f_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_384_states.bin.z b/client/resources/hardnested_tables/bitflip_0_384_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_384_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_384_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_3b1_states.bin.z b/client/resources/hardnested_tables/bitflip_0_3b1_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_3b1_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_3b1_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_3b3_states.bin.z b/client/resources/hardnested_tables/bitflip_0_3b3_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_3b3_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_3b3_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_3b9_states.bin.z b/client/resources/hardnested_tables/bitflip_0_3b9_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_3b9_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_3b9_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_3bb_states.bin.z b/client/resources/hardnested_tables/bitflip_0_3bb_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_3bb_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_3bb_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_3d4_states.bin.z b/client/resources/hardnested_tables/bitflip_0_3d4_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_3d4_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_3d4_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_3e1_states.bin.z b/client/resources/hardnested_tables/bitflip_0_3e1_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_3e1_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_3e1_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_3e3_states.bin.z b/client/resources/hardnested_tables/bitflip_0_3e3_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_3e3_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_3e3_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_3e9_states.bin.z b/client/resources/hardnested_tables/bitflip_0_3e9_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_3e9_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_3e9_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_3eb_states.bin.z b/client/resources/hardnested_tables/bitflip_0_3eb_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_3eb_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_3eb_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_002_states.bin.z b/client/resources/hardnested_tables/bitflip_1_002_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_002_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_002_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_008_states.bin.z b/client/resources/hardnested_tables/bitflip_1_008_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_008_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_008_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_00a_states.bin.z b/client/resources/hardnested_tables/bitflip_1_00a_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_00a_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_00a_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_012_states.bin.z b/client/resources/hardnested_tables/bitflip_1_012_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_012_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_012_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_018_states.bin.z b/client/resources/hardnested_tables/bitflip_1_018_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_018_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_018_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_01a_states.bin.z b/client/resources/hardnested_tables/bitflip_1_01a_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_01a_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_01a_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_020_states.bin.z b/client/resources/hardnested_tables/bitflip_1_020_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_020_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_020_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_028_states.bin.z b/client/resources/hardnested_tables/bitflip_1_028_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_028_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_028_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_02a_states.bin.z b/client/resources/hardnested_tables/bitflip_1_02a_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_02a_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_02a_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_02e_states.bin.z b/client/resources/hardnested_tables/bitflip_1_02e_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_02e_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_02e_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_032_states.bin.z b/client/resources/hardnested_tables/bitflip_1_032_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_032_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_032_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_036_states.bin.z b/client/resources/hardnested_tables/bitflip_1_036_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_036_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_036_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_038_states.bin.z b/client/resources/hardnested_tables/bitflip_1_038_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_038_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_038_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_03a_states.bin.z b/client/resources/hardnested_tables/bitflip_1_03a_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_03a_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_03a_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_03e_states.bin.z b/client/resources/hardnested_tables/bitflip_1_03e_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_03e_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_03e_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_040_states.bin.z b/client/resources/hardnested_tables/bitflip_1_040_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_040_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_040_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_042_states.bin.z b/client/resources/hardnested_tables/bitflip_1_042_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_042_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_042_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_046_states.bin.z b/client/resources/hardnested_tables/bitflip_1_046_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_046_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_046_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_048_states.bin.z b/client/resources/hardnested_tables/bitflip_1_048_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_048_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_048_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_04a_states.bin.z b/client/resources/hardnested_tables/bitflip_1_04a_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_04a_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_04a_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_04e_states.bin.z b/client/resources/hardnested_tables/bitflip_1_04e_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_04e_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_04e_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_052_states.bin.z b/client/resources/hardnested_tables/bitflip_1_052_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_052_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_052_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_056_states.bin.z b/client/resources/hardnested_tables/bitflip_1_056_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_056_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_056_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_058_states.bin.z b/client/resources/hardnested_tables/bitflip_1_058_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_058_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_058_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_05a_states.bin.z b/client/resources/hardnested_tables/bitflip_1_05a_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_05a_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_05a_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_05e_states.bin.z b/client/resources/hardnested_tables/bitflip_1_05e_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_05e_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_05e_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_060_states.bin.z b/client/resources/hardnested_tables/bitflip_1_060_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_060_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_060_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_062_states.bin.z b/client/resources/hardnested_tables/bitflip_1_062_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_062_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_062_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_066_states.bin.z b/client/resources/hardnested_tables/bitflip_1_066_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_066_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_066_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_068_states.bin.z b/client/resources/hardnested_tables/bitflip_1_068_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_068_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_068_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_06a_states.bin.z b/client/resources/hardnested_tables/bitflip_1_06a_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_06a_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_06a_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_06e_states.bin.z b/client/resources/hardnested_tables/bitflip_1_06e_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_06e_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_06e_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_072_states.bin.z b/client/resources/hardnested_tables/bitflip_1_072_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_072_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_072_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_076_states.bin.z b/client/resources/hardnested_tables/bitflip_1_076_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_076_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_076_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_078_states.bin.z b/client/resources/hardnested_tables/bitflip_1_078_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_078_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_078_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_07a_states.bin.z b/client/resources/hardnested_tables/bitflip_1_07a_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_07a_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_07a_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_07e_states.bin.z b/client/resources/hardnested_tables/bitflip_1_07e_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_07e_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_07e_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_080_states.bin.z b/client/resources/hardnested_tables/bitflip_1_080_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_080_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_080_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_082_states.bin.z b/client/resources/hardnested_tables/bitflip_1_082_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_082_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_082_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_086_states.bin.z b/client/resources/hardnested_tables/bitflip_1_086_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_086_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_086_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_088_states.bin.z b/client/resources/hardnested_tables/bitflip_1_088_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_088_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_088_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_08a_states.bin.z b/client/resources/hardnested_tables/bitflip_1_08a_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_08a_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_08a_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_08e_states.bin.z b/client/resources/hardnested_tables/bitflip_1_08e_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_08e_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_08e_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_092_states.bin.z b/client/resources/hardnested_tables/bitflip_1_092_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_092_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_092_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_096_states.bin.z b/client/resources/hardnested_tables/bitflip_1_096_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_096_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_096_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_098_states.bin.z b/client/resources/hardnested_tables/bitflip_1_098_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_098_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_098_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_09a_states.bin.z b/client/resources/hardnested_tables/bitflip_1_09a_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_09a_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_09a_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_09e_states.bin.z b/client/resources/hardnested_tables/bitflip_1_09e_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_09e_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_09e_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_0a0_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0a0_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_0a0_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_0a0_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_0a2_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0a2_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_0a2_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_0a2_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_0a6_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0a6_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_0a6_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_0a6_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_0a8_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0a8_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_0a8_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_0a8_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_0aa_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0aa_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_0aa_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_0aa_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_0ae_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0ae_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_0ae_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_0ae_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_0b2_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0b2_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_0b2_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_0b2_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_0b6_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0b6_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_0b6_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_0b6_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_0b8_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0b8_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_0b8_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_0b8_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_0ba_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0ba_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_0ba_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_0ba_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_0be_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0be_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_0be_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_0be_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_0c0_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0c0_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_0c0_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_0c0_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_0c2_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0c2_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_0c2_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_0c2_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_0c6_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0c6_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_0c6_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_0c6_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_0c8_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0c8_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_0c8_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_0c8_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_0ca_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0ca_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_0ca_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_0ca_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_0ce_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0ce_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_0ce_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_0ce_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_0d2_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0d2_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_0d2_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_0d2_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_0d6_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0d6_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_0d6_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_0d6_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_0d8_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0d8_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_0d8_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_0d8_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_0da_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0da_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_0da_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_0da_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_0de_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0de_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_0de_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_0de_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_0e0_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0e0_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_0e0_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_0e0_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_0e8_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0e8_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_0e8_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_0e8_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_0f8_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0f8_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_0f8_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_0f8_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_108_states.bin.z b/client/resources/hardnested_tables/bitflip_1_108_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_108_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_108_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_111_states.bin.z b/client/resources/hardnested_tables/bitflip_1_111_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_111_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_111_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_113_states.bin.z b/client/resources/hardnested_tables/bitflip_1_113_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_113_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_113_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_115_states.bin.z b/client/resources/hardnested_tables/bitflip_1_115_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_115_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_115_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_117_states.bin.z b/client/resources/hardnested_tables/bitflip_1_117_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_117_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_117_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_118_states.bin.z b/client/resources/hardnested_tables/bitflip_1_118_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_118_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_118_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_11a_states.bin.z b/client/resources/hardnested_tables/bitflip_1_11a_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_11a_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_11a_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_11b_states.bin.z b/client/resources/hardnested_tables/bitflip_1_11b_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_11b_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_11b_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_120_states.bin.z b/client/resources/hardnested_tables/bitflip_1_120_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_120_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_120_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_122_states.bin.z b/client/resources/hardnested_tables/bitflip_1_122_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_122_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_122_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_128_states.bin.z b/client/resources/hardnested_tables/bitflip_1_128_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_128_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_128_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_131_states.bin.z b/client/resources/hardnested_tables/bitflip_1_131_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_131_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_131_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_135_states.bin.z b/client/resources/hardnested_tables/bitflip_1_135_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_135_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_135_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_138_states.bin.z b/client/resources/hardnested_tables/bitflip_1_138_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_138_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_138_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_145_states.bin.z b/client/resources/hardnested_tables/bitflip_1_145_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_145_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_145_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_147_states.bin.z b/client/resources/hardnested_tables/bitflip_1_147_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_147_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_147_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_148_states.bin.z b/client/resources/hardnested_tables/bitflip_1_148_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_148_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_148_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_158_states.bin.z b/client/resources/hardnested_tables/bitflip_1_158_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_158_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_158_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_160_states.bin.z b/client/resources/hardnested_tables/bitflip_1_160_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_160_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_160_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_161_states.bin.z b/client/resources/hardnested_tables/bitflip_1_161_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_161_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_161_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_163_states.bin.z b/client/resources/hardnested_tables/bitflip_1_163_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_163_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_163_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_165_states.bin.z b/client/resources/hardnested_tables/bitflip_1_165_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_165_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_165_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_168_states.bin.z b/client/resources/hardnested_tables/bitflip_1_168_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_168_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_168_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_178_states.bin.z b/client/resources/hardnested_tables/bitflip_1_178_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_178_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_178_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_180_states.bin.z b/client/resources/hardnested_tables/bitflip_1_180_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_180_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_180_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_188_states.bin.z b/client/resources/hardnested_tables/bitflip_1_188_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_188_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_188_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_191_states.bin.z b/client/resources/hardnested_tables/bitflip_1_191_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_191_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_191_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_198_states.bin.z b/client/resources/hardnested_tables/bitflip_1_198_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_198_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_198_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_199_states.bin.z b/client/resources/hardnested_tables/bitflip_1_199_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_199_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_199_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_19d_states.bin.z b/client/resources/hardnested_tables/bitflip_1_19d_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_19d_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_19d_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_19f_states.bin.z b/client/resources/hardnested_tables/bitflip_1_19f_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_19f_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_19f_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_1a0_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1a0_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_1a0_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_1a0_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_1a8_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1a8_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_1a8_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_1a8_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_1b3_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1b3_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_1b3_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_1b3_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_1b5_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1b5_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_1b5_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_1b5_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_1b7_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1b7_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_1b7_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_1b7_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_1b8_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1b8_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_1b8_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_1b8_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_1b9_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1b9_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_1b9_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_1b9_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_1bd_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1bd_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_1bd_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_1bd_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_1c1_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1c1_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_1c1_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_1c1_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_1c3_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1c3_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_1c3_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_1c3_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_1c8_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1c8_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_1c8_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_1c8_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_1c9_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1c9_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_1c9_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_1c9_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_1cd_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1cd_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_1cd_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_1cd_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_1cf_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1cf_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_1cf_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_1cf_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_1d8_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1d8_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_1d8_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_1d8_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_1e0_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1e0_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_1e0_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_1e0_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_1e1_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1e1_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_1e1_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_1e1_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_1e5_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1e5_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_1e5_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_1e5_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_1e7_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1e7_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_1e7_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_1e7_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_1e8_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1e8_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_1e8_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_1e8_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_1e9_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1e9_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_1e9_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_1e9_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_1eb_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1eb_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_1eb_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_1eb_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_1ed_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1ed_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_1ed_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_1ed_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_1f8_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1f8_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_1f8_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_1f8_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_208_states.bin.z b/client/resources/hardnested_tables/bitflip_1_208_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_208_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_208_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_220_states.bin.z b/client/resources/hardnested_tables/bitflip_1_220_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_220_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_220_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_24a_states.bin.z b/client/resources/hardnested_tables/bitflip_1_24a_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_24a_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_24a_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_24e_states.bin.z b/client/resources/hardnested_tables/bitflip_1_24e_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_24e_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_24e_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_25a_states.bin.z b/client/resources/hardnested_tables/bitflip_1_25a_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_25a_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_25a_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_25e_states.bin.z b/client/resources/hardnested_tables/bitflip_1_25e_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_25e_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_25e_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_262_states.bin.z b/client/resources/hardnested_tables/bitflip_1_262_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_262_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_262_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_266_states.bin.z b/client/resources/hardnested_tables/bitflip_1_266_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_266_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_266_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_272_states.bin.z b/client/resources/hardnested_tables/bitflip_1_272_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_272_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_272_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_276_states.bin.z b/client/resources/hardnested_tables/bitflip_1_276_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_276_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_276_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_280_states.bin.z b/client/resources/hardnested_tables/bitflip_1_280_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_280_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_280_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_2a8_states.bin.z b/client/resources/hardnested_tables/bitflip_1_2a8_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_2a8_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_2a8_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_2c2_states.bin.z b/client/resources/hardnested_tables/bitflip_1_2c2_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_2c2_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_2c2_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_2c6_states.bin.z b/client/resources/hardnested_tables/bitflip_1_2c6_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_2c6_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_2c6_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_2d2_states.bin.z b/client/resources/hardnested_tables/bitflip_1_2d2_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_2d2_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_2d2_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_2d6_states.bin.z b/client/resources/hardnested_tables/bitflip_1_2d6_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_2d6_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_2d6_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_328_states.bin.z b/client/resources/hardnested_tables/bitflip_1_328_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_328_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_328_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_388_states.bin.z b/client/resources/hardnested_tables/bitflip_1_388_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_388_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_388_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_3a0_states.bin.z b/client/resources/hardnested_tables/bitflip_1_3a0_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_3a0_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_3a0_states.bin.z From a78839a644fbc509742974efeef068548f8570d5 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 30 Aug 2019 10:28:56 +0200 Subject: [PATCH 0530/1854] make os -> make fullimage --- Makefile | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/Makefile b/Makefile index 9be67311b..52793c104 100644 --- a/Makefile +++ b/Makefile @@ -58,29 +58,30 @@ recovery/%: FORCE cleanifplatformchanged bootrom/% armsrc/% $(Q)$(MAKE) --no-print-directory -C recovery $(patsubst recovery/%,%,$@) FORCE: # Dummy target to force remake in the subdirectories, even if files exist (this Makefile doesn't know about the prerequisites) -.PHONY: all clean help _test bootrom flash-bootrom os flash-os flash-all recovery client mfkey nonce2key style checks FORCE udev accessrights cleanifplatformchanged +.PHONY: all clean help _test bootrom flash-bootrom fullimage flash-fullimage flash-all recovery client mfkey nonce2key style checks FORCE udev accessrights cleanifplatformchanged help: @echo "Multi-OS Makefile" @echo @echo "Possible targets:" - @echo "+ all - Make all targets: bootrom, armsrc and OS-specific host tools" - @echo "+ clean - Clean in all targets" + @echo "+ all - Make all targets: bootrom, fullimage and OS-specific host tools" + @echo "+ clean - Clean in all targets" + @echo "+ .../clean - Clean in specified target and its deps, e.g. bootrom/clean" @echo - @echo "+ bootrom - Make bootrom" - @echo "+ os - Make armsrc (includes fpga)" - @echo "+ flash-bootrom - Make bootrom and flash it" - @echo "+ flash-os - Make armsrc and flash os image (includes fpga)" - @echo "+ flash-all - Make bootrom and armsrc and flash bootrom and os image" - @echo "+ recovery - Make bootrom and armsrc images for JTAG flashing" + @echo "+ bootrom - Make bootrom" + @echo "+ fullimage - Make armsrc fullimage (includes fpga)" + @echo "+ flash-bootrom - Make and flash bootrom" + @echo "+ flash-fullimage - Make and flash fullimage" + @echo "+ flash-all - Make and flash bootrom and fullimage" + @echo "+ recovery - Make bootrom and fullimage files for JTAG flashing" @echo - @echo "+ client - Make only the OS-specific host client" - @echo "+ mfkey - Make tools/mfkey" - @echo "+ nonce2key - Make tools/nonce2key" - @echo "+ fpga_compress - Make tools/fpga_compress" + @echo "+ client - Make only the OS-specific host client" + @echo "+ mfkey - Make tools/mfkey" + @echo "+ nonce2key - Make tools/nonce2key" + @echo "+ fpga_compress - Make tools/fpga_compress" @echo - @echo "+ style - Apply some automated source code formatting rules" - @echo "+ checks - Detect various encoding issues in source code" + @echo "+ style - Apply some automated source code formatting rules" + @echo "+ checks - Detect various encoding issues in source code" @echo @echo "Possible platforms: try \"make PLATFORM=\" for more info, default is PM3RDV4" @echo "To activate verbose mode, use make V=1" @@ -89,7 +90,9 @@ client: client/all bootrom: bootrom/all -os: armsrc/all +fullimage: armsrc/all + +fullimage/clean: armsrc/clean recovery: recovery/all @@ -102,7 +105,7 @@ fpga_compress: fpga_compress/all flash-bootrom: bootrom/obj/bootrom.elf $(FLASH_TOOL) $(FLASH_TOOL) $(FLASH_PORT) -b $(subst /,$(PATHSEP),$<) -flash-os: armsrc/obj/fullimage.elf $(FLASH_TOOL) +flash-fullimage: armsrc/obj/fullimage.elf $(FLASH_TOOL) $(FLASH_TOOL) $(FLASH_PORT) $(subst /,$(PATHSEP),$<) flash-all: bootrom/obj/bootrom.elf armsrc/obj/fullimage.elf $(FLASH_TOOL) From b5e1408e4cc125f83ff25ecc75d56beb3f7d598f Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 30 Aug 2019 10:35:41 +0200 Subject: [PATCH 0531/1854] fix pm3test.sh --- pm3test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pm3test.sh b/pm3test.sh index 119fffbb8..8785bf8df 100755 --- a/pm3test.sh +++ b/pm3test.sh @@ -80,7 +80,7 @@ while true; do if ! CheckFileExist "proxmark3 exists" "./client/proxmark3"; then break; fi if ! CheckFileExist "arm image exists" "./armsrc/obj/fullimage.elf"; then break; fi if ! CheckFileExist "bootrom exists" "./bootrom/obj/bootrom.elf"; then break; fi - if ! CheckFileExist "hardnested tables exists" "./client/hardnested/tables/*.z"; then break; fi + if ! CheckFileExist "hardnested tables exists" "./client/resources/hardnested_tables/*.z"; then break; fi printf "\n${C_BLUE}Testing basic help:${C_NC}\n" if ! CheckExecute "proxmark help" "./client/proxmark3 -h" "wait"; then break; fi From 99159b3cda735fa510eac4cf6d5639fad9f5fc6e Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 30 Aug 2019 10:40:02 +0200 Subject: [PATCH 0532/1854] remove makefile flash targets, better to use provided scripts or direct calls to flasher --- Makefile | 38 +------------------------------------- 1 file changed, 1 insertion(+), 37 deletions(-) diff --git a/Makefile b/Makefile index 52793c104..7ca9e313f 100644 --- a/Makefile +++ b/Makefile @@ -5,30 +5,6 @@ endif # To see full command lines, use make V=1 GZIP=gzip -# Windows' echo echos its input verbatim, on Posix there is some -# amount of shell command line parsing going on. echo "" on -# Windows yields literal "", on Linux yields an empty line -ifeq ($(shell echo ""),) - # This is probably a proper system, so we can use uname - DELETE=rm -rf - FLASH_TOOL=client/flasher - platform=$(shell uname) - ifneq (,$(findstring MINGW,$(platform))) - FLASH_PORT=com3 - PATHSEP=\\# - else - FLASH_PORT=/dev/ttyACM0 - PATHSEP=/ - endif -else - # Assume that we are running on native Windows - DELETE=del /q - FLASH_TOOL=client/flasher.exe - platform=Windows - FLASH_PORT=com3 - PATHSEP=\\# -endif - -include Makefile.platform -include .Makefile.options.cache include common_arm/Makefile.hal @@ -58,7 +34,7 @@ recovery/%: FORCE cleanifplatformchanged bootrom/% armsrc/% $(Q)$(MAKE) --no-print-directory -C recovery $(patsubst recovery/%,%,$@) FORCE: # Dummy target to force remake in the subdirectories, even if files exist (this Makefile doesn't know about the prerequisites) -.PHONY: all clean help _test bootrom flash-bootrom fullimage flash-fullimage flash-all recovery client mfkey nonce2key style checks FORCE udev accessrights cleanifplatformchanged +.PHONY: all clean help _test bootrom fullimage recovery client mfkey nonce2key style checks FORCE udev accessrights cleanifplatformchanged help: @echo "Multi-OS Makefile" @@ -70,9 +46,6 @@ help: @echo @echo "+ bootrom - Make bootrom" @echo "+ fullimage - Make armsrc fullimage (includes fpga)" - @echo "+ flash-bootrom - Make and flash bootrom" - @echo "+ flash-fullimage - Make and flash fullimage" - @echo "+ flash-all - Make and flash bootrom and fullimage" @echo "+ recovery - Make bootrom and fullimage files for JTAG flashing" @echo @echo "+ client - Make only the OS-specific host client" @@ -102,15 +75,6 @@ nonce2key: nonce2key/all fpga_compress: fpga_compress/all -flash-bootrom: bootrom/obj/bootrom.elf $(FLASH_TOOL) - $(FLASH_TOOL) $(FLASH_PORT) -b $(subst /,$(PATHSEP),$<) - -flash-fullimage: armsrc/obj/fullimage.elf $(FLASH_TOOL) - $(FLASH_TOOL) $(FLASH_PORT) $(subst /,$(PATHSEP),$<) - -flash-all: bootrom/obj/bootrom.elf armsrc/obj/fullimage.elf $(FLASH_TOOL) - $(FLASH_TOOL) $(FLASH_PORT) -b $(subst /,$(PATHSEP),$(filter-out $(FLASH_TOOL),$^)) - newtarbin: $(DELETE) proxmark3-$(platform)-bin.tar proxmark3-$(platform)-bin.tar.gz @touch proxmark3-$(platform)-bin.tar From 2022df10680cd245ae27a711402e8571679b373a Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 30 Aug 2019 10:45:52 +0200 Subject: [PATCH 0533/1854] make style --- armsrc/appmain.c | 2 +- armsrc/iclass.c | 18 ++--- armsrc/mifarecmd.c | 78 +++++++++--------- client/cmdhficlass.c | 92 +++++++++++----------- client/cmdhfmf.c | 148 +++++++++++++++++------------------ client/cmdlft55xx.c | 4 +- client/fileutils.c | 25 +++--- client/loclass/elite_crack.c | 2 +- client/loclass/ikeys.c | 14 ++-- client/mifare/mifarehost.c | 2 +- client/ui.c | 6 +- include/pm3_cmd.h | 6 +- 12 files changed, 199 insertions(+), 198 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 13aa6bc84..c789f6aac 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1134,7 +1134,7 @@ static void PacketReceived(PacketCommandNG *packet) { break; } case CMD_HF_MIFARE_EML_LOAD: { - mfc_eload_t *payload = (mfc_eload_t *) packet->data.asBytes; + mfc_eload_t *payload = (mfc_eload_t *) packet->data.asBytes; MifareECardLoadExt(payload->sectorcnt, payload->keytype); break; } diff --git a/armsrc/iclass.c b/armsrc/iclass.c index b550158cc..b63c696d6 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -59,7 +59,7 @@ static int g_wait = 300; static int timeout = 2900; static uint32_t time_rdr = 0; static uint32_t time_delta = 0; -static uint32_t time_delta_wait = 0; +static uint32_t time_delta_wait = 0; static uint32_t time_response = 0; static int SendIClassAnswer(uint8_t *resp, int respLen, uint16_t delay); @@ -1875,15 +1875,15 @@ static int GetIClassAnswer(uint8_t *receivedResponse, int maxLen, int *samples, } // keep tx buffer in a defined state anyway. -/* - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { - AT91C_BASE_SSC->SSC_THR = 0x00; - } -*/ + /* + if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { + AT91C_BASE_SSC->SSC_THR = 0x00; + } + */ // Wait for byte be become available in rx holding register if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { - if ( GetCountSspClk() - foo > timeout) return false; + if (GetCountSspClk() - foo > timeout) return false; // if (c >= timeout) return false; c++; @@ -1896,7 +1896,7 @@ static int GetIClassAnswer(uint8_t *receivedResponse, int maxLen, int *samples, if (ManchesterDecoding_iclass(b & 0x0f)) { if (samples) *samples = c << 3; - + time_response = GetCountSspClk() - foo; return true; } @@ -1959,7 +1959,7 @@ bool sendCmdGetResponseWithRetries(uint8_t *command, size_t cmdsize, uint8_t *re // since its called with fixed sized arrays // update/write commadn takes 4ms to 15ms before responding - if ( command[0] == ICLASS_CMD_UPDATE ) + if (command[0] == ICLASS_CMD_UPDATE) g_wait = 15000; uint8_t got_n = ReaderReceiveIClass(resp); diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 17570e680..e8263d52a 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -1523,33 +1523,33 @@ OUT: FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); BigBuf_free(); BigBuf_Clear_ext(false); - - // special trick ecfill - if (use_flashmem && foundkeys == allkeys) { - - uint8_t block[16] = {0}; - for (int i = 0; i < sectorcnt; i++) { - - uint8_t blockno; - if (i < 32) { - blockno = (i * 4) ^ 0x3; - } else { - blockno = (32 * 4 + (i - 32) * 16) ^ 0xF; - } - // get ST - emlGetMem(block, blockno, 1); - memcpy(block, k_sector[i].keyA, 6); - memcpy(block + 10, k_sector[i].keyB, 6); - - emlSetMem_xt(block, blockno, 1, sizeof(block)); - } - int oldbg = DBGLEVEL; - DBGLEVEL = DBG_NONE; - MifareECardLoad(sectorcnt, 0); - MifareECardLoad(sectorcnt, 1); - DBGLEVEL = oldbg; - } + // special trick ecfill + if (use_flashmem && foundkeys == allkeys) { + + uint8_t block[16] = {0}; + for (int i = 0; i < sectorcnt; i++) { + + uint8_t blockno; + if (i < 32) { + blockno = (i * 4) ^ 0x3; + } else { + blockno = (32 * 4 + (i - 32) * 16) ^ 0xF; + } + // get ST + emlGetMem(block, blockno, 1); + + memcpy(block, k_sector[i].keyA, 6); + memcpy(block + 10, k_sector[i].keyB, 6); + + emlSetMem_xt(block, blockno, 1, sizeof(block)); + } + int oldbg = DBGLEVEL; + DBGLEVEL = DBG_NONE; + MifareECardLoad(sectorcnt, 0); + MifareECardLoad(sectorcnt, 1); + DBGLEVEL = oldbg; + } } else { // partial/none keys found reply_mix(CMD_ACK, foundkeys, 0, 0, 0, 0); @@ -1695,9 +1695,9 @@ void MifareEMemGet(uint8_t blockno, uint8_t blockcnt) { // //----------------------------------------------------------------------------- int MifareECardLoadExt(uint8_t numSectors, uint8_t keyType) { - int retval = MifareECardLoad(numSectors, keyType); - reply_ng(CMD_HF_MIFARE_EML_LOAD, retval, NULL, 0); - return retval; + int retval = MifareECardLoad(numSectors, keyType); + reply_ng(CMD_HF_MIFARE_EML_LOAD, retval, NULL, 0); + return retval; } int MifareECardLoad(uint8_t numSectors, uint8_t keyType) { @@ -1723,7 +1723,7 @@ int MifareECardLoad(uint8_t numSectors, uint8_t keyType) { if (!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) { retval = PM3_ESOFT; if (DBGLEVEL > DBG_ERROR) Dbprintf("Can't select card"); - goto out; + goto out; } for (uint8_t sectorNo = 0; sectorNo < numSectors; sectorNo++) { @@ -1747,22 +1747,22 @@ int MifareECardLoad(uint8_t numSectors, uint8_t keyType) { if (DBGLEVEL > DBG_ERROR) Dbprintf("Error reading sector %2d block %2d", sectorNo, blockNo); break; } - if (blockNo < NumBlocksPerSector(sectorNo) - 1) { - emlSetMem(dataoutbuf, FirstBlockOfSector(sectorNo) + blockNo, 1); - } else { // sector trailer, keep the keys, set only the AC - emlGetMem(dataoutbuf2, FirstBlockOfSector(sectorNo) + blockNo, 1); - memcpy(&dataoutbuf2[6], &dataoutbuf[6], 4); - emlSetMem(dataoutbuf2, FirstBlockOfSector(sectorNo) + blockNo, 1); - } + if (blockNo < NumBlocksPerSector(sectorNo) - 1) { + emlSetMem(dataoutbuf, FirstBlockOfSector(sectorNo) + blockNo, 1); + } else { // sector trailer, keep the keys, set only the AC + emlGetMem(dataoutbuf2, FirstBlockOfSector(sectorNo) + blockNo, 1); + memcpy(&dataoutbuf2[6], &dataoutbuf[6], 4); + emlSetMem(dataoutbuf2, FirstBlockOfSector(sectorNo) + blockNo, 1); } } + } if (mifare_classic_halt(pcs, cuid)) { if (DBGLEVEL > DBG_ERROR) Dbprintf("Halt error"); - } + } - if (DBGLEVEL >= DBG_INFO) DbpString("Emulator fill sectors finished"); + if (DBGLEVEL >= DBG_INFO) DbpString("Emulator fill sectors finished"); out: crypto1_destroy(pcs); diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index f5406e8e7..39fbf9658 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -696,7 +696,7 @@ static int CmdHFiClassELoad(const char *Cmd) { return usage_hf_iclass_eload(); case 'f': if (param_getstr(Cmd, cmdp + 1, filename, FILE_PATH_SIZE) >= FILE_PATH_SIZE) { - PrintAndLogEx(FAILED, "Filename too long"); + PrintAndLogEx(FAILED, "Filename too long"); errors = true; break; } @@ -704,12 +704,12 @@ static int CmdHFiClassELoad(const char *Cmd) { break; case 'j': dftype = JSON; - cmdp++; - break; + cmdp++; + break; case 'e': - dftype = EML; - cmdp++; - break; + dftype = EML; + cmdp++; + break; default: PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); errors = true; @@ -733,9 +733,9 @@ static int CmdHFiClassELoad(const char *Cmd) { size_t bytes_read = 2048; int res = 0; - switch ( dftype ) { + switch (dftype) { case BIN: { - res = loadFile(filename, ".bin", (void*)&dump, 2048, &bytes_read); + res = loadFile(filename, ".bin", (void *)&dump, 2048, &bytes_read); break; } case EML: { @@ -747,11 +747,11 @@ static int CmdHFiClassELoad(const char *Cmd) { break; } default: - PrintAndLogEx(ERR, "No dictionary loaded"); - return PM3_ESOFT; + PrintAndLogEx(ERR, "No dictionary loaded"); + return PM3_ESOFT; } - if ( res != PM3_SUCCESS ) { + if (res != PM3_SUCCESS) { free(dump); return PM3_EFILE; } @@ -793,15 +793,15 @@ static int CmdHFiClassELoad(const char *Cmd) { #define ICLASS_DECRYPTION_BIN "iclass_decryptionkey.bin" static int CmdHFiClassDecrypt(const char *Cmd) { - + bool errors = false; bool have_key = false; uint8_t cmdp = 0; - + size_t keylen = 0; uint8_t key[32] = {0}; uint8_t *keyptr = NULL; - + size_t decryptedlen = 0; uint8_t *decrypted = NULL; char filename[FILE_PATH_SIZE]; @@ -811,13 +811,13 @@ static int CmdHFiClassDecrypt(const char *Cmd) { case 'h': return usage_hf_iclass_decrypt(); case 'f': - if ( param_getstr(Cmd, cmdp + 1, filename, sizeof(filename) ) == 0) { + if (param_getstr(Cmd, cmdp + 1, filename, sizeof(filename)) == 0) { PrintAndLogEx(WARNING, "no filename found after f"); errors = true; break; } - if ( loadFile_safe(filename, "", (void**)&decrypted, &decryptedlen) != PM3_SUCCESS ) { + if (loadFile_safe(filename, "", (void **)&decrypted, &decryptedlen) != PM3_SUCCESS) { errors = true; break; } @@ -840,11 +840,11 @@ static int CmdHFiClassDecrypt(const char *Cmd) { if (errors || cmdp < 1) return usage_hf_iclass_decrypt(); - if ( have_key == false ) { - int res = loadFile_safe(ICLASS_DECRYPTION_BIN, "", (void**)&keyptr, &keylen); + if (have_key == false) { + int res = loadFile_safe(ICLASS_DECRYPTION_BIN, "", (void **)&keyptr, &keylen); if (res != PM3_SUCCESS) return PM3_EINVARG; - + memcpy(key, keyptr, sizeof(key)); } @@ -857,7 +857,7 @@ static int CmdHFiClassDecrypt(const char *Cmd) { uint8_t app_areas = 2; uint8_t max_blk = 31; getMemConfig(mem, chip, &max_blk, &app_areas, &kb); - + // tripledes mbedtls_des3_context ctx; mbedtls_des3_set2key_dec(&ctx, key); @@ -876,10 +876,10 @@ static int CmdHFiClassDecrypt(const char *Cmd) { } //Use the first block (CSN) for filename - char *fptr = calloc(42, sizeof(uint8_t)); + char *fptr = calloc(42, sizeof(uint8_t)); strcat(fptr, "hf-iclass-"); - FillFileNameByUID(fptr, hdr->csn, "-data-decrypted", sizeof(hdr->csn) ); - + FillFileNameByUID(fptr, hdr->csn, "-data-decrypted", sizeof(hdr->csn)); + saveFile(fptr, ".bin", decrypted, decryptedlen); saveFileEML(fptr, decrypted, decryptedlen, 8); saveFileJSON(fptr, jsfIclass, decrypted, decryptedlen); @@ -935,12 +935,12 @@ static int CmdHFiClassEncryptBlk(const char *Cmd) { if (errors || cmdp < 1) return usage_hf_iclass_encrypt(); - if ( have_key == false ) { + if (have_key == false) { size_t keylen = 0; - int res = loadFile_safe(ICLASS_DECRYPTION_BIN, "", (void**)&keyptr, &keylen); + int res = loadFile_safe(ICLASS_DECRYPTION_BIN, "", (void **)&keyptr, &keylen); if (res != PM3_SUCCESS) return PM3_EINVARG; - + memcpy(key, keyptr, sizeof(key)); } @@ -1265,7 +1265,7 @@ static int CmdHFiClassReader_Dump(const char *Cmd) { //Use the first block (CSN) for filename strcat(filename, "hf-iclass-"); - FillFileNameByUID(filename, tag_data, "-data", 8 ); + FillFileNameByUID(filename, tag_data, "-data", 8); } // save the dump to .bin file @@ -1565,7 +1565,7 @@ static int ReadBlock(uint8_t *KEY, uint8_t blockno, uint8_t keyType, bool elite, } //data read is stored in: resp.data.asBytes[0-15] PrintAndLogEx(NORMAL, "block %02X: %s\n", blockno, sprint_hex(resp.data.asBytes, 8)); - // should decrypt it if file is accessable. + // should decrypt it if file is accessable. return 1; } @@ -1936,9 +1936,9 @@ static int saveKeys(char *filename) { static int printKeys(void) { PrintAndLogEx(NORMAL, ""); for (uint8_t i = 0; i < ICLASS_KEYS_MAX; i++) { - if ( memcmp(iClass_Key_Table[i], "\x00\x00\x00\x00\x00\x00\x00\x00", 8) == 0) + if (memcmp(iClass_Key_Table[i], "\x00\x00\x00\x00\x00\x00\x00\x00", 8) == 0) PrintAndLogEx(NORMAL, "%u: %s", i, sprint_hex(iClass_Key_Table[i], 8)); - else + else PrintAndLogEx(NORMAL, "%u: "_YELLOW_("%s"), i, sprint_hex(iClass_Key_Table[i], 8)); } PrintAndLogEx(NORMAL, ""); @@ -2096,7 +2096,7 @@ static int CmdHFiClassCheckKeys(const char *Cmd) { uint16_t keycount = 0; // load keys - int res = loadFileDICTIONARY_safe(filename, (void**)&keyBlock, 8, &keycount); + int res = loadFileDICTIONARY_safe(filename, (void **)&keyBlock, 8, &keycount); if (res != PM3_SUCCESS || keycount == 0) { free(keyBlock); return res; @@ -2106,11 +2106,11 @@ static int CmdHFiClassCheckKeys(const char *Cmd) { PrintAndLogEx(SUCCESS, "Reading tag CSN"); for (uint8_t i = 0; i < 10 && !got_csn; i++) { got_csn = select_only(CSN, CCNR, false, false); - if ( got_csn == false ) + if (got_csn == false) PrintAndLogEx(WARNING, "one more try\n"); - } + } - if ( got_csn == false ) { + if (got_csn == false) { PrintAndLogEx(WARNING, "Tried 10 times. Can't select card, aborting..."); return PM3_ESOFT; } @@ -2232,13 +2232,13 @@ out: PrintAndLogEx(SUCCESS, "\nTime in iclass checkkeys: %.0f seconds\n", (float)t1 / 1000.0); DropField(); - // add to managekeys - if ( found_debit ) { - for (uint8_t i=0; i< ICLASS_KEYS_MAX; i++) { + // add to managekeys + if (found_debit) { + for (uint8_t i = 0; i < ICLASS_KEYS_MAX; i++) { // simple check for preexistences - if ( memcmp(iClass_Key_Table[i], keyBlock + (key_offset + found_offset) * 8, 8) == 0 ) break; + if (memcmp(iClass_Key_Table[i], keyBlock + (key_offset + found_offset) * 8, 8) == 0) break; - if ( memcmp(iClass_Key_Table[i], "\x00\x00\x00\x00\x00\x00\x00\x00", 8) == 0 ) { + if (memcmp(iClass_Key_Table[i], "\x00\x00\x00\x00\x00\x00\x00\x00", 8) == 0) { memcpy(iClass_Key_Table[i], keyBlock + (key_offset + found_offset) * 8, 8); PrintAndLogEx(SUCCESS, "Added key to keyslot [%d] - "_YELLOW_("`hf iclass managekeys p`")" to view", i); break; @@ -2295,7 +2295,7 @@ static int CmdHFiClassLookUp(const char *Cmd) { case 'h': return usage_hf_iclass_lookup(); case 'f': - if ( param_getstr(Cmd, cmdp + 1, filename, sizeof(filename)) < 1 ) { + if (param_getstr(Cmd, cmdp + 1, filename, sizeof(filename)) < 1) { PrintAndLogEx(WARNING, "No filename found after f"); errors = true; } @@ -2358,12 +2358,12 @@ static int CmdHFiClassLookUp(const char *Cmd) { uint16_t keycount = 0; // load keys - int res = loadFileDICTIONARY_safe(filename, (void**)&keyBlock, 8, &keycount); + int res = loadFileDICTIONARY_safe(filename, (void **)&keyBlock, 8, &keycount); if (res != PM3_SUCCESS || keycount == 0) { free(keyBlock); return res; } - + //iclass_prekey_t prekey = calloc(keycount, sizeof(iclass_prekey_t)); if (!prekey) { @@ -2395,18 +2395,18 @@ static int CmdHFiClassLookUp(const char *Cmd) { // foudn if (item != NULL) { PrintAndLogEx(SUCCESS, "[debit] found key " _YELLOW_("%s"), sprint_hex(item->key, 8)); - for (uint8_t i=0; i< ICLASS_KEYS_MAX; i++) { + for (uint8_t i = 0; i < ICLASS_KEYS_MAX; i++) { // simple check for preexistences - if ( memcmp(item->key, iClass_Key_Table[i], 8) == 0 ) break; + if (memcmp(item->key, iClass_Key_Table[i], 8) == 0) break; - if ( memcmp(iClass_Key_Table[i] , "\x00\x00\x00\x00\x00\x00\x00\x00", 8) == 0 ) { + if (memcmp(iClass_Key_Table[i], "\x00\x00\x00\x00\x00\x00\x00\x00", 8) == 0) { memcpy(iClass_Key_Table[i], item->key, 8); PrintAndLogEx(SUCCESS, "Added key to keyslot [%d] - "_YELLOW_("`hf iclass managekeys p`")"to view", i); break; } } } - + free(prekey); free(keyBlock); PrintAndLogEx(NORMAL, ""); diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 538ec0569..be05d85d2 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -774,31 +774,31 @@ static char GetFormatFromSector(uint8_t sectorNo) { } } -static int FastDumpWithEcFill(uint8_t numsectors){ - PacketResponseNG resp; - - mfc_eload_t payload; - payload.sectorcnt = numsectors; - payload.keytype = 0; +static int FastDumpWithEcFill(uint8_t numsectors) { + PacketResponseNG resp; - // ecfill key A - clearCommandBuffer(); - SendCommandNG(CMD_HF_MIFARE_EML_LOAD, (uint8_t *)&payload, sizeof(payload)); - - int res = WaitForResponseTimeout(CMD_HF_MIFARE_EML_LOAD, &resp, 2000); - if ( res != PM3_SUCCESS) { - } - - // ecfill key B - payload.keytype = 1; - - clearCommandBuffer(); - SendCommandNG(CMD_HF_MIFARE_EML_LOAD, (uint8_t *)&payload, sizeof(payload)); - res = WaitForResponseTimeout(CMD_HF_MIFARE_EML_LOAD, &resp, 2000); - if ( res != PM3_SUCCESS) { + mfc_eload_t payload; + payload.sectorcnt = numsectors; + payload.keytype = 0; - } - return PM3_SUCCESS; + // ecfill key A + clearCommandBuffer(); + SendCommandNG(CMD_HF_MIFARE_EML_LOAD, (uint8_t *)&payload, sizeof(payload)); + + int res = WaitForResponseTimeout(CMD_HF_MIFARE_EML_LOAD, &resp, 2000); + if (res != PM3_SUCCESS) { + } + + // ecfill key B + payload.keytype = 1; + + clearCommandBuffer(); + SendCommandNG(CMD_HF_MIFARE_EML_LOAD, (uint8_t *)&payload, sizeof(payload)); + res = WaitForResponseTimeout(CMD_HF_MIFARE_EML_LOAD, &resp, 2000); + if (res != PM3_SUCCESS) { + + } + return PM3_SUCCESS; } static int CmdHF14AMfDump(const char *Cmd) { @@ -1287,11 +1287,11 @@ static int CmdHF14AMfNested(const char *Cmd) { PrintAndLogEx(SUCCESS, "Testing known keys. Sector count=%d", SectorsCnt); int res = mfCheckKeys_fast(SectorsCnt, true, true, 1, ARRAYLEN(g_mifare_default_keys) + 1, keyBlock, e_sector, false); - if ( res == PM3_SUCCESS ) { - // all keys found - PrintAndLogEx(SUCCESS, "Fast check found all keys"); - goto jumptoend; - } + if (res == PM3_SUCCESS) { + // all keys found + PrintAndLogEx(SUCCESS, "Fast check found all keys"); + goto jumptoend; + } uint64_t t2 = msclock() - t1; PrintAndLogEx(SUCCESS, "Time to check %d known keys: %.0f seconds\n", ARRAYLEN(g_mifare_default_keys), (float)t2 / 1000.0); @@ -1663,29 +1663,29 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { bool prng_type = false; bool verbose = false; bool has_filename = false; - bool errors = false; + bool errors = false; // Parse the options given by the user - while ( (ctmp = param_getchar(Cmd, cmdp)) && !errors ) { + while ((ctmp = param_getchar(Cmd, cmdp)) && !errors) { switch (tolower(ctmp)) { case 'h': return usage_hf14_autopwn(); case 'f': if (param_getstr(Cmd, cmdp + 1, filename, FILE_PATH_SIZE) >= FILE_PATH_SIZE) { PrintAndLogEx(FAILED, "Filename too long"); - errors = true; + errors = true; } else { - has_filename = true; + has_filename = true; } cmdp += 2; break; case 'l': legacy_mfchk = true; - cmdp++; + cmdp++; break; case 'v': verbose = true; - cmdp++; + cmdp++; break; case '*': // Get the number of sectors @@ -1696,35 +1696,35 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { case 'k': // Get the known block number if (param_getchar(Cmd, cmdp + 1) == 0x00) { - errors = true; + errors = true; break; } - + blockNo = param_get8(Cmd, cmdp + 1); - + // Get the knonwn block type ctmp = tolower(param_getchar(Cmd, cmdp + 2)); if (ctmp != 'a' && ctmp != 'b') { PrintAndLogEx(WARNING, "Key type must be A or B"); errors = true; - break; + break; } - + if (ctmp != 'a') { keyType = 1; } - + // Get the known block key if (param_gethex(Cmd, cmdp + 3, key, 12)) { PrintAndLogEx(WARNING, "Key must include 12 HEX symbols"); - errors = true; + errors = true; return PM3_EINVARG; } know_target_key = true; cmdp += 3; case 's': slow = true; - cmdp++; + cmdp++; break; case 'i': SetSIMDInstr(SIMD_AUTO); @@ -1759,9 +1759,9 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { return usage_hf14_autopwn(); } } - - if ( errors ) { - return usage_hf14_autopwn(); + + if (errors) { + return usage_hf14_autopwn(); } // Create the key storage stucture @@ -1821,7 +1821,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { ); PrintAndLogEx(WARNING, "falling back to dictionary"); } - + // Check if the user supplied key is used by other sectors for (int i = 0; i < sectors_cnt; i++) { for (int j = 0; j < 2; j++) { @@ -1858,18 +1858,18 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { bool load_success = true; // Load the dictionary if (has_filename) { - int res = loadFileDICTIONARY_safe(filename, (void**) &keyBlock, 6, &key_cnt); + int res = loadFileDICTIONARY_safe(filename, (void **) &keyBlock, 6, &key_cnt); if (res != PM3_SUCCESS || key_cnt == 0 || keyBlock == NULL) { PrintAndLogEx(FAILED, "An error occurred while loading the dictionary! (we will use the default keys now)"); if (keyBlock != NULL) free(keyBlock); - - load_success = false; + + load_success = false; } } - if ( has_filename == false || load_success == false ) { + if (has_filename == false || load_success == false) { keyBlock = calloc(ARRAYLEN(g_mifare_default_keys), 6); if (keyBlock == NULL) { free(e_sector); @@ -1880,7 +1880,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { num_to_bytes(g_mifare_default_keys[cnt], 6, keyBlock + cnt * 6); } key_cnt = ARRAYLEN(g_mifare_default_keys); - PrintAndLogEx(SUCCESS, "loaded " _GREEN_("%2d") "keys from hardcoded default array", key_cnt); + PrintAndLogEx(SUCCESS, "loaded " _GREEN_("%2d") "keys from hardcoded default array", key_cnt); } // Use the dictionary to find sector keys on the card @@ -1950,7 +1950,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { if (e_sector[i].foundKey[j] == 1) { e_sector[i].foundKey[j] = 'D'; num_to_bytes(e_sector[i].Key[j], 6, tmp_key); - + // Store valid credentials for the nested / hardnested attack if none exist if (know_target_key == false) { num_to_bytes(e_sector[i].Key[j], 6, key); @@ -2018,7 +2018,7 @@ noValidKeyFound: return PM3_ESOFT; } } - + free(keyBlock); // Clear the needed variables num_to_bytes(0, 6, tmp_key); @@ -2062,7 +2062,7 @@ noValidKeyFound: if (verbose) { PrintAndLogEx(INFO, _YELLOW_("======================= START READ B KEY ATTACK =======================")); PrintAndLogEx(INFO, "reading B key: sector: %3d key type: %c", - current_sector_i, + current_sector_i, current_key_type_i ? 'B' : 'A'); } uint8_t sectrail = (FirstBlockOfSector(current_sector_i) + NumBlocksPerSector(current_sector_i) - 1); @@ -2094,9 +2094,9 @@ noValidKeyFound: ); } else { if (verbose) PrintAndLogEx(WARNING, "unknown B key: sector: %3d key type: %c (reading the B key was not possible, maybe due to insufficient access rights) ", - current_sector_i, - current_key_type_i ? 'B' : 'A' - ); + current_sector_i, + current_key_type_i ? 'B' : 'A' + ); } if (verbose) PrintAndLogEx(INFO, _YELLOW_("======================= STOP READ B KEY ATTACK =======================")); } @@ -2226,13 +2226,13 @@ tryHardnested: // If the nested attack fails then we try the hardnested attack ); } PrintAndLogEx(NORMAL, "|---|----------------|---|----------------|---|"); - PrintAndLogEx(NORMAL, "( " + PrintAndLogEx(NORMAL, "( " _YELLOW_("D") ":Dictionary / " _YELLOW_("S") ":darkSide / " _YELLOW_("U") ":User / " _YELLOW_("R") ":Reused / " _YELLOW_("N") ":Nested / " - _YELLOW_("H") ":Hardnested / " + _YELLOW_("H") ":Hardnested / " _YELLOW_("A") ":keyA " ")" ); @@ -2254,8 +2254,8 @@ tryHardnested: // If the nested attack fails then we try the hardnested attack mfEmlSetMem(block, FirstBlockOfSector(current_sector_i) + NumBlocksPerSector(current_sector_i) - 1, 1); } - // use ecfill trick - FastDumpWithEcFill(sectors_cnt); + // use ecfill trick + FastDumpWithEcFill(sectors_cnt); bytes = block_cnt * MFBLOCK_SIZE; dump = calloc(bytes, sizeof(uint8_t)); @@ -2526,12 +2526,12 @@ out: printKeyTable(sectorsCnt, e_sector); - if ( use_flashmemory && found_keys == (sectorsCnt << 1) ) { - PrintAndLogEx(SUCCESS, "Card dumped aswell. run " _YELLOW_("`%s %c`"), - "hf mf esave", - GetFormatFromSector(sectorsCnt) - ); - } + if (use_flashmemory && found_keys == (sectorsCnt << 1)) { + PrintAndLogEx(SUCCESS, "Card dumped aswell. run " _YELLOW_("`%s %c`"), + "hf mf esave", + GetFormatFromSector(sectorsCnt) + ); + } if (transferToEml) { // fast push mode @@ -2551,10 +2551,10 @@ out: mfEmlSetMem(block, blockno, 1); } PrintAndLogEx(SUCCESS, "Found keys have been transferred to the emulator memory"); - - if ( found_keys == (sectorsCnt << 1) ) { - FastDumpWithEcFill(sectorsCnt); - } + + if (found_keys == (sectorsCnt << 1)) { + FastDumpWithEcFill(sectorsCnt); + } } if (createDumpFile) { @@ -3534,10 +3534,10 @@ static int CmdHF14AMfECFill(const char *Cmd) { PrintAndLogEx(NORMAL, "--params: numSectors: %d, keyType: %c\n", numSectors, (keyType == 0) ? 'A' : 'B'); mfc_eload_t payload; - payload.sectorcnt = numSectors; - payload.keytype = keyType; + payload.sectorcnt = numSectors; + payload.keytype = keyType; clearCommandBuffer(); - SendCommandNG(CMD_HF_MIFARE_EML_LOAD, (uint8_t *)&payload, sizeof(payload)); + SendCommandNG(CMD_HF_MIFARE_EML_LOAD, (uint8_t *)&payload, sizeof(payload)); return PM3_SUCCESS; } diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 46cc3e017..1431ca62a 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -2128,10 +2128,10 @@ static int CmdT55xxChkPwds(const char *Cmd) { if (use_pwd_file) { uint16_t keycount = 0; - int res = loadFileDICTIONARY_safe(filename, (void**) &keyBlock, 4, &keycount); + int res = loadFileDICTIONARY_safe(filename, (void **) &keyBlock, 4, &keycount); if (res != PM3_SUCCESS || keycount == 0 || keyBlock == NULL) { PrintAndLogEx(WARNING, "No keys found in file"); - if (keyBlock != NULL) + if (keyBlock != NULL) free(keyBlock); return PM3_ESOFT; diff --git a/client/fileutils.c b/client/fileutils.c index 427ebd9da..3c98b345a 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -435,7 +435,7 @@ int loadFile_safe(const char *preferredName, const char *suffix, void **pdata, s } size_t bytes_read = fread(*pdata, 1, fsize, f); - + fclose(f); if (bytes_read != fsize) { @@ -699,7 +699,7 @@ out: int loadFileDICTIONARY_safe(const char *preferredName, void **pdata, uint8_t keylen, uint16_t *keycnt) { int retval = PM3_SUCCESS; - + char *path; if (searchFile(&path, DICTIONARIES_SUBDIR, preferredName, ".dic", false) != PM3_SUCCESS) return PM3_EFILE; @@ -713,7 +713,7 @@ int loadFileDICTIONARY_safe(const char *preferredName, void **pdata, uint8_t key } size_t mem_size; - size_t block_size = 10 * keylen; + size_t block_size = 10 * keylen; // double up since its chars keylen <<= 1; @@ -721,24 +721,25 @@ int loadFileDICTIONARY_safe(const char *preferredName, void **pdata, uint8_t key char line[255]; // allocate some space for the dictionary - *pdata = calloc( block_size , sizeof(uint8_t)); + *pdata = calloc(block_size, sizeof(uint8_t)); if (*pdata == NULL) - return PM3_EFILE; + return PM3_EFILE; - mem_size = block_size; + mem_size = block_size; FILE *f = fopen(path, "r"); if (!f) { PrintAndLogEx(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", path); retval = PM3_EFILE; - goto out; } + goto out; + } // read file while (fgets(line, sizeof(line), f)) { // check if we have enough space (if not allocate more) - if ( (*keycnt * (keylen >> 1) ) >= mem_size ) { - + if ((*keycnt * (keylen >> 1)) >= mem_size) { + mem_size += block_size; *pdata = realloc(*pdata, mem_size); @@ -767,10 +768,10 @@ int loadFileDICTIONARY_safe(const char *preferredName, void **pdata, uint8_t key uint64_t key = strtoull(line, NULL, 16); - num_to_bytes(key, keylen >> 1, *pdata + (*keycnt * (keylen >> 1)) ); - + num_to_bytes(key, keylen >> 1, *pdata + (*keycnt * (keylen >> 1))); + (*keycnt)++; - + memset(line, 0, sizeof(line)); } fclose(f); diff --git a/client/loclass/elite_crack.c b/client/loclass/elite_crack.c index bc474fc21..bf9aee5b3 100644 --- a/client/loclass/elite_crack.c +++ b/client/loclass/elite_crack.c @@ -543,7 +543,7 @@ int bruteforceFile(const char *filename, uint16_t keytable[]) { size_t dumplen = 0; uint8_t *dump = NULL; - if ( loadFile_safe(filename, "", (void**)&dump, &dumplen) != PM3_SUCCESS ) { + if (loadFile_safe(filename, "", (void **)&dump, &dumplen) != PM3_SUCCESS) { return PM3_EFILE; } diff --git a/client/loclass/ikeys.c b/client/loclass/ikeys.c index f53f80221..f14e43eaf 100644 --- a/client/loclass/ikeys.c +++ b/client/loclass/ikeys.c @@ -655,19 +655,19 @@ static int doTestsWithKnownInputs() { } -static bool readKeyFile(uint8_t* key, size_t keylen) { +static bool readKeyFile(uint8_t *key, size_t keylen) { size_t len = 0; - uint8_t *keyptr = NULL; - if ( loadFile_safe("iclass_key.bin", "", (void**)&keyptr, &len) != PM3_SUCCESS ) { + uint8_t *keyptr = NULL; + if (loadFile_safe("iclass_key.bin", "", (void **)&keyptr, &len) != PM3_SUCCESS) { return false; } - - if ( keylen != len ) { + + if (keylen != len) { return false; } - - memcpy(key, keyptr, keylen ); + + memcpy(key, keyptr, keylen); return true; } diff --git a/client/mifare/mifarehost.c b/client/mifare/mifarehost.c index 54de89046..429605a4e 100644 --- a/client/mifare/mifarehost.c +++ b/client/mifare/mifarehost.c @@ -210,7 +210,7 @@ int mfCheckKeys_fast(uint8_t sectorsCnt, uint8_t firstChunk, uint8_t lastChunk, icesector_t *tmp = calloc(sectorsCnt, sizeof(icesector_t)); if (tmp == NULL) return PM3_EMALLOC; - + memcpy(tmp, resp.data.asBytes, sectorsCnt * sizeof(icesector_t)); for (int i = 0; i < sectorsCnt; i++) { diff --git a/client/ui.c b/client/ui.c index 6f177078d..68c8b197c 100644 --- a/client/ui.c +++ b/client/ui.c @@ -64,10 +64,10 @@ int searchHomeFilePath(char **foundpath, const char *filename, bool create_home) #ifdef _WIN32 struct _stat st; // Mingw _stat fails if path ends with /, so let's use a stripped path - if (path[strlen(path)-1]=='/') { - path[strlen(path)-1]='\0'; + if (path[strlen(path) - 1] == '/') { + path[strlen(path) - 1] = '\0'; result = _stat(path, &st); - path[strlen(path)]='/'; + path[strlen(path)] = '/'; } else { result = _stat(path, &st); } diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index dc48bd110..e87e8bc33 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -230,9 +230,9 @@ typedef struct { } PACKED mf_readblock_t; typedef struct { - uint8_t sectorcnt; - uint8_t keytype; -} PACKED mfc_eload_t; + uint8_t sectorcnt; + uint8_t keytype; +} PACKED mfc_eload_t; // For the bootloader #define CMD_DEVICE_INFO 0x0000 From bd7c1ccf4b7f11cf3dcbbc9af0d5ccd4d9fef19d Mon Sep 17 00:00:00 2001 From: Oleg Moiseenko <807634+merlokk@users.noreply.github.com> Date: Fri, 30 Aug 2019 12:42:17 +0300 Subject: [PATCH 0534/1854] Appveyour works (#378) * c2 * vfix * ff * dd2 --- appveyor.yml | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index b77cef02d..893aa7034 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -143,6 +143,7 @@ clone_script: ExecUpdate "update2" "C:\ProxSpace\msys2\msys2_shell.cmd -mingw32 -defterm -no-start /dev/null" "terminate?MSYS2" Write-Host "Update " -NoNewLine + Write-Host "[ OK ]" -ForegroundColor Green install: - ps: >- @@ -280,7 +281,7 @@ test_script: Function ExecTest($Name, $File, $Cmd, $CheckResult) { - + #--- begin Job $Job = Start-Job -ScriptBlock { @@ -318,6 +319,13 @@ test_script: if ($Cond -is "String" -and $Cond -like "*true*"){ $res= $true } + ForEach($line in $Cond){ + if ($line -like "*passed*"){ + $res = $true + $Cond = $line + break + } + } } Else { $res=$Cond } @@ -373,11 +381,11 @@ test_script: #proxmark logic tests - ExecTest "proxmark help" "proxmark3 -h" {bash -lc 'cd ~/client;./proxmark3 -h | grep -q wait && echo passed || echo failed'} + ExecTest "proxmark help" "proxmark3 -h" {bash -lc 'cd ~/client;./proxmark3 -h 2>&1 | grep -q wait && echo passed || echo failed'} - ExecTest "proxmark help text ISO7816" "proxmark3 -t" {bash -lc 'cd ~/client;./proxmark3 -t | grep -q ISO7816 && echo passed || echo failed'} + ExecTest "proxmark help text ISO7816" "proxmark3 -t" {bash -lc 'cd ~/client;./proxmark3 -t 2>&1 | grep -q ISO7816 && echo passed || echo failed'} - ExecTest "proxmark help text hardnested" "proxmark3 -t" {bash -lc 'cd ~/client;./proxmark3 -t | grep -q hardnested && echo passed || echo failed'} + ExecTest "proxmark help text hardnested" "proxmark3 -t" {bash -lc 'cd ~/client;./proxmark3 -t 2>&1 | grep -q hardnested && echo passed || echo failed'} ExecTest "hf mf offline text" "hf mf" {bash -lc "cd ~/client;./proxmark3 -c 'hf mf'"} "at_enc" From 4433f8982c721c50a0a70f8951129522338ed07d Mon Sep 17 00:00:00 2001 From: Oleg Moiseenko <807634+merlokk@users.noreply.github.com> Date: Fri, 30 Aug 2019 13:55:35 +0300 Subject: [PATCH 0535/1854] Appveyour fix paths (#379) --- appveyor.yml | 8 +++----- client/emv/test/cryptotest.c | 8 +++++++- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 893aa7034..1c4cc5ae5 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -193,9 +193,9 @@ build_script: } - if(!(Test-Path C:\ProxSpace\pm3\client\hardnested\tables\*.bin.z)){ + if(!(Test-Path C:\ProxSpace\pm3\client\resources\hardnested_tables\*.bin.z)){ - throw "Files in hardnested\tables not exists." + throw "Files in client\resources\hardnested_tables is not exists." } @@ -220,9 +220,7 @@ build_script: New-Item -ItemType Directory -Force -Path C:\ProxSpace\Release\hardnested\tables - Copy-Item C:\ProxSpace\pm3\client\hardnested\*.bin C:\ProxSpace\Release\hardnested - - Copy-Item C:\ProxSpace\pm3\client\hardnested\tables\*.bin.z C:\ProxSpace\Release\hardnested\tables + Copy-Item C:\ProxSpace\pm3\client\resources\hardnested_tables\*.bin.z C:\ProxSpace\Release\hardnested\tables # dll files diff --git a/client/emv/test/cryptotest.c b/client/emv/test/cryptotest.c index 29c4fdaa3..937ff7e8e 100644 --- a/client/emv/test/cryptotest.c +++ b/client/emv/test/cryptotest.c @@ -58,7 +58,13 @@ int ExecuteCryptoTests(bool verbose) { res = mbedtls_entropy_self_test(verbose); if (res) TestFail = true; - res = mbedtls_timing_self_test(verbose); + // retry for CI (when resources too low) + for (int i = 0; i < 3; i++) { + res = mbedtls_timing_self_test(verbose); + if (!res) + break; + PrintAndLogEx(WARNING, "Repeat timing test %d", i + 1); + } if (res) TestFail = true; res = mbedtls_ctr_drbg_self_test(verbose); From e1e5687e32b9fea11c95af5f3f28c01638f85721 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 30 Aug 2019 14:53:53 +0200 Subject: [PATCH 0536/1854] add: lua scripts can now search for files. --- client/scripting.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/client/scripting.c b/client/scripting.c index 5a3eaed61..6c2dbb07c 100644 --- a/client/scripting.c +++ b/client/scripting.c @@ -31,6 +31,7 @@ #include "proxmark3.h" #include "crc16.h" #include "protocols.h" +#include "fileutils.h" // searchfile static int returnToLuaWithError(lua_State *L, const char *fmt, ...) { char buffer[200]; @@ -1052,6 +1053,29 @@ static int l_ndefparse(lua_State *L) { return 1; } +static int l_searchfile(lua_State *L) { + //Check number of arguments + int n = lua_gettop(L); + if (n != 2) { + return returnToLuaWithError(L, "Only filename and extension"); + } + + size_t size; + // data + const char *filename = luaL_checklstring(L, 1, &size); + if ( size == 0 ) + return returnToLuaWithError(L, "Must specify filename"); + + const char *suffix = luaL_checklstring(L, 2, &size); + char *path; + int res = searchFile(&path, "", filename, suffix, false); + if ( res != PM3_SUCCESS) { + return returnToLuaWithError(L, "Failed to find file"); + } + + lua_pushstring(L, path); + return 1; +} /** * @brief Sets the lua path to include "./lualibs/?.lua", in order for a script to be @@ -1112,6 +1136,7 @@ int set_pm3_libraries(lua_State *L) { {"t55xx_detect", l_T55xx_detect}, {"ndefparse", l_ndefparse}, {"fast_push_mode", l_fast_push_mode}, + {"search_file", l_searchfile}, {NULL, NULL} }; From 24be423551d4ed4825cd2e3506a47abbd6c1d7f2 Mon Sep 17 00:00:00 2001 From: Uli Heilmeier Date: Fri, 30 Aug 2019 21:02:48 +0200 Subject: [PATCH 0537/1854] Readme: Fix links --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f02deabf6..2515cb6ec 100644 --- a/README.md +++ b/README.md @@ -17,8 +17,8 @@ It is dedicated to bringing the most out of the new features for Proxmark3 RDV4. | ------------------- |:-------------------:| -------------------:| |[What has changed?](#what-has-changed) | [Setup and build for Linux](/doc/md/Installation_Instructions/Linux-Installation-Instructions.md) | [Compilation Instructions](/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md)| |[Development](#development) | [Important notes on ModemManager for Linux users](/doc/md/Installation_Instructions/ModemManager-Must-Be-Discarded.md) | [Validating proxmark client functionality](/doc/md/Use_of_Proxmark/1_Validation.md) | -|[Why didn't you base it on official PM3 Master?](#why-didnt-you-base-it-on-official-pm3-master)| [Homebrew (Mac OS X) & Upgrading HomeBrew Tap Formula](/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md) | [First Use and Verification](/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md)| -|[PM3 GUI](#pm3-gui)|[Setup and build for Windows](/doc/md/Installation_Instructions/Windows-Installation-Instructions.md)|[Commands & Features](/doc/md/Use_of_Proxmark/3_Commands-and-Features.md)| +|[Why didn't you base it on official Proxmark3 Master?](#why-didnt-you-base-it-on-official-proxmark3-master)| [Homebrew (Mac OS X) & Upgrading HomeBrew Tap Formula](/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md) | [First Use and Verification](/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md)| +|[Proxmark3 GUI](#proxmark3-gui)|[Setup and build for Windows](/doc/md/Installation_Instructions/Windows-Installation-Instructions.md)|[Commands & Features](/doc/md/Use_of_Proxmark/3_Commands-and-Features.md)| |[Issues](#issues)|[Blue shark manual](/doc/bt_manual_v10.md) |[Advanced compilation parameters](/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md)| |[Notes on UART](/doc/uart_notes.md)||[Command Cheat sheet](/doc/cheatsheet.md)| |[Notes on Frame format](/doc/new_frame_format.md)||[More cheat sheets](https://github.com/RfidResearchGroup/proxmark3/wiki/More-cheat-sheets)| From 4d31b2399b320e186f864386bf6e9d12f5113ccc Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 30 Aug 2019 21:36:10 +0200 Subject: [PATCH 0538/1854] reintroduce PREFIX and use relative paths for finding share/ when installed, independently of PREFIX --- Makefile.host | 7 +------ client/Makefile | 7 +------ client/fileutils.c | 13 ++++++++----- client/scripting.c | 20 +++++++++++--------- include/common.h | 25 +++++++++++-------------- 5 files changed, 32 insertions(+), 40 deletions(-) diff --git a/Makefile.host b/Makefile.host index 3220f7add..66f3ccce0 100644 --- a/Makefile.host +++ b/Makefile.host @@ -15,12 +15,7 @@ FALSE = false CFLAGS ?= -Wall -Werror -O3 CFLAGS += $(MYDEFS) $(MYCFLAGS) $(MYINCLUDES) -ifneq (,$(PM3_BIN_PATH)) - CFLAGS += -DPM3_BIN_PATH=\"$(PM3_BIN_PATH)\" -endif -ifneq (,$(PM3_SHARE_PATH)) - CFLAGS += -DPM3_SHARE_PATH=\"$(PM3_SHARE_PATH)\" -endif +PREFIX ?= /usr/local platform = $(shell uname) diff --git a/client/Makefile b/client/Makefile index ccf7d5ab8..4a2e12329 100644 --- a/client/Makefile +++ b/client/Makefile @@ -66,12 +66,7 @@ INCLUDES_CLIENT = -I. -I../include -I../common -Iuart $(LIBS) CFLAGS ?= -Wall -Werror -g -O3 # We cannot just use CFLAGS+=... because it has impact on sub-makes if CFLAGS is defined in env: PM3CFLAGS = $(CFLAGS) -std=c99 -D_ISOC99_SOURCE $(INCLUDES_CLIENT) -ifneq (,$(PM3_BIN_PATH)) - PM3CFLAGS += -DPM3_BIN_PATH=\"$(PM3_BIN_PATH)\" -endif -ifneq (,$(PM3_SHARE_PATH)) - PM3CFLAGS += -DPM3_SHARE_PATH=\"$(PM3_SHARE_PATH)\" -endif +PREFIX ?= /usr/local ifneq (,$(findstring MINGW,$(platform))) PM3CFLAGS += -mno-ms-bitfields -fexec-charset=cp850 endif diff --git a/client/fileutils.c b/client/fileutils.c index 3c98b345a..1c0403294 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -855,9 +855,11 @@ int searchAndList(const char *pm3dir, const char *ext) { filelist(script_directory_path, ext, false, false); } // try pm3 dirs in pm3 installation dir (install mode) - { - char script_directory_path[strlen(PM3_SHARE_PATH) + strlen(pm3dir) + 1]; - strcpy(script_directory_path, PM3_SHARE_PATH); + const char *exec_path = get_my_executable_directory(); + if (exec_path != NULL) { + char script_directory_path[strlen(exec_path) + strlen(PM3_SHARE_RELPATH) + strlen(pm3dir) + 1]; + strcpy(script_directory_path, exec_path); + strcat(script_directory_path, PM3_SHARE_RELPATH); strcat(script_directory_path, pm3dir); filelist(script_directory_path, ext, true, false); } @@ -975,10 +977,11 @@ static int searchFinalFile(char **foundpath, const char *pm3dir, const char *sea } // try pm3 dirs in pm3 installation dir (install mode) { - char *path = calloc(strlen(PM3_SHARE_PATH) + strlen(pm3dir) + strlen(filename) + 1, sizeof(char)); + char *path = calloc(strlen(exec_path) + strlen(PM3_SHARE_RELPATH) + strlen(pm3dir) + strlen(filename) + 1, sizeof(char)); if (path == NULL) goto out; - strcpy(path, PM3_SHARE_PATH); + strcpy(path, exec_path); + strcat(path, PM3_SHARE_RELPATH); strcat(path, pm3dir); strcat(path, filename); if ((g_debugMode == 2) && (!silent)) { diff --git a/client/scripting.c b/client/scripting.c index 6c2dbb07c..33e7c6c42 100644 --- a/client/scripting.c +++ b/client/scripting.c @@ -1175,7 +1175,7 @@ int set_pm3_libraries(lua_State *L) { } char *user_path = getenv("HOME"); if (user_path != NULL) { - // from the ~/.proxmark3/luascripts/ directory + // from the $HOME/.proxmark3/luascripts/ directory char scripts_path[strlen(user_path) + strlen(PM3_USER_DIRECTORY) + strlen(LUA_SCRIPTS_SUBDIR) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; strcpy(scripts_path, user_path); strcat(scripts_path, PM3_USER_DIRECTORY); @@ -1183,7 +1183,7 @@ int set_pm3_libraries(lua_State *L) { strcat(scripts_path, LUA_LIBRARIES_WILDCARD); setLuaPath(L, scripts_path); - // from the ~/.proxmark3/lualib/ directory + // from the $HOME/.proxmark3/lualib/ directory char libraries_path[strlen(user_path) + strlen(PM3_USER_DIRECTORY) + strlen(LUA_LIBRARIES_SUBDIR) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; strcpy(libraries_path, user_path); strcat(libraries_path, PM3_USER_DIRECTORY); @@ -1192,16 +1192,18 @@ int set_pm3_libraries(lua_State *L) { setLuaPath(L, libraries_path); } - if (strlen(PM3_SHARE_PATH) != 0 || strlen(LUA_SCRIPTS_SUBDIR) != 0 || strlen(LUA_LIBRARIES_WILDCARD) != 0) { - // from the /usr/local/share/proxmark3/luascripts/ directory - char scripts_path[strlen(PM3_SHARE_PATH) + strlen(LUA_SCRIPTS_SUBDIR) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; - strcpy(scripts_path, PM3_SHARE_PATH); + if (exec_path != NULL) { + // from the $PREFIX/share/proxmark3/luascripts/ directory + char scripts_path[strlen(exec_path) + strlen(PM3_SHARE_RELPATH) + strlen(LUA_SCRIPTS_SUBDIR) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; + strcpy(scripts_path, exec_path); + strcat(scripts_path, PM3_SHARE_RELPATH); strcat(scripts_path, LUA_SCRIPTS_SUBDIR); strcat(scripts_path, LUA_LIBRARIES_WILDCARD); setLuaPath(L, scripts_path); - // from the /usr/local/share/proxmark3/lualib/ directory - char libraries_path[strlen(PM3_SHARE_PATH) + strlen(LUA_LIBRARIES_SUBDIR) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; - strcpy(libraries_path, PM3_SHARE_PATH); + // from the $PREFIX/share/proxmark3/lualib/ directory + char libraries_path[strlen(exec_path) + strlen(PM3_SHARE_RELPATH) + strlen(LUA_LIBRARIES_SUBDIR) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; + strcpy(libraries_path, exec_path); + strcat(libraries_path, PM3_SHARE_RELPATH); strcat(libraries_path, LUA_LIBRARIES_SUBDIR); strcat(libraries_path, LUA_LIBRARIES_WILDCARD); setLuaPath(L, libraries_path); diff --git a/include/common.h b/include/common.h index c4c5d6370..bdda44aae 100644 --- a/include/common.h +++ b/include/common.h @@ -16,22 +16,19 @@ #include #include -// brew prefixes are a bit weird so we've to split bin & share to be prepared: -#ifndef PM3_BIN_PATH -# define PM3_BIN_PATH "/usr/local/bin/" -#endif -#ifndef PM3_SHARE_PATH -# define PM3_SHARE_PATH "/usr/local/share/proxmark3/" -#endif -// PM3_USER_DIRECTORY will be expanded as if with a "~" upfront, e.g. ~/.proxmark3/ -#define PM3_USER_DIRECTORY "/.proxmark3/" +#define PATHSEP "/" +// PM3 share path relative to executable when installed +#define PM3_SHARE_RELPATH ".." PATHSEP "share" PATHSEP "proxmark3" PATHSEP + +// PM3_USER_DIRECTORY will be expanded from $HOME, e.g. ~/.proxmark3/ +#define PM3_USER_DIRECTORY PATHSEP ".proxmark3" PATHSEP // PM3 subdirectories: -#define DICTIONARIES_SUBDIR "dictionaries/" -#define LUA_LIBRARIES_SUBDIR "lualibs/" -#define LUA_SCRIPTS_SUBDIR "luascripts/" -#define RESOURCES_SUBDIR "resources/" -#define TRACES_SUBDIR "traces/" +#define DICTIONARIES_SUBDIR "dictionaries" PATHSEP +#define LUA_LIBRARIES_SUBDIR "lualibs" PATHSEP +#define LUA_SCRIPTS_SUBDIR "luascripts" PATHSEP +#define RESOURCES_SUBDIR "resources" PATHSEP +#define TRACES_SUBDIR "traces" PATHSEP #define PACKED __attribute__((packed)) From dbc9865c367a68258932f1c592c5ff9324d2770a Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 30 Aug 2019 21:38:12 +0200 Subject: [PATCH 0539/1854] clean common_arm/Makefile.common --- common_arm/Makefile.common | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/common_arm/Makefile.common b/common_arm/Makefile.common index cf4405d6a..b2f085d56 100644 --- a/common_arm/Makefile.common +++ b/common_arm/Makefile.common @@ -40,28 +40,11 @@ INCLUDE = -I../include -I../common_arm -I../common_fpga -I../common -I. TAR=tar TARFLAGS = -C .. -rvf -# Windows' echo echos its input verbatim, on Posix there is some -# amount of shell command line parsing going on. echo "" on -# Windows yields literal "", on Linux yields an empty line -ifeq ($(shell echo ""),) DELETE=rm -rf MOVE=mv COPY=cp PATHSEP=/ -FLASH_TOOL=client/flasher -# This is probably a proper system, so we can use uname DETECTED_OS=$(platform) -else - -# Assume that we are running on Windows. -DELETE=del /q -MOVE=ren -COPY=copy -PATHSEP=\\# -FLASH_TOOL=client\\flasher.exe -DETECTED_OS=Windows - -endif # Also search prerequisites in the common directory (for usb.c), the fpga directory (for fpga.bit), and the zlib directory VPATH = . ../common_arm ../common ../common/crapto1 ../common/mbedtls ../common/zlib ../fpga ../armsrc/Standalone From b5f5b9276f2fc39a8ea18e3ab5a0eabf7faa7bd0 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 30 Aug 2019 21:44:40 +0200 Subject: [PATCH 0540/1854] make install skeleton --- Makefile | 5 +++-- Makefile.host | 10 +++++++++- armsrc/Makefile | 10 +++++++++- bootrom/Makefile | 10 +++++++++- client/Makefile | 10 +++++++++- common_arm/Makefile.common | 5 +++-- recovery/Makefile | 9 +++++++++ 7 files changed, 51 insertions(+), 8 deletions(-) diff --git a/Makefile b/Makefile index 7ca9e313f..3f288f504 100644 --- a/Makefile +++ b/Makefile @@ -4,12 +4,13 @@ ifneq ($(V),1) endif # To see full command lines, use make V=1 +COPY=cp GZIP=gzip -include Makefile.platform -include .Makefile.options.cache include common_arm/Makefile.hal -all clean: %: client/% bootrom/% armsrc/% recovery/% mfkey/% nonce2key/% fpga_compress/% +all clean install uninstall: %: client/% bootrom/% armsrc/% recovery/% mfkey/% nonce2key/% fpga_compress/% mfkey/%: FORCE $(info [*] MAKE $@) @@ -34,7 +35,7 @@ recovery/%: FORCE cleanifplatformchanged bootrom/% armsrc/% $(Q)$(MAKE) --no-print-directory -C recovery $(patsubst recovery/%,%,$@) FORCE: # Dummy target to force remake in the subdirectories, even if files exist (this Makefile doesn't know about the prerequisites) -.PHONY: all clean help _test bootrom fullimage recovery client mfkey nonce2key style checks FORCE udev accessrights cleanifplatformchanged +.PHONY: all clean install uninstall help _test bootrom fullimage recovery client mfkey nonce2key style checks FORCE udev accessrights cleanifplatformchanged help: @echo "Multi-OS Makefile" diff --git a/Makefile.host b/Makefile.host index 66f3ccce0..8e76caa50 100644 --- a/Makefile.host +++ b/Makefile.host @@ -48,7 +48,15 @@ clean: $(Q)$(RM) $(CLEAN) $(Q)$(RMDIR) $(OBJDIR) -.PHONY: all clean +install: all + $(info [@] Installing $(BINS) $(LIB_A) to $(PREFIX)) + @true + +uninstall: + $(info [@] Uninstalling $(BINS) $(LIB_A) from $(PREFIX)) + @true + +.PHONY: all clean install uninstall $(BINDIR)/$(LIB_A): $(MYOBJS) $(info [=] AR $(notdir $@)) diff --git a/armsrc/Makefile b/armsrc/Makefile index 048879d96..6e67913e4 100644 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@ -213,7 +213,15 @@ clean: $(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.bin $(Q)$(DELETE) version.c -.PHONY: all clean help +install: all + $(info [@] Installing fullimage to $(PREFIX)) + @true + +uninstall: + $(info [@] Uninstalling fullimage from $(PREFIX)) + @true + +.PHONY: all clean help install uninstall help: @echo Multi-OS Makefile, you are running on $(DETECTED_OS) @echo Possible targets: diff --git a/bootrom/Makefile b/bootrom/Makefile index 884f01757..179678b92 100644 --- a/bootrom/Makefile +++ b/bootrom/Makefile @@ -56,7 +56,15 @@ clean: $(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.d $(Q)$(DELETE) version.c -.PHONY: all clean help +install: all + $(info [@] Installing bootrom to $(PREFIX)) + @true + +uninstall: + $(info [@] Uninstalling bootrom from $(PREFIX)) + @true + +.PHONY: all clean help install help: @echo Multi-OS Makefile, you are running on $(DETECTED_OS) @echo Possible targets: diff --git a/client/Makefile b/client/Makefile index 4a2e12329..42e617e1f 100644 --- a/client/Makefile +++ b/client/Makefile @@ -334,6 +334,14 @@ clean: $(Q)$(MAKE) --no-print-directory -C $(CBORLIBPATH) clean $(Q)$(MAKE) --no-print-directory -C $(REVENGPATH) clean +install: all + $(info [@] Installing client to $(PREFIX)) + @true + +uninstall: + $(info [@] Uninstalling client from $(PREFIX)) + @true + tarbin: $(BINS) $(info [=] TAR ../proxmark3-$(platform)-bin.tar) $(Q)$(TAR) $(TARFLAGS) ../proxmark3-$(platform)-bin.tar $(BINS:%=client/%) $(WINBINS:%=client/%) @@ -364,7 +372,7 @@ $(ZLIB): $(info [*] MAKE zlib) $(Q)$(MAKE) --no-print-directory -C $(ZLIBPATH) OBJDIR=$(ROOT_DIR)$(OBJDIR) BINDIR=$(ROOT_DIR)$(OBJDIR) all -.PHONY: all clean +.PHONY: all clean install uninstall # easy printing of MAKE VARIABLES print-%: ; @echo $* = $($*) diff --git a/common_arm/Makefile.common b/common_arm/Makefile.common index b2f085d56..011f020f8 100644 --- a/common_arm/Makefile.common +++ b/common_arm/Makefile.common @@ -21,10 +21,11 @@ endif # Make sure that all is the default target # (The including Makefile still needs to define what 'all' is) -platform = $(shell uname) - all: +platform = $(shell uname) +PREFIX?=/usr/local + CROSS ?= arm-none-eabi- CC = $(CROSS)gcc AS = $(CROSS)as diff --git a/recovery/Makefile b/recovery/Makefile index 59f7f37c8..60b62cfe1 100644 --- a/recovery/Makefile +++ b/recovery/Makefile @@ -19,3 +19,12 @@ proxmark3_recovery.bin: bootrom.bin fullimage.bin clean: $(Q)rm -f $(BINS) +install: all + $(info [@] Installing recovery to $(PREFIX)) + @true + +uninstall: all + $(info [@] Uninstalling recovery from $(PREFIX)) + @true + +PHONY: all clean install uninstall From 4fdb5a2f4bb8b4fd5f1499e138eff364ad594e1f Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 30 Aug 2019 21:55:13 +0200 Subject: [PATCH 0541/1854] make install: half way --- Makefile | 31 ++++++++++++++++++++++--------- Makefile.host | 14 ++++++++++++-- armsrc/Makefile | 30 ++++++++++++++++-------------- bootrom/Makefile | 25 ++++++++++++++----------- client/Makefile | 25 +++++++++++++++++++++++-- common_arm/Makefile.common | 9 +++++---- fpga/Makefile | 16 ++++++++-------- recovery/Makefile | 18 ++++++++++-------- tools/mfkey/Makefile | 1 + tools/nonce2key/Makefile | 1 + 10 files changed, 112 insertions(+), 58 deletions(-) diff --git a/Makefile b/Makefile index 3f288f504..f74932ccc 100644 --- a/Makefile +++ b/Makefile @@ -4,35 +4,48 @@ ifneq ($(V),1) endif # To see full command lines, use make V=1 -COPY=cp +CP = cp -a GZIP=gzip +MKDIR = mkdir -p +RM = rm -f +RMDIR = rm -rf -include Makefile.platform -include .Makefile.options.cache include common_arm/Makefile.hal +# preserve relative DESTDIR path for subdir makes +ifneq (,$(DESTDIR)) + # realpath needs the directory to exist + $(shell $(MKDIR) $(DESTDIR)) + MYDESTDIR:=$(realpath $(DESTDIR)) + ifeq (,$(MYDESTDIR)) + $(error Can't create $(DESTDIR)) + endif +endif + all clean install uninstall: %: client/% bootrom/% armsrc/% recovery/% mfkey/% nonce2key/% fpga_compress/% mfkey/%: FORCE $(info [*] MAKE $@) - $(Q)$(MAKE) --no-print-directory -C tools/mfkey $(patsubst mfkey/%,%,$@) + $(Q)$(MAKE) --no-print-directory -C tools/mfkey $(patsubst mfkey/%,%,$@) DESTDIR=$(MYDESTDIR) nonce2key/%: FORCE $(info [*] MAKE $@) - $(Q)$(MAKE) --no-print-directory -C tools/nonce2key $(patsubst nonce2key/%,%,$@) + $(Q)$(MAKE) --no-print-directory -C tools/nonce2key $(patsubst nonce2key/%,%,$@) DESTDIR=$(MYDESTDIR) fpga_compress/%: FORCE $(info [*] MAKE $@) - $(Q)$(MAKE) --no-print-directory -C tools/fpga_compress $(patsubst fpga_compress/%,%,$@) + $(Q)$(MAKE) --no-print-directory -C tools/fpga_compress $(patsubst fpga_compress/%,%,$@) DESTDIR=$(MYDESTDIR) bootrom/%: FORCE cleanifplatformchanged $(info [*] MAKE $@) - $(Q)$(MAKE) --no-print-directory -C bootrom $(patsubst bootrom/%,%,$@) + $(Q)$(MAKE) --no-print-directory -C bootrom $(patsubst bootrom/%,%,$@) DESTDIR=$(MYDESTDIR) armsrc/%: FORCE cleanifplatformchanged fpga_compress/% $(info [*] MAKE $@) - $(Q)$(MAKE) --no-print-directory -C armsrc $(patsubst armsrc/%,%,$@) + $(Q)$(MAKE) --no-print-directory -C armsrc $(patsubst armsrc/%,%,$@) DESTDIR=$(MYDESTDIR) client/%: FORCE $(info [*] MAKE $@) - $(Q)$(MAKE) --no-print-directory -C client $(patsubst client/%,%,$@) + $(Q)$(MAKE) --no-print-directory -C client $(patsubst client/%,%,$@) DESTDIR=$(MYDESTDIR) recovery/%: FORCE cleanifplatformchanged bootrom/% armsrc/% $(info [*] MAKE $@) - $(Q)$(MAKE) --no-print-directory -C recovery $(patsubst recovery/%,%,$@) + $(Q)$(MAKE) --no-print-directory -C recovery $(patsubst recovery/%,%,$@) DESTDIR=$(MYDESTDIR) FORCE: # Dummy target to force remake in the subdirectories, even if files exist (this Makefile doesn't know about the prerequisites) .PHONY: all clean install uninstall help _test bootrom fullimage recovery client mfkey nonce2key style checks FORCE udev accessrights cleanifplatformchanged @@ -77,7 +90,7 @@ nonce2key: nonce2key/all fpga_compress: fpga_compress/all newtarbin: - $(DELETE) proxmark3-$(platform)-bin.tar proxmark3-$(platform)-bin.tar.gz + $(RM) proxmark3-$(platform)-bin.tar proxmark3-$(platform)-bin.tar.gz @touch proxmark3-$(platform)-bin.tar tarbin: newtarbin client/tarbin armsrc/tarbin bootrom/tarbin diff --git a/Makefile.host b/Makefile.host index 8e76caa50..861e697fb 100644 --- a/Makefile.host +++ b/Makefile.host @@ -4,6 +4,9 @@ ifneq ($(V),1) endif # To see full command lines, use make V=1 +INSTALLBINRELPATH = /bin/ +INSTALLTOOLSRELPATH = /share/proxmark3/tools/ + CC = gcc LD = gcc RM = rm -f @@ -49,11 +52,18 @@ clean: $(Q)$(RMDIR) $(OBJDIR) install: all - $(info [@] Installing $(BINS) $(LIB_A) to $(PREFIX)) +ifneq (,$(INSTALLTOOLS)) + $(info [@] Installing $(BINS) to $(DESTDIR)$(PREFIX)...) + $(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(INSTALLTOOLSRELPATH) + $(Q)$(CP) $(INSTALLTOOLS) $(DESTDIR)$(PREFIX)$(INSTALLTOOLSRELPATH) +endif @true uninstall: - $(info [@] Uninstalling $(BINS) $(LIB_A) from $(PREFIX)) +ifneq (,$(INSTALLTOOLS)) + $(info [@] Uninstalling $(BINS) from $(DESTDIR)$(PREFIX)...) + $(Q)$(RM) $(foreach tool,$(INSTALLTOOLS),$(DESTDIR)$(PREFIX)$(INSTALLTOOLSRELPATH)$(notdir $(tool))) +endif @true .PHONY: all clean install uninstall diff --git a/armsrc/Makefile b/armsrc/Makefile index 6e67913e4..8cbe03dab 100644 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@ -134,6 +134,7 @@ include ../common_arm/Makefile.common COMMON_FLAGS = -Os +INSTALLFW = $(OBJDIR)/fullimage.elf OBJS = $(OBJDIR)/fullimage.s19 FPGA_COMPRESSOR = ../tools/fpga_compress/fpga_compress @@ -144,7 +145,7 @@ all: $(OBJS) # version.c should be remade on every time fullimage.stage1.elf should be remade version.c: default_version.c $(OBJDIR)/fpga_version_info.o $(OBJDIR)/fpga_all.o $(THUMBOBJ) $(ARMOBJ) $(info [-] GEN $@) - $(Q)sh ../tools/mkversion.sh > $@ || perl ../tools/mkversion.pl > $@ || $(COPY) $^ $@ + $(Q)sh ../tools/mkversion.sh > $@ || perl ../tools/mkversion.pl > $@ || $(CP) $^ $@ fpga_version_info.c: $(FPGA_BITSTREAMS) | $(FPGA_COMPRESSOR) $(info [-] GEN $@) @@ -203,23 +204,24 @@ tarbin: $(OBJS) $(Q)$(TAR) $(TARFLAGS) ../proxmark3-$(platform)-bin.tar $(OBJS:%=armsrc/%) $(OBJS:%.s19=armsrc/%.elf) clean: - $(Q)$(DELETE) $(DEPENDENCY_FILES) - $(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.o - $(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.elf - $(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.s19 - $(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.map - $(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.d - $(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.z - $(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.bin - $(Q)$(DELETE) version.c + $(Q)$(RM) $(DEPENDENCY_FILES) + $(Q)$(RM) $(OBJDIR)$(PATHSEP)*.o + $(Q)$(RM) $(OBJDIR)$(PATHSEP)*.elf + $(Q)$(RM) $(OBJDIR)$(PATHSEP)*.s19 + $(Q)$(RM) $(OBJDIR)$(PATHSEP)*.map + $(Q)$(RM) $(OBJDIR)$(PATHSEP)*.d + $(Q)$(RM) $(OBJDIR)$(PATHSEP)*.z + $(Q)$(RM) $(OBJDIR)$(PATHSEP)*.bin + $(Q)$(RM) version.c install: all - $(info [@] Installing fullimage to $(PREFIX)) - @true + $(info [@] Installing fullimage to $(DESTDIR)$(PREFIX)...) + $(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(INSTALLFWRELPATH) + $(Q)$(CP) $(INSTALLFW) $(DESTDIR)$(PREFIX)$(INSTALLFWRELPATH) uninstall: - $(info [@] Uninstalling fullimage from $(PREFIX)) - @true + $(info [@] Uninstalling fullimage from $(DESTDIR)$(PREFIX)...) + $(Q)$(RM) $(foreach fw,$(INSTALLFW),$(DESTDIR)$(PREFIX)$(INSTALLFWRELPATH)$(notdir $(fw))) .PHONY: all clean help install uninstall help: diff --git a/bootrom/Makefile b/bootrom/Makefile index 179678b92..0d3f081d9 100644 --- a/bootrom/Makefile +++ b/bootrom/Makefile @@ -31,12 +31,14 @@ APP_CFLAGS += -fno-stack-protector -fno-pie # Do not move this inclusion before the definition of {THUMB,ASM,ARM}SRC include ../common_arm/Makefile.common +INSTALLFW = $(OBJDIR)/bootrom.elf + OBJS = $(OBJDIR)/bootrom.s19 # version.c should be remade on every compilation version.c: default_version.c $(info [=] GEN $@) - $(Q)sh ../tools/mkversion.sh > $@ || perl ../tools/mkversion.pl > $@ || $(COPY) $^ $@ + $(Q)sh ../tools/mkversion.sh > $@ || perl ../tools/mkversion.pl > $@ || $(CP) $^ $@ all: $(OBJS) @@ -49,20 +51,21 @@ $(OBJDIR)/bootrom.elf: $(VERSIONOBJ) $(ASMOBJ) $(ARMOBJ) $(THUMBOBJ) $(Q)$(CC) $(LDFLAGS) -Wl,-T,ldscript-flash,-Map,$(patsubst %.elf,%.map,$@) -o $@ $^ $(LIBS) clean: - $(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.o - $(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.elf - $(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.s19 - $(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.map - $(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.d - $(Q)$(DELETE) version.c + $(Q)$(RM) $(OBJDIR)$(PATHSEP)*.o + $(Q)$(RM) $(OBJDIR)$(PATHSEP)*.elf + $(Q)$(RM) $(OBJDIR)$(PATHSEP)*.s19 + $(Q)$(RM) $(OBJDIR)$(PATHSEP)*.map + $(Q)$(RM) $(OBJDIR)$(PATHSEP)*.d + $(Q)$(RM) version.c install: all - $(info [@] Installing bootrom to $(PREFIX)) - @true + $(info [@] Installing bootrom to $(DESTDIR)$(PREFIX)...) + $(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(INSTALLFWRELPATH) + $(Q)$(CP) $(INSTALLFW) $(DESTDIR)$(PREFIX)$(INSTALLFWRELPATH) uninstall: - $(info [@] Uninstalling bootrom from $(PREFIX)) - @true + $(info [@] Uninstalling bootrom from $(DESTDIR)$(PREFIX)...) + $(Q)$(RM) $(foreach fw,$(INSTALLFW),$(DESTDIR)$(PREFIX)$(INSTALLFWRELPATH)$(notdir $(fw))) .PHONY: all clean help install help: diff --git a/client/Makefile b/client/Makefile index 42e617e1f..a8232f7e9 100644 --- a/client/Makefile +++ b/client/Makefile @@ -15,6 +15,12 @@ ifneq ($(V),1) endif # To see full command lines, use make V=1 +INSTALLBINRELPATH = /bin/ +INSTALLSHARERELPATH = /share/proxmark3/ +#TODO INSTALLBIN = proxmark3 proxmark3-flasher +INSTALLBIN = proxmark3 flasher +INSTALLSHARE = lualibs luascripts resources dictionaries + CC = gcc CXX = g++ LD = g++ @@ -27,6 +33,7 @@ MKDIR = mkdir -p MV = mv TOUCH = touch FALSE = false +CP=cp -a platform = $(shell uname) ROOT_DIR:=$(dir $(realpath $(lastword $(MAKEFILE_LIST)))) @@ -335,11 +342,25 @@ clean: $(Q)$(MAKE) --no-print-directory -C $(REVENGPATH) clean install: all - $(info [@] Installing client to $(PREFIX)) + $(info [@] Installing client to $(DESTDIR)$(PREFIX)...) +ifneq (,$(INSTALLBIN)) + $(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(INSTALLBINRELPATH) + $(Q)$(CP) $(INSTALLBIN) $(DESTDIR)$(PREFIX)$(INSTALLBINRELPATH) +endif +ifneq (,$(INSTALLSHARE)) + $(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(INSTALLSHARERELPATH) + $(Q)$(CP) $(INSTALLSHARE) $(DESTDIR)$(PREFIX)$(INSTALLSHARERELPATH) +endif @true uninstall: - $(info [@] Uninstalling client from $(PREFIX)) + $(info [@] Uninstalling client from $(DESTDIR)$(PREFIX)...) +ifneq (,$(INSTALLBIN)) + $(Q)$(RM) $(foreach tool,$(INSTALLBIN),$(DESTDIR)$(PREFIX)$(INSTALLBINRELPATH)$(notdir $(tool))) +endif +ifneq (,$(INSTALLSHARE)) + $(Q)$(RMDIR) $(foreach tool,$(INSTALLSHARE),$(DESTDIR)$(PREFIX)$(INSTALLSHARERELPATH)$(notdir $(tool))) +endif @true tarbin: $(BINS) diff --git a/common_arm/Makefile.common b/common_arm/Makefile.common index 011f020f8..5af77bcf7 100644 --- a/common_arm/Makefile.common +++ b/common_arm/Makefile.common @@ -25,6 +25,7 @@ all: platform = $(shell uname) PREFIX?=/usr/local +INSTALLFWRELPATH = /share/proxmark3/firmware/ CROSS ?= arm-none-eabi- CC = $(CROSS)gcc @@ -40,10 +41,10 @@ INCLUDE = -I../include -I../common_arm -I../common_fpga -I../common -I. TAR=tar TARFLAGS = -C .. -rvf - -DELETE=rm -rf -MOVE=mv -COPY=cp +RM=rm -f +RMDIR=rm -rf +CP=cp -a +MKDIR=mkdir -p PATHSEP=/ DETECTED_OS=$(platform) diff --git a/fpga/Makefile b/fpga/Makefile index b28c27db9..06cdec2ee 100644 --- a/fpga/Makefile +++ b/fpga/Makefile @@ -1,36 +1,36 @@ all: fpga_lf.bit fpga_hf.bit clean: - $(Q)$(DELETE) *.bgn *.drc *.ncd *.ngd *_par.xrpt *-placed.* *-placed_pad.* *_usage.xml xst_hf.srp xst_lf.srp - $(Q)$(DELETE) *.map *.ngc *.xrpt *.pcf *.rbt *_auto_* *.bld *.mrp *.ngm *.unroutes *_summary.xml netlist.lst xst + $(Q)$(RM) *.bgn *.drc *.ncd *.ngd *_par.xrpt *-placed.* *-placed_pad.* *_usage.xml xst_hf.srp xst_lf.srp + $(Q)$(RM) *.map *.ngc *.xrpt *.pcf *.rbt *_auto_* *.bld *.mrp *.ngm *.unroutes *_summary.xml netlist.lst xst fpga_hf.ngc: fpga_hf.v fpga.ucf xst_hf.scr util.v hi_simulate.v hi_read_tx.v hi_read_rx_xcorr.v hi_iso14443a.v hi_sniffer.v hi_flite.v - $(Q)$(DELETE) $@ + $(Q)$(RM) $@ $(info [-] XST $@) $(Q)$(XILINX_TOOLS_PREFIX)xst -ifn xst_hf.scr fpga_lf.ngc: fpga_lf.v fpga.ucf xst_lf.scr util.v clk_divider.v lo_edge_detect.v lo_read.v lo_passthru.v lp20khz_1MSa_iir_filter.v min_max_tracker.v lf_edge_detect.v - $(Q)$(DELETE) $@ + $(Q)$(RM) $@ $(info [-] XST $@) $(Q)$(XILINX_TOOLS_PREFIX)xst -ifn xst_lf.scr %.ngd: %.ngc - $(Q)$(DELETE) $@ + $(Q)$(RM) $@ $(info [-] NGD $@) $(Q)$(XILINX_TOOLS_PREFIX)ngdbuild -aul -p xc2s30-5-vq100 -nt timestamp -uc fpga.ucf $< $@ %.ncd: %.ngd - $(Q)$(DELETE) $@ + $(Q)$(RM) $@ $(info [-] MAP $@) $(Q)$(XILINX_TOOLS_PREFIX)map -p xc2s30-5-vq100 $< %-placed.ncd: %.ncd - $(Q)$(DELETE) $@ + $(Q)$(RM) $@ $(info [-] PAR $@) $(Q)$(XILINX_TOOLS_PREFIX)par $< $@ %.bit: %-placed.ncd - $(Q)$(DELETE) $@ $*.drc $*.rbt + $(Q)$(RM) $@ $*.drc $*.rbt $(info [=] BITGEN $@) $(Q)$(XILINX_TOOLS_PREFIX)bitgen $< $@ diff --git a/recovery/Makefile b/recovery/Makefile index 60b62cfe1..fd10020bf 100644 --- a/recovery/Makefile +++ b/recovery/Makefile @@ -1,6 +1,7 @@ include ../common_arm/Makefile.common -BINS = bootrom.bin fullimage.bin proxmark3_recovery.bin +INSTALLFW = proxmark3_recovery.bin +BINS = bootrom.bin fullimage.bin $(INSTALLFW) all: $(BINS) @@ -17,14 +18,15 @@ proxmark3_recovery.bin: bootrom.bin fullimage.bin $(Q)cat bootrom.bin fullimage.bin > $@ clean: - $(Q)rm -f $(BINS) + $(Q)$(RM) $(BINS) install: all - $(info [@] Installing recovery to $(PREFIX)) - @true + $(info [@] Installing recovery to $(DESTDIR)$(PREFIX)...) + $(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(INSTALLFWRELPATH) + $(Q)$(CP) $(INSTALLFW) $(DESTDIR)$(PREFIX)$(INSTALLFWRELPATH) -uninstall: all - $(info [@] Uninstalling recovery from $(PREFIX)) - @true +uninstall: + $(info [@] Uninstalling recovery from $(DESTDIR)$(PREFIX)...) + $(Q)$(RM) $(foreach fw,$(INSTALLFW),$(DESTDIR)$(PREFIX)$(INSTALLFWRELPATH)$(notdir $(fw))) -PHONY: all clean install uninstall +.PHONY: all clean install uninstall diff --git a/tools/mfkey/Makefile b/tools/mfkey/Makefile index 27fa95aa0..a7b006f6e 100644 --- a/tools/mfkey/Makefile +++ b/tools/mfkey/Makefile @@ -5,6 +5,7 @@ MYCFLAGS = -std=c99 -D_ISOC99_SOURCE MYDEFS = BINS = mfkey32 mfkey32v2 mfkey64 +INSTALLTOOLS = $(BINS) include ../../Makefile.host diff --git a/tools/nonce2key/Makefile b/tools/nonce2key/Makefile index 8b5d05278..77dc18099 100644 --- a/tools/nonce2key/Makefile +++ b/tools/nonce2key/Makefile @@ -5,6 +5,7 @@ MYCFLAGS = -std=c99 -D_ISOC99_SOURCE MYDEFS = BINS = nonce2key +INSTALLTOOLS = $(BINS) include ../../Makefile.host From d772c6169a719d37c798f8f75d90c90f0f2cd30d Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 30 Aug 2019 21:57:43 +0200 Subject: [PATCH 0542/1854] rename flasher -> proxmark3-flasher --- client/Makefile | 11 +++++----- doc/bt_manual_v10.md | 6 +++--- ...OS-X-Homebrew-Installation-Instructions.md | 2 +- .../ModemManager-Must-Be-Discarded.md | 2 +- .../Troubleshooting.md | 20 +++++++++---------- .../Windows-Installation-Instructions.md | 6 +++--- .../0_Compilation-Instructions.md | 2 +- 7 files changed, 25 insertions(+), 24 deletions(-) diff --git a/client/Makefile b/client/Makefile index a8232f7e9..5157e3e57 100644 --- a/client/Makefile +++ b/client/Makefile @@ -17,8 +17,7 @@ endif INSTALLBINRELPATH = /bin/ INSTALLSHARERELPATH = /share/proxmark3/ -#TODO INSTALLBIN = proxmark3 proxmark3-flasher -INSTALLBIN = proxmark3 flasher +INSTALLBIN = proxmark3 proxmark3-flasher INSTALLSHARE = lualibs luascripts resources dictionaries CC = gcc @@ -297,8 +296,10 @@ ifeq "$(SUPPORTS_AVX512)" "True" MULTIARCHOBJS += $(MULTIARCHSRCS:%.c=$(OBJDIR)/%_AVX512.o) endif -BINS = proxmark3 flasher +BINS = proxmark3 proxmark3-flasher CLEAN = $(BINS) *.moc.cpp ui/ui_overlays.h lualibs/pm3_cmd.lua lualibs/mfc_default_keys.lua +# transition: make sure old flasher is gone too +CLEAN += flasher # need to assign dependancies to build these first... all: $(BINS) @@ -311,7 +312,7 @@ proxmark3: $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(QTGUIOBJS) $(info [=] LD $@) $(Q)$(LD) $(LDFLAGS) $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(LDLIBS) -o $@ -flasher: $(OBJDIR)/flash.o $(OBJDIR)/flasher.o $(COREOBJS) $(OBJCOBJS) +proxmark3-flasher: $(OBJDIR)/flash.o $(OBJDIR)/flasher.o $(COREOBJS) $(OBJCOBJS) $(info [=] LD $@) $(Q)$(LD) $(LDFLAGS) $^ $(LDLIBS) -o $@ @@ -459,7 +460,7 @@ DEPENDENCY_FILES = $(patsubst %.c, $(OBJDIR)/%.d, $(CORESRCS) $(CMDSRCS) $(REVEN $(patsubst %.o, %.d, $(MULTIARCHOBJS)) \ $(patsubst %.cpp, $(OBJDIR)/%.d, $(QTGUISRCS)) \ $(patsubst %.m, $(OBJDIR)/%.d, $(OBJCSRCS)) \ - $(OBJDIR)/proxmark3.d $(OBJDIR)/flash.d $(OBJDIR)/flasher.d + $(OBJDIR)/proxmark3.d $(OBJDIR)/flash.d $(OBJDIR)/proxmark3-flasher.d $(OBJDIR)/flasher.d $(DEPENDENCY_FILES): ; .PRECIOUS: $(DEPENDENCY_FILES) diff --git a/doc/bt_manual_v10.md b/doc/bt_manual_v10.md index 5f140976f..38f5f0d3b 100644 --- a/doc/bt_manual_v10.md +++ b/doc/bt_manual_v10.md @@ -128,7 +128,7 @@ connection is successful. 4. Use Proxmark client on BT-serial port ```sh -./proxmark /dev/rfcomm0 +./proxmark3 /dev/rfcomm0 ``` The first time, your OS will ask you for pairing. The default PIN is 1234. If PIN is not typed in quickly, the client might timeout. Simply @@ -169,7 +169,7 @@ turn on solid. 4. a serial port `/dev/ttyUSB0` will be created, use Proxmark3 client on it ```sh -./proxmark /dev/ttyUSB0 +./proxmark3 /dev/ttyUSB0 ``` #### MacOS @@ -191,7 +191,7 @@ After reboot you can go ahead to pairing your Proxmark3 RDV4 Blue Shark: 8. A serial port like `/dev/tty.PM3_RDV40-DevB` will be created, use Proxmark3 client on it ```sh -./proxmark /dev/tty.PM3_RDV40-DevB +./proxmark3 /dev/tty.PM3_RDV40-DevB ``` #### Android diff --git a/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md b/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md index f2d87aa66..09b986ff3 100644 --- a/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md @@ -87,7 +87,7 @@ In principle, the helper script `flash-all.sh` should auto-detect your port, so If port detection failed, you'll have to call the flasher manually and specify the correct port: ```sh -client/flasher /dev/tty.usbmodemiceman1 -b bootrom/obj/bootrom.elf armsrc/obj/fullimage.elf +client/proxmark3-flasher /dev/tty.usbmodemiceman1 -b bootrom/obj/bootrom.elf armsrc/obj/fullimage.elf ``` Similarly, to run the client, you may try: diff --git a/doc/md/Installation_Instructions/ModemManager-Must-Be-Discarded.md b/doc/md/Installation_Instructions/ModemManager-Must-Be-Discarded.md index 68b69ea7b..76a4626e3 100644 --- a/doc/md/Installation_Instructions/ModemManager-Must-Be-Discarded.md +++ b/doc/md/Installation_Instructions/ModemManager-Must-Be-Discarded.md @@ -121,7 +121,7 @@ In short: * unplug device * press button and keep it pressed (IMPORTANT) * plug in device -* run flash command `sudo client/flasher /dev/ttyACM0 armsrc/obj/fullimage.elf` +* run flash command `sudo client/proxmark3-flasher /dev/ttyACM0 armsrc/obj/fullimage.elf` * wait until flash is finished * release button * un/plug device diff --git a/doc/md/Installation_Instructions/Troubleshooting.md b/doc/md/Installation_Instructions/Troubleshooting.md index b4ed877cb..336d89fe1 100644 --- a/doc/md/Installation_Instructions/Troubleshooting.md +++ b/doc/md/Installation_Instructions/Troubleshooting.md @@ -4,13 +4,13 @@ Always use the latest repository commits from *master* branch. There are always many fixes done almost daily. -## `./proxmark.sh` or `./flash-*.sh` doesn't see my Proxmark +## `./proxmark3.sh` or `./proxmark3-flash-*.sh` doesn't see my Proxmark Try using directly the client or flasher: ``` -client/flasher ... -client/proxmark ... +client/proxmark3-flasher ... +client/proxmark3 ... ``` Refer to the installation guide specific to your OS for details about ports. @@ -35,8 +35,8 @@ The flasher refused to flash your Proxmark3? Are there any messages in *red*? Th ``` or ``` -client/flasher -b bootrom/obj/bootrom.elf -client/flasher armsrc/obj/fullimage.elf +client/proxmark3-flasher -b bootrom/obj/bootrom.elf +client/proxmark3-flasher armsrc/obj/fullimage.elf ``` ### Find out why it would be bricked @@ -57,7 +57,7 @@ Once in bootloader mode, flash the main image. ``` or ``` -client/flasher armsrc/obj/fullimage.elf +client/proxmark3-flasher armsrc/obj/fullimage.elf ``` You should be back on tracks now. In case the flasher complains about bootloader version, you can follow the button procedure and flash first your bootloader. @@ -67,7 +67,7 @@ You should be back on tracks now. In case the flasher complains about bootloader ``` or ``` -client/flasher -b bootrom/obj/bootrom.elf +client/proxmark3-flasher -b bootrom/obj/bootrom.elf ``` ### Ok, my bootloader is definitively dead, now what? @@ -98,14 +98,14 @@ Instructions evolve over time so check if you're still up to date! Depending how you launch the client, your working directory might be the root of the repository: ``` -./proxmark.sh ... -client/proxmark ... +./proxmark3.sh ... +client/proxmark3 ... ``` or the `client/` subdirectory: ``` -cd client; ./proxmark ... +cd client; ./proxmark3 ... ``` Therefore client commands referring to files of the repo must be adapted, e.g. diff --git a/doc/md/Installation_Instructions/Windows-Installation-Instructions.md b/doc/md/Installation_Instructions/Windows-Installation-Instructions.md index 1df9e541b..f01e695e9 100644 --- a/doc/md/Installation_Instructions/Windows-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Windows-Installation-Instructions.md @@ -54,7 +54,7 @@ pacman -S mingw-w64-x86_64-astyle Now you're ready to follow the [compilation instructions](/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md). -To use the compiled client and flasher, the only differences are that executables end with `.exe` (e.g. `client/flasher.exe`) and that the Proxmark3 port is one of your `comX` ports where "X" is the com port number assigned to proxmark3 under Windows. +To use the compiled client and flasher, the only differences are that executables end with `.exe` (e.g. `client/proxmark3-flasher.exe`) and that the Proxmark3 port is one of your `comX` ports where "X" is the com port number assigned to proxmark3 under Windows. To flash: In principle, the helper script `flash-all.sh` should auto-detect your COM port, so you can just try: @@ -65,7 +65,7 @@ To flash: In principle, the helper script `flash-all.sh` should auto-detect your If COM port detection failed, you'll have to call the flasher manually and specify the correct port: ```sh -client/flasher.exe comX -b bootrom/obj/bootrom.elf armsrc/obj/fullimage.elf +client/proxmark3-flasher.exe comX -b bootrom/obj/bootrom.elf armsrc/obj/fullimage.elf ``` Similarly, to run the client, you may try: @@ -151,7 +151,7 @@ To flash: In principle, the helper script `flash-all.sh` should auto-detect your If port detection failed, you'll have to call the flasher manually and specify the correct port: ```sh -client/flasher /dev/ttySX -b bootrom/obj/bootrom.elf armsrc/obj/fullimage.elf +client/proxmark3-flasher /dev/ttySX -b bootrom/obj/bootrom.elf armsrc/obj/fullimage.elf ``` Similarly, to run the client, you may try: diff --git a/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md b/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md index 7493fba1a..1e6b24b88 100644 --- a/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md +++ b/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md @@ -31,7 +31,7 @@ In most cases, you can run the script `flash-all.sh` which try to auto-detect th For the other cases, specify the port by yourself. For example, for a Proxmark3 connected via USB under Linux: ```sh -client/flasher /dev/ttyACM0 -b bootrom/obj/bootrom.elf armsrc/obj/fullimage.elf +client/proxmark3-flasher /dev/ttyACM0 -b bootrom/obj/bootrom.elf armsrc/obj/fullimage.elf ``` ## Run the client From 3245260c009580c20eec57c0bdeb4c8972a154ce Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 30 Aug 2019 22:10:06 +0200 Subject: [PATCH 0543/1854] Add Makefile.defs with common defs --- Makefile | 11 +--------- Makefile.defs | 42 ++++++++++++++++++++++++++++++++++++++ Makefile.host | 41 +++++++++++-------------------------- client/Makefile | 28 ++++--------------------- common_arm/Makefile.common | 40 ++++++++++++------------------------ 5 files changed, 72 insertions(+), 90 deletions(-) create mode 100644 Makefile.defs diff --git a/Makefile b/Makefile index f74932ccc..d2d4ca643 100644 --- a/Makefile +++ b/Makefile @@ -1,14 +1,5 @@ -# Hide full compilation line: -ifneq ($(V),1) - Q?=@ -endif -# To see full command lines, use make V=1 -CP = cp -a -GZIP=gzip -MKDIR = mkdir -p -RM = rm -f -RMDIR = rm -rf +include Makefile.defs -include Makefile.platform -include .Makefile.options.cache include common_arm/Makefile.hal diff --git a/Makefile.defs b/Makefile.defs new file mode 100644 index 000000000..d69b58b33 --- /dev/null +++ b/Makefile.defs @@ -0,0 +1,42 @@ +# Hide full compilation line: +ifneq ($(V),1) + Q?=@ +endif +# To see full command lines, use make V=1 + +# been here +DEFSBEENHERE = true + +CP = cp -a +GZIP = gzip +MKDIR = mkdir -p +RM = rm -f +RMDIR = rm -rf +MV = mv +TOUCH = touch +FALSE = false +TAR = tar +TARFLAGS ?= -v --ignore-failed-read -r +TARFLAGS += -C .. -f +CROSS ?= arm-none-eabi- +CC = gcc +CXX = g++ +LD = g++ + +PATHSEP=/ +PREFIX ?= /usr/local +INSTALLBINRELPATH = /bin/ +INSTALLSHARERELPATH = /share/proxmark3/ +INSTALLFWRELPATH = /share/proxmark3/firmware/ +INSTALLTOOLSRELPATH = /share/proxmark3/tools/ + +platform = $(shell uname) +DETECTED_OS=$(platform) + +ifeq ($(platform),Darwin) + AR= /usr/bin/ar rcs + RANLIB= /usr/bin/ranlib +else + AR= ar rcs + RANLIB= ranlib +endif diff --git a/Makefile.host b/Makefile.host index 861e697fb..8fb6fceed 100644 --- a/Makefile.host +++ b/Makefile.host @@ -1,36 +1,19 @@ -# Hide full compilation line: -ifneq ($(V),1) - Q?=@ +# This Makefile might have been called from various subdirs, trying to find our Makefile.defs +ifeq ($(DEFSBEENHERE),) + -include Makefile.defs +endif +ifeq ($(DEFSBEENHERE),) + -include ../Makefile.defs +endif +ifeq ($(DEFSBEENHERE),) + -include ../../Makefile.defs +endif +ifeq ($(DEFSBEENHERE),) + $(error Can't find Makefile.defs) endif -# To see full command lines, use make V=1 - -INSTALLBINRELPATH = /bin/ -INSTALLTOOLSRELPATH = /share/proxmark3/tools/ - -CC = gcc -LD = gcc -RM = rm -f -MV = mv -CP = cp -a -MKDIR = mkdir -p -TOUCH = touch -FALSE = false CFLAGS ?= -Wall -Werror -O3 CFLAGS += $(MYDEFS) $(MYCFLAGS) $(MYINCLUDES) -PREFIX ?= /usr/local - -platform = $(shell uname) - -ifeq ($(platform),Darwin) -AR= /usr/bin/ar rcs -RANLIB= /usr/bin/ranlib -else -AR= ar rcs -RANLIB= ranlib -endif -RM= rm -f -RMDIR= rm -rf vpath %.c $(MYSRCPATHS) diff --git a/client/Makefile b/client/Makefile index 5157e3e57..4c5d53c9c 100644 --- a/client/Makefile +++ b/client/Makefile @@ -9,34 +9,14 @@ # Add -DNOFORCE to disable the -F switch # Add -DPRESETS to compile with preset models (edit config.h) -# Hide full compilation line: -ifneq ($(V),1) - Q?=@ -endif -# To see full command lines, use make V=1 +# Must be called before any Makefile include +ROOT_DIR:=$(dir $(realpath $(lastword $(MAKEFILE_LIST)))) + +include ../Makefile.defs -INSTALLBINRELPATH = /bin/ -INSTALLSHARERELPATH = /share/proxmark3/ INSTALLBIN = proxmark3 proxmark3-flasher INSTALLSHARE = lualibs luascripts resources dictionaries -CC = gcc -CXX = g++ -LD = g++ -TAR = tar -TARFLAGS ?= -v --ignore-failed-read -r -TARFLAGS += -C .. -f -RM = rm -f -RMDIR= rm -rf -MKDIR = mkdir -p -MV = mv -TOUCH = touch -FALSE = false -CP=cp -a - -platform = $(shell uname) -ROOT_DIR:=$(dir $(realpath $(lastword $(MAKEFILE_LIST)))) - VPATH = ../common uart vpath %.dic dictionaries OBJDIR = obj diff --git a/common_arm/Makefile.common b/common_arm/Makefile.common index 5af77bcf7..52ec2ebd2 100644 --- a/common_arm/Makefile.common +++ b/common_arm/Makefile.common @@ -6,48 +6,34 @@ # Common makefile functions for all platforms #----------------------------------------------------------------------------- -# This new makefile replaces the previous Makefile/Makefile.linux -# with as much common code for both environments as possible. -# Following is a short OS detection to set up variables, all the -# remaining Makefile should be portable and only depend on these -# variables -# - -ifneq ($(V),1) - Q?=@ -endif -# To see full command lines, use make V=1 - # Make sure that all is the default target # (The including Makefile still needs to define what 'all' is) all: -platform = $(shell uname) -PREFIX?=/usr/local -INSTALLFWRELPATH = /share/proxmark3/firmware/ +# This Makefile might have been called from various subdirs, trying to find our Makefile.defs +ifeq ($(DEFSBEENHERE),) + -include Makefile.defs +endif +ifeq ($(DEFSBEENHERE),) + -include ../Makefile.defs +endif +ifeq ($(DEFSBEENHERE),) + -include ../../Makefile.defs +endif +ifeq ($(DEFSBEENHERE),) + $(error Can't find Makefile.defs) +endif -CROSS ?= arm-none-eabi- CC = $(CROSS)gcc AS = $(CROSS)as LD = $(CROSS)ld OBJCOPY = $(CROSS)objcopy -GZIP=gzip -MV=mv OBJDIR = obj INCLUDE = -I../include -I../common_arm -I../common_fpga -I../common -I. -TAR=tar -TARFLAGS = -C .. -rvf -RM=rm -f -RMDIR=rm -rf -CP=cp -a -MKDIR=mkdir -p -PATHSEP=/ -DETECTED_OS=$(platform) - # Also search prerequisites in the common directory (for usb.c), the fpga directory (for fpga.bit), and the zlib directory VPATH = . ../common_arm ../common ../common/crapto1 ../common/mbedtls ../common/zlib ../fpga ../armsrc/Standalone From f6a4f9cbe37a06101a4b99fe287c22c0a2375c5d Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 30 Aug 2019 22:11:02 +0200 Subject: [PATCH 0544/1854] move client scripts to tools --- {client => tools}/pm3_eml2lower.sh | 0 {client => tools}/pm3_eml2mfd.py | 0 {client => tools}/pm3_eml2upper.sh | 0 {client => tools}/pm3_eml_mfd_test.py | 0 {client => tools}/pm3_mfd2eml.py | 0 {client => tools}/pm3_mfdread.py | 0 6 files changed, 0 insertions(+), 0 deletions(-) rename {client => tools}/pm3_eml2lower.sh (100%) rename {client => tools}/pm3_eml2mfd.py (100%) rename {client => tools}/pm3_eml2upper.sh (100%) rename {client => tools}/pm3_eml_mfd_test.py (100%) rename {client => tools}/pm3_mfd2eml.py (100%) rename {client => tools}/pm3_mfdread.py (100%) diff --git a/client/pm3_eml2lower.sh b/tools/pm3_eml2lower.sh similarity index 100% rename from client/pm3_eml2lower.sh rename to tools/pm3_eml2lower.sh diff --git a/client/pm3_eml2mfd.py b/tools/pm3_eml2mfd.py similarity index 100% rename from client/pm3_eml2mfd.py rename to tools/pm3_eml2mfd.py diff --git a/client/pm3_eml2upper.sh b/tools/pm3_eml2upper.sh similarity index 100% rename from client/pm3_eml2upper.sh rename to tools/pm3_eml2upper.sh diff --git a/client/pm3_eml_mfd_test.py b/tools/pm3_eml_mfd_test.py similarity index 100% rename from client/pm3_eml_mfd_test.py rename to tools/pm3_eml_mfd_test.py diff --git a/client/pm3_mfd2eml.py b/tools/pm3_mfd2eml.py similarity index 100% rename from client/pm3_mfd2eml.py rename to tools/pm3_mfd2eml.py diff --git a/client/pm3_mfdread.py b/tools/pm3_mfdread.py similarity index 100% rename from client/pm3_mfdread.py rename to tools/pm3_mfdread.py From 7e579f9fca28ea730f7a49441bd0f998dfee949f Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 30 Aug 2019 22:13:51 +0200 Subject: [PATCH 0545/1854] rename SIMxxx.BIN in lowercase --- client/cmdsmartcard.c | 2 +- doc/cheatsheet.md | 2 +- doc/md/Installation_Instructions/Troubleshooting.md | 4 ++-- .../2_Configuration-and-Verification.md | 8 ++++---- tools/simmodule/{SIM010.BIN => sim010.bin} | Bin .../{SIM010.sha512.txt => sim010.sha512.txt} | 2 +- tools/simmodule/{SIM011.BIN => sim011.bin} | Bin .../{SIM011.sha512.txt => sim011.sha512.txt} | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) rename tools/simmodule/{SIM010.BIN => sim010.bin} (100%) rename tools/simmodule/{SIM010.sha512.txt => sim010.sha512.txt} (90%) rename tools/simmodule/{SIM011.BIN => sim011.bin} (100%) rename tools/simmodule/{SIM011.sha512.txt => sim011.sha512.txt} (90%) diff --git a/client/cmdsmartcard.c b/client/cmdsmartcard.c index d6606ad19..c9dde7063 100644 --- a/client/cmdsmartcard.c +++ b/client/cmdsmartcard.c @@ -69,7 +69,7 @@ static int usage_sm_upgrade(void) { PrintAndLogEx(NORMAL, " f : firmware file name"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " sc upgrade f ../tools/simmodule/SIM011.BIN"); + PrintAndLogEx(NORMAL, " sc upgrade f ../tools/simmodule/sim011.bin"); return 0; } static int usage_sm_setclock(void) { diff --git a/doc/cheatsheet.md b/doc/cheatsheet.md index 670ae1979..4a61ae7d2 100644 --- a/doc/cheatsheet.md +++ b/doc/cheatsheet.md @@ -522,7 +522,7 @@ pm3 --> mem load f iclass_default_keys i Upgrade Sim Module firmware ``` -pm3 --> sc upgrade f ../tools/simmodule/SIM011.BIN +pm3 --> sc upgrade f ../tools/simmodule/sim011.bin ``` ## Smart Card diff --git a/doc/md/Installation_Instructions/Troubleshooting.md b/doc/md/Installation_Instructions/Troubleshooting.md index 336d89fe1..19f1dbee7 100644 --- a/doc/md/Installation_Instructions/Troubleshooting.md +++ b/doc/md/Installation_Instructions/Troubleshooting.md @@ -111,9 +111,9 @@ cd client; ./proxmark3 ... Therefore client commands referring to files of the repo must be adapted, e.g. ``` -pm3 --> sc upgrade f tools/simmodule/SIM011.BIN +pm3 --> sc upgrade f tools/simmodule/sim011.bin <> -pm3 --> sc upgrade f ../tools/simmodule/SIM011.BIN +pm3 --> sc upgrade f ../tools/simmodule/sim011.bin ``` ``` diff --git a/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md b/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md index 503c4b988..8ec176edb 100644 --- a/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md +++ b/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md @@ -32,21 +32,21 @@ Find version in the long output, look for these two lines This version is obsolete. -If you didn't download SIM011.bin from the RRG Repo be aware that it might be corrupted or faulty. +If you didn't download sim011.bin from the RRG Repo be aware that it might be corrupted or faulty. You find a hash text file in this folder. It was generated with the following linux command. ``` -sha512sum -b SIM011.bin > SIM011.sha512.txt +sha512sum -b sim011.bin > sim011.sha512.txt ``` -You should validate the SIM011.bin file against this hash file in order to be sure the file is not corrupted or faulty. +You should validate the sim011.bin file against this hash file in order to be sure the file is not corrupted or faulty. The following command upgrades your device sim module firmware. Don't not turn off your device during the execution of this command!! Even its a quite fast command you should be warned. You may brick it if you interrupt it. ``` -pm3 --> sc upgrade f ../tools/simmodule/SIM011.BIN +pm3 --> sc upgrade f ../tools/simmodule/sim011.bin ``` You get the following output if the execution was successful: diff --git a/tools/simmodule/SIM010.BIN b/tools/simmodule/sim010.bin similarity index 100% rename from tools/simmodule/SIM010.BIN rename to tools/simmodule/sim010.bin diff --git a/tools/simmodule/SIM010.sha512.txt b/tools/simmodule/sim010.sha512.txt similarity index 90% rename from tools/simmodule/SIM010.sha512.txt rename to tools/simmodule/sim010.sha512.txt index b7bab7246..0b3e6b438 100644 --- a/tools/simmodule/SIM010.sha512.txt +++ b/tools/simmodule/sim010.sha512.txt @@ -1 +1 @@ -e6ac5e6f1d7cc86d56f2128f2a495f1395fe044bf6ff3b6ca24ce90d1e361ae835fe273a206f2fc90e4344a13b37b180dd017a2c7f23312f1ed163f10c01ea5a *SIM010.BIN +e6ac5e6f1d7cc86d56f2128f2a495f1395fe044bf6ff3b6ca24ce90d1e361ae835fe273a206f2fc90e4344a13b37b180dd017a2c7f23312f1ed163f10c01ea5a *sim010.bin diff --git a/tools/simmodule/SIM011.BIN b/tools/simmodule/sim011.bin similarity index 100% rename from tools/simmodule/SIM011.BIN rename to tools/simmodule/sim011.bin diff --git a/tools/simmodule/SIM011.sha512.txt b/tools/simmodule/sim011.sha512.txt similarity index 90% rename from tools/simmodule/SIM011.sha512.txt rename to tools/simmodule/sim011.sha512.txt index 54a8bfd09..23ee6875f 100644 --- a/tools/simmodule/SIM011.sha512.txt +++ b/tools/simmodule/sim011.sha512.txt @@ -1 +1 @@ -752f9d8af3db214a797bacb7362a0b53eff4dd3793853e467047b7d36ddae9d1b4a050d9136225a48830d9c70bbad791f89d05553b0453f004b7bbcdc337e658 *SIM011.BIN +752f9d8af3db214a797bacb7362a0b53eff4dd3793853e467047b7d36ddae9d1b4a050d9136225a48830d9c70bbad791f89d05553b0453f004b7bbcdc337e658 *sim011.bin From 742b62502e233b1aa7fd286741a1d9d8ee9e00ad Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 30 Aug 2019 22:29:01 +0200 Subject: [PATCH 0546/1854] make install, second half --- Makefile | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ Makefile.defs | 4 ++++ 2 files changed, 55 insertions(+) diff --git a/Makefile b/Makefile index d2d4ca643..92e53cb93 100644 --- a/Makefile +++ b/Makefile @@ -16,6 +16,57 @@ endif all clean install uninstall: %: client/% bootrom/% armsrc/% recovery/% mfkey/% nonce2key/% fpga_compress/% +INSTALLTOOLS=pm3_eml2lower.sh pm3_eml2upper.sh pm3_mfdread.py pm3_mfd2eml.py pm3_eml2mfd.py findbits.py rfidtest.pl xorcheck.py +INSTALLSIMFW=sim011.bin sim011.sha512.txt + +install: all + $(info [@] Installing common resources to $(MYDESTDIR)$(PREFIX)...) + $(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(INSTALLBINRELPATH) + # TODO scripts must be adapted, they're currently broken + $(Q)$(CP) proxmark3.sh $(DESTDIR)$(PREFIX)$(INSTALLBINRELPATH)/pm3 + $(Q)$(CP) flash-all.sh $(DESTDIR)$(PREFIX)$(INSTALLBINRELPATH)/pm3-flash-all + $(Q)$(CP) flash-bootrom.sh $(DESTDIR)$(PREFIX)$(INSTALLBINRELPATH)/pm3-flash-bootrom + $(Q)$(CP) flash-fullimage.sh $(DESTDIR)$(PREFIX)$(INSTALLBINRELPATH)/pm3-flash-fullimage + $(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(INSTALLSHARERELPATH) + $(Q)$(CP) tools/jtag_openocd $(DESTDIR)$(PREFIX)$(INSTALLSHARERELPATH) + $(Q)$(CP) traces $(DESTDIR)$(PREFIX)$(INSTALLSHARERELPATH) + $(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(INSTALLDOCRELPATH) + $(Q)$(CP) doc/* $(DESTDIR)$(PREFIX)$(INSTALLDOCRELPATH) +ifneq (,$(INSTALLTOOLS)) + $(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(INSTALLTOOLSRELPATH) + $(Q)$(CP) $(foreach tool,$(INSTALLTOOLS),tools/$(tool)) $(DESTDIR)$(PREFIX)$(INSTALLTOOLSRELPATH) +endif +ifneq (,$(INSTALLSIMFW)) + $(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(INSTALLFWRELPATH) + $(Q)$(CP) $(foreach fw,$(INSTALLSIMFW),tools/simmodule/$(fw)) $(DESTDIR)$(PREFIX)$(INSTALLFWRELPATH) +endif +ifeq ($(platform),Linux) + $(Q)$(MKDIR) $(DESTDIR)$(UDEV_PREFIX) + $(Q)$(CP) driver/77-pm3-usb-device-blacklist.rules $(DESTDIR)$(UDEV_PREFIX)/77-pm3-usb-device-blacklist.rules +endif + +uninstall: + $(info [@] Uninstalling common resources from $(MYDESTDIR)$(PREFIX)...) + $(Q)$(RM) $(DESTDIR)$(PREFIX)$(INSTALLBINRELPATH)/pm3 + $(Q)$(RM) $(DESTDIR)$(PREFIX)$(INSTALLBINRELPATH)/pm3-flash-all + $(Q)$(RM) $(DESTDIR)$(PREFIX)$(INSTALLBINRELPATH)/pm3-flash-bootrom + $(Q)$(RM) $(DESTDIR)$(PREFIX)$(INSTALLBINRELPATH)/pm3-flash-fullimage + $(Q)$(RMDIR) $(DESTDIR)$(PREFIX)$(INSTALLSHARERELPATH)/jtag_openocd + $(Q)$(RMDIR) $(DESTDIR)$(PREFIX)$(INSTALLSHARERELPATH)/traces + $(Q)$(RMDIR) $(DESTDIR)$(PREFIX)$(INSTALLDOCRELPATH) +ifneq (,$(INSTALLTOOLS)) + $(Q)$(RM) $(foreach tool,$(INSTALLTOOLS),$(DESTDIR)$(PREFIX)$(INSTALLTOOLSRELPATH)$(notdir $(tool))) +endif + $(Q)$(RMDIR_SOFT) $(DESTDIR)$(PREFIX)$(INSTALLTOOLSRELPATH) +ifneq (,$(INSTALLSIMFW)) + $(Q)$(RM) $(foreach fw,$(INSTALLSIMFW),$(DESTDIR)$(PREFIX)$(INSTALLFWRELPATH)$(notdir $(fw))) +endif + $(Q)$(RMDIR_SOFT) $(DESTDIR)$(PREFIX)$(INSTALLFWRELPATH) +ifeq ($(platform),Linux) + $(Q)$(RM) $(DESTDIR)$(UDEV_PREFIX)/77-pm3-usb-device-blacklist.rules +endif + $(Q)$(RMDIR_SOFT) $(DESTDIR)$(PREFIX)$(INSTALLSHARERELPATH) + mfkey/%: FORCE $(info [*] MAKE $@) $(Q)$(MAKE) --no-print-directory -C tools/mfkey $(patsubst mfkey/%,%,$@) DESTDIR=$(MYDESTDIR) diff --git a/Makefile.defs b/Makefile.defs index d69b58b33..3f12cacb3 100644 --- a/Makefile.defs +++ b/Makefile.defs @@ -12,6 +12,8 @@ GZIP = gzip MKDIR = mkdir -p RM = rm -f RMDIR = rm -rf +# rmdir only if dir is empty, tolerate failure +RMDIR_SOFT = -rmdir MV = mv TOUCH = touch FALSE = false @@ -25,10 +27,12 @@ LD = g++ PATHSEP=/ PREFIX ?= /usr/local +UDEV_PREFIX ?= /etc/udev/rules.d INSTALLBINRELPATH = /bin/ INSTALLSHARERELPATH = /share/proxmark3/ INSTALLFWRELPATH = /share/proxmark3/firmware/ INSTALLTOOLSRELPATH = /share/proxmark3/tools/ +INSTALLDOCRELPATH = /share/doc/proxmark3/ platform = $(shell uname) DETECTED_OS=$(platform) From 595fde53126bf61f79565367ed2b545a9b2509ed Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 30 Aug 2019 23:35:29 +0200 Subject: [PATCH 0547/1854] update scripts to work with make install --- Makefile | 39 +++++++++++++++++++++++---------------- Makefile.defs | 2 +- flash-all.sh | 5 ----- flash-bootrom.sh | 5 ----- flash-fullimage.sh | 5 ----- proxmark3.sh => pm3 | 39 +++++++++++++++++++++++++++------------ pm3-flash-all | 4 ++++ pm3-flash-bootrom | 4 ++++ pm3-flash-fullimage | 4 ++++ 9 files changed, 63 insertions(+), 44 deletions(-) delete mode 100755 flash-all.sh delete mode 100755 flash-bootrom.sh delete mode 100755 flash-fullimage.sh rename proxmark3.sh => pm3 (66%) create mode 100755 pm3-flash-all create mode 100755 pm3-flash-bootrom create mode 100755 pm3-flash-fullimage diff --git a/Makefile b/Makefile index 92e53cb93..79d9a2ff8 100644 --- a/Makefile +++ b/Makefile @@ -18,20 +18,24 @@ all clean install uninstall: %: client/% bootrom/% armsrc/% recovery/% mfkey/% n INSTALLTOOLS=pm3_eml2lower.sh pm3_eml2upper.sh pm3_mfdread.py pm3_mfd2eml.py pm3_eml2mfd.py findbits.py rfidtest.pl xorcheck.py INSTALLSIMFW=sim011.bin sim011.sha512.txt +INSTALLSCRIPTS=pm3 pm3-flash-all pm3-flash-bootrom pm3-flash-fullimage +INSTALLSHARES=tools/jtag_openocd traces +INSTALLDOCS=doc/*.md doc/md install: all $(info [@] Installing common resources to $(MYDESTDIR)$(PREFIX)...) +ifneq (,$(INSTALLSCRIPTS)) $(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(INSTALLBINRELPATH) - # TODO scripts must be adapted, they're currently broken - $(Q)$(CP) proxmark3.sh $(DESTDIR)$(PREFIX)$(INSTALLBINRELPATH)/pm3 - $(Q)$(CP) flash-all.sh $(DESTDIR)$(PREFIX)$(INSTALLBINRELPATH)/pm3-flash-all - $(Q)$(CP) flash-bootrom.sh $(DESTDIR)$(PREFIX)$(INSTALLBINRELPATH)/pm3-flash-bootrom - $(Q)$(CP) flash-fullimage.sh $(DESTDIR)$(PREFIX)$(INSTALLBINRELPATH)/pm3-flash-fullimage + $(Q)$(CP) $(INSTALLSCRIPTS) $(DESTDIR)$(PREFIX)$(INSTALLBINRELPATH) +endif +ifneq (,$(INSTALLSHARES)) $(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(INSTALLSHARERELPATH) - $(Q)$(CP) tools/jtag_openocd $(DESTDIR)$(PREFIX)$(INSTALLSHARERELPATH) - $(Q)$(CP) traces $(DESTDIR)$(PREFIX)$(INSTALLSHARERELPATH) - $(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(INSTALLDOCRELPATH) - $(Q)$(CP) doc/* $(DESTDIR)$(PREFIX)$(INSTALLDOCRELPATH) + $(Q)$(CP) $(INSTALLSHARES) $(DESTDIR)$(PREFIX)$(INSTALLSHARERELPATH) +endif +ifneq (,$(INSTALLDOCS)) + $(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(INSTALLDOCSRELPATH) + $(Q)$(CP) $(INSTALLDOCS) $(DESTDIR)$(PREFIX)$(INSTALLDOCSRELPATH) +endif ifneq (,$(INSTALLTOOLS)) $(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(INSTALLTOOLSRELPATH) $(Q)$(CP) $(foreach tool,$(INSTALLTOOLS),tools/$(tool)) $(DESTDIR)$(PREFIX)$(INSTALLTOOLSRELPATH) @@ -47,13 +51,16 @@ endif uninstall: $(info [@] Uninstalling common resources from $(MYDESTDIR)$(PREFIX)...) - $(Q)$(RM) $(DESTDIR)$(PREFIX)$(INSTALLBINRELPATH)/pm3 - $(Q)$(RM) $(DESTDIR)$(PREFIX)$(INSTALLBINRELPATH)/pm3-flash-all - $(Q)$(RM) $(DESTDIR)$(PREFIX)$(INSTALLBINRELPATH)/pm3-flash-bootrom - $(Q)$(RM) $(DESTDIR)$(PREFIX)$(INSTALLBINRELPATH)/pm3-flash-fullimage - $(Q)$(RMDIR) $(DESTDIR)$(PREFIX)$(INSTALLSHARERELPATH)/jtag_openocd - $(Q)$(RMDIR) $(DESTDIR)$(PREFIX)$(INSTALLSHARERELPATH)/traces - $(Q)$(RMDIR) $(DESTDIR)$(PREFIX)$(INSTALLDOCRELPATH) +ifneq (,$(INSTALLSCRIPTS)) + $(Q)$(RM) $(foreach script,$(INSTALLSCRIPTS),$(DESTDIR)$(PREFIX)$(INSTALLBINRELPATH)$(notdir $(script))) +endif +ifneq (,$(INSTALLSHARES)) + $(Q)$(RMDIR) $(foreach share,$(INSTALLSHARES),$(DESTDIR)$(PREFIX)$(INSTALLSHARERELPATH)$(notdir $(share))) +endif +ifneq (,$(INSTALLDOCS)) + $(Q)$(RMDIR) $(foreach doc,$(INSTALLDOCS),$(DESTDIR)$(PREFIX)$(INSTALLDOCSRELPATH)$(notdir $(doc))) + $(Q)$(RMDIR_SOFT) $(DESTDIR)$(PREFIX)$(INSTALLDOCSRELPATH) +endif ifneq (,$(INSTALLTOOLS)) $(Q)$(RM) $(foreach tool,$(INSTALLTOOLS),$(DESTDIR)$(PREFIX)$(INSTALLTOOLSRELPATH)$(notdir $(tool))) endif diff --git a/Makefile.defs b/Makefile.defs index 3f12cacb3..6364c794a 100644 --- a/Makefile.defs +++ b/Makefile.defs @@ -32,7 +32,7 @@ INSTALLBINRELPATH = /bin/ INSTALLSHARERELPATH = /share/proxmark3/ INSTALLFWRELPATH = /share/proxmark3/firmware/ INSTALLTOOLSRELPATH = /share/proxmark3/tools/ -INSTALLDOCRELPATH = /share/doc/proxmark3/ +INSTALLDOCSRELPATH = /share/doc/proxmark3/ platform = $(shell uname) DETECTED_OS=$(platform) diff --git a/flash-all.sh b/flash-all.sh deleted file mode 100755 index d4fcdc975..000000000 --- a/flash-all.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash - -PM3PATH=$(dirname "$0") -cd "$PM3PATH" || exit 1 -. proxmark3.sh diff --git a/flash-bootrom.sh b/flash-bootrom.sh deleted file mode 100755 index d4fcdc975..000000000 --- a/flash-bootrom.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash - -PM3PATH=$(dirname "$0") -cd "$PM3PATH" || exit 1 -. proxmark3.sh diff --git a/flash-fullimage.sh b/flash-fullimage.sh deleted file mode 100755 index d4fcdc975..000000000 --- a/flash-fullimage.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash - -PM3PATH=$(dirname "$0") -cd "$PM3PATH" || exit 1 -. proxmark3.sh diff --git a/proxmark3.sh b/pm3 similarity index 66% rename from proxmark3.sh rename to pm3 index 89e7e960b..11eb59d31 100755 --- a/proxmark3.sh +++ b/pm3 @@ -1,10 +1,25 @@ #!/bin/bash -FULLIMAGE="armsrc/obj/fullimage.elf" -BOOTIMAGE="bootrom/obj/bootrom.elf" - PM3PATH=$(dirname "$0") -cd "$PM3PATH" || exit 1 +# try pm3 dirs in current repo workdir +if [ -d "$PM3PATH/client/" ]; then + CLIENT="$PM3PATH/client/proxmark3" + FLASHER="$PM3PATH/client/proxmark3-flasher" + FULLIMAGE="$PM3PATH/armsrc/obj/fullimage.elf" + BOOTIMAGE="$PM3PATH/bootrom/obj/bootrom.elf" +# try install dir +elif [ -x "$PM3PATH/proxmark3" ]; then + CLIENT="$PM3PATH/proxmark3" + FLASHER="$PM3PATH/proxmark3-flasher" + FULLIMAGE="$PM3PATH/../share/proxmark3/firmware/fullimage.elf" + BOOTIMAGE="$PM3PATH/../share/proxmark3/firmware/bootrom.elf" +else +# hope it's installed somehow, still not sure where fw images are... + CLIENT="proxmark3" + FLASHER="proxmark3-flasher" + FULLIMAGE="$PM3PATH/../share/proxmark3/firmware/fullimage.elf" + BOOTIMAGE="$PM3PATH/../share/proxmark3/firmware/bootrom.elf" +fi function wait4proxmark_Linux { echo >&2 "[=] Waiting for Proxmark3 to appear..." @@ -63,14 +78,14 @@ function wait4proxmark_WSL { SCRIPT=$(basename -- "$0") -if [ "$SCRIPT" = "proxmark3.sh" ]; then - CMD() { client/proxmark3 "$@"; } -elif [ "$SCRIPT" = "flash-all.sh" ]; then - CMD() { client/flasher "$1" -b "$BOOTIMAGE" "$FULLIMAGE"; } -elif [ "$SCRIPT" = "flash-fullimage.sh" ]; then - CMD() { client/flasher "$1" "$FULLIMAGE"; } -elif [ "$SCRIPT" = "flash-bootrom.sh" ]; then - CMD() { client/flasher "$1" -b "$BOOTIMAGE"; } +if [ "$SCRIPT" = "pm3" ]; then + CMD() { $CLIENT "$@"; } +elif [ "$SCRIPT" = "pm3-flash-all" ]; then + CMD() { $FLASHER "$1" -b "$BOOTIMAGE" "$FULLIMAGE"; } +elif [ "$SCRIPT" = "pm3-flash-fullimage" ]; then + CMD() { $FLASHER "$1" "$FULLIMAGE"; } +elif [ "$SCRIPT" = "pm3-flash-bootrom" ]; then + CMD() { $FLASHER "$1" -b "$BOOTIMAGE"; } else echo "[!!] Script ran under unknown name, abort: $SCRIPT" exit 1 diff --git a/pm3-flash-all b/pm3-flash-all new file mode 100755 index 000000000..e5cd5479d --- /dev/null +++ b/pm3-flash-all @@ -0,0 +1,4 @@ +#!/bin/bash + +PM3PATH=$(dirname "$0") +. "$PM3PATH/pm3" diff --git a/pm3-flash-bootrom b/pm3-flash-bootrom new file mode 100755 index 000000000..e5cd5479d --- /dev/null +++ b/pm3-flash-bootrom @@ -0,0 +1,4 @@ +#!/bin/bash + +PM3PATH=$(dirname "$0") +. "$PM3PATH/pm3" diff --git a/pm3-flash-fullimage b/pm3-flash-fullimage new file mode 100755 index 000000000..e5cd5479d --- /dev/null +++ b/pm3-flash-fullimage @@ -0,0 +1,4 @@ +#!/bin/bash + +PM3PATH=$(dirname "$0") +. "$PM3PATH/pm3" From ddd32bcb4bbcfa26cbe77719f97588ce3261749a Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 30 Aug 2019 23:53:13 +0200 Subject: [PATCH 0548/1854] Maintainers.md --- doc/md/Development/Maintainers.md | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 doc/md/Development/Maintainers.md diff --git a/doc/md/Development/Maintainers.md b/doc/md/Development/Maintainers.md new file mode 100644 index 000000000..9472cacb6 --- /dev/null +++ b/doc/md/Development/Maintainers.md @@ -0,0 +1,31 @@ +Hi maintainers! + +Here are some tips how to integrate this repo in some nice package for your distro. +Feel free to contact us via Github issues for any question, suggestion or if you want to share useful tricks in this file for other maintainers. + +Makefile +======== + +`PREFIX` and `UDEV_PREFIX` can be provided by environment variable, else it defaults to `/usr/local/share` and `/etc/udev/rules.d`. + +`DESTDIR` can be provided by environment variable, it can be a relative path and it will be prepended to `PREFIX`, so you can use e.g.: + +`make install DESTDIR=build PREFIX=/usr UDEV_PREFIX=/lib/udev/rules.d` + +and it will be deployed as + +``` +./build/lib/udev/rules.d/77-pm3-usb-device-blacklist.rules +./build/usr/bin/proxmark3 ... +./build/usr/share/doc/proxmark3/... +./build/usr/share/proxmark3/... +``` + +That should be a good start for you to create your package :) + +For verbose usage and see the actual commands being executed, add `V=1`. + +`CFLAGS` and `LDFLAGS` can be overriden by environment variables. + +Default compiler is gcc but you can use clang for the non-ARM parts with e.g. `make client CC=clang CXX=clang++ LD=clang++`. + From 6949a780fc6928f8dfd12b09484bfdfb5c8db56d Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 31 Aug 2019 00:26:35 +0200 Subject: [PATCH 0549/1854] Add possibility to make install more firmware variants --- Makefile | 2 ++ armsrc/Makefile | 10 ++++++++-- doc/md/Development/Maintainers.md | 15 +++++++++++++-- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 79d9a2ff8..43de3969b 100644 --- a/Makefile +++ b/Makefile @@ -130,6 +130,8 @@ fullimage: armsrc/all fullimage/clean: armsrc/clean +fullimage/install: armsrc/install + recovery: recovery/all mfkey: mfkey/all diff --git a/armsrc/Makefile b/armsrc/Makefile index 8cbe03dab..bb8f17ef2 100644 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@ -135,6 +135,12 @@ include ../common_arm/Makefile.common COMMON_FLAGS = -Os INSTALLFW = $(OBJDIR)/fullimage.elf +ifneq (,$(FWTAG)) + INSTALLFWTAG = $(notdir $(INSTALLFW:%.elf=%-$(FWTAG).elf)) +else + INSTALLFWTAG = $(notdir $(INSTALLFW)) +endif + OBJS = $(OBJDIR)/fullimage.s19 FPGA_COMPRESSOR = ../tools/fpga_compress/fpga_compress @@ -217,11 +223,11 @@ clean: install: all $(info [@] Installing fullimage to $(DESTDIR)$(PREFIX)...) $(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(INSTALLFWRELPATH) - $(Q)$(CP) $(INSTALLFW) $(DESTDIR)$(PREFIX)$(INSTALLFWRELPATH) + $(Q)$(CP) $(INSTALLFW) $(DESTDIR)$(PREFIX)$(INSTALLFWRELPATH)$(INSTALLFWTAG) uninstall: $(info [@] Uninstalling fullimage from $(DESTDIR)$(PREFIX)...) - $(Q)$(RM) $(foreach fw,$(INSTALLFW),$(DESTDIR)$(PREFIX)$(INSTALLFWRELPATH)$(notdir $(fw))) + $(Q)$(RM) $(DESTDIR)$(PREFIX)$(INSTALLFWRELPATH)$(INSTALLFWTAG) .PHONY: all clean help install uninstall help: diff --git a/doc/md/Development/Maintainers.md b/doc/md/Development/Maintainers.md index 9472cacb6..542512fd0 100644 --- a/doc/md/Development/Maintainers.md +++ b/doc/md/Development/Maintainers.md @@ -10,7 +10,7 @@ Makefile `DESTDIR` can be provided by environment variable, it can be a relative path and it will be prepended to `PREFIX`, so you can use e.g.: -`make install DESTDIR=build PREFIX=/usr UDEV_PREFIX=/lib/udev/rules.d` +`make -j install DESTDIR=build PREFIX=/usr UDEV_PREFIX=/lib/udev/rules.d` and it will be deployed as @@ -18,11 +18,22 @@ and it will be deployed as ./build/lib/udev/rules.d/77-pm3-usb-device-blacklist.rules ./build/usr/bin/proxmark3 ... ./build/usr/share/doc/proxmark3/... -./build/usr/share/proxmark3/... +./build/usr/share/proxmark3/firmware/fullimage.elf +etc. ``` That should be a good start for you to create your package :) +It's possible to add other firmwares as well with tagged names (`FWTAG=`), e.g. here we're compiling another image for non-RDV4 devices: + +`make -j fullimage/install DESTDIR=build PREFIX=/usr PLATFORM=PM3OTHER PLATFORM_EXTRAS= FWTAG=other` + +and it will be added along the other firmware as: + +``` +./build/usr/share/proxmark3/firmware/fullimage-other.elf +``` + For verbose usage and see the actual commands being executed, add `V=1`. `CFLAGS` and `LDFLAGS` can be overriden by environment variables. From 555c0743cb044390dc59d2a086a4f4be6ef48345 Mon Sep 17 00:00:00 2001 From: edward-p Date: Sat, 31 Aug 2019 15:31:33 +0800 Subject: [PATCH 0550/1854] Add possibility to make install more recovery variants --- recovery/Makefile | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/recovery/Makefile b/recovery/Makefile index fd10020bf..5a5fda0e8 100644 --- a/recovery/Makefile +++ b/recovery/Makefile @@ -1,6 +1,12 @@ include ../common_arm/Makefile.common INSTALLFW = proxmark3_recovery.bin +ifneq (,$(FWTAG)) + INSTALLFWTAG = $(notdir $(INSTALLFW:%.bin=%-$(FWTAG).bin)) +else + INSTALLFWTAG = $(notdir $(INSTALLFW)) +endif + BINS = bootrom.bin fullimage.bin $(INSTALLFW) all: $(BINS) @@ -23,10 +29,10 @@ clean: install: all $(info [@] Installing recovery to $(DESTDIR)$(PREFIX)...) $(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(INSTALLFWRELPATH) - $(Q)$(CP) $(INSTALLFW) $(DESTDIR)$(PREFIX)$(INSTALLFWRELPATH) + $(Q)$(CP) $(INSTALLFW) $(DESTDIR)$(PREFIX)$(INSTALLFWRELPATH)$(INSTALLFWTAG) uninstall: $(info [@] Uninstalling recovery from $(DESTDIR)$(PREFIX)...) - $(Q)$(RM) $(foreach fw,$(INSTALLFW),$(DESTDIR)$(PREFIX)$(INSTALLFWRELPATH)$(notdir $(fw))) + $(Q)$(RM) $(DESTDIR)$(PREFIX)$(INSTALLFWRELPATH)$(INSTALLFWTAG) .PHONY: all clean install uninstall From 66c8b31e65660e8d871129040a0382551281d9c9 Mon Sep 17 00:00:00 2001 From: Iceman Date: Sat, 31 Aug 2019 10:55:38 +0200 Subject: [PATCH 0551/1854] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2515cb6ec..97dadaabb 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ It is dedicated to bringing the most out of the new features for Proxmark3 RDV4. |[Why didn't you base it on official Proxmark3 Master?](#why-didnt-you-base-it-on-official-proxmark3-master)| [Homebrew (Mac OS X) & Upgrading HomeBrew Tap Formula](/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md) | [First Use and Verification](/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md)| |[Proxmark3 GUI](#proxmark3-gui)|[Setup and build for Windows](/doc/md/Installation_Instructions/Windows-Installation-Instructions.md)|[Commands & Features](/doc/md/Use_of_Proxmark/3_Commands-and-Features.md)| |[Issues](#issues)|[Blue shark manual](/doc/bt_manual_v10.md) |[Advanced compilation parameters](/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md)| -|[Notes on UART](/doc/uart_notes.md)||[Command Cheat sheet](/doc/cheatsheet.md)| +|[Notes on UART](/doc/uart_notes.md)|[Maintainers](/doc/md/Development/Maintainers.md)|[Command Cheat sheet](/doc/cheatsheet.md)| |[Notes on Frame format](/doc/new_frame_format.md)||[More cheat sheets](https://github.com/RfidResearchGroup/proxmark3/wiki/More-cheat-sheets)| |[Notes on external flash](/doc/ext_flash_notes.md)||| |[Notes on Termux / Android](/doc/termux_notes.md)||| From c5c5427f9edeae94786332c3ebc62eda72dcd080 Mon Sep 17 00:00:00 2001 From: Iceman Date: Sat, 31 Aug 2019 10:58:42 +0200 Subject: [PATCH 0552/1854] Update README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 97dadaabb..37b53a95c 100644 --- a/README.md +++ b/README.md @@ -66,6 +66,10 @@ If you intend to contribute to the code, please read the [coding style notes](HA ## Cheat sheet Thanks to Alex Dibs, you can enjoy a [command cheat sheet](/doc/cheatsheet.md) +## Maintainers ( package, distro ) +To all distro, package maintainers, we tried to make your life easier. `make install` is now available and if you want to know more. +- [Maintainers](/doc/md/Development/Maintainers.md) + ## Why didn't you base it on official Proxmark3 Master? The separation from official Proxmark3 repo gives us a lot of freedom to create a firmware/client that suits the RDV40 features. We don't want to mess up the official Proxmark3 repo with RDV40 specific code. From 3c515e8ec545ac101d76f5f31cf682b86d3f6507 Mon Sep 17 00:00:00 2001 From: Iceman Date: Sat, 31 Aug 2019 10:59:21 +0200 Subject: [PATCH 0553/1854] Update Maintainers.md --- doc/md/Development/Maintainers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/md/Development/Maintainers.md b/doc/md/Development/Maintainers.md index 542512fd0..758a4a41d 100644 --- a/doc/md/Development/Maintainers.md +++ b/doc/md/Development/Maintainers.md @@ -1,4 +1,4 @@ -Hi maintainers! +# Hi maintainers! Here are some tips how to integrate this repo in some nice package for your distro. Feel free to contact us via Github issues for any question, suggestion or if you want to share useful tricks in this file for other maintainers. From 5ff9cbaac0c1b52c248cd1ed6ffc41ddd089e6ee Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 31 Aug 2019 15:25:36 +0200 Subject: [PATCH 0554/1854] fix: 'hf iclass eload' - load file works again. --- client/cmdhficlass.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 39fbf9658..26e23d170 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -735,7 +735,7 @@ static int CmdHFiClassELoad(const char *Cmd) { switch (dftype) { case BIN: { - res = loadFile(filename, ".bin", (void *)&dump, 2048, &bytes_read); + res = loadFile_safe(filename, ".bin", (void **)&dump, &bytes_read); break; } case EML: { From b792d0d51b164ec206bce905b480371e58cc34bf Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 31 Aug 2019 19:57:49 +0200 Subject: [PATCH 0555/1854] make -j install fails from now, do make -j; make install --- doc/md/Development/Maintainers.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/doc/md/Development/Maintainers.md b/doc/md/Development/Maintainers.md index 758a4a41d..b59987881 100644 --- a/doc/md/Development/Maintainers.md +++ b/doc/md/Development/Maintainers.md @@ -10,7 +10,10 @@ Makefile `DESTDIR` can be provided by environment variable, it can be a relative path and it will be prepended to `PREFIX`, so you can use e.g.: -`make -j install DESTDIR=build PREFIX=/usr UDEV_PREFIX=/lib/udev/rules.d` +``` +make -j +make install DESTDIR=build PREFIX=/usr UDEV_PREFIX=/lib/udev/rules.d +``` and it will be deployed as From 3352904f1d08dcc76424c64b3b9bcc67a53356ed Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 31 Aug 2019 21:47:31 +0200 Subject: [PATCH 0556/1854] chg 'mem spiffs load' - use loadfile_safe --- client/cmdflashmemspiffs.c | 40 +++++++++++--------------------------- 1 file changed, 11 insertions(+), 29 deletions(-) diff --git a/client/cmdflashmemspiffs.c b/client/cmdflashmemspiffs.c index 5783e2705..0eef78259 100644 --- a/client/cmdflashmemspiffs.c +++ b/client/cmdflashmemspiffs.c @@ -330,12 +330,15 @@ static int CmdFlashMemSpiFFSLoad(const char *Cmd) { if (param_getstr(Cmd, cmdp + 1, filename, FILE_PATH_SIZE) >= FILE_PATH_SIZE) { PrintAndLogEx(FAILED, "Filename too long"); errors = true; - break; } cmdp += 2; break; case 'o': param_getstr(Cmd, cmdp + 1, destfilename, 32); + if (strlen(destfilename) == 0) { + PrintAndLogEx(FAILED, "Destination Filename missing or invalid"); + errors = true; + } cmdp += 2; break; default: @@ -345,42 +348,20 @@ static int CmdFlashMemSpiFFSLoad(const char *Cmd) { } } - if (destfilename[0] == '\0') { - PrintAndLogEx(FAILED, "Destination Filename missing or invalid"); - errors = true; - } - // Validations - if (errors || cmdp == 0) { - usage_flashmemspiffs_load(); - return PM3_EINVARG; - } + if (errors || cmdp == 0) + return usage_flashmemspiffs_load(); size_t datalen = 0; - int res = 0; - uint8_t *data = calloc(FLASH_MEM_MAX_SIZE, sizeof(uint8_t)); + uint8_t *data = NULL; - res = loadFile(filename, "", data, FLASH_MEM_MAX_SIZE, &datalen); + int res = loadFile_safe(filename, "", (void**)&data, &datalen); // int res = loadFileEML( filename, data, &datalen); - if (res) { + if (res != PM3_SUCCESS) { free(data); return PM3_EFILE; } - - if (datalen > FLASH_MEM_MAX_SIZE) { - PrintAndLogEx(ERR, "error, filesize is larger than available memory"); - free(data); - return PM3_EOVFLOW; - } - - uint8_t *newdata = realloc(data, datalen); - if (newdata == NULL) { - free(data); - return PM3_EMALLOC; - } else { - data = newdata; - } - + // We want to mount before multiple operation so the lazy writes/append will not // trigger a mount + umount each loop iteration (lazy ops device side) SendCommandNG(CMD_SPIFFS_MOUNT, NULL, 0); @@ -425,6 +406,7 @@ static int CmdFlashMemSpiFFSLoad(const char *Cmd) { if (!isok) { conn.block_after_ACK = false; PrintAndLogEx(FAILED, "Flash write fail [offset %u]", bytes_sent); + free(data); return PM3_EFLASH; } } From f1d31f1e4328d9eb5a2db20ac03b0abe34a41d20 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 31 Aug 2019 21:49:59 +0200 Subject: [PATCH 0557/1854] chg: 'mem load' - use loadxxxx_safe method --- client/cmdflashmem.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/client/cmdflashmem.c b/client/cmdflashmem.c index 7f1fa103e..0fb25fad9 100644 --- a/client/cmdflashmem.c +++ b/client/cmdflashmem.c @@ -209,9 +209,8 @@ static int CmdFlashMemLoad(const char *Cmd) { datalen += 2; break; case DICTIONARY_NONE: - res = loadFile(filename, ".bin", data, FLASH_MEM_MAX_SIZE, &datalen); - //int res = loadFileEML( filename, data, &datalen); - if (res) { + res = loadFile_safe(filename, ".bin", (void**)&data, &datalen); + if (res != PM3_SUCCESS) { free(data); return PM3_EFILE; } @@ -223,7 +222,7 @@ static int CmdFlashMemLoad(const char *Cmd) { } break; } - +// not needed when we transite to loadxxxx_safe methods.(iceman) uint8_t *newdata = realloc(data, datalen); if (newdata == NULL) { free(data); From d4e8ac27a3edf7cdfa925463ab7f6ebf08d6bc0d Mon Sep 17 00:00:00 2001 From: Oleg Moiseenko <807634+merlokk@users.noreply.github.com> Date: Sun, 1 Sep 2019 00:56:24 +0300 Subject: [PATCH 0558/1854] appveyor make install (#383) --- appveyor.yml | 48 +++++++++++++++++------------------------------- 1 file changed, 17 insertions(+), 31 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 1c4cc5ae5..fa8776607 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -200,45 +200,31 @@ build_script: } - #copy + #install - Write-Host "Copy release files..." -NoNewLine -ForegroundColor Yellow + Write-Host "Installing..." -NoNewLine -ForegroundColor Yellow - New-Item -ItemType Directory -Force -Path C:\ProxSpace\Release + New-Item -ItemType Directory -Force -Path C:\ProxSpace\pm3\Release\bin - Copy-Item C:\ProxSpace\pm3\client\*.exe C:\ProxSpace\Release - - New-Item -ItemType Directory -Force -Path C:\ProxSpace\Release\arm - - Copy-Item C:\ProxSpace\pm3\armsrc\obj\*.elf C:\ProxSpace\Release\arm - - Copy-Item C:\ProxSpace\pm3\bootrom\obj\*.elf C:\ProxSpace\Release\arm - - New-Item -ItemType Directory -Force -Path C:\ProxSpace\Release\luascripts - - Copy-Item C:\ProxSpace\pm3\client\luascripts\*.lua C:\ProxSpace\Release\luascripts - - New-Item -ItemType Directory -Force -Path C:\ProxSpace\Release\hardnested\tables - - Copy-Item C:\ProxSpace\pm3\client\resources\hardnested_tables\*.bin.z C:\ProxSpace\Release\hardnested\tables + bash -c -i 'make install DESTDIR=Release PREFIX= UDEV_PREFIX=\udev\rules.d' # dll files - Copy-Item C:\ProxSpace\msys2\mingw32\bin\libgcc_s_dw2-1.dll C:\ProxSpace\Release + Copy-Item C:\ProxSpace\msys2\mingw32\bin\libgcc_s_dw2-1.dll C:\ProxSpace\pm3\Release\bin - Copy-Item C:\ProxSpace\msys2\mingw32\bin\libstdc++-6.dll C:\ProxSpace\Release + Copy-Item C:\ProxSpace\msys2\mingw32\bin\libstdc++-6.dll C:\ProxSpace\pm3\Release\bin - Copy-Item C:\ProxSpace\msys2\mingw32\bin\libwinpthread-1.dll C:\ProxSpace\Release + Copy-Item C:\ProxSpace\msys2\mingw32\bin\libwinpthread-1.dll C:\ProxSpace\pm3\Release\bin - Copy-Item C:\ProxSpace\msys2\mingw32\bin\Qt5Core.dll C:\ProxSpace\Release + Copy-Item C:\ProxSpace\msys2\mingw32\bin\Qt5Core.dll C:\ProxSpace\pm3\Release\bin - Copy-Item C:\ProxSpace\msys2\mingw32\bin\Qt5Gui.dll C:\ProxSpace\Release + Copy-Item C:\ProxSpace\msys2\mingw32\bin\Qt5Gui.dll C:\ProxSpace\pm3\Release\bin - Copy-Item C:\ProxSpace\msys2\mingw32\bin\Qt5Widgets.dll C:\ProxSpace\Release + Copy-Item C:\ProxSpace\msys2\mingw32\bin\Qt5Widgets.dll C:\ProxSpace\pm3\Release\bin - Copy-Item C:\ProxSpace\msys2\mingw32\bin\libreadline*.dll C:\ProxSpace\Release + Copy-Item C:\ProxSpace\msys2\mingw32\bin\libreadline*.dll C:\ProxSpace\pm3\Release\bin - Copy-Item C:\ProxSpace\msys2\mingw32\bin\libtermcap-0.dll C:\ProxSpace\Release + Copy-Item C:\ProxSpace\msys2\mingw32\bin\libtermcap-0.dll C:\ProxSpace\pm3\Release\bin Write-Host "[ OK ]" -ForegroundColor Green @@ -260,7 +246,7 @@ build_script: cd C:\ProxSpace - 7z a release.zip C:\ProxSpace\Release + 7z a release.zip C:\ProxSpace\pm3\Release Push-AppveyorArtifact release.zip -DeploymentName "$releasename" @@ -366,13 +352,13 @@ test_script: #file test - ExecTest "proxmark3 exists" "proxmark3.exe" {Test-Path C:\ProxSpace\Release\proxmark3.exe} + ExecTest "proxmark3 exists" "proxmark3.exe" {Test-Path C:\ProxSpace\pm3\Release\bin\proxmark3.exe} - ExecTest "arm image exists" "\arm\fullimage1.elf" {Test-Path C:\ProxSpace\Release\arm\fullimage.elf} + ExecTest "arm image exists" "pm3-flash-fullimage" {Test-Path C:\ProxSpace\pm3\Release\bin\pm3-flash-fullimage} - ExecTest "bootrom exists" "bootrom.elf" {Test-Path C:\ProxSpace\Release\arm\bootrom.elf} + ExecTest "bootrom exists" "pm3-flash-bootrom" {Test-Path C:\ProxSpace\pm3\Release\bin\pm3-flash-bootrom} - ExecTest "hardnested tables exists" "hardnested" {Test-Path C:\ProxSpace\Release\hardnested\tables\*.z} + ExecTest "hardnested tables exists" "hardnested" {Test-Path C:\ProxSpace\pm3\Release\share\proxmark3\resources\hardnested_tables\*.z} ExecTest "release exists" "release.zip" {Test-Path C:\ProxSpace\release.zip} From b4400bbcecea28eabddcdac1f9e6d209e0ca3ff0 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 1 Sep 2019 12:09:31 +0200 Subject: [PATCH 0559/1854] appveyor: no udev on windows, fix check fw images --- appveyor.yml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index fa8776607..af725ef93 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -206,8 +206,8 @@ build_script: New-Item -ItemType Directory -Force -Path C:\ProxSpace\pm3\Release\bin - bash -c -i 'make install DESTDIR=Release PREFIX= UDEV_PREFIX=\udev\rules.d' - + bash -c -i 'make install DESTDIR=Release PREFIX=' + # dll files Copy-Item C:\ProxSpace\msys2\mingw32\bin\libgcc_s_dw2-1.dll C:\ProxSpace\pm3\Release\bin @@ -354,9 +354,11 @@ test_script: ExecTest "proxmark3 exists" "proxmark3.exe" {Test-Path C:\ProxSpace\pm3\Release\bin\proxmark3.exe} - ExecTest "arm image exists" "pm3-flash-fullimage" {Test-Path C:\ProxSpace\pm3\Release\bin\pm3-flash-fullimage} + ExecTest "arm bootrom exists" "bootrom.elf" {Test-Path C:\ProxSpace\pm3\Release\share\proxmark3\firmware\bootrom.elf} - ExecTest "bootrom exists" "pm3-flash-bootrom" {Test-Path C:\ProxSpace\pm3\Release\bin\pm3-flash-bootrom} + ExecTest "arm image exists" "fullimage.elf" {Test-Path C:\ProxSpace\pm3\Release\share\proxmark3\firmware\fullimage.elf} + + ExecTest "arm recovery image exists" "proxmark3_recovery.bin" {Test-Path C:\ProxSpace\pm3\Release\share\proxmark3\firmware\proxmark3_recovery.bin} ExecTest "hardnested tables exists" "hardnested" {Test-Path C:\ProxSpace\pm3\Release\share\proxmark3\resources\hardnested_tables\*.z} From 3cedaf450d961bbf72dd49fb59839d382bb5efa3 Mon Sep 17 00:00:00 2001 From: Iceman Date: Sun, 1 Sep 2019 18:05:23 +0200 Subject: [PATCH 0560/1854] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 37b53a95c..74ee01f37 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ It is dedicated to bringing the most out of the new features for Proxmark3 RDV4. |[Issues](#issues)|[Blue shark manual](/doc/bt_manual_v10.md) |[Advanced compilation parameters](/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md)| |[Notes on UART](/doc/uart_notes.md)|[Maintainers](/doc/md/Development/Maintainers.md)|[Command Cheat sheet](/doc/cheatsheet.md)| |[Notes on Frame format](/doc/new_frame_format.md)||[More cheat sheets](https://github.com/RfidResearchGroup/proxmark3/wiki/More-cheat-sheets)| -|[Notes on external flash](/doc/ext_flash_notes.md)||| +|[Notes on external flash](/doc/ext_flash_notes.md)||[EMV](/doc/emv_notes.md)| |[Notes on Termux / Android](/doc/termux_notes.md)||| |[Notes on Wireshark / tracedata](/doc/trace_wireshark_notes.md)||| |[Notes on loclass](/doc/loclass_notes.md)||| @@ -62,6 +62,7 @@ If you intend to contribute to the code, please read the [coding style notes](HA - Internal notes on [Termux / Android](/doc/termux_notes.md) - Internal notes on [Wireshark / tracedata](/doc/trace_wireshark_notes.md) - Internal notes on [loclass](/doc/loclass_notes.md) +- Internal notes on [EMV](/doc/emv_notes.md) ## Cheat sheet Thanks to Alex Dibs, you can enjoy a [command cheat sheet](/doc/cheatsheet.md) From 854374a344d4e22cfd10a6fe1b78219e76437806 Mon Sep 17 00:00:00 2001 From: Iceman Date: Sun, 1 Sep 2019 18:07:57 +0200 Subject: [PATCH 0561/1854] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 74ee01f37..7acb362a3 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ It is dedicated to bringing the most out of the new features for Proxmark3 RDV4. |[Notes on UART](/doc/uart_notes.md)|[Maintainers](/doc/md/Development/Maintainers.md)|[Command Cheat sheet](/doc/cheatsheet.md)| |[Notes on Frame format](/doc/new_frame_format.md)||[More cheat sheets](https://github.com/RfidResearchGroup/proxmark3/wiki/More-cheat-sheets)| |[Notes on external flash](/doc/ext_flash_notes.md)||[EMV](/doc/emv_notes.md)| -|[Notes on Termux / Android](/doc/termux_notes.md)||| +|[Notes on Termux / Android](/doc/termux_notes.md)||[Troubleshooting](/doc/md/Installation_Instructions/Troubleshooting.md)| |[Notes on Wireshark / tracedata](/doc/trace_wireshark_notes.md)||| |[Notes on loclass](/doc/loclass_notes.md)||| |[Developing standalone mode](/armsrc/Standalone/readme.md)|[Wiki about standalone mode](https://github.com/RfidResearchGroup/proxmark3/wiki/Standalone-mode) || From a8d2f395e2490bccce13e5b29234b9ddd7e1b5e0 Mon Sep 17 00:00:00 2001 From: Iceman Date: Sun, 1 Sep 2019 18:09:10 +0200 Subject: [PATCH 0562/1854] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7acb362a3..26a1ae126 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ It is dedicated to bringing the most out of the new features for Proxmark3 RDV4. |[Notes on Frame format](/doc/new_frame_format.md)||[More cheat sheets](https://github.com/RfidResearchGroup/proxmark3/wiki/More-cheat-sheets)| |[Notes on external flash](/doc/ext_flash_notes.md)||[EMV](/doc/emv_notes.md)| |[Notes on Termux / Android](/doc/termux_notes.md)||[Troubleshooting](/doc/md/Installation_Instructions/Troubleshooting.md)| -|[Notes on Wireshark / tracedata](/doc/trace_wireshark_notes.md)||| +|[Notes on Wireshark / tracedata](/doc/trace_wireshark_notes.md)||[JTAG](/doc/jtag_notes.md)| |[Notes on loclass](/doc/loclass_notes.md)||| |[Developing standalone mode](/armsrc/Standalone/readme.md)|[Wiki about standalone mode](https://github.com/RfidResearchGroup/proxmark3/wiki/Standalone-mode) || |[Donations](#Donations)||| From e80fe2588b3df5d0a1e699c2ff0a750f32b64c16 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 1 Sep 2019 19:30:29 +0200 Subject: [PATCH 0563/1854] "which" not always available... --- tools/mkversion.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/mkversion.sh b/tools/mkversion.sh index b91eab8af..f839f6e18 100755 --- a/tools/mkversion.sh +++ b/tools/mkversion.sh @@ -14,7 +14,7 @@ fullgitinfo="RRG/Iceman" clean=2 # Do we have acces to git command? -commandGIT=$(env which git) +commandGIT=$(env git) if [ "$commandGIT" != "" ]; then From 0bd3d3673f42cce9aa0a8158d05dcbba724f09b5 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 1 Sep 2019 19:52:14 +0200 Subject: [PATCH 0564/1854] remove p7zip requirement --- .../Linux-Installation-Instructions.md | 2 +- .../Mac-OS-X-Homebrew-Installation-Instructions.md | 2 +- .../Windows-Installation-Instructions.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/md/Installation_Instructions/Linux-Installation-Instructions.md b/doc/md/Installation_Instructions/Linux-Installation-Instructions.md index aa3ce9272..738784301 100644 --- a/doc/md/Installation_Instructions/Linux-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Linux-Installation-Instructions.md @@ -24,7 +24,7 @@ sudo apt-get update Install the requirements ```sh -sudo apt-get install p7zip git ca-certificates build-essential libreadline5 libreadline-dev \ +sudo apt-get install git ca-certificates build-essential libreadline5 libreadline-dev \ libusb-0.1-4 libusb-dev pkg-config wget gcc-arm-none-eabi libnewlib-dev libqt4-dev ``` diff --git a/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md b/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md index 09b986ff3..808b2c7ce 100644 --- a/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md @@ -66,7 +66,7 @@ These instructions will show how to setup the environment on OSX to the point wh 2. Install dependencies: ``` -brew install readline p7zip libusb-compat qt5 wget pkgconfig +brew install readline libusb-compat qt5 wget pkgconfig brew install RfidResearchGroup/proxmark3/arm-none-eabi-gcc ``` diff --git a/doc/md/Installation_Instructions/Windows-Installation-Instructions.md b/doc/md/Installation_Instructions/Windows-Installation-Instructions.md index f01e695e9..db378b615 100644 --- a/doc/md/Installation_Instructions/Windows-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Windows-Installation-Instructions.md @@ -98,7 +98,7 @@ Enter WSL prompt (`wsl`) and from there, follow the [Linux Installation Instruct ```sh sudo apt-get update -sudo apt-get install p7zip git ca-certificates build-essential libreadline5 libreadline-dev libusb-0.1-4 \ +sudo apt-get install git ca-certificates build-essential libreadline5 libreadline-dev libusb-0.1-4 \ libusb-dev pkg-config wget gcc-arm-none-eabi libstdc++-arm-none-eabi-newlib \ libqt4-dev ``` From bd4cce1270fc6ed7ff92ae6f097bb17a1115f1d3 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 1 Sep 2019 20:02:48 +0200 Subject: [PATCH 0565/1854] remove global libusb requirement, add note to compile HID flasher --- .../Linux-Installation-Instructions.md | 4 ++-- .../Mac-OS-X-Homebrew-Installation-Instructions.md | 2 +- .../Windows-Installation-Instructions.md | 4 ++-- tools/deprecated-hid-flasher/flasher/README.md | 9 +++++++++ 4 files changed, 14 insertions(+), 5 deletions(-) create mode 100644 tools/deprecated-hid-flasher/flasher/README.md diff --git a/doc/md/Installation_Instructions/Linux-Installation-Instructions.md b/doc/md/Installation_Instructions/Linux-Installation-Instructions.md index 738784301..55a906a4e 100644 --- a/doc/md/Installation_Instructions/Linux-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Linux-Installation-Instructions.md @@ -25,7 +25,7 @@ Install the requirements ```sh sudo apt-get install git ca-certificates build-essential libreadline5 libreadline-dev \ -libusb-0.1-4 libusb-dev pkg-config wget gcc-arm-none-eabi libnewlib-dev libqt4-dev +pkg-config wget gcc-arm-none-eabi libnewlib-dev libqt4-dev ``` If you don't need the graphical components of the Proxmark3 client, you can skip the installation of `libqt4-dev`. @@ -35,7 +35,7 @@ If you get some (non blocking) error at runtime such as _Gtk-Message: Failed to ## On ArchLinux ```sh -sudo pacman -Sy base-devel p7zip libusb readline arm-none-eabi-gcc arm-none-eabi-newlib git --needed +sudo pacman -Sy base-devel readline arm-none-eabi-gcc arm-none-eabi-newlib git --needed ``` If you want graphical output (such as in `hw tune`): ```sh diff --git a/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md b/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md index 808b2c7ce..2ad0efc23 100644 --- a/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md @@ -66,7 +66,7 @@ These instructions will show how to setup the environment on OSX to the point wh 2. Install dependencies: ``` -brew install readline libusb-compat qt5 wget pkgconfig +brew install readline qt5 wget pkgconfig brew install RfidResearchGroup/proxmark3/arm-none-eabi-gcc ``` diff --git a/doc/md/Installation_Instructions/Windows-Installation-Instructions.md b/doc/md/Installation_Instructions/Windows-Installation-Instructions.md index db378b615..61eebe47d 100644 --- a/doc/md/Installation_Instructions/Windows-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Windows-Installation-Instructions.md @@ -98,8 +98,8 @@ Enter WSL prompt (`wsl`) and from there, follow the [Linux Installation Instruct ```sh sudo apt-get update -sudo apt-get install git ca-certificates build-essential libreadline5 libreadline-dev libusb-0.1-4 \ -libusb-dev pkg-config wget gcc-arm-none-eabi libstdc++-arm-none-eabi-newlib \ +sudo apt-get install git ca-certificates build-essential libreadline5 libreadline-dev \ +pkg-config wget gcc-arm-none-eabi libstdc++-arm-none-eabi-newlib \ libqt4-dev ``` diff --git a/tools/deprecated-hid-flasher/flasher/README.md b/tools/deprecated-hid-flasher/flasher/README.md new file mode 100644 index 000000000..d8086a7bc --- /dev/null +++ b/tools/deprecated-hid-flasher/flasher/README.md @@ -0,0 +1,9 @@ +Compilation notes +================= + +Besides the global Proxmark3 requirements, this flasher compatible with very old firmwares requires the libusb 0.1 to work. +So you'll need to install the libusb 0.1 package first. + +* OSX: libusb-compat +* Debian-alike: libusb-0.1-4 libusb-dev +* Arch: libusb From 43ed7ff1458c094e39565bd5c168e4409e09bea8 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 1 Sep 2019 20:03:59 +0200 Subject: [PATCH 0566/1854] reduce Travis prereqs --- .travis.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index ac39433f8..c75bffe9b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -36,11 +36,7 @@ addons: homebrew: packages: - readline - - p7zip - - libusb-compat - - perl - qt5 - - wget - RfidResearchGroup/proxmark3/arm-none-eabi-gcc taps: RfidResearchGroup/proxmark3 From d0ad275f1e083a0ac85c2334ef1aed367cc3cfaf Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 1 Sep 2019 20:05:08 +0200 Subject: [PATCH 0567/1854] Remove wget from global requirements --- .../Linux-Installation-Instructions.md | 2 +- .../Mac-OS-X-Homebrew-Installation-Instructions.md | 2 +- .../Windows-Installation-Instructions.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/md/Installation_Instructions/Linux-Installation-Instructions.md b/doc/md/Installation_Instructions/Linux-Installation-Instructions.md index 55a906a4e..bbf4587e8 100644 --- a/doc/md/Installation_Instructions/Linux-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Linux-Installation-Instructions.md @@ -25,7 +25,7 @@ Install the requirements ```sh sudo apt-get install git ca-certificates build-essential libreadline5 libreadline-dev \ -pkg-config wget gcc-arm-none-eabi libnewlib-dev libqt4-dev +pkg-config gcc-arm-none-eabi libnewlib-dev libqt4-dev ``` If you don't need the graphical components of the Proxmark3 client, you can skip the installation of `libqt4-dev`. diff --git a/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md b/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md index 2ad0efc23..4e225b318 100644 --- a/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md @@ -66,7 +66,7 @@ These instructions will show how to setup the environment on OSX to the point wh 2. Install dependencies: ``` -brew install readline qt5 wget pkgconfig +brew install readline qt5 pkgconfig brew install RfidResearchGroup/proxmark3/arm-none-eabi-gcc ``` diff --git a/doc/md/Installation_Instructions/Windows-Installation-Instructions.md b/doc/md/Installation_Instructions/Windows-Installation-Instructions.md index 61eebe47d..4e7f6bac2 100644 --- a/doc/md/Installation_Instructions/Windows-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Windows-Installation-Instructions.md @@ -99,7 +99,7 @@ Enter WSL prompt (`wsl`) and from there, follow the [Linux Installation Instruct ```sh sudo apt-get update sudo apt-get install git ca-certificates build-essential libreadline5 libreadline-dev \ -pkg-config wget gcc-arm-none-eabi libstdc++-arm-none-eabi-newlib \ +pkg-config gcc-arm-none-eabi libstdc++-arm-none-eabi-newlib \ libqt4-dev ``` From bf8d4ece1898001858db684270eed8a413fb0ca5 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 1 Sep 2019 20:09:03 +0200 Subject: [PATCH 0568/1854] Add instructions for Fedora --- .../Linux-Installation-Instructions.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/md/Installation_Instructions/Linux-Installation-Instructions.md b/doc/md/Installation_Instructions/Linux-Installation-Instructions.md index bbf4587e8..786c73d36 100644 --- a/doc/md/Installation_Instructions/Linux-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Linux-Installation-Instructions.md @@ -42,6 +42,12 @@ If you want graphical output (such as in `hw tune`): sudo pacman -Su qt5-base ``` +## On Fedora + +```sh +sudo dnf install git make gcc gcc-c++ arm-none-eabi-gcc-cs arm-none-eabi-newlib readline-devel qt5-qtbase-devel libatomic +``` + # Clone the RRG/Iceman repository ```sh From 27a0402a3d039449e026c651414afb3507cd17aa Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 1 Sep 2019 20:13:33 +0200 Subject: [PATCH 0569/1854] HID flasher: add libusb for Fedora in readme --- tools/deprecated-hid-flasher/flasher/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/deprecated-hid-flasher/flasher/README.md b/tools/deprecated-hid-flasher/flasher/README.md index d8086a7bc..c5ddfed62 100644 --- a/tools/deprecated-hid-flasher/flasher/README.md +++ b/tools/deprecated-hid-flasher/flasher/README.md @@ -7,3 +7,4 @@ So you'll need to install the libusb 0.1 package first. * OSX: libusb-compat * Debian-alike: libusb-0.1-4 libusb-dev * Arch: libusb +* Fedora: libusb-devel From 1cc027d41af549c5d29ae49eb9c469a3777987ec Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 1 Sep 2019 22:51:08 +0200 Subject: [PATCH 0570/1854] Debian/WSL: align reqs and move to QT5 by default --- .../Linux-Installation-Instructions.md | 8 +++++--- .../Windows-Installation-Instructions.md | 7 +++---- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/doc/md/Installation_Instructions/Linux-Installation-Instructions.md b/doc/md/Installation_Instructions/Linux-Installation-Instructions.md index 786c73d36..70d102aa3 100644 --- a/doc/md/Installation_Instructions/Linux-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Linux-Installation-Instructions.md @@ -24,11 +24,11 @@ sudo apt-get update Install the requirements ```sh -sudo apt-get install git ca-certificates build-essential libreadline5 libreadline-dev \ -pkg-config gcc-arm-none-eabi libnewlib-dev libqt4-dev +sudo apt-get install --no-install-recommends git ca-certificates build-essential pkg-config \ +libreadline-dev gcc-arm-none-eabi libnewlib-dev qtbase5-dev ``` -If you don't need the graphical components of the Proxmark3 client, you can skip the installation of `libqt4-dev`. +If you don't need the graphical components of the Proxmark3 client, you can skip the installation of `qtbase5-dev`. If you get some (non blocking) error at runtime such as _Gtk-Message: Failed to load module "canberra-gtk-module"_ you may have to install `libcanberra-gtk-module`. @@ -48,6 +48,8 @@ sudo pacman -Su qt5-base sudo dnf install git make gcc gcc-c++ arm-none-eabi-gcc-cs arm-none-eabi-newlib readline-devel qt5-qtbase-devel libatomic ``` +If you don't need the graphical components of the Proxmark3 client, you can skip the installation of `qt5-qtbase-devel`. + # Clone the RRG/Iceman repository ```sh diff --git a/doc/md/Installation_Instructions/Windows-Installation-Instructions.md b/doc/md/Installation_Instructions/Windows-Installation-Instructions.md index 4e7f6bac2..f9eb9e988 100644 --- a/doc/md/Installation_Instructions/Windows-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Windows-Installation-Instructions.md @@ -98,12 +98,11 @@ Enter WSL prompt (`wsl`) and from there, follow the [Linux Installation Instruct ```sh sudo apt-get update -sudo apt-get install git ca-certificates build-essential libreadline5 libreadline-dev \ -pkg-config gcc-arm-none-eabi libstdc++-arm-none-eabi-newlib \ -libqt4-dev +sudo apt-get install --no-install-recommends git ca-certificates build-essential pkg-config \ +libreadline-dev gcc-arm-none-eabi libnewlib-dev qtbase5-dev ``` -If you don't need the graphical components of the Proxmark3 client, you can skip the installation of `libqt4-dev`. +If you don't need the graphical components of the Proxmark3 client, you can skip the installation of `qtbase5-dev`. ## Clone the RRG/Iceman repository From 002580b6d4ad57b1ea47af90a4c9b9ad7d8899b9 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 2 Sep 2019 22:46:06 +0200 Subject: [PATCH 0571/1854] fido: fix typos --- client/cmdhffido.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/client/cmdhffido.c b/client/cmdhffido.c index e9b3376a9..a7ce63c98 100644 --- a/client/cmdhffido.c +++ b/client/cmdhffido.c @@ -44,7 +44,7 @@ static int CmdHelp(const char *Cmd); static int CmdHFFidoInfo(const char *cmd) { if (cmd && strlen(cmd) > 0) - PrintAndLogEx(WARNING, "WARNING: command don't have any parameters.\n"); + PrintAndLogEx(WARNING, "WARNING: command doesn't have any parameters.\n"); // info about 14a part infoHF14A(false, false); @@ -75,14 +75,14 @@ static int CmdHFFidoInfo(const char *cmd) { if (!strncmp((char *)buf, "U2F_V2", 7)) { if (!strncmp((char *)buf, "FIDO_2_0", 8)) { - PrintAndLogEx(INFO, "FIDO2 authenricator detected. Version: %.*s", len, buf); + PrintAndLogEx(INFO, "FIDO2 authenticator detected. Version: %.*s", len, buf); } else { - PrintAndLogEx(INFO, "FIDO authenricator detected (not standard U2F)."); + PrintAndLogEx(INFO, "FIDO authenticator detected (not standard U2F)."); PrintAndLogEx(INFO, "Non U2F authenticator version:"); dump_buffer((const unsigned char *)buf, len, NULL, 0); } } else { - PrintAndLogEx(INFO, "FIDO U2F authenricator detected. Version: %.*s", len, buf); + PrintAndLogEx(INFO, "FIDO U2F authenticator detected. Version: %.*s", len, buf); } res = FIDO2GetInfo(buf, sizeof(buf), &len, &sw); @@ -91,13 +91,13 @@ static int CmdHFFidoInfo(const char *cmd) { return res; } if (sw != 0x9000) { - PrintAndLogEx(ERR, "FIDO2 version not exists (%04x - %s).", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); + PrintAndLogEx(ERR, "FIDO2 version doesn't exist (%04x - %s).", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); return 0; } if (buf[0]) { - PrintAndLogEx(ERR, "FIDO2 ger version error: %d - %s", buf[0], fido2GetCmdErrorDescription(buf[0])); + PrintAndLogEx(ERR, "FIDO2 get version error: %d - %s", buf[0], fido2GetCmdErrorDescription(buf[0])); return 0; } @@ -163,14 +163,14 @@ static int CmdHFFidoRegister(const char *cmd) { json_t *root = NULL; CLIParserInit("hf fido reg", - "Initiate a U2F token registration. Needs two 32-byte hash number. \nchallenge parameter (32b) and application parameter (32b).", + "Initiate a U2F token registration. Needs two 32-byte hash numbers. \nchallenge parameter (32b) and application parameter (32b).", "Usage:\n\thf fido reg -> execute command with 2 parameters, filled 0x00\n" "\thf fido reg 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f -> execute command with parameters" "\thf fido reg -p s0 s1 -> execute command with plain parameters"); void *argtable[] = { arg_param_begin, - arg_lit0("aA", "apdu", "show APDU reqests and responses"), + arg_lit0("aA", "apdu", "show APDU requests and responses"), arg_litn("vV", "verbose", 0, 2, "show technical data. vv - show full certificates data"), arg_lit0("pP", "plain", "send plain ASCII to challenge and application parameters instead of HEX"), arg_lit0("tT", "tlv", "Show DER certificate contents in TLV representation"), @@ -393,7 +393,7 @@ static int CmdHFFidoAuthenticate(const char *cmd) { json_t *root = NULL; CLIParserInit("hf fido auth", - "Initiate a U2F token authentication. Needs key handle and two 32-byte hash number. \nkey handle(var 0..255), challenge parameter (32b) and application parameter (32b).", + "Initiate a U2F token authentication. Needs key handle and two 32-byte hash numbers. \nkey handle(var 0..255), challenge parameter (32b) and application parameter (32b).", "Usage:\n\thf fido auth 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f -> execute command with 2 parameters, filled 0x00 and key handle\n" "\thf fido auth 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f " "000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f -> execute command with parameters"); @@ -640,8 +640,8 @@ static int CmdHFFido2MakeCredential(const char *cmd) { char fname[300] = {0}; CLIParserInit("hf fido make", - "Execute a FIDO2 Make Credentional command. Needs json file with parameters. Sample file `fido2.json`. File can be placed in proxmark directory or in `proxmark/fido` directory.", - "Usage:\n\thf fido make -> execute command default parameters file `fido2.json`\n" + "Execute a FIDO2 Make Credential command. Needs json file with parameters. Sample file " _YELLOW_("`fido2.json`") " in `resources/`.", + "Usage:\n\thf fido make -> execute command with default parameters file `fido2.json`\n" "\thf fido make test.json -> execute command with parameters file `text.json`"); void *argtable[] = { @@ -713,7 +713,7 @@ static int CmdHFFido2MakeCredential(const char *cmd) { return res; if (showCBOR) { - PrintAndLogEx(INFO, "CBOR make credentional request:"); + PrintAndLogEx(INFO, "CBOR make credential request:"); PrintAndLogEx(NORMAL, "---------------- CBOR ------------------"); TinyCborPrintFIDOPackage(fido2CmdMakeCredential, false, data, datalen); PrintAndLogEx(NORMAL, "---------------- CBOR ------------------"); @@ -738,7 +738,7 @@ static int CmdHFFido2MakeCredential(const char *cmd) { PrintAndLogEx(SUCCESS, "MakeCredential result (%d b) OK.", len); if (showCBOR) { - PrintAndLogEx(SUCCESS, "CBOR make credentional response:"); + PrintAndLogEx(SUCCESS, "CBOR make credential response:"); PrintAndLogEx(NORMAL, "---------------- CBOR ------------------"); TinyCborPrintFIDOPackage(fido2CmdMakeCredential, true, &buf[1], len - 1); PrintAndLogEx(NORMAL, "---------------- CBOR ------------------"); @@ -766,8 +766,8 @@ static int CmdHFFido2GetAssertion(const char *cmd) { char fname[300] = {0}; CLIParserInit("hf fido assert", - "Execute a FIDO2 Get Assertion command. Needs json file with parameters. Sample file " _YELLOW_("`fido2.json`") ". File can be placed in proxmark directory or in `proxmark/fido` directory.", - "Usage:\n\thf fido assert -> execute command default parameters file `fido2.json`\n" + "Execute a FIDO2 Get Assertion command. Needs json file with parameters. Sample file " _YELLOW_("`fido2.json`") " in `resources/`.", + "Usage:\n\thf fido assert -> execute command with default parameters file `fido2.json`\n" "\thf fido assert test.json -l -> execute command with parameters file `text.json` and add to request CredentialId"); void *argtable[] = { @@ -775,7 +775,7 @@ static int CmdHFFido2GetAssertion(const char *cmd) { arg_lit0("aA", "apdu", "show APDU reqests and responses"), arg_litn("vV", "verbose", 0, 2, "show technical data. vv - show full certificates data"), arg_lit0("cC", "cbor", "show CBOR decoded data"), - arg_lit0("lL", "list", "add CredentialId from json to allowList. Needs if `rk` option is `false` (authenticator don't store credential to its memory)"), + arg_lit0("lL", "list", "add CredentialId from json to allowList. Needs if `rk` option is `false` (authenticator doesn't store credential to its memory)"), arg_str0(NULL, NULL, "", "JSON input / output file name for parameters. Default `fido2.json`"), arg_param_end }; From f7f80a9b9fe8c60182077e445d7bfb1c112b678e Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 2 Sep 2019 22:51:28 +0200 Subject: [PATCH 0572/1854] fido2: fix fido assert loading file --- client/cmdhffido.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdhffido.c b/client/cmdhffido.c index a7ce63c98..fbc91e814 100644 --- a/client/cmdhffido.c +++ b/client/cmdhffido.c @@ -801,7 +801,7 @@ static int CmdHFFido2GetAssertion(const char *cmd) { SetAPDULogging(APDULogging); - int res = GetExistsFileNameJson("fido", "fido2", fname); + int res = GetExistsFileNameJson("fido", cjsonname, fname); if (res) { PrintAndLogEx(ERR, "ERROR: Can't found the json file."); return res; From bccb9069f9d4e84e30d912b6f562a34892545b4b Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 3 Sep 2019 00:18:29 +0200 Subject: [PATCH 0573/1854] prepare libamiibo.a inclusion --- client/Makefile | 13 ++++++++++--- client/amiitool/Makefile | 19 +++++++++++++++++++ client/amiitool/amiibo.c | 1 + client/amiitool/amiibo.h | 1 - client/amiitool/amiitool.c | 15 ++++++++++----- client/amiitool/drbg.c | 2 +- client/amiitool/keygen.c | 2 +- 7 files changed, 42 insertions(+), 11 deletions(-) create mode 100644 client/amiitool/Makefile diff --git a/client/Makefile b/client/Makefile index 4c5d53c9c..56de12f97 100644 --- a/client/Makefile +++ b/client/Makefile @@ -40,6 +40,8 @@ CBORLIBPATH = ./tinycbor CBORLIB = $(CBORLIBPATH)/tinycbor.a REVENGPATH = ./reveng REVENGLIB = $(REVENGPATH)/libreveng.a +AMIIBOLIBPATH = ./amiitool +AMIIBOLIB = $(AMIIBOLIBPATH)/libamiibo.a # common libraries MBEDTLSLIBPATH = ../common/mbedtls @@ -47,7 +49,7 @@ MBEDTLSLIB = $(OBJDIR)/libmbedtls.a ZLIBPATH = ../common/zlib ZLIB = $(OBJDIR)/libz.a -LIBS = -I$(LUALIBPATH) -I$(MBEDTLSLIBPATH) -I$(JANSSONLIBPATH) -I$(CBORLIBPATH) -I$(ZLIBPATH) -I$(REVENGPATH) +LIBS = -I$(LUALIBPATH) -I$(MBEDTLSLIBPATH) -I$(JANSSONLIBPATH) -I$(CBORLIBPATH) -I$(ZLIBPATH) -I$(REVENGPATH) -I$(AMIIBOLIBPATH) INCLUDES_CLIENT = -I. -I../include -I../common -Iuart $(LIBS) CFLAGS ?= -Wall -Werror -g -O3 # We cannot just use CFLAGS+=... because it has impact on sub-makes if CFLAGS is defined in env: @@ -287,8 +289,8 @@ all: $(BINS) all-static: LDLIBS:=-static $(LDLIBS) all-static: $(BINS) -proxmark3: LDLIBS+=$(LUALIB) $(JANSSONLIB) $(MBEDTLSLIB) $(CBORLIB) $(ZLIB) $(REVENGLIB) $(QTLDLIBS) -proxmark3: $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(LUALIB) $(JANSSONLIB) $(CBORLIB) $(REVENGLIB) $(MBEDTLSLIB) $(ZLIB) lualibs/pm3_cmd.lua lualibs/mfc_default_keys.lua +proxmark3: LDLIBS+=$(LUALIB) $(JANSSONLIB) $(MBEDTLSLIB) $(CBORLIB) $(ZLIB) $(REVENGLIB) $(AMIIBOLIB) $(QTLDLIBS) +proxmark3: $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(LUALIB) $(JANSSONLIB) $(CBORLIB) $(REVENGLIB) $(MBEDTLSLIB) $(ZLIB) $(AMIIBOLIB) lualibs/pm3_cmd.lua lualibs/mfc_default_keys.lua $(info [=] LD $@) $(Q)$(LD) $(LDFLAGS) $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(LDLIBS) -o $@ @@ -321,6 +323,7 @@ clean: $(Q)$(MAKE) --no-print-directory -C $(JANSSONLIBPATH) clean $(Q)$(MAKE) --no-print-directory -C $(CBORLIBPATH) clean $(Q)$(MAKE) --no-print-directory -C $(REVENGPATH) clean + $(Q)$(MAKE) --no-print-directory -C $(AMIIBOLIBPATH) clean install: all $(info [@] Installing client to $(DESTDIR)$(PREFIX)...) @@ -365,6 +368,10 @@ $(REVENGLIB): $(info [*] MAKE reveng) $(Q)$(MAKE) --no-print-directory -C $(REVENGPATH) all +$(AMIIBOLIB): + $(info [*] MAKE amiibo) + $(Q)$(MAKE) --no-print-directory -C $(AMIIBOLIBPATH) all + # common libraries: $(MBEDTLSLIB): $(info [*] MAKE mbedtls) diff --git a/client/amiitool/Makefile b/client/amiitool/Makefile new file mode 100644 index 000000000..c473f58ee --- /dev/null +++ b/client/amiitool/Makefile @@ -0,0 +1,19 @@ +MYSRCPATHS = +MYINCLUDES = -I. -I.. -I../jansson -I../../common/ -I../../include/ +MYCFLAGS = -std=c99 -D_ISOC99_SOURCE +MYDEFS = +MYSRCS = \ + amiibo.c \ + drbg.c \ + keygen.c + +LIB_A = libamiibo.a + +include ../../Makefile.host + +# just for testing amiitool before complete migration into a lib: + +amiitool: + gcc $(CFLAGS) \ + amiitool.c $(MYSRCS) ../../common/commonutil.c ../ui.c -lreadline -lm ../../common/mbedtls/libmbedtls.a \ + -o amiitool diff --git a/client/amiitool/amiibo.c b/client/amiitool/amiibo.c index a8596e30a..d8fe837b1 100644 --- a/client/amiitool/amiibo.c +++ b/client/amiitool/amiibo.c @@ -8,6 +8,7 @@ #include "amiibo.h" #include "mbedtls/md.h" #include "mbedtls/aes.h" +#include "commonutil.h" #define HMAC_POS_DATA 0x008 #define HMAC_POS_TAG 0x1B4 diff --git a/client/amiitool/amiibo.h b/client/amiitool/amiibo.h index 7b56a2c0a..47d544875 100644 --- a/client/amiitool/amiibo.h +++ b/client/amiitool/amiibo.h @@ -13,7 +13,6 @@ #include #include #include "keygen.h" -#include "util.h" #define NFC3D_AMIIBO_SIZE 520 diff --git a/client/amiitool/amiitool.c b/client/amiitool/amiitool.c index 78c8f4d1e..ca34a5c6a 100644 --- a/client/amiitool/amiitool.c +++ b/client/amiitool/amiitool.c @@ -5,10 +5,11 @@ * SPDX-License-Identifier: MIT */ -#include #include #include -#include "../loclass/fileutils.h" +#include "fileutils.h" +#include "amiibo.h" +#include "getopt.h" #define NTAG215_SIZE 540 @@ -16,7 +17,7 @@ static char *self; void amiitool_usage() { fprintf(stderr, - "amiitool build %i (commit %s-%08x)\n" + /*"amiitool build %i (commit %s-%08x)\n"*/ "by Marcos Del Sol Vives \n" "\n" "Usage: %s (-e|-d|-c) -k keyfile [-i input] [-s input2] [-o output]\n" @@ -28,7 +29,7 @@ void amiitool_usage() { " -s input save file, save from this file will replace input file ones.\n" " -o output file. If not specified, stdout will be used.\n" " -l decrypt files with invalid signatures.\n", - , self + self ); } @@ -62,6 +63,9 @@ int main(int argc, char **argv) { case 'i': infile = optarg; break; + case 'k': + keyfile = optarg; + break; case 's': savefile = optarg; break; @@ -83,7 +87,8 @@ int main(int argc, char **argv) { } nfc3d_amiibo_keys amiiboKeys; - + if (! LoadAmiikey(amiiboKeys, keyfile)) + return 5; uint8_t original[NTAG215_SIZE]; uint8_t modified[NFC3D_AMIIBO_SIZE]; diff --git a/client/amiitool/drbg.c b/client/amiitool/drbg.c index 623a29776..c1297920f 100644 --- a/client/amiitool/drbg.c +++ b/client/amiitool/drbg.c @@ -8,7 +8,7 @@ #include "drbg.h" #include #include -#include +#include "mbedtls/md.h" void nfc3d_drbg_init(nfc3d_drbg_ctx *ctx, const uint8_t *hmacKey, size_t hmacKeySize, const uint8_t *seed, size_t seedSize) { assert(ctx != NULL); diff --git a/client/amiitool/keygen.c b/client/amiitool/keygen.c index 4b74a0232..f148c0dc8 100644 --- a/client/amiitool/keygen.c +++ b/client/amiitool/keygen.c @@ -19,7 +19,7 @@ void nfc3d_keygen_prepare_seed(const nfc3d_keygen_masterkeys *baseKeys, const ui uint8_t *start = output; // 1: Copy whole type string - output = memccpy(output, baseKeys->typeString, '\0', sizeof(baseKeys->typeString)); + output = (uint8_t *)strcpy((char *)output, baseKeys->typeString); // 2: Append (16 - magicBytesSize) from the input seed size_t leadingSeedBytes = 16 - baseKeys->magicBytesSize; From 6b12cdc6d82453e2dc02c64215164f6ef2f0648e Mon Sep 17 00:00:00 2001 From: Iceman Date: Tue, 3 Sep 2019 13:11:49 +0200 Subject: [PATCH 0574/1854] Update README.md --- README.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 26a1ae126..9d8492f56 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,7 @@ It is dedicated to bringing the most out of the new features for Proxmark3 RDV4. |[Donations](#Donations)||| ## Support on other Proxmark3 platforms + In order to build this repo for other Proxmark3 platforms we urge you to read [Advanced compilation parameters](/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md) ## What has changed? @@ -43,12 +44,13 @@ On the hardware side: On the software side: quite a lot, see the [Changelog file](CHANGELOG.md). ## Development -This fork now compiles just fine on + +This repo now compiles just fine on - Proxspace v3.2 - Windows/mingw environment with Qt5.6.1 & GCC 4.8 - Ubuntu 1404, 1510, 1604, 1804, 1904 - Mac OS X / Homebrew - - ParrotOS, Gentoo, Pentoo, Kali, Nethunter, Archlinux + - ParrotOS, Gentoo, Pentoo, Kali, Nethunter, Archlinux, Fedora - WSL, WSL2 (Windows subsystem linux) on Windows 10 - Docker container @@ -65,9 +67,11 @@ If you intend to contribute to the code, please read the [coding style notes](HA - Internal notes on [EMV](/doc/emv_notes.md) ## Cheat sheet + Thanks to Alex Dibs, you can enjoy a [command cheat sheet](/doc/cheatsheet.md) ## Maintainers ( package, distro ) + To all distro, package maintainers, we tried to make your life easier. `make install` is now available and if you want to know more. - [Maintainers](/doc/md/Development/Maintainers.md) @@ -76,6 +80,7 @@ To all distro, package maintainers, we tried to make your life easier. `make ins The separation from official Proxmark3 repo gives us a lot of freedom to create a firmware/client that suits the RDV40 features. We don't want to mess up the official Proxmark3 repo with RDV40 specific code. ## Proxmark3 GUI + The official PM3-GUI from Gaucho will not work. The new universal GUI will work. [Proxmark3 Universal GUI](https://github.com/burma69/PM3UniversalGUI) Almost, change needed in order to show helptext when client isn't connected to a device. @@ -91,6 +96,7 @@ It's needed to have a good USB cable to connect Proxmark3 to USB. If you have st - updated Feb 2019 [@5w0rdfish](https://mobile.twitter.com/5w0rdFish) # Donations + Nothing says thank you as much as a donation. So if you feel the love, do feel free to become a iceman patron. For some tiers it comes with rewards. https://www.patreon.com/iceman1001 From 15d8e246d8404b21cad4f3636eededbbbb802af4 Mon Sep 17 00:00:00 2001 From: CristarIngram <49596976+CristarIngram@users.noreply.github.com> Date: Tue, 3 Sep 2019 16:10:22 +0200 Subject: [PATCH 0575/1854] more mfc keys --- client/dictionaries/mfc_default_keys.dic | 3 +++ 1 file changed, 3 insertions(+) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index 924f75488..280604b3a 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -106,6 +106,9 @@ ba5b895da162 # VIGIK1 B d01afeeb890a # 16 B 4b791bea7bcc # 17 B # +43454952534E # ARD (fr) key A +4A2B29111213 # ARD (fr) key B +# 4143414F5250 a9b43414F585 # Tehran Railway 1FB235AC1388 # Tehran Railway From 21f34fabc255916110f8c56496100f3ab8789711 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 3 Sep 2019 20:30:27 +0200 Subject: [PATCH 0576/1854] update troubleshooting notes --- doc/md/Installation_Instructions/Troubleshooting.md | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/doc/md/Installation_Instructions/Troubleshooting.md b/doc/md/Installation_Instructions/Troubleshooting.md index 19f1dbee7..041ce0f41 100644 --- a/doc/md/Installation_Instructions/Troubleshooting.md +++ b/doc/md/Installation_Instructions/Troubleshooting.md @@ -76,7 +76,7 @@ At this point, only reflashing via JTAG can revive your Proxmark3. See [details here](/doc/jtag_notes.md). -## Slow to boot +## Slow to boot or difficulties to enumerate the device over USB You're using another Proxmark3 than a RDV4? The RDV4 firmware can run on other Proxmark3 as such but the booting procedure is a bit slower because of the absence of SIM and external flash. @@ -116,13 +116,8 @@ pm3 --> sc upgrade f tools/simmodule/sim011.bin pm3 --> sc upgrade f ../tools/simmodule/sim011.bin ``` -``` -pm3 --> mem load f default_keys m -<> -pm3 --> mem load f client/default_keys m -``` - etc. -This also affects where your history and logfile will be read from and written to. +## pixmap / pixbuf warnings +If you get warnings related to pixmap or pixbuf such as *Pixbuf theme: Cannot load pixmap file* or *Invalid borders specified for theme pixmap*, it's a problem of your Theme, try another one and the problem should vanish. See e.g. [#354](https://github.com/RfidResearchGroup/proxmark3/issues/354) (Yaru theme on Ubuntu) and [#386](https://github.com/RfidResearchGroup/proxmark3/issues/386) (Kali-X theme on Kali). From 5ec14e0c94f8d132f72686c69120718d4dcedfbc Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 3 Sep 2019 20:39:47 +0200 Subject: [PATCH 0577/1854] Troubleshooting ToC Done with https://github.com/ekalinin/github-markdown-toc --- .../Installation_Instructions/Troubleshooting.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/doc/md/Installation_Instructions/Troubleshooting.md b/doc/md/Installation_Instructions/Troubleshooting.md index 041ce0f41..b8153ba8b 100644 --- a/doc/md/Installation_Instructions/Troubleshooting.md +++ b/doc/md/Installation_Instructions/Troubleshooting.md @@ -4,6 +4,20 @@ Always use the latest repository commits from *master* branch. There are always many fixes done almost daily. +## Table of Contents + + * [./proxmark3.sh or ./proxmark3-flash-*.sh doesn't see my Proxmark](#proxmark3sh-or-proxmark3-flash-sh-doesnt-see-my-proxmark) + * [My Proxmark3 seems bricked](#my-proxmark3-seems-bricked) + * [Maybe just a false alarm?](#maybe-just-a-false-alarm) + * [Find out why it would be bricked](#find-out-why-it-would-be-bricked) + * [Determine if the bootloader was damaged or only the main OS image](#determine-if-the-bootloader-was-damaged-or-only-the-main-os-image) + * [Ok, my bootloader is definitively dead, now what?](#ok-my-bootloader-is-definitively-dead-now-what) + * [Slow to boot or difficulties to enumerate the device over USB](#slow-to-boot-or-difficulties-to-enumerate-the-device-over-usb) + * [Troubles with SIM card reader](#troubles-with-sim-card-reader) + * [Troubles with t5577 commands or MFC/iClass/T55x7 dictionaries](#troubles-with-t5577-commands-or-mfciclasst55x7-dictionaries) + * [File not found](#file-not-found) + * [pixmap / pixbuf warnings](#pixmap--pixbuf-warnings) + ## `./proxmark3.sh` or `./proxmark3-flash-*.sh` doesn't see my Proxmark Try using directly the client or flasher: From 62f598c4139bb3f0581692f0f84ace4d5c8efa2c Mon Sep 17 00:00:00 2001 From: Iceman Date: Tue, 3 Sep 2019 20:59:23 +0200 Subject: [PATCH 0578/1854] Update Troubleshooting.md --- .../Installation_Instructions/Troubleshooting.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/doc/md/Installation_Instructions/Troubleshooting.md b/doc/md/Installation_Instructions/Troubleshooting.md index b8153ba8b..1eefe1c6e 100644 --- a/doc/md/Installation_Instructions/Troubleshooting.md +++ b/doc/md/Installation_Instructions/Troubleshooting.md @@ -6,7 +6,7 @@ Always use the latest repository commits from *master* branch. There are always ## Table of Contents - * [./proxmark3.sh or ./proxmark3-flash-*.sh doesn't see my Proxmark](#proxmark3sh-or-proxmark3-flash-sh-doesnt-see-my-proxmark) + * [./pm3.sh or ./pma3-flash-*.sh doesn't see my Proxmark](#pm3sh-or-pmk3-flash-sh-doesnt-see-my-proxmark) * [My Proxmark3 seems bricked](#my-proxmark3-seems-bricked) * [Maybe just a false alarm?](#maybe-just-a-false-alarm) * [Find out why it would be bricked](#find-out-why-it-would-be-bricked) @@ -18,7 +18,7 @@ Always use the latest repository commits from *master* branch. There are always * [File not found](#file-not-found) * [pixmap / pixbuf warnings](#pixmap--pixbuf-warnings) -## `./proxmark3.sh` or `./proxmark3-flash-*.sh` doesn't see my Proxmark +## `./pm3.sh` or `./pm3-flash-*.sh` doesn't see my Proxmark Try using directly the client or flasher: @@ -44,8 +44,8 @@ Note that with the Bluetooth adapter, you *have to* use directly the client, and The flasher refused to flash your Proxmark3? Are there any messages in *red*? The most common reason is that the Proxmark3 RDV4 firmware recently got a new bootloader able to handle larger firmwares and... the image grew over 256k almost at the same time. So your old bootloader can't flash such new images. But it's easy, you just need to flash *first* the bootloader *only*, then the image. ``` -./flash-bootrom.sh -./flash-fullimage.sh +./pm3-flash-bootrom.sh +./pm3-flash-fullimage.sh ``` or ``` @@ -67,7 +67,7 @@ On new bootloaders, you can release the button. If the pattern disappears, you'r Once in bootloader mode, flash the main image. ``` -./flash-fullimage.sh +./pm3-flash-fullimage.sh ``` or ``` @@ -77,7 +77,7 @@ client/proxmark3-flasher armsrc/obj/fullimage.elf You should be back on tracks now. In case the flasher complains about bootloader version, you can follow the button procedure and flash first your bootloader. ``` -./flash-bootrom.sh +./pm3-flash-bootrom.sh ``` or ``` @@ -112,7 +112,7 @@ Instructions evolve over time so check if you're still up to date! Depending how you launch the client, your working directory might be the root of the repository: ``` -./proxmark3.sh ... +./pm3.sh ... client/proxmark3 ... ``` From d4cd32b723b4339d8d524d86bcb5ebf6b63786e0 Mon Sep 17 00:00:00 2001 From: Iceman Date: Tue, 3 Sep 2019 21:00:30 +0200 Subject: [PATCH 0579/1854] Update Troubleshooting.md --- doc/md/Installation_Instructions/Troubleshooting.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/md/Installation_Instructions/Troubleshooting.md b/doc/md/Installation_Instructions/Troubleshooting.md index 1eefe1c6e..ae56ce012 100644 --- a/doc/md/Installation_Instructions/Troubleshooting.md +++ b/doc/md/Installation_Instructions/Troubleshooting.md @@ -6,7 +6,7 @@ Always use the latest repository commits from *master* branch. There are always ## Table of Contents - * [./pm3.sh or ./pma3-flash-*.sh doesn't see my Proxmark](#pm3sh-or-pmk3-flash-sh-doesnt-see-my-proxmark) + * [./pm3.sh or ./pm3-flash-*.sh doesn't see my Proxmark](#pm3sh-or-pm3-flash-sh-doesnt-see-my-proxmark) * [My Proxmark3 seems bricked](#my-proxmark3-seems-bricked) * [Maybe just a false alarm?](#maybe-just-a-false-alarm) * [Find out why it would be bricked](#find-out-why-it-would-be-bricked) From b577ca15e9c899f6537fb5eabb94c22ac9026996 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 3 Sep 2019 22:54:42 +0200 Subject: [PATCH 0580/1854] update instructions --- ...OS-X-Homebrew-Installation-Instructions.md | 34 ++++++++++---- .../ModemManager-Must-Be-Discarded.md | 2 +- .../Troubleshooting.md | 47 ++++++++++++++----- .../Windows-Installation-Instructions.md | 32 +++++++++---- .../0_Compilation-Instructions.md | 33 +++++++++++-- .../2_Configuration-and-Verification.md | 4 +- 6 files changed, 116 insertions(+), 36 deletions(-) diff --git a/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md b/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md index 4e225b318..ba6547cb2 100644 --- a/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md @@ -31,19 +31,31 @@ brew upgrade --fetch-HEAD proxmark3 With your Proxmark3 unplugged from your machine, press and hold the button on your Proxmark3 as you plug it into a USB port. You can release the button, two of the four LEDs should stay on. You're un bootloader mode, ready for the next step. In case the two LEDs don't stay on when you're releasing the button, you've an old bootloader, start over and keep the button pressed during the whole flashing procedure. +In principle, the helper script `pm3-flash-all` should auto-detect your port, so you can just try: + ```sh -sudo proxmark3-flasher /dev/tty.usbmodemiceman1 -b /usr/local/Cellar/proxmark3/HEAD-/share/firmware/bootrom.elf /usr/local/Cellar/proxmark3/HEAD-/share/firmware/fullimage.elf +pm3-flash-all ``` -> Replace \ with the HEAD-XXXX ID displayed by brew. -> Depending on the firmware version your Proxmark3 can also appear as `/dev/tty.usbmodem881` +If port detection failed, you'll have to call the flasher manually and specify the correct port: +```sh +proxmark3-flasher /dev/tty.usbmodemiceman1 -b /usr/local/share/proxmark3/firmware/bootrom.elf /usr/local/share/proxmark3/firmware/fullimage.elf +``` + +> Depending on the firmware version your Proxmark3 can also appear as `/dev/tty.usbmodem881`. ## Run the client ```sh -sudo proxmark3 /dev/tty.usbmodemiceman1 +pm3 +``` + +or, if the port doesn't get properly detected: + +```sh +proxmark3 /dev/tty.usbmodemiceman1 ``` ## Next steps @@ -78,14 +90,20 @@ To use the compiled client and flasher, the only difference is that the Proxmark To flash: With your Proxmark3 unplugged from your machine, press and hold the button on your Proxmark3 as you plug it into a USB port. You can release the button, two of the four LEDs should stay on. You're un bootloader mode, ready for the next step. In case the two LEDs don't stay on when you're releasing the button, you've an old bootloader, start over and keep the button pressed during the whole flashing procedure. -In principle, the helper script `flash-all.sh` should auto-detect your port, so you can just try: +In principle, the helper script `pm3-flash-all` should auto-detect your port, so you can just try: ```sh -./flash-all.sh +pm3-flash-all ``` If port detection failed, you'll have to call the flasher manually and specify the correct port: +```sh +proxmark3-flasher /dev/tty.usbmodemiceman1 -b /usr/local/share/proxmark3/firmware/bootrom.elf /usr/local/share/proxmark3/firmware/fullimage.elf +``` + +or from the local repo + ```sh client/proxmark3-flasher /dev/tty.usbmodemiceman1 -b bootrom/obj/bootrom.elf armsrc/obj/fullimage.elf ``` @@ -93,12 +111,12 @@ client/proxmark3-flasher /dev/tty.usbmodemiceman1 -b bootrom/obj/bootrom.elf arm Similarly, to run the client, you may try: ```sh -./proxmark3.sh +pm3 ``` Or, by specifying the port manually: ```sh -client/proxmark3 /dev/tty.usbmodemiceman1 +proxmark3 /dev/tty.usbmodemiceman1 ``` diff --git a/doc/md/Installation_Instructions/ModemManager-Must-Be-Discarded.md b/doc/md/Installation_Instructions/ModemManager-Must-Be-Discarded.md index 76a4626e3..bbf6f6ca6 100644 --- a/doc/md/Installation_Instructions/ModemManager-Must-Be-Discarded.md +++ b/doc/md/Installation_Instructions/ModemManager-Must-Be-Discarded.md @@ -121,7 +121,7 @@ In short: * unplug device * press button and keep it pressed (IMPORTANT) * plug in device -* run flash command `sudo client/proxmark3-flasher /dev/ttyACM0 armsrc/obj/fullimage.elf` +* run flash command `sudo proxmark3-flasher /dev/ttyACM0 /usr/local/share/proxmark3/firmware/fullimage.elf` * wait until flash is finished * release button * un/plug device diff --git a/doc/md/Installation_Instructions/Troubleshooting.md b/doc/md/Installation_Instructions/Troubleshooting.md index ae56ce012..e9ae8bce9 100644 --- a/doc/md/Installation_Instructions/Troubleshooting.md +++ b/doc/md/Installation_Instructions/Troubleshooting.md @@ -6,7 +6,7 @@ Always use the latest repository commits from *master* branch. There are always ## Table of Contents - * [./pm3.sh or ./pm3-flash-*.sh doesn't see my Proxmark](#pm3sh-or-pm3-flash-sh-doesnt-see-my-proxmark) + * [pm3 or pm3-flash-* doesn't see my Proxmark](#pm3-or-pm3-flash-doesnt-see-my-proxmark) * [My Proxmark3 seems bricked](#my-proxmark3-seems-bricked) * [Maybe just a false alarm?](#maybe-just-a-false-alarm) * [Find out why it would be bricked](#find-out-why-it-would-be-bricked) @@ -18,7 +18,7 @@ Always use the latest repository commits from *master* branch. There are always * [File not found](#file-not-found) * [pixmap / pixbuf warnings](#pixmap--pixbuf-warnings) -## `./pm3.sh` or `./pm3-flash-*.sh` doesn't see my Proxmark +## `pm3` or `pm3-flash-*` doesn't see my Proxmark Try using directly the client or flasher: @@ -44,13 +44,13 @@ Note that with the Bluetooth adapter, you *have to* use directly the client, and The flasher refused to flash your Proxmark3? Are there any messages in *red*? The most common reason is that the Proxmark3 RDV4 firmware recently got a new bootloader able to handle larger firmwares and... the image grew over 256k almost at the same time. So your old bootloader can't flash such new images. But it's easy, you just need to flash *first* the bootloader *only*, then the image. ``` -./pm3-flash-bootrom.sh -./pm3-flash-fullimage.sh +pm3-flash-bootrom +pm3-flash-fullimage ``` or ``` -client/proxmark3-flasher -b bootrom/obj/bootrom.elf -client/proxmark3-flasher armsrc/obj/fullimage.elf +proxmark3-flasher -b bootrom/obj/bootrom.elf +proxmark3-flasher armsrc/obj/fullimage.elf ``` ### Find out why it would be bricked @@ -67,21 +67,21 @@ On new bootloaders, you can release the button. If the pattern disappears, you'r Once in bootloader mode, flash the main image. ``` -./pm3-flash-fullimage.sh +pm3-flash-fullimage ``` or ``` -client/proxmark3-flasher armsrc/obj/fullimage.elf +proxmark3-flasher armsrc/obj/fullimage.elf ``` You should be back on tracks now. In case the flasher complains about bootloader version, you can follow the button procedure and flash first your bootloader. ``` -./pm3-flash-bootrom.sh +pm3-flash-bootrom ``` or ``` -client/proxmark3-flasher -b bootrom/obj/bootrom.elf +proxmark3-flasher -b bootrom/obj/bootrom.elf ``` ### Ok, my bootloader is definitively dead, now what? @@ -109,10 +109,29 @@ Instructions evolve over time so check if you're still up to date! ## File not found -Depending how you launch the client, your working directory might be the root of the repository: +If Proxmark3 has been installed with `make install` or packaged for your distro, the binaries should be in your path and you can call them directly: ``` -./pm3.sh ... +pm3 +proxmark3 +``` + +and you must adapt accordingly the file path of some commands, e.g. + +``` +proxmark3-flasher /usr/local/share/proxmark3/firmware/fullimage.elf +<> +proxmark3-flasher /usr/share/proxmark3/firmware/fullimage.elf + +pm3 --> sc upgrade f /usr/local/share/proxmark3/firmware/sim011.bin +<> +pm3 --> sc upgrade f /usr/share/proxmark3/firmware/sim011.bin +``` + +If you didn't install the PRoxmark but you're working from the sources directory and depending how you launch the client, your working directory might be the root of the repository: + +``` +./pm3 ... client/proxmark3 ... ``` @@ -125,6 +144,10 @@ cd client; ./proxmark3 ... Therefore client commands referring to files of the repo must be adapted, e.g. ``` +client/proxmark3-flasher armsrc/obj/fullimage.elf +<> +./proxmark3-flasher ../armsrc/obj/fullimage.elf + pm3 --> sc upgrade f tools/simmodule/sim011.bin <> pm3 --> sc upgrade f ../tools/simmodule/sim011.bin diff --git a/doc/md/Installation_Instructions/Windows-Installation-Instructions.md b/doc/md/Installation_Instructions/Windows-Installation-Instructions.md index f9eb9e988..6a821a992 100644 --- a/doc/md/Installation_Instructions/Windows-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Windows-Installation-Instructions.md @@ -54,16 +54,22 @@ pacman -S mingw-w64-x86_64-astyle Now you're ready to follow the [compilation instructions](/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md). -To use the compiled client and flasher, the only differences are that executables end with `.exe` (e.g. `client/proxmark3-flasher.exe`) and that the Proxmark3 port is one of your `comX` ports where "X" is the com port number assigned to proxmark3 under Windows. +To use the compiled client and flasher, the only differences are that executables end with `.exe` (e.g. `proxmark3-flasher.exe`) and that the Proxmark3 port is one of your `comX` ports where "X" is the com port number assigned to proxmark3 under Windows. -To flash: In principle, the helper script `flash-all.sh` should auto-detect your COM port, so you can just try: +To flash: In principle, the helper script `pm3-flash-all` should auto-detect your COM port, so you can just try: ```sh -./flash-all.sh +pm3-flash-all ``` If COM port detection failed, you'll have to call the flasher manually and specify the correct port: +```sh +proxmark3-flasher.exe comX -b /usr/local/share/proxmark3/firmware/bootrom.elf /usr/local/share/proxmark3/firmware/fullimage.elf +``` + +or from the local repo + ```sh client/proxmark3-flasher.exe comX -b bootrom/obj/bootrom.elf armsrc/obj/fullimage.elf ``` @@ -71,13 +77,13 @@ client/proxmark3-flasher.exe comX -b bootrom/obj/bootrom.elf armsrc/obj/fullimag Similarly, to run the client, you may try: ```sh -./proxmark3.sh +pm3 ``` Or, by specifying the COM port manually: ```sh -client/proxmark3.exe comX +proxmark3.exe comX ``` # Installing on Windows with WSL @@ -141,28 +147,34 @@ and add it to your Bash profile for the next times: echo "export DISPLAY=:0" >> ~/.bashrc ``` -To flash: In principle, the helper script `flash-all.sh` should auto-detect your COMX==/dev/ttySX port, so you can just try: +To flash: In principle, the helper script `pm3-flash-all` should auto-detect your COMX==/dev/ttySX port, so you can just try: ```sh -./flash-all.sh +pm3-flash-all ``` If port detection failed, you'll have to call the flasher manually and specify the correct port: ```sh -client/proxmark3-flasher /dev/ttySX -b bootrom/obj/bootrom.elf armsrc/obj/fullimage.elf +proxmark3-flasher.exe /dev/ttySX -b /usr/local/share/proxmark3/firmware/bootrom.elf /usr/local/share/proxmark3/firmware/fullimage.elf +``` + +or from the local repo + +```sh +client/proxmark3-flasher.exe /dev/ttySX -b bootrom/obj/bootrom.elf armsrc/obj/fullimage.elf ``` Similarly, to run the client, you may try: ```sh -./proxmark3.sh +pm3 ``` Or, by specifying the COM port manually: ```sh -client/proxmark3 /dev/ttySX +proxmark3 /dev/ttySX ``` Note that it may take a quite long time for a freshly plugged Proxmark3 to be visible on a WSL /dev/ttySX port. diff --git a/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md b/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md index 1e6b24b88..7faa6a658 100644 --- a/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md +++ b/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md @@ -24,27 +24,52 @@ git pull make clean && make all ``` +## Install + +This is an optional step. If you do + +```sh +sudo make install +``` + +Then the required files will be installed on your system, by default in `/usr/local/bin` and `/usr/local/share/proxmark3`. +Maintainers can read [this doc](../Development/Maintainers.md) to learn how to modify installation paths via `DESTDIR` and `PREFIX` Makefile variables. + +The commands given in the documentation assume you did the installation step. If you didn't, you've to adjust the commands paths and files paths accordingly, +e.g. calling `./pm3` or `client/proxmark3` instead of just `pm3` or `proxmark3`. + ## Flash the BOOTROM & FULLIMAGE -In most cases, you can run the script `flash-all.sh` which try to auto-detect the port to use, on several OS. +In most cases, you can run the script `pm3-flash-all` which try to auto-detect the port to use, on several OS. For the other cases, specify the port by yourself. For example, for a Proxmark3 connected via USB under Linux: +```sh +proxmark3-flasher /dev/ttyACM0 -b /usr/local/share/proxmark3/firmware/bootrom.elf /usr/local/share/proxmark3/firmware/fullimage.elf +``` + +or from the local repo + ```sh client/proxmark3-flasher /dev/ttyACM0 -b bootrom/obj/bootrom.elf armsrc/obj/fullimage.elf ``` ## Run the client -In most cases, you can run the script `proxmark3.sh` which try to auto-detect the port to use, on several OS. +In most cases, you can run the script `pm3` which try to auto-detect the port to use, on several OS. For the other cases, specify the port by yourself. For example, for a Proxmark3 connected via USB under Linux: Here, for example, for a Proxmark3 connected via USB under Linux: ```sh -cd client -./proxmark3 /dev/ttyACM0 +proxmark3 /dev/ttyACM0 +``` + +or from the local repo + +```sh +client/proxmark3 /dev/ttyACM0 ``` ## Next steps diff --git a/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md b/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md index 8ec176edb..8b88115c6 100644 --- a/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md +++ b/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md @@ -46,7 +46,9 @@ Don't not turn off your device during the execution of this command!! Even its a quite fast command you should be warned. You may brick it if you interrupt it. ``` -pm3 --> sc upgrade f ../tools/simmodule/sim011.bin +pm3 --> sc upgrade f /usr/local/share/proxmark3/firmware/sim011.bin +# or if from local repo +pm3 --> sc upgrade f tools/simmodule/sim011.bin ``` You get the following output if the execution was successful: From c2b6fb16a220d391f159db8bac325fd4290226e0 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 4 Sep 2019 09:00:03 +0200 Subject: [PATCH 0581/1854] leftover sudo --- .../Installation_Instructions/ModemManager-Must-Be-Discarded.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/md/Installation_Instructions/ModemManager-Must-Be-Discarded.md b/doc/md/Installation_Instructions/ModemManager-Must-Be-Discarded.md index bbf6f6ca6..c2c01f44f 100644 --- a/doc/md/Installation_Instructions/ModemManager-Must-Be-Discarded.md +++ b/doc/md/Installation_Instructions/ModemManager-Must-Be-Discarded.md @@ -121,7 +121,7 @@ In short: * unplug device * press button and keep it pressed (IMPORTANT) * plug in device -* run flash command `sudo proxmark3-flasher /dev/ttyACM0 /usr/local/share/proxmark3/firmware/fullimage.elf` +* run flash command `proxmark3-flasher /dev/ttyACM0 /usr/local/share/proxmark3/firmware/fullimage.elf` * wait until flash is finished * release button * un/plug device From 0e3d1d48072d4d12c17cadc865669c9864b35b9e Mon Sep 17 00:00:00 2001 From: Iceman Date: Wed, 4 Sep 2019 10:49:16 +0200 Subject: [PATCH 0582/1854] Create path_notes.md Inital comment of notes about path. --- doc/path_notes.md | 80 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 doc/path_notes.md diff --git a/doc/path_notes.md b/doc/path_notes.md new file mode 100644 index 000000000..3fc4d9629 --- /dev/null +++ b/doc/path_notes.md @@ -0,0 +1,80 @@ +# Notes on paths. + + +With the recent (2019-09-01) changes and creation of _make install_ command it is still easy to get lost. + +We are adapting the client to use searchFile when creating or calling a Proxmark3 command with a filename. +Here is where it tries to find the file and in which precedense order it takes. + + + + +## binary paths +This is where the executable / shellscripts will be copied to. + +``` +/usr/share/proxmark3 +/usr/local/share/proxmark3 +``` + +## User given paths +``` +~/.proxmark3/ +./ +``` + +## Proxmark3 client essential files +``` +/resources +/dictionaries +/lualibs +/luascripts +/cmdscripts +``` + +## seaching for a file +First instance where a file is found will be used in the client. + +1. share (install paths) +2. $HOME/.proxmark3 (user home directory +3. ./ (current working directory) + + +## What is where? +/resources +command like + +/dictionaries +Here you find the default dictionaries or your own used for commands like `hf mf chk`, `hf mf fchk`, `lf t55xx chk` +A dictionary file is a text based file with one key per line in hexdecimal form. +The length of the key is decided by the Proxmark3 client for the different commands. All chars afterwards on line is ignored. +if key isn't a hex number, the key is igonored. + +- t55xx, Mifare Ultralight/NTAG - uses 4 hexbytes (11223344) +- Mifare classic uses 6 hexbytes (112233445566) +- iClass uses 8 hexbytes (1122334455667788) + +/luascripts +Here you find existing lua scripts available, or where you put your own custom lua scripts. Look at existing scripts for ideas how to create your own scripts. + +/lualibs +Here is the supporting lua libraries used for lua scripts. basically reused functions in a lua file like converting string to hex etc. + +/cmdscripts +Here you find the proxmark3 client command line scripts. The client can run a text file containing Proxmark3 commands. + +a samplefile could be like this. +``` +$> cat myscript.cmd + +rem running some HF-based info commands +hf 14a info +hf mfu info +rem done +``` + +You call it with: +`$> pm3 -c myscript.cmd` + +The client will execute eachone of the commands in order and then exit. There are also a possibility to remain in the client afterward with the -i parameter +`pm3 -c myscript.cmd -i` From 4623340374b2a211b6d69e81dbef3d2cb9eef1c5 Mon Sep 17 00:00:00 2001 From: Iceman Date: Wed, 4 Sep 2019 11:01:49 +0200 Subject: [PATCH 0583/1854] Update path_notes.md --- doc/path_notes.md | 46 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 40 insertions(+), 6 deletions(-) diff --git a/doc/path_notes.md b/doc/path_notes.md index 3fc4d9629..94500e52a 100644 --- a/doc/path_notes.md +++ b/doc/path_notes.md @@ -7,16 +7,50 @@ We are adapting the client to use searchFile when creating or calling a Proxmark Here is where it tries to find the file and in which precedense order it takes. - - -## binary paths -This is where the executable / shellscripts will be copied to. - +# ``` /usr/share/proxmark3 /usr/local/share/proxmark3 ``` +## binary paths +This is where the Proxmark3 executable / shellscripts will be copied to. +``` +/usr/share/proxmark3/bin +/usr/local/share/proxmark3/bin +``` + +This is where the tools executable / scripts will be copied to +``` +/usr/share/proxmark3/tools +/usr/local/share/proxmark3/tools +``` +executables: mfkey32, mfkey32v2, mfkey64, nonce2key, +scripts: pm3_eml2lower.sh, pm3_eml2upper.sh, pm3_mfdread.py, pm3_mfd2eml.py, pm3_eml2mfd.py, findbits.py, rfidtest.pl, xorcheck.py + +## JTAG stuff +This is where JTAG configurations will be copied to +``` +/usr/share/proxmark3/jtag_openocd +/usr/local/share/proxmark3/tools/jtag_openocd +``` + +# Traces +Proxmark3 client has a lot of sample trace files for many different low frequency tags. They will be copied to +``` +/usr/share/proxmark3/traces +/usr/local/share/proxmark3/traces +``` + + +# Firmware paths +This is where the recovery / firmware files will be copied to. +bootrom.elf, fullimage.elf, proxmark3_recovery.bin (used for JTAG), sim011.bin, sim011.sha512.txt +``` +/usr/share/proxmark3/firmware +/usr/local/share/proxmark3/firmware +``` + ## User given paths ``` ~/.proxmark3/ @@ -42,7 +76,7 @@ First instance where a file is found will be used in the client. ## What is where? /resources -command like +The needed files for commands like hardnested, fido, EMV, iClass. /dictionaries Here you find the default dictionaries or your own used for commands like `hf mf chk`, `hf mf fchk`, `lf t55xx chk` From affecd63bf56b9843efca56d6c1de5b128f840a1 Mon Sep 17 00:00:00 2001 From: Iceman Date: Wed, 4 Sep 2019 11:03:58 +0200 Subject: [PATCH 0584/1854] Update path_notes.md --- doc/path_notes.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/path_notes.md b/doc/path_notes.md index 94500e52a..97c117de1 100644 --- a/doc/path_notes.md +++ b/doc/path_notes.md @@ -73,6 +73,12 @@ First instance where a file is found will be used in the client. 2. $HOME/.proxmark3 (user home directory 3. ./ (current working directory) +## .history / log files +We have now a rolling log file, created new per day. All those logfiles and the .history file is found +``` +~/.proxmar3/history.txt +~/.proxmar3/log_%Y%m%d.txt +``` ## What is where? /resources From 9d620922bb1a5f797876ed5ea51b09dcdb3c67ca Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 4 Sep 2019 19:14:34 +0200 Subject: [PATCH 0585/1854] tweak makefile targets recovery and fullimage --- Makefile | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 43de3969b..a602f0578 100644 --- a/Makefile +++ b/Makefile @@ -92,7 +92,9 @@ armsrc/%: FORCE cleanifplatformchanged fpga_compress/% client/%: FORCE $(info [*] MAKE $@) $(Q)$(MAKE) --no-print-directory -C client $(patsubst client/%,%,$@) DESTDIR=$(MYDESTDIR) -recovery/%: FORCE cleanifplatformchanged bootrom/% armsrc/% +recovery/all: bootrom/all armsrc/all +recovery/install: bootrom/all armsrc/all +recovery/%: FORCE cleanifplatformchanged $(info [*] MAKE $@) $(Q)$(MAKE) --no-print-directory -C recovery $(patsubst recovery/%,%,$@) DESTDIR=$(MYDESTDIR) FORCE: # Dummy target to force remake in the subdirectories, even if files exist (this Makefile doesn't know about the prerequisites) @@ -126,12 +128,18 @@ client: client/all bootrom: bootrom/all +# aliases fullimage = armsrc + fullimage: armsrc/all +fullimage/all: armsrc/all + fullimage/clean: armsrc/clean fullimage/install: armsrc/install +fullimage/uninstall: armsrc/uninstall + recovery: recovery/all mfkey: mfkey/all From 02a2b902cebdf8693c24d8804e7fcac62ee01d2a Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 4 Sep 2019 19:15:13 +0200 Subject: [PATCH 0586/1854] document make install breakdown for maintainers --- doc/md/Development/Maintainers.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/doc/md/Development/Maintainers.md b/doc/md/Development/Maintainers.md index b59987881..225912c2b 100644 --- a/doc/md/Development/Maintainers.md +++ b/doc/md/Development/Maintainers.md @@ -43,3 +43,21 @@ For verbose usage and see the actual commands being executed, add `V=1`. Default compiler is gcc but you can use clang for the non-ARM parts with e.g. `make client CC=clang CXX=clang++ LD=clang++`. +`make install` is actually triggering the following individual targets which can be accessed individually: + +* `make client/install` +* `make bootrom/install` +* `make fullimage/install` (alias of `make armsrc/install`) +* `make recovery/install` +* `make mfkey/install` +* `make nonce2key/install` +* `make fpga_compress/install` (dummy) +* some shared content installation handled by the root Makefile, which can't be installed alone: + * `pm3-*` scripts + * `tools/jtag_openocd`, `traces` + * `doc/md`, `doc/*.md` + * Tools scripts (`pm3_eml2lower.sh` etc) + * SIM firmware (beware currently it's binary blob, may break your distro policies on open source) + * udev rule on Linux + +Same logic for `make all`, `make clean`, `make uninstall` From 2ddbbd255b2ebb534e640a61a5d2f8cd0f0a1a34 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 4 Sep 2019 22:53:54 +0200 Subject: [PATCH 0587/1854] data load: search file with and without extension .pm3 --- client/cmddata.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/client/cmddata.c b/client/cmddata.c index 91bf4b65a..59c80102d 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -1648,8 +1648,10 @@ static int CmdLoad(const char *Cmd) { memcpy(filename, Cmd, len); char *path; - if (searchFile(&path, TRACES_SUBDIR, filename, "", false) != PM3_SUCCESS) { - return PM3_EFILE; + if (searchFile(&path, TRACES_SUBDIR, filename, ".pm3", true) != PM3_SUCCESS) { + if (searchFile(&path, TRACES_SUBDIR, filename, "", false) != PM3_SUCCESS) { + return PM3_EFILE; + } } FILE *f = fopen(path, "r"); From 7594ea49426566a40b30aafb4a786fe9b543058f Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 4 Sep 2019 23:13:51 +0200 Subject: [PATCH 0588/1854] skip comments in cmdscripts --- client/cmdparser.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/client/cmdparser.c b/client/cmdparser.c index 768941e10..9e7b83afa 100644 --- a/client/cmdparser.c +++ b/client/cmdparser.c @@ -176,6 +176,9 @@ int CmdsParse(const command_t Commands[], const char *Cmd) { memset(cmd_name, 0, sizeof(cmd_name)); sscanf(Cmd, "%127s%n", cmd_name, &len); str_lower(cmd_name); + // Comment + if (cmd_name[0] == '#') + return PM3_SUCCESS; int i = 0; while (Commands[i].Name) { if (0 == strcmp(Commands[i].Name, cmd_name)) { From 00ad68215bd7c54a4c050abfde3f7ec6460c4cdb Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 4 Sep 2019 23:28:02 +0200 Subject: [PATCH 0589/1854] add cmdscript example --- client/Makefile | 2 +- client/cmdscripts/rdv4_init_extflash.cmd | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100755 client/cmdscripts/rdv4_init_extflash.cmd diff --git a/client/Makefile b/client/Makefile index 56de12f97..b670965b6 100644 --- a/client/Makefile +++ b/client/Makefile @@ -15,7 +15,7 @@ ROOT_DIR:=$(dir $(realpath $(lastword $(MAKEFILE_LIST)))) include ../Makefile.defs INSTALLBIN = proxmark3 proxmark3-flasher -INSTALLSHARE = lualibs luascripts resources dictionaries +INSTALLSHARE = cmdscripts lualibs luascripts resources dictionaries VPATH = ../common uart vpath %.dic dictionaries diff --git a/client/cmdscripts/rdv4_init_extflash.cmd b/client/cmdscripts/rdv4_init_extflash.cmd new file mode 100755 index 000000000..2cae05294 --- /dev/null +++ b/client/cmdscripts/rdv4_init_extflash.cmd @@ -0,0 +1,6 @@ +#!/usr/bin/env -S pm3 -s + +mem load f mfc_default_keys m +mem load f t55xx_default_pwds t +mem load f iclass_default_keys i +lf t55xx deviceconfig z p From 43055ae6a74afd5b827f9198eafa65640da8e374 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 4 Sep 2019 23:29:03 +0200 Subject: [PATCH 0590/1854] searchFile for cmdscripts --- client/proxmark3.c | 16 +++++++++++----- include/common.h | 1 + 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/client/proxmark3.c b/client/proxmark3.c index cb3444ad7..7e732360f 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -27,6 +27,7 @@ #include "cmdhw.h" #include "whereami.h" #include "comms.h" +#include "fileutils.h" //#include "usart.h" static void showBanner(void) { @@ -95,11 +96,16 @@ main_loop(char *script_cmds_file, char *script_cmd, bool stayInCommandLoop) { if (script_cmds_file) { - sf = fopen(script_cmds_file, "r"); - if (sf) - PrintAndLogEx(SUCCESS, "executing commands from file: %s\n", script_cmds_file); - else - PrintAndLogEx(ERR, "could not open " _YELLOW_("%s") "...", script_cmds_file); + char *path; + int res = searchFile(&path, CMD_SCRIPTS_SUBDIR, script_cmds_file, ".cmd", false); + if (res == PM3_SUCCESS) { + sf = fopen(path, "r"); + if (sf) + PrintAndLogEx(SUCCESS, "executing commands from file: %s\n", path); + else + PrintAndLogEx(ERR, "could not open " _YELLOW_("%s") "...", path); + free(path); + } } char *my_history_path = NULL; diff --git a/include/common.h b/include/common.h index bdda44aae..f13f5f99a 100644 --- a/include/common.h +++ b/include/common.h @@ -24,6 +24,7 @@ #define PM3_USER_DIRECTORY PATHSEP ".proxmark3" PATHSEP // PM3 subdirectories: +#define CMD_SCRIPTS_SUBDIR "cmdscripts" PATHSEP #define DICTIONARIES_SUBDIR "dictionaries" PATHSEP #define LUA_LIBRARIES_SUBDIR "lualibs" PATHSEP #define LUA_SCRIPTS_SUBDIR "luascripts" PATHSEP From d84c0397426575102e87fff77236733a1d526ceb Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 4 Sep 2019 23:36:23 +0200 Subject: [PATCH 0591/1854] Example of shebang on Lua script --- client/luascripts/cmdline.lua | 3 +++ 1 file changed, 3 insertions(+) mode change 100644 => 100755 client/luascripts/cmdline.lua diff --git a/client/luascripts/cmdline.lua b/client/luascripts/cmdline.lua old mode 100644 new mode 100755 index dc1e752c1..baa76eed6 --- a/client/luascripts/cmdline.lua +++ b/client/luascripts/cmdline.lua @@ -1,5 +1,8 @@ +#!/usr/bin/env -S pm3 -l + --[[ A sampe script file on how to implement at cmd line inteface. +It also demonstrates how the script can be used with a shebang. --]] print("This is how a cmd-line interface could be implemented\nPrint 'exit' to exit.\n") From f8636b18dbdc1f508de37d53b752a0659552f26e Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 4 Sep 2019 23:40:42 +0200 Subject: [PATCH 0592/1854] searchFile: HOME takes precedence on repo and installed paths, more coherent --- client/fileutils.c | 48 +++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/client/fileutils.c b/client/fileutils.c index 1c0403294..a4521fcf8 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -899,6 +899,30 @@ static int searchFinalFile(char **foundpath, const char *pm3dir, const char *sea return PM3_SUCCESS; } } + // try pm3 dirs in user .proxmark3 (user mode) + char *user_path = getenv("HOME"); + if (user_path != NULL) { + char *path = calloc(strlen(user_path) + strlen(PM3_USER_DIRECTORY) + strlen(pm3dir) + strlen(filename) + 1, sizeof(char)); + if (path == NULL) + goto out; + strcpy(path, user_path); + strcat(path, PM3_USER_DIRECTORY); + strcat(path, pm3dir); + strcat(path, filename); + if ((g_debugMode == 2) && (!silent)) { + PrintAndLogEx(INFO, "Searching %s", path); + } + if (fileExists(path)) { + free(filename); + *foundpath = path; + if ((g_debugMode == 2) && (!silent)) { + PrintAndLogEx(INFO, "Found %s", *foundpath); + } + return PM3_SUCCESS; + } else { + free(path); + } + } // try pm3 dirs in current client workdir (dev mode) const char *exec_path = get_my_executable_directory(); if ((exec_path != NULL) && @@ -951,30 +975,6 @@ static int searchFinalFile(char **foundpath, const char *pm3dir, const char *sea free(path); } } - // try pm3 dirs in user .proxmark3 (user mode) - char *user_path = getenv("HOME"); - if (user_path != NULL) { - char *path = calloc(strlen(user_path) + strlen(PM3_USER_DIRECTORY) + strlen(pm3dir) + strlen(filename) + 1, sizeof(char)); - if (path == NULL) - goto out; - strcpy(path, user_path); - strcat(path, PM3_USER_DIRECTORY); - strcat(path, pm3dir); - strcat(path, filename); - if ((g_debugMode == 2) && (!silent)) { - PrintAndLogEx(INFO, "Searching %s", path); - } - if (fileExists(path)) { - free(filename); - *foundpath = path; - if ((g_debugMode == 2) && (!silent)) { - PrintAndLogEx(INFO, "Found %s", *foundpath); - } - return PM3_SUCCESS; - } else { - free(path); - } - } // try pm3 dirs in pm3 installation dir (install mode) { char *path = calloc(strlen(exec_path) + strlen(PM3_SHARE_RELPATH) + strlen(pm3dir) + strlen(filename) + 1, sizeof(char)); From 505eb0a3ca09f064142d82c406b2cd6a7ae8bba9 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 5 Sep 2019 00:11:34 +0200 Subject: [PATCH 0593/1854] path notes: updates --- doc/path_notes.md | 257 +++++++++++++++++++++++++++++++--------------- 1 file changed, 174 insertions(+), 83 deletions(-) diff --git a/doc/path_notes.md b/doc/path_notes.md index 97c117de1..c263adb57 100644 --- a/doc/path_notes.md +++ b/doc/path_notes.md @@ -1,109 +1,178 @@ # Notes on paths. -With the recent (2019-09-01) changes and creation of _make install_ command it is still easy to get lost. +With the recent (2019-09-01) changes and creation of `make install` command it is still easy to get lost. -We are adapting the client to use searchFile when creating or calling a Proxmark3 command with a filename. -Here is where it tries to find the file and in which precedense order it takes. +If you install the Proxmark tools yourself with `make install`, they will go under the prefix `/usr/local/` but if you install the tools from your distro, there are chances the path is `/usr` so you'll have to adapth the paths presented here. + +# Installed elements + +## Binaries + +The main Proxmark3 executables / shellscripts will be copied to + +`/usr/local/bin/` + +* executables: `proxmark3`, `proxmark3-flasher` +* scripts: `pm3`, `pm3-flash-all`, `pm3-flash-bootloader`, `pm3-flash-fullimage` + +Some more executable / scripts will be copied to + +`/usr/local/share/proxmark3/tools` + +* executables: `mfkey32`, `mfkey32v2`, `mfkey64`, `nonce2key` +* scripts: `pm3_eml2lower.sh`, `pm3_eml2upper.sh`, `pm3_mfdread.py`, `pm3_mfd2eml.py`, `pm3_eml2mfd.py`, `findbits.py`, `rfidtest.pl`, `xorcheck.py` -# -``` -/usr/share/proxmark3 -/usr/local/share/proxmark3 -``` +## Firmwares -## binary paths -This is where the Proxmark3 executable / shellscripts will be copied to. -``` -/usr/share/proxmark3/bin -/usr/local/share/proxmark3/bin -``` +The recovery / firmware files will be copied to -This is where the tools executable / scripts will be copied to -``` -/usr/share/proxmark3/tools -/usr/local/share/proxmark3/tools -``` -executables: mfkey32, mfkey32v2, mfkey64, nonce2key, -scripts: pm3_eml2lower.sh, pm3_eml2upper.sh, pm3_mfdread.py, pm3_mfd2eml.py, pm3_eml2mfd.py, findbits.py, rfidtest.pl, xorcheck.py +`/usr/local/share/proxmark3/firmware` -## JTAG stuff -This is where JTAG configurations will be copied to -``` -/usr/share/proxmark3/jtag_openocd -/usr/local/share/proxmark3/tools/jtag_openocd -``` +* Proxmark3 firmware: `bootrom.elf`, `fullimage.elf`, `proxmark3_recovery.bin` (used for JTAG) +* SIM firmware: `sim011.bin`, `sim011.sha512.txt` + + +## Traces -# Traces Proxmark3 client has a lot of sample trace files for many different low frequency tags. They will be copied to -``` -/usr/share/proxmark3/traces -/usr/local/share/proxmark3/traces -``` + +`/usr/local/share/proxmark3/traces` -# Firmware paths -This is where the recovery / firmware files will be copied to. -bootrom.elf, fullimage.elf, proxmark3_recovery.bin (used for JTAG), sim011.bin, sim011.sha512.txt +## JTAG-related stuff + +JTAG configurations and helper scripts for OpenOCD will be copied to + +`/usr/local/share/proxmark3/jtag_openocd` + +## Proxmark3 client files: dictionaries + +Dictionaries used by the client will be copied to + ``` -/usr/share/proxmark3/firmware -/usr/local/share/proxmark3/firmware +/usr/local/share/proxmark3/dictionaries ``` -## User given paths -``` -~/.proxmark3/ -./ -``` - -## Proxmark3 client essential files -``` -/resources -/dictionaries -/lualibs -/luascripts -/cmdscripts -``` - -## seaching for a file -First instance where a file is found will be used in the client. - -1. share (install paths) -2. $HOME/.proxmark3 (user home directory -3. ./ (current working directory) - -## .history / log files -We have now a rolling log file, created new per day. All those logfiles and the .history file is found -``` -~/.proxmar3/history.txt -~/.proxmar3/log_%Y%m%d.txt -``` - -## What is where? -/resources -The needed files for commands like hardnested, fido, EMV, iClass. - -/dictionaries -Here you find the default dictionaries or your own used for commands like `hf mf chk`, `hf mf fchk`, `lf t55xx chk` +Here you find the default dictionaries used for commands like `hf mf chk`, `hf mf fchk`, `lf t55xx chk` A dictionary file is a text based file with one key per line in hexdecimal form. The length of the key is decided by the Proxmark3 client for the different commands. All chars afterwards on line is ignored. if key isn't a hex number, the key is igonored. -- t55xx, Mifare Ultralight/NTAG - uses 4 hexbytes (11223344) +- t55xx, Mifare Ultralight/NTAG - uses 4 hexbytes (11223344) - Mifare classic uses 6 hexbytes (112233445566) - iClass uses 8 hexbytes (1122334455667788) -/luascripts -Here you find existing lua scripts available, or where you put your own custom lua scripts. Look at existing scripts for ideas how to create your own scripts. +See [here](#proxmark3-client-files-and-traces) how to add your own dictionaries. -/lualibs -Here is the supporting lua libraries used for lua scripts. basically reused functions in a lua file like converting string to hex etc. +## Proxmark3 client files: cmd scripts -/cmdscripts -Here you find the proxmark3 client command line scripts. The client can run a text file containing Proxmark3 commands. +Cmd scripts used by the client will be copied to -a samplefile could be like this. +``` +/usr/local/share/proxmark3/cmdscripts +``` + +See [here](#proxmark3-client-files-and-traces) how to add your own cmd scripts. + +## Proxmark3 client files: Lua libraries and scripts + +Lua libraries and scripts used by the client will be copied to + +``` +/usr/local/share/proxmark3/lualibs +/usr/local/share/proxmark3/luascripts +``` + +`lualibs` contains the supporting lua libraries used for lua scripts. Basically reused functions in a lua file like converting string to hex etc. + +See [here](#proxmark3-client-files-and-traces) how to add your own Lua scripts. + +## Proxmark3 client files: various resources + +Various resources used by the client will be copied to + +``` +/usr/local/share/proxmark3/resources +``` + +It comprises the needed files for commands like hardnested, fido, EMV, iClass. + +See [here](#proxmark3-client-files-and-traces) how to add your own resources. + +## Documentation + +Documentation will be copied to + +`/usr/local/share/doc/proxmark3` + +# User files + +The client will make use of a personal directory `~/.proxmark3` (or more precisely `$HOME/.proxmark3`) + +## .history / log files + +We have now a rolling log file, created new per day. All these logfiles and the history file are now located at + +``` +~/.proxmark3/history.txt +~/.proxmark3/log_YYYYMMDD.txt +``` + +## Proxmark3 client files and traces + +If you wants to add scripts, dictionaries or other resources, you can use the same structure as the installed directory structure and add your own files there, e.g. + +``` +~/.proxmark3/cmdscripts/mycmdscript.cmd +~/.proxmark3/dictionaries/mydict.dic +~/.proxmark3/luascripts/myluascript.lua +~/.proxmark3/resources/oids.json +~/.proxmark3/traces/mylftrace.pm3 +``` + +If you add a file with the same name as the file provided with the Proxmark3 installation, it will take precedence. + +See also [Scripts](#scripts) on how to write your own scripts. + +# Seaching files + +With the directory structure explained above, the client applies some heuristics to find its files or the files you specified in command line. + +## TL;DR + +It adds the expected suffix if you didn't provide it yet, then it looks (by order of precedence): + +1. in the current directory, or in the path if you provided also a path, so it works with autocompletion +2. in the `~/.proxmark3` directory structure as seen above, so it works with your stuffs +3. in the repo directory structure, so it works as usual if used from the Git repo +4. in the installed directory structure, so it works when installed + +## Gory details + +The client is using _searchFile_ (in _client/fileutils.c_) when calling a Proxmark3 command with a filename or when the client needs to find its files. +_searchFile_ takes as argument a relative path *pm3dir*, a file to search and possibly a *suffix*. + +So for example when using _searchFile_ over a filename supposed to be a dictionary file, it's called with *pm3dir=dictionaries/* and *suffix=.dic*. +When a user provides a filename (including possibly a path), _searchFile_ will search different locations and return as soon as a file is found: + +* Add the suffix if the suffix is not yet present, so: *foo* -> *foo.dic* and *foo.dic* -> *foo.dic* +* If the filename is an absolute path (*/tmp/foo.dic*), take it as it is, try to access the file and return. +* If the filename is an explicit relative path (*./foo.dic*), take it as it is, try to access the file from the current directory and return. +* Try to find the filename as relative path (*foo.dic* -> *./foo.dic*), so filenames provided by CLI autocompletion work as expected. +* Try to find the filename in the *pm3dir* relative to the user directory *$HOME/.proxmark3* (*foo.dic* -> *~/.proxmark3/dictionaries/foo.dic*) +* Try to find the filename in the *pm3dir* relative to where the client binary is when in the repo configuration (*foo.dic* -> *$(path_to_dir_of_proxmark3_bin)/dictionaries/foo.dic*), so when the client is executed from a repo workdir, filenames are searched in the expected location. +* Try to find the filename in the *pm3dir* relative to where the client binary is when in the installed configuration (*foo.dic* -> *$(path_to_dir_of_proxmark3_bin)/../share/proxmark3/dictionaries/foo.dic* which resolves to e.g. */usr/share/proxmark3/dictionaries/foo.dic* or */usr/local/share/proxmark3/dictionaries/foo.dic*), so when the client is executed from a repo workdir, filenames are searched in the expected location. + +# Scripts + +We've seen that you can provide your own Lua or cmd scripts. +Look at existing scripts for ideas how to create your own scripts. + +For cmd scripts, the command line scripts, the client can run a text file containing Proxmark3 commands. + +A samplefile could be like this. ``` $> cat myscript.cmd @@ -114,7 +183,29 @@ rem done ``` You call it with: -`$> pm3 -c myscript.cmd` -The client will execute eachone of the commands in order and then exit. There are also a possibility to remain in the client afterward with the -i parameter -`pm3 -c myscript.cmd -i` +`$> pm3 -s myscript.cmd` + +The client will execute each one of the commands in order and then exit. There is also a possibility to remain in the client afterwards with the -i parameter: + +`$> pm3 -s myscript.cmd -i` + +You can place it in `~/.proxmark3/cmdscripts/` and it will be found automatically. +You can skip the extension, so `pm3 -s myscript` works equally. + +You can also use the magic of shebangs to make an executable script, e.g. taking the example above, we can write: + +``` +$> cat myscript.cmd + +#!/usr/bin/env -S pm3 -s +hf 14a info +hf mfu info + +$> chmod +x myscript.cmd +$> ./myscript.cmd +``` + +And it will be executed invoking the `pm3` script! + +Or use `#!/usr/bin/env -S proxmark3 -s` if your script is intended to work offline. From 620be5f5ccdbb1d2ba3ab74077856f4705db3380 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 5 Sep 2019 00:14:30 +0200 Subject: [PATCH 0594/1854] doc style --- doc/path_notes.md | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/doc/path_notes.md b/doc/path_notes.md index c263adb57..cfe532daf 100644 --- a/doc/path_notes.md +++ b/doc/path_notes.md @@ -11,14 +11,18 @@ If you install the Proxmark tools yourself with `make install`, they will go und The main Proxmark3 executables / shellscripts will be copied to -`/usr/local/bin/` +``` +/usr/local/bin/ +``` * executables: `proxmark3`, `proxmark3-flasher` * scripts: `pm3`, `pm3-flash-all`, `pm3-flash-bootloader`, `pm3-flash-fullimage` Some more executable / scripts will be copied to -`/usr/local/share/proxmark3/tools` +``` +/usr/local/share/proxmark3/tools +``` * executables: `mfkey32`, `mfkey32v2`, `mfkey64`, `nonce2key` * scripts: `pm3_eml2lower.sh`, `pm3_eml2upper.sh`, `pm3_mfdread.py`, `pm3_mfd2eml.py`, `pm3_eml2mfd.py`, `findbits.py`, `rfidtest.pl`, `xorcheck.py` @@ -28,7 +32,9 @@ Some more executable / scripts will be copied to The recovery / firmware files will be copied to -`/usr/local/share/proxmark3/firmware` +``` +/usr/local/share/proxmark3/firmware +``` * Proxmark3 firmware: `bootrom.elf`, `fullimage.elf`, `proxmark3_recovery.bin` (used for JTAG) * SIM firmware: `sim011.bin`, `sim011.sha512.txt` @@ -38,7 +44,9 @@ The recovery / firmware files will be copied to Proxmark3 client has a lot of sample trace files for many different low frequency tags. They will be copied to -`/usr/local/share/proxmark3/traces` +``` +/usr/local/share/proxmark3/traces +``` ## JTAG-related stuff @@ -105,7 +113,9 @@ See [here](#proxmark3-client-files-and-traces) how to add your own resources. Documentation will be copied to -`/usr/local/share/doc/proxmark3` +``` +/usr/local/share/doc/proxmark3 +``` # User files From 7151f3fd50b4c1aa5b37de242e9f5a52364bbce6 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 5 Sep 2019 00:27:15 +0200 Subject: [PATCH 0595/1854] Provide make common/install --- Makefile | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index a602f0578..bca9681d4 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,9 @@ INSTALLSCRIPTS=pm3 pm3-flash-all pm3-flash-bootrom pm3-flash-fullimage INSTALLSHARES=tools/jtag_openocd traces INSTALLDOCS=doc/*.md doc/md -install: all +install: all common/install + +common/install: $(info [@] Installing common resources to $(MYDESTDIR)$(PREFIX)...) ifneq (,$(INSTALLSCRIPTS)) $(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(INSTALLBINRELPATH) @@ -49,7 +51,9 @@ ifeq ($(platform),Linux) $(Q)$(CP) driver/77-pm3-usb-device-blacklist.rules $(DESTDIR)$(UDEV_PREFIX)/77-pm3-usb-device-blacklist.rules endif -uninstall: +uninstall: common/uninstall + +common/uninstall: $(info [@] Uninstalling common resources from $(MYDESTDIR)$(PREFIX)...) ifneq (,$(INSTALLSCRIPTS)) $(Q)$(RM) $(foreach script,$(INSTALLSCRIPTS),$(DESTDIR)$(PREFIX)$(INSTALLBINRELPATH)$(notdir $(script))) From 326547281d8d6be8ac01d7f90b46f2c266fc324d Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 5 Sep 2019 00:37:25 +0200 Subject: [PATCH 0596/1854] update docs --- Makefile | 2 ++ doc/md/Development/Maintainers.md | 7 +++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index bca9681d4..77e038124 100644 --- a/Makefile +++ b/Makefile @@ -112,6 +112,8 @@ help: @echo "+ all - Make all targets: bootrom, fullimage and OS-specific host tools" @echo "+ clean - Clean in all targets" @echo "+ .../clean - Clean in specified target and its deps, e.g. bootrom/clean" + @echo "+ (un)install - Install/uninstall Proxmark files in the system, default to /usr/local/share, + @echo " else provide a PREFIX. See Maintainers.md for more options" @echo @echo "+ bootrom - Make bootrom" @echo "+ fullimage - Make armsrc fullimage (includes fpga)" diff --git a/doc/md/Development/Maintainers.md b/doc/md/Development/Maintainers.md index 225912c2b..0dda8af3d 100644 --- a/doc/md/Development/Maintainers.md +++ b/doc/md/Development/Maintainers.md @@ -29,7 +29,10 @@ That should be a good start for you to create your package :) It's possible to add other firmwares as well with tagged names (`FWTAG=`), e.g. here we're compiling another image for non-RDV4 devices: -`make -j fullimage/install DESTDIR=build PREFIX=/usr PLATFORM=PM3OTHER PLATFORM_EXTRAS= FWTAG=other` +``` +make -j fullimage PLATFORM=PM3OTHER PLATFORM_EXTRAS= +make fullimage/install PLATFORM=PM3OTHER PLATFORM_EXTRAS= DESTDIR=build PREFIX=/usr FWTAG=other +``` and it will be added along the other firmware as: @@ -52,7 +55,7 @@ Default compiler is gcc but you can use clang for the non-ARM parts with e.g. `m * `make mfkey/install` * `make nonce2key/install` * `make fpga_compress/install` (dummy) -* some shared content installation handled by the root Makefile, which can't be installed alone: +* `make common/install` (some shared content installation:) * `pm3-*` scripts * `tools/jtag_openocd`, `traces` * `doc/md`, `doc/*.md` From 22c5364a232cf0131f4d2ed88f5e8f5407ccd670 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 5 Sep 2019 00:48:14 +0200 Subject: [PATCH 0597/1854] changelog --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6fcbc68d8..c4e1fe1fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,11 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Add cmdscript example and show usage with shebang (@doegox) + - Add instructions for Fedora (@doegox) + - Chg reduce the list of requirements to the minimum and move to QT5 (@doegox) + - Add `make install` and reorganize/rename stuffs accordingly (@doegox) + - Add searchFile for several types of files (@doegox / @iceman1001) - Chg posix sh version of mkversion (@doegox) - Chg remove entirely ncurses, not needed nowadays (@doegox) - Chg remove deprecated termcap, use ncurses instead (@ZeroChaos-) From ecb535cc58b8ba01301c07c0168f3179e2eca2da Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 5 Sep 2019 00:48:48 +0200 Subject: [PATCH 0598/1854] make style --- client/cmdflashmem.c | 2 +- client/cmdflashmemspiffs.c | 4 ++-- client/scripting.c | 14 +++++++------- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/client/cmdflashmem.c b/client/cmdflashmem.c index 0fb25fad9..ce5b37f44 100644 --- a/client/cmdflashmem.c +++ b/client/cmdflashmem.c @@ -209,7 +209,7 @@ static int CmdFlashMemLoad(const char *Cmd) { datalen += 2; break; case DICTIONARY_NONE: - res = loadFile_safe(filename, ".bin", (void**)&data, &datalen); + res = loadFile_safe(filename, ".bin", (void **)&data, &datalen); if (res != PM3_SUCCESS) { free(data); return PM3_EFILE; diff --git a/client/cmdflashmemspiffs.c b/client/cmdflashmemspiffs.c index 0eef78259..109f51ae1 100644 --- a/client/cmdflashmemspiffs.c +++ b/client/cmdflashmemspiffs.c @@ -355,13 +355,13 @@ static int CmdFlashMemSpiFFSLoad(const char *Cmd) { size_t datalen = 0; uint8_t *data = NULL; - int res = loadFile_safe(filename, "", (void**)&data, &datalen); + int res = loadFile_safe(filename, "", (void **)&data, &datalen); // int res = loadFileEML( filename, data, &datalen); if (res != PM3_SUCCESS) { free(data); return PM3_EFILE; } - + // We want to mount before multiple operation so the lazy writes/append will not // trigger a mount + umount each loop iteration (lazy ops device side) SendCommandNG(CMD_SPIFFS_MOUNT, NULL, 0); diff --git a/client/scripting.c b/client/scripting.c index 33e7c6c42..724f72235 100644 --- a/client/scripting.c +++ b/client/scripting.c @@ -1059,20 +1059,20 @@ static int l_searchfile(lua_State *L) { if (n != 2) { return returnToLuaWithError(L, "Only filename and extension"); } - + size_t size; - // data + // data const char *filename = luaL_checklstring(L, 1, &size); - if ( size == 0 ) + if (size == 0) return returnToLuaWithError(L, "Must specify filename"); - - const char *suffix = luaL_checklstring(L, 2, &size); + + const char *suffix = luaL_checklstring(L, 2, &size); char *path; int res = searchFile(&path, "", filename, suffix, false); - if ( res != PM3_SUCCESS) { + if (res != PM3_SUCCESS) { return returnToLuaWithError(L, "Failed to find file"); } - + lua_pushstring(L, path); return 1; } From 70a7a99751832a2c2cfdb79f8f8e9b114bfcc9b5 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 5 Sep 2019 08:45:12 +0200 Subject: [PATCH 0599/1854] make install: more flexible on relpath tuning --- Makefile.defs | 10 +++++----- doc/md/Development/Maintainers.md | 9 +++++++++ 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/Makefile.defs b/Makefile.defs index 6364c794a..64e74c243 100644 --- a/Makefile.defs +++ b/Makefile.defs @@ -28,11 +28,11 @@ LD = g++ PATHSEP=/ PREFIX ?= /usr/local UDEV_PREFIX ?= /etc/udev/rules.d -INSTALLBINRELPATH = /bin/ -INSTALLSHARERELPATH = /share/proxmark3/ -INSTALLFWRELPATH = /share/proxmark3/firmware/ -INSTALLTOOLSRELPATH = /share/proxmark3/tools/ -INSTALLDOCSRELPATH = /share/doc/proxmark3/ +INSTALLBINRELPATH ?= /bin/ +INSTALLSHARERELPATH ?= /share/proxmark3/ +INSTALLFWRELPATH ?= /share/proxmark3/firmware/ +INSTALLTOOLSRELPATH ?= /share/proxmark3/tools/ +INSTALLDOCSRELPATH ?= /share/doc/proxmark3/ platform = $(shell uname) DETECTED_OS=$(platform) diff --git a/doc/md/Development/Maintainers.md b/doc/md/Development/Maintainers.md index 0dda8af3d..3d5e6dbef 100644 --- a/doc/md/Development/Maintainers.md +++ b/doc/md/Development/Maintainers.md @@ -27,6 +27,15 @@ etc. That should be a good start for you to create your package :) +If you need to tune some more paths, see their definition in `Makefile.defs`. +E.g. you might need to move the documentation elsewhere according to your distro policy: + +``` +make install PREFIX=/usr INSTALLDOCSRELPATH=/share/doc/proxmark3-${version}/ +``` + +Be careful to respect the same leading/closing `/` schema else you'll mess up your paths! + It's possible to add other firmwares as well with tagged names (`FWTAG=`), e.g. here we're compiling another image for non-RDV4 devices: ``` From 5dc63fa2392b123862b320b1e3a4ae8e1bdffb96 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 5 Sep 2019 09:29:45 +0200 Subject: [PATCH 0600/1854] Add sim011.asm --- doc/md/Development/Maintainers.md | 2 +- tools/simmodule/sim010.bin | Bin 719 -> 0 bytes tools/simmodule/sim010.sha512.txt | 1 - tools/simmodule/sim011.asm | 713 ++++++++++++++++++++++++++++++ 4 files changed, 714 insertions(+), 2 deletions(-) delete mode 100644 tools/simmodule/sim010.bin delete mode 100644 tools/simmodule/sim010.sha512.txt create mode 100644 tools/simmodule/sim011.asm diff --git a/doc/md/Development/Maintainers.md b/doc/md/Development/Maintainers.md index 3d5e6dbef..bc6b66cf5 100644 --- a/doc/md/Development/Maintainers.md +++ b/doc/md/Development/Maintainers.md @@ -69,7 +69,7 @@ Default compiler is gcc but you can use clang for the non-ARM parts with e.g. `m * `tools/jtag_openocd`, `traces` * `doc/md`, `doc/*.md` * Tools scripts (`pm3_eml2lower.sh` etc) - * SIM firmware (beware currently it's binary blob, may break your distro policies on open source) + * SIM firmware * udev rule on Linux Same logic for `make all`, `make clean`, `make uninstall` diff --git a/tools/simmodule/sim010.bin b/tools/simmodule/sim010.bin deleted file mode 100644 index dea57a7d8608a34020f7d9e5e40a5b6e915be6fa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 719 zcmbVJO=uHA6rS1L$-l5DLa~?K$zPi&EQ<%hi&CM-7^G)Cc=O`ri3c%jCH{bwbYmf* z2XzZliW1uHp@&G~bZdKD268JV2XpY2OEJ|ZaaU8USKl1o_kF{A?|VD}ucL7&IpOTI zGD})h0x#>wDni)!i+zOG{^kG6Sf3s0az&D>s?L!joojZ8)vXrkJUqrdLW$*eSQ(}+ zl9bMadb87X!JVjmY@jfA*tX&f)Jo%)%uI%v$OsFt5DTkj!?>s59LL?d9h7*~Ahr-= zQAi?AAc0iV#;3RdDFhTj+~)y7eQisz`&mdM$VlAlVUuG@e5#rXi78=0HQ&`kB(0iU z^qkg<3C}6&kp!_w(i{9{lABssVqqT9#7j)%(upyRRlyJ&TdEc!PwFABV<5-_#Z+B2 ziB*jID|Zg+Bu*^0!yL|B*IRyD_e^C1kQLy(2p1yUtAj^-uyF;}M_}KC%`NzV;Qa`m zQ+R=3;Tt@ggWWaQots(2uqpq+Hx`G`yvASgGJI-6#f7H^^sj>xf}QX1c?3%WC +; --------------------------------------------------------------------------- + VERS_HI equ 3 + VERS_LO equ 11 +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- + SCON_0 equ 098h + FE_0 equ 098h.7 + + SCON_1 equ 0F8h + RI_1 equ 0F8h.0 + TI_1 equ 0F8h.1 + FE_1 equ 0F8h.7 + SBUF_1 equ 09Ah + T3CON equ 0C4h + RL3 equ 0C5h + RH3 equ 0C6h + + P0M1 equ 0B1h + P0M2 equ 0B2h + P1M1 equ 0B3h + P1M2 equ 0B4h + P3M1 equ 0ACh; + P3M2 equ 0ADh; + + EIE equ 09Bh + EIE1 equ 09Ch + + TA equ 0C7h + + RCTRIM0 equ 084h +; --------------------------------------------------------------------------- + CKCON equ 08Eh + CKDIV equ 095h +; --------------------------------------------------------------------------- + P1S equ 0B3h ;Page1 + SFRS equ 091h ;TA Protection +; --------------------------------------------------------------------------- + AUXR1 equ 0A2h +; --------------------------------------------------------------------------- + I2DAT equ 0BCh; + I2STAT equ 0BDh; + I2CLK equ 0BEh; + I2TOC equ 0BFh; + I2CON equ 0C0h; + ; equ I2CON.7;8 + I2CEN equ I2CON.6;4 + STA equ I2CON.5;2 + STO equ I2CON.4;1 + SI equ I2CON.3;8 + AA equ I2CON.2;4 + ; equ I2CON.1;2 + I2CPX equ I2CON.0;1 + + + I2ADDR equ 0C1h; + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- + pin_TX1 equ P1.6 + + pin_TX0 equ P0.6 + pin_RX0 equ P0.7 + + pin_SCL equ P1.3 + pin_SDA equ P1.4 + + pin_RST equ P1.0 + pin_CLC equ P1.1 + pin_led equ P1.2 + +; --------------------------------------------------------------------------- +; =========================================================================== + + + CMD_GENERATE_ATR equ 01h + CMD_WRITE_DATA_SIM equ 02h + CMD_READ_DATA_SIM equ 03h + + CMD_SET_BAUD_RATE equ 04h + CMD_SET_SIM_CLC equ 05h + CMD_GET_VERS equ 06h + CMD_WRITE_CONFIRM equ 07h + + + +; --------------------------------------------------------------------------- +; =========================================================================== + + bit_RX0 equ 32.0 + bit_command_receive equ 32.1 + bit_generate_ATR equ 32.2 + i2c_write_mode equ 32.3 + i2c_write_done equ 32.4 + bit_data_sim_wr equ 32.5 + bit_length_answer equ 32.6 + bit_TX0 equ 32.7 + + bit_command_buff equ 33.0 + i2c_write_command equ 33.1 + i2c_command_done equ 33.2 + bit_wait_confirm equ 33.3 + bit_first_ATR equ 33.4 ;11/03/2019 +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + bit_32 equ 32 + bit_33 equ 33 + pointer_RX1 equ 34 ;save SBUF(SIM) to XRAM + pointer_RX2 equ 35 ;read XRAM to I2C + pointer_TX equ 36 + + length_send_to_sim equ 37 + length_answer_sim equ 38 + length_command equ 39 + time_data_read equ 40 + time_confirm equ 41 + + buff_command equ 42 + cmd_command equ 42 + data_command equ 43 + + STACKKKKK equ 200 +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- +; Beginning of the main program + cseg at 00 + Ljmp main_start + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- + cseg at 11 ;1302Hz = 4MHZ(Fsys)/12/256 +; --------------------------------------------------------------------------- + jb time_confirm.7, $+3+2 ;3 + dec time_confirm ;2 +; --------------------------------------------------------------------------- + jb time_data_read.7,reti_timer0 + djnz time_data_read, reti_timer0 + setb pin_scl +reti_timer0: + reti + + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- + cseg at 35 ;UART0 + ajmp jmp_UART0_interrupt + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- + cseg at 51 ;I2C + ajmp jmp_i2c_interrupt + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- + cseg at 123 ;UART1 + clr RI_1 + clr TI_1 + reti + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- +jmp_UART0_interrupt: + jbc RI,jmp_byte_RI + jbc TI,jmp_byte_TI + reti +; --------------------------------------------------------------------------- +jmp_byte_RI: + jnb bit_first_ATR, jmp_not_collect ;11/03/2019 + + setb bit_RX0 + jb i2c_write_done,jmp_not_collect + PUSH ACC + inc AUXR1 ;DPTR2 + mov a,SBUF ;DPTR2 + ;mov SBUF_1,DPL ;DPTR2 + mov DPL,pointer_RX1 ;DPTR2 + mov DPH,#1 ;DPTR2 + movx @DPTR,a ;DPTR2 + inc pointer_RX1 ;DPTR2 + inc AUXR1 ;DPTR2 + POP ACC + ;09/08/2018 + clr pin_scl + mov time_data_read,#52 ;52/1302Hz = 40mS + + inc length_answer_sim +jmp_not_collect: + reti +; --------------------------------------------------------------------------- +jmp_byte_TI: + setb bit_TX0 + reti + + +; =========================================================================== +; --------------------------------------------------------------------------- +jmp_i2c_interrupt: + PUSH ACC + PUSH PSW + mov PSW,#24 + mov R7,I2STAT +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + cjne R7,#000h,nextttt00000 + setb STO + clr SI + jb STO,$ + ajmp pop_i2c_psw +nextttt00000: +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + cjne R7,#060h,nextttt00001 ;START+MY ADRESS + clr pin_led ;LED ON + + clr bit_command_receive + clr i2c_write_mode + clr bit_data_sim_wr + clr bit_length_answer + clr bit_command_buff + clr i2c_write_command + + ajmp end_i2c_interrupt +nextttt00001: +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + cjne R7,#080h,nextttt00002 ;RAM ADRESS + + jb bit_command_receive,jmp_data_receive + setb bit_command_receive + + mov a,I2DAT +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + cjne a,#CMD_WRITE_CONFIRM,next_comm001a + + setb bit_wait_confirm + + sjmp jmp_WRITEDATASIM +next_comm001a: +; --------------------------------------------------------------------------- + cjne a,#CMD_WRITE_DATA_SIM,next_comm001b + clr bit_wait_confirm +jmp_WRITEDATASIM: + mov length_send_to_sim,#0 + setb bit_data_sim_wr + mov pointer_TX,#0 + ajmp end_i2c_interrupt +next_comm001b: +; --------------------------------------------------------------------------- + cjne a,#CMD_GENERATE_ATR,next_comm002 + setb bit_generate_ATR + ;Prepare to answer + mov length_answer_sim,#0 + mov pointer_RX1,#0 + mov pointer_RX2,#0 + ajmp end_i2c_interrupt +next_comm002: +; --------------------------------------------------------------------------- + cjne a,#CMD_GET_VERS,next_comm003 + ajmp ANSWER_VERS +next_comm003: +; --------------------------------------------------------------------------- + cjne a,#CMD_SET_BAUD_RATE,next_comm004 + mov R0,#data_command + mov length_command,#0 + mov cmd_command,#CMD_SET_BAUD_RATE + setb i2c_write_command + ajmp end_i2c_interrupt +next_comm004: +; --------------------------------------------------------------------------- + cjne a,#CMD_SET_SIM_CLC,next_comm005 + mov R0,#data_command + mov length_command,#0 + mov cmd_command,#CMD_SET_SIM_CLC + setb i2c_write_command + ajmp end_i2c_interrupt +next_comm005: +; --------------------------------------------------------------------------- + ajmp end_i2c_interrupt +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +jmp_data_receive: + ;What receive ? Data to SIM/Command to bridge + jb bit_data_sim_wr, jmp_data_sim_receive + jb i2c_write_command,jmp_comm_bridge_receive + ajmp end_i2c_interrupt +; --------------------------------------------------------------------------- +jmp_comm_bridge_receive: + mov @R0,I2DAT + inc R0 + inc length_command + ajmp end_i2c_interrupt +; --------------------------------------------------------------------------- +jmp_data_sim_receive: + + setb i2c_write_mode + + inc AUXR1 ;DPTR2 + mov a,I2DAT ;DPTR2 + mov DPL,pointer_TX ;DPTR2 + mov DPH,#0 ;DPTR2 + movx @DPTR,a ;DPTR2 + inc pointer_TX ;DPTR2 + inc AUXR1 ;DPTR2 + + inc length_send_to_sim + ajmp end_i2c_interrupt +nextttt00002: +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + cjne R7,#0A0h,nextttt00003 ;STOP + setb pin_led ;LED OFF + + ;Command finish ? + jnb i2c_write_command,jmp_not_command + clr i2c_write_command + setb i2c_command_done +jmp_not_command: + + ;data to SIM finish ? + jnb i2c_write_mode,end_i2c_interrupt + clr i2c_write_mode + + setb i2c_write_done + ;Prepare to answer + mov length_answer_sim,#0 + mov pointer_RX1,#0 + mov pointer_RX2,#0 + + ajmp end_i2c_interrupt +nextttt00003: +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + cjne R7,#0A8h,nextttt00004 + sjmp read_byte_I2C +nextttt00004: +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + cjne R7,#0B8h,nextttt00005 +read_byte_I2C: + jnb bit_command_buff,jmp_not_comm_buff2 + mov I2DAT,@R0 + inc R0 + ajmp end_i2c_interrupt + +jmp_not_comm_buff2: + jb bit_length_answer,read_byte_APROM + setb bit_length_answer + + mov I2DAT,length_answer_sim + ajmp end_i2c_interrupt +read_byte_APROM: + inc AUXR1 ;DPTR2 + mov DPL,pointer_RX2 ;DPTR2 + mov DPH,#1 ;DPTR2 + movx a,@DPTR ;DPTR2 + mov I2DAT,a ;DPTR2 + inc pointer_RX2 ;DPTR2 + inc AUXR1 ;DPTR2 +nextttt00005: +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +end_i2c_interrupt: + clr STA + clr STO + setb AA +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +pop_i2c_psw: + POP PSW + POP ACC + clr SI + reti + + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- +ANSWER_VERS: + mov R0,#data_command + mov cmd_command,#CMD_GET_VERS + mov (data_command+0),#2 + mov (data_command+1),#VERS_HI + mov (data_command+2),#VERS_LO + setb bit_command_buff + ajmp end_i2c_interrupt + + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- +; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +main_start: + mov SP,#STACKKKKK +; --------------------------------------------------------------------------- + ;0-bidirect 1-push pull 0-input only 1-open drain + ;0 0 1 1 +; --------------------------------------------------------------------------- + mov P0M2,#01000000b ;Р0 + mov P0M1,#11111111b ;P1.6-Tx0 SIM; + ; + mov P1M2,#01011111b ;Р1 + mov P1M1,#10111000b ;P1.6-Tx1 DEBUG; P1.4,P1.3 - I2C; + + mov P3M2,#00000000b ;P3 + mov P3M1,#11111111b ; +; --------------------------------------------------------------------------- + mov TMOD, #22h + mov TH0, #0 ;14400hz + mov TH1, #0E9h ;UART0 10800 Bit/sec + mov TCON, #55h +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + mov TA,#0AAh + mov TA,#055h + orl SFRS,#00000001b + + mov P1S, #00010000b ;P1.4 trigger schmiddt + + mov TA,#0AAh + mov TA,#055h + anl SFRS,#11111110b +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + ;------- CONFIG I2C --------- + mov I2CON, #44h ;set AA, set I2C enable + setb pin_sda + setb pin_scl + mov I2ADDR,#0C0h +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + ;mov SCON, #050h ;UART0 8bit + mov SCON, #0D0h ;UART0 9bit + ;mov PCON, #11000000b;FE_0 enable + mov PCON, #10000000b;FE_0 disable +; --------------------------------------------------------------------------- + mov SCON_1,#050h ;UART1 + ;mov T3CON, #01101000b;FE_1 enable TIMER3 UART0 BAUD + ;mov T3CON, #00101000b;FE_1 disable TIMER3 UART0 BAUD + mov T3CON, #00001000b;FE_1 disable TIMER1 UART0 BAUD + ;mov RL3,#0E9h ;10800/21600 + ;mov RH3,#0FFh +; --------------------------------------------------------------------------- + ;UART1 + mov RL3,#0F7h ;27777/55556 + mov RH3,#0FFh +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + mov CKDIV,#2 ;Fsys=4.00MHZ + ;mov CKDIV,#1 ;Fsys=8.00MHZ +; --------------------------------------------------------------------------- + mov bit_32,#0 + mov bit_33,#0 + setb time_data_read.7 +; --------------------------------------------------------------------------- + ;orl CKCON,#00000010b ;ENABLE CLC TIMER1 Fsys/12 + orl CKCON,#00010010b ;ENABLE CLC TIMER1 Fsys +; --------------------------------------------------------------------------- + ;mov a,RCTRIM0 + ;add a,#31 + ;mov TA,#0AAh + ;mov TA,#055h + ;mov RCTRIM0,a +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + acall clr_buffer +; --------------------------------------------------------------------------- + mov EIE, #00000001b ;I2C Interrupt + ;mov IE, #10010000b ;EA, SERIAL0 + mov IE, #10010010b ;EA, SERIAL0, TIMER0 +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +main_loop: + acall control_ATR + acall control_send_to_sim + acall control_command + sjmp main_loop + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- +control_command: + jbc i2c_command_done,$+3+1 ;3 + ret ;1 +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + ;Control Length command=1 + mov a,length_command + cjne a,#1,next_commandEND ;error length_command != 1 +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + mov a,cmd_command + cjne a,#CMD_SET_BAUD_RATE,next_command001 + mov TH1,data_command ;Timer1 HIGH byte + ret +next_command001: +; --------------------------------------------------------------------------- + cjne a,#CMD_SET_SIM_CLC, next_command002 + mov CKDIV,data_command ;Fsys DIV + ret +next_command002: +; --------------------------------------------------------------------------- +next_commandEND: + ret + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- +control_send_to_sim: + jb i2c_write_done,$+3+1 ;3 + ret ;1 +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + jbc bit_wait_confirm,jmp_wait_confirm +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + mov DPTR,#0000 +looop_send: + movx a,@DPTR + inc DPTR + acall for_coooooom0 + djnz length_send_to_sim,looop_send +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + jnb bit_RX0,$ + clr i2c_write_done + ret + + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- +jmp_wait_confirm: + mov DPTR,#0001 + movx a,@DPTR + mov R3,a + mov R4,#5 +; --------------------------------------------------------------------------- + mov DPTR,#0000 +looop_seend: + movx a,@DPTR + inc DPTR + acall for_coooooom0 + djnz R4,jmp_not_5byte + + jnb bit_RX0,$ + clr bit_RX0 + ;18/12/2018 + mov time_confirm,#65 ;New timeout 50mS +looop_waitconf: + jb time_confirm.7,jmp_no_answer + jnb bit_RX0,looop_waitconf + + ;clr pin_scl ;TEST PULSE! + mov a,SBUF + xrl a,R3 + ;setb pin_scl ;TEST PULSE! + + jnz jmp_no_correct_answer ;18/12/2018 + + ;pause for next byte 17/12/2018 + mov R7,#0 + djnz R7,$ ;~260mkSec + djnz R7,$ ;~260mkSec + djnz R7,$ ;~260mkSec + +jmp_not_5byte: + djnz length_send_to_sim,looop_seend +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + jnb bit_RX0,$ + clr bit_RX0 +jmp_no_answer: + clr i2c_write_done + ret + +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +;18/12/2018 +jmp_no_correct_answer: + clr EA + clr i2c_write_done + mov a,SBUF + mov DPL,pointer_RX1 + mov DPH,#1 + movx @DPTR,a + inc pointer_RX1 + clr pin_scl + mov time_data_read,#52 ;52/1302Hz = 40mS + inc length_answer_sim + setb EA + ret + + + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- +control_ATR: + jbc bit_generate_ATR,$+3+1 ;3 + ret ;1 +; --------------------------------------------------------------------------- + clr pin_RST + ;acall clr_buffer + ; Add rezet pause 17/12/2018 + + mov R6,#200 +looop_pause50mS: + djnz R7,$ ;~260mkSec + djnz R6,looop_pause50mS + + ;Prepare to answer 11/03/2019 + acall clr_buffer + mov length_answer_sim,#0 + mov pointer_RX1,#0 + mov pointer_RX2,#0 + setb bit_first_ATR + setb pin_RST + ret + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- +for_coooooom0: + clr bit_RX0 + mov c,P + mov TB8,c ;9bit parity + mov SBUF,a + jnb bit_TX0,$ + clr bit_TX0 + mov R7,#100 + djnz R7,$ + ret + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- +clr_buffer: + mov DPTR,#0256 ;Receive SIM buffer + mov R7,#255 + clr a +looop_clr_bufff: + movx @DPTR,a + inc DPTR + djnz R7,looop_clr_bufff + ret + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- +;for_coooooom1: +; mov SBUF_1,a +; jnb TI_1,$ +; clr TI_1 +; ret +; +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- + +end. From b1a63eac71b6f9fca49250803268e3d20930f8de Mon Sep 17 00:00:00 2001 From: Iceman Date: Thu, 5 Sep 2019 11:05:59 +0200 Subject: [PATCH 0601/1854] Update README.md --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9d8492f56..6680f5333 100644 --- a/README.md +++ b/README.md @@ -21,11 +21,12 @@ It is dedicated to bringing the most out of the new features for Proxmark3 RDV4. |[Proxmark3 GUI](#proxmark3-gui)|[Setup and build for Windows](/doc/md/Installation_Instructions/Windows-Installation-Instructions.md)|[Commands & Features](/doc/md/Use_of_Proxmark/3_Commands-and-Features.md)| |[Issues](#issues)|[Blue shark manual](/doc/bt_manual_v10.md) |[Advanced compilation parameters](/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md)| |[Notes on UART](/doc/uart_notes.md)|[Maintainers](/doc/md/Development/Maintainers.md)|[Command Cheat sheet](/doc/cheatsheet.md)| -|[Notes on Frame format](/doc/new_frame_format.md)||[More cheat sheets](https://github.com/RfidResearchGroup/proxmark3/wiki/More-cheat-sheets)| +|[Notes on frame format](/doc/new_frame_format.md)||[More cheat sheets](https://github.com/RfidResearchGroup/proxmark3/wiki/More-cheat-sheets)| |[Notes on external flash](/doc/ext_flash_notes.md)||[EMV](/doc/emv_notes.md)| |[Notes on Termux / Android](/doc/termux_notes.md)||[Troubleshooting](/doc/md/Installation_Instructions/Troubleshooting.md)| -|[Notes on Wireshark / tracedata](/doc/trace_wireshark_notes.md)||[JTAG](/doc/jtag_notes.md)| +|[Notes on wireshark / tracedata](/doc/trace_wireshark_notes.md)||[JTAG](/doc/jtag_notes.md)| |[Notes on loclass](/doc/loclass_notes.md)||| +|[Notes on paths](/doc/path_notes.md)||| |[Developing standalone mode](/armsrc/Standalone/readme.md)|[Wiki about standalone mode](https://github.com/RfidResearchGroup/proxmark3/wiki/Standalone-mode) || |[Donations](#Donations)||| @@ -65,6 +66,7 @@ If you intend to contribute to the code, please read the [coding style notes](HA - Internal notes on [Wireshark / tracedata](/doc/trace_wireshark_notes.md) - Internal notes on [loclass](/doc/loclass_notes.md) - Internal notes on [EMV](/doc/emv_notes.md) +- Internal notes on [Paths](/doc/path_notes.md) ## Cheat sheet From 955eb2e5367a6ab3e7b08facbef605a931f8959c Mon Sep 17 00:00:00 2001 From: Iceman Date: Thu, 5 Sep 2019 11:21:54 +0200 Subject: [PATCH 0602/1854] Update path_notes.md --- doc/path_notes.md | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/doc/path_notes.md b/doc/path_notes.md index cfe532daf..334b435b0 100644 --- a/doc/path_notes.md +++ b/doc/path_notes.md @@ -1,9 +1,9 @@ # Notes on paths. -With the recent (2019-09-01) changes and creation of `make install` command it is still easy to get lost. +With the recent (2019-09-01) changes and creation of `make install` command it is easy to get lost. -If you install the Proxmark tools yourself with `make install`, they will go under the prefix `/usr/local/` but if you install the tools from your distro, there are chances the path is `/usr` so you'll have to adapth the paths presented here. +If you install the Proxmark tools with `make install`, they will go under the prefix `/usr/local/` but if you install the tools from your distro, there are chances the path is `/usr` so you'll have to adapt the paths presented here. # Installed elements @@ -55,6 +55,7 @@ JTAG configurations and helper scripts for OpenOCD will be copied to `/usr/local/share/proxmark3/jtag_openocd` + ## Proxmark3 client files: dictionaries Dictionaries used by the client will be copied to @@ -146,7 +147,7 @@ If you add a file with the same name as the file provided with the Proxmark3 ins See also [Scripts](#scripts) on how to write your own scripts. -# Seaching files +# Searching files With the directory structure explained above, the client applies some heuristics to find its files or the files you specified in command line. @@ -177,9 +178,10 @@ When a user provides a filename (including possibly a path), _searchFile_ will s # Scripts -We've seen that you can provide your own Lua or cmd scripts. +You can provide your own lua or cmd scripts. Look at existing scripts for ideas how to create your own scripts. +### Proxmark command script (.cmd) For cmd scripts, the command line scripts, the client can run a text file containing Proxmark3 commands. A samplefile could be like this. @@ -201,8 +203,13 @@ The client will execute each one of the commands in order and then exit. There `$> pm3 -s myscript.cmd -i` You can place it in `~/.proxmark3/cmdscripts/` and it will be found automatically. -You can skip the extension, so `pm3 -s myscript` works equally. +You can skip the script file extension, it works equally well with. + +`pm3 -s myscript` + + +### Shebangs (on *nix) You can also use the magic of shebangs to make an executable script, e.g. taking the example above, we can write: ``` @@ -216,6 +223,7 @@ $> chmod +x myscript.cmd $> ./myscript.cmd ``` -And it will be executed invoking the `pm3` script! +And it will be executed invoking the `pm3` script. -Or use `#!/usr/bin/env -S proxmark3 -s` if your script is intended to work offline. +use the following if your script is intended to work offline. +`#!/usr/bin/env -S proxmark3 -s` From 9fd646f25fc105e00e0c07f7f070d59e328b964a Mon Sep 17 00:00:00 2001 From: Iceman Date: Thu, 5 Sep 2019 11:29:32 +0200 Subject: [PATCH 0603/1854] Create extensions_notes.md --- doc/extensions_notes.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 doc/extensions_notes.md diff --git a/doc/extensions_notes.md b/doc/extensions_notes.md new file mode 100644 index 000000000..3d4cfe5a1 --- /dev/null +++ b/doc/extensions_notes.md @@ -0,0 +1,16 @@ +# Notes on file extensions + +The Proxmark3 client uses a wide range of files. Here is a brief recap to get you up to speed. + + +- .exe windows executable +- .bin binary file, can be firmware or memory dump of a tag +- .eml text file, with memory dump of a tag +- .mfd binary file, usually created with Mifare Classic Tool app (MCT), contains memory dump of tag. Very similar to .bin file +- .json JSON file, usually settings file or it can also be a memory dump of a tag +- .dic dictionary file. textual, with keys/passwords one line / key +- .elf binary proxmark3 device firmware file. +- .cmd text file, contains proxmark3 client commands used to call client with -s +- .lua text file, contains lua script to be run inside client. or called with -l +- .pm3 text file, with numbers ranging 0-255 or -127 - 128. Contains trace signal data for low frequency tags (data load) +- .trace binary file, contains trace log data usually from high frequency tags. (hw trace load) From 9ce37fdd1c66418f69cb77801c3ae4140a91973a Mon Sep 17 00:00:00 2001 From: Iceman Date: Thu, 5 Sep 2019 11:33:34 +0200 Subject: [PATCH 0604/1854] Update extensions_notes.md --- doc/extensions_notes.md | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/doc/extensions_notes.md b/doc/extensions_notes.md index 3d4cfe5a1..f8d4c75c1 100644 --- a/doc/extensions_notes.md +++ b/doc/extensions_notes.md @@ -2,15 +2,16 @@ The Proxmark3 client uses a wide range of files. Here is a brief recap to get you up to speed. - -- .exe windows executable -- .bin binary file, can be firmware or memory dump of a tag -- .eml text file, with memory dump of a tag -- .mfd binary file, usually created with Mifare Classic Tool app (MCT), contains memory dump of tag. Very similar to .bin file -- .json JSON file, usually settings file or it can also be a memory dump of a tag -- .dic dictionary file. textual, with keys/passwords one line / key -- .elf binary proxmark3 device firmware file. -- .cmd text file, contains proxmark3 client commands used to call client with -s -- .lua text file, contains lua script to be run inside client. or called with -l -- .pm3 text file, with numbers ranging 0-255 or -127 - 128. Contains trace signal data for low frequency tags (data load) -- .trace binary file, contains trace log data usually from high frequency tags. (hw trace load) +| extension | description| +|---|---| +| .exe | windows executable | +| .bin | binary file, can be firmware or memory dump of a tag | +| .eml | text file, with memory dump of a tag | +| .mfd | binary file, usually created with Mifare Classic Tool app (MCT), contains memory dump of tag. Very similar to .bin file | +| .json | JSON file, usually settings file or it can also be a memory dump of a tag | +| .dic | dictionary file. textual, with keys/passwords one line / key | +| .elf | binary proxmark3 device firmware file. | +| .cmd | text file, contains proxmark3 client commands used to call client with -s | +| .lua | text file, contains lua script to be run inside client. or called with -l | +| .pm3 | text file, with numbers ranging 0-255 or -127 - 128. Contains trace signal data for low frequency tags (data load) | +| .trace | binary file, contains trace log data usually from high frequency tags. (hw trace load) | From 1429ef20f0b1ce2c79f1397c04314cdc8e10f6a4 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 5 Sep 2019 14:22:52 +0200 Subject: [PATCH 0605/1854] update notes --- doc/path_notes.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/doc/path_notes.md b/doc/path_notes.md index 334b435b0..bcdc19e33 100644 --- a/doc/path_notes.md +++ b/doc/path_notes.md @@ -210,6 +210,7 @@ You can skip the script file extension, it works equally well with. ### Shebangs (on *nix) + You can also use the magic of shebangs to make an executable script, e.g. taking the example above, we can write: ``` @@ -225,5 +226,10 @@ $> ./myscript.cmd And it will be executed invoking the `pm3` script. -use the following if your script is intended to work offline. -`#!/usr/bin/env -S proxmark3 -s` +Use the following if your script is intended to work offline. + +``` +#!/usr/bin/env -S proxmark3 -s +``` + +Beware the shebang trick is not available on all the platforms, it requires your `env` to accept the `-S` switch. From 01950bd962e835e9d37596efeb4f8e9478eee34d Mon Sep 17 00:00:00 2001 From: Iceman Date: Thu, 5 Sep 2019 15:46:40 +0200 Subject: [PATCH 0606/1854] chg more ansi color --- include/ansi.h | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/include/ansi.h b/include/ansi.h index 29df618a1..49bd46039 100644 --- a/include/ansi.h +++ b/include/ansi.h @@ -1,11 +1,14 @@ #ifndef __ANSI_H #define __ANSI_H -#define _BLUE_(s) "\x1b[34m" s "\x1b[0m " -#define _RED_(s) "\x1b[31m" s "\x1b[0m " -#define _GREEN_(s) "\x1b[32m" s "\x1b[0m " -#define _YELLOW_(s) "\x1b[33m" s "\x1b[0m " -#define _MAGENTA_(s) "\x1b[35m" s "\x1b[0m " -#define _CYAN_(s) "\x1b[36m" s "\x1b[0m " +#define AEND "\x1b[0m " + +#define _BLUE_(s) "\x1b[34m" s AEND +#define _RED_(s) "\x1b[31m" s AEND +#define _GREEN_(s) "\x1b[32m" s AEND +#define _YELLOW_(s) "\x1b[33m" s AEND +#define _MAGENTA_(s) "\x1b[35m" s AEND +#define _CYAN_(s) "\x1b[36m" s AEND +#define _WHITE_(s) "\x1b[37m" s AEND #endif From c9d42699fbb7f961cfb051a5fa90a1f2bd5b46f0 Mon Sep 17 00:00:00 2001 From: Iceman Date: Thu, 5 Sep 2019 15:52:40 +0200 Subject: [PATCH 0607/1854] textual --- client/proxmark3.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/client/proxmark3.c b/client/proxmark3.c index 7e732360f..26256dd12 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -8,18 +8,15 @@ //----------------------------------------------------------------------------- // Main binary //----------------------------------------------------------------------------- + #include "proxmark3.h" - #include - #include // for Mingw readline #include #include #include #include - #include "usart_defs.h" - #include "util_posix.h" #include "proxgui.h" #include "cmdmain.h" @@ -28,7 +25,7 @@ #include "whereami.h" #include "comms.h" #include "fileutils.h" -//#include "usart.h" + static void showBanner(void) { PrintAndLogEx(NORMAL, "\n"); @@ -47,7 +44,8 @@ static void showBanner(void) { PrintAndLogEx(NORMAL, "==. ==. ... ==. ====.. https://github.com/rfidresearchgroup/proxmark3/"); PrintAndLogEx(NORMAL, "... ... ... ..... pre-release v4.0"); #endif - PrintAndLogEx(NORMAL, "\nSupport iceman on patreon, https://www.patreon.com/iceman1001/"); + PrintAndLogEx(NORMAL, "\nSupport iceman on patreon - https://www.patreon.com/iceman1001/"); + PrintAndLogEx(NORMAL, " on paypal - https://www.paypal.me/iceman1001"); // printf("\nMonero: 43mNJLpgBVaTvyZmX9ajcohpvVkaRy1kbZPm8tqAb7itZgfuYecgkRF36rXrKFUkwEGeZedPsASRxgv4HPBHvJwyJdyvQuP"); PrintAndLogEx(NORMAL, "\n"); fflush(stdout); From 3323126d7ba9df6a89c2507fbecd4a4f446b9b9f Mon Sep 17 00:00:00 2001 From: Iceman Date: Thu, 5 Sep 2019 16:07:25 +0200 Subject: [PATCH 0608/1854] adaption --- client/cmdhficlass.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 26e23d170..8a544f655 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -36,10 +36,10 @@ static int CmdHelp(const char *Cmd); static uint8_t iClass_Key_Table[ICLASS_KEYS_MAX][8] = { - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xAE, 0xA6, 0x84, 0xA6, 0xDA, 0xB2, 0x32, 0x78 }, + { 0x76, 0x65, 0x54, 0x43, 0x32, 0x21, 0x10, 0x00 }, + { 0x5B, 0x7C, 0x62, 0xC4, 0x91, 0xc1, 0x1b, 0x39 }, + { 0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, From 1ca235e58f5337eb06013e7c59c4d3a9e7606e44 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 5 Sep 2019 22:39:30 +0200 Subject: [PATCH 0609/1854] chg: `hf iclass decrypt -d` - now also reads enccrypted blockdata as param to decrypt --- client/cmdhficlass.c | 94 ++++++++++++++++++++++++++++---------------- 1 file changed, 60 insertions(+), 34 deletions(-) diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 8a544f655..bed919cc9 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -76,14 +76,17 @@ static int usage_hf_iclass_decrypt(void) { PrintAndLogEx(NORMAL, "OBS! In order to use this function, the file 'iclass_decryptionkey.bin' must reside"); PrintAndLogEx(NORMAL, "in the resources directory. The file should be 16 bytes binary data"); PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Usage: hf iclass decrypt f k "); + PrintAndLogEx(NORMAL, "Usage: hf iclass decrypt d f k "); PrintAndLogEx(NORMAL, " options"); - PrintAndLogEx(NORMAL, " f filename of dump"); - PrintAndLogEx(NORMAL, " k 16 bytes hex"); + PrintAndLogEx(NORMAL, " d 16 bytes hex") + PrintAndLogEx(NORMAL, " f filename of dump"); + PrintAndLogEx(NORMAL, " k 16 bytes hex"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, "S hf iclass decrypt f tagdump_1.bin"); PrintAndLogEx(NORMAL, "S hf iclass decrypt f tagdump_1.bin k 000102030405060708090a0b0c0d0e0f"); + PrintAndLogEx(NORMAL, "S hf iclass decrypt d 1122334455667788 k 000102030405060708090a0b0c0d0e0f"); + return PM3_SUCCESS; } static int usage_hf_iclass_encrypt(void) { @@ -796,8 +799,12 @@ static int CmdHFiClassDecrypt(const char *Cmd) { bool errors = false; bool have_key = false; + bool have_data = false; + bool have_file = false; uint8_t cmdp = 0; + uint8_t enc_data[8] = {0}; + size_t keylen = 0; uint8_t key[32] = {0}; uint8_t *keyptr = NULL; @@ -810,6 +817,15 @@ static int CmdHFiClassDecrypt(const char *Cmd) { switch (tolower(param_getchar(Cmd, cmdp))) { case 'h': return usage_hf_iclass_decrypt(); + case 'd': + if (param_gethex(Cmd, cmdp + 1, enc_data, 16)) { + PrintAndLogEx(ERR, "data must be 16 HEX symbols"); + errors = true; + break; + } + have_data = true; + cmdp += 2; + break; case 'f': if (param_getstr(Cmd, cmdp + 1, filename, sizeof(filename)) == 0) { PrintAndLogEx(WARNING, "no filename found after f"); @@ -821,6 +837,7 @@ static int CmdHFiClassDecrypt(const char *Cmd) { errors = true; break; } + have_file = true; cmdp += 2; break; case 'k': @@ -848,45 +865,54 @@ static int CmdHFiClassDecrypt(const char *Cmd) { memcpy(key, keyptr, sizeof(key)); } - picopass_hdr *hdr = (picopass_hdr *)decrypted; - - uint8_t mem = hdr->conf.mem_config; - uint8_t chip = hdr->conf.chip_config; - uint8_t applimit = hdr->conf.app_limit; - uint8_t kb = 2; - uint8_t app_areas = 2; - uint8_t max_blk = 31; - getMemConfig(mem, chip, &max_blk, &app_areas, &kb); - // tripledes mbedtls_des3_context ctx; mbedtls_des3_set2key_dec(&ctx, key); - uint8_t enc_dump[8] = {0}; - uint8_t empty[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; - for (uint16_t blocknum = 0; blocknum < applimit; ++blocknum) { + uint8_t dec_data[8] = {0}; + + if ( have_data ) { + mbedtls_des3_crypt_ecb(&ctx, enc_data, dec_data); + PrintAndLogEx(SUCCESS, "Data: %s", sprint_hex(dec_data, sizeof(dec_data))); + } - uint8_t idx = blocknum * 8; - memcpy(enc_dump, decrypted + idx, 8); + if ( have_file ) { + picopass_hdr *hdr = (picopass_hdr *)decrypted; - // block 7 or higher, and not empty 0xFF - if (blocknum > 6 && memcmp(enc_dump, empty, 8) != 0) { - mbedtls_des3_crypt_ecb(&ctx, enc_dump, decrypted + idx); + uint8_t mem = hdr->conf.mem_config; + uint8_t chip = hdr->conf.chip_config; + uint8_t applimit = hdr->conf.app_limit; + uint8_t kb = 2; + uint8_t app_areas = 2; + uint8_t max_blk = 31; + getMemConfig(mem, chip, &max_blk, &app_areas, &kb); + + uint8_t empty[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + + for (uint16_t blocknum = 0; blocknum < applimit; ++blocknum) { + + uint8_t idx = blocknum * 8; + memcpy(enc_data, decrypted + idx, 8); + + // block 7 or higher, and not empty 0xFF + if (blocknum > 6 && memcmp(enc_data, empty, 8) != 0) { + mbedtls_des3_crypt_ecb(&ctx, enc_data, decrypted + idx); + } } + + //Use the first block (CSN) for filename + char *fptr = calloc(42, sizeof(uint8_t)); + strcat(fptr, "hf-iclass-"); + FillFileNameByUID(fptr, hdr->csn, "-data-decrypted", sizeof(hdr->csn)); + + saveFile(fptr, ".bin", decrypted, decryptedlen); + saveFileEML(fptr, decrypted, decryptedlen, 8); + saveFileJSON(fptr, jsfIclass, decrypted, decryptedlen); + + printIclassDumpContents(decrypted, 1, (decryptedlen / 8), decryptedlen); + free(decrypted); + free(fptr); } - - //Use the first block (CSN) for filename - char *fptr = calloc(42, sizeof(uint8_t)); - strcat(fptr, "hf-iclass-"); - FillFileNameByUID(fptr, hdr->csn, "-data-decrypted", sizeof(hdr->csn)); - - saveFile(fptr, ".bin", decrypted, decryptedlen); - saveFileEML(fptr, decrypted, decryptedlen, 8); - saveFileJSON(fptr, jsfIclass, decrypted, decryptedlen); - - printIclassDumpContents(decrypted, 1, (decryptedlen / 8), decryptedlen); - free(decrypted); - free(fptr); return PM3_SUCCESS; } From 9cf2cd7ca92ee637cd97427b8f4181a524181fc4 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 5 Sep 2019 23:20:46 +0200 Subject: [PATCH 0610/1854] remove leading/tailing "/" from installation RELPATHs --- Makefile | 38 +++++++++++++++---------------- Makefile.defs | 14 ++++++------ Makefile.host | 6 ++--- armsrc/Makefile | 6 ++--- bootrom/Makefile | 6 ++--- client/Makefile | 12 +++++----- doc/md/Development/Maintainers.md | 4 +--- recovery/Makefile | 6 ++--- 8 files changed, 45 insertions(+), 47 deletions(-) diff --git a/Makefile b/Makefile index 77e038124..90ee442ca 100644 --- a/Makefile +++ b/Makefile @@ -27,24 +27,24 @@ install: all common/install common/install: $(info [@] Installing common resources to $(MYDESTDIR)$(PREFIX)...) ifneq (,$(INSTALLSCRIPTS)) - $(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(INSTALLBINRELPATH) - $(Q)$(CP) $(INSTALLSCRIPTS) $(DESTDIR)$(PREFIX)$(INSTALLBINRELPATH) + $(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLBINRELPATH) + $(Q)$(CP) $(INSTALLSCRIPTS) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLBINRELPATH) endif ifneq (,$(INSTALLSHARES)) - $(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(INSTALLSHARERELPATH) - $(Q)$(CP) $(INSTALLSHARES) $(DESTDIR)$(PREFIX)$(INSTALLSHARERELPATH) + $(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH) + $(Q)$(CP) $(INSTALLSHARES) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH) endif ifneq (,$(INSTALLDOCS)) - $(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(INSTALLDOCSRELPATH) - $(Q)$(CP) $(INSTALLDOCS) $(DESTDIR)$(PREFIX)$(INSTALLDOCSRELPATH) + $(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLDOCSRELPATH) + $(Q)$(CP) $(INSTALLDOCS) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLDOCSRELPATH) endif ifneq (,$(INSTALLTOOLS)) - $(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(INSTALLTOOLSRELPATH) - $(Q)$(CP) $(foreach tool,$(INSTALLTOOLS),tools/$(tool)) $(DESTDIR)$(PREFIX)$(INSTALLTOOLSRELPATH) + $(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLTOOLSRELPATH) + $(Q)$(CP) $(foreach tool,$(INSTALLTOOLS),tools/$(tool)) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLTOOLSRELPATH) endif ifneq (,$(INSTALLSIMFW)) - $(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(INSTALLFWRELPATH) - $(Q)$(CP) $(foreach fw,$(INSTALLSIMFW),tools/simmodule/$(fw)) $(DESTDIR)$(PREFIX)$(INSTALLFWRELPATH) + $(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH) + $(Q)$(CP) $(foreach fw,$(INSTALLSIMFW),tools/simmodule/$(fw)) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH) endif ifeq ($(platform),Linux) $(Q)$(MKDIR) $(DESTDIR)$(UDEV_PREFIX) @@ -56,27 +56,27 @@ uninstall: common/uninstall common/uninstall: $(info [@] Uninstalling common resources from $(MYDESTDIR)$(PREFIX)...) ifneq (,$(INSTALLSCRIPTS)) - $(Q)$(RM) $(foreach script,$(INSTALLSCRIPTS),$(DESTDIR)$(PREFIX)$(INSTALLBINRELPATH)$(notdir $(script))) + $(Q)$(RM) $(foreach script,$(INSTALLSCRIPTS),$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLBINRELPATH)$(PATHSEP)$(notdir $(script))) endif ifneq (,$(INSTALLSHARES)) - $(Q)$(RMDIR) $(foreach share,$(INSTALLSHARES),$(DESTDIR)$(PREFIX)$(INSTALLSHARERELPATH)$(notdir $(share))) + $(Q)$(RMDIR) $(foreach share,$(INSTALLSHARES),$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH)$(PATHSEP)$(notdir $(share))) endif ifneq (,$(INSTALLDOCS)) - $(Q)$(RMDIR) $(foreach doc,$(INSTALLDOCS),$(DESTDIR)$(PREFIX)$(INSTALLDOCSRELPATH)$(notdir $(doc))) - $(Q)$(RMDIR_SOFT) $(DESTDIR)$(PREFIX)$(INSTALLDOCSRELPATH) + $(Q)$(RMDIR) $(foreach doc,$(INSTALLDOCS),$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLDOCSRELPATH)$(PATHSEP)$(notdir $(doc))) + $(Q)$(RMDIR_SOFT) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLDOCSRELPATH) endif ifneq (,$(INSTALLTOOLS)) - $(Q)$(RM) $(foreach tool,$(INSTALLTOOLS),$(DESTDIR)$(PREFIX)$(INSTALLTOOLSRELPATH)$(notdir $(tool))) + $(Q)$(RM) $(foreach tool,$(INSTALLTOOLS),$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLTOOLSRELPATH)$(PATHSEP)$(notdir $(tool))) endif - $(Q)$(RMDIR_SOFT) $(DESTDIR)$(PREFIX)$(INSTALLTOOLSRELPATH) + $(Q)$(RMDIR_SOFT) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLTOOLSRELPATH) ifneq (,$(INSTALLSIMFW)) - $(Q)$(RM) $(foreach fw,$(INSTALLSIMFW),$(DESTDIR)$(PREFIX)$(INSTALLFWRELPATH)$(notdir $(fw))) + $(Q)$(RM) $(foreach fw,$(INSTALLSIMFW),$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH)$(PATHSEP)$(notdir $(fw))) endif - $(Q)$(RMDIR_SOFT) $(DESTDIR)$(PREFIX)$(INSTALLFWRELPATH) + $(Q)$(RMDIR_SOFT) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH) ifeq ($(platform),Linux) $(Q)$(RM) $(DESTDIR)$(UDEV_PREFIX)/77-pm3-usb-device-blacklist.rules endif - $(Q)$(RMDIR_SOFT) $(DESTDIR)$(PREFIX)$(INSTALLSHARERELPATH) + $(Q)$(RMDIR_SOFT) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH) mfkey/%: FORCE $(info [*] MAKE $@) diff --git a/Makefile.defs b/Makefile.defs index 64e74c243..4068d7516 100644 --- a/Makefile.defs +++ b/Makefile.defs @@ -26,13 +26,13 @@ CXX = g++ LD = g++ PATHSEP=/ -PREFIX ?= /usr/local -UDEV_PREFIX ?= /etc/udev/rules.d -INSTALLBINRELPATH ?= /bin/ -INSTALLSHARERELPATH ?= /share/proxmark3/ -INSTALLFWRELPATH ?= /share/proxmark3/firmware/ -INSTALLTOOLSRELPATH ?= /share/proxmark3/tools/ -INSTALLDOCSRELPATH ?= /share/doc/proxmark3/ +PREFIX ?= /usr/local +UDEV_PREFIX ?= /etc/udev/rules.d +INSTALLBINRELPATH ?= bin +INSTALLSHARERELPATH ?= share/proxmark3 +INSTALLFWRELPATH ?= share/proxmark3/firmware +INSTALLTOOLSRELPATH ?= share/proxmark3/tools +INSTALLDOCSRELPATH ?= share/doc/proxmark3 platform = $(shell uname) DETECTED_OS=$(platform) diff --git a/Makefile.host b/Makefile.host index 8fb6fceed..bfadd82b7 100644 --- a/Makefile.host +++ b/Makefile.host @@ -37,15 +37,15 @@ clean: install: all ifneq (,$(INSTALLTOOLS)) $(info [@] Installing $(BINS) to $(DESTDIR)$(PREFIX)...) - $(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(INSTALLTOOLSRELPATH) - $(Q)$(CP) $(INSTALLTOOLS) $(DESTDIR)$(PREFIX)$(INSTALLTOOLSRELPATH) + $(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLTOOLSRELPATH) + $(Q)$(CP) $(INSTALLTOOLS) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLTOOLSRELPATH) endif @true uninstall: ifneq (,$(INSTALLTOOLS)) $(info [@] Uninstalling $(BINS) from $(DESTDIR)$(PREFIX)...) - $(Q)$(RM) $(foreach tool,$(INSTALLTOOLS),$(DESTDIR)$(PREFIX)$(INSTALLTOOLSRELPATH)$(notdir $(tool))) + $(Q)$(RM) $(foreach tool,$(INSTALLTOOLS),$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLTOOLSRELPATH)$(PATHSEP)$(notdir $(tool))) endif @true diff --git a/armsrc/Makefile b/armsrc/Makefile index bb8f17ef2..f94868b6e 100644 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@ -222,12 +222,12 @@ clean: install: all $(info [@] Installing fullimage to $(DESTDIR)$(PREFIX)...) - $(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(INSTALLFWRELPATH) - $(Q)$(CP) $(INSTALLFW) $(DESTDIR)$(PREFIX)$(INSTALLFWRELPATH)$(INSTALLFWTAG) + $(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH) + $(Q)$(CP) $(INSTALLFW) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH)$(PATHSEP)$(INSTALLFWTAG) uninstall: $(info [@] Uninstalling fullimage from $(DESTDIR)$(PREFIX)...) - $(Q)$(RM) $(DESTDIR)$(PREFIX)$(INSTALLFWRELPATH)$(INSTALLFWTAG) + $(Q)$(RM) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH)$(PATHSEP)$(INSTALLFWTAG) .PHONY: all clean help install uninstall help: diff --git a/bootrom/Makefile b/bootrom/Makefile index 0d3f081d9..d666f3acd 100644 --- a/bootrom/Makefile +++ b/bootrom/Makefile @@ -60,12 +60,12 @@ clean: install: all $(info [@] Installing bootrom to $(DESTDIR)$(PREFIX)...) - $(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(INSTALLFWRELPATH) - $(Q)$(CP) $(INSTALLFW) $(DESTDIR)$(PREFIX)$(INSTALLFWRELPATH) + $(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH) + $(Q)$(CP) $(INSTALLFW) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH) uninstall: $(info [@] Uninstalling bootrom from $(DESTDIR)$(PREFIX)...) - $(Q)$(RM) $(foreach fw,$(INSTALLFW),$(DESTDIR)$(PREFIX)$(INSTALLFWRELPATH)$(notdir $(fw))) + $(Q)$(RM) $(foreach fw,$(INSTALLFW),$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH)$(PATHSEP)$(notdir $(fw))) .PHONY: all clean help install help: diff --git a/client/Makefile b/client/Makefile index b670965b6..96b5d1bf4 100644 --- a/client/Makefile +++ b/client/Makefile @@ -328,22 +328,22 @@ clean: install: all $(info [@] Installing client to $(DESTDIR)$(PREFIX)...) ifneq (,$(INSTALLBIN)) - $(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(INSTALLBINRELPATH) - $(Q)$(CP) $(INSTALLBIN) $(DESTDIR)$(PREFIX)$(INSTALLBINRELPATH) + $(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLBINRELPATH) + $(Q)$(CP) $(INSTALLBIN) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLBINRELPATH) endif ifneq (,$(INSTALLSHARE)) - $(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(INSTALLSHARERELPATH) - $(Q)$(CP) $(INSTALLSHARE) $(DESTDIR)$(PREFIX)$(INSTALLSHARERELPATH) + $(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH) + $(Q)$(CP) $(INSTALLSHARE) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH) endif @true uninstall: $(info [@] Uninstalling client from $(DESTDIR)$(PREFIX)...) ifneq (,$(INSTALLBIN)) - $(Q)$(RM) $(foreach tool,$(INSTALLBIN),$(DESTDIR)$(PREFIX)$(INSTALLBINRELPATH)$(notdir $(tool))) + $(Q)$(RM) $(foreach tool,$(INSTALLBIN),$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLBINRELPATH)$(PATHSEP)$(notdir $(tool))) endif ifneq (,$(INSTALLSHARE)) - $(Q)$(RMDIR) $(foreach tool,$(INSTALLSHARE),$(DESTDIR)$(PREFIX)$(INSTALLSHARERELPATH)$(notdir $(tool))) + $(Q)$(RMDIR) $(foreach tool,$(INSTALLSHARE),$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH)$(PATHSEP)$(notdir $(tool))) endif @true diff --git a/doc/md/Development/Maintainers.md b/doc/md/Development/Maintainers.md index bc6b66cf5..ff3525784 100644 --- a/doc/md/Development/Maintainers.md +++ b/doc/md/Development/Maintainers.md @@ -31,11 +31,9 @@ If you need to tune some more paths, see their definition in `Makefile.defs`. E.g. you might need to move the documentation elsewhere according to your distro policy: ``` -make install PREFIX=/usr INSTALLDOCSRELPATH=/share/doc/proxmark3-${version}/ +make install PREFIX=/usr INSTALLDOCSRELPATH=share/doc/proxmark3-${version} ``` -Be careful to respect the same leading/closing `/` schema else you'll mess up your paths! - It's possible to add other firmwares as well with tagged names (`FWTAG=`), e.g. here we're compiling another image for non-RDV4 devices: ``` diff --git a/recovery/Makefile b/recovery/Makefile index 5a5fda0e8..2bfd1475f 100644 --- a/recovery/Makefile +++ b/recovery/Makefile @@ -28,11 +28,11 @@ clean: install: all $(info [@] Installing recovery to $(DESTDIR)$(PREFIX)...) - $(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(INSTALLFWRELPATH) - $(Q)$(CP) $(INSTALLFW) $(DESTDIR)$(PREFIX)$(INSTALLFWRELPATH)$(INSTALLFWTAG) + $(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH) + $(Q)$(CP) $(INSTALLFW) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH)$(PATHSEP)$(INSTALLFWTAG) uninstall: $(info [@] Uninstalling recovery from $(DESTDIR)$(PREFIX)...) - $(Q)$(RM) $(DESTDIR)$(PREFIX)$(INSTALLFWRELPATH)$(INSTALLFWTAG) + $(Q)$(RM) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH)$(PATHSEP)$(INSTALLFWTAG) .PHONY: all clean install uninstall From ffe849fb93e431039fa2a125a0b0b30a50a43d40 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 5 Sep 2019 23:34:51 +0200 Subject: [PATCH 0611/1854] fixing compilation bug in iclass --- client/cmdhficlass.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index bed919cc9..1580f40f6 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -78,7 +78,7 @@ static int usage_hf_iclass_decrypt(void) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Usage: hf iclass decrypt d f k "); PrintAndLogEx(NORMAL, " options"); - PrintAndLogEx(NORMAL, " d 16 bytes hex") + PrintAndLogEx(NORMAL, " d 16 bytes hex"); PrintAndLogEx(NORMAL, " f filename of dump"); PrintAndLogEx(NORMAL, " k 16 bytes hex"); PrintAndLogEx(NORMAL, ""); From f1eceab385f53b13f68d003234f8acb77190d5fd Mon Sep 17 00:00:00 2001 From: Iceman Date: Fri, 6 Sep 2019 09:00:01 +0200 Subject: [PATCH 0612/1854] chg: `hf iclass` / `hf mfu` - free some 3des contexts --- client/cmdhficlass.c | 7 +++++-- client/cmdhfmfu.c | 23 ++++++++++++----------- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 1580f40f6..1482db5bd 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -870,11 +870,11 @@ static int CmdHFiClassDecrypt(const char *Cmd) { mbedtls_des3_set2key_dec(&ctx, key); uint8_t dec_data[8] = {0}; - + if ( have_data ) { mbedtls_des3_crypt_ecb(&ctx, enc_data, dec_data); PrintAndLogEx(SUCCESS, "Data: %s", sprint_hex(dec_data, sizeof(dec_data))); - } + } if ( have_file ) { picopass_hdr *hdr = (picopass_hdr *)decrypted; @@ -913,6 +913,8 @@ static int CmdHFiClassDecrypt(const char *Cmd) { free(decrypted); free(fptr); } + + mbedtls_des3_free(&ctx); return PM3_SUCCESS; } @@ -923,6 +925,7 @@ static void iClassEncryptBlkData(uint8_t *blk_data, uint8_t *key) { mbedtls_des3_set2key_enc(&ctx, key); mbedtls_des3_crypt_ecb(&ctx, blk_data, encrypted); memcpy(blk_data, encrypted, 8); + mbedtls_des3_free(&ctx); } static int CmdHFiClassEncryptBlk(const char *Cmd) { diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index 23eac5504..818265569 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -2519,7 +2519,7 @@ static int CmdHF14AMfUCSetUid(const char *Cmd) { if (param_gethex(Cmd, 0, uid, 14)) { PrintAndLogEx(WARNING, "UID must include 14 HEX symbols"); - return 1; + return PM3_EINVARG; } // read block2. @@ -2527,7 +2527,7 @@ static int CmdHF14AMfUCSetUid(const char *Cmd) { SendCommandMIX(CMD_HF_MIFAREU_READBL, 2, 0, 0, NULL, 0); if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { PrintAndLogEx(WARNING, "Command execute timeout"); - return 2; + return PM3_ETIMEOUT; } // save old block2. @@ -2544,7 +2544,7 @@ static int CmdHF14AMfUCSetUid(const char *Cmd) { SendCommandOLD(CMD_HF_MIFAREU_WRITEBL, 0, 0, 0, data, sizeof(data)); if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { PrintAndLogEx(WARNING, "Command execute timeout"); - return 3; + return PM3_ETIMEOUT; } // block 1. @@ -2556,7 +2556,7 @@ static int CmdHF14AMfUCSetUid(const char *Cmd) { SendCommandOLD(CMD_HF_MIFAREU_WRITEBL, 1, 0, 0, data, sizeof(data)); if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { PrintAndLogEx(WARNING, "Command execute timeout"); - return 4; + return PM3_ETIMEOUT; } // block 2. @@ -2568,9 +2568,9 @@ static int CmdHF14AMfUCSetUid(const char *Cmd) { SendCommandOLD(CMD_HF_MIFAREU_WRITEBL, 2, 0, 0, data, sizeof(data)); if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { PrintAndLogEx(WARNING, "Command execute timeout"); - return 5; + return PM3_ETIMEOUT; } - return 0; + return PM3_SUCCESS; } static int CmdHF14AMfUGenDiverseKeys(const char *Cmd) { @@ -2681,8 +2681,9 @@ static int CmdHF14AMfUGenDiverseKeys(const char *Cmd) { PrintAndLogEx(NORMAL, "Mifare ABA :\t %s", sprint_hex(dmkey, sizeof(dmkey))); PrintAndLogEx(NORMAL, "Mifare Pwd :\t %s", sprint_hex(newpwd, sizeof(newpwd))); + mbedtls_des3_free(&ctx); // next. from the diversify_key method. - return 0; + return PM3_SUCCESS; } static int CmdHF14AMfUPwdGen(const char *Cmd) { @@ -2709,11 +2710,11 @@ static int CmdHF14AMfUPwdGen(const char *Cmd) { // 3: proprietary Anticollision if (select_status == 0) { PrintAndLogEx(WARNING, "iso14443a card select failed"); - return 1; + return PM3_ESOFT; } if (card.uidlen != 7) { PrintAndLogEx(WARNING, "Wrong sized UID, expected 7bytes got %d", card.uidlen); - return 1; + return PM3_ESOFT; } memcpy(uid, card.uid, sizeof(uid)); } else { @@ -2732,7 +2733,7 @@ static int CmdHF14AMfUPwdGen(const char *Cmd) { PrintAndLogEx(NORMAL, "------+----------+-----"); PrintAndLogEx(NORMAL, " Vingcard algo"); PrintAndLogEx(NORMAL, "--------------------"); - return 0; + return PM3_SUCCESS; } //------------------------------------ // Menu Stuff @@ -2757,7 +2758,7 @@ static command_t CommandTable[] = { static int CmdHelp(const char *Cmd) { (void)Cmd; // Cmd is not used so far CmdsHelp(CommandTable); - return 0; + return PM3_SUCCESS; } int CmdHFMFUltra(const char *Cmd) { From c373929c75d2749cc8f5367454e6ee1827258cca Mon Sep 17 00:00:00 2001 From: Iceman Date: Fri, 6 Sep 2019 09:15:02 +0200 Subject: [PATCH 0613/1854] ignore renamed flasher --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 5b45564b3..55640b44a 100644 --- a/.gitignore +++ b/.gitignore @@ -38,6 +38,7 @@ client/ui/ui_overlays.h hardnested_stats.txt proxmark3 +proxmark3-flasher flasher !flasher/ lua From 57dc1849dafc5fa1c045361777cc7bbbf3a64441 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 6 Sep 2019 16:52:05 +0200 Subject: [PATCH 0614/1854] return --- client/cmdhfmfu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index 818265569..7c81ebfd6 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -2191,7 +2191,7 @@ static int CmdHF14AMfURestore(const char *Cmd) { // convert old format to new format, if need int res = convertOldMfuDump(&dump, &bytes_read); - if (res) { + if (res != PM3_SUCCESS) { PrintAndLogEx(WARNING, "Failed convert on load to new Ultralight/NTAG format"); free(dump); return res; From da4da03d320771dd524b3fa62ac4494ab8caab6d Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 6 Sep 2019 16:52:25 +0200 Subject: [PATCH 0615/1854] ignore .proxmark3 folder --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 55640b44a..fda8c21af 100644 --- a/.gitignore +++ b/.gitignore @@ -77,3 +77,4 @@ client/lualibs/pm3_cmd.lua # recompiled fpga_version_info.c +.proxmark3/* From c34660b74c6d80a67055ffc3b3b1bf7a0ed27bf8 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 6 Sep 2019 17:22:54 +0200 Subject: [PATCH 0616/1854] free some mem --- client/fileutils.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/client/fileutils.c b/client/fileutils.c index a4521fcf8..3abdcc4f0 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -103,9 +103,9 @@ static char *newfilenamemcopy(const char *preferredName, const char *suffix) { int saveFile(const char *preferredName, const char *suffix, const void *data, size_t datalen) { - if (data == NULL) return 1; + if (data == NULL) return PM3_EINVARG; char *fileName = newfilenamemcopy(preferredName, suffix); - if (fileName == NULL) return 1; + if (fileName == NULL) return PM3_EMALLOC; /* We should have a valid filename now, e.g. dumpdata-3.bin */ @@ -126,9 +126,9 @@ int saveFile(const char *preferredName, const char *suffix, const void *data, si int saveFileEML(const char *preferredName, uint8_t *data, size_t datalen, size_t blocksize) { - if (data == NULL) return 1; + if (data == NULL) return PM3_EINVARG; char *fileName = newfilenamemcopy(preferredName, ".eml"); - if (fileName == NULL) return 1; + if (fileName == NULL) return PM3_EMALLOC; int retval = PM3_SUCCESS; int blocks = datalen / blocksize; @@ -171,9 +171,9 @@ out: int saveFileJSON(const char *preferredName, JSONFileType ftype, uint8_t *data, size_t datalen) { - if (data == NULL) return 1; + if (data == NULL) return PM3_EINVARG; char *fileName = newfilenamemcopy(preferredName, ".json"); - if (fileName == NULL) return 1; + if (fileName == NULL) return PM3_EMALLOC; int retval = PM3_SUCCESS; @@ -425,12 +425,16 @@ int loadFile_safe(const char *preferredName, const char *suffix, void **pdata, s if (fsize <= 0) { PrintAndLogEx(FAILED, "error, when getting filesize"); + free(path); + fclose(f); return PM3_EFILE; } *pdata = calloc(fsize, sizeof(uint8_t)); if (!pdata) { PrintAndLogEx(FAILED, "error, cannot allocate memory"); + free(path); + fclose(f); return PM3_EMALLOC; } @@ -440,20 +444,22 @@ int loadFile_safe(const char *preferredName, const char *suffix, void **pdata, s if (bytes_read != fsize) { PrintAndLogEx(FAILED, "error, bytes read mismatch file size"); + free(path); return PM3_EFILE; } *datalen = bytes_read; PrintAndLogEx(SUCCESS, "loaded %d bytes from binary file " _YELLOW_("%s"), bytes_read, preferredName); + free(path); return retval; } int loadFileEML(const char *preferredName, void *data, size_t *datalen) { - if (data == NULL) return 1; + if (data == NULL) return PM3_EINVARG; char *fileName = filenamemcopy(preferredName, ".eml"); - if (fileName == NULL) return 1; + if (fileName == NULL) return PM3_EMALLOC; size_t counter = 0; int retval = PM3_SUCCESS, hexlen = 0; @@ -505,9 +511,9 @@ out: int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_t *datalen) { - if (data == NULL) return 1; + if (data == NULL) return PM3_EINVARG; char *fileName = filenamemcopy(preferredName, ".json"); - if (fileName == NULL) return 1; + if (fileName == NULL) return PM3_EMALLOC; *datalen = 0; json_t *root; @@ -632,7 +638,7 @@ out: int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, uint8_t keylen, uint16_t *keycnt) { - if (data == NULL) return PM3_ESOFT; + if (data == NULL) return PM3_EINVARG; char *path; if (searchFile(&path, DICTIONARIES_SUBDIR, preferredName, ".dic", false) != PM3_SUCCESS) return PM3_EFILE; From 8228b66cb6d6a8e1c43df436c705f6fac897e467 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 7 Sep 2019 10:32:16 +0200 Subject: [PATCH 0617/1854] chg: \n - param not obsessed with two hexsamples. \n textual --- client/cmdhficlass.c | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 1482db5bd..a096137ee 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -1350,10 +1350,7 @@ static int CmdHFiClass_WriteBlock(const char *Cmd) { case 'h': return usage_hf_iclass_writeblock(); case 'b': - if (param_gethex(Cmd, cmdp + 1, &blockno, 2)) { - PrintAndLogEx(WARNING, "Block No must include 2 HEX symbols\n"); - errors = true; - } + blockno = param_get8ex(Cmd, cmdp + 1, 06, 16); cmdp += 2; break; case 'c': @@ -1616,10 +1613,7 @@ static int CmdHFiClass_ReadBlock(const char *Cmd) { case 'h': return usage_hf_iclass_readblock(); case 'b': - if (param_gethex(Cmd, cmdp + 1, &blockno, 2)) { - PrintAndLogEx(WARNING, "Block No must include 2 HEX symbols\n"); - errors = true; - } + blockno = param_get8ex(Cmd, cmdp + 1, 06, 16); cmdp += 2; break; case 'c': @@ -2610,25 +2604,25 @@ static int CmdHFiClassPermuteKey(const char *Cmd) { static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, - {"calcnewkey", CmdHFiClassCalcNewKey, AlwaysAvailable, "[options..] Calc Diversified keys (blocks 3 & 4) to write new keys"}, - {"chk", CmdHFiClassCheckKeys, AlwaysAvailable, " Check keys"}, - {"clone", CmdHFiClassCloneTag, IfPm3Iclass, "[options..] Authenticate and Clone from iClass bin file"}, - {"decrypt", CmdHFiClassDecrypt, AlwaysAvailable, "[f ] Decrypt tagdump" }, + {"calcnewkey", CmdHFiClassCalcNewKey, AlwaysAvailable, "[options..] Calc diversified keys (blocks 3 & 4) to write new keys"}, + {"chk", CmdHFiClassCheckKeys, AlwaysAvailable, "[options..] Check keys"}, + {"clone", CmdHFiClassCloneTag, IfPm3Iclass, "[options..] Clone (restore from tagdump file)"}, + {"decrypt", CmdHFiClassDecrypt, AlwaysAvailable, "[options..] Decrypt given block data or tagdump file" }, {"dump", CmdHFiClassReader_Dump, IfPm3Iclass, "[options..] Authenticate and Dump iClass tag's AA1"}, {"eload", CmdHFiClassELoad, IfPm3Iclass, "[f ] (experimental) Load data into iClass emulator memory"}, - {"encryptblk", CmdHFiClassEncryptBlk, AlwaysAvailable, " Encrypt given block data"}, - {"list", CmdHFiClassList, AlwaysAvailable, " List iClass history"}, + {"encrypt", CmdHFiClassEncryptBlk, AlwaysAvailable, "[options..] Encrypt given block data"}, + {"list", CmdHFiClassList, AlwaysAvailable, " List iClass history"}, {"loclass", CmdHFiClass_loclass, AlwaysAvailable, "[options..] Use loclass to perform bruteforce of reader attack dump"}, {"lookup", CmdHFiClassLookUp, AlwaysAvailable, "[options..] Uses authentication trace to check for key in dictionary file"}, {"managekeys", CmdHFiClassManageKeys, AlwaysAvailable, "[options..] Manage the keys to use with iClass"}, {"permutekey", CmdHFiClassPermuteKey, IfPm3Iclass, " Permute function from 'heart of darkness' paper"}, - {"readblk", CmdHFiClass_ReadBlock, IfPm3Iclass, "[options..] Authenticate and Read iClass block"}, + {"readblk", CmdHFiClass_ReadBlock, IfPm3Iclass, "[options..] Read iClass block"}, {"reader", CmdHFiClassReader, IfPm3Iclass, " Act like an iClass reader"}, {"readtagfile", CmdHFiClassReadTagFile, AlwaysAvailable, "[options..] Display Content from tagfile"}, {"replay", CmdHFiClassReader_Replay, IfPm3Iclass, " Read an iClass tag via Replay Attack"}, {"sim", CmdHFiClassSim, IfPm3Iclass, "[options..] Simulate iClass tag"}, {"sniff", CmdHFiClassSniff, IfPm3Iclass, " Eavesdrop iClass communication"}, - {"writeblk", CmdHFiClass_WriteBlock, IfPm3Iclass, "[options..] Authenticate and Write iClass block"}, + {"writeblk", CmdHFiClass_WriteBlock, IfPm3Iclass, "[options..] Write iClass block"}, {NULL, NULL, NULL, NULL} }; From 710c49f7632f4d9fea09e16c515108d624f522a9 Mon Sep 17 00:00:00 2001 From: sh7d <47714037+sh7d@users.noreply.github.com> Date: Sat, 7 Sep 2019 11:36:41 +0200 Subject: [PATCH 0618/1854] autopwn: fix card detection --- client/cmdhfmf.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index be05d85d2..b74a5af3a 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -1660,7 +1660,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { // Settings bool slow = false; bool legacy_mfchk = false; - bool prng_type = false; + int prng_type = 0; bool verbose = false; bool has_filename = false; bool errors = false; @@ -1776,8 +1776,12 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { } } - // card prng type (weak=true / hard=false) + // card prng type (weak=1 / hard=0 / select/card comm error fail = -vaule) prng_type = detect_classic_prng(); + if (prng_type < 0){ + PrintAndLogEx(FAILED, "\nNo tag detected or other tag communication error"); + goto noValidKeyFound; + } // print parameters if (verbose) { From 9ce820768c7778db6620511bdf51f32fb7f09f66 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 7 Sep 2019 12:07:09 +0200 Subject: [PATCH 0619/1854] missing free --- client/fileutils.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/client/fileutils.c b/client/fileutils.c index 3abdcc4f0..9a5907882 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -415,8 +415,10 @@ int loadFile_safe(const char *preferredName, const char *suffix, void **pdata, s FILE *f = fopen(path, "rb"); if (!f) { PrintAndLogEx(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", path); + free(path); return PM3_EFILE; } + free(path); // get filesize in order to malloc memory fseek(f, 0, SEEK_END); @@ -425,7 +427,6 @@ int loadFile_safe(const char *preferredName, const char *suffix, void **pdata, s if (fsize <= 0) { PrintAndLogEx(FAILED, "error, when getting filesize"); - free(path); fclose(f); return PM3_EFILE; } @@ -433,7 +434,6 @@ int loadFile_safe(const char *preferredName, const char *suffix, void **pdata, s *pdata = calloc(fsize, sizeof(uint8_t)); if (!pdata) { PrintAndLogEx(FAILED, "error, cannot allocate memory"); - free(path); fclose(f); return PM3_EMALLOC; } @@ -444,14 +444,12 @@ int loadFile_safe(const char *preferredName, const char *suffix, void **pdata, s if (bytes_read != fsize) { PrintAndLogEx(FAILED, "error, bytes read mismatch file size"); - free(path); return PM3_EFILE; } *datalen = bytes_read; PrintAndLogEx(SUCCESS, "loaded %d bytes from binary file " _YELLOW_("%s"), bytes_read, preferredName); - free(path); return retval; } From 93e323d890c1912c756c9b4d3b4484655832c7e8 Mon Sep 17 00:00:00 2001 From: sh7d <47714037+sh7d@users.noreply.github.com> Date: Sat, 7 Sep 2019 19:41:48 +0200 Subject: [PATCH 0620/1854] Review requested changes --- client/cmdhfmf.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index b74a5af3a..90501943b 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -1660,7 +1660,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { // Settings bool slow = false; bool legacy_mfchk = false; - int prng_type = 0; + int prng_type = PM3_EUNDEF; bool verbose = false; bool has_filename = false; bool errors = false; @@ -1776,11 +1776,12 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { } } - // card prng type (weak=1 / hard=0 / select/card comm error fail = -vaule) + // card prng type (weak=1 / hard=0 / select/card comm error = negative value) prng_type = detect_classic_prng(); if (prng_type < 0){ PrintAndLogEx(FAILED, "\nNo tag detected or other tag communication error"); - goto noValidKeyFound; + free(e_sector); + return prng_type; } // print parameters From 28534c10ade76c41e6ff8245abdcc47258d44384 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 7 Sep 2019 20:45:12 +0200 Subject: [PATCH 0621/1854] hf mf autopwn not available offline --- client/cmdhfmf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 90501943b..30c7c2c32 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -4394,7 +4394,7 @@ static command_t CommandTable[] = { {"darkside", CmdHF14AMfDarkside, IfPm3Iso14443a, "Darkside attack. read parity error messages."}, {"nested", CmdHF14AMfNested, IfPm3Iso14443a, "Nested attack. Test nested authentication"}, {"hardnested", CmdHF14AMfNestedHard, AlwaysAvailable, "Nested attack for hardened Mifare cards"}, - {"autopwn", CmdHF14AMfAutoPWN, AlwaysAvailable, "Automatic attack tool, to extrackt the nfc keys (with dicrionaries, nested and hardnested attacks)"}, + {"autopwn", CmdHF14AMfAutoPWN, IfPm3Iso14443a, "Automatic attack tool, to extrackt the nfc keys (with dicrionaries, nested and hardnested attacks)"}, {"keybrute", CmdHF14AMfKeyBrute, IfPm3Iso14443a, "J_Run's 2nd phase of multiple sector nested authentication key recovery"}, {"nack", CmdHf14AMfNack, IfPm3Iso14443a, "Test for Mifare NACK bug"}, {"chk", CmdHF14AMfChk, IfPm3Iso14443a, "Check keys"}, @@ -4410,7 +4410,7 @@ static command_t CommandTable[] = { {"auth4", CmdHF14AMfAuth4, IfPm3Iso14443a, "ISO14443-4 AES authentication"}, // {"sniff", CmdHF14AMfSniff, 0, "Sniff card-reader communication"}, {"-----------", CmdHelp, IfPm3Iso14443a, ""}, - {"sim", CmdHF14AMfSim, IfPm3Iso14443a, "Simulate MIFARE card"}, + {"sim", CmdHF14AMfSim, IfPm3Iso14443a, "Simulate MIFARE card"}, {"eclr", CmdHF14AMfEClear, IfPm3Iso14443a, "Clear simulator memory"}, {"eget", CmdHF14AMfEGet, IfPm3Iso14443a, "Get simulator memory block"}, {"eset", CmdHF14AMfESet, IfPm3Iso14443a, "Set simulator memory block"}, From fbe86a9070c5c2c86eb6a316fc7eca7c01912ddc Mon Sep 17 00:00:00 2001 From: Iceman Date: Sun, 8 Sep 2019 12:29:10 +0200 Subject: [PATCH 0622/1854] Update cmdhfmf.c Textual, and HF MF KEYBRUTE is considered obselete since improved hardnested. Will let it still be in code for learning purposes. --- client/cmdhfmf.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 30c7c2c32..7335a41af 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -4390,13 +4390,13 @@ static int CmdHF14AMfList(const char *Cmd) { static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, - {"list", CmdHF14AMfList, AlwaysAvailable, "List Mifare history"}, - {"darkside", CmdHF14AMfDarkside, IfPm3Iso14443a, "Darkside attack. read parity error messages."}, - {"nested", CmdHF14AMfNested, IfPm3Iso14443a, "Nested attack. Test nested authentication"}, - {"hardnested", CmdHF14AMfNestedHard, AlwaysAvailable, "Nested attack for hardened Mifare cards"}, - {"autopwn", CmdHF14AMfAutoPWN, IfPm3Iso14443a, "Automatic attack tool, to extrackt the nfc keys (with dicrionaries, nested and hardnested attacks)"}, - {"keybrute", CmdHF14AMfKeyBrute, IfPm3Iso14443a, "J_Run's 2nd phase of multiple sector nested authentication key recovery"}, - {"nack", CmdHf14AMfNack, IfPm3Iso14443a, "Test for Mifare NACK bug"}, + {"list", CmdHF14AMfList, AlwaysAvailable, "List MIFARE history"}, + {"darkside", CmdHF14AMfDarkside, IfPm3Iso14443a, "Darkside attack"}, + {"nested", CmdHF14AMfNested, IfPm3Iso14443a, "Nested attack"}, + {"hardnested", CmdHF14AMfNestedHard, AlwaysAvailable, "Nested attack for hardened MIFARE Classic cards"}, + {"autopwn", CmdHF14AMfAutoPWN, IfPm3Iso14443a, "Automatic key recovery tool for MIFARE Classic"}, +// {"keybrute", CmdHF14AMfKeyBrute, IfPm3Iso14443a, "J_Run's 2nd phase of multiple sector nested authentication key recovery"}, + {"nack", CmdHf14AMfNack, IfPm3Iso14443a, "Test for MIFARE NACK bug"}, {"chk", CmdHF14AMfChk, IfPm3Iso14443a, "Check keys"}, {"fchk", CmdHF14AMfChk_fast, IfPm3Iso14443a, "Check keys fast, targets all keys on card"}, {"decrypt", CmdHf14AMfDecryptBytes, AlwaysAvailable, "[nt] [ar_enc] [at_enc] [data] - to decrypt sniff or trace"}, @@ -4429,7 +4429,7 @@ static command_t CommandTable[] = { {"mad", CmdHF14AMfMAD, IfPm3Iso14443a, "Checks and prints MAD"}, {"ndef", CmdHFMFNDEF, IfPm3Iso14443a, "Prints NDEF records from card"}, - {"ice", CmdHF14AMfice, IfPm3Iso14443a, "collect Mifare Classic nonces to file"}, + {"ice", CmdHF14AMfice, IfPm3Iso14443a, "collect MIFARE Classic nonces to file"}, {NULL, NULL, NULL, NULL} }; From a037766e26ecc405ed6c76fb00241c4c9df1cfdc Mon Sep 17 00:00:00 2001 From: RFID Research Group Date: Sun, 8 Sep 2019 12:57:25 +0200 Subject: [PATCH 0623/1854] Update cmdhfmf.c chg: hf mf brute - commented out. --- client/cmdhfmf.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 7335a41af..baa999128 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -244,6 +244,7 @@ static int usage_hf14_chk_fast(void) { PrintAndLogEx(NORMAL, " hf mf fchk 1 m -- target 1K, use dictionary from flashmemory"); return 0; } +/* static int usage_hf14_keybrute(void) { PrintAndLogEx(NORMAL, "J_Run's 2nd phase of multiple sector nested authentication key recovery"); PrintAndLogEx(NORMAL, "You have a known 4 last bytes of a key recovered with mf_nonce_brute tool."); @@ -261,6 +262,7 @@ static int usage_hf14_keybrute(void) { PrintAndLogEx(NORMAL, " hf mf keybrute 1 A 000011223344"); return 0; } +*/ static int usage_hf14_restore(void) { PrintAndLogEx(NORMAL, "Usage: hf mf restore [card memory] u k f "); PrintAndLogEx(NORMAL, "Options:"); @@ -3250,6 +3252,8 @@ static int CmdHF14AMfSniff(const char *Cmd) { return PM3_SUCCESS; } */ + +/* static int CmdHF14AMfKeyBrute(const char *Cmd) { uint8_t blockNo = 0, keytype = 0; @@ -3280,6 +3284,7 @@ static int CmdHF14AMfKeyBrute(const char *Cmd) { PrintAndLogEx(SUCCESS, "\ntime in keybrute: %.0f seconds\n", (float)t1 / 1000.0); return PM3_SUCCESS; } +*/ void printKeyTable(uint8_t sectorscnt, sector_t *e_sector) { char strA[12 + 1] = {0}; @@ -3308,6 +3313,7 @@ void printKeyTable(uint8_t sectorscnt, sector_t *e_sector) { PrintAndLogEx(NORMAL, "|---|----------------|---|----------------|---|"); } + // EMULATOR COMMANDS static int CmdHF14AMfEGet(const char *Cmd) { char c = tolower(param_getchar(Cmd, 0)); From 305c54f3cfcd9acf9e394cdd68fbc60728a59dc1 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 8 Sep 2019 17:37:14 +0200 Subject: [PATCH 0624/1854] chg: 'hf iclass rdbl' - now retries 10 ten times and uses NG --- armsrc/appmain.c | 6 ++- armsrc/iclass.c | 19 +++++--- client/cmdhficlass.c | 100 +++++++++++++++++++++++++++++-------------- 3 files changed, 85 insertions(+), 40 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index c789f6aac..e673c078a 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1237,7 +1237,11 @@ static void PacketReceived(PacketCommandNG *packet) { break; } case CMD_HF_ICLASS_READBL: { - iClass_ReadBlk(packet->oldarg[0]); + struct p { + uint8_t blockno; + } PACKED; + struct p *payload = (struct p *)packet->data.asBytes; + iClass_ReadBlk( payload->blockno ); break; } case CMD_HF_ICLASS_AUTH: { //check diff --git a/armsrc/iclass.c b/armsrc/iclass.c index b63c696d6..940d0157a 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -1720,7 +1720,7 @@ static int SendIClassAnswer(uint8_t *resp, int respLen, uint16_t delay) { static void TransmitIClassCommand(const uint8_t *cmd, int len, int *samples, int *wait) { int c = 0; - volatile uint32_t b; +// volatile uint32_t b; bool firstpart = true; uint8_t sendbyte; @@ -1758,10 +1758,12 @@ static void TransmitIClassCommand(const uint8_t *cmd, int len, int *samples, int } // Prevent rx holding register from overflowing + /* if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { b = AT91C_BASE_SSC->SSC_RHR; (void)b; } + */ } time_rdr = GetCountSspClk(); @@ -1949,12 +1951,11 @@ void setupIclassReader() { LED_A_ON(); } -bool sendCmdGetResponseWithRetries(uint8_t *command, size_t cmdsize, uint8_t *resp, uint8_t expected_size, uint8_t retries) { +bool sendCmdGetResponseWithRetries(uint8_t *command, size_t cmdsize, uint8_t *resp, uint8_t expected_size, int8_t retries) { while (retries-- > 0) { ReaderTransmitIClass(command, cmdsize); - //iceman - if received size is bigger than expected, we smash the stack here // since its called with fixed sized arrays @@ -1967,7 +1968,7 @@ bool sendCmdGetResponseWithRetries(uint8_t *command, size_t cmdsize, uint8_t *re // 0xBB is the internal debug separator byte.. if (expected_size != got_n || (resp[0] == 0xBB || resp[7] == 0xBB || resp[2] == 0xBB)) { //try again - SpinDelayUs(400); + SpinDelayUs(360); continue; } @@ -2456,10 +2457,14 @@ bool iClass_ReadBlock(uint8_t blockno, uint8_t *data, uint8_t len) { // turn off afterwards // readblock 8 + 2. only want 8. void iClass_ReadBlk(uint8_t blockno) { - uint8_t data[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - bool isOK = iClass_ReadBlock(blockno, data, sizeof(data)); - reply_mix(CMD_ACK, isOK, 0, 0, data, sizeof(data)); + struct p { + bool isOK; + uint8_t blockdata[8]; + } PACKED result; + + result.isOK = iClass_ReadBlock(blockno, result.blockdata, sizeof(result.blockdata)); switch_off(); + reply_ng(CMD_HF_ICLASS_READBL, PM3_SUCCESS, (uint8_t *)&result, sizeof(result)); } // turn off afterwards diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index a096137ee..2f8d3b56d 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -32,6 +32,7 @@ #define NUM_CSNS 9 #define ICLASS_KEYS_MAX 8 +#define ICLASS_AUTH_RETRY 10 static int CmdHelp(const char *Cmd); @@ -662,6 +663,10 @@ static int CmdHFiClassSim(const char *Cmd) { return PM3_SUCCESS; } +static int CmdHFiClassInfo(const char *Cmd) { + return PM3_SUCCESS; +} + static int CmdHFiClassReader(const char *Cmd) { char cmdp = tolower(param_getchar(Cmd, 0)); if (cmdp == 'h') return usage_hf_iclass_reader(); @@ -1563,36 +1568,62 @@ static int CmdHFiClassCloneTag(const char *Cmd) { } static int ReadBlock(uint8_t *KEY, uint8_t blockno, uint8_t keyType, bool elite, bool rawkey, bool verbose, bool auth) { - // block 0,1 should always be able to read, and block 5 on some cards. - if (auth || blockno >= 2) { - uint8_t MAC[4] = {0x00, 0x00, 0x00, 0x00}; - uint8_t div_key[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - if (!select_and_auth(KEY, MAC, div_key, (keyType == 0x18), elite, rawkey, verbose)) - return 0; + + int numberAuthRetries = ICLASS_AUTH_RETRY; + // return data. + struct p { + bool isOK; + uint8_t blockdata[8]; + } PACKED; + + struct p *result = NULL; + + do { + // block 0,1 should always be able to read, and block 5 on some cards. + if (auth || blockno >= 2) { + uint8_t MAC[4] = {0x00, 0x00, 0x00, 0x00}; + uint8_t div_key[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + if (!select_and_auth(KEY, MAC, div_key, (keyType == 0x18), elite, rawkey, verbose)) { + numberAuthRetries--; + continue; + } + } else { + uint8_t CSN[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + uint8_t CCNR[12] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + if (!select_only(CSN, CCNR, (keyType == 0x18), verbose)) { + numberAuthRetries--; + continue; + } + } + + PacketResponseNG resp; + clearCommandBuffer(); + uint8_t payload[] = { blockno }; + SendCommandNG(CMD_HF_ICLASS_READBL, payload, sizeof(payload)); + + if (WaitForResponseTimeout(CMD_HF_ICLASS_READBL, &resp, 2000) == 0) { + PrintAndLogEx(WARNING, "Command execute timeout"); + return PM3_ETIMEOUT; + } + + if ( resp.status != PM3_SUCCESS ) { + PrintAndLogEx(ERR, "failed to communicate with card"); + return PM3_EWRONGANSVER; + } + + result = (struct p*)resp.data.asBytes; + if (result->isOK) + break; + + } while (numberAuthRetries); + + if ( numberAuthRetries > 0 ) { + PrintAndLogEx(SUCCESS, "block %02X: %s\n", blockno, sprint_hex(result->blockdata, sizeof(result->blockdata))); } else { - uint8_t CSN[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - uint8_t CCNR[12] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - if (!select_only(CSN, CCNR, (keyType == 0x18), verbose)) - return 0; + PrintAndLogEx(ERR,"failed to authenticate and read block"); + return PM3_ESOFT; } - - PacketResponseNG resp; - clearCommandBuffer(); - SendCommandMIX(CMD_HF_ICLASS_READBL, blockno, 0, 0, NULL, 0); - if (!WaitForResponseTimeout(CMD_ACK, &resp, 4500)) { - PrintAndLogEx(WARNING, "Command execute timeout"); - return 0; - } - - uint8_t isOK = resp.oldarg[0] & 0xff; - if (!isOK) { - PrintAndLogEx(WARNING, "read block failed"); - return 0; - } - //data read is stored in: resp.data.asBytes[0-15] - PrintAndLogEx(NORMAL, "block %02X: %s\n", blockno, sprint_hex(resp.data.asBytes, 8)); - // should decrypt it if file is accessable. - return 1; + return PM3_SUCCESS; } static int CmdHFiClass_ReadBlock(const char *Cmd) { @@ -1613,14 +1644,16 @@ static int CmdHFiClass_ReadBlock(const char *Cmd) { case 'h': return usage_hf_iclass_readblock(); case 'b': - blockno = param_get8ex(Cmd, cmdp + 1, 06, 16); + blockno = param_get8ex(Cmd, cmdp + 1, 7, 16); cmdp += 2; break; case 'c': + PrintAndLogEx(SUCCESS, "Using " _YELLOW_("CREDIT")); keyType = 0x18; cmdp++; break; case 'e': + PrintAndLogEx(SUCCESS, "Using " _YELLOW_("elite algo")); elite = true; cmdp++; break; @@ -1632,6 +1665,7 @@ static int CmdHFiClass_ReadBlock(const char *Cmd) { } else if (dataLen == 1) { keyNbr = param_get8(Cmd, cmdp + 1); if (keyNbr < ICLASS_KEYS_MAX) { + PrintAndLogEx(SUCCESS, "Using key[%d] %s", keyNbr, sprint_hex(iClass_Key_Table[keyNbr], 8 )); memcpy(KEY, iClass_Key_Table[keyNbr], 8); } else { PrintAndLogEx(WARNING, "\nERROR: Credit KeyNbr is invalid\n"); @@ -1644,6 +1678,7 @@ static int CmdHFiClass_ReadBlock(const char *Cmd) { cmdp += 2; break; case 'r': + PrintAndLogEx(SUCCESS, "Using " _YELLOW_("raw mode")); rawkey = true; cmdp++; break; @@ -2127,7 +2162,7 @@ static int CmdHFiClassCheckKeys(const char *Cmd) { // Get CSN / UID and CCNR PrintAndLogEx(SUCCESS, "Reading tag CSN"); - for (uint8_t i = 0; i < 10 && !got_csn; i++) { + for (uint8_t i = 0; i < ICLASS_AUTH_RETRY && !got_csn; i++) { got_csn = select_only(CSN, CCNR, false, false); if (got_csn == false) PrintAndLogEx(WARNING, "one more try\n"); @@ -2611,18 +2646,19 @@ static command_t CommandTable[] = { {"dump", CmdHFiClassReader_Dump, IfPm3Iclass, "[options..] Authenticate and Dump iClass tag's AA1"}, {"eload", CmdHFiClassELoad, IfPm3Iclass, "[f ] (experimental) Load data into iClass emulator memory"}, {"encrypt", CmdHFiClassEncryptBlk, AlwaysAvailable, "[options..] Encrypt given block data"}, + {"info", CmdHFiClassInfo, AlwaysAvailable, " Tag information"}, {"list", CmdHFiClassList, AlwaysAvailable, " List iClass history"}, {"loclass", CmdHFiClass_loclass, AlwaysAvailable, "[options..] Use loclass to perform bruteforce of reader attack dump"}, {"lookup", CmdHFiClassLookUp, AlwaysAvailable, "[options..] Uses authentication trace to check for key in dictionary file"}, {"managekeys", CmdHFiClassManageKeys, AlwaysAvailable, "[options..] Manage the keys to use with iClass"}, {"permutekey", CmdHFiClassPermuteKey, IfPm3Iclass, " Permute function from 'heart of darkness' paper"}, - {"readblk", CmdHFiClass_ReadBlock, IfPm3Iclass, "[options..] Read iClass block"}, + {"rdbl", CmdHFiClass_ReadBlock, IfPm3Iclass, "[options..] Read iClass block"}, {"reader", CmdHFiClassReader, IfPm3Iclass, " Act like an iClass reader"}, {"readtagfile", CmdHFiClassReadTagFile, AlwaysAvailable, "[options..] Display Content from tagfile"}, {"replay", CmdHFiClassReader_Replay, IfPm3Iclass, " Read an iClass tag via Replay Attack"}, {"sim", CmdHFiClassSim, IfPm3Iclass, "[options..] Simulate iClass tag"}, {"sniff", CmdHFiClassSniff, IfPm3Iclass, " Eavesdrop iClass communication"}, - {"writeblk", CmdHFiClass_WriteBlock, IfPm3Iclass, "[options..] Write iClass block"}, + {"wrbl", CmdHFiClass_WriteBlock, IfPm3Iclass, "[options..] Write iClass block"}, {NULL, NULL, NULL, NULL} }; From d8217a13d9ab9dc14428b8f4ede48ebbc4e6e70f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 8 Sep 2019 21:21:30 +0200 Subject: [PATCH 0625/1854] chg: 'hf iclass rdbl' 'hf iclass wrbl' - both commands now tries tens times. Both honor verbose param, both has gotten some love with regards to timing on device side, and they also turn off the field more consistent. --- armsrc/appmain.c | 18 +++++- armsrc/iclass.c | 61 ++++++++------------ client/cmdhficlass.c | 131 +++++++++++++++++++++++++++++++------------ 3 files changed, 133 insertions(+), 77 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index e673c078a..cb5dbe8a2 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1229,22 +1229,36 @@ static void PacketReceived(PacketCommandNG *packet) { break; } case CMD_HF_ICLASS_WRITEBL: { - iClass_WriteBlock(packet->oldarg[0], packet->data.asBytes); + struct p { + uint8_t blockno; + uint8_t data[12]; + } PACKED; + struct p *payload = (struct p *)packet->data.asBytes; + iClass_WriteBlock(payload->blockno, payload->data); break; } + // iceman2019, unused? case CMD_HF_ICLASS_READCHECK: { // auth step 1 iClass_ReadCheck(packet->oldarg[0], packet->oldarg[1]); break; } case CMD_HF_ICLASS_READBL: { +/* struct p { uint8_t blockno; } PACKED; struct p *payload = (struct p *)packet->data.asBytes; - iClass_ReadBlk( payload->blockno ); + */ + iClass_ReadBlk( packet->data.asBytes[0] ); break; } case CMD_HF_ICLASS_AUTH: { //check +/* + struct p { + uint8_t mac[4]; + } PACKED; + struct p *payload = (struct p *)packet->data.asBytes; +*/ iClass_Authentication(packet->data.asBytes); break; } diff --git a/armsrc/iclass.c b/armsrc/iclass.c index 940d0157a..fa90f0881 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -56,10 +56,8 @@ #include "ticks.h" static int g_wait = 300; -static int timeout = 2900; +static int timeout = 5000; static uint32_t time_rdr = 0; -static uint32_t time_delta = 0; -static uint32_t time_delta_wait = 0; static uint32_t time_response = 0; static int SendIClassAnswer(uint8_t *resp, int respLen, uint16_t delay); @@ -1854,12 +1852,9 @@ static int GetIClassAnswer(uint8_t *receivedResponse, int maxLen, int *samples, // only, since we are receiving, not transmitting). FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_LISTEN); - time_delta = GetCountSspClk() - time_rdr; - SpinDelayUs(g_wait); //310 Tout= 330us (iso15603-2) (330/21.3) take consideration for clock increments. - time_delta_wait = GetCountSspClk() - time_rdr - time_delta; - uint32_t foo = GetCountSspClk(); + // clear RXRDY: uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; (void)b; @@ -1877,21 +1872,15 @@ static int GetIClassAnswer(uint8_t *receivedResponse, int maxLen, int *samples, } // keep tx buffer in a defined state anyway. - /* - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { - AT91C_BASE_SSC->SSC_THR = 0x00; - } - */ + if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { + AT91C_BASE_SSC->SSC_THR = 0x00; + } + // Wait for byte be become available in rx holding register if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { - if (GetCountSspClk() - foo > timeout) return false; -// if (c >= timeout) return false; - c++; - b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - skip = !skip; if (skip) continue; @@ -1902,6 +1891,8 @@ static int GetIClassAnswer(uint8_t *receivedResponse, int maxLen, int *samples, time_response = GetCountSspClk() - foo; return true; } + + if (GetCountSspClk() - foo > timeout) return false; } } @@ -1959,12 +1950,15 @@ bool sendCmdGetResponseWithRetries(uint8_t *command, size_t cmdsize, uint8_t *re //iceman - if received size is bigger than expected, we smash the stack here // since its called with fixed sized arrays - // update/write commadn takes 4ms to 15ms before responding + // update/write command takes 4ms to 15ms before responding + int old_wait = g_wait; if (command[0] == ICLASS_CMD_UPDATE) - g_wait = 15000; + g_wait = 3900; uint8_t got_n = ReaderReceiveIClass(resp); + g_wait = old_wait; + // 0xBB is the internal debug separator byte.. if (expected_size != got_n || (resp[0] == 0xBB || resp[7] == 0xBB || resp[2] == 0xBB)) { //try again @@ -2337,8 +2331,8 @@ void iClass_Authentication(uint8_t *mac) { //memcpy(check+5, mac, 4); // 6 retries - bool isOK = sendCmdGetResponseWithRetries(check, sizeof(check), resp, 4, 6); - reply_mix(CMD_ACK, isOK, 0, 0, 0, 0); + uint8_t isOK = sendCmdGetResponseWithRetries(check, sizeof(check), resp, 4, 6); + reply_ng(CMD_HF_ICLASS_AUTH, PM3_SUCCESS, (uint8_t*)&isOK ,sizeof(uint8_t)); } typedef struct iclass_premac { @@ -2397,6 +2391,8 @@ void iClass_Authentication_fast(uint64_t arg0, uint64_t arg1, uint8_t *datain) { }; // since handshakeIclassTag_ext call sends s readcheck, we start with sending first response. + checked = 0; + // Keychunk loop for (i = 0; i < keyCount; i++) { @@ -2496,39 +2492,26 @@ void iClass_Dump(uint8_t blockno, uint8_t numblks) { } memcpy(dataout + (blkCnt * 8), blockdata, 8); } + + switch_off(); //return pointer to dump memory in arg3 reply_mix(CMD_ACK, isOK, blkCnt, BigBuf_max_traceLen(), 0, 0); - switch_off(); BigBuf_free(); } bool iClass_WriteBlock_ext(uint8_t blockno, uint8_t *data) { - uint8_t resp[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; uint8_t write[] = { ICLASS_CMD_UPDATE, blockno, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; memcpy(write + 2, data, 12); // data + mac AddCrc(write + 1, 13); - - bool isOK = sendCmdGetResponseWithRetries(write, sizeof(write), resp, sizeof(resp), 5); - if (isOK) { //if reader responded correctly - - //if response is not equal to write values - if (memcmp(write + 2, resp, 8)) { - - //if not programming key areas (note key blocks don't get programmed with actual key data it is xor data) - if (blockno != 3 && blockno != 4) { - isOK = sendCmdGetResponseWithRetries(write, sizeof(write), resp, sizeof(resp), 5); - } - } - } - return isOK; + return sendCmdGetResponseWithRetries(write, sizeof(write), resp, sizeof(resp), 5); } // turn off afterwards void iClass_WriteBlock(uint8_t blockno, uint8_t *data) { - bool isOK = iClass_WriteBlock_ext(blockno, data); - reply_mix(CMD_ACK, isOK, 0, 0, 0, 0); + uint8_t isOK = iClass_WriteBlock_ext(blockno, data); switch_off(); + reply_ng(CMD_HF_ICLASS_WRITEBL, PM3_SUCCESS, (uint8_t*)&isOK, sizeof(uint8_t)); } // turn off afterwards diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 2f8d3b56d..5ac3a8925 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -1000,7 +1000,7 @@ static bool select_only(uint8_t *CSN, uint8_t *CCNR, bool use_credit_key, bool v clearCommandBuffer(); SendCommandMIX(CMD_HF_ICLASS_READER, flags, 0, 0, NULL, 0); - if (!WaitForResponseTimeout(CMD_ACK, &resp, 4000)) { + if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { PrintAndLogEx(WARNING, "command execute timeout"); return false; } @@ -1019,7 +1019,9 @@ static bool select_only(uint8_t *CSN, uint8_t *CCNR, bool use_credit_key, bool v } if (isOK <= 1) { - PrintAndLogEx(FAILED, "failed to obtain CC! Tag-select is aborting... (%d)", isOK); + if ( verbose ) + PrintAndLogEx(FAILED, "failed to obtain CC! Tag-select is aborting... (%d)", isOK); + return false; } return true; @@ -1042,18 +1044,27 @@ static bool select_and_auth(uint8_t *KEY, uint8_t *MAC, uint8_t *div_key, bool u if (verbose) PrintAndLogEx(SUCCESS, "authing with %s: %s", rawkey ? "raw key" : "diversified key", sprint_hex(div_key, 8)); doMAC(CCNR, div_key, MAC); + PacketResponseNG resp; clearCommandBuffer(); - SendCommandOLD(CMD_HF_ICLASS_AUTH, 0, 0, 0, MAC, 4); - if (!WaitForResponseTimeout(CMD_ACK, &resp, 4000)) { - if (verbose) PrintAndLogEx(FAILED, "auth command execute timeout"); + + SendCommandNG(CMD_HF_ICLASS_AUTH, MAC, 4); + if (WaitForResponseTimeout(CMD_HF_ICLASS_AUTH, &resp, 2000) == 0) { + if (verbose) PrintAndLogEx(WARNING, "Command execute timeout"); return false; } - uint8_t isOK = resp.oldarg[0] & 0xFF; - if (!isOK) { + + if ( resp.status != PM3_SUCCESS ) { + if (verbose) PrintAndLogEx(ERR, "failed to communicate with card"); + return false; + } + + uint8_t isOK = resp.data.asBytes[0]; + if (isOK == 0) { if (verbose) PrintAndLogEx(FAILED, "authentication error"); return false; } + return true; } @@ -1311,30 +1322,60 @@ static int CmdHFiClassReader_Dump(const char *Cmd) { } static int WriteBlock(uint8_t blockno, uint8_t *bldata, uint8_t *KEY, bool use_credit_key, bool elite, bool rawkey, bool verbose) { - uint8_t MAC[4] = {0x00, 0x00, 0x00, 0x00}; - uint8_t div_key[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - if (!select_and_auth(KEY, MAC, div_key, use_credit_key, elite, rawkey, verbose)) - return 0; - PacketResponseNG resp; + int numberAuthRetries = ICLASS_AUTH_RETRY; + do { + + uint8_t MAC[4] = {0x00, 0x00, 0x00, 0x00}; + uint8_t div_key[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + if (!select_and_auth(KEY, MAC, div_key, use_credit_key, elite, rawkey, verbose)) { + numberAuthRetries--; + DropField(); + continue; + } - Calc_wb_mac(blockno, bldata, div_key, MAC); - uint8_t data[12]; - memcpy(data, bldata, 8); - memcpy(data + 8, MAC, 4); + Calc_wb_mac(blockno, bldata, div_key, MAC); - clearCommandBuffer(); - SendCommandOLD(CMD_HF_ICLASS_WRITEBL, blockno, 0, 0, data, sizeof(data)); - if (!WaitForResponseTimeout(CMD_ACK, &resp, 4500)) { - if (verbose) PrintAndLogEx(WARNING, "Write Command execute timeout"); - return 0; + struct p { + uint8_t blockno; + uint8_t data[12]; + } PACKED payload; + payload.blockno = blockno; + + memcpy(payload.data, bldata, 8); + memcpy(payload.data + 8, MAC, 4); + + clearCommandBuffer(); + SendCommandNG(CMD_HF_ICLASS_WRITEBL, (uint8_t*)&payload, sizeof(payload)); + PacketResponseNG resp; + + if (WaitForResponseTimeout(CMD_HF_ICLASS_WRITEBL, &resp, 4000) == 0) { + if (verbose) PrintAndLogEx(WARNING, "Command execute timeout"); + DropField(); + return PM3_ETIMEOUT; + } + + if ( resp.status != PM3_SUCCESS ) { + if (verbose) PrintAndLogEx(ERR, "failed to communicate with card"); + DropField(); + return PM3_EWRONGANSVER; + } + + if (resp.data.asBytes[0] == 1) + break; + + } while (numberAuthRetries); + + DropField(); + + if ( numberAuthRetries > 0 ) { + PrintAndLogEx(SUCCESS, "Write block %02X successful\n", blockno); + } else { + PrintAndLogEx(ERR,"failed to authenticate and write block"); + return PM3_ESOFT; } - uint8_t isOK = resp.oldarg[0] & 0xff; - if (isOK) - PrintAndLogEx(SUCCESS, "Write block successful"); - else - PrintAndLogEx(WARNING, "Write block failed"); - return isOK; + + return PM3_SUCCESS; } static int CmdHFiClass_WriteBlock(const char *Cmd) { @@ -1344,6 +1385,7 @@ static int CmdHFiClass_WriteBlock(const char *Cmd) { uint8_t keyNbr = 0; uint8_t dataLen = 0; char tempStr[50] = {0}; + bool got_blockno = false; bool use_credit_key = false; bool elite = false; bool rawkey = false; @@ -1355,10 +1397,12 @@ static int CmdHFiClass_WriteBlock(const char *Cmd) { case 'h': return usage_hf_iclass_writeblock(); case 'b': - blockno = param_get8ex(Cmd, cmdp + 1, 06, 16); + blockno = param_get8ex(Cmd, cmdp + 1, 07, 16); + got_blockno = true; cmdp += 2; break; case 'c': + PrintAndLogEx(SUCCESS, "Using " _YELLOW_("CREDIT")); use_credit_key = true; cmdp++; break; @@ -1370,6 +1414,7 @@ static int CmdHFiClass_WriteBlock(const char *Cmd) { cmdp += 2; break; case 'e': + PrintAndLogEx(SUCCESS, "Using " _YELLOW_("elite algo")); elite = true; cmdp++; break; @@ -1380,6 +1425,7 @@ static int CmdHFiClass_WriteBlock(const char *Cmd) { } else if (dataLen == 1) { keyNbr = param_get8(Cmd, cmdp + 1); if (keyNbr < ICLASS_KEYS_MAX) { + PrintAndLogEx(SUCCESS, "Using key[%d] %s", keyNbr, sprint_hex(iClass_Key_Table[keyNbr], 8 )); memcpy(KEY, iClass_Key_Table[keyNbr], 8); } else { PrintAndLogEx(WARNING, "\nERROR: Credit KeyNbr is invalid\n"); @@ -1392,6 +1438,7 @@ static int CmdHFiClass_WriteBlock(const char *Cmd) { cmdp += 2; break; case 'r': + PrintAndLogEx(SUCCESS, "Using " _YELLOW_("raw mode")); rawkey = true; cmdp++; break; @@ -1405,11 +1452,12 @@ static int CmdHFiClass_WriteBlock(const char *Cmd) { break; } } + if ( got_blockno == false) + errors = true; + if (errors || cmdp < 6) return usage_hf_iclass_writeblock(); - int ans = WriteBlock(blockno, bldata, KEY, use_credit_key, elite, rawkey, verbose); - DropField(); - return ans; + return WriteBlock(blockno, bldata, KEY, use_credit_key, elite, rawkey, verbose); } static int CmdHFiClassCloneTag(const char *Cmd) { @@ -1585,6 +1633,7 @@ static int ReadBlock(uint8_t *KEY, uint8_t blockno, uint8_t keyType, bool elite, uint8_t div_key[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; if (!select_and_auth(KEY, MAC, div_key, (keyType == 0x18), elite, rawkey, verbose)) { numberAuthRetries--; + DropField(); continue; } } else { @@ -1592,22 +1641,24 @@ static int ReadBlock(uint8_t *KEY, uint8_t blockno, uint8_t keyType, bool elite, uint8_t CCNR[12] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; if (!select_only(CSN, CCNR, (keyType == 0x18), verbose)) { numberAuthRetries--; + DropField(); continue; } } PacketResponseNG resp; - clearCommandBuffer(); - uint8_t payload[] = { blockno }; - SendCommandNG(CMD_HF_ICLASS_READBL, payload, sizeof(payload)); + clearCommandBuffer(); + SendCommandNG(CMD_HF_ICLASS_READBL, (uint8_t*)&blockno, sizeof(uint8_t)); if (WaitForResponseTimeout(CMD_HF_ICLASS_READBL, &resp, 2000) == 0) { - PrintAndLogEx(WARNING, "Command execute timeout"); + if (verbose) PrintAndLogEx(WARNING, "Command execute timeout"); + DropField(); return PM3_ETIMEOUT; } if ( resp.status != PM3_SUCCESS ) { - PrintAndLogEx(ERR, "failed to communicate with card"); + if (verbose) PrintAndLogEx(ERR, "failed to communicate with card"); + DropField(); return PM3_EWRONGANSVER; } @@ -1617,10 +1668,13 @@ static int ReadBlock(uint8_t *KEY, uint8_t blockno, uint8_t keyType, bool elite, } while (numberAuthRetries); + DropField(); + if ( numberAuthRetries > 0 ) { PrintAndLogEx(SUCCESS, "block %02X: %s\n", blockno, sprint_hex(result->blockdata, sizeof(result->blockdata))); } else { PrintAndLogEx(ERR,"failed to authenticate and read block"); + return PM3_ESOFT; } return PM3_SUCCESS; @@ -1633,6 +1687,7 @@ static int CmdHFiClass_ReadBlock(const char *Cmd) { uint8_t keyNbr = 0; uint8_t dataLen = 0; char tempStr[50] = {0}; + bool got_blockno = false; bool elite = false; bool rawkey = false; bool errors = false; @@ -1645,6 +1700,7 @@ static int CmdHFiClass_ReadBlock(const char *Cmd) { return usage_hf_iclass_readblock(); case 'b': blockno = param_get8ex(Cmd, cmdp + 1, 7, 16); + got_blockno = true; cmdp += 2; break; case 'c': @@ -1692,6 +1748,9 @@ static int CmdHFiClass_ReadBlock(const char *Cmd) { break; } } + if ( got_blockno == false) + errors = true; + if (errors || cmdp < 4) return usage_hf_iclass_readblock(); if (!auth) From 9a2a0116e41d48e5fd5bb87ba55c041748a295bb Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 8 Sep 2019 23:19:06 +0200 Subject: [PATCH 0626/1854] fix: 'hf iclass clone' - last block write fails, see (https://github.com/RfidResearchGroup/proxmark3/issues/183) chg: 'hf iclass clone' - now tries ten times, behavies better, obey verbose nicer, drop field constant. Uses NG. chg: 'hf iclass dump' - now tries ten times, in general nice outputs.. --- armsrc/appmain.c | 8 +- armsrc/iclass.c | 24 +++--- client/cmdhficlass.c | 200 +++++++++++++++++++++++++++---------------- 3 files changed, 145 insertions(+), 87 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index cb5dbe8a2..990ac1c56 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1271,7 +1271,13 @@ static void PacketReceived(PacketCommandNG *packet) { break; } case CMD_HF_ICLASS_CLONE: { - iClass_Clone(packet->oldarg[0], packet->oldarg[1], packet->data.asBytes); + struct p { + uint8_t startblock; + uint8_t endblock; + uint8_t data[]; + } PACKED; + struct p *payload = (struct p *)packet->data.asBytes; + iClass_Clone(payload->startblock, payload->endblock, payload->data); break; } #endif diff --git a/armsrc/iclass.c b/armsrc/iclass.c index fa90f0881..c87bade4b 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -2520,23 +2520,19 @@ void iClass_Clone(uint8_t startblock, uint8_t endblock, uint8_t *data) { int total_block = (endblock - startblock) + 1; for (i = 0; i < total_block; i++) { // block number - if (iClass_WriteBlock_ext(i + startblock, data + (i * 12))) { - Dbprintf("Write block [%02x] successful", i + startblock); + if (iClass_WriteBlock_ext(startblock + i, data + (i * 12))) { + Dbprintf("Write block [%02x] successful", startblock + i); written++; } else { - if (iClass_WriteBlock_ext(i + startblock, data + (i * 12))) { - Dbprintf("Write block [%02x] successful", i + startblock); - written++; - } else { - Dbprintf("Write block [%02x] failed", i + startblock); - } + Dbprintf("Write block [%02x] failed", startblock + i); } } - if (written == total_block) - DbpString("Clone complete"); - else - DbpString("Clone incomplete"); - - reply_mix(CMD_ACK, 1, 0, 0, 0, 0); + switch_off(); + + uint8_t isOK = 0; + if (written == total_block) + isOK = 1; + + reply_ng(CMD_HF_ICLASS_CLONE, PM3_SUCCESS, (uint8_t *)&isOK, sizeof(uint8_t)); } diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 5ac3a8925..4f9a34113 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -1118,6 +1118,7 @@ static int CmdHFiClassReader_Dump(const char *Cmd) { cmdp += 2; break; case 'e': + PrintAndLogEx(SUCCESS, "Using " _YELLOW_("elite algo")); elite = true; cmdp++; break; @@ -1149,6 +1150,7 @@ static int CmdHFiClassReader_Dump(const char *Cmd) { cmdp += 2; break; case 'r': + PrintAndLogEx(SUCCESS, "Using " _YELLOW_("raw mode")); rawkey = true; cmdp++; break; @@ -1180,7 +1182,7 @@ static int CmdHFiClassReader_Dump(const char *Cmd) { if (!WaitForResponseTimeout(CMD_ACK, &resp, 4500)) { PrintAndLogEx(WARNING, "command execute timeout"); DropField(); - return 0; + return PM3_ESOFT; } DropField(); @@ -1189,7 +1191,8 @@ static int CmdHFiClassReader_Dump(const char *Cmd) { if (readStatus == 0) { PrintAndLogEx(FAILED, "no tag found"); - return 0; + DropField(); + return PM3_ESOFT; } if (readStatus & (FLAG_ICLASS_READER_CSN | FLAG_ICLASS_READER_CONF | FLAG_ICLASS_READER_CC)) { @@ -1202,14 +1205,16 @@ static int CmdHFiClassReader_Dump(const char *Cmd) { } // authenticate debit key and get div_key - later store in dump block 3 - if (!select_and_auth(KEY, MAC, div_key, use_credit_key, elite, rawkey, verbose)) { - //try twice - for some reason it sometimes fails the first time... - PrintAndLogEx(SUCCESS, "retry to select card"); - if (!select_and_auth(KEY, MAC, div_key, use_credit_key, elite, rawkey, verbose)) { - PrintAndLogEx(WARNING, "failed authenticating with debit key"); - DropField(); - return 0; - } + int numberAuthRetries = ICLASS_AUTH_RETRY; + do { + if (select_and_auth(KEY, MAC, div_key, use_credit_key, elite, rawkey, verbose)) + break; + } while (numberAuthRetries--); + + if ( numberAuthRetries <= 0) { + PrintAndLogEx(WARNING, "failed authenticating with debit key"); + DropField(); + return PM3_ESOFT; } // begin dump @@ -1233,7 +1238,7 @@ static int CmdHFiClassReader_Dump(const char *Cmd) { uint8_t isOK = resp.oldarg[0] & 0xff; if (!isOK && !blocksRead) { PrintAndLogEx(WARNING, "read block failed"); - return 0; + return PM3_ESOFt; } uint32_t startindex = resp.oldarg[2]; @@ -1245,7 +1250,7 @@ static int CmdHFiClassReader_Dump(const char *Cmd) { // response ok - now get bigbuf content of the dump if (!GetFromDevice(BIG_BUF, tag_data + (blockno * 8), blocksRead * 8, startindex, NULL, 0, NULL, 2500, false)) { PrintAndLogEx(WARNING, "command execution time out"); - return 0; + return PM3_ETIMEOUT; } size_t gotBytes = blocksRead * 8 + blockno * 8; @@ -1254,16 +1259,22 @@ static int CmdHFiClassReader_Dump(const char *Cmd) { if (have_credit_key) { //turn off hf field before authenticating with different key DropField(); + memset(MAC, 0, 4); + // AA2 authenticate credit key and git c_div_key - later store in dump block 4 - if (!select_and_auth(CreditKEY, MAC, c_div_key, true, elite, rawkey, verbose)) { - //try twice - for some reason it sometimes fails the first time... - if (!select_and_auth(CreditKEY, MAC, c_div_key, true, elite, rawkey, verbose)) { - PrintAndLogEx(WARNING, "failed authenticating with credit key"); - DropField(); - return 0; - } + numberAuthRetries = ICLASS_AUTH_RETRY; + do { + if (select_and_auth(CreditKEY, MAC, c_div_key, true, elite, rawkey, verbose)) + break; + } while (numberAuthRetries--); + + if ( numberAuthRetries <= 0) { + PrintAndLogEx(WARNING, "failed authenticating with credit key"); + DropField(); + return PM3_ESOFT; } + // do we still need to read more block? (aa2 enabled?) if (maxBlk > blockno + numblks + 1) { // setup dump and start @@ -1271,13 +1282,13 @@ static int CmdHFiClassReader_Dump(const char *Cmd) { SendCommandMIX(CMD_HF_ICLASS_DUMP, blockno + blocksRead, maxBlk - (blockno + blocksRead), 0, NULL, 0); if (!WaitForResponseTimeout(CMD_ACK, &resp, 4500)) { PrintAndLogEx(WARNING, "command execute timeout 2"); - return 0; + return PM3_ETIMEOUT; } isOK = resp.oldarg[0] & 0xff; blocksRead = resp.oldarg[1]; if (!isOK && !blocksRead) { PrintAndLogEx(WARNING, "read block failed 2"); - return 0; + return PM3_ESOFT; } startindex = resp.oldarg[2]; @@ -1288,7 +1299,7 @@ static int CmdHFiClassReader_Dump(const char *Cmd) { // get dumped data from bigbuf if (!GetFromDevice(BIG_BUF, tag_data + gotBytes, blocksRead * 8, startindex, NULL, 0, NULL, 2500, false)) { PrintAndLogEx(WARNING, "command execution time out"); - return 0; + return PM3_ETIMEOUT; } gotBytes += blocksRead * 8; @@ -1298,16 +1309,20 @@ static int CmdHFiClassReader_Dump(const char *Cmd) { DropField(); // add diversified keys to dump - if (have_debit_key) memcpy(tag_data + (3 * 8), div_key, 8); - if (have_credit_key) memcpy(tag_data + (4 * 8), c_div_key, 8); + if (have_debit_key) + memcpy(tag_data + (3 * 8), div_key, 8); + + if (have_credit_key) + memcpy(tag_data + (4 * 8), c_div_key, 8); + // print the dump - PrintAndLogEx(NORMAL, "------+--+-------------------------+\n"); - PrintAndLogEx(NORMAL, "CSN |00| %s|\n", sprint_hex(tag_data, 8)); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "------+--+-------------------------+"); + PrintAndLogEx(NORMAL, "CSN |00| %s|", sprint_hex(tag_data, 8)); printIclassDumpContents(tag_data, 1, (gotBytes / 8), gotBytes); if (filename[0] == 0) { - //Use the first block (CSN) for filename strcat(filename, "hf-iclass-"); FillFileNameByUID(filename, tag_data, "-data", 8); @@ -1469,6 +1484,7 @@ static int CmdHFiClassCloneTag(const char *Cmd) { uint8_t startblock = 0; uint8_t endblock = 0; uint8_t dataLen = 0; + bool got_startblk = false, got_endblk = false; bool use_credit_key = false; bool elite = false; bool rawkey = false; @@ -1480,17 +1496,17 @@ static int CmdHFiClassCloneTag(const char *Cmd) { case 'h': return usage_hf_iclass_clone(); case 'b': - if (param_gethex(Cmd, cmdp + 1, &startblock, 2)) { - PrintAndLogEx(WARNING, "start block No must include 2 HEX symbols\n"); - errors = true; - } + startblock = param_get8ex(Cmd, cmdp + 1, 07, 16); + got_startblk = true; cmdp += 2; break; case 'c': + PrintAndLogEx(SUCCESS, "Using " _YELLOW_("CREDIT")); use_credit_key = true; cmdp++; break; case 'e': + PrintAndLogEx(SUCCESS, "Using " _YELLOW_("elite algo")); elite = true; cmdp++; break; @@ -1509,6 +1525,7 @@ static int CmdHFiClassCloneTag(const char *Cmd) { } else if (dataLen == 1) { keyNbr = param_get8(Cmd, cmdp + 1); if (keyNbr < ICLASS_KEYS_MAX) { + PrintAndLogEx(SUCCESS, "Using key[%d] %s", keyNbr, sprint_hex(iClass_Key_Table[keyNbr], 8 )); memcpy(KEY, iClass_Key_Table[keyNbr], 8); } else { PrintAndLogEx(WARNING, "\nERROR: Credit KeyNbr is invalid\n"); @@ -1521,13 +1538,12 @@ static int CmdHFiClassCloneTag(const char *Cmd) { cmdp += 2; break; case 'l': - if (param_gethex(Cmd, cmdp + 1, &endblock, 2)) { - PrintAndLogEx(WARNING, "start Block No must include 2 HEX symbols\n"); - errors = true; - } + endblock = param_get8ex(Cmd, cmdp + 1, 07, 16); + got_endblk = true; cmdp += 2; break; case 'r': + PrintAndLogEx(SUCCESS, "Using " _YELLOW_("raw mode")); rawkey = true; cmdp++; break; @@ -1541,53 +1557,66 @@ static int CmdHFiClassCloneTag(const char *Cmd) { break; } } + if ( got_endblk == false || got_startblk == false) + errors = true; if (errors || cmdp < 8) return usage_hf_iclass_clone(); - FILE *f; - - iclass_block_t tag_data[PM3_CMD_DATA_SIZE / 12]; - - if ((endblock - startblock + 1) * 12 > PM3_CMD_DATA_SIZE) { - PrintAndLogEx(NORMAL, "Trying to write too many blocks at once. Max: %d", PM3_CMD_DATA_SIZE / 8); + if (startblock < 5) { + PrintAndLogEx(WARNING, "you cannot write key blocks this way. yet... make your start block > 4"); + return PM3_EINVARG; } + + int total_bytes = (((endblock - startblock) + 1) * 12); + + if (total_bytes > PM3_CMD_DATA_SIZE - 2) { + PrintAndLogEx(NORMAL, "Trying to write too many blocks at once. Max: %d", PM3_CMD_DATA_SIZE / 8); + return PM3_EINVARG; + } + // file handling and reading - f = fopen(filename, "rb"); + FILE *f = fopen(filename, "rb"); if (!f) { PrintAndLogEx(FAILED, "File: " _YELLOW_("%s") ": not found or locked.", filename); return PM3_EFILE; } - if (startblock < 5) { - PrintAndLogEx(WARNING, "you cannot write key blocks this way. yet... make your start block > 4"); - fclose(f); - return 0; - } - // now read data from the file from block 6 --- 19 - // ok we will use this struct [data 8 bytes][MAC 4 bytes] for each block calculate all mac number for each data - // then copy to usbcommand->asbytes; the max is 32 - 6 = 24 block 12 bytes each block 288 bytes then we can only accept to clone 21 blocks at the time, - // else we have to create a share memory + iclass_block_t tag_data[PM3_CMD_DATA_SIZE / 12]; + + // read data from file from block 6 --- 19 + // we will use this struct [data 8 bytes][MAC 4 bytes] for each block calculate all mac number for each data + // then copy to usbcommand->asbytes; + // max is 32 - 6 = 28 block. 28 x 12 bytes gives 336 bytes int i; fseek(f, startblock * 8, SEEK_SET); size_t bytes_read = fread(tag_data, sizeof(iclass_block_t), endblock - startblock + 1, f); + fclose(f); + if (bytes_read == 0) { PrintAndLogEx(ERR, "file reading error."); - fclose(f); - return 2; + return PM3_EFILE; } - fclose(f); - uint8_t MAC[4] = {0x00, 0x00, 0x00, 0x00}; uint8_t div_key[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - - if (!select_and_auth(KEY, MAC, div_key, use_credit_key, elite, rawkey, verbose)) { - return 0; + + int numberAuthRetries = ICLASS_AUTH_RETRY; + do { + if (select_and_auth(KEY, MAC, div_key, use_credit_key, elite, rawkey, verbose)) + break; + } while (numberAuthRetries--); + + if ( numberAuthRetries <= 0 ) { + PrintAndLogEx(ERR, "failed to authenticate"); + DropField(); + return PM3_ESOFT; } - uint8_t data[(endblock - startblock) * 12]; + uint8_t data[total_bytes]; + // calculate all mac for every the block we will write for (i = startblock; i <= endblock; i++) { + Calc_wb_mac(i, tag_data[i - startblock].d, div_key, MAC); // usb command d start pointer = d + (i - 6) * 12 // memcpy(pointer,tag_data[i - 6],8) 8 bytes @@ -1597,22 +1626,49 @@ static int CmdHFiClassCloneTag(const char *Cmd) { memcpy(ptr, &(tag_data[i - startblock].d[0]), 8); memcpy(ptr + 8, MAC, 4); } - uint8_t p[12]; - for (i = 0; i <= endblock - startblock; i++) { - memcpy(p, data + (i * 12), 12); - PrintAndLogEx(NORMAL, "Block |%02x|", i + startblock); - PrintAndLogEx(NORMAL, " %02x%02x%02x%02x%02x%02x%02x%02x |", p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); - PrintAndLogEx(NORMAL, " MAC |%02x%02x%02x%02x|\n", p[8], p[9], p[10], p[11]); + + if ( verbose ) { + PrintAndLogEx(NORMAL,"------+--------------------------+-------------"); + PrintAndLogEx(NORMAL,"block | data | mac"); + PrintAndLogEx(NORMAL,"------+--------------------------+-------------"); + uint8_t p[12]; + for (i = 0; i <= endblock - startblock; i++) { + memcpy(p, data + (i * 12), 12); + char *s = calloc(70, sizeof(uint8_t)); + sprintf(s, "| %s ", sprint_hex(p, 8)); + sprintf(s + strlen(s), "| %s", sprint_hex(p + 8, 4)); + PrintAndLogEx(NORMAL, " %02X %s", i + startblock, s ); + free(s); + } } + struct p { + uint8_t startblock; + uint8_t endblock; + uint8_t data[PM3_CMD_DATA_SIZE - 2]; + } PACKED payload; + + payload.startblock = startblock; + payload.endblock = endblock; + memcpy(payload.data, data, total_bytes); + PacketResponseNG resp; clearCommandBuffer(); - SendCommandOLD(CMD_HF_ICLASS_CLONE, startblock, endblock, 0, data, (endblock - startblock) * 12); - if (!WaitForResponseTimeout(CMD_ACK, &resp, 4500)) { + SendCommandNG(CMD_HF_ICLASS_CLONE, (uint8_t*)&payload, total_bytes + 2 ); + + if (WaitForResponseTimeout(CMD_HF_ICLASS_CLONE, &resp, 4500) == 0) { PrintAndLogEx(WARNING, "command execute timeout"); - return 0; + DropField(); + return PM3_ETIMEOUT; } - return PM3_SUCCESS; + + if (resp.status == PM3_SUCCESS) { + if ( resp.data.asBytes[0] == 1 ) + PrintAndLogEx(SUCCESS, "Clone successful"); + else + PrintAndLogEx(WARNING, "Clone failed"); + } + return resp.status; } static int ReadBlock(uint8_t *KEY, uint8_t blockno, uint8_t keyType, bool elite, bool rawkey, bool verbose, bool auth) { @@ -1809,13 +1865,13 @@ void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t e //PrintAndLog ("startblock: %d, endblock: %d, filesize: %d, maxmemcount: %d, filemaxblock: %d",startblock, endblock,filesize, maxmemcount, filemaxblock); int i = startblock; - PrintAndLogEx(NORMAL, "------+--+-------------------------+\n"); + PrintAndLogEx(NORMAL, "------+--+-------------------------+"); while (i <= endblock) { uint8_t *blk = iclass_dump + (i * 8); - PrintAndLogEx(NORMAL, " |%02X| %s\n", i, sprint_hex_ascii(blk, 8)); + PrintAndLogEx(NORMAL, " |%02X| %s", i, sprint_hex_ascii(blk, 8)); i++; } - PrintAndLogEx(NORMAL, "------+--+-------------------------+\n"); + PrintAndLogEx(NORMAL, "------+--+-------------------------+"); } static int CmdHFiClassReadTagFile(const char *Cmd) { From ca606bb2117bc952ffdb2a7fa4c0610717ebb1e6 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 8 Sep 2019 23:23:06 +0200 Subject: [PATCH 0627/1854] stupid... --- client/cmdhficlass.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 4f9a34113..c24853dcb 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -1238,7 +1238,7 @@ static int CmdHFiClassReader_Dump(const char *Cmd) { uint8_t isOK = resp.oldarg[0] & 0xff; if (!isOK && !blocksRead) { PrintAndLogEx(WARNING, "read block failed"); - return PM3_ESOFt; + return PM3_ESOFT; } uint32_t startindex = resp.oldarg[2]; From fe0fe0d65b887bf5179f9f10dc70e7ff0422006a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 8 Sep 2019 23:28:45 +0200 Subject: [PATCH 0628/1854] textual --- CHANGELOG.md | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c4e1fe1fe..5cb0e5c1d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,12 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Chg `hf iclass clone\dump\rdbl\wrbl` - now uses NG (@iceman1001) + - Fix `hf iclass clone` - last block always fails (@iceman1001) + - Chg `hf iclass clone` - retries ten times, less output (honor verbose) (@iceman1001) + - Chg `hf iclass dump` - retries ten times, less output (honor verbose) (@iceman1001) + - Rename `hf iclass writeblk` -> `hf iclass wrbl` to match hf mf wrbl (@iceman1001) + - Rename `hf iclass readblk` -> `hf iclass rdbl` to match hf mf rdbl (@iceman1001) - Add cmdscript example and show usage with shebang (@doegox) - Add instructions for Fedora (@doegox) - Chg reduce the list of requirements to the minimum and move to QT5 (@doegox) @@ -11,23 +17,23 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Chg posix sh version of mkversion (@doegox) - Chg remove entirely ncurses, not needed nowadays (@doegox) - Chg remove deprecated termcap, use ncurses instead (@ZeroChaos-) - - Chg 'hf iclass encrypt' - now takes transport key as param. (@iceman1001) - - Chg 'hf iclass decrypt' - now takes transport key as param. (@iceman1001) - - Chg 'hf mf fchk m' - now secretly dumps card to emul, if all keys are found (@iceman1001) + - Chg `hf iclass encrypt` - now takes transport key as param. (@iceman1001) + - Chg `hf iclass decrypt` - now takes transport key as param. (@iceman1001) + - Chg `hf mf fchk m` - now secretly dumps card to emul, if all keys are found (@iceman1001) - Chg history and logfile are now saved into $HOME/.proxmark3/ (@doegox) - Chg optimization of iclass mac calculations on deviceside (@pwpiwi) - - Add 'hf mf autopwn' - Autopwn function for Mifare Classic, extract all keys and dump card memory (@matthiaskonrath) + - Add `hf mf autopwn` - Autopwn function for Mifare Classic, extract all keys and dump card memory (@matthiaskonrath) - Add Lua paths: look for scripts also in ~/.proxmark/lua{scripts,libs} and /usr/local/share/proxmark3/lua{scripts,libs} (@doegox) - Change Lua directory scripts/ to luascript/ (@doegox) - Change non-rdv4 PLATFORM must now use the generic PM3OTHER, simpler (@doegox) - Fix reveng integration for all platforms else than WIN32 (@doegox) - Add cheat sheet for easy operations of the Proxmark3 (scund00r) - Chg commands are now in green in the helptext list (@iceman1001) - - Fix 'script run ndefdump' - better exit messages when failing (@iceman1001) - - Fix 'hf iclass dump' - now also saves in EML format (@iceman1001) - - Fix 'hf iclass sim 3' - now works on legacy readers and legacy SE readers (@iceman1001) + - Fix `script run ndefdump` - better exit messages when failing (@iceman1001) + - Fix `hf iclass dump` - now also saves in EML format (@iceman1001) + - Fix `hf iclass sim 3` - now works on legacy readers and legacy SE readers (@iceman1001) - Rework hitag2 read/write help (@ViRb3) - - Add 'lf nedap' - encoding / decoding (anon) + - Add `lf nedap` - encoding / decoding (anon) - Add client option `-i` to stay in interactive mode after a script or command (@DidierStevens/@doegox) - Add VSCode tasks (@ViRb3) - Better warn user of hardcoded hitag info (@ViRb3) @@ -35,10 +41,10 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Fix hitag password write offset by 1 (@ViRb3) - Fix momentarily flash read/write of dicts (@doegox/@cjbrigato) - Add some more default keys (@anon) - - Add 'hf thinfilm sim' simulating Thinfilm NFC barcode tags (@doegox) - - Add 'hf thinfilm list' specific trace decoding (Thinfilm NFC barcode tags) (@doegox) - - Fix 'hf topaz reader' - don't crash when trying to read a Thinfilm tag (@iceman1001) - - Add 'hf thinfilm info' - read / decode Kovio Thinfilm NFC barcode tags (@iceman1001) + - Add `hf thinfilm sim` simulating Thinfilm NFC barcode tags (@doegox) + - Add `hf thinfilm list` specific trace decoding (Thinfilm NFC barcode tags) (@doegox) + - Fix `hf topaz reader` - don't crash when trying to read a Thinfilm tag (@iceman1001) + - Add `hf thinfilm info` - read / decode Kovio Thinfilm NFC barcode tags (@iceman1001) - Add FPGA LF adc path (@anon) - Add ECC support / check for NID_secp128r1 (@pwpiwi) - Add some more default keys (ollibolli) From afe891647fa3702ae8164d6f7503aaa4d9734626 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 9 Sep 2019 01:07:46 +0200 Subject: [PATCH 0629/1854] merge flasher in client --- Makefile | 2 +- client/Makefile | 13 +- client/flash.c | 90 ++++++----- client/flash.h | 3 + client/flasher.c | 130 ---------------- client/proxmark3.c | 144 +++++++++++++++--- ...OS-X-Homebrew-Installation-Instructions.md | 6 +- .../ModemManager-Must-Be-Discarded.md | 2 +- .../Troubleshooting.md | 18 +-- .../Windows-Installation-Instructions.md | 10 +- .../0_Compilation-Instructions.md | 4 +- doc/path_notes.md | 4 +- pm3 | 23 ++- pm3-flash | 4 + 14 files changed, 231 insertions(+), 222 deletions(-) delete mode 100644 client/flasher.c create mode 100755 pm3-flash diff --git a/Makefile b/Makefile index 90ee442ca..ebb4dacb8 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,7 @@ all clean install uninstall: %: client/% bootrom/% armsrc/% recovery/% mfkey/% n INSTALLTOOLS=pm3_eml2lower.sh pm3_eml2upper.sh pm3_mfdread.py pm3_mfd2eml.py pm3_eml2mfd.py findbits.py rfidtest.pl xorcheck.py INSTALLSIMFW=sim011.bin sim011.sha512.txt -INSTALLSCRIPTS=pm3 pm3-flash-all pm3-flash-bootrom pm3-flash-fullimage +INSTALLSCRIPTS=pm3 pm3-flash pm3-flash-all pm3-flash-bootrom pm3-flash-fullimage INSTALLSHARES=tools/jtag_openocd traces INSTALLDOCS=doc/*.md doc/md diff --git a/client/Makefile b/client/Makefile index 96b5d1bf4..6fee6eae8 100644 --- a/client/Makefile +++ b/client/Makefile @@ -14,7 +14,7 @@ ROOT_DIR:=$(dir $(realpath $(lastword $(MAKEFILE_LIST)))) include ../Makefile.defs -INSTALLBIN = proxmark3 proxmark3-flasher +INSTALLBIN = proxmark3 INSTALLSHARE = cmdscripts lualibs luascripts resources dictionaries VPATH = ../common uart @@ -237,7 +237,8 @@ CMDSRCS = crapto1/crapto1.c \ cmdscript.c \ pm3_bitlib.c \ cmdcrc.c \ - bucketsort.c + bucketsort.c \ + flash.c cpu_arch = $(shell uname -m) ifneq ($(findstring 86, $(cpu_arch)), ) @@ -278,7 +279,7 @@ ifeq "$(SUPPORTS_AVX512)" "True" MULTIARCHOBJS += $(MULTIARCHSRCS:%.c=$(OBJDIR)/%_AVX512.o) endif -BINS = proxmark3 proxmark3-flasher +BINS = proxmark3 CLEAN = $(BINS) *.moc.cpp ui/ui_overlays.h lualibs/pm3_cmd.lua lualibs/mfc_default_keys.lua # transition: make sure old flasher is gone too CLEAN += flasher @@ -294,10 +295,6 @@ proxmark3: $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(QTGUIOBJS) $(info [=] LD $@) $(Q)$(LD) $(LDFLAGS) $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(LDLIBS) -o $@ -proxmark3-flasher: $(OBJDIR)/flash.o $(OBJDIR)/flasher.o $(COREOBJS) $(OBJCOBJS) - $(info [=] LD $@) - $(Q)$(LD) $(LDFLAGS) $^ $(LDLIBS) -o $@ - proxgui.cpp: ui/ui_overlays.h proxguiqt.moc.cpp: proxguiqt.h @@ -447,7 +444,7 @@ DEPENDENCY_FILES = $(patsubst %.c, $(OBJDIR)/%.d, $(CORESRCS) $(CMDSRCS) $(REVEN $(patsubst %.o, %.d, $(MULTIARCHOBJS)) \ $(patsubst %.cpp, $(OBJDIR)/%.d, $(QTGUISRCS)) \ $(patsubst %.m, $(OBJDIR)/%.d, $(OBJCSRCS)) \ - $(OBJDIR)/proxmark3.d $(OBJDIR)/flash.d $(OBJDIR)/proxmark3-flasher.d $(OBJDIR)/flasher.d + $(OBJDIR)/proxmark3.d $(DEPENDENCY_FILES): ; .PRECIOUS: $(DEPENDENCY_FILES) diff --git a/client/flash.c b/client/flash.c index 84e1d687b..5bbb669c0 100644 --- a/client/flash.c +++ b/client/flash.c @@ -83,7 +83,7 @@ static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs, ctx->segments = calloc(sizeof(flash_seg_t) * num_phdrs, sizeof(uint8_t)); if (!ctx->segments) { PrintAndLogEx(ERR, "Out of memory"); - return -1; + return PM3_EMALLOC; } ctx->num_segs = 0; seg = ctx->segments; @@ -113,19 +113,19 @@ static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs, if (filesz != memsz) { PrintAndLogEx(ERR, "Error: PHDR file size does not equal memory size\n" "(DATA+BSS PHDRs do not make sense on ROM platforms!)"); - return -1; + return PM3_EFILE; } if (paddr < last_end) { PrintAndLogEx(ERR, "Error: PHDRs not sorted or overlap"); - return -1; + return PM3_EFILE; } if (paddr < FLASH_START || (paddr + filesz) > flash_end) { PrintAndLogEx(ERR, "Error: PHDR is not contained in Flash"); - return -1; + return PM3_EFILE; } if (vaddr >= FLASH_START && vaddr < flash_end && (flags & PF_W)) { PrintAndLogEx(ERR, "Error: Flash VMA segment is writable"); - return -1; + return PM3_EFILE; } uint8_t *data; @@ -133,12 +133,12 @@ static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs, data = calloc(filesz + BLOCK_SIZE, sizeof(uint8_t)); if (!data) { PrintAndLogEx(ERR, "Error: Out of memory"); - return -1; + return PM3_EMALLOC; } if (fseek(fd, offset, SEEK_SET) < 0 || fread(data, 1, filesz, fd) != filesz) { PrintAndLogEx(ERR, "Error while reading PHDR payload"); free(data); - return -1; + return PM3_EFILE; } uint32_t block_offset = paddr & (BLOCK_SIZE - 1); @@ -157,7 +157,7 @@ static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs, if (!new_data) { PrintAndLogEx(ERR, "Error: Out of memory"); free(data); - return -1; + return PM3_EMALLOC; } memset(new_data, 0xff, new_length); memcpy(new_data, prev_seg->data, prev_seg->length); @@ -191,7 +191,7 @@ static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs, last_end = paddr + filesz; phdr++; } - return 0; + return PM3_SUCCESS; } // Sanity check segments and check for bootloader writes @@ -201,26 +201,26 @@ static int check_segs(flash_file_t *ctx, int can_write_bl, uint32_t flash_end) { if (seg->start & (BLOCK_SIZE - 1)) { PrintAndLogEx(ERR, "Error: Segment is not aligned"); - return -1; + return PM3_EFILE; } if (seg->start < FLASH_START) { PrintAndLogEx(ERR, "Error: Segment is outside of flash bounds"); - return -1; + return PM3_EFILE; } if (seg->start + seg->length > flash_end) { PrintAndLogEx(ERR, "Error: Segment is outside of flash bounds"); - return -1; + return PM3_EFILE; } if (!can_write_bl && seg->start < BOOTLOADER_END) { PrintAndLogEx(ERR, "Attempted to write bootloader but bootloader writes are not enabled"); - return -1; + return PM3_EINVARG; } if (can_write_bl && seg->start < BOOTLOADER_END && (seg->start + seg->length > BOOTLOADER_END)) { PrintAndLogEx(ERR, "Error: Segment is outside of bootloader bounds"); - return -1; + return PM3_EFILE; } } - return 0; + return PM3_SUCCESS; } // Load an ELF file and prepare it for flashing @@ -230,11 +230,12 @@ int flash_load(flash_file_t *ctx, const char *name, int can_write_bl, int flash_ Elf32_Phdr *phdrs = NULL; uint16_t num_phdrs; uint32_t flash_end = FLASH_START + flash_size; - int res; + int res = PM3_EUNDEF; fd = fopen(name, "rb"); if (!fd) { PrintAndLogEx(ERR, _RED_("Could not open file") "%s >>> ", name); + res = PM3_EFILE; goto fail; } @@ -242,28 +243,34 @@ int flash_load(flash_file_t *ctx, const char *name, int can_write_bl, int flash_ if (fread(&ehdr, sizeof(ehdr), 1, fd) != 1) { PrintAndLogEx(ERR, "Error while reading ELF file header"); + res = PM3_EFILE; goto fail; } if (memcmp(ehdr.e_ident, elf_ident, sizeof(elf_ident)) || le32(ehdr.e_version) != 1) { PrintAndLogEx(ERR, "Not an ELF file or wrong ELF type"); + res = PM3_EFILE; goto fail; } if (le16(ehdr.e_type) != ET_EXEC) { PrintAndLogEx(ERR, "ELF is not executable"); + res = PM3_EFILE; goto fail; } if (le16(ehdr.e_machine) != EM_ARM) { PrintAndLogEx(ERR, "Wrong ELF architecture"); + res = PM3_EFILE; goto fail; } if (!ehdr.e_phnum || !ehdr.e_phoff) { PrintAndLogEx(ERR, "ELF has no PHDRs"); + res = PM3_EFILE; goto fail; } if (le16(ehdr.e_phentsize) != sizeof(Elf32_Phdr)) { // could be a structure padding issue... PrintAndLogEx(ERR, "Either the ELF file or this code is made of fail"); + res = PM3_EFILE; goto fail; } num_phdrs = le16(ehdr.e_phnum); @@ -271,28 +278,31 @@ int flash_load(flash_file_t *ctx, const char *name, int can_write_bl, int flash_ phdrs = calloc(le16(ehdr.e_phnum) * sizeof(Elf32_Phdr), sizeof(uint8_t)); if (!phdrs) { PrintAndLogEx(ERR, "Out of memory"); + res = PM3_EMALLOC; goto fail; } if (fseek(fd, le32(ehdr.e_phoff), SEEK_SET) < 0) { PrintAndLogEx(ERR, "Error while reading ELF PHDRs"); + res = PM3_EFILE; goto fail; } if (fread(phdrs, sizeof(Elf32_Phdr), num_phdrs, fd) != num_phdrs) { + res = PM3_EFILE; PrintAndLogEx(ERR, "Error while reading ELF PHDRs"); goto fail; } res = build_segs_from_phdrs(ctx, fd, phdrs, num_phdrs, flash_end); - if (res < 0) + if (res != PM3_SUCCESS) goto fail; res = check_segs(ctx, can_write_bl, flash_end); - if (res < 0) + if (res != PM3_SUCCESS) goto fail; free(phdrs); fclose(fd); ctx->filename = name; - return 0; + return PM3_SUCCESS; fail: if (phdrs) @@ -300,7 +310,7 @@ fail: if (fd) fclose(fd); flash_free(ctx); - return -1; + return res; } // Get the state of the proxmark, backwards compatible @@ -326,22 +336,23 @@ static int get_proxmark_state(uint32_t *state) { break; default: PrintAndLogEx(ERR, _RED_("Error:") "Couldn't get Proxmark3 state, bad response type: 0x%04x", resp.cmd); - return -1; + return PM3_EFATAL; break; } - return 0; + return PM3_SUCCESS; } // Enter the bootloader to be able to start flashing static int enter_bootloader(char *serial_port_name) { uint32_t state; + int ret; - if (get_proxmark_state(&state) < 0) - return -1; + if ((ret = get_proxmark_state(&state)) != PM3_SUCCESS) + return ret; /* Already in flash state, we're done. */ if (state & DEVICE_INFO_FLAG_CURRENT_MODE_BOOTROM) - return 0; + return PM3_SUCCESS; if (state & DEVICE_INFO_FLAG_CURRENT_MODE_OS) { PrintAndLogEx(SUCCESS, _BLUE_("Entering bootloader...")); @@ -364,15 +375,15 @@ static int enter_bootloader(char *serial_port_name) { if (OpenProxmark(serial_port_name, true, 60, true, FLASHMODE_SPEED)) { PrintAndLogEx(NORMAL, " " _GREEN_("Found")); - return 0; + return PM3_SUCCESS; } else { PrintAndLogEx(ERR, _RED_("Error:") "Proxmark3 not found."); - return -1; + return PM3_ETIMEOUT; } } PrintAndLogEx(ERR, _RED_("Error:") "Unknown Proxmark3 mode"); - return -1; + return PM3_EFATAL; } static int wait_for_ack(PacketResponseNG *ack) { @@ -383,9 +394,9 @@ static int wait_for_ack(PacketResponseNG *ack) { ack->cmd, (ack->cmd == CMD_NACK) ? "NACK" : "" ); - return -1; + return PM3_ESOFT; } - return 0; + return PM3_SUCCESS; } static void flash_suggest_update_bootloader(void) { @@ -401,12 +412,15 @@ static void flash_suggest_update_flasher(void) { int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t *max_allowed) { uint32_t state; uint32_t chipinfo = 0; + int ret; - if (enter_bootloader(serial_port_name) < 0) - return -1; + ret = enter_bootloader(serial_port_name); + if (ret != PM3_SUCCESS) + return ret; - if (get_proxmark_state(&state) < 0) - return -1; + ret = get_proxmark_state(&state); + if (ret != PM3_SUCCESS) + return ret; if (state & DEVICE_INFO_FLAG_UNDERSTANDS_CHIP_INFO) { SendCommandBL(CMD_CHIP_INFO, 0, 0, 0, NULL, 0); @@ -485,7 +499,7 @@ int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t PrintAndLogEx(ERR, _RED_("Note: Your bootloader does not understand the new " _YELLOW_("START_FLASH") _RED_("command"))); flash_suggest_update_bootloader(); } - return 0; + return PM3_SUCCESS; } static int write_block(uint32_t address, uint8_t *data, uint32_t length) { @@ -531,7 +545,7 @@ int flash_write(flash_file_t *ctx) { if (write_block(baddr, data, block_size) < 0) { PrintAndLogEx(ERR, "Error writing block %d of %u", block, blocks); - return -1; + return PM3_EFATAL; } data += block_size; @@ -544,7 +558,7 @@ int flash_write(flash_file_t *ctx) { PrintAndLogEx(NORMAL, " " _GREEN_("OK")); fflush(stdout); } - return 0; + return PM3_SUCCESS; } // free a file context @@ -564,5 +578,5 @@ void flash_free(flash_file_t *ctx) { int flash_stop_flashing(void) { SendCommandBL(CMD_HARDWARE_RESET, 0, 0, 0, NULL, 0); msleep(100); - return 0; + return PM3_SUCCESS; } diff --git a/client/flash.h b/client/flash.h index eca4d9ccc..23dd28079 100644 --- a/client/flash.h +++ b/client/flash.h @@ -11,6 +11,9 @@ #include "common.h" +#define FLASH_MAX_FILES 4 +#define ONE_KB 1024 + typedef struct { void *data; uint32_t start; diff --git a/client/flasher.c b/client/flasher.c deleted file mode 100644 index 931976997..000000000 --- a/client/flasher.c +++ /dev/null @@ -1,130 +0,0 @@ -//----------------------------------------------------------------------------- -// This code is licensed to you under the terms of the GNU GPL, version 2 or, -// at your option, any later version. See the LICENSE.txt file for the text of -// the license. -//----------------------------------------------------------------------------- -// Flasher frontend tool -//----------------------------------------------------------------------------- - -#include -#include -#include "usart_defs.h" -#include "flash.h" -#include "comms.h" -#include "ui.h" - -#define MAX_FILES 4 -#define ONE_KB 1024 - -static void usage(char *argv0) { - PrintAndLogEx(NORMAL, "Usage: %s [-b] image.elf [image.elf...]", argv0); - PrintAndLogEx(NORMAL, " %s -i\n", argv0); - PrintAndLogEx(NORMAL, "\t-b\tEnable flashing of bootloader area (DANGEROUS)"); - PrintAndLogEx(NORMAL, "\t-i\tProbe the connected Proxmark3 to retrieve its memory size"); - PrintAndLogEx(NORMAL, "\nExamples:\n\t %s "SERIAL_PORT_EXAMPLE_H" -i", argv0); - PrintAndLogEx(NORMAL, "\t %s "SERIAL_PORT_EXAMPLE_H" armsrc/obj/fullimage.elf", argv0); -#ifdef __linux__ - PrintAndLogEx(NORMAL, "\nNote (Linux):\nif the flasher gets stuck in 'Waiting for Proxmark3 to reappear on ',"); - PrintAndLogEx(NORMAL, "you need to blacklist Proxmark3 for modem-manager - see documentation for more details:"); - PrintAndLogEx(NORMAL, "* https://github.com/RfidResearchGroup/proxmark3/blob/master/doc/md/Installation_Instructions/ModemManager-Must-Be-Discarded.md"); - PrintAndLogEx(NORMAL, "\nMore info on flashing procedure from the official Proxmark3 wiki:"); - PrintAndLogEx(NORMAL, "* https://github.com/Proxmark/proxmark3/wiki/Gentoo%%20Linux"); - PrintAndLogEx(NORMAL, "* https://github.com/Proxmark/proxmark3/wiki/Ubuntu%%20Linux"); - PrintAndLogEx(NORMAL, "* https://github.com/Proxmark/proxmark3/wiki/OSX\n"); -#endif -} - -int main(int argc, char **argv) { - int can_write_bl = 0; - int num_files = 0; - int res; - int ret = 0; - flash_file_t files[MAX_FILES]; - char *filenames[MAX_FILES]; - bool info = false; - memset(files, 0, sizeof(files)); - - session.supports_colors = false; - session.stdinOnTTY = isatty(STDIN_FILENO); - session.stdoutOnTTY = isatty(STDOUT_FILENO); -#if defined(__linux__) || (__APPLE__) - if (session.stdinOnTTY && session.stdoutOnTTY) - session.supports_colors = true; -#endif - session.help_dump_mode = false; - - if (argc < 3) { - usage(argv[0]); - return -1; - } - - for (int i = 2; i < argc; i++) { - if (argv[i][0] == '-') { - if (!strcmp(argv[i], "-b")) { - can_write_bl = 1; - } else if (!strcmp(argv[i], "-i")) { - info = true; - } else { - usage(argv[0]); - return -1; - } - } else { - filenames[num_files] = argv[i]; - num_files++; - } - } - - char *serial_port_name = argv[1]; - - if (OpenProxmark(serial_port_name, true, 60, true, FLASHMODE_SPEED)) { - PrintAndLogEx(NORMAL, _GREEN_("Found")); - } else { - PrintAndLogEx(ERR, "Could not find Proxmark3 on " _RED_("%s") ".\n", serial_port_name); - return -1; - } - - uint32_t max_allowed = 0; - res = flash_start_flashing(can_write_bl, serial_port_name, &max_allowed); - if (res < 0) { - ret = -1; - goto finish; - } - - if (info) - goto finish; - - for (int i = 0 ; i < num_files; ++i) { - res = flash_load(&files[i], filenames[i], can_write_bl, max_allowed * ONE_KB); - if (res < 0) { - ret = -1; - goto finish; - } - PrintAndLogEx(NORMAL, ""); - } - - PrintAndLogEx(SUCCESS, "\n" _BLUE_("Flashing...")); - - for (int i = 0; i < num_files; i++) { - res = flash_write(&files[i]); - if (res < 0) { - ret = -1; - goto finish; - } - flash_free(&files[i]); - PrintAndLogEx(NORMAL, "\n"); - } - -finish: - res = flash_stop_flashing(); - if (res < 0) - ret = -1; - - CloseProxmark(); - - if (ret == 0) - PrintAndLogEx(SUCCESS, _BLUE_("All done.")); - else - PrintAndLogEx(ERR, "Aborted on error."); - PrintAndLogEx(NORMAL, "\nHave a nice day!"); - return ret; -} diff --git a/client/proxmark3.c b/client/proxmark3.c index 26256dd12..05afcc1fd 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -25,6 +25,7 @@ #include "whereami.h" #include "comms.h" #include "fileutils.h" +#include "flash.h" static void showBanner(void) { @@ -278,12 +279,12 @@ static void set_my_executable_path(void) { static void show_help(bool showFullHelp, char *exec_name) { - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "syntax: %s [-h|-t|-m]\n", exec_name); - PrintAndLogEx(NORMAL, " %s [[-p] ] [-b] [-w] [-f] [-c ]|[-l ]|[-s ] [-i]\n", exec_name); + PrintAndLogEx(NORMAL, "\nsyntax: %s [-h|-t|-m]", exec_name); + PrintAndLogEx(NORMAL, " %s [[-p] ] [-b] [-w] [-f] [-c ]|[-l ]|[-s ] [-i]", exec_name); + PrintAndLogEx(NORMAL, " %s [-p] --flash [--unlock-bootloader] [--image ]+", exec_name); if (showFullHelp) { - PrintAndLogEx(NORMAL, "options:"); + PrintAndLogEx(NORMAL, "\nOptions in client mode:"); PrintAndLogEx(NORMAL, " -h/--help this help"); PrintAndLogEx(NORMAL, " -t/--text dump all interactive command's help at once"); PrintAndLogEx(NORMAL, " -m/--markdown dump all interactive help at once in markdown syntax"); @@ -296,21 +297,93 @@ static void show_help(bool showFullHelp, char *exec_name) { PrintAndLogEx(NORMAL, " -s/--script-file script file with one Proxmark3 command per line"); PrintAndLogEx(NORMAL, " -i/--interactive enter interactive mode after executing the script or the command"); PrintAndLogEx(NORMAL, " -v/--version print client version"); - PrintAndLogEx(NORMAL, "\nsamples:"); - PrintAndLogEx(NORMAL, " %s -h\n", exec_name); - PrintAndLogEx(NORMAL, " %s -m\n", exec_name); - PrintAndLogEx(NORMAL, " %s "SERIAL_PORT_EXAMPLE_H" -f -- flush output everytime\n", exec_name); - PrintAndLogEx(NORMAL, " %s "SERIAL_PORT_EXAMPLE_H" -w -- wait for serial port\n", exec_name); - PrintAndLogEx(NORMAL, "\n how to run Proxmark3 client\n"); - PrintAndLogEx(NORMAL, " %s "SERIAL_PORT_EXAMPLE_H" -- runs the pm3 client\n", exec_name); - PrintAndLogEx(NORMAL, " %s -- runs the pm3 client in OFFLINE mode\n", exec_name); - PrintAndLogEx(NORMAL, "\n how to execute different commands from terminal\n"); - PrintAndLogEx(NORMAL, " %s "SERIAL_PORT_EXAMPLE_H" -c \"hf mf chk 1* ?\" -- execute cmd and quit client\n", exec_name); - PrintAndLogEx(NORMAL, " %s "SERIAL_PORT_EXAMPLE_H" -l hf_read -- execute lua script " _YELLOW_("`hf_read`")"and quit client\n", exec_name); - PrintAndLogEx(NORMAL, " %s "SERIAL_PORT_EXAMPLE_H" -s mycmds.txt -- execute each pm3 cmd in file and quit client\n", exec_name); + PrintAndLogEx(NORMAL, "\nOptions in flasher mode:"); + PrintAndLogEx(NORMAL, " --flash flash Proxmark3, requires at least one --image"); + PrintAndLogEx(NORMAL, " --unlock-bootloader Enable flashing of bootloader area *DANGEROUS* (need --flash or --flash-info)"); + PrintAndLogEx(NORMAL, " --image image to flash. Can be specified several times."); + PrintAndLogEx(NORMAL, "\nExamples:"); + PrintAndLogEx(NORMAL, "\n to run Proxmark3 client:\n"); + PrintAndLogEx(NORMAL, " %s "SERIAL_PORT_EXAMPLE_H" -- runs the pm3 client", exec_name); + PrintAndLogEx(NORMAL, " %s "SERIAL_PORT_EXAMPLE_H" -f -- flush output everytime", exec_name); + PrintAndLogEx(NORMAL, " %s "SERIAL_PORT_EXAMPLE_H" -w -- wait for serial port", exec_name); + PrintAndLogEx(NORMAL, " %s -- runs the pm3 client in OFFLINE mode", exec_name); + PrintAndLogEx(NORMAL, "\n to execute different commands from terminal:\n"); + PrintAndLogEx(NORMAL, " %s "SERIAL_PORT_EXAMPLE_H" -c \"hf mf chk 1* ?\" -- execute cmd and quit client", exec_name); + PrintAndLogEx(NORMAL, " %s "SERIAL_PORT_EXAMPLE_H" -l hf_read -- execute lua script " _YELLOW_("`hf_read`")"and quit client", exec_name); + PrintAndLogEx(NORMAL, " %s "SERIAL_PORT_EXAMPLE_H" -s mycmds.txt -- execute each pm3 cmd in file and quit client", exec_name); + PrintAndLogEx(NORMAL, "\n to flash fullimage and bootloader:\n"); + PrintAndLogEx(NORMAL, " %s "SERIAL_PORT_EXAMPLE_H" --flash --unlock-bootloader --image bootrom.elf --image fullimage.elf", exec_name); +#ifdef __linux__ + PrintAndLogEx(NORMAL, "\nNote (Linux):\nif the flasher gets stuck in 'Waiting for Proxmark3 to reappear on ',"); + PrintAndLogEx(NORMAL, "you need to blacklist Proxmark3 for modem-manager - see documentation for more details:"); + PrintAndLogEx(NORMAL, "* https://github.com/RfidResearchGroup/proxmark3/blob/master/doc/md/Installation_Instructions/ModemManager-Must-Be-Discarded.md"); + PrintAndLogEx(NORMAL, "\nMore info on flashing procedure from the official Proxmark3 wiki:"); + PrintAndLogEx(NORMAL, "* https://github.com/Proxmark/proxmark3/wiki/Gentoo%%20Linux"); + PrintAndLogEx(NORMAL, "* https://github.com/Proxmark/proxmark3/wiki/Ubuntu%%20Linux"); + PrintAndLogEx(NORMAL, "* https://github.com/Proxmark/proxmark3/wiki/OSX\n"); +#endif } } +static int flash_pm3(char *serial_port_name, uint8_t num_files, char *filenames[FLASH_MAX_FILES], bool can_write_bl) { + + int ret = PM3_EUNDEF; + flash_file_t files[FLASH_MAX_FILES]; + memset(files, 0, sizeof(files)); + + if (serial_port_name == NULL) { + PrintAndLogEx(ERR, "You must specify a port.\n"); + return PM3_EINVARG; + } + + if (OpenProxmark(serial_port_name, true, 60, true, FLASHMODE_SPEED)) { + PrintAndLogEx(NORMAL, _GREEN_("Found")); + } else { + PrintAndLogEx(ERR, "Could not find Proxmark3 on " _RED_("%s") ".\n", serial_port_name); + return PM3_ETIMEOUT; + } + + uint32_t max_allowed = 0; + ret = flash_start_flashing(can_write_bl, serial_port_name, &max_allowed); + if (ret != PM3_SUCCESS) { + goto finish; + } + + if (num_files == 0) + goto finish; + + for (int i = 0 ; i < num_files; ++i) { + ret = flash_load(&files[i], filenames[i], can_write_bl, max_allowed * ONE_KB); + if (ret != PM3_SUCCESS) { + goto finish; + } + PrintAndLogEx(NORMAL, ""); + } + + PrintAndLogEx(SUCCESS, "\n" _BLUE_("Flashing...")); + + for (int i = 0; i < num_files; i++) { + ret = flash_write(&files[i]); + if (ret != PM3_SUCCESS) { + goto finish; + } + flash_free(&files[i]); + PrintAndLogEx(NORMAL, "\n"); + } + +finish: + ret = flash_stop_flashing(); + + CloseProxmark(); + + if (ret == PM3_SUCCESS) + PrintAndLogEx(SUCCESS, _BLUE_("All done.")); + else + PrintAndLogEx(ERR, "Aborted on error."); + PrintAndLogEx(NORMAL, "\nHave a nice day!"); + return ret; +} + int main(int argc, char *argv[]) { srand(time(0)); @@ -341,6 +414,11 @@ int main(int argc, char *argv[]) { } #endif + bool flash_mode = false; + bool flash_can_write_bl = false; + int flash_num_files = 0; + char *flash_filenames[FLASH_MAX_FILES]; + for (int i = 1; i < argc; i++) { if (argv[i][0] != '-') { @@ -467,6 +545,33 @@ int main(int argc, char *argv[]) { continue; } + // go to flash mode + if (strcmp(argv[i], "--flash") == 0) { + flash_mode = true; + continue; + } + + // unlock bootloader area + if (strcmp(argv[i], "--unlock-bootloader") == 0) { + flash_can_write_bl = true; + continue; + } + + // flash file + if (strcmp(argv[i], "--image") == 0) { + if (flash_num_files == FLASH_MAX_FILES) { + PrintAndLogEx(ERR, _RED_("ERROR:") "too many --image, please use it max %i times\n", FLASH_MAX_FILES); + return 1; + } + if (i + 1 == argc) { + PrintAndLogEx(ERR, _RED_("ERROR:") "missing image specification after --image\n"); + show_help(false, exec_name); + return 1; + } + flash_filenames[flash_num_files++] = argv[++i]; + continue; + } + // We got an unknown parameter PrintAndLogEx(ERR, _RED_("ERROR:") "invalid parameter: " _YELLOW_("%s") "\n", argv[i]); show_help(false, exec_name); @@ -487,13 +592,18 @@ int main(int argc, char *argv[]) { session.supports_colors = true; #endif // ascii art only in interactive client - if (!script_cmds_file && !script_cmd && session.stdinOnTTY && session.stdoutOnTTY) + if (!script_cmds_file && !script_cmd && session.stdinOnTTY && session.stdoutOnTTY && !flash_mode) showBanner(); // Let's take a baudrate ok for real UART, USB-CDC & BT don't use that info anyway if (speed == 0) speed = USART_BAUD_RATE; + if (flash_mode) { + flash_pm3(port, flash_num_files, flash_filenames, flash_can_write_bl); + exit(EXIT_SUCCESS); + } + if (script_cmd) { while (script_cmd[strlen(script_cmd) - 1] == ' ') script_cmd[strlen(script_cmd) - 1] = 0x00; diff --git a/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md b/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md index ba6547cb2..6d6a1c48a 100644 --- a/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md @@ -40,7 +40,7 @@ pm3-flash-all If port detection failed, you'll have to call the flasher manually and specify the correct port: ```sh -proxmark3-flasher /dev/tty.usbmodemiceman1 -b /usr/local/share/proxmark3/firmware/bootrom.elf /usr/local/share/proxmark3/firmware/fullimage.elf +pm3-flash /dev/tty.usbmodemiceman1 -b /usr/local/share/proxmark3/firmware/bootrom.elf /usr/local/share/proxmark3/firmware/fullimage.elf ``` > Depending on the firmware version your Proxmark3 can also appear as `/dev/tty.usbmodem881`. @@ -99,13 +99,13 @@ pm3-flash-all If port detection failed, you'll have to call the flasher manually and specify the correct port: ```sh -proxmark3-flasher /dev/tty.usbmodemiceman1 -b /usr/local/share/proxmark3/firmware/bootrom.elf /usr/local/share/proxmark3/firmware/fullimage.elf +pm3-flash /dev/tty.usbmodemiceman1 -b /usr/local/share/proxmark3/firmware/bootrom.elf /usr/local/share/proxmark3/firmware/fullimage.elf ``` or from the local repo ```sh -client/proxmark3-flasher /dev/tty.usbmodemiceman1 -b bootrom/obj/bootrom.elf armsrc/obj/fullimage.elf +client/pm3-flash /dev/tty.usbmodemiceman1 -b bootrom/obj/bootrom.elf armsrc/obj/fullimage.elf ``` Similarly, to run the client, you may try: diff --git a/doc/md/Installation_Instructions/ModemManager-Must-Be-Discarded.md b/doc/md/Installation_Instructions/ModemManager-Must-Be-Discarded.md index c2c01f44f..7303bdb4b 100644 --- a/doc/md/Installation_Instructions/ModemManager-Must-Be-Discarded.md +++ b/doc/md/Installation_Instructions/ModemManager-Must-Be-Discarded.md @@ -121,7 +121,7 @@ In short: * unplug device * press button and keep it pressed (IMPORTANT) * plug in device -* run flash command `proxmark3-flasher /dev/ttyACM0 /usr/local/share/proxmark3/firmware/fullimage.elf` +* run flash command `pm3-flash /dev/ttyACM0 /usr/local/share/proxmark3/firmware/fullimage.elf` * wait until flash is finished * release button * un/plug device diff --git a/doc/md/Installation_Instructions/Troubleshooting.md b/doc/md/Installation_Instructions/Troubleshooting.md index e9ae8bce9..b7898fb97 100644 --- a/doc/md/Installation_Instructions/Troubleshooting.md +++ b/doc/md/Installation_Instructions/Troubleshooting.md @@ -23,7 +23,7 @@ Always use the latest repository commits from *master* branch. There are always Try using directly the client or flasher: ``` -client/proxmark3-flasher ... +client/pm3-flash ... client/proxmark3 ... ``` @@ -49,8 +49,8 @@ pm3-flash-fullimage ``` or ``` -proxmark3-flasher -b bootrom/obj/bootrom.elf -proxmark3-flasher armsrc/obj/fullimage.elf +pm3-flash -b bootrom/obj/bootrom.elf +pm3-flash armsrc/obj/fullimage.elf ``` ### Find out why it would be bricked @@ -71,7 +71,7 @@ pm3-flash-fullimage ``` or ``` -proxmark3-flasher armsrc/obj/fullimage.elf +pm3-flash armsrc/obj/fullimage.elf ``` You should be back on tracks now. In case the flasher complains about bootloader version, you can follow the button procedure and flash first your bootloader. @@ -81,7 +81,7 @@ pm3-flash-bootrom ``` or ``` -proxmark3-flasher -b bootrom/obj/bootrom.elf +pm3-flash -b bootrom/obj/bootrom.elf ``` ### Ok, my bootloader is definitively dead, now what? @@ -119,9 +119,9 @@ proxmark3 and you must adapt accordingly the file path of some commands, e.g. ``` -proxmark3-flasher /usr/local/share/proxmark3/firmware/fullimage.elf +pm3-flash /usr/local/share/proxmark3/firmware/fullimage.elf <> -proxmark3-flasher /usr/share/proxmark3/firmware/fullimage.elf +pm3-flash /usr/share/proxmark3/firmware/fullimage.elf pm3 --> sc upgrade f /usr/local/share/proxmark3/firmware/sim011.bin <> @@ -144,9 +144,9 @@ cd client; ./proxmark3 ... Therefore client commands referring to files of the repo must be adapted, e.g. ``` -client/proxmark3-flasher armsrc/obj/fullimage.elf +client/pm3-flash armsrc/obj/fullimage.elf <> -./proxmark3-flasher ../armsrc/obj/fullimage.elf +./pm3-flash ../armsrc/obj/fullimage.elf pm3 --> sc upgrade f tools/simmodule/sim011.bin <> diff --git a/doc/md/Installation_Instructions/Windows-Installation-Instructions.md b/doc/md/Installation_Instructions/Windows-Installation-Instructions.md index 6a821a992..4f6bf99e8 100644 --- a/doc/md/Installation_Instructions/Windows-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Windows-Installation-Instructions.md @@ -54,7 +54,7 @@ pacman -S mingw-w64-x86_64-astyle Now you're ready to follow the [compilation instructions](/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md). -To use the compiled client and flasher, the only differences are that executables end with `.exe` (e.g. `proxmark3-flasher.exe`) and that the Proxmark3 port is one of your `comX` ports where "X" is the com port number assigned to proxmark3 under Windows. +To use the compiled client and flasher, the only differences are that executables end with `.exe` (e.g. `proxmark3.exe`) and that the Proxmark3 port is one of your `comX` ports where "X" is the com port number assigned to proxmark3 under Windows. To flash: In principle, the helper script `pm3-flash-all` should auto-detect your COM port, so you can just try: @@ -65,13 +65,13 @@ pm3-flash-all If COM port detection failed, you'll have to call the flasher manually and specify the correct port: ```sh -proxmark3-flasher.exe comX -b /usr/local/share/proxmark3/firmware/bootrom.elf /usr/local/share/proxmark3/firmware/fullimage.elf +pm3-flash comX -b /usr/local/share/proxmark3/firmware/bootrom.elf /usr/local/share/proxmark3/firmware/fullimage.elf ``` or from the local repo ```sh -client/proxmark3-flasher.exe comX -b bootrom/obj/bootrom.elf armsrc/obj/fullimage.elf +client/pm3-flash comX -b bootrom/obj/bootrom.elf armsrc/obj/fullimage.elf ``` Similarly, to run the client, you may try: @@ -156,13 +156,13 @@ pm3-flash-all If port detection failed, you'll have to call the flasher manually and specify the correct port: ```sh -proxmark3-flasher.exe /dev/ttySX -b /usr/local/share/proxmark3/firmware/bootrom.elf /usr/local/share/proxmark3/firmware/fullimage.elf +pm3-flash /dev/ttySX -b /usr/local/share/proxmark3/firmware/bootrom.elf /usr/local/share/proxmark3/firmware/fullimage.elf ``` or from the local repo ```sh -client/proxmark3-flasher.exe /dev/ttySX -b bootrom/obj/bootrom.elf armsrc/obj/fullimage.elf +client/pm3-flash /dev/ttySX -b bootrom/obj/bootrom.elf armsrc/obj/fullimage.elf ``` Similarly, to run the client, you may try: diff --git a/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md b/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md index 7faa6a658..7ec483d0c 100644 --- a/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md +++ b/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md @@ -45,13 +45,13 @@ In most cases, you can run the script `pm3-flash-all` which try to auto-detect t For the other cases, specify the port by yourself. For example, for a Proxmark3 connected via USB under Linux: ```sh -proxmark3-flasher /dev/ttyACM0 -b /usr/local/share/proxmark3/firmware/bootrom.elf /usr/local/share/proxmark3/firmware/fullimage.elf +pm3-flash /dev/ttyACM0 -b /usr/local/share/proxmark3/firmware/bootrom.elf /usr/local/share/proxmark3/firmware/fullimage.elf ``` or from the local repo ```sh -client/proxmark3-flasher /dev/ttyACM0 -b bootrom/obj/bootrom.elf armsrc/obj/fullimage.elf +client/pm3-flash /dev/ttyACM0 -b bootrom/obj/bootrom.elf armsrc/obj/fullimage.elf ``` ## Run the client diff --git a/doc/path_notes.md b/doc/path_notes.md index bcdc19e33..556780f54 100644 --- a/doc/path_notes.md +++ b/doc/path_notes.md @@ -15,8 +15,8 @@ The main Proxmark3 executables / shellscripts will be copied to /usr/local/bin/ ``` -* executables: `proxmark3`, `proxmark3-flasher` -* scripts: `pm3`, `pm3-flash-all`, `pm3-flash-bootloader`, `pm3-flash-fullimage` +* executables: `proxmark3` +* scripts: `pm3`, `pm3-flash`, `pm3-flash-all`, `pm3-flash-bootloader`, `pm3-flash-fullimage` Some more executable / scripts will be copied to diff --git a/pm3 b/pm3 index 11eb59d31..705cd288e 100755 --- a/pm3 +++ b/pm3 @@ -4,19 +4,16 @@ PM3PATH=$(dirname "$0") # try pm3 dirs in current repo workdir if [ -d "$PM3PATH/client/" ]; then CLIENT="$PM3PATH/client/proxmark3" - FLASHER="$PM3PATH/client/proxmark3-flasher" FULLIMAGE="$PM3PATH/armsrc/obj/fullimage.elf" BOOTIMAGE="$PM3PATH/bootrom/obj/bootrom.elf" # try install dir elif [ -x "$PM3PATH/proxmark3" ]; then CLIENT="$PM3PATH/proxmark3" - FLASHER="$PM3PATH/proxmark3-flasher" FULLIMAGE="$PM3PATH/../share/proxmark3/firmware/fullimage.elf" BOOTIMAGE="$PM3PATH/../share/proxmark3/firmware/bootrom.elf" else # hope it's installed somehow, still not sure where fw images are... CLIENT="proxmark3" - FLASHER="proxmark3-flasher" FULLIMAGE="$PM3PATH/../share/proxmark3/firmware/fullimage.elf" BOOTIMAGE="$PM3PATH/../share/proxmark3/firmware/bootrom.elf" fi @@ -80,12 +77,26 @@ SCRIPT=$(basename -- "$0") if [ "$SCRIPT" = "pm3" ]; then CMD() { $CLIENT "$@"; } +elif [ "$SCRIPT" = "pm3-flash" ]; then + CMD() { + ARGS=("$1" "--flash") + shift; + while [ "$1" != "" ]; do + if [ "$1" == "-b" ]; then + ARGS+=("--unlock-bootloader") + else + ARGS+=("--image" "$1") + fi + shift; + done + $CLIENT ${ARGS[@]}; + } elif [ "$SCRIPT" = "pm3-flash-all" ]; then - CMD() { $FLASHER "$1" -b "$BOOTIMAGE" "$FULLIMAGE"; } + CMD() { $CLIENT "$1" "--flash" "--unlock-bootloader" "--image" "$BOOTIMAGE" "--image" "$FULLIMAGE"; } elif [ "$SCRIPT" = "pm3-flash-fullimage" ]; then - CMD() { $FLASHER "$1" "$FULLIMAGE"; } + CMD() { $CLIENT "$1" "--flash" "--image" "$FULLIMAGE"; } elif [ "$SCRIPT" = "pm3-flash-bootrom" ]; then - CMD() { $FLASHER "$1" -b "$BOOTIMAGE"; } + CMD() { $CLIENT "$1" "--flash" "--unlock-bootloader" "--image" "$BOOTIMAGE"; } else echo "[!!] Script ran under unknown name, abort: $SCRIPT" exit 1 diff --git a/pm3-flash b/pm3-flash new file mode 100755 index 000000000..e5cd5479d --- /dev/null +++ b/pm3-flash @@ -0,0 +1,4 @@ +#!/bin/bash + +PM3PATH=$(dirname "$0") +. "$PM3PATH/pm3" From 1a459d644de3e7f701bb6adf06fb549561b54953 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 9 Sep 2019 01:54:59 +0200 Subject: [PATCH 0630/1854] fix flasher doc --- CHANGELOG.md | 1 + ...OS-X-Homebrew-Installation-Instructions.md | 6 ++--- .../ModemManager-Must-Be-Discarded.md | 2 +- .../Troubleshooting.md | 23 +++++++++---------- .../Windows-Installation-Instructions.md | 8 +++---- .../0_Compilation-Instructions.md | 4 ++-- 6 files changed, 22 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5cb0e5c1d..2099db5fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Chg proxmark3-flasher is now merged into proxmark3 client. Add pm3-flash (@doegox) - Chg `hf iclass clone\dump\rdbl\wrbl` - now uses NG (@iceman1001) - Fix `hf iclass clone` - last block always fails (@iceman1001) - Chg `hf iclass clone` - retries ten times, less output (honor verbose) (@iceman1001) diff --git a/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md b/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md index 6d6a1c48a..85fb7f98f 100644 --- a/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md @@ -40,7 +40,7 @@ pm3-flash-all If port detection failed, you'll have to call the flasher manually and specify the correct port: ```sh -pm3-flash /dev/tty.usbmodemiceman1 -b /usr/local/share/proxmark3/firmware/bootrom.elf /usr/local/share/proxmark3/firmware/fullimage.elf +proxmark3 /dev/tty.usbmodemiceman1 --flash --unlock-bootloader --image /usr/local/share/proxmark3/firmware/bootrom.elf --image /usr/local/share/proxmark3/firmware/fullimage.elf ``` > Depending on the firmware version your Proxmark3 can also appear as `/dev/tty.usbmodem881`. @@ -99,13 +99,13 @@ pm3-flash-all If port detection failed, you'll have to call the flasher manually and specify the correct port: ```sh -pm3-flash /dev/tty.usbmodemiceman1 -b /usr/local/share/proxmark3/firmware/bootrom.elf /usr/local/share/proxmark3/firmware/fullimage.elf +proxmark3 /dev/tty.usbmodemiceman1 --flash --unlock-bootloader --image /usr/local/share/proxmark3/firmware/bootrom.elf --image /usr/local/share/proxmark3/firmware/fullimage.elf ``` or from the local repo ```sh -client/pm3-flash /dev/tty.usbmodemiceman1 -b bootrom/obj/bootrom.elf armsrc/obj/fullimage.elf +client/proxmark3 /dev/tty.usbmodemiceman1 --flash --unlock-bootloader --image bootrom/obj/bootrom.elf --image armsrc/obj/fullimage.elf ``` Similarly, to run the client, you may try: diff --git a/doc/md/Installation_Instructions/ModemManager-Must-Be-Discarded.md b/doc/md/Installation_Instructions/ModemManager-Must-Be-Discarded.md index 7303bdb4b..23ae480cc 100644 --- a/doc/md/Installation_Instructions/ModemManager-Must-Be-Discarded.md +++ b/doc/md/Installation_Instructions/ModemManager-Must-Be-Discarded.md @@ -121,7 +121,7 @@ In short: * unplug device * press button and keep it pressed (IMPORTANT) * plug in device -* run flash command `pm3-flash /dev/ttyACM0 /usr/local/share/proxmark3/firmware/fullimage.elf` +* run flash command `pm3-flash-fullimage` * wait until flash is finished * release button * un/plug device diff --git a/doc/md/Installation_Instructions/Troubleshooting.md b/doc/md/Installation_Instructions/Troubleshooting.md index b7898fb97..e0cf7f7aa 100644 --- a/doc/md/Installation_Instructions/Troubleshooting.md +++ b/doc/md/Installation_Instructions/Troubleshooting.md @@ -6,7 +6,7 @@ Always use the latest repository commits from *master* branch. There are always ## Table of Contents - * [pm3 or pm3-flash-* doesn't see my Proxmark](#pm3-or-pm3-flash-doesnt-see-my-proxmark) + * [pm3 or pm3-flash* doesn't see my Proxmark](#pm3-or-pm3-flash-doesnt-see-my-proxmark) * [My Proxmark3 seems bricked](#my-proxmark3-seems-bricked) * [Maybe just a false alarm?](#maybe-just-a-false-alarm) * [Find out why it would be bricked](#find-out-why-it-would-be-bricked) @@ -18,12 +18,11 @@ Always use the latest repository commits from *master* branch. There are always * [File not found](#file-not-found) * [pixmap / pixbuf warnings](#pixmap--pixbuf-warnings) -## `pm3` or `pm3-flash-*` doesn't see my Proxmark +## `pm3` or `pm3-flash*` doesn't see my Proxmark -Try using directly the client or flasher: +Try using directly the client: ``` -client/pm3-flash ... client/proxmark3 ... ``` @@ -49,8 +48,8 @@ pm3-flash-fullimage ``` or ``` -pm3-flash -b bootrom/obj/bootrom.elf -pm3-flash armsrc/obj/fullimage.elf +proxmark3 --flash --unlock-bootloader --image bootrom/obj/bootrom.elf +proxmark3 --flash --image armsrc/obj/fullimage.elf ``` ### Find out why it would be bricked @@ -71,7 +70,7 @@ pm3-flash-fullimage ``` or ``` -pm3-flash armsrc/obj/fullimage.elf +proxmark3 --flash --image armsrc/obj/fullimage.elf ``` You should be back on tracks now. In case the flasher complains about bootloader version, you can follow the button procedure and flash first your bootloader. @@ -81,7 +80,7 @@ pm3-flash-bootrom ``` or ``` -pm3-flash -b bootrom/obj/bootrom.elf +proxmark3 --flash --unlock-bootloader --image bootrom/obj/bootrom.elf ``` ### Ok, my bootloader is definitively dead, now what? @@ -119,9 +118,9 @@ proxmark3 and you must adapt accordingly the file path of some commands, e.g. ``` -pm3-flash /usr/local/share/proxmark3/firmware/fullimage.elf +proxmark3 --flash --image /usr/local/share/proxmark3/firmware/fullimage.elf <> -pm3-flash /usr/share/proxmark3/firmware/fullimage.elf +proxmark3 --flash --image /usr/share/proxmark3/firmware/fullimage.elf pm3 --> sc upgrade f /usr/local/share/proxmark3/firmware/sim011.bin <> @@ -144,9 +143,9 @@ cd client; ./proxmark3 ... Therefore client commands referring to files of the repo must be adapted, e.g. ``` -client/pm3-flash armsrc/obj/fullimage.elf +client/proxmark3 --flash --image armsrc/obj/fullimage.elf <> -./pm3-flash ../armsrc/obj/fullimage.elf +./proxmark3 --flash --image ../armsrc/obj/fullimage.elf pm3 --> sc upgrade f tools/simmodule/sim011.bin <> diff --git a/doc/md/Installation_Instructions/Windows-Installation-Instructions.md b/doc/md/Installation_Instructions/Windows-Installation-Instructions.md index 4f6bf99e8..303a87d1e 100644 --- a/doc/md/Installation_Instructions/Windows-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Windows-Installation-Instructions.md @@ -65,13 +65,13 @@ pm3-flash-all If COM port detection failed, you'll have to call the flasher manually and specify the correct port: ```sh -pm3-flash comX -b /usr/local/share/proxmark3/firmware/bootrom.elf /usr/local/share/proxmark3/firmware/fullimage.elf +proxmark3 comX --flash --unlock-bootloader --image /usr/local/share/proxmark3/firmware/bootrom.elf --image /usr/local/share/proxmark3/firmware/fullimage.elf ``` or from the local repo ```sh -client/pm3-flash comX -b bootrom/obj/bootrom.elf armsrc/obj/fullimage.elf +client/proxmark3 comX --flash --unlock-bootloader --image bootrom/obj/bootrom.elf --image armsrc/obj/fullimage.elf ``` Similarly, to run the client, you may try: @@ -156,13 +156,13 @@ pm3-flash-all If port detection failed, you'll have to call the flasher manually and specify the correct port: ```sh -pm3-flash /dev/ttySX -b /usr/local/share/proxmark3/firmware/bootrom.elf /usr/local/share/proxmark3/firmware/fullimage.elf +proxmark3 /dev/ttySX --flash --unlock-bootloader --image /usr/local/share/proxmark3/firmware/bootrom.elf --image /usr/local/share/proxmark3/firmware/fullimage.elf ``` or from the local repo ```sh -client/pm3-flash /dev/ttySX -b bootrom/obj/bootrom.elf armsrc/obj/fullimage.elf +client/proxmark3 /dev/ttySX --flash --unlock-bootloader --image bootrom/obj/bootrom.elf --image armsrc/obj/fullimage.elf ``` Similarly, to run the client, you may try: diff --git a/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md b/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md index 7ec483d0c..dd2630f18 100644 --- a/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md +++ b/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md @@ -45,13 +45,13 @@ In most cases, you can run the script `pm3-flash-all` which try to auto-detect t For the other cases, specify the port by yourself. For example, for a Proxmark3 connected via USB under Linux: ```sh -pm3-flash /dev/ttyACM0 -b /usr/local/share/proxmark3/firmware/bootrom.elf /usr/local/share/proxmark3/firmware/fullimage.elf +proxmark3 /dev/ttyACM0 --flash --unlock-bootloader --image /usr/local/share/proxmark3/firmware/bootrom.elf --image /usr/local/share/proxmark3/firmware/fullimage.elf ``` or from the local repo ```sh -client/pm3-flash /dev/ttyACM0 -b bootrom/obj/bootrom.elf armsrc/obj/fullimage.elf +client/proxmark3 /dev/ttyACM0 --flash --unlock-bootloader --image bootrom/obj/bootrom.elf --image armsrc/obj/fullimage.elf ``` ## Run the client From 936243a488cdd9b269ffa7d169683157ebd60a93 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 9 Sep 2019 12:58:11 +0200 Subject: [PATCH 0631/1854] add -h to scripts --- pm3 | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/pm3 b/pm3 index 705cd288e..90aec7eb8 100755 --- a/pm3 +++ b/pm3 @@ -1,5 +1,7 @@ #!/bin/bash +# Usage: run option -h to get help + PM3PATH=$(dirname "$0") # try pm3 dirs in current repo workdir if [ -d "$PM3PATH/client/" ]; then @@ -77,6 +79,22 @@ SCRIPT=$(basename -- "$0") if [ "$SCRIPT" = "pm3" ]; then CMD() { $CLIENT "$@"; } + HELP() { + cat << EOF +Quick helper script for proxmark3 client when working with a Proxmark device connected via USB + +Description: + The usage is the same as for the proxmark3 client, with the following differences: + * 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). + Don't use this script if you want to work offline or with the BT addon. + +Usage: + $SCRIPT [-f] [-c ]|[-l ]|[-s ] [-i] + +See "$CLIENT -h" for more details on options. +EOF + } elif [ "$SCRIPT" = "pm3-flash" ]; then CMD() { ARGS=("$1" "--flash") @@ -91,16 +109,74 @@ elif [ "$SCRIPT" = "pm3-flash" ]; then done $CLIENT ${ARGS[@]}; } + HELP() { + cat << EOF +Quick helper script for flashing a Proxmark device via USB + +Description: + The usage is similar to the old proxmark3-flasher binary, except that the correct port name will be automatically guessed. + If this doesn't work, you'll have to use manually the proxmark3 client, see "$CLIENT -h". + +Usage: + $SCRIPT [-b] image.elf [image.elf...] + +Options: + -b Enable flashing of bootloader area (DANGEROUS) + +Example: + $SCRIPT -b bootloader.elf fullimage.elf +EOF + } elif [ "$SCRIPT" = "pm3-flash-all" ]; then CMD() { $CLIENT "$1" "--flash" "--unlock-bootloader" "--image" "$BOOTIMAGE" "--image" "$FULLIMAGE"; } + HELP() { + cat << EOF +Quick helper script for flashing a Proxmark device via USB + +Description: + The correct port name will be automatically guessed and the stock bootloader and firmware image will be flashed. + If this doesn't work, you'll have to use manually the proxmark3 client, see "$CLIENT -h". + +Usage: + $SCRIPT +EOF + } elif [ "$SCRIPT" = "pm3-flash-fullimage" ]; then CMD() { $CLIENT "$1" "--flash" "--image" "$FULLIMAGE"; } + HELP() { + cat << EOF +Quick helper script for flashing a Proxmark device via USB + +Description: + The correct port name will be automatically guessed and the stock firmware image will be flashed. + If this doesn't work, you'll have to use manually the proxmark3 client, see "$CLIENT -h". + +Usage: + $SCRIPT +EOF + } elif [ "$SCRIPT" = "pm3-flash-bootrom" ]; then CMD() { $CLIENT "$1" "--flash" "--unlock-bootloader" "--image" "$BOOTIMAGE"; } + HELP() { + cat << EOF +Quick helper script for flashing a Proxmark device via USB + +Description: + The correct port name will be automatically guessed and the stock bootloader will be flashed. + If this doesn't work, you'll have to use manually the proxmark3 client, see "$CLIENT -h". + +Usage: + $SCRIPT +EOF + } else echo "[!!] Script ran under unknown name, abort: $SCRIPT" exit 1 fi +if [ "$1" == "-h" ] || [ "$1" == "--help" ]; then + HELP + exit 0 +fi HOSTOS=$(uname | awk '{print toupper($0)}') if [ "$HOSTOS" = "LINUX" ]; then if uname -a|grep -q Microsoft; then From c918e0ab802cebee7ba75748744b6536ddcdc69c Mon Sep 17 00:00:00 2001 From: Iceman Date: Mon, 9 Sep 2019 13:15:55 +0200 Subject: [PATCH 0632/1854] chg: 'hf search' - feedback text (@wvzlad) --- client/cmdhf.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/client/cmdhf.c b/client/cmdhf.c index a6c5ea11e..8326d988f 100644 --- a/client/cmdhf.c +++ b/client/cmdhf.c @@ -76,18 +76,23 @@ int CmdHFSearch(const char *Cmd) { PrintAndLogEx(INFO, "Checking for known tags...\n"); + PrintAndLogEx(INPLACE, "Searching for ThinFilm tag..."); if (IfPm3NfcBarcode()) { if (infoThinFilm(false) == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Thinfilm tag") " found\n"); return PM3_SUCCESS; } } + + PrintAndLogEx(INPLACE, "Searching for ISO14443-A tag..."); if (IfPm3Iso14443a()) { if (infoHF14A(false, false) > 0) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("ISO14443-A tag") " found\n"); return PM3_SUCCESS; } } + + PrintAndLogEx(INPLACE, "Searching for ISO15693 tag..."); if (IfPm3Iso15693()) { if (readHF15Uid(false) == 1) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("ISO15693 tag") " found\n"); @@ -97,25 +102,33 @@ int CmdHFSearch(const char *Cmd) { // until refactoring of ISO15693 cmds, this is needed. DropField(); } + + PrintAndLogEx(INPLACE, "Searching for LEGIC tag..."); if (IfPm3Legicrf()) { if (readLegicUid(false) == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("LEGIC tag") " found\n"); return PM3_SUCCESS; } } + + PrintAndLogEx(INPLACE, "Searching for Topaz tag..."); if (IfPm3Iso14443a()) { if (readTopazUid() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Topaz tag") " found\n"); return PM3_SUCCESS; } } + // 14b and iclass is the longest test (put last) + PrintAndLogEx(INPLACE, "Searching for ISO14443-B tag..."); if (IfPm3Iso14443a()) { if (readHF14B(false) == 1) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("ISO14443-B tag") " found\n"); return PM3_SUCCESS; } } + + PrintAndLogEx(INPLACE, "Searching for iClass / PicoPass tag..."); if (IfPm3Iclass()) { if (readIclass(false, false) == 1) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("iClass tag / PicoPass tag") " found\n"); @@ -133,7 +146,7 @@ int CmdHFSearch(const char *Cmd) { //} - PrintAndLogEx(FAILED, "\nno known/supported 13.56 MHz tags found\n"); + PrintAndLogEx(FAILED, "\nNo known/supported 13.56 MHz tags found\n"); return PM3_ESOFT; } @@ -208,7 +221,7 @@ static command_t CommandTable[] = { {"thinfilm", CmdHFThinfilm, AlwaysAvailable, "{ Thinfilm RFIDs... }"}, {"list", CmdTraceList, AlwaysAvailable, "List protocol data in trace buffer"}, {"tune", CmdHFTune, IfPm3Present, "Continuously measure HF antenna tuning"}, - {"search", CmdHFSearch, AlwaysAvailable, "Search for known HF tags [preliminary]"}, + {"search", CmdHFSearch, AlwaysAvailable, "Search for known HF tags"}, {"sniff", CmdHFSniff, IfPm3Hfsniff, " Generic HF Sniff"}, {NULL, NULL, NULL, NULL} }; From 98189d6ef8e7140f4db762d0889e6ee41a18fbe0 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 9 Sep 2019 13:24:45 +0200 Subject: [PATCH 0633/1854] typo --- pm3 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pm3 b/pm3 index 90aec7eb8..d235a0f67 100755 --- a/pm3 +++ b/pm3 @@ -124,7 +124,7 @@ Options: -b Enable flashing of bootloader area (DANGEROUS) Example: - $SCRIPT -b bootloader.elf fullimage.elf + $SCRIPT -b bootrom.elf fullimage.elf EOF } elif [ "$SCRIPT" = "pm3-flash-all" ]; then From df40da13805038e9e0cb34ad8e9273dc27809346 Mon Sep 17 00:00:00 2001 From: Iceman Date: Mon, 9 Sep 2019 13:38:44 +0200 Subject: [PATCH 0634/1854] ignore bmptst (@wzvlad) --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index fda8c21af..348195eba 100644 --- a/.gitignore +++ b/.gitignore @@ -35,6 +35,7 @@ Makefile.platform !client/hardnested/*.bin !client/hardnested/tables/*.z client/ui/ui_overlays.h +client/reveng/bmptst hardnested_stats.txt proxmark3 From 7b773c571b08d9079972228103d5fd1d21c6a588 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 9 Sep 2019 15:19:00 +0200 Subject: [PATCH 0635/1854] chg: 'lf t55xx dump p 11223344' - less verbose output. --- client/cmdlft55xx.c | 53 ++++++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 25 deletions(-) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 1431ca62a..55b711482 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -409,12 +409,12 @@ int T55xxReadBlock(uint8_t block, bool page1, bool usepwd, uint8_t override, uin //Password mode if (usepwd) { // try reading the config block and verify that PWD bit is set before doing this! - if (!override) { + if (override == 0) { if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, false, 0, downlink_mode)) return PM3_ESOFT; if (!tryDetectModulation()) { PrintAndLogEx(NORMAL, "Safety Check: Could not detect if PWD bit is set in config block. Exits."); - return 0; + return PM3_ESOFT; } else { PrintAndLogEx(NORMAL, "Safety Check: PWD bit is NOT set in config block. Reading without password..."); usepwd = false; @@ -422,28 +422,31 @@ int T55xxReadBlock(uint8_t block, bool page1, bool usepwd, uint8_t override, uin } } else { // Show only if first for command i.e. override = 1 (override and display) override = 2 (override and dont display) - if ((override & 2) != 2) + if (override == 1) PrintAndLogEx(NORMAL, "Safety Check Overriden - proceeding despite risk"); } } - if (!AquireData(page1, block, usepwd, password, downlink_mode)) return PM3_ESOFT; - if (!DecodeT55xxBlock()) return PM3_ESOFT; + if (!AquireData(page1, block, usepwd, password, downlink_mode)) + return PM3_ESOFT; + + if (!DecodeT55xxBlock()) + return PM3_ESOFT; printT55xxBlock(block); return PM3_SUCCESS; } static int CmdT55xxReadBlock(const char *Cmd) { - uint8_t block = REGULAR_READ_MODE_BLOCK; - uint32_t password = 0; //default to blank Block 7 - bool usepwd = false; - bool override = false; - bool page1 = false; - bool errors = false; - uint8_t cmdp = 0; - uint8_t downlink_mode = 0; + uint8_t block = REGULAR_READ_MODE_BLOCK; + uint8_t override = 0; + uint8_t cmdp = 0; + uint8_t downlink_mode = 0; + uint32_t password = 0; //default to blank Block 7 + bool usepwd = false; + bool page1 = false; + bool errors = false; while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { @@ -454,7 +457,7 @@ static int CmdT55xxReadBlock(const char *Cmd) { cmdp += 2; break; case 'o': - override = true; + override = 1; cmdp++; break; case 'p': @@ -467,7 +470,6 @@ static int CmdT55xxReadBlock(const char *Cmd) { cmdp++; break; case 'r': - case 'R': downlink_mode = param_getchar(Cmd, cmdp + 1) - '0'; if (downlink_mode > 3) downlink_mode = 0; cmdp += 2; @@ -1653,26 +1655,27 @@ static int CmdT55xxInfo(const char *Cmd) { static int CmdT55xxDump(const char *Cmd) { - uint32_t password = 0; - uint8_t override = false; - uint8_t cmd_opt_idx = 0; - uint8_t downlink_mode = 0; - uint8_t pwd_offset = 0; - char cmdp = tolower(param_getchar(Cmd, 0)); - + uint32_t password = 0; + uint8_t override = 0; + uint8_t cmd_opt_idx = 0; + uint8_t downlink_mode = 0; + uint8_t pwd_offset = 0; + char cmdp = tolower(param_getchar(Cmd, 0)); if (cmdp == 'h') return usage_t55xx_dump(); if (cmdp == 'r') { cmd_opt_idx++; downlink_mode = param_getchar(Cmd, cmd_opt_idx++) - '0'; - if (downlink_mode > 3) downlink_mode = 0; + if (downlink_mode > 3) + downlink_mode = 0; + pwd_offset = 3; } bool usepwd = (strlen(Cmd) > pwd_offset); if (usepwd) { password = param_get32ex(Cmd, cmd_opt_idx++, 0, 16); if (param_getchar(Cmd, cmd_opt_idx++) == 'o') - override = true; + override = 1; } printT5xxHeader(0); @@ -1680,7 +1683,7 @@ static int CmdT55xxDump(const char *Cmd) { T55xxReadBlock(i, 0, usepwd, override, password, downlink_mode); // idea for better user experience and display. // only show override warning on the first block read - if (override) override |= 2; // flag not to show safty for 2nd and on. + if (override == 1) override++; // flag not to show safty for 2nd and on. } printT5xxHeader(1); for (uint8_t i = 0; i < 4; i++) From f7624a7767384297da03450007ff21d4dbbc14ea Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 9 Sep 2019 17:33:44 +0200 Subject: [PATCH 0636/1854] textual --- client/cmdhficlass.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index c24853dcb..8b0c4ea35 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -2756,21 +2756,21 @@ static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, {"calcnewkey", CmdHFiClassCalcNewKey, AlwaysAvailable, "[options..] Calc diversified keys (blocks 3 & 4) to write new keys"}, {"chk", CmdHFiClassCheckKeys, AlwaysAvailable, "[options..] Check keys"}, - {"clone", CmdHFiClassCloneTag, IfPm3Iclass, "[options..] Clone (restore from tagdump file)"}, - {"decrypt", CmdHFiClassDecrypt, AlwaysAvailable, "[options..] Decrypt given block data or tagdump file" }, - {"dump", CmdHFiClassReader_Dump, IfPm3Iclass, "[options..] Authenticate and Dump iClass tag's AA1"}, - {"eload", CmdHFiClassELoad, IfPm3Iclass, "[f ] (experimental) Load data into iClass emulator memory"}, + {"clone", CmdHFiClassCloneTag, IfPm3Iclass, "[options..] Restore a dump file onto a iClass tag"}, + {"decrypt", CmdHFiClassDecrypt, AlwaysAvailable, "[options..] Decrypt given block data or tag dump file" }, + {"dump", CmdHFiClassReader_Dump, IfPm3Iclass, "[options..] Dump iClass tag to file"}, + {"eload", CmdHFiClassELoad, IfPm3Iclass, "[f ] Load iClass dump file into emulator memory"}, {"encrypt", CmdHFiClassEncryptBlk, AlwaysAvailable, "[options..] Encrypt given block data"}, {"info", CmdHFiClassInfo, AlwaysAvailable, " Tag information"}, {"list", CmdHFiClassList, AlwaysAvailable, " List iClass history"}, - {"loclass", CmdHFiClass_loclass, AlwaysAvailable, "[options..] Use loclass to perform bruteforce of reader attack dump"}, + {"loclass", CmdHFiClass_loclass, AlwaysAvailable, "[options..] Use loclass to perform bruteforce reader attack"}, {"lookup", CmdHFiClassLookUp, AlwaysAvailable, "[options..] Uses authentication trace to check for key in dictionary file"}, - {"managekeys", CmdHFiClassManageKeys, AlwaysAvailable, "[options..] Manage the keys to use with iClass"}, + {"managekeys", CmdHFiClassManageKeys, AlwaysAvailable, "[options..] Manage keys to use with iClass"}, {"permutekey", CmdHFiClassPermuteKey, IfPm3Iclass, " Permute function from 'heart of darkness' paper"}, {"rdbl", CmdHFiClass_ReadBlock, IfPm3Iclass, "[options..] Read iClass block"}, {"reader", CmdHFiClassReader, IfPm3Iclass, " Act like an iClass reader"}, - {"readtagfile", CmdHFiClassReadTagFile, AlwaysAvailable, "[options..] Display Content from tagfile"}, - {"replay", CmdHFiClassReader_Replay, IfPm3Iclass, " Read an iClass tag via Replay Attack"}, + {"readtagfile", CmdHFiClassReadTagFile, AlwaysAvailable, "[options..] Display content from tag dump file"}, + {"replay", CmdHFiClassReader_Replay, IfPm3Iclass, " Read iClass tag via replay attack"}, {"sim", CmdHFiClassSim, IfPm3Iclass, "[options..] Simulate iClass tag"}, {"sniff", CmdHFiClassSniff, IfPm3Iclass, " Eavesdrop iClass communication"}, {"wrbl", CmdHFiClass_WriteBlock, IfPm3Iclass, "[options..] Write iClass block"}, @@ -2812,7 +2812,7 @@ int readIclass(bool loop, bool verbose) { if (verbose) { PrintAndLogEx(FAILED, "Quitting..."); DropField(); - return 0; + return PM3_EOPABORTED; } } if (readStatus & FLAG_ICLASS_READER_CSN) { @@ -2841,7 +2841,7 @@ int readIclass(bool loop, bool verbose) { if (tagFound && !loop) { DropField(); - return 1; + return PM3_SUCCESS; } } else { if (verbose) From 6385ee960f4276bdac9755bce7c22744d2cf2527 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 9 Sep 2019 19:55:27 +0200 Subject: [PATCH 0637/1854] searchFile for firmwares --- client/fileutils.c | 5 ++++- client/proxmark3.c | 40 +++++++++++++++++++++++++++++++++------- include/common.h | 3 +++ pm3 | 8 ++------ 4 files changed, 42 insertions(+), 14 deletions(-) diff --git a/client/fileutils.c b/client/fileutils.c index 9a5907882..f379f56d3 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -956,7 +956,10 @@ static int searchFinalFile(char **foundpath, const char *pm3dir, const char *sea } // try pm3 dirs in current repo workdir (dev mode) if ((exec_path != NULL) && - ((strcmp(TRACES_SUBDIR, pm3dir) == 0))) { + ((strcmp(TRACES_SUBDIR, pm3dir) == 0) || + (strcmp(FIRMWARES_SUBDIR, pm3dir) == 0) || + (strcmp(BOOTROM_SUBDIR, pm3dir) == 0) || + (strcmp(FULLIMAGE_SUBDIR, pm3dir) == 0))) { char *above = "../"; char *path = calloc(strlen(exec_path) + strlen(above) + strlen(pm3dir) + strlen(filename) + 1, sizeof(char)); if (path == NULL) diff --git a/client/proxmark3.c b/client/proxmark3.c index 05afcc1fd..50f63ec51 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -330,17 +330,40 @@ static int flash_pm3(char *serial_port_name, uint8_t num_files, char *filenames[ int ret = PM3_EUNDEF; flash_file_t files[FLASH_MAX_FILES]; memset(files, 0, sizeof(files)); + char *filepaths[FLASH_MAX_FILES]; if (serial_port_name == NULL) { PrintAndLogEx(ERR, "You must specify a port.\n"); return PM3_EINVARG; } + for (int i = 0 ; i < num_files; ++i) { + char *path; + ret = searchFile(&path, FIRMWARES_SUBDIR, filenames[i], ".elf", true); + if (ret != PM3_SUCCESS) { + ret = searchFile(&path, BOOTROM_SUBDIR, filenames[i], ".elf", true); + } + if (ret != PM3_SUCCESS) { + // Last try, let the error msg be displayed if not found + ret = searchFile(&path, FULLIMAGE_SUBDIR, filenames[i], ".elf", false); + } + if (ret != PM3_SUCCESS) { + goto finish2; + } + filepaths[i] = path; + } + + PrintAndLogEx(SUCCESS, "About to use the following file%s:", num_files > 1 ? "s" : ""); + for (int i = 0 ; i < num_files; ++i) { + PrintAndLogEx(SUCCESS, " %s", filepaths[i]); + } + if (OpenProxmark(serial_port_name, true, 60, true, FLASHMODE_SPEED)) { PrintAndLogEx(NORMAL, _GREEN_("Found")); } else { PrintAndLogEx(ERR, "Could not find Proxmark3 on " _RED_("%s") ".\n", serial_port_name); - return PM3_ETIMEOUT; + ret = PM3_ETIMEOUT; + goto finish2; } uint32_t max_allowed = 0; @@ -353,7 +376,7 @@ static int flash_pm3(char *serial_port_name, uint8_t num_files, char *filenames[ goto finish; for (int i = 0 ; i < num_files; ++i) { - ret = flash_load(&files[i], filenames[i], can_write_bl, max_allowed * ONE_KB); + ret = flash_load(&files[i], filepaths[i], can_write_bl, max_allowed * ONE_KB); if (ret != PM3_SUCCESS) { goto finish; } @@ -373,9 +396,12 @@ static int flash_pm3(char *serial_port_name, uint8_t num_files, char *filenames[ finish: ret = flash_stop_flashing(); - CloseProxmark(); - +finish2: + for (int i = 0 ; i < num_files; ++i) { + if (filepaths[i] != NULL) + free(filepaths[i]); + } if (ret == PM3_SUCCESS) PrintAndLogEx(SUCCESS, _BLUE_("All done.")); else @@ -599,6 +625,9 @@ int main(int argc, char *argv[]) { if (speed == 0) speed = USART_BAUD_RATE; + // set global variables + set_my_executable_path(); + if (flash_mode) { flash_pm3(port, flash_num_files, flash_filenames, flash_can_write_bl); exit(EXIT_SUCCESS); @@ -629,9 +658,6 @@ int main(int argc, char *argv[]) { } } - // set global variables - set_my_executable_path(); - // try to open USB connection to Proxmark if (port != NULL) { OpenProxmark(port, waitCOMPort, 20, false, speed); diff --git a/include/common.h b/include/common.h index f13f5f99a..627846ff2 100644 --- a/include/common.h +++ b/include/common.h @@ -30,6 +30,9 @@ #define LUA_SCRIPTS_SUBDIR "luascripts" PATHSEP #define RESOURCES_SUBDIR "resources" PATHSEP #define TRACES_SUBDIR "traces" PATHSEP +#define FIRMWARES_SUBDIR "firmware" PATHSEP +#define BOOTROM_SUBDIR "bootrom/obj" PATHSEP +#define FULLIMAGE_SUBDIR "armsrc/obj" PATHSEP #define PACKED __attribute__((packed)) diff --git a/pm3 b/pm3 index d235a0f67..a740beb12 100755 --- a/pm3 +++ b/pm3 @@ -3,21 +3,17 @@ # Usage: run option -h to get help PM3PATH=$(dirname "$0") +FULLIMAGE="fullimage.elf" +BOOTIMAGE="bootrom.elf" # try pm3 dirs in current repo workdir if [ -d "$PM3PATH/client/" ]; then CLIENT="$PM3PATH/client/proxmark3" - FULLIMAGE="$PM3PATH/armsrc/obj/fullimage.elf" - BOOTIMAGE="$PM3PATH/bootrom/obj/bootrom.elf" # try install dir elif [ -x "$PM3PATH/proxmark3" ]; then CLIENT="$PM3PATH/proxmark3" - FULLIMAGE="$PM3PATH/../share/proxmark3/firmware/fullimage.elf" - BOOTIMAGE="$PM3PATH/../share/proxmark3/firmware/bootrom.elf" else # hope it's installed somehow, still not sure where fw images are... CLIENT="proxmark3" - FULLIMAGE="$PM3PATH/../share/proxmark3/firmware/fullimage.elf" - BOOTIMAGE="$PM3PATH/../share/proxmark3/firmware/bootrom.elf" fi function wait4proxmark_Linux { From 9f88580061ef3d29115d668d56d96b60b6182446 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 9 Sep 2019 19:55:55 +0200 Subject: [PATCH 0638/1854] adapt flasher docs --- ...OS-X-Homebrew-Installation-Instructions.md | 43 +++-------- .../Windows-Installation-Instructions.md | 76 +++---------------- .../0_Compilation-Instructions.md | 24 ++++-- 3 files changed, 38 insertions(+), 105 deletions(-) diff --git a/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md b/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md index 85fb7f98f..f78016df9 100644 --- a/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md @@ -84,39 +84,14 @@ brew install RfidResearchGroup/proxmark3/arm-none-eabi-gcc ## Compile and use the project +To use the compiled client, the only difference is that the Proxmark3 port is `/dev/tty.usbmodemiceman1`, so commands become: + +```sh +proxmark3 /dev/ttyACM0 => proxmark3 /dev/tty.usbmodemiceman1 +``` + Now you're ready to follow the [compilation instructions](/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md). -To use the compiled client and flasher, the only difference is that the Proxmark3 port is `/dev/tty.usbmodemiceman1`. - -To flash: With your Proxmark3 unplugged from your machine, press and hold the button on your Proxmark3 as you plug it into a USB port. You can release the button, two of the four LEDs should stay on. You're un bootloader mode, ready for the next step. In case the two LEDs don't stay on when you're releasing the button, you've an old bootloader, start over and keep the button pressed during the whole flashing procedure. - -In principle, the helper script `pm3-flash-all` should auto-detect your port, so you can just try: - -```sh -pm3-flash-all -``` - -If port detection failed, you'll have to call the flasher manually and specify the correct port: - -```sh -proxmark3 /dev/tty.usbmodemiceman1 --flash --unlock-bootloader --image /usr/local/share/proxmark3/firmware/bootrom.elf --image /usr/local/share/proxmark3/firmware/fullimage.elf -``` - -or from the local repo - -```sh -client/proxmark3 /dev/tty.usbmodemiceman1 --flash --unlock-bootloader --image bootrom/obj/bootrom.elf --image armsrc/obj/fullimage.elf -``` - -Similarly, to run the client, you may try: - -```sh -pm3 -``` - -Or, by specifying the port manually: - -```sh -proxmark3 /dev/tty.usbmodemiceman1 -``` - +To flash on OS X, better to enter the bootloader mode manually, else you may experience errors. +With your Proxmark3 unplugged from your machine, press and hold the button on your Proxmark3 as you plug it into a USB port. You can release the button, two of the four LEDs should stay on. You're in bootloader mode, ready for the next step. In case the two LEDs don't stay on when you're releasing the button, you've an old bootloader, start over and keep the button pressed during the whole flashing procedure. +From there, you can follow the original compilation instructions. diff --git a/doc/md/Installation_Instructions/Windows-Installation-Instructions.md b/doc/md/Installation_Instructions/Windows-Installation-Instructions.md index 303a87d1e..9cd150a22 100644 --- a/doc/md/Installation_Instructions/Windows-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Windows-Installation-Instructions.md @@ -52,40 +52,14 @@ pacman -S mingw-w64-x86_64-astyle ## Compile and use the project +To use the compiled client, the only differences are that executables end with `.exe` (e.g. `proxmark3.exe`) and that the Proxmark3 port is one of your `comX` ports where "X" is the com port number assigned to proxmark3 under Windows, so commands become: + +```sh +proxmark3 /dev/ttyACM0 => proxmark3.exe comX +``` + Now you're ready to follow the [compilation instructions](/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md). -To use the compiled client and flasher, the only differences are that executables end with `.exe` (e.g. `proxmark3.exe`) and that the Proxmark3 port is one of your `comX` ports where "X" is the com port number assigned to proxmark3 under Windows. - -To flash: In principle, the helper script `pm3-flash-all` should auto-detect your COM port, so you can just try: - -```sh -pm3-flash-all -``` - -If COM port detection failed, you'll have to call the flasher manually and specify the correct port: - -```sh -proxmark3 comX --flash --unlock-bootloader --image /usr/local/share/proxmark3/firmware/bootrom.elf --image /usr/local/share/proxmark3/firmware/fullimage.elf -``` - -or from the local repo - -```sh -client/proxmark3 comX --flash --unlock-bootloader --image bootrom/obj/bootrom.elf --image armsrc/obj/fullimage.elf -``` - -Similarly, to run the client, you may try: - -```sh -pm3 -``` - -Or, by specifying the COM port manually: - -```sh -proxmark3.exe comX -``` - # Installing on Windows with WSL It requires to run a Windows 10 version 1709 or above. Previous versions didn't have support for COM ports. @@ -118,9 +92,11 @@ git clone https://github.com/RfidResearchGroup/proxmark3.git ## Compile and use the project -Now you're ready to follow the [compilation instructions](/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md). +To use the compiled client, the only difference is that the Proxmark3 port is translated from your `comX` port where "X" is the com port number assigned to proxmark3 under Windows, to a `/dev/ttySX`, so commands become: -To use the compiled client and flasher, the only difference is that the Proxmark3 port is translated from your `comX` port where "X" is the com port number assigned to proxmark3 under Windows, to a `/dev/ttySX`. +```sh +proxmark3 /dev/ttyACM0 => proxmark3 /dev/ttySX +``` Depending on the Windows version, you might need to give permission to the current user to access `/dev/ttySX`: (change X to your port number) @@ -147,34 +123,6 @@ and add it to your Bash profile for the next times: echo "export DISPLAY=:0" >> ~/.bashrc ``` -To flash: In principle, the helper script `pm3-flash-all` should auto-detect your COMX==/dev/ttySX port, so you can just try: - -```sh -pm3-flash-all -``` - -If port detection failed, you'll have to call the flasher manually and specify the correct port: - -```sh -proxmark3 /dev/ttySX --flash --unlock-bootloader --image /usr/local/share/proxmark3/firmware/bootrom.elf --image /usr/local/share/proxmark3/firmware/fullimage.elf -``` - -or from the local repo - -```sh -client/proxmark3 /dev/ttySX --flash --unlock-bootloader --image bootrom/obj/bootrom.elf --image armsrc/obj/fullimage.elf -``` - -Similarly, to run the client, you may try: - -```sh -pm3 -``` - -Or, by specifying the COM port manually: - -```sh -proxmark3 /dev/ttySX -``` - Note that it may take a quite long time for a freshly plugged Proxmark3 to be visible on a WSL /dev/ttySX port. + +Now you're ready to follow the [compilation instructions](/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md). diff --git a/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md b/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md index dd2630f18..e423752ab 100644 --- a/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md +++ b/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md @@ -40,18 +40,28 @@ e.g. calling `./pm3` or `client/proxmark3` instead of just `pm3` or `proxmark3`. ## Flash the BOOTROM & FULLIMAGE -In most cases, you can run the script `pm3-flash-all` which try to auto-detect the port to use, on several OS. - -For the other cases, specify the port by yourself. For example, for a Proxmark3 connected via USB under Linux: +In most cases, you can run the following script which try to auto-detect the port to use, on several OS: ```sh -proxmark3 /dev/ttyACM0 --flash --unlock-bootloader --image /usr/local/share/proxmark3/firmware/bootrom.elf --image /usr/local/share/proxmark3/firmware/fullimage.elf +pm3-flash-all ``` -or from the local repo +For the other cases, specify the port by yourself. For example, for a Proxmark3 connected via USB under Linux (adjust the port for your OS): ```sh -client/proxmark3 /dev/ttyACM0 --flash --unlock-bootloader --image bootrom/obj/bootrom.elf --image armsrc/obj/fullimage.elf +proxmark3 /dev/ttyACM0 --flash --unlock-bootloader --image bootrom.elf --image fullimage.elf +``` + +The firmware files will be searched in the expected locations (installed files, working repo files, user folder, etc.). You can also specify their location: + +```sh +pm3-flash -b /tmp/my-bootrom.elf /tmp/my-fullimage.elf +``` + +or + +```sh +proxmark3 /dev/ttyACM0 --flash --unlock-bootloader --image /tmp/my-bootrom.elf --image /tmp/my-fullimage.elf ``` ## Run the client @@ -60,7 +70,7 @@ In most cases, you can run the script `pm3` which try to auto-detect the port to For the other cases, specify the port by yourself. For example, for a Proxmark3 connected via USB under Linux: -Here, for example, for a Proxmark3 connected via USB under Linux: +Here, for example, for a Proxmark3 connected via USB under Linux (adjust the port for your OS): ```sh proxmark3 /dev/ttyACM0 From d5d2c64d5025a1724016cfb93e692209cc74b8a3 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 9 Sep 2019 20:45:10 +0200 Subject: [PATCH 0639/1854] allow to set debugmode from cli options --- client/proxmark3.c | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/client/proxmark3.c b/client/proxmark3.c index 50f63ec51..f1a8bb05f 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -280,23 +280,26 @@ static void set_my_executable_path(void) { static void show_help(bool showFullHelp, char *exec_name) { PrintAndLogEx(NORMAL, "\nsyntax: %s [-h|-t|-m]", exec_name); - PrintAndLogEx(NORMAL, " %s [[-p] ] [-b] [-w] [-f] [-c ]|[-l ]|[-s ] [-i]", exec_name); - PrintAndLogEx(NORMAL, " %s [-p] --flash [--unlock-bootloader] [--image ]+", exec_name); + PrintAndLogEx(NORMAL, " %s [[-p] ] [-b] [-w] [-f] [-c ]|[-l ]|[-s ] [-i] [-d <0|1|2>]", exec_name); + PrintAndLogEx(NORMAL, " %s [-p] --flash [--unlock-bootloader] [--image ]+ [-w] [-f] [-d <0|1|2>]", exec_name); if (showFullHelp) { - PrintAndLogEx(NORMAL, "\nOptions in client mode:"); + + PrintAndLogEx(NORMAL, "\nCommon options:"); PrintAndLogEx(NORMAL, " -h/--help this help"); - PrintAndLogEx(NORMAL, " -t/--text dump all interactive command's help at once"); - PrintAndLogEx(NORMAL, " -m/--markdown dump all interactive help at once in markdown syntax"); + PrintAndLogEx(NORMAL, " -v/--version print client version"); PrintAndLogEx(NORMAL, " -p/--port serial port to connect to"); - PrintAndLogEx(NORMAL, " -b/--baud serial port speed (only needed for physical UART, not for USB-CDC or BT)"); PrintAndLogEx(NORMAL, " -w/--wait 20sec waiting the serial port to appear in the OS"); PrintAndLogEx(NORMAL, " -f/--flush output will be flushed after every print"); + PrintAndLogEx(NORMAL, " -d/--debug <0|1|2> set debugmode"); + PrintAndLogEx(NORMAL, "\nOptions in client mode:"); + PrintAndLogEx(NORMAL, " -t/--text dump all interactive command's help at once"); + PrintAndLogEx(NORMAL, " -m/--markdown dump all interactive help at once in markdown syntax"); + PrintAndLogEx(NORMAL, " -b/--baud serial port speed (only needed for physical UART, not for USB-CDC or BT)"); PrintAndLogEx(NORMAL, " -c/--command execute one Proxmark3 command (or several separated by ';')."); PrintAndLogEx(NORMAL, " -l/--lua execute lua script."); PrintAndLogEx(NORMAL, " -s/--script-file script file with one Proxmark3 command per line"); PrintAndLogEx(NORMAL, " -i/--interactive enter interactive mode after executing the script or the command"); - PrintAndLogEx(NORMAL, " -v/--version print client version"); PrintAndLogEx(NORMAL, "\nOptions in flasher mode:"); PrintAndLogEx(NORMAL, " --flash flash Proxmark3, requires at least one --image"); PrintAndLogEx(NORMAL, " --unlock-bootloader Enable flashing of bootloader area *DANGEROUS* (need --flash or --flash-info)"); @@ -494,12 +497,28 @@ int main(int argc, char *argv[]) { dumpAllHelp(1); return 0; } - // pritn client version + // print client version if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--version") == 0) { pm3_version(true, true); return 0; } + // set debugmode + if (strcmp(argv[i], "-d") == 0 || strcmp(argv[i], "--debug") == 0) { + if (i + 1 == argc) { + PrintAndLogEx(ERR, _RED_("ERROR:") "missing debugmode specification after -d\n"); + show_help(false, exec_name); + return 1; + } + int demod = atoi(argv[i + 1]); + if (demod < 0 || demod > 2) { + PrintAndLogEx(ERR, _RED_("ERROR:") "invalid debugmode: -d " _YELLOW_("%s") "\n", argv[i + 1]); + return 1; + } + g_debugMode = demod; + i++; + continue; + } // flush output if (strcmp(argv[i], "-f") == 0 || strcmp(argv[i], "--flush") == 0) { From ba47ac36cbc65aeb669119889b67d4bb5e7de747 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 9 Sep 2019 21:01:43 +0200 Subject: [PATCH 0640/1854] Do not log to history with -h/-t/-m --- client/proxmark3.c | 3 +++ client/ui.c | 4 ++-- client/util.c | 2 ++ client/util.h | 1 + 4 files changed, 8 insertions(+), 2 deletions(-) diff --git a/client/proxmark3.c b/client/proxmark3.c index f1a8bb05f..58b082078 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -481,12 +481,14 @@ int main(int argc, char *argv[]) { // short help if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) { + g_disableLogging = true; show_help(true, exec_name); return 0; } // dump help if (strcmp(argv[i], "-t") == 0 || strcmp(argv[i], "--text") == 0) { + g_disableLogging = true; show_help(false, exec_name); dumpAllHelp(0); return 0; @@ -494,6 +496,7 @@ int main(int argc, char *argv[]) { // dump markup if (strcmp(argv[i], "-m") == 0 || strcmp(argv[i], "--markdown") == 0) { + g_disableLogging = true; dumpAllHelp(1); return 0; } diff --git a/client/ui.c b/client/ui.c index 68c8b197c..2055ab972 100644 --- a/client/ui.c +++ b/client/ui.c @@ -223,7 +223,7 @@ static void fPrintAndLog(FILE *stream, const char *fmt, ...) { // lock this section to avoid interlacing prints from different threads pthread_mutex_lock(&print_lock); - if (logging && !logfile) { + if (!g_disableLogging && logging && !logfile) { char *my_logfile_path = NULL; char filename[40]; struct tm *timenow; @@ -284,7 +284,7 @@ static void fPrintAndLog(FILE *stream, const char *fmt, ...) { } #endif - if (logging && logfile) { + if (!g_disableLogging && logging && logfile) { if (filter_ansi) { // already done fprintf(logfile, "%s\n", buffer2); } else { diff --git a/client/util.c b/client/util.c index 52321689b..2261684e9 100644 --- a/client/util.c +++ b/client/util.c @@ -28,6 +28,8 @@ #define UTIL_BUFFER_SIZE_SPRINT 4097 // global client debug variable uint8_t g_debugMode = 0; +// global client disable logging variable +bool g_disableLogging = false; #ifdef _WIN32 #include diff --git a/client/util.h b/client/util.h index 09aeeaecb..072c04cfb 100644 --- a/client/util.h +++ b/client/util.h @@ -22,6 +22,7 @@ #endif uint8_t g_debugMode; +bool g_disableLogging; int kbd_enter_pressed(void); void AddLogLine(const char *fn, const char *data, const char *c); From e10085bfe82c62eadcdf1776574ac6e64ffcf0c7 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 9 Sep 2019 21:30:25 +0200 Subject: [PATCH 0641/1854] log interactive commands as well --- client/proxmark3.c | 21 ++++++++++++--------- client/ui.c | 12 +++++++----- client/util.c | 2 +- client/util.h | 4 +++- 4 files changed, 23 insertions(+), 16 deletions(-) diff --git a/client/proxmark3.c b/client/proxmark3.c index 58b082078..dbca25d17 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -117,6 +117,7 @@ main_loop(char *script_cmds_file, char *script_cmd, bool stayInCommandLoop) { // loops every time enter is pressed... while (1) { bool printprompt = false; + char *prompt = PROXPROMPT; // If there is a script file if (sf) { @@ -171,12 +172,12 @@ main_loop(char *script_cmds_file, char *script_cmd, bool stayInCommandLoop) { rl_event_hook = check_comm; if (session.pm3_present) { if (conn.send_via_fpc_usart == false) - cmd = readline(PROXPROMPT_USB); + prompt = PROXPROMPT_USB; else - cmd = readline(PROXPROMPT_FPC); + prompt = PROXPROMPT_FPC; } else - cmd = readline(PROXPROMPT_OFFLINE); - + prompt = PROXPROMPT_OFFLINE; + cmd = readline(prompt); fflush(NULL); } } @@ -199,8 +200,10 @@ main_loop(char *script_cmds_file, char *script_cmd, bool stayInCommandLoop) { cmd[strlen(cmd) - off] = '\0'; if (cmd[0] != '\0') { - if (printprompt) - PrintAndLogEx(NORMAL, PROXPROMPT"%s", cmd); + if (!printprompt) + g_printAndLog = PRINTANDLOG_LOG; + PrintAndLogEx(NORMAL, "%s%s", prompt, cmd); + g_printAndLog = PRINTANDLOG_PRINT | PRINTANDLOG_LOG; int ret = CommandReceived(cmd); @@ -481,14 +484,14 @@ int main(int argc, char *argv[]) { // short help if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) { - g_disableLogging = true; + g_printAndLog = PRINTANDLOG_PRINT; show_help(true, exec_name); return 0; } // dump help if (strcmp(argv[i], "-t") == 0 || strcmp(argv[i], "--text") == 0) { - g_disableLogging = true; + g_printAndLog = PRINTANDLOG_PRINT; show_help(false, exec_name); dumpAllHelp(0); return 0; @@ -496,7 +499,7 @@ int main(int argc, char *argv[]) { // dump markup if (strcmp(argv[i], "-m") == 0 || strcmp(argv[i], "--markdown") == 0) { - g_disableLogging = true; + g_printAndLog = PRINTANDLOG_PRINT; dumpAllHelp(1); return 0; } diff --git a/client/ui.c b/client/ui.c index 2055ab972..883ea963a 100644 --- a/client/ui.c +++ b/client/ui.c @@ -223,7 +223,7 @@ static void fPrintAndLog(FILE *stream, const char *fmt, ...) { // lock this section to avoid interlacing prints from different threads pthread_mutex_lock(&print_lock); - if (!g_disableLogging && logging && !logfile) { + if ((g_printAndLog & PRINTANDLOG_LOG) && logging && !logfile) { char *my_logfile_path = NULL; char filename[40]; struct tm *timenow; @@ -269,9 +269,11 @@ static void fPrintAndLog(FILE *stream, const char *fmt, ...) { bool filter_ansi = !session.supports_colors; memcpy_filter_ansi(buffer2, buffer, sizeof(buffer), filter_ansi); - fprintf(stream, "%s", buffer2); - fprintf(stream, " "); // cleaning prompt - fprintf(stream, "\n"); + if (g_printAndLog & PRINTANDLOG_PRINT) { + fprintf(stream, "%s", buffer2); + fprintf(stream, " "); // cleaning prompt + fprintf(stream, "\n"); + } #ifdef RL_STATE_READCMD // We are using GNU readline. libedit (OSX) doesn't support this flag. @@ -284,7 +286,7 @@ static void fPrintAndLog(FILE *stream, const char *fmt, ...) { } #endif - if (!g_disableLogging && logging && logfile) { + if ((g_printAndLog & PRINTANDLOG_LOG) && logging && logfile) { if (filter_ansi) { // already done fprintf(logfile, "%s\n", buffer2); } else { diff --git a/client/util.c b/client/util.c index 2261684e9..1f5a29781 100644 --- a/client/util.c +++ b/client/util.c @@ -29,7 +29,7 @@ // global client debug variable uint8_t g_debugMode = 0; // global client disable logging variable -bool g_disableLogging = false; +uint8_t g_printAndLog = PRINTANDLOG_PRINT | PRINTANDLOG_LOG; #ifdef _WIN32 #include diff --git a/client/util.h b/client/util.h index 072c04cfb..7cfea0f8b 100644 --- a/client/util.h +++ b/client/util.h @@ -22,7 +22,9 @@ #endif uint8_t g_debugMode; -bool g_disableLogging; +uint8_t g_printAndLog; +#define PRINTANDLOG_PRINT 1 +#define PRINTANDLOG_LOG 2 int kbd_enter_pressed(void); void AddLogLine(const char *fn, const char *data, const char *c); From d08f03058bc9680cd39c427b8adac87aa0a44429 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 9 Sep 2019 23:46:38 +0200 Subject: [PATCH 0642/1854] add support for (nested) cmd scripts in script list/run --- client/cmdscript.c | 102 ++++++++++++++++++++++++++------------------- client/fileutils.c | 1 + client/proxmark3.c | 63 +++++++++++++++++++++------- client/proxmark3.h | 2 + 4 files changed, 111 insertions(+), 57 deletions(-) diff --git a/client/cmdscript.c b/client/cmdscript.c index 473477228..a721acee5 100644 --- a/client/cmdscript.c +++ b/client/cmdscript.c @@ -33,7 +33,10 @@ static int CmdHelp(const char *Cmd); */ static int CmdScriptList(const char *Cmd) { (void)Cmd; // Cmd is not used so far - return searchAndList(LUA_SCRIPTS_SUBDIR, ".lua"); + int ret = searchAndList(LUA_SCRIPTS_SUBDIR, ".lua"); + if (ret != PM3_SUCCESS) + return ret; + return searchAndList(CMD_SCRIPTS_SUBDIR, ".cmd"); } /** @@ -43,21 +46,6 @@ static int CmdScriptList(const char *Cmd) { * @return */ static int CmdScriptRun(const char *Cmd) { - // create new Lua state - lua_State *lua_state; - lua_state = luaL_newstate(); - - // load Lua libraries - luaL_openlibs(lua_state); - - //Sets the pm3 core libraries, that go a bit 'under the hood' - set_pm3_libraries(lua_state); - - //Add the 'bin' library - set_bin_library(lua_state); - - //Add the 'bit' library - set_bit_library(lua_state); char preferredName[128] = {0}; char arguments[256] = {0}; @@ -67,37 +55,65 @@ static int CmdScriptRun(const char *Cmd) { sscanf(Cmd, "%127s%n %255[^\n\r]%n", preferredName, &name_len, arguments, &arg_len); char *script_path; - int res = searchFile(&script_path, LUA_SCRIPTS_SUBDIR, preferredName, ".lua", false); - if (res != PM3_SUCCESS) - return res; + if ((!str_endswith(preferredName, ".cmd")) && (searchFile(&script_path, LUA_SCRIPTS_SUBDIR, preferredName, ".lua", true) == PM3_SUCCESS)) { + int error; + PrintAndLogEx(SUCCESS, "Executing Lua script: %s, args '%s'\n", script_path, arguments); - int error; - PrintAndLogEx(SUCCESS, "Executing: %s, args '%s'\n", script_path, arguments); - error = luaL_loadfile(lua_state, script_path); - free(script_path); - if (!error) { - lua_pushstring(lua_state, arguments); - lua_setglobal(lua_state, "args"); + // create new Lua state + lua_State *lua_state; + lua_state = luaL_newstate(); - //Call it with 0 arguments - error = lua_pcall(lua_state, 0, LUA_MULTRET, 0); // once again, returns non-0 on error, + // load Lua libraries + luaL_openlibs(lua_state); + + //Sets the pm3 core libraries, that go a bit 'under the hood' + set_pm3_libraries(lua_state); + + //Add the 'bin' library + set_bin_library(lua_state); + + //Add the 'bit' library + set_bit_library(lua_state); + + error = luaL_loadfile(lua_state, script_path); + free(script_path); + if (!error) { + lua_pushstring(lua_state, arguments); + lua_setglobal(lua_state, "args"); + + //Call it with 0 arguments + error = lua_pcall(lua_state, 0, LUA_MULTRET, 0); // once again, returns non-0 on error, + } + if (error) { // if non-0, then an error + // the top of the stack should be the error string + if (!lua_isstring(lua_state, lua_gettop(lua_state))) + PrintAndLogEx(FAILED, "Error - but no error (?!)"); + + // get the top of the stack as the error and pop it off + const char *str = lua_tostring(lua_state, lua_gettop(lua_state)); + lua_pop(lua_state, 1); + puts(str); + } + + //luaL_dofile(lua_state, buf); + // close the Lua state + lua_close(lua_state); + PrintAndLogEx(SUCCESS, "\nFinished\n"); + return PM3_SUCCESS; } - if (error) { // if non-0, then an error - // the top of the stack should be the error string - if (!lua_isstring(lua_state, lua_gettop(lua_state))) - PrintAndLogEx(FAILED, "Error - but no error (?!)"); - - // get the top of the stack as the error and pop it off - const char *str = lua_tostring(lua_state, lua_gettop(lua_state)); - lua_pop(lua_state, 1); - puts(str); + if ((!str_endswith(preferredName, ".lua")) && (searchFile(&script_path, CMD_SCRIPTS_SUBDIR, preferredName, ".cmd", true) == PM3_SUCCESS)) { + PrintAndLogEx(SUCCESS, "Executing Cmd script: %s, args '%s'\n", script_path, arguments); + int ret = push_cmdscriptfile(script_path, true); + if (ret != PM3_SUCCESS) + PrintAndLogEx(ERR, "could not open " _YELLOW_("%s") "...", script_path); + free(script_path); + return ret; } - - //luaL_dofile(lua_state, buf); - // close the Lua state - lua_close(lua_state); - PrintAndLogEx(SUCCESS, "\nFinished\n"); - return 0; + // file not found, let's search again to display the error messages + int ret = PM3_EUNDEF; + if (!str_endswith(preferredName, ".cmd")) ret = searchFile(&script_path, LUA_SCRIPTS_SUBDIR, preferredName, ".lua", false); + if (!str_endswith(preferredName, ".lua")) ret = searchFile(&script_path, CMD_SCRIPTS_SUBDIR, preferredName, ".cmd", false); + return ret; } static command_t CommandTable[] = { diff --git a/client/fileutils.c b/client/fileutils.c index f379f56d3..8e0e3bb72 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -933,6 +933,7 @@ static int searchFinalFile(char **foundpath, const char *pm3dir, const char *sea ((strcmp(DICTIONARIES_SUBDIR, pm3dir) == 0) || (strcmp(LUA_LIBRARIES_SUBDIR, pm3dir) == 0) || (strcmp(LUA_SCRIPTS_SUBDIR, pm3dir) == 0) || + (strcmp(CMD_SCRIPTS_SUBDIR, pm3dir) == 0) || (strcmp(RESOURCES_SUBDIR, pm3dir) == 0))) { char *path = calloc(strlen(exec_path) + strlen(pm3dir) + strlen(filename) + 1, sizeof(char)); if (path == NULL) diff --git a/client/proxmark3.c b/client/proxmark3.c index dbca25d17..aa37cda9a 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -63,6 +63,38 @@ int check_comm(void) { return 0; } +// first slot is always NULL, indicating absence of script when idx=0 +FILE *cmdscriptfile[MAX_NESTED_CMDSCRIPT + 1] = {0}; +uint8_t cmdscriptfile_idx = 0; +bool cmdscriptfile_stayafter = false; + +int push_cmdscriptfile(char *path, bool stayafter) { + if (cmdscriptfile_idx == MAX_NESTED_CMDSCRIPT) { + PrintAndLogEx(ERR, "Too many nested scripts, skipping %s\n", path); + return PM3_EMALLOC; + } + FILE *tmp = fopen(path, "r"); + if (tmp == NULL) + return PM3_EFILE; + if (cmdscriptfile_idx == 0) + cmdscriptfile_stayafter = stayafter; + cmdscriptfile[++cmdscriptfile_idx] = tmp; + return PM3_SUCCESS; +} + +FILE *current_cmdscriptfile() { + return cmdscriptfile[cmdscriptfile_idx]; +} + +bool pop_cmdscriptfile() { + fclose(cmdscriptfile[cmdscriptfile_idx]); + cmdscriptfile[cmdscriptfile_idx--] = NULL; + if (cmdscriptfile_idx == 0) + return cmdscriptfile_stayafter; + else + return true; +} + // Main thread of PM3 Client void #ifdef __has_attribute @@ -80,7 +112,6 @@ main_loop(char *script_cmds_file, char *script_cmd, bool stayInCommandLoop) { strcreplace(script_cmd, script_cmd_len, ';', '\0'); } bool stdinOnPipe = !isatty(STDIN_FILENO); - FILE *sf = NULL; char script_cmd_buf[256] = {0x00}; // iceman, needs lua script the same file_path_buffer as the rest PrintAndLogEx(DEBUG, "ISATTY/STDIN_FILENO == %s\n", (stdinOnPipe) ? "true" : "false"); @@ -98,8 +129,7 @@ main_loop(char *script_cmds_file, char *script_cmd, bool stayInCommandLoop) { char *path; int res = searchFile(&path, CMD_SCRIPTS_SUBDIR, script_cmds_file, ".cmd", false); if (res == PM3_SUCCESS) { - sf = fopen(path, "r"); - if (sf) + if (push_cmdscriptfile(path, stayInCommandLoop) == PM3_SUCCESS) PrintAndLogEx(SUCCESS, "executing commands from file: %s\n", path); else PrintAndLogEx(ERR, "could not open " _YELLOW_("%s") "...", path); @@ -119,16 +149,18 @@ main_loop(char *script_cmds_file, char *script_cmd, bool stayInCommandLoop) { bool printprompt = false; char *prompt = PROXPROMPT; +check_script: // If there is a script file - if (sf) { + if (current_cmdscriptfile()) { // clear array memset(script_cmd_buf, 0, sizeof(script_cmd_buf)); // read script file - if (!fgets(script_cmd_buf, sizeof(script_cmd_buf), sf)) { - fclose(sf); - sf = NULL; + if (!fgets(script_cmd_buf, sizeof(script_cmd_buf), current_cmdscriptfile())) { + if (!pop_cmdscriptfile()) + break; + goto check_script; } else { // remove linebreaks @@ -205,12 +237,15 @@ main_loop(char *script_cmds_file, char *script_cmd, bool stayInCommandLoop) { PrintAndLogEx(NORMAL, "%s%s", prompt, cmd); g_printAndLog = PRINTANDLOG_PRINT | PRINTANDLOG_LOG; + // add to history if not from a script + if (!current_cmdscriptfile()) { + HIST_ENTRY *entry = history_get(history_length); + // add if not identical to latest recorded cmd + if ((!entry) || (strcmp(entry->line, cmd) != 0)) + add_history(cmd); + } + // process cmd int ret = CommandReceived(cmd); - - HIST_ENTRY *entry = history_get(history_length); - if ((!entry) || (strcmp(entry->line, cmd) != 0)) - add_history(cmd); - // exit or quit if (ret == PM3_EFATAL) break; @@ -230,8 +265,8 @@ main_loop(char *script_cmds_file, char *script_cmd, bool stayInCommandLoop) { SendCommandNG(CMD_QUIT_SESSION, NULL, 0); msleep(100); // Make sure command is sent before killing client - if (sf) - fclose(sf); + while (current_cmdscriptfile()) + pop_cmdscriptfile(); if (my_history_path) { write_history(my_history_path); diff --git a/client/proxmark3.h b/client/proxmark3.h index 3da261c31..14148747c 100644 --- a/client/proxmark3.h +++ b/client/proxmark3.h @@ -20,11 +20,13 @@ #define PROXPROMPT_OFFLINE "[offline] pm3 --> " #define PROXHISTORY "history.txt" #define PROXLOG "log_%Y%m%d.txt" +#define MAX_NESTED_CMDSCRIPT 10 #ifdef __cplusplus extern "C" { #endif +int push_cmdscriptfile(char *path, bool stayafter); const char *get_my_executable_path(void); const char *get_my_executable_directory(void); void main_loop(char *script_cmds_file, char *script_cmd, bool stayInCommandLoop); From 608e0ba27c7aae1f41a4d30c03cc1ea8474f7cd1 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 10 Sep 2019 00:06:16 +0200 Subject: [PATCH 0643/1854] fix plot strange values --- client/proxguiqt.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/proxguiqt.cpp b/client/proxguiqt.cpp index 344f48b03..6bf99f5a1 100644 --- a/client/proxguiqt.cpp +++ b/client/proxguiqt.cpp @@ -535,7 +535,7 @@ void Plot::paintEvent(QPaintEvent *event) { sprintf(str, "@%d dt=%d [%2.2f] zoom=%2.2f CursorAPos=%d CursorBPos=%d GridX=%d GridY=%d (%s) GridXoffset=%d", GraphStart, CursorBPos - CursorAPos, - (CursorBPos - CursorAPos) / CursorScaleFactor, + ((int32_t)(CursorBPos - CursorAPos)) / CursorScaleFactor, GraphPixelsPerPoint, CursorAPos, CursorBPos, From 843f554503a1fa1876964cc6da14c1626187cc4e Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 10 Sep 2019 12:32:01 +0200 Subject: [PATCH 0644/1854] prevent lua bombs --- client/cmdscript.c | 9 ++++++++- client/proxmark3.h | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/client/cmdscript.c b/client/cmdscript.c index a721acee5..6d7858d54 100644 --- a/client/cmdscript.c +++ b/client/cmdscript.c @@ -52,12 +52,18 @@ static int CmdScriptRun(const char *Cmd) { int name_len = 0; int arg_len = 0; + static uint8_t luascriptfile_idx = 0; sscanf(Cmd, "%127s%n %255[^\n\r]%n", preferredName, &name_len, arguments, &arg_len); char *script_path; if ((!str_endswith(preferredName, ".cmd")) && (searchFile(&script_path, LUA_SCRIPTS_SUBDIR, preferredName, ".lua", true) == PM3_SUCCESS)) { int error; + if (luascriptfile_idx == MAX_NESTED_LUASCRIPT) { + PrintAndLogEx(ERR, "Too many nested scripts, skipping %s\n", script_path); + return PM3_EMALLOC; + } PrintAndLogEx(SUCCESS, "Executing Lua script: %s, args '%s'\n", script_path, arguments); + luascriptfile_idx++; // create new Lua state lua_State *lua_state; @@ -98,7 +104,8 @@ static int CmdScriptRun(const char *Cmd) { //luaL_dofile(lua_state, buf); // close the Lua state lua_close(lua_state); - PrintAndLogEx(SUCCESS, "\nFinished\n"); + luascriptfile_idx--; + PrintAndLogEx(SUCCESS, "\nFinished %s\n", preferredName); return PM3_SUCCESS; } if ((!str_endswith(preferredName, ".lua")) && (searchFile(&script_path, CMD_SCRIPTS_SUBDIR, preferredName, ".cmd", true) == PM3_SUCCESS)) { diff --git a/client/proxmark3.h b/client/proxmark3.h index 14148747c..c370efdff 100644 --- a/client/proxmark3.h +++ b/client/proxmark3.h @@ -21,6 +21,7 @@ #define PROXHISTORY "history.txt" #define PROXLOG "log_%Y%m%d.txt" #define MAX_NESTED_CMDSCRIPT 10 +#define MAX_NESTED_LUASCRIPT 10 #ifdef __cplusplus extern "C" { From 1966e23e4d1bc36663cc81c9fd5fe23d8c6c7e38 Mon Sep 17 00:00:00 2001 From: Victor Date: Wed, 11 Sep 2019 00:51:29 +0300 Subject: [PATCH 0645/1854] Fix vscode tasks --- .vscode/tasks.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.vscode/tasks.json b/.vscode/tasks.json index ca3660980..20b68be0e 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -14,13 +14,13 @@ { "label": "flash fullimage", "type": "shell", - "command": "./flash-fullimage.sh", + "command": "sudo ./pm3-flash-fullimage", "problemMatcher": [] }, { "label": "FLASH BOOTROM", "type": "shell", - "command": "./flash-bootrom.sh", + "command": "sudo ./pm3-flash-bootrom", "problemMatcher": [] } ] From 341703d9a7de1fa81177e75f8ffe241214908cfc Mon Sep 17 00:00:00 2001 From: Iceman Date: Wed, 11 Sep 2019 13:09:08 +0200 Subject: [PATCH 0646/1854] chg: 'hf iclass sim' - better iClass protocol implementation --- armsrc/iclass.c | 56 +++++++++++++++++++++++---------------------- client/cmdhflist.c | 55 ++++++++++++++++++++++++++------------------ include/protocols.h | 27 +++++++++++----------- 3 files changed, 75 insertions(+), 63 deletions(-) diff --git a/armsrc/iclass.c b/armsrc/iclass.c index c87bade4b..08f05857b 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -1435,6 +1435,7 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) { uint32_t r2t_stime, r2t_etime = 0; LED_A_ON(); bool buttonPressed = false; + uint8_t cmd, options, block; while (!exitLoop) { WDT_HIT(); @@ -1455,7 +1456,11 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) { LED_C_ON(); //Signal tracer - if (receivedCmd[0] == ICLASS_CMD_ACTALL) { // 0x0A + cmd = receivedCmd[0] & 0xF; + options = (receivedCmd[0] >> 4) & 0xFF; + block = receivedCmd[1]; + + if (cmd == ICLASS_CMD_ACTALL) { // 0x0A // Reader in anticollission phase modulated_response = resp_sof; modulated_response_size = resp_sof_Len; //order = 1; @@ -1463,7 +1468,7 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) { trace_data_size = sizeof(sof_data); // adjusted for 330 + (160*num of slot) goto send; - } else if (receivedCmd[0] == ICLASS_CMD_READ_OR_IDENTIFY) { // 0x0C + } else if (cmd == ICLASS_CMD_READ_OR_IDENTIFY) { // 0x0C if (len == 1) { // Reader asks for anticollission CSN modulated_response = resp_anticoll; @@ -1475,7 +1480,7 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) { if (len == 4) { // block0,1,2,5 is always readable. - switch (receivedCmd[1]) { + switch (block) { case 0: // csn (0c 00) modulated_response = resp_csn; modulated_response_size = resp_csn_len; @@ -1508,7 +1513,7 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) { if (simulationMode == MODE_FULLSIM) { // 0x0C //Read block //Take the data... - memcpy(data_generic_trace, emulator + (receivedCmd[1] << 3), 8); + memcpy(data_generic_trace, emulator + (block << 3), 8); AddCrc(data_generic_trace, 8); trace_data = data_generic_trace; trace_data_size = 10; @@ -1521,7 +1526,7 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) { } }//swith }// if 4 - } else if (receivedCmd[0] == ICLASS_CMD_SELECT) { // 0x81 + } else if (cmd == ICLASS_CMD_SELECT) { // 0x81 // Reader selects anticollission CSN. // Tag sends the corresponding real CSN modulated_response = resp_csn; @@ -1529,23 +1534,15 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) { trace_data = csn_data; trace_data_size = sizeof(csn_data); goto send; - } else if (receivedCmd[0] == ICLASS_CMD_READCHECK_KD) { // 0x88 - // Read e-purse (88 02) + } else if (cmd == ICLASS_CMD_READCHECK ) { // 0x88 + // Read e-purse KD (88 02) KC (18 02) modulated_response = resp_cc; modulated_response_size = resp_cc_len; //order = 4; trace_data = card_challenge_data; trace_data_size = sizeof(card_challenge_data); LED_B_ON(); goto send; - } else if (receivedCmd[0] == ICLASS_CMD_READCHECK_KC) { // 0x18 - // Read e-purse (18 02) - modulated_response = resp_cc; - modulated_response_size = resp_cc_len; //order = 4; - trace_data = card_challenge_data; - trace_data_size = sizeof(card_challenge_data); - LED_B_ON(); - goto send; - } else if (receivedCmd[0] == ICLASS_CMD_CHECK) { // 0x05 + } else if (cmd == ICLASS_CMD_CHECK) { // 0x05 // Reader random and reader MAC!!! if (simulationMode == MODE_FULLSIM) { // NR, from reader, is in receivedCmd +1 @@ -1583,17 +1580,17 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) { } } goto send; - } else if (receivedCmd[0] == ICLASS_CMD_HALT && len == 1) { + } else if (cmd == ICLASS_CMD_HALT && options == 0 && len == 1) { // Reader ends the session modulated_response = resp_sof; modulated_response_size = 0; //order = 0; trace_data = NULL; trace_data_size = 0; goto send; - } else if (simulationMode == MODE_FULLSIM && receivedCmd[0] == ICLASS_CMD_READ4 && len == 4) { // 0x06 + } else if (simulationMode == MODE_FULLSIM && cmd == ICLASS_CMD_READ4 && len == 4) { // 0x06 //Read block //Take the data... - memcpy(data_generic_trace, emulator + (receivedCmd[1] << 3), 8 * 4); + memcpy(data_generic_trace, emulator + (block << 3), 8 * 4); AddCrc(data_generic_trace, 8 * 4); trace_data = data_generic_trace; trace_data_size = 34; @@ -1601,7 +1598,7 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) { memcpy(modulated_response, ToSend, ToSendMax); modulated_response_size = ToSendMax; goto send; - } else if (simulationMode == MODE_FULLSIM && receivedCmd[0] == ICLASS_CMD_UPDATE) { + } else if (simulationMode == MODE_FULLSIM && cmd == ICLASS_CMD_UPDATE) { //Probably the reader wants to update the nonce. Let's just ignore that for now. // OBS! If this is implemented, don't forget to regenerate the cipher_state @@ -1854,6 +1851,7 @@ static int GetIClassAnswer(uint8_t *receivedResponse, int maxLen, int *samples, SpinDelayUs(g_wait); //310 Tout= 330us (iso15603-2) (330/21.3) take consideration for clock increments. uint32_t foo = GetCountSspClk(); + uint32_t bar; // clear RXRDY: uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; @@ -1892,7 +1890,11 @@ static int GetIClassAnswer(uint8_t *receivedResponse, int maxLen, int *samples, return true; } - if (GetCountSspClk() - foo > timeout) return false; + bar = GetCountSspClk(); + if ( foo > bar ) + bar += ( UINT32_MAX - foo ); + + if (bar - foo > timeout) return false; } } @@ -1985,10 +1987,10 @@ uint8_t handshakeIclassTag_ext(uint8_t *card_data, bool use_credit_key) { static uint8_t act_all[] = { ICLASS_CMD_ACTALL }; static uint8_t identify[] = { ICLASS_CMD_READ_OR_IDENTIFY, 0x00, 0x73, 0x33 }; static uint8_t select[] = { ICLASS_CMD_SELECT, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - uint8_t readcheck_cc[] = { ICLASS_CMD_READCHECK_KD, 0x02 }; + uint8_t readcheck_cc[] = { ICLASS_CMD_READCHECK, 0x02 }; - if (use_credit_key) - readcheck_cc[0] = ICLASS_CMD_READCHECK_KC; + if (use_credit_key == false) + readcheck_cc[0] |= 0x10; uint8_t resp[ICLASS_BUFFER_SIZE] = {0}; uint8_t read_status = 0; @@ -2353,10 +2355,10 @@ void iClass_Authentication_fast(uint64_t arg0, uint64_t arg1, uint8_t *datain) { uint8_t keyCount = arg1 & 0xFF; uint8_t check[] = { ICLASS_CMD_CHECK, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; uint8_t resp[ICLASS_BUFFER_SIZE]; - uint8_t readcheck_cc[] = { ICLASS_CMD_READCHECK_KD, 0x02 }; + uint8_t readcheck_cc[] = { ICLASS_CMD_READCHECK, 0x02 }; - if (use_credit_key) - readcheck_cc[0] = ICLASS_CMD_READCHECK_KC; + if (use_credit_key == false) + readcheck_cc[0] |= 0x10; // select card / e-purse uint8_t card_data[6 * 8] = {0}; diff --git a/client/cmdhflist.c b/client/cmdhflist.c index 5a2ff5248..d0fcea8f5 100644 --- a/client/cmdhflist.c +++ b/client/cmdhflist.c @@ -323,10 +323,35 @@ void annotateIso14443a(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) { } void annotateIclass(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) { - switch (cmd[0]) { + uint8_t c = cmd[0] & 0x0F; + uint8_t parity = 0; + for ( uint8_t i=0; i<7; i++) { + parity ^= (cmd[0] >> i) & 1; + } + + if ( parity == ((cmd[0] >> 7) & 1) ) { + printf("Calc %d, cmd %02x, Par %d \n", parity, cmd[0], (cmd[0] >> 7) & 1); + } + + switch (c) { + case ICLASS_CMD_HALT: + snprintf(exp, size, "HALT"); + break; + case ICLASS_CMD_SELECT: + snprintf(exp, size, "SELECT"); + break; case ICLASS_CMD_ACTALL: snprintf(exp, size, "ACTALL"); break; + case ICLASS_CMD_DETECT: + snprintf(exp, size, "DETECT"); + break; + case ICLASS_CMD_CHECK: + snprintf(exp, size, "CHECK"); + break; + case ICLASS_CMD_READ4: + snprintf(exp, size, "READ4(%d)", cmd[1]); + break; case ICLASS_CMD_READ_OR_IDENTIFY: { if (cmdsize > 1) { snprintf(exp, size, "READ(%d)", cmd[1]); @@ -335,36 +360,22 @@ void annotateIclass(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) { } break; } - case ICLASS_CMD_SELECT: - snprintf(exp, size, "SELECT"); - break; case ICLASS_CMD_PAGESEL: snprintf(exp, size, "PAGESEL(%d)", cmd[1]); break; - case ICLASS_CMD_READCHECK_KC: - snprintf(exp, size, "READCHECK[Kc](%d)", cmd[1]); - break; - case ICLASS_CMD_READCHECK_KD: - snprintf(exp, size, "READCHECK[Kd](%d)", cmd[1]); - break; - case ICLASS_CMD_CHECK: - snprintf(exp, size, "CHECK"); - break; - case ICLASS_CMD_DETECT: - snprintf(exp, size, "DETECT"); - break; - case ICLASS_CMD_HALT: - snprintf(exp, size, "HALT"); - break; case ICLASS_CMD_UPDATE: snprintf(exp, size, "UPDATE(%d)", cmd[1]); break; + case ICLASS_CMD_READCHECK: + if ( ICLASS_CREDIT(c) ) { + snprintf(exp, size, "READCHECK[Kc](%d)", cmd[1]); + } else { + snprintf(exp, size, "READCHECK[Kd](%d)", cmd[1]); + } + break; case ICLASS_CMD_ACT: snprintf(exp, size, "ACT"); break; - case ICLASS_CMD_READ4: - snprintf(exp, size, "READ4(%d)", cmd[1]); - break; default: snprintf(exp, size, "?"); break; diff --git a/include/protocols.h b/include/protocols.h index cb38d9c84..9b47266c3 100644 --- a/include/protocols.h +++ b/include/protocols.h @@ -120,22 +120,21 @@ ISO 7816-4 Basic interindustry commands. For command APDU's. // for instance ICLASS_CMD_SELECT 0x81 tells if ISO14443b/BPSK coding/106 kbits/s // for instance ICLASS_CMD_SELECT 0x41 tells if ISO14443b/BPSK coding/423 kbits/s // -#define ICLASS_CMD_HALT 0x00 -#define ICLASS_CMD_SELECT_15 0x01 -#define ICLASS_CMD_ACTALL 0x0A -#define ICLASS_CMD_DETECT 0x0F +#define ICLASS_CMD_HALT 0x0 +#define ICLASS_CMD_SELECT 0x1 +#define ICLASS_CMD_ACTALL 0xA +#define ICLASS_CMD_DETECT 0xF -#define ICLASS_CMD_CHECK 0x05 -#define ICLASS_CMD_READ4 0x06 -#define ICLASS_CMD_READ_OR_IDENTIFY 0x0C - -#define ICLASS_CMD_SELECT 0x81 -#define ICLASS_CMD_PAGESEL 0x84 -#define ICLASS_CMD_UPDATE 0x87 -#define ICLASS_CMD_READCHECK_KC 0x18 -#define ICLASS_CMD_READCHECK_KD 0x88 -#define ICLASS_CMD_ACT 0x8E +#define ICLASS_CMD_PAGESEL 0x4 +#define ICLASS_CMD_CHECK 0x5 +#define ICLASS_CMD_READ4 0x6 +#define ICLASS_CMD_UPDATE 0x7 +#define ICLASS_CMD_READCHECK 0x8 +#define ICLASS_CMD_READ_OR_IDENTIFY 0xC +#define ICLASS_CMD_ACT 0xE +#define ICLASS_CREDIT(x) (((x) & 0x5) == 1) +#define ICLASS_DEBIT(x) (((x) & 0x5) == 0) #define ISO14443A_CMD_REQA 0x26 From 387dd82895dc427e11d6176b643b7a04c4b71765 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 11 Sep 2019 14:03:14 +0200 Subject: [PATCH 0647/1854] chg 'hf iclass list' - fix parity checks --- client/cmdhflist.c | 4 ---- client/cmdtrace.c | 14 +++++++++++++- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/client/cmdhflist.c b/client/cmdhflist.c index d0fcea8f5..d44ac635c 100644 --- a/client/cmdhflist.c +++ b/client/cmdhflist.c @@ -329,10 +329,6 @@ void annotateIclass(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) { parity ^= (cmd[0] >> i) & 1; } - if ( parity == ((cmd[0] >> 7) & 1) ) { - printf("Calc %d, cmd %02x, Par %d \n", parity, cmd[0], (cmd[0] >> 7) & 1); - } - switch (c) { case ICLASS_CMD_HALT: snprintf(exp, size, "HALT"); diff --git a/client/cmdtrace.c b/client/cmdtrace.c index ecb3fc158..401dac66e 100644 --- a/client/cmdtrace.c +++ b/client/cmdtrace.c @@ -294,6 +294,8 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr uint8_t parityBits = parityBytes[j >> 3]; if (protocol != LEGIC && protocol != ISO_14443B + && protocol != ISO_15693 + && protocol != ICLASS && protocol != ISO_7816_4 && protocol != PROTO_HITAG && protocol != THINFILM @@ -301,7 +303,17 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr && (oddparity8(frame[j]) != ((parityBits >> (7 - (j & 0x0007))) & 0x01))) { snprintf(line[j / 18] + ((j % 18) * 4), 110, "%02x! ", frame[j]); - } else { + } else if ( protocol == ICLASS && isResponse == true) { + uint8_t parity = 0; + for (int i=0; i<6; i++) { + parity ^= ((frame[0] >> i) & 1); + } + if ( parity == ((frame[0] >> 7) & 1)) { + snprintf(line[j / 18] + ((j % 18) * 4), 110, "%02x ", frame[j]); + } else { + snprintf(line[j / 18] + ((j % 18) * 4), 110, "%02x! ", frame[j]); + } + } else { snprintf(line[j / 18] + ((j % 18) * 4), 110, "%02x ", frame[j]); } From df2c294cac9e4e9edae5ac0fd77b04561bd60960 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 11 Sep 2019 15:15:13 +0200 Subject: [PATCH 0648/1854] chg - cleaning out testcode... --- armsrc/iso14443a.c | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 786db50dc..794ead3c5 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -1672,26 +1672,11 @@ static void TransmitFor14443a(const uint8_t *cmd, uint16_t len, uint32_t *timing // clear TXRDY AT91C_BASE_SSC->SSC_THR = SEC_Y; - volatile uint8_t b; uint16_t c = 0; - uint32_t sendtimer = GetTickCount(); - uint32_t cntr = 0; while (c < len) { if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { - AT91C_BASE_SSC->SSC_THR = cmd[c++]; - cntr = 0; - } else { - if (cntr++ > 1000) { - cntr = 0; - if (GetTickCount() - sendtimer > 100) - break; - } - } - - //iceman test - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { - b = (uint16_t)(AT91C_BASE_SSC->SSC_RHR); - (void)b; + AT91C_BASE_SSC->SSC_THR = cmd[c]; + c++; } } From ff66ea896b11893b1b05f0e8498c1db92ea6630b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 11 Sep 2019 15:16:20 +0200 Subject: [PATCH 0649/1854] ssp clock delta --- armsrc/ticks.c | 7 +++++++ armsrc/ticks.h | 1 + 2 files changed, 8 insertions(+) diff --git a/armsrc/ticks.c b/armsrc/ticks.c index 43555b21b..1510de490 100644 --- a/armsrc/ticks.c +++ b/armsrc/ticks.c @@ -185,6 +185,13 @@ uint32_t RAMFUNC GetCountSspClk(void) { return tmp_count; } +uint32_t RAMFUNC GetCountSspClkDelta(uint32_t start) { + uint32_t stop = GetCountSspClk(); + if ( stop >= start ) + return stop - start; + return (UINT32_MAX - start) + stop; +} + // ------------------------------------------------------------------------- // Timer for bitbanging, or LF stuff when you need a very precis timer // 1us = 1.5ticks diff --git a/armsrc/ticks.h b/armsrc/ticks.h index 089501c87..e036e018c 100644 --- a/armsrc/ticks.h +++ b/armsrc/ticks.h @@ -33,6 +33,7 @@ void SpinDelayCountUs(uint32_t us); void StartCountSspClk(); void ResetSspClk(void); uint32_t RAMFUNC GetCountSspClk(); +uint32_t RAMFUNC GetCountSspClkDelta(); void StartTicks(void); uint32_t GetTicks(void); From 105665ed0acf5abbcfd52e83d58ca08e291ce9b4 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 11 Sep 2019 15:18:40 +0200 Subject: [PATCH 0650/1854] chg: iclass.. cleaning out test/unused code.\n 'hf iclass sim' - Try LUT table --- armsrc/iclass.c | 70 ++++++++++++++++--------------------------------- 1 file changed, 23 insertions(+), 47 deletions(-) diff --git a/armsrc/iclass.c b/armsrc/iclass.c index 08f05857b..0f572cae3 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -55,7 +55,7 @@ #include "protocols.h" #include "ticks.h" -static int g_wait = 300; +static int g_wait = 270; static int timeout = 5000; static uint32_t time_rdr = 0; static uint32_t time_response = 0; @@ -1054,6 +1054,7 @@ static bool GetIClassCommandFromReader(uint8_t *received, int *len, int maxLen) return false; } +/* static uint8_t encode4Bits(const uint8_t b) { // OTA, the least significant bits first // Manchester encoding added @@ -1100,6 +1101,9 @@ static uint8_t encode4Bits(const uint8_t b) { return 0xaa; // 0000 -> 0000 -> 10101010 -> 0xaa } } +*/ + +static uint8_t lut_enc[] = { 0xAA, 0x6A, 0x9A, 0x5A, 0xA6, 0x66, 0x96, 0x56, 0xA9, 0x69, 0x99, 0x59, 0xA5, 0x65, 0x95, 0x55 }; //----------------------------------------------------------------------------- // Prepare tag messages @@ -1146,8 +1150,8 @@ static void CodeIClassTagAnswer(const uint8_t *cmd, int len) { int i; for (i = 0; i < len; i++) { uint8_t b = cmd[i]; - ToSend[++ToSendMax] = encode4Bits(b & 0xF); // least significant half - ToSend[++ToSendMax] = encode4Bits((b >> 4) & 0xF); // most significant half + ToSend[++ToSendMax] = lut_enc[b & 0xF]; // least significant half + ToSend[++ToSendMax] = lut_enc[(b >> 4) & 0xF]; // most significant half } // Send EOF @@ -1642,7 +1646,7 @@ send: A legit tag has about 330us delay between reader EOT and tag SOF. **/ if (modulated_response_size > 0) { - t2r_stime = (GetCountSspClk() - time_0) << 4; + t2r_stime = GetCountSspClkDelta(time_0) << 4; SendIClassAnswer(modulated_response, modulated_response_size, 0); t2r_etime = ((GetCountSspClk() - time_0) << 4) - t2r_stime; } @@ -1722,6 +1726,7 @@ static void TransmitIClassCommand(const uint8_t *cmd, int len, int *samples, int time_rdr = 0; FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD); + AT91C_BASE_SSC->SSC_THR = 0x00; // make sure we timeout previous comms. @@ -1762,13 +1767,6 @@ static void TransmitIClassCommand(const uint8_t *cmd, int len, int *samples, int } time_rdr = GetCountSspClk(); - - if (samples) { - if (wait) - *samples = (c + *wait) << 3; - else - *samples = c << 3; - } } //----------------------------------------------------------------------------- @@ -1819,15 +1817,14 @@ void ReaderTransmitIClass_ext(uint8_t *frame, int len, int wait) { // Select the card TransmitIClassCommand(ToSend, ToSendMax, &samples, &wait); - if (trigger) - LED_A_ON(); + LED_A_ON(); rsamples += samples; LogTrace(frame, len, rsamples, rsamples, NULL, true); } void ReaderTransmitIClass(uint8_t *frame, int len) { - ReaderTransmitIClass_ext(frame, len, 330); + ReaderTransmitIClass_ext(frame, len, 400); } //----------------------------------------------------------------------------- @@ -1835,23 +1832,21 @@ void ReaderTransmitIClass(uint8_t *frame, int len) { // If a response is captured return TRUE // If it takes too long return FALSE //----------------------------------------------------------------------------- -static int GetIClassAnswer(uint8_t *receivedResponse, int maxLen, int *samples, int *wait) { +static int GetIClassAnswer(uint8_t *receivedResponse, int maxLen, int *wait) { // buffer needs to be 512 bytes // maxLen is not used... - - int c = 0; bool skip = false; - // Setup UART/DEMOD to receive - DemodIcInit(receivedResponse); + LED_D_ON(); // Set FPGA mode to "reader listen mode", no modulation (listen // only, since we are receiving, not transmitting). FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_LISTEN); + // Setup UART/DEMOD to receive + DemodIcInit(receivedResponse); + SpinDelayUs(g_wait); //310 Tout= 330us (iso15603-2) (330/21.3) take consideration for clock increments. - uint32_t foo = GetCountSspClk(); - uint32_t bar; // clear RXRDY: uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; @@ -1859,61 +1854,42 @@ static int GetIClassAnswer(uint8_t *receivedResponse, int maxLen, int *samples, uint16_t checked = 0; + uint32_t card_start = GetCountSspClk(); for (;;) { WDT_HIT(); - if (checked == 1000) { + if (checked == 2000) { if (BUTTON_PRESS() || data_available()) return false; checked = 0; - } else { - checked++; - } - - // keep tx buffer in a defined state anyway. - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { - AT91C_BASE_SSC->SSC_THR = 0x00; } + checked++; // Wait for byte be become available in rx holding register if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { - c++; b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; skip = !skip; if (skip) continue; if (ManchesterDecoding_iclass(b & 0x0f)) { - if (samples) - *samples = c << 3; - time_response = GetCountSspClk() - foo; + time_response = GetCountSspClk() - card_start; return true; + } else if (GetCountSspClkDelta(card_start) > timeout && Demod.state == DEMOD_IC_UNSYNCD) { + return false; } - bar = GetCountSspClk(); - if ( foo > bar ) - bar += ( UINT32_MAX - foo ); - - if (bar - foo > timeout) return false; } } - return false; } int ReaderReceiveIClass(uint8_t *receivedAnswer) { - int samples = 0; - if (GetIClassAnswer(receivedAnswer, 0, &samples, NULL) == false) + if (GetIClassAnswer(receivedAnswer, 0, NULL) == false) return 0; - rsamples += samples; - LogTrace(receivedAnswer, Demod.len, rsamples, rsamples, NULL, false); - - if (samples == 0) - return 0; - return Demod.len; } From 4540b31d67f459a0445279d3a8ea694e10643aba Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 11 Sep 2019 15:58:03 +0200 Subject: [PATCH 0651/1854] thinfilm: textual --- client/cmdhfthinfilm.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/client/cmdhfthinfilm.c b/client/cmdhfthinfilm.c index 2e9ab7a85..a32aa8f59 100644 --- a/client/cmdhfthinfilm.c +++ b/client/cmdhfthinfilm.c @@ -60,10 +60,11 @@ static int print_barcode(uint8_t *barcode, const size_t barcode_len, bool verbos compute_crc(CRC_14443_A, barcode, barcode_len - 2, &b1, &b2); bool isok = (barcode[barcode_len - 1] == b1 && barcode[barcode_len - 2] == b2); - PrintAndLogEx(SUCCESS, " checksum : "_YELLOW_("%02X %02X")"- %s", b2, b1, (isok) ? _GREEN_("OK") : _RED_("fail")); + PrintAndLogEx(SUCCESS, " Checksum : "_YELLOW_("%02X %02X")"- %s", b2, b1, (isok) ? _GREEN_("OK") : _RED_("fail")); } else { - PrintAndLogEx(SUCCESS, " checksum : "_YELLOW_("too few data for checksum")"- " _RED_("fail")); + PrintAndLogEx(SUCCESS, " Checksum : "_YELLOW_("too few data for checksum")"- " _RED_("fail")); } + PrintAndLogEx(SUCCESS, " Data len (bits) : "_YELLOW_("%i")"- %s", barcode_len*8, (barcode_len==16||barcode_len==32) ? _GREEN_("OK") : _YELLOW_("warning")); PrintAndLogEx(SUCCESS, " Raw data : "_YELLOW_("%s"), sprint_hex(barcode, barcode_len)); if (barcode_len < 4) // too few to go to next decoding stages return PM3_ESOFT; From 08c345e560e7d6dcd587ab538a3fd404a8f7ed96 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 11 Sep 2019 17:21:27 +0300 Subject: [PATCH 0652/1854] added yubikey link --- client/fido/additional_ca.c | 1 + 1 file changed, 1 insertion(+) diff --git a/client/fido/additional_ca.c b/client/fido/additional_ca.c index 21d9d80f6..7ea103004 100644 --- a/client/fido/additional_ca.c +++ b/client/fido/additional_ca.c @@ -36,6 +36,7 @@ // Name: Yubico U2F Root CA Serial 457200631 // Issued: 2014-08-01 +// https://github.com/Yubico/developers.yubico.com/tree/master/static/U2F #define YUBICO_CA \ "-----BEGIN CERTIFICATE-----\r\n" \ "MIIDHjCCAgagAwIBAgIEG0BT9zANBgkqhkiG9w0BAQsFADAuMSwwKgYDVQQDEyNZ\r\n" \ From a623e6a24647b5c7ad0f8ef3851debbdff9b6d61 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 11 Sep 2019 16:22:37 +0200 Subject: [PATCH 0653/1854] chg: 'hf iclass list' - no parity on responses --- client/cmdtrace.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/cmdtrace.c b/client/cmdtrace.c index 401dac66e..010621498 100644 --- a/client/cmdtrace.c +++ b/client/cmdtrace.c @@ -303,7 +303,7 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr && (oddparity8(frame[j]) != ((parityBits >> (7 - (j & 0x0007))) & 0x01))) { snprintf(line[j / 18] + ((j % 18) * 4), 110, "%02x! ", frame[j]); - } else if ( protocol == ICLASS && isResponse == true) { + } else if ( protocol == ICLASS && isResponse == false) { uint8_t parity = 0; for (int i=0; i<6; i++) { parity ^= ((frame[0] >> i) & 1); @@ -313,6 +313,7 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr } else { snprintf(line[j / 18] + ((j % 18) * 4), 110, "%02x! ", frame[j]); } + } else { snprintf(line[j / 18] + ((j % 18) * 4), 110, "%02x ", frame[j]); } From 9f0db0bbdc89705b30bc04a746352f3e45dd9417 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 11 Sep 2019 16:23:06 +0200 Subject: [PATCH 0654/1854] textual --- client/cmdhficlass.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 8b0c4ea35..6de758d31 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -2805,7 +2805,7 @@ int readIclass(bool loop, bool verbose) { uint8_t readStatus = resp.oldarg[0] & 0xff; uint8_t *data = resp.data.asBytes; - if (verbose) PrintAndLogEx(NORMAL, "Readstatus:%02x", readStatus); + if (verbose) PrintAndLogEx(INFO, "Readstatus:%02x", readStatus); // no tag found or button pressed if ((readStatus == 0 && !loop) || readStatus == 0xFF) { // abort From ab0d81d01acce45cfd35e15555fd663aebb228ed Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 11 Sep 2019 16:24:16 +0200 Subject: [PATCH 0655/1854] ..adapt parity to cmds, prolong button loop test --- armsrc/iclass.c | 64 +++++++++++++++++++++++-------------------------- 1 file changed, 30 insertions(+), 34 deletions(-) diff --git a/armsrc/iclass.c b/armsrc/iclass.c index 0f572cae3..5e9ffb913 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -55,8 +55,8 @@ #include "protocols.h" #include "ticks.h" -static int g_wait = 270; -static int timeout = 5000; +static int g_wait = 200; +static int timeout = 15000; static uint32_t time_rdr = 0; static uint32_t time_response = 0; @@ -1029,12 +1029,11 @@ static bool GetIClassCommandFromReader(uint8_t *received, int *len, int maxLen) WDT_HIT(); - if (checked == 1000) { + if (checked == 2000) { if (BUTTON_PRESS() || data_available()) return false; checked = 0; - } else { - checked++; } + checked++; // keep tx buffer in a defined state anyway. if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) @@ -1682,12 +1681,12 @@ static int SendIClassAnswer(uint8_t *resp, int respLen, uint16_t delay) { uint16_t checked = 0; for (;;) { - if (checked == 1000) { + if (checked == 2000) { if (BUTTON_PRESS() || data_available()) return 0; checked = 0; - } else { - checked++; } + checked++; + // Prevent rx holding register from overflowing if ((AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY)) { b = AT91C_BASE_SSC->SSC_RHR; @@ -1872,7 +1871,6 @@ static int GetIClassAnswer(uint8_t *receivedResponse, int maxLen, int *wait) { if (skip) continue; if (ManchesterDecoding_iclass(b & 0x0f)) { - time_response = GetCountSspClk() - card_start; return true; } else if (GetCountSspClkDelta(card_start) > timeout && Demod.state == DEMOD_IC_UNSYNCD) { @@ -1930,7 +1928,7 @@ bool sendCmdGetResponseWithRetries(uint8_t *command, size_t cmdsize, uint8_t *re // update/write command takes 4ms to 15ms before responding int old_wait = g_wait; - if (command[0] == ICLASS_CMD_UPDATE) + if ( (command[0] & 0xF) == ICLASS_CMD_UPDATE) g_wait = 3900; uint8_t got_n = ReaderReceiveIClass(resp); @@ -1962,8 +1960,8 @@ uint8_t handshakeIclassTag_ext(uint8_t *card_data, bool use_credit_key) { // act_all... static uint8_t act_all[] = { ICLASS_CMD_ACTALL }; static uint8_t identify[] = { ICLASS_CMD_READ_OR_IDENTIFY, 0x00, 0x73, 0x33 }; - static uint8_t select[] = { ICLASS_CMD_SELECT, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - uint8_t readcheck_cc[] = { ICLASS_CMD_READCHECK, 0x02 }; + static uint8_t select[] = { 0x80 | ICLASS_CMD_SELECT, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + uint8_t readcheck_cc[] = { 0x80 | ICLASS_CMD_READCHECK, 0x02 }; if (use_credit_key == false) readcheck_cc[0] |= 0x10; @@ -2055,7 +2053,7 @@ void ReaderIClass(uint8_t arg0) { WDT_HIT(); // if only looking for one card try 2 times if we missed it the first time - if (try_once && tryCnt > 2) { + if (try_once && tryCnt > 10) { if (DBGLEVEL > 1) DbpString("Failed to find a tag"); break; } @@ -2138,9 +2136,10 @@ void ReaderIClass(uint8_t arg0) { if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("SEND %c", send ? 'y' : 'n'); if (send) { - reply_old(CMD_ACK, result_status, 0, 0, card_data, sizeof(card_data)); + reply_mix(CMD_ACK, result_status, 0, 0, card_data, sizeof(card_data)); if (abort_after_read) { LED_B_OFF(); + swith_off(); return; } //Save that we already sent this.... @@ -2149,19 +2148,18 @@ void ReaderIClass(uint8_t arg0) { } LED_B_OFF(); - if (checked == 1000) { + if (checked == 2000) { userCancelled = BUTTON_PRESS() || data_available(); checked = 0; - } else { - checked++; } + checked++; } if (userCancelled) { - reply_old(CMD_ACK, 0xFF, 0, 0, card_data, 0); + reply_mix(CMD_ACK, 0xFF, 0, 0, card_data, 0); switch_off(); } else { - reply_old(CMD_ACK, 0, 0, 0, card_data, 0); + reply_mix(CMD_ACK, 0, 0, 0, card_data, 0); } } @@ -2331,7 +2329,7 @@ void iClass_Authentication_fast(uint64_t arg0, uint64_t arg1, uint8_t *datain) { uint8_t keyCount = arg1 & 0xFF; uint8_t check[] = { ICLASS_CMD_CHECK, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; uint8_t resp[ICLASS_BUFFER_SIZE]; - uint8_t readcheck_cc[] = { ICLASS_CMD_READCHECK, 0x02 }; + uint8_t readcheck_cc[] = { 0x80 | ICLASS_CMD_READCHECK, 0x02 }; if (use_credit_key == false) readcheck_cc[0] |= 0x10; @@ -2353,12 +2351,11 @@ void iClass_Authentication_fast(uint64_t arg0, uint64_t arg1, uint8_t *datain) { uint8_t startup_limit = 10; while (read_status != 2) { - if (checked == 1000) { + if (checked == 2000) { if (BUTTON_PRESS() || !data_available()) goto out; checked = 0; - } else { - checked++; } + checked++; read_status = handshakeIclassTag_ext(card_data, use_credit_key); if (startup_limit-- == 0) { @@ -2375,12 +2372,11 @@ void iClass_Authentication_fast(uint64_t arg0, uint64_t arg1, uint8_t *datain) { for (i = 0; i < keyCount; i++) { // Allow button press / usb cmd to interrupt device - if (checked == 1000) { + if (checked == 2000) { if (BUTTON_PRESS() || !data_available()) goto out; checked = 0; - } else { - checked++; } + checked++; WDT_HIT(); LED_B_ON(); @@ -2432,10 +2428,10 @@ bool iClass_ReadBlock(uint8_t blockno, uint8_t *data, uint8_t len) { // readblock 8 + 2. only want 8. void iClass_ReadBlk(uint8_t blockno) { struct p { - bool isOK; + bool isOK; uint8_t blockdata[8]; } PACKED result; - + result.isOK = iClass_ReadBlock(blockno, result.blockdata, sizeof(result.blockdata)); switch_off(); reply_ng(CMD_HF_ICLASS_READBL, PM3_SUCCESS, (uint8_t *)&result, sizeof(result)); @@ -2470,7 +2466,7 @@ void iClass_Dump(uint8_t blockno, uint8_t numblks) { } memcpy(dataout + (blkCnt * 8), blockdata, 8); } - + switch_off(); //return pointer to dump memory in arg3 reply_mix(CMD_ACK, isOK, blkCnt, BigBuf_max_traceLen(), 0, 0); @@ -2479,7 +2475,7 @@ void iClass_Dump(uint8_t blockno, uint8_t numblks) { bool iClass_WriteBlock_ext(uint8_t blockno, uint8_t *data) { uint8_t resp[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - uint8_t write[] = { ICLASS_CMD_UPDATE, blockno, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + uint8_t write[] = { 0x80 | ICLASS_CMD_UPDATE, blockno, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; memcpy(write + 2, data, 12); // data + mac AddCrc(write + 1, 13); return sendCmdGetResponseWithRetries(write, sizeof(write), resp, sizeof(resp), 5); @@ -2505,12 +2501,12 @@ void iClass_Clone(uint8_t startblock, uint8_t endblock, uint8_t *data) { Dbprintf("Write block [%02x] failed", startblock + i); } } - + switch_off(); - + uint8_t isOK = 0; if (written == total_block) isOK = 1; - - reply_ng(CMD_HF_ICLASS_CLONE, PM3_SUCCESS, (uint8_t *)&isOK, sizeof(uint8_t)); + + reply_ng(CMD_HF_ICLASS_CLONE, PM3_SUCCESS, (uint8_t *)&isOK, sizeof(uint8_t)); } From 312e4b358c9749ec71c74c691b12ae4c10b86938 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 11 Sep 2019 16:36:41 +0200 Subject: [PATCH 0656/1854] fix: 'hf iclass reader 1' - now turns off --- client/cmdhficlass.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 6de758d31..4d6af964b 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -2806,25 +2806,27 @@ int readIclass(bool loop, bool verbose) { uint8_t *data = resp.data.asBytes; if (verbose) PrintAndLogEx(INFO, "Readstatus:%02x", readStatus); + // no tag found or button pressed if ((readStatus == 0 && !loop) || readStatus == 0xFF) { // abort - if (verbose) { - PrintAndLogEx(FAILED, "Quitting..."); - DropField(); - return PM3_EOPABORTED; - } + DropField(); + return PM3_EOPABORTED; } + if (readStatus & FLAG_ICLASS_READER_CSN) { PrintAndLogEx(NORMAL, " CSN: %s", sprint_hex(data, 8)); tagFound = true; } + if (readStatus & FLAG_ICLASS_READER_CC) { PrintAndLogEx(NORMAL, " CC: %s", sprint_hex(data + 16, 8)); } + if (readStatus & FLAG_ICLASS_READER_CONF) { printIclassDumpInfo(data); } + if (readStatus & FLAG_ICLASS_READER_AIA) { bool legacy = (memcmp((uint8_t *)(data + 8 * 5), "\xff\xff\xff\xff\xff\xff\xff\xff", 8) == 0); From 6090a66f34fb3d223fb47651c8102662f73ce3db Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 11 Sep 2019 16:37:10 +0200 Subject: [PATCH 0657/1854] ... --- armsrc/iclass.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/iclass.c b/armsrc/iclass.c index 5e9ffb913..d6c0ea72e 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -2139,7 +2139,7 @@ void ReaderIClass(uint8_t arg0) { reply_mix(CMD_ACK, result_status, 0, 0, card_data, sizeof(card_data)); if (abort_after_read) { LED_B_OFF(); - swith_off(); + switch_off(); return; } //Save that we already sent this.... From f57a6195ded5f83a779657ad778806666dea040e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 11 Sep 2019 16:56:08 +0200 Subject: [PATCH 0658/1854] turning off field on failure --- client/cmdhficlass.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 4d6af964b..fc6b2e53b 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -1021,7 +1021,7 @@ static bool select_only(uint8_t *CSN, uint8_t *CCNR, bool use_credit_key, bool v if (isOK <= 1) { if ( verbose ) PrintAndLogEx(FAILED, "failed to obtain CC! Tag-select is aborting... (%d)", isOK); - + return false; } return true; @@ -1033,6 +1033,8 @@ static bool select_and_auth(uint8_t *KEY, uint8_t *MAC, uint8_t *div_key, bool u if (!select_only(CSN, CCNR, use_credit_key, verbose)) { if (verbose) PrintAndLogEx(FAILED, "selecting tag failed"); + + DropField(); return false; } //get div_key @@ -2042,8 +2044,10 @@ static int CmdHFiClassCalcNewKey(const char *Cmd) { if (!givenCSN) { uint8_t CCNR[12] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - if (!select_only(CSN, CCNR, false, true)) + if (!select_only(CSN, CCNR, false, true)) { + DropField(); return 0; + } } HFiClassCalcNewKey(CSN, OLDKEY, NEWKEY, xor_div_key, elite, oldElite, true); @@ -2280,16 +2284,18 @@ static int CmdHFiClassCheckKeys(const char *Cmd) { for (uint8_t i = 0; i < ICLASS_AUTH_RETRY && !got_csn; i++) { got_csn = select_only(CSN, CCNR, false, false); if (got_csn == false) - PrintAndLogEx(WARNING, "one more try\n"); + PrintAndLogEx(WARNING, "one more try"); } if (got_csn == false) { PrintAndLogEx(WARNING, "Tried 10 times. Can't select card, aborting..."); + DropField(); return PM3_ESOFT; } pre = calloc(keycount, sizeof(iclass_premac_t)); if (!pre) { + DropField(); free(keyBlock); return PM3_EMALLOC; } From f4ff22a5bcca8f21e560ac7eaa1f0328479fdc7d Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 11 Sep 2019 20:40:59 +0200 Subject: [PATCH 0659/1854] revert back timeout values --- armsrc/iclass.c | 33 +++++++++------------------------ 1 file changed, 9 insertions(+), 24 deletions(-) diff --git a/armsrc/iclass.c b/armsrc/iclass.c index d6c0ea72e..c4253a260 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -55,8 +55,8 @@ #include "protocols.h" #include "ticks.h" -static int g_wait = 200; -static int timeout = 15000; +static int g_wait = 100; +static int timeout = 5000; static uint32_t time_rdr = 0; static uint32_t time_response = 0; @@ -895,9 +895,7 @@ void RAMFUNC SniffIClass(void) { // time ZERO, the point from which it all is calculated. time_0 = GetCountSspClk(); - - int divi = 0; - uint8_t tag_byte = 0, foo = 0; + // loop and listen // every sample (1byte in data), // contains HIGH nibble = reader data @@ -908,12 +906,11 @@ void RAMFUNC SniffIClass(void) { for (;;) { WDT_HIT(); - if (checked == 1000) { + if (checked == 2000) { if (BUTTON_PRESS() || data_available()) break; checked = 0; - } else { - checked++; } + checked++; previous_data <<= 8; previous_data |= *data; @@ -927,14 +924,6 @@ void RAMFUNC SniffIClass(void) { AT91C_BASE_PDC_SSC->PDC_RNCR = ICLASS_DMA_BUFFER_SIZE; } - if (*data & 0xF) { - //tag_byte <<= 1; - tag_byte ^= (1 << 4); - foo ^= (1 << (3 - divi)); - Dbprintf(" %d|%x == %d|%x", tag_byte, tag_byte, foo, foo); - } - divi++; - // every odd sample if (sniffCounter & 0x01) { // no need to try decoding reader data if the tag is sending @@ -964,8 +953,6 @@ void RAMFUNC SniffIClass(void) { LED_C_INV(); // LOW nibble is always tag data. /* - - uint32_t tag_byte = ((previous_data & 0x0F000000) >> 8 ) | ((previous_data & 0x000F0000) >> 4 ) | @@ -975,8 +962,8 @@ void RAMFUNC SniffIClass(void) { */ - //uint8_t tag_byte = ((previous_data & 0xF) << 4 ) | (*data & 0xF); - if (ManchesterDecoding_iclass(foo)) { + uint8_t tag_byte = ((previous_data & 0xF) << 4 ) | (*data & 0xF); + if (ManchesterDecoding_iclass(tag_byte)) { time_stop = GetCountSspClk() - time_0; LogTrace(Demod.output, Demod.len, time_start, time_stop, NULL, false); DemodIcReset(); @@ -986,17 +973,15 @@ void RAMFUNC SniffIClass(void) { } TagIsActive = (Demod.state != DEMOD_IC_UNSYNCD); } - tag_byte = 0; - foo = 0; - divi = 0; } } // end main loop +/* if (DBGLEVEL >= 1) { DbpString("[+] Sniff statistics:"); Dbhexdump(ICLASS_DMA_BUFFER_SIZE, data, false); } - +*/ switch_off(); } From 236175a688b15626be0dee59b939dde7e49e7978 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 11 Sep 2019 21:14:46 +0200 Subject: [PATCH 0660/1854] fix 'hf iclass chk' - timings and fixing the parity / kc / kd ... --- armsrc/iclass.c | 34 ++++++++++++---------------------- 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/armsrc/iclass.c b/armsrc/iclass.c index c4253a260..b13eff66f 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -55,7 +55,7 @@ #include "protocols.h" #include "ticks.h" -static int g_wait = 100; +static int g_wait = 240; static int timeout = 5000; static uint32_t time_rdr = 0; static uint32_t time_response = 0; @@ -1700,10 +1700,9 @@ static int SendIClassAnswer(uint8_t *resp, int respLen, uint16_t delay) { //----------------------------------------------------------------------------- // Transmit the command (to the tag) that was placed in ToSend[]. //----------------------------------------------------------------------------- -static void TransmitIClassCommand(const uint8_t *cmd, int len, int *samples, int *wait) { +static void TransmitIClassCommand(const uint8_t *cmd, int len, int *wait) { int c = 0; -// volatile uint32_t b; bool firstpart = true; uint8_t sendbyte; @@ -1740,14 +1739,6 @@ static void TransmitIClassCommand(const uint8_t *cmd, int len, int *samples, int if (c >= len) break; } - - // Prevent rx holding register from overflowing - /* - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { - b = AT91C_BASE_SSC->SSC_RHR; - (void)b; - } - */ } time_rdr = GetCountSspClk(); @@ -1794,21 +1785,17 @@ void CodeIClassCommand(const uint8_t *cmd, int len) { void ReaderTransmitIClass_ext(uint8_t *frame, int len, int wait) { - int samples = 0; - // This is tied to other size changes CodeIClassCommand(frame, len); // Select the card - TransmitIClassCommand(ToSend, ToSendMax, &samples, &wait); + TransmitIClassCommand(ToSend, ToSendMax, &wait); LED_A_ON(); - rsamples += samples; - LogTrace(frame, len, rsamples, rsamples, NULL, true); } void ReaderTransmitIClass(uint8_t *frame, int len) { - ReaderTransmitIClass_ext(frame, len, 400); + ReaderTransmitIClass_ext(frame, len, 330); } //----------------------------------------------------------------------------- @@ -1948,14 +1935,17 @@ uint8_t handshakeIclassTag_ext(uint8_t *card_data, bool use_credit_key) { static uint8_t select[] = { 0x80 | ICLASS_CMD_SELECT, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; uint8_t readcheck_cc[] = { 0x80 | ICLASS_CMD_READCHECK, 0x02 }; - if (use_credit_key == false) - readcheck_cc[0] |= 0x10; + // Bit 4: K.If this bit equals to one, the READCHECK will use the Credit Key (Kc); if equals to zero, Debit Key (Kd) willbe used + // bit 7: parity. + + if (use_credit_key) + readcheck_cc[0] = 0x10 | ICLASS_CMD_READCHECK; uint8_t resp[ICLASS_BUFFER_SIZE] = {0}; uint8_t read_status = 0; // Send act_all - ReaderTransmitIClass_ext(act_all, 1, 330 + 160); + ReaderTransmitIClass_ext(act_all, 1, 330); // Card present? if (!ReaderReceiveIClass(resp)) return read_status;//Fail @@ -2316,8 +2306,8 @@ void iClass_Authentication_fast(uint64_t arg0, uint64_t arg1, uint8_t *datain) { uint8_t resp[ICLASS_BUFFER_SIZE]; uint8_t readcheck_cc[] = { 0x80 | ICLASS_CMD_READCHECK, 0x02 }; - if (use_credit_key == false) - readcheck_cc[0] |= 0x10; + if (use_credit_key) + readcheck_cc[0] = 0x10 | ICLASS_CMD_READCHECK; // select card / e-purse uint8_t card_data[6 * 8] = {0}; From 1ad66c917f52333c2b1cd504ef44543f482fb39c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 11 Sep 2019 22:51:13 +0200 Subject: [PATCH 0661/1854] fixin... --- armsrc/iclass.c | 54 ++++++++++++++++++++++---------------------- client/cmdhficlass.c | 9 ++++---- 2 files changed, 31 insertions(+), 32 deletions(-) diff --git a/armsrc/iclass.c b/armsrc/iclass.c index b13eff66f..5bbcc1b4b 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -55,7 +55,7 @@ #include "protocols.h" #include "ticks.h" -static int g_wait = 240; +static int g_wait = 290; static int timeout = 5000; static uint32_t time_rdr = 0; static uint32_t time_response = 0; @@ -1808,7 +1808,6 @@ static int GetIClassAnswer(uint8_t *receivedResponse, int maxLen, int *wait) { // maxLen is not used... bool skip = false; - LED_D_ON(); // Set FPGA mode to "reader listen mode", no modulation (listen // only, since we are receiving, not transmitting). @@ -1848,7 +1847,6 @@ static int GetIClassAnswer(uint8_t *receivedResponse, int maxLen, int *wait) { } else if (GetCountSspClkDelta(card_start) > timeout && Demod.state == DEMOD_IC_UNSYNCD) { return false; } - } } return false; @@ -1910,7 +1908,7 @@ bool sendCmdGetResponseWithRetries(uint8_t *command, size_t cmdsize, uint8_t *re // 0xBB is the internal debug separator byte.. if (expected_size != got_n || (resp[0] == 0xBB || resp[7] == 0xBB || resp[2] == 0xBB)) { //try again - SpinDelayUs(360); +// SpinDelayUs(360); continue; } @@ -1942,19 +1940,20 @@ uint8_t handshakeIclassTag_ext(uint8_t *card_data, bool use_credit_key) { readcheck_cc[0] = 0x10 | ICLASS_CMD_READCHECK; uint8_t resp[ICLASS_BUFFER_SIZE] = {0}; - uint8_t read_status = 0; - // Send act_all - ReaderTransmitIClass_ext(act_all, 1, 330); + // Send act_all ( 330 timeout + 160 timeslot); + ReaderTransmitIClass_ext(act_all, 1, 330 + 180); + // Card present? - if (!ReaderReceiveIClass(resp)) return read_status;//Fail + if (ReaderReceiveIClass(resp) == 0) + return 0; //Send Identify ReaderTransmitIClass(identify, 1); //We expect a 10-byte response here, 8 byte anticollision-CSN and 2 byte CRC - uint8_t len = ReaderReceiveIClass(resp); - if (len != 10) return read_status;//Fail + if ( ReaderReceiveIClass(resp) != 10 ) + return 0; //Copy the Anti-collision CSN to our select-packet memcpy(&select[1], resp, 8); @@ -1963,31 +1962,33 @@ uint8_t handshakeIclassTag_ext(uint8_t *card_data, bool use_credit_key) { ReaderTransmitIClass(select, sizeof(select)); //We expect a 10-byte response here, 8 byte CSN and 2 byte CRC - len = ReaderReceiveIClass(resp); - if (len != 10) return read_status;//Fail + if ( ReaderReceiveIClass(resp) != 10) + return 0; - //Success - level 1, we got CSN - //Save CSN in response data - memcpy(card_data, resp, 8); - - //Flag that we got to at least stage 1, read CSN - read_status = 1; - - // Card selected, now read e-purse (cc) (block2) (only 8 bytes no CRC) + // Card selected, now read e-purse (cc) (block2) (only 8 bytes no CRC) // ReaderTransmitIClass(readcheck_cc, sizeof(readcheck_cc)); // if (ReaderReceiveIClass(resp) == 8) { // //Save CC (e-purse) in response data // memcpy(card_data+8, resp, 8); // read_status++; // } + + //Success - level 1, we got CSN + //Save CSN in response data + memcpy(card_data, resp, 8); + + bool isBlk_2 = sendCmdGetResponseWithRetries(readcheck_cc, sizeof(readcheck_cc), resp, 8, 3); - bool isOK = sendCmdGetResponseWithRetries(readcheck_cc, sizeof(readcheck_cc), resp, 8, 3); - if (!isOK) return read_status; - + //Flag that we got to at least stage 1, read CSN + if ( isBlk_2 == false) { + return 1; + } + //Save CC (e-purse) in response data memcpy(card_data + 8, resp, 8); - read_status++; - return read_status; + + // we got all data; + return 2; } uint8_t handshakeIclassTag(uint8_t *card_data) { return handshakeIclassTag_ext(card_data, false); @@ -2114,7 +2115,6 @@ void ReaderIClass(uint8_t arg0) { reply_mix(CMD_ACK, result_status, 0, 0, card_data, sizeof(card_data)); if (abort_after_read) { LED_B_OFF(); - switch_off(); return; } //Save that we already sent this.... @@ -2421,7 +2421,7 @@ void iClass_Dump(uint8_t blockno, uint8_t numblks) { BigBuf_free(); uint8_t *dataout = BigBuf_malloc(255 * 8); if (dataout == NULL) { - DbpString("[!] out of memory"); + DbpString("[!] fail to allocate memory"); OnError(1); return; } diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index fc6b2e53b..f45151a7b 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -1034,7 +1034,7 @@ static bool select_and_auth(uint8_t *KEY, uint8_t *MAC, uint8_t *div_key, bool u if (!select_only(CSN, CCNR, use_credit_key, verbose)) { if (verbose) PrintAndLogEx(FAILED, "selecting tag failed"); - DropField(); +// DropField(); return false; } //get div_key @@ -1728,13 +1728,12 @@ static int ReadBlock(uint8_t *KEY, uint8_t blockno, uint8_t keyType, bool elite, DropField(); - if ( numberAuthRetries > 0 ) { - PrintAndLogEx(SUCCESS, "block %02X: %s\n", blockno, sprint_hex(result->blockdata, sizeof(result->blockdata))); - } else { + if ( numberAuthRetries == 0 ) { PrintAndLogEx(ERR,"failed to authenticate and read block"); - return PM3_ESOFT; } + + PrintAndLogEx(SUCCESS, "block %02X: %s\n", blockno, sprint_hex(result->blockdata, sizeof(result->blockdata))); return PM3_SUCCESS; } From 22ead8ca0b50d50d7f3344ce344b4f1c2d6e6af5 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 12 Sep 2019 01:23:43 +0200 Subject: [PATCH 0662/1854] printdemodbuffer: add option to strip leading zeroes --- client/cmddata.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/client/cmddata.c b/client/cmddata.c index 59c80102d..9465c63ac 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -39,6 +39,7 @@ static int usage_data_printdemodbuf(void) { PrintAndLogEx(NORMAL, " x output in hex (omit for binary output)"); PrintAndLogEx(NORMAL, " o enter offset in # of bits"); PrintAndLogEx(NORMAL, " l enter length to print in # of bits or hex characters respectively"); + PrintAndLogEx(NORMAL, " s strip leading zeroes, i.e. set offset to first bit equal to one"); return PM3_SUCCESS; } static int usage_data_manrawdecode(void) { @@ -402,6 +403,7 @@ void printDemodBuff(void) { int CmdPrintDemodBuff(const char *Cmd) { bool hexMode = false; bool errors = false; + bool lstrip = false; uint32_t offset = 0; uint32_t length = 512; char cmdp = 0; @@ -423,6 +425,10 @@ int CmdPrintDemodBuff(const char *Cmd) { if (!length) errors = true; cmdp += 2; break; + case 's': + lstrip = true; + cmdp ++; + break; default: PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); errors = true; @@ -436,6 +442,15 @@ int CmdPrintDemodBuff(const char *Cmd) { PrintAndLogEx(NORMAL, "Demodbuffer is empty"); return PM3_ESOFT; } + if (lstrip) { + char *buf = (char *)(DemodBuffer + offset); + length = (length > (DemodBufferLen - offset)) ? DemodBufferLen - offset : length; + uint32_t i; + for (i = 0; i < length; i++) { + if (buf[i] == 1) break; + } + offset += i; + } length = (length > (DemodBufferLen - offset)) ? DemodBufferLen - offset : length; if (hexMode) { From 3587aeff2aaeb8d326ac2baa35824eecb02a7936 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 12 Sep 2019 09:58:05 +0200 Subject: [PATCH 0663/1854] fix: LED is used as a flag, 1,2,4,8 not 1,2,3,4.. --- armsrc/Standalone/hf_bog.c | 2 +- armsrc/Standalone/hf_colin.c | 8 ++++---- armsrc/appmain.c | 15 ++++++++------- armsrc/util.c | 32 +++++++++++++++++--------------- 4 files changed, 30 insertions(+), 27 deletions(-) diff --git a/armsrc/Standalone/hf_bog.c b/armsrc/Standalone/hf_bog.c index 6580af7fd..dc5c2e071 100644 --- a/armsrc/Standalone/hf_bog.c +++ b/armsrc/Standalone/hf_bog.c @@ -229,7 +229,7 @@ void RAMFUNC SniffAndStore(uint8_t param) { if (DBGLEVEL > 1) Dbprintf("[!] Wrote %u Authentification attempts into logfile", auth_attempts); - SpinErr(0, 200, 5); // blink led A + SpinErr(LED_A, 200, 5); SpinDelay(100); } diff --git a/armsrc/Standalone/hf_colin.c b/armsrc/Standalone/hf_colin.c index 265b7e3c9..4997f775e 100644 --- a/armsrc/Standalone/hf_colin.c +++ b/armsrc/Standalone/hf_colin.c @@ -518,7 +518,7 @@ failtag: if (cjcuid == 0) { cjSetCursLeft(); DbprintfEx(FLAG_NEWLINE, "%s>>%s BUG: 0000_CJCUID! Retrying...", _XRED_, _XWHITE_); - SpinErr(0, 100, 8); + SpinErr(LED_A, 100, 8); goto failtag; } @@ -636,7 +636,7 @@ failtag: cjTabulize(); DbprintfEx(FLAG_NEWLINE, "%s[ FAIL ]%s\r\n->did not found all the keys :'(", _XRED_, _XWHITE_); cjSetCursLeft(); - SpinErr(1, 100, 8); + SpinErr(LEB_B, 100, 8); SpinOff(100); return; } @@ -672,7 +672,7 @@ failtag: cjSetCursLeft(); DbprintfEx(FLAG_NEWLINE, "FATAL:EML_FALLBACKFILL_B"); - SpinErr(2, 100, 8); + SpinErr(LED_C, 100, 8); SpinOff(100); return; } @@ -778,7 +778,7 @@ readysim: DbprintfEx(FLAG_NEWLINE, "- [ LA FIN ] -\r\n%s`-> You can take shell back :) ...", _XWHITE_); cjSetCursLeft(); vtsend_set_attribute(NULL, 0); - SpinErr(3, 100, 16); + SpinErr(LED_D, 100, 16); SpinDown(75); SpinOff(100); return; diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 990ac1c56..a4b1c45bc 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -447,15 +447,12 @@ void SendCapabilities(void) { // Show some leds in a pattern to identify StandAlone mod is running void StandAloneMode(void) { - - DbpString("Stand-alone mode! No PC necessary."); - + DbpString("Stand-alone mode, no computer necessary"); SpinDown(50); - SpinOff(50); + SpinDelay(50); SpinUp(50); - SpinOff(50); + SpinDelay(50); SpinDown(50); - SpinDelay(500); } /* @@ -1215,7 +1212,11 @@ static void PacketReceived(PacketCommandNG *packet) { break; } case CMD_HF_ICLASS_READER: { - ReaderIClass(packet->oldarg[0]); + struct p { + uint8_t flags; + } PACKED; + struct p *payload = (struct p *)packet->data.asBytes; + ReaderIClass(payload->flags); break; } case CMD_HF_ICLASS_REPLAY: { diff --git a/armsrc/util.c b/armsrc/util.c index b855ab949..888c64b9d 100644 --- a/armsrc/util.c +++ b/armsrc/util.c @@ -90,6 +90,7 @@ void LEDsoff() { LED_D_OFF(); } +//ICEMAN: LED went from 1,2,3,4 -> 1,2,4,8 void LED(int led, int ms) { if (led & LED_A) // Proxmark3 historical mapping: LED_ORANGE LED_A_ON(); @@ -123,26 +124,27 @@ void SpinOff(uint32_t pause) { SpinDelay(pause); } -// 0=A, 1=B, 2=C, 3=D +// Blinks.. +// A = 1, B = 2, C = 4, D = 8 void SpinErr(uint8_t led, uint32_t speed, uint8_t times) { SpinOff(speed); NTIME(times) { - switch (led) { - case 0: - LED_A_INV(); - break; - case 1: - LED_B_INV(); - break; - case 2: - LED_C_INV(); - break; - case 3: - LED_D_INV(); - break; - } + + if (led & LED_A) // Proxmark3 historical mapping: LED_ORANGE + LED_A_INV(); + if (led & LED_B) // Proxmark3 historical mapping: LED_GREEN + LED_B_INV(); + if (led & LED_C) // Proxmark3 historical mapping: LED_RED + LED_C_INV(); + if (led & LED_D) // Proxmark3 historical mapping: LED_RED2 + LED_D_INV(); + SpinDelay(speed); } + LED_A_OFF(); + LED_B_OFF(); + LED_C_OFF(); + LED_D_OFF(); } void SpinDown(uint32_t speed) { From d3b2f1f6d05915d495690328ccf7a084101060ac Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 12 Sep 2019 10:39:10 +0200 Subject: [PATCH 0664/1854] fix leds. dbg msg --- armsrc/pcf7931.c | 76 ++++++++++++++++++++++++++++++------------------ 1 file changed, 48 insertions(+), 28 deletions(-) diff --git a/armsrc/pcf7931.c b/armsrc/pcf7931.c index 82865b311..1690c6ad3 100644 --- a/armsrc/pcf7931.c +++ b/armsrc/pcf7931.c @@ -94,7 +94,10 @@ size_t DemodPCF7931(uint8_t **outBlocks) { } else { // Error if (++warnings > 10) { - Dbprintf("Error: too many detection errors, aborting."); + + if ( DBGLEVEL >= DBG_EXTENDED ) + Dbprintf("Error: too many detection errors, aborting."); + return 0; } } @@ -135,11 +138,14 @@ bool IsBlock0PCF7931(uint8_t *block) { // assuming all RFU bits are set to 0 // if PAC is enabled password is set to 0 if (block[7] == 0x01) { - if (!memcmp(block, "\x00\x00\x00\x00\x00\x00\x00", 7) && !memcmp(block + 9, "\x00\x00\x00\x00\x00\x00\x00", 7)) + if (!memcmp(block, "\x00\x00\x00\x00\x00\x00\x00", 7) + && !memcmp(block + 9, "\x00\x00\x00\x00\x00\x00\x00", 7)) { return true; + } } else if (block[7] == 0x00) { - if (!memcmp(block + 9, "\x00\x00\x00\x00\x00\x00\x00", 7)) + if (!memcmp(block + 9, "\x00\x00\x00\x00\x00\x00\x00", 7)) { return true; + } } return false; } @@ -152,14 +158,14 @@ bool IsBlock1PCF7931(uint8_t *block) { uint8_t rlb = block[15]; if (block[10] == 0 - && block[11] == 0 - && block[12] == 0 - && block[13] == 0) { + && block[11] == 0 + && block[12] == 0 + && block[13] == 0) { // block 1 is sent only if (RLB >= 1 && RFB <= 1) or RB1 enabled if (rfb <= rlb - && rfb <= 9 - && rlb <= 9 - && ((rfb <= 1 && rlb >= 1) || rb1)) { + && rfb <= 9 + && rlb <= 9 + && ((rfb <= 1 && rlb >= 1) || rb1)) { return true; } } @@ -196,13 +202,18 @@ void ReadPCF7931() { // exit if no block is received if (errors >= 10 && found_blocks == 0 && single_blocks_cnt == 0) { - Dbprintf("Error, no tag or bad tag"); + + if ( DBGLEVEL >= DBG_INFO ) + Dbprintf("[!!] Error, no tag or bad tag"); + return; } // exit if too many errors during reading if (tries > 50 && (2 * errors > tries)) { - Dbprintf("Error reading the tag"); - Dbprintf("Here is the partial content"); + + if ( DBGLEVEL >= DBG_INFO ) + Dbprintf("[!!] Error reading the tag, only partial content"); + goto end; } @@ -231,7 +242,9 @@ void ReadPCF7931() { continue; } - Dbprintf("(dbg) got %d blocks (%d/%d found) (%d tries, %d errors)", n, found_blocks, (max_blocks == 0 ? found_blocks : max_blocks), tries, errors); + if ( DBGLEVEL >= DBG_EXTENDED ) + Dbprintf("(dbg) got %d blocks (%d/%d found) (%d tries, %d errors)", n, found_blocks, (max_blocks == 0 ? found_blocks : max_blocks), tries, errors); + for (i = 0; i < n; ++i) { print_result("got consecutive blocks", tmp_blocks[i], 16); } @@ -293,7 +306,9 @@ void ReadPCF7931() { } ++tries; if (BUTTON_PRESS()) { - Dbprintf("Button pressed, stopping."); + if ( DBGLEVEL >= DBG_EXTENDED) + Dbprintf("Button pressed, stopping."); + goto end; } } while (found_blocks < max_blocks); @@ -319,7 +334,7 @@ end: Dbprintf("-----------------------------------------"); } - reply_old(CMD_ACK, 0, 0, 0, 0, 0); + reply_mix(CMD_ACK, 0, 0, 0, 0, 0); } static void RealWritePCF7931(uint8_t *pass, uint16_t init_delay, int32_t l, int32_t p, uint8_t address, uint8_t byte, uint8_t data) { @@ -405,8 +420,12 @@ static void RealWritePCF7931(uint8_t *pass, uint16_t init_delay, int32_t l, int3 @param data : data to write */ void WritePCF7931(uint8_t pass1, uint8_t pass2, uint8_t pass3, uint8_t pass4, uint8_t pass5, uint8_t pass6, uint8_t pass7, uint16_t init_delay, int32_t l, int32_t p, uint8_t address, uint8_t byte, uint8_t data) { - Dbprintf("Initialization delay : %d us", init_delay); - Dbprintf("Offsets : %d us on the low pulses width, %d us on the low pulses positions", l, p); + + if ( DBGLEVEL >= DBG_INFO ) { + Dbprintf("Initialization delay : %d us", init_delay); + Dbprintf("Offsets : %d us on the low pulses width, %d us on the low pulses positions", l, p); + } + Dbprintf("Password (LSB first on each byte): %02x %02x %02x %02x %02x %02x %02x", pass1, pass2, pass3, pass4, pass5, pass6, pass7); Dbprintf("Block address : %02x", address); Dbprintf("Byte address : %02x", byte); @@ -425,8 +444,10 @@ void WritePCF7931(uint8_t pass1, uint8_t pass2, uint8_t pass3, uint8_t pass4, ui void SendCmdPCF7931(uint32_t *tab) { uint16_t u = 0, tempo = 0; - Dbprintf("Sending data frame..."); - + if ( DBGLEVEL >= DBG_INFO ) { + Dbprintf("Sending data frame..."); + } + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125kHz FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU); @@ -468,7 +489,6 @@ void SendCmdPCF7931(uint32_t *tab) { SpinDelay(200); AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; // timer disable - LED(0xFFFF, 1000); } @@ -482,13 +502,13 @@ bool AddBytePCF7931(uint8_t byte, uint32_t *tab, int32_t l, int32_t p) { uint32_t u; for (u = 0; u < 8; ++u) { if (byte & (1 << u)) { //bit is 1 - if (AddBitPCF7931(1, tab, l, p) == 1) return 1; + if (AddBitPCF7931(1, tab, l, p) == 1) return true; } else { //bit is 0 - if (AddBitPCF7931(0, tab, l, p) == 1) return 1; + if (AddBitPCF7931(0, tab, l, p) == 1) return true; } } - return 0; + return false; } /* Add a bits for building the data frame of PCF7931 tags @@ -501,7 +521,7 @@ bool AddBitPCF7931(bool b, uint32_t *tab, int32_t l, int32_t p) { uint8_t u = 0; //we put the cursor at the last value of the array - for (u = 0; tab[u] != 0; u += 3) { } + for (u = 0; tab[u] != 0; u += 3) { }; if (b == 1) { //add a bit 1 if (u == 0) @@ -511,7 +531,7 @@ bool AddBitPCF7931(bool b, uint32_t *tab, int32_t l, int32_t p) { tab[u + 1] = 6 * T0_PCF + tab[u] + l; tab[u + 2] = 88 * T0_PCF + tab[u + 1] - l - p; - return 0; + return false; } else { //add a bit 0 if (u == 0) @@ -521,9 +541,9 @@ bool AddBitPCF7931(bool b, uint32_t *tab, int32_t l, int32_t p) { tab[u + 1] = 6 * T0_PCF + tab[u] + l; tab[u + 2] = 24 * T0_PCF + tab[u + 1] - l - p; - return 0; + return false; } - return 1; + return true; } /* Add a custom pattern in the data frame @@ -540,5 +560,5 @@ bool AddPatternPCF7931(uint32_t a, uint32_t b, uint32_t c, uint32_t *tab) { tab[u + 1] = b + tab[u]; tab[u + 2] = c + tab[u + 1]; - return 0; + return true; } From ef281465ae728fbd480bc915317faf996a37711f Mon Sep 17 00:00:00 2001 From: 3ldidi94 Date: Thu, 12 Sep 2019 11:38:53 +0200 Subject: [PATCH 0665/1854] Add keys found on hardenest Mifare Classic Card Add keys found on hardenest Mifare Classic Card of an Hotel in Berlin (DE) --- client/dictionaries/mfc_default_keys.dic | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index 280604b3a..a12291199 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -1018,3 +1018,5 @@ e6849fcc324b # 0b83797a9c64 39ad2963d3d1 +34b16cd59ff8 # Hotel Berlin Classic room A KEY +bb2c0007d022 # Hotel Berlin Classic room B KEY From 9c61ac1375779108d005951967b83016f0a1e4aa Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Thu, 12 Sep 2019 16:13:36 +0300 Subject: [PATCH 0666/1854] additional fido CA --- client/fido/additional_ca.c | 80 ++++++++++++++++++++++++++++++++++++- 1 file changed, 79 insertions(+), 1 deletion(-) diff --git a/client/fido/additional_ca.c b/client/fido/additional_ca.c index 7ea103004..3c10a9de9 100644 --- a/client/fido/additional_ca.c +++ b/client/fido/additional_ca.c @@ -37,6 +37,7 @@ // Name: Yubico U2F Root CA Serial 457200631 // Issued: 2014-08-01 // https://github.com/Yubico/developers.yubico.com/tree/master/static/U2F +// https://fido-mds-parser.appspot.com/?url=https://mds.fidoalliance.org/metadata/7DwVE5vbRQysYTJrf95b3a #define YUBICO_CA \ "-----BEGIN CERTIFICATE-----\r\n" \ "MIIDHjCCAgagAwIBAgIEG0BT9zANBgkqhkiG9w0BAQsFADAuMSwwKgYDVQQDEyNZ\r\n" \ @@ -75,6 +76,83 @@ "jQGd7rwSZuE5RWUPVygYhUstQO9zNUOs\r\n" \ "-----END CERTIFICATE-----\r\n" +// FEITIAN U2F +// https://fido-mds-parser.appspot.com/?url=https://mds.fidoalliance.org/metadata/eS7v8sum4jxp7kgLQ5Qqcg +#define FEITIAN_U2F_CA \ + "-----BEGIN CERTIFICATE-----\r\n" \ + "MIIBfjCCASWgAwIBAgIBATAKBggqhkjOPQQDAjAXMRUwEwYDVQQDDAxGVCBGSURP\r\n" \ + "IDAyMDAwIBcNMTYwNTAxMDAwMDAwWhgPMjA1MDA1MDEwMDAwMDBaMBcxFTATBgNV\r\n" \ + "BAMMDEZUIEZJRE8gMDIwMDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABNBmrRqV\r\n" \ + "OxztTJVN19vtdqcL7tKQeol2nnM2/yYgvksZnr50SKbVgIEkzHQVOu80LVEE3lVh\r\n" \ + "eO1HjggxAlT6o4WjYDBeMB0GA1UdDgQWBBRJFWQt1bvG3jM6XgmV/IcjNtO/CzAf\r\n" \ + "BgNVHSMEGDAWgBRJFWQt1bvG3jM6XgmV/IcjNtO/CzAMBgNVHRMEBTADAQH/MA4G\r\n" \ + "A1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAgNHADBEAiAwfPqgIWIUB+QBBaVGsdHy\r\n" \ + "0s5RMxlkzpSX/zSyTZmUpQIgB2wJ6nZRM8oX/nA43Rh6SJovM2XwCCH//+LirBAb\r\n" \ + "B0M=\r\n" \ + "-----END CERTIFICATE-----\r\n" + +// FEITIAN FIDO2 +#define FEITIAN_FIDO2_CA \ + "-----BEGIN CERTIFICATE-----\r\n" \ + "MIIB2DCCAX6gAwIBAgIQGBUrQbdDrm20FZnDsX2CBTAKBggqhkjOPQQDAjBLMQsw\r\n" \ + "CQYDVQQGEwJVUzEdMBsGA1UECgwURmVpdGlhbiBUZWNobm9sb2dpZXMxHTAbBgNV\r\n" \ + "BAMMFEZlaXRpYW4gRklETyBSb290IENBMCAXDTE4MDQwMTAwMDAwMFoYDzIwNDgw\r\n" \ + "MzMxMjM1OTU5WjBLMQswCQYDVQQGEwJVUzEdMBsGA1UECgwURmVpdGlhbiBUZWNo\r\n" \ + "bm9sb2dpZXMxHTAbBgNVBAMMFEZlaXRpYW4gRklETyBSb290IENBMFkwEwYHKoZI\r\n" \ + "zj0CAQYIKoZIzj0DAQcDQgAEsFYEEhiJuqqnMgQjSiivBjV7DGCTf4XBBH/B7uvZ\r\n" \ + "sKxXShF0L8uDISWUvcExixRs6gB3oldSrjox6L8T94NOzqNCMEAwHQYDVR0OBBYE\r\n" \ + "FEu9hyYRrRyJzwRYvnDSCIxrFiO3MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/\r\n" \ + "BAQDAgEGMAoGCCqGSM49BAMCA0gAMEUCIDHSb2mbNDAUNXvpPU0oWKeNye0fQ2l9\r\n" \ + "D01AR2+sLZdhAiEAo3wz684IFMVsCCRmuJqxH6FQRESNqezuo1E+KkGxWuM=\r\n" \ + "-----END CERTIFICATE-----\r\n" + +// https://hypersecu.com/support/downloads +// HyperFIDO U2F Security Key Attestation CA +// Issuer: CN=FT FIDO 0100 +#define HYPERFIDO_U2F_1_CA \ + "-----BEGIN CERTIFICATE-----\r\n" \ + "MIIBjTCCATOgAwIBAgIBATAKBggqhkjOPQQDAjAXMRUwEwYDVQQDEwxGVCBGSURP\r\n" \ + "IDAxMDAwHhcNMTQwNzAxMTUzNjI2WhcNNDQwNzAzMTUzNjI2WjAXMRUwEwYDVQQD\r\n" \ + "EwxGVCBGSURPIDAxMDAwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASxdLxJx8ol\r\n" \ + "S3DS5cIHzunPF0gg69d+o8ZVCMJtpRtlfBzGuVL4YhaXk2SC2gptPTgmpZCV2vbN\r\n" \ + "fAPi5gOF0vbZo3AwbjAdBgNVHQ4EFgQUXt4jWlYDgwhaPU+EqLmeM9LoPRMwPwYD\r\n" \ + "VR0jBDgwNoAUXt4jWlYDgwhaPU+EqLmeM9LoPROhG6QZMBcxFTATBgNVBAMTDEZU\r\n" \ + "IEZJRE8gMDEwMIIBATAMBgNVHRMEBTADAQH/MAoGCCqGSM49BAMCA0gAMEUCIQC2\r\n" \ + "D9o9cconKTo8+4GZPyZBJ3amc8F0/kzyidX9dhrAIAIgM9ocs5BW/JfmshVP9Mb+\r\n" \ + "Joa/kgX4dWbZxrk0ioTfJZg=\r\n" \ + "-----END CERTIFICATE-----\r\n" + +// Issuer: CN= HYPERFIDO 0200 +#define HYPERFIDO_U2F_2_CA \ + "-----BEGIN CERTIFICATE-----\r\n" \ + "MIIBxzCCAWygAwIBAgICEAswCgYIKoZIzj0EAwIwOjELMAkGA1UEBhMCQ0ExEjAQ\r\n" \ + "BgNVBAoMCUhZUEVSU0VDVTEXMBUGA1UEAwwOSFlQRVJGSURPIDAyMDAwIBcNMTgw\r\n" \ + "MTAxMDAwMDAwWhgPMjA0NzEyMzEyMzU5NTlaMDoxCzAJBgNVBAYTAkNBMRIwEAYD\r\n" \ + "VQQKDAlIWVBFUlNFQ1UxFzAVBgNVBAMMDkhZUEVSRklETyAwMjAwMFkwEwYHKoZI\r\n" \ + "zj0CAQYIKoZIzj0DAQcDQgAErKUI1G0S7a6IOLlmHipLlBuxTYjsEESQvzQh3dB7\r\n" \ + "dvxxWWm7kWL91rq6S7ayZG0gZPR+zYqdFzwAYDcG4+aX66NgMF4wHQYDVR0OBBYE\r\n" \ + "FLZYcfMMwkQAGbt3ryzZFPFypmsIMB8GA1UdIwQYMBaAFLZYcfMMwkQAGbt3ryzZ\r\n" \ + "FPFypmsIMAwGA1UdEwQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMAoGCCqGSM49BAMC\r\n" \ + "A0kAMEYCIQCG2/ppMGt7pkcRie5YIohS3uDPIrmiRcTjqDclKVWg0gIhANcPNDZH\r\n" \ + "E2/zZ+uB5ThG9OZus+xSb4knkrbAyXKX2zm/\r\n" \ + "-----END CERTIFICATE-----\r\n" + +// NXP +// https://fido-mds-parser.appspot.com/?url=https://mds.fidoalliance.org/metadata/JKP5CiDehdMMPwtG5i7to5 +#define NXP_U2F_CA \ + "-----BEGIN CERTIFICATE-----\r\n" \ + "MIIBjzCCATWgAwIBAgIJASNFZ4mrze8BMAoGCCqGSM49BAMCMCgxJjAkBgNVBAMM\r\n" \ + "HU5YUCBTZW1pY29uZHVjdG9yIFUyRiBSb290IENBMB4XDTE1MTIxNjE2MDUxMFoX\r\n" \ + "DTI1MTIxMzE2MDUxMFowGjEYMBYGA1UEAwwPTlhQIEZJRE8gVTJGIHYwMFkwEwYH\r\n" \ + "KoZIzj0CAQYIKoZIzj0DAQcDQgAExbuQcVAAX7IPwqVVVX/ni3Ch3Zzo04WkSsr5\r\n" \ + "nHXpEarB+sd846FAi/o3a7oF1+u/oV65syguDD/0FaUGuUgTpKNWMFQwDAYDVR0T\r\n" \ + "AQH/BAIwADAOBgNVHQ8BAf8EBAMCB4AwHwYDVR0jBBgwFoAUpaNTDgOg8hGDmawL\r\n" \ + "bDydVSoNNPgwEwYLKwYBBAGC5RwCAQEEBAMCBDAwCgYIKoZIzj0EAwIDSAAwRQIh\r\n" \ + "AJlr23jig2LxRM1PpgMAQXnZJy/HnkRB9O8KD0o2oK/mAiBG5EK1S3yVHdkkVGTJ\r\n" \ + "Q12ffuK8Op7Nx89cszCr0WyIhQ==\r\n" \ + "-----END CERTIFICATE-----\r\n" + /* Concatenation of all additional CA certificates in PEM format if available */ -const char additional_ca_pem[] = GLOBALSIGN_CA YUBICO_CA SOLOKEY_CA; +const char additional_ca_pem[] = GLOBALSIGN_CA YUBICO_CA SOLOKEY_CA \ + FEITIAN_U2F_CA FEITIAN_FIDO2_CA HYPERFIDO_U2F_1_CA HYPERFIDO_U2F_2_CA NXP_U2F_CA; const size_t additional_ca_pem_len = sizeof(additional_ca_pem); From c3a0d7d88a6bfa22ac6d330c2e704bbe677e7243 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 12 Sep 2019 17:34:55 +0200 Subject: [PATCH 0667/1854] chg: 'lf t55xx info p' - got some more love, now can read with password :) chg: 'lf t55xx dump p' - less outputs and now can read with password :) chg: 'lf t55xx trace 1' - can now decode trace from a saved trace. However you must have correct configuration set in order to work. chg: 'lf t55xx wipe p' - now can use a password to write to configblock first. --- client/cmdlft55xx.c | 542 ++++++++++++++++++++++++++++---------------- 1 file changed, 348 insertions(+), 194 deletions(-) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 55b711482..320b193b6 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -91,6 +91,17 @@ static int usage_t55xx_read() { PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } +static int usage_t55xx_resetread() { + PrintAndLogEx(NORMAL, "Send Reset Cmd then lf read the stream to attempt to identify the start of it (needs a demod and/or plot after)"); + PrintAndLogEx(NORMAL, "Usage: lf t55xx resetread [r ]"); + PrintAndLogEx(NORMAL, "Options:"); + print_usage_t55xx_downloadlink(); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Examples:"); + PrintAndLogEx(NORMAL, " lf t55xx resetread"); + PrintAndLogEx(NORMAL, ""); + return PM3_SUCCESS; +} static int usage_t55xx_write() { PrintAndLogEx(NORMAL, "Usage: lf t55xx write [r ] b d [p ] [1] [t]"); PrintAndLogEx(NORMAL, "Options:"); @@ -108,26 +119,26 @@ static int usage_t55xx_write() { return PM3_SUCCESS; } static int usage_t55xx_trace() { - PrintAndLogEx(NORMAL, "Usage: lf t55xx trace [r mode]"); + PrintAndLogEx(NORMAL, "Usage: lf t55xx trace [1] [r mode]"); PrintAndLogEx(NORMAL, "Options:"); print_usage_t55xx_downloadlink(); - // Command did not seem to support the 1 option (yet) so have removed the help lines - // PrintAndLogEx(NORMAL, " 1 - if set, use Graphbuffer otherwise read data from tag."); + PrintAndLogEx(NORMAL, " 1 - if set, use Graphbuffer otherwise read data from tag."); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx trace"); - // PrintAndLogEx(NORMAL, " lf t55xx trace 1"); + PrintAndLogEx(NORMAL, " lf t55xx trace 1"); PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } static int usage_t55xx_info() { PrintAndLogEx(NORMAL, "Usage: lf t55xx info [1] [r ] [d [q]]"); PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " (default) - read data from tag."); - PrintAndLogEx(NORMAL, " 1 - if set, use Graphbuffer instead of reading tag."); - PrintAndLogEx(NORMAL, " d - 4 bytes of data (8 hex characters)"); - PrintAndLogEx(NORMAL, " if set, use these data instead of reading tag."); - PrintAndLogEx(NORMAL, " q - if set, provided data are interpreted as Q5 config."); + PrintAndLogEx(NORMAL, " (default) - read data from tag."); + PrintAndLogEx(NORMAL, " p - OPTIONAL password 4bytes (8 hex symbols)"); + PrintAndLogEx(NORMAL, " 1 - if set, use Graphbuffer instead of reading tag."); + PrintAndLogEx(NORMAL, " d - 4 bytes of data (8 hex characters)"); + PrintAndLogEx(NORMAL, " if set, use these data instead of reading tag."); + PrintAndLogEx(NORMAL, " q - if set, provided data are interpreted as Q5 config."); print_usage_t55xx_downloadlink(); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); @@ -135,19 +146,20 @@ static int usage_t55xx_info() { PrintAndLogEx(NORMAL, " lf t55xx info 1"); PrintAndLogEx(NORMAL, " lf t55xx info d 00083040"); PrintAndLogEx(NORMAL, " lf t55xx info d 6001805A q"); + PrintAndLogEx(NORMAL, " lf t55xx info p 11223344"); PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } static int usage_t55xx_dump() { - PrintAndLogEx(NORMAL, "Usage: lf t55xx dump [r ] [ [o]]"); + PrintAndLogEx(NORMAL, "Usage: lf t55xx dump [r ] [p [o]]"); PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " - OPTIONAL password 4bytes (8 hex symbols)"); - PrintAndLogEx(NORMAL, " o - OPTIONAL override, force pwd read despite danger to card"); + PrintAndLogEx(NORMAL, " p - OPTIONAL password 4bytes (8 hex symbols)"); + PrintAndLogEx(NORMAL, " o - OPTIONAL override, force pwd read despite danger to card"); print_usage_t55xx_downloadlink(); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx dump"); - PrintAndLogEx(NORMAL, " lf t55xx dump feedbeef o"); + PrintAndLogEx(NORMAL, " lf t55xx dump p feedbeef o"); PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } @@ -215,16 +227,16 @@ static int usage_t55xx_bruteforce() { PrintAndLogEx(NORMAL, "press " _YELLOW_("'enter'") " to cancel the command"); PrintAndLogEx(NORMAL, "WARNING: this may brick non-password protected chips!"); PrintAndLogEx(NORMAL, "Try reading block 7 before\n"); - PrintAndLogEx(NORMAL, "Usage: lf t55xx bruteforce [h] [r ] "); + PrintAndLogEx(NORMAL, "Usage: lf t55xx bruteforce [h] [r ] [s ] [e ]"); PrintAndLogEx(NORMAL, " password must be 4 bytes (8 hex symbols)"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h - this help"); print_usage_t55xx_downloadlink(); - PrintAndLogEx(NORMAL, " - 4 byte hex value to start pwd search at"); - PrintAndLogEx(NORMAL, " - 4 byte hex value to end pwd search at"); + PrintAndLogEx(NORMAL, " s - 4 byte hex value to start pwd search at"); + PrintAndLogEx(NORMAL, " e - 4 byte hex value to end pwd search at"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " lf t55xx bruteforce r 2 aaaaaa77 aaaaaa99"); + PrintAndLogEx(NORMAL, " lf t55xx bruteforce r 2 s aaaaaa77 e aaaaaa99"); PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } @@ -248,15 +260,15 @@ static int usage_t55xx_recoverpw() { return PM3_SUCCESS; } static int usage_t55xx_wipe() { - PrintAndLogEx(NORMAL, "Usage: lf t55xx wipe [h] [Q5]"); + PrintAndLogEx(NORMAL, "Usage: lf t55xx wipe [h] [Q5] [p ]"); PrintAndLogEx(NORMAL, "This commands wipes a tag, fills blocks 1-7 with zeros and a default configuration block"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h - this help"); - PrintAndLogEx(NORMAL, " Q5 - indicates to use the T5555 (Q5) default configuration block"); + PrintAndLogEx(NORMAL, " q - indicates to use the T5555 (Q5) default configuration block"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " lf t55xx wipe - wipes a t55x7 tag, config block 0x000880E0"); - PrintAndLogEx(NORMAL, " lf t55xx wipe Q5 - wipes a t5555 Q5 tag, config block 0x6001F004"); + PrintAndLogEx(NORMAL, " lf t55xx wipe - wipes a t55x7 tag, config block 0x000880E0"); + PrintAndLogEx(NORMAL, " lf t55xx wipe q - wipes a t5555 Q5 tag, config block 0x6001F004"); return PM3_SUCCESS; } static int usage_lf_deviceconfig() { @@ -292,6 +304,9 @@ void printT5xxHeader(uint8_t page) { static int CmdT55xxSetConfig(const char *Cmd) { + // No args + if (strlen(Cmd) == 0) return printConfiguration(config); + uint8_t offset = 0, bitRate = 0; char modulation[6] = {0x00}; uint8_t rates[9] = {8, 16, 32, 40, 50, 64, 100, 128, 0}; @@ -395,9 +410,6 @@ static int CmdT55xxSetConfig(const char *Cmd) { } } - // No args - if (cmdp == 0) return printConfiguration(config); - //Validations if (errors) return usage_t55xx_config(); @@ -418,19 +430,17 @@ int T55xxReadBlock(uint8_t block, bool page1, bool usepwd, uint8_t override, uin } else { PrintAndLogEx(NORMAL, "Safety Check: PWD bit is NOT set in config block. Reading without password..."); usepwd = false; - page1 = false; + page1 = false; // ?? } - } else { + } else if (override == 1) { // Show only if first for command i.e. override = 1 (override and display) override = 2 (override and dont display) - if (override == 1) - PrintAndLogEx(NORMAL, "Safety Check Overriden - proceeding despite risk"); + PrintAndLogEx(NORMAL, "Safety Check Overriden - proceeding despite risk"); } } - if (!AquireData(page1, block, usepwd, password, downlink_mode)) return PM3_ESOFT; - + if (!DecodeT55xxBlock()) return PM3_ESOFT; @@ -470,8 +480,10 @@ static int CmdT55xxReadBlock(const char *Cmd) { cmdp++; break; case 'r': - downlink_mode = param_getchar(Cmd, cmdp + 1) - '0'; - if (downlink_mode > 3) downlink_mode = 0; + downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); + if (downlink_mode > 3) + downlink_mode = 0; + cmdp += 2; break; @@ -595,15 +607,15 @@ void T55xx_Print_DownlinkMode(uint8_t downlink_mode) { // static int CmdT55xxDetect(const char *Cmd) { - bool errors = false; - bool useGB = false; - bool usepwd = false; - bool try_all_dl_modes = false; - bool found = false; - uint32_t password = 0; - uint8_t cmdp = 0; - uint8_t downlink_mode = 0; - uint8_t dl_mode = 0; + bool errors = false; + bool useGB = false; + bool usepwd = false; + bool try_all_dl_modes = false; + bool found = false; + uint32_t password = 0; + uint8_t cmdp = 0; + uint8_t downlink_mode = 0; + uint8_t dl_mode = 0; while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { @@ -620,9 +632,13 @@ static int CmdT55xxDetect(const char *Cmd) { cmdp++; break; case 'r': - downlink_mode = param_getchar(Cmd, cmdp + 1) - '0'; - if (downlink_mode == 4) try_all_dl_modes = true; - if (downlink_mode > 3) downlink_mode = 0; + downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); + if (downlink_mode == 4) + try_all_dl_modes = true; + + if (downlink_mode > 3) + downlink_mode = 0; + cmdp += 2; break; default: @@ -1109,24 +1125,24 @@ int special(const char *Cmd) { } int printConfiguration(t55xx_conf_block_t b) { - PrintAndLogEx(NORMAL, "Chip Type : %s", (b.Q5) ? "T5555(Q5)" : "T55x7"); - PrintAndLogEx(NORMAL, "Modulation : %s", GetSelectedModulationStr(b.modulation)); - PrintAndLogEx(NORMAL, "Bit Rate : %s", GetBitRateStr(b.bitrate, (b.block0 & T55x7_X_MODE && (b.block0 >> 28 == 6 || b.block0 >> 28 == 9)))); - PrintAndLogEx(NORMAL, "Inverted : %s", (b.inverted) ? _GREEN_("Yes") : "No"); - PrintAndLogEx(NORMAL, "Offset : %d", b.offset); - PrintAndLogEx(NORMAL, "Seq. Term. : %s", (b.ST) ? _GREEN_("Yes") : "No"); - PrintAndLogEx(NORMAL, "Block0 : 0x%08X", b.block0); + PrintAndLogEx(NORMAL, " Chip Type : %s", (b.Q5) ? "T5555(Q5)" : "T55x7"); + PrintAndLogEx(NORMAL, " Modulation : %s", GetSelectedModulationStr(b.modulation)); + PrintAndLogEx(NORMAL, " Bit Rate : %s", GetBitRateStr(b.bitrate, (b.block0 & T55x7_X_MODE && (b.block0 >> 28 == 6 || b.block0 >> 28 == 9)))); + PrintAndLogEx(NORMAL, " Inverted : %s", (b.inverted) ? _GREEN_("Yes") : "No"); + PrintAndLogEx(NORMAL, " Offset : %d", b.offset); + PrintAndLogEx(NORMAL, " Seq. Term. : %s", (b.ST) ? _GREEN_("Yes") : "No"); + PrintAndLogEx(NORMAL, " Block0 : 0x%08X", b.block0); PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } static int CmdT55xxWakeUp(const char *Cmd) { - uint32_t password = 0; - uint8_t cmdp = 0; - bool errors = false; - uint8_t downlink_mode = 0; - uint8_t flags = 0; + uint32_t password = 0; + uint8_t cmdp = 0; + bool errors = false; + uint8_t downlink_mode = 0; + uint8_t flags = 0; while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { @@ -1135,11 +1151,12 @@ static int CmdT55xxWakeUp(const char *Cmd) { case 'p': password = param_get32ex(Cmd, cmdp + 1, 0, 16); cmdp += 2; - errors = false; break; case 'r': - downlink_mode = param_getchar(Cmd, cmdp + 1) - '0'; - if (downlink_mode > 3) downlink_mode = 0; + downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); + if (downlink_mode > 3) + downlink_mode = 0; + cmdp += 2; break; default: @@ -1160,15 +1177,15 @@ static int CmdT55xxWakeUp(const char *Cmd) { } static int CmdT55xxWriteBlock(const char *Cmd) { - uint8_t block = 0xFF; //default to invalid block - uint32_t data = 0; //default to blank Block - uint32_t password = 0; //default to blank Block 7 - bool usepwd = false; - bool page1 = false; - bool gotdata = false; - bool testMode = false; - bool errors = false; - uint8_t cmdp = 0; + uint8_t block = 0xFF; // default to invalid block + uint32_t data = 0; // default to blank Block + uint32_t password = 0; // default to blank Block 7 + bool usepwd = false; + bool page1 = false; + bool gotdata = false; + bool testMode = false; + bool errors = false; + uint8_t cmdp = 0; uint32_t downlink_mode = 0; while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { @@ -1203,8 +1220,10 @@ static int CmdT55xxWriteBlock(const char *Cmd) { cmdp++; break; case 'r': - downlink_mode = param_getchar(Cmd, cmdp + 1) - '0'; - if (downlink_mode > 3) downlink_mode = 0; + downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); + if (downlink_mode > 3) + downlink_mode = 0; + cmdp += 2; break; default: @@ -1254,29 +1273,47 @@ static int CmdT55xxWriteBlock(const char *Cmd) { } static int CmdT55xxReadTrace(const char *Cmd) { - uint8_t cmd_len = 0; + + bool frombuff = false; uint8_t downlink_mode = 0; - - char cmdp = tolower(param_getchar(Cmd, 0)); - if (cmdp == 'r') { - downlink_mode = param_getchar(Cmd, 1) - '0'; - if (downlink_mode > 3) downlink_mode = 0; - cmd_len = 3; + uint8_t cmdp = 0; + bool errors = false; + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { + case 'h': + return usage_t55xx_trace(); + case 'r': + downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); + if (downlink_mode > 3) + downlink_mode = 0; + + cmdp += 2; + break; + case '1': + frombuff = true; + cmdp += 2; + break; + default: + PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } } - if ((strlen(Cmd) != cmd_len) || (cmdp == 'h')) return usage_t55xx_trace(); - if (strlen(Cmd) == cmd_len) { + if (errors) return usage_t55xx_trace(); + + if (!frombuff) { // sanity check. if (SanityOfflineCheck(false) != PM3_SUCCESS) return PM3_ENODATA; bool pwdmode = false; uint32_t password = 0; -// REGULAR_READ_MODE_BLOCK - yeilds correct Page 1 Block 2 data i.e. + 32 bit offset. -// if (!AquireData(T55x7_PAGE1, T55x7_TRACE_BLOCK1, pwdmode, password,downlink_mode)) + + // REGULAR_READ_MODE_BLOCK - yeilds correct Page 1 Block 2 data i.e. + 32 bit offset. if (!AquireData(T55x7_PAGE1, REGULAR_READ_MODE_BLOCK, pwdmode, password, downlink_mode)) return PM3_ENODATA; } - + if (config.Q5) { if (!DecodeT5555TraceBlock()) return PM3_ESOFT; } else { @@ -1515,10 +1552,10 @@ static int CmdT55xxInfo(const char *Cmd) { Normal mode Extended mode */ - bool frombuff = false, gotdata = false, dataasq5 = false; - uint8_t cmdp = 0; - uint8_t downlink_mode = 0; - uint32_t block0 = 0; + bool frombuff = false, gotdata = false, dataasq5 = false, usepwd = false; + uint8_t cmdp = 0; + uint8_t downlink_mode = 0; + uint32_t block0 = 0, password = 0; while (param_getchar(Cmd, cmdp) != 0x00) { switch (tolower(param_getchar(Cmd, cmdp))) { @@ -1529,6 +1566,11 @@ static int CmdT55xxInfo(const char *Cmd) { gotdata = true; cmdp += 2; break; + case 'p': + password = param_get32ex(Cmd, cmdp + 1, 0, 16); + usepwd = true; + cmdp += 2; + break; case '1': frombuff = true; cmdp += 2; @@ -1538,8 +1580,10 @@ static int CmdT55xxInfo(const char *Cmd) { cmdp += 2; break; case 'r': - downlink_mode = param_getchar(Cmd, cmdp + 1) - '0'; - if (downlink_mode > 3) downlink_mode = 0; + downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); + if (downlink_mode > 3) + downlink_mode = 0; + cmdp += 2; break; default: @@ -1558,11 +1602,10 @@ static int CmdT55xxInfo(const char *Cmd) { // sanity check. if (SanityOfflineCheck(false) != PM3_SUCCESS) return PM3_ENODATA; - bool pwdmode = false; - uint32_t password = 0; - if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, pwdmode, password, downlink_mode)) + if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, downlink_mode)) return PM3_ENODATA; } + if (!gotdata) { if (!DecodeT55xxBlock()) return PM3_ESOFT; @@ -1657,26 +1700,38 @@ static int CmdT55xxDump(const char *Cmd) { uint32_t password = 0; uint8_t override = 0; - uint8_t cmd_opt_idx = 0; uint8_t downlink_mode = 0; - uint8_t pwd_offset = 0; - char cmdp = tolower(param_getchar(Cmd, 0)); + bool usepwd = false; + bool errors = false; + uint8_t cmdp = 0; - if (cmdp == 'h') return usage_t55xx_dump(); - if (cmdp == 'r') { - cmd_opt_idx++; - downlink_mode = param_getchar(Cmd, cmd_opt_idx++) - '0'; - if (downlink_mode > 3) - downlink_mode = 0; - - pwd_offset = 3; - } - bool usepwd = (strlen(Cmd) > pwd_offset); - if (usepwd) { - password = param_get32ex(Cmd, cmd_opt_idx++, 0, 16); - if (param_getchar(Cmd, cmd_opt_idx++) == 'o') - override = 1; + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { + case 'h': + return usage_t55xx_dump(); + case 'r': + downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); + if (downlink_mode > 3) + downlink_mode = 0; + + cmdp += 2; + break; + case 'p': + password = param_get32ex(Cmd, cmdp + 1, 0, 16); + usepwd = true; + cmdp += 2; + break; + case 'o': + override = 1; + cmdp++; + break; + default: + PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } } + if (errors) return usage_t55xx_dump(); printT5xxHeader(0); for (uint8_t i = 0; i < 8; ++i) { @@ -1973,16 +2028,34 @@ static void t55x7_create_config_block(int tagtype) { static int CmdResetRead(const char *Cmd) { uint8_t downlink_mode = 0; - uint8_t flags = 0; + uint8_t flags = 0; + uint8_t cmdp = 0; + bool errors = false; + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { + case 'h': + return usage_t55xx_resetread(); + case 'r': + downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); + if (downlink_mode > 3) + downlink_mode = 0; + + cmdp += 2; + break; + default: + PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } + } - if (strlen(Cmd) == 3) - downlink_mode = param_getchar(Cmd, 1) - '0'; + if (errors) return usage_t55xx_resetread(); - if (downlink_mode > 3) downlink_mode = 0; - - printf("DL : %d\n", downlink_mode); + PrintAndLogEx(INFO, "DL : %d\n", downlink_mode); + flags = downlink_mode << 3; + clearCommandBuffer(); SendCommandNG(CMD_LF_T55XX_RESET_READ, &flags, sizeof(flags)); if (!WaitForResponseTimeout(CMD_ACK, NULL, 2500)) { @@ -2002,27 +2075,63 @@ static int CmdResetRead(const char *Cmd) { static int CmdT55xxWipe(const char *Cmd) { char writeData[20] = {0}; char *ptrData = writeData; - char cmdp = tolower(param_getchar(Cmd, 0)); - if (cmdp == 'h') return usage_t55xx_wipe(); + uint32_t password = 0; + bool usepwd = false; + bool Q5 = false; + uint8_t cmdp = 0; + bool errors = false; - bool Q5 = (cmdp == 'q'); + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { + case 'h': + return usage_t55xx_wipe(); + case 'p': + // password used by handheld cloners + password = param_get32ex(Cmd, cmdp + 1, 0x51243648, 16); + usepwd = true; + cmdp += 2; + break; + case 'q': + Q5 = true; + cmdp++; + break; + default: + PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } + } + + if (errors) return usage_t55xx_wipe(); // Try with the default password to reset block 0 // With a pwd should work even if pwd bit not set PrintAndLogEx(INFO, "\nBeginning Wipe of a T55xx tag (assuming the tag is not password protected)\n"); - if (Q5) - snprintf(ptrData, sizeof(writeData), "b 0 d 6001F004 p 0"); - else - snprintf(ptrData, sizeof(writeData), "b 0 d 000880E0 p 0"); - if (CmdT55xxWriteBlock(ptrData) != PM3_SUCCESS) PrintAndLogEx(WARNING, "Warning: error writing blk 0"); + if (usepwd) { + snprintf(ptrData, sizeof(writeData), "b 0 p %08x ", password); + } else { + snprintf(ptrData, sizeof(writeData), "b 0 "); + } + + if (Q5) + snprintf(ptrData + strlen(ptrData), sizeof(writeData) - strlen(ptrData), "d 6001F004"); + else + snprintf(ptrData + strlen(ptrData), sizeof(writeData) - strlen(ptrData), "d 000880E0"); + + PrintAndLogEx(INFO, "%s", ptrData); + return 0; + + if (CmdT55xxWriteBlock(ptrData) != PM3_SUCCESS) + PrintAndLogEx(WARNING, "Warning: error writing blk 0"); for (uint8_t blk = 1; blk < 8; blk++) { snprintf(ptrData, sizeof(writeData), "b %d d 0", blk); - if (CmdT55xxWriteBlock(ptrData) != PM3_SUCCESS) PrintAndLogEx(WARNING, "Warning: error writing blk %d", blk); + if (CmdT55xxWriteBlock(ptrData) != PM3_SUCCESS) + PrintAndLogEx(WARNING, "Warning: error writing blk %d", blk); memset(writeData, 0x00, sizeof(writeData)); } @@ -2040,44 +2149,52 @@ static bool IsCancelled(void) { // load a default pwd file. static int CmdT55xxChkPwds(const char *Cmd) { - char filename[FILE_PATH_SIZE] = {0}; - bool found = false; + char filename[FILE_PATH_SIZE] = {0}; + bool found = false; uint8_t timeout = 0; uint8_t *keyBlock = NULL; - bool from_flash = false; - bool try_all_dl_modes = false; + bool from_flash = false; + bool try_all_dl_modes = false; uint8_t downlink_mode = 0; - int len; - char cmdp; - bool use_pwd_file = false; - int dl_mode; // to try each downlink mode for each password + bool use_pwd_file = false; + int dl_mode; // to try each downlink mode for each password + uint8_t cmdp = 0; + bool errors = false; - - cmdp = tolower(param_getchar(Cmd, 0)); - - if (cmdp == 'h') return usage_t55xx_chk(); - if (cmdp == 'm') { - from_flash = true; - Cmd += 2; - cmdp = tolower(param_getchar(Cmd, 0)); - } - if (cmdp == 'r') { - Cmd += 2; - downlink_mode = param_getchar(Cmd, 0) - '0'; // get 2nd option, as this is fixed order. - if (downlink_mode == 4) try_all_dl_modes = true; - if (downlink_mode > 3) downlink_mode = 0; - Cmd += 2; - cmdp = param_getchar(Cmd, 0); - } - if (cmdp == 'i') { - Cmd += 2; - len = strlen(Cmd); - if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE; - memcpy(filename, Cmd, len); - use_pwd_file = true; + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { + case 'h': + return usage_t55xx_chk(); + case 'r': + downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); + if (downlink_mode == 4) + try_all_dl_modes = true; + + if (downlink_mode > 3) + downlink_mode = 0; + + cmdp += 2; + break; + case 'm': + from_flash = true; + cmdp++; + break; + case 'i': + if ( param_getstr(Cmd, cmdp + 1, filename, sizeof(filename)) == 0 ) { + PrintAndLogEx(ERR, "Error, no filename after 'f' was found"); + errors = true; + } + use_pwd_file = true; + cmdp += 2; + break; + default: + PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } } - + if (errors) return usage_t55xx_chk(); /* // block 7, page1 = false, usepwd = false, override = false, pwd = 00000000 @@ -2191,33 +2308,48 @@ out: static int CmdT55xxBruteForce(const char *Cmd) { uint32_t start_password = 0x00000000; //start password - uint32_t end_password = 0xFFFFFFFF; //end password - uint32_t curr = 0; - uint8_t downlink_mode = 0; - uint8_t cmd_opt_idx = 0; - uint8_t found = 0; // > 0 if found xx1 xx downlink needed, 1 found + uint32_t end_password = 0xFFFFFFFF; //end password + uint32_t curr = 0; + uint8_t downlink_mode = 0; + uint8_t found = 0; // > 0 if found xx1 xx downlink needed, 1 found + uint8_t cmdp = 0; + bool errors = false; - char cmdp = tolower(param_getchar(Cmd, cmd_opt_idx)); - - if (cmdp == 'h') return usage_t55xx_bruteforce(); - if (cmdp == 'r') { // downlink mode supplied - cmd_opt_idx++; // skip over 'r' - downlink_mode = param_getchar(Cmd, cmd_opt_idx++) - '0'; - if (downlink_mode > 4) downlink_mode = 0; + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { + case 'h': + return usage_t55xx_bruteforce(); + case 'r': + downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); + if (downlink_mode > 4) + downlink_mode = 0; + + cmdp += 2; + break; + case 's': + start_password = param_get32ex(Cmd, cmdp + 1, 0, 16); + cmdp += 2; + break; + case 'e': + end_password = param_get32ex(Cmd, cmdp + 1, 0, 16); + cmdp += 2; + break; + default: + PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } } - - - uint64_t t1 = msclock(); - - start_password = param_get32ex(Cmd, cmd_opt_idx++, 0, 16); - end_password = param_get32ex(Cmd, cmd_opt_idx++, 0, 16); - - curr = start_password; - if (start_password >= end_password) { return usage_t55xx_bruteforce(); } + if (errors) return usage_t55xx_bruteforce(); + + uint64_t t1 = msclock(); + + curr = start_password; + PrintAndLogEx(INFO, "Search password range [%08X -> %08X]", start_password, end_password); while (found == 0) { @@ -2278,25 +2410,41 @@ uint8_t tryOnePassword(uint32_t password, uint8_t downlink_mode) { } static int CmdT55xxRecoverPW(const char *Cmd) { - int bit = 0; + int bit = 0; uint32_t orig_password = 0x0; uint32_t curr_password = 0x0; uint32_t prev_password = 0xffffffff; - uint32_t mask = 0x0; - uint8_t downlink_mode = 0; - uint8_t found = 0; - uint8_t cmd_opt_idx = 0; + uint32_t mask = 0x0; + uint8_t downlink_mode = 0; + uint8_t found = 0; + uint8_t cmdp = 0; + bool errors = false; - char cmdp = tolower(param_getchar(Cmd, cmd_opt_idx)); - - if (cmdp == 'h') return usage_t55xx_recoverpw(); - if (cmdp == 'r') { // downlink mode supplied - cmd_opt_idx++; // skip over 'r' - downlink_mode = param_getchar(Cmd, cmd_opt_idx++) - '0'; - if (downlink_mode > 4) downlink_mode = 0; + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { + case 'h': + return usage_t55xx_recoverpw(); + case 'p': + // password used by handheld cloners + orig_password = param_get32ex(Cmd, cmdp + 1, 0x51243648, 16); + cmdp += 2; + break; + case 'r': + downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); + if (downlink_mode > 4) + downlink_mode = 0; + + cmdp += 2; + break; + default: + PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } } - orig_password = param_get32ex(Cmd, cmd_opt_idx++, 0x51243648, 16); //password used by handheld cloners + if (errors) return usage_t55xx_recoverpw(); + // first try fliping each bit in the expected password while (bit < 32) { @@ -2511,9 +2659,13 @@ static int CmdT55xxDetectPage1(const char *Cmd) { cmdp++; break; case 'r': - downlink_mode = param_getchar(Cmd, cmdp + 1) - '0'; - if (downlink_mode == 4) try_all_dl_modes = true; - if (downlink_mode > 3) downlink_mode = 0; + downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); + if (downlink_mode == 4) + try_all_dl_modes = true; + + if (downlink_mode > 3) + downlink_mode = 0; + cmdp += 2; break; default: @@ -2589,8 +2741,10 @@ static int CmdT55xxSetDeviceConfig(const char *Cmd) { cmdp += 2; break; case 'r': - downlink_mode = param_getchar(Cmd, cmdp + 1) - '0'; - if (downlink_mode > 3) downlink_mode = 0; + downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); + if (downlink_mode > 3) + downlink_mode = 0; + cmdp += 2; break; case 'p': From 4eab354f448a87c2426a707639af5c1d1a97b2b8 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 12 Sep 2019 17:37:36 +0200 Subject: [PATCH 0668/1854] chg: 'lf samyrun' standalone - rework of LED messages. A = bank A reading B = bank B reading A,C = bank A simulating A,D = bank A cloning B,C = bank B simulating B,D = bank B cloning One button press to go between steps. Maybe practice with the proxmark3 device connected with usb-cable to see the new steps. --- armsrc/Standalone/lf_samyrun.c | 184 +++++++++++++++------------------ 1 file changed, 82 insertions(+), 102 deletions(-) diff --git a/armsrc/Standalone/lf_samyrun.c b/armsrc/Standalone/lf_samyrun.c index 8228db512..5e1a35c73 100644 --- a/armsrc/Standalone/lf_samyrun.c +++ b/armsrc/Standalone/lf_samyrun.c @@ -24,131 +24,111 @@ void ModInfo(void) { } // samy's sniff and repeat routine for LF + +// LEDS. +// A , B == which bank (recording) +// FLASHING A, B = clone bank +// C = playing bank A +// D = playing bank B + void RunMod() { StandAloneMode(); - Dbprintf(">> LF HID Read/Clone/Sim a.k.a SamyRun Started <<"); FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + Dbprintf(">> LF HID Read/Clone/Sim a.k.a SamyRun Started <<"); uint32_t high[OPTS], low[OPTS]; int selected = 0; - int playing = 0; - int cardRead = 0; - bool gotCard; - // Turn on selected LED - LED(selected + 1, 0); +#define STATE_READ 0 +#define STATE_SIM 1 +#define STATE_CLONE 2 + + uint8_t state = STATE_READ; + for (;;) { + WDT_HIT(); - + // exit from SamyRun, send a usbcommand. if (data_available()) break; // Was our button held down or pressed? - int button_pressed = BUTTON_HELD(1000); + int button_pressed = BUTTON_HELD(280); + if ( button_pressed != BUTTON_HOLD ) + continue; +/* +#define BUTTON_NO_CLICK 0 +#define BUTTON_SINGLE_CLICK -1 +#define BUTTON_DOUBLE_CLICK -2 +*/ - Dbprintf("button %d", button_pressed); - SpinDelay(300); + if ( state == STATE_READ ) { - // Button was held for a second, begin recording - if (button_pressed > 0 && cardRead == 0) { - LEDsoff(); - LED(selected + 1, 0); - LED(LED_D, 0); + if (selected == 0) { + LED_A_ON(); + LED_B_OFF(); + } else { + LED_B_ON(); + LED_A_OFF(); + } + + LED_C_OFF(); + LED_D_OFF(); + WAIT_BUTTON_RELEASED(); + // record DbpString("[=] starting recording"); - // wait for button to be released - while (BUTTON_PRESS()) - WDT_HIT(); + // findone, high, low, no ledcontrol (A) + uint32_t hi = 0, lo = 0; + CmdHIDdemodFSK(1, &hi, &lo, 0); + high[selected] = hi; + low[selected] = lo; + + Dbprintf("[=] recorded bank %x | %x%08x", selected, high[selected], low[selected]); - /* need this delay to prevent catching some weird data */ - SpinDelay(500); - - CmdHIDdemodFSK(1, &high[selected], &low[selected], 0); - Dbprintf("[=] recorded bank %x | %x %08x", selected, high[selected], low[selected]); - - LEDsoff(); - LED(selected + 1, 0); - // Finished recording - // If we were previously playing, set playing off - // so next button push begins playing what we recorded - playing = 0; - cardRead = 1; - - gotCard = true; - } else if (button_pressed > 0 && cardRead == 1) { - LEDsoff(); - LED(selected + 1, 0); - LED(LED_A, 0); - - // record - Dbprintf("[=] cloning %x %x %08x", selected, high[selected], low[selected]); - - // wait for button to be released - while (BUTTON_PRESS()) - WDT_HIT(); - - /* need this delay to prevent catching some weird data */ - SpinDelay(500); - - CopyHIDtoT55x7(0, high[selected], low[selected], 0); - Dbprintf("[=] cloned %x %x %08x", selected, high[selected], low[selected]); - - LEDsoff(); - LED(selected + 1, 0); - // Finished recording - - // If we were previously playing, set playing off - // so next button push begins playing what we recorded - playing = 0; - cardRead = 0; - } - - // Change where to record (or begin playing) - else if (button_pressed && gotCard) { - // Next option if we were previously playing - if (playing) - selected = (selected + 1) % OPTS; - - playing = !playing; - - LEDsoff(); - LED(selected + 1, 0); - - // Begin transmitting - if (playing) { - - LED(LED_B, 0); - DbpString("[=] playing"); - - // wait for button to be released - while (BUTTON_PRESS()) - WDT_HIT(); - - Dbprintf("[=] %x %x %08x", selected, high[selected], low[selected]); - CmdHIDsimTAG(high[selected], low[selected], false); - DbpString("[=] done playing"); - - if (BUTTON_HELD(1000) > 0) - goto out; - - /* We pressed a button so ignore it here with a delay */ - SpinDelay(300); - - // when done, we're done playing, move to next option - selected = (selected + 1) % OPTS; - playing = !playing; - LEDsoff(); - LED(selected + 1, 0); - } else { - while (BUTTON_PRESS()) - WDT_HIT(); + // got nothing. blink and loop. + if ( hi == 0 && lo == 0 ) { + SpinErr( (selected == 0) ? LED_A : LED_B, 100, 12); + Dbprintf("[=] recorded nothing, looping"); + continue; } + + state = STATE_SIM; + continue; + + } else if ( state == STATE_SIM ) { + + LED_C_ON(); // Simulate + LED_D_OFF(); + WAIT_BUTTON_RELEASED(); + + Dbprintf("[=] simulating %x | %x%08x", selected, high[selected], low[selected]); + + // high, low, no led control(A) no time limit + CmdHIDsimTAGEx(high[selected], low[selected], false, -1); + state = STATE_CLONE; + continue; + + } else if ( state == STATE_CLONE ) { + + LED_C_OFF(); + LED_D_ON(); // clone + WAIT_BUTTON_RELEASED(); + + Dbprintf("[=] cloning %x | %x%08x", selected, high[selected], low[selected]); + + // high2, high, low, no longFMT + CopyHIDtoT55x7(0, high[selected], low[selected], 0); + state = STATE_READ; + + selected = (selected + 1) % OPTS; + + LEDsoff(); } } -out: - DbpString("[=] exiting"); + DbpString("[=] exiting samyrun"); LEDsoff(); } From 75f4a6123c623d67ecb9ad979ca29592777d3058 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 12 Sep 2019 17:38:13 +0200 Subject: [PATCH 0669/1854] textual --- armsrc/lfops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/lfops.c b/armsrc/lfops.c index bee1413fc..6addf000e 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -1306,7 +1306,7 @@ void CmdHIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol) hi2 = hi = lo = idx = 0; } FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - DbpString("Stopped"); + DbpString("HID fsk demod stopped"); if (ledcontrol) LED_A_OFF(); } From 74cd1bee3513b8970ad9765cc8b5f9851ec7b406 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 12 Sep 2019 17:39:12 +0200 Subject: [PATCH 0670/1854] minor --- armsrc/mifarecmd.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index e8263d52a..e8cce812f 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -1997,19 +1997,19 @@ void MifareCIdent() { // Generation 1 test ReaderTransmitBitsPar(wupC1, 7, NULL, NULL); - if (!ReaderReceive(rec, recpar) || (rec[0] != 0x0a)) { - goto TEST2; - }; + + if (ReaderReceive(rec, recpar) || (rec[0] != 0x0a)) { - ReaderTransmit(wupC2, sizeof(wupC2), NULL); - if (!ReaderReceive(rec, recpar) || (rec[0] != 0x0a)) { - isGen = GEN_1B; - goto OUT; - }; - isGen = GEN_1A; - goto OUT; + ReaderTransmit(wupC2, sizeof(wupC2), NULL); + + if (!ReaderReceive(rec, recpar) || (rec[0] != 0x0a)) { + isGen = GEN_1B; + goto OUT; + }; + isGen = GEN_1A; + goto OUT; + } -TEST2: // reset card FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); SpinDelay(100); @@ -2017,6 +2017,7 @@ TEST2: int res = iso14443a_select_card(uid, NULL, &cuid, true, 0, true); if (res == 2) { + Dbprintf("cident AA55C396 == %08X", cuid); if (cuid == 0xAA55C396) { isGen = GEN_UNFUSED; goto OUT; From a5bcecd05c582512b3cb5ee2727611ed300065b8 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 12 Sep 2019 17:39:57 +0200 Subject: [PATCH 0671/1854] wait define.. --- include/proxmark3_arm.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/proxmark3_arm.h b/include/proxmark3_arm.h index a2f76e93d..3ea80da9d 100644 --- a/include/proxmark3_arm.h +++ b/include/proxmark3_arm.h @@ -90,6 +90,7 @@ #define LED_D_OFF() LOW(GPIO_LED_D) #define LED_D_INV() INVBIT(GPIO_LED_D) + // SPI #define SCK_LOW LOW(GPIO_SPCK) #define SCK_HIGH HIGH(GPIO_SPCK) @@ -107,7 +108,9 @@ #define RELAY_ON() HIGH(GPIO_RELAY) #define RELAY_OFF() LOW(GPIO_RELAY) -#define BUTTON_PRESS() !((AT91C_BASE_PIOA->PIO_PDSR & GPIO_BUTTON) == GPIO_BUTTON) + +#define BUTTON_PRESS() !((AT91C_BASE_PIOA->PIO_PDSR & GPIO_BUTTON) == GPIO_BUTTON) +#define WAIT_BUTTON_RELEASED() { while ( BUTTON_PRESS() ) { WDT_HIT(); }; } //NVDD goes LOW when USB is attached. #define USB_ATTACHED() !((AT91C_BASE_PIOA->PIO_PDSR & GPIO_NVDD_ON) == GPIO_NVDD_ON) From da68369e0258fd759b58e9eeb220200ca737ffd8 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 12 Sep 2019 19:49:42 +0200 Subject: [PATCH 0672/1854] fix issue #397 --- armsrc/appmain.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index a4b1c45bc..45b53c985 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1212,11 +1212,7 @@ static void PacketReceived(PacketCommandNG *packet) { break; } case CMD_HF_ICLASS_READER: { - struct p { - uint8_t flags; - } PACKED; - struct p *payload = (struct p *)packet->data.asBytes; - ReaderIClass(payload->flags); + ReaderIClass(packet->oldarg[0]); break; } case CMD_HF_ICLASS_REPLAY: { From 46574ae0f5a3f21f4b9e694da60068e4e80d3bcd Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 12 Sep 2019 20:13:01 +0200 Subject: [PATCH 0673/1854] add get_my_user_directory() to centralize HOME processing --- client/fileutils.c | 10 +++++----- client/proxmark3.c | 17 ++++++++++++++--- client/proxmark3.h | 1 + client/scripting.c | 2 +- client/ui.c | 2 +- 5 files changed, 22 insertions(+), 10 deletions(-) diff --git a/client/fileutils.c b/client/fileutils.c index 8e0e3bb72..23553d15c 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -850,10 +850,10 @@ int searchAndList(const char *pm3dir, const char *ext) { filelist(script_directory_path, ext, false, true); } // try pm3 dirs in user .proxmark3 (user mode) - char *userpath = getenv("HOME"); - if (userpath != NULL) { - char script_directory_path[strlen(userpath) + strlen(PM3_USER_DIRECTORY) + strlen(pm3dir) + 1]; - strcpy(script_directory_path, userpath); + const char *user_path = get_my_user_directory(); + if (user_path != NULL) { + char script_directory_path[strlen(user_path) + strlen(PM3_USER_DIRECTORY) + strlen(pm3dir) + 1]; + strcpy(script_directory_path, user_path); strcat(script_directory_path, PM3_USER_DIRECTORY); strcat(script_directory_path, pm3dir); filelist(script_directory_path, ext, false, false); @@ -904,7 +904,7 @@ static int searchFinalFile(char **foundpath, const char *pm3dir, const char *sea } } // try pm3 dirs in user .proxmark3 (user mode) - char *user_path = getenv("HOME"); + const char *user_path = get_my_user_directory(); if (user_path != NULL) { char *path = calloc(strlen(user_path) + strlen(PM3_USER_DIRECTORY) + strlen(pm3dir) + strlen(filename) + 1, sizeof(char)); if (path == NULL) diff --git a/client/proxmark3.c b/client/proxmark3.c index aa37cda9a..b07884b91 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -315,6 +315,16 @@ static void set_my_executable_path(void) { } } +static char *my_user_directory = NULL; + +const char *get_my_user_directory(void) { + return my_user_directory; +} + +static void set_my_user_directory(void) { + my_user_directory = getenv("HOME"); +} + static void show_help(bool showFullHelp, char *exec_name) { PrintAndLogEx(NORMAL, "\nsyntax: %s [-h|-t|-m]", exec_name); @@ -486,6 +496,10 @@ int main(int argc, char *argv[]) { int flash_num_files = 0; char *flash_filenames[FLASH_MAX_FILES]; + // set global variables soon enough to get the log path + set_my_executable_path(); + set_my_user_directory(); + for (int i = 1; i < argc; i++) { if (argv[i][0] != '-') { @@ -685,9 +699,6 @@ int main(int argc, char *argv[]) { if (speed == 0) speed = USART_BAUD_RATE; - // set global variables - set_my_executable_path(); - if (flash_mode) { flash_pm3(port, flash_num_files, flash_filenames, flash_can_write_bl); exit(EXIT_SUCCESS); diff --git a/client/proxmark3.h b/client/proxmark3.h index c370efdff..9313e4c28 100644 --- a/client/proxmark3.h +++ b/client/proxmark3.h @@ -30,6 +30,7 @@ extern "C" { int push_cmdscriptfile(char *path, bool stayafter); const char *get_my_executable_path(void); const char *get_my_executable_directory(void); +const char *get_my_user_directory(void); void main_loop(char *script_cmds_file, char *script_cmd, bool stayInCommandLoop); #ifdef __cplusplus diff --git a/client/scripting.c b/client/scripting.c index 724f72235..6e35f809f 100644 --- a/client/scripting.c +++ b/client/scripting.c @@ -1173,7 +1173,7 @@ int set_pm3_libraries(lua_State *L) { strcat(libraries_path, LUA_LIBRARIES_WILDCARD); setLuaPath(L, libraries_path); } - char *user_path = getenv("HOME"); + const char *user_path = get_my_user_directory(); if (user_path != NULL) { // from the $HOME/.proxmark3/luascripts/ directory char scripts_path[strlen(user_path) + strlen(PM3_USER_DIRECTORY) + strlen(LUA_SCRIPTS_SUBDIR) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; diff --git a/client/ui.c b/client/ui.c index 883ea963a..d12713b9b 100644 --- a/client/ui.c +++ b/client/ui.c @@ -49,7 +49,7 @@ static void fPrintAndLog(FILE *stream, const char *fmt, ...); int searchHomeFilePath(char **foundpath, const char *filename, bool create_home) { if (foundpath == NULL) return PM3_EINVARG; - char *user_path = getenv("HOME"); + const char *user_path = get_my_user_directory(); if (user_path == NULL) { fprintf(stderr, "Could not retrieve $HOME from the environment\n"); return PM3_EFILE; From ed5fed8fac22d97c05fdda8d446c3e0fe0be3e34 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 12 Sep 2019 20:16:52 +0200 Subject: [PATCH 0674/1854] Attempt to fallback to current directory if no HOME in env --- client/proxmark3.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/client/proxmark3.c b/client/proxmark3.c index b07884b91..2ff94b841 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -323,6 +323,9 @@ const char *get_my_user_directory(void) { static void set_my_user_directory(void) { my_user_directory = getenv("HOME"); + // if not found, default to current directory + if (my_user_directory == NULL) + my_user_directory = "."; } static void show_help(bool showFullHelp, char *exec_name) { From 3821a03a4000feeea75fe5ca64f43d9bf27d6162 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 12 Sep 2019 21:20:40 +0200 Subject: [PATCH 0675/1854] chg: 'lf t55xx wipe p' - now takes a password for wipe chg: 'lf t55xx wakeup' - uses NG --- armsrc/appmain.c | 7 ++- armsrc/lfops.c | 1 + client/cmdlft55xx.c | 102 +++++++++++++++++++------------------------- 3 files changed, 50 insertions(+), 60 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 45b53c985..6194cfe39 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -797,7 +797,12 @@ static void PacketReceived(PacketCommandNG *packet) { break; } case CMD_LF_T55XX_WAKEUP: { - T55xxWakeUp(packet->oldarg[0], packet->oldarg[1]); + struct p { + uint32_t password; + uint8_t flags; + } PACKED; + struct p *payload = (struct p *) packet->data.asBytes; + T55xxWakeUp(payload->password, payload->flags); break; } case CMD_LF_T55XX_RESET_READ: { diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 6addf000e..3277100b0 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -2060,6 +2060,7 @@ void T55xxWakeUp(uint32_t pwd, uint8_t flags) { //-- Turn and leave field on to let the begin repeating transmission TurnReadLFOn(20 * 1000); + reply_ng(CMD_LF_T55XX_WAKEUP, PM3_SUCCESS, NULL, 0); } diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 320b193b6..cefb40cc6 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -493,7 +493,7 @@ static int CmdT55xxReadBlock(const char *Cmd) { break; } } - if (errors) return usage_t55xx_read(); + if (errors || cmdp == 0) return usage_t55xx_read(); if (block > 7 && block != REGULAR_READ_MODE_BLOCK) { PrintAndLogEx(NORMAL, "Block must be between 0 and 7"); @@ -611,11 +611,9 @@ static int CmdT55xxDetect(const char *Cmd) { bool useGB = false; bool usepwd = false; bool try_all_dl_modes = false; - bool found = false; uint32_t password = 0; uint8_t cmdp = 0; uint8_t downlink_mode = 0; - uint8_t dl_mode = 0; while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { @@ -627,18 +625,15 @@ static int CmdT55xxDetect(const char *Cmd) { cmdp += 2; break; case '1': - // use Graphbuffer data useGB = true; cmdp++; break; case 'r': downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); - if (downlink_mode == 4) + if (downlink_mode >= 4) { try_all_dl_modes = true; - - if (downlink_mode > 3) - downlink_mode = 0; - + downlink_mode = 4; + } cmdp += 2; break; default: @@ -650,48 +645,32 @@ static int CmdT55xxDetect(const char *Cmd) { if (errors) return usage_t55xx_detect(); // sanity check. - if (SanityOfflineCheck(useGB) != PM3_SUCCESS) return PM3_ENODATA; + if (SanityOfflineCheck(useGB) != PM3_SUCCESS) + return PM3_ESOFT; - if (!useGB) { - for (dl_mode = downlink_mode; dl_mode < 4; dl_mode++) { - found = AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, dl_mode); + if (useGB == false) { + if ( try_all_dl_modes ) { + for (uint8_t mode = 0; mode < 4; mode++) { + + if ( AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, mode) == false ) { + continue; + } - // found = false if password is supplied but wrong d/l mode - // so keep trying other modes (if requested) - /* - if (!found) { - printf ("Aquire not found"); - return PM3_ENODATA; + if (tryDetectModulation()) { + T55xx_Print_DownlinkMode(mode); + return PM3_SUCCESS; + } } - */ - if (tryDetectModulation()) { - T55xx_Print_DownlinkMode(dl_mode); - dl_mode = 4; - found = true; - } else found = false; - - if (!try_all_dl_modes) dl_mode = 4; + return PM3_ESOFT; + } else { + if ( AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, downlink_mode) == false ) + return PM3_ENODATA; } } - - if (useGB) found = tryDetectModulation(); - - if (!found) + if (tryDetectModulation() == false) PrintAndLogEx(WARNING, "Could not detect modulation automatically. Try setting it manually with " _YELLOW_("\'lf t55xx config\'")); - - /* - if (!useGB) { - if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password,downlink_mode)) - return PM3_ENODATA; - } - if (!tryDetectModulation()) - PrintAndLogEx(WARNING, "Could not detect modulation automatically. Try setting it manually with " _YELLOW_("\'lf t55xx config\'")); - else - T55xx_Print_DownlinkMode (downlink_mode); - */ - return PM3_SUCCESS; } // detect configuration? @@ -1142,7 +1121,6 @@ static int CmdT55xxWakeUp(const char *Cmd) { uint8_t cmdp = 0; bool errors = false; uint8_t downlink_mode = 0; - uint8_t flags = 0; while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { @@ -1168,11 +1146,22 @@ static int CmdT55xxWakeUp(const char *Cmd) { if (errors) return usage_t55xx_wakup(); - flags = (downlink_mode & 3) << 3; + struct p { + uint32_t password; + uint8_t flags; + } PACKED payload; + + payload.password = password; + payload.flags = (downlink_mode & 3) << 3; + clearCommandBuffer(); - SendCommandMIX(CMD_LF_T55XX_WAKEUP, password, flags, 0, NULL, 0); + SendCommandNG(CMD_LF_T55XX_WAKEUP, (uint8_t *)&payload, sizeof(payload)); + if (!WaitForResponseTimeout(CMD_LF_T55XX_WAKEUP, NULL, 1000)) { + PrintAndLogEx(WARNING, "command execution time out"); + return PM3_ETIMEOUT; + } + PrintAndLogEx(SUCCESS, "Wake up command sent. Try read now"); - return PM3_SUCCESS; } @@ -1506,7 +1495,7 @@ static void printT5x7KnownBlock0(uint32_t b0) { snprintf(s + strlen(s), sizeof(s) - strlen(s), "FDXB "); break; case T55X7_HID_26_CONFIG_BLOCK: - snprintf(s + strlen(s), sizeof(s) - strlen(s), "HID 26b "); + snprintf(s + strlen(s), sizeof(s) - strlen(s), "HID 26b (ProxCard) "); break; case T55X7_PYRAMID_CONFIG_BLOCK: snprintf(s + strlen(s), sizeof(s) - strlen(s), "Pyramid "); @@ -2073,7 +2062,7 @@ static int CmdResetRead(const char *Cmd) { } static int CmdT55xxWipe(const char *Cmd) { - char writeData[20] = {0}; + char writeData[36] = {0}; char *ptrData = writeData; uint32_t password = 0; bool usepwd = false; @@ -2116,12 +2105,9 @@ static int CmdT55xxWipe(const char *Cmd) { } if (Q5) - snprintf(ptrData + strlen(ptrData), sizeof(writeData) - strlen(ptrData), "d 6001F004"); + snprintf(ptrData + strlen(writeData), sizeof(writeData) - strlen(writeData), "d 6001F004"); else - snprintf(ptrData + strlen(ptrData), sizeof(writeData) - strlen(ptrData), "d 000880E0"); - - PrintAndLogEx(INFO, "%s", ptrData); - return 0; + snprintf(ptrData + strlen(writeData), sizeof(writeData) - strlen(writeData), "d 000880E0"); if (CmdT55xxWriteBlock(ptrData) != PM3_SUCCESS) PrintAndLogEx(WARNING, "Warning: error writing blk 0"); @@ -2167,12 +2153,10 @@ static int CmdT55xxChkPwds(const char *Cmd) { return usage_t55xx_chk(); case 'r': downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); - if (downlink_mode == 4) + if (downlink_mode >= 4) { try_all_dl_modes = true; - - if (downlink_mode > 3) - downlink_mode = 0; - + downlink_mode = 4; + } cmdp += 2; break; case 'm': From 64d2e435928ed0b74a779d07e8fda56f808f85cf Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 13 Sep 2019 00:36:25 +0200 Subject: [PATCH 0676/1854] CmdFSKsimTAG: avoid padding with very short cycles, this confused lf io sim --- armsrc/lfops.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 3277100b0..b535e155a 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -941,7 +941,7 @@ static void fcSTT(int *n) { } // compose fc/X fc/Y waveform (FSKx) -static void fcAll(uint8_t fc, int *n, uint8_t clock, uint16_t *modCnt) { +static uint8_t fcAll(uint8_t fc, int *n, uint8_t clock, uint16_t *modCnt) { uint8_t *dest = BigBuf_get_addr(); uint8_t halfFC = fc >> 1; uint8_t wavesPerClock = clock / fc; @@ -966,12 +966,15 @@ static void fcAll(uint8_t fc, int *n, uint8_t clock, uint16_t *modCnt) { *n += fc; } } +/* This code interfers with FSK2 and I don't see any example of FSK1 simulation in the code... if (!modAdjOk) { //fsk1 memset(dest + (*n), 0, mod - (mod >> 1)); memset(dest + (*n) + (mod - (mod >> 1)), 1, mod >> 1); *n += mod; } +*/ } + return mod; } // prepare a waveform pattern in the buffer based on the ID given then @@ -1059,17 +1062,17 @@ void CmdFSKsimTAG(uint8_t fchigh, uint8_t fclow, uint8_t separator, uint8_t clk, int n = 0, i = 0; uint16_t modCnt = 0; + uint8_t mod = 0; if (separator) { //int fsktype = ( fchigh == 8 && fclow == 5) ? 1 : 2; //fcSTT(&n); } - for (i = 0; i < bitslen; i++) { if (bits[i]) - fcAll(fclow, &n, clk, &modCnt); + mod = fcAll(fclow, &n, clk+mod, &modCnt); else - fcAll(fchigh, &n, clk, &modCnt); + mod = fcAll(fchigh, &n, clk+mod, &modCnt); } WDT_HIT(); From 59ea79b5834d366e92b4e882e1204376d556d1da Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 13 Sep 2019 00:38:04 +0200 Subject: [PATCH 0677/1854] CmdFSKsimTAG: swap fcH/fcL back, fix lf io/awid/pyramid sim --- armsrc/lfops.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/armsrc/lfops.c b/armsrc/lfops.c index b535e155a..e5204a5a5 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -1070,9 +1070,9 @@ void CmdFSKsimTAG(uint8_t fchigh, uint8_t fclow, uint8_t separator, uint8_t clk, } for (i = 0; i < bitslen; i++) { if (bits[i]) - mod = fcAll(fclow, &n, clk+mod, &modCnt); - else mod = fcAll(fchigh, &n, clk+mod, &modCnt); + else + mod = fcAll(fclow, &n, clk+mod, &modCnt); } WDT_HIT(); From 05e9ac97ae21fd438c955c2b3e460ce97fa14e31 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 13 Sep 2019 00:39:08 +0200 Subject: [PATCH 0678/1854] fix lf awid sim doc: must be digits --- client/cmdlfawid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdlfawid.c b/client/cmdlfawid.c index b574af772..2360906a4 100644 --- a/client/cmdlfawid.c +++ b/client/cmdlfawid.c @@ -58,7 +58,7 @@ static int usage_lf_awid_sim(void) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf awid sim 26 224 1337"); - PrintAndLogEx(NORMAL, " lf awid sim 50 2001 deadc0de"); + PrintAndLogEx(NORMAL, " lf awid sim 50 2001 13371337"); return PM3_SUCCESS; } From 5e4243e5a1b83d8e8ea3601b580e62c2f40b7dac Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 13 Sep 2019 00:51:18 +0200 Subject: [PATCH 0679/1854] Disable lf paradox sim, which needs non-existing GetParadoxBits --- client/cmdlfparadox.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdlfparadox.c b/client/cmdlfparadox.c index 8a1a940c5..74e7ce6a1 100644 --- a/client/cmdlfparadox.c +++ b/client/cmdlfparadox.c @@ -161,7 +161,7 @@ static command_t CommandTable[] = { {"demod", CmdParadoxDemod, AlwaysAvailable, "Demodulate a Paradox FSK tag from the GraphBuffer"}, {"read", CmdParadoxRead, IfPm3Lf, "Attempt to read and Extract tag data from the antenna"}, // {"clone", CmdParadoxClone, IfPm3Lf, "clone paradox tag"}, - {"sim", CmdParadoxSim, IfPm3Lf, "simulate paradox tag"}, +// {"sim", CmdParadoxSim, IfPm3Lf, "simulate paradox tag"}, {NULL, NULL, NULL, NULL} }; From f1b36c0b5a2262259abcae4ae3c4222358a86e47 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 13 Sep 2019 07:30:03 +0200 Subject: [PATCH 0680/1854] fix paradox sim compilation... --- client/cmdlfparadox.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/client/cmdlfparadox.c b/client/cmdlfparadox.c index 74e7ce6a1..5ef21992b 100644 --- a/client/cmdlfparadox.c +++ b/client/cmdlfparadox.c @@ -22,7 +22,7 @@ #include "cmdlf.h" #include "lfdemod.h" static int CmdHelp(const char *Cmd); - +/* static int usage_lf_paradox_sim(void) { PrintAndLogEx(NORMAL, "Enables simulation of Paradox card with specified card number."); PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued."); @@ -38,6 +38,7 @@ static int usage_lf_paradox_sim(void) { PrintAndLogEx(NORMAL, " lf paradox sim 123 11223"); return PM3_SUCCESS; } +*/ //by marshmellow //Paradox Prox demod - FSK2a RF/50 with preamble of 00001111 (then manchester encoded) @@ -111,8 +112,12 @@ static int CmdParadoxRead(const char *Cmd) { return CmdParadoxDemod(Cmd); } -static int CmdParadoxSim(const char *Cmd) { +static int CmdParadoxSim(const char *Cmd) { + PrintAndLogEx(INFO," To be implemented, feel free to contribute!"); + return PM3_SUCCESS; +} +/* char cmdp = tolower(param_getchar(Cmd, 0)); if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_paradox_sim(); @@ -155,13 +160,13 @@ static int CmdParadoxSim(const char *Cmd) { return resp.status; return PM3_SUCCESS; } - +*/ static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, {"demod", CmdParadoxDemod, AlwaysAvailable, "Demodulate a Paradox FSK tag from the GraphBuffer"}, {"read", CmdParadoxRead, IfPm3Lf, "Attempt to read and Extract tag data from the antenna"}, // {"clone", CmdParadoxClone, IfPm3Lf, "clone paradox tag"}, -// {"sim", CmdParadoxSim, IfPm3Lf, "simulate paradox tag"}, + {"sim", CmdParadoxSim, IfPm3Lf, "simulate paradox tag"}, {NULL, NULL, NULL, NULL} }; From a4421dfc37efb1022f94d15fd1b33024d67a48d4 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 13 Sep 2019 07:38:07 +0200 Subject: [PATCH 0681/1854] fix wrong spelling --- armsrc/Standalone/hf_colin.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/Standalone/hf_colin.c b/armsrc/Standalone/hf_colin.c index 4997f775e..6a0d9a19d 100644 --- a/armsrc/Standalone/hf_colin.c +++ b/armsrc/Standalone/hf_colin.c @@ -636,7 +636,7 @@ failtag: cjTabulize(); DbprintfEx(FLAG_NEWLINE, "%s[ FAIL ]%s\r\n->did not found all the keys :'(", _XRED_, _XWHITE_); cjSetCursLeft(); - SpinErr(LEB_B, 100, 8); + SpinErr(LED_B, 100, 8); SpinOff(100); return; } From 680d1db9ec1a761bb7c77504bf9ef9cf647c1411 Mon Sep 17 00:00:00 2001 From: Iceman Date: Fri, 13 Sep 2019 09:38:09 +0200 Subject: [PATCH 0682/1854] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6680f5333..22221abe6 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# RRG / Iceman repo - Proxmark3 RDV4.0 and other Proxmark3 platforms. +# RRG / Iceman repo - Proxmark3 This repo is based on iceman fork for Proxmark3. It supports other Proxmark3 platforms as well. From cb23de969461df4c8572ce29c3f1514138f02b2e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 13 Sep 2019 10:04:59 +0200 Subject: [PATCH 0683/1854] chg: feedback after successful operation. led flashes twice. and whitespace removed --- armsrc/Standalone/lf_samyrun.c | 47 +++++++++++++++++----------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/armsrc/Standalone/lf_samyrun.c b/armsrc/Standalone/lf_samyrun.c index 5e1a35c73..f71fef393 100644 --- a/armsrc/Standalone/lf_samyrun.c +++ b/armsrc/Standalone/lf_samyrun.c @@ -41,14 +41,14 @@ void RunMod() { #define STATE_READ 0 #define STATE_SIM 1 -#define STATE_CLONE 2 +#define STATE_CLONE 2 uint8_t state = STATE_READ; - + for (;;) { - + WDT_HIT(); - + // exit from SamyRun, send a usbcommand. if (data_available()) break; @@ -65,70 +65,71 @@ void RunMod() { if ( state == STATE_READ ) { if (selected == 0) { - LED_A_ON(); + LED_A_ON(); LED_B_OFF(); - } else { - LED_B_ON(); + } else { + LED_B_ON(); LED_A_OFF(); } - + LED_C_OFF(); LED_D_OFF(); WAIT_BUTTON_RELEASED(); - + // record DbpString("[=] starting recording"); - // findone, high, low, no ledcontrol (A) + // findone, high, low, no ledcontrol (A) uint32_t hi = 0, lo = 0; CmdHIDdemodFSK(1, &hi, &lo, 0); high[selected] = hi; low[selected] = lo; - + Dbprintf("[=] recorded bank %x | %x%08x", selected, high[selected], low[selected]); // got nothing. blink and loop. if ( hi == 0 && lo == 0 ) { - SpinErr( (selected == 0) ? LED_A : LED_B, 100, 12); + SpinErr( (selected == 0) ? LED_A : LED_B, 100, 12); Dbprintf("[=] recorded nothing, looping"); continue; } - + + SpinErr( (select==0) ? LED_A : LED_B, 250, 2); state = STATE_SIM; continue; } else if ( state == STATE_SIM ) { - - LED_C_ON(); // Simulate + + LED_C_ON(); // Simulate LED_D_OFF(); WAIT_BUTTON_RELEASED(); - + Dbprintf("[=] simulating %x | %x%08x", selected, high[selected], low[selected]); // high, low, no led control(A) no time limit - CmdHIDsimTAGEx(high[selected], low[selected], false, -1); + CmdHIDsimTAGEx(high[selected], low[selected], false, -1); + SpinErr( LED_C, 250, 2); state = STATE_CLONE; continue; - + } else if ( state == STATE_CLONE ) { LED_C_OFF(); - LED_D_ON(); // clone + LED_D_ON(); // clone WAIT_BUTTON_RELEASED(); - + Dbprintf("[=] cloning %x | %x%08x", selected, high[selected], low[selected]); // high2, high, low, no longFMT CopyHIDtoT55x7(0, high[selected], low[selected], 0); state = STATE_READ; - + SpinErr( LED_D, 250, 2); selected = (selected + 1) % OPTS; - LEDsoff(); } } - DbpString("[=] exiting samyrun"); + DbpString("[=] exiting samyrun"); LEDsoff(); } From 3a776ecf3ab71567de2a1e25c3b593f1b3fea44a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 13 Sep 2019 10:17:58 +0200 Subject: [PATCH 0684/1854] chg samyrun - dual leds flash after state changes --- armsrc/Standalone/lf_samyrun.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/armsrc/Standalone/lf_samyrun.c b/armsrc/Standalone/lf_samyrun.c index f71fef393..df9812869 100644 --- a/armsrc/Standalone/lf_samyrun.c +++ b/armsrc/Standalone/lf_samyrun.c @@ -78,7 +78,7 @@ void RunMod() { WAIT_BUTTON_RELEASED(); // record - DbpString("[=] starting recording"); + DbpString("[=] start recording"); // findone, high, low, no ledcontrol (A) uint32_t hi = 0, lo = 0; @@ -86,16 +86,16 @@ void RunMod() { high[selected] = hi; low[selected] = lo; - Dbprintf("[=] recorded bank %x | %x%08x", selected, high[selected], low[selected]); + Dbprintf("[=] recorded %x | %x%08x", selected, high[selected], low[selected]); // got nothing. blink and loop. if ( hi == 0 && lo == 0 ) { SpinErr( (selected == 0) ? LED_A : LED_B, 100, 12); - Dbprintf("[=] recorded nothing, looping"); + DbpString("[=] only got zeros, retry recording after click"); continue; } - SpinErr( (select==0) ? LED_A : LED_B, 250, 2); + SpinErr( (selected == 0) ? LED_A : LED_B, 250, 2); state = STATE_SIM; continue; @@ -109,7 +109,11 @@ void RunMod() { // high, low, no led control(A) no time limit CmdHIDsimTAGEx(high[selected], low[selected], false, -1); - SpinErr( LED_C, 250, 2); + + DbpString("[=] simulating done"); + + uint8_t leds = ((selected == 0) ? LED_A : LED_B) | LED_C; + SpinErr( leds , 250, 2); state = STATE_CLONE; continue; @@ -119,17 +123,21 @@ void RunMod() { LED_D_ON(); // clone WAIT_BUTTON_RELEASED(); - Dbprintf("[=] cloning %x | %x%08x", selected, high[selected], low[selected]); + Dbprintf("[=] cloning %x | %x%08x", selected, high[selected], low[selected]); // high2, high, low, no longFMT CopyHIDtoT55x7(0, high[selected], low[selected], 0); + + DbpString("[=] cloned done"); + state = STATE_READ; - SpinErr( LED_D, 250, 2); + uint8_t leds = ((selected == 0) ? LED_A : LED_B) | LED_D; + SpinErr(leds, 250, 2); selected = (selected + 1) % OPTS; LEDsoff(); } } - DbpString("[=] exiting samyrun"); + DbpString("[=] You can take shell back :) ..."); LEDsoff(); } From 3dc4774f20fc2978613a4931b8cf42703ba8f6fd Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 13 Sep 2019 10:35:17 +0200 Subject: [PATCH 0685/1854] simplify fcAll --- armsrc/lfops.c | 40 ++++++++++++---------------------------- 1 file changed, 12 insertions(+), 28 deletions(-) diff --git a/armsrc/lfops.c b/armsrc/lfops.c index e5204a5a5..341b98483 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -941,12 +941,10 @@ static void fcSTT(int *n) { } // compose fc/X fc/Y waveform (FSKx) -static uint8_t fcAll(uint8_t fc, int *n, uint8_t clock, uint16_t *modCnt) { +static void fcAll(uint8_t fc, int *n, uint8_t clock, int16_t *remainder) { uint8_t *dest = BigBuf_get_addr(); uint8_t halfFC = fc >> 1; - uint8_t wavesPerClock = clock / fc; - uint8_t mod = clock % fc; //modifier - + uint8_t wavesPerClock = (clock + *remainder) / fc; // loop through clock - step field clock for (uint8_t idx = 0; idx < wavesPerClock; idx++) { // put 1/2 FC length 1's and 1/2 0's per field clock wave (to create the wave) @@ -954,27 +952,14 @@ static uint8_t fcAll(uint8_t fc, int *n, uint8_t clock, uint16_t *modCnt) { memset(dest + (*n) + (fc - halfFC), 1, halfFC); *n += fc; } - if (mod > 0) { - uint8_t modAdj = fc / mod; //how often to apply modifier - bool modAdjOk = !(fc % mod); //if (fc % mod==0) modAdjOk = true; - (*modCnt)++; - - if (modAdjOk) { //fsk2 - if ((*modCnt % modAdj) == 0) { //if 4th 8 length wave in a rf/50 add extra 8 length wave - memset(dest + (*n), 0, fc - halfFC); - memset(dest + (*n) + (fc - halfFC), 1, halfFC); - *n += fc; - } - } -/* This code interfers with FSK2 and I don't see any example of FSK1 simulation in the code... - if (!modAdjOk) { //fsk1 - memset(dest + (*n), 0, mod - (mod >> 1)); - memset(dest + (*n) + (mod - (mod >> 1)), 1, mod >> 1); - *n += mod; - } -*/ + *remainder = (clock + *remainder) % fc; + // if we've room for more than a half wave, add a full wave and use negative remainder + if (*remainder > halfFC) { + memset(dest + (*n), 0, fc - halfFC); //in case of odd number use extra here + memset(dest + (*n) + (fc - halfFC), 1, halfFC); + *n += fc; + *remainder -= fc; } - return mod; } // prepare a waveform pattern in the buffer based on the ID given then @@ -1061,8 +1046,7 @@ void CmdFSKsimTAG(uint8_t fchigh, uint8_t fclow, uint8_t separator, uint8_t clk, set_tracing(false); int n = 0, i = 0; - uint16_t modCnt = 0; - uint8_t mod = 0; + int16_t remainder = 0; if (separator) { //int fsktype = ( fchigh == 8 && fclow == 5) ? 1 : 2; @@ -1070,9 +1054,9 @@ void CmdFSKsimTAG(uint8_t fchigh, uint8_t fclow, uint8_t separator, uint8_t clk, } for (i = 0; i < bitslen; i++) { if (bits[i]) - mod = fcAll(fchigh, &n, clk+mod, &modCnt); + fcAll(fchigh, &n, clk, &remainder); else - mod = fcAll(fclow, &n, clk+mod, &modCnt); + fcAll(fclow, &n, clk, &remainder); } WDT_HIT(); From 270d0821b5563c9a7635df25d2e887639644ea3b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 13 Sep 2019 12:11:56 +0200 Subject: [PATCH 0686/1854] chg: 'data print i' - new param I, inverts the demod buffer --- client/cmddata.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/client/cmddata.c b/client/cmddata.c index 9465c63ac..18e91c699 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -36,6 +36,7 @@ static int usage_data_printdemodbuf(void) { PrintAndLogEx(NORMAL, "Usage: data printdemodbuffer x o l "); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h This help"); + PrintAndLogEx(NORMAL, " i invert Demodbuffer before printing"); PrintAndLogEx(NORMAL, " x output in hex (omit for binary output)"); PrintAndLogEx(NORMAL, " o enter offset in # of bits"); PrintAndLogEx(NORMAL, " l enter length to print in # of bits or hex characters respectively"); @@ -251,7 +252,6 @@ static int usage_data_fsktonrz() { return PM3_SUCCESS; } - //set the demod buffer with given array of binary (one bit per byte) //by marshmellow void setDemodBuff(uint8_t *buff, size_t size, size_t start_idx) { @@ -404,6 +404,7 @@ int CmdPrintDemodBuff(const char *Cmd) { bool hexMode = false; bool errors = false; bool lstrip = false; + bool invert = false; uint32_t offset = 0; uint32_t length = 512; char cmdp = 0; @@ -427,7 +428,11 @@ int CmdPrintDemodBuff(const char *Cmd) { break; case 's': lstrip = true; - cmdp ++; + cmdp++; + break; + case 'i': + invert = true; + cmdp++; break; default: PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); @@ -453,6 +458,18 @@ int CmdPrintDemodBuff(const char *Cmd) { } length = (length > (DemodBufferLen - offset)) ? DemodBufferLen - offset : length; + if (invert) { + char *buf = (char *)(DemodBuffer + offset); + for (uint32_t i = 0; i < length; i++) { + if ( buf[i] == 1 ) + buf[i] = 0; + else { + if ( buf[i] == 0 ) + buf[i] = 1; + } + } + } + if (hexMode) { char *buf = (char *)(DemodBuffer + offset); char hex[512] = {0x00}; @@ -2160,7 +2177,6 @@ static command_t CommandTable[] = { {"dec", CmdDec, AlwaysAvailable, "Decimate samples"}, {"detectclock", CmdDetectClockRate, AlwaysAvailable, "[] Detect ASK, FSK, NRZ, PSK clock rate of wave in GraphBuffer"}, {"fsktonrz", CmdFSKToNRZ, AlwaysAvailable, "Convert fsk2 to nrz wave for alternate fsk demodulating (for weak fsk)"}, - {"getbitstream", CmdGetBitStream, AlwaysAvailable, "Convert GraphBuffer's >=1 values to 1 and <1 to 0"}, {"grid", CmdGrid, AlwaysAvailable, " -- overlay grid on graph window, use zero value to turn off either"}, {"hexsamples", CmdHexsamples, IfPm3Present, " [] -- Dump big buffer as hex bytes"}, From 871445212ec86dd83090897ca6f876c3bd1b0568 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 13 Sep 2019 14:10:08 +0200 Subject: [PATCH 0687/1854] chg 'lf proxebrute standalone' - simplified it. No need for clone, or multiple slots, LED A = read / record, flashing LED A 12 times, failed reader and next click try again, LED C == proxbrute, all leds flash when exiting standalone mode --- armsrc/Standalone/lf_proxbrute.c | 197 +++++++++++-------------------- 1 file changed, 68 insertions(+), 129 deletions(-) diff --git a/armsrc/Standalone/lf_proxbrute.c b/armsrc/Standalone/lf_proxbrute.c index 8044cbde9..5d435c3ee 100644 --- a/armsrc/Standalone/lf_proxbrute.c +++ b/armsrc/Standalone/lf_proxbrute.c @@ -18,8 +18,6 @@ #include "ticks.h" #include "lfops.h" -#define OPTS 2 - void ModInfo(void) { DbpString(" LF HID ProxII bruteforce - aka Proxbrute (Brad Antoniewicz)"); } @@ -30,151 +28,92 @@ void RunMod() { Dbprintf(">> LF HID proxII bruteforce a.k.a ProxBrute Started (Brad Antoniewicz) <<"); FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - uint32_t high[OPTS], low[OPTS]; - int selected = 0; - int playing = 0; - int cardRead = 0; + uint32_t high, low; - // Turn on selected LED - LED(selected + 1, 0); +#define STATE_READ 0 +#define STATE_BRUTE 1 + + uint8_t state = STATE_READ; for (;;) { + WDT_HIT(); // exit from SamyRun, send a usbcommand. if (data_available()) break; - // Was our button held down or pressed? - int button_pressed = BUTTON_HELD(1000); - SpinDelay(300); + // Was our button held down or pressed? + int button_pressed = BUTTON_HELD(280); + if ( button_pressed != BUTTON_HOLD ) + continue; // Button was held for a second, begin recording - if (button_pressed > 0 && cardRead == 0) { - LEDsoff(); - LED(selected + 1, 0); - LED(LED_D, 0); + if ( state == STATE_READ ) { + + LEDsoff(); + LED_A_ON(); + WAIT_BUTTON_RELEASED(); - // record DbpString("[=] starting recording"); - // wait for button to be released - while (BUTTON_PRESS()) - WDT_HIT(); - /* need this delay to prevent catching some weird data */ - SpinDelay(500); + // findone, high, low, no ledcontrol (A) + CmdHIDdemodFSK(1, &high, &low, 0); - CmdHIDdemodFSK(1, &high[selected], &low[selected], 0); - Dbprintf("[=] recorded %x %x %08x", selected, high[selected], low[selected]); + Dbprintf("[=] recorded | %x%08x", high, low); - LEDsoff(); - LED(selected + 1, 0); - // Finished recording - // If we were previously playing, set playing off - // so next button push begins playing what we recorded - playing = 0; - cardRead = 1; - } else if (button_pressed > 0 && cardRead == 1) { - LEDsoff(); - LED(selected + 1, 0); - LED(LED_A, 0); - - // record - Dbprintf("[=] cloning %x %x %08x", selected, high[selected], low[selected]); - - // wait for button to be released - while (BUTTON_PRESS()) - WDT_HIT(); - - /* need this delay to prevent catching some weird data */ - SpinDelay(500); - - CopyHIDtoT55x7(0, high[selected], low[selected], 0); - Dbprintf("[=] cloned %x %x %08x", selected, high[selected], low[selected]); - - LEDsoff(); - LED(selected + 1, 0); - // Finished recording - - // If we were previously playing, set playing off - // so next button push begins playing what we recorded - playing = 0; - cardRead = 0; - } - - // Change where to record (or begin playing) - else if (button_pressed) { - // Next option if we were previously playing - if (playing) - selected = (selected + 1) % OPTS; - playing = !playing; - - LEDsoff(); - LED(selected + 1, 0); - - // Begin transmitting - if (playing) { - LED(LED_B, 0); - DbpString("[=] playing"); - // wait for button to be released - while (BUTTON_PRESS()) - WDT_HIT(); - - /* START PROXBRUTE */ - - /* - ProxBrute - brad a. - foundstone - - Following code is a trivial brute forcer once you read a valid tag - the idea is you get a valid tag, then just try and brute force to - another priv level. The problem is that it has no idea if the code - worked or not, so its a crap shoot. One option is to time how long - it takes to get a valid ID then start from scratch every time. - */ - if (selected == 1) { - DbpString("[=] entering ProxBrute Mode"); - Dbprintf("[=] current Tag: Selected = %x Facility = %08x ID = %08x", selected, high[selected], low[selected]); - LED(LED_A, 0); - LED(LED_C, 0); - for (uint16_t i = low[selected] - 1; i > 0; i--) { - if (BUTTON_PRESS()) { - DbpString("[-] told to stop"); - break; - } - - Dbprintf("[=] trying Facility = %08x ID %08x", high[selected], i); - CmdHIDsimTAGEx(high[selected], i, 0, 20000); - SpinDelay(500); - } - - } else { - DbpString("[=] RED is lit, not entering ProxBrute Mode"); - Dbprintf("[=] %x %x %x", selected, high[selected], low[selected]); - CmdHIDsimTAGEx(high[selected], low[selected], 0, 20000); - DbpString("[=] done playing"); - } - - /* END PROXBRUTE */ - - - if (BUTTON_HELD(1000) > 0) - goto out; - - /* We pressed a button so ignore it here with a delay */ - SpinDelay(300); - - // when done, we're done playing, move to next option - selected = (selected + 1) % OPTS; - playing = !playing; - LEDsoff(); - LED(selected + 1, 0); - } else { - while (BUTTON_PRESS()) - WDT_HIT(); + // got nothing. blink and loop. + if ( high == 0 && low == 0 ) { + SpinErr( LED_A, 100, 12); + DbpString("[=] only got zeros, retry recording after click"); + continue; } + + SpinErr(LED_A, 250, 2); + state = STATE_BRUTE; + continue; + + } else if ( state == STATE_BRUTE ) { + + LED_C_ON(); // Simulate + WAIT_BUTTON_RELEASED(); + + + /* + ProxBrute - brad a. - foundstone + + Following code is a trivial brute forcer once you read a valid tag + the idea is you get a valid tag, then just try and brute force to + another priv level. The problem is that it has no idea if the code + worked or not, so its a crap shoot. One option is to time how long + it takes to get a valid ID then start from scratch every time. + */ + DbpString("[=] entering ProxBrute mode"); + Dbprintf("[=] simulating | %08x%08x", high, low); + + for (uint16_t i = low - 1; i > 0; i--) { + + if (data_available()) break; + + // Was our button held down or pressed? + int button_pressed = BUTTON_HELD(280); + if ( button_pressed != BUTTON_HOLD ) break; + + Dbprintf("[=] trying Facility = %08x ID %08x", high, i); + + // high, i, ledcontrol, timelimit 20000 + CmdHIDsimTAGEx(high, i, false, 20000); + + SpinDelay(100); + } + + state = STATE_READ; + SpinErr( (LED_A | LED_C ), 250, 2); + LEDsoff(); } } -out: - DbpString("[=] exiting"); + + SpinErr( (LED_A | LED_B | LED_C | LED_D), 250, 5); + DbpString("[=] You can take the shell back :) ..."); LEDsoff(); } From 1c4c21513b061feef1d8b676b93412bee20aea9a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 13 Sep 2019 14:12:12 +0200 Subject: [PATCH 0688/1854] chg samyrun, all leds flash 5times when exiting standalone mode --- armsrc/Standalone/lf_samyrun.c | 1 + 1 file changed, 1 insertion(+) diff --git a/armsrc/Standalone/lf_samyrun.c b/armsrc/Standalone/lf_samyrun.c index df9812869..58c5dfd5e 100644 --- a/armsrc/Standalone/lf_samyrun.c +++ b/armsrc/Standalone/lf_samyrun.c @@ -138,6 +138,7 @@ void RunMod() { } } + SpinErr( (LED_A | LED_B | LED_C | LED_D), 250, 5); DbpString("[=] You can take shell back :) ..."); LEDsoff(); } From 8d6bde0d63300d06945298f3d21e3d224db63c73 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 13 Sep 2019 15:13:18 +0200 Subject: [PATCH 0689/1854] chg: 'lf em 4x50_demod' - seems the read 4x50 didnt read, it demodulated only.. --- client/cmdlfem4x.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c index c04e64c00..b7948b14c 100644 --- a/client/cmdlfem4x.c +++ b/client/cmdlfem4x.c @@ -102,6 +102,14 @@ static int usage_lf_em410x_brute(void) { } //////////////// 4050 / 4450 commands +static int usage_lf_em4x50_demod(void) { + PrintAndLogEx(NORMAL, "Usage: lf em 4x50_demod [h]"); + PrintAndLogEx(NORMAL, "Options:"); + PrintAndLogEx(NORMAL, " h - this help"); + PrintAndLogEx(NORMAL, "Examples:"); + PrintAndLogEx(NORMAL, " lf em 4x50_demod"); + return PM3_SUCCESS; +} static int usage_lf_em4x50_dump(void) { PrintAndLogEx(NORMAL, "Dump EM4x50/EM4x69. Tag must be on antenna. "); PrintAndLogEx(NORMAL, ""); @@ -979,17 +987,25 @@ int EM4x50Read(const char *Cmd, bool verbose) { return AllPTest ? PM3_SUCCESS : PM3_ESOFT; } +static int CmdEM4x50Demod(const char *Cmd) { + uint8_t ctmp = tolower(param_getchar(Cmd, 0)); + if (ctmp == 'h') return usage_lf_em4x50_demod(); + return EM4x50Read(Cmd, true); +} + static int CmdEM4x50Read(const char *Cmd) { uint8_t ctmp = tolower(param_getchar(Cmd, 0)); if (ctmp == 'h') return usage_lf_em4x50_read(); return EM4x50Read(Cmd, true); } + static int CmdEM4x50Write(const char *Cmd) { uint8_t ctmp = tolower(param_getchar(Cmd, 0)); if (ctmp == 'h') return usage_lf_em4x50_write(); PrintAndLogEx(NORMAL, "no implemented yet"); return PM3_SUCCESS; } + static int CmdEM4x50Dump(const char *Cmd) { uint8_t ctmp = tolower(param_getchar(Cmd, 0)); if (ctmp == 'h') return usage_lf_em4x50_dump(); @@ -1531,6 +1547,7 @@ static command_t CommandTable[] = { {"4x05_info", CmdEM4x05Info, IfPm3Lf, "tag information EM4x05/EM4x69"}, {"4x05_read", CmdEM4x05Read, IfPm3Lf, "read word data from EM4x05/EM4x69"}, {"4x05_write", CmdEM4x05Write, IfPm3Lf, "write word data to EM4x05/EM4x69"}, + {"4x50_demod", CmdEM4x50Demod, AlwaysAvailable, "demodulate a EM4x50 tag from the GraphBuffer"}, {"4x50_dump", CmdEM4x50Dump, IfPm3Lf, "dump EM4x50 tag"}, {"4x50_read", CmdEM4x50Read, IfPm3Lf, "read word data from EM4x50"}, {"4x50_write", CmdEM4x50Write, IfPm3Lf, "write word data to EM4x50"}, From ffa3e2a0f8dfea6a3a6a5606ef50d53fae3ab2e3 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 13 Sep 2019 16:25:33 +0200 Subject: [PATCH 0690/1854] style --- armsrc/Standalone/lf_samyrun.c | 28 ++++++++++---------- armsrc/iclass.c | 44 +++++++++++++++---------------- armsrc/mifarecmd.c | 22 ++++++++-------- armsrc/pcf7931.c | 48 +++++++++++++++++----------------- armsrc/ticks.c | 2 +- 5 files changed, 72 insertions(+), 72 deletions(-) diff --git a/armsrc/Standalone/lf_samyrun.c b/armsrc/Standalone/lf_samyrun.c index 58c5dfd5e..d56f48e24 100644 --- a/armsrc/Standalone/lf_samyrun.c +++ b/armsrc/Standalone/lf_samyrun.c @@ -54,15 +54,15 @@ void RunMod() { // Was our button held down or pressed? int button_pressed = BUTTON_HELD(280); - if ( button_pressed != BUTTON_HOLD ) + if (button_pressed != BUTTON_HOLD) continue; -/* -#define BUTTON_NO_CLICK 0 -#define BUTTON_SINGLE_CLICK -1 -#define BUTTON_DOUBLE_CLICK -2 -*/ + /* + #define BUTTON_NO_CLICK 0 + #define BUTTON_SINGLE_CLICK -1 + #define BUTTON_DOUBLE_CLICK -2 + */ - if ( state == STATE_READ ) { + if (state == STATE_READ) { if (selected == 0) { LED_A_ON(); @@ -89,17 +89,17 @@ void RunMod() { Dbprintf("[=] recorded %x | %x%08x", selected, high[selected], low[selected]); // got nothing. blink and loop. - if ( hi == 0 && lo == 0 ) { - SpinErr( (selected == 0) ? LED_A : LED_B, 100, 12); + if (hi == 0 && lo == 0) { + SpinErr((selected == 0) ? LED_A : LED_B, 100, 12); DbpString("[=] only got zeros, retry recording after click"); continue; } - SpinErr( (selected == 0) ? LED_A : LED_B, 250, 2); + SpinErr((selected == 0) ? LED_A : LED_B, 250, 2); state = STATE_SIM; continue; - } else if ( state == STATE_SIM ) { + } else if (state == STATE_SIM) { LED_C_ON(); // Simulate LED_D_OFF(); @@ -113,11 +113,11 @@ void RunMod() { DbpString("[=] simulating done"); uint8_t leds = ((selected == 0) ? LED_A : LED_B) | LED_C; - SpinErr( leds , 250, 2); + SpinErr(leds, 250, 2); state = STATE_CLONE; continue; - } else if ( state == STATE_CLONE ) { + } else if (state == STATE_CLONE) { LED_C_OFF(); LED_D_ON(); // clone @@ -138,7 +138,7 @@ void RunMod() { } } - SpinErr( (LED_A | LED_B | LED_C | LED_D), 250, 5); + SpinErr((LED_A | LED_B | LED_C | LED_D), 250, 5); DbpString("[=] You can take shell back :) ..."); LEDsoff(); } diff --git a/armsrc/iclass.c b/armsrc/iclass.c index 5bbcc1b4b..fd5d663fd 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -895,7 +895,7 @@ void RAMFUNC SniffIClass(void) { // time ZERO, the point from which it all is calculated. time_0 = GetCountSspClk(); - + // loop and listen // every sample (1byte in data), // contains HIGH nibble = reader data @@ -962,7 +962,7 @@ void RAMFUNC SniffIClass(void) { */ - uint8_t tag_byte = ((previous_data & 0xF) << 4 ) | (*data & 0xF); + uint8_t tag_byte = ((previous_data & 0xF) << 4) | (*data & 0xF); if (ManchesterDecoding_iclass(tag_byte)) { time_stop = GetCountSspClk() - time_0; LogTrace(Demod.output, Demod.len, time_start, time_stop, NULL, false); @@ -976,12 +976,12 @@ void RAMFUNC SniffIClass(void) { } } // end main loop -/* - if (DBGLEVEL >= 1) { - DbpString("[+] Sniff statistics:"); - Dbhexdump(ICLASS_DMA_BUFFER_SIZE, data, false); - } -*/ + /* + if (DBGLEVEL >= 1) { + DbpString("[+] Sniff statistics:"); + Dbhexdump(ICLASS_DMA_BUFFER_SIZE, data, false); + } + */ switch_off(); } @@ -1522,7 +1522,7 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) { trace_data = csn_data; trace_data_size = sizeof(csn_data); goto send; - } else if (cmd == ICLASS_CMD_READCHECK ) { // 0x88 + } else if (cmd == ICLASS_CMD_READCHECK) { // 0x88 // Read e-purse KD (88 02) KC (18 02) modulated_response = resp_cc; modulated_response_size = resp_cc_len; //order = 4; @@ -1898,7 +1898,7 @@ bool sendCmdGetResponseWithRetries(uint8_t *command, size_t cmdsize, uint8_t *re // update/write command takes 4ms to 15ms before responding int old_wait = g_wait; - if ( (command[0] & 0xF) == ICLASS_CMD_UPDATE) + if ((command[0] & 0xF) == ICLASS_CMD_UPDATE) g_wait = 3900; uint8_t got_n = ReaderReceiveIClass(resp); @@ -1934,8 +1934,8 @@ uint8_t handshakeIclassTag_ext(uint8_t *card_data, bool use_credit_key) { uint8_t readcheck_cc[] = { 0x80 | ICLASS_CMD_READCHECK, 0x02 }; // Bit 4: K.If this bit equals to one, the READCHECK will use the Credit Key (Kc); if equals to zero, Debit Key (Kd) willbe used - // bit 7: parity. - + // bit 7: parity. + if (use_credit_key) readcheck_cc[0] = 0x10 | ICLASS_CMD_READCHECK; @@ -1945,14 +1945,14 @@ uint8_t handshakeIclassTag_ext(uint8_t *card_data, bool use_credit_key) { ReaderTransmitIClass_ext(act_all, 1, 330 + 180); // Card present? - if (ReaderReceiveIClass(resp) == 0) + if (ReaderReceiveIClass(resp) == 0) return 0; //Send Identify ReaderTransmitIClass(identify, 1); //We expect a 10-byte response here, 8 byte anticollision-CSN and 2 byte CRC - if ( ReaderReceiveIClass(resp) != 10 ) + if (ReaderReceiveIClass(resp) != 10) return 0; //Copy the Anti-collision CSN to our select-packet @@ -1962,28 +1962,28 @@ uint8_t handshakeIclassTag_ext(uint8_t *card_data, bool use_credit_key) { ReaderTransmitIClass(select, sizeof(select)); //We expect a 10-byte response here, 8 byte CSN and 2 byte CRC - if ( ReaderReceiveIClass(resp) != 10) + if (ReaderReceiveIClass(resp) != 10) return 0; - // Card selected, now read e-purse (cc) (block2) (only 8 bytes no CRC) + // Card selected, now read e-purse (cc) (block2) (only 8 bytes no CRC) // ReaderTransmitIClass(readcheck_cc, sizeof(readcheck_cc)); // if (ReaderReceiveIClass(resp) == 8) { // //Save CC (e-purse) in response data // memcpy(card_data+8, resp, 8); // read_status++; // } - + //Success - level 1, we got CSN //Save CSN in response data memcpy(card_data, resp, 8); - + bool isBlk_2 = sendCmdGetResponseWithRetries(readcheck_cc, sizeof(readcheck_cc), resp, 8, 3); //Flag that we got to at least stage 1, read CSN - if ( isBlk_2 == false) { + if (isBlk_2 == false) { return 1; } - + //Save CC (e-purse) in response data memcpy(card_data + 8, resp, 8); @@ -2283,7 +2283,7 @@ void iClass_Authentication(uint8_t *mac) { // 6 retries uint8_t isOK = sendCmdGetResponseWithRetries(check, sizeof(check), resp, 4, 6); - reply_ng(CMD_HF_ICLASS_AUTH, PM3_SUCCESS, (uint8_t*)&isOK ,sizeof(uint8_t)); + reply_ng(CMD_HF_ICLASS_AUTH, PM3_SUCCESS, (uint8_t *)&isOK, sizeof(uint8_t)); } typedef struct iclass_premac { @@ -2460,7 +2460,7 @@ bool iClass_WriteBlock_ext(uint8_t blockno, uint8_t *data) { void iClass_WriteBlock(uint8_t blockno, uint8_t *data) { uint8_t isOK = iClass_WriteBlock_ext(blockno, data); switch_off(); - reply_ng(CMD_HF_ICLASS_WRITEBL, PM3_SUCCESS, (uint8_t*)&isOK, sizeof(uint8_t)); + reply_ng(CMD_HF_ICLASS_WRITEBL, PM3_SUCCESS, (uint8_t *)&isOK, sizeof(uint8_t)); } // turn off afterwards diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index e8cce812f..1ca809a8a 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -1997,18 +1997,18 @@ void MifareCIdent() { // Generation 1 test ReaderTransmitBitsPar(wupC1, 7, NULL, NULL); - + if (ReaderReceive(rec, recpar) || (rec[0] != 0x0a)) { - ReaderTransmit(wupC2, sizeof(wupC2), NULL); - - if (!ReaderReceive(rec, recpar) || (rec[0] != 0x0a)) { - isGen = GEN_1B; - goto OUT; - }; - isGen = GEN_1A; - goto OUT; - } + ReaderTransmit(wupC2, sizeof(wupC2), NULL); + + if (!ReaderReceive(rec, recpar) || (rec[0] != 0x0a)) { + isGen = GEN_1B; + goto OUT; + }; + isGen = GEN_1A; + goto OUT; + } // reset card FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); @@ -2017,7 +2017,7 @@ void MifareCIdent() { int res = iso14443a_select_card(uid, NULL, &cuid, true, 0, true); if (res == 2) { - Dbprintf("cident AA55C396 == %08X", cuid); + Dbprintf("cident AA55C396 == %08X", cuid); if (cuid == 0xAA55C396) { isGen = GEN_UNFUSED; goto OUT; diff --git a/armsrc/pcf7931.c b/armsrc/pcf7931.c index 1690c6ad3..2bc101a48 100644 --- a/armsrc/pcf7931.c +++ b/armsrc/pcf7931.c @@ -94,10 +94,10 @@ size_t DemodPCF7931(uint8_t **outBlocks) { } else { // Error if (++warnings > 10) { - - if ( DBGLEVEL >= DBG_EXTENDED ) + + if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("Error: too many detection errors, aborting."); - + return 0; } } @@ -138,10 +138,10 @@ bool IsBlock0PCF7931(uint8_t *block) { // assuming all RFU bits are set to 0 // if PAC is enabled password is set to 0 if (block[7] == 0x01) { - if (!memcmp(block, "\x00\x00\x00\x00\x00\x00\x00", 7) - && !memcmp(block + 9, "\x00\x00\x00\x00\x00\x00\x00", 7)) { + if (!memcmp(block, "\x00\x00\x00\x00\x00\x00\x00", 7) + && !memcmp(block + 9, "\x00\x00\x00\x00\x00\x00\x00", 7)) { return true; - } + } } else if (block[7] == 0x00) { if (!memcmp(block + 9, "\x00\x00\x00\x00\x00\x00\x00", 7)) { return true; @@ -158,14 +158,14 @@ bool IsBlock1PCF7931(uint8_t *block) { uint8_t rlb = block[15]; if (block[10] == 0 - && block[11] == 0 - && block[12] == 0 - && block[13] == 0) { + && block[11] == 0 + && block[12] == 0 + && block[13] == 0) { // block 1 is sent only if (RLB >= 1 && RFB <= 1) or RB1 enabled if (rfb <= rlb - && rfb <= 9 - && rlb <= 9 - && ((rfb <= 1 && rlb >= 1) || rb1)) { + && rfb <= 9 + && rlb <= 9 + && ((rfb <= 1 && rlb >= 1) || rb1)) { return true; } } @@ -203,17 +203,17 @@ void ReadPCF7931() { // exit if no block is received if (errors >= 10 && found_blocks == 0 && single_blocks_cnt == 0) { - if ( DBGLEVEL >= DBG_INFO ) + if (DBGLEVEL >= DBG_INFO) Dbprintf("[!!] Error, no tag or bad tag"); - + return; } // exit if too many errors during reading if (tries > 50 && (2 * errors > tries)) { - - if ( DBGLEVEL >= DBG_INFO ) + + if (DBGLEVEL >= DBG_INFO) Dbprintf("[!!] Error reading the tag, only partial content"); - + goto end; } @@ -242,9 +242,9 @@ void ReadPCF7931() { continue; } - if ( DBGLEVEL >= DBG_EXTENDED ) + if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("(dbg) got %d blocks (%d/%d found) (%d tries, %d errors)", n, found_blocks, (max_blocks == 0 ? found_blocks : max_blocks), tries, errors); - + for (i = 0; i < n; ++i) { print_result("got consecutive blocks", tmp_blocks[i], 16); } @@ -306,9 +306,9 @@ void ReadPCF7931() { } ++tries; if (BUTTON_PRESS()) { - if ( DBGLEVEL >= DBG_EXTENDED) + if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("Button pressed, stopping."); - + goto end; } } while (found_blocks < max_blocks); @@ -421,7 +421,7 @@ static void RealWritePCF7931(uint8_t *pass, uint16_t init_delay, int32_t l, int3 */ void WritePCF7931(uint8_t pass1, uint8_t pass2, uint8_t pass3, uint8_t pass4, uint8_t pass5, uint8_t pass6, uint8_t pass7, uint16_t init_delay, int32_t l, int32_t p, uint8_t address, uint8_t byte, uint8_t data) { - if ( DBGLEVEL >= DBG_INFO ) { + if (DBGLEVEL >= DBG_INFO) { Dbprintf("Initialization delay : %d us", init_delay); Dbprintf("Offsets : %d us on the low pulses width, %d us on the low pulses positions", l, p); } @@ -444,10 +444,10 @@ void WritePCF7931(uint8_t pass1, uint8_t pass2, uint8_t pass3, uint8_t pass4, ui void SendCmdPCF7931(uint32_t *tab) { uint16_t u = 0, tempo = 0; - if ( DBGLEVEL >= DBG_INFO ) { + if (DBGLEVEL >= DBG_INFO) { Dbprintf("Sending data frame..."); } - + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125kHz FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU); diff --git a/armsrc/ticks.c b/armsrc/ticks.c index 1510de490..7b66d17e6 100644 --- a/armsrc/ticks.c +++ b/armsrc/ticks.c @@ -187,7 +187,7 @@ uint32_t RAMFUNC GetCountSspClk(void) { uint32_t RAMFUNC GetCountSspClkDelta(uint32_t start) { uint32_t stop = GetCountSspClk(); - if ( stop >= start ) + if (stop >= start) return stop - start; return (UINT32_MAX - start) + stop; } From 49cd525cf1d4fcb9a81786c957cd119065f3f2d9 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 13 Sep 2019 16:26:17 +0200 Subject: [PATCH 0691/1854] style --- armsrc/Standalone/lf_hidbrute.c | 42 +++++++++++--------------------- armsrc/Standalone/lf_proxbrute.c | 22 ++++++++--------- 2 files changed, 25 insertions(+), 39 deletions(-) diff --git a/armsrc/Standalone/lf_hidbrute.c b/armsrc/Standalone/lf_hidbrute.c index b659bbdf1..625459238 100644 --- a/armsrc/Standalone/lf_hidbrute.c +++ b/armsrc/Standalone/lf_hidbrute.c @@ -52,18 +52,17 @@ void RunMod() { int playing = 0; int cardRead = 0; - // Turn on selected LED - LED(selected + 1, 0); - for (;;) { + WDT_HIT(); // exit from SamyRun, send a usbcommand. if (data_available()) break; // Was our button held down or pressed? - int button_pressed = BUTTON_HELD(1000); - SpinDelay(300); + int button_pressed = BUTTON_HELD(280); + if (button_pressed != BUTTON_HOLD) + continue; // Button was held for a second, begin recording if (button_pressed > 0 && cardRead == 0) { @@ -71,16 +70,11 @@ void RunMod() { LED(selected + 1, 0); LED(LED_D, 0); + WAIT_BUTTON_RELEASED(); + // record DbpString("[=] starting recording"); - // wait for button to be released - while (BUTTON_PRESS()) - WDT_HIT(); - - /* need this delay to prevent catching some weird data */ - SpinDelay(500); - CmdHIDdemodFSK(1, &high[selected], &low[selected], 0); Dbprintf("[=] recorded %x %x %08x", selected, high[selected], low[selected]); @@ -99,12 +93,7 @@ void RunMod() { // record Dbprintf("[=] cloning %x %x %08x", selected, high[selected], low[selected]); - // wait for button to be released - while (BUTTON_PRESS()) - WDT_HIT(); - - /* need this delay to prevent catching some weird data */ - SpinDelay(500); + WAIT_BUTTON_RELEASED(); CopyHIDtoT55x7(0, high[selected], low[selected], 0); Dbprintf("[=] cloned %x %x %08x", selected, high[selected], low[selected]); @@ -136,9 +125,7 @@ void RunMod() { LED(LED_B, 0); DbpString("[=] playing"); - // wait for button to be released - while (BUTTON_PRESS()) - WDT_HIT(); + WAIT_BUTTON_RELEASED(); Dbprintf("[=] %x %x %08x", selected, high[selected], low[selected]); CmdHIDsimTAG(high[selected], low[selected], 0); @@ -168,16 +155,15 @@ void RunMod() { LED(LED_B, 0); DbpString("[=] entering bruteforce mode"); - // wait for button to be released - while (BUTTON_PRESS()) - WDT_HIT(); + + WAIT_BUTTON_RELEASED(); // Calculate Facility Code and Card Number from high and low uint32_t cardnum = (low[selected] >> 1) & 0xFFFFF; uint32_t fc = ((high[selected] & 1) << 11) | (low[selected] >> 21); uint32_t original_cardnum = cardnum; - Dbprintf("[=] Proxbrute - starting decrementing card number"); + Dbprintf("[=] HID brute - starting decrementing card number"); while (cardnum > 0) { @@ -207,7 +193,7 @@ void RunMod() { cardnum = original_cardnum; - Dbprintf("[=] Proxbrute - starting incrementing card number"); + Dbprintf("[=] HID brute - starting incrementing card number"); while (cardnum <= 0xFFFFF) { @@ -247,13 +233,13 @@ void RunMod() { LED(selected + 1, 0); } else { - while (BUTTON_PRESS()) - WDT_HIT(); + WAIT_BUTTON_RELEASED(); } } } out: + SpinErr((LED_A | LED_B | LED_C | LED_D), 250, 5); DbpString("[=] exiting"); LEDsoff(); } diff --git a/armsrc/Standalone/lf_proxbrute.c b/armsrc/Standalone/lf_proxbrute.c index 5d435c3ee..5844dda84 100644 --- a/armsrc/Standalone/lf_proxbrute.c +++ b/armsrc/Standalone/lf_proxbrute.c @@ -42,13 +42,13 @@ void RunMod() { // exit from SamyRun, send a usbcommand. if (data_available()) break; - // Was our button held down or pressed? + // Was our button held down or pressed? int button_pressed = BUTTON_HELD(280); - if ( button_pressed != BUTTON_HOLD ) + if (button_pressed != BUTTON_HOLD) continue; // Button was held for a second, begin recording - if ( state == STATE_READ ) { + if (state == STATE_READ) { LEDsoff(); LED_A_ON(); @@ -63,8 +63,8 @@ void RunMod() { Dbprintf("[=] recorded | %x%08x", high, low); // got nothing. blink and loop. - if ( high == 0 && low == 0 ) { - SpinErr( LED_A, 100, 12); + if (high == 0 && low == 0) { + SpinErr(LED_A, 100, 12); DbpString("[=] only got zeros, retry recording after click"); continue; } @@ -73,7 +73,7 @@ void RunMod() { state = STATE_BRUTE; continue; - } else if ( state == STATE_BRUTE ) { + } else if (state == STATE_BRUTE) { LED_C_ON(); // Simulate WAIT_BUTTON_RELEASED(); @@ -97,7 +97,7 @@ void RunMod() { // Was our button held down or pressed? int button_pressed = BUTTON_HELD(280); - if ( button_pressed != BUTTON_HOLD ) break; + if (button_pressed != BUTTON_HOLD) break; Dbprintf("[=] trying Facility = %08x ID %08x", high, i); @@ -107,13 +107,13 @@ void RunMod() { SpinDelay(100); } - state = STATE_READ; - SpinErr( (LED_A | LED_C ), 250, 2); - LEDsoff(); + state = STATE_READ; + SpinErr((LED_A | LED_C), 250, 2); + LEDsoff(); } } - SpinErr( (LED_A | LED_B | LED_C | LED_D), 250, 5); + SpinErr((LED_A | LED_B | LED_C | LED_D), 250, 5); DbpString("[=] You can take the shell back :) ..."); LEDsoff(); } From f5bff0d4e50031833ee5fdee7134a42823d1e014 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 13 Sep 2019 16:27:25 +0200 Subject: [PATCH 0692/1854] style --- armsrc/Standalone/hf_young.c | 4 ++-- armsrc/util.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/armsrc/Standalone/hf_young.c b/armsrc/Standalone/hf_young.c index fcf964a5e..d5c211e79 100644 --- a/armsrc/Standalone/hf_young.c +++ b/armsrc/Standalone/hf_young.c @@ -114,9 +114,9 @@ void RunMod() { Dbprintf("ATQA = %02X%02X", uids[selected].atqa[0], uids[selected].atqa[1]); Dbprintf("SAK = %02X", uids[selected].sak); LEDsoff(); - LED(LED_B, 200); + LED(LED_B, 200); LED(LED_A, 200); - LED(LED_B, 200); + LED(LED_B, 200); LED(LED_A, 200); LEDsoff(); diff --git a/armsrc/util.c b/armsrc/util.c index 888c64b9d..d1a4fb938 100644 --- a/armsrc/util.c +++ b/armsrc/util.c @@ -90,7 +90,7 @@ void LEDsoff() { LED_D_OFF(); } -//ICEMAN: LED went from 1,2,3,4 -> 1,2,4,8 +//ICEMAN: LED went from 1,2,3,4 -> 1,2,4,8 void LED(int led, int ms) { if (led & LED_A) // Proxmark3 historical mapping: LED_ORANGE LED_A_ON(); From 2b25d863921e29b0b440449f9329571ca9090c44 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 13 Sep 2019 16:31:17 +0200 Subject: [PATCH 0693/1854] style --- client/cmddata.c | 4 +- client/cmdhficlass.c | 122 ++++++++++++++++++++--------------------- client/cmdhflist.c | 4 +- client/cmdhfmf.c | 2 +- client/cmdhfthinfilm.c | 2 +- client/cmdlfparadox.c | 2 +- 6 files changed, 68 insertions(+), 68 deletions(-) diff --git a/client/cmddata.c b/client/cmddata.c index 18e91c699..792cf6a96 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -461,10 +461,10 @@ int CmdPrintDemodBuff(const char *Cmd) { if (invert) { char *buf = (char *)(DemodBuffer + offset); for (uint32_t i = 0; i < length; i++) { - if ( buf[i] == 1 ) + if (buf[i] == 1) buf[i] = 0; else { - if ( buf[i] == 0 ) + if (buf[i] == 0) buf[i] = 1; } } diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index f45151a7b..5f8ed9fbc 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -87,7 +87,7 @@ static int usage_hf_iclass_decrypt(void) { PrintAndLogEx(NORMAL, "S hf iclass decrypt f tagdump_1.bin"); PrintAndLogEx(NORMAL, "S hf iclass decrypt f tagdump_1.bin k 000102030405060708090a0b0c0d0e0f"); PrintAndLogEx(NORMAL, "S hf iclass decrypt d 1122334455667788 k 000102030405060708090a0b0c0d0e0f"); - + return PM3_SUCCESS; } static int usage_hf_iclass_encrypt(void) { @@ -664,7 +664,7 @@ static int CmdHFiClassSim(const char *Cmd) { } static int CmdHFiClassInfo(const char *Cmd) { - return PM3_SUCCESS; + return PM3_SUCCESS; } static int CmdHFiClassReader(const char *Cmd) { @@ -809,7 +809,7 @@ static int CmdHFiClassDecrypt(const char *Cmd) { uint8_t cmdp = 0; uint8_t enc_data[8] = {0}; - + size_t keylen = 0; uint8_t key[32] = {0}; uint8_t *keyptr = NULL; @@ -827,7 +827,7 @@ static int CmdHFiClassDecrypt(const char *Cmd) { PrintAndLogEx(ERR, "data must be 16 HEX symbols"); errors = true; break; - } + } have_data = true; cmdp += 2; break; @@ -876,12 +876,12 @@ static int CmdHFiClassDecrypt(const char *Cmd) { uint8_t dec_data[8] = {0}; - if ( have_data ) { + if (have_data) { mbedtls_des3_crypt_ecb(&ctx, enc_data, dec_data); PrintAndLogEx(SUCCESS, "Data: %s", sprint_hex(dec_data, sizeof(dec_data))); } - if ( have_file ) { + if (have_file) { picopass_hdr *hdr = (picopass_hdr *)decrypted; uint8_t mem = hdr->conf.mem_config; @@ -1019,7 +1019,7 @@ static bool select_only(uint8_t *CSN, uint8_t *CCNR, bool use_credit_key, bool v } if (isOK <= 1) { - if ( verbose ) + if (verbose) PrintAndLogEx(FAILED, "failed to obtain CC! Tag-select is aborting... (%d)", isOK); return false; @@ -1056,7 +1056,7 @@ static bool select_and_auth(uint8_t *KEY, uint8_t *MAC, uint8_t *div_key, bool u return false; } - if ( resp.status != PM3_SUCCESS ) { + if (resp.status != PM3_SUCCESS) { if (verbose) PrintAndLogEx(ERR, "failed to communicate with card"); return false; } @@ -1213,7 +1213,7 @@ static int CmdHFiClassReader_Dump(const char *Cmd) { break; } while (numberAuthRetries--); - if ( numberAuthRetries <= 0) { + if (numberAuthRetries <= 0) { PrintAndLogEx(WARNING, "failed authenticating with debit key"); DropField(); return PM3_ESOFT; @@ -1271,7 +1271,7 @@ static int CmdHFiClassReader_Dump(const char *Cmd) { break; } while (numberAuthRetries--); - if ( numberAuthRetries <= 0) { + if (numberAuthRetries <= 0) { PrintAndLogEx(WARNING, "failed authenticating with credit key"); DropField(); return PM3_ESOFT; @@ -1313,7 +1313,7 @@ static int CmdHFiClassReader_Dump(const char *Cmd) { // add diversified keys to dump if (have_debit_key) memcpy(tag_data + (3 * 8), div_key, 8); - + if (have_credit_key) memcpy(tag_data + (4 * 8), c_div_key, 8); @@ -1340,14 +1340,14 @@ static int CmdHFiClassReader_Dump(const char *Cmd) { static int WriteBlock(uint8_t blockno, uint8_t *bldata, uint8_t *KEY, bool use_credit_key, bool elite, bool rawkey, bool verbose) { - int numberAuthRetries = ICLASS_AUTH_RETRY; + int numberAuthRetries = ICLASS_AUTH_RETRY; do { - + uint8_t MAC[4] = {0x00, 0x00, 0x00, 0x00}; uint8_t div_key[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; if (!select_and_auth(KEY, MAC, div_key, use_credit_key, elite, rawkey, verbose)) { numberAuthRetries--; - DropField(); + DropField(); continue; } @@ -1358,12 +1358,12 @@ static int WriteBlock(uint8_t blockno, uint8_t *bldata, uint8_t *KEY, bool use_c uint8_t data[12]; } PACKED payload; payload.blockno = blockno; - + memcpy(payload.data, bldata, 8); memcpy(payload.data + 8, MAC, 4); clearCommandBuffer(); - SendCommandNG(CMD_HF_ICLASS_WRITEBL, (uint8_t*)&payload, sizeof(payload)); + SendCommandNG(CMD_HF_ICLASS_WRITEBL, (uint8_t *)&payload, sizeof(payload)); PacketResponseNG resp; if (WaitForResponseTimeout(CMD_HF_ICLASS_WRITEBL, &resp, 4000) == 0) { @@ -1372,7 +1372,7 @@ static int WriteBlock(uint8_t blockno, uint8_t *bldata, uint8_t *KEY, bool use_c return PM3_ETIMEOUT; } - if ( resp.status != PM3_SUCCESS ) { + if (resp.status != PM3_SUCCESS) { if (verbose) PrintAndLogEx(ERR, "failed to communicate with card"); DropField(); return PM3_EWRONGANSVER; @@ -1381,17 +1381,17 @@ static int WriteBlock(uint8_t blockno, uint8_t *bldata, uint8_t *KEY, bool use_c if (resp.data.asBytes[0] == 1) break; - } while (numberAuthRetries); + } while (numberAuthRetries); DropField(); - if ( numberAuthRetries > 0 ) { + if (numberAuthRetries > 0) { PrintAndLogEx(SUCCESS, "Write block %02X successful\n", blockno); } else { - PrintAndLogEx(ERR,"failed to authenticate and write block"); + PrintAndLogEx(ERR, "failed to authenticate and write block"); return PM3_ESOFT; } - + return PM3_SUCCESS; } @@ -1442,7 +1442,7 @@ static int CmdHFiClass_WriteBlock(const char *Cmd) { } else if (dataLen == 1) { keyNbr = param_get8(Cmd, cmdp + 1); if (keyNbr < ICLASS_KEYS_MAX) { - PrintAndLogEx(SUCCESS, "Using key[%d] %s", keyNbr, sprint_hex(iClass_Key_Table[keyNbr], 8 )); + PrintAndLogEx(SUCCESS, "Using key[%d] %s", keyNbr, sprint_hex(iClass_Key_Table[keyNbr], 8)); memcpy(KEY, iClass_Key_Table[keyNbr], 8); } else { PrintAndLogEx(WARNING, "\nERROR: Credit KeyNbr is invalid\n"); @@ -1469,9 +1469,9 @@ static int CmdHFiClass_WriteBlock(const char *Cmd) { break; } } - if ( got_blockno == false) + if (got_blockno == false) errors = true; - + if (errors || cmdp < 6) return usage_hf_iclass_writeblock(); return WriteBlock(blockno, bldata, KEY, use_credit_key, elite, rawkey, verbose); @@ -1527,7 +1527,7 @@ static int CmdHFiClassCloneTag(const char *Cmd) { } else if (dataLen == 1) { keyNbr = param_get8(Cmd, cmdp + 1); if (keyNbr < ICLASS_KEYS_MAX) { - PrintAndLogEx(SUCCESS, "Using key[%d] %s", keyNbr, sprint_hex(iClass_Key_Table[keyNbr], 8 )); + PrintAndLogEx(SUCCESS, "Using key[%d] %s", keyNbr, sprint_hex(iClass_Key_Table[keyNbr], 8)); memcpy(KEY, iClass_Key_Table[keyNbr], 8); } else { PrintAndLogEx(WARNING, "\nERROR: Credit KeyNbr is invalid\n"); @@ -1559,7 +1559,7 @@ static int CmdHFiClassCloneTag(const char *Cmd) { break; } } - if ( got_endblk == false || got_startblk == false) + if (got_endblk == false || got_startblk == false) errors = true; if (errors || cmdp < 8) return usage_hf_iclass_clone(); @@ -1570,7 +1570,7 @@ static int CmdHFiClassCloneTag(const char *Cmd) { } int total_bytes = (((endblock - startblock) + 1) * 12); - + if (total_bytes > PM3_CMD_DATA_SIZE - 2) { PrintAndLogEx(NORMAL, "Trying to write too many blocks at once. Max: %d", PM3_CMD_DATA_SIZE / 8); return PM3_EINVARG; @@ -1593,7 +1593,7 @@ static int CmdHFiClassCloneTag(const char *Cmd) { fseek(f, startblock * 8, SEEK_SET); size_t bytes_read = fread(tag_data, sizeof(iclass_block_t), endblock - startblock + 1, f); fclose(f); - + if (bytes_read == 0) { PrintAndLogEx(ERR, "file reading error."); return PM3_EFILE; @@ -1601,14 +1601,14 @@ static int CmdHFiClassCloneTag(const char *Cmd) { uint8_t MAC[4] = {0x00, 0x00, 0x00, 0x00}; uint8_t div_key[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - + int numberAuthRetries = ICLASS_AUTH_RETRY; do { if (select_and_auth(KEY, MAC, div_key, use_credit_key, elite, rawkey, verbose)) break; } while (numberAuthRetries--); - - if ( numberAuthRetries <= 0 ) { + + if (numberAuthRetries <= 0) { PrintAndLogEx(ERR, "failed to authenticate"); DropField(); return PM3_ESOFT; @@ -1618,7 +1618,7 @@ static int CmdHFiClassCloneTag(const char *Cmd) { // calculate all mac for every the block we will write for (i = startblock; i <= endblock; i++) { - + Calc_wb_mac(i, tag_data[i - startblock].d, div_key, MAC); // usb command d start pointer = d + (i - 6) * 12 // memcpy(pointer,tag_data[i - 6],8) 8 bytes @@ -1629,17 +1629,17 @@ static int CmdHFiClassCloneTag(const char *Cmd) { memcpy(ptr + 8, MAC, 4); } - if ( verbose ) { - PrintAndLogEx(NORMAL,"------+--------------------------+-------------"); - PrintAndLogEx(NORMAL,"block | data | mac"); - PrintAndLogEx(NORMAL,"------+--------------------------+-------------"); + if (verbose) { + PrintAndLogEx(NORMAL, "------+--------------------------+-------------"); + PrintAndLogEx(NORMAL, "block | data | mac"); + PrintAndLogEx(NORMAL, "------+--------------------------+-------------"); uint8_t p[12]; for (i = 0; i <= endblock - startblock; i++) { memcpy(p, data + (i * 12), 12); char *s = calloc(70, sizeof(uint8_t)); sprintf(s, "| %s ", sprint_hex(p, 8)); sprintf(s + strlen(s), "| %s", sprint_hex(p + 8, 4)); - PrintAndLogEx(NORMAL, " %02X %s", i + startblock, s ); + PrintAndLogEx(NORMAL, " %02X %s", i + startblock, s); free(s); } } @@ -1649,23 +1649,23 @@ static int CmdHFiClassCloneTag(const char *Cmd) { uint8_t endblock; uint8_t data[PM3_CMD_DATA_SIZE - 2]; } PACKED payload; - + payload.startblock = startblock; - payload.endblock = endblock; + payload.endblock = endblock; memcpy(payload.data, data, total_bytes); - + PacketResponseNG resp; clearCommandBuffer(); - SendCommandNG(CMD_HF_ICLASS_CLONE, (uint8_t*)&payload, total_bytes + 2 ); + SendCommandNG(CMD_HF_ICLASS_CLONE, (uint8_t *)&payload, total_bytes + 2); if (WaitForResponseTimeout(CMD_HF_ICLASS_CLONE, &resp, 4500) == 0) { PrintAndLogEx(WARNING, "command execute timeout"); DropField(); return PM3_ETIMEOUT; } - - if (resp.status == PM3_SUCCESS) { - if ( resp.data.asBytes[0] == 1 ) + + if (resp.status == PM3_SUCCESS) { + if (resp.data.asBytes[0] == 1) PrintAndLogEx(SUCCESS, "Clone successful"); else PrintAndLogEx(WARNING, "Clone failed"); @@ -1678,12 +1678,12 @@ static int ReadBlock(uint8_t *KEY, uint8_t blockno, uint8_t keyType, bool elite, int numberAuthRetries = ICLASS_AUTH_RETRY; // return data. struct p { - bool isOK; + bool isOK; uint8_t blockdata[8]; } PACKED; struct p *result = NULL; - + do { // block 0,1 should always be able to read, and block 5 on some cards. if (auth || blockno >= 2) { @@ -1702,25 +1702,25 @@ static int ReadBlock(uint8_t *KEY, uint8_t blockno, uint8_t keyType, bool elite, DropField(); continue; } - } - + } + PacketResponseNG resp; clearCommandBuffer(); - SendCommandNG(CMD_HF_ICLASS_READBL, (uint8_t*)&blockno, sizeof(uint8_t)); - + SendCommandNG(CMD_HF_ICLASS_READBL, (uint8_t *)&blockno, sizeof(uint8_t)); + if (WaitForResponseTimeout(CMD_HF_ICLASS_READBL, &resp, 2000) == 0) { if (verbose) PrintAndLogEx(WARNING, "Command execute timeout"); DropField(); return PM3_ETIMEOUT; } - - if ( resp.status != PM3_SUCCESS ) { + + if (resp.status != PM3_SUCCESS) { if (verbose) PrintAndLogEx(ERR, "failed to communicate with card"); DropField(); return PM3_EWRONGANSVER; } - - result = (struct p*)resp.data.asBytes; + + result = (struct p *)resp.data.asBytes; if (result->isOK) break; @@ -1728,8 +1728,8 @@ static int ReadBlock(uint8_t *KEY, uint8_t blockno, uint8_t keyType, bool elite, DropField(); - if ( numberAuthRetries == 0 ) { - PrintAndLogEx(ERR,"failed to authenticate and read block"); + if (numberAuthRetries == 0) { + PrintAndLogEx(ERR, "failed to authenticate and read block"); return PM3_ESOFT; } @@ -1778,7 +1778,7 @@ static int CmdHFiClass_ReadBlock(const char *Cmd) { } else if (dataLen == 1) { keyNbr = param_get8(Cmd, cmdp + 1); if (keyNbr < ICLASS_KEYS_MAX) { - PrintAndLogEx(SUCCESS, "Using key[%d] %s", keyNbr, sprint_hex(iClass_Key_Table[keyNbr], 8 )); + PrintAndLogEx(SUCCESS, "Using key[%d] %s", keyNbr, sprint_hex(iClass_Key_Table[keyNbr], 8)); memcpy(KEY, iClass_Key_Table[keyNbr], 8); } else { PrintAndLogEx(WARNING, "\nERROR: Credit KeyNbr is invalid\n"); @@ -1805,9 +1805,9 @@ static int CmdHFiClass_ReadBlock(const char *Cmd) { break; } } - if ( got_blockno == false) + if (got_blockno == false) errors = true; - + if (errors || cmdp < 4) return usage_hf_iclass_readblock(); if (!auth) @@ -2815,8 +2815,8 @@ int readIclass(bool loop, bool verbose) { // no tag found or button pressed if ((readStatus == 0 && !loop) || readStatus == 0xFF) { // abort - DropField(); - return PM3_EOPABORTED; + DropField(); + return PM3_EOPABORTED; } if (readStatus & FLAG_ICLASS_READER_CSN) { diff --git a/client/cmdhflist.c b/client/cmdhflist.c index d44ac635c..a359ff07d 100644 --- a/client/cmdhflist.c +++ b/client/cmdhflist.c @@ -325,7 +325,7 @@ void annotateIso14443a(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) { void annotateIclass(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) { uint8_t c = cmd[0] & 0x0F; uint8_t parity = 0; - for ( uint8_t i=0; i<7; i++) { + for (uint8_t i = 0; i < 7; i++) { parity ^= (cmd[0] >> i) & 1; } @@ -363,7 +363,7 @@ void annotateIclass(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) { snprintf(exp, size, "UPDATE(%d)", cmd[1]); break; case ICLASS_CMD_READCHECK: - if ( ICLASS_CREDIT(c) ) { + if (ICLASS_CREDIT(c)) { snprintf(exp, size, "READCHECK[Kc](%d)", cmd[1]); } else { snprintf(exp, size, "READCHECK[Kd](%d)", cmd[1]); diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index baa999128..edd916330 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -1780,7 +1780,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { // card prng type (weak=1 / hard=0 / select/card comm error = negative value) prng_type = detect_classic_prng(); - if (prng_type < 0){ + if (prng_type < 0) { PrintAndLogEx(FAILED, "\nNo tag detected or other tag communication error"); free(e_sector); return prng_type; diff --git a/client/cmdhfthinfilm.c b/client/cmdhfthinfilm.c index a32aa8f59..3b31d460a 100644 --- a/client/cmdhfthinfilm.c +++ b/client/cmdhfthinfilm.c @@ -64,7 +64,7 @@ static int print_barcode(uint8_t *barcode, const size_t barcode_len, bool verbos } else { PrintAndLogEx(SUCCESS, " Checksum : "_YELLOW_("too few data for checksum")"- " _RED_("fail")); } - PrintAndLogEx(SUCCESS, " Data len (bits) : "_YELLOW_("%i")"- %s", barcode_len*8, (barcode_len==16||barcode_len==32) ? _GREEN_("OK") : _YELLOW_("warning")); + PrintAndLogEx(SUCCESS, " Data len (bits) : "_YELLOW_("%i")"- %s", barcode_len * 8, (barcode_len == 16 || barcode_len == 32) ? _GREEN_("OK") : _YELLOW_("warning")); PrintAndLogEx(SUCCESS, " Raw data : "_YELLOW_("%s"), sprint_hex(barcode, barcode_len)); if (barcode_len < 4) // too few to go to next decoding stages return PM3_ESOFT; diff --git a/client/cmdlfparadox.c b/client/cmdlfparadox.c index 5ef21992b..4cb0d484f 100644 --- a/client/cmdlfparadox.c +++ b/client/cmdlfparadox.c @@ -114,7 +114,7 @@ static int CmdParadoxRead(const char *Cmd) { static int CmdParadoxSim(const char *Cmd) { - PrintAndLogEx(INFO," To be implemented, feel free to contribute!"); + PrintAndLogEx(INFO, " To be implemented, feel free to contribute!"); return PM3_SUCCESS; } /* From f1307e703cf514e1d6b6dc6eba7fe28d1dcc802e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 13 Sep 2019 16:32:37 +0200 Subject: [PATCH 0694/1854] style --- client/cmdlft55xx.c | 76 ++++++++++++++++++++++----------------------- client/cmdtrace.c | 8 ++--- client/proxmark3.c | 14 ++++----- 3 files changed, 49 insertions(+), 49 deletions(-) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index cefb40cc6..8240fa106 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -482,8 +482,8 @@ static int CmdT55xxReadBlock(const char *Cmd) { case 'r': downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); if (downlink_mode > 3) - downlink_mode = 0; - + downlink_mode = 0; + cmdp += 2; break; @@ -649,10 +649,10 @@ static int CmdT55xxDetect(const char *Cmd) { return PM3_ESOFT; if (useGB == false) { - if ( try_all_dl_modes ) { + if (try_all_dl_modes) { for (uint8_t mode = 0; mode < 4; mode++) { - - if ( AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, mode) == false ) { + + if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, mode) == false) { continue; } @@ -663,8 +663,8 @@ static int CmdT55xxDetect(const char *Cmd) { } return PM3_ESOFT; } else { - if ( AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, downlink_mode) == false ) - return PM3_ENODATA; + if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, downlink_mode) == false) + return PM3_ENODATA; } } @@ -1132,9 +1132,9 @@ static int CmdT55xxWakeUp(const char *Cmd) { break; case 'r': downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); - if (downlink_mode > 3) + if (downlink_mode > 3) downlink_mode = 0; - + cmdp += 2; break; default: @@ -1150,17 +1150,17 @@ static int CmdT55xxWakeUp(const char *Cmd) { uint32_t password; uint8_t flags; } PACKED payload; - + payload.password = password; - payload.flags = (downlink_mode & 3) << 3; - + payload.flags = (downlink_mode & 3) << 3; + clearCommandBuffer(); SendCommandNG(CMD_LF_T55XX_WAKEUP, (uint8_t *)&payload, sizeof(payload)); if (!WaitForResponseTimeout(CMD_LF_T55XX_WAKEUP, NULL, 1000)) { PrintAndLogEx(WARNING, "command execution time out"); return PM3_ETIMEOUT; } - + PrintAndLogEx(SUCCESS, "Wake up command sent. Try read now"); return PM3_SUCCESS; } @@ -1212,7 +1212,7 @@ static int CmdT55xxWriteBlock(const char *Cmd) { downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); if (downlink_mode > 3) downlink_mode = 0; - + cmdp += 2; break; default: @@ -1273,9 +1273,9 @@ static int CmdT55xxReadTrace(const char *Cmd) { return usage_t55xx_trace(); case 'r': downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); - if (downlink_mode > 3) + if (downlink_mode > 3) downlink_mode = 0; - + cmdp += 2; break; case '1': @@ -1302,7 +1302,7 @@ static int CmdT55xxReadTrace(const char *Cmd) { if (!AquireData(T55x7_PAGE1, REGULAR_READ_MODE_BLOCK, pwdmode, password, downlink_mode)) return PM3_ENODATA; } - + if (config.Q5) { if (!DecodeT5555TraceBlock()) return PM3_ESOFT; } else { @@ -1570,9 +1570,9 @@ static int CmdT55xxInfo(const char *Cmd) { break; case 'r': downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); - if (downlink_mode > 3) + if (downlink_mode > 3) downlink_mode = 0; - + cmdp += 2; break; default: @@ -1594,7 +1594,7 @@ static int CmdT55xxInfo(const char *Cmd) { if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, downlink_mode)) return PM3_ENODATA; } - + if (!gotdata) { if (!DecodeT55xxBlock()) return PM3_ESOFT; @@ -1697,10 +1697,10 @@ static int CmdT55xxDump(const char *Cmd) { while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { case 'h': - return usage_t55xx_dump(); + return usage_t55xx_dump(); case 'r': downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); - if (downlink_mode > 3) + if (downlink_mode > 3) downlink_mode = 0; cmdp += 2; @@ -2027,9 +2027,9 @@ static int CmdResetRead(const char *Cmd) { return usage_t55xx_resetread(); case 'r': downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); - if (downlink_mode > 3) + if (downlink_mode > 3) downlink_mode = 0; - + cmdp += 2; break; default: @@ -2042,9 +2042,9 @@ static int CmdResetRead(const char *Cmd) { if (errors) return usage_t55xx_resetread(); PrintAndLogEx(INFO, "DL : %d\n", downlink_mode); - + flags = downlink_mode << 3; - + clearCommandBuffer(); SendCommandNG(CMD_LF_T55XX_RESET_READ, &flags, sizeof(flags)); if (!WaitForResponseTimeout(CMD_ACK, NULL, 2500)) { @@ -2153,7 +2153,7 @@ static int CmdT55xxChkPwds(const char *Cmd) { return usage_t55xx_chk(); case 'r': downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); - if (downlink_mode >= 4) { + if (downlink_mode >= 4) { try_all_dl_modes = true; downlink_mode = 4; } @@ -2164,7 +2164,7 @@ static int CmdT55xxChkPwds(const char *Cmd) { cmdp++; break; case 'i': - if ( param_getstr(Cmd, cmdp + 1, filename, sizeof(filename)) == 0 ) { + if (param_getstr(Cmd, cmdp + 1, filename, sizeof(filename)) == 0) { PrintAndLogEx(ERR, "Error, no filename after 'f' was found"); errors = true; } @@ -2305,9 +2305,9 @@ static int CmdT55xxBruteForce(const char *Cmd) { return usage_t55xx_bruteforce(); case 'r': downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); - if (downlink_mode > 4) + if (downlink_mode > 4) downlink_mode = 0; - + cmdp += 2; break; case 's': @@ -2415,9 +2415,9 @@ static int CmdT55xxRecoverPW(const char *Cmd) { break; case 'r': downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); - if (downlink_mode > 4) + if (downlink_mode > 4) downlink_mode = 0; - + cmdp += 2; break; default: @@ -2644,12 +2644,12 @@ static int CmdT55xxDetectPage1(const char *Cmd) { break; case 'r': downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); - if (downlink_mode == 4) + if (downlink_mode == 4) try_all_dl_modes = true; - + if (downlink_mode > 3) downlink_mode = 0; - + cmdp += 2; break; default: @@ -2725,10 +2725,10 @@ static int CmdT55xxSetDeviceConfig(const char *Cmd) { cmdp += 2; break; case 'r': - downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); - if (downlink_mode > 3) + downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); + if (downlink_mode > 3) downlink_mode = 0; - + cmdp += 2; break; case 'p': diff --git a/client/cmdtrace.c b/client/cmdtrace.c index 010621498..79e7c6169 100644 --- a/client/cmdtrace.c +++ b/client/cmdtrace.c @@ -303,18 +303,18 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr && (oddparity8(frame[j]) != ((parityBits >> (7 - (j & 0x0007))) & 0x01))) { snprintf(line[j / 18] + ((j % 18) * 4), 110, "%02x! ", frame[j]); - } else if ( protocol == ICLASS && isResponse == false) { + } else if (protocol == ICLASS && isResponse == false) { uint8_t parity = 0; - for (int i=0; i<6; i++) { + for (int i = 0; i < 6; i++) { parity ^= ((frame[0] >> i) & 1); } - if ( parity == ((frame[0] >> 7) & 1)) { + if (parity == ((frame[0] >> 7) & 1)) { snprintf(line[j / 18] + ((j % 18) * 4), 110, "%02x ", frame[j]); } else { snprintf(line[j / 18] + ((j % 18) * 4), 110, "%02x! ", frame[j]); } - } else { + } else { snprintf(line[j / 18] + ((j % 18) * 4), 110, "%02x ", frame[j]); } diff --git a/client/proxmark3.c b/client/proxmark3.c index 2ff94b841..f28e14063 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -368,13 +368,13 @@ static void show_help(bool showFullHelp, char *exec_name) { PrintAndLogEx(NORMAL, "\n to flash fullimage and bootloader:\n"); PrintAndLogEx(NORMAL, " %s "SERIAL_PORT_EXAMPLE_H" --flash --unlock-bootloader --image bootrom.elf --image fullimage.elf", exec_name); #ifdef __linux__ - PrintAndLogEx(NORMAL, "\nNote (Linux):\nif the flasher gets stuck in 'Waiting for Proxmark3 to reappear on ',"); - PrintAndLogEx(NORMAL, "you need to blacklist Proxmark3 for modem-manager - see documentation for more details:"); - PrintAndLogEx(NORMAL, "* https://github.com/RfidResearchGroup/proxmark3/blob/master/doc/md/Installation_Instructions/ModemManager-Must-Be-Discarded.md"); - PrintAndLogEx(NORMAL, "\nMore info on flashing procedure from the official Proxmark3 wiki:"); - PrintAndLogEx(NORMAL, "* https://github.com/Proxmark/proxmark3/wiki/Gentoo%%20Linux"); - PrintAndLogEx(NORMAL, "* https://github.com/Proxmark/proxmark3/wiki/Ubuntu%%20Linux"); - PrintAndLogEx(NORMAL, "* https://github.com/Proxmark/proxmark3/wiki/OSX\n"); + PrintAndLogEx(NORMAL, "\nNote (Linux):\nif the flasher gets stuck in 'Waiting for Proxmark3 to reappear on ',"); + PrintAndLogEx(NORMAL, "you need to blacklist Proxmark3 for modem-manager - see documentation for more details:"); + PrintAndLogEx(NORMAL, "* https://github.com/RfidResearchGroup/proxmark3/blob/master/doc/md/Installation_Instructions/ModemManager-Must-Be-Discarded.md"); + PrintAndLogEx(NORMAL, "\nMore info on flashing procedure from the official Proxmark3 wiki:"); + PrintAndLogEx(NORMAL, "* https://github.com/Proxmark/proxmark3/wiki/Gentoo%%20Linux"); + PrintAndLogEx(NORMAL, "* https://github.com/Proxmark/proxmark3/wiki/Ubuntu%%20Linux"); + PrintAndLogEx(NORMAL, "* https://github.com/Proxmark/proxmark3/wiki/OSX\n"); #endif } } From af02ee871d6b3e25bf6cc30fa9bf5b9e29b519d8 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 13 Sep 2019 20:50:00 +0200 Subject: [PATCH 0695/1854] chg: 'lf t55xx info c' - renamed from "d" to "c", takes a block0 and print info. chg: 'lf t55xx config c' - now takes a block0 and use as configuration. usage: lf t55xx config c 000880E8 lf t55xx info c 000880E8 --- client/cmdlft55xx.c | 72 ++++++++++++++++++++++++++++++++++++++------- client/cmdlft55xx.h | 1 + 2 files changed, 62 insertions(+), 11 deletions(-) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 8240fa106..b3d2d594f 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -36,8 +36,17 @@ #define T55XX_DLMODE_1OF4 3 // 1 of 4 #define T55XX_LONGLEADINGREFERENCE 4 // Value to tell Write Bit to send long reference +//static uint8_t bit_rates[9] = {8, 16, 32, 40, 50, 64, 100, 128, 0}; + // Default configuration -t55xx_conf_block_t config = { .modulation = DEMOD_ASK, .inverted = false, .offset = 0x00, .block0 = 0x00, .Q5 = false }; +t55xx_conf_block_t config = { + .modulation = DEMOD_ASK, + .inverted = false, + .offset = 0x00, + .block0 = 0x00, + .Q5 = false, + .usepwd = false + }; t55xx_conf_block_t Get_t55xx_Config() { return config; @@ -55,9 +64,10 @@ static void print_usage_t55xx_downloadlink(void) { } static int usage_t55xx_config() { - PrintAndLogEx(NORMAL, "Usage: lf t55xx config [d ] [i [0/1]] [o ] [Q5 [0/1]] [ST [0/1]]"); + PrintAndLogEx(NORMAL, "Usage: lf t55xx config [c ] [d ] [i [0/1]] [o ] [Q5 [0/1]] [ST [0/1]]"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h - This help"); + PrintAndLogEx(NORMAL, " c - set configuration from a block0"); PrintAndLogEx(NORMAL, " b <8|16|32|40|50|64|100|128> - Set bitrate"); PrintAndLogEx(NORMAL, " d - Set demodulation FSK / ASK / PSK / NRZ / Biphase / Biphase A"); PrintAndLogEx(NORMAL, " i [0/1] - Set/reset data signal inversion"); @@ -131,14 +141,14 @@ static int usage_t55xx_trace() { return PM3_SUCCESS; } static int usage_t55xx_info() { - PrintAndLogEx(NORMAL, "Usage: lf t55xx info [1] [r ] [d [q]]"); + PrintAndLogEx(NORMAL, "Usage: lf t55xx info [1] [r ] [c [q]]"); PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " (default) - read data from tag."); - PrintAndLogEx(NORMAL, " p - OPTIONAL password 4bytes (8 hex symbols)"); - PrintAndLogEx(NORMAL, " 1 - if set, use Graphbuffer instead of reading tag."); - PrintAndLogEx(NORMAL, " d - 4 bytes of data (8 hex characters)"); + PrintAndLogEx(NORMAL, " (default) - read data from tag."); + PrintAndLogEx(NORMAL, " p - OPTIONAL password 4bytes (8 hex symbols)"); + PrintAndLogEx(NORMAL, " 1 - if set, use Graphbuffer instead of reading tag."); + PrintAndLogEx(NORMAL, " c - set configuration from a block0"); PrintAndLogEx(NORMAL, " if set, use these data instead of reading tag."); - PrintAndLogEx(NORMAL, " q - if set, provided data are interpreted as Q5 config."); + PrintAndLogEx(NORMAL, " q - if set, provided data are interpreted as Q5 config."); print_usage_t55xx_downloadlink(); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); @@ -312,6 +322,9 @@ static int CmdT55xxSetConfig(const char *Cmd) { uint8_t rates[9] = {8, 16, 32, 40, 50, 64, 100, 128, 0}; uint8_t cmdp = 0; bool errors = false; + uint32_t block0 = 0; + bool gotconf = false; + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { char tmp = tolower(param_getchar(Cmd, cmdp)); switch (tmp) { @@ -331,6 +344,11 @@ static int CmdT55xxSetConfig(const char *Cmd) { } cmdp += 2; break; + case 'c': + block0 = param_get32ex(Cmd, cmdp + 1, 0, 16); + gotconf = true; + cmdp += 2; + break; case 'd': param_getstr(Cmd, cmdp + 1, modulation, sizeof(modulation)); cmdp += 2; @@ -413,7 +431,36 @@ static int CmdT55xxSetConfig(const char *Cmd) { //Validations if (errors) return usage_t55xx_config(); - config.block0 = 0; + if ( gotconf ) { + + // Q5 + + + // T55x7 + uint32_t extend = (block0 >> (32 - 15)) & 0x01; + uint32_t dbr; + if (extend) + dbr = (block0 >> (32 - 14)) & 0x3F; + else + dbr = (block0 >> (32 - 14)) & 0x07; + + uint32_t datamod = (block0 >> (32 - 20)) & 0x1F; + bool pwd = (bool)((block0 >> (32 - 28)) & 0x01); + bool sst = (bool)((block0 >> (32 - 29)) & 0x01); + bool inv = (bool)((block0 >> (32 - 31)) & 0x01); + + config.modulation = datamod; + config.bitrate = dbr; + config.inverted = inv; + config.Q5 = 0; + config.ST = sst; + config.usepwd = pwd; + config.offset = 0; + config.block0 = block0; + } else { + config.block0 = 0; + } + return printConfiguration(config); } @@ -1014,11 +1061,14 @@ static bool testQ5(uint8_t mode, uint8_t *offset, int *fndBitRate, uint8_t clk) si += 3; //uint8_t ST = PackBits(si, 1, DemodBuffer); si += 1; if (maxBlk == 0) continue; + //test modulation if (!testQ5Modulation(mode, modread)) continue; if (bitRate != clk) continue; + *fndBitRate = convertQ5bitRate(bitRate); if (*fndBitRate < 0) continue; + *offset = idx; return true; @@ -1550,7 +1600,7 @@ static int CmdT55xxInfo(const char *Cmd) { switch (tolower(param_getchar(Cmd, cmdp))) { case 'h': return usage_t55xx_info(); - case 'd': + case 'c': block0 = param_get32ex(Cmd, cmdp + 1, 0, 16); gotdata = true; cmdp += 2; @@ -1602,7 +1652,7 @@ static int CmdT55xxInfo(const char *Cmd) { if (DemodBufferLen < 32 + config.offset) return PM3_ESOFT; //PrintAndLogEx(NORMAL, "Offset+32 ==%d\n DemodLen == %d", config.offset + 32, DemodBufferLen); - block0 = PackBits(config.offset, 32, DemodBuffer); + block0 = PackBits(config.offset, 32, DemodBuffer); } PrintAndLogEx(NORMAL, ""); diff --git a/client/cmdlft55xx.h b/client/cmdlft55xx.h index 668b23be3..3764a529c 100644 --- a/client/cmdlft55xx.h +++ b/client/cmdlft55xx.h @@ -116,6 +116,7 @@ typedef struct { } bitrate; bool Q5; bool ST; + bool usepwd; } t55xx_conf_block_t; t55xx_conf_block_t Get_t55xx_Config(void); From 250be16876aec6876f99aeb32d0ed7d056ae8e5c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 13 Sep 2019 21:25:39 +0200 Subject: [PATCH 0696/1854] chg: 'lf t55 write v' - validation of data. After a write, the command tries to read the block and see if it matches the data entered. This can fail because of password, not correct configuration settings before. Also validating a block0 write is harder, some modulations are not that perfect. This is however a nice step forward. --- client/cmdlft55xx.c | 64 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 61 insertions(+), 3 deletions(-) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index b3d2d594f..7623fd5e6 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -113,18 +113,20 @@ static int usage_t55xx_resetread() { return PM3_SUCCESS; } static int usage_t55xx_write() { - PrintAndLogEx(NORMAL, "Usage: lf t55xx write [r ] b d [p ] [1] [t]"); + PrintAndLogEx(NORMAL, "Usage: lf t55xx write [r ] b d [p ] [1] [t] [v]"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " b - block number to write. Between 0-7"); PrintAndLogEx(NORMAL, " d - 4 bytes of data to write (8 hex characters)"); PrintAndLogEx(NORMAL, " p - OPTIONAL password 4bytes (8 hex characters)"); PrintAndLogEx(NORMAL, " 1 - OPTIONAL write Page 1 instead of Page 0"); PrintAndLogEx(NORMAL, " t - OPTIONAL test mode write - ****DANGER****"); + PrintAndLogEx(NORMAL, " v - OPTIONAL validate data afterwards"); print_usage_t55xx_downloadlink(); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx write b 3 d 11223344 - write 11223344 to block 3"); PrintAndLogEx(NORMAL, " lf t55xx write b 3 d 11223344 p feedbeef - write 11223344 to block 3 password feedbeef"); + PrintAndLogEx(NORMAL, " lf t55xx write b 3 d 11223344 v - write 11223344 to block 3 and try to validate data"); PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } @@ -306,6 +308,48 @@ static int usage_lf_deviceconfig() { static int CmdHelp(const char *Cmd); +static bool t55xxVerifyWrite( uint8_t block, bool page1, bool usepwd, uint8_t override, uint32_t password, uint8_t downlink_mode, uint32_t data) { + + //Password mode + if (usepwd) { + // try reading the config block and verify that PWD bit is set before doing this! + if (override == 0) { + if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, false, 0, downlink_mode) == false) + return false; + + if (tryDetectModulation() == false) { + PrintAndLogEx(NORMAL, "Safety Check: Could not detect if PWD bit is set in config block. Exits."); + return false; + } else { + PrintAndLogEx(NORMAL, "Safety Check: PWD bit is NOT set in config block. Reading without password..."); + usepwd = false; + } + } else if (override == 1) { + PrintAndLogEx(NORMAL, "Safety Check Overriden - proceeding despite risk"); + } + } + + if (AquireData(page1, block, usepwd, password, downlink_mode) == false) + return false; + + if (block == 0 && page1 == false) { + if (tryDetectModulation() == false) { + PrintAndLogEx(WARNING, "Could not detect modulation automatically. Try setting it manually with \'lf t55xx config\'"); + return false; + } + } + + if (DecodeT55xxBlock() == false) + return false; + + // compare... + uint32_t readblock = 0; + if (GetT55xxBlockData(&readblock) == false) + return false; + + return (readblock == data); +} + void printT5xxHeader(uint8_t page) { PrintAndLogEx(NORMAL, "Reading Page %d:", page); PrintAndLogEx(NORMAL, "blk | hex data | binary | ascii"); @@ -1224,6 +1268,7 @@ static int CmdT55xxWriteBlock(const char *Cmd) { bool gotdata = false; bool testMode = false; bool errors = false; + bool validate = false; uint8_t cmdp = 0; uint32_t downlink_mode = 0; @@ -1265,6 +1310,10 @@ static int CmdT55xxWriteBlock(const char *Cmd) { cmdp += 2; break; + case 'v': + validate = true; + cmdp++; + break; default: PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); errors = true; @@ -1285,8 +1334,6 @@ static int CmdT55xxWriteBlock(const char *Cmd) { PrintAndLogEx(INFO, "Writing page %d block: %02d data: 0x%08X %s", page1, block, data, (usepwd) ? pwdStr : ""); - clearCommandBuffer(); - /* OLD style arg0 = data, (4 bytes) @@ -1303,11 +1350,22 @@ static int CmdT55xxWriteBlock(const char *Cmd) { ng.blockno = block; ng.flags = flags; + clearCommandBuffer(); SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng)); if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, 2000)) { PrintAndLogEx(ERR, "Error occurred, device did not ACK write operation. (May be due to old firmware)"); return PM3_ETIMEOUT; } + + if (validate) { +//t55xxVerifyWrite( uint8_t block, bool page1, bool usepwd, uint8_t override, uint32_t password, uint8_t downlink_mode, uint32_t data) { + bool isOK = t55xxVerifyWrite(block, page1, usepwd, 1, password, downlink_mode, data); + if (isOK) + PrintAndLogEx(SUCCESS, "Write OK, validation succesful"); + else + PrintAndLogEx(WARNING, "Write could not validate the written data"); + } + return PM3_SUCCESS; } From c3756f19034fac162e745a0a1cd36ce249b8904d Mon Sep 17 00:00:00 2001 From: mwalker33 Date: Sat, 14 Sep 2019 14:13:55 +1000 Subject: [PATCH 0697/1854] T55xx DLMode Update --- CHANGELOG.md | 4 +- client/cmdlft55xx.c | 247 ++++++++++++++++++++++++++++---------------- client/cmdlft55xx.h | 9 +- client/scripting.c | 4 +- 4 files changed, 173 insertions(+), 91 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2099db5fb..49be5d124 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -349,7 +349,9 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Added `hf fido` `assert` and `make` commands from fido2 protocol (authenticatorMakeCredential and authenticatorGetAssertion) (@merlokk) - Added trailer block decoding to `hf mf rdbl` and `hf mf cgetbl` (@merlokk) - Added `hf mf mad` and `hf mfp mad` MAD decode, check and print commands (@merlokk) - - Added T55x7 downlink mode support r 0 Default, 1 Long Leading 0, 2 Leading 0, 3 1 of 4 and 4 (in some commands) try all. + - Added T55x7 downlink mode support r 0 Default, 1 Long Leading 0, 2 Leading 0, 3 1 of 4 and 4 (in some commands) try all. (@mwalker33) + - Added T55x7 downlink mode auto usage via mode detected (lf t55 detect) (@mwalker33) + - Fix T55xx config getting displayed when using password when no password needed on read. (@mwalker33) ### Fixed - Changed driver file proxmark3.inf to support both old and new Product/Vendor IDs (@pwpiwi) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 7623fd5e6..f36e30e48 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -34,7 +34,12 @@ #define T55XX_DLMODE_LLR 1 // Long Leading Reference #define T55XX_DLMODE_LEADING_ZERO 2 // Leading Zero #define T55XX_DLMODE_1OF4 3 // 1 of 4 -#define T55XX_LONGLEADINGREFERENCE 4 // Value to tell Write Bit to send long reference +// #define T55XX_LONGLEADINGREFERENCE 4 // Value to tell Write Bit to send long reference +#define T55XX_DLMODE_ALL 4 // Tell help to show 'r 4' for all dl modes +#define T55XX_DLMODE_SINGLE 5 // Tell help file NOT to show 'r 4' (not available) + +#define T55XX_PrintConfig true +#define T55XX_DontPrintConfig false //static uint8_t bit_rates[9] = {8, 16, 32, 40, 50, 64, 100, 128, 0}; @@ -45,7 +50,8 @@ t55xx_conf_block_t config = { .offset = 0x00, .block0 = 0x00, .Q5 = false, - .usepwd = false + .usepwd = false, + .downlink_mode = refFixedBit }; t55xx_conf_block_t Get_t55xx_Config() { @@ -55,25 +61,33 @@ void Set_t55xx_Config(t55xx_conf_block_t conf) { config = conf; } -static void print_usage_t55xx_downloadlink(void) { - PrintAndLogEx(NORMAL, " r - downlink encoding 0|1|2|3"); - PrintAndLogEx(NORMAL, " 0 - fixed bit length (default)"); +static void print_usage_t55xx_downloadlink(uint8_t ShowAll) { + if (ShowAll == T55XX_DLMODE_ALL) + PrintAndLogEx(NORMAL, " r - downlink encoding 0|1|2|3|4"); + else + PrintAndLogEx(NORMAL, " r - downlink encoding 0|1|2|3"); + PrintAndLogEx(NORMAL, " 0 - fixed bit length"); // default will be whats in config struct PrintAndLogEx(NORMAL, " 1 - long leading reference"); PrintAndLogEx(NORMAL, " 2 - leading zero"); PrintAndLogEx(NORMAL, " 3 - 1 of 4 coding reference"); + if (ShowAll == T55XX_DLMODE_ALL) + PrintAndLogEx(NORMAL, " 4 - Try all downlink modes"); } static int usage_t55xx_config() { PrintAndLogEx(NORMAL, "Usage: lf t55xx config [c ] [d ] [i [0/1]] [o ] [Q5 [0/1]] [ST [0/1]]"); PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " h - This help"); - PrintAndLogEx(NORMAL, " c - set configuration from a block0"); - PrintAndLogEx(NORMAL, " b <8|16|32|40|50|64|100|128> - Set bitrate"); - PrintAndLogEx(NORMAL, " d - Set demodulation FSK / ASK / PSK / NRZ / Biphase / Biphase A"); - PrintAndLogEx(NORMAL, " i [0/1] - Set/reset data signal inversion"); - PrintAndLogEx(NORMAL, " o [offset] - Set offset, where data should start decode in bitstream"); - PrintAndLogEx(NORMAL, " Q5 [0/1] - Set/reset as Q5(T5555) chip instead of T55x7"); - PrintAndLogEx(NORMAL, " ST [0/1] - Set/reset Sequence Terminator on"); + PrintAndLogEx(NORMAL, " h - This help"); + PrintAndLogEx(NORMAL, " c - set configuration from a block0"); + PrintAndLogEx(NORMAL, " b <8|16|32|40|50|64|100|128> - Set bitrate"); + PrintAndLogEx(NORMAL, " d - Set demodulation FSK / ASK / PSK / NRZ / Biphase / Biphase A"); + PrintAndLogEx(NORMAL, " i [0/1] - Set/reset data signal inversion"); + PrintAndLogEx(NORMAL, " o [offset] - Set offset, where data should start decode in bitstream"); + PrintAndLogEx(NORMAL, " Q5 [0/1] - Set/reset as Q5(T5555) chip instead of T55x7"); + PrintAndLogEx(NORMAL, " ST [0/1] - Set/reset Sequence Terminator on"); + PrintAndLogEx(NORMAL, ""); // layout is a little differnet, so seperate until a better fix + print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE); + PrintAndLogEx(NORMAL, "fix this code...."); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx config d FSK - FSK demodulation"); @@ -89,7 +103,7 @@ static int usage_t55xx_read() { PrintAndLogEx(NORMAL, " p - OPTIONAL password (8 hex characters)"); PrintAndLogEx(NORMAL, " o - OPTIONAL override safety check"); PrintAndLogEx(NORMAL, " 1 - OPTIONAL 0|1 read Page 1 instead of Page 0"); - print_usage_t55xx_downloadlink(); + print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE); PrintAndLogEx(NORMAL, " ****WARNING****"); PrintAndLogEx(NORMAL, " Use of read with password on a tag not configured for a pwd"); PrintAndLogEx(NORMAL, " can damage the tag"); @@ -105,7 +119,7 @@ static int usage_t55xx_resetread() { PrintAndLogEx(NORMAL, "Send Reset Cmd then lf read the stream to attempt to identify the start of it (needs a demod and/or plot after)"); PrintAndLogEx(NORMAL, "Usage: lf t55xx resetread [r ]"); PrintAndLogEx(NORMAL, "Options:"); - print_usage_t55xx_downloadlink(); + print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx resetread"); @@ -121,7 +135,7 @@ static int usage_t55xx_write() { PrintAndLogEx(NORMAL, " 1 - OPTIONAL write Page 1 instead of Page 0"); PrintAndLogEx(NORMAL, " t - OPTIONAL test mode write - ****DANGER****"); PrintAndLogEx(NORMAL, " v - OPTIONAL validate data afterwards"); - print_usage_t55xx_downloadlink(); + print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx write b 3 d 11223344 - write 11223344 to block 3"); @@ -133,7 +147,7 @@ static int usage_t55xx_write() { static int usage_t55xx_trace() { PrintAndLogEx(NORMAL, "Usage: lf t55xx trace [1] [r mode]"); PrintAndLogEx(NORMAL, "Options:"); - print_usage_t55xx_downloadlink(); + print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE); PrintAndLogEx(NORMAL, " 1 - if set, use Graphbuffer otherwise read data from tag."); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); @@ -145,13 +159,13 @@ static int usage_t55xx_trace() { static int usage_t55xx_info() { PrintAndLogEx(NORMAL, "Usage: lf t55xx info [1] [r ] [c [q]]"); PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " (default) - read data from tag."); - PrintAndLogEx(NORMAL, " p - OPTIONAL password 4bytes (8 hex symbols)"); - PrintAndLogEx(NORMAL, " 1 - if set, use Graphbuffer instead of reading tag."); - PrintAndLogEx(NORMAL, " c - set configuration from a block0"); - PrintAndLogEx(NORMAL, " if set, use these data instead of reading tag."); - PrintAndLogEx(NORMAL, " q - if set, provided data are interpreted as Q5 config."); - print_usage_t55xx_downloadlink(); + PrintAndLogEx(NORMAL, " (default) - read data from tag."); + PrintAndLogEx(NORMAL, " p - OPTIONAL password 4bytes (8 hex symbols)"); + PrintAndLogEx(NORMAL, " 1 - if set, use Graphbuffer instead of reading tag."); + PrintAndLogEx(NORMAL, " c - set configuration from a block0"); + PrintAndLogEx(NORMAL, " if set, use these data instead of reading tag."); + PrintAndLogEx(NORMAL, " q - if set, provided data are interpreted as Q5 config."); + print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx info"); @@ -167,7 +181,7 @@ static int usage_t55xx_dump() { PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " p - OPTIONAL password 4bytes (8 hex symbols)"); PrintAndLogEx(NORMAL, " o - OPTIONAL override, force pwd read despite danger to card"); - print_usage_t55xx_downloadlink(); + print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx dump"); @@ -180,7 +194,7 @@ static int usage_t55xx_detect() { PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " 1 - if set, use Graphbuffer otherwise read data from tag."); PrintAndLogEx(NORMAL, " p - OPTIONAL password (8 hex characters)"); - print_usage_t55xx_downloadlink(); + print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE); // Need to setup to try all modes PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx p1detect"); @@ -210,7 +224,7 @@ static int usage_t55xx_wakup() { PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h - this help"); PrintAndLogEx(NORMAL, " p - password 4bytes (8 hex symbols)"); - print_usage_t55xx_downloadlink(); + print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx wakeup p 11223344 - send wakeup password"); @@ -225,7 +239,7 @@ static int usage_t55xx_chk() { PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h - this help"); PrintAndLogEx(NORMAL, " m - use dictionary from flashmemory\n"); - print_usage_t55xx_downloadlink(); + print_usage_t55xx_downloadlink(T55XX_DLMODE_ALL); PrintAndLogEx(NORMAL, " i <*.dic> - loads a default keys dictionary file <*.dic>"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); @@ -243,7 +257,7 @@ static int usage_t55xx_bruteforce() { PrintAndLogEx(NORMAL, " password must be 4 bytes (8 hex symbols)"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h - this help"); - print_usage_t55xx_downloadlink(); + print_usage_t55xx_downloadlink(T55XX_DLMODE_ALL); PrintAndLogEx(NORMAL, " s - 4 byte hex value to start pwd search at"); PrintAndLogEx(NORMAL, " e - 4 byte hex value to end pwd search at"); PrintAndLogEx(NORMAL, ""); @@ -257,17 +271,17 @@ static int usage_t55xx_recoverpw() { PrintAndLogEx(NORMAL, "press " _YELLOW_("'enter'") " to cancel the command"); PrintAndLogEx(NORMAL, "WARNING: this may brick non-password protected chips!"); PrintAndLogEx(NORMAL, "Try reading block 7 before\n"); - PrintAndLogEx(NORMAL, "Usage: lf t55xx recoverpw [r ] [password]"); + PrintAndLogEx(NORMAL, "Usage: lf t55xx recoverpw [r ] [p password]"); PrintAndLogEx(NORMAL, " password must be 4 bytes (8 hex symbols)"); PrintAndLogEx(NORMAL, " default password is 51243648, used by many cloners"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h - this help"); - print_usage_t55xx_downloadlink(); + print_usage_t55xx_downloadlink(T55XX_DLMODE_ALL); PrintAndLogEx(NORMAL, " [password] - 4 byte hex value of password written by cloner"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx recoverpw"); - PrintAndLogEx(NORMAL, " lf t55xx r 3 recoverpw 51243648"); + PrintAndLogEx(NORMAL, " lf t55xx recoverpw r 3 p 51243648"); PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } @@ -296,7 +310,7 @@ static int usage_lf_deviceconfig() { PrintAndLogEx(NORMAL, " f <8..255> - Set write TWO gap (1 of 4 only)"); PrintAndLogEx(NORMAL, " g <8..255> - Set write THREE gap (1 of 4 only)"); PrintAndLogEx(NORMAL, " p - persist to flashmemory"); - print_usage_t55xx_downloadlink(); + // print_usage_t55xx_downloadlink(); // does not apply to config PrintAndLogEx(NORMAL, " z - Set default t55x7 timings (use p to save if required)"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); @@ -317,7 +331,7 @@ static bool t55xxVerifyWrite( uint8_t block, bool page1, bool usepwd, uint8_t ov if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, false, 0, downlink_mode) == false) return false; - if (tryDetectModulation() == false) { + if (tryDetectModulation(downlink_mode,T55XX_DontPrintConfig) == false) { PrintAndLogEx(NORMAL, "Safety Check: Could not detect if PWD bit is set in config block. Exits."); return false; } else { @@ -333,7 +347,7 @@ static bool t55xxVerifyWrite( uint8_t block, bool page1, bool usepwd, uint8_t ov return false; if (block == 0 && page1 == false) { - if (tryDetectModulation() == false) { + if (tryDetectModulation(downlink_mode,T55XX_DontPrintConfig) == false) { PrintAndLogEx(WARNING, "Could not detect modulation automatically. Try setting it manually with \'lf t55xx config\'"); return false; } @@ -365,6 +379,7 @@ static int CmdT55xxSetConfig(const char *Cmd) { char modulation[6] = {0x00}; uint8_t rates[9] = {8, 16, 32, 40, 50, 64, 100, 128, 0}; uint8_t cmdp = 0; + uint8_t downlink_mode = 0; bool errors = false; uint32_t block0 = 0; bool gotconf = false; @@ -465,6 +480,14 @@ static int CmdT55xxSetConfig(const char *Cmd) { cmdp += 1; } break; + case 'r': + errors = param_getdec(Cmd, cmdp + 1,&downlink_mode); + if (downlink_mode > 3) + downlink_mode = 0; + if (!errors) + config.downlink_mode = downlink_mode; + cmdp += 2; + break; default: PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); errors = true; @@ -515,7 +538,7 @@ int T55xxReadBlock(uint8_t block, bool page1, bool usepwd, uint8_t override, uin if (override == 0) { if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, false, 0, downlink_mode)) return PM3_ESOFT; - if (!tryDetectModulation()) { + if (!tryDetectModulation(downlink_mode,T55XX_DontPrintConfig)) { PrintAndLogEx(NORMAL, "Safety Check: Could not detect if PWD bit is set in config block. Exits."); return PM3_ESOFT; } else { @@ -543,7 +566,7 @@ static int CmdT55xxReadBlock(const char *Cmd) { uint8_t block = REGULAR_READ_MODE_BLOCK; uint8_t override = 0; uint8_t cmdp = 0; - uint8_t downlink_mode = 0; + uint8_t downlink_mode = config.downlink_mode; uint32_t password = 0; //default to blank Block 7 bool usepwd = false; bool page1 = false; @@ -695,16 +718,19 @@ void T55xx_Print_DownlinkMode(uint8_t downlink_mode) { PrintAndLogEx(NORMAL, msg); } -// + + static int CmdT55xxDetect(const char *Cmd) { bool errors = false; bool useGB = false; bool usepwd = false; - bool try_all_dl_modes = false; + bool try_all_dl_modes = true; + bool found = false; uint32_t password = 0; uint8_t cmdp = 0; uint8_t downlink_mode = 0; + uint8_t dl_mode = 0; while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { @@ -721,10 +747,9 @@ static int CmdT55xxDetect(const char *Cmd) { break; case 'r': downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); - if (downlink_mode >= 4) { - try_all_dl_modes = true; - downlink_mode = 4; - } + if (downlink_mode <= 3) try_all_dl_modes = false; // User selected ONLY 1 so honor. + if (downlink_mode == 4) try_all_dl_modes = true; + if (downlink_mode > 3) downlink_mode = 0; cmdp += 2; break; default: @@ -740,32 +765,29 @@ static int CmdT55xxDetect(const char *Cmd) { return PM3_ESOFT; if (useGB == false) { - if (try_all_dl_modes) { - for (uint8_t mode = 0; mode < 4; mode++) { + for (dl_mode = downlink_mode; dl_mode < 4; dl_mode++) { + found = AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, dl_mode); - if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, mode) == false) { - continue; - } - - if (tryDetectModulation()) { - T55xx_Print_DownlinkMode(mode); - return PM3_SUCCESS; - } + if (tryDetectModulation(dl_mode,T55XX_PrintConfig)) { + dl_mode = 4; + found = true; } - return PM3_ESOFT; - } else { - if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, downlink_mode) == false) - return PM3_ENODATA; + else found = false; + + if (!try_all_dl_modes) dl_mode = 4; } + } else { + found = tryDetectModulation(downlink_mode,T55XX_PrintConfig); } - - if (tryDetectModulation() == false) + + if (!found) PrintAndLogEx(WARNING, "Could not detect modulation automatically. Try setting it manually with " _YELLOW_("\'lf t55xx config\'")); - + return PM3_SUCCESS; } + // detect configuration? -bool tryDetectModulation(void) { +bool tryDetectModulation(uint8_t downlink_mode, bool print_config) { t55xx_conf_block_t tests[15]; int bitRate = 0, clk = 0, firstClockEdge = 0; @@ -784,6 +806,7 @@ bool tryDetectModulation(void) { tests[hits].inverted = false; tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); tests[hits].ST = false; + tests[hits].downlink_mode = downlink_mode; ++hits; } if ((FSKrawDemod("0 1", false) == PM3_SUCCESS) && test(DEMOD_FSK, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) { @@ -796,6 +819,7 @@ bool tryDetectModulation(void) { tests[hits].inverted = true; tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); tests[hits].ST = false; + tests[hits].downlink_mode = downlink_mode; ++hits; } } else { @@ -812,6 +836,7 @@ bool tryDetectModulation(void) { tests[hits].bitrate = bitRate; tests[hits].inverted = false; tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); + tests[hits].downlink_mode = downlink_mode; ++hits; } tests[hits].ST = true; @@ -825,6 +850,7 @@ bool tryDetectModulation(void) { tests[hits].bitrate = bitRate; tests[hits].inverted = true; tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); + tests[hits].downlink_mode = downlink_mode; ++hits; } if ((ASKbiphaseDemod("0 0 0 2", false) == PM3_SUCCESS) && test(DEMOD_BI, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) { @@ -833,6 +859,7 @@ bool tryDetectModulation(void) { tests[hits].inverted = false; tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); tests[hits].ST = false; + tests[hits].downlink_mode = downlink_mode; ++hits; } if ((ASKbiphaseDemod("0 0 1 2", false) == PM3_SUCCESS) && test(DEMOD_BIa, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) { @@ -841,6 +868,7 @@ bool tryDetectModulation(void) { tests[hits].inverted = true; tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); tests[hits].ST = false; + tests[hits].downlink_mode = downlink_mode; ++hits; } } @@ -852,6 +880,7 @@ bool tryDetectModulation(void) { tests[hits].inverted = false; tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); tests[hits].ST = false; + tests[hits].downlink_mode = downlink_mode; ++hits; } @@ -861,6 +890,7 @@ bool tryDetectModulation(void) { tests[hits].inverted = true; tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); tests[hits].ST = false; + tests[hits].downlink_mode = downlink_mode; ++hits; } } @@ -877,6 +907,7 @@ bool tryDetectModulation(void) { tests[hits].inverted = false; tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); tests[hits].ST = false; + tests[hits].downlink_mode = downlink_mode; ++hits; } if ((PSKDemod("0 1 6", false) == PM3_SUCCESS) && test(DEMOD_PSK1, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) { @@ -885,6 +916,7 @@ bool tryDetectModulation(void) { tests[hits].inverted = true; tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); tests[hits].ST = false; + tests[hits].downlink_mode = downlink_mode; ++hits; } //ICEMAN: are these PSKDemod calls needed? @@ -897,6 +929,7 @@ bool tryDetectModulation(void) { tests[hits].inverted = false; tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); tests[hits].ST = false; + tests[hits].downlink_mode = downlink_mode; ++hits; } } // inverse waves does not affect this demod @@ -909,6 +942,7 @@ bool tryDetectModulation(void) { tests[hits].inverted = false; tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); tests[hits].ST = false; + tests[hits].downlink_mode = downlink_mode; ++hits; } } // inverse waves does not affect this demod @@ -924,7 +958,8 @@ bool tryDetectModulation(void) { config.block0 = tests[0].block0; config.Q5 = tests[0].Q5; config.ST = tests[0].ST; - printConfiguration(config); + config.downlink_mode = downlink_mode; + if (print_config) printConfiguration(config); return true; } @@ -942,10 +977,11 @@ bool tryDetectModulation(void) { config.block0 = tests[i].block0; config.Q5 = tests[i].Q5; config.ST = tests[i].ST; + config.downlink_mode = tests[i].downlink_mode; } else { PrintAndLogEx(NORMAL, "--[%d]---------------", i + 1); } - printConfiguration(tests[i]); + if (print_config) printConfiguration(tests[i]); } } return retval; @@ -1205,6 +1241,7 @@ int printConfiguration(t55xx_conf_block_t b) { PrintAndLogEx(NORMAL, " Offset : %d", b.offset); PrintAndLogEx(NORMAL, " Seq. Term. : %s", (b.ST) ? _GREEN_("Yes") : "No"); PrintAndLogEx(NORMAL, " Block0 : 0x%08X", b.block0); + PrintAndLogEx(NORMAL, " DL Mode : %s",GetDownlinkModeStr (b.downlink_mode)); PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } @@ -1214,7 +1251,7 @@ static int CmdT55xxWakeUp(const char *Cmd) { uint32_t password = 0; uint8_t cmdp = 0; bool errors = false; - uint8_t downlink_mode = 0; + uint8_t downlink_mode = config.downlink_mode;; while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { @@ -1228,7 +1265,6 @@ static int CmdT55xxWakeUp(const char *Cmd) { downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); if (downlink_mode > 3) downlink_mode = 0; - cmdp += 2; break; default: @@ -1270,7 +1306,7 @@ static int CmdT55xxWriteBlock(const char *Cmd) { bool errors = false; bool validate = false; uint8_t cmdp = 0; - uint32_t downlink_mode = 0; + uint32_t downlink_mode = config.downlink_mode;; while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { @@ -1372,9 +1408,10 @@ static int CmdT55xxWriteBlock(const char *Cmd) { static int CmdT55xxReadTrace(const char *Cmd) { bool frombuff = false; - uint8_t downlink_mode = 0; + uint8_t downlink_mode = config.downlink_mode;; uint8_t cmdp = 0; bool errors = false; + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { case 'h': @@ -1651,7 +1688,7 @@ static int CmdT55xxInfo(const char *Cmd) { */ bool frombuff = false, gotdata = false, dataasq5 = false, usepwd = false; uint8_t cmdp = 0; - uint8_t downlink_mode = 0; + uint8_t downlink_mode = config.downlink_mode; uint32_t block0 = 0, password = 0; while (param_getchar(Cmd, cmdp) != 0x00) { @@ -1797,7 +1834,7 @@ static int CmdT55xxDump(const char *Cmd) { uint32_t password = 0; uint8_t override = 0; - uint8_t downlink_mode = 0; + uint8_t downlink_mode = config.downlink_mode;; bool usepwd = false; bool errors = false; uint8_t cmdp = 0; @@ -2003,6 +2040,31 @@ char *GetModulationStr(uint32_t id, bool xmode) { return buf; } +char *GetDownlinkModeStr (uint8_t downlink_mode) +{ + static char buf[30]; + char *retStr = buf; + + switch (downlink_mode) { + case T55XX_DLMODE_FIXED : + snprintf (retStr,sizeof(buf),"default/fixed bit length"); + break; + case T55XX_DLMODE_LLR : + snprintf (retStr,sizeof(buf),"long leading reference"); + break; + case T55XX_DLMODE_LEADING_ZERO : + snprintf (retStr,sizeof(buf),"leading zero reference"); + break; + case T55XX_DLMODE_1OF4 : + snprintf (retStr,sizeof(buf),"1 of 4 coding reference"); + break; + default: + snprintf(retStr, sizeof(buf), _RED_("(Unknown)")); + break; + } + return buf; +} + char *GetQ5ModulationStr(uint32_t id) { static char buf[60]; char *retStr = buf; @@ -2124,7 +2186,7 @@ static void t55x7_create_config_block(int tagtype) { static int CmdResetRead(const char *Cmd) { - uint8_t downlink_mode = 0; + uint8_t downlink_mode = config.downlink_mode;; uint8_t flags = 0; uint8_t cmdp = 0; bool errors = false; @@ -2149,7 +2211,7 @@ static int CmdResetRead(const char *Cmd) { if (errors) return usage_t55xx_resetread(); - PrintAndLogEx(INFO, "DL : %d\n", downlink_mode); + // PrintAndLogEx(INFO, "DL : %d\n", downlink_mode); // no value outside of debug flags = downlink_mode << 3; @@ -2229,6 +2291,14 @@ static int CmdT55xxWipe(const char *Cmd) { memset(writeData, 0x00, sizeof(writeData)); } + + // Check and rest t55xx downlink mode. + if (config.downlink_mode != T55XX_DLMODE_FIXED) { // Detect found a different mode so card must support + snprintf(ptrData, sizeof(writeData), "b 3 1 d 00000000"); + if (CmdT55xxWriteBlock(ptrData) != PM3_SUCCESS) + PrintAndLogEx(WARNING, "Warning: error writing blk 3 page 1 (config)"); + memset(writeData, 0x00, sizeof(writeData)); + } return PM3_SUCCESS; } @@ -2263,7 +2333,7 @@ static int CmdT55xxChkPwds(const char *Cmd) { downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); if (downlink_mode >= 4) { try_all_dl_modes = true; - downlink_mode = 4; + downlink_mode = 0; } cmdp += 2; break; @@ -2320,10 +2390,10 @@ static int CmdT55xxChkPwds(const char *Cmd) { PrintAndLogEx(SUCCESS, "\nFound a candidate [ " _YELLOW_("%08X") " ]. Trying to validate", resp.oldarg[1]); if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, resp.oldarg[1], downlink_mode)) { - found = tryDetectModulation(); + found = tryDetectModulation(downlink_mode,T55XX_PrintConfig); if (found) { PrintAndLogEx(SUCCESS, "Found valid password: [ " _GREEN_("%08X") " ]", resp.oldarg[1]); - T55xx_Print_DownlinkMode(downlink_mode); + // T55xx_Print_DownlinkMode(downlink_mode); } else { PrintAndLogEx(WARNING, "Check pwd failed"); @@ -2373,10 +2443,10 @@ static int CmdT55xxChkPwds(const char *Cmd) { continue; } - found = tryDetectModulation(); + found = tryDetectModulation(dl_mode,T55XX_PrintConfig); if (found) { PrintAndLogEx(SUCCESS, "Found valid password: [ " _GREEN_("%08X") " ]", curr_password); - T55xx_Print_DownlinkMode(dl_mode); + // T55xx_Print_DownlinkMode(dl_mode); dl_mode = 4; // Exit other downlink mode checks c = keycount; // Exit loop } @@ -2492,7 +2562,7 @@ uint8_t tryOnePassword(uint32_t password, uint8_t downlink_mode) { // if (getSignalProperties()->isnoise == false) { // } else { - if (tryDetectModulation()) { + if (tryDetectModulation(dl_mode,T55XX_PrintConfig)) { return 1 + (dl_mode << 1); } // } @@ -2670,6 +2740,7 @@ bool tryDetectP1(bool getData) { (DemodBufferLen == 32 || DemodBufferLen == 64)) { return true; } + } // try NRZ clock detect. it could be another type even if successful. @@ -2729,8 +2800,9 @@ static int CmdT55xxDetectPage1(const char *Cmd) { bool errors = false; bool useGB = false; bool usepwd = false; - bool try_all_dl_modes = false; - uint8_t found = 0; + bool try_all_dl_modes = true; + bool found = false; + uint8_t found_mode = 0; uint32_t password = 0; uint8_t cmdp = 0; uint8_t downlink_mode = 0; @@ -2754,7 +2826,8 @@ static int CmdT55xxDetectPage1(const char *Cmd) { downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); if (downlink_mode == 4) try_all_dl_modes = true; - + if (downlink_mode < 4) + try_all_dl_modes = false; if (downlink_mode > 3) downlink_mode = 0; @@ -2773,24 +2846,24 @@ static int CmdT55xxDetectPage1(const char *Cmd) { found = AquireData(T55x7_PAGE1, T55x7_TRACE_BLOCK1, usepwd, password, dl_mode); //return PM3_ENODATA; if (tryDetectP1(false)) { //tryDetectModulation()) - found = dl_mode; + found = true; + found_mode = dl_mode; dl_mode = 4; } else found = false; if (!try_all_dl_modes) dl_mode = 4; } + } else { + found = tryDetectP1(false); } - - if (useGB) found = tryDetectP1(false); - + if (found) { PrintAndLogEx(SUCCESS, "T55xx chip found!"); - T55xx_Print_DownlinkMode(found); + T55xx_Print_DownlinkMode(found_mode); } else PrintAndLogEx(WARNING, "Could not detect modulation automatically. Try setting it manually with " _YELLOW_("\'lf t55xx config\'")); - return PM3_SUCCESS; } diff --git a/client/cmdlft55xx.h b/client/cmdlft55xx.h index 3764a529c..b2af0f5b4 100644 --- a/client/cmdlft55xx.h +++ b/client/cmdlft55xx.h @@ -117,6 +117,12 @@ typedef struct { bool Q5; bool ST; bool usepwd; + enum { + refFixedBit = 0x00, + refLongLeading = 0x01, + refLeading0 = 0x02, + ref1of4 = 0x03, + } downlink_mode; } t55xx_conf_block_t; t55xx_conf_block_t Get_t55xx_Config(void); @@ -131,6 +137,7 @@ char *GetQ5ModulationStr(uint32_t id); char *GetModulationStr(uint32_t id, bool xmode); char *GetModelStrFromCID(uint32_t cid); char *GetSelectedModulationStr(uint8_t id); +char *GetDownlinkModeStr (uint8_t dlmode); void printT5xxHeader(uint8_t page); void printT55xxBlock(uint8_t blockNum); int printConfiguration(t55xx_conf_block_t b); @@ -138,7 +145,7 @@ int printConfiguration(t55xx_conf_block_t b); int T55xxReadBlock(uint8_t block, bool page1, bool usepwd, uint8_t override, uint32_t password, uint8_t downlink_mode); bool GetT55xxBlockData(uint32_t *blockdata); bool DecodeT55xxBlock(void); -bool tryDetectModulation(void); +bool tryDetectModulation(uint8_t downlink_mode, bool print_config); bool testKnownConfigBlock(uint32_t block0); bool tryDetectP1(bool getData); diff --git a/client/scripting.c b/client/scripting.c index 6e35f809f..8d09013e2 100644 --- a/client/scripting.c +++ b/client/scripting.c @@ -930,7 +930,7 @@ static int l_T55xx_readblock(lua_State *L) { return returnToLuaWithError(L, "Failed to read config block"); } - if (!tryDetectModulation()) { + if (!tryDetectModulation(0,true)) { // Default to prev. behaviour (default dl mode and print config) PrintAndLogEx(NORMAL, "Safety Check: Could not detect if PWD bit is set in config block. Exits."); return 0; } else { @@ -1006,7 +1006,7 @@ static int l_T55xx_detect(lua_State *L) { } } - isok = tryDetectModulation(); + isok = tryDetectModulation(0,true); // Default to prev. behaviour (default dl mode and print config) if (isok == false) { return returnToLuaWithError(L, "Could not detect modulation automatically. Try setting it manually with \'lf t55xx config\'"); } From a1852eaa4b118e037134ba382c9b524e51586fec Mon Sep 17 00:00:00 2001 From: Ludovic Rousseau Date: Sat, 14 Sep 2019 17:44:58 +0200 Subject: [PATCH 0698/1854] Fix typos Thanks to Debian lintian for the reports: I: proxmark3: spelling-error-in-binary usr/bin/proxmark3 formated formatted I: proxmark3: spelling-error-in-binary usr/bin/proxmark3 succesfully successfully I: proxmark3: spelling-error-in-binary usr/bin/proxmark3 Skiped Skipped I: proxmark3: spelling-error-in-binary usr/bin/proxmark3 standart standard I: proxmark3: spelling-error-in-binary usr/bin/proxmark3 supress suppress I: proxmark3: spelling-error-in-binary usr/bin/proxmark3 successfull successful I: proxmark3: spelling-error-in-binary usr/bin/proxmark3 Succeded Succeeded I: proxmark3: spelling-error-in-binary usr/bin/proxmark3 Overriden Overridden I: proxmark3: spelling-error-in-binary usr/bin/proxmark3 aquire acquire I: proxmark3: spelling-error-in-binary usr/bin/proxmark3 occured occurred I: proxmark3: spelling-error-in-binary usr/bin/proxmark3 delimeter delimiter --- armsrc/Standalone/hf_young.c | 2 +- armsrc/epa.c | 6 +++--- armsrc/hitag2.c | 4 ++-- armsrc/hitagS.c | 6 +++--- armsrc/mifarecmd.c | 8 ++++---- armsrc/spiffs.c | 4 ++-- client/cmdanalyse.c | 2 +- client/cmdhfepa.c | 2 +- client/cmdhfmf.c | 8 ++++---- client/cmdlft55xx.c | 4 ++-- client/emv/apduinfo.c | 4 ++-- client/emv/cmdemv.c | 4 ++-- client/emv/emvcore.c | 2 +- client/emv/emvcore.h | 2 +- client/fido/cbortools.c | 16 ++++++++-------- client/fido/cbortools.h | 4 ++-- client/lualibs/commands.lua | 4 ++-- client/lualibs/hf_reader.lua | 4 ++-- client/lualibs/read14a.lua | 8 ++++---- client/lualibs/read14b.lua | 8 ++++---- client/lualibs/read15.lua | 8 ++++---- client/lualibs/utils.lua | 2 +- client/luascripts/mifare_autopwn.lua | 4 ++-- client/luascripts/ndef_dump.lua | 4 ++-- client/scripting.c | 6 +++--- common/mbedtls/error.c | 2 +- common/mbedtls/x509.h | 6 +++--- include/at91sam7s512.h | 4 ++-- tools/deprecated-hid-flasher/flasher/proxusb.c | 6 +++--- tools/deprecated-hid-flasher/flasher/proxusb.h | 2 +- 30 files changed, 73 insertions(+), 73 deletions(-) diff --git a/armsrc/Standalone/hf_young.c b/armsrc/Standalone/hf_young.c index d5c211e79..f137e9992 100644 --- a/armsrc/Standalone/hf_young.c +++ b/armsrc/Standalone/hf_young.c @@ -195,7 +195,7 @@ void RunMod() { MifareCGetBlock(params, 0, testBlock0); if (memcmp(testBlock0, newBlock0, 16) == 0) { - DbpString("Cloned successfull!"); + DbpString("Cloned successful!"); cardRead[selected] = 0; // Only if the card was cloned successfully should we clear it playing = 0; iGotoRecord = 1; diff --git a/armsrc/epa.c b/armsrc/epa.c index c43b35c98..f535b89a3 100644 --- a/armsrc/epa.c +++ b/armsrc/epa.c @@ -139,8 +139,8 @@ void EPA_Finish() { //----------------------------------------------------------------------------- // Parses DER encoded data, e.g. from EF.CardAccess and fills out the given // structs. If a pointer is 0, it is ignored. -// The function returns 0 on success and if an error occured, it returns the -// offset where it occured. +// The function returns 0 on success and if an error occurred, it returns the +// offset where it occurred. // // TODO: This function can access memory outside of the given data if the DER // encoding is broken @@ -274,7 +274,7 @@ void EPA_PACE_Collect_Nonce(PacketCommandNG *c) { * ack layout: * arg: * 1. element - * step where the error occured or 0 if no error occured + * step where the error occurred or 0 if no error occurred * 2. element * return code of the last executed function * d: diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index c1fc7d8d4..ab3f7cb36 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -1277,7 +1277,7 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { // Wait for HITAG_T_WAIT_2 carrier periods after the last tag bit before transmitting, // Since the clock counts since the last falling edge, a 'one' means that the - // falling edge occured halfway the period. with respect to this falling edge, + // falling edge occurred halfway the period. with respect to this falling edge, // we need to wait (T_Wait2 + half_tag_period) when the last was a 'one'. // All timer values are in terms of T0 units while (AT91C_BASE_TC0->TC_CV < T0 * (t_wait + (HITAG_T_TAG_HALF_PERIOD * lastbit))); @@ -1533,7 +1533,7 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) { // Wait for HITAG_T_WAIT_2 carrier periods after the last tag bit before transmitting, // Since the clock counts since the last falling edge, a 'one' means that the - // falling edge occured halfway the period. with respect to this falling edge, + // falling edge occurred halfway the period. with respect to this falling edge, // we need to wait (T_Wait2 + half_tag_period) when the last was a 'one'. // All timer values are in terms of T0 units while (AT91C_BASE_TC0->TC_CV < T0 * (t_wait + (HITAG_T_TAG_HALF_PERIOD * lastbit))) {}; diff --git a/armsrc/hitagS.c b/armsrc/hitagS.c index 98c3844e2..a9481f3b6 100644 --- a/armsrc/hitagS.c +++ b/armsrc/hitagS.c @@ -1354,7 +1354,7 @@ void ReadHitagS(hitag_function htf, hitag_data *htd) { // Wait for HITAG_T_WAIT_2 carrier periods after the last tag bit before transmitting, // Since the clock counts since the last falling edge, a 'one' means that the - // falling edge occured halfway the period. with respect to this falling edge, + // falling edge occurred halfway the period. with respect to this falling edge, // we need to wait (T_Wait2 + half_tag_period) when the last was a 'one'. // All timer values are in terms of T0 units @@ -1643,7 +1643,7 @@ void WritePageHitagS(hitag_function htf, hitag_data *htd, int page) { // Wait for HITAG_T_WAIT_2 carrier periods after the last tag bit before transmitting, // Since the clock counts since the last falling edge, a 'one' means that the - // falling edge occured halfway the period. with respect to this falling edge, + // falling edge occurred halfway the period. with respect to this falling edge, // we need to wait (T_Wait2 + half_tag_period) when the last was a 'one'. // All timer values are in terms of T0 units @@ -1952,7 +1952,7 @@ void check_challenges(bool file_given, uint8_t *data) { // Wait for HITAG_T_WAIT_2 carrier periods after the last tag bit before transmitting, // Since the clock counts since the last falling edge, a 'one' means that the - // falling edge occured halfway the period. with respect to this falling edge, + // falling edge occurred halfway the period. with respect to this falling edge, // we need to wait (T_Wait2 + half_tag_period) when the last was a 'one'. // All timer values are in terms of T0 units diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 1ca809a8a..4fccdab8b 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -913,7 +913,7 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain) LED_B_ON(); WDT_HIT(); - uint16_t unsuccessfull_tries = 0; + uint16_t unsuccessful_tries = 0; uint16_t davg = 0; dmax = 0; dmin = 2000; @@ -970,8 +970,8 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain) } if (DBGLEVEL >= 3) Dbprintf("Nested: calibrating... ntdist=%d", i); } else { - unsuccessfull_tries++; - if (unsuccessfull_tries > NESTED_MAX_TRIES) { // card isn't vulnerable to nested attack (random numbers are not predictable) + unsuccessful_tries++; + if (unsuccessful_tries > NESTED_MAX_TRIES) { // card isn't vulnerable to nested attack (random numbers are not predictable) isOK = -3; } } @@ -1118,7 +1118,7 @@ uint8_t chkKey(struct chk_t *c) { CHK_TIMEOUT(); - // if successfull auth, send HALT + // if successful auth, send HALT // if ( !res ) // mifare_classic_halt_ex(c->pcs); break; diff --git a/armsrc/spiffs.c b/armsrc/spiffs.c index 0296b7620..629dff422 100644 --- a/armsrc/spiffs.c +++ b/armsrc/spiffs.c @@ -302,7 +302,7 @@ int rdv40_spiffs_lazy_mount() { if (!rdv40_spiffs_mounted()) { changed = rdv40_spiffs_mount(); /* if changed = 0 = SPIFFS_OK then all went well then the change - * actually occured :)*/ + * actually occurred :)*/ changed = !changed; } return changed; @@ -371,7 +371,7 @@ just get back to this state. If not, just don't. [...] } */ -// Again : This will "toggle" spiffs mount status only if a "change" occured +// Again : This will "toggle" spiffs mount status only if a "change" occurred // (and should be fed by the result of a spiffs_lazy* function) If everything // went well, it will return SPIFFS_OK if everything went well, and a report // back the chain a SPI_ERRNO if not. diff --git a/client/cmdanalyse.c b/client/cmdanalyse.c index 2e88f6e5b..2e53af224 100644 --- a/client/cmdanalyse.c +++ b/client/cmdanalyse.c @@ -45,7 +45,7 @@ static int usage_analyse_checksum(void) { PrintAndLogEx(NORMAL, "Usage: analyse chksum [h] [v] b m "); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h This help"); - PrintAndLogEx(NORMAL, " v supress header"); + PrintAndLogEx(NORMAL, " v suppress header"); PrintAndLogEx(NORMAL, " b bytes to calc missing XOR in a LCR"); PrintAndLogEx(NORMAL, " m bit mask to limit the outpuyt"); PrintAndLogEx(NORMAL, ""); diff --git a/client/cmdhfepa.c b/client/cmdhfepa.c index b6329bef9..2a7ff5928 100644 --- a/client/cmdhfepa.c +++ b/client/cmdhfepa.c @@ -164,7 +164,7 @@ static int CmdHFEPAPACEReplay(const char *Cmd) { PrintAndLogEx(NORMAL, "GA Perform Key Agreement: %u us", resp.data.asDwords[3]); PrintAndLogEx(NORMAL, "GA Mutual Authenticate: %u us", resp.data.asDwords[4]); } else { - PrintAndLogEx(NORMAL, "PACE replay successfull!"); + PrintAndLogEx(NORMAL, "PACE replay successful!"); PrintAndLogEx(NORMAL, "MSE Set AT: %u us", resp.data.asDwords[0]); PrintAndLogEx(NORMAL, "GA Get Nonce: %u us", resp.data.asDwords[1]); PrintAndLogEx(NORMAL, "GA Map Nonce: %u us", resp.data.asDwords[2]); diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index edd916330..744532a13 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -1006,7 +1006,7 @@ static int CmdHF14AMfDump(const char *Cmd) { PrintAndLogEx(SUCCESS, "time: %" PRIu64 " seconds\n", (msclock() - t1) / 1000); - PrintAndLogEx(SUCCESS, "\nSucceded in dumping all blocks"); + PrintAndLogEx(SUCCESS, "\nSucceeded in dumping all blocks"); if (strlen(dataFilename) < 1) { fptr = GenerateFilename("hf-mf-", "-data"); @@ -1422,14 +1422,14 @@ jumptoend: } PrintAndLogEx(SUCCESS, "saving keys to binary file " _YELLOW_("%s"), fptr); - uint8_t standart[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + uint8_t standard[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; uint8_t tempkey[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; for (int i = 0; i < SectorsCnt; i++) { if (e_sector[i].foundKey[0]) { num_to_bytes(e_sector[i].Key[0], 6, tempkey); fwrite(tempkey, 1, 6, fkeys); } else { - fwrite(&standart, 1, 6, fkeys); + fwrite(&standard, 1, 6, fkeys); } } for (int i = 0; i < SectorsCnt; i++) { @@ -1437,7 +1437,7 @@ jumptoend: num_to_bytes(e_sector[i].Key[1], 6, tempkey); fwrite(tempkey, 1, 6, fkeys); } else { - fwrite(&standart, 1, 6, fkeys); + fwrite(&standard, 1, 6, fkeys); } } fflush(fkeys); diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index f36e30e48..f6412652f 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -339,7 +339,7 @@ static bool t55xxVerifyWrite( uint8_t block, bool page1, bool usepwd, uint8_t ov usepwd = false; } } else if (override == 1) { - PrintAndLogEx(NORMAL, "Safety Check Overriden - proceeding despite risk"); + PrintAndLogEx(NORMAL, "Safety Check Overridden - proceeding despite risk"); } } @@ -548,7 +548,7 @@ int T55xxReadBlock(uint8_t block, bool page1, bool usepwd, uint8_t override, uin } } else if (override == 1) { // Show only if first for command i.e. override = 1 (override and display) override = 2 (override and dont display) - PrintAndLogEx(NORMAL, "Safety Check Overriden - proceeding despite risk"); + PrintAndLogEx(NORMAL, "Safety Check Overridden - proceeding despite risk"); } } diff --git a/client/emv/apduinfo.c b/client/emv/apduinfo.c index cf43615cb..7c3e87408 100644 --- a/client/emv/apduinfo.c +++ b/client/emv/apduinfo.c @@ -29,7 +29,7 @@ const APDUCode APDUCodeTable[] = { {"6281", APDUCODE_TYPE_WARNING, "Part of returned data may be corrupted"}, {"6282", APDUCODE_TYPE_WARNING, "End of file/record reached before reading Le bytes"}, {"6283", APDUCODE_TYPE_WARNING, "Selected file invalidated"}, - {"6284", APDUCODE_TYPE_WARNING, "Selected file is not valid. FCI not formated according to ISO"}, + {"6284", APDUCODE_TYPE_WARNING, "Selected file is not valid. FCI not formatted according to ISO"}, {"6285", APDUCODE_TYPE_WARNING, "No input data available from a sensor on the card. No Purse Engine enslaved for R3bc"}, {"62A2", APDUCODE_TYPE_WARNING, "Wrong R-MAC"}, {"62A4", APDUCODE_TYPE_WARNING, "Card locked (during reset( ))"}, @@ -143,7 +143,7 @@ const APDUCode APDUCodeTable[] = { {"6FXX", APDUCODE_TYPE_ERROR, "No precise diagnosis (procedure byte), (ISO 7816-3)"}, {"9---", APDUCODE_TYPE_NONE, ""}, {"9000", APDUCODE_TYPE_INFO, "Command successfully executed (OK)."}, - {"9004", APDUCODE_TYPE_WARNING, "PIN not succesfully verified, 3 or more PIN tries left"}, + {"9004", APDUCODE_TYPE_WARNING, "PIN not successfully verified, 3 or more PIN tries left"}, {"9008", APDUCODE_TYPE_NONE, "Key/file not found"}, {"9080", APDUCODE_TYPE_WARNING, "Unblock Try Counter has reached zero"}, {"9100", APDUCODE_TYPE_NONE, "OK"}, diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c index 348840cb3..8656e4902 100644 --- a/client/emv/cmdemv.c +++ b/client/emv/cmdemv.c @@ -790,7 +790,7 @@ static int CmdEMVExec(const char *Cmd) { arg_rem("By default:", "Transaction type - MSD"), arg_lit0("vV", "qvsdc", "Transaction type - qVSDC or M/Chip."), arg_lit0("cC", "qvsdccda", "Transaction type - qVSDC or M/Chip plus CDA (SDAD generation)."), - arg_lit0("xX", "vsdc", "Transaction type - VSDC. For test only. Not a standart behavior."), + arg_lit0("xX", "vsdc", "Transaction type - VSDC. For test only. Not a standard behavior."), arg_lit0("gG", "acgpo", "VISA. generate AC from GPO."), arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."), arg_param_end @@ -1380,7 +1380,7 @@ static int CmdEMVScan(const char *Cmd) { arg_rem("By default:", "Transaction type - MSD"), arg_lit0("vV", "qvsdc", "Transaction type - qVSDC or M/Chip."), arg_lit0("cC", "qvsdccda", "Transaction type - qVSDC or M/Chip plus CDA (SDAD generation)."), - arg_lit0("xX", "vsdc", "Transaction type - VSDC. For test only. Not a standart behavior."), + arg_lit0("xX", "vsdc", "Transaction type - VSDC. For test only. Not a standard behavior."), arg_lit0("gG", "acgpo", "VISA. generate AC from GPO."), arg_lit0("mM", "merge", "Merge output file with card's data. (warning: the file may be corrupted!)"), arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."), diff --git a/client/emv/emvcore.c b/client/emv/emvcore.c index 09dc7883e..d2053495e 100644 --- a/client/emv/emvcore.c +++ b/client/emv/emvcore.c @@ -394,7 +394,7 @@ static int EMVSelectWithRetry(EMVCommandChannel channel, bool ActivateField, boo } retrycnt = 0; - PrintAndLogEx(NORMAL, "Retry failed [%s]. Skiped...", sprint_hex_inrow(AID, AIDLen)); + PrintAndLogEx(NORMAL, "Retry failed [%s]. Skipped...", sprint_hex_inrow(AID, AIDLen)); return res; } } diff --git a/client/emv/emvcore.h b/client/emv/emvcore.h index a520a2d5f..d5dccd037 100644 --- a/client/emv/emvcore.h +++ b/client/emv/emvcore.h @@ -29,7 +29,7 @@ typedef enum { enum TransactionType { TT_MSD, - TT_VSDC, // contact only. not standart for contactless + TT_VSDC, // contact only. not standard for contactless TT_QVSDCMCHIP, TT_CDA, }; diff --git a/client/fido/cbortools.c b/client/fido/cbortools.c index 72cccf429..b0d309db7 100644 --- a/client/fido/cbortools.c +++ b/client/fido/cbortools.c @@ -357,7 +357,7 @@ CborError CborGetArrayBinStringValue(CborValue *elm, uint8_t *data, size_t maxda return CborGetArrayBinStringValueEx(elm, data, maxdatalen, datalen, NULL, 0); } -CborError CborGetArrayBinStringValueEx(CborValue *elm, uint8_t *data, size_t maxdatalen, size_t *datalen, uint8_t *delimeter, size_t delimeterlen) { +CborError CborGetArrayBinStringValueEx(CborValue *elm, uint8_t *data, size_t maxdatalen, size_t *datalen, uint8_t *delimiter, size_t delimiterlen) { CborValue array; if (datalen) *datalen = 0; @@ -373,9 +373,9 @@ CborError CborGetArrayBinStringValueEx(CborValue *elm, uint8_t *data, size_t max cbor_check(res); totallen += slen; - if (delimeter) { - memcpy(&data[totallen], delimeter, delimeterlen); - totallen += delimeterlen; + if (delimiter) { + memcpy(&data[totallen], delimiter, delimiterlen); + totallen += delimiterlen; } slen = maxdatalen - totallen; } @@ -404,7 +404,7 @@ CborError CborGetBinStringValue(CborValue *elm, uint8_t *data, size_t maxdatalen return CborNoError; }; -CborError CborGetArrayStringValue(CborValue *elm, char *data, size_t maxdatalen, size_t *datalen, char *delimeter) { +CborError CborGetArrayStringValue(CborValue *elm, char *data, size_t maxdatalen, size_t *datalen, char *delimiter) { CborValue array; if (datalen) *datalen = 0; @@ -420,9 +420,9 @@ CborError CborGetArrayStringValue(CborValue *elm, char *data, size_t maxdatalen, cbor_check(res); totallen += slen; - if (delimeter) { - strcat(data, delimeter); - totallen += strlen(delimeter); + if (delimiter) { + strcat(data, delimiter); + totallen += strlen(delimiter); } slen = maxdatalen - totallen; data[totallen] = 0x00; diff --git a/client/fido/cbortools.h b/client/fido/cbortools.h index 96c39ca3b..86f8387cd 100644 --- a/client/fido/cbortools.h +++ b/client/fido/cbortools.h @@ -25,9 +25,9 @@ int JsonToCbor(json_t *elm, CborEncoder *encoder); int CborMapGetKeyById(CborParser *parser, CborValue *map, uint8_t *data, size_t dataLen, int key); CborError CborGetArrayBinStringValue(CborValue *elm, uint8_t *data, size_t maxdatalen, size_t *datalen); -CborError CborGetArrayBinStringValueEx(CborValue *elm, uint8_t *data, size_t maxdatalen, size_t *datalen, uint8_t *delimeter, size_t delimeterlen); +CborError CborGetArrayBinStringValueEx(CborValue *elm, uint8_t *data, size_t maxdatalen, size_t *datalen, uint8_t *delimiter, size_t delimiterlen); CborError CborGetBinStringValue(CborValue *elm, uint8_t *data, size_t maxdatalen, size_t *datalen); -CborError CborGetArrayStringValue(CborValue *elm, char *data, size_t maxdatalen, size_t *datalen, char *delimeter); +CborError CborGetArrayStringValue(CborValue *elm, char *data, size_t maxdatalen, size_t *datalen, char *delimiter); CborError CborGetStringValue(CborValue *elm, char *data, size_t maxdatalen, size_t *datalen); CborError CborGetStringValueBuf(CborValue *elm); diff --git a/client/lualibs/commands.lua b/client/lualibs/commands.lua index d9d358736..11227b8ac 100644 --- a/client/lualibs/commands.lua +++ b/client/lualibs/commands.lua @@ -122,8 +122,8 @@ end -- @param ignoreresponse - if set to true, we don't read the device answer packet -- which is usually recipe for fail. If not sent, the host will wait 2s for a -- response of type CMD_ACK --- @return packet,nil if successfull --- nil, errormessage if unsuccessfull +-- @return packet,nil if successful +-- nil, errormessage if unsuccessful function Command:sendMIX( ignore_response, timeout ) local data = self.data local cmd = self.cmd diff --git a/client/lualibs/hf_reader.lua b/client/lualibs/hf_reader.lua index ba7e3a17c..f49d587f2 100644 --- a/client/lualibs/hf_reader.lua +++ b/client/lualibs/hf_reader.lua @@ -12,8 +12,8 @@ local reader15693 = require('read15') -- This method library can be set waits or a 13.56 MHz tag, and when one is found, returns info about -- what tag it is. -- --- @return if successfull: an table containing card info --- @return if unsuccessfull : nil, error +-- @return if successful: an table containing card info +-- @return if unsuccessful : nil, error local function waitForTag() print("Waiting for card... press Enter to quit") local readers = {reader14443A, reader14443B, reader15693} diff --git a/client/lualibs/read14a.lua b/client/lualibs/read14a.lua index 3f0d71dde..59de3c11f 100644 --- a/client/lualibs/read14a.lua +++ b/client/lualibs/read14a.lua @@ -80,8 +80,8 @@ end -- This function does a connect and retrieves som einfo -- @param dont_disconnect - if true, does not disable the field --- @return if successfull: an table containing card info --- @return if unsuccessfull : nil, error +-- @return if successful: an table containing card info +-- @return if unsuccessful : nil, error local function read14443a(dont_disconnect, no_rats) local command, result, info, err, data @@ -118,8 +118,8 @@ end --- -- Waits for a mifare card to be placed within the vicinity of the reader. --- @return if successfull: an table containing card info --- @return if unsuccessfull : nil, error +-- @return if successful: an table containing card info +-- @return if unsuccessful : nil, error local function waitFor14443a() print('Waiting for card... press Enter to quit') while not core.kbd_enter_pressed() do diff --git a/client/lualibs/read14b.lua b/client/lualibs/read14b.lua index aace09827..b1688552f 100644 --- a/client/lualibs/read14b.lua +++ b/client/lualibs/read14b.lua @@ -55,8 +55,8 @@ local function parse14443b(data) end -- This function does a connect and retrieves some info --- @return if successfull: an table containing card info --- @return if unsuccessfull : nil, error +-- @return if successful: an table containing card info +-- @return if unsuccessful : nil, error local function read14443b(disconnect) local command, result, info, err, data @@ -96,8 +96,8 @@ end --- -- Waits for a mifare card to be placed within the vicinity of the reader. --- @return if successfull: an table containing card info --- @return if unsuccessfull : nil, error +-- @return if successful: an table containing card info +-- @return if unsuccessful : nil, error local function waitFor14443b() print('Waiting for card... press Enter to quit') while not core.kbd_enter_pressed() do diff --git a/client/lualibs/read15.lua b/client/lualibs/read15.lua index 112c12d94..5d7400e2d 100644 --- a/client/lualibs/read15.lua +++ b/client/lualibs/read15.lua @@ -64,8 +64,8 @@ end -- This function does a connect and retrieves som info -- @param dont_disconnect - if true, does not disable the field --- @return if successfull: an table containing card info --- @return if unsuccessfull : nil, error +-- @return if successful: an table containing card info +-- @return if unsuccessful : nil, error local function read15693(slow, dont_readresponse) --[[ @@ -130,8 +130,8 @@ end --- -- Waits for a ISO15693 card to be placed within the vicinity of the reader. --- @return if successfull: an table containing card info --- @return if unsuccessfull : nil, error +-- @return if successful: an table containing card info +-- @return if unsuccessful : nil, error local function waitFor15693() print('Waiting for card... press Enter to quit') while not core.kbd_enter_pressed() do diff --git a/client/lualibs/utils.lua b/client/lualibs/utils.lua index ed9874e40..c265a5d8c 100644 --- a/client/lualibs/utils.lua +++ b/client/lualibs/utils.lua @@ -59,7 +59,7 @@ local Utils = -- @param blockData. Assumed to be on the format {'\0\1\2\3,'\b\e\e\f' ..., -- that is, blockData[row] contains a string with the actual data, not ascii hex representation -- return filename if all went well, - -- @reurn nil, error message if unsuccessfulls + -- @reurn nil, error message if unsuccessful WriteDumpFile = function(uid, blockData) local destination = string.format("%s.eml", uid) local file = io.open(destination, "w") diff --git a/client/luascripts/mifare_autopwn.lua b/client/luascripts/mifare_autopwn.lua index 7a04cd641..2c9146e2b 100644 --- a/client/luascripts/mifare_autopwn.lua +++ b/client/luascripts/mifare_autopwn.lua @@ -67,8 +67,8 @@ local function help() end --- -- Waits for a mifare card to be placed within the vicinity of the reader. --- @return if successfull: an table containing card info --- @return if unsuccessfull : nil, error +-- @return if successful: an table containing card info +-- @return if unsuccessful : nil, error local function wait_for_mifare() while not core.kbd_enter_pressed() do res, err = lib14a.read() diff --git a/client/luascripts/ndef_dump.lua b/client/luascripts/ndef_dump.lua index cb4be467b..a4cbdf655 100644 --- a/client/luascripts/ndef_dump.lua +++ b/client/luascripts/ndef_dump.lua @@ -90,8 +90,8 @@ local function getblockdata(response) return nil, "Couldn't read block" end ---_ Gets data from a block --- @return {block, block+1, block+2, block+3} if successfull --- @return nil, errormessage if unsuccessfull +-- @return {block, block+1, block+2, block+3} if successful +-- @return nil, errormessage if unsuccessful local function getBlock(blockno) local block, err local c = Command:newMIX{cmd = cmds.CMD_HF_MIFAREU_READBL, arg1 = blockno, data = 0} diff --git a/client/scripting.c b/client/scripting.c index 8d09013e2..586ab0940 100644 --- a/client/scripting.c +++ b/client/scripting.c @@ -939,12 +939,12 @@ static int l_T55xx_readblock(lua_State *L) { usepage1 = false; } } else { - PrintAndLogEx(NORMAL, "Safety Check Overriden - proceeding despite risk"); + PrintAndLogEx(NORMAL, "Safety Check Overridden - proceeding despite risk"); } } if (!AquireData(usepage1, block, usepwd, password, 0)) { - return returnToLuaWithError(L, "Failed to aquire data from card"); + return returnToLuaWithError(L, "Failed to acquire data from card"); } if (!DecodeT55xxBlock()) { @@ -1002,7 +1002,7 @@ static int l_T55xx_detect(lua_State *L) { isok = AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, 0); if (isok == false) { - return returnToLuaWithError(L, "Failed to aquire LF signal data"); + return returnToLuaWithError(L, "Failed to acquire LF signal data"); } } diff --git a/common/mbedtls/error.c b/common/mbedtls/error.c index 8b8a27bb6..b85ceb041 100644 --- a/common/mbedtls/error.c +++ b/common/mbedtls/error.c @@ -558,7 +558,7 @@ void mbedtls_strerror(int ret, char *buf, size_t buflen) { if (use_ret == -(MBEDTLS_ERR_X509_BUFFER_TOO_SMALL)) mbedtls_snprintf(buf, buflen, "X509 - Destination buffer is too small"); if (use_ret == -(MBEDTLS_ERR_X509_FATAL_ERROR)) - mbedtls_snprintf(buf, buflen, "X509 - A fatal error occured, eg the chain is too long or the vrfy callback failed"); + mbedtls_snprintf(buf, buflen, "X509 - A fatal error occurred, eg the chain is too long or the vrfy callback failed"); #endif /* MBEDTLS_X509_USE_C || MBEDTLS_X509_CREATE_C */ // END generated code diff --git a/common/mbedtls/x509.h b/common/mbedtls/x509.h index 01ec3df70..676cf824a 100644 --- a/common/mbedtls/x509.h +++ b/common/mbedtls/x509.h @@ -79,7 +79,7 @@ #define MBEDTLS_ERR_X509_ALLOC_FAILED -0x2880 /**< Allocation of memory failed. */ #define MBEDTLS_ERR_X509_FILE_IO_ERROR -0x2900 /**< Read/write of file failed. */ #define MBEDTLS_ERR_X509_BUFFER_TOO_SMALL -0x2980 /**< Destination buffer is too small. */ -#define MBEDTLS_ERR_X509_FATAL_ERROR -0x3000 /**< A fatal error occured, eg the chain is too long or the vrfy callback failed. */ +#define MBEDTLS_ERR_X509_FATAL_ERROR -0x3000 /**< A fatal error occurred, eg the chain is too long or the vrfy callback failed. */ /* \} name */ /** @@ -251,7 +251,7 @@ int mbedtls_x509_serial_gets(char *buf, size_t size, const mbedtls_x509_buf *ser * * \param to mbedtls_x509_time to check * - * \return 1 if the given time is in the past or an error occured, + * \return 1 if the given time is in the past or an error occurred, * 0 otherwise. */ int mbedtls_x509_time_is_past(const mbedtls_x509_time *to); @@ -265,7 +265,7 @@ int mbedtls_x509_time_is_past(const mbedtls_x509_time *to); * * \param from mbedtls_x509_time to check * - * \return 1 if the given time is in the future or an error occured, + * \return 1 if the given time is in the future or an error occurred, * 0 otherwise. */ int mbedtls_x509_time_is_future(const mbedtls_x509_time *from); diff --git a/include/at91sam7s512.h b/include/at91sam7s512.h index bca65bdf3..b43f0dbb1 100644 --- a/include/at91sam7s512.h +++ b/include/at91sam7s512.h @@ -598,10 +598,10 @@ typedef struct _AT91S_RSTC { #define AT91C_RSTC_RSTTYP (0x7 << 8) // (RSTC) Reset Type #define AT91C_RSTC_RSTTYP_POWERUP (0x0 << 8) // (RSTC) Power-up Reset. VDDCORE rising. #define AT91C_RSTC_RSTTYP_WAKEUP (0x1 << 8) // (RSTC) WakeUp Reset. VDDCORE rising. -#define AT91C_RSTC_RSTTYP_WATCHDOG (0x2 << 8) // (RSTC) Watchdog Reset. Watchdog overflow occured. +#define AT91C_RSTC_RSTTYP_WATCHDOG (0x2 << 8) // (RSTC) Watchdog Reset. Watchdog overflow occurred. #define AT91C_RSTC_RSTTYP_SOFTWARE (0x3 << 8) // (RSTC) Software Reset. Processor reset required by the software. #define AT91C_RSTC_RSTTYP_USER (0x4 << 8) // (RSTC) User Reset. NRST pin detected low. -#define AT91C_RSTC_RSTTYP_BROWNOUT (0x5 << 8) // (RSTC) Brownout Reset occured. +#define AT91C_RSTC_RSTTYP_BROWNOUT (0x5 << 8) // (RSTC) Brownout Reset occurred. #define AT91C_RSTC_NRSTL (0x1 << 16) // (RSTC) NRST pin level #define AT91C_RSTC_SRCMP (0x1 << 17) // (RSTC) Software Reset Command in Progress. // -------- RSTC_RMR : (RSTC Offset: 0x8) Reset Mode Register -------- diff --git a/tools/deprecated-hid-flasher/flasher/proxusb.c b/tools/deprecated-hid-flasher/flasher/proxusb.c index 1edf7e094..884950297 100644 --- a/tools/deprecated-hid-flasher/flasher/proxusb.c +++ b/tools/deprecated-hid-flasher/flasher/proxusb.c @@ -19,7 +19,7 @@ usb_dev_handle *devh = NULL; static unsigned int claimed_iface = 0; unsigned char return_on_error = 0; -unsigned char error_occured = 0; +unsigned char error_occurred = 0; void SendCommandBL(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len) { int ret; @@ -37,7 +37,7 @@ void SendCommandBL(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, vo ret = usb_bulk_write(devh, 0x01, (char *)&c, sizeof(PacketCommandOLD), 1000); if (ret < 0) { - error_occured = 1; + error_occurred = 1; if (return_on_error) return; @@ -63,7 +63,7 @@ bool ReceiveCommandPoll(PacketResponseOLD *c) { ret = usb_bulk_read(devh, 0x82, (char *)c, sizeof(PacketResponseOLD), 500); if (ret < 0) { if (ret != -ETIMEDOUT) { - error_occured = 1; + error_occurred = 1; if (return_on_error) return false; diff --git a/tools/deprecated-hid-flasher/flasher/proxusb.h b/tools/deprecated-hid-flasher/flasher/proxusb.h index 125347255..205d670a1 100644 --- a/tools/deprecated-hid-flasher/flasher/proxusb.h +++ b/tools/deprecated-hid-flasher/flasher/proxusb.h @@ -24,7 +24,7 @@ #include "usb_cmd.h" extern unsigned char return_on_error; -extern unsigned char error_occured; +extern unsigned char error_occurred; void SendCommandBL(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len); bool ReceiveCommandPoll(PacketResponseOLD *c); From f961c1c551e5740c545d8b5ce7e7670aeacf0214 Mon Sep 17 00:00:00 2001 From: Ludovic Rousseau Date: Sat, 14 Sep 2019 17:50:58 +0200 Subject: [PATCH 0699/1854] Fix typos Thanks to Debian lintian for the reports: I: proxmark3: spelling-error-in-binary usr/share/proxmark3/firmware/fullimage.elf dont don't I: proxmark3: spelling-error-in-binary usr/share/proxmark3/firmware/fullimage.elf succesful successful I: proxmark3: spelling-error-in-binary usr/share/proxmark3/firmware/fullimage.elf Uknown Unknown I: proxmark3: spelling-error-in-binary usr/share/proxmark3/firmware/fullimage.elf requestes requests I: proxmark3: spelling-error-in-binary usr/share/proxmark3/firmware/fullimage.elf unkown unknown I: proxmark3: spelling-error-in-binary usr/share/proxmark3/firmware/fullimage.elf ambigous ambiguous --- armsrc/hitag2.c | 16 ++++++++-------- armsrc/iso14443a.c | 4 ++-- armsrc/iso15693.c | 2 +- armsrc/mifarecmd.c | 2 +- client/cmdlfhitag.c | 2 +- client/cmdlft55xx.c | 2 +- client/emv/apduinfo.c | 10 +++++----- common/mbedtls/ecp.h | 2 +- 8 files changed, 20 insertions(+), 20 deletions(-) diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index ab3f7cb36..67bc8c623 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -427,7 +427,7 @@ static bool hitag2_password(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t } if (blocknr > 7) { - DbpString("Read succesful!"); + DbpString("Read successful!"); bSuccessful = true; return false; } @@ -440,7 +440,7 @@ static bool hitag2_password(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t // Unexpected response default: { - Dbprintf("Uknown frame length: %d", rxlen); + Dbprintf("Unknown frame length: %d", rxlen); return false; } break; @@ -532,7 +532,7 @@ static bool hitag2_crypto(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t * blocknr++; } if (blocknr > 7) { - DbpString("Read succesful!"); + DbpString("Read successful!"); bSuccessful = true; return false; } else { @@ -546,7 +546,7 @@ static bool hitag2_crypto(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t * // Unexpected response default: { - Dbprintf("Uknown frame length: %d", rxlen); + Dbprintf("Unknown frame length: %d", rxlen); return false; } break; @@ -588,7 +588,7 @@ static bool hitag2_authenticate(uint8_t *rx, const size_t rxlen, uint8_t *tx, si memcpy(tx, NrAr, 8); bCrypto = true; } else { - DbpString("Authentication succesful!"); + DbpString("Authentication successful!"); return true; } } @@ -596,7 +596,7 @@ static bool hitag2_authenticate(uint8_t *rx, const size_t rxlen, uint8_t *tx, si // Unexpected response default: { - Dbprintf("Uknown frame length: %d", rxlen); + Dbprintf("Unknown frame length: %d", rxlen); return false; } break; @@ -655,7 +655,7 @@ static bool hitag2_test_auth_attempts(uint8_t *rx, const size_t rxlen, uint8_t * break; default: { - Dbprintf("Uknown frame length: %d", rxlen); + Dbprintf("Unknown frame length: %d", rxlen); return false; } break; @@ -696,7 +696,7 @@ static bool hitag2_read_uid(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t break; // Unexpected response default: { - Dbprintf("Uknown frame length: %d", rxlen); + Dbprintf("Unknown frame length: %d", rxlen); return false; } break; diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 794ead3c5..c49d93a1f 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -1005,7 +1005,7 @@ static bool SimulateIso14443aInit(int tagType, int flags, uint8_t *data, tag_res } break; default: { - if (DBGLEVEL >= DBG_ERROR) Dbprintf("Error: unkown tagtype (%d)", tagType); + if (DBGLEVEL >= DBG_ERROR) Dbprintf("Error: unknown tagtype (%d)", tagType); return false; } break; @@ -2999,7 +2999,7 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) { mf_nr_ar[3] &= 0x1F; - if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("Number of sent auth requestes: %u", i); + if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("Number of sent auth requests: %u", i); uint8_t buf[32] = {0x00}; memset(buf, 0x00, sizeof(buf)); diff --git a/armsrc/iso15693.c b/armsrc/iso15693.c index 84de71021..ecf0640a5 100644 --- a/armsrc/iso15693.c +++ b/armsrc/iso15693.c @@ -766,7 +766,7 @@ void DbdecodeIso15693Answer(int len, uint8_t *d) { strncat(status, "0F: no info", DBD15STATLEN - strlen(status)); break; case 0x10: - strncat(status, "10: dont exist", DBD15STATLEN - strlen(status)); + strncat(status, "10: don't exist", DBD15STATLEN - strlen(status)); break; case 0x11: strncat(status, "11: lock again", DBD15STATLEN - strlen(status)); diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 4fccdab8b..089a320ad 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -1038,7 +1038,7 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain) if (valid_nonce(nttest, nt2, ks1, par_array)) { if (ncount > 0) { // we are only interested in disambiguous nonces, try again - if (DBGLEVEL >= 3) Dbprintf("Nonce#%d: dismissed (ambigous), ntdist=%d", i + 1, j); + if (DBGLEVEL >= 3) Dbprintf("Nonce#%d: dismissed (ambiguous), ntdist=%d", i + 1, j); target_nt[i] = 0; break; } diff --git a/client/cmdlfhitag.c b/client/cmdlfhitag.c index 2bcd476ea..a54b96a68 100644 --- a/client/cmdlfhitag.c +++ b/client/cmdlfhitag.c @@ -245,7 +245,7 @@ static int CmdLFHitagList(const char *Cmd) { if (f) { fclose(f); - PrintAndLogEx(NORMAL, "Recorded activity succesfully written to file: %s", filename); + PrintAndLogEx(NORMAL, "Recorded activity successfully written to file: %s", filename); } free(got); diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index f6412652f..fbdd4c083 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -1397,7 +1397,7 @@ static int CmdT55xxWriteBlock(const char *Cmd) { //t55xxVerifyWrite( uint8_t block, bool page1, bool usepwd, uint8_t override, uint32_t password, uint8_t downlink_mode, uint32_t data) { bool isOK = t55xxVerifyWrite(block, page1, usepwd, 1, password, downlink_mode, data); if (isOK) - PrintAndLogEx(SUCCESS, "Write OK, validation succesful"); + PrintAndLogEx(SUCCESS, "Write OK, validation successful"); else PrintAndLogEx(WARNING, "Write could not validate the written data"); } diff --git a/client/emv/apduinfo.c b/client/emv/apduinfo.c index 7c3e87408..35735fb47 100644 --- a/client/emv/apduinfo.c +++ b/client/emv/apduinfo.c @@ -191,7 +191,7 @@ const APDUCode APDUCodeTable[] = { {"9681", APDUCODE_TYPE_NONE, "Slave not found"}, {"9700", APDUCODE_TYPE_NONE, "PIN blocked and Unblock Try Counter is 1 or 2"}, {"9702", APDUCODE_TYPE_NONE, "Main keys are blocked"}, - {"9704", APDUCODE_TYPE_NONE, "PIN not succesfully verified, 3 or more PIN tries left"}, + {"9704", APDUCODE_TYPE_NONE, "PIN not successfully verified, 3 or more PIN tries left"}, {"9784", APDUCODE_TYPE_NONE, "Base key"}, {"9785", APDUCODE_TYPE_NONE, "Limit exceeded - C-MAC key"}, {"9786", APDUCODE_TYPE_NONE, "SM error - Limit exceeded - R-MAC key"}, @@ -205,13 +205,13 @@ const APDUCode APDUCodeTable[] = { {"9850", APDUCODE_TYPE_ERROR, "INCREASE or DECREASE could not be executed because a limit has been reached."}, {"9862", APDUCODE_TYPE_ERROR, "Authentication Error, application specific (incorrect MAC)"}, {"9900", APDUCODE_TYPE_NONE, "1 PIN try left"}, - {"9904", APDUCODE_TYPE_NONE, "PIN not succesfully verified, 1 PIN try left"}, + {"9904", APDUCODE_TYPE_NONE, "PIN not successfully verified, 1 PIN try left"}, {"9985", APDUCODE_TYPE_NONE, "Wrong status - Cardholder lock"}, {"9986", APDUCODE_TYPE_ERROR, "Missing privilege"}, {"9987", APDUCODE_TYPE_NONE, "PIN is not installed"}, {"9988", APDUCODE_TYPE_NONE, "Wrong status - R-MAC state"}, {"9A00", APDUCODE_TYPE_NONE, "2 PIN try left"}, - {"9A04", APDUCODE_TYPE_NONE, "PIN not succesfully verified, 2 PIN try left"}, + {"9A04", APDUCODE_TYPE_NONE, "PIN not successfully verified, 2 PIN try left"}, {"9A71", APDUCODE_TYPE_NONE, "Wrong parameter value - Double agent AID"}, {"9A72", APDUCODE_TYPE_NONE, "Wrong parameter value - Double agent Type"}, {"9D05", APDUCODE_TYPE_ERROR, "Incorrect certificate type"}, @@ -258,9 +258,9 @@ const APDUCode APDUCodeTable[] = { {"9D63", APDUCODE_TYPE_ERROR, "Crypto functions not available"}, {"9D64", APDUCODE_TYPE_ERROR, "No application loaded"}, {"9E00", APDUCODE_TYPE_NONE, "PIN not installed"}, - {"9E04", APDUCODE_TYPE_NONE, "PIN not succesfully verified, PIN not installed"}, + {"9E04", APDUCODE_TYPE_NONE, "PIN not successfully verified, PIN not installed"}, {"9F00", APDUCODE_TYPE_NONE, "PIN blocked and Unblock Try Counter is 3"}, - {"9F04", APDUCODE_TYPE_NONE, "PIN not succesfully verified, PIN blocked and Unblock Try Counter is 3"}, + {"9F04", APDUCODE_TYPE_NONE, "PIN not successfully verified, PIN blocked and Unblock Try Counter is 3"}, {"9FXX", APDUCODE_TYPE_NONE, "Command successfully executed; 'xx' bytes of data are available and can be requested using GET RESPONSE."}, {"9XXX", APDUCODE_TYPE_NONE, "Application related status, (ISO 7816-3)"} }; diff --git a/common/mbedtls/ecp.h b/common/mbedtls/ecp.h index 4c2592a9e..1c4bdd65c 100644 --- a/common/mbedtls/ecp.h +++ b/common/mbedtls/ecp.h @@ -528,7 +528,7 @@ int mbedtls_ecp_tls_write_point(const mbedtls_ecp_group *grp, const mbedtls_ecp_ * * \return \c 0 on success, * \return An \c MBEDTLS_ERR_MPI_XXX error code on initialization failure. - * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE for unkownn groups. + * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE for unknown groups. */ int mbedtls_ecp_group_load(mbedtls_ecp_group *grp, mbedtls_ecp_group_id id); From da197e1999bf1556412992e696d1f12ed7105ca4 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 14 Sep 2019 18:27:58 +0200 Subject: [PATCH 0700/1854] CHG: 'lf t55xx wipe c' - now accepts user provided configuration block to configure a wiped tag with. ADD: 'lf t55xx protect' - Sets password and enables password protection in configuration block. It tries to validate its writes aswell. Samples: lf t55xx protect n 11223344 - set pwd to 11223344 lf t55xx protect n 01020304 p 11223344 - change a password protected tag from 11223344 to 01020304 To remove the password protection, you need to remember the password :) lf t55xx wipe p 11223344 - wipes whole tag, removes password protection bits. --- client/cmdlft55xx.c | 472 +++++++++++++++++++++++++++++++------------- client/cmdlft55xx.h | 8 +- 2 files changed, 343 insertions(+), 137 deletions(-) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index f36e30e48..07a365035 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -87,7 +87,6 @@ static int usage_t55xx_config() { PrintAndLogEx(NORMAL, " ST [0/1] - Set/reset Sequence Terminator on"); PrintAndLogEx(NORMAL, ""); // layout is a little differnet, so seperate until a better fix print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE); - PrintAndLogEx(NORMAL, "fix this code...."); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx config d FSK - FSK demodulation"); @@ -97,7 +96,7 @@ static int usage_t55xx_config() { return PM3_SUCCESS; } static int usage_t55xx_read() { - PrintAndLogEx(NORMAL, "Usage: lf t55xx read [r ] b [p ] "); + PrintAndLogEx(NORMAL, "Usage: lf t55xx read [r ] b [p ] [o] "); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " b - block number to read. Between 0-7"); PrintAndLogEx(NORMAL, " p - OPTIONAL password (8 hex characters)"); @@ -271,33 +270,36 @@ static int usage_t55xx_recoverpw() { PrintAndLogEx(NORMAL, "press " _YELLOW_("'enter'") " to cancel the command"); PrintAndLogEx(NORMAL, "WARNING: this may brick non-password protected chips!"); PrintAndLogEx(NORMAL, "Try reading block 7 before\n"); - PrintAndLogEx(NORMAL, "Usage: lf t55xx recoverpw [r ] [p password]"); + PrintAndLogEx(NORMAL, "Usage: lf t55xx recoverpw [r ] [p ]"); PrintAndLogEx(NORMAL, " password must be 4 bytes (8 hex symbols)"); PrintAndLogEx(NORMAL, " default password is 51243648, used by many cloners"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h - this help"); print_usage_t55xx_downloadlink(T55XX_DLMODE_ALL); - PrintAndLogEx(NORMAL, " [password] - 4 byte hex value of password written by cloner"); + PrintAndLogEx(NORMAL, " p - 4 byte hex value of password written by cloner"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx recoverpw"); + PrintAndLogEx(NORMAL, " lf t55xx recoverpw p 51243648"); PrintAndLogEx(NORMAL, " lf t55xx recoverpw r 3 p 51243648"); + PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } static int usage_t55xx_wipe() { - PrintAndLogEx(NORMAL, "Usage: lf t55xx wipe [h] [Q5] [p ]"); + PrintAndLogEx(NORMAL, "Usage: lf t55xx wipe [h] [Q5] [p ] [c ]"); PrintAndLogEx(NORMAL, "This commands wipes a tag, fills blocks 1-7 with zeros and a default configuration block"); PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " h - this help"); - PrintAndLogEx(NORMAL, " q - indicates to use the T5555 (Q5) default configuration block"); + PrintAndLogEx(NORMAL, " h - this help"); + PrintAndLogEx(NORMAL, " c - set configuration from a block0"); + PrintAndLogEx(NORMAL, " q - indicates to use the T5555 (Q5) default configuration block"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx wipe - wipes a t55x7 tag, config block 0x000880E0"); PrintAndLogEx(NORMAL, " lf t55xx wipe q - wipes a t5555 Q5 tag, config block 0x6001F004"); return PM3_SUCCESS; } -static int usage_lf_deviceconfig() { +static int usage_t55xx_deviceconfig() { PrintAndLogEx(NORMAL, "Sets t55x7 timings for direct commands. The timings are set here in Field Clocks (FC), \nwhich is converted to (US) on device"); PrintAndLogEx(NORMAL, "Usage: lf t55xx deviceconfig [r ] a b c d e f g [p]"); PrintAndLogEx(NORMAL, "Options:"); @@ -310,7 +312,6 @@ static int usage_lf_deviceconfig() { PrintAndLogEx(NORMAL, " f <8..255> - Set write TWO gap (1 of 4 only)"); PrintAndLogEx(NORMAL, " g <8..255> - Set write THREE gap (1 of 4 only)"); PrintAndLogEx(NORMAL, " p - persist to flashmemory"); - // print_usage_t55xx_downloadlink(); // does not apply to config PrintAndLogEx(NORMAL, " z - Set default t55x7 timings (use p to save if required)"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); @@ -319,49 +320,184 @@ static int usage_lf_deviceconfig() { PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } +static int usage_t55xx_protect() { + PrintAndLogEx(NORMAL, "This command set or unsets the pwd bit on T5577."); + PrintAndLogEx(NORMAL, "Usage: lf t55xx protect [r ] [p ] [o] [n ]"); + PrintAndLogEx(NORMAL, "Options:"); + PrintAndLogEx(NORMAL, " p - OPTIONAL password (8 hex characters)"); + PrintAndLogEx(NORMAL, " o - OPTIONAL override safety check"); + PrintAndLogEx(NORMAL, " n - new password"); + print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Examples:"); + PrintAndLogEx(NORMAL, " lf t55xx protect n 01020304 - sets new password to 01020304"); + PrintAndLogEx(NORMAL, " lf t55xx protect p 11223344 - use pwd 11223344 to set newpwd to 00000000"); + PrintAndLogEx(NORMAL, ""); + return PM3_SUCCESS; +} static int CmdHelp(const char *Cmd); -static bool t55xxVerifyWrite( uint8_t block, bool page1, bool usepwd, uint8_t override, uint32_t password, uint8_t downlink_mode, uint32_t data) { - - //Password mode - if (usepwd) { - // try reading the config block and verify that PWD bit is set before doing this! - if (override == 0) { - if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, false, 0, downlink_mode) == false) - return false; +static bool t55xxProtect(bool lock, bool usepwd, uint8_t override, uint32_t password, uint8_t downlink_mode, uint32_t new_password ) { - if (tryDetectModulation(downlink_mode,T55XX_DontPrintConfig) == false) { - PrintAndLogEx(NORMAL, "Safety Check: Could not detect if PWD bit is set in config block. Exits."); - return false; - } else { - PrintAndLogEx(NORMAL, "Safety Check: PWD bit is NOT set in config block. Reading without password..."); - usepwd = false; - } - } else if (override == 1) { - PrintAndLogEx(NORMAL, "Safety Check Overriden - proceeding despite risk"); - } + PrintAndLogEx(INFO, "Checking current block0"); + + bool testmode = false; + uint32_t block0 = 0; + + int res = T55xxReadBlockEx(T55x7_CONFIGURATION_BLOCK, T55x7_PAGE0, usepwd, override, password, downlink_mode, false); + if (res != PM3_SUCCESS) { + PrintAndLogEx(WARNING, "fail to read current block0, use `p` password parameter ?"); + return false; } - - if (AquireData(page1, block, usepwd, password, downlink_mode) == false) + + if (GetT55xxBlockData(&block0) == false) return false; - if (block == 0 && page1 == false) { - if (tryDetectModulation(downlink_mode,T55XX_DontPrintConfig) == false) { - PrintAndLogEx(WARNING, "Could not detect modulation automatically. Try setting it manually with \'lf t55xx config\'"); - return false; - } + uint32_t old = block0; + bool isPwdBitAlreadySet = (block0 >> (32-28) & 1); + if (isPwdBitAlreadySet) { + PrintAndLogEx(INFO, "PWD bit is already set"); + usepwd = true; } - if (DecodeT55xxBlock() == false) - return false; + if (lock) { + // set pwd bit + block0 |= 1 << 4; + } else { + block0 &= ~(1 << 4); + } + + PrintAndLogEx(INFO, " old %08X vs %08X", old, block0); - // compare... - uint32_t readblock = 0; - if (GetT55xxBlockData(&readblock) == false) - return false; - - return (readblock == data); + // write new password + if ( t55xxWrite(T55x7_PWD_BLOCK, T55x7_PAGE0, usepwd, testmode, password, downlink_mode, new_password ) != PM3_SUCCESS ) { + PrintAndLogEx(ERR, "Failed writing new pwd"); + return false; + } else { + PrintAndLogEx(SUCCESS, "Wrote new password"); + } + + // password bit already set + // write b 7 new key old_pwd + // validate b 7 new_key old_pwd + // write b0 new_key + // validate b0 new_key + + // write b7 new key + // validate b7 (no key) + // write b0 (no key) + // validate b0 w new key + + + // validate new password + uint32_t curr_password = (isPwdBitAlreadySet) ? new_password : password; + + if (t55xxVerifyWrite(T55x7_PWD_BLOCK, T55x7_PAGE0, usepwd, override, curr_password, downlink_mode, new_password) == false) { + PrintAndLogEx(WARNING, "Could not validate the new password write. aborting."); + return false; + } else { + PrintAndLogEx(SUCCESS, "Validated new password"); + } + + // write config + if ( t55xxWrite(T55x7_CONFIGURATION_BLOCK, T55x7_PAGE0, usepwd, testmode, curr_password, downlink_mode, block0 ) != PM3_SUCCESS ) { + PrintAndLogEx(ERR, "Failed writing modified configuration block %08X", block0); + return false; + } else { + PrintAndLogEx(SUCCESS, "Wrote modified configuration block"); + } + + // validate new config. If all went well, card should now demand pwd, hence override = 0. + override = 0; + if (t55xxVerifyWrite(T55x7_CONFIGURATION_BLOCK, T55x7_PAGE0, true, override, new_password, downlink_mode, block0) == false) { + PrintAndLogEx(WARNING, "Could not validate pwd bit set on configuration block. aborting."); + return false; + } else { + PrintAndLogEx(SUCCESS, "New configuration block " _YELLOW_("%08X")"password " _YELLOW_("%08X"), block0, new_password); + PrintAndLogEx(SUCCESS, "Success, tag is locked"); + return true; + } +} + +bool t55xxVerifyWrite(uint8_t block, bool page1, bool usepwd, uint8_t override, uint32_t password, uint8_t downlink_mode, uint32_t data) { + + uint32_t read_data = 0; + + int res = T55xxReadBlockEx(block, page1, usepwd, override, password, downlink_mode, false); + if (res == PM3_SUCCESS) { + + if (GetT55xxBlockData(&read_data) == false) + return false; + + } else if ( res == PM3_EWRONGANSVER) { + + // could't decode. Lets see if this was a block 0 write and try read/detect it auto. + // this messes up with ppls config.. + if (block == 0 && page1 == false) { + + PrintAndLogEx(INFO, "Block0 write detected, running `detect` to see if validation is possible (pwd == %08X)", password); + + bool got_modulation = false; + for ( uint8_t m = 0; m < 4; m++) { + + if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, password, m) == false) { + PrintAndLogEx(INPLACE, "."); + continue; + } + + if (tryDetectModulation(m, true) == false) { + PrintAndLogEx(INPLACE, "."); + continue; + } else { + got_modulation = true; + PrintAndLogEx(NORMAL, ""); + break; + } + } + + if (got_modulation == false) + return false; + + return t55xxVerifyWrite(block, page1, usepwd, 2, password, downlink_mode, data); + } + } + + return (read_data == data); +} + +int t55xxWrite(uint8_t block, bool page1, bool usepwd, bool testMode, uint32_t password, uint8_t downlink_mode, uint32_t data) { + + uint8_t flags; + flags = (usepwd) ? 0x1 : 0; + flags |= (page1) ? 0x2 : 0; + flags |= (testMode) ? 0x4 : 0; + flags |= (downlink_mode << 3); + + /* + OLD style + arg0 = data, (4 bytes) + arg1 = block (1 byte) + arg2 = password (4 bytes) + flags = data[0] (1 byte) + + new style + uses struct in pm3_cmd.h + */ + t55xx_write_block_t ng; + ng.data = data; + ng.pwd = password; + ng.blockno = block; + ng.flags = flags; + + PacketResponseNG resp; + clearCommandBuffer(); + SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng)); + if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, 2000)) { + PrintAndLogEx(ERR, "Error occurred, device did not ACK write operation."); + return PM3_ETIMEOUT; + } + return resp.status; } void printT5xxHeader(uint8_t page) { @@ -481,7 +617,7 @@ static int CmdT55xxSetConfig(const char *Cmd) { } break; case 'r': - errors = param_getdec(Cmd, cmdp + 1,&downlink_mode); + errors = param_getdec(Cmd, cmdp + 1, &downlink_mode); if (downlink_mode > 3) downlink_mode = 0; if (!errors) @@ -530,35 +666,42 @@ static int CmdT55xxSetConfig(const char *Cmd) { return printConfiguration(config); } - int T55xxReadBlock(uint8_t block, bool page1, bool usepwd, uint8_t override, uint32_t password, uint8_t downlink_mode) { + return T55xxReadBlockEx(block, page1, usepwd, override, password, downlink_mode, true); +} + +int T55xxReadBlockEx(uint8_t block, bool page1, bool usepwd, uint8_t override, uint32_t password, uint8_t downlink_mode, bool verbose) { //Password mode if (usepwd) { // try reading the config block and verify that PWD bit is set before doing this! + // override = 1 (override and display) + // override = 2 (override and no display) if (override == 0) { - if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, false, 0, downlink_mode)) return PM3_ESOFT; + if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, false, 0, downlink_mode) == false) + return PM3_ERFTRANS; - if (!tryDetectModulation(downlink_mode,T55XX_DontPrintConfig)) { - PrintAndLogEx(NORMAL, "Safety Check: Could not detect if PWD bit is set in config block. Exits."); - return PM3_ESOFT; + if (tryDetectModulation(downlink_mode, false) == false) { + PrintAndLogEx(WARNING, "Safety Check: Could not detect if PWD bit is set in config block. Exits."); + return PM3_EWRONGANSVER; } else { - PrintAndLogEx(NORMAL, "Safety Check: PWD bit is NOT set in config block. Reading without password..."); + PrintAndLogEx(WARNING, "Safety Check: PWD bit is NOT set in config block. Reading without password..."); usepwd = false; page1 = false; // ?? } } else if (override == 1) { - // Show only if first for command i.e. override = 1 (override and display) override = 2 (override and dont display) - PrintAndLogEx(NORMAL, "Safety Check Overriden - proceeding despite risk"); + PrintAndLogEx(INFO, "Safety Check Overriden - proceeding despite risk"); } } - if (!AquireData(page1, block, usepwd, password, downlink_mode)) - return PM3_ESOFT; + if (AquireData(page1, block, usepwd, password, downlink_mode) == false) + return PM3_ERFTRANS; - if (!DecodeT55xxBlock()) - return PM3_ESOFT; + if (DecodeT55xxBlock() == false) + return PM3_EWRONGANSVER; + + if (verbose) + printT55xxBlock(block); - printT55xxBlock(block); return PM3_SUCCESS; } @@ -730,7 +873,6 @@ static int CmdT55xxDetect(const char *Cmd) { uint32_t password = 0; uint8_t cmdp = 0; uint8_t downlink_mode = 0; - uint8_t dl_mode = 0; while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { @@ -765,22 +907,28 @@ static int CmdT55xxDetect(const char *Cmd) { return PM3_ESOFT; if (useGB == false) { - for (dl_mode = downlink_mode; dl_mode < 4; dl_mode++) { - found = AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, dl_mode); - - if (tryDetectModulation(dl_mode,T55XX_PrintConfig)) { - dl_mode = 4; - found = true; + + //ICEMAN STRANGE + for (uint8_t m = downlink_mode; m < 4; m++) { + if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, m) == false) { + continue; } - else found = false; + + if (tryDetectModulation(m, T55XX_PrintConfig)) { + m = 4; + found = true; + } else { + found = false; + } - if (!try_all_dl_modes) dl_mode = 4; + if (try_all_dl_modes == false) + m = 4; } } else { - found = tryDetectModulation(downlink_mode,T55XX_PrintConfig); + found = tryDetectModulation(downlink_mode, T55XX_PrintConfig); } - if (!found) + if (found == false) PrintAndLogEx(WARNING, "Could not detect modulation automatically. Try setting it manually with " _YELLOW_("\'lf t55xx config\'")); return PM3_SUCCESS; @@ -959,7 +1107,10 @@ bool tryDetectModulation(uint8_t downlink_mode, bool print_config) { config.Q5 = tests[0].Q5; config.ST = tests[0].ST; config.downlink_mode = downlink_mode; - if (print_config) printConfiguration(config); + + if (print_config) + printConfiguration(config); + return true; } @@ -981,7 +1132,9 @@ bool tryDetectModulation(uint8_t downlink_mode, bool print_config) { } else { PrintAndLogEx(NORMAL, "--[%d]---------------", i + 1); } - if (print_config) printConfiguration(tests[i]); + + if (print_config) + printConfiguration(tests[i]); } } return retval; @@ -1234,14 +1387,14 @@ int special(const char *Cmd) { } int printConfiguration(t55xx_conf_block_t b) { - PrintAndLogEx(NORMAL, " Chip Type : %s", (b.Q5) ? "T5555(Q5)" : "T55x7"); - PrintAndLogEx(NORMAL, " Modulation : %s", GetSelectedModulationStr(b.modulation)); - PrintAndLogEx(NORMAL, " Bit Rate : %s", GetBitRateStr(b.bitrate, (b.block0 & T55x7_X_MODE && (b.block0 >> 28 == 6 || b.block0 >> 28 == 9)))); - PrintAndLogEx(NORMAL, " Inverted : %s", (b.inverted) ? _GREEN_("Yes") : "No"); - PrintAndLogEx(NORMAL, " Offset : %d", b.offset); - PrintAndLogEx(NORMAL, " Seq. Term. : %s", (b.ST) ? _GREEN_("Yes") : "No"); - PrintAndLogEx(NORMAL, " Block0 : 0x%08X", b.block0); - PrintAndLogEx(NORMAL, " DL Mode : %s",GetDownlinkModeStr (b.downlink_mode)); + PrintAndLogEx(NORMAL, " Chip Type : %s", (b.Q5) ? "T5555(Q5)" : "T55x7"); + PrintAndLogEx(NORMAL, " Modulation : %s", GetSelectedModulationStr(b.modulation)); + PrintAndLogEx(NORMAL, " Bit Rate : %s", GetBitRateStr(b.bitrate, (b.block0 & T55x7_X_MODE && (b.block0 >> 28 == 6 || b.block0 >> 28 == 9)))); + PrintAndLogEx(NORMAL, " Inverted : %s", (b.inverted) ? _GREEN_("Yes") : "No"); + PrintAndLogEx(NORMAL, " Offset : %d", b.offset); + PrintAndLogEx(NORMAL, " Seq. Term. : %s", (b.ST) ? _GREEN_("Yes") : "No"); + PrintAndLogEx(NORMAL, " Block0 : 0x%08X", b.block0); + PrintAndLogEx(NORMAL, " Downling Mode : %s", GetDownlinkModeStr (b.downlink_mode)); PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } @@ -1265,6 +1418,7 @@ static int CmdT55xxWakeUp(const char *Cmd) { downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); if (downlink_mode > 3) downlink_mode = 0; + cmdp += 2; break; default: @@ -1358,43 +1512,17 @@ static int CmdT55xxWriteBlock(const char *Cmd) { } if (errors || !gotdata) return usage_t55xx_write(); - PacketResponseNG resp; - uint8_t flags; - flags = (usepwd) ? 0x1 : 0; - flags |= (page1) ? 0x2 : 0; - flags |= (testMode) ? 0x4 : 0; - flags |= (downlink_mode << 3); - char pwdStr[16] = {0}; snprintf(pwdStr, sizeof(pwdStr), "pwd: 0x%08X", password); PrintAndLogEx(INFO, "Writing page %d block: %02d data: 0x%08X %s", page1, block, data, (usepwd) ? pwdStr : ""); - /* - OLD style - arg0 = data, (4 bytes) - arg1 = block (1 byte) - arg2 = password (4 bytes) - flags = data[0] (1 byte) - - new style - uses struct in pm3_cmd.h - */ - t55xx_write_block_t ng; - ng.data = data; - ng.pwd = password; - ng.blockno = block; - ng.flags = flags; - - clearCommandBuffer(); - SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng)); - if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, 2000)) { - PrintAndLogEx(ERR, "Error occurred, device did not ACK write operation. (May be due to old firmware)"); - return PM3_ETIMEOUT; + if ( t55xxWrite(block, page1, usepwd, testMode, password, downlink_mode, data) != PM3_SUCCESS ) { + PrintAndLogEx(ERR, "Write failed"); + return PM3_ESOFT; } - + if (validate) { -//t55xxVerifyWrite( uint8_t block, bool page1, bool usepwd, uint8_t override, uint32_t password, uint8_t downlink_mode, uint32_t data) { bool isOK = t55xxVerifyWrite(block, page1, usepwd, 1, password, downlink_mode, data); if (isOK) PrintAndLogEx(SUCCESS, "Write OK, validation succesful"); @@ -2047,16 +2175,16 @@ char *GetDownlinkModeStr (uint8_t downlink_mode) switch (downlink_mode) { case T55XX_DLMODE_FIXED : - snprintf (retStr,sizeof(buf),"default/fixed bit length"); + snprintf(retStr, sizeof(buf),"default/fixed bit length"); break; case T55XX_DLMODE_LLR : - snprintf (retStr,sizeof(buf),"long leading reference"); + snprintf(retStr, sizeof(buf),"long leading reference"); break; case T55XX_DLMODE_LEADING_ZERO : - snprintf (retStr,sizeof(buf),"leading zero reference"); + snprintf(retStr, sizeof(buf),"leading zero reference"); break; case T55XX_DLMODE_1OF4 : - snprintf (retStr,sizeof(buf),"1 of 4 coding reference"); + snprintf(retStr, sizeof(buf),"1 of 4 coding reference"); break; default: snprintf(retStr, sizeof(buf), _RED_("(Unknown)")); @@ -2211,8 +2339,6 @@ static int CmdResetRead(const char *Cmd) { if (errors) return usage_t55xx_resetread(); - // PrintAndLogEx(INFO, "DL : %d\n", downlink_mode); // no value outside of debug - flags = downlink_mode << 3; clearCommandBuffer(); @@ -2232,11 +2358,11 @@ static int CmdResetRead(const char *Cmd) { } static int CmdT55xxWipe(const char *Cmd) { + char writeData[36] = {0}; char *ptrData = writeData; - uint32_t password = 0; - bool usepwd = false; - bool Q5 = false; + uint32_t password = 0, block0 = 0; + bool usepwd = false, Q5 = false, gotconf = false; uint8_t cmdp = 0; bool errors = false; @@ -2250,6 +2376,11 @@ static int CmdT55xxWipe(const char *Cmd) { usepwd = true; cmdp += 2; break; + case 'c': + block0 = param_get32ex(Cmd, cmdp + 1, 0, 16); + gotconf = true; + cmdp += 2; + break; case 'q': Q5 = true; cmdp++; @@ -2263,22 +2394,31 @@ static int CmdT55xxWipe(const char *Cmd) { if (errors) return usage_t55xx_wipe(); - // Try with the default password to reset block 0 - // With a pwd should work even if pwd bit not set - PrintAndLogEx(INFO, "\nBeginning Wipe of a T55xx tag (assuming the tag is not password protected)\n"); + PrintAndLogEx(INFO, "\nBegin wiping %s", (Q5)? "Q5 / T5555 tag" : "T55x7 tag"); - if (usepwd) { - snprintf(ptrData, sizeof(writeData), "b 0 p %08x ", password); - } else { - snprintf(ptrData, sizeof(writeData), "b 0 "); + // default config blocks. + if (gotconf == false) { + block0 = (Q5) ? 0x6001F004 : 0x000880E0; } - if (Q5) - snprintf(ptrData + strlen(writeData), sizeof(writeData) - strlen(writeData), "d 6001F004"); - else - snprintf(ptrData + strlen(writeData), sizeof(writeData) - strlen(writeData), "d 000880E0"); + char msg[80] = {0}; + if (gotconf) + snprintf(msg, sizeof(msg), "User provided configuration block %08X", block0); + else + snprintf(msg, sizeof(msg), "Default configation block %08X", block0); + + PrintAndLogEx(INFO, "%s", msg); + + // Creating cmd string for write block :) + snprintf(ptrData, sizeof(writeData), "b 0 "); + + if (usepwd) { + snprintf(ptrData + strlen(writeData), sizeof(writeData) - strlen(writeData), "p %08x ", password); + } + snprintf(ptrData + strlen(writeData), sizeof(writeData) - strlen(writeData), "d %08X", block0); + if (CmdT55xxWriteBlock(ptrData) != PM3_SUCCESS) PrintAndLogEx(WARNING, "Warning: error writing blk 0"); @@ -2296,7 +2436,7 @@ static int CmdT55xxWipe(const char *Cmd) { if (config.downlink_mode != T55XX_DLMODE_FIXED) { // Detect found a different mode so card must support snprintf(ptrData, sizeof(writeData), "b 3 1 d 00000000"); if (CmdT55xxWriteBlock(ptrData) != PM3_SUCCESS) - PrintAndLogEx(WARNING, "Warning: error writing blk 3 page 1 (config)"); + PrintAndLogEx(WARNING, "Warning: failed writing block 3 page 1 (config)"); memset(writeData, 0x00, sizeof(writeData)); } return PM3_SUCCESS; @@ -2390,10 +2530,9 @@ static int CmdT55xxChkPwds(const char *Cmd) { PrintAndLogEx(SUCCESS, "\nFound a candidate [ " _YELLOW_("%08X") " ]. Trying to validate", resp.oldarg[1]); if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, resp.oldarg[1], downlink_mode)) { - found = tryDetectModulation(downlink_mode,T55XX_PrintConfig); + found = tryDetectModulation(downlink_mode, T55XX_PrintConfig); if (found) { PrintAndLogEx(SUCCESS, "Found valid password: [ " _GREEN_("%08X") " ]", resp.oldarg[1]); - // T55xx_Print_DownlinkMode(downlink_mode); } else { PrintAndLogEx(WARNING, "Check pwd failed"); @@ -2446,7 +2585,6 @@ static int CmdT55xxChkPwds(const char *Cmd) { found = tryDetectModulation(dl_mode,T55XX_PrintConfig); if (found) { PrintAndLogEx(SUCCESS, "Found valid password: [ " _GREEN_("%08X") " ]", curr_password); - // T55xx_Print_DownlinkMode(dl_mode); dl_mode = 4; // Exit other downlink mode checks c = keycount; // Exit loop } @@ -2740,7 +2878,6 @@ bool tryDetectP1(bool getData) { (DemodBufferLen == 32 || DemodBufferLen == 64)) { return true; } - } // try NRZ clock detect. it could be another type even if successful. @@ -2822,7 +2959,8 @@ static int CmdT55xxDetectPage1(const char *Cmd) { useGB = true; cmdp++; break; - case 'r': + case 'r': + //ICEMAN STRANGE downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); if (downlink_mode == 4) try_all_dl_modes = true; @@ -2876,7 +3014,7 @@ static int CmdT55xxSetDeviceConfig(const char *Cmd) { while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { case 'h': - return usage_lf_deviceconfig(); + return usage_t55xx_deviceconfig(); case 'a': errors |= param_getdec(Cmd, cmdp + 1, &startgap); cmdp += 2; @@ -2928,7 +3066,7 @@ static int CmdT55xxSetDeviceConfig(const char *Cmd) { } //Validations - if (errors || cmdp == 0) return usage_lf_deviceconfig(); + if (errors || cmdp == 0) return usage_t55xx_deviceconfig(); t55xx_configurations_t configurations = {{{0}, {0}, {0}, {0}}}; @@ -2984,6 +3122,67 @@ static int CmdT55xxSetDeviceConfig(const char *Cmd) { return PM3_SUCCESS; } +static int CmdT55xxProtect(const char *Cmd) { + bool errors = false, usepwd = false, gotnewpwd = false; + uint32_t password = 0, new_password = 0; + uint8_t override = 0; + uint8_t cmdp = 0; + uint8_t downlink_mode = 0; + + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { + case 'h': + return usage_t55xx_protect(); + case 'o': + override = 2; + cmdp++; + break; + case 'n': + new_password = param_get32ex(Cmd, cmdp + 1, 0, 16); + gotnewpwd = true; + cmdp += 2; + break; + case 'p': + password = param_get32ex(Cmd, cmdp + 1, 0, 16); + usepwd = true; + override = 1; + cmdp += 2; + break; + case 'r': + //ICEMAN STRANGE + downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); + if (downlink_mode > 3) + downlink_mode = 0; + + cmdp += 2; + break; + default: + PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } + } + + if (gotnewpwd == false) + return usage_t55xx_protect(); + + if (errors || cmdp == 0) return usage_t55xx_protect(); + + // sanity check. + if (SanityOfflineCheck(false) != PM3_SUCCESS) + return PM3_ESOFT; + + // lock + bool res = t55xxProtect(true, usepwd, override, password, downlink_mode, new_password ); + // unlock +// res = t55xxProtect(false, usepwd, override, password, downlink_mode, new_password ); + if (res == false) { + PrintAndLogEx(WARNING, "Command failed. Did you run `lf t55xx detect` before?"); + return PM3_ESOFT; + } + return PM3_SUCCESS; +} + static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, {"bruteforce", CmdT55xxBruteForce, IfPm3Lf, " Simple bruteforce attack to find password"}, @@ -2991,9 +3190,10 @@ static command_t CommandTable[] = { {"chk", CmdT55xxChkPwds, IfPm3Lf, "Check passwords from dictionary/flash"}, {"detect", CmdT55xxDetect, AlwaysAvailable, "[1] Try detecting the tag modulation from reading the configuration block."}, {"deviceconfig", CmdT55xxSetDeviceConfig, IfPm3Lf, "Set/Get T55XX device configuration (startgap, writegap, write0, write1, readgap"}, - {"p1detect", CmdT55xxDetectPage1, IfPm3Lf, "[1] Try detecting if this is a t55xx tag by reading page 1"}, {"dump", CmdT55xxDump, IfPm3Lf, "[password] [o] Dump T55xx card block 0-7. Optional [password], [override]"}, {"info", CmdT55xxInfo, AlwaysAvailable, "[1] Show T55x7 configuration data (page 0/ blk 0)"}, + {"p1detect", CmdT55xxDetectPage1, IfPm3Lf, "[1] Try detecting if this is a t55xx tag by reading page 1"}, + {"protect", CmdT55xxProtect, IfPm3Lf, "Password protect tag"}, {"read", CmdT55xxReadBlock, IfPm3Lf, "b p [password] [o] [1] -- Read T55xx block data. Optional [p password], [override], [page1]"}, {"resetread", CmdResetRead, IfPm3Lf, "Send Reset Cmd then lf read the stream to attempt to identify the start of it (needs a demod and/or plot after)"}, {"recoverpw", CmdT55xxRecoverPW, IfPm3Lf, "[password] Try to recover from bad password write from a cloner. Only use on PW protected chips!"}, diff --git a/client/cmdlft55xx.h b/client/cmdlft55xx.h index b2af0f5b4..129a6cf5e 100644 --- a/client/cmdlft55xx.h +++ b/client/cmdlft55xx.h @@ -13,6 +13,7 @@ #include "common.h" #define T55x7_CONFIGURATION_BLOCK 0x00 +#define T55x7_PWD_BLOCK 0x07 #define T55x7_TRACE_BLOCK1 0x01 #define T55x7_TRACE_BLOCK2 0x02 #define T55x7_PAGE0 0x00 @@ -142,7 +143,12 @@ void printT5xxHeader(uint8_t page); void printT55xxBlock(uint8_t blockNum); int printConfiguration(t55xx_conf_block_t b); -int T55xxReadBlock(uint8_t block, bool page1, bool usepwd, uint8_t override, uint32_t password, uint8_t downlink_mode); +bool t55xxVerifyWrite( uint8_t block, bool page1, bool usepwd, uint8_t override, uint32_t password, uint8_t downlink_mode, uint32_t data); +int T55xxReadBlock(uint8_t block, bool page1, bool usepwd, uint8_t override, uint32_t password, uint8_t downlink_mode); +int T55xxReadBlockEx(uint8_t block, bool page1, bool usepwd, uint8_t override, uint32_t password, uint8_t downlink_mode, bool verbose); + +int t55xxWrite(uint8_t block, bool page1, bool usepwd, bool testMode, uint32_t password, uint8_t downlink_mode, uint32_t data); + bool GetT55xxBlockData(uint32_t *blockdata); bool DecodeT55xxBlock(void); bool tryDetectModulation(uint8_t downlink_mode, bool print_config); From f210f9a9349f970d2969bf49ec6fa6effc73c12e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 14 Sep 2019 19:04:17 +0200 Subject: [PATCH 0701/1854] textual --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 49be5d124..c062f6f83 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Add `lf t55xx protect` - sets password and enables password protection on t55x7 tag (@iceman1001) + - Chg `lf t55xx wipe` - now accepts user provided configuration block (@iceman1001) - Chg proxmark3-flasher is now merged into proxmark3 client. Add pm3-flash (@doegox) - Chg `hf iclass clone\dump\rdbl\wrbl` - now uses NG (@iceman1001) - Fix `hf iclass clone` - last block always fails (@iceman1001) From d5d273fedb695c03b850a90a94d79f91e81cd6a3 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 14 Sep 2019 19:11:39 +0200 Subject: [PATCH 0702/1854] fix. --- client/cmdlft55xx.c | 1 - 1 file changed, 1 deletion(-) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 2ebdd87f1..faf371443 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -354,7 +354,6 @@ static bool t55xxProtect(bool lock, bool usepwd, uint8_t override, uint32_t pass if (GetT55xxBlockData(&block0) == false) return false; - uint32_t old = block0; bool isPwdBitAlreadySet = (block0 >> (32-28) & 1); if (isPwdBitAlreadySet) { PrintAndLogEx(INFO, "PWD bit is already set"); From cd28641d962c8a1335ee6a6de80704a8b1e5f2e2 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 14 Sep 2019 19:31:00 +0200 Subject: [PATCH 0703/1854] chg: 'lf visa2000 clone' - now verify successful write of blocks. --- client/cmdlft55xx.c | 15 +++++++-------- client/cmdlfvisa2000.c | 28 +++++++++++++--------------- client/cmdlfvisa2000.h | 12 ++++++++++++ 3 files changed, 32 insertions(+), 23 deletions(-) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index faf371443..5575ef80e 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -421,29 +421,28 @@ bool t55xxVerifyWrite(uint8_t block, bool page1, bool usepwd, uint8_t override, // this messes up with ppls config.. if (block == 0 && page1 == false) { - PrintAndLogEx(INFO, "Block0 write detected, running `detect` to see if validation is possible (pwd == %08X)", password); - + + PrintAndLogEx(INFO, "Block0 write detected, running `detect` to see if validation is possible"); bool got_modulation = false; for ( uint8_t m = 0; m < 4; m++) { - if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, password, m) == false) { - PrintAndLogEx(INPLACE, "."); + if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, m) == false) { continue; } - - if (tryDetectModulation(m, true) == false) { + + if (tryDetectModulation(m, false) == false) { PrintAndLogEx(INPLACE, "."); continue; } else { got_modulation = true; - PrintAndLogEx(NORMAL, ""); break; } } + PrintAndLogEx(NORMAL, ""); if (got_modulation == false) return false; - + return t55xxVerifyWrite(block, page1, usepwd, 2, password, downlink_mode, data); } } diff --git a/client/cmdlfvisa2000.c b/client/cmdlfvisa2000.c index ed181d991..1433ced01 100644 --- a/client/cmdlfvisa2000.c +++ b/client/cmdlfvisa2000.c @@ -11,19 +11,6 @@ #include "cmdlfvisa2000.h" -#include -#include -#include - -#include "cmdparser.h" // command_t -#include "comms.h" -#include "ui.h" -#include "graph.h" -#include "cmddata.h" -#include "cmdlf.h" -#include "protocols.h" // for T55xx config register definitions -#include "lfdemod.h" // parityTest - #define BL0CK1 0x56495332 static int CmdHelp(const char *Cmd); @@ -171,7 +158,7 @@ static int CmdVisa2kClone(const char *Cmd) { id = param_get32ex(Cmd, 0, 0, 10); //Q5 - if (param_getchar(Cmd, 1) == 'Q' || param_getchar(Cmd, 1) == 'q') + if (tolower(param_getchar(Cmd, 1)) == 'q') blocks[0] = T5555_MODULATION_MANCHESTER | T5555_SET_BITRATE(64) | T5555_ST_TERMINATOR | 3 << T5555_MAXBLOCK_SHIFT; blocks[2] = id; @@ -180,8 +167,10 @@ static int CmdVisa2kClone(const char *Cmd) { PrintAndLogEx(INFO, "Preparing to clone Visa2000 to T55x7 with CardId: %u", id); print_blocks(blocks, 4); + uint8_t res = 0; + PacketResponseNG resp; - + // fast push mode conn.block_after_ACK = true; for (uint8_t i = 0; i < 4; i++) { @@ -202,7 +191,16 @@ static int CmdVisa2kClone(const char *Cmd) { PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); return PM3_ETIMEOUT; } + + bool isok = t55xxVerifyWrite(i, 0, false, false, 0, 0, blocks[i]); + if ( isok == false) { + PrintAndLogEx(WARNING, "Couldn't verify write"); + res++; + } } + if ( res == 0 ) + PrintAndLogEx(SUCCESS, "Success writing to tag"); + return PM3_SUCCESS; } diff --git a/client/cmdlfvisa2000.h b/client/cmdlfvisa2000.h index 63e7fdc67..e8995cbdd 100644 --- a/client/cmdlfvisa2000.h +++ b/client/cmdlfvisa2000.h @@ -9,7 +9,19 @@ #ifndef CMDLFVISA2000_H__ #define CMDLFVISA2000_H__ +#include +#include +#include #include "common.h" +#include "cmdparser.h" // command_t +#include "comms.h" +#include "ui.h" +#include "graph.h" +#include "cmddata.h" +#include "cmdlf.h" +#include "protocols.h" // for T55xx config register definitions +#include "lfdemod.h" // parityTest +#include "cmdlft55xx.h" // write verify int CmdLFVisa2k(const char *Cmd); From 2bec009778bd6ba01c108f1cd878f80db8057547 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 14 Sep 2019 19:58:17 +0200 Subject: [PATCH 0704/1854] chg: 'lf viking clone' - now uses NG --- armsrc/appmain.c | 13 +++++++++++-- armsrc/lfops.c | 14 ++++++++++---- armsrc/lfops.h | 2 +- client/cmdlfviking.c | 32 +++++++++++++++----------------- client/cmdlfviking.h | 13 +++++++++++++ 5 files changed, 50 insertions(+), 24 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 6194cfe39..d48b798a5 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -856,7 +856,12 @@ static void PacketReceived(PacketCommandNG *packet) { break; } case CMD_LF_VIKING_CLONE: { - CopyVikingtoT55xx(packet->oldarg[0], packet->oldarg[1], packet->oldarg[2]); + struct p { + bool Q5; + uint8_t blocks[8]; + } PACKED; + struct p *payload = (struct p*)packet->data.asBytes; + CopyVikingtoT55xx(payload->blocks, payload->Q5); break; } case CMD_LF_COTAG_READ: { @@ -1217,7 +1222,11 @@ static void PacketReceived(PacketCommandNG *packet) { break; } case CMD_HF_ICLASS_READER: { - ReaderIClass(packet->oldarg[0]); + struct p { + uint8_t flags; + } PACKED; + struct p *payload = (struct p *)packet->data.asBytes; + ReaderIClass(payload->flags); break; } case CMD_HF_ICLASS_REPLAY: { diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 341b98483..d032b2236 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -2152,13 +2152,19 @@ void CopyIndala224toT55x7(uint32_t uid1, uint32_t uid2, uint32_t uid3, uint32_t LED_D_OFF(); } // clone viking tag to T55xx -void CopyVikingtoT55xx(uint32_t block1, uint32_t block2, uint8_t Q5) { - uint32_t data[] = {T55x7_BITRATE_RF_32 | T55x7_MODULATION_MANCHESTER | (2 << T55x7_MAXBLOCK_SHIFT), block1, block2}; - if (Q5) data[0] = T5555_SET_BITRATE(32) | T5555_MODULATION_MANCHESTER | 2 << T5555_MAXBLOCK_SHIFT; +void CopyVikingtoT55xx(uint8_t *blocks, uint8_t Q5) { + + uint32_t data[] = {T55x7_BITRATE_RF_32 | T55x7_MODULATION_MANCHESTER | (2 << T55x7_MAXBLOCK_SHIFT), 0, 0}; + if (Q5) + data[0] = T5555_SET_BITRATE(32) | T5555_MODULATION_MANCHESTER | 2 << T5555_MAXBLOCK_SHIFT; + + data[1] = bytes_to_num(blocks, 4); + data[2] = bytes_to_num(blocks +4, 4); + // Program the data blocks for supplied ID and the block 0 config WriteT55xx(data, 0, 3); LED_D_OFF(); - reply_mix(CMD_ACK, 0, 0, 0, 0, 0); + reply_ng(CMD_LF_VIKING_CLONE, PM3_SUCCESS, NULL, 0); } // Define 9bit header for EM410x tags diff --git a/armsrc/lfops.h b/armsrc/lfops.h index 186b41f90..690f29db3 100644 --- a/armsrc/lfops.h +++ b/armsrc/lfops.h @@ -43,7 +43,7 @@ void CmdEM410xdemod(int findone, uint32_t *high, uint64_t *low, int ledcontrol); void CmdIOdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol); void CopyIOtoT55x7(uint32_t hi, uint32_t lo); // Clone an ioProx card to T5557/T5567 void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT); // Clone an HID card to T5557/T5567 -void CopyVikingtoT55xx(uint32_t block1, uint32_t block2, uint8_t Q5); +void CopyVikingtoT55xx(uint8_t *blocks, uint8_t Q5); void WriteEM410x(uint32_t card, uint32_t id_hi, uint32_t id_lo); void CopyIndala64toT55x7(uint32_t hi, uint32_t lo); // Clone Indala 64-bit tag by UID to T55x7 void CopyIndala224toT55x7(uint32_t uid1, uint32_t uid2, uint32_t uid3, uint32_t uid4, uint32_t uid5, uint32_t uid6, uint32_t uid7); // Clone Indala 224-bit tag by UID to T55x7 diff --git a/client/cmdlfviking.c b/client/cmdlfviking.c index ef88cc169..45fe9ffb6 100644 --- a/client/cmdlfviking.c +++ b/client/cmdlfviking.c @@ -9,17 +9,6 @@ //----------------------------------------------------------------------------- #include "cmdlfviking.h" -#include -#include -#include - -#include "cmdparser.h" // command_t -#include "comms.h" -#include "ui.h" -#include "cmddata.h" -#include "cmdlf.h" -#include "lfdemod.h" - static int CmdHelp(const char *Cmd); static int usage_lf_viking_clone(void) { @@ -90,22 +79,31 @@ static int CmdVikingClone(const char *Cmd) { id = param_get32ex(Cmd, 0, 0, 16); if (id == 0) return usage_lf_viking_clone(); - cmdp = param_getchar(Cmd, 1); - if (cmdp == 'Q' || cmdp == 'q') + cmdp = tolower(param_getchar(Cmd, 1)); + if (cmdp == 'q') Q5 = true; rawID = getVikingBits(id); - PrintAndLogEx(INFO, "Preparing to clone Viking tag - ID " _YELLOW_("%08X")" raw " _YELLOW_("%08X%08X"), id, (uint32_t)(rawID >> 32), (uint32_t)(rawID & 0xFFFFFFFF)); + struct p { + bool Q5; + uint8_t blocks[8]; + } PACKED payload; + payload.Q5 = Q5; + + num_to_bytes(rawID, 8, &payload.blocks[0]); + PrintAndLogEx(INFO, "Preparing to clone Viking tag - ID " _YELLOW_("%08X")" raw " _YELLOW_("%s"), id, sprint_hex(payload.blocks, sizeof(payload.blocks))); + clearCommandBuffer(); - SendCommandMIX(CMD_LF_VIKING_CLONE, rawID >> 32, rawID & 0xFFFFFFFF, Q5, NULL, 0); + + SendCommandNG(CMD_LF_VIKING_CLONE, (uint8_t*)&payload, sizeof(payload)); PacketResponseNG resp; - if (!WaitForResponseTimeout(CMD_ACK, &resp, T55XX_WRITE_TIMEOUT)) { + if (!WaitForResponseTimeout(CMD_LF_VIKING_CLONE, &resp, T55XX_WRITE_TIMEOUT)) { PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); return PM3_ETIMEOUT; } - return PM3_SUCCESS; + return resp.status; } static int CmdVikingSim(const char *Cmd) { diff --git a/client/cmdlfviking.h b/client/cmdlfviking.h index 156d57c7d..344bb3c0c 100644 --- a/client/cmdlfviking.h +++ b/client/cmdlfviking.h @@ -9,8 +9,21 @@ #ifndef CMDLFVIKING_H__ #define CMDLFVIKING_H__ +#include +#include +#include + #include "common.h" +#include "cmdparser.h" // command_t +#include "comms.h" +#include "ui.h" +#include "cmddata.h" +#include "cmdlf.h" +#include "lfdemod.h" +#include "commonutil.h" // num_to_bytes + + int CmdLFViking(const char *Cmd); int demodViking(void); From 61098c77163360468367a13c38d0bc44d677609b Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 14 Sep 2019 22:44:15 +0200 Subject: [PATCH 0705/1854] lf hid sim: use generic FSK sim --- armsrc/lfops.c | 119 ++++++++++--------------------------------------- armsrc/lfops.h | 1 + 2 files changed, 25 insertions(+), 95 deletions(-) diff --git a/armsrc/lfops.c b/armsrc/lfops.c index d032b2236..b546fdc49 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -876,69 +876,6 @@ void SimulateTagLowFrequency(int period, int gap, bool ledcontrol) { #define DEBUG_FRAME_CONTENTS 1 void SimulateTagLowFrequencyBidir(int divisor, int max_bitlen) { } -// compose fc/5 fc/8 waveform (FSK1) - -// compose fc/8 fc/10 waveform (FSK2) -// also manchester, -static void fc(int c, int *n) { - uint8_t *dest = BigBuf_get_addr(); - int idx; - - // for when we want an fc8 pattern every 4 logical bits - if (c == 0) { - dest[((*n)++)] = 1; - dest[((*n)++)] = 1; - dest[((*n)++)] = 1; - dest[((*n)++)] = 1; - dest[((*n)++)] = 0; - dest[((*n)++)] = 0; - dest[((*n)++)] = 0; - dest[((*n)++)] = 0; - } - - // an fc/8 encoded bit is a bit pattern of 11110000 x6 = 48 samples - if (c == 8) { - for (idx = 0; idx < 6; idx++) { - dest[((*n)++)] = 1; - dest[((*n)++)] = 1; - dest[((*n)++)] = 1; - dest[((*n)++)] = 1; - dest[((*n)++)] = 0; - dest[((*n)++)] = 0; - dest[((*n)++)] = 0; - dest[((*n)++)] = 0; - } - } - - // an fc/10 encoded bit is a bit pattern of 1111100000 x5 = 50 samples - if (c == 10) { - for (idx = 0; idx < 5; idx++) { - dest[((*n)++)] = 1; - dest[((*n)++)] = 1; - dest[((*n)++)] = 1; - dest[((*n)++)] = 1; - dest[((*n)++)] = 1; - dest[((*n)++)] = 0; - dest[((*n)++)] = 0; - dest[((*n)++)] = 0; - dest[((*n)++)] = 0; - dest[((*n)++)] = 0; - } - } -} - -// special start of frame marker containing invalid bit sequences -// this one is focused on HID, with manchester encoding. -static void fcSTT(int *n) { - fc(8, n); - fc(8, n); // invalid - fc(8, n); - fc(10, n); // logical 0 - fc(10, n); - fc(10, n); // invalid - fc(8, n); - fc(10, n); // logical 0 -} // compose fc/X fc/Y waveform (FSKx) static void fcAll(uint8_t fc, int *n, uint8_t clock, int16_t *remainder) { @@ -971,10 +908,9 @@ void CmdHIDsimTAGEx(uint32_t hi, uint32_t lo, bool ledcontrol, int numcycles) { return; } - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - set_tracing(false); - - int n = 0, i = 0; + // special start of frame marker containing invalid Manchester bit sequences + uint8_t bits[8+44*2] = { 0, 0, 0, 1, 1, 1, 0, 1 }; + uint16_t n = 8; /* HID tag bitstream format The tag contains a 44bit unique code. This is sent out MSB first in sets of 4 bits @@ -989,42 +925,28 @@ void CmdHIDsimTAGEx(uint32_t hi, uint32_t lo, bool ledcontrol, int numcycles) { bit 0 = fc8 */ - fc(0, &n); - - // special start of frame marker containing invalid bit sequences - fcSTT(&n); - + // TODO isn't there a manchester encoding function already available? // manchester encode bits 43 to 32 - for (i = 11; i >= 0; i--) { - - if ((i % 4) == 3) fc(0, &n); - + for (int i = 11; i >= 0; i--) { if ((hi >> i) & 1) { - fc(10, &n); - fc(8, &n); // low-high transition + bits[n++] = 1; + bits[n++] = 0; } else { - fc(8, &n); - fc(10, &n); // high-low transition + bits[n++] = 0; + bits[n++] = 1; } } - // manchester encode bits 31 to 0 - for (i = 31; i >= 0; i--) { - - if ((i % 4) == 3) fc(0, &n); - + for (int i = 31; i >= 0; i--) { if ((lo >> i) & 1) { - fc(10, &n); - fc(8, &n); // low-high transition + bits[n++] = 1; + bits[n++] = 0; } else { - fc(8, &n); - fc(10, &n); // high-low transition + bits[n++] = 0; + bits[n++] = 1; } } - - if (ledcontrol) LED_A_ON(); - SimulateTagLowFrequencyEx(n, 0, ledcontrol, numcycles); - if (ledcontrol) LED_A_OFF(); + CmdFSKsimTAGEx(10, 8, 0, 50, sizeof(bits), bits, ledcontrol, numcycles); } void CmdHIDsimTAG(uint32_t hi, uint32_t lo, bool ledcontrol) { @@ -1035,7 +957,7 @@ void CmdHIDsimTAG(uint32_t hi, uint32_t lo, bool ledcontrol) { // prepare a waveform pattern in the buffer based on the ID given then // simulate a FSK tag until the button is pressed // arg1 contains fcHigh and fcLow, arg2 contains STT marker and clock -void CmdFSKsimTAG(uint8_t fchigh, uint8_t fclow, uint8_t separator, uint8_t clk, uint16_t bitslen, uint8_t *bits, bool ledcontrol) { +void CmdFSKsimTAGEx(uint8_t fchigh, uint8_t fclow, uint8_t separator, uint8_t clk, uint16_t bitslen, uint8_t *bits, bool ledcontrol, int numcycles) { FpgaDownloadAndGo(FPGA_BITSTREAM_LF); @@ -1064,8 +986,15 @@ void CmdFSKsimTAG(uint8_t fchigh, uint8_t fclow, uint8_t separator, uint8_t clk, Dbprintf("Simulating with fcHigh: %d, fcLow: %d, clk: %d, STT: %d, n: %d", fchigh, fclow, clk, separator, n); if (ledcontrol) LED_A_ON(); - SimulateTagLowFrequency(n, 0, ledcontrol); + SimulateTagLowFrequencyEx(n, 0, ledcontrol, numcycles); if (ledcontrol) LED_A_OFF(); +} + +// prepare a waveform pattern in the buffer based on the ID given then +// simulate a FSK tag until the button is pressed +// arg1 contains fcHigh and fcLow, arg2 contains STT marker and clock +void CmdFSKsimTAG(uint8_t fchigh, uint8_t fclow, uint8_t separator, uint8_t clk, uint16_t bitslen, uint8_t *bits, bool ledcontrol) { + CmdFSKsimTAGEx(fchigh, fclow, separator, clk, bitslen, bits, ledcontrol, -1); reply_ng(CMD_LF_FSK_SIMULATE, PM3_EOPABORTED, NULL, 0); } diff --git a/armsrc/lfops.h b/armsrc/lfops.h index 690f29db3..4f82dfae9 100644 --- a/armsrc/lfops.h +++ b/armsrc/lfops.h @@ -33,6 +33,7 @@ void SimulateTagLowFrequencyBidir(int divisor, int max_bitlen); void CmdHIDsimTAGEx(uint32_t hi, uint32_t lo, bool ledcontrol, int numcycles); void CmdHIDsimTAG(uint32_t hi, uint32_t lo, bool ledcontrol); +void CmdFSKsimTAGEx(uint8_t fchigh, uint8_t fclow, uint8_t separator, uint8_t clk, uint16_t bitslen, uint8_t *bits, bool ledcontrol, int numcycles); void CmdFSKsimTAG(uint8_t fchigh, uint8_t fclow, uint8_t separator, uint8_t clk, uint16_t bitslen, uint8_t *bits, bool ledcontrol); void CmdASKsimTAG(uint8_t encoding, uint8_t invert, uint8_t separator, uint8_t clk, uint16_t size, uint8_t *bits, bool ledcontrol); void CmdPSKsimTag(uint8_t carrier, uint8_t invert, uint8_t clk, uint16_t size, uint8_t *bits, bool ledcontrol); From 47724d0a1b5f98dfc4b402f5964a3bae9f41f743 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 15 Sep 2019 01:13:52 +0200 Subject: [PATCH 0706/1854] textual --- client/cmdlfsecurakey.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/client/cmdlfsecurakey.c b/client/cmdlfsecurakey.c index 0ee22524f..c916478da 100644 --- a/client/cmdlfsecurakey.c +++ b/client/cmdlfsecurakey.c @@ -111,12 +111,22 @@ static int CmdSecurakeyRead(const char *Cmd) { return CmdSecurakeyDemod(Cmd); } +static int CmdSecuraClone(const char *Cmd) { + PrintAndLogEx(INFO, " To be implemented, feel free to contribute!"); + return PM3_SUCCESS; +} + +static int CmdSecureSim(const char *Cmd) { + PrintAndLogEx(INFO, " To be implemented, feel free to contribute!"); + return PM3_SUCCESS; +} + static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, {"demod", CmdSecurakeyDemod, AlwaysAvailable, "Demodulate an Securakey tag from the GraphBuffer"}, {"read", CmdSecurakeyRead, IfPm3Lf, "Attempt to read and extract tag data from the antenna"}, - //{"clone", CmdSecurakeyClone, IfPm3Lf, "clone Securakey tag"}, - //{"sim", CmdSecurakeydSim, IfPm3Lf, "simulate Securakey tag"}, + {"clone", CmdSecurakeyClone, IfPm3Lf, "clone Securakey tag"}, + {"sim", CmdSecurakeydSim, IfPm3Lf, "simulate Securakey tag"}, {NULL, NULL, NULL, NULL} }; From 06809babbbbff155d2e357188e29f5efc7c77f43 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 15 Sep 2019 01:33:54 +0200 Subject: [PATCH 0707/1854] chg: 'lf pyramid clone' - add verification --- client/cmdlfpyramid.c | 30 +++++++++++++----------------- client/cmdlfpyramid.h | 15 +++++++++++++++ client/cmdlfsecurakey.c | 6 +++--- 3 files changed, 31 insertions(+), 20 deletions(-) diff --git a/client/cmdlfpyramid.c b/client/cmdlfpyramid.c index d5c3076a9..90a4ccfde 100644 --- a/client/cmdlfpyramid.c +++ b/client/cmdlfpyramid.c @@ -9,21 +9,6 @@ //----------------------------------------------------------------------------- #include "cmdlfpyramid.h" -#include -#include -#include -#include - -#include "cmdparser.h" // command_t -#include "comms.h" -#include "ui.h" -#include "graph.h" -#include "cmddata.h" -#include "cmdlf.h" -#include "protocols.h" // for T55xx config register definitions -#include "lfdemod.h" // parityTest -#include "crc.h" - static int CmdHelp(const char *Cmd); static int usage_lf_pyramid_clone(void) { @@ -246,12 +231,13 @@ static int CmdPyramidClone(const char *Cmd) { PrintAndLogEx(INFO, "Preparing to clone Farpointe/Pyramid to T55x7 with Facility Code: %u, Card Number: %u", facilitycode, cardnumber); print_blocks(blocks, 5); + uint8_t res = 0; PacketResponseNG resp; // fast push mode conn.block_after_ACK = true; - for (uint8_t i = 0; i < 5; i++) { - if (i == 4) { + for (int8_t i = 4; i >= 0; i--) { + if (i == 0) { // Disable fast mode on last packet conn.block_after_ACK = false; } @@ -267,7 +253,17 @@ static int CmdPyramidClone(const char *Cmd) { PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); return PM3_ETIMEOUT; } + + bool isok = t55xxVerifyWrite(i, 0, false, false, 0, 0, blocks[i]); + if ( isok == false) { + PrintAndLogEx(WARNING, "Couldn't verify write"); + res++; + } } + + if ( res == 0 ) + PrintAndLogEx(SUCCESS, "Success writing to tag"); + return PM3_SUCCESS; } diff --git a/client/cmdlfpyramid.h b/client/cmdlfpyramid.h index 2d717fbb3..0a9e2674a 100644 --- a/client/cmdlfpyramid.h +++ b/client/cmdlfpyramid.h @@ -10,6 +10,21 @@ #define CMDLFPYRAMID_H__ #include "common.h" +#include +#include +#include +#include + +#include "cmdparser.h" // command_t +#include "comms.h" +#include "ui.h" +#include "graph.h" +#include "cmddata.h" +#include "cmdlf.h" +#include "protocols.h" // for T55xx config register definitions +#include "lfdemod.h" // parityTest +#include "crc.h" +#include "cmdlft55xx.h" // verifywrite int CmdLFPyramid(const char *Cmd); diff --git a/client/cmdlfsecurakey.c b/client/cmdlfsecurakey.c index c916478da..e14a679f2 100644 --- a/client/cmdlfsecurakey.c +++ b/client/cmdlfsecurakey.c @@ -111,12 +111,12 @@ static int CmdSecurakeyRead(const char *Cmd) { return CmdSecurakeyDemod(Cmd); } -static int CmdSecuraClone(const char *Cmd) { +static int CmdSecurakeyClone(const char *Cmd) { PrintAndLogEx(INFO, " To be implemented, feel free to contribute!"); return PM3_SUCCESS; } -static int CmdSecureSim(const char *Cmd) { +static int CmdSecurakeySim(const char *Cmd) { PrintAndLogEx(INFO, " To be implemented, feel free to contribute!"); return PM3_SUCCESS; } @@ -126,7 +126,7 @@ static command_t CommandTable[] = { {"demod", CmdSecurakeyDemod, AlwaysAvailable, "Demodulate an Securakey tag from the GraphBuffer"}, {"read", CmdSecurakeyRead, IfPm3Lf, "Attempt to read and extract tag data from the antenna"}, {"clone", CmdSecurakeyClone, IfPm3Lf, "clone Securakey tag"}, - {"sim", CmdSecurakeydSim, IfPm3Lf, "simulate Securakey tag"}, + {"sim", CmdSecurakeySim, IfPm3Lf, "simulate Securakey tag"}, {NULL, NULL, NULL, NULL} }; From 9275304640c1617bbcf4a3cc276c414b7452586d Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 15 Sep 2019 01:16:54 +0200 Subject: [PATCH 0708/1854] lf hid clone: fix some stuff related to long ID, still clone doesn't seem to work --- client/cmdlfhid.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/client/cmdlfhid.c b/client/cmdlfhid.c index 8e22654f4..bfabcc237 100644 --- a/client/cmdlfhid.c +++ b/client/cmdlfhid.c @@ -76,14 +76,14 @@ static int usage_lf_hid_sim(void) { static int usage_lf_hid_clone(void) { PrintAndLogEx(NORMAL, "Clone HID to T55x7. Tag must be on antenna. "); PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Usage: lf hid clone [h] [ID] "); + PrintAndLogEx(NORMAL, "Usage: lf hid clone [h] [l] ID"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h - This help"); + PrintAndLogEx(NORMAL, " l - 84bit ID"); PrintAndLogEx(NORMAL, " ID - HID id"); - PrintAndLogEx(NORMAL, " L - 84bit ID"); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf hid clone 2006ec0c86"); - PrintAndLogEx(NORMAL, " lf hid clone 2006ec0c86 L"); + PrintAndLogEx(NORMAL, " lf hid clone l 2006ec0c86"); return PM3_SUCCESS; } static int usage_lf_hid_brute(void) { @@ -294,6 +294,7 @@ static int CmdHIDClone(const char *Cmd) { if (strlen(Cmd) == 0 || ctmp == 'H' || ctmp == 'h') return usage_lf_hid_clone(); uint8_t longid[1] = {0}; if (strchr(Cmd, 'l') != 0) { + i++; while (sscanf(&Cmd[i++], "%1x", &n) == 1) { hi2 = (hi2 << 4) | (hi >> 28); hi = (hi << 4) | (lo >> 28); From 59e66ce5fd74b61c79fd9a429cc3955744717318 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 15 Sep 2019 01:17:47 +0200 Subject: [PATCH 0709/1854] lf hid sim: add support for long ID --- armsrc/Standalone/lf_hidbrute.c | 6 +- armsrc/Standalone/lf_proxbrute.c | 2 +- armsrc/Standalone/lf_samyrun.c | 2 +- armsrc/appmain.c | 3 +- armsrc/lfops.c | 109 ++++++++++++++++++++++--------- armsrc/lfops.h | 4 +- client/cmdlfhid.c | 31 +++++++-- include/pm3_cmd.h | 8 +++ 8 files changed, 120 insertions(+), 45 deletions(-) diff --git a/armsrc/Standalone/lf_hidbrute.c b/armsrc/Standalone/lf_hidbrute.c index 625459238..48efcf119 100644 --- a/armsrc/Standalone/lf_hidbrute.c +++ b/armsrc/Standalone/lf_hidbrute.c @@ -128,7 +128,7 @@ void RunMod() { WAIT_BUTTON_RELEASED(); Dbprintf("[=] %x %x %08x", selected, high[selected], low[selected]); - CmdHIDsimTAG(high[selected], low[selected], 0); + CmdHIDsimTAG(0, high[selected], low[selected], 0, 0); DbpString("[=] done playing"); if (BUTTON_HELD(1000) > 0) @@ -188,7 +188,7 @@ void RunMod() { // Print actual code to brute Dbprintf("[=] TAG ID: %x%08x (%d) - FC: %u - Card: %u", high[selected], low[selected], (low[selected] >> 1) & 0xFFFF, fc, cardnum); - CmdHIDsimTAGEx(high[selected], low[selected], 1, 50000); + CmdHIDsimTAGEx(0, high[selected], low[selected], 0, 1, 50000); } cardnum = original_cardnum; @@ -216,7 +216,7 @@ void RunMod() { // Print actual code to brute Dbprintf("[=] TAG ID: %x%08x (%d) - FC: %u - Card: %u", high[selected], low[selected], (low[selected] >> 1) & 0xFFFF, fc, cardnum); - CmdHIDsimTAGEx(high[selected], low[selected], 1, 50000); + CmdHIDsimTAGEx(0, high[selected], low[selected], 0, 1, 50000); } DbpString("[=] done bruteforcing"); diff --git a/armsrc/Standalone/lf_proxbrute.c b/armsrc/Standalone/lf_proxbrute.c index 5844dda84..25d62cc2a 100644 --- a/armsrc/Standalone/lf_proxbrute.c +++ b/armsrc/Standalone/lf_proxbrute.c @@ -102,7 +102,7 @@ void RunMod() { Dbprintf("[=] trying Facility = %08x ID %08x", high, i); // high, i, ledcontrol, timelimit 20000 - CmdHIDsimTAGEx(high, i, false, 20000); + CmdHIDsimTAGEx(0, high, i, 0, false, 20000); SpinDelay(100); } diff --git a/armsrc/Standalone/lf_samyrun.c b/armsrc/Standalone/lf_samyrun.c index d56f48e24..4dc45b0b3 100644 --- a/armsrc/Standalone/lf_samyrun.c +++ b/armsrc/Standalone/lf_samyrun.c @@ -108,7 +108,7 @@ void RunMod() { Dbprintf("[=] simulating %x | %x%08x", selected, high[selected], low[selected]); // high, low, no led control(A) no time limit - CmdHIDsimTAGEx(high[selected], low[selected], false, -1); + CmdHIDsimTAGEx(0, high[selected], low[selected], 0, false, -1); DbpString("[=] simulating done"); diff --git a/armsrc/appmain.c b/armsrc/appmain.c index d48b798a5..214e439b0 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -702,7 +702,8 @@ static void PacketReceived(PacketCommandNG *packet) { break; } case CMD_LF_HID_SIMULATE: { - CmdHIDsimTAG(packet->oldarg[0], packet->oldarg[1], 1); + lf_hidsim_t *payload = (lf_hidsim_t *)packet->data.asBytes; + CmdHIDsimTAG(payload->hi2, payload->hi, payload->lo, payload->longFMT, 1); break; } case CMD_LF_FSK_SIMULATE: { diff --git a/armsrc/lfops.c b/armsrc/lfops.c index b546fdc49..ead9966ae 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -901,16 +901,8 @@ static void fcAll(uint8_t fc, int *n, uint8_t clock, int16_t *remainder) { // prepare a waveform pattern in the buffer based on the ID given then // simulate a HID tag until the button is pressed -void CmdHIDsimTAGEx(uint32_t hi, uint32_t lo, bool ledcontrol, int numcycles) { +void CmdHIDsimTAGEx(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT, bool ledcontrol, int numcycles) { - if (hi > 0xFFF) { - DbpString("[!] tags can only have 44 bits. - USE lf simfsk for larger tags"); - return; - } - - // special start of frame marker containing invalid Manchester bit sequences - uint8_t bits[8+44*2] = { 0, 0, 0, 1, 1, 1, 0, 1 }; - uint16_t n = 8; /* HID tag bitstream format The tag contains a 44bit unique code. This is sent out MSB first in sets of 4 bits @@ -925,32 +917,87 @@ void CmdHIDsimTAGEx(uint32_t hi, uint32_t lo, bool ledcontrol, int numcycles) { bit 0 = fc8 */ - // TODO isn't there a manchester encoding function already available? - // manchester encode bits 43 to 32 - for (int i = 11; i >= 0; i--) { - if ((hi >> i) & 1) { - bits[n++] = 1; - bits[n++] = 0; - } else { - bits[n++] = 0; - bits[n++] = 1; + uint8_t bits[8+84*2] = { 0, 0, 0, 1, 1, 1, 0, 1 }; + uint8_t bitlen = 0; + + if (longFMT) { + // Ensure no more than 84 bits supplied + if (hi2 > 0xFFFFF) { + DbpString("Tags can only have 84 bits."); + return; + } + bitlen = 8+84*2; + // special start of frame marker containing invalid Manchester bit sequences + uint16_t n = 8; + hi2 |= 0x9E00000; // 9E: long format identifier + // manchester encode "9E" and bits 83 to 64 + for (int i = 27; i >= 0; i--) { + if ((hi2 >> i) & 1) { + bits[n++] = 1; + bits[n++] = 0; + } else { + bits[n++] = 0; + bits[n++] = 1; + } + } + // manchester encode bits 63 to 32 + for (int i = 31; i >= 0; i--) { + if ((hi >> i) & 1) { + bits[n++] = 1; + bits[n++] = 0; + } else { + bits[n++] = 0; + bits[n++] = 1; + } + } + // manchester encode bits 31 to 0 + for (int i = 31; i >= 0; i--) { + if ((lo >> i) & 1) { + bits[n++] = 1; + bits[n++] = 0; + } else { + bits[n++] = 0; + bits[n++] = 1; + } + } + + } else { + + if (hi > 0xFFF) { + DbpString("[!] tags can only have 44 bits. - USE lf simfsk for larger tags"); + return; + } + + bitlen = 8+44*2; + // special start of frame marker containing invalid Manchester bit sequences + uint16_t n = 8; + + // manchester encode bits 43 to 32 + for (int i = 11; i >= 0; i--) { + if ((hi >> i) & 1) { + bits[n++] = 1; + bits[n++] = 0; + } else { + bits[n++] = 0; + bits[n++] = 1; + } + } + // manchester encode bits 31 to 0 + for (int i = 31; i >= 0; i--) { + if ((lo >> i) & 1) { + bits[n++] = 1; + bits[n++] = 0; + } else { + bits[n++] = 0; + bits[n++] = 1; + } } } - // manchester encode bits 31 to 0 - for (int i = 31; i >= 0; i--) { - if ((lo >> i) & 1) { - bits[n++] = 1; - bits[n++] = 0; - } else { - bits[n++] = 0; - bits[n++] = 1; - } - } - CmdFSKsimTAGEx(10, 8, 0, 50, sizeof(bits), bits, ledcontrol, numcycles); + CmdFSKsimTAGEx(10, 8, 0, 50, bitlen, bits, ledcontrol, numcycles); } -void CmdHIDsimTAG(uint32_t hi, uint32_t lo, bool ledcontrol) { - CmdHIDsimTAGEx(hi, lo, ledcontrol, -1); +void CmdHIDsimTAG(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT, bool ledcontrol) { + CmdHIDsimTAGEx(hi2, hi, lo, longFMT, ledcontrol, -1); reply_ng(CMD_LF_HID_SIMULATE, PM3_EOPABORTED, NULL, 0); } diff --git a/armsrc/lfops.h b/armsrc/lfops.h index 4f82dfae9..99d1b29eb 100644 --- a/armsrc/lfops.h +++ b/armsrc/lfops.h @@ -30,8 +30,8 @@ void SimulateTagLowFrequencyEx(int period, int gap, bool ledcontrol, int numcycl void SimulateTagLowFrequency(int period, int gap, bool ledcontrol); void SimulateTagLowFrequencyBidir(int divisor, int max_bitlen); -void CmdHIDsimTAGEx(uint32_t hi, uint32_t lo, bool ledcontrol, int numcycles); -void CmdHIDsimTAG(uint32_t hi, uint32_t lo, bool ledcontrol); +void CmdHIDsimTAGEx(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT, bool ledcontrol, int numcycles); +void CmdHIDsimTAG(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT, bool ledcontrol); void CmdFSKsimTAGEx(uint8_t fchigh, uint8_t fclow, uint8_t separator, uint8_t clk, uint16_t bitslen, uint8_t *bits, bool ledcontrol, int numcycles); void CmdFSKsimTAG(uint8_t fchigh, uint8_t fclow, uint8_t separator, uint8_t clk, uint16_t bitslen, uint8_t *bits, bool ledcontrol); diff --git a/client/cmdlfhid.c b/client/cmdlfhid.c index bfabcc237..d4d52fa9f 100644 --- a/client/cmdlfhid.c +++ b/client/cmdlfhid.c @@ -261,22 +261,41 @@ static int CmdHIDRead_device(const char *Cmd) { } */ static int CmdHIDSim(const char *Cmd) { - uint32_t hi = 0, lo = 0; + lf_hidsim_t payload; + payload.longFMT = 0; + uint32_t hi2 = 0, hi = 0, lo = 0; uint32_t n = 0, i = 0; uint8_t ctmp = tolower(param_getchar(Cmd, 0)); if (strlen(Cmd) == 0 || ctmp == 'h') return usage_lf_hid_sim(); - while (sscanf(&Cmd[i++], "%1x", &n) == 1) { - hi = (hi << 4) | (lo >> 28); - lo = (lo << 4) | (n & 0xf); + if (strchr(Cmd, 'l') != 0) { + i++; + while (sscanf(&Cmd[i++], "%1x", &n) == 1) { + hi2 = (hi2 << 4) | (hi >> 28); + hi = (hi << 4) | (lo >> 28); + lo = (lo << 4) | (n & 0xf); + } + + PrintAndLogEx(INFO, "Simulating HID tag with long ID %x%08x%08x", hi2, hi, lo); + payload.longFMT = 1; + } else { + while (sscanf(&Cmd[i++], "%1x", &n) == 1) { + hi = (hi << 4) | (lo >> 28); + lo = (lo << 4) | (n & 0xf); + } + PrintAndLogEx(SUCCESS, "Simulating HID tag with ID %x%08x", hi, lo); + hi2 = 0; } - PrintAndLogEx(SUCCESS, "Simulating HID tag with ID %x%08x", hi, lo); PrintAndLogEx(SUCCESS, "Press pm3-button to abort simulation"); + payload.hi2 = hi2; + payload.hi = hi; + payload.lo = lo; + clearCommandBuffer(); - SendCommandMIX(CMD_LF_HID_SIMULATE, hi, lo, 0, NULL, 0); + SendCommandNG(CMD_LF_HID_SIMULATE, (uint8_t *)&payload, sizeof(payload)); PacketResponseNG resp; WaitForResponse(CMD_LF_HID_SIMULATE, &resp); PrintAndLogEx(INFO, "Done"); diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index e87e8bc33..d79433fcf 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -197,6 +197,14 @@ typedef struct { uint8_t flags; } PACKED t55xx_write_block_t; +// For CMD_LF_HID_SIMULATE (FSK) +typedef struct { + uint32_t hi2; + uint32_t hi; + uint32_t lo; + uint8_t longFMT; +} PACKED lf_hidsim_t; + // For CMD_LF_FSK_SIMULATE (FSK) typedef struct { uint8_t fchigh; From 359399b2e69cc591c4d4e4440dc68bb9ecc17284 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 15 Sep 2019 02:01:53 +0200 Subject: [PATCH 0710/1854] fix hid sim long id length --- armsrc/lfops.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/armsrc/lfops.c b/armsrc/lfops.c index ead9966ae..ba3b6e865 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -917,7 +917,7 @@ void CmdHIDsimTAGEx(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT, boo bit 0 = fc8 */ - uint8_t bits[8+84*2] = { 0, 0, 0, 1, 1, 1, 0, 1 }; + uint8_t bits[8+8*2+84*2] = { 0, 0, 0, 1, 1, 1, 0, 1 }; uint8_t bitlen = 0; if (longFMT) { @@ -926,7 +926,7 @@ void CmdHIDsimTAGEx(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT, boo DbpString("Tags can only have 84 bits."); return; } - bitlen = 8+84*2; + bitlen = 8+8*2+84*2; // special start of frame marker containing invalid Manchester bit sequences uint16_t n = 8; hi2 |= 0x9E00000; // 9E: long format identifier From 960d8c4db303fac550217b395381c642f2493950 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 15 Sep 2019 02:09:40 +0200 Subject: [PATCH 0711/1854] add helper fct manchesterEncodeUint32 --- armsrc/lfops.c | 64 ++++++------------------------------------------ common/lfdemod.c | 12 +++++++++ common/lfdemod.h | 1 + 3 files changed, 20 insertions(+), 57 deletions(-) diff --git a/armsrc/lfops.c b/armsrc/lfops.c index ba3b6e865..47c8011f8 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -917,8 +917,10 @@ void CmdHIDsimTAGEx(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT, boo bit 0 = fc8 */ + // special start of frame marker containing invalid Manchester bit sequences uint8_t bits[8+8*2+84*2] = { 0, 0, 0, 1, 1, 1, 0, 1 }; uint8_t bitlen = 0; + uint16_t n = 8; if (longFMT) { // Ensure no more than 84 bits supplied @@ -927,71 +929,19 @@ void CmdHIDsimTAGEx(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT, boo return; } bitlen = 8+8*2+84*2; - // special start of frame marker containing invalid Manchester bit sequences - uint16_t n = 8; hi2 |= 0x9E00000; // 9E: long format identifier - // manchester encode "9E" and bits 83 to 64 - for (int i = 27; i >= 0; i--) { - if ((hi2 >> i) & 1) { - bits[n++] = 1; - bits[n++] = 0; - } else { - bits[n++] = 0; - bits[n++] = 1; - } - } - // manchester encode bits 63 to 32 - for (int i = 31; i >= 0; i--) { - if ((hi >> i) & 1) { - bits[n++] = 1; - bits[n++] = 0; - } else { - bits[n++] = 0; - bits[n++] = 1; - } - } - // manchester encode bits 31 to 0 - for (int i = 31; i >= 0; i--) { - if ((lo >> i) & 1) { - bits[n++] = 1; - bits[n++] = 0; - } else { - bits[n++] = 0; - bits[n++] = 1; - } - } - + manchesterEncodeUint32(hi2, 16+12, bits, &n); + manchesterEncodeUint32(hi, 32, bits, &n); + manchesterEncodeUint32(lo, 32, bits, &n); } else { if (hi > 0xFFF) { DbpString("[!] tags can only have 44 bits. - USE lf simfsk for larger tags"); return; } - bitlen = 8+44*2; - // special start of frame marker containing invalid Manchester bit sequences - uint16_t n = 8; - - // manchester encode bits 43 to 32 - for (int i = 11; i >= 0; i--) { - if ((hi >> i) & 1) { - bits[n++] = 1; - bits[n++] = 0; - } else { - bits[n++] = 0; - bits[n++] = 1; - } - } - // manchester encode bits 31 to 0 - for (int i = 31; i >= 0; i--) { - if ((lo >> i) & 1) { - bits[n++] = 1; - bits[n++] = 0; - } else { - bits[n++] = 0; - bits[n++] = 1; - } - } + manchesterEncodeUint32(hi, 12, bits, &n); + manchesterEncodeUint32(lo, 32, bits, &n); } CmdFSKsimTAGEx(10, 8, 0, 50, bitlen, bits, ledcontrol, numcycles); } diff --git a/common/lfdemod.c b/common/lfdemod.c index b0b30a1c8..8e60eda0d 100644 --- a/common/lfdemod.c +++ b/common/lfdemod.c @@ -419,6 +419,18 @@ uint32_t manchesterEncode2Bytes(uint16_t datain) { return output; } +void manchesterEncodeUint32(uint32_t data_in, uint8_t bitlen_in, uint8_t *bits_out, uint16_t *index) { + for (int i = bitlen_in - 1; i >= 0; i--) { + if ((data_in >> i) & 1) { + bits_out[(*index)++] = 1; + bits_out[(*index)++] = 0; + } else { + bits_out[(*index)++] = 0; + bits_out[(*index)++] = 1; + } + } +} + //by marshmellow //encode binary data into binary manchester //NOTE: bitstream must have triple the size of "size" available in memory to do the swap diff --git a/common/lfdemod.h b/common/lfdemod.h index 50d769c6b..58ebd72c9 100644 --- a/common/lfdemod.h +++ b/common/lfdemod.h @@ -61,6 +61,7 @@ size_t fskdemod(uint8_t *dest, size_t size, uint8_t rfLen, uint8_t invert, uin //void getHiLo(uint8_t *bits, size_t size, int *high, int *low, uint8_t fuzzHi, uint8_t fuzzLo); void getHiLo(int *high, int *low, uint8_t fuzzHi, uint8_t fuzzLo); uint32_t manchesterEncode2Bytes(uint16_t datain); +void manchesterEncodeUint32(uint32_t data_in, uint8_t bitlen_in, uint8_t *bits_out, uint16_t *index); int ManchesterEncode(uint8_t *bits, size_t size); uint16_t manrawdecode(uint8_t *bits, size_t *size, uint8_t invert, uint8_t *alignPos); int nrzRawDemod(uint8_t *dest, size_t *size, int *clk, int *invert, int *startIdx); From 44cb67c49b16e4d9d1085436457c025aabf9a2d0 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 15 Sep 2019 20:27:50 +0200 Subject: [PATCH 0712/1854] adjusting write validation to only print when successful in validating. Otherwise like old times. silence. --- client/cmdlfpresco.c | 29 ++++++++++++++++------------- client/cmdlfpresco.h | 14 ++++++++++++++ client/cmdlfpyramid.c | 14 ++++++++------ client/cmdlfvisa2000.c | 13 +++++++------ 4 files changed, 45 insertions(+), 25 deletions(-) diff --git a/client/cmdlfpresco.c b/client/cmdlfpresco.c index 14d87648e..a9c74d9ac 100644 --- a/client/cmdlfpresco.c +++ b/client/cmdlfpresco.c @@ -9,19 +9,6 @@ #include "cmdlfpresco.h" -#include -#include -#include -#include - -#include "cmdparser.h" // command_t -#include "comms.h" -#include "ui.h" -#include "cmddata.h" -#include "cmdlf.h" -#include "protocols.h" // for T55xx config register definitions -#include "lfdemod.h" // parityTest - static int CmdHelp(const char *Cmd); static int usage_lf_presco_clone(void) { @@ -134,6 +121,7 @@ static int CmdPrescoClone(const char *Cmd) { PrintAndLogEx(INFO, "Preparing to clone Presco to T55x7 with SiteCode: %u, UserCode: %u, FullCode: %08x", sitecode, usercode, fullcode); print_blocks(blocks, 5); + uint8_t res = 0; PacketResponseNG resp; // fast push mode @@ -155,7 +143,22 @@ static int CmdPrescoClone(const char *Cmd) { PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); return PM3_ETIMEOUT; } + + // write block0, needs a detect. + if (i == 0) { + printf("enter detect "); + bool ok = t55xxAquireAndDetect(false, 0, blocks[i], false); + printf(" b0 = '%c' \n", (ok) ? 'Y':'N'); + } + if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) { + res++; + printf(" i = %d \n", i); + } } + + if ( res == 0 ) + PrintAndLogEx(SUCCESS, "Success writing to tag"); + return PM3_SUCCESS; } diff --git a/client/cmdlfpresco.h b/client/cmdlfpresco.h index 098a98342..8f7c7eb31 100644 --- a/client/cmdlfpresco.h +++ b/client/cmdlfpresco.h @@ -11,6 +11,20 @@ #include "common.h" +#include +#include +#include +#include + +#include "cmdparser.h" // command_t +#include "comms.h" +#include "ui.h" +#include "cmddata.h" +#include "cmdlf.h" +#include "protocols.h" // for T55xx config register definitions +#include "lfdemod.h" // parityTest +#include "cmdlft55xx.h" // verifywrite + int CmdLFPresco(const char *Cmd); int demodPresco(void); diff --git a/client/cmdlfpyramid.c b/client/cmdlfpyramid.c index 90a4ccfde..d0f116bf4 100644 --- a/client/cmdlfpyramid.c +++ b/client/cmdlfpyramid.c @@ -236,8 +236,8 @@ static int CmdPyramidClone(const char *Cmd) { // fast push mode conn.block_after_ACK = true; - for (int8_t i = 4; i >= 0; i--) { - if (i == 0) { + for (int8_t i = 0; i < 5; i++) { + if (i == 4) { // Disable fast mode on last packet conn.block_after_ACK = false; } @@ -254,11 +254,13 @@ static int CmdPyramidClone(const char *Cmd) { return PM3_ETIMEOUT; } - bool isok = t55xxVerifyWrite(i, 0, false, false, 0, 0, blocks[i]); - if ( isok == false) { - PrintAndLogEx(WARNING, "Couldn't verify write"); + // write block0, needs a detect. + if (i == 0) + t55xxAquireAndDetect(false, 0, blocks[i], false); + + if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) res++; - } + } if ( res == 0 ) diff --git a/client/cmdlfvisa2000.c b/client/cmdlfvisa2000.c index 1433ced01..51cedb925 100644 --- a/client/cmdlfvisa2000.c +++ b/client/cmdlfvisa2000.c @@ -168,7 +168,6 @@ static int CmdVisa2kClone(const char *Cmd) { print_blocks(blocks, 4); uint8_t res = 0; - PacketResponseNG resp; // fast push mode @@ -190,14 +189,16 @@ static int CmdVisa2kClone(const char *Cmd) { PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); return PM3_ETIMEOUT; - } + } + + // write block0, needs a detect. + if (i == 0) + t55xxAquireAndDetect(false, 0, blocks[i], false); - bool isok = t55xxVerifyWrite(i, 0, false, false, 0, 0, blocks[i]); - if ( isok == false) { - PrintAndLogEx(WARNING, "Couldn't verify write"); + if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) res++; - } } + if ( res == 0 ) PrintAndLogEx(SUCCESS, "Success writing to tag"); From a933eb4f9ed259ddd7877c3330e684c498d437eb Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 15 Sep 2019 20:30:05 +0200 Subject: [PATCH 0713/1854] adjusting beahavior for auto detection --- client/cmdlft55xx.c | 105 +++++++++++++++++++++++++------------------- client/cmdlft55xx.h | 2 + 2 files changed, 61 insertions(+), 46 deletions(-) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 5575ef80e..73932f19a 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -405,9 +405,29 @@ static bool t55xxProtect(bool lock, bool usepwd, uint8_t override, uint32_t pass } } +bool t55xxAquireAndDetect(bool usepwd, uint32_t password, uint32_t known_block0, bool verbose) { + + if (verbose) + PrintAndLogEx(INFO, "Block0 write detected, running `detect` to see if validation is possible"); + + for ( uint8_t m = 0; m < 4; m++) { + if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, m) == false) + continue; + + if (tryDetectModulationEx(m, verbose, known_block0) == false) + continue; + + return true; + } + return false; +} + bool t55xxVerifyWrite(uint8_t block, bool page1, bool usepwd, uint8_t override, uint32_t password, uint8_t downlink_mode, uint32_t data) { uint32_t read_data = 0; + + if (downlink_mode == 0xFF) + downlink_mode = config.downlink_mode; int res = T55xxReadBlockEx(block, page1, usepwd, override, password, downlink_mode, false); if (res == PM3_SUCCESS) { @@ -421,29 +441,10 @@ bool t55xxVerifyWrite(uint8_t block, bool page1, bool usepwd, uint8_t override, // this messes up with ppls config.. if (block == 0 && page1 == false) { - - PrintAndLogEx(INFO, "Block0 write detected, running `detect` to see if validation is possible"); - bool got_modulation = false; - for ( uint8_t m = 0; m < 4; m++) { - - if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, m) == false) { - continue; - } - - if (tryDetectModulation(m, false) == false) { - PrintAndLogEx(INPLACE, "."); - continue; - } else { - got_modulation = true; - break; - } - } - PrintAndLogEx(NORMAL, ""); - - if (got_modulation == false) + if (t55xxAquireAndDetect(usepwd, password, data, true) == false) return false; - - return t55xxVerifyWrite(block, page1, usepwd, 2, password, downlink_mode, data); + + return t55xxVerifyWrite(block, page1, usepwd, 2, password, config.downlink_mode, data); } } @@ -892,22 +893,25 @@ static int CmdT55xxDetect(const char *Cmd) { if (useGB == false) { - //ICEMAN STRANGE - for (uint8_t m = downlink_mode; m < 4; m++) { - if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, m) == false) { - continue; - } + if ( try_all_dl_modes ) { + + for (uint8_t m = downlink_mode; m < 4; m++) { + if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, m) == false) + continue; + + if (tryDetectModulation(m, T55XX_PrintConfig) == false) + continue; - if (tryDetectModulation(m, T55XX_PrintConfig)) { - m = 4; found = true; - } else { - found = false; - } + break; + } + } else { - if (try_all_dl_modes == false) - m = 4; + if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, downlink_mode)) { + found = tryDetectModulation(downlink_mode, T55XX_PrintConfig); + } } + } else { found = tryDetectModulation(downlink_mode, T55XX_PrintConfig); } @@ -920,6 +924,10 @@ static int CmdT55xxDetect(const char *Cmd) { // detect configuration? bool tryDetectModulation(uint8_t downlink_mode, bool print_config) { + return tryDetectModulationEx(downlink_mode, print_config, 0); +} + +bool tryDetectModulationEx(uint8_t downlink_mode, bool print_config, uint32_t wanted_conf) { t55xx_conf_block_t tests[15]; int bitRate = 0, clk = 0, firstClockEdge = 0; @@ -1102,8 +1110,13 @@ bool tryDetectModulation(uint8_t downlink_mode, bool print_config) { if (hits > 1) { PrintAndLogEx(SUCCESS, "Found [%d] possible matches for modulation.", hits); for (int i = 0; i < hits; ++i) { + + bool wanted = false; + if (wanted_conf > 0) + wanted = (wanted_conf == tests[i].block0); + retval = testKnownConfigBlock(tests[i].block0); - if (retval) { + if (retval || wanted ) { PrintAndLogEx(NORMAL, "--[%d]--------------- << selected this", i + 1); config.modulation = tests[i].modulation; config.bitrate = tests[i].bitrate; @@ -2918,16 +2931,16 @@ bool tryDetectP1(bool getData) { } // does this need to be a callable command? static int CmdT55xxDetectPage1(const char *Cmd) { - bool errors = false; - bool useGB = false; - bool usepwd = false; - bool try_all_dl_modes = true; - bool found = false; - uint8_t found_mode = 0; - uint32_t password = 0; - uint8_t cmdp = 0; - uint8_t downlink_mode = 0; - uint8_t dl_mode = 0; + bool errors = false; + bool useGB = false; + bool usepwd = false; + bool try_all_dl_modes = true; + bool found = false; + uint8_t found_mode = 0; + uint32_t password = 0; + uint8_t cmdp = 0; + uint8_t downlink_mode = config.downlink_mode; + uint8_t dl_mode = 0; while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { @@ -3111,7 +3124,7 @@ static int CmdT55xxProtect(const char *Cmd) { uint32_t password = 0, new_password = 0; uint8_t override = 0; uint8_t cmdp = 0; - uint8_t downlink_mode = 0; + uint8_t downlink_mode = config.downlink_mode; while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { diff --git a/client/cmdlft55xx.h b/client/cmdlft55xx.h index 129a6cf5e..f388a39af 100644 --- a/client/cmdlft55xx.h +++ b/client/cmdlft55xx.h @@ -143,6 +143,7 @@ void printT5xxHeader(uint8_t page); void printT55xxBlock(uint8_t blockNum); int printConfiguration(t55xx_conf_block_t b); +bool t55xxAquireAndDetect(bool usepwd, uint32_t password, uint32_t known_block0, bool verbose); bool t55xxVerifyWrite( uint8_t block, bool page1, bool usepwd, uint8_t override, uint32_t password, uint8_t downlink_mode, uint32_t data); int T55xxReadBlock(uint8_t block, bool page1, bool usepwd, uint8_t override, uint32_t password, uint8_t downlink_mode); int T55xxReadBlockEx(uint8_t block, bool page1, bool usepwd, uint8_t override, uint32_t password, uint8_t downlink_mode, bool verbose); @@ -152,6 +153,7 @@ int t55xxWrite(uint8_t block, bool page1, bool usepwd, bool testMode, uint32_t p bool GetT55xxBlockData(uint32_t *blockdata); bool DecodeT55xxBlock(void); bool tryDetectModulation(uint8_t downlink_mode, bool print_config); +bool tryDetectModulationEx(uint8_t downlink_mode, bool print_config, uint32_t wanted_conf); bool testKnownConfigBlock(uint32_t block0); bool tryDetectP1(bool getData); From 19bdfd25773edf061d13b6e6ed6c477861833fd0 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 15 Sep 2019 20:46:21 +0200 Subject: [PATCH 0714/1854] chg some printing of blocks --- client/cmdlft55xx.c | 8 ++++---- client/util.c | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 73932f19a..1afa169c9 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -486,9 +486,9 @@ int t55xxWrite(uint8_t block, bool page1, bool usepwd, bool testMode, uint32_t p } void printT5xxHeader(uint8_t page) { - PrintAndLogEx(NORMAL, "Reading Page %d:", page); - PrintAndLogEx(NORMAL, "blk | hex data | binary | ascii"); - PrintAndLogEx(NORMAL, "----+----------+----------------------------------+-------"); + PrintAndLogEx(SUCCESS, "Reading Page %d:", page); + PrintAndLogEx(SUCCESS, "blk | hex data | binary | ascii"); + PrintAndLogEx(SUCCESS, "----+----------+----------------------------------+-------"); } static int CmdT55xxSetConfig(const char *Cmd) { @@ -1185,7 +1185,7 @@ void printT55xxBlock(uint8_t blockNum) { num_to_bytes(blockData, 4, bytes); - PrintAndLogEx(NORMAL, " %02d | %08X | %s | %s", blockNum, blockData, sprint_bin(DemodBuffer + config.offset, 32), sprint_ascii(bytes, 4)); + PrintAndLogEx(SUCCESS, " %02d | %08X | %s | %s", blockNum, blockData, sprint_bin(DemodBuffer + config.offset, 32), sprint_ascii(bytes, 4)); } static bool testModulation(uint8_t mode, uint8_t modread) { diff --git a/client/util.c b/client/util.c index 1f5a29781..6877e8835 100644 --- a/client/util.c +++ b/client/util.c @@ -383,14 +383,14 @@ char *sprint_ascii(const uint8_t *data, const size_t len) { } void print_blocks(uint32_t *data, size_t len) { - PrintAndLogEx(NORMAL, "Blk | Data "); - PrintAndLogEx(NORMAL, "----+------------"); + PrintAndLogEx(SUCCESS, "Blk | Data "); + PrintAndLogEx(SUCCESS, "----+------------"); if (!data) { PrintAndLogEx(ERR, "..empty data"); } else { for (uint8_t i = 0; i < len; i++) - PrintAndLogEx(NORMAL, "%02d | 0x%08X", i, data[i]); + PrintAndLogEx(SUCCESS, " %02d | 0x%08X", i, data[i]); } } From c2f3e4b2f3439292a9540832001805205d597f23 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 15 Sep 2019 20:51:23 +0200 Subject: [PATCH 0715/1854] encourage.. --- client/cmdlfpac.c | 28 ++++++++++++++++++---------- client/cmdlfpac.h | 6 ++++++ client/cmdlfparadox.c | 6 +++++- 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/client/cmdlfpac.c b/client/cmdlfpac.c index 864506089..6ea0af7d6 100644 --- a/client/cmdlfpac.c +++ b/client/cmdlfpac.c @@ -9,13 +9,6 @@ //----------------------------------------------------------------------------- #include "cmdlfpac.h" -#include "cmdparser.h" // command_t -#include "comms.h" -#include "ui.h" -#include "cmddata.h" -#include "cmdlf.h" -#include "lfdemod.h" // preamble test - static int CmdHelp(const char *Cmd); //see NRZDemod for what args are accepted @@ -63,10 +56,25 @@ static int CmdPacRead(const char *Cmd) { return CmdPacDemod(Cmd); } +static int CmdPacClone(const char *Cmd) { + // possible to raw hex and clone + PrintAndLogEx(INFO, " To be implemented, feel free to contribute!"); + return PM3_SUCCESS; +} + +static int CmdPacSim(const char *Cmd) { + + // NRZ sim. + PrintAndLogEx(INFO, " To be implemented, feel free to contribute!"); + return PM3_SUCCESS; +} + static command_t CommandTable[] = { - {"help", CmdHelp, AlwaysAvailable, "This help"}, - {"demod", CmdPacDemod, AlwaysAvailable, "Demodulate an PAC tag from the GraphBuffer"}, - {"read", CmdPacRead, IfPm3Lf, "Attempt to read and extract tag data from the antenna"}, + {"help", CmdHelp, AlwaysAvailable, "This help"}, + {"demod", CmdPacDemod, AlwaysAvailable, "Demodulate an PAC tag from the GraphBuffer"}, + {"read", CmdPacRead, IfPm3Lf, "Attempt to read and extract tag data from the antenna"}, + {"clone", CmdPacClone, IfPm3Lf, "clone PAC tag"}, + {"sim", CmdPacSim, IfPm3Lf, "simulate PAC tag"}, {NULL, NULL, NULL, NULL} }; diff --git a/client/cmdlfpac.h b/client/cmdlfpac.h index 3c9c4fbda..edb05b7a5 100644 --- a/client/cmdlfpac.h +++ b/client/cmdlfpac.h @@ -10,6 +10,12 @@ #define CMDLFPAC_H__ #include "common.h" +#include "cmdparser.h" // command_t +#include "comms.h" +#include "ui.h" +#include "cmddata.h" +#include "cmdlf.h" +#include "lfdemod.h" // preamble test int CmdLFPac(const char *Cmd); diff --git a/client/cmdlfparadox.c b/client/cmdlfparadox.c index 4cb0d484f..440f47ced 100644 --- a/client/cmdlfparadox.c +++ b/client/cmdlfparadox.c @@ -112,6 +112,10 @@ static int CmdParadoxRead(const char *Cmd) { return CmdParadoxDemod(Cmd); } +static int CmdParadoxClone(const char *Cmd) { + PrintAndLogEx(INFO, " To be implemented, feel free to contribute!"); + return PM3_SUCCESS; +} static int CmdParadoxSim(const char *Cmd) { PrintAndLogEx(INFO, " To be implemented, feel free to contribute!"); @@ -165,7 +169,7 @@ static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, {"demod", CmdParadoxDemod, AlwaysAvailable, "Demodulate a Paradox FSK tag from the GraphBuffer"}, {"read", CmdParadoxRead, IfPm3Lf, "Attempt to read and Extract tag data from the antenna"}, -// {"clone", CmdParadoxClone, IfPm3Lf, "clone paradox tag"}, + {"clone", CmdParadoxClone, IfPm3Lf, "clone paradox tag"}, {"sim", CmdParadoxSim, IfPm3Lf, "simulate paradox tag"}, {NULL, NULL, NULL, NULL} }; From 75f4a08f5392a4b7b0647b5a8b19fe971695c91e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 15 Sep 2019 20:56:43 +0200 Subject: [PATCH 0716/1854] chg 'lf noralsy clone' - uses verifywrite --- client/cmdlfnoralsy.c | 27 ++++++++++++++------------- client/cmdlfnoralsy.h | 13 +++++++++++++ 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/client/cmdlfnoralsy.c b/client/cmdlfnoralsy.c index cc1db82ca..146c6b350 100644 --- a/client/cmdlfnoralsy.c +++ b/client/cmdlfnoralsy.c @@ -9,18 +9,6 @@ //----------------------------------------------------------------------------- #include "cmdlfnoralsy.h" -#include -#include -#include - -#include "cmdparser.h" // command_t -#include "comms.h" -#include "ui.h" -#include "cmddata.h" -#include "cmdlf.h" -#include "protocols.h" // for T55xx config register definitions -#include "lfdemod.h" // parityTest - static int CmdHelp(const char *Cmd); static int usage_lf_noralsy_clone(void) { @@ -150,7 +138,7 @@ static int CmdNoralsyClone(const char *Cmd) { year = param_get32ex(Cmd, 1, 2000, 10); //Q5 - if (param_getchar(Cmd, 2) == 'Q' || param_getchar(Cmd, 2) == 'q') + if (tolower(param_getchar(Cmd, 2) == 'q')) blocks[0] = T5555_MODULATION_MANCHESTER | T5555_SET_BITRATE(32) | T5555_ST_TERMINATOR | 3 << T5555_MAXBLOCK_SHIFT; if (getnoralsyBits(id, year, bits) != PM3_SUCCESS) { @@ -166,6 +154,7 @@ static int CmdNoralsyClone(const char *Cmd) { PrintAndLogEx(INFO, "Preparing to clone Noralsy to T55x7 with CardId: %u", id); print_blocks(blocks, 4); + uint8_t res = 0; PacketResponseNG resp; // fast push mode @@ -187,7 +176,19 @@ static int CmdNoralsyClone(const char *Cmd) { PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); return PM3_ETIMEOUT; } + + // write block0, needs a detect. + if (i == 0) + t55xxAquireAndDetect(false, 0, blocks[i], false); + + if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) + res++; + } + + if ( res == 0 ) + PrintAndLogEx(SUCCESS, "Success writing to tag"); + return PM3_SUCCESS; } diff --git a/client/cmdlfnoralsy.h b/client/cmdlfnoralsy.h index f76accab7..56ae31372 100644 --- a/client/cmdlfnoralsy.h +++ b/client/cmdlfnoralsy.h @@ -11,6 +11,19 @@ #include "common.h" +#include +#include +#include + +#include "cmdparser.h" // command_t +#include "comms.h" +#include "ui.h" +#include "cmddata.h" +#include "cmdlf.h" +#include "protocols.h" // for T55xx config register definitions +#include "lfdemod.h" // parityTest +#include "cmdlft55xx.h" // verifywrite + int CmdLFNoralsy(const char *Cmd); int demodNoralsy(void); From 8ba2f5b06ce3fc8a6bc0840bc9adbc24d42ec304 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 15 Sep 2019 21:00:38 +0200 Subject: [PATCH 0717/1854] encourage --- client/cmdlfnexwatch.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/client/cmdlfnexwatch.c b/client/cmdlfnexwatch.c index bad9dea4f..5a5e127b1 100644 --- a/client/cmdlfnexwatch.c +++ b/client/cmdlfnexwatch.c @@ -81,10 +81,25 @@ static int CmdNexWatchRead(const char *Cmd) { return CmdNexWatchDemod(Cmd); } +static int CmdNexWatchClone(const char *Cmd) { + + // should be able to clone the raw hex. + PrintAndLogEx(INFO, " To be implemented, feel free to contribute!"); + return PM3_SUCCESS; +} + +static int CmdNexWatchSim(const char *Cmd) { + PrintAndLogEx(INFO, " To be implemented, feel free to contribute!"); + return PM3_SUCCESS; +} + + static command_t CommandTable[] = { - {"help", CmdHelp, AlwaysAvailable, "This help"}, - {"demod", CmdNexWatchDemod, AlwaysAvailable, "Demodulate a NexWatch tag (nexkey, quadrakey) from the GraphBuffer"}, - {"read", CmdNexWatchRead, IfPm3Lf, "Attempt to Read and Extract tag data from the antenna"}, + {"help", CmdHelp, AlwaysAvailable, "This help"}, + {"demod", CmdNexWatchDemod, AlwaysAvailable, "Demodulate a NexWatch tag (nexkey, quadrakey) from the GraphBuffer"}, + {"read", CmdNexWatchRead, IfPm3Lf, "Attempt to Read and Extract tag data from the antenna"}, + {"clone", CmdNexWatchClone, IfPm3Lf, "clone NexWatch tag"}, + {"sim", CmdNexWatchSim, IfPm3Lf, "simulate NexWatch tag"}, {NULL, NULL, NULL, NULL} }; From 775394ae583a6e9354454530d12c7f48ea7465cc Mon Sep 17 00:00:00 2001 From: Iceman Date: Mon, 16 Sep 2019 10:21:18 +0200 Subject: [PATCH 0718/1854] Update appmain.c yet again some my unreleased stuff snuck in.. --- armsrc/appmain.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 214e439b0..058a4709e 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1223,11 +1223,7 @@ static void PacketReceived(PacketCommandNG *packet) { break; } case CMD_HF_ICLASS_READER: { - struct p { - uint8_t flags; - } PACKED; - struct p *payload = (struct p *)packet->data.asBytes; - ReaderIClass(payload->flags); + ReaderIClass(packet->oldarg[0]); break; } case CMD_HF_ICLASS_REPLAY: { From e8ef0fe263d48a7dcc506d7e6f95e93c8a731403 Mon Sep 17 00:00:00 2001 From: mwalker33 Date: Mon, 16 Sep 2019 19:01:40 +1000 Subject: [PATCH 0719/1854] Update cmdlft55xx.c --- client/cmdlft55xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 1afa169c9..c49fa037d 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -1391,7 +1391,7 @@ int printConfiguration(t55xx_conf_block_t b) { PrintAndLogEx(NORMAL, " Offset : %d", b.offset); PrintAndLogEx(NORMAL, " Seq. Term. : %s", (b.ST) ? _GREEN_("Yes") : "No"); PrintAndLogEx(NORMAL, " Block0 : 0x%08X", b.block0); - PrintAndLogEx(NORMAL, " Downling Mode : %s", GetDownlinkModeStr (b.downlink_mode)); + PrintAndLogEx(NORMAL, " Downlink Mode : %s", GetDownlinkModeStr (b.downlink_mode)); PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } From 3726df62a485447b8971ba7d262defc5c3765847 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 16 Sep 2019 11:11:54 +0200 Subject: [PATCH 0720/1854] chg: enhanced verify t55xx write. We set config to the cloned block0, whats left is to identify the offset, which we try to do. --- client/cmdlfawid.c | 15 ++++++++ client/cmdlffdx.c | 15 ++++++++ client/cmdlfguard.c | 15 ++++++++ client/cmdlfindala.c | 24 ++++++------ client/cmdlfjablotron.c | 15 ++++++++ client/cmdlfkeri.c | 14 +++++++ client/cmdlfnedap.c | 35 +++++++++--------- client/cmdlfnedap.h | 13 +++++++ client/cmdlfnoralsy.c | 9 +++-- client/cmdlfpresco.c | 13 +++---- client/cmdlfpyramid.c | 8 ++-- client/cmdlft55xx.c | 82 ++++++++++++++++++++++++++++++----------- client/cmdlft55xx.h | 3 ++ client/cmdlfvisa2000.c | 10 +++-- 14 files changed, 202 insertions(+), 69 deletions(-) diff --git a/client/cmdlfawid.c b/client/cmdlfawid.c index 2360906a4..934335c64 100644 --- a/client/cmdlfawid.c +++ b/client/cmdlfawid.c @@ -26,6 +26,7 @@ #include "cmdlf.h" // lf read #include "protocols.h" // for T55xx config register definitions #include "util_posix.h" +#include "cmdlft55xx.h" // verifywrite static int CmdHelp(const char *Cmd); /* @@ -414,6 +415,7 @@ static int CmdAWIDClone(const char *Cmd) { PrintAndLogEx(INFO, "Preparing to clone AWID %u to T55x7 with FC: %u, CN: %u", fmtlen, fc, cn); print_blocks(blocks, 4); + uint8_t res = 0; PacketResponseNG resp; // fast push mode @@ -437,7 +439,20 @@ static int CmdAWIDClone(const char *Cmd) { PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); return PM3_ETIMEOUT; } + + if (i == 0) { + SetConfigWithBlock0(blocks[0]); + if ( t55xxAquireAndCompareBlock0(false, 0, blocks[0], false) ) + continue; + } + + if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) + res++; } + + if ( res == 0 ) + PrintAndLogEx(SUCCESS, "Success writing to tag"); + return PM3_SUCCESS; } diff --git a/client/cmdlffdx.c b/client/cmdlffdx.c index 2e48918fb..233783b33 100644 --- a/client/cmdlffdx.c +++ b/client/cmdlffdx.c @@ -24,6 +24,7 @@ #include "crc16.h" // for checksum crc-16_ccitt #include "protocols.h" // for T55xx config register definitions #include "lfdemod.h" // parityTest +#include "cmdlft55xx.h" // verifywrite /* FDX-B ISO11784/85 demod (aka animal tag) BIPHASE, inverted, rf/32, with preamble of 00000000001 (128bits) @@ -296,6 +297,7 @@ static int CmdFdxClone(const char *Cmd) { PrintAndLogEx(INFO, "Preparing to clone FDX-B to T55x7 with animal ID: %04u-%"PRIu64, countryid, animalid); print_blocks(blocks, 5); + uint8_t res = 0; PacketResponseNG resp; // fast push mode @@ -318,7 +320,20 @@ static int CmdFdxClone(const char *Cmd) { PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); return PM3_ETIMEOUT; } + + if (i == 0) { + SetConfigWithBlock0(blocks[0]); + if ( t55xxAquireAndCompareBlock0(false, 0, blocks[0], false) ) + continue; + } + + if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) + res++; } + + if ( res == 0 ) + PrintAndLogEx(SUCCESS, "Success writing to tag"); + return PM3_SUCCESS; } diff --git a/client/cmdlfguard.c b/client/cmdlfguard.c index 22f7141fc..036597f0f 100644 --- a/client/cmdlfguard.c +++ b/client/cmdlfguard.c @@ -21,6 +21,7 @@ #include "cmdlf.h" #include "protocols.h" // for T55xx config register definitions #include "lfdemod.h" // parityTest +#include "cmdlft55xx.h" // verifywrite static int CmdHelp(const char *Cmd); @@ -183,6 +184,7 @@ static int CmdGuardClone(const char *Cmd) { PrintAndLogEx(INFO, "Preparing to clone Guardall to T55x7 with Facility Code: %u, Card Number: %u", facilitycode, cardnumber); print_blocks(blocks, 4); + uint8_t res = 0; PacketResponseNG resp; // fast push mode @@ -205,7 +207,20 @@ static int CmdGuardClone(const char *Cmd) { PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); return PM3_ETIMEOUT; } + + if (i == 0) { + SetConfigWithBlock0(blocks[0]); + if ( t55xxAquireAndCompareBlock0(false, 0, blocks[0], false) ) + continue; + } + + if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) + res++; } + + if ( res == 0 ) + PrintAndLogEx(SUCCESS, "Success writing to tag"); + return PM3_SUCCESS; } diff --git a/client/cmdlfindala.c b/client/cmdlfindala.c index 3fd3be59e..8d62e37ae 100644 --- a/client/cmdlfindala.c +++ b/client/cmdlfindala.c @@ -468,21 +468,21 @@ static int CmdIndalaClone(const char *Cmd) { if (isLongUid) { PrintAndLogEx(INFO, "Preparing to clone Indala 224bit tag with RawID %s", sprint_hex(data, datalen)); - uint32_t datawords[7] = {0}; - datawords[0] = bytes_to_num(data, 4); - datawords[1] = bytes_to_num(data + 4, 4); - datawords[2] = bytes_to_num(data + 8, 4); - datawords[3] = bytes_to_num(data + 12, 4); - datawords[4] = bytes_to_num(data + 16, 4); - datawords[5] = bytes_to_num(data + 20, 4); - datawords[6] = bytes_to_num(data + 24, 4); + uint32_t blocks[7] = {0}; + blocks[0] = bytes_to_num(data, 4); + blocks[1] = bytes_to_num(data + 4, 4); + blocks[2] = bytes_to_num(data + 8, 4); + blocks[3] = bytes_to_num(data + 12, 4); + blocks[4] = bytes_to_num(data + 16, 4); + blocks[5] = bytes_to_num(data + 20, 4); + blocks[6] = bytes_to_num(data + 24, 4); clearCommandBuffer(); - SendCommandOLD(CMD_LF_INDALA224_CLONE, 0, 0, 0, datawords, sizeof(datawords)); + SendCommandOLD(CMD_LF_INDALA224_CLONE, 0, 0, 0, blocks, sizeof(blocks)); } else { PrintAndLogEx(INFO, "Preparing to clone Indala 64bit tag with RawID %s", sprint_hex(data, datalen)); - uint32_t datawords[2] = {0}; - datawords[0] = bytes_to_num(data, 4); - datawords[1] = bytes_to_num(data + 4, 4); + uint32_t blocks[2] = {0}; + blocks[0] = bytes_to_num(data, 4); + blocks[1] = bytes_to_num(data + 4, 4); clearCommandBuffer(); SendCommandOLD(CMD_LF_INDALA_CLONE, 0, 0, 0, datawords, sizeof(datawords)); } diff --git a/client/cmdlfjablotron.c b/client/cmdlfjablotron.c index 9cc663895..919610293 100644 --- a/client/cmdlfjablotron.c +++ b/client/cmdlfjablotron.c @@ -24,6 +24,7 @@ #include "cmdlf.h" #include "protocols.h" // for T55xx config register definitions #include "lfdemod.h" // parityTest +#include "cmdlft55xx.h" // verifywrite static int CmdHelp(const char *Cmd); @@ -170,6 +171,7 @@ static int CmdJablotronClone(const char *Cmd) { PrintAndLogEx(INFO, "Preparing to clone Jablotron to T55x7 with FullCode: %"PRIx64, fullcode); print_blocks(blocks, 3); + uint8_t res = 0; PacketResponseNG resp; // fast push mode @@ -192,7 +194,20 @@ static int CmdJablotronClone(const char *Cmd) { PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); return PM3_ETIMEOUT; } + + if (i == 0) { + SetConfigWithBlock0(blocks[0]); + if ( t55xxAquireAndCompareBlock0(false, 0, blocks[0], false) ) + continue; + } + + if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) + res++; } + + if ( res == 0 ) + PrintAndLogEx(SUCCESS, "Success writing to tag"); + return PM3_SUCCESS; } diff --git a/client/cmdlfkeri.c b/client/cmdlfkeri.c index 384aad0b6..9f01f2f7f 100644 --- a/client/cmdlfkeri.c +++ b/client/cmdlfkeri.c @@ -22,6 +22,7 @@ #include "cmdlf.h" #include "protocols.h" // for T55xx config register definitions #include "lfdemod.h" // preamble test +#include "cmdlft55xx.h" // verifywrite static int CmdHelp(const char *Cmd); @@ -159,6 +160,7 @@ static int CmdKeriClone(const char *Cmd) { blocks[2] = data & 0xFFFFFFFF; print_blocks(blocks, 3); + uint8_t res = 0; PacketResponseNG resp; // fast push mode @@ -181,8 +183,20 @@ static int CmdKeriClone(const char *Cmd) { PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); return PM3_ETIMEOUT; } + + if (i == 0) { + SetConfigWithBlock0(blocks[0]); + if ( t55xxAquireAndCompareBlock0(false, 0, blocks[0], false) ) + continue; + } + + if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) + res++; } + if ( res == 0 ) + PrintAndLogEx(SUCCESS, "Success writing to tag"); + return PM3_SUCCESS; } diff --git a/client/cmdlfnedap.c b/client/cmdlfnedap.c index 3a4ebd131..ec2837d7a 100644 --- a/client/cmdlfnedap.c +++ b/client/cmdlfnedap.c @@ -9,20 +9,6 @@ #include "cmdlfnedap.h" -#include - -#include -#include - -#include "cmdparser.h" // command_t -#include "comms.h" -#include "crc16.h" -#include "cmdlft55xx.h" -#include "ui.h" -#include "cmddata.h" -#include "cmdlf.h" -#include "lfdemod.h" - #define FIXED_71 0x71 #define FIXED_40 0x40 #define UNKNOWN_A 0x00 @@ -469,6 +455,7 @@ int CmdLFNedapClone(const char *Cmd) { PrintAndLogEx(SUCCESS, "Preparing to clone NEDAP to T55x7"); print_blocks(blocks, max); + uint8_t res = 0; PacketResponseNG resp; // fast push mode @@ -490,10 +477,24 @@ int CmdLFNedapClone(const char *Cmd) { PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); return PM3_ETIMEOUT; } + + if (i == 0) { + SetConfigWithBlock0(blocks[0]); + if ( t55xxAquireAndCompareBlock0(false, 0, blocks[0], false) ) + continue; + } + + if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) + res++; + } + + if ( res == 0 ) + PrintAndLogEx(SUCCESS, "Success writing to tag"); + else { + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "The block 0 was changed (eXtended) which can be hard to detect."); + PrintAndLogEx(INFO, " Configure it manually " _YELLOW_("`lf t55xx config b 64 d BI i 1 o 32`")); } - PrintAndLogEx(NORMAL, "\n"); - PrintAndLogEx(INFO, "The block 0 was changed (eXtended) which can be hard to detect."); - PrintAndLogEx(INFO, " Configure it manually " _YELLOW_("`lf t55xx config b 64 d BI i 1 o 32`")); return PM3_SUCCESS; } diff --git a/client/cmdlfnedap.h b/client/cmdlfnedap.h index fda0e130e..74fdd30fb 100644 --- a/client/cmdlfnedap.h +++ b/client/cmdlfnedap.h @@ -11,6 +11,19 @@ #include "common.h" +#include + +#include +#include +#include "cmdparser.h" // command_t +#include "comms.h" +#include "crc16.h" +#include "cmdlft55xx.h" // verifywrite +#include "ui.h" +#include "cmddata.h" +#include "cmdlf.h" +#include "lfdemod.h" + int CmdLFNedap(const char *Cmd); int demodNedap(void); diff --git a/client/cmdlfnoralsy.c b/client/cmdlfnoralsy.c index 146c6b350..2d9481782 100644 --- a/client/cmdlfnoralsy.c +++ b/client/cmdlfnoralsy.c @@ -177,13 +177,14 @@ static int CmdNoralsyClone(const char *Cmd) { return PM3_ETIMEOUT; } - // write block0, needs a detect. - if (i == 0) - t55xxAquireAndDetect(false, 0, blocks[i], false); + if (i == 0) { + SetConfigWithBlock0(blocks[0]); + if ( t55xxAquireAndCompareBlock0(false, 0, blocks[0], false) ) + continue; + } if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) res++; - } if ( res == 0 ) diff --git a/client/cmdlfpresco.c b/client/cmdlfpresco.c index a9c74d9ac..39587c5ea 100644 --- a/client/cmdlfpresco.c +++ b/client/cmdlfpresco.c @@ -144,16 +144,15 @@ static int CmdPrescoClone(const char *Cmd) { return PM3_ETIMEOUT; } - // write block0, needs a detect. if (i == 0) { - printf("enter detect "); - bool ok = t55xxAquireAndDetect(false, 0, blocks[i], false); - printf(" b0 = '%c' \n", (ok) ? 'Y':'N'); + SetConfigWithBlock0(blocks[0]); + if ( t55xxAquireAndCompareBlock0(false, 0, blocks[0], false) ) + continue; } - if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) { + + if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) res++; - printf(" i = %d \n", i); - } + } if ( res == 0 ) diff --git a/client/cmdlfpyramid.c b/client/cmdlfpyramid.c index d0f116bf4..90e5c23d7 100644 --- a/client/cmdlfpyramid.c +++ b/client/cmdlfpyramid.c @@ -254,9 +254,11 @@ static int CmdPyramidClone(const char *Cmd) { return PM3_ETIMEOUT; } - // write block0, needs a detect. - if (i == 0) - t55xxAquireAndDetect(false, 0, blocks[i], false); + if (i == 0) { + SetConfigWithBlock0(blocks[0]); + if ( t55xxAquireAndCompareBlock0(false, 0, blocks[0], false) ) + continue; + } if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) res++; diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 1afa169c9..06dac9c24 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -405,6 +405,32 @@ static bool t55xxProtect(bool lock, bool usepwd, uint8_t override, uint32_t pass } } +bool t55xxAquireAndCompareBlock0(bool usepwd, uint32_t password, uint32_t known_block0, bool verbose) { + + if (verbose) + PrintAndLogEx(INFO, "Block0 write detected, running `detect` to see if validation is possible"); + + for ( uint8_t m = 0; m < 4; m++) { + if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, m) == false) { + continue; + } + + if (DecodeT55xxBlock() == false) { + continue; + } + + for( uint16_t i = 0; DemodBufferLen - 32; i++) { + uint32_t tmp = PackBits(i, 32, DemodBuffer); + if ( tmp == known_block0 ) { + config.offset = i; + config.downlink_mode = m; + return true; + } + } + } + return false; +} + bool t55xxAquireAndDetect(bool usepwd, uint32_t password, uint32_t known_block0, bool verbose) { if (verbose) @@ -417,6 +443,7 @@ bool t55xxAquireAndDetect(bool usepwd, uint32_t password, uint32_t known_block0, if (tryDetectModulationEx(m, verbose, known_block0) == false) continue; + config.downlink_mode = m; return true; } return false; @@ -491,6 +518,36 @@ void printT5xxHeader(uint8_t page) { PrintAndLogEx(SUCCESS, "----+----------+----------------------------------+-------"); } +void SetConfigWithBlock0(uint32_t block0) { + // T55x7 + uint32_t extend = (block0 >> (32 - 15)) & 0x01; + uint32_t dbr; + if (extend) + dbr = (block0 >> (32 - 14)) & 0x3F; + else + dbr = (block0 >> (32 - 14)) & 0x07; + + uint32_t datamod = (block0 >> (32 - 20)) & 0x1F; + bool pwd = (bool)((block0 >> (32 - 28)) & 0x01); + bool sst = (bool)((block0 >> (32 - 29)) & 0x01); + bool inv = (bool)((block0 >> (32 - 31)) & 0x01); + + config.modulation = datamod; + config.bitrate = dbr; + + // FSK1a, FSK2a + if ( datamod == DEMOD_FSK1a || datamod == DEMOD_FSK2a || datamod == DEMOD_BIa ) + config.inverted = 1; + else + config.inverted = inv; + + config.Q5 = 0; + config.ST = sst; + config.usepwd = pwd; + config.offset = 0; + config.block0 = block0; +} + static int CmdT55xxSetConfig(const char *Cmd) { // No args @@ -621,30 +678,11 @@ static int CmdT55xxSetConfig(const char *Cmd) { if ( gotconf ) { - // Q5 - - + // Q5 - to be implemented + // T55x7 - uint32_t extend = (block0 >> (32 - 15)) & 0x01; - uint32_t dbr; - if (extend) - dbr = (block0 >> (32 - 14)) & 0x3F; - else - dbr = (block0 >> (32 - 14)) & 0x07; + SetConfigWithBlock0(block0); - uint32_t datamod = (block0 >> (32 - 20)) & 0x1F; - bool pwd = (bool)((block0 >> (32 - 28)) & 0x01); - bool sst = (bool)((block0 >> (32 - 29)) & 0x01); - bool inv = (bool)((block0 >> (32 - 31)) & 0x01); - - config.modulation = datamod; - config.bitrate = dbr; - config.inverted = inv; - config.Q5 = 0; - config.ST = sst; - config.usepwd = pwd; - config.offset = 0; - config.block0 = block0; } else { config.block0 = 0; } diff --git a/client/cmdlft55xx.h b/client/cmdlft55xx.h index f388a39af..182377deb 100644 --- a/client/cmdlft55xx.h +++ b/client/cmdlft55xx.h @@ -131,6 +131,8 @@ void Set_t55xx_Config(t55xx_conf_block_t conf); int CmdLFT55XX(const char *Cmd); +void SetConfigWithBlock0(uint32_t block0); + char *GetPskCfStr(uint32_t id, bool q5); char *GetBitRateStr(uint32_t id, bool xmode); char *GetSaferStr(uint32_t id); @@ -143,6 +145,7 @@ void printT5xxHeader(uint8_t page); void printT55xxBlock(uint8_t blockNum); int printConfiguration(t55xx_conf_block_t b); +bool t55xxAquireAndCompareBlock0(bool usepwd, uint32_t password, uint32_t known_block0, bool verbose); bool t55xxAquireAndDetect(bool usepwd, uint32_t password, uint32_t known_block0, bool verbose); bool t55xxVerifyWrite( uint8_t block, bool page1, bool usepwd, uint8_t override, uint32_t password, uint8_t downlink_mode, uint32_t data); int T55xxReadBlock(uint8_t block, bool page1, bool usepwd, uint8_t override, uint32_t password, uint8_t downlink_mode); diff --git a/client/cmdlfvisa2000.c b/client/cmdlfvisa2000.c index 51cedb925..f23a7c5a8 100644 --- a/client/cmdlfvisa2000.c +++ b/client/cmdlfvisa2000.c @@ -189,11 +189,13 @@ static int CmdVisa2kClone(const char *Cmd) { PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); return PM3_ETIMEOUT; - } + } - // write block0, needs a detect. - if (i == 0) - t55xxAquireAndDetect(false, 0, blocks[i], false); + if (i == 0) { + SetConfigWithBlock0(blocks[0]); + if ( t55xxAquireAndCompareBlock0(false, 0, blocks[0], false) ) + continue; + } if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) res++; From 4c08477ef71d29641c59ad7b5589ccbab1d3e565 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 16 Sep 2019 11:33:05 +0200 Subject: [PATCH 0721/1854] chg: 'lf indala clone' - refactored , uses NG --- armsrc/appmain.c | 11 ------ armsrc/lfops.c | 31 +--------------- armsrc/lfops.h | 2 -- client/cmdlfindala.c | 86 +++++++++++++++++++++++++++++++++++--------- client/util.c | 2 +- include/pm3_cmd.h | 11 ++++-- 6 files changed, 80 insertions(+), 63 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 058a4709e..06ea02e50 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -769,17 +769,6 @@ static void PacketReceived(PacketCommandNG *packet) { SimulateTagLowFrequencyBidir(packet->oldarg[0], packet->oldarg[1]); break; } - case CMD_LF_INDALA_CLONE: { - CopyIndala64toT55x7(packet->data.asDwords[0], packet->data.asDwords[1]); - break; - } - case CMD_LF_INDALA224_CLONE: { - CopyIndala224toT55x7( - packet->data.asDwords[0], packet->data.asDwords[1], packet->data.asDwords[2], packet->data.asDwords[3], - packet->data.asDwords[4], packet->data.asDwords[5], packet->data.asDwords[6] - ); - break; - } case CMD_LF_T55XX_READBL: { struct p { uint32_t password; diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 47c8011f8..fd1fa36e1 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -1712,7 +1712,7 @@ void T55xxWriteBlock(uint8_t *data) { c->flags &= (0xff ^ 0x40); // Called for a write, so ensure it is clear/0 LED_A_ON(); - T55xx_SendCMD(c->data, c->pwd, c->flags | (c->blockno << 9)) ; //, false); + T55xx_SendCMD(c->data, c->pwd, c->flags | (c->blockno << 9)); // Perform write (nominal is 5.6 ms for T55x7 and 18ms for E5550, // so wait a little more) @@ -1744,7 +1744,6 @@ void T55xxWriteBlock(uint8_t *data) { // turn field off FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - // cmd_send(CMD_ACK,0,0,0,0,0); reply_ng(CMD_LF_T55XX_WRITEBL, PM3_SUCCESS, NULL, 0); LED_A_OFF(); } @@ -2049,34 +2048,6 @@ void CopyIOtoT55x7(uint32_t hi, uint32_t lo) { LED_D_OFF(); } -// Clone Indala 64-bit tag by UID to T55x7 -void CopyIndala64toT55x7(uint32_t hi, uint32_t lo) { - //Program the 2 data blocks for supplied 64bit UID - // and the Config for Indala 64 format (RF/32;PSK1 with RF/2;Maxblock=2) - uint32_t data[] = { T55x7_BITRATE_RF_32 | T55x7_MODULATION_PSK1 | (2 << T55x7_MAXBLOCK_SHIFT), hi, lo}; - //TODO add selection of chip for Q5 or T55x7 - // data[0] = T5555_SET_BITRATE(32 | T5555_MODULATION_PSK1 | 2 << T5555_MAXBLOCK_SHIFT; - LED_D_ON(); - WriteT55xx(data, 0, 3); - //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=2;Inverse data) - // T5567WriteBlock(0x603E1042,0); - LED_D_OFF(); -} -// Clone Indala 224-bit tag by UID to T55x7 -void CopyIndala224toT55x7(uint32_t uid1, uint32_t uid2, uint32_t uid3, uint32_t uid4, uint32_t uid5, uint32_t uid6, uint32_t uid7) { - //Program the 7 data blocks for supplied 224bit UID - uint32_t data[] = {0, uid1, uid2, uid3, uid4, uid5, uid6, uid7}; - // and the block 0 for Indala224 format - //Config for Indala (RF/32;PSK2 with RF/2;Maxblock=7) - data[0] = T55x7_BITRATE_RF_32 | T55x7_MODULATION_PSK2 | (7 << T55x7_MAXBLOCK_SHIFT); - //TODO add selection of chip for Q5 or T55x7 - // data[0] = T5555_SET_BITRATE(32 | T5555_MODULATION_PSK2 | 7 << T5555_MAXBLOCK_SHIFT; - LED_D_ON(); - WriteT55xx(data, 0, 8); - //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=7;Inverse data) - // T5567WriteBlock(0x603E10E2,0); - LED_D_OFF(); -} // clone viking tag to T55xx void CopyVikingtoT55xx(uint8_t *blocks, uint8_t Q5) { diff --git a/armsrc/lfops.h b/armsrc/lfops.h index 99d1b29eb..a88f05800 100644 --- a/armsrc/lfops.h +++ b/armsrc/lfops.h @@ -46,8 +46,6 @@ void CopyIOtoT55x7(uint32_t hi, uint32_t lo); // Clone an ioProx card to T5557/T void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT); // Clone an HID card to T5557/T5567 void CopyVikingtoT55xx(uint8_t *blocks, uint8_t Q5); void WriteEM410x(uint32_t card, uint32_t id_hi, uint32_t id_lo); -void CopyIndala64toT55x7(uint32_t hi, uint32_t lo); // Clone Indala 64-bit tag by UID to T55x7 -void CopyIndala224toT55x7(uint32_t uid1, uint32_t uid2, uint32_t uid3, uint32_t uid4, uint32_t uid5, uint32_t uid6, uint32_t uid7); // Clone Indala 224-bit tag by UID to T55x7 void T55xxResetRead(uint8_t flags); //id T55xxWriteBlock(uint32_t data, uint8_t blockno, uint32_t pwd, uint8_t flags); void T55xxWriteBlock(uint8_t *data); diff --git a/client/cmdlfindala.c b/client/cmdlfindala.c index 8d62e37ae..da13766db 100644 --- a/client/cmdlfindala.c +++ b/client/cmdlfindala.c @@ -25,6 +25,8 @@ #include "lfdemod.h" // parityTest, bitbytes_to_byte #include "cmddata.h" #include "cmdlf.h" // lf_read +#include "protocols.h" // t55 defines +#include "cmdlft55xx.h" // verifywrite static int CmdHelp(const char *Cmd); @@ -439,10 +441,12 @@ static int CmdIndalaSim(const char *Cmd) { return PM3_SUCCESS; } -// iceman - needs refactoring static int CmdIndalaClone(const char *Cmd) { bool isLongUid = false; + uint32_t blocks[8] = {0}; + uint8_t max = 0; + uint8_t data[7 * 4]; int datalen = 0; @@ -466,27 +470,77 @@ static int CmdIndalaClone(const char *Cmd) { CLIGetHexWithReturn(2, data, &datalen); CLIParserFree(); +/* + //TODO add selection of chip for Q5 or T55x7 + + // data[0] = T5555_SET_BITRATE(32 | T5555_MODULATION_PSK2 | 7 << T5555_MAXBLOCK_SHIFT; + //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=7;Inverse data) + // T5567WriteBlock(0x603E10E2,0); + + // data[0] = T5555_SET_BITRATE(32 | T5555_MODULATION_PSK1 | 2 << T5555_MAXBLOCK_SHIFT; + //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=2;Inverse data) + // T5567WriteBlock(0x603E1042,0); +*/ + if (isLongUid) { + // config for Indala (RF/32;PSK2 with RF/2;Maxblock=7) PrintAndLogEx(INFO, "Preparing to clone Indala 224bit tag with RawID %s", sprint_hex(data, datalen)); - uint32_t blocks[7] = {0}; - blocks[0] = bytes_to_num(data, 4); - blocks[1] = bytes_to_num(data + 4, 4); - blocks[2] = bytes_to_num(data + 8, 4); - blocks[3] = bytes_to_num(data + 12, 4); - blocks[4] = bytes_to_num(data + 16, 4); - blocks[5] = bytes_to_num(data + 20, 4); - blocks[6] = bytes_to_num(data + 24, 4); - clearCommandBuffer(); - SendCommandOLD(CMD_LF_INDALA224_CLONE, 0, 0, 0, blocks, sizeof(blocks)); + blocks[0] = T55x7_BITRATE_RF_32 | T55x7_MODULATION_PSK2 | (7 << T55x7_MAXBLOCK_SHIFT); + blocks[1] = bytes_to_num(data, 4); + blocks[2] = bytes_to_num(data + 4, 4); + blocks[3] = bytes_to_num(data + 8, 4); + blocks[4] = bytes_to_num(data + 12, 4); + blocks[5] = bytes_to_num(data + 16, 4); + blocks[6] = bytes_to_num(data + 20, 4); + blocks[7] = bytes_to_num(data + 24, 4); + max = 8; } else { + // config for Indala 64 format (RF/32;PSK1 with RF/2;Maxblock=2) PrintAndLogEx(INFO, "Preparing to clone Indala 64bit tag with RawID %s", sprint_hex(data, datalen)); - uint32_t blocks[2] = {0}; - blocks[0] = bytes_to_num(data, 4); - blocks[1] = bytes_to_num(data + 4, 4); - clearCommandBuffer(); - SendCommandOLD(CMD_LF_INDALA_CLONE, 0, 0, 0, datawords, sizeof(datawords)); + blocks[0] = T55x7_BITRATE_RF_32 | T55x7_MODULATION_PSK1 | (2 << T55x7_MAXBLOCK_SHIFT); + blocks[1] = bytes_to_num(data, 4); + blocks[2] = bytes_to_num(data + 4, 4); + max = 3; } + print_blocks(blocks, max); + + uint8_t res = 0; + PacketResponseNG resp; + + // fast push mode + conn.block_after_ACK = true; + for (uint8_t i = 0; i < max; i++) { + if (i == max - 1) { + // Disable fast mode on last packet + conn.block_after_ACK = false; + } + clearCommandBuffer(); + t55xx_write_block_t ng; + ng.data = blocks[i]; + ng.pwd = 0; + ng.blockno = i; + ng.flags = 0; + + SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng)); + if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, T55XX_WRITE_TIMEOUT)) { + PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); + return PM3_ETIMEOUT; + } + + if (i == 0) { + SetConfigWithBlock0(blocks[0]); + if ( t55xxAquireAndCompareBlock0(false, 0, blocks[0], false) ) + continue; + } + + if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) + res++; + } + + if ( res == 0 ) + PrintAndLogEx(SUCCESS, "Success writing to tag"); + return PM3_SUCCESS; } diff --git a/client/util.c b/client/util.c index 6877e8835..55b114fdb 100644 --- a/client/util.c +++ b/client/util.c @@ -390,7 +390,7 @@ void print_blocks(uint32_t *data, size_t len) { PrintAndLogEx(ERR, "..empty data"); } else { for (uint8_t i = 0; i < len; i++) - PrintAndLogEx(SUCCESS, " %02d | 0x%08X", i, data[i]); + PrintAndLogEx(SUCCESS, " %02d | %08X", i, data[i]); } } diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index d79433fcf..4982f4a60 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -242,6 +242,14 @@ typedef struct { uint8_t keytype; } PACKED mfc_eload_t; +typedef struct { + uint8_t status; + uint8_t CSN[8]; + uint8_t CONFIG[8]; + uint8_t CC[8]; + uint8_t AIA[8]; +} PACKED iclass_reader_t; + // For the bootloader #define CMD_DEVICE_INFO 0x0000 #define CMD_SETUP_WRITE 0x0001 @@ -345,9 +353,6 @@ typedef struct { #define CMD_SET_ADC_MUX 0x020F #define CMD_LF_HID_CLONE 0x0210 #define CMD_LF_EM410X_WRITE 0x0211 -#define CMD_LF_INDALA_CLONE 0x0212 -// for 224 bits UID -#define CMD_LF_INDALA224_CLONE 0x0213 #define CMD_LF_T55XX_READBL 0x0214 #define CMD_LF_T55XX_WRITEBL 0x0215 #define CMD_LF_T55XX_RESET_READ 0x0216 From e5c31886ebd9bbb1b23a0fac76922f97396b3102 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 16 Sep 2019 11:41:34 +0200 Subject: [PATCH 0722/1854] chg: 'lf io clone' - refactored, uses NG --- armsrc/appmain.c | 4 ---- armsrc/lfops.c | 12 ------------ armsrc/lfops.h | 1 - client/cmdlfio.c | 44 ++++++++++++++++++++++++++++++++++++++++---- include/pm3_cmd.h | 1 - 5 files changed, 40 insertions(+), 22 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 06ea02e50..7d29da0ee 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -730,10 +730,6 @@ static void PacketReceived(PacketCommandNG *packet) { CmdIOdemodFSK(packet->oldarg[0], &high, &low, 1); break; } - case CMD_LF_IO_CLONE: { - CopyIOtoT55x7(packet->oldarg[0], packet->oldarg[1]); - break; - } case CMD_LF_EM410X_DEMOD: { uint32_t high; uint64_t low; diff --git a/armsrc/lfops.c b/armsrc/lfops.c index fd1fa36e1..57b2b75cd 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -2036,18 +2036,6 @@ void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT) { LED_D_OFF(); } -void CopyIOtoT55x7(uint32_t hi, uint32_t lo) { - uint32_t data[] = {T55x7_BITRATE_RF_64 | T55x7_MODULATION_FSK2a | (2 << T55x7_MAXBLOCK_SHIFT), hi, lo}; - //TODO add selection of chip for Q5 or T55x7 - // data[0] = T5555_SET_BITRATE(64) | T5555_MODULATION_FSK2 | T5555_INVERT_OUTPUT | 2 << T5555_MAXBLOCK_SHIFT; - - LED_D_ON(); - // Program the data blocks for supplied ID - // and the block 0 config - WriteT55xx(data, 0, 3); - LED_D_OFF(); -} - // clone viking tag to T55xx void CopyVikingtoT55xx(uint8_t *blocks, uint8_t Q5) { diff --git a/armsrc/lfops.h b/armsrc/lfops.h index a88f05800..bf246b529 100644 --- a/armsrc/lfops.h +++ b/armsrc/lfops.h @@ -42,7 +42,6 @@ void CmdHIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol); void CmdAWIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol); // Realtime demodulation mode for AWID26 void CmdEM410xdemod(int findone, uint32_t *high, uint64_t *low, int ledcontrol); void CmdIOdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol); -void CopyIOtoT55x7(uint32_t hi, uint32_t lo); // Clone an ioProx card to T5557/T5567 void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT); // Clone an HID card to T5557/T5567 void CopyVikingtoT55xx(uint8_t *blocks, uint8_t Q5); void WriteEM410x(uint32_t card, uint32_t id_hi, uint32_t id_lo); diff --git a/client/cmdlfio.c b/client/cmdlfio.c index 87fa17b02..b71302ea9 100644 --- a/client/cmdlfio.c +++ b/client/cmdlfio.c @@ -24,6 +24,7 @@ #include "lfdemod.h" // parityTest, bitbytes_to_byte #include "protocols.h" // for T55xx config register definitions #include "cmddata.h" +#include "cmdlft55xx.h" // verifywrite static int CmdHelp(const char *Cmd); /* @@ -243,7 +244,6 @@ static int CmdIOProxSim(const char *Cmd) { static int CmdIOProxClone(const char *Cmd) { - uint32_t blocks[3] = {T55x7_MODULATION_FSK2a | T55x7_BITRATE_RF_64 | 2 << T55x7_MAXBLOCK_SHIFT, 0, 0}; uint16_t cn = 0; uint8_t version = 0, fc = 0; uint8_t bits[64]; @@ -268,7 +268,9 @@ static int CmdIOProxClone(const char *Cmd) { return PM3_ESOFT; } - if (param_getchar(Cmd, 3) == 'Q' || param_getchar(Cmd, 3) == 'q') + uint32_t blocks[3] = {T55x7_MODULATION_FSK2a | T55x7_BITRATE_RF_64 | 2 << T55x7_MAXBLOCK_SHIFT, 0, 0}; + + if (tolower(param_getchar(Cmd, 3) == 'q')) blocks[0] = T5555_MODULATION_FSK2 | T5555_INVERT_OUTPUT | T5555_SET_BITRATE(64) | 2 << T5555_MAXBLOCK_SHIFT; blocks[1] = bytebits_to_byte(bits, 32); @@ -277,8 +279,42 @@ static int CmdIOProxClone(const char *Cmd) { PrintAndLogEx(INFO, "Preparing to clone IOProx to T55x7 with Version: %u FC: %u, CN: %u", version, fc, cn); print_blocks(blocks, 3); - clearCommandBuffer(); - SendCommandMIX(CMD_LF_IO_CLONE, blocks[1], blocks[2], 0, NULL, 0); + uint8_t res = 0; + PacketResponseNG resp; + + // fast push mode + conn.block_after_ACK = true; + for (uint8_t i = 0; i < 3; i++) { + if (i == 2) { + // Disable fast mode on last packet + conn.block_after_ACK = false; + } + clearCommandBuffer(); + t55xx_write_block_t ng; + ng.data = blocks[i]; + ng.pwd = 0; + ng.blockno = i; + ng.flags = 0; + + SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng)); + if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, T55XX_WRITE_TIMEOUT)) { + PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); + return PM3_ETIMEOUT; + } + + if (i == 0) { + SetConfigWithBlock0(blocks[0]); + if ( t55xxAquireAndCompareBlock0(false, 0, blocks[0], false) ) + continue; + } + + if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) + res++; + } + + if ( res == 0 ) + PrintAndLogEx(SUCCESS, "Success writing to tag"); + return PM3_SUCCESS; } diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 4982f4a60..13995a429 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -361,7 +361,6 @@ typedef struct { #define CMD_LF_EM4X_READWORD 0x0218 #define CMD_LF_EM4X_WRITEWORD 0x0219 #define CMD_LF_IO_DEMOD 0x021A -#define CMD_LF_IO_CLONE 0x021B #define CMD_LF_EM410X_DEMOD 0x021c // Sampling configuration for LF reader/sniffer #define CMD_LF_SAMPLING_SET_CONFIG 0x021d From 412f016b94df0926e995c4aa59a6479bacc13ec9 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 16 Sep 2019 12:36:04 +0200 Subject: [PATCH 0723/1854] chg: 'lf t55xx config' - can set config based on a block0, offset and Q5 lf t55xx config c 000880E0 o 10 - sets a T55x7 w offset 10 lf t55xx config c 000880E0 o 6 Q5 - sets a Q5/T5555 w offset 6 --- client/cmdlft55xx.c | 14 ++++++-------- client/cmdlft55xx.h | 1 + 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 6b42b4688..88c6b3162 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -519,6 +519,9 @@ void printT5xxHeader(uint8_t page) { } void SetConfigWithBlock0(uint32_t block0) { + SetConfigWithBlock0Ex(block0, 0, false); +} +void SetConfigWithBlock0Ex(uint32_t block0, uint8_t offset, bool Q5) { // T55x7 uint32_t extend = (block0 >> (32 - 15)) & 0x01; uint32_t dbr; @@ -541,10 +544,10 @@ void SetConfigWithBlock0(uint32_t block0) { else config.inverted = inv; - config.Q5 = 0; + config.Q5 = Q5; config.ST = sst; config.usepwd = pwd; - config.offset = 0; + config.offset = offset; config.block0 = block0; } @@ -677,12 +680,7 @@ static int CmdT55xxSetConfig(const char *Cmd) { if (errors) return usage_t55xx_config(); if ( gotconf ) { - - // Q5 - to be implemented - - // T55x7 - SetConfigWithBlock0(block0); - + SetConfigWithBlock0Ex(block0, config.offset, config.Q5); } else { config.block0 = 0; } diff --git a/client/cmdlft55xx.h b/client/cmdlft55xx.h index 182377deb..d4e217372 100644 --- a/client/cmdlft55xx.h +++ b/client/cmdlft55xx.h @@ -132,6 +132,7 @@ void Set_t55xx_Config(t55xx_conf_block_t conf); int CmdLFT55XX(const char *Cmd); void SetConfigWithBlock0(uint32_t block0); +void SetConfigWithBlock0Ex(uint32_t block0, uint8_t offset, bool Q5); char *GetPskCfStr(uint32_t id, bool q5); char *GetBitRateStr(uint32_t id, bool xmode); From c5ea6b54ce8535652dbef92779fcc91d15cd31fa Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 16 Sep 2019 17:37:18 +0300 Subject: [PATCH 0724/1854] add ignoring results of some tests --- client/emv/cmdemv.c | 17 +++++++++++++++-- client/emv/test/cryptotest.c | 6 +++--- client/emv/test/cryptotest.h | 2 +- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c index 8656e4902..8bb630074 100644 --- a/client/emv/cmdemv.c +++ b/client/emv/cmdemv.c @@ -1714,8 +1714,21 @@ static int CmdEMVList(const char *Cmd) { } static int CmdEMVTest(const char *Cmd) { - (void)Cmd; // Cmd is not used so far - return ExecuteCryptoTests(true); + CLIParserInit("emv test", + "Executes tests\n", + "Usage:\n\temv test\n"); + + void *argtable[] = { + arg_param_begin, + arg_lit0("iI", "ignore", "ignore timing tests for VM"), + arg_param_end + }; + CLIExecWithReturn(Cmd, argtable, true); + + bool ignoreTimeTest = arg_get_lit(1); + CLIParserFree(); + + return ExecuteCryptoTests(true, ignoreTimeTest); } static int CmdEMVRoca(const char *Cmd) { diff --git a/client/emv/test/cryptotest.c b/client/emv/test/cryptotest.c index 937ff7e8e..b8ea1239e 100644 --- a/client/emv/test/cryptotest.c +++ b/client/emv/test/cryptotest.c @@ -33,7 +33,7 @@ #include "crypto/libpcrypto.h" #include "emv/emv_roca.h" -int ExecuteCryptoTests(bool verbose) { +int ExecuteCryptoTests(bool verbose, bool ignore_time) { int res; bool TestFail = false; @@ -56,7 +56,7 @@ int ExecuteCryptoTests(bool verbose) { if (res) TestFail = true; res = mbedtls_entropy_self_test(verbose); - if (res) TestFail = true; + if (res && !ignore_time) TestFail = true; // retry for CI (when resources too low) for (int i = 0; i < 3; i++) { @@ -65,7 +65,7 @@ int ExecuteCryptoTests(bool verbose) { break; PrintAndLogEx(WARNING, "Repeat timing test %d", i + 1); } - if (res) TestFail = true; + if (res && !ignore_time) TestFail = true; res = mbedtls_ctr_drbg_self_test(verbose); if (res) TestFail = true; diff --git a/client/emv/test/cryptotest.h b/client/emv/test/cryptotest.h index 74a317e4e..aeecce556 100644 --- a/client/emv/test/cryptotest.h +++ b/client/emv/test/cryptotest.h @@ -12,5 +12,5 @@ #define __CRYPTOTEST_H #include -int ExecuteCryptoTests(bool verbose); +int ExecuteCryptoTests(bool verbose, bool ignore_time); #endif From e8cd43f1affe8d922877470762b3cdf98d1a090a Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 16 Sep 2019 17:39:00 +0300 Subject: [PATCH 0725/1854] added parameter --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index af725ef93..a32c6a56a 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -383,7 +383,7 @@ test_script: #proxmark crypto tests - ExecTest "emv test" "emv test" {bash -lc "cd ~/client;./proxmark3 -c 'emv test'"} "Test?s? ? OK" + ExecTest "emv test" "emv test" {bash -lc "cd ~/client;./proxmark3 -c 'emv test -i'"} "Test?s? ? OK" if ($global:TestsPassed) { From abe5ca47a57899071df4a20202b647b809d00f86 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 17 Sep 2019 17:42:12 +0200 Subject: [PATCH 0726/1854] thinfilm: reduce timeout, no need to wait so long --- armsrc/iso14443a.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index c49d93a1f..348317a8a 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -2044,8 +2044,7 @@ bool GetIso14443aAnswerFromTag_Thinfilm(uint8_t *receivedResponse, uint8_t *rec } } - // timeout already in ms + 10ms guard time - if (GetTickCount() - receive_timer > 1160) + if (GetTickCount() - receive_timer > 100) break; } *received_len = Demod.len; From d3651cc0757a02b590ef4668a2d6297f0076d40e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 17 Sep 2019 19:13:00 +0200 Subject: [PATCH 0727/1854] chg 'hw status' - reply NG.... thanks @cjbrigato --- armsrc/appmain.c | 2 +- client/cmdhw.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 7d29da0ee..257a4a5b6 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -343,7 +343,7 @@ void SendStatus(void) { Flashmem_print_info(); #endif - reply_old(CMD_ACK, 1, 0, 0, 0, 0); + reply_ng(CMD_STATUS, PM3_SUCCESS, NULL, 0); } void SendCapabilities(void) { diff --git a/client/cmdhw.c b/client/cmdhw.c index c81efda9e..c363fdc25 100644 --- a/client/cmdhw.c +++ b/client/cmdhw.c @@ -502,7 +502,7 @@ static int CmdStatus(const char *Cmd) { clearCommandBuffer(); PacketResponseNG resp; SendCommandNG(CMD_STATUS, NULL, 0); - if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) + if (WaitForResponseTimeout(CMD_STATUS, &resp, 2000) == false) PrintAndLogEx(WARNING, "Status command failed. Communication speed test timed out"); return PM3_SUCCESS; } From 7abc10c63a388458cecdb29d0cee0cba25916468 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 18 Sep 2019 19:20:07 +0200 Subject: [PATCH 0728/1854] add: 'wiegand commands' - wiegand manipulation like encoding / decoding of credentials. From offical repo (@grauerfuchs) Adapted and converted to fit this repo. --- client/cmdmain.c | 4 +- client/cmdwiegand.c | 205 ++++++++++ client/cmdwiegand.h | 20 + client/util.c | 17 + client/util.h | 1 + client/wiegand_formats.c | 715 +++++++++++++++++++++++++++++++++++ client/wiegand_formats.h | 48 +++ client/wiegand_formatutils.c | 185 +++++++++ client/wiegand_formatutils.h | 49 +++ 9 files changed, 1243 insertions(+), 1 deletion(-) create mode 100644 client/cmdwiegand.c create mode 100644 client/cmdwiegand.h create mode 100644 client/wiegand_formats.c create mode 100644 client/wiegand_formats.h create mode 100644 client/wiegand_formatutils.c create mode 100644 client/wiegand_formatutils.h diff --git a/client/cmdmain.c b/client/cmdmain.c index eba34b2ca..4b6013d80 100644 --- a/client/cmdmain.c +++ b/client/cmdmain.c @@ -32,6 +32,7 @@ #include "cmdflashmem.h" // rdv40 flashmem commands #include "cmdsmartcard.h" // rdv40 smart card ISO7816 commands #include "cmdusart.h" // rdv40 FPC USART commands +#include "cmdwiegand.h" // wiegand commands #include "ui.h" #include "util_posix.h" @@ -98,11 +99,12 @@ static command_t CommandTable[] = { {"mem", CmdFlashMem, IfPm3Flash, "{ Flash Memory manipulation... }"}, {"msleep", CmdMsleep, AlwaysAvailable, "Add a pause in milliseconds"}, {"rem", CmdRem, AlwaysAvailable, "Add text to row in log file"}, - {"reveng", CmdRev, AlwaysAvailable, "{ Crc calculations from the RevEng software }"}, + {"reveng", CmdRev, AlwaysAvailable, "{ CRC calculations from RevEng software }"}, {"sc", CmdSmartcard, IfPm3Smartcard, "{ Smart card ISO7816 commands... }"}, {"script", CmdScript, AlwaysAvailable, "{ Scripting commands }"}, {"trace", CmdTrace, AlwaysAvailable, "{ Trace manipulation... }"}, {"usart", CmdUsart, IfPm3FpcUsartFromUsb, "{ USART commands... }"}, + {"wiegand", CmdWiegand, AlwaysAvailable, "{ Wiegand format manipulation... }"}, {"quit", CmdQuit, AlwaysAvailable, ""}, {"exit", CmdQuit, AlwaysAvailable, "Exit program"}, {NULL, NULL, NULL, NULL} diff --git a/client/cmdwiegand.c b/client/cmdwiegand.c new file mode 100644 index 000000000..0b567d514 --- /dev/null +++ b/client/cmdwiegand.c @@ -0,0 +1,205 @@ +//----------------------------------------------------------------------------- +// Copyright (C) 2018 iceman +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// Trace commands +//----------------------------------------------------------------------------- +#include "cmdwiegand.h" + +#include +#include +#include +#include "cmdparser.h" // command_t +#include "comms.h" +#include "pm3_cmd.h" +#include "protocols.h" +#include "parity.h" // oddparity +#include "cmdhflist.h" // annotations +#include "wiegand_formats.h" +#include "wiegand_formatutils.h" +#include "util.h" + +static int CmdHelp(const char *Cmd); + +static int usage_wiegand_list() { + PrintAndLogEx(NORMAL, "List available wiegand formats"); + return PM3_SUCCESS; +} +static int usage_wiegand_encode() { + PrintAndLogEx(NORMAL, "Encode wiegand formatted number to raw hex"); + PrintAndLogEx(NORMAL, "Usage: wiegand encode [w ] [ ] {...}"); + PrintAndLogEx(NORMAL, "Options:"); + PrintAndLogEx(NORMAL, " w see `wiegand list` for available formats"); + PrintAndLogEx(NORMAL, " c card number"); + PrintAndLogEx(NORMAL, " f facility code"); + PrintAndLogEx(NORMAL, " i issue Level"); + PrintAndLogEx(NORMAL, " o OEM code"); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "samples:"); + PrintAndLogEx(NORMAL, " wiegand encode w H10301 f 101 c 1337"); + return PM3_SUCCESS; +} +static int usage_wiegand_decode() { + PrintAndLogEx(NORMAL, "Decode raw hex to wiegand format"); + PrintAndLogEx(NORMAL, "Usage: wiegand decode [id]

"); + PrintAndLogEx(NORMAL, " p ignore invalid parity"); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Samples:"); + PrintAndLogEx(NORMAL, " wiegand decode 2006f623ae"); + return PM3_SUCCESS; +} + +void PrintTagId(wiegand_message_t *packed){ + if (packed->Top != 0) { + PrintAndLogEx(SUCCESS, "Card ID: %X%08X%08X", + (uint32_t)packed->Top, + (uint32_t)packed->Mid, + (uint32_t)packed->Bot) + ; + } else { + PrintAndLogEx(SUCCESS, "Card ID: %X%08X", + (uint32_t)packed->Mid, + (uint32_t)packed->Bot) + ; + } +} + +int CmdWiegandList(const char *Cmd) { + bool errors = false; + char cmdp = 0; + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { + case 'h': + return usage_wiegand_list(); + default: + PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } + } + HIDListFormats(); + return PM3_SUCCESS; +} + +int CmdWiegandEncode(const char *Cmd) { + + int format_idx = -1; + char format[16] = {0}; + + wiegand_card_t data; + memset(&data, 0, sizeof(wiegand_card_t)); + + bool errors = false; + char cmdp = 0; + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { + case 'h': + return usage_wiegand_encode(); + case 'w': + param_getstr(Cmd, cmdp + 1, format, sizeof(format)); + format_idx = HIDFindCardFormat(format); + if (format_idx == -1) { + PrintAndLogEx(WARNING, "Unknown format: %s", format); + errors = true; + } + cmdp += 2; + break; + case 'i': + data.IssueLevel = param_get32ex(Cmd, cmdp + 1, 0, 10); + cmdp += 2; + break; + case 'f': + data.FacilityCode = param_get32ex(Cmd, cmdp + 1, 0, 10); + cmdp += 2; + break; + case 'c': + data.CardNumber = param_get64ex(Cmd, cmdp + 1, 0, 10); + cmdp += 2; + break; + case 'o': + data.OEM = param_get32ex(Cmd, cmdp + 1, 0, 10); + cmdp += 2; + break; + default: + PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } + } + if (errors || cmdp == 0) return usage_wiegand_encode(); + + wiegand_message_t packed; + memset(&packed, 0, sizeof(wiegand_message_t)); + + if (HIDPack(format_idx, &data, &packed) == false) { + PrintAndLogEx(WARNING, "The card data could not be encoded in the selected format."); + return PM3_ESOFT; + } + + PrintTagId(&packed); + return PM3_SUCCESS; +} + +int CmdWiegandDecode(const char *Cmd) { + + uint32_t top = 0, mid = 0, bot = 0; + bool ignore_parity = false, gothex = false; + bool errors = false; + char cmdp = 0; + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + uint32_t strlen = param_getlength(Cmd, cmdp); + strlen++; // null termin + if ( strlen > 2 ) { + char *s = calloc(strlen, sizeof(uint8_t)); + param_getstr(Cmd, cmdp, s, strlen); + hexstring_to_u96(&top, &mid, &bot, s); + free(s); + gothex = true; + cmdp++; + continue; + } + switch (tolower(param_getchar(Cmd, cmdp))) { + case 'h': + return usage_wiegand_decode(); + case 'p': + ignore_parity = true; + cmdp++; + break; + default: + PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } + } + if (gothex == false) + errors = true; + + if (errors || cmdp < 1) return usage_wiegand_decode(); + + wiegand_message_t packed = initialize_message_object(top, mid, bot); + + HIDTryUnpack(&packed, ignore_parity); + return PM3_SUCCESS; +} + +static command_t CommandTable[] = { + {"help", CmdHelp, AlwaysAvailable, "This help"}, + {"list", CmdWiegandList, AlwaysAvailable, "List available wiegand formats"}, + {"encode", CmdWiegandEncode, AlwaysAvailable, "Convert "}, + {"decode", CmdWiegandDecode, AlwaysAvailable, "Convert raw hex to wiegand format"}, + {NULL, NULL, NULL, NULL} +}; + +static int CmdHelp(const char *Cmd) { + (void)Cmd; // Cmd is not used so far + CmdsHelp(CommandTable); + return PM3_SUCCESS; +} + +int CmdWiegand(const char *Cmd) { + clearCommandBuffer(); + return CmdsParse(CommandTable, Cmd); +} diff --git a/client/cmdwiegand.h b/client/cmdwiegand.h new file mode 100644 index 000000000..2c6e8fb40 --- /dev/null +++ b/client/cmdwiegand.h @@ -0,0 +1,20 @@ +//----------------------------------------------------------------------------- +// Copyright (C) 2019 iceman +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// Trace commands +//----------------------------------------------------------------------------- + +#ifndef CMDWIEGAND_H__ +#define CMDWIEGAND_H__ + +#include "common.h" + +int CmdWiegand(const char *Cmd); +int CmdWiegandList(const char *Cmd); +int CmdWiegandEncode(const char *Cmd); +int CmdWiegandDecode(const char *Cmd); +#endif diff --git a/client/util.c b/client/util.c index 55b114fdb..f74605562 100644 --- a/client/util.c +++ b/client/util.c @@ -878,3 +878,20 @@ char *strmcopy(const char *buf) { } return str; } + +/** + * Converts a hex string to component "hi2", "hi" and "lo" 32-bit integers, one nibble + * at a time. + * + * Returns the number of nibbles (4 bits) entered. + */ +int hexstring_to_u96(uint32_t* hi2, uint32_t* hi, uint32_t* lo, const char* str) { + int n = 0, i = 0; + + while (sscanf(&str[i++], "%1x", &n ) == 1) { + *hi2 = (*hi2 << 4) | (*hi >> 28); + *hi = (*hi << 4) | (*lo >> 28); + *lo = (*lo << 4) | (n & 0xf); + } + return i - 1; +} diff --git a/client/util.h b/client/util.h index 7cfea0f8b..df69493d2 100644 --- a/client/util.h +++ b/client/util.h @@ -98,4 +98,5 @@ void clean_ascii(unsigned char *buf, size_t len); void strcleanrn(char *buf, size_t len); void strcreplace(char *buf, size_t len, char from, char to); char *strmcopy(const char *buf); +int hexstring_to_u96(uint32_t* hi2, uint32_t* hi, uint32_t* lo, const char* str); #endif diff --git a/client/wiegand_formats.c b/client/wiegand_formats.c new file mode 100644 index 000000000..7228abd82 --- /dev/null +++ b/client/wiegand_formats.c @@ -0,0 +1,715 @@ +//----------------------------------------------------------------------------- +// Copyright (C) 2018 grauerfuchs +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// HID card format packing/unpacking routines +//----------------------------------------------------------------------------- +#include "wiegand_formats.h" + +bool Pack_H10301(wiegand_card_t* card, wiegand_message_t* packed){ + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0xFF) return false; // Can't encode FC. + if (card->CardNumber > 0xFFFF) return false; // Can't encode CN. + if (card->IssueLevel > 0) return false; // Not used in this format + if (card->OEM > 0) return false; // Not used in this format + + packed->Length = 26; // Set number of bits + packed->Bot |= (card->CardNumber & 0xFFFF) << 1; + packed->Bot |= (card->FacilityCode & 0xFF) << 17; + packed->Bot |= oddparity32((packed->Bot >> 1) & 0xFFF) & 1; + packed->Bot |= (evenparity32((packed->Bot >> 13) & 0xFFF) & 1) << 25; + return add_HID_header(packed); +} + +bool Unpack_H10301(wiegand_message_t* packed, wiegand_card_t* card){ + memset(card, 0, sizeof(wiegand_card_t)); + if (packed->Length != 26) return false; // Wrong length? Stop here. + + card->CardNumber = (packed->Bot >> 1) & 0xFFFF; + card->FacilityCode = (packed->Bot >> 17) & 0xFF; + card->ParityValid = + (oddparity32((packed->Bot >> 1) & 0xFFF) == (packed->Bot & 1)) && + ((evenparity32((packed->Bot >> 13) & 0xFFF) & 1) == ((packed->Bot >> 25) & 1)); + return true; +} + +bool Pack_Tecom27(wiegand_card_t* card, wiegand_message_t* packed){ + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0x7FF) return false; // Can't encode FC. + if (card->CardNumber > 0xFFFF) return false; // Can't encode CN. + if (card->IssueLevel > 0) return false; // Not used in this format + if (card->OEM > 0) return false; // Not used in this format + + packed->Length = 27; + set_nonlinear_field(packed, card->FacilityCode, 10, (uint8_t[]){15, 19, 24, 23, 22, 18, 6, 10, 14, 3, 2}); + set_nonlinear_field(packed, card->CardNumber, 16, (uint8_t[]){0, 1, 13, 12, 9, 26, 20, 16, 17, 21, 25, 7, 8, 11, 4, 5}); + return add_HID_header(packed); +} + +bool Unpack_Tecom27(wiegand_message_t* packed, wiegand_card_t* card){ + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 27) return false; // Wrong length? Stop here. + + card->CardNumber = get_nonlinear_field(packed, 16, (uint8_t[]){0, 1, 13, 12, 9, 26, 20, 16, 17, 21, 25, 7, 8, 11, 4, 5}); + card->FacilityCode = get_nonlinear_field(packed, 10, (uint8_t[]){15, 19, 24, 23, 22, 18, 6, 10, 14, 3, 2}); + return true; +} + +bool Pack_2804W(wiegand_card_t* card, wiegand_message_t* packed){ + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0x0FF) return false; // Can't encode FC. + if (card->CardNumber > 0x7FFF) return false; // Can't encode CN. + if (card->IssueLevel > 0) return false; // Not used in this format + if (card->OEM > 0) return false; // Not used in this format + + packed->Length = 28; + set_linear_field(packed, card->FacilityCode, 4, 8); + set_linear_field(packed, card->CardNumber, 12, 15); + set_bit_by_position(packed, + oddparity32(get_nonlinear_field(packed, 16, (uint8_t[]){4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19, 20, 22, 23, 25, 26})) + , 2); + set_bit_by_position(packed, + evenparity32(get_linear_field(packed, 1, 13)) + , 0); + set_bit_by_position(packed, + oddparity32(get_linear_field(packed, 0, 27)) + , 27); + return add_HID_header(packed); +} + +bool Unpack_2804W(wiegand_message_t* packed, wiegand_card_t* card){ + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 28) return false; // Wrong length? Stop here. + + card->FacilityCode = get_linear_field(packed, 4, 8); + card->CardNumber = get_linear_field(packed, 12, 15); + card->ParityValid = + (get_bit_by_position(packed, 0) == evenparity32(get_linear_field(packed, 1, 13))) && + (get_bit_by_position(packed, 2) == oddparity32(get_nonlinear_field(packed, 16, (uint8_t[]){4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19, 20, 22, 23, 25, 26}))) && + (get_bit_by_position(packed, 27) == oddparity32(get_linear_field(packed, 0, 27))); + return true; +} + +bool Pack_ATSW30(wiegand_card_t* card, wiegand_message_t* packed){ + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0xFFF) return false; // Can't encode FC. + if (card->CardNumber > 0xFFFF) return false; // Can't encode CN. + if (card->IssueLevel > 0) return false; // Not used in this format + if (card->OEM > 0) return false; // Not used in this format + + packed->Length = 30; + set_linear_field(packed, card->FacilityCode, 1, 12); + set_linear_field(packed, card->CardNumber, 13, 16); + set_bit_by_position(packed, + evenparity32(get_linear_field(packed, 1, 12)) + , 0); + set_bit_by_position(packed, + oddparity32(get_linear_field(packed, 13, 16)) + , 29); + return add_HID_header(packed); +} + +bool Unpack_ATSW30(wiegand_message_t* packed, wiegand_card_t* card){ + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 30) return false; // Wrong length? Stop here. + + card->FacilityCode = get_linear_field(packed, 1, 12); + card->CardNumber = get_linear_field(packed, 13, 16); + card->ParityValid = + (get_bit_by_position(packed, 0) == evenparity32(get_linear_field(packed, 1, 12))) && + (get_bit_by_position(packed, 29) == oddparity32(get_linear_field(packed, 13, 16))); + return true; +} + +bool Pack_ADT31(wiegand_card_t* card, wiegand_message_t* packed){ + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0x0F) return false; // Can't encode FC. + if (card->CardNumber > 0x7FFFFF) return false; // Can't encode CN. + if (card->IssueLevel > 0) return false; // Not used in this format + if (card->OEM > 0) return false; // Not used in this format + + packed->Length = 31; + set_linear_field(packed, card->FacilityCode, 1, 4); + set_linear_field(packed, card->CardNumber, 5, 23); + // Parity not known, but 4 bits are unused. + return add_HID_header(packed); +} + +bool Unpack_ADT31(wiegand_message_t* packed, wiegand_card_t* card){ + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 31) return false; // Wrong length? Stop here. + card->FacilityCode = get_linear_field(packed, 1, 4); + card->CardNumber = get_linear_field(packed, 5, 23); + return true; +} + +bool Pack_Kastle(wiegand_card_t* card, wiegand_message_t* packed){ + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0x00FF) return false; // Can't encode FC. + if (card->CardNumber > 0x0000FFFF) return false; // Can't encode CN. + if (card->IssueLevel > 0x001F) return false; // IL is only 5 bits. + if (card->OEM > 0) return false; // Not used in this format + + packed->Length = 32; // Set number of bits + set_bit_by_position(packed, 1, 1); // Always 1 + set_linear_field(packed, card->IssueLevel, 2, 5); + set_linear_field(packed, card->FacilityCode, 7, 8); + set_linear_field(packed, card->CardNumber, 15, 16); + set_bit_by_position(packed, evenparity32(get_linear_field(packed, 1, 16)), 0); + set_bit_by_position(packed, oddparity32(get_linear_field(packed, 14, 17)), 31); + return add_HID_header(packed); +} + +bool Unpack_Kastle(wiegand_message_t* packed, wiegand_card_t* card){ + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 32) return false; // Wrong length? Stop here. + if (get_bit_by_position(packed, 1) != 1) return false; // Always 1 in this format + + card->IssueLevel = get_linear_field(packed, 2, 5); + card->FacilityCode = get_linear_field(packed, 7, 8); + card->CardNumber = get_linear_field(packed, 15, 16); + card->ParityValid = + (get_bit_by_position(packed, 0) == evenparity32(get_linear_field(packed, 1, 16))) && + (get_bit_by_position(packed, 31) == oddparity32(get_linear_field(packed, 14, 17))); + return true; +} + +bool Pack_D10202(wiegand_card_t* card, wiegand_message_t* packed){ + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0x007F) return false; // Can't encode FC. + if (card->CardNumber > 0x00FFFFFF) return false; // Can't encode CN. + if (card->IssueLevel > 0) return false; // Not used in this format + if (card->OEM > 0) return false; // Not used in this format + + packed->Length = 33; // Set number of bits + set_linear_field(packed, card->FacilityCode, 1, 7); + set_linear_field(packed, card->CardNumber, 8, 24); + set_bit_by_position(packed, evenparity32(get_linear_field(packed, 1, 16)), 0); + set_bit_by_position(packed, oddparity32(get_linear_field(packed, 16, 16)), 32); + return add_HID_header(packed); +} + +bool Unpack_D10202(wiegand_message_t* packed, wiegand_card_t* card){ + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 33) return false; // Wrong length? Stop here. + + card->CardNumber = get_linear_field(packed, 8, 24); + card->FacilityCode = get_linear_field(packed, 1, 7); + card->ParityValid = + (get_bit_by_position(packed, 0) == evenparity32(get_linear_field(packed, 1, 16))) && + (get_bit_by_position(packed, 32) == oddparity32(get_linear_field(packed, 16, 16))); + return true; +} + +bool Pack_H10306(wiegand_card_t* card, wiegand_message_t* packed){ + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0xFFFF) return false; // Can't encode FC. + if (card->CardNumber > 0xFFFF) return false; // Can't encode CN. + if (card->IssueLevel > 0) return false; // Not used in this format + if (card->OEM > 0) return false; // Not used in this format + + packed->Length = 34; // Set number of bits + packed->Bot |= (card->CardNumber & 0xFFFF) << 1; + packed->Bot |= (card->FacilityCode & 0x7FFF) << 17; + packed->Mid |= (card->FacilityCode & 0x8000) >> 15; + packed->Mid |= (evenparity32((packed->Mid & 0x00000001) ^ (packed->Bot & 0xFFFE0000)) & 1) << 1; + packed->Bot |= ( oddparity32(packed->Bot & 0x0001FFFE) & 1); + return add_HID_header(packed); +} + +bool Unpack_H10306(wiegand_message_t* packed, wiegand_card_t* card){ + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 34) return false; // Wrong length? Stop here. + + card->CardNumber = (packed->Bot >> 1) & 0xFFFF; + card->FacilityCode = ((packed->Mid & 1) << 15) | ((packed->Bot >> 17) & 0xFF); + card->ParityValid = + ((evenparity32((packed->Mid & 0x00000001) ^ (packed->Bot & 0xFFFE0000)) & 1) == ((packed->Mid >> 1) & 1)) && + ((oddparity32(packed->Bot & 0x0001FFFE) & 1) == ((packed->Bot & 1))); + return true; +} + +bool Pack_N10002(wiegand_card_t* card, wiegand_message_t* packed){ + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0xFF) return false; // Can't encode FC. + if (card->CardNumber > 0xFFFF) return false; // Can't encode CN. + if (card->IssueLevel > 0) return false; // Not used in this format + if (card->OEM > 0) return false; // Not used in this format + + packed->Length = 34; // Set number of bits + set_linear_field(packed, card->FacilityCode, 9, 8); + set_linear_field(packed, card->CardNumber, 17, 16); + return add_HID_header(packed); +} + +bool Unpack_N10002(wiegand_message_t* packed, wiegand_card_t* card){ + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 34) return false; // Wrong length? Stop here. + + card->CardNumber = get_linear_field(packed, 17, 16); + card->FacilityCode = get_linear_field(packed, 9, 8); + return true; +} + +bool Pack_C1k35s(wiegand_card_t* card, wiegand_message_t* packed){ + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0xFFF) return false; // Can't encode FC. + if (card->CardNumber > 0xFFFFF) return false; // Can't encode CN. + if (card->IssueLevel > 0) return false; // Not used in this format + if (card->OEM > 0) return false; // Not used in this format + + packed->Length = 35; // Set number of bits + packed->Bot |= (card->CardNumber & 0x000FFFFF) << 1; + packed->Bot |= (card->FacilityCode & 0x000007FF) << 21; + packed->Mid |= (card->FacilityCode & 0x00000800) >> 11; + packed->Mid |= (evenparity32((packed->Mid & 0x00000001) ^ (packed->Bot & 0xB6DB6DB6)) & 1) << 1; + packed->Bot |= ( oddparity32((packed->Mid & 0x00000003) ^ (packed->Bot & 0x6DB6DB6C)) & 1); + packed->Mid |= ( oddparity32((packed->Mid & 0x00000003) ^ (packed->Bot & 0xFFFFFFFF)) & 1) << 2; + return add_HID_header(packed); +} + +bool Unpack_C1k35s(wiegand_message_t* packed, wiegand_card_t* card){ + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 35) return false; // Wrong length? Stop here. + + card->CardNumber = (packed->Bot >> 1) & 0x000FFFFF; + card->FacilityCode = ((packed->Mid & 1) << 11) | ((packed->Bot >> 21)); + card->ParityValid = + (evenparity32((packed->Mid & 0x00000001) ^ (packed->Bot & 0xB6DB6DB6)) == ((packed->Mid >> 1) & 1)) && + ( oddparity32((packed->Mid & 0x00000003) ^ (packed->Bot & 0x6DB6DB6C)) == ((packed->Bot >> 0) & 1)) && + ( oddparity32((packed->Mid & 0x00000003) ^ (packed->Bot & 0xFFFFFFFF)) == ((packed->Mid >> 2) & 1)); + return true; +} + +bool Pack_H10320(wiegand_card_t* card, wiegand_message_t* packed){ + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0) return false; // Can't encode FC. (none in this format) + if (card->CardNumber > 99999999) return false; // Can't encode CN. + if (card->IssueLevel > 0) return false; // Not used in this format + if (card->OEM > 0) return false; // Not used in this format + + packed->Length = 36; // Set number of bits + // This card is BCD-encoded rather than binary. Set the 4-bit groups independently. + for (uint32_t idx = 0; idx < 8; idx++){ + set_linear_field(packed, (uint64_t)(card->CardNumber / pow(10, 7-idx)) % 10, idx * 4, 4); + } + set_bit_by_position(packed, evenparity32( + get_nonlinear_field(packed, 8, (uint8_t[]){0, 4, 8, 12, 16, 20, 24, 28}) + ), 32); + set_bit_by_position(packed, oddparity32( + get_nonlinear_field(packed, 8, (uint8_t[]){1, 5, 9, 13, 17, 21, 25, 29}) + ), 33); + set_bit_by_position(packed, evenparity32( + get_nonlinear_field(packed, 8, (uint8_t[]){2, 6, 10, 14, 18, 22, 28, 30}) + ), 34); + set_bit_by_position(packed, evenparity32( + get_nonlinear_field(packed, 8, (uint8_t[]){3, 7, 11, 15, 19, 23, 29, 31}) + ), 35); + return add_HID_header(packed); +} + +bool Unpack_H10320(wiegand_message_t* packed, wiegand_card_t* card){ + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 36) return false; // Wrong length? Stop here. + + // This card is BCD-encoded rather than binary. Get the 4-bit groups independently. + for (uint32_t idx = 0; idx < 8; idx++){ + uint64_t val = get_linear_field(packed, idx * 4, 4); + if (val > 9){ + // Violation of BCD; Zero and exit. + card->CardNumber = 0; + return false; + } else { + card->CardNumber += val * pow(10, 7-idx); + } + } + card->ParityValid = + (get_bit_by_position(packed, 32) == evenparity32(get_nonlinear_field(packed, 8, (uint8_t[]){0, 4, 8, 12, 16, 20, 24, 28}))) && + (get_bit_by_position(packed, 33) == oddparity32(get_nonlinear_field(packed, 8, (uint8_t[]){1, 5, 9, 13, 17, 21, 25, 29}))) && + (get_bit_by_position(packed, 34) == evenparity32(get_nonlinear_field(packed, 8, (uint8_t[]){2, 6, 10, 14, 18, 22, 28, 30}))) && + (get_bit_by_position(packed, 35) == evenparity32(get_nonlinear_field(packed, 8, (uint8_t[]){3, 7, 11, 15, 19, 23, 29, 31}))); + return true; +} + +bool Pack_S12906(wiegand_card_t* card, wiegand_message_t* packed){ + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0xFF) return false; // Can't encode FC. + if (card->IssueLevel > 0x03) return false; // Can't encode IL. + if (card->CardNumber > 0x00FFFFFF) return false; // Can't encode CN. + if (card->OEM > 0) return false; // Not used in this format + + packed->Length = 36; // Set number of bits + set_linear_field(packed, card->FacilityCode, 1, 8); + set_linear_field(packed, card->IssueLevel, 9, 2); + set_linear_field(packed, card->CardNumber, 11, 24); + set_bit_by_position(packed, oddparity32(get_linear_field(packed, 1, 17)), 0); + set_bit_by_position(packed, oddparity32(get_linear_field(packed, 17, 18)), 35); + return add_HID_header(packed); +} + +bool Unpack_S12906(wiegand_message_t* packed, wiegand_card_t* card){ + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 36) return false; // Wrong length? Stop here. + + card->FacilityCode = get_linear_field(packed, 1, 8); + card->IssueLevel = get_linear_field(packed, 9, 2); + card->CardNumber = get_linear_field(packed, 11, 24); + card->ParityValid = + (get_bit_by_position(packed, 0) == oddparity32(get_linear_field(packed, 1, 17))) && + (get_bit_by_position(packed, 35) == oddparity32(get_linear_field(packed, 17, 18))); + return true; +} + +bool Pack_Sie36(wiegand_card_t* card, wiegand_message_t* packed){ + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0x0003FFFF) return false; // Can't encode FC. + if (card->CardNumber > 0x0000FFFF) return false; // Can't encode CN. + if (card->IssueLevel > 0) return false; // Not used in this format + if (card->OEM > 0) return false; // Not used in this format + + packed->Length = 36; // Set number of bits + set_linear_field(packed, card->FacilityCode, 1, 18); + set_linear_field(packed, card->CardNumber, 19, 16); + set_bit_by_position(packed, + oddparity32(get_nonlinear_field(packed, 23, (uint8_t[]){1, 3, 4, 6, 7, 9, 10, 12, 13, 15, 16, 18, 19, 21, 22, 24, 25, 27, 28, 30, 31, 33, 34})) + , 0); + set_bit_by_position(packed, + evenparity32(get_nonlinear_field(packed, 23, (uint8_t[]){1, 2, 4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19, 20, 22, 23, 25, 26, 28, 29, 31, 32, 34})) + , 35); + return add_HID_header(packed); +} + +bool Unpack_Sie36(wiegand_message_t* packed, wiegand_card_t* card){ + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 36) return false; // Wrong length? Stop here. + + card->FacilityCode = get_linear_field(packed, 1, 18); + card->CardNumber = get_linear_field(packed, 19, 16); + card->ParityValid = + (get_bit_by_position(packed, 0) == oddparity32(get_nonlinear_field(packed, 23, (uint8_t[]){1, 3, 4, 6, 7, 9, 10, 12, 13, 15, 16, 18, 19, 21, 22, 24, 25, 27, 28, 30, 31, 33, 34}))) && + (get_bit_by_position(packed, 35) == oddparity32(get_nonlinear_field(packed, 23, (uint8_t[]){1, 2, 4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19, 20, 22, 23, 25, 26, 28, 29, 31, 32, 34}))); + return true; +} + +bool Pack_C15001(wiegand_card_t* card, wiegand_message_t* packed){ + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0x000000FF) return false; // Can't encode FC. + if (card->CardNumber > 0x0000FFFF) return false; // Can't encode CN. + if (card->IssueLevel > 0) return false; // Not used in this format + if (card->OEM > 0x000003FF) return false; // Can't encode OEM. + + packed->Length = 36; // Set number of bits + set_linear_field(packed, card->OEM, 1, 10); + set_linear_field(packed, card->FacilityCode, 11, 8); + set_linear_field(packed, card->CardNumber, 19, 16); + set_bit_by_position(packed, evenparity32(get_linear_field(packed, 1, 17)), 0); + set_bit_by_position(packed, oddparity32(get_linear_field(packed, 18, 17)), 35); + return add_HID_header(packed); +} + +bool Unpack_C15001(wiegand_message_t* packed, wiegand_card_t* card){ + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 36) return false; // Wrong length? Stop here. + + card->OEM = get_linear_field(packed, 1, 10); + card->FacilityCode = get_linear_field(packed, 11, 8); + card->CardNumber = get_linear_field(packed, 19, 16); + card->ParityValid = + (get_bit_by_position(packed, 0) == evenparity32(get_linear_field(packed, 1, 17))) && + (get_bit_by_position(packed, 35) == oddparity32(get_linear_field(packed, 18, 17))); + return true; +} + +bool Pack_H10302(wiegand_card_t* card, wiegand_message_t* packed){ + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0) return false; // Can't encode FC. (none in this format) + if (card->CardNumber > 0x00000007FFFFFFFF) return false; // Can't encode CN. + if (card->IssueLevel > 0) return false; // Not used in this format + if (card->OEM > 0) return false; // Not used in this format + + packed->Length = 37; // Set number of bits + set_linear_field(packed, card->CardNumber, 1, 35); + set_bit_by_position(packed, evenparity32(get_linear_field(packed, 1, 18)), 0); + set_bit_by_position(packed, oddparity32(get_linear_field(packed, 18, 18)), 36); + return add_HID_header(packed); +} + +bool Unpack_H10302(wiegand_message_t* packed, wiegand_card_t* card){ + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 37) return false; // Wrong length? Stop here. + + card->CardNumber = get_linear_field(packed, 1, 35); + card->ParityValid = + (get_bit_by_position(packed, 0) == evenparity32(get_linear_field(packed, 1, 18))) && + (get_bit_by_position(packed, 36) == oddparity32(get_linear_field(packed, 18, 18))); + return true; +} + +bool Pack_H10304(wiegand_card_t* card, wiegand_message_t* packed){ + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0x0000FFFF) return false; // Can't encode FC. + if (card->CardNumber > 0x0007FFFF) return false; // Can't encode CN. + if (card->IssueLevel > 0) return false; // Not used in this format + if (card->OEM > 0) return false; // Not used in this format + + packed->Length = 37; // Set number of bits + packed->Bot |= (card->CardNumber & 0x0007FFFF) << 1; + packed->Bot |= (card->FacilityCode & 0x00000FFF) << 20; + packed->Mid |= (card->FacilityCode & 0x0000F000) >> 12; + packed->Mid |= (evenparity32((packed->Mid & 0x0000000F) ^ (packed->Bot & 0xFFFC0000)) & 1) << 4; + packed->Bot |= ( oddparity32(packed->Bot & 0x0007FFFE) & 1); + return add_HID_header(packed); +} + +bool Unpack_H10304(wiegand_message_t* packed, wiegand_card_t* card){ + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 37) return false; // Wrong length? Stop here. + + card->CardNumber = (packed->Bot >> 1) & 0x0007FFFF; + card->FacilityCode = ((packed->Mid & 0xF) << 12) | ((packed->Bot >> 20)); + card->ParityValid = + (evenparity32((packed->Mid & 0x0000000F) ^ (packed->Bot & 0xFFFC0000)) == ((packed->Mid >> 4) & 1)) && + (oddparity32( packed->Bot & 0x0007FFFE) == (packed->Bot & 1)); + return true; +} + +bool Pack_P10001(wiegand_card_t* card, wiegand_message_t* packed){ + + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0xFFF) return false; // Can't encode FC. + if (card->CardNumber > 0xFFFF) return false; // Can't encode CN. + if (card->IssueLevel > 0) return false; // Not used in this format + if (card->OEM > 0) return false; // Not used in this format + + packed->Length = 40; // Set number of bits + set_linear_field(packed, 0xF, 0, 4); + set_linear_field(packed, card->FacilityCode, 4, 12); + set_linear_field(packed, card->CardNumber, 16, 16); + set_linear_field(packed, + get_linear_field(packed, 0, 8) ^ + get_linear_field(packed, 8, 8) ^ + get_linear_field(packed, 16, 8) ^ + get_linear_field(packed, 24, 8) + , 32, 8); + return add_HID_header(packed); +} + +bool Unpack_P10001(wiegand_message_t* packed, wiegand_card_t* card){ + + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 40) return false; // Wrong length? Stop here. + + card->CardNumber = get_linear_field(packed, 16, 16); + card->FacilityCode = get_linear_field(packed, 4, 12); + card->ParityValid = ( + get_linear_field(packed, 0, 8) ^ + get_linear_field(packed, 8, 8) ^ + get_linear_field(packed, 16, 8) ^ + get_linear_field(packed, 24, 8) + ) == get_linear_field(packed, 32, 8); + return true; +} + +bool Pack_C1k48s(wiegand_card_t* card, wiegand_message_t* packed){ + + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0x003FFFFF) return false; // Can't encode FC. + if (card->CardNumber > 0x007FFFFF) return false; // Can't encode CN. + if (card->IssueLevel > 0) return false; // Not used in this format + if (card->OEM > 0) return false; // Not used in this format + + packed->Length = 48; // Set number of bits + packed->Bot |= (card->CardNumber & 0x007FFFFF) << 1; + packed->Bot |= (card->FacilityCode & 0x000000FF) << 24; + packed->Mid |= (card->FacilityCode & 0x003FFF00) >> 8; + packed->Mid |= (evenparity32((packed->Mid & 0x00001B6D) ^ (packed->Bot & 0xB6DB6DB6)) & 1) << 14; + packed->Bot |= ( oddparity32((packed->Mid & 0x000036DB) ^ (packed->Bot & 0x6DB6DB6C)) & 1); + packed->Mid |= ( oddparity32((packed->Mid & 0x00007FFF) ^ (packed->Bot & 0xFFFFFFFF)) & 1) << 15; + return add_HID_header(packed); +} + +bool Unpack_C1k48s(wiegand_message_t* packed, wiegand_card_t* card){ + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 48) return false; // Wrong length? Stop here. + + card->CardNumber = (packed->Bot >> 1) & 0x007FFFFF; + card->FacilityCode = ((packed->Mid & 0x00003FFF) << 8) | ((packed->Bot >> 24)); + card->ParityValid = + (evenparity32((packed->Mid & 0x00001B6D) ^ (packed->Bot & 0xB6DB6DB6)) == ((packed->Mid >> 14) & 1)) && + ( oddparity32((packed->Mid & 0x000036DB) ^ (packed->Bot & 0x6DB6DB6C)) == ((packed->Bot >> 0) & 1)) && + ( oddparity32((packed->Mid & 0x00007FFF) ^ (packed->Bot & 0xFFFFFFFF)) == ((packed->Mid >> 15) & 1)); + return true; +} + +static const cardformat_t FormatTable[] = { + {"H10301", Pack_H10301, Unpack_H10301, "HID H10301 26-bit", {1, 1, 0, 0, 1}}, // imported from old pack/unpack + {"Tecom27", Pack_Tecom27, Unpack_Tecom27, "Tecom 27-bit", {1, 1, 0, 0, 1}}, // from cardinfo.barkweb.com.au + {"2804W", Pack_2804W, Unpack_2804W, "2804 Wiegand", {1, 1, 0, 0, 1}}, // from cardinfo.barkweb.com.au + {"ATSW30", Pack_ATSW30, Unpack_ATSW30, "ATS Wiegand 30-bit", {1, 1, 0, 0, 1}}, // from cardinfo.barkweb.com.au + {"ADT31", Pack_ADT31, Unpack_ADT31, "HID ADT 31-bit", {1, 1, 0, 0, 1}}, // from cardinfo.barkweb.com.au + {"Kastle", Pack_Kastle, Unpack_Kastle, "Kastle 32-bit", {1, 1, 1, 0, 1}}, // from @xilni; PR #23 on RfidResearchGroup/proxmark3 + {"D10202", Pack_D10202, Unpack_D10202, "HID D10202 33-bit", {1, 1, 0, 0, 1}}, // from cardinfo.barkweb.com.au + {"H10306", Pack_H10306, Unpack_H10306, "HID H10306 34-bit", {1, 1, 0, 0, 1}}, // imported from old pack/unpack + {"N10002", Pack_N10002, Unpack_N10002, "HID N10002 34-bit", {1, 1, 0, 0, 1}}, // from cardinfo.barkweb.com.au + {"C1k35s", Pack_C1k35s, Unpack_C1k35s, "HID Corporate 1000 35-bit standard layout", {1, 1, 0, 0, 1}}, // imported from old pack/unpack + {"C15001", Pack_C15001, Unpack_C15001, "HID KeySpan 36-bit", {1, 1, 0, 1, 1}}, // from Proxmark forums + {"S12906", Pack_S12906, Unpack_S12906, "HID Simplex 36-bit", {1, 1, 1, 0, 1}}, // from cardinfo.barkweb.com.au + {"Sie36", Pack_Sie36, Unpack_Sie36, "HID 36-bit Siemens", {1, 1, 0, 0, 1}}, // from cardinfo.barkweb.com.au + {"H10320", Pack_H10320, Unpack_H10320, "HID H10320 36-bit BCD", {1, 0, 0, 0, 1}}, // from Proxmark forums + {"H10302", Pack_H10302, Unpack_H10302, "HID H10302 37-bit huge ID", {1, 0, 0, 0, 1}}, // from Proxmark forums + {"H10304", Pack_H10304, Unpack_H10304, "HID H10304 37-bit", {1, 1, 0, 0, 1}}, // imported from old pack/unpack + {"P10001", Pack_P10001, Unpack_P10001, "HID P10001 Honeywell 40-bit" }, // from cardinfo.barkweb.com.au + {"C1k48s", Pack_C1k48s, Unpack_C1k48s, "HID Corporate 1000 48-bit standard layout", {1, 1, 0, 0, 1}}, // imported from old pack/unpack + {NULL, NULL, NULL, NULL, {0, 0, 0, 0, 0}} // Must null terminate array +}; + +void HIDListFormats(){ + if (FormatTable[0].Name == NULL) + return; + + PrintAndLogEx(NORMAL, "%-10s %s", "Name", "Description"); + PrintAndLogEx(NORMAL, "------------------------------------------------------------"); + + int i = 0; + while (FormatTable[i].Name) { + PrintAndLogEx(NORMAL, _YELLOW_("%-10s")" %-30s", FormatTable[i].Name, FormatTable[i].Descrp); + ++i; + } + PrintAndLogEx(NORMAL, ""); + return; +} + +cardformat_t HIDGetCardFormat(int idx){ + return FormatTable[idx]; +} + +int HIDFindCardFormat(const char *format) { + + if (FormatTable[0].Name == NULL) + return -1; + + int i = 0; + +// str_lower + + while (FormatTable[i].Name && strcmp(FormatTable[i].Name, format)) { + ++i; + } + + if (FormatTable[i].Name) + return i; + + return -1; +} + +bool HIDPack(int format_idx, wiegand_card_t* card, wiegand_message_t* packed){ + memset(packed, 0, sizeof(wiegand_message_t)); + + if (format_idx < 0 || format_idx >= (sizeof(FormatTable) / sizeof(FormatTable[0]))) + return false; + + return FormatTable[format_idx].Pack(card, packed); +} + +void HIDDisplayUnpackedCard(wiegand_card_t* card, const cardformat_t format){ + +/* + PrintAndLogEx(SUCCESS, " Format: %s (%s)", format.Name, format.Descrp); + + if (format.Fields.hasFacilityCode) + PrintAndLogEx(SUCCESS, "Facility Code: %d",card->FacilityCode); + + if (format.Fields.hasCardNumber) + PrintAndLogEx(SUCCESS, " Card Number: %d",card->CardNumber); + + if (format.Fields.hasIssueLevel) + PrintAndLogEx(SUCCESS, " Issue Level: %d",card->IssueLevel); + + if (format.Fields.hasOEMCode) + PrintAndLogEx(SUCCESS, " OEM Code: %d",card->OEM); + + if (format.Fields.hasParity) + PrintAndLogEx(SUCCESS, " Parity: %s",card->ParityValid ? "Valid" : "Invalid"); +*/ + + char s[80] = {0}; + if (format.Fields.hasFacilityCode) + snprintf(s, sizeof(s), "FC: %d", card->FacilityCode); + + if (format.Fields.hasCardNumber) + snprintf(s + strlen(s), sizeof(s) - strlen(s), " CN: %" PRIu64, card->CardNumber); + + if (format.Fields.hasIssueLevel) + snprintf(s + strlen(s), sizeof(s) - strlen(s), " Issue %d", card->IssueLevel); + + if (format.Fields.hasOEMCode) + snprintf(s + strlen(s), sizeof(s) - strlen(s), " OEM: %d",card->OEM); + + if (format.Fields.hasParity) + snprintf(s + strlen(s), sizeof(s) - strlen(s), " parity: %s", card->ParityValid ? "valid" : "invalid"); + + PrintAndLogEx(SUCCESS, "%s [%s - %s]", s, format.Name, format.Descrp); +} + +bool HIDTryUnpack(wiegand_message_t* packed, bool ignore_parity){ + if (FormatTable[0].Name == NULL) + return false; + + bool result = false; + int i = 0; + wiegand_card_t card; + memset(&card, 0, sizeof(wiegand_card_t)); + + while (FormatTable[i].Name) { + if (FormatTable[i].Unpack(packed, &card)) { + if (ignore_parity || !FormatTable[i].Fields.hasParity || card.ParityValid) { + result = true; + HIDDisplayUnpackedCard(&card, FormatTable[i]); + } + } + ++i; + } + if ( result == false ) { + PrintAndLogEx(SUCCESS, "Unknown. Bit len %d", packed->Length); + } + + return result; +} diff --git a/client/wiegand_formats.h b/client/wiegand_formats.h new file mode 100644 index 000000000..c904f789a --- /dev/null +++ b/client/wiegand_formats.h @@ -0,0 +1,48 @@ +//----------------------------------------------------------------------------- +// Copyright (C) 2018 grauerfuchs +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// Wiegand format packing/unpacking routines +//----------------------------------------------------------------------------- + +#ifndef WIEGAND_FORMATS_H__ +#define WIEGAND_FORMATS_H__ + +#include // memset +#include +#include +#include +#include +#include +#include "cmddata.h" +#include "wiegand_formatutils.h" +#include "parity.h" // for parity +#include "ui.h" + +typedef struct { + bool hasCardNumber; + bool hasFacilityCode; + bool hasIssueLevel; + bool hasOEMCode; + bool hasParity; +} cardformatdescriptor_t; + +// Structure for defined Wiegand card formats available for packing/unpacking +typedef struct { + const char* Name; + bool (*Pack)(wiegand_card_t* card, wiegand_message_t* packed); + bool (*Unpack)(wiegand_message_t* packed, wiegand_card_t* card); + const char* Descrp; + cardformatdescriptor_t Fields; +} cardformat_t; + +void HIDListFormats(); +int HIDFindCardFormat(const char *format); +cardformat_t HIDGetCardFormat(int idx); +bool HIDPack(int FormatIndex, wiegand_card_t* card, wiegand_message_t* packed); +bool HIDTryUnpack(wiegand_message_t* packed, bool ignoreParity); + +#endif diff --git a/client/wiegand_formatutils.c b/client/wiegand_formatutils.c new file mode 100644 index 000000000..dd3678daf --- /dev/null +++ b/client/wiegand_formatutils.c @@ -0,0 +1,185 @@ +//----------------------------------------------------------------------------- +// Copyright (C) 2018 grauerfuchs +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// Wiegand card format packing/unpacking support functions +//----------------------------------------------------------------------------- + +#include +#include +#include +#include +#include "wiegand_formatutils.h" +#include "ui.h" + +bool get_bit_by_position(wiegand_message_t* data, uint8_t pos){ + if (pos >= data->Length) return false; + pos = (data->Length - pos) - 1; // invert ordering; Indexing goes from 0 to 1. Subtract 1 for weight of bit. + bool result = false; + if (pos > 95) + result = false; + else if (pos > 63) + result = (data->Top >> (pos - 64)) & 1; + else if (pos > 31) + result = (data->Mid >> (pos - 32)) & 1; + else + result = (data->Bot >> pos) & 1; + return result; +} +bool set_bit_by_position(wiegand_message_t* data, bool value, uint8_t pos){ + if (pos >= data->Length) return false; + pos = (data->Length - pos) - 1; // invert ordering; Indexing goes from 0 to 1. Subtract 1 for weight of bit. + if (pos > 95) { + return false; + } else if (pos > 63) { + if (value) + data->Top |= (1 << (pos - 64)); + else + data->Top &= ~(1 << (pos - 64)); + return true; + } else if (pos > 31) { + if (value) + data->Mid |= (1 << (pos - 32)); + else + data->Mid &= ~(1 << (pos - 32)); + return true; + } else { + if (value) + data->Bot |= (1 << pos); + else + data->Bot &= ~(1 << pos); + return true; + } +} +/** + * Safeguard the data by doing a manual deep copy + * + * At the time of the initial writing, the struct does not contain pointers. That doesn't + * mean it won't eventually contain one, however. To prevent memory leaks and erroneous + * aliasing, perform the copy function manually instead. Hence, this function. + * + * If the definition of the wiegand_message struct changes, this function must also + * be updated to match. + */ +void message_datacopy(wiegand_message_t* src, wiegand_message_t* dest){ + dest->Bot = src->Bot; + dest->Mid = src->Mid; + dest->Top = src->Top; + dest->Length = src->Length; +} +/** + * + * Yes, this is horribly inefficient for linear data. + * The current code is a temporary measure to have a working function in place + * until all the bugs shaken from the block/chunk version of the code. + * + */ +uint64_t get_linear_field(wiegand_message_t* data, uint8_t firstBit, uint8_t length){ + uint64_t result = 0; + for (uint8_t i = 0; i < length; i++ ) { + result = (result << 1) | get_bit_by_position(data, firstBit + i); + } + return result; +} +bool set_linear_field(wiegand_message_t* data, uint64_t value, uint8_t firstBit, uint8_t length){ + wiegand_message_t tmpdata; + message_datacopy(data, &tmpdata); + bool result = true; + for (int i = 0; i < length; i++){ + result &= set_bit_by_position(&tmpdata, (value >> ((length - i) - 1)) & 1, firstBit + i); + } + if (result) + message_datacopy(&tmpdata, data); + + return result; +} + +uint64_t get_nonlinear_field(wiegand_message_t* data, uint8_t numBits, uint8_t* bits){ + uint64_t result = 0; + for (int i = 0; i < numBits; i++){ + result = (result << 1) | (get_bit_by_position(data, *(bits+i)) & 1); + } + return result; +} +bool set_nonlinear_field(wiegand_message_t* data, uint64_t value, uint8_t numBits, uint8_t* bits){ + + wiegand_message_t tmpdata; + message_datacopy(data, &tmpdata); + + bool result = true; + for (int i = 0; i < numBits; i++){ + result &= set_bit_by_position(&tmpdata, (value >> ((numBits - i) - 1)) & 1, *(bits + i)); + } + + if (result) + message_datacopy(&tmpdata, data); + + return result; +} + +uint8_t get_length_from_header(wiegand_message_t* data) { + uint8_t len = 0; + uint32_t hfmt = 0; // for calculating card length + + if ((data->Top & 0x000FFFFF) > 0) { // > 64 bits + hfmt = data->Top & 0x000FFFFF; + len = 64; + } else if ((data->Mid & 0xFFFFFFC0) > 0) { // < 63-38 bits + hfmt = data->Mid & 0xFFFFFFC0; + len = 32; + } else if (data->Mid && (data->Mid & 0x00000020) == 0) { // 37 bits; + hfmt = 0; + len = 37; + } else if ((data->Mid & 0x0000001F) > 0){ // 36-32 bits + printf("a\n"); + hfmt = data->Mid & 0x0000001F; + len = 32; + } else if (data->Top == 0 && data->Mid == 0) { //< 32 bits + hfmt = data->Bot; + len = 0; + } else { + hfmt = data->Bot; + len = 0; + } + + while (hfmt > 1) { + hfmt >>= 1; + len++; + } + return len; +} + +wiegand_message_t initialize_message_object(uint32_t top, uint32_t mid, uint32_t bot){ + wiegand_message_t result; + memset(&result, 0, sizeof(wiegand_message_t)); + + result.Top = top; + result.Mid = mid; + result.Bot = bot; + result.Length = get_length_from_header(&result); + return result; +} + +bool add_HID_header(wiegand_message_t* data){ + if (data->Length > 84 || data->Length == 0) return false; // Invalid value + + if (data->Length >= 64){ + data->Top |= 1 << (data->Length - 64); // leading 1: start bit + data->Top |= 0x09e00000; // Extended-length header + } else if (data->Length > 37){ + data->Mid |= 1 << (data->Length - 32); // leading 1: start bit + data->Top |= 0x09e00000; // Extended-length header + } else if (data->Length == 37){ + // No header bits added to 37-bit cards + } else if (data->Length >= 32){ + data->Mid |= 0x20; // Bit 37; standard header + data->Mid |= 1 << (data->Length - 32); // leading 1: start bit + } else { + data->Mid |= 0x20; // Bit 37; standard header + data->Bot |= 1 << data->Length; // leading 1: start bit + } + return true; +} diff --git a/client/wiegand_formatutils.h b/client/wiegand_formatutils.h new file mode 100644 index 000000000..d9e74bcb2 --- /dev/null +++ b/client/wiegand_formatutils.h @@ -0,0 +1,49 @@ +//----------------------------------------------------------------------------- +// Copyright (C) 2018 grauerfuchs +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// Weigand card format packing/unpacking support functions +//----------------------------------------------------------------------------- + +#ifndef WIEGAND_FORMATUTILS_H__ +#define WIEGAND_FORMATUTILS_H__ + +#include +#include +#include + +// Structure for packed wiegand messages +// Always align lowest value (last transmitted) bit to ordinal position 0 (lowest valued bit bottom) +typedef struct { + uint8_t Length; // Number of encoded bits in wiegand message (excluding headers and preamble) + uint32_t Top; // Bits in x<<64 positions + uint32_t Mid; // Bits in x<<32 positions + uint32_t Bot; // Lowest ordinal positions +} wiegand_message_t; + +// Structure for unpacked wiegand card, like HID prox +typedef struct { + uint32_t FacilityCode; + uint64_t CardNumber; + uint32_t IssueLevel; + uint32_t OEM; + bool ParityValid; // Only valid for responses +} wiegand_card_t; + +bool get_bit_by_position(wiegand_message_t* data, uint8_t pos); +bool set_bit_by_position(wiegand_message_t* data, bool value, uint8_t pos); + +uint64_t get_linear_field(wiegand_message_t* data, uint8_t firstBit, uint8_t length); +bool set_linear_field(wiegand_message_t* data, uint64_t value, uint8_t firstBit, uint8_t length); + +uint64_t get_nonlinear_field(wiegand_message_t* data, uint8_t numBits, uint8_t* bits); +bool set_nonlinear_field(wiegand_message_t* data, uint64_t value, uint8_t numBits, uint8_t* bits); + +wiegand_message_t initialize_message_object(uint32_t top, uint32_t mid, uint32_t bot); + +bool add_HID_header(wiegand_message_t* data); + +#endif From a33965f1dd4a5a7e09732c06ae462b0a905d4f4f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 18 Sep 2019 19:22:45 +0200 Subject: [PATCH 0729/1854] textual --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c062f6f83..783b596c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Add `wiegand list/encode/decode` - wiegand format manipulation. Adapted to fit here. (@grauerfuchs) - Add `lf t55xx protect` - sets password and enables password protection on t55x7 tag (@iceman1001) - Chg `lf t55xx wipe` - now accepts user provided configuration block (@iceman1001) - Chg proxmark3-flasher is now merged into proxmark3 client. Add pm3-flash (@doegox) From fa36018befe3ef3a294386a70da1a9b68413d328 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 18 Sep 2019 19:42:59 +0200 Subject: [PATCH 0730/1854] also compile... --- client/Makefile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/client/Makefile b/client/Makefile index 6fee6eae8..dcbb23110 100644 --- a/client/Makefile +++ b/client/Makefile @@ -230,6 +230,7 @@ CMDSRCS = crapto1/crapto1.c \ cmdflashmemspiffs.c \ cmdsmartcard.c \ cmdusart.c \ + cmdwiegand.c \ cmdparser.c \ cmdmain.c \ pm3_binlib.c \ @@ -238,7 +239,9 @@ CMDSRCS = crapto1/crapto1.c \ pm3_bitlib.c \ cmdcrc.c \ bucketsort.c \ - flash.c + flash.c \ + wiegand_formats.c \ + wiegand_formatutils.c cpu_arch = $(shell uname -m) ifneq ($(findstring 86, $(cpu_arch)), ) From 2626c31d3dad8c3dac0a9344d75c9029eb9e0abd Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 18 Sep 2019 19:43:55 +0200 Subject: [PATCH 0731/1854] links --- client/cmdlfhid.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/client/cmdlfhid.c b/client/cmdlfhid.c index d4d52fa9f..2059066dc 100644 --- a/client/cmdlfhid.c +++ b/client/cmdlfhid.c @@ -5,7 +5,17 @@ // at your option, any later version. See the LICENSE.txt file for the text of // the license. //----------------------------------------------------------------------------- -// Low frequency HID commands +// Low frequency HID commands (known) +// +// Useful resources: +// RF interface, programming a T55x7 clone, 26-bit HID H10301 encoding: +// http://www.proxmark.org/files/Documents/125%20kHz%20-%20HID/HID_format_example.pdf +// +// "Understanding Card Data Formats" +// https://www.hidglobal.com/sites/default/files/hid-understanding_card_data_formats-wp-en.pdf +// +// "What Format Do You Need?" +// https://www.hidglobal.com/sites/default/files/resource_files/hid-prox-br-en.pdf //----------------------------------------------------------------------------- #include "cmdlfhid.h" From bb051df683aa855d404ee4ab1ddf9aa72d1076dc Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 18 Sep 2019 20:15:29 +0200 Subject: [PATCH 0732/1854] ..memset --- client/wiegand_formats.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/wiegand_formats.h b/client/wiegand_formats.h index c904f789a..102c2b0cb 100644 --- a/client/wiegand_formats.h +++ b/client/wiegand_formats.h @@ -11,7 +11,7 @@ #ifndef WIEGAND_FORMATS_H__ #define WIEGAND_FORMATS_H__ -#include // memset +#include // memset #include #include #include From 895410aec04fe510c682deb56cd617fdb78769e5 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 19 Sep 2019 10:47:12 +0200 Subject: [PATCH 0733/1854] style --- client/cmdlfnedap.c | 6 +- client/cmdlfnoralsy.c | 6 +- client/cmdlfpresco.c | 6 +- client/cmdlfpyramid.c | 8 +- client/cmdlfviking.c | 8 +- client/cmdlfvisa2000.c | 10 +- client/cmdwiegand.c | 30 +- client/util.c | 4 +- client/util.h | 2 +- client/wiegand_formats.c | 1026 +++++++++++++++++----------------- client/wiegand_formats.h | 24 +- client/wiegand_formatutils.c | 266 ++++----- client/wiegand_formatutils.h | 32 +- 13 files changed, 714 insertions(+), 714 deletions(-) diff --git a/client/cmdlfnedap.c b/client/cmdlfnedap.c index ec2837d7a..b186a1354 100644 --- a/client/cmdlfnedap.c +++ b/client/cmdlfnedap.c @@ -480,15 +480,15 @@ int CmdLFNedapClone(const char *Cmd) { if (i == 0) { SetConfigWithBlock0(blocks[0]); - if ( t55xxAquireAndCompareBlock0(false, 0, blocks[0], false) ) + if (t55xxAquireAndCompareBlock0(false, 0, blocks[0], false)) continue; } - + if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) res++; } - if ( res == 0 ) + if (res == 0) PrintAndLogEx(SUCCESS, "Success writing to tag"); else { PrintAndLogEx(NORMAL, ""); diff --git a/client/cmdlfnoralsy.c b/client/cmdlfnoralsy.c index 2d9481782..fe469720b 100644 --- a/client/cmdlfnoralsy.c +++ b/client/cmdlfnoralsy.c @@ -179,15 +179,15 @@ static int CmdNoralsyClone(const char *Cmd) { if (i == 0) { SetConfigWithBlock0(blocks[0]); - if ( t55xxAquireAndCompareBlock0(false, 0, blocks[0], false) ) + if (t55xxAquireAndCompareBlock0(false, 0, blocks[0], false)) continue; } - + if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) res++; } - if ( res == 0 ) + if (res == 0) PrintAndLogEx(SUCCESS, "Success writing to tag"); return PM3_SUCCESS; diff --git a/client/cmdlfpresco.c b/client/cmdlfpresco.c index 39587c5ea..f563e2ef8 100644 --- a/client/cmdlfpresco.c +++ b/client/cmdlfpresco.c @@ -146,7 +146,7 @@ static int CmdPrescoClone(const char *Cmd) { if (i == 0) { SetConfigWithBlock0(blocks[0]); - if ( t55xxAquireAndCompareBlock0(false, 0, blocks[0], false) ) + if (t55xxAquireAndCompareBlock0(false, 0, blocks[0], false)) continue; } @@ -155,9 +155,9 @@ static int CmdPrescoClone(const char *Cmd) { } - if ( res == 0 ) + if (res == 0) PrintAndLogEx(SUCCESS, "Success writing to tag"); - + return PM3_SUCCESS; } diff --git a/client/cmdlfpyramid.c b/client/cmdlfpyramid.c index 90e5c23d7..216e0834e 100644 --- a/client/cmdlfpyramid.c +++ b/client/cmdlfpyramid.c @@ -256,18 +256,18 @@ static int CmdPyramidClone(const char *Cmd) { if (i == 0) { SetConfigWithBlock0(blocks[0]); - if ( t55xxAquireAndCompareBlock0(false, 0, blocks[0], false) ) + if (t55xxAquireAndCompareBlock0(false, 0, blocks[0], false)) continue; } - + if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) res++; } - if ( res == 0 ) + if (res == 0) PrintAndLogEx(SUCCESS, "Success writing to tag"); - + return PM3_SUCCESS; } diff --git a/client/cmdlfviking.c b/client/cmdlfviking.c index 45fe9ffb6..9bbbeaa7e 100644 --- a/client/cmdlfviking.c +++ b/client/cmdlfviking.c @@ -90,14 +90,14 @@ static int CmdVikingClone(const char *Cmd) { uint8_t blocks[8]; } PACKED payload; payload.Q5 = Q5; - + num_to_bytes(rawID, 8, &payload.blocks[0]); PrintAndLogEx(INFO, "Preparing to clone Viking tag - ID " _YELLOW_("%08X")" raw " _YELLOW_("%s"), id, sprint_hex(payload.blocks, sizeof(payload.blocks))); - + clearCommandBuffer(); - - SendCommandNG(CMD_LF_VIKING_CLONE, (uint8_t*)&payload, sizeof(payload)); + + SendCommandNG(CMD_LF_VIKING_CLONE, (uint8_t *)&payload, sizeof(payload)); PacketResponseNG resp; if (!WaitForResponseTimeout(CMD_LF_VIKING_CLONE, &resp, T55XX_WRITE_TIMEOUT)) { PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); diff --git a/client/cmdlfvisa2000.c b/client/cmdlfvisa2000.c index f23a7c5a8..9f80a830d 100644 --- a/client/cmdlfvisa2000.c +++ b/client/cmdlfvisa2000.c @@ -169,7 +169,7 @@ static int CmdVisa2kClone(const char *Cmd) { uint8_t res = 0; PacketResponseNG resp; - + // fast push mode conn.block_after_ACK = true; for (uint8_t i = 0; i < 4; i++) { @@ -193,15 +193,15 @@ static int CmdVisa2kClone(const char *Cmd) { if (i == 0) { SetConfigWithBlock0(blocks[0]); - if ( t55xxAquireAndCompareBlock0(false, 0, blocks[0], false) ) + if (t55xxAquireAndCompareBlock0(false, 0, blocks[0], false)) continue; } - + if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) res++; } - - if ( res == 0 ) + + if (res == 0) PrintAndLogEx(SUCCESS, "Success writing to tag"); return PM3_SUCCESS; diff --git a/client/cmdwiegand.c b/client/cmdwiegand.c index 0b567d514..8c1b5e8cb 100644 --- a/client/cmdwiegand.c +++ b/client/cmdwiegand.c @@ -20,7 +20,7 @@ #include "cmdhflist.h" // annotations #include "wiegand_formats.h" #include "wiegand_formatutils.h" -#include "util.h" +#include "util.h" static int CmdHelp(const char *Cmd); @@ -52,18 +52,18 @@ static int usage_wiegand_decode() { return PM3_SUCCESS; } -void PrintTagId(wiegand_message_t *packed){ +void PrintTagId(wiegand_message_t *packed) { if (packed->Top != 0) { PrintAndLogEx(SUCCESS, "Card ID: %X%08X%08X", - (uint32_t)packed->Top, - (uint32_t)packed->Mid, - (uint32_t)packed->Bot) - ; + (uint32_t)packed->Top, + (uint32_t)packed->Mid, + (uint32_t)packed->Bot) + ; } else { PrintAndLogEx(SUCCESS, "Card ID: %X%08X", - (uint32_t)packed->Mid, - (uint32_t)packed->Bot) - ; + (uint32_t)packed->Mid, + (uint32_t)packed->Bot) + ; } } @@ -88,7 +88,7 @@ int CmdWiegandEncode(const char *Cmd) { int format_idx = -1; char format[16] = {0}; - + wiegand_card_t data; memset(&data, 0, sizeof(wiegand_card_t)); @@ -133,12 +133,12 @@ int CmdWiegandEncode(const char *Cmd) { wiegand_message_t packed; memset(&packed, 0, sizeof(wiegand_message_t)); - + if (HIDPack(format_idx, &data, &packed) == false) { PrintAndLogEx(WARNING, "The card data could not be encoded in the selected format."); return PM3_ESOFT; } - + PrintTagId(&packed); return PM3_SUCCESS; } @@ -152,7 +152,7 @@ int CmdWiegandDecode(const char *Cmd) { while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { uint32_t strlen = param_getlength(Cmd, cmdp); strlen++; // null termin - if ( strlen > 2 ) { + if (strlen > 2) { char *s = calloc(strlen, sizeof(uint8_t)); param_getstr(Cmd, cmdp, s, strlen); hexstring_to_u96(&top, &mid, &bot, s); @@ -176,11 +176,11 @@ int CmdWiegandDecode(const char *Cmd) { } if (gothex == false) errors = true; - + if (errors || cmdp < 1) return usage_wiegand_decode(); wiegand_message_t packed = initialize_message_object(top, mid, bot); - + HIDTryUnpack(&packed, ignore_parity); return PM3_SUCCESS; } diff --git a/client/util.c b/client/util.c index f74605562..da1b5d0e2 100644 --- a/client/util.c +++ b/client/util.c @@ -885,10 +885,10 @@ char *strmcopy(const char *buf) { * * Returns the number of nibbles (4 bits) entered. */ -int hexstring_to_u96(uint32_t* hi2, uint32_t* hi, uint32_t* lo, const char* str) { +int hexstring_to_u96(uint32_t *hi2, uint32_t *hi, uint32_t *lo, const char *str) { int n = 0, i = 0; - while (sscanf(&str[i++], "%1x", &n ) == 1) { + while (sscanf(&str[i++], "%1x", &n) == 1) { *hi2 = (*hi2 << 4) | (*hi >> 28); *hi = (*hi << 4) | (*lo >> 28); *lo = (*lo << 4) | (n & 0xf); diff --git a/client/util.h b/client/util.h index df69493d2..7d6c6460e 100644 --- a/client/util.h +++ b/client/util.h @@ -98,5 +98,5 @@ void clean_ascii(unsigned char *buf, size_t len); void strcleanrn(char *buf, size_t len); void strcreplace(char *buf, size_t len, char from, char to); char *strmcopy(const char *buf); -int hexstring_to_u96(uint32_t* hi2, uint32_t* hi, uint32_t* lo, const char* str); +int hexstring_to_u96(uint32_t *hi2, uint32_t *hi, uint32_t *lo, const char *str); #endif diff --git a/client/wiegand_formats.c b/client/wiegand_formats.c index 7228abd82..4e2541cbd 100644 --- a/client/wiegand_formats.c +++ b/client/wiegand_formats.c @@ -9,574 +9,574 @@ //----------------------------------------------------------------------------- #include "wiegand_formats.h" -bool Pack_H10301(wiegand_card_t* card, wiegand_message_t* packed){ - memset(packed, 0, sizeof(wiegand_message_t)); - - if (card->FacilityCode > 0xFF) return false; // Can't encode FC. - if (card->CardNumber > 0xFFFF) return false; // Can't encode CN. - if (card->IssueLevel > 0) return false; // Not used in this format - if (card->OEM > 0) return false; // Not used in this format - - packed->Length = 26; // Set number of bits - packed->Bot |= (card->CardNumber & 0xFFFF) << 1; - packed->Bot |= (card->FacilityCode & 0xFF) << 17; - packed->Bot |= oddparity32((packed->Bot >> 1) & 0xFFF) & 1; - packed->Bot |= (evenparity32((packed->Bot >> 13) & 0xFFF) & 1) << 25; - return add_HID_header(packed); +bool Pack_H10301(wiegand_card_t *card, wiegand_message_t *packed) { + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0xFF) return false; // Can't encode FC. + if (card->CardNumber > 0xFFFF) return false; // Can't encode CN. + if (card->IssueLevel > 0) return false; // Not used in this format + if (card->OEM > 0) return false; // Not used in this format + + packed->Length = 26; // Set number of bits + packed->Bot |= (card->CardNumber & 0xFFFF) << 1; + packed->Bot |= (card->FacilityCode & 0xFF) << 17; + packed->Bot |= oddparity32((packed->Bot >> 1) & 0xFFF) & 1; + packed->Bot |= (evenparity32((packed->Bot >> 13) & 0xFFF) & 1) << 25; + return add_HID_header(packed); } -bool Unpack_H10301(wiegand_message_t* packed, wiegand_card_t* card){ - memset(card, 0, sizeof(wiegand_card_t)); - if (packed->Length != 26) return false; // Wrong length? Stop here. - - card->CardNumber = (packed->Bot >> 1) & 0xFFFF; - card->FacilityCode = (packed->Bot >> 17) & 0xFF; - card->ParityValid = - (oddparity32((packed->Bot >> 1) & 0xFFF) == (packed->Bot & 1)) && - ((evenparity32((packed->Bot >> 13) & 0xFFF) & 1) == ((packed->Bot >> 25) & 1)); - return true; +bool Unpack_H10301(wiegand_message_t *packed, wiegand_card_t *card) { + memset(card, 0, sizeof(wiegand_card_t)); + if (packed->Length != 26) return false; // Wrong length? Stop here. + + card->CardNumber = (packed->Bot >> 1) & 0xFFFF; + card->FacilityCode = (packed->Bot >> 17) & 0xFF; + card->ParityValid = + (oddparity32((packed->Bot >> 1) & 0xFFF) == (packed->Bot & 1)) && + ((evenparity32((packed->Bot >> 13) & 0xFFF) & 1) == ((packed->Bot >> 25) & 1)); + return true; } -bool Pack_Tecom27(wiegand_card_t* card, wiegand_message_t* packed){ - memset(packed, 0, sizeof(wiegand_message_t)); - - if (card->FacilityCode > 0x7FF) return false; // Can't encode FC. - if (card->CardNumber > 0xFFFF) return false; // Can't encode CN. - if (card->IssueLevel > 0) return false; // Not used in this format - if (card->OEM > 0) return false; // Not used in this format - - packed->Length = 27; - set_nonlinear_field(packed, card->FacilityCode, 10, (uint8_t[]){15, 19, 24, 23, 22, 18, 6, 10, 14, 3, 2}); - set_nonlinear_field(packed, card->CardNumber, 16, (uint8_t[]){0, 1, 13, 12, 9, 26, 20, 16, 17, 21, 25, 7, 8, 11, 4, 5}); - return add_HID_header(packed); +bool Pack_Tecom27(wiegand_card_t *card, wiegand_message_t *packed) { + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0x7FF) return false; // Can't encode FC. + if (card->CardNumber > 0xFFFF) return false; // Can't encode CN. + if (card->IssueLevel > 0) return false; // Not used in this format + if (card->OEM > 0) return false; // Not used in this format + + packed->Length = 27; + set_nonlinear_field(packed, card->FacilityCode, 10, (uint8_t[]) {15, 19, 24, 23, 22, 18, 6, 10, 14, 3, 2}); + set_nonlinear_field(packed, card->CardNumber, 16, (uint8_t[]) {0, 1, 13, 12, 9, 26, 20, 16, 17, 21, 25, 7, 8, 11, 4, 5}); + return add_HID_header(packed); } -bool Unpack_Tecom27(wiegand_message_t* packed, wiegand_card_t* card){ - memset(card, 0, sizeof(wiegand_card_t)); - - if (packed->Length != 27) return false; // Wrong length? Stop here. - - card->CardNumber = get_nonlinear_field(packed, 16, (uint8_t[]){0, 1, 13, 12, 9, 26, 20, 16, 17, 21, 25, 7, 8, 11, 4, 5}); - card->FacilityCode = get_nonlinear_field(packed, 10, (uint8_t[]){15, 19, 24, 23, 22, 18, 6, 10, 14, 3, 2}); - return true; +bool Unpack_Tecom27(wiegand_message_t *packed, wiegand_card_t *card) { + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 27) return false; // Wrong length? Stop here. + + card->CardNumber = get_nonlinear_field(packed, 16, (uint8_t[]) {0, 1, 13, 12, 9, 26, 20, 16, 17, 21, 25, 7, 8, 11, 4, 5}); + card->FacilityCode = get_nonlinear_field(packed, 10, (uint8_t[]) {15, 19, 24, 23, 22, 18, 6, 10, 14, 3, 2}); + return true; } -bool Pack_2804W(wiegand_card_t* card, wiegand_message_t* packed){ - memset(packed, 0, sizeof(wiegand_message_t)); - - if (card->FacilityCode > 0x0FF) return false; // Can't encode FC. - if (card->CardNumber > 0x7FFF) return false; // Can't encode CN. - if (card->IssueLevel > 0) return false; // Not used in this format - if (card->OEM > 0) return false; // Not used in this format - - packed->Length = 28; - set_linear_field(packed, card->FacilityCode, 4, 8); - set_linear_field(packed, card->CardNumber, 12, 15); - set_bit_by_position(packed, - oddparity32(get_nonlinear_field(packed, 16, (uint8_t[]){4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19, 20, 22, 23, 25, 26})) +bool Pack_2804W(wiegand_card_t *card, wiegand_message_t *packed) { + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0x0FF) return false; // Can't encode FC. + if (card->CardNumber > 0x7FFF) return false; // Can't encode CN. + if (card->IssueLevel > 0) return false; // Not used in this format + if (card->OEM > 0) return false; // Not used in this format + + packed->Length = 28; + set_linear_field(packed, card->FacilityCode, 4, 8); + set_linear_field(packed, card->CardNumber, 12, 15); + set_bit_by_position(packed, + oddparity32(get_nonlinear_field(packed, 16, (uint8_t[]) {4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19, 20, 22, 23, 25, 26})) , 2); - set_bit_by_position(packed, - evenparity32(get_linear_field(packed, 1, 13)) - , 0); - set_bit_by_position(packed, - oddparity32(get_linear_field(packed, 0, 27)) - , 27); - return add_HID_header(packed); + set_bit_by_position(packed, + evenparity32(get_linear_field(packed, 1, 13)) + , 0); + set_bit_by_position(packed, + oddparity32(get_linear_field(packed, 0, 27)) + , 27); + return add_HID_header(packed); } -bool Unpack_2804W(wiegand_message_t* packed, wiegand_card_t* card){ - memset(card, 0, sizeof(wiegand_card_t)); - - if (packed->Length != 28) return false; // Wrong length? Stop here. - - card->FacilityCode = get_linear_field(packed, 4, 8); - card->CardNumber = get_linear_field(packed, 12, 15); - card->ParityValid = - (get_bit_by_position(packed, 0) == evenparity32(get_linear_field(packed, 1, 13))) && - (get_bit_by_position(packed, 2) == oddparity32(get_nonlinear_field(packed, 16, (uint8_t[]){4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19, 20, 22, 23, 25, 26}))) && +bool Unpack_2804W(wiegand_message_t *packed, wiegand_card_t *card) { + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 28) return false; // Wrong length? Stop here. + + card->FacilityCode = get_linear_field(packed, 4, 8); + card->CardNumber = get_linear_field(packed, 12, 15); + card->ParityValid = + (get_bit_by_position(packed, 0) == evenparity32(get_linear_field(packed, 1, 13))) && + (get_bit_by_position(packed, 2) == oddparity32(get_nonlinear_field(packed, 16, (uint8_t[]) {4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19, 20, 22, 23, 25, 26}))) && (get_bit_by_position(packed, 27) == oddparity32(get_linear_field(packed, 0, 27))); - return true; + return true; } -bool Pack_ATSW30(wiegand_card_t* card, wiegand_message_t* packed){ - memset(packed, 0, sizeof(wiegand_message_t)); - - if (card->FacilityCode > 0xFFF) return false; // Can't encode FC. - if (card->CardNumber > 0xFFFF) return false; // Can't encode CN. - if (card->IssueLevel > 0) return false; // Not used in this format - if (card->OEM > 0) return false; // Not used in this format - - packed->Length = 30; - set_linear_field(packed, card->FacilityCode, 1, 12); - set_linear_field(packed, card->CardNumber, 13, 16); - set_bit_by_position(packed, - evenparity32(get_linear_field(packed, 1, 12)) - , 0); - set_bit_by_position(packed, - oddparity32(get_linear_field(packed, 13, 16)) - , 29); - return add_HID_header(packed); +bool Pack_ATSW30(wiegand_card_t *card, wiegand_message_t *packed) { + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0xFFF) return false; // Can't encode FC. + if (card->CardNumber > 0xFFFF) return false; // Can't encode CN. + if (card->IssueLevel > 0) return false; // Not used in this format + if (card->OEM > 0) return false; // Not used in this format + + packed->Length = 30; + set_linear_field(packed, card->FacilityCode, 1, 12); + set_linear_field(packed, card->CardNumber, 13, 16); + set_bit_by_position(packed, + evenparity32(get_linear_field(packed, 1, 12)) + , 0); + set_bit_by_position(packed, + oddparity32(get_linear_field(packed, 13, 16)) + , 29); + return add_HID_header(packed); } -bool Unpack_ATSW30(wiegand_message_t* packed, wiegand_card_t* card){ - memset(card, 0, sizeof(wiegand_card_t)); - - if (packed->Length != 30) return false; // Wrong length? Stop here. - - card->FacilityCode = get_linear_field(packed, 1, 12); - card->CardNumber = get_linear_field(packed, 13, 16); - card->ParityValid = - (get_bit_by_position(packed, 0) == evenparity32(get_linear_field(packed, 1, 12))) && - (get_bit_by_position(packed, 29) == oddparity32(get_linear_field(packed, 13, 16))); - return true; +bool Unpack_ATSW30(wiegand_message_t *packed, wiegand_card_t *card) { + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 30) return false; // Wrong length? Stop here. + + card->FacilityCode = get_linear_field(packed, 1, 12); + card->CardNumber = get_linear_field(packed, 13, 16); + card->ParityValid = + (get_bit_by_position(packed, 0) == evenparity32(get_linear_field(packed, 1, 12))) && + (get_bit_by_position(packed, 29) == oddparity32(get_linear_field(packed, 13, 16))); + return true; } -bool Pack_ADT31(wiegand_card_t* card, wiegand_message_t* packed){ - memset(packed, 0, sizeof(wiegand_message_t)); - - if (card->FacilityCode > 0x0F) return false; // Can't encode FC. - if (card->CardNumber > 0x7FFFFF) return false; // Can't encode CN. - if (card->IssueLevel > 0) return false; // Not used in this format - if (card->OEM > 0) return false; // Not used in this format - - packed->Length = 31; - set_linear_field(packed, card->FacilityCode, 1, 4); - set_linear_field(packed, card->CardNumber, 5, 23); - // Parity not known, but 4 bits are unused. - return add_HID_header(packed); +bool Pack_ADT31(wiegand_card_t *card, wiegand_message_t *packed) { + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0x0F) return false; // Can't encode FC. + if (card->CardNumber > 0x7FFFFF) return false; // Can't encode CN. + if (card->IssueLevel > 0) return false; // Not used in this format + if (card->OEM > 0) return false; // Not used in this format + + packed->Length = 31; + set_linear_field(packed, card->FacilityCode, 1, 4); + set_linear_field(packed, card->CardNumber, 5, 23); + // Parity not known, but 4 bits are unused. + return add_HID_header(packed); } -bool Unpack_ADT31(wiegand_message_t* packed, wiegand_card_t* card){ - memset(card, 0, sizeof(wiegand_card_t)); - - if (packed->Length != 31) return false; // Wrong length? Stop here. - card->FacilityCode = get_linear_field(packed, 1, 4); - card->CardNumber = get_linear_field(packed, 5, 23); - return true; +bool Unpack_ADT31(wiegand_message_t *packed, wiegand_card_t *card) { + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 31) return false; // Wrong length? Stop here. + card->FacilityCode = get_linear_field(packed, 1, 4); + card->CardNumber = get_linear_field(packed, 5, 23); + return true; } -bool Pack_Kastle(wiegand_card_t* card, wiegand_message_t* packed){ - memset(packed, 0, sizeof(wiegand_message_t)); - - if (card->FacilityCode > 0x00FF) return false; // Can't encode FC. - if (card->CardNumber > 0x0000FFFF) return false; // Can't encode CN. - if (card->IssueLevel > 0x001F) return false; // IL is only 5 bits. - if (card->OEM > 0) return false; // Not used in this format - - packed->Length = 32; // Set number of bits - set_bit_by_position(packed, 1, 1); // Always 1 - set_linear_field(packed, card->IssueLevel, 2, 5); - set_linear_field(packed, card->FacilityCode, 7, 8); - set_linear_field(packed, card->CardNumber, 15, 16); - set_bit_by_position(packed, evenparity32(get_linear_field(packed, 1, 16)), 0); - set_bit_by_position(packed, oddparity32(get_linear_field(packed, 14, 17)), 31); - return add_HID_header(packed); +bool Pack_Kastle(wiegand_card_t *card, wiegand_message_t *packed) { + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0x00FF) return false; // Can't encode FC. + if (card->CardNumber > 0x0000FFFF) return false; // Can't encode CN. + if (card->IssueLevel > 0x001F) return false; // IL is only 5 bits. + if (card->OEM > 0) return false; // Not used in this format + + packed->Length = 32; // Set number of bits + set_bit_by_position(packed, 1, 1); // Always 1 + set_linear_field(packed, card->IssueLevel, 2, 5); + set_linear_field(packed, card->FacilityCode, 7, 8); + set_linear_field(packed, card->CardNumber, 15, 16); + set_bit_by_position(packed, evenparity32(get_linear_field(packed, 1, 16)), 0); + set_bit_by_position(packed, oddparity32(get_linear_field(packed, 14, 17)), 31); + return add_HID_header(packed); } -bool Unpack_Kastle(wiegand_message_t* packed, wiegand_card_t* card){ - memset(card, 0, sizeof(wiegand_card_t)); - - if (packed->Length != 32) return false; // Wrong length? Stop here. - if (get_bit_by_position(packed, 1) != 1) return false; // Always 1 in this format - - card->IssueLevel = get_linear_field(packed, 2, 5); - card->FacilityCode = get_linear_field(packed, 7, 8); - card->CardNumber = get_linear_field(packed, 15, 16); - card->ParityValid = - (get_bit_by_position(packed, 0) == evenparity32(get_linear_field(packed, 1, 16))) && - (get_bit_by_position(packed, 31) == oddparity32(get_linear_field(packed, 14, 17))); - return true; +bool Unpack_Kastle(wiegand_message_t *packed, wiegand_card_t *card) { + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 32) return false; // Wrong length? Stop here. + if (get_bit_by_position(packed, 1) != 1) return false; // Always 1 in this format + + card->IssueLevel = get_linear_field(packed, 2, 5); + card->FacilityCode = get_linear_field(packed, 7, 8); + card->CardNumber = get_linear_field(packed, 15, 16); + card->ParityValid = + (get_bit_by_position(packed, 0) == evenparity32(get_linear_field(packed, 1, 16))) && + (get_bit_by_position(packed, 31) == oddparity32(get_linear_field(packed, 14, 17))); + return true; } -bool Pack_D10202(wiegand_card_t* card, wiegand_message_t* packed){ - memset(packed, 0, sizeof(wiegand_message_t)); - - if (card->FacilityCode > 0x007F) return false; // Can't encode FC. - if (card->CardNumber > 0x00FFFFFF) return false; // Can't encode CN. - if (card->IssueLevel > 0) return false; // Not used in this format - if (card->OEM > 0) return false; // Not used in this format - - packed->Length = 33; // Set number of bits - set_linear_field(packed, card->FacilityCode, 1, 7); - set_linear_field(packed, card->CardNumber, 8, 24); - set_bit_by_position(packed, evenparity32(get_linear_field(packed, 1, 16)), 0); - set_bit_by_position(packed, oddparity32(get_linear_field(packed, 16, 16)), 32); - return add_HID_header(packed); +bool Pack_D10202(wiegand_card_t *card, wiegand_message_t *packed) { + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0x007F) return false; // Can't encode FC. + if (card->CardNumber > 0x00FFFFFF) return false; // Can't encode CN. + if (card->IssueLevel > 0) return false; // Not used in this format + if (card->OEM > 0) return false; // Not used in this format + + packed->Length = 33; // Set number of bits + set_linear_field(packed, card->FacilityCode, 1, 7); + set_linear_field(packed, card->CardNumber, 8, 24); + set_bit_by_position(packed, evenparity32(get_linear_field(packed, 1, 16)), 0); + set_bit_by_position(packed, oddparity32(get_linear_field(packed, 16, 16)), 32); + return add_HID_header(packed); } -bool Unpack_D10202(wiegand_message_t* packed, wiegand_card_t* card){ - memset(card, 0, sizeof(wiegand_card_t)); - - if (packed->Length != 33) return false; // Wrong length? Stop here. - - card->CardNumber = get_linear_field(packed, 8, 24); - card->FacilityCode = get_linear_field(packed, 1, 7); - card->ParityValid = - (get_bit_by_position(packed, 0) == evenparity32(get_linear_field(packed, 1, 16))) && - (get_bit_by_position(packed, 32) == oddparity32(get_linear_field(packed, 16, 16))); - return true; +bool Unpack_D10202(wiegand_message_t *packed, wiegand_card_t *card) { + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 33) return false; // Wrong length? Stop here. + + card->CardNumber = get_linear_field(packed, 8, 24); + card->FacilityCode = get_linear_field(packed, 1, 7); + card->ParityValid = + (get_bit_by_position(packed, 0) == evenparity32(get_linear_field(packed, 1, 16))) && + (get_bit_by_position(packed, 32) == oddparity32(get_linear_field(packed, 16, 16))); + return true; } -bool Pack_H10306(wiegand_card_t* card, wiegand_message_t* packed){ - memset(packed, 0, sizeof(wiegand_message_t)); - - if (card->FacilityCode > 0xFFFF) return false; // Can't encode FC. - if (card->CardNumber > 0xFFFF) return false; // Can't encode CN. - if (card->IssueLevel > 0) return false; // Not used in this format - if (card->OEM > 0) return false; // Not used in this format - - packed->Length = 34; // Set number of bits - packed->Bot |= (card->CardNumber & 0xFFFF) << 1; - packed->Bot |= (card->FacilityCode & 0x7FFF) << 17; - packed->Mid |= (card->FacilityCode & 0x8000) >> 15; - packed->Mid |= (evenparity32((packed->Mid & 0x00000001) ^ (packed->Bot & 0xFFFE0000)) & 1) << 1; - packed->Bot |= ( oddparity32(packed->Bot & 0x0001FFFE) & 1); - return add_HID_header(packed); +bool Pack_H10306(wiegand_card_t *card, wiegand_message_t *packed) { + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0xFFFF) return false; // Can't encode FC. + if (card->CardNumber > 0xFFFF) return false; // Can't encode CN. + if (card->IssueLevel > 0) return false; // Not used in this format + if (card->OEM > 0) return false; // Not used in this format + + packed->Length = 34; // Set number of bits + packed->Bot |= (card->CardNumber & 0xFFFF) << 1; + packed->Bot |= (card->FacilityCode & 0x7FFF) << 17; + packed->Mid |= (card->FacilityCode & 0x8000) >> 15; + packed->Mid |= (evenparity32((packed->Mid & 0x00000001) ^ (packed->Bot & 0xFFFE0000)) & 1) << 1; + packed->Bot |= (oddparity32(packed->Bot & 0x0001FFFE) & 1); + return add_HID_header(packed); } -bool Unpack_H10306(wiegand_message_t* packed, wiegand_card_t* card){ - memset(card, 0, sizeof(wiegand_card_t)); - - if (packed->Length != 34) return false; // Wrong length? Stop here. - - card->CardNumber = (packed->Bot >> 1) & 0xFFFF; - card->FacilityCode = ((packed->Mid & 1) << 15) | ((packed->Bot >> 17) & 0xFF); - card->ParityValid = - ((evenparity32((packed->Mid & 0x00000001) ^ (packed->Bot & 0xFFFE0000)) & 1) == ((packed->Mid >> 1) & 1)) && - ((oddparity32(packed->Bot & 0x0001FFFE) & 1) == ((packed->Bot & 1))); - return true; +bool Unpack_H10306(wiegand_message_t *packed, wiegand_card_t *card) { + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 34) return false; // Wrong length? Stop here. + + card->CardNumber = (packed->Bot >> 1) & 0xFFFF; + card->FacilityCode = ((packed->Mid & 1) << 15) | ((packed->Bot >> 17) & 0xFF); + card->ParityValid = + ((evenparity32((packed->Mid & 0x00000001) ^ (packed->Bot & 0xFFFE0000)) & 1) == ((packed->Mid >> 1) & 1)) && + ((oddparity32(packed->Bot & 0x0001FFFE) & 1) == ((packed->Bot & 1))); + return true; } -bool Pack_N10002(wiegand_card_t* card, wiegand_message_t* packed){ - memset(packed, 0, sizeof(wiegand_message_t)); - - if (card->FacilityCode > 0xFF) return false; // Can't encode FC. - if (card->CardNumber > 0xFFFF) return false; // Can't encode CN. - if (card->IssueLevel > 0) return false; // Not used in this format - if (card->OEM > 0) return false; // Not used in this format - - packed->Length = 34; // Set number of bits - set_linear_field(packed, card->FacilityCode, 9, 8); - set_linear_field(packed, card->CardNumber, 17, 16); - return add_HID_header(packed); +bool Pack_N10002(wiegand_card_t *card, wiegand_message_t *packed) { + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0xFF) return false; // Can't encode FC. + if (card->CardNumber > 0xFFFF) return false; // Can't encode CN. + if (card->IssueLevel > 0) return false; // Not used in this format + if (card->OEM > 0) return false; // Not used in this format + + packed->Length = 34; // Set number of bits + set_linear_field(packed, card->FacilityCode, 9, 8); + set_linear_field(packed, card->CardNumber, 17, 16); + return add_HID_header(packed); } -bool Unpack_N10002(wiegand_message_t* packed, wiegand_card_t* card){ - memset(card, 0, sizeof(wiegand_card_t)); - - if (packed->Length != 34) return false; // Wrong length? Stop here. - - card->CardNumber = get_linear_field(packed, 17, 16); - card->FacilityCode = get_linear_field(packed, 9, 8); - return true; +bool Unpack_N10002(wiegand_message_t *packed, wiegand_card_t *card) { + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 34) return false; // Wrong length? Stop here. + + card->CardNumber = get_linear_field(packed, 17, 16); + card->FacilityCode = get_linear_field(packed, 9, 8); + return true; } -bool Pack_C1k35s(wiegand_card_t* card, wiegand_message_t* packed){ - memset(packed, 0, sizeof(wiegand_message_t)); - - if (card->FacilityCode > 0xFFF) return false; // Can't encode FC. - if (card->CardNumber > 0xFFFFF) return false; // Can't encode CN. - if (card->IssueLevel > 0) return false; // Not used in this format - if (card->OEM > 0) return false; // Not used in this format +bool Pack_C1k35s(wiegand_card_t *card, wiegand_message_t *packed) { + memset(packed, 0, sizeof(wiegand_message_t)); - packed->Length = 35; // Set number of bits - packed->Bot |= (card->CardNumber & 0x000FFFFF) << 1; - packed->Bot |= (card->FacilityCode & 0x000007FF) << 21; - packed->Mid |= (card->FacilityCode & 0x00000800) >> 11; - packed->Mid |= (evenparity32((packed->Mid & 0x00000001) ^ (packed->Bot & 0xB6DB6DB6)) & 1) << 1; - packed->Bot |= ( oddparity32((packed->Mid & 0x00000003) ^ (packed->Bot & 0x6DB6DB6C)) & 1); - packed->Mid |= ( oddparity32((packed->Mid & 0x00000003) ^ (packed->Bot & 0xFFFFFFFF)) & 1) << 2; - return add_HID_header(packed); + if (card->FacilityCode > 0xFFF) return false; // Can't encode FC. + if (card->CardNumber > 0xFFFFF) return false; // Can't encode CN. + if (card->IssueLevel > 0) return false; // Not used in this format + if (card->OEM > 0) return false; // Not used in this format + + packed->Length = 35; // Set number of bits + packed->Bot |= (card->CardNumber & 0x000FFFFF) << 1; + packed->Bot |= (card->FacilityCode & 0x000007FF) << 21; + packed->Mid |= (card->FacilityCode & 0x00000800) >> 11; + packed->Mid |= (evenparity32((packed->Mid & 0x00000001) ^ (packed->Bot & 0xB6DB6DB6)) & 1) << 1; + packed->Bot |= (oddparity32((packed->Mid & 0x00000003) ^ (packed->Bot & 0x6DB6DB6C)) & 1); + packed->Mid |= (oddparity32((packed->Mid & 0x00000003) ^ (packed->Bot & 0xFFFFFFFF)) & 1) << 2; + return add_HID_header(packed); } -bool Unpack_C1k35s(wiegand_message_t* packed, wiegand_card_t* card){ - memset(card, 0, sizeof(wiegand_card_t)); - - if (packed->Length != 35) return false; // Wrong length? Stop here. - - card->CardNumber = (packed->Bot >> 1) & 0x000FFFFF; - card->FacilityCode = ((packed->Mid & 1) << 11) | ((packed->Bot >> 21)); - card->ParityValid = - (evenparity32((packed->Mid & 0x00000001) ^ (packed->Bot & 0xB6DB6DB6)) == ((packed->Mid >> 1) & 1)) && - ( oddparity32((packed->Mid & 0x00000003) ^ (packed->Bot & 0x6DB6DB6C)) == ((packed->Bot >> 0) & 1)) && - ( oddparity32((packed->Mid & 0x00000003) ^ (packed->Bot & 0xFFFFFFFF)) == ((packed->Mid >> 2) & 1)); - return true; +bool Unpack_C1k35s(wiegand_message_t *packed, wiegand_card_t *card) { + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 35) return false; // Wrong length? Stop here. + + card->CardNumber = (packed->Bot >> 1) & 0x000FFFFF; + card->FacilityCode = ((packed->Mid & 1) << 11) | ((packed->Bot >> 21)); + card->ParityValid = + (evenparity32((packed->Mid & 0x00000001) ^ (packed->Bot & 0xB6DB6DB6)) == ((packed->Mid >> 1) & 1)) && + (oddparity32((packed->Mid & 0x00000003) ^ (packed->Bot & 0x6DB6DB6C)) == ((packed->Bot >> 0) & 1)) && + (oddparity32((packed->Mid & 0x00000003) ^ (packed->Bot & 0xFFFFFFFF)) == ((packed->Mid >> 2) & 1)); + return true; } -bool Pack_H10320(wiegand_card_t* card, wiegand_message_t* packed){ - memset(packed, 0, sizeof(wiegand_message_t)); - - if (card->FacilityCode > 0) return false; // Can't encode FC. (none in this format) - if (card->CardNumber > 99999999) return false; // Can't encode CN. - if (card->IssueLevel > 0) return false; // Not used in this format - if (card->OEM > 0) return false; // Not used in this format - - packed->Length = 36; // Set number of bits - // This card is BCD-encoded rather than binary. Set the 4-bit groups independently. - for (uint32_t idx = 0; idx < 8; idx++){ - set_linear_field(packed, (uint64_t)(card->CardNumber / pow(10, 7-idx)) % 10, idx * 4, 4); - } - set_bit_by_position(packed, evenparity32( - get_nonlinear_field(packed, 8, (uint8_t[]){0, 4, 8, 12, 16, 20, 24, 28}) - ), 32); - set_bit_by_position(packed, oddparity32( - get_nonlinear_field(packed, 8, (uint8_t[]){1, 5, 9, 13, 17, 21, 25, 29}) - ), 33); - set_bit_by_position(packed, evenparity32( - get_nonlinear_field(packed, 8, (uint8_t[]){2, 6, 10, 14, 18, 22, 28, 30}) - ), 34); - set_bit_by_position(packed, evenparity32( - get_nonlinear_field(packed, 8, (uint8_t[]){3, 7, 11, 15, 19, 23, 29, 31}) - ), 35); - return add_HID_header(packed); -} +bool Pack_H10320(wiegand_card_t *card, wiegand_message_t *packed) { + memset(packed, 0, sizeof(wiegand_message_t)); -bool Unpack_H10320(wiegand_message_t* packed, wiegand_card_t* card){ - memset(card, 0, sizeof(wiegand_card_t)); - - if (packed->Length != 36) return false; // Wrong length? Stop here. - - // This card is BCD-encoded rather than binary. Get the 4-bit groups independently. - for (uint32_t idx = 0; idx < 8; idx++){ - uint64_t val = get_linear_field(packed, idx * 4, 4); - if (val > 9){ - // Violation of BCD; Zero and exit. - card->CardNumber = 0; - return false; - } else { - card->CardNumber += val * pow(10, 7-idx); + if (card->FacilityCode > 0) return false; // Can't encode FC. (none in this format) + if (card->CardNumber > 99999999) return false; // Can't encode CN. + if (card->IssueLevel > 0) return false; // Not used in this format + if (card->OEM > 0) return false; // Not used in this format + + packed->Length = 36; // Set number of bits + // This card is BCD-encoded rather than binary. Set the 4-bit groups independently. + for (uint32_t idx = 0; idx < 8; idx++) { + set_linear_field(packed, (uint64_t)(card->CardNumber / pow(10, 7 - idx)) % 10, idx * 4, 4); } - } - card->ParityValid = - (get_bit_by_position(packed, 32) == evenparity32(get_nonlinear_field(packed, 8, (uint8_t[]){0, 4, 8, 12, 16, 20, 24, 28}))) && - (get_bit_by_position(packed, 33) == oddparity32(get_nonlinear_field(packed, 8, (uint8_t[]){1, 5, 9, 13, 17, 21, 25, 29}))) && - (get_bit_by_position(packed, 34) == evenparity32(get_nonlinear_field(packed, 8, (uint8_t[]){2, 6, 10, 14, 18, 22, 28, 30}))) && - (get_bit_by_position(packed, 35) == evenparity32(get_nonlinear_field(packed, 8, (uint8_t[]){3, 7, 11, 15, 19, 23, 29, 31}))); - return true; + set_bit_by_position(packed, evenparity32( + get_nonlinear_field(packed, 8, (uint8_t[]) {0, 4, 8, 12, 16, 20, 24, 28}) + ), 32); + set_bit_by_position(packed, oddparity32( + get_nonlinear_field(packed, 8, (uint8_t[]) {1, 5, 9, 13, 17, 21, 25, 29}) + ), 33); + set_bit_by_position(packed, evenparity32( + get_nonlinear_field(packed, 8, (uint8_t[]) {2, 6, 10, 14, 18, 22, 28, 30}) + ), 34); + set_bit_by_position(packed, evenparity32( + get_nonlinear_field(packed, 8, (uint8_t[]) {3, 7, 11, 15, 19, 23, 29, 31}) + ), 35); + return add_HID_header(packed); } -bool Pack_S12906(wiegand_card_t* card, wiegand_message_t* packed){ - memset(packed, 0, sizeof(wiegand_message_t)); - - if (card->FacilityCode > 0xFF) return false; // Can't encode FC. - if (card->IssueLevel > 0x03) return false; // Can't encode IL. - if (card->CardNumber > 0x00FFFFFF) return false; // Can't encode CN. - if (card->OEM > 0) return false; // Not used in this format +bool Unpack_H10320(wiegand_message_t *packed, wiegand_card_t *card) { + memset(card, 0, sizeof(wiegand_card_t)); - packed->Length = 36; // Set number of bits - set_linear_field(packed, card->FacilityCode, 1, 8); - set_linear_field(packed, card->IssueLevel, 9, 2); - set_linear_field(packed, card->CardNumber, 11, 24); - set_bit_by_position(packed, oddparity32(get_linear_field(packed, 1, 17)), 0); - set_bit_by_position(packed, oddparity32(get_linear_field(packed, 17, 18)), 35); - return add_HID_header(packed); + if (packed->Length != 36) return false; // Wrong length? Stop here. + + // This card is BCD-encoded rather than binary. Get the 4-bit groups independently. + for (uint32_t idx = 0; idx < 8; idx++) { + uint64_t val = get_linear_field(packed, idx * 4, 4); + if (val > 9) { + // Violation of BCD; Zero and exit. + card->CardNumber = 0; + return false; + } else { + card->CardNumber += val * pow(10, 7 - idx); + } + } + card->ParityValid = + (get_bit_by_position(packed, 32) == evenparity32(get_nonlinear_field(packed, 8, (uint8_t[]) {0, 4, 8, 12, 16, 20, 24, 28}))) && + (get_bit_by_position(packed, 33) == oddparity32(get_nonlinear_field(packed, 8, (uint8_t[]) {1, 5, 9, 13, 17, 21, 25, 29}))) && + (get_bit_by_position(packed, 34) == evenparity32(get_nonlinear_field(packed, 8, (uint8_t[]) {2, 6, 10, 14, 18, 22, 28, 30}))) && + (get_bit_by_position(packed, 35) == evenparity32(get_nonlinear_field(packed, 8, (uint8_t[]) {3, 7, 11, 15, 19, 23, 29, 31}))); + return true; } -bool Unpack_S12906(wiegand_message_t* packed, wiegand_card_t* card){ - memset(card, 0, sizeof(wiegand_card_t)); - - if (packed->Length != 36) return false; // Wrong length? Stop here. - - card->FacilityCode = get_linear_field(packed, 1, 8); - card->IssueLevel = get_linear_field(packed, 9, 2); - card->CardNumber = get_linear_field(packed, 11, 24); - card->ParityValid = - (get_bit_by_position(packed, 0) == oddparity32(get_linear_field(packed, 1, 17))) && - (get_bit_by_position(packed, 35) == oddparity32(get_linear_field(packed, 17, 18))); - return true; +bool Pack_S12906(wiegand_card_t *card, wiegand_message_t *packed) { + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0xFF) return false; // Can't encode FC. + if (card->IssueLevel > 0x03) return false; // Can't encode IL. + if (card->CardNumber > 0x00FFFFFF) return false; // Can't encode CN. + if (card->OEM > 0) return false; // Not used in this format + + packed->Length = 36; // Set number of bits + set_linear_field(packed, card->FacilityCode, 1, 8); + set_linear_field(packed, card->IssueLevel, 9, 2); + set_linear_field(packed, card->CardNumber, 11, 24); + set_bit_by_position(packed, oddparity32(get_linear_field(packed, 1, 17)), 0); + set_bit_by_position(packed, oddparity32(get_linear_field(packed, 17, 18)), 35); + return add_HID_header(packed); } -bool Pack_Sie36(wiegand_card_t* card, wiegand_message_t* packed){ - memset(packed, 0, sizeof(wiegand_message_t)); - - if (card->FacilityCode > 0x0003FFFF) return false; // Can't encode FC. - if (card->CardNumber > 0x0000FFFF) return false; // Can't encode CN. - if (card->IssueLevel > 0) return false; // Not used in this format - if (card->OEM > 0) return false; // Not used in this format - - packed->Length = 36; // Set number of bits - set_linear_field(packed, card->FacilityCode, 1, 18); - set_linear_field(packed, card->CardNumber, 19, 16); - set_bit_by_position(packed, - oddparity32(get_nonlinear_field(packed, 23, (uint8_t[]){1, 3, 4, 6, 7, 9, 10, 12, 13, 15, 16, 18, 19, 21, 22, 24, 25, 27, 28, 30, 31, 33, 34})) - , 0); - set_bit_by_position(packed, - evenparity32(get_nonlinear_field(packed, 23, (uint8_t[]){1, 2, 4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19, 20, 22, 23, 25, 26, 28, 29, 31, 32, 34})) - , 35); - return add_HID_header(packed); +bool Unpack_S12906(wiegand_message_t *packed, wiegand_card_t *card) { + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 36) return false; // Wrong length? Stop here. + + card->FacilityCode = get_linear_field(packed, 1, 8); + card->IssueLevel = get_linear_field(packed, 9, 2); + card->CardNumber = get_linear_field(packed, 11, 24); + card->ParityValid = + (get_bit_by_position(packed, 0) == oddparity32(get_linear_field(packed, 1, 17))) && + (get_bit_by_position(packed, 35) == oddparity32(get_linear_field(packed, 17, 18))); + return true; } -bool Unpack_Sie36(wiegand_message_t* packed, wiegand_card_t* card){ - memset(card, 0, sizeof(wiegand_card_t)); +bool Pack_Sie36(wiegand_card_t *card, wiegand_message_t *packed) { + memset(packed, 0, sizeof(wiegand_message_t)); - if (packed->Length != 36) return false; // Wrong length? Stop here. + if (card->FacilityCode > 0x0003FFFF) return false; // Can't encode FC. + if (card->CardNumber > 0x0000FFFF) return false; // Can't encode CN. + if (card->IssueLevel > 0) return false; // Not used in this format + if (card->OEM > 0) return false; // Not used in this format - card->FacilityCode = get_linear_field(packed, 1, 18); - card->CardNumber = get_linear_field(packed, 19, 16); - card->ParityValid = - (get_bit_by_position(packed, 0) == oddparity32(get_nonlinear_field(packed, 23, (uint8_t[]){1, 3, 4, 6, 7, 9, 10, 12, 13, 15, 16, 18, 19, 21, 22, 24, 25, 27, 28, 30, 31, 33, 34}))) && - (get_bit_by_position(packed, 35) == oddparity32(get_nonlinear_field(packed, 23, (uint8_t[]){1, 2, 4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19, 20, 22, 23, 25, 26, 28, 29, 31, 32, 34}))); - return true; + packed->Length = 36; // Set number of bits + set_linear_field(packed, card->FacilityCode, 1, 18); + set_linear_field(packed, card->CardNumber, 19, 16); + set_bit_by_position(packed, + oddparity32(get_nonlinear_field(packed, 23, (uint8_t[]) {1, 3, 4, 6, 7, 9, 10, 12, 13, 15, 16, 18, 19, 21, 22, 24, 25, 27, 28, 30, 31, 33, 34})) + , 0); + set_bit_by_position(packed, + evenparity32(get_nonlinear_field(packed, 23, (uint8_t[]) {1, 2, 4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19, 20, 22, 23, 25, 26, 28, 29, 31, 32, 34})) + , 35); + return add_HID_header(packed); } -bool Pack_C15001(wiegand_card_t* card, wiegand_message_t* packed){ - memset(packed, 0, sizeof(wiegand_message_t)); - - if (card->FacilityCode > 0x000000FF) return false; // Can't encode FC. - if (card->CardNumber > 0x0000FFFF) return false; // Can't encode CN. - if (card->IssueLevel > 0) return false; // Not used in this format - if (card->OEM > 0x000003FF) return false; // Can't encode OEM. - - packed->Length = 36; // Set number of bits - set_linear_field(packed, card->OEM, 1, 10); - set_linear_field(packed, card->FacilityCode, 11, 8); - set_linear_field(packed, card->CardNumber, 19, 16); - set_bit_by_position(packed, evenparity32(get_linear_field(packed, 1, 17)), 0); - set_bit_by_position(packed, oddparity32(get_linear_field(packed, 18, 17)), 35); - return add_HID_header(packed); +bool Unpack_Sie36(wiegand_message_t *packed, wiegand_card_t *card) { + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 36) return false; // Wrong length? Stop here. + + card->FacilityCode = get_linear_field(packed, 1, 18); + card->CardNumber = get_linear_field(packed, 19, 16); + card->ParityValid = + (get_bit_by_position(packed, 0) == oddparity32(get_nonlinear_field(packed, 23, (uint8_t[]) {1, 3, 4, 6, 7, 9, 10, 12, 13, 15, 16, 18, 19, 21, 22, 24, 25, 27, 28, 30, 31, 33, 34}))) && + (get_bit_by_position(packed, 35) == oddparity32(get_nonlinear_field(packed, 23, (uint8_t[]) {1, 2, 4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19, 20, 22, 23, 25, 26, 28, 29, 31, 32, 34}))); + return true; } -bool Unpack_C15001(wiegand_message_t* packed, wiegand_card_t* card){ - memset(card, 0, sizeof(wiegand_card_t)); - - if (packed->Length != 36) return false; // Wrong length? Stop here. - - card->OEM = get_linear_field(packed, 1, 10); - card->FacilityCode = get_linear_field(packed, 11, 8); - card->CardNumber = get_linear_field(packed, 19, 16); - card->ParityValid = - (get_bit_by_position(packed, 0) == evenparity32(get_linear_field(packed, 1, 17))) && - (get_bit_by_position(packed, 35) == oddparity32(get_linear_field(packed, 18, 17))); - return true; +bool Pack_C15001(wiegand_card_t *card, wiegand_message_t *packed) { + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0x000000FF) return false; // Can't encode FC. + if (card->CardNumber > 0x0000FFFF) return false; // Can't encode CN. + if (card->IssueLevel > 0) return false; // Not used in this format + if (card->OEM > 0x000003FF) return false; // Can't encode OEM. + + packed->Length = 36; // Set number of bits + set_linear_field(packed, card->OEM, 1, 10); + set_linear_field(packed, card->FacilityCode, 11, 8); + set_linear_field(packed, card->CardNumber, 19, 16); + set_bit_by_position(packed, evenparity32(get_linear_field(packed, 1, 17)), 0); + set_bit_by_position(packed, oddparity32(get_linear_field(packed, 18, 17)), 35); + return add_HID_header(packed); } -bool Pack_H10302(wiegand_card_t* card, wiegand_message_t* packed){ - memset(packed, 0, sizeof(wiegand_message_t)); - - if (card->FacilityCode > 0) return false; // Can't encode FC. (none in this format) - if (card->CardNumber > 0x00000007FFFFFFFF) return false; // Can't encode CN. - if (card->IssueLevel > 0) return false; // Not used in this format - if (card->OEM > 0) return false; // Not used in this format +bool Unpack_C15001(wiegand_message_t *packed, wiegand_card_t *card) { + memset(card, 0, sizeof(wiegand_card_t)); - packed->Length = 37; // Set number of bits - set_linear_field(packed, card->CardNumber, 1, 35); - set_bit_by_position(packed, evenparity32(get_linear_field(packed, 1, 18)), 0); - set_bit_by_position(packed, oddparity32(get_linear_field(packed, 18, 18)), 36); - return add_HID_header(packed); + if (packed->Length != 36) return false; // Wrong length? Stop here. + + card->OEM = get_linear_field(packed, 1, 10); + card->FacilityCode = get_linear_field(packed, 11, 8); + card->CardNumber = get_linear_field(packed, 19, 16); + card->ParityValid = + (get_bit_by_position(packed, 0) == evenparity32(get_linear_field(packed, 1, 17))) && + (get_bit_by_position(packed, 35) == oddparity32(get_linear_field(packed, 18, 17))); + return true; } -bool Unpack_H10302(wiegand_message_t* packed, wiegand_card_t* card){ - memset(card, 0, sizeof(wiegand_card_t)); - - if (packed->Length != 37) return false; // Wrong length? Stop here. - - card->CardNumber = get_linear_field(packed, 1, 35); - card->ParityValid = - (get_bit_by_position(packed, 0) == evenparity32(get_linear_field(packed, 1, 18))) && - (get_bit_by_position(packed, 36) == oddparity32(get_linear_field(packed, 18, 18))); - return true; +bool Pack_H10302(wiegand_card_t *card, wiegand_message_t *packed) { + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0) return false; // Can't encode FC. (none in this format) + if (card->CardNumber > 0x00000007FFFFFFFF) return false; // Can't encode CN. + if (card->IssueLevel > 0) return false; // Not used in this format + if (card->OEM > 0) return false; // Not used in this format + + packed->Length = 37; // Set number of bits + set_linear_field(packed, card->CardNumber, 1, 35); + set_bit_by_position(packed, evenparity32(get_linear_field(packed, 1, 18)), 0); + set_bit_by_position(packed, oddparity32(get_linear_field(packed, 18, 18)), 36); + return add_HID_header(packed); } -bool Pack_H10304(wiegand_card_t* card, wiegand_message_t* packed){ - memset(packed, 0, sizeof(wiegand_message_t)); - - if (card->FacilityCode > 0x0000FFFF) return false; // Can't encode FC. - if (card->CardNumber > 0x0007FFFF) return false; // Can't encode CN. - if (card->IssueLevel > 0) return false; // Not used in this format - if (card->OEM > 0) return false; // Not used in this format - - packed->Length = 37; // Set number of bits - packed->Bot |= (card->CardNumber & 0x0007FFFF) << 1; - packed->Bot |= (card->FacilityCode & 0x00000FFF) << 20; - packed->Mid |= (card->FacilityCode & 0x0000F000) >> 12; - packed->Mid |= (evenparity32((packed->Mid & 0x0000000F) ^ (packed->Bot & 0xFFFC0000)) & 1) << 4; - packed->Bot |= ( oddparity32(packed->Bot & 0x0007FFFE) & 1); - return add_HID_header(packed); +bool Unpack_H10302(wiegand_message_t *packed, wiegand_card_t *card) { + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 37) return false; // Wrong length? Stop here. + + card->CardNumber = get_linear_field(packed, 1, 35); + card->ParityValid = + (get_bit_by_position(packed, 0) == evenparity32(get_linear_field(packed, 1, 18))) && + (get_bit_by_position(packed, 36) == oddparity32(get_linear_field(packed, 18, 18))); + return true; } -bool Unpack_H10304(wiegand_message_t* packed, wiegand_card_t* card){ - memset(card, 0, sizeof(wiegand_card_t)); +bool Pack_H10304(wiegand_card_t *card, wiegand_message_t *packed) { + memset(packed, 0, sizeof(wiegand_message_t)); - if (packed->Length != 37) return false; // Wrong length? Stop here. + if (card->FacilityCode > 0x0000FFFF) return false; // Can't encode FC. + if (card->CardNumber > 0x0007FFFF) return false; // Can't encode CN. + if (card->IssueLevel > 0) return false; // Not used in this format + if (card->OEM > 0) return false; // Not used in this format - card->CardNumber = (packed->Bot >> 1) & 0x0007FFFF; - card->FacilityCode = ((packed->Mid & 0xF) << 12) | ((packed->Bot >> 20)); - card->ParityValid = - (evenparity32((packed->Mid & 0x0000000F) ^ (packed->Bot & 0xFFFC0000)) == ((packed->Mid >> 4) & 1)) && - (oddparity32( packed->Bot & 0x0007FFFE) == (packed->Bot & 1)); - return true; + packed->Length = 37; // Set number of bits + packed->Bot |= (card->CardNumber & 0x0007FFFF) << 1; + packed->Bot |= (card->FacilityCode & 0x00000FFF) << 20; + packed->Mid |= (card->FacilityCode & 0x0000F000) >> 12; + packed->Mid |= (evenparity32((packed->Mid & 0x0000000F) ^ (packed->Bot & 0xFFFC0000)) & 1) << 4; + packed->Bot |= (oddparity32(packed->Bot & 0x0007FFFE) & 1); + return add_HID_header(packed); } -bool Pack_P10001(wiegand_card_t* card, wiegand_message_t* packed){ +bool Unpack_H10304(wiegand_message_t *packed, wiegand_card_t *card) { + memset(card, 0, sizeof(wiegand_card_t)); - memset(packed, 0, sizeof(wiegand_message_t)); + if (packed->Length != 37) return false; // Wrong length? Stop here. - if (card->FacilityCode > 0xFFF) return false; // Can't encode FC. - if (card->CardNumber > 0xFFFF) return false; // Can't encode CN. - if (card->IssueLevel > 0) return false; // Not used in this format - if (card->OEM > 0) return false; // Not used in this format - - packed->Length = 40; // Set number of bits - set_linear_field(packed, 0xF, 0, 4); - set_linear_field(packed, card->FacilityCode, 4, 12); - set_linear_field(packed, card->CardNumber, 16, 16); - set_linear_field(packed, - get_linear_field(packed, 0, 8) ^ - get_linear_field(packed, 8, 8) ^ - get_linear_field(packed, 16, 8) ^ - get_linear_field(packed, 24, 8) - , 32, 8); - return add_HID_header(packed); + card->CardNumber = (packed->Bot >> 1) & 0x0007FFFF; + card->FacilityCode = ((packed->Mid & 0xF) << 12) | ((packed->Bot >> 20)); + card->ParityValid = + (evenparity32((packed->Mid & 0x0000000F) ^ (packed->Bot & 0xFFFC0000)) == ((packed->Mid >> 4) & 1)) && + (oddparity32(packed->Bot & 0x0007FFFE) == (packed->Bot & 1)); + return true; } -bool Unpack_P10001(wiegand_message_t* packed, wiegand_card_t* card){ +bool Pack_P10001(wiegand_card_t *card, wiegand_message_t *packed) { - memset(card, 0, sizeof(wiegand_card_t)); + memset(packed, 0, sizeof(wiegand_message_t)); - if (packed->Length != 40) return false; // Wrong length? Stop here. + if (card->FacilityCode > 0xFFF) return false; // Can't encode FC. + if (card->CardNumber > 0xFFFF) return false; // Can't encode CN. + if (card->IssueLevel > 0) return false; // Not used in this format + if (card->OEM > 0) return false; // Not used in this format - card->CardNumber = get_linear_field(packed, 16, 16); - card->FacilityCode = get_linear_field(packed, 4, 12); - card->ParityValid = ( - get_linear_field(packed, 0, 8) ^ - get_linear_field(packed, 8, 8) ^ - get_linear_field(packed, 16, 8) ^ - get_linear_field(packed, 24, 8) - ) == get_linear_field(packed, 32, 8); - return true; + packed->Length = 40; // Set number of bits + set_linear_field(packed, 0xF, 0, 4); + set_linear_field(packed, card->FacilityCode, 4, 12); + set_linear_field(packed, card->CardNumber, 16, 16); + set_linear_field(packed, + get_linear_field(packed, 0, 8) ^ + get_linear_field(packed, 8, 8) ^ + get_linear_field(packed, 16, 8) ^ + get_linear_field(packed, 24, 8) + , 32, 8); + return add_HID_header(packed); } -bool Pack_C1k48s(wiegand_card_t* card, wiegand_message_t* packed){ +bool Unpack_P10001(wiegand_message_t *packed, wiegand_card_t *card) { - memset(packed, 0, sizeof(wiegand_message_t)); + memset(card, 0, sizeof(wiegand_card_t)); - if (card->FacilityCode > 0x003FFFFF) return false; // Can't encode FC. - if (card->CardNumber > 0x007FFFFF) return false; // Can't encode CN. - if (card->IssueLevel > 0) return false; // Not used in this format - if (card->OEM > 0) return false; // Not used in this format + if (packed->Length != 40) return false; // Wrong length? Stop here. - packed->Length = 48; // Set number of bits - packed->Bot |= (card->CardNumber & 0x007FFFFF) << 1; - packed->Bot |= (card->FacilityCode & 0x000000FF) << 24; - packed->Mid |= (card->FacilityCode & 0x003FFF00) >> 8; - packed->Mid |= (evenparity32((packed->Mid & 0x00001B6D) ^ (packed->Bot & 0xB6DB6DB6)) & 1) << 14; - packed->Bot |= ( oddparity32((packed->Mid & 0x000036DB) ^ (packed->Bot & 0x6DB6DB6C)) & 1); - packed->Mid |= ( oddparity32((packed->Mid & 0x00007FFF) ^ (packed->Bot & 0xFFFFFFFF)) & 1) << 15; - return add_HID_header(packed); + card->CardNumber = get_linear_field(packed, 16, 16); + card->FacilityCode = get_linear_field(packed, 4, 12); + card->ParityValid = ( + get_linear_field(packed, 0, 8) ^ + get_linear_field(packed, 8, 8) ^ + get_linear_field(packed, 16, 8) ^ + get_linear_field(packed, 24, 8) + ) == get_linear_field(packed, 32, 8); + return true; } -bool Unpack_C1k48s(wiegand_message_t* packed, wiegand_card_t* card){ - memset(card, 0, sizeof(wiegand_card_t)); +bool Pack_C1k48s(wiegand_card_t *card, wiegand_message_t *packed) { - if (packed->Length != 48) return false; // Wrong length? Stop here. + memset(packed, 0, sizeof(wiegand_message_t)); - card->CardNumber = (packed->Bot >> 1) & 0x007FFFFF; - card->FacilityCode = ((packed->Mid & 0x00003FFF) << 8) | ((packed->Bot >> 24)); - card->ParityValid = - (evenparity32((packed->Mid & 0x00001B6D) ^ (packed->Bot & 0xB6DB6DB6)) == ((packed->Mid >> 14) & 1)) && - ( oddparity32((packed->Mid & 0x000036DB) ^ (packed->Bot & 0x6DB6DB6C)) == ((packed->Bot >> 0) & 1)) && - ( oddparity32((packed->Mid & 0x00007FFF) ^ (packed->Bot & 0xFFFFFFFF)) == ((packed->Mid >> 15) & 1)); - return true; + if (card->FacilityCode > 0x003FFFFF) return false; // Can't encode FC. + if (card->CardNumber > 0x007FFFFF) return false; // Can't encode CN. + if (card->IssueLevel > 0) return false; // Not used in this format + if (card->OEM > 0) return false; // Not used in this format + + packed->Length = 48; // Set number of bits + packed->Bot |= (card->CardNumber & 0x007FFFFF) << 1; + packed->Bot |= (card->FacilityCode & 0x000000FF) << 24; + packed->Mid |= (card->FacilityCode & 0x003FFF00) >> 8; + packed->Mid |= (evenparity32((packed->Mid & 0x00001B6D) ^ (packed->Bot & 0xB6DB6DB6)) & 1) << 14; + packed->Bot |= (oddparity32((packed->Mid & 0x000036DB) ^ (packed->Bot & 0x6DB6DB6C)) & 1); + packed->Mid |= (oddparity32((packed->Mid & 0x00007FFF) ^ (packed->Bot & 0xFFFFFFFF)) & 1) << 15; + return add_HID_header(packed); +} + +bool Unpack_C1k48s(wiegand_message_t *packed, wiegand_card_t *card) { + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 48) return false; // Wrong length? Stop here. + + card->CardNumber = (packed->Bot >> 1) & 0x007FFFFF; + card->FacilityCode = ((packed->Mid & 0x00003FFF) << 8) | ((packed->Bot >> 24)); + card->ParityValid = + (evenparity32((packed->Mid & 0x00001B6D) ^ (packed->Bot & 0xB6DB6DB6)) == ((packed->Mid >> 14) & 1)) && + (oddparity32((packed->Mid & 0x000036DB) ^ (packed->Bot & 0x6DB6DB6C)) == ((packed->Bot >> 0) & 1)) && + (oddparity32((packed->Mid & 0x00007FFF) ^ (packed->Bot & 0xFFFFFFFF)) == ((packed->Mid >> 15) & 1)); + return true; } static const cardformat_t FormatTable[] = { @@ -601,7 +601,7 @@ static const cardformat_t FormatTable[] = { {NULL, NULL, NULL, NULL, {0, 0, 0, 0, 0}} // Must null terminate array }; -void HIDListFormats(){ +void HIDListFormats() { if (FormatTable[0].Name == NULL) return; @@ -617,58 +617,58 @@ void HIDListFormats(){ return; } -cardformat_t HIDGetCardFormat(int idx){ +cardformat_t HIDGetCardFormat(int idx) { return FormatTable[idx]; } int HIDFindCardFormat(const char *format) { - if (FormatTable[0].Name == NULL) + if (FormatTable[0].Name == NULL) return -1; - + int i = 0; // str_lower - + while (FormatTable[i].Name && strcmp(FormatTable[i].Name, format)) { ++i; } if (FormatTable[i].Name) return i; - + return -1; } -bool HIDPack(int format_idx, wiegand_card_t* card, wiegand_message_t* packed){ - memset(packed, 0, sizeof(wiegand_message_t)); - - if (format_idx < 0 || format_idx >= (sizeof(FormatTable) / sizeof(FormatTable[0]))) - return false; - - return FormatTable[format_idx].Pack(card, packed); +bool HIDPack(int format_idx, wiegand_card_t *card, wiegand_message_t *packed) { + memset(packed, 0, sizeof(wiegand_message_t)); + + if (format_idx < 0 || format_idx >= (sizeof(FormatTable) / sizeof(FormatTable[0]))) + return false; + + return FormatTable[format_idx].Pack(card, packed); } -void HIDDisplayUnpackedCard(wiegand_card_t* card, const cardformat_t format){ +void HIDDisplayUnpackedCard(wiegand_card_t *card, const cardformat_t format) { -/* - PrintAndLogEx(SUCCESS, " Format: %s (%s)", format.Name, format.Descrp); + /* + PrintAndLogEx(SUCCESS, " Format: %s (%s)", format.Name, format.Descrp); - if (format.Fields.hasFacilityCode) - PrintAndLogEx(SUCCESS, "Facility Code: %d",card->FacilityCode); + if (format.Fields.hasFacilityCode) + PrintAndLogEx(SUCCESS, "Facility Code: %d",card->FacilityCode); - if (format.Fields.hasCardNumber) - PrintAndLogEx(SUCCESS, " Card Number: %d",card->CardNumber); + if (format.Fields.hasCardNumber) + PrintAndLogEx(SUCCESS, " Card Number: %d",card->CardNumber); - if (format.Fields.hasIssueLevel) - PrintAndLogEx(SUCCESS, " Issue Level: %d",card->IssueLevel); + if (format.Fields.hasIssueLevel) + PrintAndLogEx(SUCCESS, " Issue Level: %d",card->IssueLevel); - if (format.Fields.hasOEMCode) - PrintAndLogEx(SUCCESS, " OEM Code: %d",card->OEM); + if (format.Fields.hasOEMCode) + PrintAndLogEx(SUCCESS, " OEM Code: %d",card->OEM); - if (format.Fields.hasParity) - PrintAndLogEx(SUCCESS, " Parity: %s",card->ParityValid ? "Valid" : "Invalid"); -*/ + if (format.Fields.hasParity) + PrintAndLogEx(SUCCESS, " Parity: %s",card->ParityValid ? "Valid" : "Invalid"); + */ char s[80] = {0}; if (format.Fields.hasFacilityCode) @@ -681,23 +681,23 @@ void HIDDisplayUnpackedCard(wiegand_card_t* card, const cardformat_t format){ snprintf(s + strlen(s), sizeof(s) - strlen(s), " Issue %d", card->IssueLevel); if (format.Fields.hasOEMCode) - snprintf(s + strlen(s), sizeof(s) - strlen(s), " OEM: %d",card->OEM); + snprintf(s + strlen(s), sizeof(s) - strlen(s), " OEM: %d", card->OEM); if (format.Fields.hasParity) snprintf(s + strlen(s), sizeof(s) - strlen(s), " parity: %s", card->ParityValid ? "valid" : "invalid"); - + PrintAndLogEx(SUCCESS, "%s [%s - %s]", s, format.Name, format.Descrp); } -bool HIDTryUnpack(wiegand_message_t* packed, bool ignore_parity){ - if (FormatTable[0].Name == NULL) +bool HIDTryUnpack(wiegand_message_t *packed, bool ignore_parity) { + if (FormatTable[0].Name == NULL) return false; bool result = false; int i = 0; wiegand_card_t card; memset(&card, 0, sizeof(wiegand_card_t)); - + while (FormatTable[i].Name) { if (FormatTable[i].Unpack(packed, &card)) { if (ignore_parity || !FormatTable[i].Fields.hasParity || card.ParityValid) { @@ -707,9 +707,9 @@ bool HIDTryUnpack(wiegand_message_t* packed, bool ignore_parity){ } ++i; } - if ( result == false ) { + if (result == false) { PrintAndLogEx(SUCCESS, "Unknown. Bit len %d", packed->Length); } - + return result; } diff --git a/client/wiegand_formats.h b/client/wiegand_formats.h index 102c2b0cb..e3aca4b9c 100644 --- a/client/wiegand_formats.h +++ b/client/wiegand_formats.h @@ -23,26 +23,26 @@ #include "ui.h" typedef struct { - bool hasCardNumber; - bool hasFacilityCode; - bool hasIssueLevel; - bool hasOEMCode; - bool hasParity; + bool hasCardNumber; + bool hasFacilityCode; + bool hasIssueLevel; + bool hasOEMCode; + bool hasParity; } cardformatdescriptor_t; // Structure for defined Wiegand card formats available for packing/unpacking typedef struct { - const char* Name; - bool (*Pack)(wiegand_card_t* card, wiegand_message_t* packed); - bool (*Unpack)(wiegand_message_t* packed, wiegand_card_t* card); - const char* Descrp; - cardformatdescriptor_t Fields; + const char *Name; + bool (*Pack)(wiegand_card_t *card, wiegand_message_t *packed); + bool (*Unpack)(wiegand_message_t *packed, wiegand_card_t *card); + const char *Descrp; + cardformatdescriptor_t Fields; } cardformat_t; void HIDListFormats(); int HIDFindCardFormat(const char *format); cardformat_t HIDGetCardFormat(int idx); -bool HIDPack(int FormatIndex, wiegand_card_t* card, wiegand_message_t* packed); -bool HIDTryUnpack(wiegand_message_t* packed, bool ignoreParity); +bool HIDPack(int FormatIndex, wiegand_card_t *card, wiegand_message_t *packed); +bool HIDTryUnpack(wiegand_message_t *packed, bool ignoreParity); #endif diff --git a/client/wiegand_formatutils.c b/client/wiegand_formatutils.c index dd3678daf..a4529955d 100644 --- a/client/wiegand_formatutils.c +++ b/client/wiegand_formatutils.c @@ -15,171 +15,171 @@ #include "wiegand_formatutils.h" #include "ui.h" -bool get_bit_by_position(wiegand_message_t* data, uint8_t pos){ - if (pos >= data->Length) return false; - pos = (data->Length - pos) - 1; // invert ordering; Indexing goes from 0 to 1. Subtract 1 for weight of bit. - bool result = false; - if (pos > 95) - result = false; - else if (pos > 63) - result = (data->Top >> (pos - 64)) & 1; - else if (pos > 31) - result = (data->Mid >> (pos - 32)) & 1; - else - result = (data->Bot >> pos) & 1; - return result; +bool get_bit_by_position(wiegand_message_t *data, uint8_t pos) { + if (pos >= data->Length) return false; + pos = (data->Length - pos) - 1; // invert ordering; Indexing goes from 0 to 1. Subtract 1 for weight of bit. + bool result = false; + if (pos > 95) + result = false; + else if (pos > 63) + result = (data->Top >> (pos - 64)) & 1; + else if (pos > 31) + result = (data->Mid >> (pos - 32)) & 1; + else + result = (data->Bot >> pos) & 1; + return result; } -bool set_bit_by_position(wiegand_message_t* data, bool value, uint8_t pos){ - if (pos >= data->Length) return false; - pos = (data->Length - pos) - 1; // invert ordering; Indexing goes from 0 to 1. Subtract 1 for weight of bit. - if (pos > 95) { - return false; - } else if (pos > 63) { - if (value) - data->Top |= (1 << (pos - 64)); - else - data->Top &= ~(1 << (pos - 64)); - return true; - } else if (pos > 31) { - if (value) - data->Mid |= (1 << (pos - 32)); - else - data->Mid &= ~(1 << (pos - 32)); - return true; - } else { - if (value) - data->Bot |= (1 << pos); - else - data->Bot &= ~(1 << pos); - return true; - } +bool set_bit_by_position(wiegand_message_t *data, bool value, uint8_t pos) { + if (pos >= data->Length) return false; + pos = (data->Length - pos) - 1; // invert ordering; Indexing goes from 0 to 1. Subtract 1 for weight of bit. + if (pos > 95) { + return false; + } else if (pos > 63) { + if (value) + data->Top |= (1 << (pos - 64)); + else + data->Top &= ~(1 << (pos - 64)); + return true; + } else if (pos > 31) { + if (value) + data->Mid |= (1 << (pos - 32)); + else + data->Mid &= ~(1 << (pos - 32)); + return true; + } else { + if (value) + data->Bot |= (1 << pos); + else + data->Bot &= ~(1 << pos); + return true; + } } /** * Safeguard the data by doing a manual deep copy - * + * * At the time of the initial writing, the struct does not contain pointers. That doesn't * mean it won't eventually contain one, however. To prevent memory leaks and erroneous * aliasing, perform the copy function manually instead. Hence, this function. - * + * * If the definition of the wiegand_message struct changes, this function must also * be updated to match. */ -void message_datacopy(wiegand_message_t* src, wiegand_message_t* dest){ - dest->Bot = src->Bot; - dest->Mid = src->Mid; - dest->Top = src->Top; - dest->Length = src->Length; +void message_datacopy(wiegand_message_t *src, wiegand_message_t *dest) { + dest->Bot = src->Bot; + dest->Mid = src->Mid; + dest->Top = src->Top; + dest->Length = src->Length; } /** * - * Yes, this is horribly inefficient for linear data. + * Yes, this is horribly inefficient for linear data. * The current code is a temporary measure to have a working function in place * until all the bugs shaken from the block/chunk version of the code. * */ -uint64_t get_linear_field(wiegand_message_t* data, uint8_t firstBit, uint8_t length){ - uint64_t result = 0; - for (uint8_t i = 0; i < length; i++ ) { - result = (result << 1) | get_bit_by_position(data, firstBit + i); - } - return result; +uint64_t get_linear_field(wiegand_message_t *data, uint8_t firstBit, uint8_t length) { + uint64_t result = 0; + for (uint8_t i = 0; i < length; i++) { + result = (result << 1) | get_bit_by_position(data, firstBit + i); + } + return result; } -bool set_linear_field(wiegand_message_t* data, uint64_t value, uint8_t firstBit, uint8_t length){ - wiegand_message_t tmpdata; - message_datacopy(data, &tmpdata); - bool result = true; - for (int i = 0; i < length; i++){ - result &= set_bit_by_position(&tmpdata, (value >> ((length - i) - 1)) & 1, firstBit + i); - } - if (result) - message_datacopy(&tmpdata, data); - - return result; -} - -uint64_t get_nonlinear_field(wiegand_message_t* data, uint8_t numBits, uint8_t* bits){ - uint64_t result = 0; - for (int i = 0; i < numBits; i++){ - result = (result << 1) | (get_bit_by_position(data, *(bits+i)) & 1); - } - return result; -} -bool set_nonlinear_field(wiegand_message_t* data, uint64_t value, uint8_t numBits, uint8_t* bits){ - +bool set_linear_field(wiegand_message_t *data, uint64_t value, uint8_t firstBit, uint8_t length) { wiegand_message_t tmpdata; message_datacopy(data, &tmpdata); - bool result = true; - for (int i = 0; i < numBits; i++){ - result &= set_bit_by_position(&tmpdata, (value >> ((numBits - i) - 1)) & 1, *(bits + i)); + for (int i = 0; i < length; i++) { + result &= set_bit_by_position(&tmpdata, (value >> ((length - i) - 1)) & 1, firstBit + i); } - if (result) message_datacopy(&tmpdata, data); return result; } -uint8_t get_length_from_header(wiegand_message_t* data) { - uint8_t len = 0; - uint32_t hfmt = 0; // for calculating card length - - if ((data->Top & 0x000FFFFF) > 0) { // > 64 bits - hfmt = data->Top & 0x000FFFFF; - len = 64; - } else if ((data->Mid & 0xFFFFFFC0) > 0) { // < 63-38 bits - hfmt = data->Mid & 0xFFFFFFC0; - len = 32; - } else if (data->Mid && (data->Mid & 0x00000020) == 0) { // 37 bits; - hfmt = 0; - len = 37; - } else if ((data->Mid & 0x0000001F) > 0){ // 36-32 bits - printf("a\n"); - hfmt = data->Mid & 0x0000001F; - len = 32; - } else if (data->Top == 0 && data->Mid == 0) { //< 32 bits - hfmt = data->Bot; - len = 0; - } else { - hfmt = data->Bot; - len = 0; - } +uint64_t get_nonlinear_field(wiegand_message_t *data, uint8_t numBits, uint8_t *bits) { + uint64_t result = 0; + for (int i = 0; i < numBits; i++) { + result = (result << 1) | (get_bit_by_position(data, *(bits + i)) & 1); + } + return result; +} +bool set_nonlinear_field(wiegand_message_t *data, uint64_t value, uint8_t numBits, uint8_t *bits) { - while (hfmt > 1) { - hfmt >>= 1; - len++; - } - return len; + wiegand_message_t tmpdata; + message_datacopy(data, &tmpdata); + + bool result = true; + for (int i = 0; i < numBits; i++) { + result &= set_bit_by_position(&tmpdata, (value >> ((numBits - i) - 1)) & 1, *(bits + i)); + } + + if (result) + message_datacopy(&tmpdata, data); + + return result; } -wiegand_message_t initialize_message_object(uint32_t top, uint32_t mid, uint32_t bot){ - wiegand_message_t result; - memset(&result, 0, sizeof(wiegand_message_t)); - - result.Top = top; - result.Mid = mid; - result.Bot = bot; - result.Length = get_length_from_header(&result); - return result; +uint8_t get_length_from_header(wiegand_message_t *data) { + uint8_t len = 0; + uint32_t hfmt = 0; // for calculating card length + + if ((data->Top & 0x000FFFFF) > 0) { // > 64 bits + hfmt = data->Top & 0x000FFFFF; + len = 64; + } else if ((data->Mid & 0xFFFFFFC0) > 0) { // < 63-38 bits + hfmt = data->Mid & 0xFFFFFFC0; + len = 32; + } else if (data->Mid && (data->Mid & 0x00000020) == 0) { // 37 bits; + hfmt = 0; + len = 37; + } else if ((data->Mid & 0x0000001F) > 0) { // 36-32 bits + printf("a\n"); + hfmt = data->Mid & 0x0000001F; + len = 32; + } else if (data->Top == 0 && data->Mid == 0) { //< 32 bits + hfmt = data->Bot; + len = 0; + } else { + hfmt = data->Bot; + len = 0; + } + + while (hfmt > 1) { + hfmt >>= 1; + len++; + } + return len; } -bool add_HID_header(wiegand_message_t* data){ - if (data->Length > 84 || data->Length == 0) return false; // Invalid value +wiegand_message_t initialize_message_object(uint32_t top, uint32_t mid, uint32_t bot) { + wiegand_message_t result; + memset(&result, 0, sizeof(wiegand_message_t)); - if (data->Length >= 64){ - data->Top |= 1 << (data->Length - 64); // leading 1: start bit - data->Top |= 0x09e00000; // Extended-length header - } else if (data->Length > 37){ - data->Mid |= 1 << (data->Length - 32); // leading 1: start bit - data->Top |= 0x09e00000; // Extended-length header - } else if (data->Length == 37){ - // No header bits added to 37-bit cards - } else if (data->Length >= 32){ - data->Mid |= 0x20; // Bit 37; standard header - data->Mid |= 1 << (data->Length - 32); // leading 1: start bit - } else { - data->Mid |= 0x20; // Bit 37; standard header - data->Bot |= 1 << data->Length; // leading 1: start bit - } - return true; + result.Top = top; + result.Mid = mid; + result.Bot = bot; + result.Length = get_length_from_header(&result); + return result; +} + +bool add_HID_header(wiegand_message_t *data) { + if (data->Length > 84 || data->Length == 0) return false; // Invalid value + + if (data->Length >= 64) { + data->Top |= 1 << (data->Length - 64); // leading 1: start bit + data->Top |= 0x09e00000; // Extended-length header + } else if (data->Length > 37) { + data->Mid |= 1 << (data->Length - 32); // leading 1: start bit + data->Top |= 0x09e00000; // Extended-length header + } else if (data->Length == 37) { + // No header bits added to 37-bit cards + } else if (data->Length >= 32) { + data->Mid |= 0x20; // Bit 37; standard header + data->Mid |= 1 << (data->Length - 32); // leading 1: start bit + } else { + data->Mid |= 0x20; // Bit 37; standard header + data->Bot |= 1 << data->Length; // leading 1: start bit + } + return true; } diff --git a/client/wiegand_formatutils.h b/client/wiegand_formatutils.h index d9e74bcb2..534bea4f3 100644 --- a/client/wiegand_formatutils.h +++ b/client/wiegand_formatutils.h @@ -18,32 +18,32 @@ // Structure for packed wiegand messages // Always align lowest value (last transmitted) bit to ordinal position 0 (lowest valued bit bottom) typedef struct { - uint8_t Length; // Number of encoded bits in wiegand message (excluding headers and preamble) - uint32_t Top; // Bits in x<<64 positions - uint32_t Mid; // Bits in x<<32 positions - uint32_t Bot; // Lowest ordinal positions + uint8_t Length; // Number of encoded bits in wiegand message (excluding headers and preamble) + uint32_t Top; // Bits in x<<64 positions + uint32_t Mid; // Bits in x<<32 positions + uint32_t Bot; // Lowest ordinal positions } wiegand_message_t; // Structure for unpacked wiegand card, like HID prox typedef struct { - uint32_t FacilityCode; - uint64_t CardNumber; - uint32_t IssueLevel; - uint32_t OEM; - bool ParityValid; // Only valid for responses + uint32_t FacilityCode; + uint64_t CardNumber; + uint32_t IssueLevel; + uint32_t OEM; + bool ParityValid; // Only valid for responses } wiegand_card_t; -bool get_bit_by_position(wiegand_message_t* data, uint8_t pos); -bool set_bit_by_position(wiegand_message_t* data, bool value, uint8_t pos); +bool get_bit_by_position(wiegand_message_t *data, uint8_t pos); +bool set_bit_by_position(wiegand_message_t *data, bool value, uint8_t pos); -uint64_t get_linear_field(wiegand_message_t* data, uint8_t firstBit, uint8_t length); -bool set_linear_field(wiegand_message_t* data, uint64_t value, uint8_t firstBit, uint8_t length); +uint64_t get_linear_field(wiegand_message_t *data, uint8_t firstBit, uint8_t length); +bool set_linear_field(wiegand_message_t *data, uint64_t value, uint8_t firstBit, uint8_t length); -uint64_t get_nonlinear_field(wiegand_message_t* data, uint8_t numBits, uint8_t* bits); -bool set_nonlinear_field(wiegand_message_t* data, uint64_t value, uint8_t numBits, uint8_t* bits); +uint64_t get_nonlinear_field(wiegand_message_t *data, uint8_t numBits, uint8_t *bits); +bool set_nonlinear_field(wiegand_message_t *data, uint64_t value, uint8_t numBits, uint8_t *bits); wiegand_message_t initialize_message_object(uint32_t top, uint32_t mid, uint32_t bot); -bool add_HID_header(wiegand_message_t* data); +bool add_HID_header(wiegand_message_t *data); #endif From ffd03dadaae9b2a7fa3f0571c266b498e282f49d Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 19 Sep 2019 10:48:32 +0200 Subject: [PATCH 0734/1854] style --- client/cmdlfawid.c | 6 +++--- client/cmdlffdx.c | 6 +++--- client/cmdlfguard.c | 6 +++--- client/cmdlfindala.c | 32 ++++++++++++++++---------------- client/cmdlfio.c | 10 +++++----- client/cmdlfjablotron.c | 10 +++++----- client/cmdlfkeri.c | 10 +++++----- 7 files changed, 40 insertions(+), 40 deletions(-) diff --git a/client/cmdlfawid.c b/client/cmdlfawid.c index 934335c64..056d95af4 100644 --- a/client/cmdlfawid.c +++ b/client/cmdlfawid.c @@ -442,15 +442,15 @@ static int CmdAWIDClone(const char *Cmd) { if (i == 0) { SetConfigWithBlock0(blocks[0]); - if ( t55xxAquireAndCompareBlock0(false, 0, blocks[0], false) ) + if (t55xxAquireAndCompareBlock0(false, 0, blocks[0], false)) continue; } - + if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) res++; } - if ( res == 0 ) + if (res == 0) PrintAndLogEx(SUCCESS, "Success writing to tag"); return PM3_SUCCESS; diff --git a/client/cmdlffdx.c b/client/cmdlffdx.c index 233783b33..85529609d 100644 --- a/client/cmdlffdx.c +++ b/client/cmdlffdx.c @@ -323,15 +323,15 @@ static int CmdFdxClone(const char *Cmd) { if (i == 0) { SetConfigWithBlock0(blocks[0]); - if ( t55xxAquireAndCompareBlock0(false, 0, blocks[0], false) ) + if (t55xxAquireAndCompareBlock0(false, 0, blocks[0], false)) continue; } - + if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) res++; } - if ( res == 0 ) + if (res == 0) PrintAndLogEx(SUCCESS, "Success writing to tag"); return PM3_SUCCESS; diff --git a/client/cmdlfguard.c b/client/cmdlfguard.c index 036597f0f..fe00d1187 100644 --- a/client/cmdlfguard.c +++ b/client/cmdlfguard.c @@ -210,15 +210,15 @@ static int CmdGuardClone(const char *Cmd) { if (i == 0) { SetConfigWithBlock0(blocks[0]); - if ( t55xxAquireAndCompareBlock0(false, 0, blocks[0], false) ) + if (t55xxAquireAndCompareBlock0(false, 0, blocks[0], false)) continue; } - + if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) res++; } - if ( res == 0 ) + if (res == 0) PrintAndLogEx(SUCCESS, "Success writing to tag"); return PM3_SUCCESS; diff --git a/client/cmdlfindala.c b/client/cmdlfindala.c index da13766db..673ed1438 100644 --- a/client/cmdlfindala.c +++ b/client/cmdlfindala.c @@ -444,7 +444,7 @@ static int CmdIndalaSim(const char *Cmd) { static int CmdIndalaClone(const char *Cmd) { bool isLongUid = false; - uint32_t blocks[8] = {0}; + uint32_t blocks[8] = {0}; uint8_t max = 0; uint8_t data[7 * 4]; @@ -470,17 +470,17 @@ static int CmdIndalaClone(const char *Cmd) { CLIGetHexWithReturn(2, data, &datalen); CLIParserFree(); -/* - //TODO add selection of chip for Q5 or T55x7 - - // data[0] = T5555_SET_BITRATE(32 | T5555_MODULATION_PSK2 | 7 << T5555_MAXBLOCK_SHIFT; - //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=7;Inverse data) - // T5567WriteBlock(0x603E10E2,0); - - // data[0] = T5555_SET_BITRATE(32 | T5555_MODULATION_PSK1 | 2 << T5555_MAXBLOCK_SHIFT; - //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=2;Inverse data) - // T5567WriteBlock(0x603E1042,0); -*/ + /* + //TODO add selection of chip for Q5 or T55x7 + + // data[0] = T5555_SET_BITRATE(32 | T5555_MODULATION_PSK2 | 7 << T5555_MAXBLOCK_SHIFT; + //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=7;Inverse data) + // T5567WriteBlock(0x603E10E2,0); + + // data[0] = T5555_SET_BITRATE(32 | T5555_MODULATION_PSK1 | 2 << T5555_MAXBLOCK_SHIFT; + //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=2;Inverse data) + // T5567WriteBlock(0x603E1042,0); + */ if (isLongUid) { // config for Indala (RF/32;PSK2 with RF/2;Maxblock=7) @@ -495,7 +495,7 @@ static int CmdIndalaClone(const char *Cmd) { blocks[7] = bytes_to_num(data + 24, 4); max = 8; } else { - // config for Indala 64 format (RF/32;PSK1 with RF/2;Maxblock=2) + // config for Indala 64 format (RF/32;PSK1 with RF/2;Maxblock=2) PrintAndLogEx(INFO, "Preparing to clone Indala 64bit tag with RawID %s", sprint_hex(data, datalen)); blocks[0] = T55x7_BITRATE_RF_32 | T55x7_MODULATION_PSK1 | (2 << T55x7_MAXBLOCK_SHIFT); blocks[1] = bytes_to_num(data, 4); @@ -530,15 +530,15 @@ static int CmdIndalaClone(const char *Cmd) { if (i == 0) { SetConfigWithBlock0(blocks[0]); - if ( t55xxAquireAndCompareBlock0(false, 0, blocks[0], false) ) + if (t55xxAquireAndCompareBlock0(false, 0, blocks[0], false)) continue; } - + if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) res++; } - if ( res == 0 ) + if (res == 0) PrintAndLogEx(SUCCESS, "Success writing to tag"); return PM3_SUCCESS; diff --git a/client/cmdlfio.c b/client/cmdlfio.c index b71302ea9..7b3e777c6 100644 --- a/client/cmdlfio.c +++ b/client/cmdlfio.c @@ -269,7 +269,7 @@ static int CmdIOProxClone(const char *Cmd) { } uint32_t blocks[3] = {T55x7_MODULATION_FSK2a | T55x7_BITRATE_RF_64 | 2 << T55x7_MAXBLOCK_SHIFT, 0, 0}; - + if (tolower(param_getchar(Cmd, 3) == 'q')) blocks[0] = T5555_MODULATION_FSK2 | T5555_INVERT_OUTPUT | T5555_SET_BITRATE(64) | 2 << T5555_MAXBLOCK_SHIFT; @@ -304,17 +304,17 @@ static int CmdIOProxClone(const char *Cmd) { if (i == 0) { SetConfigWithBlock0(blocks[0]); - if ( t55xxAquireAndCompareBlock0(false, 0, blocks[0], false) ) + if (t55xxAquireAndCompareBlock0(false, 0, blocks[0], false)) continue; } - + if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) res++; } - if ( res == 0 ) + if (res == 0) PrintAndLogEx(SUCCESS, "Success writing to tag"); - + return PM3_SUCCESS; } diff --git a/client/cmdlfjablotron.c b/client/cmdlfjablotron.c index 919610293..13a1d6e1f 100644 --- a/client/cmdlfjablotron.c +++ b/client/cmdlfjablotron.c @@ -197,17 +197,17 @@ static int CmdJablotronClone(const char *Cmd) { if (i == 0) { SetConfigWithBlock0(blocks[0]); - if ( t55xxAquireAndCompareBlock0(false, 0, blocks[0], false) ) + if (t55xxAquireAndCompareBlock0(false, 0, blocks[0], false)) continue; } - + if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) - res++; + res++; } - if ( res == 0 ) + if (res == 0) PrintAndLogEx(SUCCESS, "Success writing to tag"); - + return PM3_SUCCESS; } diff --git a/client/cmdlfkeri.c b/client/cmdlfkeri.c index 9f01f2f7f..49d3c2a33 100644 --- a/client/cmdlfkeri.c +++ b/client/cmdlfkeri.c @@ -186,17 +186,17 @@ static int CmdKeriClone(const char *Cmd) { if (i == 0) { SetConfigWithBlock0(blocks[0]); - if ( t55xxAquireAndCompareBlock0(false, 0, blocks[0], false) ) + if (t55xxAquireAndCompareBlock0(false, 0, blocks[0], false)) continue; } - + if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) - res++; + res++; } - if ( res == 0 ) + if (res == 0) PrintAndLogEx(SUCCESS, "Success writing to tag"); - + return PM3_SUCCESS; } From 21a7de38b840ae5b8d044380885ed3fdad5ec771 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 19 Sep 2019 10:54:34 +0200 Subject: [PATCH 0735/1854] style --- armsrc/lfops.c | 18 ++--- client/cmdlft55xx.c | 153 ++++++++++++++++++------------------ client/cmdlft55xx.h | 4 +- client/fido/additional_ca.c | 14 ++-- client/scripting.c | 4 +- 5 files changed, 96 insertions(+), 97 deletions(-) diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 57b2b75cd..ab0467c85 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -918,7 +918,7 @@ void CmdHIDsimTAGEx(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT, boo */ // special start of frame marker containing invalid Manchester bit sequences - uint8_t bits[8+8*2+84*2] = { 0, 0, 0, 1, 1, 1, 0, 1 }; + uint8_t bits[8 + 8 * 2 + 84 * 2] = { 0, 0, 0, 1, 1, 1, 0, 1 }; uint8_t bitlen = 0; uint16_t n = 8; @@ -928,9 +928,9 @@ void CmdHIDsimTAGEx(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT, boo DbpString("Tags can only have 84 bits."); return; } - bitlen = 8+8*2+84*2; + bitlen = 8 + 8 * 2 + 84 * 2; hi2 |= 0x9E00000; // 9E: long format identifier - manchesterEncodeUint32(hi2, 16+12, bits, &n); + manchesterEncodeUint32(hi2, 16 + 12, bits, &n); manchesterEncodeUint32(hi, 32, bits, &n); manchesterEncodeUint32(lo, 32, bits, &n); } else { @@ -939,7 +939,7 @@ void CmdHIDsimTAGEx(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT, boo DbpString("[!] tags can only have 44 bits. - USE lf simfsk for larger tags"); return; } - bitlen = 8+44*2; + bitlen = 8 + 44 * 2; manchesterEncodeUint32(hi, 12, bits, &n); manchesterEncodeUint32(lo, 32, bits, &n); } @@ -2038,14 +2038,14 @@ void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT) { // clone viking tag to T55xx void CopyVikingtoT55xx(uint8_t *blocks, uint8_t Q5) { - + uint32_t data[] = {T55x7_BITRATE_RF_32 | T55x7_MODULATION_MANCHESTER | (2 << T55x7_MAXBLOCK_SHIFT), 0, 0}; - if (Q5) + if (Q5) data[0] = T5555_SET_BITRATE(32) | T5555_MODULATION_MANCHESTER | 2 << T5555_MAXBLOCK_SHIFT; - + data[1] = bytes_to_num(blocks, 4); - data[2] = bytes_to_num(blocks +4, 4); - + data[2] = bytes_to_num(blocks + 4, 4); + // Program the data blocks for supplied ID and the block 0 config WriteT55xx(data, 0, 3); LED_D_OFF(); diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 88c6b3162..a41cd9f40 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -44,7 +44,7 @@ //static uint8_t bit_rates[9] = {8, 16, 32, 40, 50, 64, 100, 128, 0}; // Default configuration -t55xx_conf_block_t config = { +t55xx_conf_block_t config = { .modulation = DEMOD_ASK, .inverted = false, .offset = 0x00, @@ -52,7 +52,7 @@ t55xx_conf_block_t config = { .Q5 = false, .usepwd = false, .downlink_mode = refFixedBit - }; +}; t55xx_conf_block_t Get_t55xx_Config() { return config; @@ -86,7 +86,7 @@ static int usage_t55xx_config() { PrintAndLogEx(NORMAL, " Q5 [0/1] - Set/reset as Q5(T5555) chip instead of T55x7"); PrintAndLogEx(NORMAL, " ST [0/1] - Set/reset Sequence Terminator on"); PrintAndLogEx(NORMAL, ""); // layout is a little differnet, so seperate until a better fix - print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE); + print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx config d FSK - FSK demodulation"); @@ -331,17 +331,17 @@ static int usage_t55xx_protect() { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx protect n 01020304 - sets new password to 01020304"); - PrintAndLogEx(NORMAL, " lf t55xx protect p 11223344 - use pwd 11223344 to set newpwd to 00000000"); + PrintAndLogEx(NORMAL, " lf t55xx protect p 11223344 - use pwd 11223344 to set newpwd to 00000000"); PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } static int CmdHelp(const char *Cmd); -static bool t55xxProtect(bool lock, bool usepwd, uint8_t override, uint32_t password, uint8_t downlink_mode, uint32_t new_password ) { +static bool t55xxProtect(bool lock, bool usepwd, uint8_t override, uint32_t password, uint8_t downlink_mode, uint32_t new_password) { PrintAndLogEx(INFO, "Checking current configuration"); - + bool testmode = false; uint32_t block0 = 0; @@ -350,25 +350,25 @@ static bool t55xxProtect(bool lock, bool usepwd, uint8_t override, uint32_t pass PrintAndLogEx(WARNING, "Failed to read block0, use `p` password parameter?"); return false; } - + if (GetT55xxBlockData(&block0) == false) return false; - bool isPwdBitAlreadySet = (block0 >> (32-28) & 1); + bool isPwdBitAlreadySet = (block0 >> (32 - 28) & 1); if (isPwdBitAlreadySet) { PrintAndLogEx(INFO, "PWD bit is already set"); usepwd = true; } - // set / clear pwd bit + // set / clear pwd bit if (lock) { block0 |= 1 << 4; } else { block0 &= ~(1 << 4); } - // write new password - if ( t55xxWrite(T55x7_PWD_BLOCK, T55x7_PAGE0, usepwd, testmode, password, downlink_mode, new_password ) != PM3_SUCCESS ) { + // write new password + if (t55xxWrite(T55x7_PWD_BLOCK, T55x7_PAGE0, usepwd, testmode, password, downlink_mode, new_password) != PM3_SUCCESS) { PrintAndLogEx(ERR, "Failed to write new password"); return false; } else { @@ -377,22 +377,22 @@ static bool t55xxProtect(bool lock, bool usepwd, uint8_t override, uint32_t pass // validate new password uint32_t curr_password = (isPwdBitAlreadySet) ? new_password : password; - + if (t55xxVerifyWrite(T55x7_PWD_BLOCK, T55x7_PAGE0, usepwd, override, curr_password, downlink_mode, new_password) == false) { PrintAndLogEx(WARNING, "Failed to validate the password write. aborting."); return false; } else { PrintAndLogEx(SUCCESS, "Validated new password"); } - + // write config - if ( t55xxWrite(T55x7_CONFIGURATION_BLOCK, T55x7_PAGE0, usepwd, testmode, curr_password, downlink_mode, block0 ) != PM3_SUCCESS ) { + if (t55xxWrite(T55x7_CONFIGURATION_BLOCK, T55x7_PAGE0, usepwd, testmode, curr_password, downlink_mode, block0) != PM3_SUCCESS) { PrintAndLogEx(ERR, "Failed to write modified configuration block %08X", block0); return false; } else { PrintAndLogEx(SUCCESS, "Wrote modified configuration block"); } - + // validate new config. If all went well, card should now demand pwd, hence override = 0. override = 0; if (t55xxVerifyWrite(T55x7_CONFIGURATION_BLOCK, T55x7_PAGE0, true, override, new_password, downlink_mode, block0) == false) { @@ -409,34 +409,34 @@ bool t55xxAquireAndCompareBlock0(bool usepwd, uint32_t password, uint32_t known_ if (verbose) PrintAndLogEx(INFO, "Block0 write detected, running `detect` to see if validation is possible"); - - for ( uint8_t m = 0; m < 4; m++) { + + for (uint8_t m = 0; m < 4; m++) { if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, m) == false) { continue; } - + if (DecodeT55xxBlock() == false) { continue; } - - for( uint16_t i = 0; DemodBufferLen - 32; i++) { + + for (uint16_t i = 0; DemodBufferLen - 32; i++) { uint32_t tmp = PackBits(i, 32, DemodBuffer); - if ( tmp == known_block0 ) { + if (tmp == known_block0) { config.offset = i; config.downlink_mode = m; return true; } } } - return false; + return false; } bool t55xxAquireAndDetect(bool usepwd, uint32_t password, uint32_t known_block0, bool verbose) { if (verbose) PrintAndLogEx(INFO, "Block0 write detected, running `detect` to see if validation is possible"); - - for ( uint8_t m = 0; m < 4; m++) { + + for (uint8_t m = 0; m < 4; m++) { if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, m) == false) continue; @@ -446,14 +446,14 @@ bool t55xxAquireAndDetect(bool usepwd, uint32_t password, uint32_t known_block0, config.downlink_mode = m; return true; } - return false; + return false; } bool t55xxVerifyWrite(uint8_t block, bool page1, bool usepwd, uint8_t override, uint32_t password, uint8_t downlink_mode, uint32_t data) { uint32_t read_data = 0; - - if (downlink_mode == 0xFF) + + if (downlink_mode == 0xFF) downlink_mode = config.downlink_mode; int res = T55xxReadBlockEx(block, page1, usepwd, override, password, downlink_mode, false); @@ -462,15 +462,15 @@ bool t55xxVerifyWrite(uint8_t block, bool page1, bool usepwd, uint8_t override, if (GetT55xxBlockData(&read_data) == false) return false; - } else if ( res == PM3_EWRONGANSVER) { - - // could't decode. Lets see if this was a block 0 write and try read/detect it auto. + } else if (res == PM3_EWRONGANSVER) { + + // could't decode. Lets see if this was a block 0 write and try read/detect it auto. // this messes up with ppls config.. if (block == 0 && page1 == false) { if (t55xxAquireAndDetect(usepwd, password, data, true) == false) return false; - + return t55xxVerifyWrite(block, page1, usepwd, 2, password, config.downlink_mode, data); } } @@ -479,7 +479,7 @@ bool t55xxVerifyWrite(uint8_t block, bool page1, bool usepwd, uint8_t override, } int t55xxWrite(uint8_t block, bool page1, bool usepwd, bool testMode, uint32_t password, uint8_t downlink_mode, uint32_t data) { - + uint8_t flags; flags = (usepwd) ? 0x1 : 0; flags |= (page1) ? 0x2 : 0; @@ -534,16 +534,16 @@ void SetConfigWithBlock0Ex(uint32_t block0, uint8_t offset, bool Q5) { bool pwd = (bool)((block0 >> (32 - 28)) & 0x01); bool sst = (bool)((block0 >> (32 - 29)) & 0x01); bool inv = (bool)((block0 >> (32 - 31)) & 0x01); - + config.modulation = datamod; config.bitrate = dbr; - + // FSK1a, FSK2a - if ( datamod == DEMOD_FSK1a || datamod == DEMOD_FSK2a || datamod == DEMOD_BIa ) + if (datamod == DEMOD_FSK1a || datamod == DEMOD_FSK2a || datamod == DEMOD_BIa) config.inverted = 1; else config.inverted = inv; - + config.Q5 = Q5; config.ST = sst; config.usepwd = pwd; @@ -564,7 +564,7 @@ static int CmdT55xxSetConfig(const char *Cmd) { bool errors = false; uint32_t block0 = 0; bool gotconf = false; - + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { char tmp = tolower(param_getchar(Cmd, cmdp)); switch (tmp) { @@ -679,8 +679,8 @@ static int CmdT55xxSetConfig(const char *Cmd) { //Validations if (errors) return usage_t55xx_config(); - if ( gotconf ) { - SetConfigWithBlock0Ex(block0, config.offset, config.Q5); + if (gotconf) { + SetConfigWithBlock0Ex(block0, config.offset, config.Q5); } else { config.block0 = 0; } @@ -928,9 +928,9 @@ static int CmdT55xxDetect(const char *Cmd) { return PM3_ESOFT; if (useGB == false) { - - if ( try_all_dl_modes ) { - + + if (try_all_dl_modes) { + for (uint8_t m = downlink_mode; m < 4; m++) { if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, m) == false) continue; @@ -942,7 +942,7 @@ static int CmdT55xxDetect(const char *Cmd) { break; } } else { - + if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, downlink_mode)) { found = tryDetectModulation(downlink_mode, T55XX_PrintConfig); } @@ -951,10 +951,10 @@ static int CmdT55xxDetect(const char *Cmd) { } else { found = tryDetectModulation(downlink_mode, T55XX_PrintConfig); } - + if (found == false) PrintAndLogEx(WARNING, "Could not detect modulation automatically. Try setting it manually with " _YELLOW_("\'lf t55xx config\'")); - + return PM3_SUCCESS; } @@ -1146,13 +1146,13 @@ bool tryDetectModulationEx(uint8_t downlink_mode, bool print_config, uint32_t wa if (hits > 1) { PrintAndLogEx(SUCCESS, "Found [%d] possible matches for modulation.", hits); for (int i = 0; i < hits; ++i) { - + bool wanted = false; if (wanted_conf > 0) wanted = (wanted_conf == tests[i].block0); - + retval = testKnownConfigBlock(tests[i].block0); - if (retval || wanted ) { + if (retval || wanted) { PrintAndLogEx(NORMAL, "--[%d]--------------- << selected this", i + 1); config.modulation = tests[i].modulation; config.bitrate = tests[i].bitrate; @@ -1167,7 +1167,7 @@ bool tryDetectModulationEx(uint8_t downlink_mode, bool print_config, uint32_t wa } if (print_config) - printConfiguration(tests[i]); + printConfiguration(tests[i]); } } return retval; @@ -1327,14 +1327,14 @@ static bool testQ5(uint8_t mode, uint8_t *offset, int *fndBitRate, uint8_t clk) si += 3; //uint8_t ST = PackBits(si, 1, DemodBuffer); si += 1; if (maxBlk == 0) continue; - + //test modulation if (!testQ5Modulation(mode, modread)) continue; if (bitRate != clk) continue; - + *fndBitRate = convertQ5bitRate(bitRate); if (*fndBitRate < 0) continue; - + *offset = idx; return true; @@ -1427,7 +1427,7 @@ int printConfiguration(t55xx_conf_block_t b) { PrintAndLogEx(NORMAL, " Offset : %d", b.offset); PrintAndLogEx(NORMAL, " Seq. Term. : %s", (b.ST) ? _GREEN_("Yes") : "No"); PrintAndLogEx(NORMAL, " Block0 : 0x%08X", b.block0); - PrintAndLogEx(NORMAL, " Downlink Mode : %s", GetDownlinkModeStr (b.downlink_mode)); + PrintAndLogEx(NORMAL, " Downlink Mode : %s", GetDownlinkModeStr(b.downlink_mode)); PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } @@ -1550,19 +1550,19 @@ static int CmdT55xxWriteBlock(const char *Cmd) { PrintAndLogEx(INFO, "Writing page %d block: %02d data: 0x%08X %s", page1, block, data, (usepwd) ? pwdStr : ""); - if ( t55xxWrite(block, page1, usepwd, testMode, password, downlink_mode, data) != PM3_SUCCESS ) { + if (t55xxWrite(block, page1, usepwd, testMode, password, downlink_mode, data) != PM3_SUCCESS) { PrintAndLogEx(ERR, "Write failed"); return PM3_ESOFT; } if (validate) { bool isOK = t55xxVerifyWrite(block, page1, usepwd, 1, password, downlink_mode, data); - if (isOK) + if (isOK) PrintAndLogEx(SUCCESS, "Write OK, validation successful"); else PrintAndLogEx(WARNING, "Write could not validate the written data"); } - + return PM3_SUCCESS; } @@ -2201,23 +2201,22 @@ char *GetModulationStr(uint32_t id, bool xmode) { return buf; } -char *GetDownlinkModeStr (uint8_t downlink_mode) -{ +char *GetDownlinkModeStr(uint8_t downlink_mode) { static char buf[30]; char *retStr = buf; switch (downlink_mode) { case T55XX_DLMODE_FIXED : - snprintf(retStr, sizeof(buf),"default/fixed bit length"); + snprintf(retStr, sizeof(buf), "default/fixed bit length"); break; case T55XX_DLMODE_LLR : - snprintf(retStr, sizeof(buf),"long leading reference"); + snprintf(retStr, sizeof(buf), "long leading reference"); break; case T55XX_DLMODE_LEADING_ZERO : - snprintf(retStr, sizeof(buf),"leading zero reference"); + snprintf(retStr, sizeof(buf), "leading zero reference"); break; case T55XX_DLMODE_1OF4 : - snprintf(retStr, sizeof(buf),"1 of 4 coding reference"); + snprintf(retStr, sizeof(buf), "1 of 4 coding reference"); break; default: snprintf(retStr, sizeof(buf), _RED_("(Unknown)")); @@ -2428,7 +2427,7 @@ static int CmdT55xxWipe(const char *Cmd) { if (errors) return usage_t55xx_wipe(); - PrintAndLogEx(INFO, "\nBegin wiping %s", (Q5)? "Q5 / T5555 tag" : "T55x7 tag"); + PrintAndLogEx(INFO, "\nBegin wiping %s", (Q5) ? "Q5 / T5555 tag" : "T55x7 tag"); // default config blocks. if (gotconf == false) { @@ -2441,17 +2440,17 @@ static int CmdT55xxWipe(const char *Cmd) { snprintf(msg, sizeof(msg), "User provided configuration block %08X", block0); else snprintf(msg, sizeof(msg), "Default configation block %08X", block0); - + PrintAndLogEx(INFO, "%s", msg); - // Creating cmd string for write block :) + // Creating cmd string for write block :) snprintf(ptrData, sizeof(writeData), "b 0 "); if (usepwd) { snprintf(ptrData + strlen(writeData), sizeof(writeData) - strlen(writeData), "p %08x ", password); } snprintf(ptrData + strlen(writeData), sizeof(writeData) - strlen(writeData), "d %08X", block0); - + if (CmdT55xxWriteBlock(ptrData) != PM3_SUCCESS) PrintAndLogEx(WARNING, "Warning: error writing blk 0"); @@ -2464,7 +2463,7 @@ static int CmdT55xxWipe(const char *Cmd) { memset(writeData, 0x00, sizeof(writeData)); } - + // Check and rest t55xx downlink mode. if (config.downlink_mode != T55XX_DLMODE_FIXED) { // Detect found a different mode so card must support snprintf(ptrData, sizeof(writeData), "b 3 1 d 00000000"); @@ -2615,7 +2614,7 @@ static int CmdT55xxChkPwds(const char *Cmd) { continue; } - found = tryDetectModulation(dl_mode,T55XX_PrintConfig); + found = tryDetectModulation(dl_mode, T55XX_PrintConfig); if (found) { PrintAndLogEx(SUCCESS, "Found valid password: [ " _GREEN_("%08X") " ]", curr_password); dl_mode = 4; // Exit other downlink mode checks @@ -2733,7 +2732,7 @@ uint8_t tryOnePassword(uint32_t password, uint8_t downlink_mode) { // if (getSignalProperties()->isnoise == false) { // } else { - if (tryDetectModulation(dl_mode,T55XX_PrintConfig)) { + if (tryDetectModulation(dl_mode, T55XX_PrintConfig)) { return 1 + (dl_mode << 1); } // } @@ -2992,8 +2991,8 @@ static int CmdT55xxDetectPage1(const char *Cmd) { useGB = true; cmdp++; break; - case 'r': - //ICEMAN STRANGE + case 'r': + //ICEMAN STRANGE downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); if (downlink_mode == 4) try_all_dl_modes = true; @@ -3028,7 +3027,7 @@ static int CmdT55xxDetectPage1(const char *Cmd) { } else { found = tryDetectP1(false); } - + if (found) { PrintAndLogEx(SUCCESS, "T55xx chip found!"); T55xx_Print_DownlinkMode(found_mode); @@ -3181,8 +3180,8 @@ static int CmdT55xxProtect(const char *Cmd) { override = 1; cmdp += 2; break; - case 'r': - //ICEMAN STRANGE + case 'r': + //ICEMAN STRANGE downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); if (downlink_mode > 3) downlink_mode = 0; @@ -3198,15 +3197,15 @@ static int CmdT55xxProtect(const char *Cmd) { if (gotnewpwd == false) return usage_t55xx_protect(); - + if (errors || cmdp == 0) return usage_t55xx_protect(); // sanity check. if (SanityOfflineCheck(false) != PM3_SUCCESS) return PM3_ESOFT; - + // lock - if ( t55xxProtect(true, usepwd, override, password, downlink_mode, new_password) == false ) { + if (t55xxProtect(true, usepwd, override, password, downlink_mode, new_password) == false) { PrintAndLogEx(WARNING, "Command failed. Did you run `lf t55xx detect` before?"); return PM3_ESOFT; } diff --git a/client/cmdlft55xx.h b/client/cmdlft55xx.h index d4e217372..1b70ca9ca 100644 --- a/client/cmdlft55xx.h +++ b/client/cmdlft55xx.h @@ -141,14 +141,14 @@ char *GetQ5ModulationStr(uint32_t id); char *GetModulationStr(uint32_t id, bool xmode); char *GetModelStrFromCID(uint32_t cid); char *GetSelectedModulationStr(uint8_t id); -char *GetDownlinkModeStr (uint8_t dlmode); +char *GetDownlinkModeStr(uint8_t dlmode); void printT5xxHeader(uint8_t page); void printT55xxBlock(uint8_t blockNum); int printConfiguration(t55xx_conf_block_t b); bool t55xxAquireAndCompareBlock0(bool usepwd, uint32_t password, uint32_t known_block0, bool verbose); bool t55xxAquireAndDetect(bool usepwd, uint32_t password, uint32_t known_block0, bool verbose); -bool t55xxVerifyWrite( uint8_t block, bool page1, bool usepwd, uint8_t override, uint32_t password, uint8_t downlink_mode, uint32_t data); +bool t55xxVerifyWrite(uint8_t block, bool page1, bool usepwd, uint8_t override, uint32_t password, uint8_t downlink_mode, uint32_t data); int T55xxReadBlock(uint8_t block, bool page1, bool usepwd, uint8_t override, uint32_t password, uint8_t downlink_mode); int T55xxReadBlockEx(uint8_t block, bool page1, bool usepwd, uint8_t override, uint32_t password, uint8_t downlink_mode, bool verbose); diff --git a/client/fido/additional_ca.c b/client/fido/additional_ca.c index 3c10a9de9..1f383c741 100644 --- a/client/fido/additional_ca.c +++ b/client/fido/additional_ca.c @@ -89,7 +89,7 @@ "A1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAgNHADBEAiAwfPqgIWIUB+QBBaVGsdHy\r\n" \ "0s5RMxlkzpSX/zSyTZmUpQIgB2wJ6nZRM8oX/nA43Rh6SJovM2XwCCH//+LirBAb\r\n" \ "B0M=\r\n" \ - "-----END CERTIFICATE-----\r\n" + "-----END CERTIFICATE-----\r\n" // FEITIAN FIDO2 #define FEITIAN_FIDO2_CA \ @@ -104,7 +104,7 @@ "FEu9hyYRrRyJzwRYvnDSCIxrFiO3MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/\r\n" \ "BAQDAgEGMAoGCCqGSM49BAMCA0gAMEUCIDHSb2mbNDAUNXvpPU0oWKeNye0fQ2l9\r\n" \ "D01AR2+sLZdhAiEAo3wz684IFMVsCCRmuJqxH6FQRESNqezuo1E+KkGxWuM=\r\n" \ - "-----END CERTIFICATE-----\r\n" + "-----END CERTIFICATE-----\r\n" // https://hypersecu.com/support/downloads // HyperFIDO U2F Security Key Attestation CA @@ -135,9 +135,9 @@ "FPFypmsIMAwGA1UdEwQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMAoGCCqGSM49BAMC\r\n" \ "A0kAMEYCIQCG2/ppMGt7pkcRie5YIohS3uDPIrmiRcTjqDclKVWg0gIhANcPNDZH\r\n" \ "E2/zZ+uB5ThG9OZus+xSb4knkrbAyXKX2zm/\r\n" \ - "-----END CERTIFICATE-----\r\n" - -// NXP + "-----END CERTIFICATE-----\r\n" + +// NXP // https://fido-mds-parser.appspot.com/?url=https://mds.fidoalliance.org/metadata/JKP5CiDehdMMPwtG5i7to5 #define NXP_U2F_CA \ "-----BEGIN CERTIFICATE-----\r\n" \ @@ -151,8 +151,8 @@ "AJlr23jig2LxRM1PpgMAQXnZJy/HnkRB9O8KD0o2oK/mAiBG5EK1S3yVHdkkVGTJ\r\n" \ "Q12ffuK8Op7Nx89cszCr0WyIhQ==\r\n" \ "-----END CERTIFICATE-----\r\n" - + /* Concatenation of all additional CA certificates in PEM format if available */ const char additional_ca_pem[] = GLOBALSIGN_CA YUBICO_CA SOLOKEY_CA \ - FEITIAN_U2F_CA FEITIAN_FIDO2_CA HYPERFIDO_U2F_1_CA HYPERFIDO_U2F_2_CA NXP_U2F_CA; + FEITIAN_U2F_CA FEITIAN_FIDO2_CA HYPERFIDO_U2F_1_CA HYPERFIDO_U2F_2_CA NXP_U2F_CA; const size_t additional_ca_pem_len = sizeof(additional_ca_pem); diff --git a/client/scripting.c b/client/scripting.c index 586ab0940..8054ff9b4 100644 --- a/client/scripting.c +++ b/client/scripting.c @@ -930,7 +930,7 @@ static int l_T55xx_readblock(lua_State *L) { return returnToLuaWithError(L, "Failed to read config block"); } - if (!tryDetectModulation(0,true)) { // Default to prev. behaviour (default dl mode and print config) + if (!tryDetectModulation(0, true)) { // Default to prev. behaviour (default dl mode and print config) PrintAndLogEx(NORMAL, "Safety Check: Could not detect if PWD bit is set in config block. Exits."); return 0; } else { @@ -1006,7 +1006,7 @@ static int l_T55xx_detect(lua_State *L) { } } - isok = tryDetectModulation(0,true); // Default to prev. behaviour (default dl mode and print config) + isok = tryDetectModulation(0, true); // Default to prev. behaviour (default dl mode and print config) if (isok == false) { return returnToLuaWithError(L, "Could not detect modulation automatically. Try setting it manually with \'lf t55xx config\'"); } From a604f641b3c1767081238d84cbb81b863e972e4c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 19 Sep 2019 10:55:34 +0200 Subject: [PATCH 0736/1854] style --- client/cmdlfpac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdlfpac.c b/client/cmdlfpac.c index 6ea0af7d6..175d56ad4 100644 --- a/client/cmdlfpac.c +++ b/client/cmdlfpac.c @@ -63,7 +63,7 @@ static int CmdPacClone(const char *Cmd) { } static int CmdPacSim(const char *Cmd) { - + // NRZ sim. PrintAndLogEx(INFO, " To be implemented, feel free to contribute!"); return PM3_SUCCESS; From aa2f80795d427d8ff06f2cb21dfb8ed88a1e36c9 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 19 Sep 2019 12:13:39 +0200 Subject: [PATCH 0737/1854] mem spibaud uses NG. And a simplification of tuning --- armsrc/appmain.c | 42 ++++++++++++++++++++++-------------------- client/cmdflashmem.c | 2 +- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 257a4a5b6..0ac021400 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -208,13 +208,13 @@ void MeasureAntennaTuning(void) { uint16_t MeasureAntennaTuningHfData(void) { uint16_t volt = 0; // in mV - volt = (MAX_ADC_HF_VOLTAGE * AvgAdc(ADC_CHAN_HF)) >> 10; + uint16_t avg = AvgAdc(ADC_CHAN_HF); + volt = (MAX_ADC_HF_VOLTAGE * avg) >> 10; bool use_high = (volt > MAX_ADC_HF_VOLTAGE - 300); - if (!use_high) { - volt = (MAX_ADC_HF_VOLTAGE * AvgAdc(ADC_CHAN_HF)) >> 10; - } else { + if (use_high) { volt = (MAX_ADC_HF_VOLTAGE_RDV40 * AvgAdc(ADC_CHAN_HF_RDV40)) >> 10; +// volt = (MAX_ADC_HF_VOLTAGE * AvgAdc(ADC_CHAN_HF)) >> 10; } return volt; } @@ -787,7 +787,7 @@ static void PacketReceived(PacketCommandNG *packet) { uint32_t password; uint8_t flags; } PACKED; - struct p *payload = (struct p *) packet->data.asBytes; + struct p *payload = (struct p *) packet->data.asBytes; T55xxWakeUp(payload->password, payload->flags); break; } @@ -846,7 +846,7 @@ static void PacketReceived(PacketCommandNG *packet) { bool Q5; uint8_t blocks[8]; } PACKED; - struct p *payload = (struct p*)packet->data.asBytes; + struct p *payload = (struct p *)packet->data.asBytes; CopyVikingtoT55xx(payload->blocks, payload->Q5); break; } @@ -1236,22 +1236,22 @@ static void PacketReceived(PacketCommandNG *packet) { break; } case CMD_HF_ICLASS_READBL: { -/* - struct p { - uint8_t blockno; - } PACKED; - struct p *payload = (struct p *)packet->data.asBytes; - */ - iClass_ReadBlk( packet->data.asBytes[0] ); + /* + struct p { + uint8_t blockno; + } PACKED; + struct p *payload = (struct p *)packet->data.asBytes; + */ + iClass_ReadBlk(packet->data.asBytes[0]); break; } case CMD_HF_ICLASS_AUTH: { //check -/* - struct p { - uint8_t mac[4]; - } PACKED; - struct p *payload = (struct p *)packet->data.asBytes; -*/ + /* + struct p { + uint8_t mac[4]; + } PACKED; + struct p *payload = (struct p *)packet->data.asBytes; + */ iClass_Authentication(packet->data.asBytes); break; } @@ -1665,7 +1665,9 @@ static void PacketReceived(PacketCommandNG *packet) { break; } case CMD_FLASHMEM_SET_SPIBAUDRATE: { - FlashmemSetSpiBaudrate(packet->oldarg[0]); + if (packet->length != sizeof(uint32_t)) + break; + FlashmemSetSpiBaudrate(packet->data.asDwords[0]); break; } case CMD_FLASHMEM_WRITE: { diff --git a/client/cmdflashmem.c b/client/cmdflashmem.c index ce5b37f44..be59dc4f7 100644 --- a/client/cmdflashmem.c +++ b/client/cmdflashmem.c @@ -117,7 +117,7 @@ static int CmdFlashmemSpiBaudrate(const char *Cmd) { usage_flashmem_spibaud(); return PM3_EINVARG; } - SendCommandMIX(CMD_FLASHMEM_SET_SPIBAUDRATE, baudrate, 0, 0, NULL, 0); + SendCommandNG(CMD_FLASHMEM_SET_SPIBAUDRATE, (uint8_t*)&baudrate, sizeof(uint32_t)); return PM3_SUCCESS; } From a3161ae9a2ca58e7debcf08f0b8cada09429f147 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 19 Sep 2019 13:12:48 +0200 Subject: [PATCH 0738/1854] fix 'lf em 4x50_read - now checks if have enough data in Graphbuffer --- client/cmdlfem4x.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c index b7948b14c..e7b1c2b06 100644 --- a/client/cmdlfem4x.c +++ b/client/cmdlfem4x.c @@ -821,6 +821,12 @@ int EM4x50Read(const char *Cmd, bool verbose) { uint8_t bits[MAX_GRAPH_TRACE_LEN] = {0}; size_t size = getFromGraphBuf(bits); + + if (size < 4000) { + if (verbose || g_debugMode) PrintAndLogEx(ERR, "Error: EM4x50 - Too little data in Graphbuffer"); + return PM3_ESOFT; + } + computeSignalProperties(bits, size); signal_t *sp = getSignalProperties(); From e5ffcfd51359a84b65c3beb4ac9b48f3db3efa52 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 19 Sep 2019 13:46:38 +0200 Subject: [PATCH 0739/1854] chg: 'lf hid brute' - use new wiegand formats. see helptext for more details --- client/cmdlfhid.c | 346 +++++++++++----------------------------------- 1 file changed, 77 insertions(+), 269 deletions(-) diff --git a/client/cmdlfhid.c b/client/cmdlfhid.c index 2059066dc..20baa6449 100644 --- a/client/cmdlfhid.c +++ b/client/cmdlfhid.c @@ -35,40 +35,24 @@ #include "cmdlf.h" // lf_read #include "util_posix.h" #include "lfdemod.h" +#include "wiegand_formats.h" #ifndef BITS # define BITS 96 #endif static int CmdHelp(const char *Cmd); -/* -static int usage_lf_hid_read(void) { + +static int usage_lf_hid_watch(void) { PrintAndLogEx(NORMAL, "Enables HID compatible reader mode printing details."); PrintAndLogEx(NORMAL, "By default, values are printed and logged until the button is pressed or another USB command is issued."); - PrintAndLogEx(NORMAL, "If the [1] option is provided, reader mode is exited after reading a single HID card."); PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Usage: lf hid read [h] [1]"); + PrintAndLogEx(NORMAL, "Usage: lf hid watch [h]"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h : This help"); - PrintAndLogEx(NORMAL, " 1 : (optional) stop after reading a single card"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " lf hid read"); - PrintAndLogEx(NORMAL, " lf hid read 1"); - return PM3_SUCCESS; -} -*/ -static int usage_lf_hid_wiegand(void) { - PrintAndLogEx(NORMAL, "This command converts facility code/card number to Wiegand code"); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Usage: lf hid wiegand [h] [OEM] [FC] [CN]"); - PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " h - This help"); - PrintAndLogEx(NORMAL, " OEM - OEM number / site code"); - PrintAndLogEx(NORMAL, " FC - facility code"); - PrintAndLogEx(NORMAL, " CN - card number"); - PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " lf hid wiegand 0 101 2001"); + PrintAndLogEx(NORMAL, " lf hid watch"); return PM3_SUCCESS; } static int usage_lf_hid_sim(void) { @@ -101,19 +85,21 @@ static int usage_lf_hid_brute(void) { PrintAndLogEx(NORMAL, "This is a attack against reader. if cardnumber is given, it starts with it and goes up / down one step"); PrintAndLogEx(NORMAL, "if cardnumber is not given, it starts with 1 and goes up to 65535"); PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Usage: lf hid brute [h] [v] a f c d "); + PrintAndLogEx(NORMAL, "Usage: lf hid brute [h] [v] w [ (decimal)>] {...}"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h : This help"); - PrintAndLogEx(NORMAL, " a : 26|33|34|35|37|40|44|84"); - PrintAndLogEx(NORMAL, " f : 8-bit value HID facility code"); - PrintAndLogEx(NORMAL, " c : (optional) cardnumber to start with, max 65535"); + PrintAndLogEx(NORMAL, " w : see `wiegand list` for available formats"); + PrintAndLogEx(NORMAL, " f : facility code"); + PrintAndLogEx(NORMAL, " c : card number to start with"); + PrintAndLogEx(NORMAL, " i : issue level"); + PrintAndLogEx(NORMAL, " o : OEM code"); PrintAndLogEx(NORMAL, " d : delay betweens attempts in ms. Default 1000ms"); PrintAndLogEx(NORMAL, " v : verbose logging, show all tries"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " lf hid brute a 26 f 224"); - PrintAndLogEx(NORMAL, " lf hid brute a 26 f 21 d 2000"); - PrintAndLogEx(NORMAL, " lf hid brute v a 26 f 21 c 200 d 2000"); + PrintAndLogEx(NORMAL, " lf hid brute w H10301 f 224"); + PrintAndLogEx(NORMAL, " lf hid brute w H10301 f 21 d 2000"); + PrintAndLogEx(NORMAL, " lf hid brute v w H10301 f 21 c 200 d 2000"); return PM3_SUCCESS; } @@ -128,17 +114,33 @@ static int sendPing(void) { return PM3_ETIMEOUT; return PM3_SUCCESS; } -static int sendTry(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint32_t delay, uint8_t *bits, bool verbose) { +static int sendTry(uint8_t format_idx, wiegand_card_t *card, uint32_t delay, bool verbose) { + + wiegand_message_t packed; + memset(&packed, 0, sizeof(wiegand_message_t)); + + if (HIDPack(format_idx, card, &packed) == false) { + PrintAndLogEx(WARNING, "The card data could not be encoded in the selected format."); + return PM3_ESOFT; + } - // this should be optional. if (verbose) - PrintAndLogEx(INFO, "Trying FC: %u; CN: %u", fc, cn); + PrintAndLogEx(INFO, "Trying FC: %u; CN: %u; Issue level: %u; OEM: %u", card->FacilityCode, card->CardNumber, card->IssueLevel, card->OEM); - calcWiegand(fmtlen, fc, cn, bits, 0); + lf_hidsim_t payload; + payload.hi2 = packed.Top; + payload.hi = packed.Mid; + payload.lo = packed.Bot; clearCommandBuffer(); - SendCommandMIX(CMD_LF_HID_SIMULATE, bytebits_to_byte(bits, 32), bytebits_to_byte(bits + 32, 32), 0, NULL, 0); + SendCommandNG(CMD_LF_HID_SIMULATE, (uint8_t *)&payload, sizeof(payload)); +/* + PacketResponseNG resp; + WaitForResponse(CMD_LF_HID_SIMULATE, &resp); + if (resp.status == PM3_EOPABORTED) + return resp.status; +*/ msleep(delay); return sendPing(); } @@ -258,18 +260,18 @@ static int CmdHIDRead(const char *Cmd) { lf_read(true, 12000); return CmdHIDDemod(Cmd); } -/* + // this read loops on device side. // uses the demod in lfops.c -static int CmdHIDRead_device(const char *Cmd) { +static int CmdHIDWatch(const char *Cmd) { - if (Cmd[0] == 'h' || Cmd[0] == 'H') return usage_lf_hid_read(); - uint8_t findone = (Cmd[0] == '1') ? 1 : 0; + uint8_t ctmp = tolower(param_getchar(Cmd, 0)); + if ( strlen(Cmd) == 0 || ctmp == 'h') return usage_lf_hid_watch(); clearCommandBuffer(); - SendCommandMIX(CMD_LF_HID_DEMOD, findone, 0, 0, NULL, 0); + SendCommandMIX(CMD_LF_HID_DEMOD, 0, 0, 0, NULL, 0); return PM3_SUCCESS; } -*/ + static int CmdHIDSim(const char *Cmd) { lf_hidsim_t payload; payload.longFMT = 0; @@ -319,8 +321,8 @@ static int CmdHIDClone(const char *Cmd) { uint32_t hi2 = 0, hi = 0, lo = 0; uint32_t n = 0, i = 0; - uint8_t ctmp = param_getchar(Cmd, 0); - if (strlen(Cmd) == 0 || ctmp == 'H' || ctmp == 'h') return usage_lf_hid_clone(); + uint8_t ctmp = tolower(param_getchar(Cmd, 0)); + if (strlen(Cmd) == 0 || ctmp == 'h') return usage_lf_hid_clone(); uint8_t longid[1] = {0}; if (strchr(Cmd, 'l') != 0) { i++; @@ -348,202 +350,9 @@ static int CmdHIDClone(const char *Cmd) { } /* -// struct to handle wiegand -typedef struct { - uint8_t FormatLen; - uint8_t SiteCode; - uint8_t FacilityCode; - uint8_t CardNumber; - uint8_t *Wiegand; - size_t Wiegand_n; -} wiegand_t; -*/ - -static void addHIDMarker(uint8_t fmtlen, uint8_t *out) { - // temp array - uint8_t arr[BITS]; - memset(arr, 0, BITS); - - // copy inpu - uint8_t pos = sizeof(arr) - fmtlen; - memcpy(arr + pos, out, fmtlen); - - switch (fmtlen) { - case 26: { - // start sentinel, BITS-bit 27 = 1 - arr[BITS - 27] = 1; - // fmt smaller than 37 used, bit37 = 1 - arr[BITS - 38] = 1; - memcpy(out, arr, BITS); - break; - } - case 34: - // start sentinel, BITS-bit 27 = 1 - arr[BITS - 35] = 1; - - // fmt smaller than 37 used, bit37 = 1 - arr[BITS - 38] = 1; - memcpy(out, arr, BITS); - break; - default: - break; - } -} - -// static void getParity34(uint32_t *hi, uint32_t *lo){ -// uint32_t result = 0; -// int i; - -// // even parity -// for (i = 7;i >= 0;i--) -// result ^= (*hi >> i) & i; -// for (i = 31;i >= 24;i--) -// result ^= (*lo >> i) & 1; - -// *hi |= result << 2; - -// // odd parity bit -// result = 0; -// for (i = 23;i >= 1;i--) -// result ^= (*lo >> i) & 1; - -// *lo |= !result; -// } -// static void getParity37H(uint32_t *hi, uint32_t *lo){ -// uint32_t result = 0; -// int i; - -// // even parity -// for (i = 4;i >= 0;i--) -// result ^= (*hi >> i) & 1; -// for (i = 31;i >= 20;i--) -// result ^= (*lo >> i) & 1; -// *hi |= result << 4; - -// // odd parity -// result = 0; -// for (i = 19;i >= 1;i--) -// result ^= (*lo >> i) & 1; -// *lo |= result; -// } - -//static void calc26(uint16_t fc, uint32_t cardno, uint8_t *out){ -static void calc26(uint16_t fc, uint32_t cardno, uint8_t *out) { - uint8_t wiegand[24]; - num_to_bytebits(fc, 8, wiegand); - num_to_bytebits(cardno, 16, wiegand + 8); - wiegand_add_parity(out, wiegand, sizeof(wiegand)); -} -// static void calc33(uint16_t fc, uint32_t cardno, uint8_t *out){ -// } -static void calc34(uint16_t fc, uint32_t cardno, uint8_t *out) { - uint8_t wiegand[32]; - num_to_bytebits(fc, 16, wiegand); - num_to_bytebits(cardno, 16, wiegand + 16); - wiegand_add_parity(out, wiegand, sizeof(wiegand)); -} -// static void calc35(uint16_t fc, uint32_t cardno, uint8_t *out){ -// *lo = ((cardno & 0xFFFFF) << 1) | fc << 21; -// *hi = (1 << 5) | ((fc >> 11) & 1); -// } -static void calc36(uint8_t oem, uint16_t fc, uint32_t cardno, uint8_t *out) { - // FC 1 - 16 - 16 bit - // cardno 17 - 33 - 16 bit - // oem 34 - 35 - 2 bit - // Odd Parity 0th bit 1-18 - // Even Parity 36th bit 19-35 - uint8_t wiegand[34]; - num_to_bytebits(fc, 16, wiegand); - num_to_bytebits(cardno & 0xFFFF, 16, wiegand + 16); - num_to_bytebits(oem, 2, wiegand + 32); - wiegand_add_parity_swapped(out, wiegand, sizeof(wiegand)); -} -static void calc37S(uint16_t fc, uint32_t cardno, uint8_t *out) { - // FC 2 - 17 - 16 bit - // cardno 18 - 36 - 19 bit - // Even P1 1 - 19 - // Odd P37 19 - 36 - uint8_t wiegand[35]; - num_to_bytebits(fc, 16, wiegand); - num_to_bytebits(cardno, 19, wiegand + 16); - wiegand_add_parity(out, wiegand, sizeof(wiegand)); -} -static void calc37H(uint64_t cardno, uint8_t *out) { - // SC NONE - // cardno 1-35 34 bits - // Even Parity 0th bit 1-18 - // Odd Parity 36th bit 19-35 - uint8_t wiegand[37]; - num_to_bytebits((uint32_t)(cardno >> 32), 2, wiegand); - num_to_bytebits((uint32_t)(cardno >> 0), 32, wiegand + 2); - wiegand_add_parity(out, wiegand, sizeof(wiegand)); - - PrintAndLogEx(NORMAL, "%x %x\n", (uint32_t)(cardno >> 32), (uint32_t)cardno); -} -// static void calc40(uint64_t cardno, uint8_t *out){ -// cardno = (cardno & 0xFFFFFFFFFF); -// *lo = ((cardno & 0xFFFFFFFF) << 1 ); -// *hi = (cardno >> 31); -// } - -void calcWiegand(uint8_t fmtlen, uint16_t fc, uint64_t cardno, uint8_t *bits, uint8_t oem) { - uint32_t cn32 = (cardno & 0xFFFFFFFF); - switch (fmtlen) { - case 26: - calc26(fc, cn32, bits); - break; - // case 33 : calc33(fc, cn32, bits); break; - case 34: - calc34(fc, cn32, bits); - break; - // case 35 : calc35(fc, cn32, bits); break; - case 36: - calc36(oem, fc, cn32, bits); - break; - case 37: - calc37S(fc, cn32, bits); - break; - case 38: - calc37H(cardno, bits); - break; - // case 40 : calc40(cardno, bits); break; - // case 44 : { break; } - // case 84 : { break; } - default: - break; - } -} - -static int CmdHIDWiegand(const char *Cmd) { - uint32_t oem = 0, fc = 0; - uint64_t cardnum = 0; - uint8_t bits[BITS] = {0}; - uint8_t *bs = bits; - - uint8_t ctmp = tolower(param_getchar(Cmd, 0)); - if (strlen(Cmd) < 3 || ctmp == 'h') return usage_lf_hid_wiegand(); - - oem = param_get8(Cmd, 0); - fc = param_get32ex(Cmd, 1, 0, 10); - cardnum = param_get64ex(Cmd, 2, 0, 10); - - uint8_t fmtlen[] = {26, 33, 34, 35, 36, 37, 38, 40}; - PrintAndLogEx(NORMAL, "HID | OEM | FC | CN | Wiegand | HID Formatted"); PrintAndLogEx(NORMAL, "----+-----+------+---------+-----------+--------------------"); - for (uint8_t i = 0; i < ARRAYLEN(fmtlen); i++) { - memset(bits, 0x00, sizeof(bits)); - calcWiegand(fmtlen[i], fc, cardnum, bs, oem); - PrintAndLogEx(NORMAL, "ice:: %s \n", sprint_bin(bs, fmtlen[i])); - uint64_t wiegand = (uint64_t)bytebits_to_byte(bs, 32) << 32 | bytebits_to_byte(bs + 32, 32); - - addHIDMarker(fmtlen[i], bs); - PrintAndLogEx(NORMAL, "ice:: %s\n", sprint_bin(bs, BITS)); - uint64_t blocks = (uint64_t)bytebits_to_byte(bs + 32, 32) << 32 | bytebits_to_byte(bs + 64, 32); - uint8_t shifts = 64 - fmtlen[i]; - wiegand >>= shifts; - - PrintAndLogEx(NORMAL, " %u | %03u | %03u | %" PRIu64 " | %" PRIX64 " | %" PRIX64, + PrintAndLogEx(NORMAL, " %u | %03u | %03u | %" PRIu64 " | %" PRIX64 " | %" PRIX64, fmtlen[i], oem, fc, @@ -553,26 +362,33 @@ static int CmdHIDWiegand(const char *Cmd) { ); } PrintAndLogEx(NORMAL, "----+-----+-----+-------+-----------+--------------------"); - return PM3_SUCCESS; -} +*/ static int CmdHIDBrute(const char *Cmd) { bool errors = false, verbose = false; - uint32_t fc = 0, cn = 0, delay = 1000; - uint8_t fmtlen = 0; - uint8_t bits[96]; - memset(bits, 0, sizeof(bits)); + uint32_t delay = 1000; uint8_t cmdp = 0; + int format_idx = -1; + char format[16] = {0}; + wiegand_card_t data; + memset(&data, 0, sizeof(wiegand_card_t)); while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { case 'h': return usage_lf_hid_brute(); - case 'f': - fc = param_get32ex(Cmd, cmdp + 1, 0, 10); - if (!fc) + case 'w': + param_getstr(Cmd, cmdp + 1, format, sizeof(format)); + format_idx = HIDFindCardFormat(format); + if (format_idx == -1) { + PrintAndLogEx(WARNING, "Unknown format: %s", format); errors = true; + } + cmdp += 2; + break; + case 'c': + data.CardNumber = param_get32ex(Cmd, cmdp + 1, 0, 10); cmdp += 2; break; case 'd': @@ -580,24 +396,17 @@ static int CmdHIDBrute(const char *Cmd) { delay = param_get32ex(Cmd, cmdp + 1, 1000, 10); cmdp += 2; break; - case 'c': - cn = param_get32ex(Cmd, cmdp + 1, 0, 10); - // truncate cardnumber. - cn &= 0xFFFF; + case 'f': + data.FacilityCode = param_get32ex(Cmd, cmdp + 1, 0, 10); cmdp += 2; break; - case 'a': - fmtlen = param_get8(Cmd, cmdp + 1); + case 'i': + data.IssueLevel = param_get32ex(Cmd, cmdp + 1, 0, 10); + cmdp += 2; + break; + case 'o': + data.OEM = param_get32ex(Cmd, cmdp + 1, 0, 10); cmdp += 2; - bool is_ftm_ok = false; - uint8_t ftms[] = {26, 33, 34, 35, 37}; - for (uint8_t i = 0; i < ARRAYLEN(ftms); i++) { - if (ftms[i] == fmtlen) { - is_ftm_ok = true; - } - } - // negated - errors = !is_ftm_ok; break; case 'v': verbose = true; @@ -609,15 +418,11 @@ static int CmdHIDBrute(const char *Cmd) { break; } } - if (fc == 0) errors = true; if (errors) return usage_lf_hid_brute(); PrintAndLogEx(INFO, "Brute-forcing HID reader"); PrintAndLogEx(INFO, "Press pm3-button to abort simulation or run another command"); - uint16_t up = cn; - uint16_t down = cn; - // main loop for (;;) { @@ -632,13 +437,16 @@ static int CmdHIDBrute(const char *Cmd) { } // Do one up - if (up < 0xFFFF) - if (sendTry(fmtlen, fc, up++, delay, bits, verbose) != PM3_SUCCESS) return PM3_ESOFT; + if (data.CardNumber < 0xFFFF) { + data.CardNumber++; + if (sendTry(format_idx, &data, delay, verbose) != PM3_SUCCESS) return PM3_ESOFT; + } // Do one down (if cardnumber is given) - if (cn > 1) - if (down > 1) - if (sendTry(fmtlen, fc, --down, delay, bits, verbose) != PM3_SUCCESS) return PM3_ESOFT; + if (data.CardNumber > 1) { + data.CardNumber--; + if (sendTry(format_idx, &data, delay, verbose) != PM3_SUCCESS) return PM3_ESOFT; + } } return PM3_SUCCESS; } @@ -649,8 +457,8 @@ static command_t CommandTable[] = { {"read", CmdHIDRead, IfPm3Lf, "attempt to read and extract tag data"}, {"clone", CmdHIDClone, IfPm3Lf, "clone HID to T55x7"}, {"sim", CmdHIDSim, IfPm3Lf, "simulate HID tag"}, - {"wiegand", CmdHIDWiegand, AlwaysAvailable, "convert facility code/card number to Wiegand code"}, {"brute", CmdHIDBrute, IfPm3Lf, "bruteforce card number against reader"}, + {"watch", CmdHIDWatch, IfPm3Lf, "continuously watch for cards. Reader mode"}, {NULL, NULL, NULL, NULL} }; From 238e41c6833d5a8e51babdc11f3138ed29985b13 Mon Sep 17 00:00:00 2001 From: Iceman Date: Fri, 20 Sep 2019 13:19:19 +0200 Subject: [PATCH 0740/1854] Update cheatsheet.md --- doc/cheatsheet.md | 76 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 52 insertions(+), 24 deletions(-) diff --git a/doc/cheatsheet.md b/doc/cheatsheet.md index 4a61ae7d2..3fc446ec8 100644 --- a/doc/cheatsheet.md +++ b/doc/cheatsheet.md @@ -9,7 +9,7 @@ |[Sim Module](#Sim-Module)|[Hitag](#Hitag)|| |[Lua Scripts](#Lua-Scripts)||| |[Smart Card](#Smart-Card)||| - +|[Wiegand convertion](#Wiegand-manipulation)||| ## Generic ^[Top](#top) @@ -62,7 +62,7 @@ Options --- k : *Access Key as 16 hex symbols or 1 hex to select key from memory -pm3 --> hf iclass dump k AFA785A7DAB33378 +m3 --> hf iclass dump k 0 ``` Read iClass Block @@ -72,7 +72,7 @@ Options b : The block number as 2 hex symbols k : Access Key as 16 hex symbols or 1 hex to select key from memory -pm3 --> hf iclass readblk b 7 k AFA785A7DAB33378 +pm3 --> hf iclass rdbl b 7 k 0 ``` Write to iClass Block @@ -83,7 +83,7 @@ b : The block number as 2 hex symbols d : Set the Data to write as 16 hex symbols k : Access Key as 16 hex symbols or 1 hex to select key from memory -pm3 --> hf iclass writeblk b 07 d 6ce099fe7e614fd0 k AFA785A7DAB33378 +pm3 --> hf iclass wrbl b 07 d 6ce099fe7e614fd0 k 0 ``` Print keystore @@ -107,7 +107,7 @@ pm3 --> hf iclass managekeys n 0 k AFA785A7DAB33378 Encrypt iClass Block ``` -pm3 --> hf iclass encryptblk 0000000f2aa3dba8 +pm3 --> hf iclass encrypt 0000000f2aa3dba8 ``` Load iClass dump into memory for simulation @@ -116,7 +116,7 @@ Options --- f : load iclass tag-dump filename -pm3 --> hf iclass eload f iclass_tagdump-db883702f8ff12e0.bin +pm3 --> hf iclass eload f hf-iclass-db883702f8ff12e0.bin ``` Simulate iClass @@ -124,6 +124,7 @@ Simulate iClass Options --- 0 simulate the given CSN +2 Runs part 1 of LOCLASS attack 1 simulate default CSN 3 Full simulation using emulator memory (see 'hf iclass eload') @@ -132,14 +133,14 @@ pm3 --> hf iclass sim 3 Clone iClass Legacy Sequence ``` -pm3 --> hf iclass readblk b 7 k AFA785A7DAB33378 -pm3 --> hf iclass writeblk b 07 d 6ce099fe7e614fd0 k AFA785A7DAB33378 +pm3 --> hf iclass rdbl b 7 k 0 +pm3 --> hf iclass wrbl b 7 d 6ce099fe7e614fd0 k 0 ``` Simulate iClass Sequence ``` -pm3 --> hf iclass dump k AFA785A7DAB33378 -pm3 --> hf iclass eload f iclass_tagdump-db883702f8ff12e0.bin +pm3 --> hf iclass dump k 0 +pm3 --> hf iclass eload f hf-iclass-db883702f8ff12e0.bin pm3 --> hf iclass sim 3 ``` @@ -224,6 +225,14 @@ Options pm3 --> hf mf wrbl 0 A FFFFFFFFFFFF d3a2859f6b880400c801002000000016 ``` +Run autopwn +``` +Options +--- + +pm3 --> hf mf autopwn +``` + Run Hardnested attack ``` Options @@ -241,8 +250,8 @@ Options [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K, u = UL -pm3 --> hf mf eload 353C2AA6 -pm3 --> hf mf eload 1 353C2AA6 +pm3 --> hf mf eload hf-mf-353C2AA6 +pm3 --> hf mf eload 1 hf-mf-353C2AA6 ``` Simulate Mifare @@ -268,6 +277,37 @@ pm3 --> hf mf dump pm3 --> hf mf restore 1 u 4A6CE843 k hf-mf-A29558E4-key.bin f hf-mf-A29558E4-data.bin ``` +## Wiegand manipulation +^[Top](#top) + +List all available weigand formats in client +``` +pm3 --> wiegand list +``` + +Convert Site & Facility code to Wiegand raw hex +``` +Options +--- +w o f c i +w : wiegand format to use +o : OEM number / site code +f : facility code +c : card number +i : issue level + +pm3 --> wiegand encode 0 56 150 +``` + +Convert Site & Facility code from Wiegand raw hex to numbers +``` +Options +--- +p : ignore parity errors + +pm3 --> wiegand decode 2006f623ae +``` + ## HID Prox ^[Top](#top) @@ -281,18 +321,6 @@ Demodulate HID Prox card pm3 --> lf hid demod ``` -Convert Site & Facility code to Wiegand -``` -Options ---- - -OEM : OEM number / site code -FC : facility code -CN : card number - -pm3 --> lf hid wiegand 0 56 150 -``` - Simulate Prox card ``` From 93915858eacf3bd8b31f87bab9180752d6751f5c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 21 Sep 2019 08:47:12 +0200 Subject: [PATCH 0741/1854] fix `data load` now not crashing client when entering a folder path without filename --- client/cmddata.c | 2 ++ client/fileutils.c | 8 +++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/client/cmddata.c b/client/cmddata.c index 792cf6a96..d1df2be65 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -1676,6 +1676,8 @@ static int CmdLoad(const char *Cmd) { int len = 0; len = strlen(Cmd); + if (len == 0) return PM3_EFILE; + if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE; memcpy(filename, Cmd, len); diff --git a/client/fileutils.c b/client/fileutils.c index 23553d15c..717787293 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -1014,8 +1014,14 @@ out: int searchFile(char **foundpath, const char *pm3dir, const char *searchname, const char *suffix, bool silent) { if (foundpath == NULL) return PM3_EINVARG; + if (searchname == NULL || strlen(searchname) == 0) + return PM3_EINVARG; + if (searchname[ strlen(searchname)-1] == '/') + return PM3_EINVARG; + char *filename = filenamemcopy(searchname, suffix); - if (filename == NULL) return PM3_EMALLOC; + if (filename == NULL || strlen(filename) == 0) + return PM3_EMALLOC; int res = searchFinalFile(foundpath, pm3dir, filename, silent); if (res != PM3_SUCCESS) { if ((res == PM3_EFILE) && (!silent)) From f7510dc6aaef16f32a9cdfc8880498d05ab57690 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 21 Sep 2019 11:12:36 +0200 Subject: [PATCH 0742/1854] better detection of directory (@doegox) --- client/fileutils.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/client/fileutils.c b/client/fileutils.c index 717787293..3599ec6f4 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -69,6 +69,23 @@ int fileExists(const char *filename) { return result == 0; } +/** + * @brief checks if path is file or directory. + * @param filename + * @return + */ +int is_regular_file(const char *filename) { +#ifdef _WIN32 + struct _stat st; + _stat(filename, &st); + return S_ISREG(_st.st_mode); +#else + struct stat st; + stat(filename, &st); + return S_ISREG(st.st_mode); +#endif +} + static char *filenamemcopy(const char *preferredName, const char *suffix) { if (preferredName == NULL) return NULL; if (suffix == NULL) return NULL; @@ -1016,9 +1033,11 @@ int searchFile(char **foundpath, const char *pm3dir, const char *searchname, con return PM3_EINVARG; if (searchname == NULL || strlen(searchname) == 0) return PM3_EINVARG; - if (searchname[ strlen(searchname)-1] == '/') + + if (is_regular_file(searchname) == 0) return PM3_EINVARG; + char *filename = filenamemcopy(searchname, suffix); if (filename == NULL || strlen(filename) == 0) return PM3_EMALLOC; From 862bf1b793e80c65931e7eaae2e269cea812b9d3 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 21 Sep 2019 11:48:55 +0200 Subject: [PATCH 0743/1854] fix for ps3.2 compilation --- client/fileutils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/fileutils.c b/client/fileutils.c index 3599ec6f4..450672935 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -78,7 +78,7 @@ int is_regular_file(const char *filename) { #ifdef _WIN32 struct _stat st; _stat(filename, &st); - return S_ISREG(_st.st_mode); + return S_ISREG(st.st_mode); #else struct stat st; stat(filename, &st); From e7d67fc2b0d09fcd5a44aefa40c15dacdeb23453 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 21 Sep 2019 16:31:45 +0200 Subject: [PATCH 0744/1854] fix for checking directory --- client/fileutils.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/client/fileutils.c b/client/fileutils.c index 450672935..35fa735ea 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -70,7 +70,7 @@ int fileExists(const char *filename) { } /** - * @brief checks if path is file or directory. + * @brief checks if path is file. * @param filename * @return */ @@ -85,6 +85,23 @@ int is_regular_file(const char *filename) { return S_ISREG(st.st_mode); #endif } +/** + * @brief checks if path is directory. + * @param filename + * @return + */ +int is_directory(const char *filename) { +#ifdef _WIN32 + struct _stat st; + _stat(filename, &st); + return S_ISDIR(st.st_mode); +#else + struct stat st; + stat(filename, &st); + return S_ISDIR(st.st_mode); +#endif +} + static char *filenamemcopy(const char *preferredName, const char *suffix) { if (preferredName == NULL) return NULL; @@ -1029,12 +1046,14 @@ out: } int searchFile(char **foundpath, const char *pm3dir, const char *searchname, const char *suffix, bool silent) { + if (foundpath == NULL) return PM3_EINVARG; + if (searchname == NULL || strlen(searchname) == 0) return PM3_EINVARG; - if (is_regular_file(searchname) == 0) + if (is_directory(searchname) != 0) return PM3_EINVARG; From 782feb934ac5ec5f25f91ce2a5deeba2a651357a Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 21 Sep 2019 18:32:07 +0200 Subject: [PATCH 0745/1854] split slow tests --- client/cmdhficlass.c | 6 ++++-- client/emv/cmdemv.c | 6 ++++-- client/emv/test/crypto_test.c | 16 +++++++++++++--- client/emv/test/crypto_test.h | 2 +- client/emv/test/cryptotest.c | 4 ++-- client/emv/test/cryptotest.h | 2 +- client/loclass/elite_crack.c | 5 +++-- client/loclass/elite_crack.h | 2 +- pm3test.sh | 17 ++++++++++++++--- 9 files changed, 43 insertions(+), 17 deletions(-) diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 5f8ed9fbc..691072174 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -229,10 +229,11 @@ static int usage_hf_iclass_sniff(void) { return PM3_SUCCESS; } static int usage_hf_iclass_loclass(void) { - PrintAndLogEx(NORMAL, "Usage: hf iclass loclass [options]"); + PrintAndLogEx(NORMAL, "Usage: hf iclass loclass [h] [t [l]] [f ]"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h Show this help"); PrintAndLogEx(NORMAL, " t Perform self-test"); + PrintAndLogEx(NORMAL, " t l Perform self-test, including long ones"); PrintAndLogEx(NORMAL, " f Bruteforce iclass dumpfile"); PrintAndLogEx(NORMAL, " An iclass dumpfile is assumed to consist of an arbitrary number of"); PrintAndLogEx(NORMAL, " malicious CSNs, and their protocol responses"); @@ -1831,10 +1832,11 @@ static int CmdHFiClass_loclass(const char *Cmd) { return PM3_EFILE; } } else if (opt == 't') { + char opt2 = tolower(param_getchar(Cmd, 1)); int errors = testCipherUtils(); errors += testMAC(); errors += doKeyTests(0); - errors += testElite(); + errors += testElite(opt2=='l'); if (errors) PrintAndLogEx(ERR, "There were errors!!!"); return PM3_ESOFT; } diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c index 8bb630074..d45181060 100644 --- a/client/emv/cmdemv.c +++ b/client/emv/cmdemv.c @@ -1716,19 +1716,21 @@ static int CmdEMVList(const char *Cmd) { static int CmdEMVTest(const char *Cmd) { CLIParserInit("emv test", "Executes tests\n", - "Usage:\n\temv test\n"); + "Usage:\n\temv test [l]\n"); void *argtable[] = { arg_param_begin, arg_lit0("iI", "ignore", "ignore timing tests for VM"), + arg_lit0("lL", "long", "run long tests too"), arg_param_end }; CLIExecWithReturn(Cmd, argtable, true); bool ignoreTimeTest = arg_get_lit(1); + bool runSlowTests = arg_get_lit(2); CLIParserFree(); - return ExecuteCryptoTests(true, ignoreTimeTest); + return ExecuteCryptoTests(true, ignoreTimeTest, runSlowTests); } static int CmdEMVRoca(const char *Cmd) { diff --git a/client/emv/test/crypto_test.c b/client/emv/test/crypto_test.c index cdf22a995..4a40952a8 100644 --- a/client/emv/test/crypto_test.c +++ b/client/emv/test/crypto_test.c @@ -301,8 +301,9 @@ close_pub: return ret; } -int exec_crypto_test(bool verbose) { - unsigned int keylengths[] = {1024, 1152, 1408, 1984, 2048, 3072, 4096}; +int exec_crypto_test(bool verbose, bool include_slow_tests) { + unsigned int keylengths[] = {1024, 2048}; + unsigned int extra_keylengths[] = {1152, 1408, 1984, 3072, 4096}; int i; int ret; fprintf(stdout, "\n"); @@ -322,6 +323,15 @@ int exec_crypto_test(bool verbose) { return ret; } } - + if (include_slow_tests) { + for (i = 0; i < ARRAYLEN(extra_keylengths); i++) { + unsigned int kl = extra_keylengths[i]; + ret = test_genkey(kl, message, kl / 8, verbose); + if (ret) { + fprintf(stderr, "Crypto generate key[%u] test: failed\n", kl); + return ret; + } + } + } return 0; } diff --git a/client/emv/test/crypto_test.h b/client/emv/test/crypto_test.h index 024a950d5..4b8fcf074 100644 --- a/client/emv/test/crypto_test.h +++ b/client/emv/test/crypto_test.h @@ -17,5 +17,5 @@ #define __CRYPTO_TEST_H #include -int exec_crypto_test(bool verbose); +int exec_crypto_test(bool verbose, bool include_slow_tests); #endif diff --git a/client/emv/test/cryptotest.c b/client/emv/test/cryptotest.c index b8ea1239e..f343ebbea 100644 --- a/client/emv/test/cryptotest.c +++ b/client/emv/test/cryptotest.c @@ -33,7 +33,7 @@ #include "crypto/libpcrypto.h" #include "emv/emv_roca.h" -int ExecuteCryptoTests(bool verbose, bool ignore_time) { +int ExecuteCryptoTests(bool verbose, bool ignore_time, bool include_slow_tests) { int res; bool TestFail = false; @@ -94,7 +94,7 @@ int ExecuteCryptoTests(bool verbose, bool ignore_time) { res = exec_cda_test(verbose); if (res) TestFail = true; - res = exec_crypto_test(verbose); + res = exec_crypto_test(verbose, include_slow_tests); if (res) TestFail = true; res = roca_self_test(); diff --git a/client/emv/test/cryptotest.h b/client/emv/test/cryptotest.h index aeecce556..579a5a66d 100644 --- a/client/emv/test/cryptotest.h +++ b/client/emv/test/cryptotest.h @@ -12,5 +12,5 @@ #define __CRYPTOTEST_H #include -int ExecuteCryptoTests(bool verbose, bool ignore_time); +int ExecuteCryptoTests(bool verbose, bool ignore_time, bool include_slow_tests); #endif diff --git a/client/loclass/elite_crack.c b/client/loclass/elite_crack.c index bf9aee5b3..c7a617f6a 100644 --- a/client/loclass/elite_crack.c +++ b/client/loclass/elite_crack.c @@ -637,7 +637,7 @@ static int _testHash1() { return 0; } -int testElite() { +int testElite(bool slowtests) { PrintAndLogEx(INFO, "Testing iClass Elite functinality..."); PrintAndLogEx(INFO, "Testing hash2"); uint8_t k_cus[8] = {0x5B, 0x7C, 0x62, 0xC4, 0x91, 0xC1, 0x1B, 0x39}; @@ -669,6 +669,7 @@ int testElite() { errors += _testHash1(); PrintAndLogEx(INFO, "Testing key diversification ..."); errors += _test_iclass_key_permutation(); - errors += _testBruteforce(); + if (slowtests) + errors += _testBruteforce(); return errors; } diff --git a/client/loclass/elite_crack.h b/client/loclass/elite_crack.h index 819d3de47..8b357ac66 100644 --- a/client/loclass/elite_crack.h +++ b/client/loclass/elite_crack.h @@ -124,7 +124,7 @@ int calculateMasterKey(uint8_t first16bytes[], uint64_t master_key[]); * @brief Test function * @return */ -int testElite(void); +int testElite(bool slowtests); /** Here are some pretty optimal values that can be used to recover necessary data in only diff --git a/pm3test.sh b/pm3test.sh index 8785bf8df..de9134ba1 100755 --- a/pm3test.sh +++ b/pm3test.sh @@ -3,6 +3,12 @@ PM3PATH=$(dirname "$0") cd "$PM3PATH" || exit 1 +if [ "$1" == "long" ]; then + SLOWTESTS=true +else + SLOWTESTS=false +fi + C_RED='\033[0;31m' C_GREEN='\033[0;32m' C_YELLOW='\033[0;33m' @@ -95,9 +101,14 @@ while true; do printf "\n${C_BLUE}Testing HF:${C_NC}\n" if ! CheckExecute "hf mf offline text" "./client/proxmark3 -c 'hf mf'" "at_enc"; then break; fi - if ! CheckExecute "hf mf hardnested test" "./client/proxmark3 -c 'hf mf hardnested t 1 000000000000'" "found:" "repeat" "ignore"; then break; fi - if ! CheckExecute "hf iclass test" "./client/proxmark3 -c 'hf iclass loclass t'" "verified ok"; then break; fi - if ! CheckExecute "emv test" "./client/proxmark3 -c 'emv test'" "Test(s) \[ OK"; then break; fi + if $SLOWTESTS; then + if ! CheckExecute "hf mf hardnested test" "./client/proxmark3 -c 'hf mf hardnested t 1 000000000000'" "found:" "repeat" "ignore"; then break; fi + if ! CheckExecute "hf iclass test" "./client/proxmark3 -c 'hf iclass loclass t l'" "verified ok"; then break; fi + if ! CheckExecute "emv test" "./client/proxmark3 -c 'emv test -l'" "Test(s) \[ OK"; then break; fi + else + if ! CheckExecute "hf iclass test" "./client/proxmark3 -c 'hf iclass loclass t'" "OK!"; then break; fi + if ! CheckExecute "emv test" "./client/proxmark3 -c 'emv test'" "Test(s) \[ OK"; then break; fi + fi printf "\n${C_BLUE}Testing tools:${C_NC}\n" # Need a decent example for mfkey32... From 51f48301c883c85dd97210f8fa9a0984ad7ef506 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 21 Sep 2019 19:09:54 +0200 Subject: [PATCH 0746/1854] appveyor tests --- appveyor.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index a32c6a56a..db9223c17 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -376,13 +376,14 @@ test_script: ExecTest "hf mf offline text" "hf mf" {bash -lc "cd ~/client;./proxmark3 -c 'hf mf'"} "at_enc" - ExecTest "hf mf hardnested" "hf mf hardnested" {bash -lc "cd ~/client;./proxmark3 -c 'hf mf hardnested t 1 000000000000'"} "found:" - - ExecTest "hf mf iclass" "hf mf iclass" {bash -lc "cd ~/client;./proxmark3 -c 'hf iclass loclass t'"} "verified ok" - - #proxmark crypto tests +# Long tests: +# ExecTest "hf mf hardnested" "hf mf hardnested" {bash -lc "cd ~/client;./proxmark3 -c 'hf mf hardnested t 1 000000000000'"} "found:" +# ExecTest "hf mf iclass" "hf mf iclass" {bash -lc "cd ~/client;./proxmark3 -c 'hf iclass loclass t l'"} "verified ok" +# ExecTest "emv test" "emv test" {bash -lc "cd ~/client;./proxmark3 -c 'emv test -i -l'"} "Test?s? ? OK" +# Short tests: + ExecTest "hf mf iclass" "hf mf iclass" {bash -lc "cd ~/client;./proxmark3 -c 'hf iclass loclass t'"} "OK!" ExecTest "emv test" "emv test" {bash -lc "cd ~/client;./proxmark3 -c 'emv test -i'"} "Test?s? ? OK" From d395bda489261e1d737e60103037125b652a416e Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 21 Sep 2019 19:20:59 +0200 Subject: [PATCH 0747/1854] yaml comments... --- appveyor.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index db9223c17..a817ff1ac 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -378,11 +378,11 @@ test_script: #proxmark crypto tests -# Long tests: -# ExecTest "hf mf hardnested" "hf mf hardnested" {bash -lc "cd ~/client;./proxmark3 -c 'hf mf hardnested t 1 000000000000'"} "found:" -# ExecTest "hf mf iclass" "hf mf iclass" {bash -lc "cd ~/client;./proxmark3 -c 'hf iclass loclass t l'"} "verified ok" -# ExecTest "emv test" "emv test" {bash -lc "cd ~/client;./proxmark3 -c 'emv test -i -l'"} "Test?s? ? OK" -# Short tests: + # Long tests: + # ExecTest "hf mf hardnested" "hf mf hardnested" {bash -lc "cd ~/client;./proxmark3 -c 'hf mf hardnested t 1 000000000000'"} "found:" + # ExecTest "hf mf iclass" "hf mf iclass" {bash -lc "cd ~/client;./proxmark3 -c 'hf iclass loclass t l'"} "verified ok" + # ExecTest "emv test" "emv test" {bash -lc "cd ~/client;./proxmark3 -c 'emv test -i -l'"} "Test?s? ? OK" + # Short tests: ExecTest "hf mf iclass" "hf mf iclass" {bash -lc "cd ~/client;./proxmark3 -c 'hf iclass loclass t'"} "OK!" ExecTest "emv test" "emv test" {bash -lc "cd ~/client;./proxmark3 -c 'emv test -i'"} "Test?s? ? OK" From d46edd9a53d917a97b742def167a7870633adf8a Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 21 Sep 2019 20:22:17 +0200 Subject: [PATCH 0748/1854] change is_* return to bool --- client/fileutils.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/client/fileutils.c b/client/fileutils.c index 35fa735ea..6efe4c17b 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -74,15 +74,15 @@ int fileExists(const char *filename) { * @param filename * @return */ -int is_regular_file(const char *filename) { +bool is_regular_file(const char *filename) { #ifdef _WIN32 struct _stat st; _stat(filename, &st); - return S_ISREG(st.st_mode); + return S_ISREG(st.st_mode) != 0; #else struct stat st; stat(filename, &st); - return S_ISREG(st.st_mode); + return S_ISREG(st.st_mode) != 0; #endif } /** @@ -90,15 +90,15 @@ int is_regular_file(const char *filename) { * @param filename * @return */ -int is_directory(const char *filename) { +bool is_directory(const char *filename) { #ifdef _WIN32 struct _stat st; _stat(filename, &st); - return S_ISDIR(st.st_mode); + return S_ISDIR(st.st_mode) != 0; #else struct stat st; stat(filename, &st); - return S_ISDIR(st.st_mode); + return S_ISDIR(st.st_mode) != 0; #endif } @@ -1053,7 +1053,7 @@ int searchFile(char **foundpath, const char *pm3dir, const char *searchname, con if (searchname == NULL || strlen(searchname) == 0) return PM3_EINVARG; - if (is_directory(searchname) != 0) + if (is_directory(searchname)) return PM3_EINVARG; From 00344adfd392fdb6de653fd5efd9ef8c9a0f16f5 Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 21 Sep 2019 13:25:28 -0500 Subject: [PATCH 0749/1854] subtle change for clarity Both interface-raspberrypi.cfg and interface-raspberrypi2.cfg gave conflicting instructions for the dd return value. This should clear that up. --- tools/jtag_openocd/interface-raspberrypi2.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/jtag_openocd/interface-raspberrypi2.cfg b/tools/jtag_openocd/interface-raspberrypi2.cfg index b779cd290..dc97479d5 100644 --- a/tools/jtag_openocd/interface-raspberrypi2.cfg +++ b/tools/jtag_openocd/interface-raspberrypi2.cfg @@ -17,7 +17,7 @@ interface bcm2835gpio # This file is meant for recent versions of Raspberry Pi # You can check yours with: # dd if=/proc/device-tree/soc/ranges bs=4 skip=1 count=1 2>/dev/null|xxd -p -# if it returns 20000000, use interface-raspberrypi2.cfg +# if it returns 20000000, use interface-raspberrypi.cfg # if it returns 3F000000, you're fine bcm2835gpio_peripheral_base 0x3F000000 From 6422cc6d132c37d1cfdb9717fd31e9c5ae266bcc Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 21 Sep 2019 23:25:21 +0200 Subject: [PATCH 0750/1854] Fix mfc gen1b/gen1b detection --- armsrc/mifarecmd.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 089a320ad..e07b59795 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -1997,11 +1997,8 @@ void MifareCIdent() { // Generation 1 test ReaderTransmitBitsPar(wupC1, 7, NULL, NULL); - - if (ReaderReceive(rec, recpar) || (rec[0] != 0x0a)) { - + if (ReaderReceive(rec, recpar) && (rec[0] == 0x0a)) { ReaderTransmit(wupC2, sizeof(wupC2), NULL); - if (!ReaderReceive(rec, recpar) || (rec[0] != 0x0a)) { isGen = GEN_1B; goto OUT; @@ -2017,7 +2014,7 @@ void MifareCIdent() { int res = iso14443a_select_card(uid, NULL, &cuid, true, 0, true); if (res == 2) { - Dbprintf("cident AA55C396 == %08X", cuid); +// Dbprintf("cident AA55C396 == %08X", cuid); if (cuid == 0xAA55C396) { isGen = GEN_UNFUSED; goto OUT; From 11dcc4787d1dd0c9f7dce64cce92503c791283a4 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 21 Sep 2019 23:50:32 +0200 Subject: [PATCH 0751/1854] mfc magic: add some defines --- armsrc/mifarecmd.c | 16 +++++----------- client/mifare/mifarehost.c | 8 ++++---- include/protocols.h | 5 +++++ 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index e07b59795..4a469e6e1 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -1977,11 +1977,6 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain) { } void MifareCIdent() { -#define GEN_1A 1 -#define GEN_1B 2 -#define GEN_2 4 -#define GEN_UNFUSED 5 - // variables uint8_t isGen = 0; uint8_t rec[1] = {0x00}; @@ -2000,10 +1995,10 @@ void MifareCIdent() { if (ReaderReceive(rec, recpar) && (rec[0] == 0x0a)) { ReaderTransmit(wupC2, sizeof(wupC2), NULL); if (!ReaderReceive(rec, recpar) || (rec[0] != 0x0a)) { - isGen = GEN_1B; + isGen = MAGIC_GEN_1B; goto OUT; }; - isGen = GEN_1A; + isGen = MAGIC_GEN_1A; goto OUT; } @@ -2014,20 +2009,19 @@ void MifareCIdent() { int res = iso14443a_select_card(uid, NULL, &cuid, true, 0, true); if (res == 2) { -// Dbprintf("cident AA55C396 == %08X", cuid); if (cuid == 0xAA55C396) { - isGen = GEN_UNFUSED; + isGen = MAGIC_GEN_UNFUSED; goto OUT; } ReaderTransmit(rats, sizeof(rats), NULL); res = ReaderReceive(buf, par); if (memcmp(buf, "\x09\x78\x00\x91\x02\xDA\xBC\x19\x10\xF0\x05", 11) == 0) { - isGen = GEN_2; + isGen = MAGIC_GEN_2; goto OUT; } if (memcmp(buf, "\x0D\x78\x00\x71\x02\x88\x49\xA1\x30\x20\x15\x06\x08\x56\x3D", 15) == 0) { - isGen = GEN_2; + isGen = MAGIC_GEN_2; } }; diff --git a/client/mifare/mifarehost.c b/client/mifare/mifarehost.c index 429605a4e..e4cec00c0 100644 --- a/client/mifare/mifarehost.c +++ b/client/mifare/mifarehost.c @@ -1033,16 +1033,16 @@ void detect_classic_magic(void) { } switch (isGeneration) { - case 1: + case MAGIC_GEN_1A: PrintAndLogEx(SUCCESS, "Answers to magic commands (GEN 1a): " _GREEN_("YES")); break; - case 2: + case MAGIC_GEN_1B: PrintAndLogEx(SUCCESS, "Answers to magic commands (GEN 1b): " _GREEN_("YES")); break; - case 4: + case MAGIC_GEN_2: PrintAndLogEx(SUCCESS, "Answers to magic commands (GEN 2 / CUID): " _GREEN_("YES")); break; - case 5: + case MAGIC_GEN_UNFUSED: PrintAndLogEx(SUCCESS, "Answers to magic commands (Write Once / FUID): " _GREEN_("YES")); break; default: diff --git a/include/protocols.h b/include/protocols.h index 9b47266c3..747e4e346 100644 --- a/include/protocols.h +++ b/include/protocols.h @@ -205,6 +205,11 @@ ISO 7816-4 Basic interindustry commands. For command APDU's. #define MAGIC_WIPE 0x40 #define MAGIC_SINGLE (MAGIC_WUPC | MAGIC_HALT | MAGIC_INIT | MAGIC_OFF) //0x1E +// by CMD_HF_MIFARE_CIDENT +#define MAGIC_GEN_1A 1 +#define MAGIC_GEN_1B 2 +#define MAGIC_GEN_2 4 +#define MAGIC_GEN_UNFUSED 5 /** 06 00 = INITIATE 0E xx = SELECT ID (xx = Chip-ID) From 3a9087d2a13002cb805c081a82ad61f9d24b65ef Mon Sep 17 00:00:00 2001 From: mwalker33 Date: Sun, 22 Sep 2019 15:27:00 +1000 Subject: [PATCH 0752/1854] Update cmdlfem4x.c em 4x05_dump did not output data --- client/cmdlfem4x.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c index e7b1c2b06..80a10e06e 100644 --- a/client/cmdlfem4x.c +++ b/client/cmdlfem4x.c @@ -1213,19 +1213,27 @@ static int CmdEM4x05Dump(const char *Cmd) { usePwd = true; int success = PM3_SUCCESS; + int status; uint32_t word = 0; - PrintAndLogEx(NORMAL, "Addr | data | ascii"); - PrintAndLogEx(NORMAL, "-----+--------+------"); + PrintAndLogEx(NORMAL, "Addr | data | info"); + PrintAndLogEx(NORMAL, "-----+----------+-------"); for (; addr < 16; addr++) { if (addr == 2) { if (usePwd) { - PrintAndLogEx(NORMAL, " %02u | %08X", addr, pwd, word); + PrintAndLogEx(NORMAL, " %02u | %08X |", addr, pwd, word); } else { - PrintAndLogEx(NORMAL, " 02 | " _RED_("cannot read")); + PrintAndLogEx(NORMAL, " 02 | | " _RED_("cannot read")); } } else { - success &= EM4x05ReadWord_ext(addr, pwd, usePwd, &word); + // success &= EM4x05ReadWord_ext(addr, pwd, usePwd, &word); + status = EM4x05ReadWord_ext(addr, pwd, usePwd, &word); // Get status for single read + success &= status; // Update status to match previous return + + if (status == PM3_SUCCESS) + PrintAndLogEx(NORMAL, " %02d | %08X | %s", addr, word, (addr > 13) ? "Lock" : ""); + else + PrintAndLogEx(NORMAL, " %02d | " _RED_("Fail"), addr); } } From 0ea501372ba881c2cc59528edce8511f182fa0cf Mon Sep 17 00:00:00 2001 From: mwalker33 Date: Sun, 22 Sep 2019 19:41:45 +1000 Subject: [PATCH 0753/1854] Update cmdlfem4x.c Added print Ascii to em 4x05_dump --- client/cmdlfem4x.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c index 80a10e06e..ec535205e 100644 --- a/client/cmdlfem4x.c +++ b/client/cmdlfem4x.c @@ -1204,6 +1204,8 @@ static int CmdEM4x05Dump(const char *Cmd) { uint32_t pwd = 0; bool usePwd = false; uint8_t ctmp = tolower(param_getchar(Cmd, 0)); + uint8_t bytes[4] = {0}; + if (ctmp == 'h') return usage_lf_em4x05_dump(); // for now use default input of 1 as invalid (unlikely 1 will be a valid password...) @@ -1215,7 +1217,7 @@ static int CmdEM4x05Dump(const char *Cmd) { int success = PM3_SUCCESS; int status; uint32_t word = 0; - PrintAndLogEx(NORMAL, "Addr | data | info"); + PrintAndLogEx(NORMAL, "Addr | data | ascii"); PrintAndLogEx(NORMAL, "-----+----------+-------"); for (; addr < 16; addr++) { @@ -1230,10 +1232,12 @@ static int CmdEM4x05Dump(const char *Cmd) { status = EM4x05ReadWord_ext(addr, pwd, usePwd, &word); // Get status for single read success &= status; // Update status to match previous return - if (status == PM3_SUCCESS) - PrintAndLogEx(NORMAL, " %02d | %08X | %s", addr, word, (addr > 13) ? "Lock" : ""); + if (status == PM3_SUCCESS) { + num_to_bytes(word, 4, bytes); + PrintAndLogEx(NORMAL, " %02d | %08X | %s", addr, word, (addr > 13) ? "Lock" : sprint_ascii(bytes, 4)); + } else - PrintAndLogEx(NORMAL, " %02d | " _RED_("Fail"), addr); + PrintAndLogEx(NORMAL, " %02d | | " _RED_("Fail"), addr); } } @@ -1244,6 +1248,7 @@ static int CmdEM4x05Read(const char *Cmd) { uint8_t addr; uint32_t pwd; bool usePwd = false; + uint8_t ctmp = tolower(param_getchar(Cmd, 0)); if (strlen(Cmd) == 0 || ctmp == 'h') return usage_lf_em4x05_read(); From 9cdc26207fdf3ca936f67730bc80dd249e60c004 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 22 Sep 2019 13:04:28 +0200 Subject: [PATCH 0754/1854] add 'lf hid watch' , 'lf awid watch', 'lf io watch' --- client/cmdlfawid.c | 29 ++++++++++++----------------- client/cmdlfhid.c | 9 +++------ client/cmdlfio.c | 28 ++++++++++++---------------- 3 files changed, 27 insertions(+), 39 deletions(-) diff --git a/client/cmdlfawid.c b/client/cmdlfawid.c index 056d95af4..dcbcc0f7e 100644 --- a/client/cmdlfawid.c +++ b/client/cmdlfawid.c @@ -29,23 +29,18 @@ #include "cmdlft55xx.h" // verifywrite static int CmdHelp(const char *Cmd); -/* -static int usage_lf_awid_read(void) { + +static int usage_lf_awid_watch(void) { PrintAndLogEx(NORMAL, "Enables AWID compatible reader mode printing details of scanned AWID26 or AWID50 tags."); PrintAndLogEx(NORMAL, "By default, values are printed and logged until the button is pressed or another USB command is issued."); - PrintAndLogEx(NORMAL, "If the [1] option is provided, reader mode is exited after reading a single AWID card."); PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Usage: lf awid read [h] [1]"); - PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " h : This help"); - PrintAndLogEx(NORMAL, " 1 : (optional) stop after reading a single card"); + PrintAndLogEx(NORMAL, "Usage: lf awid watch"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " lf awid read"); - PrintAndLogEx(NORMAL, " lf awid read 1"); + PrintAndLogEx(NORMAL, " lf awid watch"); return PM3_SUCCESS; } -*/ + static int usage_lf_awid_sim(void) { PrintAndLogEx(NORMAL, "Enables simulation of AWID card with specified facility-code and card number."); PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued."); @@ -180,18 +175,17 @@ static void verify_values(uint8_t *fmtlen, uint32_t *fc, uint32_t *cn) { break; } } -/* + // this read loops on device side. // uses the demod in lfops.c -static int CmdAWIDRead_device(const char *Cmd) { - - if (Cmd[0] == 'h' || Cmd[0] == 'H') return usage_lf_awid_read(); - uint8_t findone = (Cmd[0] == '1') ? 1 : 0; +static int CmdAWIDWatch(const char *Cmd) { + uint8_t ctmp = tolower(param_getchar(Cmd, 0)); + if (ctmp == 'h') return usage_lf_awid_watch(); clearCommandBuffer(); - SendCommandMIX(CMD_LF_AWID_DEMOD, findone, 0, 0, NULL, 0); + SendCommandNG(CMD_LF_AWID_DEMOD, NULL, 0); return PM3_SUCCESS; } -*/ + //by marshmellow //AWID Prox demod - FSK2a RF/50 with preamble of 00000001 (always a 96 bit data stream) //print full AWID Prox ID and some bit format details if found @@ -557,6 +551,7 @@ static command_t CommandTable[] = { {"clone", CmdAWIDClone, IfPm3Lf, "clone AWID to T55x7"}, {"sim", CmdAWIDSim, IfPm3Lf, "simulate AWID tag"}, {"brute", CmdAWIDBrute, IfPm3Lf, "Bruteforce card number against reader"}, + {"watch", CmdAWIDWatch, IfPm3Lf, "continuously watch for cards. Reader mode"}, {NULL, NULL, NULL, NULL} }; diff --git a/client/cmdlfhid.c b/client/cmdlfhid.c index 20baa6449..a5cb64325 100644 --- a/client/cmdlfhid.c +++ b/client/cmdlfhid.c @@ -47,9 +47,7 @@ static int usage_lf_hid_watch(void) { PrintAndLogEx(NORMAL, "Enables HID compatible reader mode printing details."); PrintAndLogEx(NORMAL, "By default, values are printed and logged until the button is pressed or another USB command is issued."); PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Usage: lf hid watch [h]"); - PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " h : This help"); + PrintAndLogEx(NORMAL, "Usage: lf hid watch"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf hid watch"); @@ -264,11 +262,10 @@ static int CmdHIDRead(const char *Cmd) { // this read loops on device side. // uses the demod in lfops.c static int CmdHIDWatch(const char *Cmd) { - uint8_t ctmp = tolower(param_getchar(Cmd, 0)); - if ( strlen(Cmd) == 0 || ctmp == 'h') return usage_lf_hid_watch(); + if (ctmp == 'h') return usage_lf_hid_watch(); clearCommandBuffer(); - SendCommandMIX(CMD_LF_HID_DEMOD, 0, 0, 0, NULL, 0); + SendCommandNG(CMD_LF_HID_DEMOD, NULL, 0); return PM3_SUCCESS; } diff --git a/client/cmdlfio.c b/client/cmdlfio.c index 7b3e777c6..203b1c06d 100644 --- a/client/cmdlfio.c +++ b/client/cmdlfio.c @@ -27,23 +27,18 @@ #include "cmdlft55xx.h" // verifywrite static int CmdHelp(const char *Cmd); -/* -static int usage_lf_io_read(void) { + +static int usage_lf_io_watch(void) { PrintAndLogEx(NORMAL, "Enables IOProx compatible reader mode printing details of scanned tags."); PrintAndLogEx(NORMAL, "By default, values are printed and logged until the button is pressed or another USB command is issued."); - PrintAndLogEx(NORMAL, "If the [1] option is provided, reader mode is exited after reading a single card."); PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Usage: lf io read [h] [1]"); - PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " h : This help"); - PrintAndLogEx(NORMAL, " 1 : (optional) stop after reading a single card"); + PrintAndLogEx(NORMAL, "Usage: lf io watch"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " lf io read"); - PrintAndLogEx(NORMAL, " lf io read 1"); + PrintAndLogEx(NORMAL, " lf io watch"); return PM3_SUCCESS; } -*/ + static int usage_lf_io_sim(void) { PrintAndLogEx(NORMAL, "Enables simulation of IOProx card with specified facility-code and card number."); PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued."); @@ -76,17 +71,17 @@ static int usage_lf_io_clone(void) { PrintAndLogEx(NORMAL, " lf io clone 26 101 1337"); return PM3_SUCCESS; } -/* + // this read loops on device side. // uses the demod in lfops.c -static int CmdIOProxRead_device(const char *Cmd) { - if (Cmd[0] == 'h' || Cmd[0] == 'H') return usage_lf_io_read(); - int findone = (Cmd[0] == '1') ? 1 : 0; +static int CmdIOProxWatch(const char *Cmd) { + uint8_t ctmp = tolower(param_getchar(Cmd, 0)); + if (ctmp == 'h') return usage_lf_io_watch(); clearCommandBuffer(); - SendCommandMIX(CMD_LF_IO_DEMOD, findone, 0, 0, NULL, 0); + SendCommandNG(CMD_LF_IO_DEMOD, NULL, 0); return PM3_SUCCESS; } -*/ + //by marshmellow //IO-Prox demod - FSK RF/64 with preamble of 000000001 //print ioprox ID and some format details @@ -324,6 +319,7 @@ static command_t CommandTable[] = { {"read", CmdIOProxRead, IfPm3Lf, "attempt to read and extract tag data"}, {"clone", CmdIOProxClone, IfPm3Lf, "clone IOProx to T55x7"}, {"sim", CmdIOProxSim, IfPm3Lf, "simulate IOProx tag"}, + {"watch", CmdIOProxWatch, IfPm3Lf, "continuously watch for cards. Reader mode"}, {NULL, NULL, NULL, NULL} }; From b6d074cc9f4660c81f4aac999705c44f2fff71b2 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 22 Sep 2019 17:24:29 +0200 Subject: [PATCH 0755/1854] zlib: minimize diffs with upstream to prepare zlib upgrade --- common/zlib/ChangeLog | 9 ----- common/zlib/README | 9 ----- common/zlib/README_proxmark3 | 19 +++++++++++ common/zlib/adler32.c | 1 + common/zlib/deflate.c | 55 +++++++++++++++---------------- common/zlib/deflate.h | 35 ++++++++++---------- common/zlib/inffast.c | 1 + common/zlib/inffast.h | 1 + common/zlib/inffixed.h | 1 + common/zlib/inflate.c | 10 +----- common/zlib/inflate.h | 1 + common/zlib/inftrees.c | 5 +++ common/zlib/inftrees.h | 1 + common/zlib/trees.c | 64 ++++++++++++++++-------------------- common/zlib/trees.h | 1 + common/zlib/zconf.h | 1 + common/zlib/zlib.h | 28 +++++++--------- common/zlib/zutil.c | 1 + common/zlib/zutil.h | 7 ++-- 19 files changed, 122 insertions(+), 128 deletions(-) create mode 100644 common/zlib/README_proxmark3 diff --git a/common/zlib/ChangeLog b/common/zlib/ChangeLog index b9965157e..f22aabaef 100644 --- a/common/zlib/ChangeLog +++ b/common/zlib/ChangeLog @@ -1,15 +1,6 @@ ChangeLog file for zlib -Changes in 1.2.8.f-Proxmark3 (for Proxmark3 project only) (26 May 2015) -- disable decoding of fixed code blocks in deflate (eliminates the need - to store the fixed tree in RAM or ROM) -- disable generating fixed code blocks in inflate -- look harder for local optimum of consecutive matches and single literals - in inflate. -- stripped down version - unnecessary files from original distribution - are not included - Changes in 1.2.8 (28 Apr 2013) - Update contrib/minizip/iowin32.c for Windows RT [Vollant] - Do not force Z_CONST for C++ diff --git a/common/zlib/README b/common/zlib/README index ace67a512..5ca9d127e 100644 --- a/common/zlib/README +++ b/common/zlib/README @@ -1,12 +1,3 @@ -//----------------------------------------------------------------------------- -// This version of zlib is modified for use within the Proxmark3 project. -// Files from the original distribution which are not required for this -// purpose are not included. All modifications can easily be found -// by searching for #ifdef ZLIB_PM3_TUNED and #ifndef ZLIB_PM3_TUNED. -// -// The rest of this file consists of the original README content -//----------------------------------------------------------------------------- - ZLIB DATA COMPRESSION LIBRARY zlib 1.2.8 is a general purpose data compression library. All the code is diff --git a/common/zlib/README_proxmark3 b/common/zlib/README_proxmark3 new file mode 100644 index 000000000..d3192f199 --- /dev/null +++ b/common/zlib/README_proxmark3 @@ -0,0 +1,19 @@ +This version of zlib is modified for use within the Proxmark3 project. +Files from the original distribution which are not required for this +purpose are not included. All modifications can easily be found +by searching for #ifdef ZLIB_PM3_TUNED and #ifndef ZLIB_PM3_TUNED. + +Current zlib base version is 1.2.8 + + +ChangeLog for Proxmark3 project only +------------------------------------ + +Changes in 1.2.8.f-Proxmark3 (26 May 2015) +- disable decoding of fixed code blocks in deflate (eliminates the need + to store the fixed tree in RAM or ROM) +- disable generating fixed code blocks in inflate +- look harder for local optimum of consecutive matches and single literals + in inflate. +- stripped down version - unnecessary files from original distribution + are not included diff --git a/common/zlib/adler32.c b/common/zlib/adler32.c index f18f4566c..a3e96f949 100644 --- a/common/zlib/adler32.c +++ b/common/zlib/adler32.c @@ -177,3 +177,4 @@ z_off64_t len2; { return adler32_combine_(adler1, adler2, len2); } + diff --git a/common/zlib/deflate.c b/common/zlib/deflate.c index 013f92150..7445d5907 100644 --- a/common/zlib/deflate.c +++ b/common/zlib/deflate.c @@ -52,7 +52,11 @@ #include "deflate.h" const char deflate_copyright[] = +#ifdef ZLIB_PM3_TUNED " deflate 1.2.8.f-Proxmark3 Copyright 1995-2013 Jean-loup Gailly and Mark Adler "; +#else + " deflate 1.2.8 Copyright 1995-2013 Jean-loup Gailly and Mark Adler "; +#endif /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot @@ -60,15 +64,6 @@ const char deflate_copyright[] = copyright string in the executable of your product. */ -//----------------------------------------------------------------------------- -// This version of zlib is modified for use within the Proxmark3 project. -// Files from the original distribution which are not required for this -// purpose are not included. All modifications can easily be found -// by searching for #ifdef ZLIB_PM3_TUNED and #ifndef ZLIB_PM3_TUNED. -//----------------------------------------------------------------------------- - - - /* =========================================================================== * Function prototypes. */ @@ -190,14 +185,14 @@ struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ */ #ifdef FASTEST #define INSERT_STRING(s, str, match_head) \ - (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ - match_head = s->head[s->ins_h], \ - s->head[s->ins_h] = (Pos)(str)) + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + match_head = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) #else #define INSERT_STRING(s, str, match_head) \ - (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ - match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \ - s->head[s->ins_h] = (Pos)(str)) + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) #endif /* =========================================================================== @@ -1155,7 +1150,7 @@ IPos cur_match; /* current match */ { unsigned chain_length = s->max_chain_length;/* max hash chain length */ register Bytef *scan = s->window + s->strstart; /* current string */ - register Bytef *match; /* matched string */ + register Bytef *match; /* matched string */ register int len; /* length of current match */ #ifdef ZLIB_PM3_TUNED int best_len = MIN_MATCH - 1; /* lift the restriction on prev-length */ @@ -1544,21 +1539,21 @@ deflate_state *s; * IN assertion: strstart is set to the end of the current match. */ #define FLUSH_BLOCK_ONLY(s, last) { \ - _tr_flush_block(s, (s->block_start >= 0L ? \ - (charf *)&s->window[(unsigned)s->block_start] : \ - (charf *)Z_NULL), \ - (ulg)((long)s->strstart - s->block_start), \ - (last)); \ - s->block_start = s->strstart; \ - flush_pending(s->strm); \ - Tracev((stderr,"[FLUSH]")); \ - } + _tr_flush_block(s, (s->block_start >= 0L ? \ + (charf *)&s->window[(unsigned)s->block_start] : \ + (charf *)Z_NULL), \ + (ulg)((long)s->strstart - s->block_start), \ + (last)); \ + s->block_start = s->strstart; \ + flush_pending(s->strm); \ + Tracev((stderr,"[FLUSH]")); \ +} /* Same but force premature exit if necessary. */ #define FLUSH_BLOCK(s, last) { \ - FLUSH_BLOCK_ONLY(s, last); \ - if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \ - } + FLUSH_BLOCK_ONLY(s, last); \ + if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \ +} /* =========================================================================== * Copy without compression as much as possible from the input stream, return @@ -1840,7 +1835,8 @@ int flush; INSERT_STRING(s, s->strstart, hash_head); } - /* Find the longest match, discarding those <= prev_length. */ + /* Find the longest match, discarding those <= prev_length. + */ s->prev_length = s->match_length, s->prev_match = s->match_start; s->match_length = MIN_MATCH - 1; @@ -2054,3 +2050,4 @@ int flush; FLUSH_BLOCK(s, 0); return block_done; } + diff --git a/common/zlib/deflate.h b/common/zlib/deflate.h index 50760d226..1e17b476d 100644 --- a/common/zlib/deflate.h +++ b/common/zlib/deflate.h @@ -303,7 +303,7 @@ void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len, int last)); #define d_code(dist) \ - ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) + ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) /* Mapping from a distance to a distance code. dist is the distance - 1 and * must not have side effects. _dist_code[256] and _dist_code[257] are never * used. @@ -321,26 +321,27 @@ extern const uch ZLIB_INTERNAL _dist_code[]; #endif # define _tr_tally_lit(s, c, flush) \ - { uch cc = (c); \ - s->d_buf[s->last_lit] = 0; \ - s->l_buf[s->last_lit++] = cc; \ - s->dyn_ltree[cc].Freq++; \ - flush = (s->last_lit == s->lit_bufsize-1); \ - } + { uch cc = (c); \ + s->d_buf[s->last_lit] = 0; \ + s->l_buf[s->last_lit++] = cc; \ + s->dyn_ltree[cc].Freq++; \ + flush = (s->last_lit == s->lit_bufsize-1); \ + } # define _tr_tally_dist(s, distance, length, flush) \ - { uch len = (length); \ - ush dist = (distance); \ - s->d_buf[s->last_lit] = dist; \ - s->l_buf[s->last_lit++] = len; \ - dist--; \ - s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ - s->dyn_dtree[d_code(dist)].Freq++; \ - flush = (s->last_lit == s->lit_bufsize-1); \ - } + { uch len = (length); \ + ush dist = (distance); \ + s->d_buf[s->last_lit] = dist; \ + s->l_buf[s->last_lit++] = len; \ + dist--; \ + s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ + s->dyn_dtree[d_code(dist)].Freq++; \ + flush = (s->last_lit == s->lit_bufsize-1); \ + } #else # define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) # define _tr_tally_dist(s, distance, length, flush) \ - flush = _tr_tally(s, distance, length) + flush = _tr_tally(s, distance, length) #endif #endif /* DEFLATE_H */ + diff --git a/common/zlib/inffast.c b/common/zlib/inffast.c index 0cd59d49b..63f3f7d80 100644 --- a/common/zlib/inffast.c +++ b/common/zlib/inffast.c @@ -329,3 +329,4 @@ dodist: */ #endif /* !ASMINF */ + diff --git a/common/zlib/inffast.h b/common/zlib/inffast.h index e5c1aa4ca..131f157a1 100644 --- a/common/zlib/inffast.h +++ b/common/zlib/inffast.h @@ -9,3 +9,4 @@ */ void ZLIB_INTERNAL inflate_fast OF((z_streamp strm, unsigned start)); + diff --git a/common/zlib/inffixed.h b/common/zlib/inffixed.h index 35d010097..fec0606fd 100644 --- a/common/zlib/inffixed.h +++ b/common/zlib/inffixed.h @@ -92,3 +92,4 @@ static const code distfix[32] = { {16, 5, 4}, {24, 5, 769}, {20, 5, 49}, {28, 5, 12289}, {18, 5, 13}, {26, 5, 3073}, {22, 5, 193}, {64, 5, 0} }; + diff --git a/common/zlib/inflate.c b/common/zlib/inflate.c index 9e320be27..a5aee5a33 100644 --- a/common/zlib/inflate.c +++ b/common/zlib/inflate.c @@ -80,15 +80,6 @@ * The history for versions after 1.2.0 are in ChangeLog in zlib distribution. */ -//----------------------------------------------------------------------------- -// This version of zlib is modified for use within the Proxmark3 project. -// Files from the original distribution which are not required for this -// purpose are not included. All modifications can easily be found -// by searching for #ifdef ZLIB_PM3_TUNED and #ifndef ZLIB_PM3_TUNED. -//----------------------------------------------------------------------------- - - - #include "zutil.h" #include "inftrees.h" #include "inflate.h" @@ -1520,3 +1511,4 @@ z_streamp strm; (state->mode == COPY ? state->length : (state->mode == MATCH ? state->was - state->length : 0)); } + diff --git a/common/zlib/inflate.h b/common/zlib/inflate.h index 81e7aadd6..399ccc521 100644 --- a/common/zlib/inflate.h +++ b/common/zlib/inflate.h @@ -120,3 +120,4 @@ struct inflate_state { int back; /* bits back of last unprocessed length/lit */ unsigned was; /* initial length of match */ }; + diff --git a/common/zlib/inftrees.c b/common/zlib/inftrees.c index a3724254f..e5e4f8c4f 100644 --- a/common/zlib/inftrees.c +++ b/common/zlib/inftrees.c @@ -9,7 +9,11 @@ #define MAXBITS 15 const char inflate_copyright[] = +#ifdef ZLIB_PM3_TUNED " inflate 1.2.8.f-Proxmark3 Copyright 1995-2013 Mark Adler "; +#else + " inflate 1.2.8 Copyright 1995-2013 Mark Adler "; +#endif /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot @@ -300,3 +304,4 @@ int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens, *bits = root; return 0; } + diff --git a/common/zlib/inftrees.h b/common/zlib/inftrees.h index 01b1a5d75..33584c58d 100644 --- a/common/zlib/inftrees.h +++ b/common/zlib/inftrees.h @@ -60,3 +60,4 @@ typedef enum { int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens, unsigned codes, code FAR *FAR *table, unsigned FAR *bits, unsigned short FAR *work)); + diff --git a/common/zlib/trees.c b/common/zlib/trees.c index cc2d477cf..8ffab9c8e 100644 --- a/common/zlib/trees.c +++ b/common/zlib/trees.c @@ -32,16 +32,8 @@ /* @(#) $Id$ */ -//----------------------------------------------------------------------------- -// This version of zlib is modified for use within the Proxmark3 project. -// Files from the original distribution which are not required for this -// purpose are not included. All modifications can easily be found -// by searching for #ifdef ZLIB_PM3_TUNED and #ifndef ZLIB_PM3_TUNED. -//----------------------------------------------------------------------------- - /* #define GEN_TREES_H */ - #include "deflate.h" #ifdef DEBUG @@ -173,8 +165,8 @@ local void gen_trees_header OF((void)); #else /* DEBUG */ # define send_code(s, c, tree) \ - { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ - send_bits(s, tree[c].Code, tree[c].Len); } + { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ + send_bits(s, tree[c].Code, tree[c].Len); } #endif /* =========================================================================== @@ -182,9 +174,9 @@ local void gen_trees_header OF((void)); * IN assertion: there is enough room in pendingBuf. */ #define put_short(s, w) { \ - put_byte(s, (uch)((w) & 0xff)); \ - put_byte(s, (uch)((ush)(w) >> 8)); \ - } + put_byte(s, (uch)((w) & 0xff)); \ + put_byte(s, (uch)((ush)(w) >> 8)); \ +} /* =========================================================================== * Send a value on a given number of bits. @@ -219,18 +211,18 @@ int length; /* number of bits */ #else /* !DEBUG */ #define send_bits(s, value, length) \ - { int len = length;\ - if (s->bi_valid > (int)Buf_size - len) {\ - int val = value;\ - s->bi_buf |= (ush)val << s->bi_valid;\ - put_short(s, s->bi_buf);\ - s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ - s->bi_valid += len - Buf_size;\ - } else {\ - s->bi_buf |= (ush)(value) << s->bi_valid;\ - s->bi_valid += len;\ - }\ - } +{ int len = length;\ + if (s->bi_valid > (int)Buf_size - len) {\ + int val = value;\ + s->bi_buf |= (ush)val << s->bi_valid;\ + put_short(s, s->bi_buf);\ + s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ + s->bi_valid += len - Buf_size;\ + } else {\ + s->bi_buf |= (ush)(value) << s->bi_valid;\ + s->bi_valid += len;\ + }\ +} #endif /* DEBUG */ @@ -329,8 +321,8 @@ local void tr_static_init() { # endif # define SEPARATOR(i, last, width) \ - ((i) == (last)? "\n};\n\n" : \ - ((i) % (width) == (width)-1 ? ",\n" : ", ")) + ((i) == (last)? "\n};\n\n" : \ + ((i) % (width) == (width)-1 ? ",\n" : ", ")) void gen_trees_header() { FILE *header = fopen("trees.h", "w"); @@ -436,19 +428,19 @@ deflate_state *s; * one less element. Updates heap and heap_len. */ #define pqremove(s, tree, top) \ - {\ - top = s->heap[SMALLEST]; \ - s->heap[SMALLEST] = s->heap[s->heap_len--]; \ - pqdownheap(s, tree, SMALLEST); \ - } +{\ + top = s->heap[SMALLEST]; \ + s->heap[SMALLEST] = s->heap[s->heap_len--]; \ + pqdownheap(s, tree, SMALLEST); \ +} /* =========================================================================== * Compares to subtrees, using the tree depth as tie breaker when * the subtrees have equal frequency. This minimizes the worst case length. */ #define smaller(tree, n, m, depth) \ - (tree[n].Freq < tree[m].Freq || \ - (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) + (tree[n].Freq < tree[m].Freq || \ + (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) /* =========================================================================== * Restore the heap property by moving down the tree starting at node k, @@ -1021,7 +1013,8 @@ int last; /* one if this is the last block for a file */ s->compressed_len += 7; /* align on byte boundary */ #endif } - Tracev((stderr, "\ncomprlen %lu(%lu) ", s->compressed_len >> 3, s->compressed_len - 7 * last)); + Tracev((stderr, "\ncomprlen %lu(%lu) ", s->compressed_len >> 3, + s->compressed_len - 7 * last)); } /* =========================================================================== @@ -1245,3 +1238,4 @@ int header; /* true if block header must be written */ put_byte(s, *buf++); } } + diff --git a/common/zlib/trees.h b/common/zlib/trees.h index a02c374a7..74383d7c2 100644 --- a/common/zlib/trees.h +++ b/common/zlib/trees.h @@ -126,3 +126,4 @@ local const int base_dist[D_CODES] = { 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 }; + diff --git a/common/zlib/zconf.h b/common/zlib/zconf.h index d9bf35455..5230fc94b 100644 --- a/common/zlib/zconf.h +++ b/common/zlib/zconf.h @@ -509,3 +509,4 @@ typedef unsigned long z_crc_t; #endif #endif /* ZCONF_H */ + diff --git a/common/zlib/zlib.h b/common/zlib/zlib.h index 9a8bcce1d..b88bac965 100644 --- a/common/zlib/zlib.h +++ b/common/zlib/zlib.h @@ -28,13 +28,6 @@ (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format). */ -//----------------------------------------------------------------------------- -// This version of zlib is modified for use within the Proxmark3 project. -// Files from the original distribution which are not required for this -// purpose are not included. All modifications can easily be found -// by searching for #ifdef ZLIB_PM3_TUNED and #ifndef ZLIB_PM3_TUNED. -//----------------------------------------------------------------------------- - #ifndef ZLIB_H #define ZLIB_H @@ -1663,18 +1656,18 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, const char *version, int stream_size)); #define deflateInit(strm, level) \ - deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) + deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) #define inflateInit(strm) \ - inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) + inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) #define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ - deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ - (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) #define inflateInit2(strm, windowBits) \ - inflateInit2_((strm), (windowBits), ZLIB_VERSION, \ - (int)sizeof(z_stream)) + inflateInit2_((strm), (windowBits), ZLIB_VERSION, \ + (int)sizeof(z_stream)) #define inflateBackInit(strm, windowBits, window) \ - inflateBackInit_((strm), (windowBits), (window), \ - ZLIB_VERSION, (int)sizeof(z_stream)) + inflateBackInit_((strm), (windowBits), (window), \ + ZLIB_VERSION, (int)sizeof(z_stream)) #ifndef Z_SOLO @@ -1694,10 +1687,10 @@ ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */ #ifdef Z_PREFIX_SET # undef z_gzgetc # define z_gzgetc(g) \ - ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g)) + ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g)) #else # define gzgetc(g) \ - ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g)) + ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g)) #endif /* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or @@ -1784,3 +1777,4 @@ ZEXTERN int ZEXPORTVA gzvprintf Z_ARG((gzFile file, #endif #endif /* ZLIB_H */ + diff --git a/common/zlib/zutil.c b/common/zlib/zutil.c index 72d373982..30f453872 100644 --- a/common/zlib/zutil.c +++ b/common/zlib/zutil.c @@ -341,3 +341,4 @@ voidpf ptr; #endif /* MY_ZCALLOC */ #endif /* !Z_SOLO */ + diff --git a/common/zlib/zutil.h b/common/zlib/zutil.h index 1f6bee84e..a421df882 100644 --- a/common/zlib/zutil.h +++ b/common/zlib/zutil.h @@ -50,7 +50,7 @@ extern z_const char *const z_errmsg[10]; /* indexed by 2-zlib_error */ #define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] #define ERR_RETURN(strm,err) \ - return (strm->msg = ERR_MSG(err), (err)) + return (strm->msg = ERR_MSG(err), (err)) /* To be used only when the state is known to be valid */ /* common constants */ @@ -104,7 +104,7 @@ void *_Cdecl farmalloc(unsigned long nbytes); #if defined(VAXC) || defined(VMS) # define OS_CODE 0x02 # define F_OPEN(name, mode) \ - fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") + fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") #endif #if defined(ATARI) || defined(atarist) @@ -242,7 +242,7 @@ void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr)); #endif #define ZALLOC(strm, items, size) \ - (*((strm)->zalloc))((strm)->opaque, (items), (size)) + (*((strm)->zalloc))((strm)->opaque, (items), (size)) #define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) #define TRY_FREE(s, p) {if (p) ZFREE(s, p);} @@ -251,3 +251,4 @@ void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr)); (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) #endif /* ZUTIL_H */ + From 26ccdf5ce22fe9b6635f877016e06a678f77a2b2 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 22 Sep 2019 18:16:45 +0200 Subject: [PATCH 0756/1854] Update zlib to 1.2.11 --- common/zlib/ChangeLog | 55 ++- common/zlib/README | 6 +- common/zlib/README_proxmark3 | 48 +- common/zlib/adler32.c | 21 +- common/zlib/deflate.c | 854 +++++++++++++++++++++-------------- common/zlib/deflate.h | 35 +- common/zlib/inffast.c | 85 ++-- common/zlib/inflate.c | 121 +++-- common/zlib/inflate.h | 11 +- common/zlib/inftrees.c | 28 +- common/zlib/trees.c | 99 ++-- common/zlib/zconf.h | 41 +- common/zlib/zlib.h | 450 +++++++++++------- common/zlib/zutil.c | 48 +- common/zlib/zutil.h | 52 ++- 15 files changed, 1222 insertions(+), 732 deletions(-) diff --git a/common/zlib/ChangeLog b/common/zlib/ChangeLog index f22aabaef..30199a65a 100644 --- a/common/zlib/ChangeLog +++ b/common/zlib/ChangeLog @@ -1,10 +1,53 @@ ChangeLog file for zlib +Changes in 1.2.11 (15 Jan 2017) +- Fix deflate stored bug when pulling last block from window +- Permit immediate deflateParams changes before any deflate input + +Changes in 1.2.10 (2 Jan 2017) +- Avoid warnings on snprintf() return value +- Fix bug in deflate_stored() for zero-length input +- Fix bug in gzwrite.c that produced corrupt gzip files +- Remove files to be installed before copying them in Makefile.in +- Add warnings when compiling with assembler code + +Changes in 1.2.9 (31 Dec 2016) +- Fix contrib/minizip to permit unzipping with desktop API [Zouzou] +- Improve contrib/blast to return unused bytes +- Assure that gzoffset() is correct when appending +- Improve compress() and uncompress() to support large lengths +- Fix bug in test/example.c where error code not saved +- Remedy Coverity warning [Randers-Pehrson] +- Improve speed of gzprintf() in transparent mode +- Fix inflateInit2() bug when windowBits is 16 or 32 +- Change DEBUG macro to ZLIB_DEBUG +- Avoid uninitialized access by gzclose_w() +- Allow building zlib outside of the source directory +- Fix bug that accepted invalid zlib header when windowBits is zero +- Fix gzseek() problem on MinGW due to buggy _lseeki64 there +- Loop on write() calls in gzwrite.c in case of non-blocking I/O +- Add --warn (-w) option to ./configure for more compiler warnings +- Reject a window size of 256 bytes if not using the zlib wrapper +- Fix bug when level 0 used with Z_HUFFMAN or Z_RLE +- Add --debug (-d) option to ./configure to define ZLIB_DEBUG +- Fix bugs in creating a very large gzip header +- Add uncompress2() function, which returns the input size used +- Assure that deflateParams() will not switch functions mid-block +- Dramatically speed up deflation for level 0 (storing) +- Add gzfread(), duplicating the interface of fread() +- Add gzfwrite(), duplicating the interface of fwrite() +- Add deflateGetDictionary() function +- Use snprintf() for later versions of Microsoft C +- Fix *Init macros to use z_ prefix when requested +- Replace as400 with os400 for OS/400 support [Monnerat] +- Add crc32_z() and adler32_z() functions with size_t lengths +- Update Visual Studio project files [AraHaan] + Changes in 1.2.8 (28 Apr 2013) - Update contrib/minizip/iowin32.c for Windows RT [Vollant] - Do not force Z_CONST for C++ -- Clean up contrib/vstudio [Ro] +- Clean up contrib/vstudio [Roß] - Correct spelling error in zlib.h - Fix mixed line endings in contrib/vstudio @@ -34,7 +77,7 @@ Changes in 1.2.7.1 (24 Mar 2013) - Clean up the usage of z_const and respect const usage within zlib - Clean up examples/gzlog.[ch] comparisons of different types - Avoid shift equal to bits in type (caused endless loop) -- Fix unintialized value bug in gzputc() introduced by const patches +- Fix uninitialized value bug in gzputc() introduced by const patches - Fix memory allocation error in examples/zran.c [Nor] - Fix bug where gzopen(), gzclose() would write an empty file - Fix bug in gzclose() when gzwrite() runs out of memory @@ -194,7 +237,7 @@ Changes in 1.2.5.2 (17 Dec 2011) - Add a transparent write mode to gzopen() when 'T' is in the mode - Update python link in zlib man page - Get inffixed.h and MAKEFIXED result to match -- Add a ./config --solo option to make zlib subset with no libary use +- Add a ./config --solo option to make zlib subset with no library use - Add undocumented inflateResetKeep() function for CAB file decoding - Add --cover option to ./configure for gcc coverage testing - Add #define ZLIB_CONST option to use const in the z_stream interface @@ -564,7 +607,7 @@ Changes in 1.2.3.1 (16 August 2006) - Update make_vms.com [Zinser] - Use -fPIC for shared build in configure [Teredesai, Nicholson] - Use only major version number for libz.so on IRIX and OSF1 [Reinholdtsen] -- Use fdopen() (not _fdopen()) for Interix in zutil.h [Bck] +- Use fdopen() (not _fdopen()) for Interix in zutil.h [Bäck] - Add some FAQ entries about the contrib directory - Update the MVS question in the FAQ - Avoid extraneous reads after EOF in gzio.c [Brown] @@ -1178,7 +1221,7 @@ Changes in 1.0.6 (19 Jan 1998) 386 asm code replacing longest_match(). contrib/iostream/ by Kevin Ruland A C++ I/O streams interface to the zlib gz* functions - contrib/iostream2/ by Tyge Lvset + contrib/iostream2/ by Tyge Løvset Another C++ I/O streams interface contrib/untgz/ by "Pedro A. Aranda Guti\irrez" A very simple tar.gz file extractor using zlib @@ -1267,7 +1310,7 @@ Changes in 1.0.1 (20 May 96) [1.0 skipped to avoid confusion] - fix array overlay in deflate.c which sometimes caused bad compressed data - fix inflate bug with empty stored block - fix MSDOS medium model which was broken in 0.99 -- fix deflateParams() which could generated bad compressed data. +- fix deflateParams() which could generate bad compressed data. - Bytef is define'd instead of typedef'ed (work around Borland bug) - added an INDEX file - new makefiles for DJGPP (Makefile.dj2), 32-bit Borland (Makefile.b32), diff --git a/common/zlib/README b/common/zlib/README index 5ca9d127e..51106de47 100644 --- a/common/zlib/README +++ b/common/zlib/README @@ -1,6 +1,6 @@ ZLIB DATA COMPRESSION LIBRARY -zlib 1.2.8 is a general purpose data compression library. All the code is +zlib 1.2.11 is a general purpose data compression library. All the code is thread safe. The data format used by the zlib library is described by RFCs (Request for Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950 (zlib format), rfc1951 (deflate format) and @@ -31,7 +31,7 @@ Mark Nelson wrote an article about zlib for the Jan. 1997 issue of Dr. Dobb's Journal; a copy of the article is available at http://marknelson.us/1997/01/01/zlib-engine/ . -The changes made in version 1.2.8 are documented in the file ChangeLog. +The changes made in version 1.2.11 are documented in the file ChangeLog. Unsupported third party contributions are provided in directory contrib/ . @@ -84,7 +84,7 @@ Acknowledgments: Copyright notice: - (C) 1995-2013 Jean-loup Gailly and Mark Adler + (C) 1995-2017 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/common/zlib/README_proxmark3 b/common/zlib/README_proxmark3 index d3192f199..0c7babf57 100644 --- a/common/zlib/README_proxmark3 +++ b/common/zlib/README_proxmark3 @@ -3,12 +3,14 @@ Files from the original distribution which are not required for this purpose are not included. All modifications can easily be found by searching for #ifdef ZLIB_PM3_TUNED and #ifndef ZLIB_PM3_TUNED. -Current zlib base version is 1.2.8 - +Current zlib base version is 1.2.11 ChangeLog for Proxmark3 project only ------------------------------------ +Changes in 1.2.11.f-Proxmark3 (26 May 2015) +- port 1.2.11 upstream changes to 1.2.8.f-Proxmark3 + Changes in 1.2.8.f-Proxmark3 (26 May 2015) - disable decoding of fixed code blocks in deflate (eliminates the need to store the fixed tree in RAM or ROM) @@ -17,3 +19,45 @@ Changes in 1.2.8.f-Proxmark3 (26 May 2015) in inflate. - stripped down version - unnecessary files from original distribution are not included + +Notes on porting 1.2.11 upstream changes to 1.2.8.f-Proxmark3 +------------------------------------------------------------- + +mkdir zlib-1.2.8-stripped +for f in adler32.c ChangeLog deflate.c deflate.h FAQ inffast.c inffast.h inffixed.h inflate.c inflate.h inftrees.c inftrees.h README trees.c trees.h zconf.h zlib.h zutil.c zutil.h; do + cp zlib-1.2.8/$f zlib-1.2.8-stripped +done +# make style +find zlib-1.2.8-stripped -name "*.[ch]" \ + -exec perl -pi -e 's/[ \t]+$$//' {} \; \ + -exec sh -c "tail -c1 {} | xxd -p | tail -1 | grep -q -v 0a$$" \; \ + -exec sh -c "echo >> {}" \; \ + -exec astyle --formatted --mode=c --suffix=none \ + --indent=spaces=4 --indent-switches \ + --keep-one-line-blocks --max-instatement-indent=60 \ + --style=google --pad-oper --unpad-paren --pad-header \ + --align-pointer=name {} \; +diff -Naur zlib-1.2.8-stripped zlib > zlib-1.2.8-pm3.diff + +mkdir zlib-1.2.11-stripped +for f in adler32.c ChangeLog deflate.c deflate.h FAQ inffast.c inffast.h inffixed.h inflate.c inflate.h inftrees.c inftrees.h README trees.c trees.h zconf.h zlib.h zutil.c zutil.h; do + cp zlib-1.2.11/$f zlib-1.2.11-stripped +done +# make style +find zlib-1.2.11-stripped -name "*.[ch]" \ + -exec perl -pi -e 's/[ \t]+$$//' {} \; \ + -exec sh -c "tail -c1 {} | xxd -p | tail -1 | grep -q -v 0a$$" \; \ + -exec sh -c "echo >> {}" \; \ + -exec astyle --formatted --mode=c --suffix=none \ + --indent=spaces=4 --indent-switches \ + --keep-one-line-blocks --max-instatement-indent=60 \ + --style=google --pad-oper --unpad-paren --pad-header \ + --align-pointer=name {} \; + +diff -Naur zlib-1.2.8-stripped zlib-1.2.11-stripped > zlib-1.2.8-to-1.2.11.diff + +cd zlib +patch -p1 < ../zlib-1.2.8-to-1.2.11.diff +# fix .rej files manually... + +diff -Naur zlib-1.2.11-stripped zlib > zlib-1.2.11-pm3.diff diff --git a/common/zlib/adler32.c b/common/zlib/adler32.c index a3e96f949..962e1ee91 100644 --- a/common/zlib/adler32.c +++ b/common/zlib/adler32.c @@ -1,5 +1,5 @@ /* adler32.c -- compute the Adler-32 checksum of a data stream - * Copyright (C) 1995-2011 Mark Adler + * Copyright (C) 1995-2011, 2016 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -7,11 +7,9 @@ #include "zutil.h" -#define local static - local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2)); -#define BASE 65521 /* largest prime smaller than 65536 */ +#define BASE 65521U /* largest prime smaller than 65536 */ #define NMAX 5552 /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ @@ -62,10 +60,10 @@ local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2)); #endif /* ========================================================================= */ -uLong ZEXPORT adler32(adler, buf, len) +uLong ZEXPORT adler32_z(adler, buf, len) uLong adler; const Bytef *buf; -uInt len; +z_size_t len; { unsigned long sum2; unsigned n; @@ -132,6 +130,15 @@ uInt len; return adler | (sum2 << 16); } +/* ========================================================================= */ +uLong ZEXPORT adler32(adler, buf, len) +uLong adler; +const Bytef *buf; +uInt len; +{ + return adler32_z(adler, buf, len); +} + /* ========================================================================= */ local uLong adler32_combine_(adler1, adler2, len2) uLong adler1; @@ -156,7 +163,7 @@ z_off64_t len2; sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; if (sum1 >= BASE) sum1 -= BASE; if (sum1 >= BASE) sum1 -= BASE; - if (sum2 >= (BASE << 1)) sum2 -= (BASE << 1); + if (sum2 >= ((unsigned long)BASE << 1)) sum2 -= ((unsigned long)BASE << 1); if (sum2 >= BASE) sum2 -= BASE; return sum1 | (sum2 << 16); } diff --git a/common/zlib/deflate.c b/common/zlib/deflate.c index 7445d5907..f63751eed 100644 --- a/common/zlib/deflate.c +++ b/common/zlib/deflate.c @@ -1,5 +1,5 @@ /* deflate.c -- compress data using the deflation algorithm - * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler + * Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -53,9 +53,9 @@ const char deflate_copyright[] = #ifdef ZLIB_PM3_TUNED - " deflate 1.2.8.f-Proxmark3 Copyright 1995-2013 Jean-loup Gailly and Mark Adler "; + " deflate 1.2.11.f-Proxmark3 Copyright 1995-2017 Jean-loup Gailly and Mark Adler "; #else - " deflate 1.2.8 Copyright 1995-2013 Jean-loup Gailly and Mark Adler "; + " deflate 1.2.11 Copyright 1995-2017 Jean-loup Gailly and Mark Adler "; #endif /* If you use the zlib library in a product, an acknowledgment is welcome @@ -77,6 +77,8 @@ typedef enum { typedef block_state(*compress_func) OF((deflate_state *s, int flush)); /* Compression function. Returns the block state after the call. */ +local int deflateStateCheck OF((z_streamp strm)); +local void slide_hash OF((deflate_state *s)); local void fill_window OF((deflate_state *s)); local block_state deflate_stored OF((deflate_state *s, int flush)); local block_state deflate_fast OF((deflate_state *s, int flush)); @@ -88,15 +90,16 @@ local block_state deflate_huff OF((deflate_state *s, int flush)); local void lm_init OF((deflate_state *s)); local void putShortMSB OF((deflate_state *s, uInt b)); local void flush_pending OF((z_streamp strm)); -local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); +local unsigned read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); #ifdef ASMV +# pragma message("Assembler code may have bugs -- use at your own risk") void match_init OF((void)); /* asm code initialization */ uInt longest_match OF((deflate_state *s, IPos cur_match)); #else local uInt longest_match OF((deflate_state *s, IPos cur_match)); #endif -#ifdef DEBUG +#ifdef ZLIB_DEBUG local void check_match OF((deflate_state *s, IPos start, IPos match, int length)); #endif @@ -154,21 +157,14 @@ local const config configuration_table[10] = { * meaning. */ -#define EQUAL 0 -/* result of memcmp for equal strings */ - -#ifndef NO_DUMMY_DECL -struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ -#endif - /* rank Z_BLOCK between Z_NO_FLUSH and Z_PARTIAL_FLUSH */ -#define RANK(f) (((f) << 1) - ((f) > 4 ? 9 : 0)) +#define RANK(f) (((f) * 2) - ((f) > 4 ? 9 : 0)) /* =========================================================================== * Update a hash value with the given input byte - * IN assertion: all calls to to UPDATE_HASH are made with consecutive - * input characters, so that a running hash key can be computed from the - * previous key instead of complete recalculation each time. + * IN assertion: all calls to UPDATE_HASH are made with consecutive input + * characters, so that a running hash key can be computed from the previous + * key instead of complete recalculation each time. */ #define UPDATE_HASH(s,h,c) (h = (((h)<hash_shift) ^ (c)) & s->hash_mask) @@ -179,9 +175,9 @@ struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ * the previous length of the hash chain. * If this file is compiled with -DFASTEST, the compression level is forced * to 1, and no hash chains are maintained. - * IN assertion: all calls to to INSERT_STRING are made with consecutive - * input characters and the first MIN_MATCH bytes of str are valid - * (except for the last MIN_MATCH-1 bytes of the input file). + * IN assertion: all calls to INSERT_STRING are made with consecutive input + * characters and the first MIN_MATCH bytes of str are valid (except for + * the last MIN_MATCH-1 bytes of the input file). */ #ifdef FASTEST #define INSERT_STRING(s, str, match_head) \ @@ -203,6 +199,37 @@ struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ s->head[s->hash_size-1] = NIL; \ zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); +/* =========================================================================== + * Slide the hash table when sliding the window down (could be avoided with 32 + * bit values at the expense of memory usage). We slide even when level == 0 to + * keep the hash table consistent if we switch back to level > 0 later. + */ +local void slide_hash(s) +deflate_state *s; +{ + unsigned n, m; + Posf *p; + uInt wsize = s->w_size; + + n = s->hash_size; + p = &s->head[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m - wsize : NIL); + } while (--n); + n = wsize; +#ifndef FASTEST + p = &s->prev[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m - wsize : NIL); + /* If n is not on any hash chain, prev[n] is garbage but + * its value will never be used. + */ + } while (--n); +#endif +} + /* ========================================================================= */ int ZEXPORT deflateInit_(strm, level, version, stream_size) z_streamp strm; @@ -276,7 +303,7 @@ int stream_size; #endif if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || - strategy < 0 || strategy > Z_FIXED) { + strategy < 0 || strategy > Z_FIXED || (windowBits == 8 && wrap != 1)) { return Z_STREAM_ERROR; } if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */ @@ -284,14 +311,15 @@ int stream_size; if (s == Z_NULL) return Z_MEM_ERROR; strm->state = (struct internal_state FAR *)s; s->strm = strm; + s->status = INIT_STATE; /* to pass state test in deflateReset() */ s->wrap = wrap; s->gzhead = Z_NULL; - s->w_bits = windowBits; + s->w_bits = (uInt)windowBits; s->w_size = 1 << s->w_bits; s->w_mask = s->w_size - 1; - s->hash_bits = memLevel + 7; + s->hash_bits = (uInt)memLevel + 7; s->hash_size = 1 << s->hash_bits; s->hash_mask = s->hash_size - 1; s->hash_shift = ((s->hash_bits + MIN_MATCH - 1) / MIN_MATCH); @@ -325,6 +353,31 @@ int stream_size; return deflateReset(strm); } +/* ========================================================================= + * Check for a valid deflate stream state. Return 0 if ok, 1 if not. + */ +local int deflateStateCheck(strm) +z_streamp strm; +{ + deflate_state *s; + if (strm == Z_NULL || + strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) + return 1; + s = strm->state; + if (s == Z_NULL || s->strm != strm || (s->status != INIT_STATE && +#ifdef GZIP + s->status != GZIP_STATE && +#endif + s->status != EXTRA_STATE && + s->status != NAME_STATE && + s->status != COMMENT_STATE && + s->status != HCRC_STATE && + s->status != BUSY_STATE && + s->status != FINISH_STATE)) + return 1; + return 0; +} + /* ========================================================================= */ int ZEXPORT deflateSetDictionary(strm, dictionary, dictLength) z_streamp strm; @@ -337,7 +390,7 @@ uInt dictLength; unsigned avail; z_const unsigned char *next; - if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL) + if (deflateStateCheck(strm) || dictionary == Z_NULL) return Z_STREAM_ERROR; s = strm->state; wrap = s->wrap; @@ -394,14 +447,35 @@ uInt dictLength; return Z_OK; } +/* ========================================================================= */ +int ZEXPORT deflateGetDictionary(strm, dictionary, dictLength) +z_streamp strm; +Bytef *dictionary; +uInt *dictLength; +{ + deflate_state *s; + uInt len; + + if (deflateStateCheck(strm)) + return Z_STREAM_ERROR; + s = strm->state; + len = s->strstart + s->lookahead; + if (len > s->w_size) + len = s->w_size; + if (dictionary != Z_NULL && len) + zmemcpy(dictionary, s->window + s->strstart + s->lookahead - len, len); + if (dictLength != Z_NULL) + *dictLength = len; + return Z_OK; +} + /* ========================================================================= */ int ZEXPORT deflateResetKeep(strm) z_streamp strm; { deflate_state *s; - if (strm == Z_NULL || strm->state == Z_NULL || - strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) { + if (deflateStateCheck(strm)) { return Z_STREAM_ERROR; } @@ -416,7 +490,11 @@ z_streamp strm; if (s->wrap < 0) { s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ } - s->status = s->wrap ? INIT_STATE : BUSY_STATE; + s->status = +#ifdef GZIP + s->wrap == 2 ? GZIP_STATE : +#endif + s->wrap ? INIT_STATE : BUSY_STATE; strm->adler = #ifdef GZIP s->wrap == 2 ? crc32(0L, Z_NULL, 0) : @@ -446,8 +524,8 @@ int ZEXPORT deflateSetHeader(strm, head) z_streamp strm; gz_headerp head; { - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - if (strm->state->wrap != 2) return Z_STREAM_ERROR; + if (deflateStateCheck(strm) || strm->state->wrap != 2) + return Z_STREAM_ERROR; strm->state->gzhead = head; return Z_OK; } @@ -458,7 +536,7 @@ unsigned *pending; int *bits; z_streamp strm; { - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + if (deflateStateCheck(strm)) return Z_STREAM_ERROR; if (pending != Z_NULL) *pending = strm->state->pending; if (bits != Z_NULL) @@ -475,7 +553,7 @@ int value; deflate_state *s; int put; - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + if (deflateStateCheck(strm)) return Z_STREAM_ERROR; s = strm->state; if ((Bytef *)(s->d_buf) < s->pending_out + ((Buf_size + 7) >> 3)) return Z_BUF_ERROR; @@ -500,9 +578,8 @@ int strategy; { deflate_state *s; compress_func func; - int err = Z_OK; - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + if (deflateStateCheck(strm)) return Z_STREAM_ERROR; s = strm->state; #ifdef FASTEST @@ -516,13 +593,22 @@ int strategy; func = configuration_table[s->level].func; if ((strategy != s->strategy || func != configuration_table[level].func) && - strm->total_in != 0) { + s->high_water) { /* Flush the last buffer: */ - err = deflate(strm, Z_BLOCK); - if (err == Z_BUF_ERROR && s->pending == 0) - err = Z_OK; + int err = deflate(strm, Z_BLOCK); + if (err == Z_STREAM_ERROR) + return err; + if (strm->avail_out == 0) + return Z_BUF_ERROR; } if (s->level != level) { + if (s->level == 0 && s->matches != 0) { + if (s->matches == 1) + slide_hash(s); + else + CLEAR_HASH(s); + s->matches = 0; + } s->level = level; s->max_lazy_match = configuration_table[level].max_lazy; s->good_match = configuration_table[level].good_length; @@ -530,7 +616,7 @@ int strategy; s->max_chain_length = configuration_table[level].max_chain; } s->strategy = strategy; - return err; + return Z_OK; } /* ========================================================================= */ @@ -543,12 +629,12 @@ int max_chain; { deflate_state *s; - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + if (deflateStateCheck(strm)) return Z_STREAM_ERROR; s = strm->state; - s->good_match = good_length; - s->max_lazy_match = max_lazy; + s->good_match = (uInt)good_length; + s->max_lazy_match = (uInt)max_lazy; s->nice_match = nice_length; - s->max_chain_length = max_chain; + s->max_chain_length = (uInt)max_chain; return Z_OK; } @@ -575,14 +661,13 @@ uLong sourceLen; { deflate_state *s; uLong complen, wraplen; - Bytef *str; /* conservative upper bound for compressed data */ complen = sourceLen + ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5; /* if can't get parameters, return conservative bound plus zlib wrapper */ - if (strm == Z_NULL || strm->state == Z_NULL) + if (deflateStateCheck(strm)) return complen + 6; /* compute wrapper length */ @@ -594,9 +679,11 @@ uLong sourceLen; case 1: /* zlib wrapper */ wraplen = 6 + (s->strstart ? 4 : 0); break; +#ifdef GZIP case 2: /* gzip wrapper */ wraplen = 18; if (s->gzhead != Z_NULL) { /* user-supplied gzip header */ + Bytef *str; if (s->gzhead->extra != Z_NULL) wraplen += 2 + s->gzhead->extra_len; str = s->gzhead->name; @@ -613,6 +700,7 @@ uLong sourceLen; wraplen += 2; } break; +#endif default: /* for compiler happiness */ wraplen = 6; } @@ -640,10 +728,10 @@ uInt b; } /* ========================================================================= - * Flush as much pending output as possible. All deflate() output goes - * through this function so some applications may wish to modify it - * to avoid allocating a large strm->next_out buffer and copying into it. - * (See also read_buf()). + * Flush as much pending output as possible. All deflate() output, except for + * some deflate_stored() output, goes through this function so some + * applications may wish to modify it to avoid allocating a large + * strm->next_out buffer and copying into it. (See also read_buf()). */ local void flush_pending(strm) z_streamp strm; @@ -660,13 +748,23 @@ z_streamp strm; strm->next_out += len; s->pending_out += len; strm->total_out += len; - strm->avail_out -= len; - s->pending -= len; + strm->avail_out -= len; + s->pending -= len; if (s->pending == 0) { s->pending_out = s->pending_buf; } } +/* =========================================================================== + * Update the header CRC with the bytes s->pending_buf[beg..s->pending - 1]. + */ +#define HCRC_UPDATE(beg) \ + do { \ + if (s->gzhead->hcrc && s->pending > (beg)) \ + strm->adler = crc32(strm->adler, s->pending_buf + (beg), \ + s->pending - (beg)); \ + } while (0) + /* ========================================================================= */ int ZEXPORT deflate(strm, flush) z_streamp strm; @@ -675,197 +773,21 @@ int flush; int old_flush; /* value of flush param for previous deflate call */ deflate_state *s; - if (strm == Z_NULL || strm->state == Z_NULL || - flush > Z_BLOCK || flush < 0) { + if (deflateStateCheck(strm) || flush > Z_BLOCK || flush < 0) { return Z_STREAM_ERROR; } s = strm->state; if (strm->next_out == Z_NULL || - (strm->next_in == Z_NULL && strm->avail_in != 0) || + (strm->avail_in != 0 && strm->next_in == Z_NULL) || (s->status == FINISH_STATE && flush != Z_FINISH)) { ERR_RETURN(strm, Z_STREAM_ERROR); } if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); - s->strm = strm; /* just in case */ old_flush = s->last_flush; s->last_flush = flush; - /* Write the header */ - if (s->status == INIT_STATE) { -#ifdef GZIP - if (s->wrap == 2) { - strm->adler = crc32(0L, Z_NULL, 0); - put_byte(s, 31); - put_byte(s, 139); - put_byte(s, 8); - if (s->gzhead == Z_NULL) { - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, s->level == 9 ? 2 : - (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? - 4 : 0)); - put_byte(s, OS_CODE); - s->status = BUSY_STATE; - } else { - put_byte(s, (s->gzhead->text ? 1 : 0) + - (s->gzhead->hcrc ? 2 : 0) + - (s->gzhead->extra == Z_NULL ? 0 : 4) + - (s->gzhead->name == Z_NULL ? 0 : 8) + - (s->gzhead->comment == Z_NULL ? 0 : 16) - ); - put_byte(s, (Byte)(s->gzhead->time & 0xff)); - put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff)); - put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff)); - put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff)); - put_byte(s, s->level == 9 ? 2 : - (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? - 4 : 0)); - put_byte(s, s->gzhead->os & 0xff); - if (s->gzhead->extra != Z_NULL) { - put_byte(s, s->gzhead->extra_len & 0xff); - put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); - } - if (s->gzhead->hcrc) - strm->adler = crc32(strm->adler, s->pending_buf, - s->pending); - s->gzindex = 0; - s->status = EXTRA_STATE; - } - } else -#endif - { - uInt header = (Z_DEFLATED + ((s->w_bits - 8) << 4)) << 8; - uInt level_flags; - - if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) - level_flags = 0; - else if (s->level < 6) - level_flags = 1; - else if (s->level == 6) - level_flags = 2; - else - level_flags = 3; - header |= (level_flags << 6); - if (s->strstart != 0) header |= PRESET_DICT; - header += 31 - (header % 31); - - s->status = BUSY_STATE; - putShortMSB(s, header); - - /* Save the adler32 of the preset dictionary: */ - if (s->strstart != 0) { - putShortMSB(s, (uInt)(strm->adler >> 16)); - putShortMSB(s, (uInt)(strm->adler & 0xffff)); - } - strm->adler = adler32(0L, Z_NULL, 0); - } - } -#ifdef GZIP - if (s->status == EXTRA_STATE) { - if (s->gzhead->extra != Z_NULL) { - uInt beg = s->pending; /* start of bytes to update crc */ - - while (s->gzindex < (s->gzhead->extra_len & 0xffff)) { - if (s->pending == s->pending_buf_size) { - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - flush_pending(strm); - beg = s->pending; - if (s->pending == s->pending_buf_size) - break; - } - put_byte(s, s->gzhead->extra[s->gzindex]); - s->gzindex++; - } - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - if (s->gzindex == s->gzhead->extra_len) { - s->gzindex = 0; - s->status = NAME_STATE; - } - } else - s->status = NAME_STATE; - } - if (s->status == NAME_STATE) { - if (s->gzhead->name != Z_NULL) { - uInt beg = s->pending; /* start of bytes to update crc */ - int val; - - do { - if (s->pending == s->pending_buf_size) { - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - flush_pending(strm); - beg = s->pending; - if (s->pending == s->pending_buf_size) { - val = 1; - break; - } - } - val = s->gzhead->name[s->gzindex++]; - put_byte(s, val); - } while (val != 0); - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - if (val == 0) { - s->gzindex = 0; - s->status = COMMENT_STATE; - } - } else - s->status = COMMENT_STATE; - } - if (s->status == COMMENT_STATE) { - if (s->gzhead->comment != Z_NULL) { - uInt beg = s->pending; /* start of bytes to update crc */ - int val; - - do { - if (s->pending == s->pending_buf_size) { - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - flush_pending(strm); - beg = s->pending; - if (s->pending == s->pending_buf_size) { - val = 1; - break; - } - } - val = s->gzhead->comment[s->gzindex++]; - put_byte(s, val); - } while (val != 0); - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - if (val == 0) - s->status = HCRC_STATE; - } else - s->status = HCRC_STATE; - } - if (s->status == HCRC_STATE) { - if (s->gzhead->hcrc) { - if (s->pending + 2 > s->pending_buf_size) - flush_pending(strm); - if (s->pending + 2 <= s->pending_buf_size) { - put_byte(s, (Byte)(strm->adler & 0xff)); - put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); - strm->adler = crc32(0L, Z_NULL, 0); - s->status = BUSY_STATE; - } - } else - s->status = BUSY_STATE; - } -#endif - /* Flush as much pending output as possible */ if (s->pending != 0) { flush_pending(strm); @@ -894,15 +816,196 @@ int flush; ERR_RETURN(strm, Z_BUF_ERROR); } + /* Write the header */ + if (s->status == INIT_STATE) { + /* zlib header */ + uInt header = (Z_DEFLATED + ((s->w_bits - 8) << 4)) << 8; + uInt level_flags; + + if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) + level_flags = 0; + else if (s->level < 6) + level_flags = 1; + else if (s->level == 6) + level_flags = 2; + else + level_flags = 3; + header |= (level_flags << 6); + if (s->strstart != 0) header |= PRESET_DICT; + header += 31 - (header % 31); + + putShortMSB(s, header); + + /* Save the adler32 of the preset dictionary: */ + if (s->strstart != 0) { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } + strm->adler = adler32(0L, Z_NULL, 0); + s->status = BUSY_STATE; + + /* Compression must start with an empty pending buffer */ + flush_pending(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + } +#ifdef GZIP + if (s->status == GZIP_STATE) { + /* gzip header */ + strm->adler = crc32(0L, Z_NULL, 0); + put_byte(s, 31); + put_byte(s, 139); + put_byte(s, 8); + if (s->gzhead == Z_NULL) { + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, s->level == 9 ? 2 : + (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? + 4 : 0)); + put_byte(s, OS_CODE); + s->status = BUSY_STATE; + + /* Compression must start with an empty pending buffer */ + flush_pending(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + } else { + put_byte(s, (s->gzhead->text ? 1 : 0) + + (s->gzhead->hcrc ? 2 : 0) + + (s->gzhead->extra == Z_NULL ? 0 : 4) + + (s->gzhead->name == Z_NULL ? 0 : 8) + + (s->gzhead->comment == Z_NULL ? 0 : 16) + ); + put_byte(s, (Byte)(s->gzhead->time & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff)); + put_byte(s, s->level == 9 ? 2 : + (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? + 4 : 0)); + put_byte(s, s->gzhead->os & 0xff); + if (s->gzhead->extra != Z_NULL) { + put_byte(s, s->gzhead->extra_len & 0xff); + put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); + } + if (s->gzhead->hcrc) + strm->adler = crc32(strm->adler, s->pending_buf, + s->pending); + s->gzindex = 0; + s->status = EXTRA_STATE; + } + } + if (s->status == EXTRA_STATE) { + if (s->gzhead->extra != Z_NULL) { + ulg beg = s->pending; /* start of bytes to update crc */ + uInt left = (s->gzhead->extra_len & 0xffff) - s->gzindex; + while (s->pending + left > s->pending_buf_size) { + uInt copy = s->pending_buf_size - s->pending; + zmemcpy(s->pending_buf + s->pending, + s->gzhead->extra + s->gzindex, copy); + s->pending = s->pending_buf_size; + HCRC_UPDATE(beg); + s->gzindex += copy; + flush_pending(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + beg = 0; + left -= copy; + } + zmemcpy(s->pending_buf + s->pending, + s->gzhead->extra + s->gzindex, left); + s->pending += left; + HCRC_UPDATE(beg); + s->gzindex = 0; + } + s->status = NAME_STATE; + } + if (s->status == NAME_STATE) { + if (s->gzhead->name != Z_NULL) { + ulg beg = s->pending; /* start of bytes to update crc */ + int val; + do { + if (s->pending == s->pending_buf_size) { + HCRC_UPDATE(beg); + flush_pending(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + beg = 0; + } + val = s->gzhead->name[s->gzindex++]; + put_byte(s, val); + } while (val != 0); + HCRC_UPDATE(beg); + s->gzindex = 0; + } + s->status = COMMENT_STATE; + } + if (s->status == COMMENT_STATE) { + if (s->gzhead->comment != Z_NULL) { + ulg beg = s->pending; /* start of bytes to update crc */ + int val; + do { + if (s->pending == s->pending_buf_size) { + HCRC_UPDATE(beg); + flush_pending(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + beg = 0; + } + val = s->gzhead->comment[s->gzindex++]; + put_byte(s, val); + } while (val != 0); + HCRC_UPDATE(beg); + } + s->status = HCRC_STATE; + } + if (s->status == HCRC_STATE) { + if (s->gzhead->hcrc) { + if (s->pending + 2 > s->pending_buf_size) { + flush_pending(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + } + put_byte(s, (Byte)(strm->adler & 0xff)); + put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); + strm->adler = crc32(0L, Z_NULL, 0); + } + s->status = BUSY_STATE; + + /* Compression must start with an empty pending buffer */ + flush_pending(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + } +#endif + /* Start a new block or continue the current one. */ if (strm->avail_in != 0 || s->lookahead != 0 || (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { block_state bstate; - bstate = s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) : - (s->strategy == Z_RLE ? deflate_rle(s, flush) : - (*(configuration_table[s->level].func))(s, flush)); + bstate = s->level == 0 ? deflate_stored(s, flush) : + s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) : + s->strategy == Z_RLE ? deflate_rle(s, flush) : + (*(configuration_table[s->level].func))(s, flush); if (bstate == finish_started || bstate == finish_done) { s->status = FINISH_STATE; @@ -944,7 +1047,6 @@ int flush; } } } - Assert(strm->avail_out > 0, "bug2"); if (flush != Z_FINISH) return Z_OK; if (s->wrap <= 0) return Z_STREAM_END; @@ -980,18 +1082,9 @@ z_streamp strm; { int status; - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + if (deflateStateCheck(strm)) return Z_STREAM_ERROR; status = strm->state->status; - if (status != INIT_STATE && - status != EXTRA_STATE && - status != NAME_STATE && - status != COMMENT_STATE && - status != HCRC_STATE && - status != BUSY_STATE && - status != FINISH_STATE) { - return Z_STREAM_ERROR; - } /* Deallocate in reverse order of allocations: */ TRY_FREE(strm, strm->state->pending_buf); @@ -1022,7 +1115,7 @@ z_streamp source; ushf *overlay; - if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) { + if (deflateStateCheck(source) || dest == Z_NULL) { return Z_STREAM_ERROR; } @@ -1072,7 +1165,7 @@ z_streamp source; * allocating a large strm->next_in buffer and copying from it. * (See also flush_pending()). */ -local int read_buf(strm, buf, size) +local unsigned read_buf(strm, buf, size) z_streamp strm; Bytef *buf; unsigned size; @@ -1096,7 +1189,7 @@ unsigned size; strm->next_in += len; strm->total_in += len; - return (int)len; + return len; } /* =========================================================================== @@ -1150,12 +1243,12 @@ IPos cur_match; /* current match */ { unsigned chain_length = s->max_chain_length;/* max hash chain length */ register Bytef *scan = s->window + s->strstart; /* current string */ - register Bytef *match; /* matched string */ + register Bytef *match; /* matched string */ register int len; /* length of current match */ #ifdef ZLIB_PM3_TUNED int best_len = MIN_MATCH - 1; /* lift the restriction on prev-length */ #else - int best_len = s->prev_length; /* best match length so far */ + int best_len = (int)s->prev_length; /* best match length so far */ #endif int nice_match = s->nice_match; /* stop if match long enough */ IPos limit = s->strstart > (IPos)MAX_DIST(s) ? @@ -1191,7 +1284,7 @@ IPos cur_match; /* current match */ /* Do not look for matches beyond the end of the input. This is necessary * to make deflate deterministic. */ - if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; + if ((uInt)nice_match > s->lookahead) nice_match = (int)s->lookahead; Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, "need lookahead"); @@ -1352,7 +1445,11 @@ IPos cur_match; /* current match */ #endif /* FASTEST */ -#ifdef DEBUG +#ifdef ZLIB_DEBUG + +#define EQUAL 0 +/* result of memcmp for equal strings */ + /* =========================================================================== * Check that the match at match_start is indeed a match. */ @@ -1379,7 +1476,7 @@ int length; } #else # define check_match(s, start, match, length) -#endif /* DEBUG */ +#endif /* ZLIB_DEBUG */ /* =========================================================================== * Fill the window when the lookahead becomes insufficient. @@ -1394,8 +1491,7 @@ int length; local void fill_window(s) deflate_state *s; { - register unsigned n, m; - register Posf *p; + unsigned n; unsigned more; /* Amount of free space at the end of the window. */ uInt wsize = s->w_size; @@ -1422,35 +1518,11 @@ deflate_state *s; */ if (s->strstart >= wsize + MAX_DIST(s)) { - zmemcpy(s->window, s->window + wsize, (unsigned)wsize); + zmemcpy(s->window, s->window + wsize, (unsigned)wsize - more); s->match_start -= wsize; s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ s->block_start -= (long) wsize; - - /* Slide the hash table (could be avoided with 32 bit values - at the expense of memory usage). We slide even when level == 0 - to keep the hash table consistent if we switch back to level > 0 - later. (Using level 0 permanently is not an optimal usage of - zlib, so we don't care about this pathological case.) - */ - n = s->hash_size; - p = &s->head[n]; - do { - m = *--p; - *p = (Pos)(m >= wsize ? m - wsize : NIL); - } while (--n); - - n = wsize; -#ifndef FASTEST - p = &s->prev[n]; - do { - m = *--p; - *p = (Pos)(m >= wsize ? m - wsize : NIL); - /* If n is not on any hash chain, prev[n] is garbage but - * its value will never be used. - */ - } while (--n); -#endif + slide_hash(s); more += wsize; } if (s->strm->avail_in == 0) break; @@ -1555,70 +1627,198 @@ deflate_state *s; if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \ } +/* Maximum stored block length in deflate format (not including header). */ +#define MAX_STORED 65535 + +/* Minimum of a and b. */ +#define MIN(a, b) ((a) > (b) ? (b) : (a)) + /* =========================================================================== * Copy without compression as much as possible from the input stream, return * the current block state. - * This function does not insert new strings in the dictionary since - * uncompressible data is probably not useful. This function is used - * only for the level=0 compression option. - * NOTE: this function should be optimized to avoid extra copying from - * window to pending_buf. + * + * In case deflateParams() is used to later switch to a non-zero compression + * level, s->matches (otherwise unused when storing) keeps track of the number + * of hash table slides to perform. If s->matches is 1, then one hash table + * slide will be done when switching. If s->matches is 2, the maximum value + * allowed here, then the hash table will be cleared, since two or more slides + * is the same as a clear. + * + * deflate_stored() is written to minimize the number of times an input byte is + * copied. It is most efficient with large input and output buffers, which + * maximizes the opportunites to have a single copy from next_in to next_out. */ local block_state deflate_stored(s, flush) deflate_state *s; int flush; { - /* Stored blocks are limited to 0xffff bytes, pending_buf is limited - * to pending_buf_size, and each stored block has a 5 byte header: + /* Smallest worthy block size when not flushing or finishing. By default + * this is 32K. This can be as small as 507 bytes for memLevel == 1. For + * large input and output buffers, the stored block size will be larger. */ - ulg max_block_size = 0xffff; - ulg max_start; + unsigned min_block = MIN(s->pending_buf_size - 5, s->w_size); - if (max_block_size > s->pending_buf_size - 5) { - max_block_size = s->pending_buf_size - 5; - } - - /* Copy as much as possible from input to output: */ - for (;;) { - /* Fill the window as much as possible: */ - if (s->lookahead <= 1) { - - Assert(s->strstart < s->w_size + MAX_DIST(s) || - s->block_start >= (long)s->w_size, "slide too late"); - - fill_window(s); - if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more; - - if (s->lookahead == 0) break; /* flush the current block */ - } - Assert(s->block_start >= 0L, "block gone"); - - s->strstart += s->lookahead; - s->lookahead = 0; - - /* Emit a stored block if pending_buf will be full: */ - max_start = s->block_start + max_block_size; - if (s->strstart == 0 || (ulg)s->strstart >= max_start) { - /* strstart == 0 is possible when wraparound on 16-bit machine */ - s->lookahead = (uInt)(s->strstart - max_start); - s->strstart = (uInt)max_start; - FLUSH_BLOCK(s, 0); - } - /* Flush if we may have to slide, otherwise block_start may become - * negative and the data will be gone: + /* Copy as many min_block or larger stored blocks directly to next_out as + * possible. If flushing, copy the remaining available input to next_out as + * stored blocks, if there is enough space. + */ + unsigned len, left, have, last = 0; + unsigned used = s->strm->avail_in; + do { + /* Set len to the maximum size block that we can copy directly with the + * available input data and output space. Set left to how much of that + * would be copied from what's left in the window. */ - if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) { - FLUSH_BLOCK(s, 0); + len = MAX_STORED; /* maximum deflate stored block length */ + have = (s->bi_valid + 42) >> 3; /* number of header bytes */ + if (s->strm->avail_out < have) /* need room for header */ + break; + /* maximum stored block length that will fit in avail_out: */ + have = s->strm->avail_out - have; + left = s->strstart - s->block_start; /* bytes left in window */ + if (len > (ulg)left + s->strm->avail_in) + len = left + s->strm->avail_in; /* limit len to the input */ + if (len > have) + len = have; /* limit len to the output */ + + /* If the stored block would be less than min_block in length, or if + * unable to copy all of the available input when flushing, then try + * copying to the window and the pending buffer instead. Also don't + * write an empty block when flushing -- deflate() does that. + */ + if (len < min_block && ((len == 0 && flush != Z_FINISH) || + flush == Z_NO_FLUSH || + len != left + s->strm->avail_in)) + break; + + /* Make a dummy stored block in pending to get the header bytes, + * including any pending bits. This also updates the debugging counts. + */ + last = flush == Z_FINISH && len == left + s->strm->avail_in ? 1 : 0; + _tr_stored_block(s, (char *)0, 0L, last); + + /* Replace the lengths in the dummy stored block with len. */ + s->pending_buf[s->pending - 4] = len; + s->pending_buf[s->pending - 3] = len >> 8; + s->pending_buf[s->pending - 2] = ~len; + s->pending_buf[s->pending - 1] = ~len >> 8; + + /* Write the stored block header bytes. */ + flush_pending(s->strm); + +#ifdef ZLIB_DEBUG + /* Update debugging counts for the data about to be copied. */ + s->compressed_len += len << 3; + s->bits_sent += len << 3; +#endif + + /* Copy uncompressed bytes from the window to next_out. */ + if (left) { + if (left > len) + left = len; + zmemcpy(s->strm->next_out, s->window + s->block_start, left); + s->strm->next_out += left; + s->strm->avail_out -= left; + s->strm->total_out += left; + s->block_start += left; + len -= left; } + + /* Copy uncompressed bytes directly from next_in to next_out, updating + * the check value. + */ + if (len) { + read_buf(s->strm, s->strm->next_out, len); + s->strm->next_out += len; + s->strm->avail_out -= len; + s->strm->total_out += len; + } + } while (last == 0); + + /* Update the sliding window with the last s->w_size bytes of the copied + * data, or append all of the copied data to the existing window if less + * than s->w_size bytes were copied. Also update the number of bytes to + * insert in the hash tables, in the event that deflateParams() switches to + * a non-zero compression level. + */ + used -= s->strm->avail_in; /* number of input bytes directly copied */ + if (used) { + /* If any input was used, then no unused input remains in the window, + * therefore s->block_start == s->strstart. + */ + if (used >= s->w_size) { /* supplant the previous history */ + s->matches = 2; /* clear hash */ + zmemcpy(s->window, s->strm->next_in - s->w_size, s->w_size); + s->strstart = s->w_size; + } else { + if (s->window_size - s->strstart <= used) { + /* Slide the window down. */ + s->strstart -= s->w_size; + zmemcpy(s->window, s->window + s->w_size, s->strstart); + if (s->matches < 2) + s->matches++; /* add a pending slide_hash() */ + } + zmemcpy(s->window + s->strstart, s->strm->next_in - used, used); + s->strstart += used; + } + s->block_start = s->strstart; + s->insert += MIN(used, s->w_size - s->insert); } - s->insert = 0; - if (flush == Z_FINISH) { - FLUSH_BLOCK(s, 1); + if (s->high_water < s->strstart) + s->high_water = s->strstart; + + /* If the last block was written to next_out, then done. */ + if (last) return finish_done; + + /* If flushing and all input has been consumed, then done. */ + if (flush != Z_NO_FLUSH && flush != Z_FINISH && + s->strm->avail_in == 0 && (long)s->strstart == s->block_start) + return block_done; + + /* Fill the window with any remaining input. */ + have = s->window_size - s->strstart - 1; + if (s->strm->avail_in > have && s->block_start >= (long)s->w_size) { + /* Slide the window down. */ + s->block_start -= s->w_size; + s->strstart -= s->w_size; + zmemcpy(s->window, s->window + s->w_size, s->strstart); + if (s->matches < 2) + s->matches++; /* add a pending slide_hash() */ + have += s->w_size; /* more space now */ } - if ((long)s->strstart > s->block_start) - FLUSH_BLOCK(s, 0); - return block_done; + if (have > s->strm->avail_in) + have = s->strm->avail_in; + if (have) { + read_buf(s->strm, s->window + s->strstart, have); + s->strstart += have; + } + if (s->high_water < s->strstart) + s->high_water = s->strstart; + + /* There was not enough avail_out to write a complete worthy or flushed + * stored block to next_out. Write a stored block to pending instead, if we + * have enough input for a worthy block, or if flushing and there is enough + * room for the remaining input as a stored block in the pending buffer. + */ + have = (s->bi_valid + 42) >> 3; /* number of header bytes */ + /* maximum stored block length that will fit in pending: */ + have = MIN(s->pending_buf_size - have, MAX_STORED); + min_block = MIN(have, s->w_size); + left = s->strstart - s->block_start; + if (left >= min_block || + ((left || flush == Z_FINISH) && flush != Z_NO_FLUSH && + s->strm->avail_in == 0 && left <= have)) { + len = MIN(left, have); + last = flush == Z_FINISH && s->strm->avail_in == 0 && + len == left ? 1 : 0; + _tr_stored_block(s, (charf *)s->window + s->block_start, len, last); + s->block_start += len; + flush_pending(s->strm); + } + + /* We've done all we can with the available input and output. */ + return last ? finish_started : need_more; } /* =========================================================================== @@ -1977,7 +2177,7 @@ int flush; prev == *++scan && prev == *++scan && prev == *++scan && prev == *++scan && scan < strend); - s->match_length = MAX_MATCH - (int)(strend - scan); + s->match_length = MAX_MATCH - (uInt)(strend - scan); if (s->match_length > s->lookahead) s->match_length = s->lookahead; } diff --git a/common/zlib/deflate.h b/common/zlib/deflate.h index 1e17b476d..10956218e 100644 --- a/common/zlib/deflate.h +++ b/common/zlib/deflate.h @@ -1,5 +1,5 @@ /* deflate.h -- internal compression state - * Copyright (C) 1995-2012 Jean-loup Gailly + * Copyright (C) 1995-2016 Jean-loup Gailly * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -51,13 +51,16 @@ #define Buf_size 16 /* size of bit buffer in bi_buf */ -#define INIT_STATE 42 -#define EXTRA_STATE 69 -#define NAME_STATE 73 -#define COMMENT_STATE 91 -#define HCRC_STATE 103 -#define BUSY_STATE 113 -#define FINISH_STATE 666 +#define INIT_STATE 42 /* zlib header -> BUSY_STATE */ +#ifdef GZIP +# define GZIP_STATE 57 /* gzip header -> BUSY_STATE | EXTRA_STATE */ +#endif +#define EXTRA_STATE 69 /* gzip extra block -> NAME_STATE */ +#define NAME_STATE 73 /* gzip file name -> COMMENT_STATE */ +#define COMMENT_STATE 91 /* gzip comment -> HCRC_STATE */ +#define HCRC_STATE 103 /* gzip header CRC -> BUSY_STATE */ +#define BUSY_STATE 113 /* deflate -> FINISH_STATE */ +#define FINISH_STATE 666 /* stream complete */ /* Stream status */ @@ -83,7 +86,7 @@ typedef struct static_tree_desc_s static_tree_desc; typedef struct tree_desc_s { ct_data *dyn_tree; /* the dynamic tree */ int max_code; /* largest code with non zero frequency */ - static_tree_desc *stat_desc; /* the corresponding static tree */ + const static_tree_desc *stat_desc; /* the corresponding static tree */ } FAR tree_desc; typedef ush Pos; @@ -100,10 +103,10 @@ typedef struct internal_state { Bytef *pending_buf; /* output still pending */ ulg pending_buf_size; /* size of pending_buf */ Bytef *pending_out; /* next pending byte to output to the stream */ - uInt pending; /* nb of bytes in the pending buffer */ + ulg pending; /* nb of bytes in the pending buffer */ int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ gz_headerp gzhead; /* gzip header information to write */ - uInt gzindex; /* where in extra, name, or comment */ + ulg gzindex; /* where in extra, name, or comment */ Byte method; /* can only be DEFLATED */ int last_flush; /* value of flush param for previous deflate call */ @@ -249,7 +252,7 @@ typedef struct internal_state { uInt matches; /* number of string matches in current block */ uInt insert; /* bytes at end of window left to insert */ -#ifdef DEBUG +#ifdef ZLIB_DEBUG ulg compressed_len; /* total bit length of compressed file mod 2^32 */ ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ #endif @@ -275,7 +278,7 @@ typedef struct internal_state { /* Output a byte on the stream. * IN assertion: there is enough room in pending_buf. */ -#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} +#define put_byte(s, c) {s->pending_buf[s->pending++] = (Bytef)(c);} #define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) @@ -309,7 +312,7 @@ void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf, * used. */ -#ifndef DEBUG +#ifndef ZLIB_DEBUG /* Inline versions of _tr_tally for speed: */ #if defined(GEN_TREES_H) || !defined(STDC) @@ -328,8 +331,8 @@ extern const uch ZLIB_INTERNAL _dist_code[]; flush = (s->last_lit == s->lit_bufsize-1); \ } # define _tr_tally_dist(s, distance, length, flush) \ - { uch len = (length); \ - ush dist = (distance); \ + { uch len = (uch)(length); \ + ush dist = (ush)(distance); \ s->d_buf[s->last_lit] = dist; \ s->l_buf[s->last_lit++] = len; \ dist--; \ diff --git a/common/zlib/inffast.c b/common/zlib/inffast.c index 63f3f7d80..874ecc02c 100644 --- a/common/zlib/inffast.c +++ b/common/zlib/inffast.c @@ -1,5 +1,5 @@ /* inffast.c -- fast decoding - * Copyright (C) 1995-2008, 2010, 2013 Mark Adler + * Copyright (C) 1995-2017 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -8,26 +8,9 @@ #include "inflate.h" #include "inffast.h" -#ifndef ASMINF - -/* Allow machine dependent optimization for post-increment or pre-increment. - Based on testing to date, - Pre-increment preferred for: - - PowerPC G3 (Adler) - - MIPS R5000 (Randers-Pehrson) - Post-increment preferred for: - - none - No measurable difference: - - Pentium III (Anderson) - - M68060 (Nikl) - */ -#ifdef POSTINC -# define OFF 0 -# define PUP(a) *(a)++ +#ifdef ASMINF +# pragma message("Assembler code may have bugs -- use at your own risk") #else -# define OFF 1 -# define PUP(a) *++(a) -#endif /* Decode literal, length, and distance codes and write out the resulting @@ -96,9 +79,9 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ /* copy state to local variables */ state = (struct inflate_state FAR *)strm->state; - in = strm->next_in - OFF; + in = strm->next_in; last = in + (strm->avail_in - 5); - out = strm->next_out - OFF; + out = strm->next_out; beg = out - (start - strm->avail_out); end = out + (strm->avail_out - 257); #ifdef INFLATE_STRICT @@ -119,9 +102,9 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ input data or output space */ do { if (bits < 15) { - hold += (unsigned long)(PUP(in)) << bits; + hold += (unsigned long)(*in++) << bits; bits += 8; - hold += (unsigned long)(PUP(in)) << bits; + hold += (unsigned long)(*in++) << bits; bits += 8; } here = lcode[hold & lmask]; @@ -134,13 +117,13 @@ dolen: Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? "inflate: literal '%c'\n" : "inflate: literal 0x%02x\n", here.val)); - PUP(out) = (unsigned char)(here.val); + *out++ = (unsigned char)(here.val); } else if (op & 16) { /* length base */ len = (unsigned)(here.val); op &= 15; /* number of extra bits */ if (op) { if (bits < op) { - hold += (unsigned long)(PUP(in)) << bits; + hold += (unsigned long)(*in++) << bits; bits += 8; } len += (unsigned)hold & ((1U << op) - 1); @@ -149,9 +132,9 @@ dolen: } Tracevv((stderr, "inflate: length %u\n", len)); if (bits < 15) { - hold += (unsigned long)(PUP(in)) << bits; + hold += (unsigned long)(*in++) << bits; bits += 8; - hold += (unsigned long)(PUP(in)) << bits; + hold += (unsigned long)(*in++) << bits; bits += 8; } here = dcode[hold & dmask]; @@ -164,10 +147,10 @@ dodist: dist = (unsigned)(here.val); op &= 15; /* number of extra bits */ if (bits < op) { - hold += (unsigned long)(PUP(in)) << bits; + hold += (unsigned long)(*in++) << bits; bits += 8; if (bits < op) { - hold += (unsigned long)(PUP(in)) << bits; + hold += (unsigned long)(*in++) << bits; bits += 8; } } @@ -195,30 +178,30 @@ dodist: #ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR if (len <= op - whave) { do { - PUP(out) = 0; + *out++ = 0; } while (--len); continue; } len -= op - whave; do { - PUP(out) = 0; + *out++ = 0; } while (--op > whave); if (op == 0) { from = out - dist; do { - PUP(out) = PUP(from); + *out++ = *from++; } while (--len); continue; } #endif } - from = window - OFF; + from = window; if (wnext == 0) { /* very common case */ from += wsize - op; if (op < len) { /* some from window */ len -= op; do { - PUP(out) = PUP(from); + *out++ = *from++; } while (--op); from = out - dist; /* rest from output */ } @@ -228,14 +211,14 @@ dodist: if (op < len) { /* some from end of window */ len -= op; do { - PUP(out) = PUP(from); + *out++ = *from++; } while (--op); - from = window - OFF; + from = window; if (wnext < len) { /* some from start of window */ op = wnext; len -= op; do { - PUP(out) = PUP(from); + *out++ = *from++; } while (--op); from = out - dist; /* rest from output */ } @@ -245,34 +228,34 @@ dodist: if (op < len) { /* some from window */ len -= op; do { - PUP(out) = PUP(from); + *out++ = *from++; } while (--op); from = out - dist; /* rest from output */ } } while (len > 2) { - PUP(out) = PUP(from); - PUP(out) = PUP(from); - PUP(out) = PUP(from); + *out++ = *from++; + *out++ = *from++; + *out++ = *from++; len -= 3; } if (len) { - PUP(out) = PUP(from); + *out++ = *from++; if (len > 1) - PUP(out) = PUP(from); + *out++ = *from++; } } else { from = out - dist; /* copy direct from output */ do { /* minimum length is three */ - PUP(out) = PUP(from); - PUP(out) = PUP(from); - PUP(out) = PUP(from); + *out++ = *from++; + *out++ = *from++; + *out++ = *from++; len -= 3; } while (len > 2); if (len) { - PUP(out) = PUP(from); + *out++ = *from++; if (len > 1) - PUP(out) = PUP(from); + *out++ = *from++; } } } else if ((op & 64) == 0) { /* 2nd level distance code */ @@ -304,8 +287,8 @@ dodist: hold &= (1U << bits) - 1; /* update state and return */ - strm->next_in = in + OFF; - strm->next_out = out + OFF; + strm->next_in = in; + strm->next_out = out; strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); strm->avail_out = (unsigned)(out < end ? 257 + (end - out) : 257 - (out - end)); diff --git a/common/zlib/inflate.c b/common/zlib/inflate.c index a5aee5a33..0eb9ed787 100644 --- a/common/zlib/inflate.c +++ b/common/zlib/inflate.c @@ -1,5 +1,5 @@ /* inflate.c -- zlib decompression - * Copyright (C) 1995-2012 Mark Adler + * Copyright (C) 1995-2016 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -92,6 +92,7 @@ #endif /* function prototypes */ +local int inflateStateCheck OF((z_streamp strm)); #ifdef ZLIB_PM3_TUNED extern void Dbprintf(const char *fmt, ...); #else @@ -105,12 +106,26 @@ void makefixed OF((void)); local unsigned syncsearch OF((unsigned FAR *have, const unsigned char FAR *buf, unsigned len)); +local int inflateStateCheck(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + if (strm == Z_NULL || + strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) + return 1; + state = (struct inflate_state FAR *)strm->state; + if (state == Z_NULL || state->strm != strm || + state->mode < HEAD || state->mode > SYNC) + return 1; + return 0; +} + int ZEXPORT inflateResetKeep(strm) z_streamp strm; { struct inflate_state FAR *state; - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; strm->total_in = strm->total_out = state->total = 0; strm->msg = Z_NULL; @@ -135,7 +150,7 @@ z_streamp strm; { struct inflate_state FAR *state; - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; state->wsize = 0; state->whave = 0; @@ -151,7 +166,7 @@ int windowBits; struct inflate_state FAR *state; /* get the state */ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; /* extract wrap request from windowBits parameter */ @@ -159,7 +174,7 @@ int windowBits; wrap = 0; windowBits = -windowBits; } else { - wrap = (windowBits >> 4) + 1; + wrap = (windowBits >> 4) + 5; #ifdef GUNZIP if (windowBits < 48) windowBits &= 15; @@ -213,7 +228,9 @@ int stream_size; if (state == Z_NULL) return Z_MEM_ERROR; Tracev((stderr, "inflate: allocated\n")); strm->state = (struct internal_state FAR *)state; + state->strm = strm; state->window = Z_NULL; + state->mode = HEAD; /* to pass state test in inflateReset2() */ ret = inflateReset2(strm, windowBits); if (ret != Z_OK) { ZFREE(strm, state); @@ -237,17 +254,17 @@ int value; { struct inflate_state FAR *state; - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; if (bits < 0) { state->hold = 0; state->bits = 0; return Z_OK; } - if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR; + if (bits > 16 || state->bits + (uInt)bits > 32) return Z_STREAM_ERROR; value &= (1L << bits) - 1; - state->hold += value << state->bits; - state->bits += bits; + state->hold += (unsigned)value << state->bits; + state->bits += (uInt)bits; return Z_OK; } @@ -626,7 +643,7 @@ int flush; static const unsigned short order[19] = /* permutation of code lengths */ {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL || + if (inflateStateCheck(strm) || strm->next_out == Z_NULL || (strm->next_in == Z_NULL && strm->avail_in != 0)) return Z_STREAM_ERROR; @@ -646,6 +663,8 @@ int flush; NEEDBITS(16); #ifdef GUNZIP if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ + if (state->wbits == 0) + state->wbits = 15; state->check = crc32(0L, Z_NULL, 0); CRC2(state->check, hold); INITBITS(); @@ -673,7 +692,7 @@ int flush; len = BITS(4) + 8; if (state->wbits == 0) state->wbits = len; - else if (len > state->wbits) { + if (len > 15 || len > state->wbits) { strm->msg = (char *)"invalid window size"; state->mode = BAD; break; @@ -700,14 +719,16 @@ int flush; } if (state->head != Z_NULL) state->head->text = (int)((hold >> 8) & 1); - if (state->flags & 0x0200) CRC2(state->check, hold); + if ((state->flags & 0x0200) && (state->wrap & 4)) + CRC2(state->check, hold); INITBITS(); state->mode = TIME; case TIME: NEEDBITS(32); if (state->head != Z_NULL) state->head->time = hold; - if (state->flags & 0x0200) CRC4(state->check, hold); + if ((state->flags & 0x0200) && (state->wrap & 4)) + CRC4(state->check, hold); INITBITS(); state->mode = OS; case OS: @@ -716,7 +737,8 @@ int flush; state->head->xflags = (int)(hold & 0xff); state->head->os = (int)(hold >> 8); } - if (state->flags & 0x0200) CRC2(state->check, hold); + if ((state->flags & 0x0200) && (state->wrap & 4)) + CRC2(state->check, hold); INITBITS(); state->mode = EXLEN; case EXLEN: @@ -725,7 +747,8 @@ int flush; state->length = (unsigned)(hold); if (state->head != Z_NULL) state->head->extra_len = (unsigned)hold; - if (state->flags & 0x0200) CRC2(state->check, hold); + if ((state->flags & 0x0200) && (state->wrap & 4)) + CRC2(state->check, hold); INITBITS(); } else if (state->head != Z_NULL) state->head->extra = Z_NULL; @@ -742,7 +765,7 @@ int flush; len + copy > state->head->extra_max ? state->head->extra_max - len : copy); } - if (state->flags & 0x0200) + if ((state->flags & 0x0200) && (state->wrap & 4)) state->check = crc32(state->check, next, copy); have -= copy; next += copy; @@ -761,9 +784,9 @@ int flush; if (state->head != Z_NULL && state->head->name != Z_NULL && state->length < state->head->name_max) - state->head->name[state->length++] = len; + state->head->name[state->length++] = (Bytef)len; } while (len && copy < have); - if (state->flags & 0x0200) + if ((state->flags & 0x0200) && (state->wrap & 4)) state->check = crc32(state->check, next, copy); have -= copy; next += copy; @@ -781,9 +804,9 @@ int flush; if (state->head != Z_NULL && state->head->comment != Z_NULL && state->length < state->head->comm_max) - state->head->comment[state->length++] = len; + state->head->comment[state->length++] = (Bytef)len; } while (len && copy < have); - if (state->flags & 0x0200) + if ((state->flags & 0x0200) && (state->wrap & 4)) state->check = crc32(state->check, next, copy); have -= copy; next += copy; @@ -794,7 +817,7 @@ int flush; case HCRC: if (state->flags & 0x0200) { NEEDBITS(16); - if (hold != (state->check & 0xffff)) { + if ((state->wrap & 4) && hold != (state->check & 0xffff)) { strm->msg = (char *)"header crc mismatch"; state->mode = BAD; break; @@ -1175,11 +1198,11 @@ int flush; out -= left; strm->total_out += out; state->total += out; - if (out) + if ((state->wrap & 4) && out) strm->adler = state->check = UPDATE(state->check, put - out, out); out = left; - if (( + if ((state->wrap & 4) && ( #ifdef GUNZIP state->flags ? hold : #endif @@ -1238,10 +1261,10 @@ inf_leave: strm->total_in += in; strm->total_out += out; state->total += out; - if (state->wrap && out) + if ((state->wrap & 4) && out) strm->adler = state->check = UPDATE(state->check, strm->next_out - out, out); - strm->data_type = state->bits + (state->last ? 64 : 0) + + strm->data_type = (int)state->bits + (state->last ? 64 : 0) + (state->mode == TYPE ? 128 : 0) + (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0); if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) @@ -1253,7 +1276,7 @@ int ZEXPORT inflateEnd(strm) z_streamp strm; { struct inflate_state FAR *state; - if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; if (state->window != Z_NULL) ZFREE(strm, state->window); @@ -1271,7 +1294,7 @@ uInt *dictLength; struct inflate_state FAR *state; /* check state */ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; /* copy dictionary */ @@ -1296,7 +1319,7 @@ uInt dictLength; int ret; /* check state */ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; if (state->wrap != 0 && state->mode != DICT) return Z_STREAM_ERROR; @@ -1328,7 +1351,7 @@ gz_headerp head; struct inflate_state FAR *state; /* check state */ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; @@ -1381,7 +1404,7 @@ z_streamp strm; struct inflate_state FAR *state; /* check parameters */ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; @@ -1430,7 +1453,7 @@ z_streamp strm; { struct inflate_state FAR *state; - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; return state->mode == STORED && state->bits == 0; } @@ -1445,8 +1468,7 @@ z_streamp source; unsigned wsize; /* check input */ - if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL || - source->zalloc == (alloc_func)0 || source->zfree == (free_func)0) + if (inflateStateCheck(source) || dest == Z_NULL) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)source->state; @@ -1467,6 +1489,7 @@ z_streamp source; /* copy state */ zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state)); + copy->strm = dest; if (state->lencode >= state->codes && state->lencode <= state->codes + ENOUGH - 1) { copy->lencode = copy->codes + (state->lencode - state->codes); @@ -1488,27 +1511,51 @@ int subvert; { struct inflate_state FAR *state; - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; #ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR state->sane = !subvert; return Z_OK; #else + (void)subvert; state->sane = 1; return Z_DATA_ERROR; #endif } +int ZEXPORT inflateValidate(strm, check) +z_streamp strm; +int check; +{ + struct inflate_state FAR *state; + + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (check) + state->wrap |= 4; + else + state->wrap &= ~4; + return Z_OK; +} + long ZEXPORT inflateMark(strm) z_streamp strm; { struct inflate_state FAR *state; - if (strm == Z_NULL || strm->state == Z_NULL) - return ~0UL << 16; + if (inflateStateCheck(strm)) + return -(1L << 16); state = (struct inflate_state FAR *)strm->state; - return ((long)(state->back) << 16) + + return (long)(((unsigned long)((long)state->back)) << 16) + (state->mode == COPY ? state->length : (state->mode == MATCH ? state->was - state->length : 0)); } +unsigned long ZEXPORT inflateCodesUsed(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + if (inflateStateCheck(strm)) return (unsigned long) -1; + state = (struct inflate_state FAR *)strm->state; + return (unsigned long)(state->next - state->codes); +} diff --git a/common/zlib/inflate.h b/common/zlib/inflate.h index 399ccc521..f48620e08 100644 --- a/common/zlib/inflate.h +++ b/common/zlib/inflate.h @@ -1,5 +1,5 @@ /* inflate.h -- internal inflate state definition - * Copyright (C) 1995-2009 Mark Adler + * Copyright (C) 1995-2016 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -18,7 +18,7 @@ /* Possible inflate modes between inflate() calls */ typedef enum { - HEAD, /* i: waiting for magic header */ + HEAD = 16180, /* i: waiting for magic header */ FLAGS, /* i: waiting for method and flags (gzip) */ TIME, /* i: waiting for modification time (gzip) */ OS, /* i: waiting for extra flags and operating system (gzip) */ @@ -77,11 +77,14 @@ typedef enum { CHECK -> LENGTH -> DONE */ -/* state maintained between inflate() calls. Approximately 10K bytes. */ +/* State maintained between inflate() calls -- approximately 7K bytes, not + including the allocated sliding window, which is up to 32K bytes. */ struct inflate_state { + z_streamp strm; /* pointer back to this zlib stream */ inflate_mode mode; /* current inflate mode */ int last; /* true if processing last block */ - int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip, + bit 2 true to validate check value */ int havedict; /* true if dictionary provided */ int flags; /* gzip header method and flags (0 if zlib) */ unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ diff --git a/common/zlib/inftrees.c b/common/zlib/inftrees.c index e5e4f8c4f..49672650c 100644 --- a/common/zlib/inftrees.c +++ b/common/zlib/inftrees.c @@ -1,5 +1,5 @@ /* inftrees.c -- generate Huffman trees for efficient decoding - * Copyright (C) 1995-2013 Mark Adler + * Copyright (C) 1995-2017 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -10,9 +10,9 @@ const char inflate_copyright[] = #ifdef ZLIB_PM3_TUNED - " inflate 1.2.8.f-Proxmark3 Copyright 1995-2013 Mark Adler "; + " inflate 1.2.11.f-Proxmark3 Copyright 1995-2017 Mark Adler "; #else - " inflate 1.2.8 Copyright 1995-2013 Mark Adler "; + " inflate 1.2.11 Copyright 1995-2017 Mark Adler "; #endif /* If you use the zlib library in a product, an acknowledgment is welcome @@ -53,7 +53,7 @@ int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens, code FAR *next; /* next available space in table */ const unsigned short FAR *base; /* base value table to use */ const unsigned short FAR *extra; /* extra bits table to use */ - int end; /* use base and extra for symbol > end */ + unsigned match; /* use base and extra for symbol >= match */ unsigned short count[MAXBITS + 1]; /* number of codes of each length */ unsigned short offs[MAXBITS + 1]; /* offsets in table for each length */ static const unsigned short lbase[31] = { /* Length codes 257..285 base */ @@ -62,7 +62,7 @@ int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens, }; static const unsigned short lext[31] = { /* Length codes 257..285 extra */ 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, - 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78 + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 77, 202 }; static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, @@ -184,19 +184,17 @@ int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens, switch (type) { case CODES: base = extra = work; /* dummy value--not used */ - end = 19; + match = 20; break; case LENS: base = lbase; - base -= 257; extra = lext; - extra -= 257; - end = 256; + match = 257; break; - default: /* DISTS */ + default: /* DISTS */ base = dbase; extra = dext; - end = -1; + match = 0; } /* initialize state for loop */ @@ -219,12 +217,12 @@ int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens, for (;;) { /* create table entry */ here.bits = (unsigned char)(len - drop); - if ((int)(work[sym]) < end) { + if (work[sym] + 1U < match) { here.op = (unsigned char)0; here.val = work[sym]; - } else if ((int)(work[sym]) > end) { - here.op = (unsigned char)(extra[work[sym]]); - here.val = base[work[sym]]; + } else if (work[sym] >= match) { + here.op = (unsigned char)(extra[work[sym] - match]); + here.val = base[work[sym] - match]; } else { here.op = (unsigned char)(32 + 64); /* end of block */ here.val = 0; diff --git a/common/zlib/trees.c b/common/zlib/trees.c index 8ffab9c8e..8d230426e 100644 --- a/common/zlib/trees.c +++ b/common/zlib/trees.c @@ -1,5 +1,5 @@ /* trees.c -- output deflated data using Huffman coding - * Copyright (C) 1995-2012 Jean-loup Gailly + * Copyright (C) 1995-2017 Jean-loup Gailly * detect_data_type() function provided freely by Cosmin Truta, 2006 * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -36,7 +36,7 @@ #include "deflate.h" -#ifdef DEBUG +#ifdef ZLIB_DEBUG # include #endif @@ -122,13 +122,13 @@ struct static_tree_desc_s { int max_length; /* max bit length for the codes */ }; -local static_tree_desc static_l_desc = +local const static_tree_desc static_l_desc = {static_ltree, extra_lbits, LITERALS + 1, L_CODES, MAX_BITS}; -local static_tree_desc static_d_desc = +local const static_tree_desc static_d_desc = {static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; -local static_tree_desc static_bl_desc = +local const static_tree_desc static_bl_desc = {(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; /* =========================================================================== @@ -152,18 +152,16 @@ local int detect_data_type OF((deflate_state *s)); local unsigned bi_reverse OF((unsigned value, int length)); local void bi_windup OF((deflate_state *s)); local void bi_flush OF((deflate_state *s)); -local void copy_block OF((deflate_state *s, charf *buf, unsigned len, - int header)); #ifdef GEN_TREES_H local void gen_trees_header OF((void)); #endif -#ifndef DEBUG +#ifndef ZLIB_DEBUG # define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) /* Send a code of the given tree. c and tree must not have side effects */ -#else /* DEBUG */ +#else /* !ZLIB_DEBUG */ # define send_code(s, c, tree) \ { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ send_bits(s, tree[c].Code, tree[c].Len); } @@ -182,7 +180,7 @@ local void gen_trees_header OF((void)); * Send a value on a given number of bits. * IN assertion: length <= 16 and value fits in length bits. */ -#ifdef DEBUG +#ifdef ZLIB_DEBUG local void send_bits OF((deflate_state *s, int value, int length)); local void send_bits(s, value, length) @@ -208,12 +206,12 @@ int length; /* number of bits */ s->bi_valid += length; } } -#else /* !DEBUG */ +#else /* !ZLIB_DEBUG */ #define send_bits(s, value, length) \ { int len = length;\ if (s->bi_valid > (int)Buf_size - len) {\ - int val = value;\ + int val = (int)value;\ s->bi_buf |= (ush)val << s->bi_valid;\ put_short(s, s->bi_buf);\ s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ @@ -223,7 +221,7 @@ int length; /* number of bits */ s->bi_valid += len;\ }\ } -#endif /* DEBUG */ +#endif /* ZLIB_DEBUG */ /* the arguments must not have side effects */ @@ -316,7 +314,7 @@ local void tr_static_init() { * Genererate the file trees.h describing the static trees. */ #ifdef GEN_TREES_H -# ifndef DEBUG +# ifndef ZLIB_DEBUG # include # endif @@ -392,7 +390,7 @@ deflate_state *s; s->bi_buf = 0; s->bi_valid = 0; -#ifdef DEBUG +#ifdef ZLIB_DEBUG s->compressed_len = 0L; s->bits_sent = 0L; #endif @@ -521,12 +519,12 @@ tree_desc *desc; /* the tree descriptor */ xbits = 0; if (n >= base) xbits = extra[n - base]; f = tree[n].Freq; - s->opt_len += (ulg)f * (bits + xbits); - if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits); + s->opt_len += (ulg)f * (unsigned)(bits + xbits); + if (stree) s->static_len += (ulg)f * (unsigned)(stree[n].Len + xbits); } if (overflow == 0) return; - Trace((stderr, "\nbit length overflow\n")); + Tracev((stderr, "\nbit length overflow\n")); /* This happens for example on obj2 and pic of the Calgary corpus */ /* Find the first bit length which could increase: */ @@ -553,9 +551,8 @@ tree_desc *desc; /* the tree descriptor */ m = s->heap[--h]; if (m > max_code) continue; if ((unsigned) tree[m].Len != (unsigned) bits) { - Trace((stderr, "code %d bits %d->%d\n", m, tree[m].Len, bits)); - s->opt_len += ((long)bits - (long)tree[m].Len) - * (long)tree[m].Freq; + Tracev((stderr, "code %d bits %d->%d\n", m, tree[m].Len, bits)); + s->opt_len += ((ulg)bits - tree[m].Len) * tree[m].Freq; tree[m].Len = (ush)bits; } n--; @@ -577,7 +574,7 @@ int max_code; /* largest code with non zero frequency */ ushf *bl_count; /* number of codes at each bit length */ { ush next_code[MAX_BITS + 1]; /* next code value for each bit length */ - ush code = 0; /* running code value */ + unsigned code = 0; /* running code value */ int bits; /* bit index */ int n; /* code index */ @@ -585,7 +582,8 @@ ushf *bl_count; /* number of codes at each bit length */ * without bit reversal. */ for (bits = 1; bits <= MAX_BITS; bits++) { - next_code[bits] = code = (code + bl_count[bits - 1]) << 1; + code = (code + bl_count[bits - 1]) << 1; + next_code[bits] = (ush)code; } /* Check that the bit counts in bl_count are consistent. The last code * must be all ones. @@ -598,7 +596,7 @@ ushf *bl_count; /* number of codes at each bit length */ int len = tree[n].Len; if (len == 0) continue; /* Now reverse the bits */ - tree[n].Code = bi_reverse(next_code[len]++, len); + tree[n].Code = (ush)bi_reverse(next_code[len]++, len); Tracecv(tree != static_ltree, (stderr, "\nn %3d %c l %2d c %4x (%x) ", n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len] - 1)); @@ -830,7 +828,7 @@ deflate_state *s; if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; } /* Update opt_len to include the bit length tree and counts */ - s->opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4; + s->opt_len += 3 * ((ulg)max_blindex + 1) + 5 + 5 + 4; Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", s->opt_len, s->static_len)); @@ -878,11 +876,17 @@ ulg stored_len; /* length of input block */ int last; /* one if this is the last block for a file */ { send_bits(s, (STORED_BLOCK << 1) + last, 3); /* send block type */ -#ifdef DEBUG + bi_windup(s); /* align on byte boundary */ + put_short(s, (ush)stored_len); + put_short(s, (ush)~stored_len); + zmemcpy(s->pending_buf + s->pending, (Bytef *)buf, stored_len); + s->pending += stored_len; +#ifdef ZLIB_DEBUG s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; s->compressed_len += (stored_len + 4) << 3; + s->bits_sent += 2 * 16; + s->bits_sent += stored_len << 3; #endif - copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ } /* =========================================================================== @@ -903,7 +907,7 @@ deflate_state *s; { send_bits(s, STATIC_TREES << 1, 3); send_code(s, END_BLOCK, static_ltree); -#ifdef DEBUG +#ifdef ZLIB_DEBUG s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ #endif bi_flush(s); @@ -911,7 +915,7 @@ deflate_state *s; /* =========================================================================== * Determine the best encoding for the current block: dynamic trees, static - * trees or store, and output the encoded block to the zip file. + * trees or store, and write out the encoded block. */ void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last) deflate_state *s; @@ -985,7 +989,7 @@ int last; /* one if this is the last block for a file */ send_bits(s, (STATIC_TREES << 1) + last, 3); compress_block(s, (const ct_data *)static_ltree, (const ct_data *)static_dtree); -#ifdef DEBUG +#ifdef ZLIB_DEBUG s->compressed_len += 3 + s->static_len; #endif } else { @@ -995,7 +999,7 @@ int last; /* one if this is the last block for a file */ max_blindex + 1); compress_block(s, (const ct_data *)s->dyn_ltree, (const ct_data *)s->dyn_dtree); -#ifdef DEBUG +#ifdef ZLIB_DEBUG s->compressed_len += 3 + s->opt_len; #endif #ifndef ZLIB_PM3_TUNED @@ -1009,7 +1013,7 @@ int last; /* one if this is the last block for a file */ if (last) { bi_windup(s); -#ifdef DEBUG +#ifdef ZLIB_DEBUG s->compressed_len += 7; /* align on byte boundary */ #endif } @@ -1104,7 +1108,7 @@ const ct_data *dtree; /* distance tree */ send_code(s, code, dtree); /* send the distance code */ extra = extra_dbits[code]; if (extra != 0) { - dist -= base_dist[code]; + dist -= (unsigned)base_dist[code]; send_bits(s, dist, extra); /* send the extra distance bits */ } } /* literal or match pair ? */ @@ -1207,35 +1211,8 @@ deflate_state *s; } s->bi_buf = 0; s->bi_valid = 0; -#ifdef DEBUG +#ifdef ZLIB_DEBUG s->bits_sent = (s->bits_sent + 7) & ~7; #endif } -/* =========================================================================== - * Copy a stored block, storing first the length and its - * one's complement if requested. - */ -local void copy_block(s, buf, len, header) -deflate_state *s; -charf *buf; /* the input data */ -unsigned len; /* its length */ -int header; /* true if block header must be written */ -{ - bi_windup(s); /* align on byte boundary */ - - if (header) { - put_short(s, (ush)len); - put_short(s, (ush)~len); -#ifdef DEBUG - s->bits_sent += 2 * 16; -#endif - } -#ifdef DEBUG - s->bits_sent += (ulg)len << 3; -#endif - while (len--) { - put_byte(s, *buf++); - } -} - diff --git a/common/zlib/zconf.h b/common/zlib/zconf.h index 5230fc94b..2cf63398b 100644 --- a/common/zlib/zconf.h +++ b/common/zlib/zconf.h @@ -1,5 +1,5 @@ /* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2013 Jean-loup Gailly. + * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -17,7 +17,7 @@ #ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ # define Z_PREFIX_SET -/* all linked symbols */ +/* all linked symbols and init macros */ # define _dist_code z__dist_code # define _length_code z__length_code # define _tr_align z__tr_align @@ -29,6 +29,7 @@ # define adler32 z_adler32 # define adler32_combine z_adler32_combine # define adler32_combine64 z_adler32_combine64 +# define adler32_z z_adler32_z # ifndef Z_SOLO # define compress z_compress # define compress2 z_compress2 @@ -37,10 +38,14 @@ # define crc32 z_crc32 # define crc32_combine z_crc32_combine # define crc32_combine64 z_crc32_combine64 +# define crc32_z z_crc32_z # define deflate z_deflate # define deflateBound z_deflateBound # define deflateCopy z_deflateCopy # define deflateEnd z_deflateEnd +# define deflateGetDictionary z_deflateGetDictionary +# define deflateInit z_deflateInit +# define deflateInit2 z_deflateInit2 # define deflateInit2_ z_deflateInit2_ # define deflateInit_ z_deflateInit_ # define deflateParams z_deflateParams @@ -67,6 +72,8 @@ # define gzeof z_gzeof # define gzerror z_gzerror # define gzflush z_gzflush +# define gzfread z_gzfread +# define gzfwrite z_gzfwrite # define gzgetc z_gzgetc # define gzgetc_ z_gzgetc_ # define gzgets z_gzgets @@ -78,7 +85,6 @@ # define gzopen_w z_gzopen_w # endif # define gzprintf z_gzprintf -# define gzvprintf z_gzvprintf # define gzputc z_gzputc # define gzputs z_gzputs # define gzread z_gzread @@ -89,32 +95,39 @@ # define gztell z_gztell # define gztell64 z_gztell64 # define gzungetc z_gzungetc +# define gzvprintf z_gzvprintf # define gzwrite z_gzwrite # endif # define inflate z_inflate # define inflateBack z_inflateBack # define inflateBackEnd z_inflateBackEnd +# define inflateBackInit z_inflateBackInit # define inflateBackInit_ z_inflateBackInit_ +# define inflateCodesUsed z_inflateCodesUsed # define inflateCopy z_inflateCopy # define inflateEnd z_inflateEnd +# define inflateGetDictionary z_inflateGetDictionary # define inflateGetHeader z_inflateGetHeader +# define inflateInit z_inflateInit +# define inflateInit2 z_inflateInit2 # define inflateInit2_ z_inflateInit2_ # define inflateInit_ z_inflateInit_ # define inflateMark z_inflateMark # define inflatePrime z_inflatePrime # define inflateReset z_inflateReset # define inflateReset2 z_inflateReset2 +# define inflateResetKeep z_inflateResetKeep # define inflateSetDictionary z_inflateSetDictionary -# define inflateGetDictionary z_inflateGetDictionary # define inflateSync z_inflateSync # define inflateSyncPoint z_inflateSyncPoint # define inflateUndermine z_inflateUndermine -# define inflateResetKeep z_inflateResetKeep +# define inflateValidate z_inflateValidate # define inflate_copyright z_inflate_copyright # define inflate_fast z_inflate_fast # define inflate_table z_inflate_table # ifndef Z_SOLO # define uncompress z_uncompress +# define uncompress2 z_uncompress2 # endif # define zError z_zError # ifndef Z_SOLO @@ -224,9 +237,19 @@ # define z_const #endif -/* Some Mac compilers merge all .h files incorrectly: */ -#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) -# define NO_DUMMY_DECL +#ifdef Z_SOLO +typedef unsigned long z_size_t; +#else +# define z_longlong long long +# if defined(NO_SIZE_T) +typedef unsigned NO_SIZE_T z_size_t; +# elif defined(STDC) +# include +typedef size_t z_size_t; +# else +typedef unsigned long z_size_t; +# endif +# undef z_longlong #endif /* Maximum value for memLevel in deflateInit2 */ @@ -256,7 +279,7 @@ Of course this will generally degrade compression (there's no free lunch). The memory requirements for inflate are (in bytes) 1 << windowBits - that is, 32K for windowBits=15 (default value) plus a few kilobytes + that is, 32K for windowBits=15 (default value) plus about 7 kilobytes for small objects. */ diff --git a/common/zlib/zlib.h b/common/zlib/zlib.h index b88bac965..ca35828f0 100644 --- a/common/zlib/zlib.h +++ b/common/zlib/zlib.h @@ -1,7 +1,7 @@ /* zlib.h -- interface of the 'zlib' general purpose compression library - version 1.2.8, April 28th, 2013 + version 1.2.11, January 15th, 2017 - Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler + Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -38,18 +38,18 @@ extern "C" { #endif #ifndef ZLIB_PM3_TUNED -#define ZLIB_VERSION "1.2.8" -#define ZLIB_VERNUM 0x1280 +#define ZLIB_VERSION "1.2.11" +#define ZLIB_VERNUM 0x12b0 #define ZLIB_VER_MAJOR 1 #define ZLIB_VER_MINOR 2 -#define ZLIB_VER_REVISION 8 +#define ZLIB_VER_REVISION 11 #define ZLIB_VER_SUBREVISION 0 #else -#define ZLIB_VERSION "1.2.8.f-Proxmark3" -#define ZLIB_VERNUM 0x128f +#define ZLIB_VERSION "1.2.11.f-Proxmark3" +#define ZLIB_VERNUM 0x12bf #define ZLIB_VER_MAJOR 1 #define ZLIB_VER_MINOR 2 -#define ZLIB_VER_REVISION 8 +#define ZLIB_VER_REVISION 11 #define ZLIB_VER_SUBREVISION f #endif @@ -76,7 +76,8 @@ extern "C" { with "gz". The gzip format is different from the zlib format. gzip is a gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. - This library can optionally read and write gzip streams in memory as well. + This library can optionally read and write gzip and raw deflate streams in + memory as well. The zlib format was designed to be compact and fast for use in memory and on communications channels. The gzip format was designed for single- @@ -85,7 +86,7 @@ extern "C" { The library does not install any signal handler. The decoder checks the consistency of the compressed data, so the library should never crash - even in case of corrupted input. + even in the case of corrupted input. */ typedef voidpf(*alloc_func) OF((voidpf opaque, uInt items, uInt size)); @@ -98,7 +99,7 @@ typedef struct z_stream_s { uInt avail_in; /* number of bytes available at next_in */ uLong total_in; /* total number of input bytes read so far */ - Bytef *next_out; /* next output byte should be put there */ + Bytef *next_out; /* next output byte will go here */ uInt avail_out; /* remaining free space at next_out */ uLong total_out; /* total number of bytes output so far */ @@ -109,8 +110,9 @@ typedef struct z_stream_s { free_func zfree; /* used to free the internal state */ voidpf opaque; /* private data object passed to zalloc and zfree */ - int data_type; /* best guess about the data type: binary or text */ - uLong adler; /* adler32 value of the uncompressed data */ + int data_type; /* best guess about the data type: binary or text + for deflate, or the decoding state for inflate */ + uLong adler; /* Adler-32 or CRC-32 value of the uncompressed data */ uLong reserved; /* reserved for future use */ } z_stream; @@ -153,7 +155,9 @@ typedef gz_header FAR *gz_headerp; zalloc must return Z_NULL if there is not enough memory for the object. If zlib is used in a multi-threaded application, zalloc and zfree must be - thread safe. + thread safe. In that case, zlib is thread-safe. When zalloc and zfree are + Z_NULL on entry to the initialization function, they are set to internal + routines that use the standard library functions malloc() and free(). On 16-bit systems, the functions zalloc and zfree must be able to allocate exactly 65536 bytes, but will not be required to allocate more than this if @@ -166,7 +170,7 @@ typedef gz_header FAR *gz_headerp; The fields total_in and total_out can be used for statistics or progress reports. After compression, total_in holds the total size of the - uncompressed data and may be saved for use in the decompressor (particularly + uncompressed data and may be saved for use by the decompressor (particularly if the decompressor wants to decompress everything in a single step). */ @@ -211,7 +215,7 @@ typedef gz_header FAR *gz_headerp; #define Z_TEXT 1 #define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ #define Z_UNKNOWN 2 -/* Possible values of the data_type field (though see inflate()) */ +/* Possible values of the data_type field for deflate() */ #define Z_DEFLATED 8 /* The deflate compression method (the only one supported in this version) */ @@ -269,11 +273,11 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); enough room in the output buffer), next_in and avail_in are updated and processing will resume at this point for the next call of deflate(). - - Provide more output starting at next_out and update next_out and avail_out + - Generate more output starting at next_out and update next_out and avail_out accordingly. This action is forced if the parameter flush is non zero. Forcing flush frequently degrades the compression ratio, so this parameter - should be set only when necessary (in interactive applications). Some - output may be provided even if flush is not set. + should be set only when necessary. Some output may be provided even if + flush is zero. Before the call of deflate(), the application should ensure that at least one of the actions is possible, by providing more input and/or consuming more @@ -282,7 +286,9 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); output when it wants, for example when the output buffer is full (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK and with zero avail_out, it must be called again after making room in the output - buffer because there might be more output pending. + buffer because there might be more output pending. See deflatePending(), + which can be used if desired to determine whether or not there is more ouput + in that case. Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to decide how much data to accumulate before producing output, in order to @@ -303,8 +309,8 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); input data so far will be available to the decompressor, as for Z_SYNC_FLUSH. This completes the current deflate block and follows it with an empty fixed codes block that is 10 bits long. This assures that enough bytes are output - in order for the decompressor to finish the block before the empty fixed code - block. + in order for the decompressor to finish the block before the empty fixed + codes block. If flush is set to Z_BLOCK, a deflate block is completed and emitted, as for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to @@ -330,34 +336,38 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); If the parameter flush is set to Z_FINISH, pending input is processed, pending output is flushed and deflate returns with Z_STREAM_END if there was - enough output space; if deflate returns with Z_OK, this function must be - called again with Z_FINISH and more output space (updated avail_out) but no - more input data, until it returns with Z_STREAM_END or an error. After - deflate has returned Z_STREAM_END, the only possible operations on the stream - are deflateReset or deflateEnd. + enough output space. If deflate returns with Z_OK or Z_BUF_ERROR, this + function must be called again with Z_FINISH and more output space (updated + avail_out) but no more input data, until it returns with Z_STREAM_END or an + error. After deflate has returned Z_STREAM_END, the only possible operations + on the stream are deflateReset or deflateEnd. - Z_FINISH can be used immediately after deflateInit if all the compression - is to be done in a single step. In this case, avail_out must be at least the - value returned by deflateBound (see below). Then deflate is guaranteed to - return Z_STREAM_END. If not enough output space is provided, deflate will - not return Z_STREAM_END, and it must be called again as described above. + Z_FINISH can be used in the first deflate call after deflateInit if all the + compression is to be done in a single step. In order to complete in one + call, avail_out must be at least the value returned by deflateBound (see + below). Then deflate is guaranteed to return Z_STREAM_END. If not enough + output space is provided, deflate will not return Z_STREAM_END, and it must + be called again as described above. - deflate() sets strm->adler to the adler32 checksum of all input read - so far (that is, total_in bytes). + deflate() sets strm->adler to the Adler-32 checksum of all input read + so far (that is, total_in bytes). If a gzip stream is being generated, then + strm->adler will be the CRC-32 checksum of the input read so far. (See + deflateInit2 below.) deflate() may update strm->data_type if it can make a good guess about - the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered - binary. This field is only for information purposes and does not affect the - compression algorithm in any manner. + the input data type (Z_BINARY or Z_TEXT). If in doubt, the data is + considered binary. This field is only for information purposes and does not + affect the compression algorithm in any manner. deflate() returns Z_OK if some progress has been made (more input processed or more output produced), Z_STREAM_END if all input has been consumed and all output has been produced (only when flush is set to Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example - if next_in or next_out was Z_NULL), Z_BUF_ERROR if no progress is possible - (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not - fatal, and deflate() can be called again with more input and more output - space to continue compressing. + if next_in or next_out was Z_NULL or the state was inadvertently written over + by the application), or Z_BUF_ERROR if no progress is possible (for example + avail_in or avail_out was zero). Note that Z_BUF_ERROR is not fatal, and + deflate() can be called again with more input and more output space to + continue compressing. */ @@ -380,23 +390,21 @@ ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); Initializes the internal stream state for decompression. The fields next_in, avail_in, zalloc, zfree and opaque must be initialized before by - the caller. If next_in is not Z_NULL and avail_in is large enough (the - exact value depends on the compression method), inflateInit determines the - compression method from the zlib header and allocates all data structures - accordingly; otherwise the allocation will be deferred to the first call of - inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to - use default allocation functions. + the caller. In the current version of inflate, the provided input is not + read or consumed. The allocation of a sliding window will be deferred to + the first call of inflate (if the decompression does not complete on the + first call). If zalloc and zfree are set to Z_NULL, inflateInit updates + them to use default allocation functions. inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_VERSION_ERROR if the zlib library version is incompatible with the version assumed by the caller, or Z_STREAM_ERROR if the parameters are invalid, such as a null pointer to the structure. msg is set to null if - there is no error message. inflateInit does not perform any decompression - apart from possibly reading the zlib header if present: actual decompression - will be done by inflate(). (So next_in and avail_in may be modified, but - next_out and avail_out are unused and unchanged.) The current implementation - of inflateInit() does not process any header information -- that is deferred - until inflate() is called. + there is no error message. inflateInit does not perform any decompression. + Actual decompression will be done by inflate(). So next_in, and avail_in, + next_out, and avail_out are unused and unchanged. The current + implementation of inflateInit() does not process any header information -- + that is deferred until inflate() is called. */ @@ -412,17 +420,20 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); - Decompress more input starting at next_in and update next_in and avail_in accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in is updated and processing will - resume at this point for the next call of inflate(). + enough room in the output buffer), then next_in and avail_in are updated + accordingly, and processing will resume at this point for the next call of + inflate(). - - Provide more output starting at next_out and update next_out and avail_out + - Generate more output starting at next_out and update next_out and avail_out accordingly. inflate() provides as much output as possible, until there is no more input data or no more space in the output buffer (see below about the flush parameter). Before the call of inflate(), the application should ensure that at least one of the actions is possible, by providing more input and/or consuming more - output, and updating the next_* and avail_* values accordingly. The + output, and updating the next_* and avail_* values accordingly. If the + caller of inflate() does not provide both available input and available + output space, it is possible that there will be no progress made. The application can consume the uncompressed output when it wants, for example when the output buffer is full (avail_out == 0), or after each call of inflate(). If inflate returns Z_OK and with zero avail_out, it must be @@ -439,7 +450,7 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); gets to the end of that block, or when it runs out of data. The Z_BLOCK option assists in appending to or combining deflate streams. - Also to assist in this, on return inflate() will set strm->data_type to the + To assist in this, on return inflate() always sets strm->data_type to the number of unused bits in the last byte taken from strm->next_in, plus 64 if inflate() is currently decoding the last block in the deflate stream, plus 128 if inflate() returned immediately after decoding an end-of-block code or @@ -465,7 +476,7 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); this case all pending input is processed and all pending output is flushed; avail_out must be large enough to hold all of the uncompressed data for the operation to complete. (The size of the uncompressed data may have been - saved by the compressor for this purpose.) The use of Z_FINISH is not + saved by the compressor for this purpose.) The use of Z_FINISH is not required to perform an inflation in one step. However it may be used to inform inflate that a faster approach can be used for the single inflate() call. Z_FINISH also informs inflate to not maintain a sliding window if the @@ -487,32 +498,33 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); chosen by the compressor and returns Z_NEED_DICT; otherwise it sets strm->adler to the Adler-32 checksum of all output produced so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described - below. At the end of the stream, inflate() checks that its computed adler32 + below. At the end of the stream, inflate() checks that its computed Adler-32 checksum is equal to that saved by the compressor and returns Z_STREAM_END only if the checksum is correct. inflate() can decompress and check either zlib-wrapped or gzip-wrapped deflate data. The header type is detected automatically, if requested when initializing with inflateInit2(). Any information contained in the gzip - header is not retained, so applications that need that information should - instead use raw inflate, see inflateInit2() below, or inflateBack() and - perform their own processing of the gzip header and trailer. When processing + header is not retained unless inflateGetHeader() is used. When processing gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output - producted so far. The CRC-32 is checked against the gzip trailer. + produced so far. The CRC-32 is checked against the gzip trailer, as is the + uncompressed length, modulo 2^32. inflate() returns Z_OK if some progress has been made (more input processed or more output produced), Z_STREAM_END if the end of the compressed data has been reached and all uncompressed output has been produced, Z_NEED_DICT if a preset dictionary is needed at this point, Z_DATA_ERROR if the input data was corrupted (input stream not conforming to the zlib format or incorrect check - value), Z_STREAM_ERROR if the stream structure was inconsistent (for example - next_in or next_out was Z_NULL), Z_MEM_ERROR if there was not enough memory, - Z_BUF_ERROR if no progress is possible or if there was not enough room in the - output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and + value, in which case strm->msg points to a string with a more specific + error), Z_STREAM_ERROR if the stream structure was inconsistent (for example + next_in or next_out was Z_NULL, or the state was inadvertently written over + by the application), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR + if no progress was possible or if there was not enough room in the output + buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and inflate() can be called again with more input and more output space to continue decompressing. If Z_DATA_ERROR is returned, the application may then call inflateSync() to look for a good compression block if a partial - recovery of the data is desired. + recovery of the data is to be attempted. */ @@ -522,9 +534,8 @@ ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); This function discards any unprocessed input and does not flush any pending output. - inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state - was inconsistent. In the error case, msg may be set but then points to a - static string (which must not be deallocated). + inflateEnd returns Z_OK if success, or Z_STREAM_ERROR if the stream state + was inconsistent. */ @@ -555,16 +566,29 @@ ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, compression at the expense of memory usage. The default value is 15 if deflateInit is used instead. + For the current implementation of deflate(), a windowBits value of 8 (a + window size of 256 bytes) is not supported. As a result, a request for 8 + will result in 9 (a 512-byte window). In that case, providing 8 to + inflateInit2() will result in an error when the zlib header with 9 is + checked against the initialization of inflate(). The remedy is to not use 8 + with deflateInit2() with this initialization, or at least in that case use 9 + with inflateInit2(). + windowBits can also be -8..-15 for raw deflate. In this case, -windowBits determines the window size. deflate() will then generate raw deflate data - with no zlib header or trailer, and will not compute an adler32 check value. + with no zlib header or trailer, and will not compute a check value. windowBits can also be greater than 15 for optional gzip encoding. Add 16 to windowBits to write a simple gzip header and trailer around the compressed data instead of a zlib wrapper. The gzip header will have no file name, no extra data, no comment, no modification time (set to zero), no - header crc, and the operating system will be set to 255 (unknown). If a - gzip stream is being written, strm->adler is a crc32 instead of an adler32. + header crc, and the operating system will be set to the appropriate value, + if the operating system was determined at compile time. If a gzip stream is + being written, strm->adler is a CRC-32 instead of an Adler-32. + + For raw deflate or gzip encoding, a request for a 256-byte window is + rejected as invalid, since only the zlib header provides a means of + transmitting the window size to the decompressor. The memLevel parameter specifies how much memory should be allocated for the internal compression state. memLevel=1 uses minimum memory but is @@ -625,12 +649,12 @@ ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, addition, the current implementation of deflate will use at most the window size minus 262 bytes of the provided dictionary. - Upon return of this function, strm->adler is set to the adler32 value + Upon return of this function, strm->adler is set to the Adler-32 value of the dictionary; the decompressor may later use this value to determine - which dictionary has been used by the compressor. (The adler32 value + which dictionary has been used by the compressor. (The Adler-32 value applies to the whole dictionary even if only a subset of the dictionary is actually used by the compressor.) If a raw deflate was requested, then the - adler32 value is not computed and strm->adler is not set. + Adler-32 value is not computed and strm->adler is not set. deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is @@ -639,6 +663,28 @@ ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, not perform any compression: this will be done by deflate(). */ +ZEXTERN int ZEXPORT deflateGetDictionary OF((z_streamp strm, + Bytef *dictionary, + uInt *dictLength)); +/* + Returns the sliding dictionary being maintained by deflate. dictLength is + set to the number of bytes in the dictionary, and that many bytes are copied + to dictionary. dictionary must have enough space, where 32768 bytes is + always enough. If deflateGetDictionary() is called with dictionary equal to + Z_NULL, then only the dictionary length is returned, and nothing is copied. + Similary, if dictLength is Z_NULL, then it is not set. + + deflateGetDictionary() may return a length less than the window size, even + when more than the window size in input has been provided. It may return up + to 258 bytes less in that case, due to how zlib's implementation of deflate + manages the sliding window and lookahead for matches, where matches can be + up to 258 bytes long. If the application needs the last window-size bytes of + input, then that would need to be saved by the application outside of zlib. + + deflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the + stream state is inconsistent. +*/ + ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, z_streamp source)); /* @@ -659,10 +705,10 @@ ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); /* - This function is equivalent to deflateEnd followed by deflateInit, - but does not free and reallocate all the internal compression state. The - stream will keep the same compression level and any other attributes that - may have been set by deflateInit2. + This function is equivalent to deflateEnd followed by deflateInit, but + does not free and reallocate the internal compression state. The stream + will leave the compression level and any other attributes that may have been + set unchanged. deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc or state being Z_NULL). @@ -673,20 +719,36 @@ ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, int strategy)); /* Dynamically update the compression level and compression strategy. The - interpretation of level and strategy is as in deflateInit2. This can be + interpretation of level and strategy is as in deflateInit2(). This can be used to switch between compression and straight copy of the input data, or to switch to a different kind of input data requiring a different strategy. - If the compression level is changed, the input available so far is - compressed with the old level (and may be flushed); the new level will take - effect only at the next call of deflate(). + If the compression approach (which is a function of the level) or the + strategy is changed, and if any input has been consumed in a previous + deflate() call, then the input available so far is compressed with the old + level and strategy using deflate(strm, Z_BLOCK). There are three approaches + for the compression levels 0, 1..3, and 4..9 respectively. The new level + and strategy will take effect at the next call of deflate(). - Before the call of deflateParams, the stream state must be set as for - a call of deflate(), since the currently available input may have to be - compressed and flushed. In particular, strm->avail_out must be non-zero. + If a deflate(strm, Z_BLOCK) is performed by deflateParams(), and it does + not have enough output space to complete, then the parameter change will not + take effect. In this case, deflateParams() can be called again with the + same parameters and more output space to try again. - deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source - stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR if - strm->avail_out was zero. + In order to assure a change in the parameters on the first try, the + deflate stream should be flushed using deflate() with Z_BLOCK or other flush + request until strm.avail_out is not zero, before calling deflateParams(). + Then no more input data should be provided before the deflateParams() call. + If this is done, the old level and strategy will be applied to the data + compressed before deflateParams(), and the new level and strategy will be + applied to the the data compressed after deflateParams(). + + deflateParams returns Z_OK on success, Z_STREAM_ERROR if the source stream + state was inconsistent or if a parameter was invalid, or Z_BUF_ERROR if + there was not enough output space to complete the compression of the + available input data before a change in the strategy or approach. Note that + in the case of a Z_BUF_ERROR, the parameters are not changed. A return + value of Z_BUF_ERROR is not fatal, in which case deflateParams() can be + retried with more output space. */ ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, @@ -804,7 +866,7 @@ ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, is for use with other formats that use the deflate compressed data format such as zip. Those formats provide their own check values. If a custom format is developed using the raw deflate format for compressed data, it is - recommended that a check value such as an adler32 or a crc32 be applied to + recommended that a check value such as an Adler-32 or a CRC-32 be applied to the uncompressed data as is done in the zlib, gzip, and zip formats. For most applications, the zlib format should be used as is. Note that comments above on the use in deflateInit2() applies to the magnitude of windowBits. @@ -813,7 +875,10 @@ ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, 32 to windowBits to enable zlib and gzip decoding with automatic header detection, or add 16 to decode only the gzip format (the zlib format will return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a - crc32 instead of an adler32. + CRC-32 instead of an Adler-32. Unlike the gunzip utility and gzread() (see + below), inflate() will not automatically decode concatenated gzip streams. + inflate() will return Z_STREAM_END at the end of the gzip stream. The state + would need to be reset to continue decoding a subsequent gzip stream. inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_VERSION_ERROR if the zlib library version is incompatible with the @@ -834,7 +899,7 @@ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, Initializes the decompression dictionary from the given uncompressed byte sequence. This function must be called immediately after a call of inflate, if that call returned Z_NEED_DICT. The dictionary chosen by the compressor - can be determined from the adler32 value returned by that call of inflate. + can be determined from the Adler-32 value returned by that call of inflate. The compressor and decompressor must use exactly the same dictionary (see deflateSetDictionary). For raw inflate, this function can be called at any time to set the dictionary. If the provided dictionary is smaller than the @@ -845,7 +910,7 @@ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the - expected one (incorrect adler32 value). inflateSetDictionary does not + expected one (incorrect Adler-32 value). inflateSetDictionary does not perform any decompression: this will be done by subsequent calls of inflate(). */ @@ -903,7 +968,7 @@ ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); /* This function is equivalent to inflateEnd followed by inflateInit, - but does not free and reallocate all the internal decompression state. The + but does not free and reallocate the internal decompression state. The stream will keep attributes that may have been set by inflateInit2. inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source @@ -915,7 +980,9 @@ ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm, /* This function is the same as inflateReset, but it also permits changing the wrap and window size requests. The windowBits parameter is interpreted - the same as it is for inflateInit2. + the same as it is for inflateInit2. If the window size is changed, then the + memory allocated for the window is freed, and the window will be reallocated + by inflate() if needed. inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc or state being Z_NULL), or if @@ -967,7 +1034,7 @@ ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm)); location in the input stream can be determined from avail_in and data_type as noted in the description for the Z_BLOCK flush parameter for inflate. - inflateMark returns the value noted above or -1 << 16 if the provided + inflateMark returns the value noted above, or -65536 if the provided source stream state was inconsistent. */ @@ -1059,9 +1126,9 @@ ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, This routine would normally be used in a utility that reads zip or gzip files and writes out uncompressed files. The utility would decode the header and process the trailer on its own, hence this routine expects only - the raw deflate stream to decompress. This is different from the normal - behavior of inflate(), which expects either a zlib or gzip header and - trailer around the deflate stream. + the raw deflate stream to decompress. This is different from the default + behavior of inflate(), which expects a zlib header and trailer around the + deflate stream. inflateBack() uses two subroutines supplied by the caller that are then called by inflateBack() for input and output. inflateBack() calls those @@ -1070,12 +1137,12 @@ ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, parameters and return types are defined above in the in_func and out_func typedefs. inflateBack() will call in(in_desc, &buf) which should return the number of bytes of provided input, and a pointer to that input in buf. If - there is no input available, in() must return zero--buf is ignored in that - case--and inflateBack() will return a buffer error. inflateBack() will call - out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out() - should return zero on success, or non-zero on failure. If out() returns - non-zero, inflateBack() will return with an error. Neither in() nor out() - are permitted to change the contents of the window provided to + there is no input available, in() must return zero -- buf is ignored in that + case -- and inflateBack() will return a buffer error. inflateBack() will + call out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. + out() should return zero on success, or non-zero on failure. If out() + returns non-zero, inflateBack() will return with an error. Neither in() nor + out() are permitted to change the contents of the window provided to inflateBackInit(), which is also the buffer that out() uses to write from. The length written by out() will be at most the window size. Any non-zero amount of input may be provided by in(). @@ -1103,7 +1170,7 @@ ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, using strm->next_in which will be Z_NULL only if in() returned an error. If strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning non-zero. (in() will always be called before out(), so strm->next_in is - assured to be defined if out() returns non-zero.) Note that inflateBack() + assured to be defined if out() returns non-zero.) Note that inflateBack() cannot return Z_OK. */ @@ -1125,7 +1192,7 @@ ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); 7.6: size of z_off_t Compiler, assembler, and debug options: - 8: DEBUG + 8: ZLIB_DEBUG 9: ASMV or ASMINF -- use ASM code 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention 11: 0 (reserved) @@ -1175,7 +1242,8 @@ ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, the byte length of the source buffer. Upon entry, destLen is the total size of the destination buffer, which must be at least the value returned by compressBound(sourceLen). Upon exit, destLen is the actual size of the - compressed buffer. + compressed data. compress() is equivalent to compress2() with a level + parameter of Z_DEFAULT_COMPRESSION. compress returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if there was not enough room in the output @@ -1191,7 +1259,7 @@ ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, length of the source buffer. Upon entry, destLen is the total size of the destination buffer, which must be at least the value returned by compressBound(sourceLen). Upon exit, destLen is the actual size of the - compressed buffer. + compressed data. compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if there was not enough room in the output buffer, @@ -1214,7 +1282,7 @@ ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, uncompressed data. (The size of the uncompressed data must have been saved previously by the compressor and transmitted to the decompressor by some mechanism outside the scope of this compression library.) Upon exit, destLen - is the actual size of the uncompressed buffer. + is the actual size of the uncompressed data. uncompress returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if there was not enough room in the output @@ -1223,6 +1291,14 @@ ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, buffer with the uncompressed data up to that point. */ +ZEXTERN int ZEXPORT uncompress2 OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong *sourceLen)); +/* + Same as uncompress, except that sourceLen is a pointer, where the + length of the source is *sourceLen. On return, *sourceLen is the number of + source bytes consumed. +*/ + /* gzip file access functions */ /* @@ -1301,10 +1377,9 @@ ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size)); default buffer size is 8192 bytes. This function must be called after gzopen() or gzdopen(), and before any other calls that read or write the file. The buffer memory allocation is always deferred to the first read or - write. Two buffers are allocated, either both of the specified size when - writing, or one of the specified size and the other twice that size when - reading. A larger buffer size of, for example, 64K or 128K bytes will - noticeably increase the speed of decompression (reading). + write. Three times that size in buffer space is allocated. A larger buffer + size of, for example, 64K or 128K bytes will noticeably increase the speed + of decompression (reading). The new buffer size also affects the maximum length for gzprintf(). @@ -1315,10 +1390,12 @@ ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size)); ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); /* Dynamically update the compression level or strategy. See the description - of deflateInit2 for the meaning of these parameters. + of deflateInit2 for the meaning of these parameters. Previously provided + data is flushed before the parameter change. - gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not - opened for writing. + gzsetparams returns Z_OK if success, Z_STREAM_ERROR if the file was not + opened for writing, Z_ERRNO if there is an error writing the flushed data, + or Z_MEM_ERROR if there is a memory allocation error. */ ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); @@ -1346,7 +1423,35 @@ ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); case. gzread returns the number of uncompressed bytes actually read, less than - len for end of file, or -1 for error. + len for end of file, or -1 for error. If len is too large to fit in an int, + then nothing is read, -1 is returned, and the error state is set to + Z_STREAM_ERROR. +*/ + +ZEXTERN z_size_t ZEXPORT gzfread OF((voidp buf, z_size_t size, z_size_t nitems, + gzFile file)); +/* + Read up to nitems items of size size from file to buf, otherwise operating + as gzread() does. This duplicates the interface of stdio's fread(), with + size_t request and return types. If the library defines size_t, then + z_size_t is identical to size_t. If not, then z_size_t is an unsigned + integer type that can contain a pointer. + + gzfread() returns the number of full items read of size size, or zero if + the end of the file was reached and a full item could not be read, or if + there was an error. gzerror() must be consulted if zero is returned in + order to determine if there was an error. If the multiplication of size and + nitems overflows, i.e. the product does not fit in a z_size_t, then nothing + is read, zero is returned, and the error state is set to Z_STREAM_ERROR. + + In the event that the end of file is reached and only a partial item is + available at the end, i.e. the remaining uncompressed data length is not a + multiple of size, then the final partial item is nevetheless read into buf + and the end-of-file flag is set. The length of the partial item read is not + provided, but could be inferred from the result of gztell(). This behavior + is the same as the behavior of fread() implementations in common libraries, + but it prevents the direct use of gzfread() to read a concurrently written + file, reseting and retrying on end-of-file, when size is not 1. */ ZEXTERN int ZEXPORT gzwrite OF((gzFile file, @@ -1357,19 +1462,33 @@ ZEXTERN int ZEXPORT gzwrite OF((gzFile file, error. */ +ZEXTERN z_size_t ZEXPORT gzfwrite OF((voidpc buf, z_size_t size, + z_size_t nitems, gzFile file)); +/* + gzfwrite() writes nitems items of size size from buf to file, duplicating + the interface of stdio's fwrite(), with size_t request and return types. If + the library defines size_t, then z_size_t is identical to size_t. If not, + then z_size_t is an unsigned integer type that can contain a pointer. + + gzfwrite() returns the number of full items written of size size, or zero + if there was an error. If the multiplication of size and nitems overflows, + i.e. the product does not fit in a z_size_t, then nothing is written, zero + is returned, and the error state is set to Z_STREAM_ERROR. +*/ + ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...)); /* Converts, formats, and writes the arguments to the compressed file under control of the format string, as in fprintf. gzprintf returns the number of - uncompressed bytes actually written, or 0 in case of error. The number of - uncompressed bytes written is limited to 8191, or one less than the buffer - size given to gzbuffer(). The caller should assure that this limit is not - exceeded. If it is exceeded, then gzprintf() will return an error (0) with - nothing written. In this case, there may also be a buffer overflow with - unpredictable consequences, which is possible only if zlib was compiled with - the insecure functions sprintf() or vsprintf() because the secure snprintf() - or vsnprintf() functions were not available. This can be determined using - zlibCompileFlags(). + uncompressed bytes actually written, or a negative zlib error code in case + of error. The number of uncompressed bytes written is limited to 8191, or + one less than the buffer size given to gzbuffer(). The caller should assure + that this limit is not exceeded. If it is exceeded, then gzprintf() will + return an error (0) with nothing written. In this case, there may also be a + buffer overflow with unpredictable consequences, which is possible only if + zlib was compiled with the insecure functions sprintf() or vsprintf() + because the secure snprintf() or vsnprintf() functions were not available. + This can be determined using zlibCompileFlags(). */ ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); @@ -1429,7 +1548,7 @@ ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); If the flush parameter is Z_FINISH, the remaining data is written and the gzip stream is completed in the output. If gzwrite() is called again, a new gzip stream will be started in the output. gzread() is able to read such - concatented gzip streams. + concatenated gzip streams. gzflush should be called only when strictly necessary because it will degrade compression if called too often. @@ -1583,7 +1702,7 @@ ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); return the updated checksum. If buf is Z_NULL, this function returns the required initial value for the checksum. - An Adler-32 checksum is almost as reliable as a CRC32 but can be computed + An Adler-32 checksum is almost as reliable as a CRC-32 but can be computed much faster. Usage example: @@ -1596,6 +1715,12 @@ ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); if (adler != original_adler) error(); */ +ZEXTERN uLong ZEXPORT adler32_z OF((uLong adler, const Bytef *buf, + z_size_t len)); +/* + Same as adler32(), but with a size_t length. +*/ + /* ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, z_off_t len2)); @@ -1625,6 +1750,12 @@ ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); if (crc != original_crc) error(); */ +ZEXTERN uLong ZEXPORT crc32_z OF((uLong adler, const Bytef *buf, + z_size_t len)); +/* + Same as crc32(), but with a size_t length. +*/ + /* ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); @@ -1655,19 +1786,35 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, unsigned char FAR *window, const char *version, int stream_size)); -#define deflateInit(strm, level) \ - deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) -#define inflateInit(strm) \ - inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) -#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ - deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ - (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) -#define inflateInit2(strm, windowBits) \ - inflateInit2_((strm), (windowBits), ZLIB_VERSION, \ - (int)sizeof(z_stream)) -#define inflateBackInit(strm, windowBits, window) \ - inflateBackInit_((strm), (windowBits), (window), \ - ZLIB_VERSION, (int)sizeof(z_stream)) +#ifdef Z_PREFIX_SET +# define z_deflateInit(strm, level) \ + deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) +# define z_inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) +# define z_deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) +# define z_inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, \ + (int)sizeof(z_stream)) +# define z_inflateBackInit(strm, windowBits, window) \ + inflateBackInit_((strm), (windowBits), (window), \ + ZLIB_VERSION, (int)sizeof(z_stream)) +#else +# define deflateInit(strm, level) \ + deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) +# define inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) +# define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) +# define inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, \ + (int)sizeof(z_stream)) +# define inflateBackInit(strm, windowBits, window) \ + inflateBackInit_((strm), (windowBits), (window), \ + ZLIB_VERSION, (int)sizeof(z_stream)) +#endif #ifndef Z_SOLO @@ -1687,10 +1834,10 @@ ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */ #ifdef Z_PREFIX_SET # undef z_gzgetc # define z_gzgetc(g) \ - ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g)) + ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : (gzgetc)(g)) #else # define gzgetc(g) \ - ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g)) + ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : (gzgetc)(g)) #endif /* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or @@ -1748,19 +1895,16 @@ ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); #endif /* !Z_SOLO */ -/* hack for buggy compilers */ -#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) -struct internal_state {int dummy;}; -#endif - /* undocumented functions */ ZEXTERN const char *ZEXPORT zError OF((int)); ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp)); ZEXTERN const z_crc_t FAR *ZEXPORT get_crc_table OF((void)); ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int)); +ZEXTERN int ZEXPORT inflateValidate OF((z_streamp, int)); +ZEXTERN unsigned long ZEXPORT inflateCodesUsed OF((z_streamp)); ZEXTERN int ZEXPORT inflateResetKeep OF((z_streamp)); ZEXTERN int ZEXPORT deflateResetKeep OF((z_streamp)); -#if defined(_WIN32) && !defined(Z_SOLO) +#if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(Z_SOLO) ZEXTERN gzFile ZEXPORT gzopen_w OF((const wchar_t *path, const char *mode)); #endif diff --git a/common/zlib/zutil.c b/common/zlib/zutil.c index 30f453872..2d70d74c9 100644 --- a/common/zlib/zutil.c +++ b/common/zlib/zutil.c @@ -1,5 +1,5 @@ /* zutil.c -- target dependent utility functions for the compression library - * Copyright (C) 1995-2005, 2010, 2011, 2012 Jean-loup Gailly. + * Copyright (C) 1995-2017 Jean-loup Gailly * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -10,21 +10,17 @@ # include "gzguts.h" #endif -#ifndef NO_DUMMY_DECL -struct internal_state {int dummy;}; /* for buggy compilers */ -#endif - z_const char *const z_errmsg[10] = { - "need dictionary", /* Z_NEED_DICT 2 */ - "stream end", /* Z_STREAM_END 1 */ - "", /* Z_OK 0 */ - "file error", /* Z_ERRNO (-1) */ - "stream error", /* Z_STREAM_ERROR (-2) */ - "data error", /* Z_DATA_ERROR (-3) */ - "insufficient memory", /* Z_MEM_ERROR (-4) */ - "buffer error", /* Z_BUF_ERROR (-5) */ - "incompatible version",/* Z_VERSION_ERROR (-6) */ - "" + (z_const char *)"need dictionary", /* Z_NEED_DICT 2 */ + (z_const char *)"stream end", /* Z_STREAM_END 1 */ + (z_const char *)"", /* Z_OK 0 */ + (z_const char *)"file error", /* Z_ERRNO (-1) */ + (z_const char *)"stream error", /* Z_STREAM_ERROR (-2) */ + (z_const char *)"data error", /* Z_DATA_ERROR (-3) */ + (z_const char *)"insufficient memory", /* Z_MEM_ERROR (-4) */ + (z_const char *)"buffer error", /* Z_BUF_ERROR (-5) */ + (z_const char *)"incompatible version",/* Z_VERSION_ERROR (-6) */ + (z_const char *)"" }; @@ -84,7 +80,7 @@ uLong ZEXPORT zlibCompileFlags() { default: flags += 3 << 6; } -#ifdef DEBUG +#ifdef ZLIB_DEBUG flags += 1 << 8; #endif #if defined(ASMV) || defined(ASMINF) @@ -138,8 +134,8 @@ uLong ZEXPORT zlibCompileFlags() { return flags; } -#ifdef DEBUG - +#ifdef ZLIB_DEBUG +#include # ifndef verbose # define verbose 0 # endif @@ -241,9 +237,11 @@ local ptr_table table[MAX_PTR]; */ voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, unsigned size) { - voidpf buf = opaque; /* just to make some compilers happy */ + voidpf buf; ulg bsize = (ulg)items * size; + (void)opaque; + /* If we allocate less than 65520 bytes, we assume that farmalloc * will return a usable pointer which doesn't have to be normalized. */ @@ -265,6 +263,9 @@ voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, unsigned size) { void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) { int n; + + (void)opaque; + if (*(ush *)&ptr != 0) { /* object < 64K */ farfree(ptr); return; @@ -280,7 +281,6 @@ void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) { next_ptr--; return; } - ptr = opaque; /* just to make some compilers happy */ Assert(0, "zcfree: ptr not found"); } @@ -298,12 +298,12 @@ void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) { #endif voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, uInt items, uInt size) { - if (opaque) opaque = 0; /* to make compiler happy */ + (void)opaque; return _halloc((long)items, size); } void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) { - if (opaque) opaque = 0; /* to make compiler happy */ + (void)opaque; _hfree(ptr); } @@ -325,7 +325,7 @@ voidpf opaque; unsigned items; unsigned size; { - if (opaque) items += size - size; /* make compiler happy */ + (void)opaque; return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : (voidpf)calloc(items, size); } @@ -334,8 +334,8 @@ void ZLIB_INTERNAL zcfree(opaque, ptr) voidpf opaque; voidpf ptr; { + (void)opaque; free(ptr); - if (opaque) return; /* make compiler happy */ } #endif /* MY_ZCALLOC */ diff --git a/common/zlib/zutil.h b/common/zlib/zutil.h index a421df882..a5bf91366 100644 --- a/common/zlib/zutil.h +++ b/common/zlib/zutil.h @@ -1,5 +1,5 @@ /* zutil.h -- internal interface and configuration of the compression library - * Copyright (C) 1995-2013 Jean-loup Gailly. + * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -36,7 +36,9 @@ typedef long ptrdiff_t; /* guess -- will be caught if guess is wrong */ #ifndef local # define local static #endif -/* compile with -Dlocal if your debugger can't find static symbols */ +/* since "static" is used to mean two completely different things in C, we + define "local" for the non-static meaning of "static", for readability + (compile with -Dlocal if your debugger can't find static symbols) */ typedef unsigned char uch; typedef uch FAR uchf; @@ -98,28 +100,38 @@ void *_Cdecl farmalloc(unsigned long nbytes); #endif #ifdef AMIGA -# define OS_CODE 0x01 +# define OS_CODE 1 #endif #if defined(VAXC) || defined(VMS) -# define OS_CODE 0x02 +# define OS_CODE 2 # define F_OPEN(name, mode) \ fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") #endif +#ifdef __370__ +# if __TARGET_LIB__ < 0x20000000 +# define OS_CODE 4 +# elif __TARGET_LIB__ < 0x40000000 +# define OS_CODE 11 +# else +# define OS_CODE 8 +# endif +#endif + #if defined(ATARI) || defined(atarist) -# define OS_CODE 0x05 +# define OS_CODE 5 #endif #ifdef OS2 -# define OS_CODE 0x06 +# define OS_CODE 6 # if defined(M_I86) && !defined(Z_SOLO) # include # endif #endif #if defined(MACOS) || defined(TARGET_OS_MAC) -# define OS_CODE 0x07 +# define OS_CODE 7 # ifndef Z_SOLO # if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os # include /* for fdopen */ @@ -131,18 +143,24 @@ void *_Cdecl farmalloc(unsigned long nbytes); # endif #endif -#ifdef TOPS20 -# define OS_CODE 0x0a +#ifdef __acorn +# define OS_CODE 13 #endif -#ifdef WIN32 -# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */ -# define OS_CODE 0x0b -# endif +#if defined(WIN32) && !defined(__CYGWIN__) +# define OS_CODE 10 #endif -#ifdef __50SERIES /* Prime/PRIMOS */ -# define OS_CODE 0x0f +#ifdef _BEOS_ +# define OS_CODE 16 +#endif + +#ifdef __TOS_OS400__ +# define OS_CODE 18 +#endif + +#ifdef __APPLE__ +# define OS_CODE 19 #endif #if defined(_BEOS_) || defined(RISCOS) @@ -177,7 +195,7 @@ ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); /* common defaults */ #ifndef OS_CODE -# define OS_CODE 0x03 /* assume Unix */ +# define OS_CODE 3 /* assume Unix */ #endif #ifndef F_OPEN @@ -216,7 +234,7 @@ void ZLIB_INTERNAL zmemzero OF((Bytef *dest, uInt len)); #endif /* Diagnostic functions */ -#ifdef DEBUG +#ifdef ZLIB_DEBUG # include extern int ZLIB_INTERNAL z_verbose; extern void ZLIB_INTERNAL z_error OF((char *m)); From a3232e6ef573b584f577e92dc0c79ef4be295dd2 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 22 Sep 2019 18:21:12 +0200 Subject: [PATCH 0757/1854] zlib: protect CLEAR_HASH macro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix compilation warning (and probably bug): deflate.c l608 some parts of macro expansion are not guarded by this ‘else’ clause --- common/zlib/deflate.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/common/zlib/deflate.c b/common/zlib/deflate.c index f63751eed..a44bdb3ab 100644 --- a/common/zlib/deflate.c +++ b/common/zlib/deflate.c @@ -195,9 +195,10 @@ local const config configuration_table[10] = { * Initialize the hash table (avoiding 64K overflow for 16 bit systems). * prev[] will be initialized on the fly. */ -#define CLEAR_HASH(s) \ +#define CLEAR_HASH(s) {\ s->head[s->hash_size-1] = NIL; \ - zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); + zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); \ +} /* =========================================================================== * Slide the hash table when sliding the window down (could be avoided with 32 From 66ccca645705ecec407b77c9a4dcd028b79f5bdf Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 22 Sep 2019 18:57:52 +0200 Subject: [PATCH 0758/1854] fix 'lf io watch' - now loops w correct size and crc var. 'lf awid watch' - now loops w correct size --- armsrc/lfops.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/armsrc/lfops.c b/armsrc/lfops.c index ab0467c85..e8fb49698 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -1245,6 +1245,10 @@ void CmdAWIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol) DoAcquisition_default(-1, true); // FSK demodulator + size = BigBuf_max_traceLen(); + //askdemod and manchester decode + if (size > 12800) size = 12800; //big enough to catch 2 sequences of largest format + int idx = detectAWID(dest, &size, &dummyIdx); if (idx <= 0 || size != 96) continue; @@ -1306,10 +1310,10 @@ void CmdAWIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol) *low = rawLo; break; } - WDT_HIT(); } + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - DbpString("Stopped"); + DbpString("AWID fsk demod stopped"); if (ledcontrol) LED_A_OFF(); } @@ -1366,12 +1370,12 @@ void CmdEM410xdemod(int findone, uint32_t *high, uint64_t *low, int ledcontrol) break; } } - WDT_HIT(); hi = lo = size = idx = 0; clk = invert = 0; } + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - DbpString("Stopped"); + DbpString("EM man/ask demod stopped"); if (ledcontrol) LED_A_OFF(); } @@ -1398,7 +1402,10 @@ void CmdIOdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol) { DoAcquisition_default(-1, true); //fskdemod and get start index - WDT_HIT(); + size = BigBuf_max_traceLen(); + //askdemod and manchester decode + if (size > 12000) size = 12000; //big enough to catch 2 sequences of largest format + int idx = detectIOProx(dest, &size, &dummyIdx); if (idx < 0) continue; //valid tag found @@ -1455,10 +1462,11 @@ void CmdIOdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol) { code = code2 = 0; version = facilitycode = 0; number = 0; - WDT_HIT(); + calccrc = 0; } + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - DbpString("Stopped"); + DbpString("IOProx fsk demod stopped"); if (ledcontrol) LED_A_OFF(); } From 3e0b93f199be458900a1cc280bb7ee7e83101064 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 22 Sep 2019 18:58:49 +0200 Subject: [PATCH 0759/1854] lf hid/io/awid watch - loops --- armsrc/appmain.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 0ac021400..56cfec1de 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -698,7 +698,7 @@ static void PacketReceived(PacketCommandNG *packet) { } case CMD_LF_HID_DEMOD: { uint32_t high, low; - CmdHIDdemodFSK(packet->oldarg[0], &high, &low, 1); + CmdHIDdemodFSK(0, &high, &low, 1); break; } case CMD_LF_HID_SIMULATE: { @@ -727,7 +727,7 @@ static void PacketReceived(PacketCommandNG *packet) { } case CMD_LF_IO_DEMOD: { uint32_t high, low; - CmdIOdemodFSK(packet->oldarg[0], &high, &low, 1); + CmdIOdemodFSK(0, &high, &low, 1); break; } case CMD_LF_EM410X_DEMOD: { @@ -838,7 +838,7 @@ static void PacketReceived(PacketCommandNG *packet) { case CMD_LF_AWID_DEMOD: { uint32_t high, low; // Set realtime AWID demodulation - CmdAWIDdemodFSK(packet->oldarg[0], &high, &low, 1); + CmdAWIDdemodFSK(0, &high, &low, 1); break; } case CMD_LF_VIKING_CLONE: { From 9a0ca9c4cd61495a65ecc53dc51f6f73e9e05b8c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 22 Sep 2019 19:00:11 +0200 Subject: [PATCH 0760/1854] better median for clietside 10%-90% only. thanks for the suggestion @doegox!. Device side still uses old algo --- common/lfdemod.c | 93 +++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 76 insertions(+), 17 deletions(-) diff --git a/common/lfdemod.c b/common/lfdemod.c index 8e60eda0d..8852b9c00 100644 --- a/common/lfdemod.c +++ b/common/lfdemod.c @@ -38,11 +38,12 @@ #include "lfdemod.h" #include // for memset, memcmp and size_t +#include // qsort #include "parity.h" // for parity test #include "pm3_cmd.h" // error codes -//********************************************************************************************** -//---------------------------------Utilities Section-------------------------------------------- -//********************************************************************************************** +// ********************************************************************************************** +// ---------------------------------Utilities Section-------------------------------------------- +// ********************************************************************************************** #define LOWEST_DEFAULT_CLOCK 32 #define FSK_PSK_THRESHOLD 123 @@ -81,18 +82,53 @@ static void printSignal(void) { prnt(" THRESHOLD noise amplitude......%d", NOISE_AMPLITUDE_THRESHOLD); } +#ifndef ON_DEVICE +static int cmp_uint8(const void *a, const void *b) { + if (*(const uint8_t *)a < * (const uint8_t *)b) + return -1; + else + return *(const uint8_t *)a > *(const uint8_t *)b; +} +#endif + void computeSignalProperties(uint8_t *samples, uint32_t size) { resetSignal(); + if (samples == NULL || size < SIGNAL_MIN_SAMPLES) return; + uint32_t sum = 0; - for (uint32_t i = 0; i < size; i++) { + uint32_t offset_size = size - SIGNAL_IGNORE_FIRST_SAMPLES; + +#ifndef ON_DEVICE + uint8_t tmp[offset_size]; + memcpy(tmp, samples + SIGNAL_IGNORE_FIRST_SAMPLES, sizeof(tmp)); + qsort(tmp, sizeof(tmp), sizeof(uint8_t), cmp_uint8); + + uint8_t low10 = 0.5 * (tmp[(int)(offset_size * 0.1)] + tmp[(int)((offset_size - 1) * 0.1)]); + uint8_t hi90 = 0.5 * (tmp[(int)(offset_size * 0.9)] + tmp[(int)((offset_size - 1) * 0.9)]); + uint32_t cnt = 0; + for (uint32_t i = SIGNAL_IGNORE_FIRST_SAMPLES; i < size; i++) { + + if (samples[i] < signalprop.low) signalprop.low = samples[i]; + if (samples[i] > signalprop.high) signalprop.high = samples[i]; + + if (samples[i] < low10 || samples[i] > hi90) + continue; + + sum += samples[i]; + cnt++; + } + signalprop.mean = sum / cnt; +#else + for (uint32_t i = SIGNAL_IGNORE_FIRST_SAMPLES; i < size; i++) { if (samples[i] < signalprop.low) signalprop.low = samples[i]; if (samples[i] > signalprop.high) signalprop.high = samples[i]; sum += samples[i]; } + signalprop.mean = sum / offset_size; +#endif // measure amplitude of signal - signalprop.mean = sum / size; signalprop.amplitude = signalprop.high - signalprop.mean; // By measuring mean and look at amplitude of signal from HIGH / LOW, // we can detect noise @@ -106,9 +142,32 @@ void removeSignalOffset(uint8_t *samples, uint32_t size) { if (samples == NULL || size < SIGNAL_MIN_SAMPLES) return; int acc_off = 0; + uint32_t offset_size = size - SIGNAL_IGNORE_FIRST_SAMPLES; + +#ifndef ON_DEVICE + + uint8_t tmp[offset_size]; + memcpy(tmp, samples + SIGNAL_IGNORE_FIRST_SAMPLES, sizeof(tmp)); + qsort(tmp, sizeof(tmp), sizeof(uint8_t), cmp_uint8); + + uint8_t low10 = 0.5 * (tmp[(int)(offset_size * 0.05)] + tmp[(int)((offset_size - 1) * 0.05)]); + uint8_t hi90 = 0.5 * (tmp[(int)(offset_size * 0.95)] + tmp[(int)((offset_size - 1) * 0.95)]); + int32_t cnt = 0; + for (uint32_t i = SIGNAL_IGNORE_FIRST_SAMPLES; i < size; i++) { + + if (samples[i] < low10 || samples[i] > hi90) + continue; + + acc_off += samples[i] - 128; + cnt++; + } + acc_off /= cnt; +#else for (uint32_t i = SIGNAL_IGNORE_FIRST_SAMPLES; i < size; i++) acc_off += samples[i] - 128; - acc_off /= (int)(size - SIGNAL_IGNORE_FIRST_SAMPLES); + + acc_off /= (int)offset_size; +#endif // shift and saturate samples to center the mean for (uint32_t i = 0; i < size; i++) { @@ -265,13 +324,13 @@ bool preambleSearchEx(uint8_t *bits, uint8_t *preamble, size_t pLen, size_t *siz //first index found foundCnt++; if (foundCnt == 1) { - prnt("DEBUG: (preambleSearchEx) preamble found at %i", idx); + if (g_debugMode >= 1) prnt("DEBUG: (preambleSearchEx) preamble found at %i", idx); *startIdx = idx; if (findone) return true; } if (foundCnt == 2) { - prnt("DEBUG: (preambleSearchEx) preamble 2 found at %i", idx); + if (g_debugMode >= 1) prnt("DEBUG: (preambleSearchEx) preamble 2 found at %i", idx); *size = idx - *startIdx; return true; } @@ -479,9 +538,9 @@ bool DetectCleanAskWave(uint8_t *dest, size_t size, uint8_t high, uint8_t low) { } -//********************************************************************************************** -//-------------------Clock / Bitrate Detection Section------------------------------------------ -//********************************************************************************************** +// ********************************************************************************************** +// -------------------Clock / Bitrate Detection Section------------------------------------------ +// ********************************************************************************************** // by marshmellow @@ -1176,9 +1235,9 @@ uint8_t detectFSKClk(uint8_t *bits, size_t size, uint8_t fcHigh, uint8_t fcLow, } -//********************************************************************************************** -//--------------------Modulation Demods &/or Decoding Section----------------------------------- -//********************************************************************************************** +// ********************************************************************************************** +// --------------------Modulation Demods &/or Decoding Section----------------------------------- +// ********************************************************************************************** // look for Sequence Terminator - should be pulses of clk*(1 or 2), clk*2, clk*(1.5 or 2), by idx we mean graph position index... @@ -1985,9 +2044,9 @@ int pskRawDemod(uint8_t *dest, size_t *size, int *clock, int *invert) { } -//********************************************************************************************** -//-----------------Tag format detection section------------------------------------------------- -//********************************************************************************************** +// ********************************************************************************************** +// -----------------Tag format detection section------------------------------------------------- +// ********************************************************************************************** // by marshmellow From 361136f06d5a57ee419d6ace2b17886709cd313a Mon Sep 17 00:00:00 2001 From: mwalker33 Date: Mon, 23 Sep 2019 21:04:33 +1000 Subject: [PATCH 0761/1854] Update cmdlfem4x.c dump display and save to file --- client/cmdlfem4x.c | 59 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 45 insertions(+), 14 deletions(-) diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c index ec535205e..36c2089d8 100644 --- a/client/cmdlfem4x.c +++ b/client/cmdlfem4x.c @@ -16,6 +16,7 @@ #include #include +#include "fileutils.h" #include "cmdparser.h" // command_t #include "comms.h" #include "commonutil.h" @@ -1199,48 +1200,78 @@ static int EM4x05ReadWord_ext(uint8_t addr, uint32_t pwd, bool usePwd, uint32_t return demodEM4x05resp(word); } +#define swapedEndian(num) ((num>>24)&0xff) | ((num<<8)&0xff0000) | ((num>>8)&0xff00) | ((num<<24)&0xff000000) + static int CmdEM4x05Dump(const char *Cmd) { uint8_t addr = 0; uint32_t pwd = 0; bool usePwd = false; - uint8_t ctmp = tolower(param_getchar(Cmd, 0)); +//uint8_t ctmp = tolower(param_getchar(Cmd, 0)); + uint8_t cmdp = 0; uint8_t bytes[4] = {0}; + uint32_t data[16]; + char preferredName[FILE_PATH_SIZE] = {0}; + bool save = false; - if (ctmp == 'h') return usage_lf_em4x05_dump(); - + while (param_getchar(Cmd, cmdp) != 0x00) { + switch (tolower(param_getchar(Cmd, cmdp))) { + case 'h': return usage_lf_em4x05_dump(); + break; + case 's': param_getstr(Cmd, cmdp + 1, preferredName, FILE_PATH_SIZE); + save = true; + cmdp+=2; + break; + default : // for backwards-compatibility options should be > 'f' else assume its the hex password` + pwd = param_get32ex(Cmd, cmdp, 1, 16); + usePwd = true; + cmdp++; + }; + } +// if (ctmp == 'h') return usage_lf_em4x05_dump(); +// if (ctmp == 's') { // save dump +// +// } // for now use default input of 1 as invalid (unlikely 1 will be a valid password...) - pwd = param_get32ex(Cmd, 0, 1, 16); +// pwd = param_get32ex(Cmd, 0, 1, 16); - if (pwd != 1) - usePwd = true; + // if (pwd != 1) + // usePwd = true; int success = PM3_SUCCESS; int status; uint32_t word = 0; - PrintAndLogEx(NORMAL, "Addr | data | ascii"); - PrintAndLogEx(NORMAL, "-----+----------+-------"); + PrintAndLogEx(NORMAL, "Addr | data | ascii | info"); + PrintAndLogEx(NORMAL, "-----+----------+-------+------"); for (; addr < 16; addr++) { if (addr == 2) { if (usePwd) { - PrintAndLogEx(NORMAL, " %02u | %08X |", addr, pwd, word); + data[addr] = swapedEndian(pwd); + num_to_bytes(pwd, 4, bytes); + PrintAndLogEx(NORMAL, " %02u | %08X | %s | password", addr, pwd, sprint_ascii(bytes, 4)); } else { - PrintAndLogEx(NORMAL, " 02 | | " _RED_("cannot read")); + data[addr] = 0x00; // Unknown password, but not used to set to zeros + PrintAndLogEx(NORMAL, " 02 | | | " _RED_("cannot read")); } } else { // success &= EM4x05ReadWord_ext(addr, pwd, usePwd, &word); status = EM4x05ReadWord_ext(addr, pwd, usePwd, &word); // Get status for single read success &= status; // Update status to match previous return - + data[addr] = swapedEndian(word); if (status == PM3_SUCCESS) { num_to_bytes(word, 4, bytes); - PrintAndLogEx(NORMAL, " %02d | %08X | %s", addr, word, (addr > 13) ? "Lock" : sprint_ascii(bytes, 4)); + PrintAndLogEx(NORMAL, " %02d | %08X | %s | %s", addr, word, sprint_ascii(bytes, 4), (addr > 13) ? "Lock" : ""); } else - PrintAndLogEx(NORMAL, " %02d | | " _RED_("Fail"), addr); + PrintAndLogEx(NORMAL, " %02d | | | " _RED_("Fail"), addr); } } - + + if ((success == PM3_SUCCESS) && (save)) {// all ok save dump to file + saveFileEML(preferredName, (uint8_t *)data, 16*sizeof(uint32_t), sizeof(uint32_t)); + saveFile (preferredName, ".bin", data, sizeof(data)); + } + return success; } From fe2be43380f3e4d152eaf7e3f7e79e3e6da6f50c Mon Sep 17 00:00:00 2001 From: Iceman Date: Mon, 23 Sep 2019 16:40:48 +0200 Subject: [PATCH 0762/1854] Update extensions_notes.md --- doc/extensions_notes.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/extensions_notes.md b/doc/extensions_notes.md index f8d4c75c1..41365849b 100644 --- a/doc/extensions_notes.md +++ b/doc/extensions_notes.md @@ -7,7 +7,7 @@ The Proxmark3 client uses a wide range of files. Here is a brief recap to get yo | .exe | windows executable | | .bin | binary file, can be firmware or memory dump of a tag | | .eml | text file, with memory dump of a tag | -| .mfd | binary file, usually created with Mifare Classic Tool app (MCT), contains memory dump of tag. Very similar to .bin file | +| .mfd | binary file, MIFARE file dump, name comes from NFC-Tools. Usually created with Mifare Classic Tool app (MCT) or NFC-Tools, contains memory dump of tag. Very similar to .bin file | | .json | JSON file, usually settings file or it can also be a memory dump of a tag | | .dic | dictionary file. textual, with keys/passwords one line / key | | .elf | binary proxmark3 device firmware file. | @@ -15,3 +15,5 @@ The Proxmark3 client uses a wide range of files. Here is a brief recap to get yo | .lua | text file, contains lua script to be run inside client. or called with -l | | .pm3 | text file, with numbers ranging 0-255 or -127 - 128. Contains trace signal data for low frequency tags (data load) | | .trace | binary file, contains trace log data usually from high frequency tags. (hw trace load) | +| .log | text file, our log file, contains the output from almost all commands you run inside Proxmark3 client | +| .history | text file, our command log file, contains the commands you ran inside Proxmark3 client | From c36baab3c012f2e4fe7073ce2f024ef120b10a79 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 23 Sep 2019 17:10:43 +0200 Subject: [PATCH 0763/1854] releasing pressure on stack --- client/cmddata.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/client/cmddata.c b/client/cmddata.c index d1df2be65..a6a2a5cf7 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -518,7 +518,6 @@ int ASKDemod_ext(const char *Cmd, bool verbose, bool emSearch, uint8_t askType, size_t maxLen = 0; uint8_t askamp = 0; char amp = tolower(param_getchar(Cmd, 0)); - uint8_t bits[MAX_GRAPH_TRACE_LEN] = {0}; sscanf(Cmd, "%i %i %i %zu %c", &clk, &invert, &maxErr, &maxLen, &); @@ -533,12 +532,19 @@ int ASKDemod_ext(const char *Cmd, bool verbose, bool emSearch, uint8_t askType, invert = 1; clk = 0; } + uint8_t *bits = calloc(MAX_GRAPH_TRACE_LEN, sizeof(uint8_t)); + if (bits == NULL) { + return PM3_EMALLOC; + } size_t BitLen = getFromGraphBuf(bits); PrintAndLogEx(DEBUG, "DEBUG: (ASKDemod_ext) #samples from graphbuff: %d", BitLen); - if (BitLen < 255) return PM3_ESOFT; + if (BitLen < 255) { + free(bits); + return PM3_ESOFT; + } if (maxLen < BitLen && maxLen != 0) BitLen = maxLen; @@ -572,11 +578,13 @@ int ASKDemod_ext(const char *Cmd, bool verbose, bool emSearch, uint8_t askType, if (errCnt < 0 || BitLen < 16) { //if fatal error (or -1) PrintAndLogEx(DEBUG, "DEBUG: (ASKDemod_ext) No data found errors:%d, invert:%c, bitlen:%d, clock:%d", errCnt, (invert) ? 'Y' : 'N', BitLen, clk); + free(bits); return PM3_ESOFT; } if (errCnt > maxErr) { PrintAndLogEx(DEBUG, "DEBUG: (ASKDemod_ext) Too many errors found, errors:%d, bits:%d, clock:%d", errCnt, BitLen, clk); + free(bits); return PM3_ESOFT; } @@ -601,6 +609,7 @@ int ASKDemod_ext(const char *Cmd, bool verbose, bool emSearch, uint8_t askType, if (emSearch) AskEm410xDecode(true, &hi, &lo); + free(bits); return PM3_SUCCESS; } int ASKDemod(const char *Cmd, bool verbose, bool emSearch, uint8_t askType) { From f42f7c22505cb94ceb45e7ce2ba15346c35dfd7d Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 23 Sep 2019 18:59:45 +0200 Subject: [PATCH 0764/1854] 'hf search' new line for --- client/cmdhflegic.c | 1 + client/cmdhfthinfilm.c | 1 + client/cmdhftopaz.c | 1 + 3 files changed, 3 insertions(+) diff --git a/client/cmdhflegic.c b/client/cmdhflegic.c index fe1f53785..31628ffff 100644 --- a/client/cmdhflegic.c +++ b/client/cmdhflegic.c @@ -1340,6 +1340,7 @@ int readLegicUid(bool verbose) { default: break; } + PrintAndLogEx(NORMAL, ""); PrintAndLogEx(SUCCESS, " UID : %s", sprint_hex(card.uid, sizeof(card.uid))); legic_print_type(card.cardsize, 0); return PM3_SUCCESS; diff --git a/client/cmdhfthinfilm.c b/client/cmdhfthinfilm.c index 3b31d460a..2938d1443 100644 --- a/client/cmdhfthinfilm.c +++ b/client/cmdhfthinfilm.c @@ -49,6 +49,7 @@ static int usage_thinfilm_sim(void) { // https://github.com/nfc-tools/libnfc/blob/master/utils/nfc-barcode.c static int print_barcode(uint8_t *barcode, const size_t barcode_len, bool verbose) { + PrintAndLogEx(NORMAL, ""); // remove start bit uint8_t mb = barcode[0] & ~0x80; PrintAndLogEx(SUCCESS, " Manufacturer : "_YELLOW_("%s") "[0x%02X]", getTagInfo(mb), mb); diff --git a/client/cmdhftopaz.c b/client/cmdhftopaz.c index 35b31d8ce..7d1e75037 100644 --- a/client/cmdhftopaz.c +++ b/client/cmdhftopaz.c @@ -433,6 +433,7 @@ static int CmdHFTopazReader(const char *Cmd) { return PM3_ESOFT; } + PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "ATQA : %02x %02x", atqa[1], atqa[0]); topaz_tag.HR01[0] = rid_response[0]; From 7870dd6fc00e20c9d11ee070fda52414a5709693 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 23 Sep 2019 19:10:29 +0200 Subject: [PATCH 0765/1854] less arrays on stack. To counter OS which has ulimit ... --- client/cmddata.c | 64 +++++++++++++++++++++++++++++++++++------------- 1 file changed, 47 insertions(+), 17 deletions(-) diff --git a/client/cmddata.c b/client/cmddata.c index a6a2a5cf7..2e28eeb03 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -810,7 +810,7 @@ int AutoCorrelate(const int *in, int *out, size_t len, size_t window, bool SaveG // Computed variance double variance = compute_variance(in, len); - static int CorrelBuffer[MAX_GRAPH_TRACE_LEN]; + int *correl_buf = calloc(MAX_GRAPH_TRACE_LEN, sizeof(int)); for (size_t i = 0; i < len - window; ++i) { @@ -819,7 +819,7 @@ int AutoCorrelate(const int *in, int *out, size_t len, size_t window, bool SaveG } autocv = (1.0 / (len - i)) * autocv; - CorrelBuffer[i] = autocv; + correl_buf[i] = autocv; // Computed autocorrelation value to be returned // Autocorrelation is autocovariance divided by variance @@ -836,15 +836,15 @@ int AutoCorrelate(const int *in, int *out, size_t len, size_t window, bool SaveG int hi = 0, idx = 0; int distance = 0, hi_1 = 0, idx_1 = 0; for (size_t i = 0; i <= len; ++i) { - if (CorrelBuffer[i] > hi) { - hi = CorrelBuffer[i]; + if (correl_buf[i] > hi) { + hi = correl_buf[i]; idx = i; } } for (size_t i = idx + 1; i <= window; ++i) { - if (CorrelBuffer[i] > hi_1) { - hi_1 = CorrelBuffer[i]; + if (correl_buf[i] > hi_1) { + hi_1 = correl_buf[i]; idx_1 = i; } } @@ -864,7 +864,7 @@ int AutoCorrelate(const int *in, int *out, size_t len, size_t window, bool SaveG int retval = correlation; if (SaveGrph) { //GraphTraceLen = GraphTraceLen - window; - memcpy(out, CorrelBuffer, len * sizeof(int)); + memcpy(out, correl_buf, len * sizeof(int)); if (distance > 0) { setClockGrid(distance, idx); retval = distance; @@ -876,7 +876,7 @@ int AutoCorrelate(const int *in, int *out, size_t len, size_t window, bool SaveG DemodBufferLen = 0; RepaintGraphWindow(); } - + free(correl_buf); return retval; } @@ -1115,10 +1115,17 @@ int FSKrawDemod(const char *Cmd, bool verbose) { if (getSignalProperties()->isnoise) return PM3_ESOFT; - uint8_t bits[MAX_GRAPH_TRACE_LEN] = {0}; + uint8_t *bits = calloc(MAX_GRAPH_TRACE_LEN, sizeof(uint8_t)); + if (bits == NULL) { + return PM3_EMALLOC; + } + size_t BitLen = getFromGraphBuf(bits); - if (BitLen == 0) return PM3_ESOFT; - + if (BitLen == 0) { + free(bits); + return PM3_ESOFT; + } + //get field clock lengths if (!fchigh || !fclow) { uint16_t fcs = countFC(bits, BitLen, true); @@ -1148,10 +1155,13 @@ int FSKrawDemod(const char *Cmd, bool verbose) { PrintAndLogEx(NORMAL, "%s decoded bitstream:", GetFSKType(fchigh, fclow, invert)); printDemodBuff(); } - return PM3_SUCCESS; + goto out; } else { PrintAndLogEx(DEBUG, "no FSK data found"); } + +out: + free(bits); return PM3_SUCCESS; } @@ -1185,19 +1195,26 @@ int PSKDemod(const char *Cmd, bool verbose) { if (getSignalProperties()->isnoise) return PM3_ESOFT; - uint8_t bits[MAX_GRAPH_TRACE_LEN] = {0}; + uint8_t *bits = calloc(MAX_GRAPH_TRACE_LEN, sizeof(uint8_t)); + if (bits == NULL) { + return PM3_EMALLOC; + } size_t bitlen = getFromGraphBuf(bits); - if (bitlen == 0) + if (bitlen == 0) { + free(bits); return PM3_ESOFT; - + } + int startIdx = 0; int errCnt = pskRawDemod_ext(bits, &bitlen, &clk, &invert, &startIdx); if (errCnt > maxErr) { if (g_debugMode || verbose) PrintAndLogEx(DEBUG, "DEBUG: (PSKdemod) Too many errors found, clk: %d, invert: %d, numbits: %d, errCnt: %d", clk, invert, bitlen, errCnt); + free(bits); return PM3_ESOFT; } if (errCnt < 0 || bitlen < 16) { //throw away static - allow 1 and -1 (in case of threshold command first) if (g_debugMode || verbose) PrintAndLogEx(DEBUG, "DEBUG: (PSKdemod) no data found, clk: %d, invert: %d, numbits: %d, errCnt: %d", clk, invert, bitlen, errCnt); + free(bits); return PM3_ESOFT; } if (verbose || g_debugMode) { @@ -1209,6 +1226,7 @@ int PSKDemod(const char *Cmd, bool verbose) { //prime demod buffer for output setDemodBuff(bits, bitlen, 0); setClockGrid(clk, startIdx); + free(bits); return PM3_SUCCESS; } @@ -1300,20 +1318,30 @@ int NRZrawDemod(const char *Cmd, bool verbose) { if (getSignalProperties()->isnoise) return PM3_ESOFT; - uint8_t bits[MAX_GRAPH_TRACE_LEN] = {0}; + uint8_t *bits = calloc(MAX_GRAPH_TRACE_LEN, sizeof(uint8_t)); + if (bits == NULL) { + return PM3_EMALLOC; + } + size_t BitLen = getFromGraphBuf(bits); - if (BitLen == 0) return PM3_ESOFT; + if (BitLen == 0) { + free(bits); + return PM3_ESOFT; + } errCnt = nrzRawDemod(bits, &BitLen, &clk, &invert, &clkStartIdx); if (errCnt > maxErr) { PrintAndLogEx(DEBUG, "DEBUG: (NRZrawDemod) Too many errors found, clk: %d, invert: %d, numbits: %d, errCnt: %d", clk, invert, BitLen, errCnt); + free(bits); return PM3_ESOFT; } if (errCnt < 0 || BitLen < 16) { //throw away static - allow 1 and -1 (in case of threshold command first) PrintAndLogEx(DEBUG, "DEBUG: (NRZrawDemod) no data found, clk: %d, invert: %d, numbits: %d, errCnt: %d", clk, invert, BitLen, errCnt); + free(bits); return PM3_ESOFT; } + if (verbose || g_debugMode) PrintAndLogEx(DEBUG, "DEBUG: (NRZrawDemod) Tried NRZ Demod using Clock: %d - invert: %d - Bits Found: %d", clk, invert, BitLen); //prime demod buffer for output setDemodBuff(bits, BitLen, 0); @@ -1326,6 +1354,8 @@ int NRZrawDemod(const char *Cmd, bool verbose) { // Now output the bitstream to the scrollback by line of 16 bits printDemodBuff(); } + + free(bits); return PM3_SUCCESS; } From e95186e5c796f16fa67530694fd166b32f4bf3a4 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 24 Sep 2019 11:45:38 +0200 Subject: [PATCH 0766/1854] WSL: detect auth problems to run wmic --- .../Windows-Installation-Instructions.md | 2 ++ pm3 | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/doc/md/Installation_Instructions/Windows-Installation-Instructions.md b/doc/md/Installation_Instructions/Windows-Installation-Instructions.md index 9cd150a22..2f5618c40 100644 --- a/doc/md/Installation_Instructions/Windows-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Windows-Installation-Instructions.md @@ -68,6 +68,8 @@ Install WSL with e.g. the standard Ubuntu. For WSL configuration, see [Manage and configure Windows Subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl/wsl-config). +Make sure your WSL can launch Windows processes to get the `pm3` scripts working (cf `interop` in the WSL settings). + ## X Server Installation If you want to run the graphical components of the Proxmark3 client, you need to install a X Server such as [VcXsrv](https://sourceforge.net/projects/vcxsrv/) or [Xming](https://sourceforge.net/projects/xming/) and launch it, e.g. by executing XLaunch. diff --git a/pm3 b/pm3 index a740beb12..347e8bb3e 100755 --- a/pm3 +++ b/pm3 @@ -54,6 +54,13 @@ function wait4proxmark_Windows { } function wait4proxmark_WSL { + # Test presence of wmic + wmic.exe computersystem get name >/dev/null 2>&1 + if [ $? -ne 0 ]; then + echo "[!] Cannot run wmic.exe, are you sure your WSL is authorized to run Windows processes? (cf WSL interop flag)" + exit 1 + fi + echo >&2 "[=] Waiting for Proxmark3 to appear..." while true; do device=$(wmic.exe path Win32_SerialPort where "PNPDeviceID like '%VID_9AC4&PID_4B8F%'" get DeviceID,PNPDeviceID 2>/dev/null | awk 'NR==2') From 87a6316f44e13f954752c6925a3e18ba21267917 Mon Sep 17 00:00:00 2001 From: mwalker33 Date: Tue, 24 Sep 2019 19:59:54 +1000 Subject: [PATCH 0767/1854] Update cmdlfem4x.c Dump print and save to .eml and .bin --- client/cmdlfem4x.c | 43 ++++++++++++++++++++----------------------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c index 36c2089d8..e4a9d4983 100644 --- a/client/cmdlfem4x.c +++ b/client/cmdlfem4x.c @@ -20,6 +20,7 @@ #include "cmdparser.h" // command_t #include "comms.h" #include "commonutil.h" +#include "common.h" #include "util_posix.h" #include "protocols.h" #include "ui.h" @@ -155,13 +156,15 @@ static int usage_lf_em4x50_write(void) { static int usage_lf_em4x05_dump(void) { PrintAndLogEx(NORMAL, "Dump EM4x05/EM4x69. Tag must be on antenna. "); PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Usage: lf em 4x05_dump [h] "); + PrintAndLogEx(NORMAL, "Usage: lf em 4x05_dump [h] [s ] "); PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " h - this help"); - PrintAndLogEx(NORMAL, " pwd - password (hex) (optional)"); + PrintAndLogEx(NORMAL, " h - this help"); + PrintAndLogEx(NORMAL, " s - overide filename prefix (optional). Default is based on card serial number"); + PrintAndLogEx(NORMAL, " pwd - password (hex) (optional)"); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf em 4x05_dump"); PrintAndLogEx(NORMAL, " lf em 4x05_dump 11223344"); + PrintAndLogEx(NORMAL, " lf em 4x50_dump s card1 11223344"); return PM3_SUCCESS; } static int usage_lf_em4x05_read(void) { @@ -1200,42 +1203,30 @@ static int EM4x05ReadWord_ext(uint8_t addr, uint32_t pwd, bool usePwd, uint32_t return demodEM4x05resp(word); } -#define swapedEndian(num) ((num>>24)&0xff) | ((num<<8)&0xff0000) | ((num>>8)&0xff00) | ((num<<24)&0xff000000) - static int CmdEM4x05Dump(const char *Cmd) { uint8_t addr = 0; uint32_t pwd = 0; bool usePwd = false; -//uint8_t ctmp = tolower(param_getchar(Cmd, 0)); uint8_t cmdp = 0; uint8_t bytes[4] = {0}; uint32_t data[16]; char preferredName[FILE_PATH_SIZE] = {0}; - bool save = false; while (param_getchar(Cmd, cmdp) != 0x00) { switch (tolower(param_getchar(Cmd, cmdp))) { case 'h': return usage_lf_em4x05_dump(); break; case 's': param_getstr(Cmd, cmdp + 1, preferredName, FILE_PATH_SIZE); - save = true; cmdp+=2; break; default : // for backwards-compatibility options should be > 'f' else assume its the hex password` + // for now use default input of 1 as invalid (unlikely 1 will be a valid password...) pwd = param_get32ex(Cmd, cmdp, 1, 16); - usePwd = true; + if (pwd != 1) + usePwd = true; cmdp++; }; } -// if (ctmp == 'h') return usage_lf_em4x05_dump(); -// if (ctmp == 's') { // save dump -// -// } - // for now use default input of 1 as invalid (unlikely 1 will be a valid password...) -// pwd = param_get32ex(Cmd, 0, 1, 16); - - // if (pwd != 1) - // usePwd = true; int success = PM3_SUCCESS; int status; @@ -1246,7 +1237,7 @@ static int CmdEM4x05Dump(const char *Cmd) { if (addr == 2) { if (usePwd) { - data[addr] = swapedEndian(pwd); + data[addr] = BSWAP_32(pwd); num_to_bytes(pwd, 4, bytes); PrintAndLogEx(NORMAL, " %02u | %08X | %s | password", addr, pwd, sprint_ascii(bytes, 4)); } else { @@ -1256,8 +1247,9 @@ static int CmdEM4x05Dump(const char *Cmd) { } else { // success &= EM4x05ReadWord_ext(addr, pwd, usePwd, &word); status = EM4x05ReadWord_ext(addr, pwd, usePwd, &word); // Get status for single read - success &= status; // Update status to match previous return - data[addr] = swapedEndian(word); + if (status != PM3_SUCCESS) + success = PM3_ESOFT; // If any error ensure fail is set so not to save invalid data + data[addr] = BSWAP_32(word); if (status == PM3_SUCCESS) { num_to_bytes(word, 4, bytes); PrintAndLogEx(NORMAL, " %02d | %08X | %s | %s", addr, word, sprint_ascii(bytes, 4), (addr > 13) ? "Lock" : ""); @@ -1266,8 +1258,13 @@ static int CmdEM4x05Dump(const char *Cmd) { PrintAndLogEx(NORMAL, " %02d | | | " _RED_("Fail"), addr); } } - - if ((success == PM3_SUCCESS) && (save)) {// all ok save dump to file + + if (success == PM3_SUCCESS) { // all ok save dump to file + // saveFileEML will add .eml extension to filename + // saveFile (binary) passes in the .bin extension. + if (strcmp (preferredName,"") == 0) // Set default filename, if not set by user + sprintf (preferredName,"lf-4x05-%08X-data",BSWAP_32(data[1])); + saveFileEML(preferredName, (uint8_t *)data, 16*sizeof(uint32_t), sizeof(uint32_t)); saveFile (preferredName, ".bin", data, sizeof(data)); } From 072b9599b95e6a38a803a1f1ca52838b1b5c5d1a Mon Sep 17 00:00:00 2001 From: mwalker33 Date: Tue, 24 Sep 2019 20:04:21 +1000 Subject: [PATCH 0768/1854] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 783b596c5..32a317320 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -355,6 +355,8 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Added T55x7 downlink mode support r 0 Default, 1 Long Leading 0, 2 Leading 0, 3 1 of 4 and 4 (in some commands) try all. (@mwalker33) - Added T55x7 downlink mode auto usage via mode detected (lf t55 detect) (@mwalker33) - Fix T55xx config getting displayed when using password when no password needed on read. (@mwalker33) + - Fix `em 4x05_dump` to print all blocks read (@mwalker33) + - Added save to .eml and .bin for `em 4x05_dump` (@mwalker33) ### Fixed - Changed driver file proxmark3.inf to support both old and new Product/Vendor IDs (@pwpiwi) From b2c24c8010323516309582f2952bbdb7266471b4 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 24 Sep 2019 13:06:43 +0200 Subject: [PATCH 0769/1854] add - continuously measure LF antenna --- armsrc/appmain.c | 38 +++++++++++++++++++++++++++++++- client/cmdlf.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++ include/pm3_cmd.h | 1 + 3 files changed, 94 insertions(+), 1 deletion(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 56cfec1de..bbc4eecf9 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -206,8 +206,9 @@ void MeasureAntennaTuning(void) { LEDsoff(); } +// Measure HF in miliVolt uint16_t MeasureAntennaTuningHfData(void) { - uint16_t volt = 0; // in mV + uint16_t volt = 0; uint16_t avg = AvgAdc(ADC_CHAN_HF); volt = (MAX_ADC_HF_VOLTAGE * avg) >> 10; bool use_high = (volt > MAX_ADC_HF_VOLTAGE - 300); @@ -219,6 +220,11 @@ uint16_t MeasureAntennaTuningHfData(void) { return volt; } +// Measure LF in miliVolt +uint32_t MeasureAntennaTuningLfData(void) { + return (MAX_ADC_LF_VOLTAGE * AvgAdc(ADC_CHAN_LF)) >> 10; +} + void ReadMem(int addr) { const uint8_t *data = ((uint8_t *)addr); @@ -1415,6 +1421,7 @@ static void PacketReceived(PacketCommandNG *packet) { case CMD_MEASURE_ANTENNA_TUNING_HF: { if (packet->length != 1) reply_ng(CMD_MEASURE_ANTENNA_TUNING_HF, PM3_EINVARG, NULL, 0); + switch (packet->data.asBytes[0]) { case 1: // MEASURE_ANTENNA_TUNING_HF_START // Let the FPGA drive the high-frequency antenna around 13.56 MHz. @@ -1438,6 +1445,35 @@ static void PacketReceived(PacketCommandNG *packet) { } break; } + case CMD_MEASURE_ANTENNA_TUNING_LF: { + if (packet->length != 1) + reply_ng(CMD_MEASURE_ANTENNA_TUNING_LF, PM3_EINVARG, NULL, 0); + + switch (packet->data.asBytes[0]) { + case 1: // MEASURE_ANTENNA_TUNING_LF_START + // Let the FPGA drive the low-frequency antenna around 125Khz + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); + reply_ng(CMD_MEASURE_ANTENNA_TUNING_LF, PM3_SUCCESS, NULL, 0); + break; + case 2: + if (button_status == BUTTON_SINGLE_CLICK) + reply_ng(CMD_MEASURE_ANTENNA_TUNING_LF, PM3_EOPABORTED, NULL, 0); + + uint32_t volt = MeasureAntennaTuningLfData(); + reply_ng(CMD_MEASURE_ANTENNA_TUNING_LF, PM3_SUCCESS, (uint8_t *)&volt, sizeof(volt)); + break; + case 3: + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + reply_ng(CMD_MEASURE_ANTENNA_TUNING_LF, PM3_SUCCESS, NULL, 0); + break; + default: + reply_ng(CMD_MEASURE_ANTENNA_TUNING_LF, PM3_EINVARG, NULL, 0); + break; + } + break; + } case CMD_LISTEN_READER_FIELD: { if (packet->length != sizeof(uint8_t)) break; diff --git a/client/cmdlf.c b/client/cmdlf.c index 366f2ed0e..002a596fe 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -190,6 +190,61 @@ static int usage_lf_find(void) { PrintAndLogEx(NORMAL, " lf search 1 u = use data from GraphBuffer & search for known and unknown tags"); return PM3_SUCCESS; } +static int usage_lf_tune(void) { + PrintAndLogEx(NORMAL, "Continuously measure LF antenna tuning."); + PrintAndLogEx(NORMAL, "Press button or Enter to interrupt."); + PrintAndLogEx(NORMAL, "Usage: lf tune [h] <0|1>"); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Options:"); + PrintAndLogEx(NORMAL, " h This help"); + PrintAndLogEx(NORMAL, " <> "); + PrintAndLogEx(NORMAL, "Examples:"); + PrintAndLogEx(NORMAL, " lf tune = "); + return PM3_SUCCESS; +} + +int CmdLFTune(const char *Cmd) { + char cmdp = tolower(param_getchar(Cmd, 0)); + if (cmdp == 'h') return usage_lf_tune(); + int iter = param_get32ex(Cmd, 0, 0, 10); + + PrintAndLogEx(SUCCESS, "Measuring LF antenna, click button or press Enter to exit"); + + uint8_t mode[] = {1}; + PacketResponseNG resp; + + clearCommandBuffer(); + SendCommandNG(CMD_MEASURE_ANTENNA_TUNING_LF, mode, sizeof(mode)); + if (!WaitForResponseTimeout(CMD_MEASURE_ANTENNA_TUNING_LF, &resp, 1000)) { + PrintAndLogEx(WARNING, "Timeout while waiting for Proxmark LF initialization, aborting"); + return PM3_ETIMEOUT; + } + mode[0] = 2; + // loop forever (till button pressed) if iter = 0 (default) + for (uint8_t i = 0; iter == 0 || i < iter; i++) { + if (kbd_enter_pressed()) { // abort by keyboard press + break; + } + SendCommandNG(CMD_MEASURE_ANTENNA_TUNING_LF, mode, sizeof(mode)); + if (!WaitForResponseTimeout(CMD_MEASURE_ANTENNA_TUNING_LF, &resp, 1000)) { + PrintAndLogEx(WARNING, "Timeout while waiting for Proxmark LF measure, aborting"); + return PM3_ETIMEOUT; + } + if ((resp.status == PM3_EOPABORTED) || (resp.length != sizeof(uint32_t))) + break; + uint32_t volt = resp.data.asDwords[0] & 0xFFFF; + PrintAndLogEx(INPLACE, "%u mV / %5u V", volt, (uint32_t)(volt / 1000)); + } + mode[0] = 3; + SendCommandNG(CMD_MEASURE_ANTENNA_TUNING_LF, mode, sizeof(mode)); + if (!WaitForResponseTimeout(CMD_MEASURE_ANTENNA_TUNING_LF, &resp, 1000)) { + PrintAndLogEx(WARNING, "Timeout while waiting for Proxmark LF shutdown, aborting"); + return PM3_ETIMEOUT; + } + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(SUCCESS, "Done."); + return PM3_SUCCESS; +} /* send a LF command before reading */ @@ -1166,6 +1221,7 @@ static command_t CommandTable[] = { {"simpsk", CmdLFpskSim, IfPm3Lf, "[1|2|3] [c ] [i] [r ] [d ] \n\t\t-- Simulate LF PSK tag from demodbuffer or input"}, {"simbidir", CmdLFSimBidir, IfPm3Lf, "Simulate LF tag (with bidirectional data transmission between reader and tag)"}, {"sniff", CmdLFSniff, IfPm3Lf, "Sniff LF traffic between reader and tag"}, + {"tune", CmdLFTune, IfPm3Lf, "Continuously measure LF antenna tuning"}, {"vchdemod", CmdVchDemod, AlwaysAvailable, "['clone'] -- Demodulate samples for VeriChip"}, {NULL, NULL, NULL, NULL} }; diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 13995a429..1628c558d 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -442,6 +442,7 @@ typedef struct { // For measurements of the antenna tuning #define CMD_MEASURE_ANTENNA_TUNING 0x0400 #define CMD_MEASURE_ANTENNA_TUNING_HF 0x0401 +#define CMD_MEASURE_ANTENNA_TUNING_LF 0x0402 #define CMD_LISTEN_READER_FIELD 0x0420 #define CMD_HF_DROPFIELD 0x0430 From 47073554319805295fd5c9d58266e3589f92e2ec Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 24 Sep 2019 13:07:35 +0200 Subject: [PATCH 0770/1854] textual --- client/cmdlfio.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/cmdlfio.c b/client/cmdlfio.c index 203b1c06d..e17ae82d1 100644 --- a/client/cmdlfio.c +++ b/client/cmdlfio.c @@ -4,7 +4,7 @@ // at your option, any later version. See the LICENSE.txt file for the text of // the license. //----------------------------------------------------------------------------- -// Low frequency ioProx commands +// Low frequency Kantech ioProx commands // FSK2a, rf/64, 64 bits (complete) //----------------------------------------------------------------------------- @@ -319,7 +319,7 @@ static command_t CommandTable[] = { {"read", CmdIOProxRead, IfPm3Lf, "attempt to read and extract tag data"}, {"clone", CmdIOProxClone, IfPm3Lf, "clone IOProx to T55x7"}, {"sim", CmdIOProxSim, IfPm3Lf, "simulate IOProx tag"}, - {"watch", CmdIOProxWatch, IfPm3Lf, "continuously watch for cards. Reader mode"}, + {"watch", CmdIOProxWatch, IfPm3Lf, "continuously watch for cards. Reader mode"}, {NULL, NULL, NULL, NULL} }; @@ -343,7 +343,7 @@ int demodIOProx(void) { //| | | | | | | //01234567 8 90123456 7 89012345 6 78901234 5 67890123 4 56789012 3 45678901 23 //----------------------------------------------------------------------------- -//00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 ???????? 11 +//00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 crc 11 //XSF(version)facility:codeone+codetwo (raw) int getIOProxBits(uint8_t version, uint8_t fc, uint16_t cn, uint8_t *bits) { #define SEPARATOR 1 From 45318e43464bbea111bfeabe698bfa5d40220de9 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 24 Sep 2019 13:08:49 +0200 Subject: [PATCH 0771/1854] conside less than 26, to be 26bit wiegand --- client/wiegand_formatutils.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/wiegand_formatutils.c b/client/wiegand_formatutils.c index a4529955d..3e1ee0028 100644 --- a/client/wiegand_formatutils.c +++ b/client/wiegand_formatutils.c @@ -149,6 +149,8 @@ uint8_t get_length_from_header(wiegand_message_t *data) { hfmt >>= 1; len++; } + if (len < 26 ) + len = 26; return len; } From b54c7b4dd1dcf6b715720bc81e78caf6c8f92b57 Mon Sep 17 00:00:00 2001 From: Iceman Date: Tue, 24 Sep 2019 13:14:47 +0200 Subject: [PATCH 0772/1854] Update Linux-Installation-Instructions.md --- .../Linux-Installation-Instructions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/md/Installation_Instructions/Linux-Installation-Instructions.md b/doc/md/Installation_Instructions/Linux-Installation-Instructions.md index 70d102aa3..f82d0f677 100644 --- a/doc/md/Installation_Instructions/Linux-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Linux-Installation-Instructions.md @@ -9,7 +9,7 @@ You might want to follow one of these external resources to get an overview, but ![Linux Installation Video Screenshot](https://github.com/5w0rdfish/Proxmark3-RDV4-ParrotOS/blob/master/screenshot-www.youtube.com-2019.03.17-20-44-33.png) * ParrotOS: some further notes can be found at @5w0rdfish repo [Proxmark Installation for Parrot OS](https://github.com/5w0rdfish/Proxmark3-RDV4-ParrotOS) -* Iceman has also added this script to the fork. https://github.com/RfidResearchGroup/proxmark3/blob/master/install.sh + # Install the required dependencies From bf395a6c4fc83b20b4e729d43062e9a77669a895 Mon Sep 17 00:00:00 2001 From: mwalker33 Date: Tue, 24 Sep 2019 21:42:31 +1000 Subject: [PATCH 0773/1854] Update cmdlfem4x.c Add lck flags and f for filename --- client/cmdlfem4x.c | 61 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 47 insertions(+), 14 deletions(-) diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c index e4a9d4983..fd1250440 100644 --- a/client/cmdlfem4x.c +++ b/client/cmdlfem4x.c @@ -156,15 +156,15 @@ static int usage_lf_em4x50_write(void) { static int usage_lf_em4x05_dump(void) { PrintAndLogEx(NORMAL, "Dump EM4x05/EM4x69. Tag must be on antenna. "); PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Usage: lf em 4x05_dump [h] [s ] "); + PrintAndLogEx(NORMAL, "Usage: lf em 4x05_dump [h] [f ] "); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h - this help"); - PrintAndLogEx(NORMAL, " s - overide filename prefix (optional). Default is based on card serial number"); + PrintAndLogEx(NORMAL, " f - overide filename prefix (optional). Default is based on UID"); PrintAndLogEx(NORMAL, " pwd - password (hex) (optional)"); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf em 4x05_dump"); PrintAndLogEx(NORMAL, " lf em 4x05_dump 11223344"); - PrintAndLogEx(NORMAL, " lf em 4x50_dump s card1 11223344"); + PrintAndLogEx(NORMAL, " lf em 4x50_dump f card1 11223344"); return PM3_SUCCESS; } static int usage_lf_em4x05_read(void) { @@ -1211,14 +1211,20 @@ static int CmdEM4x05Dump(const char *Cmd) { uint8_t bytes[4] = {0}; uint32_t data[16]; char preferredName[FILE_PATH_SIZE] = {0}; - + char optchk[10]; + while (param_getchar(Cmd, cmdp) != 0x00) { switch (tolower(param_getchar(Cmd, cmdp))) { case 'h': return usage_lf_em4x05_dump(); break; - case 's': param_getstr(Cmd, cmdp + 1, preferredName, FILE_PATH_SIZE); - cmdp+=2; - break; + case 'f': // since f could match in password, lets confirm it is 1 character only for an option + param_getstr(Cmd, cmdp,optchk,sizeof(optchk)); + if (strlen (optchk) == 1) {// Have a single character f so filename no password + param_getstr(Cmd, cmdp + 1, preferredName, FILE_PATH_SIZE); + cmdp+=2; + break; + } // if not a single 'f' dont break and flow onto default as should be password + default : // for backwards-compatibility options should be > 'f' else assume its the hex password` // for now use default input of 1 as invalid (unlikely 1 will be a valid password...) pwd = param_get32ex(Cmd, cmdp, 1, 16); @@ -1230,19 +1236,39 @@ static int CmdEM4x05Dump(const char *Cmd) { int success = PM3_SUCCESS; int status; + uint32_t lock_bits = 0x00; // no blocks locked + uint32_t word = 0; - PrintAndLogEx(NORMAL, "Addr | data | ascii | info"); - PrintAndLogEx(NORMAL, "-----+----------+-------+------"); - for (; addr < 16; addr++) { + PrintAndLogEx(NORMAL, "Addr | data | ascii |lck| info"); + PrintAndLogEx(NORMAL, "-----+----------+-------+---+-----"); + + // To flag any blocks locked we need to read blocks 14 and 15 first + // dont swap endin until we get block lock flags. + status = EM4x05ReadWord_ext(14, pwd, usePwd, &word); + if (status != PM3_SUCCESS) + success = PM3_ESOFT; // If any error ensure fail is set so not to save invalid data + if (word != 0x00) + lock_bits = word; + data[14] = word; + + status = EM4x05ReadWord_ext(15, pwd, usePwd, &word); + if (status != PM3_SUCCESS) + success = PM3_ESOFT; // If any error ensure fail is set so not to save invalid data + if (word != 0x00) // assume block 15 is the current lock block + lock_bits = word; + data[15] = word; + + // Now read blocks 0 - 13 as we have 14 and 15 + for (; addr < 14; addr++) { if (addr == 2) { if (usePwd) { data[addr] = BSWAP_32(pwd); num_to_bytes(pwd, 4, bytes); - PrintAndLogEx(NORMAL, " %02u | %08X | %s | password", addr, pwd, sprint_ascii(bytes, 4)); + PrintAndLogEx(NORMAL, " %02u | %08X | %s | %c | password", addr, pwd, sprint_ascii(bytes, 4),((lock_bits >> addr) & 1) ? 'x' : ' '); } else { data[addr] = 0x00; // Unknown password, but not used to set to zeros - PrintAndLogEx(NORMAL, " 02 | | | " _RED_("cannot read")); + PrintAndLogEx(NORMAL, " 02 | | | | " _RED_("cannot read")); } } else { // success &= EM4x05ReadWord_ext(addr, pwd, usePwd, &word); @@ -1252,12 +1278,19 @@ static int CmdEM4x05Dump(const char *Cmd) { data[addr] = BSWAP_32(word); if (status == PM3_SUCCESS) { num_to_bytes(word, 4, bytes); - PrintAndLogEx(NORMAL, " %02d | %08X | %s | %s", addr, word, sprint_ascii(bytes, 4), (addr > 13) ? "Lock" : ""); + PrintAndLogEx(NORMAL, " %02d | %08X | %s | %c |", addr, word, sprint_ascii(bytes, 4),((lock_bits >> addr) & 1) ? 'x' : ' '); } else - PrintAndLogEx(NORMAL, " %02d | | | " _RED_("Fail"), addr); + PrintAndLogEx(NORMAL, " %02d | | | | " _RED_("Fail"), addr); } } + // Print blocks 14 and 15 + // Both lock bits are protected with bit idx 14 (special case) + PrintAndLogEx(NORMAL, " %02d | %08X | %s | %c | Lock", 14, data[14], sprint_ascii(bytes, 4),((lock_bits >> 14) & 1) ? 'x' : ' '); + PrintAndLogEx(NORMAL, " %02d | %08X | %s | %c | Lock", 15, data[15], sprint_ascii(bytes, 4),((lock_bits >> 14) & 1) ? 'x' : ' '); + // Update endian for files + data[14] = BSWAP_32(data[14]); + data[15] = BSWAP_32(data[15]); if (success == PM3_SUCCESS) { // all ok save dump to file // saveFileEML will add .eml extension to filename From 891a07998977aac2e5b22de424690a74b5eccf16 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 24 Sep 2019 14:59:05 +0200 Subject: [PATCH 0774/1854] textual --- armsrc/appmain.c | 6 +++--- client/cmdhf.c | 5 +++-- client/cmdlf.c | 12 +++++------- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index bbc4eecf9..7c483f2e1 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -206,7 +206,7 @@ void MeasureAntennaTuning(void) { LEDsoff(); } -// Measure HF in miliVolt +// Measure HF in milliVolt uint16_t MeasureAntennaTuningHfData(void) { uint16_t volt = 0; uint16_t avg = AvgAdc(ADC_CHAN_HF); @@ -220,7 +220,7 @@ uint16_t MeasureAntennaTuningHfData(void) { return volt; } -// Measure LF in miliVolt +// Measure LF in milliVolt uint32_t MeasureAntennaTuningLfData(void) { return (MAX_ADC_LF_VOLTAGE * AvgAdc(ADC_CHAN_LF)) >> 10; } @@ -1451,7 +1451,7 @@ static void PacketReceived(PacketCommandNG *packet) { switch (packet->data.asBytes[0]) { case 1: // MEASURE_ANTENNA_TUNING_LF_START - // Let the FPGA drive the low-frequency antenna around 125Khz + // Let the FPGA drive the low-frequency antenna around 125kHz FpgaDownloadAndGo(FPGA_BITSTREAM_LF); FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); diff --git a/client/cmdhf.c b/client/cmdhf.c index 8326d988f..c76f62d81 100644 --- a/client/cmdhf.c +++ b/client/cmdhf.c @@ -60,11 +60,12 @@ static int usage_hf_sniff() { } static int usage_hf_tune() { - PrintAndLogEx(NORMAL, "Usage: hf tune []"); PrintAndLogEx(NORMAL, "Continuously measure HF antenna tuning."); PrintAndLogEx(NORMAL, "Press button or Enter to interrupt."); + PrintAndLogEx(NORMAL, "Usage: hf tune [h] []"); PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " - number of iterations (default: infinite)"); + PrintAndLogEx(NORMAL, " h - This help"); + PrintAndLogEx(NORMAL, " - number of iterations (default: 0=infinite)"); PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } diff --git a/client/cmdlf.c b/client/cmdlf.c index 002a596fe..c39bcd30d 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -191,15 +191,13 @@ static int usage_lf_find(void) { return PM3_SUCCESS; } static int usage_lf_tune(void) { - PrintAndLogEx(NORMAL, "Continuously measure LF antenna tuning."); + PrintAndLogEx(NORMAL, "Continuously measure LF antenna tuning at 125 kHz."); PrintAndLogEx(NORMAL, "Press button or Enter to interrupt."); - PrintAndLogEx(NORMAL, "Usage: lf tune [h] <0|1>"); + PrintAndLogEx(NORMAL, "Usage: lf tune [h] []"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " h This help"); - PrintAndLogEx(NORMAL, " <> "); - PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " lf tune = "); + PrintAndLogEx(NORMAL, " h - This help"); + PrintAndLogEx(NORMAL, " - number of iterations (default: 0=infinite)"); return PM3_SUCCESS; } @@ -208,7 +206,7 @@ int CmdLFTune(const char *Cmd) { if (cmdp == 'h') return usage_lf_tune(); int iter = param_get32ex(Cmd, 0, 0, 10); - PrintAndLogEx(SUCCESS, "Measuring LF antenna, click button or press Enter to exit"); + PrintAndLogEx(SUCCESS, "Measuring LF antenna at 125kHz, click button or press Enter to exit"); uint8_t mode[] = {1}; PacketResponseNG resp; From 7352c19a72d49de0f40706e4a221d59021de9a38 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 24 Sep 2019 15:16:09 +0200 Subject: [PATCH 0775/1854] fix make help --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index ebb4dacb8..318251892 100644 --- a/Makefile +++ b/Makefile @@ -112,7 +112,7 @@ help: @echo "+ all - Make all targets: bootrom, fullimage and OS-specific host tools" @echo "+ clean - Clean in all targets" @echo "+ .../clean - Clean in specified target and its deps, e.g. bootrom/clean" - @echo "+ (un)install - Install/uninstall Proxmark files in the system, default to /usr/local/share, + @echo "+ (un)install - Install/uninstall Proxmark files in the system, default to /usr/local/share," @echo " else provide a PREFIX. See Maintainers.md for more options" @echo @echo "+ bootrom - Make bootrom" From 6ffae0e156dd83d0572635c21bb8d48521c5070f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 24 Sep 2019 15:27:20 +0200 Subject: [PATCH 0776/1854] fix - parites needs to be reset between iterations, and resuse standard functions for clock --- client/cmdlfem4x.c | 99 +++++++++++++++++++++++++--------------------- 1 file changed, 55 insertions(+), 44 deletions(-) diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c index fd1250440..92df808d1 100644 --- a/client/cmdlfem4x.c +++ b/client/cmdlfem4x.c @@ -690,39 +690,43 @@ static int CmdEM410xWrite(const char *Cmd) { } //**************** Start of EM4x50 Code ************************ -static bool EM_EndParityTest(uint8_t *bs, size_t size, uint8_t rows, uint8_t cols, uint8_t pType) { + +// even parity COLUMN +static bool EM_ColParityTest(uint8_t *bs, size_t size, uint8_t rows, uint8_t cols, uint8_t pType) { if (rows * cols > size) return false; uint8_t colP = 0; - //assume last col is a parity and do not test - for (uint8_t colNum = 0; colNum < cols - 1; colNum++) { - for (uint8_t rowNum = 0; rowNum < rows; rowNum++) { - colP ^= bs[(rowNum * cols) + colNum]; + + for (uint8_t c = 0; c < cols - 1; c++) { + for (uint8_t r = 0; r < rows; r++) { + colP ^= bs[(r * cols) + c]; } if (colP != pType) return false; + colP = 0; } return true; } -static bool EM_ByteParityTest(uint8_t *bs, size_t size, uint8_t rows, uint8_t cols, uint8_t pType) { +// even parity ROW +static bool EM_RowParityTest(uint8_t *bs, size_t size, uint8_t rows, uint8_t cols, uint8_t pType) { if (rows * cols > size) return false; - uint8_t rowP = 0; - //assume last row is a parity row and do not test - for (uint8_t rowNum = 0; rowNum < rows - 1; rowNum++) { - for (uint8_t colNum = 0; colNum < cols; colNum++) { - rowP ^= bs[(rowNum * cols) + colNum]; + + for (uint8_t r = 0; r < rows - 1; r++) { + for (uint8_t c = 0; c < cols; c++) { + rowP ^= bs[(r * cols) + c]; } if (rowP != pType) return false; + rowP = 0; } return true; } // EM word parity test. // 9*5 = 45 bits in total +// 012345678|r0 // 012345678|r1 // 012345678|r2 // 012345678|r3 -// 012345678|r4 // ------------ //c012345678| 0 // |- must be zero @@ -795,7 +799,7 @@ static uint32_t OutputEM4x50_Block(uint8_t *BitStream, size_t size, bool verbose * XXXXXXXX [row parity bit (even)] <- 8 bits plus parity * XXXXXXXX [row parity bit (even)] <- 8 bits plus parity * XXXXXXXX [row parity bit (even)] <- 8 bits plus parity - * CCCCCCCC <- column parity bits + * CCCCCCC0 <- column parity bits * 0 <- stop bit * LW <- Listen Window * @@ -809,9 +813,8 @@ static uint32_t OutputEM4x50_Block(uint8_t *BitStream, size_t size, bool verbose */ //completed by Marshmellow int EM4x50Read(const char *Cmd, bool verbose) { - uint8_t fndClk[] = {8, 16, 32, 40, 50, 64, 128}; int clk = 0, invert = 0, tol = 0, phaseoff; - int i = 0, j = 0, startblock, skip, block, start, end, low = 0, high = 0, minClk = 255; + int i = 0, j = 0, startblock, skip, block, start, end, low = 0, high = 0; uint32_t Code[6]; char tmp[6]; char tmp2[20]; @@ -833,16 +836,28 @@ int EM4x50Read(const char *Cmd, bool verbose) { computeSignalProperties(bits, size); - signal_t *sp = getSignalProperties(); - high = sp->high; - low = sp->low; + // get fuzzed HI / LOW limits in signal + getHiLo( &high, &low, 75, 75); // get to first full low to prime loop and skip incomplete first pulse - while ((i < size) && (bits[i] < high)) - ++i; - while ((i < size) && (bits[i] > low)) - ++i; - skip = i; + size_t offset = 0; + getNextHigh(bits, size, high, &offset); + getNextLow(bits, size, low, &offset); + + i = (int)offset; + skip = offset; + + // set clock + if (clk == 0) { + DetectASKClock(bits, size, &clk, 0); + PrintAndLogEx(INFO, " ICE CLOCK %d", clk); + if (clk == 0) { + if (verbose || g_debugMode) PrintAndLogEx(ERR, "Error: EM4x50 - didn't find a clock"); + return PM3_ESOFT; + } + } + // tolerance + tol = clk / 8; // populate tmpbuff buffer with pulse lengths while (i < size) { @@ -850,32 +865,18 @@ int EM4x50Read(const char *Cmd, bool verbose) { while ((i < size) && (bits[i] > low)) ++i; start = i; + while ((i < size) && (bits[i] < high)) ++i; + while ((i < size) && (bits[i] > low)) ++i; + if (j >= (MAX_GRAPH_TRACE_LEN / 64)) { break; } tmpbuff[j++] = i - start; - if (i - start < minClk && i < size) { - minClk = i - start; - } } - // set clock - if (!clk) { - for (uint8_t clkCnt = 0; clkCnt < 7; clkCnt++) { - tol = fndClk[clkCnt] / 8; - if (minClk >= fndClk[clkCnt] - tol && minClk <= fndClk[clkCnt] + 1) { - clk = fndClk[clkCnt]; - break; - } - } - if (!clk) { - if (verbose || g_debugMode) PrintAndLogEx(ERR, "Error: EM4x50 - didn't find a clock"); - return PM3_ESOFT; - } - } else tol = clk / 8; // look for data start - should be 2 pairs of LW (pulses of clk*3,clk*2) start = -1; @@ -910,6 +911,7 @@ int EM4x50Read(const char *Cmd, bool verbose) { } } end = i; + // report back if (verbose || g_debugMode) { if (start >= 0) { @@ -920,16 +922,23 @@ int EM4x50Read(const char *Cmd, bool verbose) { PrintAndLogEx(NORMAL, " or after a " _YELLOW_("'data askedge'") " command to clean up the read"); return PM3_ESOFT; } - } else if (start < 0) return PM3_ESOFT; + } else if (start < 0) { + return PM3_ESOFT; + } start = skip; + snprintf(tmp2, sizeof(tmp2), "%d %d 1000 %d", clk, invert, clk * 47); + // save GraphBuffer - to restore it later save_restoreGB(GRAPH_SAVE); + // get rid of leading crap snprintf(tmp, sizeof(tmp), "%i", skip); CmdLtrim(tmp); + bool AllPTest = true; + // now work through remaining buffer printing out data blocks block = 0; i = startblock; @@ -957,11 +966,12 @@ int EM4x50Read(const char *Cmd, bool verbose) { save_restoreGB(GRAPH_RESTORE); return PM3_ESOFT; } + //set DemodBufferLen to just one block DemodBufferLen = skip / clk; //test parities - bool pTest = EM_ByteParityTest(DemodBuffer, DemodBufferLen, 5, 9, 0); - pTest &= EM_EndParityTest(DemodBuffer, DemodBufferLen, 5, 9, 0); + bool pTest = EM_RowParityTest(DemodBuffer, DemodBufferLen, 5, 9, 0); + pTest &= EM_ColParityTest(DemodBuffer, DemodBufferLen, 5, 9, 0); AllPTest &= pTest; //get output Code[block] = OutputEM4x50_Block(DemodBuffer, DemodBufferLen, verbose, pTest); @@ -972,6 +982,7 @@ int EM4x50Read(const char *Cmd, bool verbose) { block++; if (i >= end) break; //in case chip doesn't output 6 blocks } + //print full code: if (verbose || g_debugMode || AllPTest) { if (!complete) { @@ -1135,7 +1146,7 @@ static int setDemodBufferEM(uint32_t *word, size_t idx) { //test for even parity bits. uint8_t parity[45] = {0}; memcpy(parity, DemodBuffer, 45); - if (!EM_EndParityTest(DemodBuffer + idx + EM_PREAMBLE_LEN, 45, 5, 9, 0)) { + if (!EM_ColParityTest(DemodBuffer + idx + EM_PREAMBLE_LEN, 45, 5, 9, 0)) { PrintAndLogEx(DEBUG, "DEBUG: Error - End Parity check failed"); return PM3_ESOFT; } From 878e394cde65de21d43bea3546b7f891ab8119c6 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 24 Sep 2019 15:44:16 +0200 Subject: [PATCH 0777/1854] lf tune: remove 16b mask (thanks @iceman1001) --- client/cmdlf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdlf.c b/client/cmdlf.c index c39bcd30d..ee4302e82 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -230,7 +230,7 @@ int CmdLFTune(const char *Cmd) { } if ((resp.status == PM3_EOPABORTED) || (resp.length != sizeof(uint32_t))) break; - uint32_t volt = resp.data.asDwords[0] & 0xFFFF; + uint32_t volt = resp.data.asDwords[0]; PrintAndLogEx(INPLACE, "%u mV / %5u V", volt, (uint32_t)(volt / 1000)); } mode[0] = 3; From e793e90803c49617e9a9b1de529ee7c2745cbf74 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 24 Sep 2019 21:01:44 +0200 Subject: [PATCH 0778/1854] textual --- client/cmdhf.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/client/cmdhf.c b/client/cmdhf.c index c76f62d81..85612f428 100644 --- a/client/cmdhf.c +++ b/client/cmdhf.c @@ -138,6 +138,7 @@ int CmdHFSearch(const char *Cmd) { } +// PrintAndLogEx(INPLACE, "Searching for FeliCa tag..."); //if (IfPm3Felica()) { // ans = CmdHFFelicaReader("s"); // if (ans) { @@ -147,7 +148,8 @@ int CmdHFSearch(const char *Cmd) { //} - PrintAndLogEx(FAILED, "\nNo known/supported 13.56 MHz tags found\n"); + PrintAndLogEx(INPLACE, "No known/supported 13.56 MHz tags found"); + PrintAndLogEx(NORMAL, ""); return PM3_ESOFT; } From 3e22d99b036ce2fe94d772a14f858b304c3dd9af Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 25 Sep 2019 10:24:34 +0200 Subject: [PATCH 0779/1854] hf mf darkside uses NG. checkbutton more seldom, shoulded interfere with syncing the prng so much --- armsrc/appmain.c | 8 +++++- armsrc/iso14443a.c | 55 +++++++++++++++++++++++++---------- client/mifare/mifarehost.c | 59 ++++++++++++++++++++++++++++---------- 3 files changed, 91 insertions(+), 31 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 7c483f2e1..b778fa785 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1032,7 +1032,13 @@ static void PacketReceived(PacketCommandNG *packet) { break; } case CMD_HF_MIFARE_READER: { - ReaderMifare(packet->oldarg[0], packet->oldarg[1], packet->oldarg[2]); + struct p { + uint8_t first_run; + uint8_t blockno; + uint8_t key_type; + } PACKED; + struct p *payload = (struct p *) packet->data.asBytes; + ReaderMifare(payload->first_run, payload->blockno, payload->key_type); break; } case CMD_HF_MIFARE_READBL: { diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 348317a8a..7b0db6499 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -2791,6 +2791,8 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) { static uint8_t par_low = 0; static uint8_t mf_nr_ar3 = 0; + int return_status = PM3_SUCCESS; + AddCrc14A(mf_auth, 2); if (first_try) { @@ -2807,6 +2809,7 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) { } LED_C_ON(); + uint16_t checkbtn_cnt = 0; uint16_t i; for (i = 0; true; ++i) { @@ -2815,10 +2818,15 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) { WDT_HIT(); // Test if the action was cancelled - if (BUTTON_PRESS()) { - isOK = -1; - break; + if (checkbtn_cnt == 2000) { + if (BUTTON_PRESS() || data_available()) { + isOK = -1; + return_status = PM3_EABORTED; + break; + } + checkbtn_cnt = 0; } + checkbtn_cnt++; // this part is from Piwi's faster nonce collecting part in Hardnested. if (!have_uid) { // need a full select cycle to get the uid first @@ -2876,8 +2884,15 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) { ReaderTransmitPar(mf_nr_ar, sizeof(mf_nr_ar), par, NULL); // Receive answer. This will be a 4 Bit NACK when the 8 parity bits are OK after decoding - if (ReaderReceive(receivedAnswer, receivedAnswerPar)) + int resp_res = ReaderReceive(receivedAnswer, receivedAnswerPar); + if (resp_res == 4) received_nack = true; + else if (resp_res == 32) { + // did we get lucky and got our dummykey to be valid? + isOK = -6; + break; + } + // we didn't calibrate our clock yet, // iceman: has to be calibrated every time. @@ -3000,26 +3015,36 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) { if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("Number of sent auth requests: %u", i); - uint8_t buf[32] = {0x00}; - memset(buf, 0x00, sizeof(buf)); - num_to_bytes(cuid, 4, buf); - num_to_bytes(nt, 4, buf + 4); - memcpy(buf + 8, par_list, 8); - memcpy(buf + 16, ks_list, 8); - memcpy(buf + 24, mf_nr_ar, 8); + struct { + int32_t isOK; + uint8_t cuid[4]; + uint8_t nt[4]; + uint8_t par_list[8]; + uint8_t ks_list[8]; + uint8_t nr[4]; + uint8_t ar[4]; + } PACKED payload; - reply_mix(CMD_ACK, isOK, 0, 0, buf, sizeof(buf)); + payload.isOK = isOK; + num_to_bytes(cuid, 4, payload.cuid); + num_to_bytes(nt, 4, payload.nt); + memcpy(payload.par_list, par_list, sizeof(payload.par_list)); + memcpy(payload.ks_list, ks_list, sizeof(payload.ks_list)); + memcpy(payload.nr, mf_nr_ar, sizeof(payload.nr)); + memcpy(payload.ar, mf_nr_ar + 4, sizeof(payload.ar)); + + reply_ng(CMD_HF_MIFARE_READER, return_status, (uint8_t*)&payload, sizeof(payload)); hf_field_off(); set_tracing(false); } /* -* Mifare Classic NACK-bug detection -* Thanks to @doegox for the feedback and new approaches. + * Mifare Classic NACK-bug detection + * Thanks to @doegox for the feedback and new approaches. */ void DetectNACKbug(void) { - uint8_t mf_auth[] = {0x60, 0x00, 0xF5, 0x7B}; + uint8_t mf_auth[] = {0x60, 0x00, 0xF5, 0x7B}; uint8_t mf_nr_ar[] = {0, 0, 0, 0, 0, 0, 0, 0}; uint8_t uid[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = {0x00}; diff --git a/client/mifare/mifarehost.c b/client/mifare/mifarehost.c index e4cec00c0..ac8015d98 100644 --- a/client/mifare/mifarehost.c +++ b/client/mifare/mifarehost.c @@ -30,7 +30,7 @@ int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) { uint32_t nt = 0, nr = 0, ar = 0; uint64_t par_list = 0, ks_list = 0; uint64_t *keylist = NULL, *last_keylist = NULL; - bool arg0 = true; + bool first_run = true; // message PrintAndLogEx(NORMAL, "--------------------------------------------------------------------------------\n"); @@ -40,7 +40,15 @@ int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) { while (true) { clearCommandBuffer(); - SendCommandMIX(CMD_HF_MIFARE_READER, arg0, blockno, key_type, NULL, 0); + struct { + uint8_t first_run; + uint8_t blockno; + uint8_t key_type; + } PACKED payload; + payload.first_run = first_run; + payload.blockno = blockno; + payload.key_type = key_type; + SendCommandNG(CMD_HF_MIFARE_READER, (uint8_t*)&payload, sizeof(payload)); //flush queue while (kbd_enter_pressed()) { @@ -56,26 +64,47 @@ int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) { } PacketResponseNG resp; - if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { - int16_t isOK = resp.oldarg[0]; - if (isOK < 0) - return isOK; + if (WaitForResponseTimeout(CMD_HF_MIFARE_READER, &resp, 2000)) { + if (resp.status == PM3_EABORTED) { + return -1; + } - uid = (uint32_t)bytes_to_num(resp.data.asBytes + 0, 4); - nt = (uint32_t)bytes_to_num(resp.data.asBytes + 4, 4); - par_list = bytes_to_num(resp.data.asBytes + 8, 8); - ks_list = bytes_to_num(resp.data.asBytes + 16, 8); - nr = (uint32_t)bytes_to_num(resp.data.asBytes + 24, 4); - ar = (uint32_t)bytes_to_num(resp.data.asBytes + 28, 4); + struct p { + int32_t isOK; + uint8_t cuid[4]; + uint8_t nt[4]; + uint8_t par_list[8]; + uint8_t ks_list[8]; + uint8_t nr[4]; + uint8_t ar[4]; + } PACKED; + + struct p* package = (struct p*) resp.data.asBytes; + + if (package->isOK == -6) { + *key = 0101; + return 1; + } + + if (package->isOK < 0) + return package->isOK; + + + uid = (uint32_t)bytes_to_num(package->cuid, sizeof(package->cuid)); + nt = (uint32_t)bytes_to_num(package->nt, sizeof(package->nr)); + par_list = bytes_to_num(package->par_list, sizeof(package->par_list)); + ks_list = bytes_to_num(package->ks_list, sizeof(package->ks_list)); + nr = (uint32_t)bytes_to_num(package->nr, 4); + ar = (uint32_t)bytes_to_num(package->ar, 4); break; } } PrintAndLogEx(NORMAL, "\n"); - if (par_list == 0 && arg0 == true) { + if (par_list == 0 && first_run == true) { PrintAndLogEx(SUCCESS, "Parity is all zero. Most likely this card sends NACK on every authentication."); } - arg0 = false; + first_run = false; uint32_t keycount = nonce2key(uid, nt, nr, ar, par_list, ks_list, &keylist); @@ -124,7 +153,7 @@ int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) { PrintAndLogEx(FAILED, "all candidate keys failed. Restarting darkside attack"); free(last_keylist); last_keylist = keylist; - arg0 = true; + first_run = true; } } free(last_keylist); From dc1650953976a643f8048898073b1980a3bb08d0 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 25 Sep 2019 15:02:40 +0200 Subject: [PATCH 0780/1854] Simple script to convert pm3 traces to something audible, thanks @rfidiot for the idea --- tools/pm3_pm32wav.py | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100755 tools/pm3_pm32wav.py diff --git a/tools/pm3_pm32wav.py b/tools/pm3_pm32wav.py new file mode 100755 index 000000000..75c94dc4c --- /dev/null +++ b/tools/pm3_pm32wav.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python3 + +# Simple script to convert pm3 traces to something audible +sampleRate = 16000.0 # hertz, so we're scaling the 125kHz to 16kHz +default_repeat = 10 + +import sys +import numpy as np +import wave +import struct + +with open(sys.argv[1]) as pm3: + data = np.fromfile(pm3, dtype=int, sep="\n") + +if len(sys.argv) > 2: + repeat = int(sys.argv[2], 10) +else: + repeat = default_repeat + +ofile = sys.argv[1].replace('pm3', 'wav') +if ofile == sys.argv[1]: + ofile = sys.argv[1]+'.wav' +obj = wave.open(ofile,'w') +obj.setnchannels(1) # mono +obj.setsampwidth(2) +obj.setframerate(sampleRate) +factor = (2**16)//512 +for i in range(repeat): + for d in data: + try: + obj.writeframesraw( struct.pack(' Date: Wed, 25 Sep 2019 22:01:51 +0200 Subject: [PATCH 0781/1854] free up some stack --- client/graph.c | 103 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 81 insertions(+), 22 deletions(-) diff --git a/client/graph.c b/client/graph.c index fc0ceab2d..094da3505 100644 --- a/client/graph.c +++ b/client/graph.c @@ -8,13 +8,14 @@ // Graph utilities //----------------------------------------------------------------------------- #include "graph.h" - +#include #include #include "ui.h" #include "util.h" //param_get32ex #include "lfdemod.h" #include "cmddata.h" //for g_debugmode + int GraphBuffer[MAX_GRAPH_TRACE_LEN]; size_t GraphTraceLen; int s_Buff[MAX_GRAPH_TRACE_LEN]; @@ -101,6 +102,7 @@ bool HasGraphData(void) { } return true; } + bool isGraphBitstream(void) { // convert to bitstream if necessary for (int i = 0; i < GraphTraceLen; i++) { @@ -110,9 +112,11 @@ bool isGraphBitstream(void) { } return true; } + void convertGraphFromBitstream() { convertGraphFromBitstreamEx(1, 0); } + void convertGraphFromBitstreamEx(int hi, int low) { for (int i = 0; i < GraphTraceLen; i++) { if (GraphBuffer[i] == hi) @@ -122,29 +126,42 @@ void convertGraphFromBitstreamEx(int hi, int low) { else GraphBuffer[i] = 0; } - uint8_t bits[GraphTraceLen]; - memset(bits, 0, sizeof(bits)); + + uint8_t *bits = calloc(GraphTraceLen, sizeof(uint8_t)); + if (bits == NULL) { + PrintAndLogEx(DEBUG, "ERR: convertGraphFromBitstreamEx, failed to allocate memory"); + return; + } + size_t size = getFromGraphBuf(bits); // set signal properties low/high/mean/amplitude and is_noise detection computeSignalProperties(bits, size); + free(bits); RepaintGraphWindow(); } // Get or auto-detect ask clock rate int GetAskClock(const char *str, bool printAns) { if (getSignalProperties()->isnoise) - return false; + return -1; int clock1 = param_get32ex(str, 0, 0, 10); if (clock1 > 0) return clock1; // Auto-detect clock - uint8_t bits[MAX_GRAPH_TRACE_LEN] = {0}; + + uint8_t *bits = calloc(MAX_GRAPH_TRACE_LEN, sizeof(uint8_t)); + if (bits == NULL) { + PrintAndLogEx(WARNING, "Failed to allocate memory"); + return -1; + } + size_t size = getFromGraphBuf(bits); if (size == 0) { PrintAndLogEx(WARNING, "Failed to copy from graphbuffer"); + free(bits); return -1; } @@ -162,20 +179,29 @@ int GetAskClock(const char *str, bool printAns) { if (printAns || g_debugMode) PrintAndLogEx(SUCCESS, "Auto-detected clock rate: %d, Best Starting Position: %d", clock1, idx); + free(bits); return clock1; } uint8_t GetPskCarrier(const char *str, bool printAns) { if (getSignalProperties()->isnoise) - return false; + return -1; uint8_t carrier = 0; - uint8_t bits[MAX_GRAPH_TRACE_LEN] = {0}; + + uint8_t *bits = calloc(MAX_GRAPH_TRACE_LEN, sizeof(uint8_t)); + if (bits == NULL) { + PrintAndLogEx(WARNING, "Failed to allocate memory"); + return -1; + } + size_t size = getFromGraphBuf(bits); if (size == 0) { PrintAndLogEx(WARNING, "Failed to copy from graphbuffer"); - return 0; + free(bits); + return -1; } + uint16_t fc = countFC(bits, size, false); carrier = fc & 0xFF; if (carrier != 2 && carrier != 4 && carrier != 8) return 0; @@ -183,6 +209,8 @@ uint8_t GetPskCarrier(const char *str, bool printAns) { // Only print this message if we're not looping something if (printAns) PrintAndLogEx(SUCCESS, "Auto-detected PSK carrier rate: %d", carrier); + + free(bits); return carrier; } @@ -196,20 +224,28 @@ int GetPskClock(const char *str, bool printAns) { return clock1; // Auto-detect clock - uint8_t grph[MAX_GRAPH_TRACE_LEN] = {0}; - size_t size = getFromGraphBuf(grph); - if (size == 0) { - PrintAndLogEx(WARNING, "Failed to copy from graphbuffer"); + uint8_t *bits = calloc(MAX_GRAPH_TRACE_LEN, sizeof(uint8_t)); + if (bits == NULL) { + PrintAndLogEx(WARNING, "Failed to allocate memory"); return -1; } + + size_t size = getFromGraphBuf(bits); + if (size == 0) { + PrintAndLogEx(WARNING, "Failed to copy from graphbuffer"); + free(bits); + return -1; + } + size_t firstPhaseShiftLoc = 0; uint8_t curPhase = 0, fc = 0; - clock1 = DetectPSKClock(grph, size, 0, &firstPhaseShiftLoc, &curPhase, &fc); + clock1 = DetectPSKClock(bits, size, 0, &firstPhaseShiftLoc, &curPhase, &fc); setClockGrid(clock1, firstPhaseShiftLoc); // Only print this message if we're not looping something if (printAns) PrintAndLogEx(SUCCESS, "Auto-detected clock rate: %d", clock1); + free(bits); return clock1; } @@ -223,21 +259,30 @@ int GetNrzClock(const char *str, bool printAns) { return clock1; // Auto-detect clock - uint8_t grph[MAX_GRAPH_TRACE_LEN] = {0}; - size_t size = getFromGraphBuf(grph); - if (size == 0) { - PrintAndLogEx(WARNING, "Failed to copy from graphbuffer"); + uint8_t *bits = calloc(MAX_GRAPH_TRACE_LEN, sizeof(uint8_t)); + if (bits == NULL) { + PrintAndLogEx(WARNING, "Failed to allocate memory"); return -1; } + + size_t size = getFromGraphBuf(bits); + if (size == 0) { + PrintAndLogEx(WARNING, "Failed to copy from graphbuffer"); + free(bits); + return -1; + } + size_t clkStartIdx = 0; - clock1 = DetectNRZClock(grph, size, 0, &clkStartIdx); + clock1 = DetectNRZClock(bits, size, 0, &clkStartIdx); setClockGrid(clock1, clkStartIdx); // Only print this message if we're not looping something if (printAns) PrintAndLogEx(SUCCESS, "Auto-detected clock rate: %d", clock1); + free(bits); return clock1; } + //by marshmellow //attempt to detect the field clock and bit clock for FSK int GetFskClock(const char *str, bool printAns) { @@ -249,12 +294,13 @@ int GetFskClock(const char *str, bool printAns) { uint8_t fc1 = 0, fc2 = 0, rf1 = 0; int firstClockEdge = 0; - if (!fskClocks(&fc1, &fc2, &rf1, &firstClockEdge)) + if (fskClocks(&fc1, &fc2, &rf1, &firstClockEdge) == false) return 0; if ((fc1 == 10 && fc2 == 8) || (fc1 == 8 && fc2 == 5)) { if (printAns) PrintAndLogEx(SUCCESS, "Detected Field Clocks: FC/%d, FC/%d - Bit Clock: RF/%d", fc1, fc2, rf1); + setClockGrid(rf1, firstClockEdge); return rf1; } @@ -263,27 +309,40 @@ int GetFskClock(const char *str, bool printAns) { PrintAndLogEx(DEBUG, "Detected Field Clocks: FC/%d, FC/%d - Bit Clock: RF/%d", fc1, fc2, rf1); return 0; } + bool fskClocks(uint8_t *fc1, uint8_t *fc2, uint8_t *rf1, int *firstClockEdge) { if (getSignalProperties()->isnoise) return false; - uint8_t bits[MAX_GRAPH_TRACE_LEN] = {0}; - size_t size = getFromGraphBuf(bits); - if (size == 0) + uint8_t *bits = calloc(MAX_GRAPH_TRACE_LEN, sizeof(uint8_t)); + if (bits == NULL) { + PrintAndLogEx(WARNING, "Failed to allocate memory"); return false; + } + + size_t size = getFromGraphBuf(bits); + if (size == 0) { + free(bits); + return false; + } uint16_t ans = countFC(bits, size, true); if (ans == 0) { PrintAndLogEx(DEBUG, "DEBUG: No data found"); + free(bits); return false; } *fc1 = (ans >> 8) & 0xFF; *fc2 = ans & 0xFF; *rf1 = detectFSKClk(bits, size, *fc1, *fc2, firstClockEdge); + + free(bits); + if (*rf1 == 0) { PrintAndLogEx(DEBUG, "DEBUG: Clock detect error"); + return false; } return true; From 86994cdc6909bfed5429761c1daadc70d83d8e4d Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 25 Sep 2019 22:06:47 +0200 Subject: [PATCH 0782/1854] textual --- client/graph.c | 1 + 1 file changed, 1 insertion(+) diff --git a/client/graph.c b/client/graph.c index 094da3505..7031da5e2 100644 --- a/client/graph.c +++ b/client/graph.c @@ -323,6 +323,7 @@ bool fskClocks(uint8_t *fc1, uint8_t *fc2, uint8_t *rf1, int *firstClockEdge) { size_t size = getFromGraphBuf(bits); if (size == 0) { + PrintAndLogEx(WARNING, "Failed to copy from graphbuffer"); free(bits); return false; } From 30d565f76c2b77d050823117f9fa9d355bad141c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 25 Sep 2019 22:10:59 +0200 Subject: [PATCH 0783/1854] free some stack --- client/cmdlfawid.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/client/cmdlfawid.c b/client/cmdlfawid.c index dcbcc0f7e..d27eb0287 100644 --- a/client/cmdlfawid.c +++ b/client/cmdlfawid.c @@ -191,10 +191,17 @@ static int CmdAWIDWatch(const char *Cmd) { //print full AWID Prox ID and some bit format details if found static int CmdAWIDDemod(const char *Cmd) { (void)Cmd; // Cmd is not used so far - uint8_t bits[MAX_GRAPH_TRACE_LEN] = {0}; + + uint8_t *bits = calloc(MAX_GRAPH_TRACE_LEN, sizeof(uint8_t)); + if (bits == NULL) { + PrintAndLogEx(DEBUG, "DEBUG: Error - AWID failed to allocate memory"); + return PM3_EMALLOC; + } + size_t size = getFromGraphBuf(bits); if (size == 0) { PrintAndLogEx(DEBUG, "DEBUG: Error - AWID not enough samples"); + free(bits); return PM3_ENODATA; } //get binary from fsk wave @@ -215,6 +222,7 @@ static int CmdAWIDDemod(const char *Cmd) { else PrintAndLogEx(DEBUG, "DEBUG: Error - AWID error demoding fsk %d", idx); + free(bits); return PM3_ESOFT; } @@ -243,6 +251,7 @@ static int CmdAWIDDemod(const char *Cmd) { size = removeParity(bits, idx + 8, 4, 1, 88); if (size != 66) { PrintAndLogEx(DEBUG, "DEBUG: Error - AWID at parity check-tag size does not match AWID format"); + free(bits); return PM3_ESOFT; } // ok valid card found! @@ -312,6 +321,7 @@ static int CmdAWIDDemod(const char *Cmd) { } break; } + free(bits); PrintAndLogEx(DEBUG, "DEBUG: AWID idx: %d, Len: %d Printing Demod Buffer:", idx, size); if (g_debugMode) From 7e15e0612ae3a138815f7bbae8f095c1f5cdb5d9 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 25 Sep 2019 22:13:56 +0200 Subject: [PATCH 0784/1854] remove debug --- client/cmdlfem4x.c | 44 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c index 92df808d1..e7ace4113 100644 --- a/client/cmdlfem4x.c +++ b/client/cmdlfem4x.c @@ -850,7 +850,6 @@ int EM4x50Read(const char *Cmd, bool verbose) { // set clock if (clk == 0) { DetectASKClock(bits, size, &clk, 0); - PrintAndLogEx(INFO, " ICE CLOCK %d", clk); if (clk == 0) { if (verbose || g_debugMode) PrintAndLogEx(ERR, "Error: EM4x50 - didn't find a clock"); return PM3_ESOFT; @@ -1139,6 +1138,20 @@ static bool detectASK_BI() { } return true; } +static bool detectNRZ() { + int ans = NRZrawDemod("0 0 1", false); + if (ans != PM3_SUCCESS) { + PrintAndLogEx(DEBUG, "DEBUG: Error - EM: NRZ normal demod failed"); + + ans = NRZrawDemod("0 1 1", false); + if (ans != PM3_SUCCESS) { + PrintAndLogEx(DEBUG, "DEBUG: Error - EM: NRZ inverted demod failed"); + return false; + } + } + + return true; +} // param: idx - start index in demoded data. static int setDemodBufferEM(uint32_t *word, size_t idx) { @@ -1161,7 +1174,7 @@ static int setDemodBufferEM(uint32_t *word, size_t idx) { return PM3_SUCCESS; } -// FSK, PSK, ASK/MANCHESTER, ASK/BIPHASE, ASK/DIPHASE +// FSK, PSK, ASK/MANCHESTER, ASK/BIPHASE, ASK/DIPHASE, NRZ // should cover 90% of known used configs // the rest will need to be manually demoded for now... static int demodEM4x05resp(uint32_t *word) { @@ -1173,6 +1186,9 @@ static int demodEM4x05resp(uint32_t *word) { if (detectASK_BI() && doPreambleSearch(&idx)) return setDemodBufferEM(word, idx); + if (detectNRZ() && doPreambleSearch(&idx)) + return setDemodBufferEM(word, idx); + if (detectFSK() && doPreambleSearch(&idx)) return setDemodBufferEM(word, idx); @@ -1214,6 +1230,13 @@ static int EM4x05ReadWord_ext(uint8_t addr, uint32_t pwd, bool usePwd, uint32_t return demodEM4x05resp(word); } +static int CmdEM4x05Demod(const char *Cmd) { +// uint8_t ctmp = tolower(param_getchar(Cmd, 0)); + // if (ctmp == 'h') return usage_lf_em4x05_demod(); + uint32_t word = 0; + return demodEM4x05resp(&word); +} + static int CmdEM4x05Dump(const char *Cmd) { uint8_t addr = 0; uint32_t pwd = 0; @@ -1223,7 +1246,7 @@ static int CmdEM4x05Dump(const char *Cmd) { uint32_t data[16]; char preferredName[FILE_PATH_SIZE] = {0}; char optchk[10]; - + while (param_getchar(Cmd, cmdp) != 0x00) { switch (tolower(param_getchar(Cmd, cmdp))) { case 'h': return usage_lf_em4x05_dump(); @@ -1235,7 +1258,7 @@ static int CmdEM4x05Dump(const char *Cmd) { cmdp+=2; break; } // if not a single 'f' dont break and flow onto default as should be password - + default : // for backwards-compatibility options should be > 'f' else assume its the hex password` // for now use default input of 1 as invalid (unlikely 1 will be a valid password...) pwd = param_get32ex(Cmd, cmdp, 1, 16); @@ -1248,20 +1271,20 @@ static int CmdEM4x05Dump(const char *Cmd) { int success = PM3_SUCCESS; int status; uint32_t lock_bits = 0x00; // no blocks locked - + uint32_t word = 0; PrintAndLogEx(NORMAL, "Addr | data | ascii |lck| info"); PrintAndLogEx(NORMAL, "-----+----------+-------+---+-----"); - + // To flag any blocks locked we need to read blocks 14 and 15 first // dont swap endin until we get block lock flags. status = EM4x05ReadWord_ext(14, pwd, usePwd, &word); if (status != PM3_SUCCESS) success = PM3_ESOFT; // If any error ensure fail is set so not to save invalid data - if (word != 0x00) + if (word != 0x00) lock_bits = word; data[14] = word; - + status = EM4x05ReadWord_ext(15, pwd, usePwd, &word); if (status != PM3_SUCCESS) success = PM3_ESOFT; // If any error ensure fail is set so not to save invalid data @@ -1270,7 +1293,7 @@ static int CmdEM4x05Dump(const char *Cmd) { data[15] = word; // Now read blocks 0 - 13 as we have 14 and 15 - for (; addr < 14; addr++) { + for (; addr < 14; addr++) { if (addr == 2) { if (usePwd) { @@ -1634,10 +1657,13 @@ static command_t CommandTable[] = { {"410x_watch", CmdEM410xWatch, IfPm3Lf, "watches for EM410x 125/134 kHz tags (option 'h' for 134)"}, {"410x_spoof", CmdEM410xWatchnSpoof, IfPm3Lf, "watches for EM410x 125/134 kHz tags, and replays them. (option 'h' for 134)" }, {"410x_write", CmdEM410xWrite, IfPm3Lf, "write EM410x UID to T5555(Q5) or T55x7 tag"}, + + {"4x05_demod", CmdEM4x05Demod, AlwaysAvailable, "demodulate a EM4x05/EM4x69 tag from the GraphBuffer"}, {"4x05_dump", CmdEM4x05Dump, IfPm3Lf, "dump EM4x05/EM4x69 tag"}, {"4x05_info", CmdEM4x05Info, IfPm3Lf, "tag information EM4x05/EM4x69"}, {"4x05_read", CmdEM4x05Read, IfPm3Lf, "read word data from EM4x05/EM4x69"}, {"4x05_write", CmdEM4x05Write, IfPm3Lf, "write word data to EM4x05/EM4x69"}, + {"4x50_demod", CmdEM4x50Demod, AlwaysAvailable, "demodulate a EM4x50 tag from the GraphBuffer"}, {"4x50_dump", CmdEM4x50Dump, IfPm3Lf, "dump EM4x50 tag"}, {"4x50_read", CmdEM4x50Read, IfPm3Lf, "read word data from EM4x50"}, From 7c2231974daa5ec59d52092d06b56256c7348408 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 26 Sep 2019 09:54:43 +0200 Subject: [PATCH 0785/1854] clean up, explain, lesser tests for buttonpress --- armsrc/iso14443a.c | 25 ++++++++++++++++--------- client/mifare/mifarehost.c | 2 +- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 7b0db6499..81bada416 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -2821,12 +2821,12 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) { if (checkbtn_cnt == 2000) { if (BUTTON_PRESS() || data_available()) { isOK = -1; - return_status = PM3_EABORTED; + return_status = PM3_EOPABORTED; break; } checkbtn_cnt = 0; } - checkbtn_cnt++; + ++checkbtn_cnt; // this part is from Piwi's faster nonce collecting part in Hardnested. if (!have_uid) { // need a full select cycle to get the uid first @@ -2885,10 +2885,11 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) { // Receive answer. This will be a 4 Bit NACK when the 8 parity bits are OK after decoding int resp_res = ReaderReceive(receivedAnswer, receivedAnswerPar); - if (resp_res == 4) + if (resp_res == 1) received_nack = true; - else if (resp_res == 32) { + else if (resp_res == 4) { // did we get lucky and got our dummykey to be valid? + // however we dont feed key w uid it the prng.. isOK = -6; break; } @@ -3075,6 +3076,8 @@ void DetectNACKbug(void) { sync_time = GetCountSspClk() & 0xfffffff8; LED_C_ON(); + uint16_t checkbtn_cnt = 0; + uint16_t i; for (i = 1; true; ++i) { @@ -3089,10 +3092,14 @@ void DetectNACKbug(void) { WDT_HIT(); // Test if the action was cancelled - if (BUTTON_PRESS() || data_available()) { - status = PM3_EOPABORTED; - break; + if (checkbtn_cnt == 2000) { + if (BUTTON_PRESS() || data_available()) { + status = PM3_EOPABORTED; + break; + } + checkbtn_cnt = 0; } + ++checkbtn_cnt; // this part is from Piwi's faster nonce collecting part in Hardnested. if (!have_uid) { // need a full select cycle to get the uid first @@ -3152,10 +3159,11 @@ void DetectNACKbug(void) { // Transmit reader nonce with fake par ReaderTransmitPar(mf_nr_ar, sizeof(mf_nr_ar), par, NULL); + // Receive answer. This will be a 4 Bit NACK when the 8 parity bits are OK after decoding if (ReaderReceive(receivedAnswer, receivedAnswerPar)) { received_nack = true; num_nacks++; - // ALWAYS leak Detection. + // ALWAYS leak Detection. Well, we could be lucky and get a response nack on first try. if (i == num_nacks) { continue; } @@ -3272,7 +3280,6 @@ void DetectNACKbug(void) { num_to_bytes(i, 2, data + 2); reply_ng(CMD_HF_MIFARE_NACK_DETECT, status, data, 4); - //reply_mix(CMD_ACK, isOK, num_nacks, i, 0, 0); BigBuf_free(); hf_field_off(); set_tracing(false); diff --git a/client/mifare/mifarehost.c b/client/mifare/mifarehost.c index ac8015d98..7cfabf3ee 100644 --- a/client/mifare/mifarehost.c +++ b/client/mifare/mifarehost.c @@ -65,7 +65,7 @@ int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) { PacketResponseNG resp; if (WaitForResponseTimeout(CMD_HF_MIFARE_READER, &resp, 2000)) { - if (resp.status == PM3_EABORTED) { + if (resp.status == PM3_EOPABORTED) { return -1; } From 300014d3b7aee8658589f90e6810ab3db89b953e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 26 Sep 2019 11:29:20 +0200 Subject: [PATCH 0786/1854] more keys --- client/dictionaries/mfc_default_keys.dic | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index a12291199..376676f1a 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -1020,3 +1020,9 @@ e6849fcc324b 39ad2963d3d1 34b16cd59ff8 # Hotel Berlin Classic room A KEY bb2c0007d022 # Hotel Berlin Classic room B KEY +# +# Coinmatic laundry Smart card +# data from: https://pastebin.com/XZQiLtUf +# +0734bfb93dab +85a438f72a8a From 5d503fc5d3bba265bdbed51e2e66df8793228ea1 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 26 Sep 2019 16:29:23 +0200 Subject: [PATCH 0787/1854] textual --- client/graph.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/client/graph.c b/client/graph.c index 7031da5e2..05d6a33dd 100644 --- a/client/graph.c +++ b/client/graph.c @@ -84,6 +84,8 @@ void setGraphBuf(uint8_t *buff, size_t size) { size_t getFromGraphBuf(uint8_t *buff) { if (buff == NULL) return 0; + if (GraphTraceLen == 0) return 0; + size_t i; for (i = 0; i < GraphTraceLen; ++i) { //trim @@ -134,6 +136,11 @@ void convertGraphFromBitstreamEx(int hi, int low) { } size_t size = getFromGraphBuf(bits); + if (size == 0) { + PrintAndLogEx(WARNING, "Failed to copy from graphbuffer"); + free(bits); + return -1; + } // set signal properties low/high/mean/amplitude and is_noise detection computeSignalProperties(bits, size); From fa2031c97a86188da42e18c7ae805114132d6ceb Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 26 Sep 2019 16:30:29 +0200 Subject: [PATCH 0788/1854] whitespace --- client/cmddata.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/cmddata.c b/client/cmddata.c index 2e28eeb03..23043cd98 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -532,7 +532,7 @@ int ASKDemod_ext(const char *Cmd, bool verbose, bool emSearch, uint8_t askType, invert = 1; clk = 0; } - uint8_t *bits = calloc(MAX_GRAPH_TRACE_LEN, sizeof(uint8_t)); + uint8_t *bits = calloc(MAX_GRAPH_TRACE_LEN, sizeof(uint8_t)); if (bits == NULL) { return PM3_EMALLOC; } @@ -1119,13 +1119,13 @@ int FSKrawDemod(const char *Cmd, bool verbose) { if (bits == NULL) { return PM3_EMALLOC; } - + size_t BitLen = getFromGraphBuf(bits); if (BitLen == 0) { free(bits); return PM3_ESOFT; } - + //get field clock lengths if (!fchigh || !fclow) { uint16_t fcs = countFC(bits, BitLen, true); From 0cdc2c446a66d43e6b307d3cbf2757b7cd42241c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 26 Sep 2019 16:39:02 +0200 Subject: [PATCH 0789/1854] less output when on NON-RDV4 platform --- client/cmdhw.c | 39 +++++++++++++++++++++++++-------------- client/graph.c | 2 +- 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/client/cmdhw.c b/client/cmdhw.c index c363fdc25..a6f242b8f 100644 --- a/client/cmdhw.c +++ b/client/cmdhw.c @@ -467,10 +467,14 @@ static int CmdSetMux(const char *Cmd) { str_lower((char *)Cmd); uint8_t arg = 0; - if (strcmp(Cmd, "lopkd") == 0) arg = 0; - else if (strcmp(Cmd, "loraw") == 0) arg = 1; - else if (strcmp(Cmd, "hipkd") == 0) arg = 2; - else if (strcmp(Cmd, "hiraw") == 0) arg = 3; + if (strcmp(Cmd, "lopkd") == 0) + arg = 0; + else if (strcmp(Cmd, "loraw") == 0) + arg = 1; + else if (strcmp(Cmd, "hipkd") == 0) + arg = 2; + else if (strcmp(Cmd, "hiraw") == 0) + arg = 3; else { usage_hw_setmux(); return PM3_EINVARG; @@ -570,8 +574,6 @@ static int CmdConnect(const char *Cmd) { memcpy(port, conn.serial_port_name, sizeof(port)); } - printf("Port:: %s Baud:: %u\n", port, baudrate); - if (session.pm3_present) { CloseProxmark(); } @@ -582,14 +584,15 @@ static int CmdConnect(const char *Cmd) { if (session.pm3_present && (TestProxmark() != PM3_SUCCESS)) { PrintAndLogEx(ERR, _RED_("ERROR:") "cannot communicate with the Proxmark3\n"); CloseProxmark(); + return PM3_ENOTTY; } return PM3_SUCCESS; } static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, - {"dbg", CmdDbg, IfPm3Present, "Set Proxmark3 debug level"}, {"connect", CmdConnect, AlwaysAvailable, "connect Proxmark3 to serial port"}, + {"dbg", CmdDbg, IfPm3Present, "Set Proxmark3 debug level"}, {"detectreader", CmdDetectReader, IfPm3Present, "['l'|'h'] -- Detect external reader field (option 'l' or 'h' to limit to LF or HF)"}, {"fpgaoff", CmdFPGAOff, IfPm3Present, "Set FPGA off"}, {"lcd", CmdLCD, IfPm3Lcd, " -- Send command/data to LCD"}, @@ -690,14 +693,22 @@ void pm3_version(bool verbose, bool oneliner) { PrintAndLogEx(NORMAL, "\n [ CLIENT ]"); PrintAndLogEx(NORMAL, " client: RRG/Iceman"); // TODO version info? PrintAndLogEx(NORMAL, " compiled with " PM3CLIENTCOMPILER __VERSION__ PM3HOSTOS PM3HOSTARCH); - PrintAndLogEx(NORMAL, "\n [ PROXMARK RDV4 ]"); - PrintAndLogEx(NORMAL, " external flash: %s", IfPm3Flash() ? _GREEN_("present") : _YELLOW_("absent")); - PrintAndLogEx(NORMAL, " smartcard reader: %s", IfPm3Smartcard() ? _GREEN_("present") : _YELLOW_("absent")); - PrintAndLogEx(NORMAL, "\n [ PROXMARK RDV4 Extras ]"); - PrintAndLogEx(NORMAL, " FPC USART for BT add-on support: %s", IfPm3FpcUsartHost() ? _GREEN_("present") : _YELLOW_("absent")); - if (IfPm3FpcUsartDevFromUsb()) - PrintAndLogEx(NORMAL, " FPC USART for developer support: %s", _GREEN_("present")); +//#if PLATFORM == PM3RDV4 + if ( IfPm3Flash() == false && IfPm3Smartcard() == false && IfPm3FpcUsartHost() == false) { + PrintAndLogEx(NORMAL, "\n [ PROXMARK3 ]"); + } else { + PrintAndLogEx(NORMAL, "\n [ PROXMARK3 RDV4 ]"); + PrintAndLogEx(NORMAL, " external flash: %s", IfPm3Flash() ? _GREEN_("present") : _YELLOW_("absent")); + PrintAndLogEx(NORMAL, " smartcard reader: %s", IfPm3Smartcard() ? _GREEN_("present") : _YELLOW_("absent")); + PrintAndLogEx(NORMAL, "\n [ PROXMARK3 RDV4 Extras ]"); + PrintAndLogEx(NORMAL, " FPC USART for BT add-on support: %s", IfPm3FpcUsartHost() ? _GREEN_("present") : _YELLOW_("absent")); + + if (IfPm3FpcUsartDevFromUsb()) { + PrintAndLogEx(NORMAL, " FPC USART for developer support: %s", _GREEN_("present")); + } + } +//#endif PrintAndLogEx(NORMAL, ""); diff --git a/client/graph.c b/client/graph.c index 05d6a33dd..be1d64920 100644 --- a/client/graph.c +++ b/client/graph.c @@ -139,7 +139,7 @@ void convertGraphFromBitstreamEx(int hi, int low) { if (size == 0) { PrintAndLogEx(WARNING, "Failed to copy from graphbuffer"); free(bits); - return -1; + return; } // set signal properties low/high/mean/amplitude and is_noise detection From cfe881040764d76390660c8d1bf811c6d7cdbfe5 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 26 Sep 2019 20:31:02 +0200 Subject: [PATCH 0790/1854] add 'lf paradox clone' - take raw hex and clone to t55x7 --- client/cmdlfparadox.c | 59 +++++++++++++++++++++++++++++++++++++++++-- client/cmdlft55xx.c | 53 ++++++++++++++++++++++++++++++++++++++ client/cmdlft55xx.h | 1 + 3 files changed, 111 insertions(+), 2 deletions(-) diff --git a/client/cmdlfparadox.c b/client/cmdlfparadox.c index 440f47ced..b3307b8a8 100644 --- a/client/cmdlfparadox.c +++ b/client/cmdlfparadox.c @@ -14,6 +14,7 @@ #include #include +#include "commonutil.h" // ARRAYLEN #include "cmdparser.h" // command_t #include "comms.h" #include "ui.h" @@ -21,7 +22,24 @@ #include "cmddata.h" #include "cmdlf.h" #include "lfdemod.h" +#include "protocols.h" // t55xx defines +#include "cmdlft55xx.h" // clone.. + static int CmdHelp(const char *Cmd); + +static int usage_lf_paradox_clone(void) { + PrintAndLogEx(NORMAL, "clone a Paradox tag to a T55x7 tag."); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Usage: lf paradox clone [h] [b ]"); + PrintAndLogEx(NORMAL, "Options:"); + PrintAndLogEx(NORMAL, " h : this help"); + PrintAndLogEx(NORMAL, " b : raw hex data. 12 bytes max"); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Examples:"); + PrintAndLogEx(NORMAL, " lf paradox clone 0f55555695596a6a9999a59a"); + return PM3_SUCCESS; +} + /* static int usage_lf_paradox_sim(void) { PrintAndLogEx(NORMAL, "Enables simulation of Paradox card with specified card number."); @@ -113,8 +131,45 @@ static int CmdParadoxRead(const char *Cmd) { } static int CmdParadoxClone(const char *Cmd) { - PrintAndLogEx(INFO, " To be implemented, feel free to contribute!"); - return PM3_SUCCESS; + + uint32_t blocks[4]; + bool errors = false; + uint8_t cmdp = 0; + int datalen = 0; + + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { + case 'h': + return usage_lf_paradox_clone(); + case 'b': { + // skip first block, 3*4 =12 bytes left + uint8_t rawhex[12] = {0}; + int res = param_gethex_to_eol(Cmd, cmdp + 1, rawhex, sizeof(rawhex), &datalen); + if ( res != 0 ) + errors = true; + + for(uint8_t i = 1; i < ARRAYLEN(blocks); i++) { + blocks[i] = bytes_to_num(rawhex + ( (i - 1) * 4 ), sizeof(uint32_t)); + } + cmdp += 2; + break; + } + default: + PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } + } + + if (errors || cmdp == 0) return usage_lf_paradox_clone(); + + //Securakey - compat mode, ASK/Man, data rate 40, 3 data blocks + blocks[0] = T55x7_MODULATION_FSK2a | T55x7_BITRATE_RF_50 | 3 << T55x7_MAXBLOCK_SHIFT; + + PrintAndLogEx(INFO, "Preparing to clone Paradox to T55x7 with raw hex"); + print_blocks(blocks, ARRAYLEN(blocks)); + + return clone_t55xx_tag(blocks, ARRAYLEN(blocks)); } static int CmdParadoxSim(const char *Cmd) { diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index a41cd9f40..8cc8142a7 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -338,6 +338,59 @@ static int usage_t55xx_protect() { static int CmdHelp(const char *Cmd); +int clone_t55xx_tag(uint32_t *blockdata, uint8_t numblocks) { + + if (blockdata == NULL) + return PM3_EINVARG; + if (numblocks < 1 || numblocks > 7) + return PM3_EINVARG; + + PacketResponseNG resp; + + // fast push mode + conn.block_after_ACK = true; + + for (int8_t i = 0; i < numblocks; i++) { + + // Disable fast mode on last packet + if (i == numblocks - 1) { + conn.block_after_ACK = false; + } + + clearCommandBuffer(); + + t55xx_write_block_t ng; + ng.data = blockdata[i]; + ng.pwd = 0; + ng.blockno = i; + ng.flags = 0; + + SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng)); + if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, T55XX_WRITE_TIMEOUT)) { + PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); + return PM3_ETIMEOUT; + } + } + + uint8_t res = 0; + for (int8_t i = 0; i < numblocks; i++) { + + if (i == 0) { + SetConfigWithBlock0(blockdata[0]); + if (t55xxAquireAndCompareBlock0(false, 0, blockdata[0], false)) + continue; + } + + if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blockdata[i]) == false) + res++; + } + + if (res == 0) + PrintAndLogEx(SUCCESS, "Success writing to tag"); + + return PM3_SUCCESS; +} + static bool t55xxProtect(bool lock, bool usepwd, uint8_t override, uint32_t password, uint8_t downlink_mode, uint32_t new_password) { PrintAndLogEx(INFO, "Checking current configuration"); diff --git a/client/cmdlft55xx.h b/client/cmdlft55xx.h index 1b70ca9ca..dce3a1b16 100644 --- a/client/cmdlft55xx.h +++ b/client/cmdlft55xx.h @@ -169,4 +169,5 @@ uint8_t tryOnePassword(uint32_t password, uint8_t downlink_mode); void printT55x7Trace(t55x7_tracedata_t data, uint8_t repeat); void printT5555Trace(t5555_tracedata_t data, uint8_t repeat); +int clone_t55xx_tag(uint32_t *blockdata, uint8_t numblocks); #endif From 2dd77330b1223e893ca3348003f27fe0e0475ad7 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 26 Sep 2019 20:31:54 +0200 Subject: [PATCH 0791/1854] add 'lf securakey clone' - take raw hew and clone to t55x7 --- client/cmdlfsecurakey.c | 63 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 59 insertions(+), 4 deletions(-) diff --git a/client/cmdlfsecurakey.c b/client/cmdlfsecurakey.c index e14a679f2..ac1f5970c 100644 --- a/client/cmdlfsecurakey.c +++ b/client/cmdlfsecurakey.c @@ -9,18 +9,35 @@ //----------------------------------------------------------------------------- #include "cmdlfsecurakey.h" -#include +#include // memcpy +#include // tolower -#include "cmdparser.h" // command_t +#include "commonutil.h" // ARRAYLEN +#include "cmdparser.h" // command_t #include "comms.h" #include "ui.h" #include "cmddata.h" #include "cmdlf.h" #include "lfdemod.h" // preamble test #include "parity.h" // for wiegand parity test +#include "protocols.h" // t55xx defines +#include "cmdlft55xx.h" // clone.. static int CmdHelp(const char *Cmd); +static int usage_lf_securakey_clone(void) { + PrintAndLogEx(NORMAL, "clone a Securakey tag to a T55x7 tag."); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Usage: lf securakey clone [h] [b ]"); + PrintAndLogEx(NORMAL, "Options:"); + PrintAndLogEx(NORMAL, " h : this help"); + PrintAndLogEx(NORMAL, " b : raw hex data. 12 bytes max"); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Examples:"); + PrintAndLogEx(NORMAL, " lf securakey clone 7FCB400001ADEA5344300000"); + return PM3_SUCCESS; +} + //see ASKDemod for what args are accepted static int CmdSecurakeyDemod(const char *Cmd) { (void)Cmd; // Cmd is not used so far @@ -100,6 +117,7 @@ static int CmdSecurakeyDemod(const char *Cmd) { PrintAndLogEx(SUCCESS, "Securakey Tag Found--BitLen: %u, Card ID: %u, FC: 0x%X, Raw: %08X%08X%08X", bitLen, cardid, fc, raw1, raw2, raw3); if (bitLen <= 32) PrintAndLogEx(SUCCESS, "Wiegand: %08X, Parity: %s", (lWiegand << (bitLen / 2)) | rWiegand, parity ? "Passed" : "Failed"); + PrintAndLogEx(INFO, "\nHow the FC translates to printed FC is unknown"); PrintAndLogEx(INFO, "How the checksum is calculated is unknown"); PrintAndLogEx(INFO, "Help the community identify this format further\n by sharing your tag on the pm3 forum or with forum members"); @@ -112,8 +130,45 @@ static int CmdSecurakeyRead(const char *Cmd) { } static int CmdSecurakeyClone(const char *Cmd) { - PrintAndLogEx(INFO, " To be implemented, feel free to contribute!"); - return PM3_SUCCESS; + + uint32_t blocks[4]; + bool errors = false; + uint8_t cmdp = 0; + int datalen = 0; + + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { + case 'h': + return usage_lf_securakey_clone(); + case 'b': { + // skip first block, 3*4 =12 bytes left + uint8_t rawhex[12] = {0}; + int res = param_gethex_to_eol(Cmd, cmdp + 1, rawhex, sizeof(rawhex), &datalen); + if ( res != 0 ) + errors = true; + + for(uint8_t i = 1; i < ARRAYLEN(blocks); i++) { + blocks[i] = bytes_to_num(rawhex + ( (i - 1) * 4 ), sizeof(uint32_t)); + } + cmdp += 2; + break; + } + default: + PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } + } + + if (errors || cmdp == 0) return usage_lf_securakey_clone(); + + //Securakey - compat mode, ASK/Man, data rate 40, 3 data blocks + blocks[0] = T55x7_MODULATION_MANCHESTER | T55x7_BITRATE_RF_40 | 3 << T55x7_MAXBLOCK_SHIFT; + + PrintAndLogEx(INFO, "Preparing to clone Securakey to T55x7 with raw hex"); + print_blocks(blocks, ARRAYLEN(blocks)); + + return clone_t55xx_tag(blocks, ARRAYLEN(blocks)); } static int CmdSecurakeySim(const char *Cmd) { From 4ed295b730a69641b2ca2509a27b1a5fcb4b9627 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 26 Sep 2019 20:32:33 +0200 Subject: [PATCH 0792/1854] chg reworked t55x7 clone function --- client/cmdlfpyramid.c | 66 ++++++++++++++++--------------------------- client/cmdlfpyramid.h | 15 ---------- 2 files changed, 25 insertions(+), 56 deletions(-) diff --git a/client/cmdlfpyramid.c b/client/cmdlfpyramid.c index 216e0834e..fa93a395c 100644 --- a/client/cmdlfpyramid.c +++ b/client/cmdlfpyramid.c @@ -8,6 +8,23 @@ // FSK2a, rf/50, 128 bits (complete) //----------------------------------------------------------------------------- #include "cmdlfpyramid.h" +#include "common.h" +#include +#include +#include +#include + +#include "commonutil.h" // ARRAYLEN +#include "cmdparser.h" // command_t +#include "comms.h" +#include "ui.h" +#include "graph.h" +#include "cmddata.h" +#include "cmdlf.h" +#include "protocols.h" // for T55xx config register definitions +#include "lfdemod.h" // parityTest +#include "crc.h" +#include "cmdlft55xx.h" // verifywrite static int CmdHelp(const char *Cmd); @@ -203,8 +220,10 @@ static int CmdPyramidClone(const char *Cmd) { uint32_t facilitycode = 0, cardnumber = 0, fc = 0, cn = 0; uint32_t blocks[5]; - uint8_t bs[128]; - memset(bs, 0x00, sizeof(bs)); + uint8_t *bs = calloc(128, sizeof(uint8_t)); + if (bs == NULL) { + return PM3_EMALLOC; + } if (sscanf(Cmd, "%u %u", &fc, &cn) != 2) return usage_lf_pyramid_clone(); @@ -228,47 +247,12 @@ static int CmdPyramidClone(const char *Cmd) { blocks[3] = bytebits_to_byte(bs + 64, 32); blocks[4] = bytebits_to_byte(bs + 96, 32); + free(bs); + PrintAndLogEx(INFO, "Preparing to clone Farpointe/Pyramid to T55x7 with Facility Code: %u, Card Number: %u", facilitycode, cardnumber); - print_blocks(blocks, 5); + print_blocks(blocks, ARRAYLEN(blocks)); - uint8_t res = 0; - PacketResponseNG resp; - - // fast push mode - conn.block_after_ACK = true; - for (int8_t i = 0; i < 5; i++) { - if (i == 4) { - // Disable fast mode on last packet - conn.block_after_ACK = false; - } - clearCommandBuffer(); - t55xx_write_block_t ng; - ng.data = blocks[i]; - ng.pwd = 0; - ng.blockno = i; - ng.flags = 0; - - SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng)); - if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, T55XX_WRITE_TIMEOUT)) { - PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); - return PM3_ETIMEOUT; - } - - if (i == 0) { - SetConfigWithBlock0(blocks[0]); - if (t55xxAquireAndCompareBlock0(false, 0, blocks[0], false)) - continue; - } - - if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) - res++; - - } - - if (res == 0) - PrintAndLogEx(SUCCESS, "Success writing to tag"); - - return PM3_SUCCESS; + return clone_t55xx_tag(blocks, ARRAYLEN(blocks)); } static int CmdPyramidSim(const char *Cmd) { diff --git a/client/cmdlfpyramid.h b/client/cmdlfpyramid.h index 0a9e2674a..2d717fbb3 100644 --- a/client/cmdlfpyramid.h +++ b/client/cmdlfpyramid.h @@ -10,21 +10,6 @@ #define CMDLFPYRAMID_H__ #include "common.h" -#include -#include -#include -#include - -#include "cmdparser.h" // command_t -#include "comms.h" -#include "ui.h" -#include "graph.h" -#include "cmddata.h" -#include "cmdlf.h" -#include "protocols.h" // for T55xx config register definitions -#include "lfdemod.h" // parityTest -#include "crc.h" -#include "cmdlft55xx.h" // verifywrite int CmdLFPyramid(const char *Cmd); From 563f6bee47281ba5a1e4947e3ce9ee1f30a1f5ea Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 26 Sep 2019 20:36:13 +0200 Subject: [PATCH 0793/1854] chg rework tx55 clone --- client/cmdlfpresco.c | 56 ++++++++++++++------------------------------ client/cmdlfpresco.h | 14 ----------- 2 files changed, 17 insertions(+), 53 deletions(-) diff --git a/client/cmdlfpresco.c b/client/cmdlfpresco.c index f563e2ef8..cfe56ad5e 100644 --- a/client/cmdlfpresco.c +++ b/client/cmdlfpresco.c @@ -9,6 +9,21 @@ #include "cmdlfpresco.h" +#include +#include +#include +#include + +#include "commonutil.h" // ARRAYLEN +#include "cmdparser.h" // command_t +#include "comms.h" +#include "ui.h" +#include "cmddata.h" +#include "cmdlf.h" +#include "protocols.h" // for T55xx config register definitions +#include "lfdemod.h" // parityTest +#include "cmdlft55xx.h" // verifywrite + static int CmdHelp(const char *Cmd); static int usage_lf_presco_clone(void) { @@ -119,46 +134,9 @@ static int CmdPrescoClone(const char *Cmd) { blocks[4] = fullcode; PrintAndLogEx(INFO, "Preparing to clone Presco to T55x7 with SiteCode: %u, UserCode: %u, FullCode: %08x", sitecode, usercode, fullcode); - print_blocks(blocks, 5); + print_blocks(blocks, ARRAYLEN(blocks)); - uint8_t res = 0; - PacketResponseNG resp; - - // fast push mode - conn.block_after_ACK = true; - for (uint8_t i = 0; i < 5; i++) { - if (i == 4) { - // Disable fast mode on last packet - conn.block_after_ACK = false; - } - clearCommandBuffer(); - t55xx_write_block_t ng; - ng.data = blocks[i]; - ng.pwd = 0; - ng.blockno = i; - ng.flags = 0; - - SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng)); - if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, T55XX_WRITE_TIMEOUT)) { - PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); - return PM3_ETIMEOUT; - } - - if (i == 0) { - SetConfigWithBlock0(blocks[0]); - if (t55xxAquireAndCompareBlock0(false, 0, blocks[0], false)) - continue; - } - - if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) - res++; - - } - - if (res == 0) - PrintAndLogEx(SUCCESS, "Success writing to tag"); - - return PM3_SUCCESS; + return clone_t55xx_tag(blocks, ARRAYLEN(blocks)); } // takes base 12 ID converts to hex diff --git a/client/cmdlfpresco.h b/client/cmdlfpresco.h index 8f7c7eb31..098a98342 100644 --- a/client/cmdlfpresco.h +++ b/client/cmdlfpresco.h @@ -11,20 +11,6 @@ #include "common.h" -#include -#include -#include -#include - -#include "cmdparser.h" // command_t -#include "comms.h" -#include "ui.h" -#include "cmddata.h" -#include "cmdlf.h" -#include "protocols.h" // for T55xx config register definitions -#include "lfdemod.h" // parityTest -#include "cmdlft55xx.h" // verifywrite - int CmdLFPresco(const char *Cmd); int demodPresco(void); From 40e793eb1a3c926238bccfb1bab578ee33cf9f7b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 26 Sep 2019 20:42:00 +0200 Subject: [PATCH 0794/1854] chg rework t55x7 clone.. --- client/cmdlfviking.c | 14 +++++++++++ client/cmdlfviking.h | 13 ---------- client/cmdlfvisa2000.c | 57 +++++++++++++----------------------------- client/cmdlfvisa2000.h | 12 --------- 4 files changed, 32 insertions(+), 64 deletions(-) diff --git a/client/cmdlfviking.c b/client/cmdlfviking.c index 9bbbeaa7e..3a2ad6a5d 100644 --- a/client/cmdlfviking.c +++ b/client/cmdlfviking.c @@ -9,6 +9,20 @@ //----------------------------------------------------------------------------- #include "cmdlfviking.h" +#include +#include +#include + +#include "common.h" + +#include "cmdparser.h" // command_t +#include "comms.h" +#include "ui.h" +#include "cmddata.h" +#include "cmdlf.h" +#include "lfdemod.h" +#include "commonutil.h" // num_to_bytes + static int CmdHelp(const char *Cmd); static int usage_lf_viking_clone(void) { diff --git a/client/cmdlfviking.h b/client/cmdlfviking.h index 344bb3c0c..156d57c7d 100644 --- a/client/cmdlfviking.h +++ b/client/cmdlfviking.h @@ -9,21 +9,8 @@ #ifndef CMDLFVIKING_H__ #define CMDLFVIKING_H__ -#include -#include -#include - #include "common.h" -#include "cmdparser.h" // command_t -#include "comms.h" -#include "ui.h" -#include "cmddata.h" -#include "cmdlf.h" -#include "lfdemod.h" -#include "commonutil.h" // num_to_bytes - - int CmdLFViking(const char *Cmd); int demodViking(void); diff --git a/client/cmdlfvisa2000.c b/client/cmdlfvisa2000.c index 9f80a830d..f60510f23 100644 --- a/client/cmdlfvisa2000.c +++ b/client/cmdlfvisa2000.c @@ -11,6 +11,22 @@ #include "cmdlfvisa2000.h" +#include +#include +#include + +#include "commonutil.h" // ARRAYLEN +#include "common.h" +#include "cmdparser.h" // command_t +#include "comms.h" +#include "ui.h" +#include "graph.h" +#include "cmddata.h" +#include "cmdlf.h" +#include "protocols.h" // for T55xx config register definitions +#include "lfdemod.h" // parityTest +#include "cmdlft55xx.h" // write verify + #define BL0CK1 0x56495332 static int CmdHelp(const char *Cmd); @@ -165,46 +181,9 @@ static int CmdVisa2kClone(const char *Cmd) { blocks[3] = (visa_parity(id) << 4) | visa_chksum(id); PrintAndLogEx(INFO, "Preparing to clone Visa2000 to T55x7 with CardId: %u", id); - print_blocks(blocks, 4); + print_blocks(blocks, ARRAYLEN(blocks)); - uint8_t res = 0; - PacketResponseNG resp; - - // fast push mode - conn.block_after_ACK = true; - for (uint8_t i = 0; i < 4; i++) { - if (i == 3) { - // Disable fast mode on last packet - conn.block_after_ACK = false; - } - clearCommandBuffer(); - t55xx_write_block_t ng; - ng.data = blocks[i]; - ng.pwd = 0; - ng.blockno = i; - ng.flags = 0; - - SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng)); - if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, T55XX_WRITE_TIMEOUT)) { - - PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); - return PM3_ETIMEOUT; - } - - if (i == 0) { - SetConfigWithBlock0(blocks[0]); - if (t55xxAquireAndCompareBlock0(false, 0, blocks[0], false)) - continue; - } - - if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) - res++; - } - - if (res == 0) - PrintAndLogEx(SUCCESS, "Success writing to tag"); - - return PM3_SUCCESS; + return clone_t55xx_tag(blocks, ARRAYLEN(blocks)); } static int CmdVisa2kSim(const char *Cmd) { diff --git a/client/cmdlfvisa2000.h b/client/cmdlfvisa2000.h index e8995cbdd..63e7fdc67 100644 --- a/client/cmdlfvisa2000.h +++ b/client/cmdlfvisa2000.h @@ -9,19 +9,7 @@ #ifndef CMDLFVISA2000_H__ #define CMDLFVISA2000_H__ -#include -#include -#include #include "common.h" -#include "cmdparser.h" // command_t -#include "comms.h" -#include "ui.h" -#include "graph.h" -#include "cmddata.h" -#include "cmdlf.h" -#include "protocols.h" // for T55xx config register definitions -#include "lfdemod.h" // parityTest -#include "cmdlft55xx.h" // write verify int CmdLFVisa2k(const char *Cmd); From e370d60171254f9983ce1d770669b36f00fc03cc Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 26 Sep 2019 20:56:18 +0200 Subject: [PATCH 0795/1854] add 'lf pac clone' - use raw hex to clone to t55x7 --- client/cmdlfpac.c | 72 +++++++++++++++++++++++++++++++++++++++++++---- client/cmdlfpac.h | 6 ---- 2 files changed, 67 insertions(+), 11 deletions(-) diff --git a/client/cmdlfpac.c b/client/cmdlfpac.c index 175d56ad4..1977224e5 100644 --- a/client/cmdlfpac.c +++ b/client/cmdlfpac.c @@ -9,8 +9,34 @@ //----------------------------------------------------------------------------- #include "cmdlfpac.h" +#include //tolower + +#include "commonutil.h" // ARRAYLEN +#include "common.h" +#include "cmdparser.h" // command_t +#include "comms.h" +#include "ui.h" +#include "cmddata.h" +#include "cmdlf.h" +#include "lfdemod.h" // preamble test +#include "protocols.h" // t55xx defines +#include "cmdlft55xx.h" // clone.. + static int CmdHelp(const char *Cmd); +static int usage_lf_pac_clone(void) { + PrintAndLogEx(NORMAL, "clone a Stanley/PAC tag to a T55x7 tag."); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Usage: lf pac clone [h] [b ]"); + PrintAndLogEx(NORMAL, "Options:"); + PrintAndLogEx(NORMAL, " h : this help"); + PrintAndLogEx(NORMAL, " b : raw hex data. 12 bytes max"); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Examples:"); + PrintAndLogEx(NORMAL, " lf pac clone b FF2049906D8511C593155B56D5B2649F "); + return PM3_SUCCESS; +} + //see NRZDemod for what args are accepted static int CmdPacDemod(const char *Cmd) { @@ -46,8 +72,8 @@ static int CmdPacDemod(const char *Cmd) { // 11111111001000000 10 01001100 10 00001101 10 00001101 10 00001101 10 00001101 10 00001101 10 00001101 10 00001101 10 00001101 10 10001100 10 100000001 // unknown checksum 9 bits at the end - PrintAndLogEx(NORMAL, "PAC/Stanley Tag Found -- Raw: %08X%08X%08X%08X", raw1, raw2, raw3, raw4); - PrintAndLogEx(NORMAL, "\nHow the Raw ID is translated by the reader is unknown"); + PrintAndLogEx(SUCCESS, "PAC/Stanley Tag Found -- Raw: %08X%08X%08X%08X", raw1, raw2, raw3, raw4); + PrintAndLogEx(INFO, "How the Raw ID is translated by the reader is unknown. Share your trace file on forum"); return PM3_SUCCESS; } @@ -57,9 +83,45 @@ static int CmdPacRead(const char *Cmd) { } static int CmdPacClone(const char *Cmd) { - // possible to raw hex and clone - PrintAndLogEx(INFO, " To be implemented, feel free to contribute!"); - return PM3_SUCCESS; + + uint32_t blocks[5]; + bool errors = false; + uint8_t cmdp = 0; + int datalen = 0; + + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { + case 'h': + return usage_lf_pac_clone(); + case 'b': { + // skip first block, 4*4 = 16 bytes left + uint8_t rawhex[16] = {0}; + int res = param_gethex_to_eol(Cmd, cmdp + 1, rawhex, sizeof(rawhex), &datalen); + if ( res != 0 ) + errors = true; + + for(uint8_t i = 1; i < ARRAYLEN(blocks); i++) { + blocks[i] = bytes_to_num(rawhex + ( (i - 1) * 4 ), sizeof(uint32_t)); + } + cmdp += 2; + break; + } + default: + PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } + } + + if (errors || cmdp == 0) return usage_lf_pac_clone(); + + //Pac - compat mode, NRZ, data rate 40, 3 data blocks + blocks[0] = T55x7_MODULATION_DIRECT | T55x7_BITRATE_RF_40 | 4 << T55x7_MAXBLOCK_SHIFT; + + PrintAndLogEx(INFO, "Preparing to clone Securakey to T55x7 with raw hex"); + print_blocks(blocks, ARRAYLEN(blocks)); + + return clone_t55xx_tag(blocks, ARRAYLEN(blocks)); } static int CmdPacSim(const char *Cmd) { diff --git a/client/cmdlfpac.h b/client/cmdlfpac.h index edb05b7a5..3c9c4fbda 100644 --- a/client/cmdlfpac.h +++ b/client/cmdlfpac.h @@ -10,12 +10,6 @@ #define CMDLFPAC_H__ #include "common.h" -#include "cmdparser.h" // command_t -#include "comms.h" -#include "ui.h" -#include "cmddata.h" -#include "cmdlf.h" -#include "lfdemod.h" // preamble test int CmdLFPac(const char *Cmd); From 0a967f7733c57a8bf6aaee424258d28e7bbb1cd5 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 26 Sep 2019 21:06:18 +0200 Subject: [PATCH 0796/1854] chg clone --- client/cmdlfnoralsy.c | 61 ++++++++++++++----------------------------- client/cmdlfnoralsy.h | 13 --------- 2 files changed, 19 insertions(+), 55 deletions(-) diff --git a/client/cmdlfnoralsy.c b/client/cmdlfnoralsy.c index fe469720b..9cec6767e 100644 --- a/client/cmdlfnoralsy.c +++ b/client/cmdlfnoralsy.c @@ -9,6 +9,20 @@ //----------------------------------------------------------------------------- #include "cmdlfnoralsy.h" +#include +#include +#include + +#include "commonutil.h" // ARRAYLEN +#include "cmdparser.h" // command_t +#include "comms.h" +#include "ui.h" +#include "cmddata.h" +#include "cmdlf.h" +#include "protocols.h" // for T55xx config register definitions +#include "lfdemod.h" // parityTest +#include "cmdlft55xx.h" // verifywrite + static int CmdHelp(const char *Cmd); static int usage_lf_noralsy_clone(void) { @@ -128,8 +142,7 @@ static int CmdNoralsyClone(const char *Cmd) { uint16_t year = 0; uint32_t id = 0; uint32_t blocks[4] = {T55x7_MODULATION_MANCHESTER | T55x7_BITRATE_RF_32 | T55x7_ST_TERMINATOR | 3 << T55x7_MAXBLOCK_SHIFT, 0, 0}; - uint8_t bits[96]; - memset(bits, 0, sizeof(bits)); + uint8_t *bits = calloc(96, sizeof(uint8_t)); char cmdp = tolower(param_getchar(Cmd, 0)); if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_noralsy_clone(); @@ -146,52 +159,16 @@ static int CmdNoralsyClone(const char *Cmd) { return PM3_ESOFT; } - // blocks[1] = bytebits_to_byte(bits, 32); blocks[2] = bytebits_to_byte(bits + 32, 32); blocks[3] = bytebits_to_byte(bits + 64, 32); + free(bits); + PrintAndLogEx(INFO, "Preparing to clone Noralsy to T55x7 with CardId: %u", id); - print_blocks(blocks, 4); + print_blocks(blocks, ARRAYLEN(blocks)); - uint8_t res = 0; - PacketResponseNG resp; - - // fast push mode - conn.block_after_ACK = true; - for (uint8_t i = 0; i < 4; i++) { - if (i == 3) { - // Disable fast mode on last packet - conn.block_after_ACK = false; - } - clearCommandBuffer(); - t55xx_write_block_t ng; - ng.data = blocks[i]; - ng.pwd = 0; - ng.blockno = i; - ng.flags = 0; - - SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng)); - if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, T55XX_WRITE_TIMEOUT)) { - PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); - return PM3_ETIMEOUT; - } - - if (i == 0) { - SetConfigWithBlock0(blocks[0]); - if (t55xxAquireAndCompareBlock0(false, 0, blocks[0], false)) - continue; - } - - if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) - res++; - } - - if (res == 0) - PrintAndLogEx(SUCCESS, "Success writing to tag"); - - return PM3_SUCCESS; -} + return clone_t55xx_tag(blocks, ARRAYLEN(blocks));} static int CmdNoralsySim(const char *Cmd) { diff --git a/client/cmdlfnoralsy.h b/client/cmdlfnoralsy.h index 56ae31372..f76accab7 100644 --- a/client/cmdlfnoralsy.h +++ b/client/cmdlfnoralsy.h @@ -11,19 +11,6 @@ #include "common.h" -#include -#include -#include - -#include "cmdparser.h" // command_t -#include "comms.h" -#include "ui.h" -#include "cmddata.h" -#include "cmdlf.h" -#include "protocols.h" // for T55xx config register definitions -#include "lfdemod.h" // parityTest -#include "cmdlft55xx.h" // verifywrite - int CmdLFNoralsy(const char *Cmd); int demodNoralsy(void); From 4e166cfd15e470d823ff5fee56faa009a4b372a3 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 26 Sep 2019 21:15:38 +0200 Subject: [PATCH 0797/1854] add 'lf nexwatch clone' - uses raw hex to clone to t55x7 --- client/cmdlfnexwatch.c | 64 +++++++++++++++++++++++++++++++++++++---- client/cmdlfsecurakey.c | 2 +- 2 files changed, 60 insertions(+), 6 deletions(-) diff --git a/client/cmdlfnexwatch.c b/client/cmdlfnexwatch.c index 5a5e127b1..d4069547b 100644 --- a/client/cmdlfnexwatch.c +++ b/client/cmdlfnexwatch.c @@ -9,16 +9,33 @@ //----------------------------------------------------------------------------- #include "cmdlfnexwatch.h" +#include // tolower +#include "commonutil.h" // ARRAYLEN #include "cmdparser.h" // command_t #include "comms.h" #include "ui.h" #include "cmddata.h" // preamblesearch #include "cmdlf.h" #include "lfdemod.h" +#include "protocols.h" // t55xx defines +#include "cmdlft55xx.h" // clone.. static int CmdHelp(const char *Cmd); +static int usage_lf_nexwatch_clone(void) { + PrintAndLogEx(NORMAL, "clone a Nexwatch tag to a T55x7 tag."); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Usage: lf nexwatch clone [h] [b ]"); + PrintAndLogEx(NORMAL, "Options:"); + PrintAndLogEx(NORMAL, " h : this help"); + PrintAndLogEx(NORMAL, " b : raw hex data. 12 bytes max"); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Examples:"); + PrintAndLogEx(NORMAL, " lf nexwatch clone b 5600000000213C9F8F150C0000000000"); + return PM3_SUCCESS; +} + static int CmdNexWatchDemod(const char *Cmd) { (void)Cmd; // Cmd is not used so far @@ -37,7 +54,7 @@ static int CmdNexWatchDemod(const char *Cmd) { // else if (idx == -3) // PrintAndLogEx(DEBUG, "DEBUG: Error - NexWatch problem during PSK demod"); else if (idx == -4) - PrintAndLogEx(DEBUG, "DEBUG: Error - NexWatch preamble not found"); + PrintAndLogEx(DEBUG, "DEBUG: Error - NexWatch preamble not found"); // else if (idx == -5) // PrintAndLogEx(DEBUG, "DEBUG: Error - NexWatch size not correct: %d", size); else @@ -47,7 +64,7 @@ static int CmdNexWatchDemod(const char *Cmd) { } setDemodBuff(DemodBuffer, size, idx + 4); - setClockGrid(g_DemodClock, g_DemodStartIdx + ((idx + 4)*g_DemodClock)); + setClockGrid(g_DemodClock, g_DemodStartIdx + ((idx + 4) * g_DemodClock)); // idx = 8 + 32; // 8 = preamble, 32 = reserved bits (always 0) @@ -82,10 +99,47 @@ static int CmdNexWatchRead(const char *Cmd) { } static int CmdNexWatchClone(const char *Cmd) { + + // 56000000 00213C9F 8F150C00 00000000 + uint32_t blocks[5]; + bool errors = false; + uint8_t cmdp = 0; + int datalen = 0; + + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { + case 'h': + return usage_lf_nexwatch_clone(); + case 'b': { + // skip first block, 4*4 = 16 bytes left + uint8_t rawhex[16] = {0}; + int res = param_gethex_to_eol(Cmd, cmdp + 1, rawhex, sizeof(rawhex), &datalen); + if ( res != 0 ) + errors = true; + + for(uint8_t i = 1; i < ARRAYLEN(blocks); i++) { + blocks[i] = bytes_to_num(rawhex + ( (i - 1) * 4 ), sizeof(uint32_t)); + } + cmdp += 2; + break; + } + default: + PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } + } + + if (errors || cmdp == 0) return usage_lf_nexwatch_clone(); + + //Nexwatch - compat mode, PSK, data rate 40, 3 data blocks + blocks[0] = T55x7_MODULATION_PSK1 | T55x7_BITRATE_RF_32 | 4 << T55x7_MAXBLOCK_SHIFT; + + PrintAndLogEx(INFO, "Preparing to clone NexWatch to T55x7 with raw hex"); + print_blocks(blocks, ARRAYLEN(blocks)); + + return clone_t55xx_tag(blocks, ARRAYLEN(blocks)); - // should be able to clone the raw hex. - PrintAndLogEx(INFO, " To be implemented, feel free to contribute!"); - return PM3_SUCCESS; } static int CmdNexWatchSim(const char *Cmd) { diff --git a/client/cmdlfsecurakey.c b/client/cmdlfsecurakey.c index ac1f5970c..784286e41 100644 --- a/client/cmdlfsecurakey.c +++ b/client/cmdlfsecurakey.c @@ -141,7 +141,7 @@ static int CmdSecurakeyClone(const char *Cmd) { case 'h': return usage_lf_securakey_clone(); case 'b': { - // skip first block, 3*4 =12 bytes left + // skip first block, 3*4 = 12 bytes left uint8_t rawhex[12] = {0}; int res = param_gethex_to_eol(Cmd, cmdp + 1, rawhex, sizeof(rawhex), &datalen); if ( res != 0 ) From ecca9fc56376839b75034e8f730426bf35d2c721 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 26 Sep 2019 21:21:13 +0200 Subject: [PATCH 0798/1854] rework clone --- client/cmdlfnedap.c | 58 +++++++++++++++------------------------------ client/cmdlfnedap.h | 13 ---------- 2 files changed, 19 insertions(+), 52 deletions(-) diff --git a/client/cmdlfnedap.c b/client/cmdlfnedap.c index b186a1354..cab5e55c6 100644 --- a/client/cmdlfnedap.c +++ b/client/cmdlfnedap.c @@ -9,6 +9,19 @@ #include "cmdlfnedap.h" +#include + +#include +#include +#include "cmdparser.h" // command_t +#include "comms.h" +#include "crc16.h" +#include "cmdlft55xx.h" // verifywrite +#include "ui.h" +#include "cmddata.h" +#include "cmdlf.h" +#include "lfdemod.h" + #define FIXED_71 0x71 #define FIXED_40 0x40 #define UNKNOWN_A 0x00 @@ -431,7 +444,7 @@ int CmdLFNedapClone(const char *Cmd) { return PM3_ESOFT; } - CmdPrintDemodBuff("x"); + //CmdPrintDemodBuff("x"); // What we had before in commented code: //NEDAP - compat mode, ASK/DIphase, data rate 64, 4 data blocks @@ -455,47 +468,14 @@ int CmdLFNedapClone(const char *Cmd) { PrintAndLogEx(SUCCESS, "Preparing to clone NEDAP to T55x7"); print_blocks(blocks, max); - uint8_t res = 0; - PacketResponseNG resp; - - // fast push mode - conn.block_after_ACK = true; - for (uint8_t i = 0; i < max; i++) { - if (i == max - 1) { - // Disable fast mode on last packet - conn.block_after_ACK = false; - } - clearCommandBuffer(); - t55xx_write_block_t ng; - ng.data = blocks[i]; - ng.pwd = 0; - ng.blockno = i; - ng.flags = 0; - - SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng)); - if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, T55XX_WRITE_TIMEOUT)) { - PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); - return PM3_ETIMEOUT; - } - - if (i == 0) { - SetConfigWithBlock0(blocks[0]); - if (t55xxAquireAndCompareBlock0(false, 0, blocks[0], false)) - continue; - } - - if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) - res++; - } - - if (res == 0) - PrintAndLogEx(SUCCESS, "Success writing to tag"); - else { - PrintAndLogEx(NORMAL, ""); + int res = clone_t55xx_tag(blocks, max); + if (res == PM3_SUCCESS) { PrintAndLogEx(INFO, "The block 0 was changed (eXtended) which can be hard to detect."); PrintAndLogEx(INFO, " Configure it manually " _YELLOW_("`lf t55xx config b 64 d BI i 1 o 32`")); + } else { + PrintAndLogEx(NORMAL, ""); } - return PM3_SUCCESS; + return res; } static int CmdLFNedapSim(const char *Cmd) { diff --git a/client/cmdlfnedap.h b/client/cmdlfnedap.h index 74fdd30fb..fda0e130e 100644 --- a/client/cmdlfnedap.h +++ b/client/cmdlfnedap.h @@ -11,19 +11,6 @@ #include "common.h" -#include - -#include -#include -#include "cmdparser.h" // command_t -#include "comms.h" -#include "crc16.h" -#include "cmdlft55xx.h" // verifywrite -#include "ui.h" -#include "cmddata.h" -#include "cmdlf.h" -#include "lfdemod.h" - int CmdLFNedap(const char *Cmd); int demodNedap(void); From 8bcb2191316e031384e9d4c5a0cf8ff06f0d0691 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 26 Sep 2019 21:24:38 +0200 Subject: [PATCH 0799/1854] rework clone --- client/cmdlfjablotron.c | 43 +++-------------------------------------- client/cmdlfkeri.c | 42 +++------------------------------------- 2 files changed, 6 insertions(+), 79 deletions(-) diff --git a/client/cmdlfjablotron.c b/client/cmdlfjablotron.c index 13a1d6e1f..d2a0d9967 100644 --- a/client/cmdlfjablotron.c +++ b/client/cmdlfjablotron.c @@ -18,7 +18,7 @@ #include "cmdparser.h" // command_t #include "comms.h" -#include "commonutil.h" +#include "commonutil.h" // ARRAYLEN #include "ui.h" #include "cmddata.h" #include "cmdlf.h" @@ -169,46 +169,9 @@ static int CmdJablotronClone(const char *Cmd) { blocks[2] = bytebits_to_byte(bits + 32, 32); PrintAndLogEx(INFO, "Preparing to clone Jablotron to T55x7 with FullCode: %"PRIx64, fullcode); - print_blocks(blocks, 3); + print_blocks(blocks, ARRAYLEN(blocks)); - uint8_t res = 0; - PacketResponseNG resp; - - // fast push mode - conn.block_after_ACK = true; - for (uint8_t i = 0; i < 3; i++) { - if (i == 2) { - // Disable fast mode on last packet - conn.block_after_ACK = false; - } - clearCommandBuffer(); - - t55xx_write_block_t ng; - ng.data = blocks[i]; - ng.pwd = 0; - ng.blockno = i; - ng.flags = 0; - - SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng)); - if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, T55XX_WRITE_TIMEOUT)) { - PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); - return PM3_ETIMEOUT; - } - - if (i == 0) { - SetConfigWithBlock0(blocks[0]); - if (t55xxAquireAndCompareBlock0(false, 0, blocks[0], false)) - continue; - } - - if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) - res++; - } - - if (res == 0) - PrintAndLogEx(SUCCESS, "Success writing to tag"); - - return PM3_SUCCESS; + return clone_t55xx_tag(blocks, ARRAYLEN(blocks)); } static int CmdJablotronSim(const char *Cmd) { diff --git a/client/cmdlfkeri.c b/client/cmdlfkeri.c index 49d3c2a33..e36388041 100644 --- a/client/cmdlfkeri.c +++ b/client/cmdlfkeri.c @@ -15,6 +15,7 @@ #include #include +#include "commonutil.h" // ARRAYLEN #include "cmdparser.h" // command_t #include "comms.h" #include "ui.h" @@ -155,49 +156,12 @@ static int CmdKeriClone(const char *Cmd) { uint64_t data = ((uint64_t)internalid << 3) + 7; PrintAndLogEx(INFO, "Preparing to clone KERI to T55x7 with Internal Id: %" PRIx64, internalid); - // blocks[1] = data >> 32; blocks[2] = data & 0xFFFFFFFF; - print_blocks(blocks, 3); - uint8_t res = 0; - PacketResponseNG resp; + print_blocks(blocks, ARRAYLEN(blocks)); - // fast push mode - conn.block_after_ACK = true; - for (uint8_t i = 0; i < 3; i++) { - if (i == 2) { - // Disable fast mode on last packet - conn.block_after_ACK = false; - } - clearCommandBuffer(); - - t55xx_write_block_t ng; - ng.data = blocks[i]; - ng.pwd = 0; - ng.blockno = i; - ng.flags = 0; - - SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng)); - if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, T55XX_WRITE_TIMEOUT)) { - PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); - return PM3_ETIMEOUT; - } - - if (i == 0) { - SetConfigWithBlock0(blocks[0]); - if (t55xxAquireAndCompareBlock0(false, 0, blocks[0], false)) - continue; - } - - if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) - res++; - } - - if (res == 0) - PrintAndLogEx(SUCCESS, "Success writing to tag"); - - return PM3_SUCCESS; + return clone_t55xx_tag(blocks, ARRAYLEN(blocks)); } static int CmdKeriSim(const char *Cmd) { From 3ea2851fe6be7ac4162089b9ee042215e560e7fa Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 26 Sep 2019 21:44:27 +0200 Subject: [PATCH 0800/1854] reworked clone --- client/cmdlffdx.c | 66 ++++++++++---------------------------------- client/cmdlfguard.c | 56 ++++++++----------------------------- client/cmdlfhid.h | 3 +- client/cmdlfindala.c | 38 +------------------------ client/cmdlfio.c | 41 ++------------------------- 5 files changed, 31 insertions(+), 173 deletions(-) diff --git a/client/cmdlffdx.c b/client/cmdlffdx.c index 85529609d..992eabdd8 100644 --- a/client/cmdlffdx.c +++ b/client/cmdlffdx.c @@ -264,12 +264,7 @@ static int CmdFdxRead(const char *Cmd) { static int CmdFdxClone(const char *Cmd) { uint32_t countryid = 0; - uint64_t animalid = 0; - uint32_t blocks[5] = {T55x7_MODULATION_DIPHASE | T55x7_BITRATE_RF_32 | 4 << T55x7_MAXBLOCK_SHIFT, 0, 0, 0, 0}; - uint8_t bits[128]; - uint8_t *bs = bits; - memset(bs, 0, sizeof(bits)); - + uint64_t animalid = 0; char cmdp = param_getchar(Cmd, 0); if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_fdx_clone(); @@ -278,63 +273,32 @@ static int CmdFdxClone(const char *Cmd) { verify_values(countryid, animalid); - // getFDXBits(uint64_t national_id, uint16_t country, uint8_t isanimal, uint8_t isextended, uint32_t extended, uint8_t *bits) - if (getFDXBits(animalid, countryid, 1, 0, 0, bs) != PM3_SUCCESS) { + uint8_t *bits = calloc(128, sizeof(uint8_t)); + + if (getFDXBits(animalid, countryid, 1, 0, 0, bits) != PM3_SUCCESS) { PrintAndLogEx(ERR, "Error with tag bitstream generation."); + free(bits); return PM3_ESOFT; } + uint32_t blocks[5] = {T55x7_MODULATION_DIPHASE | T55x7_BITRATE_RF_32 | 4 << T55x7_MAXBLOCK_SHIFT, 0, 0, 0, 0}; + //Q5 if (param_getchar(Cmd, 2) == 'Q' || param_getchar(Cmd, 2) == 'q') blocks[0] = T5555_MODULATION_BIPHASE | T5555_INVERT_OUTPUT | T5555_SET_BITRATE(32) | 4 << T5555_MAXBLOCK_SHIFT; // convert from bit stream to block data - blocks[1] = bytebits_to_byte(bs, 32); - blocks[2] = bytebits_to_byte(bs + 32, 32); - blocks[3] = bytebits_to_byte(bs + 64, 32); - blocks[4] = bytebits_to_byte(bs + 96, 32); + blocks[1] = bytebits_to_byte(bits, 32); + blocks[2] = bytebits_to_byte(bits + 32, 32); + blocks[3] = bytebits_to_byte(bits + 64, 32); + blocks[4] = bytebits_to_byte(bits + 96, 32); + free(bits); + PrintAndLogEx(INFO, "Preparing to clone FDX-B to T55x7 with animal ID: %04u-%"PRIu64, countryid, animalid); - print_blocks(blocks, 5); + print_blocks(blocks, ARRAYLEN(blocks)); - uint8_t res = 0; - PacketResponseNG resp; - - // fast push mode - conn.block_after_ACK = true; - for (int i = 4; i >= 0; --i) { - if (i == 0) { - // Disable fast mode on last packet - conn.block_after_ACK = false; - } - clearCommandBuffer(); - - t55xx_write_block_t ng; - ng.data = blocks[i]; - ng.pwd = 0; - ng.blockno = i; - ng.flags = 0; - - SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng)); - if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, T55XX_WRITE_TIMEOUT)) { - PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); - return PM3_ETIMEOUT; - } - - if (i == 0) { - SetConfigWithBlock0(blocks[0]); - if (t55xxAquireAndCompareBlock0(false, 0, blocks[0], false)) - continue; - } - - if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) - res++; - } - - if (res == 0) - PrintAndLogEx(SUCCESS, "Success writing to tag"); - - return PM3_SUCCESS; + return clone_t55xx_tag(blocks, ARRAYLEN(blocks)); } static int CmdFdxSim(const char *Cmd) { diff --git a/client/cmdlfguard.c b/client/cmdlfguard.c index fe00d1187..366fe77e3 100644 --- a/client/cmdlfguard.c +++ b/client/cmdlfguard.c @@ -14,6 +14,7 @@ #include #include +#include "commonutil.h" // ARRAYLEN #include "cmdparser.h" // command_t #include "comms.h" #include "ui.h" @@ -156,20 +157,20 @@ static int CmdGuardClone(const char *Cmd) { if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_guard_clone(); uint32_t facilitycode = 0, cardnumber = 0, fc = 0, cn = 0, fmtlen = 0; - uint8_t bs[96]; - memset(bs, 0x00, sizeof(bs)); - - //GuardProxII - compat mode, ASK/Biphase, data rate 64, 3 data blocks - uint32_t blocks[4] = {T55x7_MODULATION_BIPHASE | T55x7_BITRATE_RF_64 | 3 << T55x7_MAXBLOCK_SHIFT, 0, 0, 0}; if (sscanf(Cmd, "%u %u %u", &fmtlen, &fc, &cn) != 3) return usage_lf_guard_clone(); - + fmtlen &= 0x7f; facilitycode = (fc & 0x000000FF); cardnumber = (cn & 0x0000FFFF); + //GuardProxII - compat mode, ASK/Biphase, data rate 64, 3 data blocks + uint32_t blocks[4] = {T55x7_MODULATION_BIPHASE | T55x7_BITRATE_RF_64 | 3 << T55x7_MAXBLOCK_SHIFT, 0, 0, 0}; + uint8_t *bs = calloc(96, sizeof(uint8_t)); + if (getGuardBits(fmtlen, facilitycode, cardnumber, bs) != PM3_SUCCESS) { PrintAndLogEx(ERR, "Error with tag bitstream generation."); + free(bs); return PM3_ESOFT; } @@ -181,47 +182,12 @@ static int CmdGuardClone(const char *Cmd) { blocks[2] = bytebits_to_byte(bs + 32, 32); blocks[3] = bytebits_to_byte(bs + 64, 32); + free(bs); + PrintAndLogEx(INFO, "Preparing to clone Guardall to T55x7 with Facility Code: %u, Card Number: %u", facilitycode, cardnumber); - print_blocks(blocks, 4); + print_blocks(blocks, ARRAYLEN(blocks)); - uint8_t res = 0; - PacketResponseNG resp; - - // fast push mode - conn.block_after_ACK = true; - for (uint8_t i = 0; i < 4; i++) { - if (i == 3) { - // Disable fast mode on last packet - conn.block_after_ACK = false; - } - clearCommandBuffer(); - - t55xx_write_block_t ng; - ng.data = blocks[i]; - ng.pwd = 0; - ng.blockno = i; - ng.flags = 0; - - SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng)); - if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, T55XX_WRITE_TIMEOUT)) { - PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); - return PM3_ETIMEOUT; - } - - if (i == 0) { - SetConfigWithBlock0(blocks[0]); - if (t55xxAquireAndCompareBlock0(false, 0, blocks[0], false)) - continue; - } - - if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) - res++; - } - - if (res == 0) - PrintAndLogEx(SUCCESS, "Success writing to tag"); - - return PM3_SUCCESS; + return clone_t55xx_tag(blocks, ARRAYLEN(blocks)); } static int CmdGuardSim(const char *Cmd) { diff --git a/client/cmdlfhid.h b/client/cmdlfhid.h index 2b61861ff..5ae2d7753 100644 --- a/client/cmdlfhid.h +++ b/client/cmdlfhid.h @@ -16,6 +16,5 @@ int CmdLFHID(const char *Cmd); int demodHID(void); -//void calc26(uint16_t fc, uint32_t cardno, uint8_t *out); -void calcWiegand(uint8_t fmtlen, uint16_t fc, uint64_t cardno, uint8_t *bits, uint8_t oem); + #endif diff --git a/client/cmdlfindala.c b/client/cmdlfindala.c index 673ed1438..eae80564d 100644 --- a/client/cmdlfindala.c +++ b/client/cmdlfindala.c @@ -505,43 +505,7 @@ static int CmdIndalaClone(const char *Cmd) { print_blocks(blocks, max); - uint8_t res = 0; - PacketResponseNG resp; - - // fast push mode - conn.block_after_ACK = true; - for (uint8_t i = 0; i < max; i++) { - if (i == max - 1) { - // Disable fast mode on last packet - conn.block_after_ACK = false; - } - clearCommandBuffer(); - t55xx_write_block_t ng; - ng.data = blocks[i]; - ng.pwd = 0; - ng.blockno = i; - ng.flags = 0; - - SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng)); - if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, T55XX_WRITE_TIMEOUT)) { - PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); - return PM3_ETIMEOUT; - } - - if (i == 0) { - SetConfigWithBlock0(blocks[0]); - if (t55xxAquireAndCompareBlock0(false, 0, blocks[0], false)) - continue; - } - - if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) - res++; - } - - if (res == 0) - PrintAndLogEx(SUCCESS, "Success writing to tag"); - - return PM3_SUCCESS; + return clone_t55xx_tag(blocks, max); } static command_t CommandTable[] = { diff --git a/client/cmdlfio.c b/client/cmdlfio.c index e17ae82d1..74a9ef92d 100644 --- a/client/cmdlfio.c +++ b/client/cmdlfio.c @@ -16,6 +16,7 @@ #include +#include "commonutil.h" //ARRAYLEN #include "cmdparser.h" // command_t #include "comms.h" #include "graph.h" @@ -272,45 +273,9 @@ static int CmdIOProxClone(const char *Cmd) { blocks[2] = bytebits_to_byte(bits + 32, 32); PrintAndLogEx(INFO, "Preparing to clone IOProx to T55x7 with Version: %u FC: %u, CN: %u", version, fc, cn); - print_blocks(blocks, 3); + print_blocks(blocks, ARRAYLEN(blocks)); - uint8_t res = 0; - PacketResponseNG resp; - - // fast push mode - conn.block_after_ACK = true; - for (uint8_t i = 0; i < 3; i++) { - if (i == 2) { - // Disable fast mode on last packet - conn.block_after_ACK = false; - } - clearCommandBuffer(); - t55xx_write_block_t ng; - ng.data = blocks[i]; - ng.pwd = 0; - ng.blockno = i; - ng.flags = 0; - - SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng)); - if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, T55XX_WRITE_TIMEOUT)) { - PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); - return PM3_ETIMEOUT; - } - - if (i == 0) { - SetConfigWithBlock0(blocks[0]); - if (t55xxAquireAndCompareBlock0(false, 0, blocks[0], false)) - continue; - } - - if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) - res++; - } - - if (res == 0) - PrintAndLogEx(SUCCESS, "Success writing to tag"); - - return PM3_SUCCESS; + return clone_t55xx_tag(blocks, ARRAYLEN(blocks)); } static command_t CommandTable[] = { From 0973d30796286c1d8c88f009d700e7acc82396de Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 26 Sep 2019 21:47:48 +0200 Subject: [PATCH 0801/1854] rework clone --- client/cmdlfawid.c | 63 +++++++++++----------------------------------- 1 file changed, 14 insertions(+), 49 deletions(-) diff --git a/client/cmdlfawid.c b/client/cmdlfawid.c index d27eb0287..035730588 100644 --- a/client/cmdlfawid.c +++ b/client/cmdlfawid.c @@ -16,6 +16,7 @@ #include #include +#include "commonutil.h" // ARRAYLEN #include "cmdparser.h" // command_t #include "comms.h" #include "graph.h" @@ -385,13 +386,8 @@ static int CmdAWIDSim(const char *Cmd) { } static int CmdAWIDClone(const char *Cmd) { - uint32_t blocks[4] = {T55x7_MODULATION_FSK2a | T55x7_BITRATE_RF_50 | 3 << T55x7_MAXBLOCK_SHIFT, 0, 0, 0}; uint32_t fc = 0, cn = 0; uint8_t fmtlen = 0; - uint8_t bits[96]; - uint8_t *bs = bits; - memset(bs, 0, sizeof(bits)); - char cmdp = tolower(param_getchar(Cmd, 0)); if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_awid_clone(); @@ -401,63 +397,32 @@ static int CmdAWIDClone(const char *Cmd) { if (!fc || !cn) return usage_lf_awid_clone(); + uint32_t blocks[4] = {T55x7_MODULATION_FSK2a | T55x7_BITRATE_RF_50 | 3 << T55x7_MAXBLOCK_SHIFT, 0, 0, 0}; + if (tolower(param_getchar(Cmd, 3)) == 'q') //t5555 (Q5) BITRATE = (RF-2)/2 (iceman) blocks[0] = T5555_MODULATION_FSK2 | T5555_INVERT_OUTPUT | T5555_SET_BITRATE(50) | 3 << T5555_MAXBLOCK_SHIFT; verify_values(&fmtlen, &fc, &cn); - if (getAWIDBits(fmtlen, fc, cn, bs) != PM3_SUCCESS) { + uint8_t *bits = calloc(96, sizeof(uint8_t)); + + if (getAWIDBits(fmtlen, fc, cn, bits) != PM3_SUCCESS) { PrintAndLogEx(ERR, "Error with tag bitstream generation."); + free(bits); return PM3_ESOFT; } - blocks[1] = bytebits_to_byte(bs, 32); - blocks[2] = bytebits_to_byte(bs + 32, 32); - blocks[3] = bytebits_to_byte(bs + 64, 32); + blocks[1] = bytebits_to_byte(bits, 32); + blocks[2] = bytebits_to_byte(bits + 32, 32); + blocks[3] = bytebits_to_byte(bits + 64, 32); + free(bits); + PrintAndLogEx(INFO, "Preparing to clone AWID %u to T55x7 with FC: %u, CN: %u", fmtlen, fc, cn); - print_blocks(blocks, 4); + print_blocks(blocks, ARRAYLEN(blocks)); - uint8_t res = 0; - PacketResponseNG resp; - - // fast push mode - conn.block_after_ACK = true; - for (uint8_t i = 0; i < 4; i++) { - if (i == 3) { - // Disable fast mode on last packet - conn.block_after_ACK = false; - } - clearCommandBuffer(); - - t55xx_write_block_t ng; - - ng.data = blocks[i]; - ng.pwd = 0; - ng.blockno = i; - ng.flags = 0; - - SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng)); - if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, T55XX_WRITE_TIMEOUT)) { - PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); - return PM3_ETIMEOUT; - } - - if (i == 0) { - SetConfigWithBlock0(blocks[0]); - if (t55xxAquireAndCompareBlock0(false, 0, blocks[0], false)) - continue; - } - - if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) - res++; - } - - if (res == 0) - PrintAndLogEx(SUCCESS, "Success writing to tag"); - - return PM3_SUCCESS; + return clone_t55xx_tag(blocks, ARRAYLEN(blocks)); } static int CmdAWIDBrute(const char *Cmd) { From 5748000afc6c71328f56b120f428fb7f8226ab2f Mon Sep 17 00:00:00 2001 From: mwalker33 Date: Sat, 28 Sep 2019 13:53:24 +1000 Subject: [PATCH 0802/1854] Update cmdlfem4x.c em4x05 wipe --- client/cmdlfem4x.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c index e7ace4113..8353f1672 100644 --- a/client/cmdlfem4x.c +++ b/client/cmdlfem4x.c @@ -167,6 +167,20 @@ static int usage_lf_em4x05_dump(void) { PrintAndLogEx(NORMAL, " lf em 4x50_dump f card1 11223344"); return PM3_SUCCESS; } +static int usage_lf_em4x05_wipe(void) { + PrintAndLogEx(NORMAL, "Wipe EM4x05/EM4x69. Tag must be on antenna. "); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Usage: lf em 4x05_wipe [h] "); + PrintAndLogEx(NORMAL, "Options:"); + PrintAndLogEx(NORMAL, " h - this help"); + PrintAndLogEx(NORMAL, " c - chip type : 0 em4305 (default)"); + PrintAndLogEx(NORMAL, " 1 em4205"); + PrintAndLogEx(NORMAL, " pwd - password (hex) (optional)"); + PrintAndLogEx(NORMAL, "Examples:"); + PrintAndLogEx(NORMAL, " lf em 4x05_wipe"); + PrintAndLogEx(NORMAL, " lf em 4x05_wipe 11223344"); + return PM3_SUCCESS; +} static int usage_lf_em4x05_read(void) { PrintAndLogEx(NORMAL, "Read EM4x05/EM4x69. Tag must be on antenna. "); PrintAndLogEx(NORMAL, ""); @@ -1425,6 +1439,75 @@ static int CmdEM4x05Write(const char *Cmd) { PrintAndLogEx(NORMAL, "Write could " _RED_("not") "be verified"); return status; } +static int CmdEM4x05Wipe(const char *Cmd) { + uint8_t addr = 0; + uint32_t pwd = 0; + uint8_t cmdp = 0; + uint8_t chipType = 0; + uint32_t chipInfo = 0x00040072; // Chip info/User Block normal 4305 Chip Type + uint32_t chipUID = 0x614739AE; // UID normally readonly, but just in case + uint32_t blockData = 0x00000000; // UserBlock/Password (set to 0x00000000 for a wiped card1 + uint32_t config = 0x0001805F; // Default config (no password) + int success = PM3_SUCCESS; + char cmdStr [100]; + char optchk[10]; + + while (param_getchar(Cmd, cmdp) != 0x00) { + // check if cmd is a 1 byte option + param_getstr(Cmd, cmdp,optchk,sizeof(optchk)); + if (strlen (optchk) == 1) {// Have a single character so option not part of password + switch (tolower(param_getchar(Cmd, cmdp))) { + case 'c': // chip type + if (param_getchar(Cmd, cmdp) != 0x00) + chipType = param_get8ex (Cmd,cmdp+1,0,10); + cmdp+=2; + break; + case 'h': // return usage_lf_em4x05_wipe(); + default : // Unknown or 'h' send help + return usage_lf_em4x05_wipe(); + break; + }; + } else { // Not a single character so assume password + pwd = param_get32ex(Cmd, cmdp, 1, 16); + cmdp++; + } + } + + switch (chipType) { + case 1 : // 4205 + chipInfo = 0x00040070; + config = 0x0001805F; + break; + default : // Type 0/Default : EM4305 + chipInfo = 0x00040072; + config = 0x0001805F; + } + + // block 0 : User Data or Chip Info + sprintf (cmdStr,"%d %08X %08X",0,chipInfo,pwd); + CmdEM4x05Write (cmdStr); + // block 1 : UID - this should be read only for EM4205 and EM4305 not sure about others + sprintf (cmdStr,"%d %08X %08X",1,chipUID,pwd); + CmdEM4x05Write (cmdStr); + // block 2 : password + sprintf (cmdStr,"%d %08X %08X",2,blockData,pwd); + CmdEM4x05Write (cmdStr); + pwd = blockData; // Password should now have changed, so use new password + // block 3 : user data + sprintf (cmdStr,"%d %08X %08X",3,blockData,pwd); + CmdEM4x05Write (cmdStr); + // block 4 : config + sprintf (cmdStr,"%d %08X %08X",4,config,pwd); + CmdEM4x05Write (cmdStr); + + // Remainder of user/data blocks + for (addr = 5; addr < 14; addr++) {// Clear user data blocks + sprintf (cmdStr,"%d %08X %08X",addr,blockData,pwd); + CmdEM4x05Write (cmdStr); + } + + return success; +} static void printEM4x05config(uint32_t wordData) { uint16_t datarate = (((wordData & 0x3F) + 1) * 2); @@ -1660,6 +1743,7 @@ static command_t CommandTable[] = { {"4x05_demod", CmdEM4x05Demod, AlwaysAvailable, "demodulate a EM4x05/EM4x69 tag from the GraphBuffer"}, {"4x05_dump", CmdEM4x05Dump, IfPm3Lf, "dump EM4x05/EM4x69 tag"}, + {"4x05_wipe", CmdEM4x05Wipe, IfPm3Lf, "wipe EM4x05/EM4x69 tag"}, {"4x05_info", CmdEM4x05Info, IfPm3Lf, "tag information EM4x05/EM4x69"}, {"4x05_read", CmdEM4x05Read, IfPm3Lf, "read word data from EM4x05/EM4x69"}, {"4x05_write", CmdEM4x05Write, IfPm3Lf, "write word data to EM4x05/EM4x69"}, From b41013ca8fdd2bc18ec94500ea88408c8080fa4a Mon Sep 17 00:00:00 2001 From: mwalker33 Date: Sat, 28 Sep 2019 14:01:28 +1000 Subject: [PATCH 0803/1854] Update cmdlfem4x.c em 4x05 wipe --- client/cmdlfem4x.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c index 8353f1672..c73e63ead 100644 --- a/client/cmdlfem4x.c +++ b/client/cmdlfem4x.c @@ -173,8 +173,8 @@ static int usage_lf_em4x05_wipe(void) { PrintAndLogEx(NORMAL, "Usage: lf em 4x05_wipe [h] "); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h - this help"); - PrintAndLogEx(NORMAL, " c - chip type : 0 em4305 (default)"); - PrintAndLogEx(NORMAL, " 1 em4205"); + PrintAndLogEx(NORMAL, " c - chip type : 0 em4205"); + PrintAndLogEx(NORMAL, " 1 em4305 (default)"); PrintAndLogEx(NORMAL, " pwd - password (hex) (optional)"); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf em 4x05_wipe"); @@ -1443,7 +1443,7 @@ static int CmdEM4x05Wipe(const char *Cmd) { uint8_t addr = 0; uint32_t pwd = 0; uint8_t cmdp = 0; - uint8_t chipType = 0; + uint8_t chipType = 1; // em4305 uint32_t chipInfo = 0x00040072; // Chip info/User Block normal 4305 Chip Type uint32_t chipUID = 0x614739AE; // UID normally readonly, but just in case uint32_t blockData = 0x00000000; // UserBlock/Password (set to 0x00000000 for a wiped card1 @@ -1474,10 +1474,14 @@ static int CmdEM4x05Wipe(const char *Cmd) { } switch (chipType) { - case 1 : // 4205 + case 0 : // em4205 chipInfo = 0x00040070; config = 0x0001805F; break; + case 1 : // em4305 + chipInfo = 0x00040072; + config = 0x0001805F; + break; default : // Type 0/Default : EM4305 chipInfo = 0x00040072; config = 0x0001805F; From cf0d72e1723977c3b65b29cb7557f0bcd431feb1 Mon Sep 17 00:00:00 2001 From: mwalker33 Date: Sun, 29 Sep 2019 10:43:01 +1000 Subject: [PATCH 0804/1854] lf sniff offset Added samples to skip to lf config --- armsrc/lfsampling.c | 19 +++++++++++++++---- client/cmdlf.c | 25 ++++++++++++++++--------- include/pm3_cmd.h | 1 + 3 files changed, 32 insertions(+), 13 deletions(-) diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index 498d8f747..eea2a4c86 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -33,6 +33,7 @@ void printConfig() { Dbprintf(" [d] decimation..........%d", config.decimation); Dbprintf(" [a] averaging...........%s", (config.averaging) ? "Yes" : "No"); Dbprintf(" [t] trigger threshold...%d", config.trigger_threshold); + Dbprintf(" [s] samples to skip.....%d ", config.samples_to_skip); } /** @@ -50,6 +51,7 @@ void setSamplingConfig(sample_config *sc) { if (sc->divisor != 0) config.divisor = sc->divisor; if (sc->bits_per_sample != 0) config.bits_per_sample = sc->bits_per_sample; if (sc->trigger_threshold != -1) config.trigger_threshold = sc->trigger_threshold; + if (sc->samples_to_skip != -1) config.samples_to_skip = sc->samples_to_skip; config.decimation = (sc->decimation != 0) ? sc->decimation : 1; config.averaging = sc->averaging; @@ -124,7 +126,7 @@ void LFSetupFPGAForADC(int divisor, bool lf_field) { * @param silent - is true, now outputs are made. If false, dbprints the status * @return the number of bits occupied by the samples. */ -uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averaging, int trigger_threshold, bool silent, int bufsize, uint32_t cancel_after) { +uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averaging, int trigger_threshold, bool silent, int bufsize, uint32_t cancel_after, int samples_to_skip) { uint8_t *dest = BigBuf_get_addr(); bufsize = (bufsize > 0 && bufsize < BigBuf_max_traceLen()) ? bufsize : BigBuf_max_traceLen(); @@ -144,6 +146,7 @@ uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averag uint32_t sample_total_numbers = 0; uint32_t sample_total_saved = 0; uint32_t cancel_counter = 0; + uint32_t samples_skipped = 0; uint16_t checker = 0; @@ -176,6 +179,12 @@ uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averag } trigger_threshold = 0; + + if (samples_to_skip > samples_skipped) { + samples_skipped++; + continue; + } + sample_total_numbers++; if (averaging) @@ -196,6 +205,7 @@ uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averag // store the sample sample_total_saved ++; + if (bits_per_sample == 8) { dest[sample_total_saved - 1] = sample; @@ -238,7 +248,7 @@ uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averag * @return number of bits sampled */ uint32_t DoAcquisition_default(int trigger_threshold, bool silent) { - return DoAcquisition(1, 8, 0, trigger_threshold, silent, 0, 0); + return DoAcquisition(1, 8, 0, trigger_threshold, silent, 0, 0,0); } uint32_t DoAcquisition_config(bool silent, int sample_size) { return DoAcquisition(config.decimation @@ -247,11 +257,12 @@ uint32_t DoAcquisition_config(bool silent, int sample_size) { , config.trigger_threshold , silent , sample_size - , 0); + , 0 + , config.samples_to_skip); } uint32_t DoPartialAcquisition(int trigger_threshold, bool silent, int sample_size, uint32_t cancel_after) { - return DoAcquisition(1, 8, 0, trigger_threshold, silent, sample_size, cancel_after); + return DoAcquisition(1, 8, 0, trigger_threshold, silent, sample_size, cancel_after,0); } uint32_t ReadLF(bool activeField, bool silent, int sample_size) { diff --git a/client/cmdlf.c b/client/cmdlf.c index ee4302e82..16e8a64d5 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -105,14 +105,15 @@ static int usage_lf_sniff(void) { static int usage_lf_config(void) { PrintAndLogEx(NORMAL, "Usage: lf config [h] [H|] [b ] [d ] [a 0|1]"); PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " h This help"); - PrintAndLogEx(NORMAL, " L Low frequency (125 kHz)"); - PrintAndLogEx(NORMAL, " H High frequency (134 kHz)"); - PrintAndLogEx(NORMAL, " q Manually set divisor. 88-> 134 kHz, 95-> 125 kHz"); - PrintAndLogEx(NORMAL, " b Sets resolution of bits per sample. Default (max): 8"); - PrintAndLogEx(NORMAL, " d Sets decimation. A value of N saves only 1 in N samples. Default: 1"); - PrintAndLogEx(NORMAL, " a [0|1] Averaging - if set, will average the stored sample value when decimating. Default: 1"); - PrintAndLogEx(NORMAL, " t Sets trigger threshold. 0 means no threshold (range: 0-128)"); + PrintAndLogEx(NORMAL, " h This help"); + PrintAndLogEx(NORMAL, " L Low frequency (125 kHz)"); + PrintAndLogEx(NORMAL, " H High frequency (134 kHz)"); + PrintAndLogEx(NORMAL, " q Manually set divisor. 88-> 134 kHz, 95-> 125 kHz"); + PrintAndLogEx(NORMAL, " b Sets resolution of bits per sample. Default (max): 8"); + PrintAndLogEx(NORMAL, " d Sets decimation. A value of N saves only 1 in N samples. Default: 1"); + PrintAndLogEx(NORMAL, " a [0|1] Averaging - if set, will average the stored sample value when decimating. Default: 1"); + PrintAndLogEx(NORMAL, " t Sets trigger threshold. 0 means no threshold (range: 0-128)"); + PrintAndLogEx(NORMAL, " s Sets a number of samples to skip before capture. Default: 0"); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf config b 8 L"); PrintAndLogEx(NORMAL, " Samples at 125 kHz, 8bps."); @@ -399,6 +400,8 @@ int CmdLFSetConfig(const char *Cmd) { bool errors = false; int trigger_threshold = -1;//Means no change uint8_t unsigned_trigg = 0; + int samples_to_skip = -1; + uint8_t cmdp = 0; while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { @@ -437,6 +440,10 @@ int CmdLFSetConfig(const char *Cmd) { averaging = param_getchar(Cmd, cmdp + 1) == '1'; cmdp += 2; break; + case 's': + samples_to_skip = param_get32ex(Cmd,cmdp+1,0,10); + cmdp+=2; + break; default: PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); errors = 1; @@ -450,7 +457,7 @@ int CmdLFSetConfig(const char *Cmd) { //Bps is limited to 8 if (bps >> 4) bps = 8; - sample_config config = { decimation, bps, averaging, divisor, trigger_threshold }; + sample_config config = { decimation, bps, averaging, divisor, trigger_threshold,samples_to_skip }; clearCommandBuffer(); SendCommandNG(CMD_LF_SAMPLING_SET_CONFIG, (uint8_t *)&config, sizeof(sample_config)); diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 1628c558d..a8ef019d7 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -118,6 +118,7 @@ typedef struct { bool averaging; int divisor; int trigger_threshold; + int samples_to_skip; } PACKED sample_config; /* typedef struct { From c7b36207542648a65fa79d13cfa15d7dc9c1193f Mon Sep 17 00:00:00 2001 From: mwalker33 Date: Sun, 29 Sep 2019 11:10:07 +1000 Subject: [PATCH 0805/1854] Update lfsampling.c Set default for samples to skip --- armsrc/lfsampling.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index eea2a4c86..0926cca04 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -24,7 +24,7 @@ Default LF config is set to: divisor = 95 (125kHz) trigger_threshold = 0 */ -sample_config config = { 1, 8, 1, 95, 0 } ; +sample_config config = { 1, 8, 1, 95, 0, 0 } ; void printConfig() { DbpString(_BLUE_("LF Sampling config")); From 40b1d3bea7004dd44604a2c580d7206858181caf Mon Sep 17 00:00:00 2001 From: mwalker33 Date: Mon, 30 Sep 2019 19:22:26 +1000 Subject: [PATCH 0806/1854] samples to skip (unint32_t) Use unit32_t for all samples to skip --- CHANGELOG.md | 3 ++- armsrc/lfsampling.c | 5 +++-- client/cmdlf.c | 2 +- include/pm3_cmd.h | 2 +- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 32a317320..78a0d48d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -357,7 +357,8 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Fix T55xx config getting displayed when using password when no password needed on read. (@mwalker33) - Fix `em 4x05_dump` to print all blocks read (@mwalker33) - Added save to .eml and .bin for `em 4x05_dump` (@mwalker33) - + - Added `s` to `lf config` / `lf sniff` to skip samples when sniffing (@mwalker33) + ### Fixed - Changed driver file proxmark3.inf to support both old and new Product/Vendor IDs (@pwpiwi) - Changed start sequence in Qt mode (fix: short commands hangs main Qt thread) (@merlokk) diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index 0926cca04..97951ef37 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -51,8 +51,9 @@ void setSamplingConfig(sample_config *sc) { if (sc->divisor != 0) config.divisor = sc->divisor; if (sc->bits_per_sample != 0) config.bits_per_sample = sc->bits_per_sample; if (sc->trigger_threshold != -1) config.trigger_threshold = sc->trigger_threshold; - if (sc->samples_to_skip != -1) config.samples_to_skip = sc->samples_to_skip; +// if (sc->samples_to_skip == 0xffffffff) // if needed to not update if not supplied + config.samples_to_skip = sc->samples_to_skip; config.decimation = (sc->decimation != 0) ? sc->decimation : 1; config.averaging = sc->averaging; if (config.bits_per_sample > 8) config.bits_per_sample = 8; @@ -126,7 +127,7 @@ void LFSetupFPGAForADC(int divisor, bool lf_field) { * @param silent - is true, now outputs are made. If false, dbprints the status * @return the number of bits occupied by the samples. */ -uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averaging, int trigger_threshold, bool silent, int bufsize, uint32_t cancel_after, int samples_to_skip) { +uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averaging, int trigger_threshold, bool silent, int bufsize, uint32_t cancel_after, uint32_t samples_to_skip) { uint8_t *dest = BigBuf_get_addr(); bufsize = (bufsize > 0 && bufsize < BigBuf_max_traceLen()) ? bufsize : BigBuf_max_traceLen(); diff --git a/client/cmdlf.c b/client/cmdlf.c index 16e8a64d5..8f540310f 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -400,7 +400,7 @@ int CmdLFSetConfig(const char *Cmd) { bool errors = false; int trigger_threshold = -1;//Means no change uint8_t unsigned_trigg = 0; - int samples_to_skip = -1; + uint32_t samples_to_skip = 0; // will return offset to 0 if not supplied. Could set to 0xffffffff if needed to not update uint8_t cmdp = 0; diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index a8ef019d7..010e46728 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -118,7 +118,7 @@ typedef struct { bool averaging; int divisor; int trigger_threshold; - int samples_to_skip; + uint32_t samples_to_skip; } PACKED sample_config; /* typedef struct { From f5d7963780c2a7a7e4b9ada1bfe366e5ab23c8c0 Mon Sep 17 00:00:00 2001 From: mwalker33 Date: Mon, 30 Sep 2019 19:41:25 +1000 Subject: [PATCH 0807/1854] lf config s update --- armsrc/lfsampling.c | 9 ++++----- client/cmdlf.c | 4 ++-- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index 97951ef37..f1cea2aea 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -147,7 +147,6 @@ uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averag uint32_t sample_total_numbers = 0; uint32_t sample_total_saved = 0; uint32_t cancel_counter = 0; - uint32_t samples_skipped = 0; uint16_t checker = 0; @@ -181,8 +180,8 @@ uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averag trigger_threshold = 0; - if (samples_to_skip > samples_skipped) { - samples_skipped++; + if (samples_to_skip > 0) { + samples_to_skip--; continue; } @@ -249,7 +248,7 @@ uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averag * @return number of bits sampled */ uint32_t DoAcquisition_default(int trigger_threshold, bool silent) { - return DoAcquisition(1, 8, 0, trigger_threshold, silent, 0, 0,0); + return DoAcquisition(1, 8, 0, trigger_threshold, silent, 0, 0, 0); } uint32_t DoAcquisition_config(bool silent, int sample_size) { return DoAcquisition(config.decimation @@ -263,7 +262,7 @@ uint32_t DoAcquisition_config(bool silent, int sample_size) { } uint32_t DoPartialAcquisition(int trigger_threshold, bool silent, int sample_size, uint32_t cancel_after) { - return DoAcquisition(1, 8, 0, trigger_threshold, silent, sample_size, cancel_after,0); + return DoAcquisition(1, 8, 0, trigger_threshold, silent, sample_size, cancel_after, 0); } uint32_t ReadLF(bool activeField, bool silent, int sample_size) { diff --git a/client/cmdlf.c b/client/cmdlf.c index 8f540310f..08f93608b 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -441,7 +441,7 @@ int CmdLFSetConfig(const char *Cmd) { cmdp += 2; break; case 's': - samples_to_skip = param_get32ex(Cmd,cmdp+1,0,10); + samples_to_skip = param_get32ex(Cmd, cmdp + 1, 0, 10); cmdp+=2; break; default: @@ -457,7 +457,7 @@ int CmdLFSetConfig(const char *Cmd) { //Bps is limited to 8 if (bps >> 4) bps = 8; - sample_config config = { decimation, bps, averaging, divisor, trigger_threshold,samples_to_skip }; + sample_config config = { decimation, bps, averaging, divisor, trigger_threshold, samples_to_skip }; clearCommandBuffer(); SendCommandNG(CMD_LF_SAMPLING_SET_CONFIG, (uint8_t *)&config, sizeof(sample_config)); From 102d8221025dd9e9e7efc0793983e1be125bafa5 Mon Sep 17 00:00:00 2001 From: mwalker33 Date: Mon, 30 Sep 2019 21:06:22 +1000 Subject: [PATCH 0808/1854] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 78a0d48d2..563873a8c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -357,7 +357,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Fix T55xx config getting displayed when using password when no password needed on read. (@mwalker33) - Fix `em 4x05_dump` to print all blocks read (@mwalker33) - Added save to .eml and .bin for `em 4x05_dump` (@mwalker33) - - Added `s` to `lf config` / `lf sniff` to skip samples when sniffing (@mwalker33) + - Added `s` to `lf config` / `lf sniff` to skip samples when sniffing based on same option in Proxmark/proxmark3 by @marshmellow42. (@mwalker33) ### Fixed - Changed driver file proxmark3.inf to support both old and new Product/Vendor IDs (@pwpiwi) From 97600ee65649fdacdca6e072e7d496bd169979d6 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 30 Sep 2019 13:38:50 +0200 Subject: [PATCH 0809/1854] iir available --- client/cmddata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmddata.c b/client/cmddata.c index 23043cd98..e55b34909 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -2243,7 +2243,7 @@ static command_t CommandTable[] = { {"tune", CmdTuneSamples, IfPm3Present, "Get hw tune samples for graph window"}, {"undec", CmdUndec, AlwaysAvailable, "Un-decimate samples by 2"}, {"zerocrossings", CmdZerocrossings, AlwaysAvailable, "Count time between zero-crossings"}, - {"iir", CmdDataIIR, IfPm3Present, "apply IIR buttersworth filter on plotdata"}, + {"iir", CmdDataIIR, AlwaysAvailable, "apply IIR buttersworth filter on plotdata"}, {NULL, NULL, NULL, NULL} }; From 6a83a7dc1af1da722d314e8901e8eda0296def8e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 30 Sep 2019 19:28:50 +0200 Subject: [PATCH 0810/1854] fix 'lf cmdread' - correct report back on failure --- armsrc/lfops.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/armsrc/lfops.c b/armsrc/lfops.c index e8fb49698..4d3d568f4 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -290,10 +290,12 @@ void setT55xxConfig(uint8_t arg0, t55xx_configurations_t *c) { #ifdef WITH_FLASH // shall persist to flashmem if (arg0 == 0) { + BigBuf_free(); return; } if (!FlashInit()) { + BigBuf_free(); return; } @@ -390,7 +392,7 @@ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint WaitMS(200); // if delay_off = 0 then just bitbang 1 = antenna on 0 = off for respective periods. - bool bitbang = delay_off == 0; + bool bitbang = (delay_off == 0); // now modulate the reader field if (bitbang) { // HACK it appears the loop and if statements take up about 7us so adjust waits accordingly... @@ -399,6 +401,7 @@ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint DbpString("[!] Warning periods cannot be less than 7us in bit bang mode"); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LED_D_OFF(); + reply_ng(CMD_LF_MOD_THEN_ACQ_RAW_ADC, PM3_EINVARG, NULL, 0); return; } From aeab10d67f87dfa1a703313759d9f86cde220466 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 30 Sep 2019 19:39:34 +0200 Subject: [PATCH 0811/1854] fix 'lf cmdread' - better messaging --- client/cmdlf.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/client/cmdlf.c b/client/cmdlf.c index 08f93608b..954973f2c 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -297,21 +297,29 @@ int CmdLFCommandRead(const char *Cmd) { SendCommandNG(CMD_LF_MOD_THEN_ACQ_RAW_ADC, (uint8_t *)&payload, 8 + datalen); printf("\n"); + + PacketResponseNG resp; + uint8_t i = 10; - while (!WaitForResponseTimeout(CMD_LF_MOD_THEN_ACQ_RAW_ADC, NULL, 2000) && i != 0) { + while (!WaitForResponseTimeout(CMD_LF_MOD_THEN_ACQ_RAW_ADC, &resp, 2000) && i != 0) { printf("."); fflush(stdout); i--; } printf("\n"); - if (i) { - PrintAndLogEx(SUCCESS, "Downloading response signal data"); - getSamples(0, true); - return PM3_SUCCESS; + if (resp.status == PM3_SUCCESS) { + if (i) { + PrintAndLogEx(SUCCESS, "Downloading response signal data"); + getSamples(0, true); + return PM3_SUCCESS; + } else { + PrintAndLogEx(WARNING, "timeout while waiting for reply."); + return PM3_ETIMEOUT; + } } - PrintAndLogEx(WARNING, "timeout while waiting for reply."); - return PM3_ETIMEOUT; + PrintAndLogEx(WARNING, "Command failed."); + return PM3_ESOFT; } int CmdFlexdemod(const char *Cmd) { From fd88d7448ec78dd4f1645ab93bafc5fde120588c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 30 Sep 2019 19:47:36 +0200 Subject: [PATCH 0812/1854] fix 'lf t55xx resetread' - NG and better fault handling --- armsrc/lfops.c | 5 ++--- client/cmdlft55xx.c | 23 +++++++++++++++++------ 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 4d3d568f4..e2e8daadf 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -1694,9 +1694,8 @@ void T55xxResetRead(uint8_t flags) { DoPartialAcquisition(0, true, BigBuf_max_traceLen(), 0); // Turn the field off - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off - reply_mix(CMD_ACK, 0, 0, 0, 0, 0); - + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + reply_ng(CMD_LF_T55XX_RESET_READ, PM3_SUCCESS, NULL, 0); LED_A_OFF(); } diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 8cc8142a7..922602f9b 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -2426,19 +2426,30 @@ static int CmdResetRead(const char *Cmd) { flags = downlink_mode << 3; + PacketResponseNG resp; + clearCommandBuffer(); SendCommandNG(CMD_LF_T55XX_RESET_READ, &flags, sizeof(flags)); - if (!WaitForResponseTimeout(CMD_ACK, NULL, 2500)) { + if (!WaitForResponseTimeout(CMD_LF_T55XX_RESET_READ, &resp, 2500)) { PrintAndLogEx(WARNING, "command execution time out"); return PM3_ETIMEOUT; } - uint8_t got[BIGBUF_SIZE - 1]; - if (!GetFromDevice(BIG_BUF, got, sizeof(got), 0, NULL, 0, NULL, 2500, false)) { - PrintAndLogEx(WARNING, "command execution time out"); - return PM3_ETIMEOUT; + if (resp.status == PM3_SUCCESS) { + + uint8_t *got = calloc(BIGBUF_SIZE - 1, sizeof(uint8_t)); + if (got == NULL) { + PrintAndLogEx(WARNING, "failed to allocate memory"); + return PM3_EMALLOC; + } + + if (!GetFromDevice(BIG_BUF, got, sizeof(got), 0, NULL, 0, NULL, 2500, false)) { + PrintAndLogEx(WARNING, "command execution time out"); + return PM3_ETIMEOUT; + } + setGraphBuf(got, sizeof(got)); + free(got); } - setGraphBuf(got, sizeof(got)); return PM3_SUCCESS; } From d40341d962839d56f063affb65f2756f143b502e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 30 Sep 2019 23:17:19 +0200 Subject: [PATCH 0813/1854] Add 'data scale h' - helptext --- client/cmddata.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/client/cmddata.c b/client/cmddata.c index e55b34909..bbb4a460c 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -32,6 +32,20 @@ int g_DemodClock = 0; static int CmdHelp(const char *Cmd); +static int usage_data_scale(void) { + PrintAndLogEx(NORMAL, "Set cursor display scale."); + PrintAndLogEx(NORMAL, "Setting the scale makes the differential `dt` reading between the yellow and purple markers meaningful. "); + PrintAndLogEx(NORMAL, "once the scale is set, the differential reading between brackets is the time duration in seconds."); + PrintAndLogEx(NORMAL, "For example, if acquiring in 125kHz, use scale 125."); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Usage: data scale [h] "); + PrintAndLogEx(NORMAL, "Options:"); + PrintAndLogEx(NORMAL, " h This help"); + PrintAndLogEx(NORMAL, " Sets scale of carrier frequency expressed in kHz"); + PrintAndLogEx(NORMAL, "Samples:"); + PrintAndLogEx(NORMAL, " data scale 125 - if sampled in 125kHz"); + return PM3_SUCCESS; +} static int usage_data_printdemodbuf(void) { PrintAndLogEx(NORMAL, "Usage: data printdemodbuffer x o l "); PrintAndLogEx(NORMAL, "Options:"); @@ -1865,6 +1879,9 @@ static int CmdSave(const char *Cmd) { } static int CmdScale(const char *Cmd) { + char cmdp = tolower(param_getchar(Cmd, 0)); + if (strlen(Cmd) == 0 || cmdp == 'h') return usage_data_scale(); + CursorScaleFactor = atoi(Cmd); if (CursorScaleFactor == 0) { PrintAndLogEx(FAILED, "bad, can't have zero scale"); @@ -2236,7 +2253,7 @@ static command_t CommandTable[] = { {"samples", CmdSamples, IfPm3Present, "[512 - 40000] -- Get raw samples for graph window (GraphBuffer)"}, {"save", CmdSave, AlwaysAvailable, " -- Save trace (from graph window)"}, {"setgraphmarkers", CmdSetGraphMarkers, AlwaysAvailable, "[orange_marker] [blue_marker] (in graph window)"}, - {"scale", CmdScale, AlwaysAvailable, " -- Set cursor display scale"}, + {"scale", CmdScale, AlwaysAvailable, " -- Set cursor display scale in carrier frequency expressed in kHz"}, {"setdebugmode", CmdSetDebugMode, AlwaysAvailable, "<0|1|2> -- Set Debugging Level on client side"}, {"shiftgraphzero", CmdGraphShiftZero, AlwaysAvailable, " -- Shift 0 for Graphed wave + or - shift value"}, {"dirthreshold", CmdDirectionalThreshold, AlwaysAvailable, " -- Max rising higher up-thres/ Min falling lower down-thres, keep rest as prev."}, From f142ad139b12a3827b9bb92b21c4d750dafffc9d Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 30 Sep 2019 23:18:48 +0200 Subject: [PATCH 0814/1854] chg 'lf cmdread' - clientside checks, less wait times on device --- armsrc/lfops.c | 14 +++++++++----- client/cmdlf.c | 8 ++++++++ 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/armsrc/lfops.c b/armsrc/lfops.c index e2e8daadf..92c369b76 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -372,16 +372,19 @@ void loadT55xxConfig(void) { */ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint32_t period_1, uint8_t *command) { - // start timer - StartTicks(); + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); // use lf config settings sample_config *sc = getSamplingConfig(); + // Make sure the tag is reset - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - WaitMS(500); + + // start timer + StartTicks(); + + WaitMS(100); // clear read buffer BigBuf_Clear_keep_EM(); @@ -389,7 +392,7 @@ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint LFSetupFPGAForADC(sc->divisor, true); // little more time for the tag to fully power up - WaitMS(200); + WaitMS(20); // if delay_off = 0 then just bitbang 1 = antenna on 0 = off for respective periods. bool bitbang = (delay_off == 0); @@ -463,6 +466,7 @@ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint // Turn off antenna FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + // tell client we are done reply_ng(CMD_LF_MOD_THEN_ACQ_RAW_ADC, PM3_SUCCESS, NULL, 0); } diff --git a/client/cmdlf.c b/client/cmdlf.c index 954973f2c..ea7aada4f 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -289,6 +289,14 @@ int CmdLFCommandRead(const char *Cmd) { } } + // bitbang mode + if (payload.delay == 0){ + if (payload.zeros < 7 || payload.ones < 7) { + PrintAndLogEx(WARNING, "Warning periods cannot be less than 7us in bit bang mode"); + return PM3_EINVARG; + } + } + //Validations if (errors || cmdp == 0) return usage_lf_cmdread(); From e978b180b4c2f83ef355360a9f457317bc3399b5 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 30 Sep 2019 18:30:10 +0200 Subject: [PATCH 0815/1854] Better device detection in pm3 script, add -n option --- CHANGELOG.md | 1 + pm3 | 154 +++++++++++++++++++++++++++++---------------------- 2 files changed, 90 insertions(+), 65 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 563873a8c..a01ccab19 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Add option `-n` to scripts pm3* (@doegox) - Add `wiegand list/encode/decode` - wiegand format manipulation. Adapted to fit here. (@grauerfuchs) - Add `lf t55xx protect` - sets password and enables password protection on t55x7 tag (@iceman1001) - Chg `lf t55xx wipe` - now accepts user provided configuration block (@iceman1001) diff --git a/pm3 b/pm3 index 347e8bb3e..c3bed278e 100755 --- a/pm3 +++ b/pm3 @@ -16,66 +16,46 @@ else CLIENT="proxmark3" fi -function wait4proxmark_Linux { - echo >&2 "[=] Waiting for Proxmark3 to appear..." - while true; do - PM3=$(find /dev/pm3-* /dev/ttyACM* 2>/dev/null | head -1) - if [[ $PM3 != "" ]]; then - break +PM3LIST=() + +function get_pm3_list_Linux { + PM3LIST=() + for DEV in $(find /dev/ttyACM* 2>/dev/null); do + if udevadm info -q property -n "$DEV" |grep -q "ID_MODEL=proxmark3"; then + PM3LIST+=("$DEV") fi - sleep .1 done - echo "$PM3" } -function wait4proxmark_macOS { - echo >&2 "[=] Waiting for Proxmark3 to appear..." - while true; do - PM3=$(find /dev/pm3-* /dev/tty.usbmodem* 2>/dev/null | head -1) - if [[ $PM3 != "" ]]; then - break - fi - sleep .1 +function get_pm3_list_macOS { + PM3LIST=() + for DEV in $(ioreg -r -n proxmark3 -l|awk -F '"' '/IODialinDevice/{print $4}'); do + PM3LIST+=("$DEV") done - echo "$PM3" } -function wait4proxmark_Windows { - echo >&2 "[=] Waiting for Proxmark3 to appear..." - while true; do - device=$(wmic path Win32_SerialPort where "PNPDeviceID like '%VID_9AC4&PID_4B8F%'" get DeviceID,PNPDeviceID 2>/dev/null | awk 'NR==2') - if [[ $device != "" ]]; then - PM3=${device/ */} - break - fi - sleep .1 +function get_pm3_list_Windows { + PM3LIST=() + for DEV in $(wmic path Win32_SerialPort where "PNPDeviceID like '%VID_9AC4&PID_4B8F%'" get DeviceID,PNPDeviceID 2>/dev/null|awk '/^COM/{print $1}'); do + DEV=${DEV/ */} + PM3LIST+=("$DEV") done - echo "$PM3" } -function wait4proxmark_WSL { - # Test presence of wmic - wmic.exe computersystem get name >/dev/null 2>&1 - if [ $? -ne 0 ]; then - echo "[!] Cannot run wmic.exe, are you sure your WSL is authorized to run Windows processes? (cf WSL interop flag)" - exit 1 - fi - - echo >&2 "[=] Waiting for Proxmark3 to appear..." - while true; do - device=$(wmic.exe path Win32_SerialPort where "PNPDeviceID like '%VID_9AC4&PID_4B8F%'" get DeviceID,PNPDeviceID 2>/dev/null | awk 'NR==2') - if [[ $device != "" ]]; then - PM3=${device/ */} - PM3="/dev/ttyS${PM3#COM}" - break +function get_pm3_list_WSL { + PM3LIST=() + for DEV in $(wmic.exe path Win32_SerialPort where "PNPDeviceID like '%VID_9AC4&PID_4B8F%'" get DeviceID,PNPDeviceID 2>/dev/null|awk '/^COM/{print $1}'); do + DEV=${DEV/ */} + DEV="/dev/ttyS${DEV#COM}" + # ttyS counterpart takes some more time to appear + if [ -e "$DEV" ]; then + PM3LIST+=("$DEV") + if [ ! -w "$DEV" ]; then + echo "[!!] Let's give users read/write access to $DEV" + sudo chmod 666 "$DEV" + fi fi - sleep .1 done - if [ -e "$PM3" ] && [ ! -w "$PM3" ]; then - echo "[!!] We need to give current user read/write access to $PM3" - sudo chmod 666 "$PM3" - fi - echo "$PM3" } SCRIPT=$(basename -- "$0") @@ -84,23 +64,24 @@ if [ "$SCRIPT" = "pm3" ]; then CMD() { $CLIENT "$@"; } HELP() { cat << EOF -Quick helper script for proxmark3 client when working with a Proxmark device connected via USB +Quick helper script for proxmark3 client when working with a Proxmark3 device connected via USB Description: The usage is the same as for the proxmark3 client, with the following differences: * 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). + You can also specify a first option -n N to access the Nth Proxmark3 connected on USB. Don't use this script if you want to work offline or with the BT addon. Usage: - $SCRIPT [-f] [-c ]|[-l ]|[-s ] [-i] + $SCRIPT [-n ] [-f] [-c ]|[-l ]|[-s ] [-i] See "$CLIENT -h" for more details on options. EOF } elif [ "$SCRIPT" = "pm3-flash" ]; then CMD() { - ARGS=("$1" "--flash") + ARGS=("--port" "$1" "--flash") shift; while [ "$1" != "" ]; do if [ "$1" == "-b" ]; then @@ -118,10 +99,11 @@ Quick helper script for flashing a Proxmark device via USB Description: The usage is similar to the old proxmark3-flasher binary, except that the correct port name will be automatically guessed. + You can also specify a first option -n N to access the Nth Proxmark3 connected on USB. If this doesn't work, you'll have to use manually the proxmark3 client, see "$CLIENT -h". Usage: - $SCRIPT [-b] image.elf [image.elf...] + $SCRIPT [-n ] [-b] image.elf [image.elf...] Options: -b Enable flashing of bootloader area (DANGEROUS) @@ -131,45 +113,48 @@ Example: EOF } elif [ "$SCRIPT" = "pm3-flash-all" ]; then - CMD() { $CLIENT "$1" "--flash" "--unlock-bootloader" "--image" "$BOOTIMAGE" "--image" "$FULLIMAGE"; } + CMD() { $CLIENT "--port" "$1" "--flash" "--unlock-bootloader" "--image" "$BOOTIMAGE" "--image" "$FULLIMAGE"; } HELP() { cat << EOF Quick helper script for flashing a Proxmark device via USB Description: The correct port name will be automatically guessed and the stock bootloader and firmware image will be flashed. + You can also specify a first option -n N to access the Nth Proxmark3 connected on USB. If this doesn't work, you'll have to use manually the proxmark3 client, see "$CLIENT -h". Usage: - $SCRIPT + $SCRIPT [-n ] EOF } elif [ "$SCRIPT" = "pm3-flash-fullimage" ]; then - CMD() { $CLIENT "$1" "--flash" "--image" "$FULLIMAGE"; } + CMD() { $CLIENT "--port" "$1" "--flash" "--image" "$FULLIMAGE"; } HELP() { cat << EOF Quick helper script for flashing a Proxmark device via USB Description: The correct port name will be automatically guessed and the stock firmware image will be flashed. + You can also specify a first option -n N to access the Nth Proxmark3 connected on USB. If this doesn't work, you'll have to use manually the proxmark3 client, see "$CLIENT -h". Usage: - $SCRIPT + $SCRIPT [-n ] EOF } elif [ "$SCRIPT" = "pm3-flash-bootrom" ]; then - CMD() { $CLIENT "$1" "--flash" "--unlock-bootloader" "--image" "$BOOTIMAGE"; } + CMD() { $CLIENT "--port" "$1" "--flash" "--unlock-bootloader" "--image" "$BOOTIMAGE"; } HELP() { cat << EOF Quick helper script for flashing a Proxmark device via USB Description: The correct port name will be automatically guessed and the stock bootloader will be flashed. + You can also specify a first option -n N to access the Nth Proxmark3 connected on USB. If this doesn't work, you'll have to use manually the proxmark3 client, see "$CLIENT -h". Usage: - $SCRIPT + $SCRIPT [-n ] EOF } else @@ -180,25 +165,64 @@ if [ "$1" == "-h" ] || [ "$1" == "--help" ]; then HELP exit 0 fi + +# if a port is already provided, let's just run the command as such +for ARG in "$@"; do + if [ "$ARG" == "-p" ]; then + CMD "$@" + exit $? + fi +done + +# Number of the proxmark3 we're interested in +N=1 +if [ "$1" == "-n" ]; then + shift + if [ "$1" -ge 1 ] && [ "$1" -lt 10 ]; then + N=$1 + shift + else + echo "Option -n requires a number between 1 and 9, got \"$1\"" + exit 1 + fi +fi + +echo >&2 "[=] Waiting for Proxmark3 to appear..." HOSTOS=$(uname | awk '{print toupper($0)}') if [ "$HOSTOS" = "LINUX" ]; then if uname -a|grep -q Microsoft; then - PORT=$(wait4proxmark_WSL) + # Test presence of wmic + wmic.exe computersystem get name >/dev/null 2>&1 + if [ $? -ne 0 ]; then + echo "[!] Cannot run wmic.exe, are you sure your WSL is authorized to run Windows processes? (cf WSL interop flag)" + exit 1 + fi + GETPM3LIST=get_pm3_list_WSL else - PORT=$(wait4proxmark_Linux) + GETPM3LIST=get_pm3_list_Linux fi elif [ "$HOSTOS" = "DARWIN" ]; then - PORT=$(wait4proxmark_macOS) + GETPM3LIST=get_pm3_list_macOS elif [[ "$HOSTOS" =~ MINGW(32|64)_NT* ]]; then - PORT=$(wait4proxmark_Windows) + GETPM3LIST=get_pm3_list_Windows else echo "[!!] Host OS not recognized, abort: $HOSTOS" exit 1 fi -if [ "$PORT" = "" ]; then - echo "[!!] No port, abort" + +# Wait till we get at least N proxmark3 devices +while true; do + $GETPM3LIST $N + if [ ${#PM3LIST[*]} -ge $N ]; then + break + fi + sleep .1 +done + +if [ ${#PM3LIST} -lt $N ]; then + echo "[!!] No port found, abort" exit 1 fi -CMD "$PORT" "$@" +CMD "${PM3LIST[$((N-1))]}" "$@" exit $? From 2439f9d33c01a53d22be21509a644fe42fbca265 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 1 Oct 2019 14:29:37 +0200 Subject: [PATCH 0816/1854] new files --- client/cmdlfverichip.c | 170 +++++++++++++++++++++++++++++++++++++++++ client/cmdlfverichip.h | 19 +++++ 2 files changed, 189 insertions(+) create mode 100644 client/cmdlfverichip.c create mode 100644 client/cmdlfverichip.h diff --git a/client/cmdlfverichip.c b/client/cmdlfverichip.c new file mode 100644 index 000000000..6bb8845a5 --- /dev/null +++ b/client/cmdlfverichip.c @@ -0,0 +1,170 @@ +//----------------------------------------------------------------------------- +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// Low frequency Verichip tag commands +//NRZ, RF/32, 128 bits long +//----------------------------------------------------------------------------- +#include "cmdlfverichip.h" + +#include //tolower + +#include "commonutil.h" // ARRAYLEN +#include "common.h" +#include "cmdparser.h" // command_t +#include "comms.h" +#include "ui.h" +#include "cmddata.h" +#include "cmdlf.h" +#include "lfdemod.h" // preamble test +#include "protocols.h" // t55xx defines +#include "cmdlft55xx.h" // clone.. + +static int CmdHelp(const char *Cmd); + +static int usage_lf_verichip_clone(void) { + PrintAndLogEx(NORMAL, "clone a verichip tag to a T55x7 tag."); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Usage: lf verichip clone [h] [b ]"); + PrintAndLogEx(NORMAL, "Options:"); + PrintAndLogEx(NORMAL, " h : this help"); + PrintAndLogEx(NORMAL, " b : raw hex data. 12 bytes max"); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Examples:"); + PrintAndLogEx(NORMAL, " lf verichip clone b FF2049906D8511C593155B56D5B2649F "); + return PM3_SUCCESS; +} + +//see NRZDemod for what args are accepted +static int CmdVerichipDemod(const char *Cmd) { + + //NRZ + if (NRZrawDemod(Cmd, false) != PM3_SUCCESS) { + PrintAndLogEx(DEBUG, "DEBUG: Error - VERICHIP: NRZ Demod failed"); + return PM3_ESOFT; + } + size_t size = DemodBufferLen; + int ans = detectVerichip(DemodBuffer, &size); + if (ans < 0) { + if (ans == -1) + PrintAndLogEx(DEBUG, "DEBUG: Error - VERICHIP: too few bits found"); + else if (ans == -2) + PrintAndLogEx(DEBUG, "DEBUG: Error - VERICHIP: preamble not found"); + else if (ans == -3) + PrintAndLogEx(DEBUG, "DEBUG: Error - VERICHIP: Size not correct: %d", size); + else + PrintAndLogEx(DEBUG, "DEBUG: Error - VERICHIP: ans: %d", ans); + + return PM3_ESOFT; + } + setDemodBuff(DemodBuffer, 128, ans); + setClockGrid(g_DemodClock, g_DemodStartIdx + (ans * g_DemodClock)); + + //got a good demod + uint32_t raw1 = bytebits_to_byte(DemodBuffer, 32); + uint32_t raw2 = bytebits_to_byte(DemodBuffer + 32, 32); + uint32_t raw3 = bytebits_to_byte(DemodBuffer + 64, 32); + uint32_t raw4 = bytebits_to_byte(DemodBuffer + 96, 32); + + // preamble then appears to have marker bits of "10" CS? + // 11111111001000000 10 01001100 10 00001101 10 00001101 10 00001101 10 00001101 10 00001101 10 00001101 10 00001101 10 00001101 10 10001100 10 100000001 + // unknown checksum 9 bits at the end + + PrintAndLogEx(SUCCESS, "VERICHIP Tag Found -- Raw: %08X%08X%08X%08X", raw1, raw2, raw3, raw4); + PrintAndLogEx(INFO, "How the Raw ID is translated by the reader is unknown. Share your trace file on forum"); + return PM3_SUCCESS; +} + +static int CmdVerichipRead(const char *Cmd) { + lf_read(true, 4096 * 2 + 20); + return CmdVerichipDemod(Cmd); +} + +static int CmdVerichipClone(const char *Cmd) { + + uint32_t blocks[5]; + bool errors = false; + uint8_t cmdp = 0; + int datalen = 0; + + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { + case 'h': + return usage_lf_verichip_clone(); + case 'b': { + // skip first block, 4*4 = 16 bytes left + uint8_t rawhex[16] = {0}; + int res = param_gethex_to_eol(Cmd, cmdp + 1, rawhex, sizeof(rawhex), &datalen); + if ( res != 0 ) + errors = true; + + for(uint8_t i = 1; i < ARRAYLEN(blocks); i++) { + blocks[i] = bytes_to_num(rawhex + ( (i - 1) * 4 ), sizeof(uint32_t)); + } + cmdp += 2; + break; + } + default: + PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } + } + + if (errors || cmdp == 0) return usage_lf_verichip_clone(); + + //Pac - compat mode, NRZ, data rate 40, 3 data blocks + blocks[0] = T55x7_MODULATION_DIRECT | T55x7_BITRATE_RF_40 | 4 << T55x7_MAXBLOCK_SHIFT; + + PrintAndLogEx(INFO, "Preparing to clone Verichip to T55x7 with raw hex"); + print_blocks(blocks, ARRAYLEN(blocks)); + + return clone_t55xx_tag(blocks, ARRAYLEN(blocks)); +} + +static int CmdVerichipSim(const char *Cmd) { + + // NRZ sim. + PrintAndLogEx(INFO, " To be implemented, feel free to contribute!"); + return PM3_SUCCESS; +} + +static command_t CommandTable[] = { + {"help", CmdHelp, AlwaysAvailable, "This help"}, + {"demod", CmdVerichipDemod, AlwaysAvailable, "Demodulate an VERICHIP tag from the GraphBuffer"}, + {"read", CmdVerichipRead, IfPm3Lf, "Attempt to read and extract tag data from the antenna"}, + {"clone", CmdVerichipClone, IfPm3Lf, "clone VERICHIP tag"}, + {"sim", CmdVerichipSim, IfPm3Lf, "simulate VERICHIP tag"}, + {NULL, NULL, NULL, NULL} +}; + +static int CmdHelp(const char *Cmd) { + (void)Cmd; // Cmd is not used so far + CmdsHelp(CommandTable); + return PM3_SUCCESS; +} + +int CmdLFVerichip(const char *Cmd) { + clearCommandBuffer(); + return CmdsParse(CommandTable, Cmd); +} + +// by marshmellow +// find PAC preamble in already demoded data +int detectVerichip(uint8_t *dest, size_t *size) { + if (*size < 128) return -1; //make sure buffer has data + size_t startIdx = 0; + uint8_t preamble[] = {1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0}; + if (!preambleSearch(dest, preamble, sizeof(preamble), size, &startIdx)) + return -2; //preamble not found + if (*size != 128) return -3; //wrong demoded size + //return start position + return (int)startIdx; +} + +int demodVerichip(void) { + return CmdVerichipDemod(""); +} + diff --git a/client/cmdlfverichip.h b/client/cmdlfverichip.h new file mode 100644 index 000000000..4ddf6a5d1 --- /dev/null +++ b/client/cmdlfverichip.h @@ -0,0 +1,19 @@ +//----------------------------------------------------------------------------- +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// Low frequency Verichip tag commands +//----------------------------------------------------------------------------- +#ifndef CMDLFVERICHIP_H__ +#define CMDLFVERICHIP_H__ + +#include "common.h" + +int CmdLFVerichip(const char *Cmd); + +int demodVerichip(void); +int detectVerichip(uint8_t *dest, size_t *size); +#endif + From af56fa8242c2b6965261486cf07b29d7515fd39c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 1 Oct 2019 14:30:30 +0200 Subject: [PATCH 0817/1854] started to extract VeriChip demod/clone --- client/Makefile | 1 + client/cmdlf.c | 20 ++++++++++++++++---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/client/Makefile b/client/Makefile index dcbb23110..0f059980a 100644 --- a/client/Makefile +++ b/client/Makefile @@ -225,6 +225,7 @@ CMDSRCS = crapto1/crapto1.c \ cmdlfti.c \ cmdlfviking.c \ cmdlfvisa2000.c \ + cmdlfverichip.c \ cmdtrace.c \ cmdflashmem.c \ cmdflashmemspiffs.c \ diff --git a/client/cmdlf.c b/client/cmdlf.c index ea7aada4f..83d04e7c7 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -47,6 +47,7 @@ #include "cmdlfsecurakey.h" // for securakey menu #include "cmdlfpac.h" // for pac menu #include "cmdlfkeri.h" // for keri menu +#include "cmdlfverichip.h" // for VeriChip menu bool g_lf_threshold_set = false; @@ -977,12 +978,21 @@ int CmdLFSimBidir(const char *Cmd) { // Set ADC to twice the carrier for a slight supersampling // HACK: not implemented in ARMSRC. PrintAndLogEx(INFO, "Not implemented yet."); - SendCommandMIX(CMD_LF_SIMULATE_BIDIR, 47, 384, 0, NULL, 0); +// SendCommandMIX(CMD_LF_SIMULATE_BIDIR, 47, 384, 0, NULL, 0); return PM3_SUCCESS; } // ICEMAN, todo, swap from Graphbuffer. +// according to Westhus this demod uses decimated samples / 2. +// need to do complete rewrite. Need access to reader / chip +// should be extracted to seperate files aswell int CmdVchDemod(const char *Cmd) { + + if (GraphTraceLen < 4096) { + PrintAndLogEx(DEBUG, "debug; VchDemod - too few samples"); + return PM3_EINVARG; + } + // Is this the entire sync pattern, or does this also include some // data bits that happen to be the same everywhere? That would be // lovely to know. @@ -1154,9 +1164,10 @@ int CmdLFfind(const char *Cmd) { if (demodSecurakey() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Securakey ID") "found!"); goto out;} if (demodViking() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Viking ID") "found!"); goto out;} if (demodVisa2k() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Visa2000 ID") "found!"); goto out;} - if (demodTI() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Texas Instrument ID") "found!"); goto out;} +// if (demodTI() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Texas Instrument ID") "found!"); goto out;} +// if (demodVerichip() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("VeriChip ID") "found!"); goto out;} //if (demodFermax() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Fermax ID") "found!"); goto out;} - //if (demodFlex() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Flex ID") "found!"); goto out;} + //if (demodFlex() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Motorola FlexPass ID") "found!"); goto out;} PrintAndLogEx(FAILED, _RED_("No known 125/134 kHz tags found!")); @@ -1229,6 +1240,7 @@ static command_t CommandTable[] = { {"securakey", CmdLFSecurakey, AlwaysAvailable, "{ Securakey RFIDs... }"}, {"ti", CmdLFTI, AlwaysAvailable, "{ TI CHIPs... }"}, {"t55xx", CmdLFT55XX, AlwaysAvailable, "{ T55xx CHIPs... }"}, +// {"verichip", CmdLFVerichip, AlwaysAvailable, "{ VeriChip RFIDs... }"}, {"viking", CmdLFViking, AlwaysAvailable, "{ Viking RFIDs... }"}, {"visa2000", CmdLFVisa2k, AlwaysAvailable, "{ Visa2000 RFIDs... }"}, {"config", CmdLFSetConfig, IfPm3Lf, "Set config for LF sampling, bit/sample, decimation, frequency"}, @@ -1243,7 +1255,7 @@ static command_t CommandTable[] = { {"simbidir", CmdLFSimBidir, IfPm3Lf, "Simulate LF tag (with bidirectional data transmission between reader and tag)"}, {"sniff", CmdLFSniff, IfPm3Lf, "Sniff LF traffic between reader and tag"}, {"tune", CmdLFTune, IfPm3Lf, "Continuously measure LF antenna tuning"}, - {"vchdemod", CmdVchDemod, AlwaysAvailable, "['clone'] -- Demodulate samples for VeriChip"}, +// {"vchdemod", CmdVchDemod, AlwaysAvailable, "['clone'] -- Demodulate samples for VeriChip"}, {NULL, NULL, NULL, NULL} }; From 5def918e02719f72777d1ac15feda3897bbb8074 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 1 Oct 2019 15:03:39 +0200 Subject: [PATCH 0818/1854] textual --- client/cmddata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmddata.c b/client/cmddata.c index bbb4a460c..16d9d10de 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -868,7 +868,7 @@ int AutoCorrelate(const int *in, int *out, size_t len, size_t window, bool SaveG if (verbose && foo < bar) { distance = idx_1 - idx; - PrintAndLogEx(SUCCESS, "possible 4% visible correlation %4d samples", distance); + PrintAndLogEx(SUCCESS, "possible visible correlation %4d samples", distance); } else if (verbose && (correlation > 1)) { PrintAndLogEx(SUCCESS, "possible correlation %4d samples", correlation); } else { From eccf0d3bbc112d7133ea906f2b323fde3eec788b Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 1 Oct 2019 23:00:51 +0200 Subject: [PATCH 0819/1854] Avoid client CPU busy loop when waiting pm3 (e.g. when simulating tag) --- client/comms.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/comms.c b/client/comms.c index 8d2c8f733..f3dbf09ce 100644 --- a/client/comms.c +++ b/client/comms.c @@ -733,6 +733,8 @@ bool WaitForResponseTimeoutW(uint32_t cmd, PacketResponseNG *response, size_t ms PrintAndLogEx(INFO, "You can cancel this operation by pressing the pm3 button"); show_warning = false; } + // just to avoid CPU busy loop: + msleep(10); } return false; } From 5d3eb444fbd608a53b5e1bc3796471a6d5ac039c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 3 Oct 2019 16:15:47 +0200 Subject: [PATCH 0820/1854] chg 'hf mf nested' - uses NG. chg 'hw tune' - now also prints the 'lf config q' divisor voltage. --- armsrc/appmain.c | 75 ++++++++++++++++++++++++-------------- armsrc/lfsampling.c | 6 +-- armsrc/mifarecmd.c | 49 +++++++++++++++---------- armsrc/mifarecmd.h | 4 +- client/cmddata.c | 61 ++++++++++++++++++++----------- client/cmdhfmf.c | 12 +++--- client/cmdlf.c | 3 +- client/mifare/mifarehost.c | 54 ++++++++++++++++++++++----- 8 files changed, 175 insertions(+), 89 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index b778fa785..b67788bc5 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -143,11 +143,25 @@ uint16_t AvgAdc(int ch) { void MeasureAntennaTuning(void) { - uint8_t LF_Results[256]; - uint32_t i, peak = 0, peakv = 0, peakf = 0; - uint32_t v_lf125 = 0, v_lf134 = 0, v_hf = 0; // in mV + uint32_t peak = 0; + + // in mVolt + struct p { + uint32_t v_lf134; + uint32_t v_lf125; + uint32_t v_lfconf; + uint32_t v_hf; + uint32_t peak_v; + uint32_t peak_f; + int divisor; + uint8_t results[256]; + } PACKED payload; + + memset(payload.results, 0, sizeof(payload.results)); + + sample_config *sc = getSamplingConfig(); + payload.divisor = sc->divisor; - memset(LF_Results, 0, sizeof(LF_Results)); LED_B_ON(); /* @@ -163,21 +177,26 @@ void MeasureAntennaTuning(void) { FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); SpinDelay(50); - for (i = 255; i >= 19; i--) { + for (uint8_t i = 255; i >= 19; i--) { WDT_HIT(); FpgaSendCommand(FPGA_CMD_SET_DIVISOR, i); SpinDelay(20); uint32_t adcval = ((MAX_ADC_LF_VOLTAGE * AvgAdc(ADC_CHAN_LF)) >> 10); - if (i == 95) - v_lf125 = adcval; // voltage at 125kHz - if (i == 89) - v_lf134 = adcval; // voltage at 134kHz + if (i == 96) + payload.v_lf125 = adcval; // voltage at 125kHz - LF_Results[i] = adcval >> 9; // scale int to fit in byte for graphing purposes - if (LF_Results[i] > peak) { - peakv = adcval; - peakf = i; - peak = LF_Results[i]; + if (i == 89) + payload.v_lf134 = adcval; // voltage at 134kHz + + if (i == sc->divisor) + payload.v_lfconf = adcval; // voltage at `lf config q` + + payload.results[i] = adcval >> 9; // scale int to fit in byte for graphing purposes + + if (payload.results[i] > peak) { + payload.peak_v = adcval; + payload.peak_f = i; + peak = payload.results[i]; } } @@ -186,23 +205,16 @@ void MeasureAntennaTuning(void) { FpgaDownloadAndGo(FPGA_BITSTREAM_HF); FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR); SpinDelay(50); - v_hf = (MAX_ADC_HF_VOLTAGE * AvgAdc(ADC_CHAN_HF)) >> 10; + + payload.v_hf = (MAX_ADC_HF_VOLTAGE * AvgAdc(ADC_CHAN_HF)) >> 10; // RDV40 will hit the roof, try other ADC channel used in that hardware revision. - if (v_hf > MAX_ADC_HF_VOLTAGE - 300) { - v_hf = (MAX_ADC_HF_VOLTAGE_RDV40 * AvgAdc(ADC_CHAN_HF_RDV40)) >> 10; + if (payload.v_hf > MAX_ADC_HF_VOLTAGE - 300) { + payload.v_hf = (MAX_ADC_HF_VOLTAGE_RDV40 * AvgAdc(ADC_CHAN_HF_RDV40)) >> 10; } - uint64_t arg0 = v_lf134; - arg0 <<= 32; - arg0 |= v_lf125; - - uint64_t arg2 = peakv; - arg2 <<= 32; - arg2 |= peakf; - - reply_mix(CMD_MEASURE_ANTENNA_TUNING, arg0, v_hf, arg2, LF_Results, 256); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + reply_ng(CMD_MEASURE_ANTENNA_TUNING, PM3_SUCCESS, (uint8_t*)&payload, sizeof(payload)); LEDsoff(); } @@ -1083,7 +1095,16 @@ static void PacketReceived(PacketCommandNG *packet) { break; } case CMD_HF_MIFARE_NESTED: { - MifareNested(packet->oldarg[0], packet->oldarg[1], packet->oldarg[2], packet->data.asBytes); + struct p { + uint8_t block; + uint8_t keytype; + uint8_t target_block; + uint8_t target_keytype; + bool calibrate; + uint8_t key[6]; + } PACKED; + struct p *payload = (struct p *) packet->data.asBytes; + MifareNested(payload->block, payload->keytype, payload->target_block, payload->target_keytype, payload->calibrate, payload->key); break; } case CMD_HF_MIFARE_CHKKEYS: { diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index f1cea2aea..e8664aa47 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -24,11 +24,11 @@ Default LF config is set to: divisor = 95 (125kHz) trigger_threshold = 0 */ -sample_config config = { 1, 8, 1, 95, 0, 0 } ; +sample_config config = { 1, 8, 1, 96, 0, 0 } ; void printConfig() { DbpString(_BLUE_("LF Sampling config")); - Dbprintf(" [q] divisor.............%d ( "_GREEN_("%d kHz")")", config.divisor, 12000 / (config.divisor + 1)); + Dbprintf(" [q] divisor.............%d ( "_GREEN_("%d kHz")")", config.divisor, 12000 / config.divisor); Dbprintf(" [b] bps.................%d", config.bits_per_sample); Dbprintf(" [d] decimation..........%d", config.decimation); Dbprintf(" [a] averaging...........%s", (config.averaging) ? "Yes" : "No"); @@ -151,7 +151,7 @@ uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averag uint16_t checker = 0; while (true) { - if (checker == 1000) { + if (checker == 2000) { if (BUTTON_PRESS() || data_available()) break; else diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 4a469e6e1..d3f00c2ec 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -866,26 +866,20 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, // MIFARE nested authentication. // //----------------------------------------------------------------------------- -void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain) { - // params - uint8_t blockNo = arg0 & 0xff; - uint8_t keyType = (arg0 >> 8) & 0xff; - uint8_t targetBlockNo = arg1 & 0xff; - uint8_t targetKeyType = (arg1 >> 8) & 0xff; - // calibrate = arg2 +void MifareNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8_t targetKeyType, bool calibrate, uint8_t *key) { uint64_t ui64Key = 0; - - ui64Key = bytes_to_num(datain, 6); + ui64Key = bytes_to_num(key, 6); // variables uint16_t i, j, len; static uint16_t dmin, dmax; + + uint8_t par[1] = {0x00}; + uint8_t par_array[4] = {0x00}; uint8_t uid[10] = {0x00}; uint32_t cuid = 0, nt1, nt2, nttest, ks1; - uint8_t par[1] = {0x00}; uint32_t target_nt[2] = {0x00}, target_ks[2] = {0x00}; - uint8_t par_array[4] = {0x00}; uint16_t ncount = 0; struct Crypto1State mpcs = {0, 0}; struct Crypto1State *pcs; @@ -903,13 +897,15 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain) BigBuf_free(); BigBuf_Clear_ext(false); - if (arg2) clear_trace(); + if (calibrate) + clear_trace(); + set_tracing(true); // statistics on nonce distance int16_t isOK = 0; #define NESTED_MAX_TRIES 12 - if (arg2) { // calibrate: for first call only. Otherwise reuse previous calibration + if (calibrate) { // calibrate: for first call only. Otherwise reuse previous calibration LED_B_ON(); WDT_HIT(); @@ -1061,15 +1057,28 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain) crypto1_destroy(pcs); - uint8_t buf[4 + 4 * 4] = {0}; - memcpy(buf, &cuid, 4); - memcpy(buf + 4, &target_nt[0], 4); - memcpy(buf + 8, &target_ks[0], 4); - memcpy(buf + 12, &target_nt[1], 4); - memcpy(buf + 16, &target_ks[1], 4); + struct p { + int16_t isOK; + uint8_t block; + uint8_t keytype; + uint8_t cuid[4]; + uint8_t nt_a[4]; + uint8_t ks_a[4]; + uint8_t nt_b[4]; + uint8_t ks_b[4]; + } PACKED payload; + payload.isOK = isOK; + payload.block = targetBlockNo; + payload.keytype = targetKeyType; + + memcpy(payload.cuid, &cuid, 4); + memcpy(payload.nt_a, &target_nt[0], 4); + memcpy(payload.ks_a, &target_ks[0], 4); + memcpy(payload.nt_b, &target_nt[1], 4); + memcpy(payload.ks_b, &target_ks[1], 4); LED_B_ON(); - reply_mix(CMD_ACK, isOK, 0, targetBlockNo + (targetKeyType * 0x100), buf, sizeof(buf)); + reply_ng(CMD_HF_MIFARE_NESTED, PM3_SUCCESS, (uint8_t*)&payload, sizeof(payload)); LED_B_OFF(); if (DBGLEVEL >= 3) DbpString("NESTED FINISHED"); diff --git a/armsrc/mifarecmd.h b/armsrc/mifarecmd.h index d563e37a8..0b8e2acd3 100644 --- a/armsrc/mifarecmd.h +++ b/armsrc/mifarecmd.h @@ -21,8 +21,10 @@ void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain) void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t *datain); void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain); //void MifareUWriteBlockCompat(uint8_t arg0,uint8_t *datain); + void MifareUWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain); -void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain); +void MifareNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8_t targetKeyType, bool calibrate, uint8_t *key); + void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, uint8_t *datain); void MifareAcquireNonces(uint32_t arg0, uint32_t flags); void MifareChkKeys(uint8_t *datain); diff --git a/client/cmddata.c b/client/cmddata.c index 16d9d10de..12a937d79 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -1654,52 +1654,69 @@ int CmdTuneSamples(const char *Cmd) { return PM3_ETIMEOUT; } } + + if (resp.status != PM3_SUCCESS) { + PrintAndLogEx(WARNING, "Antenna tuning failed"); + return PM3_ESOFT; + } + PrintAndLogEx(NORMAL, "\n"); + // in mVolt + struct p { + uint32_t v_lf134; + uint32_t v_lf125; + uint32_t v_lfconf; + uint32_t v_hf; + uint32_t peak_v; + uint32_t peak_f; + int divisor; + uint8_t results[256]; + } PACKED; - uint32_t v_lf125 = resp.oldarg[0]; - uint32_t v_lf134 = resp.oldarg[0] >> 32; + struct p* package = (struct p*)resp.data.asBytes; - uint32_t v_hf = resp.oldarg[1]; - uint32_t peakf = resp.oldarg[2]; - uint32_t peakv = resp.oldarg[2] >> 32; + if (package->v_lf125 > NON_VOLTAGE) + PrintAndLogEx(SUCCESS, "LF antenna: %5.2f V - 125.00 kHz", (package->v_lf125 * ANTENNA_ERROR) / 1000.0); - if (v_lf125 > NON_VOLTAGE) - PrintAndLogEx(SUCCESS, "LF antenna: %5.2f V - 125.00 kHz", (v_lf125 * ANTENNA_ERROR) / 1000.0); - if (v_lf134 > NON_VOLTAGE) - PrintAndLogEx(SUCCESS, "LF antenna: %5.2f V - 134.00 kHz", (v_lf134 * ANTENNA_ERROR) / 1000.0); - if (peakv > NON_VOLTAGE && peakf > 0) - PrintAndLogEx(SUCCESS, "LF optimal: %5.2f V - %6.2f kHz", (peakv * ANTENNA_ERROR) / 1000.0, 12000.0 / (peakf + 1)); + if (package->v_lf134 > NON_VOLTAGE) + PrintAndLogEx(SUCCESS, "LF antenna: %5.2f V - 134.00 kHz", (package->v_lf134 * ANTENNA_ERROR) / 1000.0); + + if (package->v_lfconf > NON_VOLTAGE && package->divisor > 0) + PrintAndLogEx(SUCCESS, "LF antenna: %5.2f V - %d kHz", (package->v_lfconf * ANTENNA_ERROR) / 1000.0, (12000 / package->divisor)); + + if (package->peak_v > NON_VOLTAGE && package->peak_f > 0) + PrintAndLogEx(SUCCESS, "LF optimal: %5.2f V - %6.2f kHz", (package->peak_v * ANTENNA_ERROR) / 1000.0, 12000.0 / (package->peak_f + 1)); char judgement[20]; memset(judgement, 0, sizeof(judgement)); // LF evaluation - if (peakv < LF_UNUSABLE_V) + if (package->peak_v < LF_UNUSABLE_V) sprintf(judgement, _RED_("UNUSABLE")); - else if (peakv < LF_MARGINAL_V) + else if (package->peak_v < LF_MARGINAL_V) sprintf(judgement, _YELLOW_("MARGINAL")); else sprintf(judgement, _GREEN_("OK")); PrintAndLogEx(NORMAL, "%sLF antenna is %s \n" - , (peakv < LF_UNUSABLE_V) ? _CYAN_("[!]") : _GREEN_("[+]") + , (package->peak_v < LF_UNUSABLE_V) ? _CYAN_("[!]") : _GREEN_("[+]") , judgement ); // HF evaluation - if (v_hf > NON_VOLTAGE) - PrintAndLogEx(SUCCESS, "HF antenna: %5.2f V - 13.56 MHz", (v_hf * ANTENNA_ERROR) / 1000.0); + if (package->v_hf > NON_VOLTAGE) + PrintAndLogEx(SUCCESS, "HF antenna: %5.2f V - 13.56 MHz", (package->v_hf * ANTENNA_ERROR) / 1000.0); memset(judgement, 0, sizeof(judgement)); - if (v_hf < HF_UNUSABLE_V) + if (package->v_hf < HF_UNUSABLE_V) sprintf(judgement, _RED_("UNUSABLE")); - else if (v_hf < HF_MARGINAL_V) + else if (package->v_hf < HF_MARGINAL_V) sprintf(judgement, _YELLOW_("MARGINAL")); else sprintf(judgement, _GREEN_("OK")); PrintAndLogEx(NORMAL, "%sHF antenna is %s" - , (v_hf < HF_UNUSABLE_V) ? _CYAN_("[!]") : _GREEN_("[+]") + , (package->v_hf < HF_UNUSABLE_V) ? _CYAN_("[!]") : _GREEN_("[+]") , judgement ); @@ -1707,12 +1724,12 @@ int CmdTuneSamples(const char *Cmd) { // even here, these values has 3% error. uint16_t test1 = 0; for (int i = 0; i < 256; i++) { - GraphBuffer[i] = resp.data.asBytes[i] - 128; - test1 += resp.data.asBytes[i]; + GraphBuffer[i] = package->results[i] - 128; + test1 += package->results[i]; } if (test1 > 0) { - PrintAndLogEx(SUCCESS, "\nDisplaying LF tuning graph. Divisor 89 is 134kHz, 95 is 125kHz.\n\n"); + PrintAndLogEx(SUCCESS, "\nDisplaying LF tuning graph. Divisor 89 is 134kHz, 96 is 125kHz.\n\n"); GraphTraceLen = 256; ShowGraphWindow(); RepaintGraphWindow(); diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 744532a13..3043d19ed 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -4425,12 +4425,12 @@ static command_t CommandTable[] = { {"ecfill", CmdHF14AMfECFill, IfPm3Iso14443a, "Fill simulator memory with help of keys from simulator"}, {"ekeyprn", CmdHF14AMfEKeyPrn, IfPm3Iso14443a, "Print keys from simulator memory"}, {"-----------", CmdHelp, IfPm3Iso14443a, ""}, - {"csetuid", CmdHF14AMfCSetUID, IfPm3Iso14443a, "Set UID for magic Chinese card"}, - {"csetblk", CmdHF14AMfCSetBlk, IfPm3Iso14443a, "Write block - Magic Chinese card"}, - {"cgetblk", CmdHF14AMfCGetBlk, IfPm3Iso14443a, "Read block - Magic Chinese card"}, - {"cgetsc", CmdHF14AMfCGetSc, IfPm3Iso14443a, "Read sector - Magic Chinese card"}, - {"cload", CmdHF14AMfCLoad, IfPm3Iso14443a, "Load dump into magic Chinese card"}, - {"csave", CmdHF14AMfCSave, IfPm3Iso14443a, "Save dump from magic Chinese card into file or emulator"}, + {"csetuid", CmdHF14AMfCSetUID, IfPm3Iso14443a, "Set UID (magic chinese card)"}, + {"csetblk", CmdHF14AMfCSetBlk, IfPm3Iso14443a, "Write block (magic chinese card)"}, + {"cgetblk", CmdHF14AMfCGetBlk, IfPm3Iso14443a, "Read block (magic chinese card)"}, + {"cgetsc", CmdHF14AMfCGetSc, IfPm3Iso14443a, "Read sector (magic chinese card)"}, + {"cload", CmdHF14AMfCLoad, IfPm3Iso14443a, "Load dump (magic chinese card)"}, + {"csave", CmdHF14AMfCSave, IfPm3Iso14443a, "Save dump from magic chinese card into file or emulator"}, {"-----------", CmdHelp, IfPm3Iso14443a, ""}, {"mad", CmdHF14AMfMAD, IfPm3Iso14443a, "Checks and prints MAD"}, {"ndef", CmdHFMFNDEF, IfPm3Iso14443a, "Prints NDEF records from card"}, diff --git a/client/cmdlf.c b/client/cmdlf.c index 83d04e7c7..aa7823b34 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -1243,9 +1243,9 @@ static command_t CommandTable[] = { // {"verichip", CmdLFVerichip, AlwaysAvailable, "{ VeriChip RFIDs... }"}, {"viking", CmdLFViking, AlwaysAvailable, "{ Viking RFIDs... }"}, {"visa2000", CmdLFVisa2k, AlwaysAvailable, "{ Visa2000 RFIDs... }"}, + {"", CmdHelp, AlwaysAvailable, ""}, {"config", CmdLFSetConfig, IfPm3Lf, "Set config for LF sampling, bit/sample, decimation, frequency"}, {"cmdread", CmdLFCommandRead, IfPm3Lf, " <'0' period> <'1' period> ['h' 134] \n\t\t-- Modulate LF reader field to send command before read (all periods in microseconds)"}, - {"flexdemod", CmdFlexdemod, AlwaysAvailable, "Demodulate samples for FlexPass"}, {"read", CmdLFRead, IfPm3Lf, "['s' silent] Read 125/134 kHz LF ID-only tag. Do 'lf read h' for help"}, {"search", CmdLFfind, AlwaysAvailable, "[offline] ['u'] Read and Search for valid known tag (in offline mode it you can load first then search) \n\t\t-- 'u' to search for unknown tags"}, {"sim", CmdLFSim, IfPm3Lf, "[GAP] -- Simulate LF tag from buffer with optional GAP (in microseconds)"}, @@ -1256,6 +1256,7 @@ static command_t CommandTable[] = { {"sniff", CmdLFSniff, IfPm3Lf, "Sniff LF traffic between reader and tag"}, {"tune", CmdLFTune, IfPm3Lf, "Continuously measure LF antenna tuning"}, // {"vchdemod", CmdVchDemod, AlwaysAvailable, "['clone'] -- Demodulate samples for VeriChip"}, + {"flexdemod", CmdFlexdemod, AlwaysAvailable, "Demodulate samples for Motorola FlexPass"}, {NULL, NULL, NULL, NULL} }; diff --git a/client/mifare/mifarehost.c b/client/mifare/mifarehost.c index 7cfabf3ee..ba775d992 100644 --- a/client/mifare/mifarehost.c +++ b/client/mifare/mifarehost.c @@ -339,27 +339,63 @@ __attribute__((force_align_arg_pointer)) int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t *resultKey, bool calibrate) { uint16_t i; uint32_t uid; - PacketResponseNG resp; StateList_t statelists[2]; struct Crypto1State *p1, *p2, *p3, *p4; + struct { + uint8_t block; + uint8_t keytype; + uint8_t target_block; + uint8_t target_keytype; + bool calibrate; + uint8_t key[6]; + } PACKED payload; + payload.block = blockNo; + payload.keytype = keyType; + payload.target_block = trgBlockNo; + payload.target_keytype = trgKeyType; + payload.calibrate = calibrate; + memcpy(payload.key, key, sizeof(payload.key)); + + PacketResponseNG resp; clearCommandBuffer(); - SendCommandOLD(CMD_HF_MIFARE_NESTED, blockNo + keyType * 0x100, trgBlockNo + trgKeyType * 0x100, calibrate, key, 6); - if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) return PM3_ETIMEOUT; + SendCommandNG(CMD_HF_MIFARE_NESTED, (uint8_t*)&payload, sizeof(payload)); + + if (!WaitForResponseTimeout(CMD_HF_MIFARE_NESTED, &resp, 1500)) return PM3_ETIMEOUT; + + if (resp.status != PM3_SUCCESS) + return PM3_ESOFT; + + struct p { + int16_t isOK; + uint8_t block; + uint8_t keytype; + uint8_t cuid[4]; + uint8_t nt_a[4]; + uint8_t ks_a[4]; + uint8_t nt_b[4]; + uint8_t ks_b[4]; + } PACKED; + struct p* package = (struct p*)resp.data.asBytes; // error during nested - if (resp.oldarg[0]) return resp.oldarg[0]; + if (package->isOK) return package->isOK; - memcpy(&uid, resp.data.asBytes, 4); + memcpy(&uid, package->cuid, sizeof(package->cuid)); for (i = 0; i < 2; i++) { - statelists[i].blockNo = resp.oldarg[2] & 0xff; - statelists[i].keyType = (resp.oldarg[2] >> 8) & 0xff; + statelists[i].blockNo = package->block; + statelists[i].keyType = package->keytype; statelists[i].uid = uid; - memcpy(&statelists[i].nt, (void *)(resp.data.asBytes + 4 + i * 8 + 0), 4); - memcpy(&statelists[i].ks1, (void *)(resp.data.asBytes + 4 + i * 8 + 4), 4); } + memcpy(&statelists[0].nt, package->nt_a, sizeof(package->nt_a)); + memcpy(&statelists[0].ks1, package->ks_a, sizeof(package->ks_a)); + + memcpy(&statelists[1].nt, package->nt_b, sizeof(package->nt_b)); + memcpy(&statelists[1].ks1, package->ks_b, sizeof(package->ks_b)); + + // calc keys pthread_t thread_id[2]; From 38673a10aa955d6c61115d3b9e699e0a58d599b9 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 3 Oct 2019 16:16:49 +0200 Subject: [PATCH 0821/1854] textual --- client/cmdmain.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/client/cmdmain.c b/client/cmdmain.c index 4b6013d80..7a04960f0 100644 --- a/client/cmdmain.c +++ b/client/cmdmain.c @@ -92,19 +92,20 @@ static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help. Use ' help' for details of a particular command."}, {"analyse", CmdAnalyse, AlwaysAvailable, "{ Analyse utils... }"}, {"data", CmdData, AlwaysAvailable, "{ Plot window / data buffer manipulation... }"}, - {"emv", CmdEMV, AlwaysAvailable, "{ EMV iso14443 and iso7816... }"}, - {"hf", CmdHF, AlwaysAvailable, "{ High Frequency commands... }"}, + {"emv", CmdEMV, AlwaysAvailable, "{ EMV ISO-14443 / ISO-7816... }"}, + {"hf", CmdHF, AlwaysAvailable, "{ High frequency commands... }"}, {"hw", CmdHW, AlwaysAvailable, "{ Hardware commands... }"}, - {"lf", CmdLF, AlwaysAvailable, "{ Low Frequency commands... }"}, + {"lf", CmdLF, AlwaysAvailable, "{ Low frequency commands... }"}, {"mem", CmdFlashMem, IfPm3Flash, "{ Flash Memory manipulation... }"}, - {"msleep", CmdMsleep, AlwaysAvailable, "Add a pause in milliseconds"}, - {"rem", CmdRem, AlwaysAvailable, "Add text to row in log file"}, {"reveng", CmdRev, AlwaysAvailable, "{ CRC calculations from RevEng software }"}, - {"sc", CmdSmartcard, IfPm3Smartcard, "{ Smart card ISO7816 commands... }"}, + {"sc", CmdSmartcard, IfPm3Smartcard, "{ Smart card ISO-7816 commands... }"}, {"script", CmdScript, AlwaysAvailable, "{ Scripting commands }"}, {"trace", CmdTrace, AlwaysAvailable, "{ Trace manipulation... }"}, {"usart", CmdUsart, IfPm3FpcUsartFromUsb, "{ USART commands... }"}, {"wiegand", CmdWiegand, AlwaysAvailable, "{ Wiegand format manipulation... }"}, + {"", CmdHelp, AlwaysAvailable, ""}, + {"msleep", CmdMsleep, AlwaysAvailable, "Add a pause in milliseconds"}, + {"rem", CmdRem, AlwaysAvailable, "Add a text line in log file"}, {"quit", CmdQuit, AlwaysAvailable, ""}, {"exit", CmdQuit, AlwaysAvailable, "Exit program"}, {NULL, NULL, NULL, NULL} From 37ce43cb8b13c034bfee8325312848b162ed8e82 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 3 Oct 2019 16:17:25 +0200 Subject: [PATCH 0822/1854] chg: dont log helpout --- client/cmdparser.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/cmdparser.c b/client/cmdparser.c index 9e7b83afa..f116b5ecd 100644 --- a/client/cmdparser.c +++ b/client/cmdparser.c @@ -155,7 +155,8 @@ void CmdsHelp(const command_t Commands[]) { int i = 0; while (Commands[i].Name) { if (Commands[i].IsAvailable()) - PrintAndLogEx(NORMAL, _GREEN_("%-16s")" %s", Commands[i].Name, Commands[i].Help); +// PrintAndLogEx(NORMAL, _GREEN_("%-16s")" %s", Commands[i].Name, Commands[i].Help); + printf(_GREEN_("%-16s")" %s\n", Commands[i].Name, Commands[i].Help); ++i; } } From 6df9eea950eae9e9e88c996dd4d3ee1d873d1490 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 3 Oct 2019 17:45:43 +0200 Subject: [PATCH 0823/1854] voltage config divisor printing --- armsrc/lfsampling.c | 3 ++- client/cmddata.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index e8664aa47..75cab1e7f 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -27,8 +27,9 @@ Default LF config is set to: sample_config config = { 1, 8, 1, 96, 0, 0 } ; void printConfig() { + uint32_t d = config.divisor; DbpString(_BLUE_("LF Sampling config")); - Dbprintf(" [q] divisor.............%d ( "_GREEN_("%d kHz")")", config.divisor, 12000 / config.divisor); + Dbprintf(" [q] divisor.............%d ( "_GREEN_("%d.%02d kHz")")", d, 12000 / d, ((1200000 + d/2) / d) - ((12000 / d) * 100)); Dbprintf(" [b] bps.................%d", config.bits_per_sample); Dbprintf(" [d] decimation..........%d", config.decimation); Dbprintf(" [a] averaging...........%s", (config.averaging) ? "Yes" : "No"); diff --git a/client/cmddata.c b/client/cmddata.c index 12a937d79..5397570dd 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -1682,7 +1682,7 @@ int CmdTuneSamples(const char *Cmd) { PrintAndLogEx(SUCCESS, "LF antenna: %5.2f V - 134.00 kHz", (package->v_lf134 * ANTENNA_ERROR) / 1000.0); if (package->v_lfconf > NON_VOLTAGE && package->divisor > 0) - PrintAndLogEx(SUCCESS, "LF antenna: %5.2f V - %d kHz", (package->v_lfconf * ANTENNA_ERROR) / 1000.0, (12000 / package->divisor)); + PrintAndLogEx(SUCCESS, "LF antenna: %5.2f V - %.2f kHz", (package->v_lfconf * ANTENNA_ERROR) / 1000.0, (12000.0 / package->divisor)); if (package->peak_v > NON_VOLTAGE && package->peak_f > 0) PrintAndLogEx(SUCCESS, "LF optimal: %5.2f V - %6.2f kHz", (package->peak_v * ANTENNA_ERROR) / 1000.0, 12000.0 / (package->peak_f + 1)); From f29ad0fba29ada6d6f42886ff2dccd7d5e26b79c Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 3 Oct 2019 18:25:21 +0200 Subject: [PATCH 0824/1854] macros for divisors and fix lf optimal freq display --- armsrc/appmain.c | 4 ++-- armsrc/lfsampling.c | 2 +- client/cmddata.c | 13 +++++++------ include/pm3_cmd.h | 5 +++++ 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index b67788bc5..af90060d5 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -182,10 +182,10 @@ void MeasureAntennaTuning(void) { FpgaSendCommand(FPGA_CMD_SET_DIVISOR, i); SpinDelay(20); uint32_t adcval = ((MAX_ADC_LF_VOLTAGE * AvgAdc(ADC_CHAN_LF)) >> 10); - if (i == 96) + if (i == LF_DIVISOR_125) payload.v_lf125 = adcval; // voltage at 125kHz - if (i == 89) + if (i == LF_DIVISOR_134) payload.v_lf134 = adcval; // voltage at 134kHz if (i == sc->divisor) diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index 75cab1e7f..993418360 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -24,7 +24,7 @@ Default LF config is set to: divisor = 95 (125kHz) trigger_threshold = 0 */ -sample_config config = { 1, 8, 1, 96, 0, 0 } ; +sample_config config = { 1, 8, 1, LF_DIVISOR_125, 0, 0 } ; void printConfig() { uint32_t d = config.divisor; diff --git a/client/cmddata.c b/client/cmddata.c index 5397570dd..1e9d7855e 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -1676,16 +1676,16 @@ int CmdTuneSamples(const char *Cmd) { struct p* package = (struct p*)resp.data.asBytes; if (package->v_lf125 > NON_VOLTAGE) - PrintAndLogEx(SUCCESS, "LF antenna: %5.2f V - 125.00 kHz", (package->v_lf125 * ANTENNA_ERROR) / 1000.0); + PrintAndLogEx(SUCCESS, "LF antenna: %5.2f V - %.2f kHz", (package->v_lf125 * ANTENNA_ERROR) / 1000.0, 12000.0 / LF_DIVISOR_125); if (package->v_lf134 > NON_VOLTAGE) - PrintAndLogEx(SUCCESS, "LF antenna: %5.2f V - 134.00 kHz", (package->v_lf134 * ANTENNA_ERROR) / 1000.0); + PrintAndLogEx(SUCCESS, "LF antenna: %5.2f V - %.2f kHz", (package->v_lf134 * ANTENNA_ERROR) / 1000.0, 12000.0 / LF_DIVISOR_134); - if (package->v_lfconf > NON_VOLTAGE && package->divisor > 0) - PrintAndLogEx(SUCCESS, "LF antenna: %5.2f V - %.2f kHz", (package->v_lfconf * ANTENNA_ERROR) / 1000.0, (12000.0 / package->divisor)); + if (package->v_lfconf > NON_VOLTAGE && package->divisor > 0 && package->divisor != LF_DIVISOR_125 && package->divisor != LF_DIVISOR_134) + PrintAndLogEx(SUCCESS, "LF antenna: %5.2f V - %.2f kHz", (package->v_lfconf * ANTENNA_ERROR) / 1000.0, 12000.0 / package->divisor); if (package->peak_v > NON_VOLTAGE && package->peak_f > 0) - PrintAndLogEx(SUCCESS, "LF optimal: %5.2f V - %6.2f kHz", (package->peak_v * ANTENNA_ERROR) / 1000.0, 12000.0 / (package->peak_f + 1)); + PrintAndLogEx(SUCCESS, "LF optimal: %5.2f V - %6.2f kHz", (package->peak_v * ANTENNA_ERROR) / 1000.0, 12000.0 / package->peak_f); char judgement[20]; memset(judgement, 0, sizeof(judgement)); @@ -1729,7 +1729,8 @@ int CmdTuneSamples(const char *Cmd) { } if (test1 > 0) { - PrintAndLogEx(SUCCESS, "\nDisplaying LF tuning graph. Divisor 89 is 134kHz, 96 is 125kHz.\n\n"); + PrintAndLogEx(SUCCESS, "\nDisplaying LF tuning graph. Divisor %d is %.2f kHz, %d is %.2f kHz.\n\n", + LF_DIVISOR_134, 12000.0 / LF_DIVISOR_134, LF_DIVISOR_125, 12000.0 / LF_DIVISOR_125); GraphTraceLen = 256; ShowGraphWindow(); RepaintGraphWindow(); diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 010e46728..ed2a4585c 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -578,6 +578,11 @@ typedef struct { // Quit program client: reserved, order to quit the program #define PM3_EFATAL -99 +// LF +//#define LF_DIVISOR(f) ((12000 + (f)/2)/(f)) +//Note that 90 = 133.33 is closer to 134 than 89 = 134.83 +#define LF_DIVISOR_125 96 +#define LF_DIVISOR_134 89 // Receiving from USART need more than 30ms as we used on USB // else we get errors about partial packet reception From df08e7970c3d8959cd3692d20f088a9fafcc72cb Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 3 Oct 2019 21:18:37 +0200 Subject: [PATCH 0825/1854] fix divisor<>freq computations, add q to lf tune --- armsrc/appmain.c | 4 +-- armsrc/lfsampling.c | 2 +- client/cmddata.c | 10 ++++---- client/cmdlf.c | 60 +++++++++++++++++++++++++++++++++------------ include/pm3_cmd.h | 7 +++--- 5 files changed, 55 insertions(+), 28 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index af90060d5..eed1d97ed 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1473,7 +1473,7 @@ static void PacketReceived(PacketCommandNG *packet) { break; } case CMD_MEASURE_ANTENNA_TUNING_LF: { - if (packet->length != 1) + if (packet->length != 2) reply_ng(CMD_MEASURE_ANTENNA_TUNING_LF, PM3_EINVARG, NULL, 0); switch (packet->data.asBytes[0]) { @@ -1481,7 +1481,7 @@ static void PacketReceived(PacketCommandNG *packet) { // Let the FPGA drive the low-frequency antenna around 125kHz FpgaDownloadAndGo(FPGA_BITSTREAM_LF); FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, packet->data.asBytes[1]); reply_ng(CMD_MEASURE_ANTENNA_TUNING_LF, PM3_SUCCESS, NULL, 0); break; case 2: diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index 993418360..175e0a2ff 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -29,7 +29,7 @@ sample_config config = { 1, 8, 1, LF_DIVISOR_125, 0, 0 } ; void printConfig() { uint32_t d = config.divisor; DbpString(_BLUE_("LF Sampling config")); - Dbprintf(" [q] divisor.............%d ( "_GREEN_("%d.%02d kHz")")", d, 12000 / d, ((1200000 + d/2) / d) - ((12000 / d) * 100)); + Dbprintf(" [q] divisor.............%d ( "_GREEN_("%d.%02d kHz")")", d, 12000 / (d+1), ((1200000 + (d+1)/2) / (d+1)) - ((12000 / (d+1)) * 100)); Dbprintf(" [b] bps.................%d", config.bits_per_sample); Dbprintf(" [d] decimation..........%d", config.decimation); Dbprintf(" [a] averaging...........%s", (config.averaging) ? "Yes" : "No"); diff --git a/client/cmddata.c b/client/cmddata.c index 1e9d7855e..e025ded3f 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -1676,16 +1676,16 @@ int CmdTuneSamples(const char *Cmd) { struct p* package = (struct p*)resp.data.asBytes; if (package->v_lf125 > NON_VOLTAGE) - PrintAndLogEx(SUCCESS, "LF antenna: %5.2f V - %.2f kHz", (package->v_lf125 * ANTENNA_ERROR) / 1000.0, 12000.0 / LF_DIVISOR_125); + PrintAndLogEx(SUCCESS, "LF antenna: %5.2f V - %.2f kHz", (package->v_lf125 * ANTENNA_ERROR) / 1000.0, 12000.0 / (LF_DIVISOR_125 + 1)); if (package->v_lf134 > NON_VOLTAGE) - PrintAndLogEx(SUCCESS, "LF antenna: %5.2f V - %.2f kHz", (package->v_lf134 * ANTENNA_ERROR) / 1000.0, 12000.0 / LF_DIVISOR_134); + PrintAndLogEx(SUCCESS, "LF antenna: %5.2f V - %.2f kHz", (package->v_lf134 * ANTENNA_ERROR) / 1000.0, 12000.0 / (LF_DIVISOR_134 + 1)); if (package->v_lfconf > NON_VOLTAGE && package->divisor > 0 && package->divisor != LF_DIVISOR_125 && package->divisor != LF_DIVISOR_134) - PrintAndLogEx(SUCCESS, "LF antenna: %5.2f V - %.2f kHz", (package->v_lfconf * ANTENNA_ERROR) / 1000.0, 12000.0 / package->divisor); + PrintAndLogEx(SUCCESS, "LF antenna: %5.2f V - %.2f kHz", (package->v_lfconf * ANTENNA_ERROR) / 1000.0, 12000.0 / (package->divisor + 1)); if (package->peak_v > NON_VOLTAGE && package->peak_f > 0) - PrintAndLogEx(SUCCESS, "LF optimal: %5.2f V - %6.2f kHz", (package->peak_v * ANTENNA_ERROR) / 1000.0, 12000.0 / package->peak_f); + PrintAndLogEx(SUCCESS, "LF optimal: %5.2f V - %6.2f kHz", (package->peak_v * ANTENNA_ERROR) / 1000.0, 12000.0 / (package->peak_f + 1)); char judgement[20]; memset(judgement, 0, sizeof(judgement)); @@ -1730,7 +1730,7 @@ int CmdTuneSamples(const char *Cmd) { if (test1 > 0) { PrintAndLogEx(SUCCESS, "\nDisplaying LF tuning graph. Divisor %d is %.2f kHz, %d is %.2f kHz.\n\n", - LF_DIVISOR_134, 12000.0 / LF_DIVISOR_134, LF_DIVISOR_125, 12000.0 / LF_DIVISOR_125); + LF_DIVISOR_134, 12000.0 / (LF_DIVISOR_134 + 1), LF_DIVISOR_125, 12000.0 / (LF_DIVISOR_125 + 1)); GraphTraceLen = 256; ShowGraphWindow(); RepaintGraphWindow(); diff --git a/client/cmdlf.c b/client/cmdlf.c index aa7823b34..88ab0d200 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -109,7 +109,7 @@ static int usage_lf_config(void) { PrintAndLogEx(NORMAL, " h This help"); PrintAndLogEx(NORMAL, " L Low frequency (125 kHz)"); PrintAndLogEx(NORMAL, " H High frequency (134 kHz)"); - PrintAndLogEx(NORMAL, " q Manually set divisor. 88-> 134 kHz, 95-> 125 kHz"); + PrintAndLogEx(NORMAL, " q Manually set divisor. %d -> 134 kHz, %d -> 125 kHz", LF_DIVISOR_134, LF_DIVISOR_125); PrintAndLogEx(NORMAL, " b Sets resolution of bits per sample. Default (max): 8"); PrintAndLogEx(NORMAL, " d Sets decimation. A value of N saves only 1 in N samples. Default: 1"); PrintAndLogEx(NORMAL, " a [0|1] Averaging - if set, will average the stored sample value when decimating. Default: 1"); @@ -193,39 +193,67 @@ static int usage_lf_find(void) { return PM3_SUCCESS; } static int usage_lf_tune(void) { - PrintAndLogEx(NORMAL, "Continuously measure LF antenna tuning at 125 kHz."); + PrintAndLogEx(NORMAL, "Continuously measure LF antenna tuning."); PrintAndLogEx(NORMAL, "Press button or Enter to interrupt."); - PrintAndLogEx(NORMAL, "Usage: lf tune [h] []"); + PrintAndLogEx(NORMAL, "Usage: lf tune [h] [n ] [q ]"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h - This help"); - PrintAndLogEx(NORMAL, " - number of iterations (default: 0=infinite)"); + PrintAndLogEx(NORMAL, " n - number of iterations (default: 0=infinite)"); + PrintAndLogEx(NORMAL, " q - Frequency divisor. %d -> 134 kHz, %d -> 125 kHz", LF_DIVISOR_134, LF_DIVISOR_125); return PM3_SUCCESS; } int CmdLFTune(const char *Cmd) { - char cmdp = tolower(param_getchar(Cmd, 0)); - if (cmdp == 'h') return usage_lf_tune(); - int iter = param_get32ex(Cmd, 0, 0, 10); + int iter = 0; + uint8_t divisor = LF_DIVISOR_125;//Frequency divisor + bool errors = false; + uint8_t cmdp = 0; + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (param_getchar(Cmd, cmdp)) { + case 'h': + return usage_lf_tune(); + case 'q': + errors |= param_getdec(Cmd, cmdp + 1, &divisor); + cmdp += 2; + break; + case 'n': + iter = param_get32ex(Cmd, cmdp + 1, 0, 10); + cmdp += 2; + break; + default: + PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = 1; + break; + } + } - PrintAndLogEx(SUCCESS, "Measuring LF antenna at 125kHz, click button or press Enter to exit"); + //Validations + if (errors || divisor < 19) return usage_lf_tune(); + if (divisor < 19) { + PrintAndLogEx(ERR, "divisor must be between 19 and 255"); + return PM3_EINVARG; + } - uint8_t mode[] = {1}; + PrintAndLogEx(SUCCESS, "Measuring LF antenna at %.2f kHz, click button or press Enter to exit", 12000.0 / (divisor + 1)); + + uint8_t params[] = {1, 0}; + params[1] = divisor; PacketResponseNG resp; clearCommandBuffer(); - SendCommandNG(CMD_MEASURE_ANTENNA_TUNING_LF, mode, sizeof(mode)); + SendCommandNG(CMD_MEASURE_ANTENNA_TUNING_LF, params, sizeof(params)); if (!WaitForResponseTimeout(CMD_MEASURE_ANTENNA_TUNING_LF, &resp, 1000)) { PrintAndLogEx(WARNING, "Timeout while waiting for Proxmark LF initialization, aborting"); return PM3_ETIMEOUT; } - mode[0] = 2; + params[0] = 2; // loop forever (till button pressed) if iter = 0 (default) for (uint8_t i = 0; iter == 0 || i < iter; i++) { if (kbd_enter_pressed()) { // abort by keyboard press break; } - SendCommandNG(CMD_MEASURE_ANTENNA_TUNING_LF, mode, sizeof(mode)); + SendCommandNG(CMD_MEASURE_ANTENNA_TUNING_LF, params, sizeof(params)); if (!WaitForResponseTimeout(CMD_MEASURE_ANTENNA_TUNING_LF, &resp, 1000)) { PrintAndLogEx(WARNING, "Timeout while waiting for Proxmark LF measure, aborting"); return PM3_ETIMEOUT; @@ -235,8 +263,8 @@ int CmdLFTune(const char *Cmd) { uint32_t volt = resp.data.asDwords[0]; PrintAndLogEx(INPLACE, "%u mV / %5u V", volt, (uint32_t)(volt / 1000)); } - mode[0] = 3; - SendCommandNG(CMD_MEASURE_ANTENNA_TUNING_LF, mode, sizeof(mode)); + params[0] = 3; + SendCommandNG(CMD_MEASURE_ANTENNA_TUNING_LF, params, sizeof(params)); if (!WaitForResponseTimeout(CMD_MEASURE_ANTENNA_TUNING_LF, &resp, 1000)) { PrintAndLogEx(WARNING, "Timeout while waiting for Proxmark LF shutdown, aborting"); return PM3_ETIMEOUT; @@ -426,11 +454,11 @@ int CmdLFSetConfig(const char *Cmd) { case 'h': return usage_lf_config(); case 'H': - divisor = 88; + divisor = LF_DIVISOR_134; cmdp++; break; case 'L': - divisor = 95; + divisor = LF_DIVISOR_125; cmdp++; break; case 'q': diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index ed2a4585c..010759a30 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -579,10 +579,9 @@ typedef struct { #define PM3_EFATAL -99 // LF -//#define LF_DIVISOR(f) ((12000 + (f)/2)/(f)) -//Note that 90 = 133.33 is closer to 134 than 89 = 134.83 -#define LF_DIVISOR_125 96 -#define LF_DIVISOR_134 89 +#define LF_DIVISOR(f) (((12000 + (f)/2)/(f))-1) +#define LF_DIVISOR_125 LF_DIVISOR(125) +#define LF_DIVISOR_134 LF_DIVISOR(134) // Receiving from USART need more than 30ms as we used on USB // else we get errors about partial packet reception From f8cd16849808ab9ead57ba42d937b83cc0dabeed Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 3 Oct 2019 21:46:06 +0200 Subject: [PATCH 0826/1854] add f (freq) to lf tune & lf config --- client/cmdlf.c | 40 ++++++++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/client/cmdlf.c b/client/cmdlf.c index 88ab0d200..ad904ade1 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -104,12 +104,13 @@ static int usage_lf_sniff(void) { return PM3_SUCCESS; } static int usage_lf_config(void) { - PrintAndLogEx(NORMAL, "Usage: lf config [h] [H|] [b ] [d ] [a 0|1]"); + PrintAndLogEx(NORMAL, "Usage: lf config [h] [L | H | q | f ] [b ] [d ] [a 0|1]"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h This help"); PrintAndLogEx(NORMAL, " L Low frequency (125 kHz)"); PrintAndLogEx(NORMAL, " H High frequency (134 kHz)"); - PrintAndLogEx(NORMAL, " q Manually set divisor. %d -> 134 kHz, %d -> 125 kHz", LF_DIVISOR_134, LF_DIVISOR_125); + PrintAndLogEx(NORMAL, " q Manually set freq divisor. %d -> 134 kHz, %d -> 125 kHz", LF_DIVISOR_134, LF_DIVISOR_125); + PrintAndLogEx(NORMAL, " f Manually set frequency in kHz"); PrintAndLogEx(NORMAL, " b Sets resolution of bits per sample. Default (max): 8"); PrintAndLogEx(NORMAL, " d Sets decimation. A value of N saves only 1 in N samples. Default: 1"); PrintAndLogEx(NORMAL, " a [0|1] Averaging - if set, will average the stored sample value when decimating. Default: 1"); @@ -195,12 +196,13 @@ static int usage_lf_find(void) { static int usage_lf_tune(void) { PrintAndLogEx(NORMAL, "Continuously measure LF antenna tuning."); PrintAndLogEx(NORMAL, "Press button or Enter to interrupt."); - PrintAndLogEx(NORMAL, "Usage: lf tune [h] [n ] [q ]"); + PrintAndLogEx(NORMAL, "Usage: lf tune [h] [n ] [q | f ]"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h - This help"); PrintAndLogEx(NORMAL, " n - number of iterations (default: 0=infinite)"); PrintAndLogEx(NORMAL, " q - Frequency divisor. %d -> 134 kHz, %d -> 125 kHz", LF_DIVISOR_134, LF_DIVISOR_125); + PrintAndLogEx(NORMAL, " f - Frequency in kHz"); return PM3_SUCCESS; } @@ -216,7 +218,20 @@ int CmdLFTune(const char *Cmd) { case 'q': errors |= param_getdec(Cmd, cmdp + 1, &divisor); cmdp += 2; + if (divisor < 19) { + PrintAndLogEx(ERR, "divisor must be between 19 and 255"); + return PM3_EINVARG; + } break; + case 'f': { + divisor = LF_DIVISOR(param_get32ex(Cmd, cmdp + 1, 125, 10)); + if (divisor < 19) { + PrintAndLogEx(ERR, "freq must be between 47 and 600"); + return PM3_EINVARG; + } + cmdp += 2; + break; + } case 'n': iter = param_get32ex(Cmd, cmdp + 1, 0, 10); cmdp += 2; @@ -229,11 +244,7 @@ int CmdLFTune(const char *Cmd) { } //Validations - if (errors || divisor < 19) return usage_lf_tune(); - if (divisor < 19) { - PrintAndLogEx(ERR, "divisor must be between 19 and 255"); - return PM3_EINVARG; - } + if (errors) return usage_lf_tune(); PrintAndLogEx(SUCCESS, "Measuring LF antenna at %.2f kHz, click button or press Enter to exit", 12000.0 / (divisor + 1)); @@ -463,8 +474,21 @@ int CmdLFSetConfig(const char *Cmd) { break; case 'q': errors |= param_getdec(Cmd, cmdp + 1, &divisor); + if (divisor < 19) { + PrintAndLogEx(ERR, "divisor must be between 19 and 255"); + return PM3_EINVARG; + } cmdp += 2; break; + case 'f': { + divisor = LF_DIVISOR(param_get32ex(Cmd, cmdp + 1, 125, 10)); + if (divisor < 19) { + PrintAndLogEx(ERR, "freq must be between 47 and 600"); + return PM3_EINVARG; + } + cmdp += 2; + break; + } case 't': errors |= param_getdec(Cmd, cmdp + 1, &unsigned_trigg); cmdp += 2; From 156c3a81e82145b0c1a7a03b6fb2327c4f793bd2 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 3 Oct 2019 21:54:45 +0200 Subject: [PATCH 0827/1854] no fct call in macro, thanks @iceman1001 --- client/cmdlf.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/cmdlf.c b/client/cmdlf.c index ad904ade1..d35956e2b 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -224,7 +224,8 @@ int CmdLFTune(const char *Cmd) { } break; case 'f': { - divisor = LF_DIVISOR(param_get32ex(Cmd, cmdp + 1, 125, 10)); + int freq = param_get32ex(Cmd, cmdp + 1, 125, 10); + divisor = LF_DIVISOR(freq); if (divisor < 19) { PrintAndLogEx(ERR, "freq must be between 47 and 600"); return PM3_EINVARG; From 159b90c00265f654a3af905b5044b5a86401b190 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 3 Oct 2019 21:56:42 +0200 Subject: [PATCH 0828/1854] no fct call in macro, thanks @iceman1001 --- client/cmdlf.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/cmdlf.c b/client/cmdlf.c index d35956e2b..826391752 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -482,7 +482,8 @@ int CmdLFSetConfig(const char *Cmd) { cmdp += 2; break; case 'f': { - divisor = LF_DIVISOR(param_get32ex(Cmd, cmdp + 1, 125, 10)); + int freq = param_get32ex(Cmd, cmdp + 1, 125, 10); + divisor = LF_DIVISOR(freq); if (divisor < 19) { PrintAndLogEx(ERR, "freq must be between 47 and 600"); return PM3_EINVARG; From 42cb2a32e848b383d83756298b0c6ef9c56f6fbf Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 3 Oct 2019 22:11:16 +0200 Subject: [PATCH 0829/1854] lf config alone shows current config --- armsrc/appmain.c | 4 ++++ client/cmdlf.c | 13 ++++++++++--- include/pm3_cmd.h | 1 + 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index eed1d97ed..9be4443ed 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -685,6 +685,10 @@ static void PacketReceived(PacketCommandNG *packet) { setT55xxConfig(packet->oldarg[0], (t55xx_configurations_t *) packet->data.asBytes); break; } + case CMD_LF_SAMPLING_GET_CONFIG: { + printConfig(); + break; + } case CMD_LF_SAMPLING_SET_CONFIG: { setSamplingConfig((sample_config *) packet->data.asBytes); break; diff --git a/client/cmdlf.c b/client/cmdlf.c index 826391752..044df875b 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -117,6 +117,8 @@ static int usage_lf_config(void) { PrintAndLogEx(NORMAL, " t Sets trigger threshold. 0 means no threshold (range: 0-128)"); PrintAndLogEx(NORMAL, " s Sets a number of samples to skip before capture. Default: 0"); PrintAndLogEx(NORMAL, "Examples:"); + PrintAndLogEx(NORMAL, " lf config"); + PrintAndLogEx(NORMAL, " Shows current config"); PrintAndLogEx(NORMAL, " lf config b 8 L"); PrintAndLogEx(NORMAL, " Samples at 125 kHz, 8bps."); PrintAndLogEx(NORMAL, " lf config H b 4 d 3"); @@ -446,7 +448,7 @@ int CmdFlexdemod(const char *Cmd) { return PM3_SUCCESS; } -int CmdLFSetConfig(const char *Cmd) { +int CmdLFConfig(const char *Cmd) { if (!session.pm3_present) return PM3_ENOTTY; @@ -523,7 +525,12 @@ int CmdLFSetConfig(const char *Cmd) { } //Validations - if (errors || cmdp == 0) return usage_lf_config(); + if (errors) return usage_lf_config(); + if (cmdp == 0) { + clearCommandBuffer(); + SendCommandNG(CMD_LF_SAMPLING_GET_CONFIG, NULL, 0); + return PM3_SUCCESS; + } //Bps is limited to 8 if (bps >> 4) bps = 8; @@ -1298,7 +1305,7 @@ static command_t CommandTable[] = { {"viking", CmdLFViking, AlwaysAvailable, "{ Viking RFIDs... }"}, {"visa2000", CmdLFVisa2k, AlwaysAvailable, "{ Visa2000 RFIDs... }"}, {"", CmdHelp, AlwaysAvailable, ""}, - {"config", CmdLFSetConfig, IfPm3Lf, "Set config for LF sampling, bit/sample, decimation, frequency"}, + {"config", CmdLFConfig, IfPm3Lf, "Get/Set config for LF sampling, bit/sample, decimation, frequency"}, {"cmdread", CmdLFCommandRead, IfPm3Lf, " <'0' period> <'1' period> ['h' 134] \n\t\t-- Modulate LF reader field to send command before read (all periods in microseconds)"}, {"read", CmdLFRead, IfPm3Lf, "['s' silent] Read 125/134 kHz LF ID-only tag. Do 'lf read h' for help"}, {"search", CmdLFfind, AlwaysAvailable, "[offline] ['u'] Read and Search for valid known tag (in offline mode it you can load first then search) \n\t\t-- 'u' to search for unknown tags"}, diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 010759a30..108e3ba1f 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -373,6 +373,7 @@ typedef struct { #define CMD_LF_T55XX_WAKEUP 0x0224 #define CMD_LF_COTAG_READ 0x0225 #define CMD_LF_T55XX_SET_CONFIG 0x0226 +#define CMD_LF_SAMPLING_GET_CONFIG 0x0227 #define CMD_LF_T55XX_CHK_PWDS 0x0230 From 8a7274ec344be44588e33c7c704d3afa1bed7e87 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 4 Oct 2019 09:30:36 +0200 Subject: [PATCH 0830/1854] offline: avoid spurious "Sending bytes to proxmark failed" on exit --- client/proxmark3.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/client/proxmark3.c b/client/proxmark3.c index f28e14063..a2d4ebd72 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -261,9 +261,11 @@ check_script: } } // end while - clearCommandBuffer(); - SendCommandNG(CMD_QUIT_SESSION, NULL, 0); - msleep(100); // Make sure command is sent before killing client + if (session.pm3_present) { + clearCommandBuffer(); + SendCommandNG(CMD_QUIT_SESSION, NULL, 0); + msleep(100); // Make sure command is sent before killing client + } while (current_cmdscriptfile()) pop_cmdscriptfile(); From 3d6d83726ef844240f8f89d293bb4e699e7e6bbc Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 4 Oct 2019 10:14:38 +0200 Subject: [PATCH 0831/1854] textual --- client/cmdhflist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdhflist.c b/client/cmdhflist.c index a359ff07d..45abd1d57 100644 --- a/client/cmdhflist.c +++ b/client/cmdhflist.c @@ -1122,7 +1122,7 @@ bool DecodeMifareData(uint8_t *cmd, uint8_t cmdsize, uint8_t *parity, bool isRes AuthData.ks3 = AuthData.at_enc ^ prng_successor(AuthData.nt, 96); mfLastKey = GetCrypto1ProbableKey(&AuthData); - PrintAndLogEx(NORMAL, " | | * |%49s %012"PRIx64" prng %s | |", + PrintAndLogEx(NORMAL, " | | * |%48s %012"PRIx64" prng %s | |", "key", mfLastKey, validate_prng_nonce(AuthData.nt) ? _GREEN_("WEAK") : _YELLOW_("HARD")); From ebb2ac6f6684992997add953d90280b819251033 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 4 Oct 2019 10:24:04 +0200 Subject: [PATCH 0832/1854] adjusting check button timings --- armsrc/iclass.c | 28 ++++++++++++++-------------- armsrc/iso14443a.c | 12 ++++++------ armsrc/lfsampling.c | 9 ++++----- 3 files changed, 24 insertions(+), 25 deletions(-) diff --git a/armsrc/iclass.c b/armsrc/iclass.c index fd5d663fd..50042ef0c 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -906,11 +906,11 @@ void RAMFUNC SniffIClass(void) { for (;;) { WDT_HIT(); - if (checked == 2000) { + if (checked == 1000) { if (BUTTON_PRESS() || data_available()) break; checked = 0; } - checked++; + ++checked; previous_data <<= 8; previous_data |= *data; @@ -1014,11 +1014,11 @@ static bool GetIClassCommandFromReader(uint8_t *received, int *len, int maxLen) WDT_HIT(); - if (checked == 2000) { + if (checked == 1000) { if (BUTTON_PRESS() || data_available()) return false; checked = 0; } - checked++; + ++checked; // keep tx buffer in a defined state anyway. if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) @@ -1666,11 +1666,11 @@ static int SendIClassAnswer(uint8_t *resp, int respLen, uint16_t delay) { uint16_t checked = 0; for (;;) { - if (checked == 2000) { + if (checked == 1000) { if (BUTTON_PRESS() || data_available()) return 0; checked = 0; } - checked++; + ++checked; // Prevent rx holding register from overflowing if ((AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY)) { @@ -1828,11 +1828,11 @@ static int GetIClassAnswer(uint8_t *receivedResponse, int maxLen, int *wait) { for (;;) { WDT_HIT(); - if (checked == 2000) { + if (checked == 1000) { if (BUTTON_PRESS() || data_available()) return false; checked = 0; } - checked++; + ++checked; // Wait for byte be become available in rx holding register if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { @@ -2123,11 +2123,11 @@ void ReaderIClass(uint8_t arg0) { } LED_B_OFF(); - if (checked == 2000) { + if (checked == 1000) { userCancelled = BUTTON_PRESS() || data_available(); checked = 0; } - checked++; + ++checked; } if (userCancelled) { @@ -2326,11 +2326,11 @@ void iClass_Authentication_fast(uint64_t arg0, uint64_t arg1, uint8_t *datain) { uint8_t startup_limit = 10; while (read_status != 2) { - if (checked == 2000) { + if (checked == 1000) { if (BUTTON_PRESS() || !data_available()) goto out; checked = 0; } - checked++; + ++checked; read_status = handshakeIclassTag_ext(card_data, use_credit_key); if (startup_limit-- == 0) { @@ -2347,11 +2347,11 @@ void iClass_Authentication_fast(uint64_t arg0, uint64_t arg1, uint8_t *datain) { for (i = 0; i < keyCount; i++) { // Allow button press / usb cmd to interrupt device - if (checked == 2000) { + if (checked == 1000) { if (BUTTON_PRESS() || !data_available()) goto out; checked = 0; } - checked++; + ++checked; WDT_HIT(); LED_B_ON(); diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 81bada416..62433fa5f 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -2818,7 +2818,7 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) { WDT_HIT(); // Test if the action was cancelled - if (checkbtn_cnt == 2000) { + if (checkbtn_cnt == 1000) { if (BUTTON_PRESS() || data_available()) { isOK = -1; return_status = PM3_EOPABORTED; @@ -2832,7 +2832,7 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) { if (!have_uid) { // need a full select cycle to get the uid first iso14a_card_select_t card_info; if (!iso14443a_select_card(uid, &card_info, &cuid, true, 0, true)) { - if (DBGLEVEL >= DBG_ERROR) Dbprintf("Mifare: Can't select card (ALL)"); + if (DBGLEVEL >= DBG_INFO) Dbprintf("Mifare: Can't select card (ALL)"); continue; } switch (card_info.uidlen) { @@ -2851,7 +2851,7 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) { have_uid = true; } else { // no need for anticollision. We can directly select the card if (!iso14443a_fast_select_card(uid, cascade_levels)) { - if (DBGLEVEL >= DBG_ERROR) Dbprintf("Mifare: Can't select card (UID)"); + if (DBGLEVEL >= DBG_INFO) Dbprintf("Mifare: Can't select card (UID)"); continue; } } @@ -3092,7 +3092,7 @@ void DetectNACKbug(void) { WDT_HIT(); // Test if the action was cancelled - if (checkbtn_cnt == 2000) { + if (checkbtn_cnt == 1000) { if (BUTTON_PRESS() || data_available()) { status = PM3_EOPABORTED; break; @@ -3105,7 +3105,7 @@ void DetectNACKbug(void) { if (!have_uid) { // need a full select cycle to get the uid first iso14a_card_select_t card_info; if (!iso14443a_select_card(uid, &card_info, &cuid, true, 0, true)) { - if (DBGLEVEL >= DBG_ERROR) Dbprintf("Mifare: Can't select card (ALL)"); + if (DBGLEVEL >= DBG_INFO) Dbprintf("Mifare: Can't select card (ALL)"); i = 0; continue; } @@ -3127,7 +3127,7 @@ void DetectNACKbug(void) { have_uid = true; } else { // no need for anticollision. We can directly select the card if (!iso14443a_fast_select_card(uid, cascade_levels)) { - if (DBGLEVEL >= DBG_ERROR) Dbprintf("Mifare: Can't select card (UID)"); + if (DBGLEVEL >= DBG_INFO) Dbprintf("Mifare: Can't select card (UID)"); i = 0; have_uid = false; continue; diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index 175e0a2ff..59bb81d83 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -149,17 +149,16 @@ uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averag uint32_t sample_total_saved = 0; uint32_t cancel_counter = 0; - uint16_t checker = 0; + uint16_t checked = 0; while (true) { - if (checker == 2000) { + if (checked == 1000) { if (BUTTON_PRESS() || data_available()) break; else - checker = 0; - } else { - ++checker; + checked = 0; } + ++checked; WDT_HIT(); From 43d98da458273edf7e080a12c6954122891db02f Mon Sep 17 00:00:00 2001 From: mwalker33 Date: Fri, 4 Oct 2019 22:04:03 +1000 Subject: [PATCH 0833/1854] T5577 Howto --- doc/T5577/T5577_Guide.md | 677 +++++++++++++++++++++++++++++++++++++ doc/T5577/media/image1.png | Bin 0 -> 44034 bytes doc/T5577/media/image2.png | Bin 0 -> 26953 bytes doc/T5577/media/image3.png | Bin 0 -> 62447 bytes doc/cheatsheet.md | 20 ++ 5 files changed, 697 insertions(+) create mode 100644 doc/T5577/T5577_Guide.md create mode 100644 doc/T5577/media/image1.png create mode 100644 doc/T5577/media/image2.png create mode 100644 doc/T5577/media/image3.png diff --git a/doc/T5577/T5577_Guide.md b/doc/T5577/T5577_Guide.md new file mode 100644 index 000000000..5cf27bf02 --- /dev/null +++ b/doc/T5577/T5577_Guide.md @@ -0,0 +1,677 @@ +# T5577 Introduction Guide + +### Ver.1 8 Jul 2019 + +| Contents | +| ----------------------------------------------------------------------------------- | +| [Part 1](#part-1) | +| [Introduction](#introduction) | +| [T5577 Overview](#t5577-overview) | +| [What data is on my T5577](#what-data-is-on-my-t5577) | +| [Read and Write Blocks of Data](#read-and-write-blocks-of-data) | +| [Exercise 1](#exercise-1) | +| [How do I use a password](#how-do-i-use-a-password) | +| | +| [Part 2 – Configuration Blocks](#part-2-configuration-blocks) | +| [The configuration Block – Block 0 Page 0](#the-configuration-block-block-0-page-0) | +| [Exercise 2](#exercise-2) | +| [The configuration Block – Block 3 Page 1](#the-configuration-block-block-3-page-1) | + +# Part 1 + +## Introduction + +The T5577 is a generic LF (Low Frequency) RFID card the is used in the +125 Khz frequency. It is a good card to use to learn about RFID and +learn how to use the proxmark3. + +It is highly recommend that when learning about RFID that learning how +to read the data sheets be near the top of the list. It can be very hard +as the data sheet will hold the information you need, but you don’t yet +know what it means. As such, I will attempt to point to sections of the +data sheet and would highly advise that you look at the data sheet as +you go. Overtime the data sheet may change, as a result things may not +always be reference correctly. + +As at writing this guide, the data sheet can be found at : + + + +This guide is not a how do I clone document. It is meant to help people +learn how to use the T5577 and in the process learn about rfid and the +proxmark3. + +Throughout this guide I will give examples. It is recommended that you +try these as we go. To do so, have a blank T5577 card that you can use +for this purpose. + +## T5577 Overview + +The T5577 is a chip that can hold data and a configuration (Section +4.12). + +In the diagram below, all white blocks can hold data. Some can be used +for a second purpose, such as the ‘password’ and ‘traceability data’. +The ‘Configuration Data’ and ‘Analog front end option setup’ will tell +the chip how to behave. + +![](./media/image1.png) + + + +## What data is on my T5577 + +Let’s have a look and see what a card might look in the proxmark3 +software. Since we can change the configuration of how the T5577 will +output data, the proxmark3 software need to work out how to interpreted +the data it receives, we do this with the following command. + +It should be noted that the T5577 has many clones. As such the default +setup of each card may be different. If the tractability data is +present, then this will vary based on the batch of cards. + +Always run this command when you place a t5577 on the proxmark3. In all +examples shown, it will be assumed you have run the detect command. +``` +proxmark3 > lf t55xx detect +``` +You should see a results simular to the following: +``` +Chip Type : T55x7 +Modulation : ASK +Bit Rate : 2 - RF/32 +Inverted : No +Offset : 31 +Seq. Term. : No +Block0 : 0x00088040 +``` +Now that the proxmark3 has detected a T55x7 chip, and found some +information about it, we should be able to see all the data on the chip. +``` +proxmark3 > lf t55xx dump +``` +Your results should look similar to the following: +``` +Reading Page 0: + +blk | hex data | binary +----+----------+--------------------------------- + 0 | 00088040 | 00000000000010001000000001000000 + 1 | FFFFFFFF | 11111111111111111111111111111111 + 2 | FFFFFFFF | 11111111111111111111111111111111 + 3 | FFFFFFFF | 11111111111111111111111111111111 + 4 | FFFFFFFF | 11111111111111111111111111111111 + 5 | FFFFFFFF | 11111111111111111111111111111111 + 6 | FFFFFFFF | 11111111111111111111111111111111 + 7 | FFFFFFFF | 11111111111111111111111111111111 +Reading Page 1: +blk | hex data | binary +----+----------+--------------------------------- + 0 | 00088040 | 00000000000010001000000001000000 + 1 | E0150A48 | 11100000000101010000101001001000 + 2 | 2D782308 | 00101101011110000010001100001000 + 3 | FFFFFFFF | 11111111111111111111111111111111 +``` +I will cover the meaning of this data as we go, but for now, lets keep +it simple. + +## Read and Write Blocks of Data + +The basic function of using the proxmark3 with rfid cards is to read and +write data. This reading and writing must be done in the correct way +needed for the chip (and its configuration). Lucky for us, the +developers have done a great job and gave us commands. What we need to +know is that with the T5577 data is read/written one complete block at a +time. Each block holds 32 bits of data (hence the binary output shown) + +Since we know that the card has data and configuration blocks, lets say +away from those while we learn how to read and write. I suggest you +follow along and perform each command and check the results as we go. + +We can store our own data in blocks 1-7 (remember that block 7 will be +needed if we want to set a password). + +(Don’t forget to run the detect command: lf t55xx detect, and ensure you +can see the card) + +1) Check what is stored in block 1. The following command can be read + as, run a low frequency (lf) command for the T55xx chip (t55xx) and + read block (b) number 1. + ``` + proxmark3\> lf t55xx read b 1 + ``` + result: + ``` + Reading Page 0: + + blk | hex data | binary + ----+----------+--------------------------------- + 1 | FFFFFFFF | 11111111111111111111111111111111 + ``` + Note: Depending on the history of your card your data may vary, but + should match the dump data. + +2) Write some new data into block 1 on the card. + + We use the d option to supply the data ‘12345678’ + ``` + proxmark3\> lf t55xx write b 1 d 12345678 + ``` + result: + ``` + Writing page 0 block: 01 data: 0x12345678 + ``` +3) Now, lets check if the data was written. + ``` + proxmark3> lf t55xx read b 1 + ``` + result: + ``` + Reading Page 0: + blk | hex data | binary + ----+----------+--------------------------------- + 1 | 12345678 | 00010010001101000101011001111000 + ``` +4) The data is written in Hexadecimal. A single hex digit holds 4 bits + of data. So to store 32 bits in a block we need to supply 8 hex + digits (8 \* 4 = 32). If you are familiar with hex and binary do a + little bit of home work to learn. The following is a quick start. + + | Hex | Binary | Decimal | + |:---:|:------:|:-------:| + | 0 | 0000 | 0 | + | 1 | 0001 | 1 | + | 2 | 0010 | 2 | + | 3 | 0011 | 3 | + | 4 | 0100 | 4 | + | 5 | 0101 | 5 | + | 6 | 0110 | 6 | + | 7 | 0111 | 7 | + | 8 | 1000 | 8 | + | 9 | 1001 | 9 | + | A | 1010 | 10 | + | B | 1011 | 11 | + | C | 1100 | 12 | + | D | 1101 | 13 | + | E | 1110 | 14 | + | F | 1111 | 15 | + + To use all the bits we supply the data in Hex format and it will + always be 8 hex digits. + + Lets try and write 89ABCDEF + ``` + proxmark3> lf t55xx write b 1 d 89abcdef + ``` + result: + ``` + Writing page 0 block: 01 data: 0x89ABCDEF + ``` + and check + ``` + proxmark3> lf t55xx read b 1 + ``` + result: + ``` + Reading Page 0: + + blk | hex data | binary + ----+----------+--------------------------------- + 1 | 89ABCDEF | 10001001101010111100110111101111 + ``` + +### Exercise 1 + +Using the read and write commands you have learnt see if you can make +the lf t55 dump command show the following data for blocks 1-7 (Page 0). +Do not write to block 0 or try and change the data on page 1. +``` +proxmark3\> lf t55 dump +``` +result: +``` +Reading Page 0: + +blk | hex data | binary +----+----------+--------------------------------- + 0 | 00088040 | 00000000000010001000000001000000 + 1 | 11111111 | 00010001000100010001000100010001 + 2 | 22222222 | 00100010001000100010001000100010 + 3 | 33333333 | 00110011001100110011001100110011 + 4 | AAAAAAAA | 10101010101010101010101010101010 + 5 | BBBBBBBB | 10111011101110111011101110111011 + 6 | CCCCCCCC | 11001100110011001100110011001100 + 7 | 0123ABCD | 00000001001000111010101111001101 +Reading Page 1: +blk | hex data | binary +----+----------+--------------------------------- + 0 | 00088040 | 00000000000010001000000001000000 + 1 | E0150A48 | 11100000000101010000101001001000 + 2 | 2D782308 | 00101101011110000010001100001000 + 3 | FFFFFFFF | 11111111111111111111111111111111 +``` + +Practice reading and writing to blocks 1 to 7 until you are happy you +can do it and get the results you wanted (i.e. the data you want stored +is written to the block you want it stored in). + +## How do I use a password + +This can be a little tricky for beginners. +***If you forget your password you will lose access to your card***. + +To tell the T5577 to use a password we have to change the data in the +configuration block (0). To help learn this and make it as simple as I +can, please read and follow exactly. If your results DON’T match 100% as +required, please do not proceed. + +1) Lets start with a known card state and wipe the card. This will set + a default configuration to block 0 and set all the data in blocks + 1-7 to a default. + ``` + proxmark3> lf t55xx wipe + ``` + Result: + ``` + Beginning Wipe of a T55xx tag (assuming the tag is not password + protected) + Writing page 0 block: 00 data: 0x00088040 pwd: 0x00000000 + Writing page 0 block: 01 data: 0x00000000 + Writing page 0 block: 02 data: 0x00000000 + Writing page 0 block: 03 data: 0x00000000 + Writing page 0 block: 04 data: 0x00000000 + Writing page 0 block: 05 data: 0x00000000 + Writing page 0 block: 06 data: 0x00000000 + Writing page 0 block: 07 data: 0x00000000 + ``` + +2) Check that the card is in the desired state. + ``` + proxmark3> lf t55xx detect + ``` + result: + ``` + Chip Type : T55x7 + Modulation : ASK + Bit Rate : 2 - RF/32 + Inverted : No + Offset : 31 + Seq. Term. : No + Block0 : 0x00088040 + ``` + + If block 0 does not hold the hex data **0x00088040 resolve this + first before proceeding.** + +3) Set the password we want to use. For this example lets use the + password : ***12345678*** + + The password is saved in block 7 of page 0. + ``` + proxmark3> lf t55xx write b 7 d 12345678 + ``` + result: + ``` + Writing page 0 block: 07 data: 0x12345678 + ``` + +4) Lets verify both block 0 and block 7 + ``` + proxmark3> lf t55xx dump + ``` + result: + ``` + Reading Page 0: + blk | hex data | binary + ----+----------+--------------------------------- + 0 | 00088040 | 00000000000010001000000001000000 + 1 | FFFFFFFF | 11111111111111111111111111111111 + 2 | FFFFFFFF | 11111111111111111111111111111111 + 3 | FFFFFFFF | 11111111111111111111111111111111 + 4 | FFFFFFFF | 11111111111111111111111111111111 + 5 | FFFFFFFF | 11111111111111111111111111111111 + 6 | FFFFFFFF | 11111111111111111111111111111111 + 7 | 12345678 | 00010010001101000101011001111000 + Reading Page 1: + blk | hex data | binary + ----+----------+--------------------------------- + 0 | 00088040 | 00000000000010001000000001000000 + 1 | E0150A48 | 11100000000101010000101001001000 + 2 | 2D782308 | 00101101011110000010001100001000 + 3 | FFFFFFFF | 11111111111111111111111111111111 + ``` + ***Important : If block 0 and block 7 don’t match exactly, do not continue.*** + +5) Now we have a known configuration block and a known password of + 12345678, we are ready to tell the card to use the password. + + To do this the datasheet tells us we need to set the 28th + bit “PWD”. Check your datasheet and see the entire table (remember + the data sheet is your friend). + + ![](./media/image2.png) + + We will cover other things in the configuration later. But the key + note here is we ONLY want to change bit 28 and nothing else. + + Current Block 0 : ***00088040*** + New Block 0 : ***00088050*** + + To understand what happened to get from 00088040 to 00088050 we need + to look at the binary data. + + While this can be confusing it is important to understand this as we + do more advanced things. + + Bit Location (28) + 000000000011111111112222222 ***2*** 2233 + 123456789012345678901234567 ***8*** 9012 + + | Hex Data | Binary Data | + |:--------:|:---------------------------------------| + | 00088040 | 000000000000100010000000010***0***0000 | + | 00088050 | 000000000000100010000000010***1***0000 | + + + + See how in the above we change the bit in location 28 from a 0 to 1 + 0 = No Password, 1 = Use Password + + Note how we did NOT change any other part of the configuration, only bit 28. + + To re-cap. + We put the card into a known configuration Block 0 : 00088040 + We set the a known password Block 7 : 12345678 + We altered the config data to tell the T5577 to use the password. + New Block 0 : 00088050 + + If you have completed all steps and have the exact same results, we are + ready to apply the new configuration. + ``` + proxmark3> lf t55xx write b 0 d 00088050 + ``` + result: + ``` + Writing page 0 block: 00 data: 0x00088050 + ``` + +6) Lets check what happens when the password is set. + ``` + proxmark3> lf t55 detect + ``` + result: + ``` + Could not detect modulation automatically. Try setting it manually + with 'lf t55xx config' + ``` + Note how the lf t55 detect no longer seems to work\! + + In this case, this is due to needing a password to read/write to the + card. + + Lets try again, but this time supply the password. We use the option + p followed by the password. + ``` + proxmark3> lf t55 detect p 12345678 + ``` + result: + ``` + Chip Type : T55x7 + Modulation : ASK + Bit Rate : 2 - RF/32 + Inverted : No + Offset : 31 + Seq. Term. : No + Block0 : 0x00088050 + ``` + +7) Write a block of data with a password + ``` + proxmark3> lf t55xx write b 1 d 1234abcd p 12345678 + ``` + result: + ``` + Writing page 0 block: 01 data: 0x1234ABCD pwd: 0x12345678 + ``` + +8) Read a block of data with a password + + ***\*\*\*\* Important \*\*\*\**** + + ***Reading a T5577 block with a password when a password is not + enabled can result in locking the card. Please only use read with a + password when it is known that a password is in use.*** + + The proxmark3 has a safety check\! + ``` + proxmark3\> lf t55xx read b 1 p 12345678 + ``` + result: + ``` + Reading Page 0: + blk | hex data | binary + ----+----------+--------------------------------- + Safety Check: Could not detect if PWD bit is set in config block. + Exits. + ``` + + Note that the proxmark3 did not read the block, the safty kicked in + and wants us to confirm by supply the override option ‘o’. + + Lets try again with the ‘o’ option as we know the password is set. + ``` + proxmark3> lf t55xx read b 1 p 12345678 o + ``` + result: + ``` + Reading Page 0: + blk | hex data | binary + ----+----------+--------------------------------- + Safety Check Overriden - proceeding despite risk + 1 | 1234ABCD | 00010010001101001010101111001101 + ``` + This time, we can see the data we wrote to block 1 is found with the + read command. + +9) Remove the need to supply the password. + + To do this we need to clear Bit 28 (set to 0) in the config. We have + this from above. + + Remember if we don’t know the config and write this config to the + card, it will over write all other settings. This can recoved the + card, but will lose any settings you may want. So it’s a good idea + to read the config, and set bit 28 to 0, rather than just overwrite + the config and change the way the card works. + + In our examples we know what it should be : 00088040 + ``` + proxmark3> lf t55xx write b 0 d 00088040 p 12345678 + ``` + result: + ``` + Writing page 0 block: 00 data: 0x00088040 pwd: 0x12345678 + ``` + Now check if we can detect without a password + ``` + proxmark3> lf t55 detect + ``` + result: + ``` + Chip Type : T55x7 + Modulation : ASK + Bit Rate : 2 - RF/32 + Inverted : No + Offset : 31 + Seq. Term. : No + Block0 : 0x00088040 + ``` + Yes we can and we can see Block 0 is the correct config 00088040 + +# Part 2 – Configuration Blocks + +One of the things a lot of people have trouble with or miss, is that the +T5577 has two different and separate communications protocols, each with +their own sub-protocols. + + - Card to Reader + - Reader to Card + +In Card to Reader, the T5577 will encode its data using the settings +from Block 0 in Page 0. It will use this in both default read mode +(where is sends out the blocks from 1 to x on power up), as well as when +it responds to commands. + +In the Read To Card, the T5577 will encode the data using the settings +from Block 3 Page 1. If the command is not encoded correctly it will +ignore the command and revert back to default read mode. + +## The configuration Block – Block 0 Page 0 + +For this configuration the settings chosen will be for the purpose of +the card when used in production. E.G. If you want the card to act like +an EM4100, then we need to choose the settings that work like the +EM4100; same goes for others like HID. I am not going to cover these +here, rather use an example. Others have collect these and posted on the +forum. + +To get started lets look back at the tech sheet. + +![](./media/image3.png) + +The non-password protect EM4100 could have a block 0 config of 00148040, +so what does it mean. + +To decode this config, we need to look at it in binary +00000000000101001000000001000000. Note that it had 32 bits and the +config block 0 is 32 bits. Now we can break it down. + +| Bits | Purpose | Value | +| ------- | ---------------------- | ----------- | +| 0000 | Master Key | Nothing Set | +| 0000000 | Not used in Basic Mode | | +| 101 | Data Bit Rate | RF/64 | +| 0 | Not used in Basic Mode | | +| 01000 | Modulation | Manchester | +| 00 | PSKCF | RF/2 | +| 0 | AOR | Not Set | +| 0 | Not used in Basic Mode | | +| 010 | Max Block | 2 | +| 0 | Password | Not Set | +| 0 | ST Sequence Terminator | Not Set | +| 00 | Not used in Basic Mode | | +| 0 | Init Delay | Not Set | + +To get more detail on each item, read through the data sheet. + +Lets see how the proxmark3 can help us learn. We will assume the T5577 +is in the same state from Part 1, where we can write to the card with no +password set (if not, review and get you card back to this state). + +1) Lets turn you T5577 into an EM4100 with ID 1122334455 + ``` + proxmark3> lf em 410xwrite 1122334455 1 + ``` + result: + ``` + Writing T55x7 tag with UID 0x1122334455 (clock rate: 64) + #db# Started writing T55x7 tag ... + #db# Clock rate: 64 + #db# Tag T55x7 written with 0xff8c65298c94a940 + ``` + +2) Check this has work. + ``` + proxmark3> lf search + ``` + result: + ``` + NOTE: some demods output possible binary + if it finds something that looks like a tag + False Positives ARE possible + Checking for known tags: + EM410x pattern found: + EM TAG ID : 1122334455 + Possible de-scramble patterns + Unique TAG ID : 8844CC22AA + HoneyWell IdentKey { + DEZ 8 : 03359829 + DEZ 10 : 0573785173 + DEZ 5.5 : 08755.17493 + DEZ 3.5A : 017.17493 + DEZ 3.5B : 034.17493 + DEZ 3.5C : 051.17493 + DEZ 14/IK2 : 00073588229205 + DEZ 15/IK3 : 000585269781162 + DEZ 20/ZK : 08080404121202021010 + } + Other : 17493\_051\_03359829 + Pattern Paxton : 289899093 \[0x11478255\] + Pattern 1 : 5931804 \[0x5A831C\] + Pattern Sebury : 17493 51 3359829 \[0x4455 0x33 0x334455\] + Valid EM410x ID Found\! + ``` + Looks good. + +3) Now lest see what the T5577 detect and info shows + ``` + proxmark3> lf t55 detect + ``` + result: + ``` + Chip Type : T55x7 + Modulation : ASK + Bit Rate : 5 - RF/64 + Inverted : No + Offset : 32 + Seq. Term. : No + Block0 : 0x00148040 + ``` + ``` + proxmark3> lf t55 info + ``` + result: + ``` + -- T55x7 Configuration & Tag Information -------------------- + ------------------------------------------------------------- + Safer key : 0 + reserved : 0 + Data bit rate : 5 - RF/64 + eXtended mode : No + Modulation : 8 - Manchester + PSK clock frequency : 0 + AOR - Answer on Request : No + OTP - One Time Pad : No + Max block : 2 + Password mode : No + Sequence Start Terminator : No + Fast Write : No + Inverse data : No + POR-Delay : No + ------------------------------------------------------------- + Raw Data - Page 0 + Block 0 : 0x00148040 00000000000101001000000001000000 + ------------------------------------------------------------- + ``` + We can see that the info gave us more information and confirmed what + we decoded by hand. But remember, the detect is still needed so the + proxmark3 software will know how to decode the info block. + + We can see that for the EM4100 emulation we have two blocks of data + (Max Block = 2). On the T5577 these will be Blocks 1 and 2. + +## Exercise 2 + + Using the skills form part 1, see if you can view the data in blocks 1 and 2. + + Note: the EM4100 ID of 1122334455 is encoded, so don’t expect to see + those bytes as such. To learn how to do that, you guessed it, find the + datasheet and review. + + At this point we have a EM4100 card. If we wanted to password protect + it, we can follow the password section and update the config from + 00148040 to 00148050. + + ***Important : Don’t forget to set a valid password in block 7 and remember it.*** + +## The configuration Block – Block 3 Page 1 diff --git a/doc/T5577/media/image1.png b/doc/T5577/media/image1.png new file mode 100644 index 0000000000000000000000000000000000000000..7a985275b2ed4df3594ef5c28bd54f7ee47566d9 GIT binary patch literal 44034 zcmdqIWl&r}8#M?a1ouF2LI@DtU4y&3`!Kk>B*ER?-QC?G*x>Fuz~JtD)gJ5yIP+6oIdAyL45!~K|$NXe|ksI5UjS| z{}AjXG##O!Q2YP=pc80N3En|CCrMdRxE(lnI1aiexV5JLK%yE>Kb@V-Z5^OWD#s+= zA!Mg_NW|39*a2wg1hln*!a^V=d&d#~;lj3d?hZhJxf4`5+8Fmciuxba!PM|y)vr!K zYf~t;J2Zs%D+vFtDBGGjxf(i{Lh0JQ{i}}jpT>cX##V;!RUM$3y6dCfVfcTrx}k#& z&;|h2O|T#Ij=}ve_d7cnn?l{Z`9c0$P1x4j+SJAg>UJ!#>mB>_ubK+b$;uR}_;i{Q z3hFDAq{vSdxAfyRR~_}ax9*DtK=sFz54G5z?YGufbV?NW`(sQakF_3i`r>HkdO5e}O%Yom{(4P>aBLtatF&G$8JbbB*h zaxBWJsPCKuc%eH~^s|8d^iGV?Su9m|kyS$dtcyKdZpMkHU5dmBHeVu$MTv z^Wk}wcsMmjzv6(ism2{Q7yT}>1r|{j=iRp&f$=|=3{l2M3~}xafqa8Aqqr|i_{^`S zaHrCF!bL0?4c07R>|a*5wy$ZQRfFV;+?6U2{|)go&7CaB=J?(pI_}P}x;}qXWw3wi zg06V&O524%YRke={II+(UsEmH%fOZY^~QJ|m-7!vP}87Xo*g;qZwMOb`4!LmtLldv z+;5H5d(;M@rdN?4<1v4#&^r#9XK?*y%W^6#Y~oX!kG!8h9lUQqNQRF8xZkdqwS4n* zwKF|&s5lxH%Z_@_<{lQHs7OmV9qS;+9&cAM7KX)c|Dfhu8=}vasTVQ2V*v<=s1vvm zrmWsCr@DJ#Rcl}SwS3dcWPb#o>ao0~!0!Kh4WiuUVjNg5(Sofv7&uj5uABDwV&-@& zY0dDT)r4>-2U6l-^w{JeY&h!;y4De6sU)h=x9W19m`rYLAFS#u+;*Kz9>c{;Il z`89i(9KTv;qKT1o#M|rYnLT&XDxm0uMr?MkyL+8KqV;=nWJe~Y_!9|SXmxlXYnkR+ z#Eo#~i`IEO8&JGiLw%+XdWmA!9jq}pb8b&_$qvx}gb~JHs0?|#7&3)rwBPIhiF%A= zJngApvm?Zf$E~0G5yFX66UKElA03xzT5Y;z)hJ3Ric;(+6NB}>tun1$edlN-%YEKZ z3I|)JZdOPTZoCxOvx_d=6dIeE$;oRcGSnUN@B*BHs2i0Z zo%gJkTwl7^_6f41q$$iykENVI?!EhnD=pW6llelOF@iG}!i2J_lZ)KZ&IbG}0Fart z146nJqB<(c=I%JH6hzRjB2?pp$CodJ_1RaYk{!(4lgm3tMli*=wJ1M^d6w+Q;Bjsa zF!7V)erbKeTrS|p!R2bS?t%Sy>oQ>?Bj6FZ5S_2Dlm+TYP88&b~=H|BbbsQ};?i;JVV7AevW(PLk1g%l`fkd@6?j4#W*7uMZ z3|J@9zr&}Mitq2tN6`}IK0G`$F$0@mgp!7Z(~=tm0G#hes<`+7W}woTHS|Kg^hu5h%P}piEG4aU)U%QEI_3KTQWH_?4V2$n1COP6-qw0SlA9?q!bHU?skVIWVT6*+F z(r{y_VJeU8pd&(Ok^7HSE3FzDbx>LwWrk13`6f=S>&2317kWlPuFlGMKKR+r(XnrQ z9A)B*@BS**IHd?6Hv zFFxjuJp^vO$Zg9v`}ab%Kkx6lKxz9@cj+JVROR$!vczs7L`Q>iuv)UwJiRuYIPa&Y zyw6xG3Y>m@jfe`00@#Pcs_MUlr1X_O*X<%pTZHTMpY>_)B-I4r?eLqdhOe2#AO5{B zaKzKu`neDwJ(;^O8b1f41z2`D3mz2+75?|SdSinXAkEfbiox_vK5*1rOh70swH+Rc zZJ}Pk3J&M(bG9U*R=?@nA_YTCt$m{`=(_g&mF01W-ZJP>qeyZ8v!C5#)3KQr?#97M zvO|k3cW{ZKX4@yz%OJ03pYouP(`A9K+DZI^$z=wN#$-VL;Bu14PQfv@ryN2kY0LQqEpUpoFuV zqQBd_%fRPW=09PfG(8O0fJr3m>K6{{Os)RnC^d)q^1ix0jm`t2U{tIr$92GVs`QUm zW~WTn7O-IQo{*X6hqV*ozCI8>7 zka_OMvar#GcHz(&WfdT0%FQ?FHT|`aO2qG8685c|QAi=MApL}35V{A3UULUmISI9| zw~IRz+PTOvq+Vj#v&5-8FUE+N6Fq95i4zn^@Mr5{a_(_KE`??LAP~L# zzA*ZIr&*HH*Gx#56BZwIf5hC0lBZC-h#8cr^a&#w>~B}LJhwi>Ypz$g?Qs#UxKdy& zGQ|(#JZaQ!Gq!5!y0bYg-=X7&)go8S^y?rQ8F zm2UMKd%Hw`RCOrC#NLI|r;%+Sn_NGdd@euJ{IEwmYW6%#Ui2l!$DFF8&Ntus+_PM} z75ee!ElFEEEU%7lfvmBb%^AKbxv6?D8V?R2Ua32QB{bdfXuLnR?_Mr@o~K#C+6%Vc zi&Zv$>|DZmnb%KgV8VFv=y1!kWFu^V`b2-M*V{e^C&AjL)UiY3&wksB8Gyv|rIva* zWw}QkULP;YlAMHUUmV9E2epdRq} z;`sFQ`*L_Cm<5DWJt{Y328cCSa;c#pp{e)v_065LY0njZt}DeyD>1gzD1ICvDfO&X zWivflu@JS4D0QVRQ=>nt^l)!2^T>#L9DJl@^SrZb$Xyqzc(^c}D=say-!N||4G6&J zr4V8>vsK+dm@LDoJS`1FRRu4}qwri6J$8k%m(C9gSDr@>_p0{04f?Dr&q5%Z$xCf9K<5He149rsLpx40va+hbSn3p|ae~T?G6=QRd@@%NrD@!~tFIKy3RDSP*McWx_nWjZ!>rDof zs_j;3YukZ}Q>H~0Q-`X2Mt~MTDBnU!mF?*aZT4%2UInXBQ))&R*3m&JPO0e4t%bHN zQp0tb;ZXzu&8+$=txA{6$y_N8jzvUGkjk8s&`U{1U1^<@vY*9*!YJo~N`-PT_e;Cx z_&Spc$}B_$jYME>ysP%;%p}L6{Lk!Lh2(?!iu!vryl={!BKV+UV}(BvcCs?l>Fv4P zH5ru^wa$bf+cI`Z0>I2GnP@(lA`DyaYu2KO7dIb>-xrG-Xj`f^`nZ?q1-j<+D-o?nYeGs@`cW0<(6u`SIW@=md~JF?EI2n6r@}C zDmx()ar1q&h$yj48;czGTZ)QnJvD$l>{WNhT#a z#;fkyHu4l6@CZ?z)a8*9DQ9Z>B_$SMcpT0rcD<1`HTEr1bAw@PJMS6meH787mRM5L zfz_5=iPh(Jy?uQM`h0#IrRy=Dr~sVq+yoi&FsX1_zd>o>RMqXynN8IIo}!Y&k%l7q zArIC{$Y_W$6Yit~zZb1-Cs$?{y_TTG=b)V{iU6P$E?@MSyz1WEf}bQ;#vg=)`Wd+3 z&UjF33>|RwJqY5n<;;LR9r$Bg!zT1SGVhwWr(6fWiOn^7@TUE3C6%>2;;b{JsB6p= z)i0yEvDGzX!+gkoJ$NqB8Yiv?HFKIzKB*K1w&Cbfsi(71fAYhaxqu;*n%Z92hCSkj zYMgV=QFV7(K&@jKadRY_?vxilVyl$?WsK$FOdsU&BOF^1PP2mowbZq6CBwIEB_rE# zCiMVhWw>8nkv_MO3w+^C3ZZ*}x05ynClOt^+!oGp1Th))n>T9;ia!+6QI)}sI*bF4 ztH_>A2rmjf8_56V!$cFu*Z3Wts#<(+UawpL_bw+k@){awDJAA%vF>RZC8f)gk1}~b zVQ^)+B>lNwKH(uQ?p5@Hh~bESeWH<;X2rMU^($2z7xhzWL6m)JQOa}5d|pWZo5^>9 zTS@S+y%*>e^K`i%rFD^LjC{7S6msqD_38khM>cYKI?dQ=4!*dr1y<0=5~%x2hG~3M zfvkQ6T!p9c(NqgaLLE#(97ilze+BRZ`l;oA;cIJ4Wk-AQpXD5n zrP=aYAaOs+t1ETetK0fy?T0kb04!xh$c%R1VzVy|i_dGEKM#W|u)!RvI@e`XjI%5x zUBc;Wb0N*tj5y;lgh;1uv@XPX-6@qb>EQ~@;`{2g@3r^=u7ccoBL$S~Ld^TNMB#G0 zItv~sL_tCv71DHc!4-sZDf8Cul#UDwckP1i)1_Y9rPT<0rh(ve=`Il zZ!jrv{KI89KEH`C@vP7Tdwoehc=}QvukFCrg)Xc6UKB8;j<_|jnFfZ{dgmZnQ|c%M z+H@#zV9-u*C+S-2r&V88tVvk*yx)|#5%^vN?4wP*p{vwVTKvO zqt^F@Z#L29C)Cbo^Zu22fH`!V{ZSzBCy>6?F*~qWZ^p^&-2#D(rm<9WQ=MY9~ zPdmQ+dxDlLB`a(EGIfOcepzfu1Z3Aou_7-8H(k6x#3AB zOSaz5J*c644MY4$Kn~PhD#voPVmZY7$S1 zQfZ|W01=6-ylI_T&E&&on!}Ec(;+|qB~X2Ud^roJ7tjHR`f#y4g>VRzRIrzjhL{|4><5n ziIiMoUwHT{7UmvZTvLYSW7&Vle-9s1JJ4YVsazM%(xoT@5_Kgt&rIj~dLycpj_i-f zW)ojWxYt0HC_F)m4G(CGzFxs6eifW4I{m3`*mDvF}c*sOBF zlC~4UV$x&OVW7l?xf8u9{B>1$j*$2=GX9`6NWPNJI|UUv?I2PW%as+4p8j8eVjH-x zE&RtaM5eAbvOfO{TJRUhG5<18fAn1V|F;TMgA?<#h@X{E$G}6H+MH!{(kriLlMNQb zy{M(=R62T3Tml7m+j*eQ14JG|Qh>V-~CDlP`(HGQEvLaC#)qnAj%{>m$KWe)>Mz z<6EPfdUaTSpBno%TJ8F<-%ywx)PiM(UZX$^aug#CpL*1Ia9_P_3$xh2xM&3Qj}1iZ z94rF}%c2Uup?P5oeRdx)RcoL6qmH9XS*_<>-qx1W=?Abv+9if%P?68u8|@2k#tIDaLpQAz3Ok$D5h8v@SB{ z!c}-$)JgVVJF5FIgo1+%gUOi-V0QrCqmWnb`1z&d;#as8mZzO+M0HWp}N8h<}LsvbqGt&T9yRht8G;mJ|gMq-^$_$v-d_$&cIHk+>M&TR|hIi#>OT1ds9!&p$b5J13|Z<S`DoEoOQQ-^=|05HkHh)^2Y^ zn(ct&Af+=wI>)t%EQ)ll-)>sN|ET@mP7Bb@5XYyvjOy%8s4iryJf{-L@6Q?n5c zrLl2H1dn{`Y6TT>AT{E|4c`&ix?L4;7HR=Ip=4n&foCD(VhE?2TswRI+G$Y{g;qA0 zR#lFd?ZM;R^$^D0y&`$i$*HS4N9#NeWjj~$WJE=|m!BR_lkXsQ(|=Y~)>CO?@nDgl z$^fu!*jtP^GIdORT=+_&3P(?u874&Sm08Q~%G628fZ;8PU@$5Dh3S<^;d7 z?|l$Y@)<9ct-*b>*4>{Gp-msC`F^z%j2vDRl6-|RLxBodiwPf6DmXl1lFRU9_Ke^% zq}!r-^Rb!`XeTO5$=98Eu$154DY++sjT<{$oOyfo6$vg9l{9!r=JyW_#Kd2Y%k0oM zJ})NGbfxA2d(S8qqCG^5UcBwPnSS#CF$PWu^!V{-c$<+ai=h<0{knT_FlFU<{b?B` z6Ig-C{an35lC0nlQ zO|dHd#<-Zt&-jY6_DW^mxENw1WkJXkQ#9;BdzF4QRLZa=GK?9(G0x$6CQqyLgp27$ znu)WAA7h#1xLQC*O3E-Q%E8?W_Sg2PH*;|1( z(&cA1(I?~a*+z}>#(^AcE?7a46b3Gpa(m2Tv17kg=*}FT>eR`&Ja&ZHgE{BYZ zBmqT5NmkmYV%=@Nz}<=3qkQqQXv)crBGNil&q7Q5MYZ=M$n|t5^hnfw;REWW6h8Q_ zg7WBEl~oSAWV)ENzntgF!R9r+ zVlk;&_mhy;9s^Krc_BAAxOMrt7`lCdL$|E8wy8JC2mb0{hyQ z-WqpfjSdDn{kf3_zUPYvN-Kc^BlYS2lmz4Cj$_7@AFG^<0ZUz#WOLKdOVOH?|N?J|P_)>i2cuxYv2*Mm;AET`&SDZ4LM8hm@wjhS;s0LK6_ z76G&I7-X3R%$CHG=nRL%cu1kwiRl2y5OjycRm5pHWZ&p55ExN|ry%G((xChNaPx&w zqBhsx!9Rk=CDy&_Sw@oFY~9WWEy^zzH92a+6tut+GV!;>b1q(f$w4eAVxN=8=RO#v zCdIYi;;Z|cS0iz|il8p+%lIXWh&*8Z_{3zf)i|vsh)v&DSS0iVp7_%JIA`M^%_5he z(LLvWIcI23ved|&%V^n)bnB~bY9ro|TprEo5(M{BN4+q!neVnh z4;i2lRO#h865&w!F!K#UVGN)4%Kf^}iiuijFmhQpYoiCQ#9A7X6$AO-qmA;mrtCCE z9BR&EK26h|Yd0kO73t;5c8_DEUb5m|3;eO}If&`MqcN6XU+AB%!Ku)*m1}_F`HB@J zjbYUh9baU|qV7sZIa0#o_bFgAAJ!4Y)6Azc+<2nJXtkcCNlpNL`Y%GoG-6TKhS3U9 z%^`2Fhp#v?REZV^9QMvq=V%)E^fKpv%h}WUFSA?qdKY$leCxQ~j%-AQA6r;VnrE{uc2M0C%>Oh^ z=&6k92vmpru`{q3bcb;Qf0h7;%7@E>fgGui&hyolzI<8@6&HWs0IqkoU#zL?y>>nP z-Jsb*WdG|0a9Xl@&SvH}X3I8<@!*R4)ucArCqHyzd2O~0_8L~IVj|Sw^{?e-bfy-K z6VtD@Ggq}Lr0w=Oa7heD78)|JXb%6%%mhF!Pi_C5L*zr6dt#*~YZU_V4lGyd6T7^m z^hNjW_$FM|cAl@!ny@Pq{6@V;&E$z{pn`m?%?OJk#!QFF)wP2@{^2MahLwEHeyrnr zVNGL?5|g2tGiMUY?(rjVOg}~NvS2hHU}E&9v%VB%7R#WQYmy=;wNG5`R6xCH*!Fu@ z8Zg|s9o`n@4VrA5CzdC1tw&>$m(`xehI@fIl4srt{j{QVx~t!)b?F>^h-ePc zb8Z_r$F`L}v7$=5QvAe=VG3_V<#={=;W3NJGj8)GLF%VA1$R~QbYRW?!G1#`Tk-SF z+THd&i511JNgSA!#1t-mPi6#iLg1B+yAEP=;=$q#<*oBeCd-w_RQ?2fso41U{M|T6 z!+Y}cEKWtm!|AXZk&ViB{+H;7W0SP;P-9ncr&?Hgy-3^}vOH|O3F`QxzjZ1qtL+PK zrq6nQxm%d*gT+F2Q+0QI#@!z+3b8y`H5~HpZ*gPDu#?b;nkgx~v++6=f$2f!pB1`Z z_c55?T7W$_kSWMX$+9ngM(Kw8PS5xZqzy82c=KS)NWkQH7lDK?E$vij6@GLgPf&|; zKuFu2ZN#2pGf;$E%XCP0R=SgOG!k)D*|kJe4?=PCQK3uCf=xO z{hW0drngS+H1AhGczEnjOiq96)AX(+)!y3$9u?D_CI9PSV^n$(>qCteDt-ap_KT%2r~Jnk;8 zPJ3Rg06jB>(*HdTnvBYm-A+jxTK`OtT4f%y>4JgYEP0r}DMt5+fmg@jmhr~(vs3p> z?v#bXXYw~)kcYtY^G*6{O$d$HFM@Q`r{olAwD+WdI7%u(A&&zi$>I}v!hHwEosO9B znKHI*pARZgYd9XG?)pfNInnx_H&j4A*$QVCbTR{G3nk_X;@la5Wsfr-G7Gpb@bcxl z!@M1$RJKz#O9l8jk3v@Y`{zOKg5$jrNQo@P{wn!yPbLzu%daKJl=p)>ou;AlMnJhv z30ObhsG%eMol6*c55FjCV86xq#^(iV`;bLv6?8fN<;NEtstI5`He2cf8H*PM%|t2` z3?+ENq@$Bq_7BZeb0wShmx}K_$R^^<1?nuH#^pb%6;u$AmQ?P9V-$J7Y{LLUR(Ji!avU6#k%ms|ZDh)mxuvJ4`@ ze>)xBIBb7;uPf7f!5BUD6e&l%1QN0a>4y|u6CgMd<{N!*1W)Tu#dmmR6lf+{ zVJLXR6z%%==v|oEbSGhbhXG>`s$1hfiLTyt8JyYMr(`y)4Wps}3>y83)wWfKrWw8` z%Kn+?@zy3Udp8citgi8%R03+&1q7~PvhGxksz@&D@+A?}u35*6C7srijMLq{Q8*2% z{22ZcnZ$#VZ?*|=OJ;~u^+xWxqY>UOUPZH%p4qz!p)D6kM@wWg)?1ivf}HS%*v@y2 zZCd=4u^azNTJgbloLD?;sD@bqnzfX-<+^6tob}R5_JSlkIwMw4Di9mBKw5e7QaiBz zqf#ZL#`P}SA65`2De{bGvek-JG zXDx}*R)>GcIgc)q*rsLFhqqd&wknfs?jSfU&ASIszN9YMnjQ!mMgs64b^kpKu)QdH z)qQMgBx9RF1y9SZ9*O;|Syx>kQ(~5AbNh`PfkjUYdZ0H>tt59Kp9^-TvL%#Wak$;d+?aB$b~?|g z7hYF)G8v#Xki2KYXGiU2HbrYQ?kJh+c_9&XaD73`Zs=K`dE>X$G63HeL(tyuz1+*m zZF1+h24{ zU_##=W}%D9giQZbq4Az@J%=w<>wfe7Ss#C0A`=mm;eL)Q;XvWZ8HsMWrb7@8^Xf+{wZKS0%tb<gx=Yy7aq(WKZ`ggi# z&5V9wf<3W2_IY5s3dfQ4>NO;SznFz2;FG{W_P?V((ojo>!kRv6Ad$ecT`D4jYxX4{ zj%cl&w6Dj-j}k(Cg2);@SL&9}LwoT3ETqnSaqB5POgn3~hcKSZcX3}bePjwH%sK@K z%9{A|04>i?iBuk_WM)Tr&zc;}0F)iqHd2|>^zn2ImMOH?@XWoj^o?5%D(5ui8 zTSQ3_aeWhiIc3G*1AJt;@p~u-a3MZAiLH`6U#?i7>VLXR&A?@?CVG{3)2GYi_;}#u zzBMYKc^ycgej;@5wQT!*tNof)@@9GNWTaS$+2z4Zqjt8Zv_At>3a0FBrA6ThM90Jw z3hGv2uaNKU@&=s|rNuL(Cyym9zKL@NRVJT#NE@H{2L+KOCQGiig|Y?3{WOk<3xbPG z?7o3*f7k{ezYc+c6qt8`HK*nlJp-@KJVLyA@s=W$x*+?cMt}cy!J$SJsyNoD&WhKe z($BDCA;-E6fqlboCLU2j)4v7a1)KufqEOwX$j9~)5@9rb@(57~9^+a!*;4Pc-4<9l zNt(8~96n_`7vA{W9$w9Rxab{91Z$J-mJCWXzHTfK&OUCN$K717eA%|Ir56vg;iAbh zwOs{?&!Dg#;Y)d13QC$h{b5wOqp^C1@c!fr!o;@=LAm-;%YTVE7;9=id&9;J%aa2e zzw1Yv(Gb4|R%uVWGusSHsD_E3B`Z&^2_{0I)W~bR8%vI` z9*tOL{Ap=n(G%ascJPWV;0~kx2witEv2>6J&NcPX5*OIU>4Jl-$d|#J)z_U++BUk zibZyTMW>b-#f4qsEvqNrL@x3M^3*7WgdIubr^d7Du%9p+M+GIyp2^20pEOvF@jMwU zE`W;}K24Emh{JG6%$A2XpptdgGrs6AG<&|E;v9e+(rOul9Qgz&tF~v>B|Hll7`&ks z0-XU-IAakJtmgH}5qNwDFXmC--23&u08r_0`R-qh+|O&3sv>s`jqqW-H0_^@N=vDqo#n+E}ewA~VF)SL+s-c3UcC z`0PE~Wjb&{)u_4;xA6pfI#*yA5Z^uqNoHK~Zy_lY)(}vp8{Zb(7|upaU2b=87GeXG zv6P|sw|-><(JRB5(`(XRPlxOG@!pQ2CB66fY`sqAlBbNZF61oiPBp}*spE*4=I@~uvhb%z@B z?oG{wG0Ao$R+v&PK&YIYoSQn9gr3veAv~~qNAm;K7VxBW5cFN$#8;XsBQ*!{wCmrq zCEC@9Qqv{mycoUc<>0;5}iABOp(RPHXqepCxFsm z$rCMpF06>Nl?|R1_rDH8p9$1hiJJU^gW)Ur}@6(%aM-(IkM6p%pxZ;$5wZ!^{_{G95%xLjy;@X z)I-jR63Kd#Uo4hB*nV{*{AZHmCFibRP8W`J@S%9&miu071qk$RN`I-TJKWEOuGi2y z8U~GQ?|;@OKVglbjGfZZRHAm`|1v%O?wll}qa*U$V#Ko4F*56llnJMm1{-eFc=^)S zwYAt;Qm3T;^cWmpmNCf(7#mwY{jEtlTTj@08PySCvSy|cK`lL{@_chSP!EhmvZ?!W>&M%??Tk{aFDUzU=Lt>(~ zcX=66+M8WdvnldNen#Z3NGj-r3ERP|i#|6ia(}ZSLRu^`uB_Gv zf`tJO$Tu~L-aM%1WmS*$TH%#c|D&nsq;u zuN3!|ETd*%+6!Lgqw0?{(rkmPQdI-8XFg)F@}LLTc-L;ZRw^;;R{3>1?Ig0K0&( zB1?3s=)D@>{Y5fDyESBh0Wp?~^t4ZJlvB7*82(Sy5)E6{p$zFfZ$aOyMwaoy(U;NpgxIw1lun^}T-ugf{}6QXBdd{|L%N#5+Tg?-U>Jw)m)S z-bcH@By+01e;d?LaCrG3Vqr@Ff*YmZxAcTmb=iLI|&1dsnud zk&f5Ml)ub5Qn}Ji0H>e#e5}?_f99upUBr6g9+3e@Dd3Rso~vIVGxygT_Gl%(FNwz| zo|Lr#QF@+Wql#h*z(nY_x7U>W_K8bk@XPROr7vljZmnLDkb~J@%^NaZ8y+|te}!!RM(%queRVXQ89LBi8$aWy_|;sbuUXSGSh{wL4G`+VP`0E>T2`iePKMjukp@UT@prd|5bFO4!uKx#^rog4|M8GZNB@~tW-9=$(#I91a(SMu)K$i7pR31+-tx7yH$Ic`4g zacodVM+}$^1`PV1tEG`mnnvq~+M)M~@bBxT3#ZR#F)ZGURUN7UINtadz0woPYr5i6 z#}vITi|}riFra2E2AZNCY0?cg$Dcy;Dbs+?lj;ErDA$hRUo32dE zn3pT(mHcXlZAvbf(dynyE?Jf^gWn(R%YYwMDp#LPB8Q#N3Qpwf4rNOUC+mszAg#Qc zV2kfcB>Kb;^51*LkGsU;9@BMqmdM06WDvQ%^?m^N$TcZR?T^T7P()3UU^(eE#}5 zB;3!%Y1Vi!Br#`MDGTu`&YJ=knf#-p(YZes)&jjTUr!u;&KC2%w)#yv`(Fimxt#V+ z`$`6v5zx@YX_?}hU9l}uDg6fVDbdgf>3&0y+^z;DmR_PrEP>zbZE+!yg*ZCL`b}j0 zEK)6EyUTlou0UytzerA2E78o7R|hLczU5Mi-RXbVRV_KwpXK-UXucEO`<)A`6MtJ` zcC_E&Y`w)BI?5~IjYwG^c&ep9q+01TIWLAKlpYpSR8dhG(^Qu%xj`8o^$=LvkBG5) z>8j!?z8RPjlS>=$O?T$fa-x9~yd6C8VqFu=tIVly`V=qH$N(?w+|@hS1;Uzj{E-8l zw8-d73L#@Kq}2=*)78&YuEx?5l;rZ5Fb?NyMjXL@ot^jhq;PVonPQqMXT(7&4p!q{51)Huq@)bX3!$pYS?7hE8kfOQ z7Cz`1UN$e37@x^Cy%J>! zL9xgC*dW7foJt(#zJ69CeMK=wMiRd(7&?eZu3(mwl{V12D@4}H{1etCfC|Q8ES?j@ zp`eOx&2&v`G+dPR(*TmWtS~XSDaU-}^M%XM7M+M>hQ6@a^dicoT=oOGLEH9N z8umw@lH|VIjeAAZ#ZXE}Z;ZRb@RQPVHEGN`1xBn1hFY%+7x(TZ_yMPk@h`}w4A*&M z6-SjEK(*r+cZarOoi6l%%;q;2454V^wx}P%rWR_ofA3ly+_C)#n!qz1)Tfn8Rs=Jt ziG3U~i20SiNrl#fH8TgHp10hAybB2>?uFdNU;6Oob7(d)9rDs4Yrq)Y8&`N9bkNG2 zb*9su4b?gspzx!dJ~GAii@F;ZQ{b?6_(vza0ptai*%uos-i^26M%yj<0Igq4d&7-n zA~FAeU^UG{NrC7SomT8V3V2yH_zHCr9qE$Y+B64SMKC+#%>Pd$H5e#1cNk%wXCaZ5 zrSjCpOX9W^wmJQS4UI)5-myT3kTqB&nR6sp)`jJPf6`a_fk5fhq>V@K9K^Iz`!IooqoGNB?%;jjWJ9~ni zVD3FJJLkLfMyJf#%00iz?$`AtkZ>Ya?qYTBVKb44hzPp<*FSug0(sA+dj7AUlK_>; z|C_{RFMOt-r3ESqjtC*6SdZLHHFdldB?R&ueFRG4%!+VAdILG?&laiOJ$gs#pr`;D_X*Wnlk8S8zQ>6;cqBHI5*s<^qmlhY7 z`5lh;+FZ%q-k5QM=nN8W$vtLUjOqUjBGQbG@miO>e_B`!d&|)kL`NxNZ)6DZFDs*| zJmpuh;0n&k&{=FSL~A=Lm)dJ{8O{rr|^FPh@>+jR?io>e+9*@NUJ zD3l8Vl4I$3{snWHW!d8InU?U?Lhl3nF^QAy?)b+1*?vY*>K2C+mwqMgW40gGc8;k` z2>H}%X7q3#9{Q&A!|xLjQ-U8Hr57htcxASYn3)zIuKO!-B{%(v7VnM&2VUpO<%`|i z3OCPrGf~qAI#)j%VU5?LrHmawL*FNo7jF8ZVr{35l-N{eLsc5Xl6 z30I<+rzd_P-aDyo55JpL%t30Rg+KZY>;l)u!L zL#wjJz@?htC^6K%IUD}+^Kx-efkP{3LylnxXEEvmu$kXjuXXgRbMbd3k=L-aB(#p; zj@(P!4sZiMJY@mM!v`D1Q`tIKh)9||t;F}K$%es7Zj7>%$wV2Q20?RNNGMD-Kq$1I2 zMIacvvpv0AV0D-0!!;j={UYBvL$Dib91B$VXRukEE^>0EvKh0HX0ou0%K%%=aw#-Q*g2Q|mn<07`Va>su%jX+Ej>@2PO zfy6&$CKu=({1Jdbb-4G@%sG?PO#W3DV*@5O|YiCWIn5?L{BcHy@$uG0pz^&3^fTI40gu{*kzgR9xCD*ke?$qY%rU`Y4Q>Y47kuCsEmRT^nZQS2daYpYATbt^ zoR)!ZNPS%;pid8>!nf%6zsC8B)$JdNa0yJOp2Z#r-2?Wr09=%Qht_3^cf8C!Obt21c% zA$LjseOhDPmWwGY+^su?;N*dt;Ttk*`JRf-)TZ<8J6z)YIMs>eriSrD&6kxqON|9m zlQe8`efAf@qeslJ&ECxT4y6!GRZ2?E?k>eqjXn8Cu5};lW|}&%;%F3P$kmp(d_=o$ z`n1W#9=jeid#nXcoqT8E-p^j_c76eQR1x5Io}cNoS}6;k&uuQnVB&Zx(qwwmd2ox; z8H9s#zYDbdO*f7b1;Yp09Dr(Q3QjFH4?yXY9Mk*yaxoBMxv(isLt5@;G41h8;=2p1 zo89Ks?(^sx-F){#E9dztYri_pyl{D5f!v_3NJLff)3qCIMIFZY#V!QIeYyHf9Pao6 zbEe%7!AK9jZwA42`8lNuL+{p*pR0DiN)HC^@R&19-b(?5l*wdEcy>@x{FAfe&xZq9 zye%>DW`a+9qi$c-yUC-d)M-^mqjEomSFy&j^4OuT$rZw;PnA@U%4BOEtKZw<*>%=H zI0rdU($%|PV1p@?QLNL{x?5xjDXQxDoy-{ZMiUX8IAF;SW-6L3S7Lqj4ImR6YRrz^ zY1UbO=Aw|sy7huJlE&laC^@X9G5+k7ch}%!ZK`r&!6w|Ho3HIhX$`xle2lT6`pbKl zisf7?;DseAhNbF**P>bVi}-?E#|FZPiH;_pl|pb2GJX|36_%G89DDPk+@0HAo{?OP zU7VnY^lu$4FUjJx@0%i?(nd1|Ej{qtt71c}xrR6gTPrT19FU1W|txYq{iO$GK4XInr$c4vNF#dqfg_O~WGnoLpjjYAzO0&@{N z0Vcbk1jnn!q8hE?FkStq4=OIBfn~YL?dJC*M#``+S-PK!?%eE|2KxZEQz9UtqvMhO za621Kt4=%y3%ceHLmtPmkqSqdG4TGY(8z>CS(|MBat3NMoW4)9a@l=kC>bFNi6pkq z>y)DA>zEOW7ME~LF?@IWnQT1Ul;x1)ildbub5^4S(Q~*Ww3M1=7)PYS)hB&XE3SDy zt@Ec>datj%Yn;L02?Cu7={lAm~%84YQvV+8Hwo|xgu2hVspE>8^2j?U+B|WnxxJxO1WsOzZzN4>Z4`vee`ov z#eH_66;C!y${1!d&jgI6^ZijQ1gr3HYb>E@Qo*k|;#Zk`o6ctc6)9Fz^IlG9`01uW z@T%s7WvYMzEQUY!OzmrHfRsh#eHb-Ul5@bh%}cf(;W_TcUo7QcK^!hX3t&~nB&RqC z1zu%ISOp0>w>X^6Ep138P9Rw3SkdKVi+r`lBW=X&N&AR|{R5q}%BcABs|PzKnec4p zp*<+GDrl|6w$EN|!IqO3$;p2V=sv<2&nne8oY^_s$kNYMSo@Z?GM->(8ETU@G65tm zBerDsG2`sP9y*e3Pvg|;vEr8g<+lzjnUR~1ljp3?g!{D&VDD3zdJpz&LPh<( z6m%-ibovjj6zv&n$!RF^yO9}gmFAQ=+{bxGf_}GT#YN*{Pw);#83ruMb+k42$*@CR zC)%FRfj5pElm_q*36FV)qMEF&?QknjV=*yPYWr*N@ygV9(8uZyQH zfO4(~J(kZ#76yF^byeB+JT3`4@{U}N_0QQZ0>|fm)J%ct#?hs>z%c2_ud~y&n6R}A zx7XHuMv)UaaWgTQNZ^4rGc#elFY4c!?%nB$9kIOU9hI>-MNhDI$bZOniNK1p2rrhK z>8ccpv&Sokub6Hbs}!NcX3B+#7=#WK6}}l4=nZ7CW>r5^G%Ls%SpiNCAXQZG6@4)o zdA*bY#|hq;^Zmh|ABc8~=LGFE*~@L{Uv3us$A8vlEk< z+VKq0Z^WTl=BR3ZAGhvlE|PsU<5qLZ3Od&mP)10EvyhV+UMA~*v zTxouzou}wT*GP>|+n632n&jG~N!`6rF5kR^)?uH)It*$*L5umK{8JZ~%5?8C>e&+| z6r5BRy2~$4d0MGxY)KPH=sE$zinEg$P%+rABgeYS^}v~S3#d;0uP~ZRZ3*uyG^cXpdYIXUD5zo#oA|UwQan@f)u@9Z2{<2N#25(GZ0AU^^jxicH|q8LWvX ze7wh|@|I%V={X;5;^_+QOdI-H6n3zEY>IlmP1>Gd+^fF2?#iZ#b!>zw`+rCmI^kD; zMAj!+z1cQe_==Q*mnPh~WwWlbjBR~(I1k*2kdjuSyKWR(&-a#MPj5GO6Z>!l!$+;^ zcIXW_46QybcAme;E+%wsgIccB#ecre!0oqyCW11WUS3GuZdY5ba{=${fy*z#c+K!J z(Uq|H`BCmvpEJCEl6#*crOU`-mE1G|kc6C`!#;ek`j;)Eq-fB|QIjH~%VQb<* z3aH6-;gFP~wbG4CSeNnS>zj%Jlu2B$TA z&L)sN*%B-Y4~-D88Sr_bmzggGyG^*(ymIAuqREM-2(NK=SY}#?onepXEY-qjA&#r6 zs7-oS`wKg`d5x=Lzyl}z^O{8Pg~_BnSD>Mp^-=_;-O769oy@{w!=$F6;E7UUq-J=y z#cv^-{=vzo#Yk1;0KRaF^#Tyw4ne*>C_`#H;{{d8wXZIh*XFwxp&8+nX6IOR5ZJH} zzGsM*Q|-`SQPICH?#B~#R(7ho)T-}c!S2PgtQKf`wpLZCGX62&;^HMqqPB-tRApx; zq#{M;d3gDqk3Tb0TwBcxi@Bz=+}fuO4*KP-6eVtTXKOBN1oc5{S5BN_lfMFS_^?(&hxwA z(<~8_L%-W}o@Na$a|^5{_jjCMUdYyyn1QYsb9UFc<)gT~+0iw0g62y#{^L#Z}p>P(>$jw?2u}h~07U2zt?wmkFfkXfaztmpy zFG$=Fgie0}xicPTQg#F;Q-nzv7{V^b)X3b|8+9Q(Xwn&J;j8_}=FZEbWs{}aM=JIL zbLjX2`-dY$08a56tvTiBM{|G{RM4hMzK$4h5(%L*;{!BG2 zHyVwN`Zd|AlB?dU4HFgzYhUTK;j9DMNq-R~-fMC;_-Uos`~I#LG_@!c5##JxFlC%zhkQOs!KanP?jA>ocLZ2* z23EuaY#PrF)!Ut6-1fmaIL$7Qbg<9nvN}=vgQRp2Qww`3=>ifVo(+1_8(0gkQmJtk z?+sK{Oy&wGaaJ6^xku$S21AgXe&vMYzs%OM8;UeOO_^ki&mQ3ZE1+6%MZZw_CudE( zX)Pl=Wam!G=Jzq|ZPAl#r?O{4ynYvu4f}htkDa+l4kRx9uPh*3QH$|t5gT4Oy;&Vf z-#79j!N{98t9N}k+3e;ecQp;eFiUWO{tPEftzF5HlHqRdiLFc zrXTB_v<@B3aQoK*?aV3LHn@Fxl=)jC^QZhIlxd++@Fw&99864J>i)Ud4?jgRF+Z@H5;)k4mV*_B8_JD5oOjK~?*vi9GgWdLTipPb?>z1b4| z4`Yek_Ui|$z8{OPaziIEEInM9V~vFvk1EPAC1L0D#Fq@QGd?mwv-lzkC3T z!D>ib*S>wSJ||wAClz74&s}#1VH9aBRIRZ?$!%Hw!fGoMX2`#$q$ya)@YZ=*Yc-{B z{4l;BzDHt-!yFc-e?crv^Vdb#7XYtIbwT*4n@upb!=$Bw_#Y}}wp7b`86;)UNSk#! zey5cEMkoYQ+hb7ca@|=SDVqwRK>OG4{Z`|eC&0B9Kh%?-1A7J+`wgnL#~9#uh1GJd zFU70$>O7kp#5Vp5v#5l2!CwrY+$hy$D|V&ZX0>w+r}^x+w3m7VugEu`IC?mRpC%^p=vG9h zp!{37`0?}%YvU{IKI^FB;=rnUrLKg(8P4(tsW(>A(uNKV zI39qD*m#^GOJD{6tvRs)mjxT6;GZukR@{HwK3r+hQWb*2$hk zjj_#U5Q4wJAoOiu*8)rX!66aJin}tmt^XF^I#Bq4F|xP4 zsD`x_7HdOGdP&n=*i4D$vTS{P%_PGTO8TS4H#a!;nCn>Bvy->y`i)13?pa+~Nt9!V&eFsg-jnIxly3S0+O+#dN!~l1__?eePU=ByC@);*G zlz{XAhMw%PdWh^-G!YNsbwabgi_Pw}W=QAHb{1Sy_2+1-DI8_#Q(>>JxH>>Tb_`u> zeb?aj1w}NyGj(ZBE1j9ZDX)>DL<}Q=5V#W<&KcFv@X*%6bM?R-Q%(7Kb))hwURzph zBCUh|JJl~s=^EWD3}x+woLbAFknv*_G&JQm70a$GFVlTQrlNV56LZBQ$Ambv#5GBX zaR_b*#w<;P^CiE40T!d7JEJqM^sbge+@|;X#F6^?2wV(t%UJ?Rorc(1s8iRC?L^u^ zMKz6VO3H#g;{~$=5j#u{N-d)h^9u}pVOb0q-gDEOJfW!kiUiJo38*^QbIS~j>4~VWXyHvUB6XfRRNO&tt0nT1 zS;YX+oSc|wV#c}Hca6TVT{R3)!2>8Bbu4NAL%xkX>vhlCtXpoIU_QIeM6n&&AX7~)r z(_mk&sCl~{iY#IFQHg}j>!D+Z0|-bGgd98sNTZDTd};R~8<69zves1V!{_TSr4nb_ z%V0a@V3244h2v^z&mEQ)+P*Q2^<5jf#xrXP)^;S}o)lMq^CA&*$F3 zWC?^<67EYQBu2EWquG_G6XvC8l%aAKrHv_dw{Bmn;p70vy z+)btF9YPSxv4wo{iy{}{@;dY8TH$_cin{|X9(MnAaN4>NP01QjyV6Qm`Ei1HlZ40W zwR+68jW<@kajTsa%`i`c{;YSu?%1$t*V%`}Y;qZsl z6o_;8cQtR*Z?POt2q*f4xl^gvncicxy_GVb;Q02sSFS6s{79PF#kuWhGm3Ry z1{uX>3aPjD(k51by}!j_EJe*@eqgP@$usdydFqynMp>t948Ny53tFVtwe!?ECsVIp zL0v|`h0kEJu}i1`Cw>a&r(?6WlxI>?Mhc&O1r|C!ulGmFMZ^0d#c&82#p;m#Z~w*uf>nJ<2HxW)T>v z(Nr6UB<>>;BXBy@)W)Izg-9fF)$={q)olldCqj}R-Z$Ezw2;o@w13milIU(`7(Yyu7&l99#}kSg9oo zdjIu2K#=$y3OASj9Ho_LQcl)tw{0RpY_eug$j&Jc$W2oJKQNusrDcdghT|4WJ)!7dWC*aqTE?6Ik!+42P26uF>-j<>w$+yig@FCc?XZCt~c`fceT_ z3C5=Zmka!3M*vvsg5|zx31*`&f;Q$18fU%0N_4qUYWgty6YAodw(dp{ZN0pb=5NKK3X57hdI&6Pov;WDYxL+RSd#< z^hFqeGYe10;v;x$#eK6GgsMovp7oe>&A6{@*$Iwu`*n_(c!hDtwVvi4px6DS4jqu{6UPf=yHEXk(^kh<>qR>eu4T-uRHw#%2v|gl}TFf48eE z-p;1}n^5(W8-CgXa3;wxpGPdXjL`)a8$4v`qN~rflv$Jb?-Gh#&AXWT02}K(x{GCW zSYRz1vudauaqf+{w9J<5t?dWb>nmbSrBV^LC!($QAjT2aGS!B=&TLahldTj?OF#{51>K!}606M0tF@~GA!Y$p?^3)>l6mdD z*nI`@Ai5LWU3H+8p-}3gLZ+FkDW#ziW0uxuujq`hL~g}}kR}Ule3eJ2o~i$Q|vZwXJ=@2NlLh2FMg#FKAZh zR#ny2-5tB0(rDVm^!?vVZEtK36GsyhV=)qcDWp2brznQK%;%q;YTGIka)wyH)fddn1P*M_OU)tIr zVdggxz*9(Hs=tm1(hlwRO7VB=lrU=b$_mFi83F>H=%?^|)7fkaRQ$h9kXiS6NJ-*y zjjHzi$ao$)n!Kv&Pdz<)h~CEl z=dvcTEVPb9DYudoVKsn8F3aC zn4ENRO9g^S9hPK;$P3qP{%w%rA+J3-G|m738wbbk#bz+n>@PbuZ{OH_UQ}7Vzo95g z#NRGP**{#2`1iX|f$ep$jH(0csZl4O1O+IBM_0!Fk>q>e;dUSE-ySkdiIuM+H&r&Xcf+I zZB-&^PD|7qfcM#Dt$L;dEVu|0<@gRaxqIBDc1Brt;h9i(xd>+T3GtAZ%s0HVmGHBI z+?PIZNr>@Wkd)D#52RxsatSX!GP_NmSh`$Uk0F^ZuP?^bT4rc(8s^(o{#%!GP7Q1v zw$YJf$m_`O?&x%#*o`vS4`p7fy1f5k$}BGh#EXhj1cE`&0V^xVFBNjbAFZb8(9T$9 zQ`$YAw6wsk)B7oNy(i^T0)!}$=QTosX8q_QyLkG)i}(=WQy?Z)60g1Qej0aNOT+x5Pq|GHLOW;nSb57Oz)4EYm z@QJ20-fhisdbyb$q()qC4&^nJtDa;PE&)sWJ#T-CQ3P3cwnhI4c)GufuH4mQtk+li z5)U`145oTFEXiR`P*W43btRC1kJXb0#}m+!G(>)9{8os6tJuy#XM;Hj9#!anNr;tP zLvF#EC}qG+k*?5OyAqf!ApmvC5uTh0USpRuI__YhA+!H!EXvqcNsF!NWO&G8{Pq&h zyisOkHU27@FF$-EC9p>JvK9_3Maiyt%xO;ant#?WIL#v^jxBZW9;`%kvRSA7_gLAg zjz?gr?XEf(h0z4lqjS@~CN!)3WNe&`6f!UEnGLK!b9epiFv{}lOphADy(iN1g49(j zw=w}9!;kn9<&XD&2UBcEC7uHAo=9#Bcu!2#ujA*lNtr#*ieS>?DZ847JP@AfF=^{2 zfA7t4U7BCmJJTa@04f1M;A4*XU(4_Rhd12RZ+R4o_sX~aKqc=#P{|F-3ih{(8BkVs zP5N(T

~3fexfked1`vefL)%UF{2OqKNX!o@HO&*4ntZbiIX^2LdJ?hn;VlJgGeQ z7A#+OmzCZOLHG8lsa1U17Chn}QoE`-PLN@ENb_y!E>zBwu7JKh^?6P@j!|CtiO|Kk;q!q$mBLlH+Z*^w{1NE%C z+Gjytuy8iRL(5N!__5MWxJ3ms#h3!1+cM-&lnDKx8XTT`9 z0`t-Jty6fDTF*gN9CrHvB2j?t-5IKR%ls%Xgt0^Wb27gO*7D^?0#`b^9|0}>&?W>( z{uZQj`SQrLBBM1ZK^sFJwX=C(9g#*T3ummu6=lV9dsiExRSC}YZ}$)x5pvalNys@w~PUvi0D0 zNn32r<}YYF@bauDKd(X%73;1JuUlq*O}9oFV9Yg&vnx0=X)JmU6vHrIfD%OD0udau zufT;1=hG$tS(BNy;IZhM>s067JN{pRlZ{z@&~2K8J@6Nt=t<_0_YyDh4qG6kGi}G8 z@teC5CHq4L8>%o}^JI9Lv{Kd;_QBoxBqy071?wB=jpHw z5#itMbWq68eG2&@vcy&x#JO*1YeMQH4Qet9*X6XQWM5+l!{% zM@zctW8jm0a%me+EREiQ_CEd9A8HI}%oh&iy)g(P8X0y;x*I7SbN&1dY|QgyHUjDs z*XX&w-+S5ZxiSs+C@Zg%w7zMrUhsDd4K%o@t?NQeYZUAhgU%vwy1TskYSs3b!W_BF zm?#~|o~%2!%~kE6J){h}SdeX3u+aAuP^kcZmS9S|C380>}5E_(_Qh6@B3O#L|8XTn^Ma20J&qM$(PBIw4GkY_HaD<70)Be zU{z#x?*e)LgYK9)0HHntA`(K9H1G#)n4BcJ>6H1rD@^*>)u{xOty53qqM>u*)709$ zq`oC#py*~!c{?l%3(JyA+T?IgIB@|6D6BNzg^TM`L0VrEO4>?Y?v8cP|30J?4;8ym zN{M@}@H0e)_(Pw2#nDuq{dhAWi=8rgp_E6L&}?0wg*e&HV%xtLmw{00aQTeKDAC4Rn;^7k3 zr2fYKc>b8O71hpXd;$ik42CZZ&Kc6W>$h-gA3v)V5eK(?nYo|VxhJ3RPe?kd;ZU1qMmsm*7>*9v|lYHqX5Hm|Pbxf__j4O{rE%rL^+cZ@iW63AZMMWZ75iJC zqJhyu5?5VR8+)Vr9oegCow4e@^kw7yhF#n2e2^DcLX7%u`~LoO@0x>I!$eKv51de} z@r*@y4CQ$wgraaOI%_w*Fw$}ANIK>yh8o^0(Ym^}5CW=IqvE6=>X;2u8dH4_ixVqK zO?K27aSSFY9-M3TG=bQ~hhig*1)-Vf4~-DnYg;SNhGA!3X4_@I-FZSiPf4HF@k$Zk zF@eew<>yD7VP9;V6~BRw4UVG{4*@q%D3=AiXUfw1z=PS2yE)geo3d-&)xfrl>DvDk zTypyh1exTS9VPCE>YPhgcE>*ch^o>Lx9dFM)NJr3Q6|q^mgpn533#E}`-5hJ^=r`W zvb$_49VOODbNzN`G@}|DZ2(&5EjQ^+9Z=K?2~LI)nky5%Z77HtUI-Objadj5e%%?S zVAf|yA@8&U4iL^>b26uQ+u(Rk$^B_+-$A@H1*Bn0BR*S67^h|QGXi*R7Ut~o)VjW* zdH(L|rkCqNhNlwxlVjjY!5fcev?9V`6-S zp?P8Q!KG7{KKll^5>w<| zq>Y9XiO}iyebaW;L!p&P>kW>kI0B`!x4uU)wrPLj1X%680qYM|(jtx*MPhw^MN&Te zezS0S0>hi$D+BYH8f`%V@pEHW1+n@Q!+(+5PO^bI~r@{_CIaKUE}E zA9b93OpY@`ysV~CZ8JHb(iw;FSY{|N!mMx!*A4K?9Q)9zLDD^ege~$g6Rhxs7;V zbk-mB89esR1zr(S^R!IwL<6WwTT>krlb9I_a;2#SE3qg7#wTKOkja)uo-l+R{%Hpa zbFkEoFcO(VVcj7Kn43mWK8hzlEsF+wruhgBzHgNqIj-u{%Oi&y$f~kD1$W z_=_Q;j(_0ZV*dYexc5=Fp&1e!_pv3Z-ZCi|m|XLVO1xdiWbumB^y&EHeXI!pHV|D*lKu-;8rNF&TmSQjScF7(u@vWz3u9AT zuQH+wED-8(4wnH0`apg!j_t)Jirt=DdWy!#5VO?j=32iH3jd?o;iv(rLBtH3odsOH(hhQHr)m@nZi@VM zG&R42GDEqFSC`OCOTXn$hTVl8$lz5*LXz++%-9f1M!yfV>a;Ma!oJ^wfwOjbrxpzp zf68BE)1rr>DBQ@!F^!nt^1l<5WLx|Cr-QR&Vk(iIV9m}BH8c!vV9i~0Q}MbbkCH7g zQVs>heurQ*-Z!e_kiY^gNxJJ11pW>94Cp*%Ob5eKzhc$Dz@=wEr%%Mp?8KxFXDw$9 z>O#a>l;Lvzo?0q^N$!Y9FGN;-Yy)fT^j2tYNT>!A47K72I39Jj=g`BQpyixzpuIgn zY~5+^@aP);pQD?mo#4TT*N$6M52(s6JQ6F9r+zg)U>-A)S%!AD62vMfT}c9#Imr(M zv6$R{fo$G@Sw@Wv$ZFFg6)Km~B}-z+>x(fpk{RBZLVSIa_txc3JXLv|Bv7d*EJ1lAuQ-qGiVeszS=bSuAMOQ(CQNgN#q) zyA{vDSwJ~g2Y4OzhscownCo_?hMU#m5mr>!fAmwacq7-*q?) zQlobqO2*m};^iAuHY@W$Lj!YI(qZVD!yunrA&byolA)J9t#^`OvE?TZoHuPzZ(?(Pk~`=5C3+>-pxhu&B6{?P zxqD|U#g_-f$jmge*`Irw9Toj{rAeSvzQ1a%t`OidR{Wuq|Mseoge7d*!tUhNUbUFO zDJZT;rKWuGG*?@GcV27$m}aI~q;W`yNX8&n!P|LHe8%1d9^3(63tZ^QXK^Wp>@k^| zIXBlg-pOvw+FAi%l{#HBGcz}Ddb#Zz2edNhJdZ=mFLu?-F;<+D?JOJ}{E5V3%%{DX zy3YbC&Dma=`=9w$j%bvwx5i=-FCk_OOf6bGiiRe{cj`AXZ*KJ%gRESS^%kZ7 z`oK(KHy;Yy=uPmS$3)-o+r@v_iPd)ResSwWA9 zNek>puB<&7V%fNxl`EY`VfkRlG%2IZu?$QLK@B)(i|in*LEnjv?|=Bc?O8>gUbDJJ zL9zYj@r3iRr{oC>(@A5zb|*#r(YuiJlJ|bbP5pWWEk}=n#42^Tzoq-j-{0*xp8y7* zF|yK`Se7Glvg?>+*UiN0O>56;Ywbo%QVVyG*GjLVwJH^Sc7X1te%KSs8Sv)w(}!2_ zdP|bP;?tz~?OU53Z8iK~Xbi;o2BUyk!_6AIgKFb5hcRw>+fpHckk*3V*v;uu z)em>jFnh}#?WUK}6C>H&u0&kl!HI?kd!COQ$67}?-}jUo-c#&Gw6*!Cy;85DK-b$#Rx+6*p{Tq*8EL+Hj=ZkeB%v$^gVUx~U+ki)M#Y_{1{Ae9 zrft^#QsNbj$-mE&n41(HYy%5bo(Rp!=j~s!1GFUVha1pU@&LhRcg_(AlQf_g1?lj z$zkwfx8U6vZBT5!wgO3?J(Ri?E1RHzz zb(H(8!3xg}Il+%R?jSh#sC5x);pKf^Npds2h+~!zVA`O_>MhWv(298Ut1hv(9YVUO z4dLhpvdpPO8RojbT=p@F4idk;_dl}$03!OupBMczMDu6Zg_f*1?2hz-e)~#yiV|H{La#mkKX1a;o{l0 zidMUy$RKZ=)-t_x3g)aNPZ)pGBAslV%kogwoH3D*>zds$J@d|X#qkOeeR1m11R#BN`s`0IH2Cp7Ta zS+$^o6BVEG=!umNATRKo{?w@kkTD>X4cZ!!YQ~L-WaTDD#Kw4 zm@%;GyNvCe34`O5JaASaJc>7ZKu4|_XY~l#Ib#WH+tj$pax=wgO6d`MKNnis0@L|U zyTz5Df}JalCs$C}$eCT{-B{*QTwO0N?^AR^2M;#L$(rAMDICy|U#SRl78!a3TRyEE z#y4(gXg#aqpW1>XEsbS_E4O9qGqF-2U~qPNO0p8wGFC&irQokW9KbN?b}VAB!T)?_ z<^OMX#jY>+Yb#76Oa{xw12P)d=cmUBk!hi-6@*ZqoJUpXv0HDx#PMcXAxIB z3h4+Cp3eHrBwBJHj@O`nzATgxQyU3wA`qTFn#?4ovLUudpr0Fg2@za;zdc#vVB6Z- z3Q6^G5s^6ye&5!@p>9dw3yjZC*kQ23P~ZXYSEr(`S4}!5r|EDOAvp9Two7*Bi&U6$ z!O{9a0d9&yPI+5wEKVD;DqBPJ2L)j~xjz=$JtLneP&|wC{ehPTs=70sjjN58RWX~O zQZQ~jQOD0z@3wT0lv6S@Q=s4wBWO~)Ws3#D=kxsS`(a@8ddqh!DwwpSY3NG=-Yn~t z#OTXOBTGnX6$ZyA7qj5!2@v!@{@V;(Ip+#piyFi@Cg;lK zZeegbVgyWs9JeX9pa-)kn_-%TOEFO$`4!|pI3FwW2$?XHo|(*aP4=bkG2d{}{UPs^ zg8t`XGQwj#Pdr$vH$i_Z)W;(0MRgW%NehaVhWL^&Sk__Gyu`BELXfo7+wsy$jF(04 zPo^&|Kha<=dXDCYeZ$l%E?mLA$I_&O-ArcO<*iL?Mw0g>@o;+*6v4?!&8093PwKMb zTMGniYN4apN6Cy|v3jHp<#X+9eu1TGrUUE#F(+vBH#9aiKh=~WWcU^z*|uJ*VLYny+%t`xmA9fOWFV5&hOxu*I%B_xLy?P|lPsAtD5 z_yE(rL4qJbC_AjH!?I+{`Ue2uk{@R6S#h{GxPEjk2Hin@5`+JY{nch`3Z1)o5sncU zY4osww#z(X*bS8)5->Ux1CwdJ+3k;TBNiEqE_Uu2oJ>A3s+0&P`caIL`T|>Q;?Qc- z1pO=~M~uQb(>2;5sRsQVdKl8KFU-v=b2g$ZFidu=iPP-d!Q`m;lM8(mwbcD-T~&nu zj}hpp%L6@i$w)$$^|Y1_?WM%kwZh+VMXEJrYuCjl9>M1d1hm&Ub}CeMkGDM^piCDf zm}$pRbj-R;1C{XCKDZXTAwp{gJM~`|cH2l$e=K&ciys!Y4^2fW1`}~8@-^*H zrgB)J$!>M|`R_(Zvp?L&b^hSx5RKBD?qtMVF)ibPcuZp~qM#TJO(NhQzFmVTZbN}W zKr_sW(Sk&{pgz;pk9z59bnzu3n|j4-Xn?EjQ2wZO~n&5lpF~Kv31JCXm|HlNXXk62|)}VV=SHX zpL~$MezOt-w-YN*twXC_&HJ%QEgS$Jb)ix^W6IkCfbmk*bQ`x1=QVuRu!QZyRMHel z=ANbGkDAvE1S4|czKi9qjH6%n!BWj8&u+ci`uJV`)4x3jxK~e;)_ncY!S7s^cew(~L7pt-SU@<`L z&q!hiUg?P6U*Ku8()dX1F>c!e`1U@Em-eVJpI%N8;2Lnu)@cG>>J8i(cq*2drSk2r z5rS{{BYk|cd|x*QYVm=;ZKac;JsU}!sd#pz&2=s1#Q-+d4#f%`XF_UT@_@b+ggXQOH#S|f2Jly(<*LJ;3m zwbvOn2yW*fIyP+sBnny_aT&r6-$pOH^E7#SUaoGNAUl3?4)SVPJ!InwF(nUlRBrT1 z!43dO>Q1Ww>w*3l_EDVB>o*ycG!{TYhXLM7HhVf>Z@Amh*-EHEAK2 z6(5g&XYcDEFOb%oy$|2b=|h5Kn178r4)yvA-J@-dy9LpU@dNe7N@vFa0u?jofdZ} z5Zv9}?S_5sJ?G3l`_A0ib7t<%uQ!?e_`baFd|A(0>silPinFGkVgCkM@C&(|3tN)F zT5($zahy1u)}^$8;JIku#vEFB9GtbTlTLUfOYgw}`3AaddddM_40B0nmDc1o;yqhi zHliURwckmdi`r8;4@U>>C%s?KF|o~Udn_@F(ILbWUb1|*!ve^%Hd0Rg<{qJlYU6)o z5HXt;(`Lhn-uIq@@rb0`k+}w{k`8;Yyap&q-rsT%k}0rVjB%Nn6N^q~Ybmit*6rcO zjzaqmfw%`lU(1@AbfzIc*YeUwkt=j)%eX<0fYx0sZ1#d${HCA5o9Z*8;$GV)uu0oT zxG3W}3H7$mM5ZPmUDmYk>BA>wYJ6n%hdhN$brwjnPr6n*YibKg*nNJ3tlReD+b4rw zaCbc*L*YL|hT7BcPRW}ig~Rn< zWAuwt>k`Xq43-_|H(oiY(iKp|Tc-EX496oA=W6Q^L3jRdvs#O4)q<3*#rmq&8`yy3 zYzGU0#bu<;xt_4PQwbc$_O6g_A1o*NX%`w)%C`Xl+){1ByM1TRO+Oz98x}ix5C(+u zhRGCg)_|qM;$5n!TbRFXEm)HLj4=Lbk5-me18FINl{4>kM5Ng_KRHfle48pFKMvDf z_!Y4#yKCG(tT70%97gV|z#GNTm6Mjo;Njs}S$UN^elBvLeZ4!v#v6D^S?_>9rB1-jmic;4 z#N+*J1q-*RTW(tgz|onyddt!NFjPM^kSr} zlKL9%7h(3)KH?q0jPGzk)Z^Ec+Ovl*ZsK{8F^&gdr=AJEc|tt?Kks?P)(7#}vkllh zMI~@aqeMgd;O-6og4D1qsM=by|NkO2&)aYYpBhLVsm+qLK)St~Xbhfz2PFQs|J9Q| z{mwCts#`&mySckyt3{E3sEAP#7IDZmP+>e51<yc@;$VY5yMAY7&T@Lm^6&oqm zEp#+&nZXjCmN)L{U@j!turC6gL5`Vd%W-%(VXtM1KT2M61Vwo)0k6N;n@%=u3PvGF zl^Rd`ghNqUQ2LK!*tZ;=%R|Esew@tZE>*t8<#pN9ALCi=*fFZXa<_h?<+ZcJ6n_bf z#W-AN{~Dz;9O=*7-u8vmez^99iMB@?uZAiJOiRxTQghc2QgP!V;89IM;m^rs;SR)n z9|XoxeT(xyFW4y-5Vix*q7>qrVM5Qz8A1!~K0O9KbdUseCfJLrzPl`>e*jZTfe%lD z|6H66(XEIg8sa+5PcZ8lgjE?dEHMcOP^W*>*F%ycaR!?G2MrW-+s9iDwhcSv=0%r; zc2aW`rUvIm+F$EYP~=njw#kjS@Nma3Ea>aHnm=pplwB?$eZKLC^|NcY^PC2;C%y|Y zceOi?idv^ZLw_C2Dz(2a1m6a5+ZeI1lg^edBiKC|uL`mNQS>N&511|gCNPY=ijinL zcy#R7*e3W@z3bnCbgZ6gi7Pt|f);uKmy7nCn1--w*=Gp+>h&)inif(T=zd^rA8yM! z>|=5LMt67ql~$$j(YHzxE}qD;YtzUZT|@EDQMNo=xaU81>d6C@-8Yv%axyS3gy|GK zpC#;Gjf6Ve6LcMTgs_SE*e!U4!bBJ+W?Z>%8vqlPywS-KarAkcAN;?yZjQHon)~Wo zBLQB2bcKwnGWAQZ?buMn&zdJ#uvDVfzT;%M@Yb5LQ+ceW64OxhK6@hn@hf%(tA%TH zi5gJ8%s54+^FZ^>9<*nbvJg`!%xxj4!tUKPIEaUPn;yk8Cp*F)h`IGqHU(i(l#u_6 zwAkh9k;?C11S3{hLCXb7(-$xI<)-|ehq;T%?l&lwbDquf%wqI z%ZvEu5~!rtIp?tJQ2`LrBp>b2WnKaa!Holqd%t? zOAM4kOl-<@p!a_0q10nk03R5kJnP$pDX zgU=9XEu%jxEEzpKOlt?jB)QQ?rt2xn?YSKsdB8wAOx7bfvA2gpgidZvd?!>RsWG=j zj_gc0U^-`7z*pQFplFc6%@^{vglm#NmyAfdIGYux`9_7aMt*&z?r?PcYr38lufv7U zP@sZ-r9OHk4VnIJy@wfrh~0H{pe*y#mgw4`KnNc8um#~F#jMS5Z6@=xok#B_dXO4S zT@XW77#>t=f)MG;GSctZ$mk{};2G3lBgHxXsru2M)yLdbudaq#+C^nSXgsL%nR&@T zI2=BK+_z#T&(HQ8<-G{06W6;tW!>j&rntEyFv2W707p#)T8kW#zMs=Je517!ccSsN zhr>32edmSvsvj8}z(%tgjw>h_zE^aUtK~^$pcXt6k4PX{uShnvWqs=v5D+CwGCN?I z`WXe4g=)=pJr03bj%zBw-UZnw0smX>Du(WDzUW76gb1Yb(oM^bU0J0UeG~|zin2EL zPkx;{d&PFYfy_*zF)*qNCrLi#Z^c94GK&wp3uCaAmGG!25qbH?uD3QmPoq7khH}Ta zTsHECz)W-ubPZ%^&=cMhn)gzMn*mKeqVSx17|W#nTc|P1l-=@CqV#WN@e_24A0D1G zklH}p;a=xqUA)a#OHHgLp+(+E7#N{7mrkZ9Z5|WkbM3Elgk84oKj{<)MypBSSieR~4|?tk~1LW7e&t|6hWWTz*V93bL11su-46 zzOVLaF0^#{%>Ft$fvHB)Fd7YzvA0f&^|@^)ZVMHF9oCb>$H@&te4HmZoEy%lQ_0Eu zMwyu#tV|xeB5^*Z)TnVKUF9hl2%sS+EvqwI& z2QSKe5`Kd9-dlW+n$xcrA#vmn=!HaZhiBsoI8DgZ*;IEbh zhmAXMlf!*`2BJ_>99KJo2#+O$Ln&2ueZo=!W4*fnq{NEbC1%mD(27MU?nolBT(cV^ z-lR~TeSdv=!(Yaz^_)5tX7^=f>hkxH62+nRJGH{CMJFR2U+2DD)qLs8^Bh*-_X&Hu ztt(f95+*0VztcZjo6|W@P0tgaJ_H7lImH0E-L$*n0e^5e(xQmt`arP!*@EWj4B{@{ z@gso6(jo1lNPC3C07Hv+Qqg5v&x1f%oWQd+>96D433Z1*bfWs?iv9s?9u_O*Ya*H9 zxMkn+_~a8KL8mt6kUz z@$ZaeDC3l=bACuKr0}$#usDgLtR?Qs0SF_%OHtYSPCp)BlT1o$F-%b^0I$9P-fED$ z@CM{dQ+ydg%PzV{LP}FMAJVMHJ-D%GK-ix(Tg_u-HN`>>$+1^l>iNED8zGd$Y7H=_ z-z1BRT|q%iVN~JWmfM-Gs!H>?(bn!?i|w%JlGNC*bY#eFx8X^(np=9dC3}o_TBgjn(oRaHvF*!gKt7y@0tRk~zgNNk zZgh?vr5Z5B9Mn7cVh*^Im&eY+G!icUYjL(Mo1oNs0vo?oEcz<>v&w)i%^XPy9(ryu z3iUBZ4sOK-!i9R!`8ZOJ^Obn=+wr`YI$C^D4vyre13GW!)zOJd5EGPjF-O{sw7cF> zaP8p_xY*}dpR%tq@KBM?cTXOxDNb_2zWASUe^ko^rBWYxQ4hqjCEe}fe4oYT*c?Sc z-PQBd@hcp;aopf0q)~Gx>A9nzZwk3ONi#^+zT>V+y;!jfp5m>k-U-y3B|36s%76Md z1+xrgL5!b;6SNWAy5SasiI4(2HLhpHL$mU~Sdg~`+{u-FM4|(wOtqX7hkou>jVl%r zKTPtxBr{(`H&2wRUHRcE%eHhg>&Zb5!C`rA)NhR(>?XSt#BNNUG>}$Y} zRJT~a^7qwnTqXk|f5Zt0kx^WO`;27od}oD7DLX+_%NH*=JGJn{iaw&4ev)7JU*;jOjp}An9x~RUVpLFAJGCtj)Z~fzIBl4g4eXeB{qDXws}0{P z(lK1`lTYbkr;wtS8s&Nyej%Db=$@ZmOr%>p`Tahwe6~ei_RYXvzds%OV*;BJL7wg; z^&1Q=%A>OUU7yvM+na++PwpsM$X>>azYGkU{uvmiTdKptaSr(iLo{*qHC$mPiJvYy zB(NgX$`E9Msc-;a_ABEEJ;NaH-TB6O!dhErTvID=0s&quEg(VSxZ&nZNYdt}KT?`A z|6mJ+PM%-NR6DaB*FBpx ztvkr>@C_8!H*H3$s!)P=bI-b8VUT)~IhnpcOrPE0GE*j%P8vxd#}msgd(Dg(C`-3O zcK}+S9w=7zQN;s2w-Gw*WXiGIq z{WNhgOYd}qID*q_Z>L3R@So`S%(S-&1_f+X1|Nj)MF;gO)9W5-s| ziqqYYB>uqwyE5hGnvBk9i~2_q>p?w>i_oL#MFq{56 zuA6pAlOE&z@l#k`T?Gbk+r#Nfpb9*;l=(V) zE-KNkPpIcjW3;6Q!I*ep>0HxI@5L$0de_3$`~7lgF7!R4)O%$!#p$mtmC*=f*VJb~ z7r$<)Qh~l$P6NO3)z)Pr@4DUzrHe_e3^fc}@5&_DOno*a>u4YXj(Tw#IN2!&t zF>8hEH1lBSDGSk9c(SDEYeQX9EmYKpd2z@40~>+2r9ursnPTHOxuriwm9-TwOmR8> z0f_eo*O6cFtWyT|jv|4RyqcCbj&cIxITMCfi07UAK0DZDv+@M)6yyZsaozPy=4uCvQ>KY$eM+a3uGJsu+kL*ZrEsuaVvY#mnG%#w9#I_c+~u^e z4lQpM%C>V0=;ri_l)EW=W*a?S62`XtHo^IK&2`j;Ykfu%pQLcgW3h;0fD-bi3Qy@K zzH&q2f{n{=TI`z6v|@!7y#YS@*A$^oEXFw+#Js@693u;vvm$iL;b$9fHCSt2W~$L5 zF@S69mS116+3}LDB};8f)uwA`IJrcwnZgfmH-+CMw)VD4TF(ca#j4U>7G8$`Dd)GV zs8Z0Mh*on%?s4HxbzkoA>&FE<&lXArDNl;Y8F;j+qgs zNL-*6V)S!Bli(Ei#mOn1Zkc@{q%jCdN-L-Q=LL(VUVXN!RtgCsO}2pcAeG!o$@XRG z_6Z(@SmVRY?kC8z#z9CMW_d^Hcu&9-JeFu{x@2%I2jzF)CBDba0Xl{nOFB%PGKuuK zCNdp~<=B%!H$WogzjWPt&41{+<@Y)YM$`L7Yx}!{6L^9?+=Np7hlZooddK!5VAf?B z-3_kqcunPBIJ1>zEO`sWofSEDx7xw9D1GP@6}zh0mOH=AOF!2JqOJI(|6Mx+oHHuGC9hhnb|m-ZQ9{<_W&|uGXZ0J zoUud6v}@JEBwAN-%rlzqU(rWATg>^YZRTFKMr1gypQJl{vH*cg)WCDD&c0wxL|}R`xW!o;QJj6S}12 zvb!2EDoMdTT9wWlCZVoX%GU0>|L|P0a4{GDlhWJyvKc?89V^QETVfb$6{fz9nfbDC zfSZxEH$*3~S-{F**DvZ+AU2)(jls6|S?5WnZyYsGv#;G;9&Pe&3FPgVzVW`UhelYU zsSmuEY`~F=&sdBJe=t!myR!Xf|5--rq z=30jj){}6AoE{(%nzGULt`2e`px3Y!D83oErw^ziqcen^QaFlo7)&*lIFCH&uF)0S zEp@ZLXhh1(EIct(dn-a(=aDA(E#=;*zo(SEdwyf6;RDyyZdb+|HN8^^hSWCK6g9w0w9n&A{q_^N*bhrXck_226 z!*6?q+HcbDm)<90ojJhgR$LiVZp;8Ox{jh&&)V{JxSFPp1W9LQ2J>~USPh0eFWq(C z*wFwDT+Y$>Q;7NsY%1C~bD89-8Qv63A`bi4lZTyB;zZMSP68ZayMxLD;^yaEZ-d#) ziEV^t{aKjiOnQG9jE>K&*aGx4D~olmusDvhCvi1#G6v@x=qmY;I?&(R=(=fdUHo>L z!FvHATCgp5M_fOd6yhJ&xorij){2_X5G_jxI+m$0*a4DAMt)CToupRR*u%nv|HG-3 z8+z}Mt3j_qf$Te8*M#;8Z=*C{_tpld;LA2wY9>DOXV9gps|L9-{J2%!{zH?+3yM9V z2Y(2Hiv{%30(e0$^Ij;Dv_nf(M$Ly`oX{o!F7%SNZU|p?a=%%+BG1=Dv%Jq<5V|~^;XNTj zyNA1&_@M()5=-Ex-H zkd6?jgv9X8b5`wv%thG8hS`oMXZHzh86PNT!XT1i6#H0$wZx5`f*)EHwhdCCUaKu7 z@%t=ciWF_PIqcmiA&6rh5h<}$%U!Hqx4do~)~;i$EDN^hZ+CD%EN#?C%L-4m53SMW zg97b4;^QRkwQ0b#3pw#0{u#vfVn1B|f0t$cJ)hhN&9CxYXDCr(KSI2u M#NpCqhX<5*Yyx0RjR7Sz1a=1p)$!@}nK_8TR9seX!>7;{fj< zrR@v>fztoa_frZT3jT)>&P7^Y9Bv2hGyE4M3wD*ze?{V2F2b%ZmiA5%ZgzQ6(@Q+;7-oew!%EHnGq6&44=R=C}uhhxR=pWT@E>?DC z5bXD;@E>R3|2d;-Z|>r5f@uBO6!#(i{Et}E$O&i# zw1D`DzZdo)gZoc^S0@uQh}-v|{+#+EFga8>6m$$epSP33lXU`;`p;Dp)wWHC#QvvU^p%R2@_*XoDO~@*Z$alYB!&-8yvIPmXn*7W{<_)4 z_qAjeCERoWK+u0vR&UN+36d#XhGQMfsU2li+Hl2%WJfcP|HGDsOo^ zP-LqYE2RXKdEF~94O9EA*`Rka70fuXe?L@o3jKx=xT9VRdKIC2XI`=lbM; zPuO)NOnXAVUYV_6w66AI*%k9v)-A-Adpb-tAOIQ`_A8D?;<>HIaif-fOrI1(JEPXl4sKQ5LOJF(qGlrz-Q)j%#Hdp&4j;2b^xZ>$J z>xlra#m`f7i$K>&c#pd#iFa>ZSoC9{hnHL5a#2~Bi#O#Hf$uVG9MH^dR<$i!Yvj^+ z17k+ghe?)O=EJ)}P4(uOXz9JLUys%g-=(>JyY#F;SpAPFH=D#~&HDBVm==H^KwM*GFz=dmrxE}C?r z?cnjc*49aSq303=NUVF)g(Yfp_X-^m<>IehJN`Eyk054$0^4v(oo#pL|X{t_ahzJ8PcF(D5J{UqxA_swXrNTdj}e+ zvDHjz8M(wm+e&23yt+=Yrw_WRgl1ps#5uB&lW2Ch#tD9CNLD5GpIJ+S>k=EG1lZXa zNIKj%{P2VT(H?1TK3}OV;ok;Wao(u-;$-01=XCx2cH}KIOXHx$1Lhn*6f6)Il40Tk zP~=bhs=8vVC}wu}BLucyse;i6#@fchtCa>#Y2_%_1aRdyiK~S`w?+w)hvqpe*s)p4RY)dssExrcPR4Qm2ct1wK ztP)(UxhWYPcw+tiMgO(wi`z?Q%!2ut@qFC`7nh6qVwLuohaJA)`P3Q(Q#^}Wg-*6i z{};69gU1Ib{Gc$4jgAMWn$ULkv9mF9z}iAUu>URYK~_ zJ|)Kd?*74Heitjw;@lw>J~&;Y9n4_L(tOEDA3@))nCFd`V`d!u5JX+II47o3$o`-` z4oU2|iL0hl=g!x{+1wVZz>9`@38gzimlE~$L}&Hl9H)OS zb!C56stF{rzfq2zY)QW{S=1Rco12!%Z8$Le-6+~G#`nvnbn4IG-z5(9;MJrLw?i2E zL6`*1Sd}%h8PQG775&Tk7Zsc4>-d~Np@U$u>*|$TiQivorSaBB%PP#)&Yl9r^Y?n) zlqa9WVQlTUCBx8mqHonZmXz#qMgwz3H#y*JU2eUs&$qq>z|5)szbI7mUOUYm6uPm1 zNnfp0YSC=>p1y^9URXBfPZ&6wl_8$m--O3^(r(7c=Qz3V(opfY!JCWq1}!3(1 zR*I}TV)?a%FZ#(|pdyh^`NKoa^{{wM_!&co!-Y8#v!$cEHF9qf3;i7F?)UQE%1mEH zZc%u}NV~3f5Om7;K}Pr3w9WGrqbqA^eK(RvvUkKCo7q~Z-$)BKL!f2%PRiL!yXetb z&3CdU4Xn)r8Y;>j%S_hR7>bv^K^>ZDqKjXNr*=ep=`c#BeZQ&a0F>-^`0Y#Ir@&@09gqYKOK;?G z0$cL9PCvIEJek!$_8rdr5v4TcVzMhM8gHKv)jBZEU%nPFi_?8b9`H$0i}QwA@b)2c z_ZP0oyZtt=9lUULx7o*tqttq&DJ|5dpQlNVvj7!J4dfSFFUc2NG@F)fsFvDl;k$U) zC$D~Ur4}Og{9OjEnqE**(kgh1UcAQvelrT^To3Xw0}1 z->AJWM>kO$T-QX_>nCUe1F8F|cBCAC5M0saW;}LKX!am*y5|Azsov>Aw6oNX-s9Kb z3^(DT{BGCi9*whaH5<<^O|-fGZ$;3J=2x5qO|PM3p8}u>E(>f9?tQ>FE~zHr3IVa4 zOBhWA*H*0Czl>Jl6e-GH^-vz(!``=3^&U*16fH{0oo$Y7VcVc*=Y6R@eF|HAvGUZo z&5TvFbhMZGC%St4`t;?TswADvFkB1mipw|su7&HVBkkfwj|r04GWbix_G*Cvss0vcR~LlM!e&1CUA449*08u z-6fG8J@&!e#E7}a!{FOtQsaGs%i%P9u?reSBYDZowX1<`^cC2G(JEh39`^lcDdZcB zc^9mlfC%kW%1EKf2}m17G|-T03OqgW72vNS5sc`?TI6VN9M%3-PgwU0)*yeLL`P;B`Q|+~-Q5dsv-Q_o*0RudfJ#Q6cT|esIOsts{nArEOQD;T zhpdQxV{#Q$9~YkFil&s{>bs5CrJr#|d;3B6O@Y+#qQQuGeN#vK_uM_IZPyKU!b3Ws z1$5R4(<=U74NBZgdo0dL2CP%oIQiji@Z?b7UDQB(W@au>kU`|(6)aT+-l@fO;>QOTRWbS3+6HBQFvINSX`;{#3b<%tRH8t?p&GH+QKJHQ(T^0 zXu9!Ao@FkMaL{p7Cbt%Udqi(kjaJu*G>8hC5oA&kKWX<5IX`nI)yQP;rt&1R7hzi} zq?6-b|6MvRw(n5oK`)|#gl2j&l+@7PzaV?nODIwiXo$A(#;g<7>l-t|mpU}bp z_bei!H&7v$XL`1qVE_Fo;Lt?CJo)&HKw$Apn1uOZUmOOzMw8@RLqF^i4aAV?((dVYpN{gb~r*;^az+@oPP9pKCRT?JpJV{iYzAjQ|!*$ z60}B$aLQAyGV9PI_dtC}`FT%BP!JRfik;=csjQE@M7`@Di>8{Qyy#tCuKVg=p1Is| zc-(>c`pZ*i9XsH2N_5{>+M{Lp`g-b8T@4h(%#u0SZz&y`lTHo7R6H#nPtZkG&4lM{ zpUEzkgSNX|rJUoY^1cN+y&~?cvnpQGs#GhmODQMakcTl?bhp!n;-^g%e5}Kn61Y3h ztlKC?@5L+Nd`DMHjUF)YAqTRsVfQ<&(4y7!0(VJEQFDy;-jrZS2y(Rzw$r;^b=?$l z)L2K>RmA=v#a$)dY@vKm>2=$P&de2|joLGlqbTP{saNCE+{ov}GWy-?HEo#P47c8T zUkLoT4Kccc$Mf88%e-y{R_*k+ZF2lzuAaE1#~u*B6~=^U$4qB79cN>)Mo07bEVl## ztF4Z1fq+}KrM$qgGhVS;7s;)S*-15;+34}vvyE}PA3gn069Ro}lk@G#-+Q5V-zsp%#+zzs}fODJF#Ir||jVD$S0rCE< zd2ie8YJCCUZDw;(z?uIx@H3U-e5vM;gktVfYID&p?=3emj>6ceK!)bW8(A{l)!%!c z2q`yt9HHD|ywI_itY1Oh1+ru?#B#6aOOrJ6WqKsu?^4n+w3y6$j;UsNiC@14eCJSj z`C$Ra4szzFMEj(@r%6q%TZ?E?;^O&K??rex+scfHt+zEZKE&2&9hao)yf#t+ZViWL zs|ccZc>KCRIORUCaVK{wN@ga^cyEw(lC)88FW)yu$Cl+0jCjWHQTUU_%CjnVa-TKT zCB69v)5zQKCQa1Rj2%hrZI1u1fO>IJo_Hx+AC`FL2#)lJMX`gaFHw3nD_TB<{$_ce z3dCQ?vjM$7V>hlHHZ7u0=5v9yF~&+O_PBe9N}-V>os`dlB$QXMt1n4zn0mRoHiVwJ zYc%u?1XspUMbI9Be01c<0|+ckI;?%tUXSNr!=<5Q`?A?7q!ZsZSQpXJ(L57f z{b7XT;M+Q4j1Ii-Kxv~!iJ?z?VNmv^iu4%wpI6DeUzkwu;i6zf)l#Y zEJK9C*@%YLD0rR-@CB`t?JS5KA8W0+c;kMZZj{}0Y?m{yBDJHAlr&i?p?aqcR2g*X z+_&OjKhs*O!GWGHrSwpBn4R}g=E1jN)p-|b?|RjN^r?1t=UFSx5)G? zz!sGNa7=~~(Hrr8t;GwG0v`Omu?sVfiOL!hy@j({wfN_Rw=_IisZH%WpBYl!^Hq?J zyv~gBZruBBG}?J!(P-&Xp|x-aC3_C?q|diX)|s)(NnYKsO30RTRFk5^Pn`=nlxOKa zYR;a|8@7A;q3*y?*C-88*faWo0e?aU)rB z^k2^$c^8as0+T^2dZX+EFC#R$9#uM1Yka}JpE!rJ^i%PM+sU>-?)Cxd^=F7`gDrM& zIuEC&f1Chr90x+WD;66pDOhe<>d(ilCYQ#0(fGge*0ZgQln>jnImp+#B}F9CtqQq% z1fj3*V#;jP>TY3-)xsoB@xOMz^DVF$3B*%{mh7Kx}iv|-6eBdtEn>Fy{-K=f^=qFfsg|m&9=&C z0B+Ke)@*FL$o%0Ht;z{(97*L+4Cjm@USK;5 z<7mdauIXBd!Er-yPc-NsS9n<_4^q6|IeMv48zxD?CZRZD5f;XUp_Yo_AD(IVwq!9! zx08$UczVmmYjVdE-Jn<>1L&kV5?YI%NT7r^s#1_v8c~sHe1ih%@{@;&Q~e@9+rr$?jg;QE#Sqq=P`GH!I zq8v}l(_JE(1#N{w*p)u5ph|o{3#+}RO9vFmjrJc(}qA27eqfYk^393ULzc*?xPNR|2)>kq*80|KA|qtL`K;RG@+DP{e%e%4|Y z9x7d<{j%{lZAV!9(pE9&-$mkKYcw0MaF7?hHKo|&@U?E3`Pa*cbiDE>l>$a*$|iy8 z#X%m(#|m5hHuqFy!7B2^Cq8N4WqxIb_k{N9=!Z5>v$O1nAYz5? z;b<5XH4^&V+mJ)Gxy|ahti$fVntQK0nIDEt#ORD5PR$KjCf5PISFSp5+w_v^DwZzupjHnjfsrW`j)WG`1!wr1uq@153x`?Hi@q<9U3pnY(wpvc{ zzC(R`k)ipwCy!f0IQ%O0Ud$;;l`!?GAjU>D7kLep0B0YI{$B740cBu@KiSJR@gb#5 zq5z2|Q@W;9yMmuRsh9k_F0>%$Bfol4+JNz;H2zvQ%}SIa7U2X-gg)8Vpm(fUZ}wri z%JWVrQXci^m*Bf-Y?P)7%K-3`vjxTWP+Ve6wt_;NZFr$fEF~ddm1_(j9-L|a&X=6UR4o}yMe|w zzx(u#Vl;{dv#{v&c+8jf5YWC9PL|gWlP>!=KLDlh*Eo`U!3&zkhdoB%;XW`|0cw)+P;Eo7%3qa2OHA7>|ROk&}gBzg67 z+%OpFu%gP58|3{aS-1t>og%UKv2GOs=YQ!6a-*nZ2()jsQ^D8iS}x?Y{C8Of0`dEZ z@C`%QR4;41hzInmuRAk>iLTGfVWb{?YSY}#D?1^RhrY%}?y><+or}1>G9Ef)V`0(g z0GAfIN%Ui3;~c(OjI{#vzc!k@cNh&hzD-X9)d}&vLZKnbu_hsM#k6C%Kr=3Y{r3 zX7-tX9Q`=Jcz&Kvd%5_--At(wNW{u&=tUB5LuYwvC+p`w)L~%qD7H4;**x!2 z1UH@tB}dbCEtmnMMYbNtlO?@n?<>PtTqB%qhCZg!RcGWFKjTuE4+H+U3cr zhRJv%M`+G8yw8%|N5%n{gA$%@9#JU#xcJRTqGOq8zsjC;2V-cD{r?AvD9mGbIi$xDqY#mRm4<9sS-?p43P=E!L6^q9 z;VcbF`&>4(>YPGy{xOl{*k?HYw#$?nBT{6y!^il4r@~krhR72cCQ!KSBiK&N|N9KI ze+&YsD0NgwTN;;L5vO&0OJBo5sy)|34+3p5xV;4%KJ93^6+<_w(w#@6UJE2`F^55! z$M*ysUZ`E?63hBERoP<&z6&=Xx36hk&xK0VId9zd!o{sO!evZ#ZdY)N)ELyZPpl@g zpNF4h^qOJztLl%viP>7YkJz&$5MU5OU{Lz}{^lJ;2&ljc;rk~f`O8iH$@C=n9Q{q4 z7@jK3>1s$jE7~JtcKP9&;MtAI@0kD?=`iO&?shC7;*$J6%1kAw2ib;$fX5nSQa-xN8Z7=f_C zYuzP+*V}UjzAf&4{53d`vi1$Nw&r{bvuK`S+TwYf#(w4lzc+DOkf6q(T)fE{PE~R> zi1^Fsy%v6NaSReTbQL__$bG}`L*$+tZh96wc}@Tf-u$wQW*vQ7)QR4CyLMG!vg3^N z(to+j_&{12c9wPis?<8uo{N0BgnnlaXrYX}0Z-cpoGpSj+z>&XPmumG|4D593yqht zL9!_m+~8#S33!@!JcaW|Z8t5fj;P}cZw8_^&fQPj@_X0DN7zV52#hhJ?i18-5}`SJ zQB>-O{W}yb56*(k@uE3S(fr7_OB*@%l_9Z$_lvn!iaR~V*WHLAf`j`yHHu1v`oHTW zD8V}*I)6ZHsRK9JRN2eL!GfB5)wl{(E_ayLl-sIK;GYmAfekPHth)@!6BsK*aWyb6 zWyGfwybaVi&(Ze$`~GG=_?2H9VU;uECWydMjjcttXoeL?>A8h31O3hf+GrA@Y3gkZ zD-*3I8IHaKM5IK=jW&s6U8={6j(;F`tPly{5eUs6j1nP6q&>O2Ah4fl#+%OG441KX-2O#BE9wa@xCS?DCAfA8J8}1b z!We$3CAFhgac9L$7iXiE<^A!5jHft0=G#I`#;6;j_~-|8yTiOEnrbJI?OG^yqAT%Z zSW-?8jNUo`n7tUZMllFySdE}?!)Bx$1aZmjDWwjOnhQFI!p)3xeyyI0Z>uMR3uW4} z6fs)1$E)w4G*l_!K~Z)8TW2629*3Xn35Q9!O<%CIJCn>pY0q-2G~ZHKdY37?p7$0f zPNu2s2PQ5jO${P5ew?x6Y(+@9Y@ds%IK`>6r2>L`mIS?~+N~@E4(?z_ddYK5vgfY; zJ_)!PG#O28pSCeP$E@E5Ejeu>gz)a}8Bj%SxLubmJXzMlQ)zu)4AT*WPNZcce{$Qs zaX@twE8R0#hbf`hdJutSV&4h7Fb(FomvEW>Z!N&r4PXG0`Sx721@d~Lt+N}O;2j?KdoSh}7fl~@_Rpsb9Bw?yzfGKo>MhLe9hYs0cAv;|+7@HE zynwTRo&|BHD$KVM6+eK<^B^^%2iC?^yM0}3-U1C<(!WNuGz;%W9RO|~Io+_8nWfHz zx)9NQV+6;nF@`%hHQ=qdxvr~jOH8?{wzP1xd2IA23R-4o#Iv?06A6Kv?{ zh+Nu>;9N3ZsgPrSxajZMM+I5kHl&=Uwx_WEbGNsN3T=Fyo0WUb4mm<6fWwhJ8)eLR zYx+6-V6Dy1DIsU2V5%g?9Qfx?^qqjHN&x!8mn6+DMxggN``sdBQ%C{b8X&*?eoH4Z*T$mK+p*4Lw{NOY_-wyIB$KxGD+_HWkSCdYf0zPE2 z+2uwe6g$0h-^j+im?)LWzaA`cuYlRULZ-1Ando;vg7u9^Cwc?d*EPSC2Y8qx8vsr@ zhdQSdFE$kX8gYIt5~bp(ei}8XImw>R5z&iO$^(-SeR-RNJ!>M23^Lo*6G)DN%oc>! zk*D1q#ky-t(#@U|T^X-5IL_}XS>qb2xmr71`9)w7t;FGxhMpnpq#-=bs~*Y0@7 zwhQMc6sEH)tQ@m)^{d2(?eo;oeoHnLFrP>oEGaq9x#i2Cz^!2M{t>Yt*6eZkYN<6ykjf_iz^5v5S4 zTJ{3JcB$=cVuxp22ul5p0kF09_X_dC?wvzZ{o>92UPvMv@onzd+Ni&`!sjZbBEOgf zo#XhuOVwp{DwqdDz@Z~udiMH{ajxa(S2?1t7|BDuZwxx;*E=`ky;<)gMoattV~5RJrFZq^rDRaLYT`zEX%nJe@qc}T=|b8hH7RSo^iS?GbWh43n?kl}KKwMO zLMYpP4QHVbi|hwgYrE4ChJ-ywNobCfe122!ohuz}IqTV~o#^xgN~4n(m`wpZ;;-9l z#nXhXp+0g%HI8I;x!UD|XFp_4je#Jy9BY0#y&_IzeWiD$oS!8&&U_C%jQd;Z^JD0d zO^)uk!z58+^)h9Q?@v^EUq(T$9<69fYv}jp5mExVXyxQ`VO}QZZdbRwNP|SqV)I5d zp!h%{tR?aKx9vfFB0d>Li6L@}HI-`1$Ae@WYG?!{s z112kT7RzUOO4=J19OA*(@f#y?eg)$)x)wMioW~iDTnLyWI{gDF1}ll z=l~&o<`ilxGjY8Sz?G-DQJ9G$FRmq1vP%N>^v`b~q{W2%ukKDrF~}|5`Gx{pi}j{z zwcpv}(q<==CtIr+a3fG6guSUfEh=|~Eo{vTeQq%)Acs9b$)e_`8KtoE-C9f?0k1|h z*AwvUYz@ynOODbTYSxC0oH&0!(55QvW7}<~B^q$#G~&$E``F(H(*-q7Neklp5J%@u z`xdpK>b}EDk)DkiP2hA**qFz)6Tg92jE=Pgx>1295)Dte$JDf##>5CNRWbYX`KMwn z$Ffn&A)~o^CbjxWV0*WcmxviZiJcrD!JSHY;kT zPY&VohfN2ELu)o!HT{jF$S~y+&Zwhcz3B!;lSt4}oW=w4wW)oyAERBr2|KMiQVLuZ zg@UCta=HRc9Ii)h#DeTodeg$v?JSCp9InW*%oEsJX6IM^t%n4viH!%}a{rf>*zVy~ zK-|~Lv>Z`nTQAi8W@n-?!r3rx!84M4bGr)78p9u@{Ix&+Qj6TbjvRUNPTdg5!madX zH6i@0;#`N15F<#JagA%Q0_TM(WPU8jtL=Jt%t^}Qw**W$ZLiiJShysnUeKo%;5RWA zl1AE1W-o4w#G6G|Eceg+4jDS-Nct=E+rzCr->XfK*D`LXlHnsbxmXkvm6|AM(@qZ4h1L;@NB&gE5=W6pvC=A5q9$Rr+9H@Y@T^^+; zf+t*f3i%cqyUJAJC%7+h>9hIO>S*>5dl=r3tqKI>^^J7s{!1gR*Lqfj9bvPY#25mP zStHFF?&j6?Cf<|F)EMlCFZ-@la^qz{mE=l$L@#duDf9N1>xx>#?TYKCOxDUcuk6y3 zdVpLmcA5<@BheD`uq9mG6ByrzPVAv3rRI36bEQ{Aki~$5J;FXb3{BsKSmn zV}+lbM*|g`1D-^W&mmQoP9MZ;{&|!GKn}b%_0vMn3q!9GO45VRJUgFRuRw?#8#>!> z$1Be*F<0y2VDJc1xWmFJ{JGd0t6*o+hLfMGjduu5gMGj4Tf`5=t8;K!@W#wJK|tkt zVCcnJ6)3V4zAoxru;v+|>*X;9A15uxwi`3)CrjMQYk|?SEHhWG94>hdqgIl^ef!l| zS#V}NbBZ$Yi+aTJA4K+yo_@=nNymd$&#Y)0k=Aqb+2?B5MrUg z!>xS@Z+SBk>pw331QGAX8~!uCgsr)}X2>g7WVL#S=F%3 z%(}tg{qb9ULfITDa~nfl9#2HG&r{>uoZF`HAe6P|M=*n0Ct`^gpbCQT0fh6U>z;U7 z*K()X;AJ#mX>r;`TRpOvqR{maX#eI(m)ZU!U-j+>2hTx)%B-DlUO zlZ%EZJkna6Cp)_95*e=?dDhAtTSJtLusjs%vKDVIo1}0%;9n+av z{RN6&K}ER#*mg$L%S^(nA4zQbzM_#PRBqgpR|g^^A7O0MCptt96k<8iGa`Q%(XJ&E z4RzZzjgP!S#&^EYh>T{H(2>KyuC^<)*O=m)QSD-MIaz4W{cuNt4|hxn?MKX9{JMm- z&m>svy2IlI&Kv&N`zcdAIyd4f-4h`gXxtecZW}0&k2M(lt|sNa$P@3|@;q3WBiW0R zNE+`;d3!UVufOM)WK8AoN#IuwlR7RYi*8 z^2!J@X=S=oDXtc=ED~9spts$DgVa}7Q^6s>3JQ7b_H9+^U5uV&#iwod$VR~FBtTu> zSAd&7s6hjh=%p#Lngssy$L>U6{Org7XWGJGB3|IVf0;F&>wF!ti7KsS@@LLML)QdHQJ?0)wP6KQS>U_P=G3FfUtJS*T%H&j!u8mIDpCA%% zj)q+oz7O?)+m5o$D-?M|AJCj+7o*Hc%=F(>3$MJ%%6dJ%ehVdjp9cE+JEXry7|+=C zm&QuYoHqy&`}dptMu)QlsU{ANr=o=XSw$G;c85FvIkU7l{3*$FHO$)ZlI;c?O|SJ{`OlbEK>0*FpR?zQ(T6Gx*WwNl_gRbbiI~C% z2pI{Gisb?L)LCnqTxxE>c8{bD>5Ci9AYzg-pw)W5FW`^7_nk{GCaopeD(BhDl zlWnFl4RVowirDvQHvmVY2VVvE)-zx{s+ccYZWw41!yAo)vp~^9q0u3j-`(|o9=KOW z`f8R$s{>Z~Ct14}Y@!h~gKmY)8PbO!D$}}V%@6J>^Qun2@tKFRo^~xbAi*6QBxya& zLf{=8YkRKS-(Vek9I?24VHldw_uM` z_L#OPs-=?U{#*u5W)kPeXL_F2ba=Oc@envYKCiETVvC#D9=8v-H4IL2D{0@{c4{14 zbRl@(Tz-WfV z@p8?MyVI=i@Jr|O)ON8Z<_96LR_V!Jozm&W2>x1Xr+T1r_OuZI-6GpBqwZyQ*j(Vg zLpjbBPd_VkTG$(0l&U|@Ne}dW1_o!&wz(+-b9M>6GuO%5?(e^Las(#?Vlu$S?RD+3 zUr8}_bdKDruBHOED}__#K6B>BL{a(sEr1<{vRIIDHw7YCci@a!Xpt;MHncZ(xbsLP zM!d#!U6Iq?Tpejto_6c;lvcg;lNaUNU$VEB14S_Q+_xM3>f;5O0m(OOsi$mOPbz1t zgE!2UOER8Gu05u|y#OqxzD(Q=6Cd#7{=e{JVcjbXce3n%fY8MMo3i?MCSJ-9fG_#U zt~1>CJ4Q(FMQsNAUk(GYmr#|AV>7FoYbEe;QPuTF#DksCO_H+5Lv#FGnfY()k>$^$ zaTlZ3|JH}`m6B5Kn$3Q?_j@6Z|#Y@2e1idZ%k+1J=jn;zv(Dk`NkJh+jj@Ct*= z)$_=;i@;M6)h~Yn?uI$$iH5%^Ca7q z*y|uaO!zgaJX2ZflG_2m_@F>U?kRj*;ap<%F+@y`yaKtO4NVoT5rD7CT#65h zC%5>m^4WS9JNZRJOE!HE@G^``tG6b~eQl2pfB(c%SH@W=zK$m%_axquxkMkTt2f!~ zaa8ABCq8Z;m!o@1*%#^k z_DLi6WqIJ1@w!bua=wou`~OfpBKsE$NC?l?MKDV<`7-Z*ltrm~bah*mOA+tru$^24 z+f+cW1yc2ki5tFp`Hn?qd%)1+aqOM3W8&V^%orE6S=x#EvhEm{0v8vNv+rRi@M*AF zHYlWXk^KH^vF(2?=1OqDNgmFw%b1V#VerMV41}(OnI@-0sa&4UKeZIz^Cw%0JjgLe zIL8Y(TQdWp+kg^W)%|KBq@~6LhO}+83@MbV4RM$>cgu=28zIrb*nsQxsSlgU{bRF~ z|JaP}!)D)<#ReX%BTDTL76JVnG6MeplR|5afCz3F_t#Z3MNWWTkLrp+qXL9qcRgejeT3Cpaf#W8`qfAWeJPHUdB1|!-<*1v*`;o z1vlRPOWu!$fCoFK)5&{29}|X2{N%$$_1Qw?b@QK9@@X&-A|L*IRos}W?+Ld{-g}`r zeFS7&OAfwSmoS+yrQgUppM)v^1`Sva)Al|_??02!cG-zK?Y~Kh{|i1(^tMUGa#m)v3#}IN8{>#NA5W91R>H(=R)J92+~>j1qYSGn`7;P(&ze& z4&*e55G3_aMp6g6pc?C%Ehqc=TW`@W=qOH)a$VT`;VkY`PIxd!_@Ug^BiWPbG_CS& zvu^l1fO@7YXV8rN2n7ZMHv;i@e&1Kzc&7$L*Bky}SryI5=SfQoSBGN6{AkiW$^8yt zpC(kZoQ``yN_MZM!uasre2%#6#QV}Qo43mGEYN*Ej(TXvlz#trDvz{<_V&r|{?`O; ztcuUee<#Z1JGi@z$a;8}Ra$=Ie=jf(%lDZzqw*)@A1>ywS0yXFqNO#~>A=H$Bi6(Z zk=6%u^*8wJQTvz&&a5X)X2V{r^PXC*bTZ2Dx6t(QF{4F@y){O%cLXV+4{piZTwGrM z8X5{??-2d|-o%U23^>{Phgd^P!6xjnM6L9ZXX5d6=0^S&F}nUbn??iP#4KWz3oL7C z%Trq1?4)2hSA_L6DpWGu!4x~Y|C0p2#sy`uk86u0?}t|#gDrez?gKBgJdbd z>7(7~3?=)dErP8WDQkMBU?*d<`Ss;PEYeUES1c`lR9H`*o?UL`>-A&@V*3HpkeY z?$Pw=7c4|dl%2KIam%G0#7;N;KYgl|E}@5nI4fIDG6P}Q8dH@U^4$Wv60JwLzIjd{ zkh&y|MeDz{*4%Hz*oBhQV^<^#lOf42Y&>{h$rN{XplTJTgm77P6z}?z=I0XkThe|c zj$lR$Dd&u+j|%?@U7TYb>MZI@jHHeUUgQ;0;+64TRea=*3|ovEAYH`4Y?85vtHtGvM%~p24CTgb_v;2qlTO~r#N1fve1CPp{{m&Y^mqTf3YoZs*yn)Q-)-wQ3;6aSJ&uT;v}vw2`I zk3){dINEysQ|%s4s-wWM(gecY$4j+mzh<9>o7ENmgxMpfeb79Su&5Tp8tjJXa^41?l*Z$uBwh2`*(M~t?e zDKCNdBjMI|`WFUfzn$dC7&nPi^-l-4odXD7o|)d3T@x>|0Y(kJaBzJ@$9DEI6sPhn z{?mlA*Yr#v{Ad@NoTxzM~`2P&DA~OUA~4 zP|Y@%9~a2-6JOhKyR+i}qU!zK_gsHc>A4lvJ+`@h%}tiYY={*{dcYgz`J13WG_^Dn zj58G<=i~NqM=S+812@aN>XYJ15N&M>pvpuHF^g|u`}jEOJTwm4c|)~jUY-MD4EXFz3tl^?^mR8Sk$k8kXZSeS;| zJunRT=};d*Cpi?}oFnS*M}7lHd21PzQIku+EtxEo4(qukTe%UwW4Zp1_)3uS##g0* zuW7VDsQL%`A)CwW%~gKCGKsS>XKl1(^h_S_U0K>YTHcz+u1R@Z_E?Z6D#6(8yT={2 zaq;e)un@*=w4xWu(57!_(4aj6m?D0^FLtx~)^#1#LP1lS^2L>j6&fXh)@tZA{hw3V zvDJd@bcgLVZDtmBoS*(wUTnKTK_I)kDVBI@T6{1$ht^d|$_%FBUZo)di}K{#7?4XH z_wTe!Vts4^Wlur zM-kg~2*9Q6!nI-EmxByBMyj((L+;3!4kF){)!;$Ti@IrBmF?{RC-d1hZBAoZ-lmgkc7xqgwR;tpzY# z?<7AIq_RmDKgTdh`CNyNejjQ!JOq77Jtf;DO7npdMgGZr$2g01gEaH6KUjrA^PiJv z6Q;4v#tOeZ#{NvDTMY5RN5Ur|dh`y*`X={0fl;}@goVzldo;f`qQap&FcIMf=>>nE zJrukV$rR#ij%$`&+66ke&TYeVrDJ2f#>lT! z{V40vU3z;rKCISLCF`G%K4rQ7?wekNltLW7B&kN4tLm4(i`Q|N-_~T@R5#wa_xmdC zv{Ub(>9#-q5c|YS`ZGyRcsOz{0!2yh^0La0F3=u!CIv;zzsxkqUYAXWOGotLym39p zn}9*Xdc*|XbxX0aiA(JoGBiUvaCA09s_h~Zq^L>%4y0P$%ay+O`w!5%7|l-&7a|rt zq;oT-4zrcqE|jB zK4$5i_4Gd5$m4(x01leph9MErQYM-csH#|EsO9Y>TT2wuJy85D3A7y9IX$ z9$bSv3>sXA0S0&1;I6^lEx7yO?oN=wT`qa=IiK$R0eg4%Q?+-kT3xlOVJwS2H1Ks+ z>T*28g2XkYYB^La7_evhIPN&^@v4vFb=lE>Z2(umxIV~x+t}PNj5=SQ6uMOVdH+5M zs96^r$Jd@S)OCoGNg{V?x5qY#QI#G7p_ariOz(2PN@9?6NfH+nI2CSAd2kyMt{K{~tS)E7jFtXf+xrZ`gC3&jCx34gr`Noy{$f|ita+x- zxdyaG0|xWBFn!wUM&iW}EjH#}N*&_)7WAO4*}0r;Eg~9T1}4zo&Nv>((E!IwPpaB|A4x3u zPO(;1l4ug>CsQtDJUjPl1s&baEm`{ZLi7cJXogH_pchLFINyodN13$3sYqLou8W}~ zrr)T{emhT&UFYBmLMkWiHBpOFz-!IcWAYK#hB<+~RWmLeene z=)+kqxnB7tM+s^&cYyr_Ty}}c1%2lKM%3%=;SDo}W6ftDL|Y{}(asUIB_HleO%+^wfE#GH_fZN( ztF8Un`wAL`&ZRX%!%!%G&Ke2cSFtvBr1iPmIrTMraau2pl5OENV$ss^u=8$o++DGl zK!UEz*3o4}Aqw|6Fm>x(0u$j#~tr@b#n88G)S95FzV~{NdyV z0gHB~Sek#Qstk!Nw?p9OCR&khIA>MOS78KYDeq|spXutH@qV!wkGUCjtPbT6T z=5MPIVL;aI<3Ek91k|1A;~Y>)qYir0bm#R%J|5KHvRLd5wQfj=sU#&GJI&A`Duzq^ zurefWj;j3h^$_QqFWP$bE=I6c4ieSYRT>9;Hc@+*RWe@{?6Ak9Im+ZDjM>8TBVO!k zNscniEu`wG6fnX3ibR-Q{JGL&@r&=`FsqLY;|AP))0tAA`8-pcqZymAPLup1&ZQ`x5bvLx^sFWsb zJ;y3rvezv6Vl0c-Ga4HD`hnWi%V{YsL_vM2*S@zmUFGQZHNN~=XpAQAZ(UkdCJ56( z)uSDd6u0C$2gw^9z83^J-=N;nJifQl1li(R)j%%HOy<0oe;9#f`^;+>h2!%>FLf9&_DSS360!_BR)cw<6GJ zEN*2zGs!Jvq9ip(8yINJw@HMxxj`m+bQEd6VbE5y(zDYl$IS=*s49BG;9^$W-{o~) zakY;gKW&uyghGQqLHv*uFjL6+jeW;A4$XV)XqEY5Xfg}$bzMw(w7mFBZBW!WJ1g_F zjBP=Y_N`g&a^3+xZwItD@4&yUZIK-Wgt zIWn!#FPeE`XNw1Ygj00I#`>HpsAc4+EoglsUBUI!{0l6ogENuP(xy!MOGgajO8Zb; zCJREA$)7}x`?}T+1%^`*Q584QDc|aPtl}|EUM-8Af&vo9k)#w@Hq-7cNtfw-7 zh(vU`A%#8;99?U8ABD1BmiL1JY3l4@L8JI=#aoV7+WqCI=vhc{H~eeWd4N+h|WbqPeZHxTh;XJsUVY?$k|5QywaK z-!Rif^);P@|7eHplhH!mwKVcVs$eF`M2_LR4yV_MMNIXH-K1#Xm_v{w($+9q=7Qi% zM?KzhvxgbW9-88PM8a|tC5ADGJ1k_3<~yg~-YlfbS<%Z_QZM$7eHrh;Th10IyyG|f zeMX9~T58L6->NjyfqCIwIM1>O&*y}}K@H?qDRNp9)y^DGoF&#cgv<7BQ#oesR%JYP z0CIJqbM?!!Knaeeo(afsFh3>HO zD8Frcd|RaKNVRl%)gWC?2^_Mv9q&y#&TA#{f!Zb zc-vadU*FL;WB)UG(nXeC6hFgsE8~90qlR6!5@yeP1$5REq2qon>tfa4kvtN`MiDx z@5-t+3?93nRX9BKs^N1un^bL!v};#K%$i0vf8kF$%mIAh;mP@6!tq#n>t*; z#T~(Uin*$dJY?>U#zR$}lnIZ4C|&-h;X}-QTJIw!gUBZAA7Tb9!qMr;Y4Gv^cE-~t zAEh3XLUx7V#_Ve}guVRO{_Ro>1yy_SL^pOSzz@0dlVMk(;Z-VUOuH{8iM;xaL4P88 zojVh&wp`K9-!UU7pp~;bwEmKhwaU|m0SYi&4-ycY#(dWT~@rAl*1%qgdP_!CQpc{ke@29fyG4=;K2#6?RGXFTPj8gm|eK zH_Ma*7(d%mv6<(=;CRKFgm3Xo-Bwffljs3%D@-x=j{zUX)ptd{>O`Wy2~FX+dA2SH zRcZuH`L|_-$jM@!2fxrrG%A~wXt;#98nTj?EAGZiPG8T1!_K2*U~P>gdQoGDUkfz_ zTSN;=0)8LxF{}0#n5cI@GdNXjscjE$;k5*c8F6H`=$jV9?W#K}wS1`b5x|3Fw{KK$ z@4W$T4|F%j@-qiTQ#$Z{m=e+KyX!m@wKnS-th9?Yc9lql*R$lro562aghvGdJIu7i zD6GT?J)2~8W#wS5nU*Ws zVxjvlz}t|Bc#P9}h~P}>o@|+!p`dYWyOBO&&zZ6AxVTV@+w^N{y(Ek~hw!C2uMH(V zpI1)>wtp47_k$ZmR!bAYFqxL zJP~KriCjY=PlE>a#hthm!;pV8URAABNn;WdY|Y&zTfkB@_N@UxpGE+ZVLqfJLNy#c z&WDFiZgJSZ^D1qqzTKh1Pzbs>d8Z%LI(b|zA-#Ff*=bkqaP+D$aPLJH&t^4=(D1GP$$uAJZI zi><8JC4#?e-N|n0G{#~y0H@Wwi+-j8Zkt@>zt#&nLOp-)S4yh0Nzt5N2oY{OnO<3; zBFcSN!h769tu{prr48b|isV%eS(Z$`aAs-bdfZ%<>dF@o!eDXdf^~Ppz&J7-)sdyd z2o)n|pFfRy05T&H<{GgH65LQxt^Z}$ls^*WuBl)CnG=RZm86W zdX1`Wo|35wM<^FRF>(tMBQs(&47*u48R(H=}>1AO;znC zGhbv-Db`A4J7ILZGK7MJ)0FQ5wd>d?05UWMnjOl~du2NVktY^l$$_>!^BeuUxFZ=p zYgEF4-ml|OtpmG&aD`QCgyB!!J--1#pu#C}m-`c}$v~G8{`iiUppfKAeV1U}FK(W> zAy-HA69FNb=ii?QE`04%swFA+(lX>JB}UPi)`UVjyl*i*PZIE=_AhTkjx)5s*V>mkc3^rJ1Zy{caB#YHq>G6Uz^r(@9B ze#r^P)`J$4-`rLPR_+m?yY6bR_Kd0fl-sABTSaM3vhV6U(AFKJjfav#6J5ms@!h~D zdEjd2I8*|_svE(rU6+SfsZvPsbz}ru;j`VCzmv_t-*y-K zm}=<5!}+IGIv7a5$e%a+duho+$y)D@fM^Z8JJ@=-lGcP~GXU4Rct`Jbp*cA536^2y zSbljkl7;(NAxY}ZDe_Rx?91Rh-NfU~c{;oVp%#r7u}B6}u`%H&1V^OaSjh?W!59+` znW8Z?=Cegi%%HeG-|<59F8pHUyEoT0!R@r$BI<0-M1*%w0Dkq;orxX!RzsU2FEwJP z0i{u!`0p~Qo%_p*E0|p^Zk(zGCLWJj&2avS*4e4crp_mPeW>BQb%!%((Q9LuH8E2u*1Z-Yd$w{l>=q=SS`JFoO z9CEx~Uf(H}igq#lFtL$@d4x-1;&_K`&1uSP^o5sqVk>B!S|VWlAO>$P=is@KBRWn& z^`;IBorHj9OC@ZsTf7{HqAZ!8nl$`|g>R0ez#LY~7I=QgQ)Z=>uiSo!U94S79vr1l zjVD=F8(kRZan2E3W~ErKY+{`@x4E+C>VmQ?z3o$fRa4(f-u`|rSRTa6lkxDrwuuTu z`Y;~}za#q4ED0NHG8$$KC6&)JTERCenpfHA69(>w9|JP=B+^Z)pK%^(5nj|Z zG;>Q{($m++R2S+`A_2>5E(&+?n2!_-mm{X{IzH_wc1rOgMo?4U$ok9R;2>H?lE^+R z8j8?qct0brLj=1E>e)*l1y4&Xs`3o8*At3>L+-+30 zoJVuPS$*k^&~WHVgJ#Af(kmor`ZXvMK+jLC?TWF~p|!^z1o<@E#rM_cFj`82AeN7E zy-9-5p5p$~_dW3RsGvGRc%hd&a}z;x6tMPIxh)Ryw4Q#CGUc1m3}e%cft`ug7(A1kF}z=X);52QlgZ z7so!z?LWid;3kjVfRKnV2){y7HMtR#hJ5-obcC$EyQ@owVe!?jfivsNA+75k{3+ITK0ig`kGWf8W5aWn)w~tx>$Kd@uW!Yab^WARW3!|uhbwR_ zq+dhemNi0~1uy$52oze3d%p3@zMvtPjX@W-)#Xl)aX@Kb5u&EWHE&uaX>5aj;6!~D zk86JH%P8}K40jo+&16KVTqTKzH2(JSGFmLw;i0D%3JCp7LIcYfIA7AOo|qN!bkxsM z>JVLdJIX_`Mt(312bb99sA#YVCHw*lu=!YYnb^&Dkp8u-AxxWD0^L+yQ#B_@J5t+5 zeAu@VZ}u7#mF-87HSIK$bo@hA@g2^?*HsVx z941*g-yD!DN7(`t73 zj%}$*D`}K01Xu7ZelkSAaQCe1_H-%KFSjgg6nv`*J%azXNpQ!L*LMyAHDpr^&*TB3jEyo?RlHyf#a~J#uz-&7s%S-Evx#Mx9)%|6e_<;=fb($ zoZVR#CSc=^X0}ul?Yb?lyo=HJjleZRjL^Qmb`#hk=Y5TWPE%j>*s_`4Cfkc;Wybwb zQlB32O>{H?^LQ-_o+;x{kr|YrsYGx)YxdblwjyEsNKB5Tt7=#2oBX+P4w${Cg9jqv z8yHEUhmV@-C#VN$DKQKyaq^~a0qk_XsPy*sp(kB8C(2nKMx@&NNP+GySZ zGf}RIGQ*QI1}>=lIU^`C8C!`YY`0n%X8o&O@X~EsfRZ)>MKxnz?8f?-rcvbSOq@wk zUXAvQCXbz&hnY}l8+_`Re$OXq2Hw4vkx8cx+DCC{RH$~3gUf{SOi7`bwRR^Cr$|#f zEpIKJ>o{lKg+Okow=Naik&ZJRLZUKziggmV_ugQlE~P!W2SFN>nawUT!hm7xWG*uG zyxZAWzq&zwfsBku|KX%`p7!#l<_NNnb|k*?NjFA2Z+4#k2E3rhK%y+6X&`lc$n>_o zjm|ymZK9M6g|{E)FEWoVE5kP{9a&Pq(1DmlIixO=qkE8zN6h3oHL_rpRyBcwa)B zN!%IM@xh8ztx0ZB`7gOUq;;4W|%8i_O9OFm*N$Gv(Cr%@m z3}HCkqSE1~XH%J(NM81x^7)h(5Zfs&I(Ys|WztqpAzf{^ zN=}~os`i|L4-3)hxEjKpTp!iDK(9+4B#VzI$DuWF!h_>Z@GB^EM|@il=XIe^JqWXo z76wuhoPvXe^rPTnHyX2gSpaE3(2%f|BclJBG3-wjGYXF&wOgHJhw)0f+UWDkkA`T5 zJA6!ft7Bix^Twu+JYIjmcIe(X=9ZBqB|JZT4s^h5>PT2HhvvrPpPk@JIPC}1ztI8D zQu`m(mvI{%(J`L@_a=K*MKZM~7FroM_^3ZFiJ7Mbsef%R$1R`9L9Q-cV_iKaS#k|? zvpo=~)Srf4&N?jYln`YB7=^D<`R6W10 zzM0VRX4lw+-m;~Z_fg~xKEoaa=n1Z zu@pz#ycRFR#aWgAiAi|#X+vwD2O%*|D(oW>ZRojT8|SrUBE|Cxt8>OoZstmm1omig zc10lP017ctOPNYeF~Rd{1{*c-MD9acZD1$dt37Ck9zoAoxs;43?d!dh&bJs9y=^Be z71E5}LHmY2T8j%WQEMxmiG9#grLH!57^&v#`dJ2C*eDWONwT%V6u5n9#9Oe zgTLs$*pP;sLApC+S=a$KGKk%QE!A-I))EobYYqn{qxy@4dyo0!BhPrS1Hr7 z!D;hB|CrA)u}-w(4DpjoeX%6M2|{ck*<`G$!M2&kD&hLrgl| z^kbLMs|ZYt+bUc105iLR5>bt;%vN?Q_;t6t%Zj~E#samf%`XF5!RP_4)3M0A*{|@Z z`fl(WeBUx^?YIh`nzPQ(+M~AbHm{tkNS}Yo^I*-koW;C89v{Ep)zXw@k1&%61-ozt z?R*+YMC)`_hVv7#PT6D4IFKBtE!Amu@Nh@I`o+<084I*p%%!F1cn*A62G{JL0htPy zCh9!F{A-TlfEGE+P%-7bsyvxUx=zlDwW7{5rS0>Fd$@wz`!sbuf0z2-sXhC4zwDRO z=T6+W3ex3#Oxfzmxmkg$MzQN@U4yVd187%kq{<D&U+5k_-7p%l@D9QbfI{&Es=fR9`LI;N&SofQ_aN&;cYelzke;SCd`Skwdrbgnlq#A6!frC zl=Z|r6mvGDnXs44Z>+~@l=Bw13GSsYlW>W(ZewFZj*}3Kk6U7#UX6^JoPS8VpW>)9 z>-Dx$MBW?CS_g44LGDR#YRT$}{8s_Rr5wjPj>b3A_x#u-ed`sxbx3$I>mVkN8eH1^ zWO*ntR@YDZY_(1Y_&jlt1!hv|sX5jBGSk)w=guWnUNhCI#cq ze(E&Kfc_-r?GJ@mmHIsnG+wN8YV*T&CqJ8tmN{0xmFb~FUcDrnz{_k+`U?MX9ymx{ z{@cE-rCP&yg?cD9AIus?2SBQ*_yOMELA2-$wAcsDMCY8)!9nQ#@9EfI*`g`#yI(tu z-**-{bcH6pZsJz58yiUeEggg5JoR@oe7*m~)LY=EZPB{?KWRPN;Yx&HpVyk{?Cm;B zYdbB@d}OCQDC{8Zkb^cAM(=I5z}deU0ZGiHRQU*(7pes$DjJnr87;fve>kWDBFb%s zf;;-_AH@ZE9`xN*M-~!OygcwKR_&@LI=f*c2wCN-z4D32w1%PyZl{fW;1XL12=9Qw zst3RRWsp08xfp6?!>|TQO6`vE@mz96GdDH`?W<|G@7>Opp)$J4osas7AKAR9@S=)e4bN=xI-5efiKy*3X%sl@ceps3C5@9~sotFejR76o@p zoEdjn{l@eAY*`WvrcweUx;QdwOrE2*i3l`PT>}|=GI8%9?y0RLJnIWVLp>{-3$d_u z$$OnQAHxrARH_ox{y%P40uZ-kn~ytHGLTpJR!xsQ#p23JJMN5q?w-7Rk6<(`;*qL0 z>}06LDW}YX!yo7R$8zJ@mQy70HC7=asar!-_7|Oo*9S*5W#LC3#FnW=mw(hwjFf}o zKg8T31H=&}ccs3n9$5U+?oYAFm;9_KqZRp7K|!@g>T5+XQ41k*epC5>9^?sH-&3En z)cWV6|6bvWJMy<~-rPL()+Ht3V}%qbE3)?!r?}c|#CUa&^oV;{H-?&1Pb$U~%l|wO z6K^4B+0j*pV5?bFqTH8j?uErnjXWC9Y$9>fq%bAK_u6FE# zE;t6A8Hsk2aq5cYXK3SK}~Wb7c*S z4*j1G;$K9>&%1Q*O6~~AxFqYpIvG2?sUOl~XZ4F70!0}sJ6t45$?Fd=iIxnz#ggT*&8@jt|J76^xUqCZS>a(feNkvR#bOh-DI|R%#4rLwcjk2rsD53 z8XD3kr!D?(#}537{HQg6a6~OAf=XGC^j~12`;GBvgRGB0YPKs!23KqXQHSAtnD9c1 zkk@P;N267a$-IShhyv|*riH2sJY}>W@>0fIkHe0$SFh&a;WqO&8 zZ)!kjXymw&?j-5tz)38W>!}?}FImoIlK9GGD z$?mwP`qALkJ6fK^hQLyijno{Qk$J9_*?g5IbCrcyJYA1hVfRsIDJ^L^=D>vf;) zmZNwE)dxqQ;V5+e^P3El+EH~GpHry;Srj=at7$cBx-t_RS^S4~^nH|yHr%J-meS)) zAs@Flg(G^6{xZHOb@_P8zEGvdJhCjBo(NGca8#{r1igAn|BsG)Lj~4P(lR7|kKp<| z#b8s$BbBi!cos>mK4kXOOVVex}sAW82f#gxhbhIRZ4iBc8P*d zA`b4kE^h$_`kgGiw`mG;f0*jPMT#p34DUyaCPA>kx1y6TSD`xJA^1VFld=Dujr1Mh znDyo*Kd;mn6&Zvx^IDsQO2@slm^c#mYutavA)fiC0+d2G{O8eonxGbL;o`5+Eh<9q zS67AaQuxG2X!IR*A1^hyuC999q)o6)>kl}p2*63N<9HdcHT(G9wgNJc907}5jy}1Q z?oMGeP2v}{_d|N*v~2yyas3{dnGS>{uKpB42|aCg^d%{@ieCvfwzOkHKAr~>aK|b~ zi>yX!36&XyZ3}#oq(LVF61$BVUoOS8YUfy&IG7Y2mnh*}6&v2&G5z-kgA5|`Tc(7}?F!zNt{LteaSq{D#v)x6WmxHh1%hnCV2SOo2gw-Rz8RKQ6`V}usHV=or^iH~ zP5|8Hj!OmA*E13f`;gu=`geQ`s{&=x^ zuf6x$YjyYTe)?IVax$W@P?%6aKtQnKVnPZ)Kp>nzK;QZxz5^s6cA)lvA4ppkc5*OlE za?Lo;bkkBgc>UAOn3neK@&twkG(d6}v7j{}pG3_ZLur%h&$UitwmYSwmPCEI*>|&| z%?6r%1?LASGvl8S`er|U3)P?q^m<_q2N@^`8IPWZVCY~N>Hd66+`Kws^chcOoVv4~ z^4L6Z%g&D>78k((0Ral^%Ln+u#28J_1p4RiKavvoenZj!9%hpGztO_ZIM>40i=u@J z?42A+W`{&8OZX)f-K(3+w}U6#R!f1iFjgmxa3VjYQ79SdGf!?=))&IV9mL+ZP~@>d zAk<%&UmbYZRy=nvA6!99)A`3!S9`24%n$Uiq@2RXqGHtK*;9XX)>yR3DGReg%1Yk< zekn}fk(^#Az;&&Z*NyHJuC`7pnAV}m$DG3A!4nY*yKMNCKU+p%eoZK$X=0W|&gP`< z+`q!Ix9)>kt##NkJCRNyh7PY$z}H;{xY116$jjPm)kynv!@4u^NLxPmeM~;+?{v0& zm8})cYqh`*x(4FltX*={IeGqArd78K8GeH{NA6X!nngbuYq?9Y{Ke zZ;9ZW;AF;{K4zg`v-x?ZaC=G`sZ1dHdZ7?Oqlbay36k1*BDA8sQIz`Zl+71l`9e)- zFhyZ(-4>#|FAk%?FqZA@d!PX+-kyL!!#d^}F1GdfJzDD3@2)UeON8lHo5FI(Q;XZR zc>%r~Ub@pmMIGV=MlBbHxPNk9(MH4?+gJ9Y9fUUgr~vC0n}vyE*VcFpdaQ{Z zA!K;`OeWK|@gq_sPpFE=;f7TX=f~e4@VeZ1(7xFnTGUwH&8kg6c1(X1XuWZ^IEk~yPlijmn;dlS{GPnLCtZ}!| zBSS+niYP=EDzy9unQ#GL4nu13HvPNo@EMXy=HiWPcKXnMwdxGj;qJ5@2Ys>Xgh!5o zEqN%o+fV3lF(t72-4IlNVgi&bVvce6<%uvW(Fv;(bnQ{&_V(a|_ROmv_00{N9gym7 z5Sg_h_a(pDWMA=eh@2H<(@KuwZCNJGNjlT)%NuU3J6E;a=1Pp8Gn%E%l&45@bNXex zP}B-216}Y=e#IFW1a{|rxFaFfHg|MI6o=fZ=F4#j3rW4esSmK|LE|xD!aJrv#cKU3 zu>4hl8DU&AS{ElqduBp4wxHo+_Mv1ci*jn*Uin$JJ1Mi^q^_~U5vLNA;!G7ZMf%gs z1Erl%!t8RN?q3_rV_k<+{*#QC=kKxRp*T}g=JNB;H~_m`P+Ak=@P2f zO~1YKjSN4De7zc{Ql*8W3UAfmieFPR*cRX59tr-@3MMh;!wzJ;Ln7a3WK^HcK_?1t zrMrS>Pk%$P@PzjY9}q})$=n(BxE_rv0?9DA3#%g?to}BhHL#+@ zl@sZbPTWMoMcVPi;ta*IBrn2Q4b-|URpMr`Q%W@5v+rqR<@W5lNpXFmYh>Ls3a+HM%iJ7;w)OhcNh4Cx3vs{r90?g83lU+LgxBLo$1ClR`&B>!QlI_Ie3SEv2 z3`z=#NoFV9DkqeQCc{xl0+jEUL}pC5s4vZ#yvn8x3EHK-<|&_;dNH?qM~O$}0_^9> zy+^_lH)bz!#25v=`zUcm3SOne($5H`(}dEAXY-;^;a`30G8Lz{(aTUq+E%T~W$Cl` z$w>o^qwat)HAp_5S|mI6pL#2+btKqS7GH-TSIH|+rW*$)XqmcG6xo>-J}kD~j7tYi4wC zn{VkjZ+w|`Oeh+YYp#`x92jW9Ey@GdDDUIXb#2nugJpqyJiNrP!2( zkz}M4&m;8L+ed<7d`MHd_)s}hIARzcXjE{O350T`+SK;C`jtG~7%Hi0F)GBgWSz*P zO;Fw;D(F$f_AIw7d3LWP3O5@eX*vScc5vDu+MKf)?2XHqX*468E&xZc6I(A!R8agT z|Gb3VUo+7_p4c@$#ogHf6Bd0t@}5d1*^zy%EeT<3^;0*=am=+q8Ob3_W5z)NnInk7y98@g z!3E9Xjm}UMsSJ2yN_`(w(q&c2^l%`LSq!~l484EBegzEt<=3l*V;TxE8s?~TRLCo> z$Hhg!0`$PXu~CkoG;i}G%34@>kh-KG#?AropkvbnJShV2;ed%j3=DFSFjA3kKMJQ< zSxua-d$b!k6g97jb`PT?5p8`8i!^J0>`h zNHDhQnNd4D)&<+^JVv$u6hO6OXn0Sy{hGl`xIC9YZ>SxgE16brCWZEx9i$a7sPC@p zSJBq_qh_9M)U7Mpt|mC))o8AvljHG(ppkg7%2e#|3ufbpdJjeV?Q~3{nuJ=}q|tze z;KBz5kMzuY)P1OCyPBcLLgKn&tzO}6^ixV>_;XgL^F z(cga*04p#KS8Yq!ZgAzy$Fh0gPeOq~nb`ca;?P@~kX$JP*|;I1dL<5w^X-ktf>22X z|4C9vgMSF#bwJ={00(Ika68P9@^r#AIKuv1OR!bM@|(nSfdXHx#5!jgN33t?KU;Ac!WrXY2j?3`QqW ziqPj^sx=ELK*3W%iLi)6jPiS7h$J#P(TwD#rbaFtiSW^{WpcZ{olj5vfl>2Jl_225 z4+}}@dnMPnv(Sk~(Z8Cz$|x^JPkKwi_kKnWRmYW=qEUSRn|ax3 zwNe+nayE~LlX@vPlVBl+Y)tlO6L$N2M+Zedk=@ET6g0o{*yw?GRwg^9KIu$nDDc2F zyU>8AbeQx~>#Tb-nd%Y{VdEiW!$xr=QYS8EAYN*Lk%ctFyU2|kEh$#rMPq69aP1{g zVwLI7sA9)9gOcihd6H(PTWM#2<&WcqyDxsbHJzFUOP?_DSU=fZDP8Sef+dmRsjkyq z9lQOF%a+?Oz7Z(%3ljo))h*&g7J+e!YbG>We*|Lbd&KfDC*$J#h;W*q2M@-xo1St3 zB(86f*3@&nY-Cq21yCl=#04K?kT>$Vpb>3shrG8x>btrjDuZi(9Tf+Z0@=uNsA>>& zC7Oj-cV|ax1LxrTzQmg p9M`3IF(Yuv++KDIn4=C8fmY=*1{PTC*~a$hyH&pEk0VJ+)Q1xhZqi8#Mkftf;Ec*kh#pZgp#&m(NSo zakeA{g&kQvC8bY6JvxtTM9TVFs<4dRnlU_~@jeJYc(=#^`8UX3FB*Piqc=V`dZ|-0 zUChkgV{%2sHPDS~x{a)*_k2;rm5ZQx;f!-!M#pC=j!!40P&%--G{UPtQwNiPhxTA3 zKa4n`>v*JUO)+Xd6+YInYK;Im7`vd9HOz5=iK(@GX0mI9Rs#!HRaxtYF{H1r~xlI9xga*Rw9NJIMaBB zcgaIDiiXbAHw44oveblvD6zFi21z73h3Zei=&Zewy|ZoLe?liWHhldpH?MIxh|rz3 zYW41VZV`|7MR-x<4*e9Ae}rKcY>jqS%@)swH6WsGi9#xzgm@WXluLlvqC1GWny`=M zjUzm0lubO;Cc=iY9|FPZBDKEYm%Lv;S!wPmR7gD>sK|VC3nck9AKO7&h?1CSHKD5zI3QF-7ToYpHI{oBBps zJ|d+4p}e5W{yW~ugG?m3C2^t_7RNzKT++lOEyW4)%(nTZ^@f4 zk=bIrd${}8Et~sz{9#=VnljZ+%Y6^;@X&dXWuI`vD$4?%>KRYnJogG!u6X3@kG~7d zglXfB5Sw2N7phsfxtQow}@W_4WB)J4&>lLksA z2WAr^qXHo(hbxqK>a0Y6EY#Ymd7#KF8#cvj!l@=Wx_S#mlZanH&I#0&u zn}49Jj7v4ztMd!v?uym&J9bSCXD~4GGUU5Lu56vDq6)uN8MK_-X3^j8zJEs(z%Quv zT0ys?QOuy_K<-E#yP7hClY#@{aG7kXmzR6Z5yxK>f(EYwYWKxdH4j-(#oxx)>-=H$ z3UQYxnDo+@8x3KqSQIMn-F;z4(jn$jytb8lD%fu68ND=AyIRj{uBn3_Fp{Af22Bo! zh;1MklW|J?RDYzm#7*NCnm8uKp||&Hfh&(Gwnc4!8ApjcT|)8HJ?NmL!9pW;6L7UO zt1oipAssE=YGX=hF)=RJ5~3%P?*MMVSgXeqM>G5U!jK6CG)6WoomcRa!>P zT8K7PrK6biUHO`#E7UW!Og2nORab%w?+yHpNm;Dau)7ly?klLjk^erXXF~FXJ>|xm z!m{0|QS@$z& z=gD0?wajm+#-PWQV@W^(@D8=?gJY38_pM8-<0!@)qLAeDqqvYcG56{&tSU40J(`v; zx?_HHo-DIa9JP+nL{$H5{}~b8>rcJv4*T{mO@_06w3NgzsaaEQW6)`mu&9lrt`SJk ztgLC2)c2As%*1SUOuDj9xbPb;6#NG<;3o-4uiHlbqp#e|bgGENs>sAUf&W@IP*!dw z)Vje!wt>#!O=d(JqD*Ew%RY_F;%R6zpGS)N7mCQy`4O$wL(NaZDl~4bcSgG6njM^j zEN|TmO?{o#QkDme@^_*F9u&RKSOqfv0vDh@ddP9a;;ftqf76eD;~A{_C#wJX|KtA@ zc#+0oA1{zwa^?6R%mgsrKDOKMIJNae|GqB(MNBfsp|X!2vCR1q$@!MLRE) z!|^{*rExWFo@s2O_x`ko4Uk^<44_`egwSkx0eqN$G}&5gn*uRoxH#Vz2*HRVAo|Pj zg1P(7b=ZW-w5_-Q2GQTqx;@XGQ$5wfy!ph9xMxthQ;8spy#%cZd+J(+fZhX! zj8K>k3$@4wfl82Tx?#DXT53Uj^M=mUq2av%sx zoZsiuh9|v8h16>Va`wtd(2~J4CQd7jzh|qJR<=;T?H80)kw7Npdn%Gc*lKeLmjdD7 zHb$&~c;QyWv7!ot7JVYR_JJ-=kpgZ6GV!>mb`Q;IUY`o?euK@KJBRQ+6Ks@J|mGh%S7jLRT5>YTW)=cpg zNnS;#2Ozahc06lq&?Ajf{| z3T9XBH~Nl{6b)XYislSS8?i){m8ZboaX-w3HJ|rwVc&>}29Ba`z05qaxiV?>qctM5 ztL$%zr7g+MRQFot=IkOjy3}brs>&h^>yFA!)qTQJ*gu^-X_RJgBLUfY(pi<2X65IL zk@uymNQ^?ds6e1&83qsOprr-eBT3`-qk};_U@fnRc($^%;CsVcQ#w+mhc?`-A7oG~ zxA^$ZkXgLEL&EE%w(Wo>&XkSq+_s$HhaB$-uTl^mX9Q7CJCTrKx zvxaA+{ z_rT9+!!z~d5+^ zhWz4Otz3Uiwf05?Bu>wu^#X9)jBHdR$Z3=TeDLdZfzGGJ|DyGErS6A?c z#iwAB;L<@1ZFMA;Q?MGl6=FRSb#QPI$JeYAn1(+fFF+d3?255EX+$@~aw4wuOs%bV zS^Lz^9&c0MAzsv~3xv{iBm2op3DUbeLfZ&$hVzXgIP)77%JQ&(#-mkvmS)bQ<|x4M zQhCmZFnIfsnuoFqWtUKy7k|y6lHpryks7*A985$zGx)S|ntg2wFE(l{H%%M?ER;Hv zvww-wr)cl~tM2&k;7gHCC|U2uTJ_z|S5hXMFy@voaKv+o^`@)-I6W~LtIZc)u&5xR ztflUtML$)IiOo7SWVh9?UBNaL9>sQDz`i>_8K~xd8;O}HuG-pWHQ+p9E)6QXm9vd` z8uAJ~D_%h_@Ra$UY2Yq>pt#S+5qYf0qnE_3Sshe%*801n-i6Na(By#SW*6W5J|Vv0 z{q`lep#3xc1@B^a;<|g!{$22Hc|hzYmCYGPj^4R*WD{4_dmsxl(xU7%{h;=UVoVGb zppsd4V(P5nCul`6RxvR!c=WbUV^lIFI|7a<7c(if!C*Vm>h=tHBY<=-2N`&4Q?)PD z!D*^m-%%Wo!RmZmgU1D6qgBT1$(NpGol#2Yl5&>{@s;e;$@58TmURxk@mQ!olCLE2 zs+%70yD=_;#*JnwNaa~o{qk@&F0Vw>b?08{b6EV@HOb62iBgt~xrewb(**9K934C3 z=T1yo3FE&biG)p^6FnB6wKT>l)BO_4&g3s^Ce6$|Er--5G+T2{i^Pj4MwD|V!e>bB z%;i2Uok5MSC(1bScvqu)LQt|NCui@QId*U~_d=6MU@L8(QFaOKpk$DCE*Q&rd*HhC zx*SmdMz%UrC@UKE6(^io)bbL%LjUG)U-e;E-=SlhRH4g#GSkjDVHy^{1mfy6ykox^ ziAh11^JT`3Fw^SjS92JjvqNXc;!}5p*e`Q?q8{UmIThdV#e<3qPk?srv&NY7Bkj` zV@6AY{E6MSMEc5Tsf3qd{<_NM(e&#bX=7%LtD~TTOe%KOMDSz;s-;V# z6A0CWmhF{hQfdo|Y}AEf#lJSV#=j>I(t4nzJ|&#o5;K?dXl2ebL#sNS`dRHcF2qZl z_AN|>`*@|;-|ak)l=S6?H14suCRk2OdKLjCB<3u}(8R<{SL@@WmJ!B?{*>~3Jx#iS zoe4Vo>o={$-?NGQ`B!>(n|t%7FTK_tRJ-e;#QLI9hqbsg2W{|1d6hGllFC!nh>rAM zLfoWCSNPp&5RH8QK-^E=BM{1rw)Xke&GjRTWoMG7f2>$m%*2O=l7Aqw`AuG=G5_Wv zVy!wMKRFoKppiZm_D}E$iyx|<>COgs86kgm|332d23Bp7H7NO*$58ot`cLBgz)~QE zP8;)Z#~$YMl7hDIP>}D}CG}YK_5F&Z$5hLZDZFT-g|~*N)lHQSc(9kto_XWsP^-I0 z)%6kkwapTx>3VzTIxqrz8G5X>j$U>MFX@R~b8hes^N41_kx_@ge)8M6yA`3=Iwyy1 zXAv7kF&xX~dEeQpHkFSzg!aXzQpDw2^|F@}vMgMMnYYHw(}U}7GB{(6#hAp&VzFm$ z#RmM{reCev*D2lO?XM2L#i?#2&Qen8(|vnAQuw-+W{?M}gE%|Dj%lbg z&e1ykelrYiVrujCO14q!?}F!AKTPds!j}6-INFcU96D=2;j3xZNl;>39vQx0=s1rj zjd5?uY-y=_H1+32?AITKxs_CLpL$OcHZN|rCtcKnS{Z8uW~Y~JVAyl`Gagx-d0T$G zE9|bju&h2GaPeMeX^d8c$h)K*Zv+PLoCqG^u1Dc4`mI^l%{3XEVOAi|!;*iofp@=V zdgouVR;mn#efyBLaI<&>?#k!YF(<{ia{{~Yy(oBc!_;L(TPaA&C*`C@0szKloGP!0 zA#mxbbu_JTM~D@4Iy8HIBB%A^ZmW{U`KHmv zv&3}pnCXtX;ztGU@b+EdpggLfu1%sU5&nCQh27xWG|s&Pjdg<_P44bVW$f9k z(pR9c+ydo<6BLM>;HrP;&-a)qgVS~$a7?1r5|Y9Rp^8FBIc+5$NOpQ(F=yJ_`tTFR zyD;oOTww%z?0$o+SYoscA0Ke zbHo6)*o2?VovfIfmF}E(HEi8~@fnK^fG^(EJ6|Q)yh3|dmHaawk9Rg;&q#i+>Ycq5 z_K)-l{+vn%_!LF6yhj5J?}*Ed!Bcj)C$D;hA1aSHgYO`dv& z8lwwXdqNfPltG!Sg*vfHuMy~2W2w-0M@D!xxvP^;t!qx>mdDBJhEG8 zSxl{aAlu^E{P5G8=YETY(IyugcNdQn_AB+UnlWoxl#N4+&r*@Uq~9JKt@Cn50&Gk< z|6m2R zMD#Guy-1FSWP)>!@mjYC&VBK&g*|!u+#bzkxHuQa$RaVZT@g2#@z2R*kS%3m`1dBe zLP~!Tcz!gmgssybbd?ctbLYCv{{1T;b}D2oeJ(7;>ascR?i+-4%*3!pTZ6naIDtG* ztutEAGZ^n_TUjiX6YbD0Whd*D(GJOmXi{prCkO~yEqqVEz70+$? zA1{rZrI1J`f^B^-@aa|l7V zkFHVe8||vkl|tzw1j?EkTgt)C_)mA`hya{~$uG985BuYS;$a~q) zwtcR%UJGG))Xe?r1Jr#TpLXjUPx~56beCgiV?zBWY*9?!l@*s%E~wU*f5n~*%h%2($>viH=OKk6}rHVC1+8pLw&HgwT~FM@lreHRW?E~qb^qGA{^w6uJYYBZNLICM|JJD z=1w2Nz8Xp;lEEaOd_($((R1C@j;9||ron!N$I6@BW-);Bzce$b-J4CD{Ai1J+a`^N zJ0UcQHc6ShW24&g?P{%h)C!~?HkeXw9D*huzY*pp55gwO`AYm~*JQj~d9!F3Ht*(s z{L}aZ^uFs{f273!;+B=>UNQf47p`xwUzCsA6^HC#`jpWJ*>9Hh%k>HCVKI65&alBy z5&u*=32omCVu{w>9?ol^_MNfDj$?==Ne6G>`MUJpk|bEyK{4Yk^2i2__4*}(lpHhz z{3Em2Pb7^nW*v^Ko!)wcVshLo=x4kPP$#5LZIsKPQ~V9V63miab$$7@R}qtZjOk*n zUf%o6vQ#-YbMSQLYp#JxeTPV@-&y zmb@UZXOcLcSb|LF(xR*hgD6-<9=d4uqTA-*;8OCR*asTlc`rip>F}IsA`DDU9{BH4 zA9nHoPJU}%=6M=J5>?yG(~21vbIZ?}<+7{vGvld+6+i4pEhp}14ncs>VC z4V}GOKJ_ijd~S-!&+*ijL{ax9hDJSQvRKG2<~z00r=#T3t1UZY8iUOAU!%QHELGV7 z(e$b85A(@n#NayL%H_yTKcs7SEB`cq|N8~^{|W0IzwbM%N1^-|TlB*u_{sTSNHa&C z@PE6tYsxB#~f~3>gX;in;HoKcU>;&rY#Zo7XA0Q&Pr&gV=&kJ=?-$m0`W1wEKL9(Zf-plpgNo_bw6&q! zYY5=Rz$cQJgAj^%v0)(dr9>)r@VVy}2X$^6rzzN6da}P0Cmuy9q z&`+=jU72Pd3`p$U%`Z)%1;E-T*Aq-uP&3CH^h9=W?W3wg34Q7}bE! zn-Awn4#eNYg;ILq5{5mqC-siO31w9ZPFc>D^->T@oZCSi^#w5g$eajJIJvI}svi(i zAw079(2?6OTXG>IQ8`JDJ?)z5A~_&j9qlu@Iw-EQmHvJ5n-=^Z$#WOFBEX_0PwoJy z{ijeiX-uHV^}7uafZ8V~Imz;eLP_wL?{I@q6YA6hrQmbynaZmKVegM*MItgHUyym9|Mvxvn^n!hnjvtGxyLhGG9fc&vFK0XkUHB_@V|Ik z)>SytW^4cBi@%}&D{}kMqTZd!iUwpv z{0~fg|I4l7K-gS0GfQl6U}J*;nqNN5YHCpEhM5Q|_PYRT6F-xRX`O)sd(mJxY4_+Q z@q`bBLO5$YS+>hj8$hdwV=BBop#~Ezk_fCDvH9I*3TmW;W{r|w?t%l**2beG@_bFT z|C-Cp(S|3$l=f6&eE|A<7L?C{e3)J?lqnM7 z3N}Rdw$hB=QvtzF4`DgxJY3Lbq`XcJ5d+t3zwN_0^wSsT=DVGdY3fmVb|5FK~{HJ09n0|~{ zzk}H{dTuD6K;S?VP;zDs2gZ?xBok?I3DB&CQI4gbo33&GZp|if=n{$=3H39+&^j3+v3G#B(Qoe>kZ%(3 za)F!C%a?odjwrPet>rv`zptD3O)P8s=nTowc4(Eo7%3Upif?p9)}A+?FUb65Dih+wR@&=0A&~(p4_tPNm8TfV z05USN0p=V!+t-E1bH@kuk&Q+ejoou!>o~_|u-n=Z9hn7&@73j=k^tx)o_hqV?EP*f z9_qDgakp(DGnB+Lqceu=_Yc14KzichO#bqPya}m;wF8h5_cNRK58l#wFE^c$OqvT* z2O2;54Gp_s0pGmyx%g6DGoxWiBEFeeaMJF+COjECDw1qm;WI6~w5s z7z@V6sQAnzSFWdTC#!S)v>4)BByYou=F*X(<-+CMLo3y~26E{?ZwplZSzAq*#T@aE zAb*U*+%WoZe@)rEndgM9{J#YpPykt1U`JZ4UuX8=a3%H=ncm@D8i2z%tR%VjIBKH_ zhUl{)kh{-4#UT@NQFkTl&&Sr;!SzXkGoSuY`FTPn!>m0X@o2>R;1dpH5{R)rrVpE=>_ zQ7-hkIam;mjEtycPo=*6;>2K>3o%`dYjSDdJzNO~zr2DZZx4<7WYrV&bbbEf*+cW% za8WvAS)s??^ZzzgcOXl;%Fep8j1@h*Vs9e45zB(3vr~SjfA&vt^daO(5ftp8=HVBr z$e)xOZcW7xh_vY?PeEMrGh;y9{u^iY484KUc7r>T{48!JUUalgU1}=x&qyy8viCDk zs~xF%&bk=?uKD0(dvC<~nOKnJF6kkIL$67}qgUWnUNN67(`w|mlF?5^Wp}CL-Ouey zx8NA4Xu7-TM5^U@@elW=uSByb$uVOfvP{i6@-hGE>aVe|9N!X+5H*=dU_qWEnTDR` zZZQ zF9k#1<9;UK`KKHSBWFGXM)Lx@vkdI9DZ}t>8v*8hZmdn0oO(`c@yhPk^Fg+@HiGF* zJH+tn`g=do+8PmX0{=S0QzT~pkKmiZ+pCe3O0+yC!OK``fHNNjE0c9k7ydK%5b8*Hd zRto(zou3Y^&nPNKS>WmYV#p#ZEz$pw>g#CbovQ1MJ!E7|oK5YDtgJXwM`s*+ot@u+ z-WbzD0&?PF6CBoFETa>l@eCOaC@82aZ@eM|B5A*_o5(2Hc(%>6bN>@&&I6NFdg76g zIpKiMz4a|(`yJlrDrdRXIefyD7H8gAFZ6o)C~`R7_2-{|O*)djRf1J=ur0~?d^>@B zV~=(5?;yfsJlRmYhG_QjXgu*v!qJ$iTRdqUU~doG23J+r3elUl4zEsh?mbNxsPp*< zMb_vIl%lcE8s8%?FqI4zr*S+x6ZfDO>zt@9F|nXAw3kQ4K^z!jrFTp6Z7q&-t8Isd zB9{1+`gPN?@_y#4{q7M_o+8G2GB$5zK|b34=fHwQYjPpADj7Mib3X3v)p>BDxSOiX zPz^thY-DU#ZL~ULAvvYFkmZKI-#qW}bM#_g!E)rXRA z$u9Bt4YJ4)3}9Dx=DfR1K`2O=lYY@gO5(ly+b?%e`AwAeT|YHmM_x_C+C&RX9wp=Q z((Jsa!pJ0V{Cd#@K-Ue;RNATtK@f?b^f-`CjB zPx?RU-d#^KXQ6@bNB*f1kng{jv!8CSibd%^w|MOu7jNf6IFqz5^DW1Bw-^1LBpCuT z#3w59VJsq!Wvz@?m&w{hyeC(uH`zui`0;nGyA#2hP=L z@xnaCGgR2-+l>ZVMW1P9_Ltey&6jXt0|(o8qjAHl*X-jec6Dc+Ng)f*A{ye1#&M10 z2wWmSd<6Teo~tCpkvV?f{{`lF78RihnoNw) ze$q}v6z^aNerON5BXoWa{Q1{A1n`H)jE0D^lZDkR-nloYA0v_hTP1hj4%(gCv&8o) zug+xc>`P(-YmV0tTJcte^kGzr?-rK?PG?VsDV0Nx+xNIk{*tUs;WLGn#*?;n4E3zhkHVn+!nPe~y%OP@tJ>I30`NR#ljmomMpJG%cD)X(ZnAt1X;#zD1U(<$aZRKSrIP7-dGKz@I?#3$t zKM|h))62H>S`#ppA~i*G$uLT+#i8y$+4Gm`yvt~1jJmCIi|=sQy6=fHMIKqg9gk`U zs%M=B_%cug)gDb$MO1Dp?eo6w?ow0OGbg2ynNn-ur*i(%F4>aQ1%`aR1Bztw+EqbE zSh2-r4Mg*V(57bX{9o3Zr0&LsVYPUWdp@2b_P<#0M7MIT^ew{_-(-y9Y0|T0D!&9~ zma#E>)U`|q$Bv>aZFzxYx}+jgzSn;Zv<29xv06|E&>EISXY?&&{(26SEuP%_n0mB* zE=Ur{IFX}$sK_a_`EkYj#yG`|E493~BNRZpT}Z#@Ry{G+!P8c5s|V5&Ct6hn4-b1= zv<1@T$mJMyrX7sP@WR7Fv(;x~9~DXhUgNPAX-K{GqHF>KL2`Ya&{?*bD!$6FgQMqRh+XSeZX$m7Zc6+{kH>f|aoj6lbpA_>mDuVYIdt1poHDa|m#4Ju9EyWha%2Z- z^fd-+WG60Iv?al_Pr-Ym#HJnfV^9}l<@7}&tijw6Ui|Jhcy_aaYs9q6vLlI_M3gph zaO>^&{cIKQXw_Kg2N!xFRBB` zE}kAH?~%VV$)lk5?ndc*XotFtC%XW`GB%PziSucgij2yob^H64L#IXL)p3gdr2h)7 z&;m}SLGZzLFE8Qo0!?AR%$A(%UGQYiCQ4$}BI=-<{=RhKkpHW)A!p3gY+))e?k4(6 zVlT5uVrEsp^!R!$E*Bhv&1pOX11nkHvX-PC1KTuo8@G}Wu5LkdIG-qQpenxC$ z40JfuR04Umuim&=B>VXyZ5)3|=wo~@_V+G8n;byU)yXfFHQttiJI1HBQ<>-QZcjlWaAxg(SaM_3d$gDv?03+ee{RoI)? zF6Khd;8^3HF}wQ)rt`{7G}t%%<NIx`;^TpRl0L14vOlS7Non{u5maQ|lZBW9KqRV*)p6is!*vg0SA0N} z=_s8$`o=)0`mw5QPwpXEz?_ZZ3pL95?s975Hnu+gKqy14z!cV1SK(+haT|9?^s|^?}?Z0FI_FJ*v)b!(W_7!H*|1 zU>RxOE|#c#Ykxy1^8#NpY7;zV^1On8Zvh!Vu&#-KjHWuM|HI#*;Io1VVf`&aYotBk zQb%{5+KT;-N$_GNKB|~D_2(BXJxh{(sLzvh(}T8nZyo8e`HfEIA2flK8e@h&-DukX{}dD~kQ5T9e| z#9%x?`NSyL!6kK*EU^|m4+^o|nFasK5n!>RsBqk#Pe~v7c4?IJg#;RL(Ld67Hs)*^ zaU%a*PKw}E29&`uQ)s1lZ5m#WxXtmGilZUi*8`v2scAXYT#mFHtr?H%5nbYP8V zJwTGbqB`Pzf^M+d5HpAe$Lc#m+R$rpX9ob!DI|{lwv&=h>tnovLSymWUIcJM6^L!R z?GmpGzq#7^j)N@O;T;dP{1%nZeot6PukZsoI+R!2{o|#4^8QHatm_ryyJ1yfq%L{` zunG%grmH*9YB!&r-oWgb>vA}+P*8O8ws+1E`f{~r8PqS=6NGh4bEJb;6dGM?NedHB zgT$oD<7o!GkH+p40u|;@iLbbW^tbJ+wZ+}f9x094_`kdL(8EVoY9r8+Huzop!=Kq2 zi-!6GE8Nb3=Fq%_Cnv}x1ToV=I_)lB(d)lF!VW=H{i4HE-OMK+-f)}irdbc z0R>|NF1*6C;V4~!txY{k>DO31AF2=H8^QInh)d5ST@F6qon`QKn~ztp^60zyYBt*Z zNsg#mEJ8nVP0x=HxzcwEOqA({F9%Pi8&+UWR?!*agw8Bkgd%py^;*ko_p}8Ij=EM8 zO5`w=`}Or$=JM=8$(2}NSvVpm1=$WlnK_qJC>D28dYKJu;dpR0OIKg*YM9EG$JE(G zggZ1O88!pm&$#!`c(v|YJl<%y88#l^k8|3v{RkUX*a@HZnr$llP+ZPWNEf0nl88yoPKL@ z5AS2L8@3?5&X>{uq`#9`hqS=F=;g`&ybtM#j!&u0`E;Cp)Fwl68)f1|p> z;RNcQvl0*580|pk>E`{13vds@h1!{vS~#Pl}@#87Zj9zg>3ioWO;o( z*lYv8es$tk-UcF5*G0C-MB|L}j$HjRNbmgzgzK8`!~_T)&OMU4TRT>M>mqn|kDP^= zG+t|f)b7x~Ay&S)7keV-G#wcVyQR_^(hLZv85s<6{N#oKZE+p*v%K*A;FRB1lW4Wv z08r2fb$_Gph0iZ1+hQHKF9Wc z@8ddmM|WrPF|v;XjXslWP7Oe&amM_G#C3j-h|0vQ)xmprMi`=&x5zHc<_^G#j+K56 zEe9b=SYN%yVcdB*X>{@_OlywcoY{{_IsQ{JE3uLA{!GEh#uk;8ROrD4T zNYu7GKc_Svsv3Og2M48}6>mYl^jiP;w+Zn#8+5_;wpoLIPEXY%Q_DkqY>@AaCBdxl zT=QXqN5pM#m{a??Z)#nXdq2<3H^R`Tzv@DLU|b_ks=Egjzr=UWtFv#%1$|7UM@iI) z7Dt#SX?B~JZJvc~R`_6!ePp-$%xrFztFF7rME|wLpZYBseA|g}lMqln0+a-$1$Ndm zDw0XlesZA_VT%7hl)YtCT+h1g9g+|rxI?hu65O2xC%C&d?(UZ09^73Tch}(V?(Xi^ zz}qDMefGKM?01ZNztW7=wW_P1`aN^bTK$646z{)rTPL_AauYKhmir)BlQnziG4%w>_v#kw;0x*)XvzHp=k?kNsg@ z(t3X^h!&dzq`DN^)U?#upgm%()#wvP`&~-A5$tKc=`IkI)RGKwY9%v#&h|!$4=}8< zYyHW#8nRg&xS}!csZx!}#luenOROP9rxJ zd1Ev{#{JBup8Rf+*C`Gclydg_gc$^bO-i%iw!x&w3;_Yb%`t@6Y1QQNk~@BN zSefu{_we}{y+Y(dks6F;Qhbm^OW!>)taH7jCRltt zaa~hgxmgfh3t>P*yxI+FF>^NS*HbcAVARb>hUS8|W{8eC^}y!HXL5?sG!JrHeXf?| z3`yA`o74wFYPFwM<{iE`KjhNygc5XLE~X})FUPxsMs@Q|?e4_EXCiXKa&RCnM1!2; zekD|SBYO-$Nd$8$b`P;f!~}8(rgBPx_o_)k9S7(y(Y6%%H*J6C;2>frA3t%}Xa{Cg z+)jJbrOo8XPP?x?q3&LN)sfAH-r1*lsI#j$t$%Js>&nBHRP6Yj%S(XE-85-s@!Afc zZ*9Ict$FY3Q&?aW`CQgFr~Ic~+a;ALc@BtaYfp^H16 zBLX2W0f;)G(5?_hl5lE?cl_$Yx^XTQaObWn`Mt*nr8C;$M1t#Be{Ax=p z%ML-@y|;nAyWcMXfzFxiV_6uL42}pi_y#N9JhS2@d`^_JlRMLTp5Fve%hkA#iT$5g>`p5^p65^8kxU(X8vDje24}nKm=$7A0bocFIks$2`P)2+-FE_{ZBN6q+c9g2A3L>m$2 zA%cnjG>d-)j5`x;%F8nwdD$vTIuXLIV#l&`QqAuqyM2k4?sQYhSqRI70IIg~EcYNt zB4a~E*N?XGX$n)55;MM0&W(y2DKS<$_JRcayi1B61gwRn*%&2^2ub zm?CZ&EHN1as(ejqFvG!S5X@yEO3#O@o(o8!uybEU*v?R~HaNamOx+3*(-d*aZY)+h zBI6@ia|w>G9l_Yn((1#R{9l-~R(zvjSHe zfAxDo6Fx+)Zt{YMctc&LEC3|@bSt5B+~Z>wjpa}ST8$(67{WQ$5DgzU2<)Ri3J*{k zJYN1Zm&fT8%A;&$R4oi|iU@j=+(T4YZbz8SZ0kKsgg{MWnd$1^?n_(6qF1xCh`xst zGm}3HR|{=gK)95QK<5v{fez~|x1>^gGn6pFc2@nO5r_Dc#0GMkvekj$FqvOlU>--y zVxbtG>r+U-pVDx2I+p)dTyiH;!);{YXy25LnCF{~JA&1d`fk}~-$gyzcgehPMO*$O zLo_~M#K@`ABhKi!H}3FVEO@RJ+YOVWwI zAw!uV=b78->gKnPkrAyUam`ZftY;PW zL4?U$E8%mq$W5ywJ2uM`5~RERQYQ)qq+9M2v%;4Zk4)58PNmIjIQU9ul!M5{R&7j&3h3R?AT%`w0_aL$qw z+%aMpI<5b8s}0+(zKFaRIK$;TyP_@Hd(Yq=r}}*shINVI>Y(ZhP(qH_(MN0wKu=@z8g)3ATrgf6MR_O_K6s!|FFE?u_gw4ui_O9C=AZN6X1uGC1ohF-!zx9CwfMYX?}TI;Xd(VqdVgHokp4d$UQLn665^* z+gZ4Vv_?K#rcIM7+cf^ufy;YKyKUl5^zZOi>!58743@#~8~n_~>hL_Si+0yrHd1ID z8Plfw7TTf@Z0VQhUML*y1;jkK$7pyxa^#9e)dC<}%#=8;a9-Yg1PdcK0=tWzfQC%!4=B&PA-}91 zFK?~n`q@o>>#$4SM3y;kuHb52qz*!f#Nzek%K&y!$ghkNnJrM9xMKMp6diP#krJf7<&D?vvpv8f^Kybam=jmm4(&zcnwba=JNLll;$01S?Fgjde%rVfI!VA7kM!mE_@MPQIj`G| zE=W6g_tCe`#aNJiP(D^uq5N54&h%lOXI(7Ld};875#_G!v#1Kz;BzhWwf!{Xu;=?r z)Mt^n%nW=yy1Mbjioxqx5eH0MH)Xts*_Hw5Ymioz7t*T5D`_L>kev#~_(E>>_y{>U`nKoot@g?g zD)mVofgYHeE>i^nP4avx53X!rni2Tq4(Q44&8KGKy2{cGx69F^5GUe;=x^+vD*-Fv zsfD=a0grp@xSE%!Evt8MgT-Gnlb!kLGjkY zVtK#^M)Q*Lix1=d;PR!)R#mK*q(g=6vczccSVeJuqsij?TE%AotBt=?!b0C$)#IDb zX7VC7*Ns-@P6VGd$yvmm znh3$=GX`1$d&M!2C2nNL3b z7F&!@1VrHHr+sFPlSbUp1W{FCDo7Ap^u%C~{+ut9!^P`oM&y#YB|Uo?&R}<^ zh25AOB;%paMQzieUGJ8@Jg810HsjpjHh>_YsUHCKA&#$Jq5Jn#3QcA^g~7Ztb$8`r z)nhH!=D50f2j}*Pq>RuqTz(iw{Y%$8HdxxO*mh6ndUX9rquWQmd{oe{qzA@Glfbhb zx$!DXTH39+nKuE6pP7N>(`jOt;At26g#d_EdN*Af6!iG8^x^#lC<)4Ch0VW90GPOY zJP_Ew=}hMQ86Q(#EW$a&p-5Xd_yjxD_}t?ezLuL!E$=txaUeX8f2iKXii10r7uTkE zZ3U+;QbgNA`XWWUy)D6u#yLlw^mD=@y2dxnsd8Q{%~&mLi#;xLR}Z2Q(*dIn*L0ob zM@0ndFX_ex?2+oNdV2@T2|2LcDvtEyhpl?z-Xix+W2Ve2(wAbUh;bqh00ML0iwoN8 z=zV9iDH$1J-tDRyA?c)!oCaFZt+u?4r9;bvV?7Vnu$so+TuBogplG-N-FKyGV`nvB zM249?HWyz!V#df%E@YpcV8rF;nN`!pS-$7e&7dsn@qT}^G|6I)ViM|qsayN_>%;=M z9I};p4E2joJ>>E$02^bA5o^Hoo@YfStc(hXQftrI7l!RjZ58nIy}HtB*qj#lJ8B`L z5VBYzSIwT7UkE(MF({HpFuqG*HpoomHp>Ar_q9K)G|JmG zhxsfykcn5E;LbO>!Xv6{*DDS!l)s7LX0{yzm6kN1zkMm_A=ncVkbc;XxgY5~ z%kW$r6i}g=?E3Jm`N*E&5vi9-CyS%4zeK+)EU`)Mi^LyT+ofS0iMqUOGaE~TxW2|4 zs0&2t8>aK4rP0^LBeYEP>*&OBc}j2FcmP^jIC`NQGJo|8o7aosc zwkh+rE4JT@#iY6}jQcRi^I*wW^xFr9SsnM<-6;6aa5^=CKQ}^Oq!LZacxhZxhO@F1 zcL1kHZf9E~!jsEY`eOs%gNPn^GlW%%;mmKT*;ZwTEcLRUVkdi^L&r?Cl(nKhtG%;1 zG?Sy(t7J*sXZ@Uei&=T^r%{P`IF2(=M0!IDcfF^({XH0IMo0W~T>fsbQm~b4r+16X zZ2%f*3Z^2@03|yDI*_w=v@Zn>68JLw%q8+)pj&#O2nYz=pXt*rx|m)NZ)2Vod!f>m zZ?Zs~2mH+NRSeNN9#-dlYg+blMKT3cyzheMOpQEHHMdNeH_N9VW|57~r?du#0ChHYt1}M#} zpjs$W#>>rI-WAavtvtaAa1CJ97AhpQ!ePtZyd)8JjwR7Xsmo}1q)UB5OG(d&3`?DW zW0ktreGXc1Od2j0hI}0)_ZJnFwQJP{Z}5Bw$cpWTonUR)qwSf=l& zm=QV~3yje}7TDabI#M97;w0MC#Br1=rtZy%N2$JkApF%1rkot0aLe825dw{8*-b8K zL#z4zgP_KpK$XF$^o}GK%B9ElZyP-~g)^UJU9rrF)d_2jU9a*g5VIAj6l-3Bccw8g zs!U-?_@*L2T7F2^;|dO8GoGGikGp&?^JE?QVQRa*Avn=0&dY2UBT~6v{4{8>_}Avz zucp;*GXn?YBGmZh707Zrhy)#?$bIFKJXmbT$wWD4B`?$l#~3Hpsa)ov?$*y-I1%wW zQ%QFzP8JDDG?!5c>-_9XFF#R#a0IcWNPnQ)9`5y&j&NOy{}3Q6m6wL`x@u*fwZXT;@j zwv9XY6M`vD=p4pG!wET8&Cs64sF2@we>hTBP%07c5ZIpSu-By)XV5FPAc!Skc&OZ0 z8A_~pzmHM*r41S|K-FPy@VM8Z6sbpDO7oV@fR(I@dZ>t-8qZVqTt8_jSd+t$m~s%T zzi33P@^3I*#&YpVTEp{GWYw#+Di-_<43-A&=!=JCYG~z)BpQU0AAJbHFI)nQ#lJy| z#O8w6R3I{9bV8EHrlaf7a}>q5i2r`S-6h)!duEVRwOlid_rPFpuPi5}nZv`kSfRn* zrF?$gozv0>LKm&sGqd#RB9-;3~T$nJfpl&_N7mb}eIrS`HF$v|%0)a=} zorZ1M z4lSAQ1-f{|@>*N5zD&WIH5_JKA=wtHt{}#^iOD0}0`j|9D|#x7pVwvIpoJ2u=3DOs zRFZ^$Y=87my^TU?PI;d#r-+$*$?q{ht(_$gTX+O$k3tWsqxniJam}ki#JtnVRBPJ z!=v4g zZ@UXnoAcbB7S_179F^qB-u=(crc?Pf#4u@NK3hkZAFpv^S;kP_lF_eBLQIW>!Xx~q z;lT0H)0CfS{XmFjdxGVL;-0|0f(nl}9-i9wz7DPuUg#sF&T;eDZ^kb# zyOnka@=;Z{wy37iDjry%Gec1XSo;;(=5D$i6d+7E;?X|-UU11IG>A(COuO;)$|>xtsC_%e{6p^_{gt>ymm7hSdNB#h$jN-aSf)@1C4r zHH5m`*R?w0`R}}?@)c6C%JXsT@LLWsX0H!I;>FqgO3!m)}tiqXcRJ7~g%#LDy2!#qyFz*1M#e3>mPiLZ{8MGfDb<#<7ki0dqc zcW@tf4F9?&@|99@|LQekD~@oK+L=`|%da*wx{Lo)yvdF0W0>Q7f_fh)_qJXp6ComlU$oc0je#Osnu&W-m8op_uRdvIT)N%z62#ZMOrcfSWn0;)fouC3CQG8>4}%Mcfv?4_1s*!)2HiNX%P7l z-fnJYC?K01gD0D?|;aMr}t zuu^GV;f<_m)p~z|dTBeK-hxZ3toxQ*nR$rfy!&*fj@4lp@OZ~}+0_pTS6$aGjM=x~ zDa~kCFBeNE(*%Wl-DT1NT<1!QIB8G+&^oR!(6;l&wFy5_Xlys2)^Y z8Os-MEnp~xp!19U*|VL%d$y7&CmWxb&x1)CV_D!(7+pnFB6a%7cz%uj0zYS6POT5K zqpxu$i8OSsC_seb+eE{?*rzFJGrG%vUWNmp{vl2NYO&W+`gT5rJN7qkfLy$D4RRq2wP+Hm@85O&FusFf={~#KylvqZ53NMMN;PGw+NJb=l&% zy3ZZPYjPBMUC*!oOVPo9zJAT!&=)>?Yp%ae0e*ZYL&z$C(9GHHQB3W2>Rm|$c&vY! zEkmw=>cy;NfZ&bQzp?<*$NxVYr(oJKGtFPn$U!zb}^e`35zMluJvZ78V2TG_IbsYMb}>_P}D>D|~6`BoVo3dWnMKG`wE#+o}qc zQtO9QDe9z0jzoCNY_!N456E#r+vbcIxlT^uyym_yFh-voU<(Vn5P|M%G{ zTGk}YC;G9r2aLV(3n)AWq+<8zeqrFM4LQBK*caTji19g|*v%FO=F?9B)gk(QJ`&sK zTHzk?YOU?6is2T~zCl!L#dip;%`p!U0F-R!do!P*o|&$k3SwVl5|&TWUSv>P$WEUF z8jF|>FCu_Zd)rb3Vb}mr)m~QR`A3-IR_Ot=vj?B!$caCT`AsLpUzXXg5;0kA)2 z{+8@Vq#8iZ*iPePE)Z#}tHMIZzQ*DC7NX|~_pYG)Wcku- zBS4V+!xiOeA46^>=Y`#wgFLrkRt-gZn8kzweq$46?VJ1xusKKobR=bXD*pHFG38xp znoHS}I46j^v}+}YK=_a1wNmuq7~Tgi}4D+1>0?hjv4$FijTO2y}iQ ziB3&XHt@mYoP|gc9VDza;QC^Ms(8EO*x07$4j= zm0VT3Ym$H)&A9owq#v&(2ELB>ZsCy~fTd-?m4UR} zcUyL(-Jz@Tx@_UFo?-Z72U1xWNK8AzO|}ozqO>?YtmNrNJ4*xftlq884fajjgC&S; zbeJi{*xo&mh!!Gd{-1prmzHd73Y!);<0z9bFTg5!*}x;aCU$)$RGCGhPnm#FdrX%* z!6Qzymr9>B)YUc~+ji${Z5Sz;-g`~-;8f!<1^XK?P%`r%LXNE6D`y1-X-Npm(3d$S z55l58$j*M};a7dF*~}Wk^6<*d)d0; z>+g$nR8k`Mtq^><`^SKtN!;(uHnYb(GRbnPcn$F|3{2-UqSJ-TRmYtkA$%K;1`%r} zWp87d09m}cqi%!_Qd~4K6Mv=JykBCg*o;GFs;S_YS^(VnZ|A$bHo9o@Cscug|BO2;e_2Wl1QnVu9j0-SaJCk zg!T81=L#CK6r@d=@#R%;nS7$xBN*9u0~&*w>}H(Isnd;fNdR<3(X0%sKpd)A9^T97 zfi&;IQ1j#Xl6Q?iZt0)bv4;{EuwMvU)+Zn@g3(f76sAHzq!|3n;XMI?3HNY;VcU~F zE)GZL8}`Dq5X2AhqZ;;1wO5~z`-;1~s(7lPDRzdQHAy}o7+IJ3BSe5Tc6MbHwo{^I z{T}lr>808Ysw#4pIGUCZh~)G(IE#~)?e6|9HbH1J^BJgF@CRU*?5+HKGY=kWH`cAC zfx52F{ZI%^>Zh<<3B4@MKuzq?b~PZ74ZxWyq~?wI4sUACRU}IBehcV5WxQHRzIK?G zWl^{n5|>Sp>czJmFe4Ts1uVK~h;PuQWJAr*C%6}<_BGB4{`ht%0)*635a(iefmj9b zLEZc?`{Wq1;6fx`CqV?L{X#WuvDD)7IeCWH6Sk^iex3Jul-tG@;@z=D`8Z@{?P~N8 zZmGt$_%XiV6egSxxSJT~XEPs^HFHZ(zftA_~Fd>z!uHUXGGtVy*jU zWOevqycS0h{|cCKelhSHM(UdL!$ge?OHX7N@m?__86#l~yopXN&BNM#MC;~_~bY7Eh zM!Hw#WlsPnMEUh?NH%Sv3$k0McwwH%i5YccSk34%z&eX zYz(GvKa8?_=j<|w*1L#xMyj>8$;&pv&4ROmxohH-51Hdda>Ubje;0b{l?qOdYtR?zT>`PHgo!x2+e zk~LJMK^1C}*W2JfK|fj+`CF3Ckv0QN{*fRdRNByKE z#`Gj5`UA6@qEt0Hlqx>6@uSLLP=y|4ZH-xO_w4sdAD6({q#UiK*P90?8>CqwqMy#E z@@36LP`ERp`sa7iPp1oxG-v$I9}c%$C>rVGa*79Q0w00u(I2c(r(2CraD{DQTsk!WH*g#r1Z-(3W9{gRIW zS(3dtQw3?AT-hM3!FM8PT{{Vfy*m+rn&2SxBi=PXPq@a8TlQ*K&;Ib&V-*)&?`!an zqmYzkO(pU){48t41ARVCKXY*G<62@ zQ3@_Sbyqfy^%c#Iw=%VPBFd}R%^5W^r_L}&7SjxG4iqFbKAYSxU94nki>5k-pEW4D zh0$es9dan$sP!F6!wJiKmj1RVbyu({rP~ER`5wVgo~p>GZD9V_`;XN7&1@7Ag4s2+ zYJqV*p_Cq&$*6cR_&ahDl=yT}jQ~Wg$k4BJ;S<1sz36#z5ksZI+ z;aX3cIGM%fr(!edj`VkNGDG)fRV%8LC>ZpkH5_~_q%}m)f5q8}otOI>;~wrn7VR3z zb1t%xXT#$Qzi@_pV!AI_EpI6A2^BH*2k%XW*v@_G1Dut6_1_tYCd{SuIuMAB*q zhaG6F5aLo5fpiCn(+J}^cK3qNu_}!T+f6kUSp^$&G{6u^FARZ(P%ZenJ@#}WUx9TF z5#+m4)-q_<%0uP!k9=0I9KKA~zy39aX;Ng>v*Zn952_(pSJ3kL1>-bPBiyggda`v* z8sI`imGAnlV5L}-m1AvZd=lJtG=b%_DIz6Uu#GPH3lnX4^c1!D(E3;t_wg(1m1i2w zXjo6CZ92)$1_!opQ7=8=;4H$k7dGI~kJH3GD!L$rY-C$+q{ph)xngL;a_l1&ll z#1Jws^0Yqn&8kA}F`qmu^9bk*rZlduhjrUUN9nu9wOc}tWG3aJ9>~2Vbn-9u#xUc0 z3e8pW)+zP7@5cRKlPBqw;XiCyR_FVJuX-@(jR=S;#!?sEoSJK^9H|beF}{PBeg{)T zmA-PU%}E|{@zY{a3XDst-}6YFim_^)xhV>HWnX`+lfADDE1z<6m0e;EfFDj!Q zy5*I3ESPgOpHtu=lEJcdxr*(5es41Ovr@1G$pk_yzH72B z3t5ef)5X@gzV`ElcT;iIWLJ#Y(I0_z8b9>4qcL{ln#gS@KlBAynTEErymDJoEmyea z0k#D>X7kd=z7`FJ(iY#P6ly62Pp7K4lVM{VWtFxzpBI&T?8M|DRv z#RmhTSKbN@=I!Vf*%>HI!@p(){lN*Kq%Yt3nGuV&ji9*mc%_G$?R+2UNS-BZQbiJ~ zS^7^(6(E2;6h{q zk8igsCS*1h_7dBX296&rRdhfAg0O!5ZXAu!B}%^<m?T2c-6~5|)pid7X*IkK76TuZSMfgH*+qS*Zhw4 zcfbz>({cx0m2#XdO7c=0K?7Tx$yM+02IZa=;F>{;;Z9*~qkNA3I zNE|N5`iK`M=@gCMU)^xb?SB*>-;yu|tPT(WSP-7Qh)tGtZtk3D2t*z!+?w@7)s7au z-wuO;8f#_$iImvBPB%NbHxZ`DnXdy1p6ATN67n)gH^YPcfm{AJNYd`?SZ#YfYaupc zzRjo;M?1>Iv5RYiX2vC#UdRcDD!EBj?!kG!UJE=~r*t{D{$Gz2)3_a`BHy?eiB#i& zBOFXYLH_rV1X*m;7Y7EoIQ%7sr-wIiBKpd(IvlLD1udDja-f z?ty_WpLW`YOg$`8*|t$jLYtzs-dz3mI{!#!1gdFn{?vi;tfsY!bUZu^Oe?);Fk%VF zshK2Eh;yap0jr_5=-1$BvK3W>&Q*D=BWaty`73gQVKmogdxBRB_L++uD0HqcrsKMx zxei({X}(^P;$8_doJqYIYsUxTC*h3fEPxd{%F@hMT`rr1Lh`x!^~-`^3e6+pG@&oiVKAE#FhZdDIfJ_UL~P`R|^9i~{MuZZmaX#x^NcoXGk6YHZVpr})ip7`TDCp674k zcY52Ka1&E2OOf`a1gZ)OODO-Tr&u*N$LwEfi}!%4s#kHxS%wPN19>=Q))cwP#OByN zF`t^7=b`C=eu6bv%i}u~9)^<>-|lp|&y1v4o5V5&M1gE^OAo474E0UD8Ex0{(BmHz zwtz_hqn5vogLUv7{VmSXrc;RoJvd0o4DN+7OH&tO_(RiYYuv3^qbjN4G`r6|VS`48 z+HzHr!}_UVFR3B|5Zdyc86|gwmxFKy1qhgsZ?SlkzEFKqZ~Zt8T(bQj+{5_^_@943b4P$v)O+%LxP zSk-*aaYrxt#?TXU>+Cwg9aW6>)7GUua;!dDaiCxjSKCzlDkhd>Tii~BIh2$wDE^t< z-|Z*gw(&Pg;ZoIA&H-_ zH%#cQ{hNPif23z@O>5(|ks;HmBQFKBiy!RrtOdP0$7` zV)s;nfLNVSFAPluRxQFGGcX;6F6|Jb=cv&1C%eC;{g#^3biiptu*NTy_94jD4>v-6 zWRVBc=4>lj!k#hn#h!&=<@u8~nR|O&j%2e+Wt`$_N@M{rIiWHP&&^7U-h4d_J9`hf z7xX28VSkpM>qz8eK|iDVikX1JOLFaqWlz$uZ?*S=vPjqD6C@-b{pl9Uj%S=p$rBBCuuy!}{rVSnYPDepn&8gHT$JKzg zU#%}BKM+4KR;xo%@C-+2zeubRZ=M}x@aHz5wm~(XTR2)aCAv1|%G6e5+q4TT%8tt` zDU0@;(Dg&Z5WCl7)GT1Xa8$uaK13~J`^A9lz1cS@UM2NxY^kjiYR91q>b5=wr4a;x zXPfHKxs$LYgTKI|*vC}Oo6`$B$S$(8&IZthwc*(>;5*}!t;}*Um4Y^YWD)7Z zk!`E%3q@$s{PFsR%o;;O8D_ez3f_9{SSQCuMr#2?twlyC?SLq?0~k{8AIHfr0-)0L zea>q9 zx09O%J!o*5{Nm{bxVZSIa?bS+Hb{rK8s5A#B(ux!5pkXgY^#fuGa*v|hH_$Y1seblqTHf7g^%x!>tw_E>J8H%h}Sb7W2MVwA?-;Qixf))G zA;PKFZ6<%9W6ysH>jd7()2NLuj27Gcu2#@pts5=fPFjXZ0jV8kkij#(7?Kfb>`Juw z3w~U}k9H9OsE!k3CK!Jt_SjgBMZ|xIse7S~^uDAP@gLRu7h{b<{;7v)yYydE-WO?O zMhqbG7bk@&yX_As0;Ci5$Hy>)|K;#A4_N7&yZaa5F#R8Y4rCSE5k>nO0)X%{X_`k% zw~GeC;8{Pk@BvPKDXt_%{bT(5%6Qv6x#MejRax;Qwip1J9g|dAaJZ;qB@k9-QX+!> zl?Bl1iwOW<&r}>2cv~%4P zwz=L2td@c!=6`9)-1kiwSw*$l@6UTs=)r0#hT}2Ut5v_lM*HxGJxjX9lnvg z<_|&m`)47+TuP{`=%;Zc;j*KYdY-*J$<-4niFdeu5-N0hV3dzPge zK!#w~|1`1k;#(j_-)nB%3%8S}J>9lCBc^CR{nC6)LF-{d9c9JiC-S6nWD;G`88gc( z&VQn1M)2wW*{#>ENBO@T{Dug~5CgWzm843#Q9OY3t2)4(^27m~1}=&NPfARRW+DHP z6j$_OhI{nmc<@F*IU7CNUc+`@aAyzE|C6(i2HSoxG;gjABBYkg{%s4{IpQV;qb2oI z4_*0imAD9KSJWgD?%R`EJhYkXKfM%t^R`ME7{@YZ-V!ua7e@8yHi5*XTx zcRhYOT-b|L3;tj55AB6H(B$>2JTCh06OHk%L$0=wQ+RG?NuG2k8f&`*FCzSRU(E~Q z7b!b_rOF;tsHc9(meP-mc7u(@{Wo>ao@F0qSZi42{7>mQ7N-5+JKQ{p^0Lk%>Z~ke z&bG#%`z1aE+8wruWH{n|_f}`c23pbE)9f>9G4z(JJP%j@j7Y@0V|g_v{^DzYjF379 zfHgY3I*M|Yh`QDru_{fi{iw%KTF+I6?_h|1&TxzoN$*pZntq_4IvQLodsLX5?ryemAaD za@(A;t(v!39*-c?3(WWC7!s8$<=Bv7eUR1D{#KZc=be*DuJ+y59 zNUB(wReOS4xOjjvlbMXNg1y1mX3<=FWZ#03@R(#zIZH#F5;%oe&HCTZr%hK>1x;c% zybs-rc&EdQDqU~+sUmTkPA553KfNVl{u{nA)cId1olee~94rQTa6VT2?lt7T8vfiVoJG?%YGB}tDBDD3=-Mo* z^+Q7Hvl^p1GmqLK|?Y)+e^c=s#$}z0si5Muqv!V zi#C0+ur!_aTN-iG_7`fKOiK)~h%h*v6!8Bs_ZC2Lt?Alm5&|Isg1ZF|!QCOj2_8sr zcZc8}+}+*X-6gma+}+)!(YuZOs2lxU(m2K_^jZaQ;6-EE?E22c8f0-6bi zko-$X*sD@4w(@$hEQ&Ba34WHh$|+%bGg}pH*nKi+3a+{|%X8Uk(WKkI^XaTv#iN@> zswW*x*Z$17i8n#>%qYjws9uPS3OJXkLrD2|zkq4Dr078ZGZpbF{)VWHngZa95Ls&U zMGbY*%xA*Gjwh=ck8T@vObi7US>#>pD8|!^YG0WhRA79j0#0!_x>mu1N}dS528rtI zi1&7kzE4(q={EDjQr)-m@B##J$hssNHG%1J?LgfhfDK-^q>c|ZxXZ_4$Nb>11jdVD z)IXDPf7qV22b$!3v~0`>7fhEYiyXKBdLcZfG~L4c?|wdRc|7#S z(86Lgy&DmCe~r+=89o5@t)DjJh2Nmmu6l2AMS;gV)AXh8(jjdNUqKe8*Q9HGEc$sI zy|!|zB_bb+&yls{2?PB>-X|P^ti5f5#M4Y4YznlIyj1b|Qg1;X_|;IT7tDSKTVDmD ztl69;md36YoAHO(rj8)Ia1rY)&OTd!oUWa?othRNeYW@(rbjzM3-_n=mbV|xPz-(r( zINR>zMfA5SwU*B7A4uU$+m86x;%$i8RZ@Bs@=7h zFwfu3N!YLx#pK{&docuUjnd)d5`dEoelRR6~Lz6J@sLbX;P;-jbj$}7dl`vr$ z;oBJHaASoSbGEIc#A_l=jBB)N7vN?R*5nCahV7FMqXaBo-#@`7hoA}B6A|KdzO*&klOEwHcFi{2dh-oHl@ky zHMyBdQkON^;=5)ym!u+ZUwt67g?(D5N(?kbO0-@G%!ej|EtfQRl%R)2!tQ9&?=eeG z53%X9#Vw__I9uihFL^*Ke7`P9y3J2Ir*#-_oUE8>)&sU4@{F(&wh+wLT{|k%LBwyH zTs-SZ`!O_&JWPv%_k4r#+kHPW(>}XJFdv}{#Iy)V*l)98`QHY{W7 zh7C>*O0+m72hdq9rCLcWKA<>1`TOGca>X+SeUk4`j@fy#PI+PB zgASYh%7)(Emf&~3h$VXPH;_rf$>sTcfL$WZY=Rkp5CyN7WRhS73bhpwa=)<3DPB(T?Q%f?qw^hswSr^>hUsBE z)cQlX<)d>aOpAf~BleMWl@*}|DY7jI^#+DnxPjy0WJ-^2ZSl^R2XA#6wob+kGP@TfI|j0hg?T=1O0s-0T1P(TUk}bP(?qOeisnZ{rP47L zd3|(uGH?CHQJ;IZZQL&e;Vtb4x4?P6MukOB^yB0k2%RWtF;GA3X##c78)r*>xDm?C z@hUfk$&V5q^_XdaSUk@ibuc&Jik7)Lg|ecQx8GWgnv7?NmEmj3*+byXTDYD+*FoRU zBzen{>xLMZf+Vm}?96D_Xt(f+oXUud;()HL%|9&8bW8GGFsdb35K zDCcZfK$LT8n)ft8^+5?PbFf~DkHsN}S4c$YN_4+w?(7~m8ut>(coH)oe zZ_PLMKXRCPKCayHdzhAcc(VDQyJIHGBS^;Xm>NqS5SN?3MTUj(^zajL^-e_Y$3REp z^&K4A?9q$k`B|I#$2wvRg+ip;`U_d`;57Md=O)+?(#Ii+AZoM_Nh5arQ|!tE3M?E;zIO48NmJoI123)c_tRGbwoR&>Rh^j~ zDAIEyW8XLqHFaQaKx!iVPQ&F4~&ht;@F@ zM-y)ue+6|~UqC(-d~`^LO%C}Mi%Zo*>2;=&(DXMQ0ZMh!N|#xMW;$O7`7L-seMq;`7^_ zJ;AFf%H$KyuMZ}6Ns%Q^FmLws&zysdjv~gji?iAm+-mX?ql|dTIltqn=`lExO@!C& z*0`_;vUL4Da1Szl6hA@IrKE!SxPfl)L9H9>lx=iUB*zFQ!cbN7YiHiGO4N5#*M&id z*WC0svHNphhfw)27KGYkLb%W z!}-q4a(vJ;3Lq8_{n~}J@vNMf={}~-I#o8M3$h6}ep2z2-+Lvo#o#V(RSLrI*1&og zh1aFD$kP_%653f=yT_}#^x?E7H%Gcw|N!}$u+K7+Njl-m1}{t3qIPgDiggVTU5>pT~4Z(!n1 z?pbPK#&A>Rx}w*6rS`$nnB316G&pmlp!Lflu{{g%Zrul7qbrbv9cyo*m>G=9BeqWd z08m2{U3SuY%kRA-GOYJEPuCKHx^};LccOI&qYv}kHfVSj!|jNuJ-C-!WlNdPGtAj4 zxF{|xW(W|R=L8?a^P_q_wYtJfJr{(gBIxd9CWpm3&@|hkRm8F$*>j49HPxit=N7~w z3JyNVjL%ve&Gk?)*}NIeuv!C39RCz7;*QdAd{Q-0qCy zIcgb3tK}!I`|Z&1^47_!-euS*gQp|8CZa1@R%=jaEDSAP6kp>^Qf;kCMy@#TY}LTd z2R)hV(`1ROgyF|WeFDOt!a)5i9z^Ocj4C<4^V7+swhxh+Qo(f!%MRhmq~0??YAbH8+O}5KA6yU|ve#dMjo>v}>*VVK%lTc45 z_gHvD2VUwU%X5#hI6Z4Ub00+%VGT%P@C4PXCDaf1^MJbvO1WlpoJ#~K4oTIf@X6WIT6Xd3ZgmShC%4q`Y96BP}(j#BGq9c!o@P}1$ zN_{pnsKk=4p{JUdFfZQA?E6fAUHsu=Gmr25aR!pZz>f%%$>qgmAAKLT;!j8akk1r# zze1j&CJNHJd`5|CxExtNS+&N`tSn3_tn4mc>Rv*ZyD#*?9{-qn`<@Xxxc50{@c#tH zR)Sz)Z62a$4u9+-;9P*G5*{kn>wC2a0=+CSmFHj2-kv2OyjSlEr%g#`DrJ16YH4Y_ zOuOKjsW5pd({-h#5nEtVH=Id2eNik0W&vaXJ0TwQZCg)U*dG9pbU{1eFFbUwf5a2=@QuCr@KwpBm5jl}Ggd6N?Tf;& z16X^a# z=^GJ(^~-bvTCv#42`Ew(p&|5+p>chb`6 zLV1GCFd$oP*W)AfHTTQDjg*|;NHCZaU9|z2#>&y$;PNL<6Je)jvtla^pCpx%2q zT&Nl5hFEs0*Er!Mb%fzsc7n`^vedDwnznXOw`$0P+^Lvi)cDGAYaRFY*7HjJAecwLC^oSjzB9HFD0EAfH z&EqksS<}{ujbX}VU~o~&H6)ZUWnP-$ztlwqM9ij>en%buC})*2#x3OJI- zp1>)gG6OZbI*S9@qI<|Ap~m2Xiim0=OV;~&9%~hBety#*K%;l=fhnr|0aIpJ+Tq%c zN06$q5|52v#|ai*zOfef@kddsh*R|asiKzU%-ZdbJ5P<)cZCr-3{*F?uXdHTukUEH z4p(4dU?3@{)A3rJZ*U%+8O)Xr)SC}}b|}Um4ekE-P@dx-QGVIwi=14= z<3yhPpe`ldnjikCwFv@Z9pY10qsj?)JN=a{aDc4qe2p$x?YsW)^HtYVVme(0jS!m7 zDqAK?GH$1X7!_8@elN0EdY6}JA)KGGFGPo`te@dlCK(a2Jv?tS-8}FiIZiiXDcB-K zv}Y)3DNf^jSXI3&PVVmLA$V>;aD0m(|9|4@7?zGs|HSg84Yr_$q7qPn(m(bQRBTun zCwVNqjnI{S7rS0WbHY0^$7(aNdg-m1bOF`ORo8L3=zJGK;YHYQLvdRSKdR z9^xIlHyzOn5Dy;bA8ek7zdJ;Ozt!+)tL{4mELZSQ856_lCbIY7Rm zOK-Ow=)GP0ZsPo=dBvv71M<$*wkj_a_F;emn_%$0>VmH6fH-(xsEq4^R6C2_CHJ8l z7O{>Fd_8NDnK(>@-rsxS?lrOv42w113GVkXafpM6J>923H&G8Yw2Wyp4%4+%xxHC@2{q?n>T{6< zF!UCSZg>Pedc1BLGx9#}L5}dv4m!i5X@chz#_NxzRjD==&A`*~zei~3!#+MQ{#k0v zQ#1@sguz4N-=}h`e{6SB5C27RQsUdJ))dd%TarlWH8S-Q%8bS|)W)3a+{$p6d$4UwvOs1kjvo~ET+8+5ptA#87W<%R zikQqQG>y0pi`3_Y)c%$QU<-tS*-5^|=c`^rS;?b0#>W%_;cF1YiV?s%Lozqk{dgHb ztyDu|iLwL9z*_b$nRaYpI(b$^dj*FS0}TZVIpP79jVzjun$i;?A!#sdnBLW0TI0lo$d0@%ZMe_lYU`Qn7EC|J_~$@2=Jym#0|iV{ES{xi))4SJCRAfFDbZ zsU-iQJZZ}CR)Z-)gr5rvG9tuIBXY*e8~M?)5A?KF#eT}8OJ|>42~oim|6eiuePIWAb4Cf5Vh085YZZldKhZk7vc$xeg<$GRmp-nY2&k5J4XG>U#EUB1EEZ^Sm zD{2mGeoF!%OFZ#$hHBMXs@wMtg9ObdpyP{&eKMY(FN(f4hTpMMVLnPE4EvOv!56~L zNN5h(V6{XQHQHfSm)Qxv4og_n&^olEM3@Gjg!j`)EXED9N`(mvI^du|X(Vwb8H@;7 z)Kg=PfBY>tn)5Fc2ZLfW3yfM$0AEQ^_CT{c zZV=blbQgn}4DMC}3qlph{#&DM;zv#iUj9R4u+W8Mo>u)n{Eo#cu~Pvq!)HND3Ih0m zur_N}2&uQE3p0EyO6aIwDj%PZ2w;ioY5~*-td2%`)>Q!NMl8eySHxy`k8lVPrzSg% zSuC&prlx8Mmu=N&0e(~eKQ1(IcP>qyj^a}&&dNVfd0Ipi#}s&(-xWJg>~Y>!NO62P zQqlvn-XaR!iF(6%)gRxmmT0o}+d_I`S$F+Ufl^Qxc+lUhVep_d4z+HvLijxgtjvYA zG6;pK(t04ntiEPg2s+41;zt|O;H{Nbc`zvIr(-hT}pu0_HhtuB18;tovGA>_VV-i`}y|Z3NIlNLhx^6$%wzOX-R=9#d2tK(?nfQn&&!isf_G3`F3B5q;hWP8v2 zU9Glk*%AFq(`S!EkS5G zdoRl|jKzBM9jV)i12RXe_j5JYH=`23I9j%$UAm;tSvw%cmfNeba&n3Na@8)Dh~fd+ ziu1{Ek$3Z}Q%|?}!|fQZ)t7+OW8kEMyW7+?Eo}kO!V-y6msW_D&GL`Nf{yvxPxu%x zVi3cA>;dY>1Zm_G46a>(?q@2ysVknKv2T$PUbjG6n`1>x}dt#Po+4&_x zbZbEI0`M)J{FxS2E~4Ahy_BC_Qnpm(`z5+vt;E$ThBO1rUe%R(G>AI4*WFOby-WfE z%;pcG)YD|NF0%U1ma2ST5`m>|OboEDh1ioY@lRC>VnHaHu0!z^=C_5iEWi1U8r>XQ z+z6c)poW6!WV%S6!be9W6I-ov9U0k~?HZ^&PsmHXncW8lviSK*6&?ThsiqjUrqh&l zluX2o1~kOFPxZ#WzCEq1lN~3~A0_zM4ffyn*b)G4Q6a_DK0r}_VNXz&Wez!bPu!|p zv#a1Zm@w*GqVDVO$8|9$+b8U@E;YL44h~nWHmx~P9NF#8+_e=X_T8ZN%Me+O0m7Kr z6da)1*Geg&h&*7k19GDGNc$lm9EI_dz@5#R1DxXh0>}Yb1)f}?KsS-qZ(Rkg?|J3Iy8}8 z>*uSS@V_o=jUiBdfb#MXJzuZ+t*D^u08&5eRh!qiW04IdigbF(*uJ{%iXLYnnF%Y?F{>=SBxV8-M#Z ztHsD1qU&Nr1ZReB;o|x+Q%ZJkXVwRBJX9tp|FQPX{5*7K?u=0Ra%8Lgvc5!scp7Z| z2rt|J#?3Gpr`i{Y@0%*~b_%Yv9^IL3%Z!ha|7y{fdedOPFpff_(KSl1wRbQP+_3qF zE8;z6;)E|y!q&mUjo-YOa=%U{pIYTF7p|5=vbJP!20FHWaEl_C6B(G1SgR?I0=#o( zwBh#z-^VzN2XI3mp;Ai()+JKG&Xb$%U$TPNCwVeSJ;ihB#Nq%breD1G&&gyMzW7zd z(kYRJu^qVNC+WfAAhQ0Ky#QBm5&m{Q*tPZBGBI~Q-jADC=^^$1RoKQ*l?MtE$ zJAIty*B|3-UnPwbzCVXypV~DlNtmUA%sdYyohc_Twm|l!<3y~xfBJ}8t!ooyZ_S`_ zMP$EVTX(n6=ekv}77T+-FaoIzDZ6)r$27%YTBYz@EodC&hP5=;5!wx#I>e^eL@f?f z2Iu|YvDNN>oJ+_2DvMBvyyG5jDveGGe%y|4)=la}TYCFl>y>THjko26(hW4b`9<^P zsA5$zX8%J%<7Nq1MPk`v93BS2xsG$PAntg8cPMP&Hbz$j}M0*s`X$u;P)Pr`R5j5jb~84GT#(+lWVx$ zD^%A%4)~F>n8d&hDi@Uudge6y_XE}~qDL#IzlGm(Xm3I!#y^@r93Y<{`tI@0WwbUd zJypjTU!_hrhn&Z4k=4kL#CnpUaPg>ZYG?JAQ3iQMiMo*1Fk|(}z?^J1XcLa##3dQ^ z2={19w(=X+)j`|Jw1~)0M&md$tZE)YB&R3XUH+Y$%{XAzE}%S=ArJPmwG?ab;pFjE zGRw4?vn#_z;fZLKL}ED-3`Ts|q?Q;AsQm)ZS=)%R&rZF`BlV~^FJ>*}3M!R2a&Y=Z zTsCYI+XvJJ9$4Z<(Xnn01&C__9}w68K@O4Rmwfvl%v$+44nw$8_uZ2!J652WXx&d_ z(sSplLZCv>OK#s~=^SWhaS7IbqMCnz$`1iZ-et}DBx;4B3X>_#M~a}Mm@hUfLfU`@ zEdcri==EKfI!jaR{CjVCA4!Xg@ z5)->&SWlGisx3v}HMU_E;_knDE$Ee}PHXP09UR+RpHH~Tqu@!^;n~X=S+>W~J9AIS zKm>Jh@#0HNOB>cCtyZsNV!h#F*>Q|zOvIW~@GD+1&jAn>oq_@}e!+@NjTHtA?u?6iFKqEHh^Ob@>V6|s&P3`VaT8B#1#3B!P8PYK(`ZqGiJ9$QhHV$9=mu>52@cc*c zFucsJORQgnX6dt7BH=-$o<@IoP;Kuc!_iyzJOQcex7e25S{k%vbsWbBk8H2e82(IW z`D5)4TLFguLG+6+4uTOtv6-rsev1^={IuWxUsuytsV?s*-OyDU6u4OYdRi-=ef$qw z#mKnH{EGqk%cXTD*C23wjxERDWytJWD>eJhugB!6y@nFBg4GiAgerCW`xf$93+teK zdPW)4X~N8tSK6M>@fYjWD*sok*C6WeS#JUCpxuHaXoBKVMB)<`AV;s{m8^a@QUBKQ zjy6P7S@VZ`n(s@zyDUg=F`Ipe#q6Eo*;%38(REEuy8YjGmGx$diU#vFFg{vjB#>jJI?Zgf92A5# zPXUpCtIy0_`d{~$62mApHWF;n5qEt@tUhrqvG-<-G1NHQxF}(BzW=+%)BSwvf7^6| z#1D+ND$iQp84?;W=+U)Lwsu_{!EZ16^&ANNQ3h}X9Dc$|Q2LS$Sg};+*dQse`n+Bd zbcO@?`#t7&2}&(xd1wM=js&6) zbEG?-!185YznTV|QEb_|n%$P#RKEx1d0^|lL6IjX(PthJ`nJey0%I=YALv;usC{WT6 zzq)^Ycw>@@!m596XV#b=tmv-^Fne;j^Rp+pg+9&~%;HOJ50?(3Ocq~&pKo}@9Q#26 zNLcdz%SsHjr2Us+XT!G#dCVMD@m>7Am(bAKp0VyxrXs!EJz9+h+{^k9>faUY8mTSm z4?HH>EY$Xo9o==}?zmQ~WWcNA+_uSJ&yrcA#LixZ9l zZ&#&bgVSLq8capOMM+a^76@fo1In87kXgIBv9uQ3H`~PMgnV;oI?M8&{M*ow1nL)m zx*g@Q$PAec1L%N%=_-HO$s5n%Y*qiEhpo(?ttD^ot^9>7p1rS5(9$oP_c6%BB^ix7 zgq1D>vvFotLEo$HleZ)r+rn{!7M^D$_l>!BmdxF$Sw5FMAVr(yA=Y$cNJ<(s4zWv# zqu^ea6(Zs|Row_^^su^V&bH^nF!~lfrY-UA(KUuX#4EC%nU-Q7c~QPLw%m8h!rCRs z$PwjeSh>?N$3gIQ$ag{)CKGOS$M0)a5G3Cde${;-B!nOW8(q8*axFTrWs{%W3hXeQs-2_Nri@Scn4824cw!Dr zvLX@rTz?Jy`0bK$l`>5p&pz?>BwDlaUh3Ledt`k?ye;n+wm{9X z&K#t23SK6l#GHO1qD^>$;PLP`F0R=S=F-i3OBVaL$b5PxtyN?((-en48jBr16eN?< z&_EX0BTSAfpJqSc+uT2h*}ld`PWElnR6g?Sc_syxXxucG0i9xF6Nt{t0YQ%K%(4uF zc}dM#l-~&Fl0>&SZ*hWMv)<_t#wmq>?&$*&`Ci%HTlPo^!amg4B|J?((mhK2TKUGIn=kD97J?^t=9ltHD8(CD*7g<}YWD%nLtasn3 zI&|xF?cjPDk%ACR!W=a};dl%hvaBRTpDbKvaou0@Go94g=UUpia=;e{y?*(8iZkHt$0JYMvMcQ5y&bRt zoI^*;ZOTXSi0;1S!?^}l7BW|xn%vr`EYg_cUB~D8+2{^AV9kXc6t);^=a@bD(pB{Z zG>zRBl)l~HN<#{GwjH6hWLyTOO_Zi(*SbVG4xL+wJF63&)tm)I6bS)e#I97`(VUgm zeMN%{aTDxmBe2`h2XuWa)fxLVuX-hZ z)??4faQIOsw!h49Z+k}DohcnUHsEf-N9V=aDwBYpYVNXH1nJd}1#Jb^v;P|&dMd%m zw2O#UXjNSz4)CtU-L^bn>230P#^PxXB};4Hw+)r`Nm{7xS?I3ttm_?7xuc$VdU1AG z;s)3q>G3oQswDss@Z~`&p5=%*W?rxowDE$i;Y_%hCU|BqhQT2riB<+$V{K9Q+&d-? zmjgqPBs9#?6H;r8oE@t>oki|X4CXZ!u-Zg9t60A+na%fgdi;mj4*%iDn_vV?4E8C0 z>YXEy`R$#E_)`F99SYp20>}R`6#JiYo%O$hI8amj;0O&~M6V}Mi?dokWpo>9LyV*7 zX)(mr&k8F9XOvCU-WYVNRD>BT+1~%6Y+Gi(^RgiTgi%M#hAs0jRJ&XOInr%?wM&c%jtz{+TAZWkGF^cB& z?dZ;J{3e`6p@M=$#8g0z4KmCDK2ljz+z^-*HVzM<;+yxi&IA#j-aqYS2w*~i9n0ur zi!~mx%Yd_+@sI6mxfGB)asZKd6Q4W-U&s7q*<(Yo~PuBqY z65muM!``;Wypb@3icIqzp!Ug!7h(M^3m~iH!?3Ta)%=+cn6*%uYz5W=t-~~z_c;DG z_pTxYV>AraR^6|L3+lp(#ceo#?j`I2|5_ORj14ErnYc&L}yG5h<$V$t;vcz>c zmu|L!yUu;rj5;d~$$oiFnO>EqS1CuFLKNRM2H&`xbr*mAIH|V3;be9T43B|zRM=@P z#5&w3?u>x(TNIfOz2WW(w(I!fL z`p3#0O(mWeO5G1nAY@|W%iMnWk*#6|}&y#2Go_U=i!@ZID@jE>%@QsZ3RoG)ZE;2#&7Td*|HOdgq zSV%&^N#-$Lp2n5>ZC(WaqYExunX|acp2iBz7ByKn2nXIX7CP=sNwd6MnEP9Mj;p`+ z<;_OmA~0-(!aH4CgW0sAquc%VXL#ukmYP2&G5~Wm3TAzOh-jvi8#U~Rhc z(2(QBxMz-cdL*O2Ay?Prp0$ijV$h&A*gN?A1RJeTf7l6=DlJcXn&6?=KiQ}((qn%b z2KUoovD=b?$pxL=Fu?cqdf9uzCAKH+;oU*4k;~vJ=CBNEDq7>Ap+7o}y200m6Kj^= z6E0SAH4qxgs1!@n#<)l31EyW(Sifv80=+^Re6ap(Uj${j*CyS1lnhj z0n--?JX>sEF#6)-_VNsyR91t1UvfOX`ZL_WQj1));{PQ~dCM*S{LRoojI_e~f8vK~ z4p4g{$8ZPb9eUtA+`U-t{DUA7KT6|ELIk^49wMgwG3D}H(V&p>5O)EfUYT7BsLC9` zrz8?5YU5vItNo!UGtCiYhcF1Zku>Ul#s!u&fGEKmfQOKHa7}~`J7bFoYJM{BpR51f zSOLTszx)fDdYcLdQ=~9&IhTJ*2GU8VwQpqJl!HgP{uuqsO9}pGzd;xRNJ7R)8zglg zhrm7`Cioqv0fe3tNzSW3=oa&1_%Eit_h$7!ehVG>da1d)oF@V)D`(ckM z!x${amGOlvpi@4lX)g~wpI%{&>@+0nAcw+stzqc<3m zoJenDUrRd07uEwB}>qDE#S#ItU{s6J%Iy@K6(6VQ}+MR9a?03@A8g&NTCFt9&$Ruihu*~DI# zF*|%#DF_CTtzl~C$zv~?L45rk9I7FlLhZ{vK`xbxmR|hzW>LmTRNIWxK%Y zx5S7g+vT^@1kgY@V(@7sPZySC5BF|ljl^nS8!f0vy+7NdwrSZ~uAGwu2(Xhi;E{$l zc|pO;8zaJQnWp=MY>q_YGuX_bF;CQ8Yhi+G2|hz`J@j?V417oU^YGT>rL|Tbe&Gk3_w%6u>84Xp#~Ai45v*?M0+Hm z!1qxbu^IsYD?)Zle~`kdN5_y$99+hdE}$A_gJ))F^zQdr+mO+YH>2^7d&RH`fEQ}| z?v{AS^wF8Fo3mGP|6A#!FMbznHieZ+QSh(gB@>L!YA^%42Rfx2x~D7hmvQ~r(sUN$ ze_D_Hpa-Q{-let@)rC1=h#6U1B1<95VlBz8?|Bo?h$rma@D0;LFCamGOb0Q4qS7x& z&}V{q_uCx$i``k~-T^uh6GEI&?KQ=1buEhmkJbVxUE>o04QOeN&1P55VOWOt0or%j zZWX!_LiDxA%*;^C?SY{{6&Ae*C9$zD`2I#3^sfi$#d<`IYe3`-1ri!-T>A zM~E5K^Yj14Umb#uX@VJb3E#m_yH0}v3Jw+K#?@Ad5cc*~p84~|fPXT=bD@Cy@wBG2 z^S*sn(MxX7x*@vPsnH8@TFUD1Y7za|QiB1Tpxd2j)!H>VWls7hX~tVx&FVVAcf%C& z-(j0iFJ}iZ+BR`B6I8KvAutA*9fUHSR5_kIB_Z9Cx#^fyg%*ecx8D6CKf!&sRXZ#b zuJJBoo%0YeOld+x@U>0NM_(n@e3u`HxLv$3HZixu`z!~tsM+cLs_V z7h6+SAq-V8rLjYl7v6-P$V}?3vlF@^x)Lqw^3UjE4oo{_6>Ug9tOGwsW1ygEbu!K^ z*2>EUoZJ>f(gi--wb%aQH zVKHLCIgH_bz-|~XOdO9v4=c_#I4AX|z}|scCMwJ(W+bH;;-Ek<$JV=mp;WaG-uEcU z^{5ZaDrt`O8Dkz5gTo%{ijY;7Orfdbs5JeN?5%dON1u9EV=;Nqoe7_nAT_`2R0P*- z+>vYab8**ogUL{p4Vs2?kkgT~SEhT#Vp5ChuqJ@C$@kQOELm!JQu~Xns?V7NlYop~ zS#^4xe^r3IqQi4|;Q8>g->cyB4sj<=T5pTfoK>WY0q<>6k)~ky_`{)OWujqMsrFmH zS!%2z9`%h?mg~8N5=$!~G=^^S!+ncMY1K%~bxXWPmvox^?EaF*2>}=pn&PvunD0rN zG4J9aPGLI6uF*Jbe;SU_YKCYGf%3I!L z=aTziJlA`{uP#!vNrs=D?LnZd?gY8ekbO2(9Ys6L7e{AP7U$faWBwu$#oO$f3Fuw3b1Y}EL>2Pq+ z!aP2$N8b6+Vq3phGu5!H^FnB9)96JGC8G>hT`{flRZfz?VEGE|qXb=(!D~#v>q$LD zsJK84ta?Z`v=!i6IV@DB2l`)j;ro8*rXt|aVO0yKu&USd%DO-vQK%BxmM0yk-n%z& zQi+`A!Tg5UW+}>Q{IzYfHY7 zR!NDY$0p{l{bJtlD-+SvDp#vxd|_b;w=TxgZES;odDVV9q2mi3#`GLfrchqg(~g90 zn4^(2Q*bxdp`GJ5(~EjPzB7K?R6pSt7=HGt-uhLPtvL$5R7r@wRt-Y2qQ)gfj5(8U zc;bwq3RZ{fVX7%)4{PbO{DHdkb*G#U84|6=VKSrdl%MNd^H(Y+qt-vayt4C-0U!E z!hPJ4o6ut;OLm`MoA%C<6GbJB@40b`c;M4nI?*xIGk#potD{w`UcECJeODa~u7TPw z>neT*Z-gJ|WM>-Jbrnoe_vMf%BF|CfIp4;E6TU3E1sMw(gCQX zp7#a_MbVsYhYA`7P1ZR&c$#cH93HqT8d2M_CEG160zj>T%Jf4>x^deW1wNRyRckXc zVdyI4*xg%4^<-6dsLD&Eu;&EqNh$9yuliDLP$1atxNjXe6zge+QPP)eVcYb@P(MPu zN^wj*-?*Ie`q1!`(zpruZV~GIH!V2nV>?r9uowdZZ3(u`??IiU8ZVzis|;~V??E3_ zq(O0{nH1VMc|hrWcE}wnG3wa;#^{mc5;w7R)4M~#XQBdqo1e58h@@dw<%@Htb3W_H zx&fbKl+_G^8f^aL!m~0q@6n@<9*x7d{Znq7oA_=vanGMeU}BT}0V{QG=!0}F4Ba%Q zKP91*Szim^Oiu|HORQH>4cGSsl#$8rr9=RFgokasttm6WygKG7cUD8Y45EQD(c5dE z7X$qjy*tZ|Ash`TzT>%;pJei4`v(6!4_rdT9jBt*{ajOcv%iI$j- ziW}`<;A`Xz<@%L#3JsUa0QMx7wWt`!)*^?8>7iA&e%kN@_bbErJb8|Q*k`x-yw)70 zEZYi6AV^YA%6pSyRl_zB2Bu54$V8VU-opKRkk7r6)=fN{{W7a;Aqg9)F#59&Bp#~Q ze3r;DbGMNudOj_@BQgx_M_W$j&$GoHK3C)*XY^*~p2IDko2w?TU?K*OKAhOKGyikdkFNQ~LUL9xo^L!${m^Cs>)qKjD`_y?Xl}QF z5JSGCeOyN&q`|NGPu)UPiG*S6d5f}UN_6w5w;&S(MA1>^Rcoe@0uNn0LY-L%h{HE2 z%(1W$_8pb+>!ZfmUE3lwH<*(wdr=2!d=~`IH0@~>8_w_jqGh<;>XT?aAVpyzN^oVP zj~!%$wSE?g?6y<|CdBi9E`__H7BY??oKplhF5zK1FVo9{2sA)~mm8|OT0b9G&Vv>? zdMM7HPh`8xc5O$O-mjD3RIkY=2W>T7^b3#aN#k5L{!&9HfG1=@4P}25$7v~RE;l!QvT5Gv3&Q6Zn`uqlBbGFFedw(6R5>FpD1u(KZXsQ4PG zlorvMvK7NBPXQ&89wwNm^cG9bdDnQIpVA8-1$ zH<{qI{q-#|WZoK7i!I}Lk$(SCU7+;=Z@8R-!O63T=<*iBR|NGBMDO`<>IIgzGUwb5 zrn!@Y9)Dc)kNu)q1?CXZ1r`78T-k5Tc0CIJ--?DlIB3-b%8q@YJH>s?({ z<%f4Mz;zPCf(b9NTunuN6L771D8m_-&o^fsHruBQOFm|o+8j%Kq+$3mA@nB$NH8&) zLD@<*JB=-l#4g*z~=X-Jp>6+h5?{D=eKJ-(FTb1?kb_`R60)Tjz1cRfW5sj!h5rj^o(j zJARbbv^T$WqIY25-hb`lfD_RrbT3kX5UA7DDD;bI%A#6l+ar6Je_=G3Z0H%BjgQ(Z zHMmF(U!ub_ezaA5%J#W$ty29*2KlS%JK6(gM>)%Rl;!1kIv-S;A&zHHEHJKpz5A#5 zd@-r1K4Vt0e@Piw&2#@=JUxJ6xVW0xBqWYC;KPgPrJ~6rwAxnYR{wR+z>e-!->DBw z*hRK_#$}^zY1X7txXAd@7TIv6uSq!l3c}DNxa|)Mq$Ijb!Zm4IYpgv|uxf6Z7y7cv z(vuZvLL;|w{-ax=vwyDd-4(VrX&y~?0ZU}jH{{JSLRUOgrGZElDI$yspuv>P$h{%L z5|w)&mP~E+9IrlMXyjMK=gUTe5m(F$8n_Zu!c(5umem9dip%3KGi>!cAsDC_)?xw+ zn(6$EXQq4kYZDMh8cw>1uNAFnBk59R>dD1Y3c3|+qXQQ3NZdz7Ic7E(OKDFm=UKGy zX6mtQS~OR9YhKmUSX8fI)$iLoJxEd|p28Vci3vLfPSnG*Dqp7L)4UHWI5#S)w2!3X z)ruJ)pbHdoP#pR)gQI<9VNgi1DExiLMm4Vv3c2~?rXkn=)7V)?MfJ9897I4s7!d*K z25AZD_#+`9p>*faUD88$Nq2X54B$v3-5nxI4Fd=aL(ds~-?PrU);S-}{x*B<^*np_ z6Zd`nu6ylG905{@JNE?fv)}vFI2>N)yZ9uj7wk@-D6A(AlJ?`*bx%2PFsUa8S8B}E zg2=2M3+D;g@OUe+FJG!>yVjP+AvjYnep)ts?{zjJcSL)c$Varxt&Qc$egAQ$RS=vN zz_(y%nq%=NQt}eKjSU*_=2&h`POn}|8Sz`VU1@`obb7}qD0;n6r#o70%eUQg5SyG! zNrBYLX;Z3P*Uva#KHu=#cN7~^S{wEIOx~&x^KI;&f&k_pa^nb~wqnYjgYU;w9S~$| zVSKjec)(WVgYPT*}?%})PnUPgQmh6`1)v+g-ZPN#(2 zx_R}m&bxKo36X-u?_u8CxYTpkN-sz|m1kv}TK_6UhVcfKo2y4J9#j2*%kiF3S$pE8 z-y51vX4X=^vT7UQfmF-E&*b(Ckv{2$8X0b(D&p<<G>yE;*ZbT)qelH637x6J(RpqN_t!wgYZtYGzz2DS zs!0&IpF2sT!QbOcg#!iyM`zfWBVpKscdAAuuMuHd&ioS*xa1Qm_m|?dK56<-mb^__ z$4`^XWi(dqrKumwPDGoq%Wn087jVqC>6rA4Utx(!&bHbPaG{b=Qpn4Jpp zu5X1i0fSEa9q?&e0(n7!u_ZFnpm6kAi4uqmYveQC8J_kHl^%`awP@JJEDhr$^TJo& z8K8WK;ZsY#iPWBXcL6x8v4~{u%t7+(sxJr zV_S6Q>^all#V#)=?n;sUpPK*L;opr$$?&p$4#}P3Fyvnpe0R5BV8PD-lN6JP@j0K~ z@Jbsxu8;_YYmZpXSpKC2oFl!HXpTEIlJ7r&spI5ASNEg#pc03SBa8w?; zIta%x%ubyL_zoBwQ-irv%xCSUvoF>6y2T$&eX#ei0z#6luvYWG_(Ufk&y$2qZ^#21 zaeDsrFXgl<4crN==l92byaah4JqmS}yY5}@GIR=;HokYqTobBrpUh*z$>uV@7GfRjjknZyY_(wi)^#uD!?J z$on35{$o?tzG-{6nIBP^05;U}J3GE!+ZckVz_(lK@YEsUUugw;7`ATtH#t!Qg(kd= z(>Hg?-X_)VUocE$|Lb9wvF(p`eJ1Zcw6`_!+|T*Tr`H+FRN_7_}-Oh z6tRFE@OpOc($3S-rq`N(bLE}BIA?eBHKv3?M_>sdtI?ml5#w*Ji-{VA%^{*@0T*Cv zSk^sq+;1a;&}&lKB2{okBk_hcoc+#CY;NpLReSBgd_$ydI>ol*FZsSM3wtl~P}B?7 zcWOaP0y#sRkNXT2%kE_tQ)Fj&l4EJbmqD6Cg^iZ>J&%SbW#3=%Q&*1_8RV4EdaRfK zZhUpK zFxcaD_Fn5z_^m{KSPJf0K#tnYce_3_^2+kQ^hzp^@878zJ`{x3D{vQeZ&rFrgyg|; zqaa4gGxNGNwbo^3F#5DKqpw6_b~Lo*ym)1TJ>yf+yffAxb?ka5mwREiM4aVWJRF(Q zMQt&1P=HS775;-K0!q2@d2rk%TGThkBZU-Lbyi}+CQ(>7&RWe9)EvH4!KEkfEi%DN8{Xt5hP_%O=3oJ-aSOY!C5zOMs+WA-)7x^0*r&%? zbg}hMFWA5o)vWMe#2s1Q!w=66y=#^E6Xnn5T@Kl%^c1T>2j_S_l{t7D)ZGqE%*`o7 zi7@ZPXe!Q}A9Nqf#HW$NE`Vfs4?Ql-QUJ0T86gkjn}&Ved>vCi9J+F8wGT+DxZKCl9STwgc=b- z_YvO$KRGAL5c)e+JfIRRf}bWVXdcYWCZ(l-r8t7=L7sz$&mXkyZP7{XEuX&RSu>Do zzTT1N^rFaKc_K_gsf<~&f#DoKdY9cbQal7+Q zm61#cYxZ6+HlC5#QpZIh#>SRaQl@K6wV=dr=4nGvhC{?&(?t;bo!^n)?t3J|aNEzu z_Im|e1IN&gc!w2G^KMj+;@;df`jw6i3Z)ojWichaI2CODb)mQ*4NRZApo64)BVq zt}+utP37}b?d6+V{19|dILAIA975>qBt%2koJ3eMW^=B1ZHX0LYC`(6{X9NF%1gN$uH=mzmJnKc142H``w~o)OqEP>) zpWNDay>p(id$Fo+2C1?$$hjc);x`Z$&wiWry1666ETINMa*E-BMk$bor}NH^d`NDW zffM~fM#P90bNbKOlk>aAv5VIG=)EO<1p&z^H%!ToP#B~`@jx9#>l2+D{YBRVIU$*$^fhavd9_{aEu zf4t#EuS0^|m>Q)JGW`<;+*xKh*GQ?KUzFDx)4j|lK+WTx8|iH(6FftE5tkmcipEt1 zrlaRV>y8F(26aCrhZAhy;(!0=_geFSgGiY3f|*J{L@VAylwdLvKfNP5oz?-u^q}3u{`R4H3X9%64Z_+>Z8RMhU*BdNlW^{Aa7-PA)nQ^`Tv< zRmu%^$~-6h-YiVvP(b1S_K(atA^h{qWUqYisQPHynVkhqPiWUd-|T2lx873Fr;p=* z_%YyR$m)4S$RX^1#Q6}GglpeZ5)LvYx8dOnS^NCLlOJRpj6D9h(NjmT@87aiLXlmi zyW|6^41?dl_bV;UgME^R1PPqIJS4Uh;daACvrhP_jTF`%pJrP=v8o3MhI-N+ig?6j z(TMkFf$PoOItlBr0^}>fJ^{%?OKlBTr#fvSj&uW@l$zcR)sYh?EmwIf-HjOxJnUYr zt*KS-BrGO~xLs;Et$j^owkYBusEq9~T~utfRz@6_DgP4g5*5(>4}uM*jB$QK=i^{$ z`t{X#n_4G0bi)2ASl|!t!!Dy3?^|3$F*o(Fx&}petgU<$VmyAfBFaIJje>x}Tt-to zPeN9heZrpog_7$2Ai(&XQoXaz+2fx$F~!;)FeZA8zvvhv4<6N!?$=|CrI|p+v=?^L zWR(4y!hLjWeNR>)oNJs9)dZ(VwEzwk>h8*L|0(d*($RCeHgx-gnS)1R^>~_|A-c<` zo{9`Lhy#SxnCU{7w6L0$FGM)#BUb2_Topn;0s}3NM^pl)o;E>>SRNh25cw*y++gLR zsyQmgu_f7WAc*AmP1;J$+@CQ?#`e$Uo&`?-IwER~*Qeu3U{vZdJ4e&)_PqT=J=uTZ zCN0nm=JO7eRcXm?)nR=|;?sZDR(Ivrei$d(6c5XPl7DiL7L$|Oj5)N?x9fUqSUyiW zqsxTr@xU7u=;O>@G#;Jscx3(0nO6ZsJSSK)w%_n(dx}CHZl1kO-{fC7{?hjLahoZj zhrd$gngl4`gs;?ryo@_6kw*>i5CA22hSZC-deE)XYig4*^=;Y`3Znzzqr|fQEg;^1 zFfe4}KGug^OIM6ztm?KN-;S;R=?Uwzd1sN)EfBsU1-nMOyWpeUSZnKHS9xcjzhD)5 zK~#7X&Xx_LfF=7fUWlS1MCik#!xZGLTlL zYJ1XecgDgyTaO;rYVRxzGcu8?alZ#tyPdx0-*UPAH;7F8I$W)d^zhI{s$PQ|3r?MGbP(%5+zXy9-3KHep+Z@ zXVe(X|BGgBQMqNf@sIz-AfGn-o0Py_j4xkB#ZsMWdz3A9h71y!`{^?tE3C=$!Q9>9 zave(vySSTf96J^Iv;!WSD&7&8cJZO&%|s#)2?HuvfK?S*%lnMfq35dyr+N5zt*$#g zKD%tA_SMc#w@E)(R4IQw)LWR)=5_q;U%8Tae)&>nxK6_4c_lP&ILBbDuz2n@sig8@ zM-cF+%L^-}InOX==eB)eJ$Y!zl4XL5raFLFWmj^>byS~QlX={v_qp^7Z)8-0-jP(> zU+~#KZ6nk-0=v$Lw`2)Vu^D)myOewT@fFsUL&dE)mq-@Qe6zOp1eLqrd>`wHKm%GQ zt%xzsP<;dQwJWZTV)0B0U1%FzdSAdhHbPqBIQWQYNdA$m1V`R&D zfUjNpv>ITxa?^EUTl%)Cjh5B5k*m?I-?Y?V3cGnke5zoy@;-cp^2{MwUF#s5f@|(r ze?fOxolkn-=G6_=$F72XZmgDWlI!fXTCsV?*`)94?TfVi#nEr|GGs-r9-&r& zAU!iFL3)Nn#U{iId&9A4e967dtuU1YEk3)#IY`R$I_HLWS{#QuuC^+Bw&^VOM6Q29 zhLX$!!=m=h(T56@CW;EWgBD>?-OUnIJ8k6PM@9pifls`3D0_l42fC!uVOsP zHSdhd+q2hlxCDiH#{Y|(PHi;ICGrg|Ql!*JdfpP6y#5Wt--HDwXCylgsQu=m;oqP< znk2M*3Z7p$5<5^Ebv}#W$PM5YAKL;g7l^Af(OUBES_bB;xNjVF(<&cX?X z49T$J80RkBOu}YNu7ChK0RCpYIkwxyV-U-|%c;hbHRNmOBKwRRs%uZ5r~fzNMJTV< zY*|{KVQt!X;`qgn-~Y;pfIj|o!<8s6N0$$yzRSmis~yc512xx{D#UN>N61#Eo;J>9 zq~|KS{n9Pvp-FMngK-|(&%Yc}jSi_6+_%5uu2B~}|8a)h>E0G^IjfWCmrI0QtEMx6 zaLxbmO@nH+E@oa!z+66a2t$gFyA_8_EZJ$mMz~*g4@JLwxHUNus?pM<^k><@H%a&z zba?+apapW@{STn6?_QUTVige`Mx2;9jV*aG?-W+B1!<*^ChM}ZzLJcaK)ug42+;^& zG8#;Tz2G#@w+d}MK@Qfy7+V&Anf zpTT8Yhx{o1A*fA{275{$Mv1j7hp)lQA$H;J`D|gu5_Ug8=6=ZG*Rqap9Q_>T_2cQ| z!PL1-2f{(n%BV}{t&)W9rTnUJC&{BLF-2nKVTeNOQZwD@Q z$zGH;nk@SB=U!o!)|f&Oi%D<`Hj!Fwf#Ehp4Q=D7TS6+sErz zk05L-8W-SSiP$Bb>{ZIv=TySB|O(;Ut=+Hg7$~AV|MwQBeh1 zkTV6R&K6R2p;Ap#v5($_Wmw^T)agUuA90N7j(e$DcCWYbEb123U9QsSg`5!Y0%z+_ zB=2gukV}*|;!zY$S3hVmbXCn+Gf{ONrO}S}V?yTg_qBAZI7KaxG@SEv_K+{>0hPM6b8!@*N zd&s&|V&)6m7zJ7*fA-H;V(x-kr>iccC_r2cFqZfMw|q^tRRYV%gqNZMm{aLLaT1yZ z)L<<&?3@2U^ZP}T^ag4cm5Gd}88(ITD*5$cys#x5ULJ_$7ofH zB-aT0JOaIf%EjZySGPZw*uVwr=BFI6CZ{hopV^u)V$*v|F`hRAM{wjRQBJ|_qebN{ z`mSHB@pq>#ElCAKt}yHS(iwzu(pW?tyzweO_C(c386wrq#4!+Xyc)?|WjqF&ev zX$XhlBZUO}1kMZhKfQvzwZHICyvO!Ay3B1LHPcki7Q3m`KUu~f_;tEBlvup+%oQD3sLpE&P1p- zgI^(|hGs)ncqr-airkePmH#vojQ!FltXtsa^5Dcq6^$$5?z|y4yMSK3F3rfQ9SRz| zIn?4liB0tMqYU2-q5QH`BGZVo>?=;T^U1RThtFomd^#2szgpt%iu!atQLKHfce-CR zv0>cQ_tO;8iWOUnqyPf;Sega_@5-Wf9J#i|Bl8CvqMMiaJU6v>be)k|G~6swzNolT zSD?!V3hpbtNxzTLwIAsjtaFH{Jc&1-S!B@JMUuwA5k*l7rQZSH>}yw4(mpM!ie{n~ zmdSXWt>!z?bJok711(l_IwugzKw8v@Fn+H}&}F-bFN2jhSDXj7F|1uWHt!eBWNG(q z7f04JqA=^Zk(=Ly0xeFOqc6{y+B&s=Ujk@YOd~l%1x$q{>%3Ee4%bz==QjG6RknMt zjKLpgs?W(^W46g=#YTT5WZM;O>`JHqzX6IWO9x`T}0uD*W zNQKovA!yW@KnY>#;P;>?!BJ5I#XYvKxEU#YN}ub$NZAi_u=Ao_xUgF~mP)@WwYv;ht5@ z)C{PBh(}q<2(PXqkgFIBou5Zt*H464Y2uSEzo|h%eLMX2CiiCcluY{V;$?ui-LWjB zDhxd;_dE=~GH_oT6OGzoa55BR$PsmCoa+iWmnoUT#kU3-;>VM&{7lM~ZBiuF9~0+mF}T;iGWb*Zs*0aK7K zdyKnz;5Wk6JqfNnVSKl8KG|wu@NeCC`$M4lDuy*bAX!^93@F@;fi<|wI+s~JXF3k( zsp1p6CulT`Y*VqZYBHmpTo|cb%Ar<8Zp&SN6a=OqfH$1w}ezsm*YG8Nb@-vP*j#n+M zKe>bKG)QZ=Wh}`=v8gCg{`^dId1FfH5Z}*x&re8;G?eoY`p+et5hS}_hVq-+PM^w- z{rYE*JE?BV?MMG$O$H5DVi>9x5$?t1X1@pN2Q2-|+4x2~@{sql9;2K%dDp1yIBrjV zh0RiN3OQ!cNAH<;l|JP;{VYnxHGRL|#xR0;m+(@eBc$m~FO6U->K=kd9PIz)e*CG% s(V%CM{kK(ua#AW}2t5CvzkVVy$gBh!MR}f#p`i{1SrwVOw lf t55xx wipe ``` +Set a T5577 tag downlink mode to fixed bit (default) +``` +pm3 --> lf t55xx write b 3 1 d 00000000 +``` + +Set a T5577 tag downlink mode to long leading zero +``` +pm3 --> lf t55xx write b 3 1 d 90000400 +``` + +Set a T5577 tag downlink mode to leading zero +``` +pm3 --> lf t55xx write b 3 1 d 90000800 +``` + +Set a T5577 tag downlink mode to 1 of 4 +``` +pm3 --> lf t55xx write b 3 1 d 90000C00 +``` + ## Data ^[Top](#top) From b1e4e5e0cc3c55eeee9ef7e4689b0f39304d1d7e Mon Sep 17 00:00:00 2001 From: mwalker33 Date: Fri, 4 Oct 2019 22:12:25 +1000 Subject: [PATCH 0834/1854] Update T5577_Guide.md --- doc/T5577/T5577_Guide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/T5577/T5577_Guide.md b/doc/T5577/T5577_Guide.md index 5cf27bf02..6c39d6898 100644 --- a/doc/T5577/T5577_Guide.md +++ b/doc/T5577/T5577_Guide.md @@ -1,6 +1,6 @@ # T5577 Introduction Guide -### Ver.1 8 Jul 2019 +### Ver.1 8 Sep 2019 | Contents | | ----------------------------------------------------------------------------------- | From b8776b593ebcfdd9848973edf936b275e19e7ad5 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 4 Oct 2019 14:21:04 +0200 Subject: [PATCH 0835/1854] fix: sneaky bug in magic detection where bigbuf wasnt emptied before next run --- armsrc/mifarecmd.c | 37 ++++++++++++++++++++++--------------- client/mifare/mifarehost.c | 9 ++++----- 2 files changed, 26 insertions(+), 20 deletions(-) diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index d3f00c2ec..3cc36b28c 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -925,31 +925,37 @@ void MifareNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8 // prepare next select. No need to power down the card. if (mifare_classic_halt(pcs, cuid)) { - if (DBGLEVEL >= 2) Dbprintf("Nested: Halt error"); + if (DBGLEVEL >= DBG_INFO) Dbprintf("Nested: Halt error"); rtr--; continue; } if (!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) { - if (DBGLEVEL >= 2) Dbprintf("Nested: Can't select card"); + if (DBGLEVEL >= DBG_INFO) Dbprintf("Nested: Can't select card"); rtr--; continue; }; auth1_time = 0; if (mifare_classic_authex(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST, &nt1, &auth1_time)) { - if (DBGLEVEL >= 2) Dbprintf("Nested: Auth1 error"); + if (DBGLEVEL >= DBG_INFO) Dbprintf("Nested: Auth1 error"); rtr--; continue; }; auth2_time = (delta_time) ? auth1_time + delta_time : 0; if (mifare_classic_authex(pcs, cuid, blockNo, keyType, ui64Key, AUTH_NESTED, &nt2, &auth2_time)) { - if (DBGLEVEL >= 2) Dbprintf("Nested: Auth2 error"); + if (DBGLEVEL >= DBG_INFO) Dbprintf("Nested: Auth2 error"); rtr--; continue; }; + // cards with fixed nonce + if (nt1 == nt2) { + Dbprintf("Nested: %08x vs %08x", nt1, nt2); + break; + } + uint32_t nttmp = prng_successor(nt1, 100); //NXP Mifare is typical around 840,but for some unlicensed/compatible mifare card this can be 160 for (i = 101; i < 1200; i++) { nttmp = prng_successor(nttmp, 1); @@ -964,7 +970,7 @@ void MifareNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8 } else { delta_time = auth2_time - auth1_time + 32; // allow some slack for proper timing } - if (DBGLEVEL >= 3) Dbprintf("Nested: calibrating... ntdist=%d", i); + if (DBGLEVEL >= DBG_DEBUG) Dbprintf("Nested: calibrating... ntdist=%d", i); } else { unsuccessful_tries++; if (unsuccessful_tries > NESTED_MAX_TRIES) { // card isn't vulnerable to nested attack (random numbers are not predictable) @@ -975,7 +981,7 @@ void MifareNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8 davg = (davg + (rtr - 1) / 2) / (rtr - 1); - if (DBGLEVEL >= 3) Dbprintf("rtr=%d isOK=%d min=%d max=%d avg=%d, delta_time=%d", rtr, isOK, dmin, dmax, davg, delta_time); + if (DBGLEVEL >= DBG_DEBUG) Dbprintf("rtr=%d isOK=%d min=%d max=%d avg=%d, delta_time=%d", rtr, isOK, dmin, dmax, davg, delta_time); dmin = davg - 2; dmax = davg + 2; @@ -994,18 +1000,18 @@ void MifareNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8 // prepare next select. No need to power down the card. if (mifare_classic_halt(pcs, cuid)) { - if (DBGLEVEL >= 2) Dbprintf("Nested: Halt error"); + if (DBGLEVEL >= DBG_INFO) Dbprintf("Nested: Halt error"); continue; } if (!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) { - if (DBGLEVEL >= 2) Dbprintf("Nested: Can't select card"); + if (DBGLEVEL >= DBG_INFO) Dbprintf("Nested: Can't select card"); continue; }; auth1_time = 0; if (mifare_classic_authex(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST, &nt1, &auth1_time)) { - if (DBGLEVEL >= 2) Dbprintf("Nested: Auth1 error"); + if (DBGLEVEL >= DBG_INFO) Dbprintf("Nested: Auth1 error"); continue; }; @@ -1014,12 +1020,12 @@ void MifareNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8 len = mifare_sendcmd_short(pcs, AUTH_NESTED, 0x60 + (targetKeyType & 0x01), targetBlockNo, receivedAnswer, par, &auth2_time); if (len != 4) { - if (DBGLEVEL >= 2) Dbprintf("Nested: Auth2 error len=%d", len); + if (DBGLEVEL >= DBG_INFO) Dbprintf("Nested: Auth2 error len=%d", len); continue; }; nt2 = bytes_to_num(receivedAnswer, 4); - if (DBGLEVEL >= 3) Dbprintf("Nonce#%d: Testing nt1=%08x nt2enc=%08x nt2par=%02x", i + 1, nt1, nt2, par[0]); + if (DBGLEVEL >= DBG_DEBUG) Dbprintf("Nonce#%d: Testing nt1=%08x nt2enc=%08x nt2par=%02x", i + 1, nt1, nt2, par[0]); // Parity validity check for (j = 0; j < 4; j++) { @@ -1034,7 +1040,7 @@ void MifareNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8 if (valid_nonce(nttest, nt2, ks1, par_array)) { if (ncount > 0) { // we are only interested in disambiguous nonces, try again - if (DBGLEVEL >= 3) Dbprintf("Nonce#%d: dismissed (ambiguous), ntdist=%d", i + 1, j); + if (DBGLEVEL >= DBG_DEBUG) Dbprintf("Nonce#%d: dismissed (ambiguous), ntdist=%d", i + 1, j); target_nt[i] = 0; break; } @@ -1043,10 +1049,10 @@ void MifareNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8 ncount++; if (i == 1 && target_nt[1] == target_nt[0]) { // we need two different nonces target_nt[i] = 0; - if (DBGLEVEL >= 3) Dbprintf("Nonce#2: dismissed (= nonce#1), ntdist=%d", j); + if (DBGLEVEL >= DBG_DEBUG) Dbprintf("Nonce#2: dismissed (= nonce#1), ntdist=%d", j); break; } - if (DBGLEVEL >= 3) Dbprintf("Nonce#%d: valid, ntdist=%d", i + 1, j); + if (DBGLEVEL >= DBG_DEBUG) Dbprintf("Nonce#%d: valid, ntdist=%d", i + 1, j); } } if (target_nt[i] == 0 && j == dmax + 1 && DBGLEVEL >= 3) Dbprintf("Nonce#%d: dismissed (all invalid)", i + 1); @@ -2013,7 +2019,7 @@ void MifareCIdent() { // reset card FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelay(100); + SpinDelay(40); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); int res = iso14443a_select_card(uid, NULL, &cuid, true, 0, true); @@ -2041,6 +2047,7 @@ OUT: // turns off OnSuccessMagic(); BigBuf_free(); + BigBuf_Clear_ext(false); } void OnSuccessMagic() { diff --git a/client/mifare/mifarehost.c b/client/mifare/mifarehost.c index ba775d992..42fef7405 100644 --- a/client/mifare/mifarehost.c +++ b/client/mifare/mifarehost.c @@ -1099,19 +1099,18 @@ void detect_classic_magic(void) { switch (isGeneration) { case MAGIC_GEN_1A: - PrintAndLogEx(SUCCESS, "Answers to magic commands (GEN 1a): " _GREEN_("YES")); + PrintAndLogEx(SUCCESS, "Magic capabilities : " _GREEN_("Gen 1a")); break; case MAGIC_GEN_1B: - PrintAndLogEx(SUCCESS, "Answers to magic commands (GEN 1b): " _GREEN_("YES")); + PrintAndLogEx(SUCCESS, "Magic capabilities : " _GREEN_("Gen 1b")); break; case MAGIC_GEN_2: - PrintAndLogEx(SUCCESS, "Answers to magic commands (GEN 2 / CUID): " _GREEN_("YES")); + PrintAndLogEx(SUCCESS, "Magic capabilities : " _GREEN_("Gen 2 / CUID")); break; case MAGIC_GEN_UNFUSED: - PrintAndLogEx(SUCCESS, "Answers to magic commands (Write Once / FUID): " _GREEN_("YES")); + PrintAndLogEx(SUCCESS, "Magic capabilities : " _GREEN_("Write Once / FUID")); break; default: - PrintAndLogEx(INFO, "Answers to magic commands: " _YELLOW_("NO")); break; } } From 8c9ff2e54a97f72e6d24d2c9d6ce2938c56997e8 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 4 Oct 2019 21:28:34 +0200 Subject: [PATCH 0836/1854] t5555 textual --- client/cmdlft55xx.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 922602f9b..53c522f32 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -83,7 +83,7 @@ static int usage_t55xx_config() { PrintAndLogEx(NORMAL, " d - Set demodulation FSK / ASK / PSK / NRZ / Biphase / Biphase A"); PrintAndLogEx(NORMAL, " i [0/1] - Set/reset data signal inversion"); PrintAndLogEx(NORMAL, " o [offset] - Set offset, where data should start decode in bitstream"); - PrintAndLogEx(NORMAL, " Q5 [0/1] - Set/reset as Q5(T5555) chip instead of T55x7"); + PrintAndLogEx(NORMAL, " Q5 [0/1] - Set/reset as T5555 ( Q5 ) chip instead of T55x7"); PrintAndLogEx(NORMAL, " ST [0/1] - Set/reset Sequence Terminator on"); PrintAndLogEx(NORMAL, ""); // layout is a little differnet, so seperate until a better fix print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE); @@ -292,11 +292,11 @@ static int usage_t55xx_wipe() { PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h - this help"); PrintAndLogEx(NORMAL, " c - set configuration from a block0"); - PrintAndLogEx(NORMAL, " q - indicates to use the T5555 (Q5) default configuration block"); + PrintAndLogEx(NORMAL, " q - indicates to use T5555 ( Q5 ) default configuration block"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " lf t55xx wipe - wipes a t55x7 tag, config block 0x000880E0"); - PrintAndLogEx(NORMAL, " lf t55xx wipe q - wipes a t5555 Q5 tag, config block 0x6001F004"); + PrintAndLogEx(NORMAL, " lf t55xx wipe - wipes a T55x7 tag, config block 0x000880E0"); + PrintAndLogEx(NORMAL, " lf t55xx wipe q - wipes a T5555 ( Q5 ) tag, config block 0x6001F004"); return PM3_SUCCESS; } static int usage_t55xx_deviceconfig() { @@ -1473,7 +1473,7 @@ int special(const char *Cmd) { } int printConfiguration(t55xx_conf_block_t b) { - PrintAndLogEx(NORMAL, " Chip Type : %s", (b.Q5) ? "T5555(Q5)" : "T55x7"); + PrintAndLogEx(NORMAL, " Chip Type : %s", (b.Q5) ? "T5555 ( Q5 )" : "T55x7"); PrintAndLogEx(NORMAL, " Modulation : %s", GetSelectedModulationStr(b.modulation)); PrintAndLogEx(NORMAL, " Bit Rate : %s", GetBitRateStr(b.bitrate, (b.block0 & T55x7_X_MODE && (b.block0 >> 28 == 6 || b.block0 >> 28 == 9)))); PrintAndLogEx(NORMAL, " Inverted : %s", (b.inverted) ? _GREEN_("Yes") : "No"); @@ -1682,7 +1682,7 @@ static int CmdT55xxReadTrace(const char *Cmd) { si += 9; if (hdr != 0x1FF) { - PrintAndLogEx(FAILED, "Invalid Q5 Trace data header (expected 0x1FF, found %X)", hdr); + PrintAndLogEx(FAILED, "Invalid T555 ( Q5 ) Trace data header (expected 0x1FF, found %X)", hdr); return PM3_ESOFT; } @@ -1809,7 +1809,7 @@ void printT55x7Trace(t55x7_tracedata_t data, uint8_t repeat) { } void printT5555Trace(t5555_tracedata_t data, uint8_t repeat) { - PrintAndLogEx(NORMAL, "-- T5555 (Q5) Trace Information -----------------------------"); + PrintAndLogEx(NORMAL, "-- T5555 ( Q5 ) Trace Information ---------------------------"); PrintAndLogEx(NORMAL, "-------------------------------------------------------------"); PrintAndLogEx(NORMAL, " ICR IC Revision : %d", data.icr); PrintAndLogEx(NORMAL, " Lot : %c%d", data.lotidc, data.lotid); @@ -2388,7 +2388,7 @@ static void t55x7_create_config_block(int tagtype) { snprintf(retStr, sizeof(buf), "%08X - T55X7 Raw", T55X7_RAW_CONFIG_BLOCK); break; case 2: - snprintf(retStr, sizeof(buf), "%08X - T5555 Q5 Default", T5555_DEFAULT_CONFIG_BLOCK); + snprintf(retStr, sizeof(buf), "%08X - T5555 ( Q5 ) Default", T5555_DEFAULT_CONFIG_BLOCK); break; default: break; @@ -2491,7 +2491,7 @@ static int CmdT55xxWipe(const char *Cmd) { if (errors) return usage_t55xx_wipe(); - PrintAndLogEx(INFO, "\nBegin wiping %s", (Q5) ? "Q5 / T5555 tag" : "T55x7 tag"); + PrintAndLogEx(INFO, "\nBegin wiping %s", (Q5) ? "T5555 ( Q5 ) tag" : "T55x7 tag"); // default config blocks. if (gotconf == false) { From 098e0a183f4fdad7e50d05714bfb8f645d9d1832 Mon Sep 17 00:00:00 2001 From: mwalker33 Date: Sat, 5 Oct 2019 14:09:46 +1000 Subject: [PATCH 0837/1854] client win10 color support --- client/proxmark3.c | 28 ++ doc/T5577/T5577_Guide.md | 677 ------------------------------------- doc/T5577/media/image1.png | Bin 44034 -> 0 bytes doc/T5577/media/image2.png | Bin 26953 -> 0 bytes doc/T5577/media/image3.png | Bin 62447 -> 0 bytes doc/cheatsheet.md | 20 -- 6 files changed, 28 insertions(+), 697 deletions(-) delete mode 100644 doc/T5577/T5577_Guide.md delete mode 100644 doc/T5577/media/image1.png delete mode 100644 doc/T5577/media/image2.png delete mode 100644 doc/T5577/media/image3.png diff --git a/client/proxmark3.c b/client/proxmark3.c index f28e14063..6b252157f 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -682,6 +682,34 @@ int main(int argc, char *argv[]) { } session.supports_colors = false; + +#if defined(_WIN32) + // Check if windows AnsiColor Support is enabled in the registery + // [HKEY_CURRENT_USER\Console] + // "VirtualTerminalLevel"=dword:00000001 + + HKEY hKey = NULL; + + if(RegOpenKeyA (HKEY_CURRENT_USER,"Console",&hKey) == ERROR_SUCCESS) { + DWORD dwType = REG_SZ; + BYTE KeyValue[sizeof(dwType)]; + DWORD len = sizeof(KeyValue); + + if (RegQueryValueEx(hKey,"VirtualTerminalLevel", NULL, &dwType,KeyValue, &len) != ERROR_FILE_NOT_FOUND) { + uint8_t i; + uint32_t Data = 0; + for (i = 0; i < 4; i++) + Data += KeyValue[i] << (8 * i); + + if (Data == 1) { // Reg key is set to 1, Ansi Color Enabled + session.supports_colors = true; + } + } + RegCloseKey(hKey); + } + +#endif + session.stdinOnTTY = isatty(STDIN_FILENO); session.stdoutOnTTY = isatty(STDOUT_FILENO); #if defined(__linux__) || (__APPLE__) diff --git a/doc/T5577/T5577_Guide.md b/doc/T5577/T5577_Guide.md deleted file mode 100644 index 6c39d6898..000000000 --- a/doc/T5577/T5577_Guide.md +++ /dev/null @@ -1,677 +0,0 @@ -# T5577 Introduction Guide - -### Ver.1 8 Sep 2019 - -| Contents | -| ----------------------------------------------------------------------------------- | -| [Part 1](#part-1) | -| [Introduction](#introduction) | -| [T5577 Overview](#t5577-overview) | -| [What data is on my T5577](#what-data-is-on-my-t5577) | -| [Read and Write Blocks of Data](#read-and-write-blocks-of-data) | -| [Exercise 1](#exercise-1) | -| [How do I use a password](#how-do-i-use-a-password) | -| | -| [Part 2 – Configuration Blocks](#part-2-configuration-blocks) | -| [The configuration Block – Block 0 Page 0](#the-configuration-block-block-0-page-0) | -| [Exercise 2](#exercise-2) | -| [The configuration Block – Block 3 Page 1](#the-configuration-block-block-3-page-1) | - -# Part 1 - -## Introduction - -The T5577 is a generic LF (Low Frequency) RFID card the is used in the -125 Khz frequency. It is a good card to use to learn about RFID and -learn how to use the proxmark3. - -It is highly recommend that when learning about RFID that learning how -to read the data sheets be near the top of the list. It can be very hard -as the data sheet will hold the information you need, but you don’t yet -know what it means. As such, I will attempt to point to sections of the -data sheet and would highly advise that you look at the data sheet as -you go. Overtime the data sheet may change, as a result things may not -always be reference correctly. - -As at writing this guide, the data sheet can be found at : - - - -This guide is not a how do I clone document. It is meant to help people -learn how to use the T5577 and in the process learn about rfid and the -proxmark3. - -Throughout this guide I will give examples. It is recommended that you -try these as we go. To do so, have a blank T5577 card that you can use -for this purpose. - -## T5577 Overview - -The T5577 is a chip that can hold data and a configuration (Section -4.12). - -In the diagram below, all white blocks can hold data. Some can be used -for a second purpose, such as the ‘password’ and ‘traceability data’. -The ‘Configuration Data’ and ‘Analog front end option setup’ will tell -the chip how to behave. - -![](./media/image1.png) - - - -## What data is on my T5577 - -Let’s have a look and see what a card might look in the proxmark3 -software. Since we can change the configuration of how the T5577 will -output data, the proxmark3 software need to work out how to interpreted -the data it receives, we do this with the following command. - -It should be noted that the T5577 has many clones. As such the default -setup of each card may be different. If the tractability data is -present, then this will vary based on the batch of cards. - -Always run this command when you place a t5577 on the proxmark3. In all -examples shown, it will be assumed you have run the detect command. -``` -proxmark3 > lf t55xx detect -``` -You should see a results simular to the following: -``` -Chip Type : T55x7 -Modulation : ASK -Bit Rate : 2 - RF/32 -Inverted : No -Offset : 31 -Seq. Term. : No -Block0 : 0x00088040 -``` -Now that the proxmark3 has detected a T55x7 chip, and found some -information about it, we should be able to see all the data on the chip. -``` -proxmark3 > lf t55xx dump -``` -Your results should look similar to the following: -``` -Reading Page 0: - -blk | hex data | binary -----+----------+--------------------------------- - 0 | 00088040 | 00000000000010001000000001000000 - 1 | FFFFFFFF | 11111111111111111111111111111111 - 2 | FFFFFFFF | 11111111111111111111111111111111 - 3 | FFFFFFFF | 11111111111111111111111111111111 - 4 | FFFFFFFF | 11111111111111111111111111111111 - 5 | FFFFFFFF | 11111111111111111111111111111111 - 6 | FFFFFFFF | 11111111111111111111111111111111 - 7 | FFFFFFFF | 11111111111111111111111111111111 -Reading Page 1: -blk | hex data | binary -----+----------+--------------------------------- - 0 | 00088040 | 00000000000010001000000001000000 - 1 | E0150A48 | 11100000000101010000101001001000 - 2 | 2D782308 | 00101101011110000010001100001000 - 3 | FFFFFFFF | 11111111111111111111111111111111 -``` -I will cover the meaning of this data as we go, but for now, lets keep -it simple. - -## Read and Write Blocks of Data - -The basic function of using the proxmark3 with rfid cards is to read and -write data. This reading and writing must be done in the correct way -needed for the chip (and its configuration). Lucky for us, the -developers have done a great job and gave us commands. What we need to -know is that with the T5577 data is read/written one complete block at a -time. Each block holds 32 bits of data (hence the binary output shown) - -Since we know that the card has data and configuration blocks, lets say -away from those while we learn how to read and write. I suggest you -follow along and perform each command and check the results as we go. - -We can store our own data in blocks 1-7 (remember that block 7 will be -needed if we want to set a password). - -(Don’t forget to run the detect command: lf t55xx detect, and ensure you -can see the card) - -1) Check what is stored in block 1. The following command can be read - as, run a low frequency (lf) command for the T55xx chip (t55xx) and - read block (b) number 1. - ``` - proxmark3\> lf t55xx read b 1 - ``` - result: - ``` - Reading Page 0: - - blk | hex data | binary - ----+----------+--------------------------------- - 1 | FFFFFFFF | 11111111111111111111111111111111 - ``` - Note: Depending on the history of your card your data may vary, but - should match the dump data. - -2) Write some new data into block 1 on the card. - - We use the d option to supply the data ‘12345678’ - ``` - proxmark3\> lf t55xx write b 1 d 12345678 - ``` - result: - ``` - Writing page 0 block: 01 data: 0x12345678 - ``` -3) Now, lets check if the data was written. - ``` - proxmark3> lf t55xx read b 1 - ``` - result: - ``` - Reading Page 0: - blk | hex data | binary - ----+----------+--------------------------------- - 1 | 12345678 | 00010010001101000101011001111000 - ``` -4) The data is written in Hexadecimal. A single hex digit holds 4 bits - of data. So to store 32 bits in a block we need to supply 8 hex - digits (8 \* 4 = 32). If you are familiar with hex and binary do a - little bit of home work to learn. The following is a quick start. - - | Hex | Binary | Decimal | - |:---:|:------:|:-------:| - | 0 | 0000 | 0 | - | 1 | 0001 | 1 | - | 2 | 0010 | 2 | - | 3 | 0011 | 3 | - | 4 | 0100 | 4 | - | 5 | 0101 | 5 | - | 6 | 0110 | 6 | - | 7 | 0111 | 7 | - | 8 | 1000 | 8 | - | 9 | 1001 | 9 | - | A | 1010 | 10 | - | B | 1011 | 11 | - | C | 1100 | 12 | - | D | 1101 | 13 | - | E | 1110 | 14 | - | F | 1111 | 15 | - - To use all the bits we supply the data in Hex format and it will - always be 8 hex digits. - - Lets try and write 89ABCDEF - ``` - proxmark3> lf t55xx write b 1 d 89abcdef - ``` - result: - ``` - Writing page 0 block: 01 data: 0x89ABCDEF - ``` - and check - ``` - proxmark3> lf t55xx read b 1 - ``` - result: - ``` - Reading Page 0: - - blk | hex data | binary - ----+----------+--------------------------------- - 1 | 89ABCDEF | 10001001101010111100110111101111 - ``` - -### Exercise 1 - -Using the read and write commands you have learnt see if you can make -the lf t55 dump command show the following data for blocks 1-7 (Page 0). -Do not write to block 0 or try and change the data on page 1. -``` -proxmark3\> lf t55 dump -``` -result: -``` -Reading Page 0: - -blk | hex data | binary -----+----------+--------------------------------- - 0 | 00088040 | 00000000000010001000000001000000 - 1 | 11111111 | 00010001000100010001000100010001 - 2 | 22222222 | 00100010001000100010001000100010 - 3 | 33333333 | 00110011001100110011001100110011 - 4 | AAAAAAAA | 10101010101010101010101010101010 - 5 | BBBBBBBB | 10111011101110111011101110111011 - 6 | CCCCCCCC | 11001100110011001100110011001100 - 7 | 0123ABCD | 00000001001000111010101111001101 -Reading Page 1: -blk | hex data | binary -----+----------+--------------------------------- - 0 | 00088040 | 00000000000010001000000001000000 - 1 | E0150A48 | 11100000000101010000101001001000 - 2 | 2D782308 | 00101101011110000010001100001000 - 3 | FFFFFFFF | 11111111111111111111111111111111 -``` - -Practice reading and writing to blocks 1 to 7 until you are happy you -can do it and get the results you wanted (i.e. the data you want stored -is written to the block you want it stored in). - -## How do I use a password - -This can be a little tricky for beginners. -***If you forget your password you will lose access to your card***. - -To tell the T5577 to use a password we have to change the data in the -configuration block (0). To help learn this and make it as simple as I -can, please read and follow exactly. If your results DON’T match 100% as -required, please do not proceed. - -1) Lets start with a known card state and wipe the card. This will set - a default configuration to block 0 and set all the data in blocks - 1-7 to a default. - ``` - proxmark3> lf t55xx wipe - ``` - Result: - ``` - Beginning Wipe of a T55xx tag (assuming the tag is not password - protected) - Writing page 0 block: 00 data: 0x00088040 pwd: 0x00000000 - Writing page 0 block: 01 data: 0x00000000 - Writing page 0 block: 02 data: 0x00000000 - Writing page 0 block: 03 data: 0x00000000 - Writing page 0 block: 04 data: 0x00000000 - Writing page 0 block: 05 data: 0x00000000 - Writing page 0 block: 06 data: 0x00000000 - Writing page 0 block: 07 data: 0x00000000 - ``` - -2) Check that the card is in the desired state. - ``` - proxmark3> lf t55xx detect - ``` - result: - ``` - Chip Type : T55x7 - Modulation : ASK - Bit Rate : 2 - RF/32 - Inverted : No - Offset : 31 - Seq. Term. : No - Block0 : 0x00088040 - ``` - - If block 0 does not hold the hex data **0x00088040 resolve this - first before proceeding.** - -3) Set the password we want to use. For this example lets use the - password : ***12345678*** - - The password is saved in block 7 of page 0. - ``` - proxmark3> lf t55xx write b 7 d 12345678 - ``` - result: - ``` - Writing page 0 block: 07 data: 0x12345678 - ``` - -4) Lets verify both block 0 and block 7 - ``` - proxmark3> lf t55xx dump - ``` - result: - ``` - Reading Page 0: - blk | hex data | binary - ----+----------+--------------------------------- - 0 | 00088040 | 00000000000010001000000001000000 - 1 | FFFFFFFF | 11111111111111111111111111111111 - 2 | FFFFFFFF | 11111111111111111111111111111111 - 3 | FFFFFFFF | 11111111111111111111111111111111 - 4 | FFFFFFFF | 11111111111111111111111111111111 - 5 | FFFFFFFF | 11111111111111111111111111111111 - 6 | FFFFFFFF | 11111111111111111111111111111111 - 7 | 12345678 | 00010010001101000101011001111000 - Reading Page 1: - blk | hex data | binary - ----+----------+--------------------------------- - 0 | 00088040 | 00000000000010001000000001000000 - 1 | E0150A48 | 11100000000101010000101001001000 - 2 | 2D782308 | 00101101011110000010001100001000 - 3 | FFFFFFFF | 11111111111111111111111111111111 - ``` - ***Important : If block 0 and block 7 don’t match exactly, do not continue.*** - -5) Now we have a known configuration block and a known password of - 12345678, we are ready to tell the card to use the password. - - To do this the datasheet tells us we need to set the 28th - bit “PWD”. Check your datasheet and see the entire table (remember - the data sheet is your friend). - - ![](./media/image2.png) - - We will cover other things in the configuration later. But the key - note here is we ONLY want to change bit 28 and nothing else. - - Current Block 0 : ***00088040*** - New Block 0 : ***00088050*** - - To understand what happened to get from 00088040 to 00088050 we need - to look at the binary data. - - While this can be confusing it is important to understand this as we - do more advanced things. - - Bit Location (28) - 000000000011111111112222222 ***2*** 2233 - 123456789012345678901234567 ***8*** 9012 - - | Hex Data | Binary Data | - |:--------:|:---------------------------------------| - | 00088040 | 000000000000100010000000010***0***0000 | - | 00088050 | 000000000000100010000000010***1***0000 | - - - - See how in the above we change the bit in location 28 from a 0 to 1 - 0 = No Password, 1 = Use Password - - Note how we did NOT change any other part of the configuration, only bit 28. - - To re-cap. - We put the card into a known configuration Block 0 : 00088040 - We set the a known password Block 7 : 12345678 - We altered the config data to tell the T5577 to use the password. - New Block 0 : 00088050 - - If you have completed all steps and have the exact same results, we are - ready to apply the new configuration. - ``` - proxmark3> lf t55xx write b 0 d 00088050 - ``` - result: - ``` - Writing page 0 block: 00 data: 0x00088050 - ``` - -6) Lets check what happens when the password is set. - ``` - proxmark3> lf t55 detect - ``` - result: - ``` - Could not detect modulation automatically. Try setting it manually - with 'lf t55xx config' - ``` - Note how the lf t55 detect no longer seems to work\! - - In this case, this is due to needing a password to read/write to the - card. - - Lets try again, but this time supply the password. We use the option - p followed by the password. - ``` - proxmark3> lf t55 detect p 12345678 - ``` - result: - ``` - Chip Type : T55x7 - Modulation : ASK - Bit Rate : 2 - RF/32 - Inverted : No - Offset : 31 - Seq. Term. : No - Block0 : 0x00088050 - ``` - -7) Write a block of data with a password - ``` - proxmark3> lf t55xx write b 1 d 1234abcd p 12345678 - ``` - result: - ``` - Writing page 0 block: 01 data: 0x1234ABCD pwd: 0x12345678 - ``` - -8) Read a block of data with a password - - ***\*\*\*\* Important \*\*\*\**** - - ***Reading a T5577 block with a password when a password is not - enabled can result in locking the card. Please only use read with a - password when it is known that a password is in use.*** - - The proxmark3 has a safety check\! - ``` - proxmark3\> lf t55xx read b 1 p 12345678 - ``` - result: - ``` - Reading Page 0: - blk | hex data | binary - ----+----------+--------------------------------- - Safety Check: Could not detect if PWD bit is set in config block. - Exits. - ``` - - Note that the proxmark3 did not read the block, the safty kicked in - and wants us to confirm by supply the override option ‘o’. - - Lets try again with the ‘o’ option as we know the password is set. - ``` - proxmark3> lf t55xx read b 1 p 12345678 o - ``` - result: - ``` - Reading Page 0: - blk | hex data | binary - ----+----------+--------------------------------- - Safety Check Overriden - proceeding despite risk - 1 | 1234ABCD | 00010010001101001010101111001101 - ``` - This time, we can see the data we wrote to block 1 is found with the - read command. - -9) Remove the need to supply the password. - - To do this we need to clear Bit 28 (set to 0) in the config. We have - this from above. - - Remember if we don’t know the config and write this config to the - card, it will over write all other settings. This can recoved the - card, but will lose any settings you may want. So it’s a good idea - to read the config, and set bit 28 to 0, rather than just overwrite - the config and change the way the card works. - - In our examples we know what it should be : 00088040 - ``` - proxmark3> lf t55xx write b 0 d 00088040 p 12345678 - ``` - result: - ``` - Writing page 0 block: 00 data: 0x00088040 pwd: 0x12345678 - ``` - Now check if we can detect without a password - ``` - proxmark3> lf t55 detect - ``` - result: - ``` - Chip Type : T55x7 - Modulation : ASK - Bit Rate : 2 - RF/32 - Inverted : No - Offset : 31 - Seq. Term. : No - Block0 : 0x00088040 - ``` - Yes we can and we can see Block 0 is the correct config 00088040 - -# Part 2 – Configuration Blocks - -One of the things a lot of people have trouble with or miss, is that the -T5577 has two different and separate communications protocols, each with -their own sub-protocols. - - - Card to Reader - - Reader to Card - -In Card to Reader, the T5577 will encode its data using the settings -from Block 0 in Page 0. It will use this in both default read mode -(where is sends out the blocks from 1 to x on power up), as well as when -it responds to commands. - -In the Read To Card, the T5577 will encode the data using the settings -from Block 3 Page 1. If the command is not encoded correctly it will -ignore the command and revert back to default read mode. - -## The configuration Block – Block 0 Page 0 - -For this configuration the settings chosen will be for the purpose of -the card when used in production. E.G. If you want the card to act like -an EM4100, then we need to choose the settings that work like the -EM4100; same goes for others like HID. I am not going to cover these -here, rather use an example. Others have collect these and posted on the -forum. - -To get started lets look back at the tech sheet. - -![](./media/image3.png) - -The non-password protect EM4100 could have a block 0 config of 00148040, -so what does it mean. - -To decode this config, we need to look at it in binary -00000000000101001000000001000000. Note that it had 32 bits and the -config block 0 is 32 bits. Now we can break it down. - -| Bits | Purpose | Value | -| ------- | ---------------------- | ----------- | -| 0000 | Master Key | Nothing Set | -| 0000000 | Not used in Basic Mode | | -| 101 | Data Bit Rate | RF/64 | -| 0 | Not used in Basic Mode | | -| 01000 | Modulation | Manchester | -| 00 | PSKCF | RF/2 | -| 0 | AOR | Not Set | -| 0 | Not used in Basic Mode | | -| 010 | Max Block | 2 | -| 0 | Password | Not Set | -| 0 | ST Sequence Terminator | Not Set | -| 00 | Not used in Basic Mode | | -| 0 | Init Delay | Not Set | - -To get more detail on each item, read through the data sheet. - -Lets see how the proxmark3 can help us learn. We will assume the T5577 -is in the same state from Part 1, where we can write to the card with no -password set (if not, review and get you card back to this state). - -1) Lets turn you T5577 into an EM4100 with ID 1122334455 - ``` - proxmark3> lf em 410xwrite 1122334455 1 - ``` - result: - ``` - Writing T55x7 tag with UID 0x1122334455 (clock rate: 64) - #db# Started writing T55x7 tag ... - #db# Clock rate: 64 - #db# Tag T55x7 written with 0xff8c65298c94a940 - ``` - -2) Check this has work. - ``` - proxmark3> lf search - ``` - result: - ``` - NOTE: some demods output possible binary - if it finds something that looks like a tag - False Positives ARE possible - Checking for known tags: - EM410x pattern found: - EM TAG ID : 1122334455 - Possible de-scramble patterns - Unique TAG ID : 8844CC22AA - HoneyWell IdentKey { - DEZ 8 : 03359829 - DEZ 10 : 0573785173 - DEZ 5.5 : 08755.17493 - DEZ 3.5A : 017.17493 - DEZ 3.5B : 034.17493 - DEZ 3.5C : 051.17493 - DEZ 14/IK2 : 00073588229205 - DEZ 15/IK3 : 000585269781162 - DEZ 20/ZK : 08080404121202021010 - } - Other : 17493\_051\_03359829 - Pattern Paxton : 289899093 \[0x11478255\] - Pattern 1 : 5931804 \[0x5A831C\] - Pattern Sebury : 17493 51 3359829 \[0x4455 0x33 0x334455\] - Valid EM410x ID Found\! - ``` - Looks good. - -3) Now lest see what the T5577 detect and info shows - ``` - proxmark3> lf t55 detect - ``` - result: - ``` - Chip Type : T55x7 - Modulation : ASK - Bit Rate : 5 - RF/64 - Inverted : No - Offset : 32 - Seq. Term. : No - Block0 : 0x00148040 - ``` - ``` - proxmark3> lf t55 info - ``` - result: - ``` - -- T55x7 Configuration & Tag Information -------------------- - ------------------------------------------------------------- - Safer key : 0 - reserved : 0 - Data bit rate : 5 - RF/64 - eXtended mode : No - Modulation : 8 - Manchester - PSK clock frequency : 0 - AOR - Answer on Request : No - OTP - One Time Pad : No - Max block : 2 - Password mode : No - Sequence Start Terminator : No - Fast Write : No - Inverse data : No - POR-Delay : No - ------------------------------------------------------------- - Raw Data - Page 0 - Block 0 : 0x00148040 00000000000101001000000001000000 - ------------------------------------------------------------- - ``` - We can see that the info gave us more information and confirmed what - we decoded by hand. But remember, the detect is still needed so the - proxmark3 software will know how to decode the info block. - - We can see that for the EM4100 emulation we have two blocks of data - (Max Block = 2). On the T5577 these will be Blocks 1 and 2. - -## Exercise 2 - - Using the skills form part 1, see if you can view the data in blocks 1 and 2. - - Note: the EM4100 ID of 1122334455 is encoded, so don’t expect to see - those bytes as such. To learn how to do that, you guessed it, find the - datasheet and review. - - At this point we have a EM4100 card. If we wanted to password protect - it, we can follow the password section and update the config from - 00148040 to 00148050. - - ***Important : Don’t forget to set a valid password in block 7 and remember it.*** - -## The configuration Block – Block 3 Page 1 diff --git a/doc/T5577/media/image1.png b/doc/T5577/media/image1.png deleted file mode 100644 index 7a985275b2ed4df3594ef5c28bd54f7ee47566d9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 44034 zcmdqIWl&r}8#M?a1ouF2LI@DtU4y&3`!Kk>B*ER?-QC?G*x>Fuz~JtD)gJ5yIP+6oIdAyL45!~K|$NXe|ksI5UjS| z{}AjXG##O!Q2YP=pc80N3En|CCrMdRxE(lnI1aiexV5JLK%yE>Kb@V-Z5^OWD#s+= zA!Mg_NW|39*a2wg1hln*!a^V=d&d#~;lj3d?hZhJxf4`5+8Fmciuxba!PM|y)vr!K zYf~t;J2Zs%D+vFtDBGGjxf(i{Lh0JQ{i}}jpT>cX##V;!RUM$3y6dCfVfcTrx}k#& z&;|h2O|T#Ij=}ve_d7cnn?l{Z`9c0$P1x4j+SJAg>UJ!#>mB>_ubK+b$;uR}_;i{Q z3hFDAq{vSdxAfyRR~_}ax9*DtK=sFz54G5z?YGufbV?NW`(sQakF_3i`r>HkdO5e}O%Yom{(4P>aBLtatF&G$8JbbB*h zaxBWJsPCKuc%eH~^s|8d^iGV?Su9m|kyS$dtcyKdZpMkHU5dmBHeVu$MTv z^Wk}wcsMmjzv6(ism2{Q7yT}>1r|{j=iRp&f$=|=3{l2M3~}xafqa8Aqqr|i_{^`S zaHrCF!bL0?4c07R>|a*5wy$ZQRfFV;+?6U2{|)go&7CaB=J?(pI_}P}x;}qXWw3wi zg06V&O524%YRke={II+(UsEmH%fOZY^~QJ|m-7!vP}87Xo*g;qZwMOb`4!LmtLldv z+;5H5d(;M@rdN?4<1v4#&^r#9XK?*y%W^6#Y~oX!kG!8h9lUQqNQRF8xZkdqwS4n* zwKF|&s5lxH%Z_@_<{lQHs7OmV9qS;+9&cAM7KX)c|Dfhu8=}vasTVQ2V*v<=s1vvm zrmWsCr@DJ#Rcl}SwS3dcWPb#o>ao0~!0!Kh4WiuUVjNg5(Sofv7&uj5uABDwV&-@& zY0dDT)r4>-2U6l-^w{JeY&h!;y4De6sU)h=x9W19m`rYLAFS#u+;*Kz9>c{;Il z`89i(9KTv;qKT1o#M|rYnLT&XDxm0uMr?MkyL+8KqV;=nWJe~Y_!9|SXmxlXYnkR+ z#Eo#~i`IEO8&JGiLw%+XdWmA!9jq}pb8b&_$qvx}gb~JHs0?|#7&3)rwBPIhiF%A= zJngApvm?Zf$E~0G5yFX66UKElA03xzT5Y;z)hJ3Ric;(+6NB}>tun1$edlN-%YEKZ z3I|)JZdOPTZoCxOvx_d=6dIeE$;oRcGSnUN@B*BHs2i0Z zo%gJkTwl7^_6f41q$$iykENVI?!EhnD=pW6llelOF@iG}!i2J_lZ)KZ&IbG}0Fart z146nJqB<(c=I%JH6hzRjB2?pp$CodJ_1RaYk{!(4lgm3tMli*=wJ1M^d6w+Q;Bjsa zF!7V)erbKeTrS|p!R2bS?t%Sy>oQ>?Bj6FZ5S_2Dlm+TYP88&b~=H|BbbsQ};?i;JVV7AevW(PLk1g%l`fkd@6?j4#W*7uMZ z3|J@9zr&}Mitq2tN6`}IK0G`$F$0@mgp!7Z(~=tm0G#hes<`+7W}woTHS|Kg^hu5h%P}piEG4aU)U%QEI_3KTQWH_?4V2$n1COP6-qw0SlA9?q!bHU?skVIWVT6*+F z(r{y_VJeU8pd&(Ok^7HSE3FzDbx>LwWrk13`6f=S>&2317kWlPuFlGMKKR+r(XnrQ z9A)B*@BS**IHd?6Hv zFFxjuJp^vO$Zg9v`}ab%Kkx6lKxz9@cj+JVROR$!vczs7L`Q>iuv)UwJiRuYIPa&Y zyw6xG3Y>m@jfe`00@#Pcs_MUlr1X_O*X<%pTZHTMpY>_)B-I4r?eLqdhOe2#AO5{B zaKzKu`neDwJ(;^O8b1f41z2`D3mz2+75?|SdSinXAkEfbiox_vK5*1rOh70swH+Rc zZJ}Pk3J&M(bG9U*R=?@nA_YTCt$m{`=(_g&mF01W-ZJP>qeyZ8v!C5#)3KQr?#97M zvO|k3cW{ZKX4@yz%OJ03pYouP(`A9K+DZI^$z=wN#$-VL;Bu14PQfv@ryN2kY0LQqEpUpoFuV zqQBd_%fRPW=09PfG(8O0fJr3m>K6{{Os)RnC^d)q^1ix0jm`t2U{tIr$92GVs`QUm zW~WTn7O-IQo{*X6hqV*ozCI8>7 zka_OMvar#GcHz(&WfdT0%FQ?FHT|`aO2qG8685c|QAi=MApL}35V{A3UULUmISI9| zw~IRz+PTOvq+Vj#v&5-8FUE+N6Fq95i4zn^@Mr5{a_(_KE`??LAP~L# zzA*ZIr&*HH*Gx#56BZwIf5hC0lBZC-h#8cr^a&#w>~B}LJhwi>Ypz$g?Qs#UxKdy& zGQ|(#JZaQ!Gq!5!y0bYg-=X7&)go8S^y?rQ8F zm2UMKd%Hw`RCOrC#NLI|r;%+Sn_NGdd@euJ{IEwmYW6%#Ui2l!$DFF8&Ntus+_PM} z75ee!ElFEEEU%7lfvmBb%^AKbxv6?D8V?R2Ua32QB{bdfXuLnR?_Mr@o~K#C+6%Vc zi&Zv$>|DZmnb%KgV8VFv=y1!kWFu^V`b2-M*V{e^C&AjL)UiY3&wksB8Gyv|rIva* zWw}QkULP;YlAMHUUmV9E2epdRq} z;`sFQ`*L_Cm<5DWJt{Y328cCSa;c#pp{e)v_065LY0njZt}DeyD>1gzD1ICvDfO&X zWivflu@JS4D0QVRQ=>nt^l)!2^T>#L9DJl@^SrZb$Xyqzc(^c}D=say-!N||4G6&J zr4V8>vsK+dm@LDoJS`1FRRu4}qwri6J$8k%m(C9gSDr@>_p0{04f?Dr&q5%Z$xCf9K<5He149rsLpx40va+hbSn3p|ae~T?G6=QRd@@%NrD@!~tFIKy3RDSP*McWx_nWjZ!>rDof zs_j;3YukZ}Q>H~0Q-`X2Mt~MTDBnU!mF?*aZT4%2UInXBQ))&R*3m&JPO0e4t%bHN zQp0tb;ZXzu&8+$=txA{6$y_N8jzvUGkjk8s&`U{1U1^<@vY*9*!YJo~N`-PT_e;Cx z_&Spc$}B_$jYME>ysP%;%p}L6{Lk!Lh2(?!iu!vryl={!BKV+UV}(BvcCs?l>Fv4P zH5ru^wa$bf+cI`Z0>I2GnP@(lA`DyaYu2KO7dIb>-xrG-Xj`f^`nZ?q1-j<+D-o?nYeGs@`cW0<(6u`SIW@=md~JF?EI2n6r@}C zDmx()ar1q&h$yj48;czGTZ)QnJvD$l>{WNhT#a z#;fkyHu4l6@CZ?z)a8*9DQ9Z>B_$SMcpT0rcD<1`HTEr1bAw@PJMS6meH787mRM5L zfz_5=iPh(Jy?uQM`h0#IrRy=Dr~sVq+yoi&FsX1_zd>o>RMqXynN8IIo}!Y&k%l7q zArIC{$Y_W$6Yit~zZb1-Cs$?{y_TTG=b)V{iU6P$E?@MSyz1WEf}bQ;#vg=)`Wd+3 z&UjF33>|RwJqY5n<;;LR9r$Bg!zT1SGVhwWr(6fWiOn^7@TUE3C6%>2;;b{JsB6p= z)i0yEvDGzX!+gkoJ$NqB8Yiv?HFKIzKB*K1w&Cbfsi(71fAYhaxqu;*n%Z92hCSkj zYMgV=QFV7(K&@jKadRY_?vxilVyl$?WsK$FOdsU&BOF^1PP2mowbZq6CBwIEB_rE# zCiMVhWw>8nkv_MO3w+^C3ZZ*}x05ynClOt^+!oGp1Th))n>T9;ia!+6QI)}sI*bF4 ztH_>A2rmjf8_56V!$cFu*Z3Wts#<(+UawpL_bw+k@){awDJAA%vF>RZC8f)gk1}~b zVQ^)+B>lNwKH(uQ?p5@Hh~bESeWH<;X2rMU^($2z7xhzWL6m)JQOa}5d|pWZo5^>9 zTS@S+y%*>e^K`i%rFD^LjC{7S6msqD_38khM>cYKI?dQ=4!*dr1y<0=5~%x2hG~3M zfvkQ6T!p9c(NqgaLLE#(97ilze+BRZ`l;oA;cIJ4Wk-AQpXD5n zrP=aYAaOs+t1ETetK0fy?T0kb04!xh$c%R1VzVy|i_dGEKM#W|u)!RvI@e`XjI%5x zUBc;Wb0N*tj5y;lgh;1uv@XPX-6@qb>EQ~@;`{2g@3r^=u7ccoBL$S~Ld^TNMB#G0 zItv~sL_tCv71DHc!4-sZDf8Cul#UDwckP1i)1_Y9rPT<0rh(ve=`Il zZ!jrv{KI89KEH`C@vP7Tdwoehc=}QvukFCrg)Xc6UKB8;j<_|jnFfZ{dgmZnQ|c%M z+H@#zV9-u*C+S-2r&V88tVvk*yx)|#5%^vN?4wP*p{vwVTKvO zqt^F@Z#L29C)Cbo^Zu22fH`!V{ZSzBCy>6?F*~qWZ^p^&-2#D(rm<9WQ=MY9~ zPdmQ+dxDlLB`a(EGIfOcepzfu1Z3Aou_7-8H(k6x#3AB zOSaz5J*c644MY4$Kn~PhD#voPVmZY7$S1 zQfZ|W01=6-ylI_T&E&&on!}Ec(;+|qB~X2Ud^roJ7tjHR`f#y4g>VRzRIrzjhL{|4><5n ziIiMoUwHT{7UmvZTvLYSW7&Vle-9s1JJ4YVsazM%(xoT@5_Kgt&rIj~dLycpj_i-f zW)ojWxYt0HC_F)m4G(CGzFxs6eifW4I{m3`*mDvF}c*sOBF zlC~4UV$x&OVW7l?xf8u9{B>1$j*$2=GX9`6NWPNJI|UUv?I2PW%as+4p8j8eVjH-x zE&RtaM5eAbvOfO{TJRUhG5<18fAn1V|F;TMgA?<#h@X{E$G}6H+MH!{(kriLlMNQb zy{M(=R62T3Tml7m+j*eQ14JG|Qh>V-~CDlP`(HGQEvLaC#)qnAj%{>m$KWe)>Mz z<6EPfdUaTSpBno%TJ8F<-%ywx)PiM(UZX$^aug#CpL*1Ia9_P_3$xh2xM&3Qj}1iZ z94rF}%c2Uup?P5oeRdx)RcoL6qmH9XS*_<>-qx1W=?Abv+9if%P?68u8|@2k#tIDaLpQAz3Ok$D5h8v@SB{ z!c}-$)JgVVJF5FIgo1+%gUOi-V0QrCqmWnb`1z&d;#as8mZzO+M0HWp}N8h<}LsvbqGt&T9yRht8G;mJ|gMq-^$_$v-d_$&cIHk+>M&TR|hIi#>OT1ds9!&p$b5J13|Z<S`DoEoOQQ-^=|05HkHh)^2Y^ zn(ct&Af+=wI>)t%EQ)ll-)>sN|ET@mP7Bb@5XYyvjOy%8s4iryJf{-L@6Q?n5c zrLl2H1dn{`Y6TT>AT{E|4c`&ix?L4;7HR=Ip=4n&foCD(VhE?2TswRI+G$Y{g;qA0 zR#lFd?ZM;R^$^D0y&`$i$*HS4N9#NeWjj~$WJE=|m!BR_lkXsQ(|=Y~)>CO?@nDgl z$^fu!*jtP^GIdORT=+_&3P(?u874&Sm08Q~%G628fZ;8PU@$5Dh3S<^;d7 z?|l$Y@)<9ct-*b>*4>{Gp-msC`F^z%j2vDRl6-|RLxBodiwPf6DmXl1lFRU9_Ke^% zq}!r-^Rb!`XeTO5$=98Eu$154DY++sjT<{$oOyfo6$vg9l{9!r=JyW_#Kd2Y%k0oM zJ})NGbfxA2d(S8qqCG^5UcBwPnSS#CF$PWu^!V{-c$<+ai=h<0{knT_FlFU<{b?B` z6Ig-C{an35lC0nlQ zO|dHd#<-Zt&-jY6_DW^mxENw1WkJXkQ#9;BdzF4QRLZa=GK?9(G0x$6CQqyLgp27$ znu)WAA7h#1xLQC*O3E-Q%E8?W_Sg2PH*;|1( z(&cA1(I?~a*+z}>#(^AcE?7a46b3Gpa(m2Tv17kg=*}FT>eR`&Ja&ZHgE{BYZ zBmqT5NmkmYV%=@Nz}<=3qkQqQXv)crBGNil&q7Q5MYZ=M$n|t5^hnfw;REWW6h8Q_ zg7WBEl~oSAWV)ENzntgF!R9r+ zVlk;&_mhy;9s^Krc_BAAxOMrt7`lCdL$|E8wy8JC2mb0{hyQ z-WqpfjSdDn{kf3_zUPYvN-Kc^BlYS2lmz4Cj$_7@AFG^<0ZUz#WOLKdOVOH?|N?J|P_)>i2cuxYv2*Mm;AET`&SDZ4LM8hm@wjhS;s0LK6_ z76G&I7-X3R%$CHG=nRL%cu1kwiRl2y5OjycRm5pHWZ&p55ExN|ry%G((xChNaPx&w zqBhsx!9Rk=CDy&_Sw@oFY~9WWEy^zzH92a+6tut+GV!;>b1q(f$w4eAVxN=8=RO#v zCdIYi;;Z|cS0iz|il8p+%lIXWh&*8Z_{3zf)i|vsh)v&DSS0iVp7_%JIA`M^%_5he z(LLvWIcI23ved|&%V^n)bnB~bY9ro|TprEo5(M{BN4+q!neVnh z4;i2lRO#h865&w!F!K#UVGN)4%Kf^}iiuijFmhQpYoiCQ#9A7X6$AO-qmA;mrtCCE z9BR&EK26h|Yd0kO73t;5c8_DEUb5m|3;eO}If&`MqcN6XU+AB%!Ku)*m1}_F`HB@J zjbYUh9baU|qV7sZIa0#o_bFgAAJ!4Y)6Azc+<2nJXtkcCNlpNL`Y%GoG-6TKhS3U9 z%^`2Fhp#v?REZV^9QMvq=V%)E^fKpv%h}WUFSA?qdKY$leCxQ~j%-AQA6r;VnrE{uc2M0C%>Oh^ z=&6k92vmpru`{q3bcb;Qf0h7;%7@E>fgGui&hyolzI<8@6&HWs0IqkoU#zL?y>>nP z-Jsb*WdG|0a9Xl@&SvH}X3I8<@!*R4)ucArCqHyzd2O~0_8L~IVj|Sw^{?e-bfy-K z6VtD@Ggq}Lr0w=Oa7heD78)|JXb%6%%mhF!Pi_C5L*zr6dt#*~YZU_V4lGyd6T7^m z^hNjW_$FM|cAl@!ny@Pq{6@V;&E$z{pn`m?%?OJk#!QFF)wP2@{^2MahLwEHeyrnr zVNGL?5|g2tGiMUY?(rjVOg}~NvS2hHU}E&9v%VB%7R#WQYmy=;wNG5`R6xCH*!Fu@ z8Zg|s9o`n@4VrA5CzdC1tw&>$m(`xehI@fIl4srt{j{QVx~t!)b?F>^h-ePc zb8Z_r$F`L}v7$=5QvAe=VG3_V<#={=;W3NJGj8)GLF%VA1$R~QbYRW?!G1#`Tk-SF z+THd&i511JNgSA!#1t-mPi6#iLg1B+yAEP=;=$q#<*oBeCd-w_RQ?2fso41U{M|T6 z!+Y}cEKWtm!|AXZk&ViB{+H;7W0SP;P-9ncr&?Hgy-3^}vOH|O3F`QxzjZ1qtL+PK zrq6nQxm%d*gT+F2Q+0QI#@!z+3b8y`H5~HpZ*gPDu#?b;nkgx~v++6=f$2f!pB1`Z z_c55?T7W$_kSWMX$+9ngM(Kw8PS5xZqzy82c=KS)NWkQH7lDK?E$vij6@GLgPf&|; zKuFu2ZN#2pGf;$E%XCP0R=SgOG!k)D*|kJe4?=PCQK3uCf=xO z{hW0drngS+H1AhGczEnjOiq96)AX(+)!y3$9u?D_CI9PSV^n$(>qCteDt-ap_KT%2r~Jnk;8 zPJ3Rg06jB>(*HdTnvBYm-A+jxTK`OtT4f%y>4JgYEP0r}DMt5+fmg@jmhr~(vs3p> z?v#bXXYw~)kcYtY^G*6{O$d$HFM@Q`r{olAwD+WdI7%u(A&&zi$>I}v!hHwEosO9B znKHI*pARZgYd9XG?)pfNInnx_H&j4A*$QVCbTR{G3nk_X;@la5Wsfr-G7Gpb@bcxl z!@M1$RJKz#O9l8jk3v@Y`{zOKg5$jrNQo@P{wn!yPbLzu%daKJl=p)>ou;AlMnJhv z30ObhsG%eMol6*c55FjCV86xq#^(iV`;bLv6?8fN<;NEtstI5`He2cf8H*PM%|t2` z3?+ENq@$Bq_7BZeb0wShmx}K_$R^^<1?nuH#^pb%6;u$AmQ?P9V-$J7Y{LLUR(Ji!avU6#k%ms|ZDh)mxuvJ4`@ ze>)xBIBb7;uPf7f!5BUD6e&l%1QN0a>4y|u6CgMd<{N!*1W)Tu#dmmR6lf+{ zVJLXR6z%%==v|oEbSGhbhXG>`s$1hfiLTyt8JyYMr(`y)4Wps}3>y83)wWfKrWw8` z%Kn+?@zy3Udp8citgi8%R03+&1q7~PvhGxksz@&D@+A?}u35*6C7srijMLq{Q8*2% z{22ZcnZ$#VZ?*|=OJ;~u^+xWxqY>UOUPZH%p4qz!p)D6kM@wWg)?1ivf}HS%*v@y2 zZCd=4u^azNTJgbloLD?;sD@bqnzfX-<+^6tob}R5_JSlkIwMw4Di9mBKw5e7QaiBz zqf#ZL#`P}SA65`2De{bGvek-JG zXDx}*R)>GcIgc)q*rsLFhqqd&wknfs?jSfU&ASIszN9YMnjQ!mMgs64b^kpKu)QdH z)qQMgBx9RF1y9SZ9*O;|Syx>kQ(~5AbNh`PfkjUYdZ0H>tt59Kp9^-TvL%#Wak$;d+?aB$b~?|g z7hYF)G8v#Xki2KYXGiU2HbrYQ?kJh+c_9&XaD73`Zs=K`dE>X$G63HeL(tyuz1+*m zZF1+h24{ zU_##=W}%D9giQZbq4Az@J%=w<>wfe7Ss#C0A`=mm;eL)Q;XvWZ8HsMWrb7@8^Xf+{wZKS0%tb<gx=Yy7aq(WKZ`ggi# z&5V9wf<3W2_IY5s3dfQ4>NO;SznFz2;FG{W_P?V((ojo>!kRv6Ad$ecT`D4jYxX4{ zj%cl&w6Dj-j}k(Cg2);@SL&9}LwoT3ETqnSaqB5POgn3~hcKSZcX3}bePjwH%sK@K z%9{A|04>i?iBuk_WM)Tr&zc;}0F)iqHd2|>^zn2ImMOH?@XWoj^o?5%D(5ui8 zTSQ3_aeWhiIc3G*1AJt;@p~u-a3MZAiLH`6U#?i7>VLXR&A?@?CVG{3)2GYi_;}#u zzBMYKc^ycgej;@5wQT!*tNof)@@9GNWTaS$+2z4Zqjt8Zv_At>3a0FBrA6ThM90Jw z3hGv2uaNKU@&=s|rNuL(Cyym9zKL@NRVJT#NE@H{2L+KOCQGiig|Y?3{WOk<3xbPG z?7o3*f7k{ezYc+c6qt8`HK*nlJp-@KJVLyA@s=W$x*+?cMt}cy!J$SJsyNoD&WhKe z($BDCA;-E6fqlboCLU2j)4v7a1)KufqEOwX$j9~)5@9rb@(57~9^+a!*;4Pc-4<9l zNt(8~96n_`7vA{W9$w9Rxab{91Z$J-mJCWXzHTfK&OUCN$K717eA%|Ir56vg;iAbh zwOs{?&!Dg#;Y)d13QC$h{b5wOqp^C1@c!fr!o;@=LAm-;%YTVE7;9=id&9;J%aa2e zzw1Yv(Gb4|R%uVWGusSHsD_E3B`Z&^2_{0I)W~bR8%vI` z9*tOL{Ap=n(G%ascJPWV;0~kx2witEv2>6J&NcPX5*OIU>4Jl-$d|#J)z_U++BUk zibZyTMW>b-#f4qsEvqNrL@x3M^3*7WgdIubr^d7Du%9p+M+GIyp2^20pEOvF@jMwU zE`W;}K24Emh{JG6%$A2XpptdgGrs6AG<&|E;v9e+(rOul9Qgz&tF~v>B|Hll7`&ks z0-XU-IAakJtmgH}5qNwDFXmC--23&u08r_0`R-qh+|O&3sv>s`jqqW-H0_^@N=vDqo#n+E}ewA~VF)SL+s-c3UcC z`0PE~Wjb&{)u_4;xA6pfI#*yA5Z^uqNoHK~Zy_lY)(}vp8{Zb(7|upaU2b=87GeXG zv6P|sw|-><(JRB5(`(XRPlxOG@!pQ2CB66fY`sqAlBbNZF61oiPBp}*spE*4=I@~uvhb%z@B z?oG{wG0Ao$R+v&PK&YIYoSQn9gr3veAv~~qNAm;K7VxBW5cFN$#8;XsBQ*!{wCmrq zCEC@9Qqv{mycoUc<>0;5}iABOp(RPHXqepCxFsm z$rCMpF06>Nl?|R1_rDH8p9$1hiJJU^gW)Ur}@6(%aM-(IkM6p%pxZ;$5wZ!^{_{G95%xLjy;@X z)I-jR63Kd#Uo4hB*nV{*{AZHmCFibRP8W`J@S%9&miu071qk$RN`I-TJKWEOuGi2y z8U~GQ?|;@OKVglbjGfZZRHAm`|1v%O?wll}qa*U$V#Ko4F*56llnJMm1{-eFc=^)S zwYAt;Qm3T;^cWmpmNCf(7#mwY{jEtlTTj@08PySCvSy|cK`lL{@_chSP!EhmvZ?!W>&M%??Tk{aFDUzU=Lt>(~ zcX=66+M8WdvnldNen#Z3NGj-r3ERP|i#|6ia(}ZSLRu^`uB_Gv zf`tJO$Tu~L-aM%1WmS*$TH%#c|D&nsq;u zuN3!|ETd*%+6!Lgqw0?{(rkmPQdI-8XFg)F@}LLTc-L;ZRw^;;R{3>1?Ig0K0&( zB1?3s=)D@>{Y5fDyESBh0Wp?~^t4ZJlvB7*82(Sy5)E6{p$zFfZ$aOyMwaoy(U;NpgxIw1lun^}T-ugf{}6QXBdd{|L%N#5+Tg?-U>Jw)m)S z-bcH@By+01e;d?LaCrG3Vqr@Ff*YmZxAcTmb=iLI|&1dsnud zk&f5Ml)ub5Qn}Ji0H>e#e5}?_f99upUBr6g9+3e@Dd3Rso~vIVGxygT_Gl%(FNwz| zo|Lr#QF@+Wql#h*z(nY_x7U>W_K8bk@XPROr7vljZmnLDkb~J@%^NaZ8y+|te}!!RM(%queRVXQ89LBi8$aWy_|;sbuUXSGSh{wL4G`+VP`0E>T2`iePKMjukp@UT@prd|5bFO4!uKx#^rog4|M8GZNB@~tW-9=$(#I91a(SMu)K$i7pR31+-tx7yH$Ic`4g zacodVM+}$^1`PV1tEG`mnnvq~+M)M~@bBxT3#ZR#F)ZGURUN7UINtadz0woPYr5i6 z#}vITi|}riFra2E2AZNCY0?cg$Dcy;Dbs+?lj;ErDA$hRUo32dE zn3pT(mHcXlZAvbf(dynyE?Jf^gWn(R%YYwMDp#LPB8Q#N3Qpwf4rNOUC+mszAg#Qc zV2kfcB>Kb;^51*LkGsU;9@BMqmdM06WDvQ%^?m^N$TcZR?T^T7P()3UU^(eE#}5 zB;3!%Y1Vi!Br#`MDGTu`&YJ=knf#-p(YZes)&jjTUr!u;&KC2%w)#yv`(Fimxt#V+ z`$`6v5zx@YX_?}hU9l}uDg6fVDbdgf>3&0y+^z;DmR_PrEP>zbZE+!yg*ZCL`b}j0 zEK)6EyUTlou0UytzerA2E78o7R|hLczU5Mi-RXbVRV_KwpXK-UXucEO`<)A`6MtJ` zcC_E&Y`w)BI?5~IjYwG^c&ep9q+01TIWLAKlpYpSR8dhG(^Qu%xj`8o^$=LvkBG5) z>8j!?z8RPjlS>=$O?T$fa-x9~yd6C8VqFu=tIVly`V=qH$N(?w+|@hS1;Uzj{E-8l zw8-d73L#@Kq}2=*)78&YuEx?5l;rZ5Fb?NyMjXL@ot^jhq;PVonPQqMXT(7&4p!q{51)Huq@)bX3!$pYS?7hE8kfOQ z7Cz`1UN$e37@x^Cy%J>! zL9xgC*dW7foJt(#zJ69CeMK=wMiRd(7&?eZu3(mwl{V12D@4}H{1etCfC|Q8ES?j@ zp`eOx&2&v`G+dPR(*TmWtS~XSDaU-}^M%XM7M+M>hQ6@a^dicoT=oOGLEH9N z8umw@lH|VIjeAAZ#ZXE}Z;ZRb@RQPVHEGN`1xBn1hFY%+7x(TZ_yMPk@h`}w4A*&M z6-SjEK(*r+cZarOoi6l%%;q;2454V^wx}P%rWR_ofA3ly+_C)#n!qz1)Tfn8Rs=Jt ziG3U~i20SiNrl#fH8TgHp10hAybB2>?uFdNU;6Oob7(d)9rDs4Yrq)Y8&`N9bkNG2 zb*9su4b?gspzx!dJ~GAii@F;ZQ{b?6_(vza0ptai*%uos-i^26M%yj<0Igq4d&7-n zA~FAeU^UG{NrC7SomT8V3V2yH_zHCr9qE$Y+B64SMKC+#%>Pd$H5e#1cNk%wXCaZ5 zrSjCpOX9W^wmJQS4UI)5-myT3kTqB&nR6sp)`jJPf6`a_fk5fhq>V@K9K^Iz`!IooqoGNB?%;jjWJ9~ni zVD3FJJLkLfMyJf#%00iz?$`AtkZ>Ya?qYTBVKb44hzPp<*FSug0(sA+dj7AUlK_>; z|C_{RFMOt-r3ESqjtC*6SdZLHHFdldB?R&ueFRG4%!+VAdILG?&laiOJ$gs#pr`;D_X*Wnlk8S8zQ>6;cqBHI5*s<^qmlhY7 z`5lh;+FZ%q-k5QM=nN8W$vtLUjOqUjBGQbG@miO>e_B`!d&|)kL`NxNZ)6DZFDs*| zJmpuh;0n&k&{=FSL~A=Lm)dJ{8O{rr|^FPh@>+jR?io>e+9*@NUJ zD3l8Vl4I$3{snWHW!d8InU?U?Lhl3nF^QAy?)b+1*?vY*>K2C+mwqMgW40gGc8;k` z2>H}%X7q3#9{Q&A!|xLjQ-U8Hr57htcxASYn3)zIuKO!-B{%(v7VnM&2VUpO<%`|i z3OCPrGf~qAI#)j%VU5?LrHmawL*FNo7jF8ZVr{35l-N{eLsc5Xl6 z30I<+rzd_P-aDyo55JpL%t30Rg+KZY>;l)u!L zL#wjJz@?htC^6K%IUD}+^Kx-efkP{3LylnxXEEvmu$kXjuXXgRbMbd3k=L-aB(#p; zj@(P!4sZiMJY@mM!v`D1Q`tIKh)9||t;F}K$%es7Zj7>%$wV2Q20?RNNGMD-Kq$1I2 zMIacvvpv0AV0D-0!!;j={UYBvL$Dib91B$VXRukEE^>0EvKh0HX0ou0%K%%=aw#-Q*g2Q|mn<07`Va>su%jX+Ej>@2PO zfy6&$CKu=({1Jdbb-4G@%sG?PO#W3DV*@5O|YiCWIn5?L{BcHy@$uG0pz^&3^fTI40gu{*kzgR9xCD*ke?$qY%rU`Y4Q>Y47kuCsEmRT^nZQS2daYpYATbt^ zoR)!ZNPS%;pid8>!nf%6zsC8B)$JdNa0yJOp2Z#r-2?Wr09=%Qht_3^cf8C!Obt21c% zA$LjseOhDPmWwGY+^su?;N*dt;Ttk*`JRf-)TZ<8J6z)YIMs>eriSrD&6kxqON|9m zlQe8`efAf@qeslJ&ECxT4y6!GRZ2?E?k>eqjXn8Cu5};lW|}&%;%F3P$kmp(d_=o$ z`n1W#9=jeid#nXcoqT8E-p^j_c76eQR1x5Io}cNoS}6;k&uuQnVB&Zx(qwwmd2ox; z8H9s#zYDbdO*f7b1;Yp09Dr(Q3QjFH4?yXY9Mk*yaxoBMxv(isLt5@;G41h8;=2p1 zo89Ks?(^sx-F){#E9dztYri_pyl{D5f!v_3NJLff)3qCIMIFZY#V!QIeYyHf9Pao6 zbEe%7!AK9jZwA42`8lNuL+{p*pR0DiN)HC^@R&19-b(?5l*wdEcy>@x{FAfe&xZq9 zye%>DW`a+9qi$c-yUC-d)M-^mqjEomSFy&j^4OuT$rZw;PnA@U%4BOEtKZw<*>%=H zI0rdU($%|PV1p@?QLNL{x?5xjDXQxDoy-{ZMiUX8IAF;SW-6L3S7Lqj4ImR6YRrz^ zY1UbO=Aw|sy7huJlE&laC^@X9G5+k7ch}%!ZK`r&!6w|Ho3HIhX$`xle2lT6`pbKl zisf7?;DseAhNbF**P>bVi}-?E#|FZPiH;_pl|pb2GJX|36_%G89DDPk+@0HAo{?OP zU7VnY^lu$4FUjJx@0%i?(nd1|Ej{qtt71c}xrR6gTPrT19FU1W|txYq{iO$GK4XInr$c4vNF#dqfg_O~WGnoLpjjYAzO0&@{N z0Vcbk1jnn!q8hE?FkStq4=OIBfn~YL?dJC*M#``+S-PK!?%eE|2KxZEQz9UtqvMhO za621Kt4=%y3%ceHLmtPmkqSqdG4TGY(8z>CS(|MBat3NMoW4)9a@l=kC>bFNi6pkq z>y)DA>zEOW7ME~LF?@IWnQT1Ul;x1)ildbub5^4S(Q~*Ww3M1=7)PYS)hB&XE3SDy zt@Ec>datj%Yn;L02?Cu7={lAm~%84YQvV+8Hwo|xgu2hVspE>8^2j?U+B|WnxxJxO1WsOzZzN4>Z4`vee`ov z#eH_66;C!y${1!d&jgI6^ZijQ1gr3HYb>E@Qo*k|;#Zk`o6ctc6)9Fz^IlG9`01uW z@T%s7WvYMzEQUY!OzmrHfRsh#eHb-Ul5@bh%}cf(;W_TcUo7QcK^!hX3t&~nB&RqC z1zu%ISOp0>w>X^6Ep138P9Rw3SkdKVi+r`lBW=X&N&AR|{R5q}%BcABs|PzKnec4p zp*<+GDrl|6w$EN|!IqO3$;p2V=sv<2&nne8oY^_s$kNYMSo@Z?GM->(8ETU@G65tm zBerDsG2`sP9y*e3Pvg|;vEr8g<+lzjnUR~1ljp3?g!{D&VDD3zdJpz&LPh<( z6m%-ibovjj6zv&n$!RF^yO9}gmFAQ=+{bxGf_}GT#YN*{Pw);#83ruMb+k42$*@CR zC)%FRfj5pElm_q*36FV)qMEF&?QknjV=*yPYWr*N@ygV9(8uZyQH zfO4(~J(kZ#76yF^byeB+JT3`4@{U}N_0QQZ0>|fm)J%ct#?hs>z%c2_ud~y&n6R}A zx7XHuMv)UaaWgTQNZ^4rGc#elFY4c!?%nB$9kIOU9hI>-MNhDI$bZOniNK1p2rrhK z>8ccpv&Sokub6Hbs}!NcX3B+#7=#WK6}}l4=nZ7CW>r5^G%Ls%SpiNCAXQZG6@4)o zdA*bY#|hq;^Zmh|ABc8~=LGFE*~@L{Uv3us$A8vlEk< z+VKq0Z^WTl=BR3ZAGhvlE|PsU<5qLZ3Od&mP)10EvyhV+UMA~*v zTxouzou}wT*GP>|+n632n&jG~N!`6rF5kR^)?uH)It*$*L5umK{8JZ~%5?8C>e&+| z6r5BRy2~$4d0MGxY)KPH=sE$zinEg$P%+rABgeYS^}v~S3#d;0uP~ZRZ3*uyG^cXpdYIXUD5zo#oA|UwQan@f)u@9Z2{<2N#25(GZ0AU^^jxicH|q8LWvX ze7wh|@|I%V={X;5;^_+QOdI-H6n3zEY>IlmP1>Gd+^fF2?#iZ#b!>zw`+rCmI^kD; zMAj!+z1cQe_==Q*mnPh~WwWlbjBR~(I1k*2kdjuSyKWR(&-a#MPj5GO6Z>!l!$+;^ zcIXW_46QybcAme;E+%wsgIccB#ecre!0oqyCW11WUS3GuZdY5ba{=${fy*z#c+K!J z(Uq|H`BCmvpEJCEl6#*crOU`-mE1G|kc6C`!#;ek`j;)Eq-fB|QIjH~%VQb<* z3aH6-;gFP~wbG4CSeNnS>zj%Jlu2B$TA z&L)sN*%B-Y4~-D88Sr_bmzggGyG^*(ymIAuqREM-2(NK=SY}#?onepXEY-qjA&#r6 zs7-oS`wKg`d5x=Lzyl}z^O{8Pg~_BnSD>Mp^-=_;-O769oy@{w!=$F6;E7UUq-J=y z#cv^-{=vzo#Yk1;0KRaF^#Tyw4ne*>C_`#H;{{d8wXZIh*XFwxp&8+nX6IOR5ZJH} zzGsM*Q|-`SQPICH?#B~#R(7ho)T-}c!S2PgtQKf`wpLZCGX62&;^HMqqPB-tRApx; zq#{M;d3gDqk3Tb0TwBcxi@Bz=+}fuO4*KP-6eVtTXKOBN1oc5{S5BN_lfMFS_^?(&hxwA z(<~8_L%-W}o@Na$a|^5{_jjCMUdYyyn1QYsb9UFc<)gT~+0iw0g62y#{^L#Z}p>P(>$jw?2u}h~07U2zt?wmkFfkXfaztmpy zFG$=Fgie0}xicPTQg#F;Q-nzv7{V^b)X3b|8+9Q(Xwn&J;j8_}=FZEbWs{}aM=JIL zbLjX2`-dY$08a56tvTiBM{|G{RM4hMzK$4h5(%L*;{!BG2 zHyVwN`Zd|AlB?dU4HFgzYhUTK;j9DMNq-R~-fMC;_-Uos`~I#LG_@!c5##JxFlC%zhkQOs!KanP?jA>ocLZ2* z23EuaY#PrF)!Ut6-1fmaIL$7Qbg<9nvN}=vgQRp2Qww`3=>ifVo(+1_8(0gkQmJtk z?+sK{Oy&wGaaJ6^xku$S21AgXe&vMYzs%OM8;UeOO_^ki&mQ3ZE1+6%MZZw_CudE( zX)Pl=Wam!G=Jzq|ZPAl#r?O{4ynYvu4f}htkDa+l4kRx9uPh*3QH$|t5gT4Oy;&Vf z-#79j!N{98t9N}k+3e;ecQp;eFiUWO{tPEftzF5HlHqRdiLFc zrXTB_v<@B3aQoK*?aV3LHn@Fxl=)jC^QZhIlxd++@Fw&99864J>i)Ud4?jgRF+Z@H5;)k4mV*_B8_JD5oOjK~?*vi9GgWdLTipPb?>z1b4| z4`Yek_Ui|$z8{OPaziIEEInM9V~vFvk1EPAC1L0D#Fq@QGd?mwv-lzkC3T z!D>ib*S>wSJ||wAClz74&s}#1VH9aBRIRZ?$!%Hw!fGoMX2`#$q$ya)@YZ=*Yc-{B z{4l;BzDHt-!yFc-e?crv^Vdb#7XYtIbwT*4n@upb!=$Bw_#Y}}wp7b`86;)UNSk#! zey5cEMkoYQ+hb7ca@|=SDVqwRK>OG4{Z`|eC&0B9Kh%?-1A7J+`wgnL#~9#uh1GJd zFU70$>O7kp#5Vp5v#5l2!CwrY+$hy$D|V&ZX0>w+r}^x+w3m7VugEu`IC?mRpC%^p=vG9h zp!{37`0?}%YvU{IKI^FB;=rnUrLKg(8P4(tsW(>A(uNKV zI39qD*m#^GOJD{6tvRs)mjxT6;GZukR@{HwK3r+hQWb*2$hk zjj_#U5Q4wJAoOiu*8)rX!66aJin}tmt^XF^I#Bq4F|xP4 zsD`x_7HdOGdP&n=*i4D$vTS{P%_PGTO8TS4H#a!;nCn>Bvy->y`i)13?pa+~Nt9!V&eFsg-jnIxly3S0+O+#dN!~l1__?eePU=ByC@);*G zlz{XAhMw%PdWh^-G!YNsbwabgi_Pw}W=QAHb{1Sy_2+1-DI8_#Q(>>JxH>>Tb_`u> zeb?aj1w}NyGj(ZBE1j9ZDX)>DL<}Q=5V#W<&KcFv@X*%6bM?R-Q%(7Kb))hwURzph zBCUh|JJl~s=^EWD3}x+woLbAFknv*_G&JQm70a$GFVlTQrlNV56LZBQ$Ambv#5GBX zaR_b*#w<;P^CiE40T!d7JEJqM^sbge+@|;X#F6^?2wV(t%UJ?Rorc(1s8iRC?L^u^ zMKz6VO3H#g;{~$=5j#u{N-d)h^9u}pVOb0q-gDEOJfW!kiUiJo38*^QbIS~j>4~VWXyHvUB6XfRRNO&tt0nT1 zS;YX+oSc|wV#c}Hca6TVT{R3)!2>8Bbu4NAL%xkX>vhlCtXpoIU_QIeM6n&&AX7~)r z(_mk&sCl~{iY#IFQHg}j>!D+Z0|-bGgd98sNTZDTd};R~8<69zves1V!{_TSr4nb_ z%V0a@V3244h2v^z&mEQ)+P*Q2^<5jf#xrXP)^;S}o)lMq^CA&*$F3 zWC?^<67EYQBu2EWquG_G6XvC8l%aAKrHv_dw{Bmn;p70vy z+)btF9YPSxv4wo{iy{}{@;dY8TH$_cin{|X9(MnAaN4>NP01QjyV6Qm`Ei1HlZ40W zwR+68jW<@kajTsa%`i`c{;YSu?%1$t*V%`}Y;qZsl z6o_;8cQtR*Z?POt2q*f4xl^gvncicxy_GVb;Q02sSFS6s{79PF#kuWhGm3Ry z1{uX>3aPjD(k51by}!j_EJe*@eqgP@$usdydFqynMp>t948Ny53tFVtwe!?ECsVIp zL0v|`h0kEJu}i1`Cw>a&r(?6WlxI>?Mhc&O1r|C!ulGmFMZ^0d#c&82#p;m#Z~w*uf>nJ<2HxW)T>v z(Nr6UB<>>;BXBy@)W)Izg-9fF)$={q)olldCqj}R-Z$Ezw2;o@w13milIU(`7(Yyu7&l99#}kSg9oo zdjIu2K#=$y3OASj9Ho_LQcl)tw{0RpY_eug$j&Jc$W2oJKQNusrDcdghT|4WJ)!7dWC*aqTE?6Ik!+42P26uF>-j<>w$+yig@FCc?XZCt~c`fceT_ z3C5=Zmka!3M*vvsg5|zx31*`&f;Q$18fU%0N_4qUYWgty6YAodw(dp{ZN0pb=5NKK3X57hdI&6Pov;WDYxL+RSd#< z^hFqeGYe10;v;x$#eK6GgsMovp7oe>&A6{@*$Iwu`*n_(c!hDtwVvi4px6DS4jqu{6UPf=yHEXk(^kh<>qR>eu4T-uRHw#%2v|gl}TFf48eE z-p;1}n^5(W8-CgXa3;wxpGPdXjL`)a8$4v`qN~rflv$Jb?-Gh#&AXWT02}K(x{GCW zSYRz1vudauaqf+{w9J<5t?dWb>nmbSrBV^LC!($QAjT2aGS!B=&TLahldTj?OF#{51>K!}606M0tF@~GA!Y$p?^3)>l6mdD z*nI`@Ai5LWU3H+8p-}3gLZ+FkDW#ziW0uxuujq`hL~g}}kR}Ule3eJ2o~i$Q|vZwXJ=@2NlLh2FMg#FKAZh zR#ny2-5tB0(rDVm^!?vVZEtK36GsyhV=)qcDWp2brznQK%;%q;YTGIka)wyH)fddn1P*M_OU)tIr zVdggxz*9(Hs=tm1(hlwRO7VB=lrU=b$_mFi83F>H=%?^|)7fkaRQ$h9kXiS6NJ-*y zjjHzi$ao$)n!Kv&Pdz<)h~CEl z=dvcTEVPb9DYudoVKsn8F3aC zn4ENRO9g^S9hPK;$P3qP{%w%rA+J3-G|m738wbbk#bz+n>@PbuZ{OH_UQ}7Vzo95g z#NRGP**{#2`1iX|f$ep$jH(0csZl4O1O+IBM_0!Fk>q>e;dUSE-ySkdiIuM+H&r&Xcf+I zZB-&^PD|7qfcM#Dt$L;dEVu|0<@gRaxqIBDc1Brt;h9i(xd>+T3GtAZ%s0HVmGHBI z+?PIZNr>@Wkd)D#52RxsatSX!GP_NmSh`$Uk0F^ZuP?^bT4rc(8s^(o{#%!GP7Q1v zw$YJf$m_`O?&x%#*o`vS4`p7fy1f5k$}BGh#EXhj1cE`&0V^xVFBNjbAFZb8(9T$9 zQ`$YAw6wsk)B7oNy(i^T0)!}$=QTosX8q_QyLkG)i}(=WQy?Z)60g1Qej0aNOT+x5Pq|GHLOW;nSb57Oz)4EYm z@QJ20-fhisdbyb$q()qC4&^nJtDa;PE&)sWJ#T-CQ3P3cwnhI4c)GufuH4mQtk+li z5)U`145oTFEXiR`P*W43btRC1kJXb0#}m+!G(>)9{8os6tJuy#XM;Hj9#!anNr;tP zLvF#EC}qG+k*?5OyAqf!ApmvC5uTh0USpRuI__YhA+!H!EXvqcNsF!NWO&G8{Pq&h zyisOkHU27@FF$-EC9p>JvK9_3Maiyt%xO;ant#?WIL#v^jxBZW9;`%kvRSA7_gLAg zjz?gr?XEf(h0z4lqjS@~CN!)3WNe&`6f!UEnGLK!b9epiFv{}lOphADy(iN1g49(j zw=w}9!;kn9<&XD&2UBcEC7uHAo=9#Bcu!2#ujA*lNtr#*ieS>?DZ847JP@AfF=^{2 zfA7t4U7BCmJJTa@04f1M;A4*XU(4_Rhd12RZ+R4o_sX~aKqc=#P{|F-3ih{(8BkVs zP5N(T

~3fexfked1`vefL)%UF{2OqKNX!o@HO&*4ntZbiIX^2LdJ?hn;VlJgGeQ z7A#+OmzCZOLHG8lsa1U17Chn}QoE`-PLN@ENb_y!E>zBwu7JKh^?6P@j!|CtiO|Kk;q!q$mBLlH+Z*^w{1NE%C z+Gjytuy8iRL(5N!__5MWxJ3ms#h3!1+cM-&lnDKx8XTT`9 z0`t-Jty6fDTF*gN9CrHvB2j?t-5IKR%ls%Xgt0^Wb27gO*7D^?0#`b^9|0}>&?W>( z{uZQj`SQrLBBM1ZK^sFJwX=C(9g#*T3ummu6=lV9dsiExRSC}YZ}$)x5pvalNys@w~PUvi0D0 zNn32r<}YYF@bauDKd(X%73;1JuUlq*O}9oFV9Yg&vnx0=X)JmU6vHrIfD%OD0udau zufT;1=hG$tS(BNy;IZhM>s067JN{pRlZ{z@&~2K8J@6Nt=t<_0_YyDh4qG6kGi}G8 z@teC5CHq4L8>%o}^JI9Lv{Kd;_QBoxBqy071?wB=jpHw z5#itMbWq68eG2&@vcy&x#JO*1YeMQH4Qet9*X6XQWM5+l!{% zM@zctW8jm0a%me+EREiQ_CEd9A8HI}%oh&iy)g(P8X0y;x*I7SbN&1dY|QgyHUjDs z*XX&w-+S5ZxiSs+C@Zg%w7zMrUhsDd4K%o@t?NQeYZUAhgU%vwy1TskYSs3b!W_BF zm?#~|o~%2!%~kE6J){h}SdeX3u+aAuP^kcZmS9S|C380>}5E_(_Qh6@B3O#L|8XTn^Ma20J&qM$(PBIw4GkY_HaD<70)Be zU{z#x?*e)LgYK9)0HHntA`(K9H1G#)n4BcJ>6H1rD@^*>)u{xOty53qqM>u*)709$ zq`oC#py*~!c{?l%3(JyA+T?IgIB@|6D6BNzg^TM`L0VrEO4>?Y?v8cP|30J?4;8ym zN{M@}@H0e)_(Pw2#nDuq{dhAWi=8rgp_E6L&}?0wg*e&HV%xtLmw{00aQTeKDAC4Rn;^7k3 zr2fYKc>b8O71hpXd;$ik42CZZ&Kc6W>$h-gA3v)V5eK(?nYo|VxhJ3RPe?kd;ZU1qMmsm*7>*9v|lYHqX5Hm|Pbxf__j4O{rE%rL^+cZ@iW63AZMMWZ75iJC zqJhyu5?5VR8+)Vr9oegCow4e@^kw7yhF#n2e2^DcLX7%u`~LoO@0x>I!$eKv51de} z@r*@y4CQ$wgraaOI%_w*Fw$}ANIK>yh8o^0(Ym^}5CW=IqvE6=>X;2u8dH4_ixVqK zO?K27aSSFY9-M3TG=bQ~hhig*1)-Vf4~-DnYg;SNhGA!3X4_@I-FZSiPf4HF@k$Zk zF@eew<>yD7VP9;V6~BRw4UVG{4*@q%D3=AiXUfw1z=PS2yE)geo3d-&)xfrl>DvDk zTypyh1exTS9VPCE>YPhgcE>*ch^o>Lx9dFM)NJr3Q6|q^mgpn533#E}`-5hJ^=r`W zvb$_49VOODbNzN`G@}|DZ2(&5EjQ^+9Z=K?2~LI)nky5%Z77HtUI-Objadj5e%%?S zVAf|yA@8&U4iL^>b26uQ+u(Rk$^B_+-$A@H1*Bn0BR*S67^h|QGXi*R7Ut~o)VjW* zdH(L|rkCqNhNlwxlVjjY!5fcev?9V`6-S zp?P8Q!KG7{KKll^5>w<| zq>Y9XiO}iyebaW;L!p&P>kW>kI0B`!x4uU)wrPLj1X%680qYM|(jtx*MPhw^MN&Te zezS0S0>hi$D+BYH8f`%V@pEHW1+n@Q!+(+5PO^bI~r@{_CIaKUE}E zA9b93OpY@`ysV~CZ8JHb(iw;FSY{|N!mMx!*A4K?9Q)9zLDD^ege~$g6Rhxs7;V zbk-mB89esR1zr(S^R!IwL<6WwTT>krlb9I_a;2#SE3qg7#wTKOkja)uo-l+R{%Hpa zbFkEoFcO(VVcj7Kn43mWK8hzlEsF+wruhgBzHgNqIj-u{%Oi&y$f~kD1$W z_=_Q;j(_0ZV*dYexc5=Fp&1e!_pv3Z-ZCi|m|XLVO1xdiWbumB^y&EHeXI!pHV|D*lKu-;8rNF&TmSQjScF7(u@vWz3u9AT zuQH+wED-8(4wnH0`apg!j_t)Jirt=DdWy!#5VO?j=32iH3jd?o;iv(rLBtH3odsOH(hhQHr)m@nZi@VM zG&R42GDEqFSC`OCOTXn$hTVl8$lz5*LXz++%-9f1M!yfV>a;Ma!oJ^wfwOjbrxpzp zf68BE)1rr>DBQ@!F^!nt^1l<5WLx|Cr-QR&Vk(iIV9m}BH8c!vV9i~0Q}MbbkCH7g zQVs>heurQ*-Z!e_kiY^gNxJJ11pW>94Cp*%Ob5eKzhc$Dz@=wEr%%Mp?8KxFXDw$9 z>O#a>l;Lvzo?0q^N$!Y9FGN;-Yy)fT^j2tYNT>!A47K72I39Jj=g`BQpyixzpuIgn zY~5+^@aP);pQD?mo#4TT*N$6M52(s6JQ6F9r+zg)U>-A)S%!AD62vMfT}c9#Imr(M zv6$R{fo$G@Sw@Wv$ZFFg6)Km~B}-z+>x(fpk{RBZLVSIa_txc3JXLv|Bv7d*EJ1lAuQ-qGiVeszS=bSuAMOQ(CQNgN#q) zyA{vDSwJ~g2Y4OzhscownCo_?hMU#m5mr>!fAmwacq7-*q?) zQlobqO2*m};^iAuHY@W$Lj!YI(qZVD!yunrA&byolA)J9t#^`OvE?TZoHuPzZ(?(Pk~`=5C3+>-pxhu&B6{?P zxqD|U#g_-f$jmge*`Irw9Toj{rAeSvzQ1a%t`OidR{Wuq|Mseoge7d*!tUhNUbUFO zDJZT;rKWuGG*?@GcV27$m}aI~q;W`yNX8&n!P|LHe8%1d9^3(63tZ^QXK^Wp>@k^| zIXBlg-pOvw+FAi%l{#HBGcz}Ddb#Zz2edNhJdZ=mFLu?-F;<+D?JOJ}{E5V3%%{DX zy3YbC&Dma=`=9w$j%bvwx5i=-FCk_OOf6bGiiRe{cj`AXZ*KJ%gRESS^%kZ7 z`oK(KHy;Yy=uPmS$3)-o+r@v_iPd)ResSwWA9 zNek>puB<&7V%fNxl`EY`VfkRlG%2IZu?$QLK@B)(i|in*LEnjv?|=Bc?O8>gUbDJJ zL9zYj@r3iRr{oC>(@A5zb|*#r(YuiJlJ|bbP5pWWEk}=n#42^Tzoq-j-{0*xp8y7* zF|yK`Se7Glvg?>+*UiN0O>56;Ywbo%QVVyG*GjLVwJH^Sc7X1te%KSs8Sv)w(}!2_ zdP|bP;?tz~?OU53Z8iK~Xbi;o2BUyk!_6AIgKFb5hcRw>+fpHckk*3V*v;uu z)em>jFnh}#?WUK}6C>H&u0&kl!HI?kd!COQ$67}?-}jUo-c#&Gw6*!Cy;85DK-b$#Rx+6*p{Tq*8EL+Hj=ZkeB%v$^gVUx~U+ki)M#Y_{1{Ae9 zrft^#QsNbj$-mE&n41(HYy%5bo(Rp!=j~s!1GFUVha1pU@&LhRcg_(AlQf_g1?lj z$zkwfx8U6vZBT5!wgO3?J(Ri?E1RHzz zb(H(8!3xg}Il+%R?jSh#sC5x);pKf^Npds2h+~!zVA`O_>MhWv(298Ut1hv(9YVUO z4dLhpvdpPO8RojbT=p@F4idk;_dl}$03!OupBMczMDu6Zg_f*1?2hz-e)~#yiV|H{La#mkKX1a;o{l0 zidMUy$RKZ=)-t_x3g)aNPZ)pGBAslV%kogwoH3D*>zds$J@d|X#qkOeeR1m11R#BN`s`0IH2Cp7Ta zS+$^o6BVEG=!umNATRKo{?w@kkTD>X4cZ!!YQ~L-WaTDD#Kw4 zm@%;GyNvCe34`O5JaASaJc>7ZKu4|_XY~l#Ib#WH+tj$pax=wgO6d`MKNnis0@L|U zyTz5Df}JalCs$C}$eCT{-B{*QTwO0N?^AR^2M;#L$(rAMDICy|U#SRl78!a3TRyEE z#y4(gXg#aqpW1>XEsbS_E4O9qGqF-2U~qPNO0p8wGFC&irQokW9KbN?b}VAB!T)?_ z<^OMX#jY>+Yb#76Oa{xw12P)d=cmUBk!hi-6@*ZqoJUpXv0HDx#PMcXAxIB z3h4+Cp3eHrBwBJHj@O`nzATgxQyU3wA`qTFn#?4ovLUudpr0Fg2@za;zdc#vVB6Z- z3Q6^G5s^6ye&5!@p>9dw3yjZC*kQ23P~ZXYSEr(`S4}!5r|EDOAvp9Two7*Bi&U6$ z!O{9a0d9&yPI+5wEKVD;DqBPJ2L)j~xjz=$JtLneP&|wC{ehPTs=70sjjN58RWX~O zQZQ~jQOD0z@3wT0lv6S@Q=s4wBWO~)Ws3#D=kxsS`(a@8ddqh!DwwpSY3NG=-Yn~t z#OTXOBTGnX6$ZyA7qj5!2@v!@{@V;(Ip+#piyFi@Cg;lK zZeegbVgyWs9JeX9pa-)kn_-%TOEFO$`4!|pI3FwW2$?XHo|(*aP4=bkG2d{}{UPs^ zg8t`XGQwj#Pdr$vH$i_Z)W;(0MRgW%NehaVhWL^&Sk__Gyu`BELXfo7+wsy$jF(04 zPo^&|Kha<=dXDCYeZ$l%E?mLA$I_&O-ArcO<*iL?Mw0g>@o;+*6v4?!&8093PwKMb zTMGniYN4apN6Cy|v3jHp<#X+9eu1TGrUUE#F(+vBH#9aiKh=~WWcU^z*|uJ*VLYny+%t`xmA9fOWFV5&hOxu*I%B_xLy?P|lPsAtD5 z_yE(rL4qJbC_AjH!?I+{`Ue2uk{@R6S#h{GxPEjk2Hin@5`+JY{nch`3Z1)o5sncU zY4osww#z(X*bS8)5->Ux1CwdJ+3k;TBNiEqE_Uu2oJ>A3s+0&P`caIL`T|>Q;?Qc- z1pO=~M~uQb(>2;5sRsQVdKl8KFU-v=b2g$ZFidu=iPP-d!Q`m;lM8(mwbcD-T~&nu zj}hpp%L6@i$w)$$^|Y1_?WM%kwZh+VMXEJrYuCjl9>M1d1hm&Ub}CeMkGDM^piCDf zm}$pRbj-R;1C{XCKDZXTAwp{gJM~`|cH2l$e=K&ciys!Y4^2fW1`}~8@-^*H zrgB)J$!>M|`R_(Zvp?L&b^hSx5RKBD?qtMVF)ibPcuZp~qM#TJO(NhQzFmVTZbN}W zKr_sW(Sk&{pgz;pk9z59bnzu3n|j4-Xn?EjQ2wZO~n&5lpF~Kv31JCXm|HlNXXk62|)}VV=SHX zpL~$MezOt-w-YN*twXC_&HJ%QEgS$Jb)ix^W6IkCfbmk*bQ`x1=QVuRu!QZyRMHel z=ANbGkDAvE1S4|czKi9qjH6%n!BWj8&u+ci`uJV`)4x3jxK~e;)_ncY!S7s^cew(~L7pt-SU@<`L z&q!hiUg?P6U*Ku8()dX1F>c!e`1U@Em-eVJpI%N8;2Lnu)@cG>>J8i(cq*2drSk2r z5rS{{BYk|cd|x*QYVm=;ZKac;JsU}!sd#pz&2=s1#Q-+d4#f%`XF_UT@_@b+ggXQOH#S|f2Jly(<*LJ;3m zwbvOn2yW*fIyP+sBnny_aT&r6-$pOH^E7#SUaoGNAUl3?4)SVPJ!InwF(nUlRBrT1 z!43dO>Q1Ww>w*3l_EDVB>o*ycG!{TYhXLM7HhVf>Z@Amh*-EHEAK2 z6(5g&XYcDEFOb%oy$|2b=|h5Kn178r4)yvA-J@-dy9LpU@dNe7N@vFa0u?jofdZ} z5Zv9}?S_5sJ?G3l`_A0ib7t<%uQ!?e_`baFd|A(0>silPinFGkVgCkM@C&(|3tN)F zT5($zahy1u)}^$8;JIku#vEFB9GtbTlTLUfOYgw}`3AaddddM_40B0nmDc1o;yqhi zHliURwckmdi`r8;4@U>>C%s?KF|o~Udn_@F(ILbWUb1|*!ve^%Hd0Rg<{qJlYU6)o z5HXt;(`Lhn-uIq@@rb0`k+}w{k`8;Yyap&q-rsT%k}0rVjB%Nn6N^q~Ybmit*6rcO zjzaqmfw%`lU(1@AbfzIc*YeUwkt=j)%eX<0fYx0sZ1#d${HCA5o9Z*8;$GV)uu0oT zxG3W}3H7$mM5ZPmUDmYk>BA>wYJ6n%hdhN$brwjnPr6n*YibKg*nNJ3tlReD+b4rw zaCbc*L*YL|hT7BcPRW}ig~Rn< zWAuwt>k`Xq43-_|H(oiY(iKp|Tc-EX496oA=W6Q^L3jRdvs#O4)q<3*#rmq&8`yy3 zYzGU0#bu<;xt_4PQwbc$_O6g_A1o*NX%`w)%C`Xl+){1ByM1TRO+Oz98x}ix5C(+u zhRGCg)_|qM;$5n!TbRFXEm)HLj4=Lbk5-me18FINl{4>kM5Ng_KRHfle48pFKMvDf z_!Y4#yKCG(tT70%97gV|z#GNTm6Mjo;Njs}S$UN^elBvLeZ4!v#v6D^S?_>9rB1-jmic;4 z#N+*J1q-*RTW(tgz|onyddt!NFjPM^kSr} zlKL9%7h(3)KH?q0jPGzk)Z^Ec+Ovl*ZsK{8F^&gdr=AJEc|tt?Kks?P)(7#}vkllh zMI~@aqeMgd;O-6og4D1qsM=by|NkO2&)aYYpBhLVsm+qLK)St~Xbhfz2PFQs|J9Q| z{mwCts#`&mySckyt3{E3sEAP#7IDZmP+>e51<yc@;$VY5yMAY7&T@Lm^6&oqm zEp#+&nZXjCmN)L{U@j!turC6gL5`Vd%W-%(VXtM1KT2M61Vwo)0k6N;n@%=u3PvGF zl^Rd`ghNqUQ2LK!*tZ;=%R|Esew@tZE>*t8<#pN9ALCi=*fFZXa<_h?<+ZcJ6n_bf z#W-AN{~Dz;9O=*7-u8vmez^99iMB@?uZAiJOiRxTQghc2QgP!V;89IM;m^rs;SR)n z9|XoxeT(xyFW4y-5Vix*q7>qrVM5Qz8A1!~K0O9KbdUseCfJLrzPl`>e*jZTfe%lD z|6H66(XEIg8sa+5PcZ8lgjE?dEHMcOP^W*>*F%ycaR!?G2MrW-+s9iDwhcSv=0%r; zc2aW`rUvIm+F$EYP~=njw#kjS@Nma3Ea>aHnm=pplwB?$eZKLC^|NcY^PC2;C%y|Y zceOi?idv^ZLw_C2Dz(2a1m6a5+ZeI1lg^edBiKC|uL`mNQS>N&511|gCNPY=ijinL zcy#R7*e3W@z3bnCbgZ6gi7Pt|f);uKmy7nCn1--w*=Gp+>h&)inif(T=zd^rA8yM! z>|=5LMt67ql~$$j(YHzxE}qD;YtzUZT|@EDQMNo=xaU81>d6C@-8Yv%axyS3gy|GK zpC#;Gjf6Ve6LcMTgs_SE*e!U4!bBJ+W?Z>%8vqlPywS-KarAkcAN;?yZjQHon)~Wo zBLQB2bcKwnGWAQZ?buMn&zdJ#uvDVfzT;%M@Yb5LQ+ceW64OxhK6@hn@hf%(tA%TH zi5gJ8%s54+^FZ^>9<*nbvJg`!%xxj4!tUKPIEaUPn;yk8Cp*F)h`IGqHU(i(l#u_6 zwAkh9k;?C11S3{hLCXb7(-$xI<)-|ehq;T%?l&lwbDquf%wqI z%ZvEu5~!rtIp?tJQ2`LrBp>b2WnKaa!Holqd%t? zOAM4kOl-<@p!a_0q10nk03R5kJnP$pDX zgU=9XEu%jxEEzpKOlt?jB)QQ?rt2xn?YSKsdB8wAOx7bfvA2gpgidZvd?!>RsWG=j zj_gc0U^-`7z*pQFplFc6%@^{vglm#NmyAfdIGYux`9_7aMt*&z?r?PcYr38lufv7U zP@sZ-r9OHk4VnIJy@wfrh~0H{pe*y#mgw4`KnNc8um#~F#jMS5Z6@=xok#B_dXO4S zT@XW77#>t=f)MG;GSctZ$mk{};2G3lBgHxXsru2M)yLdbudaq#+C^nSXgsL%nR&@T zI2=BK+_z#T&(HQ8<-G{06W6;tW!>j&rntEyFv2W707p#)T8kW#zMs=Je517!ccSsN zhr>32edmSvsvj8}z(%tgjw>h_zE^aUtK~^$pcXt6k4PX{uShnvWqs=v5D+CwGCN?I z`WXe4g=)=pJr03bj%zBw-UZnw0smX>Du(WDzUW76gb1Yb(oM^bU0J0UeG~|zin2EL zPkx;{d&PFYfy_*zF)*qNCrLi#Z^c94GK&wp3uCaAmGG!25qbH?uD3QmPoq7khH}Ta zTsHECz)W-ubPZ%^&=cMhn)gzMn*mKeqVSx17|W#nTc|P1l-=@CqV#WN@e_24A0D1G zklH}p;a=xqUA)a#OHHgLp+(+E7#N{7mrkZ9Z5|WkbM3Elgk84oKj{<)MypBSSieR~4|?tk~1LW7e&t|6hWWTz*V93bL11su-46 zzOVLaF0^#{%>Ft$fvHB)Fd7YzvA0f&^|@^)ZVMHF9oCb>$H@&te4HmZoEy%lQ_0Eu zMwyu#tV|xeB5^*Z)TnVKUF9hl2%sS+EvqwI& z2QSKe5`Kd9-dlW+n$xcrA#vmn=!HaZhiBsoI8DgZ*;IEbh zhmAXMlf!*`2BJ_>99KJo2#+O$Ln&2ueZo=!W4*fnq{NEbC1%mD(27MU?nolBT(cV^ z-lR~TeSdv=!(Yaz^_)5tX7^=f>hkxH62+nRJGH{CMJFR2U+2DD)qLs8^Bh*-_X&Hu ztt(f95+*0VztcZjo6|W@P0tgaJ_H7lImH0E-L$*n0e^5e(xQmt`arP!*@EWj4B{@{ z@gso6(jo1lNPC3C07Hv+Qqg5v&x1f%oWQd+>96D433Z1*bfWs?iv9s?9u_O*Ya*H9 zxMkn+_~a8KL8mt6kUz z@$ZaeDC3l=bACuKr0}$#usDgLtR?Qs0SF_%OHtYSPCp)BlT1o$F-%b^0I$9P-fED$ z@CM{dQ+ydg%PzV{LP}FMAJVMHJ-D%GK-ix(Tg_u-HN`>>$+1^l>iNED8zGd$Y7H=_ z-z1BRT|q%iVN~JWmfM-Gs!H>?(bn!?i|w%JlGNC*bY#eFx8X^(np=9dC3}o_TBgjn(oRaHvF*!gKt7y@0tRk~zgNNk zZgh?vr5Z5B9Mn7cVh*^Im&eY+G!icUYjL(Mo1oNs0vo?oEcz<>v&w)i%^XPy9(ryu z3iUBZ4sOK-!i9R!`8ZOJ^Obn=+wr`YI$C^D4vyre13GW!)zOJd5EGPjF-O{sw7cF> zaP8p_xY*}dpR%tq@KBM?cTXOxDNb_2zWASUe^ko^rBWYxQ4hqjCEe}fe4oYT*c?Sc z-PQBd@hcp;aopf0q)~Gx>A9nzZwk3ONi#^+zT>V+y;!jfp5m>k-U-y3B|36s%76Md z1+xrgL5!b;6SNWAy5SasiI4(2HLhpHL$mU~Sdg~`+{u-FM4|(wOtqX7hkou>jVl%r zKTPtxBr{(`H&2wRUHRcE%eHhg>&Zb5!C`rA)NhR(>?XSt#BNNUG>}$Y} zRJT~a^7qwnTqXk|f5Zt0kx^WO`;27od}oD7DLX+_%NH*=JGJn{iaw&4ev)7JU*;jOjp}An9x~RUVpLFAJGCtj)Z~fzIBl4g4eXeB{qDXws}0{P z(lK1`lTYbkr;wtS8s&Nyej%Db=$@ZmOr%>p`Tahwe6~ei_RYXvzds%OV*;BJL7wg; z^&1Q=%A>OUU7yvM+na++PwpsM$X>>azYGkU{uvmiTdKptaSr(iLo{*qHC$mPiJvYy zB(NgX$`E9Msc-;a_ABEEJ;NaH-TB6O!dhErTvID=0s&quEg(VSxZ&nZNYdt}KT?`A z|6mJ+PM%-NR6DaB*FBpx ztvkr>@C_8!H*H3$s!)P=bI-b8VUT)~IhnpcOrPE0GE*j%P8vxd#}msgd(Dg(C`-3O zcK}+S9w=7zQN;s2w-Gw*WXiGIq z{WNhgOYd}qID*q_Z>L3R@So`S%(S-&1_f+X1|Nj)MF;gO)9W5-s| ziqqYYB>uqwyE5hGnvBk9i~2_q>p?w>i_oL#MFq{56 zuA6pAlOE&z@l#k`T?Gbk+r#Nfpb9*;l=(V) zE-KNkPpIcjW3;6Q!I*ep>0HxI@5L$0de_3$`~7lgF7!R4)O%$!#p$mtmC*=f*VJb~ z7r$<)Qh~l$P6NO3)z)Pr@4DUzrHe_e3^fc}@5&_DOno*a>u4YXj(Tw#IN2!&t zF>8hEH1lBSDGSk9c(SDEYeQX9EmYKpd2z@40~>+2r9ursnPTHOxuriwm9-TwOmR8> z0f_eo*O6cFtWyT|jv|4RyqcCbj&cIxITMCfi07UAK0DZDv+@M)6yyZsaozPy=4uCvQ>KY$eM+a3uGJsu+kL*ZrEsuaVvY#mnG%#w9#I_c+~u^e z4lQpM%C>V0=;ri_l)EW=W*a?S62`XtHo^IK&2`j;Ykfu%pQLcgW3h;0fD-bi3Qy@K zzH&q2f{n{=TI`z6v|@!7y#YS@*A$^oEXFw+#Js@693u;vvm$iL;b$9fHCSt2W~$L5 zF@S69mS116+3}LDB};8f)uwA`IJrcwnZgfmH-+CMw)VD4TF(ca#j4U>7G8$`Dd)GV zs8Z0Mh*on%?s4HxbzkoA>&FE<&lXArDNl;Y8F;j+qgs zNL-*6V)S!Bli(Ei#mOn1Zkc@{q%jCdN-L-Q=LL(VUVXN!RtgCsO}2pcAeG!o$@XRG z_6Z(@SmVRY?kC8z#z9CMW_d^Hcu&9-JeFu{x@2%I2jzF)CBDba0Xl{nOFB%PGKuuK zCNdp~<=B%!H$WogzjWPt&41{+<@Y)YM$`L7Yx}!{6L^9?+=Np7hlZooddK!5VAf?B z-3_kqcunPBIJ1>zEO`sWofSEDx7xw9D1GP@6}zh0mOH=AOF!2JqOJI(|6Mx+oHHuGC9hhnb|m-ZQ9{<_W&|uGXZ0J zoUud6v}@JEBwAN-%rlzqU(rWATg>^YZRTFKMr1gypQJl{vH*cg)WCDD&c0wxL|}R`xW!o;QJj6S}12 zvb!2EDoMdTT9wWlCZVoX%GU0>|L|P0a4{GDlhWJyvKc?89V^QETVfb$6{fz9nfbDC zfSZxEH$*3~S-{F**DvZ+AU2)(jls6|S?5WnZyYsGv#;G;9&Pe&3FPgVzVW`UhelYU zsSmuEY`~F=&sdBJe=t!myR!Xf|5--rq z=30jj){}6AoE{(%nzGULt`2e`px3Y!D83oErw^ziqcen^QaFlo7)&*lIFCH&uF)0S zEp@ZLXhh1(EIct(dn-a(=aDA(E#=;*zo(SEdwyf6;RDyyZdb+|HN8^^hSWCK6g9w0w9n&A{q_^N*bhrXck_226 z!*6?q+HcbDm)<90ojJhgR$LiVZp;8Ox{jh&&)V{JxSFPp1W9LQ2J>~USPh0eFWq(C z*wFwDT+Y$>Q;7NsY%1C~bD89-8Qv63A`bi4lZTyB;zZMSP68ZayMxLD;^yaEZ-d#) ziEV^t{aKjiOnQG9jE>K&*aGx4D~olmusDvhCvi1#G6v@x=qmY;I?&(R=(=fdUHo>L z!FvHATCgp5M_fOd6yhJ&xorij){2_X5G_jxI+m$0*a4DAMt)CToupRR*u%nv|HG-3 z8+z}Mt3j_qf$Te8*M#;8Z=*C{_tpld;LA2wY9>DOXV9gps|L9-{J2%!{zH?+3yM9V z2Y(2Hiv{%30(e0$^Ij;Dv_nf(M$Ly`oX{o!F7%SNZU|p?a=%%+BG1=Dv%Jq<5V|~^;XNTj zyNA1&_@M()5=-Ex-H zkd6?jgv9X8b5`wv%thG8hS`oMXZHzh86PNT!XT1i6#H0$wZx5`f*)EHwhdCCUaKu7 z@%t=ciWF_PIqcmiA&6rh5h<}$%U!Hqx4do~)~;i$EDN^hZ+CD%EN#?C%L-4m53SMW zg97b4;^QRkwQ0b#3pw#0{u#vfVn1B|f0t$cJ)hhN&9CxYXDCr(KSI2u M#NpCqhX<5*Yyx0RjR7Sz1a=1p)$!@}nK_8TR9seX!>7;{fj< zrR@v>fztoa_frZT3jT)>&P7^Y9Bv2hGyE4M3wD*ze?{V2F2b%ZmiA5%ZgzQ6(@Q+;7-oew!%EHnGq6&44=R=C}uhhxR=pWT@E>?DC z5bXD;@E>R3|2d;-Z|>r5f@uBO6!#(i{Et}E$O&i# zw1D`DzZdo)gZoc^S0@uQh}-v|{+#+EFga8>6m$$epSP33lXU`;`p;Dp)wWHC#QvvU^p%R2@_*XoDO~@*Z$alYB!&-8yvIPmXn*7W{<_)4 z_qAjeCERoWK+u0vR&UN+36d#XhGQMfsU2li+Hl2%WJfcP|HGDsOo^ zP-LqYE2RXKdEF~94O9EA*`Rka70fuXe?L@o3jKx=xT9VRdKIC2XI`=lbM; zPuO)NOnXAVUYV_6w66AI*%k9v)-A-Adpb-tAOIQ`_A8D?;<>HIaif-fOrI1(JEPXl4sKQ5LOJF(qGlrz-Q)j%#Hdp&4j;2b^xZ>$J z>xlra#m`f7i$K>&c#pd#iFa>ZSoC9{hnHL5a#2~Bi#O#Hf$uVG9MH^dR<$i!Yvj^+ z17k+ghe?)O=EJ)}P4(uOXz9JLUys%g-=(>JyY#F;SpAPFH=D#~&HDBVm==H^KwM*GFz=dmrxE}C?r z?cnjc*49aSq303=NUVF)g(Yfp_X-^m<>IehJN`Eyk054$0^4v(oo#pL|X{t_ahzJ8PcF(D5J{UqxA_swXrNTdj}e+ zvDHjz8M(wm+e&23yt+=Yrw_WRgl1ps#5uB&lW2Ch#tD9CNLD5GpIJ+S>k=EG1lZXa zNIKj%{P2VT(H?1TK3}OV;ok;Wao(u-;$-01=XCx2cH}KIOXHx$1Lhn*6f6)Il40Tk zP~=bhs=8vVC}wu}BLucyse;i6#@fchtCa>#Y2_%_1aRdyiK~S`w?+w)hvqpe*s)p4RY)dssExrcPR4Qm2ct1wK ztP)(UxhWYPcw+tiMgO(wi`z?Q%!2ut@qFC`7nh6qVwLuohaJA)`P3Q(Q#^}Wg-*6i z{};69gU1Ib{Gc$4jgAMWn$ULkv9mF9z}iAUu>URYK~_ zJ|)Kd?*74Heitjw;@lw>J~&;Y9n4_L(tOEDA3@))nCFd`V`d!u5JX+II47o3$o`-` z4oU2|iL0hl=g!x{+1wVZz>9`@38gzimlE~$L}&Hl9H)OS zb!C56stF{rzfq2zY)QW{S=1Rco12!%Z8$Le-6+~G#`nvnbn4IG-z5(9;MJrLw?i2E zL6`*1Sd}%h8PQG775&Tk7Zsc4>-d~Np@U$u>*|$TiQivorSaBB%PP#)&Yl9r^Y?n) zlqa9WVQlTUCBx8mqHonZmXz#qMgwz3H#y*JU2eUs&$qq>z|5)szbI7mUOUYm6uPm1 zNnfp0YSC=>p1y^9URXBfPZ&6wl_8$m--O3^(r(7c=Qz3V(opfY!JCWq1}!3(1 zR*I}TV)?a%FZ#(|pdyh^`NKoa^{{wM_!&co!-Y8#v!$cEHF9qf3;i7F?)UQE%1mEH zZc%u}NV~3f5Om7;K}Pr3w9WGrqbqA^eK(RvvUkKCo7q~Z-$)BKL!f2%PRiL!yXetb z&3CdU4Xn)r8Y;>j%S_hR7>bv^K^>ZDqKjXNr*=ep=`c#BeZQ&a0F>-^`0Y#Ir@&@09gqYKOK;?G z0$cL9PCvIEJek!$_8rdr5v4TcVzMhM8gHKv)jBZEU%nPFi_?8b9`H$0i}QwA@b)2c z_ZP0oyZtt=9lUULx7o*tqttq&DJ|5dpQlNVvj7!J4dfSFFUc2NG@F)fsFvDl;k$U) zC$D~Ur4}Og{9OjEnqE**(kgh1UcAQvelrT^To3Xw0}1 z->AJWM>kO$T-QX_>nCUe1F8F|cBCAC5M0saW;}LKX!am*y5|Azsov>Aw6oNX-s9Kb z3^(DT{BGCi9*whaH5<<^O|-fGZ$;3J=2x5qO|PM3p8}u>E(>f9?tQ>FE~zHr3IVa4 zOBhWA*H*0Czl>Jl6e-GH^-vz(!``=3^&U*16fH{0oo$Y7VcVc*=Y6R@eF|HAvGUZo z&5TvFbhMZGC%St4`t;?TswADvFkB1mipw|su7&HVBkkfwj|r04GWbix_G*Cvss0vcR~LlM!e&1CUA449*08u z-6fG8J@&!e#E7}a!{FOtQsaGs%i%P9u?reSBYDZowX1<`^cC2G(JEh39`^lcDdZcB zc^9mlfC%kW%1EKf2}m17G|-T03OqgW72vNS5sc`?TI6VN9M%3-PgwU0)*yeLL`P;B`Q|+~-Q5dsv-Q_o*0RudfJ#Q6cT|esIOsts{nArEOQD;T zhpdQxV{#Q$9~YkFil&s{>bs5CrJr#|d;3B6O@Y+#qQQuGeN#vK_uM_IZPyKU!b3Ws z1$5R4(<=U74NBZgdo0dL2CP%oIQiji@Z?b7UDQB(W@au>kU`|(6)aT+-l@fO;>QOTRWbS3+6HBQFvINSX`;{#3b<%tRH8t?p&GH+QKJHQ(T^0 zXu9!Ao@FkMaL{p7Cbt%Udqi(kjaJu*G>8hC5oA&kKWX<5IX`nI)yQP;rt&1R7hzi} zq?6-b|6MvRw(n5oK`)|#gl2j&l+@7PzaV?nODIwiXo$A(#;g<7>l-t|mpU}bp z_bei!H&7v$XL`1qVE_Fo;Lt?CJo)&HKw$Apn1uOZUmOOzMw8@RLqF^i4aAV?((dVYpN{gb~r*;^az+@oPP9pKCRT?JpJV{iYzAjQ|!*$ z60}B$aLQAyGV9PI_dtC}`FT%BP!JRfik;=csjQE@M7`@Di>8{Qyy#tCuKVg=p1Is| zc-(>c`pZ*i9XsH2N_5{>+M{Lp`g-b8T@4h(%#u0SZz&y`lTHo7R6H#nPtZkG&4lM{ zpUEzkgSNX|rJUoY^1cN+y&~?cvnpQGs#GhmODQMakcTl?bhp!n;-^g%e5}Kn61Y3h ztlKC?@5L+Nd`DMHjUF)YAqTRsVfQ<&(4y7!0(VJEQFDy;-jrZS2y(Rzw$r;^b=?$l z)L2K>RmA=v#a$)dY@vKm>2=$P&de2|joLGlqbTP{saNCE+{ov}GWy-?HEo#P47c8T zUkLoT4Kccc$Mf88%e-y{R_*k+ZF2lzuAaE1#~u*B6~=^U$4qB79cN>)Mo07bEVl## ztF4Z1fq+}KrM$qgGhVS;7s;)S*-15;+34}vvyE}PA3gn069Ro}lk@G#-+Q5V-zsp%#+zzs}fODJF#Ir||jVD$S0rCE< zd2ie8YJCCUZDw;(z?uIx@H3U-e5vM;gktVfYID&p?=3emj>6ceK!)bW8(A{l)!%!c z2q`yt9HHD|ywI_itY1Oh1+ru?#B#6aOOrJ6WqKsu?^4n+w3y6$j;UsNiC@14eCJSj z`C$Ra4szzFMEj(@r%6q%TZ?E?;^O&K??rex+scfHt+zEZKE&2&9hao)yf#t+ZViWL zs|ccZc>KCRIORUCaVK{wN@ga^cyEw(lC)88FW)yu$Cl+0jCjWHQTUU_%CjnVa-TKT zCB69v)5zQKCQa1Rj2%hrZI1u1fO>IJo_Hx+AC`FL2#)lJMX`gaFHw3nD_TB<{$_ce z3dCQ?vjM$7V>hlHHZ7u0=5v9yF~&+O_PBe9N}-V>os`dlB$QXMt1n4zn0mRoHiVwJ zYc%u?1XspUMbI9Be01c<0|+ckI;?%tUXSNr!=<5Q`?A?7q!ZsZSQpXJ(L57f z{b7XT;M+Q4j1Ii-Kxv~!iJ?z?VNmv^iu4%wpI6DeUzkwu;i6zf)l#Y zEJK9C*@%YLD0rR-@CB`t?JS5KA8W0+c;kMZZj{}0Y?m{yBDJHAlr&i?p?aqcR2g*X z+_&OjKhs*O!GWGHrSwpBn4R}g=E1jN)p-|b?|RjN^r?1t=UFSx5)G? zz!sGNa7=~~(Hrr8t;GwG0v`Omu?sVfiOL!hy@j({wfN_Rw=_IisZH%WpBYl!^Hq?J zyv~gBZruBBG}?J!(P-&Xp|x-aC3_C?q|diX)|s)(NnYKsO30RTRFk5^Pn`=nlxOKa zYR;a|8@7A;q3*y?*C-88*faWo0e?aU)rB z^k2^$c^8as0+T^2dZX+EFC#R$9#uM1Yka}JpE!rJ^i%PM+sU>-?)Cxd^=F7`gDrM& zIuEC&f1Chr90x+WD;66pDOhe<>d(ilCYQ#0(fGge*0ZgQln>jnImp+#B}F9CtqQq% z1fj3*V#;jP>TY3-)xsoB@xOMz^DVF$3B*%{mh7Kx}iv|-6eBdtEn>Fy{-K=f^=qFfsg|m&9=&C z0B+Ke)@*FL$o%0Ht;z{(97*L+4Cjm@USK;5 z<7mdauIXBd!Er-yPc-NsS9n<_4^q6|IeMv48zxD?CZRZD5f;XUp_Yo_AD(IVwq!9! zx08$UczVmmYjVdE-Jn<>1L&kV5?YI%NT7r^s#1_v8c~sHe1ih%@{@;&Q~e@9+rr$?jg;QE#Sqq=P`GH!I zq8v}l(_JE(1#N{w*p)u5ph|o{3#+}RO9vFmjrJc(}qA27eqfYk^393ULzc*?xPNR|2)>kq*80|KA|qtL`K;RG@+DP{e%e%4|Y z9x7d<{j%{lZAV!9(pE9&-$mkKYcw0MaF7?hHKo|&@U?E3`Pa*cbiDE>l>$a*$|iy8 z#X%m(#|m5hHuqFy!7B2^Cq8N4WqxIb_k{N9=!Z5>v$O1nAYz5? z;b<5XH4^&V+mJ)Gxy|ahti$fVntQK0nIDEt#ORD5PR$KjCf5PISFSp5+w_v^DwZzupjHnjfsrW`j)WG`1!wr1uq@153x`?Hi@q<9U3pnY(wpvc{ zzC(R`k)ipwCy!f0IQ%O0Ud$;;l`!?GAjU>D7kLep0B0YI{$B740cBu@KiSJR@gb#5 zq5z2|Q@W;9yMmuRsh9k_F0>%$Bfol4+JNz;H2zvQ%}SIa7U2X-gg)8Vpm(fUZ}wri z%JWVrQXci^m*Bf-Y?P)7%K-3`vjxTWP+Ve6wt_;NZFr$fEF~ddm1_(j9-L|a&X=6UR4o}yMe|w zzx(u#Vl;{dv#{v&c+8jf5YWC9PL|gWlP>!=KLDlh*Eo`U!3&zkhdoB%;XW`|0cw)+P;Eo7%3qa2OHA7>|ROk&}gBzg67 z+%OpFu%gP58|3{aS-1t>og%UKv2GOs=YQ!6a-*nZ2()jsQ^D8iS}x?Y{C8Of0`dEZ z@C`%QR4;41hzInmuRAk>iLTGfVWb{?YSY}#D?1^RhrY%}?y><+or}1>G9Ef)V`0(g z0GAfIN%Ui3;~c(OjI{#vzc!k@cNh&hzD-X9)d}&vLZKnbu_hsM#k6C%Kr=3Y{r3 zX7-tX9Q`=Jcz&Kvd%5_--At(wNW{u&=tUB5LuYwvC+p`w)L~%qD7H4;**x!2 z1UH@tB}dbCEtmnMMYbNtlO?@n?<>PtTqB%qhCZg!RcGWFKjTuE4+H+U3cr zhRJv%M`+G8yw8%|N5%n{gA$%@9#JU#xcJRTqGOq8zsjC;2V-cD{r?AvD9mGbIi$xDqY#mRm4<9sS-?p43P=E!L6^q9 z;VcbF`&>4(>YPGy{xOl{*k?HYw#$?nBT{6y!^il4r@~krhR72cCQ!KSBiK&N|N9KI ze+&YsD0NgwTN;;L5vO&0OJBo5sy)|34+3p5xV;4%KJ93^6+<_w(w#@6UJE2`F^55! z$M*ysUZ`E?63hBERoP<&z6&=Xx36hk&xK0VId9zd!o{sO!evZ#ZdY)N)ELyZPpl@g zpNF4h^qOJztLl%viP>7YkJz&$5MU5OU{Lz}{^lJ;2&ljc;rk~f`O8iH$@C=n9Q{q4 z7@jK3>1s$jE7~JtcKP9&;MtAI@0kD?=`iO&?shC7;*$J6%1kAw2ib;$fX5nSQa-xN8Z7=f_C zYuzP+*V}UjzAf&4{53d`vi1$Nw&r{bvuK`S+TwYf#(w4lzc+DOkf6q(T)fE{PE~R> zi1^Fsy%v6NaSReTbQL__$bG}`L*$+tZh96wc}@Tf-u$wQW*vQ7)QR4CyLMG!vg3^N z(to+j_&{12c9wPis?<8uo{N0BgnnlaXrYX}0Z-cpoGpSj+z>&XPmumG|4D593yqht zL9!_m+~8#S33!@!JcaW|Z8t5fj;P}cZw8_^&fQPj@_X0DN7zV52#hhJ?i18-5}`SJ zQB>-O{W}yb56*(k@uE3S(fr7_OB*@%l_9Z$_lvn!iaR~V*WHLAf`j`yHHu1v`oHTW zD8V}*I)6ZHsRK9JRN2eL!GfB5)wl{(E_ayLl-sIK;GYmAfekPHth)@!6BsK*aWyb6 zWyGfwybaVi&(Ze$`~GG=_?2H9VU;uECWydMjjcttXoeL?>A8h31O3hf+GrA@Y3gkZ zD-*3I8IHaKM5IK=jW&s6U8={6j(;F`tPly{5eUs6j1nP6q&>O2Ah4fl#+%OG441KX-2O#BE9wa@xCS?DCAfA8J8}1b z!We$3CAFhgac9L$7iXiE<^A!5jHft0=G#I`#;6;j_~-|8yTiOEnrbJI?OG^yqAT%Z zSW-?8jNUo`n7tUZMllFySdE}?!)Bx$1aZmjDWwjOnhQFI!p)3xeyyI0Z>uMR3uW4} z6fs)1$E)w4G*l_!K~Z)8TW2629*3Xn35Q9!O<%CIJCn>pY0q-2G~ZHKdY37?p7$0f zPNu2s2PQ5jO${P5ew?x6Y(+@9Y@ds%IK`>6r2>L`mIS?~+N~@E4(?z_ddYK5vgfY; zJ_)!PG#O28pSCeP$E@E5Ejeu>gz)a}8Bj%SxLubmJXzMlQ)zu)4AT*WPNZcce{$Qs zaX@twE8R0#hbf`hdJutSV&4h7Fb(FomvEW>Z!N&r4PXG0`Sx721@d~Lt+N}O;2j?KdoSh}7fl~@_Rpsb9Bw?yzfGKo>MhLe9hYs0cAv;|+7@HE zynwTRo&|BHD$KVM6+eK<^B^^%2iC?^yM0}3-U1C<(!WNuGz;%W9RO|~Io+_8nWfHz zx)9NQV+6;nF@`%hHQ=qdxvr~jOH8?{wzP1xd2IA23R-4o#Iv?06A6Kv?{ zh+Nu>;9N3ZsgPrSxajZMM+I5kHl&=Uwx_WEbGNsN3T=Fyo0WUb4mm<6fWwhJ8)eLR zYx+6-V6Dy1DIsU2V5%g?9Qfx?^qqjHN&x!8mn6+DMxggN``sdBQ%C{b8X&*?eoH4Z*T$mK+p*4Lw{NOY_-wyIB$KxGD+_HWkSCdYf0zPE2 z+2uwe6g$0h-^j+im?)LWzaA`cuYlRULZ-1Ando;vg7u9^Cwc?d*EPSC2Y8qx8vsr@ zhdQSdFE$kX8gYIt5~bp(ei}8XImw>R5z&iO$^(-SeR-RNJ!>M23^Lo*6G)DN%oc>! zk*D1q#ky-t(#@U|T^X-5IL_}XS>qb2xmr71`9)w7t;FGxhMpnpq#-=bs~*Y0@7 zwhQMc6sEH)tQ@m)^{d2(?eo;oeoHnLFrP>oEGaq9x#i2Cz^!2M{t>Yt*6eZkYN<6ykjf_iz^5v5S4 zTJ{3JcB$=cVuxp22ul5p0kF09_X_dC?wvzZ{o>92UPvMv@onzd+Ni&`!sjZbBEOgf zo#XhuOVwp{DwqdDz@Z~udiMH{ajxa(S2?1t7|BDuZwxx;*E=`ky;<)gMoattV~5RJrFZq^rDRaLYT`zEX%nJe@qc}T=|b8hH7RSo^iS?GbWh43n?kl}KKwMO zLMYpP4QHVbi|hwgYrE4ChJ-ywNobCfe122!ohuz}IqTV~o#^xgN~4n(m`wpZ;;-9l z#nXhXp+0g%HI8I;x!UD|XFp_4je#Jy9BY0#y&_IzeWiD$oS!8&&U_C%jQd;Z^JD0d zO^)uk!z58+^)h9Q?@v^EUq(T$9<69fYv}jp5mExVXyxQ`VO}QZZdbRwNP|SqV)I5d zp!h%{tR?aKx9vfFB0d>Li6L@}HI-`1$Ae@WYG?!{s z112kT7RzUOO4=J19OA*(@f#y?eg)$)x)wMioW~iDTnLyWI{gDF1}ll z=l~&o<`ilxGjY8Sz?G-DQJ9G$FRmq1vP%N>^v`b~q{W2%ukKDrF~}|5`Gx{pi}j{z zwcpv}(q<==CtIr+a3fG6guSUfEh=|~Eo{vTeQq%)Acs9b$)e_`8KtoE-C9f?0k1|h z*AwvUYz@ynOODbTYSxC0oH&0!(55QvW7}<~B^q$#G~&$E``F(H(*-q7Neklp5J%@u z`xdpK>b}EDk)DkiP2hA**qFz)6Tg92jE=Pgx>1295)Dte$JDf##>5CNRWbYX`KMwn z$Ffn&A)~o^CbjxWV0*WcmxviZiJcrD!JSHY;kT zPY&VohfN2ELu)o!HT{jF$S~y+&Zwhcz3B!;lSt4}oW=w4wW)oyAERBr2|KMiQVLuZ zg@UCta=HRc9Ii)h#DeTodeg$v?JSCp9InW*%oEsJX6IM^t%n4viH!%}a{rf>*zVy~ zK-|~Lv>Z`nTQAi8W@n-?!r3rx!84M4bGr)78p9u@{Ix&+Qj6TbjvRUNPTdg5!madX zH6i@0;#`N15F<#JagA%Q0_TM(WPU8jtL=Jt%t^}Qw**W$ZLiiJShysnUeKo%;5RWA zl1AE1W-o4w#G6G|Eceg+4jDS-Nct=E+rzCr->XfK*D`LXlHnsbxmXkvm6|AM(@qZ4h1L;@NB&gE5=W6pvC=A5q9$Rr+9H@Y@T^^+; zf+t*f3i%cqyUJAJC%7+h>9hIO>S*>5dl=r3tqKI>^^J7s{!1gR*Lqfj9bvPY#25mP zStHFF?&j6?Cf<|F)EMlCFZ-@la^qz{mE=l$L@#duDf9N1>xx>#?TYKCOxDUcuk6y3 zdVpLmcA5<@BheD`uq9mG6ByrzPVAv3rRI36bEQ{Aki~$5J;FXb3{BsKSmn zV}+lbM*|g`1D-^W&mmQoP9MZ;{&|!GKn}b%_0vMn3q!9GO45VRJUgFRuRw?#8#>!> z$1Be*F<0y2VDJc1xWmFJ{JGd0t6*o+hLfMGjduu5gMGj4Tf`5=t8;K!@W#wJK|tkt zVCcnJ6)3V4zAoxru;v+|>*X;9A15uxwi`3)CrjMQYk|?SEHhWG94>hdqgIl^ef!l| zS#V}NbBZ$Yi+aTJA4K+yo_@=nNymd$&#Y)0k=Aqb+2?B5MrUg z!>xS@Z+SBk>pw331QGAX8~!uCgsr)}X2>g7WVL#S=F%3 z%(}tg{qb9ULfITDa~nfl9#2HG&r{>uoZF`HAe6P|M=*n0Ct`^gpbCQT0fh6U>z;U7 z*K()X;AJ#mX>r;`TRpOvqR{maX#eI(m)ZU!U-j+>2hTx)%B-DlUO zlZ%EZJkna6Cp)_95*e=?dDhAtTSJtLusjs%vKDVIo1}0%;9n+av z{RN6&K}ER#*mg$L%S^(nA4zQbzM_#PRBqgpR|g^^A7O0MCptt96k<8iGa`Q%(XJ&E z4RzZzjgP!S#&^EYh>T{H(2>KyuC^<)*O=m)QSD-MIaz4W{cuNt4|hxn?MKX9{JMm- z&m>svy2IlI&Kv&N`zcdAIyd4f-4h`gXxtecZW}0&k2M(lt|sNa$P@3|@;q3WBiW0R zNE+`;d3!UVufOM)WK8AoN#IuwlR7RYi*8 z^2!J@X=S=oDXtc=ED~9spts$DgVa}7Q^6s>3JQ7b_H9+^U5uV&#iwod$VR~FBtTu> zSAd&7s6hjh=%p#Lngssy$L>U6{Org7XWGJGB3|IVf0;F&>wF!ti7KsS@@LLML)QdHQJ?0)wP6KQS>U_P=G3FfUtJS*T%H&j!u8mIDpCA%% zj)q+oz7O?)+m5o$D-?M|AJCj+7o*Hc%=F(>3$MJ%%6dJ%ehVdjp9cE+JEXry7|+=C zm&QuYoHqy&`}dptMu)QlsU{ANr=o=XSw$G;c85FvIkU7l{3*$FHO$)ZlI;c?O|SJ{`OlbEK>0*FpR?zQ(T6Gx*WwNl_gRbbiI~C% z2pI{Gisb?L)LCnqTxxE>c8{bD>5Ci9AYzg-pw)W5FW`^7_nk{GCaopeD(BhDl zlWnFl4RVowirDvQHvmVY2VVvE)-zx{s+ccYZWw41!yAo)vp~^9q0u3j-`(|o9=KOW z`f8R$s{>Z~Ct14}Y@!h~gKmY)8PbO!D$}}V%@6J>^Qun2@tKFRo^~xbAi*6QBxya& zLf{=8YkRKS-(Vek9I?24VHldw_uM` z_L#OPs-=?U{#*u5W)kPeXL_F2ba=Oc@envYKCiETVvC#D9=8v-H4IL2D{0@{c4{14 zbRl@(Tz-WfV z@p8?MyVI=i@Jr|O)ON8Z<_96LR_V!Jozm&W2>x1Xr+T1r_OuZI-6GpBqwZyQ*j(Vg zLpjbBPd_VkTG$(0l&U|@Ne}dW1_o!&wz(+-b9M>6GuO%5?(e^Las(#?Vlu$S?RD+3 zUr8}_bdKDruBHOED}__#K6B>BL{a(sEr1<{vRIIDHw7YCci@a!Xpt;MHncZ(xbsLP zM!d#!U6Iq?Tpejto_6c;lvcg;lNaUNU$VEB14S_Q+_xM3>f;5O0m(OOsi$mOPbz1t zgE!2UOER8Gu05u|y#OqxzD(Q=6Cd#7{=e{JVcjbXce3n%fY8MMo3i?MCSJ-9fG_#U zt~1>CJ4Q(FMQsNAUk(GYmr#|AV>7FoYbEe;QPuTF#DksCO_H+5Lv#FGnfY()k>$^$ zaTlZ3|JH}`m6B5Kn$3Q?_j@6Z|#Y@2e1idZ%k+1J=jn;zv(Dk`NkJh+jj@Ct*= z)$_=;i@;M6)h~Yn?uI$$iH5%^Ca7q z*y|uaO!zgaJX2ZflG_2m_@F>U?kRj*;ap<%F+@y`yaKtO4NVoT5rD7CT#65h zC%5>m^4WS9JNZRJOE!HE@G^``tG6b~eQl2pfB(c%SH@W=zK$m%_axquxkMkTt2f!~ zaa8ABCq8Z;m!o@1*%#^k z_DLi6WqIJ1@w!bua=wou`~OfpBKsE$NC?l?MKDV<`7-Z*ltrm~bah*mOA+tru$^24 z+f+cW1yc2ki5tFp`Hn?qd%)1+aqOM3W8&V^%orE6S=x#EvhEm{0v8vNv+rRi@M*AF zHYlWXk^KH^vF(2?=1OqDNgmFw%b1V#VerMV41}(OnI@-0sa&4UKeZIz^Cw%0JjgLe zIL8Y(TQdWp+kg^W)%|KBq@~6LhO}+83@MbV4RM$>cgu=28zIrb*nsQxsSlgU{bRF~ z|JaP}!)D)<#ReX%BTDTL76JVnG6MeplR|5afCz3F_t#Z3MNWWTkLrp+qXL9qcRgejeT3Cpaf#W8`qfAWeJPHUdB1|!-<*1v*`;o z1vlRPOWu!$fCoFK)5&{29}|X2{N%$$_1Qw?b@QK9@@X&-A|L*IRos}W?+Ld{-g}`r zeFS7&OAfwSmoS+yrQgUppM)v^1`Sva)Al|_??02!cG-zK?Y~Kh{|i1(^tMUGa#m)v3#}IN8{>#NA5W91R>H(=R)J92+~>j1qYSGn`7;P(&ze& z4&*e55G3_aMp6g6pc?C%Ehqc=TW`@W=qOH)a$VT`;VkY`PIxd!_@Ug^BiWPbG_CS& zvu^l1fO@7YXV8rN2n7ZMHv;i@e&1Kzc&7$L*Bky}SryI5=SfQoSBGN6{AkiW$^8yt zpC(kZoQ``yN_MZM!uasre2%#6#QV}Qo43mGEYN*Ej(TXvlz#trDvz{<_V&r|{?`O; ztcuUee<#Z1JGi@z$a;8}Ra$=Ie=jf(%lDZzqw*)@A1>ywS0yXFqNO#~>A=H$Bi6(Z zk=6%u^*8wJQTvz&&a5X)X2V{r^PXC*bTZ2Dx6t(QF{4F@y){O%cLXV+4{piZTwGrM z8X5{??-2d|-o%U23^>{Phgd^P!6xjnM6L9ZXX5d6=0^S&F}nUbn??iP#4KWz3oL7C z%Trq1?4)2hSA_L6DpWGu!4x~Y|C0p2#sy`uk86u0?}t|#gDrez?gKBgJdbd z>7(7~3?=)dErP8WDQkMBU?*d<`Ss;PEYeUES1c`lR9H`*o?UL`>-A&@V*3HpkeY z?$Pw=7c4|dl%2KIam%G0#7;N;KYgl|E}@5nI4fIDG6P}Q8dH@U^4$Wv60JwLzIjd{ zkh&y|MeDz{*4%Hz*oBhQV^<^#lOf42Y&>{h$rN{XplTJTgm77P6z}?z=I0XkThe|c zj$lR$Dd&u+j|%?@U7TYb>MZI@jHHeUUgQ;0;+64TRea=*3|ovEAYH`4Y?85vtHtGvM%~p24CTgb_v;2qlTO~r#N1fve1CPp{{m&Y^mqTf3YoZs*yn)Q-)-wQ3;6aSJ&uT;v}vw2`I zk3){dINEysQ|%s4s-wWM(gecY$4j+mzh<9>o7ENmgxMpfeb79Su&5Tp8tjJXa^41?l*Z$uBwh2`*(M~t?e zDKCNdBjMI|`WFUfzn$dC7&nPi^-l-4odXD7o|)d3T@x>|0Y(kJaBzJ@$9DEI6sPhn z{?mlA*Yr#v{Ad@NoTxzM~`2P&DA~OUA~4 zP|Y@%9~a2-6JOhKyR+i}qU!zK_gsHc>A4lvJ+`@h%}tiYY={*{dcYgz`J13WG_^Dn zj58G<=i~NqM=S+812@aN>XYJ15N&M>pvpuHF^g|u`}jEOJTwm4c|)~jUY-MD4EXFz3tl^?^mR8Sk$k8kXZSeS;| zJunRT=};d*Cpi?}oFnS*M}7lHd21PzQIku+EtxEo4(qukTe%UwW4Zp1_)3uS##g0* zuW7VDsQL%`A)CwW%~gKCGKsS>XKl1(^h_S_U0K>YTHcz+u1R@Z_E?Z6D#6(8yT={2 zaq;e)un@*=w4xWu(57!_(4aj6m?D0^FLtx~)^#1#LP1lS^2L>j6&fXh)@tZA{hw3V zvDJd@bcgLVZDtmBoS*(wUTnKTK_I)kDVBI@T6{1$ht^d|$_%FBUZo)di}K{#7?4XH z_wTe!Vts4^Wlur zM-kg~2*9Q6!nI-EmxByBMyj((L+;3!4kF){)!;$Ti@IrBmF?{RC-d1hZBAoZ-lmgkc7xqgwR;tpzY# z?<7AIq_RmDKgTdh`CNyNejjQ!JOq77Jtf;DO7npdMgGZr$2g01gEaH6KUjrA^PiJv z6Q;4v#tOeZ#{NvDTMY5RN5Ur|dh`y*`X={0fl;}@goVzldo;f`qQap&FcIMf=>>nE zJrukV$rR#ij%$`&+66ke&TYeVrDJ2f#>lT! z{V40vU3z;rKCISLCF`G%K4rQ7?wekNltLW7B&kN4tLm4(i`Q|N-_~T@R5#wa_xmdC zv{Ub(>9#-q5c|YS`ZGyRcsOz{0!2yh^0La0F3=u!CIv;zzsxkqUYAXWOGotLym39p zn}9*Xdc*|XbxX0aiA(JoGBiUvaCA09s_h~Zq^L>%4y0P$%ay+O`w!5%7|l-&7a|rt zq;oT-4zrcqE|jB zK4$5i_4Gd5$m4(x01leph9MErQYM-csH#|EsO9Y>TT2wuJy85D3A7y9IX$ z9$bSv3>sXA0S0&1;I6^lEx7yO?oN=wT`qa=IiK$R0eg4%Q?+-kT3xlOVJwS2H1Ks+ z>T*28g2XkYYB^La7_evhIPN&^@v4vFb=lE>Z2(umxIV~x+t}PNj5=SQ6uMOVdH+5M zs96^r$Jd@S)OCoGNg{V?x5qY#QI#G7p_ariOz(2PN@9?6NfH+nI2CSAd2kyMt{K{~tS)E7jFtXf+xrZ`gC3&jCx34gr`Noy{$f|ita+x- zxdyaG0|xWBFn!wUM&iW}EjH#}N*&_)7WAO4*}0r;Eg~9T1}4zo&Nv>((E!IwPpaB|A4x3u zPO(;1l4ug>CsQtDJUjPl1s&baEm`{ZLi7cJXogH_pchLFINyodN13$3sYqLou8W}~ zrr)T{emhT&UFYBmLMkWiHBpOFz-!IcWAYK#hB<+~RWmLeene z=)+kqxnB7tM+s^&cYyr_Ty}}c1%2lKM%3%=;SDo}W6ftDL|Y{}(asUIB_HleO%+^wfE#GH_fZN( ztF8Un`wAL`&ZRX%!%!%G&Ke2cSFtvBr1iPmIrTMraau2pl5OENV$ss^u=8$o++DGl zK!UEz*3o4}Aqw|6Fm>x(0u$j#~tr@b#n88G)S95FzV~{NdyV z0gHB~Sek#Qstk!Nw?p9OCR&khIA>MOS78KYDeq|spXutH@qV!wkGUCjtPbT6T z=5MPIVL;aI<3Ek91k|1A;~Y>)qYir0bm#R%J|5KHvRLd5wQfj=sU#&GJI&A`Duzq^ zurefWj;j3h^$_QqFWP$bE=I6c4ieSYRT>9;Hc@+*RWe@{?6Ak9Im+ZDjM>8TBVO!k zNscniEu`wG6fnX3ibR-Q{JGL&@r&=`FsqLY;|AP))0tAA`8-pcqZymAPLup1&ZQ`x5bvLx^sFWsb zJ;y3rvezv6Vl0c-Ga4HD`hnWi%V{YsL_vM2*S@zmUFGQZHNN~=XpAQAZ(UkdCJ56( z)uSDd6u0C$2gw^9z83^J-=N;nJifQl1li(R)j%%HOy<0oe;9#f`^;+>h2!%>FLf9&_DSS360!_BR)cw<6GJ zEN*2zGs!Jvq9ip(8yINJw@HMxxj`m+bQEd6VbE5y(zDYl$IS=*s49BG;9^$W-{o~) zakY;gKW&uyghGQqLHv*uFjL6+jeW;A4$XV)XqEY5Xfg}$bzMw(w7mFBZBW!WJ1g_F zjBP=Y_N`g&a^3+xZwItD@4&yUZIK-Wgt zIWn!#FPeE`XNw1Ygj00I#`>HpsAc4+EoglsUBUI!{0l6ogENuP(xy!MOGgajO8Zb; zCJREA$)7}x`?}T+1%^`*Q584QDc|aPtl}|EUM-8Af&vo9k)#w@Hq-7cNtfw-7 zh(vU`A%#8;99?U8ABD1BmiL1JY3l4@L8JI=#aoV7+WqCI=vhc{H~eeWd4N+h|WbqPeZHxTh;XJsUVY?$k|5QywaK z-!Rif^);P@|7eHplhH!mwKVcVs$eF`M2_LR4yV_MMNIXH-K1#Xm_v{w($+9q=7Qi% zM?KzhvxgbW9-88PM8a|tC5ADGJ1k_3<~yg~-YlfbS<%Z_QZM$7eHrh;Th10IyyG|f zeMX9~T58L6->NjyfqCIwIM1>O&*y}}K@H?qDRNp9)y^DGoF&#cgv<7BQ#oesR%JYP z0CIJqbM?!!Knaeeo(afsFh3>HO zD8Frcd|RaKNVRl%)gWC?2^_Mv9q&y#&TA#{f!Zb zc-vadU*FL;WB)UG(nXeC6hFgsE8~90qlR6!5@yeP1$5REq2qon>tfa4kvtN`MiDx z@5-t+3?93nRX9BKs^N1un^bL!v};#K%$i0vf8kF$%mIAh;mP@6!tq#n>t*; z#T~(Uin*$dJY?>U#zR$}lnIZ4C|&-h;X}-QTJIw!gUBZAA7Tb9!qMr;Y4Gv^cE-~t zAEh3XLUx7V#_Ve}guVRO{_Ro>1yy_SL^pOSzz@0dlVMk(;Z-VUOuH{8iM;xaL4P88 zojVh&wp`K9-!UU7pp~;bwEmKhwaU|m0SYi&4-ycY#(dWT~@rAl*1%qgdP_!CQpc{ke@29fyG4=;K2#6?RGXFTPj8gm|eK zH_Ma*7(d%mv6<(=;CRKFgm3Xo-Bwffljs3%D@-x=j{zUX)ptd{>O`Wy2~FX+dA2SH zRcZuH`L|_-$jM@!2fxrrG%A~wXt;#98nTj?EAGZiPG8T1!_K2*U~P>gdQoGDUkfz_ zTSN;=0)8LxF{}0#n5cI@GdNXjscjE$;k5*c8F6H`=$jV9?W#K}wS1`b5x|3Fw{KK$ z@4W$T4|F%j@-qiTQ#$Z{m=e+KyX!m@wKnS-th9?Yc9lql*R$lro562aghvGdJIu7i zD6GT?J)2~8W#wS5nU*Ws zVxjvlz}t|Bc#P9}h~P}>o@|+!p`dYWyOBO&&zZ6AxVTV@+w^N{y(Ek~hw!C2uMH(V zpI1)>wtp47_k$ZmR!bAYFqxL zJP~KriCjY=PlE>a#hthm!;pV8URAABNn;WdY|Y&zTfkB@_N@UxpGE+ZVLqfJLNy#c z&WDFiZgJSZ^D1qqzTKh1Pzbs>d8Z%LI(b|zA-#Ff*=bkqaP+D$aPLJH&t^4=(D1GP$$uAJZI zi><8JC4#?e-N|n0G{#~y0H@Wwi+-j8Zkt@>zt#&nLOp-)S4yh0Nzt5N2oY{OnO<3; zBFcSN!h769tu{prr48b|isV%eS(Z$`aAs-bdfZ%<>dF@o!eDXdf^~Ppz&J7-)sdyd z2o)n|pFfRy05T&H<{GgH65LQxt^Z}$ls^*WuBl)CnG=RZm86W zdX1`Wo|35wM<^FRF>(tMBQs(&47*u48R(H=}>1AO;znC zGhbv-Db`A4J7ILZGK7MJ)0FQ5wd>d?05UWMnjOl~du2NVktY^l$$_>!^BeuUxFZ=p zYgEF4-ml|OtpmG&aD`QCgyB!!J--1#pu#C}m-`c}$v~G8{`iiUppfKAeV1U}FK(W> zAy-HA69FNb=ii?QE`04%swFA+(lX>JB}UPi)`UVjyl*i*PZIE=_AhTkjx)5s*V>mkc3^rJ1Zy{caB#YHq>G6Uz^r(@9B ze#r^P)`J$4-`rLPR_+m?yY6bR_Kd0fl-sABTSaM3vhV6U(AFKJjfav#6J5ms@!h~D zdEjd2I8*|_svE(rU6+SfsZvPsbz}ru;j`VCzmv_t-*y-K zm}=<5!}+IGIv7a5$e%a+duho+$y)D@fM^Z8JJ@=-lGcP~GXU4Rct`Jbp*cA536^2y zSbljkl7;(NAxY}ZDe_Rx?91Rh-NfU~c{;oVp%#r7u}B6}u`%H&1V^OaSjh?W!59+` znW8Z?=Cegi%%HeG-|<59F8pHUyEoT0!R@r$BI<0-M1*%w0Dkq;orxX!RzsU2FEwJP z0i{u!`0p~Qo%_p*E0|p^Zk(zGCLWJj&2avS*4e4crp_mPeW>BQb%!%((Q9LuH8E2u*1Z-Yd$w{l>=q=SS`JFoO z9CEx~Uf(H}igq#lFtL$@d4x-1;&_K`&1uSP^o5sqVk>B!S|VWlAO>$P=is@KBRWn& z^`;IBorHj9OC@ZsTf7{HqAZ!8nl$`|g>R0ez#LY~7I=QgQ)Z=>uiSo!U94S79vr1l zjVD=F8(kRZan2E3W~ErKY+{`@x4E+C>VmQ?z3o$fRa4(f-u`|rSRTa6lkxDrwuuTu z`Y;~}za#q4ED0NHG8$$KC6&)JTERCenpfHA69(>w9|JP=B+^Z)pK%^(5nj|Z zG;>Q{($m++R2S+`A_2>5E(&+?n2!_-mm{X{IzH_wc1rOgMo?4U$ok9R;2>H?lE^+R z8j8?qct0brLj=1E>e)*l1y4&Xs`3o8*At3>L+-+30 zoJVuPS$*k^&~WHVgJ#Af(kmor`ZXvMK+jLC?TWF~p|!^z1o<@E#rM_cFj`82AeN7E zy-9-5p5p$~_dW3RsGvGRc%hd&a}z;x6tMPIxh)Ryw4Q#CGUc1m3}e%cft`ug7(A1kF}z=X);52QlgZ z7so!z?LWid;3kjVfRKnV2){y7HMtR#hJ5-obcC$EyQ@owVe!?jfivsNA+75k{3+ITK0ig`kGWf8W5aWn)w~tx>$Kd@uW!Yab^WARW3!|uhbwR_ zq+dhemNi0~1uy$52oze3d%p3@zMvtPjX@W-)#Xl)aX@Kb5u&EWHE&uaX>5aj;6!~D zk86JH%P8}K40jo+&16KVTqTKzH2(JSGFmLw;i0D%3JCp7LIcYfIA7AOo|qN!bkxsM z>JVLdJIX_`Mt(312bb99sA#YVCHw*lu=!YYnb^&Dkp8u-AxxWD0^L+yQ#B_@J5t+5 zeAu@VZ}u7#mF-87HSIK$bo@hA@g2^?*HsVx z941*g-yD!DN7(`t73 zj%}$*D`}K01Xu7ZelkSAaQCe1_H-%KFSjgg6nv`*J%azXNpQ!L*LMyAHDpr^&*TB3jEyo?RlHyf#a~J#uz-&7s%S-Evx#Mx9)%|6e_<;=fb($ zoZVR#CSc=^X0}ul?Yb?lyo=HJjleZRjL^Qmb`#hk=Y5TWPE%j>*s_`4Cfkc;Wybwb zQlB32O>{H?^LQ-_o+;x{kr|YrsYGx)YxdblwjyEsNKB5Tt7=#2oBX+P4w${Cg9jqv z8yHEUhmV@-C#VN$DKQKyaq^~a0qk_XsPy*sp(kB8C(2nKMx@&NNP+GySZ zGf}RIGQ*QI1}>=lIU^`C8C!`YY`0n%X8o&O@X~EsfRZ)>MKxnz?8f?-rcvbSOq@wk zUXAvQCXbz&hnY}l8+_`Re$OXq2Hw4vkx8cx+DCC{RH$~3gUf{SOi7`bwRR^Cr$|#f zEpIKJ>o{lKg+Okow=Naik&ZJRLZUKziggmV_ugQlE~P!W2SFN>nawUT!hm7xWG*uG zyxZAWzq&zwfsBku|KX%`p7!#l<_NNnb|k*?NjFA2Z+4#k2E3rhK%y+6X&`lc$n>_o zjm|ymZK9M6g|{E)FEWoVE5kP{9a&Pq(1DmlIixO=qkE8zN6h3oHL_rpRyBcwa)B zN!%IM@xh8ztx0ZB`7gOUq;;4W|%8i_O9OFm*N$Gv(Cr%@m z3}HCkqSE1~XH%J(NM81x^7)h(5Zfs&I(Ys|WztqpAzf{^ zN=}~os`i|L4-3)hxEjKpTp!iDK(9+4B#VzI$DuWF!h_>Z@GB^EM|@il=XIe^JqWXo z76wuhoPvXe^rPTnHyX2gSpaE3(2%f|BclJBG3-wjGYXF&wOgHJhw)0f+UWDkkA`T5 zJA6!ft7Bix^Twu+JYIjmcIe(X=9ZBqB|JZT4s^h5>PT2HhvvrPpPk@JIPC}1ztI8D zQu`m(mvI{%(J`L@_a=K*MKZM~7FroM_^3ZFiJ7Mbsef%R$1R`9L9Q-cV_iKaS#k|? zvpo=~)Srf4&N?jYln`YB7=^D<`R6W10 zzM0VRX4lw+-m;~Z_fg~xKEoaa=n1Z zu@pz#ycRFR#aWgAiAi|#X+vwD2O%*|D(oW>ZRojT8|SrUBE|Cxt8>OoZstmm1omig zc10lP017ctOPNYeF~Rd{1{*c-MD9acZD1$dt37Ck9zoAoxs;43?d!dh&bJs9y=^Be z71E5}LHmY2T8j%WQEMxmiG9#grLH!57^&v#`dJ2C*eDWONwT%V6u5n9#9Oe zgTLs$*pP;sLApC+S=a$KGKk%QE!A-I))EobYYqn{qxy@4dyo0!BhPrS1Hr7 z!D;hB|CrA)u}-w(4DpjoeX%6M2|{ck*<`G$!M2&kD&hLrgl| z^kbLMs|ZYt+bUc105iLR5>bt;%vN?Q_;t6t%Zj~E#samf%`XF5!RP_4)3M0A*{|@Z z`fl(WeBUx^?YIh`nzPQ(+M~AbHm{tkNS}Yo^I*-koW;C89v{Ep)zXw@k1&%61-ozt z?R*+YMC)`_hVv7#PT6D4IFKBtE!Amu@Nh@I`o+<084I*p%%!F1cn*A62G{JL0htPy zCh9!F{A-TlfEGE+P%-7bsyvxUx=zlDwW7{5rS0>Fd$@wz`!sbuf0z2-sXhC4zwDRO z=T6+W3ex3#Oxfzmxmkg$MzQN@U4yVd187%kq{<D&U+5k_-7p%l@D9QbfI{&Es=fR9`LI;N&SofQ_aN&;cYelzke;SCd`Skwdrbgnlq#A6!frC zl=Z|r6mvGDnXs44Z>+~@l=Bw13GSsYlW>W(ZewFZj*}3Kk6U7#UX6^JoPS8VpW>)9 z>-Dx$MBW?CS_g44LGDR#YRT$}{8s_Rr5wjPj>b3A_x#u-ed`sxbx3$I>mVkN8eH1^ zWO*ntR@YDZY_(1Y_&jlt1!hv|sX5jBGSk)w=guWnUNhCI#cq ze(E&Kfc_-r?GJ@mmHIsnG+wN8YV*T&CqJ8tmN{0xmFb~FUcDrnz{_k+`U?MX9ymx{ z{@cE-rCP&yg?cD9AIus?2SBQ*_yOMELA2-$wAcsDMCY8)!9nQ#@9EfI*`g`#yI(tu z-**-{bcH6pZsJz58yiUeEggg5JoR@oe7*m~)LY=EZPB{?KWRPN;Yx&HpVyk{?Cm;B zYdbB@d}OCQDC{8Zkb^cAM(=I5z}deU0ZGiHRQU*(7pes$DjJnr87;fve>kWDBFb%s zf;;-_AH@ZE9`xN*M-~!OygcwKR_&@LI=f*c2wCN-z4D32w1%PyZl{fW;1XL12=9Qw zst3RRWsp08xfp6?!>|TQO6`vE@mz96GdDH`?W<|G@7>Opp)$J4osas7AKAR9@S=)e4bN=xI-5efiKy*3X%sl@ceps3C5@9~sotFejR76o@p zoEdjn{l@eAY*`WvrcweUx;QdwOrE2*i3l`PT>}|=GI8%9?y0RLJnIWVLp>{-3$d_u z$$OnQAHxrARH_ox{y%P40uZ-kn~ytHGLTpJR!xsQ#p23JJMN5q?w-7Rk6<(`;*qL0 z>}06LDW}YX!yo7R$8zJ@mQy70HC7=asar!-_7|Oo*9S*5W#LC3#FnW=mw(hwjFf}o zKg8T31H=&}ccs3n9$5U+?oYAFm;9_KqZRp7K|!@g>T5+XQ41k*epC5>9^?sH-&3En z)cWV6|6bvWJMy<~-rPL()+Ht3V}%qbE3)?!r?}c|#CUa&^oV;{H-?&1Pb$U~%l|wO z6K^4B+0j*pV5?bFqTH8j?uErnjXWC9Y$9>fq%bAK_u6FE# zE;t6A8Hsk2aq5cYXK3SK}~Wb7c*S z4*j1G;$K9>&%1Q*O6~~AxFqYpIvG2?sUOl~XZ4F70!0}sJ6t45$?Fd=iIxnz#ggT*&8@jt|J76^xUqCZS>a(feNkvR#bOh-DI|R%#4rLwcjk2rsD53 z8XD3kr!D?(#}537{HQg6a6~OAf=XGC^j~12`;GBvgRGB0YPKs!23KqXQHSAtnD9c1 zkk@P;N267a$-IShhyv|*riH2sJY}>W@>0fIkHe0$SFh&a;WqO&8 zZ)!kjXymw&?j-5tz)38W>!}?}FImoIlK9GGD z$?mwP`qALkJ6fK^hQLyijno{Qk$J9_*?g5IbCrcyJYA1hVfRsIDJ^L^=D>vf;) zmZNwE)dxqQ;V5+e^P3El+EH~GpHry;Srj=at7$cBx-t_RS^S4~^nH|yHr%J-meS)) zAs@Flg(G^6{xZHOb@_P8zEGvdJhCjBo(NGca8#{r1igAn|BsG)Lj~4P(lR7|kKp<| z#b8s$BbBi!cos>mK4kXOOVVex}sAW82f#gxhbhIRZ4iBc8P*d zA`b4kE^h$_`kgGiw`mG;f0*jPMT#p34DUyaCPA>kx1y6TSD`xJA^1VFld=Dujr1Mh znDyo*Kd;mn6&Zvx^IDsQO2@slm^c#mYutavA)fiC0+d2G{O8eonxGbL;o`5+Eh<9q zS67AaQuxG2X!IR*A1^hyuC999q)o6)>kl}p2*63N<9HdcHT(G9wgNJc907}5jy}1Q z?oMGeP2v}{_d|N*v~2yyas3{dnGS>{uKpB42|aCg^d%{@ieCvfwzOkHKAr~>aK|b~ zi>yX!36&XyZ3}#oq(LVF61$BVUoOS8YUfy&IG7Y2mnh*}6&v2&G5z-kgA5|`Tc(7}?F!zNt{LteaSq{D#v)x6WmxHh1%hnCV2SOo2gw-Rz8RKQ6`V}usHV=or^iH~ zP5|8Hj!OmA*E13f`;gu=`geQ`s{&=x^ zuf6x$YjyYTe)?IVax$W@P?%6aKtQnKVnPZ)Kp>nzK;QZxz5^s6cA)lvA4ppkc5*OlE za?Lo;bkkBgc>UAOn3neK@&twkG(d6}v7j{}pG3_ZLur%h&$UitwmYSwmPCEI*>|&| z%?6r%1?LASGvl8S`er|U3)P?q^m<_q2N@^`8IPWZVCY~N>Hd66+`Kws^chcOoVv4~ z^4L6Z%g&D>78k((0Ral^%Ln+u#28J_1p4RiKavvoenZj!9%hpGztO_ZIM>40i=u@J z?42A+W`{&8OZX)f-K(3+w}U6#R!f1iFjgmxa3VjYQ79SdGf!?=))&IV9mL+ZP~@>d zAk<%&UmbYZRy=nvA6!99)A`3!S9`24%n$Uiq@2RXqGHtK*;9XX)>yR3DGReg%1Yk< zekn}fk(^#Az;&&Z*NyHJuC`7pnAV}m$DG3A!4nY*yKMNCKU+p%eoZK$X=0W|&gP`< z+`q!Ix9)>kt##NkJCRNyh7PY$z}H;{xY116$jjPm)kynv!@4u^NLxPmeM~;+?{v0& zm8})cYqh`*x(4FltX*={IeGqArd78K8GeH{NA6X!nngbuYq?9Y{Ke zZ;9ZW;AF;{K4zg`v-x?ZaC=G`sZ1dHdZ7?Oqlbay36k1*BDA8sQIz`Zl+71l`9e)- zFhyZ(-4>#|FAk%?FqZA@d!PX+-kyL!!#d^}F1GdfJzDD3@2)UeON8lHo5FI(Q;XZR zc>%r~Ub@pmMIGV=MlBbHxPNk9(MH4?+gJ9Y9fUUgr~vC0n}vyE*VcFpdaQ{Z zA!K;`OeWK|@gq_sPpFE=;f7TX=f~e4@VeZ1(7xFnTGUwH&8kg6c1(X1XuWZ^IEk~yPlijmn;dlS{GPnLCtZ}!| zBSS+niYP=EDzy9unQ#GL4nu13HvPNo@EMXy=HiWPcKXnMwdxGj;qJ5@2Ys>Xgh!5o zEqN%o+fV3lF(t72-4IlNVgi&bVvce6<%uvW(Fv;(bnQ{&_V(a|_ROmv_00{N9gym7 z5Sg_h_a(pDWMA=eh@2H<(@KuwZCNJGNjlT)%NuU3J6E;a=1Pp8Gn%E%l&45@bNXex zP}B-216}Y=e#IFW1a{|rxFaFfHg|MI6o=fZ=F4#j3rW4esSmK|LE|xD!aJrv#cKU3 zu>4hl8DU&AS{ElqduBp4wxHo+_Mv1ci*jn*Uin$JJ1Mi^q^_~U5vLNA;!G7ZMf%gs z1Erl%!t8RN?q3_rV_k<+{*#QC=kKxRp*T}g=JNB;H~_m`P+Ak=@P2f zO~1YKjSN4De7zc{Ql*8W3UAfmieFPR*cRX59tr-@3MMh;!wzJ;Ln7a3WK^HcK_?1t zrMrS>Pk%$P@PzjY9}q})$=n(BxE_rv0?9DA3#%g?to}BhHL#+@ zl@sZbPTWMoMcVPi;ta*IBrn2Q4b-|URpMr`Q%W@5v+rqR<@W5lNpXFmYh>Ls3a+HM%iJ7;w)OhcNh4Cx3vs{r90?g83lU+LgxBLo$1ClR`&B>!QlI_Ie3SEv2 z3`z=#NoFV9DkqeQCc{xl0+jEUL}pC5s4vZ#yvn8x3EHK-<|&_;dNH?qM~O$}0_^9> zy+^_lH)bz!#25v=`zUcm3SOne($5H`(}dEAXY-;^;a`30G8Lz{(aTUq+E%T~W$Cl` z$w>o^qwat)HAp_5S|mI6pL#2+btKqS7GH-TSIH|+rW*$)XqmcG6xo>-J}kD~j7tYi4wC zn{VkjZ+w|`Oeh+YYp#`x92jW9Ey@GdDDUIXb#2nugJpqyJiNrP!2( zkz}M4&m;8L+ed<7d`MHd_)s}hIARzcXjE{O350T`+SK;C`jtG~7%Hi0F)GBgWSz*P zO;Fw;D(F$f_AIw7d3LWP3O5@eX*vScc5vDu+MKf)?2XHqX*468E&xZc6I(A!R8agT z|Gb3VUo+7_p4c@$#ogHf6Bd0t@}5d1*^zy%EeT<3^;0*=am=+q8Ob3_W5z)NnInk7y98@g z!3E9Xjm}UMsSJ2yN_`(w(q&c2^l%`LSq!~l484EBegzEt<=3l*V;TxE8s?~TRLCo> z$Hhg!0`$PXu~CkoG;i}G%34@>kh-KG#?AropkvbnJShV2;ed%j3=DFSFjA3kKMJQ< zSxua-d$b!k6g97jb`PT?5p8`8i!^J0>`h zNHDhQnNd4D)&<+^JVv$u6hO6OXn0Sy{hGl`xIC9YZ>SxgE16brCWZEx9i$a7sPC@p zSJBq_qh_9M)U7Mpt|mC))o8AvljHG(ppkg7%2e#|3ufbpdJjeV?Q~3{nuJ=}q|tze z;KBz5kMzuY)P1OCyPBcLLgKn&tzO}6^ixV>_;XgL^F z(cga*04p#KS8Yq!ZgAzy$Fh0gPeOq~nb`ca;?P@~kX$JP*|;I1dL<5w^X-ktf>22X z|4C9vgMSF#bwJ={00(Ika68P9@^r#AIKuv1OR!bM@|(nSfdXHx#5!jgN33t?KU;Ac!WrXY2j?3`QqW ziqPj^sx=ELK*3W%iLi)6jPiS7h$J#P(TwD#rbaFtiSW^{WpcZ{olj5vfl>2Jl_225 z4+}}@dnMPnv(Sk~(Z8Cz$|x^JPkKwi_kKnWRmYW=qEUSRn|ax3 zwNe+nayE~LlX@vPlVBl+Y)tlO6L$N2M+Zedk=@ET6g0o{*yw?GRwg^9KIu$nDDc2F zyU>8AbeQx~>#Tb-nd%Y{VdEiW!$xr=QYS8EAYN*Lk%ctFyU2|kEh$#rMPq69aP1{g zVwLI7sA9)9gOcihd6H(PTWM#2<&WcqyDxsbHJzFUOP?_DSU=fZDP8Sef+dmRsjkyq z9lQOF%a+?Oz7Z(%3ljo))h*&g7J+e!YbG>We*|Lbd&KfDC*$J#h;W*q2M@-xo1St3 zB(86f*3@&nY-Cq21yCl=#04K?kT>$Vpb>3shrG8x>btrjDuZi(9Tf+Z0@=uNsA>>& zC7Oj-cV|ax1LxrTzQmg p9M`3IF(Yuv++KDIn4=C8fmY=*1{PTC*~a$hyH&pEk0VJ+)Q1xhZqi8#Mkftf;Ec*kh#pZgp#&m(NSo zakeA{g&kQvC8bY6JvxtTM9TVFs<4dRnlU_~@jeJYc(=#^`8UX3FB*Piqc=V`dZ|-0 zUChkgV{%2sHPDS~x{a)*_k2;rm5ZQx;f!-!M#pC=j!!40P&%--G{UPtQwNiPhxTA3 zKa4n`>v*JUO)+Xd6+YInYK;Im7`vd9HOz5=iK(@GX0mI9Rs#!HRaxtYF{H1r~xlI9xga*Rw9NJIMaBB zcgaIDiiXbAHw44oveblvD6zFi21z73h3Zei=&Zewy|ZoLe?liWHhldpH?MIxh|rz3 zYW41VZV`|7MR-x<4*e9Ae}rKcY>jqS%@)swH6WsGi9#xzgm@WXluLlvqC1GWny`=M zjUzm0lubO;Cc=iY9|FPZBDKEYm%Lv;S!wPmR7gD>sK|VC3nck9AKO7&h?1CSHKD5zI3QF-7ToYpHI{oBBps zJ|d+4p}e5W{yW~ugG?m3C2^t_7RNzKT++lOEyW4)%(nTZ^@f4 zk=bIrd${}8Et~sz{9#=VnljZ+%Y6^;@X&dXWuI`vD$4?%>KRYnJogG!u6X3@kG~7d zglXfB5Sw2N7phsfxtQow}@W_4WB)J4&>lLksA z2WAr^qXHo(hbxqK>a0Y6EY#Ymd7#KF8#cvj!l@=Wx_S#mlZanH&I#0&u zn}49Jj7v4ztMd!v?uym&J9bSCXD~4GGUU5Lu56vDq6)uN8MK_-X3^j8zJEs(z%Quv zT0ys?QOuy_K<-E#yP7hClY#@{aG7kXmzR6Z5yxK>f(EYwYWKxdH4j-(#oxx)>-=H$ z3UQYxnDo+@8x3KqSQIMn-F;z4(jn$jytb8lD%fu68ND=AyIRj{uBn3_Fp{Af22Bo! zh;1MklW|J?RDYzm#7*NCnm8uKp||&Hfh&(Gwnc4!8ApjcT|)8HJ?NmL!9pW;6L7UO zt1oipAssE=YGX=hF)=RJ5~3%P?*MMVSgXeqM>G5U!jK6CG)6WoomcRa!>P zT8K7PrK6biUHO`#E7UW!Og2nORab%w?+yHpNm;Dau)7ly?klLjk^erXXF~FXJ>|xm z!m{0|QS@$z& z=gD0?wajm+#-PWQV@W^(@D8=?gJY38_pM8-<0!@)qLAeDqqvYcG56{&tSU40J(`v; zx?_HHo-DIa9JP+nL{$H5{}~b8>rcJv4*T{mO@_06w3NgzsaaEQW6)`mu&9lrt`SJk ztgLC2)c2As%*1SUOuDj9xbPb;6#NG<;3o-4uiHlbqp#e|bgGENs>sAUf&W@IP*!dw z)Vje!wt>#!O=d(JqD*Ew%RY_F;%R6zpGS)N7mCQy`4O$wL(NaZDl~4bcSgG6njM^j zEN|TmO?{o#QkDme@^_*F9u&RKSOqfv0vDh@ddP9a;;ftqf76eD;~A{_C#wJX|KtA@ zc#+0oA1{zwa^?6R%mgsrKDOKMIJNae|GqB(MNBfsp|X!2vCR1q$@!MLRE) z!|^{*rExWFo@s2O_x`ko4Uk^<44_`egwSkx0eqN$G}&5gn*uRoxH#Vz2*HRVAo|Pj zg1P(7b=ZW-w5_-Q2GQTqx;@XGQ$5wfy!ph9xMxthQ;8spy#%cZd+J(+fZhX! zj8K>k3$@4wfl82Tx?#DXT53Uj^M=mUq2av%sx zoZsiuh9|v8h16>Va`wtd(2~J4CQd7jzh|qJR<=;T?H80)kw7Npdn%Gc*lKeLmjdD7 zHb$&~c;QyWv7!ot7JVYR_JJ-=kpgZ6GV!>mb`Q;IUY`o?euK@KJBRQ+6Ks@J|mGh%S7jLRT5>YTW)=cpg zNnS;#2Ozahc06lq&?Ajf{| z3T9XBH~Nl{6b)XYislSS8?i){m8ZboaX-w3HJ|rwVc&>}29Ba`z05qaxiV?>qctM5 ztL$%zr7g+MRQFot=IkOjy3}brs>&h^>yFA!)qTQJ*gu^-X_RJgBLUfY(pi<2X65IL zk@uymNQ^?ds6e1&83qsOprr-eBT3`-qk};_U@fnRc($^%;CsVcQ#w+mhc?`-A7oG~ zxA^$ZkXgLEL&EE%w(Wo>&XkSq+_s$HhaB$-uTl^mX9Q7CJCTrKx zvxaA+{ z_rT9+!!z~d5+^ zhWz4Otz3Uiwf05?Bu>wu^#X9)jBHdR$Z3=TeDLdZfzGGJ|DyGErS6A?c z#iwAB;L<@1ZFMA;Q?MGl6=FRSb#QPI$JeYAn1(+fFF+d3?255EX+$@~aw4wuOs%bV zS^Lz^9&c0MAzsv~3xv{iBm2op3DUbeLfZ&$hVzXgIP)77%JQ&(#-mkvmS)bQ<|x4M zQhCmZFnIfsnuoFqWtUKy7k|y6lHpryks7*A985$zGx)S|ntg2wFE(l{H%%M?ER;Hv zvww-wr)cl~tM2&k;7gHCC|U2uTJ_z|S5hXMFy@voaKv+o^`@)-I6W~LtIZc)u&5xR ztflUtML$)IiOo7SWVh9?UBNaL9>sQDz`i>_8K~xd8;O}HuG-pWHQ+p9E)6QXm9vd` z8uAJ~D_%h_@Ra$UY2Yq>pt#S+5qYf0qnE_3Sshe%*801n-i6Na(By#SW*6W5J|Vv0 z{q`lep#3xc1@B^a;<|g!{$22Hc|hzYmCYGPj^4R*WD{4_dmsxl(xU7%{h;=UVoVGb zppsd4V(P5nCul`6RxvR!c=WbUV^lIFI|7a<7c(if!C*Vm>h=tHBY<=-2N`&4Q?)PD z!D*^m-%%Wo!RmZmgU1D6qgBT1$(NpGol#2Yl5&>{@s;e;$@58TmURxk@mQ!olCLE2 zs+%70yD=_;#*JnwNaa~o{qk@&F0Vw>b?08{b6EV@HOb62iBgt~xrewb(**9K934C3 z=T1yo3FE&biG)p^6FnB6wKT>l)BO_4&g3s^Ce6$|Er--5G+T2{i^Pj4MwD|V!e>bB z%;i2Uok5MSC(1bScvqu)LQt|NCui@QId*U~_d=6MU@L8(QFaOKpk$DCE*Q&rd*HhC zx*SmdMz%UrC@UKE6(^io)bbL%LjUG)U-e;E-=SlhRH4g#GSkjDVHy^{1mfy6ykox^ ziAh11^JT`3Fw^SjS92JjvqNXc;!}5p*e`Q?q8{UmIThdV#e<3qPk?srv&NY7Bkj` zV@6AY{E6MSMEc5Tsf3qd{<_NM(e&#bX=7%LtD~TTOe%KOMDSz;s-;V# z6A0CWmhF{hQfdo|Y}AEf#lJSV#=j>I(t4nzJ|&#o5;K?dXl2ebL#sNS`dRHcF2qZl z_AN|>`*@|;-|ak)l=S6?H14suCRk2OdKLjCB<3u}(8R<{SL@@WmJ!B?{*>~3Jx#iS zoe4Vo>o={$-?NGQ`B!>(n|t%7FTK_tRJ-e;#QLI9hqbsg2W{|1d6hGllFC!nh>rAM zLfoWCSNPp&5RH8QK-^E=BM{1rw)Xke&GjRTWoMG7f2>$m%*2O=l7Aqw`AuG=G5_Wv zVy!wMKRFoKppiZm_D}E$iyx|<>COgs86kgm|332d23Bp7H7NO*$58ot`cLBgz)~QE zP8;)Z#~$YMl7hDIP>}D}CG}YK_5F&Z$5hLZDZFT-g|~*N)lHQSc(9kto_XWsP^-I0 z)%6kkwapTx>3VzTIxqrz8G5X>j$U>MFX@R~b8hes^N41_kx_@ge)8M6yA`3=Iwyy1 zXAv7kF&xX~dEeQpHkFSzg!aXzQpDw2^|F@}vMgMMnYYHw(}U}7GB{(6#hAp&VzFm$ z#RmM{reCev*D2lO?XM2L#i?#2&Qen8(|vnAQuw-+W{?M}gE%|Dj%lbg z&e1ykelrYiVrujCO14q!?}F!AKTPds!j}6-INFcU96D=2;j3xZNl;>39vQx0=s1rj zjd5?uY-y=_H1+32?AITKxs_CLpL$OcHZN|rCtcKnS{Z8uW~Y~JVAyl`Gagx-d0T$G zE9|bju&h2GaPeMeX^d8c$h)K*Zv+PLoCqG^u1Dc4`mI^l%{3XEVOAi|!;*iofp@=V zdgouVR;mn#efyBLaI<&>?#k!YF(<{ia{{~Yy(oBc!_;L(TPaA&C*`C@0szKloGP!0 zA#mxbbu_JTM~D@4Iy8HIBB%A^ZmW{U`KHmv zv&3}pnCXtX;ztGU@b+EdpggLfu1%sU5&nCQh27xWG|s&Pjdg<_P44bVW$f9k z(pR9c+ydo<6BLM>;HrP;&-a)qgVS~$a7?1r5|Y9Rp^8FBIc+5$NOpQ(F=yJ_`tTFR zyD;oOTww%z?0$o+SYoscA0Ke zbHo6)*o2?VovfIfmF}E(HEi8~@fnK^fG^(EJ6|Q)yh3|dmHaawk9Rg;&q#i+>Ycq5 z_K)-l{+vn%_!LF6yhj5J?}*Ed!Bcj)C$D;hA1aSHgYO`dv& z8lwwXdqNfPltG!Sg*vfHuMy~2W2w-0M@D!xxvP^;t!qx>mdDBJhEG8 zSxl{aAlu^E{P5G8=YETY(IyugcNdQn_AB+UnlWoxl#N4+&r*@Uq~9JKt@Cn50&Gk< z|6m2R zMD#Guy-1FSWP)>!@mjYC&VBK&g*|!u+#bzkxHuQa$RaVZT@g2#@z2R*kS%3m`1dBe zLP~!Tcz!gmgssybbd?ctbLYCv{{1T;b}D2oeJ(7;>ascR?i+-4%*3!pTZ6naIDtG* ztutEAGZ^n_TUjiX6YbD0Whd*D(GJOmXi{prCkO~yEqqVEz70+$? zA1{rZrI1J`f^B^-@aa|l7V zkFHVe8||vkl|tzw1j?EkTgt)C_)mA`hya{~$uG985BuYS;$a~q) zwtcR%UJGG))Xe?r1Jr#TpLXjUPx~56beCgiV?zBWY*9?!l@*s%E~wU*f5n~*%h%2($>viH=OKk6}rHVC1+8pLw&HgwT~FM@lreHRW?E~qb^qGA{^w6uJYYBZNLICM|JJD z=1w2Nz8Xp;lEEaOd_($((R1C@j;9||ron!N$I6@BW-);Bzce$b-J4CD{Ai1J+a`^N zJ0UcQHc6ShW24&g?P{%h)C!~?HkeXw9D*huzY*pp55gwO`AYm~*JQj~d9!F3Ht*(s z{L}aZ^uFs{f273!;+B=>UNQf47p`xwUzCsA6^HC#`jpWJ*>9Hh%k>HCVKI65&alBy z5&u*=32omCVu{w>9?ol^_MNfDj$?==Ne6G>`MUJpk|bEyK{4Yk^2i2__4*}(lpHhz z{3Em2Pb7^nW*v^Ko!)wcVshLo=x4kPP$#5LZIsKPQ~V9V63miab$$7@R}qtZjOk*n zUf%o6vQ#-YbMSQLYp#JxeTPV@-&y zmb@UZXOcLcSb|LF(xR*hgD6-<9=d4uqTA-*;8OCR*asTlc`rip>F}IsA`DDU9{BH4 zA9nHoPJU}%=6M=J5>?yG(~21vbIZ?}<+7{vGvld+6+i4pEhp}14ncs>VC z4V}GOKJ_ijd~S-!&+*ijL{ax9hDJSQvRKG2<~z00r=#T3t1UZY8iUOAU!%QHELGV7 z(e$b85A(@n#NayL%H_yTKcs7SEB`cq|N8~^{|W0IzwbM%N1^-|TlB*u_{sTSNHa&C z@PE6tYsxB#~f~3>gX;in;HoKcU>;&rY#Zo7XA0Q&Pr&gV=&kJ=?-$m0`W1wEKL9(Zf-plpgNo_bw6&q! zYY5=Rz$cQJgAj^%v0)(dr9>)r@VVy}2X$^6rzzN6da}P0Cmuy9q z&`+=jU72Pd3`p$U%`Z)%1;E-T*Aq-uP&3CH^h9=W?W3wg34Q7}bE! zn-Awn4#eNYg;ILq5{5mqC-siO31w9ZPFc>D^->T@oZCSi^#w5g$eajJIJvI}svi(i zAw079(2?6OTXG>IQ8`JDJ?)z5A~_&j9qlu@Iw-EQmHvJ5n-=^Z$#WOFBEX_0PwoJy z{ijeiX-uHV^}7uafZ8V~Imz;eLP_wL?{I@q6YA6hrQmbynaZmKVegM*MItgHUyym9|Mvxvn^n!hnjvtGxyLhGG9fc&vFK0XkUHB_@V|Ik z)>SytW^4cBi@%}&D{}kMqTZd!iUwpv z{0~fg|I4l7K-gS0GfQl6U}J*;nqNN5YHCpEhM5Q|_PYRT6F-xRX`O)sd(mJxY4_+Q z@q`bBLO5$YS+>hj8$hdwV=BBop#~Ezk_fCDvH9I*3TmW;W{r|w?t%l**2beG@_bFT z|C-Cp(S|3$l=f6&eE|A<7L?C{e3)J?lqnM7 z3N}Rdw$hB=QvtzF4`DgxJY3Lbq`XcJ5d+t3zwN_0^wSsT=DVGdY3fmVb|5FK~{HJ09n0|~{ zzk}H{dTuD6K;S?VP;zDs2gZ?xBok?I3DB&CQI4gbo33&GZp|if=n{$=3H39+&^j3+v3G#B(Qoe>kZ%(3 za)F!C%a?odjwrPet>rv`zptD3O)P8s=nTowc4(Eo7%3Upif?p9)}A+?FUb65Dih+wR@&=0A&~(p4_tPNm8TfV z05USN0p=V!+t-E1bH@kuk&Q+ejoou!>o~_|u-n=Z9hn7&@73j=k^tx)o_hqV?EP*f z9_qDgakp(DGnB+Lqceu=_Yc14KzichO#bqPya}m;wF8h5_cNRK58l#wFE^c$OqvT* z2O2;54Gp_s0pGmyx%g6DGoxWiBEFeeaMJF+COjECDw1qm;WI6~w5s z7z@V6sQAnzSFWdTC#!S)v>4)BByYou=F*X(<-+CMLo3y~26E{?ZwplZSzAq*#T@aE zAb*U*+%WoZe@)rEndgM9{J#YpPykt1U`JZ4UuX8=a3%H=ncm@D8i2z%tR%VjIBKH_ zhUl{)kh{-4#UT@NQFkTl&&Sr;!SzXkGoSuY`FTPn!>m0X@o2>R;1dpH5{R)rrVpE=>_ zQ7-hkIam;mjEtycPo=*6;>2K>3o%`dYjSDdJzNO~zr2DZZx4<7WYrV&bbbEf*+cW% za8WvAS)s??^ZzzgcOXl;%Fep8j1@h*Vs9e45zB(3vr~SjfA&vt^daO(5ftp8=HVBr z$e)xOZcW7xh_vY?PeEMrGh;y9{u^iY484KUc7r>T{48!JUUalgU1}=x&qyy8viCDk zs~xF%&bk=?uKD0(dvC<~nOKnJF6kkIL$67}qgUWnUNN67(`w|mlF?5^Wp}CL-Ouey zx8NA4Xu7-TM5^U@@elW=uSByb$uVOfvP{i6@-hGE>aVe|9N!X+5H*=dU_qWEnTDR` zZZQ zF9k#1<9;UK`KKHSBWFGXM)Lx@vkdI9DZ}t>8v*8hZmdn0oO(`c@yhPk^Fg+@HiGF* zJH+tn`g=do+8PmX0{=S0QzT~pkKmiZ+pCe3O0+yC!OK``fHNNjE0c9k7ydK%5b8*Hd zRto(zou3Y^&nPNKS>WmYV#p#ZEz$pw>g#CbovQ1MJ!E7|oK5YDtgJXwM`s*+ot@u+ z-WbzD0&?PF6CBoFETa>l@eCOaC@82aZ@eM|B5A*_o5(2Hc(%>6bN>@&&I6NFdg76g zIpKiMz4a|(`yJlrDrdRXIefyD7H8gAFZ6o)C~`R7_2-{|O*)djRf1J=ur0~?d^>@B zV~=(5?;yfsJlRmYhG_QjXgu*v!qJ$iTRdqUU~doG23J+r3elUl4zEsh?mbNxsPp*< zMb_vIl%lcE8s8%?FqI4zr*S+x6ZfDO>zt@9F|nXAw3kQ4K^z!jrFTp6Z7q&-t8Isd zB9{1+`gPN?@_y#4{q7M_o+8G2GB$5zK|b34=fHwQYjPpADj7Mib3X3v)p>BDxSOiX zPz^thY-DU#ZL~ULAvvYFkmZKI-#qW}bM#_g!E)rXRA z$u9Bt4YJ4)3}9Dx=DfR1K`2O=lYY@gO5(ly+b?%e`AwAeT|YHmM_x_C+C&RX9wp=Q z((Jsa!pJ0V{Cd#@K-Ue;RNATtK@f?b^f-`CjB zPx?RU-d#^KXQ6@bNB*f1kng{jv!8CSibd%^w|MOu7jNf6IFqz5^DW1Bw-^1LBpCuT z#3w59VJsq!Wvz@?m&w{hyeC(uH`zui`0;nGyA#2hP=L z@xnaCGgR2-+l>ZVMW1P9_Ltey&6jXt0|(o8qjAHl*X-jec6Dc+Ng)f*A{ye1#&M10 z2wWmSd<6Teo~tCpkvV?f{{`lF78RihnoNw) ze$q}v6z^aNerON5BXoWa{Q1{A1n`H)jE0D^lZDkR-nloYA0v_hTP1hj4%(gCv&8o) zug+xc>`P(-YmV0tTJcte^kGzr?-rK?PG?VsDV0Nx+xNIk{*tUs;WLGn#*?;n4E3zhkHVn+!nPe~y%OP@tJ>I30`NR#ljmomMpJG%cD)X(ZnAt1X;#zD1U(<$aZRKSrIP7-dGKz@I?#3$t zKM|h))62H>S`#ppA~i*G$uLT+#i8y$+4Gm`yvt~1jJmCIi|=sQy6=fHMIKqg9gk`U zs%M=B_%cug)gDb$MO1Dp?eo6w?ow0OGbg2ynNn-ur*i(%F4>aQ1%`aR1Bztw+EqbE zSh2-r4Mg*V(57bX{9o3Zr0&LsVYPUWdp@2b_P<#0M7MIT^ew{_-(-y9Y0|T0D!&9~ zma#E>)U`|q$Bv>aZFzxYx}+jgzSn;Zv<29xv06|E&>EISXY?&&{(26SEuP%_n0mB* zE=Ur{IFX}$sK_a_`EkYj#yG`|E493~BNRZpT}Z#@Ry{G+!P8c5s|V5&Ct6hn4-b1= zv<1@T$mJMyrX7sP@WR7Fv(;x~9~DXhUgNPAX-K{GqHF>KL2`Ya&{?*bD!$6FgQMqRh+XSeZX$m7Zc6+{kH>f|aoj6lbpA_>mDuVYIdt1poHDa|m#4Ju9EyWha%2Z- z^fd-+WG60Iv?al_Pr-Ym#HJnfV^9}l<@7}&tijw6Ui|Jhcy_aaYs9q6vLlI_M3gph zaO>^&{cIKQXw_Kg2N!xFRBB` zE}kAH?~%VV$)lk5?ndc*XotFtC%XW`GB%PziSucgij2yob^H64L#IXL)p3gdr2h)7 z&;m}SLGZzLFE8Qo0!?AR%$A(%UGQYiCQ4$}BI=-<{=RhKkpHW)A!p3gY+))e?k4(6 zVlT5uVrEsp^!R!$E*Bhv&1pOX11nkHvX-PC1KTuo8@G}Wu5LkdIG-qQpenxC$ z40JfuR04Umuim&=B>VXyZ5)3|=wo~@_V+G8n;byU)yXfFHQttiJI1HBQ<>-QZcjlWaAxg(SaM_3d$gDv?03+ee{RoI)? zF6Khd;8^3HF}wQ)rt`{7G}t%%<NIx`;^TpRl0L14vOlS7Non{u5maQ|lZBW9KqRV*)p6is!*vg0SA0N} z=_s8$`o=)0`mw5QPwpXEz?_ZZ3pL95?s975Hnu+gKqy14z!cV1SK(+haT|9?^s|^?}?Z0FI_FJ*v)b!(W_7!H*|1 zU>RxOE|#c#Ykxy1^8#NpY7;zV^1On8Zvh!Vu&#-KjHWuM|HI#*;Io1VVf`&aYotBk zQb%{5+KT;-N$_GNKB|~D_2(BXJxh{(sLzvh(}T8nZyo8e`HfEIA2flK8e@h&-DukX{}dD~kQ5T9e| z#9%x?`NSyL!6kK*EU^|m4+^o|nFasK5n!>RsBqk#Pe~v7c4?IJg#;RL(Ld67Hs)*^ zaU%a*PKw}E29&`uQ)s1lZ5m#WxXtmGilZUi*8`v2scAXYT#mFHtr?H%5nbYP8V zJwTGbqB`Pzf^M+d5HpAe$Lc#m+R$rpX9ob!DI|{lwv&=h>tnovLSymWUIcJM6^L!R z?GmpGzq#7^j)N@O;T;dP{1%nZeot6PukZsoI+R!2{o|#4^8QHatm_ryyJ1yfq%L{` zunG%grmH*9YB!&r-oWgb>vA}+P*8O8ws+1E`f{~r8PqS=6NGh4bEJb;6dGM?NedHB zgT$oD<7o!GkH+p40u|;@iLbbW^tbJ+wZ+}f9x094_`kdL(8EVoY9r8+Huzop!=Kq2 zi-!6GE8Nb3=Fq%_Cnv}x1ToV=I_)lB(d)lF!VW=H{i4HE-OMK+-f)}irdbc z0R>|NF1*6C;V4~!txY{k>DO31AF2=H8^QInh)d5ST@F6qon`QKn~ztp^60zyYBt*Z zNsg#mEJ8nVP0x=HxzcwEOqA({F9%Pi8&+UWR?!*agw8Bkgd%py^;*ko_p}8Ij=EM8 zO5`w=`}Or$=JM=8$(2}NSvVpm1=$WlnK_qJC>D28dYKJu;dpR0OIKg*YM9EG$JE(G zggZ1O88!pm&$#!`c(v|YJl<%y88#l^k8|3v{RkUX*a@HZnr$llP+ZPWNEf0nl88yoPKL@ z5AS2L8@3?5&X>{uq`#9`hqS=F=;g`&ybtM#j!&u0`E;Cp)Fwl68)f1|p> z;RNcQvl0*580|pk>E`{13vds@h1!{vS~#Pl}@#87Zj9zg>3ioWO;o( z*lYv8es$tk-UcF5*G0C-MB|L}j$HjRNbmgzgzK8`!~_T)&OMU4TRT>M>mqn|kDP^= zG+t|f)b7x~Ay&S)7keV-G#wcVyQR_^(hLZv85s<6{N#oKZE+p*v%K*A;FRB1lW4Wv z08r2fb$_Gph0iZ1+hQHKF9Wc z@8ddmM|WrPF|v;XjXslWP7Oe&amM_G#C3j-h|0vQ)xmprMi`=&x5zHc<_^G#j+K56 zEe9b=SYN%yVcdB*X>{@_OlywcoY{{_IsQ{JE3uLA{!GEh#uk;8ROrD4T zNYu7GKc_Svsv3Og2M48}6>mYl^jiP;w+Zn#8+5_;wpoLIPEXY%Q_DkqY>@AaCBdxl zT=QXqN5pM#m{a??Z)#nXdq2<3H^R`Tzv@DLU|b_ks=Egjzr=UWtFv#%1$|7UM@iI) z7Dt#SX?B~JZJvc~R`_6!ePp-$%xrFztFF7rME|wLpZYBseA|g}lMqln0+a-$1$Ndm zDw0XlesZA_VT%7hl)YtCT+h1g9g+|rxI?hu65O2xC%C&d?(UZ09^73Tch}(V?(Xi^ zz}qDMefGKM?01ZNztW7=wW_P1`aN^bTK$646z{)rTPL_AauYKhmir)BlQnziG4%w>_v#kw;0x*)XvzHp=k?kNsg@ z(t3X^h!&dzq`DN^)U?#upgm%()#wvP`&~-A5$tKc=`IkI)RGKwY9%v#&h|!$4=}8< zYyHW#8nRg&xS}!csZx!}#luenOROP9rxJ zd1Ev{#{JBup8Rf+*C`Gclydg_gc$^bO-i%iw!x&w3;_Yb%`t@6Y1QQNk~@BN zSefu{_we}{y+Y(dks6F;Qhbm^OW!>)taH7jCRltt zaa~hgxmgfh3t>P*yxI+FF>^NS*HbcAVARb>hUS8|W{8eC^}y!HXL5?sG!JrHeXf?| z3`yA`o74wFYPFwM<{iE`KjhNygc5XLE~X})FUPxsMs@Q|?e4_EXCiXKa&RCnM1!2; zekD|SBYO-$Nd$8$b`P;f!~}8(rgBPx_o_)k9S7(y(Y6%%H*J6C;2>frA3t%}Xa{Cg z+)jJbrOo8XPP?x?q3&LN)sfAH-r1*lsI#j$t$%Js>&nBHRP6Yj%S(XE-85-s@!Afc zZ*9Ict$FY3Q&?aW`CQgFr~Ic~+a;ALc@BtaYfp^H16 zBLX2W0f;)G(5?_hl5lE?cl_$Yx^XTQaObWn`Mt*nr8C;$M1t#Be{Ax=p z%ML-@y|;nAyWcMXfzFxiV_6uL42}pi_y#N9JhS2@d`^_JlRMLTp5Fve%hkA#iT$5g>`p5^p65^8kxU(X8vDje24}nKm=$7A0bocFIks$2`P)2+-FE_{ZBN6q+c9g2A3L>m$2 zA%cnjG>d-)j5`x;%F8nwdD$vTIuXLIV#l&`QqAuqyM2k4?sQYhSqRI70IIg~EcYNt zB4a~E*N?XGX$n)55;MM0&W(y2DKS<$_JRcayi1B61gwRn*%&2^2ub zm?CZ&EHN1as(ejqFvG!S5X@yEO3#O@o(o8!uybEU*v?R~HaNamOx+3*(-d*aZY)+h zBI6@ia|w>G9l_Yn((1#R{9l-~R(zvjSHe zfAxDo6Fx+)Zt{YMctc&LEC3|@bSt5B+~Z>wjpa}ST8$(67{WQ$5DgzU2<)Ri3J*{k zJYN1Zm&fT8%A;&$R4oi|iU@j=+(T4YZbz8SZ0kKsgg{MWnd$1^?n_(6qF1xCh`xst zGm}3HR|{=gK)95QK<5v{fez~|x1>^gGn6pFc2@nO5r_Dc#0GMkvekj$FqvOlU>--y zVxbtG>r+U-pVDx2I+p)dTyiH;!);{YXy25LnCF{~JA&1d`fk}~-$gyzcgehPMO*$O zLo_~M#K@`ABhKi!H}3FVEO@RJ+YOVWwI zAw!uV=b78->gKnPkrAyUam`ZftY;PW zL4?U$E8%mq$W5ywJ2uM`5~RERQYQ)qq+9M2v%;4Zk4)58PNmIjIQU9ul!M5{R&7j&3h3R?AT%`w0_aL$qw z+%aMpI<5b8s}0+(zKFaRIK$;TyP_@Hd(Yq=r}}*shINVI>Y(ZhP(qH_(MN0wKu=@z8g)3ATrgf6MR_O_K6s!|FFE?u_gw4ui_O9C=AZN6X1uGC1ohF-!zx9CwfMYX?}TI;Xd(VqdVgHokp4d$UQLn665^* z+gZ4Vv_?K#rcIM7+cf^ufy;YKyKUl5^zZOi>!58743@#~8~n_~>hL_Si+0yrHd1ID z8Plfw7TTf@Z0VQhUML*y1;jkK$7pyxa^#9e)dC<}%#=8;a9-Yg1PdcK0=tWzfQC%!4=B&PA-}91 zFK?~n`q@o>>#$4SM3y;kuHb52qz*!f#Nzek%K&y!$ghkNnJrM9xMKMp6diP#krJf7<&D?vvpv8f^Kybam=jmm4(&zcnwba=JNLll;$01S?Fgjde%rVfI!VA7kM!mE_@MPQIj`G| zE=W6g_tCe`#aNJiP(D^uq5N54&h%lOXI(7Ld};875#_G!v#1Kz;BzhWwf!{Xu;=?r z)Mt^n%nW=yy1Mbjioxqx5eH0MH)Xts*_Hw5Ymioz7t*T5D`_L>kev#~_(E>>_y{>U`nKoot@g?g zD)mVofgYHeE>i^nP4avx53X!rni2Tq4(Q44&8KGKy2{cGx69F^5GUe;=x^+vD*-Fv zsfD=a0grp@xSE%!Evt8MgT-Gnlb!kLGjkY zVtK#^M)Q*Lix1=d;PR!)R#mK*q(g=6vczccSVeJuqsij?TE%AotBt=?!b0C$)#IDb zX7VC7*Ns-@P6VGd$yvmm znh3$=GX`1$d&M!2C2nNL3b z7F&!@1VrHHr+sFPlSbUp1W{FCDo7Ap^u%C~{+ut9!^P`oM&y#YB|Uo?&R}<^ zh25AOB;%paMQzieUGJ8@Jg810HsjpjHh>_YsUHCKA&#$Jq5Jn#3QcA^g~7Ztb$8`r z)nhH!=D50f2j}*Pq>RuqTz(iw{Y%$8HdxxO*mh6ndUX9rquWQmd{oe{qzA@Glfbhb zx$!DXTH39+nKuE6pP7N>(`jOt;At26g#d_EdN*Af6!iG8^x^#lC<)4Ch0VW90GPOY zJP_Ew=}hMQ86Q(#EW$a&p-5Xd_yjxD_}t?ezLuL!E$=txaUeX8f2iKXii10r7uTkE zZ3U+;QbgNA`XWWUy)D6u#yLlw^mD=@y2dxnsd8Q{%~&mLi#;xLR}Z2Q(*dIn*L0ob zM@0ndFX_ex?2+oNdV2@T2|2LcDvtEyhpl?z-Xix+W2Ve2(wAbUh;bqh00ML0iwoN8 z=zV9iDH$1J-tDRyA?c)!oCaFZt+u?4r9;bvV?7Vnu$so+TuBogplG-N-FKyGV`nvB zM249?HWyz!V#df%E@YpcV8rF;nN`!pS-$7e&7dsn@qT}^G|6I)ViM|qsayN_>%;=M z9I};p4E2joJ>>E$02^bA5o^Hoo@YfStc(hXQftrI7l!RjZ58nIy}HtB*qj#lJ8B`L z5VBYzSIwT7UkE(MF({HpFuqG*HpoomHp>Ar_q9K)G|JmG zhxsfykcn5E;LbO>!Xv6{*DDS!l)s7LX0{yzm6kN1zkMm_A=ncVkbc;XxgY5~ z%kW$r6i}g=?E3Jm`N*E&5vi9-CyS%4zeK+)EU`)Mi^LyT+ofS0iMqUOGaE~TxW2|4 zs0&2t8>aK4rP0^LBeYEP>*&OBc}j2FcmP^jIC`NQGJo|8o7aosc zwkh+rE4JT@#iY6}jQcRi^I*wW^xFr9SsnM<-6;6aa5^=CKQ}^Oq!LZacxhZxhO@F1 zcL1kHZf9E~!jsEY`eOs%gNPn^GlW%%;mmKT*;ZwTEcLRUVkdi^L&r?Cl(nKhtG%;1 zG?Sy(t7J*sXZ@Uei&=T^r%{P`IF2(=M0!IDcfF^({XH0IMo0W~T>fsbQm~b4r+16X zZ2%f*3Z^2@03|yDI*_w=v@Zn>68JLw%q8+)pj&#O2nYz=pXt*rx|m)NZ)2Vod!f>m zZ?Zs~2mH+NRSeNN9#-dlYg+blMKT3cyzheMOpQEHHMdNeH_N9VW|57~r?du#0ChHYt1}M#} zpjs$W#>>rI-WAavtvtaAa1CJ97AhpQ!ePtZyd)8JjwR7Xsmo}1q)UB5OG(d&3`?DW zW0ktreGXc1Od2j0hI}0)_ZJnFwQJP{Z}5Bw$cpWTonUR)qwSf=l& zm=QV~3yje}7TDabI#M97;w0MC#Br1=rtZy%N2$JkApF%1rkot0aLe825dw{8*-b8K zL#z4zgP_KpK$XF$^o}GK%B9ElZyP-~g)^UJU9rrF)d_2jU9a*g5VIAj6l-3Bccw8g zs!U-?_@*L2T7F2^;|dO8GoGGikGp&?^JE?QVQRa*Avn=0&dY2UBT~6v{4{8>_}Avz zucp;*GXn?YBGmZh707Zrhy)#?$bIFKJXmbT$wWD4B`?$l#~3Hpsa)ov?$*y-I1%wW zQ%QFzP8JDDG?!5c>-_9XFF#R#a0IcWNPnQ)9`5y&j&NOy{}3Q6m6wL`x@u*fwZXT;@j zwv9XY6M`vD=p4pG!wET8&Cs64sF2@we>hTBP%07c5ZIpSu-By)XV5FPAc!Skc&OZ0 z8A_~pzmHM*r41S|K-FPy@VM8Z6sbpDO7oV@fR(I@dZ>t-8qZVqTt8_jSd+t$m~s%T zzi33P@^3I*#&YpVTEp{GWYw#+Di-_<43-A&=!=JCYG~z)BpQU0AAJbHFI)nQ#lJy| z#O8w6R3I{9bV8EHrlaf7a}>q5i2r`S-6h)!duEVRwOlid_rPFpuPi5}nZv`kSfRn* zrF?$gozv0>LKm&sGqd#RB9-;3~T$nJfpl&_N7mb}eIrS`HF$v|%0)a=} zorZ1M z4lSAQ1-f{|@>*N5zD&WIH5_JKA=wtHt{}#^iOD0}0`j|9D|#x7pVwvIpoJ2u=3DOs zRFZ^$Y=87my^TU?PI;d#r-+$*$?q{ht(_$gTX+O$k3tWsqxniJam}ki#JtnVRBPJ z!=v4g zZ@UXnoAcbB7S_179F^qB-u=(crc?Pf#4u@NK3hkZAFpv^S;kP_lF_eBLQIW>!Xx~q z;lT0H)0CfS{XmFjdxGVL;-0|0f(nl}9-i9wz7DPuUg#sF&T;eDZ^kb# zyOnka@=;Z{wy37iDjry%Gec1XSo;;(=5D$i6d+7E;?X|-UU11IG>A(COuO;)$|>xtsC_%e{6p^_{gt>ymm7hSdNB#h$jN-aSf)@1C4r zHH5m`*R?w0`R}}?@)c6C%JXsT@LLWsX0H!I;>FqgO3!m)}tiqXcRJ7~g%#LDy2!#qyFz*1M#e3>mPiLZ{8MGfDb<#<7ki0dqc zcW@tf4F9?&@|99@|LQekD~@oK+L=`|%da*wx{Lo)yvdF0W0>Q7f_fh)_qJXp6ComlU$oc0je#Osnu&W-m8op_uRdvIT)N%z62#ZMOrcfSWn0;)fouC3CQG8>4}%Mcfv?4_1s*!)2HiNX%P7l z-fnJYC?K01gD0D?|;aMr}t zuu^GV;f<_m)p~z|dTBeK-hxZ3toxQ*nR$rfy!&*fj@4lp@OZ~}+0_pTS6$aGjM=x~ zDa~kCFBeNE(*%Wl-DT1NT<1!QIB8G+&^oR!(6;l&wFy5_Xlys2)^Y z8Os-MEnp~xp!19U*|VL%d$y7&CmWxb&x1)CV_D!(7+pnFB6a%7cz%uj0zYS6POT5K zqpxu$i8OSsC_seb+eE{?*rzFJGrG%vUWNmp{vl2NYO&W+`gT5rJN7qkfLy$D4RRq2wP+Hm@85O&FusFf={~#KylvqZ53NMMN;PGw+NJb=l&% zy3ZZPYjPBMUC*!oOVPo9zJAT!&=)>?Yp%ae0e*ZYL&z$C(9GHHQB3W2>Rm|$c&vY! zEkmw=>cy;NfZ&bQzp?<*$NxVYr(oJKGtFPn$U!zb}^e`35zMluJvZ78V2TG_IbsYMb}>_P}D>D|~6`BoVo3dWnMKG`wE#+o}qc zQtO9QDe9z0jzoCNY_!N456E#r+vbcIxlT^uyym_yFh-voU<(Vn5P|M%G{ zTGk}YC;G9r2aLV(3n)AWq+<8zeqrFM4LQBK*caTji19g|*v%FO=F?9B)gk(QJ`&sK zTHzk?YOU?6is2T~zCl!L#dip;%`p!U0F-R!do!P*o|&$k3SwVl5|&TWUSv>P$WEUF z8jF|>FCu_Zd)rb3Vb}mr)m~QR`A3-IR_Ot=vj?B!$caCT`AsLpUzXXg5;0kA)2 z{+8@Vq#8iZ*iPePE)Z#}tHMIZzQ*DC7NX|~_pYG)Wcku- zBS4V+!xiOeA46^>=Y`#wgFLrkRt-gZn8kzweq$46?VJ1xusKKobR=bXD*pHFG38xp znoHS}I46j^v}+}YK=_a1wNmuq7~Tgi}4D+1>0?hjv4$FijTO2y}iQ ziB3&XHt@mYoP|gc9VDza;QC^Ms(8EO*x07$4j= zm0VT3Ym$H)&A9owq#v&(2ELB>ZsCy~fTd-?m4UR} zcUyL(-Jz@Tx@_UFo?-Z72U1xWNK8AzO|}ozqO>?YtmNrNJ4*xftlq884fajjgC&S; zbeJi{*xo&mh!!Gd{-1prmzHd73Y!);<0z9bFTg5!*}x;aCU$)$RGCGhPnm#FdrX%* z!6Qzymr9>B)YUc~+ji${Z5Sz;-g`~-;8f!<1^XK?P%`r%LXNE6D`y1-X-Npm(3d$S z55l58$j*M};a7dF*~}Wk^6<*d)d0; z>+g$nR8k`Mtq^><`^SKtN!;(uHnYb(GRbnPcn$F|3{2-UqSJ-TRmYtkA$%K;1`%r} zWp87d09m}cqi%!_Qd~4K6Mv=JykBCg*o;GFs;S_YS^(VnZ|A$bHo9o@Cscug|BO2;e_2Wl1QnVu9j0-SaJCk zg!T81=L#CK6r@d=@#R%;nS7$xBN*9u0~&*w>}H(Isnd;fNdR<3(X0%sKpd)A9^T97 zfi&;IQ1j#Xl6Q?iZt0)bv4;{EuwMvU)+Zn@g3(f76sAHzq!|3n;XMI?3HNY;VcU~F zE)GZL8}`Dq5X2AhqZ;;1wO5~z`-;1~s(7lPDRzdQHAy}o7+IJ3BSe5Tc6MbHwo{^I z{T}lr>808Ysw#4pIGUCZh~)G(IE#~)?e6|9HbH1J^BJgF@CRU*?5+HKGY=kWH`cAC zfx52F{ZI%^>Zh<<3B4@MKuzq?b~PZ74ZxWyq~?wI4sUACRU}IBehcV5WxQHRzIK?G zWl^{n5|>Sp>czJmFe4Ts1uVK~h;PuQWJAr*C%6}<_BGB4{`ht%0)*635a(iefmj9b zLEZc?`{Wq1;6fx`CqV?L{X#WuvDD)7IeCWH6Sk^iex3Jul-tG@;@z=D`8Z@{?P~N8 zZmGt$_%XiV6egSxxSJT~XEPs^HFHZ(zftA_~Fd>z!uHUXGGtVy*jU zWOevqycS0h{|cCKelhSHM(UdL!$ge?OHX7N@m?__86#l~yopXN&BNM#MC;~_~bY7Eh zM!Hw#WlsPnMEUh?NH%Sv3$k0McwwH%i5YccSk34%z&eX zYz(GvKa8?_=j<|w*1L#xMyj>8$;&pv&4ROmxohH-51Hdda>Ubje;0b{l?qOdYtR?zT>`PHgo!x2+e zk~LJMK^1C}*W2JfK|fj+`CF3Ckv0QN{*fRdRNByKE z#`Gj5`UA6@qEt0Hlqx>6@uSLLP=y|4ZH-xO_w4sdAD6({q#UiK*P90?8>CqwqMy#E z@@36LP`ERp`sa7iPp1oxG-v$I9}c%$C>rVGa*79Q0w00u(I2c(r(2CraD{DQTsk!WH*g#r1Z-(3W9{gRIW zS(3dtQw3?AT-hM3!FM8PT{{Vfy*m+rn&2SxBi=PXPq@a8TlQ*K&;Ib&V-*)&?`!an zqmYzkO(pU){48t41ARVCKXY*G<62@ zQ3@_Sbyqfy^%c#Iw=%VPBFd}R%^5W^r_L}&7SjxG4iqFbKAYSxU94nki>5k-pEW4D zh0$es9dan$sP!F6!wJiKmj1RVbyu({rP~ER`5wVgo~p>GZD9V_`;XN7&1@7Ag4s2+ zYJqV*p_Cq&$*6cR_&ahDl=yT}jQ~Wg$k4BJ;S<1sz36#z5ksZI+ z;aX3cIGM%fr(!edj`VkNGDG)fRV%8LC>ZpkH5_~_q%}m)f5q8}otOI>;~wrn7VR3z zb1t%xXT#$Qzi@_pV!AI_EpI6A2^BH*2k%XW*v@_G1Dut6_1_tYCd{SuIuMAB*q zhaG6F5aLo5fpiCn(+J}^cK3qNu_}!T+f6kUSp^$&G{6u^FARZ(P%ZenJ@#}WUx9TF z5#+m4)-q_<%0uP!k9=0I9KKA~zy39aX;Ng>v*Zn952_(pSJ3kL1>-bPBiyggda`v* z8sI`imGAnlV5L}-m1AvZd=lJtG=b%_DIz6Uu#GPH3lnX4^c1!D(E3;t_wg(1m1i2w zXjo6CZ92)$1_!opQ7=8=;4H$k7dGI~kJH3GD!L$rY-C$+q{ph)xngL;a_l1&ll z#1Jws^0Yqn&8kA}F`qmu^9bk*rZlduhjrUUN9nu9wOc}tWG3aJ9>~2Vbn-9u#xUc0 z3e8pW)+zP7@5cRKlPBqw;XiCyR_FVJuX-@(jR=S;#!?sEoSJK^9H|beF}{PBeg{)T zmA-PU%}E|{@zY{a3XDst-}6YFim_^)xhV>HWnX`+lfADDE1z<6m0e;EfFDj!Q zy5*I3ESPgOpHtu=lEJcdxr*(5es41Ovr@1G$pk_yzH72B z3t5ef)5X@gzV`ElcT;iIWLJ#Y(I0_z8b9>4qcL{ln#gS@KlBAynTEErymDJoEmyea z0k#D>X7kd=z7`FJ(iY#P6ly62Pp7K4lVM{VWtFxzpBI&T?8M|DRv z#RmhTSKbN@=I!Vf*%>HI!@p(){lN*Kq%Yt3nGuV&ji9*mc%_G$?R+2UNS-BZQbiJ~ zS^7^(6(E2;6h{q zk8igsCS*1h_7dBX296&rRdhfAg0O!5ZXAu!B}%^<m?T2c-6~5|)pid7X*IkK76TuZSMfgH*+qS*Zhw4 zcfbz>({cx0m2#XdO7c=0K?7Tx$yM+02IZa=;F>{;;Z9*~qkNA3I zNE|N5`iK`M=@gCMU)^xb?SB*>-;yu|tPT(WSP-7Qh)tGtZtk3D2t*z!+?w@7)s7au z-wuO;8f#_$iImvBPB%NbHxZ`DnXdy1p6ATN67n)gH^YPcfm{AJNYd`?SZ#YfYaupc zzRjo;M?1>Iv5RYiX2vC#UdRcDD!EBj?!kG!UJE=~r*t{D{$Gz2)3_a`BHy?eiB#i& zBOFXYLH_rV1X*m;7Y7EoIQ%7sr-wIiBKpd(IvlLD1udDja-f z?ty_WpLW`YOg$`8*|t$jLYtzs-dz3mI{!#!1gdFn{?vi;tfsY!bUZu^Oe?);Fk%VF zshK2Eh;yap0jr_5=-1$BvK3W>&Q*D=BWaty`73gQVKmogdxBRB_L++uD0HqcrsKMx zxei({X}(^P;$8_doJqYIYsUxTC*h3fEPxd{%F@hMT`rr1Lh`x!^~-`^3e6+pG@&oiVKAE#FhZdDIfJ_UL~P`R|^9i~{MuZZmaX#x^NcoXGk6YHZVpr})ip7`TDCp674k zcY52Ka1&E2OOf`a1gZ)OODO-Tr&u*N$LwEfi}!%4s#kHxS%wPN19>=Q))cwP#OByN zF`t^7=b`C=eu6bv%i}u~9)^<>-|lp|&y1v4o5V5&M1gE^OAo474E0UD8Ex0{(BmHz zwtz_hqn5vogLUv7{VmSXrc;RoJvd0o4DN+7OH&tO_(RiYYuv3^qbjN4G`r6|VS`48 z+HzHr!}_UVFR3B|5Zdyc86|gwmxFKy1qhgsZ?SlkzEFKqZ~Zt8T(bQj+{5_^_@943b4P$v)O+%LxP zSk-*aaYrxt#?TXU>+Cwg9aW6>)7GUua;!dDaiCxjSKCzlDkhd>Tii~BIh2$wDE^t< z-|Z*gw(&Pg;ZoIA&H-_ zH%#cQ{hNPif23z@O>5(|ks;HmBQFKBiy!RrtOdP0$7` zV)s;nfLNVSFAPluRxQFGGcX;6F6|Jb=cv&1C%eC;{g#^3biiptu*NTy_94jD4>v-6 zWRVBc=4>lj!k#hn#h!&=<@u8~nR|O&j%2e+Wt`$_N@M{rIiWHP&&^7U-h4d_J9`hf z7xX28VSkpM>qz8eK|iDVikX1JOLFaqWlz$uZ?*S=vPjqD6C@-b{pl9Uj%S=p$rBBCuuy!}{rVSnYPDepn&8gHT$JKzg zU#%}BKM+4KR;xo%@C-+2zeubRZ=M}x@aHz5wm~(XTR2)aCAv1|%G6e5+q4TT%8tt` zDU0@;(Dg&Z5WCl7)GT1Xa8$uaK13~J`^A9lz1cS@UM2NxY^kjiYR91q>b5=wr4a;x zXPfHKxs$LYgTKI|*vC}Oo6`$B$S$(8&IZthwc*(>;5*}!t;}*Um4Y^YWD)7Z zk!`E%3q@$s{PFsR%o;;O8D_ez3f_9{SSQCuMr#2?twlyC?SLq?0~k{8AIHfr0-)0L zea>q9 zx09O%J!o*5{Nm{bxVZSIa?bS+Hb{rK8s5A#B(ux!5pkXgY^#fuGa*v|hH_$Y1seblqTHf7g^%x!>tw_E>J8H%h}Sb7W2MVwA?-;Qixf))G zA;PKFZ6<%9W6ysH>jd7()2NLuj27Gcu2#@pts5=fPFjXZ0jV8kkij#(7?Kfb>`Juw z3w~U}k9H9OsE!k3CK!Jt_SjgBMZ|xIse7S~^uDAP@gLRu7h{b<{;7v)yYydE-WO?O zMhqbG7bk@&yX_As0;Ci5$Hy>)|K;#A4_N7&yZaa5F#R8Y4rCSE5k>nO0)X%{X_`k% zw~GeC;8{Pk@BvPKDXt_%{bT(5%6Qv6x#MejRax;Qwip1J9g|dAaJZ;qB@k9-QX+!> zl?Bl1iwOW<&r}>2cv~%4P zwz=L2td@c!=6`9)-1kiwSw*$l@6UTs=)r0#hT}2Ut5v_lM*HxGJxjX9lnvg z<_|&m`)47+TuP{`=%;Zc;j*KYdY-*J$<-4niFdeu5-N0hV3dzPge zK!#w~|1`1k;#(j_-)nB%3%8S}J>9lCBc^CR{nC6)LF-{d9c9JiC-S6nWD;G`88gc( z&VQn1M)2wW*{#>ENBO@T{Dug~5CgWzm843#Q9OY3t2)4(^27m~1}=&NPfARRW+DHP z6j$_OhI{nmc<@F*IU7CNUc+`@aAyzE|C6(i2HSoxG;gjABBYkg{%s4{IpQV;qb2oI z4_*0imAD9KSJWgD?%R`EJhYkXKfM%t^R`ME7{@YZ-V!ua7e@8yHi5*XTx zcRhYOT-b|L3;tj55AB6H(B$>2JTCh06OHk%L$0=wQ+RG?NuG2k8f&`*FCzSRU(E~Q z7b!b_rOF;tsHc9(meP-mc7u(@{Wo>ao@F0qSZi42{7>mQ7N-5+JKQ{p^0Lk%>Z~ke z&bG#%`z1aE+8wruWH{n|_f}`c23pbE)9f>9G4z(JJP%j@j7Y@0V|g_v{^DzYjF379 zfHgY3I*M|Yh`QDru_{fi{iw%KTF+I6?_h|1&TxzoN$*pZntq_4IvQLodsLX5?ryemAaD za@(A;t(v!39*-c?3(WWC7!s8$<=Bv7eUR1D{#KZc=be*DuJ+y59 zNUB(wReOS4xOjjvlbMXNg1y1mX3<=FWZ#03@R(#zIZH#F5;%oe&HCTZr%hK>1x;c% zybs-rc&EdQDqU~+sUmTkPA553KfNVl{u{nA)cId1olee~94rQTa6VT2?lt7T8vfiVoJG?%YGB}tDBDD3=-Mo* z^+Q7Hvl^p1GmqLK|?Y)+e^c=s#$}z0si5Muqv!V zi#C0+ur!_aTN-iG_7`fKOiK)~h%h*v6!8Bs_ZC2Lt?Alm5&|Isg1ZF|!QCOj2_8sr zcZc8}+}+*X-6gma+}+)!(YuZOs2lxU(m2K_^jZaQ;6-EE?E22c8f0-6bi zko-$X*sD@4w(@$hEQ&Ba34WHh$|+%bGg}pH*nKi+3a+{|%X8Uk(WKkI^XaTv#iN@> zswW*x*Z$17i8n#>%qYjws9uPS3OJXkLrD2|zkq4Dr078ZGZpbF{)VWHngZa95Ls&U zMGbY*%xA*Gjwh=ck8T@vObi7US>#>pD8|!^YG0WhRA79j0#0!_x>mu1N}dS528rtI zi1&7kzE4(q={EDjQr)-m@B##J$hssNHG%1J?LgfhfDK-^q>c|ZxXZ_4$Nb>11jdVD z)IXDPf7qV22b$!3v~0`>7fhEYiyXKBdLcZfG~L4c?|wdRc|7#S z(86Lgy&DmCe~r+=89o5@t)DjJh2Nmmu6l2AMS;gV)AXh8(jjdNUqKe8*Q9HGEc$sI zy|!|zB_bb+&yls{2?PB>-X|P^ti5f5#M4Y4YznlIyj1b|Qg1;X_|;IT7tDSKTVDmD ztl69;md36YoAHO(rj8)Ia1rY)&OTd!oUWa?othRNeYW@(rbjzM3-_n=mbV|xPz-(r( zINR>zMfA5SwU*B7A4uU$+m86x;%$i8RZ@Bs@=7h zFwfu3N!YLx#pK{&docuUjnd)d5`dEoelRR6~Lz6J@sLbX;P;-jbj$}7dl`vr$ z;oBJHaASoSbGEIc#A_l=jBB)N7vN?R*5nCahV7FMqXaBo-#@`7hoA}B6A|KdzO*&klOEwHcFi{2dh-oHl@ky zHMyBdQkON^;=5)ym!u+ZUwt67g?(D5N(?kbO0-@G%!ej|EtfQRl%R)2!tQ9&?=eeG z53%X9#Vw__I9uihFL^*Ke7`P9y3J2Ir*#-_oUE8>)&sU4@{F(&wh+wLT{|k%LBwyH zTs-SZ`!O_&JWPv%_k4r#+kHPW(>}XJFdv}{#Iy)V*l)98`QHY{W7 zh7C>*O0+m72hdq9rCLcWKA<>1`TOGca>X+SeUk4`j@fy#PI+PB zgASYh%7)(Emf&~3h$VXPH;_rf$>sTcfL$WZY=Rkp5CyN7WRhS73bhpwa=)<3DPB(T?Q%f?qw^hswSr^>hUsBE z)cQlX<)d>aOpAf~BleMWl@*}|DY7jI^#+DnxPjy0WJ-^2ZSl^R2XA#6wob+kGP@TfI|j0hg?T=1O0s-0T1P(TUk}bP(?qOeisnZ{rP47L zd3|(uGH?CHQJ;IZZQL&e;Vtb4x4?P6MukOB^yB0k2%RWtF;GA3X##c78)r*>xDm?C z@hUfk$&V5q^_XdaSUk@ibuc&Jik7)Lg|ecQx8GWgnv7?NmEmj3*+byXTDYD+*FoRU zBzen{>xLMZf+Vm}?96D_Xt(f+oXUud;()HL%|9&8bW8GGFsdb35K zDCcZfK$LT8n)ft8^+5?PbFf~DkHsN}S4c$YN_4+w?(7~m8ut>(coH)oe zZ_PLMKXRCPKCayHdzhAcc(VDQyJIHGBS^;Xm>NqS5SN?3MTUj(^zajL^-e_Y$3REp z^&K4A?9q$k`B|I#$2wvRg+ip;`U_d`;57Md=O)+?(#Ii+AZoM_Nh5arQ|!tE3M?E;zIO48NmJoI123)c_tRGbwoR&>Rh^j~ zDAIEyW8XLqHFaQaKx!iVPQ&F4~&ht;@F@ zM-y)ue+6|~UqC(-d~`^LO%C}Mi%Zo*>2;=&(DXMQ0ZMh!N|#xMW;$O7`7L-seMq;`7^_ zJ;AFf%H$KyuMZ}6Ns%Q^FmLws&zysdjv~gji?iAm+-mX?ql|dTIltqn=`lExO@!C& z*0`_;vUL4Da1Szl6hA@IrKE!SxPfl)L9H9>lx=iUB*zFQ!cbN7YiHiGO4N5#*M&id z*WC0svHNphhfw)27KGYkLb%W z!}-q4a(vJ;3Lq8_{n~}J@vNMf={}~-I#o8M3$h6}ep2z2-+Lvo#o#V(RSLrI*1&og zh1aFD$kP_%653f=yT_}#^x?E7H%Gcw|N!}$u+K7+Njl-m1}{t3qIPgDiggVTU5>pT~4Z(!n1 z?pbPK#&A>Rx}w*6rS`$nnB316G&pmlp!Lflu{{g%Zrul7qbrbv9cyo*m>G=9BeqWd z08m2{U3SuY%kRA-GOYJEPuCKHx^};LccOI&qYv}kHfVSj!|jNuJ-C-!WlNdPGtAj4 zxF{|xW(W|R=L8?a^P_q_wYtJfJr{(gBIxd9CWpm3&@|hkRm8F$*>j49HPxit=N7~w z3JyNVjL%ve&Gk?)*}NIeuv!C39RCz7;*QdAd{Q-0qCy zIcgb3tK}!I`|Z&1^47_!-euS*gQp|8CZa1@R%=jaEDSAP6kp>^Qf;kCMy@#TY}LTd z2R)hV(`1ROgyF|WeFDOt!a)5i9z^Ocj4C<4^V7+swhxh+Qo(f!%MRhmq~0??YAbH8+O}5KA6yU|ve#dMjo>v}>*VVK%lTc45 z_gHvD2VUwU%X5#hI6Z4Ub00+%VGT%P@C4PXCDaf1^MJbvO1WlpoJ#~K4oTIf@X6WIT6Xd3ZgmShC%4q`Y96BP}(j#BGq9c!o@P}1$ zN_{pnsKk=4p{JUdFfZQA?E6fAUHsu=Gmr25aR!pZz>f%%$>qgmAAKLT;!j8akk1r# zze1j&CJNHJd`5|CxExtNS+&N`tSn3_tn4mc>Rv*ZyD#*?9{-qn`<@Xxxc50{@c#tH zR)Sz)Z62a$4u9+-;9P*G5*{kn>wC2a0=+CSmFHj2-kv2OyjSlEr%g#`DrJ16YH4Y_ zOuOKjsW5pd({-h#5nEtVH=Id2eNik0W&vaXJ0TwQZCg)U*dG9pbU{1eFFbUwf5a2=@QuCr@KwpBm5jl}Ggd6N?Tf;& z16X^a# z=^GJ(^~-bvTCv#42`Ew(p&|5+p>chb`6 zLV1GCFd$oP*W)AfHTTQDjg*|;NHCZaU9|z2#>&y$;PNL<6Je)jvtla^pCpx%2q zT&Nl5hFEs0*Er!Mb%fzsc7n`^vedDwnznXOw`$0P+^Lvi)cDGAYaRFY*7HjJAecwLC^oSjzB9HFD0EAfH z&EqksS<}{ujbX}VU~o~&H6)ZUWnP-$ztlwqM9ij>en%buC})*2#x3OJI- zp1>)gG6OZbI*S9@qI<|Ap~m2Xiim0=OV;~&9%~hBety#*K%;l=fhnr|0aIpJ+Tq%c zN06$q5|52v#|ai*zOfef@kddsh*R|asiKzU%-ZdbJ5P<)cZCr-3{*F?uXdHTukUEH z4p(4dU?3@{)A3rJZ*U%+8O)Xr)SC}}b|}Um4ekE-P@dx-QGVIwi=14= z<3yhPpe`ldnjikCwFv@Z9pY10qsj?)JN=a{aDc4qe2p$x?YsW)^HtYVVme(0jS!m7 zDqAK?GH$1X7!_8@elN0EdY6}JA)KGGFGPo`te@dlCK(a2Jv?tS-8}FiIZiiXDcB-K zv}Y)3DNf^jSXI3&PVVmLA$V>;aD0m(|9|4@7?zGs|HSg84Yr_$q7qPn(m(bQRBTun zCwVNqjnI{S7rS0WbHY0^$7(aNdg-m1bOF`ORo8L3=zJGK;YHYQLvdRSKdR z9^xIlHyzOn5Dy;bA8ek7zdJ;Ozt!+)tL{4mELZSQ856_lCbIY7Rm zOK-Ow=)GP0ZsPo=dBvv71M<$*wkj_a_F;emn_%$0>VmH6fH-(xsEq4^R6C2_CHJ8l z7O{>Fd_8NDnK(>@-rsxS?lrOv42w113GVkXafpM6J>923H&G8Yw2Wyp4%4+%xxHC@2{q?n>T{6< zF!UCSZg>Pedc1BLGx9#}L5}dv4m!i5X@chz#_NxzRjD==&A`*~zei~3!#+MQ{#k0v zQ#1@sguz4N-=}h`e{6SB5C27RQsUdJ))dd%TarlWH8S-Q%8bS|)W)3a+{$p6d$4UwvOs1kjvo~ET+8+5ptA#87W<%R zikQqQG>y0pi`3_Y)c%$QU<-tS*-5^|=c`^rS;?b0#>W%_;cF1YiV?s%Lozqk{dgHb ztyDu|iLwL9z*_b$nRaYpI(b$^dj*FS0}TZVIpP79jVzjun$i;?A!#sdnBLW0TI0lo$d0@%ZMe_lYU`Qn7EC|J_~$@2=Jym#0|iV{ES{xi))4SJCRAfFDbZ zsU-iQJZZ}CR)Z-)gr5rvG9tuIBXY*e8~M?)5A?KF#eT}8OJ|>42~oim|6eiuePIWAb4Cf5Vh085YZZldKhZk7vc$xeg<$GRmp-nY2&k5J4XG>U#EUB1EEZ^Sm zD{2mGeoF!%OFZ#$hHBMXs@wMtg9ObdpyP{&eKMY(FN(f4hTpMMVLnPE4EvOv!56~L zNN5h(V6{XQHQHfSm)Qxv4og_n&^olEM3@Gjg!j`)EXED9N`(mvI^du|X(Vwb8H@;7 z)Kg=PfBY>tn)5Fc2ZLfW3yfM$0AEQ^_CT{c zZV=blbQgn}4DMC}3qlph{#&DM;zv#iUj9R4u+W8Mo>u)n{Eo#cu~Pvq!)HND3Ih0m zur_N}2&uQE3p0EyO6aIwDj%PZ2w;ioY5~*-td2%`)>Q!NMl8eySHxy`k8lVPrzSg% zSuC&prlx8Mmu=N&0e(~eKQ1(IcP>qyj^a}&&dNVfd0Ipi#}s&(-xWJg>~Y>!NO62P zQqlvn-XaR!iF(6%)gRxmmT0o}+d_I`S$F+Ufl^Qxc+lUhVep_d4z+HvLijxgtjvYA zG6;pK(t04ntiEPg2s+41;zt|O;H{Nbc`zvIr(-hT}pu0_HhtuB18;tovGA>_VV-i`}y|Z3NIlNLhx^6$%wzOX-R=9#d2tK(?nfQn&&!isf_G3`F3B5q;hWP8v2 zU9Glk*%AFq(`S!EkS5G zdoRl|jKzBM9jV)i12RXe_j5JYH=`23I9j%$UAm;tSvw%cmfNeba&n3Na@8)Dh~fd+ ziu1{Ek$3Z}Q%|?}!|fQZ)t7+OW8kEMyW7+?Eo}kO!V-y6msW_D&GL`Nf{yvxPxu%x zVi3cA>;dY>1Zm_G46a>(?q@2ysVknKv2T$PUbjG6n`1>x}dt#Po+4&_x zbZbEI0`M)J{FxS2E~4Ahy_BC_Qnpm(`z5+vt;E$ThBO1rUe%R(G>AI4*WFOby-WfE z%;pcG)YD|NF0%U1ma2ST5`m>|OboEDh1ioY@lRC>VnHaHu0!z^=C_5iEWi1U8r>XQ z+z6c)poW6!WV%S6!be9W6I-ov9U0k~?HZ^&PsmHXncW8lviSK*6&?ThsiqjUrqh&l zluX2o1~kOFPxZ#WzCEq1lN~3~A0_zM4ffyn*b)G4Q6a_DK0r}_VNXz&Wez!bPu!|p zv#a1Zm@w*GqVDVO$8|9$+b8U@E;YL44h~nWHmx~P9NF#8+_e=X_T8ZN%Me+O0m7Kr z6da)1*Geg&h&*7k19GDGNc$lm9EI_dz@5#R1DxXh0>}Yb1)f}?KsS-qZ(Rkg?|J3Iy8}8 z>*uSS@V_o=jUiBdfb#MXJzuZ+t*D^u08&5eRh!qiW04IdigbF(*uJ{%iXLYnnF%Y?F{>=SBxV8-M#Z ztHsD1qU&Nr1ZReB;o|x+Q%ZJkXVwRBJX9tp|FQPX{5*7K?u=0Ra%8Lgvc5!scp7Z| z2rt|J#?3Gpr`i{Y@0%*~b_%Yv9^IL3%Z!ha|7y{fdedOPFpff_(KSl1wRbQP+_3qF zE8;z6;)E|y!q&mUjo-YOa=%U{pIYTF7p|5=vbJP!20FHWaEl_C6B(G1SgR?I0=#o( zwBh#z-^VzN2XI3mp;Ai()+JKG&Xb$%U$TPNCwVeSJ;ihB#Nq%breD1G&&gyMzW7zd z(kYRJu^qVNC+WfAAhQ0Ky#QBm5&m{Q*tPZBGBI~Q-jADC=^^$1RoKQ*l?MtE$ zJAIty*B|3-UnPwbzCVXypV~DlNtmUA%sdYyohc_Twm|l!<3y~xfBJ}8t!ooyZ_S`_ zMP$EVTX(n6=ekv}77T+-FaoIzDZ6)r$27%YTBYz@EodC&hP5=;5!wx#I>e^eL@f?f z2Iu|YvDNN>oJ+_2DvMBvyyG5jDveGGe%y|4)=la}TYCFl>y>THjko26(hW4b`9<^P zsA5$zX8%J%<7Nq1MPk`v93BS2xsG$PAntg8cPMP&Hbz$j}M0*s`X$u;P)Pr`R5j5jb~84GT#(+lWVx$ zD^%A%4)~F>n8d&hDi@Uudge6y_XE}~qDL#IzlGm(Xm3I!#y^@r93Y<{`tI@0WwbUd zJypjTU!_hrhn&Z4k=4kL#CnpUaPg>ZYG?JAQ3iQMiMo*1Fk|(}z?^J1XcLa##3dQ^ z2={19w(=X+)j`|Jw1~)0M&md$tZE)YB&R3XUH+Y$%{XAzE}%S=ArJPmwG?ab;pFjE zGRw4?vn#_z;fZLKL}ED-3`Ts|q?Q;AsQm)ZS=)%R&rZF`BlV~^FJ>*}3M!R2a&Y=Z zTsCYI+XvJJ9$4Z<(Xnn01&C__9}w68K@O4Rmwfvl%v$+44nw$8_uZ2!J652WXx&d_ z(sSplLZCv>OK#s~=^SWhaS7IbqMCnz$`1iZ-et}DBx;4B3X>_#M~a}Mm@hUfLfU`@ zEdcri==EKfI!jaR{CjVCA4!Xg@ z5)->&SWlGisx3v}HMU_E;_knDE$Ee}PHXP09UR+RpHH~Tqu@!^;n~X=S+>W~J9AIS zKm>Jh@#0HNOB>cCtyZsNV!h#F*>Q|zOvIW~@GD+1&jAn>oq_@}e!+@NjTHtA?u?6iFKqEHh^Ob@>V6|s&P3`VaT8B#1#3B!P8PYK(`ZqGiJ9$QhHV$9=mu>52@cc*c zFucsJORQgnX6dt7BH=-$o<@IoP;Kuc!_iyzJOQcex7e25S{k%vbsWbBk8H2e82(IW z`D5)4TLFguLG+6+4uTOtv6-rsev1^={IuWxUsuytsV?s*-OyDU6u4OYdRi-=ef$qw z#mKnH{EGqk%cXTD*C23wjxERDWytJWD>eJhugB!6y@nFBg4GiAgerCW`xf$93+teK zdPW)4X~N8tSK6M>@fYjWD*sok*C6WeS#JUCpxuHaXoBKVMB)<`AV;s{m8^a@QUBKQ zjy6P7S@VZ`n(s@zyDUg=F`Ipe#q6Eo*;%38(REEuy8YjGmGx$diU#vFFg{vjB#>jJI?Zgf92A5# zPXUpCtIy0_`d{~$62mApHWF;n5qEt@tUhrqvG-<-G1NHQxF}(BzW=+%)BSwvf7^6| z#1D+ND$iQp84?;W=+U)Lwsu_{!EZ16^&ANNQ3h}X9Dc$|Q2LS$Sg};+*dQse`n+Bd zbcO@?`#t7&2}&(xd1wM=js&6) zbEG?-!185YznTV|QEb_|n%$P#RKEx1d0^|lL6IjX(PthJ`nJey0%I=YALv;usC{WT6 zzq)^Ycw>@@!m596XV#b=tmv-^Fne;j^Rp+pg+9&~%;HOJ50?(3Ocq~&pKo}@9Q#26 zNLcdz%SsHjr2Us+XT!G#dCVMD@m>7Am(bAKp0VyxrXs!EJz9+h+{^k9>faUY8mTSm z4?HH>EY$Xo9o==}?zmQ~WWcNA+_uSJ&yrcA#LixZ9l zZ&#&bgVSLq8capOMM+a^76@fo1In87kXgIBv9uQ3H`~PMgnV;oI?M8&{M*ow1nL)m zx*g@Q$PAec1L%N%=_-HO$s5n%Y*qiEhpo(?ttD^ot^9>7p1rS5(9$oP_c6%BB^ix7 zgq1D>vvFotLEo$HleZ)r+rn{!7M^D$_l>!BmdxF$Sw5FMAVr(yA=Y$cNJ<(s4zWv# zqu^ea6(Zs|Row_^^su^V&bH^nF!~lfrY-UA(KUuX#4EC%nU-Q7c~QPLw%m8h!rCRs z$PwjeSh>?N$3gIQ$ag{)CKGOS$M0)a5G3Cde${;-B!nOW8(q8*axFTrWs{%W3hXeQs-2_Nri@Scn4824cw!Dr zvLX@rTz?Jy`0bK$l`>5p&pz?>BwDlaUh3Ledt`k?ye;n+wm{9X z&K#t23SK6l#GHO1qD^>$;PLP`F0R=S=F-i3OBVaL$b5PxtyN?((-en48jBr16eN?< z&_EX0BTSAfpJqSc+uT2h*}ld`PWElnR6g?Sc_syxXxucG0i9xF6Nt{t0YQ%K%(4uF zc}dM#l-~&Fl0>&SZ*hWMv)<_t#wmq>?&$*&`Ci%HTlPo^!amg4B|J?((mhK2TKUGIn=kD97J?^t=9ltHD8(CD*7g<}YWD%nLtasn3 zI&|xF?cjPDk%ACR!W=a};dl%hvaBRTpDbKvaou0@Go94g=UUpia=;e{y?*(8iZkHt$0JYMvMcQ5y&bRt zoI^*;ZOTXSi0;1S!?^}l7BW|xn%vr`EYg_cUB~D8+2{^AV9kXc6t);^=a@bD(pB{Z zG>zRBl)l~HN<#{GwjH6hWLyTOO_Zi(*SbVG4xL+wJF63&)tm)I6bS)e#I97`(VUgm zeMN%{aTDxmBe2`h2XuWa)fxLVuX-hZ z)??4faQIOsw!h49Z+k}DohcnUHsEf-N9V=aDwBYpYVNXH1nJd}1#Jb^v;P|&dMd%m zw2O#UXjNSz4)CtU-L^bn>230P#^PxXB};4Hw+)r`Nm{7xS?I3ttm_?7xuc$VdU1AG z;s)3q>G3oQswDss@Z~`&p5=%*W?rxowDE$i;Y_%hCU|BqhQT2riB<+$V{K9Q+&d-? zmjgqPBs9#?6H;r8oE@t>oki|X4CXZ!u-Zg9t60A+na%fgdi;mj4*%iDn_vV?4E8C0 z>YXEy`R$#E_)`F99SYp20>}R`6#JiYo%O$hI8amj;0O&~M6V}Mi?dokWpo>9LyV*7 zX)(mr&k8F9XOvCU-WYVNRD>BT+1~%6Y+Gi(^RgiTgi%M#hAs0jRJ&XOInr%?wM&c%jtz{+TAZWkGF^cB& z?dZ;J{3e`6p@M=$#8g0z4KmCDK2ljz+z^-*HVzM<;+yxi&IA#j-aqYS2w*~i9n0ur zi!~mx%Yd_+@sI6mxfGB)asZKd6Q4W-U&s7q*<(Yo~PuBqY z65muM!``;Wypb@3icIqzp!Ug!7h(M^3m~iH!?3Ta)%=+cn6*%uYz5W=t-~~z_c;DG z_pTxYV>AraR^6|L3+lp(#ceo#?j`I2|5_ORj14ErnYc&L}yG5h<$V$t;vcz>c zmu|L!yUu;rj5;d~$$oiFnO>EqS1CuFLKNRM2H&`xbr*mAIH|V3;be9T43B|zRM=@P z#5&w3?u>x(TNIfOz2WW(w(I!fL z`p3#0O(mWeO5G1nAY@|W%iMnWk*#6|}&y#2Go_U=i!@ZID@jE>%@QsZ3RoG)ZE;2#&7Td*|HOdgq zSV%&^N#-$Lp2n5>ZC(WaqYExunX|acp2iBz7ByKn2nXIX7CP=sNwd6MnEP9Mj;p`+ z<;_OmA~0-(!aH4CgW0sAquc%VXL#ukmYP2&G5~Wm3TAzOh-jvi8#U~Rhc z(2(QBxMz-cdL*O2Ay?Prp0$ijV$h&A*gN?A1RJeTf7l6=DlJcXn&6?=KiQ}((qn%b z2KUoovD=b?$pxL=Fu?cqdf9uzCAKH+;oU*4k;~vJ=CBNEDq7>Ap+7o}y200m6Kj^= z6E0SAH4qxgs1!@n#<)l31EyW(Sifv80=+^Re6ap(Uj${j*CyS1lnhj z0n--?JX>sEF#6)-_VNsyR91t1UvfOX`ZL_WQj1));{PQ~dCM*S{LRoojI_e~f8vK~ z4p4g{$8ZPb9eUtA+`U-t{DUA7KT6|ELIk^49wMgwG3D}H(V&p>5O)EfUYT7BsLC9` zrz8?5YU5vItNo!UGtCiYhcF1Zku>Ul#s!u&fGEKmfQOKHa7}~`J7bFoYJM{BpR51f zSOLTszx)fDdYcLdQ=~9&IhTJ*2GU8VwQpqJl!HgP{uuqsO9}pGzd;xRNJ7R)8zglg zhrm7`Cioqv0fe3tNzSW3=oa&1_%Eit_h$7!ehVG>da1d)oF@V)D`(ckM z!x${amGOlvpi@4lX)g~wpI%{&>@+0nAcw+stzqc<3m zoJenDUrRd07uEwB}>qDE#S#ItU{s6J%Iy@K6(6VQ}+MR9a?03@A8g&NTCFt9&$Ruihu*~DI# zF*|%#DF_CTtzl~C$zv~?L45rk9I7FlLhZ{vK`xbxmR|hzW>LmTRNIWxK%Y zx5S7g+vT^@1kgY@V(@7sPZySC5BF|ljl^nS8!f0vy+7NdwrSZ~uAGwu2(Xhi;E{$l zc|pO;8zaJQnWp=MY>q_YGuX_bF;CQ8Yhi+G2|hz`J@j?V417oU^YGT>rL|Tbe&Gk3_w%6u>84Xp#~Ai45v*?M0+Hm z!1qxbu^IsYD?)Zle~`kdN5_y$99+hdE}$A_gJ))F^zQdr+mO+YH>2^7d&RH`fEQ}| z?v{AS^wF8Fo3mGP|6A#!FMbznHieZ+QSh(gB@>L!YA^%42Rfx2x~D7hmvQ~r(sUN$ ze_D_Hpa-Q{-let@)rC1=h#6U1B1<95VlBz8?|Bo?h$rma@D0;LFCamGOb0Q4qS7x& z&}V{q_uCx$i``k~-T^uh6GEI&?KQ=1buEhmkJbVxUE>o04QOeN&1P55VOWOt0or%j zZWX!_LiDxA%*;^C?SY{{6&Ae*C9$zD`2I#3^sfi$#d<`IYe3`-1ri!-T>A zM~E5K^Yj14Umb#uX@VJb3E#m_yH0}v3Jw+K#?@Ad5cc*~p84~|fPXT=bD@Cy@wBG2 z^S*sn(MxX7x*@vPsnH8@TFUD1Y7za|QiB1Tpxd2j)!H>VWls7hX~tVx&FVVAcf%C& z-(j0iFJ}iZ+BR`B6I8KvAutA*9fUHSR5_kIB_Z9Cx#^fyg%*ecx8D6CKf!&sRXZ#b zuJJBoo%0YeOld+x@U>0NM_(n@e3u`HxLv$3HZixu`z!~tsM+cLs_V z7h6+SAq-V8rLjYl7v6-P$V}?3vlF@^x)Lqw^3UjE4oo{_6>Ug9tOGwsW1ygEbu!K^ z*2>EUoZJ>f(gi--wb%aQH zVKHLCIgH_bz-|~XOdO9v4=c_#I4AX|z}|scCMwJ(W+bH;;-Ek<$JV=mp;WaG-uEcU z^{5ZaDrt`O8Dkz5gTo%{ijY;7Orfdbs5JeN?5%dON1u9EV=;Nqoe7_nAT_`2R0P*- z+>vYab8**ogUL{p4Vs2?kkgT~SEhT#Vp5ChuqJ@C$@kQOELm!JQu~Xns?V7NlYop~ zS#^4xe^r3IqQi4|;Q8>g->cyB4sj<=T5pTfoK>WY0q<>6k)~ky_`{)OWujqMsrFmH zS!%2z9`%h?mg~8N5=$!~G=^^S!+ncMY1K%~bxXWPmvox^?EaF*2>}=pn&PvunD0rN zG4J9aPGLI6uF*Jbe;SU_YKCYGf%3I!L z=aTziJlA`{uP#!vNrs=D?LnZd?gY8ekbO2(9Ys6L7e{AP7U$faWBwu$#oO$f3Fuw3b1Y}EL>2Pq+ z!aP2$N8b6+Vq3phGu5!H^FnB9)96JGC8G>hT`{flRZfz?VEGE|qXb=(!D~#v>q$LD zsJK84ta?Z`v=!i6IV@DB2l`)j;ro8*rXt|aVO0yKu&USd%DO-vQK%BxmM0yk-n%z& zQi+`A!Tg5UW+}>Q{IzYfHY7 zR!NDY$0p{l{bJtlD-+SvDp#vxd|_b;w=TxgZES;odDVV9q2mi3#`GLfrchqg(~g90 zn4^(2Q*bxdp`GJ5(~EjPzB7K?R6pSt7=HGt-uhLPtvL$5R7r@wRt-Y2qQ)gfj5(8U zc;bwq3RZ{fVX7%)4{PbO{DHdkb*G#U84|6=VKSrdl%MNd^H(Y+qt-vayt4C-0U!E z!hPJ4o6ut;OLm`MoA%C<6GbJB@40b`c;M4nI?*xIGk#potD{w`UcECJeODa~u7TPw z>neT*Z-gJ|WM>-Jbrnoe_vMf%BF|CfIp4;E6TU3E1sMw(gCQX zp7#a_MbVsYhYA`7P1ZR&c$#cH93HqT8d2M_CEG160zj>T%Jf4>x^deW1wNRyRckXc zVdyI4*xg%4^<-6dsLD&Eu;&EqNh$9yuliDLP$1atxNjXe6zge+QPP)eVcYb@P(MPu zN^wj*-?*Ie`q1!`(zpruZV~GIH!V2nV>?r9uowdZZ3(u`??IiU8ZVzis|;~V??E3_ zq(O0{nH1VMc|hrWcE}wnG3wa;#^{mc5;w7R)4M~#XQBdqo1e58h@@dw<%@Htb3W_H zx&fbKl+_G^8f^aL!m~0q@6n@<9*x7d{Znq7oA_=vanGMeU}BT}0V{QG=!0}F4Ba%Q zKP91*Szim^Oiu|HORQH>4cGSsl#$8rr9=RFgokasttm6WygKG7cUD8Y45EQD(c5dE z7X$qjy*tZ|Ash`TzT>%;pJei4`v(6!4_rdT9jBt*{ajOcv%iI$j- ziW}`<;A`Xz<@%L#3JsUa0QMx7wWt`!)*^?8>7iA&e%kN@_bbErJb8|Q*k`x-yw)70 zEZYi6AV^YA%6pSyRl_zB2Bu54$V8VU-opKRkk7r6)=fN{{W7a;Aqg9)F#59&Bp#~Q ze3r;DbGMNudOj_@BQgx_M_W$j&$GoHK3C)*XY^*~p2IDko2w?TU?K*OKAhOKGyikdkFNQ~LUL9xo^L!${m^Cs>)qKjD`_y?Xl}QF z5JSGCeOyN&q`|NGPu)UPiG*S6d5f}UN_6w5w;&S(MA1>^Rcoe@0uNn0LY-L%h{HE2 z%(1W$_8pb+>!ZfmUE3lwH<*(wdr=2!d=~`IH0@~>8_w_jqGh<;>XT?aAVpyzN^oVP zj~!%$wSE?g?6y<|CdBi9E`__H7BY??oKplhF5zK1FVo9{2sA)~mm8|OT0b9G&Vv>? zdMM7HPh`8xc5O$O-mjD3RIkY=2W>T7^b3#aN#k5L{!&9HfG1=@4P}25$7v~RE;l!QvT5Gv3&Q6Zn`uqlBbGFFedw(6R5>FpD1u(KZXsQ4PG zlorvMvK7NBPXQ&89wwNm^cG9bdDnQIpVA8-1$ zH<{qI{q-#|WZoK7i!I}Lk$(SCU7+;=Z@8R-!O63T=<*iBR|NGBMDO`<>IIgzGUwb5 zrn!@Y9)Dc)kNu)q1?CXZ1r`78T-k5Tc0CIJ--?DlIB3-b%8q@YJH>s?({ z<%f4Mz;zPCf(b9NTunuN6L771D8m_-&o^fsHruBQOFm|o+8j%Kq+$3mA@nB$NH8&) zLD@<*JB=-l#4g*z~=X-Jp>6+h5?{D=eKJ-(FTb1?kb_`R60)Tjz1cRfW5sj!h5rj^o(j zJARbbv^T$WqIY25-hb`lfD_RrbT3kX5UA7DDD;bI%A#6l+ar6Je_=G3Z0H%BjgQ(Z zHMmF(U!ub_ezaA5%J#W$ty29*2KlS%JK6(gM>)%Rl;!1kIv-S;A&zHHEHJKpz5A#5 zd@-r1K4Vt0e@Piw&2#@=JUxJ6xVW0xBqWYC;KPgPrJ~6rwAxnYR{wR+z>e-!->DBw z*hRK_#$}^zY1X7txXAd@7TIv6uSq!l3c}DNxa|)Mq$Ijb!Zm4IYpgv|uxf6Z7y7cv z(vuZvLL;|w{-ax=vwyDd-4(VrX&y~?0ZU}jH{{JSLRUOgrGZElDI$yspuv>P$h{%L z5|w)&mP~E+9IrlMXyjMK=gUTe5m(F$8n_Zu!c(5umem9dip%3KGi>!cAsDC_)?xw+ zn(6$EXQq4kYZDMh8cw>1uNAFnBk59R>dD1Y3c3|+qXQQ3NZdz7Ic7E(OKDFm=UKGy zX6mtQS~OR9YhKmUSX8fI)$iLoJxEd|p28Vci3vLfPSnG*Dqp7L)4UHWI5#S)w2!3X z)ruJ)pbHdoP#pR)gQI<9VNgi1DExiLMm4Vv3c2~?rXkn=)7V)?MfJ9897I4s7!d*K z25AZD_#+`9p>*faUD88$Nq2X54B$v3-5nxI4Fd=aL(ds~-?PrU);S-}{x*B<^*np_ z6Zd`nu6ylG905{@JNE?fv)}vFI2>N)yZ9uj7wk@-D6A(AlJ?`*bx%2PFsUa8S8B}E zg2=2M3+D;g@OUe+FJG!>yVjP+AvjYnep)ts?{zjJcSL)c$Varxt&Qc$egAQ$RS=vN zz_(y%nq%=NQt}eKjSU*_=2&h`POn}|8Sz`VU1@`obb7}qD0;n6r#o70%eUQg5SyG! zNrBYLX;Z3P*Uva#KHu=#cN7~^S{wEIOx~&x^KI;&f&k_pa^nb~wqnYjgYU;w9S~$| zVSKjec)(WVgYPT*}?%})PnUPgQmh6`1)v+g-ZPN#(2 zx_R}m&bxKo36X-u?_u8CxYTpkN-sz|m1kv}TK_6UhVcfKo2y4J9#j2*%kiF3S$pE8 z-y51vX4X=^vT7UQfmF-E&*b(Ckv{2$8X0b(D&p<<G>yE;*ZbT)qelH637x6J(RpqN_t!wgYZtYGzz2DS zs!0&IpF2sT!QbOcg#!iyM`zfWBVpKscdAAuuMuHd&ioS*xa1Qm_m|?dK56<-mb^__ z$4`^XWi(dqrKumwPDGoq%Wn087jVqC>6rA4Utx(!&bHbPaG{b=Qpn4Jpp zu5X1i0fSEa9q?&e0(n7!u_ZFnpm6kAi4uqmYveQC8J_kHl^%`awP@JJEDhr$^TJo& z8K8WK;ZsY#iPWBXcL6x8v4~{u%t7+(sxJr zV_S6Q>^all#V#)=?n;sUpPK*L;opr$$?&p$4#}P3Fyvnpe0R5BV8PD-lN6JP@j0K~ z@Jbsxu8;_YYmZpXSpKC2oFl!HXpTEIlJ7r&spI5ASNEg#pc03SBa8w?; zIta%x%ubyL_zoBwQ-irv%xCSUvoF>6y2T$&eX#ei0z#6luvYWG_(Ufk&y$2qZ^#21 zaeDsrFXgl<4crN==l92byaah4JqmS}yY5}@GIR=;HokYqTobBrpUh*z$>uV@7GfRjjknZyY_(wi)^#uD!?J z$on35{$o?tzG-{6nIBP^05;U}J3GE!+ZckVz_(lK@YEsUUugw;7`ATtH#t!Qg(kd= z(>Hg?-X_)VUocE$|Lb9wvF(p`eJ1Zcw6`_!+|T*Tr`H+FRN_7_}-Oh z6tRFE@OpOc($3S-rq`N(bLE}BIA?eBHKv3?M_>sdtI?ml5#w*Ji-{VA%^{*@0T*Cv zSk^sq+;1a;&}&lKB2{okBk_hcoc+#CY;NpLReSBgd_$ydI>ol*FZsSM3wtl~P}B?7 zcWOaP0y#sRkNXT2%kE_tQ)Fj&l4EJbmqD6Cg^iZ>J&%SbW#3=%Q&*1_8RV4EdaRfK zZhUpK zFxcaD_Fn5z_^m{KSPJf0K#tnYce_3_^2+kQ^hzp^@878zJ`{x3D{vQeZ&rFrgyg|; zqaa4gGxNGNwbo^3F#5DKqpw6_b~Lo*ym)1TJ>yf+yffAxb?ka5mwREiM4aVWJRF(Q zMQt&1P=HS775;-K0!q2@d2rk%TGThkBZU-Lbyi}+CQ(>7&RWe9)EvH4!KEkfEi%DN8{Xt5hP_%O=3oJ-aSOY!C5zOMs+WA-)7x^0*r&%? zbg}hMFWA5o)vWMe#2s1Q!w=66y=#^E6Xnn5T@Kl%^c1T>2j_S_l{t7D)ZGqE%*`o7 zi7@ZPXe!Q}A9Nqf#HW$NE`Vfs4?Ql-QUJ0T86gkjn}&Ved>vCi9J+F8wGT+DxZKCl9STwgc=b- z_YvO$KRGAL5c)e+JfIRRf}bWVXdcYWCZ(l-r8t7=L7sz$&mXkyZP7{XEuX&RSu>Do zzTT1N^rFaKc_K_gsf<~&f#DoKdY9cbQal7+Q zm61#cYxZ6+HlC5#QpZIh#>SRaQl@K6wV=dr=4nGvhC{?&(?t;bo!^n)?t3J|aNEzu z_Im|e1IN&gc!w2G^KMj+;@;df`jw6i3Z)ojWichaI2CODb)mQ*4NRZApo64)BVq zt}+utP37}b?d6+V{19|dILAIA975>qBt%2koJ3eMW^=B1ZHX0LYC`(6{X9NF%1gN$uH=mzmJnKc142H``w~o)OqEP>) zpWNDay>p(id$Fo+2C1?$$hjc);x`Z$&wiWry1666ETINMa*E-BMk$bor}NH^d`NDW zffM~fM#P90bNbKOlk>aAv5VIG=)EO<1p&z^H%!ToP#B~`@jx9#>l2+D{YBRVIU$*$^fhavd9_{aEu zf4t#EuS0^|m>Q)JGW`<;+*xKh*GQ?KUzFDx)4j|lK+WTx8|iH(6FftE5tkmcipEt1 zrlaRV>y8F(26aCrhZAhy;(!0=_geFSgGiY3f|*J{L@VAylwdLvKfNP5oz?-u^q}3u{`R4H3X9%64Z_+>Z8RMhU*BdNlW^{Aa7-PA)nQ^`Tv< zRmu%^$~-6h-YiVvP(b1S_K(atA^h{qWUqYisQPHynVkhqPiWUd-|T2lx873Fr;p=* z_%YyR$m)4S$RX^1#Q6}GglpeZ5)LvYx8dOnS^NCLlOJRpj6D9h(NjmT@87aiLXlmi zyW|6^41?dl_bV;UgME^R1PPqIJS4Uh;daACvrhP_jTF`%pJrP=v8o3MhI-N+ig?6j z(TMkFf$PoOItlBr0^}>fJ^{%?OKlBTr#fvSj&uW@l$zcR)sYh?EmwIf-HjOxJnUYr zt*KS-BrGO~xLs;Et$j^owkYBusEq9~T~utfRz@6_DgP4g5*5(>4}uM*jB$QK=i^{$ z`t{X#n_4G0bi)2ASl|!t!!Dy3?^|3$F*o(Fx&}petgU<$VmyAfBFaIJje>x}Tt-to zPeN9heZrpog_7$2Ai(&XQoXaz+2fx$F~!;)FeZA8zvvhv4<6N!?$=|CrI|p+v=?^L zWR(4y!hLjWeNR>)oNJs9)dZ(VwEzwk>h8*L|0(d*($RCeHgx-gnS)1R^>~_|A-c<` zo{9`Lhy#SxnCU{7w6L0$FGM)#BUb2_Topn;0s}3NM^pl)o;E>>SRNh25cw*y++gLR zsyQmgu_f7WAc*AmP1;J$+@CQ?#`e$Uo&`?-IwER~*Qeu3U{vZdJ4e&)_PqT=J=uTZ zCN0nm=JO7eRcXm?)nR=|;?sZDR(Ivrei$d(6c5XPl7DiL7L$|Oj5)N?x9fUqSUyiW zqsxTr@xU7u=;O>@G#;Jscx3(0nO6ZsJSSK)w%_n(dx}CHZl1kO-{fC7{?hjLahoZj zhrd$gngl4`gs;?ryo@_6kw*>i5CA22hSZC-deE)XYig4*^=;Y`3Znzzqr|fQEg;^1 zFfe4}KGug^OIM6ztm?KN-;S;R=?Uwzd1sN)EfBsU1-nMOyWpeUSZnKHS9xcjzhD)5 zK~#7X&Xx_LfF=7fUWlS1MCik#!xZGLTlL zYJ1XecgDgyTaO;rYVRxzGcu8?alZ#tyPdx0-*UPAH;7F8I$W)d^zhI{s$PQ|3r?MGbP(%5+zXy9-3KHep+Z@ zXVe(X|BGgBQMqNf@sIz-AfGn-o0Py_j4xkB#ZsMWdz3A9h71y!`{^?tE3C=$!Q9>9 zave(vySSTf96J^Iv;!WSD&7&8cJZO&%|s#)2?HuvfK?S*%lnMfq35dyr+N5zt*$#g zKD%tA_SMc#w@E)(R4IQw)LWR)=5_q;U%8Tae)&>nxK6_4c_lP&ILBbDuz2n@sig8@ zM-cF+%L^-}InOX==eB)eJ$Y!zl4XL5raFLFWmj^>byS~QlX={v_qp^7Z)8-0-jP(> zU+~#KZ6nk-0=v$Lw`2)Vu^D)myOewT@fFsUL&dE)mq-@Qe6zOp1eLqrd>`wHKm%GQ zt%xzsP<;dQwJWZTV)0B0U1%FzdSAdhHbPqBIQWQYNdA$m1V`R&D zfUjNpv>ITxa?^EUTl%)Cjh5B5k*m?I-?Y?V3cGnke5zoy@;-cp^2{MwUF#s5f@|(r ze?fOxolkn-=G6_=$F72XZmgDWlI!fXTCsV?*`)94?TfVi#nEr|GGs-r9-&r& zAU!iFL3)Nn#U{iId&9A4e967dtuU1YEk3)#IY`R$I_HLWS{#QuuC^+Bw&^VOM6Q29 zhLX$!!=m=h(T56@CW;EWgBD>?-OUnIJ8k6PM@9pifls`3D0_l42fC!uVOsP zHSdhd+q2hlxCDiH#{Y|(PHi;ICGrg|Ql!*JdfpP6y#5Wt--HDwXCylgsQu=m;oqP< znk2M*3Z7p$5<5^Ebv}#W$PM5YAKL;g7l^Af(OUBES_bB;xNjVF(<&cX?X z49T$J80RkBOu}YNu7ChK0RCpYIkwxyV-U-|%c;hbHRNmOBKwRRs%uZ5r~fzNMJTV< zY*|{KVQt!X;`qgn-~Y;pfIj|o!<8s6N0$$yzRSmis~yc512xx{D#UN>N61#Eo;J>9 zq~|KS{n9Pvp-FMngK-|(&%Yc}jSi_6+_%5uu2B~}|8a)h>E0G^IjfWCmrI0QtEMx6 zaLxbmO@nH+E@oa!z+66a2t$gFyA_8_EZJ$mMz~*g4@JLwxHUNus?pM<^k><@H%a&z zba?+apapW@{STn6?_QUTVige`Mx2;9jV*aG?-W+B1!<*^ChM}ZzLJcaK)ug42+;^& zG8#;Tz2G#@w+d}MK@Qfy7+V&Anf zpTT8Yhx{o1A*fA{275{$Mv1j7hp)lQA$H;J`D|gu5_Ug8=6=ZG*Rqap9Q_>T_2cQ| z!PL1-2f{(n%BV}{t&)W9rTnUJC&{BLF-2nKVTeNOQZwD@Q z$zGH;nk@SB=U!o!)|f&Oi%D<`Hj!Fwf#Ehp4Q=D7TS6+sErz zk05L-8W-SSiP$Bb>{ZIv=TySB|O(;Ut=+Hg7$~AV|MwQBeh1 zkTV6R&K6R2p;Ap#v5($_Wmw^T)agUuA90N7j(e$DcCWYbEb123U9QsSg`5!Y0%z+_ zB=2gukV}*|;!zY$S3hVmbXCn+Gf{ONrO}S}V?yTg_qBAZI7KaxG@SEv_K+{>0hPM6b8!@*N zd&s&|V&)6m7zJ7*fA-H;V(x-kr>iccC_r2cFqZfMw|q^tRRYV%gqNZMm{aLLaT1yZ z)L<<&?3@2U^ZP}T^ag4cm5Gd}88(ITD*5$cys#x5ULJ_$7ofH zB-aT0JOaIf%EjZySGPZw*uVwr=BFI6CZ{hopV^u)V$*v|F`hRAM{wjRQBJ|_qebN{ z`mSHB@pq>#ElCAKt}yHS(iwzu(pW?tyzweO_C(c386wrq#4!+Xyc)?|WjqF&ev zX$XhlBZUO}1kMZhKfQvzwZHICyvO!Ay3B1LHPcki7Q3m`KUu~f_;tEBlvup+%oQD3sLpE&P1p- zgI^(|hGs)ncqr-airkePmH#vojQ!FltXtsa^5Dcq6^$$5?z|y4yMSK3F3rfQ9SRz| zIn?4liB0tMqYU2-q5QH`BGZVo>?=;T^U1RThtFomd^#2szgpt%iu!atQLKHfce-CR zv0>cQ_tO;8iWOUnqyPf;Sega_@5-Wf9J#i|Bl8CvqMMiaJU6v>be)k|G~6swzNolT zSD?!V3hpbtNxzTLwIAsjtaFH{Jc&1-S!B@JMUuwA5k*l7rQZSH>}yw4(mpM!ie{n~ zmdSXWt>!z?bJok711(l_IwugzKw8v@Fn+H}&}F-bFN2jhSDXj7F|1uWHt!eBWNG(q z7f04JqA=^Zk(=Ly0xeFOqc6{y+B&s=Ujk@YOd~l%1x$q{>%3Ee4%bz==QjG6RknMt zjKLpgs?W(^W46g=#YTT5WZM;O>`JHqzX6IWO9x`T}0uD*W zNQKovA!yW@KnY>#;P;>?!BJ5I#XYvKxEU#YN}ub$NZAi_u=Ao_xUgF~mP)@WwYv;ht5@ z)C{PBh(}q<2(PXqkgFIBou5Zt*H464Y2uSEzo|h%eLMX2CiiCcluY{V;$?ui-LWjB zDhxd;_dE=~GH_oT6OGzoa55BR$PsmCoa+iWmnoUT#kU3-;>VM&{7lM~ZBiuF9~0+mF}T;iGWb*Zs*0aK7K zdyKnz;5Wk6JqfNnVSKl8KG|wu@NeCC`$M4lDuy*bAX!^93@F@;fi<|wI+s~JXF3k( zsp1p6CulT`Y*VqZYBHmpTo|cb%Ar<8Zp&SN6a=OqfH$1w}ezsm*YG8Nb@-vP*j#n+M zKe>bKG)QZ=Wh}`=v8gCg{`^dId1FfH5Z}*x&re8;G?eoY`p+et5hS}_hVq-+PM^w- z{rYE*JE?BV?MMG$O$H5DVi>9x5$?t1X1@pN2Q2-|+4x2~@{sql9;2K%dDp1yIBrjV zh0RiN3OQ!cNAH<;l|JP;{VYnxHGRL|#xR0;m+(@eBc$m~FO6U->K=kd9PIz)e*CG% s(V%CM{kK(ua#AW}2t5CvzkVVy$gBh!MR}f#p`i{1SrwVOw lf t55xx wipe ``` -Set a T5577 tag downlink mode to fixed bit (default) -``` -pm3 --> lf t55xx write b 3 1 d 00000000 -``` - -Set a T5577 tag downlink mode to long leading zero -``` -pm3 --> lf t55xx write b 3 1 d 90000400 -``` - -Set a T5577 tag downlink mode to leading zero -``` -pm3 --> lf t55xx write b 3 1 d 90000800 -``` - -Set a T5577 tag downlink mode to 1 of 4 -``` -pm3 --> lf t55xx write b 3 1 d 90000C00 -``` - ## Data ^[Top](#top) From 7d009a9ea744e078c97e76203f862ff2ad7a1e8f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 5 Oct 2019 12:07:28 +0200 Subject: [PATCH 0838/1854] emphase warnings --- client/cmdlft55xx.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 53c522f32..8ede60e11 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -103,9 +103,10 @@ static int usage_t55xx_read() { PrintAndLogEx(NORMAL, " o - OPTIONAL override safety check"); PrintAndLogEx(NORMAL, " 1 - OPTIONAL 0|1 read Page 1 instead of Page 0"); print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE); - PrintAndLogEx(NORMAL, " ****WARNING****"); - PrintAndLogEx(NORMAL, " Use of read with password on a tag not configured for a pwd"); - PrintAndLogEx(NORMAL, " can damage the tag"); + PrintAndLogEx(NORMAL, " " _RED_("**** WARNING ****")); + PrintAndLogEx(NORMAL, " Use of read with password on a tag not configured"); + PrintAndLogEx(NORMAL, " for a password can damage the tag"); + PrintAndLogEx(NORMAL, " " _RED_("*****************")); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx read b 0 - read data from block 0"); @@ -232,7 +233,7 @@ static int usage_t55xx_wakup() { static int usage_t55xx_chk() { PrintAndLogEx(NORMAL, "This command uses a dictionary attack"); PrintAndLogEx(NORMAL, "press " _YELLOW_("'enter'") " to cancel the command"); - PrintAndLogEx(NORMAL, "WARNING: this may brick non-password protected chips!"); + PrintAndLogEx(NORMAL, _RED_("WARNING:") " this may brick non-password protected chips!"); PrintAndLogEx(NORMAL, "Try to reading block 7 before\n"); PrintAndLogEx(NORMAL, "Usage: lf t55xx chk [h] [m] [r ] [i <*.dic>]"); PrintAndLogEx(NORMAL, "Options:"); @@ -250,7 +251,7 @@ static int usage_t55xx_chk() { static int usage_t55xx_bruteforce() { PrintAndLogEx(NORMAL, "This command uses bruteforce to scan a number range"); PrintAndLogEx(NORMAL, "press " _YELLOW_("'enter'") " to cancel the command"); - PrintAndLogEx(NORMAL, "WARNING: this may brick non-password protected chips!"); + PrintAndLogEx(NORMAL, _RED_("WARNING:") " this may brick non-password protected chips!"); PrintAndLogEx(NORMAL, "Try reading block 7 before\n"); PrintAndLogEx(NORMAL, "Usage: lf t55xx bruteforce [h] [r ] [s ] [e ]"); PrintAndLogEx(NORMAL, " password must be 4 bytes (8 hex symbols)"); @@ -268,7 +269,7 @@ static int usage_t55xx_bruteforce() { static int usage_t55xx_recoverpw() { PrintAndLogEx(NORMAL, "This command uses a few tricks to try to recover mangled password"); PrintAndLogEx(NORMAL, "press " _YELLOW_("'enter'") " to cancel the command"); - PrintAndLogEx(NORMAL, "WARNING: this may brick non-password protected chips!"); + PrintAndLogEx(NORMAL, _RED_("WARNING:") " this may brick non-password protected chips!"); PrintAndLogEx(NORMAL, "Try reading block 7 before\n"); PrintAndLogEx(NORMAL, "Usage: lf t55xx recoverpw [r ] [p ]"); PrintAndLogEx(NORMAL, " password must be 4 bytes (8 hex symbols)"); @@ -1976,7 +1977,7 @@ static int CmdT55xxInfo(const char *Cmd) { uint32_t inv = (block0 >> (32 - 25)) & 0x01; uint32_t datamod = (block0 >> (32 - 28)) & 0x07; uint32_t maxblk = (block0 >> (32 - 31)) & 0x07; - uint32_t st = (block0 >> (32 - 32)) & 0x01; + uint32_t st = block0 & 0x01; PrintAndLogEx(NORMAL, "-- Q5 Configuration & Tag Information -----------------------"); PrintAndLogEx(NORMAL, "-------------------------------------------------------------"); PrintAndLogEx(NORMAL, " Header : 0x%03X%s", header, (header != 0x600) ? _RED_(" - Warning") : ""); From a5001de76c8d3bfe5e6fe48363e547ccd0e70c94 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 5 Oct 2019 12:43:46 +0200 Subject: [PATCH 0839/1854] less magic trick in fpga_compress for coverity --- tools/fpga_compress/fpga_compress.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tools/fpga_compress/fpga_compress.c b/tools/fpga_compress/fpga_compress.c index 54d2438d2..2174571d6 100644 --- a/tools/fpga_compress/fpga_compress.c +++ b/tools/fpga_compress/fpga_compress.c @@ -275,11 +275,15 @@ static int bitparse_find_section(FILE *infile, char section_name, unsigned int * /* Four byte length field */ current_length += fgetc(infile) << 24; current_length += fgetc(infile) << 16; - numbytes += 2; + current_length += fgetc(infile) << 8; + current_length += fgetc(infile) << 0; + numbytes += 4; + break; default: /* Fall through, two byte length field */ current_length += fgetc(infile) << 8; current_length += fgetc(infile) << 0; numbytes += 2; + break; } if (current_name != 'e' && current_length > 255) { From 9370649861a24dce2f82fb06bd1f3a83121b0b62 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 5 Oct 2019 18:34:12 +0200 Subject: [PATCH 0840/1854] bootrom: avoid pointer magic to please coverity --- bootrom/bootrom.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/bootrom/bootrom.c b/bootrom/bootrom.c index 2c1a6f23a..1b45f4534 100644 --- a/bootrom/bootrom.c +++ b/bootrom/bootrom.c @@ -12,7 +12,8 @@ struct common_area common_area __attribute__((section(".commonarea"))); unsigned int start_addr, end_addr, bootrom_unlocked; -extern char _bootrom_start, _bootrom_end, _flash_start, _flash_end; +extern char _bootrom_start, _bootrom_end, _flash_end; +extern uint32_t _flash_start[AT91C_IFLASH_NB_OF_PAGES * AT91C_IFLASH_PAGE_SIZE / sizeof(uint32_t)]; extern uint32_t _osimage_entry; static int reply_old(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len) { @@ -153,19 +154,17 @@ void UsbPacketReceived(uint8_t *packet, int len) { /* The temporary write buffer of the embedded flash controller is mapped to the * whole memory region, only the last 8 bits are decoded. */ - volatile uint32_t *p = (volatile uint32_t *)&_flash_start; for (i = 0; i < 12; i++) - p[i + arg0] = c->d.asDwords[i]; + _flash_start[i + arg0] = c->d.asDwords[i]; } break; case CMD_FINISH_WRITE: { - uint32_t *flash_mem = (uint32_t *)(&_flash_start); for (int j = 0; j < 2; j++) { uint32_t flash_address = arg0 + (0x100 * j); AT91PS_EFC efc_bank = AT91C_BASE_EFC0; int offset = 0; - uint32_t page_n = (flash_address - ((uint32_t)flash_mem)) / AT91C_IFLASH_PAGE_SIZE; + uint32_t page_n = (flash_address - ((uint32_t)_flash_start)) / AT91C_IFLASH_PAGE_SIZE; if (page_n >= AT91C_IFLASH_NB_OF_PAGES / 2) { page_n -= AT91C_IFLASH_NB_OF_PAGES / 2; efc_bank = AT91C_BASE_EFC1; @@ -173,7 +172,7 @@ void UsbPacketReceived(uint8_t *packet, int len) { offset = (AT91C_IFLASH_NB_OF_PAGES / 2) * AT91C_IFLASH_PAGE_SIZE / sizeof(uint32_t); } for (i = 0 + (64 * j); i < 64 + (64 * j); i++) { - flash_mem[offset + i] = c->d.asDwords[i]; + _flash_start[offset + i] = c->d.asDwords[i]; } /* Check that the address that we are supposed to write to is within our allowed region */ From 3560cf5466f6ac5cae2b7749eaba005479e9cd86 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 5 Oct 2019 18:42:32 +0200 Subject: [PATCH 0841/1854] bootrom: remove deprecated CMD_SETUP_WRITE --- armsrc/appmain.c | 1 - bootrom/bootrom.c | 9 --------- doc/new_frame_format.md | 2 +- include/pm3_cmd.h | 2 +- 4 files changed, 2 insertions(+), 12 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 9be4443ed..2f6697429 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1895,7 +1895,6 @@ static void PacketReceived(PacketCommandNG *packet) { break; } #endif - case CMD_SETUP_WRITE: case CMD_FINISH_WRITE: case CMD_HARDWARE_RESET: { usb_disable(); diff --git a/bootrom/bootrom.c b/bootrom/bootrom.c index 1b45f4534..4b255536f 100644 --- a/bootrom/bootrom.c +++ b/bootrom/bootrom.c @@ -150,15 +150,6 @@ void UsbPacketReceived(uint8_t *packet, int len) { } break; - case CMD_SETUP_WRITE: { - /* The temporary write buffer of the embedded flash controller is mapped to the - * whole memory region, only the last 8 bits are decoded. - */ - for (i = 0; i < 12; i++) - _flash_start[i + arg0] = c->d.asDwords[i]; - } - break; - case CMD_FINISH_WRITE: { for (int j = 0; j < 2; j++) { uint32_t flash_address = arg0 + (0x100 * j); diff --git a/doc/new_frame_format.md b/doc/new_frame_format.md index 17c94120a..c16aee939 100644 --- a/doc/new_frame_format.md +++ b/doc/new_frame_format.md @@ -200,7 +200,7 @@ Bootrom code will still use the old frame format to remain compatible with other (`bootrom/bootrom.c`) usb_read (common/usb_cdc.c) ⇒ UsbPacketReceived (bootrom.c) - ⇒ CMD_DEVICE_INFO / CMD_START_FLASH / CMD_FINISH_WRITE / CMD_HARDWARE_RESET / CMD_SETUP_WRITE + ⇒ CMD_DEVICE_INFO / CMD_START_FLASH / CMD_FINISH_WRITE / CMD_HARDWARE_RESET also `usb_enable`, `usb_disable` (`common/usb_cdc.c`) diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 108e3ba1f..ca778a495 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -253,7 +253,7 @@ typedef struct { // For the bootloader #define CMD_DEVICE_INFO 0x0000 -#define CMD_SETUP_WRITE 0x0001 +//#define CMD_SETUP_WRITE 0x0001 #define CMD_FINISH_WRITE 0x0003 #define CMD_HARDWARE_RESET 0x0004 #define CMD_START_FLASH 0x0005 From b9424795ea88e6e2da8ac8a051319f4886363a30 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 5 Oct 2019 20:00:33 +0200 Subject: [PATCH 0842/1854] remove unused vars --- armsrc/appmain.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 2f6697429..4a9ac2c9f 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -246,7 +246,7 @@ void ReadMem(int addr) { /* osimage version information is linked in */ extern struct version_information version_information; /* bootrom version information is pointed to from _bootphase1_version_pointer */ -extern char *_bootphase1_version_pointer, _flash_start, _flash_end, _bootrom_start, _bootrom_end, __data_src_start__; +extern char *_bootphase1_version_pointer, _flash_start, _flash_end, __data_src_start__; void SendVersion(void) { char temp[PM3_CMD_DATA_SIZE - 12]; /* Limited data payload in USB packets */ char VersionString[PM3_CMD_DATA_SIZE - 12] = { '\0' }; From 4ae8a3d86b68296884383950840be0a3077cdc69 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 5 Oct 2019 23:56:19 +0200 Subject: [PATCH 0843/1854] fix few printf arg types --- client/cliparser/argtable3.c | 2 +- client/cmdanalyse.c | 2 +- client/cmddata.c | 32 +++++++++++++-------------- client/cmdflashmem.c | 2 +- client/cmdflashmemspiffs.c | 2 +- client/cmdhf14a.c | 8 +++---- client/cmdhf14b.c | 2 +- client/cmdhf15.c | 6 +++--- client/cmdhfepa.c | 4 ++-- client/cmdhffelica.c | 5 +++-- client/cmdhffido.c | 14 ++++++------ client/cmdhficlass.c | 8 +++---- client/cmdhflegic.c | 8 +++---- client/cmdhfmf.c | 2 +- client/cmdhfmfu.c | 2 +- client/cmdhfthinfilm.c | 2 +- client/cmdhftopaz.c | 3 ++- client/cmdlf.c | 8 +++---- client/cmdlfawid.c | 2 +- client/cmdlfem4x.c | 4 ++-- client/cmdlffdx.c | 2 +- client/cmdlfguard.c | 6 +++--- client/cmdlfhid.c | 4 ++-- client/cmdlfindala.c | 10 ++++----- client/cmdlfio.c | 6 +++--- client/cmdlfjablotron.c | 2 +- client/cmdlfkeri.c | 6 +++--- client/cmdlfnedap.c | 2 +- client/cmdlfnoralsy.c | 2 +- client/cmdlfpac.c | 2 +- client/cmdlfparadox.c | 4 ++-- client/cmdlfpresco.c | 2 +- client/cmdlfpyramid.c | 4 ++-- client/cmdlfsecurakey.c | 4 ++-- client/cmdlft55xx.c | 10 ++++----- client/cmdlfverichip.c | 2 +- client/cmdlfvisa2000.c | 5 +++-- client/cmdsmartcard.c | 4 ++-- client/cmdtrace.c | 4 ++-- client/cmdusart.c | 34 ++++++++++++++--------------- client/comms.c | 8 +++---- client/emv/cmdemv.c | 42 ++++++++++++++++++------------------ client/emv/emvcore.c | 6 +++--- client/emv/emvjson.c | 6 +++--- client/fido/cose.c | 6 +++--- client/fido/fidocore.c | 24 ++++++++++----------- client/fileutils.c | 10 ++++----- client/mifare/mifarehost.c | 2 +- client/mifare/ndef.c | 30 +++++++++++++------------- 49 files changed, 185 insertions(+), 182 deletions(-) diff --git a/client/cliparser/argtable3.c b/client/cliparser/argtable3.c index 9d83dc33c..b6284fd07 100644 --- a/client/cliparser/argtable3.c +++ b/client/cliparser/argtable3.c @@ -1522,7 +1522,7 @@ struct arg_dbl *arg_dbln( addr = (size_t)(result + 1); rem = addr % sizeof(double); result->dval = (double *)(addr + sizeof(double) - rem); - ARG_TRACE(("addr=%p, dval=%p, sizeof(double)=%d rem=%d\n", addr, result->dval, (int)sizeof(double), (int)rem)); + ARG_TRACE(("addr=%zu, dval=%p, sizeof(double)=%d rem=%d\n", addr, result->dval, (int)sizeof(double), (int)rem)); result->count = 0; } diff --git a/client/cmdanalyse.c b/client/cmdanalyse.c index 2e53af224..733c741c7 100644 --- a/client/cmdanalyse.c +++ b/client/cmdanalyse.c @@ -260,7 +260,7 @@ static int CmdAnalyseLCR(const char *Cmd) { PrintAndLogEx(WARNING, "Invalid HEX value."); return 1; case 2: - PrintAndLogEx(WARNING, "Too many bytes. Max %d bytes", sizeof(data)); + PrintAndLogEx(WARNING, "Too many bytes. Max %zu bytes", sizeof(data)); return 1; case 3: PrintAndLogEx(WARNING, "Hex must have even number of digits."); diff --git a/client/cmddata.c b/client/cmddata.c index e025ded3f..4c8e0c45e 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -553,7 +553,7 @@ int ASKDemod_ext(const char *Cmd, bool verbose, bool emSearch, uint8_t askType, size_t BitLen = getFromGraphBuf(bits); - PrintAndLogEx(DEBUG, "DEBUG: (ASKDemod_ext) #samples from graphbuff: %d", BitLen); + PrintAndLogEx(DEBUG, "DEBUG: (ASKDemod_ext) #samples from graphbuff: %zu", BitLen); if (BitLen < 255) { free(bits); @@ -591,18 +591,18 @@ int ASKDemod_ext(const char *Cmd, bool verbose, bool emSearch, uint8_t askType, int errCnt = askdemod_ext(bits, &BitLen, &clk, &invert, maxErr, askamp, askType, &startIdx); if (errCnt < 0 || BitLen < 16) { //if fatal error (or -1) - PrintAndLogEx(DEBUG, "DEBUG: (ASKDemod_ext) No data found errors:%d, invert:%c, bitlen:%d, clock:%d", errCnt, (invert) ? 'Y' : 'N', BitLen, clk); + PrintAndLogEx(DEBUG, "DEBUG: (ASKDemod_ext) No data found errors:%d, invert:%c, bitlen:%zu, clock:%d", errCnt, (invert) ? 'Y' : 'N', BitLen, clk); free(bits); return PM3_ESOFT; } if (errCnt > maxErr) { - PrintAndLogEx(DEBUG, "DEBUG: (ASKDemod_ext) Too many errors found, errors:%d, bits:%d, clock:%d", errCnt, BitLen, clk); + PrintAndLogEx(DEBUG, "DEBUG: (ASKDemod_ext) Too many errors found, errors:%d, bits:%zu, clock:%d", errCnt, BitLen, clk); free(bits); return PM3_ESOFT; } - if (verbose) PrintAndLogEx(DEBUG, "DEBUG: (ASKDemod_ext) Using clock:%d, invert:%d, bits found:%d, start index %d", clk, invert, BitLen, startIdx); + if (verbose) PrintAndLogEx(DEBUG, "DEBUG: (ASKDemod_ext) Using clock:%d, invert:%d, bits found:%zu, start index %d", clk, invert, BitLen, startIdx); //output setDemodBuff(bits, BitLen, 0); @@ -812,7 +812,7 @@ int AutoCorrelate(const int *in, int *out, size_t len, size_t window, bool SaveG // sanity check if (window > len) window = len; - if (verbose) PrintAndLogEx(INFO, "performing " _YELLOW_("%d")" correlations", GraphTraceLen - window); + if (verbose) PrintAndLogEx(INFO, "performing " _YELLOW_("%zu")" correlations", GraphTraceLen - window); //test double autocv = 0.0; // Autocovariance value @@ -870,7 +870,7 @@ int AutoCorrelate(const int *in, int *out, size_t len, size_t window, bool SaveG distance = idx_1 - idx; PrintAndLogEx(SUCCESS, "possible visible correlation %4d samples", distance); } else if (verbose && (correlation > 1)) { - PrintAndLogEx(SUCCESS, "possible correlation %4d samples", correlation); + PrintAndLogEx(SUCCESS, "possible correlation %4zu samples", correlation); } else { PrintAndLogEx(FAILED, "no repeating pattern found, try increasing window size"); } @@ -912,7 +912,7 @@ static int CmdAutoCorr(const char *Cmd) { case 'w': window = param_get32ex(Cmd, cmdp + 1, 4000, 10); if (window >= GraphTraceLen) { - PrintAndLogEx(WARNING, "window must be smaller than trace (%d samples)", GraphTraceLen); + PrintAndLogEx(WARNING, "window must be smaller than trace (%zu samples)", GraphTraceLen); errors = true; } cmdp += 2; @@ -1222,17 +1222,17 @@ int PSKDemod(const char *Cmd, bool verbose) { int startIdx = 0; int errCnt = pskRawDemod_ext(bits, &bitlen, &clk, &invert, &startIdx); if (errCnt > maxErr) { - if (g_debugMode || verbose) PrintAndLogEx(DEBUG, "DEBUG: (PSKdemod) Too many errors found, clk: %d, invert: %d, numbits: %d, errCnt: %d", clk, invert, bitlen, errCnt); + if (g_debugMode || verbose) PrintAndLogEx(DEBUG, "DEBUG: (PSKdemod) Too many errors found, clk: %d, invert: %d, numbits: %zu, errCnt: %d", clk, invert, bitlen, errCnt); free(bits); return PM3_ESOFT; } if (errCnt < 0 || bitlen < 16) { //throw away static - allow 1 and -1 (in case of threshold command first) - if (g_debugMode || verbose) PrintAndLogEx(DEBUG, "DEBUG: (PSKdemod) no data found, clk: %d, invert: %d, numbits: %d, errCnt: %d", clk, invert, bitlen, errCnt); + if (g_debugMode || verbose) PrintAndLogEx(DEBUG, "DEBUG: (PSKdemod) no data found, clk: %d, invert: %d, numbits: %zu, errCnt: %d", clk, invert, bitlen, errCnt); free(bits); return PM3_ESOFT; } if (verbose || g_debugMode) { - PrintAndLogEx(DEBUG, "DEBUG: (PSKdemod) Using Clock:%d, invert:%d, Bits Found:%d", clk, invert, bitlen); + PrintAndLogEx(DEBUG, "DEBUG: (PSKdemod) Using Clock:%d, invert:%d, Bits Found:%zu", clk, invert, bitlen); if (errCnt > 0) { PrintAndLogEx(DEBUG, "DEBUG: (PSKdemod) errors during Demoding (shown as 7 in bit stream): %d", errCnt); } @@ -1264,7 +1264,7 @@ static int CmdIdteckDemod(const char *Cmd) { else if (idx == -3) PrintAndLogEx(DEBUG, "DEBUG: Error - Idteck: preamble not found"); else if (idx == -4) - PrintAndLogEx(DEBUG, "DEBUG: Error - Idteck: size not correct: %d", size); + PrintAndLogEx(DEBUG, "DEBUG: Error - Idteck: size not correct: %zu", size); else PrintAndLogEx(DEBUG, "DEBUG: Error - Idteck: idx: %d", idx); @@ -1283,7 +1283,7 @@ static int CmdIdteckDemod(const char *Cmd) { else if (idx == -3) PrintAndLogEx(DEBUG, "DEBUG: Error - Idteck: preamble not found"); else if (idx == -4) - PrintAndLogEx(DEBUG, "DEBUG: Error - Idteck: size not correct: %d", size); + PrintAndLogEx(DEBUG, "DEBUG: Error - Idteck: size not correct: %zu", size); else PrintAndLogEx(DEBUG, "DEBUG: Error - Idteck: idx: %d", idx); @@ -1346,17 +1346,17 @@ int NRZrawDemod(const char *Cmd, bool verbose) { errCnt = nrzRawDemod(bits, &BitLen, &clk, &invert, &clkStartIdx); if (errCnt > maxErr) { - PrintAndLogEx(DEBUG, "DEBUG: (NRZrawDemod) Too many errors found, clk: %d, invert: %d, numbits: %d, errCnt: %d", clk, invert, BitLen, errCnt); + PrintAndLogEx(DEBUG, "DEBUG: (NRZrawDemod) Too many errors found, clk: %d, invert: %d, numbits: %zu, errCnt: %d", clk, invert, BitLen, errCnt); free(bits); return PM3_ESOFT; } if (errCnt < 0 || BitLen < 16) { //throw away static - allow 1 and -1 (in case of threshold command first) - PrintAndLogEx(DEBUG, "DEBUG: (NRZrawDemod) no data found, clk: %d, invert: %d, numbits: %d, errCnt: %d", clk, invert, BitLen, errCnt); + PrintAndLogEx(DEBUG, "DEBUG: (NRZrawDemod) no data found, clk: %d, invert: %d, numbits: %zu, errCnt: %d", clk, invert, BitLen, errCnt); free(bits); return PM3_ESOFT; } - if (verbose || g_debugMode) PrintAndLogEx(DEBUG, "DEBUG: (NRZrawDemod) Tried NRZ Demod using Clock: %d - invert: %d - Bits Found: %d", clk, invert, BitLen); + if (verbose || g_debugMode) PrintAndLogEx(DEBUG, "DEBUG: (NRZrawDemod) Tried NRZ Demod using Clock: %d - invert: %d - Bits Found: %zu", clk, invert, BitLen); //prime demod buffer for output setDemodBuff(bits, BitLen, 0); setClockGrid(clk, clkStartIdx); @@ -1779,7 +1779,7 @@ static int CmdLoad(const char *Cmd) { fclose(f); - PrintAndLogEx(SUCCESS, "loaded %d samples", GraphTraceLen); + PrintAndLogEx(SUCCESS, "loaded %zu samples", GraphTraceLen); uint8_t bits[GraphTraceLen]; size_t size = getFromGraphBuf(bits); diff --git a/client/cmdflashmem.c b/client/cmdflashmem.c index be59dc4f7..a313a418d 100644 --- a/client/cmdflashmem.c +++ b/client/cmdflashmem.c @@ -266,7 +266,7 @@ static int CmdFlashMemLoad(const char *Cmd) { conn.block_after_ACK = false; free(data); - PrintAndLogEx(SUCCESS, "Wrote "_GREEN_("%u")"bytes to offset "_GREEN_("%u"), datalen, start_index); + PrintAndLogEx(SUCCESS, "Wrote "_GREEN_("%zu")"bytes to offset "_GREEN_("%u"), datalen, start_index); return PM3_SUCCESS; } static int CmdFlashMemDump(const char *Cmd) { diff --git a/client/cmdflashmemspiffs.c b/client/cmdflashmemspiffs.c index 109f51ae1..492fc0bcc 100644 --- a/client/cmdflashmemspiffs.c +++ b/client/cmdflashmemspiffs.c @@ -413,7 +413,7 @@ static int CmdFlashMemSpiFFSLoad(const char *Cmd) { conn.block_after_ACK = false; free(data); - PrintAndLogEx(SUCCESS, "Wrote "_GREEN_("%u") "bytes to file "_GREEN_("%s"), datalen, destfilename); + PrintAndLogEx(SUCCESS, "Wrote "_GREEN_("%zu") "bytes to file "_GREEN_("%s"), datalen, destfilename); // We want to unmount after these to set things back to normal but more than this // unmouting ensure that SPIFFS CACHES are all flushed so our file is actually written on memory diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index b21e8dbd7..14be6f7a7 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -553,7 +553,7 @@ int ExchangeRAW14a(uint8_t *datain, int datainlen, bool activateField, bool leav } if (resp.oldarg[0] != 1 && resp.oldarg[0] != 2) { - PrintAndLogEx(ERR, "Card not in iso14443-4. res=%d.", resp.oldarg[0]); + PrintAndLogEx(ERR, "Card not in iso14443-4. res=" PRId64 ".", resp.oldarg[0]); return 1; } @@ -647,7 +647,7 @@ static int SelectCard14443_4(bool disconnect, iso14a_card_select_t *card) { } if (resp.oldarg[0] != 1 && resp.oldarg[0] != 2) { - PrintAndLogEx(ERR, "Card not in iso14443-4. res=%d.", resp.oldarg[0]); + PrintAndLogEx(ERR, "Card not in iso14443-4. res=%" PRId64 ".", resp.oldarg[0]); return 1; } @@ -1376,7 +1376,7 @@ int infoHF14A(bool verbose, bool do_nack_test) { int16_t fsci = card.ats[1] & 0x0f; PrintAndLogEx(NORMAL, " - T0 : TA1 is%s present, TB1 is%s present, " - "TC1 is%s present, FSCI is %d (FSC = %ld)", + "TC1 is%s present, FSCI is %d (FSC = %d)", (ta1 ? "" : " NOT"), (tb1 ? "" : " NOT"), (tc1 ? "" : " NOT"), @@ -1408,7 +1408,7 @@ int infoHF14A(bool verbose, bool do_nack_test) { if (tb1) { uint32_t sfgi = card.ats[pos] & 0x0F; uint32_t fwi = card.ats[pos] >> 4; - PrintAndLogEx(NORMAL, " - TB1 : SFGI = %d (SFGT = %s%ld/fc), FWI = %d (FWT = %ld/fc)", + PrintAndLogEx(NORMAL, " - TB1 : SFGI = %d (SFGT = %s%d/fc), FWI = %d (FWT = %d/fc)", (sfgi), sfgi ? "" : "(not needed) ", sfgi ? (1 << 12) << sfgi : 0, diff --git a/client/cmdhf14b.c b/client/cmdhf14b.c index 57f275a31..03a5f9b9f 100644 --- a/client/cmdhf14b.c +++ b/client/cmdhf14b.c @@ -900,7 +900,7 @@ static int CmdHF14BDump(const char *Cmd) { //select if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { if (resp.oldarg[0]) { - PrintAndLogEx(INFO, "failed to select %d | %d", resp.oldarg[0], resp.oldarg[1]); + PrintAndLogEx(INFO, "failed to select %" PRId64 " | %" PRId64, resp.oldarg[0], resp.oldarg[1]); goto out; } } diff --git a/client/cmdhf15.c b/client/cmdhf15.c index eb8cb6f87..f6c298f63 100644 --- a/client/cmdhf15.c +++ b/client/cmdhf15.c @@ -534,7 +534,7 @@ static int CmdHF15Demod(const char *Cmd) { } } - PrintAndLogEx(NORMAL, "SOF at %d, correlation %d", maxPos, max / (ARRAYLEN(FrameSOF) / skip)); + PrintAndLogEx(NORMAL, "SOF at %d, correlation %zu", maxPos, max / (ARRAYLEN(FrameSOF) / skip)); i = maxPos + ARRAYLEN(FrameSOF) / skip; int k = 0; @@ -1228,7 +1228,7 @@ static int CmdHF15Restore(const char *Cmd) { cmdp++; } - PrintAndLogEx(INFO, "Blocksize: %u", blocksize); + PrintAndLogEx(INFO, "Blocksize: %zu", blocksize); if (!strlen(filename)) { PrintAndLogEx(WARNING, "Please provide a filename"); @@ -1259,7 +1259,7 @@ static int CmdHF15Restore(const char *Cmd) { fclose(f); return 0; } else if (bytes_read != blocksize) { - PrintAndLogEx(ERR, "File reading error (%s), %u bytes read instead of %u bytes.", filename, bytes_read, blocksize); + PrintAndLogEx(ERR, "File reading error (%s), %zu bytes read instead of %zu bytes.", filename, bytes_read, blocksize); fclose(f); return 2; } diff --git a/client/cmdhfepa.c b/client/cmdhfepa.c index 2a7ff5928..1b6ec4d6a 100644 --- a/client/cmdhfepa.c +++ b/client/cmdhfepa.c @@ -50,7 +50,7 @@ static int CmdHFEPACollectPACENonces(const char *Cmd) { // check if command failed if (resp.oldarg[0] != 0) { - PrintAndLogEx(FAILED, "Error in step %d, Return code: %d", resp.oldarg[0], (int)resp.oldarg[1]); + PrintAndLogEx(FAILED, "Error in step %" PRId64 ", Return code: %" PRId64, resp.oldarg[0], (int)resp.oldarg[1]); } else { size_t nonce_length = resp.oldarg[1]; char *nonce = (char *) calloc(2 * nonce_length + 1, sizeof(uint8_t)); @@ -58,7 +58,7 @@ static int CmdHFEPACollectPACENonces(const char *Cmd) { sprintf(nonce + (2 * j), "%02X", resp.data.asBytes[j]); } // print nonce - PrintAndLogEx(NORMAL, "Length: %d, Nonce: %s", nonce_length, nonce); + PrintAndLogEx(NORMAL, "Length: %zu, Nonce: %s", nonce_length, nonce); free(nonce); } if (i < n - 1) { diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index c3681bf60..0948bcf82 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -13,6 +13,7 @@ #include #include #include +#include #include "cmdparser.h" // command_t #include "comms.h" @@ -391,7 +392,7 @@ static int CmdHFFelicaDumpLite(const char *Cmd) { return 1; } - uint64_t tracelen = resp.oldarg[1]; + uint32_t tracelen = resp.oldarg[1]; if (tracelen == 0) return 1; @@ -407,7 +408,7 @@ static int CmdHFFelicaDumpLite(const char *Cmd) { return 0; } - PrintAndLogEx(SUCCESS, "Recorded Activity (trace len = %d bytes)", tracelen); + PrintAndLogEx(SUCCESS, "Recorded Activity (trace len = %"PRIu64" bytes)", tracelen); print_hex_break(trace, tracelen, 32); printSep(); diff --git a/client/cmdhffido.c b/client/cmdhffido.c index fbc91e814..8930e237d 100644 --- a/client/cmdhffido.c +++ b/client/cmdhffido.c @@ -75,14 +75,14 @@ static int CmdHFFidoInfo(const char *cmd) { if (!strncmp((char *)buf, "U2F_V2", 7)) { if (!strncmp((char *)buf, "FIDO_2_0", 8)) { - PrintAndLogEx(INFO, "FIDO2 authenticator detected. Version: %.*s", len, buf); + PrintAndLogEx(INFO, "FIDO2 authenticator detected. Version: %.*s", (int)len, buf); } else { PrintAndLogEx(INFO, "FIDO authenticator detected (not standard U2F)."); PrintAndLogEx(INFO, "Non U2F authenticator version:"); dump_buffer((const unsigned char *)buf, len, NULL, 0); } } else { - PrintAndLogEx(INFO, "FIDO U2F authenticator detected. Version: %.*s", len, buf); + PrintAndLogEx(INFO, "FIDO U2F authenticator detected. Version: %.*s", (int)len, buf); } res = FIDO2GetInfo(buf, sizeof(buf), &len, &sw); @@ -274,7 +274,7 @@ static int CmdHFFidoRegister(const char *cmd) { PrintAndLogEx(NORMAL, ""); if (APDULogging) PrintAndLogEx(NORMAL, "---------------------------------------------------------------"); - PrintAndLogEx(NORMAL, "data len: %d", len); + PrintAndLogEx(NORMAL, "data len: %zu", len); if (verbose2) { PrintAndLogEx(NORMAL, "--------------data----------------------"); dump_buffer((const unsigned char *)buf, len, NULL, 0); @@ -316,7 +316,7 @@ static int CmdHFFidoRegister(const char *cmd) { // get hash int hashp = 1 + 65 + 1 + keyHandleLen + derLen; - PrintAndLogEx(SUCCESS, "Hash[%d]: %s", len - hashp, sprint_hex(&buf[hashp], len - hashp)); + PrintAndLogEx(SUCCESS, "Hash[%zu]: %s", len - hashp, sprint_hex(&buf[hashp], len - hashp)); // check ANSI X9.62 format ECDSA signature (on P-256) uint8_t rval[300] = {0}; @@ -543,7 +543,7 @@ static int CmdHFFidoAuthenticate(const char *cmd) { PrintAndLogEx(SUCCESS, "User presence: %s", (buf[0] ? "verified" : "not verified")); uint32_t cntr = (uint32_t)bytes_to_num(&buf[1], 4); PrintAndLogEx(SUCCESS, "Counter: %d", cntr); - PrintAndLogEx(SUCCESS, "Hash[%d]: %s", len - 5, sprint_hex(&buf[5], len - 5)); + PrintAndLogEx(SUCCESS, "Hash[%zu]: %s", len - 5, sprint_hex(&buf[5], len - 5)); // check ANSI X9.62 format ECDSA signature (on P-256) uint8_t rval[300] = {0}; @@ -736,7 +736,7 @@ static int CmdHFFido2MakeCredential(const char *cmd) { return 0; } - PrintAndLogEx(SUCCESS, "MakeCredential result (%d b) OK.", len); + PrintAndLogEx(SUCCESS, "MakeCredential result (%zu b) OK.", len); if (showCBOR) { PrintAndLogEx(SUCCESS, "CBOR make credential response:"); PrintAndLogEx(NORMAL, "---------------- CBOR ------------------"); @@ -862,7 +862,7 @@ static int CmdHFFido2GetAssertion(const char *cmd) { return 0; } - PrintAndLogEx(SUCCESS, "GetAssertion result (%d b) OK.", len); + PrintAndLogEx(SUCCESS, "GetAssertion result (%zu b) OK.", len); if (showCBOR) { PrintAndLogEx(SUCCESS, "CBOR get assertion response:"); PrintAndLogEx(NORMAL, "---------------- CBOR ------------------"); diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 691072174..a8526cbde 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -1332,7 +1332,7 @@ static int CmdHFiClassReader_Dump(const char *Cmd) { } // save the dump to .bin file - PrintAndLogEx(SUCCESS, "saving dump file - %d blocks read", gotBytes / 8); + PrintAndLogEx(SUCCESS, "saving dump file - %zu blocks read", gotBytes / 8); saveFile(filename, ".bin", tag_data, gotBytes); saveFileEML(filename, tag_data, gotBytes, 8); saveFileJSON(filename, jsfIclass, tag_data, gotBytes); @@ -2081,7 +2081,7 @@ static int loadKeys(char *filename) { size_t bytes_read = fread(dump, 1, fsize, f); fclose(f); if (bytes_read > ICLASS_KEYS_MAX * 8) { - PrintAndLogEx(WARNING, "File is too long to load - bytes: %u", bytes_read); + PrintAndLogEx(WARNING, "File is too long to load - bytes: %zu", bytes_read); free(dump); return 0; } @@ -2502,7 +2502,7 @@ static int CmdHFiClassLookUp(const char *Cmd) { case 'p': param_gethex_ex(Cmd, cmdp + 1, EPURSE, &len); if (len >> 1 != sizeof(EPURSE)) { - PrintAndLogEx(WARNING, "Wrong EPURSE length, expected %d got [%d] ", sizeof(EPURSE), len >> 1); + PrintAndLogEx(WARNING, "Wrong EPURSE length, expected %zu got [%d] ", sizeof(EPURSE), len >> 1); errors = true; } cmdp += 2; @@ -2652,7 +2652,7 @@ void PrintPreCalc(iclass_prekey_t *list, int itemcnt) { for (int i = 0; i < itemcnt; i++) { if (i < 10) { - PrintAndLogEx(NORMAL, "[%2d] | %016" PRIx64 " | %08" PRIx32, i, bytes_to_num(list[i].key, 8), bytes_to_num(list[i].mac, 4)); + PrintAndLogEx(NORMAL, "[%2d] | %016" PRIx64 " | %08" PRIx64, i, bytes_to_num(list[i].key, 8), bytes_to_num(list[i].mac, 4)); } else if (i == 10) { PrintAndLogEx(SUCCESS, "... skip printing the rest"); } diff --git a/client/cmdhflegic.c b/client/cmdhflegic.c index 31628ffff..4a72397e3 100644 --- a/client/cmdhflegic.c +++ b/client/cmdhflegic.c @@ -1036,7 +1036,7 @@ static int CmdLegicRestore(const char *Cmd) { fseek(f, 0, SEEK_SET); // seek back to beginning of file if (filesize != numofbytes) { - PrintAndLogEx(WARNING, "Fail, filesize and cardsize is not equal. [%u != %u]", filesize, numofbytes); + PrintAndLogEx(WARNING, "Fail, filesize and cardsize is not equal. [%zu != %u]", filesize, numofbytes); free(data); fclose(f); return PM3_EFILE; @@ -1084,11 +1084,11 @@ static int CmdLegicRestore(const char *Cmd) { uint8_t isOK = resp.oldarg[0] & 0xFF; if (!isOK) { - PrintAndLogEx(WARNING, "Failed writing tag [msg = %u]", resp.oldarg[1] & 0xFF); + PrintAndLogEx(WARNING, "Failed writing tag [msg = %u]", (uint8_t)(resp.oldarg[1] & 0xFF)); free(data); return PM3_ERFTRANS; } - PrintAndLogEx(SUCCESS, "Wrote chunk [offset %d | len %d | total %d", i, len, i + len); + PrintAndLogEx(SUCCESS, "Wrote chunk [offset %zu | len %zu | total %zu", i, len, i + len); } free(data); @@ -1281,7 +1281,7 @@ static int CmdLegicWipe(const char *Cmd) { uint8_t isOK = resp.oldarg[0] & 0xFF; if (!isOK) { - PrintAndLogEx(WARNING, "Failed writing tag [msg = %u]", resp.oldarg[1] & 0xFF); + PrintAndLogEx(WARNING, "Failed writing tag [msg = %u]", (uint8_t)(resp.oldarg[1] & 0xFF)); free(data); return PM3_ERFTRANS; } diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 3043d19ed..a660ae1b3 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -1296,7 +1296,7 @@ static int CmdHF14AMfNested(const char *Cmd) { } uint64_t t2 = msclock() - t1; - PrintAndLogEx(SUCCESS, "Time to check %d known keys: %.0f seconds\n", ARRAYLEN(g_mifare_default_keys), (float)t2 / 1000.0); + PrintAndLogEx(SUCCESS, "Time to check %zu known keys: %.0f seconds\n", ARRAYLEN(g_mifare_default_keys), (float)t2 / 1000.0); PrintAndLogEx(SUCCESS, "enter nested attack"); // nested sectors diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index 7c81ebfd6..3393c0a0c 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -2496,7 +2496,7 @@ static int CmdHF14AMfUCSetPwd(const char *Cmd) { if ((resp.oldarg[0] & 0xff) == 1) { PrintAndLogEx(INFO, "Ultralight-C new password: %s", sprint_hex(pwd, 16)); } else { - PrintAndLogEx(WARNING, "Failed writing at block %d", resp.oldarg[1] & 0xff); + PrintAndLogEx(WARNING, "Failed writing at block %u", (uint8_t)(resp.oldarg[1] & 0xff)); return 1; } } else { diff --git a/client/cmdhfthinfilm.c b/client/cmdhfthinfilm.c index 2938d1443..6f36a0a9b 100644 --- a/client/cmdhfthinfilm.c +++ b/client/cmdhfthinfilm.c @@ -65,7 +65,7 @@ static int print_barcode(uint8_t *barcode, const size_t barcode_len, bool verbos } else { PrintAndLogEx(SUCCESS, " Checksum : "_YELLOW_("too few data for checksum")"- " _RED_("fail")); } - PrintAndLogEx(SUCCESS, " Data len (bits) : "_YELLOW_("%i")"- %s", barcode_len * 8, (barcode_len == 16 || barcode_len == 32) ? _GREEN_("OK") : _YELLOW_("warning")); + PrintAndLogEx(SUCCESS, " Data len (bits) : "_YELLOW_("%zu")"- %s", barcode_len * 8, (barcode_len == 16 || barcode_len == 32) ? _GREEN_("OK") : _YELLOW_("warning")); PrintAndLogEx(SUCCESS, " Raw data : "_YELLOW_("%s"), sprint_hex(barcode, barcode_len)); if (barcode_len < 4) // too few to go to next decoding stages return PM3_ESOFT; diff --git a/client/cmdhftopaz.c b/client/cmdhftopaz.c index 7d1e75037..ae404b22d 100644 --- a/client/cmdhftopaz.c +++ b/client/cmdhftopaz.c @@ -13,6 +13,7 @@ #include #include #include +#include #include "cmdparser.h" // command_t #include "comms.h" @@ -71,7 +72,7 @@ static int topaz_send_cmd_raw(uint8_t *cmd, uint8_t len, uint8_t *response, uint memcpy(response, resp.data.asBytes, *response_len); } } else { - if (verbose) PrintAndLogEx(WARNING, "Wrong response length (%d != %d)", *response_len, resp.oldarg[0]); + if (verbose) PrintAndLogEx(WARNING, "Wrong response length (%d != %" PRIu64 ")", *response_len, resp.oldarg[0]); return PM3_ESOFT; } return PM3_SUCCESS; diff --git a/client/cmdlf.c b/client/cmdlf.c index 044df875b..49183f609 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -651,7 +651,7 @@ int CmdLFSim(const char *Cmd) { // convert to bitstream if necessary ChkBitstream(); - PrintAndLogEx(DEBUG, "DEBUG: Uploading %d bytes", GraphTraceLen); + PrintAndLogEx(DEBUG, "DEBUG: Uploading %zu bytes", GraphTraceLen); struct pupload { uint8_t flag; @@ -787,7 +787,7 @@ int CmdLFfskSim(const char *Cmd) { size_t size = DemodBufferLen; if (size > (PM3_CMD_DATA_SIZE - sizeof(lf_fsksim_t))) { - PrintAndLogEx(NORMAL, "DemodBuffer too long for current implementation - length: %d - max: %d", size, PM3_CMD_DATA_SIZE - sizeof(lf_fsksim_t)); + PrintAndLogEx(NORMAL, "DemodBuffer too long for current implementation - length: %zu - max: %zu", size, PM3_CMD_DATA_SIZE - sizeof(lf_fsksim_t)); size = PM3_CMD_DATA_SIZE - sizeof(lf_fsksim_t); } @@ -889,7 +889,7 @@ int CmdLFaskSim(const char *Cmd) { size_t size = DemodBufferLen; if (size > (PM3_CMD_DATA_SIZE - sizeof(lf_asksim_t))) { - PrintAndLogEx(NORMAL, "DemodBuffer too long for current implementation - length: %d - max: %d", size, PM3_CMD_DATA_SIZE - sizeof(lf_asksim_t)); + PrintAndLogEx(NORMAL, "DemodBuffer too long for current implementation - length: %zu - max: %zu", size, PM3_CMD_DATA_SIZE - sizeof(lf_asksim_t)); size = PM3_CMD_DATA_SIZE - sizeof(lf_asksim_t); } @@ -1009,7 +1009,7 @@ int CmdLFpskSim(const char *Cmd) { } size_t size = DemodBufferLen; if (size > (PM3_CMD_DATA_SIZE - sizeof(lf_psksim_t))) { - PrintAndLogEx(NORMAL, "DemodBuffer too long for current implementation - length: %d - max: %d", size, PM3_CMD_DATA_SIZE - sizeof(lf_psksim_t)); + PrintAndLogEx(NORMAL, "DemodBuffer too long for current implementation - length: %zu - max: %zu", size, PM3_CMD_DATA_SIZE - sizeof(lf_psksim_t)); size = PM3_CMD_DATA_SIZE - sizeof(lf_psksim_t); } diff --git a/client/cmdlfawid.c b/client/cmdlfawid.c index 035730588..641c29720 100644 --- a/client/cmdlfawid.c +++ b/client/cmdlfawid.c @@ -324,7 +324,7 @@ static int CmdAWIDDemod(const char *Cmd) { } free(bits); - PrintAndLogEx(DEBUG, "DEBUG: AWID idx: %d, Len: %d Printing Demod Buffer:", idx, size); + PrintAndLogEx(DEBUG, "DEBUG: AWID idx: %d, Len: %zu Printing Demod Buffer:", idx, size); if (g_debugMode) printDemodBuff(); diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c index c73e63ead..bd93a48ab 100644 --- a/client/cmdlfem4x.c +++ b/client/cmdlfem4x.c @@ -416,7 +416,7 @@ int AskEm410xDecode(bool verbose, uint32_t *hi, uint64_t *lo) { setDemodBuff(DemodBuffer, (size == 40) ? 64 : 128, idx + 1); setClockGrid(g_DemodClock, g_DemodStartIdx + ((idx + 1)*g_DemodClock)); - PrintAndLogEx(DEBUG, "DEBUG: Em410x idx: %d, Len: %d, Printing Demod Buffer:", idx, size); + PrintAndLogEx(DEBUG, "DEBUG: Em410x idx: %zu, Len: %zu, Printing Demod Buffer:", idx, size); if (g_debugMode) printDemodBuff(); @@ -1085,7 +1085,7 @@ static bool doPreambleSearch(size_t *startIdx) { uint8_t preamble[EM_PREAMBLE_LEN] = {0, 0, 1, 0, 1, 0}; if (!preambleSearchEx(DemodBuffer, preamble, EM_PREAMBLE_LEN, &size, startIdx, true)) { - PrintAndLogEx(DEBUG, "DEBUG: Error - EM4305 preamble not found :: %d", *startIdx); + PrintAndLogEx(DEBUG, "DEBUG: Error - EM4305 preamble not found :: %zu", *startIdx); return false; } return true; diff --git a/client/cmdlffdx.c b/client/cmdlffdx.c index 992eabdd8..f1f3d6100 100644 --- a/client/cmdlffdx.c +++ b/client/cmdlffdx.c @@ -245,7 +245,7 @@ static int CmdFdxDemod(const char *Cmd) { PrintAndLogEx(SUCCESS, "CRC-16 0x%04X - 0x%04X [%s]", crc_16, calcCrc, (calcCrc == crc_16) ? _GREEN_("Ok") : _RED_("Fail")); if (g_debugMode) { - PrintAndLogEx(DEBUG, "Start marker %d; Size %d", preambleIndex, size); + PrintAndLogEx(DEBUG, "Start marker %d; Size %zu", preambleIndex, size); char *bin = sprint_bin_break(DemodBuffer, size, 16); PrintAndLogEx(DEBUG, "DEBUG bin stream:\n%s", bin); } diff --git a/client/cmdlfguard.c b/client/cmdlfguard.c index 366fe77e3..c65ff068a 100644 --- a/client/cmdlfguard.c +++ b/client/cmdlfguard.c @@ -84,7 +84,7 @@ static int CmdGuardDemod(const char *Cmd) { else if (preambleIndex == -2) PrintAndLogEx(DEBUG, "DEBUG: Error - gProxII preamble not found"); else if (preambleIndex == -3) - PrintAndLogEx(DEBUG, "DEBUG: Error - gProxII size not correct: %d", size); + PrintAndLogEx(DEBUG, "DEBUG: Error - gProxII size not correct: %zu", size); else if (preambleIndex == -5) PrintAndLogEx(DEBUG, "DEBUG: Error - gProxII wrong spacerbits"); else @@ -103,14 +103,14 @@ static int CmdGuardDemod(const char *Cmd) { // remove the 18 (90/5=18) parity bits (down to 72 bits (96-6-18=72)) size_t len = removeParity(bits_no_spacer, 0, 5, 3, 90); //source, startloc, paritylen, ptype, length_to_run if (len != 72) { - PrintAndLogEx(DEBUG, "DEBUG: Error - gProxII spacer removal did not produce 72 bits: %u, start: %u", len, startIdx); + PrintAndLogEx(DEBUG, "DEBUG: Error - gProxII spacer removal did not produce 72 bits: %zu, start: %zu", len, startIdx); return PM3_ESOFT; } // get key and then get all 8 bytes of payload decoded xorKey = (uint8_t)bytebits_to_byteLSBF(bits_no_spacer, 8); for (size_t idx = 0; idx < 8; idx++) { ByteStream[idx] = ((uint8_t)bytebits_to_byteLSBF(bits_no_spacer + 8 + (idx * 8), 8)) ^ xorKey; - PrintAndLogEx(DEBUG, "DEBUG: gProxII byte %u after xor: %02x", (unsigned int)idx, ByteStream[idx]); + PrintAndLogEx(DEBUG, "DEBUG: gProxII byte %zu after xor: %02x", idx, ByteStream[idx]); } setDemodBuff(DemodBuffer, 96, preambleIndex); diff --git a/client/cmdlfhid.c b/client/cmdlfhid.c index a5cb64325..09cf90b03 100644 --- a/client/cmdlfhid.c +++ b/client/cmdlfhid.c @@ -123,7 +123,7 @@ static int sendTry(uint8_t format_idx, wiegand_card_t *card, uint32_t delay, boo } if (verbose) - PrintAndLogEx(INFO, "Trying FC: %u; CN: %u; Issue level: %u; OEM: %u", card->FacilityCode, card->CardNumber, card->IssueLevel, card->OEM); + PrintAndLogEx(INFO, "Trying FC: %u; CN: %"PRIu64"; Issue level: %u; OEM: %u", card->FacilityCode, card->CardNumber, card->IssueLevel, card->OEM); lf_hidsim_t payload; payload.hi2 = packed.Top; @@ -177,7 +177,7 @@ static int CmdHIDDemod(const char *Cmd) { else if (idx == -4) PrintAndLogEx(DEBUG, "DEBUG: Error - HID preamble not found"); else if (idx == -5) - PrintAndLogEx(DEBUG, "DEBUG: Error - HID error in Manchester data, size %d", size); + PrintAndLogEx(DEBUG, "DEBUG: Error - HID error in Manchester data, size %zu", size); else PrintAndLogEx(DEBUG, "DEBUG: Error - HID error demoding fsk %d", idx); diff --git a/client/cmdlfindala.c b/client/cmdlfindala.c index eae80564d..0e308be35 100644 --- a/client/cmdlfindala.c +++ b/client/cmdlfindala.c @@ -98,7 +98,7 @@ static int CmdIndalaDemod(const char *Cmd) { else if (idx == -4) PrintAndLogEx(DEBUG, "DEBUG: Error - Indala: preamble not found"); else if (idx == -5) - PrintAndLogEx(DEBUG, "DEBUG: Error - Indala: size not correct: %d", size); + PrintAndLogEx(DEBUG, "DEBUG: Error - Indala: size not correct: %zu", size); else PrintAndLogEx(DEBUG, "DEBUG: Error - Indala: error demoding psk idx: %d", idx); return PM3_ESOFT; @@ -114,7 +114,7 @@ static int CmdIndalaDemod(const char *Cmd) { if (DemodBufferLen == 64) { PrintAndLogEx( SUCCESS - , "Indala Found - bitlength %d, Raw %x%08x" + , "Indala Found - bitlength %zu, Raw %x%08x" , DemodBufferLen , uid1 , uid2 @@ -161,7 +161,7 @@ static int CmdIndalaDemod(const char *Cmd) { uint32_t uid7 = bytebits_to_byte(DemodBuffer + 192, 32); PrintAndLogEx( SUCCESS - , "Indala Found - bitlength %d, Raw 0x%x%08x%08x%08x%08x%08x%08x" + , "Indala Found - bitlength %zu, Raw 0x%x%08x%08x%08x%08x%08x%08x" , DemodBufferLen , uid1 , uid2 @@ -237,7 +237,7 @@ static int CmdIndalaDemodAlt(const char *Cmd) { } if (rawbit > 0) { - PrintAndLogEx(INFO, "Recovered %d raw bits, expected: %d", rawbit, GraphTraceLen / 32); + PrintAndLogEx(INFO, "Recovered %d raw bits, expected: %zu", rawbit, GraphTraceLen / 32); PrintAndLogEx(INFO, "worst metric (0=best..7=worst): %d at pos %d", worst, worstPos); } else { return PM3_ESOFT; @@ -629,7 +629,7 @@ out: //PrintAndLogEx(INFO, "DEBUG: detectindala RES = %d | %d | %d", res, found_size, idx); if (found_size != 224 && found_size != 64) { - PrintAndLogEx(INFO, "DEBUG: detectindala | %d", found_size); + PrintAndLogEx(INFO, "DEBUG: detectindala | %zu", found_size); return -5; } diff --git a/client/cmdlfio.c b/client/cmdlfio.c index 74a9ef92d..dd3a78aa7 100644 --- a/client/cmdlfio.c +++ b/client/cmdlfio.c @@ -109,7 +109,7 @@ static int CmdIOProxDemod(const char *Cmd) { } else if (idx == -4) { PrintAndLogEx(DEBUG, "DEBUG: Error - IO prox preamble not found"); } else if (idx == -5) { - PrintAndLogEx(DEBUG, "DEBUG: Error - IO size not correct, size %d", size); + PrintAndLogEx(DEBUG, "DEBUG: Error - IO size not correct, size %zu", size); } else if (idx == -6) { PrintAndLogEx(DEBUG, "DEBUG: Error - IO prox separator bits not found"); } else { @@ -123,7 +123,7 @@ static int CmdIOProxDemod(const char *Cmd) { if (idx == 0) { if (g_debugMode) { - PrintAndLogEx(DEBUG, "DEBUG: Error - IO prox data not found - FSK Bits: %d", size); + PrintAndLogEx(DEBUG, "DEBUG: Error - IO prox data not found - FSK Bits: %zu", size); if (size > 92) PrintAndLogEx(DEBUG, "%s", sprint_bin_break(bits, 92, 16)); } return PM3_ESOFT; @@ -176,7 +176,7 @@ static int CmdIOProxDemod(const char *Cmd) { PrintAndLogEx(SUCCESS, "IO Prox XSF(%02d)%02x:%05d (%08x%08x) [crc %s]", version, facilitycode, number, code, code2, crcStr); if (g_debugMode) { - PrintAndLogEx(DEBUG, "DEBUG: IO prox idx: %d, Len: %d, Printing demod buffer:", idx, size); + PrintAndLogEx(DEBUG, "DEBUG: IO prox idx: %d, Len: %zu, Printing demod buffer:", idx, size); printDemodBuff(); } return retval; diff --git a/client/cmdlfjablotron.c b/client/cmdlfjablotron.c index d2a0d9967..3633902f2 100644 --- a/client/cmdlfjablotron.c +++ b/client/cmdlfjablotron.c @@ -94,7 +94,7 @@ static int CmdJablotronDemod(const char *Cmd) { else if (ans == -2) PrintAndLogEx(DEBUG, "DEBUG: Error - Jablotron preamble not found"); else if (ans == -3) - PrintAndLogEx(DEBUG, "DEBUG: Error - Jablotron size not correct: %d", size); + PrintAndLogEx(DEBUG, "DEBUG: Error - Jablotron size not correct: %zu", size); else if (ans == -5) PrintAndLogEx(DEBUG, "DEBUG: Error - Jablotron checksum failed"); else diff --git a/client/cmdlfkeri.c b/client/cmdlfkeri.c index e36388041..9e9bbdb49 100644 --- a/client/cmdlfkeri.c +++ b/client/cmdlfkeri.c @@ -70,7 +70,7 @@ static int CmdKeriDemod(const char *Cmd) { else if (idx == -2) PrintAndLogEx(DEBUG, "DEBUG: Error - KERI: preamble not found"); else if (idx == -3) - PrintAndLogEx(DEBUG, "DEBUG: Error - KERI: Size not correct: 64 != %d", size); + PrintAndLogEx(DEBUG, "DEBUG: Error - KERI: Size not correct: 64 != %zu", size); else PrintAndLogEx(DEBUG, "DEBUG: Error - KERI: ans: %d", idx); @@ -154,7 +154,7 @@ static int CmdKeriClone(const char *Cmd) { // 3 LSB is ONE uint64_t data = ((uint64_t)internalid << 3) + 7; - PrintAndLogEx(INFO, "Preparing to clone KERI to T55x7 with Internal Id: %" PRIx64, internalid); + PrintAndLogEx(INFO, "Preparing to clone KERI to T55x7 with Internal Id: %" PRIx32, internalid); blocks[1] = data >> 32; blocks[2] = data & 0xFFFFFFFF; @@ -182,7 +182,7 @@ static int CmdKeriSim(const char *Cmd) { bs[j++] = ((internalid >> i) & 1); } - PrintAndLogEx(SUCCESS, "Simulating KERI - Internal Id: %u", internalid); + PrintAndLogEx(SUCCESS, "Simulating KERI - Internal Id: %" PRIu64, internalid); lf_psksim_t *payload = calloc(1, sizeof(lf_psksim_t) + sizeof(bs)); payload->carrier = 2; diff --git a/client/cmdlfnedap.c b/client/cmdlfnedap.c index cab5e55c6..f4c5346e2 100644 --- a/client/cmdlfnedap.c +++ b/client/cmdlfnedap.c @@ -124,7 +124,7 @@ static int CmdLFNedapDemod(const char *Cmd) { // sanity checks if ((size != 128) && (size != 64)) { - PrintAndLogEx(DEBUG, "DEBUG: Error - NEDAP: Size not correct: %d", size); + PrintAndLogEx(DEBUG, "DEBUG: Error - NEDAP: Size not correct: %zu", size); return PM3_ESOFT; } diff --git a/client/cmdlfnoralsy.c b/client/cmdlfnoralsy.c index 9cec6767e..207d6e4f8 100644 --- a/client/cmdlfnoralsy.c +++ b/client/cmdlfnoralsy.c @@ -85,7 +85,7 @@ static int CmdNoralsyDemod(const char *Cmd) { else if (ans == -2) PrintAndLogEx(DEBUG, "DEBUG: Error - Noralsy: preamble not found"); else if (ans == -3) - PrintAndLogEx(DEBUG, "DEBUG: Error - Noralsy: Size not correct: %d", size); + PrintAndLogEx(DEBUG, "DEBUG: Error - Noralsy: Size not correct: %zu", size); else PrintAndLogEx(DEBUG, "DEBUG: Error - Noralsy: ans: %d", ans); } diff --git a/client/cmdlfpac.c b/client/cmdlfpac.c index 1977224e5..9e6f9337c 100644 --- a/client/cmdlfpac.c +++ b/client/cmdlfpac.c @@ -53,7 +53,7 @@ static int CmdPacDemod(const char *Cmd) { else if (ans == -2) PrintAndLogEx(DEBUG, "DEBUG: Error - PAC: preamble not found"); else if (ans == -3) - PrintAndLogEx(DEBUG, "DEBUG: Error - PAC: Size not correct: %d", size); + PrintAndLogEx(DEBUG, "DEBUG: Error - PAC: Size not correct: %zu", size); else PrintAndLogEx(DEBUG, "DEBUG: Error - PAC: ans: %d", ans); diff --git a/client/cmdlfparadox.c b/client/cmdlfparadox.c index b3307b8a8..b1a20dec2 100644 --- a/client/cmdlfparadox.c +++ b/client/cmdlfparadox.c @@ -86,7 +86,7 @@ static int CmdParadoxDemod(const char *Cmd) { else if (idx == -4) PrintAndLogEx(DEBUG, "DEBUG: Error - Paradox preamble not found"); else if (idx == -5) - PrintAndLogEx(DEBUG, "DEBUG: Error - Paradox error in Manchester data, size %d", size); + PrintAndLogEx(DEBUG, "DEBUG: Error - Paradox error in Manchester data, size %zu", size); else PrintAndLogEx(DEBUG, "DEBUG: Error - Paradox error demoding fsk %d", idx); @@ -117,7 +117,7 @@ static int CmdParadoxDemod(const char *Cmd) { rawLo ); - PrintAndLogEx(DEBUG, "DEBUG: Paradox idx: %d, len: %d, Printing Demod Buffer:", idx, size); + PrintAndLogEx(DEBUG, "DEBUG: Paradox idx: %d, len: %zu, Printing Demod Buffer:", idx, size); if (g_debugMode) printDemodBuff(); diff --git a/client/cmdlfpresco.c b/client/cmdlfpresco.c index cfe56ad5e..06645e86f 100644 --- a/client/cmdlfpresco.c +++ b/client/cmdlfpresco.c @@ -72,7 +72,7 @@ static int CmdPrescoDemod(const char *Cmd) { else if (ans == -2) PrintAndLogEx(DEBUG, "DEBUG: Error - Presco: preamble not found"); else if (ans == -3) - PrintAndLogEx(DEBUG, "DEBUG: Error - Presco: Size not correct: %d", size); + PrintAndLogEx(DEBUG, "DEBUG: Error - Presco: Size not correct: %zu", size); else PrintAndLogEx(DEBUG, "DEBUG: Error - Presco: ans: %d", ans); return PM3_ESOFT; diff --git a/client/cmdlfpyramid.c b/client/cmdlfpyramid.c index fa93a395c..0f21c7c33 100644 --- a/client/cmdlfpyramid.c +++ b/client/cmdlfpyramid.c @@ -87,7 +87,7 @@ static int CmdPyramidDemod(const char *Cmd) { else if (idx == -4) PrintAndLogEx(DEBUG, "DEBUG: Error - Pyramid: preamble not found"); else if (idx == -5) - PrintAndLogEx(DEBUG, "DEBUG: Error - Pyramid: size not correct: %d", size); + PrintAndLogEx(DEBUG, "DEBUG: Error - Pyramid: size not correct: %zu", size); else PrintAndLogEx(DEBUG, "DEBUG: Error - Pyramid: error demoding fsk idx: %d", idx); return PM3_ESOFT; @@ -137,7 +137,7 @@ static int CmdPyramidDemod(const char *Cmd) { if (size == 0) PrintAndLogEx(DEBUG, "DEBUG: Error - Pyramid: parity check failed - IDX: %d, hi3: %08X", idx, rawHi3); else - PrintAndLogEx(DEBUG, "DEBUG: Error - Pyramid: at parity check - tag size does not match Pyramid format, SIZE: %d, IDX: %d, hi3: %08X", size, idx, rawHi3); + PrintAndLogEx(DEBUG, "DEBUG: Error - Pyramid: at parity check - tag size does not match Pyramid format, SIZE: %zu, IDX: %d, hi3: %08X", size, idx, rawHi3); return PM3_ESOFT; } diff --git a/client/cmdlfsecurakey.c b/client/cmdlfsecurakey.c index 784286e41..183762338 100644 --- a/client/cmdlfsecurakey.c +++ b/client/cmdlfsecurakey.c @@ -59,7 +59,7 @@ static int CmdSecurakeyDemod(const char *Cmd) { else if (ans == -2) PrintAndLogEx(DEBUG, "DEBUG: Error - Securakey: preamble not found"); else if (ans == -3) - PrintAndLogEx(DEBUG, "DEBUG: Error - Securakey: Size not correct: %d", size); + PrintAndLogEx(DEBUG, "DEBUG: Error - Securakey: Size not correct: %zu", size); else PrintAndLogEx(DEBUG, "DEBUG: Error - Securakey: ans: %d", ans); return PM3_ESOFT; @@ -90,7 +90,7 @@ static int CmdSecurakeyDemod(const char *Cmd) { // remove marker bits (0's every 9th digit after preamble) (pType = 3 (always 0s)) size = removeParity(bits_no_spacer, 0, 9, 3, 85); if (size != 85 - 9) { - PrintAndLogEx(DEBUG, "DEBUG: Error removeParity: %d", size); + PrintAndLogEx(DEBUG, "DEBUG: Error removeParity: %zu", size); return 0; } diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 8ede60e11..eaa181aad 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -1257,7 +1257,7 @@ bool GetT55xxBlockData(uint32_t *blockdata) { uint8_t idx = config.offset; if (idx + 32 > DemodBufferLen) { - PrintAndLogEx(WARNING, "The configured offset %d is too big. Possible offset: %d)", idx, DemodBufferLen - 32); + PrintAndLogEx(WARNING, "The configured offset %d is too big. Possible offset: %zu)", idx, DemodBufferLen - 32); return false; } @@ -2624,12 +2624,12 @@ static int CmdT55xxChkPwds(const char *Cmd) { } if (resp.oldarg[0]) { - PrintAndLogEx(SUCCESS, "\nFound a candidate [ " _YELLOW_("%08X") " ]. Trying to validate", resp.oldarg[1]); + PrintAndLogEx(SUCCESS, "\nFound a candidate [ " _YELLOW_("%08"PRIX64) " ]. Trying to validate", resp.oldarg[1]); if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, resp.oldarg[1], downlink_mode)) { found = tryDetectModulation(downlink_mode, T55XX_PrintConfig); if (found) { - PrintAndLogEx(SUCCESS, "Found valid password: [ " _GREEN_("%08X") " ]", resp.oldarg[1]); + PrintAndLogEx(SUCCESS, "Found valid password: [ " _GREEN_("%08"PRIX64) " ]", resp.oldarg[1]); } else { PrintAndLogEx(WARNING, "Check pwd failed"); @@ -2672,7 +2672,7 @@ static int CmdT55xxChkPwds(const char *Cmd) { curr_password = bytes_to_num(keyBlock + 4 * c, 4); - PrintAndLogEx(INFO, "Testing %08X", curr_password); + PrintAndLogEx(INFO, "Testing %08"PRIX64, curr_password); for (dl_mode = downlink_mode; dl_mode <= 3; dl_mode++) { if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, curr_password, dl_mode)) { @@ -2681,7 +2681,7 @@ static int CmdT55xxChkPwds(const char *Cmd) { found = tryDetectModulation(dl_mode, T55XX_PrintConfig); if (found) { - PrintAndLogEx(SUCCESS, "Found valid password: [ " _GREEN_("%08X") " ]", curr_password); + PrintAndLogEx(SUCCESS, "Found valid password: [ " _GREEN_("%08"PRIX64) " ]", curr_password); dl_mode = 4; // Exit other downlink mode checks c = keycount; // Exit loop } diff --git a/client/cmdlfverichip.c b/client/cmdlfverichip.c index 6bb8845a5..21ac52836 100644 --- a/client/cmdlfverichip.c +++ b/client/cmdlfverichip.c @@ -53,7 +53,7 @@ static int CmdVerichipDemod(const char *Cmd) { else if (ans == -2) PrintAndLogEx(DEBUG, "DEBUG: Error - VERICHIP: preamble not found"); else if (ans == -3) - PrintAndLogEx(DEBUG, "DEBUG: Error - VERICHIP: Size not correct: %d", size); + PrintAndLogEx(DEBUG, "DEBUG: Error - VERICHIP: Size not correct: %zu", size); else PrintAndLogEx(DEBUG, "DEBUG: Error - VERICHIP: ans: %d", ans); diff --git a/client/cmdlfvisa2000.c b/client/cmdlfvisa2000.c index f60510f23..a32dc5aeb 100644 --- a/client/cmdlfvisa2000.c +++ b/client/cmdlfvisa2000.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "commonutil.h" // ARRAYLEN #include "common.h" @@ -119,7 +120,7 @@ static int CmdVisa2kDemod(const char *Cmd) { else if (ans == -2) PrintAndLogEx(DEBUG, "DEBUG: Error - Visa2k: preamble not found"); else if (ans == -3) - PrintAndLogEx(DEBUG, "DEBUG: Error - Visa2k: Size not correct: %d", size); + PrintAndLogEx(DEBUG, "DEBUG: Error - Visa2k: Size not correct: %zu", size); else PrintAndLogEx(DEBUG, "DEBUG: Error - Visa2k: ans: %d", ans); @@ -180,7 +181,7 @@ static int CmdVisa2kClone(const char *Cmd) { blocks[2] = id; blocks[3] = (visa_parity(id) << 4) | visa_chksum(id); - PrintAndLogEx(INFO, "Preparing to clone Visa2000 to T55x7 with CardId: %u", id); + PrintAndLogEx(INFO, "Preparing to clone Visa2000 to T55x7 with CardId: %"PRIu64, id); print_blocks(blocks, ARRAYLEN(blocks)); return clone_t55xx_tag(blocks, ARRAYLEN(blocks)); diff --git a/client/cmdsmartcard.c b/client/cmdsmartcard.c index c9dde7063..c69e4f037 100644 --- a/client/cmdsmartcard.c +++ b/client/cmdsmartcard.c @@ -311,7 +311,7 @@ static int PrintATR(uint8_t *atr, size_t atrlen) { uint8_t calen = 2 + T1len + TD1len + TDilen + K; if (atrlen != calen && atrlen != calen + 1) // may be CRC - PrintAndLogEx(WARNING, "Invalid ATR length. len: %d, T1len: %d, TD1len: %d, TDilen: %d, K: %d", atrlen, T1len, TD1len, TDilen, K); + PrintAndLogEx(WARNING, "Invalid ATR length. len: %zu, T1len: %d, TD1len: %d, TDilen: %d, K: %d", atrlen, T1len, TD1len, TDilen, K); if (K > 0) PrintAndLogEx(INFO, "\nHistorical bytes | len 0x%02d | format %02x", K, atr[2 + T1len + TD1len + TDilen]); @@ -443,7 +443,7 @@ static int CmdSmartRaw(const char *Cmd) { PrintAndLogEx(WARNING, "Invalid HEX value."); return 1; case 2: - PrintAndLogEx(WARNING, "Too many bytes. Max %d bytes", sizeof(data)); + PrintAndLogEx(WARNING, "Too many bytes. Max %zu bytes", sizeof(data)); return 1; case 3: PrintAndLogEx(WARNING, "Hex must have even number of digits."); diff --git a/client/cmdtrace.c b/client/cmdtrace.c index 79e7c6169..7cf178bf0 100644 --- a/client/cmdtrace.c +++ b/client/cmdtrace.c @@ -665,7 +665,7 @@ static int CmdTraceLoad(const char *Cmd) { size_t bytes_read = fread(trace, 1, fsize, f); traceLen = bytes_read; fclose(f); - PrintAndLogEx(SUCCESS, "Recorded Activity (TraceLen = %d bytes) loaded from file %s", traceLen, filename); + PrintAndLogEx(SUCCESS, "Recorded Activity (TraceLen = %l bytes) loaded from file %s", traceLen, filename); return 0; } @@ -815,7 +815,7 @@ int CmdTraceList(const char *Cmd) { } } - PrintAndLogEx(SUCCESS, "Recorded Activity (TraceLen = %d bytes)", traceLen); + PrintAndLogEx(SUCCESS, "Recorded Activity (TraceLen = %l bytes)", traceLen); PrintAndLogEx(INFO, ""); if (protocol == FELICA) { printFelica(traceLen, trace); diff --git a/client/cmdusart.c b/client/cmdusart.c index 26b972f82..3d664d516 100644 --- a/client/cmdusart.c +++ b/client/cmdusart.c @@ -278,13 +278,13 @@ static int usart_bt_testcomm(uint32_t baudrate, uint8_t parity) { uint8_t data[PM3_CMD_DATA_SIZE] = {0x00}; size_t len = 0; - PrintAndLogEx(SUCCESS, "TX (%3u):%.*s at %u 8%c1", strlen(string), strlen(string), string, baudrate, parity); + PrintAndLogEx(SUCCESS, "TX (%3zu):%.*s at %u 8%c1", strlen(string), (int)strlen(string), string, baudrate, parity); ret = usart_txrx((uint8_t *)string, strlen(string), data, &len, 1000); // such large timeout needed if (ret == PM3_SUCCESS) { - PrintAndLogEx(SUCCESS, "RX (%3u):%.*s", len, len, data); + PrintAndLogEx(SUCCESS, "RX (%3zu):%.*s", len, (int)len, data); if (strcmp((char *)data, "hc01.comV2.0") == 0) { - PrintAndLogEx(SUCCESS, "Add-on " _GREEN_("found!"), len, len, data); + PrintAndLogEx(SUCCESS, "Add-on " _GREEN_("found!")); return PM3_SUCCESS; } } @@ -365,11 +365,11 @@ static int CmdUsartBtFactory(const char *Cmd) { memset(data, 0, sizeof(data)); string = "AT+NAMEPM3_RDV4.0"; - PrintAndLogEx(SUCCESS, "TX (%3u):%.*s", strlen(string), strlen(string), string); + PrintAndLogEx(SUCCESS, "TX (%3zu):%.*s", strlen(string), (int)strlen(string), string); int ret = usart_txrx((uint8_t *)string, strlen(string), data, &len, 1000); if (ret == PM3_SUCCESS) { - PrintAndLogEx(SUCCESS, "RX (%3u):%.*s", len, len, data); + PrintAndLogEx(SUCCESS, "RX (%3zu):%.*s", len, (int)len, data); if (strcmp((char *)data, "OKsetname") == 0) { PrintAndLogEx(SUCCESS, "Name set to " _GREEN_("PM3_RDV4.0")); } else { @@ -383,11 +383,11 @@ static int CmdUsartBtFactory(const char *Cmd) { memset(data, 0, sizeof(data)); len = 0; string = "AT+ROLE=S"; - PrintAndLogEx(SUCCESS, "TX (%3u):%.*s", strlen(string), strlen(string), string); + PrintAndLogEx(SUCCESS, "TX (%3zu):%.*s", strlen(string), (int)strlen(string), string); ret = usart_txrx((uint8_t *)string, strlen(string), data, &len, 1000); if (ret == PM3_SUCCESS) { - PrintAndLogEx(SUCCESS, "RX (%3u):%.*s", len, len, data); + PrintAndLogEx(SUCCESS, "RX (%3zu):%.*s", len, (int)len, data); if (strcmp((char *)data, "OK+ROLE:S") == 0) { PrintAndLogEx(SUCCESS, "Role set to " _GREEN_("Slave")); } else { @@ -401,11 +401,11 @@ static int CmdUsartBtFactory(const char *Cmd) { memset(data, 0, sizeof(data)); len = 0; string = "AT+PIN1234"; - PrintAndLogEx(SUCCESS, "TX (%3u):%.*s", strlen(string), strlen(string), string); + PrintAndLogEx(SUCCESS, "TX (%3zu):%.*s", strlen(string), (int)strlen(string), string); ret = usart_txrx((uint8_t *)string, strlen(string), data, &len, 1000); if (ret == PM3_SUCCESS) { - PrintAndLogEx(SUCCESS, "RX (%3u):%.*s", len, len, data); + PrintAndLogEx(SUCCESS, "RX (%3zu):%.*s", len, (int)len, data); if (strcmp((char *)data, "OKsetPIN") == 0) { PrintAndLogEx(SUCCESS, "PIN set to " _GREEN_("1234")); } else { @@ -421,11 +421,11 @@ static int CmdUsartBtFactory(const char *Cmd) { memset(data, 0, sizeof(data)); len = 0; string = "AT+PN"; - PrintAndLogEx(SUCCESS, "TX (%3u):%.*s", strlen(string), strlen(string), string); + PrintAndLogEx(SUCCESS, "TX (%3zu):%.*s", strlen(string), (int)strlen(string), string); ret = usart_txrx((uint8_t *)string, strlen(string), data, &len, 1000); if (ret == PM3_SUCCESS) { - PrintAndLogEx(SUCCESS, "RX (%3u):%.*s", len, len, data); + PrintAndLogEx(SUCCESS, "RX (%3zu):%.*s", len, (int)len, data); if (strcmp((char *)data, "OK None") == 0) { PrintAndLogEx(SUCCESS, "Parity set to " _GREEN_("None")); } else { @@ -441,11 +441,11 @@ static int CmdUsartBtFactory(const char *Cmd) { memset(data, 0, sizeof(data)); len = 0; string = BTADDON_BAUD_AT; - PrintAndLogEx(SUCCESS, "TX (%3u):%.*s", strlen(string), strlen(string), string); + PrintAndLogEx(SUCCESS, "TX (%3zu):%.*s", strlen(string), (int)strlen(string), string); ret = usart_txrx((uint8_t *)string, strlen(string), data, &len, 1000); if (ret == PM3_SUCCESS) { - PrintAndLogEx(SUCCESS, "RX (%3u):%.*s", len, len, data); + PrintAndLogEx(SUCCESS, "RX (%3zu):%.*s", len, (int)len, data); if (strcmp((char *)data, "OK" BTADDON_BAUD_NUM) == 0) { PrintAndLogEx(SUCCESS, "Baudrate set to " _GREEN_(BTADDON_BAUD_NUM)); } else { @@ -514,7 +514,7 @@ static int CmdUsartBtPin(const char *Cmd) { sprintf(string, "AT+PIN%s", pin); uint8_t data[PM3_CMD_DATA_SIZE] = {0x00}; size_t len = 0; -// PrintAndLogEx(NORMAL, "TX (%3u):%.*s", strlen(string), strlen(string), string); +// PrintAndLogEx(NORMAL, "TX (%3zu):%.*s", strlen(string), (int)strlen(string), string); int ret = usart_txrx((uint8_t *)string, strlen(string), data, &len, 600); if (ret == PM3_ENODATA) { PrintAndLogEx(FAILED, "No response from add-on, is it ON and blinking?"); @@ -524,7 +524,7 @@ static int CmdUsartBtPin(const char *Cmd) { PrintAndLogEx(FAILED, "Command failed, ret=%i", ret); return ret; } -// PrintAndLogEx(NORMAL, "RX (%3u):%.*s", len, len, data); +// PrintAndLogEx(NORMAL, "RX (%3zu):%.*s", len, (int)len, data); if (strcmp((char *)data, "OKsetPIN") == 0) { PrintAndLogEx(NORMAL, "PIN changed " _GREEN_("successfully")); } else { @@ -688,11 +688,11 @@ static int CmdUsartTXRX(const char *Cmd) { } uint8_t data[PM3_CMD_DATA_SIZE] = {0x00}; size_t len = 0; - PrintAndLogEx(NORMAL, "TX (%3u):%.*s", strlen(string2), strlen(string2), string2); + PrintAndLogEx(NORMAL, "TX (%3zu):%.*s", strlen(string2), (int)strlen(string2), string2); int ret = usart_txrx((uint8_t *)string2, strlen(string2), data, &len, waittime); if (ret != PM3_SUCCESS) return ret; - PrintAndLogEx(NORMAL, "RX (%3u):%.*s", len, len, data); + PrintAndLogEx(NORMAL, "RX (%3zu):%.*s", len, (int)len, data); return PM3_SUCCESS; } diff --git a/client/comms.c b/client/comms.c index f3dbf09ce..bdb6e5ab1 100644 --- a/client/comms.c +++ b/client/comms.c @@ -123,7 +123,7 @@ static void SendCommandNG_internal(uint16_t cmd, uint8_t *data, size_t len, bool return; } if (len > PM3_CMD_DATA_SIZE) { - PrintAndLogEx(WARNING, "Sending %d bytes of payload is too much, abort", len); + PrintAndLogEx(WARNING, "Sending %zu bytes of payload is too much, abort", len); return; } @@ -183,7 +183,7 @@ void SendCommandNG(uint16_t cmd, uint8_t *data, size_t len) { void SendCommandMIX(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len) { uint64_t arg[3] = {arg0, arg1, arg2}; if (len > PM3_CMD_DATA_SIZE_MIX) { - PrintAndLogEx(WARNING, "Sending %d bytes of payload is too much for MIX frames, abort", len); + PrintAndLogEx(WARNING, "Sending %zu bytes of payload is too much for MIX frames, abort", len); return; } uint8_t cmddata[PM3_CMD_DATA_SIZE]; @@ -434,7 +434,7 @@ __attribute__((force_align_arg_pointer)) res = uart_receive(sp, ((uint8_t *)&rx_old) + sizeof(PacketResponseNGPreamble), sizeof(PacketResponseOLD) - sizeof(PacketResponseNGPreamble), &rxlen); if ((res != PM3_SUCCESS) || (rxlen != sizeof(PacketResponseOLD) - sizeof(PacketResponseNGPreamble))) { - PrintAndLogEx(WARNING, "Received packet OLD frame with payload too short? %d/%d", rxlen, sizeof(PacketResponseOLD) - sizeof(PacketResponseNGPreamble)); + PrintAndLogEx(WARNING, "Received packet OLD frame with payload too short? %d/%zu", rxlen, sizeof(PacketResponseOLD) - sizeof(PacketResponseNGPreamble)); error = true; } if (!error) { @@ -464,7 +464,7 @@ __attribute__((force_align_arg_pointer)) } } else { if (rxlen > 0) { - PrintAndLogEx(WARNING, "Received packet frame preamble too short: %d/%d", rxlen, sizeof(PacketResponseNGPreamble)); + PrintAndLogEx(WARNING, "Received packet frame preamble too short: %d/%zu", rxlen, sizeof(PacketResponseNGPreamble)); error = true; } if (res == PM3_ENOTTY) { diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c index d45181060..cead47287 100644 --- a/client/emv/cmdemv.c +++ b/client/emv/cmdemv.c @@ -301,7 +301,7 @@ static int CmdEMVGPO(const char *Cmd) { free(pdol_data_tlv); return PM3_ESOFT; } - PrintAndLogEx(INFO, "PDOL data[%d]: %s", pdol_data_tlv_data_len, sprint_hex(pdol_data_tlv_data, pdol_data_tlv_data_len)); + PrintAndLogEx(INFO, "PDOL data[%zu]: %s", pdol_data_tlv_data_len, sprint_hex(pdol_data_tlv_data, pdol_data_tlv_data_len)); // exec uint8_t buf[APDU_RES_LEN] = {0}; @@ -477,7 +477,7 @@ static int CmdEMVAC(const char *Cmd) { cdol_data_tlv = &data_tlv; } - PrintAndLogEx(INFO, "CDOL data[%d]: %s", cdol_data_tlv->len, sprint_hex(cdol_data_tlv->value, cdol_data_tlv->len)); + PrintAndLogEx(INFO, "CDOL data[%zu]: %s", cdol_data_tlv->len, sprint_hex(cdol_data_tlv->value, cdol_data_tlv->len)); // exec uint8_t buf[APDU_RES_LEN] = {0}; @@ -543,7 +543,7 @@ static int CmdEMVGenerateChallenge(const char *Cmd) { PrintAndLogEx(SUCCESS, "Challenge: %s", sprint_hex(buf, len)); if (len != 4 && len != 8) - PrintAndLogEx(WARNING, "Length of challenge must be 4 or 8, but it %d", len); + PrintAndLogEx(WARNING, "Length of challenge must be 4 or 8, but it %zu", len); return PM3_SUCCESS; } @@ -624,7 +624,7 @@ static int CmdEMVInternalAuthenticate(const char *Cmd) { ddol_data_tlv = &data_tlv; } - PrintAndLogEx(INFO, "DDOL data[%d]: %s", ddol_data_tlv->len, sprint_hex(ddol_data_tlv->value, ddol_data_tlv->len)); + PrintAndLogEx(INFO, "DDOL data[%zu]: %s", ddol_data_tlv->len, sprint_hex(ddol_data_tlv->value, ddol_data_tlv->len)); // exec uint8_t buf[APDU_RES_LEN] = {0}; @@ -693,7 +693,7 @@ static void ProcessGPOResponseFormat1(struct tlvdb *tlvRoot, uint8_t *buf, size_ } if (len < 4 || (len - 4) % 4) { - PrintAndLogEx(ERR, "GPO response format 1 parsing error. length = %d", len); + PrintAndLogEx(ERR, "GPO response format 1 parsing error. length = %zu", len); } else { // AIP struct tlvdb *f1AIP = tlvdb_fixed(0x82, 2, buf + 2); @@ -725,7 +725,7 @@ static void ProcessACResponseFormat1(struct tlvdb *tlvRoot, uint8_t *buf, size_t uint8_t elmlen = len - 2; // wo 0x80XX if (len < 4 + 2 || (elmlen - 2) % 4 || elmlen != buf[1]) { - PrintAndLogEx(ERR, "GPO response format1 parsing error. length=%d", len); + PrintAndLogEx(ERR, "GPO response format1 parsing error. length=%zu", len); } else { struct tlvdb *tlvElm = NULL; if (decodeTLV) @@ -907,7 +907,7 @@ static int CmdEMVExec(const char *Cmd) { PrintAndLogEx(ERR, "Error: can't create PDOL data."); dreturn(PM3_ESOFT); } - PrintAndLogEx(NORMAL, "PDOL data[%d]: %s", pdol_data_tlv_data_len, sprint_hex(pdol_data_tlv_data, pdol_data_tlv_data_len)); + PrintAndLogEx(NORMAL, "PDOL data[%zu]: %s", pdol_data_tlv_data_len, sprint_hex(pdol_data_tlv_data, pdol_data_tlv_data_len)); PrintAndLogEx(NORMAL, "\n* GPO."); res = EMVGPO(channel, true, pdol_data_tlv_data, pdol_data_tlv_data_len, buf, sizeof(buf), &len, &sw, tlvRoot); @@ -947,7 +947,7 @@ static int CmdEMVExec(const char *Cmd) { while (AFL && AFL->len) { if (AFL->len % 4) { - PrintAndLogEx(WARNING, "Warning: Wrong AFL length: %d", AFL->len); + PrintAndLogEx(WARNING, "Warning: Wrong AFL length: %zu", AFL->len); break; } @@ -1007,7 +1007,7 @@ static int CmdEMVExec(const char *Cmd) { if (ODAiListLen) { struct tlvdb *oda = tlvdb_fixed(0x21, ODAiListLen, ODAiList); // not a standard tag tlvdb_add(tlvRoot, oda); - PrintAndLogEx(NORMAL, "* Input list for Offline Data Authentication added to TLV. len=%d \n", ODAiListLen); + PrintAndLogEx(NORMAL, "* Input list for Offline Data Authentication added to TLV. len=%zu \n", ODAiListLen); } // get AIP @@ -1058,7 +1058,7 @@ static int CmdEMVExec(const char *Cmd) { if (IAD->len >= IAD->value[0] + 1) { PrintAndLogEx(NORMAL, "\tKey index: 0x%02x", IAD->value[1]); PrintAndLogEx(NORMAL, "\tCrypto ver: 0x%02x(%03d)", IAD->value[2], IAD->value[2]); - PrintAndLogEx(NORMAL, "\tCVR:", sprint_hex(&IAD->value[3], IAD->value[0] - 2)); + PrintAndLogEx(NORMAL, "\tCVR: %s", sprint_hex(&IAD->value[3], IAD->value[0] - 2)); struct tlvdb *cvr = tlvdb_fixed(0x20, IAD->value[0] - 2, &IAD->value[3]); TLVPrintFromTLVLev(cvr, 1); } @@ -1085,7 +1085,7 @@ static int CmdEMVExec(const char *Cmd) { dreturn(PM3_ERFTRANS); } if (len < 4) { - PrintAndLogEx(ERR, "Error GetChallenge. Wrong challenge length %d", len); + PrintAndLogEx(ERR, "Error GetChallenge. Wrong challenge length %zu", len); dreturn(PM3_ESOFT); } @@ -1104,7 +1104,7 @@ static int CmdEMVExec(const char *Cmd) { dreturn(PM3_ESOFT); } - PrintAndLogEx(NORMAL, "CDOL1 data[%d]: %s", cdol_data_tlv->len, sprint_hex(cdol_data_tlv->value, cdol_data_tlv->len)); + PrintAndLogEx(NORMAL, "CDOL1 data[%zu]: %s", cdol_data_tlv->len, sprint_hex(cdol_data_tlv->value, cdol_data_tlv->len)); PrintAndLogEx(NORMAL, "* * AC1"); // EMVAC_TC + EMVAC_CDAREQ --- to get SDAD @@ -1151,7 +1151,7 @@ static int CmdEMVExec(const char *Cmd) { break; } } else { - PrintAndLogEx(WARNING, "Warning: Wrong CID length %d", CID->len); + PrintAndLogEx(WARNING, "Warning: Wrong CID length %zu", CID->len); } } else { PrintAndLogEx(WARNING, "Warning: CID(9F27) not found."); @@ -1194,7 +1194,7 @@ static int CmdEMVExec(const char *Cmd) { dreturn(PM3_ESOFT); } - PrintAndLogEx(NORMAL, "UDOL data[%d]: %s", udol_data_tlv->len, sprint_hex(udol_data_tlv->value, udol_data_tlv->len)); + PrintAndLogEx(NORMAL, "UDOL data[%zu]: %s", udol_data_tlv->len, sprint_hex(udol_data_tlv->value, udol_data_tlv->len)); PrintAndLogEx(NORMAL, "\n* Mastercard compute cryptographic checksum(UDOL)"); @@ -1228,7 +1228,7 @@ static int CmdEMVExec(const char *Cmd) { dreturn(PM3_ESOFT); } - PrintAndLogEx(NORMAL, "CDOL1 data[%d]: %s", cdol1_data_tlv->len, sprint_hex(cdol1_data_tlv->value, cdol1_data_tlv->len)); + PrintAndLogEx(NORMAL, "CDOL1 data[%zu]: %s", cdol1_data_tlv->len, sprint_hex(cdol1_data_tlv->value, cdol1_data_tlv->len)); PrintAndLogEx(NORMAL, "* * AC1"); // EMVAC_TC + EMVAC_CDAREQ --- to get SDAD @@ -1260,7 +1260,7 @@ static int CmdEMVExec(const char *Cmd) { PrintAndLogEx(NORMAL, "\n* * Issuer Application Data (IAD):"); uint8_t VDDlen = IAD->value[0]; // Visa discretionary data length uint8_t IDDlen = 0; // Issuer discretionary data length - PrintAndLogEx(NORMAL, "IAD length: %d", IAD->len); + PrintAndLogEx(NORMAL, "IAD length: %zu", IAD->len); PrintAndLogEx(NORMAL, "VDDlen: %d", VDDlen); if (VDDlen < IAD->len - 1) IDDlen = IAD->value[VDDlen + 1]; @@ -1331,7 +1331,7 @@ static int CmdEMVExec(const char *Cmd) { dreturn(PM3_ESOFT); } - PrintAndLogEx(NORMAL, "CDOL2 data[%d]: %s", cdol2_data_tlv->len, sprint_hex(cdol2_data_tlv->value, cdol2_data_tlv->len)); + PrintAndLogEx(NORMAL, "CDOL2 data[%zu]: %s", cdol2_data_tlv->len, sprint_hex(cdol2_data_tlv->value, cdol2_data_tlv->len)); //PrintAndLogEx(NORMAL, "* * AC2"); // here must be AC2, but we dont make external authenticate ( /* // AC2 @@ -1590,7 +1590,7 @@ static int CmdEMVScan(const char *Cmd) { DropFieldEx(channel); return PM3_ESOFT; } - PrintAndLogEx(INFO, "PDOL data[%d]: %s", pdol_data_tlv_data_len, sprint_hex(pdol_data_tlv_data, pdol_data_tlv_data_len)); + PrintAndLogEx(INFO, "PDOL data[%zu]: %s", pdol_data_tlv_data_len, sprint_hex(pdol_data_tlv_data, pdol_data_tlv_data_len)); PrintAndLogEx(INFO, "-->GPO."); res = EMVGPO(channel, true, pdol_data_tlv_data, pdol_data_tlv_data_len, buf, sizeof(buf), &len, &sw, tlvRoot); @@ -1622,7 +1622,7 @@ static int CmdEMVScan(const char *Cmd) { while (AFL && AFL->len) { if (AFL->len % 4) { - PrintAndLogEx(ERR, "Wrong AFL length: %d", AFL->len); + PrintAndLogEx(ERR, "Wrong AFL length: %zu", AFL->len); break; } @@ -1850,7 +1850,7 @@ static int CmdEMVRoca(const char *Cmd) { free(pdol_data_tlv); return PM3_ESOFT; } - PrintAndLogEx(INFO, "PDOL data[%d]: %s", pdol_data_tlv_data_len, sprint_hex(pdol_data_tlv_data, pdol_data_tlv_data_len)); + PrintAndLogEx(INFO, "PDOL data[%zu]: %s", pdol_data_tlv_data_len, sprint_hex(pdol_data_tlv_data, pdol_data_tlv_data_len)); PrintAndLogEx(INFO, "-->GPO."); res = EMVGPO(channel, true, pdol_data_tlv_data, pdol_data_tlv_data_len, buf, sizeof(buf), &len, &sw, tlvRoot); @@ -1871,7 +1871,7 @@ static int CmdEMVRoca(const char *Cmd) { while (AFL && AFL->len) { if (AFL->len % 4) { - PrintAndLogEx(ERR, "Wrong AFL length: %d", AFL->len); + PrintAndLogEx(ERR, "Wrong AFL length: %zu", AFL->len); break; } diff --git a/client/emv/emvcore.c b/client/emv/emvcore.c index d2053495e..8c9b2ea1e 100644 --- a/client/emv/emvcore.c +++ b/client/emv/emvcore.c @@ -495,7 +495,7 @@ int EMVSearchPSE(EMVCommandChannel channel, bool ActivateField, bool LeaveFieldO if (tsfi) { struct tlvdb *tsfitmp = tlvdb_find_path(tsfi, (tlv_tag_t[]) {0x70, 0x61, 0x00}); if (!tsfitmp) { - PrintAndLogEx(FAILED, "SFI 0x%02d doesn't have any records.", sfidatalen[ui]); + PrintAndLogEx(FAILED, "SFI 0x%02zu doesn't have any records.", sfidatalen[ui]); continue; } res = EMVCheckAID(channel, decodeTLV, tsfitmp, tlv); @@ -863,7 +863,7 @@ int trDDA(EMVCommandChannel channel, bool decodeTLV, struct tlvdb *tlv) { return 5; } - PrintAndLogEx(NORMAL, "DDOL data[%d]: %s", ddol_data_tlv->len, sprint_hex(ddol_data_tlv->value, ddol_data_tlv->len)); + PrintAndLogEx(NORMAL, "DDOL data[%zu]: %s", ddol_data_tlv->len, sprint_hex(ddol_data_tlv->value, ddol_data_tlv->len)); PrintAndLogEx(NORMAL, "\n* Internal Authenticate"); int res = EMVInternalAuthenticate(channel, true, (uint8_t *)ddol_data_tlv->value, ddol_data_tlv->len, buf, sizeof(buf), &len, &sw, NULL); @@ -879,7 +879,7 @@ int trDDA(EMVCommandChannel channel, bool decodeTLV, struct tlvdb *tlv) { struct tlvdb *dda_db = NULL; if (buf[0] == 0x80) { if (len < 3) { - PrintAndLogEx(WARNING, "Warning: Internal Authenticate format1 parsing error. length=%d", len); + PrintAndLogEx(WARNING, "Warning: Internal Authenticate format1 parsing error. length=%zu", len); } else { // parse response 0x80 struct tlvdb *t80 = tlvdb_parse_multi(buf, len); diff --git a/client/emv/emvjson.c b/client/emv/emvjson.c index 785b6b8e7..e1fd9111c 100644 --- a/client/emv/emvjson.c +++ b/client/emv/emvjson.c @@ -255,7 +255,7 @@ static bool HexToBuffer(const char *errormsg, const char *hexvalue, uint8_t *buf } if (buflen > maxbufferlen) { - PrintAndLogEx(ERR, "%s HEX length (%d) more than %d", errormsg, (bufferlen) ? *bufferlen : -1, maxbufferlen); + PrintAndLogEx(ERR, "%s HEX length (%zu) more than %zu", errormsg, (bufferlen) ? *bufferlen : -1, maxbufferlen); return false; } @@ -321,7 +321,7 @@ bool ParamLoadFromJson(struct tlvdb *tlv) { return false; } - PrintAndLogEx(SUCCESS, "Load params: json(%d) " _GREEN_("OK"), json_array_size(root)); + PrintAndLogEx(SUCCESS, "Load params: json(%zu) " _GREEN_("OK"), json_array_size(root)); for (int i = 0; i < json_array_size(root); i++) { json_t *data, *jtag, *jlength, *jvalue; @@ -382,7 +382,7 @@ bool ParamLoadFromJson(struct tlvdb *tlv) { } if (buflen != tlvLength) { - PrintAndLogEx(ERR, "Load params: data [%d] length of HEX must(%d) be identical to length in TLV param(%d)", i + 1, buflen, tlvLength); + PrintAndLogEx(ERR, "Load params: data [%d] length of HEX must(%zu) be identical to length in TLV param(%d)", i + 1, buflen, tlvLength); json_decref(root); return false; } diff --git a/client/fido/cose.c b/client/fido/cose.c index f6f20852b..0812288e3 100644 --- a/client/fido/cose.c +++ b/client/fido/cose.c @@ -206,7 +206,7 @@ int COSEGetECDSAKey(uint8_t *data, size_t datalen, bool verbose, uint8_t *public res = CborGetBinStringValue(&map, &public_key[1], 32, &len); cbor_check(res); if (verbose) - PrintAndLogEx(SUCCESS, "x - coordinate [%d]: %s", len, sprint_hex(&public_key[1], 32)); + PrintAndLogEx(SUCCESS, "x - coordinate [%zu]: %s", len, sprint_hex(&public_key[1], 32)); if (len != 32) PrintAndLogEx(ERR, "ERROR: x - coordinate length must be 32."); } @@ -217,7 +217,7 @@ int COSEGetECDSAKey(uint8_t *data, size_t datalen, bool verbose, uint8_t *public res = CborGetBinStringValue(&map, &public_key[33], 32, &len); cbor_check(res); if (verbose) - PrintAndLogEx(SUCCESS, "y - coordinate [%d]: %s", len, sprint_hex(&public_key[33], 32)); + PrintAndLogEx(SUCCESS, "y - coordinate [%zu]: %s", len, sprint_hex(&public_key[33], 32)); if (len != 32) PrintAndLogEx(ERR, "ERROR: y - coordinate length must be 32."); } @@ -229,7 +229,7 @@ int COSEGetECDSAKey(uint8_t *data, size_t datalen, bool verbose, uint8_t *public res = CborGetBinStringValue(&map, private_key, sizeof(private_key), &len); cbor_check(res); if (verbose) - PrintAndLogEx(SUCCESS, "d - private key [%d]: %s", len, sprint_hex(private_key, len)); + PrintAndLogEx(SUCCESS, "d - private key [%zu]: %s", len, sprint_hex(private_key, len)); } if (verbose) diff --git a/client/fido/fidocore.c b/client/fido/fidocore.c index 8093f45c8..1a680ed88 100644 --- a/client/fido/fidocore.c +++ b/client/fido/fidocore.c @@ -434,9 +434,9 @@ int FIDO2MakeCredentionalParseRes(json_t *root, uint8_t *data, size_t dataLen, b memcpy(authData, ubuf, authDataLen); if (verbose2) { - PrintAndLogEx(INFO, "authData[%d]: %s", n, sprint_hex_inrow(authData, authDataLen)); + PrintAndLogEx(INFO, "authData[%zu]: %s", n, sprint_hex_inrow(authData, authDataLen)); } else { - PrintAndLogEx(INFO, "authData[%d]: %s...", n, sprint_hex(authData, MIN(authDataLen, 16))); + PrintAndLogEx(INFO, "authData[%zu]: %s...", n, sprint_hex(authData, MIN(authDataLen, 16))); } PrintAndLogEx(INFO, "RP ID Hash: %s", sprint_hex(ubuf, 32)); @@ -530,9 +530,9 @@ int FIDO2MakeCredentionalParseRes(json_t *root, uint8_t *data, size_t dataLen, b res = CborGetBinStringValue(&mapsmt, sign, sizeof(sign), &signLen); cbor_check(res); if (verbose2) { - PrintAndLogEx(INFO, "signature [%d]: %s", signLen, sprint_hex_inrow(sign, signLen)); + PrintAndLogEx(INFO, "signature [%zu]: %s", signLen, sprint_hex_inrow(sign, signLen)); } else { - PrintAndLogEx(INFO, "signature [%d]: %s...", signLen, sprint_hex(sign, MIN(signLen, 16))); + PrintAndLogEx(INFO, "signature [%zu]: %s...", signLen, sprint_hex(sign, MIN(signLen, 16))); } } @@ -540,11 +540,11 @@ int FIDO2MakeCredentionalParseRes(json_t *root, uint8_t *data, size_t dataLen, b res = CborGetArrayBinStringValue(&mapsmt, der, sizeof(der), &derLen); cbor_check(res); if (verbose2) { - PrintAndLogEx(NORMAL, "DER certificate[%d]:\n------------------DER-------------------", derLen); + PrintAndLogEx(NORMAL, "DER certificate[%zu]:\n------------------DER-------------------", derLen); dump_buffer_simple((const unsigned char *)der, derLen, NULL); PrintAndLogEx(NORMAL, "\n----------------DER---------------------"); } else { - PrintAndLogEx(NORMAL, "DER [%d]: %s...", derLen, sprint_hex(der, MIN(derLen, 16))); + PrintAndLogEx(NORMAL, "DER [%zu]: %s...", derLen, sprint_hex(der, MIN(derLen, 16))); } JsonSaveBufAsHexCompact(root, "$.AppData.DER", der, derLen); } @@ -674,7 +674,7 @@ int FIDO2GetAssertionParseRes(json_t *root, uint8_t *data, size_t dataLen, bool uint8_t cid[200] = {0}; res = CborGetBinStringValue(&mapint, cid, sizeof(cid), &n); cbor_check(res); - PrintAndLogEx(SUCCESS, "credential id [%d]: %s", n, sprint_hex(cid, n)); + PrintAndLogEx(SUCCESS, "credential id [%zu]: %s", n, sprint_hex(cid, n)); } } res = cbor_value_leave_container(&map, &mapint); @@ -693,9 +693,9 @@ int FIDO2GetAssertionParseRes(json_t *root, uint8_t *data, size_t dataLen, bool memcpy(authData, ubuf, authDataLen); if (verbose2) { - PrintAndLogEx(INFO, "authData[%d]: %s", n, sprint_hex_inrow(authData, authDataLen)); + PrintAndLogEx(INFO, "authData[%zu]: %s", n, sprint_hex_inrow(authData, authDataLen)); } else { - PrintAndLogEx(INFO, "authData[%d]: %s...", n, sprint_hex(authData, MIN(authDataLen, 16))); + PrintAndLogEx(INFO, "authData[%zu]: %s...", n, sprint_hex(authData, MIN(authDataLen, 16))); } PrintAndLogEx(INFO, "RP ID Hash: %s", sprint_hex(ubuf, 32)); @@ -749,7 +749,7 @@ int FIDO2GetAssertionParseRes(json_t *root, uint8_t *data, size_t dataLen, bool uint8_t cid[200] = {0}; res = CborGetBinStringValue(&mapint, cid, sizeof(cid), &n); cbor_check(res); - PrintAndLogEx(SUCCESS, "UserEntity id [%d]: %s", n, sprint_hex(cid, n)); + PrintAndLogEx(SUCCESS, "UserEntity id [%zu]: %s", n, sprint_hex(cid, n)); // check uint8_t idbuf[100] = {0}; @@ -781,9 +781,9 @@ int FIDO2GetAssertionParseRes(json_t *root, uint8_t *data, size_t dataLen, bool cbor_check(res); if (verbose2) { - PrintAndLogEx(SUCCESS, "signature [%d]: %s", signLen, sprint_hex_inrow(sign, signLen)); + PrintAndLogEx(SUCCESS, "signature [%zu]: %s", signLen, sprint_hex_inrow(sign, signLen)); } else { - PrintAndLogEx(SUCCESS, "signature [%d]: %s...", signLen, sprint_hex(sign, MIN(signLen, 16))); + PrintAndLogEx(SUCCESS, "signature [%zu]: %s...", signLen, sprint_hex(sign, MIN(signLen, 16))); } // get public key from json diff --git a/client/fileutils.c b/client/fileutils.c index 6efe4c17b..79906020e 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -153,7 +153,7 @@ int saveFile(const char *preferredName, const char *suffix, const void *data, si fwrite(data, 1, datalen, f); fflush(f); fclose(f); - PrintAndLogEx(SUCCESS, "saved %u bytes to binary file " _YELLOW_("%s"), datalen, fileName); + PrintAndLogEx(SUCCESS, "saved %zu bytes to binary file " _YELLOW_("%s"), datalen, fileName); free(fileName); return PM3_SUCCESS; } @@ -420,14 +420,14 @@ int loadFile(const char *preferredName, const char *suffix, void *data, size_t m } if (bytes_read > maxdatalen) { - PrintAndLogEx(WARNING, "Warning, bytes read exceed calling array limit. Max bytes is %d bytes", maxdatalen); + PrintAndLogEx(WARNING, "Warning, bytes read exceed calling array limit. Max bytes is %zu bytes", maxdatalen); bytes_read = maxdatalen; } memcpy((data), dump, bytes_read); free(dump); - PrintAndLogEx(SUCCESS, "loaded %d bytes from binary file " _YELLOW_("%s"), bytes_read, fileName); + PrintAndLogEx(SUCCESS, "loaded %zu bytes from binary file " _YELLOW_("%s"), bytes_read, fileName); *datalen = bytes_read; @@ -483,7 +483,7 @@ int loadFile_safe(const char *preferredName, const char *suffix, void **pdata, s *datalen = bytes_read; - PrintAndLogEx(SUCCESS, "loaded %d bytes from binary file " _YELLOW_("%s"), bytes_read, preferredName); + PrintAndLogEx(SUCCESS, "loaded %zu bytes from binary file " _YELLOW_("%s"), bytes_read, preferredName); return retval; } @@ -531,7 +531,7 @@ int loadFileEML(const char *preferredName, void *data, size_t *datalen) { } } fclose(f); - PrintAndLogEx(SUCCESS, "loaded %d bytes from text file " _YELLOW_("%s"), counter, fileName); + PrintAndLogEx(SUCCESS, "loaded %zu bytes from text file " _YELLOW_("%s"), counter, fileName); if (datalen) *datalen = counter; diff --git a/client/mifare/mifarehost.c b/client/mifare/mifarehost.c index 42fef7405..d61201662 100644 --- a/client/mifare/mifarehost.c +++ b/client/mifare/mifarehost.c @@ -1005,7 +1005,7 @@ int detect_classic_prng(void) { // check respA if (respA.oldarg[0] != 4) { - PrintAndLogEx(ERR, "PRNG data error: Wrong length: %d", respA.oldarg[0]); + PrintAndLogEx(ERR, "PRNG data error: Wrong length: %"PRIu64, respA.oldarg[0]); return PM3_ESOFT; } diff --git a/client/mifare/ndef.c b/client/mifare/ndef.c index 95c66bd72..f4575c893 100644 --- a/client/mifare/ndef.c +++ b/client/mifare/ndef.c @@ -143,11 +143,11 @@ static int ndefPrintHeader(NDEFHeader_t *header) { PrintAndLogEx(NORMAL, "\tID Len Present: %s", STRBOOL(header->IDLenPresent)); PrintAndLogEx(NORMAL, "\tType Name Format: [0x%02x] %s", header->TypeNameFormat, TypeNameFormat_s[header->TypeNameFormat]); - PrintAndLogEx(NORMAL, "\tHeader length : %d", header->len); - PrintAndLogEx(NORMAL, "\tType length : %d", header->TypeLen); - PrintAndLogEx(NORMAL, "\tPayload length : %d", header->PayloadLen); - PrintAndLogEx(NORMAL, "\tID length : %d", header->IDLen); - PrintAndLogEx(NORMAL, "\tRecord length : %d", header->RecLen); + PrintAndLogEx(NORMAL, "\tHeader length : %zu", header->len); + PrintAndLogEx(NORMAL, "\tType length : %zu", header->TypeLen); + PrintAndLogEx(NORMAL, "\tPayload length : %zu", header->PayloadLen); + PrintAndLogEx(NORMAL, "\tID length : %zu", header->IDLen); + PrintAndLogEx(NORMAL, "\tRecord length : %zu", header->RecLen); return 0; } @@ -171,7 +171,7 @@ static int ndefDecodeSig(uint8_t *sig, size_t siglen) { // ecdsa 0x04 if (sigType == stECDSA) { indx += 3; - PrintAndLogEx(NORMAL, "\tsignature [%d]: %s", intsiglen, sprint_hex_inrow(&sig[indx], intsiglen)); + PrintAndLogEx(NORMAL, "\tsignature [%zu]: %s", intsiglen, sprint_hex_inrow(&sig[indx], intsiglen)); uint8_t rval[300] = {0}; uint8_t sval[300] = {0}; @@ -186,7 +186,7 @@ static int ndefDecodeSig(uint8_t *sig, size_t siglen) { if (sigURI) { size_t intsigurilen = (sig[indx] << 8) + sig[indx + 1]; indx += 2; - PrintAndLogEx(NORMAL, "\tsignature uri [%d]: %.*s", intsigurilen, intsigurilen, &sig[indx]); + PrintAndLogEx(NORMAL, "\tsignature uri [%zu]: %.*s", intsigurilen, intsigurilen, &sig[indx]); indx += intsigurilen; } @@ -203,7 +203,7 @@ static int ndefDecodeSig(uint8_t *sig, size_t siglen) { size_t intcertlen = (sig[indx + 1] << 8) + sig[indx + 2]; indx += 2; - PrintAndLogEx(NORMAL, "\tcertificate %d [%d]: %s", i + 1, intcertlen, sprint_hex_inrow(&sig[indx], intcertlen)); + PrintAndLogEx(NORMAL, "\tcertificate %d [%zu]: %s", i + 1, intcertlen, sprint_hex_inrow(&sig[indx], intcertlen)); indx += intcertlen; } @@ -211,7 +211,7 @@ static int ndefDecodeSig(uint8_t *sig, size_t siglen) { if ((indx <= siglen) && certURI) { size_t inturilen = (sig[indx] << 8) + sig[indx + 1]; indx += 2; - PrintAndLogEx(NORMAL, "\tcertificate uri [%d]: %.*s", inturilen, inturilen, &sig[indx]); + PrintAndLogEx(NORMAL, "\tcertificate uri [%zu]: %.*s", inturilen, inturilen, &sig[indx]); } return 0; @@ -222,17 +222,17 @@ static int ndefDecodePayload(NDEFHeader_t *ndef) { switch (ndef->TypeNameFormat) { case tnfWellKnownRecord: PrintAndLogEx(INFO, "Well Known Record"); - PrintAndLogEx(NORMAL, "\ttype: %.*s", ndef->TypeLen, ndef->Type); + PrintAndLogEx(NORMAL, "\ttype: %.*s", (int)ndef->TypeLen, ndef->Type); if (!strncmp((char *)ndef->Type, "T", ndef->TypeLen)) { - PrintAndLogEx(NORMAL, "\ttext : %.*s", ndef->PayloadLen, ndef->Payload); + PrintAndLogEx(NORMAL, "\ttext : %.*s", (int)ndef->PayloadLen, ndef->Payload); } if (!strncmp((char *)ndef->Type, "U", ndef->TypeLen)) { PrintAndLogEx(NORMAL , "\turi : %s%.*s" , (ndef->Payload[0] <= 0x23 ? URI_s[ndef->Payload[0]] : "[err]") - , ndef->PayloadLen - 1 + , (int)(ndef->PayloadLen - 1) , &ndef->Payload[1] ); } @@ -244,8 +244,8 @@ static int ndefDecodePayload(NDEFHeader_t *ndef) { break; case tnfAbsoluteURIRecord: PrintAndLogEx(INFO, "Absolute URI Record"); - PrintAndLogEx(NORMAL, "\ttype: %.*s", ndef->TypeLen, ndef->Type); - PrintAndLogEx(NORMAL, "\tpayload: %.*s", ndef->PayloadLen, ndef->Payload); + PrintAndLogEx(NORMAL, "\ttype: %.*s", (int)ndef->TypeLen, ndef->Type); + PrintAndLogEx(NORMAL, "\tpayload: %.*s", (int)ndef->PayloadLen, ndef->Payload); break; case tnfEmptyRecord: case tnfMIMEMediaRecord: @@ -302,7 +302,7 @@ static int ndefRecordsDecodeAndPrint(uint8_t *ndefRecord, size_t ndefRecordLen) } if (NDEFHeader.MessageEnd && len + NDEFHeader.RecLen != ndefRecordLen) { - PrintAndLogEx(ERR, "NDEF records have wrong length. Must be %d, calculated %d", ndefRecordLen, len + NDEFHeader.RecLen); + PrintAndLogEx(ERR, "NDEF records have wrong length. Must be %zu, calculated %zu", ndefRecordLen, len + NDEFHeader.RecLen); return 1; } From 78c153fe74c33253b8e535d5e212162f5ee5b1e6 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 6 Oct 2019 00:17:32 +0200 Subject: [PATCH 0844/1854] fix wrong fix --- client/cmdtrace.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/cmdtrace.c b/client/cmdtrace.c index 7cf178bf0..836c0b9eb 100644 --- a/client/cmdtrace.c +++ b/client/cmdtrace.c @@ -665,7 +665,7 @@ static int CmdTraceLoad(const char *Cmd) { size_t bytes_read = fread(trace, 1, fsize, f); traceLen = bytes_read; fclose(f); - PrintAndLogEx(SUCCESS, "Recorded Activity (TraceLen = %l bytes) loaded from file %s", traceLen, filename); + PrintAndLogEx(SUCCESS, "Recorded Activity (TraceLen = %lu bytes) loaded from file %s", traceLen, filename); return 0; } @@ -815,7 +815,7 @@ int CmdTraceList(const char *Cmd) { } } - PrintAndLogEx(SUCCESS, "Recorded Activity (TraceLen = %l bytes)", traceLen); + PrintAndLogEx(SUCCESS, "Recorded Activity (TraceLen = %lu bytes)", traceLen); PrintAndLogEx(INFO, ""); if (protocol == FELICA) { printFelica(traceLen, trace); From 1f364106ce30f99d7b14df9bc7ab66fdd7fdb9ec Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 6 Oct 2019 01:18:04 +0200 Subject: [PATCH 0845/1854] fix few mem leaks --- client/cmdcrc.c | 2 ++ client/cmdhficlass.c | 2 ++ client/cmdhfmf.c | 5 ++++- client/cmdlfnoralsy.c | 3 ++- client/cmdlfpyramid.c | 4 +--- client/cmdlft55xx.c | 1 + client/cmdscript.c | 1 + client/comms.c | 3 ++- client/emv/cmdemv.c | 1 + client/fileutils.c | 17 +++++++++++------ client/graph.c | 3 +-- client/mifare/mifarehost.c | 1 + client/proxmark3.c | 2 +- client/scripting.c | 1 + 14 files changed, 31 insertions(+), 15 deletions(-) diff --git a/client/cmdcrc.c b/client/cmdcrc.c index 7f41b90e3..d51e18021 100644 --- a/client/cmdcrc.c +++ b/client/cmdcrc.c @@ -89,6 +89,8 @@ int GetModels(char *Models[], int *count, uint8_t *width) { memcpy(tmp, model.name, size); Models[mode] = tmp; width[mode] = plen(model.spoly); + } else { + free(tmp); } } mfree(&model); diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index a8526cbde..61710201e 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -757,6 +757,7 @@ static int CmdHFiClassELoad(const char *Cmd) { } default: PrintAndLogEx(ERR, "No dictionary loaded"); + free(dump); return PM3_ESOFT; } @@ -977,6 +978,7 @@ static int CmdHFiClassEncryptBlk(const char *Cmd) { return PM3_EINVARG; memcpy(key, keyptr, sizeof(key)); + free(keyptr); } iClassEncryptBlkData(blk_data, key); diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index a660ae1b3..8c7cfcee7 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -2607,7 +2607,10 @@ static int CmdHF14AMfChk(const char *Cmd) { if (param_getchar(Cmd, 0) == '*') { blockNo = 3; SectorsCnt = NumOfSectors(param_getchar(Cmd + 1, 0)); - if (SectorsCnt == 0) return usage_hf14_chk(); + if (SectorsCnt == 0) { + free(keyBlock); + return usage_hf14_chk(); + } } else { blockNo = param_get8(Cmd, 0); } diff --git a/client/cmdlfnoralsy.c b/client/cmdlfnoralsy.c index 207d6e4f8..ed6ff0e09 100644 --- a/client/cmdlfnoralsy.c +++ b/client/cmdlfnoralsy.c @@ -142,7 +142,6 @@ static int CmdNoralsyClone(const char *Cmd) { uint16_t year = 0; uint32_t id = 0; uint32_t blocks[4] = {T55x7_MODULATION_MANCHESTER | T55x7_BITRATE_RF_32 | T55x7_ST_TERMINATOR | 3 << T55x7_MAXBLOCK_SHIFT, 0, 0}; - uint8_t *bits = calloc(96, sizeof(uint8_t)); char cmdp = tolower(param_getchar(Cmd, 0)); if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_noralsy_clone(); @@ -154,8 +153,10 @@ static int CmdNoralsyClone(const char *Cmd) { if (tolower(param_getchar(Cmd, 2) == 'q')) blocks[0] = T5555_MODULATION_MANCHESTER | T5555_SET_BITRATE(32) | T5555_ST_TERMINATOR | 3 << T5555_MAXBLOCK_SHIFT; + uint8_t *bits = calloc(96, sizeof(uint8_t)); if (getnoralsyBits(id, year, bits) != PM3_SUCCESS) { PrintAndLogEx(ERR, "Error with tag bitstream generation."); + free(bits); return PM3_ESOFT; } diff --git a/client/cmdlfpyramid.c b/client/cmdlfpyramid.c index 0f21c7c33..d8c9511a6 100644 --- a/client/cmdlfpyramid.c +++ b/client/cmdlfpyramid.c @@ -217,16 +217,14 @@ static int CmdPyramidClone(const char *Cmd) { char cmdp = tolower(param_getchar(Cmd, 0)); if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_pyramid_clone(); - uint32_t facilitycode = 0, cardnumber = 0, fc = 0, cn = 0; + if (sscanf(Cmd, "%u %u", &fc, &cn) != 2) return usage_lf_pyramid_clone(); uint32_t blocks[5]; uint8_t *bs = calloc(128, sizeof(uint8_t)); if (bs == NULL) { return PM3_EMALLOC; } - if (sscanf(Cmd, "%u %u", &fc, &cn) != 2) return usage_lf_pyramid_clone(); - facilitycode = (fc & 0x000000FF); cardnumber = (cn & 0x0000FFFF); diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index eaa181aad..f00328fcd 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -2446,6 +2446,7 @@ static int CmdResetRead(const char *Cmd) { if (!GetFromDevice(BIG_BUF, got, sizeof(got), 0, NULL, 0, NULL, 2500, false)) { PrintAndLogEx(WARNING, "command execution time out"); + free(got); return PM3_ETIMEOUT; } setGraphBuf(got, sizeof(got)); diff --git a/client/cmdscript.c b/client/cmdscript.c index 6d7858d54..245ae61dc 100644 --- a/client/cmdscript.c +++ b/client/cmdscript.c @@ -60,6 +60,7 @@ static int CmdScriptRun(const char *Cmd) { int error; if (luascriptfile_idx == MAX_NESTED_LUASCRIPT) { PrintAndLogEx(ERR, "Too many nested scripts, skipping %s\n", script_path); + free(script_path); return PM3_EMALLOC; } PrintAndLogEx(SUCCESS, "Executing Lua script: %s, args '%s'\n", script_path, arguments); diff --git a/client/comms.c b/client/comms.c index bdb6e5ab1..1ccdb4d05 100644 --- a/client/comms.c +++ b/client/comms.c @@ -302,7 +302,8 @@ static void PacketResponseReceived(PacketResponseNG *packet) { break; } case CMD_DEBUG_PRINT_INTEGERS: { - PrintAndLogEx(NORMAL, "#db# %" PRIx64 ", %" PRIx64 ", %" PRIx64 "", packet->oldarg[0], packet->oldarg[1], packet->oldarg[2]); + if (! packet->ng) + PrintAndLogEx(NORMAL, "#db# %" PRIx64 ", %" PRIx64 ", %" PRIx64 "", packet->oldarg[0], packet->oldarg[1], packet->oldarg[2]); break; } // iceman: hw status - down the path on device, runs printusbspeed which starts sending a lot of diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c index cead47287..e3c88c3e3 100644 --- a/client/emv/cmdemv.c +++ b/client/emv/cmdemv.c @@ -752,6 +752,7 @@ static void ProcessACResponseFormat1(struct tlvdb *tlvRoot, uint8_t *buf, size_t if (decodeTLV) TLVPrintFromTLV(tlvElm); } + tlvdb_free(tlvElm); } } else { if (decodeTLV) diff --git a/client/fileutils.c b/client/fileutils.c index 79906020e..b8ee376f1 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -410,7 +410,6 @@ int loadFile(const char *preferredName, const char *suffix, void *data, size_t m } size_t bytes_read = fread(dump, 1, fsize, f); - fclose(f); if (bytes_read != fsize) { PrintAndLogEx(FAILED, "error, bytes read mismatch file size"); @@ -432,6 +431,7 @@ int loadFile(const char *preferredName, const char *suffix, void *data, size_t m *datalen = bytes_read; out: + fclose(f); free(fileName); return retval; } @@ -444,8 +444,6 @@ int loadFile_safe(const char *preferredName, const char *suffix, void **pdata, s return PM3_EFILE; } - int retval = PM3_SUCCESS; - FILE *f = fopen(path, "rb"); if (!f) { PrintAndLogEx(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", path); @@ -478,13 +476,14 @@ int loadFile_safe(const char *preferredName, const char *suffix, void **pdata, s if (bytes_read != fsize) { PrintAndLogEx(FAILED, "error, bytes read mismatch file size"); + free(*pdata); return PM3_EFILE; } *datalen = bytes_read; PrintAndLogEx(SUCCESS, "loaded %zu bytes from binary file " _YELLOW_("%s"), bytes_read, preferredName); - return retval; + return PM3_SUCCESS; } int loadFileEML(const char *preferredName, void *data, size_t *datalen) { @@ -782,7 +781,9 @@ int loadFileDICTIONARY_safe(const char *preferredName, void **pdata, uint8_t key *pdata = realloc(*pdata, mem_size); if (*pdata == NULL) { - return PM3_EFILE; + retval = PM3_EFILE; + fclose(f); + goto out; } else { memset(*pdata + (mem_size - block_size), 0, block_size); } @@ -1058,8 +1059,12 @@ int searchFile(char **foundpath, const char *pm3dir, const char *searchname, con char *filename = filenamemcopy(searchname, suffix); - if (filename == NULL || strlen(filename) == 0) + if (filename == NULL) return PM3_EMALLOC; + if (strlen(filename) == 0) { + free(filename); + return PM3_EFILE; + } int res = searchFinalFile(foundpath, pm3dir, filename, silent); if (res != PM3_SUCCESS) { if ((res == PM3_EFILE) && (!silent)) diff --git a/client/graph.c b/client/graph.c index be1d64920..f9e610414 100644 --- a/client/graph.c +++ b/client/graph.c @@ -210,14 +210,13 @@ uint8_t GetPskCarrier(const char *str, bool printAns) { } uint16_t fc = countFC(bits, size, false); + free(bits); carrier = fc & 0xFF; if (carrier != 2 && carrier != 4 && carrier != 8) return 0; if ((fc >> 8) == 10 && carrier == 8) return 0; // Only print this message if we're not looping something if (printAns) PrintAndLogEx(SUCCESS, "Auto-detected PSK carrier rate: %d", carrier); - - free(bits); return carrier; } diff --git a/client/mifare/mifarehost.c b/client/mifare/mifarehost.c index d61201662..1f7f2e35a 100644 --- a/client/mifare/mifarehost.c +++ b/client/mifare/mifarehost.c @@ -577,6 +577,7 @@ int mfEmlSetMem_xt(uint8_t *data, int blockNum, int blocksCount, int blockBtWidt clearCommandBuffer(); SendCommandNG(CMD_HF_MIFARE_EML_MEMSET, (uint8_t *)payload, sizeof(payload) + size); + free(payload); return PM3_SUCCESS; } diff --git a/client/proxmark3.c b/client/proxmark3.c index a2d4ebd72..a6eadb15b 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -386,7 +386,7 @@ static int flash_pm3(char *serial_port_name, uint8_t num_files, char *filenames[ int ret = PM3_EUNDEF; flash_file_t files[FLASH_MAX_FILES]; memset(files, 0, sizeof(files)); - char *filepaths[FLASH_MAX_FILES]; + char *filepaths[FLASH_MAX_FILES] = {0}; if (serial_port_name == NULL) { PrintAndLogEx(ERR, "You must specify a port.\n"); diff --git a/client/scripting.c b/client/scripting.c index 8054ff9b4..7157957ca 100644 --- a/client/scripting.c +++ b/client/scripting.c @@ -1074,6 +1074,7 @@ static int l_searchfile(lua_State *L) { } lua_pushstring(L, path); + free(path); return 1; } From 9b2dcf1a5ce364851f766fe83fb519ef7d1a867c Mon Sep 17 00:00:00 2001 From: mwalker33 Date: Sun, 6 Oct 2019 18:40:50 +1100 Subject: [PATCH 0846/1854] help for win10 color --- CHANGELOG.md | 3 ++- .../Windows-Installation-Instructions.md | 8 ++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 563873a8c..82db1b76b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -358,7 +358,8 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Fix `em 4x05_dump` to print all blocks read (@mwalker33) - Added save to .eml and .bin for `em 4x05_dump` (@mwalker33) - Added `s` to `lf config` / `lf sniff` to skip samples when sniffing based on same option in Proxmark/proxmark3 by @marshmellow42. (@mwalker33) - + - Added support for color text on windows 10 (@mwalker33) + ### Fixed - Changed driver file proxmark3.inf to support both old and new Product/Vendor IDs (@pwpiwi) - Changed start sequence in Qt mode (fix: short commands hangs main Qt thread) (@merlokk) diff --git a/doc/md/Installation_Instructions/Windows-Installation-Instructions.md b/doc/md/Installation_Instructions/Windows-Installation-Instructions.md index 2f5618c40..32cc42b2a 100644 --- a/doc/md/Installation_Instructions/Windows-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Windows-Installation-Instructions.md @@ -128,3 +128,11 @@ echo "export DISPLAY=:0" >> ~/.bashrc Note that it may take a quite long time for a freshly plugged Proxmark3 to be visible on a WSL /dev/ttySX port. Now you're ready to follow the [compilation instructions](/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md). + +## Color text on windows 10 +In later versions of windows 10 you may be able to get color to work by setting this registery key +``` +[HKEY_CURRENT_USER\Console] + "VirtualTerminalLevel"=dword:00000001 +``` +If after setting this key (and restarting proxmark.exe) you get extra characters and no color text, either delete the key or set the value to 0 From bf14b91a851cc69a71c2520e233c339eed16d435 Mon Sep 17 00:00:00 2001 From: Bruno Sutic Date: Mon, 7 Oct 2019 14:57:53 +0200 Subject: [PATCH 0847/1854] Fix Legic_clone.lua script typos --- client/luascripts/Legic_clone.lua | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/client/luascripts/Legic_clone.lua b/client/luascripts/Legic_clone.lua index 4313102b0..982b17aec 100644 --- a/client/luascripts/Legic_clone.lua +++ b/client/luascripts/Legic_clone.lua @@ -20,7 +20,7 @@ place your empty tag onto the PM3 to read and display the MCD & MSN0..2 the values will be shown below - confirm whnen ready [y/n] ?y + confirm when ready [y/n] ?y #db# setting up legic card #db# MIM 256 card found, reading card ... #db# Card read, use 'hf legic decode' or @@ -88,7 +88,7 @@ copyright = '' author = 'Mosci' version = 'v1.0.1' desc = [[ -This is a script which create a clone-dump of a dump from a Legic Prime Tag (MIM256 or MIM1024) +This is a script which creates a clone-dump of a dump from a Legic Prime Tag (MIM256 or MIM1024) (created with 'hf legic save my_dump.hex') ]] example = [[ @@ -98,13 +98,13 @@ example = [[ usage = [[ script run legic_clone -h -i -o -c -d -s -w -requiered arguments: +required arguments: -i (file to read data from) optional arguments : -h - Help text - -o - requieres option -c to be given - -c - requieres option -o to be given + -o - requires option -c to be given + -c - requires option -o to be given -d - Display content of found Segments -s - Display summary at the end -w - write directly to Tag - a file myLegicClone.hex wille be generated also @@ -472,7 +472,7 @@ function main(args) outfile = a ofs = true if (file_check(a)) then - local answer = utils.confirm('\nthe output-file '..a..' alredy exists!\nthis will delete the previous content!\ncontinue?') + local answer = utils.confirm('\nthe output-file '..a..' already exists!\nthis will delete the previous content!\ncontinue?') if (answer==false) then return oops('quiting') end end end From 9a741220794924e719f6c0c58a19e4cf799c1e93 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 7 Oct 2019 17:18:56 +0200 Subject: [PATCH 0848/1854] fix: 'lf indala clone' - now write long id again --- client/cmdlft55xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index f00328fcd..bb4b5415b 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -343,7 +343,7 @@ int clone_t55xx_tag(uint32_t *blockdata, uint8_t numblocks) { if (blockdata == NULL) return PM3_EINVARG; - if (numblocks < 1 || numblocks > 7) + if (numblocks < 1 || numblocks > 8) return PM3_EINVARG; PacketResponseNG resp; From b2592a2f1cd5c0fdaf96ca48fe80f1c546d924de Mon Sep 17 00:00:00 2001 From: David Lam Date: Mon, 7 Oct 2019 14:56:20 -0400 Subject: [PATCH 0849/1854] display high bit for Kastle HID to allow for lf hid clone --- client/cmdlfhid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdlfhid.c b/client/cmdlfhid.c index 09cf90b03..1ec068a4f 100644 --- a/client/cmdlfhid.c +++ b/client/cmdlfhid.c @@ -239,7 +239,7 @@ static int CmdHIDDemod(const char *Cmd) { fc = ((hi & 0xF) << 12) | (lo >> 20); } if (fmtLen == 32 && (lo & 0x40000000)) { //if 32 bit and Kastle bit set - PrintAndLogEx(SUCCESS, "HID Prox TAG (Kastle format) ID: %08x (%u) - Format Len: 32bit - CC: %u - FC: %u - Card: %u", lo, (lo >> 1) & 0xFFFF, cc, fc, cardnum); + PrintAndLogEx(SUCCESS, "HID Prox TAG (Kastle format) ID: %x%08x (%u) - Format Len: 32bit - CC: %u - FC: %u - Card: %u", hi, lo, (lo >> 1) & 0xFFFF, cc, fc, cardnum); } else { PrintAndLogEx(SUCCESS, "HID Prox TAG ID: %x%08x (%u) - Format Len: %ubit - OEM: %03u - FC: %u - Card: %u", hi, lo, cardnum, fmtLen, oem, fc, cardnum); From 86e7cac1e9fd5e19fd68a633f27eadf2d3f09288 Mon Sep 17 00:00:00 2001 From: David Lam Date: Tue, 8 Oct 2019 04:47:14 -0400 Subject: [PATCH 0850/1854] Update CHANGELOG.md for Kastle HID high bit change --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e566eec9f..19b0a2b62 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Display high bit for detected Kastle HIDs to allow `lf hid clone [id]` to work properly (@swg0101) - Add option `-n` to scripts pm3* (@doegox) - Add `wiegand list/encode/decode` - wiegand format manipulation. Adapted to fit here. (@grauerfuchs) - Add `lf t55xx protect` - sets password and enables password protection on t55x7 tag (@iceman1001) From 1baf51b862486587cdd5474e651f15d74d400556 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 8 Oct 2019 11:49:23 +0200 Subject: [PATCH 0851/1854] t5577-M3 ATMEL info, thanks @doegox --- client/cmdlft55xx.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index bb4b5415b..fa1cee1e3 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -1792,11 +1792,17 @@ void printT55x7Trace(t55x7_tracedata_t data, uint8_t repeat) { PrintAndLogEx(NORMAL, "-------------------------------------------------------------"); /* + Trace info. + M1, M2 has the about ATMEL defintion of trace data. + M3 has unique format following industry defacto standard with row/col parity + TRACE - BLOCK O Bits Definition HEX 1-8 ACL Allocation class (ISO/IEC 15963-1) 0xE0 9-16 MFC Manufacturer ID (ISO/IEC 7816-6) 0x15 Atmel Corporation - 17-21 CID 0x1 = Atmel ATA5577M1 0x2 = Atmel ATA5577M2 + 17-21 CID 0x1 = Atmel ATA5577M1 + 0x2 = Atmel ATA5577M2 + 0x3 = Atmel ATA5577M3 22-24 ICR IC revision 25-28 YEAR (BCD encoded) 9 (= 2009) 29-30 QUARTER 1,2,3,4 @@ -1806,6 +1812,11 @@ void printT55x7Trace(t55x7_tracedata_t data, uint8_t repeat) { 1-12 LOT ID 13-17 Wafer number 18-32 DW, die number sequential + + + Startup times (FC) + M1, M2 = 192 + M3 = 128 */ } @@ -2319,6 +2330,7 @@ char *GetModelStrFromCID(uint32_t cid) { if (cid == 1) snprintf(retStr, sizeof(buf), "ATA5577M1"); if (cid == 2) snprintf(retStr, sizeof(buf), "ATA5577M2"); + if (cid == 3) snprintf(retStr, sizeof(buf), "ATA5577M3"); return buf; } From 810a70d8a8258bc4fc91cd1ae7b9abad4f14cfbb Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 8 Oct 2019 11:50:43 +0200 Subject: [PATCH 0852/1854] tweak? --- client/cmdhfmfhard.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/client/cmdhfmfhard.c b/client/cmdhfmfhard.c index c38c4022e..75e647489 100644 --- a/client/cmdhfmfhard.c +++ b/client/cmdhfmfhard.c @@ -237,7 +237,6 @@ static void init_bitflip_bitarrays(void) { uint8_t line = 0; #endif - z_stream compressed_stream; char state_files_path[strlen(get_my_executable_directory()) + strlen(STATE_FILES_DIRECTORY) + strlen(STATE_FILE_TEMPLATE) + 1]; @@ -248,9 +247,11 @@ static void init_bitflip_bitarrays(void) { for (uint16_t bitflip = 0x001; bitflip < 0x400; bitflip++) { bitflip_bitarrays[odd_even][bitflip] = NULL; count_bitflip_bitarrays[odd_even][bitflip] = 1 << 24; + sprintf(state_file_name, STATE_FILE_TEMPLATE, odd_even, bitflip); strcpy(state_files_path, STATE_FILES_DIRECTORY); strcat(state_files_path, state_file_name); + char *path; if (searchFile(&path, RESOURCES_SUBDIR, state_files_path, "", true) != PM3_SUCCESS) { continue; @@ -1637,15 +1638,18 @@ static inline bool bitflips_match(uint8_t byte, uint32_t state, odd_even_t odd_e return true; } - +/* static uint_fast8_t reverse(uint_fast8_t b) { b = (b & 0xF0) >> 4 | (b & 0x0F) << 4; b = (b & 0xCC) >> 2 | (b & 0x33) << 2; b = (b & 0xAA) >> 1 | (b & 0x55) << 1; return b; +} +*/ +static uint_fast8_t reverse(uint_fast8_t b) { + return (b * 0x0202020202ULL & 0x010884422010ULL) % 1023; } - static bool all_bitflips_match(uint8_t byte, uint32_t state, odd_even_t odd_even) { uint32_t masks[2][8] = { {0x00fffff0, 0x00fffff8, 0x00fffff8, 0x00fffffc, 0x00fffffc, 0x00fffffe, 0x00fffffe, 0x00ffffff}, From 275c628da5add41a846a4492f376bdf6284ba57f Mon Sep 17 00:00:00 2001 From: mwalker33 Date: Tue, 8 Oct 2019 21:46:36 +1100 Subject: [PATCH 0853/1854] lf t55xx detect and help Added lf t55xx detect to try without password first and try password if still not detected. Added password status to detected output. Updated lf t55xx help to show current default downlink mode. typo fixed in win10 color help --- CHANGELOG.md | 3 +- client/cmdlft55xx.c | 108 ++++++++++++------ client/cmdlft55xx.h | 1 + .../Windows-Installation-Instructions.md | 2 +- 4 files changed, 77 insertions(+), 37 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e566eec9f..8ce4c51d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -360,7 +360,8 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Added save to .eml and .bin for `em 4x05_dump` (@mwalker33) - Added `s` to `lf config` / `lf sniff` to skip samples when sniffing based on same option in Proxmark/proxmark3 by @marshmellow42. (@mwalker33) - Added support for color text on windows 10 (@mwalker33) - + - Added lf t55xx detected to try without password first (@mwalker33) + ### Fixed - Changed driver file proxmark3.inf to support both old and new Product/Vendor IDs (@pwpiwi) - Changed start sequence in Qt mode (fix: short commands hangs main Qt thread) (@merlokk) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index bb4b5415b..0fbf348d7 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -61,17 +61,17 @@ void Set_t55xx_Config(t55xx_conf_block_t conf) { config = conf; } -static void print_usage_t55xx_downloadlink(uint8_t ShowAll) { +static void print_usage_t55xx_downloadlink(uint8_t ShowAll, uint8_t dl_mode_default) { if (ShowAll == T55XX_DLMODE_ALL) PrintAndLogEx(NORMAL, " r - downlink encoding 0|1|2|3|4"); else PrintAndLogEx(NORMAL, " r - downlink encoding 0|1|2|3"); - PrintAndLogEx(NORMAL, " 0 - fixed bit length"); // default will be whats in config struct - PrintAndLogEx(NORMAL, " 1 - long leading reference"); - PrintAndLogEx(NORMAL, " 2 - leading zero"); - PrintAndLogEx(NORMAL, " 3 - 1 of 4 coding reference"); + PrintAndLogEx(NORMAL, " 0 - fixed bit length%s",(dl_mode_default == 0)? " (detected default)":""); // default will be whats in config struct + PrintAndLogEx(NORMAL, " 1 - long leading reference%s",(dl_mode_default == 1)? " (detected default)":""); + PrintAndLogEx(NORMAL, " 2 - leading zero%s",(dl_mode_default == 2)? " (detected default)":""); + PrintAndLogEx(NORMAL, " 3 - 1 of 4 coding reference%s",(dl_mode_default == 3)? " (detected default)":""); if (ShowAll == T55XX_DLMODE_ALL) - PrintAndLogEx(NORMAL, " 4 - Try all downlink modes"); + PrintAndLogEx(NORMAL, " 4 - Try all downlink modes%s",(dl_mode_default == 4)? " (default)":""); } static int usage_t55xx_config() { @@ -86,7 +86,7 @@ static int usage_t55xx_config() { PrintAndLogEx(NORMAL, " Q5 [0/1] - Set/reset as T5555 ( Q5 ) chip instead of T55x7"); PrintAndLogEx(NORMAL, " ST [0/1] - Set/reset Sequence Terminator on"); PrintAndLogEx(NORMAL, ""); // layout is a little differnet, so seperate until a better fix - print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE); + print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE,config.downlink_mode); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx config d FSK - FSK demodulation"); @@ -102,7 +102,7 @@ static int usage_t55xx_read() { PrintAndLogEx(NORMAL, " p - OPTIONAL password (8 hex characters)"); PrintAndLogEx(NORMAL, " o - OPTIONAL override safety check"); PrintAndLogEx(NORMAL, " 1 - OPTIONAL 0|1 read Page 1 instead of Page 0"); - print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE); + print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE,config.downlink_mode); PrintAndLogEx(NORMAL, " " _RED_("**** WARNING ****")); PrintAndLogEx(NORMAL, " Use of read with password on a tag not configured"); PrintAndLogEx(NORMAL, " for a password can damage the tag"); @@ -119,7 +119,7 @@ static int usage_t55xx_resetread() { PrintAndLogEx(NORMAL, "Send Reset Cmd then lf read the stream to attempt to identify the start of it (needs a demod and/or plot after)"); PrintAndLogEx(NORMAL, "Usage: lf t55xx resetread [r ]"); PrintAndLogEx(NORMAL, "Options:"); - print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE); + print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE,config.downlink_mode); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx resetread"); @@ -135,7 +135,7 @@ static int usage_t55xx_write() { PrintAndLogEx(NORMAL, " 1 - OPTIONAL write Page 1 instead of Page 0"); PrintAndLogEx(NORMAL, " t - OPTIONAL test mode write - ****DANGER****"); PrintAndLogEx(NORMAL, " v - OPTIONAL validate data afterwards"); - print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE); + print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE,config.downlink_mode); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx write b 3 d 11223344 - write 11223344 to block 3"); @@ -147,7 +147,7 @@ static int usage_t55xx_write() { static int usage_t55xx_trace() { PrintAndLogEx(NORMAL, "Usage: lf t55xx trace [1] [r mode]"); PrintAndLogEx(NORMAL, "Options:"); - print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE); + print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE,config.downlink_mode); PrintAndLogEx(NORMAL, " 1 - if set, use Graphbuffer otherwise read data from tag."); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); @@ -165,7 +165,7 @@ static int usage_t55xx_info() { PrintAndLogEx(NORMAL, " c - set configuration from a block0"); PrintAndLogEx(NORMAL, " if set, use these data instead of reading tag."); PrintAndLogEx(NORMAL, " q - if set, provided data are interpreted as Q5 config."); - print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE); + print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE,config.downlink_mode); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx info"); @@ -181,7 +181,7 @@ static int usage_t55xx_dump() { PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " p - OPTIONAL password 4bytes (8 hex symbols)"); PrintAndLogEx(NORMAL, " o - OPTIONAL override, force pwd read despite danger to card"); - print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE); + print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE,config.downlink_mode); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx dump"); @@ -194,7 +194,7 @@ static int usage_t55xx_detect() { PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " 1 - if set, use Graphbuffer otherwise read data from tag."); PrintAndLogEx(NORMAL, " p - OPTIONAL password (8 hex characters)"); - print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE); // Need to setup to try all modes + print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE,config.downlink_mode); // Need to setup to try all modes PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx p1detect"); @@ -224,7 +224,7 @@ static int usage_t55xx_wakup() { PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h - this help"); PrintAndLogEx(NORMAL, " p - password 4bytes (8 hex symbols)"); - print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE); + print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE,config.downlink_mode); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx wakeup p 11223344 - send wakeup password"); @@ -239,7 +239,7 @@ static int usage_t55xx_chk() { PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h - this help"); PrintAndLogEx(NORMAL, " m - use dictionary from flashmemory\n"); - print_usage_t55xx_downloadlink(T55XX_DLMODE_ALL); + print_usage_t55xx_downloadlink(T55XX_DLMODE_ALL,T55XX_DLMODE_ALL); PrintAndLogEx(NORMAL, " i <*.dic> - loads a default keys dictionary file <*.dic>"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); @@ -257,7 +257,7 @@ static int usage_t55xx_bruteforce() { PrintAndLogEx(NORMAL, " password must be 4 bytes (8 hex symbols)"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h - this help"); - print_usage_t55xx_downloadlink(T55XX_DLMODE_ALL); + print_usage_t55xx_downloadlink(T55XX_DLMODE_ALL,T55XX_DLMODE_ALL); PrintAndLogEx(NORMAL, " s - 4 byte hex value to start pwd search at"); PrintAndLogEx(NORMAL, " e - 4 byte hex value to end pwd search at"); PrintAndLogEx(NORMAL, ""); @@ -276,7 +276,7 @@ static int usage_t55xx_recoverpw() { PrintAndLogEx(NORMAL, " default password is 51243648, used by many cloners"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h - this help"); - print_usage_t55xx_downloadlink(T55XX_DLMODE_ALL); + print_usage_t55xx_downloadlink(T55XX_DLMODE_ALL,T55XX_DLMODE_ALL); PrintAndLogEx(NORMAL, " p - 4 byte hex value of password written by cloner"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); @@ -328,7 +328,7 @@ static int usage_t55xx_protect() { PrintAndLogEx(NORMAL, " p - OPTIONAL password (8 hex characters)"); PrintAndLogEx(NORMAL, " o - OPTIONAL override safety check"); PrintAndLogEx(NORMAL, " n - new password"); - print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE); + print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE,config.downlink_mode); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx protect n 01020304 - sets new password to 01020304"); @@ -490,6 +490,13 @@ bool t55xxAquireAndDetect(bool usepwd, uint32_t password, uint32_t known_block0, if (verbose) PrintAndLogEx(INFO, "Block0 write detected, running `detect` to see if validation is possible"); + // Update flags for usepwd pwd assume its correct + config.usepwd = usepwd; + if (usepwd) + config.pwd = password; + else + config.pwd = 0x00; + for (uint8_t m = 0; m < 4; m++) { if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, m) == false) continue; @@ -500,6 +507,9 @@ bool t55xxAquireAndDetect(bool usepwd, uint32_t password, uint32_t known_block0, config.downlink_mode = m; return true; } + config.usepwd = false; // unknown so assume no password + config.pwd = 0x00; + return false; } @@ -943,6 +953,7 @@ static int CmdT55xxDetect(const char *Cmd) { bool errors = false; bool useGB = false; bool usepwd = false; + bool try_with_pwd = false; bool try_all_dl_modes = true; bool found = false; uint32_t password = 0; @@ -982,33 +993,57 @@ static int CmdT55xxDetect(const char *Cmd) { return PM3_ESOFT; if (useGB == false) { + // do ... while to check without password then loop back if password supplied + do { + + if (try_all_dl_modes) { + for (uint8_t m = downlink_mode; m < 4; m++) { + + if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, try_with_pwd & usepwd, password, m) == false) + continue; - if (try_all_dl_modes) { + // pre fill to save passing in. + config.usepwd = try_with_pwd; + if (try_with_pwd) + config.pwd = password; + else + config.pwd = 0x00; - for (uint8_t m = downlink_mode; m < 4; m++) { - if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, m) == false) - continue; + if (tryDetectModulation(m, T55XX_PrintConfig) == false) + continue; - if (tryDetectModulation(m, T55XX_PrintConfig) == false) - continue; + found = true; + break; + } + } else { + config.usepwd = try_with_pwd; + if (try_with_pwd) + config.pwd = password; + else + config.pwd = 0x00; - found = true; - break; + if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, downlink_mode)) { + found = tryDetectModulation(downlink_mode, T55XX_PrintConfig); + } } - } else { - if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, downlink_mode)) { - found = tryDetectModulation(downlink_mode, T55XX_PrintConfig); - } - } + if (!found & usepwd) + try_with_pwd = !try_with_pwd; // toggle so we loop back if not found and try with pwd + + if (found) + try_with_pwd = false; // force exit as decect block has been found. + + } while (try_with_pwd); } else { found = tryDetectModulation(downlink_mode, T55XX_PrintConfig); } - if (found == false) + if (found == false) { + config.usepwd = false; + config.pwd = 0x00; PrintAndLogEx(WARNING, "Could not detect modulation automatically. Try setting it manually with " _YELLOW_("\'lf t55xx config\'")); - + } return PM3_SUCCESS; } @@ -1482,6 +1517,9 @@ int printConfiguration(t55xx_conf_block_t b) { PrintAndLogEx(NORMAL, " Seq. Term. : %s", (b.ST) ? _GREEN_("Yes") : "No"); PrintAndLogEx(NORMAL, " Block0 : 0x%08X", b.block0); PrintAndLogEx(NORMAL, " Downlink Mode : %s", GetDownlinkModeStr(b.downlink_mode)); + PrintAndLogEx(NORMAL, " Password Set : %s", (b.usepwd) ? _RED_("Yes") : _GREEN_("No")); + if (b.usepwd) + PrintAndLogEx(NORMAL, " Password : %08X",b.pwd); PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } diff --git a/client/cmdlft55xx.h b/client/cmdlft55xx.h index dce3a1b16..d7791466c 100644 --- a/client/cmdlft55xx.h +++ b/client/cmdlft55xx.h @@ -118,6 +118,7 @@ typedef struct { bool Q5; bool ST; bool usepwd; + uint32_t pwd; enum { refFixedBit = 0x00, refLongLeading = 0x01, diff --git a/doc/md/Installation_Instructions/Windows-Installation-Instructions.md b/doc/md/Installation_Instructions/Windows-Installation-Instructions.md index 32cc42b2a..dfbea55c4 100644 --- a/doc/md/Installation_Instructions/Windows-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Windows-Installation-Instructions.md @@ -135,4 +135,4 @@ In later versions of windows 10 you may be able to get color to work by setting [HKEY_CURRENT_USER\Console] "VirtualTerminalLevel"=dword:00000001 ``` -If after setting this key (and restarting proxmark.exe) you get extra characters and no color text, either delete the key or set the value to 0 +If after setting this key (and restarting proxmark3.exe) you get extra characters and no color text, either delete the key or set the value to 0 From ec27aabb680c1672fd27e816d6092bc8a1d424fa Mon Sep 17 00:00:00 2001 From: mwalker33 Date: Tue, 8 Oct 2019 23:02:37 +1100 Subject: [PATCH 0854/1854] Update CHANGELOG.md Move entries closer to where the should be. --- CHANGELOG.md | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ce4c51d4..82b8f58fa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,10 +3,18 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] - - Add option `-n` to scripts pm3* (@doegox) + - Added lf t55xx detected to try without password first (@mwalker33) - Add `wiegand list/encode/decode` - wiegand format manipulation. Adapted to fit here. (@grauerfuchs) + - Added support for color text on windows 10 (@mwalker33) + - Added `s` to `lf config` / `lf sniff` to skip samples when sniffing based on same option in Proxmark/proxmark3 by @marshmellow42. (@mwalker33) + - Added save to .eml and .bin for `em 4x05_dump` (@mwalker33) + - Add option `-n` to scripts pm3* (@doegox) + - Fix `em 4x05_dump` to print all blocks read (@mwalker33) + - Fix T55xx config getting displayed when using password when no password needed on read. (@mwalker33) + - Added T55x7 downlink mode auto usage via mode detected (lf t55 detect) (@mwalker33) - Add `lf t55xx protect` - sets password and enables password protection on t55x7 tag (@iceman1001) - Chg `lf t55xx wipe` - now accepts user provided configuration block (@iceman1001) + - Added T55x7 downlink mode support r 0 Default, 1 Long Leading 0, 2 Leading 0, 3 1 of 4 and 4 (in some commands) try all. (@mwalker33) - Chg proxmark3-flasher is now merged into proxmark3 client. Add pm3-flash (@doegox) - Chg `hf iclass clone\dump\rdbl\wrbl` - now uses NG (@iceman1001) - Fix `hf iclass clone` - last block always fails (@iceman1001) @@ -353,15 +361,8 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Added `hf fido` `assert` and `make` commands from fido2 protocol (authenticatorMakeCredential and authenticatorGetAssertion) (@merlokk) - Added trailer block decoding to `hf mf rdbl` and `hf mf cgetbl` (@merlokk) - Added `hf mf mad` and `hf mfp mad` MAD decode, check and print commands (@merlokk) - - Added T55x7 downlink mode support r 0 Default, 1 Long Leading 0, 2 Leading 0, 3 1 of 4 and 4 (in some commands) try all. (@mwalker33) - - Added T55x7 downlink mode auto usage via mode detected (lf t55 detect) (@mwalker33) - - Fix T55xx config getting displayed when using password when no password needed on read. (@mwalker33) - - Fix `em 4x05_dump` to print all blocks read (@mwalker33) - - Added save to .eml and .bin for `em 4x05_dump` (@mwalker33) - - Added `s` to `lf config` / `lf sniff` to skip samples when sniffing based on same option in Proxmark/proxmark3 by @marshmellow42. (@mwalker33) - - Added support for color text on windows 10 (@mwalker33) - - Added lf t55xx detected to try without password first (@mwalker33) - + + ### Fixed - Changed driver file proxmark3.inf to support both old and new Product/Vendor IDs (@pwpiwi) - Changed start sequence in Qt mode (fix: short commands hangs main Qt thread) (@merlokk) From 9cbfe5481b66eba29268a458b5965dd283e48580 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 8 Oct 2019 14:16:46 +0200 Subject: [PATCH 0855/1854] chg: lf t55xx brute / lf t55xx chk / lf t55xx recoverpwd - now shows help when called without params --- client/cmdlft55xx.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 97cd3ae9c..b1c156157 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -2644,7 +2644,7 @@ static int CmdT55xxChkPwds(const char *Cmd) { } } - if (errors) return usage_t55xx_chk(); + if (errors || cmdp == 0) return usage_t55xx_chk(); /* // block 7, page1 = false, usepwd = false, override = false, pwd = 00000000 @@ -2788,11 +2788,11 @@ static int CmdT55xxBruteForce(const char *Cmd) { break; } } - if (start_password >= end_password) { - return usage_t55xx_bruteforce(); - } - if (errors) return usage_t55xx_bruteforce(); + if (start_password >= end_password) + errors = true; + + if (errors || cmdp == 0) return usage_t55xx_bruteforce(); uint64_t t1 = msclock(); @@ -2891,8 +2891,7 @@ static int CmdT55xxRecoverPW(const char *Cmd) { } } - if (errors) return usage_t55xx_recoverpw(); - + if (errors || cmdp == 0) return usage_t55xx_recoverpw(); // first try fliping each bit in the expected password while (bit < 32) { From 2d2564f53e1ec7a2123dd19b5a4b09eb74b178bd Mon Sep 17 00:00:00 2001 From: Iceman Date: Tue, 8 Oct 2019 14:37:00 +0200 Subject: [PATCH 0856/1854] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 22221abe6..2d51d3fbf 100644 --- a/README.md +++ b/README.md @@ -94,8 +94,9 @@ It's needed to have a good USB cable to connect Proxmark3 to USB. If you have st ## The end -- [@herrmann1001](https://mobile.twitter.com/herrmann1001) July 2018 +- July 2018 [@herrmann1001](https://mobile.twitter.com/herrmann1001) - updated Feb 2019 [@5w0rdfish](https://mobile.twitter.com/5w0rdFish) +- updated 2019 [@doegox](https://mobile.twitter.com/doegox) # Donations From c4249ecbb8278eb37d8e2870713d0d88c9703074 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 8 Oct 2019 15:24:06 +0200 Subject: [PATCH 0857/1854] WiP - 'lf t55xx restore' - read a dump file and restore it to a t55xx card --- client/cmdlft55xx.c | 73 +++++++++++++++++++++++++++++++++++++++++++-- client/fileutils.c | 42 +++++++++++++++++++++++++- client/fileutils.h | 9 +++--- 3 files changed, 116 insertions(+), 8 deletions(-) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index b1c156157..054747f2e 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -189,6 +189,19 @@ static int usage_t55xx_dump() { PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } +static int usage_t55xx_restore() { + PrintAndLogEx(NORMAL, "Usage: lf t55xx restore [r ] [p [o]]"); + PrintAndLogEx(NORMAL, "Options:"); + PrintAndLogEx(NORMAL, " p - OPTIONAL password 4bytes (8 hex symbols)"); + PrintAndLogEx(NORMAL, " o - OPTIONAL override, force pwd read despite danger to card"); + print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE,config.downlink_mode); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Examples:"); + PrintAndLogEx(NORMAL, " lf t55xx restore f lf-t55xx-01020304.eml"); + PrintAndLogEx(NORMAL, " lf t55xx restore f lf-t55xx-01020304.eml p feedbeef o"); + PrintAndLogEx(NORMAL, ""); + return PM3_SUCCESS; +} static int usage_t55xx_detect() { PrintAndLogEx(NORMAL, "Usage: lf t55xx detect [1] [r ] [p ]"); PrintAndLogEx(NORMAL, "Options:"); @@ -340,8 +353,8 @@ static int usage_t55xx_protect() { static int CmdHelp(const char *Cmd); int clone_t55xx_tag(uint32_t *blockdata, uint8_t numblocks) { - - if (blockdata == NULL) + + if (blockdata == NULL) return PM3_EINVARG; if (numblocks < 1 || numblocks > 8) return PM3_EINVARG; @@ -2145,6 +2158,59 @@ static int CmdT55xxDump(const char *Cmd) { return PM3_SUCCESS; } +static int CmdT55xxRestore(const char *Cmd) { + + uint32_t password = 0; + uint8_t override = 0; + uint8_t downlink_mode = config.downlink_mode;; + bool usepwd = false; + bool errors = false; + uint8_t cmdp = 0; + + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { + case 'h': + return usage_t55xx_restore(); + case 'r': + downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); + if (downlink_mode > 3) + downlink_mode = 0; + + cmdp += 2; + break; + case 'p': + password = param_get32ex(Cmd, cmdp + 1, 0, 16); + usepwd = true; + cmdp += 2; + break; + case 'o': + override = 1; + cmdp++; + break; + default: + PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } + } + if (errors) return usage_t55xx_restore(); + + PrintAndLogEx(INFO, "Work in progress. To be implemented"); + if (usepwd || password || override ) { + + } + // load file name (json/eml/bin) + + // Print dump data? + + uint32_t res = PM3_SUCCESS; + +// page0. +// res = clone_t55xx_tag(blockdata, numblocks); + + return res; +} + bool AquireData(uint8_t page, uint8_t block, bool pwdmode, uint32_t password, uint8_t downlink_mode) { // arg0 bitmodes: // b0 = pwdmode @@ -3334,12 +3400,13 @@ static command_t CommandTable[] = { {"chk", CmdT55xxChkPwds, IfPm3Lf, "Check passwords from dictionary/flash"}, {"detect", CmdT55xxDetect, AlwaysAvailable, "[1] Try detecting the tag modulation from reading the configuration block."}, {"deviceconfig", CmdT55xxSetDeviceConfig, IfPm3Lf, "Set/Get T55XX device configuration (startgap, writegap, write0, write1, readgap"}, - {"dump", CmdT55xxDump, IfPm3Lf, "[password] [o] Dump T55xx card block 0-7. Optional [password], [override]"}, + {"dump", CmdT55xxDump, IfPm3Lf, "[password] [o] Dump T55xx card Page 0 block 0-7. Optional [password], [override]"}, {"info", CmdT55xxInfo, AlwaysAvailable, "[1] Show T55x7 configuration data (page 0/ blk 0)"}, {"p1detect", CmdT55xxDetectPage1, IfPm3Lf, "[1] Try detecting if this is a t55xx tag by reading page 1"}, {"protect", CmdT55xxProtect, IfPm3Lf, "Password protect tag"}, {"read", CmdT55xxReadBlock, IfPm3Lf, "b p [password] [o] [1] -- Read T55xx block data. Optional [p password], [override], [page1]"}, {"resetread", CmdResetRead, IfPm3Lf, "Send Reset Cmd then lf read the stream to attempt to identify the start of it (needs a demod and/or plot after)"}, + {"restore", CmdT55xxRestore, IfPm3Lf, "[password] Restore T55xx card Page 0 / Page 1 blocks"}, {"recoverpw", CmdT55xxRecoverPW, IfPm3Lf, "[password] Try to recover from bad password write from a cloner. Only use on PW protected chips!"}, {"special", special, IfPm3Lf, "Show block changes with 64 different offsets"}, {"trace", CmdT55xxReadTrace, AlwaysAvailable, "[1] Show T55x7 traceability data (page 1/ blk 0-1)"}, diff --git a/client/fileutils.c b/client/fileutils.c index b8ee376f1..9c226dd3b 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -328,6 +328,25 @@ int saveFileJSON(const char *preferredName, JSONFileType ftype, uint8_t *data, s } break; } + case jsfT55x7: { + JsonSaveStr(root, "FileType", "t55x7"); + uint8_t id[4] = {0}; + memcpy(id, data, 4); + JsonSaveBufAsHexCompact(root, "$.Card.ID", id, sizeof(id)); + + for (size_t i = 0; i < (datalen / 4); i++) { + char path[PATH_MAX_LENGTH] = {0}; + sprintf(path, "$.blocks.%zu", i); + JsonSaveBufAsHexCompact(root, path, data + (i * 4), 4); + } + break; + } + case jsf14b: + case jsf15: + case jsfLegic: + case jsfT5555: + default: + break; } int res = json_dump_file(root, fileName, JSON_INDENT(2)); @@ -660,6 +679,27 @@ int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_ *datalen = sptr; } + if (!strcmp(ctype, "t55x7")) { + size_t sptr = 0; + for (size_t i = 0; i < (maxdatalen / 4); i++) { + if (sptr + 4 > maxdatalen) { + retval = PM3_EMALLOC; + goto out; + } + + char path[30] = {0}; + sprintf(path, "$.blocks.%zu", i); + + size_t len = 0; + JsonLoadBufAsHex(root, path, &udata[sptr], 4, &len); + if (!len) + break; + + sptr += len; + } + *datalen = sptr; + } + PrintAndLogEx(SUCCESS, "loaded from JSON file " _YELLOW_("%s"), fileName); out: json_decref(root); @@ -1057,10 +1097,10 @@ int searchFile(char **foundpath, const char *pm3dir, const char *searchname, con if (is_directory(searchname)) return PM3_EINVARG; - char *filename = filenamemcopy(searchname, suffix); if (filename == NULL) return PM3_EMALLOC; + if (strlen(filename) == 0) { free(filename); return PM3_EFILE; diff --git a/client/fileutils.h b/client/fileutils.h index 5432aa816..eb4b57c82 100644 --- a/client/fileutils.h +++ b/client/fileutils.h @@ -56,10 +56,11 @@ typedef enum { jsfMfuMemory, jsfHitag, jsfIclass, -// jsf14b, -// jsf15, -// jsfLegic, -// jsfT55xx, + jsf14b, + jsf15, + jsfLegic, + jsfT55x7, + jsfT5555, } JSONFileType; typedef enum { From 813f1e228c77156f416841b8d6fb6e73d147dee0 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 8 Oct 2019 16:10:50 +0200 Subject: [PATCH 0858/1854] fix nedap examples --- client/cmdlfnedap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/cmdlfnedap.c b/client/cmdlfnedap.c index f4c5346e2..66d093800 100644 --- a/client/cmdlfnedap.c +++ b/client/cmdlfnedap.c @@ -41,7 +41,7 @@ static int usage_lf_nedap_gen(void) { PrintAndLogEx(NORMAL, " l : optional - long (128), default to short (64)"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " lf nedap generate s 1 c 123 i 112233"); + PrintAndLogEx(NORMAL, " lf nedap generate s 1 c 123 i 12345"); return PM3_SUCCESS; } @@ -58,7 +58,7 @@ static int usage_lf_nedap_clone(void) { // PrintAndLogEx(NORMAL, " Q5 : optional - clone to Q5 (T5555) instead of T55x7 chip"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " lf nedap clone s 1 c 123 i 112233"); + PrintAndLogEx(NORMAL, " lf nedap clone s 1 c 123 i 12345"); return PM3_SUCCESS; } From 6d1e109c82bbf77cfd90115924ed08932394cb1b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 8 Oct 2019 16:11:01 +0200 Subject: [PATCH 0859/1854] filechecks.. could fail stat call and directory could be symlinked --- client/fileutils.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/client/fileutils.c b/client/fileutils.c index 9c226dd3b..57aa939a7 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -77,13 +77,15 @@ int fileExists(const char *filename) { bool is_regular_file(const char *filename) { #ifdef _WIN32 struct _stat st; - _stat(filename, &st); - return S_ISREG(st.st_mode) != 0; + if (_stat(filename, &st) == -1) + return false; #else struct stat st; - stat(filename, &st); - return S_ISREG(st.st_mode) != 0; +// stat(filename, &st); + if (lstat(filename, &st) == -1) + return false; #endif + return S_ISREG(st.st_mode) != 0; } /** * @brief checks if path is directory. @@ -93,13 +95,15 @@ bool is_regular_file(const char *filename) { bool is_directory(const char *filename) { #ifdef _WIN32 struct _stat st; - _stat(filename, &st); - return S_ISDIR(st.st_mode) != 0; + if (_stat(filename, &st) == -1) + return false; #else struct stat st; - stat(filename, &st); - return S_ISDIR(st.st_mode) != 0; +// stat(filename, &st); + if (lstat(filename, &st) == -1) + return false; #endif + return S_ISDIR(st.st_mode) != 0; } From e7a632292d7af7c82f3791279d6e91326a85d601 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 8 Oct 2019 16:13:36 +0200 Subject: [PATCH 0860/1854] fix t55 comments --- client/cmdlft55xx.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/cmdlft55xx.h b/client/cmdlft55xx.h index d7791466c..2efecdc26 100644 --- a/client/cmdlft55xx.h +++ b/client/cmdlft55xx.h @@ -37,11 +37,11 @@ #define T55X7_INDALA_224_CONFIG_BLOCK 0x000810E0 // emulate indala 224 bit - compat mode, PSK1, psk carrier FC * 2, data rate 32, maxblock 7 #define T55X7_GUARDPROXII_CONFIG_BLOCK 0x00150060 // bitrate 64pcb, Direct modulation, Biphase, 3 data blocks #define T55X7_VIKING_CONFIG_BLOCK 0x00088040 // ASK, compat mode, data rate 32, Manchester, 2 data blocks -#define T55X7_NORALYS_CONFIG_BLOCK 0x00088C6A // ASK, compat mode, (NORALYS - KCP3000) +#define T55X7_NORALYS_CONFIG_BLOCK 0x00088C6A // ASK, compat mode, (NORALYS - KCP3000), 3 data blocks #define T55X7_IOPROX_CONFIG_BLOCK 0x00147040 // ioprox - FSK2a, data rate 64, 2 data blocks -#define T55X7_PRESCO_CONFIG_BLOCK 0x00088088 // ASK, data rate 32, Manchester, 5 data blocks, STT -#define T55X7_NEDAP_64_CONFIG_BLOCK 0x907f0042 // BiPhase, data rate 64, 3 data blocks -#define T55X7_NEDAP_128_CONFIG_BLOCK 0x907f0082 // BiPhase, data rate 64, 5 data blocks +#define T55X7_PRESCO_CONFIG_BLOCK 0x00088088 // ASK, data rate 32, Manchester, 4 data blocks, STT +#define T55X7_NEDAP_64_CONFIG_BLOCK 0x907f0042 // BiPhase, data rate 64, 2 data blocks +#define T55X7_NEDAP_128_CONFIG_BLOCK 0x907f0082 // BiPhase, data rate 64, 4 data blocks #define T55X7_bin 0b0010 From 96bc4438e9de79cc2bdcc15cec28770a2cf0fa9a Mon Sep 17 00:00:00 2001 From: David Lam Date: Tue, 8 Oct 2019 12:42:51 -0400 Subject: [PATCH 0861/1854] remove extra spaces --- client/cmdlft55xx.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 054747f2e..68df3fb31 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -2746,7 +2746,7 @@ static int CmdT55xxChkPwds(const char *Cmd) { if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, resp.oldarg[1], downlink_mode)) { found = tryDetectModulation(downlink_mode, T55XX_PrintConfig); if (found) { - PrintAndLogEx(SUCCESS, "Found valid password: [ " _GREEN_("%08"PRIX64) " ]", resp.oldarg[1]); + PrintAndLogEx(SUCCESS, "Found valid password: [ " _GREEN_("%08"PRIX64) "]", resp.oldarg[1]); } else { PrintAndLogEx(WARNING, "Check pwd failed"); @@ -2798,7 +2798,7 @@ static int CmdT55xxChkPwds(const char *Cmd) { found = tryDetectModulation(dl_mode, T55XX_PrintConfig); if (found) { - PrintAndLogEx(SUCCESS, "Found valid password: [ " _GREEN_("%08"PRIX64) " ]", curr_password); + PrintAndLogEx(SUCCESS, "Found valid password: [ " _GREEN_("%08"PRIX64) "]", curr_password); dl_mode = 4; // Exit other downlink mode checks c = keycount; // Exit loop } @@ -2889,7 +2889,7 @@ static int CmdT55xxBruteForce(const char *Cmd) { PrintAndLogEx(SUCCESS, "Found valid password: [ " _GREEN_("%08X") "]", curr - 1); T55xx_Print_DownlinkMode((found >> 1) & 3); } else - PrintAndLogEx(WARNING, "Bruteforce failed, last tried: [ " _YELLOW_("%08X") " ]", curr); + PrintAndLogEx(WARNING, "Bruteforce failed, last tried: [ " _YELLOW_("%08X") "]", curr); t1 = msclock() - t1; PrintAndLogEx(SUCCESS, "\nTime in bruteforce: %.0f seconds\n", (float)t1 / 1000.0); From 3a63b727418ae98cf0f79e4670f04c203891a941 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 8 Oct 2019 19:49:34 +0200 Subject: [PATCH 0862/1854] Chg: 'hf mf autopwn' - skip extra checks if all keys found on first check --- client/cmdhfmf.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 8c7cfcee7..637cb6635 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -1644,7 +1644,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { int block_cnt = MIFARE_1K_MAXBLOCK; uint8_t tmp_key[6] = {0}; bool know_target_key = false; - // For the timier + // For the timer uint64_t t1; // Parameters and dictionary file char filename[FILE_PATH_SIZE] = {0}; @@ -1666,6 +1666,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { bool verbose = false; bool has_filename = false; bool errors = false; + uint8_t num_found_keys = 0; // Parse the options given by the user while ((ctmp = param_getchar(Cmd, cmdp)) && !errors) { @@ -1819,6 +1820,9 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { // Store the key for the nested / hardnested attack (if supplied by the user) e_sector[blockNo].Key[keyType] = key64; + e_sector[blockNo].foundKey[keyType] = 'U'; + + ++num_found_keys; } else { know_target_key = false; PrintAndLogEx(FAILED, "Key is wrong. Can't authenticate to sector:"_RED_("%3d") " key type: "_RED_("%c") " key: " _RED_("%s"), @@ -1855,11 +1859,14 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { sprint_hex(key, sizeof(key)) ); } + ++num_found_keys; } } } } if (verbose) PrintAndLogEx(INFO, _YELLOW_("======================= STOP KNOWN KEY ATTACK =======================")); + if (num_found_keys == sectors_cnt * 2) + goto all_found; } bool load_success = true; @@ -1873,7 +1880,6 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { load_success = false; } - } if (has_filename == false || load_success == false) { @@ -1905,6 +1911,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { if (mfCheckKeys(FirstBlockOfSector(i), j, true, 1, (keyBlock + (6 * k)), &key64) == PM3_SUCCESS) { e_sector[i].Key[j] = bytes_to_num((keyBlock + (6 * k)), 6); e_sector[i].foundKey[j] = 'D'; + ++num_found_keys; break; } } @@ -2205,6 +2212,8 @@ tryHardnested: // If the nested attack fails then we try the hardnested attack } } +all_found: + // Show the results to the user PrintAndLogEx(NORMAL, ""); PrintAndLogEx(INFO, "found Keys:"); From 7affb00e76d128c6e14cb69b0e276ce9874209b2 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 8 Oct 2019 19:55:01 +0200 Subject: [PATCH 0863/1854] textual --- client/cmdhfmfu.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index 3393c0a0c..8ac391a6e 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -791,8 +791,13 @@ static int ndef_print_CC(uint8_t *data) { } int ul_print_type(uint32_t tagtype, uint8_t spaces) { + char spc[11] = " "; spc[10] = 0x00; + + if (spaces > 10) + spaces = 10; + char *spacer = spc + (10 - spaces); if (tagtype & UL) @@ -1405,7 +1410,7 @@ static int CmdHF14AMfUInfo(const char *Cmd) { num_to_bytes(ul_ev1_pwdgenA(card.uid), 4, key); len = ulev1_requestAuthentication(key, pack, sizeof(pack)); if (len > -1) { - PrintAndLogEx(SUCCESS, "Found a default password: %s || Pack: %02X %02X", sprint_hex(key, 4), pack[0], pack[1]); + PrintAndLogEx(SUCCESS, "Found a default password:" _GREEN_("%s") " || Pack: %02X %02X", sprint_hex(key, 4), pack[0], pack[1]); goto out; } @@ -1415,7 +1420,7 @@ static int CmdHF14AMfUInfo(const char *Cmd) { num_to_bytes(ul_ev1_pwdgenB(card.uid), 4, key); len = ulev1_requestAuthentication(key, pack, sizeof(pack)); if (len > -1) { - PrintAndLogEx(SUCCESS, "Found a default password: %s || Pack: %02X %02X", sprint_hex(key, 4), pack[0], pack[1]); + PrintAndLogEx(SUCCESS, "Found a default password:" _GREEN_("%s") " || Pack: %02X %02X", sprint_hex(key, 4), pack[0], pack[1]); goto out; } @@ -1425,7 +1430,7 @@ static int CmdHF14AMfUInfo(const char *Cmd) { num_to_bytes(ul_ev1_pwdgenC(card.uid), 4, key); len = ulev1_requestAuthentication(key, pack, sizeof(pack)); if (len > -1) { - PrintAndLogEx(SUCCESS, "Found a default password: %s || Pack: %02X %02X", sprint_hex(key, 4), pack[0], pack[1]); + PrintAndLogEx(SUCCESS, "Found a default password:" _GREEN_("%s") " || Pack: %02X %02X", sprint_hex(key, 4), pack[0], pack[1]); goto out; } @@ -1435,7 +1440,7 @@ static int CmdHF14AMfUInfo(const char *Cmd) { num_to_bytes(ul_ev1_pwdgenD(card.uid), 4, key); len = ulev1_requestAuthentication(key, pack, sizeof(pack)); if (len > -1) { - PrintAndLogEx(SUCCESS, "Found a default password: %s || Pack: %02X %02X", sprint_hex(key, 4), pack[0], pack[1]); + PrintAndLogEx(SUCCESS, "Found a default password:" _GREEN_("%s") " || Pack: %02X %02X", sprint_hex(key, 4), pack[0], pack[1]); goto out; } @@ -1445,7 +1450,7 @@ static int CmdHF14AMfUInfo(const char *Cmd) { key = default_pwd_pack[i]; len = ulev1_requestAuthentication(key, pack, sizeof(pack)); if (len > -1) { - PrintAndLogEx(SUCCESS, "Found a default password: %s || Pack: %02X %02X", sprint_hex(key, 4), pack[0], pack[1]); + PrintAndLogEx(SUCCESS, "Found a default password:" _GREEN_("%s") " || Pack: %02X %02X", sprint_hex(key, 4), pack[0], pack[1]); break; } else { if (ul_auth_select(&card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack)) == PM3_ESOFT) return PM3_ESOFT; From 10a4361cccd96e4be63a6276e63e0e92a8438f5a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 8 Oct 2019 21:45:40 +0200 Subject: [PATCH 0864/1854] Add: 'lf gallagher *' support. Unknown how to decode to printed number yet. --- client/Makefile | 1 + client/cmdlf.c | 3 + client/cmdlfgallagher.c | 174 ++++++++++++++++++++++++++++++++++++++++ client/cmdlfgallagher.h | 19 +++++ 4 files changed, 197 insertions(+) create mode 100644 client/cmdlfgallagher.c create mode 100644 client/cmdlfgallagher.h diff --git a/client/Makefile b/client/Makefile index 0f059980a..71def6aae 100644 --- a/client/Makefile +++ b/client/Makefile @@ -206,6 +206,7 @@ CMDSRCS = crapto1/crapto1.c \ cmdlfem4x.c \ cmdlffdx.c \ cmdlfguard.c \ + cmdlfgallagher.c \ cmdlfhid.c \ cmdlfhitag.c \ cmdlfio.c \ diff --git a/client/cmdlf.c b/client/cmdlf.c index 49183f609..a77b86d0d 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -48,6 +48,7 @@ #include "cmdlfpac.h" // for pac menu #include "cmdlfkeri.h" // for keri menu #include "cmdlfverichip.h" // for VeriChip menu +#include "cmdlfgallagher.h" // for GALLAGHER menu bool g_lf_threshold_set = false; @@ -1225,6 +1226,7 @@ int CmdLFfind(const char *Cmd) { if (demodSecurakey() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Securakey ID") "found!"); goto out;} if (demodViking() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Viking ID") "found!"); goto out;} if (demodVisa2k() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Visa2000 ID") "found!"); goto out;} + if (demodGallagher() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("GALLAGHER ID") "found!"); goto out;} // if (demodTI() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Texas Instrument ID") "found!"); goto out;} // if (demodVerichip() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("VeriChip ID") "found!"); goto out;} //if (demodFermax() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Fermax ID") "found!"); goto out;} @@ -1283,6 +1285,7 @@ static command_t CommandTable[] = { {"cotag", CmdLFCOTAG, AlwaysAvailable, "{ COTAG CHIPs... }"}, {"em", CmdLFEM4X, AlwaysAvailable, "{ EM4X CHIPs & RFIDs... }"}, {"fdx", CmdLFFdx, AlwaysAvailable, "{ FDX-B RFIDs... }"}, + {"gallagher", CmdLFGallagher, AlwaysAvailable, "{ GALLAGHER RFIDs... }"}, {"gproxii", CmdLFGuard, AlwaysAvailable, "{ Guardall Prox II RFIDs... }"}, {"hid", CmdLFHID, AlwaysAvailable, "{ HID RFIDs... }"}, {"hitag", CmdLFHitag, AlwaysAvailable, "{ Hitag CHIPs... }"}, diff --git a/client/cmdlfgallagher.c b/client/cmdlfgallagher.c new file mode 100644 index 000000000..650c5886a --- /dev/null +++ b/client/cmdlfgallagher.c @@ -0,0 +1,174 @@ +//----------------------------------------------------------------------------- +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// Low frequency GALLAGHER tag commands +// NRZ, RF/32, 128 bits long (unknown cs) +//----------------------------------------------------------------------------- +#include "cmdlfgallagher.h" + +#include //tolower + +#include "commonutil.h" // ARRAYLEN +#include "common.h" +#include "cmdparser.h" // command_t +#include "comms.h" +#include "ui.h" +#include "cmddata.h" +#include "cmdlf.h" +#include "lfdemod.h" // preamble test +#include "protocols.h" // t55xx defines +#include "cmdlft55xx.h" // clone.. + +static int CmdHelp(const char *Cmd); + +static int usage_lf_gallagher_clone(void) { + PrintAndLogEx(NORMAL, "clone a GALLAGHER tag to a T55x7 tag."); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Usage: lf gallagher clone [h] [b ]"); + PrintAndLogEx(NORMAL, "Options:"); + PrintAndLogEx(NORMAL, " h : this help"); + PrintAndLogEx(NORMAL, " b : raw hex data. 12 bytes max"); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Examples:"); + PrintAndLogEx(NORMAL, " lf gallagher clone b 0FFD5461A9DA1346B2D1AC32 "); + return PM3_SUCCESS; +} + +//see ASK/MAN Demod for what args are accepted +static int CmdGallagherDemod(const char *Cmd) { + + (void)Cmd; + bool st = true; + if (ASKDemod_ext("32 0 0 0 a", false, false, 1, &st) != PM3_SUCCESS) { + PrintAndLogEx(DEBUG, "DEBUG: Error - GALLAGHER: ASKDemod failed"); + return PM3_ESOFT; + } + + size_t size = DemodBufferLen; + int ans = detectGallagher(DemodBuffer, &size); + if (ans < 0) { + if (ans == -1) + PrintAndLogEx(DEBUG, "DEBUG: Error - GALLAGHER: too few bits found"); + else if (ans == -2) + PrintAndLogEx(DEBUG, "DEBUG: Error - GALLAGHER: preamble not found"); + else if (ans == -3) + PrintAndLogEx(DEBUG, "DEBUG: Error - GALLAGHER: Size not correct: %zu", size); + else + PrintAndLogEx(DEBUG, "DEBUG: Error - GALLAGHER: ans: %d", ans); + + return PM3_ESOFT; + } + setDemodBuff(DemodBuffer, 96, ans); + setClockGrid(g_DemodClock, g_DemodStartIdx + (ans * g_DemodClock)); + + //got a good demod + uint32_t raw1 = bytebits_to_byte(DemodBuffer, 32); + uint32_t raw2 = bytebits_to_byte(DemodBuffer + 32, 32); + uint32_t raw3 = bytebits_to_byte(DemodBuffer + 64, 32); + + // preamble then appears to have marker bits of "10" CS? + + PrintAndLogEx(SUCCESS, "GALLAGHER Tag Found -- Raw: %08X%08X%08X", raw1, raw2, raw3); + PrintAndLogEx(INFO, "How the Raw ID is translated by the reader is unknown. Share your trace file on forum"); + return PM3_SUCCESS; +} + +static int CmdGallagherRead(const char *Cmd) { + lf_read(true, 4096 * 2 + 20); + return CmdGallagherDemod(Cmd); +} + +static int CmdGallagherClone(const char *Cmd) { + + uint32_t blocks[4]; + bool errors = false; + uint8_t cmdp = 0; + int datalen = 0; + + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { + case 'h': + return usage_lf_gallagher_clone(); + case 'b': { + // skip first block, 3*4 = 12 bytes left + uint8_t rawhex[12] = {0}; + int res = param_gethex_to_eol(Cmd, cmdp + 1, rawhex, sizeof(rawhex), &datalen); + if ( res != 0 ) + errors = true; + + for(uint8_t i = 1; i < ARRAYLEN(blocks); i++) { + blocks[i] = bytes_to_num(rawhex + ( (i - 1) * 4 ), sizeof(uint32_t)); + } + cmdp += 2; + break; + } + default: + PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } + } + + if (errors || cmdp == 0) return usage_lf_gallagher_clone(); + + //Pac - compat mode, NRZ, data rate 40, 3 data blocks + blocks[0] = T55x7_MODULATION_MANCHESTER | T55x7_BITRATE_RF_32 | 3 << T55x7_MAXBLOCK_SHIFT; + + PrintAndLogEx(INFO, "Preparing to clone Gallagher to T55x7 with raw hex"); + print_blocks(blocks, ARRAYLEN(blocks)); + + return clone_t55xx_tag(blocks, ARRAYLEN(blocks)); +} + +static int CmdGallagherSim(const char *Cmd) { + + // ASK/MAN sim. + PrintAndLogEx(INFO, " To be implemented, feel free to contribute!"); + return PM3_SUCCESS; +} + +static command_t CommandTable[] = { + {"help", CmdHelp, AlwaysAvailable, "This help"}, + {"demod", CmdGallagherDemod, AlwaysAvailable, "Demodulate an GALLAGHER tag from the GraphBuffer"}, + {"read", CmdGallagherRead, IfPm3Lf, "Attempt to read and extract tag data from the antenna"}, + {"clone", CmdGallagherClone, IfPm3Lf, "clone GALLAGHER tag"}, + {"sim", CmdGallagherSim, IfPm3Lf, "simulate GALLAGHER tag"}, + {NULL, NULL, NULL, NULL} +}; + +static int CmdHelp(const char *Cmd) { + (void)Cmd; // Cmd is not used so far + CmdsHelp(CommandTable); + return PM3_SUCCESS; +} + +int CmdLFGallagher(const char *Cmd) { + clearCommandBuffer(); + return CmdsParse(CommandTable, Cmd); +} + +// by marshmellow +// find PAC preamble in already demoded data +int detectGallagher(uint8_t *dest, size_t *size) { + if (*size < 96) return -1; //make sure buffer has data + size_t startIdx = 0; + uint8_t preamble[] = { + 0, 0, 0, 0, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 0, + 0, 1, 1, 0, 0 ,0 ,0 ,1 + }; + if (!preambleSearch(dest, preamble, sizeof(preamble), size, &startIdx)) + return -2; //preamble not found + if (*size != 96) return -3; //wrong demoded size + //return start position + return (int)startIdx; +} + +int demodGallagher(void) { + return CmdGallagherDemod(""); +} + diff --git a/client/cmdlfgallagher.h b/client/cmdlfgallagher.h new file mode 100644 index 000000000..90729b152 --- /dev/null +++ b/client/cmdlfgallagher.h @@ -0,0 +1,19 @@ +//----------------------------------------------------------------------------- +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// Low frequency GALLAGHER tag commands +//----------------------------------------------------------------------------- +#ifndef CMDLFGALLAGHER_H__ +#define CMDLFGALLAGHER_H__ + +#include "common.h" + +int CmdLFGallagher(const char *Cmd); + +int demodGallagher(void); +int detectGallagher(uint8_t *dest, size_t *size); +#endif + From 0a50d8f8450ef60d4af8ddb3cd610520a61e1b87 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 8 Oct 2019 22:02:02 +0200 Subject: [PATCH 0865/1854] adjustments --- client/cmdlfgallagher.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/cmdlfgallagher.c b/client/cmdlfgallagher.c index 650c5886a..051973a28 100644 --- a/client/cmdlfgallagher.c +++ b/client/cmdlfgallagher.c @@ -42,7 +42,7 @@ static int CmdGallagherDemod(const char *Cmd) { (void)Cmd; bool st = true; - if (ASKDemod_ext("32 0 0 0 a", false, false, 1, &st) != PM3_SUCCESS) { + if (ASKDemod_ext("32 0 0 0", false, false, 1, &st) != PM3_SUCCESS) { PrintAndLogEx(DEBUG, "DEBUG: Error - GALLAGHER: ASKDemod failed"); return PM3_ESOFT; } @@ -69,7 +69,7 @@ static int CmdGallagherDemod(const char *Cmd) { uint32_t raw2 = bytebits_to_byte(DemodBuffer + 32, 32); uint32_t raw3 = bytebits_to_byte(DemodBuffer + 64, 32); - // preamble then appears to have marker bits of "10" CS? + // preamble CS? PrintAndLogEx(SUCCESS, "GALLAGHER Tag Found -- Raw: %08X%08X%08X", raw1, raw2, raw3); PrintAndLogEx(INFO, "How the Raw ID is translated by the reader is unknown. Share your trace file on forum"); From 1e5e930bf05c539fe8a02d49a1d865c084884384 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 8 Oct 2019 22:04:15 +0200 Subject: [PATCH 0866/1854] clean --- common/lfdemod.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/lfdemod.c b/common/lfdemod.c index 8852b9c00..f555c8f65 100644 --- a/common/lfdemod.c +++ b/common/lfdemod.c @@ -1479,10 +1479,10 @@ uint16_t manrawdecode(uint8_t *bits, size_t *size, uint8_t invert, uint8_t *alig int errCnt = 0, bestErr = 1000; uint16_t bitnum = 0, maxBits = 512, bestRun = 0; - size_t i, k; + size_t i; //find correct start position [alignment] - for (k = 0; k < 2; k++) { + for (uint8_t k = 0; k < 2; k++) { for (i = k; i < *size - 1; i += 2) { From ab2078f0a3fed12f076dee650b01cecd1bb32ddd Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 8 Oct 2019 22:05:23 +0200 Subject: [PATCH 0867/1854] gallagher trace --- traces/gallagher.pm3 | 39999 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 39999 insertions(+) create mode 100644 traces/gallagher.pm3 diff --git a/traces/gallagher.pm3 b/traces/gallagher.pm3 new file mode 100644 index 000000000..d6e58a707 --- /dev/null +++ b/traces/gallagher.pm3 @@ -0,0 +1,39999 @@ +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +66 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +87 +14 +-51 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +55 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +114 +37 +-31 +-92 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +5 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +96 +21 +-46 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +4 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +93 +18 +-49 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +0 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +113 +105 +98 +91 +86 +80 +74 +68 +62 +58 +57 +53 +45 +40 +-31 +-92 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-33 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +79 +5 +-60 +-118 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-9 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +92 +17 +-49 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-4 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +94 +19 +-48 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-3 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +91 +16 +-50 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-4 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +90 +15 +-52 +-110 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-1 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +89 +15 +-52 +-110 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-3 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +87 +12 +-54 +-112 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-3 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +90 +15 +-51 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-8 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +100 +24 +-44 +-103 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +88 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +117 +108 +102 +95 +19 +-48 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +77 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +119 +111 +105 +96 +20 +-47 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +87 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +124 +115 +103 +91 +15 +-52 +-111 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +75 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +115 +106 +99 +93 +17 +-49 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +85 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +90 +17 +-49 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +53 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +116 +38 +-31 +-92 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-1 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +114 +101 +95 +89 +82 +76 +69 +63 +57 +52 +47 +42 +41 +-29 +-90 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-36 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +77 +4 +-61 +-119 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +84 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +90 +16 +-49 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +59 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +115 +37 +-32 +-92 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +4 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +89 +14 +-52 +-110 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +3 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +125 +112 +101 +92 +84 +77 +71 +67 +62 +57 +53 +45 +38 +37 +-33 +-94 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-28 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +71 +-2 +-66 +-123 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +90 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +122 +112 +103 +94 +18 +-49 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +79 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +126 +118 +112 +104 +96 +20 +-47 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +80 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +88 +15 +-50 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +54 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +126 +113 +105 +99 +92 +86 +76 +68 +65 +62 +57 +51 +47 +-23 +-86 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-34 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +77 +4 +-61 +-118 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-4 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +88 +13 +-53 +-111 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +91 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +117 +108 +99 +93 +17 +-50 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-13 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +86 +12 +-54 +-112 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +90 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +119 +112 +106 +96 +20 +-46 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +82 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +91 +17 +-49 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +47 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +115 +38 +-31 +-92 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +3 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +96 +21 +-46 +-105 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-1 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +123 +113 +103 +95 +84 +72 +63 +60 +57 +55 +51 +45 +42 +36 +-33 +-95 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +67 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +87 +14 +-51 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +50 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +118 +109 +101 +94 +87 +80 +73 +66 +59 +53 +48 +42 +-28 +-90 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-31 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +83 +10 +-56 +-114 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +86 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +120 +110 +101 +92 +16 +-50 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +83 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +90 +17 +-49 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +48 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +111 +34 +-34 +-94 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +2 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +122 +105 +93 +84 +79 +75 +73 +68 +66 +62 +58 +50 +40 +34 +-35 +-97 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-27 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +83 +9 +-57 +-114 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +91 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +123 +113 +105 +93 +17 +-49 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +80 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +120 +111 +102 +93 +17 +-50 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-18 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +81 +8 +-58 +-116 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +93 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +90 +16 +-49 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +52 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +113 +103 +94 +89 +85 +77 +69 +64 +59 +54 +50 +45 +-25 +-87 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +65 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +124 +115 +104 +90 +15 +-52 +-111 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-9 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +88 +13 +-53 +-112 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +92 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +123 +114 +105 +97 +21 +-47 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +77 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +88 +15 +-51 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +55 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +118 +40 +-29 +-90 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +3 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +124 +113 +105 +97 +89 +80 +72 +68 +64 +59 +54 +46 +42 +37 +-33 +-94 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-32 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +83 +9 +-57 +-115 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +88 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +121 +110 +100 +91 +15 +-52 +-111 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +84 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +122 +112 +101 +92 +17 +-50 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-20 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +89 +14 +-52 +-111 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +83 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +91 +17 +-49 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +52 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +121 +43 +-27 +-88 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +3 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +93 +18 +-49 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +6 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +125 +114 +104 +93 +80 +73 +67 +63 +60 +57 +53 +48 +44 +38 +-33 +-94 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-31 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +78 +4 +-61 +-118 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +83 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +90 +17 +-49 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +47 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +116 +106 +96 +88 +83 +77 +72 +66 +60 +55 +53 +47 +-23 +-85 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +67 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +84 +12 +-53 +-110 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +49 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +115 +38 +-31 +-92 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +1 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +96 +21 +-46 +-105 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +0 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +95 +20 +-47 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-3 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +125 +111 +103 +93 +86 +79 +72 +65 +60 +55 +51 +46 +43 +36 +-33 +-95 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-31 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +77 +3 +-62 +-119 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-4 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +92 +17 +-49 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +0 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +93 +19 +-48 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +0 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +83 +9 +-57 +-115 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +2 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +94 +19 +-48 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-3 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +90 +16 +-51 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-3 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +92 +17 +-50 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-2 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +91 +17 +-50 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +1 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +92 +17 +-50 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +93 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +115 +100 +88 +83 +9 +-57 +-116 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +79 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +124 +116 +110 +100 +92 +17 +-50 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +84 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +125 +114 +101 +87 +12 +-55 +-113 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +85 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +123 +115 +104 +95 +18 +-49 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +78 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +91 +17 +-49 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +54 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +116 +39 +-30 +-91 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +0 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +126 +110 +97 +91 +85 +82 +75 +69 +63 +59 +53 +51 +44 +40 +-30 +-91 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-32 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +78 +5 +-61 +-118 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +86 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +86 +13 +-51 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +57 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +121 +43 +-26 +-87 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-1 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +97 +22 +-45 +-104 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-12 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +122 +110 +101 +93 +84 +77 +70 +65 +58 +53 +51 +49 +45 +38 +-31 +-93 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-33 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +81 +7 +-58 +-116 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +87 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +118 +111 +104 +95 +20 +-47 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +83 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +126 +117 +111 +103 +98 +22 +-45 +-105 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +71 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +93 +19 +-47 +-105 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +48 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +115 +104 +98 +91 +84 +77 +71 +64 +60 +55 +49 +48 +-23 +-85 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-29 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +80 +6 +-59 +-117 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-7 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +90 +15 +-51 +-110 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +90 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +120 +112 +103 +94 +18 +-49 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-17 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +86 +12 +-54 +-112 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +89 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +124 +114 +101 +88 +12 +-54 +-113 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +77 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +91 +17 +-48 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +51 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +110 +33 +-36 +-96 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +3 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +97 +22 +-45 +-104 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-3 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +122 +110 +98 +90 +83 +79 +71 +65 +57 +47 +40 +38 +35 +34 +-35 +-95 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +75 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +90 +16 +-50 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +53 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +120 +107 +99 +92 +87 +83 +79 +75 +69 +60 +50 +43 +39 +-31 +-92 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-23 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +84 +10 +-56 +-114 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +89 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +121 +112 +101 +92 +17 +-50 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +75 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +86 +13 +-52 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +48 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +121 +44 +-25 +-87 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +6 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +112 +96 +88 +81 +76 +73 +66 +60 +56 +51 +47 +42 +37 +-32 +-94 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-39 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +74 +1 +-64 +-121 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +90 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +122 +113 +103 +95 +19 +-48 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +78 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +123 +112 +103 +95 +19 +-48 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-15 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +88 +13 +-53 +-111 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +92 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +94 +20 +-45 +-103 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +51 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +120 +111 +102 +94 +85 +75 +67 +63 +60 +55 +50 +46 +-24 +-87 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +69 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +124 +111 +97 +90 +15 +-51 +-111 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-9 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +88 +13 +-53 +-111 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +89 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +112 +101 +94 +89 +13 +-53 +-112 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +82 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +89 +15 +-49 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +50 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +117 +40 +-29 +-90 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +4 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +120 +111 +101 +93 +88 +81 +75 +69 +61 +55 +52 +50 +46 +41 +-29 +-91 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-34 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +79 +6 +-60 +-117 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +90 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +115 +106 +97 +91 +16 +-51 +-110 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +85 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +121 +111 +100 +93 +17 +-50 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-23 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +91 +17 +-50 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +86 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +90 +17 +-49 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +53 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +116 +39 +-30 +-91 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-1 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +95 +20 +-47 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +0 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +123 +113 +103 +93 +84 +78 +71 +65 +59 +54 +49 +45 +42 +38 +-32 +-94 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-32 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +79 +6 +-60 +-117 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +81 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +92 +19 +-47 +-105 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +48 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +119 +104 +95 +89 +83 +78 +73 +67 +60 +54 +50 +47 +-23 +-85 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +68 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +85 +13 +-52 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +49 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +115 +38 +-31 +-91 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +4 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +97 +22 +-45 +-104 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +0 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +87 +13 +-53 +-111 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-3 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +123 +111 +100 +94 +86 +77 +71 +64 +60 +55 +52 +48 +41 +32 +-37 +-98 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-31 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +79 +5 +-60 +-118 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-9 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +91 +16 +-50 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-4 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +93 +18 +-49 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-2 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +94 +19 +-48 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-4 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +92 +17 +-49 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-3 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +90 +16 +-51 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-5 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +96 +21 +-46 +-105 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-6 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +88 +13 +-53 +-111 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +0 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +86 +11 +-54 +-112 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +94 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +120 +111 +103 +93 +18 +-49 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +85 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +114 +100 +90 +15 +-52 +-111 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +80 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +125 +118 +112 +104 +93 +17 +-50 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +82 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +121 +111 +101 +91 +15 +-51 +-111 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +75 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +90 +17 +-49 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +54 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +115 +38 +-30 +-91 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +10 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +125 +115 +104 +92 +83 +75 +71 +66 +62 +58 +52 +44 +38 +35 +-34 +-96 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-26 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +78 +5 +-60 +-117 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +79 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +92 +19 +-47 +-105 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +53 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +120 +42 +-28 +-89 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-5 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +94 +19 +-48 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-10 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +126 +113 +101 +92 +87 +80 +73 +66 +61 +54 +48 +45 +41 +40 +-30 +-91 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-28 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +79 +6 +-59 +-117 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +88 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +117 +111 +103 +95 +19 +-48 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +85 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +117 +106 +97 +89 +14 +-53 +-111 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +84 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +88 +15 +-50 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +57 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +118 +103 +93 +86 +81 +76 +70 +67 +61 +56 +50 +46 +-25 +-87 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-31 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +73 +0 +-65 +-121 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-9 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +93 +18 +-49 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +92 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +124 +112 +98 +91 +15 +-51 +-110 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-22 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +90 +15 +-50 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +80 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +124 +112 +99 +89 +14 +-53 +-112 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +81 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +89 +15 +-51 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +59 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +115 +38 +-31 +-92 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +5 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +94 +19 +-48 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +0 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +122 +109 +101 +95 +90 +83 +75 +67 +57 +50 +46 +44 +42 +39 +-31 +-92 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +68 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +85 +12 +-53 +-110 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +56 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +119 +108 +99 +91 +83 +75 +69 +63 +57 +54 +49 +42 +-28 +-90 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-27 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +85 +11 +-55 +-113 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +85 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +121 +113 +100 +88 +12 +-54 +-113 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +81 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +86 +13 +-52 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +57 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +120 +42 +-27 +-88 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +7 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +118 +103 +89 +79 +74 +70 +67 +64 +60 +55 +52 +47 +40 +-30 +-92 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-35 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +76 +3 +-62 +-119 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +94 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +118 +108 +100 +95 +19 +-48 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +80 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +121 +112 +102 +93 +18 +-49 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-10 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +90 +15 +-51 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +95 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +91 +17 +-49 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +51 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +118 +109 +99 +87 +79 +74 +70 +64 +56 +51 +47 +43 +-28 +-90 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +76 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +126 +112 +98 +86 +81 +7 +-59 +-117 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-11 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +86 +12 +-54 +-112 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +85 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +113 +101 +95 +19 +-48 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +84 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +91 +18 +-48 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +56 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +115 +38 +-31 +-91 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +1 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +115 +103 +95 +87 +78 +73 +66 +60 +56 +49 +45 +40 +36 +-33 +-95 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-27 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +80 +6 +-60 +-117 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +92 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +116 +105 +97 +92 +16 +-50 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +76 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +120 +113 +103 +95 +19 +-48 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-13 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +79 +6 +-60 +-117 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +89 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +93 +20 +-46 +-104 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +57 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +109 +33 +-35 +-96 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +11 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +96 +21 +-45 +-105 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +1 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +115 +99 +88 +82 +77 +72 +67 +60 +54 +47 +46 +41 +38 +-32 +-93 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-30 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +81 +7 +-58 +-115 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +85 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +92 +19 +-47 +-105 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +52 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +119 +109 +101 +92 +85 +78 +75 +69 +62 +56 +50 +44 +-26 +-89 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +69 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +86 +13 +-52 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +50 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +121 +43 +-26 +-87 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-5 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +95 +20 +-47 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +2 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +92 +17 +-50 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-4 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +123 +110 +99 +91 +83 +75 +69 +65 +62 +57 +51 +47 +43 +40 +-30 +-91 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-28 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +77 +3 +-62 +-120 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-7 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +91 +16 +-49 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +2 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +92 +18 +-49 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-2 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +93 +18 +-49 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-8 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +92 +17 +-49 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-2 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +88 +14 +-52 +-111 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-2 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +95 +20 +-47 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-5 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +92 +17 +-50 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-1 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +83 +8 +-57 +-115 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +89 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +125 +115 +106 +98 +22 +-45 +-105 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +74 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +124 +116 +110 +104 +96 +20 +-47 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +80 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +119 +113 +103 +94 +18 +-49 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +85 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +124 +114 +109 +102 +95 +19 +-48 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +82 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +88 +15 +-51 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +56 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +106 +29 +-39 +-99 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +15 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +118 +102 +95 +88 +82 +74 +68 +63 +58 +52 +47 +42 +38 +-32 +-93 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-32 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +79 +5 +-60 +-117 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +89 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +90 +16 +-49 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +57 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +116 +39 +-30 +-90 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +8 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +92 +17 +-50 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-5 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +121 +109 +98 +91 +84 +77 +71 +65 +59 +54 +49 +44 +35 +31 +-38 +-98 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-32 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +81 +8 +-58 +-116 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +82 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +119 +109 +102 +96 +20 +-46 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +82 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +124 +114 +107 +100 +95 +20 +-47 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +80 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +90 +16 +-50 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +59 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +121 +113 +106 +101 +95 +87 +83 +77 +71 +60 +50 +43 +40 +-30 +-92 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-24 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +76 +3 +-62 +-120 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-7 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +85 +11 +-55 +-113 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +90 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +120 +111 +101 +92 +17 +-50 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-9 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +89 +14 +-52 +-111 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +88 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +124 +113 +106 +97 +22 +-45 +-105 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +78 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +89 +15 +-50 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +58 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +117 +40 +-29 +-90 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +4 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +96 +21 +-45 +-104 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-2 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +119 +108 +99 +91 +83 +75 +67 +63 +60 +57 +51 +45 +37 +32 +-37 +-98 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +72 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +80 +7 +-57 +-114 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +55 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +123 +112 +105 +99 +92 +85 +79 +72 +66 +60 +51 +42 +37 +-33 +-95 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-36 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +81 +8 +-58 +-116 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +89 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +121 +112 +103 +95 +19 +-48 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +79 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +91 +17 +-49 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +51 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +120 +42 +-27 +-88 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-1 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +125 +114 +105 +96 +87 +79 +73 +64 +58 +55 +50 +47 +43 +38 +-32 +-93 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-34 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +80 +7 +-59 +-116 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +84 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +119 +109 +95 +86 +11 +-56 +-114 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +83 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +122 +116 +107 +97 +21 +-46 +-105 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-17 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +84 +9 +-57 +-115 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +83 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +94 +20 +-46 +-104 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +50 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +118 +108 +99 +88 +77 +68 +63 +60 +57 +56 +51 +46 +-25 +-88 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +74 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +117 +107 +97 +92 +16 +-50 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-27 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +86 +11 +-55 +-112 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +89 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +120 +106 +97 +91 +15 +-51 +-110 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +80 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +92 +18 +-48 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +46 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +117 +39 +-30 +-91 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +1 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +114 +102 +95 +86 +80 +73 +67 +61 +53 +48 +42 +40 +38 +-32 +-93 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-28 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +79 +5 +-60 +-118 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +90 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +124 +113 +100 +89 +14 +-52 +-111 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +82 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +119 +110 +101 +93 +17 +-50 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-17 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +86 +12 +-54 +-113 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +91 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +90 +16 +-49 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +58 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +117 +39 +-30 +-91 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +6 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +89 +14 +-52 +-110 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +2 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +111 +103 +93 +85 +78 +71 +65 +58 +56 +51 +47 +43 +39 +-31 +-93 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-38 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +80 +7 +-59 +-116 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +87 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +90 +16 +-49 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +51 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +113 +107 +100 +91 +86 +79 +74 +66 +57 +51 +47 +45 +-25 +-87 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +73 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +88 +15 +-51 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +45 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +119 +41 +-29 +-89 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +4 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +97 +22 +-46 +-105 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-3 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +92 +17 +-49 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-1 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +124 +112 +102 +93 +84 +78 +71 +66 +59 +54 +49 +44 +39 +39 +-31 +-92 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-33 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +76 +3 +-62 +-120 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-3 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +92 +17 +-50 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-9 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +83 +9 +-57 +-115 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +3 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +99 +23 +-44 +-104 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +1 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +92 +17 +-50 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-3 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +89 +14 +-52 +-110 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-3 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +91 +16 +-50 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-1 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +92 +17 +-50 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +1 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +89 +15 +-52 +-110 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +94 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +126 +114 +104 +96 +20 +-47 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +76 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +121 +111 +103 +95 +19 +-48 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +71 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +119 +111 +100 +92 +16 +-51 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +85 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +120 +111 +101 +94 +18 +-49 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +81 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +88 +15 +-51 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +54 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +116 +39 +-30 +-90 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +7 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +125 +112 +104 +95 +84 +72 +65 +61 +57 +55 +51 +50 +45 +41 +-29 +-90 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-38 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +82 +8 +-57 +-115 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +80 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +93 +18 +-47 +-105 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +55 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +110 +33 +-35 +-96 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-1 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +101 +25 +-42 +-102 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +1 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +123 +110 +98 +91 +87 +81 +75 +66 +56 +50 +46 +44 +41 +37 +-32 +-94 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-33 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +81 +7 +-58 +-116 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +80 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +120 +113 +104 +98 +22 +-45 +-105 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +80 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +121 +111 +103 +94 +18 +-49 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +83 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +89 +15 +-50 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +51 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +120 +109 +101 +96 +87 +77 +65 +58 +54 +51 +48 +48 +-23 +-85 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-38 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +82 +8 +-58 +-115 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-5 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +90 +15 +-51 +-110 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +89 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +122 +112 +103 +95 +19 +-48 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-22 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +85 +11 +-55 +-113 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +86 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +121 +112 +102 +95 +19 +-48 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +83 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +88 +15 +-51 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +53 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +118 +40 +-29 +-89 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +2 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +100 +25 +-43 +-103 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +0 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +119 +109 +101 +93 +85 +77 +74 +71 +66 +57 +48 +38 +30 +29 +-40 +-100 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +73 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +88 +15 +-51 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +47 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +114 +103 +96 +91 +84 +78 +71 +66 +62 +57 +48 +39 +-32 +-93 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-27 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +85 +11 +-54 +-113 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +89 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +119 +109 +101 +95 +19 +-48 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +78 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +88 +15 +-50 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +59 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +119 +42 +-27 +-88 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +5 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +123 +111 +100 +91 +84 +78 +74 +71 +65 +60 +54 +49 +43 +37 +-33 +-94 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-31 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +77 +4 +-61 +-118 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +82 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +119 +114 +103 +91 +15 +-52 +-111 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +82 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +120 +113 +104 +97 +21 +-46 +-105 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-18 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +79 +5 +-60 +-117 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +93 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +92 +19 +-48 +-105 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +59 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +118 +110 +103 +95 +87 +78 +71 +66 +59 +56 +51 +47 +-23 +-86 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +74 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +120 +111 +105 +98 +93 +17 +-49 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-16 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +88 +13 +-53 +-111 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +81 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +124 +114 +101 +87 +12 +-54 +-113 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +80 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +91 +18 +-48 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +50 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +117 +40 +-29 +-90 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +3 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +126 +117 +107 +95 +82 +74 +68 +64 +61 +57 +53 +50 +44 +39 +-31 +-92 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-32 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +78 +5 +-60 +-117 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +87 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +119 +110 +100 +94 +18 +-48 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +82 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +121 +107 +93 +83 +8 +-58 +-116 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-15 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +89 +15 +-51 +-110 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +88 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +90 +17 +-48 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +52 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +119 +40 +-29 +-89 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +8 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +96 +21 +-46 +-105 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-4 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +126 +110 +99 +90 +83 +75 +68 +62 +59 +56 +51 +48 +44 +37 +-33 +-94 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-31 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +77 +5 +-60 +-118 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +80 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +90 +17 +-49 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +56 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +118 +106 +97 +90 +82 +76 +71 +69 +63 +56 +51 +47 +-24 +-87 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +75 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +83 +10 +-55 +-112 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +50 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +120 +43 +-27 +-89 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-3 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +97 +22 +-45 +-105 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-6 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +93 +18 +-49 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-5 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +120 +112 +102 +94 +85 +74 +66 +62 +59 +57 +53 +48 +44 +36 +-34 +-95 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-26 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +83 +10 +-56 +-114 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-5 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +94 +19 +-48 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-8 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +94 +19 +-48 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-1 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +93 +18 +-49 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-3 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +92 +17 +-50 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +0 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +95 +20 +-47 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-2 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +91 +16 +-50 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-8 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +94 +19 +-48 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-1 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +95 +20 +-46 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +87 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +118 +108 +98 +91 +15 +-52 +-111 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +87 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +122 +107 +96 +89 +14 +-53 +-112 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +83 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +124 +110 +100 +91 +15 +-51 +-111 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +79 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +117 +107 +98 +90 +15 +-52 +-111 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +85 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +89 +16 +-49 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +55 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +117 +40 +-29 +-89 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +9 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +124 +112 +103 +94 +86 +81 +75 +69 +63 +56 +49 +47 +46 +42 +-28 +-90 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-38 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +79 +6 +-60 +-117 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +82 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +91 +17 +-49 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +56 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +119 +41 +-28 +-88 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +1 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +95 +20 +-47 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-4 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +123 +111 +101 +92 +83 +77 +71 +66 +61 +55 +51 +45 +41 +40 +-29 +-91 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-30 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +75 +2 +-63 +-119 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +91 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +125 +114 +105 +97 +93 +17 +-49 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +74 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +120 +110 +102 +94 +18 +-49 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +81 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +86 +13 +-52 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +52 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +121 +111 +101 +94 +82 +70 +62 +60 +57 +54 +53 +49 +-22 +-84 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-29 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +79 +6 +-59 +-116 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-6 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +92 +17 +-49 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +84 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +124 +112 +101 +92 +16 +-50 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-15 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +86 +12 +-53 +-111 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +88 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +117 +107 +100 +95 +18 +-49 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +87 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +91 +18 +-48 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +52 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +108 +31 +-36 +-97 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-1 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +100 +24 +-43 +-102 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-4 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +123 +110 +99 +90 +81 +74 +70 +67 +61 +57 +48 +45 +43 +42 +-28 +-90 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +58 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +89 +15 +-50 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +55 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +117 +108 +101 +93 +85 +79 +71 +64 +57 +50 +46 +44 +-27 +-88 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-32 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +84 +10 +-56 +-114 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +81 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +122 +115 +106 +98 +21 +-46 +-105 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +81 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +89 +16 +-50 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +58 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +118 +41 +-28 +-90 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-1 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +123 +113 +106 +101 +91 +83 +73 +62 +55 +53 +50 +46 +42 +39 +-31 +-92 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-32 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +78 +5 +-60 +-117 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +89 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +115 +101 +92 +16 +-51 +-110 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +88 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +119 +107 +93 +83 +8 +-58 +-116 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-8 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +90 +15 +-51 +-110 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +88 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +92 +18 +-48 +-105 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +53 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +120 +108 +94 +86 +80 +75 +69 +64 +60 +58 +54 +49 +-22 +-84 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +68 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +126 +118 +110 +100 +91 +15 +-51 +-110 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-14 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +87 +13 +-53 +-111 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +83 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +120 +111 +99 +90 +15 +-52 +-111 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +85 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +85 +12 +-52 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +53 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +117 +40 +-29 +-89 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +4 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +114 +102 +97 +89 +78 +67 +57 +51 +48 +46 +46 +46 +43 +-27 +-89 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-29 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +78 +5 +-61 +-118 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +83 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +118 +109 +100 +93 +17 +-50 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +85 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +123 +117 +109 +100 +24 +-44 +-104 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-16 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +83 +9 +-56 +-114 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +92 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +92 +18 +-48 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +49 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +119 +42 +-28 +-89 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +4 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +101 +25 +-43 +-102 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-12 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +123 +110 +99 +89 +81 +74 +69 +63 +58 +53 +51 +47 +41 +37 +-33 +-94 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-30 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +81 +7 +-58 +-116 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +86 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +90 +17 +-49 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +55 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +121 +110 +102 +91 +82 +74 +68 +63 +61 +57 +54 +44 +-27 +-89 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +73 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +81 +9 +-56 +-113 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +56 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +117 +40 +-30 +-91 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +7 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +90 +15 +-51 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-4 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +97 +21 +-46 +-105 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-6 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +124 +110 +95 +86 +79 +75 +71 +68 +62 +59 +52 +45 +41 +40 +-30 +-92 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-36 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +80 +6 +-60 +-117 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-5 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +92 +17 +-49 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-2 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +92 +17 +-49 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-1 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +93 +18 +-49 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-2 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +92 +17 +-49 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-9 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +94 +19 +-48 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +0 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +91 +17 +-50 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +0 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +93 +19 +-48 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-5 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +94 +19 +-48 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +89 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +125 +114 +101 +86 +11 +-56 +-114 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +87 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +121 +111 +103 +93 +17 +-50 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +77 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +118 +108 +101 +94 +18 +-48 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +84 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +118 +108 +100 +88 +13 +-54 +-113 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +86 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +89 +16 +-49 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +53 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +119 +41 +-28 +-89 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +2 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +126 +111 +95 +86 +79 +74 +71 +69 +64 +57 +51 +45 +43 +40 +-30 +-92 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-29 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +75 +2 +-63 +-120 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +89 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +92 +19 +-47 +-105 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +55 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +114 +37 +-32 +-92 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +7 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +97 +21 +-45 +-105 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-4 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +118 +106 +97 +92 +87 +81 +71 +65 +59 +53 +50 +48 +43 +38 +-32 +-93 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-29 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +79 +6 +-60 +-117 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +86 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +123 +111 +101 +93 +17 +-50 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +84 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +121 +114 +105 +97 +21 +-47 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +76 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +90 +17 +-49 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +56 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +125 +115 +108 +102 +95 +88 +80 +74 +66 +62 +56 +51 +45 +-26 +-88 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-31 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +82 +8 +-57 +-115 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-11 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +88 +13 +-53 +-111 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +91 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +122 +113 +101 +88 +13 +-54 +-113 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-9 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +86 +12 +-55 +-113 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +84 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +121 +113 +104 +96 +20 +-47 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +75 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +91 +17 +-49 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +52 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +112 +35 +-33 +-94 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +1 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +95 +20 +-47 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +1 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +125 +112 +100 +93 +84 +78 +69 +63 +57 +52 +50 +47 +42 +37 +-32 +-94 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +70 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +86 +13 +-52 +-110 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +50 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +113 +104 +98 +90 +82 +76 +70 +63 +60 +55 +48 +41 +-30 +-91 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-24 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +85 +11 +-55 +-113 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +88 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +119 +109 +101 +93 +18 +-49 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +81 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +91 +17 +-49 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +42 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +118 +41 +-28 +-89 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +2 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +123 +112 +103 +96 +86 +74 +67 +63 +59 +57 +55 +51 +42 +34 +-36 +-97 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-28 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +79 +6 +-60 +-117 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +85 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +117 +109 +102 +97 +21 +-46 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +82 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +122 +111 +103 +92 +16 +-51 +-110 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-15 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +90 +15 +-52 +-110 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +85 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +91 +17 +-48 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +57 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +116 +106 +98 +90 +83 +75 +68 +63 +60 +56 +51 +47 +-24 +-86 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +66 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +115 +104 +97 +92 +16 +-51 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-12 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +90 +15 +-51 +-110 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +87 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +122 +112 +100 +89 +14 +-53 +-111 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +87 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +86 +14 +-51 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +60 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +119 +41 +-28 +-89 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +7 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +126 +109 +98 +92 +83 +79 +72 +67 +60 +54 +51 +48 +43 +38 +-32 +-93 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-32 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +83 +9 +-57 +-115 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +83 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +122 +111 +102 +93 +17 +-50 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +85 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +124 +112 +101 +93 +17 +-50 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-13 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +90 +15 +-51 +-110 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +84 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +93 +20 +-46 +-104 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +55 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +118 +40 +-29 +-90 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +4 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +97 +22 +-45 +-104 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +2 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +121 +112 +102 +93 +85 +81 +75 +69 +59 +53 +48 +43 +39 +34 +-35 +-97 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-32 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +78 +5 +-60 +-117 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +91 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +91 +18 +-48 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +57 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +116 +105 +95 +90 +85 +81 +75 +67 +60 +53 +48 +43 +-27 +-89 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +74 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +85 +12 +-52 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +48 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +119 +42 +-28 +-89 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-4 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +100 +25 +-43 +-102 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-1 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +95 +20 +-46 +-105 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-5 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +118 +108 +98 +89 +83 +77 +70 +64 +58 +54 +49 +47 +43 +39 +-30 +-92 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-34 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +80 +7 +-58 +-115 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-8 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +88 +14 +-53 +-111 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-2 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +92 +17 +-49 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-2 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +95 +20 +-47 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-3 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +95 +21 +-46 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-4 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +92 +17 +-50 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-2 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +91 +16 +-50 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-4 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +87 +13 +-53 +-111 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +0 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +93 +18 +-49 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +87 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +119 +109 +103 +96 +20 +-47 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +81 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +121 +111 +104 +95 +20 +-47 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +78 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +117 +107 +99 +92 +17 +-50 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +86 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +114 +104 +95 +89 +14 +-53 +-111 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +83 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +90 +16 +-49 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +56 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +114 +36 +-33 +-93 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +7 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +124 +110 +101 +94 +88 +82 +74 +65 +59 +55 +52 +48 +44 +40 +-30 +-91 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-32 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +82 +9 +-57 +-115 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +88 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +91 +18 +-48 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +55 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +114 +37 +-32 +-93 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +2 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +96 +21 +-46 +-104 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +0 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +123 +113 +103 +91 +78 +70 +66 +62 +60 +57 +53 +46 +37 +33 +-36 +-97 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-31 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +83 +9 +-56 +-114 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +87 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +119 +111 +103 +96 +20 +-47 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +87 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +124 +113 +103 +97 +21 +-46 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +73 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +87 +14 +-51 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +56 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +124 +114 +107 +99 +92 +85 +79 +73 +66 +63 +57 +48 +43 +-27 +-89 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-24 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +79 +6 +-59 +-116 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-9 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +92 +17 +-50 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +96 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +123 +112 +105 +97 +21 +-46 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-13 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +86 +12 +-54 +-113 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +93 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +119 +111 +101 +91 +15 +-51 +-110 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +81 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +84 +11 +-54 +-111 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +56 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +115 +38 +-31 +-92 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +3 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +97 +22 +-45 +-104 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +0 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +121 +104 +94 +86 +80 +76 +73 +67 +62 +58 +52 +48 +44 +38 +-32 +-93 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +73 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +88 +14 +-51 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +48 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +117 +108 +98 +93 +89 +83 +72 +66 +59 +49 +42 +39 +-31 +-93 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-32 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +83 +9 +-57 +-114 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +86 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +124 +114 +105 +98 +93 +18 +-49 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +81 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +92 +18 +-48 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +52 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +117 +39 +-30 +-91 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +5 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +125 +113 +103 +96 +87 +84 +74 +64 +52 +45 +41 +39 +38 +38 +-32 +-93 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-27 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +80 +7 +-59 +-117 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +90 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +121 +114 +103 +95 +20 +-47 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +74 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +121 +112 +102 +95 +19 +-48 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-15 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +90 +14 +-52 +-110 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +89 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +89 +16 +-49 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +52 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +118 +110 +104 +95 +87 +76 +69 +65 +62 +57 +48 +46 +-24 +-87 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +72 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +119 +111 +103 +96 +20 +-47 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-15 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +91 +16 +-51 +-110 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +92 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +122 +114 +105 +98 +22 +-45 +-105 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +79 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +89 +15 +-50 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +47 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +117 +39 +-30 +-90 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +4 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +115 +103 +94 +87 +80 +73 +70 +62 +54 +43 +38 +34 +33 +-36 +-98 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-34 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +83 +10 +-56 +-114 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +87 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +126 +113 +103 +95 +89 +14 +-53 +-111 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +87 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +120 +109 +103 +95 +19 +-48 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-10 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +82 +8 +-58 +-116 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +93 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +92 +18 +-47 +-105 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +49 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +117 +40 +-29 +-90 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-1 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +96 +20 +-47 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-1 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +121 +108 +98 +92 +86 +79 +71 +65 +59 +56 +53 +48 +40 +31 +-39 +-99 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-28 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +81 +7 +-58 +-116 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +85 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +89 +16 +-49 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +53 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +117 +107 +97 +91 +84 +80 +74 +66 +58 +53 +49 +44 +-27 +-89 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +73 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +87 +13 +-52 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +48 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +115 +38 +-31 +-91 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +2 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +96 +22 +-45 +-105 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-1 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +92 +17 +-49 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-1 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +112 +96 +86 +80 +75 +72 +70 +64 +59 +49 +43 +39 +38 +-32 +-93 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-31 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +79 +5 +-60 +-118 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-9 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +92 +17 +-50 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +0 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +89 +15 +-51 +-110 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-1 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +89 +15 +-52 +-110 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-9 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +90 +15 +-51 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +3 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +90 +15 +-51 +-110 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +2 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +91 +16 +-50 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-8 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +94 +19 +-47 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +0 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +93 +18 +-48 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +89 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +125 +115 +106 +93 +17 +-50 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +83 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +119 +110 +101 +93 +17 +-50 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +85 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +119 +110 +101 +93 +18 +-49 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +89 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +124 +113 +105 +98 +93 +17 +-50 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +79 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +85 +13 +-52 +-110 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +55 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +113 +36 +-33 +-93 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +5 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +116 +103 +92 +83 +79 +73 +68 +59 +53 +50 +44 +40 +37 +-33 +-94 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-31 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +82 +9 +-57 +-115 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +88 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +91 +17 +-48 +-105 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +61 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +113 +37 +-32 +-92 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +0 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +100 +25 +-43 +-103 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-11 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +114 +104 +97 +92 +88 +82 +74 +69 +62 +56 +53 +52 +44 +35 +-35 +-96 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-34 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +83 +9 +-57 +-115 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +87 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +121 +111 +98 +87 +12 +-54 +-113 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +78 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +122 +115 +101 +94 +18 +-49 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +84 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +90 +16 +-49 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +54 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +110 +97 +90 +84 +80 +78 +74 +70 +64 +59 +54 +48 +-23 +-86 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-32 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +79 +6 +-60 +-117 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-5 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +88 +13 +-53 +-112 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +91 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +121 +112 +103 +94 +19 +-48 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-14 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +90 +15 +-51 +-110 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +87 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +119 +110 +99 +91 +16 +-51 +-110 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +85 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +92 +17 +-49 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +52 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +110 +33 +-35 +-96 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +7 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +100 +25 +-42 +-101 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-11 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +112 +96 +87 +80 +75 +71 +66 +60 +55 +46 +40 +38 +35 +-34 +-95 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +65 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +86 +12 +-53 +-110 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +51 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +125 +116 +108 +99 +92 +85 +75 +69 +63 +56 +54 +53 +49 +-21 +-83 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-32 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +77 +4 +-61 +-119 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +88 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +124 +114 +101 +87 +12 +-55 +-113 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +86 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +92 +18 +-48 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +49 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +121 +43 +-27 +-88 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-3 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +126 +113 +102 +93 +85 +78 +73 +68 +62 +57 +52 +44 +34 +28 +-40 +-101 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-31 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +83 +9 +-57 +-115 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +82 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +121 +112 +104 +95 +20 +-47 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +87 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +120 +107 +99 +93 +17 +-50 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-13 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +82 +8 +-58 +-116 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +95 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +92 +18 +-48 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +57 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +117 +107 +97 +90 +84 +77 +70 +64 +61 +56 +51 +45 +-26 +-88 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +70 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +122 +113 +102 +94 +18 +-49 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-15 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +86 +12 +-55 +-113 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +88 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +123 +116 +110 +103 +94 +19 +-49 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +84 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +89 +16 +-50 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +51 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +116 +38 +-31 +-91 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-1 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +125 +113 +99 +86 +76 +71 +67 +64 +63 +59 +56 +48 +39 +34 +-36 +-97 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-34 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +82 +8 +-57 +-115 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +86 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +125 +116 +107 +98 +22 +-45 +-105 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +83 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +126 +116 +109 +102 +96 +20 +-46 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-19 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +86 +12 +-54 +-112 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +84 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +89 +16 +-49 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +58 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +118 +40 +-29 +-90 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +4 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +94 +19 +-48 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +1 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +121 +109 +99 +92 +83 +76 +68 +65 +63 +55 +51 +46 +42 +38 +-32 +-93 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-32 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +79 +5 +-61 +-118 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +86 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +89 +16 +-50 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +57 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +125 +115 +108 +101 +95 +84 +77 +69 +65 +60 +58 +51 +43 +-27 +-89 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +73 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +87 +14 +-51 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +54 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +114 +37 +-32 +-92 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +3 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +96 +21 +-46 +-105 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-5 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +92 +17 +-49 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-5 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +124 +111 +96 +83 +73 +67 +63 +62 +60 +58 +55 +49 +45 +41 +-29 +-91 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-26 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +82 +8 +-58 +-115 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-11 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +90 +16 +-51 +-110 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +0 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +94 +19 +-48 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-4 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +92 +17 +-49 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-2 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +89 +14 +-52 +-110 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-6 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +92 +17 +-49 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-2 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +90 +15 +-51 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-3 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +90 +16 +-50 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-4 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +93 +19 +-48 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +88 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +125 +111 +100 +94 +18 +-49 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +84 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +121 +109 +100 +92 +16 +-51 +-110 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +88 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +123 +115 +110 +103 +91 +15 +-51 +-110 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +87 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +121 +111 +101 +95 +20 +-47 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +83 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +90 +16 +-49 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +58 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +117 +40 +-29 +-89 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +6 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +118 +108 +101 +93 +86 +76 +68 +66 +60 +57 +54 +51 +46 +37 +-33 +-95 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-35 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +83 +9 +-57 +-115 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +89 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +87 +14 +-51 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +56 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +118 +40 +-28 +-89 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +5 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +89 +14 +-52 +-111 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-3 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +122 +110 +102 +93 +86 +79 +70 +67 +63 +60 +52 +42 +37 +35 +-35 +-96 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-29 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +81 +7 +-59 +-116 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +91 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +119 +104 +94 +87 +12 +-54 +-113 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +84 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +122 +113 +103 +95 +20 +-48 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +83 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +87 +15 +-51 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +48 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +122 +111 +99 +91 +83 +77 +70 +64 +58 +52 +50 +45 +-25 +-87 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-31 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +73 +0 +-65 +-121 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +0 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +84 +10 +-56 +-114 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +91 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +122 +114 +105 +95 +19 +-48 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-14 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +90 +16 +-50 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +86 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +118 +110 +104 +96 +20 +-47 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +85 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +88 +15 +-50 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +55 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +118 +41 +-28 +-89 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +5 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +97 +21 +-46 +-105 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +0 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +115 +105 +96 +92 +85 +78 +72 +67 +62 +57 +51 +45 +40 +38 +-32 +-93 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +70 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +87 +14 +-51 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +52 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +118 +109 +100 +92 +85 +79 +71 +63 +61 +55 +50 +46 +-25 +-87 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-32 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +81 +8 +-58 +-115 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +88 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +120 +111 +104 +97 +22 +-45 +-105 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +75 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +89 +16 +-50 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +54 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +117 +40 +-30 +-90 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +4 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +120 +110 +102 +96 +88 +78 +67 +60 +55 +52 +50 +47 +43 +40 +-30 +-92 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-29 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +72 +0 +-65 +-122 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +93 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +120 +111 +102 +93 +18 +-49 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +81 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +124 +115 +107 +101 +94 +18 +-49 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-13 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +90 +15 +-51 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +92 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +91 +18 +-47 +-105 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +50 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +123 +113 +106 +100 +94 +86 +81 +75 +70 +64 +58 +52 +47 +-23 +-86 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +74 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +122 +113 +106 +100 +93 +18 +-49 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-15 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +88 +14 +-52 +-111 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +81 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +124 +113 +99 +89 +14 +-53 +-111 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +81 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +87 +14 +-51 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +56 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +117 +39 +-30 +-90 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +7 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +113 +101 +94 +86 +80 +75 +69 +63 +59 +53 +47 +46 +42 +-28 +-90 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-32 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +79 +5 +-60 +-117 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +85 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +120 +111 +102 +97 +21 +-46 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +82 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +125 +115 +108 +103 +95 +20 +-47 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-12 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +84 +10 +-56 +-114 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +86 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +92 +18 +-47 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +45 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +118 +40 +-29 +-90 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +6 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +95 +20 +-47 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-6 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +115 +108 +102 +97 +89 +84 +74 +63 +55 +52 +49 +47 +46 +42 +-27 +-89 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-37 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +78 +4 +-61 +-118 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +88 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +87 +14 +-51 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +60 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +117 +107 +96 +88 +81 +76 +67 +63 +56 +52 +45 +40 +-30 +-92 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +64 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +86 +13 +-52 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +55 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +116 +39 +-31 +-91 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +3 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +95 +20 +-47 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +2 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +92 +17 +-49 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-7 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +124 +113 +101 +92 +85 +79 +70 +65 +59 +54 +49 +45 +42 +39 +-31 +-92 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-29 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +79 +5 +-60 +-118 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-12 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +92 +17 +-49 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-7 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +92 +17 +-49 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-4 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +92 +17 +-49 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-5 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +93 +18 +-48 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-1 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +87 +13 +-54 +-112 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-5 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +99 +23 +-44 +-103 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-2 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +86 +11 +-55 +-113 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +2 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +92 +17 +-50 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +81 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +120 +111 +103 +94 +18 +-49 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +85 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +119 +105 +94 +87 +12 +-54 +-112 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +83 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +118 +110 +101 +95 +19 +-47 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +79 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +118 +111 +105 +98 +22 +-45 +-105 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +80 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +89 +16 +-50 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +48 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +119 +41 +-29 +-89 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +0 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +110 +99 +90 +84 +80 +77 +72 +62 +58 +51 +46 +42 +41 +-29 +-91 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-28 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +77 +4 +-61 +-118 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +94 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +87 +14 +-51 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +58 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +114 +37 +-33 +-93 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +7 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +92 +18 +-49 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-10 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +116 +101 +94 +90 +85 +80 +75 +70 +64 +56 +46 +40 +36 +35 +-35 +-96 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-29 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +79 +6 +-59 +-117 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +86 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +120 +111 +102 +93 +18 +-49 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +87 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +119 +110 +100 +93 +17 +-50 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +83 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +87 +15 +-50 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +46 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +122 +110 +100 +92 +87 +81 +74 +67 +61 +55 +48 +43 +-28 +-90 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-30 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +80 +6 +-59 +-117 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-12 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +89 +14 +-52 +-110 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +91 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +121 +115 +106 +98 +22 +-45 +-105 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-15 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +87 +13 +-53 +-112 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +93 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +121 +114 +105 +96 +20 +-47 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +84 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +90 +16 +-49 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +51 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +117 +39 +-30 +-91 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +5 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +93 +19 +-48 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-8 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +114 +100 +86 +78 +73 +68 +67 +62 +59 +53 +49 +43 +38 +-32 +-93 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +65 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +86 +13 +-52 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +55 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +123 +114 +105 +96 +87 +82 +74 +71 +64 +57 +51 +45 +-25 +-87 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-30 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +78 +5 +-61 +-118 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +82 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +120 +112 +104 +97 +21 +-46 +-105 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +81 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +88 +14 +-51 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +56 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +119 +41 +-28 +-89 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +0 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +125 +112 +101 +91 +82 +77 +73 +67 +63 +55 +49 +44 +44 +40 +-30 +-92 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-27 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +80 +6 +-59 +-117 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +91 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +118 +109 +100 +93 +18 +-49 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +81 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +122 +116 +107 +97 +21 +-47 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-17 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +86 +11 +-55 +-113 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +87 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +90 +17 +-48 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +53 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +120 +110 +101 +95 +86 +79 +75 +69 +61 +55 +50 +46 +-25 +-87 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +75 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +120 +108 +95 +81 +7 +-59 +-117 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-11 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +89 +15 +-52 +-110 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +89 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +123 +111 +101 +92 +16 +-50 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +82 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +87 +14 +-51 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +52 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +119 +41 +-28 +-89 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-1 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +119 +106 +97 +91 +86 +79 +76 +72 +64 +56 +51 +45 +41 +40 +-30 +-91 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-29 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +82 +9 +-57 +-115 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +85 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +119 +110 +100 +96 +20 +-47 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +81 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +121 +114 +102 +94 +18 +-49 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-23 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +85 +11 +-55 +-113 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +89 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +91 +18 +-48 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +52 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +118 +40 +-30 +-90 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +9 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +95 +20 +-47 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-2 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +122 +109 +98 +93 +87 +81 +73 +67 +57 +50 +46 +44 +40 +37 +-32 +-94 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-32 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +73 +0 +-65 +-122 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +94 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +89 +16 +-49 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +55 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +117 +107 +98 +93 +86 +80 +75 +64 +58 +52 +49 +45 +-26 +-88 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +77 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +88 +15 +-50 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +52 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +118 +40 +-29 +-90 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +5 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +93 +18 +-48 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-2 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +90 +15 +-50 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-6 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +120 +109 +101 +93 +86 +80 +74 +68 +60 +53 +48 +44 +39 +35 +-34 +-96 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-33 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +84 +10 +-56 +-114 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-14 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +91 +17 +-50 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-2 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +96 +21 +-46 +-105 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-4 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +91 +16 +-50 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +0 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +92 +17 +-49 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-2 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +93 +18 +-49 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-7 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +91 +17 +-50 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-9 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +96 +21 +-46 +-104 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +4 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +91 +16 +-50 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +94 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +120 +111 +102 +92 +16 +-51 +-110 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +85 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +119 +112 +104 +95 +19 +-48 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +81 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +124 +113 +103 +95 +20 +-48 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +85 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +121 +112 +105 +96 +20 +-47 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +79 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +89 +15 +-50 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +52 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +116 +39 +-30 +-91 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +9 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +118 +108 +100 +96 +90 +80 +69 +62 +57 +55 +53 +50 +43 +41 +-29 +-91 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-30 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +70 +-2 +-67 +-123 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +94 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +91 +17 +-48 +-105 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +54 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +115 +37 +-31 +-92 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-3 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +97 +22 +-44 +-103 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-1 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +118 +109 +99 +91 +85 +78 +72 +66 +60 +56 +51 +47 +41 +37 +-33 +-94 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-32 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +78 +5 +-60 +-117 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +89 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +123 +111 +101 +93 +17 +-50 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +77 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +118 +113 +103 +96 +20 +-48 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +84 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +87 +14 +-51 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +58 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +116 +107 +97 +91 +84 +78 +70 +64 +58 +57 +50 +44 +-27 +-89 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-22 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +79 +6 +-60 +-118 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-3 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +89 +15 +-52 +-110 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +92 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +119 +110 +102 +94 +18 +-48 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-16 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +84 +11 +-55 +-113 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +89 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +119 +111 +104 +95 +19 +-48 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +85 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +91 +17 +-48 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +54 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +116 +38 +-31 +-91 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +4 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +100 +24 +-43 +-103 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-1 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +123 +111 +100 +91 +83 +76 +70 +64 +59 +54 +48 +44 +39 +37 +-32 +-93 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +67 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +87 +13 +-52 +-110 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +56 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +118 +107 +98 +91 +84 +76 +70 +63 +57 +53 +48 +43 +-27 +-89 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-27 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +77 +4 +-61 +-119 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +91 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +125 +118 +111 +104 +98 +22 +-45 +-105 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +80 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +90 +16 +-49 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +52 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +116 +39 +-30 +-91 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +1 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +113 +101 +95 +87 +79 +72 +69 +63 +58 +50 +40 +33 +30 +-39 +-99 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-32 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +85 +11 +-54 +-113 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +78 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +123 +115 +103 +93 +16 +-50 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +81 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +120 +111 +102 +89 +13 +-53 +-112 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-6 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +91 +16 +-51 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +89 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +89 +16 +-49 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +56 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +121 +115 +105 +97 +88 +80 +72 +66 +60 +59 +53 +49 +-22 +-85 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +65 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +119 +108 +96 +87 +12 +-54 +-113 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-15 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +84 +10 +-56 +-114 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +96 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +121 +110 +101 +92 +16 +-51 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +84 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +89 +16 +-50 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +49 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +117 +39 +-30 +-90 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +9 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +120 +106 +96 +91 +87 +81 +75 +66 +60 +56 +54 +49 +45 +36 +-34 +-95 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-32 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +75 +1 +-64 +-121 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +80 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +122 +114 +104 +97 +21 +-47 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +79 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +125 +116 +110 +104 +97 +21 +-46 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-14 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +83 +9 +-56 +-114 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +95 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +91 +18 +-48 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +52 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +114 +37 +-32 +-93 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +0 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +96 +21 +-46 +-105 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-4 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +119 +109 +101 +93 +86 +81 +73 +68 +63 +57 +50 +44 +42 +39 +-31 +-93 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-33 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +79 +5 +-60 +-118 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +91 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +91 +17 +-48 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +50 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +116 +105 +96 +91 +86 +77 +71 +61 +54 +51 +48 +47 +-24 +-86 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +68 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +85 +12 +-53 +-110 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +56 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +113 +35 +-33 +-94 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +3 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +100 +24 +-44 +-103 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-3 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +89 +14 +-52 +-110 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +1 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +126 +112 +102 +93 +85 +77 +73 +66 +61 +55 +49 +44 +40 +36 +-34 +-96 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-28 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +85 +11 +-55 +-113 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-7 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +92 +17 +-50 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-7 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +89 +15 +-51 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-1 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +90 +15 +-51 +-110 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-10 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +96 +21 +-46 +-105 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-9 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +91 +16 +-51 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +2 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +92 +17 +-50 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +7 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +86 +11 +-54 +-113 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +1 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +89 +14 +-52 +-111 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +91 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +117 +107 +98 +92 +17 +-50 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +75 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +122 +113 +103 +93 +18 +-49 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +83 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +122 +110 +103 +95 +90 +15 +-52 +-111 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +91 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +121 +109 +100 +91 +15 +-51 +-110 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +85 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +89 +15 +-50 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +53 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +117 +39 +-30 +-91 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +7 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +125 +115 +105 +93 +81 +72 +68 +66 +63 +62 +57 +52 +46 +42 +-29 +-90 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-31 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +71 +-1 +-66 +-123 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +93 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +93 +19 +-47 +-105 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +56 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +119 +42 +-27 +-88 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +7 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +89 +15 +-51 +-110 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +2 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +124 +112 +102 +95 +90 +83 +73 +63 +51 +48 +44 +43 +41 +39 +-31 +-92 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-37 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +82 +8 +-58 +-115 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +91 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +115 +106 +98 +93 +17 +-50 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +80 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +124 +113 +103 +97 +21 +-46 +-105 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +83 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +87 +15 +-51 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +57 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +115 +108 +103 +93 +83 +77 +73 +66 +61 +56 +51 +46 +-25 +-87 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-29 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +79 +5 +-60 +-117 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +0 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +91 +16 +-50 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +93 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +124 +115 +104 +95 +19 +-48 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-19 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +87 +12 +-54 +-112 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +91 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +118 +108 +99 +92 +16 +-51 +-110 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +79 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +89 +15 +-50 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +54 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +117 +40 +-30 +-91 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +3 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +102 +26 +-41 +-101 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-10 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +111 +102 +94 +89 +87 +81 +77 +74 +69 +61 +55 +46 +39 +37 +-33 +-94 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +73 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +88 +14 +-51 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +43 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +119 +110 +101 +92 +83 +77 +70 +63 +58 +53 +48 +43 +-28 +-90 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-24 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +84 +10 +-56 +-114 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +80 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +120 +108 +98 +92 +17 +-50 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +70 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +89 +15 +-50 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +54 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +118 +41 +-28 +-89 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +9 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +117 +107 +98 +94 +87 +80 +75 +67 +61 +56 +51 +49 +43 +39 +-31 +-92 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-37 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +80 +6 +-60 +-118 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +77 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +118 +109 +102 +94 +18 +-49 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +84 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +121 +112 +104 +97 +21 +-46 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-14 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +88 +13 +-53 +-111 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +89 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +92 +18 +-48 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +55 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +120 +106 +93 +85 +79 +76 +70 +67 +62 +54 +45 +40 +-30 +-91 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +68 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +116 +105 +99 +95 +19 +-48 +-107 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-17 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +83 +9 +-57 +-115 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +93 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +117 +107 +101 +94 +18 +-49 +-108 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +86 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +86 +14 +-51 +-109 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +50 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +119 +41 +-28 +-89 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-3 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +125 +112 +102 +90 +83 +76 +69 +66 +61 +59 +54 +46 +38 +28 +-41 +-101 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-25 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +85 +11 +-54 +-113 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +84 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +118 +109 +99 +90 +15 +-52 +-111 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +80 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +121 +110 +96 +87 +12 +-55 +-113 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-11 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +89 +14 +-52 +-111 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +94 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +90 +17 +-49 +-106 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +55 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +117 +40 +-29 +-90 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +9 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +88 +13 +-53 +-111 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-5 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +125 +113 +101 +91 +83 +77 +73 +67 +61 +57 +50 +45 +43 +38 +-32 +-93 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-34 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +77 +4 +-62 +-119 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +89 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +93 +18 +-47 +-105 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +57 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +116 +101 +93 +86 +82 +76 +71 +68 +63 +57 +53 +46 +-25 +-87 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +71 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +82 +9 +-55 +-112 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +-128 +62 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +112 +35 +-34 +-94 +-128 +-128 +-128 From 73c460dec2a054700e79270338f7dc05a8722a65 Mon Sep 17 00:00:00 2001 From: Iceman Date: Wed, 9 Oct 2019 10:24:02 +0200 Subject: [PATCH 0868/1854] Update README.md coverity scan badge up --- README.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 2d51d3fbf..822f744eb 100644 --- a/README.md +++ b/README.md @@ -5,10 +5,9 @@ This repo is based on iceman fork for Proxmark3. It supports other Proxmark3 pl It is dedicated to bringing the most out of the new features for Proxmark3 RDV4.0 new hardware and design. -| Releases | Linux & OSX CI | Windows CI | -| ------------------- |:-------------------:| -------------------:| -| [![Latest release](https://img.shields.io/github/release/RfidResearchGroup/proxmark3.svg)](https://github.com/RfidResearchGroup/proxmark3/releases/latest) | [![Build status](https://travis-ci.org/RfidResearchGroup/proxmark3.svg?branch=master)](https://travis-ci.org/RfidResearchGroup/proxmark3) | [![Build status](https://ci.appveyor.com/api/projects/status/b4gwrhq3nc876cuu/branch/master?svg=true)](https://ci.appveyor.com/project/RfidResearchGroup/proxmark3/branch/master) | - +| Releases | Linux & OSX CI | Windows CI | Coverity | +| ------------------- |:-------------------:| -------------------:| -------------------:| +| [![Latest release](https://img.shields.io/github/release/RfidResearchGroup/proxmark3.svg)](https://github.com/RfidResearchGroup/proxmark3/releases/latest) | [![Build status](https://travis-ci.org/RfidResearchGroup/proxmark3.svg?branch=master)](https://travis-ci.org/RfidResearchGroup/proxmark3) | [![Build status](https://ci.appveyor.com/api/projects/status/b4gwrhq3nc876cuu/branch/master?svg=true)](https://ci.appveyor.com/project/RfidResearchGroup/proxmark3/branch/master) | [![Coverity Status](https://scan.coverity.com/projects/19334/badge.svg)](https://scan.coverity.com/project/proxmark3-rrg-iceman-repo) | --- # PROXMARK INSTALLATION AND OVERVIEW From 0ae7652ea24f88db04761e865b5f134e44df4ce1 Mon Sep 17 00:00:00 2001 From: Iceman Date: Wed, 9 Oct 2019 10:25:42 +0200 Subject: [PATCH 0869/1854] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 822f744eb..7f5b35569 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ It is dedicated to bringing the most out of the new features for Proxmark3 RDV4. | Releases | Linux & OSX CI | Windows CI | Coverity | | ------------------- |:-------------------:| -------------------:| -------------------:| -| [![Latest release](https://img.shields.io/github/release/RfidResearchGroup/proxmark3.svg)](https://github.com/RfidResearchGroup/proxmark3/releases/latest) | [![Build status](https://travis-ci.org/RfidResearchGroup/proxmark3.svg?branch=master)](https://travis-ci.org/RfidResearchGroup/proxmark3) | [![Build status](https://ci.appveyor.com/api/projects/status/b4gwrhq3nc876cuu/branch/master?svg=true)](https://ci.appveyor.com/project/RfidResearchGroup/proxmark3/branch/master) | [![Coverity Status](https://scan.coverity.com/projects/19334/badge.svg)](https://scan.coverity.com/project/proxmark3-rrg-iceman-repo) | +| [![Latest release](https://img.shields.io/github/release/RfidResearchGroup/proxmark3.svg)](https://github.com/RfidResearchGroup/proxmark3/releases/latest) | [![Build status](https://travis-ci.org/RfidResearchGroup/proxmark3.svg?branch=master)](https://travis-ci.org/RfidResearchGroup/proxmark3) | [![Build status](https://ci.appveyor.com/api/projects/status/b4gwrhq3nc876cuu/branch/master?svg=true)](https://ci.appveyor.com/project/RfidResearchGroup/proxmark3/branch/master) | [![Coverity Status](https://scan.coverity.com/projects/19334/badge.svg)](https://scan.coverity.com/projects/proxmark3-rrg-iceman-repo)| --- # PROXMARK INSTALLATION AND OVERVIEW From fb7728974e29bf3ef897dd5454a2e99f8d0b1376 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 9 Oct 2019 10:33:42 +0200 Subject: [PATCH 0870/1854] strlen checks --- armsrc/appmain.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 4a9ac2c9f..5c645062d 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1678,33 +1678,33 @@ static void PacketReceived(PacketCommandNG *packet) { } case CMD_SPIFFS_RENAME: { LED_B_ON(); - uint8_t srcfilename[32]; - uint8_t destfilename[32]; + uint8_t src[32]; + uint8_t dest[32]; uint8_t *pfilename = packet->data.asBytes; char *token; token = strtok((char *)pfilename, ","); - strcpy((char *)srcfilename, token); + strncpy((char *)src, token, sizeof(src) - 1); token = strtok(NULL, ","); - strcpy((char *)destfilename, token); - if (DBGLEVEL > 1) Dbprintf("> Filename received as source for spiffs RENAME : %s", srcfilename); - if (DBGLEVEL > 1) Dbprintf("> Filename received as destination for spiffs RENAME : %s", destfilename); - rdv40_spiffs_rename((char *) srcfilename, (char *)destfilename, RDV40_SPIFFS_SAFETY_SAFE); + strncpy((char *)dest, token, sizeof(dest) - 1); + if (DBGLEVEL > 1) Dbprintf("> Filename received as source for spiffs RENAME : %s", src); + if (DBGLEVEL > 1) Dbprintf("> Filename received as destination for spiffs RENAME : %s", dest); + rdv40_spiffs_rename((char *) src, (char *)dest, RDV40_SPIFFS_SAFETY_SAFE); LED_B_OFF(); break; } case CMD_SPIFFS_COPY: { LED_B_ON(); - uint8_t srcfilename[32]; - uint8_t destfilename[32]; + uint8_t src[32]; + uint8_t dest[32]; uint8_t *pfilename = packet->data.asBytes; char *token; token = strtok((char *)pfilename, ","); - strcpy((char *)srcfilename, token); + strncpy((char *)src, token, sizeof(src) - 1); token = strtok(NULL, ","); - strcpy((char *)destfilename, token); - if (DBGLEVEL > 1) Dbprintf("> Filename received as source for spiffs COPY : %s", srcfilename); - if (DBGLEVEL > 1) Dbprintf("> Filename received as destination for spiffs COPY : %s", destfilename); - rdv40_spiffs_copy((char *) srcfilename, (char *)destfilename, RDV40_SPIFFS_SAFETY_SAFE); + strncpy((char *)dest, token, sizeof(dest) - 1); + if (DBGLEVEL > 1) Dbprintf("> Filename received as source for spiffs COPY : %s", src); + if (DBGLEVEL > 1) Dbprintf("> Filename received as destination for spiffs COPY : %s", dest); + rdv40_spiffs_copy((char *) src, (char *)dest, RDV40_SPIFFS_SAFETY_SAFE); LED_B_OFF(); break; } From 8c4a42ff3682f5f3941277d08ed9e0d74bd256cf Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 9 Oct 2019 10:36:34 +0200 Subject: [PATCH 0871/1854] consider null termination --- armsrc/spiffs_hydrogen.c | 2 +- armsrc/spiffs_nucleus.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/armsrc/spiffs_hydrogen.c b/armsrc/spiffs_hydrogen.c index dee72fb5f..7290e676a 100644 --- a/armsrc/spiffs_hydrogen.c +++ b/armsrc/spiffs_hydrogen.c @@ -749,7 +749,7 @@ static s32_t spiffs_stat_pix(spiffs *fs, spiffs_page_ix pix, spiffs_file fh, spi s->type = objix_hdr.type; s->size = objix_hdr.size == SPIFFS_UNDEFINED_LEN ? 0 : objix_hdr.size; s->pix = pix; - strncpy((char *)s->name, (char *)objix_hdr.name, SPIFFS_OBJ_NAME_LEN); + strncpy((char *)s->name, (char *)objix_hdr.name, SPIFFS_OBJ_NAME_LEN - 1); #if SPIFFS_OBJ_META_LEN _SPIFFS_MEMCPY(s->meta, objix_hdr.meta, SPIFFS_OBJ_META_LEN); #endif diff --git a/armsrc/spiffs_nucleus.c b/armsrc/spiffs_nucleus.c index 8dd4b5629..ef1db36f1 100644 --- a/armsrc/spiffs_nucleus.c +++ b/armsrc/spiffs_nucleus.c @@ -944,7 +944,7 @@ s32_t spiffs_object_create( oix_hdr.p_hdr.flags = 0xff & ~(SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_USED); oix_hdr.type = type; oix_hdr.size = SPIFFS_UNDEFINED_LEN; // keep ones so we can update later without wasting this page - strncpy((char *)oix_hdr.name, (const char *)name, SPIFFS_OBJ_NAME_LEN); + strncpy((char *)oix_hdr.name, (const char *)name, SPIFFS_OBJ_NAME_LEN - 1); #if SPIFFS_OBJ_META_LEN if (meta) { _SPIFFS_MEMCPY(oix_hdr.meta, meta, SPIFFS_OBJ_META_LEN); @@ -1007,7 +1007,7 @@ s32_t spiffs_object_update_index_hdr( // change name if (name) { - strncpy((char *)objix_hdr->name, (const char *)name, SPIFFS_OBJ_NAME_LEN); + strncpy((char *)objix_hdr->name, (const char *)name, SPIFFS_OBJ_NAME_LEN - 1); } #if SPIFFS_OBJ_META_LEN if (meta) { From ba461b8e1b07537b54421403e4138c55377b6099 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 9 Oct 2019 10:39:36 +0200 Subject: [PATCH 0872/1854] fix: wrong size when going to calloc --- client/cmdlft55xx.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 68df3fb31..97798a0eb 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -2554,18 +2554,19 @@ static int CmdResetRead(const char *Cmd) { if (resp.status == PM3_SUCCESS) { - uint8_t *got = calloc(BIGBUF_SIZE - 1, sizeof(uint8_t)); + uint16_t gotsize = BIGBUF_SIZE - 1; + uint8_t *got = calloc(gotsize, sizeof(uint8_t)); if (got == NULL) { PrintAndLogEx(WARNING, "failed to allocate memory"); return PM3_EMALLOC; } - if (!GetFromDevice(BIG_BUF, got, sizeof(got), 0, NULL, 0, NULL, 2500, false)) { + if (!GetFromDevice(BIG_BUF, got, gotsize, 0, NULL, 0, NULL, 2500, false)) { PrintAndLogEx(WARNING, "command execution time out"); free(got); return PM3_ETIMEOUT; } - setGraphBuf(got, sizeof(got)); + setGraphBuf(got, gotsize); free(got); } return PM3_SUCCESS; From abb011c179beb89f571288cf3770229bde17fbac Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 9 Oct 2019 10:41:59 +0200 Subject: [PATCH 0873/1854] fix: wrong key copied --- client/cmdhfmf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 637cb6635..8671dc6c8 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -1967,7 +1967,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { // Store valid credentials for the nested / hardnested attack if none exist if (know_target_key == false) { - num_to_bytes(e_sector[i].Key[j], 6, key); + num_to_bytes(e_sector[i].Key[j], 6, tmp_key); know_target_key = true; blockNo = i; keyType = j; From b463f2ab5ac15438d25bff327249e622a0fb19cc Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 9 Oct 2019 10:48:20 +0200 Subject: [PATCH 0874/1854] coverity 226340, make sure its not null --- client/fileutils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/fileutils.c b/client/fileutils.c index 57aa939a7..294d92f15 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -910,7 +910,7 @@ static int filelist(const char *path, const char *ext, bool last, bool tentative PrintAndLogEx(NORMAL, "%s── %s", last ? "└" : "├", path); for (uint16_t i = 0; i < n; i++) { - if (((ext == NULL) && (namelist[i]->d_name[0] != '.')) || (str_endswith(namelist[i]->d_name, ext))) { + if (((ext == NULL) && (namelist[i]->d_name[0] != '.')) || ((ext != NULL) && (str_endswith(namelist[i]->d_name, ext)))) { PrintAndLogEx(NORMAL, "%s   %s── %-21s", last ? " " : "│", i == n - 1 ? "└" : "├", namelist[i]->d_name); } free(namelist[i]); From a3376117080283e2e3f6e333a7834e197bea54a9 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 9 Oct 2019 10:59:10 +0200 Subject: [PATCH 0875/1854] coverity 226386, u8 can never be larger than 256 --- armsrc/mifaresim.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/armsrc/mifaresim.c b/armsrc/mifaresim.c index 7edcec398..93b950e6e 100644 --- a/armsrc/mifaresim.c +++ b/armsrc/mifaresim.c @@ -796,12 +796,17 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1 if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] Commands must be encrypted (authenticated)"); break; } + + // iceman, u8 can never be larger the MIFARE_4K_MAXBLOCK (256) // Check if Block num is not too far + /* if (receivedCmd_dec[1] > MIFARE_4K_MAXBLOCK) { EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA)); if (DBGLEVEL >= DBG_ERROR) Dbprintf("[MFEMUL_WORK] Reader tried to operate (0x%02x) on out of range block: %d (0x%02x), nacking", receivedCmd_dec[0], receivedCmd_dec[1], receivedCmd_dec[1]); break; } + */ + if (MifareBlockToSector(receivedCmd_dec[1]) != cardAUTHSC) { EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA)); if (DBGLEVEL >= DBG_ERROR) Dbprintf("[MFEMUL_WORK] Reader tried to operate (0x%02x) on block (0x%02x) not authenticated for (0x%02x), nacking", receivedCmd_dec[0], receivedCmd_dec[1], cardAUTHSC); From 6835cfd76ab3288b401530abeb6c9cdb0715a648 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 9 Oct 2019 11:21:53 +0200 Subject: [PATCH 0876/1854] textual --- client/cmdlft55xx.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 97798a0eb..8053c2e76 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -335,7 +335,8 @@ static int usage_t55xx_deviceconfig() { return PM3_SUCCESS; } static int usage_t55xx_protect() { - PrintAndLogEx(NORMAL, "This command set or unsets the pwd bit on T5577."); + PrintAndLogEx(NORMAL, "This command set the pwd bit on T5577. "); + PrintAndLogEx(NORMAL, _RED_("WARNING:") " this locks the tag!"); PrintAndLogEx(NORMAL, "Usage: lf t55xx protect [r ] [p ] [o] [n ]"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " p - OPTIONAL password (8 hex characters)"); @@ -385,7 +386,7 @@ int clone_t55xx_tag(uint32_t *blockdata, uint8_t numblocks) { return PM3_ETIMEOUT; } } - + uint8_t res = 0; for (int8_t i = 0; i < numblocks; i++) { @@ -401,7 +402,7 @@ int clone_t55xx_tag(uint32_t *blockdata, uint8_t numblocks) { if (res == 0) PrintAndLogEx(SUCCESS, "Success writing to tag"); - + return PM3_SUCCESS; } From 84f5f0352f957f4985771d3dd22aea60837b61de Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 9 Oct 2019 11:46:11 +0200 Subject: [PATCH 0877/1854] coverity 226350 - fix resource leak --- client/cmdhficlass.c | 1 + 1 file changed, 1 insertion(+) diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 61710201e..e2ecf943c 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -870,6 +870,7 @@ static int CmdHFiClassDecrypt(const char *Cmd) { return PM3_EINVARG; memcpy(key, keyptr, sizeof(key)); + free(keyptr); } // tripledes From cd0a47308d7dd5283ef12ca1b731f79b86a407ce Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 9 Oct 2019 11:47:56 +0200 Subject: [PATCH 0878/1854] coverity 226337 - fix resource leak --- client/cmdscript.c | 1 + 1 file changed, 1 insertion(+) diff --git a/client/cmdscript.c b/client/cmdscript.c index 245ae61dc..f8306c041 100644 --- a/client/cmdscript.c +++ b/client/cmdscript.c @@ -121,6 +121,7 @@ static int CmdScriptRun(const char *Cmd) { int ret = PM3_EUNDEF; if (!str_endswith(preferredName, ".cmd")) ret = searchFile(&script_path, LUA_SCRIPTS_SUBDIR, preferredName, ".lua", false); if (!str_endswith(preferredName, ".lua")) ret = searchFile(&script_path, CMD_SCRIPTS_SUBDIR, preferredName, ".cmd", false); + free(script_path); return ret; } From 08e62afc59a78c5c846f6e3e7d5be44bf0a30b9d Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 9 Oct 2019 11:50:55 +0200 Subject: [PATCH 0879/1854] coverity 226277 - fix resource leak --- client/loclass/ikeys.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/loclass/ikeys.c b/client/loclass/ikeys.c index f14e43eaf..1bff33f37 100644 --- a/client/loclass/ikeys.c +++ b/client/loclass/ikeys.c @@ -664,10 +664,12 @@ static bool readKeyFile(uint8_t *key, size_t keylen) { } if (keylen != len) { + free(keyptr); return false; } memcpy(key, keyptr, keylen); + free(keyptr); return true; } From b993819b927e7fe733c39dd201c2a1b6386a900c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 9 Oct 2019 11:52:38 +0200 Subject: [PATCH 0880/1854] coverity 226268 - fix resource leak --- client/fileutils.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/client/fileutils.c b/client/fileutils.c index 294d92f15..de2fbef19 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -803,9 +803,10 @@ int loadFileDICTIONARY_safe(const char *preferredName, void **pdata, uint8_t key // allocate some space for the dictionary *pdata = calloc(block_size, sizeof(uint8_t)); - if (*pdata == NULL) + if (*pdata == NULL) { + free(path); return PM3_EFILE; - + } mem_size = block_size; FILE *f = fopen(path, "r"); @@ -910,7 +911,7 @@ static int filelist(const char *path, const char *ext, bool last, bool tentative PrintAndLogEx(NORMAL, "%s── %s", last ? "└" : "├", path); for (uint16_t i = 0; i < n; i++) { - if (((ext == NULL) && (namelist[i]->d_name[0] != '.')) || ((ext != NULL) && (str_endswith(namelist[i]->d_name, ext)))) { + if (((ext == NULL) && (namelist[i]->d_name[0] != '.')) || (ext && (str_endswith(namelist[i]->d_name, ext)))) { PrintAndLogEx(NORMAL, "%s   %s── %-21s", last ? " " : "│", i == n - 1 ? "└" : "├", namelist[i]->d_name); } free(namelist[i]); From cce039554db5e7737fafe42fac601bdd38d94754 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 8 Oct 2019 20:57:35 +0200 Subject: [PATCH 0881/1854] Avoid hardcoded lf divisors --- armsrc/hitag2.c | 8 ++++---- armsrc/hitagS.c | 8 ++++---- armsrc/lfops.c | 22 +++++++++++----------- armsrc/lfsampling.c | 4 ++-- armsrc/pcf7931.c | 4 ++-- 5 files changed, 23 insertions(+), 23 deletions(-) diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index 67bc8c623..3531ac9ea 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -738,7 +738,7 @@ void SniffHitag(void) { // Set up eavesdropping mode, frequency divisor which will drive the FPGA // and analog mux selection. FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_TOGGLE_MODE); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, LF_DIVISOR_125); SetAdcMuxFor(GPIO_MUXSEL_LOPKD); // Configure output pin that is connected to the FPGA (for modulating) @@ -967,7 +967,7 @@ void SimulateHitagTag(bool tag_mem_supplied, uint8_t *data) { // Set up simulator mode, frequency divisor which will drive the FPGA // and analog mux selection. FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125kHz + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, LF_DIVISOR_125); //125kHz SetAdcMuxFor(GPIO_MUXSEL_LOPKD); // Configure output pin that is connected to the FPGA (for modulating) @@ -1173,7 +1173,7 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { // Set fpga in edge detect with reader field, we can modulate as reader now FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125kHz + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, LF_DIVISOR_125); //125kHz SetAdcMuxFor(GPIO_MUXSEL_LOPKD); // Configure output and enable pin that is connected to the FPGA (for modulating) @@ -1444,7 +1444,7 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) { // Set fpga in edge detect with reader field, we can modulate as reader now FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125kHz + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, LF_DIVISOR_125); //125kHz SetAdcMuxFor(GPIO_MUXSEL_LOPKD); // Disable modulation at default, which means enable the field diff --git a/armsrc/hitagS.c b/armsrc/hitagS.c index a9481f3b6..7c8a01523 100644 --- a/armsrc/hitagS.c +++ b/armsrc/hitagS.c @@ -994,7 +994,7 @@ void SimulateHitagSTag(bool tag_mem_supplied, uint8_t *data) { // and analog mux selection. FpgaDownloadAndGo(FPGA_BITSTREAM_LF); FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125kHz + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, LF_DIVISOR_125); //125kHz SetAdcMuxFor(GPIO_MUXSEL_LOPKD); // Configure output pin that is connected to the FPGA (for modulating) @@ -1193,7 +1193,7 @@ void ReadHitagS(hitag_function htf, hitag_data *htd) { // Set fpga in edge detect with reader field, we can modulate as reader now FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125kHz + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, LF_DIVISOR_125); //125kHz SetAdcMuxFor(GPIO_MUXSEL_LOPKD); // Configure output and enable pin that is connected to the FPGA (for modulating) @@ -1528,7 +1528,7 @@ void WritePageHitagS(hitag_function htf, hitag_data *htd, int page) { // Set fpga in edge detect with reader field, we can modulate as reader now FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125kHz + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, LF_DIVISOR_125); //125kHz SetAdcMuxFor(GPIO_MUXSEL_LOPKD); // Disable modulation at default, which means enable the field @@ -1789,7 +1789,7 @@ void check_challenges(bool file_given, uint8_t *data) { // Set fpga in edge detect with reader field, we can modulate as reader now FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125kHz + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, LF_DIVISOR_125); //125kHz SetAdcMuxFor(GPIO_MUXSEL_LOPKD); // Disable modulation at default, which means enable the field diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 92c369b76..862f31626 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -503,7 +503,7 @@ void ReadTItag(void) { // TI tags charge at 134.2kHz FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8kHz + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, LF_DIVISOR_134); //~134kHz // Place FPGA in passthrough mode, in this mode the CROSS_LO line // connects to SSP_DIN and the SSP_DOUT logic level controls @@ -730,7 +730,7 @@ void WriteTItag(uint32_t idhi, uint32_t idlo, uint16_t crc) { Dbprintf("Writing to tag: %x%08x, crc=%x", idhi, idlo, crc); // TI tags charge at 134.2kHz - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8kHz + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, LF_DIVISOR_134); //~134kHz // Place FPGA in passthrough mode, in this mode the CROSS_LO line // connects to SSP_DIN and the SSP_DOUT logic level controls // whether we're modulating the antenna (high) @@ -803,9 +803,9 @@ void SimulateTagLowFrequencyEx(int period, int gap, bool ledcontrol, int numcycl sample_config *sc = getSamplingConfig(); if ((sc->divisor == 1) || (sc->divisor < 0) || (sc->divisor > 255)) - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8kHz + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, LF_DIVISOR_134); //~134kHz else if (sc->divisor == 0) - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125kHz + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, LF_DIVISOR_125); //125kHz else FpgaSendCommand(FPGA_CMD_SET_DIVISOR, sc->divisor); @@ -1145,7 +1145,7 @@ void CmdHIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol) uint32_t hi2 = 0, hi = 0, lo = 0; int dummyIdx = 0; // Configure to go in 125kHz listen mode - LFSetupFPGAForADC(95, true); + LFSetupFPGAForADC(LF_DIVISOR_125, true); //clear read buffer BigBuf_Clear_keep_EM(); @@ -1242,7 +1242,7 @@ void CmdAWIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol) BigBuf_Clear_keep_EM(); - LFSetupFPGAForADC(95, true); + LFSetupFPGAForADC(LF_DIVISOR_125, true); while (!BUTTON_PRESS() && !data_available()) { @@ -1334,7 +1334,7 @@ void CmdEM410xdemod(int findone, uint32_t *high, uint64_t *low, int ledcontrol) BigBuf_Clear_keep_EM(); - LFSetupFPGAForADC(95, true); + LFSetupFPGAForADC(LF_DIVISOR_125, true); while (!BUTTON_PRESS() && !data_available()) { @@ -1400,7 +1400,7 @@ void CmdIOdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol) { BigBuf_Clear_keep_EM(); // Configure to go in 125kHz listen mode - LFSetupFPGAForADC(95, true); + LFSetupFPGAForADC(LF_DIVISOR_125, true); while (!BUTTON_PRESS() && !data_available()) { WDT_HIT(); @@ -1651,7 +1651,7 @@ void T55xx_SendCMD(uint32_t data, uint32_t pwd, uint16_t arg) { // Send Bits to T55xx // Set up FPGA, 125kHz - LFSetupFPGAForADC(95, true); + LFSetupFPGAForADC(LF_DIVISOR_125, true); // make sure tag is fully powered up... WaitMS(start_wait); @@ -2274,7 +2274,7 @@ void SendForward(uint8_t fwd_bit_count) { fwd_bit_sz = fwd_bit_count; // Set up FPGA, 125kHz or 95 divisor - LFSetupFPGAForADC(95, true); + LFSetupFPGAForADC(LF_DIVISOR_125, true); // force 1st mod pulse (start gap must be longer for 4305) fwd_bit_sz--; //prepare next bit modulation @@ -2396,7 +2396,7 @@ void Cotag(uint32_t arg0) { LED_A_ON(); - LFSetupFPGAForADC(89, true); + LFSetupFPGAForADC(LF_DIVISOR_134, true); //clear buffer now so it does not interfere with timing later BigBuf_Clear_ext(false); diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index 59bb81d83..e8d507b29 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -95,9 +95,9 @@ void pushBit(BitstreamOut *stream, uint8_t bit) { void LFSetupFPGAForADC(int divisor, bool lf_field) { FpgaDownloadAndGo(FPGA_BITSTREAM_LF); if ((divisor == 1) || (divisor < 0) || (divisor > 255)) - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8kHz + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, LF_DIVISOR_134); //~134kHz else if (divisor == 0) - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125kHz + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, LF_DIVISOR_125); //125kHz else FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor); diff --git a/armsrc/pcf7931.c b/armsrc/pcf7931.c index 2bc101a48..21a739f45 100644 --- a/armsrc/pcf7931.c +++ b/armsrc/pcf7931.c @@ -32,7 +32,7 @@ size_t DemodPCF7931(uint8_t **outBlocks) { uint8_t dir; BigBuf_Clear_keep_EM(); - LFSetupFPGAForADC(95, true); + LFSetupFPGAForADC(LF_DIVISOR_125, true); DoAcquisition_default(0, true); /* Find first local max/min */ @@ -449,7 +449,7 @@ void SendCmdPCF7931(uint32_t *tab) { } FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125kHz + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, LF_DIVISOR_125); //125kHz FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU); LED_A_ON(); From 98d641dba5bb38fc9decd46d5786e4b067e2088a Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 9 Oct 2019 12:06:45 +0200 Subject: [PATCH 0882/1854] WaitUS/WaitMS: accept uint32_t --- armsrc/ticks.c | 8 ++++---- armsrc/ticks.h | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/armsrc/ticks.c b/armsrc/ticks.c index 7b66d17e6..0ce55e417 100644 --- a/armsrc/ticks.c +++ b/armsrc/ticks.c @@ -250,11 +250,11 @@ void WaitTicks(uint32_t ticks) { // Wait / Spindelay in us (microseconds) // 1us = 1.5ticks. -void WaitUS(uint16_t us) { - WaitTicks((uint32_t)us * 3 / 2); +void WaitUS(uint32_t us) { + WaitTicks((us & 0x3FFFFFFF) * 3 / 2); } -void WaitMS(uint16_t ms) { - WaitTicks((uint32_t)ms * 1500); +void WaitMS(uint32_t ms) { + WaitTicks((ms & 0x1FFFFF) * 1500); } // stop clock diff --git a/armsrc/ticks.h b/armsrc/ticks.h index e036e018c..b39ec52bd 100644 --- a/armsrc/ticks.h +++ b/armsrc/ticks.h @@ -38,8 +38,8 @@ uint32_t RAMFUNC GetCountSspClkDelta(); void StartTicks(void); uint32_t GetTicks(void); void WaitTicks(uint32_t ticks); -void WaitUS(uint16_t us); -void WaitMS(uint16_t ms); +void WaitUS(uint32_t us); +void WaitMS(uint32_t ms); void StopTicks(void); From 6d3adf71b61b0d552bfaa36d094ff366a3458c01 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 9 Oct 2019 12:44:17 +0200 Subject: [PATCH 0883/1854] coverity 226370 - fix resource leak --- client/emv/emv_pki_priv.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/client/emv/emv_pki_priv.c b/client/emv/emv_pki_priv.c index f10c5352b..db8b6381d 100644 --- a/client/emv/emv_pki_priv.c +++ b/client/emv/emv_pki_priv.c @@ -196,7 +196,6 @@ static struct tlvdb *emv_pki_sign_key(const struct crypto_pk *cp, struct tlvdb *exp_db = tlvdb_fixed(exp_tag, ipk->elen, ipk->exp); if (!exp_db) { free(msg); - return NULL; } @@ -207,8 +206,10 @@ static struct tlvdb *emv_pki_sign_key(const struct crypto_pk *cp, add_tlv, NULL); free(msg); - if (!db) + if (!db) { + free(exp_db); return NULL; + } tlvdb_add(db, exp_db); From 0aa88aecf52d290ddfacce63aaac6dcc72ac48b9 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 9 Oct 2019 12:45:12 +0200 Subject: [PATCH 0884/1854] coverity - fix tainted --- client/emv/emv_pk.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/emv/emv_pk.c b/client/emv/emv_pk.c index 8465a6e95..3d64e6326 100644 --- a/client/emv/emv_pk.c +++ b/client/emv/emv_pk.c @@ -408,7 +408,8 @@ static struct emv_pk *emv_pk_get_ca_pk_from_file(const char *fname, char buf[2048]; if (fgets(buf, sizeof(buf), f) == NULL) break; - + if (buf == NULL) + break; struct emv_pk *pk = emv_pk_parse_pk(buf); if (!pk) continue; From b9c020a1dd2d275e0c07bd208655073f10de2628 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 9 Oct 2019 12:46:01 +0200 Subject: [PATCH 0885/1854] coverity 227802 - fix uninitialized --- client/cmdscript.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdscript.c b/client/cmdscript.c index f8306c041..322fd6adb 100644 --- a/client/cmdscript.c +++ b/client/cmdscript.c @@ -55,7 +55,7 @@ static int CmdScriptRun(const char *Cmd) { static uint8_t luascriptfile_idx = 0; sscanf(Cmd, "%127s%n %255[^\n\r]%n", preferredName, &name_len, arguments, &arg_len); - char *script_path; + char *script_path = NULL; if ((!str_endswith(preferredName, ".cmd")) && (searchFile(&script_path, LUA_SCRIPTS_SUBDIR, preferredName, ".lua", true) == PM3_SUCCESS)) { int error; if (luascriptfile_idx == MAX_NESTED_LUASCRIPT) { From efe5e33acb69e6fd1141a02abf2fb4ac5ee25797 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 9 Oct 2019 12:48:43 +0200 Subject: [PATCH 0886/1854] coverity 226283 - fix out-of-bounds. Maybe a bit too large buffer now. --- armsrc/dbprint.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/armsrc/dbprint.c b/armsrc/dbprint.c index a26b7ba8b..499703ef1 100644 --- a/armsrc/dbprint.c +++ b/armsrc/dbprint.c @@ -44,7 +44,7 @@ void DbpString(char *str) { void DbprintfEx(uint32_t flags, const char *fmt, ...) { #if DEBUG // should probably limit size here; oh well, let's just use a big buffer - char output_string[128] = {0x00}; + char output_string[PM3_CMD_DATA_SIZE] = {0x00}; va_list ap; va_start(ap, fmt); kvsprintf(fmt, output_string, 10, ap); @@ -57,7 +57,7 @@ void DbprintfEx(uint32_t flags, const char *fmt, ...) { void Dbprintf(const char *fmt, ...) { #if DEBUG // should probably limit size here; oh well, let's just use a big buffer - char output_string[128] = {0x00}; + char output_string[PM3_CMD_DATA_SIZE] = {0x00}; va_list ap; va_start(ap, fmt); From 201817d7e47a8d18a26f214938893e5aa3c573c9 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 9 Oct 2019 12:56:11 +0200 Subject: [PATCH 0887/1854] coverity 226430 - printf args --- client/cmdhfmfu.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index 8ac391a6e..e3ae2f0e1 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -856,10 +856,10 @@ int ul_print_type(uint32_t tagtype, uint8_t spaces) { } static int ulc_print_3deskey(uint8_t *data) { - PrintAndLogEx(NORMAL, " deskey1 [44/0x2C] : %s [s]", sprint_hex(data, 4), sprint_ascii(data, 4)); - PrintAndLogEx(NORMAL, " deskey1 [45/0x2D] : %s [s]", sprint_hex(data + 4, 4), sprint_ascii(data + 4, 4)); - PrintAndLogEx(NORMAL, " deskey2 [46/0x2E] : %s [s]", sprint_hex(data + 8, 4), sprint_ascii(data + 8, 4)); - PrintAndLogEx(NORMAL, " deskey2 [47/0x2F] : %s [s]", sprint_hex(data + 12, 4), sprint_ascii(data + 12, 4)); + PrintAndLogEx(NORMAL, " deskey1 [44/0x2C] : %s [%s]", sprint_hex(data, 4), sprint_ascii(data, 4)); + PrintAndLogEx(NORMAL, " deskey1 [45/0x2D] : %s [%s]", sprint_hex(data + 4, 4), sprint_ascii(data + 4, 4)); + PrintAndLogEx(NORMAL, " deskey2 [46/0x2E] : %s [%s]", sprint_hex(data + 8, 4), sprint_ascii(data + 8, 4)); + PrintAndLogEx(NORMAL, " deskey2 [47/0x2F] : %s [%s]", sprint_hex(data + 12, 4), sprint_ascii(data + 12, 4)); PrintAndLogEx(NORMAL, "\n 3des key : %s", sprint_hex(SwapEndian64(data, 16, 8), 16)); return PM3_SUCCESS; } From 2b50ccbef81649f6c94be33ddb2058624480e76c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 9 Oct 2019 13:00:22 +0200 Subject: [PATCH 0888/1854] coverity 226404 - fix ignoring number.. --- client/amiitool/amiibo.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/client/amiitool/amiibo.c b/client/amiitool/amiibo.c index d8fe837b1..36b9ae967 100644 --- a/client/amiitool/amiibo.c +++ b/client/amiitool/amiibo.c @@ -137,16 +137,15 @@ bool nfc3d_amiibo_load_keys(nfc3d_amiibo_keys *amiiboKeys, const char *path) { return false; } - if (!fread(amiiboKeys, sizeof(*amiiboKeys), 1, f)) { - fclose(f); - return false; - } + size_t len = fread(amiiboKeys, sizeof(*amiiboKeys), 1, f); fclose(f); - if ( - (amiiboKeys->data.magicBytesSize > 16) || - (amiiboKeys->tag.magicBytesSize > 16) - ) { + if (len != sizeof(*amiiboKeys)) { + return false; + } + + if ((amiiboKeys->data.magicBytesSize > 16) || + (amiiboKeys->tag.magicBytesSize > 16)) { return false; } From 86a47a3282476c6e9a6b44f11898e8383c747f52 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 9 Oct 2019 13:03:23 +0200 Subject: [PATCH 0889/1854] dangerous stuff... --- armsrc/appmain.c | 4 +++ armsrc/lfops.c | 39 +++++++++++++++++++++++++++ armsrc/lfops.h | 1 + client/cmdlft55xx.c | 64 +++++++++++++++++++++++++++++++++++++++++++++ include/pm3_cmd.h | 7 +++++ 5 files changed, 115 insertions(+) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 5c645062d..248346b4f 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -804,6 +804,10 @@ static void PacketReceived(PacketCommandNG *packet) { T55xxWriteBlock(packet->data.asBytes); break; } + case CMD_LF_T55XX_DANGERRAW: { + T55xxDangerousRawTest(packet->data.asBytes); + break; + } case CMD_LF_T55XX_WAKEUP: { struct p { uint32_t password; diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 862f31626..5ff1867de 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -1703,6 +1703,45 @@ void T55xxResetRead(uint8_t flags) { LED_A_OFF(); } +void T55xxDangerousRawTest(uint8_t *data) { + // supports only default downlink mode + t55xx_test_block_t *c = (t55xx_test_block_t *)data; + + uint8_t start_wait = 4; + uint8_t bs[128/8]; + memset(bs, 0x00, sizeof(bs)); + uint8_t len = 0; + if (c->bitlen == 0 || c->bitlen > 128 || c->time == 0) + reply_ng(CMD_LF_T55XX_DANGERRAW, PM3_EINVARG, NULL, 0); + for (uint8_t i=0; ibitlen; i++) + len = T55xx_SetBits(bs, len, c->data[i], 1, sizeof(bs)); + + if (DBGLEVEL > 1) { + Dbprintf("LEN %i, TIMING %i", len, c->time); + for (uint8_t i = 0; i < len; i++) { + uint8_t sendbits = (bs[BITSTREAM_BYTE(i)] >> BITSTREAM_BIT(i)); + Dbprintf("%02i: %i", i, sendbits & 1); + } + } + + LED_A_ON(); + LFSetupFPGAForADC(LF_DIVISOR_125, true); + // make sure tag is fully powered up... + WaitMS(start_wait); + // Trigger T55x7 in mode. + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + WaitUS(T55xx_Timing.m[0].start_gap); + uint8_t sendbits; + for (uint8_t i = 0; i < len; i++) { + sendbits = (bs[BITSTREAM_BYTE(i)] >> BITSTREAM_BIT(i)); + T55xxWriteBit(sendbits & 1, 0); + } + TurnReadLFOn(c->time); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + reply_ng(CMD_LF_T55XX_DANGERRAW, PM3_SUCCESS, NULL, 0); + LED_A_OFF(); +} + // Write one card block in page 0, no lock //void T55xxWriteBlockExt(uint32_t data, uint8_t blockno, uint32_t pwd, uint8_t flags) { void T55xxWriteBlock(uint8_t *data) { diff --git a/armsrc/lfops.h b/armsrc/lfops.h index bf246b529..f81d1e7ab 100644 --- a/armsrc/lfops.h +++ b/armsrc/lfops.h @@ -52,6 +52,7 @@ void T55xxWriteBlock(uint8_t *data); void T55xxReadBlock(uint8_t page, bool pwd_mode, bool brute_mem, uint8_t block, uint32_t pwd, uint8_t downlink_mode); void T55xxWakeUp(uint32_t pwd, uint8_t flags); void T55xx_ChkPwds(uint8_t flags); +void T55xxDangerousRawTest(uint8_t *data); void TurnReadLFOn(uint32_t delay); diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 8053c2e76..b96dd4cb8 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -1672,6 +1672,69 @@ static int CmdT55xxWriteBlock(const char *Cmd) { return PM3_SUCCESS; } +static int CmdT55xxDangerousRaw(const char *Cmd) { + // supports only default downlink mode + t55xx_test_block_t ng; + ng.time = 0; + ng.bitlen = 0; + memset(ng.data, 0x00, sizeof(ng.data)); + bool errors = false; + uint8_t cmdp = 0; + + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { + case 't': + ng.time = param_get32ex(Cmd, cmdp + 1, 0, 10); + if (ng.time == 0 || ng.time > 200000) { + PrintAndLogEx(ERR, "Timing off 1..200000 limits, got %i", ng.time); + errors = true; + break; + } + cmdp += 2; + break; + case 'b': { + uint32_t n = param_getlength(Cmd, cmdp + 1); + if (n > 128) { + PrintAndLogEx(ERR, "Bitstream too long, max 128 bits, got %i", n); + errors = true; + break; + } + for (uint8_t i = 0; i < n; i++) { + char c = param_getchar_indx(Cmd, i, cmdp + 1); + if (c == '0') + ng.data[i] = 0; + else if (c == '1') + ng.data[i] = 1; + else { + PrintAndLogEx(ERR, "Unknown bit char '%c'", c); + errors = true; + break; + } + } + ng.bitlen = n; + cmdp += 2; + break; + } + default: + PrintAndLogEx(ERR, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } + } + if (errors || ng.bitlen == 0 || ng.time == 0) { + PrintAndLogEx(ERR, "Error occurred, abort. " _RED_("DANGEROUS COMMAND, DO NOT USE!")); + return PM3_EINVARG; + } + PacketResponseNG resp; + clearCommandBuffer(); + SendCommandNG(CMD_LF_T55XX_DANGERRAW, (uint8_t *)&ng, sizeof(ng)); + if (!WaitForResponseTimeout(CMD_LF_T55XX_DANGERRAW, &resp, 2000)) { + PrintAndLogEx(ERR, "Error occurred, device did not ACK write operation."); + return PM3_ETIMEOUT; + } + return resp.status; +} + static int CmdT55xxReadTrace(const char *Cmd) { bool frombuff = false; @@ -3400,6 +3463,7 @@ static command_t CommandTable[] = { {"bruteforce", CmdT55xxBruteForce, IfPm3Lf, " Simple bruteforce attack to find password"}, {"config", CmdT55xxSetConfig, AlwaysAvailable, "Set/Get T55XX configuration (modulation, inverted, offset, rate)"}, {"chk", CmdT55xxChkPwds, IfPm3Lf, "Check passwords from dictionary/flash"}, + {"dangerraw", CmdT55xxDangerousRaw, IfPm3Lf, "Sends raw bitstream. Dangerous, do not use!! b t "}, {"detect", CmdT55xxDetect, AlwaysAvailable, "[1] Try detecting the tag modulation from reading the configuration block."}, {"deviceconfig", CmdT55xxSetDeviceConfig, IfPm3Lf, "Set/Get T55XX device configuration (startgap, writegap, write0, write1, readgap"}, {"dump", CmdT55xxDump, IfPm3Lf, "[password] [o] Dump T55xx card Page 0 block 0-7. Optional [password], [override]"}, diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index ca778a495..a6d59aa05 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -198,6 +198,12 @@ typedef struct { uint8_t flags; } PACKED t55xx_write_block_t; +typedef struct { + uint8_t data[128]; + uint8_t bitlen; + uint32_t time; +} PACKED t55xx_test_block_t; + // For CMD_LF_HID_SIMULATE (FSK) typedef struct { uint32_t hi2; @@ -376,6 +382,7 @@ typedef struct { #define CMD_LF_SAMPLING_GET_CONFIG 0x0227 #define CMD_LF_T55XX_CHK_PWDS 0x0230 +#define CMD_LF_T55XX_DANGERRAW 0x0231 /* CMD_SET_ADC_MUX: ext1 is 0 for lopkd, 1 for loraw, 2 for hipkd, 3 for hiraw */ From 1ec34e00b673cfb4a699df98f8af74cd56663a1b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 9 Oct 2019 13:05:23 +0200 Subject: [PATCH 0890/1854] coverity 226386 - fix operands dont.. --- armsrc/mifaresim.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/armsrc/mifaresim.c b/armsrc/mifaresim.c index 93b950e6e..b1f419242 100644 --- a/armsrc/mifaresim.c +++ b/armsrc/mifaresim.c @@ -495,10 +495,10 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1 //allow collecting up to 7 sets of nonces to allow recovery of up to 7 keys #define ATTACK_KEY_COUNT 7 // keep same as define in cmdhfmf.c -> readerAttack() (Cannot be more than 7) - nonces_t ar_nr_resp[ATTACK_KEY_COUNT * 2]; //*2 for 2 separate attack types (nml, moebius) 36 * 7 * 2 bytes = 504 bytes + nonces_t ar_nr_resp[ATTACK_KEY_COUNT * 2]; // *2 for 2 separate attack types (nml, moebius) 36 * 7 * 2 bytes = 504 bytes memset(ar_nr_resp, 0x00, sizeof(ar_nr_resp)); - uint8_t ar_nr_collected[ATTACK_KEY_COUNT * 2]; //*2 for 2nd attack type (moebius) + uint8_t ar_nr_collected[ATTACK_KEY_COUNT * 2]; // *2 for 2nd attack type (moebius) memset(ar_nr_collected, 0x00, sizeof(ar_nr_collected)); uint8_t nonce1_count = 0; uint8_t nonce2_count = 0; @@ -719,8 +719,9 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1 // RCV: 61 XX => Using KEY B // XX: Block number + // iceman, u8 can never be larger than 256 // if authenticating to a block that shouldn't exist - as long as we are not doing the reader attack - if (receivedCmd_dec[1] > MIFARE_4K_MAXBLOCK && !((flags & FLAG_NR_AR_ATTACK) == FLAG_NR_AR_ATTACK)) { + if ( ((flags & FLAG_NR_AR_ATTACK) != FLAG_NR_AR_ATTACK) ) { EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA)); if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("Reader tried to operate (0x%02x) on out of range block: %d (0x%02x), nacking", receivedCmd_dec[0], receivedCmd_dec[1], receivedCmd_dec[1]); break; From 88424214227c50b210a1d8d1440e12c21deac95b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 9 Oct 2019 13:11:22 +0200 Subject: [PATCH 0891/1854] coverity 71844 - fix untrusted value. fgets could have nulled the pointer. --- client/proxmark3.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/proxmark3.c b/client/proxmark3.c index ced6ed5c5..31afe470f 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -160,6 +160,8 @@ check_script: if (!fgets(script_cmd_buf, sizeof(script_cmd_buf), current_cmdscriptfile())) { if (!pop_cmdscriptfile()) break; + if (script_cmd_buf == NULL) + break; goto check_script; } else { From ab222a06b99833f73e1a929d6681cd11b3ffb25b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 9 Oct 2019 13:19:47 +0200 Subject: [PATCH 0892/1854] ..revert --- client/emv/emv_pk.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/client/emv/emv_pk.c b/client/emv/emv_pk.c index 3d64e6326..fbd0e39a9 100644 --- a/client/emv/emv_pk.c +++ b/client/emv/emv_pk.c @@ -408,23 +408,21 @@ static struct emv_pk *emv_pk_get_ca_pk_from_file(const char *fname, char buf[2048]; if (fgets(buf, sizeof(buf), f) == NULL) break; - if (buf == NULL) - break; + struct emv_pk *pk = emv_pk_parse_pk(buf); if (!pk) continue; + if (memcmp(pk->rid, rid, 5) || pk->index != idx) { emv_pk_free(pk); continue; } fclose(f); - return pk; } fclose(f); - return NULL; } From 81e7e34a24cf760ac16c15875ac11aef10473b90 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 9 Oct 2019 13:44:51 +0200 Subject: [PATCH 0893/1854] revert tainted --- client/proxmark3.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/client/proxmark3.c b/client/proxmark3.c index 31afe470f..c6045d900 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -157,11 +157,9 @@ check_script: memset(script_cmd_buf, 0, sizeof(script_cmd_buf)); // read script file - if (!fgets(script_cmd_buf, sizeof(script_cmd_buf), current_cmdscriptfile())) { + if (fgets(script_cmd_buf, sizeof(script_cmd_buf), current_cmdscriptfile()) == NULL) { if (!pop_cmdscriptfile()) break; - if (script_cmd_buf == NULL) - break; goto check_script; } else { From 07a23b202cdeda89dfb2075987c2f260a0a5d426 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 9 Oct 2019 13:56:01 +0200 Subject: [PATCH 0894/1854] coverity 226308 - fix logically dead code --- include/protocols.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/protocols.h b/include/protocols.h index 747e4e346..4eb3ab58c 100644 --- a/include/protocols.h +++ b/include/protocols.h @@ -133,7 +133,7 @@ ISO 7816-4 Basic interindustry commands. For command APDU's. #define ICLASS_CMD_READ_OR_IDENTIFY 0xC #define ICLASS_CMD_ACT 0xE -#define ICLASS_CREDIT(x) (((x) & 0x5) == 1) +#define ICLASS_CREDIT(x) (((x) & 0x5) == 0x5) #define ICLASS_DEBIT(x) (((x) & 0x5) == 0) From 26c8f680fce5dda27368756eabacd1d6708d5b17 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 9 Oct 2019 14:14:27 +0200 Subject: [PATCH 0895/1854] coverity 226289 - printf --- client/emv/emvjson.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/emv/emvjson.c b/client/emv/emvjson.c index e1fd9111c..ee2245eb0 100644 --- a/client/emv/emvjson.c +++ b/client/emv/emvjson.c @@ -157,7 +157,7 @@ int JsonSaveTLVElm(json_t *elm, const char *path, struct tlv *tlvelm, bool saveN } } else { if (json_path_set(elm, path, obj, 0, &error)) { - PrintAndLogEx(ERR, "ERROR: can't set json path: ", error.text); + PrintAndLogEx(ERR, "ERROR: can't set json path: %s", error.text); return 2; } } From 3ba529612e0d0ce291c207b19787a39dcff611af Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 9 Oct 2019 14:17:28 +0200 Subject: [PATCH 0896/1854] coverity 226321 - printf --- client/cmdlfem4x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c index bd93a48ab..7d1266cdc 100644 --- a/client/cmdlfem4x.c +++ b/client/cmdlfem4x.c @@ -692,7 +692,7 @@ static int CmdEM410xWrite(const char *Cmd) { // the clock rate in bits 8-15 of the card value card = (card & 0xFF) | ((clock1 << 8) & 0xFF00); } else if (card == 0) { - PrintAndLogEx(SUCCESS, "Writing %s tag with UID 0x%010" PRIx64, "T5555", id, clock1); + PrintAndLogEx(SUCCESS, "Writing %s tag with UID 0x%010" PRIx64, "(clock rate: %d)"; "T5555", id, clock1); card = (card & 0xFF) | ((clock1 << 8) & 0xFF00); } else { PrintAndLogEx(FAILED, "Error! Bad card type selected.\n"); From be51e98d7cbdfe5cf05948a67e8f422b050ff31a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 9 Oct 2019 14:19:10 +0200 Subject: [PATCH 0897/1854] coverity 226361 - printf --- client/cmdhf14a.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index 14be6f7a7..519a8b0f2 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -553,7 +553,7 @@ int ExchangeRAW14a(uint8_t *datain, int datainlen, bool activateField, bool leav } if (resp.oldarg[0] != 1 && resp.oldarg[0] != 2) { - PrintAndLogEx(ERR, "Card not in iso14443-4. res=" PRId64 ".", resp.oldarg[0]); + PrintAndLogEx(ERR, "Card not in iso14443-4. res=%" PRId64 ".", resp.oldarg[0]); return 1; } From f1b15d8e076fd017390a9f87cd80d0434d2b2276 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 9 Oct 2019 14:21:09 +0200 Subject: [PATCH 0898/1854] coverity 226425 - printf --- client/emv/emvjson.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/emv/emvjson.c b/client/emv/emvjson.c index ee2245eb0..4a3ef9299 100644 --- a/client/emv/emvjson.c +++ b/client/emv/emvjson.c @@ -76,7 +76,7 @@ int JsonSaveJsonObject(json_t *root, const char *path, json_t *value) { if (path[0] == '$') { if (json_path_set(root, path, value, 0, &error)) { - PrintAndLogEx(ERR, "ERROR: can't set json path: ", error.text); + PrintAndLogEx(ERR, "ERROR: can't set json path: %s", error.text); return 2; } else { return 0; From 16f186694366af8765130501b031713a13ce35bb Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 9 Oct 2019 14:22:35 +0200 Subject: [PATCH 0899/1854] coverity 226410 - printf --- client/cmdhfmf.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 8671dc6c8..6b266e21e 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -2735,8 +2735,13 @@ static int CmdHF14AMfChk(const char *Cmd) { PrintAndLogEx(INFO, "No key specified, trying default keys"); for (; keycnt < ARRAYLEN(g_mifare_default_keys); keycnt++) PrintAndLogEx(NORMAL, "[%2d] %02x%02x%02x%02x%02x%02x", keycnt, - (keyBlock + 6 * keycnt)[0], (keyBlock + 6 * keycnt)[1], (keyBlock + 6 * keycnt)[2], - (keyBlock + 6 * keycnt)[3], (keyBlock + 6 * keycnt)[4], (keyBlock + 6 * keycnt)[5], 6); + (keyBlock + 6 * keycnt)[0], + (keyBlock + 6 * keycnt)[1], + (keyBlock + 6 * keycnt)[2], + (keyBlock + 6 * keycnt)[3], + (keyBlock + 6 * keycnt)[4], + (keyBlock + 6 * keycnt)[5] + ); } // initialize storage for found keys From 55c33e75efb056af6c51cd6cb4b7c05986dcc855 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 9 Oct 2019 14:25:13 +0200 Subject: [PATCH 0900/1854] coverity 226254... - printf --- client/cmdusart.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/client/cmdusart.c b/client/cmdusart.c index 3d664d516..8e8899dc8 100644 --- a/client/cmdusart.c +++ b/client/cmdusart.c @@ -391,7 +391,7 @@ static int CmdUsartBtFactory(const char *Cmd) { if (strcmp((char *)data, "OK+ROLE:S") == 0) { PrintAndLogEx(SUCCESS, "Role set to " _GREEN_("Slave")); } else { - PrintAndLogEx(WARNING, "Unexpected response to AT+ROLE=S: " _YELLOW_("%.*s"), len, data); + PrintAndLogEx(WARNING, "Unexpected response to AT+ROLE=S: " _YELLOW_("%.*s"), (int)len, data); } } else { PrintAndLogEx(WARNING, "Lost contact with add-on, please try again"); @@ -505,30 +505,33 @@ static int CmdUsartBtPin(const char *Cmd) { break; } } + //Validations if (errors || cmdp == 0) { usage_usart_bt_pin(); return PM3_EINVARG; } + char string[6 + sizeof(pin)] = {0}; sprintf(string, "AT+PIN%s", pin); uint8_t data[PM3_CMD_DATA_SIZE] = {0x00}; size_t len = 0; -// PrintAndLogEx(NORMAL, "TX (%3zu):%.*s", strlen(string), (int)strlen(string), string); int ret = usart_txrx((uint8_t *)string, strlen(string), data, &len, 600); + if (ret == PM3_ENODATA) { PrintAndLogEx(FAILED, "No response from add-on, is it ON and blinking?"); return ret; } + if (ret != PM3_SUCCESS) { PrintAndLogEx(FAILED, "Command failed, ret=%i", ret); return ret; } -// PrintAndLogEx(NORMAL, "RX (%3zu):%.*s", len, (int)len, data); + if (strcmp((char *)data, "OKsetPIN") == 0) { PrintAndLogEx(NORMAL, "PIN changed " _GREEN_("successfully")); } else { - PrintAndLogEx(WARNING, "Unexpected answer: %.*s", len, data); + PrintAndLogEx(WARNING, "Unexpected answer: %.*s", (int)len, data); } return PM3_SUCCESS; } @@ -621,7 +624,7 @@ static int CmdUsartRX(const char *Cmd) { int ret = usart_rx(data, &len, waittime); if (ret != PM3_SUCCESS) return ret; - PrintAndLogEx(NORMAL, "RX:%.*s", len, data); + PrintAndLogEx(NORMAL, "RX:%.*s", (int)len, data); return PM3_SUCCESS; } From 9b0e70ca279aab3be921e16ac18d1588348661e8 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 9 Oct 2019 14:28:52 +0200 Subject: [PATCH 0901/1854] fixes --- client/cmdlfawid.c | 2 +- client/cmdlfem4x.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/client/cmdlfawid.c b/client/cmdlfawid.c index 641c29720..5084edf6a 100644 --- a/client/cmdlfawid.c +++ b/client/cmdlfawid.c @@ -219,7 +219,7 @@ static int CmdAWIDDemod(const char *Cmd) { else if (idx == -4) PrintAndLogEx(DEBUG, "DEBUG: Error - AWID preamble not found"); else if (idx == -5) - PrintAndLogEx(DEBUG, "DEBUG: Error - AWID size not correct, size %d", size); + PrintAndLogEx(DEBUG, "DEBUG: Error - AWID size not correct, size %zu", size); else PrintAndLogEx(DEBUG, "DEBUG: Error - AWID error demoding fsk %d", idx); diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c index 7d1266cdc..2bfb25eaa 100644 --- a/client/cmdlfem4x.c +++ b/client/cmdlfem4x.c @@ -692,7 +692,7 @@ static int CmdEM410xWrite(const char *Cmd) { // the clock rate in bits 8-15 of the card value card = (card & 0xFF) | ((clock1 << 8) & 0xFF00); } else if (card == 0) { - PrintAndLogEx(SUCCESS, "Writing %s tag with UID 0x%010" PRIx64, "(clock rate: %d)"; "T5555", id, clock1); + PrintAndLogEx(SUCCESS, "Writing %s tag with UID 0x%010" PRIx64, "(clock rate: %d)", "T5555", id, clock1); card = (card & 0xFF) | ((clock1 << 8) & 0xFF00); } else { PrintAndLogEx(FAILED, "Error! Bad card type selected.\n"); From 0556c835700dec6ad6bbb5d1aca2fab935ed1de6 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 9 Oct 2019 14:30:50 +0200 Subject: [PATCH 0902/1854] fixes --- client/cmdlfhid.c | 2 +- client/mifare/ndef.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/client/cmdlfhid.c b/client/cmdlfhid.c index 1ec068a4f..de7d9ecd5 100644 --- a/client/cmdlfhid.c +++ b/client/cmdlfhid.c @@ -246,7 +246,7 @@ static int CmdHIDDemod(const char *Cmd) { } } - PrintAndLogEx(DEBUG, "DEBUG: HID idx: %d, Len: %d, Printing Demod Buffer:", idx, size); + PrintAndLogEx(DEBUG, "DEBUG: HID idx: %d, Len: %zu, Printing Demod Buffer:", idx, size); if (g_debugMode) printDemodBuff(); diff --git a/client/mifare/ndef.c b/client/mifare/ndef.c index f4575c893..946b80b04 100644 --- a/client/mifare/ndef.c +++ b/client/mifare/ndef.c @@ -186,7 +186,7 @@ static int ndefDecodeSig(uint8_t *sig, size_t siglen) { if (sigURI) { size_t intsigurilen = (sig[indx] << 8) + sig[indx + 1]; indx += 2; - PrintAndLogEx(NORMAL, "\tsignature uri [%zu]: %.*s", intsigurilen, intsigurilen, &sig[indx]); + PrintAndLogEx(NORMAL, "\tsignature uri [%zu]: %.*s", intsigurilen, (int)intsigurilen, &sig[indx]); indx += intsigurilen; } From d8dba632becb478df78be12d6834b79be18f3c4a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 9 Oct 2019 15:06:22 +0200 Subject: [PATCH 0903/1854] coverity 226322 - resourceleak --- client/emv/crypto_polarssl.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/emv/crypto_polarssl.c b/client/emv/crypto_polarssl.c index b87dd9ee0..a6f69a529 100644 --- a/client/emv/crypto_polarssl.c +++ b/client/emv/crypto_polarssl.c @@ -260,6 +260,7 @@ static unsigned char *crypto_pk_polarssl_get_parameter(const struct crypto_pk *_ res = mbedtls_mpi_write_binary(&cp->ctx.N, result, *plen); if (res < 0) { printf("Error write_binary."); + free(result); result = 0; } break; @@ -271,6 +272,7 @@ static unsigned char *crypto_pk_polarssl_get_parameter(const struct crypto_pk *_ res = mbedtls_mpi_write_binary(&cp->ctx.E, result, *plen); if (res < 0) { printf("Error write_binary."); + free(result); result = 0; } break; From 69274a1184aaf4bfb6ccde21255e3ec46e836721 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 9 Oct 2019 15:23:58 +0200 Subject: [PATCH 0904/1854] fix --- client/cmdtrace.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/client/cmdtrace.c b/client/cmdtrace.c index 836c0b9eb..29c3732f8 100644 --- a/client/cmdtrace.c +++ b/client/cmdtrace.c @@ -153,6 +153,8 @@ static uint16_t printHexLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trac return tracepos; } + uint16_t ret; + switch (protocol) { case ISO_14443A: { /* https://www.kaiser.cx/pcap-iso14443.html defines a pseudo header: @@ -185,16 +187,14 @@ static uint16_t printHexLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trac temp_str1, temp_str2, line); - return tracepos; + ret = tracepos; } default: PrintAndLogEx(NORMAL, "Currently only 14a supported"); - return traceLen; + ret = traceLen; } - if (is_last_record(tracepos, trace, traceLen)) return traceLen; - - return tracepos; + return ret; } static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, uint8_t protocol, bool showWaitCycles, bool markCRCBytes) { From 89dd574f53e6aea5917e24868cda74662775a051 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 9 Oct 2019 15:29:42 +0200 Subject: [PATCH 0905/1854] new coverity scripts --- .coverity.conf.sample | 35 ++++++++++++++++++++++++++++++++ covbuild.sh | 46 ++++++++++++++----------------------------- covconfig.sh | 13 +++--------- covsubmit.sh | 31 +++++++++++++++++++++++++++++ 4 files changed, 84 insertions(+), 41 deletions(-) create mode 100644 .coverity.conf.sample create mode 100755 covsubmit.sh diff --git a/.coverity.conf.sample b/.coverity.conf.sample new file mode 100644 index 000000000..2beb3e519 --- /dev/null +++ b/.coverity.conf.sample @@ -0,0 +1,35 @@ +COVLOGIN=myemail@corp.com +COVTOKEN=aAbBcCdDeEfFgGhHiIjJkK +COVBINDIR="/opt/cov-analysis-linux64-2019.03/bin" +# Nickname included in scan description: +NICKNAME=myself + +COVDIR=cov-int +COVBUILD="cov-build --dir $COVDIR" + +# Depending if your kernel > 4.8.x, you might need to activate this to run Coverity executables +# (but latest tools with kernel 5.2 run fine) +#sysctl vsyscall=emulate + +export PATH="$PATH:$COVBINDIR" + +function pre_build_hook() { + # tmp dir will be /tmp/cov-$username/ + # It's the good place if you need to redirect to elsewhere with a symlink + return 0 +} + +function post_build_hook() { + return 0 +} + +function pre_submit_hook() { + return 0 +} + +function post_submit_hook() { + # Clean up build folders? + rm -rf "$COVDIR" + echo "Coverity build cleaned" + return 0 +} diff --git a/covbuild.sh b/covbuild.sh index ab6273d73..bd06630d4 100755 --- a/covbuild.sh +++ b/covbuild.sh @@ -1,36 +1,20 @@ #!/bin/bash -## 2016-01-16, Iceman -## build script for Coverity Scan of the proxmark3 source code +set -e +. .coverity.conf || exit 1 -## clean up pre-compiled objects. +pre_build_hook + +rm -rf "$COVDIR" +mkdir "$COVDIR" make clean +$COVBUILD make -j 4 bootrom +$COVBUILD make -j 4 fullimage +$COVBUILD make -j 4 mfkey +$COVBUILD make -j 4 nonce2key +$COVBUILD make -j 4 fpga_compress +# make sure to do client after ARM because Coverity retains one build info per file +# and we want the client-side of the common/ analysis +$COVBUILD make -j 4 client -## coverity build -/home/user/cov-analysis-linux-2017.07/bin/cov-build --dir cov-int make all - -## delete all previous tarballs -rm proxmark3.all.*.tgz - -## -VERSION="0.1.`date --date now +%H%M`" -TODAY="`date --date now +%Y%m%d.%H%M`" -DESCNAME="autoMango.$TODAY" -FILENAME=proxmark3.all.$TODAY.tgz - -## create tarball -tar cfz $FILENAME cov-int -echo "Coverity build file is ready" - -## clean up build folders -rm -rf cov-int -echo "Coverity build cleaned" - -## upload tarball to Coverity.com -curl --form token=dY262wIFmfkcRkA5Pyw0eA \ - --form email=herrmann1001@gmail.com \ - --form file=@$FILENAME \ - --form version="$VERSION" \ - --form description="$DESCNAME" \ - https://scan.coverity.com/builds?project=proxmark3_iceman_fork -echo "tarball uploaded to Coverity for analyse" +post_build_hook diff --git a/covconfig.sh b/covconfig.sh index 91b59ceaa..5f4878b3c 100755 --- a/covconfig.sh +++ b/covconfig.sh @@ -1,13 +1,6 @@ #!/bin/bash -## 20160116, iceman -## remove old -rm /home/user/cov-analysis-linux-2017.07/config/coverity_config.xml -rm -rf /home/user/cov-analysis-linux-2017.07/config/gcc-config-? -rm -rf /home/user/cov-analysis-linux-2017.07/config/g++-config-? - - ## Configure ARM , make sure you have the arm gcc in your $PATH variable. -#/home/user/cov-analysis-linux-2017.07/bin/cov-configure -co arm-none-eabi-gcc -- -mthumb-interwork -/home/user/cov-analysis-linux-2017.07/bin/cov-configure -co arm-none-eabi-gcc -- -std=c99 -mthumb -mthumb-interwork +set -e +. .coverity.conf || exit 1 -echo "Done." \ No newline at end of file +cov-configure --template --compiler arm-none-eabi-gcc --comptype gcc diff --git a/covsubmit.sh b/covsubmit.sh new file mode 100755 index 000000000..daa8d203d --- /dev/null +++ b/covsubmit.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +set -e +. .coverity.conf || exit 1 + +pre_submit_hook + +## delete all previous tarballs +rm proxmark3.all.*.tgz + +VERSION="0.1.$(date --date now +%H%M)" +TODAY="$(date --date now +%Y%m%d.%H%M)" +DESCNAME="manual_by_$NICKNAME.$TODAY" +FILENAME="proxmark3.all.$TODAY.tgz" +LOGFILENAME="${FILENAME/.tgz/.log}" + +## create tarball +tar cfz "$FILENAME" "$COVDIR" || exit $? +echo "Coverity build file is ready" + +## upload tarball to Coverity.com +curl --progress-bar --fail \ + --form token="$COVTOKEN" \ + --form email="$COVLOGIN" \ + --form file="@$FILENAME" \ + --form version="$VERSION" \ + --form description="$DESCNAME" \ + https://scan.coverity.com/builds?project=Proxmark3+RRG+Iceman+repo | tee -a "${LOGFILENAME}" ; test "${PIPESTATUS[0]}" -eq 0 || exit $? +echo "tarball uploaded to Coverity for analyse" + +post_submit_hook From 9fac99025b15ab22d467c8ef4bbffb526d208d49 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 9 Oct 2019 16:40:01 +0200 Subject: [PATCH 0906/1854] fix bunch of printf api warnings in common/lfdemod.c --- common/lfdemod.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/common/lfdemod.c b/common/lfdemod.c index f555c8f65..1d1749d8e 100644 --- a/common/lfdemod.c +++ b/common/lfdemod.c @@ -324,13 +324,13 @@ bool preambleSearchEx(uint8_t *bits, uint8_t *preamble, size_t pLen, size_t *siz //first index found foundCnt++; if (foundCnt == 1) { - if (g_debugMode >= 1) prnt("DEBUG: (preambleSearchEx) preamble found at %i", idx); + if (g_debugMode >= 1) prnt("DEBUG: (preambleSearchEx) preamble found at %zu", idx); *startIdx = idx; if (findone) return true; } if (foundCnt == 2) { - if (g_debugMode >= 1) prnt("DEBUG: (preambleSearchEx) preamble 2 found at %i", idx); + if (g_debugMode >= 1) prnt("DEBUG: (preambleSearchEx) preamble 2 found at %zu", idx); *size = idx - *startIdx; return true; } @@ -361,7 +361,7 @@ static size_t findModStart(uint8_t *src, size_t size, uint8_t expWaveSize) { } if (thresholdCnt > 10) break; } - if (g_debugMode == 2) prnt("DEBUG: threshold Count reached at index %u, count: %u", i, thresholdCnt); + if (g_debugMode == 2) prnt("DEBUG: threshold Count reached at index %zu, count: %u", i, thresholdCnt); return i; } @@ -436,7 +436,7 @@ size_t pskFindFirstPhaseShift(uint8_t *samples, size_t size, uint8_t *curPhase, // find peak // was "samples[i] + fc" but why? must have been used to weed out some wave error... removed.. if (samples[i] < samples[i + 1] && samples[i + 1] >= samples[i + 2]) { waveEnd = i + 1; - if (g_debugMode == 2) prnt("DEBUG PSK: waveEnd: %u, waveStart: %u", waveEnd, waveStart); + if (g_debugMode == 2) prnt("DEBUG PSK: waveEnd: %zu, waveStart: %zu", waveEnd, waveStart); waveLenCnt = waveEnd - waveStart; if (waveLenCnt > fc && waveStart > fc && !(waveLenCnt > fc + 8)) { //not first peak and is a large wave but not out of whack lastAvgWaveVal = avgWaveVal / (waveLenCnt); @@ -1021,7 +1021,7 @@ uint16_t countFC(uint8_t *bits, size_t size, bool fskAdj) { fcL = fcLens[best1]; } if ((size - 180) / fcH / 3 > fcCnts[best1] + fcCnts[best2]) { - if (g_debugMode == 2) prnt("DEBUG countfc: fc is too large: %u > %u. Not psk or fsk", (size - 180) / fcH / 3, fcCnts[best1] + fcCnts[best2]); + if (g_debugMode == 2) prnt("DEBUG countfc: fc is too large: %zu > %u. Not psk or fsk", (size - 180) / fcH / 3, fcCnts[best1] + fcCnts[best2]); return 0; //lots of waves not psk or fsk } // TODO: take top 3 answers and compare to known Field clocks to get top 2 @@ -1072,7 +1072,7 @@ int DetectPSKClock(uint8_t *dest, size_t size, int clock, size_t *firstPhaseShif } *firstPhaseShift = firstFullWave; - if (g_debugMode == 2) prnt("DEBUG PSK: firstFullWave: %d, waveLen: %d", firstFullWave, fullWaveLen); + if (g_debugMode == 2) prnt("DEBUG PSK: firstFullWave: %zu, waveLen: %d", firstFullWave, fullWaveLen); //test each valid clock from greatest to smallest to see which lines up for (clkCnt = 7; clkCnt >= 1 ; clkCnt--) { @@ -1081,7 +1081,7 @@ int DetectPSKClock(uint8_t *dest, size_t size, int clock, size_t *firstPhaseShif size_t waveStart = 0; uint16_t errCnt = 0; uint16_t peakcnt = 0; - if (g_debugMode == 2) prnt("DEBUG PSK: clk: %d, lastClkBit: %d", clk[clkCnt], lastClkBit); + if (g_debugMode == 2) prnt("DEBUG PSK: clk: %d, lastClkBit: %zu", clk[clkCnt], lastClkBit); for (i = firstFullWave + fullWaveLen - 1; i < loopCnt - 2; i++) { //top edge of wave = start of new wave @@ -1093,7 +1093,7 @@ int DetectPSKClock(uint8_t *dest, size_t size, int clock, size_t *firstPhaseShif waveLenCnt = waveEnd - waveStart; if (waveLenCnt > *fc) { //if this wave is a phase shift - if (g_debugMode == 2) prnt("DEBUG PSK: phase shift at: %d, len: %d, nextClk: %d, i: %d, fc: %d", waveStart, waveLenCnt, lastClkBit + clk[clkCnt] - tol, i + 1, *fc); + if (g_debugMode == 2) prnt("DEBUG PSK: phase shift at: %zu, len: %d, nextClk: %zu, i: %zu, fc: %d", waveStart, waveLenCnt, lastClkBit + clk[clkCnt] - tol, i + 1, *fc); if (i + 1 >= lastClkBit + clk[clkCnt] - tol) { //should be a clock bit peakcnt++; lastClkBit += clk[clkCnt]; @@ -1325,7 +1325,7 @@ bool DetectST(uint8_t *buffer, size_t *size, int *foundclock, size_t *ststart, s // padd the amount off - could be problematic... but shouldn't happen often datalen -= datalen % clk; } else { - if (g_debugMode == 2) prnt("DEBUG STT: datalen not divisible by clk: %u %% %d = %d - quitting", datalen, clk, datalen % clk); + if (g_debugMode == 2) prnt("DEBUG STT: datalen not divisible by clk: %zu %% %d = %zu - quitting", datalen, clk, datalen % clk); return false; } // if datalen is less than one t55xx block - ERROR @@ -1346,7 +1346,7 @@ bool DetectST(uint8_t *buffer, size_t *size, int *foundclock, size_t *ststart, s size_t newloc = 0; i = 0; - if (g_debugMode == 2) prnt("DEBUG STT: Starting STT trim - start: %d, datalen: %d ", dataloc, datalen); + if (g_debugMode == 2) prnt("DEBUG STT: Starting STT trim - start: %zu, datalen: %zu ", dataloc, datalen); bool firstrun = true; // warning - overwriting buffer given with raw wave data with ST removed... while (dataloc < bufsize - (clk / 2)) { @@ -1376,7 +1376,7 @@ bool DetectST(uint8_t *buffer, size_t *size, int *foundclock, size_t *ststart, s } newloc += i; //skip next ST - we just assume it will be there from now on... - if (g_debugMode == 2) prnt("DEBUG STT: skipping STT at %d to %d", dataloc, dataloc + (clk * 4)); + if (g_debugMode == 2) prnt("DEBUG STT: skipping STT at %zu to %zu", dataloc, dataloc + (clk * 4)); dataloc += clk * 4; } *size = newloc; @@ -1549,7 +1549,7 @@ static uint16_t cleanAskRawDemod(uint8_t *bits, size_t *size, int clk, int inver if (smplCnt > clk + cl_4 + 1) { //too many samples errCnt++; - if (g_debugMode == 2) prnt("DEBUG ASK: cleanAskRawDemod ASK Modulation Error FULL at: %u [%u > %u]", i, smplCnt, clk + cl_4 + 1); + if (g_debugMode == 2) prnt("DEBUG ASK: cleanAskRawDemod ASK Modulation Error FULL at: %zu [%zu > %u]", i, smplCnt, clk + cl_4 + 1); bits[bitCnt++] = 7; } else if (waveHigh) { bits[bitCnt++] = invert; @@ -1570,7 +1570,7 @@ static uint16_t cleanAskRawDemod(uint8_t *bits, size_t *size, int clk, int inver if (smplCnt > cl_2 + cl_4 + 1) { //too many samples errCnt++; - if (g_debugMode == 2) prnt("DEBUG ASK: cleanAskRawDemod ASK Modulation Error HALF at: %u [%u]", i, smplCnt); + if (g_debugMode == 2) prnt("DEBUG ASK: cleanAskRawDemod ASK Modulation Error HALF at: %zu [%zu]", i, smplCnt); bits[bitCnt++] = 7; } @@ -1645,7 +1645,7 @@ int askdemod_ext(uint8_t *bits, size_t *size, int *clk, int *invert, int maxErr, errCnt = manrawdecode(bits, size, 0, &alignPos); *startIdx += ((*clk / 2) * alignPos); - prnt("DEBUG: (askdemod_ext) CLEAN: startIdx %i, alignPos %u , bestError %u", *startIdx, alignPos, errCnt); + prnt("DEBUG: (askdemod_ext) CLEAN: startIdx %i, alignPos %u , bestError %zu", *startIdx, alignPos, errCnt); } return errCnt; } @@ -1870,10 +1870,10 @@ static size_t aggregate_bits(uint8_t *dest, size_t size, uint8_t clk, uint8_t in if (numBits == 0) { if (lastval == 1) { //high to low *startIdx += (fclow * i) - (n * clk); - if (g_debugMode == 2) prnt("DEBUG (aggregate_bits) FSK startIdx %i, fclow*idx %i, n*clk %u", *startIdx, fclow * i, n * clk); + if (g_debugMode == 2) prnt("DEBUG (aggregate_bits) FSK startIdx %i, fclow*idx %zu, n*clk %u", *startIdx, fclow * i, n * clk); } else { *startIdx += (fchigh * i) - (n * clk); - if (g_debugMode == 2) prnt("DEBUG (aggregate_bits) FSK startIdx %i, fchigh*idx %i, n*clk %u", *startIdx, fchigh * i, n * clk); + if (g_debugMode == 2) prnt("DEBUG (aggregate_bits) FSK startIdx %i, fchigh*idx %zu, n*clk %u", *startIdx, fchigh * i, n * clk); } } @@ -1984,8 +1984,8 @@ int pskRawDemod_ext(uint8_t *dest, size_t *size, int *clock, int *invert, int *s //set start of wave as clock align lastClkBit = firstFullWave; if (g_debugMode == 2) { - prnt("DEBUG PSK: firstFullWave: %u, waveLen: %u, startIdx %i", firstFullWave, fullWaveLen, *startIdx); - prnt("DEBUG PSK: clk: %d, lastClkBit: %u, fc: %u", *clock, lastClkBit, fc); + prnt("DEBUG PSK: firstFullWave: %zu, waveLen: %u, startIdx %i", firstFullWave, fullWaveLen, *startIdx); + prnt("DEBUG PSK: clk: %d, lastClkBit: %zu, fc: %u", *clock, lastClkBit, fc); } waveStart = 0; From a00e016643224c338c2f225580ec133556b2c2ee Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 9 Oct 2019 16:40:08 +0200 Subject: [PATCH 0907/1854] text --- .coverity.conf.sample | 1 + 1 file changed, 1 insertion(+) diff --git a/.coverity.conf.sample b/.coverity.conf.sample index 2beb3e519..3ed4be64b 100644 --- a/.coverity.conf.sample +++ b/.coverity.conf.sample @@ -1,5 +1,6 @@ COVLOGIN=myemail@corp.com COVTOKEN=aAbBcCdDeEfFgGhHiIjJkK +# Toolchain available at https://scan.coverity.com/download COVBINDIR="/opt/cov-analysis-linux64-2019.03/bin" # Nickname included in scan description: NICKNAME=myself From 2b42e79a2f461a1e5220735591293ec022a64a32 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 9 Oct 2019 16:54:09 +0200 Subject: [PATCH 0908/1854] cov: add git ref --- covsubmit.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/covsubmit.sh b/covsubmit.sh index daa8d203d..881b0e161 100755 --- a/covsubmit.sh +++ b/covsubmit.sh @@ -10,7 +10,7 @@ rm proxmark3.all.*.tgz VERSION="0.1.$(date --date now +%H%M)" TODAY="$(date --date now +%Y%m%d.%H%M)" -DESCNAME="manual_by_$NICKNAME.$TODAY" +DESCNAME="manual_by_$NICKNAME.$TODAY.$(git describe --dirty --always)" FILENAME="proxmark3.all.$TODAY.tgz" LOGFILENAME="${FILENAME/.tgz/.log}" From 020141726e9a94d401beb37aee949f586df9fd41 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 9 Oct 2019 17:53:45 +0200 Subject: [PATCH 0909/1854] cov: use incremental pseudoversion --- covsubmit.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/covsubmit.sh b/covsubmit.sh index 881b0e161..6cf1bba47 100755 --- a/covsubmit.sh +++ b/covsubmit.sh @@ -8,8 +8,8 @@ pre_submit_hook ## delete all previous tarballs rm proxmark3.all.*.tgz -VERSION="0.1.$(date --date now +%H%M)" TODAY="$(date --date now +%Y%m%d.%H%M)" +VERSION="0.1.$TODAY" DESCNAME="manual_by_$NICKNAME.$TODAY.$(git describe --dirty --always)" FILENAME="proxmark3.all.$TODAY.tgz" LOGFILENAME="${FILENAME/.tgz/.log}" From d588b04537d19766f1d5dc5f79e4d14ac3932bb3 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 9 Oct 2019 18:03:56 +0200 Subject: [PATCH 0910/1854] fix more printf api warnings/bugs --- client/cmdhfepa.c | 2 +- client/cmdhffelica.c | 2 +- client/cmdhficlass.c | 4 ++-- client/cmdlfem4x.c | 4 ++-- client/cmdlffdx.c | 2 +- client/cmdusart.c | 8 ++++---- client/mifare/ndef.c | 2 +- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/client/cmdhfepa.c b/client/cmdhfepa.c index 1b6ec4d6a..af5d26eaf 100644 --- a/client/cmdhfepa.c +++ b/client/cmdhfepa.c @@ -50,7 +50,7 @@ static int CmdHFEPACollectPACENonces(const char *Cmd) { // check if command failed if (resp.oldarg[0] != 0) { - PrintAndLogEx(FAILED, "Error in step %" PRId64 ", Return code: %" PRId64, resp.oldarg[0], (int)resp.oldarg[1]); + PrintAndLogEx(FAILED, "Error in step %" PRId64 ", Return code: %" PRId64, resp.oldarg[0], resp.oldarg[1]); } else { size_t nonce_length = resp.oldarg[1]; char *nonce = (char *) calloc(2 * nonce_length + 1, sizeof(uint8_t)); diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index 0948bcf82..333498f37 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -408,7 +408,7 @@ static int CmdHFFelicaDumpLite(const char *Cmd) { return 0; } - PrintAndLogEx(SUCCESS, "Recorded Activity (trace len = %"PRIu64" bytes)", tracelen); + PrintAndLogEx(SUCCESS, "Recorded Activity (trace len = %"PRIu32" bytes)", tracelen); print_hex_break(trace, tracelen, 32); printSep(); diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index e2ecf943c..028e04a4c 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -2487,7 +2487,7 @@ static int CmdHFiClassLookUp(const char *Cmd) { case 'u': param_gethex_ex(Cmd, cmdp + 1, CSN, &len); if (len >> 1 != sizeof(CSN)) { - PrintAndLogEx(WARNING, "Wrong CSN length, expected %d got [%d]", sizeof(CSN), len >> 1); + PrintAndLogEx(WARNING, "Wrong CSN length, expected %zu got [%d]", sizeof(CSN), len >> 1); errors = true; } cmdp += 2; @@ -2495,7 +2495,7 @@ static int CmdHFiClassLookUp(const char *Cmd) { case 'm': param_gethex_ex(Cmd, cmdp + 1, MACS, &len); if (len >> 1 != sizeof(MACS)) { - PrintAndLogEx(WARNING, "Wrong MACS length, expected %d got [%d] ", sizeof(MACS), len >> 1); + PrintAndLogEx(WARNING, "Wrong MACS length, expected %zu got [%d] ", sizeof(MACS), len >> 1); errors = true; } else { memcpy(MAC_TAG, MACS + 4, 4); diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c index 2bfb25eaa..e1e9c75d8 100644 --- a/client/cmdlfem4x.c +++ b/client/cmdlfem4x.c @@ -401,7 +401,7 @@ int AskEm410xDecode(bool verbose, uint32_t *hi, uint64_t *lo) { else if (ans == -4) PrintAndLogEx(DEBUG, "DEBUG: Error - Em410x preamble not found"); else if (ans == -5) - PrintAndLogEx(DEBUG, "DEBUG: Error - Em410x Size not correct: %d", size); + PrintAndLogEx(DEBUG, "DEBUG: Error - Em410x Size not correct: %zu", size); else if (ans == -6) PrintAndLogEx(DEBUG, "DEBUG: Error - Em410x parity failed"); @@ -692,7 +692,7 @@ static int CmdEM410xWrite(const char *Cmd) { // the clock rate in bits 8-15 of the card value card = (card & 0xFF) | ((clock1 << 8) & 0xFF00); } else if (card == 0) { - PrintAndLogEx(SUCCESS, "Writing %s tag with UID 0x%010" PRIx64, "(clock rate: %d)", "T5555", id, clock1); + PrintAndLogEx(SUCCESS, "Writing %s tag with UID 0x%010" PRIx64 "(clock rate: %d)", "T5555", id, clock1); card = (card & 0xFF) | ((clock1 << 8) & 0xFF00); } else { PrintAndLogEx(FAILED, "Error! Bad card type selected.\n"); diff --git a/client/cmdlffdx.c b/client/cmdlffdx.c index f1f3d6100..dc2a11478 100644 --- a/client/cmdlffdx.c +++ b/client/cmdlffdx.c @@ -216,7 +216,7 @@ static int CmdFdxDemod(const char *Cmd) { // remove marker bits (1's every 9th digit after preamble) (pType = 2) size = removeParity(DemodBuffer, 11, 9, 2, 117); if (size != 104) { - PrintAndLogEx(DEBUG, "DEBUG: Error - FDX-B error removeParity: %d", size); + PrintAndLogEx(DEBUG, "DEBUG: Error - FDX-B error removeParity: %zu", size); return PM3_ESOFT; } diff --git a/client/cmdusart.c b/client/cmdusart.c index 8e8899dc8..8e095f41e 100644 --- a/client/cmdusart.c +++ b/client/cmdusart.c @@ -373,7 +373,7 @@ static int CmdUsartBtFactory(const char *Cmd) { if (strcmp((char *)data, "OKsetname") == 0) { PrintAndLogEx(SUCCESS, "Name set to " _GREEN_("PM3_RDV4.0")); } else { - PrintAndLogEx(WARNING, "Unexpected response to AT+NAME: " _YELLOW_("%.*s"), len, data); + PrintAndLogEx(WARNING, "Unexpected response to AT+NAME: " _YELLOW_("%.*s"), (int)len, data); } } else { PrintAndLogEx(WARNING, "Lost contact with add-on, please try again"); @@ -409,7 +409,7 @@ static int CmdUsartBtFactory(const char *Cmd) { if (strcmp((char *)data, "OKsetPIN") == 0) { PrintAndLogEx(SUCCESS, "PIN set to " _GREEN_("1234")); } else { - PrintAndLogEx(WARNING, "Unexpected response to AT+PIN: " _YELLOW_("%.*s"), len, data); + PrintAndLogEx(WARNING, "Unexpected response to AT+PIN: " _YELLOW_("%.*s"), (int)len, data); } } else { PrintAndLogEx(WARNING, "Lost contact with add-on, please try again"); @@ -429,7 +429,7 @@ static int CmdUsartBtFactory(const char *Cmd) { if (strcmp((char *)data, "OK None") == 0) { PrintAndLogEx(SUCCESS, "Parity set to " _GREEN_("None")); } else { - PrintAndLogEx(WARNING, "Unexpected response to AT+P: " _YELLOW_("%.*s"), len, data); + PrintAndLogEx(WARNING, "Unexpected response to AT+P: " _YELLOW_("%.*s"), (int)len, data); } } else { PrintAndLogEx(WARNING, "Lost contact with add-on, please try again"); @@ -449,7 +449,7 @@ static int CmdUsartBtFactory(const char *Cmd) { if (strcmp((char *)data, "OK" BTADDON_BAUD_NUM) == 0) { PrintAndLogEx(SUCCESS, "Baudrate set to " _GREEN_(BTADDON_BAUD_NUM)); } else { - PrintAndLogEx(WARNING, "Unexpected response to AT+BAUD: " _YELLOW_("%.*s"), len, data); + PrintAndLogEx(WARNING, "Unexpected response to AT+BAUD: " _YELLOW_("%.*s"), (int)len, data); } } else { PrintAndLogEx(WARNING, "Lost contact with add-on, please try again"); diff --git a/client/mifare/ndef.c b/client/mifare/ndef.c index 946b80b04..392a550af 100644 --- a/client/mifare/ndef.c +++ b/client/mifare/ndef.c @@ -211,7 +211,7 @@ static int ndefDecodeSig(uint8_t *sig, size_t siglen) { if ((indx <= siglen) && certURI) { size_t inturilen = (sig[indx] << 8) + sig[indx + 1]; indx += 2; - PrintAndLogEx(NORMAL, "\tcertificate uri [%zu]: %.*s", inturilen, inturilen, &sig[indx]); + PrintAndLogEx(NORMAL, "\tcertificate uri [%zu]: %.*s", inturilen, (int)inturilen, &sig[indx]); } return 0; From 906193981f0d034d7728f542d421b52085f04688 Mon Sep 17 00:00:00 2001 From: David Lam Date: Wed, 9 Oct 2019 12:48:45 -0400 Subject: [PATCH 0911/1854] textual changes --- client/cmdlft55xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index b96dd4cb8..c823e6a06 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -335,7 +335,7 @@ static int usage_t55xx_deviceconfig() { return PM3_SUCCESS; } static int usage_t55xx_protect() { - PrintAndLogEx(NORMAL, "This command set the pwd bit on T5577. "); + PrintAndLogEx(NORMAL, "This command sets the pwd bit on T5577."); PrintAndLogEx(NORMAL, _RED_("WARNING:") " this locks the tag!"); PrintAndLogEx(NORMAL, "Usage: lf t55xx protect [r ] [p ] [o] [n ]"); PrintAndLogEx(NORMAL, "Options:"); From 8b99cd0303bbb07a937955c1c453c5a91a3dfc05 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 9 Oct 2019 19:28:37 +0200 Subject: [PATCH 0912/1854] Add SKIPQT makefile var --- client/Makefile | 53 ++++++++++--------- .../4_Advanced-compilation-parameters.md | 7 +++ 2 files changed, 34 insertions(+), 26 deletions(-) diff --git a/client/Makefile b/client/Makefile index 71def6aae..95a258a78 100644 --- a/client/Makefile +++ b/client/Makefile @@ -77,36 +77,37 @@ else endif endif -# Check for correctly configured Qt5 -QTINCLUDES = $(shell pkg-config --cflags Qt5Core Qt5Widgets 2>/dev/null) -QTLDLIBS = $(shell pkg-config --libs Qt5Core Qt5Widgets 2>/dev/null) -MOC = $(shell pkg-config --variable=host_bins Qt5Core)/moc -UIC = $(shell pkg-config --variable=host_bins Qt5Core)/uic -ifeq ($(QTINCLUDES), ) -# if Qt5 not found check for correctly configured Qt4 - QTINCLUDES = $(shell pkg-config --cflags QtCore QtGui 2>/dev/null) - QTLDLIBS = $(shell pkg-config --libs QtCore QtGui 2>/dev/null) - MOC = $(shell pkg-config --variable=moc_location QtCore) - UIC = $(shell pkg-config --variable=uic_location QtCore) -else - PM3CXXFLAGS += -std=c++11 -fPIC -endif -ifeq ($(QTINCLUDES), ) -# if both pkg-config commands failed, search in common places - ifneq ($(QTDIR), ) - QTINCLUDES = -I$(QTDIR)/include -I$(QTDIR)/include/QtCore -I$(QTDIR)/include/QtGui - QTLDLIBS = -L$(QTDIR)/lib -lQtCore4 -lQtGui4 - ifneq ($(wildcard $(QTDIR)/include/QtWidgets),) - QTINCLUDES += -I$(QTDIR)/include/QtWidgets - QTLDLIBS = -L$(QTDIR)/lib -lQt5Widgets -lQt5Gui -lQt5Core - PM3CXXFLAGS += -std=c++11 -fPIC +ifneq ($(SKIPQT),1) + # Check for correctly configured Qt5 + QTINCLUDES = $(shell pkg-config --cflags Qt5Core Qt5Widgets 2>/dev/null) + QTLDLIBS = $(shell pkg-config --libs Qt5Core Qt5Widgets 2>/dev/null) + MOC = $(shell pkg-config --variable=host_bins Qt5Core)/moc + UIC = $(shell pkg-config --variable=host_bins Qt5Core)/uic + ifeq ($(QTINCLUDES), ) + # if Qt5 not found check for correctly configured Qt4 + QTINCLUDES = $(shell pkg-config --cflags QtCore QtGui 2>/dev/null) + QTLDLIBS = $(shell pkg-config --libs QtCore QtGui 2>/dev/null) + MOC = $(shell pkg-config --variable=moc_location QtCore) + UIC = $(shell pkg-config --variable=uic_location QtCore) + else + PM3CXXFLAGS += -std=c++11 -fPIC + endif + ifeq ($(QTINCLUDES), ) + # if both pkg-config commands failed, search in common places + ifneq ($(QTDIR), ) + QTINCLUDES = -I$(QTDIR)/include -I$(QTDIR)/include/QtCore -I$(QTDIR)/include/QtGui + QTLDLIBS = -L$(QTDIR)/lib -lQtCore4 -lQtGui4 + ifneq ($(wildcard $(QTDIR)/include/QtWidgets),) + QTINCLUDES += -I$(QTDIR)/include/QtWidgets + QTLDLIBS = -L$(QTDIR)/lib -lQt5Widgets -lQt5Gui -lQt5Core + PM3CXXFLAGS += -std=c++11 -fPIC + endif + MOC = $(QTDIR)/bin/moc + UIC = $(QTDIR)/bin/uic endif - MOC = $(QTDIR)/bin/moc - UIC = $(QTDIR)/bin/uic endif endif - ifneq ($(QTLDLIBS),) QTGUIOBJS = $(OBJDIR)/proxgui.o $(OBJDIR)/proxguiqt.o $(OBJDIR)/proxguiqt.moc.o PM3CFLAGS += -DHAVE_GUI diff --git a/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md b/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md index b4fb4384a..977af704c 100644 --- a/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md +++ b/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md @@ -12,6 +12,13 @@ Via some definitions, you can adjust the firmware for a given platform, but also The client doesn't depend on the capabilities of the Proxmark3 it's connected to. So you can use the same client for different Proxmark3 platforms, given that everything is running the same version. +It's possible to explicitly skip the Qt support in the compilation even if Qt is present on the host, with: + +``` +make clean +make SKIPQT=1 +``` + ## Firmware By default, the firmware is of course tuned for the Proxmark3 Rdv4.0 device, which has built-in support for 256kb onboard flash SPI memory, Sim module (smart card support), FPC connector. From 5017e33b6d241def57adf4efee29fb947ad8a804 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 9 Oct 2019 19:44:06 +0200 Subject: [PATCH 0913/1854] coverity 226232 - tainted input --- client/emv/emv_pk.c | 50 +++++++++++++++++++++++++++------------------ client/emv/emv_pk.h | 2 +- 2 files changed, 31 insertions(+), 21 deletions(-) diff --git a/client/emv/emv_pk.c b/client/emv/emv_pk.c index fbd0e39a9..3331e50a5 100644 --- a/client/emv/emv_pk.c +++ b/client/emv/emv_pk.c @@ -42,14 +42,14 @@ #define TOHEX(v) ((v) < 10 ? (v) + '0' : (v) - 10 + 'a') -static ssize_t emv_pk_read_bin(char *buf, unsigned char *bin, size_t size, size_t *read) { +static ssize_t emv_pk_read_bin(char *buf, size_t buflen, unsigned char *bin, size_t size, size_t *read) { if (buf == NULL) return 0; size_t left = size; char *p = buf; - while (*p == ' ') + while ((*p == ' ') && (p < (buf + buflen - 1))) p++; while (left > 0) { @@ -57,15 +57,19 @@ static ssize_t emv_pk_read_bin(char *buf, unsigned char *bin, size_t size, size_ c1 = HEX(*p); if (c1 == -1) return -(p - buf); + if (p == (buf + buflen - 1)) + return -(p - buf); p++; c2 = HEX(*p); if (c2 == -1) return -(p - buf); + if (p == (buf + buflen - 1)) + return -(p - buf); p++; *bin = (c1 * 16 + c2); bin ++; left --; - if (*p == ':') + if ((*p == ':') && (p < (buf + buflen - 1))) p++; else if (read) { *read = (size - left); @@ -76,7 +80,7 @@ static ssize_t emv_pk_read_bin(char *buf, unsigned char *bin, size_t size, size_ return -(p - buf); } - while (*p == ' ') + while ((*p == ' ') && (p < (buf + buflen - 1))) p++; p--; @@ -84,7 +88,7 @@ static ssize_t emv_pk_read_bin(char *buf, unsigned char *bin, size_t size, size_ return (p - buf); } -static ssize_t emv_pk_read_ymv(char *buf, unsigned *ymv) { +static ssize_t emv_pk_read_ymv(char *buf, size_t buflen, unsigned *ymv) { if (buf == NULL) return 0; @@ -95,7 +99,7 @@ static ssize_t emv_pk_read_ymv(char *buf, unsigned *ymv) { *ymv = 0; - while (*p == ' ') + while ((*p == ' ') && (p < (buf + buflen - 1))) p++; for (i = 0; i < 3; i++) { @@ -103,15 +107,19 @@ static ssize_t emv_pk_read_ymv(char *buf, unsigned *ymv) { c1 = BCD(*p); if (c1 == -1) return -(p - buf); + if (p == (buf + buflen - 1)) + return -(p - buf); p++; c2 = BCD(*p); if (c2 == -1) return -(p - buf); + if (p == (buf + buflen - 1)) + return -(p - buf); p++; temp[i] = (c1 * 16 + c2); } - while (*p == ' ') + while ((*p == ' ') && (p < (buf + buflen - 1))) p++; p--; @@ -124,13 +132,13 @@ static ssize_t emv_pk_read_ymv(char *buf, unsigned *ymv) { return (p - buf); } -static ssize_t emv_pk_read_string(char *buf, char *str, size_t size) { +static ssize_t emv_pk_read_string(char *buf, size_t buflen, char *str, size_t size) { if (buf == NULL) return 0; char *p = buf; - while (*p == ' ') + while ((*p == ' ') && (p < (buf + buflen - 1))) p++; while (size > 1) { @@ -139,6 +147,8 @@ static ssize_t emv_pk_read_string(char *buf, char *str, size_t size) { else if (*p < 0x20 || *p >= 0x7f) return -(p - buf); *str = *p; + if (p == (buf + buflen - 1)) + return -(p - buf); p++; str ++; size --; @@ -146,7 +156,7 @@ static ssize_t emv_pk_read_string(char *buf, char *str, size_t size) { *str = 0; - while (*p == ' ') + while ((*p == ' ') && (p < (buf + buflen - 1))) p++; p--; @@ -155,27 +165,27 @@ static ssize_t emv_pk_read_string(char *buf, char *str, size_t size) { } -struct emv_pk *emv_pk_parse_pk(char *buf) { +struct emv_pk *emv_pk_parse_pk(char *buf, size_t buflen) { struct emv_pk *r = calloc(1, sizeof(*r)); ssize_t l; char temp[10]; - l = emv_pk_read_bin(buf, r->rid, 5, NULL); + l = emv_pk_read_bin(buf, buflen, r->rid, 5, NULL); if (l <= 0) goto out; buf += l; - l = emv_pk_read_bin(buf, &r->index, 1, NULL); + l = emv_pk_read_bin(buf, buflen, &r->index, 1, NULL); if (l <= 0) goto out; buf += l; - l = emv_pk_read_ymv(buf, &r->expire); + l = emv_pk_read_ymv(buf, buflen, &r->expire); if (l <= 0) goto out; buf += l; - l = emv_pk_read_string(buf, temp, sizeof(temp)); + l = emv_pk_read_string(buf, buflen, temp, sizeof(temp)); if (l <= 0) goto out; buf += l; @@ -185,18 +195,18 @@ struct emv_pk *emv_pk_parse_pk(char *buf) { else goto out; - l = emv_pk_read_bin(buf, r->exp, sizeof(r->exp), &r->elen); + l = emv_pk_read_bin(buf, buflen, r->exp, sizeof(r->exp), &r->elen); if (l <= 0) goto out; buf += l; r->modulus = malloc(2048 / 8); - l = emv_pk_read_bin(buf, r->modulus, 2048 / 8, &r->mlen); + l = emv_pk_read_bin(buf, buflen, r->modulus, 2048 / 8, &r->mlen); if (l <= 0) goto out2; buf += l; - l = emv_pk_read_string(buf, temp, sizeof(temp)); + l = emv_pk_read_string(buf, buflen, temp, sizeof(temp)); if (l <= 0) goto out2; buf += l; @@ -206,7 +216,7 @@ struct emv_pk *emv_pk_parse_pk(char *buf) { else goto out2; - l = emv_pk_read_bin(buf, r->hash, 20, NULL); + l = emv_pk_read_bin(buf, buflen, r->hash, 20, NULL); if (l <= 0) goto out2; @@ -409,7 +419,7 @@ static struct emv_pk *emv_pk_get_ca_pk_from_file(const char *fname, if (fgets(buf, sizeof(buf), f) == NULL) break; - struct emv_pk *pk = emv_pk_parse_pk(buf); + struct emv_pk *pk = emv_pk_parse_pk(buf, sizeof(buf)); if (!pk) continue; diff --git a/client/emv/emv_pk.h b/client/emv/emv_pk.h index dfc249710..015a06dd6 100644 --- a/client/emv/emv_pk.h +++ b/client/emv/emv_pk.h @@ -35,7 +35,7 @@ struct emv_pk { #define EXPIRE(yy, mm, dd) 0x ## yy ## mm ## dd -struct emv_pk *emv_pk_parse_pk(char *buf); +struct emv_pk *emv_pk_parse_pk(char *bufm, size_t buflen); struct emv_pk *emv_pk_new(size_t modlen, size_t explen); void emv_pk_free(struct emv_pk *pk); char *emv_pk_dump_pk(const struct emv_pk *pk); From e3b267112f75a5b97f945626315392a88732b0b5 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 9 Oct 2019 21:07:33 +0200 Subject: [PATCH 0914/1854] coverity 226372 - leak --- client/emv/tlv.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/client/emv/tlv.c b/client/emv/tlv.c index 6e840f928..49a4038b5 100644 --- a/client/emv/tlv.c +++ b/client/emv/tlv.c @@ -367,12 +367,14 @@ void tlvdb_change_or_add_node_ex(struct tlvdb *tlvdb, tlv_tag_t tag, size_t len, // replace tlv element struct tlvdb *tnewelm = tlvdb_fixed(tag, len, value); + bool tnewelm_linked = false; tnewelm->next = telm->next; tnewelm->parent = telm->parent; // if telm stayed first in children chain if (telm->parent && telm->parent->children == telm) { telm->parent->children = tnewelm; + tnewelm_linked = true; } // if telm have previous element @@ -387,6 +389,7 @@ void tlvdb_change_or_add_node_ex(struct tlvdb *tlvdb, tlv_tag_t tag, size_t len, for (; celm; celm = celm->next) { if (celm->next == telm) { celm->next = tnewelm; + tnewelm_linked = true; break; } } @@ -396,8 +399,13 @@ void tlvdb_change_or_add_node_ex(struct tlvdb *tlvdb, tlv_tag_t tag, size_t len, telm->next = NULL; tlvdb_free(telm); - if (tlvdb_elm) + if (tlvdb_elm) { *tlvdb_elm = tnewelm; + tnewelm_linked = true; + } + if (! tnewelm_linked) { + tlvdb_free(tnewelm); + } } return; From 30168d1e20aceff4befb38afb7dfc09c5900858d Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 9 Oct 2019 21:14:55 +0200 Subject: [PATCH 0915/1854] coverity 226247 --- client/fileutils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/fileutils.c b/client/fileutils.c index de2fbef19..273bedd3e 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -1064,7 +1064,7 @@ static int searchFinalFile(char **foundpath, const char *pm3dir, const char *sea } } // try pm3 dirs in pm3 installation dir (install mode) - { + if (exec_path != NULL) { char *path = calloc(strlen(exec_path) + strlen(PM3_SHARE_RELPATH) + strlen(pm3dir) + strlen(filename) + 1, sizeof(char)); if (path == NULL) goto out; From 31efbf9a59f19aee2c89ff9ca2e174e398c480d4 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 9 Oct 2019 21:17:27 +0200 Subject: [PATCH 0916/1854] coverity 226275 --- client/fileutils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/fileutils.c b/client/fileutils.c index 273bedd3e..a8a1dc6ef 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -487,7 +487,7 @@ int loadFile_safe(const char *preferredName, const char *suffix, void **pdata, s } *pdata = calloc(fsize, sizeof(uint8_t)); - if (!pdata) { + if (!*pdata) { PrintAndLogEx(FAILED, "error, cannot allocate memory"); fclose(f); return PM3_EMALLOC; From bc35a966903948b1cd916241533d97c0786c76e7 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 9 Oct 2019 21:34:41 +0200 Subject: [PATCH 0917/1854] coverity 226497 --- armsrc/spiffs_nucleus.c | 1 + 1 file changed, 1 insertion(+) diff --git a/armsrc/spiffs_nucleus.c b/armsrc/spiffs_nucleus.c index ef1db36f1..459222d5b 100644 --- a/armsrc/spiffs_nucleus.c +++ b/armsrc/spiffs_nucleus.c @@ -1560,6 +1560,7 @@ s32_t spiffs_object_modify(spiffs_fd *fd, u32_t offset, u8_t *data, u32_t len) { res = spiffs_page_allocate_data(fs, fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, &p_hdr, &data[written], to_write, page_offs, 1, &data_pix); SPIFFS_DBG("modify: store new data page, "_SPIPRIpg":"_SPIPRIsp" offset:"_SPIPRIi", len "_SPIPRIi", written "_SPIPRIi"\n", data_pix, data_spix, page_offs, to_write, written); + if (res != SPIFFS_OK) break; } else { // write to existing page, allocate new and copy unmodified data From 54585089a36a952e5b0fc3c5210dcda923784476 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 9 Oct 2019 21:36:29 +0200 Subject: [PATCH 0918/1854] coverity 226339 --- client/cmdlffdx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdlffdx.c b/client/cmdlffdx.c index dc2a11478..ce78525ac 100644 --- a/client/cmdlffdx.c +++ b/client/cmdlffdx.c @@ -204,7 +204,7 @@ static int CmdFdxDemod(const char *Cmd) { else if (preambleIndex == -2) PrintAndLogEx(DEBUG, "DEBUG: Error - FDX-B preamble not found"); else if (preambleIndex == -3) - PrintAndLogEx(DEBUG, "DEBUG: Error - FDX-B Size not correct: %d", size); + PrintAndLogEx(DEBUG, "DEBUG: Error - FDX-B Size not correct: %zu", size); else PrintAndLogEx(DEBUG, "DEBUG: Error - FDX-B ans: %d", preambleIndex); return PM3_ESOFT; From 31cf43504586472446b8a75a2525fc3bcd35ad78 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 9 Oct 2019 21:55:01 +0200 Subject: [PATCH 0919/1854] coverity 226359 --- client/cmdhfmfhard.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/client/cmdhfmfhard.c b/client/cmdhfmfhard.c index 75e647489..bc3591d06 100644 --- a/client/cmdhfmfhard.c +++ b/client/cmdhfmfhard.c @@ -282,7 +282,12 @@ static void init_bitflip_bitarrays(void) { fclose(statesfile); uint32_t count = 0; init_inflate(&compressed_stream, input_buffer, filesize, (uint8_t *)&count, sizeof(count)); - inflate(&compressed_stream, Z_SYNC_FLUSH); + int res = inflate(&compressed_stream, Z_SYNC_FLUSH); + if (res != Z_OK) { + PrintAndLogEx(ERR, "Inflate error. Aborting...\n"); + inflateEnd(&compressed_stream); + exit(4); + } if ((float)count / (1 << 24) < IGNORE_BITFLIP_THRESHOLD) { uint32_t *bitset = (uint32_t *)malloc_bitarray(sizeof(uint32_t) * (1 << 19)); if (bitset == NULL) { @@ -292,7 +297,12 @@ static void init_bitflip_bitarrays(void) { } compressed_stream.next_out = (uint8_t *)bitset; compressed_stream.avail_out = sizeof(uint32_t) * (1 << 19); - inflate(&compressed_stream, Z_SYNC_FLUSH); + res = inflate(&compressed_stream, Z_SYNC_FLUSH); + if (res != Z_OK && res != Z_STREAM_END) { + PrintAndLogEx(ERR, "Inflate error. Aborting...\n"); + inflateEnd(&compressed_stream); + exit(4); + } effective_bitflip[odd_even][num_effective_bitflips[odd_even]++] = bitflip; bitflip_bitarrays[odd_even][bitflip] = bitset; count_bitflip_bitarrays[odd_even][bitflip] = count; From b7d543888c58b34d280a9030792208d041494468 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 9 Oct 2019 22:24:54 +0200 Subject: [PATCH 0920/1854] coverity 226272 --- client/scripting.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/client/scripting.c b/client/scripting.c index 7157957ca..1368894c8 100644 --- a/client/scripting.c +++ b/client/scripting.c @@ -69,7 +69,10 @@ static int l_fast_push_mode(lua_State *L) { // Disable fast mode and send a dummy command to make it effective if (enable == false) { SendCommandNG(CMD_PING, NULL, 0); - WaitForResponseTimeout(CMD_PING, NULL, 1000); + if (!WaitForResponseTimeout(CMD_PING, NULL, 1000)) { + PrintAndLogEx(WARNING, "command execution time out"); + return returnToLuaWithError(L, "command execution time out"); + } } //Push the retval on the stack From 7b482c64b1b7008d45123d80efec4b44e52c5b0b Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 9 Oct 2019 22:29:42 +0200 Subject: [PATCH 0921/1854] coverity 226188 --- client/cmdhfmf.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 6b266e21e..87475926e 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -2866,18 +2866,21 @@ out: PrintAndLogEx(SUCCESS, "Found keys have been transferred to the emulator memory"); } - // Disable fast mode and send a dummy command to make it effective - conn.block_after_ACK = false; - SendCommandNG(CMD_PING, NULL, 0); - WaitForResponseTimeout(CMD_PING, NULL, 1000); - if (createDumpFile) { fptr = GenerateFilename("hf-mf-", "-key.bin"); createMfcKeyDump(SectorsCnt, e_sector, fptr); } - free(keyBlock); free(e_sector); + + // Disable fast mode and send a dummy command to make it effective + conn.block_after_ACK = false; + SendCommandNG(CMD_PING, NULL, 0); + if (!WaitForResponseTimeout(CMD_PING, NULL, 1000)) { + PrintAndLogEx(WARNING, "command execution time out"); + return PM3_ETIMEOUT; + } + PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } From d3efe5342cf57fce1d15877a48f5f051d050ebcd Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 9 Oct 2019 22:32:38 +0200 Subject: [PATCH 0922/1854] misspelled fct --- client/cmdlft55xx.c | 28 ++++++++++++++-------------- client/cmdlft55xx.h | 2 +- client/scripting.c | 6 +++--- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index c823e6a06..dec987a2e 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -479,7 +479,7 @@ bool t55xxAquireAndCompareBlock0(bool usepwd, uint32_t password, uint32_t known_ PrintAndLogEx(INFO, "Block0 write detected, running `detect` to see if validation is possible"); for (uint8_t m = 0; m < 4; m++) { - if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, m) == false) { + if (AcquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, m) == false) { continue; } @@ -512,7 +512,7 @@ bool t55xxAquireAndDetect(bool usepwd, uint32_t password, uint32_t known_block0, config.pwd = 0x00; for (uint8_t m = 0; m < 4; m++) { - if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, m) == false) + if (AcquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, m) == false) continue; if (tryDetectModulationEx(m, verbose, known_block0) == false) @@ -776,7 +776,7 @@ int T55xxReadBlockEx(uint8_t block, bool page1, bool usepwd, uint8_t override, u // override = 1 (override and display) // override = 2 (override and no display) if (override == 0) { - if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, false, 0, downlink_mode) == false) + if (AcquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, false, 0, downlink_mode) == false) return PM3_ERFTRANS; if (tryDetectModulation(downlink_mode, false) == false) { @@ -792,7 +792,7 @@ int T55xxReadBlockEx(uint8_t block, bool page1, bool usepwd, uint8_t override, u } } - if (AquireData(page1, block, usepwd, password, downlink_mode) == false) + if (AcquireData(page1, block, usepwd, password, downlink_mode) == false) return PM3_ERFTRANS; if (DecodeT55xxBlock() == false) @@ -1013,7 +1013,7 @@ static int CmdT55xxDetect(const char *Cmd) { if (try_all_dl_modes) { for (uint8_t m = downlink_mode; m < 4; m++) { - if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, try_with_pwd & usepwd, password, m) == false) + if (AcquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, try_with_pwd & usepwd, password, m) == false) continue; // pre fill to save passing in. @@ -1036,7 +1036,7 @@ static int CmdT55xxDetect(const char *Cmd) { else config.pwd = 0x00; - if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, downlink_mode)) { + if (AcquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, downlink_mode)) { found = tryDetectModulation(downlink_mode, T55XX_PrintConfig); } } @@ -1774,7 +1774,7 @@ static int CmdT55xxReadTrace(const char *Cmd) { uint32_t password = 0; // REGULAR_READ_MODE_BLOCK - yeilds correct Page 1 Block 2 data i.e. + 32 bit offset. - if (!AquireData(T55x7_PAGE1, REGULAR_READ_MODE_BLOCK, pwdmode, password, downlink_mode)) + if (!AcquireData(T55x7_PAGE1, REGULAR_READ_MODE_BLOCK, pwdmode, password, downlink_mode)) return PM3_ENODATA; } @@ -2077,7 +2077,7 @@ static int CmdT55xxInfo(const char *Cmd) { // sanity check. if (SanityOfflineCheck(false) != PM3_SUCCESS) return PM3_ENODATA; - if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, downlink_mode)) + if (!AcquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, downlink_mode)) return PM3_ENODATA; } @@ -2275,7 +2275,7 @@ static int CmdT55xxRestore(const char *Cmd) { return res; } -bool AquireData(uint8_t page, uint8_t block, bool pwdmode, uint32_t password, uint8_t downlink_mode) { +bool AcquireData(uint8_t page, uint8_t block, bool pwdmode, uint32_t password, uint8_t downlink_mode) { // arg0 bitmodes: // b0 = pwdmode // b1 = page to read from @@ -2808,7 +2808,7 @@ static int CmdT55xxChkPwds(const char *Cmd) { if (resp.oldarg[0]) { PrintAndLogEx(SUCCESS, "\nFound a candidate [ " _YELLOW_("%08"PRIX64) " ]. Trying to validate", resp.oldarg[1]); - if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, resp.oldarg[1], downlink_mode)) { + if (AcquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, resp.oldarg[1], downlink_mode)) { found = tryDetectModulation(downlink_mode, T55XX_PrintConfig); if (found) { PrintAndLogEx(SUCCESS, "Found valid password: [ " _GREEN_("%08"PRIX64) "]", resp.oldarg[1]); @@ -2857,7 +2857,7 @@ static int CmdT55xxChkPwds(const char *Cmd) { PrintAndLogEx(INFO, "Testing %08"PRIX64, curr_password); for (dl_mode = downlink_mode; dl_mode <= 3; dl_mode++) { - if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, curr_password, dl_mode)) { + if (!AcquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, curr_password, dl_mode)) { continue; } @@ -2975,7 +2975,7 @@ uint8_t tryOnePassword(uint32_t password, uint8_t downlink_mode) { // check if dl mode 4 and loop if needed for (dl_mode = downlink_mode; dl_mode < 4; dl_mode++) { - AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, password, dl_mode); + AcquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, password, dl_mode); // if (getSignalProperties()->isnoise == false) { // } else { @@ -3109,7 +3109,7 @@ bool tryDetectP1(bool getData) { bool st = true; if (getData) { - if (!AquireData(T55x7_PAGE1, T55x7_TRACE_BLOCK1, false, 0, 0)) + if (!AcquireData(T55x7_PAGE1, T55x7_TRACE_BLOCK1, false, 0, 0)) return false; } @@ -3259,7 +3259,7 @@ static int CmdT55xxDetectPage1(const char *Cmd) { if (!useGB) { for (dl_mode = downlink_mode; dl_mode < 4; dl_mode++) { - found = AquireData(T55x7_PAGE1, T55x7_TRACE_BLOCK1, usepwd, password, dl_mode); + found = AcquireData(T55x7_PAGE1, T55x7_TRACE_BLOCK1, usepwd, password, dl_mode); //return PM3_ENODATA; if (tryDetectP1(false)) { //tryDetectModulation()) found = true; diff --git a/client/cmdlft55xx.h b/client/cmdlft55xx.h index 2efecdc26..876cbf7d7 100644 --- a/client/cmdlft55xx.h +++ b/client/cmdlft55xx.h @@ -164,7 +164,7 @@ bool testKnownConfigBlock(uint32_t block0); bool tryDetectP1(bool getData); bool test(uint8_t mode, uint8_t *offset, int *fndBitRate, uint8_t clk, bool *Q5); int special(const char *Cmd); -bool AquireData(uint8_t page, uint8_t block, bool pwdmode, uint32_t password, uint8_t downlink_mode); +bool AcquireData(uint8_t page, uint8_t block, bool pwdmode, uint32_t password, uint8_t downlink_mode); uint8_t tryOnePassword(uint32_t password, uint8_t downlink_mode); void printT55x7Trace(t55x7_tracedata_t data, uint8_t repeat); diff --git a/client/scripting.c b/client/scripting.c index 1368894c8..e5c3990fb 100644 --- a/client/scripting.c +++ b/client/scripting.c @@ -929,7 +929,7 @@ static int l_T55xx_readblock(lua_State *L) { // try reading the config block and verify that PWD bit is set before doing this! if (!override) { - if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, false, 0, 0)) { + if (!AcquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, false, 0, 0)) { return returnToLuaWithError(L, "Failed to read config block"); } @@ -946,7 +946,7 @@ static int l_T55xx_readblock(lua_State *L) { } } - if (!AquireData(usepage1, block, usepwd, password, 0)) { + if (!AcquireData(usepage1, block, usepwd, password, 0)) { return returnToLuaWithError(L, "Failed to acquire data from card"); } @@ -1003,7 +1003,7 @@ static int l_T55xx_detect(lua_State *L) { if (!useGB) { - isok = AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, 0); + isok = AcquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, 0); if (isok == false) { return returnToLuaWithError(L, "Failed to acquire LF signal data"); } From 209fa45107babba25968960488e138c92e213e36 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 9 Oct 2019 22:44:25 +0200 Subject: [PATCH 0923/1854] coverity 226215 --- client/cmdlft55xx.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index dec987a2e..73809fd6d 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -2975,14 +2975,14 @@ uint8_t tryOnePassword(uint32_t password, uint8_t downlink_mode) { // check if dl mode 4 and loop if needed for (dl_mode = downlink_mode; dl_mode < 4; dl_mode++) { - AcquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, password, dl_mode); - - // if (getSignalProperties()->isnoise == false) { - // } else { - if (tryDetectModulation(dl_mode, T55XX_PrintConfig)) { - return 1 + (dl_mode << 1); + if (AcquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, password, dl_mode)) { + // if (getSignalProperties()->isnoise == false) { + // } else { + if (tryDetectModulation(dl_mode, T55XX_PrintConfig)) { + return 1 + (dl_mode << 1); + } + // } } - // } if (!try_all_dl_modes) dl_mode = 4; } return 0; From 2024f87ed3691d544e8fd239c2901a58b406c0e8 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 9 Oct 2019 22:48:54 +0200 Subject: [PATCH 0924/1854] coverity 226201 --- armsrc/mifaredesfire.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/armsrc/mifaredesfire.c b/armsrc/mifaredesfire.c index e16c00ed1..c13311051 100644 --- a/armsrc/mifaredesfire.c +++ b/armsrc/mifaredesfire.c @@ -585,7 +585,9 @@ size_t CreateAPDU(uint8_t *datain, size_t len, uint8_t *dataout) { void OnSuccess() { pcb_blocknum = 0; ReaderTransmit(deselect_cmd, 3, NULL); - mifare_ultra_halt(); + if (mifare_ultra_halt()) { + if (DBGLEVEL >= DBG_ERROR) Dbprintf("Halt error"); + } switch_off(); } From e4ad1a74716a72a2bf81645bff8d6cc08101456b Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 9 Oct 2019 23:01:07 +0200 Subject: [PATCH 0925/1854] coverity 227889 227898 - division by zero --- common/lfdemod.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/common/lfdemod.c b/common/lfdemod.c index 1d1749d8e..9ed1a83c3 100644 --- a/common/lfdemod.c +++ b/common/lfdemod.c @@ -117,8 +117,11 @@ void computeSignalProperties(uint8_t *samples, uint32_t size) { sum += samples[i]; cnt++; - } - signalprop.mean = sum / cnt; + } + if (cnt > 0) + signalprop.mean = sum / cnt; + else + signalprop.mean = 0; #else for (uint32_t i = SIGNAL_IGNORE_FIRST_SAMPLES; i < size; i++) { if (samples[i] < signalprop.low) signalprop.low = samples[i]; @@ -160,8 +163,11 @@ void removeSignalOffset(uint8_t *samples, uint32_t size) { acc_off += samples[i] - 128; cnt++; - } - acc_off /= cnt; + } + if (cnt > 0) + acc_off /= cnt; + else + acc_off = 0; #else for (uint32_t i = SIGNAL_IGNORE_FIRST_SAMPLES; i < size; i++) acc_off += samples[i] - 128; From f4ec8463a4ba13d729d2e1e92d0e1657442ad61d Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 9 Oct 2019 23:31:22 +0200 Subject: [PATCH 0926/1854] coverity 226367 - strange indala code --- client/cmdlfindala.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/client/cmdlfindala.c b/client/cmdlfindala.c index 0e308be35..914b510fc 100644 --- a/client/cmdlfindala.c +++ b/client/cmdlfindala.c @@ -109,7 +109,10 @@ static int CmdIndalaDemod(const char *Cmd) { //convert UID to HEX uint32_t uid1 = bytebits_to_byte(DemodBuffer, 32); uint32_t uid2 = bytebits_to_byte(DemodBuffer + 32, 32); - uint64_t foo = (((uint64_t)uid1 << 32) & 0x1FFFFFFF) | (uid2 & 0x7FFFFFFF); + // To be checked, what's this internal ID ? + // foo is only used for 64b ids and in that case uid1 must be only preamble, plus the following code is wrong as x<<32 & 0x1FFFFFFF is always zero + //uint64_t foo = (((uint64_t)uid1 << 32) & 0x1FFFFFFF) | (uid2 & 0x7FFFFFFF); + uint64_t foo = uid2 & 0x7FFFFFFF; if (DemodBufferLen == 64) { PrintAndLogEx( From b6c683bd02a664cbeeb943d60d34937033073e25 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 9 Oct 2019 23:34:19 +0200 Subject: [PATCH 0927/1854] coverity 226304 --- client/fileutils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/fileutils.c b/client/fileutils.c index a8a1dc6ef..8b537d423 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -820,7 +820,7 @@ int loadFileDICTIONARY_safe(const char *preferredName, void **pdata, uint8_t key while (fgets(line, sizeof(line), f)) { // check if we have enough space (if not allocate more) - if ((*keycnt * (keylen >> 1)) >= mem_size) { + if ((((size_t)(*keycnt)) * (keylen >> 1)) >= mem_size) { mem_size += block_size; *pdata = realloc(*pdata, mem_size); From 755ac62ab867371d65365ad7ecf898511eb9b36c Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 9 Oct 2019 23:38:41 +0200 Subject: [PATCH 0928/1854] coverity 226422 --- client/cmdhw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdhw.c b/client/cmdhw.c index a6f242b8f..fa43e6200 100644 --- a/client/cmdhw.c +++ b/client/cmdhw.c @@ -532,7 +532,7 @@ static int CmdPing(const char *Cmd) { error = memcmp(data, resp.data.asBytes, len) != 0; PrintAndLogEx((error) ? ERR : SUCCESS, "Ping response " _GREEN_("received") "and content is %s", error ? _RED_("NOT ok") : _GREEN_("ok")); } else { - PrintAndLogEx((error) ? ERR : SUCCESS, "Ping response " _GREEN_("received")); + PrintAndLogEx(SUCCESS, "Ping response " _GREEN_("received")); } } else PrintAndLogEx(WARNING, "Ping response " _RED_("timeout")); From fb1e7879e1ddf942f6b6c36add58c6fa9314b52e Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 9 Oct 2019 23:44:46 +0200 Subject: [PATCH 0929/1854] coverity 226393 - missing break in mifaresim --- armsrc/mifaresim.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/armsrc/mifaresim.c b/armsrc/mifaresim.c index b1f419242..6c65a4f65 100644 --- a/armsrc/mifaresim.c +++ b/armsrc/mifaresim.c @@ -588,9 +588,11 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1 case MFEMUL_NOFIELD: if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("MFEMUL_NOFIELD"); + break; case MFEMUL_HALTED: if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("MFEMUL_HALTED"); + break; case MFEMUL_IDLE: { LogTrace(uart->output, uart->len, uart->startTime * 16 - DELAY_AIR2ARM_AS_TAG, uart->endTime * 16 - DELAY_AIR2ARM_AS_TAG, uart->parity, true); if (DBGLEVEL >= DBG_EXTENDED) From 904f0fe2fdb0e8df292761105a27d60443c66bcc Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 10 Oct 2019 00:08:30 +0200 Subject: [PATCH 0930/1854] coverity 226229 --- client/cmdtrace.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/client/cmdtrace.c b/client/cmdtrace.c index 836c0b9eb..97d91e54d 100644 --- a/client/cmdtrace.c +++ b/client/cmdtrace.c @@ -840,8 +840,6 @@ int CmdTraceList(const char *Cmd) { PrintAndLogEx(NORMAL, "ISO15693 - Timings are not as accurate"); if (protocol == ISO_7816_4) PrintAndLogEx(NORMAL, "ISO7816-4 / Smartcard - Timings N/A yet"); - if (protocol == FELICA) - PrintAndLogEx(NORMAL, "Felica"); // Timings ? if (protocol == PROTO_HITAG) PrintAndLogEx(NORMAL, "Hitag2 / HitagS - Timings in ETU (8us)"); From d43460ab9f61050ed0cadcd858a446bf7efec034 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 10 Oct 2019 00:30:14 +0200 Subject: [PATCH 0931/1854] cov submit: delete old logs --- covsubmit.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/covsubmit.sh b/covsubmit.sh index 6cf1bba47..dcfda0999 100755 --- a/covsubmit.sh +++ b/covsubmit.sh @@ -6,7 +6,7 @@ set -e pre_submit_hook ## delete all previous tarballs -rm proxmark3.all.*.tgz +rm proxmark3.all.*.tgz proxmark3.all.*.log TODAY="$(date --date now +%Y%m%d.%H%M)" VERSION="0.1.$TODAY" From f909039d015a88a62263b2bae145ca8ab5097e79 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 10 Oct 2019 07:34:30 +0200 Subject: [PATCH 0932/1854] frame --- armsrc/iclass.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/iclass.c b/armsrc/iclass.c index 50042ef0c..33ea46e85 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -1765,7 +1765,7 @@ void CodeIClassCommand(const uint8_t *cmd, int len) { for (k = 0; k < 4; k++) { if (k == (b & 3)) - ToSend[++ToSendMax] = 0xf0; + ToSend[++ToSendMax] = 0x0f; else ToSend[++ToSendMax] = 0x00; } From 762075f34a730986e3ccc9da43cf1e74d349c8ad Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 10 Oct 2019 07:56:39 +0200 Subject: [PATCH 0933/1854] textual --- client/cmdlf.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/client/cmdlf.c b/client/cmdlf.c index a77b86d0d..adc5bc9b5 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -1139,18 +1139,17 @@ static bool CheckChipType(bool getDeviceData) { //check for em4x05/em4x69 chips first uint32_t word = 0; if (EM4x05IsBlock0(&word)) { - PrintAndLogEx(SUCCESS, "\nChipset detection : " _GREEN_("EM4x05/EM4x69") "found"); - PrintAndLogEx(SUCCESS, "Try " _YELLOW_("`lf em 4x05`") " commands"); + PrintAndLogEx(SUCCESS, "Chipset detection: " _GREEN_("EM4x05/EM4x69")); + PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf em 4x05`") "commands"); retval = true; goto out; } //check for t55xx chip... if (tryDetectP1(true)) { - PrintAndLogEx(SUCCESS, "\nChipset detection : " _GREEN_("T55xx") "found"); - PrintAndLogEx(SUCCESS, "Try " _YELLOW_("`lf t55xx`")"commands"); + PrintAndLogEx(SUCCESS, "Chipset detection: " _GREEN_("T55xx")); + PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf t55xx`") "commands"); retval = true; - goto out; } out: @@ -1184,7 +1183,8 @@ int CmdLFfind(const char *Cmd) { PrintAndLogEx(INFO, "if it finds something that looks like a tag"); PrintAndLogEx(INFO, "False Positives " _YELLOW_("ARE") "possible"); PrintAndLogEx(INFO, ""); - PrintAndLogEx(INFO, "Checking for known tags...\n"); + PrintAndLogEx(INFO, "Checking for known tags..."); + PrintAndLogEx(INFO, ""); // only run these tests if device is online if (isOnline) { @@ -1197,7 +1197,8 @@ int CmdLFfind(const char *Cmd) { } if (readCOTAGUid()) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("COTAG ID") "found!"); return PM3_SUCCESS;} - PrintAndLogEx(FAILED, "\n" _YELLOW_("No data found!") " - Signal looks like noise. Maybe not an LF tag?"); + PrintAndLogEx(FAILED, _RED_("No data found!")); + PrintAndLogEx(INFO, "Signal looks like noise. Maybe not an LF tag?"); return PM3_ESOFT; } } From 49caa7f96283e3ca6701b9298f67964e70243f30 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 10 Oct 2019 10:34:56 +0200 Subject: [PATCH 0934/1854] chg cotag operates on 132kHz. textual --- armsrc/lfops.c | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 5ff1867de..377a20b45 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -2411,18 +2411,37 @@ void EM4xWriteWord(uint8_t addr, uint32_t data, uint32_t pwd, uint8_t usepwd) { } /* -Reading a COTAG. +Reading COTAG. COTAG needs the reader to send a startsequence and the card has an extreme slow datarate. because of this, we can "sample" the data signal but we interpreate it to Manchester direct. -READER START SEQUENCE: -burst 800 us, gap 2.2 msecs -burst 3.6 msecs gap 2.2 msecs -burst 800 us gap 2.2 msecs -pulse 3.6 msecs +This behavior looks very similar to old ancient Motorola Flexpass + +----------------------------------------------------------------------- +According to patent: +Operating freq + reader 132 kHz + tag 66 kHz + +Divide by 384 counter + +PULSE repetition 5.82ms +LOW 2.91 ms +HIGH 2.91 ms + +Also references to a half-bit format and leading zero. +----------------------------------------------------------------------- + +READER START SEQUENCE: + +burst 800 us gap 2.2 ms +burst 3.6 ms gap 2.2 ms +burst 800 us gap 2.2 ms +pulse 3.6 ms + +This triggers COTAG tag to response -This triggers a COTAG tag to response */ void Cotag(uint32_t arg0) { #ifndef OFF @@ -2435,7 +2454,7 @@ void Cotag(uint32_t arg0) { LED_A_ON(); - LFSetupFPGAForADC(LF_DIVISOR_134, true); + LFSetupFPGAForADC(LF_DIVISOR(132), true); //clear buffer now so it does not interfere with timing later BigBuf_Clear_ext(false); From 371a0e3ee002b0cf5d779547742cda87f114b988 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 10 Oct 2019 11:13:14 +0200 Subject: [PATCH 0935/1854] coverity 226308 --- client/cmdhflist.c | 2 +- include/protocols.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/client/cmdhflist.c b/client/cmdhflist.c index 45abd1d57..737405787 100644 --- a/client/cmdhflist.c +++ b/client/cmdhflist.c @@ -363,7 +363,7 @@ void annotateIclass(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) { snprintf(exp, size, "UPDATE(%d)", cmd[1]); break; case ICLASS_CMD_READCHECK: - if (ICLASS_CREDIT(c)) { + if (ICLASS_CREDIT(cmd[0])) { snprintf(exp, size, "READCHECK[Kc](%d)", cmd[1]); } else { snprintf(exp, size, "READCHECK[Kd](%d)", cmd[1]); diff --git a/include/protocols.h b/include/protocols.h index 4eb3ab58c..2547f01de 100644 --- a/include/protocols.h +++ b/include/protocols.h @@ -133,8 +133,8 @@ ISO 7816-4 Basic interindustry commands. For command APDU's. #define ICLASS_CMD_READ_OR_IDENTIFY 0xC #define ICLASS_CMD_ACT 0xE -#define ICLASS_CREDIT(x) (((x) & 0x5) == 0x5) -#define ICLASS_DEBIT(x) (((x) & 0x5) == 0) +#define ICLASS_CREDIT(x) (((x) & 0x10) == 0x10) +#define ICLASS_DEBIT(x) !(ICLASS_CREDIT(x)) #define ISO14443A_CMD_REQA 0x26 From 7435663ea15f9958ada6d365646a993fcea2cbbd Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 10 Oct 2019 11:36:28 +0200 Subject: [PATCH 0936/1854] coverity 226262 --- armsrc/dbprint.c | 14 +++++++------- armsrc/dbprint.h | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/armsrc/dbprint.c b/armsrc/dbprint.c index 499703ef1..9b18b7aca 100644 --- a/armsrc/dbprint.c +++ b/armsrc/dbprint.c @@ -22,35 +22,35 @@ // Debug print functions, to go out over USB, to the usual PC-side client. //============================================================================= -void DbpStringEx(uint32_t flags, char *str) { +void DbpStringEx(uint32_t flags, char *src, size_t srclen) { #if DEBUG struct { uint16_t flag; uint8_t buf[PM3_CMD_DATA_SIZE - sizeof(uint16_t)]; } PACKED data; data.flag = flags; - uint16_t len = MIN(strlen(str), sizeof(data.buf)); - memcpy(data.buf, str, len); + uint16_t len = MIN(srclen, sizeof(data.buf)); + memcpy(data.buf, src, len); reply_ng(CMD_DEBUG_PRINT_STRING, PM3_SUCCESS, (uint8_t *)&data, sizeof(data.flag) + len); #endif } void DbpString(char *str) { #if DEBUG - DbpStringEx(FLAG_LOG, str); + DbpStringEx(FLAG_LOG, str, strlen(str)); #endif } void DbprintfEx(uint32_t flags, const char *fmt, ...) { #if DEBUG // should probably limit size here; oh well, let's just use a big buffer - char output_string[PM3_CMD_DATA_SIZE] = {0x00}; + char s[PM3_CMD_DATA_SIZE] = {0x00}; va_list ap; va_start(ap, fmt); - kvsprintf(fmt, output_string, 10, ap); + kvsprintf(fmt, s, 10, ap); va_end(ap); - DbpStringEx(flags, output_string); + DbpStringEx(flags, s, strlen(s)); #endif } diff --git a/armsrc/dbprint.h b/armsrc/dbprint.h index 54b813218..c3229f46f 100644 --- a/armsrc/dbprint.h +++ b/armsrc/dbprint.h @@ -43,7 +43,7 @@ void DbpString(char *str); -void DbpStringEx(uint32_t flags, char *str); +void DbpStringEx(uint32_t flags, char *src, size_t srclen); void Dbprintf(const char *fmt, ...); void DbprintfEx(uint32_t flags, const char *fmt, ...); void Dbhexdump(int len, uint8_t *d, bool bAsci); From 9be5627537bbe620ebdd551a858d9a8b4dcf618f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 10 Oct 2019 11:37:36 +0200 Subject: [PATCH 0937/1854] should unify authors messages, remove from individual functions that was done for awhile --- client/cmdlfcotag.c | 5 +++-- client/cmdlfcotag.h | 2 +- client/cmdlfgallagher.c | 1 + client/cmdlfgallagher.h | 1 + 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/client/cmdlfcotag.c b/client/cmdlfcotag.c index 96548fca9..dd7d5d648 100644 --- a/client/cmdlfcotag.c +++ b/client/cmdlfcotag.c @@ -1,5 +1,5 @@ //----------------------------------------------------------------------------- -// Authored by Iceman +// Iceman // // This code is licensed to you under the terms of the GNU GPL, version 2 or, // at your option, any later version. See the LICENSE.txt file for the text of @@ -17,6 +17,7 @@ #include "lfdemod.h" #include "cmddata.h" // getSamples #include "ui.h" // PrintAndLog +#include "ctype.h" // tolower static int CmdHelp(const char *Cmd); @@ -78,7 +79,7 @@ static int CmdCOTAGDemod(const char *Cmd) { // 2 = raw signal - maxlength bigbuff static int CmdCOTAGRead(const char *Cmd) { - if (Cmd[0] == 'h' || Cmd[0] == 'H') return usage_lf_cotag_read(); + if ( tolower(Cmd[0]) == 'h') return usage_lf_cotag_read(); uint32_t rawsignal = 1; sscanf(Cmd, "%u", &rawsignal); diff --git a/client/cmdlfcotag.h b/client/cmdlfcotag.h index 01c4daa03..d7b5bc331 100644 --- a/client/cmdlfcotag.h +++ b/client/cmdlfcotag.h @@ -1,5 +1,5 @@ //----------------------------------------------------------------------------- -// Authored by Iceman +// Iceman // // This code is licensed to you under the terms of the GNU GPL, version 2 or, // at your option, any later version. See the LICENSE.txt file for the text of diff --git a/client/cmdlfgallagher.c b/client/cmdlfgallagher.c index 051973a28..894e98ef8 100644 --- a/client/cmdlfgallagher.c +++ b/client/cmdlfgallagher.c @@ -1,4 +1,5 @@ //----------------------------------------------------------------------------- +// Iceman, 2019 // // This code is licensed to you under the terms of the GNU GPL, version 2 or, // at your option, any later version. See the LICENSE.txt file for the text of diff --git a/client/cmdlfgallagher.h b/client/cmdlfgallagher.h index 90729b152..0ee2a72b3 100644 --- a/client/cmdlfgallagher.h +++ b/client/cmdlfgallagher.h @@ -1,4 +1,5 @@ //----------------------------------------------------------------------------- +// Iceman, 2019 // // This code is licensed to you under the terms of the GNU GPL, version 2 or, // at your option, any later version. See the LICENSE.txt file for the text of From 9f544954120321045f250f053bdbc45d20381e27 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 10 Oct 2019 11:54:23 +0200 Subject: [PATCH 0938/1854] coverity 226214 --- armsrc/iso15693.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/armsrc/iso15693.c b/armsrc/iso15693.c index ecf0640a5..f1fd3eb9c 100644 --- a/armsrc/iso15693.c +++ b/armsrc/iso15693.c @@ -937,10 +937,9 @@ void BruteforceIso15693Afi(uint32_t speed) { data[0] = ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH | ISO15_REQ_INVENTORY | ISO15_REQINV_SLOT1; data[1] = ISO15_CMD_INVENTORY; - data[2] = 0; // mask length + data[2] = 0; // AFI AddCrc15(data, 3); - datalen += 2; - + datalen = 5; recvlen = SendDataTag(data, datalen, false, speed, buf); WDT_HIT(); @@ -955,10 +954,12 @@ void BruteforceIso15693Afi(uint32_t speed) { data[2] = 0; // AFI data[3] = 0; // mask length + // 4 + 2crc + datalen = 6; + for (uint16_t i = 0; i < 256; i++) { data[2] = i & 0xFF; AddCrc15(data, 4); - datalen += 2; recvlen = SendDataTag(data, datalen, false, speed, buf); WDT_HIT(); if (recvlen >= 12) { From c2b448de0f86838262875a7c804f4c7086389270 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 10 Oct 2019 12:02:01 +0200 Subject: [PATCH 0939/1854] elite_crack: static include else we get issue with gcov --- client/loclass/elite_crack.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/loclass/elite_crack.c b/client/loclass/elite_crack.c index c7a617f6a..fd0c5c8dd 100644 --- a/client/loclass/elite_crack.c +++ b/client/loclass/elite_crack.c @@ -108,7 +108,7 @@ void permutekey_rev(uint8_t key[8], uint8_t dest[8]) { * @param val * @return */ -inline uint8_t rr(uint8_t val) { +static inline uint8_t rr(uint8_t val) { return val >> 1 | ((val & 1) << 7); } @@ -118,7 +118,7 @@ inline uint8_t rr(uint8_t val) { * @param val * @return */ -inline uint8_t rl(uint8_t val) { +static inline uint8_t rl(uint8_t val) { return val << 1 | ((val & 0x80) >> 7); } @@ -128,7 +128,7 @@ inline uint8_t rl(uint8_t val) { * @param val * @return */ -inline uint8_t swap(uint8_t val) { +static inline uint8_t swap(uint8_t val) { return ((val >> 4) & 0xFF) | ((val & 0xFF) << 4); } From e435d8a6ff865a29bf001307b3f186a67b968135 Mon Sep 17 00:00:00 2001 From: mwalker33 Date: Thu, 10 Oct 2019 21:27:48 +1100 Subject: [PATCH 0940/1854] t55x7 save and restore eml/bin --- client/cmdlft55xx.c | 199 ++++++++++++++++++++++++++++++++++++++++++-- client/cmdlft55xx.h | 5 +- 2 files changed, 195 insertions(+), 9 deletions(-) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 0fbf348d7..86ec6d0e2 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -51,12 +51,15 @@ t55xx_conf_block_t config = { .block0 = 0x00, .Q5 = false, .usepwd = false, - .downlink_mode = refFixedBit + .downlink_mode = refFixedBit, + .blockData = {0}, // array to hold data blocks + .blockValid = {0} // array to hold data valid status }; t55xx_conf_block_t Get_t55xx_Config() { return config; } + void Set_t55xx_Config(t55xx_conf_block_t conf) { config = conf; } @@ -179,8 +182,9 @@ static int usage_t55xx_info() { static int usage_t55xx_dump() { PrintAndLogEx(NORMAL, "Usage: lf t55xx dump [r ] [p [o]]"); PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " p - OPTIONAL password 4bytes (8 hex symbols)"); - PrintAndLogEx(NORMAL, " o - OPTIONAL override, force pwd read despite danger to card"); + PrintAndLogEx(NORMAL, " p - OPTIONAL password 4bytes (8 hex symbols)"); + PrintAndLogEx(NORMAL, " o - OPTIONAL override, force pwd read despite danger to card"); + PrintAndLogEx(NORMAL, " f - overide filename prefix (optional). Default is based on blk 0"); print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE,config.downlink_mode); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); @@ -189,6 +193,20 @@ static int usage_t55xx_dump() { PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } +static int usage_t55xx_restore() { + PrintAndLogEx(NORMAL, "Usage: lf t55xx restore f [p password]"); + PrintAndLogEx(NORMAL, "Options:"); + PrintAndLogEx(NORMAL, " f - filename of the dump file (.bin/.eml)"); + PrintAndLogEx(NORMAL, " p - optional password if target card has password set"); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, _YELLOW_(" Assumes lf t55 detect has been run first!")); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Examples:"); + PrintAndLogEx(NORMAL, " lf t55xx restore f lf-t55xx-00148040-data.bin"); + PrintAndLogEx(NORMAL, ""); + return PM3_SUCCESS; +} + static int usage_t55xx_detect() { PrintAndLogEx(NORMAL, "Usage: lf t55xx detect [1] [r ] [p ]"); PrintAndLogEx(NORMAL, "Options:"); @@ -339,6 +357,19 @@ static int usage_t55xx_protect() { static int CmdHelp(const char *Cmd); +void T55x7_SaveBlockData (uint8_t idx,uint32_t data) { + if (idx < T55x7_BLOCK_COUNT) { + config.blockValid[idx] = true; + config.blockData[idx] = data; + } +} +void T55x7_ClearAllBlockData (void) { + for (uint8_t idx = 0; idx < T55x7_BLOCK_COUNT; idx++) { + config.blockValid[idx] = false; + config.blockData[idx] = 0x00; + } +} + int clone_t55xx_tag(uint32_t *blockdata, uint8_t numblocks) { if (blockdata == NULL) @@ -785,7 +816,7 @@ int T55xxReadBlockEx(uint8_t block, bool page1, bool usepwd, uint8_t override, u return PM3_EWRONGANSVER; if (verbose) - printT55xxBlock(block); + printT55xxBlock(block,page1); return PM3_SUCCESS; } @@ -988,6 +1019,9 @@ static int CmdT55xxDetect(const char *Cmd) { } if (errors) return usage_t55xx_detect(); + // detect called so clear data blocks + T55x7_ClearAllBlockData (); + // sanity check. if (SanityOfflineCheck(useGB) != PM3_SUCCESS) return PM3_ESOFT; @@ -1300,7 +1334,7 @@ bool GetT55xxBlockData(uint32_t *blockdata) { return true; } -void printT55xxBlock(uint8_t blockNum) { +void printT55xxBlock(uint8_t blockNum, bool page1) { uint32_t blockData = 0; uint8_t bytes[4] = {0}; @@ -1310,6 +1344,8 @@ void printT55xxBlock(uint8_t blockNum) { num_to_bytes(blockData, 4, bytes); + T55x7_SaveBlockData ((page1)?blockNum+8 : blockNum,blockData); + PrintAndLogEx(SUCCESS, " %02d | %08X | %s | %s", blockNum, blockData, sprint_bin(DemodBuffer + config.offset, 32), sprint_ascii(bytes, 4)); } @@ -2091,6 +2127,8 @@ static int CmdT55xxDump(const char *Cmd) { bool usepwd = false; bool errors = false; uint8_t cmdp = 0; + char preferredName[FILE_PATH_SIZE] = {0}; + bool success = true; while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { @@ -2112,6 +2150,12 @@ static int CmdT55xxDump(const char *Cmd) { override = 1; cmdp++; break; + case 'f': + param_getstr(Cmd, cmdp + 1, preferredName, FILE_PATH_SIZE); + cmdp+=2; + if (strlen (preferredName) == 0) + errors = true; + break; default: PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); errors = true; @@ -2120,16 +2164,154 @@ static int CmdT55xxDump(const char *Cmd) { } if (errors) return usage_t55xx_dump(); + // Due to the few different T55xx cards and number of blocks supported + // will save the dump file if ALL page 0 is OK printT5xxHeader(0); for (uint8_t i = 0; i < 8; ++i) { - T55xxReadBlock(i, 0, usepwd, override, password, downlink_mode); + if (T55xxReadBlock(i, 0, usepwd, override, password, downlink_mode) != PM3_SUCCESS) + success = false; // idea for better user experience and display. // only show override warning on the first block read if (override == 1) override++; // flag not to show safty for 2nd and on. } printT5xxHeader(1); - for (uint8_t i = 0; i < 4; i++) - T55xxReadBlock(i, 1, usepwd, override, password, downlink_mode); + for (uint8_t i = 0; i < 4; i++) + if (T55xxReadBlock(i, 1, usepwd, override, password, downlink_mode) != PM3_SUCCESS) + T55x7_SaveBlockData (8+i,0x00); + + + if (success) { // all ok save dump to file + // saveFileEML will add .eml extension to filename + // saveFile (binary) passes in the .bin extension. + if (strcmp (preferredName,"") == 0) { // Set default filename, if not set by user + strcpy (preferredName,"lf-t55xx"); + for (uint8_t i = 1; i <= 7; i++) { + if ((config.blockData[i] != 0x00) && (config.blockData[i] != 0xFFFFFFFF)) + sprintf (preferredName,"%s-%08X",preferredName,config.blockData[i]); + else + break; + } + sprintf (preferredName,"%s-data",preferredName); + } + + // Swap endian so the files match the txt display + uint32_t data[T55x7_BLOCK_COUNT]; + + for (int i = 0; i < T55x7_BLOCK_COUNT; i++) + data[i] = BSWAP_32(config.blockData[i]); + + saveFileEML(preferredName, (uint8_t *)data, T55x7_BLOCK_COUNT*sizeof(uint32_t), sizeof(uint32_t)); + saveFile (preferredName, ".bin", data, sizeof(data)); + } + + return PM3_SUCCESS; +} + +static int CmdT55xxRestore(const char *Cmd) { + bool errors = false; + uint8_t cmdp = 0; + char preferredName[FILE_PATH_SIZE] = {0}; + char ext[FILE_PATH_SIZE] = {0}; + int success = PM3_ESOFT; + uint32_t password = 0x00; + bool usepwd = false; + uint32_t data[12] = {0}; + size_t datalen = 0; + uint8_t blockidx; + uint8_t downlink_mode; + char writeCmdOpt[100]; + char pwdOpt [11] = {0}; // p XXXXXXXX + + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { + case 'h': + return usage_t55xx_restore(); + case 'f': + param_getstr(Cmd, cmdp + 1, preferredName, FILE_PATH_SIZE); + if (strlen (preferredName) == 0) + errors = true; + cmdp+=2; + break; + case 'p': + password = param_get32ex(Cmd, cmdp + 1, 0, 16); + usepwd = true; + cmdp += 2; + break; + default: + PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } + } + + // File name expected to be .eml .bin or .json so sould be at least 4 + if (errors || (strlen (preferredName) == 0)) return usage_t55xx_restore(); + + // split file name into prefix and ext. + int fnLength; + + fnLength = strlen (preferredName); + + if (fnLength > 4) { // Holds .EXT [.bin|.eml] + memcpy (ext,&preferredName[fnLength - 4],4); + ext[5] = 0x00; + + if (memcmp (ext,".bin",4) == 0) { + preferredName[fnLength-4] = 0x00; + success = loadFile (preferredName, ".bin", data, sizeof(data),&datalen); + } + if (memcmp (ext,".eml",4) == 0) { + preferredName[fnLength-4] = 0x00; + datalen = 12; + success = loadFileEML(preferredName, (uint8_t *)data, &datalen); + } + } + + if (success == PM3_SUCCESS) { // Got data, so write to cards + if (datalen == T55x7_BLOCK_COUNT * 4) { // 12 blocks * 4 bytes per block + if (usepwd) + sprintf (pwdOpt,"p %08X",password); + + // Restore endien for writing to card + for (blockidx = 0; blockidx < 12; blockidx++) + data[blockidx] = BSWAP_32(data[blockidx]); + + // Have data ready, lets write + // Order + // write blocks 1..7 page 0 + // write blocks 1..3 page 1 + // update downlink mode (if needed) and write b 0 + downlink_mode = 0; + if ((((data[11] >> 28) & 0xf) == 6) || (((data[11] >> 28) & 0xf) == 9)) + downlink_mode = (data[11] >> 10) & 3; + + // write out blocks 1-7 page 0 + for (blockidx = 1; blockidx <= 7; blockidx++) { + sprintf (writeCmdOpt,"b %d d %08X %s",blockidx,data[blockidx],pwdOpt); + if (CmdT55xxWriteBlock(writeCmdOpt) != PM3_SUCCESS) + PrintAndLogEx(WARNING, "Warning: error writing blk %d",blockidx); + } + + // if password was set on the "blank" update as we may have just changed it + if (usepwd) + sprintf (pwdOpt,"p %08X",data[7]); + + // write out blocks 1-3 page 1 + for (blockidx = 9; blockidx <= 11; blockidx++) { + sprintf (writeCmdOpt,"b %d 1 d %08X %s",blockidx-8,data[blockidx],pwdOpt); + if (CmdT55xxWriteBlock(writeCmdOpt) != PM3_SUCCESS) + PrintAndLogEx(WARNING, "Warning: error writing blk %d",blockidx); + } + + // Update downlink mode for the page 0 config write. + config.downlink_mode = downlink_mode; + + // Write the page 0 config + sprintf (writeCmdOpt,"b 0 d %08X %s",data[0],pwdOpt); + if (CmdT55xxWriteBlock(writeCmdOpt) != PM3_SUCCESS) + PrintAndLogEx(WARNING, "Warning: error writing blk 0"); + } + } return PM3_SUCCESS; } @@ -3324,6 +3506,7 @@ static command_t CommandTable[] = { {"detect", CmdT55xxDetect, AlwaysAvailable, "[1] Try detecting the tag modulation from reading the configuration block."}, {"deviceconfig", CmdT55xxSetDeviceConfig, IfPm3Lf, "Set/Get T55XX device configuration (startgap, writegap, write0, write1, readgap"}, {"dump", CmdT55xxDump, IfPm3Lf, "[password] [o] Dump T55xx card block 0-7. Optional [password], [override]"}, + {"restore", CmdT55xxRestore, IfPm3Lf, "f [p ] -- Restore a dump file of a T55xx card"}, {"info", CmdT55xxInfo, AlwaysAvailable, "[1] Show T55x7 configuration data (page 0/ blk 0)"}, {"p1detect", CmdT55xxDetectPage1, IfPm3Lf, "[1] Try detecting if this is a t55xx tag by reading page 1"}, {"protect", CmdT55xxProtect, IfPm3Lf, "Password protect tag"}, diff --git a/client/cmdlft55xx.h b/client/cmdlft55xx.h index d7791466c..06c9399f1 100644 --- a/client/cmdlft55xx.h +++ b/client/cmdlft55xx.h @@ -20,6 +20,7 @@ #define T55x7_PAGE1 0x01 #define T55x7_PWD 0x00000010 #define REGULAR_READ_MODE_BLOCK 0xFF +#define T55x7_BLOCK_COUNT 12 // config blocks #define T55X7_DEFAULT_CONFIG_BLOCK 0x000880E8 // ASK, compat mode, data rate 32, manchester, STT, 7 data blocks @@ -125,6 +126,8 @@ typedef struct { refLeading0 = 0x02, ref1of4 = 0x03, } downlink_mode; + uint32_t blockData [T55x7_BLOCK_COUNT]; // the dump/read will save data here. + bool blockValid [T55x7_BLOCK_COUNT]; // this will allow easy access to the data for display etc. } t55xx_conf_block_t; t55xx_conf_block_t Get_t55xx_Config(void); @@ -144,7 +147,7 @@ char *GetModelStrFromCID(uint32_t cid); char *GetSelectedModulationStr(uint8_t id); char *GetDownlinkModeStr(uint8_t dlmode); void printT5xxHeader(uint8_t page); -void printT55xxBlock(uint8_t blockNum); +void printT55xxBlock(uint8_t blockNum,bool page1); int printConfiguration(t55xx_conf_block_t b); bool t55xxAquireAndCompareBlock0(bool usepwd, uint32_t password, uint32_t known_block0, bool verbose); From f6c1e73378890758084c01e081e5b6179d898a51 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 10 Oct 2019 12:34:11 +0200 Subject: [PATCH 0941/1854] coverity 263230 --- client/cmdtrace.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/cmdtrace.c b/client/cmdtrace.c index d9ee12a11..63cfa388c 100644 --- a/client/cmdtrace.c +++ b/client/cmdtrace.c @@ -188,10 +188,12 @@ static uint16_t printHexLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trac temp_str2, line); ret = tracepos; + break; } default: PrintAndLogEx(NORMAL, "Currently only 14a supported"); ret = traceLen; + break; } return ret; From 92639c9df8b52acf5cf95d493c7e21120e2f4f7b Mon Sep 17 00:00:00 2001 From: mwalker33 Date: Thu, 10 Oct 2019 21:38:53 +1100 Subject: [PATCH 0942/1854] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f6996545..140c072c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Added lf t55xx dump save and lf t55xx restore for .bin and .eml files (@mwalker33) - Added lf t55xx detected to try without password first (@mwalker33) - Display high bit for detected Kastle HIDs to allow `lf hid clone [id]` to work properly (@swg0101) - Add option `-n` to scripts pm3* (@doegox) From 8416bdb485f5bf7a52569261714476bc12875f9d Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 10 Oct 2019 12:41:12 +0200 Subject: [PATCH 0943/1854] coverity 226278 --- armsrc/appmain.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 248346b4f..4218d93a0 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1568,9 +1568,10 @@ static void PacketReceived(PacketCommandNG *packet) { BigBuf_Clear_ext(false); BigBuf_free(); } + uint16_t offset = MIN(BIGBUF_SIZE - PM3_CMD_DATA_SIZE - 3, payload->offset); uint8_t *mem = BigBuf_get_addr(); - memcpy(mem + payload->offset, &payload->data, PM3_CMD_DATA_SIZE - 3); + memcpy(mem + offset, &payload->data, PM3_CMD_DATA_SIZE - 3); reply_ng(CMD_LF_UPLOAD_SIM_SAMPLES, PM3_SUCCESS, NULL, 0); break; } From 18520a5dfd3eeb1b3855e44b8235f83d3a16bdda Mon Sep 17 00:00:00 2001 From: mwalker33 Date: Thu, 10 Oct 2019 22:07:57 +1100 Subject: [PATCH 0944/1854] Update cmdlft55xx.c --- client/cmdlft55xx.c | 195 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 157 insertions(+), 38 deletions(-) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 98767eda3..796179ad9 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -340,7 +340,8 @@ static int usage_t55xx_deviceconfig() { return PM3_SUCCESS; } static int usage_t55xx_protect() { - PrintAndLogEx(NORMAL, "This command set or unsets the pwd bit on T5577."); + PrintAndLogEx(NORMAL, "This command sets the pwd bit on T5577."); + PrintAndLogEx(NORMAL, _RED_("WARNING:") " this locks the tag!"); PrintAndLogEx(NORMAL, "Usage: lf t55xx protect [r ] [p ] [o] [n ]"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " p - OPTIONAL password (8 hex characters)"); @@ -371,8 +372,8 @@ void T55x7_ClearAllBlockData (void) { } int clone_t55xx_tag(uint32_t *blockdata, uint8_t numblocks) { - - if (blockdata == NULL) + + if (blockdata == NULL) return PM3_EINVARG; if (numblocks < 1 || numblocks > 8) return PM3_EINVARG; @@ -403,7 +404,7 @@ int clone_t55xx_tag(uint32_t *blockdata, uint8_t numblocks) { return PM3_ETIMEOUT; } } - + uint8_t res = 0; for (int8_t i = 0; i < numblocks; i++) { @@ -419,7 +420,7 @@ int clone_t55xx_tag(uint32_t *blockdata, uint8_t numblocks) { if (res == 0) PrintAndLogEx(SUCCESS, "Success writing to tag"); - + return PM3_SUCCESS; } @@ -496,7 +497,7 @@ bool t55xxAquireAndCompareBlock0(bool usepwd, uint32_t password, uint32_t known_ PrintAndLogEx(INFO, "Block0 write detected, running `detect` to see if validation is possible"); for (uint8_t m = 0; m < 4; m++) { - if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, m) == false) { + if (AcquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, m) == false) { continue; } @@ -529,7 +530,7 @@ bool t55xxAquireAndDetect(bool usepwd, uint32_t password, uint32_t known_block0, config.pwd = 0x00; for (uint8_t m = 0; m < 4; m++) { - if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, m) == false) + if (AcquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, m) == false) continue; if (tryDetectModulationEx(m, verbose, known_block0) == false) @@ -793,7 +794,7 @@ int T55xxReadBlockEx(uint8_t block, bool page1, bool usepwd, uint8_t override, u // override = 1 (override and display) // override = 2 (override and no display) if (override == 0) { - if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, false, 0, downlink_mode) == false) + if (AcquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, false, 0, downlink_mode) == false) return PM3_ERFTRANS; if (tryDetectModulation(downlink_mode, false) == false) { @@ -809,7 +810,7 @@ int T55xxReadBlockEx(uint8_t block, bool page1, bool usepwd, uint8_t override, u } } - if (AquireData(page1, block, usepwd, password, downlink_mode) == false) + if (AcquireData(page1, block, usepwd, password, downlink_mode) == false) return PM3_ERFTRANS; if (DecodeT55xxBlock() == false) @@ -1033,7 +1034,7 @@ static int CmdT55xxDetect(const char *Cmd) { if (try_all_dl_modes) { for (uint8_t m = downlink_mode; m < 4; m++) { - if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, try_with_pwd & usepwd, password, m) == false) + if (AcquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, try_with_pwd & usepwd, password, m) == false) continue; // pre fill to save passing in. @@ -1056,7 +1057,7 @@ static int CmdT55xxDetect(const char *Cmd) { else config.pwd = 0x00; - if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, downlink_mode)) { + if (AcquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, downlink_mode)) { found = tryDetectModulation(downlink_mode, T55XX_PrintConfig); } } @@ -1694,6 +1695,69 @@ static int CmdT55xxWriteBlock(const char *Cmd) { return PM3_SUCCESS; } +static int CmdT55xxDangerousRaw(const char *Cmd) { + // supports only default downlink mode + t55xx_test_block_t ng; + ng.time = 0; + ng.bitlen = 0; + memset(ng.data, 0x00, sizeof(ng.data)); + bool errors = false; + uint8_t cmdp = 0; + + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { + case 't': + ng.time = param_get32ex(Cmd, cmdp + 1, 0, 10); + if (ng.time == 0 || ng.time > 200000) { + PrintAndLogEx(ERR, "Timing off 1..200000 limits, got %i", ng.time); + errors = true; + break; + } + cmdp += 2; + break; + case 'b': { + uint32_t n = param_getlength(Cmd, cmdp + 1); + if (n > 128) { + PrintAndLogEx(ERR, "Bitstream too long, max 128 bits, got %i", n); + errors = true; + break; + } + for (uint8_t i = 0; i < n; i++) { + char c = param_getchar_indx(Cmd, i, cmdp + 1); + if (c == '0') + ng.data[i] = 0; + else if (c == '1') + ng.data[i] = 1; + else { + PrintAndLogEx(ERR, "Unknown bit char '%c'", c); + errors = true; + break; + } + } + ng.bitlen = n; + cmdp += 2; + break; + } + default: + PrintAndLogEx(ERR, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } + } + if (errors || ng.bitlen == 0 || ng.time == 0) { + PrintAndLogEx(ERR, "Error occurred, abort. " _RED_("DANGEROUS COMMAND, DO NOT USE!")); + return PM3_EINVARG; + } + PacketResponseNG resp; + clearCommandBuffer(); + SendCommandNG(CMD_LF_T55XX_DANGERRAW, (uint8_t *)&ng, sizeof(ng)); + if (!WaitForResponseTimeout(CMD_LF_T55XX_DANGERRAW, &resp, 2000)) { + PrintAndLogEx(ERR, "Error occurred, device did not ACK write operation."); + return PM3_ETIMEOUT; + } + return resp.status; +} + static int CmdT55xxReadTrace(const char *Cmd) { bool frombuff = false; @@ -1733,7 +1797,7 @@ static int CmdT55xxReadTrace(const char *Cmd) { uint32_t password = 0; // REGULAR_READ_MODE_BLOCK - yeilds correct Page 1 Block 2 data i.e. + 32 bit offset. - if (!AquireData(T55x7_PAGE1, REGULAR_READ_MODE_BLOCK, pwdmode, password, downlink_mode)) + if (!AcquireData(T55x7_PAGE1, REGULAR_READ_MODE_BLOCK, pwdmode, password, downlink_mode)) return PM3_ENODATA; } @@ -2036,7 +2100,7 @@ static int CmdT55xxInfo(const char *Cmd) { // sanity check. if (SanityOfflineCheck(false) != PM3_SUCCESS) return PM3_ENODATA; - if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, downlink_mode)) + if (!AcquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, downlink_mode)) return PM3_ENODATA; } @@ -2327,7 +2391,60 @@ static int CmdT55xxRestore(const char *Cmd) { return PM3_SUCCESS; } -bool AquireData(uint8_t page, uint8_t block, bool pwdmode, uint32_t password, uint8_t downlink_mode) { +static int CmdT55xxRestore(const char *Cmd) { + + uint32_t password = 0; + uint8_t override = 0; + uint8_t downlink_mode = config.downlink_mode;; + bool usepwd = false; + bool errors = false; + uint8_t cmdp = 0; + + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { + case 'h': + return usage_t55xx_restore(); + case 'r': + downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); + if (downlink_mode > 3) + downlink_mode = 0; + + cmdp += 2; + break; + case 'p': + password = param_get32ex(Cmd, cmdp + 1, 0, 16); + usepwd = true; + cmdp += 2; + break; + case 'o': + override = 1; + cmdp++; + break; + default: + PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } + } + if (errors) return usage_t55xx_restore(); + + PrintAndLogEx(INFO, "Work in progress. To be implemented"); + if (usepwd || password || override ) { + + } + // load file name (json/eml/bin) + + // Print dump data? + + uint32_t res = PM3_SUCCESS; + +// page0. +// res = clone_t55xx_tag(blockdata, numblocks); + + return res; +} + +bool AcquireData(uint8_t page, uint8_t block, bool pwdmode, uint32_t password, uint8_t downlink_mode) { // arg0 bitmodes: // b0 = pwdmode // b1 = page to read from @@ -2670,18 +2787,19 @@ static int CmdResetRead(const char *Cmd) { if (resp.status == PM3_SUCCESS) { - uint8_t *got = calloc(BIGBUF_SIZE - 1, sizeof(uint8_t)); + uint16_t gotsize = BIGBUF_SIZE - 1; + uint8_t *got = calloc(gotsize, sizeof(uint8_t)); if (got == NULL) { PrintAndLogEx(WARNING, "failed to allocate memory"); return PM3_EMALLOC; } - if (!GetFromDevice(BIG_BUF, got, sizeof(got), 0, NULL, 0, NULL, 2500, false)) { + if (!GetFromDevice(BIG_BUF, got, gotsize, 0, NULL, 0, NULL, 2500, false)) { PrintAndLogEx(WARNING, "command execution time out"); free(got); return PM3_ETIMEOUT; } - setGraphBuf(got, sizeof(got)); + setGraphBuf(got, gotsize); free(got); } return PM3_SUCCESS; @@ -2826,7 +2944,7 @@ static int CmdT55xxChkPwds(const char *Cmd) { } } - if (errors) return usage_t55xx_chk(); + if (errors || cmdp == 0) return usage_t55xx_chk(); /* // block 7, page1 = false, usepwd = false, override = false, pwd = 00000000 @@ -2859,10 +2977,10 @@ static int CmdT55xxChkPwds(const char *Cmd) { if (resp.oldarg[0]) { PrintAndLogEx(SUCCESS, "\nFound a candidate [ " _YELLOW_("%08"PRIX64) " ]. Trying to validate", resp.oldarg[1]); - if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, resp.oldarg[1], downlink_mode)) { + if (AcquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, resp.oldarg[1], downlink_mode)) { found = tryDetectModulation(downlink_mode, T55XX_PrintConfig); if (found) { - PrintAndLogEx(SUCCESS, "Found valid password: [ " _GREEN_("%08"PRIX64) " ]", resp.oldarg[1]); + PrintAndLogEx(SUCCESS, "Found valid password: [ " _GREEN_("%08"PRIX64) "]", resp.oldarg[1]); } else { PrintAndLogEx(WARNING, "Check pwd failed"); @@ -2908,13 +3026,13 @@ static int CmdT55xxChkPwds(const char *Cmd) { PrintAndLogEx(INFO, "Testing %08"PRIX64, curr_password); for (dl_mode = downlink_mode; dl_mode <= 3; dl_mode++) { - if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, curr_password, dl_mode)) { + if (!AcquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, curr_password, dl_mode)) { continue; } found = tryDetectModulation(dl_mode, T55XX_PrintConfig); if (found) { - PrintAndLogEx(SUCCESS, "Found valid password: [ " _GREEN_("%08"PRIX64) " ]", curr_password); + PrintAndLogEx(SUCCESS, "Found valid password: [ " _GREEN_("%08"PRIX64) "]", curr_password); dl_mode = 4; // Exit other downlink mode checks c = keycount; // Exit loop } @@ -2970,11 +3088,11 @@ static int CmdT55xxBruteForce(const char *Cmd) { break; } } - if (start_password >= end_password) { - return usage_t55xx_bruteforce(); - } - if (errors) return usage_t55xx_bruteforce(); + if (start_password >= end_password) + errors = true; + + if (errors || cmdp == 0) return usage_t55xx_bruteforce(); uint64_t t1 = msclock(); @@ -3005,7 +3123,7 @@ static int CmdT55xxBruteForce(const char *Cmd) { PrintAndLogEx(SUCCESS, "Found valid password: [ " _GREEN_("%08X") "]", curr - 1); T55xx_Print_DownlinkMode((found >> 1) & 3); } else - PrintAndLogEx(WARNING, "Bruteforce failed, last tried: [ " _YELLOW_("%08X") " ]", curr); + PrintAndLogEx(WARNING, "Bruteforce failed, last tried: [ " _YELLOW_("%08X") "]", curr); t1 = msclock() - t1; PrintAndLogEx(SUCCESS, "\nTime in bruteforce: %.0f seconds\n", (float)t1 / 1000.0); @@ -3026,14 +3144,14 @@ uint8_t tryOnePassword(uint32_t password, uint8_t downlink_mode) { // check if dl mode 4 and loop if needed for (dl_mode = downlink_mode; dl_mode < 4; dl_mode++) { - AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, password, dl_mode); - - // if (getSignalProperties()->isnoise == false) { - // } else { - if (tryDetectModulation(dl_mode, T55XX_PrintConfig)) { - return 1 + (dl_mode << 1); + if (AcquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, password, dl_mode)) { + // if (getSignalProperties()->isnoise == false) { + // } else { + if (tryDetectModulation(dl_mode, T55XX_PrintConfig)) { + return 1 + (dl_mode << 1); + } + // } } - // } if (!try_all_dl_modes) dl_mode = 4; } return 0; @@ -3073,8 +3191,7 @@ static int CmdT55xxRecoverPW(const char *Cmd) { } } - if (errors) return usage_t55xx_recoverpw(); - + if (errors || cmdp == 0) return usage_t55xx_recoverpw(); // first try fliping each bit in the expected password while (bit < 32) { @@ -3161,7 +3278,7 @@ bool tryDetectP1(bool getData) { bool st = true; if (getData) { - if (!AquireData(T55x7_PAGE1, T55x7_TRACE_BLOCK1, false, 0, 0)) + if (!AcquireData(T55x7_PAGE1, T55x7_TRACE_BLOCK1, false, 0, 0)) return false; } @@ -3311,7 +3428,7 @@ static int CmdT55xxDetectPage1(const char *Cmd) { if (!useGB) { for (dl_mode = downlink_mode; dl_mode < 4; dl_mode++) { - found = AquireData(T55x7_PAGE1, T55x7_TRACE_BLOCK1, usepwd, password, dl_mode); + found = AcquireData(T55x7_PAGE1, T55x7_TRACE_BLOCK1, usepwd, password, dl_mode); //return PM3_ENODATA; if (tryDetectP1(false)) { //tryDetectModulation()) found = true; @@ -3515,6 +3632,7 @@ static command_t CommandTable[] = { {"bruteforce", CmdT55xxBruteForce, IfPm3Lf, " Simple bruteforce attack to find password"}, {"config", CmdT55xxSetConfig, AlwaysAvailable, "Set/Get T55XX configuration (modulation, inverted, offset, rate)"}, {"chk", CmdT55xxChkPwds, IfPm3Lf, "Check passwords from dictionary/flash"}, + {"dangerraw", CmdT55xxDangerousRaw, IfPm3Lf, "Sends raw bitstream. Dangerous, do not use!! b t "}, {"detect", CmdT55xxDetect, AlwaysAvailable, "[1] Try detecting the tag modulation from reading the configuration block."}, {"deviceconfig", CmdT55xxSetDeviceConfig, IfPm3Lf, "Set/Get T55XX device configuration (startgap, writegap, write0, write1, readgap"}, {"dump", CmdT55xxDump, IfPm3Lf, "[password] [o] Dump T55xx card block 0-7. Optional [password], [override]"}, @@ -3524,6 +3642,7 @@ static command_t CommandTable[] = { {"protect", CmdT55xxProtect, IfPm3Lf, "Password protect tag"}, {"read", CmdT55xxReadBlock, IfPm3Lf, "b p [password] [o] [1] -- Read T55xx block data. Optional [p password], [override], [page1]"}, {"resetread", CmdResetRead, IfPm3Lf, "Send Reset Cmd then lf read the stream to attempt to identify the start of it (needs a demod and/or plot after)"}, + {"restore", CmdT55xxRestore, IfPm3Lf, "[password] Restore T55xx card Page 0 / Page 1 blocks"}, {"recoverpw", CmdT55xxRecoverPW, IfPm3Lf, "[password] Try to recover from bad password write from a cloner. Only use on PW protected chips!"}, {"special", special, IfPm3Lf, "Show block changes with 64 different offsets"}, {"trace", CmdT55xxReadTrace, AlwaysAvailable, "[1] Show T55x7 traceability data (page 1/ blk 0-1)"}, From ed4cdc8b759d433880c12ba1b57efd5d1cec0830 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 10 Oct 2019 13:11:29 +0200 Subject: [PATCH 0945/1854] coverity 226411 --- client/loclass/cipherutils.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/loclass/cipherutils.c b/client/loclass/cipherutils.c index b50268697..c2a802c7a 100644 --- a/client/loclass/cipherutils.c +++ b/client/loclass/cipherutils.c @@ -150,6 +150,8 @@ void reverse_arraycopy(uint8_t *arr, uint8_t *dest, size_t len) { } void printarr(const char *name, uint8_t *arr, int len) { + if (name == NULL || arr == NULL) return; + int cx, i; size_t outsize = 40 + strlen(name) + len * 5; char *output = calloc(outsize, sizeof(char)); From 12622709243992599a13768f92823684d127f4ed Mon Sep 17 00:00:00 2001 From: martinbeier Date: Thu, 10 Oct 2019 14:25:41 +0200 Subject: [PATCH 0946/1854] added indala 26bit decoding --- client/cmdlfindala.c | 46 +++++++++++++++++++++++++++++++------------- 1 file changed, 33 insertions(+), 13 deletions(-) diff --git a/client/cmdlfindala.c b/client/cmdlfindala.c index 914b510fc..0668fedd6 100644 --- a/client/cmdlfindala.c +++ b/client/cmdlfindala.c @@ -69,7 +69,7 @@ static int usage_lf_indala_sim(void) { } // Indala 26 bit decode -// by marshmellow +// by marshmellow, martinbeier // optional arguments - same as PSKDemod (clock & invert & maxerr) static int CmdIndalaDemod(const char *Cmd) { @@ -136,24 +136,44 @@ static int CmdIndalaDemod(const char *Cmd) { p1 |= DemodBuffer[32 + 22] << 0; p1 |= DemodBuffer[32 + 24] << 9; - /* - uint16_t fc = 0; - fc |= DemodBuffer[32+ 1] << 0; - fc |= DemodBuffer[32+ 2] << 1; - fc |= DemodBuffer[32+ 4] << 2; - fc |= DemodBuffer[32+ 5] << 3; - fc |= DemodBuffer[32+ 7] << 4; - fc |= DemodBuffer[32+10] << 5; - fc |= DemodBuffer[32+14] << 6; - fc |= DemodBuffer[32+15] << 7; - fc |= DemodBuffer[32+17] << 8; - */ + uint8_t fc = 0; + fc |= DemodBuffer[32+25] << 7; // b8 + fc |= DemodBuffer[32+17] << 6; // b7 + fc |= DemodBuffer[32+12] << 5; // b6 + fc |= DemodBuffer[32+16] << 4; // b5 + fc |= DemodBuffer[32+15] << 3; // b4 + fc |= DemodBuffer[32+21] << 2; // b3 + fc |= DemodBuffer[32+7] << 1; // b2 + fc |= DemodBuffer[32+26] << 0; // b1 + + uint16_t csn = 0; + csn |= DemodBuffer[32+10] << 15; // b16 + csn |= DemodBuffer[32+13] << 14; // b15 + csn |= DemodBuffer[32+11] << 13; // b14 + csn |= DemodBuffer[32+8] << 12; // b13 + csn |= DemodBuffer[32+20] << 11; // b12 + csn |= DemodBuffer[32+4] << 10; // b11 + csn |= DemodBuffer[32+3] << 9; // b10 + csn |= DemodBuffer[32+19] << 8; // b9 + csn |= DemodBuffer[32+14] << 7; // b8 + csn |= DemodBuffer[32+1] << 6; // b7 + csn |= DemodBuffer[32+5] << 5; // b6 + csn |= DemodBuffer[32+22] << 4; // b5 + csn |= DemodBuffer[32+24] << 3; // b4 + csn |= DemodBuffer[32+27] << 2; // b3 + csn |= DemodBuffer[32+18] << 1; // b2 + csn |= DemodBuffer[32+9] << 0; // b1 + + uint8_t checksum = 0; + checksum |= DemodBuffer[32+30] << 1; // b2 + checksum |= DemodBuffer[92+31] << 0; // b1 PrintAndLogEx(NORMAL, ""); PrintAndLogEx(SUCCESS, "Possible de-scramble patterns"); PrintAndLogEx(SUCCESS, "\tPrinted | __%04d__ [0x%X]", p1, p1); //PrintAndLogEx(SUCCESS, "\tPrinted | __%04d__ [0x%X]", fc, fc); PrintAndLogEx(SUCCESS, "\tInternal ID | %" PRIu64, foo); + PrintAndLogEx(SUCCESS, "\nFC %u , CSN %u , checksum %1d%1d", fc, csn, checksum >> 1 & 0x01, checksum & 0x01 ); } else { From 81c1625bfc7755c702f42676dde6cd07ade34241 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 10 Oct 2019 14:52:51 +0200 Subject: [PATCH 0947/1854] cov settings --- .coverity.conf.sample | 6 +++++- covbuild.sh | 39 +++++++++++++++++++++++++++++++-------- covconfig.sh | 3 +++ 3 files changed, 39 insertions(+), 9 deletions(-) diff --git a/.coverity.conf.sample b/.coverity.conf.sample index 3ed4be64b..5caf5d6fb 100644 --- a/.coverity.conf.sample +++ b/.coverity.conf.sample @@ -4,9 +4,13 @@ COVTOKEN=aAbBcCdDeEfFgGhHiIjJkK COVBINDIR="/opt/cov-analysis-linux64-2019.03/bin" # Nickname included in scan description: NICKNAME=myself +# cov can't read gcov from gcc > 7 +HOSTCC=gcc-7 +HOSTCXX=g++-7 +HOSTLD=g++-7 +# Do not change it: COVDIR=cov-int -COVBUILD="cov-build --dir $COVDIR" # Depending if your kernel > 4.8.x, you might need to activate this to run Coverity executables # (but latest tools with kernel 5.2 run fine) diff --git a/covbuild.sh b/covbuild.sh index bd06630d4..4784a1de6 100755 --- a/covbuild.sh +++ b/covbuild.sh @@ -5,16 +5,39 @@ set -e pre_build_hook -rm -rf "$COVDIR" -mkdir "$COVDIR" +mkdir -p "$COVDIR" make clean -$COVBUILD make -j 4 bootrom -$COVBUILD make -j 4 fullimage -$COVBUILD make -j 4 mfkey -$COVBUILD make -j 4 nonce2key -$COVBUILD make -j 4 fpga_compress +cov-build --dir "$COVDIR" --initialize + +######################################### +# Build Host prerequisites # +######################################### +cov-build --dir "$COVDIR" --c-coverage=gcov --no-network-coverage --no-generate-build-id --force make CC=$HOSTCC CXX=$HOSTCXX LD=$HOSTLD fpga_compress + +######################################### +# Build ARM, no test coverage # +######################################### +cov-build --dir "$COVDIR" --no-generate-build-id --force make bootrom +cov-build --dir "$COVDIR" --no-generate-build-id --force make fullimage + +######################################### +# Build client # +######################################### # make sure to do client after ARM because Coverity retains one build info per file # and we want the client-side of the common/ analysis -$COVBUILD make -j 4 client +cov-build --dir "$COVDIR" --c-coverage=gcov --no-network-coverage --no-generate-build-id --force make CC=$HOSTCC CXX=$HOSTCXX LD=$HOSTLD mfkey +cov-build --dir "$COVDIR" --c-coverage=gcov --no-network-coverage --no-generate-build-id --force make CC=$HOSTCC CXX=$HOSTCXX LD=$HOSTLD nonce2key +cov-build --dir "$COVDIR" --c-coverage=gcov --no-network-coverage --no-generate-build-id --force make CC=$HOSTCC CXX=$HOSTCXX LD=$HOSTLD client + +######################################### +# Run tests # +######################################### +cov-build --dir "$COVDIR" --c-coverage=gcov --no-network-coverage --test-capture ./pm3test.sh +#cov-manage-emit --dir "$COVDIR" list-coverage-known + +######################################### +# Import Git annotations (~ git blame) # +######################################### +cov-import-scm --dir "$COVDIR" --scm git --filename-regex "$PWD" --log ""$COVDIR"/cov-import-scm-log.txt" post_build_hook diff --git a/covconfig.sh b/covconfig.sh index 5f4878b3c..24815f200 100755 --- a/covconfig.sh +++ b/covconfig.sh @@ -3,4 +3,7 @@ set -e . .coverity.conf || exit 1 +# cov-configure --list-configured-compilers text cov-configure --template --compiler arm-none-eabi-gcc --comptype gcc +# cov can't read gcov from gcc > 7 +cov-configure --template --compiler $HOSTCC --comptype gcc From d61a7b4a0fd6599436379646703c1df4da8577b4 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 10 Oct 2019 15:10:22 +0200 Subject: [PATCH 0948/1854] textual --- client/cmdlfindala.c | 62 +++++++++++++++++++++----------------------- 1 file changed, 30 insertions(+), 32 deletions(-) diff --git a/client/cmdlfindala.c b/client/cmdlfindala.c index 0668fedd6..8926d9007 100644 --- a/client/cmdlfindala.c +++ b/client/cmdlfindala.c @@ -137,44 +137,42 @@ static int CmdIndalaDemod(const char *Cmd) { p1 |= DemodBuffer[32 + 24] << 9; uint8_t fc = 0; - fc |= DemodBuffer[32+25] << 7; // b8 - fc |= DemodBuffer[32+17] << 6; // b7 - fc |= DemodBuffer[32+12] << 5; // b6 - fc |= DemodBuffer[32+16] << 4; // b5 - fc |= DemodBuffer[32+15] << 3; // b4 - fc |= DemodBuffer[32+21] << 2; // b3 - fc |= DemodBuffer[32+7] << 1; // b2 - fc |= DemodBuffer[32+26] << 0; // b1 - + fc |= DemodBuffer[57] << 7; // b8 + fc |= DemodBuffer[49] << 6; // b7 + fc |= DemodBuffer[44] << 5; // b6 + fc |= DemodBuffer[48] << 4; // b5 + fc |= DemodBuffer[47] << 3; // b4 + fc |= DemodBuffer[53] << 2; // b3 + fc |= DemodBuffer[39] << 1; // b2 + fc |= DemodBuffer[58] << 0; // b1 + uint16_t csn = 0; - csn |= DemodBuffer[32+10] << 15; // b16 - csn |= DemodBuffer[32+13] << 14; // b15 - csn |= DemodBuffer[32+11] << 13; // b14 - csn |= DemodBuffer[32+8] << 12; // b13 - csn |= DemodBuffer[32+20] << 11; // b12 - csn |= DemodBuffer[32+4] << 10; // b11 - csn |= DemodBuffer[32+3] << 9; // b10 - csn |= DemodBuffer[32+19] << 8; // b9 - csn |= DemodBuffer[32+14] << 7; // b8 - csn |= DemodBuffer[32+1] << 6; // b7 - csn |= DemodBuffer[32+5] << 5; // b6 - csn |= DemodBuffer[32+22] << 4; // b5 - csn |= DemodBuffer[32+24] << 3; // b4 - csn |= DemodBuffer[32+27] << 2; // b3 - csn |= DemodBuffer[32+18] << 1; // b2 - csn |= DemodBuffer[32+9] << 0; // b1 - - uint8_t checksum = 0; - checksum |= DemodBuffer[32+30] << 1; // b2 - checksum |= DemodBuffer[92+31] << 0; // b1 + csn |= DemodBuffer[42] << 15; // b16 + csn |= DemodBuffer[45] << 14; // b15 + csn |= DemodBuffer[43] << 13; // b14 + csn |= DemodBuffer[40] << 12; // b13 + csn |= DemodBuffer[52] << 11; // b12 + csn |= DemodBuffer[36] << 10; // b11 + csn |= DemodBuffer[35] << 9; // b10 + csn |= DemodBuffer[51] << 8; // b9 + csn |= DemodBuffer[46] << 7; // b8 + csn |= DemodBuffer[33] << 6; // b7 + csn |= DemodBuffer[37] << 5; // b6 + csn |= DemodBuffer[54] << 4; // b5 + csn |= DemodBuffer[56] << 3; // b4 + csn |= DemodBuffer[59] << 2; // b3 + csn |= DemodBuffer[50] << 1; // b2 + csn |= DemodBuffer[41] << 0; // b1 + + uint8_t checksum = 0; + checksum |= DemodBuffer[62] << 1; // b2 + checksum |= DemodBuffer[63] << 0; // b1 PrintAndLogEx(NORMAL, ""); PrintAndLogEx(SUCCESS, "Possible de-scramble patterns"); PrintAndLogEx(SUCCESS, "\tPrinted | __%04d__ [0x%X]", p1, p1); - //PrintAndLogEx(SUCCESS, "\tPrinted | __%04d__ [0x%X]", fc, fc); PrintAndLogEx(SUCCESS, "\tInternal ID | %" PRIu64, foo); - PrintAndLogEx(SUCCESS, "\nFC %u , CSN %u , checksum %1d%1d", fc, csn, checksum >> 1 & 0x01, checksum & 0x01 ); - + PrintAndLogEx(SUCCESS, "Fmt 26 bit FC %u , CSN %u , checksum %1d%1d", fc, csn, checksum >> 1 & 0x01, checksum & 0x01 ); } else { uint32_t uid3 = bytebits_to_byte(DemodBuffer + 64, 32); From 602067da4a508dd3c199e5aadf467c1707e2c82d Mon Sep 17 00:00:00 2001 From: martinbeier Date: Thu, 10 Oct 2019 15:32:27 +0200 Subject: [PATCH 0949/1854] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f6996545..102cd8590 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Chg ´lf indala read´ - added indala 26bit decoding (@martinbeier) - Added lf t55xx detected to try without password first (@mwalker33) - Display high bit for detected Kastle HIDs to allow `lf hid clone [id]` to work properly (@swg0101) - Add option `-n` to scripts pm3* (@doegox) From baffd45d5ae5923e32d6d1cf6c95f9998a727927 Mon Sep 17 00:00:00 2001 From: martinbeier Date: Thu, 10 Oct 2019 16:01:54 +0200 Subject: [PATCH 0950/1854] fixed indala FC decoding --- client/cmdlfindala.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/cmdlfindala.c b/client/cmdlfindala.c index 8926d9007..c93d695aa 100644 --- a/client/cmdlfindala.c +++ b/client/cmdlfindala.c @@ -140,8 +140,8 @@ static int CmdIndalaDemod(const char *Cmd) { fc |= DemodBuffer[57] << 7; // b8 fc |= DemodBuffer[49] << 6; // b7 fc |= DemodBuffer[44] << 5; // b6 - fc |= DemodBuffer[48] << 4; // b5 - fc |= DemodBuffer[47] << 3; // b4 + fc |= DemodBuffer[47] << 4; // b5 + fc |= DemodBuffer[48] << 3; // b4 fc |= DemodBuffer[53] << 2; // b3 fc |= DemodBuffer[39] << 1; // b2 fc |= DemodBuffer[58] << 0; // b1 From 973c1c71cf6b22f2c7c5d9645bfdd40e0f259392 Mon Sep 17 00:00:00 2001 From: Iceman Date: Thu, 10 Oct 2019 16:27:33 +0200 Subject: [PATCH 0951/1854] Update CHANGELOG.md --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 102cd8590..86b768210 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,8 +3,8 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] - - Chg ´lf indala read´ - added indala 26bit decoding (@martinbeier) - - Added lf t55xx detected to try without password first (@mwalker33) + - Chg `lf indala read` - added indala 26bit decoding (@martinbeier) + - Chg `lf t55xx detect` to try without password first (@mwalker33) - Display high bit for detected Kastle HIDs to allow `lf hid clone [id]` to work properly (@swg0101) - Add option `-n` to scripts pm3* (@doegox) - Add `wiegand list/encode/decode` - wiegand format manipulation. Adapted to fit here. (@grauerfuchs) From 6781eeae1eb3d84a47d50fce91517728d8a01f43 Mon Sep 17 00:00:00 2001 From: Iceman Date: Fri, 11 Oct 2019 09:32:51 +0200 Subject: [PATCH 0952/1854] Update README.md --- README.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7f5b35569..8ff5a3b61 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,10 @@ On the software side: quite a lot, see the [Changelog file](CHANGELOG.md). ## Development -This repo now compiles just fine on +⚠ **Note**: This is a bleeding edge repository. The maintainers actively is working out of this repository and will be periodically re-structuring the code to make it easier to comprehend, navigate, build, test, and contribute to, so **DO expect significant changes to code layout on a regular basis**. + + +This repo compiles nicely on - Proxspace v3.2 - Windows/mingw environment with Qt5.6.1 & GCC 4.8 - Ubuntu 1404, 1510, 1604, 1804, 1904 @@ -54,8 +57,9 @@ This repo now compiles just fine on - WSL, WSL2 (Windows subsystem linux) on Windows 10 - Docker container -If you intend to contribute to the code, please read the [coding style notes](HACKING.md) first. +👉 **Remember** If you intend to contribute to the code, please read the [coding style notes](HACKING.md) first. +## Notes / helpful documents - Internal notes on [Coverity Scan Config & Run](/doc/md/Development/Coverity-Scan-Config-%26-Run.md). - Internal notes on [UART](/doc/uart_notes.md) - Internal notes on [Frame format](/doc/new_frame_format.md) From b2fb2677743a89e4775a48e159ac2180788cbddb Mon Sep 17 00:00:00 2001 From: Iceman Date: Fri, 11 Oct 2019 09:34:55 +0200 Subject: [PATCH 0953/1854] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8ff5a3b61..7386baf10 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,8 @@ This repo compiles nicely on - WSL, WSL2 (Windows subsystem linux) on Windows 10 - Docker container -👉 **Remember** If you intend to contribute to the code, please read the [coding style notes](HACKING.md) first. +👉 **Remember!** If you intend to contribute to the code, please read the [coding style notes](HACKING.md) first. +We usually merge your contributions fast since we do like the idea of getting a functionality in the Proxmark3 and weed out the bugs afterwards. ## Notes / helpful documents - Internal notes on [Coverity Scan Config & Run](/doc/md/Development/Coverity-Scan-Config-%26-Run.md). From f5d0fdf2a1aec7b0f1f98741999c3bc429e78b5e Mon Sep 17 00:00:00 2001 From: Iceman Date: Fri, 11 Oct 2019 09:36:09 +0200 Subject: [PATCH 0954/1854] Update README.md --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 7386baf10..62c3add53 100644 --- a/README.md +++ b/README.md @@ -45,8 +45,7 @@ On the software side: quite a lot, see the [Changelog file](CHANGELOG.md). ## Development -⚠ **Note**: This is a bleeding edge repository. The maintainers actively is working out of this repository and will be periodically re-structuring the code to make it easier to comprehend, navigate, build, test, and contribute to, so **DO expect significant changes to code layout on a regular basis**. - +> ⚠ **Note**: This is a bleeding edge repository. The maintainers actively is working out of this repository and will be periodically re-structuring the code to make it easier to comprehend, navigate, build, test, and contribute to, so **DO expect significant changes to code layout on a regular basis**. This repo compiles nicely on - Proxspace v3.2 @@ -57,7 +56,7 @@ This repo compiles nicely on - WSL, WSL2 (Windows subsystem linux) on Windows 10 - Docker container -👉 **Remember!** If you intend to contribute to the code, please read the [coding style notes](HACKING.md) first. +> 👉 **Remember!** If you intend to contribute to the code, please read the [coding style notes](HACKING.md) first. We usually merge your contributions fast since we do like the idea of getting a functionality in the Proxmark3 and weed out the bugs afterwards. ## Notes / helpful documents From 9c82f84fa7ab49d1147c9fd18193280e108fbcae Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 11 Oct 2019 11:26:14 +0200 Subject: [PATCH 0955/1854] analyze demodbuff - fill demodbuffer with binary from client --- client/cmdanalyse.c | 59 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 53 insertions(+), 6 deletions(-) diff --git a/client/cmdanalyse.c b/client/cmdanalyse.c index 733c741c7..6f3af2247 100644 --- a/client/cmdanalyse.c +++ b/client/cmdanalyse.c @@ -12,7 +12,7 @@ #include // size_t #include #include // tolower - +#include // printf #include "commonutil.h" // reflect... #include "comms.h" // clearCommandBuffer #include "cmdparser.h" // command_t @@ -21,6 +21,7 @@ #include "crc16.h" // crc16 ccitt #include "tea.h" #include "legic_prng.h" +#include "cmddata.h" // demodbuffer static int CmdHelp(const char *Cmd); @@ -36,7 +37,7 @@ static int usage_analyse_lcr(void) { PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " analyse lcr 04008064BA"); PrintAndLogEx(NORMAL, "expected output: Target (BA) requires final LRC XOR byte value: 5A"); - return 0; + return PM3_SUCCESS; } static int usage_analyse_checksum(void) { PrintAndLogEx(NORMAL, "The bytes will be added with eachother and than limited with the applied mask"); @@ -52,7 +53,7 @@ static int usage_analyse_checksum(void) { PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " analyse chksum b 137AF00A0A0D m FF"); PrintAndLogEx(NORMAL, "expected output: 0x61"); - return 0; + return PM3_SUCCESS; } static int usage_analyse_crc(void) { PrintAndLogEx(NORMAL, "A stub method to test different crc implementations inside the PM3 sourcecode. Just because you figured out the poly, doesn't mean you get the desired output"); @@ -64,7 +65,7 @@ static int usage_analyse_crc(void) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " analyse crc 137AF00A0A0D"); - return 0; + return PM3_SUCCESS; } static int usage_analyse_nuid(void) { PrintAndLogEx(NORMAL, "Generate 4byte NUID from 7byte UID"); @@ -76,7 +77,7 @@ static int usage_analyse_nuid(void) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " analyse nuid 11223344556677"); - return 0; + return PM3_SUCCESS; } static int usage_analyse_a(void) { PrintAndLogEx(NORMAL, "Iceman's personal garbage test command"); @@ -88,7 +89,19 @@ static int usage_analyse_a(void) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " analyse a d 137AF00A0A0D"); - return 0; + return PM3_SUCCESS; +} +static int usage_analyse_demodbuffer(void) { + PrintAndLogEx(NORMAL, "loads a binary string into demod buffer"); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Usage: analyse demodbuff [h] "); + PrintAndLogEx(NORMAL, "Options:"); + PrintAndLogEx(NORMAL, " h This help"); + PrintAndLogEx(NORMAL, " Binary string to load"); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Examples:"); + PrintAndLogEx(NORMAL, " analyse demodbuff 0011101001001011"); + return PM3_SUCCESS; } static uint8_t calculateLRC(uint8_t *bytes, uint8_t len) { @@ -878,6 +891,39 @@ static int CmdAnalyseNuid(const char *Cmd) { PrintAndLogEx(NORMAL, "NUID | %s \n", sprint_hex(nuid, 4)); return 0; } + +static int CmdAnalyseDemodBuffer(const char *Cmd) { + + char cmdp = tolower(param_getchar(Cmd, 0)); + if (strlen(Cmd) == 0 || cmdp == 'h') return usage_analyse_demodbuffer(); + + int bg = 0, en = 0; + if (param_getptr(Cmd, &bg, &en, 0)) + return usage_analyse_demodbuffer(); + + int len = MIN( (en- bg + 1), MAX_DEMOD_BUF_LEN); + + // add 1 for null terminator. + uint8_t *data = calloc(len + 1, sizeof(uint8_t)); + if (!data) return PM3_EMALLOC; + + for(int i = 0; bg <= en; bg++ , i++) { + char c = Cmd[bg]; + if (c == '1') + DemodBuffer[i] = 1; + if (c == '0') + DemodBuffer[i] = 0; + + printf("%c", c); + } + + printf("\n"); + + DemodBufferLen = len; + free(data); + return PM3_SUCCESS; +} + static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, {"lcr", CmdAnalyseLCR, AlwaysAvailable, "Generate final byte for XOR LRC"}, @@ -888,6 +934,7 @@ static command_t CommandTable[] = { {"lfsr", CmdAnalyseLfsr, AlwaysAvailable, "LFSR tests"}, {"a", CmdAnalyseA, AlwaysAvailable, "num bits test"}, {"nuid", CmdAnalyseNuid, AlwaysAvailable, "create NUID from 7byte UID"}, + {"demodbuff", CmdAnalyseDemodBuffer, AlwaysAvailable, "Load binary string to demodbuffer"}, {NULL, NULL, NULL, NULL} }; From f109915ebdbbbbd483fa662691809f07a564c03d Mon Sep 17 00:00:00 2001 From: mwalker33 Date: Fri, 11 Oct 2019 20:29:20 +1100 Subject: [PATCH 0956/1854] T55xx Save and Restore --- client/cmdlft55xx.c | 42 +++++++++++++++++++++++------------------- client/cmdlft55xx.h | 7 +++++-- 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 4cffd059a..7bfadf790 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -52,10 +52,10 @@ t55xx_conf_block_t config = { .Q5 = false, .usepwd = false, .downlink_mode = refFixedBit, - .blockData = {0}, // array to hold data blocks - .blockValid = {0} // array to hold data valid status }; +t55xx_memory_item_t cardmem[T55x7_BLOCK_COUNT] = {0}; + t55xx_conf_block_t Get_t55xx_Config() { return config; } @@ -360,14 +360,14 @@ static int CmdHelp(const char *Cmd); void T55x7_SaveBlockData (uint8_t idx,uint32_t data) { if (idx < T55x7_BLOCK_COUNT) { - config.blockValid[idx] = true; - config.blockData[idx] = data; + cardmem[idx].valid = true; + cardmem[idx].blockdata = data; } } void T55x7_ClearAllBlockData (void) { for (uint8_t idx = 0; idx < T55x7_BLOCK_COUNT; idx++) { - config.blockValid[idx] = false; - config.blockData[idx] = 0x00; + cardmem[idx].valid = false; + cardmem[idx].blockdata = 0x00; } } @@ -2261,8 +2261,8 @@ static int CmdT55xxDump(const char *Cmd) { if (strcmp (preferredName,"") == 0) { // Set default filename, if not set by user strcpy (preferredName,"lf-t55xx"); for (uint8_t i = 1; i <= 7; i++) { - if ((config.blockData[i] != 0x00) && (config.blockData[i] != 0xFFFFFFFF)) - sprintf (preferredName,"%s-%08X",preferredName,config.blockData[i]); + if ((cardmem[i].blockdata != 0x00) && (cardmem[i].blockdata != 0xFFFFFFFF)) + sprintf (preferredName,"%s-%08X",preferredName,cardmem[i].blockdata); else break; } @@ -2273,7 +2273,7 @@ static int CmdT55xxDump(const char *Cmd) { uint32_t data[T55x7_BLOCK_COUNT]; for (int i = 0; i < T55x7_BLOCK_COUNT; i++) - data[i] = BSWAP_32(config.blockData[i]); + data[i] = BSWAP_32(cardmem[i].blockdata); saveFileEML(preferredName, (uint8_t *)data, T55x7_BLOCK_COUNT*sizeof(uint32_t), sizeof(uint32_t)); saveFile (preferredName, ".bin", data, sizeof(data)); @@ -2327,19 +2327,24 @@ static int CmdT55xxRestore(const char *Cmd) { fnLength = strlen (preferredName); - if (fnLength > 4) { // Holds .EXT [.bin|.eml] + success = PM3_ESOFT; + if (fnLength > 4) { // Holds extension [.bin|.eml] memcpy (ext,&preferredName[fnLength - 4],4); ext[5] = 0x00; - + + // check if valid file extension and attempt to load data + if (memcmp (ext,".bin",4) == 0) { preferredName[fnLength-4] = 0x00; success = loadFile (preferredName, ".bin", data, sizeof(data),&datalen); - } - if (memcmp (ext,".eml",4) == 0) { + + } else if (memcmp (ext,".eml",4) == 0) { preferredName[fnLength-4] = 0x00; datalen = 12; success = loadFileEML(preferredName, (uint8_t *)data, &datalen); - } + + } else + PrintAndLogEx(WARNING,"\nWarning: invalid dump filename "_YELLOW_("%s")"to restore!\n",preferredName); } if (success == PM3_SUCCESS) { // Got data, so write to cards @@ -2390,7 +2395,7 @@ static int CmdT55xxRestore(const char *Cmd) { return PM3_SUCCESS; } - +/* static int CmdT55xxRestore(const char *Cmd) { uint32_t password = 0; @@ -2443,7 +2448,7 @@ static int CmdT55xxRestore(const char *Cmd) { return res; } - +*/ bool AcquireData(uint8_t page, uint8_t block, bool pwdmode, uint32_t password, uint8_t downlink_mode) { // arg0 bitmodes: // b0 = pwdmode @@ -3494,7 +3499,6 @@ static int CmdT55xxSetDeviceConfig(const char *Cmd) { downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); if (downlink_mode > 3) downlink_mode = 0; - cmdp += 2; break; case 'p': @@ -3636,13 +3640,13 @@ static command_t CommandTable[] = { {"detect", CmdT55xxDetect, AlwaysAvailable, "[1] Try detecting the tag modulation from reading the configuration block."}, {"deviceconfig", CmdT55xxSetDeviceConfig, IfPm3Lf, "Set/Get T55XX device configuration (startgap, writegap, write0, write1, readgap"}, {"dump", CmdT55xxDump, IfPm3Lf, "[password] [o] Dump T55xx card Page 0 block 0-7. Optional [password], [override]"}, - {"restore", CmdT55xxRestore, IfPm3Lf, "f [p ] -- Restore a dump file of a T55xx card"}, + {"restore", CmdT55xxRestore, IfPm3Lf, "f [p ] Restore T55xx card Page 0 / Page 1 blocks"}, {"info", CmdT55xxInfo, AlwaysAvailable, "[1] Show T55x7 configuration data (page 0/ blk 0)"}, {"p1detect", CmdT55xxDetectPage1, IfPm3Lf, "[1] Try detecting if this is a t55xx tag by reading page 1"}, {"protect", CmdT55xxProtect, IfPm3Lf, "Password protect tag"}, {"read", CmdT55xxReadBlock, IfPm3Lf, "b p [password] [o] [1] -- Read T55xx block data. Optional [p password], [override], [page1]"}, {"resetread", CmdResetRead, IfPm3Lf, "Send Reset Cmd then lf read the stream to attempt to identify the start of it (needs a demod and/or plot after)"}, - {"restore", CmdT55xxRestore, IfPm3Lf, "[password] Restore T55xx card Page 0 / Page 1 blocks"}, +// {"restore", CmdT55xxRestore, IfPm3Lf, "[password] Restore T55xx card Page 0 / Page 1 blocks"}, {"recoverpw", CmdT55xxRecoverPW, IfPm3Lf, "[password] Try to recover from bad password write from a cloner. Only use on PW protected chips!"}, {"special", special, IfPm3Lf, "Show block changes with 64 different offsets"}, {"trace", CmdT55xxReadTrace, AlwaysAvailable, "[1] Show T55x7 traceability data (page 1/ blk 0-1)"}, diff --git a/client/cmdlft55xx.h b/client/cmdlft55xx.h index 59b8dc3f0..7b980c042 100644 --- a/client/cmdlft55xx.h +++ b/client/cmdlft55xx.h @@ -126,10 +126,13 @@ typedef struct { refLeading0 = 0x02, ref1of4 = 0x03, } downlink_mode; - uint32_t blockData [T55x7_BLOCK_COUNT]; // the dump/read will save data here. - bool blockValid [T55x7_BLOCK_COUNT]; // this will allow easy access to the data for display etc. } t55xx_conf_block_t; +typedef struct { + uint32_t blockdata; + bool valid; +} t55xx_memory_item_t ; + t55xx_conf_block_t Get_t55xx_Config(void); void Set_t55xx_Config(t55xx_conf_block_t conf); From 25182d8e2fbb92e3e374773a8f2540a898f65c34 Mon Sep 17 00:00:00 2001 From: mwalker33 Date: Fri, 11 Oct 2019 21:16:28 +1100 Subject: [PATCH 0957/1854] Update cmdlft55xx.c Fix travis initilisation error. --- client/cmdlft55xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 7bfadf790..c2a62dc6e 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -54,7 +54,7 @@ t55xx_conf_block_t config = { .downlink_mode = refFixedBit, }; -t55xx_memory_item_t cardmem[T55x7_BLOCK_COUNT] = {0}; +t55xx_memory_item_t cardmem[T55x7_BLOCK_COUNT] = {{0}}; t55xx_conf_block_t Get_t55xx_Config() { return config; From 71baf71e17caf91e40c67cb9cd0c46b258ce8dc9 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 11 Oct 2019 23:13:52 +0200 Subject: [PATCH 0958/1854] Add 'lf motorola *' commands. Old grey Motorola cards, presumably Flexpass, which operates in 74 kHz, PSK1 , Clock 32. No chance a t55x7 can clone it :), simulation should be doable --- client/Makefile | 2 +- client/cmdlf.c | 58 +++++++++++++++++++++++++++++++------------------ client/cmdlf.h | 4 +++- 3 files changed, 41 insertions(+), 23 deletions(-) diff --git a/client/Makefile b/client/Makefile index 95a258a78..58bdf7592 100644 --- a/client/Makefile +++ b/client/Makefile @@ -227,7 +227,7 @@ CMDSRCS = crapto1/crapto1.c \ cmdlfti.c \ cmdlfviking.c \ cmdlfvisa2000.c \ - cmdlfverichip.c \ + cmdlfmotorola.c \ cmdtrace.c \ cmdflashmem.c \ cmdflashmemspiffs.c \ diff --git a/client/cmdlf.c b/client/cmdlf.c index adc5bc9b5..e2f2a2153 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -1,5 +1,9 @@ //----------------------------------------------------------------------------- // Copyright (C) 2010 iZsh +// Modified by +// Marshellow +// Iceman +// Doegox // // This code is licensed to you under the terms of the GNU GPL, version 2 or, // at your option, any later version. See the LICENSE.txt file for the text of @@ -47,7 +51,7 @@ #include "cmdlfsecurakey.h" // for securakey menu #include "cmdlfpac.h" // for pac menu #include "cmdlfkeri.h" // for keri menu -#include "cmdlfverichip.h" // for VeriChip menu +#include "cmdlfmotorola.h" // for Motorola menu #include "cmdlfgallagher.h" // for GALLAGHER menu bool g_lf_threshold_set = false; @@ -449,6 +453,14 @@ int CmdFlexdemod(const char *Cmd) { return PM3_SUCCESS; } +int lf_config(sample_config *config) { + if (!session.pm3_present) return PM3_ENOTTY; + + clearCommandBuffer(); + SendCommandNG(CMD_LF_SAMPLING_SET_CONFIG, (uint8_t *)config, sizeof(sample_config)); + return PM3_SUCCESS; +} + int CmdLFConfig(const char *Cmd) { if (!session.pm3_present) return PM3_ENOTTY; @@ -525,22 +537,19 @@ int CmdLFConfig(const char *Cmd) { } } - //Validations + // validations if (errors) return usage_lf_config(); - if (cmdp == 0) { - clearCommandBuffer(); - SendCommandNG(CMD_LF_SAMPLING_GET_CONFIG, NULL, 0); - return PM3_SUCCESS; - } - //Bps is limited to 8 + // print current settings. + if (cmdp == 0) + return lf_config(NULL); + + // bps is limited to 8 if (bps >> 4) bps = 8; - sample_config config = { decimation, bps, averaging, divisor, trigger_threshold, samples_to_skip }; + sample_config config = { decimation, bps, averaging, divisor, trigger_threshold, samples_to_skip, true }; - clearCommandBuffer(); - SendCommandNG(CMD_LF_SAMPLING_SET_CONFIG, (uint8_t *)&config, sizeof(sample_config)); - return PM3_SUCCESS; + return lf_config(&config); } int lf_read(bool silent, uint32_t samples) { @@ -632,6 +641,7 @@ static void ChkBitstream() { } } } + //Attempt to simulate any wave in buffer (one bit per output sample) // converts GraphBuffer to bitstream (based on zero crossings) if needed. int CmdLFSim(const char *Cmd) { @@ -711,7 +721,7 @@ int CmdLFSim(const char *Cmd) { return PM3_SUCCESS; } -// by marshmellow - sim fsk data given clock, fcHigh, fcLow, invert +// sim fsk data given clock, fcHigh, fcLow, invert // - allow pull data from DemodBuffer int CmdLFfskSim(const char *Cmd) { //might be able to autodetect FCs and clock from Graphbuffer if using demod buffer @@ -815,7 +825,7 @@ int CmdLFfskSim(const char *Cmd) { return PM3_SUCCESS; } -// by marshmellow - sim ask data given clock, invert, manchester or raw, separator +// sim ask data given clock, invert, manchester or raw, separator // - allow pull data from DemodBuffer int CmdLFaskSim(const char *Cmd) { // autodetect clock from Graphbuffer if using demod buffer @@ -916,7 +926,7 @@ int CmdLFaskSim(const char *Cmd) { return PM3_SUCCESS; } -// by marshmellow - sim psk data given carrier, clock, invert +// sim psk data given carrier, clock, invert // - allow pull data from DemodBuffer or parameters int CmdLFpskSim(const char *Cmd) { //might be able to autodetect FC and clock from Graphbuffer if using demod buffer @@ -1126,7 +1136,6 @@ int CmdVchDemod(const char *Cmd) { return PM3_SUCCESS; } -//by marshmellow static bool CheckChipType(bool getDeviceData) { bool retval = false; @@ -1158,7 +1167,6 @@ out: return retval; } -//by marshmellow int CmdLFfind(const char *Cmd) { int ans = 0; size_t minLength = 2000; @@ -1193,9 +1201,18 @@ int CmdLFfind(const char *Cmd) { if (getSignalProperties()->isnoise) { if (IfPm3Hitag()) { - if (readHitagUid()) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Hitag") "found!"); return PM3_SUCCESS;} + if (readHitagUid()) { + PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Hitag") "found!"); return PM3_SUCCESS; + } + } + + if (readMotorolaUid()) { + PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Motorola ID") "found!"); return PM3_SUCCESS; + } + + if (readCOTAGUid()) { + PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("COTAG ID") "found!"); return PM3_SUCCESS; } - if (readCOTAGUid()) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("COTAG ID") "found!"); return PM3_SUCCESS;} PrintAndLogEx(FAILED, _RED_("No data found!")); PrintAndLogEx(INFO, "Signal looks like noise. Maybe not an LF tag?"); @@ -1229,7 +1246,6 @@ int CmdLFfind(const char *Cmd) { if (demodVisa2k() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Visa2000 ID") "found!"); goto out;} if (demodGallagher() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("GALLAGHER ID") "found!"); goto out;} // if (demodTI() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Texas Instrument ID") "found!"); goto out;} -// if (demodVerichip() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("VeriChip ID") "found!"); goto out;} //if (demodFermax() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Fermax ID") "found!"); goto out;} //if (demodFlex() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Motorola FlexPass ID") "found!"); goto out;} @@ -1297,6 +1313,7 @@ static command_t CommandTable[] = { {"nedap", CmdLFNedap, AlwaysAvailable, "{ Nedap RFIDs... }"}, {"nexwatch", CmdLFNEXWATCH, AlwaysAvailable, "{ NexWatch RFIDs... }"}, {"noralsy", CmdLFNoralsy, AlwaysAvailable, "{ Noralsy RFIDs... }"}, + {"motorola", CmdLFMotorola, AlwaysAvailable, "{ Motorola RFIDs... }"}, {"pac", CmdLFPac, AlwaysAvailable, "{ PAC/Stanley RFIDs... }"}, {"paradox", CmdLFParadox, AlwaysAvailable, "{ Paradox RFIDs... }"}, {"pcf7931", CmdLFPCF7931, AlwaysAvailable, "{ PCF7931 CHIPs... }"}, @@ -1305,7 +1322,6 @@ static command_t CommandTable[] = { {"securakey", CmdLFSecurakey, AlwaysAvailable, "{ Securakey RFIDs... }"}, {"ti", CmdLFTI, AlwaysAvailable, "{ TI CHIPs... }"}, {"t55xx", CmdLFT55XX, AlwaysAvailable, "{ T55xx CHIPs... }"}, -// {"verichip", CmdLFVerichip, AlwaysAvailable, "{ VeriChip RFIDs... }"}, {"viking", CmdLFViking, AlwaysAvailable, "{ Viking RFIDs... }"}, {"visa2000", CmdLFVisa2k, AlwaysAvailable, "{ Visa2000 RFIDs... }"}, {"", CmdHelp, AlwaysAvailable, ""}, diff --git a/client/cmdlf.h b/client/cmdlf.h index 8c90d2d42..3f0670d1f 100644 --- a/client/cmdlf.h +++ b/client/cmdlf.h @@ -12,12 +12,13 @@ #define CMDLF_H__ #include "common.h" +#include "pm3_cmd.h" // sample_config_t #define T55XX_WRITE_TIMEOUT 1500 int CmdLF(const char *Cmd); -int CmdLFSetConfig(const char *Cmd); +int CmdLFConfig(const char *Cmd); int CmdLFCommandRead(const char *Cmd); int CmdFlexdemod(const char *Cmd); @@ -32,5 +33,6 @@ int CmdVchDemod(const char *Cmd); int CmdLFfind(const char *Cmd); int lf_read(bool silent, uint32_t samples); +int lf_config(sample_config *config); #endif From 354c5f2ea81e6a4dde47fd4c0c74c62fb9875ff6 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 11 Oct 2019 23:13:58 +0200 Subject: [PATCH 0959/1854] q --- client/cmdlfmotorola.c | 136 +++++++++++++++++++++++++++++++++++++++++ client/cmdlfmotorola.h | 21 +++++++ 2 files changed, 157 insertions(+) create mode 100644 client/cmdlfmotorola.c create mode 100644 client/cmdlfmotorola.h diff --git a/client/cmdlfmotorola.c b/client/cmdlfmotorola.c new file mode 100644 index 000000000..32410b8d7 --- /dev/null +++ b/client/cmdlfmotorola.c @@ -0,0 +1,136 @@ +//----------------------------------------------------------------------------- +// Iceman, 2019 +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// Low frequency Motorola tag commands +// PSK1, RF/32, 64 bits long, at 74 kHz +//----------------------------------------------------------------------------- +#include "cmdlfmotorola.h" + +#include //tolower + +#include "commonutil.h" // ARRAYLEN +#include "common.h" +#include "cmdparser.h" // command_t +#include "comms.h" +#include "ui.h" +#include "cmddata.h" +#include "cmdlf.h" +#include "lfdemod.h" // preamble test +#include "protocols.h" // t55xx defines +#include "cmdlft55xx.h" // clone.. +#include "cmdlf.h" // cmdlfconfig + +static int CmdHelp(const char *Cmd); + +//see PSKDemod for what args are accepted +static int CmdMotorolaDemod(const char *Cmd) { + + //PSK1 + if (PSKDemod("32 1", true) != PM3_SUCCESS) { + PrintAndLogEx(DEBUG, "DEBUG: Error - Motorola: PSK Demod failed"); + return PM3_ESOFT; + } + size_t size = DemodBufferLen; + int ans = detectMotorola(DemodBuffer, &size); + if (ans < 0) { + if (ans == -1) + PrintAndLogEx(DEBUG, "DEBUG: Error - Motorola: too few bits found"); + else if (ans == -2) + PrintAndLogEx(DEBUG, "DEBUG: Error - Motorola: preamble not found"); + else if (ans == -3) + PrintAndLogEx(DEBUG, "DEBUG: Error - Motorola: Size not correct: %zu", size); + else + PrintAndLogEx(DEBUG, "DEBUG: Error - Motorola: ans: %d", ans); + + return PM3_ESOFT; + } + setDemodBuff(DemodBuffer, 64, ans); + setClockGrid(g_DemodClock, g_DemodStartIdx + (ans * g_DemodClock)); + + //got a good demod + uint32_t raw1 = bytebits_to_byte(DemodBuffer, 32); + uint32_t raw2 = bytebits_to_byte(DemodBuffer + 32, 32); + + PrintAndLogEx(SUCCESS, "Motorola Tag Found -- Raw: %08X%08X", raw1, raw2); + PrintAndLogEx(INFO, "How the Raw ID is translated by the reader is unknown. Share your trace file on forum"); + return PM3_SUCCESS; +} + +static int CmdMotorolaRead(const char *Cmd) { + // Motorola Flexpass seem to work at 74 kHz + // and take about 4400 samples to befor modulating + sample_config sc = { + .decimation = 0, + .bits_per_sample = 0, + .averaging= false, + .divisor = LF_DIVISOR(74), + .trigger_threshold = -1, + .samples_to_skip = 4500, + .verbose = false + }; + lf_config(&sc); + + // 64 * 32 * 2 * n-ish + lf_read(true, 5000); + + // reset back to 125 kHz + sc.divisor = LF_DIVISOR_125; + sc.samples_to_skip = 0; + lf_config(&sc); + return CmdMotorolaDemod(Cmd); +} + +static int CmdMotorolaSim(const char *Cmd) { + + // PSK sim. + PrintAndLogEx(INFO, " PSK1 at 66 kHz... Interesting."); + PrintAndLogEx(INFO, " To be implemented, feel free to contribute!"); + return PM3_SUCCESS; +} + +static command_t CommandTable[] = { + {"help", CmdHelp, AlwaysAvailable, "This help"}, + {"demod", CmdMotorolaDemod, AlwaysAvailable, "Demodulate an MOTOROLA tag from the GraphBuffer"}, + {"read", CmdMotorolaRead, IfPm3Lf, "Attempt to read and extract tag data from the antenna"}, + {"sim", CmdMotorolaSim, IfPm3Lf, "simulate MOTOROLA tag"}, + {NULL, NULL, NULL, NULL} +}; + +static int CmdHelp(const char *Cmd) { + (void)Cmd; // Cmd is not used so far + CmdsHelp(CommandTable); + return PM3_SUCCESS; +} + +int CmdLFMotorola(const char *Cmd) { + clearCommandBuffer(); + return CmdsParse(CommandTable, Cmd); +} + +// find MOTOROLA preamble in already demoded data +int detectMotorola(uint8_t *dest, size_t *size) { + if (*size < 64) return -1; //make sure buffer has data + size_t startIdx = 0; + uint8_t preamble[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1 + }; + if (!preambleSearch(dest, preamble, sizeof(preamble), size, &startIdx)) + return -2; //preamble not found + if (*size != 64) return -3; //wrong demoded size + //return start position + return (int)startIdx; +} + +int demodMotorola(void) { + return CmdMotorolaDemod(""); +} + +int readMotorolaUid(void) { + return ( CmdMotorolaRead("") == PM3_SUCCESS); +} diff --git a/client/cmdlfmotorola.h b/client/cmdlfmotorola.h new file mode 100644 index 000000000..682193ebc --- /dev/null +++ b/client/cmdlfmotorola.h @@ -0,0 +1,21 @@ +//----------------------------------------------------------------------------- +// Iceman, 2019 +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// Low frequency MOTOROLA tag commands +//----------------------------------------------------------------------------- +#ifndef CMDLFMOTOROLA_H__ +#define CMDLFMOTOROLA_H__ + +#include "common.h" + +int CmdLFMotorola(const char *Cmd); + +int demodMotorola(void); +int detectMotorola(uint8_t *dest, size_t *size); +int readMotorolaUid(void); +#endif + From 76f77638937f5076b6263190acfee545af963ed0 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 11 Oct 2019 23:14:57 +0200 Subject: [PATCH 0960/1854] motorola --- armsrc/lfsampling.c | 7 +++++-- include/pm3_cmd.h | 2 ++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index e8d507b29..08fb1dd94 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -23,8 +23,10 @@ Default LF config is set to: averaging = YES divisor = 95 (125kHz) trigger_threshold = 0 + samples_to_skip = 0 + verbose = YES */ -sample_config config = { 1, 8, 1, LF_DIVISOR_125, 0, 0 } ; +sample_config config = { 1, 8, 1, LF_DIVISOR_125, 0, 0, 1} ; void printConfig() { uint32_t d = config.divisor; @@ -59,7 +61,8 @@ void setSamplingConfig(sample_config *sc) { config.averaging = sc->averaging; if (config.bits_per_sample > 8) config.bits_per_sample = 8; - printConfig(); + if (sc->verbose) + printConfig(); } sample_config *getSamplingConfig() { diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index a6d59aa05..c92a1faee 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -119,6 +119,7 @@ typedef struct { int divisor; int trigger_threshold; uint32_t samples_to_skip; + bool verbose; } PACKED sample_config; /* typedef struct { @@ -488,6 +489,7 @@ typedef struct { #define CMD_HF_MIFARE_CHKKEYS_FAST 0x0625 #define CMD_HF_MIFARE_SNIFF 0x0630 +#define CMD_HF_MIFARE_MFKEY 0x0631 //ultralightC #define CMD_HF_MIFAREUC_AUTH 0x0724 //0x0725 and 0x0726 no longer used From 44b25cc6ac3d6a9f283b7b0bd040c076e7cf4014 Mon Sep 17 00:00:00 2001 From: mwalker33 Date: Sat, 12 Oct 2019 17:55:23 +1100 Subject: [PATCH 0961/1854] Update cmdlft55xx.c removed extra comma. --- client/cmdlft55xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index c2a62dc6e..2894faa46 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -51,7 +51,7 @@ t55xx_conf_block_t config = { .block0 = 0x00, .Q5 = false, .usepwd = false, - .downlink_mode = refFixedBit, + .downlink_mode = refFixedBit }; t55xx_memory_item_t cardmem[T55x7_BLOCK_COUNT] = {{0}}; From b745602d8c9c87d10f3445a4de21e05f096839e0 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 12 Oct 2019 12:36:09 +0200 Subject: [PATCH 0962/1854] Motorola. FC guessing. CSN mapped straight from Indala descramble. --- client/cmdlfindala.c | 2 - client/cmdlfmotorola.c | 148 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 135 insertions(+), 15 deletions(-) diff --git a/client/cmdlfindala.c b/client/cmdlfindala.c index c93d695aa..f455fae66 100644 --- a/client/cmdlfindala.c +++ b/client/cmdlfindala.c @@ -647,8 +647,6 @@ out: *size = found_size; - //PrintAndLogEx(INFO, "DEBUG: detectindala RES = %d | %d | %d", res, found_size, idx); - if (found_size != 224 && found_size != 64) { PrintAndLogEx(INFO, "DEBUG: detectindala | %zu", found_size); return -5; diff --git a/client/cmdlfmotorola.c b/client/cmdlfmotorola.c index 32410b8d7..035eb7dc1 100644 --- a/client/cmdlfmotorola.c +++ b/client/cmdlfmotorola.c @@ -23,6 +23,8 @@ #include "protocols.h" // t55xx defines #include "cmdlft55xx.h" // clone.. #include "cmdlf.h" // cmdlfconfig +#include "cliparser/cliparser.h" // cli parse input + static int CmdHelp(const char *Cmd); @@ -54,9 +56,67 @@ static int CmdMotorolaDemod(const char *Cmd) { //got a good demod uint32_t raw1 = bytebits_to_byte(DemodBuffer, 32); uint32_t raw2 = bytebits_to_byte(DemodBuffer + 32, 32); + +// A0000000E308C0C1 +// 10100000000000000000000000000000 1110 0011 0000 1000 1100 0000 1100 0001 + + +// 1 1 2 2 2 3 3 4 4 4 5 5 6 +// 0 4 8 2 6 0 4 8 2 6 0 4 8 2 6 0 +// 1010 0000 0000 0000 0000 0000 0000 0000 1110 0011 0000 1000 1100 0000 0101 0010 +// 9 .0 5 4 26 3 . 71 +// . .0 5 4 26 3 . 71 +// 6 9 A5 C0FD E7 18 B 4 3 2 + +// hex(234) 0xEA bin(234) 1110 1010 +// hex(437) 0x1B5 bin(437) 1 1011 0101 +// hex(229) 0xE5 bin(229) 1110 0101 + + uint16_t fc = 0; + +// FC seems to be guess work. Need more samples +// guessing printed FC is 4 digits. 1024? 10bit? +// fc |= DemodBuffer[38] << 9; // b10 + fc |= DemodBuffer[34] << 8; // b9 + + fc |= DemodBuffer[44] << 7; // b8 + fc |= DemodBuffer[47] << 6; // b7 + fc |= DemodBuffer[57] << 5; // b6 + fc |= DemodBuffer[49] << 4; // b5 + +// seems to match + fc |= DemodBuffer[53] << 3; // b4 + fc |= DemodBuffer[48] << 2; // b3 + fc |= DemodBuffer[58] << 1; // b2 + fc |= DemodBuffer[39] << 0; // b1 + +// CSN was same as Indala CSN descramble. + uint16_t csn = 0; + csn |= DemodBuffer[42] << 15; // b16 + csn |= DemodBuffer[45] << 14; // b15 + csn |= DemodBuffer[43] << 13; // b14 + csn |= DemodBuffer[40] << 12; // b13 + csn |= DemodBuffer[52] << 11; // b12 + csn |= DemodBuffer[36] << 10; // b11 + csn |= DemodBuffer[35] << 9; // b10 + csn |= DemodBuffer[51] << 8; // b9 + csn |= DemodBuffer[46] << 7; // b8 + csn |= DemodBuffer[33] << 6; // b7 + csn |= DemodBuffer[37] << 5; // b6 + csn |= DemodBuffer[54] << 4; // b5 + csn |= DemodBuffer[56] << 3; // b4 + csn |= DemodBuffer[59] << 2; // b3 + csn |= DemodBuffer[50] << 1; // b2 + csn |= DemodBuffer[41] << 0; // b1 + + uint8_t checksum = 0; + checksum |= DemodBuffer[62] << 1; // b2 + checksum |= DemodBuffer[63] << 0; // b1 PrintAndLogEx(SUCCESS, "Motorola Tag Found -- Raw: %08X%08X", raw1, raw2); - PrintAndLogEx(INFO, "How the Raw ID is translated by the reader is unknown. Share your trace file on forum"); + PrintAndLogEx(SUCCESS, "Fmt 26 bit FC %u , CSN %u , checksum %1d%1d", fc, csn, checksum >> 1 & 0x01, checksum & 0x01 ); + PrintAndLogEx(NORMAL, ""); + return PM3_SUCCESS; } @@ -84,6 +144,42 @@ static int CmdMotorolaRead(const char *Cmd) { return CmdMotorolaDemod(Cmd); } +static int CmdMotorolaClone(const char *Cmd) { + + uint32_t blocks[3] = {0}; + uint8_t data[8]; + int datalen = 0; + + CLIParserInit("lf indala clone", + "Enables cloning of Motorola card with specified uid onto T55x7\n" + "defaults to 64.\n", + "\n" + "Samples:\n" + "\tlf motorola clone a0000000a0002021\n" + ); + + void *argtable[] = { + arg_param_begin, + arg_strx1(NULL, NULL, "", NULL), + arg_param_end + }; + CLIExecWithReturn(Cmd, argtable, false); + CLIGetHexWithReturn(1, data, &datalen); + CLIParserFree(); + + //TODO add selection of chip for Q5 or T55x7 + // data[0] = T5555_SET_BITRATE(32 | T5555_MODULATION_PSK1 | 2 << T5555_MAXBLOCK_SHIFT; + + // config for Motorola 64 format (RF/32;PSK1 with RF/2; Maxblock=2) + PrintAndLogEx(INFO, "Preparing to clone Motorola 64bit tag with RawID %s", sprint_hex(data, datalen)); + blocks[0] = T55x7_BITRATE_RF_32 | T55x7_MODULATION_PSK1 | (2 << T55x7_MAXBLOCK_SHIFT); + blocks[1] = bytes_to_num(data, 4); + blocks[2] = bytes_to_num(data + 4, 4); + + print_blocks(blocks, ARRAYLEN(blocks)); + return clone_t55xx_tag(blocks, ARRAYLEN(blocks)); +} + static int CmdMotorolaSim(const char *Cmd) { // PSK sim. @@ -96,6 +192,7 @@ static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, {"demod", CmdMotorolaDemod, AlwaysAvailable, "Demodulate an MOTOROLA tag from the GraphBuffer"}, {"read", CmdMotorolaRead, IfPm3Lf, "Attempt to read and extract tag data from the antenna"}, + {"clone", CmdMotorolaClone, IfPm3Lf, "clone MOTOROLA to T55x7"}, {"sim", CmdMotorolaSim, IfPm3Lf, "simulate MOTOROLA tag"}, {NULL, NULL, NULL, NULL} }; @@ -113,18 +210,43 @@ int CmdLFMotorola(const char *Cmd) { // find MOTOROLA preamble in already demoded data int detectMotorola(uint8_t *dest, size_t *size) { - if (*size < 64) return -1; //make sure buffer has data - size_t startIdx = 0; - uint8_t preamble[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1 - }; - if (!preambleSearch(dest, preamble, sizeof(preamble), size, &startIdx)) - return -2; //preamble not found - if (*size != 64) return -3; //wrong demoded size - //return start position - return (int)startIdx; + + //make sure buffer has data + if (*size < 64) + return -1; + + bool inverted = false; + size_t found_size = *size; + size_t start_idx = 0; + + // Seems Motorola is based on the following indala format. + // standard 64 bit Motorola formats including 26 bit 40134 format + uint8_t preamble[] = {1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}; + uint8_t preamble_i[] = {0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}; + + // preamble not found + if (!preambleSearch(dest, preamble, sizeof(preamble), &found_size, &start_idx)) { + found_size = *size; + if (!preambleSearch(dest, preamble_i, sizeof(preamble_i), &found_size, &start_idx)) { + return -2; + } + PrintAndLogEx(DEBUG, "DEBUG: detectMotorola PSK1 found inverted preamble"); + inverted = true; + } + + *size = found_size; + + // wrong demoded size + if (*size != 64) + return -3; + + if (inverted && start_idx > 0) { + for(size_t i= start_idx -1 ; i < *size + start_idx + 2; i++) { + dest[i] ^= 1; + } + } + + return (int)start_idx; } int demodMotorola(void) { From 36e4dfc1afe4aa008835dc05680f35567e616f79 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 12 Oct 2019 12:37:44 +0200 Subject: [PATCH 0963/1854] added a Motorola trace. --- traces/motorola_0437_00072.pm3 | 39999 +++++++++++++++++++++++++++++++ 1 file changed, 39999 insertions(+) create mode 100644 traces/motorola_0437_00072.pm3 diff --git a/traces/motorola_0437_00072.pm3 b/traces/motorola_0437_00072.pm3 new file mode 100644 index 000000000..48e91d46e --- /dev/null +++ b/traces/motorola_0437_00072.pm3 @@ -0,0 +1,39999 @@ +10 +-10 +10 +-9 +11 +-12 +13 +-10 +10 +-9 +10 +-10 +11 +-9 +10 +-10 +12 +-11 +10 +-11 +11 +-11 +11 +-11 +10 +-10 +10 +-10 +9 +-10 +10 +-10 +10 +-12 +15 +9 +-16 +10 +-10 +9 +-10 +11 +-12 +10 +-10 +12 +-12 +9 +-11 +10 +-11 +9 +-12 +11 +-10 +10 +-10 +9 +-11 +10 +-11 +11 +-11 +9 +-9 +9 +-11 +9 +-10 +10 +-9 +9 +-9 +12 +-9 +10 +-9 +11 +-8 +10 +-8 +9 +-9 +12 +-8 +11 +-9 +10 +-9 +11 +-9 +11 +-10 +11 +-10 +7 +-9 +9 +-11 +-9 +13 +-7 +12 +-8 +9 +-10 +10 +-8 +11 +-9 +10 +-10 +10 +-9 +11 +-10 +11 +-10 +10 +-9 +11 +-10 +11 +-9 +11 +-9 +11 +-9 +11 +-10 +10 +-9 +10 +-9 +10 +-10 +10 +-9 +11 +-10 +11 +-11 +11 +-10 +11 +-9 +10 +-11 +10 +-10 +10 +-9 +9 +-11 +9 +-11 +10 +-10 +10 +-10 +10 +-10 +11 +-11 +10 +-9 +10 +-11 +11 +-10 +11 +-10 +12 +-10 +11 +-10 +11 +-10 +11 +-10 +10 +-11 +11 +-10 +11 +-11 +11 +-8 +12 +-9 +10 +-9 +10 +-10 +12 +-10 +10 +-10 +12 +-12 +11 +-11 +12 +-9 +9 +-11 +10 +-9 +10 +-10 +11 +-9 +12 +-9 +11 +-10 +13 +-11 +11 +-9 +9 +-10 +10 +-11 +9 +-11 +9 +-10 +8 +-11 +11 +-9 +9 +-11 +11 +-10 +10 +-9 +10 +-10 +12 +-10 +11 +-10 +11 +-10 +10 +-10 +10 +-10 +9 +-10 +11 +-10 +11 +-10 +10 +-9 +10 +-11 +10 +-9 +9 +-10 +10 +-10 +13 +-11 +10 +-10 +10 +-10 +11 +-10 +10 +-9 +11 +-10 +11 +-8 +10 +-9 +11 +-9 +12 +-10 +11 +-11 +11 +-11 +13 +9 +-16 +11 +-10 +6 +-11 +9 +-12 +9 +-10 +9 +-10 +10 +-9 +9 +-10 +10 +-10 +9 +-9 +10 +-9 +11 +-9 +11 +-9 +10 +-11 +9 +-10 +9 +-9 +10 +-10 +11 +-9 +11 +-10 +9 +-10 +9 +-9 +10 +-9 +9 +-10 +10 +-9 +9 +-9 +10 +-9 +11 +-9 +10 +-10 +10 +-9 +9 +-10 +11 +-9 +10 +-12 +-8 +16 +-6 +10 +-9 +11 +-9 +13 +-10 +10 +-10 +12 +-11 +14 +-8 +12 +-8 +12 +-8 +12 +-9 +11 +-9 +11 +-10 +11 +-10 +11 +-10 +10 +-10 +10 +-10 +10 +-10 +9 +-10 +10 +-11 +11 +-10 +10 +-9 +11 +-9 +12 +-9 +11 +-10 +12 +-9 +10 +-10 +10 +-10 +11 +-10 +11 +-10 +11 +-10 +12 +-10 +10 +-10 +10 +-11 +9 +-11 +10 +-10 +9 +-10 +11 +-9 +8 +-12 +11 +-9 +11 +-10 +9 +-10 +11 +-10 +11 +-9 +8 +-10 +11 +-11 +10 +-10 +9 +-11 +12 +-10 +11 +-8 +9 +-10 +13 +-9 +11 +-9 +11 +-9 +11 +-10 +10 +-11 +10 +-11 +11 +-10 +10 +-12 +10 +-11 +9 +-11 +10 +-10 +9 +-10 +8 +-11 +11 +-10 +9 +-10 +10 +-11 +11 +-10 +12 +-8 +11 +-9 +11 +-9 +11 +-10 +11 +-10 +10 +-10 +11 +-10 +10 +-10 +9 +-10 +9 +-11 +10 +-11 +8 +-10 +13 +9 +-16 +10 +-12 +10 +-11 +10 +-10 +11 +-10 +11 +-10 +9 +-9 +10 +-10 +9 +-11 +9 +-11 +10 +-9 +9 +-10 +9 +-10 +10 +-8 +10 +-9 +10 +-10 +9 +-8 +8 +-9 +10 +-9 +12 +-11 +11 +-9 +10 +-8 +12 +-11 +12 +-11 +8 +-8 +8 +-9 +9 +-8 +9 +-9 +11 +-9 +9 +-11 +9 +-9 +9 +-12 +-8 +13 +-8 +11 +-9 +9 +-10 +10 +-10 +10 +-10 +10 +-10 +12 +-10 +12 +-9 +11 +-9 +11 +-9 +10 +-10 +12 +-9 +10 +-9 +10 +-10 +10 +-10 +14 +10 +-16 +11 +-11 +11 +-11 +9 +-11 +11 +-10 +10 +-9 +10 +-11 +9 +-11 +10 +-12 +9 +-11 +8 +-9 +9 +-11 +10 +-9 +11 +-9 +9 +-10 +11 +-12 +-8 +13 +-8 +12 +-9 +12 +-9 +12 +-10 +11 +-9 +10 +-8 +11 +-10 +13 +-8 +11 +-9 +11 +-9 +10 +-9 +11 +-10 +10 +-10 +10 +-11 +10 +-10 +11 +-11 +11 +-10 +9 +-10 +9 +-11 +10 +-11 +10 +-10 +11 +-10 +9 +-9 +10 +-9 +11 +-10 +12 +-11 +12 +-11 +9 +-9 +12 +-11 +10 +-9 +11 +-10 +11 +-9 +11 +-9 +11 +-11 +10 +-8 +11 +-11 +12 +-9 +9 +-10 +10 +-10 +11 +-9 +11 +-9 +12 +-9 +10 +-10 +11 +-11 +10 +-11 +10 +-10 +9 +-10 +10 +-11 +11 +-10 +10 +-11 +11 +-9 +11 +-11 +11 +-11 +11 +-11 +11 +-10 +10 +-10 +11 +-10 +10 +-8 +9 +-9 +11 +-11 +10 +-11 +11 +-10 +10 +-10 +10 +-10 +11 +-10 +10 +-10 +11 +-10 +12 +-10 +10 +-9 +11 +-11 +13 +-9 +10 +-9 +10 +-9 +10 +-10 +11 +-10 +10 +-10 +11 +-11 +10 +-10 +11 +-10 +11 +-10 +12 +-10 +10 +-9 +11 +-9 +9 +-9 +11 +-10 +11 +-10 +11 +-10 +11 +-10 +11 +-10 +10 +-9 +9 +-10 +9 +-10 +9 +-10 +12 +-11 +11 +-9 +10 +-9 +11 +-10 +10 +-9 +10 +-11 +10 +-12 +10 +-10 +9 +-11 +10 +-11 +11 +-12 +10 +-11 +11 +-9 +10 +-9 +10 +-9 +11 +-10 +11 +-11 +11 +-12 +10 +-9 +9 +-9 +11 +-9 +9 +-9 +11 +-9 +13 +-10 +8 +-11 +10 +-8 +11 +-10 +10 +-10 +11 +-9 +10 +-9 +10 +-11 +11 +-11 +11 +-10 +10 +-10 +10 +-10 +10 +-11 +10 +-11 +9 +-10 +9 +-11 +11 +-10 +10 +-10 +10 +-10 +10 +-11 +9 +-10 +10 +-12 +11 +-9 +8 +-11 +10 +-10 +11 +-11 +10 +-11 +10 +-11 +11 +-9 +10 +-8 +9 +-9 +12 +-10 +11 +-10 +11 +-10 +13 +-10 +11 +-10 +10 +-11 +13 +-10 +9 +-9 +10 +-11 +13 +-9 +10 +-10 +11 +-10 +11 +-11 +11 +-10 +11 +-10 +10 +-11 +11 +-10 +11 +-12 +11 +-10 +10 +-11 +9 +-11 +10 +-11 +11 +-11 +10 +-10 +11 +-11 +11 +-10 +11 +-9 +11 +-10 +11 +-9 +12 +-10 +10 +-10 +10 +-9 +10 +-10 +13 +-9 +10 +-10 +10 +-11 +10 +-11 +11 +-10 +9 +-11 +10 +-11 +9 +-11 +9 +-10 +10 +-10 +11 +-11 +10 +-9 +10 +-12 +11 +-10 +11 +-9 +10 +-8 +11 +-10 +10 +-11 +11 +-10 +11 +-10 +11 +-11 +11 +-11 +11 +-9 +10 +-10 +11 +-10 +10 +-9 +11 +-10 +11 +-10 +11 +-10 +10 +-11 +9 +-11 +9 +-10 +9 +-10 +11 +-9 +10 +-11 +10 +-10 +9 +-9 +9 +-10 +10 +-11 +11 +-10 +12 +-9 +11 +-9 +10 +-8 +10 +-9 +11 +-10 +11 +-10 +11 +-9 +11 +-9 +8 +-11 +11 +-9 +10 +-9 +9 +-12 +11 +-10 +9 +-10 +12 +-9 +9 +-9 +10 +-10 +11 +-10 +10 +-10 +10 +-10 +11 +-8 +10 +-10 +11 +-10 +11 +-9 +11 +-10 +11 +-10 +11 +-11 +9 +-10 +12 +-10 +9 +-11 +11 +-10 +10 +-11 +11 +-10 +9 +-11 +12 +-9 +10 +-11 +11 +-9 +10 +-9 +11 +-10 +11 +-11 +11 +-9 +12 +-10 +10 +-9 +10 +-9 +10 +-10 +11 +-12 +9 +-11 +12 +-10 +12 +-9 +12 +-9 +10 +-9 +11 +-9 +10 +-9 +12 +-11 +9 +-10 +9 +-10 +9 +-10 +11 +-9 +10 +-10 +10 +-10 +10 +-9 +10 +-10 +11 +-11 +11 +-9 +10 +-9 +9 +-12 +13 +-9 +11 +-9 +11 +-10 +12 +-9 +10 +-11 +10 +-10 +11 +-11 +10 +-10 +9 +-11 +9 +-11 +9 +-11 +11 +-10 +11 +-11 +10 +-10 +10 +-9 +10 +-11 +10 +-11 +10 +-11 +10 +-10 +11 +-9 +11 +-9 +9 +-10 +11 +-11 +10 +-10 +11 +-10 +10 +-11 +11 +-9 +10 +-10 +11 +-10 +10 +-10 +9 +-11 +10 +-9 +9 +-10 +10 +-10 +12 +-8 +9 +-9 +12 +-10 +11 +-9 +11 +-11 +11 +-9 +10 +-11 +11 +-11 +11 +-10 +11 +-9 +10 +-11 +11 +-8 +11 +-9 +11 +-10 +11 +-10 +10 +-10 +11 +-10 +10 +-11 +10 +-11 +11 +-11 +9 +-11 +11 +-10 +11 +-10 +10 +-10 +11 +-9 +10 +-8 +11 +-11 +10 +-9 +11 +-9 +10 +-9 +11 +-10 +10 +-9 +12 +-10 +12 +-9 +10 +-10 +12 +-9 +10 +-8 +10 +-11 +11 +-11 +10 +-11 +10 +-10 +9 +-11 +9 +-11 +10 +-11 +11 +-11 +11 +-10 +11 +-10 +9 +-9 +10 +-10 +10 +-10 +12 +-10 +11 +-10 +10 +-9 +9 +-12 +11 +-11 +10 +-10 +9 +-10 +9 +-11 +11 +-10 +9 +-10 +11 +-10 +12 +-9 +11 +-9 +11 +-9 +11 +-9 +11 +-8 +12 +-11 +12 +-9 +11 +-10 +10 +-10 +11 +-10 +10 +-10 +10 +-10 +10 +-11 +11 +-9 +9 +-9 +10 +-11 +11 +-10 +9 +-10 +10 +-11 +10 +-10 +8 +-10 +9 +-10 +10 +-11 +11 +-11 +11 +-10 +10 +-10 +10 +-11 +10 +-11 +10 +-10 +10 +-10 +10 +-11 +11 +-9 +11 +-10 +11 +-9 +11 +-8 +9 +-9 +11 +-9 +12 +-9 +12 +-10 +11 +-9 +11 +-9 +13 +-10 +11 +-11 +11 +-10 +10 +-10 +10 +-10 +13 +-11 +10 +-11 +9 +-10 +9 +-11 +11 +-11 +8 +-11 +11 +-10 +10 +-10 +10 +-10 +10 +-11 +10 +-10 +10 +-9 +11 +-9 +11 +-9 +12 +-11 +11 +-10 +10 +-11 +10 +-9 +9 +-11 +13 +-10 +10 +-9 +11 +-11 +10 +-10 +8 +-12 +12 +-10 +10 +-11 +10 +-10 +10 +-10 +10 +-10 +9 +-10 +10 +-10 +9 +-9 +10 +-11 +10 +-11 +11 +-10 +10 +-9 +14 +9 +-15 +9 +-10 +11 +-10 +9 +-9 +10 +-11 +9 +-11 +9 +-10 +9 +-10 +11 +-10 +10 +-10 +10 +-10 +10 +-9 +9 +-10 +10 +-9 +10 +-10 +8 +-10 +10 +-11 +10 +-11 +9 +-10 +9 +-8 +10 +-12 +11 +-10 +10 +-9 +10 +-10 +9 +-11 +11 +-9 +10 +-11 +10 +-8 +9 +-9 +10 +-9 +12 +-10 +11 +-10 +10 +-8 +9 +-8 +10 +-10 +11 +-8 +9 +-9 +11 +-11 +11 +-9 +10 +-9 +11 +-10 +9 +-9 +10 +-10 +10 +-9 +11 +-9 +8 +-10 +8 +-8 +11 +-12 +-7 +14 +-7 +11 +-9 +11 +-8 +10 +-8 +8 +-9 +11 +-7 +11 +-11 +10 +-9 +10 +-8 +10 +-10 +11 +-8 +9 +-11 +10 +-11 +10 +-10 +9 +-10 +11 +-11 +9 +-8 +11 +-10 +10 +-8 +11 +-10 +12 +-10 +11 +-8 +10 +-10 +14 +-10 +10 +-10 +10 +-10 +10 +-10 +12 +-10 +10 +-11 +10 +-10 +10 +-10 +9 +-10 +10 +-10 +9 +-10 +9 +-11 +10 +-12 +10 +-10 +9 +-10 +9 +-10 +10 +-10 +11 +-9 +10 +-11 +11 +-10 +11 +-9 +10 +-9 +11 +-11 +10 +-10 +14 +10 +-16 +10 +-12 +10 +-11 +10 +-11 +8 +-9 +9 +-10 +8 +-10 +10 +-8 +9 +-10 +9 +-10 +10 +-10 +10 +-9 +10 +-9 +9 +-10 +11 +-9 +9 +-9 +11 +-9 +10 +-10 +10 +-8 +11 +-8 +10 +-9 +10 +-9 +7 +-9 +9 +-10 +10 +-10 +10 +-10 +10 +-10 +10 +-10 +9 +-10 +10 +-10 +9 +-8 +8 +-13 +-8 +14 +-8 +10 +-9 +10 +-10 +11 +-10 +10 +-9 +11 +-9 +11 +-7 +11 +-10 +11 +-9 +11 +-8 +8 +-8 +12 +-9 +11 +-10 +12 +-9 +10 +-9 +12 +-10 +10 +-10 +9 +-10 +10 +-9 +9 +-10 +10 +-10 +11 +-10 +8 +-10 +9 +-10 +9 +-9 +10 +-10 +11 +-10 +13 +-10 +9 +-9 +12 +-10 +12 +-11 +10 +-9 +9 +-8 +9 +-11 +11 +-11 +11 +-11 +11 +-10 +11 +-10 +11 +-11 +9 +-10 +10 +-10 +10 +-11 +9 +-10 +10 +-11 +9 +-11 +10 +-11 +9 +-10 +11 +-10 +11 +-10 +10 +-11 +10 +-9 +11 +-9 +10 +-10 +13 +-9 +10 +-10 +10 +-9 +11 +-10 +11 +-9 +10 +-10 +10 +-10 +10 +-9 +11 +-10 +11 +-10 +14 +10 +-15 +9 +-11 +10 +-10 +11 +-9 +12 +-10 +10 +-9 +9 +-10 +10 +-9 +8 +-10 +10 +-10 +10 +-10 +11 +-9 +9 +-10 +9 +-9 +10 +-9 +10 +-12 +-8 +15 +-7 +12 +-9 +11 +-10 +12 +-9 +12 +-9 +10 +-9 +10 +-11 +11 +-9 +9 +-11 +10 +-10 +10 +-10 +9 +-10 +10 +-10 +11 +-11 +11 +-11 +11 +-10 +9 +-10 +9 +-12 +12 +-11 +10 +-11 +9 +-9 +10 +-9 +9 +-10 +12 +-10 +10 +-9 +12 +-9 +12 +-9 +10 +-9 +12 +-9 +10 +-9 +10 +-10 +11 +-11 +11 +-9 +11 +-11 +10 +-10 +10 +-9 +9 +-10 +10 +-10 +10 +-10 +12 +-13 +10 +-10 +10 +-9 +11 +-11 +11 +-9 +10 +-9 +11 +-10 +11 +-11 +13 +10 +-15 +9 +-11 +8 +-11 +9 +-11 +9 +-10 +9 +-11 +9 +-11 +8 +-11 +9 +-10 +10 +-11 +12 +-9 +9 +-7 +11 +-10 +11 +-10 +10 +-10 +10 +-10 +9 +-9 +10 +-9 +9 +-9 +11 +-10 +9 +-9 +10 +-10 +11 +-8 +6 +-10 +9 +-9 +9 +-8 +10 +-10 +11 +-8 +9 +-8 +9 +-10 +11 +-10 +10 +-12 +-8 +15 +-9 +11 +-10 +12 +-9 +9 +-9 +10 +-9 +9 +-10 +11 +-9 +9 +-10 +8 +-9 +9 +-9 +12 +-9 +12 +-11 +11 +-10 +10 +-10 +10 +-11 +12 +-9 +8 +-10 +10 +-9 +10 +-8 +10 +-10 +12 +-10 +10 +-10 +10 +-11 +11 +-9 +9 +-8 +12 +-9 +10 +-10 +9 +-11 +11 +-11 +10 +-11 +11 +-11 +10 +-9 +11 +-10 +9 +-10 +11 +-10 +12 +-9 +11 +-9 +11 +-9 +11 +-9 +10 +-10 +10 +-8 +10 +-10 +12 +-9 +12 +-10 +11 +-9 +11 +-10 +11 +-10 +11 +-10 +10 +-9 +10 +-10 +9 +-12 +10 +-12 +10 +-11 +10 +-11 +9 +-9 +10 +-12 +10 +-9 +9 +-12 +10 +-10 +10 +-9 +10 +-10 +11 +-9 +11 +-9 +10 +-11 +12 +-13 +11 +-9 +12 +-9 +10 +-8 +10 +-9 +11 +-11 +12 +-10 +10 +-10 +9 +-9 +10 +-10 +11 +-9 +12 +-10 +10 +-10 +10 +-8 +9 +-12 +13 +-10 +10 +-10 +10 +-9 +10 +-10 +11 +-11 +10 +-10 +9 +-10 +11 +-9 +11 +-9 +11 +-11 +11 +-10 +8 +-10 +10 +-10 +11 +-11 +9 +-11 +11 +-11 +14 +10 +-15 +10 +-10 +9 +-11 +11 +-10 +10 +-9 +9 +-10 +10 +-9 +9 +-10 +9 +-10 +10 +-10 +9 +-10 +11 +-9 +10 +-10 +9 +-10 +10 +-11 +10 +-9 +11 +-10 +10 +-9 +10 +-10 +10 +-9 +11 +-10 +9 +-8 +10 +-10 +11 +-10 +10 +-9 +10 +-11 +10 +-8 +8 +-10 +10 +-10 +9 +-9 +10 +-10 +9 +-13 +-7 +14 +-8 +11 +-9 +10 +-9 +10 +-9 +10 +-9 +10 +-10 +12 +-9 +9 +-9 +10 +-9 +10 +-9 +10 +-10 +9 +-9 +10 +-9 +9 +-11 +11 +-8 +10 +-9 +12 +-9 +11 +-10 +10 +-10 +12 +-9 +9 +-10 +11 +-10 +10 +-11 +10 +-9 +12 +-10 +10 +-9 +11 +-11 +12 +-10 +10 +-9 +10 +-9 +12 +-10 +10 +-11 +9 +-10 +11 +-11 +11 +-10 +10 +-10 +11 +-11 +12 +-11 +8 +-10 +9 +-10 +9 +-11 +10 +-12 +9 +-10 +9 +-10 +10 +-8 +11 +-10 +11 +-10 +11 +-10 +10 +-9 +10 +-9 +11 +-9 +10 +-10 +11 +-10 +13 +-10 +10 +-10 +10 +-10 +10 +-9 +10 +-10 +10 +-10 +9 +-11 +11 +-9 +11 +-10 +11 +-11 +12 +-9 +10 +-9 +10 +-10 +10 +-10 +10 +-11 +11 +-11 +11 +-10 +9 +-11 +10 +-10 +11 +-11 +10 +-10 +10 +-11 +11 +-11 +12 +-10 +11 +-8 +10 +-10 +14 +11 +-14 +11 +-10 +10 +-9 +9 +-10 +9 +-11 +11 +-10 +10 +-11 +10 +-9 +9 +-10 +9 +-9 +10 +-9 +7 +-9 +9 +-10 +11 +-11 +8 +-10 +9 +-9 +11 +-9 +10 +-9 +9 +-10 +10 +-9 +10 +-9 +10 +-9 +10 +-10 +11 +-10 +9 +-10 +10 +-9 +11 +-11 +9 +-9 +10 +-9 +11 +-9 +9 +-10 +12 +-11 +-7 +13 +-8 +10 +-10 +11 +-9 +10 +-10 +11 +-9 +10 +-10 +11 +-9 +10 +-9 +9 +-10 +10 +-10 +12 +-9 +11 +-10 +12 +-9 +9 +-9 +11 +-9 +14 +10 +-15 +10 +-11 +9 +-9 +10 +-10 +9 +-10 +8 +-11 +10 +-11 +9 +-10 +9 +-9 +8 +-9 +9 +-10 +10 +-10 +10 +-10 +10 +-10 +11 +-10 +9 +-13 +-8 +12 +-8 +10 +-8 +10 +-8 +10 +-9 +10 +-10 +10 +-10 +11 +-10 +9 +-10 +10 +-9 +9 +-10 +9 +-9 +10 +-9 +12 +-7 +11 +-10 +11 +-9 +10 +-10 +10 +-10 +10 +-11 +11 +-11 +10 +-10 +10 +-9 +9 +-9 +11 +-9 +10 +-10 +11 +-10 +9 +-10 +10 +-11 +11 +-9 +10 +-9 +11 +-11 +10 +-9 +11 +-10 +9 +-10 +10 +-10 +9 +-10 +10 +-9 +10 +-11 +11 +-10 +10 +-11 +10 +-8 +10 +-10 +9 +-11 +10 +-12 +10 +-11 +10 +-11 +10 +-10 +10 +-10 +11 +-9 +10 +-11 +10 +-10 +12 +-11 +11 +-10 +10 +-9 +12 +-10 +12 +-9 +11 +-10 +11 +-9 +12 +-9 +9 +-10 +12 +-9 +10 +-10 +11 +-11 +12 +-10 +10 +-10 +12 +-10 +12 +-9 +9 +-11 +10 +-10 +10 +-11 +11 +-11 +10 +-10 +9 +-11 +10 +-11 +10 +-11 +10 +-11 +10 +-12 +10 +-11 +10 +-11 +11 +-11 +11 +-10 +8 +-11 +11 +-10 +11 +-10 +11 +-9 +11 +-10 +11 +-8 +12 +-10 +11 +-9 +11 +-10 +10 +-10 +12 +-10 +10 +-10 +12 +-9 +11 +-9 +11 +-9 +11 +-9 +11 +-10 +10 +-10 +10 +-11 +9 +-10 +10 +-11 +10 +-11 +11 +-10 +9 +-10 +11 +-11 +10 +-12 +10 +-11 +10 +-11 +10 +-10 +11 +-10 +11 +-9 +10 +-10 +10 +-10 +10 +-9 +11 +-9 +10 +-11 +11 +-10 +9 +-9 +10 +-11 +10 +-10 +8 +-9 +11 +-9 +12 +-11 +12 +-9 +9 +-11 +11 +-10 +10 +-11 +10 +-11 +10 +-9 +13 +-10 +11 +-10 +10 +-12 +12 +-11 +10 +-10 +10 +-11 +12 +-9 +12 +-10 +10 +-9 +9 +-11 +12 +-10 +11 +-10 +10 +-10 +10 +-9 +9 +-11 +10 +-10 +11 +-9 +11 +-10 +12 +-9 +11 +-9 +10 +-8 +12 +-10 +13 +-9 +11 +-9 +10 +-9 +12 +-10 +11 +-10 +10 +-9 +10 +-10 +11 +-11 +11 +-9 +10 +-10 +11 +-9 +11 +-9 +11 +-10 +12 +-10 +10 +-10 +10 +-10 +11 +-10 +11 +-10 +10 +-11 +10 +-10 +10 +-11 +10 +-11 +9 +-9 +10 +-11 +11 +-9 +10 +-10 +10 +-10 +8 +-9 +11 +-10 +10 +-10 +12 +-9 +11 +-10 +10 +-10 +10 +-10 +11 +-10 +11 +-11 +10 +-11 +11 +-8 +10 +-11 +11 +-10 +10 +-8 +8 +-10 +12 +-9 +10 +-11 +12 +-10 +12 +-10 +11 +-9 +12 +-10 +11 +-11 +11 +-12 +9 +-11 +9 +-10 +11 +-10 +10 +-9 +9 +-11 +12 +-10 +11 +-13 +11 +-11 +12 +-10 +9 +-10 +9 +-10 +11 +-11 +12 +-11 +11 +-10 +10 +-11 +11 +-9 +10 +-10 +9 +-10 +12 +-10 +12 +-9 +11 +-9 +11 +-9 +10 +-9 +12 +-11 +10 +-10 +10 +-9 +10 +-10 +11 +-11 +9 +-10 +11 +-10 +10 +-11 +11 +-10 +8 +-11 +10 +-10 +9 +-12 +11 +-11 +10 +-11 +11 +-10 +9 +-10 +11 +-10 +10 +-9 +11 +-9 +10 +-10 +12 +-9 +12 +-8 +11 +-10 +11 +-11 +11 +-10 +11 +-11 +10 +-11 +11 +-11 +10 +-11 +10 +-11 +12 +-11 +7 +-11 +9 +-10 +9 +-11 +9 +-11 +11 +-10 +12 +-11 +10 +-9 +10 +-10 +12 +-9 +11 +-9 +11 +-10 +10 +-11 +11 +-11 +12 +-9 +11 +-10 +9 +-10 +12 +-10 +11 +-11 +12 +-10 +10 +-10 +11 +-11 +12 +-8 +10 +-11 +12 +-10 +9 +-8 +11 +-11 +13 +-9 +11 +-9 +9 +-8 +9 +-10 +11 +-10 +10 +-10 +10 +-10 +9 +-11 +10 +-10 +11 +-11 +10 +-11 +10 +-12 +10 +-10 +9 +-11 +12 +-11 +9 +-11 +12 +-11 +13 +-11 +11 +-11 +11 +-10 +12 +-12 +11 +-10 +10 +-11 +11 +-10 +11 +-11 +12 +-10 +10 +-10 +11 +-11 +10 +-11 +10 +-9 +10 +-9 +10 +-10 +11 +-11 +11 +-9 +10 +-9 +11 +-10 +12 +-11 +10 +-11 +11 +-10 +9 +-11 +10 +-11 +11 +-11 +10 +-11 +10 +-10 +10 +-11 +9 +-10 +10 +-10 +11 +-11 +11 +-10 +9 +-10 +9 +-10 +11 +-10 +9 +-11 +10 +-10 +8 +-11 +11 +-10 +11 +-10 +9 +-11 +11 +-10 +12 +-11 +9 +-9 +13 +-9 +12 +-11 +12 +-10 +10 +-10 +11 +-10 +10 +-11 +11 +-9 +11 +-9 +12 +-9 +11 +-10 +13 +-10 +12 +-9 +11 +-9 +10 +-10 +11 +-10 +9 +-8 +12 +-9 +12 +-8 +10 +-10 +13 +-9 +10 +-11 +11 +-11 +9 +-10 +10 +-11 +10 +-11 +11 +-10 +10 +-10 +9 +-10 +10 +-12 +9 +-12 +11 +-10 +10 +-9 +10 +-11 +11 +-10 +10 +-9 +11 +-11 +11 +-10 +11 +-10 +10 +-12 +9 +-11 +9 +-10 +9 +-11 +10 +-9 +11 +-10 +9 +-10 +10 +-10 +11 +-9 +10 +-9 +13 +-11 +12 +-9 +9 +-9 +12 +-10 +11 +-12 +12 +-9 +11 +-11 +10 +-11 +11 +-9 +10 +-10 +11 +-9 +10 +-10 +10 +-12 +12 +-11 +12 +-9 +10 +-11 +10 +-9 +9 +-12 +10 +-10 +11 +-11 +9 +-11 +12 +-11 +12 +-9 +11 +-10 +12 +-10 +10 +-8 +11 +-9 +11 +-9 +11 +-9 +10 +-10 +11 +-10 +10 +-10 +10 +-10 +10 +-10 +11 +-10 +10 +-10 +10 +-9 +12 +-12 +10 +-9 +9 +-11 +9 +-10 +11 +-9 +11 +-9 +11 +-9 +12 +-8 +12 +-10 +11 +-9 +12 +-11 +10 +-10 +9 +-11 +10 +-10 +9 +-11 +9 +-11 +9 +-11 +10 +-10 +10 +-10 +12 +-10 +11 +-9 +11 +-10 +12 +-9 +12 +-9 +12 +-10 +12 +-9 +10 +-10 +11 +-10 +10 +-11 +11 +-11 +10 +-9 +11 +-9 +12 +-10 +11 +-10 +10 +-10 +11 +-11 +12 +9 +-15 +12 +-13 +9 +-10 +9 +-11 +10 +-10 +8 +-11 +11 +-11 +9 +-11 +9 +-10 +10 +-10 +9 +-10 +11 +-8 +7 +-10 +10 +-10 +10 +-11 +11 +-10 +10 +-10 +8 +-10 +10 +-9 +10 +-9 +10 +-10 +9 +-10 +8 +-7 +10 +-10 +9 +-9 +10 +-9 +9 +-8 +8 +-9 +11 +-10 +10 +-9 +9 +-11 +9 +-10 +9 +-8 +9 +-9 +11 +-9 +10 +-9 +9 +-11 +11 +-10 +9 +-9 +9 +-10 +9 +-9 +9 +-10 +11 +-9 +11 +-10 +9 +-9 +10 +-8 +10 +-9 +10 +-12 +-9 +13 +-8 +10 +-8 +10 +-9 +12 +-8 +10 +-10 +12 +-10 +11 +-9 +9 +-11 +11 +-9 +11 +-9 +12 +-11 +11 +-10 +11 +-8 +10 +-8 +11 +-9 +12 +-9 +11 +-8 +10 +-9 +12 +-9 +9 +-11 +10 +-11 +12 +-9 +11 +-10 +11 +-9 +10 +-9 +9 +-10 +10 +-9 +11 +-10 +9 +-11 +11 +-10 +11 +-11 +10 +-10 +10 +-10 +10 +-9 +11 +-9 +9 +-12 +10 +-9 +9 +-11 +10 +-10 +9 +-9 +9 +-10 +10 +-10 +10 +-10 +9 +-10 +12 +-9 +11 +-10 +11 +-10 +14 +11 +-16 +11 +-11 +8 +-11 +11 +-11 +10 +-11 +8 +-11 +10 +-11 +9 +-11 +10 +-9 +10 +-12 +11 +-10 +9 +-11 +9 +-9 +10 +-10 +8 +-9 +9 +-10 +10 +-9 +11 +-10 +10 +-10 +9 +-8 +10 +-9 +9 +-10 +10 +-9 +9 +-10 +11 +-7 +8 +-9 +9 +-8 +10 +-10 +9 +-9 +11 +-9 +10 +-10 +11 +-12 +-8 +14 +-8 +12 +-9 +10 +-7 +10 +-9 +9 +-9 +11 +-10 +11 +-8 +9 +-9 +10 +-10 +10 +-10 +10 +-10 +9 +-9 +11 +-10 +11 +-8 +10 +-9 +12 +-10 +11 +-9 +10 +-10 +8 +-8 +13 +-10 +12 +-8 +12 +-8 +9 +-10 +11 +-11 +9 +-10 +10 +-10 +11 +-9 +10 +-9 +10 +-10 +10 +-8 +10 +-9 +11 +-10 +12 +-10 +11 +-10 +10 +-10 +10 +-11 +12 +-11 +11 +-10 +10 +-11 +11 +-11 +9 +-11 +9 +-10 +11 +-12 +9 +-11 +9 +-10 +8 +-10 +9 +-11 +9 +-12 +10 +-9 +9 +-12 +12 +-10 +11 +-8 +9 +-10 +11 +-9 +11 +-8 +12 +-9 +14 +-10 +11 +-8 +11 +-10 +12 +-9 +13 +-10 +11 +-10 +11 +-11 +13 +11 +-16 +11 +-12 +9 +-10 +9 +-12 +10 +-10 +9 +-11 +9 +-10 +10 +-11 +11 +-11 +10 +-9 +10 +-9 +10 +-10 +11 +-12 +10 +-10 +9 +-10 +11 +-13 +-8 +15 +-9 +11 +-10 +11 +-9 +11 +-9 +10 +-9 +10 +-10 +10 +-8 +10 +-9 +11 +-10 +10 +-9 +12 +-9 +10 +-8 +12 +-11 +13 +-9 +12 +-8 +12 +-9 +12 +-10 +13 +-9 +10 +-9 +10 +-10 +10 +-10 +11 +-11 +11 +-11 +9 +-10 +9 +-11 +10 +-12 +10 +-10 +9 +-11 +10 +-11 +10 +-11 +9 +-10 +9 +-11 +11 +-9 +10 +-9 +10 +-10 +11 +-10 +11 +-9 +9 +-9 +12 +-9 +11 +-9 +12 +-10 +11 +-8 +10 +-9 +11 +-9 +10 +-11 +11 +-11 +9 +-9 +14 +10 +-15 +11 +-11 +10 +-11 +11 +-11 +9 +-10 +10 +-10 +10 +-8 +11 +-11 +10 +-9 +10 +-10 +9 +-10 +10 +-10 +10 +-10 +9 +-10 +9 +-10 +10 +-10 +9 +-10 +10 +-10 +10 +-9 +9 +-9 +11 +-11 +11 +-11 +11 +-11 +9 +-9 +10 +-9 +8 +-9 +9 +-9 +9 +-10 +10 +-9 +10 +-9 +11 +-9 +10 +-11 +-9 +14 +-7 +12 +-8 +11 +-9 +10 +-8 +11 +-9 +12 +-9 +11 +-9 +11 +-9 +10 +-10 +10 +-9 +10 +-9 +9 +-10 +10 +-10 +10 +-11 +10 +-10 +9 +-11 +11 +-9 +11 +-11 +11 +-9 +10 +-9 +10 +-11 +11 +-9 +11 +-11 +10 +-10 +9 +-9 +10 +-10 +12 +-10 +11 +-8 +11 +-10 +10 +-10 +10 +-10 +10 +-11 +10 +-11 +10 +-11 +11 +-11 +10 +-10 +11 +-9 +9 +-9 +10 +-9 +13 +-9 +9 +-9 +10 +-10 +11 +-10 +11 +-10 +12 +-10 +12 +-9 +12 +-10 +10 +-10 +11 +-9 +10 +-11 +11 +-11 +11 +-11 +10 +-11 +10 +-10 +10 +-11 +11 +-9 +10 +-10 +11 +-10 +10 +-10 +11 +-10 +11 +-10 +10 +-10 +10 +-10 +10 +-12 +11 +-10 +11 +-9 +12 +-9 +11 +-10 +12 +-10 +11 +-9 +8 +-9 +10 +-10 +11 +-10 +11 +-11 +11 +-12 +9 +-10 +10 +-11 +12 +-12 +11 +-11 +11 +-11 +10 +-11 +12 +-10 +12 +-9 +11 +-11 +11 +-10 +10 +-11 +10 +-11 +11 +-10 +11 +-10 +10 +-11 +10 +-11 +11 +-11 +12 +-9 +10 +-11 +10 +-11 +14 +11 +-17 +11 +-12 +11 +-10 +11 +-10 +10 +-11 +9 +-10 +9 +-10 +11 +-10 +10 +-10 +10 +-9 +12 +-10 +14 +-10 +9 +-10 +9 +-9 +10 +-10 +9 +-10 +10 +-9 +9 +-10 +9 +-10 +10 +-9 +10 +-11 +10 +-9 +9 +-9 +9 +-10 +10 +-11 +10 +-9 +9 +-8 +9 +-11 +11 +-9 +8 +-8 +10 +-9 +11 +-13 +-9 +14 +-8 +10 +-8 +8 +-10 +10 +-10 +11 +-8 +12 +-11 +9 +-9 +12 +-9 +12 +-8 +11 +-9 +9 +-10 +11 +-11 +11 +-10 +11 +-10 +10 +-9 +10 +-9 +11 +-9 +11 +-10 +11 +-10 +10 +-11 +9 +-10 +11 +-11 +10 +-9 +11 +-9 +10 +-10 +10 +-9 +11 +-10 +12 +-10 +10 +-11 +11 +-10 +10 +-9 +11 +-9 +12 +-10 +11 +-9 +10 +-10 +10 +-10 +10 +-11 +10 +-9 +11 +-11 +9 +-11 +10 +-8 +8 +-10 +10 +-11 +10 +-11 +11 +-10 +9 +-10 +11 +-10 +9 +-11 +11 +-10 +8 +-10 +11 +-10 +10 +-11 +11 +-11 +11 +-10 +10 +-12 +12 +-9 +11 +-10 +9 +-10 +12 +-10 +9 +-11 +9 +-9 +11 +-11 +11 +-9 +10 +-9 +10 +-9 +11 +-9 +10 +-9 +10 +-10 +11 +-10 +11 +-8 +8 +-12 +12 +-11 +10 +-10 +8 +-10 +11 +-11 +12 +-11 +10 +-9 +11 +-11 +12 +-9 +15 +11 +-14 +10 +-11 +10 +-10 +10 +-10 +9 +-9 +9 +-11 +10 +-11 +10 +-11 +9 +-11 +9 +-10 +8 +-10 +9 +-10 +11 +-9 +9 +-8 +8 +-10 +10 +-9 +8 +-10 +10 +-9 +9 +-11 +8 +-8 +7 +-11 +11 +-12 +9 +-8 +10 +-11 +10 +-9 +9 +-10 +10 +-10 +10 +-11 +8 +-8 +10 +-12 +9 +-9 +10 +-13 +-9 +15 +-9 +11 +-8 +8 +-9 +12 +-9 +10 +-9 +11 +-8 +11 +-8 +11 +-10 +11 +-10 +11 +-10 +10 +-11 +11 +-9 +11 +-8 +11 +-9 +11 +-9 +14 +10 +-15 +11 +-9 +10 +-10 +10 +-9 +10 +-9 +11 +-9 +11 +-9 +9 +-10 +10 +-11 +11 +-9 +9 +-10 +8 +-11 +9 +-10 +9 +-11 +9 +-10 +9 +-13 +-9 +13 +-9 +11 +-10 +8 +-9 +10 +-8 +9 +-11 +10 +-11 +12 +-9 +12 +-9 +10 +-9 +10 +-8 +10 +-9 +11 +-8 +10 +-9 +11 +-9 +10 +-9 +11 +-9 +10 +-10 +10 +-10 +10 +-9 +7 +-10 +11 +-9 +10 +-11 +11 +-10 +11 +-10 +10 +-10 +11 +-11 +12 +-12 +11 +-11 +10 +-10 +10 +-8 +11 +-10 +11 +-11 +11 +-9 +11 +-10 +11 +-9 +11 +-11 +11 +-10 +11 +-10 +12 +-9 +12 +-10 +10 +-10 +10 +-8 +10 +-9 +9 +-10 +12 +-10 +10 +-9 +10 +-9 +10 +-10 +11 +-9 +10 +-10 +10 +-11 +11 +-11 +11 +-9 +10 +-9 +11 +-9 +10 +-9 +11 +-10 +12 +-10 +10 +-9 +10 +-11 +11 +-10 +11 +-11 +10 +-10 +9 +-11 +10 +-10 +9 +-10 +11 +-10 +10 +-10 +11 +-9 +10 +-10 +11 +-10 +11 +-11 +12 +-9 +9 +-10 +11 +-9 +10 +-9 +10 +-9 +9 +-10 +11 +-10 +10 +-10 +10 +-10 +10 +-10 +11 +-9 +10 +-10 +10 +-11 +10 +-10 +9 +-10 +12 +-10 +10 +-9 +10 +-9 +10 +-11 +13 +-9 +11 +-7 +9 +-9 +11 +-9 +10 +-10 +11 +-11 +10 +-10 +9 +-10 +9 +-11 +11 +-10 +11 +-10 +11 +-10 +10 +-10 +11 +-11 +10 +-10 +9 +-10 +11 +-10 +11 +-10 +11 +-9 +11 +-11 +12 +-10 +10 +-8 +10 +-9 +10 +-10 +9 +-9 +12 +-10 +10 +-10 +10 +-10 +10 +-9 +9 +-9 +9 +-10 +9 +-11 +11 +-10 +9 +-11 +10 +-11 +11 +-9 +10 +-11 +10 +-10 +10 +-10 +10 +-10 +10 +-12 +9 +-9 +10 +-12 +13 +-11 +10 +-10 +11 +-10 +11 +-9 +10 +-9 +11 +-10 +9 +-10 +12 +-10 +11 +-10 +11 +-10 +9 +-10 +13 +-10 +10 +-11 +11 +-10 +12 +-9 +10 +-9 +12 +-11 +10 +-9 +10 +-10 +10 +-10 +11 +-10 +12 +-9 +9 +-10 +10 +-9 +10 +-9 +10 +-12 +11 +-8 +9 +-10 +11 +-11 +10 +-10 +10 +-10 +12 +-10 +11 +-10 +10 +-10 +11 +-9 +10 +-9 +12 +-8 +11 +-11 +11 +-11 +10 +-10 +9 +-8 +8 +-11 +12 +-9 +10 +-11 +11 +-10 +10 +-10 +11 +-10 +10 +-10 +10 +-9 +11 +-10 +10 +-11 +11 +-10 +12 +-9 +9 +-10 +10 +-10 +9 +-10 +10 +-10 +10 +-10 +10 +-11 +10 +-10 +9 +-11 +11 +-9 +10 +-10 +11 +-10 +10 +-11 +10 +-12 +11 +-10 +9 +-11 +10 +-10 +11 +-11 +11 +-11 +10 +-10 +11 +-10 +11 +-10 +11 +-10 +9 +-10 +10 +-10 +11 +-9 +11 +-10 +10 +-11 +8 +-11 +11 +-9 +10 +-9 +11 +-10 +11 +-10 +12 +-10 +11 +-9 +10 +-9 +11 +-10 +13 +-10 +11 +-10 +11 +-10 +10 +-10 +9 +-10 +10 +-11 +9 +-12 +11 +-9 +8 +-11 +11 +-11 +11 +-10 +10 +-12 +12 +-10 +11 +-8 +10 +-10 +11 +-10 +11 +-9 +12 +-9 +11 +-10 +12 +-9 +11 +-11 +10 +-11 +11 +-10 +9 +-10 +10 +-11 +10 +-10 +9 +-10 +10 +-10 +9 +-11 +10 +-10 +12 +-12 +11 +-10 +11 +-11 +10 +-11 +10 +-11 +11 +-10 +11 +-12 +10 +-10 +8 +-11 +13 +-9 +9 +-9 +10 +-12 +13 +-9 +11 +-10 +10 +-11 +9 +-11 +11 +-11 +10 +-10 +10 +-11 +12 +-10 +10 +-10 +10 +-9 +12 +-9 +12 +-9 +12 +-10 +10 +-10 +10 +-10 +11 +-10 +10 +-9 +9 +-10 +11 +-11 +11 +-11 +10 +-11 +10 +-9 +10 +-10 +10 +-10 +10 +-10 +9 +-12 +10 +-10 +11 +-10 +10 +-10 +11 +-10 +11 +-9 +12 +-9 +10 +-8 +10 +-8 +11 +-10 +12 +-8 +9 +-9 +11 +-10 +11 +-11 +10 +-10 +11 +-9 +8 +-12 +11 +-11 +11 +-11 +9 +-11 +9 +-11 +10 +-10 +11 +-9 +11 +-10 +10 +-11 +11 +-9 +12 +-11 +13 +-11 +11 +-8 +9 +-10 +11 +-10 +11 +-8 +12 +-10 +10 +-10 +10 +-10 +10 +-10 +11 +-11 +11 +-10 +10 +-10 +11 +-10 +8 +-9 +10 +-10 +8 +-10 +11 +-10 +10 +-11 +10 +-10 +11 +-10 +10 +-10 +10 +-10 +10 +-10 +10 +-11 +9 +-11 +11 +-10 +11 +-11 +11 +-9 +11 +-10 +10 +-11 +10 +-9 +11 +-11 +12 +-9 +11 +-10 +10 +-10 +10 +-10 +10 +-9 +10 +-10 +10 +-10 +11 +-10 +10 +-11 +11 +-12 +10 +-8 +7 +-9 +10 +-11 +12 +-11 +9 +-11 +12 +-11 +13 +-12 +10 +-8 +11 +-8 +11 +-9 +12 +-10 +12 +-9 +11 +-9 +11 +-10 +13 +-9 +10 +-9 +11 +-11 +11 +-9 +10 +-9 +10 +-10 +11 +-9 +9 +-10 +12 +-10 +12 +-10 +10 +-10 +9 +-11 +11 +-11 +10 +-10 +10 +-10 +12 +-10 +12 +-11 +12 +-11 +12 +-10 +10 +-9 +11 +-11 +11 +-8 +12 +-10 +10 +-9 +9 +-10 +10 +-10 +10 +-10 +9 +-11 +10 +-9 +9 +-9 +11 +-10 +10 +-10 +10 +-10 +10 +-11 +10 +-10 +10 +-11 +11 +-10 +11 +-11 +11 +-10 +9 +-11 +10 +-9 +11 +-10 +10 +-12 +10 +-12 +11 +-9 +9 +-11 +11 +-11 +11 +-11 +10 +-9 +10 +-10 +10 +-10 +12 +-8 +11 +-10 +12 +-10 +10 +-11 +11 +-10 +12 +-10 +9 +-10 +11 +-9 +11 +-11 +11 +-10 +11 +-10 +11 +-9 +9 +-11 +12 +-10 +10 +-11 +10 +-11 +11 +-9 +8 +-10 +11 +-11 +10 +-12 +10 +-10 +10 +-10 +10 +-11 +12 +-9 +10 +-11 +11 +-9 +10 +-11 +12 +-10 +11 +-11 +10 +-10 +9 +-10 +10 +-9 +11 +-10 +11 +-10 +10 +-10 +12 +-10 +14 +-10 +9 +-10 +10 +-9 +13 +10 +-15 +11 +-10 +9 +-9 +10 +-10 +8 +-11 +11 +-10 +10 +-9 +9 +-10 +11 +-9 +9 +-10 +9 +-10 +10 +-9 +11 +-9 +10 +-8 +9 +-10 +11 +-9 +9 +-9 +11 +-11 +11 +-8 +7 +-9 +8 +-8 +9 +-8 +9 +-10 +8 +-9 +9 +-10 +10 +-9 +7 +-9 +9 +-7 +9 +-10 +11 +-9 +10 +-9 +9 +-11 +11 +-9 +10 +-9 +10 +-8 +10 +-11 +9 +-8 +10 +-9 +10 +-8 +10 +-9 +9 +-9 +11 +-10 +10 +-9 +9 +-10 +10 +-10 +11 +-9 +11 +-9 +10 +-13 +-6 +14 +-8 +11 +-9 +8 +-9 +10 +-10 +11 +-10 +9 +-10 +11 +-9 +10 +-10 +10 +-9 +10 +-11 +11 +-10 +10 +-8 +11 +-12 +10 +-10 +9 +-11 +10 +-10 +11 +-10 +11 +-10 +11 +-9 +10 +-9 +10 +-8 +11 +-10 +10 +-11 +11 +-10 +10 +-10 +11 +-10 +11 +-10 +12 +-9 +9 +-10 +9 +-9 +11 +-10 +11 +-11 +10 +-11 +10 +-11 +11 +-10 +10 +-9 +11 +-12 +11 +-11 +11 +-8 +10 +-10 +11 +-10 +11 +-10 +10 +-10 +10 +-9 +11 +-11 +11 +-11 +9 +-11 +13 +10 +-14 +9 +-12 +9 +-11 +10 +-11 +9 +-10 +10 +-10 +11 +-8 +10 +-8 +12 +-9 +12 +-9 +11 +-10 +9 +-8 +9 +-11 +12 +-10 +9 +-9 +10 +-9 +9 +-10 +9 +-10 +9 +-10 +8 +-9 +10 +-10 +10 +-10 +9 +-10 +10 +-9 +10 +-9 +10 +-10 +12 +-9 +10 +-8 +10 +-8 +9 +-9 +10 +-9 +11 +-14 +-7 +14 +-9 +10 +-10 +11 +-10 +11 +-9 +10 +-10 +11 +-10 +10 +-10 +10 +-9 +9 +-10 +10 +-10 +11 +-9 +9 +-10 +10 +-10 +10 +-10 +12 +-10 +10 +-10 +10 +-11 +11 +-9 +10 +-9 +10 +-8 +10 +-9 +9 +-10 +10 +-10 +11 +-9 +10 +-10 +10 +-10 +10 +-10 +9 +-11 +10 +-11 +11 +-10 +11 +-8 +10 +-10 +12 +-10 +11 +-9 +9 +-9 +9 +-10 +10 +-10 +12 +-9 +10 +-10 +10 +-8 +10 +-10 +11 +-10 +12 +-8 +11 +-9 +10 +-8 +10 +-11 +9 +-11 +11 +-9 +9 +-10 +10 +-10 +11 +-11 +11 +-9 +10 +-11 +10 +-10 +10 +-9 +10 +-12 +10 +-10 +10 +-11 +9 +-11 +10 +-12 +11 +-10 +11 +-10 +11 +-10 +13 +9 +-14 +9 +-11 +10 +-10 +10 +-10 +9 +-10 +9 +-10 +10 +-10 +9 +-11 +9 +-9 +9 +-10 +8 +-8 +9 +-10 +11 +-9 +10 +-9 +9 +-10 +11 +-13 +-5 +12 +-8 +11 +-9 +10 +-9 +11 +-8 +10 +-10 +11 +-9 +11 +-9 +12 +-9 +10 +-10 +10 +-9 +12 +-11 +10 +-10 +12 +-9 +10 +-9 +10 +-9 +10 +-11 +11 +-8 +9 +-10 +9 +-10 +10 +-9 +11 +-9 +10 +-10 +13 +-11 +9 +-8 +11 +-10 +10 +-10 +11 +-10 +10 +-9 +9 +-11 +10 +-9 +9 +-10 +11 +-9 +11 +-11 +11 +-9 +9 +-10 +10 +-11 +12 +-11 +9 +-11 +11 +-11 +9 +-9 +10 +-8 +11 +-11 +13 +-8 +11 +-10 +11 +-10 +11 +-9 +9 +-11 +14 +8 +-16 +10 +-12 +11 +-11 +7 +-10 +9 +-12 +10 +-11 +10 +-10 +9 +-10 +11 +-10 +10 +-11 +10 +-9 +9 +-9 +11 +-9 +11 +-9 +12 +-9 +12 +-10 +11 +-9 +10 +-9 +10 +-8 +10 +-10 +11 +-9 +10 +-10 +11 +-10 +9 +-10 +10 +-10 +10 +-10 +9 +-10 +12 +-10 +10 +-11 +10 +-10 +11 +-9 +9 +-11 +-9 +13 +-9 +11 +-9 +10 +-8 +10 +-8 +10 +-9 +9 +-10 +10 +-9 +10 +-10 +10 +-9 +9 +-9 +10 +-10 +10 +-9 +12 +-9 +12 +-8 +10 +-9 +12 +-8 +13 +-7 +10 +-10 +11 +-8 +10 +-9 +11 +-8 +12 +-9 +11 +-10 +11 +-9 +10 +-10 +10 +-11 +10 +-12 +10 +-11 +9 +-11 +10 +-11 +10 +-11 +10 +-10 +10 +-11 +8 +-10 +9 +-9 +11 +-10 +11 +-9 +10 +-10 +11 +-10 +11 +-9 +10 +-11 +10 +-12 +10 +-11 +10 +-10 +9 +-12 +10 +-11 +9 +-10 +10 +-10 +10 +-10 +11 +-9 +12 +-9 +12 +-10 +11 +-10 +11 +-10 +11 +-8 +8 +-9 +11 +-9 +10 +-9 +12 +-8 +11 +-10 +10 +-9 +10 +-11 +12 +-11 +10 +-9 +10 +-11 +10 +-10 +10 +-10 +9 +-11 +10 +-10 +10 +-10 +10 +-11 +11 +-11 +10 +-9 +7 +-10 +10 +-9 +11 +-10 +10 +-10 +12 +-10 +10 +-8 +11 +-8 +12 +-9 +11 +-11 +13 +-10 +10 +-9 +11 +-9 +12 +-11 +11 +-9 +10 +-10 +10 +-10 +10 +-9 +10 +-10 +11 +-10 +9 +-10 +11 +-11 +11 +-10 +16 +10 +-15 +10 +-11 +9 +-12 +10 +-10 +8 +-11 +9 +-11 +10 +-12 +9 +-10 +10 +-11 +10 +-10 +9 +-10 +9 +-9 +9 +-9 +10 +-9 +10 +-9 +9 +-10 +10 +-11 +10 +-10 +10 +-9 +12 +-8 +9 +-8 +9 +-9 +12 +-10 +11 +-9 +10 +-9 +9 +-8 +10 +-9 +10 +-9 +10 +-10 +10 +-9 +10 +-10 +10 +-12 +-9 +11 +-9 +11 +-10 +11 +-12 +8 +-11 +11 +-10 +10 +-9 +9 +-10 +12 +-9 +10 +-10 +11 +-11 +11 +-9 +12 +-8 +11 +-10 +10 +-8 +12 +-11 +10 +-10 +10 +-10 +10 +-11 +11 +-10 +10 +-11 +13 +-10 +12 +-9 +10 +-9 +10 +-9 +11 +-11 +12 +-10 +11 +-10 +10 +-10 +10 +-10 +10 +-9 +11 +-9 +11 +-11 +11 +-9 +10 +-10 +10 +-11 +10 +-9 +9 +-11 +10 +-11 +9 +-11 +11 +-11 +10 +-9 +11 +-10 +13 +-10 +11 +-9 +10 +-10 +11 +-10 +11 +-10 +11 +-10 +11 +-11 +11 +-9 +9 +-12 +12 +-10 +11 +-9 +10 +-10 +10 +-10 +12 +-9 +11 +-10 +11 +-9 +11 +-10 +12 +-10 +11 +-9 +10 +-10 +10 +-10 +9 +-11 +11 +-9 +11 +-9 +11 +-10 +11 +-8 +11 +-10 +10 +-10 +11 +-9 +9 +-10 +10 +-9 +12 +-11 +11 +-10 +11 +-9 +12 +-11 +11 +-11 +11 +-10 +15 +10 +-16 +10 +-11 +10 +-10 +12 +-11 +8 +-10 +9 +-11 +9 +-10 +9 +-12 +9 +-10 +8 +-12 +9 +-10 +9 +-11 +10 +-10 +8 +-11 +10 +-10 +8 +-10 +9 +-11 +10 +-9 +8 +-9 +10 +-10 +10 +-9 +10 +-9 +11 +-7 +8 +-9 +11 +-8 +10 +-11 +11 +-10 +10 +-9 +11 +-9 +10 +-10 +9 +-10 +8 +-13 +-9 +13 +-7 +8 +-10 +9 +-11 +12 +-8 +11 +-9 +10 +-10 +10 +-9 +11 +-9 +11 +-9 +12 +-10 +9 +-8 +11 +-10 +13 +-9 +11 +-9 +9 +-9 +14 +10 +-15 +11 +-10 +9 +-10 +9 +-11 +9 +-10 +9 +-10 +9 +-11 +9 +-10 +9 +-9 +9 +-10 +10 +-9 +11 +-10 +9 +-10 +10 +-10 +10 +-11 +10 +-14 +-9 +14 +-9 +10 +-8 +8 +-11 +11 +-8 +9 +-8 +10 +-9 +10 +-8 +10 +-9 +12 +-10 +11 +-9 +12 +-11 +10 +-10 +11 +-10 +10 +-10 +11 +-10 +10 +-11 +11 +-10 +10 +-10 +11 +-9 +10 +-8 +12 +-11 +12 +-10 +11 +-11 +10 +-8 +10 +-11 +13 +-11 +10 +-11 +11 +-9 +10 +-9 +9 +-11 +11 +-10 +9 +-10 +9 +-10 +10 +-9 +10 +-11 +11 +-11 +11 +-11 +10 +-9 +9 +-11 +11 +-11 +11 +-11 +10 +-10 +10 +-10 +10 +-11 +10 +-11 +14 +-10 +10 +-10 +10 +-11 +12 +-10 +11 +-10 +10 +-10 +12 +-10 +13 +-10 +11 +-9 +8 +-9 +11 +-9 +11 +-10 +10 +-9 +11 +-9 +9 +-9 +10 +-12 +11 +-9 +10 +-9 +12 +-9 +12 +-9 +14 +-10 +10 +-9 +12 +-10 +10 +-9 +10 +-11 +10 +-11 +11 +-11 +10 +-11 +9 +-9 +10 +-11 +10 +-11 +10 +-10 +11 +-11 +11 +-10 +10 +-11 +11 +-10 +11 +-9 +10 +-11 +11 +-9 +9 +-10 +10 +-11 +9 +-9 +10 +-11 +12 +-10 +10 +-10 +12 +-9 +8 +-9 +10 +-12 +12 +-10 +12 +-9 +11 +-10 +12 +-10 +10 +-10 +11 +-10 +11 +-9 +9 +-10 +10 +-10 +10 +-9 +10 +-11 +11 +-9 +10 +-10 +10 +-10 +11 +-10 +10 +-9 +12 +-10 +12 +-10 +10 +-10 +10 +-10 +9 +-11 +12 +-9 +11 +-10 +11 +-9 +11 +-9 +10 +-11 +11 +-10 +10 +-12 +11 +-10 +9 +-10 +11 +-9 +10 +-9 +9 +-11 +10 +-11 +10 +-9 +10 +-9 +11 +-11 +10 +-9 +10 +-11 +10 +-9 +10 +-10 +12 +-9 +11 +-10 +11 +-9 +12 +-10 +10 +-11 +10 +-10 +10 +-10 +10 +-10 +9 +-10 +10 +-11 +10 +-9 +10 +-11 +10 +-11 +8 +-10 +11 +-11 +12 +-11 +11 +-9 +9 +-10 +11 +-10 +11 +-10 +11 +-10 +11 +-10 +12 +-11 +10 +-10 +11 +-9 +11 +-9 +11 +-8 +10 +-11 +13 +-9 +11 +-9 +11 +-10 +10 +-9 +9 +-10 +11 +-11 +12 +-9 +10 +-11 +11 +-10 +10 +-10 +10 +-9 +10 +-8 +9 +-12 +12 +-10 +9 +-10 +9 +-10 +10 +-9 +10 +-11 +11 +-10 +10 +-9 +10 +-9 +13 +-11 +11 +-10 +11 +-9 +11 +-10 +10 +-9 +12 +-12 +11 +-10 +11 +-9 +11 +-10 +11 +-10 +10 +-10 +10 +-12 +10 +-11 +11 +-9 +10 +-9 +10 +-10 +11 +-10 +10 +-10 +12 +-11 +12 +-9 +10 +-11 +10 +-10 +10 +-10 +10 +-10 +11 +-10 +8 +-10 +11 +-10 +9 +-11 +10 +-10 +11 +-11 +10 +-9 +12 +-10 +9 +-12 +11 +-9 +10 +-10 +12 +-10 +11 +-10 +11 +-10 +11 +-11 +10 +-11 +10 +-10 +12 +-10 +12 +-9 +11 +-9 +11 +-11 +11 +-10 +10 +-10 +9 +-9 +8 +-11 +11 +-11 +10 +-10 +9 +-11 +11 +-10 +10 +-10 +9 +-11 +10 +-9 +10 +-9 +10 +-10 +11 +-10 +11 +-10 +10 +-10 +11 +-10 +11 +-9 +9 +-9 +11 +-11 +11 +-9 +11 +-11 +11 +-11 +10 +-10 +10 +-10 +11 +-11 +11 +-11 +9 +-11 +10 +-9 +9 +-11 +13 +-10 +8 +-9 +10 +-10 +11 +-9 +11 +-9 +10 +-10 +12 +-9 +12 +-9 +11 +-10 +11 +-11 +10 +-9 +11 +-10 +9 +-10 +11 +-10 +9 +-10 +10 +-10 +12 +-11 +12 +-10 +10 +-10 +9 +-10 +10 +-10 +9 +-10 +10 +-11 +11 +-10 +10 +-11 +9 +-10 +11 +-11 +13 +-9 +9 +-9 +11 +-10 +11 +-10 +9 +-12 +10 +-8 +11 +-11 +11 +-9 +10 +-9 +10 +-10 +11 +-9 +10 +-10 +10 +-11 +11 +-11 +11 +-9 +10 +-11 +11 +-11 +10 +-9 +10 +-10 +10 +-10 +10 +-10 +11 +-10 +9 +-11 +11 +-10 +12 +-10 +11 +-10 +12 +-8 +11 +-10 +10 +-10 +12 +-11 +12 +-10 +11 +-9 +9 +-10 +10 +-10 +12 +-11 +11 +-9 +11 +-11 +11 +-10 +11 +-9 +11 +-11 +11 +-10 +10 +-11 +10 +-10 +10 +-11 +10 +-11 +10 +-10 +10 +-11 +10 +-10 +9 +-12 +11 +-11 +11 +-11 +10 +-11 +11 +-11 +12 +-9 +8 +-10 +10 +-8 +9 +-10 +10 +-11 +12 +-10 +9 +-11 +11 +-10 +10 +-9 +11 +-8 +11 +-10 +11 +-9 +10 +-10 +11 +-8 +12 +-9 +12 +-8 +10 +-11 +13 +-9 +12 +-9 +11 +-10 +11 +-10 +10 +-10 +14 +-10 +10 +-10 +10 +-9 +11 +-10 +10 +-10 +10 +-11 +11 +-9 +8 +-11 +10 +-10 +10 +-9 +11 +-10 +10 +-9 +12 +-11 +10 +-11 +10 +-11 +11 +-10 +10 +-9 +10 +-10 +10 +-10 +10 +-10 +9 +-10 +11 +-10 +9 +-9 +9 +-11 +11 +-11 +11 +-9 +11 +-11 +12 +-9 +10 +-8 +11 +-8 +8 +-11 +9 +-10 +11 +-10 +11 +-10 +12 +-11 +11 +-8 +11 +-9 +8 +-10 +11 +-9 +8 +-12 +12 +-9 +10 +-11 +10 +-10 +11 +-10 +9 +-10 +9 +-11 +10 +-11 +10 +-9 +10 +-11 +11 +-10 +10 +-10 +11 +-10 +12 +-10 +11 +-9 +11 +-9 +12 +-10 +11 +-9 +9 +-10 +10 +-9 +11 +-10 +11 +-10 +10 +-10 +10 +-10 +10 +-11 +10 +-11 +10 +-10 +11 +-9 +11 +-10 +12 +-10 +11 +-10 +9 +-11 +9 +-10 +10 +-9 +10 +-10 +10 +-10 +10 +-10 +11 +-11 +10 +-10 +9 +-11 +10 +-10 +11 +-10 +11 +-11 +13 +-11 +11 +-10 +9 +-10 +9 +-10 +9 +-10 +9 +-10 +11 +-10 +9 +-9 +9 +-11 +10 +-11 +9 +-11 +10 +-10 +11 +-9 +10 +-11 +13 +-8 +11 +-10 +11 +-9 +11 +-10 +11 +-10 +12 +-10 +10 +-10 +14 +9 +-14 +10 +-11 +12 +-10 +9 +-11 +10 +-11 +9 +-11 +8 +-9 +10 +-10 +10 +-9 +10 +-9 +11 +-9 +10 +-9 +10 +-10 +9 +-10 +10 +-9 +9 +-8 +9 +-11 +12 +-9 +9 +-9 +10 +-8 +8 +-10 +9 +-8 +9 +-9 +9 +-10 +11 +-9 +9 +-10 +9 +-10 +9 +-10 +9 +-10 +10 +-9 +10 +-10 +11 +-8 +11 +-9 +9 +-9 +10 +-10 +9 +-10 +10 +-9 +10 +-9 +9 +-9 +10 +-11 +11 +-10 +9 +-10 +10 +-9 +10 +-10 +11 +-8 +10 +-9 +10 +-8 +9 +-13 +-6 +15 +-7 +11 +-11 +12 +-9 +10 +-10 +12 +-9 +10 +-9 +10 +-10 +9 +-10 +10 +-12 +9 +-11 +9 +-10 +10 +-11 +11 +-10 +9 +-9 +10 +-10 +11 +-10 +10 +-11 +10 +-10 +8 +-9 +9 +-11 +11 +-9 +11 +-9 +11 +-9 +10 +-9 +11 +-9 +12 +-9 +11 +-9 +11 +-9 +12 +-8 +12 +-11 +11 +-9 +11 +-9 +10 +-9 +10 +-10 +11 +-10 +12 +-11 +10 +-10 +10 +-10 +10 +-10 +11 +-11 +9 +-9 +10 +-10 +12 +-9 +12 +-11 +10 +-11 +10 +-10 +11 +-10 +15 +9 +-16 +10 +-11 +10 +-10 +9 +-10 +9 +-12 +9 +-8 +9 +-11 +12 +-11 +10 +-11 +9 +-9 +9 +-10 +11 +-9 +10 +-11 +10 +-9 +11 +-8 +10 +-10 +11 +-9 +11 +-9 +9 +-9 +10 +-9 +10 +-9 +11 +-10 +9 +-9 +8 +-10 +10 +-11 +8 +-10 +10 +-10 +9 +-11 +9 +-9 +9 +-10 +10 +-9 +11 +-12 +-8 +13 +-9 +9 +-9 +9 +-10 +12 +-9 +10 +-9 +11 +-9 +10 +-9 +12 +-9 +10 +-10 +10 +-10 +10 +-9 +12 +-9 +11 +-9 +10 +-10 +10 +-9 +9 +-10 +12 +-11 +10 +-10 +11 +-9 +9 +-10 +11 +-10 +11 +-9 +10 +-11 +10 +-11 +10 +-10 +11 +-11 +13 +-11 +11 +-8 +11 +-9 +11 +-9 +10 +-10 +12 +-9 +12 +-8 +7 +-10 +11 +-10 +10 +-10 +11 +-11 +11 +-10 +11 +-8 +10 +-9 +12 +-9 +11 +-9 +10 +-10 +10 +-11 +11 +-9 +10 +-9 +11 +-10 +10 +-9 +14 +-11 +10 +-10 +10 +-9 +10 +-11 +11 +-10 +10 +-11 +10 +-11 +11 +-9 +11 +-9 +10 +-11 +11 +-8 +11 +-10 +11 +-11 +9 +-10 +10 +-10 +14 +9 +-16 +11 +-11 +10 +-9 +7 +-10 +9 +-8 +9 +-11 +9 +-11 +11 +-10 +8 +-10 +10 +-10 +9 +-11 +11 +-9 +9 +-11 +9 +-11 +9 +-9 +10 +-13 +-9 +13 +-8 +10 +-10 +11 +-9 +11 +-8 +10 +-9 +9 +-9 +11 +-10 +11 +-9 +10 +-7 +10 +-10 +11 +-9 +11 +-10 +10 +-10 +10 +-10 +12 +-9 +12 +-9 +12 +-9 +12 +-8 +11 +-10 +11 +-10 +10 +-11 +10 +-9 +10 +-11 +10 +-10 +10 +-11 +11 +-9 +11 +-11 +9 +-10 +10 +-11 +10 +-12 +10 +-10 +9 +-10 +10 +-9 +11 +-10 +8 +-10 +10 +-10 +10 +-11 +10 +-11 +11 +-9 +8 +-11 +12 +-11 +12 +-9 +10 +-9 +10 +-11 +11 +-9 +11 +-11 +13 +-8 +14 +9 +-15 +10 +-11 +9 +-11 +9 +-10 +9 +-11 +9 +-11 +9 +-10 +8 +-10 +10 +-10 +10 +-9 +10 +-10 +10 +-10 +10 +-11 +10 +-10 +9 +-11 +11 +-9 +8 +-10 +9 +-10 +9 +-9 +9 +-8 +11 +-9 +8 +-10 +11 +-12 +9 +-11 +10 +-9 +10 +-10 +9 +-9 +11 +-9 +11 +-8 +9 +-10 +9 +-9 +10 +-12 +-8 +14 +-8 +10 +-8 +11 +-9 +11 +-9 +10 +-8 +11 +-8 +11 +-9 +11 +-9 +10 +-10 +10 +-11 +9 +-9 +11 +-9 +12 +-9 +10 +-10 +11 +-8 +9 +-9 +11 +-9 +9 +-8 +11 +-9 +10 +-10 +10 +-11 +10 +-9 +10 +-9 +10 +-10 +12 +-9 +11 +-9 +11 +-9 +10 +-9 +11 +-10 +9 +-11 +10 +-10 +11 +-11 +10 +-10 +10 +-9 +11 +-10 +10 +-10 +10 +-11 +10 +-10 +10 +-10 +9 +-10 +11 +-9 +11 +-10 +12 +-9 +10 +-10 +11 +-9 +11 +-9 +12 +-9 +12 +-10 +12 +-9 +10 +-10 +11 +-10 +10 +-10 +12 +-10 +10 +-11 +9 +-12 +10 +-9 +10 +-11 +11 +-10 +8 +-10 +10 +-10 +11 +-11 +10 +-9 +9 +-11 +11 +-9 +9 +-9 +11 +-10 +10 +-10 +10 +-11 +11 +-9 +9 +-10 +10 +-8 +10 +-10 +11 +-10 +11 +-8 +10 +-11 +11 +-11 +11 +-9 +13 +-9 +11 +-9 +11 +-9 +12 +-10 +12 +-9 +11 +-10 +10 +-10 +9 +-9 +12 +-9 +9 +-10 +11 +-10 +10 +-11 +11 +-11 +10 +-10 +11 +-11 +10 +-9 +11 +-10 +10 +-11 +14 +10 +-16 +10 +-10 +10 +-11 +12 +-10 +11 +-9 +9 +-10 +9 +-10 +9 +-10 +9 +-9 +8 +-11 +9 +-8 +7 +-11 +9 +-11 +9 +-11 +9 +-9 +9 +-11 +8 +-11 +11 +-10 +10 +-8 +9 +-9 +10 +-9 +10 +-9 +10 +-10 +10 +-9 +10 +-11 +9 +-9 +9 +-10 +10 +-9 +9 +-9 +11 +-10 +10 +-11 +10 +-12 +-9 +12 +-7 +10 +-10 +13 +-10 +9 +-9 +11 +-8 +11 +-9 +12 +-9 +10 +-10 +10 +-10 +11 +-10 +9 +-10 +10 +-9 +12 +-9 +11 +-9 +11 +-9 +12 +-9 +9 +-10 +11 +-10 +10 +-11 +10 +-10 +11 +-9 +11 +-9 +10 +-9 +12 +-10 +11 +-10 +12 +-9 +11 +-11 +10 +-10 +10 +-11 +11 +-10 +10 +-9 +8 +-10 +11 +-11 +10 +-9 +9 +-11 +9 +-11 +9 +-11 +10 +-9 +9 +-10 +9 +-10 +10 +-11 +12 +-10 +9 +-11 +10 +-10 +12 +-9 +10 +-11 +11 +-9 +12 +-9 +9 +-10 +12 +-10 +10 +-10 +10 +-10 +10 +-11 +8 +-10 +10 +-9 +10 +-11 +9 +-9 +11 +-10 +9 +-11 +11 +-10 +10 +-10 +9 +-10 +11 +-11 +10 +-12 +11 +-9 +13 +-10 +12 +-10 +11 +-10 +13 +-11 +9 +-10 +12 +-10 +10 +-11 +11 +-10 +10 +-10 +9 +-10 +11 +-9 +11 +-11 +11 +-10 +9 +-10 +14 +9 +-15 +11 +-12 +9 +-8 +8 +-10 +9 +-7 +10 +-9 +10 +-9 +9 +-10 +10 +-10 +10 +-9 +9 +-10 +10 +-11 +11 +-10 +9 +-10 +9 +-10 +9 +-10 +9 +-9 +8 +-8 +10 +-10 +10 +-9 +11 +-9 +10 +-11 +10 +-10 +10 +-8 +9 +-11 +11 +-9 +9 +-8 +9 +-9 +10 +-9 +9 +-8 +9 +-10 +11 +-12 +-8 +14 +-6 +9 +-11 +11 +-10 +10 +-10 +11 +-9 +10 +-10 +10 +-10 +10 +-7 +9 +-9 +12 +-11 +10 +-8 +11 +-9 +11 +-9 +11 +-9 +10 +-9 +14 +9 +-15 +9 +-11 +10 +-12 +9 +-8 +10 +-10 +10 +-10 +9 +-10 +9 +-9 +10 +-9 +10 +-10 +10 +-10 +10 +-10 +11 +-10 +12 +-9 +11 +-8 +7 +-12 +-7 +13 +-7 +10 +-9 +12 +-8 +10 +-9 +11 +-9 +8 +-10 +11 +-9 +10 +-9 +11 +-9 +10 +-10 +10 +-10 +11 +-10 +11 +-12 +11 +-10 +10 +-11 +10 +-11 +12 +-10 +12 +-9 +9 +-11 +11 +-10 +12 +-9 +10 +-10 +9 +-10 +11 +-11 +11 +-10 +9 +-10 +9 +-9 +10 +-9 +11 +-10 +11 +-10 +9 +-10 +9 +-10 +12 +-10 +10 +-9 +10 +-9 +11 +-10 +10 +-11 +11 +-10 +10 +-10 +12 +-10 +9 +-10 +10 +-10 +10 +-10 +11 +-11 +11 +-9 +11 +-10 +12 +-11 +11 +-11 +11 +-9 +8 +-9 +10 +-9 +11 +-11 +11 +-9 +10 +-10 +10 +-10 +10 +-11 +11 +-11 +10 +-10 +12 +-10 +11 +-9 +9 +-12 +12 +-9 +10 +-10 +11 +-11 +9 +-10 +12 +-10 +12 +-10 +12 +-9 +10 +-10 +11 +-11 +9 +-10 +9 +-10 +12 +-10 +10 +-11 +11 +-9 +10 +-10 +8 +-11 +11 +-11 +11 +-10 +10 +-8 +11 +-11 +12 +-10 +11 +-10 +10 +-11 +13 +-9 +9 +-10 +12 +-11 +12 +-11 +11 +-9 +10 +-9 +11 +-9 +10 +-9 +13 +-11 +11 +-10 +12 +-8 +11 +-10 +12 +-10 +11 +-10 +11 +-10 +10 +-10 +10 +-11 +10 +-11 +11 +-10 +9 +-11 +12 +-10 +10 +-9 +11 +-9 +9 +-9 +10 +-9 +10 +-10 +10 +-10 +10 +-11 +8 +-10 +10 +-9 +10 +-9 +12 +-9 +10 +-9 +10 +-9 +10 +-10 +10 +-11 +11 +-9 +10 +-10 +11 +-10 +12 +-9 +10 +-10 +12 +-9 +11 +-10 +10 +-9 +10 +-11 +10 +-11 +10 +-10 +10 +-10 +11 +-11 +8 +-10 +10 +-11 +12 +-11 +9 +-10 +11 +-11 +10 +-11 +8 +-11 +10 +-9 +11 +-12 +10 +-11 +12 +-11 +11 +-9 +11 +-9 +11 +-12 +12 +-11 +10 +-10 +10 +-10 +10 +-10 +9 +-9 +8 +-12 +12 +-10 +11 +-11 +10 +-11 +11 +-11 +13 +-9 +9 +-10 +10 +-11 +11 +-10 +11 +-10 +9 +-11 +11 +-11 +12 +-10 +10 +-10 +9 +-10 +11 +-9 +10 +-10 +10 +-11 +10 +-11 +10 +-10 +9 +-10 +11 +-10 +10 +-11 +11 +-10 +11 +-9 +10 +-9 +9 +-10 +11 +-11 +10 +-9 +9 +-10 +12 +-9 +10 +-10 +10 +-11 +10 +-11 +10 +-10 +11 +-10 +12 +-10 +11 +-10 +9 +-9 +10 +-10 +10 +-9 +10 +-8 +11 +-9 +10 +-10 +10 +-10 +11 +-10 +11 +-10 +9 +-10 +9 +-11 +10 +-10 +9 +-11 +10 +-11 +9 +-10 +10 +-11 +11 +-11 +10 +-9 +12 +-11 +13 +-8 +11 +-8 +11 +-9 +11 +-8 +11 +-9 +12 +-10 +10 +-8 +12 +-9 +9 +-11 +12 +-8 +9 +-10 +10 +-10 +10 +-9 +12 +-11 +11 +-10 +10 +-10 +11 +-10 +10 +-11 +10 +-10 +10 +-10 +11 +-10 +10 +-9 +11 +-11 +11 +-11 +9 +-10 +10 +-10 +9 +-11 +11 +-8 +10 +-10 +10 +-10 +11 +-10 +11 +-11 +12 +-11 +10 +-12 +11 +-11 +10 +-11 +10 +-11 +10 +-10 +10 +-11 +11 +-10 +11 +-8 +10 +-10 +10 +-11 +10 +-9 +9 +-10 +10 +-10 +10 +-11 +11 +-10 +10 +-9 +11 +-11 +10 +-9 +9 +-9 +10 +-9 +11 +-9 +10 +-10 +11 +-11 +11 +-10 +10 +-10 +9 +-11 +11 +-10 +12 +-9 +11 +-10 +11 +-9 +11 +-9 +9 +-10 +11 +-10 +11 +-10 +10 +-10 +10 +-10 +9 +-9 +10 +-10 +10 +-10 +11 +-11 +11 +-9 +10 +-10 +10 +-11 +10 +-9 +11 +-11 +10 +-10 +11 +-11 +12 +-11 +10 +-11 +11 +-9 +10 +-9 +10 +-10 +12 +-8 +10 +-11 +11 +-9 +11 +-11 +9 +-9 +12 +-10 +11 +-10 +10 +-11 +11 +-11 +10 +-10 +11 +-10 +12 +-9 +9 +-9 +11 +-9 +10 +-9 +11 +-10 +11 +-10 +11 +-9 +10 +-10 +12 +-8 +10 +-10 +10 +-10 +10 +-9 +9 +-11 +10 +-11 +10 +-10 +12 +-9 +10 +-9 +11 +-11 +9 +-9 +11 +-10 +10 +-11 +12 +-10 +10 +-11 +13 +-10 +10 +-9 +11 +-9 +11 +-10 +10 +-10 +13 +-10 +11 +-8 +10 +-10 +11 +-10 +10 +-10 +10 +-10 +10 +-11 +9 +-9 +10 +-11 +8 +-10 +10 +-11 +10 +-10 +11 +-10 +9 +-11 +10 +-11 +10 +-10 +11 +-10 +10 +-10 +10 +-10 +9 +-9 +10 +-10 +12 +-10 +11 +-10 +9 +-10 +11 +-10 +9 +-9 +10 +-10 +11 +-11 +10 +-10 +11 +-12 +12 +-10 +12 +-12 +10 +-10 +11 +-9 +9 +-10 +11 +-9 +10 +-10 +11 +-9 +10 +-9 +11 +-9 +11 +-10 +11 +-10 +10 +-9 +10 +-10 +11 +-12 +11 +-10 +10 +-10 +10 +-11 +10 +-10 +9 +-10 +10 +-11 +11 +-10 +10 +-10 +11 +-10 +12 +-9 +11 +-10 +10 +-9 +11 +-12 +11 +-9 +10 +-9 +9 +-9 +11 +-10 +10 +-10 +10 +-9 +10 +-10 +11 +-10 +11 +-9 +9 +-11 +10 +-12 +11 +-11 +11 +-11 +10 +-11 +10 +-11 +9 +-10 +11 +-11 +10 +-10 +12 +-11 +11 +-12 +11 +-10 +10 +-10 +9 +-8 +11 +-9 +11 +-11 +11 +-10 +12 +-10 +10 +-9 +10 +-11 +12 +-10 +11 +-10 +13 +-11 +10 +-8 +12 +-10 +12 +-9 +11 +-7 +10 +-9 +12 +-10 +11 +-10 +11 +-12 +11 +-10 +11 +-10 +10 +-10 +8 +-10 +10 +-11 +10 +-11 +10 +-10 +8 +-10 +9 +-11 +11 +-10 +11 +-12 +11 +-12 +10 +-10 +11 +-9 +13 +-10 +10 +-9 +10 +-10 +11 +-10 +11 +-10 +10 +-10 +12 +-8 +10 +-10 +12 +-10 +9 +-10 +12 +-10 +10 +-9 +11 +-11 +10 +-9 +13 +-9 +9 +-11 +11 +-10 +10 +-13 +14 +9 +-14 +11 +-11 +8 +-9 +12 +-12 +8 +-11 +8 +-12 +9 +-9 +9 +-11 +10 +-11 +10 +-11 +9 +-10 +10 +-9 +7 +-9 +11 +-8 +11 +-9 +12 +-10 +11 +-10 +9 +-9 +9 +-9 +9 +-9 +10 +-8 +9 +-11 +11 +-8 +12 +-9 +10 +-10 +11 +-9 +11 +-10 +10 +-8 +9 +-7 +11 +-10 +9 +-9 +9 +-9 +9 +-9 +10 +-9 +10 +-10 +11 +-8 +9 +-10 +11 +-8 +12 +-9 +9 +-10 +10 +-9 +9 +-10 +12 +-10 +9 +-8 +10 +-10 +11 +-9 +10 +-11 +10 +-11 +-9 +15 +-10 +10 +-9 +12 +-9 +9 +-10 +10 +-8 +11 +-10 +12 +-9 +9 +-11 +12 +-9 +10 +-9 +10 +-9 +12 +-11 +10 +-9 +9 +-10 +12 +-10 +12 +-10 +9 +-10 +10 +-10 +12 +-11 +11 +-11 +11 +-11 +10 +-11 +9 +-11 +10 +-10 +10 +-9 +10 +-11 +10 +-9 +11 +-10 +12 +-11 +10 +-11 +10 +-10 +10 +-11 +9 +-11 +10 +-9 +11 +-9 +10 +-10 +10 +-9 +11 +-9 +11 +-10 +10 +-9 +11 +-8 +11 +-10 +11 +-9 +10 +-9 +10 +-8 +12 +-11 +10 +-9 +14 +10 +-15 +11 +-10 +11 +-10 +10 +-10 +10 +-9 +9 +-11 +12 +-10 +10 +-7 +9 +-12 +13 +-10 +9 +-9 +10 +-11 +10 +-11 +9 +-9 +8 +-11 +9 +-11 +10 +-11 +9 +-10 +9 +-10 +8 +-10 +9 +-11 +9 +-7 +8 +-10 +10 +-10 +10 +-9 +9 +-9 +10 +-11 +10 +-9 +11 +-10 +11 +-10 +9 +-8 +9 +-12 +-10 +14 +-8 +11 +-9 +10 +-9 +10 +-8 +10 +-9 +12 +-10 +10 +-9 +11 +-10 +12 +-8 +11 +-9 +10 +-8 +11 +-11 +10 +-9 +12 +-8 +10 +-9 +11 +-11 +11 +-11 +9 +-9 +9 +-10 +9 +-11 +10 +-9 +9 +-11 +12 +-9 +12 +-10 +12 +-7 +10 +-9 +12 +-9 +9 +-10 +10 +-10 +10 +-11 +11 +-12 +12 +-10 +10 +-10 +10 +-10 +11 +-11 +9 +-10 +10 +-9 +9 +-9 +11 +-10 +9 +-11 +11 +-12 +10 +-10 +11 +-9 +11 +-9 +13 +-11 +10 +-8 +11 +-10 +10 +-10 +11 +-10 +12 +-10 +10 +-9 +11 +-11 +11 +-9 +11 +-11 +11 +-9 +11 +-10 +11 +-10 +11 +-9 +10 +-10 +12 +-10 +10 +-10 +10 +-8 +9 +-10 +14 +8 +-15 +12 +-10 +9 +-11 +11 +-11 +8 +-11 +10 +-9 +9 +-10 +10 +-9 +9 +-10 +11 +-10 +10 +-8 +8 +-9 +9 +-10 +11 +-10 +10 +-9 +12 +-13 +-9 +15 +-8 +11 +-9 +9 +-10 +11 +-9 +9 +-10 +10 +-10 +10 +-9 +11 +-10 +10 +-11 +9 +-10 +9 +-10 +10 +-10 +10 +-11 +10 +-11 +11 +-11 +11 +-9 +10 +-10 +10 +-10 +10 +-10 +11 +-10 +10 +-11 +13 +-9 +9 +-9 +10 +-10 +10 +-8 +9 +-10 +11 +-9 +11 +-9 +10 +-10 +9 +-9 +11 +-10 +11 +-10 +11 +-10 +9 +-11 +11 +-11 +9 +-9 +10 +-9 +11 +-10 +11 +-10 +11 +-10 +12 +-12 +10 +-10 +12 +-8 +11 +-8 +10 +-11 +12 +-9 +10 +-9 +12 +9 +-15 +11 +-12 +10 +-10 +11 +-10 +10 +-10 +9 +-10 +9 +-10 +10 +-11 +9 +-9 +9 +-10 +10 +-10 +11 +-12 +11 +-10 +8 +-10 +10 +-9 +9 +-10 +8 +-8 +10 +-9 +10 +-9 +10 +-9 +9 +-8 +10 +-11 +11 +-8 +7 +-7 +10 +-8 +11 +-10 +11 +-7 +9 +-9 +10 +-8 +11 +-9 +9 +-10 +11 +-13 +-8 +14 +-9 +10 +-9 +10 +-10 +11 +-10 +10 +-9 +9 +-10 +11 +-10 +9 +-9 +9 +-9 +9 +-10 +9 +-10 +10 +-7 +9 +-10 +11 +-10 +11 +-10 +11 +-10 +10 +-11 +11 +-9 +11 +-11 +10 +-10 +10 +-11 +12 +-10 +8 +-9 +11 +-11 +12 +-9 +12 +-9 +9 +-9 +11 +-9 +10 +-11 +12 +-10 +10 +-10 +10 +-9 +11 +-10 +12 +-10 +11 +-10 +9 +-9 +12 +-8 +10 +-10 +11 +-9 +11 +-9 +10 +-8 +11 +-10 +11 +-10 +10 +-9 +11 +-11 +9 +-11 +10 +-9 +10 +-11 +9 +-11 +11 +-10 +10 +-11 +9 +-11 +10 +-11 +11 +-11 +11 +-11 +10 +-11 +10 +-11 +11 +-10 +10 +-8 +9 +-11 +10 +-9 +10 +-10 +10 +-10 +9 +-9 +10 +-10 +10 +-10 +10 +-9 +11 +-10 +11 +-10 +11 +-10 +10 +-11 +12 +-11 +10 +-10 +11 +-10 +10 +-9 +11 +-9 +11 +-10 +12 +-9 +13 +-11 +11 +-10 +11 +-10 +10 +-10 +10 +-11 +10 +-9 +9 +-11 +10 +-10 +10 +-11 +10 +-10 +10 +-9 +10 +-10 +11 +-10 +10 +-9 +10 +-9 +11 +-10 +10 +-9 +14 +9 +-15 +10 +-12 +11 +-9 +9 +-11 +11 +-9 +10 +-10 +10 +-10 +10 +-10 +11 +-9 +10 +-11 +10 +-9 +11 +-10 +9 +-10 +10 +-9 +9 +-10 +10 +-9 +10 +-10 +10 +-11 +10 +-10 +11 +-9 +9 +-10 +11 +-9 +9 +-9 +8 +-10 +11 +-10 +9 +-11 +9 +-10 +9 +-12 +9 +-9 +9 +-9 +10 +-10 +11 +-12 +-8 +13 +-9 +11 +-10 +9 +-9 +11 +-9 +10 +-9 +10 +-8 +9 +-10 +12 +-9 +11 +-9 +9 +-9 +11 +-9 +12 +-10 +12 +-10 +11 +-10 +11 +-9 +11 +-10 +12 +-9 +10 +-11 +11 +-8 +9 +-9 +11 +-9 +11 +-10 +10 +-9 +10 +-10 +10 +-11 +12 +-10 +11 +-11 +10 +-10 +10 +-11 +10 +-12 +10 +-11 +9 +-11 +11 +-9 +10 +-9 +11 +-10 +10 +-10 +10 +-9 +8 +-10 +10 +-11 +9 +-10 +10 +-10 +11 +-11 +10 +-10 +10 +-11 +11 +-12 +10 +-10 +11 +-10 +10 +-10 +11 +-10 +11 +-9 +12 +-9 +12 +-9 +12 +-8 +9 +-9 +13 +-9 +12 +-8 +9 +-10 +11 +-10 +10 +-8 +9 +-9 +9 +-9 +12 +-10 +10 +-10 +10 +-11 +10 +-9 +11 +-12 +11 +-11 +9 +-11 +10 +-11 +9 +-11 +10 +-10 +10 +-10 +10 +-10 +10 +-10 +9 +-11 +10 +-12 +12 +-11 +11 +-10 +12 +-10 +16 +7 +-15 +11 +-11 +11 +-10 +10 +-10 +10 +-10 +9 +-11 +9 +-10 +11 +-11 +9 +-8 +8 +-10 +9 +-10 +10 +-9 +9 +-9 +9 +-11 +10 +-11 +8 +-10 +9 +-10 +9 +-10 +9 +-9 +9 +-10 +8 +-11 +10 +-10 +9 +-10 +9 +-9 +11 +-9 +8 +-9 +10 +-7 +11 +-8 +10 +-10 +11 +-9 +10 +-9 +9 +-12 +-8 +13 +-8 +11 +-9 +11 +-8 +11 +-9 +12 +-9 +12 +-9 +13 +-10 +11 +-9 +10 +-8 +11 +-10 +10 +-9 +11 +-11 +10 +-11 +10 +-10 +9 +-11 +13 +10 +-15 +10 +-11 +9 +-10 +8 +-10 +9 +-10 +8 +-10 +9 +-9 +8 +-10 +10 +-11 +10 +-10 +8 +-10 +9 +-10 +10 +-10 +8 +-9 +10 +-9 +11 +-12 +-9 +16 +-7 +10 +-10 +11 +-9 +10 +-10 +10 +-10 +10 +-9 +11 +-8 +12 +-9 +13 +-8 +12 +-9 +11 +-9 +11 +-8 +11 +-8 +12 +-11 +11 +-9 +10 +-10 +10 +-9 +9 +-11 +12 +-10 +8 +-10 +9 +-10 +10 +-10 +10 +-10 +8 +-8 +9 +-10 +10 +-10 +11 +-9 +10 +-9 +11 +-10 +12 +-8 +9 +-8 +10 +-11 +10 +-9 +9 +-9 +10 +-11 +12 +-9 +12 +-10 +12 +-10 +12 +-10 +12 +-10 +12 +-9 +10 +-11 +11 +-11 +9 +-10 +10 +-11 +10 +-11 +10 +-10 +11 +-10 +11 +-10 +10 +-10 +10 +-9 +13 +-11 +10 +-11 +10 +-11 +11 +-11 +9 +-10 +11 +-9 +9 +-11 +12 +-9 +11 +-9 +12 +-12 +11 +-10 +11 +-10 +12 +-10 +11 +-8 +9 +-10 +11 +-9 +11 +-9 +12 +-9 +12 +-9 +10 +-9 +10 +-10 +13 +-11 +10 +-10 +10 +-10 +11 +-11 +10 +-10 +10 +-10 +10 +-11 +10 +-10 +9 +-11 +10 +-11 +9 +-11 +10 +-10 +10 +-11 +11 +-11 +9 +-11 +11 +-11 +10 +-11 +9 +-10 +10 +-10 +10 +-10 +9 +-9 +11 +-11 +12 +-9 +11 +-10 +9 +-10 +11 +-11 +11 +-10 +10 +-10 +11 +-10 +10 +-10 +10 +-10 +10 +-9 +10 +-10 +10 +-10 +11 +-10 +10 +-10 +8 +-10 +10 +-9 +11 +-9 +12 +-11 +12 +-11 +11 +-11 +10 +-11 +10 +-11 +11 +-10 +11 +-9 +11 +-11 +10 +-10 +9 +-11 +9 +-11 +11 +-11 +10 +-12 +10 +-12 +9 +-10 +11 +-11 +11 +-9 +11 +-9 +10 +-10 +10 +-9 +10 +-10 +10 +-10 +11 +-10 +10 +-9 +10 +-10 +10 +-9 +11 +-11 +11 +-9 +10 +-10 +11 +-10 +11 +-9 +11 +-9 +10 +-11 +10 +-10 +10 +-9 +11 +-10 +10 +-10 +11 +-11 +10 +-11 +10 +-10 +11 +-10 +9 +-10 +10 +-9 +11 +-12 +9 +-9 +11 +-10 +12 +-10 +9 +-9 +12 +-9 +9 +-12 +13 +-10 +10 +-11 +11 +-9 +12 +-11 +10 +-8 +10 +-13 +10 +-9 +10 +-11 +11 +-10 +9 +-10 +12 +-8 +10 +-9 +11 +-10 +12 +-8 +12 +-8 +9 +-9 +11 +-10 +12 +-8 +10 +-8 +10 +-11 +12 +-10 +9 +-9 +9 +-10 +11 +-10 +10 +-10 +12 +-11 +10 +-11 +12 +-10 +10 +-10 +13 +-11 +9 +-10 +11 +-10 +10 +-8 +10 +-10 +11 +-10 +11 +-11 +10 +-10 +9 +-12 +11 +-12 +10 +-10 +11 +-10 +9 +-10 +10 +-10 +11 +-11 +11 +-10 +11 +-10 +12 +-10 +10 +-9 +10 +-11 +10 +-10 +10 +-10 +10 +-11 +10 +-11 +10 +-9 +10 +-10 +11 +-9 +9 +-11 +11 +-11 +11 +-8 +8 +-10 +11 +-10 +11 +-8 +11 +-10 +11 +-9 +11 +-8 +9 +-11 +12 +-10 +10 +-10 +10 +-8 +11 +-11 +11 +-10 +10 +-9 +11 +-9 +12 +-10 +9 +-11 +11 +-11 +10 +-10 +11 +-11 +11 +-10 +9 +-11 +11 +-11 +11 +-9 +8 +-9 +10 +-10 +11 +-10 +10 +-10 +10 +-11 +12 +-10 +12 +-9 +11 +-10 +11 +-9 +11 +-11 +10 +-11 +12 +-11 +10 +-10 +10 +-11 +10 +-11 +10 +-10 +10 +-10 +11 +-11 +10 +-9 +10 +-9 +11 +-10 +10 +-9 +11 +-9 +12 +-11 +11 +-10 +12 +-9 +10 +-9 +10 +-9 +11 +-10 +13 +-8 +8 +-11 +11 +-9 +11 +-11 +9 +-12 +11 +-9 +11 +-12 +9 +-9 +9 +-10 +11 +-11 +10 +-10 +10 +-11 +9 +-12 +12 +-11 +10 +-9 +10 +-9 +11 +-9 +10 +-10 +9 +-9 +10 +-11 +12 +-10 +10 +-9 +10 +-11 +10 +-10 +9 +-10 +10 +-11 +12 +-11 +11 +-10 +10 +-9 +11 +-10 +10 +-8 +10 +-10 +12 +-10 +11 +-9 +11 +-10 +9 +-11 +9 +-10 +10 +-9 +9 +-11 +12 +-10 +11 +-10 +12 +-9 +11 +-8 +10 +-9 +10 +-10 +11 +-11 +11 +-9 +10 +-10 +11 +-10 +11 +-10 +11 +-9 +11 +-11 +11 +-10 +10 +-10 +10 +-11 +11 +-12 +11 +-9 +9 +-10 +9 +-11 +12 +-10 +9 +-11 +10 +-10 +11 +-10 +10 +-12 +10 +-11 +10 +-11 +9 +-11 +10 +-14 +12 +-11 +11 +-10 +8 +-10 +12 +-11 +11 +-8 +11 +-9 +12 +-9 +12 +-10 +11 +-8 +12 +-9 +11 +-10 +10 +-9 +10 +-10 +11 +-10 +10 +-10 +10 +-10 +12 +-9 +12 +-11 +10 +-11 +12 +-10 +9 +-9 +9 +-11 +10 +-11 +10 +-11 +10 +-10 +11 +-9 +9 +-11 +11 +-11 +11 +-11 +10 +-9 +11 +-9 +11 +-8 +13 +-10 +10 +-11 +11 +-11 +11 +-10 +9 +-11 +12 +-10 +10 +-10 +9 +-11 +10 +-11 +10 +-10 +8 +-11 +10 +-11 +12 +-11 +11 +-11 +12 +-9 +8 +-8 +9 +-11 +12 +-10 +12 +-9 +12 +-10 +11 +-8 +11 +-9 +11 +-9 +12 +-9 +10 +-9 +10 +-10 +11 +-8 +11 +-9 +9 +-9 +10 +-10 +11 +-11 +10 +-11 +11 +-11 +10 +-10 +11 +-10 +10 +-9 +10 +-10 +9 +-10 +10 +-9 +11 +-11 +11 +-11 +9 +-9 +10 +-10 +11 +-10 +10 +-9 +10 +-11 +10 +-10 +9 +-10 +9 +-10 +10 +-11 +10 +-9 +10 +-9 +11 +-10 +9 +-11 +12 +-9 +10 +-8 +11 +-10 +12 +-9 +11 +-8 +12 +-10 +11 +-10 +10 +-9 +14 +-11 +11 +-12 +11 +-9 +11 +-11 +10 +-9 +11 +-11 +10 +-10 +11 +-10 +11 +-10 +10 +-9 +12 +-9 +10 +-10 +11 +-10 +10 +-9 +12 +-9 +11 +-9 +10 +-9 +9 +-10 +11 +-11 +12 +-10 +11 +-9 +10 +-10 +11 +-11 +10 +-11 +10 +-8 +9 +-11 +11 +-10 +11 +-12 +10 +-11 +13 +11 +-15 +9 +-10 +8 +-10 +9 +-13 +12 +-9 +9 +-10 +10 +-11 +8 +-11 +8 +-9 +9 +-11 +9 +-9 +10 +-10 +10 +-10 +11 +-9 +10 +-10 +10 +-10 +10 +-9 +10 +-8 +9 +-12 +10 +-9 +10 +-8 +9 +-9 +11 +-10 +11 +-9 +10 +-9 +10 +-10 +9 +-9 +10 +-8 +9 +-10 +9 +-8 +10 +-8 +8 +-10 +10 +-10 +11 +-9 +10 +-8 +9 +-10 +10 +-10 +10 +-10 +9 +-10 +9 +-8 +9 +-10 +11 +-10 +10 +-10 +8 +-9 +9 +-9 +9 +-9 +11 +-9 +10 +-12 +-8 +14 +-8 +12 +-8 +11 +-7 +12 +-9 +11 +-8 +10 +-9 +11 +-9 +10 +-9 +10 +-10 +11 +-9 +11 +-10 +9 +-9 +10 +-9 +10 +-8 +8 +-10 +10 +-10 +11 +-10 +11 +-11 +10 +-10 +11 +-11 +11 +-10 +10 +-9 +10 +-10 +10 +-9 +11 +-9 +10 +-10 +11 +-10 +11 +-10 +13 +-10 +10 +-10 +11 +-10 +10 +-11 +11 +-10 +10 +-11 +10 +-10 +9 +-10 +10 +-10 +11 +-10 +9 +-10 +10 +-11 +11 +-10 +11 +-9 +9 +-10 +10 +-11 +12 +-11 +11 +-9 +9 +-10 +14 +11 +-14 +11 +-10 +12 +-11 +11 +-10 +9 +-11 +12 +-10 +10 +-10 +9 +-11 +10 +-11 +8 +-10 +11 +-11 +10 +-11 +8 +-10 +10 +-10 +11 +-10 +8 +-9 +11 +-10 +11 +-10 +8 +-9 +10 +-9 +8 +-9 +10 +-10 +9 +-11 +9 +-10 +10 +-11 +11 +-10 +11 +-7 +10 +-9 +11 +-9 +11 +-8 +9 +-10 +11 +-13 +-7 +15 +-8 +11 +-10 +11 +-9 +9 +-9 +10 +-11 +12 +-11 +9 +-9 +8 +-9 +10 +-9 +10 +-10 +12 +-8 +10 +-9 +10 +-9 +10 +-10 +11 +-10 +11 +-8 +10 +-9 +12 +-10 +13 +-12 +12 +-9 +10 +-10 +9 +-10 +11 +-11 +11 +-9 +10 +-11 +11 +-10 +11 +-9 +10 +-9 +11 +-10 +11 +-10 +10 +-11 +9 +-10 +11 +-12 +11 +-10 +9 +-11 +11 +-11 +11 +-9 +12 +-9 +12 +-9 +10 +-9 +10 +-9 +11 +-11 +10 +-9 +10 +-9 +9 +-10 +11 +-10 +10 +-10 +9 +-11 +12 +-11 +10 +-11 +10 +-9 +10 +-9 +11 +-9 +12 +-11 +10 +-11 +10 +-10 +11 +-9 +9 +-8 +9 +-10 +13 +-10 +10 +-11 +11 +-10 +10 +-10 +13 +9 +-14 +10 +-11 +10 +-10 +11 +-9 +8 +-11 +9 +-10 +9 +-9 +10 +-10 +11 +-10 +9 +-10 +9 +-9 +10 +-11 +10 +-9 +10 +-9 +8 +-10 +10 +-14 +-10 +13 +-8 +10 +-10 +10 +-9 +12 +-10 +9 +-8 +8 +-8 +11 +-9 +12 +-8 +9 +-8 +11 +-8 +10 +-10 +9 +-10 +12 +-10 +9 +-9 +10 +-8 +12 +-9 +11 +-10 +12 +-10 +10 +-11 +10 +-10 +10 +-8 +11 +-13 +11 +-10 +9 +-9 +11 +-11 +10 +-10 +10 +-11 +11 +-10 +12 +-11 +10 +-10 +12 +-9 +11 +-8 +8 +-11 +12 +-10 +10 +-11 +11 +-11 +9 +-10 +9 +-11 +9 +-10 +8 +-9 +9 +-10 +11 +-11 +10 +-10 +9 +-11 +11 +-10 +12 +-9 +10 +-10 +14 +9 +-15 +11 +-10 +9 +-10 +9 +-11 +9 +-9 +9 +-10 +10 +-9 +10 +-10 +10 +-9 +9 +-8 +11 +-10 +12 +-10 +10 +-8 +9 +-10 +9 +-9 +8 +-8 +11 +-9 +8 +-8 +8 +-9 +9 +-10 +11 +-9 +10 +-9 +9 +-10 +9 +-10 +9 +-10 +9 +-9 +9 +-9 +9 +-10 +10 +-10 +9 +-9 +10 +-9 +11 +-13 +-7 +14 +-8 +11 +-8 +13 +-9 +11 +-7 +12 +-9 +9 +-9 +10 +-11 +11 +-9 +10 +-10 +11 +-10 +11 +-11 +10 +-11 +11 +-10 +11 +-9 +10 +-9 +10 +-10 +11 +-10 +10 +-10 +11 +-11 +10 +-10 +10 +-10 +9 +-11 +12 +-10 +9 +-10 +11 +-10 +12 +-11 +12 +-9 +11 +-10 +9 +-11 +10 +-11 +10 +-12 +10 +-10 +10 +-9 +8 +-11 +11 +-9 +10 +-9 +10 +-10 +10 +-9 +10 +-10 +11 +-10 +12 +-10 +9 +-10 +13 +-10 +11 +-9 +11 +-9 +12 +-9 +11 +-10 +10 +-10 +10 +-10 +11 +-9 +9 +-10 +11 +-10 +10 +-9 +9 +-11 +12 +-10 +11 +-9 +10 +-9 +10 +-10 +10 +-11 +11 +-11 +10 +-10 +9 +-11 +10 +-11 +9 +-9 +9 +-12 +10 +-10 +11 +-11 +10 +-11 +12 +-9 +10 +-12 +10 +-9 +11 +-10 +11 +-10 +12 +-9 +11 +-10 +11 +-9 +11 +-11 +11 +-10 +10 +-11 +11 +-10 +10 +-10 +11 +-10 +10 +-9 +11 +-9 +10 +-8 +11 +-10 +12 +-8 +12 +-9 +11 +-10 +11 +-11 +12 +-9 +12 +-12 +11 +-10 +10 +-12 +11 +-10 +12 +9 +-16 +9 +-10 +7 +-12 +9 +-10 +9 +-10 +9 +-12 +9 +-8 +10 +-10 +9 +-9 +12 +-10 +11 +-9 +11 +-10 +9 +-9 +11 +-9 +9 +-10 +9 +-10 +10 +-10 +9 +-9 +8 +-11 +10 +-9 +9 +-10 +9 +-11 +9 +-8 +9 +-10 +11 +-10 +11 +-8 +9 +-9 +11 +-9 +10 +-9 +9 +-9 +10 +-9 +11 +-13 +-8 +14 +-7 +11 +-8 +11 +-8 +10 +-9 +9 +-9 +10 +-10 +11 +-10 +10 +-10 +10 +-10 +11 +-10 +9 +-11 +10 +-10 +11 +-8 +10 +-10 +10 +-10 +9 +-9 +11 +-9 +12 +-9 +9 +-8 +11 +-10 +10 +-10 +9 +-9 +11 +-10 +12 +-10 +12 +-8 +11 +-9 +10 +-9 +9 +-10 +12 +-8 +9 +-9 +11 +-9 +12 +-8 +11 +-8 +9 +-9 +11 +-9 +11 +-10 +10 +-10 +10 +-10 +11 +-11 +8 +-12 +11 +-10 +10 +-11 +10 +-9 +10 +-9 +10 +-11 +11 +-12 +8 +-11 +12 +-11 +10 +-9 +10 +-10 +9 +-11 +10 +-11 +12 +-11 +11 +-9 +11 +-10 +10 +-9 +11 +-8 +12 +-10 +10 +-9 +10 +-8 +9 +-11 +12 +-9 +11 +-11 +9 +-10 +10 +-10 +10 +-11 +10 +-11 +11 +-11 +8 +-10 +8 +-10 +13 +-10 +11 +-10 +10 +-9 +11 +-10 +12 +-11 +9 +-10 +11 +-9 +9 +-10 +12 +-11 +13 +9 +-18 +10 +-10 +8 +-11 +10 +-10 +10 +-10 +11 +-9 +9 +-11 +11 +-11 +10 +-9 +10 +-10 +11 +-10 +11 +-11 +9 +-9 +11 +-10 +10 +-9 +10 +-10 +11 +-8 +11 +-9 +10 +-11 +10 +-9 +9 +-10 +12 +-10 +11 +-8 +9 +-9 +12 +-9 +11 +-10 +9 +-9 +10 +-10 +10 +-10 +9 +-11 +10 +-9 +9 +-13 +-8 +13 +-8 +11 +-9 +11 +-7 +10 +-10 +11 +-9 +10 +-9 +11 +-9 +10 +-9 +9 +-8 +11 +-10 +11 +-9 +11 +-9 +10 +-9 +10 +-10 +11 +-9 +12 +10 +-14 +9 +-10 +10 +-11 +9 +-9 +8 +-12 +10 +-10 +9 +-7 +8 +-10 +10 +-11 +9 +-9 +7 +-11 +10 +-11 +8 +-9 +10 +-9 +11 +-9 +11 +-13 +-8 +14 +-8 +9 +-9 +11 +-11 +9 +-10 +10 +-9 +11 +-10 +9 +-9 +9 +-9 +11 +-9 +12 +-9 +9 +-11 +11 +-10 +10 +-9 +10 +-9 +12 +-9 +11 +-9 +10 +-10 +11 +-9 +10 +-9 +10 +-9 +12 +-9 +10 +-8 +11 +-9 +11 +-10 +10 +-9 +11 +-11 +10 +-11 +11 +-11 +9 +-10 +10 +-10 +10 +-10 +11 +-11 +11 +-10 +11 +-9 +9 +-11 +11 +-11 +10 +-10 +10 +-10 +11 +-10 +12 +-10 +10 +-11 +11 +-10 +10 +-11 +10 +-12 +11 +-11 +9 +-10 +9 +-11 +11 +-9 +10 +-10 +11 +-11 +11 +-9 +10 +-11 +10 +-10 +10 +-11 +12 +-9 +10 +-10 +12 +-9 +10 +-10 +10 +-9 +10 +-8 +11 +-10 +10 +-8 +9 +-9 +11 +-9 +11 +-9 +10 +-9 +11 +-10 +10 +-10 +12 +-9 +9 +-10 +11 +-10 +9 +-10 +11 +-8 +9 +-11 +9 +-9 +9 +-11 +10 +-10 +11 +-11 +8 +-10 +9 +-11 +12 +-12 +12 +-10 +11 +-10 +10 +-9 +10 +-9 +9 +-8 +11 +-9 +11 +-10 +10 +-11 +10 +-9 +7 +-11 +10 +-11 +9 +-10 +10 +-11 +12 +-11 +10 +-9 +9 +-11 +10 +-9 +11 +-10 +11 +-9 +9 +-9 +10 +-9 +11 +-9 +12 +-10 +12 +-9 +12 +-9 +12 +-11 +10 +-10 +13 +-9 +11 +-10 +12 +-9 +10 +-8 +9 +-9 +11 +-10 +10 +-9 +10 +-10 +11 +-10 +10 +-10 +9 +-11 +9 +-9 +8 +-11 +11 +-10 +11 +-9 +10 +-10 +11 +-10 +11 +-11 +10 +-10 +10 +-10 +10 +-10 +11 +-11 +11 +-11 +10 +-11 +10 +-10 +11 +-11 +10 +-10 +10 +-11 +11 +-11 +11 +-9 +11 +-11 +12 +-10 +12 +-8 +10 +-9 +12 +-10 +10 +-10 +11 +-9 +11 +-9 +9 +-11 +10 +-11 +9 +-10 +9 +-11 +11 +-10 +11 +-10 +11 +-10 +11 +-10 +10 +-10 +10 +-11 +9 +-9 +10 +-10 +11 +-9 +11 +-8 +12 +-10 +11 +-9 +9 +-10 +10 +-10 +11 +-9 +11 +-10 +11 +-10 +10 +-10 +10 +-10 +9 +-9 +10 +-11 +11 +-11 +10 +-12 +10 +-11 +10 +-10 +11 +-10 +10 +-9 +11 +-12 +10 +-10 +10 +-11 +10 +-11 +10 +-11 +12 +-10 +11 +-9 +12 +-10 +11 +-9 +10 +-12 +11 +-9 +11 +-10 +12 +-10 +11 +-10 +10 +-10 +10 +-10 +10 +-11 +11 +-10 +11 +-10 +10 +-10 +11 +-10 +11 +-10 +11 +-10 +11 +-10 +10 +-11 +11 +-10 +10 +-11 +10 +-10 +10 +-11 +12 +-10 +10 +-9 +9 +-10 +11 +-9 +10 +-10 +10 +-9 +10 +-11 +11 +-11 +10 +-10 +9 +-10 +11 +-11 +11 +-10 +10 +-10 +12 +-9 +10 +-10 +10 +-10 +11 +-9 +10 +-10 +11 +-12 +13 +-10 +10 +-11 +9 +-10 +9 +-11 +10 +-10 +11 +-9 +9 +-9 +11 +-8 +8 +-10 +12 +-9 +10 +-11 +11 +-10 +10 +-9 +11 +-9 +10 +-9 +11 +-9 +10 +-10 +11 +-9 +11 +-10 +11 +-11 +11 +-11 +10 +-10 +10 +-11 +13 +-11 +11 +-9 +9 +-10 +11 +-10 +10 +-11 +11 +-10 +12 +-11 +10 +-10 +10 +-11 +10 +-9 +10 +-11 +11 +-9 +12 +-9 +11 +-11 +11 +-10 +9 +-9 +11 +-9 +11 +-10 +11 +-10 +11 +-9 +9 +-11 +12 +-9 +11 +-9 +10 +-10 +12 +-10 +13 +-10 +11 +-9 +10 +-10 +9 +-10 +9 +-10 +10 +-10 +12 +-10 +12 +-10 +10 +-10 +10 +-9 +10 +-11 +10 +-10 +11 +-9 +11 +-11 +12 +-10 +11 +-10 +11 +-10 +12 +-9 +12 +-10 +10 +-8 +10 +-11 +11 +-10 +10 +-10 +10 +-9 +10 +-9 +12 +-9 +11 +-9 +10 +-9 +10 +-10 +11 +-11 +10 +-10 +10 +-10 +9 +-11 +11 +-11 +11 +-11 +9 +-10 +9 +-11 +11 +-11 +12 +-9 +12 +-10 +10 +-9 +8 +-11 +11 +-11 +11 +-11 +11 +-10 +11 +-11 +10 +-11 +11 +-11 +9 +-10 +9 +-10 +9 +-11 +12 +-11 +10 +-11 +12 +-11 +10 +-9 +11 +-11 +11 +-11 +10 +-10 +10 +-11 +10 +-11 +10 +-11 +11 +-10 +10 +-11 +11 +-10 +11 +-9 +10 +-10 +10 +-10 +11 +-9 +11 +-11 +10 +-10 +10 +-9 +9 +-9 +10 +-9 +10 +-10 +11 +-10 +11 +-10 +11 +-9 +10 +-10 +11 +-11 +11 +-11 +10 +-10 +11 +-11 +11 +-10 +10 +-10 +11 +-11 +9 +-10 +11 +-10 +11 +-11 +10 +-10 +11 +-10 +8 +-10 +11 +-9 +9 +-11 +11 +-10 +11 +-11 +10 +-10 +11 +-12 +10 +-10 +10 +-10 +9 +-11 +11 +-8 +11 +-11 +11 +-9 +11 +-9 +11 +-9 +10 +-9 +11 +-10 +12 +-9 +10 +-9 +11 +-9 +11 +-10 +11 +-10 +10 +-9 +10 +-10 +10 +-9 +11 +-9 +10 +-11 +12 +-11 +12 +-10 +10 +-10 +10 +-11 +10 +-11 +10 +-10 +10 +-9 +9 +-13 +12 +-9 +10 +-11 +11 +-10 +11 +-9 +10 +-9 +11 +-9 +12 +-8 +10 +-11 +12 +-10 +12 +-10 +10 +-10 +11 +-9 +10 +-10 +12 +-9 +12 +-10 +10 +-9 +10 +-9 +11 +-10 +10 +-11 +10 +-10 +11 +-10 +10 +-11 +10 +-11 +10 +-10 +8 +-11 +9 +-10 +11 +-12 +10 +-10 +10 +-11 +10 +-10 +11 +-12 +11 +-11 +10 +-9 +11 +-11 +10 +-9 +10 +-10 +12 +-10 +11 +-8 +10 +-9 +12 +-10 +11 +-9 +10 +-9 +11 +-9 +11 +-9 +10 +-8 +10 +-9 +12 +-11 +10 +-9 +11 +-11 +11 +-10 +11 +-11 +9 +-12 +11 +-10 +9 +-11 +9 +-11 +10 +-11 +10 +-10 +10 +-12 +11 +-10 +9 +-10 +12 +-10 +11 +-9 +12 +-9 +10 +-10 +12 +-9 +14 +11 +-15 +11 +-11 +9 +-10 +11 +-10 +10 +-11 +11 +-9 +9 +-11 +11 +-11 +11 +-11 +11 +-9 +7 +-9 +10 +-9 +10 +-9 +9 +-9 +9 +-10 +10 +-11 +10 +-10 +9 +-9 +10 +-9 +10 +-9 +10 +-10 +10 +-9 +12 +-11 +9 +-10 +10 +-9 +13 +-10 +10 +-10 +9 +-9 +11 +-9 +10 +-8 +9 +-9 +10 +-10 +10 +-10 +10 +-9 +9 +-9 +10 +-11 +9 +-11 +10 +-10 +9 +-9 +8 +-10 +9 +-10 +11 +-10 +11 +-8 +7 +-11 +10 +-9 +9 +-10 +12 +-9 +11 +-12 +-8 +14 +-8 +10 +-10 +10 +-10 +10 +-9 +11 +-10 +10 +-8 +10 +-8 +11 +-10 +11 +-9 +10 +-10 +10 +-9 +10 +-10 +10 +-10 +10 +-11 +9 +-10 +9 +-10 +11 +-10 +10 +-10 +10 +-9 +11 +-9 +11 +-10 +11 +-9 +11 +-10 +10 +-9 +9 +-8 +11 +-10 +10 +-10 +11 +-9 +10 +-10 +12 +-7 +11 +-8 +11 +-9 +11 +-10 +12 +-11 +10 +-11 +12 +-9 +10 +-11 +10 +-10 +9 +-10 +10 +-9 +9 +-11 +9 +-10 +9 +-11 +10 +-11 +10 +-11 +9 +-9 +9 +-10 +13 +9 +-15 +10 +-11 +12 +-11 +11 +-10 +9 +-10 +8 +-9 +9 +-10 +10 +-11 +9 +-11 +9 +-8 +10 +-9 +9 +-10 +10 +-10 +11 +-10 +10 +-9 +11 +-8 +9 +-9 +11 +-10 +10 +-8 +9 +-10 +10 +-9 +10 +-10 +11 +-9 +9 +-9 +8 +-9 +9 +-11 +11 +-10 +9 +-10 +9 +-10 +9 +-10 +10 +-9 +9 +-13 +-8 +15 +-8 +12 +-9 +10 +-8 +11 +-8 +10 +-10 +11 +-10 +10 +-8 +10 +-9 +11 +-9 +11 +-9 +11 +-11 +12 +-10 +11 +-10 +11 +-11 +8 +-10 +12 +-10 +11 +-9 +11 +-12 +11 +-9 +10 +-9 +9 +-10 +11 +-11 +11 +-10 +8 +-11 +10 +-11 +11 +-9 +9 +-10 +11 +-10 +11 +-9 +10 +-13 +12 +-9 +11 +-10 +12 +-10 +9 +-11 +12 +-10 +11 +-11 +9 +-9 +11 +-10 +9 +-11 +10 +-8 +9 +-11 +12 +-9 +10 +-11 +10 +-12 +12 +-10 +10 +-9 +11 +-10 +10 +-10 +12 +-9 +11 +-11 +11 +-10 +11 +-9 +10 +-10 +11 +-10 +10 +-9 +11 +-10 +12 +-11 +11 +-11 +12 +-10 +10 +-10 +11 +-10 +11 +-10 +10 +-11 +15 +10 +-15 +12 +-11 +9 +-10 +9 +-11 +10 +-11 +9 +-10 +11 +-11 +8 +-10 +10 +-10 +10 +-10 +10 +-11 +12 +-11 +10 +-11 +11 +-9 +10 +-8 +10 +-14 +-8 +13 +-10 +12 +-11 +11 +-8 +8 +-8 +11 +-9 +11 +-9 +10 +-9 +11 +-8 +10 +-9 +11 +-9 +13 +-10 +10 +-10 +11 +-11 +10 +-10 +12 +-9 +9 +-9 +12 +-9 +13 +-9 +11 +-9 +12 +-11 +10 +-9 +9 +-11 +10 +-11 +10 +-10 +10 +-11 +11 +-10 +9 +-10 +10 +-10 +10 +-12 +10 +-11 +10 +-11 +10 +-9 +13 +-12 +11 +-9 +11 +-9 +10 +-11 +11 +-10 +10 +-11 +12 +-9 +9 +-10 +10 +-9 +12 +-11 +12 +-9 +11 +-11 +9 +-11 +10 +-10 +10 +-11 +13 +9 +-14 +9 +-12 +9 +-12 +9 +-11 +9 +-9 +9 +-11 +10 +-10 +12 +-10 +9 +-10 +11 +-10 +9 +-10 +9 +-9 +9 +-10 +11 +-11 +11 +-11 +9 +-11 +10 +-10 +9 +-10 +10 +-10 +10 +-11 +10 +-10 +10 +-7 +9 +-9 +9 +-10 +10 +-8 +10 +-9 +9 +-9 +10 +-9 +10 +-9 +9 +-11 +9 +-9 +10 +-14 +-9 +13 +-8 +10 +-10 +11 +-9 +10 +-8 +9 +-9 +11 +-9 +11 +-10 +12 +-11 +10 +-9 +11 +-10 +10 +-9 +9 +-9 +10 +-10 +11 +-10 +9 +-9 +10 +-9 +11 +-11 +11 +-9 +9 +-11 +11 +-10 +10 +-11 +11 +-10 +12 +-9 +12 +-6 +9 +-10 +12 +-10 +11 +-11 +10 +-11 +10 +-9 +10 +-10 +10 +-10 +9 +-11 +11 +-11 +11 +-10 +10 +-9 +10 +-10 +12 +-8 +9 +-9 +9 +-10 +11 +-10 +10 +-10 +10 +-11 +11 +-10 +10 +-10 +11 +-9 +10 +-9 +10 +-10 +12 +-11 +9 +-10 +10 +-10 +9 +-10 +12 +-11 +11 +-10 +11 +-9 +10 +-10 +10 +-9 +11 +-10 +12 +-10 +10 +-8 +10 +-9 +11 +-9 +10 +-11 +10 +-9 +10 +-11 +10 +-10 +10 +-9 +11 +-12 +11 +-11 +9 +-9 +10 +-10 +11 +-10 +11 +-10 +10 +-10 +11 +-10 +10 +-9 +11 +-8 +10 +-9 +11 +-8 +9 +-11 +10 +-9 +11 +-10 +10 +-11 +11 +-9 +9 +-11 +11 +-11 +11 +-9 +10 +-10 +12 +-9 +10 +-10 +10 +-10 +11 +-12 +10 +-9 +10 +-11 +12 +-11 +10 +-11 +13 +10 +-16 +11 +-12 +8 +-11 +9 +-12 +9 +-8 +6 +-12 +9 +-9 +9 +-9 +9 +-10 +11 +-10 +11 +-8 +9 +-9 +10 +-10 +10 +-11 +11 +-9 +10 +-10 +11 +-9 +9 +-8 +9 +-10 +9 +-9 +9 +-8 +9 +-8 +10 +-9 +9 +-11 +10 +-8 +8 +-9 +10 +-10 +11 +-10 +9 +-10 +8 +-9 +10 +-10 +8 +-13 +-7 +13 +-8 +12 +-10 +9 +-9 +11 +-10 +10 +-9 +12 +-9 +13 +-10 +10 +-8 +11 +-8 +11 +-8 +8 +-8 +12 +-10 +10 +-9 +10 +-8 +12 +-9 +11 +-9 +11 +-9 +9 +-9 +10 +-9 +10 +-10 +11 +-11 +10 +-11 +10 +-11 +11 +-11 +8 +-11 +9 +-11 +10 +-9 +10 +-10 +9 +-10 +12 +-10 +12 +-9 +10 +-9 +12 +-9 +12 +-9 +10 +-10 +11 +-11 +11 +-10 +10 +-11 +11 +-11 +11 +-8 +10 +-8 +12 +-10 +11 +-11 +11 +-11 +11 +-9 +12 +-9 +11 +-10 +12 +-10 +11 +-10 +10 +-10 +10 +-10 +10 +-12 +11 +-10 +10 +-10 +11 +-10 +10 +-10 +9 +-10 +11 +-9 +9 +-11 +10 +-10 +10 +-10 +11 +-9 +10 +-11 +11 +-10 +9 +-10 +10 +-12 +9 +-8 +8 +-12 +11 +-12 +10 +-9 +10 +-10 +10 +-9 +10 +-10 +10 +-11 +12 +-10 +11 +-9 +9 +-11 +10 +-11 +11 +-10 +14 +11 +-15 +11 +-10 +9 +-9 +9 +-11 +9 +-11 +11 +-9 +9 +-10 +11 +-10 +11 +-9 +9 +-10 +9 +-10 +9 +-10 +10 +-9 +9 +-10 +10 +-9 +11 +-9 +9 +-10 +10 +-10 +9 +-10 +10 +-9 +10 +-9 +9 +-10 +10 +-9 +9 +-8 +8 +-11 +12 +-9 +8 +-11 +12 +-10 +10 +-8 +9 +-8 +10 +-9 +8 +-12 +-6 +13 +-8 +12 +-10 +11 +-10 +11 +-9 +10 +-9 +11 +-10 +11 +-10 +10 +-11 +11 +-9 +10 +-11 +9 +-11 +11 +-10 +10 +-11 +10 +-10 +11 +-9 +14 +9 +-14 +12 +-9 +11 +-10 +11 +-10 +10 +-9 +9 +-11 +9 +-11 +9 +-10 +10 +-10 +9 +-9 +10 +-9 +9 +-9 +11 +-10 +11 +-9 +9 +-9 +10 +-13 +-8 +14 +-9 +12 +-10 +11 +-10 +11 +-9 +11 +-9 +9 +-10 +11 +-9 +11 +-10 +12 +-11 +8 +-9 +9 +-9 +9 +-9 +9 +-10 +10 +-10 +13 +-11 +10 +-10 +11 +-12 +10 +-10 +9 +-10 +9 +-11 +11 +-10 +11 +-9 +9 +-11 +12 +-9 +11 +-10 +10 +-11 +10 +-9 +11 +-10 +11 +-9 +11 +-11 +11 +-9 +10 +-10 +12 +-9 +11 +-12 +10 +-10 +11 +-8 +10 +-11 +11 +-10 +10 +-10 +11 +-10 +10 +-10 +12 +-9 +12 +-9 +10 +-9 +11 +-9 +10 +-10 +13 +-10 +9 +-11 +10 +-10 +11 +-10 +11 +-9 +10 +-9 +11 +-11 +11 +-10 +10 +-10 +9 +-10 +11 +-11 +11 +-11 +10 +-9 +9 +-10 +11 +-8 +10 +-10 +10 +-9 +11 +-11 +11 +-11 +10 +-11 +11 +-10 +9 +-11 +10 +-11 +11 +-12 +10 +-11 +9 +-11 +10 +-11 +11 +-11 +9 +-10 +12 +-9 +11 +-10 +10 +-10 +10 +-10 +10 +-10 +11 +-10 +10 +-9 +11 +-9 +10 +-12 +12 +-9 +10 +-10 +10 +-9 +8 +-9 +9 +-10 +12 +-11 +11 +-9 +10 +-10 +11 +-10 +11 +-9 +10 +-11 +11 +-10 +10 +-10 +11 +-10 +12 +-10 +10 +-10 +11 +-9 +11 +-9 +10 +-10 +10 +-10 +10 +-10 +9 +-9 +11 +-9 +10 +-9 +11 +-10 +9 +-9 +10 +-9 +10 +-8 +8 +-9 +11 +-11 +11 +-10 +10 +-10 +11 +-9 +11 +-9 +11 +-9 +11 +-10 +10 +-10 +9 +-10 +9 +-10 +11 +-11 +10 +-10 +10 +-12 +12 +-11 +10 +-10 +10 +-11 +11 +-10 +12 +-9 +11 +-9 +10 +-9 +12 +-10 +12 +-8 +11 +-8 +10 +-10 +11 +-10 +11 +-9 +11 +-10 +10 +-10 +10 +-10 +10 +-10 +10 +-10 +11 +-10 +9 +-11 +10 +-10 +10 +-10 +9 +-11 +10 +-11 +10 +-12 +10 +-11 +8 +-10 +9 +-11 +9 +-10 +9 +-11 +10 +-11 +11 +-9 +10 +-10 +12 +-10 +9 +-10 +12 +-11 +9 +-10 +10 +-9 +11 +-11 +11 +-10 +12 +-9 +11 +-7 +11 +-9 +13 +-10 +13 +-9 +11 +-10 +10 +-8 +9 +-10 +11 +-11 +10 +-9 +8 +-11 +9 +-11 +10 +-11 +12 +-10 +10 +-10 +10 +-9 +10 +-9 +10 +-10 +12 +-10 +11 +-9 +10 +-9 +11 +-11 +10 +-10 +11 +-10 +11 +-10 +11 +-9 +12 +-11 +11 +-12 +11 +-10 +10 +-10 +10 +-11 +10 +-11 +10 +-11 +12 +-10 +10 +-9 +11 +-10 +11 +-10 +12 +-9 +10 +-10 +10 +-11 +11 +-10 +10 +-10 +9 +-10 +10 +-11 +12 +-11 +11 +-10 +10 +-9 +9 +-11 +10 +-11 +11 +-10 +11 +-12 +9 +-9 +10 +-11 +10 +-9 +11 +-10 +10 +-10 +10 +-9 +10 +-10 +11 +-9 +10 +-10 +11 +-9 +11 +-9 +12 +-9 +12 +-9 +11 +-10 +12 +-10 +10 +-10 +10 +-10 +11 +-11 +10 +-10 +11 +-9 +11 +-11 +12 +-10 +12 +-9 +10 +-11 +11 +-10 +11 +-12 +10 +-9 +9 +-11 +10 +-11 +11 +-10 +8 +-10 +9 +-10 +10 +-9 +10 +-11 +12 +-11 +10 +-10 +10 +-10 +12 +-11 +11 +-11 +10 +-11 +13 +-11 +11 +-10 +11 +-10 +12 +-10 +9 +-10 +11 +-10 +11 +-9 +10 +-11 +11 +-10 +10 +-10 +9 +-10 +11 +-10 +12 +-10 +10 +-11 +10 +-11 +10 +-11 +10 +-10 +9 +-10 +10 +-10 +11 +-10 +11 +-10 +11 +-10 +9 +-10 +9 +-10 +11 +-10 +9 +-10 +12 +-10 +11 +-9 +12 +-10 +11 +-9 +10 +-10 +11 +-9 +11 +-10 +12 +-10 +10 +-12 +12 +-9 +10 +-10 +10 +-10 +10 +-11 +11 +-9 +11 +-11 +8 +-10 +11 +-9 +9 +-11 +12 +-12 +11 +-11 +10 +-11 +10 +-11 +10 +-10 +10 +-11 +10 +-12 +12 +-10 +10 +-9 +10 +-9 +12 +-10 +11 +-10 +12 +-9 +9 +-10 +11 +-11 +10 +-12 +11 +-10 +11 +-10 +9 +-12 +13 +-9 +8 +-11 +10 +-10 +10 +-10 +11 +-11 +11 +-11 +11 +-9 +11 +-10 +12 +-10 +10 +-10 +10 +-10 +10 +-10 +10 +-10 +10 +-10 +9 +-11 +10 +-9 +11 +-12 +11 +-11 +8 +-11 +11 +-11 +10 +-10 +10 +-11 +10 +-12 +11 +-10 +10 +-10 +12 +-9 +10 +-11 +11 +-10 +12 +-10 +13 +-9 +11 +-9 +11 +-10 +11 +-10 +10 +-10 +12 +-9 +10 +-10 +11 +-10 +11 +-12 +9 +-9 +10 +-10 +10 +-11 +11 +-10 +9 +-11 +11 +-9 +9 +-11 +13 +-12 +11 +-9 +10 +-9 +10 +-10 +12 +-9 +11 +-10 +9 +-10 +11 +-11 +11 +-10 +11 +-10 +11 +-8 +8 +-10 +11 +-9 +11 +-9 +10 +-10 +11 +-10 +10 +-8 +12 +-10 +11 +-9 +9 +-10 +10 +-11 +11 +-10 +10 +-10 +11 +-11 +11 +-10 +10 +-8 +9 +-11 +11 +-11 +10 +-11 +11 +-11 +11 +-9 +8 +-9 +10 +-11 +12 +-10 +11 +-8 +11 +-9 +12 +-10 +11 +-9 +11 +-9 +11 +-9 +10 +-10 +10 +-9 +10 +-9 +9 +-11 +11 +-10 +11 +-11 +10 +-9 +10 +-11 +10 +-11 +9 +-10 +9 +-10 +10 +-11 +11 +-10 +10 +-12 +13 +-11 +11 +-10 +11 +-11 +12 +-10 +9 +-11 +10 +-11 +10 +-11 +11 +-10 +11 +-12 +12 +-8 +9 +-10 +10 +-12 +12 +-10 +10 +-10 +11 +-8 +11 +-10 +11 +-9 +11 +-10 +11 +-11 +11 +-11 +9 +-8 +10 +-9 +12 +-9 +12 +-10 +10 +-10 +11 +-9 +12 +-11 +10 +-10 +9 +-11 +11 +-11 +11 +-9 +12 +-10 +11 +-9 +10 +-9 +11 +-11 +10 +-11 +11 +-9 +11 +-10 +8 +-8 +11 +-9 +11 +-11 +10 +-10 +12 +-9 +12 +-9 +14 +10 +-15 +10 +-11 +9 +-11 +10 +-11 +9 +-10 +9 +-9 +8 +-9 +10 +-9 +9 +-10 +11 +-8 +10 +-9 +11 +-9 +10 +-9 +11 +-8 +9 +-11 +10 +-10 +9 +-8 +8 +-10 +9 +-9 +9 +-10 +9 +-13 +13 +-8 +10 +-9 +9 +-9 +9 +-9 +9 +-10 +9 +-9 +9 +-9 +10 +-7 +8 +-9 +11 +-9 +11 +-8 +9 +-11 +10 +-10 +10 +-9 +9 +-10 +10 +-10 +11 +-9 +10 +-11 +9 +-10 +10 +-9 +10 +-10 +9 +-10 +11 +-9 +10 +-10 +11 +-10 +9 +-10 +9 +-13 +-8 +13 +-7 +9 +-9 +10 +-9 +9 +-10 +10 +-10 +11 +-11 +9 +-9 +11 +-11 +10 +-9 +12 +-9 +12 +-10 +10 +-9 +10 +-10 +11 +-9 +9 +-10 +11 +-9 +10 +-9 +9 +-9 +11 +-9 +10 +-11 +11 +-10 +9 +-10 +10 +-10 +10 +-9 +10 +-11 +11 +-10 +11 +-10 +10 +-11 +11 +-9 +11 +-9 +11 +-10 +10 +-10 +11 +-8 +10 +-10 +12 +-9 +11 +-9 +12 +-9 +11 +-9 +10 +-10 +10 +-10 +10 +-10 +11 +-10 +11 +-11 +11 +-9 +11 +-8 +10 +-10 +10 +-10 +13 +9 +-16 +12 +-10 +11 +-9 +10 +-10 +10 +-10 +9 +-11 +10 +-9 +8 +-11 +9 +-9 +9 +-10 +9 +-11 +9 +-11 +9 +-10 +8 +-10 +9 +-10 +11 +-10 +10 +-10 +9 +-9 +7 +-9 +10 +-11 +10 +-9 +9 +-9 +8 +-9 +10 +-10 +9 +-10 +9 +-10 +9 +-9 +8 +-10 +9 +-9 +8 +-10 +9 +-9 +10 +-13 +-8 +14 +-8 +9 +-10 +11 +-8 +12 +-8 +9 +-10 +11 +-7 +11 +-9 +11 +-9 +11 +-9 +10 +-10 +11 +-9 +11 +-9 +11 +-9 +9 +-8 +10 +-9 +11 +-11 +10 +-9 +10 +-8 +9 +-10 +11 +-8 +10 +-10 +10 +-10 +11 +-11 +10 +-8 +8 +-11 +12 +-10 +11 +-10 +10 +-10 +11 +-8 +9 +-11 +13 +-11 +9 +-9 +10 +-11 +10 +-10 +11 +-9 +11 +-10 +9 +-10 +10 +-10 +9 +-11 +10 +-9 +11 +-11 +10 +-9 +10 +-9 +10 +-11 +10 +-10 +10 +-10 +11 +-10 +10 +-12 +12 +-10 +12 +-9 +11 +-9 +12 +-11 +10 +-9 +10 +-11 +10 +-11 +11 +-9 +10 +-11 +11 +-9 +11 +-8 +9 +-11 +13 +-9 +12 +-10 +11 +-10 +15 +9 +-16 +12 +-11 +9 +-11 +9 +-11 +8 +-10 +8 +-10 +12 +-12 +9 +-10 +10 +-9 +10 +-12 +9 +-10 +10 +-10 +9 +-9 +10 +-10 +10 +-9 +10 +-12 +-6 +15 +-7 +11 +-8 +11 +-8 +11 +-9 +12 +-9 +12 +-10 +10 +-9 +9 +-9 +11 +-9 +10 +-9 +10 +-11 +11 +-10 +10 +-11 +10 +-10 +10 +-9 +9 +-10 +10 +-10 +10 +-8 +10 +-10 +11 +-10 +11 +-9 +10 +-10 +9 +-11 +11 +-11 +9 +-10 +11 +-11 +11 +-11 +10 +-11 +11 +-10 +9 +-10 +10 +-11 +10 +-11 +10 +-9 +9 +-11 +12 +-9 +10 +-10 +12 +-9 +11 +-9 +11 +-10 +10 +-9 +10 +-11 +12 +-9 +12 +-9 +11 +-9 +12 +-10 +11 +-9 +10 +-10 +15 +10 +-15 +10 +-11 +9 +-11 +9 +-10 +10 +-10 +10 +-10 +9 +-10 +9 +-11 +9 +-11 +10 +-11 +9 +-11 +10 +-9 +9 +-9 +10 +-10 +11 +-11 +9 +-9 +10 +-9 +10 +-10 +11 +-10 +12 +-9 +11 +-8 +8 +-10 +9 +-9 +9 +-10 +10 +-10 +9 +-10 +10 +-10 +11 +-10 +9 +-10 +9 +-9 +10 +-10 +10 +-12 +-9 +14 +-8 +10 +-9 +11 +-8 +8 +-9 +11 +-8 +10 +-9 +12 +-9 +13 +-8 +9 +-8 +11 +-8 +10 +-10 +10 +-10 +11 +-10 +10 +-11 +9 +-10 +9 +-9 +10 +-10 +11 +-9 +10 +-9 +9 +-9 +11 +-10 +10 +-10 +10 +-10 +10 +-10 +11 +-11 +10 +-11 +10 +-10 +10 +-9 +11 +-11 +12 +-10 +10 +-9 +9 +-11 +11 +-11 +10 +-10 +10 +-10 +12 +-9 +10 +-9 +10 +-12 +10 +-10 +9 +-10 +10 +-11 +11 +-9 +11 +-9 +10 +-10 +10 +-9 +9 +-11 +10 +-10 +10 +-10 +10 +-10 +11 +-11 +11 +-9 +10 +-9 +11 +-10 +11 +-9 +11 +-10 +12 +-11 +11 +-9 +11 +-10 +11 +-11 +11 +-9 +9 +-11 +11 +-9 +10 +-9 +9 +-9 +10 +-10 +10 +-9 +10 +-8 +10 +-12 +10 +-11 +10 +-11 +11 +-9 +9 +-9 +11 +-9 +11 +-10 +10 +-10 +11 +-10 +10 +-11 +12 +-9 +10 +-11 +12 +-11 +10 +-10 +10 +-10 +10 +-11 +12 +-11 +9 +-10 +10 +-10 +9 +-10 +12 +-11 +9 +-10 +9 +-9 +11 +-10 +10 +-11 +11 +-9 +11 +-10 +10 +-11 +14 +9 +-15 +11 +-11 +10 +-10 +10 +-12 +9 +-11 +9 +-11 +7 +-11 +10 +-12 +10 +-10 +11 +-10 +10 +-10 +9 +-9 +8 +-9 +10 +-9 +9 +-9 +10 +-9 +12 +-9 +12 +-9 +10 +-9 +10 +-9 +9 +-9 +10 +-11 +9 +-8 +9 +-8 +8 +-10 +9 +-9 +9 +-10 +9 +-10 +10 +-10 +10 +-9 +8 +-10 +10 +-13 +-9 +13 +-8 +11 +-8 +11 +-9 +11 +-6 +10 +-10 +11 +-11 +13 +-10 +10 +-10 +10 +-10 +10 +-10 +10 +-9 +10 +-11 +13 +-11 +8 +-10 +11 +-9 +10 +-10 +11 +-10 +11 +-12 +13 +-9 +11 +-9 +11 +-10 +11 +-9 +14 +-12 +10 +-9 +11 +-9 +10 +-9 +12 +-9 +10 +-11 +12 +-10 +11 +-9 +11 +-11 +10 +-10 +11 +-10 +11 +-10 +8 +-9 +9 +-9 +10 +-11 +12 +-10 +9 +-9 +12 +-10 +10 +-9 +9 +-9 +12 +-10 +10 +-8 +9 +-9 +11 +-10 +9 +-10 +11 +-11 +10 +-11 +12 +-9 +10 +-9 +11 +-10 +10 +-10 +8 +-9 +11 +-11 +11 +-9 +10 +-10 +12 +-8 +10 +-8 +10 +-10 +11 +-9 +10 +-9 +10 +-11 +11 +-10 +11 +-11 +10 +-10 +10 +-10 +11 +-11 +10 +-9 +11 +-10 +11 +-10 +10 +-10 +11 +-9 +9 +-9 +10 +-9 +10 +-10 +11 +-10 +11 +-10 +12 +-10 +14 +9 +-16 +10 +-11 +9 +-10 +8 +-11 +8 +-10 +10 +-10 +9 +-11 +8 +-10 +9 +-11 +10 +-11 +9 +-10 +9 +-10 +10 +-10 +10 +-9 +10 +-10 +10 +-8 +10 +-9 +11 +-10 +9 +-11 +10 +-10 +10 +-10 +10 +-9 +8 +-11 +10 +-10 +9 +-9 +9 +-9 +9 +-8 +9 +-10 +11 +-9 +10 +-9 +10 +-10 +10 +-11 +-8 +13 +-8 +11 +-9 +11 +-11 +9 +-8 +11 +-8 +10 +-9 +9 +-9 +10 +-10 +9 +-9 +10 +-9 +10 +-11 +12 +-9 +10 +-10 +9 +-9 +10 +-11 +14 +10 +-15 +11 +-10 +9 +-11 +11 +-10 +8 +-8 +9 +-10 +12 +-11 +9 +-9 +11 +-10 +9 +-9 +10 +-9 +10 +-10 +10 +-9 +9 +-9 +7 +-9 +10 +-12 +-8 +14 +-9 +10 +-9 +11 +-10 +10 +-8 +11 +-8 +12 +-9 +12 +-8 +10 +-7 +9 +-9 +10 +-9 +12 +-11 +11 +-10 +9 +-9 +10 +-10 +11 +-10 +11 +-10 +10 +-10 +12 +-9 +11 +-9 +10 +-11 +10 +-10 +11 +-11 +10 +-11 +12 +-10 +9 +-10 +9 +-10 +10 +-11 +9 +-9 +9 +-11 +10 +-10 +9 +-10 +10 +-9 +10 +-10 +9 +-11 +11 +-9 +9 +-10 +11 +-9 +11 +-10 +10 +-10 +10 +-10 +10 +-10 +10 +-10 +8 +-11 +11 +-10 +11 +-10 +11 +-9 +11 +-10 +10 +-10 +10 +-10 +11 +-10 +12 +-11 +8 +-9 +11 +-10 +11 +-11 +11 +-9 +10 +-12 +10 +-10 +10 +-10 +10 +-10 +10 +-11 +11 +-10 +12 +-10 +10 +-10 +10 +-8 +13 +-9 +8 +-9 +12 +-10 +12 +-10 +11 +-10 +10 +-9 +9 +-10 +10 +-9 +10 +-10 +10 +-10 +9 +-11 +10 +-10 +11 +-10 +11 +-10 +14 +-10 +9 +-8 +12 +-10 +10 +-10 +10 +-11 +12 +-10 +11 +-10 +10 +-9 +10 +-10 +10 +-10 +11 +-11 +9 +-10 +12 +-10 +10 +-10 +9 +-11 +11 +-10 +9 +-10 +9 +-11 +10 +-11 +10 +-10 +10 +-10 +11 +-10 +11 +-10 +12 +-11 +12 +-10 +11 +-10 +11 +-9 +11 +-10 +11 +-9 +10 +-9 +11 +-9 +12 +-10 +12 +-10 +9 +-10 +9 +-11 +12 +-9 +10 +-11 +11 +-11 +11 +-9 +12 +-8 +10 +-10 +11 +-8 +8 +-10 +10 +-10 +11 +-11 +12 +-9 +9 +-9 +11 +-10 +10 +-10 +10 +-10 +10 +-9 +10 +-10 +9 +-11 +10 +-10 +10 +-10 +10 +-10 +11 +-9 +10 +-9 +10 +-10 +11 +-8 +10 +-9 +12 +-10 +11 +-10 +11 +-10 +10 +-10 +11 +-9 +11 +-8 +11 +-12 +12 +-11 +11 +-9 +9 +-10 +11 +-12 +10 +-11 +10 +-11 +10 +-11 +10 +-11 +10 +-10 +11 +-10 +10 +-11 +10 +-11 +9 +-10 +10 +-9 +9 +-9 +10 +-9 +12 +-9 +11 +-9 +11 +-10 +12 +-10 +12 +-9 +12 +-10 +11 +-10 +11 +-11 +10 +-9 +8 +-10 +12 +-11 +9 +-11 +8 +-9 +11 +-12 +11 +-11 +10 +-12 +11 +-11 +9 +-10 +9 +-10 +11 +-10 +11 +-9 +10 +-9 +8 +-12 +10 +-10 +9 +-10 +10 +-11 +10 +-11 +11 +-9 +12 +-11 +12 +-9 +12 +-11 +10 +-9 +11 +-10 +10 +-11 +11 +-9 +11 +-10 +9 +-10 +10 +-9 +10 +-10 +11 +-9 +10 +-10 +11 +-11 +9 +-11 +10 +-10 +11 +-10 +11 +-9 +10 +-10 +11 +-9 +12 +-8 +11 +-10 +11 +-10 +11 +-9 +12 +-11 +10 +-9 +10 +-10 +11 +-10 +11 +-9 +11 +-9 +10 +-9 +10 +-10 +10 +-10 +9 +-11 +10 +-10 +10 +-9 +11 +-9 +12 +-10 +10 +-9 +11 +-10 +12 +-11 +9 +-11 +11 +-9 +10 +-11 +12 +-11 +9 +-10 +10 +-10 +10 +-10 +9 +-9 +11 +-10 +11 +-10 +9 +-9 +10 +-9 +9 +-10 +11 +-9 +11 +-10 +13 +-10 +11 +-11 +11 +-8 +10 +-11 +10 +-11 +10 +-12 +12 +-10 +11 +-9 +11 +-11 +12 +-9 +11 +-9 +11 +-11 +12 +-12 +9 +-11 +9 +-10 +12 +-10 +9 +-10 +11 +-10 +11 +-9 +11 +-9 +12 +-10 +9 +-11 +11 +-10 +10 +-10 +9 +-11 +11 +-11 +11 +-10 +11 +-11 +10 +-9 +9 +-10 +11 +-11 +9 +-11 +9 +-10 +10 +-10 +9 +-10 +9 +-11 +12 +-10 +10 +-10 +10 +-10 +10 +-11 +10 +-11 +10 +-9 +10 +-10 +9 +-9 +10 +-12 +12 +-10 +11 +-9 +8 +-10 +11 +-11 +11 +-10 +11 +-10 +10 +-9 +10 +-9 +11 +-11 +11 +-9 +12 +-11 +11 +-9 +11 +-9 +10 +-10 +13 +-12 +10 +-10 +10 +-10 +11 +-11 +12 +-9 +9 +-10 +9 +-9 +11 +-11 +9 +-10 +11 +-11 +11 +-10 +10 +-10 +11 +-11 +10 +-10 +12 +-9 +10 +-9 +10 +-11 +11 +-9 +11 +-10 +12 +-10 +12 +-10 +12 +-10 +12 +-10 +13 +-9 +9 +-9 +11 +-9 +11 +-10 +12 +-11 +11 +-8 +11 +-11 +11 +-10 +10 +-11 +12 +-12 +12 +-9 +9 +-10 +12 +-10 +9 +-11 +10 +-10 +11 +-11 +11 +-10 +9 +-11 +12 +-10 +10 +-11 +11 +-10 +10 +-11 +10 +-11 +10 +-9 +10 +-10 +11 +-11 +11 +-10 +11 +-11 +10 +-10 +10 +-9 +10 +-11 +10 +-10 +11 +-10 +11 +-10 +12 +-11 +11 +-10 +13 +-10 +10 +-10 +11 +-9 +9 +-11 +12 +-9 +8 +-11 +11 +-10 +11 +-10 +11 +-10 +11 +-11 +9 +-9 +12 +-10 +10 +-11 +9 +-11 +10 +-11 +11 +-12 +11 +-11 +9 +-11 +12 +-10 +10 +-10 +11 +-11 +12 +-12 +12 +-10 +11 +-9 +12 +-9 +10 +-10 +12 +-10 +12 +-9 +11 +-9 +11 +-9 +12 +-10 +13 +-10 +12 +-9 +10 +-10 +11 +-9 +10 +-11 +11 +-11 +11 +-9 +10 +-11 +12 +-10 +11 +-9 +10 +-9 +9 +-10 +11 +-9 +11 +-9 +10 +-9 +9 +-10 +11 +-10 +10 +-10 +10 +-12 +11 +-11 +10 +-10 +10 +-10 +10 +-10 +9 +-10 +9 +-9 +13 +-11 +8 +-9 +10 +-10 +11 +-10 +9 +-10 +10 +-10 +11 +-9 +10 +-9 +13 +-8 +9 +-10 +12 +-10 +9 +-10 +11 +-11 +10 +-11 +9 +-10 +8 +-10 +11 +-11 +12 +-9 +9 +-9 +11 +-10 +13 +-11 +12 +-11 +10 +-10 +10 +-10 +10 +-11 +11 +-9 +11 +-10 +12 +-9 +11 +-9 +11 +-9 +10 +-10 +11 +-9 +11 +-10 +10 +-10 +11 +-9 +11 +-10 +11 +-11 +12 +-11 +9 +-9 +12 +-10 +10 +-11 +10 +-9 +8 +-10 +14 +9 +-15 +11 +-11 +10 +-10 +10 +-10 +10 +-10 +10 +-12 +10 +-10 +10 +-10 +9 +-10 +8 +-10 +9 +-10 +9 +-10 +8 +-10 +9 +-10 +10 +-11 +8 +-9 +9 +-11 +10 +-11 +10 +-9 +9 +-10 +10 +-9 +11 +-9 +9 +-9 +10 +-9 +9 +-10 +11 +-8 +10 +-10 +11 +-8 +11 +-10 +11 +-9 +11 +-9 +11 +-9 +10 +-8 +9 +-10 +10 +-10 +10 +-9 +9 +-9 +10 +-10 +11 +-10 +10 +-9 +10 +-8 +10 +-10 +11 +-8 +10 +-11 +10 +-8 +8 +-11 +9 +-10 +9 +-12 +-11 +14 +-9 +11 +-10 +10 +-10 +10 +-8 +11 +-8 +10 +-9 +10 +-9 +8 +-10 +11 +-8 +10 +-11 +12 +-9 +8 +-10 +9 +-10 +9 +-10 +9 +-11 +11 +-10 +11 +-11 +9 +-8 +11 +-10 +12 +-10 +10 +-10 +10 +-10 +12 +-10 +10 +-10 +12 +-11 +10 +-11 +11 +-10 +9 +-10 +11 +-11 +11 +-10 +11 +-8 +9 +-8 +11 +-9 +11 +-9 +11 +-9 +11 +-9 +10 +-10 +12 +-11 +12 +-9 +10 +-9 +9 +-11 +11 +-10 +11 +-8 +9 +-11 +12 +-10 +9 +-9 +9 +-10 +13 +10 +-16 +12 +-9 +9 +-11 +10 +-10 +10 +-10 +10 +-10 +11 +-10 +8 +-10 +10 +-10 +8 +-9 +9 +-9 +9 +-10 +10 +-10 +8 +-10 +9 +-10 +10 +-9 +11 +-9 +8 +-9 +11 +-10 +9 +-9 +9 +-8 +11 +-9 +10 +-10 +10 +-9 +10 +-9 +10 +-9 +10 +-9 +9 +-10 +9 +-9 +10 +-9 +8 +-10 +10 +-12 +-8 +14 +-8 +11 +-9 +9 +-8 +10 +-9 +10 +-9 +9 +-10 +10 +-10 +11 +-12 +10 +-8 +10 +-9 +12 +-9 +12 +-9 +10 +-10 +11 +-9 +10 +-9 +12 +-10 +12 +-9 +9 +-9 +11 +-10 +10 +-11 +10 +-10 +10 +-11 +9 +-9 +9 +-10 +12 +-9 +9 +-11 +11 +-10 +8 +-11 +11 +-10 +11 +-9 +11 +-11 +10 +-10 +8 +-11 +10 +-11 +11 +-9 +10 +-11 +11 +-10 +9 +-9 +11 +-10 +12 +-9 +10 +-8 +10 +-9 +11 +-9 +11 +-8 +10 +-10 +9 +-10 +10 +-9 +12 +-10 +11 +-10 +11 +-9 +9 +-11 +12 +-8 +10 +-10 +12 +-11 +11 +-10 +9 +-10 +9 +-11 +8 +-9 +12 +-9 +9 +-11 +10 +-10 +11 +-10 +9 +-10 +13 +11 +-16 +10 +-11 +7 +-12 +11 +-11 +9 +-11 +9 +-11 +10 +-11 +9 +-9 +10 +-11 +9 +-10 +10 +-11 +9 +-9 +11 +-11 +9 +-9 +10 +-10 +11 +-12 +-8 +15 +-8 +11 +-9 +10 +-9 +10 +-10 +11 +-9 +11 +-10 +9 +-10 +9 +-9 +9 +-9 +11 +-9 +11 +-10 +12 +-11 +11 +-10 +10 +-9 +11 +-10 +11 +-9 +11 +-10 +10 +-9 +10 +-9 +10 +-11 +9 +-9 +10 +-10 +10 +-11 +11 +-10 +10 +-10 +10 +-10 +12 +-10 +11 +-8 +8 +-9 +13 +-11 +12 +-7 +9 +-9 +10 +-10 +12 +-10 +10 +-11 +11 +-9 +11 +-10 +10 +-9 +10 +-10 +9 +-9 +10 +-10 +9 +-10 +11 +-9 +10 +-10 +9 +-10 +11 +-10 +9 +-11 +13 +10 +-14 +11 +-10 +11 +-10 +10 +-9 +10 +-10 +10 +-8 +8 +-11 +12 +-12 +10 +-7 +7 +-11 +10 +-10 +8 +-11 +9 +-10 +10 +-10 +9 +-10 +10 +-9 +10 +-9 +11 +-9 +10 +-9 +10 +-10 +9 +-8 +10 +-10 +12 +-9 +10 +-9 +10 +-9 +11 +-12 +8 +-9 +10 +-10 +10 +-9 +9 +-9 +10 +-9 +10 +-12 +-8 +14 +-8 +11 +-10 +10 +-10 +11 +-9 +10 +-11 +10 +-10 +9 +-9 +11 +-9 +11 +-9 +10 +-10 +12 +-9 +10 +-9 +12 +-8 +10 +-9 +10 +-10 +11 +-10 +10 +-12 +12 +-8 +9 +-10 +11 +-11 +9 +-10 +10 +-10 +9 +-11 +11 +-9 +11 +-10 +9 +-10 +12 +-10 +9 +-10 +10 +-11 +11 +-10 +10 +-9 +10 +-10 +11 +-12 +10 +-9 +9 +-10 +10 +-10 +11 +-10 +12 +-10 +9 +-11 +10 +-9 +8 +-11 +11 +-9 +11 +-10 +11 +-11 +11 +-9 +10 +-9 +9 +-10 +11 +-10 +10 +-10 +10 +-10 +9 +-10 +10 +-11 +10 +-10 +10 +-11 +12 +-11 +11 +-10 +9 +-12 +11 +-12 +12 +-10 +10 +-9 +10 +-10 +10 +-9 +8 +-10 +10 +-10 +9 +-9 +12 +-9 +11 +-10 +11 +-10 +13 +-10 +11 +-9 +10 +-10 +12 +-9 +12 +-9 +9 +-11 +10 +-10 +10 +-10 +10 +-11 +12 +-11 +11 +-10 +10 +-11 +10 +-9 +11 +-10 +10 +-12 +10 +-11 +11 +-9 +11 +-10 +10 +-10 +11 +-10 +8 +-9 +10 +-11 +11 +-10 +12 +-10 +10 +-9 +11 +-9 +10 +-11 +14 +10 +-16 +11 +-12 +9 +-11 +8 +-11 +9 +-11 +9 +-10 +9 +-10 +10 +-10 +9 +-10 +9 +-10 +10 +-10 +11 +-9 +10 +-9 +9 +-9 +9 +-10 +10 +-8 +10 +-10 +12 +-9 +9 +-9 +12 +-11 +9 +-9 +9 +-9 +9 +-9 +12 +-10 +9 +-10 +10 +-10 +9 +-9 +9 +-9 +12 +-11 +9 +-11 +10 +-11 +9 +-13 +-9 +13 +-8 +8 +-10 +11 +-9 +10 +-10 +11 +-10 +11 +-8 +12 +-8 +12 +-9 +12 +-8 +10 +-9 +11 +-9 +10 +-9 +10 +-9 +10 +-9 +10 +-11 +11 +-10 +10 +-11 +10 +-11 +10 +-10 +10 +-10 +9 +-9 +10 +-11 +11 +-10 +11 +-9 +11 +-10 +13 +-10 +10 +-8 +12 +-9 +12 +-10 +11 +-11 +12 +-11 +10 +-8 +9 +-11 +9 +-10 +10 +-11 +10 +-11 +10 +-10 +9 +-10 +12 +-10 +11 +-10 +10 +-11 +8 +-10 +10 +-9 +10 +-10 +9 +-11 +10 +-10 +9 +-10 +11 +-10 +11 +-10 +11 +-10 +9 +-10 +9 +-11 +9 +-10 +11 +-10 +11 +-9 +11 +-9 +11 +-9 +10 +-9 +11 +-9 +10 +-9 +10 +-10 +10 +-10 +10 +-10 +12 +-10 +10 +-10 +10 +-10 +12 +-9 +9 +-10 +11 +-11 +11 +-9 +9 +-11 +10 +-12 +11 +-9 +9 +-11 +9 +-10 +9 +-10 +10 +-10 +11 +-10 +9 +-9 +14 +9 +-15 +11 +-11 +9 +-10 +10 +-9 +11 +-9 +9 +-9 +11 +-9 +11 +-10 +11 +-11 +9 +-10 +10 +-11 +10 +-9 +10 +-10 +9 +-9 +10 +-11 +10 +-10 +9 +-10 +10 +-10 +10 +-9 +10 +-9 +10 +-8 +9 +-9 +9 +-9 +10 +-11 +9 +-9 +10 +-9 +9 +-10 +9 +-10 +12 +-10 +10 +-11 +10 +-9 +10 +-13 +-7 +13 +-8 +10 +-9 +11 +-9 +10 +-9 +10 +-8 +10 +-8 +9 +-9 +10 +-11 +11 +-9 +11 +-9 +11 +-10 +9 +-11 +12 +-9 +10 +-10 +10 +-8 +14 +11 +-14 +12 +-11 +9 +-9 +10 +-11 +10 +-11 +10 +-10 +9 +-10 +11 +-10 +11 +-11 +11 +-11 +10 +-9 +9 +-9 +9 +-10 +11 +-10 +10 +-9 +11 +-10 +-9 +14 +-8 +11 +-8 +9 +-8 +10 +-9 +10 +-9 +11 +-9 +10 +-9 +10 +-10 +10 +-10 +10 +-10 +10 +-11 +10 +-9 +11 +-10 +11 +-11 +11 +-9 +11 +-8 +11 +-8 +12 +-10 +12 +-11 +9 +-9 +11 +-9 +8 +-12 +11 +-9 +12 +-11 +10 +-8 +11 +-10 +12 +-10 +10 +-8 +9 +-10 +10 +-9 +10 +-9 +12 +-10 +10 +-9 +10 +-11 +12 +-11 +11 +-11 +10 +-10 +9 +-11 +11 +-10 +10 +-10 +10 +-10 +11 +-10 +10 +-9 +10 +-11 +12 +-9 +8 +-8 +12 +-10 +11 +-10 +11 +-9 +10 +-10 +11 +-10 +10 +-10 +9 +-9 +12 +-10 +12 +-9 +10 +-10 +12 +-10 +10 +-11 +11 +-10 +10 +-11 +11 +-11 +11 +-12 +10 +-9 +9 +-9 +9 +-11 +9 +-8 +10 +-9 +11 +-11 +10 +-8 +10 +-9 +10 +-9 +10 +-11 +10 +-10 +10 +-11 +11 +-8 +9 +-9 +10 +-10 +11 +-9 +12 +-9 +11 +-11 +13 +-9 +11 +-9 +12 +-10 +10 +-9 +10 +-10 +12 +-10 +11 +-10 +13 +-10 +10 +-10 +10 +-11 +10 +-10 +10 +-10 +8 +-10 +11 +-9 +12 +-10 +10 +-10 +12 +-10 +10 +-10 +10 +-10 +12 +-10 +11 +-10 +10 +-10 +9 +-7 +9 +-10 +11 +-9 +12 +-11 +10 +-11 +9 +-11 +12 +-11 +10 +-10 +10 +-10 +8 +-9 +11 +-10 +10 +-11 +11 +-9 +11 +-10 +12 +-10 +11 +-11 +11 +-9 +9 +-10 +11 +-10 +8 +-11 +11 +-8 +9 +-10 +12 +-11 +11 +-10 +10 +-10 +10 +-11 +9 +-9 +9 +-11 +13 +-9 +9 +-11 +11 +-10 +12 +-9 +11 +-10 +10 +-11 +10 +-11 +10 +-9 +10 +-11 +11 +-11 +12 +-10 +9 +-10 +11 +-9 +11 +-8 +10 +-11 +11 +-10 +10 +-8 +11 +-10 +12 +-11 +12 +-9 +11 +-10 +11 +-11 +10 +-10 +10 +-10 +10 +-11 +10 +-11 +9 +-10 +9 +-10 +9 +-9 +11 +-12 +11 +-12 +9 +-11 +10 +-11 +10 +-10 +10 +-10 +9 +-8 +9 +-12 +11 +-9 +11 +-11 +11 +-11 +10 +-11 +12 +-10 +11 +-10 +9 +-10 +11 +-10 +10 +-10 +11 +-9 +9 +-9 +10 +-10 +10 +-10 +10 +-11 +11 +-9 +11 +-10 +9 +-10 +11 +-10 +11 +-10 +13 +-10 +10 +-9 +9 +-9 +10 +-9 +11 +-11 +11 +-10 +11 +-8 +9 +-10 +10 +-10 +11 +-9 +11 +-10 +11 +-9 +13 +-9 +11 +-11 +12 +-9 +9 +-12 +12 +-10 +12 +-11 +12 +-10 +10 +-10 +11 +-9 +11 +-12 +10 +-10 +11 +-9 +10 +-10 +11 +-10 +10 +-9 +11 +-9 +12 +-11 +12 +-10 +11 +-10 +10 +-10 +9 +-10 +10 +-10 +10 +-10 +10 +-11 +10 +-11 +10 +-11 +10 +-11 +10 +-9 +8 +-11 +12 +-10 +10 +-9 +8 +-9 +13 +-13 +11 +-10 +11 +-11 +9 +-10 +10 +-11 +12 +-9 +12 +-10 +10 +-10 +10 +-10 +12 +-10 +11 +-10 +11 +-10 +11 +-10 +10 +-10 +11 +-10 +10 +-10 +9 +-10 +11 +-11 +11 +-11 +10 +-10 +11 +-9 +8 +-10 +11 +-8 +12 +-11 +11 +-10 +10 +-8 +9 +-10 +10 +-9 +8 +-9 +10 +-10 +12 +-10 +10 +-10 +12 +-10 +10 +-9 +10 +-9 +9 +-9 +10 +-11 +11 +-11 +10 +-10 +9 +-10 +11 +-11 +11 +-10 +10 +-11 +12 +-10 +11 +-10 +12 +-12 +11 +-11 +10 +-10 +9 +-11 +10 +-10 +11 +-9 +11 +-10 +9 +-9 +11 +-9 +11 +-10 +10 +-9 +11 +-10 +12 +-9 +12 +-9 +10 +-10 +11 +-11 +9 +-10 +9 +-10 +11 +-11 +12 +-11 +11 +-11 +9 +-10 +9 +-11 +11 +-11 +12 +-9 +10 +-11 +10 +-10 +11 +-11 +10 +-9 +10 +-9 +9 +-10 +12 +-10 +12 +-10 +10 +-10 +10 +-10 +12 +-10 +11 +-10 +10 +-10 +12 +-10 +11 +-8 +11 +-11 +11 +-9 +12 +-10 +10 +-10 +12 +-9 +10 +-9 +10 +-10 +10 +-11 +10 +-10 +10 +-10 +11 +-11 +11 +-11 +9 +-10 +12 +-11 +10 +-8 +10 +-8 +11 +-10 +11 +-10 +10 +-10 +10 +-10 +10 +-10 +9 +-11 +9 +-9 +9 +-12 +10 +-10 +10 +-10 +9 +-10 +10 +-10 +10 +-11 +10 +-10 +10 +-10 +10 +-11 +12 +-10 +9 +-11 +12 +-10 +10 +-10 +9 +-11 +12 +-10 +11 +-8 +9 +-10 +10 +-11 +10 +-10 +10 +-10 +12 +-10 +9 +-10 +12 +-13 +13 +-9 +9 +-11 +11 +-9 +10 +-9 +11 +-10 +9 +-10 +10 +-10 +11 +-9 +8 +-11 +10 +-11 +10 +-11 +10 +-10 +8 +-9 +10 +-10 +12 +-9 +10 +-9 +12 +-10 +12 +-9 +12 +-10 +11 +-10 +12 +-10 +9 +-10 +11 +-9 +11 +-9 +11 +-9 +10 +-10 +10 +-10 +10 +-10 +11 +-11 +11 +-11 +10 +-10 +11 +-10 +10 +-10 +9 +-10 +9 +-9 +10 +-10 +12 +-10 +10 +-11 +12 +-9 +10 +-9 +10 +-10 +11 +-11 +10 +-9 +11 +-9 +11 +-11 +11 +-11 +11 +-9 +10 +-9 +10 +-9 +11 +-10 +9 +-9 +11 +-9 +12 +-11 +10 +-9 +10 +-10 +11 +-10 +11 +-10 +11 +-11 +12 +-10 +10 +-10 +10 +-12 +12 +-10 +11 +-11 +11 +-10 +10 +-10 +11 +-10 +11 +-9 +10 +-11 +9 +-10 +11 +-10 +11 +-11 +10 +-9 +10 +-11 +11 +-9 +11 +-10 +11 +-8 +11 +-9 +11 +-9 +11 +-10 +12 +-11 +10 +-9 +10 +-11 +11 +-9 +10 +-10 +9 +-11 +10 +-10 +9 +-9 +10 +-10 +11 +-12 +10 +-7 +7 +-11 +10 +-11 +10 +-10 +9 +-10 +10 +-10 +10 +-10 +11 +-10 +12 +-10 +9 +-10 +9 +-10 +10 +-9 +12 +-10 +14 +11 +-15 +10 +-11 +9 +-10 +9 +-10 +9 +-11 +9 +-11 +9 +-10 +11 +-9 +10 +-10 +11 +-11 +10 +-9 +9 +-8 +10 +-9 +10 +-9 +10 +-10 +9 +-10 +10 +-9 +10 +-9 +9 +-9 +9 +-9 +11 +-11 +9 +-9 +9 +-11 +9 +-10 +9 +-9 +8 +-10 +10 +-11 +9 +-10 +10 +-9 +10 +-10 +9 +-10 +9 +-11 +11 +-11 +10 +-9 +8 +-9 +11 +-9 +9 +-9 +9 +-10 +10 +-10 +10 +-10 +9 +-10 +10 +-9 +10 +-10 +10 +-10 +9 +-10 +10 +-10 +12 +-6 +9 +-13 +-6 +15 +-7 +11 +-9 +12 +-8 +12 +-9 +11 +-9 +11 +-9 +12 +-9 +10 +-10 +12 +-9 +12 +-10 +11 +-9 +12 +-9 +11 +-10 +12 +-10 +10 +-9 +9 +-8 +11 +-10 +12 +-10 +10 +-10 +10 +-11 +11 +-10 +10 +-11 +11 +-9 +10 +-10 +10 +-10 +11 +-11 +10 +-11 +10 +-10 +9 +-9 +11 +-10 +11 +-10 +11 +-11 +12 +-10 +9 +-10 +11 +-9 +11 +-11 +10 +-10 +11 +-11 +9 +-9 +10 +-11 +11 +-9 +10 +-9 +12 +-9 +10 +-9 +9 +-9 +11 +-9 +10 +-9 +12 +10 +-15 +11 +-11 +10 +-11 +9 +-10 +9 +-10 +9 +-11 +8 +-10 +8 +-11 +9 +-12 +10 +-10 +8 +-11 +10 +-9 +10 +-10 +12 +-10 +12 +-8 +8 +-9 +12 +-10 +10 +-9 +10 +-10 +10 +-9 +11 +-9 +10 +-11 +9 +-9 +9 +-11 +10 +-10 +10 +-7 +8 +-9 +10 +-8 +10 +-9 +10 +-10 +11 +-9 +11 +-13 +-6 +13 +-8 +10 +-8 +11 +-8 +8 +-9 +12 +-8 +10 +-9 +11 +-9 +10 +-9 +11 +-11 +12 +-11 +11 +-10 +9 +-10 +11 +-11 +11 +-9 +10 +-10 +10 +-10 +9 +-9 +10 +-11 +10 +-10 +11 +-10 +11 +-11 +8 +-11 +10 +-10 +11 +-9 +9 +-8 +9 +-10 +12 +-10 +11 +-9 +10 +-9 +9 +-9 +8 +-10 +10 +-9 +11 +-9 +8 +-9 +9 +-9 +11 +-10 +11 +-10 +11 +-12 +13 +-9 +10 +-9 +11 +-9 +11 +-10 +11 +-10 +10 +-10 +10 +-10 +11 +-11 +10 +-9 +8 +-10 +10 +-11 +9 +-12 +11 +-12 +11 +-10 +12 +-8 +9 +-9 +12 +-9 +10 +-9 +10 +-9 +11 +-10 +11 +-10 +12 +-9 +12 +-9 +10 +-9 +10 +-9 +13 +9 +-15 +11 +-11 +8 +-11 +11 +-11 +10 +-9 +10 +-10 +10 +-10 +9 +-11 +11 +-10 +10 +-10 +11 +-11 +10 +-11 +11 +-10 +10 +-11 +11 +-9 +8 +-13 +-8 +15 +-8 +11 +-9 +10 +-8 +12 +-10 +11 +-9 +12 +-8 +12 +-9 +12 +-10 +10 +-11 +11 +-10 +10 +-9 +11 +-11 +10 +-10 +10 +-11 +10 +-9 +11 +-11 +10 +-10 +9 +-11 +10 +-9 +11 +-10 +10 +-11 +10 +-11 +10 +-9 +8 +-11 +11 +-10 +10 +-11 +11 +-9 +10 +-9 +11 +-11 +12 +-10 +11 +-10 +10 +-8 +10 +-10 +11 +-10 +11 +-9 +7 +-12 +12 +-8 +9 +-9 +10 +-9 +12 +-10 +10 +-8 +11 +-9 +11 +-10 +9 +-10 +10 +-10 +10 +-9 +11 +-10 +14 +10 +-13 +11 +-11 +10 +-10 +10 +-11 +9 +-11 +9 +-10 +9 +-11 +10 +-10 +10 +-11 +9 +-10 +9 +-11 +9 +-10 +11 +-10 +9 +-10 +9 +-10 +9 +-11 +10 +-10 +11 +-10 +9 +-9 +9 +-8 +9 +-10 +10 +-9 +9 +-9 +10 +-9 +11 +-10 +9 +-8 +8 +-11 +9 +-10 +11 +-9 +11 +-8 +11 +-8 +10 +-11 +-7 +15 +-7 +10 +-9 +11 +-8 +10 +-11 +11 +-9 +10 +-10 +13 +-10 +11 +-9 +10 +-10 +9 +-8 +11 +-9 +10 +-8 +10 +-10 +11 +-9 +12 +-9 +11 +-9 +11 +-10 +11 +-9 +11 +-12 +11 +-9 +9 +-8 +12 +-11 +11 +-10 +12 +-9 +10 +-10 +12 +-9 +9 +-10 +11 +-10 +9 +-10 +9 +-9 +11 +-11 +10 +-10 +10 +-10 +9 +-11 +11 +-10 +9 +-11 +9 +-11 +9 +-12 +11 +-11 +10 +-10 +10 +-10 +10 +-11 +12 +-10 +9 +-10 +11 +-11 +11 +-9 +11 +-9 +12 +-7 +10 +-9 +12 +-10 +10 +-9 +11 +-10 +13 +-9 +11 +-11 +10 +-10 +10 +-10 +10 +-11 +13 +-11 +10 +-11 +11 +-9 +10 +-11 +9 +-12 +11 +-9 +8 +-10 +10 +-10 +11 +-9 +10 +-10 +11 +-9 +11 +-9 +12 +-12 +12 +-10 +10 +-10 +10 +-11 +9 +-11 +10 +-11 +10 +-10 +10 +-9 +10 +-11 +10 +-10 +9 +-9 +11 +-9 +10 +-11 +10 +-10 +9 +-12 +13 +-10 +10 +-10 +11 +-9 +9 +-11 +10 +-8 +10 +-10 +11 +-9 +10 +-10 +10 +-10 +10 +-10 +9 +-10 +12 +12 +-14 +9 +-12 +11 +-10 +11 +-11 +10 +-11 +9 +-11 +8 +-11 +10 +-10 +10 +-8 +10 +-10 +11 +-10 +10 +-10 +10 +-9 +10 +-10 +9 +-10 +9 +-9 +11 +-9 +10 +-9 +9 +-11 +13 +-11 +10 +-9 +10 +-11 +9 +-11 +9 +-10 +10 +-10 +9 +-9 +9 +-10 +10 +-9 +11 +-9 +11 +-10 +10 +-7 +11 +-12 +-6 +13 +-7 +11 +-8 +9 +-7 +10 +-9 +9 +-9 +9 +-9 +9 +-10 +10 +-10 +12 +-9 +10 +-8 +8 +-11 +10 +-9 +10 +-9 +11 +-10 +10 +-10 +11 +-9 +10 +-9 +10 +-11 +12 +-7 +8 +-10 +11 +-11 +12 +-10 +9 +-10 +11 +-9 +11 +-11 +10 +-10 +10 +-10 +13 +-11 +12 +-10 +11 +-10 +12 +-10 +10 +-10 +11 +-10 +10 +-9 +12 +-9 +12 +-11 +10 +-9 +10 +-10 +10 +-10 +10 +-11 +10 +-10 +9 +-8 +11 +-11 +12 +-11 +11 +-10 +11 +-11 +10 +-10 +11 +-10 +11 +-9 +11 +-9 +11 +-9 +10 +-11 +13 +-12 +12 +-11 +11 +-9 +10 +-10 +11 +-11 +10 +-9 +10 +-10 +9 +-10 +10 +-9 +10 +-10 +11 +-12 +9 +-11 +11 +-11 +10 +-10 +10 +-10 +9 +-10 +10 +-9 +12 +-11 +11 +-10 +9 +-10 +10 +-9 +9 +-11 +10 +-11 +10 +-10 +10 +-9 +10 +-10 +10 +-10 +14 +10 +-15 +10 +-12 +8 +-10 +10 +-11 +8 +-11 +8 +-11 +9 +-10 +9 +-11 +8 +-9 +8 +-9 +8 +-11 +10 +-10 +9 +-10 +9 +-9 +10 +-10 +12 +-10 +9 +-9 +11 +-9 +10 +-9 +9 +-10 +9 +-10 +9 +-10 +12 +-11 +11 +-10 +9 +-11 +11 +-9 +8 +-10 +9 +-9 +9 +-10 +11 +-10 +11 +-10 +11 +-13 +-8 +15 +-9 +10 +-9 +11 +-9 +10 +-9 +12 +-8 +10 +-8 +10 +-9 +12 +-10 +11 +-10 +11 +-8 +10 +-9 +11 +-9 +11 +-10 +11 +-12 +9 +-10 +12 +11 +-15 +10 +-10 +10 +-10 +12 +-12 +10 +-11 +9 +-10 +9 +-9 +8 +-11 +9 +-12 +10 +-9 +8 +-8 +8 +-9 +10 +-10 +10 +-10 +10 +-9 +10 +-13 +-6 +16 +-8 +11 +-7 +12 +-9 +12 +-8 +12 +-8 +10 +-8 +11 +-9 +11 +-9 +12 +-10 +11 +-10 +9 +-10 +10 +-8 +9 +-10 +12 +-10 +11 +-9 +10 +-10 +9 +-11 +11 +-10 +8 +-10 +10 +-9 +10 +-11 +11 +-10 +9 +-9 +10 +-10 +11 +-9 +8 +-10 +12 +-10 +9 +-9 +10 +-11 +12 +-10 +11 +-8 +11 +-9 +10 +-10 +11 +-10 +10 +-11 +10 +-10 +11 +-10 +9 +-11 +10 +-10 +10 +-10 +12 +-9 +9 +-10 +11 +-9 +10 +-11 +10 +-10 +12 +-10 +12 +-11 +10 +-11 +11 +-11 +12 +-10 +10 +-12 +11 +-10 +10 +-9 +10 +-9 +11 +-11 +11 +-10 +9 +-10 +11 +-12 +9 +-10 +11 +-11 +9 +-10 +10 +-9 +11 +-9 +10 +-10 +11 +-11 +10 +-12 +8 +-10 +9 +-10 +12 +-10 +9 +-8 +11 +-10 +11 +-11 +10 +-8 +11 +-12 +11 +-11 +11 +-9 +9 +-9 +12 +-10 +10 +-10 +11 +-10 +10 +-10 +10 +-10 +10 +-11 +9 +-9 +10 +-10 +11 +-9 +10 +-10 +11 +-10 +9 +-11 +12 +-9 +12 +-9 +10 +-10 +11 +-11 +11 +-10 +11 +-10 +9 +-10 +10 +-11 +11 +-11 +10 +-10 +9 +-11 +9 +-10 +10 +-11 +10 +-11 +11 +-10 +10 +-10 +10 +-10 +10 +-10 +10 +-9 +12 +-9 +12 +-9 +14 +-10 +11 +-9 +12 +-10 +13 +-9 +11 +-8 +12 +-9 +13 +-8 +13 +-8 +10 +-9 +11 +-9 +12 +-10 +11 +-9 +10 +-11 +10 +-12 +10 +-12 +9 +-12 +9 +-10 +10 +-10 +9 +-10 +8 +-10 +8 +-10 +10 +-11 +9 +-10 +10 +-10 +9 +-10 +12 +-11 +10 +-10 +11 +-8 +9 +-11 +11 +-11 +10 +-9 +9 +-11 +14 +-11 +10 +-9 +10 +-9 +11 +-8 +9 +-11 +12 +-10 +10 +-11 +10 +-11 +10 +-10 +9 +-8 +11 +-11 +11 +-11 +11 +-10 +10 +-11 +12 +-10 +11 +-11 +10 +-10 +11 +-9 +11 +-10 +11 +-11 +10 +-9 +11 +-11 +12 +-11 +11 +-10 +9 +-9 +10 +-9 +10 +-10 +10 +-12 +12 +-9 +10 +-11 +12 +-10 +10 +-9 +11 +-9 +11 +-10 +12 +-11 +9 +-9 +10 +-12 +12 +-11 +11 +-10 +9 +-11 +9 +-10 +10 +-10 +11 +-11 +11 +-9 +9 +-10 +10 +-10 +10 +-10 +10 +-10 +9 +-9 +10 +-10 +10 +-10 +12 +-10 +10 +-10 +10 +-10 +11 +-10 +10 +-12 +12 +-11 +10 +-9 +9 +-10 +10 +-11 +10 +-10 +9 +-9 +11 +-10 +10 +-8 +10 +-9 +10 +-9 +10 +-9 +12 +-9 +12 +-10 +12 +-8 +11 +-9 +11 +-10 +11 +-11 +10 +-11 +10 +-11 +11 +-10 +9 +-10 +10 +-11 +12 +-11 +11 +-10 +9 +-10 +11 +-11 +11 +-10 +10 +-10 +12 +-11 +11 +-9 +10 +-11 +11 +-10 +11 +-10 +10 +-10 +12 +-10 +12 +-10 +12 +-10 +10 +-9 +12 +-8 +12 +-9 +11 +-9 +10 +-9 +11 +-9 +10 +-9 +11 +-11 +10 +-10 +10 +-10 +9 +-10 +10 +-12 +11 +-10 +10 +-9 +10 +-9 +9 +-9 +12 +-8 +10 +-10 +12 +-10 +10 +-10 +11 +-10 +9 +-11 +11 +-11 +11 +-10 +10 +-10 +11 +-9 +12 +-11 +10 +-11 +11 +-10 +11 +-11 +10 +-11 +12 +-9 +11 +-10 +11 +-11 +10 +-10 +9 +-9 +9 +-11 +10 +-11 +10 +-11 +11 +-11 +9 +-11 +11 +-11 +9 +-11 +8 +-10 +11 +-10 +12 +-11 +11 +-11 +12 +-9 +10 +-9 +10 +-10 +12 +-10 +12 +-10 +11 +-11 +11 +-10 +10 +-11 +10 +-11 +11 +-8 +11 +-10 +12 +-11 +12 +-10 +10 +-9 +11 +-10 +11 +-10 +9 +-9 +12 +-11 +9 +-11 +8 +-10 +10 +-11 +13 +-10 +10 +-9 +10 +-9 +11 +-8 +10 +-10 +11 +-9 +11 +-9 +11 +-9 +10 +-10 +11 +-9 +11 +-10 +12 +-9 +12 +-10 +10 +-9 +11 +-10 +11 +-9 +10 +-10 +11 +-10 +10 +-10 +12 +-12 +9 +-11 +10 +-11 +10 +-11 +9 +-12 +11 +-11 +11 +-11 +9 +-9 +10 +-11 +10 +-10 +11 +-10 +12 +-9 +10 +-10 +12 +-10 +10 +-8 +10 +-9 +12 +-11 +10 +-11 +10 +-9 +11 +-11 +9 +-9 +9 +-11 +10 +-10 +13 +-10 +10 +-10 +11 +-9 +11 +-9 +9 +-9 +12 +-9 +7 +-10 +12 +-11 +10 +-10 +11 +-10 +11 +-10 +12 +-11 +11 +-9 +9 +-10 +10 +-10 +13 +-11 +11 +-9 +8 +-11 +12 +-11 +9 +-11 +12 +-11 +11 +-10 +10 +-10 +10 +-10 +10 +-10 +11 +-10 +11 +-9 +10 +-9 +9 +-11 +10 +-10 +11 +-11 +9 +-11 +12 +-10 +10 +-11 +12 +-10 +13 +-10 +10 +-11 +9 +-12 +12 +-11 +10 +-11 +9 +-11 +10 +-10 +10 +-11 +11 +-11 +10 +-9 +12 +-10 +12 +-8 +11 +-9 +11 +-10 +11 +-10 +13 +-9 +11 +-9 +12 +-10 +10 +-10 +12 +-9 +11 +-9 +9 +-11 +10 +-10 +9 +-10 +10 +-10 +10 +-11 +11 +-10 +9 +-10 +11 +-10 +11 +-11 +9 +-11 +9 +-9 +11 +-9 +11 +-11 +10 +-11 +9 +-11 +11 +-11 +9 +-10 +11 +-11 +10 +-10 +12 +-12 +10 +-10 +9 +-10 +11 +-11 +10 +-11 +11 +-10 +9 +-11 +10 +-10 +11 +-10 +11 +-10 +10 +-9 +10 +-9 +12 +-10 +13 +-9 +10 +-10 +10 +-10 +10 +-8 +10 +-9 +12 +-10 +11 +-11 +9 +-11 +12 +-10 +7 +-10 +11 +-11 +12 +-10 +11 +-10 +11 +-12 +9 +-9 +10 +-10 +10 +-10 +10 +-11 +10 +-10 +10 +-10 +11 +-9 +11 +-11 +11 +-10 +12 +-10 +11 +-10 +10 +-9 +13 +-8 +11 +-10 +11 +-9 +9 +-10 +15 +11 +-14 +10 +-11 +10 +-10 +9 +-11 +10 +-11 +11 +-12 +10 +-9 +9 +-11 +12 +-11 +12 +-11 +9 +-10 +9 +-9 +9 +-10 +9 +-9 +9 +-10 +10 +-9 +9 +-10 +8 +-10 +10 +-10 +9 +-10 +9 +-10 +10 +-11 +10 +-11 +9 +-10 +10 +-9 +9 +-9 +9 +-10 +10 +-9 +11 +-9 +8 +-9 +9 +-10 +9 +-10 +11 +-10 +9 +-9 +9 +-10 +8 +-9 +9 +-9 +10 +-10 +10 +-9 +8 +-10 +9 +-9 +10 +-11 +9 +-10 +10 +-9 +11 +-9 +9 +-7 +9 +-9 +10 +-13 +-6 +14 +-9 +11 +-10 +11 +-8 +10 +-8 +12 +-8 +11 +-9 +11 +-8 +13 +-10 +12 +-9 +10 +-9 +12 +-8 +9 +-11 +11 +-10 +10 +-10 +9 +-10 +11 +-9 +11 +-10 +10 +-9 +11 +-10 +10 +-11 +11 +-11 +10 +-10 +11 +-10 +12 +-11 +11 +-11 +12 +-9 +10 +-10 +11 +-9 +12 +-11 +10 +-9 +11 +-11 +11 +-11 +9 +-11 +10 +-11 +12 +-9 +11 +-11 +11 +-10 +12 +-9 +11 +-10 +11 +-9 +10 +-9 +12 +-11 +10 +-11 +12 +-10 +10 +-9 +10 +-10 +10 +-11 +15 +10 +-16 +10 +-10 +9 +-11 +9 +-11 +8 +-10 +8 +-11 +9 +-10 +9 +-9 +10 +-11 +9 +-10 +11 +-9 +8 +-11 +10 +-10 +8 +-9 +9 +-10 +11 +-9 +10 +-9 +11 +-10 +11 +-8 +10 +-10 +11 +-11 +9 +-9 +10 +-11 +9 +-9 +9 +-9 +10 +-9 +9 +-10 +11 +-8 +9 +-10 +10 +-9 +10 +-9 +10 +-13 +-7 +13 +-8 +12 +-8 +11 +-9 +10 +-9 +11 +-9 +11 +-9 +10 +-9 +9 +-10 +11 +-10 +10 +-10 +10 +-10 +11 +-10 +9 +-8 +11 +-10 +10 +-11 +10 +-10 +10 +-11 +9 +-9 +10 +-9 +11 +-9 +10 +-9 +11 +-12 +11 +-11 +10 +-11 +10 +-9 +10 +-10 +10 +-11 +10 +-9 +10 +-9 +11 +-10 +12 +-10 +10 +-10 +11 +-11 +10 +-10 +10 +-9 +12 +-10 +11 +-9 +10 +-11 +11 +-11 +11 +-10 +11 +-10 +12 +-8 +8 +-10 +13 +-9 +11 +-9 +10 +-10 +11 +-9 +9 +-9 +10 +-10 +10 +-10 +10 +-10 +11 +-10 +12 +-12 +10 +-11 +10 +-10 +10 +-11 +11 +-11 +10 +-11 +12 +-9 +10 +-11 +10 +-11 +11 +-10 +9 +-11 +13 +10 +-16 +10 +-14 +10 +-11 +6 +-10 +10 +-11 +10 +-11 +11 +-8 +9 +-9 +8 +-10 +9 +-10 +9 +-10 +10 +-10 +11 +-9 +9 +-10 +9 +-11 +10 +-12 +-9 +14 +-9 +10 +-9 +10 +-10 +11 +-9 +10 +-9 +11 +-9 +12 +-9 +11 +-8 +10 +-9 +12 +-9 +11 +-9 +10 +-9 +9 +-10 +11 +-9 +10 +-10 +10 +-12 +13 +-11 +12 +-11 +11 +-9 +9 +-11 +12 +-11 +9 +-9 +10 +-9 +9 +-12 +11 +-10 +11 +-10 +9 +-10 +10 +-10 +10 +-9 +10 +-10 +11 +-10 +10 +-11 +11 +-8 +11 +-10 +11 +-9 +12 +-9 +11 +-9 +9 +-10 +12 +-12 +10 +-10 +12 +-10 +9 +-9 +10 +-11 +10 +-10 +9 +-10 +9 +-10 +11 +-9 +14 +11 +-15 +10 +-11 +10 +-12 +7 +-8 +8 +-12 +10 +-10 +12 +-9 +11 +-10 +9 +-7 +8 +-11 +10 +-9 +9 +-10 +9 +-10 +11 +-9 +10 +-8 +11 +-10 +11 +-7 +10 +-8 +10 +-9 +10 +-9 +12 +-10 +10 +-9 +10 +-9 +9 +-10 +10 +-10 +9 +-10 +9 +-10 +10 +-11 +9 +-8 +7 +-10 +9 +-9 +11 +-14 +-8 +14 +-8 +10 +-8 +9 +-9 +10 +-10 +10 +-9 +11 +-11 +9 +-10 +10 +-10 +11 +-11 +9 +-10 +9 +-11 +10 +-8 +11 +-9 +10 +-9 +10 +-10 +12 +-8 +9 +-10 +11 +-9 +10 +-9 +10 +-10 +10 +-10 +11 +-10 +9 +-10 +9 +-10 +12 +-10 +11 +-10 +10 +-11 +10 +-9 +10 +-10 +11 +-12 +10 +-12 +9 +-8 +8 +-12 +12 +-10 +11 +-10 +10 +-10 +9 +-11 +12 +-9 +10 +-9 +10 +-11 +11 +-10 +11 +-11 +11 +-10 +11 +-10 +11 +-9 +10 +-9 +12 +-9 +10 +-8 +11 +-8 +10 +-8 +12 +-7 +9 +-9 +11 +-10 +12 +-11 +11 +-10 +12 +-9 +11 +-9 +11 +-11 +10 +-10 +10 +-10 +10 +-10 +11 +-11 +10 +-10 +11 +-10 +7 +-11 +11 +-10 +10 +-9 +10 +-12 +11 +-10 +10 +-11 +11 +-11 +10 +-11 +10 +-11 +10 +-10 +9 +-10 +10 +-9 +9 +-10 +11 +-10 +11 +-10 +10 +-11 +11 +-9 +10 +-11 +10 +-10 +12 +-10 +11 +-11 +11 +-10 +11 +-9 +12 +-10 +11 +-12 +13 +-9 +12 +-9 +12 +-10 +11 +-10 +10 +-8 +9 +-11 +12 +11 +-16 +10 +-11 +8 +-11 +8 +-11 +9 +-11 +8 +-11 +11 +-9 +9 +-10 +11 +-12 +11 +-9 +10 +-9 +10 +-9 +10 +-10 +10 +-11 +10 +-11 +9 +-9 +10 +-9 +7 +-11 +10 +-11 +9 +-10 +9 +-10 +10 +-10 +9 +-9 +10 +-9 +9 +-10 +11 +-10 +10 +-8 +9 +-9 +10 +-8 +10 +-7 +10 +-10 +10 +-12 +-9 +13 +-7 +11 +-11 +10 +-10 +11 +-9 +10 +-9 +11 +-9 +10 +-8 +11 +-9 +11 +-9 +13 +-8 +11 +-10 +11 +-9 +9 +-10 +10 +-10 +9 +-10 +10 +-11 +10 +-10 +9 +-11 +13 +-9 +11 +-8 +10 +-8 +10 +-8 +11 +-9 +11 +-10 +10 +-10 +10 +-10 +13 +-11 +9 +-10 +9 +-10 +11 +-9 +8 +-9 +10 +-11 +12 +-12 +11 +-10 +12 +-9 +9 +-12 +12 +-9 +10 +-9 +10 +-10 +10 +-11 +11 +-10 +10 +-10 +10 +-10 +9 +-11 +11 +-10 +9 +-10 +9 +-10 +13 +-11 +10 +-10 +9 +-11 +10 +-9 +11 +-11 +11 +-9 +11 +-11 +13 +-10 +12 +-10 +10 +-10 +10 +-8 +10 +-10 +9 +-11 +12 +-10 +11 +-8 +8 +-10 +11 +-11 +10 +-9 +12 +-11 +10 +-10 +12 +-11 +12 +-10 +10 +-11 +10 +-10 +12 +-9 +9 +-11 +12 +-9 +12 +-9 +11 +-10 +11 +-9 +12 +-11 +12 +-10 +14 +10 +-16 +11 +-12 +10 +-10 +9 +-12 +10 +-11 +9 +-9 +10 +-10 +9 +-11 +9 +-10 +10 +-10 +9 +-10 +9 +-10 +10 +-10 +9 +-10 +9 +-9 +8 +-10 +9 +-9 +9 +-10 +8 +-10 +10 +-9 +11 +-8 +10 +-10 +11 +-10 +10 +-10 +11 +-8 +10 +-9 +10 +-8 +9 +-8 +10 +-9 +11 +-9 +12 +-12 +8 +-12 +-8 +13 +-10 +9 +-10 +10 +-9 +12 +-9 +10 +-11 +10 +-10 +10 +-9 +10 +-9 +11 +-9 +11 +-8 +12 +-9 +12 +-9 +10 +-10 +10 +-9 +9 +-10 +15 +11 +-14 +11 +-11 +11 +-10 +10 +-9 +9 +-10 +11 +-9 +9 +-11 +10 +-11 +9 +-10 +9 +-10 +8 +-11 +10 +-10 +8 +-9 +9 +-9 +10 +-10 +11 +-14 +-8 +14 +-7 +10 +-12 +11 +-9 +11 +-9 +9 +-9 +10 +-10 +10 +-11 +10 +-10 +9 +-10 +10 +-10 +10 +-11 +10 +-11 +10 +-9 +10 +-9 +11 +-9 +11 +-10 +10 +-9 +9 +-9 +10 +-11 +10 +-9 +10 +-9 +9 +-9 +10 +-9 +10 +-11 +11 +-8 +8 +-9 +11 +-9 +9 +-9 +11 +-11 +10 +-10 +11 +-11 +9 +-10 +13 +-10 +10 +-11 +11 +-11 +11 +-10 +11 +-10 +10 +-9 +12 +-12 +9 +-9 +10 +-10 +11 +-12 +11 +-9 +10 +-10 +11 +-9 +9 +-11 +11 +-8 +10 +-11 +12 +-9 +11 +-10 +11 +-10 +10 +-10 +11 +-8 +9 +-10 +12 +-10 +11 +-10 +11 +-10 +10 +-10 +9 +-9 +9 +-10 +12 +-9 +8 +-11 +11 +-10 +10 +-11 +10 +-10 +9 +-11 +11 +-11 +9 +-9 +11 +-10 +10 +-10 +11 +-9 +12 +-10 +8 +-9 +10 +-10 +11 +-9 +12 +-9 +10 +-8 +10 +-10 +11 +-10 +11 +-10 +10 +-9 +9 +-10 +10 +-10 +9 +-11 +10 +-11 +12 +-8 +9 +-11 +11 +-10 +10 +-10 +10 +-11 +11 +-9 +8 +-11 +11 +-11 +12 +-9 +9 +-10 +11 +-10 +10 +-11 +10 +-9 +11 +-8 +9 +-10 +12 +-11 +10 +-9 +10 +-10 +9 +-11 +12 +-10 +11 +-10 +11 +-10 +10 +-11 +11 +-8 +8 +-9 +12 +-8 +11 +-9 +11 +-10 +12 +-10 +9 +-8 +10 +-10 +10 +-9 +10 +-10 +12 +-9 +11 +-10 +9 +-8 +11 +-11 +11 +-10 +11 +-9 +11 +-9 +11 +-10 +11 +-9 +8 +-10 +10 +-10 +9 +-11 +10 +-10 +9 +-10 +9 +-9 +9 +-10 +10 +-10 +11 +-10 +11 +-10 +11 +-10 +11 +-11 +11 +-10 +10 +-10 +11 +-10 +10 +-10 +11 +-10 +9 +-10 +11 +-11 +12 +-10 +11 +-10 +9 +-11 +10 +-10 +10 +-10 +9 +-11 +9 +-12 +10 +-10 +9 +-10 +9 +-10 +10 +-10 +11 +-9 +11 +-11 +11 +-11 +11 +-11 +10 +-9 +10 +-9 +12 +-11 +11 +-11 +12 +-11 +10 +-11 +12 +-9 +13 +-10 +10 +-9 +12 +-10 +11 +-9 +11 +-8 +10 +-11 +12 +-11 +10 +-10 +11 +-10 +11 +-11 +9 +-10 +10 +-10 +10 +-10 +11 +-10 +9 +-12 +11 +-10 +10 +-10 +10 +-10 +11 +-10 +10 +-10 +11 +-10 +11 +-10 +9 +-10 +9 +-11 +11 +-11 +11 +-10 +9 +-11 +11 +-10 +10 +-9 +10 +-10 +10 +-9 +11 +-9 +9 +-10 +10 +-10 +13 +-10 +11 +-10 +11 +-8 +9 +-11 +13 +-9 +10 +-9 +11 +-11 +11 +-10 +10 +-9 +9 +-10 +9 +-11 +11 +-11 +12 +-11 +11 +-8 +10 +-8 +12 +-9 +12 +-8 +12 +-9 +10 +-11 +14 +-11 +10 +-10 +12 +-10 +11 +-11 +11 +-9 +8 +-10 +10 +-10 +11 +-10 +10 +-10 +9 +-11 +12 +-11 +10 +-10 +10 +-10 +10 +-11 +11 +-10 +10 +-10 +9 +-10 +10 +-9 +12 +-9 +10 +-10 +12 +-10 +10 +-9 +9 +-10 +10 +-9 +10 +-10 +10 +-10 +11 +-9 +11 +-10 +10 +-11 +12 +-10 +10 +-11 +11 +-10 +10 +-11 +11 +-8 +11 +-9 +10 +-10 +11 +-10 +11 +-10 +10 +-11 +13 +-10 +9 +-9 +10 +-9 +12 +-9 +10 +-10 +10 +-10 +10 +-11 +10 +-10 +10 +-9 +9 +-9 +11 +-11 +8 +-10 +10 +-11 +10 +-9 +10 +-10 +11 +-10 +12 +-10 +11 +-9 +11 +-11 +13 +-11 +10 +-10 +8 +-9 +10 +-10 +10 +-10 +11 +-9 +11 +-10 +11 +-10 +11 +-10 +10 +-10 +9 +-10 +14 +-10 +10 +-9 +11 +-9 +10 +-10 +11 +-9 +10 +-11 +11 +-9 +12 +-11 +10 +-11 +10 +-9 +10 +-11 +10 +-11 +11 +-12 +11 +-10 +12 +-11 +10 +-11 +12 +-9 +12 +-10 +10 +-11 +11 +-10 +9 +-9 +8 +-11 +11 +-10 +11 +-12 +11 +-10 +9 +-10 +11 +-10 +10 +-11 +12 +-10 +12 +-11 +9 +-10 +12 +-11 +11 +-9 +9 +-8 +10 +-10 +10 +-9 +8 +-7 +10 +-11 +11 +-11 +8 +-10 +10 +-11 +11 +-11 +9 +-10 +9 +-10 +9 +-12 +11 +-11 +9 +-9 +9 +-12 +9 +-10 +8 +-11 +10 +-9 +9 +-11 +10 +-9 +10 +-9 +11 +-9 +12 +-9 +13 +-10 +13 +-8 +9 +-10 +11 +-10 +10 +-10 +11 +-9 +11 +-10 +9 +-10 +9 +-9 +11 +-10 +12 +-9 +11 +-9 +11 +-9 +11 +-10 +12 +-9 +10 +-9 +12 +-9 +12 +-10 +10 +-11 +11 +-11 +10 +-11 +9 +-9 +11 +-12 +11 +-9 +10 +-11 +10 +-9 +10 +-11 +10 +-11 +10 +-10 +8 +-10 +11 +-11 +10 +-10 +9 +-11 +10 +-11 +10 +-10 +11 +-9 +10 +-11 +11 +-10 +11 +-12 +10 +-10 +9 +-11 +10 +-10 +11 +-10 +11 +-9 +9 +-10 +12 +-11 +12 +-11 +11 +-9 +10 +-9 +10 +-10 +10 +-10 +10 +-10 +9 +-9 +10 +-11 +12 +-10 +10 +-9 +11 +-10 +12 +-10 +10 +-9 +12 +-11 +10 +-10 +10 +-9 +11 +-10 +10 +-9 +11 +-9 +11 +-11 +12 +-12 +11 +-11 +10 +-9 +9 +-11 +11 +-10 +10 +-12 +12 +-10 +9 +-11 +11 +-9 +11 +-8 +11 +-10 +12 +-10 +12 +-10 +10 +-10 +10 +-11 +11 +-9 +10 +-11 +11 +-10 +10 +-10 +9 +-11 +9 +-11 +12 +-9 +9 +-10 +12 +-10 +10 +-10 +10 +-9 +10 +-9 +11 +-9 +12 +-10 +11 +-10 +10 +-10 +11 +-8 +10 +-10 +12 +-11 +10 +-9 +10 +-10 +11 +-10 +9 +-10 +12 +-11 +11 +-10 +10 +-9 +11 +-11 +10 +-10 +12 +-10 +10 +-10 +9 +-10 +10 +-10 +10 +-11 +10 +-11 +9 +-9 +9 +-11 +15 +9 +-15 +11 +-10 +10 +-9 +11 +-10 +10 +-9 +9 +-9 +9 +-11 +11 +-10 +10 +-9 +10 +-10 +11 +-9 +9 +-9 +9 +-8 +7 +-10 +9 +-9 +8 +-11 +10 +-10 +9 +-9 +9 +-9 +8 +-11 +10 +-10 +10 +-9 +10 +-10 +10 +-9 +11 +-11 +10 +-8 +10 +-9 +10 +-10 +11 +-10 +9 +-9 +10 +-10 +9 +-9 +9 +-10 +10 +-9 +9 +-9 +10 +-9 +10 +-10 +10 +-9 +9 +-10 +9 +-9 +8 +-11 +9 +-9 +8 +-10 +10 +-10 +9 +-9 +8 +-9 +9 +-9 +10 +-13 +-5 +14 +-8 +12 +-8 +10 +-8 +10 +-9 +10 +-8 +9 +-9 +10 +-10 +10 +-9 +11 +-8 +10 +-9 +11 +-8 +11 +-9 +10 +-9 +11 +-9 +10 +-9 +10 +-9 +10 +-9 +10 +-9 +9 +-10 +11 +-10 +11 +-10 +10 +-10 +11 +-11 +10 +-11 +9 +-11 +8 +-11 +10 +-11 +10 +-9 +9 +-11 +8 +-11 +10 +-10 +9 +-10 +11 +-10 +10 +-9 +10 +-9 +11 +-10 +11 +-9 +13 +-11 +12 +-10 +10 +-8 +10 +-10 +11 +-9 +11 +-11 +11 +-9 +10 +-10 +10 +-11 +13 +-11 +13 +10 +-15 +12 +-13 +10 +-10 +9 +-10 +10 +-9 +10 +-10 +10 +-10 +10 +-8 +10 +-9 +10 +-10 +10 +-10 +11 +-10 +9 +-9 +10 +-11 +10 +-11 +10 +-10 +9 +-8 +9 +-10 +10 +-10 +11 +-9 +9 +-10 +10 +-9 +11 +-8 +10 +-9 +10 +-9 +10 +-8 +9 +-9 +9 +-9 +10 +-10 +11 +-9 +10 +-9 +9 +-12 +-8 +13 +-9 +10 +-10 +9 +-10 +10 +-10 +10 +-12 +10 +-10 +10 +-10 +10 +-11 +9 +-10 +10 +-10 +9 +-10 +9 +-11 +10 +-8 +7 +-11 +9 +-10 +10 +-11 +11 +-10 +10 +-10 +10 +-11 +10 +-9 +11 +-10 +11 +-10 +12 +-9 +11 +-9 +10 +-11 +12 +-8 +12 +-9 +10 +-10 +10 +-9 +11 +-9 +11 +-10 +11 +-9 +10 +-10 +10 +-11 +12 +-9 +11 +-11 +11 +-9 +10 +-10 +11 +-10 +10 +-9 +11 +-10 +12 +-10 +10 +-9 +10 +-9 +10 +-11 +11 +-11 +11 +-11 +10 +-11 +11 +-10 +11 +-12 +11 +-10 +11 +-10 +12 +-10 +12 +-11 +12 +-10 +11 +-10 +10 +-9 +10 +-11 +9 +-10 +11 +-10 +9 +-11 +11 +-11 +9 +-10 +12 +9 +-16 +10 +-12 +10 +-11 +9 +-10 +12 +-11 +9 +-10 +9 +-10 +10 +-10 +9 +-10 +10 +-10 +10 +-9 +11 +-10 +11 +-8 +9 +-10 +10 +-9 +10 +-13 +-8 +14 +-8 +9 +-9 +12 +-9 +10 +-9 +11 +-9 +11 +-8 +11 +-10 +10 +-8 +11 +-10 +10 +-9 +11 +-9 +10 +-10 +12 +-11 +11 +-9 +11 +-10 +11 +-11 +12 +-10 +10 +-9 +12 +-10 +12 +-11 +10 +-10 +9 +-8 +11 +-10 +10 +-9 +11 +-8 +9 +-10 +12 +-12 +11 +-9 +9 +-10 +10 +-10 +10 +-12 +11 +-9 +11 +-11 +11 +-10 +10 +-10 +9 +-12 +10 +-10 +10 +-9 +9 +-10 +10 +-10 +11 +-10 +10 +-11 +12 +-10 +11 +-9 +9 +-12 +13 +-10 +10 +-11 +15 +10 +-16 +11 +-11 +10 +-10 +8 +-11 +10 +-10 +9 +-10 +10 +-11 +9 +-9 +9 +-11 +9 +-9 +11 +-10 +11 +-11 +11 +-11 +10 +-10 +9 +-9 +9 +-10 +10 +-9 +10 +-9 +12 +-10 +12 +-10 +9 +-10 +10 +-8 +9 +-9 +10 +-10 +10 +-10 +10 +-10 +9 +-8 +11 +-10 +8 +-9 +10 +-10 +9 +-10 +10 +-13 +-9 +13 +-9 +9 +-10 +9 +-10 +10 +-9 +11 +-10 +11 +-11 +10 +-11 +10 +-9 +11 +-8 +12 +-10 +10 +-8 +10 +-8 +11 +-9 +9 +-10 +12 +-10 +12 +-10 +10 +-9 +10 +-9 +10 +-9 +10 +-10 +12 +-9 +11 +-10 +11 +-10 +10 +-10 +11 +-11 +10 +-10 +10 +-10 +11 +-10 +11 +-10 +10 +-10 +11 +-9 +10 +-10 +11 +-10 +11 +-9 +10 +-10 +10 +-9 +10 +-11 +11 +-10 +10 +-9 +10 +-10 +11 +-11 +11 +-9 +10 +-10 +12 +-10 +12 +-9 +8 +-10 +10 +-10 +10 +-11 +10 +-10 +11 +-10 +10 +-12 +11 +-10 +9 +-10 +14 +-10 +11 +-10 +11 +-10 +11 +-9 +9 +-11 +11 +-11 +9 +-11 +10 +-10 +10 +-10 +9 +-11 +10 +-10 +9 +-11 +11 +-11 +9 +-11 +9 +-11 +10 +-11 +11 +-10 +11 +-10 +10 +-10 +11 +-10 +11 +-12 +12 +-10 +11 +-10 +10 +-9 +12 +-10 +13 +-7 +9 +-9 +10 +-10 +10 +-10 +10 +-11 +12 +-10 +12 +-10 +11 +-9 +11 +-11 +12 +-11 +10 +-10 +10 +-9 +10 +-10 +11 +-9 +7 +-10 +10 +-11 +9 +-11 +13 +9 +-16 +10 +-13 +10 +-10 +8 +-9 +9 +-11 +13 +-11 +10 +-11 +10 +-11 +9 +-11 +9 +-9 +9 +-11 +10 +-10 +9 +-9 +10 +-10 +10 +-10 +10 +-11 +11 +-8 +9 +-9 +10 +-10 +11 +-10 +11 +-9 +10 +-8 +9 +-9 +10 +-9 +9 +-9 +11 +-10 +12 +-9 +11 +-8 +10 +-9 +11 +-10 +10 +-10 +10 +-13 +-7 +13 +-8 +10 +-10 +11 +-9 +13 +-8 +12 +-9 +11 +-9 +10 +-8 +11 +-8 +11 +-10 +12 +-10 +11 +-11 +10 +-10 +10 +-10 +10 +-9 +9 +-10 +10 +-11 +10 +-10 +10 +-10 +10 +-11 +10 +-8 +9 +-10 +11 +-11 +10 +-9 +11 +-9 +9 +-9 +10 +-10 +10 +-10 +11 +-10 +10 +-10 +12 +-9 +11 +-12 +11 +-9 +12 +-9 +10 +-10 +12 +-8 +12 +-9 +12 +-10 +11 +-9 +10 +-10 +11 +-11 +10 +-10 +10 +-11 +11 +-10 +9 +-11 +10 +-10 +11 +-11 +12 +-11 +10 +-9 +12 +-8 +9 +-10 +11 +-9 +10 +-10 +11 +-11 +10 +-9 +9 +-10 +10 +-9 +8 +-10 +10 +-9 +11 +-11 +11 +-9 +10 +-10 +10 +-11 +10 +-9 +10 +-10 +11 +-10 +11 +-9 +10 +-10 +10 +-11 +10 +-10 +10 +-11 +10 +-11 +10 +-10 +11 +-11 +11 +-10 +9 +-10 +11 +-11 +11 +-10 +11 +-10 +10 +-10 +14 +10 +-15 +10 +-10 +9 +-11 +9 +-12 +9 +-9 +10 +-10 +9 +-10 +9 +-10 +9 +-10 +10 +-12 +9 +-10 +9 +-10 +10 +-10 +10 +-9 +10 +-10 +8 +-10 +10 +-8 +11 +-10 +10 +-9 +9 +-9 +10 +-8 +10 +-9 +10 +-9 +10 +-10 +10 +-9 +10 +-9 +9 +-10 +12 +-9 +8 +-9 +9 +-10 +10 +-8 +10 +-12 +-7 +14 +-7 +11 +-9 +12 +-9 +11 +-9 +12 +-9 +11 +-9 +10 +-9 +10 +-10 +12 +-8 +10 +-9 +13 +-9 +12 +-9 +12 +-8 +11 +-10 +10 +-10 +13 +10 +-16 +11 +-10 +10 +-12 +9 +-9 +8 +-10 +9 +-10 +10 +-10 +10 +-10 +10 +-9 +11 +-9 +9 +-10 +10 +-10 +9 +-9 +8 +-10 +10 +-10 +10 +-13 +-8 +14 +-8 +10 +-11 +9 +-9 +9 +-10 +10 +-10 +11 +-9 +13 +-9 +11 +-9 +11 +-10 +12 +-9 +12 +-9 +11 +-9 +10 +-9 +10 +-9 +11 +-10 +12 +-10 +10 +-9 +11 +-10 +10 +-10 +12 +-9 +11 +-11 +9 +-9 +11 +-12 +12 +-11 +11 +-9 +10 +-12 +10 +-11 +10 +-10 +10 +-11 +10 +-10 +10 +-11 +11 +-10 +9 +-10 +10 +-10 +9 +-10 +10 +-9 +8 +-11 +11 +-9 +9 +-10 +11 +-10 +10 +-11 +11 +-10 +10 +-11 +10 +-10 +11 +-10 +8 +-11 +11 +-8 +9 +-8 +10 +-9 +12 +-11 +10 +-9 +11 +-10 +12 +-10 +11 +-9 +12 +-10 +11 +-9 +11 +-9 +11 +-10 +12 +-8 +10 +-11 +10 +-11 +11 +-11 +10 +-11 +11 +-10 +9 +-10 +9 +-11 +11 +-9 +10 +-12 +10 +-10 +9 +-11 +10 +-11 +11 +-13 +11 +-12 +12 +-12 +10 +-10 +10 +-10 +11 +-9 +10 +-9 +12 +-9 +12 +-8 +10 +-9 +12 +-10 +11 +-9 +12 +-9 +10 +-9 +10 +-10 +11 +-10 +9 +-9 +11 +-10 +9 +-9 +10 +-10 +10 +-9 +11 +-10 +9 +-11 +12 +-10 +9 +-12 +12 +-9 +10 +-9 +11 +-10 +10 +-9 +11 +-9 +11 +-10 +11 +-10 +12 +-9 +10 +-10 +11 +-9 +12 +-10 +10 +-10 +10 +-11 +11 +-10 +10 +-11 +10 +-11 +12 +-8 +11 +-9 +10 +-10 +10 +-11 +10 +-10 +10 +-10 +11 +-10 +12 +-10 +12 +-10 +12 +-11 +12 +-10 +10 +-11 +12 +-10 +10 +-9 +10 +-10 +11 +-10 +10 +-10 +9 +-8 +9 +-12 +11 +-11 +9 +-11 +10 +-9 +9 +-10 +9 +-11 +10 +-10 +11 +-10 +10 +-10 +10 +-10 +11 +-10 +12 +-9 +10 +-9 +11 +-9 +10 +-12 +11 +-9 +10 +-10 +10 +-11 +11 +-10 +13 +-10 +11 +-9 +12 +-9 +10 +-10 +11 +-10 +11 +-10 +10 +-9 +10 +-11 +9 +-11 +11 +-10 +10 +-10 +10 +-12 +9 +-11 +10 +-10 +9 +-11 +10 +-10 +11 +-10 +12 +-9 +11 +-10 +10 +-10 +10 +-8 +12 +-10 +11 +-9 +13 +-8 +9 +-8 +9 +-10 +11 +-10 +10 +-11 +9 +-10 +11 +-10 +8 +-11 +10 +-11 +9 +-10 +9 +-10 +11 +-10 +11 +-9 +12 +-11 +10 +-9 +11 +-10 +12 +-9 +9 +-10 +10 +-9 +10 +-10 +10 +-10 +10 +-11 +12 +-9 +10 +-9 +10 +-9 +10 +-9 +11 +-9 +10 +-9 +12 +-9 +12 +-10 +10 +-10 +9 +-11 +13 +-10 +11 +-9 +10 +-9 +10 +-9 +11 +-10 +11 +-10 +10 +-10 +11 +-10 +10 +-10 +10 +-10 +10 +-9 +11 +-10 +11 +-10 +11 +-10 +11 +-10 +12 +-9 +10 +-10 +11 +-10 +12 +-11 +11 +-8 +8 +-11 +11 +-9 +11 +-10 +10 +-10 +11 +-11 +9 +-10 +11 +-8 +10 +-10 +11 +-11 +12 +-10 +11 +-9 +10 +-11 +10 +-11 +11 +-9 +9 +-10 +10 +-11 +9 +-10 +10 +-11 +10 +-12 +11 +-9 +11 +-10 +11 +-10 +11 +-9 +11 +-9 +11 +-9 +12 +-10 +12 +-9 +11 +-11 +10 +-9 +12 +-10 +10 +-10 +10 +-10 +10 +-10 +10 +-11 +10 +-10 +9 +-10 +10 +-11 +9 +-12 +11 +-11 +10 +-12 +10 +-11 +8 +-12 +11 +-10 +9 +-11 +8 +-11 +9 +-10 +10 +-8 +11 +-10 +11 +-10 +12 +-8 +11 +-9 +11 +-8 +12 +-9 +10 +-9 +10 +-9 +11 +-12 +11 +-10 +10 +-11 +9 +-11 +10 +-9 +10 +-10 +10 +-10 +8 +-10 +11 +-11 +11 +-9 +10 +-10 +11 +-10 +12 +-10 +10 +-10 +11 +-10 +10 +-10 +12 +-11 +11 +-9 +9 +-11 +10 +-10 +11 +-10 +10 +-9 +10 +-12 +12 +-10 +11 +-10 +10 +-10 +12 +-10 +11 +-9 +10 +-9 +9 +-11 +11 +-9 +9 +-11 +12 +-10 +9 +-10 +10 +-10 +8 +-9 +11 +-10 +11 +-11 +11 +-11 +10 +-11 +11 +-10 +10 +-10 +12 +-11 +11 +-10 +9 +-8 +11 +-10 +9 +-10 +11 +-9 +12 +-12 +10 +-11 +10 +-11 +11 +-9 +8 +-10 +12 +-9 +13 +-12 +9 +-9 +9 +-11 +10 +-9 +9 +-11 +11 +-11 +12 +-10 +12 +-9 +12 +-10 +10 +-9 +11 +-11 +11 +-11 +11 +-10 +10 +-10 +10 +-9 +10 +-11 +10 +-11 +11 +-9 +11 +-8 +8 +-9 +12 +-10 +10 +-11 +11 +-11 +12 +-10 +9 +-10 +10 +-9 +10 +-11 +10 +-10 +11 +-10 +9 +-10 +11 +-11 +9 +-10 +9 +-9 +12 +-10 +12 +-11 +10 +-10 +10 +-10 +11 +-10 +11 +-10 +11 +-8 +10 +-9 +11 +-10 +12 +-9 +11 +-8 +12 +-9 +10 +-8 +13 +-10 +9 +-11 +12 +-10 +11 +-10 +10 +-10 +10 +-10 +10 +-9 +10 +-10 +10 +-11 +10 +-10 +9 +-12 +10 +-11 +10 +-10 +9 +-11 +10 +-12 +10 +-12 +9 +-10 +9 +-11 +10 +-11 +11 +-12 +11 +-11 +11 +-11 +8 +-10 +10 +-10 +12 +-10 +12 +-11 +12 +-8 +12 +-9 +10 +-9 +12 +-10 +10 +-11 +12 +-10 +11 +-10 +11 +-9 +10 +-9 +10 +-10 +10 +-10 +10 +-9 +10 +-9 +10 +-11 +11 +-10 +9 +-10 +9 +-11 +10 +-11 +11 +-10 +11 +-11 +11 +-11 +10 +-11 +10 +-10 +9 +-9 +10 +-10 +11 +-10 +10 +-11 +10 +-9 +8 +-10 +12 +-11 +11 +-10 +11 +-11 +10 +-11 +11 +-10 +11 +-11 +12 +-8 +11 +-10 +11 +-10 +11 +-9 +12 +-11 +11 +-10 +9 +-11 +11 +-10 +10 +-11 +9 +-10 +11 +-9 +10 +-9 +11 +-8 +12 +-10 +11 +-11 +11 +-9 +11 +-10 +11 +-10 +11 +-9 +10 +-10 +11 +-9 +11 +-9 +11 +-11 +12 +10 +-16 +10 +-11 +9 +-9 +9 +-10 +10 +-9 +10 +-12 +10 +-11 +8 +-10 +9 +-9 +10 +-11 +10 +-12 +11 +-9 +9 +-9 +10 +-10 +10 +-9 +9 +-10 +8 +-9 +11 +-9 +10 +-9 +9 +-8 +11 +-10 +11 +-9 +9 +-9 +8 +-10 +9 +-10 +12 +-10 +8 +-9 +11 +-9 +10 +-8 +10 +-9 +11 +-9 +10 +-9 +10 +-9 +10 +-9 +10 +-10 +12 +-8 +10 +-9 +11 +-10 +10 +-10 +9 +-10 +10 +-10 +9 +-10 +10 +-9 +9 +-9 +8 +-9 +10 +-10 +9 +-9 +9 +-12 +-9 +14 +-8 +10 +-8 +9 +-9 +10 +-9 +10 +-9 +10 +-8 +8 +-10 +11 +-9 +9 +-10 +11 +-9 +10 +-9 +9 +-8 +10 +-10 +10 +-10 +10 +-9 +11 +-9 +11 +-8 +10 +-10 +10 +-11 +11 +-10 +12 +-10 +10 +-10 +11 +-11 +9 +-10 +10 +-11 +11 +-11 +9 +-11 +11 +-10 +10 +-10 +10 +-10 +11 +-11 +10 +-10 +11 +-10 +11 +-10 +10 +-10 +10 +-10 +12 +-9 +11 +-9 +11 +-10 +10 +-9 +10 +-10 +13 +-9 +11 +-10 +12 +-9 +12 +-10 +12 +-9 +10 +-9 +14 +9 +-15 +9 +-11 +9 +-10 +9 +-11 +10 +-11 +9 +-11 +8 +-11 +9 +-11 +10 +-12 +8 +-11 +9 +-11 +8 +-11 +10 +-10 +10 +-11 +9 +-10 +9 +-10 +9 +-10 +9 +-9 +10 +-10 +10 +-8 +12 +-10 +9 +-9 +9 +-9 +10 +-11 +11 +-9 +9 +-9 +8 +-10 +12 +-10 +9 +-9 +9 +-7 +8 +-9 +10 +-12 +-8 +13 +-8 +10 +-10 +11 +-10 +12 +-9 +10 +-10 +10 +-9 +10 +-9 +10 +-10 +10 +-10 +10 +-9 +10 +-9 +11 +-10 +9 +-10 +10 +-9 +10 +-9 +10 +-9 +12 +-8 +11 +-8 +12 +-9 +12 +-9 +12 +-8 +11 +-9 +11 +-10 +12 +-10 +12 +-9 +9 +-10 +11 +-10 +9 +-9 +11 +-11 +12 +-10 +11 +-11 +9 +-11 +10 +-10 +9 +-9 +10 +-11 +10 +-11 +10 +-10 +10 +-10 +12 +-11 +11 +-10 +10 +-10 +10 +-10 +11 +-8 +9 +-10 +11 +-10 +10 +-9 +11 +-12 +11 +-11 +12 +-10 +9 +-11 +10 +-11 +9 +-10 +10 +-10 +11 +-11 +9 +-11 +9 +-11 +10 +-11 +9 +-11 +8 +-10 +11 +-11 +11 +-11 +11 +-9 +10 +-10 +15 +10 +-15 +11 +-10 +9 +-10 +10 +-10 +10 +-10 +10 +-10 +10 +-10 +10 +-10 +9 +-10 +10 +-10 +10 +-11 +10 +-10 +10 +-9 +9 +-10 +11 +-10 +9 +-14 +-9 +13 +-8 +11 +-8 +11 +-8 +9 +-9 +12 +-8 +10 +-8 +11 +-9 +11 +-8 +10 +-9 +12 +-8 +10 +-9 +11 +-10 +10 +-9 +11 +-9 +9 +-10 +13 +-11 +8 +-10 +10 +-10 +11 +-10 +11 +-10 +11 +-10 +10 +-10 +12 +-10 +10 +-10 +10 +-10 +10 +-10 +9 +-11 +12 +-10 +9 +-10 +11 +-11 +11 +-11 +11 +-9 +9 +-10 +11 +-11 +10 +-10 +10 +-10 +10 +-10 +10 +-10 +9 +-10 +11 +-11 +11 +-9 +11 +-10 +12 +-10 +12 +-10 +10 +-11 +10 +-9 +10 +-11 +14 +10 +-16 +12 +-12 +8 +-11 +9 +-11 +10 +-12 +9 +-12 +10 +-11 +9 +-9 +10 +-10 +10 +-9 +9 +-9 +9 +-12 +10 +-9 +9 +-9 +10 +-12 +11 +-10 +10 +-10 +10 +-10 +9 +-10 +9 +-9 +9 +-10 +11 +-9 +10 +-9 +10 +-10 +9 +-9 +11 +-10 +11 +-10 +10 +-10 +11 +-9 +10 +-8 +10 +-9 +12 +-13 +-8 +14 +-8 +11 +-9 +10 +-9 +11 +-9 +10 +-10 +11 +-9 +12 +-9 +11 +-8 +11 +-9 +10 +-9 +10 +-10 +9 +-10 +10 +-10 +9 +-10 +11 +-10 +9 +-9 +9 +-8 +11 +-9 +10 +-10 +13 +-8 +10 +-9 +10 +-11 +10 +-9 +11 +-8 +10 +-10 +10 +-9 +10 +-12 +10 +-11 +11 +-10 +9 +-11 +11 +-11 +10 +-10 +11 +-11 +10 +-9 +11 +-9 +10 +-11 +10 +-11 +11 +-12 +9 +-11 +9 +-9 +11 +-11 +11 +-10 +11 +-10 +10 +-11 +10 +-8 +12 +-10 +11 +-7 +10 +-9 +11 +-10 +11 +-8 +10 +-9 +11 +-9 +12 +-9 +11 +-10 +10 +-10 +11 +-8 +11 +-10 +11 +-11 +10 +-10 +9 +-10 +10 +-9 +10 +-10 +10 +-12 +12 +-10 +10 +-11 +10 +-9 +10 +-10 +11 +-9 +10 +-11 +9 +-9 +11 +-9 +11 +-11 +10 +-8 +10 +-11 +10 +-11 +10 +-11 +10 +-10 +9 +-10 +10 +-11 +10 +-11 +10 +-10 +11 +-10 +10 +-10 +10 +-10 +11 +-11 +10 +-10 +10 +-10 +9 +-10 +11 +-9 +11 +-8 +11 +-10 +11 +-10 +12 +-9 +11 +-10 +9 +-10 +14 +10 +-16 +9 +-11 +9 +-11 +8 +-9 +10 +-11 +9 +-11 +10 +-10 +9 +-10 +8 +-9 +9 +-11 +10 +-10 +10 +-9 +9 +-11 +10 +-9 +10 +-9 +11 +-9 +10 +-9 +9 +-10 +9 +-9 +9 +-11 +10 +-10 +10 +-9 +10 +-9 +11 +-8 +8 +-10 +10 +-9 +9 +-10 +10 +-11 +10 +-10 +8 +-10 +11 +-11 +10 +-13 +-8 +14 +-8 +12 +-9 +11 +-10 +10 +-9 +12 +-7 +8 +-9 +12 +-9 +11 +-8 +12 +-8 +12 +-9 +10 +-9 +11 +-8 +10 +-10 +10 +-9 +10 +-9 +10 +-9 +11 +-9 +10 +-10 +10 +-10 +12 +-8 +11 +-10 +11 +-9 +11 +-10 +11 +-9 +11 +-9 +11 +-9 +11 +-9 +11 +-10 +11 +-9 +11 +-10 +11 +-10 +10 +-10 +9 +-9 +10 +-10 +11 +-10 +12 +-10 +11 +-10 +10 +-10 +10 +-11 +10 +-10 +11 +-10 +10 +-9 +9 +-10 +11 +-12 +10 +-10 +10 +-11 +10 +-11 +10 +-11 +12 +-10 +10 +-10 +10 +-11 +11 +-9 +9 +-12 +9 +-10 +11 +-10 +10 +-11 +12 +-9 +9 +-11 +10 +-11 +11 +-9 +10 +-9 +10 +-10 +11 +-11 +9 +-9 +9 +-10 +10 +-9 +9 +-10 +10 +-9 +9 +-11 +11 +-10 +12 +-11 +9 +-10 +11 +-10 +11 +-10 +12 +-12 +8 +-11 +11 +-10 +9 +-9 +10 +-9 +13 +8 +-15 +11 +-11 +9 +-10 +9 +-11 +11 +-10 +10 +-10 +10 +-11 +11 +-11 +9 +-12 +9 +-9 +9 +-10 +9 +-10 +10 +-10 +10 +-9 +9 +-9 +9 +-10 +10 +-9 +10 +-10 +10 +-10 +9 +-9 +9 +-10 +10 +-10 +10 +-9 +8 +-9 +10 +-9 +10 +-9 +10 +-10 +9 +-8 +9 +-9 +11 +-10 +10 +-9 +10 +-13 +-7 +13 +-8 +11 +-8 +9 +-8 +11 +-10 +9 +-10 +10 +-10 +10 +-10 +10 +-9 +11 +-9 +10 +-9 +11 +-10 +10 +-9 +11 +-9 +11 +-10 +11 +-10 +14 +10 +-13 +10 +-10 +10 +-10 +10 +-10 +10 +-10 +9 +-10 +10 +-10 +10 +-10 +9 +-10 +9 +-9 +9 +-9 +9 +-9 +9 +-12 +10 +-11 +10 +-8 +9 +-12 +-8 +15 +-8 +11 +-8 +10 +-9 +10 +-9 +10 +-9 +9 +-8 +10 +-9 +12 +-9 +12 +-10 +11 +-9 +10 +-8 +10 +-8 +10 +-9 +10 +-10 +10 +-10 +11 +-10 +11 +-9 +10 +-9 +10 +-10 +9 +-10 +9 +-10 +9 +-11 +9 +-11 +9 +-10 +10 +-10 +10 +-10 +12 +-9 +11 +-10 +11 +-10 +11 +-8 +11 +-10 +11 +-9 +12 +-10 +10 +-10 +10 +-10 +11 +-11 +12 +-10 +10 +-10 +10 +-10 +10 +-10 +9 +-10 +11 +-10 +12 +-10 +13 +-10 +11 +-10 +10 +-9 +11 +-9 +12 +-11 +12 +-12 +11 +-11 +10 +-9 +10 +-9 +11 +-9 +11 +-11 +10 +-9 +12 +-11 +9 +-9 +10 +-9 +10 +-11 +12 +-9 +10 +-10 +11 +-11 +12 +-11 +11 +-11 +11 +-10 +8 +-8 +11 +-10 +10 +-10 +11 +-9 +8 +-10 +11 +-11 +11 +-11 +11 +-12 +9 +-9 +11 +-10 +10 +-9 +10 +-9 +12 +-9 +11 +-9 +11 +-10 +10 +-9 +9 +-12 +11 +-10 +9 +-9 +9 +-10 +10 +-11 +10 +-10 +9 +-11 +10 +-10 +10 +-11 +10 +-10 +11 +-8 +11 +-10 +11 +-9 +11 +-11 +9 +-10 +9 +-11 +10 +-9 +10 +-10 +11 +-11 +11 +-9 +9 +-10 +11 +-9 +12 +-10 +11 +-8 +11 +-10 +13 +-8 +12 +-10 +12 +-9 +12 +-9 +12 +-8 +13 +-10 +11 +-10 +10 +-10 +10 +-10 +11 +-10 +11 +-10 +10 +-10 +11 +-10 +11 +-10 +10 +-10 +12 +-11 +10 +-9 +9 +-10 +10 +-11 +11 +-10 +9 +-11 +10 +-10 +9 +-10 +9 +-11 +9 +-10 +10 +-10 +11 +-8 +10 +-11 +11 +-10 +11 +-10 +12 +-10 +10 +-11 +11 +-11 +10 +-11 +10 +-9 +10 +-10 +10 +-9 +11 +-9 +12 +-10 +10 +-11 +10 +-11 +11 +-10 +11 +-9 +11 +-10 +11 +-11 +12 +-9 +10 +-10 +12 +-10 +10 +-11 +10 +-10 +10 +-9 +12 +-11 +12 +-9 +12 +-10 +11 +-11 +9 +-9 +10 +-11 +12 +-9 +10 +-10 +10 +-11 +10 +-9 +10 +-10 +9 +-10 +10 +-10 +11 +-11 +10 +-11 +12 +-12 +9 +-9 +10 +-10 +11 +-10 +12 +-10 +10 +-10 +11 +-10 +10 +-10 +9 +-9 +10 +-11 +11 +-11 +12 +-11 +11 +-11 +10 +-10 +10 +-10 +9 +-11 +9 +-10 +10 +-10 +10 +-11 +9 +-9 +10 +-9 +11 +-8 +10 +-9 +10 +-8 +10 +-9 +12 +-8 +10 +-10 +12 +-8 +10 +-8 +11 +-10 +10 +-9 +10 +-10 +11 +-10 +11 +-10 +10 +-10 +9 +-10 +11 +-11 +9 +-11 +11 +-10 +10 +-11 +11 +-9 +10 +-11 +11 +-9 +10 +-12 +11 +-10 +11 +-10 +9 +-11 +10 +-9 +11 +-11 +12 +-10 +11 +-9 +10 +-11 +11 +-11 +9 +-10 +9 +-12 +11 +-11 +10 +-10 +11 +-11 +11 +-9 +12 +-8 +11 +-9 +11 +-9 +10 +-11 +9 +-11 +11 +-10 +11 +-9 +10 +-12 +11 +-10 +12 +-10 +10 +-10 +10 +-10 +10 +-11 +11 +-11 +10 +-10 +11 +-10 +10 +-10 +11 +-9 +12 +-9 +10 +-10 +11 +-11 +11 +-10 +9 +-10 +10 +-10 +10 +-11 +10 +-10 +10 +-8 +10 +-11 +10 +-11 +10 +-11 +10 +-11 +11 +-11 +10 +-10 +10 +-8 +11 +-10 +11 +-10 +11 +-11 +11 +-9 +9 +-9 +10 +-10 +10 +-11 +11 +-10 +10 +-10 +10 +-12 +11 +-10 +11 +-10 +10 +-11 +10 +-10 +10 +-10 +10 +-10 +12 +-10 +11 +-9 +9 +-9 +11 +-11 +10 +-10 +10 +-10 +10 +-10 +11 +-12 +9 +-10 +10 +-10 +11 +-11 +10 +-10 +12 +-10 +10 +-9 +10 +-9 +11 +-9 +12 +-10 +9 +-10 +12 +-10 +11 +-11 +11 +-11 +11 +-10 +11 +-10 +10 +-8 +8 +-10 +11 +-10 +13 +-11 +10 +-10 +10 +-9 +10 +-10 +10 +-9 +11 +-9 +10 +-10 +11 +-10 +12 +-10 +11 +-10 +10 +-11 +10 +-10 +9 +-10 +11 +-10 +10 +-10 +11 +-10 +11 +-9 +9 +-11 +11 +-11 +11 +-10 +8 +-11 +11 +-11 +10 +-10 +10 +-11 +11 +-9 +11 +-9 +8 +-10 +10 +-9 +11 +-9 +12 +-8 +10 +-9 +11 +-10 +10 +-9 +10 +-10 +10 +-11 +12 +-10 +12 +-10 +12 +-10 +9 +-10 +11 +-11 +10 +-10 +10 +-11 +10 +-11 +10 +-9 +10 +-10 +11 +-10 +11 +-9 +10 +-10 +10 +-10 +10 +-11 +10 +-10 +10 +-10 +11 +-10 +9 +-10 +10 +-9 +11 +-10 +10 +-10 +11 +-10 +11 +-10 +11 +-10 +11 +-8 +11 +-9 +11 +-10 +10 +-11 +9 +-9 +10 +-11 +10 +-11 +11 +-9 +11 +-9 +11 +-10 +11 +-10 +11 +-9 +11 +-10 +12 +-9 +9 +-10 +11 +-11 +10 +-10 +10 +-11 +11 +-10 +11 +-11 +10 +-9 +11 +-11 +13 +-11 +12 +-9 +10 +-11 +11 +-11 +11 +-10 +10 +-11 +9 +-10 +10 +-12 +10 +-11 +10 +-11 +10 +-11 +11 +-10 +9 +-10 +11 +-10 +11 +-11 +10 +-11 +13 +-9 +10 +-11 +10 +-9 +9 +-10 +11 +-9 +10 +-10 +11 +-10 +10 +-10 +9 +-11 +10 +-12 +10 +-10 +10 +-10 +10 +-11 +10 +-10 +12 +-12 +11 +-12 +12 +-10 +9 +-9 +12 +-8 +10 +-9 +12 +-8 +12 +-8 +11 +-9 +12 +-9 +12 +-10 +12 +-10 +11 +-10 +11 +-10 +10 +-11 +12 +-10 +10 +-10 +10 +-11 +10 +-11 +10 +-10 +11 +-10 +10 +-11 +10 +-9 +10 +-10 +11 +-11 +11 +-9 +10 +-10 +11 +-10 +9 +-11 +10 +-11 +9 +-11 +10 +-10 +9 +-10 +11 +-10 +10 +-10 +12 +-11 +10 +-11 +10 +-10 +10 +-10 +11 +-11 +11 +-10 +10 +-9 +11 +-10 +10 +-9 +15 +10 +-15 +10 +-10 +9 +-9 +11 +-12 +10 +-10 +8 +-11 +10 +-9 +9 +-10 +9 +-11 +9 +-10 +10 +-10 +9 +-10 +10 +-9 +9 +-10 +10 +-9 +10 +-10 +11 +-9 +9 +-10 +11 +-10 +10 +-8 +9 +-9 +10 +-10 +9 +-9 +9 +-10 +10 +-9 +8 +-10 +9 +-10 +9 +-9 +9 +-10 +9 +-10 +10 +-10 +9 +-8 +10 +-9 +9 +-9 +11 +-9 +10 +-9 +9 +-10 +11 +-10 +10 +-8 +9 +-9 +10 +-9 +9 +-10 +8 +-10 +8 +-10 +10 +-11 +9 +-9 +9 +-9 +11 +-12 +-10 +13 +-8 +12 +-9 +10 +-8 +11 +-9 +10 +-10 +13 +-9 +11 +-11 +10 +-9 +10 +-10 +9 +-9 +12 +-9 +12 +-10 +9 +-11 +10 +-9 +11 +-9 +10 +-10 +10 +-10 +9 +-11 +10 +-9 +8 +-11 +10 +-11 +11 +-10 +11 +-9 +10 +-9 +12 +-8 +12 +-10 +11 +-9 +12 +-11 +12 +-8 +9 +-10 +11 +-10 +10 +-11 +11 +-10 +10 +-10 +11 +-10 +12 +-10 +10 +-10 +9 +-9 +10 +-10 +10 +-10 +10 +-11 +9 +-10 +9 +-10 +10 +-11 +10 +-10 +10 +-10 +11 +-9 +15 +10 +-13 +11 +-10 +11 +-10 +12 +-9 +10 +-10 +11 +-11 +11 +-11 +11 +-10 +9 +-10 +10 +-10 +9 +-10 +10 +-11 +10 +-9 +9 +-11 +9 +-10 +9 +-10 +9 +-12 +11 +-11 +7 +-10 +9 +-10 +8 +-9 +10 +-7 +9 +-8 +9 +-8 +10 +-8 +11 +-9 +11 +-9 +10 +-9 +9 +-8 +10 +-9 +11 +-9 +10 +-13 +-8 +14 +-9 +11 +-9 +9 +-8 +10 +-9 +11 +-10 +10 +-8 +10 +-9 +9 +-10 +11 +-8 +11 +-8 +11 +-10 +11 +-10 +11 +-9 +10 +-10 +12 +-9 +11 +-9 +10 +-10 +13 +-9 +11 +-8 +11 +-10 +11 +-9 +12 +-11 +12 +-12 +10 +-9 +9 +-11 +11 +-9 +10 +-10 +11 +-10 +9 +-10 +10 +-9 +10 +-10 +10 +-12 +12 +-10 +10 +-11 +10 +-11 +10 +-11 +9 +-11 +10 +-10 +9 +-11 +11 +-10 +10 +-11 +10 +-10 +10 +-9 +9 +-11 +10 +-9 +10 +-8 +9 +-9 +9 +-9 +10 +-9 +10 +-11 +12 +-11 +12 +-9 +10 +-9 +10 +-9 +12 +-11 +10 +-10 +11 +-9 +9 +-11 +10 +-11 +11 +-10 +9 +-10 +12 +-11 +10 +-10 +15 +9 +-14 +11 +-11 +13 +-9 +9 +-10 +11 +-10 +10 +-12 +12 +-11 +9 +-10 +8 +-11 +11 +-11 +11 +-10 +10 +-10 +11 +-9 +9 +-8 +10 +-9 +10 +-13 +-7 +15 +-7 +11 +-10 +11 +-8 +10 +-8 +9 +-9 +11 +-10 +11 +-9 +10 +-8 +10 +-10 +10 +-11 +12 +-10 +10 +-9 +11 +-10 +11 +-10 +9 +-10 +10 +-10 +10 +-10 +9 +-9 +11 +-9 +12 +-9 +9 +-11 +11 +-10 +10 +-10 +11 +-10 +9 +-11 +12 +-8 +8 +-10 +10 +-10 +9 +-10 +9 +-10 +8 +-10 +10 +-9 +10 +-11 +12 +-10 +11 +-8 +10 +-10 +11 +-10 +11 +-8 +11 +-10 +12 +-10 +12 +-10 +11 +-10 +9 +-10 +11 +-9 +10 +-10 +10 +-10 +11 +-11 +14 +8 +-16 +10 +-11 +10 +-12 +8 +-11 +9 +-12 +9 +-10 +10 +-10 +10 +-9 +9 +-9 +9 +-11 +11 +-10 +10 +-9 +11 +-8 +8 +-9 +10 +-11 +11 +-9 +10 +-10 +9 +-11 +11 +-10 +9 +-9 +8 +-10 +10 +-9 +9 +-10 +8 +-10 +10 +-11 +11 +-12 +8 +-10 +9 +-10 +10 +-11 +9 +-9 +8 +-8 +9 +-12 +-7 +13 +-8 +13 +-9 +12 +-8 +11 +-8 +8 +-8 +11 +-9 +11 +-9 +10 +-9 +10 +-9 +8 +-11 +11 +-8 +9 +-12 +12 +-9 +10 +-10 +10 +-11 +11 +-9 +10 +-10 +11 +-9 +11 +-9 +10 +-9 +10 +-10 +12 +-10 +11 +-10 +11 +-11 +11 +-10 +9 +-11 +10 +-9 +10 +-11 +12 +-10 +10 +-11 +10 +-10 +11 +-9 +10 +-8 +10 +-8 +12 +-10 +11 +-10 +11 +-10 +9 +-9 +10 +-9 +11 +-11 +10 +-10 +12 +-9 +13 +-9 +9 +-9 +12 +-10 +12 +-10 +11 +-9 +8 +-10 +9 +-11 +9 +-10 +10 +-10 +10 +-9 +10 +-10 +10 +-11 +10 +-10 +9 +-10 +10 +-11 +10 +-9 +10 +-10 +9 +-10 +10 +-10 +10 +-11 +10 +-11 +10 +-9 +10 +-10 +12 +-13 +10 +-9 +10 +-10 +12 +-11 +10 +-11 +12 +-9 +11 +-9 +11 +-9 +12 +-9 +10 +-9 +11 +-10 +11 +-9 +9 +-9 +10 +-10 +10 +-9 +11 +-11 +10 +-10 +9 +-10 +10 +-11 +12 +-11 +10 +-10 +9 +-11 +11 +-10 +10 +-11 +10 +-11 +12 +-11 +10 +-9 +10 +-10 +10 +-10 +10 +-9 +13 +10 +-16 +10 +-11 +10 +-9 +9 +-10 +10 +-10 +10 +-9 +10 +-10 +10 +-10 +10 +-11 +11 +-10 +9 +-10 +10 +-10 +10 +-9 +9 +-10 +10 +-10 +10 +-9 +11 +-9 +9 +-9 +9 +-9 +12 +-7 +8 +-9 +10 +-9 +11 +-8 +11 +-10 +13 +-9 +10 +-8 +10 +-9 +8 +-10 +9 +-10 +9 +-11 +9 +-9 +10 +-14 +-8 +13 +-8 +11 +-10 +8 +-9 +12 +-8 +10 +-9 +9 +-6 +11 +-8 +13 +-9 +11 +-9 +10 +-11 +12 +-10 +10 +-10 +11 +-10 +12 +-9 +9 +-9 +11 +-9 +10 +-9 +9 +-10 +12 +-9 +9 +-9 +11 +-11 +12 +-9 +9 +-8 +12 +-9 +10 +-9 +12 +-10 +9 +-10 +10 +-10 +10 +-10 +12 +-10 +10 +-9 +10 +-10 +13 +-11 +10 +-10 +11 +-9 +9 +-10 +9 +-9 +9 +-11 +12 +-10 +11 +-9 +11 +-10 +10 +-11 +11 +-9 +11 +-11 +11 +-9 +10 +-9 +9 +-10 +10 +-9 +11 +-10 +12 +-10 +11 +-11 +11 +-12 +12 +-9 +12 +-10 +10 +-9 +11 +-9 +10 +-10 +11 +-10 +10 +-10 +11 +-10 +10 +-9 +11 +-9 +11 +-10 +10 +-10 +8 +-10 +10 +-11 +8 +-11 +9 +-10 +10 +-10 +10 +-10 +10 +-11 +9 +-11 +10 +-11 +11 +-11 +9 +-10 +11 +-8 +11 +-10 +10 +-10 +10 +-11 +13 +10 +-15 +10 +-12 +9 +-11 +10 +-10 +10 +-10 +10 +-12 +10 +-11 +10 +-9 +8 +-11 +10 +-10 +8 +-10 +8 +-11 +9 +-10 +9 +-10 +9 +-10 +9 +-10 +10 +-10 +10 +-9 +10 +-7 +8 +-9 +12 +-9 +9 +-9 +10 +-9 +10 +-10 +11 +-8 +10 +-9 +11 +-8 +9 +-7 +9 +-9 +12 +-9 +9 +-8 +10 +-13 +-7 +15 +-7 +12 +-9 +11 +-8 +11 +-10 +11 +-8 +9 +-9 +11 +-9 +10 +-10 +11 +-9 +11 +-9 +10 +-10 +10 +-10 +11 +-10 +10 +-10 +10 +-9 +13 +9 +-16 +10 +-11 +10 +-10 +8 +-11 +10 +-10 +8 +-10 +10 +-10 +8 +-9 +9 +-10 +8 +-11 +9 +-10 +10 +-9 +10 +-10 +10 +-9 +10 +-10 +9 +-12 +-9 +12 +-7 +11 +-8 +11 +-8 +11 +-8 +10 +-10 +11 +-10 +10 +-9 +10 +-8 +10 +-10 +11 +-9 +11 +-9 +10 +-10 +12 +-9 +10 +-8 +11 +-11 +11 +-9 +12 +-10 +8 +-10 +10 +-10 +10 +-10 +11 +-11 +11 +-10 +9 +-11 +10 +-10 +9 +-11 +13 +-10 +12 +-9 +12 +-9 +13 +-9 +11 +-9 +12 +-10 +11 +-9 +10 +-9 +11 +-9 +10 +-10 +10 +-10 +10 +-9 +8 +-10 +11 +-11 +11 +-10 +10 +-10 +9 +-10 +9 +-9 +11 +-10 +12 +-9 +9 +-10 +12 +-9 +11 +-11 +10 +-9 +12 +-11 +11 +-10 +10 +-11 +10 +-10 +11 +-10 +10 +-9 +8 +-9 +11 +-11 +11 +-10 +11 +-10 +12 +-9 +10 +-10 +10 +-10 +11 +-11 +11 +-11 +11 +-9 +11 +-10 +12 +-10 +10 +-9 +10 +-9 +11 +-9 +11 +-9 +11 +-10 +9 +-10 +9 +-10 +11 +-11 +9 +-10 +10 +-10 +11 +-9 +11 +-11 +12 +-9 +11 +-8 +10 +-10 +10 +-10 +10 +-10 +11 +-11 +12 +-10 +11 +-10 +10 +-10 +11 +-11 +12 +-10 +10 +-10 +11 +-10 +10 +-9 +10 +-12 +10 +-10 +11 +-10 +11 +-11 +10 +-11 +11 +-9 +11 +-10 +11 +-11 +11 +-10 +10 +-11 +11 +-10 +10 +-10 +12 +-11 +10 +-12 +11 +-10 +9 +-11 +9 +-11 +11 +-10 +11 +-11 +9 +-10 +9 +-11 +11 +-10 +11 +-10 +11 +-11 +12 +-11 +12 +-10 +10 +-11 +12 +-11 +10 +-9 +10 +-8 +11 +-10 +11 +-9 +11 +-10 +13 +-10 +12 +-10 +11 +-10 +10 +-9 +10 +-10 +11 +-11 +10 +-9 +10 +-11 +9 +-11 +12 +-9 +9 +-9 +9 +-10 +9 +-9 +10 +-12 +10 +-10 +8 +-11 +9 +-11 +10 +-11 +10 +-10 +10 +-10 +10 +-12 +10 +-10 +8 +-11 +10 +-10 +11 +-10 +12 +-9 +10 +-10 +11 +-10 +11 +-10 +11 +-8 +11 +-11 +11 +-10 +11 +-9 +12 +-11 +12 +-9 +9 +-11 +10 +-10 +10 +-10 +11 +-11 +9 +-10 +9 +-13 +11 +-11 +9 +-12 +11 +-11 +10 +-10 +10 +-10 +12 +-10 +11 +-11 +12 +-9 +12 +-10 +10 +-10 +12 +-9 +10 +-9 +11 +-10 +12 +-11 +13 +-10 +10 +-10 +11 +-10 +10 +-9 +10 +-10 +11 +-11 +11 +-10 +10 +-9 +10 +-10 +10 +-10 +10 +-11 +12 +-10 +11 +-10 +12 +-9 +11 +-10 +10 +-11 +11 +-9 +11 +-11 +9 +-11 +11 +-9 +10 +-11 +11 +-10 +10 +-10 +10 +-11 +11 +-9 +11 +-11 +11 +-10 +10 +-10 +11 +-10 +9 +-9 +11 +-8 +11 +-10 +11 +-9 +11 +-9 +12 +-10 +9 +-10 +11 +-10 +10 +-9 +10 +-10 +11 +-10 +9 +-10 +10 +-10 +11 +-10 +11 +-9 +10 +-11 +12 +-10 +10 +-9 +11 +-10 +11 +-10 +10 +-11 +10 +-10 +11 +-11 +9 +-10 +10 +-10 +11 +-9 +11 +-10 +12 +-9 +11 +-11 +12 +-9 +11 +-11 +11 +-10 +10 +-9 +10 +-9 +9 +-11 +10 +-10 +10 +-10 +11 +-10 +11 +-10 +9 +-11 +10 +-10 +10 +-11 +11 +-10 +10 +-10 +12 +-10 +10 +-11 +10 +-9 +9 +-9 +11 +-10 +11 +-9 +11 +-9 +10 +-9 +10 +-10 +11 +-11 +11 +-10 +11 +-11 +10 +-10 +10 +-10 +11 +-11 +13 +-10 +10 +-11 +11 +-11 +10 +-9 +11 +-10 +10 +-11 +11 +-11 +10 +-9 +10 +-11 +11 +-10 +12 +-11 +9 +-9 +10 +-11 +11 +-10 +11 +-9 +10 +-11 +9 +-11 +11 +-9 +10 +-10 +11 +-11 +9 +-9 +11 +-8 +9 +-9 +10 +-8 +11 +-11 +11 +-9 +9 +-11 +11 +-11 +10 +-11 +11 +-12 +11 +-9 +8 +-9 +9 +-12 +10 +-10 +11 +-10 +12 +-10 +12 +-10 +10 +-9 +10 +-10 +13 +-10 +12 +-9 +11 +-9 +10 +-10 +11 +-10 +10 +-11 +10 +-11 +11 +-10 +8 +-10 +10 +-11 +9 +-12 +10 +-11 +10 +-10 +10 +-11 +11 +-11 +12 +-10 +10 +-8 +10 +-10 +10 +-9 +11 +-8 +11 +-11 +12 +-10 +11 +-9 +9 +-9 +11 +-13 +10 +-8 +10 +-9 +12 +-10 +12 +-10 +10 +-10 +12 +-10 +9 +-9 +11 +-10 +10 +-10 +12 +-11 +11 +-9 +11 +-10 +11 +-11 +11 +-11 +12 +-10 +11 +-10 +11 +-10 +11 +-10 +10 +-10 +9 +-11 +10 +-10 +10 +-12 +9 +-9 +9 +-9 +10 +-10 +11 +-12 +12 +-11 +12 +-8 +11 +-12 +9 +-10 +10 +-10 +11 +-11 +11 +-10 +11 +-9 +11 +-9 +10 +-9 +10 +-11 +10 +-10 +10 +-10 +9 +-10 +11 +-12 +10 +-10 +10 +-11 +11 +-10 +10 +-10 +10 +-11 +11 +-10 +9 +-11 +12 +-11 +11 +-10 +10 +-10 +11 +-10 +10 +-10 +9 +-11 +10 +-11 +11 +-10 +7 +-9 +10 +-10 +9 +-10 +11 +-9 +11 +-10 +11 +-10 +10 +-9 +10 +-9 +11 +-10 +10 +-9 +11 +-9 +11 +-9 +11 +-9 +11 +-10 +10 +-10 +10 +-9 +11 +-10 +10 +-9 +10 +-10 +11 +-11 +10 +-10 +11 +-10 +8 +-11 +10 +-10 +10 +-11 +10 +-11 +10 +-9 +11 +-10 +10 +-10 +10 +-11 +12 +-9 +10 +-9 +9 +-9 +11 +-10 +11 +-10 +10 +-9 +10 +-8 +10 +-9 +12 +-10 +11 +-9 +12 +-8 +11 +-9 +12 +-10 +12 +-11 +10 +-10 +9 +-12 +12 +-9 +9 +-11 +11 +-10 +11 +-9 +8 +-10 +10 +-9 +11 +-10 +9 +-10 +10 +-10 +11 +-9 +9 +-10 +11 +-10 +11 +-7 +9 +-9 +12 +-10 +11 +-10 +9 +-11 +11 +-11 +9 +-10 +10 +-11 +8 +-11 +9 +-9 +10 +-11 +10 +-11 +11 +-12 +11 +-10 +12 +-10 +11 +-10 +13 +10 +-14 +11 +-12 +10 +-11 +10 +-11 +10 +-10 +9 +-10 +10 +-11 +9 +-10 +9 +-12 +9 +-9 +9 +-10 +11 +-12 +9 +-11 +9 +-11 +8 +-10 +9 +-9 +9 +-10 +9 +-10 +9 +-8 +10 +-9 +9 +-10 +10 +-9 +9 +-10 +10 +-10 +11 +-10 +9 +-9 +9 +-11 +9 +-9 +9 +-9 +9 +-11 +10 +-11 +10 +-9 +9 +-10 +11 +-8 +10 +-7 +9 +-9 +12 +-9 +11 +-8 +10 +-9 +12 +-9 +10 +-9 +9 +-10 +10 +-10 +10 +-9 +9 +-9 +9 +-10 +9 +-10 +10 +-12 +-7 +16 +-7 +12 +-9 +11 +-10 +12 +-8 +10 +-9 +10 +-10 +11 +-10 +10 +-9 +9 +-8 +10 +-9 +8 +-8 +9 +-10 +10 +-9 +12 +-10 +10 +-8 +10 +-11 +11 +-9 +11 +-8 +12 +-8 +11 +-8 +12 +-9 +13 +-10 +11 +-10 +12 +-10 +11 +-8 +9 +-9 +10 +-8 +10 +-11 +12 +-9 +11 +-10 +11 +-10 +11 +-9 +10 +-10 +10 +-11 +10 +-10 +10 +-9 +10 +-10 +10 +-9 +12 +-9 +11 +-10 +10 +-10 +10 +-10 +11 +-11 +10 +-11 +10 +-10 +9 +-10 +10 +-11 +14 +10 +-15 +10 +-11 +9 +-12 +9 +-11 +10 +-10 +8 +-12 +10 +-10 +10 +-11 +9 +-10 +9 +-9 +9 +-12 +10 +-11 +10 +-10 +10 +-10 +11 +-9 +10 +-8 +10 +-9 +10 +-9 +11 +-9 +10 +-9 +10 +-10 +10 +-10 +9 +-10 +11 +-10 +10 +-9 +11 +-10 +10 +-9 +10 +-9 +9 +-11 +10 +-11 +10 +-10 +9 +-13 +-10 +14 +-8 +9 +-10 +11 +-9 +10 +-10 +12 +-9 +13 +-9 +9 +-10 +11 +-9 +11 +-8 +12 +-8 +10 +-8 +10 +-10 +12 +-9 +11 +-9 +10 +-8 +9 +-12 +11 +-9 +10 +-11 +10 +-11 +9 +-8 +10 +-11 +11 +-10 +10 +-10 +9 +-11 +11 +-11 +9 +-11 +9 +-9 +11 +-10 +10 +-10 +10 +-9 +10 +-10 +11 +-10 +9 +-10 +9 +-10 +10 +-11 +10 +-9 +11 +-10 +9 +-10 +11 +-10 +11 +-10 +10 +-9 +10 +-10 +10 +-9 +11 +-9 +11 +-9 +10 +-10 +13 +-9 +10 +-9 +9 +-10 +10 +-11 +11 +-9 +10 +-11 +10 +-11 +10 +-9 +8 +-11 +11 +-11 +11 +-9 +11 +-11 +10 +-11 +10 +-11 +12 +-11 +11 +-10 +10 +-9 +13 +11 +-15 +11 +-11 +9 +-11 +9 +-11 +9 +-11 +10 +-10 +10 +-9 +8 +-10 +9 +-10 +9 +-11 +11 +-10 +10 +-9 +8 +-10 +9 +-9 +10 +-10 +11 +-13 +-8 +14 +-7 +10 +-10 +11 +-8 +12 +-8 +10 +-9 +12 +-10 +9 +-9 +11 +-9 +12 +-8 +10 +-11 +11 +-11 +11 +-10 +10 +-9 +10 +-10 +11 +-10 +9 +-10 +10 +-9 +8 +-11 +11 +-10 +9 +-10 +9 +-10 +9 +-9 +12 +-12 +10 +-9 +11 +-8 +10 +-9 +10 +-10 +9 +-10 +11 +-10 +9 +-11 +11 +-9 +10 +-10 +13 +-12 +10 +-11 +10 +-8 +12 +-9 +13 +-9 +13 +-9 +10 +-9 +10 +-9 +9 +-11 +10 +-10 +10 +-11 +9 +-10 +9 +-11 +10 +-10 +9 +-11 +13 +11 +-15 +10 +-12 +9 +-11 +10 +-10 +9 +-11 +10 +-11 +9 +-11 +9 +-11 +8 +-10 +10 +-10 +11 +-9 +8 +-9 +9 +-9 +11 +-10 +11 +-9 +12 +-9 +8 +-10 +10 +-10 +10 +-9 +9 +-9 +11 +-9 +10 +-9 +10 +-10 +10 +-10 +10 +-9 +11 +-8 +10 +-8 +11 +-10 +11 +-8 +10 +-9 +11 +-9 +9 +-12 +-8 +14 +-9 +12 +-10 +13 +-9 +9 +-8 +9 +-10 +11 +-8 +11 +-10 +11 +-8 +12 +-8 +10 +-9 +11 +-9 +10 +-9 +11 +-9 +12 +-9 +10 +-10 +11 +-8 +10 +-9 +11 +-10 +11 +-11 +11 +-11 +9 +-10 +10 +-10 +9 +-9 +9 +-10 +10 +-11 +10 +-11 +9 +-10 +9 +-11 +9 +-12 +11 +-10 +11 +-11 +11 +-9 +9 +-9 +10 +-9 +9 +-10 +12 +-11 +9 +-10 +10 +-11 +10 +-11 +9 +-9 +9 +-9 +10 +-12 +10 +-10 +11 +-9 +11 +-10 +11 +-9 +12 +-10 +12 +-11 +12 +-8 +11 +-10 +9 +-9 +11 +-10 +10 +-11 +9 +-10 +10 +-11 +9 +-11 +10 +-9 +9 +-11 +10 +-10 +11 +-9 +11 +-8 +10 +-11 +12 +-9 +11 +-11 +11 +-11 +10 +-11 +10 +-10 +9 +-11 +12 +-12 +10 +-10 +9 +-11 +10 +-11 +11 +-9 +11 +-12 +11 +-10 +11 +-9 +12 +-9 +10 +-9 +12 +-10 +11 +-9 +11 +-10 +10 +-10 +13 +-9 +12 +-11 +11 +-10 +11 +-10 +10 +-9 +10 +-9 +11 +-10 +10 +-9 +9 +-11 +12 +-9 +10 +-8 +10 +-9 +10 +-10 +15 +9 +-15 +11 +-10 +8 +-11 +9 +-11 +9 +-10 +8 +-11 +11 +-10 +10 +-11 +9 +-9 +8 +-10 +9 +-10 +10 +-10 +9 +-9 +9 +-9 +11 +-10 +9 +-10 +11 +-12 +10 +-10 +10 +-11 +9 +-10 +10 +-11 +9 +-11 +9 +-10 +8 +-9 +10 +-8 +10 +-9 +10 +-10 +11 +-10 +10 +-8 +9 +-9 +10 +-9 +10 +-13 +-8 +13 +-7 +11 +-10 +9 +-10 +11 +-8 +10 +-8 +11 +-8 +11 +-10 +9 +-8 +10 +-8 +11 +-10 +11 +-10 +9 +-9 +9 +-8 +9 +-12 +10 +-7 +8 +-10 +10 +-11 +10 +-8 +10 +-11 +10 +-10 +10 +-9 +9 +-9 +10 +-9 +8 +-9 +13 +-10 +9 +-12 +11 +-10 +12 +-9 +10 +-10 +11 +-10 +11 +-11 +12 +-9 +10 +-11 +8 +-10 +10 +-10 +12 +-9 +11 +-8 +11 +-10 +11 +-10 +10 +-10 +13 +-9 +11 +-10 +11 +-9 +9 +-9 +10 +-11 +11 +-10 +12 +-11 +10 +-10 +11 +-10 +11 +-10 +12 +-10 +10 +-10 +11 +-11 +10 +-10 +9 +-10 +10 +-11 +8 +-10 +11 +-11 +9 +-12 +14 +-10 +9 +-10 +13 +-9 +12 +-10 +10 +-10 +11 +-10 +9 +-9 +11 +-9 +11 +-13 +9 +-10 +10 +-11 +9 +-10 +12 +-10 +10 +-9 +10 +-11 +9 +-10 +10 +-8 +11 +-11 +12 +-10 +10 +-10 +15 +10 +-14 +11 +-10 +10 +-10 +9 +-10 +9 +-10 +8 +-11 +11 +-9 +10 +-10 +8 +-10 +9 +-12 +11 +-6 +8 +-11 +12 +-9 +11 +-8 +10 +-10 +11 +-11 +9 +-9 +10 +-8 +10 +-10 +9 +-10 +10 +-9 +12 +-9 +9 +-8 +10 +-9 +11 +-9 +10 +-9 +9 +-7 +9 +-11 +11 +-10 +9 +-9 +9 +-10 +9 +-13 +-9 +14 +-8 +11 +-10 +10 +-10 +9 +-9 +9 +-9 +10 +-9 +11 +-10 +11 +-9 +11 +-10 +11 +-9 +10 +-10 +10 +-9 +11 +-12 +10 +-9 +9 +-11 +15 +9 +-15 +10 +-10 +10 +-11 +10 +-9 +9 +-9 +9 +-10 +12 +-11 +9 +-8 +8 +-11 +10 +-9 +10 +-10 +10 +-10 +9 +-10 +10 +-10 +9 +-7 +9 +-14 +-7 +14 +-8 +9 +-9 +12 +-10 +10 +-8 +11 +-11 +10 +-8 +11 +-8 +11 +-8 +11 +-9 +10 +-10 +11 +-9 +10 +-9 +10 +-11 +10 +-9 +10 +-10 +10 +-8 +9 +-11 +11 +-11 +10 +-11 +12 +-10 +11 +-9 +12 +-10 +11 +-9 +10 +-10 +11 +-9 +10 +-9 +12 +-8 +9 +-9 +10 +-9 +12 +-9 +8 +-10 +11 +-9 +10 +-10 +12 +-12 +12 +-10 +11 +-7 +10 +-9 +12 +-10 +11 +-10 +11 +-10 +11 +-10 +11 +-10 +8 +-9 +9 +-10 +11 +-10 +10 +-9 +12 +-9 +10 +-9 +12 +-11 +11 +-9 +10 +-10 +12 +-10 +12 +-9 +10 +-9 +10 +-9 +11 +-12 +10 +-9 +9 +-9 +10 +-10 +10 +-9 +9 +-9 +10 +-11 +10 +-9 +10 +-10 +10 +-12 +11 +-11 +11 +-11 +10 +-11 +10 +-12 +9 +-10 +9 +-11 +10 +-11 +10 +-10 +10 +-11 +12 +-11 +11 +-10 +10 +-11 +12 +-11 +9 +-11 +11 +-9 +10 +-11 +12 +-10 +10 +-11 +12 +-10 +11 +-9 +10 +-10 +12 +-9 +13 +-9 +11 +-10 +12 +-9 +10 +-9 +11 +-11 +11 +-11 +10 +-10 +10 +-10 +9 +-12 +9 +-10 +10 +-9 +10 +-12 +11 +-9 +10 +-12 +11 +-12 +11 +-11 +11 +-10 +11 +-11 +12 +-9 +10 +-10 +12 +-9 +11 +-9 +11 +-9 +11 +-9 +11 +-8 +10 +-11 +13 +-9 +10 +-9 +10 +-9 +11 +-10 +10 +-12 +11 +-10 +11 +-10 +12 +-10 +11 +-9 +11 +-9 +11 +-10 +12 +-9 +9 +-9 +11 +-9 +12 +-10 +11 +-10 +11 +-10 +9 +-9 +10 +-10 +10 +-10 +8 +-11 +10 +-11 +10 +-10 +10 +-10 +9 +-11 +12 +-10 +10 +-10 +9 +-10 +11 +-11 +10 +-11 +11 +-10 +9 +-10 +11 +-11 +9 +-11 +12 +-9 +10 +-9 +9 +-11 +10 +-10 +10 +-9 +9 +-10 +9 +-10 +11 +-9 +11 +-11 +11 +-8 +10 +-10 +10 +-9 +9 +-11 +11 +-10 +10 +-10 +11 +-9 +10 +-9 +11 +-10 +11 +-10 +11 +-9 +8 +-12 +12 +-9 +11 +-9 +10 +-10 +11 +-10 +11 +-9 +9 +-9 +12 +-9 +12 +-9 +10 +-10 +12 +-10 +11 +-10 +10 +-11 +10 +-10 +10 +-11 +11 +-10 +9 +-10 +11 +-9 +10 +-10 +10 +-11 +10 +-10 +9 +-10 +10 +-10 +12 +-10 +9 +-9 +10 +-10 +12 +-10 +11 +-9 +10 +-10 +10 +-11 +11 +-9 +11 +-9 +11 +-9 +11 +-10 +12 +-10 +10 +-10 +10 +-10 +10 +-10 +9 +-9 +11 +-10 +9 +-9 +12 +-11 +10 +-10 +10 +-11 +10 +-12 +11 +-11 +10 +-10 +9 +-11 +12 +-10 +11 +-10 +10 +-9 +10 +-10 +11 +-10 +10 +-9 +10 +-10 +11 +-10 +11 +-9 +12 +-12 +9 +-10 +10 +-10 +10 +-10 +11 +-11 +9 +-9 +9 +-9 +11 +-10 +12 +-10 +10 +-10 +11 +-9 +10 +-9 +10 +-10 +11 +-10 +10 +-9 +9 +-11 +12 +-12 +10 +-10 +9 +-11 +11 +-9 +11 +-9 +12 +-11 +10 +-10 +10 +-9 +10 +-9 +10 +-10 +11 +-10 +11 +-12 +13 +-10 +12 +-9 +10 +-11 +12 +-11 +11 +-10 +10 +-10 +11 +-11 +11 +-9 +10 +-12 +11 +-9 +10 +-10 +11 +-11 +12 +-11 +9 +-9 +10 +-11 +10 +-11 +11 +-10 +9 +-10 +10 +-11 +10 +-9 +10 +-11 +11 +-11 +11 +-10 +11 +-9 +10 +-9 +11 +-10 +11 +-10 +10 +-10 +12 +-10 +12 +-9 +10 +-10 +12 +-11 +11 +-9 +11 +-9 +10 +-10 +11 +-11 +11 +-8 +9 +-10 +10 +-10 +10 +-11 +11 +-10 +11 +-9 +10 +-10 +10 +-10 +10 +-11 +10 +-9 +9 +-10 +10 +-10 +11 +-10 +12 +-10 +10 +-10 +11 +-10 +10 +-11 +11 +-9 +9 +-11 +11 +-10 +9 +-10 +11 +-10 +11 +-11 +10 +-10 +12 +-11 +10 +-11 +10 +-11 +10 +-10 +11 +-11 +12 +-10 +10 +-9 +10 +-9 +10 +-10 +11 +-10 +9 +-10 +10 +-12 +10 +-11 +11 +-10 +11 +-10 +11 +-9 +12 +-9 +11 +-10 +11 +-9 +11 +-9 +12 +-9 +10 +-10 +11 +-8 +10 +-9 +11 +-11 +11 +-11 +9 +-9 +11 +-8 +9 +-10 +11 +-10 +12 +-10 +10 +-8 +10 +-10 +11 +-11 +10 +-11 +10 +-11 +9 +-12 +10 +-10 +10 +-10 +10 +-12 +11 +-10 +9 +-10 +9 +-12 +10 +-10 +10 +-10 +8 +-10 +11 +-10 +11 +-10 +11 +-9 +11 +-9 +10 +-11 +12 +-9 +11 +-10 +11 +-8 +10 +-12 +10 +-10 +10 +-11 +10 +-11 +11 +-11 +9 +-10 +10 +-9 +9 +-10 +11 +-11 +10 +-10 +11 +-11 +11 +-12 +11 +-10 +10 +-11 +11 +-10 +11 +-11 +10 +-11 +9 +-9 +10 +-10 +10 +-11 +13 +-11 +10 +-10 +11 +-9 +11 +-9 +10 +-11 +11 +-10 +12 +-10 +9 +-9 +10 +-10 +12 +-10 +11 +-10 +11 +-11 +10 +-9 +10 +-10 +11 +-10 +11 +-9 +9 +-8 +10 +-9 +10 +-10 +12 +-10 +9 +-10 +10 +-11 +12 +-9 +11 +-9 +10 +-11 +11 +-10 +10 +-10 +11 +-9 +10 +-9 +9 +-11 +12 +-11 +12 +-9 +10 +-9 +11 +-10 +12 +-10 +12 +-10 +11 +-9 +11 +-9 +10 +-10 +11 +-10 +11 +-11 +10 +-11 +10 +-10 +10 +-10 +13 +-11 +10 +-10 +10 +-9 +9 +-10 +9 +-10 +9 +-11 +9 +-10 +11 +-11 +10 +-11 +9 +-9 +11 +-10 +11 +-10 +10 +-11 +10 +-10 +9 +-11 +10 +-11 +10 +-11 +10 +-11 +10 +-10 +9 +-11 +10 +-10 +10 +-12 +10 +-10 +11 +-10 +10 +-9 +12 +-9 +10 +-10 +9 +-10 +10 +-11 +10 +-10 +11 +-10 +10 +-10 +10 +-10 +15 +9 +-15 +11 +-11 +11 +-11 +10 +-10 +9 +-9 +11 +-9 +10 +-9 +10 +-11 +12 +-9 +8 +-10 +9 +-11 +10 +-10 +10 +-9 +10 +-10 +11 +-8 +10 +-10 +11 +-9 +8 +-10 +11 +-8 +11 +-10 +10 +-11 +11 +-9 +8 +-8 +8 +-10 +10 +-9 +9 +-10 +9 +-10 +10 +-8 +10 +-11 +10 +-7 +8 +-10 +10 +-10 +8 +-10 +12 +-9 +9 +-8 +9 +-7 +10 +-9 +10 +-7 +10 +-8 +11 +-9 +10 +-8 +10 +-9 +9 +-10 +10 +-9 +8 +-8 +10 +-9 +9 +-9 +11 +-13 +-8 +13 +-8 +11 +-10 +9 +-8 +10 +-9 +11 +-10 +10 +-9 +9 +-9 +9 +-10 +10 +-11 +10 +-10 +11 +-11 +11 +-9 +9 +-10 +10 +-9 +12 +-9 +11 +-9 +10 +-9 +11 +-10 +11 +-8 +10 +-12 +10 +-10 +9 +-11 +11 +-11 +11 +-10 +9 +-10 +9 +-10 +10 +-10 +10 +-10 +10 +-10 +10 +-9 +9 +-9 +10 +-9 +11 +-10 +10 +-11 +10 +-10 +11 +-10 +10 +-10 +12 +-11 +11 +-10 +12 +-11 +11 +-10 +11 +-11 +11 +-9 +9 +-10 +10 +-11 +10 +-9 +10 +-9 +13 +10 +-14 +11 +-12 +9 +-12 +10 +-10 +10 +-11 +9 +-10 +10 +-10 +11 +-9 +11 +-9 +10 +-9 +12 +-10 +11 +-9 +12 +-8 +11 +-9 +10 +-10 +11 +-10 +10 +-10 +10 +-9 +9 +-8 +9 +-10 +9 +-10 +9 +-10 +11 +-11 +9 +-10 +9 +-10 +9 +-9 +8 +-10 +9 +-11 +10 +-11 +10 +-11 +8 +-9 +9 +-13 +-6 +11 +-8 +10 +-10 +12 +-8 +11 +-8 +11 +-7 +10 +-10 +11 +-8 +11 +-8 +12 +-11 +11 +-6 +9 +-11 +11 +-9 +10 +-9 +11 +-10 +11 +-10 +10 +-10 +11 +-11 +10 +-9 +11 +-9 +8 +-9 +11 +-10 +10 +-11 +11 +-9 +9 +-10 +11 +-10 +10 +-9 +11 +-10 +11 +-11 +10 +-11 +9 +-10 +10 +-11 +10 +-9 +10 +-9 +10 +-10 +10 +-10 +10 +-11 +10 +-9 +10 +-10 +12 +-10 +11 +-10 +11 +-10 +11 +-10 +10 +-10 +12 +-9 +11 +-11 +11 +-8 +10 +-11 +11 +-11 +10 +-9 +10 +-11 +12 +-11 +10 +-11 +11 +-11 +10 +-9 +10 +-10 +11 +-8 +11 +-12 +13 +-9 +11 +-9 +11 +-10 +12 +-11 +12 +-9 +9 +-10 +14 +10 +-16 +10 +-11 +10 +-10 +9 +-10 +9 +-10 +10 +-11 +11 +-12 +8 +-11 +10 +-11 +10 +-11 +8 +-10 +10 +-9 +10 +-10 +10 +-10 +10 +-9 +11 +-13 +-7 +15 +-7 +10 +-8 +10 +-9 +12 +-9 +11 +-10 +6 +-8 +10 +-8 +11 +-9 +11 +-8 +11 +-9 +10 +-9 +9 +-9 +9 +-10 +10 +-10 +10 +-9 +11 +-10 +12 +-10 +11 +-9 +11 +-9 +11 +-10 +9 +-9 +10 +-10 +10 +-10 +9 +-11 +9 +-9 +11 +-11 +11 +-9 +11 +-10 +12 +-8 +10 +-9 +9 +-8 +11 +-10 +10 +-11 +10 +-10 +11 +-10 +11 +-11 +10 +-11 +10 +-10 +11 +-12 +11 +-10 +11 +-8 +9 +-11 +9 +-10 +10 +-10 +8 +-10 +10 +-11 +9 +-12 +15 +9 +-16 +9 +-12 +10 +-10 +8 +-10 +8 +-12 +9 +-12 +10 +-10 +8 +-11 +10 +-9 +10 +-8 +9 +-9 +9 +-8 +9 +-8 +11 +-9 +11 +-9 +11 +-10 +9 +-9 +10 +-9 +9 +-9 +10 +-9 +9 +-9 +9 +-10 +9 +-11 +12 +-9 +7 +-10 +9 +-9 +10 +-12 +9 +-9 +9 +-9 +11 +-9 +12 +-9 +9 +-13 +-8 +14 +-7 +12 +-8 +11 +-9 +12 +-9 +10 +-9 +11 +-10 +10 +-8 +9 +-9 +10 +-9 +10 +-11 +11 +-8 +10 +-10 +11 +-9 +9 +-11 +10 +-10 +10 +-11 +8 +-10 +10 +-11 +10 +-10 +10 +-10 +11 +-10 +10 +-9 +12 +-8 +11 +-9 +9 +-9 +10 +-9 +13 +-9 +10 +-9 +10 +-10 +9 +-10 +10 +-9 +11 +-10 +10 +-11 +11 +-9 +9 +-9 +9 +-10 +12 +-11 +11 +-11 +11 +-8 +9 +-9 +12 +-8 +11 +-11 +11 +-10 +11 +-10 +10 +-11 +12 +-10 +12 +-10 +12 +-12 +11 +-10 +11 +-11 +11 +-10 +11 +-10 +12 +-10 +11 +-10 +11 +-10 +10 +-10 +9 +-10 +10 +-11 +12 +-11 +12 +-10 +11 +-11 +10 +-10 +10 +-10 +11 +-10 +12 +-12 +9 +-9 +9 +-11 +12 +-10 +10 +-10 +10 +-11 +11 +-9 +10 +-10 +9 +-10 +10 +-10 +9 +-10 +11 +-10 +9 +-11 +10 +-11 +12 +-10 +10 +-9 +9 +-10 +11 +-10 +11 +-10 +11 +-9 +11 +-8 +11 +-9 +12 +-12 +11 +-8 +11 +-11 +12 +-10 +10 +-9 +10 +-11 +10 +-11 +10 +-10 +10 +-11 +14 +9 +-15 +10 +-12 +9 +-11 +10 +-12 +11 +-9 +9 +-13 +11 +-11 +9 +-10 +9 +-10 +11 +-9 +8 +-11 +12 +-10 +10 +-11 +10 +-10 +11 +-9 +10 +-10 +10 +-9 +9 +-10 +9 +-10 +9 +-9 +9 +-9 +9 +-10 +9 +-10 +10 +-9 +9 +-9 +11 +-8 +9 +-8 +8 +-8 +9 +-8 +9 +-9 +11 +-8 +10 +-13 +-9 +16 +-8 +11 +-9 +10 +-8 +11 +-8 +11 +-9 +8 +-9 +12 +-10 +10 +-9 +10 +-9 +11 +-9 +11 +-10 +10 +-10 +9 +-9 +9 +-9 +10 +-10 +10 +-11 +10 +-10 +10 +-9 +13 +-10 +10 +-8 +11 +-8 +11 +-10 +12 +-8 +12 +-8 +12 +-8 +8 +-10 +12 +-11 +10 +-9 +8 +-10 +10 +-10 +11 +-11 +9 +-11 +10 +-11 +10 +-11 +9 +-10 +10 +-11 +10 +-11 +10 +-9 +10 +-10 +11 +-11 +10 +-8 +9 +-11 +11 +-10 +10 +-9 +10 +-11 +10 +-11 +9 +-11 +12 +-10 +11 +-11 +12 +-9 +10 +-10 +11 +-10 +10 +-10 +11 +-9 +10 +-9 +9 +-11 +11 +-10 +10 +-10 +12 +-10 +11 +-8 +11 +-8 +8 +-12 +11 +-9 +10 +-10 +12 +-9 +11 +-9 +10 +-9 +9 +-9 +10 +-9 +11 +-10 +10 +-8 +11 +-13 +13 +-10 +10 +-11 +10 +-11 +13 +-11 +10 +-10 +11 +-9 +11 +-10 +15 +10 +-16 +10 +-11 +9 +-11 +11 +-11 +10 +-10 +9 +-11 +10 +-10 +9 +-11 +9 +-10 +9 +-12 +10 +-10 +10 +-11 +9 +-11 +11 +-9 +9 +-10 +10 +-10 +9 +-10 +10 +-10 +10 +-8 +9 +-9 +11 +-9 +10 +-8 +9 +-10 +8 +-9 +10 +-9 +10 +-9 +9 +-9 +9 +-9 +9 +-10 +9 +-10 +9 +-11 +10 +-12 +-8 +13 +-8 +10 +-10 +10 +-8 +10 +-8 +12 +-8 +11 +-9 +11 +-7 +11 +-10 +12 +-10 +10 +-8 +11 +-9 +10 +-8 +10 +-9 +10 +-10 +11 +-9 +14 +10 +-16 +10 +-11 +11 +-10 +9 +-9 +9 +-10 +10 +-10 +11 +-10 +10 +-9 +11 +-10 +11 +-10 +10 +-9 +8 +-10 +10 +-9 +10 +-11 +9 +-10 +10 +-13 +-8 +14 +-8 +11 +-9 +9 +-9 +11 +-10 +10 +-9 +10 +-10 +10 +-9 +11 +-10 +9 +-9 +12 +-9 +10 +-9 +11 +-10 +9 +-9 +10 +-11 +11 +-9 +11 +-9 +9 +-10 +10 +-10 +11 +-9 +10 +-9 +10 +-11 +9 +-10 +12 +-10 +10 +-10 +10 +-10 +11 +-10 +11 +-10 +9 +-10 +10 +-10 +12 +-12 +9 +-10 +9 +-10 +11 +-10 +12 +-9 +11 +-11 +11 +-10 +10 +-9 +11 +-11 +10 +-9 +11 +-9 +10 +-10 +11 +-9 +10 +-10 +11 +-10 +11 +-10 +10 +-10 +10 +-11 +10 +-9 +11 +-10 +10 +-11 +12 +-10 +10 +-10 +10 +-10 +10 +-11 +11 +-11 +12 +-12 +10 +-10 +10 +-10 +12 +-11 +10 +-10 +11 +-9 +11 +-10 +11 +-9 +12 +-9 +12 +-10 +11 +-10 +12 +-11 +10 +-10 +11 +-9 +9 +-10 +11 +-9 +11 +-11 +10 +-9 +10 +-11 +12 +-9 +11 +-9 +10 +-10 +12 +-9 +11 +-9 +9 +-10 +12 +-11 +11 +-11 +9 +-9 +11 +-11 +10 +-9 +11 +-10 +12 +-10 +11 +-9 +10 +-10 +11 +-11 +10 +-9 +11 +-10 +10 +-9 +11 +-10 +12 +-10 +12 +-10 +11 +-11 +11 +-10 +11 +-10 +11 +-10 +12 +-11 +9 +-10 +10 +-10 +10 +-9 +10 +-9 +10 +-10 +9 +-9 +10 +-10 +11 +-9 +11 +-10 +12 +-10 +11 +-10 +12 +-10 +11 +-10 +12 +-11 +10 +-11 +11 +-12 +9 +-8 +10 +-10 +10 +-11 +9 +-10 +10 +-10 +9 +-10 +10 +-10 +9 +-10 +10 +-12 +10 +-9 +9 +-10 +10 +-9 +11 +-10 +11 +-9 +10 +-9 +11 +-9 +11 +-8 +8 +-10 +11 +-10 +11 +-10 +10 +-10 +9 +-10 +11 +-11 +10 +-11 +12 +-9 +9 +-10 +10 +-10 +8 +-10 +12 +-10 +10 +-9 +9 +-11 +10 +-11 +10 +-10 +11 +-9 +9 +-9 +10 +-9 +11 +-10 +12 +-11 +12 +-11 +10 +-10 +10 +-9 +12 +-10 +12 +-9 +10 +-10 +11 +-10 +10 +-11 +11 +-10 +10 +-9 +8 +-11 +10 +-11 +10 +-10 +12 +-9 +11 +-10 +10 +-10 +10 +-10 +11 +-10 +10 +-11 +11 +-9 +10 +-10 +11 +-9 +10 +-10 +9 +-11 +11 +-9 +11 +-9 +11 +-10 +10 +-10 +10 +-10 +12 +-10 +11 +-10 +11 +-9 +12 +-9 +12 +-10 +10 +-10 +11 +-11 +11 +-10 +10 +-10 +10 +-10 +10 +-11 +10 +-11 +10 +-10 +9 +-9 +10 +-10 +12 +-10 +10 +-10 +9 +-11 +11 +-11 +11 +-12 +10 +-10 +11 +-11 +11 +-10 +10 +-9 +10 +-10 +12 +-10 +11 +-9 +10 +-9 +10 +-9 +10 +-11 +11 +-11 +12 +-9 +11 +-12 +12 +-10 +12 +-10 +10 +-9 +11 +-10 +10 +-11 +11 +-10 +9 +-10 +10 +-10 +11 +-11 +11 +-9 +10 +-10 +10 +-10 +11 +-9 +11 +-11 +9 +-9 +10 +-10 +11 +-10 +11 +-9 +9 +-11 +13 +-9 +11 +-10 +11 +-10 +10 +-11 +10 +-8 +8 +-10 +11 +-10 +10 +-10 +9 +-12 +12 +-10 +10 +-9 +11 +-11 +13 +-10 +10 +-11 +11 +-10 +11 +-10 +11 +-11 +11 +-11 +11 +-10 +10 +-8 +10 +-10 +9 +-10 +11 +-10 +10 +-10 +12 +-11 +12 +-9 +10 +-11 +11 +-10 +12 +-10 +10 +-9 +9 +-10 +11 +-11 +7 +-10 +10 +-11 +10 +-10 +11 +-10 +12 +-9 +11 +-9 +11 +-10 +11 +-12 +10 +-11 +9 +-9 +10 +-9 +12 +-9 +10 +-8 +11 +-11 +11 +-10 +10 +-10 +11 +-11 +11 +-11 +9 +-10 +10 +-11 +12 +-11 +11 +-11 +11 +-10 +10 +-10 +11 +-8 +9 +-10 +10 +-10 +10 +-9 +9 +-10 +11 +-11 +10 +-11 +12 +-10 +11 +-9 +10 +-10 +10 +-9 +11 +-9 +11 +-8 +10 +-11 +11 +-10 +11 +-12 +12 +-10 +10 +-10 +10 +-11 +11 +-11 +9 +-10 +11 +-11 +10 +-11 +10 +-10 +11 +-11 +10 +-11 +11 +-12 +10 +-9 +11 +-12 +11 +-10 +10 +-9 +10 +-10 +11 +-10 +9 +-10 +10 +-11 +12 +-9 +11 +-11 +11 +-11 +11 +-11 +11 +-8 +11 +-10 +11 +-9 +11 +-11 +10 +-10 +9 +-8 +10 +-10 +11 +-10 +10 +-11 +11 +-9 +9 +-10 +10 +-9 +11 +-11 +10 +-11 +10 +-11 +10 +-11 +11 +-10 +9 +-12 +11 +-9 +10 +-10 +11 +-10 +12 +-9 +10 +-10 +12 +-9 +11 +-9 +11 +-9 +12 +-9 +10 +-9 +12 +-10 +11 +-10 +10 +-11 +11 +-10 +9 +-11 +12 +-10 +11 +-9 +13 +-8 +12 +-9 +10 +-9 +11 +-10 +10 +-10 +10 +-10 +12 +-9 +10 +-10 +10 +-9 +12 +-12 +11 +-11 +9 +-10 +10 +-8 +11 +-10 +12 +-9 +10 +-10 +11 +-10 +10 +-11 +9 +-9 +10 +-11 +10 +-9 +10 +-9 +10 +-11 +11 +-11 +10 +-10 +10 +-10 +9 +-9 +11 +-11 +11 +-11 +10 +-10 +9 +-11 +9 +-9 +9 +-10 +8 +-11 +10 +-8 +9 +-11 +10 +-10 +10 +-10 +11 +-10 +10 +-9 +11 +-9 +10 +-10 +12 +-9 +11 +-10 +12 +-8 +10 +-9 +11 +-10 +10 +-9 +9 +-11 +10 +-9 +10 +-11 +9 +-10 +12 +-11 +10 +-11 +11 +-12 +9 +-11 +11 +-12 +9 +-10 +10 +-12 +11 +-10 +10 +-10 +10 +-11 +10 +-11 +10 +-10 +11 +-11 +12 +-9 +11 +-10 +11 +-11 +11 +-10 +9 +-10 +10 +-9 +11 +-10 +12 +-9 +11 +-9 +9 +-10 +10 +-10 +9 +-9 +10 +-10 +10 +-11 +11 +-9 +10 +-11 +11 +-11 +11 +-10 +10 +-9 +11 +-10 +12 +-10 +11 +-11 +12 +-9 +11 +-10 +10 +-10 +11 +-10 +10 +-9 +10 +-10 +11 +-10 +11 +-10 +10 +-10 +9 +-10 +14 +9 +-16 +10 +-11 +9 +-11 +9 +-10 +9 +-11 +10 +-10 +10 +-8 +9 +-10 +9 +-10 +9 +-11 +12 +-10 +10 +-9 +9 +-9 +10 +-9 +10 +-9 +9 +-11 +10 +-10 +8 +-11 +10 +-9 +11 +-9 +10 +-9 +9 +-10 +10 +-10 +9 +-10 +9 +-9 +9 +-10 +9 +-10 +10 +-9 +9 +-9 +11 +-10 +11 +-9 +10 +-8 +10 +-10 +9 +-8 +11 +-9 +10 +-10 +10 +-9 +9 +-10 +10 +-10 +9 +-11 +10 +-10 +9 +-9 +9 +-10 +10 +-9 +11 +-10 +9 +-9 +10 +-10 +11 +-14 +-8 +15 +-7 +11 +-9 +11 +-8 +11 +-9 +10 +-10 +10 +-8 +11 +-9 +11 +-10 +12 +-8 +11 +-8 +11 +-10 +12 +-7 +11 +-10 +12 +-9 +11 +-9 +11 +-9 +11 +-10 +11 +-10 +10 +-10 +8 +-9 +12 +-12 +10 +-10 +10 +-10 +9 +-10 +10 +-11 +11 +-12 +11 +-10 +11 +-10 +10 +-10 +10 +-8 +12 +-10 +11 +-9 +7 +-9 +10 +-11 +11 +-9 +11 +-9 +12 +-12 +12 +-9 +9 +-10 +11 +-10 +11 +-9 +10 +-10 +10 +-8 +10 +-10 +11 +-10 +11 +-11 +10 +-11 +14 +9 +-16 +10 +-11 +9 +-11 +10 +-12 +9 +-10 +8 +-11 +9 +-11 +10 +-12 +9 +-11 +11 +-10 +8 +-10 +11 +-9 +11 +-10 +11 +-10 +10 +-10 +9 +-9 +11 +-11 +12 +-10 +10 +-9 +9 +-10 +11 +-9 +11 +-10 +11 +-10 +10 +-10 +10 +-9 +9 +-10 +10 +-9 +9 +-9 +9 +-10 +9 +-8 +8 +-9 +10 +-12 +-9 +14 +-8 +11 +-9 +10 +-9 +10 +-9 +10 +-9 +11 +-9 +10 +-9 +11 +-9 +10 +-8 +12 +-9 +13 +-10 +10 +-9 +10 +-9 +12 +-11 +11 +-9 +9 +-8 +9 +-9 +10 +-9 +10 +-10 +10 +-10 +11 +-11 +10 +-11 +9 +-10 +10 +-12 +12 +-10 +11 +-11 +10 +-8 +10 +-11 +12 +-8 +10 +-10 +11 +-9 +9 +-10 +13 +-11 +9 +-10 +9 +-9 +11 +-12 +11 +-11 +11 +-9 +8 +-11 +12 +-9 +11 +-9 +11 +-11 +11 +-11 +10 +-11 +10 +-11 +11 +-10 +11 +-10 +9 +-10 +9 +-10 +9 +-11 +11 +-12 +12 +-10 +10 +-10 +10 +-11 +10 +-10 +10 +-11 +12 +-10 +12 +-10 +11 +-10 +11 +-11 +11 +-10 +9 +-10 +11 +-10 +15 +10 +-16 +10 +-12 +9 +-11 +10 +-11 +10 +-11 +10 +-10 +10 +-10 +9 +-10 +11 +-10 +10 +-9 +10 +-10 +11 +-9 +11 +-10 +10 +-9 +11 +-9 +11 +-13 +-8 +15 +-8 +10 +-9 +10 +-7 +9 +-10 +10 +-9 +10 +-9 +11 +-9 +11 +-9 +10 +-11 +11 +-10 +9 +-11 +11 +-9 +9 +-11 +11 +-9 +10 +-9 +12 +-10 +10 +-10 +10 +-11 +10 +-9 +11 +-10 +8 +-10 +11 +-8 +10 +-10 +12 +-10 +12 +-10 +12 +-8 +12 +-10 +12 +-10 +10 +-10 +12 +-9 +10 +-8 +10 +-9 +10 +-11 +10 +-10 +9 +-11 +10 +-10 +10 +-9 +9 +-10 +11 +-11 +11 +-10 +9 +-9 +10 +-10 +13 +-11 +12 +-8 +12 +-10 +10 +-10 +11 +-10 +14 +9 +-14 +10 +-12 +10 +-11 +9 +-11 +10 +-10 +10 +-9 +10 +-10 +10 +-10 +9 +-9 +9 +-11 +9 +-12 +9 +-10 +9 +-10 +8 +-9 +8 +-11 +10 +-12 +10 +-10 +11 +-10 +8 +-11 +9 +-9 +9 +-10 +10 +-9 +10 +-8 +10 +-9 +10 +-8 +11 +-9 +11 +-9 +11 +-8 +11 +-10 +11 +-9 +10 +-10 +11 +-12 +-9 +12 +-7 +9 +-9 +11 +-10 +10 +-10 +9 +-11 +9 +-8 +9 +-10 +10 +-10 +10 +-8 +10 +-9 +8 +-10 +10 +-9 +10 +-11 +11 +-11 +9 +-11 +10 +-10 +11 +-8 +10 +-10 +10 +-11 +11 +-11 +9 +-9 +9 +-9 +9 +-10 +12 +-9 +10 +-8 +8 +-9 +12 +-9 +12 +-10 +11 +-9 +11 +-9 +10 +-10 +12 +-10 +10 +-10 +10 +-10 +11 +-10 +11 +-9 +10 +-10 +12 +-8 +11 +-10 +10 +-10 +11 +-10 +11 +-9 +10 +-9 +9 +-10 +11 +-11 +10 +-11 +11 +-11 +10 +-10 +9 +-11 +11 +-9 +11 +-10 +10 +-10 +10 +-9 +10 +-10 +11 +-11 +11 +-9 +10 +-9 +12 +-10 +9 +-10 +11 +-9 +11 +-9 +10 +-10 +10 +-9 +11 +-9 +10 +-9 +10 +-9 +11 +-10 +11 +-10 +11 +-10 +10 +-10 +11 +-9 +11 +-10 +10 +-10 +11 +-9 +10 +-9 +10 +-11 +10 +-11 +12 +-12 +11 +-10 +10 +-10 +12 +-12 +10 +-10 +11 +-10 +11 +-10 +11 +-9 +12 +-10 +11 +-10 +12 +-10 +8 +-8 +11 +-12 +13 +-11 +9 +-11 +9 +-11 +10 +-11 +10 +-10 +10 +9 +-16 +10 +-12 +9 +-11 +10 +-11 +9 +-12 +10 +-10 +8 +-11 +10 +-9 +8 +-9 +9 +-11 +9 +-11 +9 +-10 +12 +-10 +11 +-10 +9 +-10 +11 +-10 +11 +-8 +11 +-8 +10 +-8 +10 +-10 +13 +-9 +9 +-9 +10 +-9 +10 +-10 +10 +-9 +9 +-9 +10 +-10 +12 +-10 +9 +-9 +10 +-10 +11 +-9 +9 +-13 +-8 +15 +-8 +11 +-9 +12 +-10 +10 +-9 +10 +-9 +10 +-9 +10 +-10 +10 +-10 +12 +-10 +10 +-10 +11 +-9 +10 +-10 +11 +-9 +13 +-9 +10 +-9 +10 +-9 +11 +-9 +10 +-9 +10 +-10 +11 +-12 +9 +-9 +11 +-9 +10 +-8 +12 +-9 +12 +-10 +11 +-10 +11 +-9 +11 +-9 +11 +-9 +11 +-11 +11 +-9 +11 +-9 +11 +-10 +11 +-11 +10 +-10 +11 +-10 +9 +-10 +11 +-11 +10 +-11 +10 +-11 +10 +-11 +10 +-10 +11 +-12 +10 +-10 +9 +-11 +10 +-9 +12 +-8 +8 +-11 +12 +-9 +10 +-10 +11 +-9 +12 +-10 +12 +-9 +11 +-11 +9 +-9 +7 +-9 +10 +-10 +12 +-10 +12 +-10 +10 +-11 +11 +-10 +12 +-10 +11 +-11 +12 +-10 +9 +-10 +11 +-13 +9 +-10 +9 +-9 +11 +-12 +10 +-10 +11 +-8 +9 +-11 +11 +-9 +11 +-9 +12 +-10 +11 +-9 +11 +-10 +9 +-10 +10 +-11 +13 +10 +-14 +12 +-13 +9 +-10 +11 +-11 +9 +-10 +9 +-10 +10 +-11 +9 +-11 +9 +-10 +8 +-10 +8 +-9 +9 +-9 +10 +-10 +11 +-9 +10 +-9 +10 +-9 +10 +-9 +9 +-9 +11 +-10 +11 +-10 +10 +-10 +9 +-10 +9 +-10 +9 +-9 +10 +-10 +10 +-9 +9 +-10 +9 +-8 +10 +-9 +9 +-11 +11 +-9 +9 +-13 +-10 +14 +-8 +10 +-10 +10 +-11 +11 +-8 +9 +-9 +9 +-10 +11 +-9 +10 +-9 +11 +-11 +10 +-9 +11 +-10 +13 +-10 +10 +-10 +10 +-10 +10 +-9 +14 +9 +-14 +8 +-11 +10 +-11 +10 +-12 +9 +-11 +9 +-10 +8 +-10 +9 +-10 +10 +-10 +9 +-10 +9 +-10 +11 +-8 +9 +-8 +10 +-10 +12 +-7 +9 +-13 +-8 +14 +-7 +11 +-9 +11 +-8 +11 +-9 +10 +-8 +11 +-8 +10 +-10 +12 +-9 +13 +-9 +11 +-9 +11 +-9 +12 +-10 +9 +-10 +11 +-10 +11 +-9 +9 +-9 +11 +-12 +10 +-11 +8 +-11 +9 +-11 +11 +-10 +11 +-10 +10 +-10 +11 +-10 +10 +-11 +10 +-10 +11 +-9 +11 +-9 +11 +-10 +10 +-11 +11 +-11 +11 +-11 +10 +-10 +9 +-11 +11 +-11 +10 +-9 +10 +-11 +10 +-10 +10 +-10 +11 +-10 +12 +-9 +10 +-9 +12 +-8 +10 +-8 +10 +-10 +12 +-10 +10 +-9 +12 +-10 +11 +-10 +10 +-9 +11 +-10 +11 +-9 +10 +-11 +10 +-10 +9 +-10 +11 +-10 +10 +-10 +11 +-10 +9 +-10 +10 +-10 +11 +-9 +11 +-9 +12 +-10 +10 +-9 +9 +-10 +12 +-11 +11 +-9 +11 +-10 +10 +-10 +10 +-9 +11 +-11 +11 +-10 +10 +-10 +9 +-11 +11 +-10 +12 +-10 +11 +-10 +10 +-10 +10 +-10 +10 +-11 +12 +-12 +10 +-11 +9 +-10 +10 +-10 +10 +-9 +9 +-10 +12 +-11 +11 +-9 +11 +-9 +12 +-11 +10 +-11 +10 +-10 +10 +-9 +10 +-10 +11 +-9 +11 +-9 +12 +-10 +11 +-11 +12 +-10 +12 +-9 +10 +-9 +12 +-11 +10 +-11 +10 +-10 +10 +-10 +8 +-10 +10 +-10 +10 +-9 +11 +-9 +11 +-9 +8 +-10 +11 +-11 +11 +-12 +10 +-11 +11 +-10 +10 +-9 +10 +-10 +12 +-10 +11 +-10 +10 +-11 +10 +-10 +12 +-10 +10 +-9 +11 +-10 +12 +-9 +10 +-10 +10 +-10 +9 +-9 +10 +-9 +11 +-10 +12 +-10 +11 +-9 +11 +-10 +11 +-11 +11 +-10 +9 +-10 +11 +-11 +9 +-10 +10 +-9 +10 +-10 +11 +-9 +9 +-9 +12 +-9 +10 +-10 +11 +-10 +10 +-9 +11 +-9 +11 +-10 +12 +-10 +11 +-10 +10 +-10 +11 +-9 +11 +-10 +12 +-10 +10 +-11 +10 +-10 +11 +-9 +10 +-10 +10 +-10 +10 +-8 +10 +-11 +10 +-10 +10 +-9 +10 +-10 +11 +-11 +11 +-10 +11 +-10 +11 +-10 +9 +-9 +10 +-10 +11 +-10 +10 +-10 +11 +-10 +9 +-10 +11 +-10 +9 +-10 +10 +-10 +9 +-10 +10 +-11 +10 +-11 +11 +-11 +10 +-10 +9 +-9 +10 +-11 +11 +-11 +10 +-10 +10 +-10 +10 +-9 +11 +-11 +12 +-10 +11 +-9 +11 +-10 +9 +-11 +11 +-10 +9 +-11 +12 +-10 +10 +-10 +10 +-11 +9 +-11 +12 +-10 +10 +-10 +9 +-10 +10 +-10 +13 +-10 +9 +-10 +12 +-11 +10 +-10 +10 +-10 +11 +-10 +11 +-9 +10 +-10 +12 +-10 +11 +-11 +9 +-11 +9 +-10 +10 +-10 +10 +-9 +10 +-10 +12 +-8 +12 +-10 +12 +-10 +11 +-10 +12 +-9 +12 +-10 +10 +-8 +10 +-10 +11 +-9 +11 +-9 +9 +-11 +12 +-11 +10 +-10 +9 +-11 +10 +-10 +10 +-10 +9 +-9 +11 +-10 +10 +-11 +10 +-10 +9 +-12 +11 +-10 +9 +-12 +11 +-10 +10 +-9 +11 +-11 +12 +-8 +10 +-9 +10 +-10 +11 +-11 +10 +-9 +9 +-10 +10 +-10 +10 +-10 +9 +-10 +11 +-10 +10 +-9 +12 +-10 +12 +-11 +12 +-10 +13 +-10 +9 +-9 +12 +-10 +10 +-10 +10 +-9 +11 +-10 +12 +-10 +10 +-12 +11 +-9 +11 +-8 +10 +-10 +12 +-10 +12 +-10 +11 +-9 +10 +-10 +11 +-11 +10 +-12 +9 +-8 +10 +-10 +10 +-10 +10 +-10 +10 +-11 +9 +-11 +10 +-11 +10 +-9 +10 +-11 +12 +-10 +12 +-9 +11 +-10 +11 +-11 +11 +-9 +10 +-10 +11 +-10 +9 +-10 +9 +-11 +11 +-12 +10 +-10 +10 +-9 +9 +-12 +9 +-11 +11 +-10 +9 +-11 +9 +-10 +11 +-11 +12 +-9 +12 +-10 +10 +-10 +10 +-10 +10 +-10 +11 +-9 +11 +-10 +11 +-9 +9 +-11 +11 +-10 +10 +-10 +12 +-9 +10 +-9 +11 +-9 +12 +-10 +9 +-9 +10 +-11 +11 +-10 +11 +-11 +10 +-10 +10 +-8 +9 +-9 +10 +-10 +11 +-10 +12 +-9 +10 +-10 +10 +-8 +11 +-10 +12 +-9 +11 +-9 +10 +-10 +10 +-11 +10 +-11 +9 +-10 +10 +-11 +11 +-11 +10 +-12 +10 +-10 +10 +-11 +10 +-10 +10 +-11 +10 +-11 +10 +-10 +9 +-12 +11 +-10 +10 +-9 +11 +-10 +11 +-9 +11 +-8 +11 +-10 +11 +-9 +11 +-10 +10 +-10 +10 +-9 +10 +-9 +9 +-10 +9 +-9 +9 +-10 +11 +-9 +12 +-9 +10 +-9 +13 +-11 +9 +-11 +10 +-10 +10 +-9 +10 +-10 +12 +-10 +11 +-10 +11 +-11 +10 +-10 +11 +-11 +12 +-10 +11 +-11 +12 +-9 +10 +-10 +10 +-11 +10 +-12 +10 +-10 +10 +-11 +9 +-11 +9 +-10 +9 +-10 +9 +-11 +9 +-11 +10 +-10 +10 +-11 +11 +-10 +11 +-8 +11 +-10 +12 +-9 +11 +-9 +13 +-9 +10 +-9 +11 +-8 +10 +-10 +10 +-10 +12 +-9 +9 +-11 +12 +-9 +10 +-10 +9 +-9 +11 +-11 +11 +-10 +10 +-9 +12 +-12 +10 +-11 +9 +-10 +11 +-11 +10 +-9 +10 +-10 +9 +-11 +10 +-10 +9 +-10 +10 +-10 +8 +-10 +11 +-9 +10 +-10 +11 +-9 +10 +-10 +10 +-10 +10 +-11 +9 +-11 +10 +-11 +11 +-12 +10 +-9 +11 +-10 +11 +-10 +11 +-9 +11 +-9 +9 +-9 +11 +-10 +11 +-9 +11 +-10 +11 +-10 +10 +-8 +10 +-10 +11 +-10 +11 +-10 +11 +-11 +11 +-9 +12 +-9 +10 +-10 +11 +-10 +11 +-9 +11 +-11 +11 +-10 +10 +-10 +10 +-11 +10 +-10 +9 +-10 +10 +-11 +12 +-10 +10 +-8 +10 +-9 +11 +-9 +10 +-10 +10 +-10 +9 +-10 +10 +-10 +9 +-11 +10 +-10 +14 +10 +-14 +10 +-11 +11 +-10 +10 +-10 +11 +-10 +11 +-10 +9 +-10 +10 +-10 +9 +-10 +9 +-11 +10 +-10 +11 +-11 +9 +-9 +10 +-10 +10 +-10 +10 +-10 +9 +-10 +10 +-10 +10 +-9 +9 +-9 +9 +-10 +10 +-9 +9 +-9 +10 +-11 +9 +-9 +8 +-10 +9 +-10 +10 +-10 +10 +-10 +10 +-10 +11 +-10 +10 +-9 +11 +-10 +10 +-10 +11 +-10 +9 +-8 +9 +-10 +10 +-10 +10 +-10 +9 +-9 +11 +-8 +9 +-9 +10 +-9 +9 +-9 +11 +-10 +9 +-9 +11 +-9 +10 +-13 +-8 +15 +-8 +11 +-9 +9 +-10 +9 +-9 +11 +-10 +11 +-9 +10 +-10 +12 +-9 +9 +-10 +9 +-10 +10 +-9 +10 +-11 +10 +-9 +11 +-9 +10 +-9 +11 +-9 +10 +-9 +11 +-8 +11 +-10 +13 +-9 +12 +-9 +10 +-9 +12 +-9 +10 +-10 +12 +-10 +11 +-8 +11 +-9 +9 +-10 +10 +-9 +10 +-10 +12 +-11 +10 +-10 +9 +-11 +10 +-9 +8 +-12 +11 +-11 +9 +-11 +9 +-11 +10 +-11 +9 +-11 +9 +-10 +9 +-11 +8 +-10 +10 +-10 +10 +-9 +10 +-10 +10 +-10 +15 +10 +-15 +12 +-11 +11 +-9 +11 +-10 +9 +-9 +10 +-8 +10 +-9 +11 +-10 +9 +-9 +8 +-11 +9 +-9 +7 +-11 +10 +-10 +10 +-10 +9 +-8 +9 +-10 +10 +-9 +11 +-10 +9 +-11 +9 +-9 +8 +-10 +10 +-9 +10 +-10 +10 +-8 +11 +-10 +9 +-8 +8 +-10 +11 +-9 +11 +-10 +9 +-10 +10 +-10 +8 +-13 +-8 +13 +-8 +10 +-9 +9 +-9 +11 +-9 +10 +-9 +11 +-9 +11 +-9 +10 +-9 +11 +-9 +11 +-9 +11 +-9 +11 +-9 +10 +-9 +10 +-9 +9 +-11 +11 +-9 +11 +-9 +10 +-9 +11 +-10 +9 +-9 +10 +-8 +12 +-10 +10 +-10 +11 +-9 +9 +-11 +11 +-9 +9 +-11 +10 +-11 +10 +-10 +9 +-11 +10 +-11 +12 +-10 +10 +-11 +11 +-10 +11 +-9 +9 +-11 +10 +-10 +10 +-11 +9 +-10 +11 +-10 +10 +-11 +11 +-10 +10 +-11 +11 +-11 +9 +-11 +10 +-10 +10 +-10 +10 +-11 +10 +-11 +11 +-10 +11 +-9 +11 +-9 +10 +-9 +12 +-10 +12 +-9 +13 +-9 +10 +-10 +12 +-9 +12 +-9 +11 +-9 +11 +-9 +11 +-11 +11 +-10 +14 +9 +-16 +11 +-12 +9 +-10 +9 +-10 +8 +-10 +10 +-12 +9 +-10 +9 +-10 +9 +-10 +11 +-11 +10 +-11 +10 +-10 +10 +-10 +9 +-9 +10 +-11 +10 +-13 +-8 +13 +-10 +11 +-10 +11 +-10 +11 +-9 +12 +-8 +11 +-9 +12 +-8 +9 +-9 +12 +-8 +10 +-10 +12 +-9 +10 +-9 +9 +-9 +9 +-11 +11 +-9 +10 +-11 +11 +-10 +10 +-10 +10 +-10 +10 +-11 +11 +-10 +10 +-10 +11 +-8 +11 +-9 +10 +-9 +10 +-9 +9 +-9 +11 +-10 +10 +-11 +10 +-11 +11 +-11 +10 +-12 +9 +-10 +11 +-11 +10 +-10 +8 +-9 +11 +-10 +10 +-9 +11 +-9 +12 +-9 +11 +-9 +11 +-10 +11 +-11 +12 +-9 +11 +-9 +11 +-10 +11 +-10 +14 +10 +-15 +10 +-11 +11 +-11 +9 +-10 +10 +-11 +9 +-10 +9 +-12 +9 +-10 +9 +-9 +10 +-10 +9 +-11 +10 +-10 +11 +-10 +9 +-9 +9 +-9 +10 +-9 +10 +-10 +9 +-9 +10 +-10 +10 +-10 +10 +-10 +9 +-11 +11 +-10 +10 +-11 +9 +-9 +11 +-9 +11 +-9 +10 +-9 +10 +-9 +9 +-10 +9 +-10 +11 +-13 +-9 +14 +-8 +11 +-10 +11 +-10 +10 +-10 +11 +-10 +10 +-9 +12 +-9 +10 +-9 +11 +-11 +12 +-9 +11 +-9 +11 +-8 +11 +-9 +12 +-9 +11 +-8 +12 +-9 +11 +-9 +9 +-10 +9 +-9 +9 +-9 +10 +-11 +12 +-11 +11 +-9 +11 +-10 +10 +-11 +11 +-11 +11 +-10 +9 +-11 +11 +-10 +11 +-10 +10 +-10 +8 +-11 +13 +-9 +11 +-11 +10 +-10 +10 +-10 +9 +-9 +10 +-11 +10 +-10 +10 +-9 +11 +-10 +10 +-11 +10 +-9 +12 +-9 +10 +-10 +11 +-10 +12 +-10 +10 +-10 +12 +-9 +10 +-10 +10 +-11 +11 +-11 +11 +-9 +9 +-9 +11 +-10 +11 +-10 +12 +-9 +10 +-11 +10 +-10 +8 +-11 +11 +-10 +9 +-9 +10 +-11 +11 +-9 +11 +-10 +10 +-9 +9 +-10 +11 +-10 +10 +-9 +11 +-10 +11 +-9 +13 +-8 +12 +-10 +11 +-8 +10 +-10 +10 +-10 +10 +-10 +10 +-9 +11 +-10 +9 +-10 +9 +-11 +12 +-12 +9 +-11 +12 +-10 +10 +-11 +11 +-10 +10 +-10 +10 +-9 +11 +-10 +9 +-9 +11 +-10 +11 +-9 +10 +-9 +12 +-10 +11 +-9 +14 +10 +-15 +11 +-11 +9 +-10 +10 +-13 +9 +-10 +8 +-10 +9 +-12 +10 +-11 +10 +-10 +10 +-9 +10 +-9 +10 +-9 +9 +-10 +10 +-11 +9 +-11 +10 +-9 +9 +-9 +8 +-10 +10 +-10 +9 +-10 +8 +-9 +8 +-9 +9 +-11 +10 +-9 +9 +-9 +10 +-10 +10 +-9 +9 +-9 +11 +-8 +11 +-8 +11 +-8 +12 +-11 +-7 +15 +-8 +11 +-10 +12 +-8 +10 +-9 +12 +-9 +11 +-8 +10 +-9 +12 +-9 +11 +-9 +9 +-10 +10 +-10 +10 +-11 +10 +-9 +10 +-11 +9 +-9 +11 +-11 +10 +-9 +10 +-10 +10 +-11 +11 +-10 +11 +-11 +12 +-12 +10 +-10 +10 +-12 +12 +-12 +10 +-10 +9 +-10 +9 +-10 +11 +-11 +10 +-9 +11 +-9 +11 +-9 +12 +-9 +10 +-9 +13 +-10 +11 +-9 +10 +-10 +11 +-8 +11 +-9 +11 +-10 +11 +-9 +11 +-10 +13 +-11 +11 +-10 +11 +-10 +9 +-11 +9 +-10 +11 +-11 +10 +-10 +10 +-9 +10 +-11 +11 +-10 +11 +-9 +12 +-9 +10 +-10 +11 +-10 +10 +-9 +9 +-9 +10 +-10 +12 +-10 +11 +-11 +10 +-12 +9 +-11 +11 +-10 +9 +-11 +10 +-9 +11 +-10 +12 +-10 +11 +-10 +10 +-10 +10 +-10 +11 +-9 +11 +-11 +11 +-10 +10 +-10 +11 +-10 +12 +-11 +11 +-9 +10 +-9 +14 +10 +-16 +10 +-10 +9 +-11 +9 +-11 +9 +-11 +10 +-10 +9 +-9 +8 +-10 +11 +-10 +10 +-10 +10 +-10 +11 +-9 +10 +-9 +10 +-9 +12 +-10 +9 +-9 +9 +-9 +10 +-10 +10 +-9 +11 +-10 +9 +-10 +11 +-9 +10 +-10 +10 +-9 +10 +-9 +9 +-9 +9 +-9 +10 +-9 +9 +-10 +10 +-9 +10 +-8 +11 +-11 +-8 +14 +-8 +12 +-10 +12 +-9 +11 +-9 +11 +-9 +10 +-10 +11 +-9 +11 +-10 +10 +-9 +9 +-11 +10 +-11 +10 +-8 +7 +-10 +11 +-9 +11 +-8 +13 +10 +-15 +10 +-11 +9 +-11 +9 +-11 +9 +-10 +8 +-10 +11 +-11 +10 +-10 +10 +-9 +9 +-10 +9 +-10 +9 +-10 +10 +-10 +9 +-9 +10 +-10 +9 +-13 +-9 +13 +-8 +11 +-10 +11 +-9 +11 +-8 +10 +-9 +12 +-8 +11 +-9 +11 +-10 +11 +-10 +12 +-10 +9 +-10 +11 +-10 +9 +-10 +10 +-8 +9 +-11 +12 +-10 +10 +-9 +11 +-8 +10 +-10 +12 +-10 +11 +-10 +10 +-10 +10 +-10 +10 +-9 +9 +-9 +11 +-9 +10 +-9 +10 +-9 +11 +-11 +12 +-9 +10 +-10 +12 +-9 +9 +-11 +12 +-10 +11 +-9 +10 +-9 +12 +-9 +12 +-9 +11 +-9 +12 +-9 +10 +-8 +11 +-10 +12 +-11 +10 +-11 +10 +-10 +9 +-8 +9 +-10 +10 +-11 +11 +-11 +9 +-10 +12 +-10 +10 +-12 +11 +-11 +10 +-9 +9 +-9 +9 +-11 +9 +-9 +11 +-10 +9 +-10 +10 +-11 +10 +-11 +10 +-11 +11 +-11 +11 +-10 +10 +-10 +10 +-9 +11 +-10 +10 +-9 +11 +-11 +11 +-10 +9 +-11 +9 +-12 +10 +-11 +12 +-12 +11 +-9 +11 +-10 +10 +-10 +10 +-10 +10 +-11 +12 +-10 +11 +-10 +11 +-10 +11 +-10 +10 +-11 +11 +-10 +10 +-9 +11 +-9 +11 +-9 +11 +-10 +11 +-10 +10 +-9 +11 +-10 +10 +-11 +11 +-10 +11 +-9 +11 +-10 +11 +-10 +10 +-9 +10 +-11 +11 +-11 +10 +-9 +10 +-11 +11 +-9 +10 +-9 +11 +-11 +10 +-10 +10 +-10 +10 +-11 +11 +-11 +9 +-11 +9 +-12 +11 +-11 +11 +-12 +9 +-9 +9 +-10 +9 +-10 +9 +-12 +10 +-11 +11 +-11 +11 +-11 +11 +-10 +9 +-9 +12 +-10 +10 +-10 +11 +-10 +10 +-11 +12 +-11 +10 +-10 +13 +-11 +10 +-10 +10 +-10 +11 +-10 +12 +-10 +11 +-9 +9 +-11 +10 +-10 +10 +-11 +12 +-10 +12 +-10 +12 +-9 +9 +-11 +12 +-10 +11 +-10 +11 +-11 +11 +-8 +9 +-8 +11 +-10 +10 +-10 +11 +-10 +12 +-10 +11 +-10 +10 +-11 +11 +-10 +8 +-10 +10 +-11 +10 +-11 +9 +-10 +9 +-11 +10 +-10 +9 +-9 +10 +-12 +11 +-10 +10 +-10 +10 +-10 +12 +-11 +10 +-9 +8 +-11 +12 +-8 +11 +-9 +10 +-10 +12 +-9 +10 +-10 +11 +-10 +11 +-10 +10 +-10 +10 +-10 +11 +-9 +12 +-10 +12 +-10 +12 +-8 +11 +-9 +11 +-9 +11 +-10 +11 +-10 +11 +-9 +8 +-10 +10 +-10 +11 +-11 +11 +-10 +9 +-10 +11 +-9 +10 +-11 +9 +-10 +10 +-11 +10 +-10 +11 +-10 +10 +-11 +10 +-10 +10 +-10 +10 +-9 +11 +-9 +11 +-9 +11 +-11 +11 +-9 +9 +-10 +11 +-12 +9 +-11 +10 +-9 +10 +-11 +9 +-10 +12 +-11 +11 +-10 +10 +-11 +12 +-11 +11 +-10 +10 +-10 +11 +-8 +9 +-9 +11 +-11 +11 +-10 +10 +-11 +9 +-10 +11 +-10 +12 +-9 +10 +-10 +12 +-10 +9 +-9 +10 +-8 +13 +-11 +12 +-10 +10 +-9 +11 +-10 +11 +-10 +10 +-10 +10 +-10 +9 +-11 +10 +-11 +10 +-11 +10 +-9 +9 +-10 +12 +-9 +10 +-10 +11 +-11 +11 +-9 +11 +-8 +11 +-10 +11 +-10 +11 +-9 +12 +-10 +12 +-9 +12 +-10 +11 +-10 +11 +-11 +10 +-8 +11 +-11 +9 +-10 +9 +-11 +11 +-10 +10 +-9 +11 +-11 +11 +-10 +10 +-10 +11 +-12 +11 +-10 +11 +-9 +11 +-10 +11 +-10 +11 +-10 +10 +-11 +10 +-11 +11 +-11 +10 +-10 +10 +-11 +13 +-12 +13 +-9 +9 +-8 +10 +-9 +13 +-11 +11 +-10 +13 +-11 +11 +-9 +10 +-10 +11 +-11 +8 +-10 +10 +-10 +9 +-11 +11 +-12 +10 +-11 +9 +-11 +10 +-11 +10 +-10 +9 +-11 +11 +-11 +11 +-10 +10 +-8 +11 +-10 +12 +-9 +10 +-11 +10 +-11 +10 +-11 +9 +-9 +9 +-11 +12 +-9 +10 +-9 +10 +-9 +12 +-8 +9 +-9 +10 +-10 +11 +-11 +10 +-10 +10 +-10 +10 +-12 +10 +-10 +10 +-10 +11 +-10 +10 +-10 +10 +-12 +12 +-10 +10 +-10 +11 +-9 +10 +-11 +12 +-10 +10 +-10 +12 +-9 +11 +-9 +9 +-11 +12 +-11 +11 +-10 +9 +-10 +10 +-11 +11 +-10 +9 +-9 +12 +-11 +11 +-10 +10 +-10 +11 +-11 +9 +-9 +9 +-10 +11 +-9 +12 +-9 +12 +-10 +10 +-11 +10 +-10 +10 +-10 +9 +-9 +11 +-11 +11 +-11 +11 +-11 +9 +-10 +11 +-9 +10 +-10 +10 +-10 +9 +-11 +11 +-10 +10 +-10 +12 +-11 +12 +-10 +10 +-10 +10 +-10 +9 +-9 +10 +-10 +11 +-9 +13 +-10 +12 +-11 +10 +-11 +10 +-9 +10 +-11 +10 +-10 +10 +-11 +12 +-10 +9 +-8 +12 +-9 +12 +-10 +12 +-9 +11 +-9 +10 +-10 +11 +-10 +12 +-10 +9 +-9 +11 +-9 +10 +-10 +11 +-9 +11 +-10 +12 +-9 +10 +-9 +10 +-9 +12 +-11 +12 +-10 +9 +-11 +10 +-10 +12 +-11 +11 +-11 +12 +-8 +8 +-10 +11 +-9 +10 +-12 +11 +-10 +9 +-11 +10 +-11 +9 +-9 +10 +-11 +10 +-11 +10 +-12 +10 +-11 +11 +-11 +9 +-11 +10 +-11 +9 +-9 +10 +-10 +10 +-11 +10 +-10 +10 +-10 +9 +-11 +10 +-11 +10 +-10 +10 +-10 +9 +-10 +11 +-11 +10 +-9 +12 +-9 +9 +-11 +12 +-9 +11 +-11 +12 +-11 +9 +-10 +10 +-9 +12 +-11 +11 +-10 +11 +-9 +9 +-9 +10 +-11 +10 +-10 +10 +-9 +10 +-10 +10 +-10 +11 +-9 +11 +-11 +10 +-10 +11 +-10 +12 +-11 +11 +-10 +11 +-11 +12 +-10 +9 +-10 +12 +-10 +11 +-10 +11 +-10 +11 +-11 +11 +-9 +9 +-11 +11 +-10 +12 +-9 +11 +-10 +11 +-9 +9 +-10 +12 +-10 +10 +-10 +11 +-9 +9 +-10 +11 +-9 +10 +-8 +11 +-10 +10 +-11 +13 +10 +-17 +10 +-12 +11 +-11 +9 +-10 +8 +-10 +9 +-10 +10 +-10 +10 +-10 +11 +-10 +9 +-11 +12 +-10 +9 +-10 +11 +-9 +9 +-9 +10 +-8 +9 +-10 +10 +-9 +10 +-10 +9 +-10 +9 +-10 +9 +-9 +10 +-10 +9 +-8 +8 +-10 +9 +-12 +10 +-9 +10 +-10 +10 +-9 +9 +-9 +9 +-9 +9 +-10 +10 +-9 +10 +-9 +9 +-10 +10 +-10 +9 +-9 +8 +-10 +10 +-11 +10 +-9 +10 +-9 +11 +-8 +10 +-9 +9 +-9 +12 +-8 +10 +-10 +9 +-9 +10 +-9 +10 +-12 +-9 +13 +-9 +12 +-10 +11 +-8 +9 +-10 +10 +-9 +9 +-8 +11 +-9 +13 +-11 +11 +-9 +13 +-9 +10 +-8 +10 +-9 +10 +-8 +10 +-9 +10 +-10 +11 +-11 +11 +-9 +10 +-9 +11 +-10 +11 +-10 +10 +-9 +10 +-11 +11 +-11 +10 +-10 +10 +-11 +10 +-10 +10 +-9 +10 +-10 +11 +-10 +11 +-9 +12 +-9 +11 +-10 +11 +-9 +11 +-9 +12 +-10 +9 +-8 +10 +-10 +11 +-12 +11 +-10 +10 +-12 +10 +-10 +12 +-10 +11 +-11 +10 +-10 +12 +-9 +12 +-10 +10 +-9 +14 +11 +-15 +10 +-12 +11 +-11 +9 +-12 +10 +-11 +10 +-12 +8 +-11 +9 +-10 +10 +-10 +10 +-10 +9 +-10 +9 +-10 +8 +-9 +10 +-10 +11 +-9 +8 +-11 +12 +-10 +11 +-10 +11 +-9 +12 +-9 +10 +-9 +11 +-8 +11 +-9 +10 +-9 +9 +-10 +10 +-8 +10 +-11 +10 +-10 +8 +-10 +9 +-10 +8 +-10 +8 +-14 +-7 +10 +-8 +10 +-10 +10 +-10 +11 +-10 +9 +-10 +10 +-9 +10 +-8 +11 +-9 +10 +-10 +10 +-9 +10 +-10 +12 +-8 +11 +-9 +11 +-7 +11 +-9 +10 +-9 +10 +-10 +11 +-10 +9 +-10 +12 +-11 +10 +-9 +10 +-10 +11 +-9 +10 +-9 +9 +-9 +11 +-9 +11 +-10 +10 +-8 +9 +-9 +11 +-10 +11 +-10 +12 +-10 +9 +-10 +9 +-11 +10 +-10 +10 +-9 +10 +-9 +10 +-10 +10 +-11 +12 +-10 +11 +-9 +9 +-9 +11 +-9 +11 +-9 +11 +-10 +12 +-9 +11 +-10 +10 +-11 +10 +-11 +12 +-10 +11 +-10 +10 +-8 +11 +-10 +12 +-10 +11 +-9 +9 +-11 +11 +-11 +10 +-9 +11 +-10 +11 +-9 +11 +-10 +11 +-11 +10 +-12 +13 +10 +-16 +9 +-11 +9 +-10 +10 +-12 +9 +-12 +9 +-11 +9 +-11 +9 +-10 +9 +-12 +10 +-10 +11 +-10 +10 +-10 +10 +-10 +10 +-10 +11 +-9 +9 +-12 +-8 +12 +-8 +12 +-10 +10 +-9 +10 +-10 +10 +-10 +10 +-10 +10 +-10 +10 +-10 +11 +-10 +11 +-8 +11 +-10 +10 +-9 +11 +-9 +12 +-9 +10 +-9 +10 +-10 +11 +-9 +10 +-9 +11 +-10 +9 +-12 +10 +-10 +10 +-11 +10 +-11 +11 +-11 +11 +-10 +12 +-10 +11 +-12 +9 +-11 +11 +-10 +10 +-9 +11 +-10 +13 +-9 +11 +-10 +10 +-10 +12 +-11 +12 +-10 +11 +-10 +11 +-8 +11 +-9 +12 +-10 +12 +-10 +11 +-10 +10 +-9 +10 +-9 +11 +-11 +9 +-10 +10 +-11 +15 +9 +-16 +12 +-9 +9 +-10 +9 +-10 +10 +-10 +10 +-11 +9 +-10 +8 +-11 +10 +-10 +9 +-10 +10 +-9 +8 +-9 +9 +-10 +10 +-10 +11 +-9 +8 +-9 +10 +-9 +9 +-10 +10 +-10 +10 +-10 +9 +-8 +9 +-8 +10 +-9 +10 +-9 +10 +-9 +11 +-12 +9 +-10 +10 +-8 +8 +-9 +10 +-10 +11 +-9 +9 +-12 +-10 +13 +-8 +11 +-9 +11 +-9 +11 +-9 +11 +-9 +10 +-9 +11 +-11 +9 +-9 +10 +-9 +12 +-12 +12 +-9 +11 +-10 +9 +-8 +11 +-9 +11 +-10 +10 +-9 +11 +-9 +8 +-11 +10 +-10 +11 +-9 +10 +-10 +12 +-10 +10 +-9 +10 +-9 +10 +-11 +9 +-10 +9 +-11 +11 +-10 +11 +-11 +11 +-10 +8 +-9 +11 +-8 +12 +-10 +11 +-8 +10 +-10 +9 +-11 +10 +-9 +11 +-11 +12 +-10 +12 +-9 +10 +-9 +12 +-9 +11 +-10 +12 +-10 +9 +-10 +13 +-10 +10 +-12 +11 +-10 +10 +-10 +10 +-10 +11 +-11 +10 +-10 +11 +-9 +9 +-12 +11 +-11 +10 +-10 +10 +-11 +12 +-10 +10 +-7 +12 +-10 +11 +-8 +10 +-12 +11 +-9 +9 +-10 +10 +-10 +9 +-11 +10 +-10 +9 +-10 +10 +-11 +11 +-11 +11 +-11 +10 +-10 +9 +-10 +10 +-11 +11 +-10 +12 +-8 +8 +-10 +9 +-11 +10 +-10 +10 +-11 +10 +-10 +11 +-8 +11 +-10 +12 +-11 +11 +-9 +11 +-8 +8 +-11 +13 +-10 +13 +-8 +10 +-11 +11 +-9 +10 +-10 +11 +-10 +10 +-11 +11 +-9 +13 +10 +-15 +10 +-11 +10 +-11 +9 +-11 +9 +-10 +9 +-9 +8 +-12 +9 +-11 +9 +-10 +9 +-10 +8 +-9 +9 +-10 +11 +-9 +9 +-7 +9 +-10 +11 +-9 +10 +-9 +11 +-10 +10 +-7 +10 +-10 +11 +-8 +10 +-10 +11 +-9 +11 +-11 +10 +-9 +10 +-9 +10 +-9 +8 +-12 +9 +-11 +10 +-11 +10 +-11 +9 +-11 +-8 +13 +-8 +10 +-9 +11 +-10 +11 +-9 +11 +-10 +11 +-9 +10 +-9 +11 +-9 +11 +-12 +12 +-10 +11 +-9 +10 +-12 +10 +-10 +11 +-10 +9 +-12 +11 +-10 +10 +-9 +10 +-10 +10 +-9 +10 +-10 +11 +-10 +10 +-10 +12 +-10 +11 +-8 +10 +-9 +10 +-8 +11 +-11 +10 +-8 +10 +-10 +10 +-11 +10 +-10 +9 +-11 +12 +-10 +10 +-10 +13 +-7 +10 +-10 +10 +-9 +10 +-10 +11 +-11 +10 +-10 +11 +-10 +11 +-10 +10 +-9 +10 +-10 +12 +-10 +12 +-10 +12 +-9 +10 +-10 +11 +-10 +10 +-11 +10 +-10 +10 +-10 +11 +-10 +11 +-10 +11 +-10 +13 +-10 +12 +-9 +11 +-9 +11 +-11 +10 +-10 +10 +-9 +9 +-10 +11 +-9 +10 +-11 +11 +-10 +9 +-10 +10 +-10 +11 +-10 +12 +-10 +9 +-10 +12 +-10 +11 +-10 +10 +-10 +10 +-10 +10 +-9 +10 +-8 +11 +-11 +12 +-11 +10 +-9 +13 +9 +-14 +10 +-11 +10 +-10 +11 +-11 +10 +-11 +9 +-10 +9 +-9 +9 +-11 +11 +-11 +10 +-11 +9 +-11 +9 +-9 +11 +-10 +9 +-11 +10 +-9 +10 +-9 +9 +-9 +12 +-9 +9 +-8 +10 +-9 +10 +-9 +9 +-10 +9 +-9 +11 +-10 +9 +-10 +10 +-9 +11 +-11 +10 +-9 +10 +-8 +9 +-10 +10 +-10 +10 +-13 +-9 +13 +-8 +10 +-8 +9 +-9 +9 +-8 +10 +-9 +10 +-9 +12 +-9 +10 +-8 +11 +-9 +10 +-10 +11 +-10 +10 +-9 +10 +-10 +10 +-10 +10 +-11 +14 +9 +-16 +11 +-9 +9 +-9 +10 +-9 +9 +-8 +8 +-9 +12 +-11 +11 +-9 +10 +-8 +9 +-9 +9 +-10 +10 +-9 +8 +-11 +11 +-10 +10 +-11 +10 +-13 +-8 +13 +-7 +10 +-10 +10 +-10 +9 +-10 +11 +-9 +7 +-10 +11 +-10 +10 +-10 +10 +-9 +10 +-10 +12 +-9 +10 +-10 +10 +-11 +11 +-10 +10 +-10 +11 +-9 +11 +-9 +10 +-10 +11 +-10 +11 +-9 +10 +-10 +10 +-9 +10 +-9 +10 +-10 +12 +-10 +9 +-10 +10 +-10 +8 +-9 +11 +-11 +11 +-10 +10 +-9 +11 +-10 +11 +-11 +12 +-11 +11 +-11 +10 +-10 +9 +-11 +9 +-10 +10 +-9 +9 +-10 +11 +-10 +11 +-9 +11 +-9 +11 +-10 +10 +-9 +12 +-11 +10 +-11 +11 +-8 +10 +-10 +10 +-11 +12 +-10 +12 +-9 +10 +-10 +11 +-10 +11 +-11 +11 +-10 +12 +-9 +9 +-10 +11 +-10 +13 +-9 +11 +-11 +10 +-10 +11 +-9 +9 +-11 +12 +-11 +11 +-10 +11 +-11 +10 +-11 +10 +-9 +9 +-10 +8 +-10 +11 +-10 +10 +-11 +11 +-9 +11 +-11 +10 +-10 +10 +-12 +11 +-11 +10 +-9 +10 +-9 +11 +-11 +10 +-10 +10 +-10 +12 +-10 +9 +-9 +11 +-9 +10 +-9 +10 +-9 +11 +-10 +12 +-10 +12 +-10 +11 +-9 +13 +-9 +9 +-10 +11 +-10 +12 +-11 +12 +-10 +10 +-9 +10 +-9 +11 +-12 +9 +-8 +10 +-9 +10 +-10 +9 +-10 +12 +-10 +11 +-10 +11 +-9 +11 +-10 +11 +-8 +12 +-10 +12 +-11 +11 +-10 +10 +-9 +9 +-11 +12 +-11 +10 +-11 +11 +-10 +11 +-11 +12 +-9 +10 +-11 +10 +-11 +10 +-11 +10 +-11 +11 +-11 +11 +-9 +11 +-11 +12 +-10 +11 +-9 +13 +-9 +11 +-10 +11 +-10 +12 +-10 +10 +-9 +10 +-12 +12 +-11 +12 +-9 +10 +-11 +11 +-10 +10 +-11 +10 +-10 +10 +-11 +9 +-10 +11 +-10 +9 +-12 +10 +-11 +12 +-10 +12 +-10 +10 +-9 +11 +-9 +11 +-12 +11 +-10 +10 +-9 +11 +-9 +11 +-10 +10 +-10 +10 +-9 +10 +-10 +10 +-9 +11 +-10 +11 +-10 +10 +-10 +8 +-10 +11 +-9 +8 +-11 +10 +-10 +11 +-10 +10 +-11 +10 +-11 +10 +-11 +10 +-11 +11 +-9 +12 +-11 +12 +-9 +11 +-10 +10 +-11 +11 +-10 +10 +-10 +11 +-9 +10 +-9 +10 +-9 +10 +-8 +10 +-10 +10 +-11 +12 +-9 +10 +-11 +11 +-10 +10 +-10 +11 +-9 +11 +-9 +8 +-10 +11 +-10 +10 +-10 +11 +-11 +11 +-11 +10 +-10 +10 +-10 +11 +-11 +9 +-11 +11 +-10 +12 +-8 +11 +-9 +11 +-9 +11 +-11 +10 +-10 +11 +-10 +10 +-9 +11 +-9 +10 +-10 +10 +-10 +11 +-10 +12 +-9 +10 +-9 +10 +-10 +11 +-9 +9 +-10 +10 +-9 +10 +-10 +11 +-10 +12 +-10 +10 +-10 +10 +-11 +11 From 150afebf28dc4c0ca4c8469a9c4fbced6d6eb8f7 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 12 Oct 2019 12:40:22 +0200 Subject: [PATCH 0964/1854] text --- traces/README.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/traces/README.txt b/traces/README.txt index 804f1a0ff..4cc42ba74 100644 --- a/traces/README.txt +++ b/traces/README.txt @@ -25,4 +25,6 @@ indala-504278295.pm3: PSK 26 bit indala AWID-15-259.pm3: AWID FSK RF/50 FC: 15 Card: 259 HID-weak-fob-11647.pm3: HID 32bit Prox Card#: 11647. very weak tag/read but just readable. visa2000.pm3: VISA2000 ASK/MAN RF/64, Card: 480518 -securakey-64169.pm3 Securakey Tag BitLen: 26, Card ID: 64169, FC: 0x35 \ No newline at end of file +securakey-64169.pm3 Securakey Tag BitLen: 26, Card ID: 64169, FC: 0x35 + +motorola_0437_00072.pm3 - Motorola Grey clamshell card, old. (RAW: A0000000E308C0C1) From 63711dd31237b79d24f3f7e4e33fe17765685d68 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 13 Oct 2019 00:31:21 +0200 Subject: [PATCH 0965/1854] =?UTF-8?q?fix=20gcc8=20failure,=20man=20sprintf?= =?UTF-8?q?:=20Some=20programs=20imprudently=20rely=20on=20code=20such=20a?= =?UTF-8?q?s=20the=20following=20sprintf(buf,=20"%s=20some=20further=20tex?= =?UTF-8?q?t",=20buf);=20to=20append=20text=20to=20buf.=20=20However,=20th?= =?UTF-8?q?e=20standards=20explicitly=20note=20that=20the=20results=20are?= =?UTF-8?q?=20undefined=20if=20source=20and=20destination=20buffers=20over?= =?UTF-8?q?lap=20=20when=20=20calling=20=20sprintf(),=20=20snprintf(),=20?= =?UTF-8?q?=20vsprintf(),=20=20and=20=20vs=E2=80=90=20nprintf().=20=20Depe?= =?UTF-8?q?nding=20on=20the=20version=20of=20gcc(1)=20used,=20and=20the=20?= =?UTF-8?q?compiler=20options=20employed,=20calls=20such=20as=20the=20abov?= =?UTF-8?q?e=20will=20not=20produce=20the=20expected=20results.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/cmdlft55xx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 2894faa46..ccabadeb4 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -2262,11 +2262,11 @@ static int CmdT55xxDump(const char *Cmd) { strcpy (preferredName,"lf-t55xx"); for (uint8_t i = 1; i <= 7; i++) { if ((cardmem[i].blockdata != 0x00) && (cardmem[i].blockdata != 0xFFFFFFFF)) - sprintf (preferredName,"%s-%08X",preferredName,cardmem[i].blockdata); + sprintf (preferredName + strlen(preferredName),"-%08X",cardmem[i].blockdata); else break; } - sprintf (preferredName,"%s-data",preferredName); + strcat (preferredName,"-data"); } // Swap endian so the files match the txt display From 5520bdc20f92ce580e0c398d8053e378196c5752 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 13 Oct 2019 00:48:12 +0200 Subject: [PATCH 0966/1854] make style: skip cov-int --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 318251892..783b5fa27 100644 --- a/Makefile +++ b/Makefile @@ -197,12 +197,12 @@ style: # Make sure astyle is installed @which astyle >/dev/null || ( echo "Please install 'astyle' package first" ; exit 1 ) # Remove spaces & tabs at EOL, add LF at EOF if needed on *.c, *.h, *.cpp. *.lua, *.py, *.pl, Makefile - find . \( -name "*.[ch]" -or \( -name "*.cpp" -and -not -name "*.moc.cpp" \) -or -name "*.lua" -or -name "*.py" -or -name "*.pl" -or -name "Makefile" -or -name "*.v" \) \ + find . \( -not -path "./cov-int/*" -and \( -name "*.[ch]" -or \( -name "*.cpp" -and -not -name "*.moc.cpp" \) -or -name "*.lua" -or -name "*.py" -or -name "*.pl" -or -name "Makefile" -or -name "*.v" \) \) \ -exec perl -pi -e 's/[ \t]+$$//' {} \; \ -exec sh -c "tail -c1 {} | xxd -p | tail -1 | grep -q -v 0a$$" \; \ -exec sh -c "echo >> {}" \; # Apply astyle on *.c, *.h, *.cpp - find . \( -name "*.[ch]" -or \( -name "*.cpp" -and -not -name "*.moc.cpp" \) \) -exec astyle --formatted --mode=c --suffix=none \ + find . \( -not -path "./cov-int/*" -and \( -name "*.[ch]" -or \( -name "*.cpp" -and -not -name "*.moc.cpp" \) \) \) -exec astyle --formatted --mode=c --suffix=none \ --indent=spaces=4 --indent-switches \ --keep-one-line-blocks --max-instatement-indent=60 \ --style=google --pad-oper --unpad-paren --pad-header \ From 395d0f9ebf7c5f7275e5423f802f35b501d50f2e Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 13 Oct 2019 00:48:26 +0200 Subject: [PATCH 0967/1854] make style --- armsrc/appmain.c | 4 +- armsrc/iso14443a.c | 2 +- armsrc/lfops.c | 6 +- armsrc/lfsampling.c | 4 +- armsrc/mifarecmd.c | 22 ++--- armsrc/mifaresim.c | 2 +- client/amiitool/amiibo.c | 2 +- client/cmdanalyse.c | 10 +- client/cmddata.c | 14 +-- client/cmdflashmem.c | 2 +- client/cmdhficlass.c | 2 +- client/cmdhfmf.c | 4 +- client/cmdhfmfhard.c | 4 +- client/cmdhw.c | 2 +- client/cmdlf.c | 25 ++--- client/cmdlfawid.c | 2 +- client/cmdlfcotag.c | 2 +- client/cmdlfem4x.c | 126 ++++++++++++------------ client/cmdlffdx.c | 6 +- client/cmdlfgallagher.c | 14 +-- client/cmdlfguard.c | 6 +- client/cmdlfhid.c | 16 +-- client/cmdlfindala.c | 4 +- client/cmdlfio.c | 2 +- client/cmdlfmotorola.c | 36 +++---- client/cmdlfnexwatch.c | 14 +-- client/cmdlfnoralsy.c | 5 +- client/cmdlfpac.c | 12 +-- client/cmdlfparadox.c | 12 +-- client/cmdlfsecurakey.c | 12 +-- client/cmdlft55xx.c | 184 +++++++++++++++++------------------ client/cmdlft55xx.h | 6 +- client/cmdlfverichip.c | 8 +- client/emv/emv_pki_priv.c | 2 +- client/mifare/mifarehost.c | 12 +-- client/proxmark3.c | 8 +- client/wiegand_formatutils.c | 2 +- common/lfdemod.c | 10 +- 38 files changed, 305 insertions(+), 301 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 4218d93a0..b524c4883 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -214,7 +214,7 @@ void MeasureAntennaTuning(void) { } FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - reply_ng(CMD_MEASURE_ANTENNA_TUNING, PM3_SUCCESS, (uint8_t*)&payload, sizeof(payload)); + reply_ng(CMD_MEASURE_ANTENNA_TUNING, PM3_SUCCESS, (uint8_t *)&payload, sizeof(payload)); LEDsoff(); } @@ -234,7 +234,7 @@ uint16_t MeasureAntennaTuningHfData(void) { // Measure LF in milliVolt uint32_t MeasureAntennaTuningLfData(void) { - return (MAX_ADC_LF_VOLTAGE * AvgAdc(ADC_CHAN_LF)) >> 10; + return (MAX_ADC_LF_VOLTAGE * AvgAdc(ADC_CHAN_LF)) >> 10; } void ReadMem(int addr) { diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 62433fa5f..db347cf13 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -3034,7 +3034,7 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) { memcpy(payload.nr, mf_nr_ar, sizeof(payload.nr)); memcpy(payload.ar, mf_nr_ar + 4, sizeof(payload.ar)); - reply_ng(CMD_HF_MIFARE_READER, return_status, (uint8_t*)&payload, sizeof(payload)); + reply_ng(CMD_HF_MIFARE_READER, return_status, (uint8_t *)&payload, sizeof(payload)); hf_field_off(); set_tracing(false); diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 377a20b45..042e5edbc 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -404,7 +404,7 @@ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint DbpString("[!] Warning periods cannot be less than 7us in bit bang mode"); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LED_D_OFF(); - reply_ng(CMD_LF_MOD_THEN_ACQ_RAW_ADC, PM3_EINVARG, NULL, 0); + reply_ng(CMD_LF_MOD_THEN_ACQ_RAW_ADC, PM3_EINVARG, NULL, 0); return; } @@ -1708,12 +1708,12 @@ void T55xxDangerousRawTest(uint8_t *data) { t55xx_test_block_t *c = (t55xx_test_block_t *)data; uint8_t start_wait = 4; - uint8_t bs[128/8]; + uint8_t bs[128 / 8]; memset(bs, 0x00, sizeof(bs)); uint8_t len = 0; if (c->bitlen == 0 || c->bitlen > 128 || c->time == 0) reply_ng(CMD_LF_T55XX_DANGERRAW, PM3_EINVARG, NULL, 0); - for (uint8_t i=0; ibitlen; i++) + for (uint8_t i = 0; i < c->bitlen; i++) len = T55xx_SetBits(bs, len, c->data[i], 1, sizeof(bs)); if (DBGLEVEL > 1) { diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index 08fb1dd94..d168dcc78 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -31,7 +31,7 @@ sample_config config = { 1, 8, 1, LF_DIVISOR_125, 0, 0, 1} ; void printConfig() { uint32_t d = config.divisor; DbpString(_BLUE_("LF Sampling config")); - Dbprintf(" [q] divisor.............%d ( "_GREEN_("%d.%02d kHz")")", d, 12000 / (d+1), ((1200000 + (d+1)/2) / (d+1)) - ((12000 / (d+1)) * 100)); + Dbprintf(" [q] divisor.............%d ( "_GREEN_("%d.%02d kHz")")", d, 12000 / (d + 1), ((1200000 + (d + 1) / 2) / (d + 1)) - ((12000 / (d + 1)) * 100)); Dbprintf(" [b] bps.................%d", config.bits_per_sample); Dbprintf(" [d] decimation..........%d", config.decimation); Dbprintf(" [a] averaging...........%s", (config.averaging) ? "Yes" : "No"); @@ -54,7 +54,7 @@ void setSamplingConfig(sample_config *sc) { if (sc->divisor != 0) config.divisor = sc->divisor; if (sc->bits_per_sample != 0) config.bits_per_sample = sc->bits_per_sample; if (sc->trigger_threshold != -1) config.trigger_threshold = sc->trigger_threshold; -// if (sc->samples_to_skip == 0xffffffff) // if needed to not update if not supplied +// if (sc->samples_to_skip == 0xffffffff) // if needed to not update if not supplied config.samples_to_skip = sc->samples_to_skip; config.decimation = (sc->decimation != 0) ? sc->decimation : 1; diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 3cc36b28c..b0b7c95ab 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -952,8 +952,8 @@ void MifareNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8 // cards with fixed nonce if (nt1 == nt2) { - Dbprintf("Nested: %08x vs %08x", nt1, nt2); - break; + Dbprintf("Nested: %08x vs %08x", nt1, nt2); + break; } uint32_t nttmp = prng_successor(nt1, 100); //NXP Mifare is typical around 840,but for some unlicensed/compatible mifare card this can be 160 @@ -1064,14 +1064,14 @@ void MifareNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8 crypto1_destroy(pcs); struct p { - int16_t isOK; - uint8_t block; - uint8_t keytype; - uint8_t cuid[4]; - uint8_t nt_a[4]; - uint8_t ks_a[4]; - uint8_t nt_b[4]; - uint8_t ks_b[4]; + int16_t isOK; + uint8_t block; + uint8_t keytype; + uint8_t cuid[4]; + uint8_t nt_a[4]; + uint8_t ks_a[4]; + uint8_t nt_b[4]; + uint8_t ks_b[4]; } PACKED payload; payload.isOK = isOK; payload.block = targetBlockNo; @@ -1084,7 +1084,7 @@ void MifareNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8 memcpy(payload.ks_b, &target_ks[1], 4); LED_B_ON(); - reply_ng(CMD_HF_MIFARE_NESTED, PM3_SUCCESS, (uint8_t*)&payload, sizeof(payload)); + reply_ng(CMD_HF_MIFARE_NESTED, PM3_SUCCESS, (uint8_t *)&payload, sizeof(payload)); LED_B_OFF(); if (DBGLEVEL >= 3) DbpString("NESTED FINISHED"); diff --git a/armsrc/mifaresim.c b/armsrc/mifaresim.c index 6c65a4f65..0f912c083 100644 --- a/armsrc/mifaresim.c +++ b/armsrc/mifaresim.c @@ -723,7 +723,7 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1 // iceman, u8 can never be larger than 256 // if authenticating to a block that shouldn't exist - as long as we are not doing the reader attack - if ( ((flags & FLAG_NR_AR_ATTACK) != FLAG_NR_AR_ATTACK) ) { + if (((flags & FLAG_NR_AR_ATTACK) != FLAG_NR_AR_ATTACK)) { EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA)); if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("Reader tried to operate (0x%02x) on out of range block: %d (0x%02x), nacking", receivedCmd_dec[0], receivedCmd_dec[1], receivedCmd_dec[1]); break; diff --git a/client/amiitool/amiibo.c b/client/amiitool/amiibo.c index 36b9ae967..809f611d3 100644 --- a/client/amiitool/amiibo.c +++ b/client/amiitool/amiibo.c @@ -145,7 +145,7 @@ bool nfc3d_amiibo_load_keys(nfc3d_amiibo_keys *amiiboKeys, const char *path) { } if ((amiiboKeys->data.magicBytesSize > 16) || - (amiiboKeys->tag.magicBytesSize > 16)) { + (amiiboKeys->tag.magicBytesSize > 16)) { return false; } diff --git a/client/cmdanalyse.c b/client/cmdanalyse.c index 6f3af2247..c4fe2d795 100644 --- a/client/cmdanalyse.c +++ b/client/cmdanalyse.c @@ -899,20 +899,20 @@ static int CmdAnalyseDemodBuffer(const char *Cmd) { int bg = 0, en = 0; if (param_getptr(Cmd, &bg, &en, 0)) - return usage_analyse_demodbuffer(); + return usage_analyse_demodbuffer(); - int len = MIN( (en- bg + 1), MAX_DEMOD_BUF_LEN); + int len = MIN((en - bg + 1), MAX_DEMOD_BUF_LEN); // add 1 for null terminator. uint8_t *data = calloc(len + 1, sizeof(uint8_t)); if (!data) return PM3_EMALLOC; - for(int i = 0; bg <= en; bg++ , i++) { + for (int i = 0; bg <= en; bg++, i++) { char c = Cmd[bg]; if (c == '1') - DemodBuffer[i] = 1; + DemodBuffer[i] = 1; if (c == '0') - DemodBuffer[i] = 0; + DemodBuffer[i] = 0; printf("%c", c); } diff --git a/client/cmddata.c b/client/cmddata.c index 4c8e0c45e..9bd18eb90 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -1174,7 +1174,7 @@ int FSKrawDemod(const char *Cmd, bool verbose) { PrintAndLogEx(DEBUG, "no FSK data found"); } -out: +out: free(bits); return PM3_SUCCESS; } @@ -1218,7 +1218,7 @@ int PSKDemod(const char *Cmd, bool verbose) { free(bits); return PM3_ESOFT; } - + int startIdx = 0; int errCnt = pskRawDemod_ext(bits, &bitlen, &clk, &invert, &startIdx); if (errCnt > maxErr) { @@ -1336,7 +1336,7 @@ int NRZrawDemod(const char *Cmd, bool verbose) { if (bits == NULL) { return PM3_EMALLOC; } - + size_t BitLen = getFromGraphBuf(bits); if (BitLen == 0) { @@ -1355,7 +1355,7 @@ int NRZrawDemod(const char *Cmd, bool verbose) { free(bits); return PM3_ESOFT; } - + if (verbose || g_debugMode) PrintAndLogEx(DEBUG, "DEBUG: (NRZrawDemod) Tried NRZ Demod using Clock: %d - invert: %d - Bits Found: %zu", clk, invert, BitLen); //prime demod buffer for output setDemodBuff(bits, BitLen, 0); @@ -1368,7 +1368,7 @@ int NRZrawDemod(const char *Cmd, bool verbose) { // Now output the bitstream to the scrollback by line of 16 bits printDemodBuff(); } - + free(bits); return PM3_SUCCESS; } @@ -1673,7 +1673,7 @@ int CmdTuneSamples(const char *Cmd) { uint8_t results[256]; } PACKED; - struct p* package = (struct p*)resp.data.asBytes; + struct p *package = (struct p *)resp.data.asBytes; if (package->v_lf125 > NON_VOLTAGE) PrintAndLogEx(SUCCESS, "LF antenna: %5.2f V - %.2f kHz", (package->v_lf125 * ANTENNA_ERROR) / 1000.0, 12000.0 / (LF_DIVISOR_125 + 1)); @@ -1730,7 +1730,7 @@ int CmdTuneSamples(const char *Cmd) { if (test1 > 0) { PrintAndLogEx(SUCCESS, "\nDisplaying LF tuning graph. Divisor %d is %.2f kHz, %d is %.2f kHz.\n\n", - LF_DIVISOR_134, 12000.0 / (LF_DIVISOR_134 + 1), LF_DIVISOR_125, 12000.0 / (LF_DIVISOR_125 + 1)); + LF_DIVISOR_134, 12000.0 / (LF_DIVISOR_134 + 1), LF_DIVISOR_125, 12000.0 / (LF_DIVISOR_125 + 1)); GraphTraceLen = 256; ShowGraphWindow(); RepaintGraphWindow(); diff --git a/client/cmdflashmem.c b/client/cmdflashmem.c index a313a418d..ab104276d 100644 --- a/client/cmdflashmem.c +++ b/client/cmdflashmem.c @@ -117,7 +117,7 @@ static int CmdFlashmemSpiBaudrate(const char *Cmd) { usage_flashmem_spibaud(); return PM3_EINVARG; } - SendCommandNG(CMD_FLASHMEM_SET_SPIBAUDRATE, (uint8_t*)&baudrate, sizeof(uint32_t)); + SendCommandNG(CMD_FLASHMEM_SET_SPIBAUDRATE, (uint8_t *)&baudrate, sizeof(uint32_t)); return PM3_SUCCESS; } diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 028e04a4c..67aa84396 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -1839,7 +1839,7 @@ static int CmdHFiClass_loclass(const char *Cmd) { int errors = testCipherUtils(); errors += testMAC(); errors += doKeyTests(0); - errors += testElite(opt2=='l'); + errors += testElite(opt2 == 'l'); if (errors) PrintAndLogEx(ERR, "There were errors!!!"); return PM3_ESOFT; } diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 87475926e..3ae332397 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -1866,7 +1866,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { } if (verbose) PrintAndLogEx(INFO, _YELLOW_("======================= STOP KNOWN KEY ATTACK =======================")); if (num_found_keys == sectors_cnt * 2) - goto all_found; + goto all_found; } bool load_success = true; @@ -2741,7 +2741,7 @@ static int CmdHF14AMfChk(const char *Cmd) { (keyBlock + 6 * keycnt)[3], (keyBlock + 6 * keycnt)[4], (keyBlock + 6 * keycnt)[5] - ); + ); } // initialize storage for found keys diff --git a/client/cmdhfmfhard.c b/client/cmdhfmfhard.c index bc3591d06..ab3e1a3d0 100644 --- a/client/cmdhfmfhard.c +++ b/client/cmdhfmfhard.c @@ -1654,8 +1654,8 @@ static uint_fast8_t reverse(uint_fast8_t b) { b = (b & 0xCC) >> 2 | (b & 0x33) << 2; b = (b & 0xAA) >> 1 | (b & 0x55) << 1; return b; -} -*/ +} +*/ static uint_fast8_t reverse(uint_fast8_t b) { return (b * 0x0202020202ULL & 0x010884422010ULL) % 1023; } diff --git a/client/cmdhw.c b/client/cmdhw.c index fa43e6200..5dddac5fc 100644 --- a/client/cmdhw.c +++ b/client/cmdhw.c @@ -695,7 +695,7 @@ void pm3_version(bool verbose, bool oneliner) { PrintAndLogEx(NORMAL, " compiled with " PM3CLIENTCOMPILER __VERSION__ PM3HOSTOS PM3HOSTARCH); //#if PLATFORM == PM3RDV4 - if ( IfPm3Flash() == false && IfPm3Smartcard() == false && IfPm3FpcUsartHost() == false) { + if (IfPm3Flash() == false && IfPm3Smartcard() == false && IfPm3FpcUsartHost() == false) { PrintAndLogEx(NORMAL, "\n [ PROXMARK3 ]"); } else { PrintAndLogEx(NORMAL, "\n [ PROXMARK3 RDV4 ]"); diff --git a/client/cmdlf.c b/client/cmdlf.c index e2f2a2153..57c28c1b0 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -337,13 +337,13 @@ int CmdLFCommandRead(const char *Cmd) { } } - // bitbang mode - if (payload.delay == 0){ - if (payload.zeros < 7 || payload.ones < 7) { - PrintAndLogEx(WARNING, "Warning periods cannot be less than 7us in bit bang mode"); - return PM3_EINVARG; - } - } + // bitbang mode + if (payload.delay == 0) { + if (payload.zeros < 7 || payload.ones < 7) { + PrintAndLogEx(WARNING, "Warning periods cannot be less than 7us in bit bang mode"); + return PM3_EINVARG; + } + } //Validations if (errors || cmdp == 0) return usage_lf_cmdread(); @@ -528,7 +528,7 @@ int CmdLFConfig(const char *Cmd) { break; case 's': samples_to_skip = param_get32ex(Cmd, cmdp + 1, 0, 10); - cmdp+=2; + cmdp += 2; break; default: PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); @@ -1202,16 +1202,19 @@ int CmdLFfind(const char *Cmd) { if (IfPm3Hitag()) { if (readHitagUid()) { - PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Hitag") "found!"); return PM3_SUCCESS; + PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Hitag") "found!"); + return PM3_SUCCESS; } } if (readMotorolaUid()) { - PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Motorola ID") "found!"); return PM3_SUCCESS; + PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Motorola ID") "found!"); + return PM3_SUCCESS; } if (readCOTAGUid()) { - PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("COTAG ID") "found!"); return PM3_SUCCESS; + PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("COTAG ID") "found!"); + return PM3_SUCCESS; } PrintAndLogEx(FAILED, _RED_("No data found!")); diff --git a/client/cmdlfawid.c b/client/cmdlfawid.c index 5084edf6a..afd2206f3 100644 --- a/client/cmdlfawid.c +++ b/client/cmdlfawid.c @@ -418,7 +418,7 @@ static int CmdAWIDClone(const char *Cmd) { blocks[3] = bytebits_to_byte(bits + 64, 32); free(bits); - + PrintAndLogEx(INFO, "Preparing to clone AWID %u to T55x7 with FC: %u, CN: %u", fmtlen, fc, cn); print_blocks(blocks, ARRAYLEN(blocks)); diff --git a/client/cmdlfcotag.c b/client/cmdlfcotag.c index dd7d5d648..b4e8e96c8 100644 --- a/client/cmdlfcotag.c +++ b/client/cmdlfcotag.c @@ -79,7 +79,7 @@ static int CmdCOTAGDemod(const char *Cmd) { // 2 = raw signal - maxlength bigbuff static int CmdCOTAGRead(const char *Cmd) { - if ( tolower(Cmd[0]) == 'h') return usage_lf_cotag_read(); + if (tolower(Cmd[0]) == 'h') return usage_lf_cotag_read(); uint32_t rawsignal = 1; sscanf(Cmd, "%u", &rawsignal); diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c index e1e9c75d8..5493b124d 100644 --- a/client/cmdlfem4x.c +++ b/client/cmdlfem4x.c @@ -720,7 +720,7 @@ static bool EM_ColParityTest(uint8_t *bs, size_t size, uint8_t rows, uint8_t col return true; } -// even parity ROW +// even parity ROW static bool EM_RowParityTest(uint8_t *bs, size_t size, uint8_t rows, uint8_t cols, uint8_t pType) { if (rows * cols > size) return false; uint8_t rowP = 0; @@ -844,14 +844,14 @@ int EM4x50Read(const char *Cmd, bool verbose) { size_t size = getFromGraphBuf(bits); if (size < 4000) { - if (verbose || g_debugMode) PrintAndLogEx(ERR, "Error: EM4x50 - Too little data in Graphbuffer"); - return PM3_ESOFT; + if (verbose || g_debugMode) PrintAndLogEx(ERR, "Error: EM4x50 - Too little data in Graphbuffer"); + return PM3_ESOFT; } computeSignalProperties(bits, size); // get fuzzed HI / LOW limits in signal - getHiLo( &high, &low, 75, 75); + getHiLo(&high, &low, 75, 75); // get to first full low to prime loop and skip incomplete first pulse size_t offset = 0; @@ -866,7 +866,7 @@ int EM4x50Read(const char *Cmd, bool verbose) { DetectASKClock(bits, size, &clk, 0); if (clk == 0) { if (verbose || g_debugMode) PrintAndLogEx(ERR, "Error: EM4x50 - didn't find a clock"); - return PM3_ESOFT; + return PM3_ESOFT; } } // tolerance @@ -1246,7 +1246,7 @@ static int EM4x05ReadWord_ext(uint8_t addr, uint32_t pwd, bool usePwd, uint32_t static int CmdEM4x05Demod(const char *Cmd) { // uint8_t ctmp = tolower(param_getchar(Cmd, 0)); - // if (ctmp == 'h') return usage_lf_em4x05_demod(); +// if (ctmp == 'h') return usage_lf_em4x05_demod(); uint32_t word = 0; return demodEM4x05resp(&word); } @@ -1263,22 +1263,23 @@ static int CmdEM4x05Dump(const char *Cmd) { while (param_getchar(Cmd, cmdp) != 0x00) { switch (tolower(param_getchar(Cmd, cmdp))) { - case 'h': return usage_lf_em4x05_dump(); - break; + case 'h': + return usage_lf_em4x05_dump(); + break; case 'f': // since f could match in password, lets confirm it is 1 character only for an option - param_getstr(Cmd, cmdp,optchk,sizeof(optchk)); - if (strlen (optchk) == 1) {// Have a single character f so filename no password - param_getstr(Cmd, cmdp + 1, preferredName, FILE_PATH_SIZE); - cmdp+=2; - break; - } // if not a single 'f' dont break and flow onto default as should be password + param_getstr(Cmd, cmdp, optchk, sizeof(optchk)); + if (strlen(optchk) == 1) { // Have a single character f so filename no password + param_getstr(Cmd, cmdp + 1, preferredName, FILE_PATH_SIZE); + cmdp += 2; + break; + } // if not a single 'f' dont break and flow onto default as should be password default : // for backwards-compatibility options should be > 'f' else assume its the hex password` - // for now use default input of 1 as invalid (unlikely 1 will be a valid password...) - pwd = param_get32ex(Cmd, cmdp, 1, 16); - if (pwd != 1) - usePwd = true; - cmdp++; + // for now use default input of 1 as invalid (unlikely 1 will be a valid password...) + pwd = param_get32ex(Cmd, cmdp, 1, 16); + if (pwd != 1) + usePwd = true; + cmdp++; }; } @@ -1313,7 +1314,7 @@ static int CmdEM4x05Dump(const char *Cmd) { if (usePwd) { data[addr] = BSWAP_32(pwd); num_to_bytes(pwd, 4, bytes); - PrintAndLogEx(NORMAL, " %02u | %08X | %s | %c | password", addr, pwd, sprint_ascii(bytes, 4),((lock_bits >> addr) & 1) ? 'x' : ' '); + PrintAndLogEx(NORMAL, " %02u | %08X | %s | %c | password", addr, pwd, sprint_ascii(bytes, 4), ((lock_bits >> addr) & 1) ? 'x' : ' '); } else { data[addr] = 0x00; // Unknown password, but not used to set to zeros PrintAndLogEx(NORMAL, " 02 | | | | " _RED_("cannot read")); @@ -1326,16 +1327,15 @@ static int CmdEM4x05Dump(const char *Cmd) { data[addr] = BSWAP_32(word); if (status == PM3_SUCCESS) { num_to_bytes(word, 4, bytes); - PrintAndLogEx(NORMAL, " %02d | %08X | %s | %c |", addr, word, sprint_ascii(bytes, 4),((lock_bits >> addr) & 1) ? 'x' : ' '); - } - else + PrintAndLogEx(NORMAL, " %02d | %08X | %s | %c |", addr, word, sprint_ascii(bytes, 4), ((lock_bits >> addr) & 1) ? 'x' : ' '); + } else PrintAndLogEx(NORMAL, " %02d | | | | " _RED_("Fail"), addr); } } - // Print blocks 14 and 15 + // Print blocks 14 and 15 // Both lock bits are protected with bit idx 14 (special case) - PrintAndLogEx(NORMAL, " %02d | %08X | %s | %c | Lock", 14, data[14], sprint_ascii(bytes, 4),((lock_bits >> 14) & 1) ? 'x' : ' '); - PrintAndLogEx(NORMAL, " %02d | %08X | %s | %c | Lock", 15, data[15], sprint_ascii(bytes, 4),((lock_bits >> 14) & 1) ? 'x' : ' '); + PrintAndLogEx(NORMAL, " %02d | %08X | %s | %c | Lock", 14, data[14], sprint_ascii(bytes, 4), ((lock_bits >> 14) & 1) ? 'x' : ' '); + PrintAndLogEx(NORMAL, " %02d | %08X | %s | %c | Lock", 15, data[15], sprint_ascii(bytes, 4), ((lock_bits >> 14) & 1) ? 'x' : ' '); // Update endian for files data[14] = BSWAP_32(data[14]); data[15] = BSWAP_32(data[15]); @@ -1343,13 +1343,13 @@ static int CmdEM4x05Dump(const char *Cmd) { if (success == PM3_SUCCESS) { // all ok save dump to file // saveFileEML will add .eml extension to filename // saveFile (binary) passes in the .bin extension. - if (strcmp (preferredName,"") == 0) // Set default filename, if not set by user - sprintf (preferredName,"lf-4x05-%08X-data",BSWAP_32(data[1])); + if (strcmp(preferredName, "") == 0) // Set default filename, if not set by user + sprintf(preferredName, "lf-4x05-%08X-data", BSWAP_32(data[1])); - saveFileEML(preferredName, (uint8_t *)data, 16*sizeof(uint32_t), sizeof(uint32_t)); - saveFile (preferredName, ".bin", data, sizeof(data)); + saveFileEML(preferredName, (uint8_t *)data, 16 * sizeof(uint32_t), sizeof(uint32_t)); + saveFile(preferredName, ".bin", data, sizeof(data)); } - + return success; } @@ -1443,7 +1443,7 @@ static int CmdEM4x05Wipe(const char *Cmd) { uint8_t addr = 0; uint32_t pwd = 0; uint8_t cmdp = 0; - uint8_t chipType = 1; // em4305 + uint8_t chipType = 1; // em4305 uint32_t chipInfo = 0x00040072; // Chip info/User Block normal 4305 Chip Type uint32_t chipUID = 0x614739AE; // UID normally readonly, but just in case uint32_t blockData = 0x00000000; // UserBlock/Password (set to 0x00000000 for a wiped card1 @@ -1454,60 +1454,60 @@ static int CmdEM4x05Wipe(const char *Cmd) { while (param_getchar(Cmd, cmdp) != 0x00) { // check if cmd is a 1 byte option - param_getstr(Cmd, cmdp,optchk,sizeof(optchk)); - if (strlen (optchk) == 1) {// Have a single character so option not part of password + param_getstr(Cmd, cmdp, optchk, sizeof(optchk)); + if (strlen(optchk) == 1) { // Have a single character so option not part of password switch (tolower(param_getchar(Cmd, cmdp))) { case 'c': // chip type - if (param_getchar(Cmd, cmdp) != 0x00) - chipType = param_get8ex (Cmd,cmdp+1,0,10); - cmdp+=2; - break; + if (param_getchar(Cmd, cmdp) != 0x00) + chipType = param_get8ex(Cmd, cmdp + 1, 0, 10); + cmdp += 2; + break; case 'h': // return usage_lf_em4x05_wipe(); default : // Unknown or 'h' send help - return usage_lf_em4x05_wipe(); - break; + return usage_lf_em4x05_wipe(); + break; }; - } else { // Not a single character so assume password + } else { // Not a single character so assume password pwd = param_get32ex(Cmd, cmdp, 1, 16); cmdp++; - } + } } switch (chipType) { case 0 : // em4205 - chipInfo = 0x00040070; - config = 0x0001805F; - break; + chipInfo = 0x00040070; + config = 0x0001805F; + break; case 1 : // em4305 - chipInfo = 0x00040072; - config = 0x0001805F; - break; + chipInfo = 0x00040072; + config = 0x0001805F; + break; default : // Type 0/Default : EM4305 - chipInfo = 0x00040072; - config = 0x0001805F; + chipInfo = 0x00040072; + config = 0x0001805F; } - + // block 0 : User Data or Chip Info - sprintf (cmdStr,"%d %08X %08X",0,chipInfo,pwd); - CmdEM4x05Write (cmdStr); + sprintf(cmdStr, "%d %08X %08X", 0, chipInfo, pwd); + CmdEM4x05Write(cmdStr); // block 1 : UID - this should be read only for EM4205 and EM4305 not sure about others - sprintf (cmdStr,"%d %08X %08X",1,chipUID,pwd); - CmdEM4x05Write (cmdStr); + sprintf(cmdStr, "%d %08X %08X", 1, chipUID, pwd); + CmdEM4x05Write(cmdStr); // block 2 : password - sprintf (cmdStr,"%d %08X %08X",2,blockData,pwd); - CmdEM4x05Write (cmdStr); + sprintf(cmdStr, "%d %08X %08X", 2, blockData, pwd); + CmdEM4x05Write(cmdStr); pwd = blockData; // Password should now have changed, so use new password // block 3 : user data - sprintf (cmdStr,"%d %08X %08X",3,blockData,pwd); - CmdEM4x05Write (cmdStr); + sprintf(cmdStr, "%d %08X %08X", 3, blockData, pwd); + CmdEM4x05Write(cmdStr); // block 4 : config - sprintf (cmdStr,"%d %08X %08X",4,config,pwd); - CmdEM4x05Write (cmdStr); + sprintf(cmdStr, "%d %08X %08X", 4, config, pwd); + CmdEM4x05Write(cmdStr); // Remainder of user/data blocks for (addr = 5; addr < 14; addr++) {// Clear user data blocks - sprintf (cmdStr,"%d %08X %08X",addr,blockData,pwd); - CmdEM4x05Write (cmdStr); + sprintf(cmdStr, "%d %08X %08X", addr, blockData, pwd); + CmdEM4x05Write(cmdStr); } return success; diff --git a/client/cmdlffdx.c b/client/cmdlffdx.c index ce78525ac..244c0caf3 100644 --- a/client/cmdlffdx.c +++ b/client/cmdlffdx.c @@ -264,7 +264,7 @@ static int CmdFdxRead(const char *Cmd) { static int CmdFdxClone(const char *Cmd) { uint32_t countryid = 0; - uint64_t animalid = 0; + uint64_t animalid = 0; char cmdp = param_getchar(Cmd, 0); if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_fdx_clone(); @@ -282,7 +282,7 @@ static int CmdFdxClone(const char *Cmd) { } uint32_t blocks[5] = {T55x7_MODULATION_DIPHASE | T55x7_BITRATE_RF_32 | 4 << T55x7_MAXBLOCK_SHIFT, 0, 0, 0, 0}; - + //Q5 if (param_getchar(Cmd, 2) == 'Q' || param_getchar(Cmd, 2) == 'q') blocks[0] = T5555_MODULATION_BIPHASE | T5555_INVERT_OUTPUT | T5555_SET_BITRATE(32) | 4 << T5555_MAXBLOCK_SHIFT; @@ -294,7 +294,7 @@ static int CmdFdxClone(const char *Cmd) { blocks[4] = bytebits_to_byte(bits + 96, 32); free(bits); - + PrintAndLogEx(INFO, "Preparing to clone FDX-B to T55x7 with animal ID: %04u-%"PRIu64, countryid, animalid); print_blocks(blocks, ARRAYLEN(blocks)); diff --git a/client/cmdlfgallagher.c b/client/cmdlfgallagher.c index 894e98ef8..d32c9ade9 100644 --- a/client/cmdlfgallagher.c +++ b/client/cmdlfgallagher.c @@ -97,11 +97,11 @@ static int CmdGallagherClone(const char *Cmd) { // skip first block, 3*4 = 12 bytes left uint8_t rawhex[12] = {0}; int res = param_gethex_to_eol(Cmd, cmdp + 1, rawhex, sizeof(rawhex), &datalen); - if ( res != 0 ) + if (res != 0) errors = true; - for(uint8_t i = 1; i < ARRAYLEN(blocks); i++) { - blocks[i] = bytes_to_num(rawhex + ( (i - 1) * 4 ), sizeof(uint32_t)); + for (uint8_t i = 1; i < ARRAYLEN(blocks); i++) { + blocks[i] = bytes_to_num(rawhex + ((i - 1) * 4), sizeof(uint32_t)); } cmdp += 2; break; @@ -157,10 +157,10 @@ int detectGallagher(uint8_t *dest, size_t *size) { if (*size < 96) return -1; //make sure buffer has data size_t startIdx = 0; uint8_t preamble[] = { - 0, 0, 0, 0, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 0, 1, - 0, 1, 0, 1, 0, 1, 0, 0, - 0, 1, 1, 0, 0 ,0 ,0 ,1 + 0, 0, 0, 0, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 0, + 0, 1, 1, 0, 0, 0, 0, 1 }; if (!preambleSearch(dest, preamble, sizeof(preamble), size, &startIdx)) return -2; //preamble not found diff --git a/client/cmdlfguard.c b/client/cmdlfguard.c index c65ff068a..a8cd8a65b 100644 --- a/client/cmdlfguard.c +++ b/client/cmdlfguard.c @@ -159,7 +159,7 @@ static int CmdGuardClone(const char *Cmd) { uint32_t facilitycode = 0, cardnumber = 0, fc = 0, cn = 0, fmtlen = 0; if (sscanf(Cmd, "%u %u %u", &fmtlen, &fc, &cn) != 3) return usage_lf_guard_clone(); - + fmtlen &= 0x7f; facilitycode = (fc & 0x000000FF); cardnumber = (cn & 0x0000FFFF); @@ -167,7 +167,7 @@ static int CmdGuardClone(const char *Cmd) { //GuardProxII - compat mode, ASK/Biphase, data rate 64, 3 data blocks uint32_t blocks[4] = {T55x7_MODULATION_BIPHASE | T55x7_BITRATE_RF_64 | 3 << T55x7_MAXBLOCK_SHIFT, 0, 0, 0}; uint8_t *bs = calloc(96, sizeof(uint8_t)); - + if (getGuardBits(fmtlen, facilitycode, cardnumber, bs) != PM3_SUCCESS) { PrintAndLogEx(ERR, "Error with tag bitstream generation."); free(bs); @@ -183,7 +183,7 @@ static int CmdGuardClone(const char *Cmd) { blocks[3] = bytebits_to_byte(bs + 64, 32); free(bs); - + PrintAndLogEx(INFO, "Preparing to clone Guardall to T55x7 with Facility Code: %u, Card Number: %u", facilitycode, cardnumber); print_blocks(blocks, ARRAYLEN(blocks)); diff --git a/client/cmdlfhid.c b/client/cmdlfhid.c index de7d9ecd5..004248e43 100644 --- a/client/cmdlfhid.c +++ b/client/cmdlfhid.c @@ -35,7 +35,7 @@ #include "cmdlf.h" // lf_read #include "util_posix.h" #include "lfdemod.h" -#include "wiegand_formats.h" +#include "wiegand_formats.h" #ifndef BITS # define BITS 96 @@ -133,12 +133,12 @@ static int sendTry(uint8_t format_idx, wiegand_card_t *card, uint32_t delay, boo clearCommandBuffer(); SendCommandNG(CMD_LF_HID_SIMULATE, (uint8_t *)&payload, sizeof(payload)); -/* - PacketResponseNG resp; - WaitForResponse(CMD_LF_HID_SIMULATE, &resp); - if (resp.status == PM3_EOPABORTED) - return resp.status; -*/ + /* + PacketResponseNG resp; + WaitForResponse(CMD_LF_HID_SIMULATE, &resp); + if (resp.status == PM3_EOPABORTED) + return resp.status; + */ msleep(delay); return sendPing(); } @@ -443,7 +443,7 @@ static int CmdHIDBrute(const char *Cmd) { if (data.CardNumber > 1) { data.CardNumber--; if (sendTry(format_idx, &data, delay, verbose) != PM3_SUCCESS) return PM3_ESOFT; - } + } } return PM3_SUCCESS; } diff --git a/client/cmdlfindala.c b/client/cmdlfindala.c index f455fae66..e57368400 100644 --- a/client/cmdlfindala.c +++ b/client/cmdlfindala.c @@ -164,7 +164,7 @@ static int CmdIndalaDemod(const char *Cmd) { csn |= DemodBuffer[50] << 1; // b2 csn |= DemodBuffer[41] << 0; // b1 - uint8_t checksum = 0; + uint8_t checksum = 0; checksum |= DemodBuffer[62] << 1; // b2 checksum |= DemodBuffer[63] << 0; // b1 @@ -172,7 +172,7 @@ static int CmdIndalaDemod(const char *Cmd) { PrintAndLogEx(SUCCESS, "Possible de-scramble patterns"); PrintAndLogEx(SUCCESS, "\tPrinted | __%04d__ [0x%X]", p1, p1); PrintAndLogEx(SUCCESS, "\tInternal ID | %" PRIu64, foo); - PrintAndLogEx(SUCCESS, "Fmt 26 bit FC %u , CSN %u , checksum %1d%1d", fc, csn, checksum >> 1 & 0x01, checksum & 0x01 ); + PrintAndLogEx(SUCCESS, "Fmt 26 bit FC %u , CSN %u , checksum %1d%1d", fc, csn, checksum >> 1 & 0x01, checksum & 0x01); } else { uint32_t uid3 = bytebits_to_byte(DemodBuffer + 64, 32); diff --git a/client/cmdlfio.c b/client/cmdlfio.c index dd3a78aa7..3aefd7b55 100644 --- a/client/cmdlfio.c +++ b/client/cmdlfio.c @@ -284,7 +284,7 @@ static command_t CommandTable[] = { {"read", CmdIOProxRead, IfPm3Lf, "attempt to read and extract tag data"}, {"clone", CmdIOProxClone, IfPm3Lf, "clone IOProx to T55x7"}, {"sim", CmdIOProxSim, IfPm3Lf, "simulate IOProx tag"}, - {"watch", CmdIOProxWatch, IfPm3Lf, "continuously watch for cards. Reader mode"}, + {"watch", CmdIOProxWatch, IfPm3Lf, "continuously watch for cards. Reader mode"}, {NULL, NULL, NULL, NULL} }; diff --git a/client/cmdlfmotorola.c b/client/cmdlfmotorola.c index 035eb7dc1..e306827ed 100644 --- a/client/cmdlfmotorola.c +++ b/client/cmdlfmotorola.c @@ -56,7 +56,7 @@ static int CmdMotorolaDemod(const char *Cmd) { //got a good demod uint32_t raw1 = bytebits_to_byte(DemodBuffer, 32); uint32_t raw2 = bytebits_to_byte(DemodBuffer + 32, 32); - + // A0000000E308C0C1 // 10100000000000000000000000000000 1110 0011 0000 1000 1100 0000 1100 0001 @@ -74,13 +74,13 @@ static int CmdMotorolaDemod(const char *Cmd) { uint16_t fc = 0; -// FC seems to be guess work. Need more samples +// FC seems to be guess work. Need more samples // guessing printed FC is 4 digits. 1024? 10bit? // fc |= DemodBuffer[38] << 9; // b10 fc |= DemodBuffer[34] << 8; // b9 fc |= DemodBuffer[44] << 7; // b8 - fc |= DemodBuffer[47] << 6; // b7 + fc |= DemodBuffer[47] << 6; // b7 fc |= DemodBuffer[57] << 5; // b6 fc |= DemodBuffer[49] << 4; // b5 @@ -89,7 +89,7 @@ static int CmdMotorolaDemod(const char *Cmd) { fc |= DemodBuffer[48] << 2; // b3 fc |= DemodBuffer[58] << 1; // b2 fc |= DemodBuffer[39] << 0; // b1 - + // CSN was same as Indala CSN descramble. uint16_t csn = 0; csn |= DemodBuffer[42] << 15; // b16 @@ -109,14 +109,14 @@ static int CmdMotorolaDemod(const char *Cmd) { csn |= DemodBuffer[50] << 1; // b2 csn |= DemodBuffer[41] << 0; // b1 - uint8_t checksum = 0; + uint8_t checksum = 0; checksum |= DemodBuffer[62] << 1; // b2 checksum |= DemodBuffer[63] << 0; // b1 PrintAndLogEx(SUCCESS, "Motorola Tag Found -- Raw: %08X%08X", raw1, raw2); - PrintAndLogEx(SUCCESS, "Fmt 26 bit FC %u , CSN %u , checksum %1d%1d", fc, csn, checksum >> 1 & 0x01, checksum & 0x01 ); + PrintAndLogEx(SUCCESS, "Fmt 26 bit FC %u , CSN %u , checksum %1d%1d", fc, csn, checksum >> 1 & 0x01, checksum & 0x01); PrintAndLogEx(NORMAL, ""); - + return PM3_SUCCESS; } @@ -124,13 +124,13 @@ static int CmdMotorolaRead(const char *Cmd) { // Motorola Flexpass seem to work at 74 kHz // and take about 4400 samples to befor modulating sample_config sc = { - .decimation = 0, - .bits_per_sample = 0, - .averaging= false, - .divisor = LF_DIVISOR(74), - .trigger_threshold = -1, - .samples_to_skip = 4500, - .verbose = false + .decimation = 0, + .bits_per_sample = 0, + .averaging = false, + .divisor = LF_DIVISOR(74), + .trigger_threshold = -1, + .samples_to_skip = 4500, + .verbose = false }; lf_config(&sc); @@ -156,7 +156,7 @@ static int CmdMotorolaClone(const char *Cmd) { "\n" "Samples:\n" "\tlf motorola clone a0000000a0002021\n" - ); + ); void *argtable[] = { arg_param_begin, @@ -175,7 +175,7 @@ static int CmdMotorolaClone(const char *Cmd) { blocks[0] = T55x7_BITRATE_RF_32 | T55x7_MODULATION_PSK1 | (2 << T55x7_MAXBLOCK_SHIFT); blocks[1] = bytes_to_num(data, 4); blocks[2] = bytes_to_num(data + 4, 4); - + print_blocks(blocks, ARRAYLEN(blocks)); return clone_t55xx_tag(blocks, ARRAYLEN(blocks)); } @@ -241,7 +241,7 @@ int detectMotorola(uint8_t *dest, size_t *size) { return -3; if (inverted && start_idx > 0) { - for(size_t i= start_idx -1 ; i < *size + start_idx + 2; i++) { + for (size_t i = start_idx - 1 ; i < *size + start_idx + 2; i++) { dest[i] ^= 1; } } @@ -254,5 +254,5 @@ int demodMotorola(void) { } int readMotorolaUid(void) { - return ( CmdMotorolaRead("") == PM3_SUCCESS); + return (CmdMotorolaRead("") == PM3_SUCCESS); } diff --git a/client/cmdlfnexwatch.c b/client/cmdlfnexwatch.c index d4069547b..8d40d47d6 100644 --- a/client/cmdlfnexwatch.c +++ b/client/cmdlfnexwatch.c @@ -54,7 +54,7 @@ static int CmdNexWatchDemod(const char *Cmd) { // else if (idx == -3) // PrintAndLogEx(DEBUG, "DEBUG: Error - NexWatch problem during PSK demod"); else if (idx == -4) - PrintAndLogEx(DEBUG, "DEBUG: Error - NexWatch preamble not found"); + PrintAndLogEx(DEBUG, "DEBUG: Error - NexWatch preamble not found"); // else if (idx == -5) // PrintAndLogEx(DEBUG, "DEBUG: Error - NexWatch size not correct: %d", size); else @@ -99,7 +99,7 @@ static int CmdNexWatchRead(const char *Cmd) { } static int CmdNexWatchClone(const char *Cmd) { - + // 56000000 00213C9F 8F150C00 00000000 uint32_t blocks[5]; bool errors = false; @@ -112,13 +112,13 @@ static int CmdNexWatchClone(const char *Cmd) { return usage_lf_nexwatch_clone(); case 'b': { // skip first block, 4*4 = 16 bytes left - uint8_t rawhex[16] = {0}; + uint8_t rawhex[16] = {0}; int res = param_gethex_to_eol(Cmd, cmdp + 1, rawhex, sizeof(rawhex), &datalen); - if ( res != 0 ) + if (res != 0) errors = true; - - for(uint8_t i = 1; i < ARRAYLEN(blocks); i++) { - blocks[i] = bytes_to_num(rawhex + ( (i - 1) * 4 ), sizeof(uint32_t)); + + for (uint8_t i = 1; i < ARRAYLEN(blocks); i++) { + blocks[i] = bytes_to_num(rawhex + ((i - 1) * 4), sizeof(uint32_t)); } cmdp += 2; break; diff --git a/client/cmdlfnoralsy.c b/client/cmdlfnoralsy.c index ed6ff0e09..79fbb3913 100644 --- a/client/cmdlfnoralsy.c +++ b/client/cmdlfnoralsy.c @@ -165,11 +165,12 @@ static int CmdNoralsyClone(const char *Cmd) { blocks[3] = bytebits_to_byte(bits + 64, 32); free(bits); - + PrintAndLogEx(INFO, "Preparing to clone Noralsy to T55x7 with CardId: %u", id); print_blocks(blocks, ARRAYLEN(blocks)); - return clone_t55xx_tag(blocks, ARRAYLEN(blocks));} + return clone_t55xx_tag(blocks, ARRAYLEN(blocks)); +} static int CmdNoralsySim(const char *Cmd) { diff --git a/client/cmdlfpac.c b/client/cmdlfpac.c index 9e6f9337c..9b735f02e 100644 --- a/client/cmdlfpac.c +++ b/client/cmdlfpac.c @@ -83,7 +83,7 @@ static int CmdPacRead(const char *Cmd) { } static int CmdPacClone(const char *Cmd) { - + uint32_t blocks[5]; bool errors = false; uint8_t cmdp = 0; @@ -95,13 +95,13 @@ static int CmdPacClone(const char *Cmd) { return usage_lf_pac_clone(); case 'b': { // skip first block, 4*4 = 16 bytes left - uint8_t rawhex[16] = {0}; + uint8_t rawhex[16] = {0}; int res = param_gethex_to_eol(Cmd, cmdp + 1, rawhex, sizeof(rawhex), &datalen); - if ( res != 0 ) + if (res != 0) errors = true; - - for(uint8_t i = 1; i < ARRAYLEN(blocks); i++) { - blocks[i] = bytes_to_num(rawhex + ( (i - 1) * 4 ), sizeof(uint32_t)); + + for (uint8_t i = 1; i < ARRAYLEN(blocks); i++) { + blocks[i] = bytes_to_num(rawhex + ((i - 1) * 4), sizeof(uint32_t)); } cmdp += 2; break; diff --git a/client/cmdlfparadox.c b/client/cmdlfparadox.c index b1a20dec2..d2c8d64b5 100644 --- a/client/cmdlfparadox.c +++ b/client/cmdlfparadox.c @@ -131,7 +131,7 @@ static int CmdParadoxRead(const char *Cmd) { } static int CmdParadoxClone(const char *Cmd) { - + uint32_t blocks[4]; bool errors = false; uint8_t cmdp = 0; @@ -143,13 +143,13 @@ static int CmdParadoxClone(const char *Cmd) { return usage_lf_paradox_clone(); case 'b': { // skip first block, 3*4 =12 bytes left - uint8_t rawhex[12] = {0}; + uint8_t rawhex[12] = {0}; int res = param_gethex_to_eol(Cmd, cmdp + 1, rawhex, sizeof(rawhex), &datalen); - if ( res != 0 ) + if (res != 0) errors = true; - - for(uint8_t i = 1; i < ARRAYLEN(blocks); i++) { - blocks[i] = bytes_to_num(rawhex + ( (i - 1) * 4 ), sizeof(uint32_t)); + + for (uint8_t i = 1; i < ARRAYLEN(blocks); i++) { + blocks[i] = bytes_to_num(rawhex + ((i - 1) * 4), sizeof(uint32_t)); } cmdp += 2; break; diff --git a/client/cmdlfsecurakey.c b/client/cmdlfsecurakey.c index 183762338..64e8a2121 100644 --- a/client/cmdlfsecurakey.c +++ b/client/cmdlfsecurakey.c @@ -130,7 +130,7 @@ static int CmdSecurakeyRead(const char *Cmd) { } static int CmdSecurakeyClone(const char *Cmd) { - + uint32_t blocks[4]; bool errors = false; uint8_t cmdp = 0; @@ -142,13 +142,13 @@ static int CmdSecurakeyClone(const char *Cmd) { return usage_lf_securakey_clone(); case 'b': { // skip first block, 3*4 = 12 bytes left - uint8_t rawhex[12] = {0}; + uint8_t rawhex[12] = {0}; int res = param_gethex_to_eol(Cmd, cmdp + 1, rawhex, sizeof(rawhex), &datalen); - if ( res != 0 ) + if (res != 0) errors = true; - - for(uint8_t i = 1; i < ARRAYLEN(blocks); i++) { - blocks[i] = bytes_to_num(rawhex + ( (i - 1) * 4 ), sizeof(uint32_t)); + + for (uint8_t i = 1; i < ARRAYLEN(blocks); i++) { + blocks[i] = bytes_to_num(rawhex + ((i - 1) * 4), sizeof(uint32_t)); } cmdp += 2; break; diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index ccabadeb4..ceecbddc1 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -69,12 +69,12 @@ static void print_usage_t55xx_downloadlink(uint8_t ShowAll, uint8_t dl_mode_defa PrintAndLogEx(NORMAL, " r - downlink encoding 0|1|2|3|4"); else PrintAndLogEx(NORMAL, " r - downlink encoding 0|1|2|3"); - PrintAndLogEx(NORMAL, " 0 - fixed bit length%s",(dl_mode_default == 0)? " (detected default)":""); // default will be whats in config struct - PrintAndLogEx(NORMAL, " 1 - long leading reference%s",(dl_mode_default == 1)? " (detected default)":""); - PrintAndLogEx(NORMAL, " 2 - leading zero%s",(dl_mode_default == 2)? " (detected default)":""); - PrintAndLogEx(NORMAL, " 3 - 1 of 4 coding reference%s",(dl_mode_default == 3)? " (detected default)":""); + PrintAndLogEx(NORMAL, " 0 - fixed bit length%s", (dl_mode_default == 0) ? " (detected default)" : ""); // default will be whats in config struct + PrintAndLogEx(NORMAL, " 1 - long leading reference%s", (dl_mode_default == 1) ? " (detected default)" : ""); + PrintAndLogEx(NORMAL, " 2 - leading zero%s", (dl_mode_default == 2) ? " (detected default)" : ""); + PrintAndLogEx(NORMAL, " 3 - 1 of 4 coding reference%s", (dl_mode_default == 3) ? " (detected default)" : ""); if (ShowAll == T55XX_DLMODE_ALL) - PrintAndLogEx(NORMAL, " 4 - Try all downlink modes%s",(dl_mode_default == 4)? " (default)":""); + PrintAndLogEx(NORMAL, " 4 - Try all downlink modes%s", (dl_mode_default == 4) ? " (default)" : ""); } static int usage_t55xx_config() { @@ -89,7 +89,7 @@ static int usage_t55xx_config() { PrintAndLogEx(NORMAL, " Q5 [0/1] - Set/reset as T5555 ( Q5 ) chip instead of T55x7"); PrintAndLogEx(NORMAL, " ST [0/1] - Set/reset Sequence Terminator on"); PrintAndLogEx(NORMAL, ""); // layout is a little differnet, so seperate until a better fix - print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE,config.downlink_mode); + print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE, config.downlink_mode); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx config d FSK - FSK demodulation"); @@ -105,7 +105,7 @@ static int usage_t55xx_read() { PrintAndLogEx(NORMAL, " p - OPTIONAL password (8 hex characters)"); PrintAndLogEx(NORMAL, " o - OPTIONAL override safety check"); PrintAndLogEx(NORMAL, " 1 - OPTIONAL 0|1 read Page 1 instead of Page 0"); - print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE,config.downlink_mode); + print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE, config.downlink_mode); PrintAndLogEx(NORMAL, " " _RED_("**** WARNING ****")); PrintAndLogEx(NORMAL, " Use of read with password on a tag not configured"); PrintAndLogEx(NORMAL, " for a password can damage the tag"); @@ -122,7 +122,7 @@ static int usage_t55xx_resetread() { PrintAndLogEx(NORMAL, "Send Reset Cmd then lf read the stream to attempt to identify the start of it (needs a demod and/or plot after)"); PrintAndLogEx(NORMAL, "Usage: lf t55xx resetread [r ]"); PrintAndLogEx(NORMAL, "Options:"); - print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE,config.downlink_mode); + print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE, config.downlink_mode); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx resetread"); @@ -138,7 +138,7 @@ static int usage_t55xx_write() { PrintAndLogEx(NORMAL, " 1 - OPTIONAL write Page 1 instead of Page 0"); PrintAndLogEx(NORMAL, " t - OPTIONAL test mode write - ****DANGER****"); PrintAndLogEx(NORMAL, " v - OPTIONAL validate data afterwards"); - print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE,config.downlink_mode); + print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE, config.downlink_mode); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx write b 3 d 11223344 - write 11223344 to block 3"); @@ -150,7 +150,7 @@ static int usage_t55xx_write() { static int usage_t55xx_trace() { PrintAndLogEx(NORMAL, "Usage: lf t55xx trace [1] [r mode]"); PrintAndLogEx(NORMAL, "Options:"); - print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE,config.downlink_mode); + print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE, config.downlink_mode); PrintAndLogEx(NORMAL, " 1 - if set, use Graphbuffer otherwise read data from tag."); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); @@ -168,7 +168,7 @@ static int usage_t55xx_info() { PrintAndLogEx(NORMAL, " c - set configuration from a block0"); PrintAndLogEx(NORMAL, " if set, use these data instead of reading tag."); PrintAndLogEx(NORMAL, " q - if set, provided data are interpreted as Q5 config."); - print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE,config.downlink_mode); + print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE, config.downlink_mode); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx info"); @@ -185,7 +185,7 @@ static int usage_t55xx_dump() { PrintAndLogEx(NORMAL, " p - OPTIONAL password 4bytes (8 hex symbols)"); PrintAndLogEx(NORMAL, " o - OPTIONAL override, force pwd read despite danger to card"); PrintAndLogEx(NORMAL, " f - overide filename prefix (optional). Default is based on blk 0"); - print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE,config.downlink_mode); + print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE, config.downlink_mode); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx dump"); @@ -212,7 +212,7 @@ static int usage_t55xx_detect() { PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " 1 - if set, use Graphbuffer otherwise read data from tag."); PrintAndLogEx(NORMAL, " p - OPTIONAL password (8 hex characters)"); - print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE,config.downlink_mode); // Need to setup to try all modes + print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE, config.downlink_mode); // Need to setup to try all modes PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx p1detect"); @@ -242,7 +242,7 @@ static int usage_t55xx_wakup() { PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h - this help"); PrintAndLogEx(NORMAL, " p - password 4bytes (8 hex symbols)"); - print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE,config.downlink_mode); + print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE, config.downlink_mode); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx wakeup p 11223344 - send wakeup password"); @@ -257,7 +257,7 @@ static int usage_t55xx_chk() { PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h - this help"); PrintAndLogEx(NORMAL, " m - use dictionary from flashmemory\n"); - print_usage_t55xx_downloadlink(T55XX_DLMODE_ALL,T55XX_DLMODE_ALL); + print_usage_t55xx_downloadlink(T55XX_DLMODE_ALL, T55XX_DLMODE_ALL); PrintAndLogEx(NORMAL, " i <*.dic> - loads a default keys dictionary file <*.dic>"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); @@ -275,7 +275,7 @@ static int usage_t55xx_bruteforce() { PrintAndLogEx(NORMAL, " password must be 4 bytes (8 hex symbols)"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h - this help"); - print_usage_t55xx_downloadlink(T55XX_DLMODE_ALL,T55XX_DLMODE_ALL); + print_usage_t55xx_downloadlink(T55XX_DLMODE_ALL, T55XX_DLMODE_ALL); PrintAndLogEx(NORMAL, " s - 4 byte hex value to start pwd search at"); PrintAndLogEx(NORMAL, " e - 4 byte hex value to end pwd search at"); PrintAndLogEx(NORMAL, ""); @@ -294,7 +294,7 @@ static int usage_t55xx_recoverpw() { PrintAndLogEx(NORMAL, " default password is 51243648, used by many cloners"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h - this help"); - print_usage_t55xx_downloadlink(T55XX_DLMODE_ALL,T55XX_DLMODE_ALL); + print_usage_t55xx_downloadlink(T55XX_DLMODE_ALL, T55XX_DLMODE_ALL); PrintAndLogEx(NORMAL, " p - 4 byte hex value of password written by cloner"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); @@ -347,7 +347,7 @@ static int usage_t55xx_protect() { PrintAndLogEx(NORMAL, " p - OPTIONAL password (8 hex characters)"); PrintAndLogEx(NORMAL, " o - OPTIONAL override safety check"); PrintAndLogEx(NORMAL, " n - new password"); - print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE,config.downlink_mode); + print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE, config.downlink_mode); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx protect n 01020304 - sets new password to 01020304"); @@ -358,15 +358,15 @@ static int usage_t55xx_protect() { static int CmdHelp(const char *Cmd); -void T55x7_SaveBlockData (uint8_t idx,uint32_t data) { +void T55x7_SaveBlockData(uint8_t idx, uint32_t data) { if (idx < T55x7_BLOCK_COUNT) { - cardmem[idx].valid = true; + cardmem[idx].valid = true; cardmem[idx].blockdata = data; } } -void T55x7_ClearAllBlockData (void) { +void T55x7_ClearAllBlockData(void) { for (uint8_t idx = 0; idx < T55x7_BLOCK_COUNT; idx++) { - cardmem[idx].valid = false; + cardmem[idx].valid = false; cardmem[idx].blockdata = 0x00; } } @@ -405,7 +405,7 @@ int clone_t55xx_tag(uint32_t *blockdata, uint8_t numblocks) { } } - uint8_t res = 0; + uint8_t res = 0; for (int8_t i = 0; i < numblocks; i++) { if (i == 0) { @@ -524,9 +524,9 @@ bool t55xxAquireAndDetect(bool usepwd, uint32_t password, uint32_t known_block0, // Update flags for usepwd pwd assume its correct config.usepwd = usepwd; - if (usepwd) + if (usepwd) config.pwd = password; - else + else config.pwd = 0x00; for (uint8_t m = 0; m < 4; m++) { @@ -541,7 +541,7 @@ bool t55xxAquireAndDetect(bool usepwd, uint32_t password, uint32_t known_block0, } config.usepwd = false; // unknown so assume no password config.pwd = 0x00; - + return false; } @@ -817,7 +817,7 @@ int T55xxReadBlockEx(uint8_t block, bool page1, bool usepwd, uint8_t override, u return PM3_EWRONGANSVER; if (verbose) - printT55xxBlock(block,page1); + printT55xxBlock(block, page1); return PM3_SUCCESS; } @@ -1021,7 +1021,7 @@ static int CmdT55xxDetect(const char *Cmd) { if (errors) return usage_t55xx_detect(); // detect called so clear data blocks - T55x7_ClearAllBlockData (); + T55x7_ClearAllBlockData(); // sanity check. if (SanityOfflineCheck(useGB) != PM3_SUCCESS) @@ -1030,18 +1030,18 @@ static int CmdT55xxDetect(const char *Cmd) { if (useGB == false) { // do ... while to check without password then loop back if password supplied do { - + if (try_all_dl_modes) { for (uint8_t m = downlink_mode; m < 4; m++) { - + if (AcquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, try_with_pwd & usepwd, password, m) == false) continue; // pre fill to save passing in. config.usepwd = try_with_pwd; - if (try_with_pwd) + if (try_with_pwd) config.pwd = password; - else + else config.pwd = 0x00; if (tryDetectModulation(m, T55XX_PrintConfig) == false) @@ -1052,9 +1052,9 @@ static int CmdT55xxDetect(const char *Cmd) { } } else { config.usepwd = try_with_pwd; - if (try_with_pwd) + if (try_with_pwd) config.pwd = password; - else + else config.pwd = 0x00; if (AcquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, downlink_mode)) { @@ -1062,12 +1062,12 @@ static int CmdT55xxDetect(const char *Cmd) { } } - if (!found & usepwd) + if (!found & usepwd) try_with_pwd = !try_with_pwd; // toggle so we loop back if not found and try with pwd - - if (found) + + if (found) try_with_pwd = false; // force exit as decect block has been found. - + } while (try_with_pwd); } else { @@ -1345,7 +1345,7 @@ void printT55xxBlock(uint8_t blockNum, bool page1) { num_to_bytes(blockData, 4, bytes); - T55x7_SaveBlockData ((page1)?blockNum+8 : blockNum,blockData); + T55x7_SaveBlockData((page1) ? blockNum + 8 : blockNum, blockData); PrintAndLogEx(SUCCESS, " %02d | %08X | %s | %s", blockNum, blockData, sprint_bin(DemodBuffer + config.offset, 32), sprint_ascii(bytes, 4)); } @@ -1556,7 +1556,7 @@ int printConfiguration(t55xx_conf_block_t b) { PrintAndLogEx(NORMAL, " Downlink Mode : %s", GetDownlinkModeStr(b.downlink_mode)); PrintAndLogEx(NORMAL, " Password Set : %s", (b.usepwd) ? _RED_("Yes") : _GREEN_("No")); if (b.usepwd) - PrintAndLogEx(NORMAL, " Password : %08X",b.pwd); + PrintAndLogEx(NORMAL, " Password : %08X", b.pwd); PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } @@ -1930,9 +1930,9 @@ void printT55x7Trace(t55x7_tracedata_t data, uint8_t repeat) { PrintAndLogEx(NORMAL, "-------------------------------------------------------------"); /* - Trace info. - M1, M2 has the about ATMEL defintion of trace data. - M3 has unique format following industry defacto standard with row/col parity + Trace info. + M1, M2 has the about ATMEL defintion of trace data. + M3 has unique format following industry defacto standard with row/col parity TRACE - BLOCK O Bits Definition HEX @@ -1950,11 +1950,11 @@ void printT55x7Trace(t55x7_tracedata_t data, uint8_t repeat) { 1-12 LOT ID 13-17 Wafer number 18-32 DW, die number sequential - + Startup times (FC) - M1, M2 = 192 - M3 = 128 + M1, M2 = 192 + M3 = 128 */ } @@ -2226,11 +2226,11 @@ static int CmdT55xxDump(const char *Cmd) { cmdp++; break; case 'f': - param_getstr(Cmd, cmdp + 1, preferredName, FILE_PATH_SIZE); - cmdp+=2; - if (strlen (preferredName) == 0) - errors = true; - break; + param_getstr(Cmd, cmdp + 1, preferredName, FILE_PATH_SIZE); + cmdp += 2; + if (strlen(preferredName) == 0) + errors = true; + break; default: PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); errors = true; @@ -2250,35 +2250,35 @@ static int CmdT55xxDump(const char *Cmd) { if (override == 1) override++; // flag not to show safty for 2nd and on. } printT5xxHeader(1); - for (uint8_t i = 0; i < 4; i++) + for (uint8_t i = 0; i < 4; i++) if (T55xxReadBlock(i, 1, usepwd, override, password, downlink_mode) != PM3_SUCCESS) - T55x7_SaveBlockData (8+i,0x00); + T55x7_SaveBlockData(8 + i, 0x00); if (success) { // all ok save dump to file // saveFileEML will add .eml extension to filename // saveFile (binary) passes in the .bin extension. - if (strcmp (preferredName,"") == 0) { // Set default filename, if not set by user - strcpy (preferredName,"lf-t55xx"); + if (strcmp(preferredName, "") == 0) { // Set default filename, if not set by user + strcpy(preferredName, "lf-t55xx"); for (uint8_t i = 1; i <= 7; i++) { if ((cardmem[i].blockdata != 0x00) && (cardmem[i].blockdata != 0xFFFFFFFF)) - sprintf (preferredName + strlen(preferredName),"-%08X",cardmem[i].blockdata); + sprintf(preferredName + strlen(preferredName), "-%08X", cardmem[i].blockdata); else break; } - strcat (preferredName,"-data"); + strcat(preferredName, "-data"); } // Swap endian so the files match the txt display uint32_t data[T55x7_BLOCK_COUNT]; - + for (int i = 0; i < T55x7_BLOCK_COUNT; i++) data[i] = BSWAP_32(cardmem[i].blockdata); - saveFileEML(preferredName, (uint8_t *)data, T55x7_BLOCK_COUNT*sizeof(uint32_t), sizeof(uint32_t)); - saveFile (preferredName, ".bin", data, sizeof(data)); + saveFileEML(preferredName, (uint8_t *)data, T55x7_BLOCK_COUNT * sizeof(uint32_t), sizeof(uint32_t)); + saveFile(preferredName, ".bin", data, sizeof(data)); } - + return PM3_SUCCESS; } @@ -2301,17 +2301,17 @@ static int CmdT55xxRestore(const char *Cmd) { switch (tolower(param_getchar(Cmd, cmdp))) { case 'h': return usage_t55xx_restore(); - case 'f': - param_getstr(Cmd, cmdp + 1, preferredName, FILE_PATH_SIZE); - if (strlen (preferredName) == 0) - errors = true; - cmdp+=2; - break; + case 'f': + param_getstr(Cmd, cmdp + 1, preferredName, FILE_PATH_SIZE); + if (strlen(preferredName) == 0) + errors = true; + cmdp += 2; + break; case 'p': password = param_get32ex(Cmd, cmdp + 1, 0, 16); usepwd = true; cmdp += 2; - break; + break; default: PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); errors = true; @@ -2320,40 +2320,40 @@ static int CmdT55xxRestore(const char *Cmd) { } // File name expected to be .eml .bin or .json so sould be at least 4 - if (errors || (strlen (preferredName) == 0)) return usage_t55xx_restore(); - + if (errors || (strlen(preferredName) == 0)) return usage_t55xx_restore(); + // split file name into prefix and ext. int fnLength; - fnLength = strlen (preferredName); - + fnLength = strlen(preferredName); + success = PM3_ESOFT; if (fnLength > 4) { // Holds extension [.bin|.eml] - memcpy (ext,&preferredName[fnLength - 4],4); + memcpy(ext, &preferredName[fnLength - 4], 4); ext[5] = 0x00; // check if valid file extension and attempt to load data - if (memcmp (ext,".bin",4) == 0) { - preferredName[fnLength-4] = 0x00; - success = loadFile (preferredName, ".bin", data, sizeof(data),&datalen); - - } else if (memcmp (ext,".eml",4) == 0) { - preferredName[fnLength-4] = 0x00; + if (memcmp(ext, ".bin", 4) == 0) { + preferredName[fnLength - 4] = 0x00; + success = loadFile(preferredName, ".bin", data, sizeof(data), &datalen); + + } else if (memcmp(ext, ".eml", 4) == 0) { + preferredName[fnLength - 4] = 0x00; datalen = 12; success = loadFileEML(preferredName, (uint8_t *)data, &datalen); - } else - PrintAndLogEx(WARNING,"\nWarning: invalid dump filename "_YELLOW_("%s")"to restore!\n",preferredName); + } else + PrintAndLogEx(WARNING, "\nWarning: invalid dump filename "_YELLOW_("%s")"to restore!\n", preferredName); } if (success == PM3_SUCCESS) { // Got data, so write to cards if (datalen == T55x7_BLOCK_COUNT * 4) { // 12 blocks * 4 bytes per block if (usepwd) - sprintf (pwdOpt,"p %08X",password); + sprintf(pwdOpt, "p %08X", password); // Restore endien for writing to card - for (blockidx = 0; blockidx < 12; blockidx++) + for (blockidx = 0; blockidx < 12; blockidx++) data[blockidx] = BSWAP_32(data[blockidx]); // Have data ready, lets write @@ -2364,30 +2364,30 @@ static int CmdT55xxRestore(const char *Cmd) { downlink_mode = 0; if ((((data[11] >> 28) & 0xf) == 6) || (((data[11] >> 28) & 0xf) == 9)) downlink_mode = (data[11] >> 10) & 3; - + // write out blocks 1-7 page 0 for (blockidx = 1; blockidx <= 7; blockidx++) { - sprintf (writeCmdOpt,"b %d d %08X %s",blockidx,data[blockidx],pwdOpt); + sprintf(writeCmdOpt, "b %d d %08X %s", blockidx, data[blockidx], pwdOpt); if (CmdT55xxWriteBlock(writeCmdOpt) != PM3_SUCCESS) - PrintAndLogEx(WARNING, "Warning: error writing blk %d",blockidx); + PrintAndLogEx(WARNING, "Warning: error writing blk %d", blockidx); } // if password was set on the "blank" update as we may have just changed it if (usepwd) - sprintf (pwdOpt,"p %08X",data[7]); + sprintf(pwdOpt, "p %08X", data[7]); // write out blocks 1-3 page 1 for (blockidx = 9; blockidx <= 11; blockidx++) { - sprintf (writeCmdOpt,"b %d 1 d %08X %s",blockidx-8,data[blockidx],pwdOpt); + sprintf(writeCmdOpt, "b %d 1 d %08X %s", blockidx - 8, data[blockidx], pwdOpt); if (CmdT55xxWriteBlock(writeCmdOpt) != PM3_SUCCESS) - PrintAndLogEx(WARNING, "Warning: error writing blk %d",blockidx); + PrintAndLogEx(WARNING, "Warning: error writing blk %d", blockidx); } // Update downlink mode for the page 0 config write. config.downlink_mode = downlink_mode; - + // Write the page 0 config - sprintf (writeCmdOpt,"b 0 d %08X %s",data[0],pwdOpt); + sprintf(writeCmdOpt, "b 0 d %08X %s", data[0], pwdOpt); if (CmdT55xxWriteBlock(writeCmdOpt) != PM3_SUCCESS) PrintAndLogEx(WARNING, "Warning: error writing blk 0"); } diff --git a/client/cmdlft55xx.h b/client/cmdlft55xx.h index 7b980c042..4f96006b5 100644 --- a/client/cmdlft55xx.h +++ b/client/cmdlft55xx.h @@ -129,8 +129,8 @@ typedef struct { } t55xx_conf_block_t; typedef struct { - uint32_t blockdata; - bool valid; + uint32_t blockdata; + bool valid; } t55xx_memory_item_t ; t55xx_conf_block_t Get_t55xx_Config(void); @@ -150,7 +150,7 @@ char *GetModelStrFromCID(uint32_t cid); char *GetSelectedModulationStr(uint8_t id); char *GetDownlinkModeStr(uint8_t dlmode); void printT5xxHeader(uint8_t page); -void printT55xxBlock(uint8_t blockNum,bool page1); +void printT55xxBlock(uint8_t blockNum, bool page1); int printConfiguration(t55xx_conf_block_t b); bool t55xxAquireAndCompareBlock0(bool usepwd, uint32_t password, uint32_t known_block0, bool verbose); diff --git a/client/cmdlfverichip.c b/client/cmdlfverichip.c index 21ac52836..9bccefde4 100644 --- a/client/cmdlfverichip.c +++ b/client/cmdlfverichip.c @@ -95,13 +95,13 @@ static int CmdVerichipClone(const char *Cmd) { return usage_lf_verichip_clone(); case 'b': { // skip first block, 4*4 = 16 bytes left - uint8_t rawhex[16] = {0}; + uint8_t rawhex[16] = {0}; int res = param_gethex_to_eol(Cmd, cmdp + 1, rawhex, sizeof(rawhex), &datalen); - if ( res != 0 ) + if (res != 0) errors = true; - for(uint8_t i = 1; i < ARRAYLEN(blocks); i++) { - blocks[i] = bytes_to_num(rawhex + ( (i - 1) * 4 ), sizeof(uint32_t)); + for (uint8_t i = 1; i < ARRAYLEN(blocks); i++) { + blocks[i] = bytes_to_num(rawhex + ((i - 1) * 4), sizeof(uint32_t)); } cmdp += 2; break; diff --git a/client/emv/emv_pki_priv.c b/client/emv/emv_pki_priv.c index db8b6381d..d14e0b6ef 100644 --- a/client/emv/emv_pki_priv.c +++ b/client/emv/emv_pki_priv.c @@ -209,7 +209,7 @@ static struct tlvdb *emv_pki_sign_key(const struct crypto_pk *cp, if (!db) { free(exp_db); return NULL; - } + } tlvdb_add(db, exp_db); diff --git a/client/mifare/mifarehost.c b/client/mifare/mifarehost.c index 1f7f2e35a..39d2d6001 100644 --- a/client/mifare/mifarehost.c +++ b/client/mifare/mifarehost.c @@ -48,7 +48,7 @@ int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) { payload.first_run = first_run; payload.blockno = blockno; payload.key_type = key_type; - SendCommandNG(CMD_HF_MIFARE_READER, (uint8_t*)&payload, sizeof(payload)); + SendCommandNG(CMD_HF_MIFARE_READER, (uint8_t *)&payload, sizeof(payload)); //flush queue while (kbd_enter_pressed()) { @@ -79,11 +79,11 @@ int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) { uint8_t ar[4]; } PACKED; - struct p* package = (struct p*) resp.data.asBytes; + struct p *package = (struct p *) resp.data.asBytes; if (package->isOK == -6) { - *key = 0101; - return 1; + *key = 0101; + return 1; } if (package->isOK < 0) @@ -359,7 +359,7 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, PacketResponseNG resp; clearCommandBuffer(); - SendCommandNG(CMD_HF_MIFARE_NESTED, (uint8_t*)&payload, sizeof(payload)); + SendCommandNG(CMD_HF_MIFARE_NESTED, (uint8_t *)&payload, sizeof(payload)); if (!WaitForResponseTimeout(CMD_HF_MIFARE_NESTED, &resp, 1500)) return PM3_ETIMEOUT; @@ -376,7 +376,7 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, uint8_t nt_b[4]; uint8_t ks_b[4]; } PACKED; - struct p* package = (struct p*)resp.data.asBytes; + struct p *package = (struct p *)resp.data.asBytes; // error during nested if (package->isOK) return package->isOK; diff --git a/client/proxmark3.c b/client/proxmark3.c index c6045d900..db8434e07 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -689,22 +689,22 @@ int main(int argc, char *argv[]) { // Check if windows AnsiColor Support is enabled in the registery // [HKEY_CURRENT_USER\Console] // "VirtualTerminalLevel"=dword:00000001 - + HKEY hKey = NULL; - if(RegOpenKeyA (HKEY_CURRENT_USER,"Console",&hKey) == ERROR_SUCCESS) { + if (RegOpenKeyA(HKEY_CURRENT_USER, "Console", &hKey) == ERROR_SUCCESS) { DWORD dwType = REG_SZ; BYTE KeyValue[sizeof(dwType)]; DWORD len = sizeof(KeyValue); - if (RegQueryValueEx(hKey,"VirtualTerminalLevel", NULL, &dwType,KeyValue, &len) != ERROR_FILE_NOT_FOUND) { + if (RegQueryValueEx(hKey, "VirtualTerminalLevel", NULL, &dwType, KeyValue, &len) != ERROR_FILE_NOT_FOUND) { uint8_t i; uint32_t Data = 0; for (i = 0; i < 4; i++) Data += KeyValue[i] << (8 * i); if (Data == 1) { // Reg key is set to 1, Ansi Color Enabled - session.supports_colors = true; + session.supports_colors = true; } } RegCloseKey(hKey); diff --git a/client/wiegand_formatutils.c b/client/wiegand_formatutils.c index 3e1ee0028..80a9c9268 100644 --- a/client/wiegand_formatutils.c +++ b/client/wiegand_formatutils.c @@ -149,7 +149,7 @@ uint8_t get_length_from_header(wiegand_message_t *data) { hfmt >>= 1; len++; } - if (len < 26 ) + if (len < 26) len = 26; return len; } diff --git a/common/lfdemod.c b/common/lfdemod.c index 9ed1a83c3..30990ec73 100644 --- a/common/lfdemod.c +++ b/common/lfdemod.c @@ -84,10 +84,10 @@ static void printSignal(void) { #ifndef ON_DEVICE static int cmp_uint8(const void *a, const void *b) { - if (*(const uint8_t *)a < * (const uint8_t *)b) - return -1; - else - return *(const uint8_t *)a > *(const uint8_t *)b; + if (*(const uint8_t *)a < * (const uint8_t *)b) + return -1; + else + return *(const uint8_t *)a > *(const uint8_t *)b; } #endif @@ -123,7 +123,7 @@ void computeSignalProperties(uint8_t *samples, uint32_t size) { else signalprop.mean = 0; #else - for (uint32_t i = SIGNAL_IGNORE_FIRST_SAMPLES; i < size; i++) { + for (uint32_t i = SIGNAL_IGNORE_FIRST_SAMPLES; i < size; i++) { if (samples[i] < signalprop.low) signalprop.low = samples[i]; if (samples[i] > signalprop.high) signalprop.high = samples[i]; sum += samples[i]; From 23efb59d5f8bb4d750e5063407568febb79ae13b Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 13 Oct 2019 00:49:19 +0200 Subject: [PATCH 0968/1854] coverity: long test --- covbuild.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/covbuild.sh b/covbuild.sh index 4784a1de6..1899cb8b3 100755 --- a/covbuild.sh +++ b/covbuild.sh @@ -32,7 +32,7 @@ cov-build --dir "$COVDIR" --c-coverage=gcov --no-network-coverage --no-generate- ######################################### # Run tests # ######################################### -cov-build --dir "$COVDIR" --c-coverage=gcov --no-network-coverage --test-capture ./pm3test.sh +cov-build --dir "$COVDIR" --c-coverage=gcov --no-network-coverage --test-capture ./pm3test.sh long #cov-manage-emit --dir "$COVDIR" list-coverage-known ######################################### From 47d6eef7c947767551c50540d1d79f39943556e4 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 13 Oct 2019 01:21:59 +0200 Subject: [PATCH 0969/1854] usage --- client/cmdlft55xx.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index ceecbddc1..1607dc746 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -355,6 +355,21 @@ static int usage_t55xx_protect() { PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } +static int usage_t55xx_dangerraw() { + PrintAndLogEx(NORMAL, "This command allows to emit arbitrary raw commands on T5577 and cut the field after arbitrary duration."); + PrintAndLogEx(NORMAL, _RED_("WARNING:") " this may lock definitively the tag in an unusable state!"); + PrintAndLogEx(NORMAL, "Uncontrolled usage can easily write an invalid configuration, activate lock bits,"); + PrintAndLogEx(NORMAL, "OTP bit, password protection bit, deactivate test-mode, lock your card forever."); + PrintAndLogEx(NORMAL, "Uncontrolled usage is known to the State of California to cause cancer."); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Usage: lf t55xx dangerraw [h] [b t ]"); + PrintAndLogEx(NORMAL, "Options:"); + PrintAndLogEx(NORMAL, " h - This help"); + PrintAndLogEx(NORMAL, " b - raw bitstream"); + PrintAndLogEx(NORMAL, " t - time in microseconds before dropping the field"); + PrintAndLogEx(NORMAL, ""); + return PM3_SUCCESS; +} static int CmdHelp(const char *Cmd); @@ -1706,6 +1721,8 @@ static int CmdT55xxDangerousRaw(const char *Cmd) { while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { + case 'h': + return usage_t55xx_dangerraw(); case 't': ng.time = param_get32ex(Cmd, cmdp + 1, 0, 10); if (ng.time == 0 || ng.time > 200000) { @@ -1745,8 +1762,7 @@ static int CmdT55xxDangerousRaw(const char *Cmd) { } } if (errors || ng.bitlen == 0 || ng.time == 0) { - PrintAndLogEx(ERR, "Error occurred, abort. " _RED_("DANGEROUS COMMAND, DO NOT USE!")); - return PM3_EINVARG; + return usage_t55xx_dangerraw(); } PacketResponseNG resp; clearCommandBuffer(); From 0ffb748f5e7eedaa89ea852cdae66d19d9294134 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 14 Oct 2019 21:17:41 +0200 Subject: [PATCH 0970/1854] fix: hi/low should not be same --- common/lfdemod.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/common/lfdemod.c b/common/lfdemod.c index 30990ec73..2a9983130 100644 --- a/common/lfdemod.c +++ b/common/lfdemod.c @@ -201,7 +201,7 @@ void getHiLo(int *high, int *low, uint8_t fuzzHi, uint8_t fuzzLo) { } // if fuzzing to great and overlap - if (*high < *low) { + if (*high <= *low) { *high = signalprop.high; *low = signalprop.low; } @@ -1723,7 +1723,6 @@ int nrzRawDemod(uint8_t *dest, size_t *size, int *clk, int *invert, int *startId size_t i; int high, low; - getHiLo(&high, &low, 75, 75); getHiLo(&high, &low, 75, 75); uint8_t bit = 0; From bd13f72a59e8a094c5022eb79fefb1469c8c3e91 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 14 Oct 2019 22:32:58 +0200 Subject: [PATCH 0971/1854] textual --- client/cmdhficlass.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 67aa84396..bb20e5b3a 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -150,7 +150,7 @@ static int usage_hf_iclass_writeblock(void) { return PM3_SUCCESS; } static int usage_hf_iclass_readblock(void) { - PrintAndLogEx(NORMAL, "Usage: hf iclass readblk b k [c|e|r|v]\n"); + PrintAndLogEx(NORMAL, "Usage: hf iclass rdbl b k [c|e|r|v]\n"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " b : The block number as 2 hex symbols"); PrintAndLogEx(NORMAL, " k : Access Key as 16 hex symbols or 1 hex to select key from memory"); @@ -159,9 +159,9 @@ static int usage_hf_iclass_readblock(void) { PrintAndLogEx(NORMAL, " r : raw, no computations applied to key"); PrintAndLogEx(NORMAL, " v : verbose output"); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf iclass readblk b 06 k 0011223344556677"); - PrintAndLogEx(NORMAL, " hf iclass readblk b 1B k 0011223344556677 c"); - PrintAndLogEx(NORMAL, " hf iclass readblk b 0A k 0"); + PrintAndLogEx(NORMAL, " hf iclass rdbl b 06 k 0011223344556677"); + PrintAndLogEx(NORMAL, " hf iclass rdbl b 1B k 0011223344556677 c"); + PrintAndLogEx(NORMAL, " hf iclass rdbl b 0A k 0"); return PM3_SUCCESS; } static int usage_hf_iclass_readtagfile() { From 2173cadf23c4b678e1392cdda370b134f741ef8f Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 15 Oct 2019 13:06:46 +0200 Subject: [PATCH 0972/1854] openocd scripts: allow to call them from another dir --- tools/jtag_openocd/openocd_flash_dump.sh | 1 + tools/jtag_openocd/openocd_flash_recovery.sh | 1 + tools/jtag_openocd/openocd_interactive.sh | 1 + 3 files changed, 3 insertions(+) diff --git a/tools/jtag_openocd/openocd_flash_dump.sh b/tools/jtag_openocd/openocd_flash_dump.sh index 497847dd1..650c218f1 100755 --- a/tools/jtag_openocd/openocd_flash_dump.sh +++ b/tools/jtag_openocd/openocd_flash_dump.sh @@ -1,5 +1,6 @@ #!/bin/bash +cd $(dirname "$0") . openocd_configuration || exit 1 if [ -e "$DUMP" ]; then diff --git a/tools/jtag_openocd/openocd_flash_recovery.sh b/tools/jtag_openocd/openocd_flash_recovery.sh index 2e88c52e6..80caa08f0 100755 --- a/tools/jtag_openocd/openocd_flash_recovery.sh +++ b/tools/jtag_openocd/openocd_flash_recovery.sh @@ -1,5 +1,6 @@ #!/bin/bash +cd $(dirname "$0") . openocd_configuration || exit 1 if [ ! -e "$IMAGE" ]; then diff --git a/tools/jtag_openocd/openocd_interactive.sh b/tools/jtag_openocd/openocd_interactive.sh index ea7919da8..ac022f3f2 100755 --- a/tools/jtag_openocd/openocd_interactive.sh +++ b/tools/jtag_openocd/openocd_interactive.sh @@ -1,5 +1,6 @@ #!/bin/bash +cd $(dirname "$0") . openocd_configuration || exit 1 echo "*********************************************" From c7d84ce2399cee2322f7b32b1610e5d264f2ef91 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 15 Oct 2019 14:07:20 +0200 Subject: [PATCH 0973/1854] hw status: Detect slow clock drift problems --- armsrc/appmain.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index b524c4883..a0c9a78f2 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -354,6 +354,17 @@ void SendStatus(void) { while ((AT91C_BASE_PMC->PMC_MCFR & AT91C_CKGR_MAINRDY) == 0); // Wait for MAINF value to become available... uint16_t mainf = AT91C_BASE_PMC->PMC_MCFR & AT91C_CKGR_MAINF; // Get # main clocks within 16 slow clocks Dbprintf(" Slow clock..............%d Hz", (16 * MAINCK) / mainf); + uint32_t delta_time = 0; + uint32_t start_time = GetTickCount(); + #define SLCK_CHECK_MS 50 + WaitMS(SLCK_CHECK_MS); + delta_time = GetTickCountDelta(start_time); + if ((delta_time < SLCK_CHECK_MS - 1) || (delta_time > SLCK_CHECK_MS + 1)) { + // error > 2% with SLCK_CHECK_MS=50 + Dbprintf(_RED_(" Slow Clock speed change detected, TIA needed")); + Dbprintf(_YELLOW_(" Slow Clock actual speed seems closer to %d kHz"), + (16 * MAINCK / 1000) / mainf * delta_time / SLCK_CHECK_MS); + } DbpString(_BLUE_("Installed StandAlone Mode")); ModInfo(); From 3fce47d023f7c54bb05b64772d27442808a07a4b Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 15 Oct 2019 14:21:26 +0200 Subject: [PATCH 0974/1854] Add `hw tia` to trigger a new Timing Interval Acquisition --- armsrc/Makefile | 1 + armsrc/appmain.c | 19 ++++++++++++++ bootrom/Makefile | 1 + bootrom/bootrom.c | 41 ++---------------------------- client/cmdhw.c | 13 ++++++++++ common_arm/clocks.c | 62 +++++++++++++++++++++++++++++++++++++++++++++ common_arm/clocks.h | 10 ++++++++ include/pm3_cmd.h | 1 + 8 files changed, 109 insertions(+), 39 deletions(-) create mode 100644 common_arm/clocks.c create mode 100644 common_arm/clocks.h diff --git a/armsrc/Makefile b/armsrc/Makefile index f94868b6e..beb19c243 100644 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@ -109,6 +109,7 @@ THUMBSRC = start.c \ string.c \ BigBuf.c \ ticks.c \ + clocks.c \ hfsnoop.c diff --git a/armsrc/appmain.c b/armsrc/appmain.c index a0c9a78f2..f2e4424ee 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -11,6 +11,7 @@ //----------------------------------------------------------------------------- #include "appmain.h" +#include "clocks.h" #include "usb_cdc.h" #include "proxmark3_arm.h" #include "dbprint.h" @@ -303,6 +304,14 @@ void SendVersion(void) { reply_ng(CMD_VERSION, PM3_SUCCESS, (uint8_t *)&payload, 12 + payload.versionstr_len); } +void TimingIntervalAcquisition(void) { + // trigger new acquisition by turning main oscillator off and on + mck_from_pll_to_slck(); + mck_from_slck_to_pll(false); + // wait for MCFR and recompute RTMR scaler + StartTickCount(); +} + // measure the Connection Speed by sending SpeedTestBufferSize bytes to client and measuring the elapsed time. // Note: this mimics GetFromBigbuf(), i.e. we have the overhead of the PacketCommandNG structure included. void printConnSpeed(void) { @@ -1889,6 +1898,16 @@ static void PacketReceived(PacketCommandNG *packet) { SendStatus(); break; } + case CMD_TIA: { + uint16_t mainf = AT91C_BASE_PMC->PMC_MCFR & AT91C_CKGR_MAINF; + Dbprintf(" Slow clock old measured value:.........%d Hz", (16 * MAINCK) / mainf); + TimingIntervalAcquisition(); + mainf = AT91C_BASE_PMC->PMC_MCFR & AT91C_CKGR_MAINF; + Dbprintf(""); // first message gets lost + Dbprintf(" Slow clock new measured value:.........%d Hz", (16 * MAINCK) / mainf); + reply_ng(CMD_TIA, PM3_SUCCESS, NULL, 0); + break; + } case CMD_STANDALONE: { RunMod(); break; diff --git a/bootrom/Makefile b/bootrom/Makefile index d666f3acd..5c7823896 100644 --- a/bootrom/Makefile +++ b/bootrom/Makefile @@ -9,6 +9,7 @@ # DO NOT use thumb mode in the phase 1 bootloader since that generates a section with glue code ARMSRC = THUMBSRC = usb_cdc.c \ + clocks.c \ bootrom.c ASMSRC = ram-reset.s flash-reset.s diff --git a/bootrom/bootrom.c b/bootrom/bootrom.c index 4b255536f..081a49c24 100644 --- a/bootrom/bootrom.c +++ b/bootrom/bootrom.c @@ -6,6 +6,7 @@ // Main code for the bootloader //----------------------------------------------------------------------------- +#include "clocks.h" #include "usb_cdc.h" #include "proxmark3_arm.h" @@ -68,45 +69,7 @@ static void ConfigClocks(void) { (1 << AT91C_ID_PWMC) | (1 << AT91C_ID_UDP); - // worst case scenario, with MAINCK = 16MHz xtal, startup delay is 1.4ms - // if SLCK slow clock runs at its worst case (max) frequency of 42kHz - // max startup delay = (1.4ms*42k)/8 = 7.356 so round up to 8 - - // enable main oscillator and set startup delay - AT91C_BASE_PMC->PMC_MOR = - AT91C_CKGR_MOSCEN | - PMC_MAIN_OSC_STARTUP_DELAY(8); - - // wait for main oscillator to stabilize - while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MOSCS)) {}; - - // PLL output clock frequency in range 80 - 160 MHz needs CKGR_PLL = 00 - // PLL output clock frequency in range 150 - 180 MHz needs CKGR_PLL = 10 - // PLL output is MAINCK * multiplier / divisor = 16MHz * 12 / 2 = 96MHz - AT91C_BASE_PMC->PMC_PLLR = - PMC_PLL_DIVISOR(2) | - //PMC_PLL_COUNT_BEFORE_LOCK(0x10) | - PMC_PLL_COUNT_BEFORE_LOCK(0x3F) | - PMC_PLL_FREQUENCY_RANGE(0) | - PMC_PLL_MULTIPLIER(12) | - PMC_PLL_USB_DIVISOR(1); - - // wait for PLL to lock - while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCK)) {}; - - // we want a master clock (MCK) to be PLL clock / 2 = 96MHz / 2 = 48MHz - // datasheet recommends that this register is programmed in two operations - // when changing to PLL, program the prescaler first then the source - AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_PRES_CLK_2; - - // wait for main clock ready signal - while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY)) {}; - - // set the source to PLL - AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_PRES_CLK_2 | AT91C_PMC_CSS_PLL_CLK; - - // wait for main clock ready signal - while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY)) {}; + mck_from_slck_to_pll(true); } static void Fatal(void) { diff --git a/client/cmdhw.c b/client/cmdhw.c index 5dddac5fc..ec53ad2cf 100644 --- a/client/cmdhw.c +++ b/client/cmdhw.c @@ -511,6 +511,18 @@ static int CmdStatus(const char *Cmd) { return PM3_SUCCESS; } +static int CmdTia(const char *Cmd) { + (void)Cmd; // Cmd is not used so far + clearCommandBuffer(); + PrintAndLogEx(INFO, "Triggering new Timing Interval Acquisition..."); + PacketResponseNG resp; + SendCommandNG(CMD_TIA, NULL, 0); + if (WaitForResponseTimeout(CMD_TIA, &resp, 2000) == false) + PrintAndLogEx(WARNING, "Tia command failed. You probably need to unplug the Proxmark3."); + PrintAndLogEx(INFO, "TIA done."); + return PM3_SUCCESS; +} + static int CmdPing(const char *Cmd) { uint32_t len = strtol(Cmd, NULL, 0); if (len > PM3_CMD_DATA_SIZE) @@ -604,6 +616,7 @@ static command_t CommandTable[] = { {"setmux", CmdSetMux, IfPm3Present, "Set the ADC mux to a specific value"}, {"standalone", CmdStandalone, IfPm3Present, "Jump to the standalone mode"}, {"status", CmdStatus, IfPm3Present, "Show runtime status information about the connected Proxmark3"}, + {"tia", CmdTia, IfPm3Present, "Trigger a Timing Interval Acquisition to re-adjust the RealTimeCounter divider"}, {"tune", CmdTune, IfPm3Present, "Measure antenna tuning"}, {"version", CmdVersion, IfPm3Present, "Show version information about the connected Proxmark3"}, {NULL, NULL, NULL, NULL} diff --git a/common_arm/clocks.c b/common_arm/clocks.c new file mode 100644 index 000000000..a4c2d6ced --- /dev/null +++ b/common_arm/clocks.c @@ -0,0 +1,62 @@ +#include "clocks.h" +#include "proxmark3_arm.h" + +void mck_from_pll_to_slck(void) { + // switch main clk to slow clk, first CSS then PRES + AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_PRES_CLK_2 | AT91C_PMC_CSS_SLOW_CLK; + while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY)) {}; + AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_PRES_CLK | AT91C_PMC_CSS_SLOW_CLK; + while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY)) {}; + + // disable the PLL + AT91C_BASE_PMC->PMC_PLLR = 0x0; + + // disable main oscillator + AT91C_BASE_PMC->PMC_MOR = 0; +} + +void mck_from_slck_to_pll(bool cold) { + // worst case scenario, with MAINCK = 16MHz xtal, startup delay is 1.4ms + // if SLCK slow clock runs at its worst case (max) frequency of 42kHz + // max startup delay = (1.4ms*42k)/8 = 7.356 so round up to 8 + + // enable main oscillator and set startup delay if cold boot + if (cold) { + AT91C_BASE_PMC->PMC_MOR = + AT91C_CKGR_MOSCEN | + PMC_MAIN_OSC_STARTUP_DELAY(8); + } else { + AT91C_BASE_PMC->PMC_MOR = AT91C_CKGR_MOSCEN; + } + + // wait for main oscillator to stabilize + while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MOSCS)) {}; + + // PLL output clock frequency in range 80 - 160 MHz needs CKGR_PLL = 00 + // PLL output clock frequency in range 150 - 180 MHz needs CKGR_PLL = 10 + // PLL output is MAINCK * multiplier / divisor = 16MHz * 12 / 2 = 96MHz + AT91C_BASE_PMC->PMC_PLLR = + PMC_PLL_DIVISOR(2) | + //PMC_PLL_COUNT_BEFORE_LOCK(0x10) | + PMC_PLL_COUNT_BEFORE_LOCK(0x3F) | + PMC_PLL_FREQUENCY_RANGE(0) | + PMC_PLL_MULTIPLIER(12) | + PMC_PLL_USB_DIVISOR(1); + + // wait for PLL to lock + while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCK)) {}; + + // we want a master clock (MCK) to be PLL clock / 2 = 96MHz / 2 = 48MHz + // datasheet recommends that this register is programmed in two operations + // when changing to PLL, program the prescaler first then the source + AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_PRES_CLK_2 | AT91C_PMC_CSS_SLOW_CLK; + + // wait for main clock ready signal + while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY)) {}; + + // set the source to PLL + AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_PRES_CLK_2 | AT91C_PMC_CSS_PLL_CLK; + + // wait for main clock ready signal + while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY)) {}; +} diff --git a/common_arm/clocks.h b/common_arm/clocks.h new file mode 100644 index 000000000..8359dad27 --- /dev/null +++ b/common_arm/clocks.h @@ -0,0 +1,10 @@ +#ifndef _CLOCKS_H_ +#define _CLOCKS_H_ + +#include "common.h" +#include "at91sam7s512.h" + +void mck_from_pll_to_slck(void); +void mck_from_slck_to_pll(bool cold); + +#endif // _CLOCKS_H_ diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index c92a1faee..19ef27afb 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -287,6 +287,7 @@ typedef struct { #define CMD_SET_DBGMODE 0x0114 #define CMD_STANDALONE 0x0115 #define CMD_WTX 0x0116 +#define CMD_TIA 0x0117 // RDV40, Flash memory operations #define CMD_FLASHMEM_WRITE 0x0121 From 0877802dedca90b6dd741411c3a9965b0084019e Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 15 Oct 2019 18:02:19 +0200 Subject: [PATCH 0975/1854] Bumping PMC_MAIN_OSC_STARTUP_DELAY to solve slow clock on some devices, thanks @iceman1001! --- common_arm/clocks.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/common_arm/clocks.c b/common_arm/clocks.c index a4c2d6ced..3499b73d0 100644 --- a/common_arm/clocks.c +++ b/common_arm/clocks.c @@ -19,12 +19,15 @@ void mck_from_slck_to_pll(bool cold) { // worst case scenario, with MAINCK = 16MHz xtal, startup delay is 1.4ms // if SLCK slow clock runs at its worst case (max) frequency of 42kHz // max startup delay = (1.4ms*42k)/8 = 7.356 so round up to 8 + // UPDATE: + // we observed on 10% of the devices very wrong initial slow clock RC TIA measures. + // Bumping delay to 16 helps fixing the issue even on the most screwed RC. // enable main oscillator and set startup delay if cold boot if (cold) { AT91C_BASE_PMC->PMC_MOR = AT91C_CKGR_MOSCEN | - PMC_MAIN_OSC_STARTUP_DELAY(8); + PMC_MAIN_OSC_STARTUP_DELAY(16); } else { AT91C_BASE_PMC->PMC_MOR = AT91C_CKGR_MOSCEN; } From bf3ae7f00732873a893670fa6d7047eabb820da5 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 15 Oct 2019 18:07:24 +0200 Subject: [PATCH 0976/1854] perform startup delay also during TIA --- armsrc/appmain.c | 2 +- bootrom/bootrom.c | 2 +- common_arm/clocks.c | 14 +++++--------- common_arm/clocks.h | 2 +- 4 files changed, 8 insertions(+), 12 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index f2e4424ee..d75d00c14 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -307,7 +307,7 @@ void SendVersion(void) { void TimingIntervalAcquisition(void) { // trigger new acquisition by turning main oscillator off and on mck_from_pll_to_slck(); - mck_from_slck_to_pll(false); + mck_from_slck_to_pll(); // wait for MCFR and recompute RTMR scaler StartTickCount(); } diff --git a/bootrom/bootrom.c b/bootrom/bootrom.c index 081a49c24..aa633f448 100644 --- a/bootrom/bootrom.c +++ b/bootrom/bootrom.c @@ -69,7 +69,7 @@ static void ConfigClocks(void) { (1 << AT91C_ID_PWMC) | (1 << AT91C_ID_UDP); - mck_from_slck_to_pll(true); + mck_from_slck_to_pll(); } static void Fatal(void) { diff --git a/common_arm/clocks.c b/common_arm/clocks.c index 3499b73d0..c6fa874d3 100644 --- a/common_arm/clocks.c +++ b/common_arm/clocks.c @@ -15,7 +15,7 @@ void mck_from_pll_to_slck(void) { AT91C_BASE_PMC->PMC_MOR = 0; } -void mck_from_slck_to_pll(bool cold) { +void mck_from_slck_to_pll(void) { // worst case scenario, with MAINCK = 16MHz xtal, startup delay is 1.4ms // if SLCK slow clock runs at its worst case (max) frequency of 42kHz // max startup delay = (1.4ms*42k)/8 = 7.356 so round up to 8 @@ -23,14 +23,10 @@ void mck_from_slck_to_pll(bool cold) { // we observed on 10% of the devices very wrong initial slow clock RC TIA measures. // Bumping delay to 16 helps fixing the issue even on the most screwed RC. - // enable main oscillator and set startup delay if cold boot - if (cold) { - AT91C_BASE_PMC->PMC_MOR = - AT91C_CKGR_MOSCEN | - PMC_MAIN_OSC_STARTUP_DELAY(16); - } else { - AT91C_BASE_PMC->PMC_MOR = AT91C_CKGR_MOSCEN; - } + // enable main oscillator and set startup delay + AT91C_BASE_PMC->PMC_MOR = + AT91C_CKGR_MOSCEN | + PMC_MAIN_OSC_STARTUP_DELAY(16); // wait for main oscillator to stabilize while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MOSCS)) {}; diff --git a/common_arm/clocks.h b/common_arm/clocks.h index 8359dad27..1752ba4fd 100644 --- a/common_arm/clocks.h +++ b/common_arm/clocks.h @@ -5,6 +5,6 @@ #include "at91sam7s512.h" void mck_from_pll_to_slck(void); -void mck_from_slck_to_pll(bool cold); +void mck_from_slck_to_pll(void); #endif // _CLOCKS_H_ From f9157c946d544de79c444c8b390cf24514db00ed Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 15 Oct 2019 18:53:29 +0200 Subject: [PATCH 0977/1854] SLCK detection: use more available SpinDelay --- armsrc/appmain.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index d75d00c14..e70b03cf8 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -366,7 +366,7 @@ void SendStatus(void) { uint32_t delta_time = 0; uint32_t start_time = GetTickCount(); #define SLCK_CHECK_MS 50 - WaitMS(SLCK_CHECK_MS); + SpinDelay(SLCK_CHECK_MS); delta_time = GetTickCountDelta(start_time); if ((delta_time < SLCK_CHECK_MS - 1) || (delta_time > SLCK_CHECK_MS + 1)) { // error > 2% with SLCK_CHECK_MS=50 From 8ea04a42a6bd9ae6a1e02310d009e3f6d5dec056 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 16 Oct 2019 00:03:53 +0200 Subject: [PATCH 0978/1854] Use GetTickCountDelta when possible --- armsrc/iso14443a.c | 4 ++-- armsrc/mifaresim.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index db347cf13..38eb2ecb6 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -2044,7 +2044,7 @@ bool GetIso14443aAnswerFromTag_Thinfilm(uint8_t *receivedResponse, uint8_t *rec } } - if (GetTickCount() - receive_timer > 100) + if (GetTickCountDelta(receive_timer) > 100) break; } *received_len = Demod.len; @@ -2094,7 +2094,7 @@ static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receive } // timeout already in ms + 100ms guard time - if (GetTickCount() - receive_timer > timeout + 100) + if (GetTickCountDelta(receive_timer) > timeout + 100) break; } return false; diff --git a/armsrc/mifaresim.c b/armsrc/mifaresim.c index 0f912c083..cdd8b556d 100644 --- a/armsrc/mifaresim.c +++ b/armsrc/mifaresim.c @@ -1106,7 +1106,7 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1 Dbprintf("[MFEMUL_AUTH1] AUTH COMPLETED for sector %d with key %c. time=%d", cardAUTHSC, cardAUTHKEY == 0 ? 'A' : 'B', - GetTickCount() - authTimer + GetTickCountDelta(authTimer) ); } LED_C_ON(); From 2fd3095c059ec8df1104b51f7d8b9d538dacbc73 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 16 Oct 2019 01:22:45 +0200 Subject: [PATCH 0979/1854] Attempt to document clocks and timers --- doc/clocks.md | 144 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 doc/clocks.md diff --git a/doc/clocks.md b/doc/clocks.md new file mode 100644 index 000000000..3ec59f0c8 --- /dev/null +++ b/doc/clocks.md @@ -0,0 +1,144 @@ +## Slow clock + +~32kHz internal RC clock + +Can be between 22 and 42 kHz + +## Main Oscillator / MAINCK + +cf `PMC_MOR` register + +16 MHz, based on external Xtal + +## PLL clock + +cf `PMC_PLLR` register + +96 MHz (MAINCK * 12 / 2) + +## Master Clock MCK, Processor Clock PCK, USB clock UDPCK + +cf `common_arm/clocks.c` + +cf `PMC_MCKR` and `PMC_SCER` registers + +* MCK starts with RC slow clock (22 to 42 kHz). +* Then MCK configured from PLL: 48 MHz (PLL / 2) + +cf `bootrom.c`: + +PCK can be disabled to enter idle mode, but on Proxmark3 it's always on, so PCK is also 48 MHz. + +USB need to be clocked at 48 MHz from the PLL, so PLL / 2 (cf `CKGR_PLLR`). + + +## Peripheral clocks + +cf `bootrom.c`: + +Distribute MCK/PCK? clock to Parallel I/O controller, ADC, SPI, Synchronous Serial controller, PWM controller, USB. + +cf `appmain.c` + +Activate PCK0 pin as clock output, based on PLL / 4 = 24 MHz, for the FPGA. + +## 1 kHz RTC: TickCount functions + +cf `armsrc/ticks.c` + +cf `PMC_MCFR` and `RTTC_RTMR` registers for configuration, `RTTC_RTVR` register for reading value. + +Characteristics: + +* 1 kHz, 32b (49 days), if used with 16b: 65s +* Configured at boot (or TIA) with `StartTickCount()` +* Time events with `GetTickCount()`/`GetTickCountDeltaDelta()`, see example +* Coarse, based on the ~32kHz RC slow clock with some adjustment factor computed by TIA +* Maybe 2.5% error, can increase if temperature conditions change and no TIA is recomputed +* If TimingIntervalAcquisition() is called later, StartTickCount() is called again and RTC is reset + +Usage: + +``` +uint32_t ti = GetTickCount(); +...do stuff... +uint32_t delta = GetTickCountDelta(ti); +``` + +Current usages: + +* cheap random for nonces, e.g. `prng_successor(GetTickCount(), 32)` +* rough timing of some operations, only for informative purposes +* timeouts +* USB connection speed measure + +## Occasional PWM timer + +* `void SpinDelayUs(int us)` +* `void SpinDelay(int ms)` based on SpinDelayUs + +Busy wait based on 46.875 kHz PWM Channel 0, 21.3 us precision + +WARNING: timer can't measure more than 1.39 s + + +## Occasional TC0+TC1 / CountUS functions + +cf `armsrc/ticks.c` + +About 1 us precision + +* `void StartCountUS(void)` +* `uint32_t RAMFUNC GetCountUS(void)` + +Use two chainer timers TC0 and TC1. +TC0 runs at 1.5 MHz and TC1 is clocked when TC0 reaches 0xC000. + +Maximal value: 0x7fffffff = 2147 s + +Can't be used at the same time as CountSspClk or Ticks functions. + +## Occasional TC0+TC1 SSP_CLK from FPGA / CountSspClk functions + +cf `armsrc/ticks.c` + +About 1 cycle of 13.56 MHz? precision + +* `void StartCountSspClk(void)` +* `void ResetSspClk(void)` +* `uint32_t RAMFUNC GetCountSspClk(void)` +* `uint32_t RAMFUNC GetCountSspClkDelta(uint32_t start)` <= **TODO** could be used more often + +Use two chainer timers TC0 and TC1. +TC0 runs at SSP_CLK from FPGA (13.56 MHz?) and TC1 is clocked when TC0 loops. + +Usage: + +* for iso14443 commands to count field cycles +* Also usable with FPGA in LF mode ?? cf `armsrc/legicrfsim.c` SSP Clock is clocked by the FPGA at 212 kHz (subcarrier frequency) + +Can't be used at the same time as CountUS or Ticks functions. + +## Occasional TC0+TC1 / Ticks functions + +cf `armsrc/ticks.c` + +1.5 MHz + +* `void StartTicks(void)` +* `uint32_t GetTicks(void)` <= **TODO** why no GetTicksDelta ? +* `void WaitTicks(uint32_t ticks)` +* `void WaitUS(uint32_t us)` +* `void WaitMS(uint32_t ms)` +* `void StopTicks(void)` <= **TODO** why a stop for this timer and not for CountUS / CountSspClk ? + +Use two chainer timers TC0 and TC1. +TC0 runs at 1.5 MHz and TC1 is clocked when TC0 loops. + +Maximal value: 0xffffffff = 2863 s (but don't use high value with WaitTicks else you'll trigger WDT) + +Usage: + +* Timer for bitbanging, or LF stuff when you need a very precise timer + +Can't be used at the same time as CountUS or CountSspClk functions. From 260f6b9c2fc6765c9fb6447bbef39b6631eed970 Mon Sep 17 00:00:00 2001 From: Iceman Date: Wed, 16 Oct 2019 10:04:38 +0200 Subject: [PATCH 0980/1854] Update Troubleshooting.md --- doc/md/Installation_Instructions/Troubleshooting.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/doc/md/Installation_Instructions/Troubleshooting.md b/doc/md/Installation_Instructions/Troubleshooting.md index e0cf7f7aa..ab893d177 100644 --- a/doc/md/Installation_Instructions/Troubleshooting.md +++ b/doc/md/Installation_Instructions/Troubleshooting.md @@ -16,7 +16,8 @@ Always use the latest repository commits from *master* branch. There are always * [Troubles with SIM card reader](#troubles-with-sim-card-reader) * [Troubles with t5577 commands or MFC/iClass/T55x7 dictionaries](#troubles-with-t5577-commands-or-mfciclasst55x7-dictionaries) * [File not found](#file-not-found) - * [pixmap / pixbuf warnings](#pixmap--pixbuf-warnings) + * [Pixmap / pixbuf warnings](#pixmap--pixbuf-warnings) + * [Usb cable](#usb-cable) ## `pm3` or `pm3-flash*` doesn't see my Proxmark @@ -154,6 +155,12 @@ pm3 --> sc upgrade f ../tools/simmodule/sim011.bin etc. -## pixmap / pixbuf warnings +## Pixmap / pixbuf warnings If you get warnings related to pixmap or pixbuf such as *Pixbuf theme: Cannot load pixmap file* or *Invalid borders specified for theme pixmap*, it's a problem of your Theme, try another one and the problem should vanish. See e.g. [#354](https://github.com/RfidResearchGroup/proxmark3/issues/354) (Yaru theme on Ubuntu) and [#386](https://github.com/RfidResearchGroup/proxmark3/issues/386) (Kali-X theme on Kali). + +## Usb cable + +It's needed to have a good USB cable to connect Proxmark3 to USB. If you have stability problems (Proxmark3 resets, firmware hangs, especially firmware hangs just after start, etc.) + +- check your cable with a USB tester (or try to change it). It needs to have a resistance smaller or equal to 0.3 Ohm. From 8a91880e332085b60c99af1b147ca477170383d8 Mon Sep 17 00:00:00 2001 From: Iceman Date: Wed, 16 Oct 2019 10:05:21 +0200 Subject: [PATCH 0981/1854] Update README.md --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 62c3add53..350763c34 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,8 @@ This repo compiles nicely on - WSL, WSL2 (Windows subsystem linux) on Windows 10 - Docker container +The [public roadmap](https://github.com/RfidResearchGroup/proxmark3/wiki/Public-Roadmap) is an excellent start to read if you are interesting in contributing. + > 👉 **Remember!** If you intend to contribute to the code, please read the [coding style notes](HACKING.md) first. We usually merge your contributions fast since we do like the idea of getting a functionality in the Proxmark3 and weed out the bugs afterwards. @@ -93,7 +95,8 @@ The new universal GUI will work. [Proxmark3 Universal GUI](https://github.com/bu Please see the [Proxmark Forum](http://www.proxmark.org/forum/index.php) and see if your issue is listed in the first instance Google is your friend :) Questions will be answered via the forum by Iceman and the team. -It's needed to have a good USB cable to connect Proxmark3 to USB. If you have stability problems (Proxmark3 resets, firmware hangs, especially firmware hangs just after start, etc.) - check your cable with a USB tester (or try to change it). It needs to have a resistance smaller or equal to 0.3 Ohm. +Read the [Troubleshooting](/doc/md/Installation_Instructions/Troubleshooting.md) guide to weed out most known problems. + ## The end From bae3f65db6f9793fe346c7739377553a3ea62721 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 16 Oct 2019 10:22:41 +0200 Subject: [PATCH 0982/1854] textual --- client/cmdlfnoralsy.c | 2 +- client/cmdlfpresco.c | 2 +- client/cmdlfpyramid.c | 2 +- client/cmdlfviking.c | 4 ++-- client/cmdlfvisa2000.c | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/client/cmdlfnoralsy.c b/client/cmdlfnoralsy.c index 79fbb3913..06186099c 100644 --- a/client/cmdlfnoralsy.c +++ b/client/cmdlfnoralsy.c @@ -219,7 +219,7 @@ static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, {"demod", CmdNoralsyDemod, AlwaysAvailable, "Demodulate an Noralsy tag from the GraphBuffer"}, {"read", CmdNoralsyRead, IfPm3Lf, "Attempt to read and extract tag data from the antenna"}, - {"clone", CmdNoralsyClone, IfPm3Lf, "clone Noralsy to T55x7"}, + {"clone", CmdNoralsyClone, IfPm3Lf, "clone Noralsy to T55x7 (or to q5/T5555)"}, {"sim", CmdNoralsySim, IfPm3Lf, "simulate Noralsy tag"}, {NULL, NULL, NULL, NULL} }; diff --git a/client/cmdlfpresco.c b/client/cmdlfpresco.c index 06645e86f..abce377f4 100644 --- a/client/cmdlfpresco.c +++ b/client/cmdlfpresco.c @@ -176,7 +176,7 @@ static int CmdPrescoSim(const char *Cmd) { static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, {"read", CmdPrescoRead, IfPm3Lf, "Attempt to read and Extract tag data"}, - {"clone", CmdPrescoClone, IfPm3Lf, "clone presco tag"}, + {"clone", CmdPrescoClone, IfPm3Lf, "clone presco tag to T55x7 (or to q5/T5555)"}, {"sim", CmdPrescoSim, IfPm3Lf, "simulate presco tag"}, {NULL, NULL, NULL, NULL} }; diff --git a/client/cmdlfpyramid.c b/client/cmdlfpyramid.c index d8c9511a6..a36bd34e3 100644 --- a/client/cmdlfpyramid.c +++ b/client/cmdlfpyramid.c @@ -300,7 +300,7 @@ static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "this help"}, {"demod", CmdPyramidDemod, AlwaysAvailable, "demodulate a Pyramid FSK tag from the GraphBuffer"}, {"read", CmdPyramidRead, IfPm3Lf, "attempt to read and extract tag data"}, - {"clone", CmdPyramidClone, IfPm3Lf, "clone pyramid tag"}, + {"clone", CmdPyramidClone, IfPm3Lf, "clone pyramid tag to T55x7 (or to q5/T5555)"}, {"sim", CmdPyramidSim, IfPm3Lf, "simulate pyramid tag"}, {NULL, NULL, NULL, NULL} }; diff --git a/client/cmdlfviking.c b/client/cmdlfviking.c index 3a2ad6a5d..6221c73f3 100644 --- a/client/cmdlfviking.c +++ b/client/cmdlfviking.c @@ -160,8 +160,8 @@ static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, {"demod", CmdVikingDemod, AlwaysAvailable, "Demodulate a Viking tag from the GraphBuffer"}, {"read", CmdVikingRead, IfPm3Lf, "Attempt to read and Extract tag data from the antenna"}, - {"clone", CmdVikingClone, IfPm3Lf, "<8 digit ID number> clone viking tag"}, - {"sim", CmdVikingSim, IfPm3Lf, "<8 digit ID number> simulate viking tag"}, + {"clone", CmdVikingClone, IfPm3Lf, "clone viking to T55x7 (or to q5/T5555)"}, + {"sim", CmdVikingSim, IfPm3Lf, "simulate viking tag"}, {NULL, NULL, NULL, NULL} }; diff --git a/client/cmdlfvisa2000.c b/client/cmdlfvisa2000.c index a32dc5aeb..3fd1f7b94 100644 --- a/client/cmdlfvisa2000.c +++ b/client/cmdlfvisa2000.c @@ -228,7 +228,7 @@ static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, {"demod", CmdVisa2kDemod, AlwaysAvailable, "demodulate an VISA2000 tag from the GraphBuffer"}, {"read", CmdVisa2kRead, IfPm3Lf, "attempt to read and extract tag data from the antenna"}, - {"clone", CmdVisa2kClone, IfPm3Lf, "clone Visa2000 to t55x7"}, + {"clone", CmdVisa2kClone, IfPm3Lf, "clone Visa2000 to T55x7 (or to q5/T5555)"}, {"sim", CmdVisa2kSim, IfPm3Lf, "simulate Visa2000 tag"}, {NULL, NULL, NULL, NULL} }; From db3da4d22451d95ad8d5ba431751a198617ec43f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 16 Oct 2019 10:28:53 +0200 Subject: [PATCH 0983/1854] textual --- client/cmdlfnexwatch.c | 2 +- client/cmdlfpac.c | 2 +- client/cmdlfparadox.c | 2 +- client/cmdlfsecurakey.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/client/cmdlfnexwatch.c b/client/cmdlfnexwatch.c index 8d40d47d6..1a204ed41 100644 --- a/client/cmdlfnexwatch.c +++ b/client/cmdlfnexwatch.c @@ -152,7 +152,7 @@ static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, {"demod", CmdNexWatchDemod, AlwaysAvailable, "Demodulate a NexWatch tag (nexkey, quadrakey) from the GraphBuffer"}, {"read", CmdNexWatchRead, IfPm3Lf, "Attempt to Read and Extract tag data from the antenna"}, - {"clone", CmdNexWatchClone, IfPm3Lf, "clone NexWatch tag"}, + {"clone", CmdNexWatchClone, IfPm3Lf, "clone NexWatch tag to T55x7"}, {"sim", CmdNexWatchSim, IfPm3Lf, "simulate NexWatch tag"}, {NULL, NULL, NULL, NULL} }; diff --git a/client/cmdlfpac.c b/client/cmdlfpac.c index 9b735f02e..eb1b20cd9 100644 --- a/client/cmdlfpac.c +++ b/client/cmdlfpac.c @@ -135,7 +135,7 @@ static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, {"demod", CmdPacDemod, AlwaysAvailable, "Demodulate an PAC tag from the GraphBuffer"}, {"read", CmdPacRead, IfPm3Lf, "Attempt to read and extract tag data from the antenna"}, - {"clone", CmdPacClone, IfPm3Lf, "clone PAC tag"}, + {"clone", CmdPacClone, IfPm3Lf, "clone PAC tag to T55x7"}, {"sim", CmdPacSim, IfPm3Lf, "simulate PAC tag"}, {NULL, NULL, NULL, NULL} }; diff --git a/client/cmdlfparadox.c b/client/cmdlfparadox.c index d2c8d64b5..c154e7efa 100644 --- a/client/cmdlfparadox.c +++ b/client/cmdlfparadox.c @@ -224,7 +224,7 @@ static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, {"demod", CmdParadoxDemod, AlwaysAvailable, "Demodulate a Paradox FSK tag from the GraphBuffer"}, {"read", CmdParadoxRead, IfPm3Lf, "Attempt to read and Extract tag data from the antenna"}, - {"clone", CmdParadoxClone, IfPm3Lf, "clone paradox tag"}, + {"clone", CmdParadoxClone, IfPm3Lf, "clone paradox tag to T55x7"}, {"sim", CmdParadoxSim, IfPm3Lf, "simulate paradox tag"}, {NULL, NULL, NULL, NULL} }; diff --git a/client/cmdlfsecurakey.c b/client/cmdlfsecurakey.c index 64e8a2121..48ec731ce 100644 --- a/client/cmdlfsecurakey.c +++ b/client/cmdlfsecurakey.c @@ -180,7 +180,7 @@ static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, {"demod", CmdSecurakeyDemod, AlwaysAvailable, "Demodulate an Securakey tag from the GraphBuffer"}, {"read", CmdSecurakeyRead, IfPm3Lf, "Attempt to read and extract tag data from the antenna"}, - {"clone", CmdSecurakeyClone, IfPm3Lf, "clone Securakey tag"}, + {"clone", CmdSecurakeyClone, IfPm3Lf, "clone Securakey tag to T55x7"}, {"sim", CmdSecurakeySim, IfPm3Lf, "simulate Securakey tag"}, {NULL, NULL, NULL, NULL} }; From cec9330a79464795ae599f7f64f0f54cdbb1d707 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 16 Oct 2019 10:32:50 +0200 Subject: [PATCH 0984/1854] textual --- client/cmdlfgallagher.c | 2 +- client/cmdlfguard.c | 2 +- client/cmdlfhid.c | 2 +- client/cmdlfindala.c | 2 +- client/cmdlfio.c | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/client/cmdlfgallagher.c b/client/cmdlfgallagher.c index d32c9ade9..f8d513a13 100644 --- a/client/cmdlfgallagher.c +++ b/client/cmdlfgallagher.c @@ -135,7 +135,7 @@ static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, {"demod", CmdGallagherDemod, AlwaysAvailable, "Demodulate an GALLAGHER tag from the GraphBuffer"}, {"read", CmdGallagherRead, IfPm3Lf, "Attempt to read and extract tag data from the antenna"}, - {"clone", CmdGallagherClone, IfPm3Lf, "clone GALLAGHER tag"}, + {"clone", CmdGallagherClone, IfPm3Lf, "clone GALLAGHER tag to T55x7"}, {"sim", CmdGallagherSim, IfPm3Lf, "simulate GALLAGHER tag"}, {NULL, NULL, NULL, NULL} }; diff --git a/client/cmdlfguard.c b/client/cmdlfguard.c index a8cd8a65b..79ec13c71 100644 --- a/client/cmdlfguard.c +++ b/client/cmdlfguard.c @@ -238,7 +238,7 @@ static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "this help"}, {"demod", CmdGuardDemod, AlwaysAvailable, "demodulate a G Prox II tag from the GraphBuffer"}, {"read", CmdGuardRead, IfPm3Lf, "attempt to read and extract tag data from the antenna"}, - {"clone", CmdGuardClone, IfPm3Lf, "clone Guardall tag"}, + {"clone", CmdGuardClone, IfPm3Lf, "clone Guardall tag to T55x7"}, {"sim", CmdGuardSim, IfPm3Lf, "simulate Guardall tag"}, {NULL, NULL, NULL, NULL} }; diff --git a/client/cmdlfhid.c b/client/cmdlfhid.c index 004248e43..f5ad3717b 100644 --- a/client/cmdlfhid.c +++ b/client/cmdlfhid.c @@ -452,7 +452,7 @@ static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "this help"}, {"demod", CmdHIDDemod, AlwaysAvailable, "demodulate HID Prox tag from the GraphBuffer"}, {"read", CmdHIDRead, IfPm3Lf, "attempt to read and extract tag data"}, - {"clone", CmdHIDClone, IfPm3Lf, "clone HID to T55x7"}, + {"clone", CmdHIDClone, IfPm3Lf, "clone HID tag to T55x7"}, {"sim", CmdHIDSim, IfPm3Lf, "simulate HID tag"}, {"brute", CmdHIDBrute, IfPm3Lf, "bruteforce card number against reader"}, {"watch", CmdHIDWatch, IfPm3Lf, "continuously watch for cards. Reader mode"}, diff --git a/client/cmdlfindala.c b/client/cmdlfindala.c index e57368400..443435f88 100644 --- a/client/cmdlfindala.c +++ b/client/cmdlfindala.c @@ -534,7 +534,7 @@ static command_t CommandTable[] = { {"demod", CmdIndalaDemod, AlwaysAvailable, "demodulate an indala tag (PSK1) from GraphBuffer"}, {"altdemod", CmdIndalaDemodAlt, AlwaysAvailable, "alternative method to Demodulate samples for Indala 64 bit UID (option '224' for 224 bit)"}, {"read", CmdIndalaRead, IfPm3Lf, "read an Indala Prox tag from the antenna"}, - {"clone", CmdIndalaClone, IfPm3Lf, "clone Indala to T55x7"}, + {"clone", CmdIndalaClone, IfPm3Lf, "clone Indala tag to T55x7"}, {"sim", CmdIndalaSim, IfPm3Lf, "simulate Indala tag"}, {NULL, NULL, NULL, NULL} }; diff --git a/client/cmdlfio.c b/client/cmdlfio.c index 3aefd7b55..57a8a64d1 100644 --- a/client/cmdlfio.c +++ b/client/cmdlfio.c @@ -282,7 +282,7 @@ static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "this help"}, {"demod", CmdIOProxDemod, AlwaysAvailable, "demodulate an IOProx tag from the GraphBuffer"}, {"read", CmdIOProxRead, IfPm3Lf, "attempt to read and extract tag data"}, - {"clone", CmdIOProxClone, IfPm3Lf, "clone IOProx to T55x7"}, + {"clone", CmdIOProxClone, IfPm3Lf, "clone IOProx tag to T55x7 (or to q5/T5555)"}, {"sim", CmdIOProxSim, IfPm3Lf, "simulate IOProx tag"}, {"watch", CmdIOProxWatch, IfPm3Lf, "continuously watch for cards. Reader mode"}, {NULL, NULL, NULL, NULL} From 726c421b1e5622fc50827c4f4fe1613a01a29cb6 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 16 Oct 2019 10:38:05 +0200 Subject: [PATCH 0985/1854] textual --- client/cmdlfawid.c | 2 +- client/cmdlfjablotron.c | 2 +- client/cmdlfkeri.c | 2 +- client/cmdlfmotorola.c | 2 +- client/cmdlfnoralsy.c | 2 +- client/cmdlfviking.c | 4 ++-- client/cmdlfvisa2000.c | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/client/cmdlfawid.c b/client/cmdlfawid.c index afd2206f3..e9fe6d6e1 100644 --- a/client/cmdlfawid.c +++ b/client/cmdlfawid.c @@ -523,7 +523,7 @@ static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "this help"}, {"demod", CmdAWIDDemod, AlwaysAvailable, "demodulate an AWID FSK tag from the GraphBuffer"}, {"read", CmdAWIDRead, IfPm3Lf, "attempt to read and extract tag data"}, - {"clone", CmdAWIDClone, IfPm3Lf, "clone AWID to T55x7"}, + {"clone", CmdAWIDClone, IfPm3Lf, "clone AWID tag to T55x7 (or to q5/T5555)"}, {"sim", CmdAWIDSim, IfPm3Lf, "simulate AWID tag"}, {"brute", CmdAWIDBrute, IfPm3Lf, "Bruteforce card number against reader"}, {"watch", CmdAWIDWatch, IfPm3Lf, "continuously watch for cards. Reader mode"}, diff --git a/client/cmdlfjablotron.c b/client/cmdlfjablotron.c index 3633902f2..a1f5b0592 100644 --- a/client/cmdlfjablotron.c +++ b/client/cmdlfjablotron.c @@ -217,7 +217,7 @@ static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, {"demod", CmdJablotronDemod, AlwaysAvailable, "Demodulate an Jablotron tag from the GraphBuffer"}, {"read", CmdJablotronRead, IfPm3Lf, "Attempt to read and extract tag data from the antenna"}, - {"clone", CmdJablotronClone, IfPm3Lf, "clone jablotron tag"}, + {"clone", CmdJablotronClone, IfPm3Lf, "clone jablotron tag to T55x7 (or to q5/T5555)"}, {"sim", CmdJablotronSim, IfPm3Lf, "simulate jablotron tag"}, {NULL, NULL, NULL, NULL} }; diff --git a/client/cmdlfkeri.c b/client/cmdlfkeri.c index 9e9bbdb49..b36be56b9 100644 --- a/client/cmdlfkeri.c +++ b/client/cmdlfkeri.c @@ -209,7 +209,7 @@ static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, {"demod", CmdKeriDemod, AlwaysAvailable, "Demodulate an KERI tag from the GraphBuffer"}, {"read", CmdKeriRead, IfPm3Lf, "Attempt to read and extract tag data from the antenna"}, - {"clone", CmdKeriClone, IfPm3Lf, "clone KERI to T55x7"}, + {"clone", CmdKeriClone, IfPm3Lf, "clone KERI tag to T55x7 (or to q5/T5555)"}, {"sim", CmdKeriSim, IfPm3Lf, "simulate KERI tag"}, {NULL, NULL, NULL, NULL} }; diff --git a/client/cmdlfmotorola.c b/client/cmdlfmotorola.c index e306827ed..87ea53a3b 100644 --- a/client/cmdlfmotorola.c +++ b/client/cmdlfmotorola.c @@ -192,7 +192,7 @@ static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, {"demod", CmdMotorolaDemod, AlwaysAvailable, "Demodulate an MOTOROLA tag from the GraphBuffer"}, {"read", CmdMotorolaRead, IfPm3Lf, "Attempt to read and extract tag data from the antenna"}, - {"clone", CmdMotorolaClone, IfPm3Lf, "clone MOTOROLA to T55x7"}, + {"clone", CmdMotorolaClone, IfPm3Lf, "clone MOTOROLA tag to T55x7"}, {"sim", CmdMotorolaSim, IfPm3Lf, "simulate MOTOROLA tag"}, {NULL, NULL, NULL, NULL} }; diff --git a/client/cmdlfnoralsy.c b/client/cmdlfnoralsy.c index 06186099c..ceebb8e2d 100644 --- a/client/cmdlfnoralsy.c +++ b/client/cmdlfnoralsy.c @@ -219,7 +219,7 @@ static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, {"demod", CmdNoralsyDemod, AlwaysAvailable, "Demodulate an Noralsy tag from the GraphBuffer"}, {"read", CmdNoralsyRead, IfPm3Lf, "Attempt to read and extract tag data from the antenna"}, - {"clone", CmdNoralsyClone, IfPm3Lf, "clone Noralsy to T55x7 (or to q5/T5555)"}, + {"clone", CmdNoralsyClone, IfPm3Lf, "clone Noralsy tag to T55x7 (or to q5/T5555)"}, {"sim", CmdNoralsySim, IfPm3Lf, "simulate Noralsy tag"}, {NULL, NULL, NULL, NULL} }; diff --git a/client/cmdlfviking.c b/client/cmdlfviking.c index 6221c73f3..c404b4f0a 100644 --- a/client/cmdlfviking.c +++ b/client/cmdlfviking.c @@ -160,8 +160,8 @@ static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, {"demod", CmdVikingDemod, AlwaysAvailable, "Demodulate a Viking tag from the GraphBuffer"}, {"read", CmdVikingRead, IfPm3Lf, "Attempt to read and Extract tag data from the antenna"}, - {"clone", CmdVikingClone, IfPm3Lf, "clone viking to T55x7 (or to q5/T5555)"}, - {"sim", CmdVikingSim, IfPm3Lf, "simulate viking tag"}, + {"clone", CmdVikingClone, IfPm3Lf, "clone Viking tag to T55x7 (or to q5/T5555)"}, + {"sim", CmdVikingSim, IfPm3Lf, "simulate Viking tag"}, {NULL, NULL, NULL, NULL} }; diff --git a/client/cmdlfvisa2000.c b/client/cmdlfvisa2000.c index 3fd1f7b94..677562e12 100644 --- a/client/cmdlfvisa2000.c +++ b/client/cmdlfvisa2000.c @@ -228,7 +228,7 @@ static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, {"demod", CmdVisa2kDemod, AlwaysAvailable, "demodulate an VISA2000 tag from the GraphBuffer"}, {"read", CmdVisa2kRead, IfPm3Lf, "attempt to read and extract tag data from the antenna"}, - {"clone", CmdVisa2kClone, IfPm3Lf, "clone Visa2000 to T55x7 (or to q5/T5555)"}, + {"clone", CmdVisa2kClone, IfPm3Lf, "clone Visa2000 tag to T55x7 (or to q5/T5555)"}, {"sim", CmdVisa2kSim, IfPm3Lf, "simulate Visa2000 tag"}, {NULL, NULL, NULL, NULL} }; From abf81bbbb7659af0d774f624ed633f7072f90c53 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 16 Oct 2019 10:42:58 +0200 Subject: [PATCH 0986/1854] log help as well, for consistent logging experience --- client/cmdparser.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdparser.c b/client/cmdparser.c index f116b5ecd..52d4e805e 100644 --- a/client/cmdparser.c +++ b/client/cmdparser.c @@ -156,7 +156,7 @@ void CmdsHelp(const command_t Commands[]) { while (Commands[i].Name) { if (Commands[i].IsAvailable()) // PrintAndLogEx(NORMAL, _GREEN_("%-16s")" %s", Commands[i].Name, Commands[i].Help); - printf(_GREEN_("%-16s")" %s\n", Commands[i].Name, Commands[i].Help); + PrintAndLogEx(NORMAL, _GREEN_("%-16s")" %s", Commands[i].Name, Commands[i].Help); ++i; } } From f9bf50e20b7170d34e93d776a4e7e6bc360c0dbe Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 16 Oct 2019 10:43:32 +0200 Subject: [PATCH 0987/1854] add xrefs between t55 menu and lf clone commands --- client/cmdlft55xx.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 1607dc746..6332a77dd 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -373,6 +373,32 @@ static int usage_t55xx_dangerraw() { static int CmdHelp(const char *Cmd); +static int CmdT55xxCloneHelp(const char *Cmd) { + (void)Cmd; // Cmd is not used so far + PrintAndLogEx(NORMAL, "For cloning specific techs on T55xx tags, see commands available in corresponding LF sub-menus, e.g.:"); + PrintAndLogEx(NORMAL, _GREEN_("lf awid clone")); + PrintAndLogEx(NORMAL, _GREEN_("lf em 410x_write")); + PrintAndLogEx(NORMAL, _GREEN_("lf fdx clone")); + PrintAndLogEx(NORMAL, _GREEN_("lf gallagher clone")); + PrintAndLogEx(NORMAL, _GREEN_("lf gproxii clone")); + PrintAndLogEx(NORMAL, _GREEN_("lf hid clone")); + PrintAndLogEx(NORMAL, _GREEN_("lf indala clone")); + PrintAndLogEx(NORMAL, _GREEN_("lf io clone")); + PrintAndLogEx(NORMAL, _GREEN_("lf jablotron clone")); + PrintAndLogEx(NORMAL, _GREEN_("lf keri clone")); + PrintAndLogEx(NORMAL, _GREEN_("lf nedap clone")); + PrintAndLogEx(NORMAL, _GREEN_("lf noralsy clone")); + PrintAndLogEx(NORMAL, _GREEN_("lf motorola clone")); + PrintAndLogEx(NORMAL, _GREEN_("lf pac clone")); + PrintAndLogEx(NORMAL, _GREEN_("lf paradox clone")); + PrintAndLogEx(NORMAL, _GREEN_("lf presco clone")); + PrintAndLogEx(NORMAL, _GREEN_("lf pyramid clone")); + PrintAndLogEx(NORMAL, _GREEN_("lf securakey clone")); + PrintAndLogEx(NORMAL, _GREEN_("lf viking clone")); + PrintAndLogEx(NORMAL, _GREEN_("lf visa2000 clone")); + return PM3_SUCCESS; +} + void T55x7_SaveBlockData(uint8_t idx, uint32_t data) { if (idx < T55x7_BLOCK_COUNT) { cardmem[idx].valid = true; @@ -3652,6 +3678,7 @@ static command_t CommandTable[] = { {"bruteforce", CmdT55xxBruteForce, IfPm3Lf, " Simple bruteforce attack to find password"}, {"config", CmdT55xxSetConfig, AlwaysAvailable, "Set/Get T55XX configuration (modulation, inverted, offset, rate)"}, {"chk", CmdT55xxChkPwds, IfPm3Lf, "Check passwords from dictionary/flash"}, + {"clonehelp", CmdT55xxCloneHelp, IfPm3Lf, "Shows the available clone commands"}, {"dangerraw", CmdT55xxDangerousRaw, IfPm3Lf, "Sends raw bitstream. Dangerous, do not use!! b t "}, {"detect", CmdT55xxDetect, AlwaysAvailable, "[1] Try detecting the tag modulation from reading the configuration block."}, {"deviceconfig", CmdT55xxSetDeviceConfig, IfPm3Lf, "Set/Get T55XX device configuration (startgap, writegap, write0, write1, readgap"}, From cce04ef93cbe15c637adc352540e5bd2dc7ff319 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 16 Oct 2019 10:57:14 +0200 Subject: [PATCH 0988/1854] textual --- client/cmdlft55xx.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 6332a77dd..e1f84b32b 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -371,13 +371,14 @@ static int usage_t55xx_dangerraw() { return PM3_SUCCESS; } -static int CmdHelp(const char *Cmd); - -static int CmdT55xxCloneHelp(const char *Cmd) { - (void)Cmd; // Cmd is not used so far +static int usage_t55xx_clonehelp(){ PrintAndLogEx(NORMAL, "For cloning specific techs on T55xx tags, see commands available in corresponding LF sub-menus, e.g.:"); PrintAndLogEx(NORMAL, _GREEN_("lf awid clone")); +// todo: rename to clone PrintAndLogEx(NORMAL, _GREEN_("lf em 410x_write")); +// todo: implement restore +// PrintAndLogEx(NORMAL, _GREEN_("lf em 4x05_write")); +// PrintAndLogEx(NORMAL, _GREEN_("lf em 4x50_write")); PrintAndLogEx(NORMAL, _GREEN_("lf fdx clone")); PrintAndLogEx(NORMAL, _GREEN_("lf gallagher clone")); PrintAndLogEx(NORMAL, _GREEN_("lf gproxii clone")); @@ -399,6 +400,13 @@ static int CmdT55xxCloneHelp(const char *Cmd) { return PM3_SUCCESS; } +static int CmdHelp(const char *Cmd); + +static int CmdT55xxCloneHelp(const char *Cmd) { + (void)Cmd; // Cmd is not used so far + return usage_t55xx_clonehelp(); +} + void T55x7_SaveBlockData(uint8_t idx, uint32_t data) { if (idx < T55x7_BLOCK_COUNT) { cardmem[idx].valid = true; From c3c45e03ce6216eefa46ac92357cd8b4dad00a21 Mon Sep 17 00:00:00 2001 From: mwalker33 Date: Wed, 16 Oct 2019 20:24:03 +1100 Subject: [PATCH 0989/1854] Update proxmark3.c --- client/proxmark3.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/client/proxmark3.c b/client/proxmark3.c index db8434e07..ceabbc6f3 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -684,6 +684,8 @@ int main(int argc, char *argv[]) { } session.supports_colors = false; +/* + // Removed color on windows until a better option can be implemented. #if defined(_WIN32) // Check if windows AnsiColor Support is enabled in the registery @@ -711,6 +713,7 @@ int main(int argc, char *argv[]) { } #endif +*/ session.stdinOnTTY = isatty(STDIN_FILENO); session.stdoutOnTTY = isatty(STDOUT_FILENO); From 9d3331511b92c685e125a9b79723e1583bf57a94 Mon Sep 17 00:00:00 2001 From: Thomas Sutter Date: Wed, 16 Oct 2019 14:17:52 +0200 Subject: [PATCH 0990/1854] Fix FeliCa select_card. Selection works now for FeliCa standard cards. Fix SendRaw data. Add some new unfinished cmds. --- armsrc/felica.c | 219 +++++++++++++++++++++++++++++++++---------- armsrc/felica.h | 6 ++ client/cmdhffelica.c | 110 ++++++++++++++++------ client/cmdhffelica.h | 2 + 4 files changed, 257 insertions(+), 80 deletions(-) diff --git a/armsrc/felica.c b/armsrc/felica.c index 322d11327..0dfad3a61 100644 --- a/armsrc/felica.c +++ b/armsrc/felica.c @@ -14,17 +14,17 @@ // FeliCa timings // minimum time between the start bits of consecutive transfers from reader to tag: 6800 carrier (13.56MHz) cycles #ifndef FELICA_REQUEST_GUARD_TIME -# define FELICA_REQUEST_GUARD_TIME (6800/16 + 1) +# define FELICA_REQUEST_GUARD_TIME (6800/16 + 1) // 426 #endif // FRAME DELAY TIME 2672 carrier cycles #ifndef FELICA_FRAME_DELAY_TIME -# define FELICA_FRAME_DELAY_TIME (2672/16 + 1) +# define FELICA_FRAME_DELAY_TIME (2672/16 + 1) // 168 #endif #ifndef DELAY_AIR2ARM_AS_READER -#define DELAY_AIR2ARM_AS_READER (3 + 16 + 8 + 8*16 + 4*16 - 8*16) +#define DELAY_AIR2ARM_AS_READER (3 + 16 + 8 + 8*16 + 4*16 - 8*16) // 27 + 128 + 64 - 128 = 91 #endif #ifndef DELAY_ARM2AIR_AS_READER -#define DELAY_ARM2AIR_AS_READER (4*16 + 8*16 + 8 + 8 + 1) +#define DELAY_ARM2AIR_AS_READER (4*16 + 8*16 + 8 + 8 + 1) // 64 + 128 + 17 = 209 #endif // CRC skips two first sync bits in data buffer @@ -111,7 +111,7 @@ static void shiftInByte(uint8_t bt) { static void Process18092Byte(uint8_t bt) { switch (FelicaFrame.state) { case STATE_UNSYNCD: { - //almost any nonzero byte can be start of SYNC. SYNC should be preceded by zeros, but that is not alsways the case + //almost any nonzero byte can be start of SYNC. SYNC should be preceded by zeros, but that is not always the case if (bt > 0) { FelicaFrame.shiftReg = reflect8(bt); FelicaFrame.state = STATE_TRYING_SYNC; @@ -175,13 +175,11 @@ static void Process18092Byte(uint8_t bt) { } case STATE_GET_CRC: { shiftInByte(bt); - if (FelicaFrame.rem_len <= 0) { + FelicaFrame.rem_len = 0; // skip sync 2bytes. IF ok, residue should be 0x0000 FelicaFrame.crc_ok = check_crc(CRC_FELICA, FelicaFrame.framebytes + 2, FelicaFrame.len - 2); FelicaFrame.state = STATE_FULL; - FelicaFrame.rem_len = 0; - if (DBGLEVEL > 3) Dbprintf("[+] got 2 crc bytes [%s]", (FelicaFrame.crc_ok) ? "OK" : "No"); } break; } @@ -194,6 +192,7 @@ static void Process18092Byte(uint8_t bt) { /* Perform FeliCa polling card * Currently does NOT do any collision handling. * It expects 0-1 cards in the device's range. + * return 0 if selection was successful */ static uint8_t felica_select_card(felica_card_select_t *card) { @@ -201,17 +200,16 @@ static uint8_t felica_select_card(felica_card_select_t *card) { // 0xB2 0x4B = sync code // 0x06 = len // 0x00 = rfu - // 0xff = system service - // 0xff = system service - // 0x00 = - // b7 = automatic switching of data rate - // b6-b2 = reserved - // b1 = fc/32 (414kbps) - // b0 = fc/64 (212kbps) + // 0xff = system code service + // 0xff = system code service + // 0x00 = request code + // b7 = automatic switching of data rate + // b6-b2 = reserved + // b1 = fc/32 (414kbps) + // b0 = fc/64 (212kbps) // 0x00 = timeslot // 0x09 0x21 = crc static uint8_t poll[10] = {0xb2, 0x4d, 0x06, FELICA_POLL_REQ, 0xFF, 0xFF, 0x00, 0x00, 0x09, 0x21}; - int len = 20; // We try 20 times, or if answer was received. @@ -222,7 +220,7 @@ static uint8_t felica_select_card(felica_card_select_t *card) { TransmitFor18092_AsReader(poll, sizeof(poll), NULL, 1, 0); // polling card, break if success - if (WaitForFelicaReply(512) && FelicaFrame.framebytes[3] == FELICA_POLL_ACK) + if (WaitForFelicaReply(1024) && FelicaFrame.framebytes[3] == FELICA_POLL_ACK) break; WDT_HIT(); @@ -230,17 +228,31 @@ static uint8_t felica_select_card(felica_card_select_t *card) { } while (--len); // timed-out - if (len == 0) + if (len == 0){ + if (DBGLEVEL > 3) + Dbprintf("Error: Time out card selection!"); return 1; + } // wrong answer - if (FelicaFrame.framebytes[3] != FELICA_POLL_ACK) + if (FelicaFrame.framebytes[3] != FELICA_POLL_ACK){ + if (DBGLEVEL > 3) + Dbprintf("Error: Wrong answer selecting card!"); return 2; + } // VALIDATE CRC residue is 0, hence if crc is a value it failed. - if (!check_crc(CRC_FELICA, FelicaFrame.framebytes + 2, FelicaFrame.len - 2)) + if (!check_crc(CRC_FELICA, FelicaFrame.framebytes + 2, FelicaFrame.len - 2)){ + if (DBGLEVEL > 3){ + Dbprintf("Error: CRC check failed!"); + Dbprintf("CRC check was done on Frame: "); + Dbhexdump(FelicaFrame.len - 2, FelicaFrame.framebytes + 2, 0); + } return 3; + } + if (DBGLEVEL > 3) + Dbprintf("Card selection successful!"); // copy UID // idm 8 if (card) { @@ -251,7 +263,10 @@ static uint8_t felica_select_card(felica_card_select_t *card) { memcpy(card->uid, card->IDm + 2, 6); memcpy(card->iccode, card->PMm, 2); memcpy(card->mrt, card->PMm + 2, 6); - + if (DBGLEVEL > 3){ + Dbprintf("Received Frame: "); + Dbhexdump(FelicaFrame.len, FelicaFrame.framebytes, 0); + } } // more status bytes? return 0; @@ -349,10 +364,13 @@ static void TransmitFor18092_AsReader(uint8_t *frame, int len, uint32_t *timing, c++; } } - // sending sync code - - // sending data + // sending data with sync bytes c = 0; + if (DBGLEVEL > 3){ + Dbprintf("Sending frame:"); + Dbhexdump(len, frame, 0); + } + while (c < len) { // Put byte into tx holding register as soon as it is ready @@ -386,22 +404,21 @@ static void TransmitFor18092_AsReader(uint8_t *frame, int len, uint32_t *timing, // stop when button is pressed // or return TRUE when command is captured bool WaitForFelicaReply(uint16_t maxbytes) { - + if (DBGLEVEL > 3) + Dbprintf("WaitForFelicaReply Start"); uint32_t c = 0; - // power, no modulation FpgaWriteConfWord(FPGA_MAJOR_MODE_ISO18092 | FPGA_HF_ISO18092_FLAG_READER | FPGA_HF_ISO18092_FLAG_NOMOD); - FelicaFrameReset(); // clear RXRDY: uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - (void)b; - uint32_t timeout = iso18092_get_timeout(); + if (DBGLEVEL > 3) + Dbprintf("timeout set: %i", timeout); + //TODO FIX THIS METHOD - Race Condition or something: TIMING/MEMORY ISSUES for (;;) { WDT_HIT(); - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { b = (uint8_t)(AT91C_BASE_SSC->SSC_RHR); Process18092Byte(b); @@ -410,8 +427,7 @@ bool WaitForFelicaReply(uint16_t maxbytes) { MAX( felica_nexttransfertime, (GetCountSspClk() & 0xfffffff8) - (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER) / 16 + FELICA_FRAME_DELAY_TIME - ) - ; + ); LogTrace( FelicaFrame.framebytes, @@ -421,22 +437,20 @@ bool WaitForFelicaReply(uint16_t maxbytes) { NULL, false ); + if (DBGLEVEL > 3) Dbprintf("All bytes received! STATE_FULL"); return true; } else if (c++ > timeout && FelicaFrame.state == STATE_UNSYNCD) { + if (DBGLEVEL > 3) Dbprintf("Error: Timeout! STATE_UNSYNCD"); return false; - } else if (FelicaFrame.state == STATE_GET_CRC) { - Dbprintf(" Frame: "); - Dbhexdump(16, FelicaFrame.framebytes, 0); - //return false; - } + } // If you add content here, timing problems appear?! } } - return false; } // Set up FeliCa communication (similar to iso14443a_setup) // field is setup for "Sending as Reader" static void iso18092_setup(uint8_t fpga_minor_mode) { + if (DBGLEVEL > 3) Dbprintf("Start iso18092_setup"); LEDsoff(); FpgaDownloadAndGo(FPGA_BITSTREAM_HF); @@ -481,7 +495,6 @@ static void iso18092_setup(uint8_t fpga_minor_mode) { // arg1 len of commandbytes // d.asBytes command bytes to send void felica_sendraw(PacketCommandNG *c) { - if (DBGLEVEL > 3) Dbprintf("FeliCa_sendraw Enter"); felica_command_t param = c->oldarg[0]; @@ -492,21 +505,25 @@ void felica_sendraw(PacketCommandNG *c) { felica_card_select_t card; if ((param & FELICA_CONNECT)) + if (DBGLEVEL > 3) Dbprintf("Clear trace"); clear_trace(); set_tracing(true); + iso18092_setup(FPGA_HF_ISO18092_FLAG_READER | FPGA_HF_ISO18092_FLAG_NOMOD); if ((param & FELICA_CONNECT)) { - iso18092_setup(FPGA_HF_ISO18092_FLAG_READER | FPGA_HF_ISO18092_FLAG_NOMOD); - // notify client selecting status. // if failed selecting, turn off antenna and quite. if (!(param & FELICA_NO_SELECT)) { arg0 = felica_select_card(&card); reply_old(CMD_ACK, arg0, sizeof(card.uid), 0, &card, sizeof(felica_card_select_t)); - if (arg0 > 0) - goto OUT; + if (arg0 > 0){ + Dbprintf("Error: Failed selecting card! "); + } + goto OUT; } + }else{ + if (DBGLEVEL > 3) Dbprintf("No card selection"); } if ((param & FELICA_RAW)) { @@ -527,22 +544,32 @@ void felica_sendraw(PacketCommandNG *c) { AddCrc(buf, len); } } - + if (DBGLEVEL > 3) { + Dbprintf("Transmit Frame (no CRC shown):"); + Dbhexdump(len, buf, 0); + Dbprintf("Buffer Length: %i", buf[2] + 4); + }; TransmitFor18092_AsReader(buf, buf[2] + 4, NULL, 1, 0); - arg0 = !WaitForFelicaReply(1024); + arg0 = WaitForFelicaReply(1024); + if (DBGLEVEL > 3) { + Dbprintf("Received Frame: %d", arg0); + Dbhexdump(FelicaFrame.len, FelicaFrame.framebytes, 0); + }; reply_old(CMD_ACK, arg0, 0, 0, FelicaFrame.framebytes + 2, FelicaFrame.len - 2); + FelicaFrameReset(); } if ((param & FELICA_NO_DISCONNECT)) + Dbprintf("Disconnect"); return; -OUT: - switch_off(); + OUT: + switch_off(); - //Resetting Frame mode (First set in fpgaloader.c) - AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(8) | AT91C_SSC_MSBF | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0); + //Resetting Frame mode (First set in fpgaloader.c) + AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(8) | AT91C_SSC_MSBF | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0); - if (DBGLEVEL > 3) Dbprintf("FeliCa_sendraw Exit"); + if (DBGLEVEL > 3) Dbprintf("FeliCa_sendraw Exit"); } void felica_sniff(uint32_t samplesToSkip, uint32_t triggersToSkip) { @@ -722,8 +749,98 @@ void felica_sim_lite(uint64_t uid) { DbpString("Felica Lite-S sim end"); } -void felica_dump_lite_s() { +void felica_dump(){ + uint8_t ndef[8]; + uint8_t poll[10] = { 0xb2, 0x4d, 0x06, FELICA_POLL_REQ, 0xff, 0xff, 0x00, 0x00, 0x09, 0x21}; // B24D0600FFFF00000921 + iso18092_setup(FPGA_HF_ISO18092_FLAG_READER | FPGA_HF_ISO18092_FLAG_NOMOD); + TransmitFor18092_AsReader(poll, 10, NULL, 1, 0); + while (!BUTTON_PRESS() && !data_available()) { + WDT_HIT(); + TransmitFor18092_AsReader(poll, 10, NULL, 1, 0); + if (WaitForFelicaReply(512) && FelicaFrame.framebytes[3] == FELICA_POLL_ACK) { + memcpy(ndef, FelicaFrame.framebytes + 4, 8); + uint8_t *request_service = felica_create_request_service_frame(0x01, ndef); + felica_send_request_service(request_service); + } + } +} + +void felica_send_request_service(uint8_t *request_service){ + uint8_t len = sizeof(request_service) / sizeof((request_service)[0]); + Dbprintf("Send Service Request - len: d%", len); + TransmitFor18092_AsReader(request_service, len, NULL, 1, 0); + if (WaitForFelicaReply(512) && FelicaFrame.framebytes[3] == FELICA_REQSRV_ACK) { + Dbprintf("Got Service Response!"); + } +} + +/* Create Request Service Frame +// Use this command to verify the existence of Area and Service, and to acquire Key Version. +// When the specified Area or Service exists, the card returns Key Version. +// When the specified Area or Service does not exist, the card returns FFFFh as Key Version. +*/ +uint8_t * felica_create_request_service_frame(uint8_t nodeNumber, uint8_t *idm){ + if(nodeNumber < 1 && nodeNumber > 32){ + Dbprintf("Node number out of range: 1 <= %d <= 32 - set node number to 1"); + nodeNumber = 1; + } + // Sync 2-Byte, Length 1-Byte, CMD 1-Byte, IDm 8-Byte, nodeNumber 1 <= n <= 32 1-Byte, Node Code List + uint8_t *request_service = BigBuf_malloc(sizeof(uint8_t)*11); + //{ 0xb2, 0x4d, 0x06, FELICA_REQSRV_REQ, 0xff, 0xff, 0x00, 0x00, 0x09, 0x21}; + request_service[0] = 0xb2; //Sync + request_service[1] = 0x4d; //Sync + request_service[2] = 0x0B; // Length + request_service[3] = FELICA_REQSRV_REQ; // CMD + request_service[4] = idm[0]; + request_service[5] = idm[1]; + request_service[6] = idm[2]; + request_service[7] = idm[3]; + request_service[8] = idm[4]; + request_service[9] = idm[5]; + request_service[9] = idm[6]; + request_service[9] = idm[7]; + request_service[10] = nodeNumber; // Node we like to ask for services + request_service[11] = 0x00; // Node Code List // TODO FIND OUT WHAT NEEDS TO BE IN HERE + return request_service; +} + +// Create Frame for authentication1 CMD +void felica_create_authentication1_frame(){ + +} + +// Create Frame for authentication2 CMD +void felica_create_authentication2_frame(){ + +} + +// Create a Frame for Read without encryption CMD as Payload +void felica_create_read_block_frame(uint16_t blockNr){ + if(blockNr < 1 || blockNr > 567){ + Dbprintf("Block number out of range!"); + return; + } + uint8_t c = 0; + // First Byte of SYNC + frameSpace[c++] = 0xb2; + frameSpace[c++] = 0x4d; + // skip Length of Frame + c++; + // Payload + frameSpace[c++] = FELICA_RDBLK_REQ; //command number + + // Set frame length + + // CRC +} + +void felica_read_block(uint8_t *idm, uint16_t blockNr){ + + +} + +void felica_dump_lite_s() { uint8_t ndef[8]; uint8_t poll[10] = { 0xb2, 0x4d, 0x06, FELICA_POLL_REQ, 0xff, 0xff, 0x00, 0x00, 0x09, 0x21}; uint16_t liteblks[28] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x90, 0x91, 0x92, 0xa0}; diff --git a/armsrc/felica.h b/armsrc/felica.h index ef34dc108..f160a0edf 100644 --- a/armsrc/felica.h +++ b/armsrc/felica.h @@ -18,5 +18,11 @@ void felica_sendraw(PacketCommandNG *c); void felica_sniff(uint32_t samplesToSkip, uint32_t triggersToSkip); void felica_sim_lite(uint64_t uid); void felica_dump_lite_s(); +void felica_dump(); +void felica_create_read_block_frame(uint16_t blockNr); +void felica_create_authentication1_frame(); +void felica_create_authentication2_frame(); +void felica_send_request_service(uint8_t *request_service); +uint8_t * felica_create_request_service_frame(uint8_t nodeNumber, uint8_t *idm); #endif diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index 333498f37..8a8d08ec0 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -39,6 +39,7 @@ static int usage_hf_felica_sim(void) { return 0; } */ + static int usage_hf_felica_sniff(void) { PrintAndLogEx(NORMAL, "It get data from the field and saves it into command buffer."); PrintAndLogEx(NORMAL, "Buffer accessible from command 'hf list felica'"); @@ -80,6 +81,12 @@ static int usage_hf_felica_raw(void) { return 0; } +static int usage_hf_felica_dump(void) { + PrintAndLogEx(NORMAL, "Usage: hf felica dump [-h] "); + PrintAndLogEx(NORMAL, " -h this help"); + return 0; +} + static int CmdHFFelicaList(const char *Cmd) { (void)Cmd; // Cmd is not used so far //PrintAndLogEx(NORMAL, "Deprecated command, use 'hf list felica' instead"); @@ -93,6 +100,12 @@ static int CmdHFFelicaReader(const char *Cmd) { return 0; } +static int CmdHFFelicaDump(const char *Cmd) { + if (strlen(Cmd) < 1) return usage_hf_felica_dump(); + dump(*Cmd); + return 0; +} + // simulate iso18092 / FeliCa tag // Commented, there is no counterpart in ARM at the moment /* @@ -351,7 +364,7 @@ static uint16_t PrintFliteBlock(uint16_t tracepos, uint8_t *trace, uint16_t trac PrintAndLogEx(NORMAL, "Authenticated: %s", trace[3] ? "yes" : "no"); break; case 0xa0: - PrintAndLogEx(NORMAL, "CRC of all bloacks match : %s", (trace[3 + 2] == 0xff) ? "no" : "yes"); + PrintAndLogEx(NORMAL, "CRC of all blocks match : %s", (trace[3 + 2] == 0xff) ? "no" : "yes"); break; default: PrintAndLogEx(WARNING, "INVALID %d: %s", blocknum, line); @@ -393,8 +406,10 @@ static int CmdHFFelicaDumpLite(const char *Cmd) { } uint32_t tracelen = resp.oldarg[1]; - if (tracelen == 0) + if (tracelen == 0){ + PrintAndLogEx(WARNING, "\nNo trace data! Maybe not a FeliCa Lite card?"); return 1; + } uint8_t *trace = calloc(tracelen, sizeof(uint8_t)); if (trace == NULL) { @@ -408,7 +423,7 @@ static int CmdHFFelicaDumpLite(const char *Cmd) { return 0; } - PrintAndLogEx(SUCCESS, "Recorded Activity (trace len = %"PRIu32" bytes)", tracelen); + PrintAndLogEx(SUCCESS, "Recorded Activity (trace len = %"PRIu64" bytes)", tracelen); print_hex_break(trace, tracelen, 32); printSep(); @@ -427,7 +442,7 @@ static void waitCmdFelica(uint8_t iSelect) { PacketResponseNG resp; if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { - uint16_t len = iSelect ? (resp.oldarg[1] & 0xffff) : (resp.oldarg[0] & 0xffff); + uint16_t len = iSelect ? (resp.oldarg[1] & 0xffff) : (resp.oldarg[0] & 0xffff); PrintAndLogEx(NORMAL, "received %i octets", len); if (!len) return; @@ -435,6 +450,7 @@ static void waitCmdFelica(uint8_t iSelect) { } else { PrintAndLogEx(WARNING, "timeout while waiting for reply."); } + } static int CmdHFFelicaCmdRaw(const char *Cmd) { @@ -516,8 +532,8 @@ static int CmdHFFelicaCmdRaw(const char *Cmd) { if (crc && datalen > 0 && datalen < sizeof(data) - 2) { uint8_t b1, b2; compute_crc(CRC_FELICA, data, datalen, &b1, &b2); - data[datalen++] = b1; data[datalen++] = b2; + data[datalen++] = b1; } uint8_t flags = 0; @@ -543,6 +559,7 @@ static int CmdHFFelicaCmdRaw(const char *Cmd) { if (reply) { if (active_select) + PrintAndLogEx(NORMAL, "Active select wait for FeliCa."); waitCmdFelica(1); if (datalen > 0) waitCmdFelica(0); @@ -550,30 +567,6 @@ static int CmdHFFelicaCmdRaw(const char *Cmd) { return 0; } -static command_t CommandTable[] = { - {"help", CmdHelp, AlwaysAvailable, "This help"}, - {"list", CmdHFFelicaList, AlwaysAvailable, "List ISO 18092/FeliCa history"}, - {"reader", CmdHFFelicaReader, IfPm3Felica, "Act like an ISO18092/FeliCa reader"}, -// {"sim", CmdHFFelicaSim, IfPm3Felica, " -- Simulate ISO 18092/FeliCa tag"}, - {"sniff", CmdHFFelicaSniff, IfPm3Felica, "sniff ISO 18092/Felica traffic"}, - {"raw", CmdHFFelicaCmdRaw, IfPm3Felica, "Send raw hex data to tag"}, - - {"litesim", CmdHFFelicaSimLite, IfPm3Felica, " - only reply to poll request"}, - {"litedump", CmdHFFelicaDumpLite, IfPm3Felica, "Wait for and try dumping FelicaLite"}, - {NULL, NULL, NULL, NULL} -}; - -static int CmdHelp(const char *Cmd) { - (void)Cmd; // Cmd is not used so far - CmdsHelp(CommandTable); - return 0; -} - -int CmdHFFelica(const char *Cmd) { - clearCommandBuffer(); - return CmdsParse(CommandTable, Cmd); -} - int readFelicaUid(bool verbose) { clearCommandBuffer(); @@ -587,6 +580,7 @@ int readFelicaUid(bool verbose) { felica_card_select_t card; memcpy(&card, (felica_card_select_t *)resp.data.asBytes, sizeof(felica_card_select_t)); + PrintAndLogEx(NORMAL, "Received bytes: \n%s", sprint_hex(resp.data.asBytes, sizeof(resp.data.asBytes))); uint64_t status = resp.oldarg[0]; switch (status) { @@ -622,3 +616,61 @@ int readFelicaUid(bool verbose) { } return status; } + +// TODO FINISH THIS METHOD +int dump(const char *Cmd){ + clearCommandBuffer(); + char ctmp = tolower(param_getchar(Cmd, 0)); + if (ctmp == 'h') return usage_hf_felica_dumplite(); + + PrintAndLogEx(SUCCESS, "FeliCa - dump started"); + clearCommandBuffer(); + SendCommandNG(CMD_HF_FELICALITE_DUMP, NULL, 0); + PacketResponseNG resp; + + uint8_t timeout = 0; + while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { + timeout++; + printf("."); + fflush(stdout); + if (kbd_enter_pressed()) { + PrintAndLogEx(WARNING, "\n[!] aborted via keyboard!\n"); + DropField(); + return 1; + } + if (timeout > 100) { + PrintAndLogEx(WARNING, "timeout while waiting for reply."); + DropField(); + return 1; + } + } + if (resp.oldarg[0] == 0) { + PrintAndLogEx(WARNING, "\nButton pressed. Aborted."); + return 1; + } + return 0; +} + +static command_t CommandTable[] = { + {"help", CmdHelp, AlwaysAvailable, "This help"}, + {"list", CmdHFFelicaList, AlwaysAvailable, "List ISO 18092/FeliCa history"}, + {"reader", CmdHFFelicaReader, IfPm3Felica, "Act like an ISO18092/FeliCa reader"}, +// {"sim", CmdHFFelicaSim, IfPm3Felica, " -- Simulate ISO 18092/FeliCa tag"}, + {"sniff", CmdHFFelicaSniff, IfPm3Felica, "sniff ISO 18092/Felica traffic"}, + {"raw", CmdHFFelicaCmdRaw, IfPm3Felica, "Send raw hex data to tag"}, + {"dump", CmdHFFelicaDump, IfPm3Felica, "Wait for and try dumping Felica"}, + {"litesim", CmdHFFelicaSimLite, IfPm3Felica, " - only reply to poll request"}, + {"litedump", CmdHFFelicaDumpLite, IfPm3Felica, "Wait for and try dumping FelicaLite"}, + {NULL, NULL, NULL, NULL} +}; + +static int CmdHelp(const char *Cmd) { + (void)Cmd; // Cmd is not used so far + CmdsHelp(CommandTable); + return 0; +} + +int CmdHFFelica(const char *Cmd) { + clearCommandBuffer(); + return CmdsParse(CommandTable, Cmd); +} diff --git a/client/cmdhffelica.h b/client/cmdhffelica.h index 4193235f5..abbbd42a4 100644 --- a/client/cmdhffelica.h +++ b/client/cmdhffelica.h @@ -16,4 +16,6 @@ int CmdHFFelica(const char *Cmd); int readFelicaUid(bool verbose); + +int dump(); #endif From 5737355985e28af306a8566e12fce69a3cff12cd Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 16 Oct 2019 14:46:57 +0200 Subject: [PATCH 0991/1854] chg renable win ansi test. trying turning offlogging. @doegox can refacor this away when we get a prefs.json settings file --- client/cmdparser.c | 6 +++-- client/proxmark3.c | 65 ++++++++++++++++++++++++---------------------- 2 files changed, 38 insertions(+), 33 deletions(-) diff --git a/client/cmdparser.c b/client/cmdparser.c index 52d4e805e..72628f2fb 100644 --- a/client/cmdparser.c +++ b/client/cmdparser.c @@ -154,9 +154,11 @@ void CmdsHelp(const command_t Commands[]) { if (Commands[0].Name == NULL) return; int i = 0; while (Commands[i].Name) { - if (Commands[i].IsAvailable()) -// PrintAndLogEx(NORMAL, _GREEN_("%-16s")" %s", Commands[i].Name, Commands[i].Help); + if (Commands[i].IsAvailable()) { + g_printAndLog = PRINTANDLOG_PRINT; PrintAndLogEx(NORMAL, _GREEN_("%-16s")" %s", Commands[i].Name, Commands[i].Help); + g_printAndLog = PRINTANDLOG_PRINT | PRINTANDLOG_LOG; + } ++i; } } diff --git a/client/proxmark3.c b/client/proxmark3.c index ceabbc6f3..fb02396bd 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -29,6 +29,8 @@ static void showBanner(void) { + g_printAndLog = PRINTANDLOG_PRINT; + PrintAndLogEx(NORMAL, "\n"); #if defined(__linux__) || (__APPLE__) || (_WIN32) PrintAndLogEx(NORMAL, _BLUE_("██████╗ ███╗ ███╗ ████╗ ") " ...iceman fork"); @@ -50,6 +52,8 @@ static void showBanner(void) { // printf("\nMonero: 43mNJLpgBVaTvyZmX9ajcohpvVkaRy1kbZPm8tqAb7itZgfuYecgkRF36rXrKFUkwEGeZedPsASRxgv4HPBHvJwyJdyvQuP"); PrintAndLogEx(NORMAL, "\n"); fflush(stdout); + + g_printAndLog = PRINTANDLOG_PRINT | PRINTANDLOG_LOG; } int check_comm(void) { @@ -466,6 +470,35 @@ finish2: return ret; } +// Check if windows AnsiColor Support is enabled in the registery +// [HKEY_CURRENT_USER\Console] +// "VirtualTerminalLevel"=dword:00000001 +static bool DetectWindowsAnsiSupport(void) { + bool ret = false; +#if defined(_WIN32) + HKEY hKey = NULL; + + if (RegOpenKeyA(HKEY_CURRENT_USER, "Console", &hKey) == ERROR_SUCCESS) { + DWORD dwType = REG_SZ; + BYTE KeyValue[sizeof(dwType)]; + DWORD len = sizeof(KeyValue); + + if (RegQueryValueEx(hKey, "VirtualTerminalLevel", NULL, &dwType, KeyValue, &len) != ERROR_FILE_NOT_FOUND) { + uint8_t i; + uint32_t Data = 0; + for (i = 0; i < 4; i++) + Data += KeyValue[i] << (8 * i); + + if (Data == 1) { // Reg key is set to 1, Ansi Color Enabled + ret = true; + } + } + RegCloseKey(hKey); + } +#endif + return ret; +} + int main(int argc, char *argv[]) { srand(time(0)); @@ -683,37 +716,7 @@ int main(int argc, char *argv[]) { return 1; } - session.supports_colors = false; -/* - // Removed color on windows until a better option can be implemented. - -#if defined(_WIN32) - // Check if windows AnsiColor Support is enabled in the registery - // [HKEY_CURRENT_USER\Console] - // "VirtualTerminalLevel"=dword:00000001 - - HKEY hKey = NULL; - - if (RegOpenKeyA(HKEY_CURRENT_USER, "Console", &hKey) == ERROR_SUCCESS) { - DWORD dwType = REG_SZ; - BYTE KeyValue[sizeof(dwType)]; - DWORD len = sizeof(KeyValue); - - if (RegQueryValueEx(hKey, "VirtualTerminalLevel", NULL, &dwType, KeyValue, &len) != ERROR_FILE_NOT_FOUND) { - uint8_t i; - uint32_t Data = 0; - for (i = 0; i < 4; i++) - Data += KeyValue[i] << (8 * i); - - if (Data == 1) { // Reg key is set to 1, Ansi Color Enabled - session.supports_colors = true; - } - } - RegCloseKey(hKey); - } - -#endif -*/ + session.supports_colors = DetectWindowsAnsiSupport(); session.stdinOnTTY = isatty(STDIN_FILENO); session.stdoutOnTTY = isatty(STDOUT_FILENO); From 224b03a1f875181c493652971dca7d3dd340b046 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 16 Oct 2019 15:09:20 +0200 Subject: [PATCH 0992/1854] chg printf.. --- client/guidummy.cpp | 3 ++- client/hardnested/hardnested_bruteforce.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/client/guidummy.cpp b/client/guidummy.cpp index 8557b0015..2ea6c2e46 100644 --- a/client/guidummy.cpp +++ b/client/guidummy.cpp @@ -9,12 +9,13 @@ //----------------------------------------------------------------------------- #include +#include "ui.h" extern "C" void ShowGraphWindow(void) { static int warned = 0; if (!warned) { - printf("No GUI in this build!\n"); + PrintAndLogEx(INFO, "No GUI in this build!"); warned = 1; } } diff --git a/client/hardnested/hardnested_bruteforce.c b/client/hardnested/hardnested_bruteforce.c index 3aea34a96..4af190d71 100644 --- a/client/hardnested/hardnested_bruteforce.c +++ b/client/hardnested/hardnested_bruteforce.c @@ -164,7 +164,7 @@ crack_states_thread(void *x) { statelist_t *bucket = buckets[current_bucket]; if (bucket) { #if defined (DEBUG_BRUTE_FORCE) - printf("Thread %u starts working on bucket %u\n", thread_id, current_bucket); + PrintAndLogEx(INFO, "Thread %u starts working on bucket %u\n", thread_id, current_bucket); #endif const uint64_t key = crack_states_bitsliced(thread_arg->cuid, thread_arg->best_first_bytes, bucket, &keys_found, &num_keys_tested, nonces_to_bruteforce, bf_test_nonce_2nd_byte, thread_arg->nonces); if (key != -1) { From 801ace94a21d434af5afe9f8038ffa1bca157a73 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 16 Oct 2019 15:37:39 +0200 Subject: [PATCH 0993/1854] dummy gui compilation on OSX.. --- client/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/Makefile b/client/Makefile index 58bdf7592..1fef2cd9b 100644 --- a/client/Makefile +++ b/client/Makefile @@ -109,9 +109,11 @@ ifneq ($(SKIPQT),1) endif ifneq ($(QTLDLIBS),) + QTGUISRCS = proxgui.cpp proxguiqt.cpp proxguiqt.moc.cpp QTGUIOBJS = $(OBJDIR)/proxgui.o $(OBJDIR)/proxguiqt.o $(OBJDIR)/proxguiqt.moc.o PM3CFLAGS += -DHAVE_GUI else + QTGUISRCS = guidummy.cpp QTGUIOBJS = $(OBJDIR)/guidummy.o endif @@ -257,7 +259,6 @@ ifeq ($(MULTIARCHSRCS), ) CMDSRCS += hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c endif -QTGUISRCS = proxgui.cpp proxguiqt.cpp proxguiqt.moc.cpp guidummy.cpp COREOBJS = $(CORESRCS:%.c=$(OBJDIR)/%.o) CMDOBJS = $(CMDSRCS:%.c=$(OBJDIR)/%.o) From aa46570208112421f54fc70c3c121c088073c632 Mon Sep 17 00:00:00 2001 From: Iceman Date: Wed, 16 Oct 2019 15:41:03 +0200 Subject: [PATCH 0994/1854] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 350763c34..b306ad542 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # RRG / Iceman repo - Proxmark3 -This repo is based on iceman fork for Proxmark3. It supports other Proxmark3 platforms as well. +This repo is based on iceman fork for Proxmark3. -It is dedicated to bringing the most out of the new features for Proxmark3 RDV4.0 new hardware and design. +It supports RDV4.0 and other Proxmark3 platforms as well. | Releases | Linux & OSX CI | Windows CI | Coverity | From ce4711cc13b5a0520a159545ed9f79bf039c84d5 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 16 Oct 2019 15:45:52 +0200 Subject: [PATCH 0995/1854] revert printf --- client/guidummy.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/client/guidummy.cpp b/client/guidummy.cpp index 2ea6c2e46..8557b0015 100644 --- a/client/guidummy.cpp +++ b/client/guidummy.cpp @@ -9,13 +9,12 @@ //----------------------------------------------------------------------------- #include -#include "ui.h" extern "C" void ShowGraphWindow(void) { static int warned = 0; if (!warned) { - PrintAndLogEx(INFO, "No GUI in this build!"); + printf("No GUI in this build!\n"); warned = 1; } } From 51022d4329ef4afaa74fe28141d2a112ad2095cc Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 16 Oct 2019 14:24:23 -0400 Subject: [PATCH 0996/1854] textual --- armsrc/spiffs.c | 72 +++++++++++++++++++++++++++++++------------------ 1 file changed, 46 insertions(+), 26 deletions(-) diff --git a/armsrc/spiffs.c b/armsrc/spiffs.c index 629dff422..f242062be 100644 --- a/armsrc/spiffs.c +++ b/armsrc/spiffs.c @@ -536,21 +536,28 @@ int rdv40_spiffs_read_as_filetype(char *filename, uint8_t *dst, uint32_t size, R //////////////////////////////////////////////////////////////////////////////// ///////// MISC HIGH LEVEL FUNCTIONS //////////////////////////////////////////// +#define SPIFFS_BANNER DbpString(_BLUE_("Flash Memory FileSystem tree (SPIFFS)")); void rdv40_spiffs_safe_print_fsinfo() { rdv40_spiffs_fsinfo fsinfo; rdv40_spiffs_getfsinfo(&fsinfo, RDV40_SPIFFS_SAFETY_SAFE); + DbpString(_BLUE_("Flash Memory FileSystem Info (SPIFFS)")); - Dbprintf("-------------------------------------"); - Dbprintf("* Filesystem Logical Block Size.........%d bytes", fsinfo.blockSize); - Dbprintf("* Filesystem Logical Page Size..........%d bytes", fsinfo.pageSize); - Dbprintf("--"); - Dbprintf("* Filesystem Max Open Files.............%d file descriptors", fsinfo.maxOpenFiles); - Dbprintf("* Filesystem Max Path Length............%d chars", fsinfo.maxPathLength); - Dbprintf("--"); - Dbprintf("Filesystem\tSize\tUsed\tAvailable\tUse%\tMounted on"); - Dbprintf("spiffs\t%dB\t%dB\t%dB\t\t%d%\t/", fsinfo.totalBytes, fsinfo.usedBytes, fsinfo.freeBytes, - fsinfo.usedPercent); + + + Dbprintf(" Logical Block Size........." _YELLOW_("%d")"bytes", fsinfo.blockSize); + Dbprintf(" Logical Page Size.........." _YELLOW_("%d")"bytes", fsinfo.pageSize); + Dbprintf(""); + Dbprintf(" Max Open Files............." _YELLOW_("%d")"file descriptors", fsinfo.maxOpenFiles); + Dbprintf(" Max Path Length............" _YELLOW_("%d")"chars", fsinfo.maxPathLength); + DbpString(""); + Dbprintf(" filesystem size used available use% mounted"); + Dbprintf(" spiffs %6d B %6d B %6d B"_YELLOW_("%2d%")" /" + , fsinfo.totalBytes + , fsinfo.usedBytes + , fsinfo.freeBytes + , fsinfo.usedPercent + ); } // this function is safe and WILL rollback since it is only a PRINTING function, @@ -562,14 +569,16 @@ void rdv40_spiffs_safe_print_fsinfo() { // dont want, as prefix are way easier and lighter in every aspect. void rdv40_spiffs_safe_print_tree(uint8_t banner) { - int changed = rdv40_spiffs_lazy_mount(); - spiffs_DIR d; - struct spiffs_dirent e; - struct spiffs_dirent *pe = &e; if (banner) { DbpString(_BLUE_("Flash Memory FileSystem tree (SPIFFS)")); Dbprintf("-------------------------------------"); } + + int changed = rdv40_spiffs_lazy_mount(); + spiffs_DIR d; + struct spiffs_dirent e; + struct spiffs_dirent *pe = &e; + SPIFFS_opendir(&fs, "/", &d); Dbprintf(" \t \t/"); while ((pe = SPIFFS_readdir(&d, pe))) { @@ -592,29 +601,40 @@ void rdv40_spiffs_safe_print_tree(uint8_t banner) { rdv40_spiffs_lazy_mount_rollback(changed); } + +// Selftest function void test_spiffs() { - Dbprintf("---------------------------"); + Dbprintf("----------------------------------------------"); Dbprintf("Testing SPIFFS operations"); - Dbprintf("---------------------------"); - Dbprintf("(all test are made using lazy safetylevel)"); - Dbprintf("* Mounting filesystem (lazy)......."); + Dbprintf("----------------------------------------------"); + Dbprintf("-- all test are made using lazy safetylevel"); + + Dbprintf(" Mounting filesystem (lazy)......."); int changed = rdv40_spiffs_lazy_mount(); - Dbprintf("* Printing tree.............."); + + Dbprintf(" Printing tree.............."); rdv40_spiffs_safe_print_tree(false); - Dbprintf("* Writing 'I love Proxmark' in a testspiffs.txt"); + + Dbprintf(" Writing 'I love Proxmark3 RDV4' in a testspiffs.txt"); + // Since We lazy_mounted manually before hand, the wrte safety level will // just imply noops - rdv40_spiffs_write((char *)"testspiffs.txt", (uint8_t *)"I love Proxmark", 15, RDV40_SPIFFS_SAFETY_SAFE); - Dbprintf("* Printing tree again......."); + rdv40_spiffs_write((char *)"testspiffs.txt", (uint8_t *)"I love Proxmark3 RDV4", 21, RDV40_SPIFFS_SAFETY_SAFE); + + Dbprintf(" Printing tree again......."); rdv40_spiffs_safe_print_tree(false); - Dbprintf("* Making a symlink to testspiffs.txt"); + + Dbprintf(" Making a symlink to testspiffs.txt"); rdv40_spiffs_make_symlink((char *)"testspiffs.txt", (char *)"linktotestspiffs.txt", RDV40_SPIFFS_SAFETY_SAFE); - Dbprintf("* Printing tree again......."); + + Dbprintf(" Printing tree again......."); rdv40_spiffs_safe_print_tree(false); + // TODO READBACK, rename,print tree read back, remove, print tree; - Dbprintf("* Rollbacking The mount status IF things have changed"); + Dbprintf(" Rollbacking The mount status IF things have changed"); rdv40_spiffs_lazy_mount_rollback(changed); - Dbprintf("All done"); + + Dbprintf(_GREEN_("All done")); return; } From 5c0dfdbf6b8cd6ec24d8ede72851d1b6cf58b416 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 17 Oct 2019 09:27:55 +0200 Subject: [PATCH 0997/1854] chg: send ref instead --- client/cmdhfmf.c | 2 +- client/mifare/mfkey.c | 44 +++++++++++++++++++++---------------------- client/mifare/mfkey.h | 6 +++--- 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 3ae332397..16e4029db 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -2920,7 +2920,7 @@ void readerAttack(nonces_t data, bool setEmulatorMem, bool verbose) { if (k_sector == NULL) emptySectorTable(); - success = mfkey32_moebius(data, &key); + success = mfkey32_moebius(&data, &key); if (success) { uint8_t sector = data.sector; uint8_t keytype = data.keytype; diff --git a/client/mifare/mfkey.c b/client/mifare/mfkey.c index bdccd302e..ee0c9f052 100644 --- a/client/mifare/mfkey.c +++ b/client/mifare/mfkey.c @@ -89,25 +89,25 @@ uint32_t nonce2key(uint32_t uid, uint32_t nt, uint32_t nr, uint32_t ar, uint64_t } // recover key from 2 different reader responses on same tag challenge -bool mfkey32(nonces_t data, uint64_t *outputkey) { +bool mfkey32(nonces_t *data, uint64_t *outputkey) { struct Crypto1State *s, *t; uint64_t outkey = 0; uint64_t key = 0; // recovered key bool isSuccess = false; uint8_t counter = 0; - uint32_t p640 = prng_successor(data.nonce, 64); + uint32_t p640 = prng_successor(data->nonce, 64); - s = lfsr_recovery32(data.ar ^ p640, 0); + s = lfsr_recovery32(data->ar ^ p640, 0); for (t = s; t->odd | t->even; ++t) { lfsr_rollback_word(t, 0, 0); - lfsr_rollback_word(t, data.nr, 1); - lfsr_rollback_word(t, data.cuid ^ data.nonce, 0); + lfsr_rollback_word(t, data->nr, 1); + lfsr_rollback_word(t, data->cuid ^ data->nonce, 0); crypto1_get_lfsr(t, &key); - crypto1_word(t, data.cuid ^ data.nonce, 0); - crypto1_word(t, data.nr2, 1); - if (data.ar2 == (crypto1_word(t, 0, 0) ^ p640)) { + crypto1_word(t, data->cuid ^ data->nonce, 0); + crypto1_word(t, data->nr2, 1); + if (data->ar2 == (crypto1_word(t, 0, 0) ^ p640)) { outkey = key; counter++; if (counter == 20) break; @@ -121,26 +121,26 @@ bool mfkey32(nonces_t data, uint64_t *outputkey) { // recover key from 2 reader responses on 2 different tag challenges // skip "several found keys". Only return true if ONE key is found -bool mfkey32_moebius(nonces_t data, uint64_t *outputkey) { +bool mfkey32_moebius(nonces_t *data, uint64_t *outputkey) { struct Crypto1State *s, *t; uint64_t outkey = 0; uint64_t key = 0; // recovered key bool isSuccess = false; int counter = 0; - uint32_t p640 = prng_successor(data.nonce, 64); - uint32_t p641 = prng_successor(data.nonce2, 64); + uint32_t p640 = prng_successor(data->nonce, 64); + uint32_t p641 = prng_successor(data->nonce2, 64); - s = lfsr_recovery32(data.ar ^ p640, 0); + s = lfsr_recovery32(data->ar ^ p640, 0); for (t = s; t->odd | t->even; ++t) { lfsr_rollback_word(t, 0, 0); - lfsr_rollback_word(t, data.nr, 1); - lfsr_rollback_word(t, data.cuid ^ data.nonce, 0); + lfsr_rollback_word(t, data->nr, 1); + lfsr_rollback_word(t, data->cuid ^ data->nonce, 0); crypto1_get_lfsr(t, &key); - crypto1_word(t, data.cuid ^ data.nonce2, 0); - crypto1_word(t, data.nr2, 1); - if (data.ar2 == (crypto1_word(t, 0, 0) ^ p641)) { + crypto1_word(t, data->cuid ^ data->nonce2, 0); + crypto1_word(t, data->nr2, 1); + if (data->ar2 == (crypto1_word(t, 0, 0) ^ p641)) { outkey = key; ++counter; if (counter == 20) break; @@ -153,20 +153,20 @@ bool mfkey32_moebius(nonces_t data, uint64_t *outputkey) { } // recover key from reader response and tag response of one authentication sequence -int mfkey64(nonces_t data, uint64_t *outputkey) { +int mfkey64(nonces_t *data, uint64_t *outputkey) { uint64_t key = 0; // recovered key uint32_t ks2; // keystream used to encrypt reader response uint32_t ks3; // keystream used to encrypt tag response struct Crypto1State *revstate; // Extract the keystream from the messages - ks2 = data.ar ^ prng_successor(data.nonce, 64); - ks3 = data.at ^ prng_successor(data.nonce, 96); + ks2 = data->ar ^ prng_successor(data->nonce, 64); + ks3 = data->at ^ prng_successor(data->nonce, 96); revstate = lfsr_recovery64(ks2, ks3); lfsr_rollback_word(revstate, 0, 0); lfsr_rollback_word(revstate, 0, 0); - lfsr_rollback_word(revstate, data.nr, 1); - lfsr_rollback_word(revstate, data.cuid ^ data.nonce, 0); + lfsr_rollback_word(revstate, data->nr, 1); + lfsr_rollback_word(revstate, data->cuid ^ data->nonce, 0); crypto1_get_lfsr(revstate, &key); crypto1_destroy(revstate); *outputkey = key; diff --git a/client/mifare/mfkey.h b/client/mifare/mfkey.h index 36ca8ed11..e108d5fa7 100644 --- a/client/mifare/mfkey.h +++ b/client/mifare/mfkey.h @@ -17,9 +17,9 @@ #include "mifare.h" uint32_t nonce2key(uint32_t uid, uint32_t nt, uint32_t nr, uint32_t ar, uint64_t par_info, uint64_t ks_info, uint64_t **keys); -bool mfkey32(nonces_t data, uint64_t *outputkey); -bool mfkey32_moebius(nonces_t data, uint64_t *outputkey); -int mfkey64(nonces_t data, uint64_t *outputkey); +bool mfkey32(nonces_t *data, uint64_t *outputkey); +bool mfkey32_moebius(nonces_t *data, uint64_t *outputkey); +int mfkey64(nonces_t *data, uint64_t *outputkey); int compare_uint64(const void *a, const void *b); uint32_t intersection(uint64_t *listA, uint64_t *listB); From 2ae2e1fff5c5d94fca579ae7ccdde817fb5fb927 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 17 Oct 2019 09:31:37 +0200 Subject: [PATCH 0998/1854] textual --- client/cmdlf.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/client/cmdlf.c b/client/cmdlf.c index 57c28c1b0..4d7c72acc 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -63,12 +63,12 @@ static int usage_lf_cmdread(void) { PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h This help"); PrintAndLogEx(NORMAL, " d delay OFF period, (0 for bitbang mode) (decimal)"); - PrintAndLogEx(NORMAL, " z time period ZERO, (decimal)"); - PrintAndLogEx(NORMAL, " o time period ONE, (decimal)"); - PrintAndLogEx(NORMAL, " c Command bytes (in ones and zeros)"); + PrintAndLogEx(NORMAL, " z ZERO time period (decimal)"); + PrintAndLogEx(NORMAL, " o ONE time period (decimal)"); + PrintAndLogEx(NORMAL, " c Command bytes (in ones and zeros)"); PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, " ************* All periods in microseconds (ms)"); - PrintAndLogEx(NORMAL, " ************* Use lf config to configure options."); + PrintAndLogEx(NORMAL, " ************* " _YELLOW_("All periods in microseconds (us)")); + PrintAndLogEx(NORMAL, " ************* Use " _YELLOW_("'lf config'") "to configure options."); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf cmdread d 80 z 100 o 200 c 11000"); return PM3_SUCCESS; @@ -77,7 +77,7 @@ static int usage_lf_read(void) { PrintAndLogEx(NORMAL, "Usage: lf read [h] [s] [d numofsamples]"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h This help"); - PrintAndLogEx(NORMAL, " s silent run no printout"); + PrintAndLogEx(NORMAL, " s silent run, no printout"); PrintAndLogEx(NORMAL, " d #samples # samples to collect (optional)"); PrintAndLogEx(NORMAL, "Use 'lf config' to set parameters."); PrintAndLogEx(NORMAL, ""); From 4da87d3f962eb6cb444ee402f685dcbb4950e5f5 Mon Sep 17 00:00:00 2001 From: Thomas Sutter Date: Thu, 17 Oct 2019 11:46:59 +0200 Subject: [PATCH 0999/1854] Fix Client Response for RAW command. Client should receives now all response octects. --- armsrc/felica.c | 41 ++++++++++++++++++++++++----------------- armsrc/felica.h | 1 + client/cmdhffelica.c | 44 +++++++++++--------------------------------- 3 files changed, 36 insertions(+), 50 deletions(-) diff --git a/armsrc/felica.c b/armsrc/felica.c index 0dfad3a61..26e45292c 100644 --- a/armsrc/felica.c +++ b/armsrc/felica.c @@ -417,6 +417,7 @@ bool WaitForFelicaReply(uint16_t maxbytes) { if (DBGLEVEL > 3) Dbprintf("timeout set: %i", timeout); //TODO FIX THIS METHOD - Race Condition or something: TIMING/MEMORY ISSUES + // If you add content here (dbprintf), timing problems appear?! Last Bytes (CRC) of frame will be cutoff. for (;;) { WDT_HIT(); if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { @@ -442,7 +443,7 @@ bool WaitForFelicaReply(uint16_t maxbytes) { } else if (c++ > timeout && FelicaFrame.state == STATE_UNSYNCD) { if (DBGLEVEL > 3) Dbprintf("Error: Timeout! STATE_UNSYNCD"); return false; - } // If you add content here, timing problems appear?! + } } } } @@ -488,6 +489,14 @@ static void iso18092_setup(uint8_t fpga_minor_mode) { LED_D_ON(); } + +void felica_reset_frame_mode(){ + switch_off(); + //Resetting Frame mode (First set in fpgaloader.c) + AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(8) | AT91C_SSC_MSBF | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0); +} + + //----------------------------------------------------------------------------- // RAW FeliCa commands. Send out commands and store answers. //----------------------------------------------------------------------------- @@ -516,11 +525,12 @@ void felica_sendraw(PacketCommandNG *c) { // if failed selecting, turn off antenna and quite. if (!(param & FELICA_NO_SELECT)) { arg0 = felica_select_card(&card); - reply_old(CMD_ACK, arg0, sizeof(card.uid), 0, &card, sizeof(felica_card_select_t)); + reply_mix(CMD_ACK, arg0, sizeof(card.uid), 0, &card, sizeof(felica_card_select_t)); if (arg0 > 0){ Dbprintf("Error: Failed selecting card! "); + felica_reset_frame_mode(); + return; } - goto OUT; } }else{ if (DBGLEVEL > 3) Dbprintf("No card selection"); @@ -552,24 +562,21 @@ void felica_sendraw(PacketCommandNG *c) { TransmitFor18092_AsReader(buf, buf[2] + 4, NULL, 1, 0); arg0 = WaitForFelicaReply(1024); if (DBGLEVEL > 3) { - Dbprintf("Received Frame: %d", arg0); + Dbprintf("Received Frame Code: %d", arg0); Dbhexdump(FelicaFrame.len, FelicaFrame.framebytes, 0); }; - reply_old(CMD_ACK, arg0, 0, 0, FelicaFrame.framebytes + 2, FelicaFrame.len - 2); - FelicaFrameReset(); + uint32_t result = reply_mix(CMD_ACK, FelicaFrame.len, arg0, 0, FelicaFrame.framebytes, FelicaFrame.len); + if(result){ + Dbprintf("Reply to Client Error Code: %i", result); + } } - - if ((param & FELICA_NO_DISCONNECT)) + if ((param & FELICA_NO_DISCONNECT)){ Dbprintf("Disconnect"); - return; - - OUT: - switch_off(); - - //Resetting Frame mode (First set in fpgaloader.c) - AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(8) | AT91C_SSC_MSBF | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0); - - if (DBGLEVEL > 3) Dbprintf("FeliCa_sendraw Exit"); + } + if (DBGLEVEL > 3) + Dbprintf("FeliCa_sendraw Exit"); + felica_reset_frame_mode(); + return; } void felica_sniff(uint32_t samplesToSkip, uint32_t triggersToSkip) { diff --git a/armsrc/felica.h b/armsrc/felica.h index f160a0edf..faa52aa66 100644 --- a/armsrc/felica.h +++ b/armsrc/felica.h @@ -23,6 +23,7 @@ void felica_create_read_block_frame(uint16_t blockNr); void felica_create_authentication1_frame(); void felica_create_authentication2_frame(); void felica_send_request_service(uint8_t *request_service); +void felica_reset_frame_mode(); uint8_t * felica_create_request_service_frame(uint8_t nodeNumber, uint8_t *idm); #endif diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index 8a8d08ec0..cb93d6269 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -440,17 +440,15 @@ static int CmdHFFelicaDumpLite(const char *Cmd) { static void waitCmdFelica(uint8_t iSelect) { PacketResponseNG resp; - if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { uint16_t len = iSelect ? (resp.oldarg[1] & 0xffff) : (resp.oldarg[0] & 0xffff); - PrintAndLogEx(NORMAL, "received %i octets", len); + PrintAndLogEx(NORMAL, "Client Received %i octets", len); if (!len) return; PrintAndLogEx(NORMAL, "%s", sprint_hex(resp.data.asBytes, len)); } else { - PrintAndLogEx(WARNING, "timeout while waiting for reply."); + PrintAndLogEx(WARNING, "Timeout while waiting for reply."); } - } static int CmdHFFelicaCmdRaw(const char *Cmd) { @@ -532,6 +530,7 @@ static int CmdHFFelicaCmdRaw(const char *Cmd) { if (crc && datalen > 0 && datalen < sizeof(data) - 2) { uint8_t b1, b2; compute_crc(CRC_FELICA, data, datalen, &b1, &b2); + // TODO FIND OUT IF FeliCa Light has another CRC order - Order changed for FeliCa Standard cards data[datalen++] = b2; data[datalen++] = b1; } @@ -555,14 +554,16 @@ static int CmdHFFelicaCmdRaw(const char *Cmd) { datalen = (datalen > PM3_CMD_DATA_SIZE) ? PM3_CMD_DATA_SIZE : datalen; clearCommandBuffer(); - SendCommandOLD(CMD_HF_FELICA_COMMAND, flags, (datalen & 0xFFFF) | (uint32_t)(numbits << 16), 0, data, datalen); + SendCommandMIX(CMD_HF_FELICA_COMMAND, flags, (datalen & 0xFFFF) | (uint32_t)(numbits << 16), 0, data, datalen); if (reply) { - if (active_select) + if (active_select){ PrintAndLogEx(NORMAL, "Active select wait for FeliCa."); waitCmdFelica(1); - if (datalen > 0) + } + if (datalen > 0){ waitCmdFelica(0); + } } return 0; } @@ -617,37 +618,14 @@ int readFelicaUid(bool verbose) { return status; } -// TODO FINISH THIS METHOD + int dump(const char *Cmd){ clearCommandBuffer(); char ctmp = tolower(param_getchar(Cmd, 0)); if (ctmp == 'h') return usage_hf_felica_dumplite(); + // TODO FINISH THIS METHOD + PrintAndLogEx(SUCCESS, "NOT IMPLEMENTED YET!"); - PrintAndLogEx(SUCCESS, "FeliCa - dump started"); - clearCommandBuffer(); - SendCommandNG(CMD_HF_FELICALITE_DUMP, NULL, 0); - PacketResponseNG resp; - - uint8_t timeout = 0; - while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { - timeout++; - printf("."); - fflush(stdout); - if (kbd_enter_pressed()) { - PrintAndLogEx(WARNING, "\n[!] aborted via keyboard!\n"); - DropField(); - return 1; - } - if (timeout > 100) { - PrintAndLogEx(WARNING, "timeout while waiting for reply."); - DropField(); - return 1; - } - } - if (resp.oldarg[0] == 0) { - PrintAndLogEx(WARNING, "\nButton pressed. Aborted."); - return 1; - } return 0; } From 97f85ba50ad2dfdf685a3cc5883c49a56da33e67 Mon Sep 17 00:00:00 2001 From: Thomas Sutter Date: Thu, 17 Oct 2019 12:54:56 +0200 Subject: [PATCH 1000/1854] Remove printf from client. Ready for testing. --- client/cmdhffelica.c | 1 - 1 file changed, 1 deletion(-) diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index cb93d6269..e6c0192bb 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -581,7 +581,6 @@ int readFelicaUid(bool verbose) { felica_card_select_t card; memcpy(&card, (felica_card_select_t *)resp.data.asBytes, sizeof(felica_card_select_t)); - PrintAndLogEx(NORMAL, "Received bytes: \n%s", sprint_hex(resp.data.asBytes, sizeof(resp.data.asBytes))); uint64_t status = resp.oldarg[0]; switch (status) { From 376e367d4546e09be2e2a4011e4e08fb25006341 Mon Sep 17 00:00:00 2001 From: Thomas Sutter Date: Thu, 17 Oct 2019 13:48:34 +0200 Subject: [PATCH 1001/1854] Make Style and remove some comments. --- armsrc/appmain.c | 4 +-- armsrc/felica.c | 66 ++++++++++++++++++++++---------------------- armsrc/felica.h | 2 +- client/cmdhffelica.c | 26 ++++++++--------- 4 files changed, 49 insertions(+), 49 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index e70b03cf8..b073598b2 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -365,14 +365,14 @@ void SendStatus(void) { Dbprintf(" Slow clock..............%d Hz", (16 * MAINCK) / mainf); uint32_t delta_time = 0; uint32_t start_time = GetTickCount(); - #define SLCK_CHECK_MS 50 +#define SLCK_CHECK_MS 50 SpinDelay(SLCK_CHECK_MS); delta_time = GetTickCountDelta(start_time); if ((delta_time < SLCK_CHECK_MS - 1) || (delta_time > SLCK_CHECK_MS + 1)) { // error > 2% with SLCK_CHECK_MS=50 Dbprintf(_RED_(" Slow Clock speed change detected, TIA needed")); Dbprintf(_YELLOW_(" Slow Clock actual speed seems closer to %d kHz"), - (16 * MAINCK / 1000) / mainf * delta_time / SLCK_CHECK_MS); + (16 * MAINCK / 1000) / mainf * delta_time / SLCK_CHECK_MS); } DbpString(_BLUE_("Installed StandAlone Mode")); ModInfo(); diff --git a/armsrc/felica.c b/armsrc/felica.c index 26e45292c..ab22bc778 100644 --- a/armsrc/felica.c +++ b/armsrc/felica.c @@ -14,17 +14,17 @@ // FeliCa timings // minimum time between the start bits of consecutive transfers from reader to tag: 6800 carrier (13.56MHz) cycles #ifndef FELICA_REQUEST_GUARD_TIME -# define FELICA_REQUEST_GUARD_TIME (6800/16 + 1) // 426 +# define FELICA_REQUEST_GUARD_TIME (6800/16 + 1) #endif // FRAME DELAY TIME 2672 carrier cycles #ifndef FELICA_FRAME_DELAY_TIME -# define FELICA_FRAME_DELAY_TIME (2672/16 + 1) // 168 +# define FELICA_FRAME_DELAY_TIME (2672/16 + 1) #endif #ifndef DELAY_AIR2ARM_AS_READER -#define DELAY_AIR2ARM_AS_READER (3 + 16 + 8 + 8*16 + 4*16 - 8*16) // 27 + 128 + 64 - 128 = 91 +#define DELAY_AIR2ARM_AS_READER (3 + 16 + 8 + 8*16 + 4*16 - 8*16) #endif #ifndef DELAY_ARM2AIR_AS_READER -#define DELAY_ARM2AIR_AS_READER (4*16 + 8*16 + 8 + 8 + 1) // 64 + 128 + 17 = 209 +#define DELAY_ARM2AIR_AS_READER (4*16 + 8*16 + 8 + 8 + 1) #endif // CRC skips two first sync bits in data buffer @@ -203,10 +203,10 @@ static uint8_t felica_select_card(felica_card_select_t *card) { // 0xff = system code service // 0xff = system code service // 0x00 = request code - // b7 = automatic switching of data rate - // b6-b2 = reserved - // b1 = fc/32 (414kbps) - // b0 = fc/64 (212kbps) + // b7 = automatic switching of data rate + // b6-b2 = reserved + // b1 = fc/32 (414kbps) + // b0 = fc/64 (212kbps) // 0x00 = timeslot // 0x09 0x21 = crc static uint8_t poll[10] = {0xb2, 0x4d, 0x06, FELICA_POLL_REQ, 0xFF, 0xFF, 0x00, 0x00, 0x09, 0x21}; @@ -228,22 +228,22 @@ static uint8_t felica_select_card(felica_card_select_t *card) { } while (--len); // timed-out - if (len == 0){ + if (len == 0) { if (DBGLEVEL > 3) Dbprintf("Error: Time out card selection!"); return 1; } // wrong answer - if (FelicaFrame.framebytes[3] != FELICA_POLL_ACK){ - if (DBGLEVEL > 3) - Dbprintf("Error: Wrong answer selecting card!"); + if (FelicaFrame.framebytes[3] != FELICA_POLL_ACK) { + if (DBGLEVEL > 3) + Dbprintf("Error: Wrong answer selecting card!"); return 2; } // VALIDATE CRC residue is 0, hence if crc is a value it failed. - if (!check_crc(CRC_FELICA, FelicaFrame.framebytes + 2, FelicaFrame.len - 2)){ - if (DBGLEVEL > 3){ + if (!check_crc(CRC_FELICA, FelicaFrame.framebytes + 2, FelicaFrame.len - 2)) { + if (DBGLEVEL > 3) { Dbprintf("Error: CRC check failed!"); Dbprintf("CRC check was done on Frame: "); Dbhexdump(FelicaFrame.len - 2, FelicaFrame.framebytes + 2, 0); @@ -263,7 +263,7 @@ static uint8_t felica_select_card(felica_card_select_t *card) { memcpy(card->uid, card->IDm + 2, 6); memcpy(card->iccode, card->PMm, 2); memcpy(card->mrt, card->PMm + 2, 6); - if (DBGLEVEL > 3){ + if (DBGLEVEL > 3) { Dbprintf("Received Frame: "); Dbhexdump(FelicaFrame.len, FelicaFrame.framebytes, 0); } @@ -366,7 +366,7 @@ static void TransmitFor18092_AsReader(uint8_t *frame, int len, uint32_t *timing, } // sending data with sync bytes c = 0; - if (DBGLEVEL > 3){ + if (DBGLEVEL > 3) { Dbprintf("Sending frame:"); Dbhexdump(len, frame, 0); } @@ -490,7 +490,7 @@ static void iso18092_setup(uint8_t fpga_minor_mode) { LED_D_ON(); } -void felica_reset_frame_mode(){ +void felica_reset_frame_mode() { switch_off(); //Resetting Frame mode (First set in fpgaloader.c) AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(8) | AT91C_SSC_MSBF | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0); @@ -515,7 +515,7 @@ void felica_sendraw(PacketCommandNG *c) { if ((param & FELICA_CONNECT)) if (DBGLEVEL > 3) Dbprintf("Clear trace"); - clear_trace(); + clear_trace(); set_tracing(true); iso18092_setup(FPGA_HF_ISO18092_FLAG_READER | FPGA_HF_ISO18092_FLAG_NOMOD); @@ -526,13 +526,13 @@ void felica_sendraw(PacketCommandNG *c) { if (!(param & FELICA_NO_SELECT)) { arg0 = felica_select_card(&card); reply_mix(CMD_ACK, arg0, sizeof(card.uid), 0, &card, sizeof(felica_card_select_t)); - if (arg0 > 0){ + if (arg0 > 0) { Dbprintf("Error: Failed selecting card! "); felica_reset_frame_mode(); return; } } - }else{ + } else { if (DBGLEVEL > 3) Dbprintf("No card selection"); } @@ -566,11 +566,11 @@ void felica_sendraw(PacketCommandNG *c) { Dbhexdump(FelicaFrame.len, FelicaFrame.framebytes, 0); }; uint32_t result = reply_mix(CMD_ACK, FelicaFrame.len, arg0, 0, FelicaFrame.framebytes, FelicaFrame.len); - if(result){ + if (result) { Dbprintf("Reply to Client Error Code: %i", result); } } - if ((param & FELICA_NO_DISCONNECT)){ + if ((param & FELICA_NO_DISCONNECT)) { Dbprintf("Disconnect"); } if (DBGLEVEL > 3) @@ -756,7 +756,7 @@ void felica_sim_lite(uint64_t uid) { DbpString("Felica Lite-S sim end"); } -void felica_dump(){ +void felica_dump() { uint8_t ndef[8]; uint8_t poll[10] = { 0xb2, 0x4d, 0x06, FELICA_POLL_REQ, 0xff, 0xff, 0x00, 0x00, 0x09, 0x21}; // B24D0600FFFF00000921 iso18092_setup(FPGA_HF_ISO18092_FLAG_READER | FPGA_HF_ISO18092_FLAG_NOMOD); @@ -773,7 +773,7 @@ void felica_dump(){ } } -void felica_send_request_service(uint8_t *request_service){ +void felica_send_request_service(uint8_t *request_service) { uint8_t len = sizeof(request_service) / sizeof((request_service)[0]); Dbprintf("Send Service Request - len: d%", len); TransmitFor18092_AsReader(request_service, len, NULL, 1, 0); @@ -787,14 +787,14 @@ void felica_send_request_service(uint8_t *request_service){ // When the specified Area or Service exists, the card returns Key Version. // When the specified Area or Service does not exist, the card returns FFFFh as Key Version. */ -uint8_t * felica_create_request_service_frame(uint8_t nodeNumber, uint8_t *idm){ - if(nodeNumber < 1 && nodeNumber > 32){ +uint8_t *felica_create_request_service_frame(uint8_t nodeNumber, uint8_t *idm) { + if (nodeNumber < 1 && nodeNumber > 32) { Dbprintf("Node number out of range: 1 <= %d <= 32 - set node number to 1"); nodeNumber = 1; } // Sync 2-Byte, Length 1-Byte, CMD 1-Byte, IDm 8-Byte, nodeNumber 1 <= n <= 32 1-Byte, Node Code List - uint8_t *request_service = BigBuf_malloc(sizeof(uint8_t)*11); - //{ 0xb2, 0x4d, 0x06, FELICA_REQSRV_REQ, 0xff, 0xff, 0x00, 0x00, 0x09, 0x21}; + uint8_t *request_service = BigBuf_malloc(sizeof(uint8_t) * 11); + //{ 0xb2, 0x4d, 0x06, FELICA_REQSRV_REQ, 0xff, 0xff, 0x00, 0x00, 0x09, 0x21}; request_service[0] = 0xb2; //Sync request_service[1] = 0x4d; //Sync request_service[2] = 0x0B; // Length @@ -813,18 +813,18 @@ uint8_t * felica_create_request_service_frame(uint8_t nodeNumber, uint8_t *idm){ } // Create Frame for authentication1 CMD -void felica_create_authentication1_frame(){ +void felica_create_authentication1_frame() { } // Create Frame for authentication2 CMD -void felica_create_authentication2_frame(){ +void felica_create_authentication2_frame() { } // Create a Frame for Read without encryption CMD as Payload -void felica_create_read_block_frame(uint16_t blockNr){ - if(blockNr < 1 || blockNr > 567){ +void felica_create_read_block_frame(uint16_t blockNr) { + if (blockNr < 1 || blockNr > 567) { Dbprintf("Block number out of range!"); return; } @@ -842,7 +842,7 @@ void felica_create_read_block_frame(uint16_t blockNr){ // CRC } -void felica_read_block(uint8_t *idm, uint16_t blockNr){ +void felica_read_block(uint8_t *idm, uint16_t blockNr) { } diff --git a/armsrc/felica.h b/armsrc/felica.h index faa52aa66..7bbc48614 100644 --- a/armsrc/felica.h +++ b/armsrc/felica.h @@ -24,6 +24,6 @@ void felica_create_authentication1_frame(); void felica_create_authentication2_frame(); void felica_send_request_service(uint8_t *request_service); void felica_reset_frame_mode(); -uint8_t * felica_create_request_service_frame(uint8_t nodeNumber, uint8_t *idm); +uint8_t *felica_create_request_service_frame(uint8_t nodeNumber, uint8_t *idm); #endif diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index e6c0192bb..22acf6344 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -406,7 +406,7 @@ static int CmdHFFelicaDumpLite(const char *Cmd) { } uint32_t tracelen = resp.oldarg[1]; - if (tracelen == 0){ + if (tracelen == 0) { PrintAndLogEx(WARNING, "\nNo trace data! Maybe not a FeliCa Lite card?"); return 1; } @@ -557,11 +557,11 @@ static int CmdHFFelicaCmdRaw(const char *Cmd) { SendCommandMIX(CMD_HF_FELICA_COMMAND, flags, (datalen & 0xFFFF) | (uint32_t)(numbits << 16), 0, data, datalen); if (reply) { - if (active_select){ + if (active_select) { PrintAndLogEx(NORMAL, "Active select wait for FeliCa."); waitCmdFelica(1); } - if (datalen > 0){ + if (datalen > 0) { waitCmdFelica(0); } } @@ -618,7 +618,7 @@ int readFelicaUid(bool verbose) { } -int dump(const char *Cmd){ +int dump(const char *Cmd) { clearCommandBuffer(); char ctmp = tolower(param_getchar(Cmd, 0)); if (ctmp == 'h') return usage_hf_felica_dumplite(); @@ -629,16 +629,16 @@ int dump(const char *Cmd){ } static command_t CommandTable[] = { - {"help", CmdHelp, AlwaysAvailable, "This help"}, - {"list", CmdHFFelicaList, AlwaysAvailable, "List ISO 18092/FeliCa history"}, - {"reader", CmdHFFelicaReader, IfPm3Felica, "Act like an ISO18092/FeliCa reader"}, + {"help", CmdHelp, AlwaysAvailable, "This help"}, + {"list", CmdHFFelicaList, AlwaysAvailable, "List ISO 18092/FeliCa history"}, + {"reader", CmdHFFelicaReader, IfPm3Felica, "Act like an ISO18092/FeliCa reader"}, // {"sim", CmdHFFelicaSim, IfPm3Felica, " -- Simulate ISO 18092/FeliCa tag"}, - {"sniff", CmdHFFelicaSniff, IfPm3Felica, "sniff ISO 18092/Felica traffic"}, - {"raw", CmdHFFelicaCmdRaw, IfPm3Felica, "Send raw hex data to tag"}, - {"dump", CmdHFFelicaDump, IfPm3Felica, "Wait for and try dumping Felica"}, - {"litesim", CmdHFFelicaSimLite, IfPm3Felica, " - only reply to poll request"}, - {"litedump", CmdHFFelicaDumpLite, IfPm3Felica, "Wait for and try dumping FelicaLite"}, - {NULL, NULL, NULL, NULL} + {"sniff", CmdHFFelicaSniff, IfPm3Felica, "sniff ISO 18092/Felica traffic"}, + {"raw", CmdHFFelicaCmdRaw, IfPm3Felica, "Send raw hex data to tag"}, + {"dump", CmdHFFelicaDump, IfPm3Felica, "Wait for and try dumping Felica"}, + {"litesim", CmdHFFelicaSimLite, IfPm3Felica, " - only reply to poll request"}, + {"litedump", CmdHFFelicaDumpLite, IfPm3Felica, "Wait for and try dumping FelicaLite"}, + {NULL, NULL, NULL, NULL} }; static int CmdHelp(const char *Cmd) { From 945fb82b48054d4096f82fda892abd21422a0025 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 17 Oct 2019 13:58:22 +0200 Subject: [PATCH 1002/1854] make style --- armsrc/appmain.c | 4 ++-- armsrc/spiffs.c | 6 +++--- client/cmdlft55xx.c | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index e70b03cf8..b073598b2 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -365,14 +365,14 @@ void SendStatus(void) { Dbprintf(" Slow clock..............%d Hz", (16 * MAINCK) / mainf); uint32_t delta_time = 0; uint32_t start_time = GetTickCount(); - #define SLCK_CHECK_MS 50 +#define SLCK_CHECK_MS 50 SpinDelay(SLCK_CHECK_MS); delta_time = GetTickCountDelta(start_time); if ((delta_time < SLCK_CHECK_MS - 1) || (delta_time > SLCK_CHECK_MS + 1)) { // error > 2% with SLCK_CHECK_MS=50 Dbprintf(_RED_(" Slow Clock speed change detected, TIA needed")); Dbprintf(_YELLOW_(" Slow Clock actual speed seems closer to %d kHz"), - (16 * MAINCK / 1000) / mainf * delta_time / SLCK_CHECK_MS); + (16 * MAINCK / 1000) / mainf * delta_time / SLCK_CHECK_MS); } DbpString(_BLUE_("Installed StandAlone Mode")); ModInfo(); diff --git a/armsrc/spiffs.c b/armsrc/spiffs.c index f242062be..87321148d 100644 --- a/armsrc/spiffs.c +++ b/armsrc/spiffs.c @@ -543,7 +543,7 @@ void rdv40_spiffs_safe_print_fsinfo() { rdv40_spiffs_getfsinfo(&fsinfo, RDV40_SPIFFS_SAFETY_SAFE); DbpString(_BLUE_("Flash Memory FileSystem Info (SPIFFS)")); - + Dbprintf(" Logical Block Size........." _YELLOW_("%d")"bytes", fsinfo.blockSize); Dbprintf(" Logical Page Size.........." _YELLOW_("%d")"bytes", fsinfo.pageSize); @@ -573,7 +573,7 @@ void rdv40_spiffs_safe_print_tree(uint8_t banner) { DbpString(_BLUE_("Flash Memory FileSystem tree (SPIFFS)")); Dbprintf("-------------------------------------"); } - + int changed = rdv40_spiffs_lazy_mount(); spiffs_DIR d; struct spiffs_dirent e; @@ -614,7 +614,7 @@ void test_spiffs() { Dbprintf(" Printing tree.............."); rdv40_spiffs_safe_print_tree(false); - + Dbprintf(" Writing 'I love Proxmark3 RDV4' in a testspiffs.txt"); // Since We lazy_mounted manually before hand, the wrte safety level will diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index e1f84b32b..541a67fe4 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -371,7 +371,7 @@ static int usage_t55xx_dangerraw() { return PM3_SUCCESS; } -static int usage_t55xx_clonehelp(){ +static int usage_t55xx_clonehelp() { PrintAndLogEx(NORMAL, "For cloning specific techs on T55xx tags, see commands available in corresponding LF sub-menus, e.g.:"); PrintAndLogEx(NORMAL, _GREEN_("lf awid clone")); // todo: rename to clone From 3cd053218f7174761eed9da1fd32a71ebdef5978 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 17 Oct 2019 20:08:17 +0200 Subject: [PATCH 1003/1854] chg: wait until ready --- armsrc/appmain.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index b073598b2..3b6976819 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1899,9 +1899,13 @@ static void PacketReceived(PacketCommandNG *packet) { break; } case CMD_TIA: { + + while ((AT91C_BASE_PMC->PMC_MCFR & AT91C_CKGR_MAINRDY) == 0); // Wait for MAINF value to become available... uint16_t mainf = AT91C_BASE_PMC->PMC_MCFR & AT91C_CKGR_MAINF; Dbprintf(" Slow clock old measured value:.........%d Hz", (16 * MAINCK) / mainf); TimingIntervalAcquisition(); + + while ((AT91C_BASE_PMC->PMC_MCFR & AT91C_CKGR_MAINRDY) == 0); // Wait for MAINF value to become available... mainf = AT91C_BASE_PMC->PMC_MCFR & AT91C_CKGR_MAINF; Dbprintf(""); // first message gets lost Dbprintf(" Slow clock new measured value:.........%d Hz", (16 * MAINCK) / mainf); From 9fdc29e91c02f8c0c1f86ea8ca11bb9955907583 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 17 Oct 2019 21:58:57 +0200 Subject: [PATCH 1004/1854] chg: 'hf search' - add FeliCa detection --- client/cmdhf.c | 31 +++++++++++++--------- client/cmdhffelica.c | 61 ++++++++++++++++++++++---------------------- 2 files changed, 49 insertions(+), 43 deletions(-) diff --git a/client/cmdhf.c b/client/cmdhf.c index 85612f428..bf8a9dceb 100644 --- a/client/cmdhf.c +++ b/client/cmdhf.c @@ -70,6 +70,8 @@ static int usage_hf_tune() { return PM3_SUCCESS; } +#define PROMPT_CLEARLINE PrintAndLogEx(INPLACE, " ") + int CmdHFSearch(const char *Cmd) { char cmdp = tolower(param_getchar(Cmd, 0)); @@ -77,6 +79,7 @@ int CmdHFSearch(const char *Cmd) { PrintAndLogEx(INFO, "Checking for known tags...\n"); + PROMPT_CLEARLINE; PrintAndLogEx(INPLACE, "Searching for ThinFilm tag..."); if (IfPm3NfcBarcode()) { if (infoThinFilm(false) == PM3_SUCCESS) { @@ -85,6 +88,7 @@ int CmdHFSearch(const char *Cmd) { } } + PROMPT_CLEARLINE; PrintAndLogEx(INPLACE, "Searching for ISO14443-A tag..."); if (IfPm3Iso14443a()) { if (infoHF14A(false, false) > 0) { @@ -92,7 +96,8 @@ int CmdHFSearch(const char *Cmd) { return PM3_SUCCESS; } } - + + PROMPT_CLEARLINE; PrintAndLogEx(INPLACE, "Searching for ISO15693 tag..."); if (IfPm3Iso15693()) { if (readHF15Uid(false) == 1) { @@ -104,6 +109,7 @@ int CmdHFSearch(const char *Cmd) { DropField(); } + PROMPT_CLEARLINE; PrintAndLogEx(INPLACE, "Searching for LEGIC tag..."); if (IfPm3Legicrf()) { if (readLegicUid(false) == PM3_SUCCESS) { @@ -112,6 +118,7 @@ int CmdHFSearch(const char *Cmd) { } } + PROMPT_CLEARLINE; PrintAndLogEx(INPLACE, "Searching for Topaz tag..."); if (IfPm3Iso14443a()) { if (readTopazUid() == PM3_SUCCESS) { @@ -120,7 +127,17 @@ int CmdHFSearch(const char *Cmd) { } } + PROMPT_CLEARLINE; + PrintAndLogEx(INPLACE, "Searching for FeliCa tag..."); + if (IfPm3Felica()) { + if (readFelicaUid(false) == PM3_SUCCESS) { + PrintAndLogEx(NORMAL, "\nValid " _GREEN_("ISO18092 / FeliCa tag") " found\n"); + return PM3_SUCCESS; + } + } + // 14b and iclass is the longest test (put last) + PROMPT_CLEARLINE; PrintAndLogEx(INPLACE, "Searching for ISO14443-B tag..."); if (IfPm3Iso14443a()) { if (readHF14B(false) == 1) { @@ -129,6 +146,7 @@ int CmdHFSearch(const char *Cmd) { } } + PROMPT_CLEARLINE; PrintAndLogEx(INPLACE, "Searching for iClass / PicoPass tag..."); if (IfPm3Iclass()) { if (readIclass(false, false) == 1) { @@ -137,17 +155,6 @@ int CmdHFSearch(const char *Cmd) { } } - -// PrintAndLogEx(INPLACE, "Searching for FeliCa tag..."); - //if (IfPm3Felica()) { - // ans = CmdHFFelicaReader("s"); - // if (ans) { - // PrintAndLogEx(NORMAL, "\nValid " _GREEN_("ISO18092 / FeliCa tag") " found\n"); - // return ans; - // } - //} - - PrintAndLogEx(INPLACE, "No known/supported 13.56 MHz tags found"); PrintAndLogEx(NORMAL, ""); return PM3_ESOFT; diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index 22acf6344..d2583b5ff 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -36,7 +36,7 @@ static int usage_hf_felica_sim(void) { PrintAndLogEx(NORMAL, " v : (Optional) Verbose"); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf felica sim t 1 "); - return 0; + return PM3_SUCCESS; } */ @@ -48,7 +48,7 @@ static int usage_hf_felica_sniff(void) { PrintAndLogEx(NORMAL, " t triggers to skip (decimal)"); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf felica sniff s 1000"); - return 0; + return PM3_SUCCESS; } static int usage_hf_felica_simlite(void) { PrintAndLogEx(NORMAL, "\n Emulating ISO/18092 FeliCa Lite tag \n"); @@ -58,7 +58,7 @@ static int usage_hf_felica_simlite(void) { PrintAndLogEx(NORMAL, " uid : UID in hexsymbol"); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf felica litesim 11223344556677"); - return 0; + return PM3_SUCCESS; } static int usage_hf_felica_dumplite(void) { PrintAndLogEx(NORMAL, "\n Dump ISO/18092 FeliCa Lite tag \n"); @@ -68,7 +68,7 @@ static int usage_hf_felica_dumplite(void) { PrintAndLogEx(NORMAL, " h : This help"); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf felica litedump"); - return 0; + return PM3_SUCCESS; } static int usage_hf_felica_raw(void) { PrintAndLogEx(NORMAL, "Usage: hf felica raw [-h] [-r] [-c] [-p] [-a] <0A 0B 0C ... hex>"); @@ -78,32 +78,30 @@ static int usage_hf_felica_raw(void) { PrintAndLogEx(NORMAL, " -p leave the signal field ON after receive"); PrintAndLogEx(NORMAL, " -a active signal field ON without select"); PrintAndLogEx(NORMAL, " -s active signal field ON with select"); - return 0; + return PM3_SUCCESS; } static int usage_hf_felica_dump(void) { PrintAndLogEx(NORMAL, "Usage: hf felica dump [-h] "); PrintAndLogEx(NORMAL, " -h this help"); - return 0; + return PM3_SUCCESS; } static int CmdHFFelicaList(const char *Cmd) { (void)Cmd; // Cmd is not used so far //PrintAndLogEx(NORMAL, "Deprecated command, use 'hf list felica' instead"); CmdTraceList("felica"); - return 0; + return PM3_SUCCESS; } static int CmdHFFelicaReader(const char *Cmd) { bool verbose = !(Cmd[0] == 's' || Cmd[0] == 'S'); - readFelicaUid(verbose); - return 0; + return readFelicaUid(verbose); } static int CmdHFFelicaDump(const char *Cmd) { if (strlen(Cmd) < 1) return usage_hf_felica_dump(); - dump(*Cmd); - return 0; + return dump(*Cmd); } // simulate iso18092 / FeliCa tag @@ -169,7 +167,7 @@ static int CmdHFFelicaSim(const char *Cmd) { while (!kbd_enter_pressed()) { if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) continue; } - return 0; + return PM3_SUCCESS; } */ @@ -206,7 +204,7 @@ static int CmdHFFelicaSniff(const char *Cmd) { clearCommandBuffer(); SendCommandMIX(CMD_HF_FELICA_SNIFF, samples2skip, triggers2skip, 0, NULL, 0); - return 0; + return PM3_SUCCESS; } // uid hex @@ -219,7 +217,7 @@ static int CmdHFFelicaSimLite(const char *Cmd) { clearCommandBuffer(); SendCommandMIX(CMD_HF_FELICALITE_SIMULATE, uid, 0, 0, NULL, 0); - return 0; + return PM3_SUCCESS; } static void printSep() { @@ -392,35 +390,35 @@ static int CmdHFFelicaDumpLite(const char *Cmd) { if (kbd_enter_pressed()) { PrintAndLogEx(WARNING, "\n[!] aborted via keyboard!\n"); DropField(); - return 1; + return PM3_EOPABORTED; } if (timeout > 100) { PrintAndLogEx(WARNING, "timeout while waiting for reply."); DropField(); - return 1; + return PM3_ETIMEOUT; } } if (resp.oldarg[0] == 0) { PrintAndLogEx(WARNING, "\nButton pressed. Aborted."); - return 1; + return PM3_EOPABORTED; } uint32_t tracelen = resp.oldarg[1]; if (tracelen == 0) { PrintAndLogEx(WARNING, "\nNo trace data! Maybe not a FeliCa Lite card?"); - return 1; + return PM3_ESOFT; } uint8_t *trace = calloc(tracelen, sizeof(uint8_t)); if (trace == NULL) { PrintAndLogEx(WARNING, "Cannot allocate memory for trace"); - return 1; + return PM3_EMALLOC; } if (!GetFromDevice(BIG_BUF, trace, tracelen, 0, NULL, 0, NULL, 2500, false)) { PrintAndLogEx(WARNING, "command execution time out"); free(trace); - return 0; + return PM3_ETIMEOUT; } PrintAndLogEx(SUCCESS, "Recorded Activity (trace len = %"PRIu64" bytes)", tracelen); @@ -435,7 +433,7 @@ static int CmdHFFelicaDumpLite(const char *Cmd) { printSep(); free(trace); - return 0; + return PM3_SUCCESS; } static void waitCmdFelica(uint8_t iSelect) { @@ -524,7 +522,7 @@ static int CmdHFFelicaCmdRaw(const char *Cmd) { continue; } PrintAndLogEx(WARNING, "Invalid char on input"); - return 0; + return PM3_EINVARG; } if (crc && datalen > 0 && datalen < sizeof(data) - 2) { @@ -565,7 +563,7 @@ static int CmdHFFelicaCmdRaw(const char *Cmd) { waitCmdFelica(0); } } - return 0; + return PM3_SUCCESS; } int readFelicaUid(bool verbose) { @@ -576,7 +574,7 @@ int readFelicaUid(bool verbose) { if (!WaitForResponseTimeout(CMD_ACK, &resp, 2500)) { if (verbose) PrintAndLogEx(WARNING, "FeliCa card select failed"); //SendCommandMIX(CMD_HF_FELICA_COMMAND, 0, 0, 0, NULL, 0); - return 0; + return PM3_ESOFT; } felica_card_select_t card; @@ -587,19 +585,20 @@ int readFelicaUid(bool verbose) { case 1: { if (verbose) PrintAndLogEx(WARNING, "card timeout"); - break; + return PM3_ETIMEOUT; } case 2: { if (verbose) PrintAndLogEx(WARNING, "card answered wrong"); - break; + return PM3_ESOFT; } case 3: { if (verbose) PrintAndLogEx(WARNING, "CRC check failed"); - break; + return PM3_ESOFT; } case 0: { + PrintAndLogEx(NORMAL, ""); PrintAndLogEx(SUCCESS, "FeliCa tag info"); PrintAndLogEx(NORMAL, "IDm %s", sprint_hex(card.IDm, sizeof(card.IDm))); @@ -614,18 +613,18 @@ int readFelicaUid(bool verbose) { break; } } - return status; + return PM3_SUCCESS; } - int dump(const char *Cmd) { clearCommandBuffer(); char ctmp = tolower(param_getchar(Cmd, 0)); if (ctmp == 'h') return usage_hf_felica_dumplite(); + // TODO FINISH THIS METHOD PrintAndLogEx(SUCCESS, "NOT IMPLEMENTED YET!"); - return 0; + return PM3_SUCCESS; } static command_t CommandTable[] = { @@ -644,7 +643,7 @@ static command_t CommandTable[] = { static int CmdHelp(const char *Cmd) { (void)Cmd; // Cmd is not used so far CmdsHelp(CommandTable); - return 0; + return PM3_SUCCESS; } int CmdHFFelica(const char *Cmd) { From 2c4e6606050de08b647a8aaab35891d158e5ecc5 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 17 Oct 2019 22:24:32 +0200 Subject: [PATCH 1005/1854] fix --- client/cmdhffelica.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index d2583b5ff..6d7362c3c 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -95,7 +95,7 @@ static int CmdHFFelicaList(const char *Cmd) { } static int CmdHFFelicaReader(const char *Cmd) { - bool verbose = !(Cmd[0] == 's' || Cmd[0] == 'S'); + bool verbose = !(tolower(Cmd[0]) == 's'); return readFelicaUid(verbose); } From ed565d04f5cce3bdc323085027a8cb4170fc9996 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 17 Oct 2019 22:28:49 +0200 Subject: [PATCH 1006/1854] chg: remark available in lua --- client/cmdmain.c | 2 +- client/cmdmain.h | 1 + client/scripting.c | 18 ++++++++++++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/client/cmdmain.c b/client/cmdmain.c index 7a04960f0..5a2c91904 100644 --- a/client/cmdmain.c +++ b/client/cmdmain.c @@ -38,7 +38,7 @@ static int CmdHelp(const char *Cmd); -static int CmdRem(const char *Cmd) { +int CmdRem(const char *Cmd) { char buf[22] = {0}; struct tm *ct, tm_buf; time_t now = time(NULL); diff --git a/client/cmdmain.h b/client/cmdmain.h index 8b440143e..68984efab 100644 --- a/client/cmdmain.h +++ b/client/cmdmain.h @@ -15,6 +15,7 @@ #include "cmdparser.h" // command_t int CommandReceived(char *Cmd); +int CmdRem(const char *Cmd); command_t *getTopLevelCommandTable(void); #endif diff --git a/client/scripting.c b/client/scripting.c index e5c3990fb..43bcbd9c7 100644 --- a/client/scripting.c +++ b/client/scripting.c @@ -32,6 +32,7 @@ #include "crc16.h" #include "protocols.h" #include "fileutils.h" // searchfile +#include "cmdlf.h" // lf_config static int returnToLuaWithError(lua_State *L, const char *fmt, ...) { char buffer[200]; @@ -1056,6 +1057,22 @@ static int l_ndefparse(lua_State *L) { return 1; } +static int l_remark(lua_State *L) { + //Check number of arguments + int n = lua_gettop(L); + if (n != 1) { + return returnToLuaWithError(L, "Only one string allowed"); + } + + size_t size; + // data + const char *s = luaL_checklstring(L, 1, &size); + + int res = CmdRem(s); + lua_pushinteger(L, res); + return 1; +} + static int l_searchfile(lua_State *L) { //Check number of arguments int n = lua_gettop(L); @@ -1141,6 +1158,7 @@ int set_pm3_libraries(lua_State *L) { {"ndefparse", l_ndefparse}, {"fast_push_mode", l_fast_push_mode}, {"search_file", l_searchfile}, + {"rem", l_remark}, {NULL, NULL} }; From a823c7821fa3055f737e9141f7e2448bf6b7ee30 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 17 Oct 2019 22:30:18 +0200 Subject: [PATCH 1007/1854] chg: 'sc upgrade' - ignore case on all platforms --- client/cmdsmartcard.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/client/cmdsmartcard.c b/client/cmdsmartcard.c index c69e4f037..21066ffb7 100644 --- a/client/cmdsmartcard.c +++ b/client/cmdsmartcard.c @@ -548,7 +548,6 @@ static int CmdSmartUpgrade(const char *Cmd) { //Validations if (errors || cmdp == 0) return usage_sm_upgrade(); - char sha512filename[FILE_PATH_SIZE] = {'\0'}; char *bin_extension = filename; char *dot_position = NULL; @@ -556,11 +555,7 @@ static int CmdSmartUpgrade(const char *Cmd) { bin_extension = dot_position + 1; } - if (!strcmp(bin_extension, "BIN") -#ifdef _WIN32 - || !strcmp(bin_extension, "bin") -#endif - ) { + if (!strcmp(bin_extension, "BIN") || !strcmp(bin_extension, "bin")) { memcpy(sha512filename, filename, strlen(filename) - strlen("bin")); strcat(sha512filename, "sha512.txt"); } else { From 065a1b68486362891b54a8a1728e97e85b19c7d2 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 17 Oct 2019 22:32:09 +0200 Subject: [PATCH 1008/1854] chg: enforce PACKED on more structs --- include/mifare.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/mifare.h b/include/mifare.h index 9d444e833..23dbceb68 100644 --- a/include/mifare.h +++ b/include/mifare.h @@ -34,7 +34,7 @@ typedef struct { uint8_t signature[32]; uint8_t counter_tearing[3][4]; // 3 bytes counter, 1 byte tearing flag uint8_t data[1024]; -} mfu_dump_t; +} PACKED mfu_dump_t; //----------------------------------------------------------------------------- // ISO 14443A @@ -69,7 +69,7 @@ typedef struct { uint16_t modulation_n; uint32_t ProxToAirDuration; uint8_t par; // enough for precalculated parity of 8 Byte responses -} tag_response_info_t; +} PACKED tag_response_info_t; //----------------------------------------------------------------------------- // ISO 14443B //----------------------------------------------------------------------------- @@ -79,7 +79,7 @@ typedef struct { uint8_t atqb[7]; uint8_t chipid; uint8_t cid; -} __attribute__((__packed__)) iso14b_card_select_t; +} PACKED iso14b_card_select_t; typedef enum ISO14B_COMMAND { ISO14B_CONNECT = (1 << 0), @@ -121,7 +121,7 @@ typedef struct { FIRST, SECOND, } state; -} nonces_t; +} PACKED nonces_t; //----------------------------------------------------------------------------- // ISO 7618 Smart Card From 61c3c9b5d04d80d46fbf2a71353ebfb1c0d42ac4 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 17 Oct 2019 22:51:27 +0200 Subject: [PATCH 1009/1854] Add: genuine VeriChip trace --- traces/README.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/traces/README.txt b/traces/README.txt index 4cc42ba74..63ebe18ee 100644 --- a/traces/README.txt +++ b/traces/README.txt @@ -27,4 +27,5 @@ HID-weak-fob-11647.pm3: HID 32bit Prox Card#: 11647. very weak tag/read but jus visa2000.pm3: VISA2000 ASK/MAN RF/64, Card: 480518 securakey-64169.pm3 Securakey Tag BitLen: 26, Card ID: 64169, FC: 0x35 -motorola_0437_00072.pm3 - Motorola Grey clamshell card, old. (RAW: A0000000E308C0C1) +motorola_0437_00072.pm3: Motorola Grey clamshell card, old. (RAW: A0000000E308C0C1) +verichip_1022000000084146.pm3: VeriChip, epoxy encased glasschip (ID: 1022-00000000084146) From 861f9bd8b2bbfbd99dd09c1dc7758bb9d4e65c57 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 17 Oct 2019 22:51:59 +0200 Subject: [PATCH 1010/1854] and the file --- traces/verichip_1022000000084146.pm3 | 39999 +++++++++++++++++++++++++ 1 file changed, 39999 insertions(+) create mode 100644 traces/verichip_1022000000084146.pm3 diff --git a/traces/verichip_1022000000084146.pm3 b/traces/verichip_1022000000084146.pm3 new file mode 100644 index 000000000..9109d7599 --- /dev/null +++ b/traces/verichip_1022000000084146.pm3 @@ -0,0 +1,39999 @@ +18 +17 +17 +10 +-9 +-24 +-35 +-43 +-48 +-52 +-54 +-55 +-55 +-54 +-52 +-50 +-49 +-47 +-44 +-41 +-38 +-36 +-34 +-33 +-31 +-30 +-28 +-27 +-25 +-24 +-22 +-21 +-19 +-18 +-16 +-6 +15 +29 +40 +47 +51 +54 +56 +56 +56 +54 +53 +52 +50 +48 +46 +37 +17 +1 +-10 +-19 +-24 +-28 +-32 +-35 +-36 +-37 +-37 +-36 +-35 +-34 +-32 +-22 +-1 +13 +25 +32 +39 +42 +45 +46 +46 +45 +44 +44 +42 +40 +37 +29 +9 +-6 +-18 +-27 +-33 +-37 +-40 +-41 +-42 +-42 +-41 +-41 +-39 +-39 +-37 +-27 +-6 +9 +20 +28 +34 +38 +41 +43 +43 +43 +43 +42 +41 +39 +38 +29 +10 +-6 +-17 +-26 +-32 +-37 +-39 +-41 +-41 +-42 +-41 +-41 +-39 +-37 +-35 +-24 +-3 +12 +23 +30 +35 +39 +41 +42 +43 +43 +42 +41 +40 +38 +37 +29 +9 +-6 +-18 +-26 +-32 +-37 +-40 +-42 +-43 +-43 +-43 +-42 +-40 +-39 +-37 +-26 +-4 +11 +22 +30 +36 +39 +41 +42 +42 +42 +41 +39 +38 +37 +35 +27 +7 +-8 +-20 +-28 +-34 +-38 +-41 +-42 +-43 +-44 +-43 +-42 +-40 +-39 +-37 +-27 +-4 +10 +21 +29 +35 +38 +41 +42 +43 +43 +43 +42 +40 +39 +38 +29 +9 +-6 +-17 +-26 +-32 +-36 +-38 +-39 +-40 +-40 +-39 +-38 +-37 +-35 +-34 +-24 +-2 +12 +23 +30 +35 +38 +41 +41 +42 +41 +41 +41 +40 +38 +37 +29 +9 +-6 +-17 +-27 +-34 +-39 +-42 +-44 +-44 +-44 +-43 +-42 +-41 +-39 +-37 +-26 +-4 +11 +21 +30 +36 +39 +42 +43 +43 +43 +41 +40 +39 +38 +37 +29 +9 +-6 +-17 +-26 +-31 +-35 +-38 +-40 +-41 +-41 +-41 +-40 +-39 +-38 +-36 +-26 +-4 +11 +23 +31 +36 +39 +41 +42 +43 +43 +43 +41 +39 +37 +36 +34 +32 +30 +29 +27 +26 +25 +23 +22 +22 +21 +20 +18 +17 +17 +15 +8 +-11 +-26 +-37 +-44 +-50 +-54 +-55 +-56 +-55 +-55 +-53 +-51 +-49 +-47 +-45 +-33 +-10 +5 +16 +24 +30 +34 +36 +38 +39 +40 +39 +38 +36 +35 +34 +26 +7 +-8 +-20 +-28 +-34 +-38 +-42 +-43 +-44 +-44 +-44 +-44 +-41 +-40 +-39 +-28 +-6 +9 +20 +28 +34 +38 +40 +41 +42 +41 +40 +39 +37 +36 +35 +26 +7 +-8 +-19 +-28 +-33 +-38 +-40 +-42 +-43 +-43 +-42 +-40 +-39 +-38 +-36 +-26 +-4 +10 +22 +30 +36 +39 +42 +43 +43 +43 +43 +41 +40 +39 +37 +28 +8 +-7 +-19 +-28 +-34 +-38 +-41 +-43 +-43 +-43 +-42 +-41 +-40 +-38 +-37 +-27 +-6 +10 +21 +28 +33 +37 +39 +41 +41 +41 +40 +39 +38 +37 +35 +28 +7 +-8 +-20 +-29 +-34 +-38 +-41 +-43 +-44 +-44 +-44 +-43 +-41 +-40 +-38 +-27 +-5 +11 +22 +30 +35 +38 +41 +42 +44 +43 +42 +41 +40 +38 +37 +29 +10 +-5 +-17 +-26 +-32 +-36 +-39 +-41 +-41 +-42 +-42 +-40 +-39 +-38 +-36 +-25 +-4 +11 +23 +30 +36 +39 +42 +43 +43 +42 +41 +40 +39 +38 +37 +29 +9 +-7 +-19 +-27 +-33 +-36 +-39 +-41 +-41 +-40 +-40 +-40 +-39 +-37 +-36 +-25 +-3 +11 +22 +31 +36 +39 +42 +44 +44 +45 +44 +43 +41 +39 +38 +29 +9 +-7 +-18 +-27 +-33 +-38 +-41 +-42 +-43 +-43 +-43 +-41 +-39 +-37 +-36 +-26 +-4 +10 +21 +28 +34 +37 +39 +40 +41 +40 +40 +39 +38 +36 +35 +26 +7 +-8 +-19 +-29 +-35 +-40 +-43 +-44 +-45 +-45 +-44 +-43 +-42 +-40 +-38 +-36 +-33 +-32 +-29 +-28 +-26 +-25 +-23 +-22 +-20 +-19 +-18 +-17 +-16 +-15 +-14 +-4 +19 +33 +43 +50 +54 +57 +58 +58 +58 +57 +55 +53 +51 +49 +48 +45 +43 +41 +39 +36 +35 +33 +31 +29 +28 +25 +23 +22 +20 +19 +18 +11 +-8 +-23 +-33 +-41 +-45 +-49 +-50 +-51 +-51 +-50 +-49 +-48 +-47 +-46 +-43 +-33 +-10 +5 +17 +26 +31 +35 +38 +39 +40 +39 +39 +38 +37 +35 +33 +25 +6 +-10 +-21 +-30 +-36 +-40 +-43 +-44 +-45 +-44 +-43 +-42 +-40 +-39 +-37 +-27 +-6 +9 +20 +28 +34 +37 +40 +41 +42 +42 +42 +42 +40 +38 +36 +28 +8 +-7 +-18 +-28 +-34 +-38 +-41 +-42 +-42 +-42 +-41 +-40 +-39 +-37 +-35 +-33 +-31 +-29 +-27 +-26 +-25 +-23 +-22 +-21 +-19 +-18 +-17 +-16 +-14 +-13 +-12 +-3 +19 +34 +44 +50 +54 +56 +57 +57 +57 +55 +54 +52 +50 +48 +46 +43 +41 +39 +37 +35 +33 +31 +30 +29 +27 +25 +23 +21 +19 +18 +17 +9 +-10 +-25 +-35 +-42 +-47 +-51 +-53 +-54 +-54 +-53 +-51 +-50 +-49 +-47 +-45 +-34 +-12 +4 +15 +23 +30 +34 +36 +38 +39 +39 +39 +38 +37 +35 +34 +26 +6 +-9 +-20 +-29 +-35 +-39 +-42 +-44 +-45 +-44 +-43 +-42 +-40 +-38 +-37 +-36 +-34 +-32 +-30 +-29 +-27 +-26 +-24 +-22 +-21 +-19 +-17 +-16 +-16 +-14 +-12 +-2 +18 +32 +43 +49 +53 +55 +57 +57 +57 +55 +53 +51 +49 +47 +45 +37 +17 +2 +-10 +-20 +-27 +-32 +-36 +-38 +-38 +-39 +-38 +-38 +-35 +-34 +-33 +-22 +-1 +14 +25 +34 +39 +42 +45 +46 +46 +45 +44 +42 +41 +39 +38 +36 +35 +33 +31 +29 +28 +26 +25 +23 +23 +21 +20 +18 +17 +15 +14 +6 +-13 +-27 +-38 +-45 +-51 +-54 +-56 +-56 +-56 +-55 +-54 +-52 +-50 +-47 +-45 +-42 +-40 +-38 +-36 +-34 +-32 +-31 +-30 +-28 +-27 +-25 +-24 +-22 +-20 +-19 +-18 +-7 +14 +29 +39 +46 +50 +52 +53 +53 +52 +51 +50 +48 +46 +44 +42 +40 +39 +37 +35 +32 +31 +29 +28 +26 +25 +24 +23 +22 +18 +17 +16 +9 +-10 +-25 +-36 +-43 +-48 +-51 +-53 +-53 +-52 +-51 +-50 +-48 +-46 +-44 +-42 +-32 +-10 +6 +17 +26 +31 +35 +37 +39 +39 +39 +38 +37 +36 +35 +34 +26 +7 +-8 +-20 +-29 +-35 +-39 +-42 +-44 +-44 +-44 +-43 +-42 +-41 +-40 +-38 +-36 +-33 +-32 +-29 +-28 +-25 +-24 +-22 +-21 +-19 +-19 +-18 +-17 +-16 +-15 +-13 +-4 +17 +30 +41 +49 +54 +56 +57 +58 +58 +57 +55 +53 +51 +48 +45 +43 +40 +38 +37 +35 +33 +31 +29 +28 +27 +26 +24 +23 +22 +20 +19 +11 +-8 +-23 +-33 +-42 +-46 +-49 +-52 +-53 +-53 +-52 +-50 +-48 +-46 +-44 +-41 +-30 +-8 +7 +19 +27 +32 +36 +38 +38 +39 +40 +39 +38 +37 +36 +35 +26 +7 +-9 +-20 +-29 +-35 +-39 +-42 +-44 +-45 +-45 +-44 +-43 +-42 +-40 +-38 +-36 +-34 +-32 +-30 +-28 +-26 +-25 +-22 +-21 +-19 +-18 +-18 +-17 +-16 +-15 +-14 +-4 +17 +31 +42 +49 +54 +56 +58 +58 +58 +57 +55 +53 +51 +49 +46 +43 +42 +39 +36 +34 +32 +30 +29 +27 +25 +24 +23 +22 +20 +19 +18 +11 +-8 +-23 +-35 +-42 +-48 +-51 +-54 +-54 +-54 +-54 +-52 +-51 +-48 +-46 +-43 +-41 +-39 +-37 +-35 +-34 +-32 +-30 +-28 +-27 +-24 +-23 +-21 +-20 +-19 +-18 +-17 +-8 +14 +29 +40 +46 +51 +53 +54 +55 +54 +52 +51 +49 +48 +46 +43 +35 +15 +0 +-12 +-20 +-26 +-30 +-34 +-35 +-36 +-35 +-36 +-36 +-36 +-34 +-33 +-22 +-1 +14 +24 +32 +37 +41 +43 +44 +45 +44 +44 +43 +41 +40 +38 +30 +9 +-6 +-19 +-28 +-34 +-38 +-41 +-42 +-43 +-43 +-42 +-41 +-40 +-38 +-36 +-26 +-4 +11 +21 +29 +34 +38 +40 +42 +43 +42 +42 +41 +40 +38 +37 +30 +10 +-5 +-17 +-25 +-31 +-36 +-38 +-40 +-41 +-42 +-41 +-40 +-38 +-37 +-35 +-25 +-3 +11 +23 +31 +37 +40 +43 +43 +43 +43 +42 +40 +39 +37 +36 +28 +8 +-7 +-19 +-27 +-32 +-36 +-39 +-41 +-42 +-41 +-41 +-40 +-39 +-38 +-36 +-26 +-5 +10 +21 +29 +35 +38 +40 +42 +42 +41 +41 +41 +39 +37 +35 +26 +7 +-9 +-21 +-29 +-35 +-39 +-42 +-43 +-44 +-44 +-42 +-40 +-39 +-38 +-36 +-26 +-5 +10 +20 +28 +33 +37 +39 +40 +41 +40 +40 +39 +38 +37 +36 +28 +9 +-6 +-18 +-27 +-33 +-37 +-40 +-42 +-43 +-42 +-41 +-40 +-38 +-37 +-35 +-24 +-2 +13 +25 +32 +38 +42 +44 +46 +47 +47 +45 +43 +41 +39 +38 +30 +10 +-5 +-16 +-24 +-31 +-35 +-38 +-39 +-39 +-38 +-39 +-38 +-36 +-35 +-34 +-24 +-2 +12 +23 +31 +37 +39 +42 +42 +43 +43 +43 +41 +40 +38 +37 +29 +10 +-5 +-17 +-26 +-32 +-37 +-40 +-41 +-42 +-42 +-42 +-40 +-39 +-37 +-36 +-25 +-3 +11 +23 +31 +36 +39 +42 +42 +43 +42 +42 +40 +39 +37 +36 +35 +33 +30 +29 +27 +26 +24 +24 +22 +21 +21 +21 +19 +17 +16 +15 +7 +-12 +-26 +-36 +-44 +-49 +-53 +-54 +-55 +-55 +-54 +-53 +-51 +-49 +-47 +-45 +-34 +-12 +4 +15 +23 +29 +33 +35 +36 +37 +37 +37 +36 +36 +34 +33 +25 +6 +-9 +-21 +-29 +-36 +-40 +-43 +-44 +-45 +-44 +-44 +-43 +-42 +-40 +-39 +-28 +-6 +9 +22 +29 +35 +38 +41 +42 +42 +41 +40 +38 +37 +36 +35 +26 +7 +-8 +-19 +-29 +-34 +-38 +-41 +-42 +-42 +-42 +-41 +-40 +-39 +-38 +-37 +-26 +-5 +10 +22 +31 +36 +40 +42 +43 +43 +44 +43 +41 +40 +38 +37 +28 +8 +-8 +-19 +-28 +-34 +-39 +-41 +-43 +-43 +-44 +-43 +-42 +-41 +-40 +-38 +-27 +-6 +9 +20 +28 +33 +36 +39 +39 +41 +41 +40 +39 +38 +36 +35 +28 +9 +-6 +-18 +-26 +-32 +-36 +-40 +-41 +-42 +-42 +-40 +-39 +-38 +-37 +-35 +-25 +-4 +12 +23 +31 +36 +40 +42 +43 +43 +43 +42 +40 +40 +38 +36 +28 +8 +-8 +-19 +-28 +-34 +-38 +-41 +-42 +-42 +-43 +-43 +-42 +-41 +-39 +-38 +-27 +-5 +10 +21 +30 +35 +38 +41 +43 +43 +43 +42 +41 +41 +39 +37 +29 +9 +-7 +-18 +-27 +-33 +-38 +-40 +-42 +-43 +-43 +-42 +-41 +-39 +-38 +-36 +-25 +-3 +11 +22 +30 +35 +37 +40 +41 +42 +41 +40 +39 +38 +36 +35 +27 +8 +-7 +-19 +-28 +-33 +-38 +-40 +-42 +-43 +-44 +-43 +-42 +-40 +-39 +-37 +-26 +-5 +10 +22 +30 +36 +40 +43 +43 +44 +43 +43 +41 +40 +38 +37 +28 +8 +-7 +-19 +-27 +-33 +-38 +-39 +-41 +-41 +-41 +-40 +-39 +-38 +-37 +-35 +-34 +-32 +-30 +-28 +-26 +-25 +-22 +-21 +-19 +-18 +-16 +-15 +-13 +-11 +-11 +-10 +0 +20 +33 +43 +49 +54 +56 +57 +57 +56 +55 +53 +52 +50 +47 +45 +36 +16 +-1 +-13 +-22 +-29 +-34 +-37 +-39 +-40 +-40 +-40 +-39 +-37 +-36 +-35 +-24 +-2 +12 +24 +32 +37 +40 +43 +43 +43 +43 +42 +41 +40 +38 +37 +29 +9 +-6 +-17 +-26 +-32 +-36 +-39 +-40 +-42 +-42 +-42 +-40 +-39 +-37 +-36 +-25 +-4 +12 +23 +31 +36 +39 +42 +43 +44 +45 +45 +43 +42 +39 +37 +28 +8 +-7 +-18 +-27 +-34 +-37 +-39 +-41 +-43 +-42 +-41 +-40 +-39 +-36 +-35 +-24 +-2 +12 +22 +30 +35 +38 +41 +42 +43 +42 +42 +41 +40 +38 +37 +29 +9 +-6 +-18 +-26 +-32 +-38 +-40 +-42 +-43 +-43 +-42 +-41 +-39 +-38 +-36 +-26 +-4 +12 +23 +31 +37 +41 +43 +43 +43 +42 +42 +40 +39 +37 +36 +28 +9 +-7 +-18 +-27 +-32 +-37 +-40 +-41 +-42 +-42 +-42 +-41 +-40 +-39 +-37 +-27 +-6 +10 +21 +29 +35 +39 +41 +42 +43 +43 +42 +41 +40 +38 +36 +28 +8 +-7 +-19 +-28 +-34 +-38 +-40 +-42 +-43 +-44 +-42 +-41 +-39 +-37 +-35 +-25 +-4 +11 +23 +30 +36 +39 +42 +43 +43 +43 +43 +41 +40 +38 +38 +29 +9 +-6 +-17 +-26 +-32 +-36 +-39 +-42 +-43 +-43 +-42 +-41 +-39 +-38 +-36 +-25 +-3 +12 +24 +31 +37 +40 +43 +44 +45 +44 +42 +40 +39 +37 +36 +28 +8 +-7 +-18 +-27 +-33 +-37 +-40 +-41 +-41 +-41 +-40 +-39 +-38 +-36 +-35 +-25 +-3 +11 +22 +30 +36 +39 +42 +44 +44 +43 +43 +42 +40 +38 +37 +35 +33 +31 +29 +27 +26 +24 +22 +21 +20 +19 +18 +17 +15 +15 +14 +7 +-13 +-26 +-37 +-45 +-51 +-54 +-56 +-58 +-58 +-57 +-55 +-54 +-51 +-49 +-47 +-35 +-13 +2 +14 +22 +28 +32 +34 +35 +36 +36 +35 +34 +32 +31 +30 +22 +3 +-12 +-23 +-30 +-36 +-41 +-43 +-44 +-45 +-44 +-43 +-43 +-42 +-40 +-38 +-27 +-6 +9 +21 +29 +34 +38 +40 +42 +43 +43 +42 +42 +41 +39 +38 +29 +9 +-6 +-17 +-27 +-33 +-38 +-40 +-42 +-42 +-43 +-42 +-40 +-38 +-37 +-36 +-25 +-3 +12 +23 +31 +36 +39 +41 +42 +42 +42 +41 +41 +39 +38 +37 +29 +10 +-6 +-17 +-26 +-32 +-37 +-40 +-42 +-43 +-43 +-43 +-41 +-40 +-38 +-36 +-25 +-3 +11 +23 +31 +36 +39 +42 +43 +43 +42 +41 +40 +40 +37 +36 +27 +8 +-7 +-19 +-28 +-34 +-38 +-40 +-42 +-42 +-42 +-42 +-41 +-39 +-38 +-36 +-26 +-4 +10 +21 +29 +34 +37 +40 +42 +43 +43 +43 +42 +42 +40 +38 +30 +10 +-6 +-17 +-25 +-31 +-35 +-38 +-39 +-41 +-40 +-40 +-39 +-37 +-36 +-34 +-23 +-1 +14 +25 +32 +39 +42 +43 +44 +44 +43 +43 +41 +40 +38 +37 +28 +9 +-6 +-18 +-27 +-32 +-36 +-39 +-40 +-41 +-41 +-41 +-40 +-39 +-38 +-37 +-26 +-4 +10 +22 +30 +35 +38 +41 +42 +43 +42 +42 +41 +40 +38 +37 +28 +8 +-8 +-19 +-28 +-34 +-39 +-41 +-43 +-43 +-44 +-43 +-42 +-40 +-38 +-35 +-25 +-3 +12 +22 +29 +35 +38 +40 +41 +42 +42 +41 +40 +39 +38 +36 +28 +8 +-7 +-18 +-27 +-33 +-37 +-40 +-42 +-43 +-43 +-43 +-42 +-40 +-38 +-36 +-25 +-3 +12 +22 +30 +36 +40 +43 +44 +44 +44 +43 +42 +40 +38 +37 +29 +9 +-6 +-18 +-27 +-31 +-36 +-39 +-41 +-41 +-40 +-40 +-39 +-37 +-36 +-35 +-25 +-3 +11 +23 +31 +36 +40 +42 +44 +45 +45 +44 +42 +41 +39 +38 +29 +10 +-6 +-18 +-27 +-33 +-37 +-40 +-42 +-43 +-43 +-43 +-41 +-39 +-38 +-37 +-35 +-33 +-31 +-29 +-29 +-27 +-27 +-25 +-25 +-23 +-22 +-20 +-18 +-17 +-16 +-15 +-4 +16 +31 +41 +48 +52 +54 +55 +55 +54 +54 +52 +50 +48 +46 +44 +35 +15 +-1 +-13 +-22 +-28 +-32 +-36 +-37 +-39 +-40 +-40 +-39 +-38 +-37 +-35 +-25 +-3 +12 +22 +31 +36 +39 +42 +44 +44 +43 +43 +41 +40 +38 +36 +34 +32 +31 +30 +28 +27 +25 +24 +23 +22 +20 +19 +19 +18 +17 +17 +10 +-9 +-24 +-35 +-42 +-48 +-51 +-53 +-54 +-54 +-53 +-52 +-49 +-47 +-45 +-43 +-32 +-10 +5 +17 +25 +31 +35 +38 +39 +39 +38 +39 +37 +36 +35 +34 +25 +6 +-9 +-20 +-28 +-34 +-38 +-39 +-41 +-42 +-43 +-42 +-42 +-41 +-40 +-38 +-28 +-6 +9 +21 +29 +35 +38 +41 +41 +42 +43 +42 +41 +39 +37 +35 +26 +6 +-9 +-20 +-29 +-35 +-39 +-41 +-43 +-43 +-44 +-42 +-41 +-40 +-38 +-36 +-34 +-32 +-31 +-29 +-28 +-26 +-25 +-23 +-21 +-19 +-17 +-16 +-16 +-14 +-13 +-12 +-2 +19 +33 +43 +50 +54 +57 +58 +59 +58 +57 +55 +52 +51 +48 +46 +43 +42 +38 +37 +34 +32 +30 +30 +28 +27 +24 +23 +21 +20 +18 +17 +9 +-10 +-25 +-35 +-43 +-48 +-51 +-53 +-54 +-54 +-53 +-51 +-49 +-47 +-45 +-43 +-32 +-10 +5 +16 +24 +29 +33 +35 +37 +38 +38 +38 +36 +36 +34 +33 +25 +6 +-10 +-21 +-29 +-35 +-39 +-42 +-44 +-44 +-44 +-43 +-43 +-42 +-40 +-38 +-37 +-34 +-32 +-30 +-28 +-26 +-24 +-22 +-20 +-18 +-17 +-16 +-14 +-14 +-12 +-11 +-3 +18 +31 +42 +49 +54 +57 +58 +58 +58 +57 +56 +54 +52 +50 +48 +46 +44 +41 +39 +36 +34 +31 +29 +27 +26 +24 +23 +22 +20 +19 +18 +11 +-8 +-22 +-33 +-41 +-46 +-49 +-52 +-53 +-54 +-53 +-52 +-50 +-49 +-47 +-45 +-34 +-12 +4 +16 +24 +30 +34 +38 +40 +41 +40 +39 +39 +38 +37 +35 +27 +7 +-8 +-20 +-29 +-35 +-40 +-42 +-44 +-43 +-44 +-43 +-42 +-40 +-39 +-37 +-26 +-5 +10 +21 +28 +33 +37 +38 +39 +40 +39 +38 +38 +37 +35 +34 +26 +6 +-9 +-20 +-29 +-34 +-38 +-42 +-43 +-44 +-44 +-43 +-43 +-42 +-40 +-38 +-27 +-5 +10 +22 +30 +35 +39 +41 +43 +43 +44 +44 +43 +41 +40 +39 +30 +10 +-6 +-16 +-26 +-31 +-36 +-38 +-40 +-41 +-41 +-40 +-39 +-37 +-36 +-35 +-32 +-31 +-30 +-28 +-27 +-26 +-25 +-23 +-23 +-22 +-21 +-20 +-19 +-17 +-16 +-15 +-5 +16 +30 +40 +47 +51 +54 +55 +56 +55 +53 +52 +50 +48 +46 +44 +35 +15 +0 +-12 +-21 +-27 +-32 +-35 +-37 +-37 +-37 +-36 +-35 +-34 +-33 +-32 +-22 +-1 +14 +25 +33 +38 +42 +45 +45 +45 +44 +44 +43 +41 +40 +38 +30 +11 +-5 +-17 +-26 +-32 +-37 +-41 +-42 +-43 +-43 +-42 +-41 +-39 +-38 +-36 +-26 +-4 +11 +23 +31 +36 +40 +43 +43 +44 +43 +41 +40 +39 +37 +35 +34 +32 +31 +29 +28 +26 +24 +23 +21 +21 +20 +19 +18 +17 +16 +15 +7 +-13 +-28 +-39 +-46 +-51 +-54 +-56 +-57 +-56 +-55 +-54 +-52 +-50 +-47 +-45 +-34 +-12 +3 +15 +23 +29 +32 +34 +36 +37 +37 +37 +36 +35 +34 +33 +25 +6 +-8 +-20 +-28 +-34 +-37 +-40 +-42 +-43 +-43 +-43 +-42 +-41 +-39 +-38 +-36 +-35 +-33 +-31 +-30 +-28 +-26 +-24 +-23 +-21 +-20 +-18 +-17 +-16 +-15 +-14 +-5 +16 +29 +40 +46 +51 +53 +55 +55 +56 +55 +53 +51 +49 +48 +45 +43 +41 +39 +37 +34 +32 +30 +28 +26 +25 +24 +22 +21 +20 +19 +18 +10 +-8 +-23 +-34 +-41 +-47 +-50 +-53 +-54 +-54 +-53 +-52 +-51 +-48 +-46 +-44 +-33 +-11 +4 +16 +25 +31 +35 +37 +38 +39 +39 +38 +37 +35 +34 +34 +25 +5 +-10 +-21 +-30 +-36 +-39 +-42 +-43 +-44 +-43 +-42 +-40 +-39 +-36 +-34 +-24 +-2 +13 +24 +32 +38 +41 +43 +44 +45 +45 +44 +43 +42 +40 +39 +31 +11 +-4 +-15 +-24 +-31 +-35 +-38 +-40 +-41 +-41 +-41 +-41 +-40 +-39 +-37 +-27 +-5 +10 +21 +29 +34 +37 +40 +41 +42 +42 +41 +39 +38 +37 +35 +26 +5 +-9 +-21 +-29 +-36 +-39 +-42 +-44 +-45 +-44 +-43 +-42 +-41 +-39 +-37 +-27 +-4 +11 +21 +29 +34 +38 +40 +41 +42 +42 +41 +40 +39 +38 +36 +28 +9 +-6 +-18 +-26 +-33 +-38 +-41 +-43 +-43 +-43 +-41 +-41 +-40 +-38 +-36 +-26 +-4 +11 +22 +31 +37 +40 +42 +43 +43 +42 +42 +41 +39 +37 +36 +27 +8 +-8 +-19 +-28 +-34 +-39 +-41 +-42 +-42 +-41 +-40 +-40 +-39 +-38 +-37 +-27 +-5 +10 +21 +29 +35 +39 +42 +43 +44 +44 +43 +42 +41 +39 +38 +30 +10 +-5 +-17 +-26 +-33 +-37 +-40 +-41 +-42 +-42 +-41 +-40 +-39 +-37 +-35 +-24 +-2 +13 +24 +32 +37 +41 +43 +43 +43 +43 +42 +40 +39 +37 +36 +28 +8 +-7 +-18 +-27 +-33 +-38 +-40 +-42 +-43 +-43 +-43 +-42 +-40 +-39 +-38 +-37 +-35 +-33 +-31 +-30 +-28 +-26 +-24 +-23 +-21 +-19 +-17 +-17 +-16 +-16 +-15 +-6 +15 +29 +39 +45 +50 +53 +55 +55 +55 +54 +53 +51 +51 +49 +46 +37 +17 +0 +-12 +-21 +-28 +-32 +-35 +-37 +-37 +-38 +-37 +-37 +-35 +-34 +-32 +-21 +1 +16 +27 +35 +40 +43 +45 +46 +46 +46 +44 +43 +42 +41 +39 +31 +11 +-4 +-16 +-24 +-30 +-34 +-37 +-39 +-40 +-41 +-40 +-40 +-39 +-37 +-36 +-26 +-4 +12 +22 +30 +36 +39 +41 +43 +44 +43 +42 +41 +40 +38 +36 +28 +8 +-7 +-19 +-27 +-33 +-37 +-40 +-41 +-42 +-42 +-41 +-39 +-38 +-36 +-34 +-23 +-1 +14 +24 +32 +38 +41 +43 +44 +44 +44 +44 +43 +43 +41 +39 +31 +11 +-4 +-15 +-24 +-31 +-35 +-38 +-39 +-41 +-42 +-41 +-41 +-39 +-38 +-36 +-26 +-4 +11 +22 +29 +35 +38 +41 +42 +42 +41 +41 +39 +37 +35 +34 +25 +6 +-9 +-21 +-30 +-35 +-39 +-42 +-43 +-44 +-44 +-43 +-41 +-40 +-39 +-37 +-27 +-5 +9 +20 +29 +34 +38 +40 +42 +42 +42 +42 +41 +40 +39 +38 +30 +10 +-6 +-18 +-27 +-33 +-37 +-40 +-42 +-42 +-42 +-42 +-41 +-39 +-38 +-36 +-25 +-3 +12 +24 +31 +37 +41 +43 +45 +46 +45 +43 +42 +40 +38 +37 +29 +10 +-5 +-17 +-26 +-31 +-35 +-38 +-40 +-40 +-40 +-40 +-39 +-39 +-38 +-36 +-26 +-4 +11 +22 +30 +36 +39 +42 +43 +43 +43 +42 +41 +40 +38 +36 +28 +9 +-8 +-20 +-29 +-36 +-40 +-42 +-44 +-45 +-44 +-43 +-42 +-40 +-38 +-36 +-25 +-3 +12 +23 +30 +35 +38 +41 +42 +42 +42 +42 +40 +39 +37 +36 +34 +33 +31 +30 +29 +28 +26 +24 +22 +20 +19 +17 +16 +15 +14 +13 +6 +-13 +-27 +-38 +-45 +-51 +-53 +-55 +-55 +-55 +-55 +-53 +-52 +-50 +-47 +-45 +-34 +-12 +3 +16 +23 +29 +33 +36 +38 +39 +39 +39 +38 +37 +36 +34 +26 +6 +-9 +-21 +-29 +-35 +-39 +-42 +-44 +-44 +-44 +-43 +-42 +-41 +-39 +-37 +-27 +-5 +9 +21 +28 +33 +36 +39 +40 +41 +40 +40 +39 +38 +36 +35 +27 +8 +-8 +-20 +-28 +-35 +-39 +-42 +-44 +-44 +-45 +-44 +-44 +-42 +-40 +-38 +-28 +-6 +10 +21 +29 +34 +37 +40 +41 +42 +42 +41 +40 +39 +38 +37 +29 +9 +-5 +-16 +-26 +-32 +-35 +-39 +-41 +-42 +-42 +-41 +-40 +-39 +-37 +-35 +-25 +-3 +12 +24 +32 +37 +41 +44 +45 +46 +44 +43 +41 +39 +37 +36 +28 +8 +-7 +-18 +-27 +-33 +-38 +-40 +-42 +-41 +-40 +-39 +-39 +-38 +-37 +-35 +-25 +-4 +11 +22 +30 +35 +39 +42 +43 +44 +44 +43 +42 +41 +39 +37 +28 +8 +-8 +-19 +-28 +-34 +-39 +-40 +-42 +-43 +-43 +-42 +-41 +-39 +-38 +-36 +-25 +-3 +12 +23 +31 +37 +40 +42 +43 +43 +43 +43 +41 +41 +39 +38 +30 +9 +-6 +-18 +-27 +-34 +-39 +-42 +-44 +-44 +-45 +-44 +-43 +-42 +-41 +-38 +-27 +-6 +9 +20 +28 +34 +37 +39 +40 +41 +40 +40 +39 +38 +36 +35 +27 +8 +-7 +-18 +-27 +-32 +-37 +-39 +-40 +-41 +-41 +-41 +-40 +-39 +-38 +-36 +-34 +-32 +-30 +-28 +-26 +-25 +-24 +-22 +-20 +-18 +-17 +-16 +-15 +-15 +-14 +-14 +-5 +15 +30 +40 +47 +52 +55 +56 +57 +56 +54 +53 +51 +50 +48 +46 +43 +40 +38 +36 +34 +33 +30 +29 +27 +26 +24 +23 +21 +21 +19 +19 +11 +-9 +-23 +-34 +-42 +-48 +-52 +-54 +-54 +-54 +-53 +-52 +-50 +-48 +-46 +-43 +-41 +-39 +-37 +-35 +-33 +-31 +-30 +-28 +-27 +-25 +-23 +-22 +-20 +-19 +-17 +-16 +-6 +15 +29 +41 +47 +52 +54 +55 +55 +55 +54 +53 +50 +48 +46 +45 +42 +40 +37 +35 +34 +32 +30 +29 +27 +26 +24 +23 +21 +20 +18 +16 +9 +-10 +-25 +-35 +-43 +-48 +-51 +-53 +-54 +-54 +-53 +-51 +-50 +-48 +-46 +-44 +-42 +-40 +-38 +-36 +-34 +-32 +-31 +-28 +-26 +-24 +-22 +-20 +-19 +-17 +-16 +-15 +-5 +17 +31 +40 +46 +50 +52 +54 +54 +54 +52 +51 +50 +48 +46 +44 +41 +40 +38 +36 +34 +32 +30 +28 +27 +25 +23 +21 +20 +18 +17 +16 +8 +-10 +-24 +-35 +-42 +-47 +-50 +-52 +-53 +-53 +-53 +-52 +-51 +-49 +-47 +-44 +-42 +-40 +-37 +-35 +-33 +-31 +-28 +-27 +-25 +-24 +-22 +-20 +-18 +-16 +-15 +-15 +-5 +15 +30 +40 +47 +52 +55 +56 +56 +56 +55 +54 +52 +50 +47 +46 +42 +40 +38 +36 +34 +32 +30 +28 +27 +25 +24 +22 +21 +20 +18 +18 +10 +-9 +-23 +-35 +-42 +-48 +-51 +-54 +-55 +-55 +-54 +-53 +-51 +-49 +-47 +-45 +-42 +-39 +-38 +-36 +-33 +-32 +-30 +-28 +-27 +-25 +-24 +-22 +-21 +-19 +-18 +-17 +-7 +14 +29 +39 +46 +51 +54 +55 +55 +54 +53 +51 +49 +47 +45 +44 +42 +40 +38 +36 +33 +32 +30 +28 +26 +25 +23 +21 +20 +18 +17 +17 +10 +-9 +-24 +-34 +-42 +-48 +-51 +-53 +-53 +-53 +-52 +-51 +-50 +-48 +-46 +-45 +-42 +-40 +-38 +-36 +-33 +-32 +-29 +-28 +-26 +-24 +-22 +-20 +-18 +-17 +-16 +-15 +-5 +15 +29 +39 +46 +51 +54 +55 +56 +56 +55 +53 +52 +50 +49 +47 +39 +18 +2 +-11 +-20 +-26 +-31 +-34 +-36 +-37 +-37 +-36 +-36 +-35 +-34 +-32 +-22 +0 +15 +26 +34 +38 +42 +43 +44 +44 +44 +44 +42 +41 +39 +37 +28 +9 +-6 +-17 +-26 +-31 +-36 +-39 +-41 +-42 +-43 +-43 +-42 +-41 +-40 +-38 +-27 +-6 +9 +21 +29 +35 +39 +41 +42 +43 +43 +42 +41 +39 +38 +36 +28 +8 +-7 +-18 +-27 +-34 +-38 +-40 +-41 +-42 +-41 +-40 +-39 +-38 +-36 +-34 +-24 +-3 +12 +23 +31 +36 +40 +43 +44 +45 +44 +44 +43 +42 +41 +40 +31 +11 +-5 +-16 +-25 +-32 +-37 +-40 +-42 +-42 +-43 +-42 +-41 +-40 +-38 +-36 +-25 +-3 +12 +23 +31 +37 +39 +42 +43 +43 +43 +43 +41 +40 +38 +37 +29 +9 +-7 +-18 +-27 +-33 +-37 +-39 +-41 +-42 +-43 +-42 +-42 +-40 +-38 +-37 +-27 +-5 +10 +21 +29 +34 +38 +41 +42 +43 +43 +42 +41 +39 +37 +36 +27 +8 +-8 +-20 +-28 +-34 +-38 +-40 +-42 +-43 +-42 +-41 +-40 +-39 +-37 +-36 +-26 +-4 +10 +21 +28 +34 +37 +40 +41 +42 +42 +42 +41 +40 +39 +37 +29 +9 +-6 +-18 +-27 +-34 +-39 +-42 +-43 +-44 +-43 +-42 +-41 +-39 +-39 +-37 +-26 +-3 +11 +23 +32 +38 +41 +43 +44 +44 +44 +43 +42 +41 +40 +39 +30 +11 +-4 +-16 +-25 +-31 +-35 +-38 +-40 +-42 +-42 +-41 +-40 +-39 +-38 +-37 +-26 +-5 +10 +22 +30 +35 +38 +41 +43 +44 +43 +43 +41 +40 +38 +36 +35 +33 +31 +29 +27 +26 +24 +23 +22 +21 +19 +18 +17 +16 +15 +14 +6 +-13 +-28 +-39 +-47 +-53 +-56 +-58 +-59 +-58 +-57 +-56 +-54 +-52 +-49 +-47 +-35 +-13 +3 +14 +22 +28 +33 +36 +37 +37 +37 +37 +36 +35 +34 +32 +24 +4 +-10 +-21 +-29 +-36 +-40 +-42 +-44 +-44 +-44 +-44 +-43 +-42 +-40 +-39 +-29 +-7 +8 +20 +28 +34 +37 +40 +41 +42 +42 +42 +41 +40 +38 +36 +28 +8 +-8 +-19 +-28 +-34 +-37 +-40 +-41 +-42 +-41 +-41 +-40 +-39 +-37 +-35 +-24 +-2 +13 +23 +31 +36 +39 +42 +43 +43 +43 +42 +42 +41 +40 +38 +30 +11 +-5 +-16 +-24 +-30 +-35 +-38 +-41 +-41 +-41 +-41 +-40 +-39 +-37 +-35 +-25 +-3 +11 +23 +31 +36 +40 +43 +44 +45 +45 +44 +43 +41 +38 +37 +29 +9 +-6 +-18 +-26 +-32 +-36 +-39 +-41 +-41 +-41 +-40 +-40 +-38 +-36 +-34 +-25 +-4 +10 +21 +29 +34 +38 +40 +42 +42 +42 +42 +41 +40 +38 +36 +29 +10 +-6 +-18 +-28 +-34 +-38 +-42 +-44 +-44 +-44 +-43 +-42 +-40 +-39 +-37 +-27 +-5 +9 +21 +29 +35 +39 +41 +42 +43 +42 +42 +40 +39 +37 +35 +27 +7 +-8 +-19 +-28 +-34 +-38 +-41 +-42 +-42 +-42 +-42 +-41 +-40 +-38 +-36 +-26 +-5 +10 +21 +28 +34 +38 +41 +42 +42 +42 +43 +42 +41 +40 +38 +29 +9 +-6 +-18 +-27 +-33 +-37 +-39 +-41 +-42 +-42 +-42 +-41 +-39 +-37 +-35 +-25 +-2 +13 +24 +32 +37 +40 +43 +44 +44 +44 +44 +42 +41 +39 +38 +29 +10 +-5 +-17 +-25 +-31 +-35 +-38 +-40 +-41 +-41 +-41 +-41 +-40 +-38 +-36 +-35 +-33 +-31 +-30 +-28 +-27 +-25 +-23 +-22 +-21 +-19 +-18 +-16 +-16 +-14 +-13 +-4 +16 +31 +41 +47 +52 +55 +57 +57 +57 +55 +54 +53 +51 +49 +48 +45 +43 +40 +38 +36 +34 +32 +30 +28 +26 +24 +23 +21 +20 +20 +19 +11 +-9 +-23 +-33 +-41 +-47 +-51 +-53 +-54 +-54 +-54 +-53 +-51 +-49 +-47 +-45 +-34 +-12 +4 +16 +25 +30 +34 +37 +38 +39 +39 +38 +37 +36 +34 +33 +25 +5 +-10 +-21 +-30 +-35 +-40 +-41 +-43 +-43 +-43 +-43 +-41 +-39 +-38 +-36 +-26 +-5 +10 +22 +30 +36 +40 +42 +43 +43 +42 +42 +41 +40 +39 +38 +29 +9 +-7 +-19 +-28 +-34 +-39 +-41 +-43 +-43 +-44 +-43 +-42 +-41 +-39 +-37 +-35 +-33 +-31 +-29 +-28 +-27 +-26 +-24 +-24 +-23 +-22 +-20 +-18 +-17 +-15 +-15 +-4 +17 +31 +41 +48 +52 +55 +56 +55 +54 +53 +52 +50 +48 +46 +44 +41 +39 +37 +35 +33 +32 +30 +29 +26 +24 +22 +21 +19 +18 +17 +16 +7 +-11 +-26 +-36 +-44 +-49 +-52 +-54 +-54 +-54 +-53 +-51 +-49 +-47 +-45 +-43 +-32 +-10 +5 +17 +25 +32 +35 +38 +39 +40 +40 +40 +39 +38 +37 +35 +27 +8 +-7 +-18 +-27 +-34 +-39 +-41 +-43 +-43 +-43 +-41 +-41 +-40 +-38 +-36 +-35 +-33 +-31 +-29 +-28 +-27 +-25 +-24 +-23 +-21 +-19 +-17 +-16 +-16 +-15 +-14 +-4 +17 +32 +42 +49 +54 +57 +58 +57 +57 +55 +54 +52 +50 +48 +46 +37 +17 +2 +-10 +-19 +-26 +-31 +-33 +-35 +-36 +-37 +-37 +-36 +-36 +-34 +-33 +-23 +-2 +13 +24 +32 +37 +41 +44 +45 +46 +46 +45 +43 +42 +40 +38 +36 +35 +32 +30 +28 +27 +25 +24 +22 +21 +19 +19 +17 +18 +16 +15 +7 +-12 +-26 +-37 +-46 +-51 +-55 +-57 +-57 +-57 +-56 +-54 +-52 +-49 +-47 +-45 +-42 +-40 +-37 +-35 +-33 +-31 +-30 +-28 +-26 +-23 +-22 +-21 +-20 +-19 +-18 +-16 +-6 +15 +29 +40 +46 +51 +54 +56 +56 +56 +55 +53 +50 +49 +47 +45 +43 +40 +37 +36 +34 +32 +30 +29 +27 +26 +24 +23 +21 +20 +18 +17 +9 +-10 +-24 +-35 +-43 +-48 +-52 +-53 +-54 +-53 +-52 +-50 +-48 +-46 +-44 +-42 +-31 +-10 +6 +17 +25 +31 +35 +37 +39 +39 +39 +39 +39 +37 +37 +36 +28 +8 +-6 +-18 +-27 +-34 +-38 +-41 +-42 +-43 +-43 +-42 +-41 +-40 +-38 +-36 +-34 +-32 +-31 +-29 +-27 +-26 +-25 +-24 +-23 +-22 +-20 +-18 +-17 +-17 +-16 +-16 +-6 +15 +29 +39 +46 +51 +54 +54 +54 +53 +52 +51 +49 +48 +45 +43 +41 +39 +36 +34 +32 +31 +29 +28 +26 +24 +23 +21 +20 +18 +17 +15 +8 +-11 +-26 +-36 +-44 +-49 +-51 +-53 +-54 +-54 +-53 +-51 +-49 +-47 +-46 +-44 +-33 +-10 +6 +18 +26 +31 +35 +37 +39 +40 +40 +40 +39 +38 +37 +36 +29 +9 +-7 +-19 +-27 +-34 +-38 +-41 +-43 +-43 +-44 +-43 +-42 +-40 +-38 +-36 +-34 +-33 +-32 +-30 +-29 +-27 +-25 +-23 +-23 +-22 +-21 +-19 +-18 +-17 +-16 +-15 +-5 +16 +30 +40 +47 +52 +55 +57 +57 +56 +55 +53 +51 +49 +46 +44 +41 +40 +38 +36 +34 +32 +31 +29 +28 +27 +25 +23 +22 +20 +19 +18 +10 +-9 +-23 +-33 +-41 +-47 +-50 +-52 +-53 +-52 +-51 +-49 +-47 +-45 +-43 +-41 +-39 +-37 +-36 +-34 +-32 +-30 +-28 +-26 +-24 +-23 +-22 +-20 +-18 +-17 +-16 +-15 +-4 +17 +31 +41 +48 +52 +55 +57 +57 +56 +54 +53 +51 +50 +47 +45 +36 +16 +1 +-11 +-21 +-27 +-32 +-35 +-37 +-39 +-40 +-39 +-38 +-37 +-36 +-35 +-24 +-3 +12 +23 +31 +36 +40 +42 +42 +42 +42 +41 +39 +38 +36 +35 +27 +7 +-8 +-20 +-28 +-34 +-38 +-41 +-42 +-42 +-42 +-41 +-40 +-38 +-37 +-36 +-24 +-3 +12 +23 +31 +37 +41 +44 +45 +45 +45 +44 +44 +42 +41 +39 +30 +10 +-6 +-17 +-26 +-32 +-36 +-39 +-41 +-42 +-41 +-41 +-40 +-39 +-37 +-36 +-26 +-4 +10 +21 +29 +35 +39 +42 +42 +43 +43 +42 +41 +40 +38 +37 +29 +10 +-5 +-16 +-26 +-32 +-36 +-39 +-41 +-42 +-42 +-41 +-41 +-39 +-38 +-36 +-26 +-4 +11 +23 +30 +35 +39 +41 +42 +42 +42 +41 +40 +39 +37 +36 +28 +9 +-6 +-17 +-25 +-31 +-36 +-39 +-40 +-41 +-42 +-41 +-40 +-39 +-38 +-36 +-26 +-4 +11 +22 +30 +35 +39 +42 +43 +44 +43 +42 +40 +39 +37 +35 +27 +7 +-8 +-19 +-28 +-34 +-39 +-41 +-42 +-43 +-43 +-42 +-41 +-40 +-38 +-37 +-26 +-5 +10 +21 +29 +35 +38 +40 +41 +42 +42 +41 +41 +40 +39 +37 +28 +8 +-7 +-19 +-28 +-34 +-38 +-42 +-43 +-43 +-44 +-43 +-42 +-41 +-39 +-37 +-25 +-4 +10 +21 +30 +34 +37 +40 +40 +41 +40 +40 +40 +38 +36 +35 +27 +8 +-8 +-18 +-27 +-33 +-38 +-41 +-42 +-43 +-43 +-43 +-42 +-40 +-38 +-36 +-24 +-3 +11 +22 +30 +35 +39 +41 +43 +43 +44 +42 +42 +40 +38 +36 +35 +33 +31 +29 +28 +27 +25 +24 +22 +21 +20 +19 +18 +17 +16 +15 +7 +-12 +-26 +-37 +-45 +-50 +-54 +-56 +-56 +-55 +-54 +-52 +-51 +-48 +-46 +-44 +-32 +-10 +5 +18 +26 +31 +36 +38 +39 +40 +39 +39 +38 +38 +36 +35 +27 +8 +-7 +-18 +-27 +-32 +-36 +-39 +-41 +-42 +-42 +-42 +-41 +-40 +-39 +-37 +-27 +-5 +10 +21 +30 +35 +39 +41 +43 +43 +43 +42 +41 +41 +39 +37 +28 +9 +-7 +-18 +-27 +-33 +-38 +-40 +-42 +-42 +-42 +-41 +-40 +-38 +-36 +-34 +-24 +-3 +12 +23 +30 +35 +38 +41 +42 +43 +43 +43 +42 +41 +39 +38 +29 +10 +-6 +-17 +-26 +-32 +-37 +-39 +-41 +-42 +-43 +-42 +-41 +-40 +-38 +-37 +-27 +-5 +10 +21 +29 +35 +38 +41 +42 +43 +42 +42 +41 +40 +38 +36 +28 +8 +-8 +-20 +-28 +-34 +-38 +-41 +-43 +-43 +-43 +-41 +-40 +-39 +-37 +-36 +-26 +-5 +10 +21 +29 +34 +38 +41 +42 +42 +42 +42 +40 +39 +38 +36 +28 +9 +-6 +-18 +-27 +-33 +-36 +-39 +-42 +-43 +-44 +-43 +-42 +-40 +-38 +-36 +-26 +-4 +11 +22 +30 +36 +39 +41 +41 +41 +41 +41 +39 +39 +38 +36 +28 +9 +-7 +-18 +-27 +-33 +-37 +-40 +-42 +-42 +-42 +-42 +-41 +-40 +-38 +-37 +-27 +-5 +10 +21 +30 +36 +40 +42 +43 +43 +44 +43 +42 +41 +39 +37 +29 +10 +-5 +-17 +-26 +-32 +-37 +-39 +-41 +-41 +-41 +-40 +-39 +-38 +-36 +-35 +-24 +-2 +13 +24 +31 +36 +39 +42 +43 +43 +42 +41 +39 +38 +37 +36 +27 +8 +-7 +-19 +-27 +-33 +-37 +-40 +-42 +-44 +-44 +-43 +-42 +-40 +-39 +-38 +-36 +-34 +-32 +-30 +-28 +-26 +-25 +-24 +-23 +-21 +-20 +-19 +-19 +-18 +-17 +-16 +-6 +15 +29 +39 +46 +51 +54 +56 +57 +57 +54 +52 +50 +48 +46 +44 +35 +15 +0 +-12 +-21 +-27 +-32 +-35 +-36 +-36 +-36 +-36 +-35 +-34 +-32 +-30 +-18 +2 +16 +26 +34 +40 +43 +45 +47 +47 +46 +45 +44 +43 +42 +40 +31 +11 +-4 +-16 +-25 +-32 +-36 +-40 +-42 +-43 +-43 +-42 +-41 +-40 +-38 +-35 +-25 +-4 +11 +23 +30 +35 +39 +41 +42 +43 +42 +42 +41 +39 +37 +36 +28 +9 +-6 +-18 +-26 +-32 +-36 +-39 +-42 +-43 +-43 +-43 +-42 +-41 +-39 +-37 +-27 +-5 +11 +22 +30 +35 +39 +42 +43 +43 +42 +42 +40 +39 +37 +35 +27 +7 +-8 +-19 +-28 +-34 +-38 +-41 +-42 +-42 +-42 +-41 +-40 +-39 +-38 +-36 +-26 +-5 +9 +20 +28 +34 +37 +40 +41 +42 +42 +41 +41 +39 +38 +36 +29 +9 +-6 +-18 +-27 +-32 +-38 +-40 +-42 +-42 +-43 +-42 +-41 +-39 +-37 +-34 +-24 +-2 +13 +23 +30 +36 +39 +41 +43 +43 +42 +41 +40 +39 +38 +36 +28 +8 +-7 +-18 +-27 +-33 +-38 +-41 +-43 +-44 +-44 +-43 +-42 +-41 +-40 +-38 +-28 +-6 +10 +22 +30 +36 +39 +42 +43 +43 +43 +42 +40 +39 +37 +36 +28 +8 +-7 +-18 +-26 +-32 +-36 +-38 +-40 +-40 +-41 +-40 +-39 +-38 +-37 +-35 +-25 +-4 +11 +22 +31 +37 +40 +42 +43 +44 +43 +43 +42 +41 +39 +38 +30 +10 +-5 +-17 +-26 +-33 +-37 +-40 +-42 +-43 +-43 +-42 +-41 +-39 +-38 +-36 +-26 +-4 +11 +22 +30 +36 +39 +41 +42 +42 +41 +40 +39 +38 +37 +35 +35 +33 +31 +29 +29 +27 +25 +24 +22 +21 +19 +18 +17 +16 +15 +14 +6 +-12 +-25 +-36 +-44 +-49 +-52 +-54 +-55 +-55 +-54 +-53 +-52 +-50 +-48 +-46 +-35 +-12 +3 +15 +23 +29 +33 +36 +38 +39 +40 +40 +39 +38 +36 +35 +28 +8 +-8 +-19 +-28 +-34 +-39 +-42 +-44 +-44 +-44 +-43 +-42 +-40 +-38 +-36 +-26 +-4 +10 +21 +28 +34 +36 +39 +40 +41 +40 +40 +39 +38 +36 +34 +26 +7 +-9 +-20 +-28 +-35 +-39 +-42 +-44 +-45 +-45 +-44 +-43 +-42 +-40 +-39 +-28 +-6 +10 +21 +29 +35 +39 +41 +42 +43 +42 +41 +39 +38 +36 +35 +27 +7 +-8 +-19 +-27 +-33 +-37 +-40 +-42 +-43 +-43 +-42 +-41 +-40 +-38 +-37 +-25 +-4 +11 +22 +30 +35 +38 +40 +43 +43 +43 +43 +42 +41 +38 +36 +28 +8 +-7 +-19 +-27 +-34 +-38 +-41 +-42 +-43 +-42 +-42 +-41 +-39 +-38 +-36 +-25 +-3 +12 +24 +31 +35 +38 +41 +41 +42 +42 +41 +40 +39 +37 +36 +28 +9 +-6 +-17 +-26 +-32 +-37 +-40 +-41 +-43 +-43 +-42 +-41 +-39 +-38 +-36 +-26 +-4 +11 +22 +30 +36 +40 +42 +44 +45 +45 +43 +42 +41 +39 +37 +28 +8 +-7 +-18 +-27 +-33 +-37 +-40 +-42 +-42 +-42 +-41 +-40 +-38 +-36 +-34 +-24 +-2 +13 +24 +31 +36 +39 +42 +43 +43 +43 +43 +41 +40 +38 +37 +29 +9 +-6 +-17 +-26 +-33 +-37 +-40 +-42 +-43 +-43 +-42 +-41 +-40 +-38 +-37 +-26 +-4 +11 +22 +31 +37 +39 +41 +42 +42 +43 +42 +40 +38 +36 +35 +27 +7 +-8 +-19 +-27 +-34 +-38 +-42 +-43 +-43 +-43 +-42 +-41 +-40 +-38 +-37 +-27 +-5 +10 +21 +29 +35 +38 +41 +43 +43 +43 +42 +41 +40 +39 +38 +30 +10 +-6 +-18 +-27 +-32 +-37 +-40 +-41 +-42 +-41 +-41 +-39 +-38 +-36 +-35 +-24 +-2 +14 +25 +32 +38 +42 +43 +44 +44 +43 +42 +41 +41 +38 +37 +29 +9 +-6 +-17 +-26 +-32 +-35 +-38 +-40 +-41 +-42 +-42 +-41 +-39 +-38 +-36 +-35 +-33 +-32 +-30 +-28 +-27 +-25 +-23 +-22 +-20 +-18 +-17 +-16 +-16 +-15 +-15 +-5 +15 +29 +40 +47 +51 +54 +56 +56 +55 +54 +54 +52 +51 +49 +47 +37 +18 +1 +-11 +-20 +-27 +-32 +-34 +-36 +-37 +-38 +-37 +-36 +-35 +-34 +-32 +-22 +0 +15 +26 +33 +39 +42 +44 +45 +45 +44 +43 +42 +40 +39 +37 +35 +34 +33 +31 +29 +28 +25 +24 +22 +20 +19 +18 +16 +15 +14 +13 +5 +-14 +-28 +-39 +-46 +-51 +-55 +-56 +-57 +-55 +-54 +-53 +-52 +-51 +-48 +-47 +-36 +-14 +1 +13 +22 +28 +32 +35 +37 +38 +38 +38 +37 +37 +36 +35 +27 +8 +-9 +-20 +-28 +-34 +-38 +-41 +-43 +-43 +-43 +-42 +-41 +-40 +-38 +-36 +-25 +-3 +12 +24 +31 +36 +39 +42 +43 +43 +42 +42 +41 +40 +38 +37 +29 +9 +-6 +-18 +-27 +-33 +-37 +-39 +-41 +-42 +-42 +-42 +-41 +-40 +-39 +-37 +-35 +-34 +-32 +-30 +-28 +-27 +-25 +-23 +-22 +-20 +-18 +-16 +-16 +-15 +-15 +-14 +-4 +16 +30 +40 +47 +51 +54 +55 +55 +55 +54 +53 +51 +50 +48 +47 +44 +43 +40 +37 +34 +32 +30 +29 +26 +25 +23 +22 +20 +20 +18 +17 +10 +-9 +-24 +-34 +-41 +-48 +-51 +-54 +-55 +-54 +-54 +-53 +-51 +-49 +-47 +-45 +-33 +-11 +4 +17 +25 +32 +35 +37 +39 +39 +39 +38 +37 +36 +34 +33 +26 +6 +-10 +-21 +-30 +-36 +-40 +-43 +-44 +-44 +-44 +-43 +-43 +-42 +-41 +-39 +-37 +-35 +-34 +-32 +-30 +-27 +-26 +-23 +-22 +-21 +-19 +-18 +-17 +-15 +-14 +-13 +-4 +17 +30 +40 +47 +51 +53 +55 +56 +57 +55 +53 +51 +49 +47 +46 +44 +42 +39 +37 +35 +33 +31 +29 +27 +25 +23 +22 +21 +20 +19 +18 +10 +-9 +-24 +-34 +-42 +-47 +-50 +-52 +-53 +-54 +-53 +-53 +-51 +-49 +-47 +-45 +-33 +-12 +4 +16 +25 +31 +35 +37 +39 +40 +40 +40 +38 +37 +35 +34 +26 +7 +-9 +-20 +-28 +-34 +-39 +-41 +-42 +-42 +-42 +-41 +-41 +-39 +-38 +-36 +-27 +-5 +11 +21 +28 +34 +37 +40 +41 +42 +41 +40 +39 +39 +38 +36 +28 +9 +-6 +-18 +-27 +-33 +-38 +-40 +-42 +-42 +-42 +-41 +-40 +-39 +-37 +-35 +-25 +-3 +12 +25 +32 +38 +41 +43 +44 +43 +43 +42 +41 +39 +38 +36 +29 +9 +-6 +-18 +-26 +-32 +-36 +-38 +-41 +-41 +-42 +-42 +-41 +-40 +-39 +-37 +-36 +-34 +-32 +-29 +-28 +-26 +-25 +-23 +-22 +-20 +-19 +-18 +-17 +-17 +-15 +-15 +-5 +16 +30 +40 +47 +52 +54 +55 +56 +55 +55 +53 +52 +50 +48 +45 +37 +16 +1 +-11 +-20 +-28 +-32 +-35 +-37 +-38 +-38 +-37 +-37 +-35 +-34 +-33 +-22 +0 +14 +25 +32 +38 +40 +42 +43 +43 +42 +42 +41 +39 +38 +36 +28 +8 +-7 +-18 +-26 +-32 +-36 +-39 +-41 +-42 +-43 +-42 +-41 +-39 +-38 +-36 +-26 +-4 +11 +22 +30 +36 +39 +43 +44 +45 +44 +44 +43 +41 +39 +37 +35 +34 +32 +31 +29 +28 +26 +25 +23 +23 +21 +20 +20 +19 +17 +17 +8 +-11 +-26 +-36 +-44 +-49 +-51 +-53 +-55 +-54 +-54 +-52 +-50 +-48 +-46 +-44 +-33 +-11 +5 +17 +25 +30 +34 +37 +38 +38 +37 +38 +37 +36 +35 +34 +25 +6 +-9 +-20 +-28 +-34 +-38 +-42 +-44 +-44 +-44 +-44 +-43 +-42 +-40 +-39 +-37 +-35 +-33 +-30 +-28 +-27 +-25 +-23 +-21 +-20 +-18 +-17 +-16 +-15 +-14 +-14 +-4 +17 +31 +40 +47 +52 +55 +56 +56 +56 +55 +53 +51 +50 +47 +45 +43 +41 +38 +36 +34 +32 +30 +28 +27 +25 +23 +22 +21 +20 +19 +19 +11 +-8 +-23 +-34 +-42 +-47 +-51 +-53 +-54 +-54 +-53 +-52 +-50 +-48 +-46 +-43 +-32 +-10 +5 +17 +25 +31 +35 +37 +38 +39 +38 +38 +36 +36 +34 +33 +25 +6 +-9 +-20 +-29 +-35 +-39 +-42 +-45 +-45 +-46 +-45 +-45 +-43 +-41 +-38 +-28 +-6 +9 +20 +27 +34 +38 +41 +42 +42 +42 +42 +40 +39 +37 +36 +27 +8 +-7 +-19 +-27 +-33 +-38 +-40 +-41 +-41 +-41 +-40 +-39 +-38 +-36 +-35 +-25 +-3 +12 +23 +31 +37 +40 +43 +44 +45 +45 +44 +43 +42 +41 +39 +31 +11 +-5 +-17 +-26 +-32 +-36 +-40 +-41 +-42 +-42 +-41 +-40 +-39 +-37 +-35 +-24 +-3 +12 +23 +31 +36 +40 +42 +42 +42 +42 +40 +39 +38 +37 +34 +26 +7 +-9 +-20 +-28 +-34 +-38 +-41 +-42 +-43 +-43 +-43 +-43 +-41 +-40 +-39 +-28 +-6 +9 +20 +29 +34 +37 +40 +42 +42 +42 +41 +40 +39 +37 +37 +28 +7 +-9 +-20 +-29 +-35 +-39 +-42 +-44 +-44 +-43 +-42 +-41 +-39 +-37 +-36 +-25 +-3 +12 +22 +30 +35 +38 +41 +42 +42 +43 +42 +41 +40 +39 +38 +29 +10 +-5 +-17 +-25 +-31 +-36 +-39 +-41 +-42 +-42 +-42 +-41 +-40 +-38 +-36 +-26 +-3 +12 +23 +31 +37 +40 +43 +44 +44 +43 +44 +41 +40 +38 +36 +29 +9 +-7 +-19 +-27 +-34 +-37 +-40 +-41 +-42 +-42 +-42 +-41 +-40 +-38 +-37 +-35 +-34 +-31 +-30 +-27 +-26 +-25 +-24 +-21 +-20 +-19 +-18 +-16 +-15 +-14 +-13 +-3 +17 +32 +41 +48 +52 +54 +56 +56 +57 +55 +53 +52 +49 +47 +46 +37 +17 +2 +-10 +-19 +-26 +-31 +-35 +-37 +-38 +-38 +-38 +-37 +-36 +-35 +-34 +-23 +-2 +13 +24 +32 +38 +42 +43 +45 +45 +44 +43 +43 +41 +39 +37 +29 +9 +-6 +-17 +-26 +-32 +-36 +-39 +-40 +-40 +-39 +-39 +-38 +-37 +-36 +-34 +-23 +-3 +12 +23 +31 +36 +39 +42 +43 +43 +44 +43 +43 +41 +39 +37 +29 +9 +-6 +-18 +-27 +-34 +-38 +-41 +-42 +-42 +-42 +-42 +-41 +-39 +-37 +-36 +-25 +-4 +11 +23 +30 +35 +38 +42 +42 +42 +41 +41 +39 +38 +37 +35 +27 +8 +-8 +-19 +-27 +-33 +-37 +-40 +-42 +-43 +-42 +-42 +-41 +-41 +-39 +-37 +-26 +-4 +11 +22 +29 +35 +39 +42 +44 +44 +44 +44 +43 +41 +39 +37 +29 +9 +-7 +-18 +-26 +-32 +-37 +-39 +-41 +-41 +-41 +-40 +-40 +-38 +-37 +-36 +-26 +-5 +10 +21 +29 +35 +39 +41 +42 +43 +43 +42 +41 +40 +38 +36 +28 +8 +-7 +-19 +-28 +-34 +-38 +-42 +-43 +-44 +-44 +-43 +-42 +-41 +-39 +-37 +-26 +-4 +11 +22 +30 +36 +39 +41 +41 +42 +40 +40 +39 +38 +36 +35 +26 +8 +-7 +-18 +-27 +-33 +-37 +-40 +-41 +-42 +-41 +-41 +-40 +-39 +-38 +-36 +-25 +-3 +12 +23 +31 +37 +40 +43 +45 +45 +45 +44 +43 +42 +40 +38 +30 +10 +-5 +-16 +-25 +-31 +-36 +-38 +-40 +-40 +-41 +-40 +-39 +-38 +-36 +-35 +-25 +-3 +11 +22 +30 +35 +38 +40 +42 +42 +42 +41 +40 +38 +37 +35 +34 +33 +31 +30 +28 +25 +23 +22 +20 +19 +18 +17 +15 +14 +13 +12 +6 +-13 +-28 +-38 +-45 +-51 +-54 +-56 +-56 +-56 +-56 +-55 +-54 +-52 +-50 +-47 +-35 +-13 +2 +14 +22 +29 +33 +36 +38 +39 +39 +39 +37 +36 +35 +33 +25 +5 +-10 +-21 +-29 +-36 +-39 +-42 +-44 +-44 +-44 +-43 +-41 +-39 +-38 +-36 +-26 +-4 +10 +21 +29 +34 +38 +40 +42 +42 +42 +42 +41 +40 +39 +37 +29 +10 +-5 +-16 +-25 +-31 +-36 +-39 +-41 +-42 +-42 +-42 +-41 +-40 +-38 +-36 +-26 +-4 +11 +22 +30 +35 +38 +40 +41 +42 +42 +40 +38 +37 +36 +34 +26 +7 +-8 +-20 +-28 +-34 +-38 +-41 +-42 +-43 +-43 +-42 +-41 +-40 +-39 +-37 +-26 +-5 +10 +21 +28 +34 +38 +41 +42 +42 +42 +42 +42 +40 +38 +37 +28 +8 +-7 +-18 +-27 +-33 +-37 +-40 +-41 +-42 +-41 +-41 +-39 +-38 +-36 +-34 +-24 +-2 +13 +24 +32 +36 +40 +42 +43 +43 +43 +42 +42 +40 +39 +37 +28 +8 +-6 +-18 +-26 +-33 +-37 +-41 +-42 +-43 +-44 +-43 +-43 +-41 +-39 +-38 +-27 +-5 +10 +21 +30 +36 +39 +42 +43 +44 +44 +43 +41 +39 +38 +36 +28 +9 +-7 +-18 +-27 +-32 +-37 +-40 +-42 +-42 +-42 +-41 +-40 +-38 +-37 +-36 +-26 +-5 +10 +21 +29 +34 +37 +40 +41 +41 +41 +40 +39 +38 +36 +35 +27 +8 +-8 +-20 +-28 +-35 +-40 +-43 +-44 +-45 +-44 +-44 +-43 +-41 +-40 +-38 +-36 +-34 +-32 +-30 +-28 +-27 +-25 +-23 +-22 +-21 +-19 +-18 +-16 +-16 +-14 +-13 +-4 +17 +31 +42 +48 +53 +55 +58 +58 +58 +56 +55 +53 +51 +48 +45 +43 +41 +39 +37 +34 +32 +30 +28 +27 +26 +24 +24 +23 +22 +20 +19 +11 +-9 +-24 +-35 +-42 +-47 +-50 +-52 +-53 +-53 +-52 +-50 +-48 +-46 +-44 +-41 +-39 +-36 +-34 +-32 +-31 +-29 +-27 +-25 +-24 +-22 +-21 +-19 +-18 +-17 +-16 +-14 +-4 +17 +31 +42 +48 +53 +55 +57 +57 +56 +55 +53 +51 +49 +47 +45 +42 +40 +39 +37 +35 +33 +31 +29 +27 +25 +23 +21 +20 +18 +17 +17 +9 +-10 +-24 +-35 +-42 +-47 +-50 +-53 +-53 +-53 +-51 +-50 +-48 +-47 +-45 +-43 +-41 +-39 +-37 +-35 +-33 +-31 +-29 +-27 +-26 +-24 +-22 +-20 +-19 +-17 +-16 +-15 +-5 +15 +28 +39 +46 +50 +52 +54 +54 +53 +53 +52 +50 +49 +47 +44 +42 +39 +36 +34 +32 +31 +29 +27 +25 +22 +21 +20 +19 +18 +17 +15 +8 +-11 +-25 +-35 +-43 +-48 +-52 +-54 +-55 +-55 +-54 +-53 +-52 +-50 +-48 +-46 +-43 +-41 +-39 +-37 +-34 +-31 +-29 +-28 +-25 +-24 +-24 +-22 +-21 +-19 +-18 +-17 +-6 +15 +29 +39 +47 +52 +54 +56 +57 +57 +55 +55 +53 +50 +47 +45 +42 +40 +37 +36 +34 +32 +30 +28 +27 +26 +24 +23 +21 +20 +19 +18 +10 +-8 +-22 +-33 +-41 +-46 +-50 +-52 +-53 +-54 +-53 +-51 +-50 +-47 +-45 +-42 +-40 +-38 +-36 +-34 +-32 +-30 +-28 +-27 +-26 +-24 +-23 +-22 +-21 +-20 +-19 +-18 +-7 +13 +27 +38 +45 +50 +52 +54 +54 +54 +52 +51 +48 +46 +43 +42 +39 +37 +34 +33 +30 +29 +27 +26 +24 +23 +22 +21 +19 +19 +17 +16 +8 +-12 +-26 +-36 +-44 +-49 +-52 +-54 +-55 +-55 +-54 +-52 +-51 +-48 +-46 +-43 +-40 +-38 +-37 +-35 +-33 +-31 +-29 +-27 +-25 +-23 +-21 +-19 +-18 +-17 +-15 +-13 +-3 +18 +32 +43 +49 +54 +57 +59 +58 +58 +56 +55 +53 +51 +49 +47 +39 +19 +4 +-8 +-17 +-24 +-29 +-32 +-34 +-35 +-35 +-35 +-35 +-34 +-33 +-32 +-21 +0 +15 +25 +34 +39 +43 +45 +46 +46 +46 +47 +45 +43 +41 +39 +31 +10 +-6 +-17 +-26 +-32 +-37 +-40 +-41 +-42 +-42 +-41 +-40 +-38 +-37 +-35 +-24 +-3 +11 +22 +30 +35 +37 +40 +40 +41 +41 +41 +39 +38 +37 +35 +28 +9 +-7 +-18 +-27 +-33 +-37 +-40 +-42 +-42 +-42 +-41 +-40 +-39 +-37 +-36 +-25 +-3 +12 +23 +31 +37 +40 +43 +44 +44 +43 +42 +40 +39 +37 +36 +28 +8 +-7 +-18 +-27 +-33 +-38 +-40 +-42 +-42 +-42 +-41 +-41 +-40 +-39 +-38 +-28 +-7 +8 +21 +29 +35 +38 +41 +42 +43 +42 +43 +41 +40 +38 +37 +28 +8 +-7 +-18 +-27 +-33 +-37 +-39 +-40 +-41 +-41 +-40 +-39 +-38 +-37 +-35 +-25 +-3 +12 +22 +30 +35 +39 +41 +41 +42 +41 +41 +40 +39 +38 +36 +28 +9 +-6 +-18 +-27 +-33 +-38 +-41 +-42 +-44 +-43 +-43 +-42 +-41 +-39 +-38 +-27 +-5 +10 +22 +30 +35 +38 +41 +42 +42 +41 +41 +41 +40 +37 +35 +27 +8 +-7 +-18 +-27 +-33 +-38 +-40 +-42 +-42 +-43 +-42 +-41 +-40 +-38 +-36 +-27 +-5 +10 +22 +30 +36 +39 +42 +43 +43 +42 +41 +39 +38 +37 +35 +27 +7 +-9 +-20 +-28 +-34 +-38 +-40 +-42 +-42 +-42 +-42 +-41 +-40 +-38 +-38 +-27 +-6 +10 +20 +29 +35 +39 +41 +42 +42 +43 +42 +41 +40 +38 +36 +35 +33 +31 +30 +28 +27 +25 +24 +22 +21 +20 +19 +18 +18 +17 +16 +8 +-11 +-26 +-36 +-45 +-50 +-53 +-55 +-56 +-55 +-54 +-53 +-51 +-49 +-47 +-45 +-34 +-12 +4 +15 +23 +29 +32 +35 +36 +37 +37 +36 +36 +35 +33 +32 +25 +5 +-9 +-21 +-29 +-35 +-38 +-42 +-44 +-44 +-44 +-43 +-43 +-41 +-40 +-38 +-28 +-5 +10 +21 +29 +36 +39 +42 +43 +43 +43 +42 +39 +39 +37 +36 +28 +7 +-8 +-19 +-28 +-34 +-39 +-41 +-43 +-43 +-43 +-42 +-42 +-40 +-39 +-38 +-27 +-5 +10 +20 +28 +33 +38 +40 +42 +42 +42 +42 +42 +41 +40 +38 +30 +10 +-5 +-17 +-25 +-31 +-36 +-38 +-40 +-41 +-40 +-40 +-39 +-38 +-36 +-35 +-24 +-2 +14 +25 +32 +38 +41 +43 +44 +44 +43 +43 +41 +40 +38 +37 +28 +9 +-6 +-17 +-26 +-32 +-36 +-39 +-41 +-41 +-42 +-41 +-41 +-40 +-38 +-36 +-26 +-4 +11 +22 +30 +36 +39 +42 +44 +45 +45 +43 +43 +41 +40 +38 +30 +9 +-6 +-17 +-25 +-32 +-36 +-39 +-39 +-40 +-40 +-39 +-38 +-37 +-36 +-35 +-25 +-4 +11 +22 +29 +34 +38 +39 +41 +41 +41 +41 +40 +39 +37 +36 +28 +7 +-8 +-20 +-29 +-35 +-39 +-42 +-43 +-44 +-44 +-43 +-42 +-39 +-37 +-35 +-25 +-3 +11 +22 +29 +34 +39 +42 +42 +43 +42 +42 +41 +40 +39 +38 +29 +9 +-6 +-18 +-27 +-33 +-38 +-40 +-42 +-43 +-42 +-42 +-41 +-40 +-39 +-36 +-26 +-4 +10 +22 +29 +35 +38 +40 +40 +41 +40 +40 +39 +38 +36 +35 +26 +7 +-9 +-20 +-28 +-34 +-38 +-41 +-42 +-44 +-44 +-43 +-42 +-41 +-39 +-38 +-36 +-34 +-32 +-30 +-28 +-25 +-24 +-22 +-20 +-18 +-17 +-17 +-17 +-16 +-15 +-14 +-4 +17 +30 +41 +49 +53 +55 +57 +57 +57 +56 +55 +53 +51 +48 +46 +44 +42 +39 +37 +35 +33 +31 +30 +28 +26 +25 +23 +21 +20 +19 +18 +10 +-9 +-24 +-35 +-43 +-49 +-52 +-54 +-54 +-54 +-53 +-51 +-49 +-47 +-45 +-43 +-32 +-10 +5 +16 +24 +29 +33 +37 +39 +40 +40 +40 +39 +38 +37 +35 +27 +8 +-7 +-19 +-28 +-34 +-38 +-41 +-43 +-43 +-43 +-42 +-40 +-39 +-37 +-35 +-24 +-2 +13 +24 +32 +37 +40 +43 +44 +44 +43 +43 +42 +41 +39 +37 +29 +9 +-6 +-17 +-27 +-33 +-37 +-40 +-43 +-44 +-44 +-44 +-43 +-42 +-40 +-38 +-36 +-35 +-33 +-31 +-30 +-28 +-25 +-24 +-22 +-21 +-20 +-18 +-17 +-16 +-15 +-14 +-4 +17 +31 +41 +47 +52 +55 +57 +57 +57 +56 +55 +52 +50 +48 +46 +43 +40 +38 +36 +34 +32 +30 +28 +27 +25 +23 +21 +20 +19 +19 +18 +9 +-10 +-25 +-35 +-43 +-49 +-52 +-54 +-55 +-55 +-54 +-53 +-51 +-48 +-45 +-43 +-32 +-10 +5 +17 +25 +31 +34 +37 +37 +38 +38 +38 +37 +36 +34 +33 +25 +6 +-9 +-21 +-29 +-35 +-39 +-43 +-44 +-45 +-45 +-44 +-43 +-42 +-40 +-39 +-37 +-35 +-33 +-32 +-30 +-27 +-25 +-23 +-22 +-20 +-20 +-19 +-18 +-17 +-16 +-15 +-5 +15 +29 +39 +46 +51 +54 +56 +58 +57 +56 +55 +53 +51 +48 +46 +36 +16 +0 +-12 +-22 +-28 +-33 +-35 +-37 +-38 +-38 +-37 +-36 +-35 +-34 +-31 +-21 +0 +15 +25 +32 +37 +41 +43 +44 +44 +44 +43 +42 +41 +39 +38 +36 +35 +33 +32 +29 +29 +28 +25 +22 +21 +19 +18 +17 +16 +14 +14 +6 +-13 +-28 +-38 +-45 +-49 +-52 +-54 +-54 +-54 +-53 +-51 +-50 +-48 +-46 +-45 +-43 +-40 +-38 +-36 +-34 +-31 +-29 +-27 +-25 +-24 +-22 +-21 +-20 +-18 +-16 +-15 +-5 +16 +30 +39 +46 +51 +54 +55 +55 +55 +54 +53 +51 +50 +48 +46 +44 +42 +39 +38 +36 +34 +31 +30 +28 +25 +23 +22 +20 +19 +18 +17 +9 +-10 +-24 +-34 +-41 +-47 +-51 +-54 +-55 +-55 +-54 +-54 +-52 +-50 +-48 +-47 +-35 +-12 +3 +14 +23 +29 +33 +36 +38 +39 +39 +38 +38 +37 +35 +34 +25 +5 +-10 +-21 +-30 +-35 +-39 +-41 +-43 +-43 +-43 +-41 +-40 +-39 +-38 +-36 +-35 +-33 +-32 +-30 +-28 +-26 +-25 +-23 +-22 +-20 +-19 +-17 +-15 +-14 +-13 +-12 +-2 +18 +32 +41 +48 +52 +54 +56 +56 +55 +54 +53 +51 +48 +46 +44 +42 +41 +38 +36 +34 +32 +31 +29 +28 +26 +24 +23 +22 +21 +20 +19 +11 +-8 +-22 +-33 +-41 +-46 +-49 +-51 +-52 +-52 +-52 +-51 +-49 +-48 +-46 +-45 +-34 +-13 +3 +15 +23 +29 +33 +36 +37 +38 +38 +38 +37 +35 +34 +32 +24 +4 +-10 +-22 +-30 +-37 +-41 +-44 +-44 +-45 +-44 +-43 +-42 +-41 +-39 +-37 +-35 +-33 +-31 +-30 +-29 +-27 +-25 +-24 +-23 +-21 +-19 +-18 +-16 +-15 +-13 +-12 +-2 +19 +33 +44 +50 +54 +57 +58 +58 +57 +55 +54 +52 +50 +48 +46 +44 +42 +39 +38 +36 +34 +32 +30 +28 +26 +24 +23 +21 +20 +19 +17 +9 +-9 +-23 +-34 +-42 +-47 +-51 +-52 +-54 +-53 +-52 +-51 +-50 +-48 +-47 +-44 +-42 +-40 +-38 +-36 +-34 +-32 +-30 +-28 +-25 +-24 +-22 +-21 +-20 +-18 +-17 +-17 +-6 +13 +27 +37 +45 +50 +52 +54 +55 +54 +53 +52 +50 +48 +47 +44 +36 +15 +-1 +-13 +-22 +-28 +-33 +-36 +-38 +-39 +-39 +-38 +-38 +-36 +-35 +-33 +-23 +-2 +13 +24 +32 +37 +40 +41 +42 +43 +43 +42 +41 +40 +39 +37 +29 +9 +-6 +-17 +-25 +-32 +-37 +-40 +-42 +-43 +-43 +-42 +-41 +-39 +-38 +-36 +-26 +-4 +12 +23 +31 +37 +40 +43 +44 +44 +43 +43 +41 +40 +38 +37 +28 +9 +-6 +-17 +-27 +-33 +-37 +-39 +-40 +-41 +-40 +-39 +-39 +-38 +-36 +-35 +-25 +-3 +12 +23 +31 +37 +41 +43 +44 +45 +46 +45 +44 +42 +40 +38 +29 +10 +-5 +-17 +-25 +-32 +-36 +-39 +-41 +-41 +-41 +-41 +-39 +-38 +-37 +-35 +-25 +-4 +11 +22 +30 +35 +38 +41 +42 +43 +42 +41 +40 +39 +37 +36 +28 +8 +-7 +-19 +-27 +-34 +-38 +-42 +-44 +-45 +-44 +-43 +-43 +-41 +-40 +-38 +-28 +-6 +9 +21 +29 +34 +38 +40 +41 +41 +41 +40 +39 +38 +37 +35 +27 +8 +-7 +-18 +-27 +-33 +-37 +-39 +-41 +-42 +-42 +-42 +-41 +-40 +-39 +-37 +-27 +-5 +10 +21 +29 +35 +38 +41 +43 +44 +43 +43 +41 +40 +38 +37 +28 +8 +-7 +-19 +-27 +-32 +-37 +-39 +-40 +-41 +-41 +-39 +-38 +-37 +-35 +-33 +-23 +-2 +12 +22 +31 +36 +40 +42 +43 +43 +43 +42 +41 +40 +39 +38 +30 +10 +-5 +-17 +-26 +-32 +-37 +-40 +-42 +-43 +-43 +-42 +-41 +-39 +-38 +-36 +-26 +-4 +11 +22 +30 +35 +39 +41 +41 +42 +41 +41 +39 +38 +36 +35 +33 +32 +30 +28 +26 +25 +24 +22 +21 +20 +18 +17 +16 +15 +14 +13 +6 +-13 +-28 +-38 +-45 +-50 +-53 +-56 +-56 +-56 +-54 +-53 +-51 +-48 +-46 +-44 +-33 +-11 +4 +17 +25 +30 +34 +37 +38 +40 +40 +40 +39 +38 +37 +36 +28 +8 +-7 +-19 +-27 +-33 +-38 +-41 +-43 +-43 +-42 +-41 +-40 +-39 +-37 +-35 +-25 +-3 +11 +23 +31 +37 +40 +41 +41 +42 +41 +41 +39 +38 +36 +35 +27 +8 +-7 +-18 +-27 +-33 +-39 +-42 +-43 +-44 +-44 +-44 +-43 +-42 +-40 +-38 +-27 +-5 +10 +21 +29 +35 +37 +40 +41 +41 +41 +40 +39 +37 +36 +34 +26 +6 +-9 +-20 +-29 +-35 +-39 +-41 +-42 +-43 +-43 +-43 +-42 +-42 +-40 +-38 +-27 +-5 +9 +21 +29 +35 +38 +41 +42 +43 +43 +42 +41 +40 +39 +37 +28 +7 +-8 +-20 +-28 +-34 +-38 +-41 +-43 +-43 +-43 +-42 +-40 +-38 +-35 +-34 +-24 +-3 +12 +23 +30 +36 +39 +41 +43 +43 +43 +42 +42 +40 +39 +37 +29 +10 +-5 +-16 +-25 +-31 +-36 +-39 +-41 +-41 +-41 +-41 +-40 +-38 +-37 +-35 +-25 +-2 +13 +25 +32 +38 +42 +44 +45 +45 +45 +43 +42 +41 +39 +38 +29 +10 +-6 +-18 +-26 +-31 +-36 +-38 +-39 +-41 +-41 +-42 +-41 +-39 +-38 +-36 +-26 +-5 +10 +21 +29 +35 +39 +42 +43 +43 +43 +42 +41 +40 +38 +36 +28 +8 +-8 +-19 +-28 +-34 +-38 +-40 +-43 +-43 +-43 +-42 +-41 +-38 +-38 +-36 +-27 +-5 +10 +21 +29 +34 +38 +40 +41 +41 +42 +40 +39 +38 +37 +36 +28 +9 +-7 +-18 +-27 +-33 +-38 +-40 +-42 +-43 +-43 +-42 +-42 +-40 +-38 +-36 +-35 +-33 +-31 +-29 +-27 +-24 +-23 +-21 +-20 +-19 +-19 +-18 +-17 +-16 +-15 +-14 +-4 +16 +31 +40 +48 +52 +55 +56 +56 +56 +55 +54 +52 +49 +47 +45 +36 +16 +0 +-12 +-21 +-27 +-32 +-35 +-36 +-36 +-36 +-36 +-35 +-34 +-33 +-32 +-22 +-1 +14 +25 +32 +38 +41 +43 +45 +46 +45 +45 +44 +42 +41 +40 +31 +11 +-4 +-16 +-25 +-31 +-35 +-37 +-39 +-40 +-40 +-39 +-38 +-37 +-36 +-34 +-24 +-2 +12 +22 +30 +35 +38 +40 +41 +42 +42 +40 +38 +38 +36 +35 +26 +7 +-8 +-20 +-28 +-34 +-38 +-42 +-44 +-45 +-45 +-44 +-44 +-42 +-40 +-37 +-27 +-6 +9 +22 +29 +35 +39 +42 +42 +43 +43 +43 +42 +40 +39 +38 +30 +10 +-5 +-17 +-25 +-31 +-35 +-38 +-39 +-39 +-39 +-38 +-38 +-37 +-35 +-34 +-24 +-2 +13 +24 +32 +37 +41 +43 +44 +45 +45 +44 +42 +41 +39 +37 +29 +8 +-8 +-20 +-28 +-35 +-40 +-43 +-44 +-44 +-44 +-43 +-43 +-41 +-39 +-38 +-27 +-5 +10 +21 +28 +34 +37 +40 +41 +40 +40 +40 +38 +38 +36 +36 +28 +8 +-7 +-18 +-26 +-32 +-36 +-39 +-41 +-41 +-41 +-40 +-39 +-38 +-36 +-34 +-24 +-3 +14 +25 +32 +36 +40 +43 +44 +45 +45 +45 +43 +42 +40 +38 +29 +10 +-6 +-18 +-27 +-33 +-37 +-41 +-42 +-43 +-43 +-42 +-41 +-39 +-38 +-36 +-26 +-4 +10 +22 +29 +35 +38 +40 +41 +40 +40 +40 +39 +38 +37 +36 +27 +8 +-7 +-18 +-27 +-33 +-38 +-40 +-42 +-42 +-43 +-42 +-41 +-40 +-38 +-36 +-26 +-4 +11 +23 +30 +36 +39 +42 +43 +44 +43 +42 +41 +40 +38 +37 +35 +33 +31 +29 +27 +25 +23 +22 +20 +20 +19 +18 +17 +16 +14 +14 +6 +-13 +-28 +-38 +-46 +-52 +-55 +-57 +-58 +-58 +-56 +-55 +-53 +-51 +-49 +-46 +-34 +-12 +3 +14 +23 +29 +33 +35 +36 +37 +37 +37 +36 +35 +34 +33 +25 +5 +-10 +-21 +-29 +-35 +-39 +-42 +-43 +-44 +-44 +-43 +-42 +-40 +-39 +-37 +-26 +-5 +10 +21 +29 +36 +39 +42 +43 +44 +44 +43 +41 +39 +38 +36 +27 +7 +-8 +-19 +-28 +-34 +-38 +-41 +-43 +-43 +-43 +-42 +-42 +-40 +-39 +-37 +-26 +-4 +10 +22 +29 +35 +38 +41 +43 +44 +43 +42 +41 +40 +38 +37 +29 +10 +-5 +-16 +-25 +-31 +-36 +-38 +-40 +-41 +-41 +-41 +-39 +-39 +-37 +-35 +-24 +-3 +12 +23 +31 +37 +40 +43 +44 +44 +44 +43 +41 +40 +38 +36 +28 +8 +-7 +-19 +-28 +-33 +-36 +-39 +-40 +-41 +-41 +-41 +-40 +-39 +-38 +-36 +-25 +-4 +10 +21 +29 +35 +38 +41 +42 +43 +42 +42 +41 +41 +39 +38 +29 +8 +-7 +-19 +-28 +-34 +-39 +-41 +-43 +-44 +-44 +-43 +-42 +-40 +-38 +-37 +-26 +-5 +10 +20 +28 +33 +37 +39 +39 +40 +39 +39 +38 +37 +35 +34 +26 +7 +-8 +-19 +-28 +-33 +-37 +-41 +-43 +-43 +-43 +-43 +-42 +-40 +-39 +-37 +-26 +-4 +10 +22 +30 +36 +39 +42 +43 +44 +43 +42 +41 +40 +37 +36 +28 +9 +-7 +-18 +-27 +-33 +-38 +-40 +-41 +-41 +-41 +-40 +-40 +-39 +-38 +-37 +-26 +-4 +11 +22 +30 +35 +38 +41 +42 +42 +42 +42 +40 +39 +37 +36 +28 +9 +-7 +-19 +-27 +-33 +-38 +-39 +-42 +-42 +-42 +-41 +-40 +-38 +-36 +-34 +-24 +-3 +12 +22 +30 +35 +39 +41 +42 +42 +42 +42 +40 +40 +38 +36 +29 +9 +-5 +-17 +-26 +-33 +-37 +-40 +-42 +-43 +-43 +-43 +-42 +-41 +-39 +-37 +-27 +-5 +10 +22 +30 +36 +40 +43 +44 +45 +44 +43 +42 +41 +39 +39 +30 +10 +-6 +-17 +-25 +-31 +-36 +-39 +-40 +-40 +-40 +-39 +-38 +-37 +-36 +-35 +-33 +-32 +-31 +-29 +-28 +-26 +-25 +-24 +-22 +-21 +-19 +-18 +-17 +-16 +-14 +-13 +-3 +18 +32 +41 +48 +53 +54 +56 +56 +56 +54 +53 +51 +50 +48 +46 +37 +17 +1 +-11 +-20 +-26 +-32 +-35 +-38 +-39 +-39 +-39 +-38 +-37 +-35 +-34 +-23 +-2 +13 +24 +32 +37 +40 +43 +43 +44 +43 +43 +41 +40 +38 +37 +35 +34 +32 +31 +29 +27 +26 +24 +23 +23 +21 +20 +18 +17 +16 +15 +6 +-13 +-28 +-38 +-46 +-51 +-54 +-56 +-57 +-55 +-55 +-53 +-52 +-50 +-48 +-45 +-34 +-12 +3 +15 +23 +29 +33 +36 +38 +39 +39 +39 +38 +37 +37 +36 +28 +9 +-6 +-17 +-26 +-31 +-36 +-39 +-41 +-41 +-41 +-41 +-40 +-39 +-37 +-35 +-25 +-3 +12 +24 +32 +38 +40 +42 +43 +44 +43 +42 +41 +39 +38 +37 +28 +8 +-7 +-18 +-27 +-33 +-38 +-40 +-41 +-42 +-42 +-42 +-41 +-38 +-38 +-37 +-36 +-35 +-33 +-31 +-29 +-28 +-26 +-24 +-23 +-21 +-20 +-19 +-17 +-16 +-15 +-13 +-4 +17 +30 +40 +47 +51 +54 +56 +56 +56 +55 +54 +52 +50 +48 +46 +44 +42 +39 +38 +36 +34 +31 +30 +27 +26 +24 +23 +22 +21 +19 +18 +10 +-8 +-22 +-33 +-41 +-46 +-50 +-51 +-52 +-53 +-53 +-52 +-50 +-49 +-46 +-45 +-33 +-11 +4 +16 +25 +31 +35 +37 +38 +40 +39 +39 +37 +36 +35 +33 +25 +5 +-10 +-21 +-29 +-35 +-40 +-42 +-44 +-44 +-43 +-43 +-41 +-40 +-39 +-38 +-36 +-34 +-33 +-30 +-29 +-27 +-26 +-24 +-22 +-20 +-19 +-17 +-16 +-15 +-13 +-12 +-3 +18 +32 +42 +49 +52 +55 +56 +56 +56 +55 +53 +52 +50 +48 +46 +44 +42 +39 +37 +34 +33 +31 +29 +27 +25 +22 +21 +20 +18 +17 +16 +8 +-11 +-25 +-36 +-43 +-48 +-52 +-53 +-54 +-54 +-54 +-52 +-52 +-49 +-47 +-44 +-34 +-12 +4 +15 +23 +30 +33 +36 +37 +39 +39 +39 +38 +37 +36 +33 +25 +5 +-10 +-21 +-29 +-36 +-39 +-42 +-43 +-44 +-44 +-43 +-41 +-40 +-38 +-37 +-27 +-6 +9 +20 +27 +33 +36 +38 +39 +40 +40 +39 +39 +38 +37 +35 +28 +7 +-8 +-20 +-28 +-35 +-38 +-41 +-43 +-43 +-43 +-43 +-41 +-40 +-38 +-36 +-26 +-5 +10 +22 +30 +35 +38 +40 +42 +42 +41 +42 +40 +39 +37 +36 +28 +9 +-6 +-17 +-26 +-32 +-36 +-39 +-41 +-41 +-42 +-41 +-41 +-39 +-38 +-36 +-35 +-33 +-31 +-29 +-27 +-25 +-23 +-22 +-21 +-20 +-19 +-17 +-16 +-15 +-14 +-13 +-4 +17 +31 +42 +49 +54 +56 +58 +58 +59 +57 +56 +54 +51 +49 +46 +38 +17 +1 +-11 +-20 +-27 +-31 +-33 +-36 +-36 +-37 +-36 +-36 +-35 +-34 +-33 +-23 +-2 +13 +24 +31 +37 +39 +42 +43 +44 +44 +44 +42 +41 +39 +38 +29 +9 +-6 +-18 +-27 +-33 +-38 +-40 +-42 +-43 +-43 +-41 +-40 +-39 +-37 +-35 +-25 +-3 +13 +24 +31 +37 +39 +42 +42 +43 +42 +42 +41 +39 +38 +37 +34 +33 +31 +30 +29 +27 +25 +24 +23 +21 +20 +18 +18 +17 +15 +15 +7 +-11 +-25 +-35 +-43 +-48 +-50 +-53 +-54 +-53 +-53 +-52 +-50 +-49 +-47 +-45 +-34 +-12 +3 +15 +24 +30 +33 +36 +38 +39 +39 +38 +36 +35 +34 +32 +24 +4 +-11 +-22 +-30 +-36 +-40 +-43 +-44 +-44 +-43 +-42 +-41 +-41 +-39 +-37 +-35 +-34 +-32 +-31 +-29 +-27 +-26 +-24 +-22 +-20 +-18 +-16 +-15 +-15 +-14 +-13 +-3 +17 +30 +40 +48 +52 +54 +56 +56 +56 +54 +53 +51 +49 +47 +45 +42 +40 +38 +36 +33 +32 +30 +28 +26 +24 +23 +22 +21 +20 +19 +18 +11 +-8 +-22 +-33 +-41 +-47 +-51 +-54 +-54 +-55 +-54 +-53 +-51 +-48 +-46 +-43 +-32 +-10 +5 +18 +26 +32 +35 +38 +39 +40 +40 +39 +39 +38 +36 +36 +28 +7 +-7 +-19 +-27 +-33 +-37 +-40 +-42 +-42 +-42 +-43 +-42 +-41 +-39 +-37 +-26 +-4 +11 +22 +30 +35 +40 +42 +43 +44 +43 +43 +42 +40 +38 +36 +28 +9 +-7 +-18 +-26 +-32 +-36 +-39 +-41 +-41 +-41 +-40 +-39 +-38 +-36 +-35 +-25 +-4 +11 +22 +29 +34 +37 +40 +41 +42 +42 +42 +41 +40 +38 +36 +28 +8 +-7 +-18 +-28 +-35 +-39 +-42 +-43 +-44 +-44 +-43 +-42 +-40 +-38 +-36 +-25 +-4 +12 +23 +30 +35 +39 +41 +43 +43 +42 +42 +41 +40 +38 +36 +29 +8 +-6 +-18 +-26 +-32 +-37 +-40 +-42 +-43 +-44 +-44 +-43 +-41 +-39 +-38 +-28 +-6 +9 +21 +29 +35 +39 +41 +42 +43 +43 +42 +40 +39 +37 +36 +28 +9 +-7 +-19 +-27 +-33 +-37 +-39 +-40 +-41 +-41 +-41 +-39 +-39 +-38 +-36 +-26 +-5 +10 +21 +29 +35 +38 +41 +42 +43 +43 +43 +42 +40 +39 +38 +29 +9 +-6 +-18 +-27 +-33 +-38 +-40 +-41 +-42 +-43 +-42 +-41 +-39 +-38 +-36 +-26 +-4 +10 +22 +30 +35 +38 +40 +41 +42 +41 +41 +40 +39 +37 +36 +27 +8 +-7 +-19 +-27 +-33 +-38 +-42 +-44 +-44 +-44 +-43 +-42 +-40 +-39 +-37 +-35 +-33 +-31 +-29 +-27 +-26 +-24 +-23 +-23 +-22 +-21 +-20 +-18 +-17 +-16 +-15 +-5 +16 +31 +41 +48 +53 +55 +57 +57 +57 +57 +55 +52 +51 +48 +46 +37 +17 +1 +-11 +-20 +-26 +-31 +-34 +-35 +-37 +-37 +-37 +-36 +-36 +-34 +-33 +-23 +-2 +13 +25 +33 +37 +41 +44 +44 +44 +43 +43 +42 +40 +39 +38 +30 +9 +-7 +-18 +-27 +-33 +-37 +-40 +-42 +-42 +-42 +-42 +-41 +-39 +-37 +-35 +-25 +-3 +12 +23 +30 +35 +39 +41 +42 +43 +42 +42 +40 +40 +38 +37 +29 +10 +-6 +-17 +-26 +-32 +-37 +-40 +-41 +-43 +-42 +-42 +-41 +-40 +-38 +-36 +-25 +-3 +12 +24 +31 +36 +39 +42 +42 +42 +42 +41 +40 +39 +37 +36 +28 +8 +-7 +-18 +-26 +-33 +-37 +-40 +-42 +-43 +-43 +-42 +-40 +-39 +-38 +-37 +-26 +-4 +10 +22 +30 +35 +39 +42 +43 +43 +43 +42 +40 +39 +37 +36 +27 +8 +-8 +-19 +-28 +-34 +-39 +-41 +-42 +-43 +-43 +-43 +-42 +-41 +-39 +-38 +-28 +-7 +8 +20 +28 +34 +38 +40 +41 +41 +41 +42 +41 +39 +38 +36 +28 +8 +-7 +-18 +-26 +-32 +-37 +-40 +-41 +-41 +-40 +-40 +-39 +-38 +-36 +-35 +-24 +-3 +12 +23 +30 +35 +38 +40 +42 +42 +42 +41 +41 +40 +39 +37 +29 +10 +-6 +-17 +-26 +-32 +-36 +-39 +-40 +-41 +-42 +-42 +-41 +-39 +-37 +-35 +-25 +-3 +12 +23 +32 +38 +41 +43 +43 +44 +43 +43 +42 +41 +39 +38 +29 +10 +-5 +-16 +-25 +-31 +-35 +-38 +-39 +-40 +-41 +-40 +-39 +-38 +-36 +-35 +-24 +-3 +13 +24 +32 +37 +41 +44 +45 +46 +45 +44 +44 +43 +40 +38 +36 +34 +32 +31 +29 +28 +26 +25 +23 +22 +22 +21 +19 +18 +16 +15 +7 +-12 +-27 +-38 +-46 +-51 +-54 +-56 +-57 +-56 +-56 +-54 +-52 +-50 +-47 +-45 +-34 +-12 +3 +15 +23 +29 +33 +36 +37 +38 +39 +38 +37 +36 +36 +34 +27 +7 +-7 +-19 +-28 +-34 +-38 +-42 +-43 +-44 +-44 +-43 +-42 +-41 +-40 +-39 +-28 +-5 +10 +21 +29 +35 +38 +41 +41 +42 +41 +40 +38 +37 +35 +34 +26 +7 +-9 +-21 +-29 +-35 +-39 +-41 +-43 +-44 +-44 +-44 +-43 +-42 +-40 +-39 +-28 +-6 +8 +20 +28 +34 +37 +40 +41 +42 +41 +41 +40 +38 +36 +34 +26 +6 +-9 +-20 +-28 +-33 +-38 +-41 +-42 +-42 +-42 +-41 +-39 +-37 +-36 +-35 +-25 +-4 +11 +22 +30 +36 +39 +41 +43 +43 +43 +42 +42 +41 +39 +38 +30 +10 +-6 +-17 +-27 +-33 +-38 +-41 +-42 +-43 +-43 +-42 +-41 +-40 +-38 +-36 +-26 +-4 +12 +23 +32 +36 +40 +42 +43 +43 +43 +42 +41 +39 +38 +37 +29 +9 +-6 +-17 +-26 +-32 +-36 +-39 +-41 +-42 +-42 +-42 +-40 +-39 +-38 +-36 +-26 +-4 +12 +23 +31 +36 +41 +44 +44 +44 +44 +43 +41 +40 +38 +36 +28 +8 +-7 +-19 +-27 +-34 +-38 +-40 +-41 +-41 +-41 +-40 +-39 +-39 +-37 +-36 +-25 +-4 +12 +23 +31 +36 +39 +42 +43 +44 +44 +43 +41 +40 +38 +36 +28 +8 +-7 +-19 +-27 +-34 +-38 +-41 +-41 +-42 +-41 +-41 +-40 +-38 +-36 +-36 +-35 +-34 +-32 +-30 +-28 +-27 +-25 +-24 +-22 +-21 +-18 +-17 +-16 +-15 +-14 +-14 +-4 +16 +29 +40 +46 +51 +53 +54 +54 +55 +54 +53 +51 +49 +48 +46 +44 +42 +39 +37 +35 +33 +31 +29 +28 +26 +24 +22 +21 +21 +20 +19 +12 +-7 +-21 +-33 +-41 +-46 +-50 +-53 +-53 +-53 +-53 +-52 +-50 +-48 +-46 +-44 +-42 +-39 +-37 +-34 +-32 +-30 +-28 +-27 +-26 +-25 +-24 +-22 +-21 +-20 +-19 +-17 +-7 +14 +28 +38 +45 +50 +53 +55 +55 +54 +54 +52 +49 +47 +45 +43 +40 +38 +36 +34 +32 +30 +29 +27 +26 +25 +23 +21 +20 +19 +18 +18 +9 +-10 +-24 +-34 +-42 +-47 +-51 +-53 +-54 +-53 +-52 +-50 +-48 +-46 +-44 +-42 +-39 +-37 +-35 +-33 +-32 +-30 +-28 +-26 +-24 +-23 +-21 +-18 +-16 +-16 +-15 +-14 +-4 +17 +31 +42 +49 +54 +57 +57 +57 +57 +56 +54 +52 +50 +47 +45 +43 +41 +39 +37 +35 +33 +31 +29 +28 +26 +24 +22 +21 +19 +18 +17 +9 +-10 +-24 +-34 +-42 +-47 +-51 +-53 +-53 +-53 +-52 +-51 +-50 +-48 +-46 +-44 +-42 +-40 +-38 +-36 +-34 +-32 +-30 +-27 +-26 +-24 +-22 +-20 +-19 +-17 +-16 +-16 +-6 +14 +28 +37 +44 +49 +51 +53 +53 +53 +52 +51 +49 +47 +46 +43 +41 +38 +36 +34 +32 +30 +28 +27 +25 +23 +22 +21 +20 +18 +17 +16 +8 +-10 +-24 +-34 +-42 +-47 +-51 +-53 +-54 +-54 +-53 +-52 +-50 +-48 +-45 +-43 +-40 +-38 +-36 +-33 +-31 +-29 +-27 +-25 +-24 +-22 +-21 +-19 +-18 +-17 +-17 +-16 +-6 +16 +30 +40 +47 +52 +54 +56 +57 +57 +55 +53 +51 +49 +46 +44 +41 +39 +37 +35 +32 +32 +30 +28 +27 +25 +24 +23 +21 +20 +19 +18 +10 +-9 +-24 +-35 +-43 +-48 +-51 +-53 +-54 +-53 +-52 +-51 +-49 +-47 +-45 +-43 +-40 +-38 +-37 +-35 +-33 +-31 +-29 +-28 +-26 +-25 +-23 +-22 +-21 +-19 +-18 +-16 +-6 +15 +29 +39 +46 +50 +52 +53 +53 +53 +52 +50 +49 +47 +45 +43 +34 +14 +-2 +-14 +-22 +-29 +-33 +-36 +-39 +-40 +-40 +-40 +-39 +-37 +-37 +-35 +-24 +-2 +12 +23 +31 +37 +40 +43 +43 +44 +44 +43 +42 +40 +39 +37 +29 +9 +-6 +-17 +-26 +-32 +-36 +-38 +-39 +-40 +-40 +-39 +-38 +-37 +-36 +-35 +-25 +-3 +12 +23 +31 +36 +39 +42 +43 +43 +43 +42 +41 +40 +39 +37 +29 +9 +-6 +-18 +-28 +-34 +-38 +-41 +-43 +-43 +-42 +-41 +-41 +-40 +-38 +-36 +-25 +-4 +11 +22 +30 +35 +38 +39 +40 +41 +40 +40 +39 +38 +37 +35 +27 +8 +-7 +-19 +-27 +-33 +-37 +-40 +-42 +-42 +-42 +-41 +-41 +-40 +-38 +-37 +-26 +-4 +11 +22 +30 +36 +40 +42 +44 +45 +45 +44 +43 +42 +39 +37 +29 +9 +-6 +-18 +-27 +-34 +-38 +-40 +-41 +-42 +-42 +-41 +-40 +-39 +-37 +-35 +-25 +-4 +10 +21 +29 +34 +37 +39 +40 +41 +41 +41 +40 +39 +37 +36 +28 +9 +-7 +-18 +-27 +-34 +-38 +-41 +-43 +-43 +-43 +-43 +-42 +-39 +-38 +-36 +-25 +-3 +11 +23 +31 +36 +40 +42 +43 +44 +43 +42 +41 +39 +39 +37 +28 +8 +-7 +-18 +-26 +-32 +-36 +-39 +-41 +-42 +-42 +-41 +-41 +-40 +-39 +-38 +-27 +-6 +10 +21 +29 +35 +38 +41 +42 +43 +43 +42 +41 +40 +39 +37 +28 +8 +-6 +-18 +-26 +-33 +-37 +-40 +-42 +-42 +-42 +-41 +-40 +-38 +-37 +-35 +-25 +-3 +11 +22 +30 +36 +39 +42 +43 +44 +43 +43 +42 +41 +39 +38 +36 +34 +31 +29 +27 +26 +24 +21 +20 +18 +17 +16 +15 +14 +13 +13 +5 +-14 +-28 +-39 +-46 +-52 +-56 +-58 +-59 +-59 +-58 +-57 +-54 +-52 +-50 +-48 +-37 +-14 +2 +14 +22 +28 +32 +35 +36 +37 +37 +37 +36 +35 +34 +33 +25 +7 +-9 +-19 +-27 +-34 +-38 +-41 +-42 +-43 +-44 +-43 +-42 +-40 +-38 +-36 +-25 +-4 +12 +24 +31 +37 +40 +43 +44 +44 +43 +43 +42 +41 +39 +37 +29 +9 +-6 +-17 +-25 +-31 +-35 +-37 +-38 +-39 +-40 +-39 +-39 +-38 +-37 +-36 +-26 +-4 +10 +22 +30 +35 +39 +42 +43 +43 +43 +42 +41 +40 +38 +36 +28 +8 +-8 +-19 +-28 +-34 +-38 +-40 +-41 +-41 +-41 +-40 +-39 +-38 +-37 +-35 +-25 +-4 +11 +23 +30 +36 +39 +42 +43 +43 +43 +43 +42 +41 +40 +38 +30 +10 +-6 +-18 +-27 +-33 +-38 +-41 +-42 +-43 +-43 +-42 +-40 +-39 +-37 +-36 +-25 +-3 +11 +22 +30 +35 +39 +42 +43 +43 +42 +42 +41 +40 +39 +38 +30 +10 +-5 +-16 +-25 +-31 +-36 +-39 +-40 +-41 +-41 +-40 +-39 +-37 +-36 +-35 +-24 +-2 +13 +25 +32 +38 +42 +43 +44 +44 +43 +42 +40 +40 +39 +38 +29 +9 +-6 +-17 +-26 +-31 +-36 +-39 +-41 +-43 +-43 +-43 +-42 +-41 +-39 +-37 +-26 +-5 +10 +21 +29 +34 +38 +41 +42 +42 +42 +40 +39 +37 +36 +34 +25 +6 +-9 +-20 +-29 +-35 +-39 +-41 +-43 +-43 +-43 +-43 +-41 +-39 +-38 +-36 +-27 +-5 +9 +21 +28 +34 +38 +40 +41 +42 +42 +42 +42 +40 +38 +37 +29 +9 +-7 +-18 +-27 +-33 +-38 +-41 +-42 +-42 +-42 +-42 +-40 +-39 +-37 +-35 +-34 +-32 +-30 +-29 +-28 +-27 +-25 +-24 +-22 +-21 +-20 +-19 +-17 +-16 +-15 +-13 +-3 +17 +32 +42 +49 +53 +56 +57 +57 +57 +56 +54 +52 +50 +48 +46 +44 +42 +40 +38 +36 +34 +33 +31 +29 +28 +26 +24 +23 +21 +20 +19 +11 +-7 +-22 +-32 +-40 +-45 +-49 +-50 +-50 +-51 +-50 +-50 +-48 +-46 +-44 +-42 +-31 +-10 +5 +17 +26 +31 +35 +37 +39 +39 +39 +40 +38 +37 +36 +34 +25 +6 +-9 +-21 +-29 +-35 +-39 +-43 +-44 +-44 +-44 +-43 +-42 +-40 +-39 +-37 +-27 +-5 +10 +21 +29 +34 +37 +40 +41 +41 +41 +41 +39 +38 +37 +35 +27 +8 +-7 +-19 +-28 +-35 +-39 +-42 +-43 +-44 +-44 +-43 +-42 +-41 +-39 +-37 +-36 +-33 +-32 +-30 +-29 +-27 +-26 +-25 +-23 +-22 +-21 +-19 +-17 +-15 +-14 +-13 +-3 +18 +32 +42 +49 +54 +57 +59 +58 +57 +55 +53 +51 +49 +47 +45 +43 +41 +39 +37 +34 +33 +31 +29 +27 +26 +25 +24 +22 +21 +19 +17 +9 +-10 +-24 +-35 +-43 +-48 +-52 +-54 +-54 +-54 +-53 +-52 +-49 +-47 +-46 +-44 +-32 +-11 +4 +15 +23 +28 +32 +34 +35 +36 +36 +36 +37 +36 +34 +33 +25 +5 +-10 +-21 +-30 +-36 +-40 +-42 +-44 +-44 +-44 +-44 +-43 +-41 +-39 +-37 +-35 +-33 +-31 +-29 +-27 +-25 +-23 +-22 +-21 +-20 +-19 +-18 +-16 +-15 +-14 +-13 +-3 +17 +32 +42 +49 +54 +57 +58 +59 +58 +57 +56 +53 +51 +48 +46 +36 +17 +1 +-11 +-21 +-27 +-31 +-34 +-36 +-36 +-36 +-36 +-35 +-34 +-33 +-31 +-21 +0 +16 +26 +33 +38 +42 +43 +44 +45 +44 +44 +43 +42 +40 +38 +36 +34 +32 +30 +28 +26 +24 +22 +21 +20 +19 +18 +17 +15 +14 +13 +6 +-13 +-27 +-38 +-45 +-50 +-55 +-57 +-58 +-57 +-56 +-54 +-53 +-50 +-48 +-44 +-42 +-40 +-37 +-35 +-33 +-30 +-28 +-26 +-24 +-23 +-22 +-20 +-19 +-17 +-16 +-15 +-4 +16 +30 +41 +48 +52 +55 +57 +57 +56 +55 +54 +51 +49 +47 +45 +42 +40 +37 +36 +33 +32 +30 +29 +27 +25 +24 +23 +22 +21 +19 +18 +10 +-9 +-24 +-34 +-42 +-47 +-50 +-53 +-54 +-53 +-52 +-51 +-49 +-46 +-45 +-43 +-32 +-10 +5 +16 +24 +30 +33 +36 +38 +38 +38 +38 +37 +37 +35 +34 +26 +6 +-9 +-21 +-28 +-34 +-38 +-42 +-43 +-44 +-44 +-43 +-42 +-40 +-38 +-37 +-35 +-32 +-30 +-28 +-26 +-25 +-24 +-23 +-21 +-20 +-19 +-18 +-17 +-16 +-15 +-14 +-4 +16 +30 +41 +48 +52 +55 +57 +56 +56 +54 +54 +51 +49 +46 +44 +41 +40 +37 +35 +33 +31 +29 +28 +27 +25 +24 +23 +21 +19 +17 +16 +8 +-10 +-25 +-35 +-43 +-48 +-52 +-54 +-56 +-55 +-54 +-53 +-51 +-48 +-46 +-44 +-33 +-11 +4 +15 +23 +29 +34 +37 +38 +39 +39 +39 +38 +37 +36 +35 +27 +8 +-7 +-19 +-28 +-34 +-39 +-41 +-43 +-43 +-44 +-43 +-42 +-40 +-39 +-37 +-35 +-33 +-31 +-29 +-28 +-27 +-26 +-24 +-24 +-22 +-21 +-20 +-19 +-17 +-16 +-14 +-5 +16 +30 +41 +48 +53 +55 +57 +57 +56 +55 +54 +52 +49 +47 +45 +43 +42 +39 +37 +35 +33 +31 +30 +28 +26 +24 +22 +21 +19 +18 +17 +9 +-10 +-24 +-35 +-42 +-47 +-50 +-52 +-53 +-52 +-51 +-50 +-48 +-46 +-44 +-42 +-41 +-39 +-37 +-35 +-32 +-30 +-29 +-27 +-25 +-22 +-21 +-20 +-19 +-17 +-16 +-15 +-5 +16 +29 +39 +45 +50 +53 +54 +54 +54 +54 +52 +50 +49 +47 +44 +36 +16 +0 +-12 +-21 +-29 +-33 +-36 +-38 +-39 +-38 +-37 +-37 +-37 +-35 +-34 +-23 +-1 +14 +25 +32 +37 +40 +42 +43 +44 +43 +43 +42 +41 +39 +37 +29 +10 +-5 +-17 +-25 +-31 +-35 +-39 +-40 +-42 +-42 +-40 +-40 +-38 +-37 +-35 +-25 +-3 +12 +24 +31 +37 +41 +43 +44 +44 +43 +42 +41 +40 +39 +37 +29 +9 +-7 +-18 +-27 +-33 +-37 +-40 +-41 +-41 +-41 +-40 +-39 +-39 +-37 +-36 +-26 +-4 +10 +22 +30 +36 +40 +42 +44 +45 +44 +43 +42 +41 +39 +37 +29 +8 +-7 +-18 +-28 +-34 +-39 +-41 +-42 +-42 +-42 +-42 +-40 +-39 +-38 +-36 +-27 +-5 +9 +21 +29 +34 +38 +40 +42 +43 +43 +41 +40 +39 +38 +37 +28 +8 +-7 +-19 +-28 +-34 +-38 +-41 +-42 +-43 +-43 +-42 +-41 +-40 +-39 +-36 +-26 +-4 +11 +21 +29 +35 +38 +40 +41 +41 +40 +40 +39 +37 +36 +34 +27 +7 +-8 +-18 +-26 +-33 +-38 +-41 +-43 +-43 +-44 +-43 +-43 +-41 +-39 +-38 +-28 +-6 +9 +21 +29 +35 +39 +42 +43 +44 +43 +42 +40 +39 +37 +35 +27 +8 +-8 +-20 +-29 +-34 +-39 +-41 +-43 +-44 +-43 +-42 +-41 +-40 +-39 +-37 +-27 +-5 +10 +21 +28 +34 +37 +40 +41 +42 +43 +42 +41 +39 +38 +37 +29 +10 +-5 +-17 +-27 +-33 +-37 +-40 +-42 +-43 +-43 +-42 +-41 +-39 +-38 +-37 +-26 +-4 +11 +22 +31 +37 +41 +42 +43 +43 +42 +42 +41 +38 +36 +34 +33 +32 +30 +28 +26 +25 +23 +22 +21 +19 +19 +18 +16 +14 +13 +12 +4 +-14 +-28 +-38 +-46 +-51 +-54 +-56 +-56 +-55 +-53 +-52 +-50 +-49 +-47 +-45 +-34 +-12 +3 +15 +23 +30 +34 +38 +39 +40 +41 +41 +39 +39 +37 +36 +28 +8 +-7 +-19 +-27 +-33 +-37 +-40 +-42 +-43 +-43 +-43 +-41 +-40 +-38 +-36 +-26 +-4 +11 +21 +29 +34 +38 +41 +42 +43 +43 +42 +41 +40 +38 +38 +30 +11 +-5 +-16 +-25 +-32 +-36 +-39 +-41 +-42 +-43 +-42 +-41 +-39 +-38 +-36 +-25 +-3 +12 +24 +31 +37 +41 +43 +44 +44 +43 +43 +41 +40 +38 +37 +29 +9 +-7 +-19 +-27 +-33 +-37 +-40 +-41 +-41 +-40 +-40 +-39 +-39 +-38 +-36 +-25 +-4 +10 +21 +29 +35 +38 +41 +42 +42 +42 +42 +41 +40 +39 +37 +29 +9 +-6 +-18 +-27 +-32 +-36 +-39 +-41 +-42 +-42 +-41 +-41 +-39 +-37 +-34 +-24 +-2 +13 +24 +31 +36 +39 +42 +43 +43 +42 +42 +40 +39 +38 +37 +28 +9 +-6 +-18 +-27 +-33 +-37 +-39 +-40 +-41 +-42 +-41 +-41 +-40 +-38 +-37 +-26 +-4 +11 +22 +29 +35 +38 +40 +42 +43 +43 +42 +41 +40 +38 +37 +28 +8 +-7 +-19 +-28 +-34 +-38 +-41 +-42 +-43 +-42 +-42 +-41 +-40 +-38 +-36 +-25 +-4 +11 +22 +29 +35 +38 +40 +41 +42 +41 +41 +40 +40 +38 +36 +27 +8 +-7 +-18 +-27 +-33 +-37 +-40 +-42 +-43 +-44 +-43 +-41 +-39 +-39 +-37 +-26 +-4 +10 +21 +30 +37 +41 +43 +43 +44 +44 +43 +41 +40 +38 +37 +28 +9 +-6 +-18 +-27 +-32 +-37 +-40 +-42 +-42 +-42 +-41 +-40 +-38 +-37 +-36 +-35 +-33 +-32 +-30 +-28 +-26 +-25 +-23 +-21 +-20 +-19 +-17 +-16 +-14 +-14 +-14 +-4 +16 +30 +40 +46 +50 +53 +54 +55 +54 +53 +51 +50 +49 +47 +44 +36 +16 +0 +-13 +-22 +-29 +-34 +-38 +-40 +-41 +-41 +-40 +-39 +-38 +-36 +-35 +-24 +-3 +13 +24 +32 +37 +41 +43 +44 +44 +44 +43 +42 +41 +39 +37 +29 +9 +-6 +-17 +-26 +-31 +-36 +-39 +-40 +-41 +-41 +-41 +-41 +-39 +-38 +-36 +-26 +-4 +11 +22 +30 +36 +39 +42 +43 +44 +43 +43 +42 +40 +38 +36 +28 +8 +-7 +-19 +-27 +-33 +-37 +-40 +-42 +-43 +-42 +-41 +-40 +-38 +-37 +-35 +-24 +-2 +13 +24 +31 +36 +39 +42 +43 +44 +44 +43 +42 +40 +39 +37 +29 +10 +-5 +-17 +-26 +-32 +-37 +-40 +-42 +-43 +-42 +-42 +-41 +-40 +-38 +-36 +-25 +-4 +11 +22 +30 +36 +39 +42 +42 +43 +43 +44 +42 +40 +38 +36 +28 +8 +-7 +-19 +-27 +-33 +-38 +-41 +-42 +-42 +-42 +-41 +-40 +-39 +-37 +-36 +-26 +-4 +10 +22 +29 +35 +38 +42 +42 +43 +43 +42 +41 +40 +39 +38 +30 +10 +-6 +-18 +-26 +-33 +-37 +-40 +-42 +-42 +-42 +-41 +-40 +-39 +-37 +-35 +-24 +-3 +12 +24 +31 +36 +40 +42 +43 +43 +43 +42 +41 +39 +38 +36 +28 +8 +-7 +-18 +-27 +-33 +-37 +-40 +-41 +-42 +-42 +-41 +-41 +-40 +-39 +-37 +-27 +-6 +9 +20 +28 +33 +37 +39 +40 +42 +41 +41 +39 +38 +37 +36 +28 +8 +-7 +-19 +-28 +-35 +-38 +-41 +-42 +-43 +-42 +-41 +-40 +-38 +-36 +-35 +-24 +-2 +13 +24 +31 +37 +39 +42 +42 +43 +42 +42 +40 +39 +37 +36 +34 +32 +30 +30 +29 +27 +25 +24 +22 +21 +19 +18 +16 +15 +14 +13 +6 +-12 +-26 +-37 +-44 +-50 +-53 +-55 +-56 +-55 +-54 +-53 +-52 +-49 +-48 +-45 +-34 +-12 +3 +14 +23 +29 +33 +36 +37 +38 +39 +38 +38 +37 +36 +34 +26 +6 +-9 +-21 +-30 +-36 +-39 +-43 +-44 +-45 +-44 +-43 +-42 +-40 +-38 +-37 +-26 +-4 +11 +22 +30 +35 +39 +41 +42 +42 +42 +41 +40 +39 +36 +35 +27 +8 +-8 +-18 +-27 +-33 +-37 +-40 +-41 +-43 +-42 +-42 +-41 +-40 +-38 +-37 +-26 +-5 +10 +22 +31 +36 +39 +42 +44 +44 +44 +44 +43 +42 +40 +38 +30 +10 +-6 +-18 +-27 +-33 +-38 +-40 +-41 +-41 +-41 +-41 +-40 +-38 +-37 +-35 +-25 +-4 +11 +21 +29 +34 +38 +40 +41 +41 +42 +41 +40 +38 +37 +36 +28 +8 +-7 +-19 +-27 +-34 +-38 +-41 +-44 +-45 +-45 +-44 +-43 +-41 +-39 +-37 +-27 +-5 +10 +21 +29 +35 +38 +40 +41 +42 +42 +41 +39 +37 +36 +34 +26 +6 +-9 +-20 +-28 +-34 +-39 +-41 +-42 +-42 +-42 +-41 +-40 +-39 +-38 +-37 +-27 +-5 +9 +21 +28 +34 +38 +41 +42 +43 +43 +42 +41 +40 +38 +37 +28 +9 +-7 +-18 +-27 +-33 +-37 +-40 +-41 +-42 +-41 +-40 +-39 +-38 +-36 +-35 +-25 +-4 +10 +20 +28 +34 +38 +41 +41 +42 +42 +42 +40 +40 +38 +37 +29 +10 +-5 +-16 +-25 +-32 +-36 +-39 +-40 +-41 +-41 +-41 +-41 +-39 +-37 +-35 +-24 +-2 +12 +24 +32 +38 +41 +44 +45 +45 +44 +43 +42 +40 +38 +36 +29 +9 +-6 +-17 +-25 +-32 +-36 +-39 +-40 +-41 +-40 +-39 +-39 +-38 +-37 +-35 +-25 +-2 +12 +23 +31 +37 +40 +42 +44 +45 +44 +44 +43 +42 +40 +38 +29 +9 +-6 +-18 +-26 +-33 +-38 +-41 +-42 +-42 +-42 +-42 +-40 +-39 +-37 +-35 +-25 +-3 +11 +22 +30 +36 +39 +42 +43 +43 +43 +42 +40 +39 +38 +37 +28 +10 +-6 +-17 +-26 +-32 +-36 +-39 +-41 +-43 +-43 +-42 +-41 +-40 +-38 +-37 +-35 +-34 +-31 +-29 +-27 +-25 +-24 +-23 +-22 +-21 +-20 +-19 +-18 +-17 +-16 +-15 +-6 +16 +29 +40 +47 +52 +54 +56 +56 +56 +55 +54 +52 +49 +47 +45 +35 +15 +-1 +-13 +-22 +-27 +-32 +-35 +-37 +-38 +-38 +-37 +-36 +-35 +-34 +-32 +-22 +-1 +14 +25 +32 +37 +40 +42 +43 +44 +44 +43 +42 +41 +39 +38 +36 +34 +33 +31 +28 +27 +26 +23 +21 +20 +18 +17 +16 +15 +14 +13 +5 +-13 +-27 +-37 +-45 +-50 +-53 +-54 +-55 +-55 +-54 +-53 +-52 +-50 +-48 +-45 +-34 +-12 +4 +16 +24 +30 +34 +37 +38 +39 +39 +39 +38 +36 +35 +33 +25 +5 +-10 +-21 +-28 +-35 +-39 +-42 +-43 +-44 +-44 +-43 +-41 +-39 +-38 +-36 +-25 +-4 +10 +21 +29 +34 +38 +40 +42 +42 +42 +41 +41 +40 +38 +37 +29 +10 +-6 +-17 +-25 +-31 +-36 +-38 +-40 +-41 +-41 +-41 +-40 +-38 +-37 +-35 +-33 +-30 +-29 +-27 +-26 +-24 +-23 +-21 +-20 +-19 +-17 +-17 +-16 +-15 +-14 +-14 +-4 +16 +30 +40 +47 +52 +55 +57 +58 +57 +57 +56 +54 +52 +49 +46 +43 +41 +39 +36 +34 +32 +30 +28 +27 +25 +24 +23 +21 +20 +19 +18 +10 +-9 +-24 +-34 +-42 +-47 +-51 +-53 +-54 +-55 +-54 +-53 +-50 +-48 +-46 +-43 +-31 +-10 +6 +18 +26 +31 +35 +38 +38 +39 +39 +39 +37 +36 +35 +34 +25 +6 +-10 +-21 +-29 +-35 +-39 +-41 +-44 +-44 +-44 +-44 +-43 +-42 +-40 +-39 +-36 +-35 +-33 +-31 +-29 +-27 +-25 +-24 +-22 +-21 +-20 +-19 +-18 +-17 +-17 +-16 +-6 +15 +29 +39 +46 +50 +53 +55 +56 +56 +55 +53 +52 +50 +47 +44 +43 +40 +38 +36 +35 +33 +31 +29 +28 +27 +26 +25 +24 +23 +21 +20 +12 +-7 +-22 +-32 +-41 +-46 +-49 +-51 +-52 +-51 +-51 +-50 +-48 +-46 +-44 +-41 +-29 +-8 +7 +19 +27 +33 +36 +38 +39 +39 +39 +39 +37 +37 +35 +34 +25 +6 +-9 +-21 +-29 +-35 +-40 +-42 +-45 +-45 +-45 +-45 +-44 +-42 +-41 +-39 +-28 +-6 +9 +20 +28 +33 +37 +40 +41 +41 +41 +40 +38 +37 +36 +34 +26 +7 +-8 +-20 +-28 +-34 +-38 +-41 +-42 +-42 +-43 +-42 +-41 +-39 +-38 +-37 +-26 +-5 +10 +22 +31 +36 +39 +42 +43 +44 +43 +43 +42 +42 +40 +39 +30 +10 +-6 +-18 +-27 +-33 +-38 +-40 +-42 +-43 +-43 +-42 +-41 +-39 +-38 +-36 +-35 +-32 +-31 +-29 +-28 +-27 +-26 +-24 +-23 +-22 +-21 +-19 +-18 +-16 +-16 +-15 +-4 +17 +31 +41 +48 +53 +55 +57 +57 +57 +55 +54 +52 +49 +46 +44 +36 +16 +0 +-12 +-21 +-28 +-32 +-35 +-37 +-37 +-37 +-37 +-37 +-36 +-36 +-35 +-24 +-3 +12 +24 +32 +38 +41 +44 +45 +46 +46 +45 +43 +41 +39 +37 +29 +9 +-7 +-18 +-27 +-32 +-37 +-40 +-42 +-42 +-43 +-41 +-40 +-38 +-37 +-35 +-25 +-3 +11 +22 +31 +35 +38 +41 +42 +43 +42 +42 +40 +40 +38 +37 +34 +33 +32 +29 +27 +25 +23 +21 +20 +19 +19 +17 +17 +16 +15 +14 +6 +-12 +-26 +-36 +-44 +-49 +-52 +-54 +-56 +-56 +-55 +-54 +-52 +-50 +-48 +-45 +-34 +-11 +5 +17 +26 +33 +37 +39 +39 +40 +39 +39 +38 +38 +36 +34 +26 +6 +-9 +-20 +-28 +-34 +-38 +-41 +-42 +-42 +-42 +-42 +-40 +-39 +-38 +-37 +-36 +-34 +-33 +-31 +-30 +-28 +-27 +-25 +-23 +-21 +-19 +-17 +-16 +-15 +-14 +-13 +-4 +16 +30 +39 +46 +51 +54 +56 +56 +56 +55 +53 +52 +50 +48 +47 +45 +43 +40 +38 +35 +33 +31 +29 +27 +25 +24 +22 +21 +20 +19 +18 +10 +-9 +-23 +-34 +-41 +-46 +-50 +-52 +-53 +-53 +-52 +-51 +-49 +-47 +-46 +-43 +-32 +-10 +5 +17 +26 +31 +36 +38 +40 +40 +41 +39 +38 +37 +36 +34 +26 +6 +-9 +-19 +-28 +-35 +-39 +-42 +-44 +-44 +-43 +-43 +-41 +-40 +-38 +-36 +-26 +-5 +9 +21 +29 +34 +38 +40 +41 +42 +42 +42 +40 +39 +38 +37 +28 +9 +-6 +-18 +-27 +-34 +-38 +-41 +-43 +-43 +-43 +-43 +-42 +-41 +-39 +-37 +-27 +-5 +10 +21 +29 +34 +37 +39 +40 +41 +41 +41 +39 +38 +37 +36 +27 +8 +-7 +-18 +-26 +-32 +-37 +-40 +-41 +-42 +-42 +-42 +-40 +-39 +-37 +-36 +-25 +-3 +12 +23 +32 +38 +41 +43 +44 +45 +44 +43 +42 +40 +39 +37 +29 +9 +-6 +-17 +-27 +-33 +-37 +-39 +-40 +-41 +-42 +-41 +-40 +-39 +-38 +-37 +-27 +-5 +10 +21 +29 +35 +39 +41 +43 +43 +43 +42 +41 +40 +39 +36 +28 +7 +-8 +-19 +-28 +-34 +-38 +-40 +-42 +-43 +-43 +-43 +-41 +-40 +-39 +-37 +-27 +-6 +9 +20 +27 +33 +37 +40 +41 +42 +41 +40 +40 +39 +37 +37 +28 +8 +-7 +-18 +-27 +-34 +-38 +-40 +-42 +-42 +-42 +-41 +-40 +-38 +-37 +-35 +-24 +-3 +12 +23 +31 +36 +40 +42 +43 +43 +43 +42 +41 +40 +38 +37 +29 +9 +-6 +-18 +-27 +-34 +-38 +-41 +-43 +-43 +-43 +-43 +-41 +-41 +-39 +-38 +-35 +-34 +-32 +-30 +-28 +-26 +-25 +-23 +-21 +-20 +-19 +-18 +-16 +-15 +-14 +-13 +-3 +17 +31 +41 +48 +53 +56 +57 +57 +56 +54 +53 +50 +49 +47 +45 +36 +16 +0 +-12 +-20 +-27 +-32 +-34 +-36 +-37 +-38 +-37 +-38 +-36 +-36 +-34 +-24 +-2 +13 +24 +32 +38 +41 +43 +45 +46 +46 +45 +44 +42 +40 +38 +29 +10 +-6 +-17 +-27 +-32 +-37 +-40 +-41 +-42 +-42 +-41 +-40 +-38 +-37 +-35 +-24 +-3 +12 +23 +30 +36 +39 +42 +43 +44 +43 +43 +41 +40 +39 +38 +29 +9 +-6 +-18 +-27 +-32 +-37 +-40 +-42 +-43 +-43 +-42 +-41 +-39 +-37 +-35 +-25 +-3 +11 +22 +29 +35 +38 +41 +42 +43 +43 +43 +41 +40 +38 +36 +29 +9 +-6 +-18 +-27 +-32 +-37 +-40 +-42 +-43 +-44 +-43 +-42 +-41 +-38 +-37 +-27 +-5 +10 +21 +30 +35 +39 +41 +42 +43 +42 +42 +40 +39 +37 +35 +27 +8 +-7 +-18 +-27 +-33 +-36 +-40 +-41 +-42 +-41 +-41 +-39 +-38 +-37 +-35 +-25 +-4 +11 +21 +29 +35 +38 +41 +42 +42 +42 +42 +41 +40 +38 +36 +28 +8 +-7 +-18 +-28 +-34 +-38 +-41 +-43 +-43 +-43 +-42 +-41 +-40 +-38 +-36 +-25 +-3 +12 +23 +31 +36 +40 +42 +44 +44 +43 +43 +42 +41 +40 +39 +30 +11 +-4 +-16 +-25 +-31 +-34 +-37 +-39 +-40 +-39 +-38 +-38 +-38 +-37 +-35 +-25 +-3 +11 +23 +31 +36 +39 +42 +44 +44 +43 +43 +42 +40 +37 +36 +28 +7 +-9 +-20 +-28 +-34 +-39 +-41 +-43 +-43 +-43 +-42 +-40 +-38 +-37 +-35 +-25 +-3 +11 +22 +30 +35 +38 +40 +42 +42 +42 +41 +40 +39 +37 +36 +34 +33 +32 +30 +29 +27 +25 +23 +21 +20 +19 +17 +16 +15 +15 +14 +7 +-13 +-26 +-37 +-44 +-49 +-53 +-55 +-57 +-56 +-55 +-55 +-53 +-51 +-49 +-46 +-35 +-13 +3 +15 +23 +29 +34 +37 +38 +39 +38 +37 +36 +36 +34 +33 +26 +6 +-9 +-20 +-28 +-34 +-38 +-40 +-42 +-42 +-42 +-42 +-41 +-40 +-39 +-38 +-27 +-5 +10 +22 +31 +36 +39 +41 +43 +43 +43 +42 +41 +40 +38 +36 +28 +7 +-8 +-20 +-28 +-34 +-38 +-41 +-42 +-43 +-43 +-42 +-41 +-39 +-38 +-36 +-26 +-4 +10 +21 +28 +33 +36 +39 +40 +40 +40 +39 +38 +38 +36 +35 +28 +9 +-7 +-18 +-27 +-33 +-38 +-40 +-42 +-42 +-42 +-41 +-40 +-39 +-37 +-35 +-25 +-4 +12 +23 +30 +35 +38 +40 +41 +42 +42 +40 +39 +38 +36 +35 +28 +8 +-7 +-18 +-27 +-33 +-38 +-41 +-42 +-43 +-43 +-43 +-42 +-40 +-39 +-37 +-26 +-5 +11 +22 +30 +36 +39 +42 +43 +43 +42 +41 +40 +38 +36 +35 +27 +8 +-8 +-18 +-27 +-33 +-38 +-40 +-42 +-42 +-43 +-42 +-41 +-41 +-39 +-38 +-28 +-6 +9 +20 +28 +34 +37 +40 +42 +43 +42 +42 +40 +40 +38 +36 +27 +8 +-8 +-19 +-28 +-34 +-38 +-40 +-43 +-43 +-44 +-42 +-41 +-39 +-38 +-35 +-25 +-4 +11 +22 +30 +35 +38 +41 +43 +43 +43 +42 +42 +41 +40 +38 +30 +11 +-4 +-16 +-24 +-30 +-34 +-37 +-39 +-41 +-41 +-40 +-39 +-38 +-36 +-34 +-32 +-31 +-29 +-27 +-25 +-24 +-22 +-21 +-20 +-19 +-18 +-18 +-17 +-16 +-15 +-14 +-4 +16 +30 +40 +48 +52 +56 +57 +57 +57 +56 +53 +51 +50 +47 +45 +42 +40 +38 +35 +33 +31 +30 +28 +27 +25 +24 +23 +21 +20 +18 +17 +9 +-10 +-25 +-36 +-44 +-49 +-53 +-55 +-55 +-55 +-54 +-51 +-49 +-47 +-46 +-43 +-41 +-38 +-36 +-34 +-32 +-30 +-29 +-27 +-25 +-24 +-22 +-21 +-19 +-18 +-17 +-16 +-6 +16 +31 +41 +48 +53 +55 +57 +57 +56 +55 +54 +52 +49 +46 +44 +42 +40 +37 +36 +33 +32 +30 +29 +27 +26 +24 +23 +21 +21 +19 +19 +11 +-8 +-23 +-34 +-43 +-48 +-50 +-53 +-54 +-54 +-53 +-51 +-50 +-47 +-45 +-43 +-40 +-37 +-35 +-33 +-31 +-29 +-28 +-27 +-25 +-24 +-23 +-21 +-19 +-17 +-17 +-15 +-6 +15 +29 +40 +47 +51 +54 +55 +55 +55 +53 +51 +49 +48 +45 +44 +42 +40 +38 +35 +33 +31 +30 +29 +28 +26 +25 +23 +21 +19 +18 +17 +9 +-10 +-25 +-35 +-43 +-48 +-51 +-53 +-54 +-54 +-53 +-52 +-50 +-48 +-46 +-44 +-42 +-40 +-38 +-36 +-34 +-32 +-30 +-28 +-25 +-24 +-22 +-21 +-19 +-18 +-16 +-15 +-5 +16 +30 +41 +48 +53 +55 +57 +56 +56 +55 +54 +52 +50 +48 +46 +44 +42 +40 +38 +36 +34 +32 +30 +28 +26 +24 +22 +20 +18 +17 +16 +8 +-11 +-25 +-35 +-43 +-48 +-52 +-53 +-54 +-54 +-53 +-51 +-50 +-48 +-46 +-44 +-42 +-40 +-38 +-36 +-33 +-32 +-30 +-29 +-27 +-25 +-23 +-22 +-20 +-17 +-16 +-15 +-6 +16 +30 +39 +46 +51 +53 +55 +55 +54 +53 +52 +50 +48 +46 +44 +42 +40 +37 +36 +33 +31 +29 +27 +25 +24 +22 +21 +19 +18 +17 +16 +8 +-11 +-24 +-35 +-43 +-48 +-51 +-53 +-54 +-54 +-53 +-52 +-50 +-48 +-46 +-44 +-42 +-39 +-37 +-34 +-33 +-30 +-28 +-27 +-25 +-23 +-21 +-19 +-18 +-16 +-15 +-14 +-5 +16 +29 +40 +46 +51 +54 +55 +55 +56 +55 +53 +51 +50 +48 +46 +37 +18 +1 +-11 +-21 +-28 +-33 +-36 +-38 +-38 +-38 +-38 +-38 +-36 +-35 +-33 +-22 +-1 +14 +25 +33 +38 +41 +43 +44 +45 +45 +43 +41 +41 +39 +37 +29 +9 +-6 +-17 +-26 +-32 +-37 +-40 +-42 +-43 +-42 +-43 +-42 +-41 +-39 +-37 +-26 +-5 +10 +21 +29 +35 +39 +42 +43 +43 +43 +43 +42 +40 +38 +36 +28 +9 +-6 +-18 +-26 +-32 +-37 +-40 +-41 +-42 +-41 +-40 +-38 +-37 +-36 +-35 +-24 +-3 +12 +23 +31 +36 +39 +42 +43 +43 +43 +43 +42 +41 +39 +38 +29 +10 +-5 +-17 +-26 +-32 +-37 +-40 +-42 +-42 +-42 +-42 +-42 +-40 +-39 +-37 +-27 +-5 +10 +22 +30 +35 +39 +41 +42 +42 +42 +41 +39 +38 +37 +35 +26 +7 +-7 +-20 +-28 +-35 +-38 +-40 +-41 +-41 +-41 +-41 +-40 +-39 +-37 +-36 +-26 +-5 +10 +21 +29 +35 +38 +40 +41 +42 +42 +41 +40 +39 +38 +36 +28 +8 +-7 +-20 +-28 +-34 +-38 +-42 +-44 +-45 +-44 +-43 +-42 +-41 +-39 +-37 +-26 +-4 +11 +22 +31 +36 +40 +42 +43 +44 +43 +42 +40 +39 +37 +36 +28 +8 +-7 +-19 +-28 +-33 +-38 +-40 +-41 +-41 +-42 +-41 +-41 +-39 +-38 +-37 +-27 +-6 +8 +20 +27 +33 +36 +39 +40 +41 +40 +40 +39 +38 +37 +36 +28 +9 +-8 +-20 +-29 +-35 +-38 +-41 +-43 +-44 +-44 +-43 +-41 +-39 +-37 +-36 +-25 +-3 +12 +23 +31 +36 +39 +41 +42 +42 +42 +41 +40 +38 +37 +36 +35 +33 +32 +30 +28 +27 +25 +24 +22 +21 +20 +18 +17 +15 +14 +13 +6 +-13 +-26 +-37 +-45 +-50 +-54 +-55 +-56 +-55 +-55 +-53 +-51 +-49 +-47 +-45 +-34 +-12 +4 +14 +23 +30 +33 +35 +37 +39 +38 +37 +37 +36 +35 +33 +25 +6 +-9 +-20 +-28 +-34 +-38 +-40 +-43 +-44 +-44 +-43 +-42 +-40 +-38 +-37 +-26 +-4 +11 +22 +31 +36 +40 +42 +44 +44 +43 +42 +40 +39 +37 +36 +28 +8 +-7 +-19 +-28 +-33 +-38 +-40 +-42 +-42 +-42 +-41 +-40 +-39 +-38 +-36 +-26 +-4 +11 +22 +29 +35 +38 +41 +43 +44 +44 +43 +42 +41 +39 +38 +30 +10 +-6 +-17 +-25 +-32 +-36 +-39 +-40 +-41 +-41 +-41 +-39 +-37 +-36 +-34 +-23 +-2 +13 +24 +31 +36 +39 +42 +42 +43 +43 +42 +40 +39 +38 +37 +28 +8 +-7 +-18 +-27 +-33 +-37 +-40 +-42 +-42 +-41 +-42 +-40 +-39 +-38 +-36 +-25 +-4 +11 +22 +30 +36 +39 +42 +43 +44 +43 +42 +40 +39 +37 +35 +26 +7 +-8 +-20 +-28 +-34 +-38 +-41 +-42 +-43 +-43 +-42 +-40 +-39 +-37 +-36 +-26 +-5 +10 +20 +28 +33 +37 +40 +41 +41 +41 +40 +40 +38 +37 +36 +28 +9 +-6 +-18 +-27 +-33 +-38 +-42 +-43 +-43 +-44 +-43 +-42 +-40 +-38 +-36 +-26 +-4 +11 +22 +30 +36 +40 +43 +43 +43 +42 +42 +39 +38 +36 +34 +26 +7 +-8 +-20 +-28 +-34 +-38 +-41 +-42 +-42 +-42 +-41 +-39 +-38 +-37 +-35 +-25 +-4 +11 +23 +32 +37 +40 +42 +44 +44 +44 +44 +44 +43 +41 +40 +31 +11 +-4 +-16 +-25 +-31 +-36 +-39 +-40 +-41 +-41 +-40 +-39 +-38 +-37 +-35 +-33 +-31 +-29 +-27 +-25 +-24 +-23 +-21 +-20 +-19 +-18 +-18 +-17 +-16 +-15 +-14 +-4 +17 +31 +41 +47 +52 +55 +57 +57 +57 +55 +54 +52 +51 +48 +46 +43 +40 +37 +36 +33 +32 +29 +28 +26 +25 +24 +23 +22 +21 +19 +18 +11 +-9 +-24 +-35 +-43 +-47 +-50 +-53 +-54 +-54 +-53 +-52 +-50 +-48 +-46 +-43 +-32 +-9 +6 +17 +25 +30 +34 +36 +37 +37 +37 +37 +36 +35 +33 +32 +23 +3 +-11 +-22 +-30 +-36 +-40 +-43 +-44 +-44 +-44 +-44 +-44 +-42 +-41 +-39 +-28 +-6 +9 +21 +29 +34 +38 +41 +42 +43 +43 +43 +42 +40 +39 +37 +28 +8 +-9 +-20 +-28 +-34 +-38 +-41 +-43 +-44 +-43 +-43 +-42 +-41 +-38 +-36 +-34 +-32 +-31 +-29 +-28 +-27 +-25 +-23 +-22 +-20 +-20 +-18 +-17 +-16 +-15 +-13 +-3 +17 +31 +42 +48 +53 +55 +55 +55 +55 +55 +54 +51 +49 +47 +45 +43 +41 +39 +37 +35 +33 +31 +30 +28 +28 +26 +24 +23 +21 +20 +18 +10 +-9 +-22 +-34 +-42 +-47 +-50 +-52 +-52 +-52 +-52 +-50 +-49 +-47 +-46 +-44 +-33 +-11 +4 +16 +24 +30 +34 +37 +38 +39 +39 +39 +38 +37 +36 +35 +26 +7 +-8 +-20 +-29 +-35 +-39 +-42 +-43 +-43 +-42 +-41 +-41 +-39 +-38 +-36 +-33 +-31 +-30 +-28 +-27 +-26 +-25 +-24 +-22 +-21 +-19 +-18 +-17 +-16 +-15 +-14 +-3 +18 +32 +42 +49 +54 +57 +57 +57 +57 +55 +53 +51 +49 +47 +44 +35 +15 +-1 +-12 +-22 +-28 +-33 +-36 +-38 +-39 +-39 +-39 +-39 +-37 +-36 +-35 +-25 +-3 +12 +22 +30 +36 +40 +42 +43 +44 +44 +43 +42 +41 +39 +38 +36 +34 +32 +31 +29 +28 +26 +26 +25 +23 +22 +21 +20 +19 +18 +17 +10 +-9 +-23 +-34 +-41 +-47 +-51 +-53 +-54 +-54 +-52 +-51 +-49 +-47 +-45 +-43 +-41 +-37 +-35 +-33 +-31 +-29 +-28 +-26 +-25 +-23 +-22 +-20 +-19 +-17 +-16 +-14 +-5 +16 +30 +41 +48 +52 +54 +56 +56 +56 +54 +52 +50 +48 +46 +44 +41 +39 +36 +34 +32 +30 +29 +27 +26 +24 +23 +21 +19 +17 +16 +15 +7 +-12 +-27 +-38 +-45 +-51 +-54 +-56 +-57 +-56 +-56 +-54 +-51 +-49 +-47 +-46 +-34 +-12 +4 +15 +24 +30 +33 +36 +37 +37 +37 +36 +36 +35 +35 +33 +25 +5 +-9 +-20 +-28 +-34 +-39 +-42 +-44 +-46 +-45 +-44 +-43 +-42 +-40 +-39 +-36 +-35 +-33 +-31 +-29 +-27 +-25 +-23 +-22 +-21 +-19 +-18 +-18 +-17 +-16 +-15 +-5 +15 +29 +39 +47 +51 +54 +56 +56 +55 +55 +53 +51 +50 +47 +44 +42 +40 +38 +36 +35 +33 +31 +29 +28 +26 +25 +23 +22 +21 +20 +19 +11 +-8 +-23 +-34 +-42 +-47 +-51 +-52 +-53 +-53 +-53 +-51 +-49 +-47 +-44 +-42 +-30 +-8 +7 +19 +27 +33 +36 +39 +40 +41 +41 +40 +39 +38 +37 +36 +28 +8 +-6 +-18 +-27 +-33 +-37 +-40 +-42 +-43 +-43 +-43 +-42 +-41 +-39 +-38 +-36 +-34 +-32 +-30 +-28 +-26 +-24 +-23 +-22 +-21 +-19 +-19 +-18 +-17 +-16 +-16 +-6 +15 +29 +40 +47 +52 +55 +57 +57 +57 +56 +54 +52 +51 +49 +47 +44 +42 +39 +38 +35 +33 +31 +29 +28 +26 +24 +22 +21 +20 +19 +18 +11 +-8 +-23 +-34 +-41 +-47 +-51 +-53 +-54 +-54 +-54 +-52 +-50 +-48 +-47 +-44 +-42 +-40 +-37 +-35 +-32 +-30 +-28 +-26 +-24 +-23 +-21 +-20 +-19 +-18 +-16 +-15 +-5 +16 +31 +41 +47 +52 +55 +57 +57 +58 +57 +55 +53 +51 +49 +46 +37 +16 +0 +-12 +-21 +-27 +-32 +-34 +-37 +-38 +-38 +-37 +-37 +-36 +-35 +-32 +-22 +0 +14 +25 +31 +36 +40 +42 +43 +44 +44 +43 +42 +41 +39 +37 +29 +9 +-6 +-17 +-26 +-32 +-37 +-40 +-42 +-43 +-44 +-43 +-42 +-40 +-38 +-36 +-26 +-3 +11 +23 +31 +37 +40 +42 +43 +43 +42 +42 +41 +40 +38 +37 +29 +9 +-6 +-17 +-26 +-31 +-36 +-38 +-40 +-42 +-42 +-43 +-42 +-41 +-39 +-38 +-27 +-6 +10 +21 +29 +35 +39 +41 +43 +43 +43 +42 +40 +39 +37 +35 +26 +7 +-8 +-19 +-28 +-34 +-38 +-40 +-41 +-41 +-41 +-40 +-39 +-38 +-37 +-36 +-26 +-4 +11 +22 +29 +35 +39 +42 +43 +44 +43 +43 +42 +41 +39 +37 +29 +9 +-7 +-18 +-26 +-32 +-36 +-39 +-40 +-41 +-41 +-40 +-38 +-37 +-36 +-34 +-23 +-2 +12 +23 +30 +35 +39 +41 +42 +43 +42 +42 +41 +40 +38 +37 +29 +9 +-6 +-18 +-27 +-33 +-38 +-41 +-44 +-44 +-44 +-44 +-43 +-41 +-40 +-38 +-27 +-5 +10 +21 +29 +34 +37 +39 +40 +40 +40 +39 +38 +37 +36 +34 +27 +7 +-7 +-19 +-27 +-34 +-38 +-41 +-43 +-44 +-44 +-44 +-43 +-41 +-40 +-38 +-26 +-5 +10 +21 +29 +35 +39 +42 +44 +44 +45 +43 +41 +40 +38 +37 +29 +9 +-6 +-17 +-25 +-31 +-35 +-38 +-40 +-41 +-40 +-39 +-38 +-38 +-37 +-36 +-26 +-4 +10 +21 +29 +35 +39 +42 +42 +42 +42 +43 +41 +40 +38 +37 +35 +33 +31 +29 +27 +26 +24 +22 +21 +20 +19 +18 +17 +15 +15 +14 +7 +-12 +-26 +-36 +-43 +-48 +-52 +-54 +-55 +-55 +-55 +-53 +-51 +-49 +-47 +-44 +-33 +-10 +5 +17 +25 +31 +35 +37 +39 +40 +39 +38 +37 +36 +35 +33 +25 +6 +-9 +-21 +-29 +-35 +-38 +-41 +-43 +-43 +-43 +-42 +-41 +-40 +-39 +-37 +-27 +-6 +9 +21 +28 +34 +38 +40 +41 +42 +42 +42 +41 +40 +39 +37 +30 +9 +-6 +-18 +-27 +-33 +-37 +-39 +-41 +-42 +-42 +-41 +-39 +-37 +-35 +-33 +-23 +-1 +14 +24 +33 +37 +41 +42 +42 +43 +43 +42 +42 +40 +39 +37 +29 +9 +-6 +-17 +-26 +-32 +-36 +-39 +-41 +-42 +-42 +-42 +-42 +-40 +-39 +-38 +-27 +-6 +9 +20 +29 +34 +38 +41 +42 +43 +43 +42 +41 +39 +38 +36 +27 +7 +-8 +-19 +-28 +-34 +-38 +-42 +-43 +-43 +-44 +-43 +-42 +-41 +-38 +-37 +-27 +-5 +10 +21 +29 +35 +38 +41 +42 +43 +42 +43 +41 +41 +39 +38 +29 +9 +-7 +-18 +-28 +-34 +-38 +-41 +-43 +-43 +-43 +-42 +-41 +-40 +-38 +-35 +-25 +-3 +11 +23 +30 +36 +40 +42 +42 +42 +42 +42 +41 +40 +38 +37 +28 +9 +-6 +-18 +-26 +-32 +-36 +-39 +-41 +-43 +-43 +-42 +-41 +-41 +-39 +-37 +-27 +-5 +10 +20 +29 +35 +38 +41 +42 +42 +42 +41 +40 +38 +37 +35 +26 +6 +-9 +-20 +-28 +-34 +-38 +-41 +-42 +-43 +-42 +-42 +-41 +-40 +-38 +-36 +-26 +-5 +10 +21 +30 +35 +39 +42 +42 +43 +42 +42 +41 +40 +39 +37 +29 +9 +-6 +-17 +-26 +-33 +-37 +-40 +-42 +-42 +-43 +-42 +-41 +-39 +-38 +-36 +-34 +-32 +-30 +-28 +-26 +-24 +-23 +-21 +-21 +-19 +-19 +-17 +-16 +-15 +-14 +-12 +-2 +18 +32 +42 +49 +53 +56 +58 +58 +58 +56 +55 +52 +50 +47 +45 +36 +15 +-1 +-12 +-22 +-28 +-33 +-35 +-37 +-38 +-38 +-37 +-36 +-36 +-34 +-33 +-23 +-2 +12 +24 +31 +37 +40 +43 +43 +44 +44 +43 +43 +41 +39 +38 +29 +9 +-7 +-19 +-27 +-34 +-38 +-41 +-43 +-43 +-43 +-42 +-41 +-39 +-38 +-37 +-26 +-4 +11 +22 +29 +35 +37 +39 +40 +41 +40 +41 +39 +38 +37 +36 +28 +9 +-6 +-18 +-26 +-32 +-37 +-40 +-41 +-42 +-42 +-42 +-41 +-40 +-38 +-36 +-25 +-4 +11 +22 +31 +36 +40 +42 +43 +43 +42 +42 +41 +40 +38 +37 +29 +9 +-6 +-18 +-26 +-31 +-35 +-38 +-39 +-40 +-40 +-40 +-39 +-39 +-37 +-35 +-24 +-3 +11 +23 +31 +37 +39 +42 +43 +44 +44 +43 +42 +40 +38 +36 +28 +8 +-8 +-19 +-28 +-34 +-38 +-41 +-42 +-42 +-42 +-42 +-40 +-39 +-37 +-36 +-25 +-3 +12 +22 +29 +35 +39 +41 +43 +43 +43 +42 +42 +41 +40 +38 +30 +11 +-4 +-16 +-25 +-31 +-36 +-38 +-40 +-41 +-41 +-40 +-39 +-37 +-36 +-34 +-23 +-2 +13 +25 +32 +38 +41 +43 +45 +44 +44 +42 +41 +39 +37 +37 +28 +8 +-7 +-19 +-28 +-33 +-38 +-40 +-42 +-43 +-43 +-42 +-41 +-40 +-39 +-38 +-27 +-5 +10 +22 +30 +36 +39 +41 +43 +43 +43 +43 +41 +40 +38 +36 +28 +8 +-7 +-19 +-27 +-33 +-37 +-40 +-41 +-41 +-41 +-41 +-40 +-38 +-36 +-34 +-23 +-2 +12 +23 +30 +36 +40 +42 +43 +43 +43 +42 +41 +40 +39 +37 +35 +34 +33 +31 +29 +28 +26 +23 +22 +21 +19 +17 +16 +14 +13 +13 +5 +-14 +-29 +-39 +-47 +-51 +-54 +-56 +-56 +-55 +-55 +-53 +-52 +-50 +-48 +-46 +-35 +-12 +3 +15 +22 +29 +33 +36 +38 +39 +39 +40 +39 +38 +37 +35 +27 +7 +-8 +-20 +-28 +-35 +-38 +-41 +-43 +-43 +-42 +-42 +-41 +-40 +-39 +-37 +-26 +-5 +10 +21 +29 +34 +37 +40 +40 +40 +39 +39 +38 +37 +35 +34 +25 +6 +-9 +-21 +-30 +-36 +-40 +-42 +-44 +-46 +-46 +-45 +-43 +-42 +-39 +-37 +-26 +-5 +10 +22 +30 +35 +38 +41 +42 +42 +42 +42 +41 +40 +37 +36 +28 +8 +-7 +-18 +-27 +-33 +-37 +-40 +-41 +-42 +-42 +-41 +-41 +-40 +-37 +-36 +-25 +-5 +11 +22 +30 +35 +40 +42 +44 +44 +44 +43 +42 +41 +39 +37 +29 +9 +-6 +-18 +-26 +-32 +-37 +-39 +-41 +-42 +-41 +-40 +-39 +-38 +-38 +-36 +-25 +-4 +11 +22 +30 +35 +38 +41 +42 +43 +43 +43 +42 +41 +39 +37 +29 +10 +-6 +-18 +-27 +-33 +-37 +-40 +-41 +-42 +-42 +-42 +-40 +-38 +-37 +-35 +-24 +-2 +14 +24 +32 +37 +40 +42 +43 +43 +43 +42 +41 +39 +37 +36 +28 +8 +-7 +-18 +-27 +-33 +-37 +-40 +-41 +-42 +-43 +-43 +-42 +-41 +-40 +-38 +-28 +-6 +9 +21 +29 +34 +38 +40 +42 +43 +42 +42 +40 +39 +37 +36 +28 +7 +-8 +-20 +-28 +-34 +-38 +-41 +-42 +-43 +-42 +-42 +-40 +-38 +-37 +-36 +-25 +-3 +12 +22 +30 +36 +39 +41 +43 +43 +43 +42 +41 +40 +39 +38 +30 +9 +-6 +-18 +-27 +-33 +-38 +-41 +-43 +-43 +-43 +-42 +-41 +-40 +-39 +-37 +-26 +-5 +10 +22 +30 +36 +39 +41 +42 +42 +41 +41 +39 +38 +37 +35 +27 +8 +-8 +-19 +-28 +-34 +-38 +-41 +-42 +-43 +-43 +-43 +-42 +-41 +-39 +-38 +-27 +-5 +10 +22 +30 +35 +39 +41 +42 +43 +42 +42 +40 +39 +37 +35 +26 +7 +-7 +-19 +-28 +-34 +-38 +-41 +-42 +-42 +-42 +-41 +-40 +-39 +-38 +-36 +-34 +-32 +-31 +-29 +-27 +-26 +-25 +-22 +-21 +-20 +-19 +-18 +-16 +-15 +-14 +-13 +-4 +17 +30 +40 +46 +51 +52 +54 +55 +54 +53 +52 +51 +49 +48 +45 +36 +16 +0 +-12 +-22 +-28 +-33 +-36 +-38 +-38 +-38 +-38 +-37 +-36 +-35 +-33 +-22 +-1 +15 +26 +34 +38 +42 +44 +45 +46 +44 +44 +43 +41 +39 +38 +36 +34 +32 +31 +29 +28 +26 +24 +23 +21 +19 +18 +17 +15 +15 +14 +7 +-13 +-27 +-37 +-44 +-49 +-53 +-54 +-55 +-55 +-55 +-54 +-51 +-50 +-48 +-46 +-33 +-11 +4 +15 +24 +30 +34 +37 +39 +40 +40 +40 +40 +39 +37 +35 +27 +7 +-7 +-19 +-27 +-34 +-37 +-39 +-40 +-40 +-40 +-40 +-40 +-38 +-36 +-34 +-24 +-2 +12 +23 +30 +36 +39 +42 +42 +43 +42 +42 +41 +40 +39 +38 +30 +9 +-6 +-18 +-27 +-34 +-38 +-41 +-43 +-43 +-43 +-43 +-42 +-40 +-38 +-37 +-35 +-33 +-32 +-30 +-28 +-25 +-23 +-22 +-21 +-20 +-19 +-17 +-16 +-15 +-14 +-13 +-3 +18 +32 +43 +49 +54 +58 +59 +59 +59 +58 +56 +54 +52 +49 +47 +44 +42 +40 +38 +36 +34 +31 +30 +28 +27 +26 +25 +23 +22 +20 +19 +11 +-8 +-23 +-35 +-42 +-47 +-51 +-52 +-53 +-54 +-52 +-51 +-49 +-48 +-46 +-43 +-33 +-11 +4 +15 +23 +29 +32 +35 +36 +37 +36 +36 +36 +35 +33 +33 +25 +5 +-10 +-22 +-30 +-37 +-41 +-45 +-46 +-46 +-46 +-45 +-44 +-42 +-41 +-39 +-37 +-35 +-33 +-31 +-29 +-27 +-26 +-25 +-24 +-22 +-21 +-20 +-19 +-17 +-16 +-15 +-4 +16 +31 +41 +48 +52 +55 +57 +57 +57 +55 +53 +51 +50 +47 +45 +42 +40 +37 +36 +33 +32 +30 +29 +27 +26 +24 +23 +21 +20 +19 +18 +10 +-9 +-23 +-34 +-42 +-48 +-51 +-53 +-54 +-54 +-53 +-51 +-48 +-46 +-45 +-43 +-32 +-10 +4 +15 +23 +29 +33 +36 +37 +38 +39 +38 +38 +36 +35 +34 +27 +7 +-8 +-19 +-28 +-34 +-38 +-41 +-43 +-43 +-43 +-43 +-42 +-40 +-38 +-37 +-26 +-4 +11 +22 +31 +36 +39 +41 +42 +42 +42 +41 +40 +39 +37 +36 +27 +7 +-8 +-19 +-27 +-33 +-37 +-40 +-41 +-42 +-43 +-42 +-41 +-40 +-39 +-36 +-26 +-4 +11 +22 +30 +36 +39 +42 +43 +44 +43 +43 +41 +40 +38 +36 +28 +8 +-7 +-19 +-27 +-33 +-37 +-40 +-42 +-43 +-42 +-41 +-40 +-39 +-37 +-36 +-34 +-32 +-31 +-30 +-28 +-27 +-26 +-24 +-22 +-21 +-20 +-18 +-16 +-15 +-14 +-13 +-3 +18 +32 +41 +48 +52 +55 +56 +56 +55 +54 +53 +51 +49 +47 +45 +36 +17 +1 +-10 +-19 +-25 +-30 +-34 +-36 +-37 +-38 +-38 +-37 +-35 +-35 +-33 +-23 +-1 +15 +26 +34 +39 +42 +44 +44 +44 +43 +42 +41 +39 +37 +36 +28 +7 +-8 +-19 +-28 +-34 +-39 +-41 +-43 +-43 +-43 +-43 +-42 +-40 +-39 +-38 +-27 +-6 +9 +20 +28 +34 +38 +41 +42 +44 +44 +43 +41 +40 +38 +36 +34 +32 +29 +28 +27 +26 +24 +24 +23 +21 +20 +19 +18 +17 +16 +14 +7 +-12 +-26 +-38 +-45 +-51 +-53 +-55 +-56 +-56 +-54 +-53 +-51 +-48 +-45 +-43 +-32 +-10 +5 +17 +25 +31 +35 +39 +40 +40 +40 +39 +38 +38 +37 +36 +28 +9 +-6 +-18 +-27 +-33 +-38 +-40 +-42 +-43 +-43 +-42 +-41 +-39 +-37 +-36 +-35 +-32 +-30 +-28 +-27 +-25 +-24 +-22 +-22 +-21 +-21 +-19 +-18 +-16 +-15 +-13 +-4 +16 +31 +41 +48 +53 +55 +57 +57 +56 +55 +53 +51 +49 +47 +46 +43 +41 +38 +36 +35 +33 +31 +30 +28 +27 +25 +23 +22 +21 +19 +18 +9 +-9 +-24 +-34 +-42 +-47 +-50 +-51 +-52 +-52 +-51 +-50 +-49 +-47 +-46 +-44 +-33 +-11 +4 +15 +24 +29 +33 +36 +37 +38 +38 +38 +37 +36 +35 +33 +24 +5 +-11 +-22 +-31 +-37 +-40 +-43 +-45 +-46 +-46 +-45 +-44 +-42 +-40 +-38 +-27 +-6 +9 +19 +27 +32 +36 +38 +39 +40 +40 +39 +38 +37 +36 +35 +27 +7 +-8 +-19 +-27 +-34 +-38 +-42 +-43 +-43 +-43 +-42 +-41 +-40 +-38 +-36 +-25 +-3 +13 +24 +32 +37 +42 +44 +44 +44 +43 +42 +41 +40 +38 +36 +28 +9 +-6 +-17 +-25 +-31 +-36 +-38 +-40 +-42 +-42 +-42 +-41 +-39 +-38 +-36 +-26 +-4 +12 +23 +31 +37 +40 +43 +44 +44 +43 +43 +41 +39 +38 +37 +28 +9 +-6 +-18 +-26 +-32 +-36 +-39 +-40 +-41 +-41 +-41 +-39 +-39 +-38 +-36 +-26 +-4 +10 +21 +30 +36 +39 +42 +44 +44 +44 +44 +43 +42 +40 +38 +29 +9 +-6 +-18 +-27 +-33 +-36 +-40 +-41 +-42 +-42 +-41 +-40 +-38 +-36 +-34 +-24 +-3 +12 +22 +30 +35 +39 +41 +42 +43 +42 +41 +40 +39 +37 +36 +28 +8 +-8 +-19 +-28 +-33 +-37 +-41 +-43 +-44 +-44 +-44 +-43 +-42 +-40 +-37 +-27 +-5 +10 +21 +29 +35 +38 +40 +40 +40 +39 +39 +38 +37 +35 +33 +25 +5 +-10 +-21 +-29 +-35 +-38 +-41 +-43 +-43 +-43 +-42 +-41 +-41 +-39 +-37 +-35 +-33 +-31 +-29 +-28 +-26 +-25 +-23 +-21 +-19 +-18 +-17 +-16 +-15 +-14 +-14 +-4 +16 +31 +41 +48 +52 +54 +56 +57 +57 +55 +54 +52 +50 +48 +46 +36 +16 +0 +-12 +-21 +-28 +-33 +-36 +-38 +-39 +-39 +-39 +-38 +-36 +-35 +-33 +-22 +0 +14 +25 +32 +37 +40 +43 +44 +45 +44 +44 +43 +41 +40 +39 +31 +12 +-3 +-15 +-23 +-29 +-34 +-37 +-39 +-40 +-40 +-40 +-39 +-37 +-35 +-33 +-23 +-1 +14 +25 +33 +39 +42 +44 +45 +45 +45 +44 +43 +41 +39 +37 +28 +8 +-7 +-18 +-26 +-33 +-37 +-40 +-41 +-42 +-41 +-41 +-40 +-39 +-37 +-36 +-25 +-4 +11 +22 +30 +35 +39 +41 +42 +44 +43 +43 +41 +41 +39 +37 +28 +9 +-8 +-19 +-28 +-34 +-38 +-40 +-42 +-42 +-43 +-42 +-41 +-39 +-37 +-36 +-26 +-4 +10 +20 +28 +34 +37 +39 +40 +41 +41 +40 +39 +39 +38 +36 +28 +9 +-6 +-17 +-26 +-32 +-37 +-40 +-42 +-42 +-42 +-41 +-41 +-39 +-37 +-35 +-24 +-2 +13 +25 +32 +38 +41 +43 +44 +44 +43 +42 +41 +40 +38 +37 +29 +9 +-6 +-17 +-25 +-31 +-36 +-39 +-41 +-41 +-42 +-42 +-41 +-40 +-38 +-37 +-27 +-4 +10 +21 +29 +35 +39 +42 +43 +44 +44 +43 +42 +40 +39 +37 +28 +8 +-7 +-18 +-27 +-33 +-38 +-41 +-42 +-43 +-42 +-42 +-41 +-40 +-38 +-36 +-25 +-3 +12 +23 +30 +35 +38 +41 +42 +42 +42 +41 +40 +39 +37 +36 +28 +8 +-7 +-18 +-27 +-33 +-38 +-41 +-43 +-44 +-43 +-42 +-41 +-40 +-38 +-37 +-26 +-4 +11 +22 +31 +36 +40 +42 +43 +44 +43 +42 +40 +38 +37 +36 +34 +33 +31 +29 +27 +25 +24 +23 +21 +21 +20 +19 +17 +16 +14 +14 +6 +-13 +-27 +-38 +-46 +-51 +-55 +-56 +-57 +-56 +-55 +-53 +-51 +-49 +-47 +-45 +-33 +-11 +4 +16 +24 +30 +33 +36 +38 +40 +39 +39 +38 +37 +36 +35 +27 +7 +-8 +-20 +-28 +-34 +-37 +-41 +-43 +-44 +-44 +-44 +-42 +-41 +-39 +-38 +-27 +-5 +11 +22 +29 +35 +39 +41 +42 +42 +41 +40 +38 +37 +36 +35 +28 +8 +-8 +-19 +-27 +-34 +-37 +-39 +-40 +-41 +-41 +-41 +-39 +-38 +-37 +-36 +-25 +-3 +12 +23 +31 +37 +40 +43 +44 +44 +45 +44 +42 +40 +38 +37 +28 +8 +-7 +-18 +-27 +-33 +-37 +-40 +-42 +-43 +-42 +-41 +-39 +-38 +-36 +-35 +-25 +-3 +11 +22 +29 +35 +39 +41 +41 +42 +41 +41 +39 +38 +37 +36 +28 +8 +-8 +-20 +-28 +-35 +-40 +-43 +-45 +-45 +-44 +-44 +-43 +-41 +-39 +-38 +-27 +-5 +10 +21 +29 +34 +37 +39 +40 +41 +41 +40 +39 +38 +37 +36 +28 +8 +-7 +-19 +-27 +-32 +-36 +-39 +-40 +-41 +-42 +-41 +-40 +-39 +-37 +-35 +-26 +-4 +11 +23 +30 +36 +39 +42 +43 +44 +44 +43 +42 +40 +38 +37 +29 +9 +-6 +-17 +-26 +-32 +-36 +-39 +-41 +-41 +-41 +-40 +-39 +-37 +-36 +-34 +-25 +-3 +12 +23 +31 +36 +39 +42 +43 +43 +43 +43 +42 +41 +39 +37 +28 +7 +-8 +-20 +-28 +-34 +-38 +-42 +-43 +-44 +-44 +-43 +-42 +-41 +-39 +-37 +-35 +-33 +-31 +-29 +-28 +-27 +-26 +-25 +-24 +-22 +-21 +-19 +-17 +-16 +-15 +-13 +-4 +18 +32 +43 +49 +54 +56 +57 +57 +57 +56 +54 +52 +51 +49 +47 +45 +43 +41 +39 +37 +34 +32 +30 +29 +27 +24 +23 +21 +20 +19 +18 +10 +-8 +-23 +-33 +-41 +-47 +-50 +-52 +-53 +-53 +-52 +-51 +-50 +-49 +-47 +-45 +-42 +-40 +-38 +-36 +-33 +-32 +-30 +-27 +-25 +-24 +-22 +-20 +-19 +-18 +-16 +-15 +-6 +15 +29 +40 +47 +52 +54 +56 +56 +56 +55 +54 +53 +51 +49 +47 +44 +42 +39 +37 +34 +32 +30 +29 +26 +25 +24 +22 +21 +20 +18 +17 +10 +-9 +-24 +-35 +-43 +-49 +-53 +-55 +-56 +-56 +-56 +-54 +-52 +-50 +-48 +-46 +-44 +-41 +-38 +-36 +-34 +-32 +-30 +-28 +-26 +-25 +-24 +-23 +-21 +-20 +-19 +-18 +-8 +13 +29 +39 +46 +51 +54 +55 +56 +55 +54 +52 +50 +49 +47 +44 +42 +40 +37 +35 +33 +32 +29 +28 +25 +25 +23 +22 +21 +21 +20 +19 +10 +-8 +-22 +-32 +-41 +-46 +-50 +-52 +-53 +-53 +-52 +-50 +-49 +-47 +-45 +-43 +-40 +-38 +-36 +-35 +-33 +-31 +-30 +-28 +-26 +-24 +-23 +-22 +-21 +-19 +-18 +-17 +-6 +14 +29 +40 +48 +52 +55 +57 +57 +57 +56 +54 +52 +50 +48 +46 +44 +41 +38 +36 +35 +33 +32 +30 +28 +27 +25 +24 +21 +20 +18 +17 +9 +-10 +-25 +-35 +-42 +-47 +-51 +-52 +-53 +-53 +-52 +-51 +-50 +-48 +-46 +-44 +-42 +-40 +-39 +-37 +-35 +-33 +-31 +-29 +-27 +-25 +-24 +-22 +-20 +-19 +-17 +-16 +-6 +15 +29 +38 +45 +49 +51 +53 +53 +53 +52 +51 +50 +48 +47 +44 +43 +41 +39 +36 +34 +32 +30 +28 +26 +24 +22 +21 +20 +18 +18 +17 +9 +-11 +-25 +-35 +-41 +-47 +-51 +-52 +-52 +-53 +-53 +-52 +-51 +-49 +-47 +-44 +-42 +-39 +-37 +-35 +-33 +-30 +-28 +-26 +-25 +-23 +-22 +-20 +-19 +-18 +-17 +-16 +-6 +15 +29 +40 +47 +51 +54 +55 +56 +56 +55 +53 +52 +50 +48 +46 +37 +16 +0 +-12 +-20 +-27 +-32 +-35 +-37 +-37 +-37 +-36 +-36 +-35 +-33 +-32 +-22 +-1 +14 +24 +31 +37 +40 +42 +43 +44 +43 +43 +42 +40 +38 +37 +29 +9 +-6 +-17 +-26 +-32 +-37 +-40 +-42 +-43 +-43 +-43 +-42 +-41 +-39 +-37 +-27 +-5 +10 +22 +30 +36 +39 +42 +43 +43 +42 +41 +40 +39 +37 +36 +28 +8 +-7 +-18 +-27 +-33 +-37 +-40 +-42 +-42 +-42 +-42 +-41 +-39 +-38 +-37 +-27 +-4 +10 +22 +29 +35 +38 +41 +43 +43 +42 +41 +40 +40 +38 +37 +29 +10 +-6 +-18 +-27 +-33 +-38 +-40 +-41 +-42 +-42 +-41 +-40 +-38 +-36 +-35 +-24 +-2 +13 +24 +32 +37 +40 +42 +43 +43 +42 +42 +40 +39 +38 +37 +28 +8 +-7 +-18 +-27 +-32 +-37 +-40 +-41 +-42 +-42 +-42 +-41 +-40 +-38 +-37 +-26 +-5 +10 +21 +29 +35 +39 +41 +43 +43 +43 +42 +40 +39 +38 +37 +28 +8 +-8 +-19 +-27 +-34 +-38 +-41 +-42 +-43 +-43 +-41 +-41 +-38 +-36 +-34 +-23 +-2 +12 +24 +31 +36 +39 +41 +42 +43 +42 +42 +40 +39 +38 +36 +28 +9 +-7 +-18 +-27 +-31 +-36 +-39 +-41 +-42 +-43 +-43 +-43 +-41 +-40 +-38 +-28 +-6 +9 +21 +29 +34 +38 +40 +41 +42 +42 +41 +40 +39 +37 +36 +27 +8 +-7 +-19 +-28 +-34 +-39 +-41 +-42 +-42 +-43 +-42 +-41 +-40 +-38 +-36 +-25 +-4 +11 +22 +29 +35 +38 +41 +42 +43 +43 +42 +42 +40 +39 +38 +37 +35 +33 +32 +30 +29 +27 +25 +23 +23 +21 +20 +19 +17 +16 +16 +8 +-10 +-25 +-35 +-42 +-47 +-51 +-53 +-54 +-54 +-53 +-52 +-51 +-49 +-47 +-45 +-34 +-12 +4 +14 +23 +28 +32 +36 +37 +38 +38 +38 +37 +36 +35 +33 +24 +4 +-11 +-23 +-31 +-37 +-41 +-43 +-45 +-46 +-45 +-45 +-43 +-42 +-40 +-38 +-27 +-5 +10 +21 +29 +35 +38 +39 +39 +40 +40 +40 +39 +38 +37 +35 +27 +8 +-7 +-18 +-26 +-32 +-37 +-40 +-42 +-42 +-42 +-42 +-41 +-39 +-38 +-36 +-26 +-4 +11 +22 +30 +36 +39 +42 +43 +44 +43 +42 +40 +39 +37 +36 +27 +7 +-7 +-19 +-28 +-34 +-37 +-40 +-42 +-42 +-42 +-41 +-40 +-39 +-37 +-35 +-25 +-4 +11 +22 +30 +35 +39 +42 +43 +44 +44 +43 +42 +41 +39 +38 +29 +9 +-7 +-19 +-28 +-34 +-38 +-41 +-42 +-43 +-43 +-42 +-41 +-40 +-38 +-36 +-25 +-3 +11 +22 +30 +36 +39 +41 +42 +42 +42 +42 +41 +40 +38 +37 +29 +9 +-6 +-17 +-26 +-32 +-36 +-39 +-41 +-43 +-42 +-42 +-40 +-38 +-36 +-35 +-24 +-2 +13 +24 +32 +36 +40 +43 +44 +45 +44 +43 +40 +39 +37 +36 +27 +7 +-9 +-20 +-28 +-34 +-38 +-41 +-42 +-43 +-43 +-43 +-42 +-41 +-39 +-39 +-29 +-7 +7 +19 +27 +33 +36 +39 +40 +41 +40 +40 +39 +39 +38 +36 +27 +8 +-7 +-19 +-28 +-34 +-39 +-42 +-44 +-44 +-44 +-43 +-42 +-40 +-38 +-36 +-25 +-3 +13 +24 +32 +37 +41 +43 +43 +43 +43 +42 +41 +40 +38 +36 +28 +9 +-6 +-17 +-26 +-31 +-36 +-38 +-40 +-40 +-41 +-41 +-40 +-38 +-37 +-36 +-34 +-32 +-30 +-28 +-27 +-25 +-23 +-22 +-20 +-18 +-17 +-16 +-15 +-15 +-14 +-13 +-4 +16 +31 +40 +48 +52 +55 +56 +57 +56 +55 +54 +52 +50 +48 +45 +43 +40 +39 +37 +33 +30 +29 +27 +25 +24 +24 +22 +21 +20 +19 +19 +11 +-8 +-23 +-34 +-42 +-47 +-50 +-52 +-53 +-54 +-53 +-51 +-49 +-46 +-45 +-42 +-30 +-7 +7 +20 +27 +33 +37 +39 +40 +41 +41 +40 +40 +38 +37 +35 +28 +8 +-7 +-18 +-27 +-32 +-36 +-39 +-41 +-41 +-41 +-42 +-41 +-39 +-37 +-35 +-25 +-4 +10 +21 +30 +35 +39 +42 +43 +43 +43 +42 +41 +39 +37 +35 +27 +7 +-9 +-20 +-29 +-34 +-38 +-39 +-41 +-42 +-42 +-41 +-40 +-39 +-37 +-35 +-33 +-32 +-30 +-29 +-27 +-25 +-24 +-22 +-21 +-20 +-18 +-17 +-16 +-14 +-13 +-13 +-2 +19 +33 +43 +49 +53 +56 +57 +57 +57 +55 +54 +52 +50 +48 +46 +44 +42 +39 +37 +34 +33 +30 +29 +28 +26 +24 +23 +22 +20 +19 +18 +9 +-10 +-25 +-35 +-43 +-48 +-52 +-54 +-55 +-54 +-54 +-52 +-50 +-49 +-46 +-45 +-33 +-11 +5 +16 +24 +30 +33 +36 +37 +38 +38 +37 +36 +36 +35 +33 +26 +6 +-8 +-20 +-29 +-35 +-40 +-43 +-45 +-45 +-46 +-45 +-44 +-42 +-41 +-39 +-37 +-35 +-33 +-31 +-29 +-28 +-26 +-24 +-22 +-21 +-20 +-18 +-18 +-17 +-17 +-16 +-6 +14 +28 +38 +45 +50 +54 +55 +55 +56 +55 +53 +52 +49 +47 +45 +36 +16 +0 +-13 +-21 +-27 +-32 +-35 +-37 +-37 +-37 +-37 +-37 +-36 +-35 +-32 +-22 +-1 +14 +25 +32 +37 +41 +43 +43 +43 +43 +42 +40 +39 +37 +36 +34 +32 +31 +30 +28 +26 +25 +24 +23 +21 +20 +19 +18 +16 +15 +14 +7 +-13 +-27 +-37 +-45 +-49 +-53 +-54 +-56 +-56 +-55 +-53 +-51 +-49 +-46 +-44 +-42 +-40 +-38 +-36 +-34 +-32 +-30 +-28 +-26 +-25 +-23 +-21 +-20 +-18 +-16 +-15 +-6 +16 +30 +40 +48 +52 +55 +56 +56 +56 +54 +53 +51 +49 +46 +44 +42 +40 +38 +36 +34 +32 +31 +30 +28 +26 +25 +24 +22 +20 +19 +18 +10 +-9 +-24 +-35 +-42 +-47 +-50 +-53 +-53 +-53 +-52 +-50 +-49 +-47 +-44 +-42 +-31 +-10 +6 +17 +25 +31 +34 +36 +38 +38 +38 +38 +37 +36 +34 +33 +25 +5 +-10 +-21 +-30 +-36 +-40 +-43 +-45 +-46 +-46 +-45 +-44 +-42 +-40 +-38 +-36 +-34 +-32 +-30 +-28 +-26 +-25 +-23 +-21 +-20 +-19 +-18 +-17 +-16 +-15 +-14 +-4 +16 +31 +41 +48 +53 +56 +58 +58 +58 +57 +55 +53 +51 +48 +46 +43 +41 +38 +36 +34 +32 +31 +30 +29 +27 +26 +24 +23 +21 +20 +19 +11 +-8 +-23 +-34 +-42 +-48 +-51 +-53 +-53 +-53 +-53 +-52 +-51 +-49 +-47 +-44 +-33 +-10 +5 +17 +24 +30 +33 +36 +37 +38 +37 +37 +36 +35 +34 +33 +25 +6 +-9 +-20 +-28 +-34 +-38 +-40 +-42 +-43 +-43 +-43 +-42 +-40 +-38 +-37 +-35 +-33 +-31 +-29 +-27 +-25 +-24 +-22 +-21 +-19 +-18 +-17 +-16 +-15 +-15 +-14 +-4 +18 +31 +42 +48 +53 +55 +58 +58 +58 +57 +55 +54 +52 +50 +48 +44 +42 +39 +36 +34 +32 +30 +28 +26 +25 +23 +22 +20 +19 +18 +17 +9 +-10 +-24 +-34 +-43 +-48 +-52 +-54 +-56 +-55 +-55 +-53 +-52 +-50 +-48 +-45 +-43 +-40 +-38 +-35 +-33 +-31 +-29 +-27 +-26 +-24 +-24 +-22 +-21 +-19 +-18 +-17 +-6 +15 +29 +40 +46 +52 +54 +56 +57 +57 +55 +53 +51 +49 +47 +45 +36 +16 +0 +-12 +-21 +-27 +-32 +-35 +-37 +-38 +-38 +-38 +-37 +-36 +-35 +-34 +-24 +-3 +11 +22 +31 +36 +39 +41 +42 +43 +43 +42 +42 +41 +39 +37 +28 +7 +-8 +-20 +-28 +-34 +-38 +-41 +-43 +-43 +-43 +-42 +-41 +-38 +-37 +-34 +-24 +-2 +13 +23 +31 +36 +40 +42 +43 +44 +43 +43 +41 +40 +39 +38 +29 +9 +-6 +-18 +-27 +-33 +-37 +-40 +-42 +-42 +-42 +-42 +-41 +-40 +-38 +-36 +-25 +-3 +12 +23 +30 +36 +39 +42 +42 +42 +42 +41 +40 +39 +37 +36 +28 +8 +-6 +-17 +-26 +-32 +-36 +-40 +-41 +-43 +-42 +-42 +-41 +-40 +-38 +-37 +-26 +-4 +10 +21 +29 +35 +39 +41 +42 +43 +43 +42 +41 +39 +38 +37 +28 +8 +-7 +-19 +-27 +-33 +-37 +-40 +-41 +-42 +-42 +-41 +-41 +-40 +-38 +-37 +-26 +-5 +10 +21 +28 +34 +38 +41 +42 +43 +42 +42 +40 +39 +38 +37 +29 +8 +-7 +-19 +-28 +-34 +-38 +-40 +-42 +-42 +-41 +-41 +-40 +-39 +-37 +-36 +-25 +-4 +11 +22 +29 +34 +38 +40 +42 +43 +43 +42 +41 +40 +38 +37 +29 +10 +-6 +-18 +-26 +-33 +-37 +-40 +-42 +-43 +-42 +-41 +-40 +-39 +-37 +-35 +-24 +-1 +14 +25 +33 +39 +42 +44 +45 +45 +44 +42 +41 +41 +39 +38 +29 +9 +-6 +-17 +-26 +-32 +-36 +-38 +-40 +-41 +-42 +-41 +-41 +-40 +-38 +-36 +-26 +-5 +10 +21 +29 +34 +37 +40 +41 +43 +42 +41 +39 +39 +37 +35 +33 +32 +29 +28 +26 +25 +23 +22 +20 +20 +18 +18 +16 +15 +14 +13 +6 +-12 +-27 +-38 +-46 +-51 +-54 +-56 +-58 +-57 +-56 +-54 +-53 +-51 +-48 +-45 +-34 +-11 +5 +17 +25 +31 +34 +38 +39 +39 +39 +39 +38 +37 +36 +34 +26 +7 +-8 +-19 +-27 +-32 +-36 +-39 +-41 +-41 +-42 +-41 +-40 +-39 +-38 +-36 +-26 +-4 +11 +22 +30 +35 +39 +41 +43 +43 +43 +42 +41 +39 +37 +36 +27 +7 +-8 +-20 +-28 +-34 +-38 +-40 +-41 +-43 +-42 +-42 +-41 +-39 +-38 +-37 +-26 +-5 +9 +20 +27 +33 +36 +40 +41 +42 +41 +42 +40 +40 +38 +37 +29 +9 +-7 +-18 +-28 +-34 +-38 +-41 +-43 +-43 +-43 +-43 +-41 +-40 +-38 +-36 +-25 +-3 +11 +22 +30 +35 +38 +40 +42 +43 +42 +41 +40 +39 +37 +36 +29 +9 +-6 +-18 +-26 +-32 +-36 +-40 +-42 +-43 +-44 +-43 +-42 +-40 +-39 +-37 +-27 +-5 +10 +22 +30 +35 +39 +41 +42 +42 +42 +41 +39 +39 +36 +35 +26 +7 +-9 +-20 +-28 +-33 +-38 +-41 +-42 +-43 +-43 +-42 +-41 +-40 +-40 +-38 +-28 +-6 +9 +21 +28 +34 +37 +40 +42 +43 +42 +42 +40 +39 +38 +36 +28 +7 +-8 +-20 +-29 +-35 +-39 +-41 +-43 +-43 +-43 +-42 +-41 +-39 +-37 +-35 +-25 +-3 +11 +22 +30 +36 +39 +42 +43 +44 +43 +43 +41 +40 +38 +37 +30 +10 +-4 +-16 +-25 +-31 +-36 +-40 +-42 +-42 +-42 +-41 +-40 +-38 +-37 +-35 +-25 +-3 +12 +23 +32 +38 +41 +43 +44 +44 +43 +42 +41 +39 +38 +36 +28 +8 +-7 +-18 +-27 +-33 +-37 +-39 +-42 +-43 +-43 +-43 +-42 +-41 +-39 +-38 +-37 +-35 +-33 +-31 +-30 +-28 +-26 +-24 +-22 +-20 +-19 +-17 +-16 +-15 +-15 +-14 +-4 +16 +30 +40 +47 +52 +54 +56 +56 +56 +56 +54 +52 +51 +50 +47 +38 +18 +2 +-11 +-20 +-26 +-31 +-35 +-37 +-37 +-37 +-37 +-36 +-35 +-34 +-31 +-20 +1 +16 +26 +34 +39 +43 +45 +45 +46 +45 +44 +42 +41 +40 +38 +30 +11 +-4 +-16 +-25 +-30 +-34 +-38 +-40 +-41 +-41 +-41 +-41 +-39 +-38 +-36 +-26 +-4 +11 +22 +31 +37 +40 +42 +43 +44 +43 +42 +41 +40 +37 +36 +27 +7 +-8 +-20 +-29 +-35 +-39 +-42 +-43 +-43 +-44 +-43 +-42 +-41 +-39 +-38 +-28 +-6 +9 +19 +27 +32 +36 +38 +40 +40 +40 +40 +39 +38 +37 +35 +27 +8 +-8 +-20 +-29 +-35 +-39 +-42 +-42 +-43 +-43 +-43 +-41 +-40 +-38 +-37 +-26 +-3 +12 +23 +31 +36 +39 +41 +42 +43 +42 +42 +41 +40 +38 +37 +29 +10 +-5 +-16 +-25 +-31 +-36 +-39 +-41 +-41 +-41 +-41 +-40 +-39 +-37 +-35 +-24 +-3 +13 +24 +32 +38 +42 +44 +46 +46 +45 +44 +43 +41 +39 +37 +29 +9 +-6 +-17 +-26 +-32 +-37 +-39 +-42 +-42 +-42 +-42 +-41 +-39 +-38 +-37 +-26 +-5 +10 +21 +29 +34 +38 +40 +41 +42 +42 +41 +41 +40 +38 +36 +28 +8 +-8 +-20 +-29 +-34 +-38 +-41 +-43 +-43 +-42 +-42 +-41 +-40 +-38 +-36 +-25 +-3 +12 +24 +32 +37 +40 +42 +43 +43 +43 +42 +41 +40 +38 +37 +29 +10 +-6 +-17 +-25 +-32 +-35 +-39 +-41 +-42 +-42 +-42 +-41 +-40 +-38 +-36 +-26 +-4 +11 +22 +30 +36 +40 +42 +43 +43 +42 +41 +39 +37 +36 +35 +34 +33 +30 +29 +27 +25 +24 +23 +22 +21 +20 +19 +17 +16 +15 +13 +6 +-13 +-27 +-38 +-45 +-50 +-53 +-54 +-56 +-55 +-54 +-52 +-50 +-47 +-45 +-43 +-32 +-10 +4 +16 +24 +30 +34 +37 +38 +39 +39 +40 +40 +38 +37 +36 +28 +8 +-8 +-20 +-28 +-34 +-37 +-41 +-42 +-43 +-43 +-43 +-41 +-40 +-38 +-36 +-26 +-4 +11 +23 +31 +36 +40 +42 +43 +43 +42 +41 +39 +38 +36 +35 +26 +7 +-9 +-20 +-28 +-34 +-39 +-41 +-43 +-43 +-43 +-43 +-41 +-40 +-39 +-38 +-28 +-6 +9 +21 +28 +34 +39 +41 +41 +42 +41 +41 +40 +40 +38 +37 +29 +8 +-7 +-19 +-27 +-33 +-37 +-40 +-41 +-42 +-41 +-41 +-39 +-37 +-35 +-33 +-23 +-1 +14 +24 +32 +36 +39 +42 +42 +43 +43 +43 +42 +40 +38 +37 +29 +10 +-5 +-16 +-25 +-32 +-36 +-39 +-41 +-42 +-42 +-41 +-40 +-39 +-37 +-35 +-25 +-3 +13 +24 +32 +37 +41 +44 +45 +46 +45 +44 +43 +42 +39 +38 +29 +9 +-6 +-18 +-26 +-32 +-37 +-39 +-41 +-42 +-42 +-41 +-40 +-38 +-37 +-36 +-25 +-4 +11 +22 +30 +35 +38 +41 +42 +42 +42 +42 +41 +40 +38 +37 +29 +9 +-6 +-18 +-26 +-33 +-38 +-40 +-42 +-43 +-43 +-42 +-42 +-40 +-38 +-37 +-26 +-4 +10 +21 +29 +36 +39 +41 +43 +43 +42 +42 +40 +39 +37 +36 +26 +7 +-8 +-20 +-29 +-34 +-38 +-41 +-43 +-43 +-42 +-41 +-40 +-39 +-38 +-36 +-27 +-6 +10 +21 +28 +34 +37 +40 +41 +42 +42 +41 +40 +39 +37 +36 +27 +8 +-7 +-19 +-28 +-34 +-39 +-42 +-44 +-44 +-44 +-42 +-42 +-41 +-39 +-37 +-27 +-5 +10 +21 +29 +34 +38 +40 +41 +41 +41 +40 +39 +38 +36 +35 +27 +7 +-8 +-19 +-28 +-33 +-37 +-39 +-41 +-41 +-41 +-41 +-40 +-38 +-37 +-35 +-25 +-4 +11 +23 +31 +37 +40 +43 +43 +45 +45 +44 +43 +42 +40 +39 +31 +12 +-4 +-16 +-25 +-32 +-37 +-39 +-41 +-41 +-41 +-40 +-40 +-38 +-37 +-35 +-34 +-31 +-30 +-28 +-27 +-26 +-25 +-23 +-23 +-21 +-19 +-18 +-17 +-16 +-15 +-14 +-4 +17 +31 +42 +49 +54 +55 +57 +56 +56 +54 +52 +49 +47 +45 +43 +35 +14 +-2 +-14 +-23 +-29 +-33 +-36 +-37 +-38 +-38 +-37 +-37 +-36 +-35 +-34 +-23 +-2 +13 +24 +32 +37 +40 +43 +44 +45 +45 +45 +44 +42 +41 +40 +38 +36 +34 +32 +30 +28 +26 +26 +24 +23 +21 +21 +19 +19 +17 +17 +9 +-10 +-25 +-35 +-44 +-49 +-53 +-55 +-56 +-56 +-55 +-54 +-52 +-50 +-47 +-45 +-34 +-12 +4 +16 +23 +29 +32 +35 +36 +37 +36 +36 +35 +35 +33 +32 +24 +5 +-10 +-21 +-30 +-36 +-39 +-42 +-43 +-43 +-43 +-43 +-41 +-40 +-39 +-37 +-26 +-4 +11 +22 +30 +36 +40 +43 +44 +45 +44 +43 +42 +40 +38 +36 +28 +8 +-8 +-19 +-27 +-33 +-38 +-41 +-42 +-42 +-42 +-41 +-40 +-39 +-39 +-37 +-36 +-34 +-32 +-30 +-29 +-27 +-25 +-24 +-23 +-21 +-19 +-17 +-14 +-13 +-13 +-12 +-2 +18 +32 +42 +48 +53 +55 +58 +57 +58 +56 +55 +54 +52 +50 +48 +46 +44 +42 +39 +37 +35 +32 +30 +28 +26 +24 +23 +21 +20 +19 +18 +10 +-8 +-23 +-34 +-42 +-47 +-51 +-53 +-53 +-53 +-53 +-51 +-50 +-48 +-46 +-45 +-34 +-11 +4 +16 +25 +31 +35 +38 +39 +40 +40 +40 +38 +36 +34 +33 +25 +4 +-10 +-22 +-30 +-36 +-40 +-43 +-44 +-44 +-45 +-43 +-43 +-41 +-39 +-37 +-36 +-35 +-33 +-31 +-30 +-28 +-27 +-25 +-24 +-22 +-20 +-19 +-17 +-16 +-14 +-13 +-3 +17 +32 +41 +48 +53 +55 +56 +56 +56 +55 +53 +52 +50 +48 +46 +45 +43 +40 +39 +37 +35 +33 +30 +28 +26 +24 +22 +20 +19 +18 +17 +10 +-10 +-24 +-35 +-42 +-47 +-51 +-52 +-54 +-54 +-53 +-53 +-51 +-49 +-47 +-45 +-34 +-12 +3 +15 +24 +29 +33 +36 +38 +38 +39 +38 +37 +36 +34 +33 +25 +6 +-10 +-20 +-29 +-36 +-40 +-43 +-44 +-44 +-44 +-43 +-41 +-40 +-38 +-37 +-26 +-4 +10 +21 +29 +35 +38 +41 +42 +43 +42 +42 +41 +40 +39 +38 +31 +10 +-5 +-17 +-25 +-31 +-36 +-39 +-40 +-41 +-41 +-41 +-40 +-38 +-37 +-35 +-25 +-3 +12 +23 +32 +37 +41 +43 +44 +44 +43 +43 +41 +40 +38 +36 +27 +7 +-8 +-20 +-28 +-34 +-38 +-41 +-42 +-42 +-42 +-41 +-40 +-39 +-36 +-34 +-33 +-32 +-31 +-30 +-29 +-27 +-25 +-23 +-22 +-20 +-18 +-17 +-17 +-15 +-14 +-13 +-3 +18 +32 +43 +49 +53 +56 +57 +57 +56 +54 +53 +51 +50 +48 +45 +37 +16 +1 +-11 +-19 +-26 +-31 +-34 +-36 +-37 +-38 +-38 +-38 +-37 +-36 +-34 +-23 +-2 +13 +25 +33 +38 +42 +44 +45 +47 +46 +45 +43 +42 +40 +38 +28 +8 +-7 +-19 +-28 +-34 +-38 +-41 +-43 +-44 +-44 +-43 +-42 +-40 +-39 +-37 +-27 +-6 +9 +20 +27 +32 +36 +38 +39 +39 +39 +38 +38 +37 +36 +35 +33 +32 +31 +29 +28 +26 +25 +23 +21 +20 +19 +18 +17 +16 +15 +14 +7 +-12 +-26 +-36 +-43 +-49 +-52 +-53 +-54 +-54 +-52 +-52 +-51 +-49 +-47 +-45 +-34 +-12 +4 +15 +24 +30 +34 +37 +38 +40 +40 +41 +39 +38 +36 +36 +27 +8 +-8 +-21 +-29 +-35 +-39 +-41 +-42 +-43 +-43 +-41 +-40 +-39 +-38 +-36 +-34 +-32 +-31 +-30 +-29 +-27 +-26 +-25 +-22 +-21 +-19 +-18 +-16 +-15 +-15 +-14 +-4 +16 +31 +41 +48 +53 +55 +56 +57 +56 +54 +52 +50 +48 +47 +45 +43 +41 +38 +36 +34 +32 +31 +29 +27 +25 +23 +22 +20 +18 +17 +17 +9 +-11 +-25 +-37 +-44 +-49 +-52 +-54 +-55 +-54 +-53 +-51 +-50 +-48 +-46 +-44 +-34 +-12 +4 +15 +23 +29 +33 +36 +37 +39 +39 +38 +37 +36 +35 +34 +26 +6 +-8 +-20 +-29 +-35 +-40 +-43 +-44 +-45 +-45 +-45 +-44 +-42 +-41 +-38 +-28 +-6 +9 +22 +30 +35 +38 +40 +41 +42 +41 +41 +39 +38 +36 +36 +27 +8 +-7 +-18 +-27 +-32 +-37 +-40 +-41 +-42 +-41 +-41 +-40 +-39 +-38 +-36 +-26 +-5 +10 +21 +29 +35 +39 +42 +42 +43 +43 +43 +42 +41 +40 +39 +30 +11 +-4 +-15 +-25 +-31 +-35 +-38 +-39 +-39 +-39 +-39 +-38 +-37 +-36 +-34 +-23 +-1 +14 +25 +33 +38 +41 +44 +44 +44 +43 +43 +41 +40 +39 +37 +29 +10 +-6 +-17 +-26 +-32 +-37 +-40 +-42 +-43 +-43 +-43 +-42 +-40 +-38 +-37 +-27 +-6 +9 +20 +28 +34 +37 +40 +41 +42 +42 +41 +40 +39 +37 +35 +27 +7 +-9 +-20 +-28 +-34 +-39 +-41 +-43 +-43 +-43 +-41 +-40 +-39 +-37 +-36 +-25 +-4 +11 +22 +29 +35 +38 +40 +41 +42 +42 +42 +41 +40 +38 +37 +29 +9 +-7 +-18 +-26 +-33 +-38 +-41 +-42 +-43 +-43 +-43 +-42 +-41 +-39 +-38 +-27 +-5 +11 +22 +30 +36 +39 +41 +43 +43 +42 +42 +41 +40 +38 +36 +28 +9 +-6 +-17 +-26 +-32 +-36 +-38 +-39 +-41 +-41 +-41 +-40 +-39 +-37 +-36 +-34 +-32 +-31 +-29 +-27 +-26 +-24 +-22 +-20 +-19 +-17 +-16 +-15 +-15 +-14 +-13 +-3 +17 +31 +41 +47 +53 +55 +57 +57 +58 +57 +55 +53 +51 +49 +48 +39 +18 +2 +-10 +-19 +-26 +-31 +-34 +-36 +-37 +-38 +-37 +-36 +-34 +-33 +-31 +-21 +0 +14 +25 +33 +38 +41 +42 +43 +44 +44 +43 +42 +41 +39 +38 +30 +10 +-4 +-16 +-25 +-31 +-36 +-38 +-40 +-42 +-42 +-42 +-42 +-41 +-38 +-36 +-26 +-4 +11 +21 +29 +34 +37 +40 +42 +42 +41 +41 +39 +38 +36 +35 +27 +8 +-8 +-19 +-28 +-34 +-38 +-41 +-42 +-42 +-41 +-40 +-38 +-37 +-36 +-35 +-24 +-3 +12 +23 +30 +36 +39 +42 +43 +44 +43 +43 +42 +40 +39 +38 +30 +10 +-6 +-18 +-26 +-32 +-36 +-40 +-41 +-42 +-42 +-42 +-41 +-40 +-38 +-36 +-25 +-3 +12 +23 +32 +37 +40 +42 +43 +43 +43 +42 +40 +39 +37 +36 +27 +7 +-7 +-19 +-27 +-32 +-37 +-39 +-41 +-41 +-41 +-40 +-39 +-39 +-38 +-37 +-27 +-6 +9 +21 +28 +34 +37 +40 +41 +43 +42 +42 +41 +41 +39 +38 +29 +9 +-6 +-18 +-27 +-33 +-37 +-40 +-42 +-43 +-43 +-43 +-42 +-40 +-39 +-37 +-25 +-4 +11 +22 +30 +36 +39 +41 +42 +42 +42 +40 +39 +37 +36 +35 +27 +8 +-7 +-19 +-27 +-33 +-36 +-39 +-41 +-41 +-41 +-41 +-41 +-40 +-39 +-37 +-26 +-5 +9 +20 +28 +34 +37 +40 +41 +43 +42 +42 +41 +40 +38 +37 +28 +8 +-7 +-19 +-28 +-34 +-39 +-41 +-42 +-43 +-43 +-43 +-42 +-41 +-39 +-37 +-26 +-4 +10 +22 +30 +35 +38 +41 +41 +42 +42 +42 +40 +39 +38 +38 +36 +34 +33 +32 +29 +28 +26 +24 +23 +21 +20 +18 +17 +16 +16 +15 +7 +-11 +-25 +-36 +-43 +-48 +-51 +-53 +-53 +-52 +-51 +-50 +-48 +-47 +-44 +-43 +-33 +-11 +5 +16 +24 +29 +33 +36 +37 +38 +38 +38 +37 +36 +36 +35 +27 +8 +-7 +-19 +-28 +-34 +-38 +-41 +-43 +-44 +-44 +-43 +-42 +-41 +-39 +-38 +-27 +-6 +10 +21 +29 +35 +38 +40 +42 +42 +41 +41 +39 +38 +36 +34 +26 +7 +-9 +-20 +-28 +-34 +-39 +-41 +-43 +-43 +-43 +-42 +-40 +-40 +-39 +-37 +-27 +-6 +9 +20 +28 +34 +37 +40 +41 +42 +41 +41 +40 +39 +37 +36 +28 +8 +-8 +-20 +-29 +-35 +-39 +-42 +-44 +-44 +-43 +-42 +-41 +-40 +-39 +-37 +-27 +-5 +10 +21 +29 +34 +37 +40 +41 +42 +40 +40 +38 +37 +36 +35 +26 +7 +-8 +-20 +-28 +-34 +-39 +-42 +-44 +-45 +-45 +-44 +-43 +-42 +-40 +-39 +-27 +-5 +9 +21 +29 +34 +38 +41 +42 +42 +42 +42 +40 +39 +38 +36 +27 +7 +-8 +-19 +-28 +-33 +-37 +-40 +-41 +-42 +-41 +-41 +-39 +-38 +-36 +-35 +-25 +-3 +12 +23 +31 +37 +40 +42 +44 +44 +45 +45 +44 +42 +41 +40 +32 +13 +-2 +-14 +-23 +-29 +-34 +-36 +-38 +-39 +-39 +-39 +-38 +-36 +-35 +-33 +-22 +-1 +14 +25 +33 +39 +42 +44 +45 +45 +44 +43 +41 +39 +37 +35 +27 +7 +-8 +-20 +-29 +-34 +-39 +-42 +-43 +-43 +-44 +-42 +-41 +-40 +-40 +-38 +-37 +-35 +-34 +-32 +-30 +-28 +-27 +-25 +-24 +-22 +-20 +-19 +-17 +-15 +-14 +-13 +-3 +17 +31 +41 +48 +52 +54 +56 +56 +56 +55 +54 +52 +50 +48 +46 +44 +42 +40 +38 +35 +33 +31 +29 +26 +25 +23 +22 +21 +20 +19 +18 +10 +-9 +-23 +-34 +-41 +-47 +-50 +-52 +-53 +-53 +-52 +-51 +-50 +-47 +-46 +-43 +-41 +-39 +-37 +-35 +-32 +-30 +-28 +-25 +-24 +-22 +-21 +-19 +-18 +-17 +-16 +-16 +-6 +14 +28 +39 +46 +50 +53 +55 +55 +55 +54 +53 +51 +49 +47 +45 +43 +40 +37 +35 +33 +31 +30 +28 +26 +25 +24 +22 +20 +19 +18 +18 +10 +-9 +-24 +-34 +-42 +-48 +-52 +-54 +-55 +-54 +-53 +-51 +-50 +-48 +-47 +-44 +-42 +-39 +-36 +-33 +-31 +-29 +-27 +-25 +-24 +-23 +-22 +-21 +-19 +-18 +-16 +-15 +-5 +15 +30 +40 +47 +52 +55 +57 +57 +56 +55 +53 +51 +49 +47 +44 +42 +40 +38 +36 +34 +32 +30 +29 +27 +27 +24 +23 +21 +19 +18 +17 +9 +-11 +-25 +-36 +-44 +-49 +-53 +-55 +-56 +-55 +-54 +-53 +-51 +-49 +-47 +-45 +-43 +-41 +-39 +-37 +-35 +-33 +-31 +-30 +-28 +-26 +-25 +-23 +-22 +-20 +-18 +-16 +-6 +16 +30 +40 +47 +52 +54 +55 +55 +55 +54 +52 +50 +48 +46 +45 +43 +41 +39 +37 +35 +34 +32 +30 +28 +27 +25 +23 +22 +20 +19 +17 +10 +-9 +-24 +-35 +-42 +-47 +-49 +-51 +-52 +-52 +-51 +-50 +-48 +-47 +-45 +-44 +-41 +-39 +-37 +-35 +-32 +-30 +-29 +-27 +-25 +-24 +-22 +-21 +-19 +-17 +-16 +-15 +-5 +15 +29 +39 +46 +51 +54 +56 +56 +55 +53 +52 +50 +48 +46 +44 +42 +40 +38 +36 +34 +31 +29 +27 +25 +23 +22 +21 +19 +18 +17 +16 +8 +-11 +-25 +-35 +-43 +-48 +-52 +-55 +-56 +-56 +-55 +-54 +-53 +-51 +-49 +-46 +-44 +-42 +-40 +-37 +-34 +-32 +-30 +-28 +-27 +-25 +-24 +-22 +-21 +-20 +-18 +-17 +-7 +14 +29 +39 +46 +51 +54 +56 +56 +56 +55 +54 +53 +51 +49 +46 +37 +16 +1 +-12 +-20 +-27 +-32 +-35 +-35 +-36 +-37 +-36 +-35 +-34 +-33 +-32 +-21 +0 +15 +25 +33 +38 +41 +43 +45 +45 +45 +43 +43 +41 +40 +39 +31 +11 +-4 +-16 +-25 +-31 +-36 +-39 +-41 +-42 +-42 +-41 +-40 +-39 +-38 +-36 +-26 +-3 +12 +23 +31 +37 +41 +43 +44 +44 +44 +42 +41 +40 +38 +36 +28 +8 +-7 +-18 +-26 +-32 +-37 +-40 +-41 +-42 +-42 +-41 +-40 +-40 +-38 +-36 +-25 +-4 +11 +22 +30 +35 +39 +41 +43 +43 +43 +42 +42 +40 +39 +37 +29 +9 +-6 +-18 +-27 +-34 +-38 +-41 +-43 +-43 +-43 +-43 +-41 +-39 +-38 +-36 +-25 +-4 +11 +22 +29 +34 +38 +40 +42 +42 +42 +42 +41 +39 +38 +36 +28 +8 +-7 +-18 +-27 +-33 +-38 +-41 +-43 +-44 +-45 +-44 +-43 +-41 +-40 +-38 +-27 +-6 +9 +21 +29 +35 +39 +42 +43 +43 +42 +41 +39 +38 +36 +35 +27 +7 +-8 +-19 +-28 +-33 +-37 +-39 +-41 +-41 +-41 +-40 +-39 +-38 +-37 +-35 +-25 +-3 +12 +23 +30 +36 +41 +44 +44 +45 +45 +44 +43 +42 +40 +39 +30 +10 +-6 +-18 +-27 +-32 +-37 +-39 +-41 +-41 +-42 +-41 +-39 +-38 +-37 +-35 +-25 +-3 +12 +22 +30 +35 +38 +40 +42 +42 +42 +41 +41 +39 +38 +37 +29 +9 +-6 +-17 +-26 +-32 +-36 +-40 +-42 +-43 +-43 +-43 +-42 +-40 +-39 +-37 +-27 +-5 +10 +22 +30 +35 +39 +42 +43 +43 +43 +42 +41 +39 +38 +36 +34 +34 +32 +31 +29 +27 +26 +25 +24 +23 +22 +20 +19 +17 +16 +15 +7 +-12 +-26 +-36 +-44 +-49 +-52 +-54 +-55 +-55 +-55 +-53 +-51 +-49 +-47 +-45 +-33 +-12 +4 +15 +24 +30 +34 +36 +37 +38 +38 +38 +37 +37 +35 +34 +26 +6 +-8 +-20 +-30 +-36 +-41 +-44 +-45 +-46 +-45 +-45 +-44 +-42 +-40 +-38 +-28 +-6 +9 +21 +29 +34 +37 +39 +40 +40 +40 +39 +38 +37 +35 +34 +25 +6 +-9 +-20 +-28 +-34 +-38 +-41 +-41 +-43 +-44 +-43 +-43 +-42 +-40 +-39 +-29 +-7 +8 +19 +28 +34 +37 +40 +41 +42 +42 +41 +40 +40 +38 +36 +28 +7 +-8 +-19 +-28 +-34 +-39 +-41 +-42 +-42 +-42 +-41 +-40 +-38 +-36 +-34 +-23 +-2 +14 +24 +32 +37 +40 +42 +44 +44 +44 +43 +43 +41 +40 +38 +30 +10 +-4 +-16 +-25 +-30 +-35 +-38 +-40 +-41 +-41 +-40 +-39 +-38 +-37 +-35 +-25 +-4 +11 +23 +31 +36 +39 +42 +44 +44 +43 +41 +39 +38 +36 +35 +26 +7 +-8 +-19 +-28 +-32 +-37 +-39 +-41 +-42 +-41 +-40 +-39 +-38 +-37 +-36 +-25 +-4 +11 +22 +30 +36 +39 +42 +43 +44 +44 +44 +43 +42 +40 +39 +30 +10 +-6 +-17 +-26 +-32 +-36 +-39 +-41 +-42 +-42 +-40 +-39 +-39 +-37 +-35 +-24 +-2 +13 +24 +32 +37 +40 +43 +43 +44 +44 +44 +42 +41 +39 +38 +30 +11 +-4 +-15 +-25 +-31 +-35 +-38 +-40 +-41 +-40 +-41 +-40 +-39 +-36 +-35 +-25 +-4 +11 +22 +31 +36 +40 +42 +43 +44 +43 +42 +41 +39 +37 +36 +27 +7 +-8 +-20 +-28 +-34 +-38 +-41 +-42 +-43 +-43 +-43 +-42 +-40 +-38 +-36 +-35 +-33 +-31 +-29 +-28 +-27 +-25 +-23 +-22 +-20 +-19 +-17 +-16 +-15 +-14 +-12 +-3 +19 +33 +43 +49 +53 +55 +57 +58 +56 +55 +53 +51 +49 +47 +45 +42 +40 +39 +37 +35 +33 +31 +29 +27 +25 +23 +22 +21 +19 +18 +17 +9 +-10 +-25 +-35 +-43 +-48 +-51 +-53 +-54 +-53 +-52 +-51 +-49 +-47 +-46 +-44 +-34 +-12 +4 +16 +25 +30 +34 +36 +38 +38 +38 +37 +37 +36 +34 +33 +24 +4 +-11 +-22 +-31 +-36 +-42 +-44 +-46 +-46 +-45 +-44 +-44 +-42 +-40 +-37 +-27 +-5 +10 +21 +29 +35 +38 +40 +41 +41 +40 +40 +39 +38 +37 +35 +27 +8 +-7 +-18 +-27 +-33 +-38 +-40 +-43 +-44 +-44 +-44 +-43 +-42 +-39 +-38 +-36 +-34 +-33 +-31 +-29 +-27 +-25 +-23 +-22 +-21 +-19 +-18 +-18 +-17 +-16 +-15 +-6 +15 +29 +39 +46 +51 +54 +56 +57 +56 +55 +53 +51 +49 +47 +45 +43 +40 +38 +36 +34 +32 +31 +29 +28 +26 +25 +24 +23 +22 +21 +20 +12 +-7 +-22 +-33 +-41 +-47 +-50 +-52 +-53 +-53 +-52 +-51 +-49 +-47 +-45 +-43 +-31 +-9 +7 +18 +27 +32 +35 +37 +38 +40 +40 +39 +38 +36 +35 +32 +24 +4 +-10 +-21 +-30 +-35 +-39 +-42 +-43 +-44 +-44 +-43 +-42 +-41 +-39 +-38 +-36 +-34 +-32 +-29 +-28 +-26 +-24 +-22 +-21 +-19 +-18 +-17 +-15 +-14 +-14 +-14 +-4 +16 +30 +41 +48 +52 +54 +56 +56 +56 +55 +54 +52 +51 +49 +46 +37 +17 +0 +-12 +-21 +-28 +-33 +-36 +-38 +-39 +-39 +-39 +-38 +-37 +-36 +-34 +-24 +-3 +13 +24 +32 +37 +40 +42 +43 +43 +43 +42 +41 +40 +38 +37 +34 +33 +31 +30 +29 +27 +26 +24 +22 +21 +19 +18 +17 +16 +14 +14 +6 +-13 +-27 +-36 +-43 +-48 +-52 +-54 +-55 +-55 +-53 +-53 +-51 +-49 +-47 +-45 +-43 +-41 +-38 +-37 +-35 +-32 +-30 +-28 +-27 +-25 +-23 +-21 +-19 +-17 +-16 +-15 +-5 +15 +29 +40 +47 +51 +53 +55 +55 +55 +54 +53 +52 +50 +47 +45 +43 +41 +39 +37 +35 +33 +30 +28 +27 +25 +24 +23 +21 +20 +19 +17 +10 +-9 +-23 +-33 +-41 +-46 +-50 +-51 +-52 +-52 +-51 +-51 +-50 +-48 +-46 +-43 +-33 +-11 +5 +17 +26 +32 +35 +38 +39 +40 +40 +39 +39 +37 +36 +34 +25 +6 +-9 +-21 +-30 +-36 +-40 +-43 +-45 +-45 +-45 +-44 +-42 +-41 +-39 +-37 +-35 +-33 +-32 +-30 +-29 +-27 +-25 +-23 +-21 +-20 +-19 +-17 +-16 +-15 +-14 +-13 +-4 +17 +32 +42 +49 +53 +56 +57 +57 +56 +54 +52 +50 +48 +46 +44 +42 +40 +38 +36 +34 +33 +31 +29 +28 +26 +24 +22 +20 +19 +18 +16 +8 +-11 +-26 +-36 +-43 +-49 +-52 +-54 +-55 +-55 +-54 +-52 +-50 +-48 +-46 +-44 +-33 +-11 +5 +16 +24 +30 +34 +37 +38 +39 +39 +39 +39 +38 +36 +35 +26 +7 +-8 +-19 +-28 +-34 +-39 +-42 +-43 +-44 +-44 +-43 +-42 +-40 +-38 +-36 +-34 +-32 +-31 +-29 +-27 +-25 +-24 +-23 +-22 +-21 +-20 +-19 +-17 +-16 +-15 +-13 +-3 +17 +32 +43 +50 +55 +58 +59 +58 +58 +56 +55 +52 +51 +49 +46 +43 +41 +39 +37 +36 +35 +32 +30 +28 +27 +26 +25 +24 +22 +20 +19 +10 +-8 +-24 +-34 +-42 +-47 +-51 +-52 +-53 +-53 +-52 +-50 +-48 +-47 +-45 +-44 +-42 +-39 +-36 +-35 +-34 +-31 +-30 +-28 +-27 +-25 +-23 +-21 +-20 +-18 +-16 +-15 +-6 +15 +29 +38 +44 +48 +51 +52 +52 +52 +51 +50 +49 +47 +45 +43 +34 +14 +-1 +-12 +-21 +-28 +-32 +-36 +-38 +-39 +-39 +-39 +-38 +-37 +-36 +-34 +-24 +-2 +13 +24 +32 +37 +41 +44 +45 +45 +45 +43 +42 +40 +39 +37 +28 +8 +-7 +-19 +-28 +-34 +-37 +-40 +-41 +-42 +-42 +-41 +-40 +-39 +-38 +-37 +-27 +-5 +10 +20 +28 +34 +38 +40 +42 +43 +43 +42 +41 +40 +39 +37 +29 +9 +-6 +-18 +-26 +-32 +-37 +-40 +-41 +-42 +-41 +-41 +-39 +-38 +-36 +-34 +-23 +-2 +14 +25 +33 +38 +41 +43 +43 +44 +44 +43 +42 +41 +38 +37 +28 +9 +-6 +-17 +-26 +-32 +-36 +-39 +-41 +-42 +-43 +-42 +-41 +-40 +-39 +-37 +-27 +-6 +9 +20 +28 +34 +37 +40 +41 +42 +41 +41 +40 +38 +36 +35 +28 +8 +-7 +-18 +-26 +-32 +-36 +-38 +-40 +-41 +-41 +-40 +-39 +-38 +-37 +-35 +-25 +-4 +10 +21 +29 +35 +38 +41 +42 +43 +42 +42 +41 +40 +38 +36 +27 +7 +-8 +-20 +-29 +-34 +-38 +-41 +-42 +-43 +-42 +-41 +-40 +-39 +-36 +-35 +-25 +-3 +12 +23 +31 +36 +39 +42 +43 +44 +43 +43 +42 +40 +39 +37 +29 +9 +-5 +-17 +-26 +-32 +-37 +-40 +-42 +-42 +-43 +-42 +-41 +-40 +-39 +-36 +-25 +-4 +10 +21 +29 +35 +38 +41 +41 +41 +41 +40 +39 +38 +36 +36 +27 +7 +-7 +-19 +-27 +-33 +-36 +-39 +-41 +-42 +-42 +-42 +-41 +-40 +-38 +-36 +-25 +-4 +11 +24 +31 +37 +40 +43 +44 +45 +44 +43 +42 +40 +39 +37 +36 +34 +32 +31 +29 +28 +26 +25 +24 +22 +22 +20 +19 +18 +17 +16 +8 +-11 +-26 +-36 +-43 +-48 +-50 +-52 +-53 +-53 +-52 +-51 +-49 +-47 +-45 +-43 +-33 +-11 +3 +15 +23 +29 +33 +35 +37 +38 +38 +37 +37 +36 +34 +34 +25 +5 +-11 +-22 +-30 +-36 +-40 +-43 +-45 +-46 +-45 +-44 +-43 +-41 +-39 +-37 +-27 +-5 +10 +21 +29 +35 +38 +40 +41 +41 +41 +41 +40 +39 +37 +36 +27 +7 +-7 +-18 +-26 +-33 +-37 +-40 +-42 +-43 +-43 +-42 +-42 +-40 +-38 +-37 +-26 +-5 +10 +21 +29 +35 +38 +41 +42 +43 +42 +41 +40 +39 +36 +35 +27 +7 +-8 +-19 +-27 +-33 +-38 +-40 +-42 +-42 +-42 +-41 +-40 +-39 +-38 +-37 +-26 +-5 +10 +22 +29 +35 +39 +41 +42 +43 +44 +43 +42 +41 +40 +39 +31 +10 +-5 +-17 +-26 +-32 +-37 +-40 +-42 +-42 +-42 +-41 +-39 +-38 +-36 +-35 +-23 +-2 +13 +24 +31 +36 +39 +42 +43 +43 +43 +42 +40 +39 +37 +36 +29 +9 +-6 +-18 +-27 +-33 +-37 +-40 +-42 +-43 +-43 +-42 +-41 +-39 +-38 +-37 +-26 +-4 +11 +22 +31 +36 +40 +43 +44 +44 +43 +43 +41 +40 +38 +36 +28 +9 +-7 +-18 +-27 +-32 +-36 +-39 +-41 +-41 +-41 +-41 +-40 +-40 +-38 +-36 +-26 +-4 +11 +22 +30 +35 +39 +42 +44 +45 +44 +43 +42 +41 +39 +38 +29 +9 +-6 +-19 +-27 +-34 +-38 +-41 +-43 +-44 +-43 +-43 +-42 +-41 +-39 +-37 +-26 +-5 +10 +21 +28 +34 +37 +38 +38 +39 +39 +39 +38 +37 +35 +34 +26 +6 +-9 +-20 +-28 +-34 +-39 +-42 +-43 +-45 +-44 +-44 +-42 +-42 +-39 +-38 +-36 +-33 +-32 +-30 +-28 +-26 +-24 +-22 +-21 +-19 +-19 +-18 +-17 +-16 +-15 +-13 +-3 +18 +32 +42 +49 +54 +57 +59 +59 +59 +58 +57 +54 +52 +49 +47 +38 +18 +3 +-9 +-19 +-25 +-29 +-33 +-35 +-36 +-35 +-35 +-35 +-34 +-33 +-32 +-21 +0 +14 +24 +32 +37 +41 +43 +45 +46 +46 +45 +44 +43 +41 +40 +31 +11 +-4 +-16 +-25 +-32 +-36 +-39 +-42 +-42 +-41 +-41 +-40 +-39 +-37 +-36 +-25 +-3 +11 +22 +30 +35 +38 +40 +40 +41 +40 +40 +39 +38 +36 +35 +27 +8 +-7 +-19 +-27 +-33 +-38 +-40 +-42 +-43 +-44 +-43 +-42 +-40 +-39 +-38 +-27 +-5 +10 +22 +30 +36 +39 +42 +43 +44 +43 +43 +42 +41 +40 +38 +29 +9 +-5 +-17 +-26 +-32 +-37 +-40 +-42 +-43 +-42 +-40 +-40 +-38 +-36 +-35 +-25 +-3 +11 +22 +30 +35 +38 +41 +41 +42 +41 +41 +40 +39 +37 +36 +28 +9 +-6 +-17 +-27 +-34 +-39 +-41 +-43 +-44 +-45 +-44 +-42 +-41 +-39 +-38 +-27 +-5 +10 +21 +30 +35 +39 +42 +42 +42 +41 +41 +39 +39 +37 +36 +28 +8 +-6 +-18 +-27 +-33 +-36 +-40 +-41 +-42 +-42 +-42 +-41 +-39 +-38 +-36 +-25 +-4 +11 +22 +30 +36 +40 +42 +43 +44 +44 +43 +42 +40 +38 +37 +28 +8 +-7 +-18 +-28 +-33 +-37 +-40 +-43 +-43 +-43 +-42 +-41 +-39 +-38 +-36 +-25 +-4 +11 +22 +30 +36 +39 +41 +43 +43 +43 +42 +41 +41 +39 +38 +30 +10 +-5 +-17 +-26 +-32 +-37 +-40 +-42 +-42 +-42 +-42 +-41 +-39 +-38 +-36 +-25 +-3 +12 +23 +31 +36 +39 +42 +42 +42 +42 +42 +41 +41 +39 +37 +35 +34 +32 +31 +29 +28 +26 +24 +22 +21 +19 +18 +16 +15 +14 +13 +6 +-13 +-27 +-38 +-46 +-51 +-54 +-56 +-57 +-57 +-56 +-54 +-53 +-51 +-49 +-47 +-35 +-13 +2 +14 +22 +29 +32 +36 +37 +39 +38 +39 +37 +37 +35 +34 +26 +6 +-9 +-20 +-29 +-35 +-39 +-41 +-43 +-43 +-43 +-41 +-40 +-39 +-38 +-36 +-26 +-5 +10 +21 +29 +34 +37 +40 +42 +43 +43 +42 +41 +40 +39 +37 +29 +9 +-6 +-18 +-27 +-33 +-38 +-41 +-43 +-44 +-44 +-43 +-42 +-41 +-39 +-37 +-26 +-4 +10 +21 +30 +35 +38 +41 +42 +42 +41 +40 +38 +37 +36 +35 +27 +8 +-7 +-19 +-28 +-33 +-38 +-40 +-42 +-43 +-43 +-43 +-42 +-40 +-39 +-37 +-27 +-5 +10 +21 +30 +35 +39 +41 +43 +43 +42 +42 +40 +39 +38 +36 +27 +8 +-7 +-18 +-27 +-33 +-37 +-40 +-41 +-42 +-41 +-40 +-39 +-37 +-36 +-35 +-24 +-3 +12 +23 +32 +37 +40 +43 +44 +44 +44 +44 +43 +42 +40 +39 +30 +11 +-5 +-16 +-26 +-32 +-37 +-40 +-42 +-42 +-42 +-42 +-40 +-38 +-37 +-35 +-24 +-2 +12 +24 +31 +36 +39 +42 +43 +43 +42 +42 +40 +39 +38 +36 +29 +9 +-6 +-18 +-27 +-33 +-37 +-40 +-42 +-43 +-44 +-43 +-44 +-42 +-41 +-38 +-28 +-7 +8 +19 +27 +33 +36 +39 +40 +41 +41 +41 +39 +38 +36 +35 +26 +6 +-9 +-21 +-29 +-35 +-38 +-41 +-42 +-43 +-42 +-41 +-40 +-39 +-37 +-36 +-26 +-4 +10 +21 +29 +34 +37 +40 +41 +42 +41 +41 +40 +39 +39 +38 +29 +9 +-6 +-18 +-27 +-32 +-37 +-41 +-42 +-43 +-42 +-42 +-41 +-39 +-37 +-34 +-24 +-2 +14 +26 +33 +39 +43 +45 +45 +46 +45 +44 +43 +42 +40 +39 +31 +11 +-4 +-15 +-24 +-30 +-34 +-37 +-39 +-40 +-40 +-40 +-39 +-38 +-37 +-36 +-25 +-3 +12 +23 +31 +37 +40 +43 +44 +44 +44 +43 +42 +42 +40 +38 +29 +8 +-8 +-20 +-29 +-35 +-39 +-42 +-44 +-44 +-44 +-44 +-43 +-42 +-40 +-38 +-36 +-34 +-32 +-30 +-28 +-27 +-26 +-25 +-23 +-21 +-20 +-19 +-17 +-16 +-15 +-14 +-4 +17 +31 +42 +49 +53 +55 +56 +56 +56 +54 +52 +51 +49 +47 +45 +36 +16 +0 +-12 +-20 +-27 +-31 +-34 +-36 +-37 +-37 +-38 +-37 +-36 +-35 +-33 +-23 +-2 +14 +24 +32 +37 +41 +43 +44 +44 +44 +43 +43 +40 +38 +37 +35 +33 +32 +30 +28 +27 +26 +24 +23 +22 +20 +19 +19 +17 +15 +15 +6 +-13 +-27 +-37 +-44 +-49 +-53 +-54 +-55 +-54 +-53 +-52 +-50 +-47 +-46 +-43 +-33 +-11 +4 +16 +24 +29 +33 +36 +37 +37 +38 +38 +37 +36 +34 +33 +25 +6 +-10 +-21 +-29 +-36 +-40 +-43 +-44 +-44 +-44 +-43 +-41 +-40 +-38 +-35 +-25 +-3 +13 +24 +32 +37 +40 +42 +43 +43 +43 +42 +40 +39 +38 +36 +28 +9 +-6 +-17 +-26 +-32 +-36 +-39 +-41 +-42 +-43 +-42 +-41 +-40 +-39 +-37 +-36 +-34 +-33 +-31 +-29 +-27 +-25 +-23 +-23 +-21 +-20 +-19 +-18 +-18 +-17 +-16 +-6 +14 +29 +39 +46 +51 +53 +55 +55 +55 +54 +52 +50 +48 +46 +43 +40 +38 +36 +35 +33 +30 +28 +27 +26 +24 +22 +21 +20 +19 +18 +17 +9 +-11 +-25 +-36 +-42 +-48 +-51 +-53 +-53 +-53 +-51 +-49 +-47 +-46 +-44 +-42 +-30 +-9 +7 +18 +26 +32 +35 +38 +39 +40 +40 +40 +38 +37 +36 +35 +27 +8 +-8 +-20 +-29 +-35 +-40 +-43 +-45 +-45 +-45 +-44 +-43 +-41 +-39 +-37 +-36 +-34 +-32 +-30 +-28 +-27 +-25 +-24 +-23 +-21 +-20 +-18 +-17 +-16 +-15 +-13 +-3 +18 +32 +43 +49 +54 +56 +57 +57 +57 +56 +55 +53 +51 +49 +47 +44 +43 +41 +39 +37 +35 +33 +32 +30 +28 +25 +24 +22 +21 +19 +18 +10 +-8 +-23 +-34 +-42 +-47 +-50 +-52 +-53 +-53 +-53 +-52 +-51 +-49 +-48 +-46 +-35 +-13 +2 +14 +23 +29 +32 +36 +38 +39 +38 +37 +36 +35 +33 +32 +23 +4 +-12 +-23 +-31 +-37 +-41 +-44 +-45 +-45 +-44 +-43 +-42 +-40 +-39 +-37 +-27 +-6 +9 +20 +28 +34 +38 +41 +42 +43 +43 +42 +41 +40 +39 +37 +29 +8 +-7 +-19 +-28 +-34 +-38 +-41 +-42 +-43 +-43 +-42 +-41 +-39 +-37 +-36 +-25 +-3 +12 +23 +31 +36 +39 +41 +42 +43 +43 +42 +41 +39 +38 +37 +29 +9 +-6 +-17 +-26 +-33 +-36 +-39 +-41 +-42 +-41 +-41 +-40 +-39 +-38 +-36 +-35 +-32 +-30 +-29 +-27 +-26 +-25 +-24 +-22 +-20 +-19 +-18 +-17 +-16 +-15 +-13 +-3 +18 +32 +42 +49 +53 +56 +58 +57 +57 +55 +53 +51 +49 +47 +45 +37 +17 +1 +-11 +-20 +-26 +-31 +-34 +-36 +-38 +-38 +-37 +-37 +-36 +-35 +-34 +-22 +-1 +15 +26 +33 +38 +42 +44 +45 +46 +46 +45 +44 +42 +40 +39 +30 +10 +-6 +-17 +-25 +-31 +-36 +-39 +-40 +-41 +-41 +-40 +-38 +-37 +-35 +-34 +-24 +-3 +12 +23 +31 +36 +39 +42 +44 +44 +43 +43 +42 +40 +39 +37 +36 +35 +32 +31 +29 +28 +26 +24 +23 +22 +20 +19 +18 +17 +16 +15 +8 +-10 +-25 +-35 +-43 +-49 +-52 +-54 +-55 +-56 +-55 +-54 +-52 +-50 +-47 +-45 +-34 +-12 +4 +15 +24 +29 +33 +35 +36 +37 +36 +35 +35 +34 +32 +31 +23 +3 +-12 +-23 +-31 +-37 +-40 +-43 +-45 +-45 +-45 +-45 +-44 +-43 +-42 +-40 +-38 +-36 +-34 +-31 +-30 +-28 +-25 +-23 +-22 +-20 +-18 +-17 +-16 +-15 +-15 +-14 +-3 +18 +31 +42 +49 +53 +56 +58 +59 +58 +57 +56 +54 +52 +50 +47 +45 +42 +39 +37 +35 +32 +31 +29 +28 +26 +24 +23 +21 +21 +19 +18 +10 +-9 +-24 +-35 +-43 +-48 +-52 +-54 +-55 +-54 +-53 +-52 +-50 +-48 +-45 +-43 +-32 +-10 +5 +17 +25 +30 +34 +36 +38 +39 +39 +38 +38 +37 +36 +35 +26 +7 +-8 +-19 +-27 +-33 +-38 +-41 +-43 +-43 +-43 +-42 +-41 +-39 +-38 +-36 +-25 +-3 +12 +23 +31 +36 +40 +41 +42 +43 +42 +41 +40 +38 +36 +35 +26 +7 +-8 +-19 +-28 +-33 +-37 +-40 +-42 +-42 +-42 +-42 +-41 +-40 +-38 +-37 +-26 +-4 +11 +22 +30 +35 +39 +42 +43 +44 +43 +42 +40 +39 +37 +35 +26 +7 +-8 +-20 +-29 +-35 +-39 +-42 +-43 +-43 +-43 +-42 +-41 +-40 +-39 +-37 +-27 +-6 +9 +20 +28 +33 +37 +40 +41 +42 +42 +42 +41 +40 +38 +37 +28 +8 +-6 +-18 +-27 +-33 +-36 +-39 +-41 +-42 +-41 +-41 +-39 +-38 +-36 +-34 +-23 +-2 +14 +25 +32 +37 +41 +43 +44 +45 +45 +44 +43 +41 +40 +38 +30 +10 +-4 +-16 +-24 +-30 +-35 +-38 +-40 +-41 +-41 +-41 +-40 +-39 +-37 +-35 +-25 +-3 +12 +23 +31 +36 +39 +42 +44 +43 +42 +41 +40 +38 +37 +35 +27 +7 +-8 +-20 +-28 +-34 +-39 +-41 +-42 +-43 +-44 +-44 +-43 +-42 +-40 +-38 +-28 +-6 +9 +21 +29 +34 +38 +41 +42 +42 +42 +42 +41 +40 +39 +37 +29 +9 +-7 +-18 +-27 +-33 +-37 +-40 +-42 +-42 +-42 +-41 +-40 +-39 +-37 +-34 +-32 +-31 +-29 +-28 +-27 +-25 +-24 +-23 +-22 +-20 +-19 +-17 +-16 +-15 +-14 +-13 +-3 +18 +32 +42 +49 +53 +55 +56 +57 +56 +54 +53 +51 +49 +47 +45 +36 +16 +0 +-10 +-20 +-26 +-31 +-34 +-36 +-38 +-39 +-39 +-38 +-37 +-36 +-35 +-25 +-3 +12 +23 +31 +37 +41 +42 +42 +42 +42 +40 +39 +37 +36 +34 +26 +6 +-9 +-20 +-28 +-34 +-38 +-41 +-42 +-43 +-43 +-42 +-41 +-40 +-38 +-35 +-25 +-3 +11 +23 +31 +37 +40 +43 +44 +45 +45 +45 +43 +42 +41 +39 +31 +10 +-5 +-16 +-25 +-31 +-35 +-38 +-40 +-40 +-40 +-39 +-38 +-36 +-34 +-32 +-22 +-1 +13 +24 +31 +37 +40 +42 +43 +44 +43 +42 +41 +40 +38 +37 +29 +9 +-6 +-17 +-26 +-32 +-37 +-40 +-42 +-43 +-43 +-42 +-41 +-39 +-38 +-36 +-26 +-3 +12 +23 +31 +37 +40 +43 +43 +43 +43 +42 +40 +39 +38 +36 +28 +8 +-7 +-18 +-27 +-32 +-36 +-39 +-41 +-42 +-42 +-42 +-41 +-39 +-38 +-36 +-25 +-4 +12 +23 +31 +36 +39 +42 +43 +44 +43 +43 +41 +40 +38 +36 +28 +8 +-8 +-19 +-28 +-33 +-37 +-41 +-42 +-42 +-42 +-41 +-40 +-39 +-37 +-36 +-25 +-4 +11 +22 +30 +35 +39 +41 +42 +43 +43 +42 +41 +40 +39 +38 +29 +9 +-6 +-18 +-27 +-33 +-38 +-41 +-43 +-43 +-43 +-43 +-41 +-40 +-38 +-36 +-25 +-4 +11 +22 +30 +36 +39 +41 +42 +42 +42 +41 +40 +38 +37 +36 +28 +8 +-7 +-18 +-27 +-33 +-37 +-40 +-43 +-44 +-43 +-43 +-41 +-41 +-39 +-37 +-26 +-5 +10 +22 +30 +36 +39 +42 +43 +43 +42 +41 +39 +37 +36 +34 +33 +31 +29 +28 +26 +25 +24 +23 +21 +21 +19 +18 +17 +16 +14 +13 +6 +-13 +-28 +-37 +-45 +-50 +-54 +-55 +-56 +-56 +-55 +-53 +-51 +-49 +-47 +-46 +-35 +-13 +2 +14 +22 +28 +32 +35 +37 +38 +38 +38 +37 +37 +36 +34 +26 +6 +-9 +-20 +-29 +-35 +-38 +-41 +-43 +-43 +-43 +-42 +-41 +-39 +-38 +-36 +-25 +-3 +12 +22 +30 +36 +38 +40 +41 +42 +41 +40 +39 +38 +37 +35 +27 +7 +-8 +-20 +-28 +-34 +-39 +-42 +-43 +-45 +-45 +-44 +-44 +-42 +-41 +-38 +-28 +-6 +9 +20 +28 +34 +38 +41 +42 +43 +43 +42 +41 +40 +39 +37 +29 +9 +-6 +-17 +-26 +-31 +-35 +-39 +-40 +-41 +-41 +-40 +-38 +-36 +-35 +-34 +-24 +-3 +13 +23 +31 +36 +40 +42 +43 +44 +43 +43 +42 +41 +39 +37 +29 +10 +-5 +-17 +-26 +-32 +-37 +-41 +-42 +-43 +-43 +-43 +-41 +-40 +-39 +-37 +-26 +-4 +11 +22 +31 +36 +39 +42 +43 +43 +42 +42 +40 +38 +36 +36 +28 +8 +-7 +-18 +-27 +-34 +-38 +-40 +-42 +-43 +-44 +-43 +-43 +-41 +-40 +-38 +-28 +-6 +9 +21 +29 +35 +38 +42 +42 +43 +43 +43 +42 +41 +39 +38 +29 +9 +-6 +-18 +-26 +-33 +-37 +-40 +-41 +-42 +-42 +-41 +-40 +-39 +-37 +-36 +-25 +-3 +12 +24 +32 +38 +40 +42 +42 +42 +42 +41 +40 +39 +37 +36 +28 +8 +-7 +-18 +-26 +-32 +-36 +-40 +-42 +-43 +-43 +-43 +-42 +-42 +-40 +-39 +-37 +-35 +-33 +-31 +-30 +-28 +-26 +-24 +-23 +-21 +-20 +-18 +-17 +-16 +-15 +-14 +-5 +16 +30 +40 +47 +52 +54 +55 +56 +56 +55 +54 +52 +50 +48 +46 +45 +43 +40 +37 +35 +32 +30 +28 +27 +26 +24 +22 +21 +21 +19 +18 +10 +-8 +-22 +-33 +-41 +-46 +-50 +-52 +-53 +-53 +-53 +-51 +-50 +-47 +-45 +-43 +-41 +-39 +-37 +-34 +-32 +-29 +-28 +-26 +-24 +-23 +-22 +-21 +-19 +-18 +-17 +-16 +-6 +15 +30 +40 +47 +51 +54 +56 +56 +56 +54 +52 +50 +48 +46 +44 +42 +40 +38 +36 +34 +32 +31 +29 +28 +26 +25 +24 +23 +22 +20 +19 +11 +-9 +-23 +-33 +-41 +-46 +-50 +-52 +-53 +-53 +-52 +-50 +-49 +-46 +-44 +-42 +-40 +-37 +-36 +-35 +-33 +-30 +-29 +-27 +-26 +-23 +-22 +-21 +-20 +-18 +-17 +-15 +-5 +16 +29 +40 +46 +51 +53 +55 +55 +55 +53 +52 +50 +48 +46 +44 +42 +40 +38 +36 +35 +33 +31 +30 +28 +26 +25 +23 +22 +20 +19 +19 +11 +-8 +-22 +-33 +-40 +-46 +-50 +-52 +-53 +-53 +-52 +-50 +-49 +-48 +-47 +-44 +-42 +-40 +-38 +-36 +-34 +-32 +-30 +-28 +-26 +-24 +-23 +-21 +-19 +-18 +-16 +-15 +-6 +15 +29 +39 +46 +50 +53 +54 +54 +54 +53 +52 +50 +49 +47 +45 +42 +40 +37 +35 +32 +31 +29 +26 +24 +22 +20 +20 +18 +18 +16 +16 +9 +-10 +-24 +-35 +-43 +-48 +-52 +-54 +-55 +-54 +-54 +-52 +-50 +-48 +-46 +-44 +-41 +-39 +-36 +-34 +-31 +-29 +-28 +-26 +-25 +-23 +-22 +-20 +-18 +-17 +-16 +-14 +-5 +16 +30 +41 +49 +54 +57 +58 +58 +57 +56 +54 +51 +50 +47 +45 +43 +41 +39 +37 +34 +33 +31 +29 +27 +25 +24 +22 +21 +20 +18 +17 +9 +-10 +-25 +-35 +-43 +-48 +-52 +-54 +-54 +-54 +-53 +-52 +-51 +-49 +-47 +-45 +-44 +-41 +-39 +-37 +-36 +-33 +-32 +-29 +-27 +-25 +-24 +-23 +-21 +-19 +-18 +-18 +-8 +13 +27 +36 +43 +48 +50 +52 +52 +52 +52 +50 +48 +46 +44 +43 +34 +15 +-1 +-13 +-23 +-28 +-34 +-37 +-39 +-40 +-41 +-40 +-39 +-37 +-36 +-34 +-23 +-1 +14 +25 +33 +38 +42 +44 +45 +45 +45 +44 +43 +42 +40 +38 +30 +10 +-4 +-16 +-25 +-31 +-35 +-37 +-39 +-39 +-40 +-40 +-39 +-38 +-36 +-35 +-25 +-3 +12 +23 +32 +37 +41 +44 +45 +46 +46 +45 +44 +42 +40 +39 +30 +10 +-5 +-16 +-25 +-32 +-36 +-39 +-40 +-41 +-41 +-40 +-39 +-38 +-37 +-36 +-25 +-4 +11 +21 +29 +34 +37 +39 +41 +42 +41 +40 +39 +38 +37 +36 +28 +8 +-7 +-19 +-28 +-34 +-38 +-41 +-43 +-43 +-43 +-42 +-41 +-38 +-37 +-36 +-25 +-3 +12 +24 +32 +37 +40 +42 +43 +43 +43 +43 +41 +40 +38 +38 +29 +9 +-7 +-17 +-26 +-31 +-36 +-38 +-40 +-40 +-41 +-40 +-39 +-38 +-37 +-36 +-26 +-4 +11 +22 +30 +36 +39 +42 +43 +44 +44 +43 +42 +41 +39 +36 +28 +8 +-7 +-19 +-27 +-33 +-37 +-40 +-41 +-42 +-41 +-41 +-40 +-38 +-37 +-35 +-25 +-3 +12 +23 +30 +36 +38 +41 +42 +43 +42 +42 +41 +40 +38 +37 +28 +9 +-7 +-18 +-27 +-34 +-39 +-42 +-42 +-44 +-44 +-44 +-43 +-42 +-41 +-39 +-28 +-5 +9 +20 +29 +34 +38 +40 +42 +42 +41 +40 +39 +37 +35 +34 +26 +7 +-8 +-20 +-28 +-35 +-39 +-42 +-44 +-44 +-44 +-44 +-42 +-41 +-40 +-39 +-28 +-6 +9 +20 +28 +34 +37 +40 +41 +42 +42 +42 +41 +39 +38 +37 +35 +33 +30 +29 +27 +26 +25 +24 +22 +21 +20 +18 +17 +17 +16 +15 +8 +-10 +-25 +-35 +-43 +-48 +-52 +-54 +-55 +-55 +-54 +-53 +-51 +-49 +-47 +-45 +-33 +-11 +4 +17 +24 +30 +34 +37 +38 +39 +38 +37 +36 +36 +34 +32 +24 +6 +-9 +-20 +-29 +-35 +-39 +-41 +-43 +-43 +-42 +-42 +-41 +-40 +-39 +-38 +-27 +-5 +10 +21 +29 +35 +39 +41 +43 +43 +44 +43 +42 +40 +39 +37 +29 +8 +-6 +-19 +-27 +-34 +-38 +-41 +-42 +-43 +-43 +-42 +-41 +-40 +-38 +-36 +-26 +-4 +10 +21 +29 +34 +37 +40 +41 +41 +41 +41 +40 +39 +38 +36 +28 +8 +-7 +-18 +-28 +-34 +-38 +-41 +-43 +-44 +-44 +-43 +-42 +-40 +-39 +-36 +-26 +-4 +11 +23 +31 +37 +41 +43 +44 +44 +43 +43 +42 +41 +39 +38 +30 +10 +-5 +-16 +-24 +-30 +-34 +-37 +-39 +-39 +-40 +-40 +-39 +-38 +-36 +-35 +-25 +-3 +12 +24 +32 +37 +41 +43 +44 +45 +45 +44 +43 +41 +40 +38 +30 +9 +-6 +-18 +-27 +-33 +-37 +-40 +-42 +-42 +-43 +-42 +-41 +-39 +-38 +-36 +-25 +-4 +11 +21 +29 +34 +38 +39 +41 +40 +40 +40 +39 +37 +36 +35 +26 +7 +-8 +-19 +-28 +-34 +-39 +-42 +-44 +-45 +-45 +-44 +-43 +-41 +-39 +-38 +-28 +-6 +9 +21 +29 +35 +39 +42 +43 +44 +43 +42 +41 +39 +37 +36 +28 +7 +-7 +-19 +-27 +-34 +-37 +-40 +-41 +-42 +-42 +-42 +-40 +-40 +-38 +-37 +-27 +-5 +10 +21 +29 +35 +38 +41 +42 +43 +43 +42 +41 +40 +39 +38 +29 +9 +-6 +-17 +-26 +-32 +-37 +-39 +-41 +-41 +-42 +-40 +-39 +-38 +-37 +-35 +-33 +-31 +-30 +-28 +-27 +-25 +-24 +-22 +-21 +-20 +-18 +-17 +-16 +-14 +-14 +-13 +-4 +18 +32 +43 +49 +53 +55 +56 +55 +55 +54 +52 +49 +48 +46 +43 +40 +39 +37 +35 +32 +31 +29 +28 +26 +25 +23 +22 +20 +19 +17 +16 +8 +-11 +-25 +-35 +-42 +-48 +-51 +-53 +-53 +-52 +-52 +-50 +-49 +-47 +-45 +-42 +-32 +-10 +5 +17 +25 +31 +35 +38 +39 +40 +40 +40 +39 +38 +37 +36 +28 +8 +-8 +-19 +-28 +-35 +-38 +-41 +-42 +-43 +-43 +-42 +-41 +-39 +-37 +-35 +-25 +-3 +13 +23 +30 +36 +39 +41 +42 +42 +42 +41 +40 +39 +38 +37 +28 +8 +-6 +-18 +-27 +-33 +-37 +-40 +-42 +-43 +-44 +-43 +-42 +-41 +-40 +-38 +-37 +-35 +-33 +-31 +-30 +-28 +-26 +-24 +-23 +-22 +-21 +-19 +-18 +-17 +-16 +-15 +-5 +16 +30 +40 +47 +51 +55 +56 +57 +56 +55 +53 +51 +49 +46 +44 +42 +39 +37 +36 +33 +32 +30 +29 +27 +26 +24 +23 +22 +21 +20 +18 +11 +-8 +-22 +-33 +-41 +-47 +-51 +-52 +-53 +-52 +-51 +-50 +-48 +-46 +-44 +-42 +-31 +-8 +6 +18 +26 +33 +36 +38 +39 +40 +40 +39 +39 +38 +37 +35 +27 +7 +-7 +-19 +-28 +-34 +-39 +-42 +-43 +-43 +-43 +-43 +-42 +-41 +-38 +-37 +-35 +-33 +-31 +-29 +-27 +-26 +-25 +-24 +-23 +-22 +-21 +-19 +-18 +-18 +-16 +-16 +-7 +14 +29 +39 +46 +50 +53 +55 +54 +54 +53 +51 +48 +46 +44 +42 +33 +13 +-2 +-13 +-23 +-29 +-34 +-36 +-38 +-38 +-38 +-37 +-37 +-36 +-35 +-34 +-23 +-2 +13 +24 +32 +37 +40 +43 +43 +44 +44 +43 +42 +42 +40 +39 +37 +35 +33 +31 +30 +28 +26 +25 +24 +22 +22 +21 +20 +19 +18 +17 +10 +-9 +-23 +-34 +-42 +-47 +-51 +-53 +-54 +-53 +-52 +-51 +-49 +-47 +-45 +-43 +-40 +-38 +-36 +-34 +-32 +-30 +-29 +-28 +-27 +-24 +-23 +-21 +-20 +-19 +-18 +-16 +-6 +15 +29 +40 +46 +51 +54 +55 +55 +55 +54 +52 +51 +49 +47 +44 +42 +40 +37 +35 +33 +32 +30 +29 +27 +25 +23 +21 +19 +19 +17 +17 +9 +-9 +-24 +-35 +-43 +-48 +-51 +-52 +-53 +-53 +-52 +-51 +-49 +-47 +-46 +-43 +-32 +-10 +5 +17 +25 +31 +35 +38 +39 +40 +39 +39 +38 +37 +35 +33 +24 +5 +-11 +-22 +-30 +-36 +-40 +-43 +-45 +-45 +-44 +-43 +-42 +-40 +-38 +-36 +-35 +-33 +-32 +-31 +-29 +-28 +-27 +-25 +-23 +-21 +-19 +-18 +-17 +-16 +-14 +-13 +-3 +17 +31 +40 +47 +51 +53 +54 +55 +56 +55 +53 +52 +50 +49 +46 +44 +42 +39 +37 +35 +33 +30 +29 +28 +26 +24 +23 +22 +21 +19 +18 +11 +-7 +-21 +-32 +-39 +-45 +-48 +-50 +-51 +-52 +-51 +-50 +-49 +-46 +-44 +-42 +-31 +-8 +7 +19 +27 +33 +37 +40 +40 +40 +40 +39 +38 +37 +35 +34 +26 +6 +-9 +-20 +-27 +-33 +-37 +-40 +-42 +-42 +-42 +-41 +-41 +-39 +-38 +-37 +-36 +-35 +-33 +-32 +-31 +-28 +-27 +-24 +-23 +-21 +-20 +-18 +-17 +-15 +-14 +-14 +-4 +16 +30 +40 +47 +50 +53 +55 +55 +55 +55 +53 +51 +50 +48 +46 +43 +41 +39 +36 +34 +31 +29 +28 +26 +24 +22 +21 +20 +19 +18 +17 +9 +-9 +-24 +-34 +-42 +-48 +-52 +-55 +-56 +-56 +-55 +-54 +-53 +-51 +-48 +-46 +-45 +-42 +-39 +-36 +-33 +-31 +-29 +-27 +-26 +-25 +-23 +-22 +-21 +-20 +-19 +-17 +-8 +14 +28 +38 +45 +51 +54 +56 +56 +56 +55 +53 +51 +49 +47 +45 +36 +15 +-1 +-12 +-20 +-27 +-32 +-35 +-37 +-38 +-38 +-37 +-36 +-36 +-35 +-33 +-23 +-1 +13 +23 +31 +36 +39 +41 +43 +43 +43 +42 +41 +39 +38 +37 +29 +9 +-6 +-18 +-26 +-33 +-38 +-41 +-42 +-42 +-42 +-42 +-41 +-39 +-37 +-36 +-25 +-3 +12 +24 +32 +38 +41 +43 +44 +44 +44 +43 +42 +41 +39 +38 +29 +10 +-6 +-17 +-25 +-31 +-35 +-38 +-39 +-40 +-39 +-39 +-38 +-38 +-36 +-35 +-24 +-3 +12 +23 +31 +37 +40 +42 +43 +44 +44 +43 +43 +41 +39 +38 +29 +9 +-6 +-18 +-27 +-34 +-38 +-40 +-42 +-43 +-43 +-43 +-42 +-41 +-38 +-37 +-26 +-4 +11 +21 +29 +35 +38 +40 +41 +41 +42 +41 +39 +38 +37 +35 +26 +7 +-8 +-20 +-28 +-34 +-37 +-40 +-41 +-42 +-41 +-41 +-39 +-38 +-37 +-36 +-25 +-4 +11 +22 +30 +36 +40 +43 +44 +44 +44 +44 +42 +41 +39 +37 +29 +9 +-7 +-19 +-27 +-33 +-38 +-41 +-42 +-43 +-42 +-41 +-40 +-39 +-37 +-35 +-24 +-2 +12 +24 +31 +36 +39 +41 +42 +42 +42 +42 +41 +39 +38 +37 +29 +9 +-6 +-17 +-25 +-31 +-35 +-39 +-40 +-41 +-41 +-40 +-40 +-39 +-37 +-36 +-25 +-4 +11 +22 +31 +36 +40 +42 +44 +44 +44 +43 +42 +41 +39 +37 +28 +8 +-8 +-19 +-28 +-34 +-38 +-41 +-43 +-43 +-43 +-42 +-41 +-39 +-38 +-36 +-26 +-5 +10 +21 +28 +34 +37 +39 +40 +41 +41 +40 +40 +38 +37 +36 +34 +32 +31 +29 +27 +26 +25 +23 +21 +19 +18 +17 +16 +15 +13 +12 +5 +-14 +-28 +-38 +-45 +-51 +-53 +-55 +-56 +-56 +-55 +-54 +-53 +-50 +-48 +-46 +-35 +-13 +2 +14 +23 +29 +33 +37 +38 +39 +39 +39 +38 +37 +35 +34 +26 +6 +-9 +-20 +-29 +-35 +-39 +-41 +-43 +-43 +-43 +-42 +-41 +-40 +-38 +-36 +-25 +-4 +12 +23 +31 +36 +39 +42 +43 +43 +43 +43 +42 +41 +39 +38 +29 +10 +-6 +-17 +-25 +-32 +-36 +-38 +-40 +-41 +-41 +-42 +-41 +-40 +-38 +-36 +-26 +-5 +11 +22 +30 +36 +40 +43 +44 +44 +43 +43 +42 +40 +38 +37 +28 +9 +-6 +-18 +-27 +-32 +-37 +-39 +-41 +-42 +-42 +-41 +-41 +-39 +-38 +-37 +-26 +-5 +10 +21 +30 +36 +39 +41 +42 +42 +42 +42 +40 +39 +37 +36 +27 +8 +-8 +-19 +-28 +-33 +-38 +-41 +-42 +-43 +-43 +-42 +-41 +-40 +-38 +-36 +-25 +-4 +11 +22 +30 +35 +37 +40 +41 +41 +41 +41 +41 +40 +38 +36 +28 +8 +-7 +-19 +-28 +-34 +-38 +-41 +-42 +-42 +-42 +-43 +-41 +-40 +-38 +-36 +-25 +-4 +11 +23 +31 +36 +40 +43 +43 +44 +44 +43 +42 +41 +39 +38 +30 +10 +-5 +-16 +-26 +-31 +-36 +-40 +-41 +-42 +-42 +-41 +-40 +-38 +-37 +-35 +-25 +-3 +12 +24 +32 +37 +40 +42 +43 +44 +43 +43 +42 +40 +38 +37 +29 +9 +-6 +-17 +-26 +-32 +-36 +-38 +-40 +-40 +-40 +-40 +-39 +-39 +-37 +-36 +-25 +-3 +12 +22 +31 +37 +40 +42 +44 +44 +44 +43 +41 +39 +37 +36 +27 +8 +-8 +-20 +-28 +-35 +-39 +-42 +-43 +-44 +-44 +-43 +-42 +-41 +-39 +-38 +-37 +-35 +-33 +-31 +-29 +-28 +-27 +-25 +-24 +-21 +-19 +-18 +-17 +-16 +-15 +-14 +-5 +16 +29 +40 +46 +51 +53 +56 +55 +55 +54 +53 +52 +51 +49 +47 +38 +18 +3 +-10 +-19 +-26 +-31 +-33 +-35 +-36 +-36 +-36 +-35 +-35 +-33 +-32 +-21 +0 +16 +27 +34 +39 +42 +44 +45 +45 +44 +43 +42 +40 +39 +37 +29 +10 +-6 +-17 +-26 +-31 +-36 +-38 +-41 +-41 +-41 +-41 +-40 +-40 +-39 +-37 +-27 +-5 +9 +21 +29 +35 +38 +40 +42 +42 +41 +41 +39 +37 +35 +34 +25 +6 +-9 +-21 +-29 +-34 +-39 +-42 +-43 +-43 +-43 +-42 +-41 +-40 +-38 +-36 +-26 +-5 +10 +21 +30 +35 +39 +42 +43 +44 +45 +44 +43 +42 +40 +39 +31 +11 +-5 +-17 +-25 +-32 +-36 +-39 +-40 +-41 +-41 +-40 +-39 +-38 +-36 +-34 +-23 +-1 +14 +25 +33 +38 +41 +43 +44 +44 +44 +43 +42 +40 +39 +37 +29 +9 +-6 +-18 +-26 +-33 +-36 +-40 +-42 +-43 +-44 +-44 +-43 +-42 +-39 +-38 +-28 +-6 +9 +20 +28 +34 +37 +40 +41 +41 +41 +40 +39 +37 +36 +35 +27 +7 +-8 +-20 +-28 +-34 +-38 +-41 +-42 +-42 +-42 +-41 +-41 +-40 +-39 +-37 +-27 +-5 +10 +21 +30 +36 +39 +41 +43 +44 +44 +43 +42 +41 +39 +37 +29 +9 +-6 +-18 +-27 +-33 +-38 +-40 +-42 +-42 +-42 +-41 +-40 +-39 +-37 +-36 +-25 +-3 +11 +22 +30 +35 +38 +41 +42 +42 +42 +42 +40 +40 +38 +37 +29 +10 +-6 +-17 +-27 +-32 +-37 +-40 +-42 +-42 +-42 +-41 +-41 +-39 +-37 +-35 +-24 +-3 +12 +24 +31 +36 +39 +41 +42 +42 +42 +42 +40 +40 +38 +37 +36 +34 +33 +32 +30 +28 +26 +25 +23 +21 +19 +18 +17 +16 +15 +15 +7 +-12 +-26 +-36 +-44 +-49 +-52 +-54 +-55 +-55 +-54 +-54 +-52 +-50 +-47 +-45 +-34 +-12 +3 +15 +23 +29 +34 +38 +39 +39 +38 +38 +36 +35 +33 +32 +24 +5 +-11 +-22 +-31 +-36 +-40 +-43 +-44 +-45 +-45 +-44 +-44 +-43 +-41 +-39 +-29 +-8 +8 +19 +27 +33 +36 +39 +40 +41 +42 +41 +40 +39 +37 +36 +28 +8 +-7 +-19 +-28 +-34 +-38 +-40 +-42 +-43 +-43 +-43 +-41 +-38 +-37 +-35 +-25 +-3 +11 +21 +29 +34 +37 +39 +40 +40 +40 +40 +39 +37 +36 +35 +26 +7 +-8 +-20 +-29 +-36 +-40 +-42 +-44 +-45 +-45 +-44 +-42 +-41 +-39 +-37 +-26 +-4 +11 +23 +31 +36 +40 +42 +44 +44 +44 +42 +42 +40 +39 +37 +29 +9 +-5 +-16 +-25 +-31 +-35 +-38 +-40 +-40 +-41 +-40 +-39 +-38 +-37 +-36 +-26 +-4 +11 +22 +30 +36 +39 +42 +43 +44 +44 +43 +42 +41 +39 +38 +29 +9 +-7 +-18 +-27 +-33 +-37 +-40 +-42 +-43 +-42 +-42 +-41 +-40 +-38 +-35 +-25 +-3 +12 +22 +29 +35 +39 +41 +42 +42 +42 +41 +40 +39 +37 +36 +28 +8 +-7 +-18 +-27 +-33 +-37 +-40 +-42 +-43 +-44 +-43 +-42 +-41 +-40 +-38 +-27 +-5 +10 +22 +29 +35 +39 +42 +43 +44 +43 +42 +41 +40 +38 +36 +28 +9 +-6 +-18 +-26 +-32 +-36 +-39 +-39 +-40 +-40 +-39 +-39 +-38 +-36 +-35 +-24 +-3 +13 +23 +31 +36 +40 +42 +44 +44 +44 +43 +43 +41 +40 +38 +30 +9 +-7 +-19 +-28 +-34 +-38 +-41 +-42 +-43 +-43 +-42 +-41 +-39 +-37 +-35 +-25 +-3 +12 +23 +30 +36 +38 +41 +42 +43 +42 +42 +41 +40 +38 +37 +29 +9 +-6 +-17 +-26 +-32 +-37 +-40 +-42 +-43 +-43 +-42 +-41 +-40 +-38 +-36 +-26 +-5 +10 +22 +30 +35 +39 +41 +42 +42 +42 +40 +39 +38 +37 +35 +26 +7 +-8 +-19 +-28 +-34 +-38 +-41 +-42 +-42 +-42 +-42 +-42 +-40 +-39 +-37 +-36 +-34 +-32 +-30 +-29 +-27 +-25 +-24 +-22 +-20 +-19 +-17 +-16 +-15 +-15 +-14 +-5 +16 +30 +40 +48 +52 +55 +57 +57 +56 +55 +54 +52 +50 +48 +46 +37 +17 +1 +-11 +-20 +-27 +-31 +-34 +-36 +-37 +-37 +-37 +-36 +-35 +-33 +-31 +-20 +1 +16 +27 +35 +40 +43 +46 +47 +47 +47 +45 +43 +42 +40 +39 +37 +35 +34 +33 +30 +29 +27 +26 +24 +23 +22 +20 +18 +17 +16 +15 +7 +-11 +-26 +-36 +-44 +-49 +-52 +-54 +-54 +-54 +-53 +-52 +-51 +-48 +-46 +-44 +-34 +-12 +3 +14 +23 +28 +32 +35 +37 +38 +38 +38 +37 +36 +34 +34 +25 +5 +-10 +-21 +-30 +-36 +-41 +-43 +-45 +-45 +-46 +-45 +-44 +-42 +-41 +-38 +-28 +-6 +8 +20 +27 +32 +35 +38 +39 +39 +38 +38 +37 +37 +35 +35 +26 +7 +-8 +-19 +-28 +-33 +-37 +-41 +-42 +-43 +-44 +-43 +-42 +-40 +-39 +-37 +-35 +-33 +-31 +-29 +-27 +-25 +-23 +-21 +-19 +-18 +-16 +-15 +-15 +-14 +-13 +-11 +-2 +19 +33 +44 +50 +55 +57 +59 +60 +60 +58 +57 +55 +53 +50 +48 +45 +43 +40 +38 +36 +34 +32 +31 +29 +28 +25 +24 +22 +22 +20 +19 +11 +-7 +-22 +-34 +-42 +-48 +-51 +-54 +-55 +-55 +-54 +-53 +-51 +-49 +-47 +-45 +-34 +-11 +4 +15 +23 +29 +33 +35 +37 +38 +38 +37 +36 +35 +34 +33 +26 +6 +-9 +-21 +-30 +-36 +-41 +-44 +-45 +-46 +-45 +-44 +-43 +-42 +-40 +-38 +-36 +-34 +-32 +-30 +-28 +-26 +-25 +-24 +-23 +-22 +-20 +-18 +-17 +-16 +-15 +-14 +-3 +17 +32 +42 +49 +53 +56 +58 +58 +57 +55 +53 +51 +49 +47 +45 +42 +40 +38 +36 +34 +33 +31 +30 +29 +27 +25 +23 +22 +20 +19 +18 +10 +-9 +-24 +-34 +-42 +-47 +-50 +-52 +-52 +-52 +-50 +-49 +-47 +-46 +-44 +-42 +-31 +-8 +6 +18 +26 +32 +36 +39 +40 +41 +40 +41 +39 +39 +38 +37 +28 +9 +-6 +-18 +-27 +-33 +-38 +-41 +-42 +-43 +-43 +-43 +-41 +-40 +-39 +-37 +-26 +-4 +10 +22 +30 +36 +39 +41 +41 +42 +41 +40 +39 +37 +36 +34 +26 +6 +-9 +-20 +-28 +-34 +-38 +-41 +-42 +-43 +-43 +-42 +-42 +-41 +-40 +-38 +-27 +-5 +11 +22 +29 +35 +39 +41 +43 +44 +43 +42 +41 +40 +38 +36 +28 +8 +-7 +-19 +-28 +-34 +-38 +-41 +-42 +-43 +-43 +-42 +-41 +-39 +-37 +-36 +-35 +-33 +-31 +-30 +-29 +-27 +-25 +-24 +-22 +-21 +-19 +-18 +-16 +-16 +-14 +-13 +-3 +18 +32 +42 +49 +53 +55 +57 +56 +55 +53 +53 +51 +50 +48 +46 +37 +17 +1 +-11 +-19 +-26 +-31 +-34 +-36 +-37 +-38 +-38 +-38 +-36 +-35 +-34 +-23 +-2 +13 +25 +33 +39 +42 +44 +45 +45 +45 +44 +42 +41 +39 +36 +28 +8 +-7 +-18 +-26 +-32 +-36 +-39 +-40 +-41 +-41 +-40 +-39 +-37 +-36 +-35 +-24 +-3 +12 +23 +31 +37 +40 +42 +44 +44 +44 +43 +43 +42 +41 +39 +37 +35 +33 +31 +29 +27 +26 +24 +23 +22 +20 +19 +18 +17 +16 +15 +8 +-12 +-26 +-36 +-44 +-49 +-53 +-55 +-56 +-56 +-56 +-54 +-52 +-50 +-48 +-46 +-34 +-11 +4 +16 +24 +30 +34 +36 +37 +38 +37 +36 +36 +35 +33 +32 +25 +5 +-11 +-22 +-30 +-36 +-40 +-43 +-44 +-45 +-45 +-45 +-44 +-43 +-41 +-39 +-38 +-35 +-34 +-31 +-30 +-27 +-25 +-24 +-22 +-21 +-20 +-19 +-18 +-17 +-16 +-15 +-5 +16 +30 +40 +47 +51 +54 +56 +56 +57 +55 +53 +52 +50 +47 +44 +41 +39 +37 +35 +33 +32 +30 +28 +26 +25 +24 +22 +21 +20 +19 +18 +11 +-8 +-24 +-35 +-42 +-48 +-51 +-54 +-54 +-54 +-53 +-52 +-50 +-48 +-45 +-43 +-32 +-10 +6 +17 +25 +30 +33 +36 +37 +38 +37 +37 +37 +36 +35 +34 +26 +6 +-9 +-20 +-28 +-34 +-39 +-41 +-43 +-44 +-44 +-44 +-42 +-41 +-39 +-37 +-27 +-5 +10 +21 +29 +35 +38 +41 +42 +43 +43 +42 +40 +38 +37 +36 +29 +9 +-6 +-18 +-27 +-33 +-37 +-39 +-41 +-41 +-42 +-41 +-40 +-39 +-37 +-36 +-25 +-4 +10 +21 +29 +34 +38 +40 +41 +42 +42 +42 +40 +39 +37 +36 +27 +7 +-9 +-21 +-30 +-36 +-41 +-43 +-44 +-45 +-45 +-44 +-43 +-41 +-39 +-37 +-27 +-5 +10 +22 +29 +35 +37 +40 +41 +42 +41 +41 +40 +39 +37 +37 +29 +9 +-6 +-16 +-25 +-31 +-35 +-37 +-39 +-40 +-40 +-40 +-39 +-38 +-37 +-35 +-24 +-3 +12 +23 +31 +37 +40 +43 +45 +45 +44 +43 +42 +41 +38 +36 +29 +9 +-6 +-18 +-26 +-32 +-36 +-39 +-41 +-41 +-41 +-41 +-40 +-39 +-37 +-36 +-26 +-4 +10 +22 +29 +35 +38 +40 +42 +42 +42 +42 +40 +40 +39 +38 +29 +10 +-6 +-17 +-26 +-32 +-37 +-40 +-42 +-43 +-42 +-41 +-41 +-39 +-38 +-35 +-25 +-3 +12 +23 +31 +36 +40 +42 +43 +43 +43 +42 +40 +40 +38 +37 +29 +9 +-6 +-17 +-26 +-32 +-37 +-40 +-41 +-42 +-42 +-41 +-41 +-40 +-38 +-36 +-34 +-32 +-30 +-28 +-26 +-24 +-22 +-20 +-19 +-17 +-15 +-14 +-14 +-13 +-13 +-12 +-2 +19 +32 +42 +49 +53 +55 +57 +57 +57 +56 +55 +52 +51 +48 +46 +36 +16 +0 +-12 +-22 +-28 +-33 +-36 +-38 +-39 +-39 +-38 +-37 +-35 +-34 +-33 +-23 +-2 +13 +24 +30 +36 +39 +41 +42 +43 +42 +42 +41 +40 +38 +36 +28 +8 +-7 +-17 +-26 +-32 +-37 +-40 +-42 +-43 +-43 +-43 +-41 +-40 +-39 +-37 +-26 +-4 +10 +21 +30 +36 +39 +41 +43 +43 +43 +42 +41 +40 +38 +37 +28 +9 +-6 +-18 +-27 +-33 +-37 +-40 +-41 +-42 +-42 +-41 +-41 +-40 +-39 +-37 +-28 +-6 +9 +21 +29 +34 +38 +40 +41 +42 +42 +41 +40 +39 +38 +36 +27 +7 +-9 +-20 +-28 +-35 +-39 +-41 +-43 +-43 +-43 +-43 +-41 +-39 +-38 +-35 +-25 +-4 +11 +22 +30 +35 +39 +41 +42 +42 +42 +41 +40 +39 +38 +36 +29 +9 +-7 +-18 +-27 +-33 +-38 +-42 +-43 +-44 +-44 +-43 +-42 +-40 +-38 +-36 +-26 +-4 +11 +23 +30 +36 +39 +42 +42 +43 +42 +42 +40 +39 +38 +37 +29 +10 +-6 +-18 +-26 +-32 +-36 +-39 +-40 +-41 +-40 +-40 +-40 +-38 +-36 +-36 +-25 +-3 +12 +23 +31 +37 +41 +43 +44 +45 +45 +45 +44 +42 +40 +39 +31 +11 +-5 +-16 +-25 +-32 +-36 +-39 +-40 +-41 +-41 +-40 +-39 +-38 +-37 +-35 +-25 +-3 +11 +23 +29 +35 +38 +40 +41 +41 +40 +40 +39 +38 +36 +34 +26 +6 +-9 +-20 +-29 +-35 +-38 +-42 +-44 +-45 +-45 +-44 +-43 +-42 +-40 +-37 +-26 +-4 +10 +22 +29 +36 +39 +42 +43 +44 +44 +43 +42 +40 +39 +37 +36 +34 +32 +31 +29 +28 +26 +24 +23 +22 +21 +20 +19 +17 +16 +15 +8 +-11 +-26 +-37 +-44 +-49 +-52 +-54 +-55 +-54 +-53 +-52 +-50 +-48 +-46 +-44 +-33 +-11 +4 +15 +23 +28 +32 +35 +37 +38 +39 +39 +38 +37 +35 +34 +25 +5 +-10 +-21 +-31 +-37 +-41 +-43 +-45 +-45 +-45 +-44 +-43 +-42 +-39 +-38 +-27 +-5 +10 +21 +28 +33 +36 +39 +39 +41 +40 +40 +39 +38 +36 +36 +27 +8 +-7 +-19 +-28 +-33 +-38 +-41 +-43 +-43 +-44 +-43 +-42 +-40 +-38 +-36 +-25 +-3 +12 +24 +32 +38 +41 +44 +45 +45 +44 +44 +42 +41 +38 +37 +28 +8 +-7 +-17 +-26 +-32 +-36 +-39 +-41 +-41 +-41 +-40 +-40 +-39 +-38 +-37 +-27 +-6 +9 +20 +28 +34 +38 +40 +41 +42 +42 +41 +40 +39 +37 +36 +26 +6 +-9 +-20 +-29 +-34 +-39 +-42 +-44 +-44 +-44 +-42 +-41 +-40 +-38 +-36 +-26 +-4 +10 +22 +30 +35 +39 +42 +44 +44 +44 +44 +43 +42 +41 +40 +32 +12 +-3 +-14 +-24 +-30 +-35 +-38 +-39 +-40 +-40 +-39 +-38 +-36 +-35 +-33 +-22 +-1 +14 +25 +33 +38 +42 +44 +44 +45 +45 +44 +42 +41 +39 +38 +30 +10 +-6 +-17 +-26 +-32 +-36 +-40 +-42 +-42 +-43 +-43 +-43 +-42 +-40 +-39 +-29 +-6 +8 +20 +28 +33 +37 +40 +41 +42 +41 +40 +39 +38 +36 +34 +26 +6 +-9 +-20 +-30 +-36 +-40 +-42 +-43 +-43 +-44 +-43 +-42 +-40 +-38 +-37 +-35 +-34 +-32 +-30 +-29 +-27 +-26 +-23 +-22 +-20 +-19 +-18 +-17 +-15 +-14 +-12 +-3 +18 +32 +42 +48 +53 +54 +56 +56 +56 +55 +53 +52 +50 +48 +46 +44 +43 +40 +39 +36 +34 +31 +30 +27 +26 +24 +23 +21 +20 +19 +18 +10 +-8 +-23 +-33 +-41 +-46 +-49 +-51 +-53 +-53 +-53 +-52 +-50 +-49 +-46 +-44 +-42 +-39 +-37 +-34 +-32 +-30 +-28 +-27 +-26 +-24 +-23 +-22 +-22 +-20 +-19 +-17 +-7 +14 +28 +39 +47 +51 +53 +55 +55 +55 +54 +53 +51 +48 +46 +44 +42 +40 +37 +35 +34 +32 +31 +28 +26 +25 +24 +23 +22 +21 +20 +18 +10 +-9 +-24 +-34 +-42 +-47 +-51 +-53 +-54 +-54 +-53 +-52 +-49 +-48 +-45 +-43 +-41 +-39 +-37 +-35 +-33 +-32 +-29 +-28 +-27 +-25 +-23 +-22 +-21 +-19 +-17 +-16 +-6 +15 +29 +39 +47 +51 +54 +55 +55 +55 +54 +53 +51 +49 +47 +45 +43 +41 +39 +37 +34 +32 +30 +29 +27 +25 +23 +21 +19 +18 +16 +15 +7 +-12 +-27 +-37 +-44 +-49 +-52 +-55 +-56 +-55 +-55 +-53 +-51 +-49 +-47 +-46 +-43 +-40 +-38 +-36 +-34 +-32 +-30 +-28 +-26 +-24 +-22 +-21 +-20 +-18 +-16 +-15 +-5 +15 +29 +40 +47 +51 +54 +55 +55 +55 +54 +53 +50 +49 +47 +46 +43 +41 +39 +36 +34 +31 +29 +27 +26 +25 +23 +21 +20 +19 +18 +17 +10 +-9 +-23 +-33 +-41 +-47 +-51 +-54 +-55 +-55 +-54 +-53 +-51 +-49 +-47 +-45 +-43 +-40 +-38 +-36 +-33 +-31 +-29 +-27 +-26 +-25 +-23 +-21 +-20 +-19 +-18 +-17 +-7 +14 +29 +40 +48 +52 +54 +56 +57 +56 +55 +54 +53 +50 +48 +46 +43 +41 +39 +37 +34 +33 +31 +29 +28 +27 +25 +24 +23 +21 +20 +19 +11 +-8 +-22 +-33 +-41 +-46 +-49 +-51 +-52 +-52 +-51 +-49 +-47 +-46 +-44 +-42 +-39 +-37 +-35 +-34 +-32 +-31 +-28 +-26 +-25 +-23 +-22 +-21 +-21 +-19 +-18 +-16 +-6 +14 +28 +38 +45 +49 +51 +53 +53 +53 +52 +50 +49 +47 +45 +43 +35 +15 +-1 +-13 +-22 +-28 +-32 +-36 +-39 +-39 +-39 +-39 +-38 +-37 +-35 +-34 +-23 +-1 +14 +25 +33 +38 +41 +43 +44 +45 +45 +44 +42 +41 +39 +38 +29 +10 +-5 +-16 +-25 +-30 +-34 +-37 +-39 +-40 +-40 +-40 +-39 +-38 +-37 +-35 +-25 +-3 +12 +23 +30 +36 +39 +42 +44 +44 +44 +43 +42 +40 +39 +37 +28 +9 +-7 +-18 +-27 +-33 +-37 +-39 +-41 +-41 +-41 +-40 +-39 +-38 +-37 +-36 +-26 +-5 +10 +21 +29 +35 +38 +40 +42 +43 +42 +42 +40 +39 +37 +36 +28 +9 +-7 +-18 +-27 +-33 +-38 +-41 +-42 +-43 +-43 +-42 +-42 +-40 +-38 +-36 +-25 +-2 +12 +24 +31 +37 +41 +43 +45 +45 +44 +44 +43 +42 +40 +40 +31 +11 +-5 +-16 +-25 +-31 +-35 +-38 +-40 +-41 +-42 +-42 +-41 +-40 +-39 +-37 +-27 +-5 +10 +22 +30 +35 +38 +41 +42 +43 +42 +42 +40 +38 +36 +35 +27 +7 +-8 +-19 +-27 +-33 +-38 +-40 +-42 +-42 +-41 +-40 +-39 +-37 +-36 +-35 +-25 +-3 +11 +22 +30 +36 +39 +41 +42 +42 +42 +42 +40 +39 +38 +37 +29 +9 +-7 +-19 +-27 +-34 +-39 +-42 +-43 +-44 +-44 +-44 +-43 +-41 +-39 +-37 +-27 +-5 +11 +21 +29 +34 +37 +39 +40 +41 +40 +40 +39 +38 +37 +35 +28 +8 +-7 +-18 +-26 +-32 +-35 +-38 +-40 +-41 +-41 +-41 +-40 +-38 +-37 +-35 +-24 +-3 +12 +23 +31 +37 +41 +43 +45 +45 +44 +42 +41 +39 +38 +36 +35 +33 +32 +29 +28 +26 +25 +23 +22 +21 +19 +18 +16 +15 +14 +12 +5 +-14 +-28 +-39 +-47 +-52 +-55 +-57 +-57 +-57 +-56 +-54 +-52 +-50 +-47 +-45 +-35 +-13 +3 +14 +22 +28 +32 +35 +37 +38 +38 +38 +37 +37 +35 +34 +26 +6 +-10 +-21 +-29 +-35 +-39 +-42 +-43 +-44 +-44 +-43 +-42 +-39 +-38 +-36 +-26 +-5 +10 +21 +28 +34 +37 +39 +40 +41 +41 +40 +40 +39 +37 +35 +28 +8 +-7 +-19 +-27 +-34 +-38 +-43 +-44 +-45 +-45 +-44 +-43 +-41 +-40 +-37 +-27 +-5 +11 +23 +30 +36 +39 +42 +43 +43 +42 +41 +40 +39 +37 +37 +29 +9 +-6 +-18 +-26 +-31 +-36 +-39 +-41 +-41 +-42 +-41 +-40 +-39 +-37 +-36 +-25 +-4 +12 +23 +30 +36 +39 +42 +43 +43 +43 +42 +40 +39 +38 +36 +28 +8 +-8 +-19 +-27 +-33 +-37 +-39 +-42 +-42 +-42 +-42 +-41 +-40 +-37 +-36 +-26 +-4 +10 +21 +29 +35 +38 +41 +42 +43 +43 +43 +42 +40 +39 +37 +28 +8 +-7 +-18 +-27 +-32 +-37 +-40 +-41 +-41 +-41 +-41 +-39 +-37 +-35 +-34 +-24 +-3 +11 +22 +29 +35 +38 +40 +42 +42 +42 +41 +40 +38 +37 +36 +27 +6 +-8 +-19 +-28 +-34 +-39 +-42 +-43 +-45 +-45 +-43 +-42 +-40 +-39 +-36 +-25 +-3 +11 +23 +31 +36 +40 +42 +44 +44 +43 +42 +42 +41 +39 +37 +29 +9 +-6 +-17 +-25 +-31 +-35 +-38 +-39 +-40 +-41 +-40 +-39 +-38 +-38 +-36 +-25 +-3 +11 +23 +30 +36 +39 +42 +43 +44 +44 +43 +42 +40 +38 +36 +28 +8 +-7 +-18 +-27 +-33 +-37 +-40 +-42 +-42 +-41 +-41 +-41 +-39 +-38 +-36 +-34 +-32 +-31 +-30 +-29 +-27 +-25 +-23 +-22 +-20 +-19 +-18 +-16 +-15 +-13 +-12 +-3 +18 +32 +42 +49 +53 +55 +56 +56 +56 +55 +53 +51 +50 +47 +46 +44 +42 +39 +37 +36 +33 +31 +28 +26 +25 +23 +22 +20 +19 +18 +17 +9 +-10 +-25 +-35 +-42 +-48 +-52 +-53 +-55 +-56 +-55 +-55 +-53 +-51 +-49 +-47 +-35 +-13 +2 +14 +23 +29 +33 +35 +37 +38 +37 +37 +36 +34 +33 +32 +24 +5 +-10 +-21 +-29 +-34 +-38 +-40 +-42 +-42 +-42 +-41 +-41 +-40 +-38 +-36 +-26 +-4 +11 +23 +32 +38 +41 +44 +45 +46 +45 +45 +43 +42 +40 +39 +30 +10 +-5 +-16 +-26 +-32 +-36 +-39 +-41 +-42 +-41 +-41 +-39 +-38 +-36 +-35 +-33 +-32 +-31 +-30 +-29 +-27 +-26 +-25 +-24 +-21 +-20 +-19 +-19 +-17 +-16 +-15 +-5 +16 +30 +41 +47 +52 +54 +56 +55 +55 +54 +53 +51 +49 +48 +46 +43 +41 +39 +38 +35 +34 +31 +29 +27 +25 +24 +22 +21 +20 +19 +18 +10 +-9 +-23 +-33 +-40 +-46 +-49 +-52 +-52 +-52 +-51 +-51 +-49 +-48 +-46 +-44 +-33 +-10 +6 +17 +25 +31 +36 +38 +39 +40 +39 +39 +37 +36 +34 +32 +24 +5 +-10 +-21 +-29 +-35 +-39 +-42 +-43 +-44 +-43 +-43 +-43 +-41 +-39 +-38 +-36 +-35 +-33 +-32 +-30 +-28 +-27 +-25 +-23 +-22 +-20 +-19 +-18 +-17 +-16 +-15 +-5 +15 +29 +39 +47 +52 +54 +55 +56 +56 +55 +54 +52 +51 +49 +46 +37 +17 +1 +-11 +-20 +-27 +-32 +-35 +-37 +-38 +-38 +-38 +-35 +-34 +-33 +-32 +-22 +-1 +14 +25 +33 +38 +41 +43 +44 +45 +44 +43 +42 +41 +40 +38 +36 +35 +33 +31 +29 +28 +26 +24 +23 +22 +20 +18 +17 +16 +16 +15 +7 +-11 +-25 +-35 +-43 +-48 +-52 +-54 +-55 +-56 +-55 +-53 +-52 +-50 +-48 +-46 +-44 +-41 +-38 +-36 +-33 +-31 +-29 +-27 +-25 +-24 +-23 +-22 +-21 +-19 +-18 +-17 +-7 +15 +29 +39 +46 +51 +54 +56 +56 +55 +54 +53 +51 +50 +47 +44 +42 +40 +38 +36 +34 +32 +31 +29 +27 +26 +25 +23 +21 +19 +18 +17 +9 +-10 +-25 +-35 +-43 +-48 +-51 +-53 +-54 +-53 +-52 +-51 +-49 +-47 +-45 +-43 +-32 +-10 +4 +16 +25 +31 +35 +38 +39 +40 +39 +39 +38 +38 +36 +34 +26 +7 +-9 +-21 +-30 +-36 +-40 +-43 +-45 +-45 +-46 +-45 +-43 +-41 +-39 +-38 +-36 +-35 +-33 +-32 +-30 +-29 +-27 +-26 +-23 +-22 +-20 +-19 +-18 +-17 +-15 +-14 +-3 +18 +32 +42 +49 +53 +56 +58 +58 +58 +57 +56 +53 +51 +50 +48 +46 +43 +41 +39 +37 +35 +32 +30 +28 +26 +24 +22 +21 +20 +18 +17 +9 +-10 +-24 +-34 +-42 +-47 +-51 +-54 +-55 +-55 +-54 +-53 +-52 +-50 +-48 +-46 +-35 +-13 +4 +16 +25 +31 +35 +37 +38 +38 +37 +37 +36 +35 +34 +33 +25 +5 +-10 +-21 +-29 +-35 +-39 +-41 +-43 +-44 +-44 +-44 +-43 +-41 +-39 +-38 +-36 +-34 +-32 +-31 +-29 +-27 +-25 +-23 +-21 +-20 +-19 +-17 +-16 +-16 +-15 +-13 +-4 +17 +31 +41 +48 +53 +56 +58 +58 +57 +56 +54 +52 +50 +48 +46 +43 +40 +38 +36 +34 +33 +32 +31 +28 +27 +25 +24 +22 +21 +19 +17 +9 +-10 +-24 +-34 +-42 +-47 +-51 +-53 +-54 +-53 +-53 +-52 +-50 +-48 +-46 +-44 +-42 +-40 +-39 +-37 +-34 +-32 +-31 +-29 +-27 +-25 +-23 +-21 +-20 +-18 +-17 +-16 +-6 +15 +29 +39 +46 +50 +52 +54 +54 +54 +53 +52 +50 +49 +47 +46 +37 +18 +1 +-11 +-20 +-26 +-31 +-35 +-37 +-38 +-37 +-36 +-36 +-35 +-34 +-33 +-22 +-1 +14 +25 +33 +38 +41 +44 +44 +45 +44 +44 +43 +42 +40 +38 +30 +11 +-5 +-16 +-24 +-31 +-36 +-39 +-40 +-41 +-42 +-41 +-41 +-39 +-37 +-35 +-24 +-2 +12 +24 +32 +37 +40 +43 +44 +44 +44 +42 +41 +39 +38 +36 +27 +7 +-7 +-19 +-28 +-34 +-38 +-40 +-42 +-42 +-43 +-42 +-41 +-40 +-38 +-36 +-27 +-5 +9 +21 +29 +35 +38 +41 +42 +43 +43 +42 +40 +39 +37 +36 +27 +7 +-7 +-18 +-27 +-34 +-38 +-41 +-42 +-43 +-43 +-42 +-40 +-39 +-38 +-36 +-25 +-4 +10 +21 +30 +35 +39 +41 +43 +43 +43 +43 +42 +41 +39 +38 +30 +10 +-6 +-17 +-26 +-32 +-36 +-39 +-40 +-41 +-41 +-40 +-39 +-38 +-36 +-34 +-25 +-3 +12 +24 +31 +36 +39 +42 +42 +41 +41 +41 +40 +39 +37 +36 +28 +9 +-7 +-19 +-27 +-33 +-38 +-41 +-43 +-44 +-44 +-44 +-43 +-41 +-40 +-38 +-27 +-5 +9 +21 +29 +34 +38 +41 +42 +42 +42 +42 +41 +40 +38 +36 +28 +9 +-6 +-17 +-25 +-31 +-35 +-38 +-39 +-40 +-40 +-40 +-40 +-39 +-37 +-36 +-25 +-3 +12 +24 +32 +38 +41 +44 +45 +45 +45 +44 +44 +42 +41 +38 +30 +9 +-5 +-17 +-26 +-32 +-37 +-40 +-41 +-42 +-42 +-41 +-40 +-39 +-37 +-36 +-26 +-5 +10 +21 +28 +34 +37 +39 +40 +41 +41 +40 +39 +38 +37 +35 +33 +31 +29 +27 +25 +23 +21 +20 +19 +18 +17 +16 +15 +14 +14 +12 +5 +-14 +-28 +-39 +-46 +-52 +-56 +-58 +-58 +-58 +-57 +-56 +-54 +-52 +-49 +-46 +-35 +-12 +3 +15 +23 +29 +32 +36 +37 +39 +38 +38 +38 +38 +36 +35 +27 +8 +-7 +-19 +-28 +-34 +-38 +-41 +-43 +-43 +-43 +-43 +-41 +-40 +-38 +-36 +-25 +-3 +11 +23 +31 +37 +39 +43 +43 +43 +43 +42 +41 +40 +39 +38 +29 +10 +-6 +-17 +-25 +-31 +-35 +-39 +-40 +-42 +-42 +-41 +-40 +-38 +-37 +-36 +-25 +-3 +12 +24 +31 +37 +40 +43 +44 +45 +45 +44 +42 +40 +39 +36 +29 +9 +-6 +-17 +-26 +-32 +-36 +-38 +-39 +-41 +-40 +-40 +-39 +-38 +-37 +-36 +-25 +-3 +12 +23 +31 +37 +40 +43 +44 +45 +44 +44 +43 +41 +39 +38 +29 +9 +-6 +-18 +-27 +-33 +-37 +-40 +-42 +-43 +-42 +-41 +-40 +-39 +-37 +-35 +-25 +-3 +12 +22 +30 +34 +38 +40 +41 +41 +41 +40 +39 +38 +37 +36 +27 +8 +-8 +-19 +-28 +-35 +-40 +-43 +-45 +-45 +-45 +-45 +-44 +-42 +-40 +-38 +-28 +-6 +10 +22 +29 +34 +37 +40 +41 +42 +42 +41 +40 +39 +37 +36 +28 +8 +-7 +-18 +-27 +-33 +-38 +-40 +-42 +-44 +-44 +-44 +-42 +-41 +-39 +-37 +-27 +-5 +10 +21 +29 +35 +39 +42 +43 +43 +42 +41 +40 +39 +38 +36 +28 +9 +-7 +-18 +-26 +-32 +-36 +-39 +-40 +-41 +-40 +-40 +-39 +-38 +-37 +-36 +-25 +-4 +11 +23 +31 +36 +39 +41 +43 +43 +43 +42 +41 +40 +38 +36 +27 +7 +-9 +-21 +-29 +-35 +-39 +-41 +-42 +-43 +-43 +-42 +-41 +-38 +-37 +-35 +-34 +-33 +-32 +-30 +-28 +-27 +-26 +-24 +-22 +-20 +-18 +-17 +-16 +-14 +-14 +-12 +-2 +18 +32 +43 +49 +54 +56 +57 +57 +57 +56 +55 +54 +52 +50 +47 +38 +18 +2 +-10 +-20 +-26 +-31 +-35 +-37 +-38 +-39 +-38 +-37 +-36 +-34 +-33 +-22 +-1 +14 +25 +33 +38 +42 +43 +44 +44 +43 +43 +41 +40 +38 +37 +28 +8 +-6 +-18 +-26 +-32 +-36 +-39 +-41 +-41 +-42 +-42 +-41 +-40 +-39 +-37 +-26 +-4 +10 +21 +30 +35 +39 +41 +43 +44 +43 +42 +41 +39 +37 +36 +27 +7 +-8 +-19 +-28 +-34 +-37 +-40 +-41 +-42 +-42 +-41 +-39 +-39 +-38 +-36 +-25 +-4 +10 +21 +28 +34 +38 +41 +42 +43 +43 +42 +41 +40 +39 +38 +30 +10 +-5 +-16 +-26 +-32 +-37 +-39 +-40 +-42 +-42 +-42 +-41 +-40 +-37 +-35 +-24 +-3 +12 +23 +31 +37 +40 +42 +42 +43 +42 +41 +40 +39 +37 +36 +28 +8 +-7 +-19 +-27 +-32 +-37 +-39 +-41 +-42 +-43 +-42 +-42 +-40 +-39 +-36 +-26 +-4 +11 +22 +30 +35 +39 +41 +43 +43 +43 +42 +41 +40 +38 +36 +29 +9 +-6 +-18 +-27 +-33 +-38 +-40 +-41 +-41 +-41 +-40 +-39 +-37 +-36 +-35 +-25 +-3 +12 +23 +30 +35 +38 +41 +43 +43 +43 +42 +41 +40 +39 +37 +28 +8 +-8 +-19 +-28 +-35 +-40 +-42 +-44 +-44 +-44 +-43 +-42 +-41 +-39 +-37 +-26 +-4 +11 +21 +29 +34 +38 +40 +41 +41 +41 +41 +39 +38 +36 +35 +28 +9 +-6 +-17 +-26 +-32 +-36 +-40 +-41 +-41 +-41 +-40 +-40 +-39 +-38 +-36 +-26 +-4 +12 +22 +31 +37 +40 +42 +43 +43 +42 +42 +40 +39 +37 +36 +33 +32 +30 +29 +27 +27 +25 +24 +22 +21 +19 +17 +16 +15 +14 +13 +5 +-13 +-27 +-37 +-44 +-50 +-53 +-54 +-55 +-55 +-54 +-53 +-51 +-49 +-47 +-45 +-33 +-12 +4 +15 +24 +30 +34 +37 +38 +39 +39 +38 +37 +36 +35 +33 +24 +5 +-11 +-22 +-30 +-35 +-39 +-42 +-43 +-43 +-43 +-42 +-41 +-39 +-37 +-36 +-25 +-4 +11 +21 +29 +35 +39 +41 +43 +43 +43 +42 +41 +40 +39 +38 +30 +10 +-5 +-16 +-25 +-31 +-36 +-39 +-40 +-41 +-42 +-42 +-40 +-39 +-37 +-35 +-24 +-3 +13 +24 +32 +37 +40 +42 +43 +43 +44 +43 +42 +40 +38 +36 +28 +9 +-6 +-17 +-25 +-31 +-36 +-39 +-41 +-42 +-42 +-42 +-41 +-39 +-37 +-35 +-25 +-4 +12 +23 +31 +37 +40 +42 +43 +43 +42 +41 +39 +39 +37 +35 +27 +7 +-8 +-19 +-28 +-34 +-38 +-41 +-42 +-43 +-43 +-43 +-42 +-41 +-40 +-38 +-27 +-6 +9 +20 +28 +34 +38 +41 +42 +43 +43 +42 +41 +40 +37 +35 +27 +8 +-7 +-18 +-26 +-32 +-36 +-39 +-40 +-41 +-41 +-41 +-40 +-39 +-38 +-37 +-26 +-5 +10 +21 +29 +34 +38 +41 +42 +43 +42 +42 +41 +40 +38 +36 +27 +7 +-9 +-20 +-29 +-34 +-38 +-41 +-43 +-43 +-43 +-42 +-41 +-39 +-37 +-36 +-26 +-5 +10 +21 +29 +34 +38 +40 +42 +42 +42 +42 +40 +40 +39 +38 +29 +9 +-6 +-17 +-26 +-32 +-36 +-40 +-42 +-42 +-42 +-41 +-39 +-38 +-37 +-35 +-23 +-2 +12 +23 +31 +36 +39 +42 +43 +43 +42 +41 +40 +39 +37 +36 +28 +8 +-7 +-18 +-27 +-33 +-37 +-40 +-42 +-43 +-42 +-41 +-41 +-40 +-38 +-37 +-26 +-4 +10 +21 +29 +35 +39 +41 +42 +42 +41 +41 +39 +38 +36 +34 +26 +6 +-9 +-21 +-29 +-35 +-39 +-42 +-43 +-44 +-44 +-42 +-41 +-40 +-39 +-38 +-27 +-5 +10 +21 +29 +35 +38 +41 +43 +43 +43 +42 +42 +40 +39 +37 +29 +10 +-5 +-17 +-26 +-33 +-37 +-40 +-42 +-42 +-42 +-41 +-40 +-39 +-37 +-35 +-33 +-31 +-30 +-28 +-27 +-25 +-24 +-22 +-22 +-21 +-19 +-18 +-16 +-16 +-15 +-14 +-4 +17 +31 +41 +48 +52 +55 +56 +56 +56 +54 +53 +51 +49 +46 +44 +36 +16 +1 +-11 +-20 +-27 +-32 +-35 +-38 +-39 +-39 +-37 +-37 +-35 +-34 +-33 +-23 +-2 +13 +25 +33 +38 +42 +45 +46 +46 +45 +44 +44 +42 +40 +38 +36 +34 +33 +31 +30 +28 +26 +25 +24 +23 +21 +20 +18 +17 +16 +14 +7 +-12 +-27 +-36 +-44 +-49 +-52 +-54 +-55 +-54 +-54 +-52 +-50 +-47 +-45 +-43 +-32 +-11 +5 +16 +25 +30 +34 +37 +38 +39 +39 +40 +38 +37 +36 +35 +27 +7 +-8 +-20 +-29 +-35 +-39 +-42 +-44 +-44 +-44 +-43 +-42 +-41 +-39 +-37 +-26 +-4 +11 +22 +30 +35 +38 +41 +41 +42 +40 +40 +39 +39 +37 +36 +27 +7 +-8 +-19 +-27 +-33 +-38 +-41 +-42 +-43 +-43 +-43 +-42 +-41 +-39 +-37 +-36 +-33 +-32 +-30 +-28 +-26 +-24 +-23 +-21 +-20 +-19 +-18 +-16 +-16 +-14 +-14 +-4 +17 +31 +41 +48 +53 +56 +58 +58 +58 +57 +55 +53 +51 +48 +46 +44 +41 +39 +37 +35 +33 +31 +29 +28 +27 +25 +24 +22 +21 +20 +19 +11 +-9 +-22 +-33 +-40 +-46 +-49 +-52 +-53 +-53 +-52 +-50 +-49 +-47 +-45 +-43 +-32 +-10 +5 +17 +25 +30 +34 +37 +38 +39 +38 +38 +38 +37 +35 +35 +26 +6 +-9 +-20 +-29 +-35 +-40 +-42 +-44 +-45 +-45 +-43 +-42 +-40 +-39 +-37 +-35 +-33 +-32 +-29 +-28 +-26 +-25 +-24 +-23 +-22 +-21 +-19 +-18 +-17 +-16 +-14 +-4 +16 +30 +40 +47 +52 +54 +56 +56 +55 +54 +53 +51 +49 +46 +44 +43 +40 +38 +36 +34 +32 +31 +29 +27 +25 +23 +22 +20 +19 +17 +16 +8 +-11 +-25 +-36 +-43 +-48 +-51 +-53 +-54 +-54 +-53 +-51 +-49 +-47 +-46 +-43 +-33 +-11 +4 +16 +24 +30 +34 +37 +38 +39 +40 +40 +39 +38 +37 +35 +27 +7 +-9 +-20 +-28 +-34 +-38 +-41 +-43 +-43 +-44 +-43 +-41 +-40 +-38 +-36 +-26 +-5 +10 +21 +28 +34 +37 +39 +41 +42 +41 +41 +39 +39 +37 +36 +28 +9 +-6 +-18 +-27 +-33 +-37 +-40 +-41 +-42 +-42 +-42 +-40 +-39 +-37 +-36 +-25 +-3 +12 +24 +32 +37 +41 +43 +44 +44 +43 +42 +41 +39 +37 +35 +27 +7 +-7 +-19 +-27 +-33 +-37 +-40 +-41 +-42 +-42 +-42 +-41 +-40 +-39 +-37 +-36 +-35 +-33 +-30 +-29 +-27 +-26 +-24 +-22 +-20 +-19 +-17 +-17 +-16 +-15 +-14 +-5 +16 +30 +40 +47 +51 +54 +55 +56 +56 +55 +54 +52 +51 +48 +46 +37 +17 +1 +-12 +-21 +-27 +-32 +-34 +-36 +-37 +-37 +-37 +-36 +-34 +-33 +-32 +-21 +0 +15 +26 +34 +39 +42 +44 +45 +45 +45 +45 +43 +42 +40 +38 +30 +10 +-5 +-17 +-26 +-32 +-37 +-40 +-42 +-43 +-43 +-42 +-41 +-41 +-39 +-37 +-27 +-5 +10 +22 +30 +35 +38 +41 +42 +42 +41 +40 +39 +38 +36 +36 +34 +32 +30 +29 +28 +26 +25 +23 +22 +21 +19 +18 +17 +15 +14 +13 +6 +-13 +-27 +-37 +-45 +-49 +-52 +-54 +-54 +-54 +-53 +-52 +-51 +-48 +-46 +-43 +-33 +-11 +5 +16 +24 +30 +34 +37 +39 +40 +40 +40 +40 +38 +37 +35 +27 +7 +-9 +-20 +-28 +-34 +-39 +-42 +-44 +-44 +-44 +-43 +-42 +-40 +-38 +-36 +-34 +-33 +-31 +-30 +-29 +-28 +-26 +-25 +-24 +-22 +-21 +-20 +-18 +-17 +-15 +-14 +-4 +16 +30 +40 +48 +52 +54 +55 +55 +55 +55 +53 +50 +48 +46 +45 +43 +40 +39 +37 +35 +33 +31 +28 +26 +25 +23 +21 +20 +19 +19 +18 +11 +-8 +-22 +-33 +-40 +-45 +-48 +-50 +-51 +-52 +-51 +-50 +-49 +-47 +-45 +-43 +-32 +-9 +6 +18 +26 +32 +36 +39 +40 +41 +40 +40 +38 +37 +35 +34 +26 +6 +-9 +-20 +-28 +-35 +-38 +-41 +-42 +-43 +-43 +-42 +-41 +-40 +-39 +-37 +-26 +-5 +10 +21 +29 +35 +38 +41 +42 +43 +43 +42 +41 +40 +39 +36 +28 +8 +-8 +-19 +-28 +-34 +-38 +-41 +-42 +-43 +-42 +-42 +-40 +-38 +-37 +-35 +-25 +-3 +12 +22 +29 +35 +38 +41 +42 +43 +43 +42 +41 +40 +39 +37 +29 +9 +-6 +-18 +-27 +-33 +-38 +-41 +-41 +-43 +-43 +-42 +-41 +-39 +-37 +-36 +-25 +-3 +12 +23 +31 +37 +40 +42 +43 +43 +43 +43 +42 +40 +39 +37 +29 +10 +-6 +-17 +-25 +-31 +-35 +-38 +-40 +-40 +-41 +-41 +-40 +-39 +-38 +-37 +-26 +-5 +10 +21 +28 +34 +38 +41 +41 +42 +42 +41 +39 +37 +35 +34 +25 +5 +-10 +-21 +-29 +-36 +-40 +-43 +-44 +-44 +-44 +-44 +-42 +-40 +-39 +-38 +-27 +-6 +10 +21 +28 +35 +38 +41 +42 +43 +43 +43 +42 +41 +39 +39 +30 +10 +-5 +-17 +-26 +-32 +-36 +-39 +-41 +-41 +-40 +-40 +-38 +-37 +-35 +-34 +-23 +-2 +13 +25 +33 +38 +41 +42 +43 +43 +42 +42 +41 +39 +37 +35 +28 +8 +-8 +-19 +-27 +-34 +-39 +-42 +-43 +-45 +-45 +-44 +-43 +-42 +-40 +-39 +-36 +-34 +-32 +-30 +-28 +-27 +-25 +-24 +-22 +-21 +-20 +-19 +-17 +-15 +-14 +-14 +-4 +17 +31 +41 +48 +52 +55 +57 +58 +58 +56 +53 +51 +49 +47 +45 +36 +16 +0 +-12 +-21 +-27 +-32 +-35 +-37 +-37 +-38 +-38 +-37 +-36 +-35 +-34 +-24 +-2 +13 +23 +31 +36 +40 +42 +43 +44 +43 +43 +42 +40 +39 +37 +29 +8 +-7 +-19 +-28 +-34 +-38 +-40 +-42 +-42 +-42 +-41 +-39 +-38 +-36 +-35 +-24 +-3 +12 +23 +31 +36 +39 +42 +44 +44 +43 +43 +42 +41 +39 +38 +30 +11 +-4 +-16 +-25 +-31 +-36 +-39 +-41 +-42 +-42 +-41 +-40 +-39 +-37 +-35 +-25 +-4 +11 +23 +31 +36 +40 +42 +43 +43 +43 +42 +40 +40 +37 +36 +27 +8 +-7 +-18 +-27 +-33 +-37 +-40 +-41 +-42 +-42 +-42 +-41 +-40 +-38 +-37 +-27 +-5 +10 +21 +28 +34 +37 +39 +41 +42 +41 +41 +40 +39 +37 +35 +26 +7 +-8 +-20 +-29 +-35 +-39 +-42 +-43 +-44 +-43 +-43 +-42 +-40 +-38 +-36 +-26 +-4 +10 +21 +28 +33 +36 +38 +39 +40 +39 +40 +39 +38 +36 +34 +27 +7 +-9 +-21 +-30 +-36 +-41 +-44 +-45 +-46 +-46 +-45 +-44 +-42 +-40 +-38 +-27 +-5 +10 +21 +29 +35 +39 +41 +42 +42 +42 +41 +40 +39 +38 +37 +29 +10 +-5 +-17 +-25 +-32 +-36 +-39 +-40 +-41 +-41 +-41 +-40 +-38 +-37 +-36 +-25 +-3 +12 +23 +32 +37 +40 +42 +43 +44 +44 +43 +43 +42 +40 +38 +30 +10 +-5 +-16 +-25 +-31 +-35 +-38 +-39 +-40 +-40 +-39 +-38 +-36 +-35 +-33 +-22 +-1 +14 +25 +32 +37 +41 +43 +44 +45 +44 +43 +42 +41 +40 +39 +37 +35 +33 +31 +29 +28 +25 +24 +22 +20 +19 +18 +17 +15 +14 +14 +6 +-12 +-26 +-36 +-44 +-49 +-53 +-55 +-56 +-56 +-55 +-54 +-53 +-51 +-48 +-46 +-35 +-13 +3 +15 +23 +29 +34 +36 +37 +38 +38 +37 +36 +34 +33 +31 +23 +3 +-12 +-23 +-30 +-36 +-41 +-43 +-45 +-45 +-45 +-44 +-43 +-42 +-41 +-39 +-28 +-7 +8 +20 +28 +34 +37 +40 +41 +42 +43 +42 +41 +40 +39 +37 +28 +9 +-6 +-17 +-26 +-32 +-36 +-39 +-40 +-40 +-41 +-40 +-39 +-37 +-36 +-34 +-24 +-2 +13 +24 +32 +37 +40 +42 +44 +44 +44 +44 +43 +42 +40 +38 +30 +10 +-6 +-18 +-27 +-34 +-38 +-40 +-41 +-41 +-42 +-42 +-41 +-39 +-37 +-35 +-25 +-3 +11 +21 +29 +35 +38 +40 +42 +42 +42 +42 +41 +40 +38 +37 +29 +9 +-6 +-18 +-27 +-33 +-38 +-40 +-42 +-42 +-43 +-43 +-42 +-40 +-38 +-36 +-26 +-3 +12 +24 +31 +36 +39 +41 +43 +43 +43 +42 +41 +40 +39 +38 +30 +10 +-5 +-17 +-25 +-31 +-35 +-38 +-39 +-40 +-41 +-40 +-39 +-38 +-38 +-35 +-25 +-3 +11 +23 +31 +37 +41 +43 +44 +45 +44 +43 +42 +40 +38 +36 +27 +7 +-8 +-20 +-28 +-34 +-38 +-41 +-42 +-43 +-43 +-43 +-42 +-40 +-39 +-37 +-28 +-7 +9 +20 +28 +33 +37 +40 +41 +42 +41 +41 +41 +39 +38 +37 +29 +10 +-6 +-17 +-26 +-32 +-36 +-39 +-41 +-41 +-42 +-41 +-40 +-38 +-36 +-35 +-33 +-31 +-29 +-28 +-26 +-25 +-24 +-22 +-21 +-20 +-19 +-18 +-18 +-16 +-15 +-14 +-5 +16 +30 +40 +47 +52 +54 +56 +57 +56 +54 +53 +50 +48 +46 +44 +41 +40 +38 +35 +34 +32 +30 +29 +27 +26 +25 +23 +21 +20 +18 +18 +11 +-8 +-24 +-34 +-41 +-46 +-50 +-51 +-52 +-53 +-52 +-50 +-49 +-47 +-45 +-43 +-41 +-40 +-38 +-36 +-34 +-32 +-30 +-28 +-27 +-25 +-24 +-22 +-21 +-20 +-18 +-17 +-7 +14 +28 +38 +45 +50 +52 +54 +54 +54 +53 +52 +50 +49 +47 +45 +42 +40 +38 +35 +33 +31 +28 +26 +24 +23 +21 +21 +19 +18 +16 +16 +8 +-11 +-25 +-35 +-42 +-47 +-51 +-53 +-54 +-54 +-53 +-51 +-50 +-47 +-45 +-43 +-41 +-38 +-36 +-34 +-31 +-28 +-26 +-24 +-23 +-21 +-20 +-18 +-17 +-16 +-15 +-14 +-4 +17 +31 +42 +48 +53 +56 +57 +57 +57 +56 +55 +53 +51 +49 +46 +43 +41 +38 +36 +33 +31 +29 +28 +26 +24 +23 +22 +21 +20 +18 +17 +9 +-11 +-26 +-37 +-45 +-50 +-53 +-54 +-55 +-55 +-54 +-53 +-51 +-49 +-47 +-45 +-43 +-41 +-39 +-37 +-35 +-34 +-31 +-29 +-27 +-25 +-23 +-22 +-21 +-20 +-19 +-17 +-7 +14 +28 +39 +46 +50 +52 +53 +53 +53 +52 +52 +49 +48 +46 +44 +41 +39 +38 +36 +33 +32 +30 +28 +26 +23 +22 +21 +20 +18 +17 +16 +8 +-11 +-24 +-34 +-40 +-46 +-50 +-52 +-53 +-53 +-53 +-51 +-50 +-48 +-47 +-44 +-42 +-39 +-37 +-35 +-33 +-30 +-28 +-26 +-25 +-23 +-21 +-20 +-19 +-18 +-16 +-16 +-6 +14 +29 +39 +47 +51 +53 +54 +55 +54 +54 +53 +51 +49 +46 +44 +42 +39 +36 +34 +32 +30 +28 +27 +24 +23 +22 +21 +20 +19 +18 +17 +9 +-10 +-25 +-35 +-43 +-48 +-52 +-54 +-55 +-55 +-54 +-52 +-50 +-48 +-46 +-43 +-41 +-40 +-37 +-35 +-34 +-32 +-31 +-29 +-28 +-26 +-25 +-23 +-22 +-20 +-18 +-17 +-6 +15 +29 +39 +46 +51 +54 +55 +55 +55 +54 +52 +50 +48 +47 +44 +36 +15 +-1 +-13 +-21 +-27 +-31 +-34 +-37 +-38 +-38 +-38 +-37 +-35 +-34 +-32 +-22 +0 +14 +25 +33 +39 +43 +46 +46 +47 +46 +46 +44 +42 +40 +38 +30 +10 +-5 +-16 +-25 +-30 +-35 +-37 +-39 +-40 +-40 +-38 +-38 +-37 +-35 +-33 +-23 +-2 +13 +24 +32 +38 +41 +42 +43 +43 +43 +42 +41 +41 +40 +38 +30 +9 +-6 +-18 +-27 +-33 +-37 +-40 +-42 +-43 +-43 +-42 +-41 +-40 +-38 +-35 +-24 +-3 +12 +23 +30 +35 +38 +41 +42 +42 +42 +41 +40 +39 +38 +37 +29 +10 +-5 +-17 +-25 +-31 +-35 +-38 +-40 +-42 +-42 +-42 +-40 +-39 +-38 +-36 +-25 +-4 +12 +23 +31 +37 +40 +42 +43 +44 +44 +43 +41 +39 +37 +36 +28 +8 +-7 +-18 +-27 +-33 +-37 +-40 +-41 +-42 +-42 +-41 +-40 +-39 +-38 +-36 +-27 +-5 +10 +21 +28 +34 +37 +40 +41 +42 +42 +42 +41 +39 +37 +36 +27 +7 +-7 +-19 +-28 +-34 +-39 +-41 +-43 +-43 +-43 +-42 +-41 +-39 +-38 +-36 +-26 +-4 +10 +21 +28 +34 +37 +39 +40 +42 +42 +41 +40 +39 +38 +37 +29 +10 +-6 +-18 +-27 +-33 +-38 +-40 +-42 +-42 +-41 +-41 +-41 +-40 +-39 +-37 +-26 +-4 +11 +24 +31 +37 +40 +43 +43 +43 +43 +43 +42 +41 +39 +38 +29 +10 +-5 +-16 +-24 +-30 +-35 +-38 +-39 +-40 +-41 +-41 +-40 +-38 +-37 +-35 +-25 +-3 +12 +24 +32 +38 +42 +44 +46 +46 +45 +45 +43 +42 +39 +38 +36 +35 +32 +31 +29 +27 +25 +24 +23 +22 +21 +20 +19 +17 +15 +14 +6 +-13 +-27 +-37 +-45 +-50 +-54 +-56 +-56 +-56 +-54 +-53 +-52 +-50 +-48 +-46 +-35 +-13 +2 +14 +22 +28 +31 +34 +36 +37 +36 +37 +36 +36 +34 +34 +25 +5 +-9 +-20 +-30 +-36 +-41 +-43 +-45 +-45 +-45 +-44 +-43 +-42 +-40 +-37 +-27 +-5 +11 +22 +30 +35 +38 +40 +41 +41 +41 +41 +41 +40 +38 +36 +28 +8 +-7 +-18 +-27 +-33 +-37 +-39 +-41 +-42 +-42 +-42 +-40 +-38 +-37 +-35 +-25 +-3 +12 +24 +32 +37 +41 +44 +44 +45 +44 +43 +42 +41 +39 +37 +28 +8 +-6 +-18 +-27 +-33 +-37 +-40 +-41 +-42 +-41 +-42 +-41 +-40 +-39 +-37 +-27 +-5 +10 +21 +29 +34 +38 +40 +42 +43 +43 +42 +42 +41 +38 +36 +28 +7 +-9 +-19 +-27 +-33 +-38 +-40 +-42 +-42 +-42 +-41 +-40 +-38 +-37 +-35 +-25 +-3 +11 +22 +29 +34 +37 +40 +41 +42 +42 +41 +40 +39 +38 +36 +28 +9 +-6 +-18 +-27 +-34 +-38 +-41 +-43 +-44 +-44 +-43 +-42 +-40 +-38 +-36 +-26 +-4 +11 +22 +30 +36 +39 +41 +42 +42 +42 +41 +39 +38 +37 +36 +27 +8 +-7 +-18 +-27 +-32 +-37 +-40 +-42 +-43 +-43 +-43 +-42 +-40 +-39 +-36 +-26 +-4 +11 +22 +29 +36 +39 +41 +42 +43 +42 +41 +40 +38 +37 +35 +26 +6 +-9 +-21 +-29 +-35 +-39 +-42 +-44 +-43 +-44 +-42 +-42 +-40 +-39 +-37 +-27 +-6 +9 +20 +28 +34 +38 +40 +42 +42 +42 +41 +40 +39 +38 +37 +29 +9 +-7 +-18 +-27 +-33 +-37 +-39 +-41 +-41 +-41 +-39 +-38 +-36 +-35 +-33 +-31 +-29 +-27 +-26 +-25 +-24 +-22 +-21 +-20 +-18 +-17 +-15 +-15 +-14 +-13 +-12 +-2 +20 +34 +43 +50 +54 +56 +58 +58 +58 +56 +54 +52 +52 +49 +46 +43 +41 +39 +37 +35 +33 +31 +29 +27 +25 +24 +22 +20 +19 +17 +16 +8 +-11 +-25 +-35 +-42 +-48 +-51 +-53 +-54 +-54 +-54 +-53 +-52 +-50 +-49 +-47 +-35 +-13 +3 +14 +22 +29 +33 +36 +38 +39 +39 +39 +37 +36 +34 +33 +25 +5 +-10 +-21 +-29 +-35 +-39 +-41 +-42 +-42 +-42 +-42 +-41 +-40 +-38 +-37 +-27 +-6 +9 +20 +29 +35 +38 +41 +43 +42 +42 +41 +40 +39 +38 +36 +28 +8 +-7 +-19 +-27 +-34 +-38 +-41 +-43 +-43 +-42 +-42 +-41 +-39 +-37 +-35 +-33 +-32 +-30 +-28 +-25 +-24 +-23 +-23 +-22 +-20 +-19 +-18 +-17 +-16 +-15 +-14 +-3 +18 +32 +43 +49 +53 +56 +57 +58 +58 +55 +53 +51 +49 +48 +45 +43 +41 +39 +36 +34 +32 +30 +29 +28 +27 +26 +24 +22 +20 +19 +17 +9 +-10 +-24 +-35 +-43 +-49 +-52 +-54 +-54 +-54 +-53 +-51 +-49 +-47 +-45 +-43 +-33 +-11 +5 +17 +25 +31 +34 +38 +39 +40 +40 +40 +40 +39 +37 +36 +29 +9 +-7 +-19 +-28 +-34 +-38 +-41 +-43 +-43 +-43 +-42 +-42 +-40 +-38 +-36 +-35 +-33 +-32 +-30 +-28 +-27 +-26 +-25 +-24 +-22 +-21 +-19 +-18 +-17 +-16 +-14 +-4 +17 +31 +42 +48 +53 +55 +56 +55 +55 +53 +52 +50 +48 +45 +44 +35 +16 +0 +-11 +-20 +-27 +-32 +-34 +-36 +-36 +-37 +-37 +-37 +-36 +-35 +-34 +-24 +-2 +13 +24 +32 +37 +41 +45 +45 +45 +44 +44 +42 +41 +39 +37 +36 +35 +33 +31 +28 +27 +25 +24 +22 +21 +20 +19 +18 +17 +16 +15 +6 +-13 +-28 +-38 +-46 +-52 +-55 +-56 +-57 +-56 +-56 +-54 +-53 +-50 +-47 +-45 +-43 +-41 +-39 +-37 +-35 +-33 +-31 +-30 +-28 +-26 +-24 +-21 +-19 +-18 +-17 +-16 +-6 +16 +30 +41 +48 +52 +55 +56 +56 +55 +54 +53 +51 +50 +47 +45 +43 +41 +39 +36 +35 +33 +32 +30 +27 +26 +24 +23 +20 +19 +17 +16 +9 +-11 +-25 +-36 +-43 +-48 +-52 +-53 +-55 +-54 +-53 +-51 +-50 +-47 +-45 +-43 +-31 +-9 +5 +17 +25 +31 +35 +38 +40 +41 +41 +40 +40 +39 +38 +37 +30 +10 +-6 +-17 +-26 +-32 +-37 +-40 +-42 +-43 +-43 +-42 +-41 +-39 +-37 +-36 +-34 +-32 +-30 +-28 +-27 +-25 +-24 +-22 +-21 +-20 +-20 +-18 +-18 +-16 +-15 +-14 +-4 +17 +31 +41 +48 +53 +56 +58 +58 +58 +56 +55 +52 +50 +48 +45 +43 +40 +38 +36 +35 +33 +31 +29 +28 +26 +25 +24 +22 +21 +20 +19 +11 +-7 +-22 +-34 +-42 +-47 +-50 +-51 +-52 +-53 +-53 +-51 +-49 +-48 +-45 +-43 +-32 +-10 +5 +17 +25 +31 +35 +37 +38 +39 +39 +39 +37 +36 +34 +33 +26 +5 +-9 +-20 +-28 +-33 +-37 +-41 +-42 +-43 +-44 +-43 +-41 +-41 +-39 +-38 +-37 +-34 +-31 +-29 +-27 +-26 +-23 +-22 +-21 +-19 +-17 +-16 +-14 +-13 +-13 +-12 +-3 +18 +31 +41 +48 +53 +55 +57 +57 +56 +55 +53 +52 +50 +47 +44 +42 +39 +36 +33 +32 +29 +28 +26 +23 +22 +20 +19 +17 +17 +16 +16 +8 +-11 +-26 +-36 +-45 +-50 +-54 +-55 +-57 +-56 +-55 +-54 +-52 +-50 +-48 +-44 +-42 +-39 +-37 +-34 +-32 +-31 +-30 +-28 +-26 +-25 +-23 +-22 +-20 +-18 +-17 +-16 +-6 +15 +30 +40 +47 +52 +54 +56 +56 +55 +54 +52 +50 +48 +46 +45 +36 +16 +0 +-12 +-21 +-28 +-32 +-35 +-37 +-39 +-39 +-39 +-38 +-38 +-36 +-35 +-25 +-4 +11 +23 +30 +36 +39 +42 +43 +45 +44 +43 +42 +41 +39 +37 +29 +9 +-7 +-18 +-27 +-33 +-37 +-40 +-42 +-43 +-42 +-42 +-41 +-39 +-37 +-36 +-26 +-4 +11 +22 +29 +35 +37 +40 +41 +42 +41 +42 +40 +39 +37 +36 +27 +8 +-7 +-18 +-27 +-33 +-38 +-40 +-42 +-43 +-44 +-43 +-42 +-40 +-39 +-37 +-26 +-4 +11 +22 +30 +36 +40 +42 +43 +43 +42 +41 +40 +39 +38 +36 +29 +9 +-6 +-18 +-26 +-32 +-35 +-39 +-40 +-41 +-41 +-40 +-39 +-38 +-36 +-35 +-24 +-3 +12 +24 +31 +37 +41 +43 +44 +45 +45 +44 +43 +42 +40 +38 +29 +10 +-6 +-17 +-26 +-32 +-37 +-40 +-42 +-41 +-42 +-41 +-40 +-39 +-38 +-37 +-27 +-6 +9 +20 +28 +33 +37 +40 +41 +42 +41 +41 +40 +40 +38 +36 +27 +8 +-7 +-19 +-28 +-34 +-38 +-41 +-43 +-43 +-43 +-42 +-41 +-40 +-38 +-37 +-27 +-4 +10 +21 +29 +34 +37 +39 +40 +41 +41 +40 +39 +38 +37 +35 +28 +8 +-7 +-18 +-27 +-33 +-37 +-40 +-42 +-42 +-42 +-41 +-41 +-39 +-37 +-34 +-24 +-2 +13 +24 +32 +38 +42 +44 +45 +46 +45 +44 +42 +41 +39 +38 +29 +9 +-7 +-17 +-25 +-31 +-36 +-40 +-41 +-42 +-42 +-42 +-41 +-40 +-38 +-37 +-27 +-5 +10 +21 +29 +34 +38 +40 +42 +42 +42 +42 +41 +40 +38 +36 +35 +34 +31 +30 +27 +26 +24 +23 +21 +20 +18 +18 +17 +16 +15 +14 +7 +-11 +-26 +-37 +-45 +-51 +-54 +-56 +-57 +-57 +-56 +-54 +-52 +-50 +-48 +-45 +-35 +-12 +3 +15 +23 +29 +34 +36 +38 +38 +39 +38 +37 +36 +34 +33 +26 +6 +-9 +-20 +-28 +-34 +-38 +-40 +-42 +-43 +-43 +-43 +-41 +-40 +-38 +-38 +-27 +-6 +9 +20 +29 +35 +39 +41 +43 +43 +43 +42 +41 +39 +36 +35 +26 +7 +-8 +-20 +-28 +-34 +-38 +-40 +-41 +-42 +-42 +-42 +-41 +-39 +-38 +-36 +-26 +-5 +9 +21 +30 +36 +39 +42 +43 +44 +44 +43 +42 +42 +40 +38 +29 +9 +-7 +-18 +-27 +-34 +-38 +-41 +-42 +-43 +-43 +-43 +-42 +-40 +-38 +-36 +-26 +-4 +11 +22 +30 +36 +38 +41 +41 +41 +42 +42 +40 +39 +38 +36 +28 +9 +-6 +-17 +-26 +-32 +-37 +-39 +-41 +-42 +-43 +-42 +-41 +-40 +-38 +-36 +-26 +-4 +10 +21 +30 +35 +39 +42 +42 +43 +42 +41 +40 +39 +37 +35 +26 +6 +-9 +-20 +-29 +-34 +-39 +-41 +-42 +-43 +-42 +-42 +-41 +-40 +-38 +-37 +-27 +-5 +9 +21 +29 +35 +37 +40 +41 +41 +41 +41 +40 +39 +38 +37 +28 +8 +-7 +-19 +-28 +-35 +-39 +-42 +-43 +-44 +-44 +-43 +-41 +-40 +-38 +-36 +-25 +-3 +12 +23 +31 +36 +39 +42 +43 +44 +44 +43 +41 +40 +38 +37 +29 +9 +-6 +-17 +-26 +-32 +-36 +-39 +-40 +-42 +-42 +-42 +-41 +-39 +-38 +-37 +-26 +-4 +11 +24 +32 +37 +40 +43 +44 +44 +44 +43 +41 +40 +38 +37 +29 +9 +-6 +-18 +-26 +-32 +-36 +-39 +-40 +-40 +-40 +-40 +-39 +-37 +-37 +-35 +-34 +-32 +-31 +-29 +-27 +-26 +-24 +-22 +-21 +-20 +-18 +-17 +-15 +-14 +-13 +-13 +-3 +17 +30 +40 +48 +51 +54 +55 +55 +54 +53 +52 +50 +49 +47 +45 +36 +17 +1 +-11 +-21 +-27 +-33 +-35 +-38 +-39 +-39 +-38 +-38 +-36 +-35 +-33 +-22 +0 +14 +26 +34 +40 +43 +45 +45 +46 +45 +45 +43 +42 +40 +39 +30 +10 +-5 +-16 +-24 +-30 +-35 +-38 +-39 +-40 +-41 +-41 +-40 +-39 +-38 +-36 +-25 +-4 +11 +23 +31 +36 +40 +42 +43 +44 +44 +43 +41 +39 +37 +36 +27 +7 +-8 +-20 +-29 +-35 +-39 +-42 +-43 +-43 +-43 +-43 +-41 +-40 +-39 +-37 +-27 +-6 +9 +20 +28 +34 +37 +40 +41 +41 +41 +41 +40 +39 +38 +37 +28 +8 +-7 +-18 +-28 +-34 +-38 +-41 +-43 +-43 +-44 +-42 +-42 +-40 +-39 +-37 +-26 +-4 +11 +22 +30 +36 +39 +41 +42 +42 +42 +41 +40 +39 +38 +37 +29 +10 +-6 +-17 +-25 +-31 +-35 +-38 +-40 +-41 +-42 +-41 +-40 +-38 +-37 +-36 +-25 +-3 +12 +23 +31 +36 +39 +42 +44 +44 +44 +44 +42 +41 +39 +37 +29 +9 +-6 +-17 +-26 +-32 +-36 +-39 +-40 +-40 +-40 +-39 +-38 +-36 +-35 +-33 +-23 +-2 +13 +24 +32 +37 +41 +43 +44 +44 +44 +44 +43 +42 +40 +38 +30 +10 +-6 +-17 +-26 +-32 +-37 +-39 +-41 +-42 +-43 +-42 +-41 +-39 +-38 +-36 +-26 +-3 +11 +23 +31 +37 +39 +42 +42 +42 +42 +41 +39 +38 +37 +36 +28 +8 +-7 +-18 +-27 +-32 +-36 +-39 +-41 +-42 +-43 +-43 +-43 +-42 +-41 +-39 +-28 +-7 +7 +19 +27 +33 +36 +39 +40 +41 +40 +40 +38 +37 +35 +33 +32 +30 +29 +27 +26 +25 +23 +22 +20 +19 +19 +18 +18 +17 +18 +16 +9 +-10 +-25 +-35 +-43 +-48 +-52 +-53 +-54 +-53 +-52 +-51 +-49 +-47 +-45 +-43 +-31 +-9 +5 +17 +25 +30 +35 +37 +38 +38 +38 +37 +37 +36 +35 +33 +25 +6 +-9 +-20 +-28 +-35 +-39 +-43 +-44 +-45 +-45 +-45 +-44 +-42 +-41 +-39 +-27 +-5 +9 +21 +28 +34 +38 +41 +42 +43 +42 +41 +40 +38 +37 +35 +28 +7 +-7 +-19 +-27 +-33 +-37 +-39 +-41 +-41 +-41 +-40 +-40 +-39 +-37 +-36 +-26 +-4 +11 +23 +30 +36 +38 +41 +43 +43 +43 +42 +41 +40 +38 +36 +27 +8 +-7 +-19 +-28 +-33 +-38 +-41 +-43 +-44 +-43 +-42 +-42 +-40 +-39 +-37 +-26 +-4 +10 +21 +29 +34 +37 +39 +40 +41 +41 +40 +39 +38 +37 +36 +28 +8 +-6 +-18 +-27 +-33 +-37 +-40 +-41 +-43 +-43 +-43 +-42 +-40 +-39 +-37 +-27 +-5 +11 +22 +29 +35 +38 +40 +40 +41 +40 +40 +39 +38 +36 +35 +26 +6 +-8 +-19 +-27 +-33 +-37 +-40 +-42 +-43 +-44 +-43 +-42 +-41 +-38 +-36 +-26 +-4 +11 +22 +30 +36 +40 +42 +43 +44 +44 +43 +42 +41 +39 +38 +29 +9 +-6 +-18 +-27 +-33 +-37 +-39 +-41 +-41 +-41 +-41 +-40 +-39 +-38 +-37 +-26 +-5 +10 +21 +29 +34 +38 +40 +42 +42 +42 +42 +41 +40 +38 +37 +28 +9 +-6 +-18 +-27 +-34 +-39 +-41 +-43 +-44 +-43 +-43 +-41 +-40 +-38 +-36 +-26 +-4 +11 +22 +30 +35 +39 +41 +41 +41 +41 +40 +38 +37 +35 +34 +26 +7 +-8 +-19 +-28 +-34 +-38 +-41 +-42 +-43 +-43 +-43 +-42 +-41 +-39 +-37 +-27 +-4 +10 +22 +30 +36 +39 +42 +43 +45 +44 +44 +42 +42 +40 +38 +29 +10 +-6 +-17 +-27 +-32 +-36 +-39 +-40 +-41 +-41 +-39 +-38 +-37 +-36 +-34 +-24 +-3 +12 +24 +32 +37 +40 +42 +44 +44 +44 +43 +42 +41 +39 +38 +30 +11 +-5 +-17 +-25 +-32 +-36 +-40 +-42 +-43 +-42 +-41 +-40 +-39 +-37 +-36 +-33 +-32 +-30 +-28 +-26 +-24 +-23 +-22 +-21 +-20 +-19 +-18 +-16 +-15 +-15 +-14 +-4 +16 +30 +41 +48 +53 +57 +58 +57 +57 +55 +53 +51 +49 +46 +44 +35 +15 +-1 +-12 +-22 +-28 +-33 +-36 +-37 +-38 +-38 +-38 +-37 +-37 +-36 +-34 +-24 +-3 +12 +23 +31 +36 +40 +42 +43 +43 +43 +42 +41 +39 +38 +36 +34 +31 +29 +28 +26 +25 +24 +22 +21 +20 +19 +17 +17 +16 +15 +15 +7 +-11 +-26 +-36 +-44 +-49 +-52 +-54 +-55 +-54 +-53 +-51 +-50 +-48 +-45 +-42 +-31 +-9 +7 +18 +26 +31 +35 +37 +39 +40 +39 +39 +38 +38 +37 +35 +27 +7 +-8 +-19 +-28 +-34 +-38 +-41 +-43 +-44 +-45 +-44 +-43 +-41 +-39 +-37 +-27 +-4 +11 +22 +30 +36 +40 +42 +43 +43 +42 +42 +40 +39 +38 +36 +28 +8 +-7 +-18 +-27 +-32 +-37 +-39 +-40 +-41 +-41 +-40 +-40 +-38 +-37 +-36 +-34 +-32 +-31 +-29 +-27 +-25 +-24 +-22 +-20 +-18 +-17 +-15 +-15 +-13 +-12 +-11 +-1 +19 +33 +42 +49 +54 +57 +58 +58 +58 +57 +55 +53 +51 +50 +48 +46 +43 +41 +38 +36 +33 +31 +29 +27 +25 +23 +22 +20 +19 +17 +17 +10 +-9 +-23 +-35 +-43 +-48 +-52 +-54 +-55 +-56 +-55 +-54 +-52 +-50 +-48 +-46 +-34 +-12 +4 +15 +23 +30 +34 +37 +38 +39 +39 +38 +37 +36 +34 +32 +25 +5 +-9 +-21 +-29 +-35 +-39 +-42 +-43 +-43 +-42 +-41 +-40 +-39 +-38 +-35 +-34 +-32 +-31 +-29 +-28 +-27 +-26 +-24 +-22 +-20 +-19 +-17 +-16 +-14 +-14 +-12 +-3 +18 +31 +41 +48 +52 +54 +56 +57 +57 +55 +54 +52 +51 +48 +47 +44 +42 +40 +38 +36 +34 +32 +30 +27 +26 +23 +21 +20 +19 +18 +17 +9 +-10 +-25 +-35 +-43 +-47 +-50 +-52 +-53 +-53 +-52 +-50 +-49 +-48 +-46 +-43 +-32 +-10 +5 +17 +26 +31 +36 +38 +40 +40 +40 +40 +38 +37 +35 +34 +25 +6 +-9 +-20 +-28 +-35 +-39 +-41 +-42 +-43 +-43 +-43 +-42 +-41 +-40 +-39 +-28 +-6 +8 +19 +27 +32 +36 +38 +39 +39 +39 +38 +38 +37 +36 +35 +27 +7 +-8 +-20 +-29 +-36 +-41 +-44 +-45 +-46 +-46 +-44 +-43 +-42 +-41 +-39 +-28 +-6 +10 +21 +29 +35 +38 +40 +41 +42 +41 +41 +40 +39 +37 +36 +27 +8 +-6 +-17 +-26 +-32 +-36 +-39 +-41 +-42 +-42 +-41 +-41 +-40 +-38 +-36 +-34 +-32 +-31 +-28 +-27 +-25 +-23 +-21 +-19 +-18 +-17 +-15 +-15 +-14 +-13 +-13 +-3 +18 +32 +42 +49 +54 +57 +58 +59 +59 +57 +56 +53 +51 +48 +46 +37 +17 +1 +-11 +-21 +-28 +-32 +-35 +-37 +-38 +-38 +-37 +-36 +-35 +-34 +-33 +-23 +-2 +13 +24 +31 +36 +39 +42 +42 +43 +42 +42 +40 +40 +38 +37 +28 +8 +-8 +-19 +-28 +-34 +-38 +-41 +-42 +-43 +-43 +-42 +-41 +-40 +-38 +-36 +-25 +-3 +12 +23 +31 +36 +39 +42 +42 +42 +42 +42 +40 +39 +37 +36 +35 +33 +32 +30 +29 +28 +27 +25 +23 +22 +20 +19 +17 +16 +15 +15 +7 +-11 +-26 +-36 +-44 +-48 +-51 +-53 +-54 +-54 +-53 +-51 +-50 +-48 +-46 +-44 +-33 +-11 +4 +16 +24 +31 +35 +37 +38 +40 +40 +40 +38 +38 +37 +34 +26 +5 +-10 +-21 +-29 +-35 +-39 +-41 +-43 +-43 +-44 +-43 +-42 +-40 +-39 +-37 +-36 +-34 +-33 +-32 +-30 +-27 +-26 +-25 +-23 +-22 +-20 +-19 +-17 +-16 +-15 +-14 +-5 +16 +30 +39 +45 +50 +52 +53 +54 +53 +53 +51 +50 +48 +46 +44 +42 +40 +37 +35 +34 +32 +30 +28 +27 +25 +23 +21 +20 +19 +18 +17 +10 +-9 +-23 +-34 +-41 +-47 +-50 +-52 +-53 +-54 +-53 +-53 +-51 +-49 +-47 +-45 +-33 +-12 +4 +15 +24 +30 +34 +38 +39 +39 +38 +38 +36 +36 +34 +33 +26 +6 +-9 +-21 +-29 +-35 +-39 +-41 +-43 +-43 +-44 +-44 +-43 +-42 +-40 +-37 +-27 +-5 +9 +20 +28 +35 +39 +42 +43 +43 +43 +42 +41 +40 +37 +36 +27 +7 +-8 +-19 +-27 +-33 +-37 +-40 +-41 +-42 +-41 +-40 +-40 +-39 +-38 +-36 +-26 +-5 +10 +21 +28 +33 +37 +40 +41 +42 +42 +41 +40 +39 +38 +36 +28 +9 +-7 +-19 +-27 +-34 +-38 +-40 +-42 +-42 +-42 +-42 +-40 +-39 +-37 +-35 +-24 +-3 +12 +23 +30 +36 +39 +42 +43 +43 +42 +42 From 65f7d8cac98196638bc059aaad4aab4c21b0dc13 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 17 Oct 2019 23:05:15 +0200 Subject: [PATCH 1011/1854] add: 'script run init_rdv4' - lua script to help setup your RDV4 initally --- client/luascripts/init_rdv4.lua | 96 +++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 client/luascripts/init_rdv4.lua diff --git a/client/luascripts/init_rdv4.lua b/client/luascripts/init_rdv4.lua new file mode 100644 index 000000000..4836cda77 --- /dev/null +++ b/client/luascripts/init_rdv4.lua @@ -0,0 +1,96 @@ +local getopt = require('getopt') + +copyright = 'Copyright (c) 2019 IceSQL AB. All rights reserved.' +author = 'Christian Herrmann' +version = 'v1.0.0' +desc = [[ +This script initialize a Proxmark3 RDV4.0 with + - uploading dictionary files to flashmem + - configuring the LF T55X7 device settings + ]] +example = [[ + + script run init_rdv4 +]] +usage = [[ +script run init_rdv4 -h + +Arguments: + -h : this help +]] + +local DEBUG = true +--- +-- A debug printout-function +local function dbg(args) + if not DEBUG then return end + if type(args) == 'table' then + local i = 1 + while args[i] do + dbg(args[i]) + i = i+1 + end + else + print('###', args) + end +end +--- +-- This is only meant to be used when errors occur +local function oops(err) + print('ERROR:', err) + core.clearCommandBuffer() + return nil, err +end +--- +-- Usage help +local function help() + print(copyright) + print(author) + print(version) + print(desc) + print('Example usage') + print(example) + print(usage) +end +--- +-- The main entry point +function main(args) + local dash = string.rep('--', 20) + + print( dash ) + print( dash ) + print() + + -- Read the parameters + for o, a in getopt.getopt(args, 'h') do + if o == 'h' then return help() end + end + + print('Prepping your Proxmark3 RDV4') + + -- Upload dictionaries + print('Uploading dictionaries to RDV4 flashmemory') + print(dash) + core.console('mem load f mfc_default_keys m') + core.console('mem load f t55xx_default_pwds t') + core.console('mem load f iclass_default_keys i') + print(dash) + + -- T55x7 Device configuration + print('Configure T55XX device side to match RDV4') + print(dash) + core.console('lf t55xx deviceconfig r 0 a 29 b 17 c 15 d 47 e 15 p') + core.console('lf t55xx deviceconfig r 1 a 29 b 17 c 18 d 50 e 15 p') + core.console('lf t55xx deviceconfig r 2 a 29 b 17 c 18 d 40 e 15 p') + core.console('lf t55xx deviceconfig r 3 a 29 b 17 c 15 d 31 e 15 f 47 g 63 p') + + print('') + print('') + core.console('hw status') + print(dash) + + print('all done!') + +end + +main(args) From 5fcb5f0ca5fa868664dc3495086ae1e17f1eed0c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 18 Oct 2019 12:46:20 +0200 Subject: [PATCH 1012/1854] coverity 226278 --- armsrc/appmain.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 3b6976819..35838ffab 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1591,7 +1591,7 @@ static void PacketReceived(PacketCommandNG *packet) { uint16_t offset = MIN(BIGBUF_SIZE - PM3_CMD_DATA_SIZE - 3, payload->offset); uint8_t *mem = BigBuf_get_addr(); - memcpy(mem + offset, &payload->data, PM3_CMD_DATA_SIZE - 3); + memcpy(mem + offset, &payload->data, PM3_CMD_DATA_SIZE - 3 - offset); reply_ng(CMD_LF_UPLOAD_SIM_SAMPLES, PM3_SUCCESS, NULL, 0); break; } From 39fd6b1910daff03811d4a4e5da70068250d8605 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 18 Oct 2019 16:58:24 +0200 Subject: [PATCH 1013/1854] coverity: separate crypto1 fcts ARM<>host into create/destroy and init/deinit --- armsrc/Standalone/hf_colin.c | 6 +++--- armsrc/Standalone/hf_mattyrun.c | 4 ++-- armsrc/mifarecmd.c | 18 ++++++++--------- armsrc/mifaresim.c | 6 +++--- armsrc/mifareutil.c | 4 ++-- common/crapto1/crapto1.c | 7 ++++++- common/crapto1/crapto1.h | 12 ++++++----- common/crapto1/crypto1.c | 35 ++++++++++++++++----------------- 8 files changed, 49 insertions(+), 43 deletions(-) diff --git a/armsrc/Standalone/hf_colin.c b/armsrc/Standalone/hf_colin.c index 6a0d9a19d..8efcb1003 100644 --- a/armsrc/Standalone/hf_colin.c +++ b/armsrc/Standalone/hf_colin.c @@ -857,7 +857,7 @@ int e_MifareECardLoad(uint32_t numofsectors, uint8_t keytype) { DbprintfEx(FLAG_NEWLINE, "Halt error"); }; - crypto1_destroy(pcs); + crypto1_deinit(pcs); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); @@ -894,12 +894,12 @@ int cjat91_saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace, ui SpinDelayUs(AUTHENTICATION_TIMEOUT); continue; } - crypto1_destroy(pcs); + crypto1_deinit(pcs); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); *key = ui64Key; return i; } - crypto1_destroy(pcs); + crypto1_deinit(pcs); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); return -1; diff --git a/armsrc/Standalone/hf_mattyrun.c b/armsrc/Standalone/hf_mattyrun.c index bf13a39c0..9fff4a226 100644 --- a/armsrc/Standalone/hf_mattyrun.c +++ b/armsrc/Standalone/hf_mattyrun.c @@ -195,12 +195,12 @@ static int saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace, ui SpinDelayUs(AUTHENTICATION_TIMEOUT); continue; } - crypto1_destroy(pcs); + crypto1_deinit(pcs); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); *key = ui64Key; return i; } - crypto1_destroy(pcs); + crypto1_deinit(pcs); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); return -1; diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index b0b7c95ab..f5e3fe961 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -103,7 +103,7 @@ void MifareReadBlock(uint8_t blockNo, uint8_t keyType, uint8_t *datain) { break; } - crypto1_destroy(pcs); + crypto1_deinit(pcs); if (DBGLEVEL >= 2) DbpString("READ BLOCK FINISHED"); @@ -264,7 +264,7 @@ void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t *datain) { if (DBGLEVEL >= 2) DbpString("READ SECTOR FINISHED"); - crypto1_destroy(pcs); + crypto1_deinit(pcs); LED_B_ON(); reply_old(CMD_ACK, isOK, 0, 0, dataoutbuf, 16 * NumBlocksPerSector(sectorNo)); @@ -430,7 +430,7 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain) { break; } - crypto1_destroy(pcs); + crypto1_deinit(pcs); if (DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED"); @@ -847,7 +847,7 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, } LED_C_OFF(); - crypto1_destroy(pcs); + crypto1_deinit(pcs); LED_B_ON(); reply_old(CMD_ACK, isOK, cuid, num_nonces, buf, sizeof(buf)); LED_B_OFF(); @@ -1061,7 +1061,7 @@ void MifareNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8 LED_C_OFF(); - crypto1_destroy(pcs); + crypto1_deinit(pcs); struct p { int16_t isOK; @@ -1510,7 +1510,7 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da OUT: LEDsoff(); - crypto1_destroy(pcs); + crypto1_deinit(pcs); // All keys found, send to client, or last keychunk from client if (foundkeys == allkeys || lastchunk) { @@ -1660,7 +1660,7 @@ void MifareChkKeys(uint8_t *datain) { LEDsoff(); set_tracing(false); - crypto1_destroy(pcs); + crypto1_deinit(pcs); } //----------------------------------------------------------------------------- @@ -1780,7 +1780,7 @@ int MifareECardLoad(uint8_t numSectors, uint8_t keyType) { if (DBGLEVEL >= DBG_INFO) DbpString("Emulator fill sectors finished"); out: - crypto1_destroy(pcs); + crypto1_deinit(pcs); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); set_tracing(false); @@ -2110,7 +2110,7 @@ void MifareSetMod(uint8_t *datain) { break; } - crypto1_destroy(pcs); + crypto1_deinit(pcs); LED_B_ON(); reply_ng(CMD_HF_MIFARE_SETMOD, isOK, NULL, 0); diff --git a/armsrc/mifaresim.c b/armsrc/mifaresim.c index cdd8b556d..b055be6c7 100644 --- a/armsrc/mifaresim.c +++ b/armsrc/mifaresim.c @@ -571,7 +571,7 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1 EmSendPrecompiledCmd(&responses[ATQA]); // init crypto block - crypto1_destroy(pcs); + crypto1_deinit(pcs); cardAUTHKEY = AUTHKEYNONE; nonce = prng_successor(selTimer, 32); // prepare NT for nested authentication @@ -743,10 +743,10 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1 if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] KEY %c: %012" PRIx64, (cardAUTHKEY == 0) ? 'A' : 'B', emlGetKey(cardAUTHSC, cardAUTHKEY)); // first authentication - crypto1_destroy(pcs); + crypto1_deinit(pcs); // Load key into crypto - crypto1_create(pcs, emlGetKey(cardAUTHSC, cardAUTHKEY)); + crypto1_init(pcs, emlGetKey(cardAUTHSC, cardAUTHKEY)); if (!encrypted_data) { // Receive Cmd in clear txt diff --git a/armsrc/mifareutil.c b/armsrc/mifareutil.c index ca112f1f8..e36199bac 100644 --- a/armsrc/mifareutil.c +++ b/armsrc/mifareutil.c @@ -149,10 +149,10 @@ int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockN // ----------------------------- crypto1 create if (isNested) - crypto1_destroy(pcs); + crypto1_deinit(pcs); // Init cipher with key - crypto1_create(pcs, ui64Key); + crypto1_init(pcs, ui64Key); if (isNested == AUTH_NESTED) { // decrypt nt with help of new key diff --git a/common/crapto1/crapto1.c b/common/crapto1/crapto1.c index 66af2f41c..43e45c3db 100644 --- a/common/crapto1/crapto1.c +++ b/common/crapto1/crapto1.c @@ -124,6 +124,9 @@ recover(uint32_t *o_head, uint32_t *o_tail, uint32_t oks, return sl; } + + +#if !defined(__arm__) || defined(__linux__) || defined(_WIN32) || defined(__APPLE__) // bare metal ARM Proxmark lacks malloc()/free() /** lfsr_recovery * recover the state of the lfsr given 32 bits of the keystream * additionally you can use the in parameter to specify the value @@ -286,6 +289,7 @@ continue2: } return statelist; } +#endif /** lfsr_rollback_bit * Rollback the shift register in order to get previous states @@ -465,7 +469,7 @@ static struct Crypto1State *check_pfx_parity(uint32_t prefix, uint32_t rresp, ui return sl + good; } - +#if !defined(__arm__) || defined(__linux__) || defined(_WIN32) || defined(__APPLE__) // bare metal ARM Proxmark lacks malloc()/free() /** lfsr_common_prefix * Implentation of the common prefix attack. * Requires the 28 bit constant prefix used as reader nonce (pfx) @@ -504,3 +508,4 @@ out: free(even); return statelist; } +#endif diff --git a/common/crapto1/crapto1.h b/common/crapto1/crapto1.h index ab061e2e7..7fa16539e 100644 --- a/common/crapto1/crapto1.h +++ b/common/crapto1/crapto1.h @@ -25,23 +25,25 @@ #include struct Crypto1State {uint32_t odd, even;}; -#if defined(__arm__) && !defined(__linux__) && !defined(_WIN32) && !defined(__APPLE__) // bare metal ARM Proxmark lacks malloc()/free() -void crypto1_create(struct Crypto1State *s, uint64_t key); -#else +void crypto1_init(struct Crypto1State *s, uint64_t key); +void crypto1_deinit(struct Crypto1State *); +#if !defined(__arm__) || defined(__linux__) || defined(_WIN32) || defined(__APPLE__) // bare metal ARM Proxmark lacks malloc()/free() struct Crypto1State *crypto1_create(uint64_t key); -#endif void crypto1_destroy(struct Crypto1State *); +#endif void crypto1_get_lfsr(struct Crypto1State *, uint64_t *); uint8_t crypto1_bit(struct Crypto1State *, uint8_t, int); uint8_t crypto1_byte(struct Crypto1State *, uint8_t, int); uint32_t crypto1_word(struct Crypto1State *, uint32_t, int); uint32_t prng_successor(uint32_t x, uint32_t n); +#if !defined(__arm__) || defined(__linux__) || defined(_WIN32) || defined(__APPLE__) // bare metal ARM Proxmark lacks malloc()/free() struct Crypto1State *lfsr_recovery32(uint32_t ks2, uint32_t in); struct Crypto1State *lfsr_recovery64(uint32_t ks2, uint32_t ks3); -uint32_t *lfsr_prefix_ks(uint8_t ks[8], int isodd); struct Crypto1State * lfsr_common_prefix(uint32_t pfx, uint32_t rr, uint8_t ks[8], uint8_t par[8][8], uint32_t no_par); +#endif +uint32_t *lfsr_prefix_ks(uint8_t ks[8], int isodd); uint8_t lfsr_rollback_bit(struct Crypto1State *s, uint32_t in, int fb); diff --git a/common/crapto1/crypto1.c b/common/crapto1/crypto1.c index 9df30b356..bb501cd58 100644 --- a/common/crapto1/crypto1.c +++ b/common/crapto1/crypto1.c @@ -25,38 +25,37 @@ #define SWAPENDIAN(x)\ (x = (x >> 8 & 0xff00ff) | (x & 0xff00ff) << 8, x = x >> 16 | x << 16) -#if defined(__arm__) && !defined(__linux__) && !defined(_WIN32) && !defined(__APPLE__) // bare metal ARM Proxmark lacks malloc()/free() -void crypto1_create(struct Crypto1State *s, uint64_t key) { +void crypto1_init(struct Crypto1State *state, uint64_t key) { + state->odd = 0; + state->even = 0; + int i; - for (i = 47; s && i > 0; i -= 2) { - s->odd = s->odd << 1 | BIT(key, (i - 1) ^ 7); - s->even = s->even << 1 | BIT(key, i ^ 7); + for (i = 47; state && i > 0; i -= 2) { + state->odd = state->odd << 1 | BIT(key, (i - 1) ^ 7); + state->even = state->even << 1 | BIT(key, i ^ 7); } return; } -void crypto1_destroy(struct Crypto1State *state) { + +void crypto1_deinit(struct Crypto1State *state) { state->odd = 0; state->even = 0; } -#else + +#if !defined(__arm__) || defined(__linux__) || defined(_WIN32) || defined(__APPLE__) // bare metal ARM Proxmark lacks malloc()/free() struct Crypto1State *crypto1_create(uint64_t key) { - struct Crypto1State *s = malloc(sizeof(*s)); - if (!s) return NULL; - - s->odd = s->even = 0; - - int i; - for (i = 47; i > 0; i -= 2) { - s->odd = s->odd << 1 | BIT(key, (i - 1) ^ 7); - s->even = s->even << 1 | BIT(key, i ^ 7); - } - return s; + struct Crypto1State *state = malloc(sizeof(*state)); + if (!state) return NULL; + crypto1_init(state, key); + return state; } + void crypto1_destroy(struct Crypto1State *state) { free(state); } #endif + void crypto1_get_lfsr(struct Crypto1State *state, uint64_t *lfsr) { int i; for (*lfsr = 0, i = 23; i >= 0; --i) { From 6ba85af19943f12cb6dcd470df813f7993d967f1 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 18 Oct 2019 22:42:56 +0200 Subject: [PATCH 1014/1854] quick fix for felica, we can't leave repo broken so long... --- armsrc/felica.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/armsrc/felica.c b/armsrc/felica.c index ab22bc778..2b2b72201 100644 --- a/armsrc/felica.c +++ b/armsrc/felica.c @@ -756,6 +756,8 @@ void felica_sim_lite(uint64_t uid) { DbpString("Felica Lite-S sim end"); } +#define RES_SVC_LEN 11 + void felica_dump() { uint8_t ndef[8]; uint8_t poll[10] = { 0xb2, 0x4d, 0x06, FELICA_POLL_REQ, 0xff, 0xff, 0x00, 0x00, 0x09, 0x21}; // B24D0600FFFF00000921 @@ -774,9 +776,8 @@ void felica_dump() { } void felica_send_request_service(uint8_t *request_service) { - uint8_t len = sizeof(request_service) / sizeof((request_service)[0]); - Dbprintf("Send Service Request - len: d%", len); - TransmitFor18092_AsReader(request_service, len, NULL, 1, 0); + Dbprintf("Send Service Request - len: d%", RES_SVC_LEN); + TransmitFor18092_AsReader(request_service, RES_SVC_LEN, NULL, 1, 0); if (WaitForFelicaReply(512) && FelicaFrame.framebytes[3] == FELICA_REQSRV_ACK) { Dbprintf("Got Service Response!"); } @@ -793,7 +794,7 @@ uint8_t *felica_create_request_service_frame(uint8_t nodeNumber, uint8_t *idm) { nodeNumber = 1; } // Sync 2-Byte, Length 1-Byte, CMD 1-Byte, IDm 8-Byte, nodeNumber 1 <= n <= 32 1-Byte, Node Code List - uint8_t *request_service = BigBuf_malloc(sizeof(uint8_t) * 11); + uint8_t *request_service = BigBuf_malloc(sizeof(uint8_t) * RES_SVC_LEN); //{ 0xb2, 0x4d, 0x06, FELICA_REQSRV_REQ, 0xff, 0xff, 0x00, 0x00, 0x09, 0x21}; request_service[0] = 0xb2; //Sync request_service[1] = 0x4d; //Sync From f094e8fd508c02ec6cf53563e697a51b719c0379 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 19 Oct 2019 13:13:00 +0200 Subject: [PATCH 1015/1854] Add - automatic try LF and HF search and if both fail, try lf read and save a trace file --- client/cmddata.c | 2 +- client/cmddata.h | 1 + client/cmdmain.c | 73 ++++++++++++++++++++++++++++++++++++++---------- 3 files changed, 61 insertions(+), 15 deletions(-) diff --git a/client/cmddata.c b/client/cmddata.c index 9bd18eb90..80c3bf076 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -1872,7 +1872,7 @@ int CmdPlot(const char *Cmd) { return PM3_SUCCESS; } -static int CmdSave(const char *Cmd) { +int CmdSave(const char *Cmd) { int len = 0; char filename[FILE_PATH_SIZE] = {0x00}; diff --git a/client/cmddata.h b/client/cmddata.h index a453fafb1..a4bba407c 100644 --- a/client/cmddata.h +++ b/client/cmddata.h @@ -53,6 +53,7 @@ int CmdHpf(const char *Cmd); int CmdLtrim(const char *Cmd); // used by cmd lf em4x, lf t55xx int CmdNorm(const char *Cmd); // used by cmd lf data (!) int CmdPlot(const char *Cmd); // used by cmd lf cotag +int CmdSave(const char *Cmd); // used by cmd auto int CmdTuneSamples(const char *Cmd); // used by cmd lf hw int ASKbiphaseDemod(const char *Cmd, bool verbose); // used by cmd lf em4x, lf fdx, lf guard, lf jablotron, lf nedap, lf t55xx int ASKDemod(const char *Cmd, bool verbose, bool emSearch, uint8_t askType); // used by cmd lf em4x, lf t55xx, lf viking diff --git a/client/cmdmain.c b/client/cmdmain.c index 5a2c91904..802d09fa9 100644 --- a/client/cmdmain.c +++ b/client/cmdmain.c @@ -18,6 +18,7 @@ #include #include #include // MingW +#include // calloc #include "comms.h" #include "cmdhf.h" @@ -38,20 +39,6 @@ static int CmdHelp(const char *Cmd); -int CmdRem(const char *Cmd) { - char buf[22] = {0}; - struct tm *ct, tm_buf; - time_t now = time(NULL); -#if defined(_WIN32) - ct = gmtime_s(&tm_buf, &now) == 0 ? &tm_buf : NULL; -#else - ct = gmtime_r(&now, &tm_buf); -#endif - strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%SZ", ct); // ISO8601 - PrintAndLogEx(NORMAL, "%s remark: %s", buf, Cmd); - return PM3_SUCCESS; -} - static int usage_msleep(void) { PrintAndLogEx(NORMAL, "Sleep for given amount of milliseconds"); PrintAndLogEx(NORMAL, ""); @@ -65,6 +52,63 @@ static int usage_msleep(void) { return PM3_SUCCESS; } +static int usage_auto(void) { + PrintAndLogEx(NORMAL, "Run LF SEARCH / HF SEARCH / DATA PLOT / DATA SAVE "); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Usage: auto "); + PrintAndLogEx(NORMAL, "Options:"); + PrintAndLogEx(NORMAL, " h This help"); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Examples:"); + PrintAndLogEx(NORMAL, " auto"); + return PM3_SUCCESS; +} + +static void AppendDate(char *s, size_t slen, char *fmt) { + struct tm *ct, tm_buf; + time_t now = time(NULL); +#if defined(_WIN32) + ct = gmtime_s(&tm_buf, &now) == 0 ? &tm_buf : NULL; +#else + ct = gmtime_r(&now, &tm_buf); +#endif + if (fmt == NULL) + strftime(s, slen, "%Y-%m-%dT%H:%M:%SZ", ct); // ISO8601 + else + strftime(s, slen, fmt, ct); +} + +static int CmdAuto(const char *Cmd) { + char ctmp = tolower(param_getchar(Cmd, 0)); + if (ctmp == 'h') return usage_auto(); + + int ret = CmdLFfind(""); + if (ret == PM3_SUCCESS) + return ret; + + ret = CmdHFSearch(""); + if (ret == PM3_SUCCESS) + return ret; + + PrintAndLogEx(INFO, "Failed both LF / HF SEARCH,"); + PrintAndLogEx(INFO, "Trying 'lf read' and save a trace for you..."); + + CmdPlot(""); + lf_read(true, 40000); + char *fname = calloc(100, sizeof(uint8_t)); + AppendDate(fname, 100, "lf_unknown_%Y-%m-%d_%H:%M.pm3"); + CmdSave(fname); + free(fname); + return PM3_SUCCESS; +} + +int CmdRem(const char *Cmd) { + char buf[22] = {0}; + AppendDate(buf, sizeof(buf), NULL); + PrintAndLogEx(NORMAL, "%s remark: %s", buf, Cmd); + return PM3_SUCCESS; +} + static int CmdMsleep(const char *Cmd) { uint32_t ms = 0; char ctmp = tolower(param_getchar(Cmd, 0)); @@ -90,6 +134,7 @@ static int CmdRev(const char *Cmd) { static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help. Use ' help' for details of a particular command."}, + {"auto", CmdAuto, IfPm3Present, "Automated detection process for unknown tags"}, {"analyse", CmdAnalyse, AlwaysAvailable, "{ Analyse utils... }"}, {"data", CmdData, AlwaysAvailable, "{ Plot window / data buffer manipulation... }"}, {"emv", CmdEMV, AlwaysAvailable, "{ EMV ISO-14443 / ISO-7816... }"}, From 1694eaef0ab57112b02a9f7946833b91b31cbf74 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 19 Oct 2019 15:38:53 +0200 Subject: [PATCH 1016/1854] detect iClass vs PicoPass --- client/cmdhficlass.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index bb20e5b3a..966762cb3 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -2806,16 +2806,18 @@ int readIclass(bool loop, bool verbose) { FLAG_ICLASS_READER_ONE_TRY; // loop in client not device - else on windows have a communication error - PacketResponseNG resp; while (!kbd_enter_pressed()) { clearCommandBuffer(); SendCommandMIX(CMD_HF_ICLASS_READER, flags, 0, 0, NULL, 0); + PacketResponseNG resp; + if (WaitForResponseTimeout(CMD_ACK, &resp, 4500)) { + uint8_t readStatus = resp.oldarg[0] & 0xff; uint8_t *data = resp.data.asBytes; - if (verbose) PrintAndLogEx(INFO, "Readstatus:%02x", readStatus); +// if (verbose) PrintAndLogEx(INFO, "Readstatus:%02x", readStatus); // no tag found or button pressed if ((readStatus == 0 && !loop) || readStatus == 0xFF) { @@ -2837,18 +2839,27 @@ int readIclass(bool loop, bool verbose) { printIclassDumpInfo(data); } + // if CSN ends with FF12E0, it's inside HID CSN range. + bool isHidRange = (memcmp((uint8_t *)(data + 5), "\xFF\x12\xE0", 3) == 0); + if (readStatus & FLAG_ICLASS_READER_AIA) { bool legacy = (memcmp((uint8_t *)(data + 8 * 5), "\xff\xff\xff\xff\xff\xff\xff\xff", 8) == 0); bool se_enabled = (memcmp((uint8_t *)(data + 8 * 5), "\xff\xff\xff\x00\x06\xff\xff\xff", 8) == 0); PrintAndLogEx(NORMAL, " App IA: %s", sprint_hex(data + 8 * 5, 8)); - if (legacy) - PrintAndLogEx(SUCCESS, " : Possible iClass (legacy credential tag)"); - else if (se_enabled) - PrintAndLogEx(SUCCESS, " : Possible iClass (SE credential tag)"); - else - PrintAndLogEx(WARNING, " : Possible iClass (NOT legacy tag)"); + + if (legacy && isHidRange) + PrintAndLogEx(SUCCESS, " : Possible iClass - legacy credential tag"); + + if (se_enabled & isHidRange) + PrintAndLogEx(SUCCESS, " : Possible iClass - SE credential tag"); + + if (isHidRange) { + PrintAndLogEx(SUCCESS, " : Tag is "_YELLOW_("iClass")", CSN is in HID range"); + } else { + PrintAndLogEx(SUCCESS, " : Tag is "_YELLOW_("PicoPass")", CSN is not in HID range"); + } } if (tagFound && !loop) { From 21f93ef12ae10d9231594b6def034fdab25205c8 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 19 Oct 2019 15:57:16 -0400 Subject: [PATCH 1017/1854] shadowing --- armsrc/Standalone/hf_bog.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/armsrc/Standalone/hf_bog.c b/armsrc/Standalone/hf_bog.c index dc5c2e071..5e84d4cc1 100644 --- a/armsrc/Standalone/hf_bog.c +++ b/armsrc/Standalone/hf_bog.c @@ -217,12 +217,12 @@ void RAMFUNC SniffAndStore(uint8_t param) { if (DBGLEVEL > 1) Dbprintf("[!] Authentication attempts = %u", auth_attempts); size_t size = 4 * auth_attempts; - uint8_t *data = BigBuf_malloc(size); + uint8_t *buf = BigBuf_malloc(size); if (!exists_in_spiffs((char *)HF_BOG_LOGFILE)) { - rdv40_spiffs_write((char *)HF_BOG_LOGFILE, (uint8_t *)data, size, RDV40_SPIFFS_SAFETY_SAFE); + rdv40_spiffs_write((char *)HF_BOG_LOGFILE, buf, size, RDV40_SPIFFS_SAFETY_SAFE); } else { - rdv40_spiffs_append((char *)HF_BOG_LOGFILE, (uint8_t *)data, size, RDV40_SPIFFS_SAFETY_SAFE); + rdv40_spiffs_append((char *)HF_BOG_LOGFILE, buf, size, RDV40_SPIFFS_SAFETY_SAFE); } } From 3620236725b65d1281734249a288378ec62f259e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 19 Oct 2019 16:04:16 -0400 Subject: [PATCH 1018/1854] shadow --- armsrc/Standalone/lf_hidbrute.c | 2 +- armsrc/Standalone/lf_proxbrute.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/armsrc/Standalone/lf_hidbrute.c b/armsrc/Standalone/lf_hidbrute.c index 48efcf119..7cae49a5b 100644 --- a/armsrc/Standalone/lf_hidbrute.c +++ b/armsrc/Standalone/lf_hidbrute.c @@ -65,7 +65,7 @@ void RunMod() { continue; // Button was held for a second, begin recording - if (button_pressed > 0 && cardRead == 0) { + if (cardRead == 0) { LEDsoff(); LED(selected + 1, 0); LED(LED_D, 0); diff --git a/armsrc/Standalone/lf_proxbrute.c b/armsrc/Standalone/lf_proxbrute.c index 25d62cc2a..3cdfa6819 100644 --- a/armsrc/Standalone/lf_proxbrute.c +++ b/armsrc/Standalone/lf_proxbrute.c @@ -96,7 +96,7 @@ void RunMod() { if (data_available()) break; // Was our button held down or pressed? - int button_pressed = BUTTON_HELD(280); + button_pressed = BUTTON_HELD(280); if (button_pressed != BUTTON_HOLD) break; Dbprintf("[=] trying Facility = %08x ID %08x", high, i); From 5c0d6b1c9cfa2de95a69960770fd268ce157f733 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 19 Oct 2019 16:06:27 -0400 Subject: [PATCH 1019/1854] no need --- armsrc/appmain.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 35838ffab..84589ff00 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1711,8 +1711,10 @@ static void PacketReceived(PacketCommandNG *packet) { strncpy((char *)src, token, sizeof(src) - 1); token = strtok(NULL, ","); strncpy((char *)dest, token, sizeof(dest) - 1); - if (DBGLEVEL > 1) Dbprintf("> Filename received as source for spiffs RENAME : %s", src); - if (DBGLEVEL > 1) Dbprintf("> Filename received as destination for spiffs RENAME : %s", dest); + if (DBGLEVEL > 1) { + Dbprintf("> Filename received as source for spiffs RENAME : %s", src); + Dbprintf("> Filename received as destination for spiffs RENAME : %s", dest); + } rdv40_spiffs_rename((char *) src, (char *)dest, RDV40_SPIFFS_SAFETY_SAFE); LED_B_OFF(); break; @@ -1727,8 +1729,10 @@ static void PacketReceived(PacketCommandNG *packet) { strncpy((char *)src, token, sizeof(src) - 1); token = strtok(NULL, ","); strncpy((char *)dest, token, sizeof(dest) - 1); - if (DBGLEVEL > 1) Dbprintf("> Filename received as source for spiffs COPY : %s", src); - if (DBGLEVEL > 1) Dbprintf("> Filename received as destination for spiffs COPY : %s", dest); + if (DBGLEVEL > 1) { + Dbprintf("> Filename received as source for spiffs COPY : %s", src); + Dbprintf("> Filename received as destination for spiffs COPY : %s", dest); + } rdv40_spiffs_copy((char *) src, (char *)dest, RDV40_SPIFFS_SAFETY_SAFE); LED_B_OFF(); break; From 29468ee8173b90b7befaf6fb624652762b8785f0 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 19 Oct 2019 16:12:33 -0400 Subject: [PATCH 1020/1854] fix: wrong mess len --- armsrc/felica.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/armsrc/felica.c b/armsrc/felica.c index 2b2b72201..bbaf21e4c 100644 --- a/armsrc/felica.c +++ b/armsrc/felica.c @@ -615,7 +615,7 @@ void felica_sniff(uint32_t samplesToSkip, uint32_t triggersToSkip) { //crc NOT checked if (FelicaFrame.state == STATE_FULL) { endframe = GetCountSspClk(); - //*dest = FelicaFrame.crc_ok; //kind of wasteful + // *dest = FelicaFrame.crc_ok; //kind of wasteful dest++; for (int i = 0; i < FelicaFrame.len; i++) { *dest = FelicaFrame.framebytes[i]; @@ -756,7 +756,7 @@ void felica_sim_lite(uint64_t uid) { DbpString("Felica Lite-S sim end"); } -#define RES_SVC_LEN 11 +#define RES_SVC_LEN 11 + 3 void felica_dump() { uint8_t ndef[8]; @@ -806,10 +806,10 @@ uint8_t *felica_create_request_service_frame(uint8_t nodeNumber, uint8_t *idm) { request_service[7] = idm[3]; request_service[8] = idm[4]; request_service[9] = idm[5]; - request_service[9] = idm[6]; - request_service[9] = idm[7]; - request_service[10] = nodeNumber; // Node we like to ask for services - request_service[11] = 0x00; // Node Code List // TODO FIND OUT WHAT NEEDS TO BE IN HERE + request_service[10] = idm[6]; + request_service[11] = idm[7]; + request_service[12] = nodeNumber; // Node we like to ask for services + request_service[13] = 0x00; // Node Code List // TODO FIND OUT WHAT NEEDS TO BE IN HERE return request_service; } From c12bff8cdc6324eef85a917fc40bc843ef5eb368 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 19 Oct 2019 16:21:08 -0400 Subject: [PATCH 1021/1854] fix limit sizes --- armsrc/lfops.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 042e5edbc..a298af4a9 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -1235,8 +1235,8 @@ void CmdAWIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol) uint8_t *dest = BigBuf_get_addr(); - //big enough to catch 2 sequences of largest format - size_t size = 12800; //50 * 128 * 2; + //big enough to catch 2 sequences of largest format but don't exeed whats available in bigbuff. + size_t size = MIN(12800, BigBuf_max_traceLen()); //50 * 128 * 2; int dummyIdx = 0; @@ -1544,13 +1544,12 @@ void T55xxWriteBit(uint8_t bit, uint8_t downlink_idx) { // max_len - how many bytes can the bit_array hold (ensure no buffer overflow) // returns "Next" bit offset / bits stored (for next store) uint8_t T55xx_SetBits(uint8_t *bs, uint8_t start_offset, uint32_t data, uint8_t num_bits, uint8_t max_len) { - int8_t offset; int8_t next_offset = start_offset; // Check if data will fit. if ((start_offset + num_bits) <= (max_len * 8)) { // Loop through the data and store - for (offset = (num_bits - 1); offset >= 0; offset--) { + for (int8_t offset = (num_bits - 1); offset >= 0; offset--) { if ((data >> offset) & 1) bs[BITSTREAM_BYTE(next_offset)] |= (1 << BITSTREAM_BIT(next_offset)); // Set 1 From 768bf223118452f050a690b1c54e0a344974f97e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 19 Oct 2019 16:21:19 -0400 Subject: [PATCH 1022/1854] rename --- armsrc/frozen.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/armsrc/frozen.h b/armsrc/frozen.h index beb6c5f44..a81522a64 100644 --- a/armsrc/frozen.h +++ b/armsrc/frozen.h @@ -201,8 +201,8 @@ int json_printf_array(struct json_out *, va_list *ap); * Return number of elements successfully scanned & converted. * Negative number means scan error. */ -int json_scanf(const char *str, int str_len, const char *fmt, ...); -int json_vscanf(const char *str, int str_len, const char *fmt, va_list ap); +int json_scanf(const char *str, int len, const char *fmt, ...); +int json_vscanf(const char *str, int len, const char *fmt, va_list ap); /* json_scanf's %M handler */ typedef void (*json_scanner_t)(const char *str, int len, void *user_data); @@ -234,7 +234,7 @@ int json_escape(struct json_out *out, const char *str, size_t str_len); * Read the whole file in memory. * Return malloc-ed file content, or NULL on error. The caller must free(). */ -char *json_fread(const char *file_name); +char *json_fread(const char *path); /* * Update given JSON string `s,len` by changing the value at given `json_path`. From 729bf524371f7bc678ab77993c8959fc1c6d8a1b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 19 Oct 2019 16:25:51 -0400 Subject: [PATCH 1023/1854] fix: no crypto auth in MFU --- armsrc/mifareutil.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/armsrc/mifareutil.c b/armsrc/mifareutil.c index e36199bac..3ccf25737 100644 --- a/armsrc/mifareutil.c +++ b/armsrc/mifareutil.c @@ -276,7 +276,7 @@ int mifare_ultra_auth(uint8_t *keybytes) { uint8_t respPar[3] = {0, 0, 0}; // REQUEST AUTHENTICATION - len = mifare_sendcmd_short(NULL, 1, MIFARE_ULC_AUTH_1, 0x00, resp, respPar, NULL); + len = mifare_sendcmd_short(NULL, CRYPT_NONE, MIFARE_ULC_AUTH_1, 0x00, resp, respPar, NULL); if (len != 11) { if (DBGLEVEL >= DBG_ERROR) Dbprintf("Cmd Error: %02x", resp[0]); return 0; @@ -351,7 +351,7 @@ int mifare_ultra_readblockEx(uint8_t blockNo, uint8_t *blockData) { uint8_t receivedAnswer[MAX_FRAME_SIZE] = {0x00}; uint8_t receivedAnswerPar[MAX_PARITY_SIZE] = {0x00}; - len = mifare_sendcmd_short(NULL, 1, ISO14443A_CMD_READBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL); + len = mifare_sendcmd_short(NULL, CRYPT_NONE, ISO14443A_CMD_READBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL); if (len == 1) { if (DBGLEVEL >= DBG_ERROR) Dbprintf("Cmd Error: %02x", receivedAnswer[0]); return 1; @@ -444,7 +444,7 @@ int mifare_ultra_writeblock_compat(uint8_t blockNo, uint8_t *blockData) { uint8_t receivedAnswer[MAX_FRAME_SIZE]; uint8_t receivedAnswerPar[MAX_PARITY_SIZE]; - len = mifare_sendcmd_short(NULL, true, ISO14443A_CMD_WRITEBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL); + len = mifare_sendcmd_short(NULL, CRYPT_NONE, ISO14443A_CMD_WRITEBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL); if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK if (DBGLEVEL >= DBG_ERROR) From 0a978d8f8c1eb001843be578376923965b09f252 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 19 Oct 2019 16:31:10 -0400 Subject: [PATCH 1024/1854] fix: clarity --- armsrc/thinfilm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/thinfilm.c b/armsrc/thinfilm.c index bd8e696fb..46fa5a920 100644 --- a/armsrc/thinfilm.c +++ b/armsrc/thinfilm.c @@ -63,7 +63,7 @@ static void CodeThinfilmAsTag(const uint8_t *cmd, uint16_t len) { for (uint16_t i = 0; i < len; i++) { uint8_t b = cmd[i]; for (uint8_t j = 0; j < 8; j++) { - ToSend[++ToSendMax] = b & 0x80 ? SEC_D : SEC_E; + ToSend[++ToSendMax] = (b & 0x80) ? SEC_D : SEC_E; b <<= 1; } } From c9a390a480d68a8c203f80cc59123cecee1c361a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 19 Oct 2019 16:35:21 -0400 Subject: [PATCH 1025/1854] fix --- client/wiegand_formats.c | 6 +++--- client/wiegand_formats.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/client/wiegand_formats.c b/client/wiegand_formats.c index 4e2541cbd..1e08874ef 100644 --- a/client/wiegand_formats.c +++ b/client/wiegand_formats.c @@ -672,16 +672,16 @@ void HIDDisplayUnpackedCard(wiegand_card_t *card, const cardformat_t format) { char s[80] = {0}; if (format.Fields.hasFacilityCode) - snprintf(s, sizeof(s), "FC: %d", card->FacilityCode); + snprintf(s, sizeof(s), "FC: %u", card->FacilityCode); if (format.Fields.hasCardNumber) snprintf(s + strlen(s), sizeof(s) - strlen(s), " CN: %" PRIu64, card->CardNumber); if (format.Fields.hasIssueLevel) - snprintf(s + strlen(s), sizeof(s) - strlen(s), " Issue %d", card->IssueLevel); + snprintf(s + strlen(s), sizeof(s) - strlen(s), " Issue %u", card->IssueLevel); if (format.Fields.hasOEMCode) - snprintf(s + strlen(s), sizeof(s) - strlen(s), " OEM: %d", card->OEM); + snprintf(s + strlen(s), sizeof(s) - strlen(s), " OEM: %u", card->OEM); if (format.Fields.hasParity) snprintf(s + strlen(s), sizeof(s) - strlen(s), " parity: %s", card->ParityValid ? "valid" : "invalid"); diff --git a/client/wiegand_formats.h b/client/wiegand_formats.h index e3aca4b9c..b75f5e491 100644 --- a/client/wiegand_formats.h +++ b/client/wiegand_formats.h @@ -43,6 +43,6 @@ void HIDListFormats(); int HIDFindCardFormat(const char *format); cardformat_t HIDGetCardFormat(int idx); bool HIDPack(int FormatIndex, wiegand_card_t *card, wiegand_message_t *packed); -bool HIDTryUnpack(wiegand_message_t *packed, bool ignoreParity); +bool HIDTryUnpack(wiegand_message_t *packed, bool ignore_parity); #endif From 4ab474610472b6725fd754951dcbfd3269749e31 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 19 Oct 2019 16:39:28 -0400 Subject: [PATCH 1026/1854] fix: bad bool --- client/cmdhficlass.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 966762cb3..b57996af1 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -2330,7 +2330,7 @@ static int CmdHFiClassCheckKeys(const char *Cmd) { uint8_t found_offset = 0; uint32_t key_offset = 0; // main keychunk loop - for (uint32_t key_offset = 0; key_offset < keycount; key_offset += chunksize) { + for (key_offset = 0; key_offset < keycount; key_offset += chunksize) { uint64_t t2 = msclock(); uint8_t timeout = 0; @@ -2849,11 +2849,13 @@ int readIclass(bool loop, bool verbose) { PrintAndLogEx(NORMAL, " App IA: %s", sprint_hex(data + 8 * 5, 8)); - if (legacy && isHidRange) - PrintAndLogEx(SUCCESS, " : Possible iClass - legacy credential tag"); + if (isHidRange) { + if (legacy) + PrintAndLogEx(SUCCESS, " : Possible iClass - legacy credential tag"); - if (se_enabled & isHidRange) - PrintAndLogEx(SUCCESS, " : Possible iClass - SE credential tag"); + if (se_enabled) + PrintAndLogEx(SUCCESS, " : Possible iClass - SE credential tag"); + } if (isHidRange) { PrintAndLogEx(SUCCESS, " : Tag is "_YELLOW_("iClass")", CSN is in HID range"); From e5df52fb8695dd58b8029fa5d337cd91ec74bec6 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 19 Oct 2019 16:42:37 -0400 Subject: [PATCH 1027/1854] fix: bools --- client/cmdlft55xx.c | 4 ++-- client/cmdlft55xx.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 541a67fe4..9175bdaf5 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -1083,7 +1083,7 @@ static int CmdT55xxDetect(const char *Cmd) { if (try_all_dl_modes) { for (uint8_t m = downlink_mode; m < 4; m++) { - if (AcquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, try_with_pwd & usepwd, password, m) == false) + if (AcquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, try_with_pwd && usepwd, password, m) == false) continue; // pre fill to save passing in. @@ -1111,7 +1111,7 @@ static int CmdT55xxDetect(const char *Cmd) { } } - if (!found & usepwd) + if (!found && usepwd) try_with_pwd = !try_with_pwd; // toggle so we loop back if not found and try with pwd if (found) diff --git a/client/cmdlft55xx.h b/client/cmdlft55xx.h index 4f96006b5..71fda2a72 100644 --- a/client/cmdlft55xx.h +++ b/client/cmdlft55xx.h @@ -148,7 +148,7 @@ char *GetQ5ModulationStr(uint32_t id); char *GetModulationStr(uint32_t id, bool xmode); char *GetModelStrFromCID(uint32_t cid); char *GetSelectedModulationStr(uint8_t id); -char *GetDownlinkModeStr(uint8_t dlmode); +char *GetDownlinkModeStr(uint8_t downlink_mode); void printT5xxHeader(uint8_t page); void printT55xxBlock(uint8_t blockNum, bool page1); int printConfiguration(t55xx_conf_block_t b); From b0e01f9236b9c4fa20242f8869bc984b7efc1790 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 19 Oct 2019 16:46:11 -0400 Subject: [PATCH 1028/1854] fix: double free --- client/emv/emvcore.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/emv/emvcore.c b/client/emv/emvcore.c index 8c9b2ea1e..c18521b6c 100644 --- a/client/emv/emvcore.c +++ b/client/emv/emvcore.c @@ -1089,7 +1089,7 @@ int RecoveryCertificates(struct tlvdb *tlvRoot, json_t *root) { char *icc_pk_c = emv_pk_dump_pk(icc_pk); JsonSaveStr(root, "$.ApplicationData.ICCPublicKeyDec", icc_pk_c); JsonSaveBufAsHex(root, "$.ApplicationData.ICCPublicKeyModulus", icc_pk->modulus, icc_pk->mlen); - free(issuer_pk_c); + free(icc_pk_c); return 0; } From 0dd9e66bcf42e3f29a48c249ed6d2ac503045060 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 19 Oct 2019 23:40:34 +0200 Subject: [PATCH 1029/1854] text --- armsrc/felica.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/armsrc/felica.c b/armsrc/felica.c index bbaf21e4c..4d9712a0d 100644 --- a/armsrc/felica.c +++ b/armsrc/felica.c @@ -527,7 +527,7 @@ void felica_sendraw(PacketCommandNG *c) { arg0 = felica_select_card(&card); reply_mix(CMD_ACK, arg0, sizeof(card.uid), 0, &card, sizeof(felica_card_select_t)); if (arg0 > 0) { - Dbprintf("Error: Failed selecting card! "); + if (DBGLEVEL >= DBG_DEBUG) Dbprintf("Error: Failed selecting card! "); felica_reset_frame_mode(); return; } @@ -764,6 +764,8 @@ void felica_dump() { iso18092_setup(FPGA_HF_ISO18092_FLAG_READER | FPGA_HF_ISO18092_FLAG_NOMOD); TransmitFor18092_AsReader(poll, 10, NULL, 1, 0); + + // iceman, no exit path in this loop while (!BUTTON_PRESS() && !data_available()) { WDT_HIT(); TransmitFor18092_AsReader(poll, 10, NULL, 1, 0); @@ -773,6 +775,7 @@ void felica_dump() { felica_send_request_service(request_service); } } + } void felica_send_request_service(uint8_t *request_service) { From 29573f1ac5cfdef4468d18e397ceab4230a0dfda Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 20 Oct 2019 06:23:57 -0400 Subject: [PATCH 1030/1854] fix --- client/mifare/mad.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/mifare/mad.c b/client/mifare/mad.c index 5cf3e1852..fe41ac032 100644 --- a/client/mifare/mad.c +++ b/client/mifare/mad.c @@ -181,7 +181,7 @@ int MADCheck(uint8_t *sector0, uint8_t *sector10, bool verbose, bool *haveMAD2) if (!res) res = res2; - if (verbose & !res2) + if (verbose && !res2) PrintAndLogEx(NORMAL, "CRC8-MAD2 OK."); } From 7b2b49ff734dd161b1073a35d472ae82bc0deef3 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 20 Oct 2019 06:24:46 -0400 Subject: [PATCH 1031/1854] fix: sanity check --- client/cmdhfmfhard.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/client/cmdhfmfhard.c b/client/cmdhfmfhard.c index ab3e1a3d0..d83c60047 100644 --- a/client/cmdhfmfhard.c +++ b/client/cmdhfmfhard.c @@ -1052,6 +1052,11 @@ static void estimate_sum_a8(void) { static int read_nonce_file(char *filename) { + + if (filename == NULL) { + PrintAndLogEx(WARNING, "Filename is NULL"); + return 1; + } FILE *fnonces = NULL; char progress_text[80] = ""; uint8_t read_buf[9]; @@ -1061,6 +1066,7 @@ static int read_nonce_file(char *filename) { PrintAndLogEx(WARNING, "Could not open file %s", filename); return 1; } + snprintf(progress_text, 80, "Reading nonces from file %s...", filename); hardnested_print_progress(0, progress_text, (float)(1LL << 47), 0); size_t bytes_read = fread(read_buf, 1, 6, fnonces); @@ -1766,7 +1772,7 @@ static void add_matching_states(statelist_t *candidates, uint8_t part_sum_a0, ui } static statelist_t *add_more_candidates(void) { - statelist_t *new_candidates = candidates; + statelist_t *new_candidates; if (candidates == NULL) { candidates = (statelist_t *)malloc(sizeof(statelist_t)); new_candidates = candidates; From 6091894b72b226bcd3653d42f472d2c9da0ff731 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 20 Oct 2019 06:25:29 -0400 Subject: [PATCH 1032/1854] fix: unshadow --- client/hardnested/hardnested_bruteforce.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/client/hardnested/hardnested_bruteforce.c b/client/hardnested/hardnested_bruteforce.c index 4af190d71..682257415 100644 --- a/client/hardnested/hardnested_bruteforce.c +++ b/client/hardnested/hardnested_bruteforce.c @@ -250,16 +250,16 @@ void prepare_bf_test_nonces(noncelist_t *nonces, uint8_t best_first_byte) { uint32_t bf_test_nonce_temp[4]; uint8_t bf_test_nonce_par_temp[4]; uint8_t bf_test_nonce_2nd_byte_temp[4]; - for (uint8_t i = 0; i < 4 && i < nonces_to_bruteforce; i++) { - bf_test_nonce_temp[i] = bf_test_nonce[best_4[i]]; + for (uint8_t j = 0; j < 4 && j < nonces_to_bruteforce; j++) { + bf_test_nonce_temp[j] = bf_test_nonce[best_4[j]]; - bf_test_nonce_par_temp[i] = bf_test_nonce_par[best_4[i]]; - bf_test_nonce_2nd_byte_temp[i] = bf_test_nonce_2nd_byte[best_4[i]]; + bf_test_nonce_par_temp[j] = bf_test_nonce_par[best_4[j]]; + bf_test_nonce_2nd_byte_temp[j] = bf_test_nonce_2nd_byte[best_4[j]]; } - for (uint8_t i = 0; i < 4 && i < nonces_to_bruteforce; i++) { - bf_test_nonce[i] = bf_test_nonce_temp[i]; - bf_test_nonce_par[i] = bf_test_nonce_par_temp[i]; - bf_test_nonce_2nd_byte[i] = bf_test_nonce_2nd_byte_temp[i]; + for (uint8_t j = 0; j < 4 && j < nonces_to_bruteforce; j++) { + bf_test_nonce[j] = bf_test_nonce_temp[j]; + bf_test_nonce_par[j] = bf_test_nonce_par_temp[j]; + bf_test_nonce_2nd_byte[j] = bf_test_nonce_2nd_byte_temp[j]; } } From 2ba8d07e1bc752757676b663af6093b4aa3beeff Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 20 Oct 2019 06:28:49 -0400 Subject: [PATCH 1033/1854] fix: unshadow --- client/fido/cbortools.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/fido/cbortools.c b/client/fido/cbortools.c index b0d309db7..911244806 100644 --- a/client/fido/cbortools.c +++ b/client/fido/cbortools.c @@ -75,9 +75,9 @@ static CborError dumpelm(CborValue *it, bool *got_next, int nestingLevel) { } case CborSimpleType: { - uint8_t type; - cbor_value_get_simple_type(it, &type); - printf("simple(%u)", type); + uint8_t t; + cbor_value_get_simple_type(it, &t); + printf("simple(%u)", t); break; } @@ -206,7 +206,7 @@ int TinyCborPrintFIDOPackage(uint8_t cmdCode, bool isResponse, uint8_t *data, si if (err) { fprintf(stderr, - "CBOR parsing failure at offset %" PRId32 " : %s\n", + "CBOR parsing failure at offset %" PRIu32 " : %s\n", (uint32_t)(cb.ptr - data), cbor_error_string(err) ); From 339f499a255c9bfd8b6446ab32e4989a7099fd79 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 20 Oct 2019 06:30:09 -0400 Subject: [PATCH 1034/1854] fix: unshadow --- client/emv/emvjson.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/emv/emvjson.c b/client/emv/emvjson.c index 4a3ef9299..0d3e9bb29 100644 --- a/client/emv/emvjson.c +++ b/client/emv/emvjson.c @@ -1,4 +1,4 @@ -//----------------------------------------------------------------------------- +://----------------------------------------------------------------------------- // Copyright (C) 2018 Merlok // // This code is licensed to you under the terms of the GNU GPL, version 2 or, @@ -372,8 +372,8 @@ bool ParamLoadFromJson(struct tlvdb *tlv) { return false; } tlv_tag_t tag = 0; - for (int i = 0; i < buflen; i++) { - tag = (tag << 8) | buf[i]; + for (int j = 0; j < buflen; j++) { + tag = (tag << 8) | buf[j]; } if (!HexToBuffer("TLV Error value:", tlvValue, buf, sizeof(buf) - 1, &buflen)) { From 2f573ebfb3412a341c53a6e01450b155f4c95ddb Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 20 Oct 2019 06:31:49 -0400 Subject: [PATCH 1035/1854] fix: unshadow --- client/cmdwiegand.c | 10 +++++----- client/emv/emvjson.c | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/client/cmdwiegand.c b/client/cmdwiegand.c index 8c1b5e8cb..3c939261f 100644 --- a/client/cmdwiegand.c +++ b/client/cmdwiegand.c @@ -150,11 +150,11 @@ int CmdWiegandDecode(const char *Cmd) { bool errors = false; char cmdp = 0; while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { - uint32_t strlen = param_getlength(Cmd, cmdp); - strlen++; // null termin - if (strlen > 2) { - char *s = calloc(strlen, sizeof(uint8_t)); - param_getstr(Cmd, cmdp, s, strlen); + uint32_t slen = param_getlength(Cmd, cmdp); + slen++; // null termin + if (slen > 2) { + char *s = calloc(slen, sizeof(uint8_t)); + param_getstr(Cmd, cmdp, s, slen); hexstring_to_u96(&top, &mid, &bot, s); free(s); gothex = true; diff --git a/client/emv/emvjson.c b/client/emv/emvjson.c index 0d3e9bb29..75b2e87bf 100644 --- a/client/emv/emvjson.c +++ b/client/emv/emvjson.c @@ -1,4 +1,4 @@ -://----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- // Copyright (C) 2018 Merlok // // This code is licensed to you under the terms of the GNU GPL, version 2 or, From f7d4f2e9f3a0a069f916b406519104095bf1e9db Mon Sep 17 00:00:00 2001 From: Thomas Sutter Date: Sun, 20 Oct 2019 18:28:07 +0200 Subject: [PATCH 1036/1854] Unfinished request service commands. --- armsrc/felica.c | 14 ++-- client/cmdhffelica.c | 149 +++++++++++++++++++++++++++++++++++++++---- client/cmdhffelica.h | 3 +- 3 files changed, 144 insertions(+), 22 deletions(-) diff --git a/armsrc/felica.c b/armsrc/felica.c index ab22bc778..023f4d719 100644 --- a/armsrc/felica.c +++ b/armsrc/felica.c @@ -14,17 +14,17 @@ // FeliCa timings // minimum time between the start bits of consecutive transfers from reader to tag: 6800 carrier (13.56MHz) cycles #ifndef FELICA_REQUEST_GUARD_TIME -# define FELICA_REQUEST_GUARD_TIME (6800/16 + 1) +# define FELICA_REQUEST_GUARD_TIME (6800/16 + 1) // 426 #endif // FRAME DELAY TIME 2672 carrier cycles #ifndef FELICA_FRAME_DELAY_TIME -# define FELICA_FRAME_DELAY_TIME (2672/16 + 1) +# define FELICA_FRAME_DELAY_TIME (2672/16 + 1) // 168 #endif #ifndef DELAY_AIR2ARM_AS_READER -#define DELAY_AIR2ARM_AS_READER (3 + 16 + 8 + 8*16 + 4*16 - 8*16) +#define DELAY_AIR2ARM_AS_READER (3 + 16 + 8 + 8*16 + 4*16 - 8*16) // 91 #endif #ifndef DELAY_ARM2AIR_AS_READER -#define DELAY_ARM2AIR_AS_READER (4*16 + 8*16 + 8 + 8 + 1) +#define DELAY_ARM2AIR_AS_READER (4*16 + 8*16 + 8 + 8 + 1) // 209 #endif // CRC skips two first sync bits in data buffer @@ -357,7 +357,6 @@ static void TransmitFor18092_AsReader(uint8_t *frame, int len, uint32_t *timing, // sending 0x00 0x00 0x00 0x00 0x00 0x00 uint16_t c = 0; while (c < 6) { - // keep tx buffer in a defined state anyway. if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { AT91C_BASE_SSC->SSC_THR = 0x00; @@ -416,8 +415,6 @@ bool WaitForFelicaReply(uint16_t maxbytes) { uint32_t timeout = iso18092_get_timeout(); if (DBGLEVEL > 3) Dbprintf("timeout set: %i", timeout); - //TODO FIX THIS METHOD - Race Condition or something: TIMING/MEMORY ISSUES - // If you add content here (dbprintf), timing problems appear?! Last Bytes (CRC) of frame will be cutoff. for (;;) { WDT_HIT(); if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { @@ -527,7 +524,7 @@ void felica_sendraw(PacketCommandNG *c) { arg0 = felica_select_card(&card); reply_mix(CMD_ACK, arg0, sizeof(card.uid), 0, &card, sizeof(felica_card_select_t)); if (arg0 > 0) { - Dbprintf("Error: Failed selecting card! "); + Dbprintf("Error: Failed selecting card!"); felica_reset_frame_mode(); return; } @@ -565,6 +562,7 @@ void felica_sendraw(PacketCommandNG *c) { Dbprintf("Received Frame Code: %d", arg0); Dbhexdump(FelicaFrame.len, FelicaFrame.framebytes, 0); }; + uint32_t result = reply_mix(CMD_ACK, FelicaFrame.len, arg0, 0, FelicaFrame.framebytes, FelicaFrame.len); if (result) { Dbprintf("Reply to Client Error Code: %i", result); diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index 22acf6344..288ef409e 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -43,7 +43,7 @@ static int usage_hf_felica_sim(void) { static int usage_hf_felica_sniff(void) { PrintAndLogEx(NORMAL, "It get data from the field and saves it into command buffer."); PrintAndLogEx(NORMAL, "Buffer accessible from command 'hf list felica'"); - PrintAndLogEx(NORMAL, "Usage: hf felica sniff "); + PrintAndLogEx(NORMAL, "Usage: hf felica sniff "); PrintAndLogEx(NORMAL, " s samples to skip (decimal)"); PrintAndLogEx(NORMAL, " t triggers to skip (decimal)"); PrintAndLogEx(NORMAL, "Examples:"); @@ -81,6 +81,17 @@ static int usage_hf_felica_raw(void) { return 0; } +static int usage_hf_felica_request_service(void) { + PrintAndLogEx(NORMAL, "\nInfo: Use this command to verify the existence of Area and Service, and to acquire Key Version:"); + PrintAndLogEx(NORMAL, " - When the specified Area or Service exists, the card returns Key Version."); + PrintAndLogEx(NORMAL, " - When the specified Area or Service does not exist, the card returns FFFFh as Key Version."); + PrintAndLogEx(NORMAL, "\nUsage: hf felica rqservice [-h] <0A 0B 0C ... IDm hex> <01 Number of Node hex> <0A 0B Node Code List hex (Little Endian)> <0A 0B CRC hex>"); + PrintAndLogEx(NORMAL, " -h this help"); + PrintAndLogEx(NORMAL, " -c calculate and append CRC"); + PrintAndLogEx(NORMAL, "Example: rqservice 01100910c11bc407 01 FFFF 2837"); + return 0; +} + static int usage_hf_felica_dump(void) { PrintAndLogEx(NORMAL, "Usage: hf felica dump [-h] "); PrintAndLogEx(NORMAL, " -h this help"); @@ -102,7 +113,95 @@ static int CmdHFFelicaReader(const char *Cmd) { static int CmdHFFelicaDump(const char *Cmd) { if (strlen(Cmd) < 1) return usage_hf_felica_dump(); - dump(*Cmd); + clearCommandBuffer(); + char ctmp = tolower(param_getchar(Cmd, 0)); + if (ctmp == 'h') return usage_hf_felica_dumplite(); + dump(); + return 0; +} + +static int CmdHFFelicaRequestService(const char *Cmd) { + if (strlen(Cmd) < 2) return usage_hf_felica_request_service(); + char buf[5] = ""; + int i = 0; + uint8_t data[PM3_CMD_DATA_SIZE]; + uint16_t datalen = 0; + set_number_of_cmds(); + while (Cmd[i] != '\0') { + PrintAndLogEx(NORMAL, "String %s: ", Cmd[i]); + if (Cmd[i] == '-') { + switch (Cmd[i + 1]) { + case 'H': + case 'h': + return usage_hf_felica_raw(); + case 'c': + crc = true; + break; + default: + return usage_hf_felica_raw(); + } + i += 2; + } + i = i + parse_cmd_parameter(i); + if(is_hex_input()){ + buf[strlen(buf) + 1] = 0; + buf[strlen(buf)] = Cmd[i]; + i++; + i = i + get_cmd_data(i); + }else{ + i++; + } + } + request_service(); + clearCommandBuffer(); + return 0; +} + +/* + * Parses line spacing and tabs. + * Returns 1 if the given char is a space or tab + */ +static int parse_cmd_parameter_separator(const char *Cmd, int i){ + PrintAndLogEx(NORMAL, "parse_cmd_parameter_separator String %s: ", Cmd[i]); + return Cmd[i] == ' ' || Cmd[i] == '\t' ? 1 : 0; +} + +/* + * Counts and sets the number of commands. + */ +static void set_number_of_cmds(const char *Cmd){ + while (*Cmd == ' ' || *Cmd == '\t'){ + Cmd++; + } +} + +/** + * Checks if a char is a hex value. + * @param Cmd + * @return one if it is a valid hex char. Zero if not a valid hex char. + */ +static bool is_hex_input(const char *Cmd, int i){ + PrintAndLogEx(NORMAL, "is_hex_input String %s: ", Cmd[i]); + return (Cmd[i] >= '0' && Cmd[i] <= '9') || (Cmd[i] >= 'a' && Cmd[i] <= 'f') || (Cmd[i] >= 'A' && Cmd[i] <= 'F') ? 1 : 0; +} + +/** + * + * @param Cmd the chars from which the data will be extracted. + * @return a buffer with the data from the command + */ +static int get_cmd_data(const char *Cmd, int i){ + int char_counter = 0; + if (strlen(buf) >= 2) { + sscanf(buf, "%x", &temp); + data[datalen] = (uint8_t)(temp & 0xff); + *buf = 0; + } + return 0; +} + +static int CmdHFFelicaNotImplementedYet(const char *Cmd) { + PrintAndLogEx(NORMAL, "Feature not implemented Yet!"); return 0; } @@ -174,7 +273,6 @@ static int CmdHFFelicaSim(const char *Cmd) { */ static int CmdHFFelicaSniff(const char *Cmd) { - uint8_t cmdp = 0; uint64_t samples2skip = 0; uint64_t triggers2skip = 0; @@ -211,7 +309,6 @@ static int CmdHFFelicaSniff(const char *Cmd) { // uid hex static int CmdHFFelicaSimLite(const char *Cmd) { - uint64_t uid = param_get64ex(Cmd, 0, 0, 16); if (!uid) @@ -446,6 +543,9 @@ static void waitCmdFelica(uint8_t iSelect) { if (!len) return; PrintAndLogEx(NORMAL, "%s", sprint_hex(resp.data.asBytes, len)); + if(!check_crc(CRC_FELICA, resp.data.asBytes + 2, len - 2)){ + PrintAndLogEx(ERR, "Error: CRC of received bytes are incorrect!"); + } } else { PrintAndLogEx(WARNING, "Timeout while waiting for reply."); } @@ -530,7 +630,6 @@ static int CmdHFFelicaCmdRaw(const char *Cmd) { if (crc && datalen > 0 && datalen < sizeof(data) - 2) { uint8_t b1, b2; compute_crc(CRC_FELICA, data, datalen, &b1, &b2); - // TODO FIND OUT IF FeliCa Light has another CRC order - Order changed for FeliCa Standard cards data[datalen++] = b2; data[datalen++] = b1; } @@ -617,27 +716,53 @@ int readFelicaUid(bool verbose) { return status; } +int dump() { -int dump(const char *Cmd) { - clearCommandBuffer(); - char ctmp = tolower(param_getchar(Cmd, 0)); - if (ctmp == 'h') return usage_hf_felica_dumplite(); // TODO FINISH THIS METHOD PrintAndLogEx(SUCCESS, "NOT IMPLEMENTED YET!"); + return 0; +} + +int request_service() { + + + return 0; } static command_t CommandTable[] = { + {"----------- General -----------", CmdHelp, IfPm3Iso14443a, ""}, {"help", CmdHelp, AlwaysAvailable, "This help"}, {"list", CmdHFFelicaList, AlwaysAvailable, "List ISO 18092/FeliCa history"}, {"reader", CmdHFFelicaReader, IfPm3Felica, "Act like an ISO18092/FeliCa reader"}, -// {"sim", CmdHFFelicaSim, IfPm3Felica, " -- Simulate ISO 18092/FeliCa tag"}, - {"sniff", CmdHFFelicaSniff, IfPm3Felica, "sniff ISO 18092/Felica traffic"}, + {"sniff", CmdHFFelicaSniff, IfPm3Felica, "Sniff ISO 18092/FeliCa traffic"}, {"raw", CmdHFFelicaCmdRaw, IfPm3Felica, "Send raw hex data to tag"}, - {"dump", CmdHFFelicaDump, IfPm3Felica, "Wait for and try dumping Felica"}, + {"----------- FeliCa Standard (support in progress) -----------", CmdHelp, IfPm3Iso14443a, ""}, + {"dump", CmdHFFelicaDump, IfPm3Felica, "Wait for and try dumping FeliCa"}, + {"rqservice", CmdHFFelicaRequestService, IfPm3Felica, "verify the existence of Area and Service, and to acquire Key Version."}, + {"rqresponse", CmdHFFelicaNotImplementedYet, IfPm3Felica, "verify the existence of a card and its Mode."}, + //{"rdNoEncryption", CmdHFFelicaNotImplementedYet, IfPm3Felica, "read Block Data from authentication-not-required Service."}, + //{"wrNoEncryption", CmdHFFelicaNotImplementedYet, IfPm3Felica, "write Block Data to an authentication-required Service."}, + //{"searchSvCode", CmdHFFelicaNotImplementedYet, IfPm3Felica, "acquire Area Code and Service Code."}, + //{"rqSysCode", CmdHFFelicaNotImplementedYet, IfPm3Felica, "acquire System Code registered to the card."}, + //{"auth1", CmdHFFelicaNotImplementedYet, IfPm3Felica, "authenticate a card."}, + //{"auth2", CmdHFFelicaNotImplementedYet, IfPm3Felica, "allow a card to authenticate a Reader/Writer."}, + //{"read", CmdHFFelicaNotImplementedYet, IfPm3Felica, "read Block Data from authentication-required Service."}, + //{"write", CmdHFFelicaNotImplementedYet, IfPm3Felica, "write Block Data to an authentication-required Service."}, + //{"searchSvCodeV2", CmdHFFelicaNotImplementedYet, IfPm3Felica, "verify the existence of Area or Service, and to acquire Key Version."}, + //{"getSysStatus", CmdHFFelicaNotImplementedYet, IfPm3Felica, "acquire the setup information in System."}, + //{"rqSpecVer", CmdHFFelicaNotImplementedYet, IfPm3Felica, "acquire the version of card OS."}, + //{"resetMode", CmdHFFelicaNotImplementedYet, IfPm3Felica, "reset Mode to Mode 0."}, + //{"auth1V2", CmdHFFelicaNotImplementedYet, IfPm3Felica, "authenticate a card."}, + //{"auth2V2", CmdHFFelicaNotImplementedYet, IfPm3Felica, "allow a card to authenticate a Reader/Writer."}, + //{"readV2", CmdHFFelicaNotImplementedYet, IfPm3Felica, "read Block Data from authentication-required Service."}, + //{"writeV2", CmdHFFelicaNotImplementedYet, IfPm3Felica, "write Block Data to authentication-required Service."}, + //{"upRandomID", CmdHFFelicaNotImplementedYet, IfPm3Felica, "update Random ID (IDr)."}, + {"----------- FeliCa Light -----------", CmdHelp, IfPm3Iso14443a, ""}, {"litesim", CmdHFFelicaSimLite, IfPm3Felica, " - only reply to poll request"}, {"litedump", CmdHFFelicaDumpLite, IfPm3Felica, "Wait for and try dumping FelicaLite"}, + // {"sim", CmdHFFelicaSim, IfPm3Felica, " -- Simulate ISO 18092/FeliCa tag"} {NULL, NULL, NULL, NULL} }; diff --git a/client/cmdhffelica.h b/client/cmdhffelica.h index abbbd42a4..88a1a0080 100644 --- a/client/cmdhffelica.h +++ b/client/cmdhffelica.h @@ -14,8 +14,7 @@ #include "common.h" int CmdHFFelica(const char *Cmd); - int readFelicaUid(bool verbose); - int dump(); +int request_service(); #endif From 7cbac6067e824dbe8d07605e069201343535ee9c Mon Sep 17 00:00:00 2001 From: grspy <49810400+grspy@users.noreply.github.com> Date: Sun, 20 Oct 2019 20:08:52 +0300 Subject: [PATCH 1037/1854] Fix pack in dump PACK wasn't included in the output dump due to incorrect check of ul_auth_select return value --- client/cmdhfmfu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index e3ae2f0e1..06f44e35d 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -1991,7 +1991,7 @@ static int CmdHF14AMfUDump(const char *Cmd) { if (!(tagtype & UL_C || tagtype & UL)) { //attempt to read pack uint8_t get_pack[] = {0, 0}; - if (!ul_auth_select(&card, tagtype, true, authKeyPtr, get_pack, sizeof(get_pack))) { + if (ul_auth_select(&card, tagtype, true, authKeyPtr, get_pack, sizeof(get_pack)) != PM3_SUCCESS) { //reset pack get_pack[0] = 0; get_pack[1] = 0; From a3f8d635ca6f33550fc4cb494b7003b6580c3ac2 Mon Sep 17 00:00:00 2001 From: Thomas Sutter Date: Sun, 20 Oct 2019 20:26:00 +0200 Subject: [PATCH 1038/1854] Add new cmd parser functions. --- client/cmdhffelica.c | 134 ++++++++++++++++++++++--------------------- client/cmdhffelica.h | 2 - 2 files changed, 69 insertions(+), 67 deletions(-) diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index 04580b239..5f963b947 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -88,10 +88,52 @@ static int usage_hf_felica_request_service(void) { PrintAndLogEx(NORMAL, "\nUsage: hf felica rqservice [-h] <0A 0B 0C ... IDm hex> <01 Number of Node hex> <0A 0B Node Code List hex (Little Endian)> <0A 0B CRC hex>"); PrintAndLogEx(NORMAL, " -h this help"); PrintAndLogEx(NORMAL, " -c calculate and append CRC"); - PrintAndLogEx(NORMAL, "Example: rqservice 01100910c11bc407 01 FFFF 2837"); + PrintAndLogEx(NORMAL, "\nExample: hf felica rqservice 01100910c11bc407 01 FFFF 2837\n\n"); return PM3_SUCCESS; } +/* + * Parses line spacing and tabs. + * Returns 1 if the given char is a space or tab + */ +static int parse_cmd_parameter_separator(const char *Cmd, int i){ + return Cmd[i] == ' ' || Cmd[i] == '\t' ? 1 : 0; +} + +/* + * Counts and sets the number of commands. + */ +static void strip_cmds(const char *Cmd){ + PrintAndLogEx(NORMAL, "CMD count: %i", strlen(Cmd)); + while (*Cmd == ' ' || *Cmd == '\t'){ + PrintAndLogEx(NORMAL, "CMD: %s", Cmd); + Cmd++; + } + PrintAndLogEx(NORMAL, "CMD string: %s", Cmd); +} + +/** + * Checks if a char is a hex value. + * @param Cmd + * @return one if it is a valid hex char. Zero if not a valid hex char. + */ +static bool is_hex_input(const char *Cmd, int i){ + return (Cmd[i] >= '0' && Cmd[i] <= '9') || (Cmd[i] >= 'a' && Cmd[i] <= 'f') || (Cmd[i] >= 'A' && Cmd[i] <= 'F') ? 1 : 0; +} + +/** + * + * @param Extracts the data from the cmd and puts it into the data array. + */ +static void get_cmd_data(const char *Cmd, int i, uint16_t datalen, uint8_t *data, char buf[]){ + uint32_t temp; + if (strlen(buf) >= 2) { + sscanf(buf, "%x", &temp); + data[datalen] = (uint8_t)(temp & 0xff); + *buf = 0; + } +} + static int usage_hf_felica_dump(void) { PrintAndLogEx(NORMAL, "Usage: hf felica dump [-h] "); PrintAndLogEx(NORMAL, " -h this help"); @@ -120,15 +162,24 @@ static int CmdHFFelicaDump(const char *Cmd) { return 0; } +/** + * Command parser for rqservice. + * @param Cmd input data of the user. + * @return client result code. + */ static int CmdHFFelicaRequestService(const char *Cmd) { if (strlen(Cmd) < 2) return usage_hf_felica_request_service(); - char buf[5] = ""; int i = 0; uint8_t data[PM3_CMD_DATA_SIZE]; + bool crc = false; + bool length = false; uint16_t datalen = 0; - set_number_of_cmds(); + char buf[5] = ""; + + strip_cmds(Cmd); while (Cmd[i] != '\0') { - PrintAndLogEx(NORMAL, "String %s: ", Cmd[i]); + PrintAndLogEx(NORMAL, "Parse String %s: ", Cmd); + PrintAndLogEx(NORMAL, "i = %i: ", i); if (Cmd[i] == '-') { switch (Cmd[i + 1]) { case 'H': @@ -137,72 +188,36 @@ static int CmdHFFelicaRequestService(const char *Cmd) { case 'c': crc = true; break; + case 'l': + length = true; + break; default: return usage_hf_felica_raw(); } i += 2; } - i = i + parse_cmd_parameter(i); - if(is_hex_input()){ + PrintAndLogEx(NORMAL, "i after single params = %i: ", i); + i = i + parse_cmd_parameter_separator(Cmd, i); + PrintAndLogEx(NORMAL, "i after cnd separator: %i", i); + if (is_hex_input(Cmd, i)){ buf[strlen(buf) + 1] = 0; buf[strlen(buf)] = Cmd[i]; i++; - i = i + get_cmd_data(i); - }else{ + PrintAndLogEx(NORMAL, "i after is hex input: %i", i); + get_cmd_data(Cmd, i, datalen, data, buf); + + }else { i++; } } request_service(); clearCommandBuffer(); - return 0; -} - -/* - * Parses line spacing and tabs. - * Returns 1 if the given char is a space or tab - */ -static int parse_cmd_parameter_separator(const char *Cmd, int i){ - PrintAndLogEx(NORMAL, "parse_cmd_parameter_separator String %s: ", Cmd[i]); - return Cmd[i] == ' ' || Cmd[i] == '\t' ? 1 : 0; -} - -/* - * Counts and sets the number of commands. - */ -static void set_number_of_cmds(const char *Cmd){ - while (*Cmd == ' ' || *Cmd == '\t'){ - Cmd++; - } -} - -/** - * Checks if a char is a hex value. - * @param Cmd - * @return one if it is a valid hex char. Zero if not a valid hex char. - */ -static bool is_hex_input(const char *Cmd, int i){ - PrintAndLogEx(NORMAL, "is_hex_input String %s: ", Cmd[i]); - return (Cmd[i] >= '0' && Cmd[i] <= '9') || (Cmd[i] >= 'a' && Cmd[i] <= 'f') || (Cmd[i] >= 'A' && Cmd[i] <= 'F') ? 1 : 0; -} - -/** - * - * @param Cmd the chars from which the data will be extracted. - * @return a buffer with the data from the command - */ -static int get_cmd_data(const char *Cmd, int i){ - int char_counter = 0; - if (strlen(buf) >= 2) { - sscanf(buf, "%x", &temp); - data[datalen] = (uint8_t)(temp & 0xff); - *buf = 0; - } - return 0; + return PM3_SUCCESS; } static int CmdHFFelicaNotImplementedYet(const char *Cmd) { PrintAndLogEx(NORMAL, "Feature not implemented Yet!"); - return 0; + return PM3_SUCCESS; } // simulate iso18092 / FeliCa tag @@ -717,21 +732,10 @@ int readFelicaUid(bool verbose) { return PM3_SUCCESS; } -int dump(const char *Cmd) { - clearCommandBuffer(); - char ctmp = tolower(param_getchar(Cmd, 0)); - if (ctmp == 'h') return usage_hf_felica_dumplite(); - - // TODO FINISH THIS METHOD - PrintAndLogEx(SUCCESS, "NOT IMPLEMENTED YET!"); - return PM3_SUCCESS; -} - int request_service() { return PM3_SUCCESS; } - static command_t CommandTable[] = { {"----------- General -----------", CmdHelp, IfPm3Iso14443a, ""}, {"help", CmdHelp, AlwaysAvailable, "This help"}, @@ -740,7 +744,7 @@ static command_t CommandTable[] = { {"sniff", CmdHFFelicaSniff, IfPm3Felica, "Sniff ISO 18092/FeliCa traffic"}, {"raw", CmdHFFelicaCmdRaw, IfPm3Felica, "Send raw hex data to tag"}, {"----------- FeliCa Standard (support in progress) -----------", CmdHelp, IfPm3Iso14443a, ""}, - {"dump", CmdHFFelicaDump, IfPm3Felica, "Wait for and try dumping FeliCa"}, + //{"dump", CmdHFFelicaDump, IfPm3Felica, "Wait for and try dumping FeliCa"}, {"rqservice", CmdHFFelicaRequestService, IfPm3Felica, "verify the existence of Area and Service, and to acquire Key Version."}, {"rqresponse", CmdHFFelicaNotImplementedYet, IfPm3Felica, "verify the existence of a card and its Mode."}, //{"rdNoEncryption", CmdHFFelicaNotImplementedYet, IfPm3Felica, "read Block Data from authentication-not-required Service."}, diff --git a/client/cmdhffelica.h b/client/cmdhffelica.h index 88a1a0080..59032ee31 100644 --- a/client/cmdhffelica.h +++ b/client/cmdhffelica.h @@ -15,6 +15,4 @@ int CmdHFFelica(const char *Cmd); int readFelicaUid(bool verbose); -int dump(); -int request_service(); #endif From 3a3b66d0798472e82fe22cc667704bb4d7a15c5a Mon Sep 17 00:00:00 2001 From: Thomas Sutter Date: Sun, 20 Oct 2019 20:28:57 +0200 Subject: [PATCH 1039/1854] Fix build --- client/cmdhffelica.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index 5f963b947..caeb4cb9f 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -134,11 +134,13 @@ static void get_cmd_data(const char *Cmd, int i, uint16_t datalen, uint8_t *data } } +/* static int usage_hf_felica_dump(void) { + // TODO IMPLEMENT PrintAndLogEx(NORMAL, "Usage: hf felica dump [-h] "); PrintAndLogEx(NORMAL, " -h this help"); return PM3_SUCCESS; -} +}*/ static int CmdHFFelicaList(const char *Cmd) { (void)Cmd; // Cmd is not used so far @@ -152,14 +154,19 @@ static int CmdHFFelicaReader(const char *Cmd) { return readFelicaUid(verbose); } +/* static int CmdHFFelicaDump(const char *Cmd) { if (strlen(Cmd) < 1) return usage_hf_felica_dump(); - return dump(*Cmd); - clearCommandBuffer(); - char ctmp = tolower(param_getchar(Cmd, 0)); - if (ctmp == 'h') return usage_hf_felica_dumplite(); - dump(); - return 0; + // TODO IMPLEMENT + return PM3_SUCCESS; +}*/ + +/** + * Sends a request service frame + * @return + */ +static int request_service() { + return PM3_SUCCESS; } /** @@ -732,10 +739,6 @@ int readFelicaUid(bool verbose) { return PM3_SUCCESS; } -int request_service() { - return PM3_SUCCESS; -} - static command_t CommandTable[] = { {"----------- General -----------", CmdHelp, IfPm3Iso14443a, ""}, {"help", CmdHelp, AlwaysAvailable, "This help"}, From e7f7810d2260bd5fa5f27a954af908160400e353 Mon Sep 17 00:00:00 2001 From: Thomas Sutter Date: Mon, 21 Oct 2019 09:59:15 +0200 Subject: [PATCH 1040/1854] Make style. Change DBG_DEBUG. Refactor CRC calculation --- armsrc/felica.c | 34 ++++++------ client/cmdhf.c | 2 +- client/cmdhffelica.c | 128 ++++++++++++++++++++++++++----------------- 3 files changed, 96 insertions(+), 68 deletions(-) diff --git a/armsrc/felica.c b/armsrc/felica.c index 6a0e8c190..3b4de9d5f 100644 --- a/armsrc/felica.c +++ b/armsrc/felica.c @@ -229,21 +229,21 @@ static uint8_t felica_select_card(felica_card_select_t *card) { // timed-out if (len == 0) { - if (DBGLEVEL > 3) + if (DBGLEVEL >= DBG_DEBUG) Dbprintf("Error: Time out card selection!"); return 1; } // wrong answer if (FelicaFrame.framebytes[3] != FELICA_POLL_ACK) { - if (DBGLEVEL > 3) + if (DBGLEVEL >= DBG_DEBUG) Dbprintf("Error: Wrong answer selecting card!"); return 2; } // VALIDATE CRC residue is 0, hence if crc is a value it failed. if (!check_crc(CRC_FELICA, FelicaFrame.framebytes + 2, FelicaFrame.len - 2)) { - if (DBGLEVEL > 3) { + if (DBGLEVEL >= DBG_DEBUG) { Dbprintf("Error: CRC check failed!"); Dbprintf("CRC check was done on Frame: "); Dbhexdump(FelicaFrame.len - 2, FelicaFrame.framebytes + 2, 0); @@ -251,7 +251,7 @@ static uint8_t felica_select_card(felica_card_select_t *card) { return 3; } - if (DBGLEVEL > 3) + if (DBGLEVEL >= DBG_DEBUG) Dbprintf("Card selection successful!"); // copy UID // idm 8 @@ -263,7 +263,7 @@ static uint8_t felica_select_card(felica_card_select_t *card) { memcpy(card->uid, card->IDm + 2, 6); memcpy(card->iccode, card->PMm, 2); memcpy(card->mrt, card->PMm + 2, 6); - if (DBGLEVEL > 3) { + if (DBGLEVEL >= DBG_DEBUG) { Dbprintf("Received Frame: "); Dbhexdump(FelicaFrame.len, FelicaFrame.framebytes, 0); } @@ -365,7 +365,7 @@ static void TransmitFor18092_AsReader(uint8_t *frame, int len, uint32_t *timing, } // sending data with sync bytes c = 0; - if (DBGLEVEL > 3) { + if (DBGLEVEL >= DBG_DEBUG) { Dbprintf("Sending frame:"); Dbhexdump(len, frame, 0); } @@ -403,7 +403,7 @@ static void TransmitFor18092_AsReader(uint8_t *frame, int len, uint32_t *timing, // stop when button is pressed // or return TRUE when command is captured bool WaitForFelicaReply(uint16_t maxbytes) { - if (DBGLEVEL > 3) + if (DBGLEVEL >= DBG_DEBUG) Dbprintf("WaitForFelicaReply Start"); uint32_t c = 0; // power, no modulation @@ -413,7 +413,7 @@ bool WaitForFelicaReply(uint16_t maxbytes) { // clear RXRDY: uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; uint32_t timeout = iso18092_get_timeout(); - if (DBGLEVEL > 3) + if (DBGLEVEL >= DBG_DEBUG) Dbprintf("timeout set: %i", timeout); for (;;) { WDT_HIT(); @@ -435,10 +435,10 @@ bool WaitForFelicaReply(uint16_t maxbytes) { NULL, false ); - if (DBGLEVEL > 3) Dbprintf("All bytes received! STATE_FULL"); + if (DBGLEVEL >= DBG_DEBUG) Dbprintf("All bytes received! STATE_FULL"); return true; } else if (c++ > timeout && FelicaFrame.state == STATE_UNSYNCD) { - if (DBGLEVEL > 3) Dbprintf("Error: Timeout! STATE_UNSYNCD"); + if (DBGLEVEL >= DBG_DEBUG) Dbprintf("Error: Timeout! STATE_UNSYNCD"); return false; } } @@ -448,7 +448,7 @@ bool WaitForFelicaReply(uint16_t maxbytes) { // Set up FeliCa communication (similar to iso14443a_setup) // field is setup for "Sending as Reader" static void iso18092_setup(uint8_t fpga_minor_mode) { - if (DBGLEVEL > 3) Dbprintf("Start iso18092_setup"); + if (DBGLEVEL >= DBG_DEBUG) Dbprintf("Start iso18092_setup"); LEDsoff(); FpgaDownloadAndGo(FPGA_BITSTREAM_HF); @@ -501,7 +501,7 @@ void felica_reset_frame_mode() { // arg1 len of commandbytes // d.asBytes command bytes to send void felica_sendraw(PacketCommandNG *c) { - if (DBGLEVEL > 3) Dbprintf("FeliCa_sendraw Enter"); + if (DBGLEVEL >= DBG_DEBUG) Dbprintf("FeliCa_sendraw Enter"); felica_command_t param = c->oldarg[0]; size_t len = c->oldarg[1] & 0xffff; @@ -511,7 +511,7 @@ void felica_sendraw(PacketCommandNG *c) { felica_card_select_t card; if ((param & FELICA_CONNECT)) - if (DBGLEVEL > 3) Dbprintf("Clear trace"); + if (DBGLEVEL >= DBG_DEBUG) Dbprintf("Clear trace"); clear_trace(); set_tracing(true); @@ -530,7 +530,7 @@ void felica_sendraw(PacketCommandNG *c) { } } } else { - if (DBGLEVEL > 3) Dbprintf("No card selection"); + if (DBGLEVEL >= DBG_DEBUG) Dbprintf("No card selection"); } if ((param & FELICA_RAW)) { @@ -551,14 +551,14 @@ void felica_sendraw(PacketCommandNG *c) { AddCrc(buf, len); } } - if (DBGLEVEL > 3) { + if (DBGLEVEL >= DBG_DEBUG) { Dbprintf("Transmit Frame (no CRC shown):"); Dbhexdump(len, buf, 0); Dbprintf("Buffer Length: %i", buf[2] + 4); }; TransmitFor18092_AsReader(buf, buf[2] + 4, NULL, 1, 0); arg0 = WaitForFelicaReply(1024); - if (DBGLEVEL > 3) { + if (DBGLEVEL >= DBG_DEBUG) { Dbprintf("Received Frame Code: %d", arg0); Dbhexdump(FelicaFrame.len, FelicaFrame.framebytes, 0); }; @@ -571,7 +571,7 @@ void felica_sendraw(PacketCommandNG *c) { if ((param & FELICA_NO_DISCONNECT)) { Dbprintf("Disconnect"); } - if (DBGLEVEL > 3) + if (DBGLEVEL >= DBG_DEBUG) Dbprintf("FeliCa_sendraw Exit"); felica_reset_frame_mode(); return; diff --git a/client/cmdhf.c b/client/cmdhf.c index bf8a9dceb..9166b01ca 100644 --- a/client/cmdhf.c +++ b/client/cmdhf.c @@ -96,7 +96,7 @@ int CmdHFSearch(const char *Cmd) { return PM3_SUCCESS; } } - + PROMPT_CLEARLINE; PrintAndLogEx(INPLACE, "Searching for ISO15693 tag..."); if (IfPm3Iso15693()) { diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index caeb4cb9f..c50382758 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -85,27 +85,47 @@ static int usage_hf_felica_request_service(void) { PrintAndLogEx(NORMAL, "\nInfo: Use this command to verify the existence of Area and Service, and to acquire Key Version:"); PrintAndLogEx(NORMAL, " - When the specified Area or Service exists, the card returns Key Version."); PrintAndLogEx(NORMAL, " - When the specified Area or Service does not exist, the card returns FFFFh as Key Version."); - PrintAndLogEx(NORMAL, "\nUsage: hf felica rqservice [-h] <0A 0B 0C ... IDm hex> <01 Number of Node hex> <0A 0B Node Code List hex (Little Endian)> <0A 0B CRC hex>"); + PrintAndLogEx(NORMAL, "\nUsage: hf felica rqservice [-h] [-i] <01 Number of Node hex> <0A 0B Node Code List hex (Little Endian)>"); PrintAndLogEx(NORMAL, " -h this help"); - PrintAndLogEx(NORMAL, " -c calculate and append CRC"); + PrintAndLogEx(NORMAL, " -i <0A 0B 0C ... hex> set IDm"); PrintAndLogEx(NORMAL, "\nExample: hf felica rqservice 01100910c11bc407 01 FFFF 2837\n\n"); return PM3_SUCCESS; } +/** + * Wait for response from pm3 or timeout. + * Checks if receveid bytes have a valid CRC. + */ +static void waitCmdFelica(uint8_t iSelect) { + PacketResponseNG resp; + if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { + uint16_t len = iSelect ? (resp.oldarg[1] & 0xffff) : (resp.oldarg[0] & 0xffff); + PrintAndLogEx(NORMAL, "Client Received %i octets", len); + if (!len) + return; + PrintAndLogEx(NORMAL, "%s", sprint_hex(resp.data.asBytes, len)); + if (!check_crc(CRC_FELICA, resp.data.asBytes + 2, len - 2)) { + PrintAndLogEx(ERR, "Error: CRC of received bytes are incorrect!"); + } + } else { + PrintAndLogEx(WARNING, "Timeout while waiting for reply."); + } +} + /* * Parses line spacing and tabs. * Returns 1 if the given char is a space or tab */ -static int parse_cmd_parameter_separator(const char *Cmd, int i){ +static int parse_cmd_parameter_separator(const char *Cmd, int i) { return Cmd[i] == ' ' || Cmd[i] == '\t' ? 1 : 0; } /* * Counts and sets the number of commands. */ -static void strip_cmds(const char *Cmd){ +static void strip_cmds(const char *Cmd) { PrintAndLogEx(NORMAL, "CMD count: %i", strlen(Cmd)); - while (*Cmd == ' ' || *Cmd == '\t'){ + while (*Cmd == ' ' || *Cmd == '\t') { PrintAndLogEx(NORMAL, "CMD: %s", Cmd); Cmd++; } @@ -117,15 +137,36 @@ static void strip_cmds(const char *Cmd){ * @param Cmd * @return one if it is a valid hex char. Zero if not a valid hex char. */ -static bool is_hex_input(const char *Cmd, int i){ +static bool is_hex_input(const char *Cmd, int i) { return (Cmd[i] >= '0' && Cmd[i] <= '9') || (Cmd[i] >= 'a' && Cmd[i] <= 'f') || (Cmd[i] >= 'A' && Cmd[i] <= 'F') ? 1 : 0; } /** - * - * @param Extracts the data from the cmd and puts it into the data array. + * Add crc bytes to the end of the given data. + * @param datalen length of the data frame. + * @param data frame on which the crc is calculated. + * @param size of the data. + * @return true if the crc was added. */ -static void get_cmd_data(const char *Cmd, int i, uint16_t datalen, uint8_t *data, char buf[]){ +static bool add_crc_bytes(uint16_t *datalen, uint8_t *data, size_t dataSize) { + if (*datalen > 0 && *datalen < dataSize - 2) { + uint8_t b1, b2; + compute_crc(CRC_FELICA, data, *datalen, &b1, &b2); + data[(*datalen)++] = b2; + data[(*datalen)++] = b1; + return 1; + } + return 0; +} + +/** + * Extracts the data from the cmd and puts it into the data array. + * @param Cmd input string of the user with the data + * @param datalen length of the data frame. + * @param data the array in which the data gets stored. + * @param buf temporary buffer. + */ +static void get_cmd_data(const char *Cmd, uint16_t datalen, uint8_t *data, char buf[]) { uint32_t temp; if (strlen(buf) >= 2) { sscanf(buf, "%x", &temp); @@ -161,14 +202,6 @@ static int CmdHFFelicaDump(const char *Cmd) { return PM3_SUCCESS; }*/ -/** - * Sends a request service frame - * @return - */ -static int request_service() { - return PM3_SUCCESS; -} - /** * Command parser for rqservice. * @param Cmd input data of the user. @@ -178,9 +211,10 @@ static int CmdHFFelicaRequestService(const char *Cmd) { if (strlen(Cmd) < 2) return usage_hf_felica_request_service(); int i = 0; uint8_t data[PM3_CMD_DATA_SIZE]; - bool crc = false; - bool length = false; + bool custom_IDm = false; uint16_t datalen = 0; + uint16_t numbits = 0; + uint8_t flags = 0; char buf[5] = ""; strip_cmds(Cmd); @@ -192,11 +226,8 @@ static int CmdHFFelicaRequestService(const char *Cmd) { case 'H': case 'h': return usage_hf_felica_raw(); - case 'c': - crc = true; - break; - case 'l': - length = true; + case 'i': + custom_IDm = true; break; default: return usage_hf_felica_raw(); @@ -206,19 +237,33 @@ static int CmdHFFelicaRequestService(const char *Cmd) { PrintAndLogEx(NORMAL, "i after single params = %i: ", i); i = i + parse_cmd_parameter_separator(Cmd, i); PrintAndLogEx(NORMAL, "i after cnd separator: %i", i); - if (is_hex_input(Cmd, i)){ + if (is_hex_input(Cmd, i)) { buf[strlen(buf) + 1] = 0; buf[strlen(buf)] = Cmd[i]; i++; PrintAndLogEx(NORMAL, "i after is hex input: %i", i); - get_cmd_data(Cmd, i, datalen, data, buf); - - }else { - i++; + get_cmd_data(Cmd, datalen, data, buf); + } else { + i++; } } - request_service(); + flags |= FELICA_APPEND_CRC; + if (custom_IDm) { + flags |= FELICA_NO_SELECT; + } + if (datalen > 0) { + flags |= FELICA_RAW; + } + datalen = (datalen > PM3_CMD_DATA_SIZE) ? PM3_CMD_DATA_SIZE : datalen; clearCommandBuffer(); + PrintAndLogEx(NORMAL, "Data: %s", data); + SendCommandMIX(CMD_HF_FELICA_COMMAND, flags, (datalen & 0xFFFF) | (uint32_t)(numbits << 16), 0, data, datalen); + if (custom_IDm) { + waitCmdFelica(1); + } + if (datalen > 0) { + waitCmdFelica(0); + } return PM3_SUCCESS; } @@ -557,21 +602,7 @@ static int CmdHFFelicaDumpLite(const char *Cmd) { return PM3_SUCCESS; } -static void waitCmdFelica(uint8_t iSelect) { - PacketResponseNG resp; - if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { - uint16_t len = iSelect ? (resp.oldarg[1] & 0xffff) : (resp.oldarg[0] & 0xffff); - PrintAndLogEx(NORMAL, "Client Received %i octets", len); - if (!len) - return; - PrintAndLogEx(NORMAL, "%s", sprint_hex(resp.data.asBytes, len)); - if(!check_crc(CRC_FELICA, resp.data.asBytes + 2, len - 2)){ - PrintAndLogEx(ERR, "Error: CRC of received bytes are incorrect!"); - } - } else { - PrintAndLogEx(WARNING, "Timeout while waiting for reply."); - } -} + static int CmdHFFelicaCmdRaw(const char *Cmd) { bool reply = 1; @@ -649,11 +680,8 @@ static int CmdHFFelicaCmdRaw(const char *Cmd) { return PM3_EINVARG; } - if (crc && datalen > 0 && datalen < sizeof(data) - 2) { - uint8_t b1, b2; - compute_crc(CRC_FELICA, data, datalen, &b1, &b2); - data[datalen++] = b2; - data[datalen++] = b1; + if (crc) { + add_crc_bytes(&datalen, data, sizeof(data)); } uint8_t flags = 0; From e54edfd8db526ee51298ea348338cf97531cb659 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 21 Oct 2019 13:44:08 +0200 Subject: [PATCH 1041/1854] wiegand: use ARRAYLEN --- client/wiegand_formats.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/wiegand_formats.c b/client/wiegand_formats.c index 1e08874ef..983e0f432 100644 --- a/client/wiegand_formats.c +++ b/client/wiegand_formats.c @@ -8,6 +8,7 @@ // HID card format packing/unpacking routines //----------------------------------------------------------------------------- #include "wiegand_formats.h" +#include "commonutil.h" bool Pack_H10301(wiegand_card_t *card, wiegand_message_t *packed) { memset(packed, 0, sizeof(wiegand_message_t)); @@ -643,7 +644,7 @@ int HIDFindCardFormat(const char *format) { bool HIDPack(int format_idx, wiegand_card_t *card, wiegand_message_t *packed) { memset(packed, 0, sizeof(wiegand_message_t)); - if (format_idx < 0 || format_idx >= (sizeof(FormatTable) / sizeof(FormatTable[0]))) + if (format_idx < 0 || format_idx >= ARRAYLEN(FormatTable)) return false; return FormatTable[format_idx].Pack(card, packed); From 8792679fc8126abf19fcb900542562a5a8cb46d8 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 21 Oct 2019 13:46:23 +0200 Subject: [PATCH 1042/1854] make style --- client/cmdhf.c | 2 +- client/cmdhffelica.c | 2 +- client/luascripts/init_rdv4.lua | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/client/cmdhf.c b/client/cmdhf.c index bf8a9dceb..9166b01ca 100644 --- a/client/cmdhf.c +++ b/client/cmdhf.c @@ -96,7 +96,7 @@ int CmdHFSearch(const char *Cmd) { return PM3_SUCCESS; } } - + PROMPT_CLEARLINE; PrintAndLogEx(INPLACE, "Searching for ISO15693 tag..."); if (IfPm3Iso15693()) { diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index 6d7362c3c..1fa5b035d 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -620,7 +620,7 @@ int dump(const char *Cmd) { clearCommandBuffer(); char ctmp = tolower(param_getchar(Cmd, 0)); if (ctmp == 'h') return usage_hf_felica_dumplite(); - + // TODO FINISH THIS METHOD PrintAndLogEx(SUCCESS, "NOT IMPLEMENTED YET!"); diff --git a/client/luascripts/init_rdv4.lua b/client/luascripts/init_rdv4.lua index 4836cda77..d2dd03e24 100644 --- a/client/luascripts/init_rdv4.lua +++ b/client/luascripts/init_rdv4.lua @@ -88,7 +88,7 @@ function main(args) print('') core.console('hw status') print(dash) - + print('all done!') end From 6144e2d09bab56b29f746db53bac5e82495107af Mon Sep 17 00:00:00 2001 From: Thomas Sutter Date: Tue, 22 Oct 2019 15:56:05 +0200 Subject: [PATCH 1043/1854] Add felica request service command. Add cmd parser functions. --- armsrc/felica.c | 84 +-------------------------- client/cmdhffelica.c | 131 +++++++++++++++++++++++++++++++------------ include/mifare.h | 9 +++ 3 files changed, 107 insertions(+), 117 deletions(-) diff --git a/armsrc/felica.c b/armsrc/felica.c index 3b4de9d5f..83ff2bea3 100644 --- a/armsrc/felica.c +++ b/armsrc/felica.c @@ -337,9 +337,7 @@ static void BuildFliteRdblk(uint8_t *idm, int blocknum, uint16_t *blocks) { } static void TransmitFor18092_AsReader(uint8_t *frame, int len, uint32_t *timing, uint8_t power, uint8_t highspeed) { - uint8_t flags = FPGA_MAJOR_MODE_ISO18092; - if (power) flags |= FPGA_HF_ISO18092_FLAG_READER; if (highspeed) @@ -371,7 +369,6 @@ static void TransmitFor18092_AsReader(uint8_t *frame, int len, uint32_t *timing, } while (c < len) { - // Put byte into tx holding register as soon as it is ready if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { AT91C_BASE_SSC->SSC_THR = frame[c++]; @@ -415,18 +412,16 @@ bool WaitForFelicaReply(uint16_t maxbytes) { uint32_t timeout = iso18092_get_timeout(); if (DBGLEVEL >= DBG_DEBUG) Dbprintf("timeout set: %i", timeout); + for (;;) { WDT_HIT(); if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { b = (uint8_t)(AT91C_BASE_SSC->SSC_RHR); Process18092Byte(b); if (FelicaFrame.state == STATE_FULL) { - felica_nexttransfertime = - MAX( - felica_nexttransfertime, + felica_nexttransfertime = MAX(felica_nexttransfertime, (GetCountSspClk() & 0xfffffff8) - (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER) / 16 + FELICA_FRAME_DELAY_TIME - ); - + ); LogTrace( FelicaFrame.framebytes, FelicaFrame.len, @@ -774,79 +769,6 @@ void felica_dump() { } } -} - -void felica_send_request_service(uint8_t *request_service) { - Dbprintf("Send Service Request - len: d%", RES_SVC_LEN); - TransmitFor18092_AsReader(request_service, RES_SVC_LEN, NULL, 1, 0); - if (WaitForFelicaReply(512) && FelicaFrame.framebytes[3] == FELICA_REQSRV_ACK) { - Dbprintf("Got Service Response!"); - } -} - -/* Create Request Service Frame -// Use this command to verify the existence of Area and Service, and to acquire Key Version. -// When the specified Area or Service exists, the card returns Key Version. -// When the specified Area or Service does not exist, the card returns FFFFh as Key Version. -*/ -uint8_t *felica_create_request_service_frame(uint8_t nodeNumber, uint8_t *idm) { - if (nodeNumber < 1 && nodeNumber > 32) { - Dbprintf("Node number out of range: 1 <= %d <= 32 - set node number to 1"); - nodeNumber = 1; - } - // Sync 2-Byte, Length 1-Byte, CMD 1-Byte, IDm 8-Byte, nodeNumber 1 <= n <= 32 1-Byte, Node Code List - uint8_t *request_service = BigBuf_malloc(sizeof(uint8_t) * RES_SVC_LEN); - //{ 0xb2, 0x4d, 0x06, FELICA_REQSRV_REQ, 0xff, 0xff, 0x00, 0x00, 0x09, 0x21}; - request_service[0] = 0xb2; //Sync - request_service[1] = 0x4d; //Sync - request_service[2] = 0x0B; // Length - request_service[3] = FELICA_REQSRV_REQ; // CMD - request_service[4] = idm[0]; - request_service[5] = idm[1]; - request_service[6] = idm[2]; - request_service[7] = idm[3]; - request_service[8] = idm[4]; - request_service[9] = idm[5]; - request_service[10] = idm[6]; - request_service[11] = idm[7]; - request_service[12] = nodeNumber; // Node we like to ask for services - request_service[13] = 0x00; // Node Code List // TODO FIND OUT WHAT NEEDS TO BE IN HERE - return request_service; -} - -// Create Frame for authentication1 CMD -void felica_create_authentication1_frame() { - -} - -// Create Frame for authentication2 CMD -void felica_create_authentication2_frame() { - -} - -// Create a Frame for Read without encryption CMD as Payload -void felica_create_read_block_frame(uint16_t blockNr) { - if (blockNr < 1 || blockNr > 567) { - Dbprintf("Block number out of range!"); - return; - } - uint8_t c = 0; - // First Byte of SYNC - frameSpace[c++] = 0xb2; - frameSpace[c++] = 0x4d; - // skip Length of Frame - c++; - // Payload - frameSpace[c++] = FELICA_RDBLK_REQ; //command number - - // Set frame length - - // CRC -} - -void felica_read_block(uint8_t *idm, uint16_t blockNr) { - - } void felica_dump_lite_s() { diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index c50382758..81fb3e67d 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -24,6 +24,11 @@ #include "mifare.h" // felica_card_select_t struct static int CmdHelp(const char *Cmd); +static felica_card_select_t last_known_card; + +static void set_last_known_card(felica_card_select_t card){ + last_known_card = card; +} /* static int usage_hf_felica_sim(void) { @@ -85,10 +90,14 @@ static int usage_hf_felica_request_service(void) { PrintAndLogEx(NORMAL, "\nInfo: Use this command to verify the existence of Area and Service, and to acquire Key Version:"); PrintAndLogEx(NORMAL, " - When the specified Area or Service exists, the card returns Key Version."); PrintAndLogEx(NORMAL, " - When the specified Area or Service does not exist, the card returns FFFFh as Key Version."); + PrintAndLogEx(NORMAL, "For Node Code List of a command packet, Area Code or Service Code of the target " + "of acquisition of Key Version shall be enumerated in Little Endian format." + "If Key Version of System is the target of acquisition, FFFFh shall be specified " + "in the command packet."); PrintAndLogEx(NORMAL, "\nUsage: hf felica rqservice [-h] [-i] <01 Number of Node hex> <0A 0B Node Code List hex (Little Endian)>"); PrintAndLogEx(NORMAL, " -h this help"); - PrintAndLogEx(NORMAL, " -i <0A 0B 0C ... hex> set IDm"); - PrintAndLogEx(NORMAL, "\nExample: hf felica rqservice 01100910c11bc407 01 FFFF 2837\n\n"); + PrintAndLogEx(NORMAL, " -i <0A 0B 0C ... hex> set custom IDm to use"); + PrintAndLogEx(NORMAL, "\nExample: hf felica rqservice 01 FFFF \n\n"); return PM3_SUCCESS; } @@ -96,20 +105,22 @@ static int usage_hf_felica_request_service(void) { * Wait for response from pm3 or timeout. * Checks if receveid bytes have a valid CRC. */ -static void waitCmdFelica(uint8_t iSelect) { - PacketResponseNG resp; - if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { - uint16_t len = iSelect ? (resp.oldarg[1] & 0xffff) : (resp.oldarg[0] & 0xffff); +static bool waitCmdFelica(uint8_t iSelect, PacketResponseNG *resp) { + if (WaitForResponseTimeout(CMD_ACK, resp, 2000)) { + uint16_t len = iSelect ? (resp->oldarg[1] & 0xffff) : (resp->oldarg[0] & 0xffff); PrintAndLogEx(NORMAL, "Client Received %i octets", len); - if (!len) - return; - PrintAndLogEx(NORMAL, "%s", sprint_hex(resp.data.asBytes, len)); - if (!check_crc(CRC_FELICA, resp.data.asBytes + 2, len - 2)) { - PrintAndLogEx(ERR, "Error: CRC of received bytes are incorrect!"); + if (!len || len < 2){ + PrintAndLogEx(ERR, "Could not receive data correctly!"); } + PrintAndLogEx(NORMAL, "%s", sprint_hex(resp->data.asBytes, len)); + if (!check_crc(CRC_FELICA, resp->data.asBytes + 2, len - 2)) { + PrintAndLogEx(WARNING, "Wrong or no CRC bytes"); + } + return true; } else { PrintAndLogEx(WARNING, "Timeout while waiting for reply."); } + return false; } /* @@ -124,12 +135,9 @@ static int parse_cmd_parameter_separator(const char *Cmd, int i) { * Counts and sets the number of commands. */ static void strip_cmds(const char *Cmd) { - PrintAndLogEx(NORMAL, "CMD count: %i", strlen(Cmd)); while (*Cmd == ' ' || *Cmd == '\t') { - PrintAndLogEx(NORMAL, "CMD: %s", Cmd); Cmd++; } - PrintAndLogEx(NORMAL, "CMD string: %s", Cmd); } /** @@ -160,21 +168,53 @@ static bool add_crc_bytes(uint16_t *datalen, uint8_t *data, size_t dataSize) { } /** - * Extracts the data from the cmd and puts it into the data array. + * Extracts the hex data from the cmd and puts it into the data array. * @param Cmd input string of the user with the data * @param datalen length of the data frame. * @param data the array in which the data gets stored. - * @param buf temporary buffer. + * @param buf buffer with hex data. */ -static void get_cmd_data(const char *Cmd, uint16_t datalen, uint8_t *data, char buf[]) { - uint32_t temp; +static void get_cmd_data(const char *Cmd, uint16_t *datalen, uint8_t *data, char buf[]) { + uint32_t hex; if (strlen(buf) >= 2) { - sscanf(buf, "%x", &temp); - data[datalen] = (uint8_t)(temp & 0xff); + sscanf(buf, "%x", &hex); + data[*datalen] = (uint8_t)(hex & 0xff); + (*datalen)++; *buf = 0; } } +/** + * Converts integer value to equivalent hex value. + * @param number number of hex bytes. + * @return number as hex value. + */ +static uint8_t int_to_hex(uint16_t *number){ + uint32_t hex; + char dataLengthChar[5]; + sprintf(dataLengthChar, "%x", *number); + sscanf(dataLengthChar, "%x", &hex); + return (uint8_t)(hex & 0xff); +} + +/** + * Adds the last known IDm (8-Byte) to the data frame. + * @param position start of where the IDm is added within the frame. + * @param data frame in where the IDM is added. + * @return true if IDm was added; + */ +static bool add_last_IDm(uint8_t position, uint8_t *data){ + if(last_known_card.IDm[0] != 0 && last_known_card.IDm[1] != 0){ + for(int i = 0; i < 8; i++){ + uint16_t number = (uint16_t)last_known_card.IDm[i]; + data[position+i] = int_to_hex(&number); + } + return true; + }else{ + return false; + } +} + /* static int usage_hf_felica_dump(void) { // TODO IMPLEMENT @@ -213,14 +253,12 @@ static int CmdHFFelicaRequestService(const char *Cmd) { uint8_t data[PM3_CMD_DATA_SIZE]; bool custom_IDm = false; uint16_t datalen = 0; - uint16_t numbits = 0; uint8_t flags = 0; + uint16_t numbits = 0; char buf[5] = ""; - + datalen += 10; // length (1) + CMD (1) + IDm (8) strip_cmds(Cmd); while (Cmd[i] != '\0') { - PrintAndLogEx(NORMAL, "Parse String %s: ", Cmd); - PrintAndLogEx(NORMAL, "i = %i: ", i); if (Cmd[i] == '-') { switch (Cmd[i + 1]) { case 'H': @@ -234,15 +272,12 @@ static int CmdHFFelicaRequestService(const char *Cmd) { } i += 2; } - PrintAndLogEx(NORMAL, "i after single params = %i: ", i); i = i + parse_cmd_parameter_separator(Cmd, i); - PrintAndLogEx(NORMAL, "i after cnd separator: %i", i); if (is_hex_input(Cmd, i)) { buf[strlen(buf) + 1] = 0; buf[strlen(buf)] = Cmd[i]; i++; - PrintAndLogEx(NORMAL, "i after is hex input: %i", i); - get_cmd_data(Cmd, datalen, data, buf); + get_cmd_data(Cmd, &datalen, data, buf); } else { i++; } @@ -255,14 +290,37 @@ static int CmdHFFelicaRequestService(const char *Cmd) { flags |= FELICA_RAW; } datalen = (datalen > PM3_CMD_DATA_SIZE) ? PM3_CMD_DATA_SIZE : datalen; + if(!custom_IDm){ + if(!add_last_IDm(2, data)){ + PrintAndLogEx(ERR, "No last known card! Use reader first or set a custom IDm!"); + return PM3_EINVARG; + }else{ + PrintAndLogEx(INFO, "Used last known IDm.", sprint_hex(data, datalen)); + } + } + data[0] = int_to_hex(&datalen); + data[1] = 0x02; // Request Command ID + add_crc_bytes(&datalen, data, sizeof(data)); + PrintAndLogEx(NORMAL, "Send Service Request Frame: %s", sprint_hex(data, datalen)); clearCommandBuffer(); - PrintAndLogEx(NORMAL, "Data: %s", data); SendCommandMIX(CMD_HF_FELICA_COMMAND, flags, (datalen & 0xFFFF) | (uint32_t)(numbits << 16), 0, data, datalen); + PacketResponseNG resp; if (custom_IDm) { - waitCmdFelica(1); + waitCmdFelica(1, &resp); } if (datalen > 0) { - waitCmdFelica(0); + if(!waitCmdFelica(0, &resp)){ + return PM3_ESOFT; + } + felica_request_service_response_t rqs_response; + memcpy(&rqs_response, (felica_request_service_response_t *)resp.data.asBytes, sizeof(felica_request_service_response_t)); + + PrintAndLogEx(SUCCESS, "\nGot Service Response:"); + PrintAndLogEx(NORMAL, "IDm: %s", sprint_hex(rqs_response.IDm, sizeof(rqs_response.IDm))); + PrintAndLogEx(NORMAL, " -Node Number: %s", sprint_hex(rqs_response.node_number, sizeof(rqs_response.node_number))); + PrintAndLogEx(NORMAL, " -Node Key Version List: %s\n", sprint_hex(rqs_response.node_key_versions, sizeof(rqs_response.node_key_versions))); + }else{ + return PM3_ESOFT; } return PM3_SUCCESS; } @@ -602,8 +660,6 @@ static int CmdHFFelicaDumpLite(const char *Cmd) { return PM3_SUCCESS; } - - static int CmdHFFelicaCmdRaw(const char *Cmd) { bool reply = 1; bool crc = false; @@ -703,15 +759,18 @@ static int CmdHFFelicaCmdRaw(const char *Cmd) { datalen = (datalen > PM3_CMD_DATA_SIZE) ? PM3_CMD_DATA_SIZE : datalen; clearCommandBuffer(); + PrintAndLogEx(NORMAL, "Data: %s", sprint_hex(data, datalen)); SendCommandMIX(CMD_HF_FELICA_COMMAND, flags, (datalen & 0xFFFF) | (uint32_t)(numbits << 16), 0, data, datalen); if (reply) { if (active_select) { PrintAndLogEx(NORMAL, "Active select wait for FeliCa."); - waitCmdFelica(1); + PacketResponseNG resp_IDm; + waitCmdFelica(1, &resp_IDm); } if (datalen > 0) { - waitCmdFelica(0); + PacketResponseNG resp_frame; + waitCmdFelica(0, &resp_frame); } } return PM3_SUCCESS; @@ -724,7 +783,6 @@ int readFelicaUid(bool verbose) { PacketResponseNG resp; if (!WaitForResponseTimeout(CMD_ACK, &resp, 2500)) { if (verbose) PrintAndLogEx(WARNING, "FeliCa card select failed"); - //SendCommandMIX(CMD_HF_FELICA_COMMAND, 0, 0, 0, NULL, 0); return PM3_ESOFT; } @@ -761,6 +819,7 @@ int readFelicaUid(bool verbose) { PrintAndLogEx(NORMAL, " - MRT %s", sprint_hex(card.mrt, sizeof(card.mrt))); PrintAndLogEx(NORMAL, "SERVICE CODE %s", sprint_hex(card.servicecode, sizeof(card.servicecode))); + set_last_known_card(card); break; } } diff --git a/include/mifare.h b/include/mifare.h index 23dbceb68..32427309d 100644 --- a/include/mifare.h +++ b/include/mifare.h @@ -169,6 +169,15 @@ typedef struct { uint8_t servicecode[2]; } PACKED felica_card_select_t; +typedef struct { + uint8_t sync[4]; + uint8_t length[1]; + uint8_t cmd_code[1]; + uint8_t IDm[8]; + uint8_t node_number[1]; + uint8_t node_key_versions[2]; +} PACKED felica_request_service_response_t; + typedef enum FELICA_COMMAND { FELICA_CONNECT = (1 << 0), FELICA_NO_DISCONNECT = (1 << 1), From 3f56116615bf3da583e4ce81dda63ea835e28306 Mon Sep 17 00:00:00 2001 From: Thomas Sutter Date: Tue, 22 Oct 2019 17:03:54 +0200 Subject: [PATCH 1044/1854] Add felica request service all nodes command. Make style. --- armsrc/felica.c | 4 +- client/cmdhffelica.c | 107 ++++++++++++++++++++------------ client/cmdhffelica.h | 1 + client/luascripts/init_rdv4.lua | 2 +- include/mifare.h | 2 +- 5 files changed, 71 insertions(+), 45 deletions(-) diff --git a/armsrc/felica.c b/armsrc/felica.c index 83ff2bea3..cc9c2c9ed 100644 --- a/armsrc/felica.c +++ b/armsrc/felica.c @@ -420,8 +420,8 @@ bool WaitForFelicaReply(uint16_t maxbytes) { Process18092Byte(b); if (FelicaFrame.state == STATE_FULL) { felica_nexttransfertime = MAX(felica_nexttransfertime, - (GetCountSspClk() & 0xfffffff8) - (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER) / 16 + FELICA_FRAME_DELAY_TIME - ); + (GetCountSspClk() & 0xfffffff8) - (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER) / 16 + FELICA_FRAME_DELAY_TIME + ); LogTrace( FelicaFrame.framebytes, FelicaFrame.len, diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index 81fb3e67d..bcca6f63a 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -26,7 +26,7 @@ static int CmdHelp(const char *Cmd); static felica_card_select_t last_known_card; -static void set_last_known_card(felica_card_select_t card){ +static void set_last_known_card(felica_card_select_t card) { last_known_card = card; } @@ -91,13 +91,16 @@ static int usage_hf_felica_request_service(void) { PrintAndLogEx(NORMAL, " - When the specified Area or Service exists, the card returns Key Version."); PrintAndLogEx(NORMAL, " - When the specified Area or Service does not exist, the card returns FFFFh as Key Version."); PrintAndLogEx(NORMAL, "For Node Code List of a command packet, Area Code or Service Code of the target " - "of acquisition of Key Version shall be enumerated in Little Endian format." - "If Key Version of System is the target of acquisition, FFFFh shall be specified " - "in the command packet."); + "of acquisition of Key Version shall be enumerated in Little Endian format." + "If Key Version of System is the target of acquisition, FFFFh shall be specified " + "in the command packet."); PrintAndLogEx(NORMAL, "\nUsage: hf felica rqservice [-h] [-i] <01 Number of Node hex> <0A 0B Node Code List hex (Little Endian)>"); PrintAndLogEx(NORMAL, " -h this help"); PrintAndLogEx(NORMAL, " -i <0A 0B 0C ... hex> set custom IDm to use"); - PrintAndLogEx(NORMAL, "\nExample: hf felica rqservice 01 FFFF \n\n"); + PrintAndLogEx(NORMAL, "\nExamples: hf felica rqservice 01 FF FF"); + PrintAndLogEx(NORMAL, " hf felica rqservice 01 FF FF"); + PrintAndLogEx(NORMAL, " hf felica rqs -a FF FF"); + PrintAndLogEx(NORMAL, " hf felica rqs -i 01 10 09 10 c1 1b c4 07 01 FF FF \n\n"); return PM3_SUCCESS; } @@ -109,7 +112,7 @@ static bool waitCmdFelica(uint8_t iSelect, PacketResponseNG *resp) { if (WaitForResponseTimeout(CMD_ACK, resp, 2000)) { uint16_t len = iSelect ? (resp->oldarg[1] & 0xffff) : (resp->oldarg[0] & 0xffff); PrintAndLogEx(NORMAL, "Client Received %i octets", len); - if (!len || len < 2){ + if (!len || len < 2) { PrintAndLogEx(ERR, "Could not receive data correctly!"); } PrintAndLogEx(NORMAL, "%s", sprint_hex(resp->data.asBytes, len)); @@ -120,7 +123,7 @@ static bool waitCmdFelica(uint8_t iSelect, PacketResponseNG *resp) { } else { PrintAndLogEx(WARNING, "Timeout while waiting for reply."); } - return false; + return false; } /* @@ -150,7 +153,7 @@ static bool is_hex_input(const char *Cmd, int i) { } /** - * Add crc bytes to the end of the given data. + * Add crc bytes to the end of the given data and increments datalen. * @param datalen length of the data frame. * @param data frame on which the crc is calculated. * @param size of the data. @@ -189,7 +192,7 @@ static void get_cmd_data(const char *Cmd, uint16_t *datalen, uint8_t *data, char * @param number number of hex bytes. * @return number as hex value. */ -static uint8_t int_to_hex(uint16_t *number){ +static uint8_t int_to_hex(uint16_t *number) { uint32_t hex; char dataLengthChar[5]; sprintf(dataLengthChar, "%x", *number); @@ -203,14 +206,14 @@ static uint8_t int_to_hex(uint16_t *number){ * @param data frame in where the IDM is added. * @return true if IDm was added; */ -static bool add_last_IDm(uint8_t position, uint8_t *data){ - if(last_known_card.IDm[0] != 0 && last_known_card.IDm[1] != 0){ - for(int i = 0; i < 8; i++){ +static bool add_last_IDm(uint8_t position, uint8_t *data) { + if (last_known_card.IDm[0] != 0 && last_known_card.IDm[1] != 0) { + for (int i = 0; i < 8; i++) { uint16_t number = (uint16_t)last_known_card.IDm[i]; - data[position+i] = int_to_hex(&number); + data[position + i] = int_to_hex(&number); } return true; - }else{ + } else { return false; } } @@ -242,6 +245,32 @@ static int CmdHFFelicaDump(const char *Cmd) { return PM3_SUCCESS; }*/ +/** + * Sends a request service frame to the pm3. + */ +void send_request_service(uint8_t flags, uint16_t datalen, uint8_t *data) { + uint16_t numbits = 0; + clearCommandBuffer(); + PrintAndLogEx(NORMAL, "Send Service Request Frame: %s", sprint_hex(data, datalen)); + SendCommandMIX(CMD_HF_FELICA_COMMAND, flags, (datalen & 0xFFFF) | (uint32_t)(numbits << 16), 0, data, datalen); + PacketResponseNG resp; + if (datalen > 0) { + if (!waitCmdFelica(0, &resp)) { + PrintAndLogEx(ERR, "\nGot no Response from card"); + return; + } + felica_request_service_response_t rqs_response; + memcpy(&rqs_response, (felica_request_service_response_t *)resp.data.asBytes, sizeof(felica_request_service_response_t)); + + if (rqs_response.IDm[0] != 0) { + PrintAndLogEx(SUCCESS, "\nGot Service Response:"); + PrintAndLogEx(NORMAL, "IDm: %s", sprint_hex(rqs_response.IDm, sizeof(rqs_response.IDm))); + PrintAndLogEx(NORMAL, " -Node Number: %s", sprint_hex(rqs_response.node_number, sizeof(rqs_response.node_number))); + PrintAndLogEx(NORMAL, " -Node Key Version List: %s\n", sprint_hex(rqs_response.node_key_versions, sizeof(rqs_response.node_key_versions))); + } + } +} + /** * Command parser for rqservice. * @param Cmd input data of the user. @@ -252,23 +281,29 @@ static int CmdHFFelicaRequestService(const char *Cmd) { int i = 0; uint8_t data[PM3_CMD_DATA_SIZE]; bool custom_IDm = false; + bool all_nodes = false; uint16_t datalen = 0; uint8_t flags = 0; - uint16_t numbits = 0; + char buf[5] = ""; - datalen += 10; // length (1) + CMD (1) + IDm (8) + datalen += 10; // length (1) + CMD (1) + IDm(8) strip_cmds(Cmd); while (Cmd[i] != '\0') { if (Cmd[i] == '-') { switch (Cmd[i + 1]) { case 'H': case 'h': - return usage_hf_felica_raw(); + return usage_hf_felica_request_service(); case 'i': custom_IDm = true; + datalen -= 8; + break; + case 'a': + all_nodes = true; + datalen += 1; break; default: - return usage_hf_felica_raw(); + return usage_hf_felica_request_service(); } i += 2; } @@ -290,38 +325,28 @@ static int CmdHFFelicaRequestService(const char *Cmd) { flags |= FELICA_RAW; } datalen = (datalen > PM3_CMD_DATA_SIZE) ? PM3_CMD_DATA_SIZE : datalen; - if(!custom_IDm){ - if(!add_last_IDm(2, data)){ + if (!custom_IDm) { + if (!add_last_IDm(2, data)) { PrintAndLogEx(ERR, "No last known card! Use reader first or set a custom IDm!"); return PM3_EINVARG; - }else{ + } else { PrintAndLogEx(INFO, "Used last known IDm.", sprint_hex(data, datalen)); } } data[0] = int_to_hex(&datalen); data[1] = 0x02; // Request Command ID - add_crc_bytes(&datalen, data, sizeof(data)); - PrintAndLogEx(NORMAL, "Send Service Request Frame: %s", sprint_hex(data, datalen)); - clearCommandBuffer(); - SendCommandMIX(CMD_HF_FELICA_COMMAND, flags, (datalen & 0xFFFF) | (uint32_t)(numbits << 16), 0, data, datalen); - PacketResponseNG resp; - if (custom_IDm) { - waitCmdFelica(1, &resp); - } - if (datalen > 0) { - if(!waitCmdFelica(0, &resp)){ - return PM3_ESOFT; + if (all_nodes) { + for (uint16_t y = 1; y < 32; y++) { + data[10] = int_to_hex(&y); + add_crc_bytes(&datalen, data, sizeof(data)); + send_request_service(flags, datalen, data); + datalen -= 2; // Remove CRC bytes before adding new ones } - felica_request_service_response_t rqs_response; - memcpy(&rqs_response, (felica_request_service_response_t *)resp.data.asBytes, sizeof(felica_request_service_response_t)); - - PrintAndLogEx(SUCCESS, "\nGot Service Response:"); - PrintAndLogEx(NORMAL, "IDm: %s", sprint_hex(rqs_response.IDm, sizeof(rqs_response.IDm))); - PrintAndLogEx(NORMAL, " -Node Number: %s", sprint_hex(rqs_response.node_number, sizeof(rqs_response.node_number))); - PrintAndLogEx(NORMAL, " -Node Key Version List: %s\n", sprint_hex(rqs_response.node_key_versions, sizeof(rqs_response.node_key_versions))); - }else{ - return PM3_ESOFT; + } else { + add_crc_bytes(&datalen, data, sizeof(data)); + send_request_service(flags, datalen, data); } + return PM3_SUCCESS; } diff --git a/client/cmdhffelica.h b/client/cmdhffelica.h index 59032ee31..dd127cfaf 100644 --- a/client/cmdhffelica.h +++ b/client/cmdhffelica.h @@ -15,4 +15,5 @@ int CmdHFFelica(const char *Cmd); int readFelicaUid(bool verbose); +void send_request_service(uint8_t flags, uint16_t datalen, uint8_t *data); #endif diff --git a/client/luascripts/init_rdv4.lua b/client/luascripts/init_rdv4.lua index 4836cda77..d2dd03e24 100644 --- a/client/luascripts/init_rdv4.lua +++ b/client/luascripts/init_rdv4.lua @@ -88,7 +88,7 @@ function main(args) print('') core.console('hw status') print(dash) - + print('all done!') end diff --git a/include/mifare.h b/include/mifare.h index 32427309d..5461bd19f 100644 --- a/include/mifare.h +++ b/include/mifare.h @@ -170,7 +170,7 @@ typedef struct { } PACKED felica_card_select_t; typedef struct { - uint8_t sync[4]; + uint8_t sync[2]; uint8_t length[1]; uint8_t cmd_code[1]; uint8_t IDm[8]; From b6117e499695b9fe05cb1743c904b1184054a37d Mon Sep 17 00:00:00 2001 From: Thomas Sutter Date: Tue, 22 Oct 2019 17:10:32 +0200 Subject: [PATCH 1045/1854] Add parameter a to usage text. --- client/cmdhffelica.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index bcca6f63a..1c276c629 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -91,13 +91,14 @@ static int usage_hf_felica_request_service(void) { PrintAndLogEx(NORMAL, " - When the specified Area or Service exists, the card returns Key Version."); PrintAndLogEx(NORMAL, " - When the specified Area or Service does not exist, the card returns FFFFh as Key Version."); PrintAndLogEx(NORMAL, "For Node Code List of a command packet, Area Code or Service Code of the target " - "of acquisition of Key Version shall be enumerated in Little Endian format." + "of acquisition of Key Version shall be enumerated in Little Endian format. " "If Key Version of System is the target of acquisition, FFFFh shall be specified " "in the command packet."); PrintAndLogEx(NORMAL, "\nUsage: hf felica rqservice [-h] [-i] <01 Number of Node hex> <0A 0B Node Code List hex (Little Endian)>"); PrintAndLogEx(NORMAL, " -h this help"); PrintAndLogEx(NORMAL, " -i <0A 0B 0C ... hex> set custom IDm to use"); - PrintAndLogEx(NORMAL, "\nExamples: hf felica rqservice 01 FF FF"); + PrintAndLogEx(NORMAL, " -a auto node number mode - iterates through all possible node 1 < n < 32"); + PrintAndLogEx(NORMAL, "\nExamples: "); PrintAndLogEx(NORMAL, " hf felica rqservice 01 FF FF"); PrintAndLogEx(NORMAL, " hf felica rqs -a FF FF"); PrintAndLogEx(NORMAL, " hf felica rqs -i 01 10 09 10 c1 1b c4 07 01 FF FF \n\n"); From 22743831297b29eee59916a1ba8949210c33de6b Mon Sep 17 00:00:00 2001 From: Thomas Sutter Date: Wed, 23 Oct 2019 09:21:43 +0200 Subject: [PATCH 1046/1854] Remove crc methode. Add CRC macro. Change help text for request service. --- armsrc/felica.c | 2 +- client/cmdhffelica.c | 52 ++++++++++---------------------------------- 2 files changed, 12 insertions(+), 42 deletions(-) diff --git a/armsrc/felica.c b/armsrc/felica.c index cc9c2c9ed..09e2b582f 100644 --- a/armsrc/felica.c +++ b/armsrc/felica.c @@ -3,7 +3,7 @@ #include "BigBuf.h" #include "util.h" #include "protocols.h" -#include "crc16.h" // crc16 ccitt +#include "crc16.h" #include "fpgaloader.h" #include "string.h" #include "commonutil.h" diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index 1c276c629..dfdbfe887 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -22,6 +22,7 @@ #include "ui.h" #include "mifare.h" // felica_card_select_t struct +#define AddCrc(data, len) compute_crc(CRC_FELICA, (data), (len), (data)+(len)+1, (data)+(len)) static int CmdHelp(const char *Cmd); static felica_card_select_t last_known_card; @@ -100,8 +101,8 @@ static int usage_hf_felica_request_service(void) { PrintAndLogEx(NORMAL, " -a auto node number mode - iterates through all possible node 1 < n < 32"); PrintAndLogEx(NORMAL, "\nExamples: "); PrintAndLogEx(NORMAL, " hf felica rqservice 01 FF FF"); - PrintAndLogEx(NORMAL, " hf felica rqs -a FF FF"); - PrintAndLogEx(NORMAL, " hf felica rqs -i 01 10 09 10 c1 1b c4 07 01 FF FF \n\n"); + PrintAndLogEx(NORMAL, " hf felica rqservice -a FF FF"); + PrintAndLogEx(NORMAL, " hf felica rqservice -i 01 10 09 10 c1 1b c4 07 01 FF FF \n\n"); return PM3_SUCCESS; } @@ -153,24 +154,6 @@ static bool is_hex_input(const char *Cmd, int i) { return (Cmd[i] >= '0' && Cmd[i] <= '9') || (Cmd[i] >= 'a' && Cmd[i] <= 'f') || (Cmd[i] >= 'A' && Cmd[i] <= 'F') ? 1 : 0; } -/** - * Add crc bytes to the end of the given data and increments datalen. - * @param datalen length of the data frame. - * @param data frame on which the crc is calculated. - * @param size of the data. - * @return true if the crc was added. - */ -static bool add_crc_bytes(uint16_t *datalen, uint8_t *data, size_t dataSize) { - if (*datalen > 0 && *datalen < dataSize - 2) { - uint8_t b1, b2; - compute_crc(CRC_FELICA, data, *datalen, &b1, &b2); - data[(*datalen)++] = b2; - data[(*datalen)++] = b1; - return 1; - } - return 0; -} - /** * Extracts the hex data from the cmd and puts it into the data array. * @param Cmd input string of the user with the data @@ -219,17 +202,8 @@ static bool add_last_IDm(uint8_t position, uint8_t *data) { } } -/* -static int usage_hf_felica_dump(void) { - // TODO IMPLEMENT - PrintAndLogEx(NORMAL, "Usage: hf felica dump [-h] "); - PrintAndLogEx(NORMAL, " -h this help"); - return PM3_SUCCESS; -}*/ - static int CmdHFFelicaList(const char *Cmd) { - (void)Cmd; // Cmd is not used so far - //PrintAndLogEx(NORMAL, "Deprecated command, use 'hf list felica' instead"); + (void)Cmd; CmdTraceList("felica"); return PM3_SUCCESS; } @@ -239,13 +213,6 @@ static int CmdHFFelicaReader(const char *Cmd) { return readFelicaUid(verbose); } -/* -static int CmdHFFelicaDump(const char *Cmd) { - if (strlen(Cmd) < 1) return usage_hf_felica_dump(); - // TODO IMPLEMENT - return PM3_SUCCESS; -}*/ - /** * Sends a request service frame to the pm3. */ @@ -314,7 +281,7 @@ static int CmdHFFelicaRequestService(const char *Cmd) { buf[strlen(buf)] = Cmd[i]; i++; get_cmd_data(Cmd, &datalen, data, buf); - } else { + } else { i++; } } @@ -339,12 +306,14 @@ static int CmdHFFelicaRequestService(const char *Cmd) { if (all_nodes) { for (uint16_t y = 1; y < 32; y++) { data[10] = int_to_hex(&y); - add_crc_bytes(&datalen, data, sizeof(data)); + AddCrc(data, datalen); send_request_service(flags, datalen, data); datalen -= 2; // Remove CRC bytes before adding new ones } } else { - add_crc_bytes(&datalen, data, sizeof(data)); + PrintAndLogEx(INFO, "Datalen %i", datalen); + AddCrc(data, datalen); + datalen += 2; send_request_service(flags, datalen, data); } @@ -763,7 +732,8 @@ static int CmdHFFelicaCmdRaw(const char *Cmd) { } if (crc) { - add_crc_bytes(&datalen, data, sizeof(data)); + AddCrc(data, datalen); + datalen += 2; } uint8_t flags = 0; From 21f0095029b80e9150cd6d9b6033e66298196075 Mon Sep 17 00:00:00 2001 From: Thomas Sutter Date: Wed, 23 Oct 2019 09:42:45 +0200 Subject: [PATCH 1047/1854] Make Style. --- client/cmdhffelica.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index dfdbfe887..e7e410d4b 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -281,7 +281,7 @@ static int CmdHFFelicaRequestService(const char *Cmd) { buf[strlen(buf)] = Cmd[i]; i++; get_cmd_data(Cmd, &datalen, data, buf); - } else { + } else { i++; } } From bdbb4cb5c940fd0bf72775e0a41a03ded56fb32f Mon Sep 17 00:00:00 2001 From: Thomas Sutter Date: Wed, 23 Oct 2019 13:25:52 +0200 Subject: [PATCH 1048/1854] Refactor request service parsing. Change Examples. --- client/cmdhffelica.c | 92 ++++++++++++++++++-------------------------- 1 file changed, 37 insertions(+), 55 deletions(-) diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index e7e410d4b..bad416212 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -19,7 +19,7 @@ #include "comms.h" #include "cmdtrace.h" #include "crc16.h" - +#include "util.h" #include "ui.h" #include "mifare.h" // felica_card_select_t struct #define AddCrc(data, len) compute_crc(CRC_FELICA, (data), (len), (data)+(len)+1, (data)+(len)) @@ -98,11 +98,11 @@ static int usage_hf_felica_request_service(void) { PrintAndLogEx(NORMAL, "\nUsage: hf felica rqservice [-h] [-i] <01 Number of Node hex> <0A 0B Node Code List hex (Little Endian)>"); PrintAndLogEx(NORMAL, " -h this help"); PrintAndLogEx(NORMAL, " -i <0A 0B 0C ... hex> set custom IDm to use"); - PrintAndLogEx(NORMAL, " -a auto node number mode - iterates through all possible node 1 < n < 32"); + PrintAndLogEx(NORMAL, " -a auto node number mode - iterates through all possible nodes 1 < n < 32"); PrintAndLogEx(NORMAL, "\nExamples: "); - PrintAndLogEx(NORMAL, " hf felica rqservice 01 FF FF"); - PrintAndLogEx(NORMAL, " hf felica rqservice -a FF FF"); - PrintAndLogEx(NORMAL, " hf felica rqservice -i 01 10 09 10 c1 1b c4 07 01 FF FF \n\n"); + PrintAndLogEx(NORMAL, " hf felica rqservice 01 FFFF"); + PrintAndLogEx(NORMAL, " hf felica rqservice -a FFFF"); + PrintAndLogEx(NORMAL, " hf felica rqservice -i 01100910c11bc407 01 FFFF \n\n"); return PM3_SUCCESS; } @@ -129,15 +129,7 @@ static bool waitCmdFelica(uint8_t iSelect, PacketResponseNG *resp) { } /* - * Parses line spacing and tabs. - * Returns 1 if the given char is a space or tab - */ -static int parse_cmd_parameter_separator(const char *Cmd, int i) { - return Cmd[i] == ' ' || Cmd[i] == '\t' ? 1 : 0; -} - -/* - * Counts and sets the number of commands. + * Counts and sets the number of parameters. */ static void strip_cmds(const char *Cmd) { while (*Cmd == ' ' || *Cmd == '\t') { @@ -145,34 +137,9 @@ static void strip_cmds(const char *Cmd) { } } -/** - * Checks if a char is a hex value. - * @param Cmd - * @return one if it is a valid hex char. Zero if not a valid hex char. - */ -static bool is_hex_input(const char *Cmd, int i) { - return (Cmd[i] >= '0' && Cmd[i] <= '9') || (Cmd[i] >= 'a' && Cmd[i] <= 'f') || (Cmd[i] >= 'A' && Cmd[i] <= 'F') ? 1 : 0; -} - -/** - * Extracts the hex data from the cmd and puts it into the data array. - * @param Cmd input string of the user with the data - * @param datalen length of the data frame. - * @param data the array in which the data gets stored. - * @param buf buffer with hex data. - */ -static void get_cmd_data(const char *Cmd, uint16_t *datalen, uint8_t *data, char buf[]) { - uint32_t hex; - if (strlen(buf) >= 2) { - sscanf(buf, "%x", &hex); - data[*datalen] = (uint8_t)(hex & 0xff); - (*datalen)++; - *buf = 0; - } -} - /** * Converts integer value to equivalent hex value. + * Examples: 1 = 1, 11 = B * @param number number of hex bytes. * @return number as hex value. */ @@ -250,11 +217,9 @@ static int CmdHFFelicaRequestService(const char *Cmd) { uint8_t data[PM3_CMD_DATA_SIZE]; bool custom_IDm = false; bool all_nodes = false; - uint16_t datalen = 0; + uint16_t datalen = 13; // length (1) + CMD (1) + IDm(8) + Node Number (1) + Node Code List (2) uint8_t flags = 0; - - char buf[5] = ""; - datalen += 10; // length (1) + CMD (1) + IDm(8) + uint8_t paramCount = 0; strip_cmds(Cmd); while (Cmd[i] != '\0') { if (Cmd[i] == '-') { @@ -263,28 +228,45 @@ static int CmdHFFelicaRequestService(const char *Cmd) { case 'h': return usage_hf_felica_request_service(); case 'i': + paramCount++; custom_IDm = true; - datalen -= 8; + if (param_getlength(Cmd, paramCount) == 16) { + param_gethex(Cmd, paramCount++, data + 2, 16); + } else { + PrintAndLogEx(ERR, "Incorrect IDm length! IDm must be 8-Byte."); + return PM3_EINVARG; + } + i += 8; break; case 'a': + paramCount++; all_nodes = true; - datalen += 1; break; default: return usage_hf_felica_request_service(); } i += 2; } - i = i + parse_cmd_parameter_separator(Cmd, i); - if (is_hex_input(Cmd, i)) { - buf[strlen(buf) + 1] = 0; - buf[strlen(buf)] = Cmd[i]; - i++; - get_cmd_data(Cmd, &datalen, data, buf); + i++; + } + if (!all_nodes) { + // Node Number + if (param_getlength(Cmd, paramCount) == 2) { + param_gethex(Cmd, paramCount++, data + 10, 2); } else { - i++; + PrintAndLogEx(ERR, "Incorrect Node number length!"); + return PM3_EINVARG; } } + + // Node Code List + if (param_getlength(Cmd, paramCount) == 4) { + param_gethex(Cmd, paramCount++, data + 11, 4); + } else { + PrintAndLogEx(ERR, "Incorrect Node Code List length!"); + return PM3_EINVARG; + } + flags |= FELICA_APPEND_CRC; if (custom_IDm) { flags |= FELICA_NO_SELECT; @@ -302,16 +284,16 @@ static int CmdHFFelicaRequestService(const char *Cmd) { } } data[0] = int_to_hex(&datalen); - data[1] = 0x02; // Request Command ID + data[1] = 0x02; // Service Request Command ID if (all_nodes) { for (uint16_t y = 1; y < 32; y++) { data[10] = int_to_hex(&y); AddCrc(data, datalen); + datalen += 2; send_request_service(flags, datalen, data); datalen -= 2; // Remove CRC bytes before adding new ones } } else { - PrintAndLogEx(INFO, "Datalen %i", datalen); AddCrc(data, datalen); datalen += 2; send_request_service(flags, datalen, data); From 1f7dd3e2a7e9f290bc24bb58688d4e3db1841053 Mon Sep 17 00:00:00 2001 From: Thomas Sutter Date: Wed, 23 Oct 2019 14:48:23 +0200 Subject: [PATCH 1049/1854] Add request response command for felica Mode. --- CHANGELOG.md | 3 + client/cmdhffelica.c | 142 ++++++++++++++++++++++++++++++++++--------- include/mifare.h | 8 +++ 3 files changed, 123 insertions(+), 30 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cc6237f6a..168199c2b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,9 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Added hf felica rqresponse (@7homasSutter) + - Added hf felica rqservice (@7homasSutter) + - Added polling for felica standard (@7homasSutter) - Added lf t55xx dump save and lf t55xx restore for .bin and .eml files (@mwalker33) - Added lf t55xx detected to try without password first (@mwalker33) - Chg `lf indala read` - added indala 26bit decoding (@martinbeier) diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index bad416212..1b46f68e5 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -95,9 +95,9 @@ static int usage_hf_felica_request_service(void) { "of acquisition of Key Version shall be enumerated in Little Endian format. " "If Key Version of System is the target of acquisition, FFFFh shall be specified " "in the command packet."); - PrintAndLogEx(NORMAL, "\nUsage: hf felica rqservice [-h] [-i] <01 Number of Node hex> <0A 0B Node Code List hex (Little Endian)>"); + PrintAndLogEx(NORMAL, "\nUsage: hf felica rqservice [-h] [-i] <01 Number of Node hex> <0A0B Node Code List hex (Little Endian)>"); PrintAndLogEx(NORMAL, " -h this help"); - PrintAndLogEx(NORMAL, " -i <0A 0B 0C ... hex> set custom IDm to use"); + PrintAndLogEx(NORMAL, " -i <0A0B0C ... hex> set custom IDm to use"); PrintAndLogEx(NORMAL, " -a auto node number mode - iterates through all possible nodes 1 < n < 32"); PrintAndLogEx(NORMAL, "\nExamples: "); PrintAndLogEx(NORMAL, " hf felica rqservice 01 FFFF"); @@ -106,6 +106,16 @@ static int usage_hf_felica_request_service(void) { return PM3_SUCCESS; } +static int usage_hf_felica_request_response(void) { + PrintAndLogEx(NORMAL, "\nInfo: Use this command to verify the existence of a card and its Mode."); + PrintAndLogEx(NORMAL, " - Current Mode of the card is returned."); + PrintAndLogEx(NORMAL, "\nUsage: hf felica rqresponse [-h]"); + PrintAndLogEx(NORMAL, " -h this help"); + PrintAndLogEx(NORMAL, " -i <0A0B0C ... hex> set custom IDm to use"); + + return PM3_SUCCESS; +} + /** * Wait for response from pm3 or timeout. * Checks if receveid bytes have a valid CRC. @@ -181,13 +191,20 @@ static int CmdHFFelicaReader(const char *Cmd) { } /** - * Sends a request service frame to the pm3. + * Clears command buffer and sends the given data to pm3 with mix mode. */ -void send_request_service(uint8_t flags, uint16_t datalen, uint8_t *data) { +static void clear_and_send_command(uint8_t flags, uint16_t datalen, uint8_t *data) { uint16_t numbits = 0; clearCommandBuffer(); PrintAndLogEx(NORMAL, "Send Service Request Frame: %s", sprint_hex(data, datalen)); SendCommandMIX(CMD_HF_FELICA_COMMAND, flags, (datalen & 0xFFFF) | (uint32_t)(numbits << 16), 0, data, datalen); +} + +/** + * Sends a request service frame to the pm3. + */ +void send_request_service(uint8_t flags, uint16_t datalen, uint8_t *data) { + clear_and_send_command(flags, datalen, data); PacketResponseNG resp; if (datalen > 0) { if (!waitCmdFelica(0, &resp)) { @@ -206,6 +223,71 @@ void send_request_service(uint8_t flags, uint16_t datalen, uint8_t *data) { } } +/** + * Command parser for rqresponse + * @param Cmd input data of the user. + * @return client result code. + */ +static int CmdHFFelicaRequestResponse(const char *Cmd) { + uint8_t data[PM3_CMD_DATA_SIZE]; + bool custom_IDm = false; + strip_cmds(Cmd); + uint16_t datalen = 10; // Length (1), Command ID (1), IDm (8) + uint8_t paramCount = 0; + uint8_t flags = 0; + int i = 0; + while (Cmd[i] != '\0') { + if (Cmd[i] == '-') { + switch (Cmd[i + 1]) { + case 'H': + case 'h': + return usage_hf_felica_request_response(); + case 'i': + paramCount++; + custom_IDm = true; + if (param_getlength(Cmd, paramCount) == 16) { + param_gethex(Cmd, paramCount++, data + 2, 16); + } else { + PrintAndLogEx(ERR, "Incorrect IDm length! IDm must be 8-Byte."); + return PM3_EINVARG; + } + break; + } + } + i++; + } + data[0] = 0x0A; // Static length + data[1] = 0x04; // Command ID + if (!custom_IDm) { + if (!add_last_IDm(2, data)) { + PrintAndLogEx(ERR, "No last known card! Use reader first or set a custom IDm!"); + return PM3_EINVARG; + } else { + PrintAndLogEx(INFO, "Used last known IDm.", sprint_hex(data, datalen)); + } + } + AddCrc(data, datalen); + datalen += 2; + flags |= FELICA_APPEND_CRC; + flags |= FELICA_RAW; + clear_and_send_command(flags, datalen, data); + PacketResponseNG resp; + if (!waitCmdFelica(0, &resp)) { + PrintAndLogEx(ERR, "\nGot no Response from card"); + return PM3_ERFTRANS; + } else { + felica_request_request_response_t rq_response; + memcpy(&rq_response, (felica_request_request_response_t *)resp.data.asBytes, sizeof(felica_request_request_response_t)); + if (rq_response.IDm[0] != 0) { + PrintAndLogEx(SUCCESS, "\nGot Request Response:"); + PrintAndLogEx(NORMAL, "IDm: %s", sprint_hex(rq_response.IDm, sizeof(rq_response.IDm))); + PrintAndLogEx(NORMAL, " -Mode: %s\n\n", sprint_hex(rq_response.mode, sizeof(rq_response.mode))); + } + } + return PM3_SUCCESS; +} + + /** * Command parser for rqservice. * @param Cmd input data of the user. @@ -806,36 +888,36 @@ int readFelicaUid(bool verbose) { static command_t CommandTable[] = { {"----------- General -----------", CmdHelp, IfPm3Iso14443a, ""}, - {"help", CmdHelp, AlwaysAvailable, "This help"}, - {"list", CmdHFFelicaList, AlwaysAvailable, "List ISO 18092/FeliCa history"}, - {"reader", CmdHFFelicaReader, IfPm3Felica, "Act like an ISO18092/FeliCa reader"}, - {"sniff", CmdHFFelicaSniff, IfPm3Felica, "Sniff ISO 18092/FeliCa traffic"}, - {"raw", CmdHFFelicaCmdRaw, IfPm3Felica, "Send raw hex data to tag"}, + {"help", CmdHelp, AlwaysAvailable, "This help"}, + {"list", CmdHFFelicaList, AlwaysAvailable, "List ISO 18092/FeliCa history"}, + {"reader", CmdHFFelicaReader, IfPm3Felica, "Act like an ISO18092/FeliCa reader"}, + {"sniff", CmdHFFelicaSniff, IfPm3Felica, "Sniff ISO 18092/FeliCa traffic"}, + {"raw", CmdHFFelicaCmdRaw, IfPm3Felica, "Send raw hex data to tag"}, {"----------- FeliCa Standard (support in progress) -----------", CmdHelp, IfPm3Iso14443a, ""}, - //{"dump", CmdHFFelicaDump, IfPm3Felica, "Wait for and try dumping FeliCa"}, - {"rqservice", CmdHFFelicaRequestService, IfPm3Felica, "verify the existence of Area and Service, and to acquire Key Version."}, - {"rqresponse", CmdHFFelicaNotImplementedYet, IfPm3Felica, "verify the existence of a card and its Mode."}, - //{"rdNoEncryption", CmdHFFelicaNotImplementedYet, IfPm3Felica, "read Block Data from authentication-not-required Service."}, + //{"dump", CmdHFFelicaDump, IfPm3Felica, "Wait for and try dumping FeliCa"}, + {"rqservice", CmdHFFelicaRequestService, IfPm3Felica, "verify the existence of Area and Service, and to acquire Key Version."}, + {"rqresponse", CmdHFFelicaRequestResponse, IfPm3Felica, "verify the existence of a card and its Mode."}, + {"rdNoEncryption", CmdHFFelicaNotImplementedYet, IfPm3Felica, "read Block Data from authentication-not-required Service."}, //{"wrNoEncryption", CmdHFFelicaNotImplementedYet, IfPm3Felica, "write Block Data to an authentication-required Service."}, - //{"searchSvCode", CmdHFFelicaNotImplementedYet, IfPm3Felica, "acquire Area Code and Service Code."}, - //{"rqSysCode", CmdHFFelicaNotImplementedYet, IfPm3Felica, "acquire System Code registered to the card."}, - //{"auth1", CmdHFFelicaNotImplementedYet, IfPm3Felica, "authenticate a card."}, - //{"auth2", CmdHFFelicaNotImplementedYet, IfPm3Felica, "allow a card to authenticate a Reader/Writer."}, - //{"read", CmdHFFelicaNotImplementedYet, IfPm3Felica, "read Block Data from authentication-required Service."}, - //{"write", CmdHFFelicaNotImplementedYet, IfPm3Felica, "write Block Data to an authentication-required Service."}, + //{"searchSvCode", CmdHFFelicaNotImplementedYet, IfPm3Felica, "acquire Area Code and Service Code."}, + //{"rqSysCode", CmdHFFelicaNotImplementedYet, IfPm3Felica, "acquire System Code registered to the card."}, + //{"auth1", CmdHFFelicaNotImplementedYet, IfPm3Felica, "authenticate a card."}, + //{"auth2", CmdHFFelicaNotImplementedYet, IfPm3Felica, "allow a card to authenticate a Reader/Writer."}, + //{"read", CmdHFFelicaNotImplementedYet, IfPm3Felica, "read Block Data from authentication-required Service."}, + //{"write", CmdHFFelicaNotImplementedYet, IfPm3Felica, "write Block Data to an authentication-required Service."}, //{"searchSvCodeV2", CmdHFFelicaNotImplementedYet, IfPm3Felica, "verify the existence of Area or Service, and to acquire Key Version."}, - //{"getSysStatus", CmdHFFelicaNotImplementedYet, IfPm3Felica, "acquire the setup information in System."}, - //{"rqSpecVer", CmdHFFelicaNotImplementedYet, IfPm3Felica, "acquire the version of card OS."}, - //{"resetMode", CmdHFFelicaNotImplementedYet, IfPm3Felica, "reset Mode to Mode 0."}, - //{"auth1V2", CmdHFFelicaNotImplementedYet, IfPm3Felica, "authenticate a card."}, - //{"auth2V2", CmdHFFelicaNotImplementedYet, IfPm3Felica, "allow a card to authenticate a Reader/Writer."}, - //{"readV2", CmdHFFelicaNotImplementedYet, IfPm3Felica, "read Block Data from authentication-required Service."}, - //{"writeV2", CmdHFFelicaNotImplementedYet, IfPm3Felica, "write Block Data to authentication-required Service."}, - //{"upRandomID", CmdHFFelicaNotImplementedYet, IfPm3Felica, "update Random ID (IDr)."}, + //{"getSysStatus", CmdHFFelicaNotImplementedYet, IfPm3Felica, "acquire the setup information in System."}, + //{"rqSpecVer", CmdHFFelicaNotImplementedYet, IfPm3Felica, "acquire the version of card OS."}, + //{"resetMode", CmdHFFelicaNotImplementedYet, IfPm3Felica, "reset Mode to Mode 0."}, + //{"auth1V2", CmdHFFelicaNotImplementedYet, IfPm3Felica, "authenticate a card."}, + //{"auth2V2", CmdHFFelicaNotImplementedYet, IfPm3Felica, "allow a card to authenticate a Reader/Writer."}, + //{"readV2", CmdHFFelicaNotImplementedYet, IfPm3Felica, "read Block Data from authentication-required Service."}, + //{"writeV2", CmdHFFelicaNotImplementedYet, IfPm3Felica, "write Block Data to authentication-required Service."}, + //{"upRandomID", CmdHFFelicaNotImplementedYet, IfPm3Felica, "update Random ID (IDr)."}, {"----------- FeliCa Light -----------", CmdHelp, IfPm3Iso14443a, ""}, - {"litesim", CmdHFFelicaSimLite, IfPm3Felica, " - only reply to poll request"}, - {"litedump", CmdHFFelicaDumpLite, IfPm3Felica, "Wait for and try dumping FelicaLite"}, - // {"sim", CmdHFFelicaSim, IfPm3Felica, " -- Simulate ISO 18092/FeliCa tag"} + {"litesim", CmdHFFelicaSimLite, IfPm3Felica, " - only reply to poll request"}, + {"litedump", CmdHFFelicaDumpLite, IfPm3Felica, "Wait for and try dumping FelicaLite"}, + // {"sim", CmdHFFelicaSim, IfPm3Felica, " -- Simulate ISO 18092/FeliCa tag"} {NULL, NULL, NULL, NULL} }; diff --git a/include/mifare.h b/include/mifare.h index 5461bd19f..754a0c82f 100644 --- a/include/mifare.h +++ b/include/mifare.h @@ -178,6 +178,14 @@ typedef struct { uint8_t node_key_versions[2]; } PACKED felica_request_service_response_t; +typedef struct { + uint8_t sync[2]; + uint8_t length[1]; + uint8_t cmd_code[1]; + uint8_t IDm[8]; + uint8_t mode[1]; +} PACKED felica_request_request_response_t; + typedef enum FELICA_COMMAND { FELICA_CONNECT = (1 << 0), FELICA_NO_DISCONNECT = (1 << 1), From e872ac58f747dadb318ffaf23d3073fedc80f3fd Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 24 Oct 2019 01:30:54 +0200 Subject: [PATCH 1050/1854] coverity 263770 fix dead code --- armsrc/felica.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/felica.c b/armsrc/felica.c index 4d9712a0d..1374927d8 100644 --- a/armsrc/felica.c +++ b/armsrc/felica.c @@ -792,7 +792,7 @@ void felica_send_request_service(uint8_t *request_service) { // When the specified Area or Service does not exist, the card returns FFFFh as Key Version. */ uint8_t *felica_create_request_service_frame(uint8_t nodeNumber, uint8_t *idm) { - if (nodeNumber < 1 && nodeNumber > 32) { + if (nodeNumber < 1 || nodeNumber > 32) { Dbprintf("Node number out of range: 1 <= %d <= 32 - set node number to 1"); nodeNumber = 1; } From 30da3cfd429d3e2019e1d1b2de69daf3df11bc5d Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 24 Oct 2019 01:32:44 +0200 Subject: [PATCH 1051/1854] coverity 263769 dereference before null check --- common/crapto1/crypto1.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/common/crapto1/crypto1.c b/common/crapto1/crypto1.c index bb501cd58..dd5541b29 100644 --- a/common/crapto1/crypto1.c +++ b/common/crapto1/crypto1.c @@ -26,12 +26,11 @@ (x = (x >> 8 & 0xff00ff) | (x & 0xff00ff) << 8, x = x >> 16 | x << 16) void crypto1_init(struct Crypto1State *state, uint64_t key) { + if (state == NULL) + return; state->odd = 0; state->even = 0; - - int i; - - for (i = 47; state && i > 0; i -= 2) { + for (int i = 47; i > 0; i -= 2) { state->odd = state->odd << 1 | BIT(key, (i - 1) ^ 7); state->even = state->even << 1 | BIT(key, i ^ 7); } From ff9eabdab50ade1d2440199290df950f3789e4a7 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 24 Oct 2019 01:35:58 +0200 Subject: [PATCH 1052/1854] coverity 226329 invalid type for printf --- client/cmdhffelica.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index 1fa5b035d..bdb9cc57f 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -421,7 +421,7 @@ static int CmdHFFelicaDumpLite(const char *Cmd) { return PM3_ETIMEOUT; } - PrintAndLogEx(SUCCESS, "Recorded Activity (trace len = %"PRIu64" bytes)", tracelen); + PrintAndLogEx(SUCCESS, "Recorded Activity (trace len = %"PRIu32" bytes)", tracelen); print_hex_break(trace, tracelen, 32); printSep(); From 3b0447fbb3ccf06799b45df298631058f5db738c Mon Sep 17 00:00:00 2001 From: Thomas Sutter Date: Thu, 24 Oct 2019 08:44:20 +0200 Subject: [PATCH 1053/1854] Draft read without encryption --- client/cmdhffelica.c | 54 ++++++++++++++++++++++++++++++++++++++++++-- include/mifare.h | 11 +++++++++ 2 files changed, 63 insertions(+), 2 deletions(-) diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index 1b46f68e5..f0c699b9b 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -116,6 +116,16 @@ static int usage_hf_felica_request_response(void) { return PM3_SUCCESS; } +static int usage_hf_felica_read_without_encryption(void) { + PrintAndLogEx(NORMAL, "\nInfo: Use this command to read Block Data from authentication-not-required Service."); + PrintAndLogEx(NORMAL, " - Mode shall be Mode0."); + PrintAndLogEx(NORMAL, "\nUsage: hf felica rdNoEncryption [-h]"); + PrintAndLogEx(NORMAL, " -h this help"); + PrintAndLogEx(NORMAL, " -i <0A0B0C ... hex> set custom IDm to use"); + + return PM3_SUCCESS; +} + /** * Wait for response from pm3 or timeout. * Checks if receveid bytes have a valid CRC. @@ -223,6 +233,46 @@ void send_request_service(uint8_t flags, uint16_t datalen, uint8_t *data) { } } +/** + * Command parser for rdNoEncryption. + * @param Cmd input data of the user. + * @return client result code. + */ +static int CmdHFFelicaReadWithoutEncryption(const char *Cmd) { + if (strlen(Cmd) < 4) + return usage_hf_felica_read_without_encryption; + uint8_t data[PM3_CMD_DATA_SIZE]; + bool custom_IDm = false; + strip_cmds(Cmd); + uint16_t datalen = 17; // Length (1), Command ID (1), IDm (8), Number of Service (1), Service Code List(2), Number of Block(1), Block List(3) + uint8_t paramCount = 0; + uint8_t flags = 0; + int i = 0; + while (Cmd[i] != '\0') { + if (Cmd[i] == '-') { + switch (Cmd[i + 1]) { + case 'H': + case 'h': + return usage_hf_felica_request_response(); + case 'i': + paramCount++; + custom_IDm = true; + if (param_getlength(Cmd, paramCount) == 16) { + param_gethex(Cmd, paramCount++, data + 2, 16); + } else { + PrintAndLogEx(ERR, "Incorrect IDm length! IDm must be 8-Byte."); + return PM3_EINVARG; + } + break; + } + } + i++; + } + + + return PM3_SUCCESS; +} + /** * Command parser for rqresponse * @param Cmd input data of the user. @@ -897,8 +947,8 @@ static command_t CommandTable[] = { //{"dump", CmdHFFelicaDump, IfPm3Felica, "Wait for and try dumping FeliCa"}, {"rqservice", CmdHFFelicaRequestService, IfPm3Felica, "verify the existence of Area and Service, and to acquire Key Version."}, {"rqresponse", CmdHFFelicaRequestResponse, IfPm3Felica, "verify the existence of a card and its Mode."}, - {"rdNoEncryption", CmdHFFelicaNotImplementedYet, IfPm3Felica, "read Block Data from authentication-not-required Service."}, - //{"wrNoEncryption", CmdHFFelicaNotImplementedYet, IfPm3Felica, "write Block Data to an authentication-required Service."}, + {"rdNoEncryption", CmdHFFelicaReadWithoutEncryption, IfPm3Felica, "read Block Data from authentication-not-required Service."}, + {"wrNoEncryption", CmdHFFelicaNotImplementedYet, IfPm3Felica, "write Block Data to an authentication-required Service."}, //{"searchSvCode", CmdHFFelicaNotImplementedYet, IfPm3Felica, "acquire Area Code and Service Code."}, //{"rqSysCode", CmdHFFelicaNotImplementedYet, IfPm3Felica, "acquire System Code registered to the card."}, //{"auth1", CmdHFFelicaNotImplementedYet, IfPm3Felica, "authenticate a card."}, diff --git a/include/mifare.h b/include/mifare.h index 754a0c82f..e472d5c59 100644 --- a/include/mifare.h +++ b/include/mifare.h @@ -186,6 +186,17 @@ typedef struct { uint8_t mode[1]; } PACKED felica_request_request_response_t; +typedef struct { + uint8_t sync[2]; + uint8_t length[1]; + uint8_t cmd_code[1]; + uint8_t IDm[8]; + uint8_t status_flag1[1]; + uint8_t status_flag2[1]; + uint8_t number_of_block[1]; + uint8_t block_data[16]; +} PACKED felica_read_without_encryption_response_t; + typedef enum FELICA_COMMAND { FELICA_CONNECT = (1 << 0), FELICA_NO_DISCONNECT = (1 << 1), From fc800d97b52fa356eb84b904d4b6431981736f5f Mon Sep 17 00:00:00 2001 From: mwalker33 Date: Thu, 24 Oct 2019 19:06:59 +1100 Subject: [PATCH 1054/1854] Update appmain.c --- armsrc/appmain.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 84589ff00..dcb7d63a0 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1589,9 +1589,14 @@ static void PacketReceived(PacketCommandNG *packet) { BigBuf_free(); } uint16_t offset = MIN(BIGBUF_SIZE - PM3_CMD_DATA_SIZE - 3, payload->offset); + + // need to copy len bytes of data, not PM3_CMD_DATA_SIZE - 3 - offset + // ensure len bytes copied wont go past end of bigbuf + uint16_t len = MIN(BIGBUF_SIZE - offset,PM3_CMD_DATA_SIZE - 3); uint8_t *mem = BigBuf_get_addr(); - memcpy(mem + offset, &payload->data, PM3_CMD_DATA_SIZE - 3 - offset); + memcpy(mem + offset, &payload->data, len); + // memcpy(mem + offset, &payload->data, PM3_CMD_DATA_SIZE - 3 - offset); reply_ng(CMD_LF_UPLOAD_SIM_SAMPLES, PM3_SUCCESS, NULL, 0); break; } From 003aada18f7727cef11ec082c86843d93d6a3711 Mon Sep 17 00:00:00 2001 From: Thomas Sutter Date: Thu, 24 Oct 2019 11:30:52 +0200 Subject: [PATCH 1055/1854] Add basic read_without_encryption command. --- client/cmdhffelica.c | 113 +++++++++++++++++++++++++++++++++---------- 1 file changed, 88 insertions(+), 25 deletions(-) diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index f0c699b9b..ea52e5112 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -112,17 +112,19 @@ static int usage_hf_felica_request_response(void) { PrintAndLogEx(NORMAL, "\nUsage: hf felica rqresponse [-h]"); PrintAndLogEx(NORMAL, " -h this help"); PrintAndLogEx(NORMAL, " -i <0A0B0C ... hex> set custom IDm to use"); - return PM3_SUCCESS; } static int usage_hf_felica_read_without_encryption(void) { PrintAndLogEx(NORMAL, "\nInfo: Use this command to read Block Data from authentication-not-required Service."); PrintAndLogEx(NORMAL, " - Mode shall be Mode0."); - PrintAndLogEx(NORMAL, "\nUsage: hf felica rdNoEncryption [-h]"); + + PrintAndLogEx(NORMAL, "\nUsage: hf felica rdunencrypted [-h] <01 Number of Service hex> <0A0B Service Code List hex> <01 Number of Block hex> <0A0B or 0A0B0C Block List Element hex>"); PrintAndLogEx(NORMAL, " -h this help"); PrintAndLogEx(NORMAL, " -i <0A0B0C ... hex> set custom IDm to use"); - + PrintAndLogEx(NORMAL, "\nExamples: "); + PrintAndLogEx(NORMAL, " hf felica rdunencrypted 01 8B00 01 8000"); + PrintAndLogEx(NORMAL, " hf felica rdunencrypted -i 01100910c11bc407 01 8B00 01 8000\n\n"); return PM3_SUCCESS; } @@ -211,7 +213,35 @@ static void clear_and_send_command(uint8_t flags, uint16_t datalen, uint8_t *dat } /** - * Sends a request service frame to the pm3. + * Prints the given block data. + */ +static void print_block_data(uint8_t *number_of_block, uint8_t *block_data, size_t block_size){ + PrintAndLogEx(NORMAL, "Block Nr.: %i", *number_of_block); + PrintAndLogEx(NORMAL, "Data: %s", sprint_hex(block_data, block_size)); +}; + + +/** + * Adds a parameter to the frame and checks if the parameter has the specific length. + * @param Cmd User input with the parameter. + * @param paramCount number of the parameter within the user input. + * @param data frame in which the data is stored. + * @param dataPosition position within frame where the data will be stored. + * @param length which the parameter should have and will be tested against. + * @return + */ +static bool add_param(const char *Cmd, uint8_t paramCount, uint8_t *data, uint8_t dataPosition, uint8_t length){ + if (param_getlength(Cmd, paramCount) == length) { + param_gethex(Cmd, paramCount, data + dataPosition, length); + return true; + } else { + PrintAndLogEx(ERR, "Incorrect Parameter length! Param %i", paramCount); + return false; + } +} + +/** + * Sends a request service frame to the pm3 and prints response. */ void send_request_service(uint8_t flags, uint16_t datalen, uint8_t *data) { clear_and_send_command(flags, datalen, data); @@ -234,17 +264,17 @@ void send_request_service(uint8_t flags, uint16_t datalen, uint8_t *data) { } /** - * Command parser for rdNoEncryption. + * Command parser for rdunencrypted. * @param Cmd input data of the user. * @return client result code. */ static int CmdHFFelicaReadWithoutEncryption(const char *Cmd) { if (strlen(Cmd) < 4) - return usage_hf_felica_read_without_encryption; + return usage_hf_felica_read_without_encryption(); uint8_t data[PM3_CMD_DATA_SIZE]; bool custom_IDm = false; strip_cmds(Cmd); - uint16_t datalen = 17; // Length (1), Command ID (1), IDm (8), Number of Service (1), Service Code List(2), Number of Block(1), Block List(3) + uint16_t datalen = 16; // Length (1), Command ID (1), IDm (8), Number of Service (1), Service Code List(2), Number of Block(1), Block List(3) uint8_t paramCount = 0; uint8_t flags = 0; int i = 0; @@ -257,10 +287,7 @@ static int CmdHFFelicaReadWithoutEncryption(const char *Cmd) { case 'i': paramCount++; custom_IDm = true; - if (param_getlength(Cmd, paramCount) == 16) { - param_gethex(Cmd, paramCount++, data + 2, 16); - } else { - PrintAndLogEx(ERR, "Incorrect IDm length! IDm must be 8-Byte."); + if(!add_param(Cmd, paramCount, data, 3, 8)){ return PM3_EINVARG; } break; @@ -268,8 +295,44 @@ static int CmdHFFelicaReadWithoutEncryption(const char *Cmd) { } i++; } + data[0] = 0x10; // Static length + data[1] = 0x06; // Command ID + if (!custom_IDm) { + if (!add_last_IDm(2, data)) { + PrintAndLogEx(ERR, "No last known card! Use reader first or set a custom IDm!"); + return PM3_EINVARG; + } else { + PrintAndLogEx(INFO, "Used last known IDm.", sprint_hex(data, datalen)); + } + } + // Number of Service 2, Service Code List 4, Number of Block 2, Block List Element 4 + uint8_t lengths[] = {2, 4, 2, 4}; + uint8_t dataPositions[] = {10, 11, 13, 14}; + for(int i=0; i < 4; i++){ + if(add_param(Cmd, paramCount, data, dataPositions[i], lengths[i])){ + paramCount++; + }else{ + return PM3_EINVARG; + } + } + AddCrc(data, datalen); + datalen += 2; + flags |= FELICA_APPEND_CRC; + flags |= FELICA_RAW; + clear_and_send_command(flags, datalen, data); + PacketResponseNG resp; + if (!waitCmdFelica(0, &resp)) { + PrintAndLogEx(ERR, "\nGot no Response from card"); + return PM3_ERFTRANS; + } else { + PrintAndLogEx(SUCCESS, "\nGot Response from card"); + felica_read_without_encryption_response_t rd_noCry_resp; + memcpy(&rd_noCry_resp, (felica_read_without_encryption_response_t *)resp.data.asBytes, sizeof(felica_read_without_encryption_response_t)); - + if (rd_noCry_resp.IDm[0] != 0) { + print_block_data(rd_noCry_resp.number_of_block, rd_noCry_resp.block_data, sizeof(rd_noCry_resp.block_data)); + } + } return PM3_SUCCESS; } @@ -947,23 +1010,23 @@ static command_t CommandTable[] = { //{"dump", CmdHFFelicaDump, IfPm3Felica, "Wait for and try dumping FeliCa"}, {"rqservice", CmdHFFelicaRequestService, IfPm3Felica, "verify the existence of Area and Service, and to acquire Key Version."}, {"rqresponse", CmdHFFelicaRequestResponse, IfPm3Felica, "verify the existence of a card and its Mode."}, - {"rdNoEncryption", CmdHFFelicaReadWithoutEncryption, IfPm3Felica, "read Block Data from authentication-not-required Service."}, - {"wrNoEncryption", CmdHFFelicaNotImplementedYet, IfPm3Felica, "write Block Data to an authentication-required Service."}, - //{"searchSvCode", CmdHFFelicaNotImplementedYet, IfPm3Felica, "acquire Area Code and Service Code."}, - //{"rqSysCode", CmdHFFelicaNotImplementedYet, IfPm3Felica, "acquire System Code registered to the card."}, + {"rdunencrypted", CmdHFFelicaReadWithoutEncryption, IfPm3Felica, "read Block Data from authentication-not-required Service."}, + {"wrunencrypted", CmdHFFelicaNotImplementedYet, IfPm3Felica, "write Block Data to an authentication-not-required Service."}, + //{"scsvcode", CmdHFFelicaNotImplementedYet, IfPm3Felica, "acquire Area Code and Service Code."}, + //{"rqsyscode", CmdHFFelicaNotImplementedYet, IfPm3Felica, "acquire System Code registered to the card."}, //{"auth1", CmdHFFelicaNotImplementedYet, IfPm3Felica, "authenticate a card."}, //{"auth2", CmdHFFelicaNotImplementedYet, IfPm3Felica, "allow a card to authenticate a Reader/Writer."}, //{"read", CmdHFFelicaNotImplementedYet, IfPm3Felica, "read Block Data from authentication-required Service."}, //{"write", CmdHFFelicaNotImplementedYet, IfPm3Felica, "write Block Data to an authentication-required Service."}, - //{"searchSvCodeV2", CmdHFFelicaNotImplementedYet, IfPm3Felica, "verify the existence of Area or Service, and to acquire Key Version."}, - //{"getSysStatus", CmdHFFelicaNotImplementedYet, IfPm3Felica, "acquire the setup information in System."}, - //{"rqSpecVer", CmdHFFelicaNotImplementedYet, IfPm3Felica, "acquire the version of card OS."}, - //{"resetMode", CmdHFFelicaNotImplementedYet, IfPm3Felica, "reset Mode to Mode 0."}, - //{"auth1V2", CmdHFFelicaNotImplementedYet, IfPm3Felica, "authenticate a card."}, - //{"auth2V2", CmdHFFelicaNotImplementedYet, IfPm3Felica, "allow a card to authenticate a Reader/Writer."}, - //{"readV2", CmdHFFelicaNotImplementedYet, IfPm3Felica, "read Block Data from authentication-required Service."}, - //{"writeV2", CmdHFFelicaNotImplementedYet, IfPm3Felica, "write Block Data to authentication-required Service."}, - //{"upRandomID", CmdHFFelicaNotImplementedYet, IfPm3Felica, "update Random ID (IDr)."}, + //{"scsvcodev2", CmdHFFelicaNotImplementedYet, IfPm3Felica, "verify the existence of Area or Service, and to acquire Key Version."}, + //{"getsysstatus", CmdHFFelicaNotImplementedYet, IfPm3Felica, "acquire the setup information in System."}, + //{"rqspecver", CmdHFFelicaNotImplementedYet, IfPm3Felica, "acquire the version of card OS."}, + //{"resetmode", CmdHFFelicaNotImplementedYet, IfPm3Felica, "reset Mode to Mode 0."}, + //{"auth1v2", CmdHFFelicaNotImplementedYet, IfPm3Felica, "authenticate a card."}, + //{"auth2v2", CmdHFFelicaNotImplementedYet, IfPm3Felica, "allow a card to authenticate a Reader/Writer."}, + //{"readv2", CmdHFFelicaNotImplementedYet, IfPm3Felica, "read Block Data from authentication-required Service."}, + //{"writev2", CmdHFFelicaNotImplementedYet, IfPm3Felica, "write Block Data to authentication-required Service."}, + //{"uprandomid", CmdHFFelicaNotImplementedYet, IfPm3Felica, "update Random ID (IDr)."}, {"----------- FeliCa Light -----------", CmdHelp, IfPm3Iso14443a, ""}, {"litesim", CmdHFFelicaSimLite, IfPm3Felica, " - only reply to poll request"}, {"litedump", CmdHFFelicaDumpLite, IfPm3Felica, "Wait for and try dumping FelicaLite"}, From 94ec36de2007bf277f9fff0925c26be03db9094e Mon Sep 17 00:00:00 2001 From: Thomas Sutter Date: Thu, 24 Oct 2019 11:59:58 +0200 Subject: [PATCH 1056/1854] Add status flag interpretation. --- client/cmdhffelica.c | 60 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 3 deletions(-) diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index ea52e5112..176031d3f 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -115,11 +115,58 @@ static int usage_hf_felica_request_response(void) { return PM3_SUCCESS; } +static void print_status_flag1_interpretation(){ + PrintAndLogEx(NORMAL, "Status Flag1:"); + PrintAndLogEx(NORMAL, " - 00h : Indicates the successful completion of a command."); + PrintAndLogEx(NORMAL, " - FFh : If an error occurs during the processing of a command that includes no list in the command packet, or if " + "an error occurs independently of any list, the card returns a response by setting FFh to Status Flag1."); + PrintAndLogEx(NORMAL, " - XXh : If an error occurs while processing a command that includes Service Code List or Block List " + "in the command packet, the card returns a response by setting a number in the list to Status Flag1, " + "indicating the location of the error. Have a look at the FeliCa User Manual for more information."); +} + +static void print_status_flag2_interpration(){ + PrintAndLogEx(NORMAL, "Status Flag2:"); + PrintAndLogEx(NORMAL, " - 00h : Indicates the successful completion of a command."); + PrintAndLogEx(NORMAL, " - 01h : The calculated result is either less than zero when the purse data is decremented, or exceeds 4" + "Bytes when the purse data is incremented."); + PrintAndLogEx(NORMAL, " - 02h : The specified data exceeds the value of cashback data at cashback of purse."); + PrintAndLogEx(NORMAL, " - 70h : Memory error (fatal error)."); + PrintAndLogEx(NORMAL, " - 71h : The number of memory rewrites exceeds the upper limit (this is only a warning; data writing is " + "performed as normal). The maximum number of rewrites can differ, depending on the product being used." + " In addition, Status Flag1 is either 00h or FFh depending on the product being used."); + PrintAndLogEx(NORMAL, " - A1h : Illegal Number of Service: Number of Service or Number of Node specified by the command falls outside the range of the prescribed value."); + PrintAndLogEx(NORMAL, " - A2h : Illegal command packet (specified Number of Block): Number of Block specified by the command falls outside the range of the prescribed values for the product."); + PrintAndLogEx(NORMAL, " - A3h : Illegal Block List (specified order of Service): Service Code List Order specified by Block List Element falls outside the Number of Service specified by the " + "command (or the Number of Service specified at the times of mutual authentication)."); + PrintAndLogEx(NORMAL, " - A4h : Illegal Service type: Area Attribute specified by the command or Service Attribute of Service Code is incorrect."); + PrintAndLogEx(NORMAL, " - A5h : Access is not allowed: Area or Service specified by the command cannot be accessed. " + "The parameter specified by the command does not satisfy the conditions for success."); + PrintAndLogEx(NORMAL, " - A6h : Illegal Service Code List: Target to be accessed, identified by Service Code List Order, specified by Block " + "List Element does not exist. Or, Node specified by Node Code List does not exist."); + PrintAndLogEx(NORMAL, " - A7h : Illegal Block List (Access Mode): Access Mode specified by Block List Element is incorrect."); + PrintAndLogEx(NORMAL, " - A8h : Illegal Block Number Block Number (access to the specified data is inhibited): specified by Block List Element exceeds the number of Blocks assigned to Service."); + PrintAndLogEx(NORMAL, " - A9h : Data write failure: This is the error that occurs in issuance commands."); + PrintAndLogEx(NORMAL, " - AAh : Key-change failure: Key change failed."); + PrintAndLogEx(NORMAL, " - ABh : Illegal Package Parity or illegal Package MAC: This is the error that occurs in issuance commands."); + PrintAndLogEx(NORMAL, " - ACh : Illegal parameter: This is the error that occurs in issuance commands."); + PrintAndLogEx(NORMAL, " - ADh : Service exists already: This is the error that occurs in issuance commands."); + PrintAndLogEx(NORMAL, " - AEh : Illegal System Code: This is the error that occurs in issuance commands."); + PrintAndLogEx(NORMAL, " - AFh : Too many simultaneous cyclic write operations: Number of simultaneous write Blocks specified by the command to Cyclic Service " + "exceeds the number of Blocks assigned to Service."); + PrintAndLogEx(NORMAL, " - C0h : Illegal Package Identifier: This is the error that occurs in issuance commands."); + PrintAndLogEx(NORMAL, " - C1h : Discrepancy of parameters inside and outside Package: This is the error that occurs in issuance commands."); + PrintAndLogEx(NORMAL, " - C2h : Command is disabled already: This is the error that occurs in issuance commands."); +} + static int usage_hf_felica_read_without_encryption(void) { PrintAndLogEx(NORMAL, "\nInfo: Use this command to read Block Data from authentication-not-required Service."); PrintAndLogEx(NORMAL, " - Mode shall be Mode0."); - - PrintAndLogEx(NORMAL, "\nUsage: hf felica rdunencrypted [-h] <01 Number of Service hex> <0A0B Service Code List hex> <01 Number of Block hex> <0A0B or 0A0B0C Block List Element hex>"); + PrintAndLogEx(NORMAL, " - Successful read: Card responses the block data"); + PrintAndLogEx(NORMAL, " - Unsuccessful read: Card responses with Status Flag1 and Flag2"); + print_status_flag1_interpretation(); + print_status_flag2_interpration(); + PrintAndLogEx(NORMAL, "\nUsage: hf felica rdunencrypted [-h] <01 Number of Service hex> <0A0B Service Code List (Little Endian) hex> <01 Number of Block hex> <0A0B Block List Element hex>"); PrintAndLogEx(NORMAL, " -h this help"); PrintAndLogEx(NORMAL, " -i <0A0B0C ... hex> set custom IDm to use"); PrintAndLogEx(NORMAL, "\nExamples: "); @@ -330,7 +377,14 @@ static int CmdHFFelicaReadWithoutEncryption(const char *Cmd) { memcpy(&rd_noCry_resp, (felica_read_without_encryption_response_t *)resp.data.asBytes, sizeof(felica_read_without_encryption_response_t)); if (rd_noCry_resp.IDm[0] != 0) { - print_block_data(rd_noCry_resp.number_of_block, rd_noCry_resp.block_data, sizeof(rd_noCry_resp.block_data)); + PrintAndLogEx(NORMAL, "IDm: %s", sprint_hex(rd_noCry_resp.IDm, sizeof(rd_noCry_resp.IDm))); + PrintAndLogEx(NORMAL, " -Status Flag1: %s", sprint_hex(rd_noCry_resp.status_flag1, sizeof(rd_noCry_resp.status_flag1))); + PrintAndLogEx(NORMAL, " -Status Flag2: %s", sprint_hex(rd_noCry_resp.status_flag2, sizeof(rd_noCry_resp.status_flag2))); + if(rd_noCry_resp.status_flag1[0] == 00 && rd_noCry_resp.status_flag2[0] == 00){ + print_block_data(rd_noCry_resp.number_of_block, rd_noCry_resp.block_data, sizeof(rd_noCry_resp.block_data)); + }else{ + PrintAndLogEx(ERR, "Could not read data! See -h for more information about the status flags."); + } } } return PM3_SUCCESS; From bfd5214cd5ab5ddfae2e2293b059f9216d6c1700 Mon Sep 17 00:00:00 2001 From: Thomas Sutter Date: Thu, 24 Oct 2019 16:08:44 +0200 Subject: [PATCH 1057/1854] Add read_without_encryption command. --- armsrc/felica.c | 20 ----- armsrc/felica.h | 5 -- client/cmdhffelica.c | 181 ++++++++++++++++++++++++++++++------------- client/cmdhffelica.h | 4 +- include/mifare.h | 1 + 5 files changed, 133 insertions(+), 78 deletions(-) diff --git a/armsrc/felica.c b/armsrc/felica.c index 09e2b582f..7ec40efcf 100644 --- a/armsrc/felica.c +++ b/armsrc/felica.c @@ -751,26 +751,6 @@ void felica_sim_lite(uint64_t uid) { #define RES_SVC_LEN 11 + 3 -void felica_dump() { - uint8_t ndef[8]; - uint8_t poll[10] = { 0xb2, 0x4d, 0x06, FELICA_POLL_REQ, 0xff, 0xff, 0x00, 0x00, 0x09, 0x21}; // B24D0600FFFF00000921 - iso18092_setup(FPGA_HF_ISO18092_FLAG_READER | FPGA_HF_ISO18092_FLAG_NOMOD); - - TransmitFor18092_AsReader(poll, 10, NULL, 1, 0); - - // iceman, no exit path in this loop - while (!BUTTON_PRESS() && !data_available()) { - WDT_HIT(); - TransmitFor18092_AsReader(poll, 10, NULL, 1, 0); - if (WaitForFelicaReply(512) && FelicaFrame.framebytes[3] == FELICA_POLL_ACK) { - memcpy(ndef, FelicaFrame.framebytes + 4, 8); - uint8_t *request_service = felica_create_request_service_frame(0x01, ndef); - felica_send_request_service(request_service); - } - } - -} - void felica_dump_lite_s() { uint8_t ndef[8]; uint8_t poll[10] = { 0xb2, 0x4d, 0x06, FELICA_POLL_REQ, 0xff, 0xff, 0x00, 0x00, 0x09, 0x21}; diff --git a/armsrc/felica.h b/armsrc/felica.h index 7bbc48614..95e13a588 100644 --- a/armsrc/felica.h +++ b/armsrc/felica.h @@ -18,12 +18,7 @@ void felica_sendraw(PacketCommandNG *c); void felica_sniff(uint32_t samplesToSkip, uint32_t triggersToSkip); void felica_sim_lite(uint64_t uid); void felica_dump_lite_s(); -void felica_dump(); void felica_create_read_block_frame(uint16_t blockNr); -void felica_create_authentication1_frame(); -void felica_create_authentication2_frame(); void felica_send_request_service(uint8_t *request_service); -void felica_reset_frame_mode(); -uint8_t *felica_create_request_service_frame(uint8_t nodeNumber, uint8_t *idm); #endif diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index 176031d3f..8a1926276 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -159,9 +159,19 @@ static void print_status_flag2_interpration(){ PrintAndLogEx(NORMAL, " - C2h : Command is disabled already: This is the error that occurs in issuance commands."); } -static int usage_hf_felica_read_without_encryption(void) { +static int usage_hf_felica_read_without_encryption() { PrintAndLogEx(NORMAL, "\nInfo: Use this command to read Block Data from authentication-not-required Service."); PrintAndLogEx(NORMAL, " - Mode shall be Mode0."); + PrintAndLogEx(NORMAL, " - Number of Service shall be a positive integer in the range of 1 to 16, inclusive."); + PrintAndLogEx(NORMAL, " - Number of Block shall be less than or equal to the maximum number of Blocks that can be read simultaneously. " + "The maximum number of Blocks that can be read simultaneously can differ, depending on the product being used."); + PrintAndLogEx(NORMAL, " - Each Block List Element shall satisfy the following conditions:"); + PrintAndLogEx(NORMAL, " - The value of Service Code List Order shall not exceed Number of Service."); + PrintAndLogEx(NORMAL, " - Access Mode shall be 000b."); + PrintAndLogEx(NORMAL, " - The target specified by Service Code shall not be Area or System."); + PrintAndLogEx(NORMAL, " - Service specified in Service Code List shall exist in System."); + PrintAndLogEx(NORMAL, " - Service Attribute of Service specified in Service Code List shall be authentication-not-required Service."); + PrintAndLogEx(NORMAL, " - Block Number shall be in the range of the number of Blocks assigned to the specified Service."); PrintAndLogEx(NORMAL, " - Successful read: Card responses the block data"); PrintAndLogEx(NORMAL, " - Unsuccessful read: Card responses with Status Flag1 and Flag2"); print_status_flag1_interpretation(); @@ -169,6 +179,7 @@ static int usage_hf_felica_read_without_encryption(void) { PrintAndLogEx(NORMAL, "\nUsage: hf felica rdunencrypted [-h] <01 Number of Service hex> <0A0B Service Code List (Little Endian) hex> <01 Number of Block hex> <0A0B Block List Element hex>"); PrintAndLogEx(NORMAL, " -h this help"); PrintAndLogEx(NORMAL, " -i <0A0B0C ... hex> set custom IDm to use"); + PrintAndLogEx(NORMAL, " -b get all Block List Elements of service"); PrintAndLogEx(NORMAL, "\nExamples: "); PrintAndLogEx(NORMAL, " hf felica rdunencrypted 01 8B00 01 8000"); PrintAndLogEx(NORMAL, " hf felica rdunencrypted -i 01100910c11bc407 01 8B00 01 8000\n\n"); @@ -178,17 +189,20 @@ static int usage_hf_felica_read_without_encryption(void) { /** * Wait for response from pm3 or timeout. * Checks if receveid bytes have a valid CRC. + * @param verbose prints out the response received. */ -static bool waitCmdFelica(uint8_t iSelect, PacketResponseNG *resp) { +static bool waitCmdFelica(uint8_t iSelect, PacketResponseNG *resp, bool verbose) { if (WaitForResponseTimeout(CMD_ACK, resp, 2000)) { uint16_t len = iSelect ? (resp->oldarg[1] & 0xffff) : (resp->oldarg[0] & 0xffff); - PrintAndLogEx(NORMAL, "Client Received %i octets", len); - if (!len || len < 2) { - PrintAndLogEx(ERR, "Could not receive data correctly!"); - } - PrintAndLogEx(NORMAL, "%s", sprint_hex(resp->data.asBytes, len)); - if (!check_crc(CRC_FELICA, resp->data.asBytes + 2, len - 2)) { - PrintAndLogEx(WARNING, "Wrong or no CRC bytes"); + if(verbose){ + PrintAndLogEx(NORMAL, "Client Received %i octets", len); + if (!len || len < 2) { + PrintAndLogEx(ERR, "Could not receive data correctly!"); + } + PrintAndLogEx(NORMAL, "%s", sprint_hex(resp->data.asBytes, len)); + if (!check_crc(CRC_FELICA, resp->data.asBytes + 2, len - 2)) { + PrintAndLogEx(WARNING, "Wrong or no CRC bytes"); + } } return true; } else { @@ -252,22 +266,15 @@ static int CmdHFFelicaReader(const char *Cmd) { /** * Clears command buffer and sends the given data to pm3 with mix mode. */ -static void clear_and_send_command(uint8_t flags, uint16_t datalen, uint8_t *data) { +static void clear_and_send_command(uint8_t flags, uint16_t datalen, uint8_t *data, bool verbose) { uint16_t numbits = 0; clearCommandBuffer(); - PrintAndLogEx(NORMAL, "Send Service Request Frame: %s", sprint_hex(data, datalen)); + if(verbose){ + PrintAndLogEx(NORMAL, "Send Service Request Frame: %s", sprint_hex(data, datalen)); + } SendCommandMIX(CMD_HF_FELICA_COMMAND, flags, (datalen & 0xFFFF) | (uint32_t)(numbits << 16), 0, data, datalen); } -/** - * Prints the given block data. - */ -static void print_block_data(uint8_t *number_of_block, uint8_t *block_data, size_t block_size){ - PrintAndLogEx(NORMAL, "Block Nr.: %i", *number_of_block); - PrintAndLogEx(NORMAL, "Data: %s", sprint_hex(block_data, block_size)); -}; - - /** * Adds a parameter to the frame and checks if the parameter has the specific length. * @param Cmd User input with the parameter. @@ -275,7 +282,7 @@ static void print_block_data(uint8_t *number_of_block, uint8_t *block_data, size * @param data frame in which the data is stored. * @param dataPosition position within frame where the data will be stored. * @param length which the parameter should have and will be tested against. - * @return + * @return true if parameters was added. */ static bool add_param(const char *Cmd, uint8_t paramCount, uint8_t *data, uint8_t dataPosition, uint8_t length){ if (param_getlength(Cmd, paramCount) == length) { @@ -287,16 +294,42 @@ static bool add_param(const char *Cmd, uint8_t paramCount, uint8_t *data, uint8_ } } +/** + * Prints read-without-encryption response. + * @param rd_noCry_resp Response frame. + */ +static void print_rd_noEncrpytion_response(felica_read_without_encryption_response_t *rd_noCry_resp){ + if(rd_noCry_resp->status_flag1[0] == 00 && rd_noCry_resp->status_flag2[0] == 00){ + char bl_number[4]; + char *temp = sprint_hex(rd_noCry_resp->number_of_block, sizeof(rd_noCry_resp->number_of_block)); + strcpy(bl_number, temp); + + temp = sprint_hex(rd_noCry_resp->block_data, sizeof(rd_noCry_resp->block_data)); + char bl_data[256]; + strcpy(bl_data, temp); + + char bl_element_number[4]; + temp = sprint_hex(rd_noCry_resp->block_element_number, sizeof(rd_noCry_resp->block_element_number)); + strcpy(bl_element_number, temp); + + PrintAndLogEx(NORMAL, "%s: %s: %s", bl_number, bl_element_number, bl_data); + }else{ + PrintAndLogEx(NORMAL, "IDm: %s", sprint_hex(rd_noCry_resp->IDm, sizeof(rd_noCry_resp->IDm))); + PrintAndLogEx(NORMAL, "Status Flag1: %s", sprint_hex(rd_noCry_resp->status_flag1, sizeof(rd_noCry_resp->status_flag1))); + PrintAndLogEx(NORMAL, "Status Flag2: %s", sprint_hex(rd_noCry_resp->status_flag1, sizeof(rd_noCry_resp->status_flag1))); + } +} + /** * Sends a request service frame to the pm3 and prints response. */ -void send_request_service(uint8_t flags, uint16_t datalen, uint8_t *data) { - clear_and_send_command(flags, datalen, data); +int send_request_service(uint8_t flags, uint16_t datalen, uint8_t *data, bool verbose) { + clear_and_send_command(flags, datalen, data, verbose); PacketResponseNG resp; if (datalen > 0) { - if (!waitCmdFelica(0, &resp)) { + if (!waitCmdFelica(0, &resp, 1)) { PrintAndLogEx(ERR, "\nGot no Response from card"); - return; + return PM3_ERFTRANS; } felica_request_service_response_t rqs_response; memcpy(&rqs_response, (felica_request_service_response_t *)resp.data.asBytes, sizeof(felica_request_service_response_t)); @@ -307,6 +340,30 @@ void send_request_service(uint8_t flags, uint16_t datalen, uint8_t *data) { PrintAndLogEx(NORMAL, " -Node Number: %s", sprint_hex(rqs_response.node_number, sizeof(rqs_response.node_number))); PrintAndLogEx(NORMAL, " -Node Key Version List: %s\n", sprint_hex(rqs_response.node_key_versions, sizeof(rqs_response.node_key_versions))); } + return PM3_SUCCESS; + } + return PM3_ERFTRANS; +} + +/** + * Sends a read_without_encryption frame to the pm3 and prints response. + * @param flags to use for pm3 communication. + * @param datalen frame length. + * @param data frame to be send. + * @param verbose display additional output. + * @param rd_noCry_resp frame in which the response will be saved + * @return success if response was received. + */ +int send_rd_unencrypted(uint8_t flags, uint16_t datalen, uint8_t *data, bool verbose, felica_read_without_encryption_response_t *rd_noCry_resp){ + clear_and_send_command(flags, datalen, data, verbose); + PacketResponseNG resp; + if (!waitCmdFelica(0, &resp, verbose)) { + PrintAndLogEx(ERR, "\nGot no Response from card"); + return PM3_ERFTRANS; + } else { + memcpy(rd_noCry_resp, (felica_read_without_encryption_response_t *)resp.data.asBytes, sizeof(felica_read_without_encryption_response_t)); + rd_noCry_resp->block_element_number[0] = data[15]; + return PM3_SUCCESS; } } @@ -324,6 +381,8 @@ static int CmdHFFelicaReadWithoutEncryption(const char *Cmd) { uint16_t datalen = 16; // Length (1), Command ID (1), IDm (8), Number of Service (1), Service Code List(2), Number of Block(1), Block List(3) uint8_t paramCount = 0; uint8_t flags = 0; + uint8_t all_block_list_elements = false; + uint8_t long_block_numbers = false; int i = 0; while (Cmd[i] != '\0') { if (Cmd[i] == '-') { @@ -338,6 +397,14 @@ static int CmdHFFelicaReadWithoutEncryption(const char *Cmd) { return PM3_EINVARG; } break; + case 'b': + paramCount++; + all_block_list_elements = true; + break; + case 'l': + paramCount++; + long_block_numbers = true; + break; } } i++; @@ -355,6 +422,10 @@ static int CmdHFFelicaReadWithoutEncryption(const char *Cmd) { // Number of Service 2, Service Code List 4, Number of Block 2, Block List Element 4 uint8_t lengths[] = {2, 4, 2, 4}; uint8_t dataPositions[] = {10, 11, 13, 14}; + if(long_block_numbers){ + datalen += 1; + lengths[3] = 6; + } for(int i=0; i < 4; i++){ if(add_param(Cmd, paramCount, data, dataPositions[i], lengths[i])){ paramCount++; @@ -362,30 +433,36 @@ static int CmdHFFelicaReadWithoutEncryption(const char *Cmd) { return PM3_EINVARG; } } - AddCrc(data, datalen); - datalen += 2; + flags |= FELICA_APPEND_CRC; flags |= FELICA_RAW; - clear_and_send_command(flags, datalen, data); - PacketResponseNG resp; - if (!waitCmdFelica(0, &resp)) { - PrintAndLogEx(ERR, "\nGot no Response from card"); - return PM3_ERFTRANS; - } else { - PrintAndLogEx(SUCCESS, "\nGot Response from card"); - felica_read_without_encryption_response_t rd_noCry_resp; - memcpy(&rd_noCry_resp, (felica_read_without_encryption_response_t *)resp.data.asBytes, sizeof(felica_read_without_encryption_response_t)); - - if (rd_noCry_resp.IDm[0] != 0) { - PrintAndLogEx(NORMAL, "IDm: %s", sprint_hex(rd_noCry_resp.IDm, sizeof(rd_noCry_resp.IDm))); - PrintAndLogEx(NORMAL, " -Status Flag1: %s", sprint_hex(rd_noCry_resp.status_flag1, sizeof(rd_noCry_resp.status_flag1))); - PrintAndLogEx(NORMAL, " -Status Flag2: %s", sprint_hex(rd_noCry_resp.status_flag2, sizeof(rd_noCry_resp.status_flag2))); - if(rd_noCry_resp.status_flag1[0] == 00 && rd_noCry_resp.status_flag2[0] == 00){ - print_block_data(rd_noCry_resp.number_of_block, rd_noCry_resp.block_data, sizeof(rd_noCry_resp.block_data)); - }else{ - PrintAndLogEx(ERR, "Could not read data! See -h for more information about the status flags."); - } + if(all_block_list_elements){ + uint16_t last_block_number = 0xFF; + if(long_block_numbers){ + last_block_number = 0xFFFF; } + for(int i=0x00; i < last_block_number; i++){ + data[15] = i; + AddCrc(data, datalen); + datalen += 2; + felica_read_without_encryption_response_t rd_noCry_resp; + if((send_rd_unencrypted(flags, datalen, data, 0, &rd_noCry_resp) == PM3_SUCCESS)){ + if(rd_noCry_resp.status_flag1[0] == 00 && rd_noCry_resp.status_flag2[0] == 00){ + print_rd_noEncrpytion_response(&rd_noCry_resp); + }else{ + break; + } + }else{ + break; + } + datalen -= 2; + } + }else{ + AddCrc(data, datalen); + datalen += 2; + felica_read_without_encryption_response_t rd_noCry_resp; + send_rd_unencrypted(flags, datalen, data, 1, &rd_noCry_resp); + print_rd_noEncrpytion_response(&rd_noCry_resp); } return PM3_SUCCESS; } @@ -437,9 +514,9 @@ static int CmdHFFelicaRequestResponse(const char *Cmd) { datalen += 2; flags |= FELICA_APPEND_CRC; flags |= FELICA_RAW; - clear_and_send_command(flags, datalen, data); + clear_and_send_command(flags, datalen, data, 0); PacketResponseNG resp; - if (!waitCmdFelica(0, &resp)) { + if (!waitCmdFelica(0, &resp, 1)) { PrintAndLogEx(ERR, "\nGot no Response from card"); return PM3_ERFTRANS; } else { @@ -539,13 +616,13 @@ static int CmdHFFelicaRequestService(const char *Cmd) { data[10] = int_to_hex(&y); AddCrc(data, datalen); datalen += 2; - send_request_service(flags, datalen, data); + send_request_service(flags, datalen, data, 1); datalen -= 2; // Remove CRC bytes before adding new ones } } else { AddCrc(data, datalen); datalen += 2; - send_request_service(flags, datalen, data); + send_request_service(flags, datalen, data, 1); } return PM3_SUCCESS; @@ -993,11 +1070,11 @@ static int CmdHFFelicaCmdRaw(const char *Cmd) { if (active_select) { PrintAndLogEx(NORMAL, "Active select wait for FeliCa."); PacketResponseNG resp_IDm; - waitCmdFelica(1, &resp_IDm); + waitCmdFelica(1, &resp_IDm, 1); } if (datalen > 0) { PacketResponseNG resp_frame; - waitCmdFelica(0, &resp_frame); + waitCmdFelica(0, &resp_frame, 1); } } return PM3_SUCCESS; diff --git a/client/cmdhffelica.h b/client/cmdhffelica.h index dd127cfaf..7626d002b 100644 --- a/client/cmdhffelica.h +++ b/client/cmdhffelica.h @@ -12,8 +12,10 @@ #define CMDHFFELICA_H__ #include "common.h" +#include "mifare.h" int CmdHFFelica(const char *Cmd); int readFelicaUid(bool verbose); -void send_request_service(uint8_t flags, uint16_t datalen, uint8_t *data); +int send_request_service(uint8_t flags, uint16_t datalen, uint8_t *data, bool verbose); +int send_rd_unencrypted(uint8_t flags, uint16_t datalen, uint8_t *data, bool verbose, felica_read_without_encryption_response_t *rd_noCry_resp); #endif diff --git a/include/mifare.h b/include/mifare.h index e472d5c59..7a40a26e4 100644 --- a/include/mifare.h +++ b/include/mifare.h @@ -195,6 +195,7 @@ typedef struct { uint8_t status_flag2[1]; uint8_t number_of_block[1]; uint8_t block_data[16]; + uint8_t block_element_number[1]; } PACKED felica_read_without_encryption_response_t; typedef enum FELICA_COMMAND { From 12cd208253b61bef7fdd4565b8eabfbfd16b696f Mon Sep 17 00:00:00 2001 From: Thomas Sutter Date: Thu, 24 Oct 2019 17:07:27 +0200 Subject: [PATCH 1058/1854] Make style. Format help text. --- client/cmdhffelica.c | 94 ++++++++++++++++++++++---------------------- 1 file changed, 48 insertions(+), 46 deletions(-) diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index 8a1926276..bd0099923 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -115,35 +115,35 @@ static int usage_hf_felica_request_response(void) { return PM3_SUCCESS; } -static void print_status_flag1_interpretation(){ - PrintAndLogEx(NORMAL, "Status Flag1:"); +static void print_status_flag1_interpretation() { + PrintAndLogEx(NORMAL, "\nStatus Flag1:"); PrintAndLogEx(NORMAL, " - 00h : Indicates the successful completion of a command."); PrintAndLogEx(NORMAL, " - FFh : If an error occurs during the processing of a command that includes no list in the command packet, or if " - "an error occurs independently of any list, the card returns a response by setting FFh to Status Flag1."); + "an error occurs independently of any list, the card returns a response by setting FFh to Status Flag1."); PrintAndLogEx(NORMAL, " - XXh : If an error occurs while processing a command that includes Service Code List or Block List " - "in the command packet, the card returns a response by setting a number in the list to Status Flag1, " - "indicating the location of the error. Have a look at the FeliCa User Manual for more information."); + "in the command packet, the card returns a response by setting a number in the list to Status Flag1, " + "indicating the location of the error."); } -static void print_status_flag2_interpration(){ - PrintAndLogEx(NORMAL, "Status Flag2:"); +static void print_status_flag2_interpration() { + PrintAndLogEx(NORMAL, "\nStatus Flag2:"); PrintAndLogEx(NORMAL, " - 00h : Indicates the successful completion of a command."); PrintAndLogEx(NORMAL, " - 01h : The calculated result is either less than zero when the purse data is decremented, or exceeds 4" - "Bytes when the purse data is incremented."); + "Bytes when the purse data is incremented."); PrintAndLogEx(NORMAL, " - 02h : The specified data exceeds the value of cashback data at cashback of purse."); PrintAndLogEx(NORMAL, " - 70h : Memory error (fatal error)."); PrintAndLogEx(NORMAL, " - 71h : The number of memory rewrites exceeds the upper limit (this is only a warning; data writing is " - "performed as normal). The maximum number of rewrites can differ, depending on the product being used." - " In addition, Status Flag1 is either 00h or FFh depending on the product being used."); + "performed as normal). The maximum number of rewrites can differ, depending on the product being used."); + PrintAndLogEx(NORMAL, " In addition, Status Flag1 is either 00h or FFh depending on the product being used."); PrintAndLogEx(NORMAL, " - A1h : Illegal Number of Service: Number of Service or Number of Node specified by the command falls outside the range of the prescribed value."); PrintAndLogEx(NORMAL, " - A2h : Illegal command packet (specified Number of Block): Number of Block specified by the command falls outside the range of the prescribed values for the product."); PrintAndLogEx(NORMAL, " - A3h : Illegal Block List (specified order of Service): Service Code List Order specified by Block List Element falls outside the Number of Service specified by the " - "command (or the Number of Service specified at the times of mutual authentication)."); + "command (or the Number of Service specified at the times of mutual authentication)."); PrintAndLogEx(NORMAL, " - A4h : Illegal Service type: Area Attribute specified by the command or Service Attribute of Service Code is incorrect."); PrintAndLogEx(NORMAL, " - A5h : Access is not allowed: Area or Service specified by the command cannot be accessed. " - "The parameter specified by the command does not satisfy the conditions for success."); + "The parameter specified by the command does not satisfy the conditions for success."); PrintAndLogEx(NORMAL, " - A6h : Illegal Service Code List: Target to be accessed, identified by Service Code List Order, specified by Block " - "List Element does not exist. Or, Node specified by Node Code List does not exist."); + "List Element does not exist. Or, Node specified by Node Code List does not exist."); PrintAndLogEx(NORMAL, " - A7h : Illegal Block List (Access Mode): Access Mode specified by Block List Element is incorrect."); PrintAndLogEx(NORMAL, " - A8h : Illegal Block Number Block Number (access to the specified data is inhibited): specified by Block List Element exceeds the number of Blocks assigned to Service."); PrintAndLogEx(NORMAL, " - A9h : Data write failure: This is the error that occurs in issuance commands."); @@ -153,7 +153,7 @@ static void print_status_flag2_interpration(){ PrintAndLogEx(NORMAL, " - ADh : Service exists already: This is the error that occurs in issuance commands."); PrintAndLogEx(NORMAL, " - AEh : Illegal System Code: This is the error that occurs in issuance commands."); PrintAndLogEx(NORMAL, " - AFh : Too many simultaneous cyclic write operations: Number of simultaneous write Blocks specified by the command to Cyclic Service " - "exceeds the number of Blocks assigned to Service."); + "exceeds the number of Blocks assigned to Service."); PrintAndLogEx(NORMAL, " - C0h : Illegal Package Identifier: This is the error that occurs in issuance commands."); PrintAndLogEx(NORMAL, " - C1h : Discrepancy of parameters inside and outside Package: This is the error that occurs in issuance commands."); PrintAndLogEx(NORMAL, " - C2h : Command is disabled already: This is the error that occurs in issuance commands."); @@ -162,9 +162,12 @@ static void print_status_flag2_interpration(){ static int usage_hf_felica_read_without_encryption() { PrintAndLogEx(NORMAL, "\nInfo: Use this command to read Block Data from authentication-not-required Service."); PrintAndLogEx(NORMAL, " - Mode shall be Mode0."); - PrintAndLogEx(NORMAL, " - Number of Service shall be a positive integer in the range of 1 to 16, inclusive."); - PrintAndLogEx(NORMAL, " - Number of Block shall be less than or equal to the maximum number of Blocks that can be read simultaneously. " - "The maximum number of Blocks that can be read simultaneously can differ, depending on the product being used."); + PrintAndLogEx(NORMAL, " - Number of Service: shall be a positive integer in the range of 1 to 16, inclusive."); + PrintAndLogEx(NORMAL, " - Number of Block: shall be less than or equal to the maximum number of Blocks that can be read simultaneously. " + "The maximum number of Blocks that can be read simultaneously can differ, depending on the product being used. Use as default 01"); + PrintAndLogEx(NORMAL, " - Service Code List: For Service Code List, only Service Code existing in the product shall be specified:"); + PrintAndLogEx(NORMAL, " - Even when Service Code exists in the product, Service Code not referenced from Block List shall not be specified to Service Code List."); + PrintAndLogEx(NORMAL, " - For existence or nonexistence of Service in a product, please check using the Request Service (or Request Service v2) command."); PrintAndLogEx(NORMAL, " - Each Block List Element shall satisfy the following conditions:"); PrintAndLogEx(NORMAL, " - The value of Service Code List Order shall not exceed Number of Service."); PrintAndLogEx(NORMAL, " - Access Mode shall be 000b."); @@ -179,10 +182,12 @@ static int usage_hf_felica_read_without_encryption() { PrintAndLogEx(NORMAL, "\nUsage: hf felica rdunencrypted [-h] <01 Number of Service hex> <0A0B Service Code List (Little Endian) hex> <01 Number of Block hex> <0A0B Block List Element hex>"); PrintAndLogEx(NORMAL, " -h this help"); PrintAndLogEx(NORMAL, " -i <0A0B0C ... hex> set custom IDm to use"); - PrintAndLogEx(NORMAL, " -b get all Block List Elements of service"); + PrintAndLogEx(NORMAL, " -b get all Block List Elements starting from 00 to FF - stops when a block return an error status flags"); + PrintAndLogEx(NORMAL, " -l use 3-byte block list element block number"); PrintAndLogEx(NORMAL, "\nExamples: "); PrintAndLogEx(NORMAL, " hf felica rdunencrypted 01 8B00 01 8000"); - PrintAndLogEx(NORMAL, " hf felica rdunencrypted -i 01100910c11bc407 01 8B00 01 8000\n\n"); + PrintAndLogEx(NORMAL, " hf felica rdunencrypted -i 01100910c11bc407 01 8B00 01 8000"); + PrintAndLogEx(NORMAL, " hf felica rdunencrypted -b 01 8B00 01 8000\n\n"); return PM3_SUCCESS; } @@ -194,7 +199,7 @@ static int usage_hf_felica_read_without_encryption() { static bool waitCmdFelica(uint8_t iSelect, PacketResponseNG *resp, bool verbose) { if (WaitForResponseTimeout(CMD_ACK, resp, 2000)) { uint16_t len = iSelect ? (resp->oldarg[1] & 0xffff) : (resp->oldarg[0] & 0xffff); - if(verbose){ + if (verbose) { PrintAndLogEx(NORMAL, "Client Received %i octets", len); if (!len || len < 2) { PrintAndLogEx(ERR, "Could not receive data correctly!"); @@ -269,7 +274,7 @@ static int CmdHFFelicaReader(const char *Cmd) { static void clear_and_send_command(uint8_t flags, uint16_t datalen, uint8_t *data, bool verbose) { uint16_t numbits = 0; clearCommandBuffer(); - if(verbose){ + if (verbose) { PrintAndLogEx(NORMAL, "Send Service Request Frame: %s", sprint_hex(data, datalen)); } SendCommandMIX(CMD_HF_FELICA_COMMAND, flags, (datalen & 0xFFFF) | (uint32_t)(numbits << 16), 0, data, datalen); @@ -284,7 +289,7 @@ static void clear_and_send_command(uint8_t flags, uint16_t datalen, uint8_t *dat * @param length which the parameter should have and will be tested against. * @return true if parameters was added. */ -static bool add_param(const char *Cmd, uint8_t paramCount, uint8_t *data, uint8_t dataPosition, uint8_t length){ +static bool add_param(const char *Cmd, uint8_t paramCount, uint8_t *data, uint8_t dataPosition, uint8_t length) { if (param_getlength(Cmd, paramCount) == length) { param_gethex(Cmd, paramCount, data + dataPosition, length); return true; @@ -298,22 +303,17 @@ static bool add_param(const char *Cmd, uint8_t paramCount, uint8_t *data, uint8_ * Prints read-without-encryption response. * @param rd_noCry_resp Response frame. */ -static void print_rd_noEncrpytion_response(felica_read_without_encryption_response_t *rd_noCry_resp){ - if(rd_noCry_resp->status_flag1[0] == 00 && rd_noCry_resp->status_flag2[0] == 00){ - char bl_number[4]; - char *temp = sprint_hex(rd_noCry_resp->number_of_block, sizeof(rd_noCry_resp->number_of_block)); - strcpy(bl_number, temp); - - temp = sprint_hex(rd_noCry_resp->block_data, sizeof(rd_noCry_resp->block_data)); +static void print_rd_noEncrpytion_response(felica_read_without_encryption_response_t *rd_noCry_resp) { + if (rd_noCry_resp->status_flag1[0] == 00 && rd_noCry_resp->status_flag2[0] == 00) { + char *temp = sprint_hex(rd_noCry_resp->block_data, sizeof(rd_noCry_resp->block_data)); char bl_data[256]; strcpy(bl_data, temp); char bl_element_number[4]; temp = sprint_hex(rd_noCry_resp->block_element_number, sizeof(rd_noCry_resp->block_element_number)); strcpy(bl_element_number, temp); - - PrintAndLogEx(NORMAL, "%s: %s: %s", bl_number, bl_element_number, bl_data); - }else{ + PrintAndLogEx(NORMAL, "\t%s\t| %s ", bl_element_number, bl_data); + } else { PrintAndLogEx(NORMAL, "IDm: %s", sprint_hex(rd_noCry_resp->IDm, sizeof(rd_noCry_resp->IDm))); PrintAndLogEx(NORMAL, "Status Flag1: %s", sprint_hex(rd_noCry_resp->status_flag1, sizeof(rd_noCry_resp->status_flag1))); PrintAndLogEx(NORMAL, "Status Flag2: %s", sprint_hex(rd_noCry_resp->status_flag1, sizeof(rd_noCry_resp->status_flag1))); @@ -354,7 +354,7 @@ int send_request_service(uint8_t flags, uint16_t datalen, uint8_t *data, bool ve * @param rd_noCry_resp frame in which the response will be saved * @return success if response was received. */ -int send_rd_unencrypted(uint8_t flags, uint16_t datalen, uint8_t *data, bool verbose, felica_read_without_encryption_response_t *rd_noCry_resp){ +int send_rd_unencrypted(uint8_t flags, uint16_t datalen, uint8_t *data, bool verbose, felica_read_without_encryption_response_t *rd_noCry_resp) { clear_and_send_command(flags, datalen, data, verbose); PacketResponseNG resp; if (!waitCmdFelica(0, &resp, verbose)) { @@ -393,7 +393,7 @@ static int CmdHFFelicaReadWithoutEncryption(const char *Cmd) { case 'i': paramCount++; custom_IDm = true; - if(!add_param(Cmd, paramCount, data, 3, 8)){ + if (!add_param(Cmd, paramCount, data, 3, 8)) { return PM3_EINVARG; } break; @@ -422,46 +422,48 @@ static int CmdHFFelicaReadWithoutEncryption(const char *Cmd) { // Number of Service 2, Service Code List 4, Number of Block 2, Block List Element 4 uint8_t lengths[] = {2, 4, 2, 4}; uint8_t dataPositions[] = {10, 11, 13, 14}; - if(long_block_numbers){ + if (long_block_numbers) { datalen += 1; lengths[3] = 6; } - for(int i=0; i < 4; i++){ - if(add_param(Cmd, paramCount, data, dataPositions[i], lengths[i])){ + for (int i = 0; i < 4; i++) { + if (add_param(Cmd, paramCount, data, dataPositions[i], lengths[i])) { paramCount++; - }else{ + } else { return PM3_EINVARG; } } flags |= FELICA_APPEND_CRC; flags |= FELICA_RAW; - if(all_block_list_elements){ + if (all_block_list_elements) { uint16_t last_block_number = 0xFF; - if(long_block_numbers){ + if (long_block_numbers) { last_block_number = 0xFFFF; } - for(int i=0x00; i < last_block_number; i++){ + PrintAndLogEx(NORMAL, "Block Element\t| Data "); + for (int i = 0x00; i < last_block_number; i++) { data[15] = i; AddCrc(data, datalen); datalen += 2; felica_read_without_encryption_response_t rd_noCry_resp; - if((send_rd_unencrypted(flags, datalen, data, 0, &rd_noCry_resp) == PM3_SUCCESS)){ - if(rd_noCry_resp.status_flag1[0] == 00 && rd_noCry_resp.status_flag2[0] == 00){ + if ((send_rd_unencrypted(flags, datalen, data, 0, &rd_noCry_resp) == PM3_SUCCESS)) { + if (rd_noCry_resp.status_flag1[0] == 00 && rd_noCry_resp.status_flag2[0] == 00) { print_rd_noEncrpytion_response(&rd_noCry_resp); - }else{ + } else { break; } - }else{ + } else { break; } datalen -= 2; } - }else{ + } else { AddCrc(data, datalen); datalen += 2; felica_read_without_encryption_response_t rd_noCry_resp; send_rd_unencrypted(flags, datalen, data, 1, &rd_noCry_resp); + PrintAndLogEx(NORMAL, "Block Element\t| Data "); print_rd_noEncrpytion_response(&rd_noCry_resp); } return PM3_SUCCESS; From b4bcec581cbc9a4e05fcdf42ec41ec167d74c8eb Mon Sep 17 00:00:00 2001 From: Thomas Sutter Date: Thu, 24 Oct 2019 17:10:56 +0200 Subject: [PATCH 1059/1854] Add changelong text --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 168199c2b..c0ef300cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Added hf felica rdunencrypted (@7homasSutter) - Added hf felica rqresponse (@7homasSutter) - Added hf felica rqservice (@7homasSutter) - Added polling for felica standard (@7homasSutter) From eb7268cd98ecf991b3fe61242dea8ce6bbe3fb63 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 25 Oct 2019 00:42:47 +0200 Subject: [PATCH 1060/1854] lf: change macros to allow float freq, change 134 -> 134.2 --- armsrc/lfops.c | 4 ++-- client/cmddata.c | 10 +++++----- client/cmdlf.c | 6 +++--- client/cmdlfmotorola.c | 2 +- include/pm3_cmd.h | 7 ++++--- 5 files changed, 15 insertions(+), 14 deletions(-) diff --git a/armsrc/lfops.c b/armsrc/lfops.c index a298af4a9..f4f3a9e7b 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -2418,7 +2418,7 @@ because of this, we can "sample" the data signal but we interpreate it to Manche This behavior looks very similar to old ancient Motorola Flexpass ----------------------------------------------------------------------- -According to patent: +According to patent EP0040544B1: Operating freq reader 132 kHz tag 66 kHz @@ -2453,7 +2453,7 @@ void Cotag(uint32_t arg0) { LED_A_ON(); - LFSetupFPGAForADC(LF_DIVISOR(132), true); + LFSetupFPGAForADC(LF_FREQ2DIV(132), true); //clear buffer now so it does not interfere with timing later BigBuf_Clear_ext(false); diff --git a/client/cmddata.c b/client/cmddata.c index 80c3bf076..5962d6ca6 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -1676,16 +1676,16 @@ int CmdTuneSamples(const char *Cmd) { struct p *package = (struct p *)resp.data.asBytes; if (package->v_lf125 > NON_VOLTAGE) - PrintAndLogEx(SUCCESS, "LF antenna: %5.2f V - %.2f kHz", (package->v_lf125 * ANTENNA_ERROR) / 1000.0, 12000.0 / (LF_DIVISOR_125 + 1)); + PrintAndLogEx(SUCCESS, "LF antenna: %5.2f V - %.2f kHz", (package->v_lf125 * ANTENNA_ERROR) / 1000.0, LF_DIV2FREQ(LF_DIVISOR_125)); if (package->v_lf134 > NON_VOLTAGE) - PrintAndLogEx(SUCCESS, "LF antenna: %5.2f V - %.2f kHz", (package->v_lf134 * ANTENNA_ERROR) / 1000.0, 12000.0 / (LF_DIVISOR_134 + 1)); + PrintAndLogEx(SUCCESS, "LF antenna: %5.2f V - %.2f kHz", (package->v_lf134 * ANTENNA_ERROR) / 1000.0, LF_DIV2FREQ(LF_DIVISOR_134)); if (package->v_lfconf > NON_VOLTAGE && package->divisor > 0 && package->divisor != LF_DIVISOR_125 && package->divisor != LF_DIVISOR_134) - PrintAndLogEx(SUCCESS, "LF antenna: %5.2f V - %.2f kHz", (package->v_lfconf * ANTENNA_ERROR) / 1000.0, 12000.0 / (package->divisor + 1)); + PrintAndLogEx(SUCCESS, "LF antenna: %5.2f V - %.2f kHz", (package->v_lfconf * ANTENNA_ERROR) / 1000.0, LF_DIV2FREQ(package->divisor)); if (package->peak_v > NON_VOLTAGE && package->peak_f > 0) - PrintAndLogEx(SUCCESS, "LF optimal: %5.2f V - %6.2f kHz", (package->peak_v * ANTENNA_ERROR) / 1000.0, 12000.0 / (package->peak_f + 1)); + PrintAndLogEx(SUCCESS, "LF optimal: %5.2f V - %6.2f kHz", (package->peak_v * ANTENNA_ERROR) / 1000.0, LF_DIV2FREQ(package->peak_f)); char judgement[20]; memset(judgement, 0, sizeof(judgement)); @@ -1730,7 +1730,7 @@ int CmdTuneSamples(const char *Cmd) { if (test1 > 0) { PrintAndLogEx(SUCCESS, "\nDisplaying LF tuning graph. Divisor %d is %.2f kHz, %d is %.2f kHz.\n\n", - LF_DIVISOR_134, 12000.0 / (LF_DIVISOR_134 + 1), LF_DIVISOR_125, 12000.0 / (LF_DIVISOR_125 + 1)); + LF_DIVISOR_134, LF_DIV2FREQ(LF_DIVISOR_134), LF_DIVISOR_125, LF_DIV2FREQ(LF_DIVISOR_125)); GraphTraceLen = 256; ShowGraphWindow(); RepaintGraphWindow(); diff --git a/client/cmdlf.c b/client/cmdlf.c index 4d7c72acc..8f5a88923 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -232,7 +232,7 @@ int CmdLFTune(const char *Cmd) { break; case 'f': { int freq = param_get32ex(Cmd, cmdp + 1, 125, 10); - divisor = LF_DIVISOR(freq); + divisor = LF_FREQ2DIV(freq); if (divisor < 19) { PrintAndLogEx(ERR, "freq must be between 47 and 600"); return PM3_EINVARG; @@ -254,7 +254,7 @@ int CmdLFTune(const char *Cmd) { //Validations if (errors) return usage_lf_tune(); - PrintAndLogEx(SUCCESS, "Measuring LF antenna at %.2f kHz, click button or press Enter to exit", 12000.0 / (divisor + 1)); + PrintAndLogEx(SUCCESS, "Measuring LF antenna at %.2f kHz, click button or press Enter to exit", LF_DIV2FREQ(divisor)); uint8_t params[] = {1, 0}; params[1] = divisor; @@ -498,7 +498,7 @@ int CmdLFConfig(const char *Cmd) { break; case 'f': { int freq = param_get32ex(Cmd, cmdp + 1, 125, 10); - divisor = LF_DIVISOR(freq); + divisor = LF_FREQ2DIV(freq); if (divisor < 19) { PrintAndLogEx(ERR, "freq must be between 47 and 600"); return PM3_EINVARG; diff --git a/client/cmdlfmotorola.c b/client/cmdlfmotorola.c index 87ea53a3b..dbcf28e40 100644 --- a/client/cmdlfmotorola.c +++ b/client/cmdlfmotorola.c @@ -127,7 +127,7 @@ static int CmdMotorolaRead(const char *Cmd) { .decimation = 0, .bits_per_sample = 0, .averaging = false, - .divisor = LF_DIVISOR(74), + .divisor = LF_FREQ2DIV(74), .trigger_threshold = -1, .samples_to_skip = 4500, .verbose = false diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 19ef27afb..544d5e5c2 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -590,9 +590,10 @@ typedef struct { #define PM3_EFATAL -99 // LF -#define LF_DIVISOR(f) (((12000 + (f)/2)/(f))-1) -#define LF_DIVISOR_125 LF_DIVISOR(125) -#define LF_DIVISOR_134 LF_DIVISOR(134) +#define LF_FREQ2DIV(f) ((int)(((12000.0 + (f)/2.0)/(f))-1)) +#define LF_DIVISOR_125 LF_FREQ2DIV(125) +#define LF_DIVISOR_134 LF_FREQ2DIV(134.2) +#define LF_DIV2FREQ(d) (12000.0/((d)+1)) // Receiving from USART need more than 30ms as we used on USB // else we get errors about partial packet reception From 390d0ab52527b0410b7b52afb81c44a360c420f4 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 25 Oct 2019 00:53:56 +0200 Subject: [PATCH 1061/1854] lf tune: allow float, added parse_getfloat to utils --- client/cmdlf.c | 6 +++--- client/util.c | 8 ++++++++ client/util.h | 1 + 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/client/cmdlf.c b/client/cmdlf.c index 8f5a88923..328af5e29 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -231,12 +231,12 @@ int CmdLFTune(const char *Cmd) { } break; case 'f': { - int freq = param_get32ex(Cmd, cmdp + 1, 125, 10); - divisor = LF_FREQ2DIV(freq); - if (divisor < 19) { + float freq = param_getfloat(Cmd, cmdp + 1, 125); + if ((freq < 47) || (freq > 600)) { PrintAndLogEx(ERR, "freq must be between 47 and 600"); return PM3_EINVARG; } + divisor = LF_FREQ2DIV(freq); cmdp += 2; break; } diff --git a/client/util.c b/client/util.c index da1b5d0e2..58dce8eca 100644 --- a/client/util.c +++ b/client/util.c @@ -551,6 +551,14 @@ uint64_t param_get64ex(const char *line, int paramnum, int deflt, int base) { return deflt; } +float param_getfloat(const char *line, int paramnum, float deflt) { + int bg, en; + if (!param_getptr(line, &bg, &en, paramnum)) + return strtof(&line[bg], NULL); + else + return deflt; +} + int param_gethex(const char *line, int paramnum, uint8_t *data, int hexcnt) { int bg, en, i; uint32_t temp; diff --git a/client/util.h b/client/util.h index 7d6c6460e..d549458c4 100644 --- a/client/util.h +++ b/client/util.h @@ -68,6 +68,7 @@ uint8_t param_get8(const char *line, int paramnum); uint8_t param_get8ex(const char *line, int paramnum, int deflt, int base); uint32_t param_get32ex(const char *line, int paramnum, int deflt, int base); uint64_t param_get64ex(const char *line, int paramnum, int deflt, int base); +float param_getfloat(const char *line, int paramnum, float deflt); uint8_t param_getdec(const char *line, int paramnum, uint8_t *destination); uint8_t param_isdec(const char *line, int paramnum); int param_gethex(const char *line, int paramnum, uint8_t *data, int hexcnt); From 07cf3fd32bf7319241941a014c38c59747834030 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 25 Oct 2019 00:55:16 +0200 Subject: [PATCH 1062/1854] fix few missing declarations -> static or add include file --- client/cmddata.c | 2 +- client/cmdhf.c | 2 +- client/cmdhw.c | 2 +- client/cmdlf.c | 2 +- client/cmdlfhitag.c | 2 ++ client/cmdlfnedap.c | 2 +- client/fileutils.c | 7 +++++-- client/loclass/ikeys.c | 2 ++ client/loclass/ikeys.h | 1 + client/proxmark3.c | 4 ++-- client/wiegand_formats.c | 2 +- client/wiegand_formatutils.c | 2 +- 12 files changed, 19 insertions(+), 11 deletions(-) diff --git a/client/cmddata.c b/client/cmddata.c index 5962d6ca6..499db7128 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -508,7 +508,7 @@ int CmdGetBitStream(const char *Cmd) { RepaintGraphWindow(); return PM3_SUCCESS; } -int CmdConvertBitStream(const char *Cmd) { +static int CmdConvertBitStream(const char *Cmd) { if (isGraphBitstream()) { convertGraphFromBitstream(); diff --git a/client/cmdhf.c b/client/cmdhf.c index 9166b01ca..1960de2ee 100644 --- a/client/cmdhf.c +++ b/client/cmdhf.c @@ -8,7 +8,7 @@ //----------------------------------------------------------------------------- // High frequency commands //----------------------------------------------------------------------------- -//#include "cmdhf.h" +#include "cmdhf.h" #include // tolower diff --git a/client/cmdhw.c b/client/cmdhw.c index ec53ad2cf..619e73abe 100644 --- a/client/cmdhw.c +++ b/client/cmdhw.c @@ -366,7 +366,7 @@ static void lookupChipID(uint32_t iChipID, uint32_t mem_used) { PrintAndLogEx(NORMAL, " --= Nonvolatile Program Memory Type: %s", asBuff); } -int CmdDbg(const char *Cmd) { +static int CmdDbg(const char *Cmd) { char ctmp = tolower(param_getchar(Cmd, 0)); if (strlen(Cmd) < 1 || ctmp == 'h') return usage_dbg(); diff --git a/client/cmdlf.c b/client/cmdlf.c index 328af5e29..e0238b0d6 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -213,7 +213,7 @@ static int usage_lf_tune(void) { return PM3_SUCCESS; } -int CmdLFTune(const char *Cmd) { +static int CmdLFTune(const char *Cmd) { int iter = 0; uint8_t divisor = LF_DIVISOR_125;//Frequency divisor bool errors = false; diff --git a/client/cmdlfhitag.c b/client/cmdlfhitag.c index a54b96a68..40e909024 100644 --- a/client/cmdlfhitag.c +++ b/client/cmdlfhitag.c @@ -8,6 +8,8 @@ // Low frequency Hitag support //----------------------------------------------------------------------------- +#include "cmdlfhitag.h" + #include #include "cmdparser.h" // command_t diff --git a/client/cmdlfnedap.c b/client/cmdlfnedap.c index 66d093800..84b433a0c 100644 --- a/client/cmdlfnedap.c +++ b/client/cmdlfnedap.c @@ -426,7 +426,7 @@ static int CmdLfNedapGen(const char *Cmd) { return PM3_SUCCESS; } -int CmdLFNedapClone(const char *Cmd) { +static int CmdLFNedapClone(const char *Cmd) { uint8_t max; uint32_t blocks[5] = {0}; diff --git a/client/fileutils.c b/client/fileutils.c index 8b537d423..ebdb662ca 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -74,7 +74,8 @@ int fileExists(const char *filename) { * @param filename * @return */ -bool is_regular_file(const char *filename) { +/* +static bool is_regular_file(const char *filename) { #ifdef _WIN32 struct _stat st; if (_stat(filename, &st) == -1) @@ -87,12 +88,14 @@ bool is_regular_file(const char *filename) { #endif return S_ISREG(st.st_mode) != 0; } +*/ + /** * @brief checks if path is directory. * @param filename * @return */ -bool is_directory(const char *filename) { +static bool is_directory(const char *filename) { #ifdef _WIN32 struct _stat st; if (_stat(filename, &st) == -1) diff --git a/client/loclass/ikeys.c b/client/loclass/ikeys.c index 1bff33f37..2f3a6c067 100644 --- a/client/loclass/ikeys.c +++ b/client/loclass/ikeys.c @@ -58,6 +58,8 @@ From "Dismantling iclass": output of hash0 is the diversified card key k = k [0] , . . . , k [7] ∈ (F 82 ) 8 . **/ +#include "ikeys.h" + #include #include #include diff --git a/client/loclass/ikeys.h b/client/loclass/ikeys.h index 29d285639..ccbc5539b 100644 --- a/client/loclass/ikeys.h +++ b/client/loclass/ikeys.h @@ -38,6 +38,7 @@ #ifndef IKEYS_H #define IKEYS_H +#include /** * @brief diff --git a/client/proxmark3.c b/client/proxmark3.c index fb02396bd..fde2af91e 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -56,7 +56,7 @@ static void showBanner(void) { g_printAndLog = PRINTANDLOG_PRINT | PRINTANDLOG_LOG; } -int check_comm(void) { +static int check_comm(void) { // If communications thread goes down. Device disconnected then this should hook up PM3 again. if (IsCommunicationThreadDead() && session.pm3_present) { rl_set_prompt(PROXPROMPT_OFFLINE); @@ -86,7 +86,7 @@ int push_cmdscriptfile(char *path, bool stayafter) { return PM3_SUCCESS; } -FILE *current_cmdscriptfile() { +static FILE *current_cmdscriptfile() { return cmdscriptfile[cmdscriptfile_idx]; } diff --git a/client/wiegand_formats.c b/client/wiegand_formats.c index 983e0f432..613f68e20 100644 --- a/client/wiegand_formats.c +++ b/client/wiegand_formats.c @@ -650,7 +650,7 @@ bool HIDPack(int format_idx, wiegand_card_t *card, wiegand_message_t *packed) { return FormatTable[format_idx].Pack(card, packed); } -void HIDDisplayUnpackedCard(wiegand_card_t *card, const cardformat_t format) { +static void HIDDisplayUnpackedCard(wiegand_card_t *card, const cardformat_t format) { /* PrintAndLogEx(SUCCESS, " Format: %s (%s)", format.Name, format.Descrp); diff --git a/client/wiegand_formatutils.c b/client/wiegand_formatutils.c index 80a9c9268..ba446957a 100644 --- a/client/wiegand_formatutils.c +++ b/client/wiegand_formatutils.c @@ -120,7 +120,7 @@ bool set_nonlinear_field(wiegand_message_t *data, uint64_t value, uint8_t numBit return result; } -uint8_t get_length_from_header(wiegand_message_t *data) { +static uint8_t get_length_from_header(wiegand_message_t *data) { uint8_t len = 0; uint32_t hfmt = 0; // for calculating card length From 6f3f5d2d838c0bdf958828825c0c20da8706e229 Mon Sep 17 00:00:00 2001 From: Fl0-0 Date: Fri, 25 Oct 2019 14:53:08 +0200 Subject: [PATCH 1063/1854] Fix for hf mf autopwn #db# AcquireNonces: Auth1 error loop, revert commit abb011c --- client/cmdhfmf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 16e4029db..47b591875 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -1967,7 +1967,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { // Store valid credentials for the nested / hardnested attack if none exist if (know_target_key == false) { - num_to_bytes(e_sector[i].Key[j], 6, tmp_key); + num_to_bytes(e_sector[i].Key[j], 6, key); know_target_key = true; blockNo = i; keyType = j; From 9c2ef4e0da09e8f13830ac292526064c34b98630 Mon Sep 17 00:00:00 2001 From: mwalker33 Date: Sat, 26 Oct 2019 13:17:33 +1100 Subject: [PATCH 1064/1854] 2nd Win10 Color Reg. Key Check --- client/proxmark3.c | 29 +++++++++++++++++-- .../Windows-Installation-Instructions.md | 10 ++++++- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/client/proxmark3.c b/client/proxmark3.c index fde2af91e..53ce6e203 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -473,11 +473,16 @@ finish2: // Check if windows AnsiColor Support is enabled in the registery // [HKEY_CURRENT_USER\Console] // "VirtualTerminalLevel"=dword:00000001 +// 2nd Key needs to be enabled... This key takes the console out of legacy mode. +// [HKEY_CURRENT_USER\Console] +// "ForceV2"=dword:00000001 static bool DetectWindowsAnsiSupport(void) { bool ret = false; #if defined(_WIN32) HKEY hKey = NULL; - + bool virtualTerminalLevelSet = false; + bool forceV2Set = false; + if (RegOpenKeyA(HKEY_CURRENT_USER, "Console", &hKey) == ERROR_SUCCESS) { DWORD dwType = REG_SZ; BYTE KeyValue[sizeof(dwType)]; @@ -490,11 +495,31 @@ static bool DetectWindowsAnsiSupport(void) { Data += KeyValue[i] << (8 * i); if (Data == 1) { // Reg key is set to 1, Ansi Color Enabled - ret = true; + virtualTerminalLevelSet = true; } } RegCloseKey(hKey); } + + if (RegOpenKeyA(HKEY_CURRENT_USER, "Console", &hKey) == ERROR_SUCCESS) { + DWORD dwType = REG_SZ; + BYTE KeyValue[sizeof(dwType)]; + DWORD len = sizeof(KeyValue); + + if (RegQueryValueEx(hKey, "ForceV2", NULL, &dwType, KeyValue, &len) != ERROR_FILE_NOT_FOUND) { + uint8_t i; + uint32_t Data = 0; + for (i = 0; i < 4; i++) + Data += KeyValue[i] << (8 * i); + + if (Data == 1) { // Reg key is set to 1, Not using legacy Mode. + forceV2Set = true; + } + } + RegCloseKey(hKey); + } + // If both VirtualTerminalLevel and ForceV2 is set, AnsiColor should work + ret = virtualTerminalLevelSet && forceV2Set; #endif return ret; } diff --git a/doc/md/Installation_Instructions/Windows-Installation-Instructions.md b/doc/md/Installation_Instructions/Windows-Installation-Instructions.md index dfbea55c4..d77a2dfae 100644 --- a/doc/md/Installation_Instructions/Windows-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Windows-Installation-Instructions.md @@ -135,4 +135,12 @@ In later versions of windows 10 you may be able to get color to work by setting [HKEY_CURRENT_USER\Console] "VirtualTerminalLevel"=dword:00000001 ``` -If after setting this key (and restarting proxmark3.exe) you get extra characters and no color text, either delete the key or set the value to 0 +You also need to disable "use legacy console" in the cmd.exe properties, or set the following registry key +``` +[HKEY_CURRENT_USER\Console] + "ForceV2"=dword:00000001 +``` +After making these changes, you will need to start a new command prompt (cmd.exe) to ensure its using the new settings. + +If after making these changes (and restarting proxmark3.exe) you get extra characters and no color text, set either key to 0 or enable legacy mode again (and restart the command prompt). + From c613a758b267679da57af9643594f527969ab52c Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 26 Oct 2019 18:06:52 +0200 Subject: [PATCH 1065/1854] mfkey64: fix sscanf uint8_t clang warning --- tools/mfkey/mfkey64.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/mfkey/mfkey64.c b/tools/mfkey/mfkey64.c index dbf0bea9f..04126c7cf 100644 --- a/tools/mfkey/mfkey64.c +++ b/tools/mfkey/mfkey64.c @@ -38,7 +38,7 @@ int main(int argc, char *argv[]) { for (int i = 0; i < encc; i++) { enclen[i] = strlen(argv[i + 6]) / 2; for (int i2 = 0; i2 < enclen[i]; i2++) { - sscanf(argv[i + 6] + i2 * 2, "%2x", (unsigned int *)&enc[i][i2]); + sscanf(argv[i + 6] + i2 * 2, "%2hhx", &enc[i][i2]); } } From c6220dc7beac979b4479653a09f35f3cfecc0f42 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 26 Oct 2019 18:32:17 +0200 Subject: [PATCH 1066/1854] fpga_compress: unused parameter warning --- tools/fpga_compress/fpga_compress.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/fpga_compress/fpga_compress.c b/tools/fpga_compress/fpga_compress.c index 2174571d6..56dab1865 100644 --- a/tools/fpga_compress/fpga_compress.c +++ b/tools/fpga_compress/fpga_compress.c @@ -53,11 +53,13 @@ static void usage(void) { static voidpf fpga_deflate_malloc(voidpf opaque, uInt items, uInt size) { + (void) opaque; return calloc(items * size, sizeof(uint8_t)); } static void fpga_deflate_free(voidpf opaque, voidpf address) { + (void) opaque; free(address); } From 5ef4d6dbbb0548de88c1f6a5a51f0ab17bd60469 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 26 Oct 2019 18:32:38 +0200 Subject: [PATCH 1067/1854] fpga_compress: no previous prototype warning --- tools/fpga_compress/fpga_compress.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/fpga_compress/fpga_compress.c b/tools/fpga_compress/fpga_compress.c index 56dab1865..0992c53ca 100644 --- a/tools/fpga_compress/fpga_compress.c +++ b/tools/fpga_compress/fpga_compress.c @@ -74,7 +74,7 @@ static bool all_feof(FILE *infile[], uint8_t num_infiles) { } -int zlib_compress(FILE *infile[], uint8_t num_infiles, FILE *outfile, bool hardnested_mode) { +static int zlib_compress(FILE *infile[], uint8_t num_infiles, FILE *outfile, bool hardnested_mode) { uint8_t *fpga_config; uint32_t i; int32_t ret; @@ -184,7 +184,7 @@ int zlib_compress(FILE *infile[], uint8_t num_infiles, FILE *outfile, bool hardn } -int zlib_decompress(FILE *infile, FILE *outfile) { +static int zlib_decompress(FILE *infile, FILE *outfile) { #define DECOMPRESS_BUF_SIZE 1024 uint8_t outbuf[DECOMPRESS_BUF_SIZE]; uint8_t inbuf[DECOMPRESS_BUF_SIZE]; From c523980d99689e91bf0f66e4bc4c1b89c7ce6f01 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 26 Oct 2019 18:34:04 +0200 Subject: [PATCH 1068/1854] zlib: enumeration values not explicitly handled in switch warning --- common/zlib/inflate.h | 4 ++++ common/zlib/inftrees.c | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/common/zlib/inflate.h b/common/zlib/inflate.h index f48620e08..f91e0aa78 100644 --- a/common/zlib/inflate.h +++ b/common/zlib/inflate.h @@ -19,6 +19,7 @@ /* Possible inflate modes between inflate() calls */ typedef enum { HEAD = 16180, /* i: waiting for magic header */ +#ifdef GUNZIP FLAGS, /* i: waiting for method and flags (gzip) */ TIME, /* i: waiting for modification time (gzip) */ OS, /* i: waiting for extra flags and operating system (gzip) */ @@ -27,6 +28,7 @@ typedef enum { NAME, /* i: waiting for end of file name (gzip) */ COMMENT, /* i: waiting for end of comment (gzip) */ HCRC, /* i: waiting for header crc (gzip) */ +#endif DICTID, /* i: waiting for dictionary check value */ DICT, /* waiting for inflateSetDictionary() call */ TYPE, /* i: waiting for type bits, including last-flag bit */ @@ -45,7 +47,9 @@ typedef enum { MATCH, /* o: waiting for output space to copy string */ LIT, /* o: waiting for output space to write literal */ CHECK, /* i: waiting for 32-bit check value */ +#ifdef GUNZIP LENGTH, /* i: waiting for 32-bit length (gzip) */ +#endif DONE, /* finished check, done -- remain here until reset */ BAD, /* got a data error -- remain here until reset */ MEM, /* got an inflate() memory error -- remain here until reset */ diff --git a/common/zlib/inftrees.c b/common/zlib/inftrees.c index 49672650c..3dae7e534 100644 --- a/common/zlib/inftrees.c +++ b/common/zlib/inftrees.c @@ -191,7 +191,8 @@ int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens, extra = lext; match = 257; break; - default: /* DISTS */ + case DISTS: + default: base = dbase; extra = dext; match = 0; From a869ae9687839b08a44c2ec25ea92f424db34e6b Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 26 Oct 2019 18:34:25 +0200 Subject: [PATCH 1069/1854] zlib: unused parameter warning --- common/zlib/trees.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/common/zlib/trees.c b/common/zlib/trees.c index 8d230426e..1ef49d00d 100644 --- a/common/zlib/trees.c +++ b/common/zlib/trees.c @@ -923,6 +923,10 @@ charf *buf; /* input block, or NULL if too old */ ulg stored_len; /* length of input block */ int last; /* one if this is the last block for a file */ { +#ifdef ZLIB_PM3_TUNED + (void) buf; + (void) stored_len; +#endif int max_blindex = 0; /* index of last bit length code of non zero freq */ #ifndef ZLIB_PM3_TUNED ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ From af75c70c2735010a460462e8576dce13c1750493 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 26 Oct 2019 18:49:25 +0200 Subject: [PATCH 1070/1854] wiegand: no previous prototype warnings --- client/proxmark3.c | 2 +- client/wiegand_formats.c | 72 ++++++++++++++++++++-------------------- 2 files changed, 37 insertions(+), 37 deletions(-) diff --git a/client/proxmark3.c b/client/proxmark3.c index 53ce6e203..91d130fb2 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -90,7 +90,7 @@ static FILE *current_cmdscriptfile() { return cmdscriptfile[cmdscriptfile_idx]; } -bool pop_cmdscriptfile() { +static bool pop_cmdscriptfile() { fclose(cmdscriptfile[cmdscriptfile_idx]); cmdscriptfile[cmdscriptfile_idx--] = NULL; if (cmdscriptfile_idx == 0) diff --git a/client/wiegand_formats.c b/client/wiegand_formats.c index 613f68e20..a535bc614 100644 --- a/client/wiegand_formats.c +++ b/client/wiegand_formats.c @@ -10,7 +10,7 @@ #include "wiegand_formats.h" #include "commonutil.h" -bool Pack_H10301(wiegand_card_t *card, wiegand_message_t *packed) { +static bool Pack_H10301(wiegand_card_t *card, wiegand_message_t *packed) { memset(packed, 0, sizeof(wiegand_message_t)); if (card->FacilityCode > 0xFF) return false; // Can't encode FC. @@ -26,7 +26,7 @@ bool Pack_H10301(wiegand_card_t *card, wiegand_message_t *packed) { return add_HID_header(packed); } -bool Unpack_H10301(wiegand_message_t *packed, wiegand_card_t *card) { +static bool Unpack_H10301(wiegand_message_t *packed, wiegand_card_t *card) { memset(card, 0, sizeof(wiegand_card_t)); if (packed->Length != 26) return false; // Wrong length? Stop here. @@ -38,7 +38,7 @@ bool Unpack_H10301(wiegand_message_t *packed, wiegand_card_t *card) { return true; } -bool Pack_Tecom27(wiegand_card_t *card, wiegand_message_t *packed) { +static bool Pack_Tecom27(wiegand_card_t *card, wiegand_message_t *packed) { memset(packed, 0, sizeof(wiegand_message_t)); if (card->FacilityCode > 0x7FF) return false; // Can't encode FC. @@ -52,7 +52,7 @@ bool Pack_Tecom27(wiegand_card_t *card, wiegand_message_t *packed) { return add_HID_header(packed); } -bool Unpack_Tecom27(wiegand_message_t *packed, wiegand_card_t *card) { +static bool Unpack_Tecom27(wiegand_message_t *packed, wiegand_card_t *card) { memset(card, 0, sizeof(wiegand_card_t)); if (packed->Length != 27) return false; // Wrong length? Stop here. @@ -62,7 +62,7 @@ bool Unpack_Tecom27(wiegand_message_t *packed, wiegand_card_t *card) { return true; } -bool Pack_2804W(wiegand_card_t *card, wiegand_message_t *packed) { +static bool Pack_2804W(wiegand_card_t *card, wiegand_message_t *packed) { memset(packed, 0, sizeof(wiegand_message_t)); if (card->FacilityCode > 0x0FF) return false; // Can't encode FC. @@ -85,7 +85,7 @@ bool Pack_2804W(wiegand_card_t *card, wiegand_message_t *packed) { return add_HID_header(packed); } -bool Unpack_2804W(wiegand_message_t *packed, wiegand_card_t *card) { +static bool Unpack_2804W(wiegand_message_t *packed, wiegand_card_t *card) { memset(card, 0, sizeof(wiegand_card_t)); if (packed->Length != 28) return false; // Wrong length? Stop here. @@ -99,7 +99,7 @@ bool Unpack_2804W(wiegand_message_t *packed, wiegand_card_t *card) { return true; } -bool Pack_ATSW30(wiegand_card_t *card, wiegand_message_t *packed) { +static bool Pack_ATSW30(wiegand_card_t *card, wiegand_message_t *packed) { memset(packed, 0, sizeof(wiegand_message_t)); if (card->FacilityCode > 0xFFF) return false; // Can't encode FC. @@ -119,7 +119,7 @@ bool Pack_ATSW30(wiegand_card_t *card, wiegand_message_t *packed) { return add_HID_header(packed); } -bool Unpack_ATSW30(wiegand_message_t *packed, wiegand_card_t *card) { +static bool Unpack_ATSW30(wiegand_message_t *packed, wiegand_card_t *card) { memset(card, 0, sizeof(wiegand_card_t)); if (packed->Length != 30) return false; // Wrong length? Stop here. @@ -132,7 +132,7 @@ bool Unpack_ATSW30(wiegand_message_t *packed, wiegand_card_t *card) { return true; } -bool Pack_ADT31(wiegand_card_t *card, wiegand_message_t *packed) { +static bool Pack_ADT31(wiegand_card_t *card, wiegand_message_t *packed) { memset(packed, 0, sizeof(wiegand_message_t)); if (card->FacilityCode > 0x0F) return false; // Can't encode FC. @@ -147,7 +147,7 @@ bool Pack_ADT31(wiegand_card_t *card, wiegand_message_t *packed) { return add_HID_header(packed); } -bool Unpack_ADT31(wiegand_message_t *packed, wiegand_card_t *card) { +static bool Unpack_ADT31(wiegand_message_t *packed, wiegand_card_t *card) { memset(card, 0, sizeof(wiegand_card_t)); if (packed->Length != 31) return false; // Wrong length? Stop here. @@ -156,7 +156,7 @@ bool Unpack_ADT31(wiegand_message_t *packed, wiegand_card_t *card) { return true; } -bool Pack_Kastle(wiegand_card_t *card, wiegand_message_t *packed) { +static bool Pack_Kastle(wiegand_card_t *card, wiegand_message_t *packed) { memset(packed, 0, sizeof(wiegand_message_t)); if (card->FacilityCode > 0x00FF) return false; // Can't encode FC. @@ -174,7 +174,7 @@ bool Pack_Kastle(wiegand_card_t *card, wiegand_message_t *packed) { return add_HID_header(packed); } -bool Unpack_Kastle(wiegand_message_t *packed, wiegand_card_t *card) { +static bool Unpack_Kastle(wiegand_message_t *packed, wiegand_card_t *card) { memset(card, 0, sizeof(wiegand_card_t)); if (packed->Length != 32) return false; // Wrong length? Stop here. @@ -189,7 +189,7 @@ bool Unpack_Kastle(wiegand_message_t *packed, wiegand_card_t *card) { return true; } -bool Pack_D10202(wiegand_card_t *card, wiegand_message_t *packed) { +static bool Pack_D10202(wiegand_card_t *card, wiegand_message_t *packed) { memset(packed, 0, sizeof(wiegand_message_t)); if (card->FacilityCode > 0x007F) return false; // Can't encode FC. @@ -205,7 +205,7 @@ bool Pack_D10202(wiegand_card_t *card, wiegand_message_t *packed) { return add_HID_header(packed); } -bool Unpack_D10202(wiegand_message_t *packed, wiegand_card_t *card) { +static bool Unpack_D10202(wiegand_message_t *packed, wiegand_card_t *card) { memset(card, 0, sizeof(wiegand_card_t)); if (packed->Length != 33) return false; // Wrong length? Stop here. @@ -218,7 +218,7 @@ bool Unpack_D10202(wiegand_message_t *packed, wiegand_card_t *card) { return true; } -bool Pack_H10306(wiegand_card_t *card, wiegand_message_t *packed) { +static bool Pack_H10306(wiegand_card_t *card, wiegand_message_t *packed) { memset(packed, 0, sizeof(wiegand_message_t)); if (card->FacilityCode > 0xFFFF) return false; // Can't encode FC. @@ -235,7 +235,7 @@ bool Pack_H10306(wiegand_card_t *card, wiegand_message_t *packed) { return add_HID_header(packed); } -bool Unpack_H10306(wiegand_message_t *packed, wiegand_card_t *card) { +static bool Unpack_H10306(wiegand_message_t *packed, wiegand_card_t *card) { memset(card, 0, sizeof(wiegand_card_t)); if (packed->Length != 34) return false; // Wrong length? Stop here. @@ -248,7 +248,7 @@ bool Unpack_H10306(wiegand_message_t *packed, wiegand_card_t *card) { return true; } -bool Pack_N10002(wiegand_card_t *card, wiegand_message_t *packed) { +static bool Pack_N10002(wiegand_card_t *card, wiegand_message_t *packed) { memset(packed, 0, sizeof(wiegand_message_t)); if (card->FacilityCode > 0xFF) return false; // Can't encode FC. @@ -262,7 +262,7 @@ bool Pack_N10002(wiegand_card_t *card, wiegand_message_t *packed) { return add_HID_header(packed); } -bool Unpack_N10002(wiegand_message_t *packed, wiegand_card_t *card) { +static bool Unpack_N10002(wiegand_message_t *packed, wiegand_card_t *card) { memset(card, 0, sizeof(wiegand_card_t)); if (packed->Length != 34) return false; // Wrong length? Stop here. @@ -272,7 +272,7 @@ bool Unpack_N10002(wiegand_message_t *packed, wiegand_card_t *card) { return true; } -bool Pack_C1k35s(wiegand_card_t *card, wiegand_message_t *packed) { +static bool Pack_C1k35s(wiegand_card_t *card, wiegand_message_t *packed) { memset(packed, 0, sizeof(wiegand_message_t)); if (card->FacilityCode > 0xFFF) return false; // Can't encode FC. @@ -290,7 +290,7 @@ bool Pack_C1k35s(wiegand_card_t *card, wiegand_message_t *packed) { return add_HID_header(packed); } -bool Unpack_C1k35s(wiegand_message_t *packed, wiegand_card_t *card) { +static bool Unpack_C1k35s(wiegand_message_t *packed, wiegand_card_t *card) { memset(card, 0, sizeof(wiegand_card_t)); if (packed->Length != 35) return false; // Wrong length? Stop here. @@ -304,7 +304,7 @@ bool Unpack_C1k35s(wiegand_message_t *packed, wiegand_card_t *card) { return true; } -bool Pack_H10320(wiegand_card_t *card, wiegand_message_t *packed) { +static bool Pack_H10320(wiegand_card_t *card, wiegand_message_t *packed) { memset(packed, 0, sizeof(wiegand_message_t)); if (card->FacilityCode > 0) return false; // Can't encode FC. (none in this format) @@ -332,7 +332,7 @@ bool Pack_H10320(wiegand_card_t *card, wiegand_message_t *packed) { return add_HID_header(packed); } -bool Unpack_H10320(wiegand_message_t *packed, wiegand_card_t *card) { +static bool Unpack_H10320(wiegand_message_t *packed, wiegand_card_t *card) { memset(card, 0, sizeof(wiegand_card_t)); if (packed->Length != 36) return false; // Wrong length? Stop here. @@ -356,7 +356,7 @@ bool Unpack_H10320(wiegand_message_t *packed, wiegand_card_t *card) { return true; } -bool Pack_S12906(wiegand_card_t *card, wiegand_message_t *packed) { +static bool Pack_S12906(wiegand_card_t *card, wiegand_message_t *packed) { memset(packed, 0, sizeof(wiegand_message_t)); if (card->FacilityCode > 0xFF) return false; // Can't encode FC. @@ -373,7 +373,7 @@ bool Pack_S12906(wiegand_card_t *card, wiegand_message_t *packed) { return add_HID_header(packed); } -bool Unpack_S12906(wiegand_message_t *packed, wiegand_card_t *card) { +static bool Unpack_S12906(wiegand_message_t *packed, wiegand_card_t *card) { memset(card, 0, sizeof(wiegand_card_t)); if (packed->Length != 36) return false; // Wrong length? Stop here. @@ -387,7 +387,7 @@ bool Unpack_S12906(wiegand_message_t *packed, wiegand_card_t *card) { return true; } -bool Pack_Sie36(wiegand_card_t *card, wiegand_message_t *packed) { +static bool Pack_Sie36(wiegand_card_t *card, wiegand_message_t *packed) { memset(packed, 0, sizeof(wiegand_message_t)); if (card->FacilityCode > 0x0003FFFF) return false; // Can't encode FC. @@ -407,7 +407,7 @@ bool Pack_Sie36(wiegand_card_t *card, wiegand_message_t *packed) { return add_HID_header(packed); } -bool Unpack_Sie36(wiegand_message_t *packed, wiegand_card_t *card) { +static bool Unpack_Sie36(wiegand_message_t *packed, wiegand_card_t *card) { memset(card, 0, sizeof(wiegand_card_t)); if (packed->Length != 36) return false; // Wrong length? Stop here. @@ -420,7 +420,7 @@ bool Unpack_Sie36(wiegand_message_t *packed, wiegand_card_t *card) { return true; } -bool Pack_C15001(wiegand_card_t *card, wiegand_message_t *packed) { +static bool Pack_C15001(wiegand_card_t *card, wiegand_message_t *packed) { memset(packed, 0, sizeof(wiegand_message_t)); if (card->FacilityCode > 0x000000FF) return false; // Can't encode FC. @@ -437,7 +437,7 @@ bool Pack_C15001(wiegand_card_t *card, wiegand_message_t *packed) { return add_HID_header(packed); } -bool Unpack_C15001(wiegand_message_t *packed, wiegand_card_t *card) { +static bool Unpack_C15001(wiegand_message_t *packed, wiegand_card_t *card) { memset(card, 0, sizeof(wiegand_card_t)); if (packed->Length != 36) return false; // Wrong length? Stop here. @@ -451,7 +451,7 @@ bool Unpack_C15001(wiegand_message_t *packed, wiegand_card_t *card) { return true; } -bool Pack_H10302(wiegand_card_t *card, wiegand_message_t *packed) { +static bool Pack_H10302(wiegand_card_t *card, wiegand_message_t *packed) { memset(packed, 0, sizeof(wiegand_message_t)); if (card->FacilityCode > 0) return false; // Can't encode FC. (none in this format) @@ -466,7 +466,7 @@ bool Pack_H10302(wiegand_card_t *card, wiegand_message_t *packed) { return add_HID_header(packed); } -bool Unpack_H10302(wiegand_message_t *packed, wiegand_card_t *card) { +static bool Unpack_H10302(wiegand_message_t *packed, wiegand_card_t *card) { memset(card, 0, sizeof(wiegand_card_t)); if (packed->Length != 37) return false; // Wrong length? Stop here. @@ -478,7 +478,7 @@ bool Unpack_H10302(wiegand_message_t *packed, wiegand_card_t *card) { return true; } -bool Pack_H10304(wiegand_card_t *card, wiegand_message_t *packed) { +static bool Pack_H10304(wiegand_card_t *card, wiegand_message_t *packed) { memset(packed, 0, sizeof(wiegand_message_t)); if (card->FacilityCode > 0x0000FFFF) return false; // Can't encode FC. @@ -495,7 +495,7 @@ bool Pack_H10304(wiegand_card_t *card, wiegand_message_t *packed) { return add_HID_header(packed); } -bool Unpack_H10304(wiegand_message_t *packed, wiegand_card_t *card) { +static bool Unpack_H10304(wiegand_message_t *packed, wiegand_card_t *card) { memset(card, 0, sizeof(wiegand_card_t)); if (packed->Length != 37) return false; // Wrong length? Stop here. @@ -508,7 +508,7 @@ bool Unpack_H10304(wiegand_message_t *packed, wiegand_card_t *card) { return true; } -bool Pack_P10001(wiegand_card_t *card, wiegand_message_t *packed) { +static bool Pack_P10001(wiegand_card_t *card, wiegand_message_t *packed) { memset(packed, 0, sizeof(wiegand_message_t)); @@ -530,7 +530,7 @@ bool Pack_P10001(wiegand_card_t *card, wiegand_message_t *packed) { return add_HID_header(packed); } -bool Unpack_P10001(wiegand_message_t *packed, wiegand_card_t *card) { +static bool Unpack_P10001(wiegand_message_t *packed, wiegand_card_t *card) { memset(card, 0, sizeof(wiegand_card_t)); @@ -547,7 +547,7 @@ bool Unpack_P10001(wiegand_message_t *packed, wiegand_card_t *card) { return true; } -bool Pack_C1k48s(wiegand_card_t *card, wiegand_message_t *packed) { +static bool Pack_C1k48s(wiegand_card_t *card, wiegand_message_t *packed) { memset(packed, 0, sizeof(wiegand_message_t)); @@ -566,7 +566,7 @@ bool Pack_C1k48s(wiegand_card_t *card, wiegand_message_t *packed) { return add_HID_header(packed); } -bool Unpack_C1k48s(wiegand_message_t *packed, wiegand_card_t *card) { +static bool Unpack_C1k48s(wiegand_message_t *packed, wiegand_card_t *card) { memset(card, 0, sizeof(wiegand_card_t)); if (packed->Length != 48) return false; // Wrong length? Stop here. From 129b1c4b1f7a2c65587aabed546e68de227b43d3 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 26 Oct 2019 18:56:36 +0200 Subject: [PATCH 1071/1854] make sure all .c include their own .h --- armsrc/{fonts.c => fonts_disabled.c} | 2 ++ armsrc/{fonts.h => fonts_disabled.h} | 0 armsrc/hfsnoop.c | 1 + armsrc/legicrfsim.c | 1 + client/loclass/hash1_brute.c | 3 ++- 5 files changed, 6 insertions(+), 1 deletion(-) rename armsrc/{fonts.c => fonts_disabled.c} (99%) rename armsrc/{fonts.h => fonts_disabled.h} (100%) diff --git a/armsrc/fonts.c b/armsrc/fonts_disabled.c similarity index 99% rename from armsrc/fonts.c rename to armsrc/fonts_disabled.c index 78b96e238..97079f48a 100644 --- a/armsrc/fonts.c +++ b/armsrc/fonts_disabled.c @@ -6,6 +6,8 @@ // Fonts for the LCD //----------------------------------------------------------------------------- +#include "fonts.h" + const char FONT6x8[97][8] = { {0x06, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00}, // columns, rows, bytes per char {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // space diff --git a/armsrc/fonts.h b/armsrc/fonts_disabled.h similarity index 100% rename from armsrc/fonts.h rename to armsrc/fonts_disabled.h diff --git a/armsrc/hfsnoop.c b/armsrc/hfsnoop.c index 994d76e51..2c96ec218 100644 --- a/armsrc/hfsnoop.c +++ b/armsrc/hfsnoop.c @@ -1,3 +1,4 @@ +#include "hfsnoop.h" #include "proxmark3_arm.h" #include "BigBuf.h" #include "fpgaloader.h" diff --git a/armsrc/legicrfsim.c b/armsrc/legicrfsim.c index 111c4940b..34f8458ce 100644 --- a/armsrc/legicrfsim.c +++ b/armsrc/legicrfsim.c @@ -9,6 +9,7 @@ //----------------------------------------------------------------------------- // LEGIC RF simulation code //----------------------------------------------------------------------------- +#include "legicrfsim.h" #include "legicrf.h" #include "crc.h" /* legic crc-4 */ diff --git a/client/loclass/hash1_brute.c b/client/loclass/hash1_brute.c index 29430a2a6..e381c5a3a 100644 --- a/client/loclass/hash1_brute.c +++ b/client/loclass/hash1_brute.c @@ -1,3 +1,4 @@ +#include "hash1_brute.h" #include #include "cipherutils.h" #include @@ -54,7 +55,7 @@ static void calc_score(uint8_t *csn, uint8_t *k) { } } -static void brute_hash1(void) { +void brute_hash1(void) { uint16_t a, b, c, d; uint8_t csn[8] = {0, 0, 0, 0, 0xf7, 0xff, 0x12, 0xe0}; uint8_t k[8] = {0, 0, 0, 0, 0, 0, 0, 0}; From d5a68ac2922173be8a0824f0e1f01c0b6819804f Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 26 Oct 2019 19:37:36 +0200 Subject: [PATCH 1072/1854] check_crc: add CRC_KERMIT --- common/crc16.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/common/crc16.c b/common/crc16.c index 729c15cf4..57b984773 100644 --- a/common/crc16.c +++ b/common/crc16.c @@ -230,7 +230,7 @@ uint16_t Crc16ex(CrcType_t ct, const uint8_t *d, size_t n) { // n length (including crc) // // This function uses the message + crc bytes in order to compare the "residue" afterwards. -// crc16 algos like CRC-A become 0x000 +// crc16 algos like CRC-A become 0x0000 // while CRC-15693 become 0x0F47 // If calculated with crc bytes, the residue should be 0xF0B8 bool check_crc(CrcType_t ct, const uint8_t *d, size_t n) { @@ -254,6 +254,8 @@ bool check_crc(CrcType_t ct, const uint8_t *d, size_t n) { return (crc16_xmodem(d, n) == 0); case CRC_CCITT: return (crc16_ccitt(d, n) == 0); + case CRC_KERMIT: + return (crc16_kermit(d, n) == 0); case CRC_LEGIC: // TODO return false; From 11b954b6bdbcd7beb6d9e6344e654f8c0dc6779a Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 26 Oct 2019 19:40:32 +0200 Subject: [PATCH 1073/1854] proxmark.c: warnings discarded qualifiers --- client/proxmark3.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/proxmark3.c b/client/proxmark3.c index 91d130fb2..c1d6a5dc7 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -151,7 +151,7 @@ main_loop(char *script_cmds_file, char *script_cmd, bool stayInCommandLoop) { // loops every time enter is pressed... while (1) { bool printprompt = false; - char *prompt = PROXPROMPT; + const char *prompt = PROXPROMPT; check_script: // If there is a script file @@ -321,7 +321,7 @@ static void set_my_executable_path(void) { } } -static char *my_user_directory = NULL; +static const char *my_user_directory = NULL; const char *get_my_user_directory(void) { return my_user_directory; From cc902fb4d85ef4523f881cb98c644621df6ca778 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 26 Oct 2019 19:40:59 +0200 Subject: [PATCH 1074/1854] ui.c: warnings discarded qualifiers --- client/ui.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ui.c b/client/ui.c index d12713b9b..0cd2c589a 100644 --- a/client/ui.c +++ b/client/ui.c @@ -134,7 +134,7 @@ void PrintAndLogEx(logLevel_t level, const char *fmt, ...) { char *token = NULL; char *tmp_ptr = NULL; FILE *stream = stdout; - char *spinner[] = {_YELLOW_("[\\]"), _YELLOW_("[|]"), _YELLOW_("[/]"), _YELLOW_("[-]")}; + const char *spinner[] = {_YELLOW_("[\\]"), _YELLOW_("[|]"), _YELLOW_("[/]"), _YELLOW_("[-]")}; switch (level) { case ERR: strncpy(prefix, _RED_("[!!]"), sizeof(prefix) - 1); From c084862e07c64a6b968b68b5ab3521dd1b5bf8e2 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 26 Oct 2019 19:41:30 +0200 Subject: [PATCH 1075/1854] crc16: all enumerates in switch --- common/crc16.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/common/crc16.c b/common/crc16.c index 57b984773..22445beda 100644 --- a/common/crc16.c +++ b/common/crc16.c @@ -218,6 +218,7 @@ uint16_t Crc16ex(CrcType_t ct, const uint8_t *d, size_t n) { case CRC_LEGIC: // TODO return 0; + case CRC_NONE: default: break; } @@ -259,6 +260,7 @@ bool check_crc(CrcType_t ct, const uint8_t *d, size_t n) { case CRC_LEGIC: // TODO return false; + case CRC_NONE: default: break; } From 6c048c5026b2deaaf0a377658542227974e71b1f Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 26 Oct 2019 19:49:46 +0200 Subject: [PATCH 1076/1854] comms.c dl_it: remove unused arg --- client/comms.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/client/comms.c b/client/comms.c index 1ccdb4d05..d39680c6c 100644 --- a/client/comms.c +++ b/client/comms.c @@ -60,7 +60,7 @@ static uint64_t timeout_start_time; static uint64_t last_packet_time; -static bool dl_it(uint8_t *dest, uint32_t bytes, uint32_t start_index, PacketResponseNG *response, size_t ms_timeout, bool show_warning, uint32_t rec_cmd); +static bool dl_it(uint8_t *dest, uint32_t bytes, PacketResponseNG *response, size_t ms_timeout, bool show_warning, uint32_t rec_cmd); // Simple alias to track usages linked to the Bootloader, these commands must not be migrated. // - commands sent to enter bootloader mode as we might have to talk to old firmwares @@ -778,30 +778,30 @@ bool GetFromDevice(DeviceMemType_t memtype, uint8_t *dest, uint32_t bytes, uint3 switch (memtype) { case BIG_BUF: { SendCommandMIX(CMD_DOWNLOAD_BIGBUF, start_index, bytes, 0, NULL, 0); - return dl_it(dest, bytes, start_index, response, ms_timeout, show_warning, CMD_DOWNLOADED_BIGBUF); + return dl_it(dest, bytes, response, ms_timeout, show_warning, CMD_DOWNLOADED_BIGBUF); } case BIG_BUF_EML: { SendCommandMIX(CMD_DOWNLOAD_EML_BIGBUF, start_index, bytes, 0, NULL, 0); - return dl_it(dest, bytes, start_index, response, ms_timeout, show_warning, CMD_DOWNLOADED_EML_BIGBUF); + return dl_it(dest, bytes, response, ms_timeout, show_warning, CMD_DOWNLOADED_EML_BIGBUF); } case SPIFFS: { SendCommandMIX(CMD_SPIFFS_DOWNLOAD, start_index, bytes, 0, data, datalen); - return dl_it(dest, bytes, start_index, response, ms_timeout, show_warning, CMD_SPIFFS_DOWNLOADED); + return dl_it(dest, bytes, response, ms_timeout, show_warning, CMD_SPIFFS_DOWNLOADED); } case FLASH_MEM: { SendCommandMIX(CMD_FLASHMEM_DOWNLOAD, start_index, bytes, 0, NULL, 0); - return dl_it(dest, bytes, start_index, response, ms_timeout, show_warning, CMD_FLASHMEM_DOWNLOADED); + return dl_it(dest, bytes, response, ms_timeout, show_warning, CMD_FLASHMEM_DOWNLOADED); } case SIM_MEM: { //SendCommandMIX(CMD_DOWNLOAD_SIM_MEM, start_index, bytes, 0, NULL, 0); - //return dl_it(dest, bytes, start_index, response, ms_timeout, show_warning, CMD_DOWNLOADED_SIMMEM); + //return dl_it(dest, bytes, response, ms_timeout, show_warning, CMD_DOWNLOADED_SIMMEM); return false; } } return false; } -static bool dl_it(uint8_t *dest, uint32_t bytes, uint32_t start_index, PacketResponseNG *response, size_t ms_timeout, bool show_warning, uint32_t rec_cmd) { +static bool dl_it(uint8_t *dest, uint32_t bytes, PacketResponseNG *response, size_t ms_timeout, bool show_warning, uint32_t rec_cmd) { uint32_t bytes_completed = 0; __atomic_store_n(&timeout_start_time, msclock(), __ATOMIC_SEQ_CST); From 900184b600629f0edd528bd8ba77cb06794eb91a Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 26 Oct 2019 20:37:48 +0200 Subject: [PATCH 1077/1854] ikeys: "declaration shadows a variable in the global scope" warning --- client/loclass/ikeys.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/loclass/ikeys.c b/client/loclass/ikeys.c index 2f3a6c067..339ea91f7 100644 --- a/client/loclass/ikeys.c +++ b/client/loclass/ikeys.c @@ -422,7 +422,7 @@ typedef struct { uint8_t div_key[8]; } Testcase; -static int testDES(Testcase testcase, mbedtls_des_context ctx_enc, mbedtls_des_context ctx_dec) { +static int testDES(Testcase testcase) { uint8_t des_encrypted_csn[8] = {0}; uint8_t decrypted[8] = {0}; uint8_t div_key[8] = {0}; @@ -562,7 +562,7 @@ static int testKeyDiversificationWithMasterkeyTestcases() { PrintAndLogEx(INFO, "Testing encryption/decryption"); for (i = 0; memcmp(testcases + i, empty, 8); i++) - error += testDES(testcases[i], ctx_enc, ctx_dec); + error += testDES(testcases[i]); if (error) PrintAndLogEx(FAILED, "%d errors occurred (%d testcases)", error, i); From 377ead8e62a539203ec500fa13c21a05984eae31 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 27 Oct 2019 00:31:37 +0200 Subject: [PATCH 1078/1854] arm: honor CFLAGS and LDFLAGS --- common_arm/Makefile.common | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/common_arm/Makefile.common b/common_arm/Makefile.common index 52ec2ebd2..586901354 100644 --- a/common_arm/Makefile.common +++ b/common_arm/Makefile.common @@ -39,8 +39,10 @@ VPATH = . ../common_arm ../common ../common/crapto1 ../common/mbedtls ../common/ INCLUDES = ../include/proxmark3_arm.h ../include/at91sam7s512.h ../include/config_gpio.h ../include/pm3_cmd.h -CFLAGS = -c $(INCLUDE) -Wall -Werror -pedantic -Wunused -std=c99 $(APP_CFLAGS) -Os -LDFLAGS = -nostartfiles -nodefaultlibs -Wl,-gc-sections -n +CFLAGS ?= -Wall -Werror -pedantic -Wunused -Os +CFLAGS += -c $(INCLUDE) -std=c99 $(APP_CFLAGS) + +LDFLAGS += -nostartfiles -nodefaultlibs -Wl,-gc-sections -n LIBS = -lgcc # Flags to generate temporary dependency files From 2a0bc9c07b39b8c5f0c5f612acdba0349af09d48 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 27 Oct 2019 01:28:07 +0200 Subject: [PATCH 1079/1854] arm: move mthumb-interwork to CFLAGS for clang compatibility --- common_arm/Makefile.common | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/common_arm/Makefile.common b/common_arm/Makefile.common index 586901354..36887707c 100644 --- a/common_arm/Makefile.common +++ b/common_arm/Makefile.common @@ -39,7 +39,7 @@ VPATH = . ../common_arm ../common ../common/crapto1 ../common/mbedtls ../common/ INCLUDES = ../include/proxmark3_arm.h ../include/at91sam7s512.h ../include/config_gpio.h ../include/pm3_cmd.h -CFLAGS ?= -Wall -Werror -pedantic -Wunused -Os +CFLAGS ?= -Wall -Werror -pedantic -Wunused -Os -mthumb-interwork CFLAGS += -c $(INCLUDE) -std=c99 $(APP_CFLAGS) LDFLAGS += -nostartfiles -nodefaultlibs -Wl,-gc-sections -n @@ -57,21 +57,21 @@ VERSIONOBJ = $(patsubst %.c,$(OBJDIR)/%.o,$(notdir $(VERSIONSRC))) $(THUMBOBJ): $(OBJDIR)/%.o: %.c $(INCLUDES) $(info [-] CC $<) - $(Q)$(CC) $(CFLAGS) $(DEPFLAGS) -mthumb -mthumb-interwork -o $@ $< + $(Q)$(CC) $(CFLAGS) $(DEPFLAGS) -mthumb -o $@ $< $(Q)$(POSTCOMPILE) $(ARMOBJ): $(OBJDIR)/%.o: %.c $(INCLUDES) $(info [-] CC $<) - $(Q)$(CC) $(CFLAGS) $(DEPFLAGS) -mthumb-interwork -o $@ $< + $(Q)$(CC) $(CFLAGS) $(DEPFLAGS) -o $@ $< $(Q)$(POSTCOMPILE) $(ASMOBJ): $(OBJDIR)/%.o: %.s $(info [-] CC $<) - $(Q)$(CC) $(CFLAGS) -mthumb-interwork -o $@ $< + $(Q)$(CC) $(CFLAGS) -o $@ $< $(VERSIONOBJ): $(OBJDIR)/%.o: %.c $(INCLUDES) $(info [-] CC $<) - $(Q)$(CC) $(CFLAGS) -mthumb -mthumb-interwork -o $@ $< + $(Q)$(CC) $(CFLAGS) -mthumb -o $@ $< # This objcopy call translates physical flash addresses to logical addresses # without touching start address or RAM addresses (.bss and .data sections) From 271a8ce5481d439d7e50c1efa1a4f17c4905a897 Mon Sep 17 00:00:00 2001 From: Thomas Sutter Date: Tue, 29 Oct 2019 09:44:38 +0100 Subject: [PATCH 1080/1854] Add additional check for xero byte response. Add wrunencrypted usage text. --- client/cmdhffelica.c | 123 +++++++++++++++++++++++++++++++------------ 1 file changed, 89 insertions(+), 34 deletions(-) diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index b5a31b666..ead19c104 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -159,15 +159,7 @@ static void print_status_flag2_interpration() { PrintAndLogEx(NORMAL, " - C2h : Command is disabled already: This is the error that occurs in issuance commands."); } -static int usage_hf_felica_read_without_encryption() { - PrintAndLogEx(NORMAL, "\nInfo: Use this command to read Block Data from authentication-not-required Service."); - PrintAndLogEx(NORMAL, " - Mode shall be Mode0."); - PrintAndLogEx(NORMAL, " - Number of Service: shall be a positive integer in the range of 1 to 16, inclusive."); - PrintAndLogEx(NORMAL, " - Number of Block: shall be less than or equal to the maximum number of Blocks that can be read simultaneously. " - "The maximum number of Blocks that can be read simultaneously can differ, depending on the product being used. Use as default 01"); - PrintAndLogEx(NORMAL, " - Service Code List: For Service Code List, only Service Code existing in the product shall be specified:"); - PrintAndLogEx(NORMAL, " - Even when Service Code exists in the product, Service Code not referenced from Block List shall not be specified to Service Code List."); - PrintAndLogEx(NORMAL, " - For existence or nonexistence of Service in a product, please check using the Request Service (or Request Service v2) command."); +static void print_block_list_element_constraints(){ PrintAndLogEx(NORMAL, " - Each Block List Element shall satisfy the following conditions:"); PrintAndLogEx(NORMAL, " - The value of Service Code List Order shall not exceed Number of Service."); PrintAndLogEx(NORMAL, " - Access Mode shall be 000b."); @@ -175,6 +167,30 @@ static int usage_hf_felica_read_without_encryption() { PrintAndLogEx(NORMAL, " - Service specified in Service Code List shall exist in System."); PrintAndLogEx(NORMAL, " - Service Attribute of Service specified in Service Code List shall be authentication-not-required Service."); PrintAndLogEx(NORMAL, " - Block Number shall be in the range of the number of Blocks assigned to the specified Service."); +} + +static void print_number_of_service_constraints(){ + PrintAndLogEx(NORMAL, " - Number of Service: shall be a positive integer in the range of 1 to 16, inclusive."); +} + +static void print_number_of_block_constraints(){ + PrintAndLogEx(NORMAL, " - Number of Block: shall be less than or equal to the maximum number of Blocks that can be read simultaneously. " + "The maximum number of Blocks that can be read simultaneously can differ, depending on the product being used. Use as default 01"); +} + +static void print_service_code_list_constraints(){ + PrintAndLogEx(NORMAL, " - Service Code List: For Service Code List, only Service Code existing in the product shall be specified:"); + PrintAndLogEx(NORMAL, " - Even when Service Code exists in the product, Service Code not referenced from Block List shall not be specified to Service Code List."); + PrintAndLogEx(NORMAL, " - For existence or nonexistence of Service in a product, please check using the Request Service (or Request Service v2) command."); +} + +static int usage_hf_felica_read_without_encryption() { + PrintAndLogEx(NORMAL, "\nInfo: Use this command to read Block Data from authentication-not-required Service."); + PrintAndLogEx(NORMAL, " - Mode shall be Mode0."); + print_number_of_service_constraints(); + print_number_of_block_constraints(); + print_service_code_list_constraints(); + print_block_list_element_constraints(); PrintAndLogEx(NORMAL, " - Successful read: Card responses the block data"); PrintAndLogEx(NORMAL, " - Unsuccessful read: Card responses with Status Flag1 and Flag2"); print_status_flag1_interpretation(); @@ -191,6 +207,26 @@ static int usage_hf_felica_read_without_encryption() { return PM3_SUCCESS; } +static int usage_hf_felica_write_without_encryption() { + PrintAndLogEx(NORMAL, "\nInfo: Use this command to write Block Data to authentication-not-required Service."); + PrintAndLogEx(NORMAL, " - Mode shall be Mode0."); + print_number_of_service_constraints(); + print_number_of_block_constraints(); + print_service_code_list_constraints(); + print_block_list_element_constraints(); + PrintAndLogEx(NORMAL, " - Un-/Successful read: Card responses with Status Flag1 and Flag2"); + print_status_flag1_interpretation(); + print_status_flag2_interpration(); + PrintAndLogEx(NORMAL, "\nUsage: hf felica wrunencrypted [-h] <01 Number of Service hex> <0A0B Service Code List (Little Endian) hex> <01 Number of Block hex> <0A0B Block List Element hex> <0A0B0C0D0E0F... Data hex (16-Byte)>"); + PrintAndLogEx(NORMAL, " -h this help"); + PrintAndLogEx(NORMAL, " -i <0A0B0C ... hex> set custom IDm to use"); + + + PrintAndLogEx(NORMAL, "\nExamples: "); + PrintAndLogEx(NORMAL, " hf felica wrunencrypted"); + return PM3_SUCCESS; +} + /** * Wait for response from pm3 or timeout. * Checks if receveid bytes have a valid CRC. @@ -208,6 +244,10 @@ static bool waitCmdFelica(uint8_t iSelect, PacketResponseNG *resp, bool verbose) if (!check_crc(CRC_FELICA, resp->data.asBytes + 2, len - 2)) { PrintAndLogEx(WARNING, "Wrong or no CRC bytes"); } + if(resp->data.asBytes[0] != 0xB2 && resp->data.asBytes[1] != 0x4D){ + PrintAndLogEx(ERR, "Received incorrect Frame Format!"); + return false; + } } return true; } else { @@ -351,7 +391,7 @@ int send_request_service(uint8_t flags, uint16_t datalen, uint8_t *data, bool ve * @param datalen frame length. * @param data frame to be send. * @param verbose display additional output. - * @param rd_noCry_resp frame in which the response will be saved + * @param rd_noCry_resp frame in which the response will be saved. * @return success if response was received. */ int send_rd_unencrypted(uint8_t flags, uint16_t datalen, uint8_t *data, bool verbose, felica_read_without_encryption_response_t *rd_noCry_resp) { @@ -367,6 +407,19 @@ int send_rd_unencrypted(uint8_t flags, uint16_t datalen, uint8_t *data, bool ver } } +/** + * Command parser for wrunencrypted. + * @param Cmd input data of the user. + * @return client result code. + */ +static int CmdHFFelicaWriteWithoutEncryption(const char *Cmd) { + if (strlen(Cmd) < 4) + return usage_hf_felica_write_without_encryption(); + //uint8_t data[PM3_CMD_DATA_SIZE]; + + return PM3_SUCCESS; +} + /** * Command parser for rdunencrypted. * @param Cmd input data of the user. @@ -462,10 +515,12 @@ static int CmdHFFelicaReadWithoutEncryption(const char *Cmd) { AddCrc(data, datalen); datalen += 2; felica_read_without_encryption_response_t rd_noCry_resp; - send_rd_unencrypted(flags, datalen, data, 1, &rd_noCry_resp); - PrintAndLogEx(NORMAL, "Block Element\t| Data "); - print_rd_noEncrpytion_response(&rd_noCry_resp); + if(send_rd_unencrypted(flags, datalen, data, 1, &rd_noCry_resp) == PM3_SUCCESS){ + PrintAndLogEx(NORMAL, "Block Element\t| Data "); + print_rd_noEncrpytion_response(&rd_noCry_resp); + } } + return PM3_SUCCESS; } @@ -1139,27 +1194,27 @@ static command_t CommandTable[] = { {"reader", CmdHFFelicaReader, IfPm3Felica, "Act like an ISO18092/FeliCa reader"}, {"sniff", CmdHFFelicaSniff, IfPm3Felica, "Sniff ISO 18092/FeliCa traffic"}, {"raw", CmdHFFelicaCmdRaw, IfPm3Felica, "Send raw hex data to tag"}, - {"----------- FeliCa Standard (support in progress) -----------", CmdHelp, IfPm3Iso14443a, ""}, - //{"dump", CmdHFFelicaDump, IfPm3Felica, "Wait for and try dumping FeliCa"}, - {"rqservice", CmdHFFelicaRequestService, IfPm3Felica, "verify the existence of Area and Service, and to acquire Key Version."}, - {"rqresponse", CmdHFFelicaRequestResponse, IfPm3Felica, "verify the existence of a card and its Mode."}, - {"rdunencrypted", CmdHFFelicaReadWithoutEncryption, IfPm3Felica, "read Block Data from authentication-not-required Service."}, - {"wrunencrypted", CmdHFFelicaNotImplementedYet, IfPm3Felica, "write Block Data to an authentication-not-required Service."}, - //{"scsvcode", CmdHFFelicaNotImplementedYet, IfPm3Felica, "acquire Area Code and Service Code."}, - //{"rqsyscode", CmdHFFelicaNotImplementedYet, IfPm3Felica, "acquire System Code registered to the card."}, - //{"auth1", CmdHFFelicaNotImplementedYet, IfPm3Felica, "authenticate a card."}, - //{"auth2", CmdHFFelicaNotImplementedYet, IfPm3Felica, "allow a card to authenticate a Reader/Writer."}, - //{"read", CmdHFFelicaNotImplementedYet, IfPm3Felica, "read Block Data from authentication-required Service."}, - //{"write", CmdHFFelicaNotImplementedYet, IfPm3Felica, "write Block Data to an authentication-required Service."}, - //{"scsvcodev2", CmdHFFelicaNotImplementedYet, IfPm3Felica, "verify the existence of Area or Service, and to acquire Key Version."}, - //{"getsysstatus", CmdHFFelicaNotImplementedYet, IfPm3Felica, "acquire the setup information in System."}, - //{"rqspecver", CmdHFFelicaNotImplementedYet, IfPm3Felica, "acquire the version of card OS."}, - //{"resetmode", CmdHFFelicaNotImplementedYet, IfPm3Felica, "reset Mode to Mode 0."}, - //{"auth1v2", CmdHFFelicaNotImplementedYet, IfPm3Felica, "authenticate a card."}, - //{"auth2v2", CmdHFFelicaNotImplementedYet, IfPm3Felica, "allow a card to authenticate a Reader/Writer."}, - //{"readv2", CmdHFFelicaNotImplementedYet, IfPm3Felica, "read Block Data from authentication-required Service."}, - //{"writev2", CmdHFFelicaNotImplementedYet, IfPm3Felica, "write Block Data to authentication-required Service."}, - //{"uprandomid", CmdHFFelicaNotImplementedYet, IfPm3Felica, "update Random ID (IDr)."}, + {"----------- FeliCa Standard (support in progress) -----------", CmdHelp, IfPm3Iso14443a, ""}, + //{"dump", CmdHFFelicaDump, IfPm3Felica, "Wait for and try dumping FeliCa"}, + {"rqservice", CmdHFFelicaRequestService, IfPm3Felica, "verify the existence of Area and Service, and to acquire Key Version."}, + {"rqresponse", CmdHFFelicaRequestResponse, IfPm3Felica, "verify the existence of a card and its Mode."}, + {"rdunencrypted", CmdHFFelicaReadWithoutEncryption, IfPm3Felica, "read Block Data from authentication-not-required Service."}, + {"wrunencrypted", CmdHFFelicaWriteWithoutEncryption, IfPm3Felica, "write Block Data to an authentication-not-required Service."}, + {"scsvcode", CmdHFFelicaNotImplementedYet, IfPm3Felica, "acquire Area Code and Service Code."}, + //{"rqsyscode", CmdHFFelicaNotImplementedYet, IfPm3Felica, "acquire System Code registered to the card."}, + //{"auth1", CmdHFFelicaNotImplementedYet, IfPm3Felica, "authenticate a card."}, + //{"auth2", CmdHFFelicaNotImplementedYet, IfPm3Felica, "allow a card to authenticate a Reader/Writer."}, + //{"read", CmdHFFelicaNotImplementedYet, IfPm3Felica, "read Block Data from authentication-required Service."}, + //{"write", CmdHFFelicaNotImplementedYet, IfPm3Felica, "write Block Data to an authentication-required Service."}, + //{"scsvcodev2", CmdHFFelicaNotImplementedYet, IfPm3Felica, "verify the existence of Area or Service, and to acquire Key Version."}, + //{"getsysstatus", CmdHFFelicaNotImplementedYet, IfPm3Felica, "acquire the setup information in System."}, + //{"rqspecver", CmdHFFelicaNotImplementedYet, IfPm3Felica, "acquire the version of card OS."}, + //{"resetmode", CmdHFFelicaNotImplementedYet, IfPm3Felica, "reset Mode to Mode 0."}, + //{"auth1v2", CmdHFFelicaNotImplementedYet, IfPm3Felica, "authenticate a card."}, + //{"auth2v2", CmdHFFelicaNotImplementedYet, IfPm3Felica, "allow a card to authenticate a Reader/Writer."}, + //{"readv2", CmdHFFelicaNotImplementedYet, IfPm3Felica, "read Block Data from authentication-required Service."}, + //{"writev2", CmdHFFelicaNotImplementedYet, IfPm3Felica, "write Block Data to authentication-required Service."}, + //{"uprandomid", CmdHFFelicaNotImplementedYet, IfPm3Felica, "update Random ID (IDr)."}, {"----------- FeliCa Light -----------", CmdHelp, IfPm3Iso14443a, ""}, {"litesim", CmdHFFelicaSimLite, IfPm3Felica, " - only reply to poll request"}, {"litedump", CmdHFFelicaDumpLite, IfPm3Felica, "Wait for and try dumping FelicaLite"}, From 06f3f1b637015275d5d68750a60fa542b62512b0 Mon Sep 17 00:00:00 2001 From: Thomas Sutter Date: Tue, 29 Oct 2019 10:00:47 +0100 Subject: [PATCH 1081/1854] Remove code duplication. --- client/cmdhffelica.c | 77 +++++++++++++++++++++++++++++++------------- 1 file changed, 54 insertions(+), 23 deletions(-) diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index ead19c104..18a992ba7 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -407,15 +407,61 @@ int send_rd_unencrypted(uint8_t flags, uint16_t datalen, uint8_t *data, bool ver } } +/** + * Checks if last known card can be added to data and adds it if possible. + * @param custom_IDm + * @param data + * @return + */ +static bool check_last_idm(uint8_t *data, uint16_t datalen){ + if (!add_last_IDm(2, data)) { + PrintAndLogEx(ERR, "No last known card! Use reader first or set a custom IDm!"); + return 0; + } else { + PrintAndLogEx(INFO, "Used last known IDm.", sprint_hex(data, datalen)); + return 1; + } +} + /** * Command parser for wrunencrypted. * @param Cmd input data of the user. * @return client result code. */ static int CmdHFFelicaWriteWithoutEncryption(const char *Cmd) { - if (strlen(Cmd) < 4) + if (strlen(Cmd) < 5) return usage_hf_felica_write_without_encryption(); - //uint8_t data[PM3_CMD_DATA_SIZE]; + uint8_t data[PM3_CMD_DATA_SIZE]; + bool custom_IDm = false; + strip_cmds(Cmd); + uint16_t datalen = 32; // Length (1), Command ID (1), IDm (8), Number of Service (1), Service Code List(2), Number of Block(1), Block List(3), Block Data(16) + uint8_t paramCount = 0; + uint8_t flags = 0; + int i = 0; + while (Cmd[i] != '\0') { + if (Cmd[i] == '-') { + switch (Cmd[i + 1]) { + case 'H': + case 'h': + return usage_hf_felica_request_response(); + case 'i': + paramCount++; + custom_IDm = true; + if (!add_param(Cmd, paramCount, data, 3, 8)) { + return PM3_EINVARG; + } + break; + } + } + i++; + } + data[0] = 0x20; // Static length + data[1] = 0x08; // Command ID + if (!custom_IDm && !check_last_idm(data, datalen)) { + return PM3_EINVARG; + } + flags |= FELICA_APPEND_CRC; + flags |= FELICA_RAW; return PM3_SUCCESS; } @@ -464,13 +510,8 @@ static int CmdHFFelicaReadWithoutEncryption(const char *Cmd) { } data[0] = 0x10; // Static length data[1] = 0x06; // Command ID - if (!custom_IDm) { - if (!add_last_IDm(2, data)) { - PrintAndLogEx(ERR, "No last known card! Use reader first or set a custom IDm!"); - return PM3_EINVARG; - } else { - PrintAndLogEx(INFO, "Used last known IDm.", sprint_hex(data, datalen)); - } + if (!custom_IDm && !check_last_idm(data, datalen)) { + return PM3_EINVARG; } // Number of Service 2, Service Code List 4, Number of Block 2, Block List Element 4 uint8_t lengths[] = {2, 4, 2, 4}; @@ -559,13 +600,8 @@ static int CmdHFFelicaRequestResponse(const char *Cmd) { } data[0] = 0x0A; // Static length data[1] = 0x04; // Command ID - if (!custom_IDm) { - if (!add_last_IDm(2, data)) { - PrintAndLogEx(ERR, "No last known card! Use reader first or set a custom IDm!"); - return PM3_EINVARG; - } else { - PrintAndLogEx(INFO, "Used last known IDm.", sprint_hex(data, datalen)); - } + if (!custom_IDm && !check_last_idm(data, datalen)) { + return PM3_EINVARG; } AddCrc(data, datalen); datalen += 2; @@ -658,13 +694,8 @@ static int CmdHFFelicaRequestService(const char *Cmd) { flags |= FELICA_RAW; } datalen = (datalen > PM3_CMD_DATA_SIZE) ? PM3_CMD_DATA_SIZE : datalen; - if (!custom_IDm) { - if (!add_last_IDm(2, data)) { - PrintAndLogEx(ERR, "No last known card! Use reader first or set a custom IDm!"); - return PM3_EINVARG; - } else { - PrintAndLogEx(INFO, "Used last known IDm.", sprint_hex(data, datalen)); - } + if (!custom_IDm && !check_last_idm(data, datalen)) { + return PM3_EINVARG; } data[0] = int_to_hex(&datalen); data[1] = 0x02; // Service Request Command ID From 498c4b83776cbb777f3f58815241e1f2350b0cda Mon Sep 17 00:00:00 2001 From: Thomas Sutter Date: Tue, 29 Oct 2019 10:22:47 +0100 Subject: [PATCH 1082/1854] Refactor FeliCa structs. --- armsrc/felica.h | 2 -- client/cmdhffelica.c | 33 ++++++++++++++++++++++++--------- client/cmdhffelica.h | 1 + include/mifare.h | 22 ++++++++++++---------- 4 files changed, 37 insertions(+), 21 deletions(-) diff --git a/armsrc/felica.h b/armsrc/felica.h index 95e13a588..ef34dc108 100644 --- a/armsrc/felica.h +++ b/armsrc/felica.h @@ -18,7 +18,5 @@ void felica_sendraw(PacketCommandNG *c); void felica_sniff(uint32_t samplesToSkip, uint32_t triggersToSkip); void felica_sim_lite(uint64_t uid); void felica_dump_lite_s(); -void felica_create_read_block_frame(uint16_t blockNr); -void felica_send_request_service(uint8_t *request_service); #endif diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index 18a992ba7..74fea45bb 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -344,7 +344,7 @@ static bool add_param(const char *Cmd, uint8_t paramCount, uint8_t *data, uint8_ * @param rd_noCry_resp Response frame. */ static void print_rd_noEncrpytion_response(felica_read_without_encryption_response_t *rd_noCry_resp) { - if (rd_noCry_resp->status_flag1[0] == 00 && rd_noCry_resp->status_flag2[0] == 00) { + if (rd_noCry_resp->status_flags.status_flag1[0] == 00 && rd_noCry_resp->status_flags.status_flag2[0] == 00) { char *temp = sprint_hex(rd_noCry_resp->block_data, sizeof(rd_noCry_resp->block_data)); char bl_data[256]; strcpy(bl_data, temp); @@ -354,9 +354,9 @@ static void print_rd_noEncrpytion_response(felica_read_without_encryption_respon strcpy(bl_element_number, temp); PrintAndLogEx(NORMAL, "\t%s\t| %s ", bl_element_number, bl_data); } else { - PrintAndLogEx(NORMAL, "IDm: %s", sprint_hex(rd_noCry_resp->IDm, sizeof(rd_noCry_resp->IDm))); - PrintAndLogEx(NORMAL, "Status Flag1: %s", sprint_hex(rd_noCry_resp->status_flag1, sizeof(rd_noCry_resp->status_flag1))); - PrintAndLogEx(NORMAL, "Status Flag2: %s", sprint_hex(rd_noCry_resp->status_flag1, sizeof(rd_noCry_resp->status_flag1))); + PrintAndLogEx(NORMAL, "IDm: %s", sprint_hex(rd_noCry_resp->frame_response.IDm, sizeof(rd_noCry_resp->frame_response.IDm))); + PrintAndLogEx(NORMAL, "Status Flag1: %s", sprint_hex(rd_noCry_resp->status_flags.status_flag1, sizeof(rd_noCry_resp->status_flags.status_flag1))); + PrintAndLogEx(NORMAL, "Status Flag2: %s", sprint_hex(rd_noCry_resp->status_flags.status_flag1, sizeof(rd_noCry_resp->status_flags.status_flag1))); } } @@ -374,9 +374,9 @@ int send_request_service(uint8_t flags, uint16_t datalen, uint8_t *data, bool ve felica_request_service_response_t rqs_response; memcpy(&rqs_response, (felica_request_service_response_t *)resp.data.asBytes, sizeof(felica_request_service_response_t)); - if (rqs_response.IDm[0] != 0) { + if (rqs_response.frame_response.IDm[0] != 0) { PrintAndLogEx(SUCCESS, "\nGot Service Response:"); - PrintAndLogEx(NORMAL, "IDm: %s", sprint_hex(rqs_response.IDm, sizeof(rqs_response.IDm))); + PrintAndLogEx(NORMAL, "IDm: %s", sprint_hex(rqs_response.frame_response.IDm, sizeof(rqs_response.frame_response.IDm))); PrintAndLogEx(NORMAL, " -Node Number: %s", sprint_hex(rqs_response.node_number, sizeof(rqs_response.node_number))); PrintAndLogEx(NORMAL, " -Node Key Version List: %s\n", sprint_hex(rqs_response.node_key_versions, sizeof(rqs_response.node_key_versions))); } @@ -423,6 +423,10 @@ static bool check_last_idm(uint8_t *data, uint16_t datalen){ } } + + + + /** * Command parser for wrunencrypted. * @param Cmd input data of the user. @@ -460,9 +464,20 @@ static int CmdHFFelicaWriteWithoutEncryption(const char *Cmd) { if (!custom_IDm && !check_last_idm(data, datalen)) { return PM3_EINVARG; } + // Number of Service 2, Service Code List 4, Number of Block 2, Block List Element 4 + uint8_t lengths[] = {2, 4, 2, 4}; + uint8_t dataPositions[] = {10, 11, 13, 14}; + for (int i = 0; i < 4; i++) { + if (add_param(Cmd, paramCount, data, dataPositions[i], lengths[i])) { + paramCount++; + } else { + return PM3_EINVARG; + } + } flags |= FELICA_APPEND_CRC; flags |= FELICA_RAW; + return PM3_SUCCESS; } @@ -542,7 +557,7 @@ static int CmdHFFelicaReadWithoutEncryption(const char *Cmd) { datalen += 2; felica_read_without_encryption_response_t rd_noCry_resp; if ((send_rd_unencrypted(flags, datalen, data, 0, &rd_noCry_resp) == PM3_SUCCESS)) { - if (rd_noCry_resp.status_flag1[0] == 00 && rd_noCry_resp.status_flag2[0] == 00) { + if (rd_noCry_resp.status_flags.status_flag1[0] == 00 && rd_noCry_resp.status_flags.status_flag2[0] == 00) { print_rd_noEncrpytion_response(&rd_noCry_resp); } else { break; @@ -615,9 +630,9 @@ static int CmdHFFelicaRequestResponse(const char *Cmd) { } else { felica_request_request_response_t rq_response; memcpy(&rq_response, (felica_request_request_response_t *)resp.data.asBytes, sizeof(felica_request_request_response_t)); - if (rq_response.IDm[0] != 0) { + if (rq_response.frame_response.IDm[0] != 0) { PrintAndLogEx(SUCCESS, "\nGot Request Response:"); - PrintAndLogEx(NORMAL, "IDm: %s", sprint_hex(rq_response.IDm, sizeof(rq_response.IDm))); + PrintAndLogEx(NORMAL, "IDm: %s", sprint_hex(rq_response.frame_response.IDm, sizeof(rq_response.frame_response.IDm))); PrintAndLogEx(NORMAL, " -Mode: %s\n\n", sprint_hex(rq_response.mode, sizeof(rq_response.mode))); } } diff --git a/client/cmdhffelica.h b/client/cmdhffelica.h index 7626d002b..8d8156006 100644 --- a/client/cmdhffelica.h +++ b/client/cmdhffelica.h @@ -18,4 +18,5 @@ int CmdHFFelica(const char *Cmd); int readFelicaUid(bool verbose); int send_request_service(uint8_t flags, uint16_t datalen, uint8_t *data, bool verbose); int send_rd_unencrypted(uint8_t flags, uint16_t datalen, uint8_t *data, bool verbose, felica_read_without_encryption_response_t *rd_noCry_resp); + #endif diff --git a/include/mifare.h b/include/mifare.h index 7a40a26e4..699c7e1ec 100644 --- a/include/mifare.h +++ b/include/mifare.h @@ -174,25 +174,27 @@ typedef struct { uint8_t length[1]; uint8_t cmd_code[1]; uint8_t IDm[8]; +} PACKED felica_frame_response_t; + +typedef struct { + uint8_t status_flag1[1]; + uint8_t status_flag2[1]; +} PACKED felica_status_flag_response_t; + +typedef struct { + felica_frame_response_t frame_response; uint8_t node_number[1]; uint8_t node_key_versions[2]; } PACKED felica_request_service_response_t; typedef struct { - uint8_t sync[2]; - uint8_t length[1]; - uint8_t cmd_code[1]; - uint8_t IDm[8]; + felica_frame_response_t frame_response; uint8_t mode[1]; } PACKED felica_request_request_response_t; typedef struct { - uint8_t sync[2]; - uint8_t length[1]; - uint8_t cmd_code[1]; - uint8_t IDm[8]; - uint8_t status_flag1[1]; - uint8_t status_flag2[1]; + felica_frame_response_t frame_response; + felica_status_flag_response_t status_flags; uint8_t number_of_block[1]; uint8_t block_data[16]; uint8_t block_element_number[1]; From 2e60cb4fa632bea48bb0a1902ac57817cb9cbf53 Mon Sep 17 00:00:00 2001 From: Thomas Sutter Date: Tue, 29 Oct 2019 11:14:38 +0100 Subject: [PATCH 1083/1854] Add write without encryption command. --- client/cmdhffelica.c | 50 +++++++++++++++++++++++++++++++------------- include/mifare.h | 9 ++++++-- 2 files changed, 43 insertions(+), 16 deletions(-) diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index 74fea45bb..c47622951 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -203,7 +203,7 @@ static int usage_hf_felica_read_without_encryption() { PrintAndLogEx(NORMAL, "\nExamples: "); PrintAndLogEx(NORMAL, " hf felica rdunencrypted 01 8B00 01 8000"); PrintAndLogEx(NORMAL, " hf felica rdunencrypted -i 01100910c11bc407 01 8B00 01 8000"); - PrintAndLogEx(NORMAL, " hf felica rdunencrypted -b 01 8B00 01 8000\n\n"); + PrintAndLogEx(NORMAL, " hf felica rdunencrypted -b 01 4B18 01 8000\n\n"); return PM3_SUCCESS; } @@ -219,11 +219,11 @@ static int usage_hf_felica_write_without_encryption() { print_status_flag2_interpration(); PrintAndLogEx(NORMAL, "\nUsage: hf felica wrunencrypted [-h] <01 Number of Service hex> <0A0B Service Code List (Little Endian) hex> <01 Number of Block hex> <0A0B Block List Element hex> <0A0B0C0D0E0F... Data hex (16-Byte)>"); PrintAndLogEx(NORMAL, " -h this help"); - PrintAndLogEx(NORMAL, " -i <0A0B0C ... hex> set custom IDm to use"); - + PrintAndLogEx(NORMAL, " -i <0A0B0C ... hex> set custom IDm to use\n"); + PrintAndLogEx(NORMAL, " hf felica wrunencrypted 01 CB10 01 8001 0102030405060708090A0B0C0D0E0F10\n\n"); PrintAndLogEx(NORMAL, "\nExamples: "); - PrintAndLogEx(NORMAL, " hf felica wrunencrypted"); + PrintAndLogEx(NORMAL, " hf felica wrunencrypted "); return PM3_SUCCESS; } @@ -423,9 +423,26 @@ static bool check_last_idm(uint8_t *data, uint16_t datalen){ } } - - - +/** + * Sends a read_without_encryption frame to the pm3 and prints response. + * @param flags to use for pm3 communication. + * @param datalen frame length. + * @param data frame to be send. + * @param verbose display additional output. + * @param wr_noCry_resp frame in which the response will be saved. + * @return success if response was received. + */ +int send_wr_unencrypted(uint8_t flags, uint16_t datalen, uint8_t *data, bool verbose, felica_status_response_t *wr_noCry_resp) { + clear_and_send_command(flags, datalen, data, verbose); + PacketResponseNG resp; + if (!waitCmdFelica(0, &resp, verbose)) { + PrintAndLogEx(ERR, "\nGot no Response from card"); + return PM3_ERFTRANS; + } else { + memcpy(wr_noCry_resp, (felica_status_response_t *)resp.data.asBytes, sizeof(felica_status_response_t)); + return PM3_SUCCESS; + } +} /** * Command parser for wrunencrypted. @@ -464,10 +481,10 @@ static int CmdHFFelicaWriteWithoutEncryption(const char *Cmd) { if (!custom_IDm && !check_last_idm(data, datalen)) { return PM3_EINVARG; } - // Number of Service 2, Service Code List 4, Number of Block 2, Block List Element 4 - uint8_t lengths[] = {2, 4, 2, 4}; - uint8_t dataPositions[] = {10, 11, 13, 14}; - for (int i = 0; i < 4; i++) { + // Number of Service 2, Service Code List 4, Number of Block 2, Block List Element 4, Data 16 + uint8_t lengths[] = {2, 4, 2, 4, 32}; + uint8_t dataPositions[] = {10, 11, 13, 14, 16}; + for (int i = 0; i < 5; i++) { if (add_param(Cmd, paramCount, data, dataPositions[i], lengths[i])) { paramCount++; } else { @@ -476,8 +493,14 @@ static int CmdHFFelicaWriteWithoutEncryption(const char *Cmd) { } flags |= FELICA_APPEND_CRC; flags |= FELICA_RAW; - - + AddCrc(data, datalen); + datalen += 2; + felica_status_response_t wr_noCry_resp; + if(send_wr_unencrypted(flags, datalen, data, 1, &wr_noCry_resp) == PM3_SUCCESS){ + PrintAndLogEx(NORMAL, "\nIDm: %s", sprint_hex(wr_noCry_resp.frame_response.IDm, sizeof(wr_noCry_resp.frame_response.IDm))); + PrintAndLogEx(NORMAL, "Status Flag1: %s", sprint_hex(wr_noCry_resp.status_flags.status_flag1, sizeof(wr_noCry_resp.status_flags.status_flag1))); + PrintAndLogEx(NORMAL, "Status Flag2: %s\n\n", sprint_hex(wr_noCry_resp.status_flags.status_flag2, sizeof(wr_noCry_resp.status_flags.status_flag2))); + } return PM3_SUCCESS; } @@ -576,7 +599,6 @@ static int CmdHFFelicaReadWithoutEncryption(const char *Cmd) { print_rd_noEncrpytion_response(&rd_noCry_resp); } } - return PM3_SUCCESS; } diff --git a/include/mifare.h b/include/mifare.h index 699c7e1ec..4a65357e5 100644 --- a/include/mifare.h +++ b/include/mifare.h @@ -179,7 +179,7 @@ typedef struct { typedef struct { uint8_t status_flag1[1]; uint8_t status_flag2[1]; -} PACKED felica_status_flag_response_t; +} PACKED felica_status_flags_t; typedef struct { felica_frame_response_t frame_response; @@ -194,12 +194,17 @@ typedef struct { typedef struct { felica_frame_response_t frame_response; - felica_status_flag_response_t status_flags; + felica_status_flags_t status_flags; uint8_t number_of_block[1]; uint8_t block_data[16]; uint8_t block_element_number[1]; } PACKED felica_read_without_encryption_response_t; +typedef struct { + felica_frame_response_t frame_response; + felica_status_flags_t status_flags; +} PACKED felica_status_response_t; + typedef enum FELICA_COMMAND { FELICA_CONNECT = (1 << 0), FELICA_NO_DISCONNECT = (1 << 1), From 83c629cbecef5cfb66e5bcd198b4bb5d26e90875 Mon Sep 17 00:00:00 2001 From: Thomas Sutter Date: Tue, 29 Oct 2019 12:52:45 +0100 Subject: [PATCH 1084/1854] Fix parameter i parsing bug. --- client/cmdhffelica.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index c47622951..2ed405476 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -112,6 +112,7 @@ static int usage_hf_felica_request_response(void) { PrintAndLogEx(NORMAL, "\nUsage: hf felica rqresponse [-h]"); PrintAndLogEx(NORMAL, " -h this help"); PrintAndLogEx(NORMAL, " -i <0A0B0C ... hex> set custom IDm to use"); + PrintAndLogEx(NORMAL, " hf felica rqresponse -i 01100910c11bc407"); return PM3_SUCCESS; } @@ -334,7 +335,8 @@ static bool add_param(const char *Cmd, uint8_t paramCount, uint8_t *data, uint8_ param_gethex(Cmd, paramCount, data + dataPosition, length); return true; } else { - PrintAndLogEx(ERR, "Incorrect Parameter length! Param %i", paramCount); + PrintAndLogEx(ERR, "Param %s", Cmd); + PrintAndLogEx(ERR, "Incorrect Parameter length! Param %i should be %i", paramCount, length); return false; } } @@ -468,9 +470,11 @@ static int CmdHFFelicaWriteWithoutEncryption(const char *Cmd) { case 'i': paramCount++; custom_IDm = true; - if (!add_param(Cmd, paramCount, data, 3, 8)) { + if (!add_param(Cmd, paramCount, data, 2, 16)) { return PM3_EINVARG; } + paramCount++; + i += 16; break; } } @@ -530,9 +534,11 @@ static int CmdHFFelicaReadWithoutEncryption(const char *Cmd) { case 'i': paramCount++; custom_IDm = true; - if (!add_param(Cmd, paramCount, data, 3, 8)) { + if (!add_param(Cmd, paramCount, data, 2, 16)) { return PM3_EINVARG; } + paramCount++; + i += 16; break; case 'b': paramCount++; @@ -624,12 +630,11 @@ static int CmdHFFelicaRequestResponse(const char *Cmd) { case 'i': paramCount++; custom_IDm = true; - if (param_getlength(Cmd, paramCount) == 16) { - param_gethex(Cmd, paramCount++, data + 2, 16); - } else { - PrintAndLogEx(ERR, "Incorrect IDm length! IDm must be 8-Byte."); + if (!add_param(Cmd, paramCount, data, 2, 16)) { return PM3_EINVARG; } + paramCount++; + i+=16; break; } } @@ -686,13 +691,11 @@ static int CmdHFFelicaRequestService(const char *Cmd) { case 'i': paramCount++; custom_IDm = true; - if (param_getlength(Cmd, paramCount) == 16) { - param_gethex(Cmd, paramCount++, data + 2, 16); - } else { - PrintAndLogEx(ERR, "Incorrect IDm length! IDm must be 8-Byte."); + if (!add_param(Cmd, paramCount, data, 2, 16)) { return PM3_EINVARG; } - i += 8; + paramCount++; + i += 16; break; case 'a': paramCount++; From eba19c0bd67cd4789e9952db6875ef0cbf68b1ee Mon Sep 17 00:00:00 2001 From: Thomas Sutter Date: Tue, 29 Oct 2019 13:35:09 +0100 Subject: [PATCH 1085/1854] Make style. --- armsrc/appmain.c | 4 ++-- client/cmdhffelica.c | 27 ++++++++++++++++----------- client/proxmark3.c | 2 +- 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index dcb7d63a0..5011c1979 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1589,10 +1589,10 @@ static void PacketReceived(PacketCommandNG *packet) { BigBuf_free(); } uint16_t offset = MIN(BIGBUF_SIZE - PM3_CMD_DATA_SIZE - 3, payload->offset); - + // need to copy len bytes of data, not PM3_CMD_DATA_SIZE - 3 - offset // ensure len bytes copied wont go past end of bigbuf - uint16_t len = MIN(BIGBUF_SIZE - offset,PM3_CMD_DATA_SIZE - 3); + uint16_t len = MIN(BIGBUF_SIZE - offset, PM3_CMD_DATA_SIZE - 3); uint8_t *mem = BigBuf_get_addr(); memcpy(mem + offset, &payload->data, len); diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index 2ed405476..2afb5f3aa 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -160,7 +160,7 @@ static void print_status_flag2_interpration() { PrintAndLogEx(NORMAL, " - C2h : Command is disabled already: This is the error that occurs in issuance commands."); } -static void print_block_list_element_constraints(){ +static void print_block_list_element_constraints() { PrintAndLogEx(NORMAL, " - Each Block List Element shall satisfy the following conditions:"); PrintAndLogEx(NORMAL, " - The value of Service Code List Order shall not exceed Number of Service."); PrintAndLogEx(NORMAL, " - Access Mode shall be 000b."); @@ -170,16 +170,16 @@ static void print_block_list_element_constraints(){ PrintAndLogEx(NORMAL, " - Block Number shall be in the range of the number of Blocks assigned to the specified Service."); } -static void print_number_of_service_constraints(){ +static void print_number_of_service_constraints() { PrintAndLogEx(NORMAL, " - Number of Service: shall be a positive integer in the range of 1 to 16, inclusive."); } -static void print_number_of_block_constraints(){ +static void print_number_of_block_constraints() { PrintAndLogEx(NORMAL, " - Number of Block: shall be less than or equal to the maximum number of Blocks that can be read simultaneously. " - "The maximum number of Blocks that can be read simultaneously can differ, depending on the product being used. Use as default 01"); + "The maximum number of Blocks that can be read simultaneously can differ, depending on the product being used. Use as default 01"); } -static void print_service_code_list_constraints(){ +static void print_service_code_list_constraints() { PrintAndLogEx(NORMAL, " - Service Code List: For Service Code List, only Service Code existing in the product shall be specified:"); PrintAndLogEx(NORMAL, " - Even when Service Code exists in the product, Service Code not referenced from Block List shall not be specified to Service Code List."); PrintAndLogEx(NORMAL, " - For existence or nonexistence of Service in a product, please check using the Request Service (or Request Service v2) command."); @@ -245,7 +245,7 @@ static bool waitCmdFelica(uint8_t iSelect, PacketResponseNG *resp, bool verbose) if (!check_crc(CRC_FELICA, resp->data.asBytes + 2, len - 2)) { PrintAndLogEx(WARNING, "Wrong or no CRC bytes"); } - if(resp->data.asBytes[0] != 0xB2 && resp->data.asBytes[1] != 0x4D){ + if (resp->data.asBytes[0] != 0xB2 && resp->data.asBytes[1] != 0x4D) { PrintAndLogEx(ERR, "Received incorrect Frame Format!"); return false; } @@ -415,7 +415,7 @@ int send_rd_unencrypted(uint8_t flags, uint16_t datalen, uint8_t *data, bool ver * @param data * @return */ -static bool check_last_idm(uint8_t *data, uint16_t datalen){ +static bool check_last_idm(uint8_t *data, uint16_t datalen) { if (!add_last_IDm(2, data)) { PrintAndLogEx(ERR, "No last known card! Use reader first or set a custom IDm!"); return 0; @@ -500,10 +500,15 @@ static int CmdHFFelicaWriteWithoutEncryption(const char *Cmd) { AddCrc(data, datalen); datalen += 2; felica_status_response_t wr_noCry_resp; - if(send_wr_unencrypted(flags, datalen, data, 1, &wr_noCry_resp) == PM3_SUCCESS){ + if (send_wr_unencrypted(flags, datalen, data, 1, &wr_noCry_resp) == PM3_SUCCESS) { PrintAndLogEx(NORMAL, "\nIDm: %s", sprint_hex(wr_noCry_resp.frame_response.IDm, sizeof(wr_noCry_resp.frame_response.IDm))); PrintAndLogEx(NORMAL, "Status Flag1: %s", sprint_hex(wr_noCry_resp.status_flags.status_flag1, sizeof(wr_noCry_resp.status_flags.status_flag1))); - PrintAndLogEx(NORMAL, "Status Flag2: %s\n\n", sprint_hex(wr_noCry_resp.status_flags.status_flag2, sizeof(wr_noCry_resp.status_flags.status_flag2))); + PrintAndLogEx(NORMAL, "Status Flag2: %s\n", sprint_hex(wr_noCry_resp.status_flags.status_flag2, sizeof(wr_noCry_resp.status_flags.status_flag2))); + if (wr_noCry_resp.status_flags.status_flag1[0] == 0x00 && wr_noCry_resp.status_flags.status_flag2[0] == 0x00) { + PrintAndLogEx(SUCCESS, "Writing data successful!\n"); + } else { + PrintAndLogEx(ERR, "Something went wrong! Check status flags.\n"); + } } return PM3_SUCCESS; } @@ -600,7 +605,7 @@ static int CmdHFFelicaReadWithoutEncryption(const char *Cmd) { AddCrc(data, datalen); datalen += 2; felica_read_without_encryption_response_t rd_noCry_resp; - if(send_rd_unencrypted(flags, datalen, data, 1, &rd_noCry_resp) == PM3_SUCCESS){ + if (send_rd_unencrypted(flags, datalen, data, 1, &rd_noCry_resp) == PM3_SUCCESS) { PrintAndLogEx(NORMAL, "Block Element\t| Data "); print_rd_noEncrpytion_response(&rd_noCry_resp); } @@ -634,7 +639,7 @@ static int CmdHFFelicaRequestResponse(const char *Cmd) { return PM3_EINVARG; } paramCount++; - i+=16; + i += 16; break; } } diff --git a/client/proxmark3.c b/client/proxmark3.c index c1d6a5dc7..bb291ee6c 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -482,7 +482,7 @@ static bool DetectWindowsAnsiSupport(void) { HKEY hKey = NULL; bool virtualTerminalLevelSet = false; bool forceV2Set = false; - + if (RegOpenKeyA(HKEY_CURRENT_USER, "Console", &hKey) == ERROR_SUCCESS) { DWORD dwType = REG_SZ; BYTE KeyValue[sizeof(dwType)]; From 76215fffc6028a762624619f7726a795498e01a8 Mon Sep 17 00:00:00 2001 From: Thomas Sutter Date: Tue, 29 Oct 2019 15:39:54 +0100 Subject: [PATCH 1086/1854] Refactor sniffing command. --- client/cmdhffelica.c | 100 ++++++++++++++++++++++++++++--------------- 1 file changed, 66 insertions(+), 34 deletions(-) diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index 2afb5f3aa..bcbda18e4 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -47,15 +47,18 @@ static int usage_hf_felica_sim(void) { */ static int usage_hf_felica_sniff(void) { - PrintAndLogEx(NORMAL, "It get data from the field and saves it into command buffer."); - PrintAndLogEx(NORMAL, "Buffer accessible from command 'hf list felica'"); - PrintAndLogEx(NORMAL, "Usage: hf felica sniff "); - PrintAndLogEx(NORMAL, " s samples to skip (decimal)"); - PrintAndLogEx(NORMAL, " t triggers to skip (decimal)"); + PrintAndLogEx(NORMAL, "\nInfo: It get data from the field and saves it into command buffer. "); + PrintAndLogEx(NORMAL, " Buffer accessible from command 'hf list felica'"); + PrintAndLogEx(NORMAL, "\nUsage: hf felica sniff [-h] [-s] [-t]"); + PrintAndLogEx(NORMAL, " -h this help"); + PrintAndLogEx(NORMAL, " -s samples to skip (decimal) max 9999"); + PrintAndLogEx(NORMAL, " -t triggers to skip (decimal) max 9999"); + PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf felica sniff s 1000"); + PrintAndLogEx(NORMAL, " hf felica sniff 10 10"); return PM3_SUCCESS; } + static int usage_hf_felica_simlite(void) { PrintAndLogEx(NORMAL, "\n Emulating ISO/18092 FeliCa Lite tag \n"); PrintAndLogEx(NORMAL, "Usage: hf felica litesim [h] u "); @@ -66,6 +69,7 @@ static int usage_hf_felica_simlite(void) { PrintAndLogEx(NORMAL, " hf felica litesim 11223344556677"); return PM3_SUCCESS; } + static int usage_hf_felica_dumplite(void) { PrintAndLogEx(NORMAL, "\n Dump ISO/18092 FeliCa Lite tag \n"); PrintAndLogEx(NORMAL, "press button to abort run, otherwise it will loop for 200sec."); @@ -76,6 +80,7 @@ static int usage_hf_felica_dumplite(void) { PrintAndLogEx(NORMAL, " hf felica litedump"); return PM3_SUCCESS; } + static int usage_hf_felica_raw(void) { PrintAndLogEx(NORMAL, "Usage: hf felica raw [-h] [-r] [-c] [-p] [-a] <0A 0B 0C ... hex>"); PrintAndLogEx(NORMAL, " -h this help"); @@ -221,8 +226,8 @@ static int usage_hf_felica_write_without_encryption() { PrintAndLogEx(NORMAL, "\nUsage: hf felica wrunencrypted [-h] <01 Number of Service hex> <0A0B Service Code List (Little Endian) hex> <01 Number of Block hex> <0A0B Block List Element hex> <0A0B0C0D0E0F... Data hex (16-Byte)>"); PrintAndLogEx(NORMAL, " -h this help"); PrintAndLogEx(NORMAL, " -i <0A0B0C ... hex> set custom IDm to use\n"); - PrintAndLogEx(NORMAL, " hf felica wrunencrypted 01 CB10 01 8001 0102030405060708090A0B0C0D0E0F10\n\n"); - + PrintAndLogEx(NORMAL, " hf felica wrunencrypted 01 CB10 01 8001 0102030405060708090A0B0C0D0E0F10"); + PrintAndLogEx(NORMAL, " hf felica wrunencrypted -i 11100910C11BC407 01 CB10 01 8001 0102030405060708090A0B0C0D0E0F10\n\n"); PrintAndLogEx(NORMAL, "\nExamples: "); PrintAndLogEx(NORMAL, " hf felica wrunencrypted "); return PM3_SUCCESS; @@ -466,7 +471,7 @@ static int CmdHFFelicaWriteWithoutEncryption(const char *Cmd) { switch (Cmd[i + 1]) { case 'H': case 'h': - return usage_hf_felica_request_response(); + return usage_hf_felica_write_without_encryption(); case 'i': paramCount++; custom_IDm = true; @@ -476,6 +481,8 @@ static int CmdHFFelicaWriteWithoutEncryption(const char *Cmd) { paramCount++; i += 16; break; + default: + return usage_hf_felica_write_without_encryption(); } } i++; @@ -535,7 +542,7 @@ static int CmdHFFelicaReadWithoutEncryption(const char *Cmd) { switch (Cmd[i + 1]) { case 'H': case 'h': - return usage_hf_felica_request_response(); + return usage_hf_felica_read_without_encryption(); case 'i': paramCount++; custom_IDm = true; @@ -553,6 +560,8 @@ static int CmdHFFelicaReadWithoutEncryption(const char *Cmd) { paramCount++; long_block_numbers = true; break; + default: + return usage_hf_felica_read_without_encryption(); } } i++; @@ -641,6 +650,8 @@ static int CmdHFFelicaRequestResponse(const char *Cmd) { paramCount++; i += 16; break; + default: + return usage_hf_felica_request_response(); } } i++; @@ -834,35 +845,56 @@ static int CmdHFFelicaSim(const char *Cmd) { */ static int CmdHFFelicaSniff(const char *Cmd) { - uint8_t cmdp = 0; + if (strlen(Cmd) < 2) return usage_hf_felica_sniff(); + uint8_t paramCount = 0; uint64_t samples2skip = 0; uint64_t triggers2skip = 0; - bool errors = false; - - while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { - switch (param_getchar(Cmd, cmdp)) { - case 'h': - case 'H': - return usage_hf_felica_sniff(); - case 's': - case 'S': - samples2skip = param_get32ex(Cmd, cmdp + 1, 0, 10); - cmdp += 2; - break; - case 't': - case 'T': - triggers2skip = param_get32ex(Cmd, cmdp + 1, 0, 10); - cmdp += 2; - break; - default: - PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); - errors = true; - break; + strip_cmds(Cmd); + int i = 0; + while (Cmd[i] != '\0') { + if (Cmd[i] == '-') { + switch (Cmd[i + 1]) { + case 'h': + case 'H': + return usage_hf_felica_sniff(); + case 's': + case 'S': + paramCount++; + if (param_getlength(Cmd, paramCount) < 5) { + samples2skip = param_get32ex(Cmd, paramCount++, 0, 10); + }else{ + PrintAndLogEx(ERR, "Invalid samples number!"); + return PM3_EINVARG; + } + break; + case 't': + case 'T': + paramCount++; + if (param_getlength(Cmd, paramCount) < 5) { + triggers2skip = param_get32ex(Cmd, paramCount++, 0, 10); + }else{ + PrintAndLogEx(ERR, "Invalid triggers number!"); + return PM3_EINVARG; + } + break; + default: + PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, paramCount)); + return usage_hf_felica_sniff(); + } + i += 2; } + i++; + } + if(samples2skip == 0){ + samples2skip = 10; + PrintAndLogEx(INFO, "Set default samples2skip: %i", samples2skip); + } + if(triggers2skip == 0){ + triggers2skip = 10; + PrintAndLogEx(INFO, "Set default triggers2skip: %i", triggers2skip); } - //Validations - if (errors || cmdp == 0) return usage_hf_felica_sniff(); + PrintAndLogEx(INFO, "Start Sniffing now. You can stop sniffing with clicking the PM3 Button"); clearCommandBuffer(); SendCommandMIX(CMD_HF_FELICA_SNIFF, samples2skip, triggers2skip, 0, NULL, 0); return PM3_SUCCESS; From c6f4bf2aa6bb6683d6ae8a919367ccd3d42c338b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 29 Oct 2019 19:32:27 +0100 Subject: [PATCH 1087/1854] return codes --- client/cmdhf14b.c | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/client/cmdhf14b.c b/client/cmdhf14b.c index 03a5f9b9f..ba8db1f92 100644 --- a/client/cmdhf14b.c +++ b/client/cmdhf14b.c @@ -147,15 +147,15 @@ static bool waitCmd14b(bool verbose) { if (len >= 3) { bool crc = check_crc(CRC_14443_B, data, len); - PrintAndLogEx(NORMAL, "[LEN %u] %s[%02X %02X] %s", + PrintAndLogEx(SUCCESS, "[LEN %u] %s[%02X %02X] %s", len, sprint_hex(data, len - 2), data[len - 2], data[len - 1], - (crc) ? "OK" : "FAIL" + (crc) ? _GREEN_("OK") : _RED_("FAIL") ); } else { - PrintAndLogEx(NORMAL, "[LEN %u] %s", len, sprint_hex(data, len)); + PrintAndLogEx(SUCCESS, "[LEN %u] %s", len, sprint_hex(data, len)); } } return true; @@ -182,7 +182,7 @@ static int CmdHF14BSim(const char *Cmd) { clearCommandBuffer(); SendCommandMIX(CMD_HF_ISO14443B_SIMULATE, pupi, 0, 0, NULL, 0); - return 0; + return PM3_SUCCESS; } static int CmdHF14BSniff(const char *Cmd) { @@ -192,7 +192,7 @@ static int CmdHF14BSniff(const char *Cmd) { clearCommandBuffer(); SendCommandNG(CMD_HF_ISO14443B_SNIFF, NULL, 0); - return 0; + return PM3_SUCCESS; } static int CmdHF14BCmdRaw(const char *Cmd) { @@ -262,15 +262,16 @@ static int CmdHF14BCmdRaw(const char *Cmd) { continue; } PrintAndLogEx(WARNING, "unknown parameter '%c'\n", param_getchar(Cmd, i)); - return 0; + return PM3_EINVARG; } if (hasTimeout) { -#define MAX_TIMEOUT 40542464 // = (2^32-1) * (8*16) / 13560000Hz * 1000ms/s + +#define MAX_14B_TIMEOUT 40542464 // = (2^32-1) * (8*16) / 13560000Hz * 1000ms/s flags |= ISO14B_SET_TIMEOUT; - if (user_timeout > MAX_TIMEOUT) { - user_timeout = MAX_TIMEOUT; - PrintAndLogEx(NORMAL, "Set timeout to 40542 seconds (11.26 hours). The max we can wait for response"); + if (user_timeout > MAX_14B_TIMEOUT) { + user_timeout = MAX_14B_TIMEOUT; + PrintAndLogEx(INFO, "Set timeout to 40542 seconds (11.26 hours). The max we can wait for response"); } time_wait = 13560000 / 1000 / (8 * 16) * user_timeout; // timeout in ETUs (time to transfer 1 bit, approx. 9.4 us) } @@ -287,7 +288,7 @@ static int CmdHF14BCmdRaw(const char *Cmd) { clearCommandBuffer(); SendCommandOLD(CMD_HF_ISO14443B_COMMAND, flags, datalen, time_wait, data, datalen); - if (!reply) return 1; + if (!reply) return PM3_SUCCESS; bool success = true; // get back iso14b_card_select_t, don't print it. @@ -297,7 +298,7 @@ static int CmdHF14BCmdRaw(const char *Cmd) { // get back response from the raw bytes you sent. if (success && datalen > 0) waitCmd14b(true); - return 1; + return PM3_SUCCESS; } static bool get_14b_UID(iso14b_card_select_t *card) { @@ -484,7 +485,6 @@ static void print_st_general_info(uint8_t *data, uint8_t len) { PrintAndLogEx(NORMAL, " UID: %s", sprint_hex(SwapEndian64(data, 8, 8), len)); PrintAndLogEx(NORMAL, " MFG: %02X, %s", data[6], getTagInfo(data[6])); PrintAndLogEx(NORMAL, "Chip: %02X, %s", data[5] >> 2, get_ST_Chip_Model(data[5] >> 2)); - return; } //05 00 00 = find one tag in field @@ -793,18 +793,18 @@ static int CmdHF14BWriteSri(const char *Cmd) { if (isSrix4k) { if (blockno > 0x7f && blockno != 0xff) { PrintAndLogEx(FAILED, "block number out of range"); - return 0; + return PM3_ESOFT; } } else { if (blockno > 0x0f && blockno != 0xff) { PrintAndLogEx(FAILED, "block number out of range"); - return 0; + return PM3_ESOFT; } } if (param_gethex(Cmd, 2, data, 8)) { PrintAndLogEx(WARNING, "data must include 8 HEX symbols"); - return 0; + return PM3_ESOFT; } if (blockno == 0xff) { @@ -822,8 +822,7 @@ static int CmdHF14BWriteSri(const char *Cmd) { } sprintf(str, "-ss -c %02x %02x %02x %02x %02x %02x", ISO14443B_WRITE_BLK, blockno, data[0], data[1], data[2], data[3]); - CmdHF14BCmdRaw(str); - return 0; + return CmdHF14BCmdRaw(str); } // need to write to file @@ -875,7 +874,7 @@ static int CmdHF14BDump(const char *Cmd) { if (!get_14b_UID(&card)) { PrintAndLogEx(WARNING, "No tag found."); - return 1; + return PM3_SUCCESS; } if (fileNameLen < 1) { @@ -1102,7 +1101,7 @@ static command_t CommandTable[] = { static int CmdHelp(const char *Cmd) { (void)Cmd; // Cmd is not used so far CmdsHelp(CommandTable); - return 0; + return PM3_SUCCESS; } int CmdHF14B(const char *Cmd) { From f9a80ea47bb8ec0a210b7b79290d3c44529eb5bd Mon Sep 17 00:00:00 2001 From: Riley Guerin Date: Tue, 29 Oct 2019 12:41:33 -0700 Subject: [PATCH 1088/1854] make warning about ModemManager louder #updatingforafriend --- .../Linux-Installation-Instructions.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/md/Installation_Instructions/Linux-Installation-Instructions.md b/doc/md/Installation_Instructions/Linux-Installation-Instructions.md index f82d0f677..d56d1056c 100644 --- a/doc/md/Installation_Instructions/Linux-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Linux-Installation-Instructions.md @@ -58,7 +58,8 @@ git clone https://github.com/RfidResearchGroup/proxmark3.git # Check ModemManager -**Very important**: make sure ModemManager will not interfer, otherwise it could brick your Proxmark3! +### ⚠️ Very important ⚠️ +make sure ModemManager will not interfer, otherwise it could brick your Proxmark3! Read carefully [this page about ModemManager](ModemManager-Must-Be-Discarded.md) and follow its instructions. # Check connection From 417679c3d83fce07306d70fd652a7bd285e298bf Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 30 Oct 2019 11:16:53 +0100 Subject: [PATCH 1089/1854] more keys --- client/dictionaries/mfc_default_keys.dic | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index 376676f1a..ab113b0f5 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -21,6 +21,8 @@ a0478cc39091 8fd0a4f256e9 # d2ece8b9395e # lib +# NSCP default key +☻1494E81663D7 # # more Keys from mfc_default_keys.lua 000000000001 From 1a852e02c7b183ab53189ca4f4e957debf5f7a2b Mon Sep 17 00:00:00 2001 From: Thomas Sutter Date: Wed, 30 Oct 2019 13:35:03 +0100 Subject: [PATCH 1090/1854] Fix sniffing command. Refactor hf list felica. --- armsrc/felica.c | 18 ++++++++++-------- client/cmdhflist.c | 7 +++++-- client/cmdhflist.h | 1 + client/cmdtrace.c | 28 ++++++++++++++++++++-------- 4 files changed, 36 insertions(+), 18 deletions(-) diff --git a/armsrc/felica.c b/armsrc/felica.c index 7ec40efcf..2ad9b06ce 100644 --- a/armsrc/felica.c +++ b/armsrc/felica.c @@ -573,25 +573,26 @@ void felica_sendraw(PacketCommandNG *c) { } void felica_sniff(uint32_t samplesToSkip, uint32_t triggersToSkip) { - int remFrames = (samplesToSkip) ? samplesToSkip : 0; - Dbprintf("Sniff FelicaLiteS: Getting first %d frames, Skipping %d triggers.\n", samplesToSkip, triggersToSkip); - iso18092_setup(FPGA_HF_ISO18092_FLAG_NOMOD); - + LED_D_ON(); + BigBuf_free(); + BigBuf_Clear(); //the frame bits are slow enough. int n = BigBuf_max_traceLen() / sizeof(uint8_t); // take all memory int numbts = 0; uint8_t *dest = (uint8_t *)BigBuf_get_addr(); uint8_t *destend = dest + n - 2; - uint32_t endframe = GetCountSspClk(); - while (dest <= destend) { - WDT_HIT(); - if (BUTTON_PRESS()) break; + // Set up the synchronous serial port + FpgaSetupSsc(); + //FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SNOOP); + SpinDelay(100); + while (dest <= destend && !BUTTON_PRESS()) { + WDT_HIT(); if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { uint8_t dist = (uint8_t)(AT91C_BASE_SSC->SSC_RHR); Process18092Byte(dist); @@ -636,6 +637,7 @@ void felica_sniff(uint32_t samplesToSkip, uint32_t triggersToSkip) { Dbprintf("Felica sniffing done, tracelen: %i, use hf list felica for annotations", BigBuf_get_traceLen()); reply_old(CMD_ACK, 1, numbts, 0, 0, 0); + LED_D_OFF(); } #define R_POLL0_LEN 0x16 diff --git a/client/cmdhflist.c b/client/cmdhflist.c index 737405787..71ae81926 100644 --- a/client/cmdhflist.c +++ b/client/cmdhflist.c @@ -97,6 +97,10 @@ uint8_t iso15693_CRC_check(uint8_t *d, uint8_t n) { return check_crc(CRC_15693, d, n); } +uint8_t felica_CRC_check(uint8_t *d, uint8_t n) { + return check_crc(CRC_FELICA, d, n); +} + /** * @brief iclass_CRC_Ok Checks CRC in command or response * @param isResponse @@ -889,8 +893,7 @@ void annotateLegic(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) { } void annotateFelica(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) { - - switch (cmd[0]) { + switch (cmd[3]) { case FELICA_POLL_REQ: snprintf(exp, size, "POLLING"); break; diff --git a/client/cmdhflist.h b/client/cmdhflist.h index 0dda4ea17..42ae6e83b 100644 --- a/client/cmdhflist.h +++ b/client/cmdhflist.h @@ -31,6 +31,7 @@ void ClearAuthData(void); uint8_t iso14443A_CRC_check(bool isResponse, uint8_t *d, uint8_t n); uint8_t iso14443B_CRC_check(uint8_t *d, uint8_t n); +uint8_t felica_CRC_check(uint8_t *d, uint8_t n); uint8_t mifare_CRC_check(bool isResponse, uint8_t *data, uint8_t len); uint8_t iso15693_CRC_check(uint8_t *d, uint8_t n); uint8_t iclass_CRC_check(bool isResponse, uint8_t *d, uint8_t n); diff --git a/client/cmdtrace.c b/client/cmdtrace.c index 63cfa388c..6958297b2 100644 --- a/client/cmdtrace.c +++ b/client/cmdtrace.c @@ -257,7 +257,7 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr case ISO_14443B: case TOPAZ: case FELICA: - crcStatus = iso14443B_CRC_check(frame, data_len); + crcStatus = !felica_CRC_check(frame+2, data_len-4); break; case PROTO_MIFARE: crcStatus = mifare_CRC_check(isResponse, frame, data_len); @@ -349,6 +349,9 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr if (protocol == PROTO_MIFARE) annotateMifare(explanation, sizeof(explanation), frame, data_len, parityBytes, parity_len, isResponse); + if(protocol == FELICA) + annotateFelica(explanation, sizeof(explanation), frame, data_len); + if (!isResponse) { switch (protocol) { case ICLASS: @@ -408,7 +411,7 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr sprint_hex_inrow_spaces(mfData, mfDataLen, 2), (crcc == 0 ? "!crc" : (crcc == 1 ? " ok " : " ")), explanation); - }; + } if (is_last_record(tracepos, trace, traceLen)) return traceLen; @@ -423,19 +426,22 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr return tracepos; } - +/* static void printFelica(uint16_t traceLen, uint8_t *trace) { PrintAndLogEx(NORMAL, "ISO18092 / FeliCa - Timings are not as accurate"); - PrintAndLogEx(NORMAL, " Gap | Src | Data | CRC | Annotation |"); - PrintAndLogEx(NORMAL, "--------|-----|---------------------------------|----------|-------------------|"); + PrintAndLogEx(NORMAL, " Gap | Src | Data | CRC | Annotation |"); + PrintAndLogEx(NORMAL, "--------|-----|-------------------------------------------------------------------------|----------|-------------------|"); uint16_t tracepos = 0; + PrintAndLogEx(NORMAL, "traceLen: %i", traceLen); + PrintAndLogEx(NORMAL, "Raw trace: %s", sprint_hex(trace, traceLen)); while (tracepos < traceLen) { + PrintAndLogEx(NORMAL, "tracepos: %i", tracepos); + PrintAndLogEx(NORMAL, "traceLen: %i", traceLen); if (tracepos + 3 >= traceLen) break; - uint16_t gap = *((uint16_t *)(trace + tracepos)); uint8_t crc_ok = trace[tracepos + 2]; tracepos += 3; @@ -443,6 +449,7 @@ static void printFelica(uint16_t traceLen, uint8_t *trace) { if (tracepos + 3 >= traceLen) break; uint16_t len = trace[tracepos + 2]; + PrintAndLogEx(NORMAL, "LEN: %i", len); //I am stripping SYNC tracepos += 3; //skip SYNC @@ -611,7 +618,7 @@ static void printFelica(uint16_t traceLen, uint8_t *trace) { tracepos += len + 1; } PrintAndLogEx(NORMAL, ""); -} +}*/ // sanity check. Don't use proxmark if it is offline and you didn't specify useTraceBuffer /* @@ -819,9 +826,13 @@ int CmdTraceList(const char *Cmd) { PrintAndLogEx(SUCCESS, "Recorded Activity (TraceLen = %lu bytes)", traceLen); PrintAndLogEx(INFO, ""); + + /* if (protocol == FELICA) { printFelica(traceLen, trace); - } else if (showHex) { + } */ + + if (showHex) { while (tracepos < traceLen) { tracepos = printHexLine(tracepos, traceLen, trace, protocol); } @@ -844,6 +855,7 @@ int CmdTraceList(const char *Cmd) { PrintAndLogEx(NORMAL, "ISO7816-4 / Smartcard - Timings N/A yet"); if (protocol == PROTO_HITAG) PrintAndLogEx(NORMAL, "Hitag2 / HitagS - Timings in ETU (8us)"); + if (protocol == FELICA) PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, " Start | End | Src | Data (! denotes parity error) | CRC | Annotation"); From f3d79c22f2ac666a7bf2e2dc3a10f0dd23ba02bc Mon Sep 17 00:00:00 2001 From: Thomas Sutter Date: Wed, 30 Oct 2019 13:42:52 +0100 Subject: [PATCH 1091/1854] Remove parity bit check for felica. --- client/cmdhffelica.c | 1 - client/cmdtrace.c | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index bcbda18e4..f667a9f8c 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -845,7 +845,6 @@ static int CmdHFFelicaSim(const char *Cmd) { */ static int CmdHFFelicaSniff(const char *Cmd) { - if (strlen(Cmd) < 2) return usage_hf_felica_sniff(); uint8_t paramCount = 0; uint64_t samples2skip = 0; uint64_t triggers2skip = 0; diff --git a/client/cmdtrace.c b/client/cmdtrace.c index 6958297b2..941a8bc86 100644 --- a/client/cmdtrace.c +++ b/client/cmdtrace.c @@ -301,6 +301,7 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr && protocol != ISO_7816_4 && protocol != PROTO_HITAG && protocol != THINFILM + && protocol != FELICA && (isResponse || protocol == ISO_14443A) && (oddparity8(frame[j]) != ((parityBits >> (7 - (j & 0x0007))) & 0x01))) { From 9738834fafbd58814f2ad80e6b9134685457e0f8 Mon Sep 17 00:00:00 2001 From: Thomas Sutter Date: Wed, 30 Oct 2019 13:43:23 +0100 Subject: [PATCH 1092/1854] Remove unused function. --- client/cmdhffelica.c | 67 -------------------------------------------- 1 file changed, 67 deletions(-) diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index f667a9f8c..4c492176e 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -777,73 +777,6 @@ static int CmdHFFelicaNotImplementedYet(const char *Cmd) { return PM3_SUCCESS; } -// simulate iso18092 / FeliCa tag -// Commented, there is no counterpart in ARM at the moment -/* -static int CmdHFFelicaSim(const char *Cmd) { - bool errors = false; - uint8_t flags = 0; - uint8_t tagtype = 1; - uint8_t cmdp = 0; - uint8_t uid[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - int uidlen = 0; - bool verbose = false; - - while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { - switch (param_getchar(Cmd, cmdp)) { - case 'h': - case 'H': - return usage_hf_felica_sim(); - case 't': - case 'T': - // Retrieve the tag type - tagtype = param_get8ex(Cmd, cmdp + 1, 0, 10); - if (tagtype == 0) - errors = true; - cmdp += 2; - break; - case 'u': - case 'U': - // Retrieve the full 4,7,10 byte long uid - param_gethex_ex(Cmd, cmdp + 1, uid, &uidlen); - if (!errors) { - PrintAndLogEx(NORMAL, "Emulating ISO18092/FeliCa tag with %d byte UID (%s)", uidlen >> 1, sprint_hex(uid, uidlen >> 1)); - } - cmdp += 2; - break; - case 'v': - case 'V': - verbose = true; - cmdp++; - break; - case 'e': - case 'E': - cmdp++; - break; - default: - PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); - errors = true; - break; - } - } - - //Validations - if (errors || cmdp == 0) return usage_hf_felica_sim(); - - clearCommandBuffer(); - SendCommandOLD(CMD_HF_FELICA_SIMULATE, tagtype, flags, 0, uid, uidlen >> 1); - PacketResponseNG resp; - - if (verbose) - PrintAndLogEx(NORMAL, "Press pm3-button to abort simulation"); - - while (!kbd_enter_pressed()) { - if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) continue; - } - return PM3_SUCCESS; -} -*/ - static int CmdHFFelicaSniff(const char *Cmd) { uint8_t paramCount = 0; uint64_t samples2skip = 0; From 01b149efa5809a4f480f27a9abda325585cc9986 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 30 Oct 2019 15:44:57 +0100 Subject: [PATCH 1093/1854] fix: fdx crc calc --- client/cmdlffdx.c | 22 ++++++++++++---------- common/crc16.c | 17 ++++++++++++++++- common/crc16.h | 11 ++++++++--- 3 files changed, 36 insertions(+), 14 deletions(-) diff --git a/client/cmdlffdx.c b/client/cmdlffdx.c index 244c0caf3..6cf3b0efa 100644 --- a/client/cmdlffdx.c +++ b/client/cmdlffdx.c @@ -13,6 +13,7 @@ #include #include #include +#include // tolower #include "cmdparser.h" // command_t #include "comms.h" @@ -226,15 +227,12 @@ static int CmdFdxDemod(const char *Cmd) { uint8_t dataBlockBit = DemodBuffer[48]; uint32_t reservedCode = bytebits_to_byteLSBF(DemodBuffer + 49, 14); uint8_t animalBit = DemodBuffer[63]; - uint32_t crc_16 = bytebits_to_byteLSBF(DemodBuffer + 64, 16); + uint16_t crc = bytebits_to_byteLSBF(DemodBuffer + 64, 16); uint32_t extended = bytebits_to_byteLSBF(DemodBuffer + 80, 24); uint64_t rawid = (uint64_t)(bytebits_to_byte(DemodBuffer, 32)) << 32 | bytebits_to_byte(DemodBuffer + 32, 32); uint8_t raw[8]; num_to_bytes(rawid, 8, raw); - - uint16_t calcCrc = crc16_kermit(raw, 8); - PrintAndLogEx(SUCCESS, "\nFDX-B / ISO 11784/5 Animal Tag ID Found: Raw : %s", sprint_hex(raw, 8)); PrintAndLogEx(SUCCESS, "Animal ID %04u-%012" PRIu64, countryCode, NationalCode); PrintAndLogEx(SUCCESS, "National Code %012" PRIu64 " (0x%" PRIx64 ")", NationalCode, NationalCode); @@ -242,7 +240,10 @@ static int CmdFdxDemod(const char *Cmd) { PrintAndLogEx(SUCCESS, "Reserved/RFU %u (0x04%X)", reservedCode, reservedCode); PrintAndLogEx(SUCCESS, "Animal Tag %s", animalBit ? _YELLOW_("True") : "False"); PrintAndLogEx(SUCCESS, "Has extended data %s [0x%X]", dataBlockBit ? _YELLOW_("True") : "False", extended); - PrintAndLogEx(SUCCESS, "CRC-16 0x%04X - 0x%04X [%s]", crc_16, calcCrc, (calcCrc == crc_16) ? _GREEN_("Ok") : _RED_("Fail")); + + uint8_t c[] = {0, 0}; + compute_crc(CRC_11784, raw, sizeof(raw), &c[0], &c[1]); + PrintAndLogEx(SUCCESS, "CRC-16 0x%04X [ %s] ", crc, (crc == (c[1] << 8 | c[0]) ) ? _GREEN_("OK") : _RED_("Fail")); if (g_debugMode) { PrintAndLogEx(DEBUG, "Start marker %d; Size %zu", preambleIndex, size); @@ -265,8 +266,8 @@ static int CmdFdxClone(const char *Cmd) { uint32_t countryid = 0; uint64_t animalid = 0; - char cmdp = param_getchar(Cmd, 0); - if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_fdx_clone(); + char cmdp = tolower(param_getchar(Cmd, 0)); + if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_fdx_clone(); countryid = param_get32ex(Cmd, 0, 0, 10); animalid = param_get64ex(Cmd, 1, 0, 10); @@ -305,8 +306,8 @@ static int CmdFdxSim(const char *Cmd) { uint32_t countryid = 0; uint64_t animalid = 0; - char cmdp = param_getchar(Cmd, 0); - if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_fdx_sim(); + char cmdp = tolower(param_getchar(Cmd, 0)); + if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_fdx_sim(); countryid = param_get32ex(Cmd, 0, 0, 10); animalid = param_get64ex(Cmd, 1, 0, 10); @@ -417,7 +418,8 @@ int getFDXBits(uint64_t national_id, uint16_t country, uint8_t isanimal, uint8_t for (uint8_t i = 0; i < 8; ++i) raw[i] = bytebits_to_byte(bits + 11 + i * 9, 8); - uint16_t crc = crc16_kermit(raw, 8); + init_table(CRC_11784); + uint16_t crc = crc16_fdx(raw, 8); num_to_bytebitsLSBF(crc >> 0, 8, bits + 83); num_to_bytebitsLSBF(crc >> 8, 8, bits + 92); diff --git a/common/crc16.c b/common/crc16.c index 22445beda..b1c2ac248 100644 --- a/common/crc16.c +++ b/common/crc16.c @@ -46,6 +46,9 @@ void init_table(CrcType_t crctype) { case CRC_KERMIT: generate_table(CRC16_POLY_CCITT, true); break; + case CRC_11784: + generate_table(CRC16_POLY_CCITT, false); + break; case CRC_NONE: crc_table_init = false; current_crc_type = CRC_NONE; @@ -185,6 +188,9 @@ void compute_crc(CrcType_t ct, const uint8_t *d, size_t n, uint8_t *first, uint8 case CRC_KERMIT: crc = crc16_kermit(d, n); break; + case CRC_11784: + crc = crc16_fdx(d, n); + break; case CRC_LEGIC: // TODO return; @@ -215,6 +221,8 @@ uint16_t Crc16ex(CrcType_t ct, const uint8_t *d, size_t n) { return crc16_ccitt(d, n); case CRC_KERMIT: return crc16_kermit(d, n); + case CRC_11784: + return crc16_fdx(d, n); case CRC_LEGIC: // TODO return 0; @@ -257,6 +265,8 @@ bool check_crc(CrcType_t ct, const uint8_t *d, size_t n) { return (crc16_ccitt(d, n) == 0); case CRC_KERMIT: return (crc16_kermit(d, n) == 0); + case CRC_11784: + return (crc16_fdx(d, n) == 0); case CRC_LEGIC: // TODO return false; @@ -272,7 +282,12 @@ uint16_t crc16_ccitt(uint8_t const *d, size_t n) { return crc16_fast(d, n, 0xffff, false, false); } -// FDX-B ISO11784/85) uses KERMIT +// FDX-B ISO11784/85) uses KERMIT/CCITT +// poly 0x xx init=0x000 refin=false refout=true xorout=0x0000 ... +uint16_t crc16_fdx(uint8_t const *d, size_t n) { + return crc16_fast(d, n, 0x0000, false, true); +} + // poly=0x1021 init=0x0000 refin=true refout=true xorout=0x0000 name="KERMIT" uint16_t crc16_kermit(uint8_t const *d, size_t n) { return crc16_fast(d, n, 0x0000, true, true); diff --git a/common/crc16.h b/common/crc16.h index 6989af22e..7a273683c 100644 --- a/common/crc16.h +++ b/common/crc16.h @@ -10,14 +10,16 @@ #include "common.h" -#define CRC16_POLY_CCITT 0x1021 -#define CRC16_POLY_LEGIC 0xc6c6 //0x6363 -#define CRC16_POLY_DNP 0x3d65 +#define CRC16_POLY_CCITT 0x1021 +#define CRC16_POLY_KERMIT 0x8408 +#define CRC16_POLY_LEGIC 0xc6c6 //0x6363 +#define CRC16_POLY_DNP 0x3d65 #define X25_CRC_CHECK ((uint16_t)(~0xF0B8 & 0xFFFF)) // use this for checking of a correct crc typedef enum { CRC_NONE, + CRC_11784, CRC_14443_A, CRC_14443_B, CRC_15693, @@ -41,6 +43,9 @@ bool check_crc(CrcType_t ct, const uint8_t *d, size_t n); uint16_t crc16_ccitt(uint8_t const *d, size_t n); // Calculate CRC-16/KERMIT (FDX-B ISO11784/85) LF +uint16_t crc16_fdx(uint8_t const *d, size_t n); + +// Calculate CRC-16/KERMIT uint16_t crc16_kermit(uint8_t const *d, size_t n); // Calculate CRC-16/XMODEM (FeliCa) From eb7fd5f8ab841dd3a1418e1eedbec5847aa58a3c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 30 Oct 2019 15:45:52 +0100 Subject: [PATCH 1094/1854] textual --- client/cmdhw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdhw.c b/client/cmdhw.c index 619e73abe..5eb6c7100 100644 --- a/client/cmdhw.c +++ b/client/cmdhw.c @@ -542,7 +542,7 @@ static int CmdPing(const char *Cmd) { bool error = false; if (len) { error = memcmp(data, resp.data.asBytes, len) != 0; - PrintAndLogEx((error) ? ERR : SUCCESS, "Ping response " _GREEN_("received") "and content is %s", error ? _RED_("NOT ok") : _GREEN_("ok")); + PrintAndLogEx((error) ? ERR : SUCCESS, "Ping response " _GREEN_("received") "and content is %s", error ? _RED_("NOT ok") : _GREEN_("OK")); } else { PrintAndLogEx(SUCCESS, "Ping response " _GREEN_("received")); } From b383b16dede8b5f8a5f59eaca3116a626fbf425f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 31 Oct 2019 08:39:11 +0100 Subject: [PATCH 1095/1854] chg: lf fdx clone/sim - added extended data --- client/cmdlffdx.c | 61 ++++++++++++++++++++++++++++------------------- 1 file changed, 36 insertions(+), 25 deletions(-) diff --git a/client/cmdlffdx.c b/client/cmdlffdx.c index 6cf3b0efa..17dbd2fd0 100644 --- a/client/cmdlffdx.c +++ b/client/cmdlffdx.c @@ -50,15 +50,14 @@ static int CmdHelp(const char *Cmd); static int usage_lf_fdx_clone(void) { PrintAndLogEx(NORMAL, "Clone a FDX-B animal tag to a T55x7 tag."); - PrintAndLogEx(NORMAL, "Usage: lf fdx clone [h] "); + PrintAndLogEx(NORMAL, "Usage: lf fdx clone [h] "); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h : This help"); PrintAndLogEx(NORMAL, " : Country id"); PrintAndLogEx(NORMAL, " : Animal id"); - // has extended data? + PrintAndLogEx(NORMAL, " : Extended data"); //reserved/rfu //is animal tag - // extended data PrintAndLogEx(NORMAL, " : Specify write to Q5 (t5555 instead of t55x7)"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); @@ -70,11 +69,12 @@ static int usage_lf_fdx_sim(void) { PrintAndLogEx(NORMAL, "Enables simulation of FDX-B animal tag"); PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued."); PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Usage: lf fdx sim [h] "); + PrintAndLogEx(NORMAL, "Usage: lf fdx sim [h] "); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h : This help"); PrintAndLogEx(NORMAL, " : Country ID"); PrintAndLogEx(NORMAL, " : Animal ID"); + PrintAndLogEx(NORMAL, " : Extended data"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf fdx sim 999 112233"); @@ -82,14 +82,14 @@ static int usage_lf_fdx_sim(void) { } // clearing the topbit needed for the preambl detection. -static void verify_values(uint32_t countryid, uint64_t animalid) { - if ((animalid & 0x3FFFFFFFFF) != animalid) { - animalid &= 0x3FFFFFFFFF; - PrintAndLogEx(INFO, "Animal ID Truncated to 38bits: %"PRIx64, animalid); +static void verify_values(uint64_t *animalid, uint32_t *countryid) { + if ((*animalid & 0x3FFFFFFFFF) != *animalid) { + *animalid &= 0x3FFFFFFFFF; + PrintAndLogEx(INFO, "Animal ID Truncated to 38bits: %"PRIx64, *animalid); } - if ((countryid & 0x3ff) != countryid) { - countryid &= 0x3ff; - PrintAndLogEx(INFO, "Country ID Truncated to 10bits: %03d", countryid); + if ((*countryid & 0x3ff) != *countryid) { + *countryid &= 0x3ff; + PrintAndLogEx(INFO, "Country ID Truncated to 10bits: %03d", *countryid); } } @@ -264,19 +264,21 @@ static int CmdFdxRead(const char *Cmd) { static int CmdFdxClone(const char *Cmd) { - uint32_t countryid = 0; + uint32_t countryid = 0, extended = 0; uint64_t animalid = 0; + char cmdp = tolower(param_getchar(Cmd, 0)); if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_fdx_clone(); countryid = param_get32ex(Cmd, 0, 0, 10); animalid = param_get64ex(Cmd, 1, 0, 10); + extended = param_get32ex(Cmd, 2, 0, 10); - verify_values(countryid, animalid); + verify_values(&animalid, &countryid); uint8_t *bits = calloc(128, sizeof(uint8_t)); - if (getFDXBits(animalid, countryid, 1, 0, 0, bits) != PM3_SUCCESS) { + if (getFDXBits(animalid, countryid, 1, (extended > 0), extended, bits) != PM3_SUCCESS) { PrintAndLogEx(ERR, "Error with tag bitstream generation."); free(bits); return PM3_ESOFT; @@ -285,7 +287,7 @@ static int CmdFdxClone(const char *Cmd) { uint32_t blocks[5] = {T55x7_MODULATION_DIPHASE | T55x7_BITRATE_RF_32 | 4 << T55x7_MAXBLOCK_SHIFT, 0, 0, 0, 0}; //Q5 - if (param_getchar(Cmd, 2) == 'Q' || param_getchar(Cmd, 2) == 'q') + if (tolower(param_getchar(Cmd, 2)) == 'q') blocks[0] = T5555_MODULATION_BIPHASE | T5555_INVERT_OUTPUT | T5555_SET_BITRATE(32) | 4 << T5555_MAXBLOCK_SHIFT; // convert from bit stream to block data @@ -303,7 +305,7 @@ static int CmdFdxClone(const char *Cmd) { } static int CmdFdxSim(const char *Cmd) { - uint32_t countryid = 0; + uint32_t countryid = 0, extended = 0; uint64_t animalid = 0; char cmdp = tolower(param_getchar(Cmd, 0)); @@ -311,25 +313,33 @@ static int CmdFdxSim(const char *Cmd) { countryid = param_get32ex(Cmd, 0, 0, 10); animalid = param_get64ex(Cmd, 1, 0, 10); + extended = param_get32ex(Cmd, 2, 0 , 10); - verify_values(countryid, animalid); + verify_values(&animalid, &countryid); PrintAndLogEx(SUCCESS, "Simulating FDX-B animal ID: %04u-%"PRIu64, countryid, animalid); - uint8_t bs[128]; //getFDXBits(uint64_t national_id, uint16_t country, uint8_t isanimal, uint8_t isextended, uint32_t extended, uint8_t *bits) - getFDXBits(animalid, countryid, 1, 0, 0, bs); + uint8_t *bits = calloc(128, sizeof(uint8_t)); + + if (getFDXBits(animalid, countryid, 1, (extended > 0), extended, bits) != PM3_SUCCESS) { + PrintAndLogEx(ERR, "Error with tag bitstream generation."); + free(bits); + return PM3_ESOFT; + } // 32, no STT, BIPHASE INVERTED == diphase - lf_asksim_t *payload = calloc(1, sizeof(lf_asksim_t) + sizeof(bs)); + lf_asksim_t *payload = calloc(1, sizeof(lf_asksim_t) + 128); payload->encoding = 2; payload->invert = 1; payload->separator = 0; payload->clock = 32; - memcpy(payload->data, bs, sizeof(bs)); + memcpy(payload->data, bits, 128); clearCommandBuffer(); - SendCommandNG(CMD_LF_ASK_SIMULATE, (uint8_t *)payload, sizeof(lf_asksim_t) + sizeof(bs)); + SendCommandNG(CMD_LF_ASK_SIMULATE, (uint8_t *)payload, sizeof(lf_asksim_t) + 128); + + free(bits); free(payload); PacketResponseNG resp; @@ -338,6 +348,7 @@ static int CmdFdxSim(const char *Cmd) { PrintAndLogEx(INFO, "Done"); if (resp.status != PM3_EOPABORTED) return resp.status; + return PM3_SUCCESS; } @@ -379,7 +390,7 @@ int demodFDX(void) { return CmdFdxDemod(""); } -int getFDXBits(uint64_t national_id, uint16_t country, uint8_t isanimal, uint8_t isextended, uint32_t extended, uint8_t *bits) { +int getFDXBits(uint64_t national_id, uint16_t country, uint8_t is_animal, uint8_t is_extended, uint32_t extended, uint8_t *bits) { // add preamble ten 0x00 and one 0x01 memset(bits, 0x00, 10); @@ -397,10 +408,10 @@ int getFDXBits(uint64_t national_id, uint16_t country, uint8_t isanimal, uint8_t num_to_bytebitsLSBF(0x00 >> 7, 7, bits + 74); // add animal flag - OK - bits[65] = isanimal; + bits[65] = is_animal; // add extended flag - OK - bits[81] = isextended; + bits[81] = is_extended; // add national code 40bits - OK num_to_bytebitsLSBF(national_id >> 0, 8, bits + 11); From dadad1dacf5365f2942f8bb52afab715e607e701 Mon Sep 17 00:00:00 2001 From: Thomas Sutter Date: Fri, 1 Nov 2019 15:06:48 +0100 Subject: [PATCH 1096/1854] Fix felica sniffing. --- CHANGELOG.md | 2 + armsrc/felica.c | 79 +++++++----------- client/cmdhffelica.c | 10 ++- client/cmdtrace.c | 194 +------------------------------------------ 4 files changed, 41 insertions(+), 244 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c0ef300cb..89a04d651 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Fix hf list felica and hf felica sniff (@7homasSutter) + - Added hf felica wrunencrypted (@7homasSutter) - Added hf felica rdunencrypted (@7homasSutter) - Added hf felica rqresponse (@7homasSutter) - Added hf felica rqservice (@7homasSutter) diff --git a/armsrc/felica.c b/armsrc/felica.c index 2ad9b06ce..c9ebf9969 100644 --- a/armsrc/felica.c +++ b/armsrc/felica.c @@ -410,8 +410,6 @@ bool WaitForFelicaReply(uint16_t maxbytes) { // clear RXRDY: uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; uint32_t timeout = iso18092_get_timeout(); - if (DBGLEVEL >= DBG_DEBUG) - Dbprintf("timeout set: %i", timeout); for (;;) { WDT_HIT(); @@ -420,8 +418,8 @@ bool WaitForFelicaReply(uint16_t maxbytes) { Process18092Byte(b); if (FelicaFrame.state == STATE_FULL) { felica_nexttransfertime = MAX(felica_nexttransfertime, - (GetCountSspClk() & 0xfffffff8) - (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER) / 16 + FELICA_FRAME_DELAY_TIME - ); + (GetCountSspClk() & 0xfffffff8) - (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER) / 16 + FELICA_FRAME_DELAY_TIME); + LogTrace( FelicaFrame.framebytes, FelicaFrame.len, @@ -453,7 +451,7 @@ static void iso18092_setup(uint8_t fpga_minor_mode) { BigBuf_Clear_ext(false); // Initialize Demod and Uart structs - //DemodInit(BigBuf_malloc(MAX_FRAME_SIZE)); + // DemodInit(BigBuf_malloc(MAX_FRAME_SIZE)); FelicaFrameinit(BigBuf_malloc(FELICA_MAX_FRAME_SIZE)); felica_nexttransfertime = 2 * DELAY_ARM2AIR_AS_READER; @@ -574,66 +572,53 @@ void felica_sendraw(PacketCommandNG *c) { void felica_sniff(uint32_t samplesToSkip, uint32_t triggersToSkip) { int remFrames = (samplesToSkip) ? samplesToSkip : 0; - Dbprintf("Sniff FelicaLiteS: Getting first %d frames, Skipping %d triggers.\n", samplesToSkip, triggersToSkip); + Dbprintf("Sniff Felica: Getting first %d frames, Skipping after %d triggers.\n", samplesToSkip, triggersToSkip); + clear_trace(); + set_tracing(true); iso18092_setup(FPGA_HF_ISO18092_FLAG_NOMOD); LED_D_ON(); - BigBuf_free(); - BigBuf_Clear(); - //the frame bits are slow enough. - int n = BigBuf_max_traceLen() / sizeof(uint8_t); // take all memory - int numbts = 0; - uint8_t *dest = (uint8_t *)BigBuf_get_addr(); - uint8_t *destend = dest + n - 2; - uint32_t endframe = GetCountSspClk(); - - // Set up the synchronous serial port - FpgaSetupSsc(); - //FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SNOOP); - SpinDelay(100); - - while (dest <= destend && !BUTTON_PRESS()) { + uint16_t numbts = 0; + int trigger_cnt = 0; + uint32_t timeout = iso18092_get_timeout(); + bool isTagFrame = true; + while (!BUTTON_PRESS()) { WDT_HIT(); if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { uint8_t dist = (uint8_t)(AT91C_BASE_SSC->SSC_RHR); Process18092Byte(dist); - - //to be sure we are in frame - if (FelicaFrame.state == STATE_GET_LENGTH) { - //length is after 48 (PRE)+16 (SYNC) - 64 ticks +maybe offset? not 100% - uint16_t distance = GetCountSspClk() - endframe - 64 + (FelicaFrame.byte_offset > 0 ? (8 - FelicaFrame.byte_offset) : 0); - *dest = distance >> 8; - dest++; - *dest = (distance & 0xff); - dest++; + if ((MAX(dist & 0xff, dist >> 8) >= 178) && (++trigger_cnt > triggersToSkip)) { + Dbprintf("triggersToSkip kicked %d", dist); + break; } - //crc NOT checked if (FelicaFrame.state == STATE_FULL) { - endframe = GetCountSspClk(); - // *dest = FelicaFrame.crc_ok; //kind of wasteful - dest++; - for (int i = 0; i < FelicaFrame.len; i++) { - *dest = FelicaFrame.framebytes[i]; - dest++; - if (dest >= destend) break; - - } - + //Dbprintf("Sniffing - Got Felica Frame! Sample remaining %i", remFrames); remFrames--; - if (remFrames <= 0) break; - if (dest >= destend) break; - + if (remFrames <= 0){ + Dbprintf("Stop Sniffing - samplesToSkip reached!"); + break; + } + if((FelicaFrame.framebytes[3] % 2) == 0){ + isTagFrame = false; // All Reader Frames are even and all Tag frames are odd + } else{ + isTagFrame = true; + } + LogTrace(FelicaFrame.framebytes, + FelicaFrame.len, + ((GetCountSspClk() & 0xfffffff8) << 4) - DELAY_AIR2ARM_AS_READER - timeout, + ((GetCountSspClk() & 0xfffffff8) << 4) - DELAY_AIR2ARM_AS_READER, + NULL, + isTagFrame + ); numbts += FelicaFrame.len; - FelicaFrameReset(); } } } - switch_off(); - //reset framing AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(8) | AT91C_SSC_MSBF | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0); set_tracelen(numbts); + set_tracelen(BigBuf_max_traceLen()); Dbprintf("Felica sniffing done, tracelen: %i, use hf list felica for annotations", BigBuf_get_traceLen()); reply_old(CMD_ACK, 1, numbts, 0, 0, 0); diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index 4c492176e..427ca07c1 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -55,7 +55,8 @@ static int usage_hf_felica_sniff(void) { PrintAndLogEx(NORMAL, " -t triggers to skip (decimal) max 9999"); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf felica sniff 10 10"); + PrintAndLogEx(NORMAL, " hf felica sniff"); + PrintAndLogEx(NORMAL, " hf felica sniff -s 10 -t 10"); return PM3_SUCCESS; } @@ -817,16 +818,17 @@ static int CmdHFFelicaSniff(const char *Cmd) { } i++; } - if(samples2skip == 0){ + if(samples2skip <= 0){ samples2skip = 10; PrintAndLogEx(INFO, "Set default samples2skip: %i", samples2skip); } - if(triggers2skip == 0){ - triggers2skip = 10; + if(triggers2skip <= 0){ + triggers2skip = 5000; PrintAndLogEx(INFO, "Set default triggers2skip: %i", triggers2skip); } PrintAndLogEx(INFO, "Start Sniffing now. You can stop sniffing with clicking the PM3 Button"); + PrintAndLogEx(INFO, "During sniffing, other pm3 commands may not response."); clearCommandBuffer(); SendCommandMIX(CMD_HF_FELICA_SNIFF, samples2skip, triggers2skip, 0, NULL, 0); return PM3_SUCCESS; diff --git a/client/cmdtrace.c b/client/cmdtrace.c index 941a8bc86..77aab71e5 100644 --- a/client/cmdtrace.c +++ b/client/cmdtrace.c @@ -427,199 +427,6 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr return tracepos; } -/* -static void printFelica(uint16_t traceLen, uint8_t *trace) { - - PrintAndLogEx(NORMAL, "ISO18092 / FeliCa - Timings are not as accurate"); - PrintAndLogEx(NORMAL, " Gap | Src | Data | CRC | Annotation |"); - PrintAndLogEx(NORMAL, "--------|-----|-------------------------------------------------------------------------|----------|-------------------|"); - uint16_t tracepos = 0; - - PrintAndLogEx(NORMAL, "traceLen: %i", traceLen); - PrintAndLogEx(NORMAL, "Raw trace: %s", sprint_hex(trace, traceLen)); - while (tracepos < traceLen) { - PrintAndLogEx(NORMAL, "tracepos: %i", tracepos); - PrintAndLogEx(NORMAL, "traceLen: %i", traceLen); - - if (tracepos + 3 >= traceLen) break; - - uint16_t gap = *((uint16_t *)(trace + tracepos)); - uint8_t crc_ok = trace[tracepos + 2]; - tracepos += 3; - - if (tracepos + 3 >= traceLen) break; - - uint16_t len = trace[tracepos + 2]; - PrintAndLogEx(NORMAL, "LEN: %i", len); - - //I am stripping SYNC - tracepos += 3; //skip SYNC - - if (tracepos + len + 1 >= traceLen) break; - - uint8_t cmd = trace[tracepos]; - uint8_t isResponse = cmd & 1; - - char line[32][110] = {{0}}; - for (int j = 0; j < len + 1 && j / 8 < 32; j++) { - snprintf(line[j / 8] + ((j % 8) * 4), 110, " %02x ", trace[tracepos + j]); - } - char expbuf[50]; - switch (cmd) { - case FELICA_POLL_REQ: - snprintf(expbuf, 49, "Poll Req"); - break; - case FELICA_POLL_ACK: - snprintf(expbuf, 49, "Poll Resp"); - break; - - case FELICA_REQSRV_REQ: - snprintf(expbuf, 49, "Request Srvc Req"); - break; - case FELICA_REQSRV_ACK: - snprintf(expbuf, 49, "Request Srv Resp"); - break; - - case FELICA_RDBLK_REQ: - snprintf(expbuf, 49, "Read block(s) Req"); - break; - case FELICA_RDBLK_ACK: - snprintf(expbuf, 49, "Read block(s) Resp"); - break; - - case FELICA_WRTBLK_REQ: - snprintf(expbuf, 49, "Write block(s) Req"); - break; - case FELICA_WRTBLK_ACK: - snprintf(expbuf, 49, "Write block(s) Resp"); - break; - case FELICA_SRCHSYSCODE_REQ: - snprintf(expbuf, 49, "Search syscode Req"); - break; - case FELICA_SRCHSYSCODE_ACK: - snprintf(expbuf, 49, "Search syscode Resp"); - break; - - case FELICA_REQSYSCODE_REQ: - snprintf(expbuf, 49, "Request syscode Req"); - break; - case FELICA_REQSYSCODE_ACK: - snprintf(expbuf, 49, "Request syscode Resp"); - break; - - case FELICA_AUTH1_REQ: - snprintf(expbuf, 49, "Auth1 Req"); - break; - case FELICA_AUTH1_ACK: - snprintf(expbuf, 49, "Auth1 Resp"); - break; - - case FELICA_AUTH2_REQ: - snprintf(expbuf, 49, "Auth2 Req"); - break; - case FELICA_AUTH2_ACK: - snprintf(expbuf, 49, "Auth2 Resp"); - break; - - case FELICA_RDSEC_REQ: - snprintf(expbuf, 49, "Secure read Req"); - break; - case FELICA_RDSEC_ACK: - snprintf(expbuf, 49, "Secure read Resp"); - break; - - case FELICA_WRTSEC_REQ: - snprintf(expbuf, 49, "Secure write Req"); - break; - case FELICA_WRTSEC_ACK: - snprintf(expbuf, 49, "Secure write Resp"); - break; - - case FELICA_REQSRV2_REQ: - snprintf(expbuf, 49, "Request Srvc v2 Req"); - break; - case FELICA_REQSRV2_ACK: - snprintf(expbuf, 49, "Request Srvc v2 Resp"); - break; - - case FELICA_GETSTATUS_REQ: - snprintf(expbuf, 49, "Get status Req"); - break; - case FELICA_GETSTATUS_ACK: - snprintf(expbuf, 49, "Get status Resp"); - break; - - case FELICA_OSVER_REQ: - snprintf(expbuf, 49, "Get OS Version Req"); - break; - case FELICA_OSVER_ACK: - snprintf(expbuf, 49, "Get OS Version Resp"); - break; - - case FELICA_RESET_MODE_REQ: - snprintf(expbuf, 49, "Reset mode Req"); - break; - case FELICA_RESET_MODE_ACK: - snprintf(expbuf, 49, "Reset mode Resp"); - break; - - case FELICA_AUTH1V2_REQ: - snprintf(expbuf, 49, "Auth1 v2 Req"); - break; - case FELICA_AUTH1V2_ACK: - snprintf(expbuf, 49, "Auth1 v2 Resp"); - break; - - case FELICA_AUTH2V2_REQ: - snprintf(expbuf, 49, "Auth2 v2 Req"); - break; - case FELICA_AUTH2V2_ACK: - snprintf(expbuf, 49, "Auth2 v2 Resp"); - break; - - case FELICA_RDSECV2_REQ: - snprintf(expbuf, 49, "Secure read v2 Req"); - break; - case FELICA_RDSECV2_ACK: - snprintf(expbuf, 49, "Secure read v2 Resp"); - break; - case FELICA_WRTSECV2_REQ: - snprintf(expbuf, 49, "Secure write v2 Req"); - break; - case FELICA_WRTSECV2_ACK: - snprintf(expbuf, 49, "Secure write v2 Resp"); - break; - - case FELICA_UPDATE_RNDID_REQ: - snprintf(expbuf, 49, "Update IDr Req"); - break; - case FELICA_UPDATE_RNDID_ACK: - snprintf(expbuf, 49, "Update IDr Resp"); - break; - default: - snprintf(expbuf, 49, "Unknown"); - break; - } - - int num_lines = MIN((len) / 16 + 1, 16); - for (int j = 0; j < num_lines ; j++) { - if (j == 0) { - PrintAndLogEx(NORMAL, "%7d | %s |%-32s |%02x %02x %s| %s", - gap, - (isResponse ? "Tag" : "Rdr"), - line[j], - trace[tracepos + len], - trace[tracepos + len + 1], - (crc_ok) ? "OK" : "NG", - expbuf); - } else { - PrintAndLogEx(NORMAL, " | |%-32s | | ", line[j]); - } - } - tracepos += len + 1; - } - PrintAndLogEx(NORMAL, ""); -}*/ // sanity check. Don't use proxmark if it is offline and you didn't specify useTraceBuffer /* @@ -857,6 +664,7 @@ int CmdTraceList(const char *Cmd) { if (protocol == PROTO_HITAG) PrintAndLogEx(NORMAL, "Hitag2 / HitagS - Timings in ETU (8us)"); if (protocol == FELICA) + PrintAndLogEx(NORMAL, "ISO18092 / FeliCa - Timings are not as accurate"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, " Start | End | Src | Data (! denotes parity error) | CRC | Annotation"); From 42fd13985f6f862fca2f452f49055eaf3c06070f Mon Sep 17 00:00:00 2001 From: Thomas Sutter Date: Fri, 1 Nov 2019 15:19:09 +0100 Subject: [PATCH 1097/1854] Make style. --- armsrc/felica.c | 10 +++++----- client/cmdhffelica.c | 8 ++++---- client/cmdlffdx.c | 4 ++-- client/cmdtrace.c | 4 ++-- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/armsrc/felica.c b/armsrc/felica.c index c9ebf9969..06bc53e99 100644 --- a/armsrc/felica.c +++ b/armsrc/felica.c @@ -418,7 +418,7 @@ bool WaitForFelicaReply(uint16_t maxbytes) { Process18092Byte(b); if (FelicaFrame.state == STATE_FULL) { felica_nexttransfertime = MAX(felica_nexttransfertime, - (GetCountSspClk() & 0xfffffff8) - (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER) / 16 + FELICA_FRAME_DELAY_TIME); + (GetCountSspClk() & 0xfffffff8) - (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER) / 16 + FELICA_FRAME_DELAY_TIME); LogTrace( FelicaFrame.framebytes, @@ -593,13 +593,13 @@ void felica_sniff(uint32_t samplesToSkip, uint32_t triggersToSkip) { if (FelicaFrame.state == STATE_FULL) { //Dbprintf("Sniffing - Got Felica Frame! Sample remaining %i", remFrames); remFrames--; - if (remFrames <= 0){ + if (remFrames <= 0) { Dbprintf("Stop Sniffing - samplesToSkip reached!"); break; } - if((FelicaFrame.framebytes[3] % 2) == 0){ + if ((FelicaFrame.framebytes[3] % 2) == 0) { isTagFrame = false; // All Reader Frames are even and all Tag frames are odd - } else{ + } else { isTagFrame = true; } LogTrace(FelicaFrame.framebytes, @@ -608,7 +608,7 @@ void felica_sniff(uint32_t samplesToSkip, uint32_t triggersToSkip) { ((GetCountSspClk() & 0xfffffff8) << 4) - DELAY_AIR2ARM_AS_READER, NULL, isTagFrame - ); + ); numbts += FelicaFrame.len; FelicaFrameReset(); } diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index 427ca07c1..03bd390c2 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -795,7 +795,7 @@ static int CmdHFFelicaSniff(const char *Cmd) { paramCount++; if (param_getlength(Cmd, paramCount) < 5) { samples2skip = param_get32ex(Cmd, paramCount++, 0, 10); - }else{ + } else { PrintAndLogEx(ERR, "Invalid samples number!"); return PM3_EINVARG; } @@ -805,7 +805,7 @@ static int CmdHFFelicaSniff(const char *Cmd) { paramCount++; if (param_getlength(Cmd, paramCount) < 5) { triggers2skip = param_get32ex(Cmd, paramCount++, 0, 10); - }else{ + } else { PrintAndLogEx(ERR, "Invalid triggers number!"); return PM3_EINVARG; } @@ -818,11 +818,11 @@ static int CmdHFFelicaSniff(const char *Cmd) { } i++; } - if(samples2skip <= 0){ + if (samples2skip <= 0) { samples2skip = 10; PrintAndLogEx(INFO, "Set default samples2skip: %i", samples2skip); } - if(triggers2skip <= 0){ + if (triggers2skip <= 0) { triggers2skip = 5000; PrintAndLogEx(INFO, "Set default triggers2skip: %i", triggers2skip); } diff --git a/client/cmdlffdx.c b/client/cmdlffdx.c index 17dbd2fd0..06e45f515 100644 --- a/client/cmdlffdx.c +++ b/client/cmdlffdx.c @@ -243,7 +243,7 @@ static int CmdFdxDemod(const char *Cmd) { uint8_t c[] = {0, 0}; compute_crc(CRC_11784, raw, sizeof(raw), &c[0], &c[1]); - PrintAndLogEx(SUCCESS, "CRC-16 0x%04X [ %s] ", crc, (crc == (c[1] << 8 | c[0]) ) ? _GREEN_("OK") : _RED_("Fail")); + PrintAndLogEx(SUCCESS, "CRC-16 0x%04X [ %s] ", crc, (crc == (c[1] << 8 | c[0])) ? _GREEN_("OK") : _RED_("Fail")); if (g_debugMode) { PrintAndLogEx(DEBUG, "Start marker %d; Size %zu", preambleIndex, size); @@ -313,7 +313,7 @@ static int CmdFdxSim(const char *Cmd) { countryid = param_get32ex(Cmd, 0, 0, 10); animalid = param_get64ex(Cmd, 1, 0, 10); - extended = param_get32ex(Cmd, 2, 0 , 10); + extended = param_get32ex(Cmd, 2, 0, 10); verify_values(&animalid, &countryid); diff --git a/client/cmdtrace.c b/client/cmdtrace.c index 77aab71e5..67f15be59 100644 --- a/client/cmdtrace.c +++ b/client/cmdtrace.c @@ -257,7 +257,7 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr case ISO_14443B: case TOPAZ: case FELICA: - crcStatus = !felica_CRC_check(frame+2, data_len-4); + crcStatus = !felica_CRC_check(frame + 2, data_len - 4); break; case PROTO_MIFARE: crcStatus = mifare_CRC_check(isResponse, frame, data_len); @@ -350,7 +350,7 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr if (protocol == PROTO_MIFARE) annotateMifare(explanation, sizeof(explanation), frame, data_len, parityBytes, parity_len, isResponse); - if(protocol == FELICA) + if (protocol == FELICA) annotateFelica(explanation, sizeof(explanation), frame, data_len); if (!isResponse) { From b4c1333ac34924dd41bfcbf38041a03d81cc2f25 Mon Sep 17 00:00:00 2001 From: Thomas Sutter Date: Fri, 1 Nov 2019 15:37:53 +0100 Subject: [PATCH 1098/1854] Remove unused comments. Change boolean for src. --- armsrc/felica.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/armsrc/felica.c b/armsrc/felica.c index 06bc53e99..1a3b6f6ac 100644 --- a/armsrc/felica.c +++ b/armsrc/felica.c @@ -580,7 +580,7 @@ void felica_sniff(uint32_t samplesToSkip, uint32_t triggersToSkip) { uint16_t numbts = 0; int trigger_cnt = 0; uint32_t timeout = iso18092_get_timeout(); - bool isTagFrame = true; + bool isReaderFrame = true; while (!BUTTON_PRESS()) { WDT_HIT(); if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { @@ -591,23 +591,22 @@ void felica_sniff(uint32_t samplesToSkip, uint32_t triggersToSkip) { break; } if (FelicaFrame.state == STATE_FULL) { - //Dbprintf("Sniffing - Got Felica Frame! Sample remaining %i", remFrames); + if ((FelicaFrame.framebytes[3] % 2) == 0) { + isReaderFrame = true; // All Reader Frames are even and all Tag frames are odd + } else { + isReaderFrame = false; + } remFrames--; if (remFrames <= 0) { Dbprintf("Stop Sniffing - samplesToSkip reached!"); break; } - if ((FelicaFrame.framebytes[3] % 2) == 0) { - isTagFrame = false; // All Reader Frames are even and all Tag frames are odd - } else { - isTagFrame = true; - } LogTrace(FelicaFrame.framebytes, FelicaFrame.len, ((GetCountSspClk() & 0xfffffff8) << 4) - DELAY_AIR2ARM_AS_READER - timeout, ((GetCountSspClk() & 0xfffffff8) << 4) - DELAY_AIR2ARM_AS_READER, NULL, - isTagFrame + isReaderFrame ); numbts += FelicaFrame.len; FelicaFrameReset(); From c76c59a35c2d21f05f75620418ed93b8f2e927da Mon Sep 17 00:00:00 2001 From: Thomas Sutter Date: Sat, 2 Nov 2019 13:29:38 +0100 Subject: [PATCH 1099/1854] Fix segmentation fault in cmd. --- client/cmdhffelica.c | 1 + 1 file changed, 1 insertion(+) diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index 03bd390c2..d1714c3a0 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -246,6 +246,7 @@ static bool waitCmdFelica(uint8_t iSelect, PacketResponseNG *resp, bool verbose) PrintAndLogEx(NORMAL, "Client Received %i octets", len); if (!len || len < 2) { PrintAndLogEx(ERR, "Could not receive data correctly!"); + return false; } PrintAndLogEx(NORMAL, "%s", sprint_hex(resp->data.asBytes, len)); if (!check_crc(CRC_FELICA, resp->data.asBytes + 2, len - 2)) { From 025234ba2b3a8a1aa3e44940b65b28fc439537cc Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 2 Nov 2019 17:29:20 +0100 Subject: [PATCH 1100/1854] yes --- client/cmdlfjablotron.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/client/cmdlfjablotron.c b/client/cmdlfjablotron.c index a1f5b0592..68671ebe7 100644 --- a/client/cmdlfjablotron.c +++ b/client/cmdlfjablotron.c @@ -117,9 +117,12 @@ static int CmdJablotronDemod(const char *Cmd) { PrintAndLogEx(SUCCESS, "Jablotron Tag Found: Card ID: %"PRIx64" :: Raw: %08X%08X", id, raw1, raw2); uint8_t chksum = raw2 & 0xFF; - PrintAndLogEx(INFO, "Checksum: %02X [%s]", + bool isok = (chksum == jablontron_chksum(DemodBuffer)); + + PrintAndLogEx( isok ? SUCCESS : INFO, + "Checksum: %02X [ %s]", chksum, - (chksum == jablontron_chksum(DemodBuffer)) ? _GREEN_("OK") : _RED_("Fail") + isok ? _GREEN_("OK") : _RED_("Fail") ); id = DEC2BCD(id); @@ -142,9 +145,6 @@ static int CmdJablotronClone(const char *Cmd) { uint64_t fullcode = 0; uint32_t blocks[3] = {T55x7_MODULATION_DIPHASE | T55x7_BITRATE_RF_64 | 2 << T55x7_MAXBLOCK_SHIFT, 0, 0}; - uint8_t bits[64]; - memset(bits, 0, sizeof(bits)); - char cmdp = tolower(param_getchar(Cmd, 0)); if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_jablotron_clone(); @@ -160,6 +160,12 @@ static int CmdJablotronClone(const char *Cmd) { PrintAndLogEx(INFO, "Card Number Truncated to 39bits: %"PRIx64, fullcode); } + uint8_t *bits = calloc(64, sizeof(uint8_t)); + if (bits == NULL) { + PrintAndLogEx(WARNING, "Failed to allocate memory"); + return PM3_EMALLOC; + } + if (getJablotronBits(fullcode, bits) != PM3_SUCCESS) { PrintAndLogEx(ERR, "Error with tag bitstream generation."); return PM3_ESOFT; From 06076708a7676f5c7f9dcf1c4ea1406e6286356b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 2 Nov 2019 17:59:06 +0100 Subject: [PATCH 1101/1854] chg: less stack pressure. And now also free:ing --- client/cmdlfjablotron.c | 39 +++++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/client/cmdlfjablotron.c b/client/cmdlfjablotron.c index 68671ebe7..a3692fb60 100644 --- a/client/cmdlfjablotron.c +++ b/client/cmdlfjablotron.c @@ -26,6 +26,8 @@ #include "lfdemod.h" // parityTest #include "cmdlft55xx.h" // verifywrite +#define JABLOTRON_ARR_LEN 64 + static int CmdHelp(const char *Cmd); static int usage_lf_jablotron_clone(void) { @@ -103,7 +105,7 @@ static int CmdJablotronDemod(const char *Cmd) { return PM3_ESOFT; } - setDemodBuff(DemodBuffer, 64, ans); + setDemodBuff(DemodBuffer, JABLOTRON_ARR_LEN, ans); setClockGrid(g_DemodClock, g_DemodStartIdx + (ans * g_DemodClock)); //got a good demod @@ -117,8 +119,8 @@ static int CmdJablotronDemod(const char *Cmd) { PrintAndLogEx(SUCCESS, "Jablotron Tag Found: Card ID: %"PRIx64" :: Raw: %08X%08X", id, raw1, raw2); uint8_t chksum = raw2 & 0xFF; - bool isok = (chksum == jablontron_chksum(DemodBuffer)); - + bool isok = (chksum == jablontron_chksum(DemodBuffer)); + PrintAndLogEx( isok ? SUCCESS : INFO, "Checksum: %02X [ %s]", chksum, @@ -151,7 +153,7 @@ static int CmdJablotronClone(const char *Cmd) { fullcode = param_get64ex(Cmd, 0, 0, 16); //Q5 - if (param_getchar(Cmd, 1) == 'Q' || param_getchar(Cmd, 1) == 'q') + if (tolower(param_getchar(Cmd, 1)) == 'q') blocks[0] = T5555_MODULATION_BIPHASE | T5555_INVERT_OUTPUT | T5555_SET_BITRATE(64) | 2 << T5555_MAXBLOCK_SHIFT; // clearing the topbit needed for the preambl detection. @@ -160,11 +162,11 @@ static int CmdJablotronClone(const char *Cmd) { PrintAndLogEx(INFO, "Card Number Truncated to 39bits: %"PRIx64, fullcode); } - uint8_t *bits = calloc(64, sizeof(uint8_t)); - if (bits == NULL) { + uint8_t *bits = calloc(JABLOTRON_ARR_LEN, sizeof(uint8_t)); + if (bits == NULL) { PrintAndLogEx(WARNING, "Failed to allocate memory"); - return PM3_EMALLOC; - } + return PM3_EMALLOC; + } if (getJablotronBits(fullcode, bits) != PM3_SUCCESS) { PrintAndLogEx(ERR, "Error with tag bitstream generation."); @@ -174,6 +176,8 @@ static int CmdJablotronClone(const char *Cmd) { blocks[1] = bytebits_to_byte(bits, 32); blocks[2] = bytebits_to_byte(bits + 32, 32); + free(bits); + PrintAndLogEx(INFO, "Preparing to clone Jablotron to T55x7 with FullCode: %"PRIx64, fullcode); print_blocks(blocks, ARRAYLEN(blocks)); @@ -196,18 +200,25 @@ static int CmdJablotronSim(const char *Cmd) { PrintAndLogEx(SUCCESS, "Simulating Jablotron - FullCode: %"PRIx64, fullcode); - uint8_t bs[64]; + uint8_t *bs = calloc(JABLOTRON_ARR_LEN, sizeof(uint8_t)); + if (bs == NULL) { + PrintAndLogEx(WARNING, "Failed to allocate memory"); + return PM3_EMALLOC; + } + getJablotronBits(fullcode, bs); - lf_asksim_t *payload = calloc(1, sizeof(lf_asksim_t) + sizeof(bs)); + lf_asksim_t *payload = calloc(1, sizeof(lf_asksim_t) + JABLOTRON_ARR_LEN); payload->encoding = 2; payload->invert = 1; payload->separator = 0; payload->clock = 64; - memcpy(payload->data, bs, sizeof(bs)); + memcpy(payload->data, bs, JABLOTRON_ARR_LEN); + + free(bs); clearCommandBuffer(); - SendCommandNG(CMD_LF_ASK_SIMULATE, (uint8_t *)payload, sizeof(lf_asksim_t) + sizeof(bs)); + SendCommandNG(CMD_LF_ASK_SIMULATE, (uint8_t *)payload, sizeof(lf_asksim_t) + JABLOTRON_ARR_LEN); free(payload); PacketResponseNG resp; @@ -257,12 +268,12 @@ int getJablotronBits(uint64_t fullcode, uint8_t *bits) { // the parameter *bits needs to be demoded before call // 0xFFFF preamble, 64bits int detectJablotron(uint8_t *bits, size_t *size) { - if (*size < 64 * 2) return -1; //make sure buffer has enough data + if (*size < JABLOTRON_ARR_LEN * 2) return -1; //make sure buffer has enough data size_t startIdx = 0; uint8_t preamble[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}; if (preambleSearch(bits, preamble, sizeof(preamble), size, &startIdx) == 0) return -2; //preamble not found - if (*size != 64) return -3; // wrong demoded size + if (*size != JABLOTRON_ARR_LEN) return -3; // wrong demoded size uint8_t checkchksum = jablontron_chksum(bits + startIdx); uint8_t crc = bytebits_to_byte(bits + startIdx + 56, 8); From f7256b77f747f691a6a7312fd730d299f47e13cf Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 2 Nov 2019 18:10:39 +0100 Subject: [PATCH 1102/1854] fix: lf fdx sim - now two pm3 (one sim other read) will detect. Also works against proper verichip reader. --- armsrc/lfops.c | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/armsrc/lfops.c b/armsrc/lfops.c index f4f3a9e7b..b929f10a4 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -1045,6 +1045,16 @@ static void leadingZeroAskSimBits(int *n, uint8_t clock) { memset(dest + (*n), 0, clock * 8); *n += clock * 8; } +/* +static void leadingZeroBiphaseSimBits(int *n, uint8_t clock, uint8_t *phase) { + uint8_t *dest = BigBuf_get_addr(); + for (uint8_t i = 0; i < 8; i++) { + memset(dest + (*n), 0 ^ *phase, clock); + *phase ^= 1; + *n += clock; + } +} +*/ // args clock, ask/man or askraw, invert, transmission separator @@ -1054,10 +1064,14 @@ void CmdASKsimTAG(uint8_t encoding, uint8_t invert, uint8_t separator, uint8_t c int n = 0, i = 0; - leadingZeroAskSimBits(&n, clk); - if (encoding == 2) { //biphase uint8_t phase = 0; + +// iceman, if I add this, the demod includes these extra zero and detection fails. +// now, I only need to figure out just to add carrier without modulation +// the old bug, with adding ask zeros messed up the phase variable and deteion failed because of it in LF FDX +// leadingZeroBiphaseSimBits(&n, clk, &phase); + for (i = 0; i < size; i++) { biphaseSimBit(bits[i] ^ invert, &n, clk, &phase); } @@ -1067,6 +1081,9 @@ void CmdASKsimTAG(uint8_t encoding, uint8_t invert, uint8_t separator, uint8_t c } } } else { // ask/manchester || ask/raw + + leadingZeroAskSimBits(&n, clk); + for (i = 0; i < size; i++) { askSimBit(bits[i] ^ invert, &n, clk, encoding); } @@ -1083,7 +1100,14 @@ void CmdASKsimTAG(uint8_t encoding, uint8_t invert, uint8_t separator, uint8_t c WDT_HIT(); - Dbprintf("Simulating with clk: %d, invert: %d, encoding: %d, separator: %d, n: %d", clk, invert, encoding, separator, n); + Dbprintf("Simulating with clk: %d, invert: %d, encoding: %s (%d), separator: %d, n: %d" + , clk + , invert + , (encoding == 2) ? "BI" : (encoding == 1) ? "ASK" : "RAW" + , encoding + , separator + , n + ); if (ledcontrol) LED_A_ON(); SimulateTagLowFrequency(n, 0, ledcontrol); From 85acdfe1090668a3afd0e46cf34ce1b92146e9d3 Mon Sep 17 00:00:00 2001 From: bogiton <34060135+bogiton@users.noreply.github.com> Date: Sat, 2 Nov 2019 18:06:02 +0000 Subject: [PATCH 1103/1854] Update hf_bog.c --- armsrc/Standalone/hf_bog.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/armsrc/Standalone/hf_bog.c b/armsrc/Standalone/hf_bog.c index 5e84d4cc1..ac0bb7749 100644 --- a/armsrc/Standalone/hf_bog.c +++ b/armsrc/Standalone/hf_bog.c @@ -216,13 +216,11 @@ void RAMFUNC SniffAndStore(uint8_t param) { if (auth_attempts > 0) { if (DBGLEVEL > 1) Dbprintf("[!] Authentication attempts = %u", auth_attempts); - size_t size = 4 * auth_attempts; - uint8_t *buf = BigBuf_malloc(size); if (!exists_in_spiffs((char *)HF_BOG_LOGFILE)) { - rdv40_spiffs_write((char *)HF_BOG_LOGFILE, buf, size, RDV40_SPIFFS_SAFETY_SAFE); + rdv40_spiffs_write((char *)HF_BOG_LOGFILE, capturedPwds, 4 * auth_attempts, RDV40_SPIFFS_SAFETY_SAFE); } else { - rdv40_spiffs_append((char *)HF_BOG_LOGFILE, buf, size, RDV40_SPIFFS_SAFETY_SAFE); + rdv40_spiffs_append((char *)HF_BOG_LOGFILE, capturedPwds, 4 * auth_attempts, RDV40_SPIFFS_SAFETY_SAFE); } } From 22b7d54362b9a5bf9cb876c600b3d5a1c3d02ab6 Mon Sep 17 00:00:00 2001 From: bogiton <34060135+bogiton@users.noreply.github.com> Date: Sat, 2 Nov 2019 18:07:36 +0000 Subject: [PATCH 1104/1854] Add GetFromFlashMemSpiffs in scripting.c --- client/scripting.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/client/scripting.c b/client/scripting.c index 43bcbd9c7..6ad9bc0fc 100644 --- a/client/scripting.c +++ b/client/scripting.c @@ -304,6 +304,61 @@ static int l_GetFromFlashMem(lua_State *L) { } +/** + * @brief The following params expected: + * uint8_t *destfilename + * @param L + * @return + */ +static int l_GetFromFlashMemSpiffs(lua_State *L) { + + if (IfPm3Flash()) { + uint32_t start_index = 0, len = 0x40000; //FLASH_MEM_MAX_SIZE + char destfilename[32] = {0}; + size_t size; + + int n = lua_gettop(L); + if (n == 0) + return returnToLuaWithError(L, "You need to supply the destination filename"); + + if (n >= 1) { + const char *p_filename = luaL_checklstring(L, 1, &size); + if (size != 0) + memcpy(destfilename, p_filename, 31); + } + + if (destfilename[0] == '\0') + return returnToLuaWithError(L, "Filename missing or invalid"); + + // get size from spiffs itself ! + SendCommandMIX(CMD_SPIFFS_STAT, 0, 0, 0, (uint8_t *)destfilename, 32); + PacketResponseNG resp; + if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) + return returnToLuaWithError(L, "No response from the device"); + + len = resp.oldarg[0]; + + if (len <= 0) + return returnToLuaWithError(L, "Filename invalid or empty"); + + uint8_t *data = calloc(len, sizeof(uint8_t)); + if (!data) + return returnToLuaWithError(L, "Allocating memory failed"); + + if (!GetFromDevice(SPIFFS, data, len, start_index, (uint8_t *)destfilename, 32, NULL, -1, true)) { + free(data); + return returnToLuaWithError(L, "ERROR; downloading from spiffs(flashmemory)"); + } + + lua_pushlstring(L, (const char *)data, len); + lua_pushunsigned(L, len); + free(data); + return 2; + } else { + return returnToLuaWithError(L, "No FLASH MEM support"); + } +} + /** * @brief The following params expected: * uint32_t cmd @@ -1128,6 +1183,7 @@ int set_pm3_libraries(lua_State *L) { {"SendCommandNG", l_SendCommandNG}, {"GetFromBigBuf", l_GetFromBigBuf}, {"GetFromFlashMem", l_GetFromFlashMem}, + {"GetFromFlashMemSpiffs", l_GetFromFlashMemSpiffs}, {"WaitForResponseTimeout", l_WaitForResponseTimeout}, {"mfDarkside", l_mfDarkside}, {"foobar", l_foobar}, From 7a79901ed0633d6ba981ec523657275f287bf63f Mon Sep 17 00:00:00 2001 From: bogiton <34060135+bogiton@users.noreply.github.com> Date: Sat, 2 Nov 2019 18:08:59 +0000 Subject: [PATCH 1105/1854] Add read_pwd_mem_spiffs.lua --- client/luascripts/read_pwd_mem_spiffs.lua | 91 +++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 client/luascripts/read_pwd_mem_spiffs.lua diff --git a/client/luascripts/read_pwd_mem_spiffs.lua b/client/luascripts/read_pwd_mem_spiffs.lua new file mode 100644 index 000000000..8dbdac691 --- /dev/null +++ b/client/luascripts/read_pwd_mem_spiffs.lua @@ -0,0 +1,91 @@ +local getopt = require('getopt') +local bin = require('bin') + +copyright = 'Copyright (c) 2019 Bogito. All rights reserved.' +author = 'Bogito' +version = 'v1.1.0' +desc = +[[ +This script will read the flash memory of RDV4 using SPIFFS and print the stored passwords. +It was meant to be used as a help tool after using the BogRun standalone mode. +]] +example = +[[ + -- This will read the hf_bog.log file in SPIFFS and print the stored passwords + script run read_pwd_mem_spiffs + + -- This will read the other.log file in SPIFFS and print the stored passwords + script run read_pwd_mem_spiffs -f other.log +]] +usage = +[[ +Usage: + script run read_pwd_mem_spiffs -h -f + +Arguments: + -h : this help + -f : filename in SPIFFS +]] +--- +-- This is only meant to be used when errors occur +local function oops(err) + print('ERROR:', err) + core.clearCommandBuffer() + return nil, err +end +--- +-- Usage help +local function help() + print(copyright) + print(author) + print(version) + print(desc) + print('Example usage') + print(example) + print(usage) +end +--- +-- The main entry point +local function main(args) + + print( string.rep('--',20) ) + print('Read passwords stored in memory (SPIFFS)') + print( string.rep('--',20) ) + print() + + local data, length, err + local cnt = 0 + local filename = 'hf_bog.log' + local keylength = 4 + + for o, a in getopt.getopt(args, 'f:h') do + + -- help + if o == 'h' then return help() end + + -- offset + if o == 'f' then filename = a end + + end + + data, length, err = core.GetFromFlashMemSpiffs(filename) + if data == nil then return oops('Problem while reading file from SPIFFS') end + + --print('Filename', filename) + --print('Filesize (B)', length) + + _, s = bin.unpack('H'..length, data) + + local cnt = 0, i + for i = 1, length/keylength do + key = string.sub(s, (i-1)*8+1, i*8) + if key == 'FFFFFFFF' then break end + print(string.format('[%02d] %s',i, key)) + cnt = cnt + 1 + end + print( string.rep('--',20) ) + print( ('[+] found %d passwords'):format(cnt)) + +end + +main(args) From 601b8d281a38e15491bf64db11bf32fb2c651a3b Mon Sep 17 00:00:00 2001 From: Thomas Sutter Date: Mon, 4 Nov 2019 10:24:29 +0100 Subject: [PATCH 1106/1854] Add command request system code. Add command request specification version. Add command reset mode. Make Style. --- client/cmdhffelica.c | 286 ++++++++++++++++++++++++++++++++++++++++++- include/mifare.h | 15 +++ 2 files changed, 296 insertions(+), 5 deletions(-) diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index d1714c3a0..fe11d4c60 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -224,13 +224,61 @@ static int usage_hf_felica_write_without_encryption() { PrintAndLogEx(NORMAL, " - Un-/Successful read: Card responses with Status Flag1 and Flag2"); print_status_flag1_interpretation(); print_status_flag2_interpration(); - PrintAndLogEx(NORMAL, "\nUsage: hf felica wrunencrypted [-h] <01 Number of Service hex> <0A0B Service Code List (Little Endian) hex> <01 Number of Block hex> <0A0B Block List Element hex> <0A0B0C0D0E0F... Data hex (16-Byte)>"); + PrintAndLogEx(NORMAL, "\nUsage: hf felica wrunencrypted [-h][-i] <01 Number of Service hex> <0A0B Service Code List (Little Endian) hex> <01 Number of Block hex> <0A0B Block List Element hex> <0A0B0C0D0E0F... Data hex (16-Byte)>"); PrintAndLogEx(NORMAL, " -h this help"); PrintAndLogEx(NORMAL, " -i <0A0B0C ... hex> set custom IDm to use\n"); + PrintAndLogEx(NORMAL, "\nExamples: "); PrintAndLogEx(NORMAL, " hf felica wrunencrypted 01 CB10 01 8001 0102030405060708090A0B0C0D0E0F10"); PrintAndLogEx(NORMAL, " hf felica wrunencrypted -i 11100910C11BC407 01 CB10 01 8001 0102030405060708090A0B0C0D0E0F10\n\n"); + return PM3_SUCCESS; +} + +static int usage_hf_felica_request_system_code() { + PrintAndLogEx(NORMAL, "\nInfo: Use this command to acquire System Code registered to the card."); + PrintAndLogEx(NORMAL, " - If a card is divided into more than one System, this command acquires System Code of each System existing in the card."); + PrintAndLogEx(NORMAL, "\nUsage: hf felica rqsyscode [-h] [-i]"); + PrintAndLogEx(NORMAL, " -h this help"); + PrintAndLogEx(NORMAL, " -i <0A0B0C ... hex> set custom IDm to use"); PrintAndLogEx(NORMAL, "\nExamples: "); - PrintAndLogEx(NORMAL, " hf felica wrunencrypted "); + PrintAndLogEx(NORMAL, " hf felica rqsyscode "); + PrintAndLogEx(NORMAL, " hf felica rqsyscode -i 11100910C11BC407\n\n"); + return PM3_SUCCESS; +} + +static int usage_hf_felica_reset_mode() { + PrintAndLogEx(NORMAL, "\nInfo: Use this command to reset Mode to Mode 0."); + print_status_flag1_interpretation(); + print_status_flag2_interpration(); + PrintAndLogEx(NORMAL, "\nUsage: hf felica resetmode [-h][-i][-r]"); + PrintAndLogEx(NORMAL, " -h this help"); + PrintAndLogEx(NORMAL, " -i <0A0B0C ... hex> set custom IDm to use"); + PrintAndLogEx(NORMAL, " -r <0A0B hex> set custom reserve to use"); + PrintAndLogEx(NORMAL, "\nExamples: "); + PrintAndLogEx(NORMAL, " hf felica resetmode "); + PrintAndLogEx(NORMAL, " hf felica resetmode -r 0001"); + PrintAndLogEx(NORMAL, " hf felica resetmode -i 11100910C11BC407\n\n"); + return PM3_SUCCESS; +} + +static int usage_hf_felica_request_specification_version() { + PrintAndLogEx(NORMAL, "\nInfo: Use this command to acquire the version of card OS."); + PrintAndLogEx(NORMAL, " - Response:"); + PrintAndLogEx(NORMAL, " - Format Version: Fixed value 00h. Provided only if Status Flag1 = 00h."); + PrintAndLogEx(NORMAL, " - Basic Version: Each value of version is expressed in BCD notation . Provided only if Status Flag1 = 00h."); + PrintAndLogEx(NORMAL, " - Number of Option: value = 0: AES card, value = 1: AES/DES card. Provided only if Status Flag1 = 00h."); + PrintAndLogEx(NORMAL, " - Option Version List: Provided only if Status Flag1 = 00h."); + PrintAndLogEx(NORMAL, " - For AES card: not added."); + PrintAndLogEx(NORMAL, " - For AES/DES card: DES option version is added - BCD notation ."); + print_status_flag1_interpretation(); + print_status_flag2_interpration(); + PrintAndLogEx(NORMAL, "\nUsage: hf felica rqspecver [-h][-i][-r]"); + PrintAndLogEx(NORMAL, " -h this help"); + PrintAndLogEx(NORMAL, " -i <0A0B0C ... hex> set custom IDm to use"); + PrintAndLogEx(NORMAL, " -r <0A0B hex> set custom reserve to use"); + PrintAndLogEx(NORMAL, "\nExamples: "); + PrintAndLogEx(NORMAL, " hf felica rqspecver "); + PrintAndLogEx(NORMAL, " hf felica rqspecver -r 0001"); + PrintAndLogEx(NORMAL, " hf felica rqspecver -i 11100910C11BC407\n\n"); return PM3_SUCCESS; } @@ -685,6 +733,234 @@ static int CmdHFFelicaRequestResponse(const char *Cmd) { } +/** + * Command parser for rqspecver + * @param Cmd input data of the user. + * @return client result code. + */ +static int CmdHFFelicaRequestSpecificationVersion(const char *Cmd) { + uint8_t data[PM3_CMD_DATA_SIZE]; + bool custom_IDm = false; + bool custom_reserve = false; + strip_cmds(Cmd); + uint16_t datalen = 12; // Length (1), Command ID (1), IDm (8), Reserved (2) + uint8_t paramCount = 0; + uint8_t flags = 0; + int i = 0; + while (Cmd[i] != '\0') { + if (Cmd[i] == '-') { + switch (Cmd[i + 1]) { + case 'H': + case 'h': + return usage_hf_felica_request_specification_version(); + case 'i': + paramCount++; + custom_IDm = true; + if (!add_param(Cmd, paramCount, data, 2, 16)) { + return PM3_EINVARG; + } + paramCount++; + i += 16; + break; + case 'r': + paramCount++; + custom_reserve = true; + if (!add_param(Cmd, paramCount, data, 10, 4)) { + return PM3_EINVARG; + } + paramCount++; + i += 4; + break; + default: + return usage_hf_felica_request_specification_version(); + } + } + i++; + } + data[0] = 0x0C; // Static length + data[1] = 0x3C; // Command ID + if (!custom_reserve) { + data[10] = 0x00; // Reserved Value + data[11] = 0x00; // Reserved Value + } + if (!custom_IDm && !check_last_idm(data, datalen)) { + return PM3_EINVARG; + } + AddCrc(data, datalen); + datalen += 2; + flags |= FELICA_APPEND_CRC; + flags |= FELICA_RAW; + clear_and_send_command(flags, datalen, data, 0); + PacketResponseNG resp; + if (!waitCmdFelica(0, &resp, 1)) { + PrintAndLogEx(ERR, "\nGot no Response from card"); + return PM3_ERFTRANS; + } else { + felica_request_spec_response_t spec_response; + memcpy(&spec_response, (felica_request_spec_response_t *)resp.data.asBytes, sizeof(felica_request_spec_response_t)); + if (spec_response.frame_response.IDm[0] != 0) { + PrintAndLogEx(SUCCESS, "\nGot Request Response:"); + PrintAndLogEx(NORMAL, "\nIDm: %s", sprint_hex(spec_response.frame_response.IDm, sizeof(spec_response.frame_response.IDm))); + PrintAndLogEx(NORMAL, "Status Flag1: %s", sprint_hex(spec_response.status_flags.status_flag1, sizeof(spec_response.status_flags.status_flag1))); + PrintAndLogEx(NORMAL, "Status Flag2: %s", sprint_hex(spec_response.status_flags.status_flag2, sizeof(spec_response.status_flags.status_flag2))); + if (spec_response.status_flags.status_flag1[0] == 0x00) { + PrintAndLogEx(NORMAL, "Format Version: %s", sprint_hex(spec_response.format_version, sizeof(spec_response.format_version))); + PrintAndLogEx(NORMAL, "Basic Version: %s", sprint_hex(spec_response.basic_version, sizeof(spec_response.basic_version))); + PrintAndLogEx(NORMAL, "Number of Option: %s", sprint_hex(spec_response.number_of_option, sizeof(spec_response.number_of_option))); + if (spec_response.number_of_option[0] == 0x01) { + PrintAndLogEx(NORMAL, "Option Version List:"); + for (uint8_t i = 0; i < spec_response.number_of_option[0]; i++) { + PrintAndLogEx(NORMAL, " - %s", sprint_hex(spec_response.option_version_list + i * 2, sizeof(uint8_t) * 2)); + } + } + } + } + } + return PM3_SUCCESS; +} + + +/** + * Command parser for resetmode + * @param Cmd input data of the user. + * @return client result code. + */ +static int CmdHFFelicaResetMode(const char *Cmd) { + uint8_t data[PM3_CMD_DATA_SIZE]; + bool custom_IDm = false; + bool custom_reserve = false; + strip_cmds(Cmd); + uint16_t datalen = 12; // Length (1), Command ID (1), IDm (8), Reserved (2) + uint8_t paramCount = 0; + uint8_t flags = 0; + int i = 0; + while (Cmd[i] != '\0') { + if (Cmd[i] == '-') { + switch (Cmd[i + 1]) { + case 'H': + case 'h': + return usage_hf_felica_reset_mode(); + case 'i': + paramCount++; + custom_IDm = true; + if (!add_param(Cmd, paramCount, data, 2, 16)) { + return PM3_EINVARG; + } + paramCount++; + i += 16; + break; + case 'r': + paramCount++; + custom_reserve = true; + if (!add_param(Cmd, paramCount, data, 10, 4)) { + return PM3_EINVARG; + } + paramCount++; + i += 4; + break; + default: + return usage_hf_felica_reset_mode(); + } + } + i++; + } + data[0] = 0x0C; // Static length + data[1] = 0x3E; // Command ID + if (!custom_reserve) { + data[10] = 0x00; // Reserved Value + data[11] = 0x00; // Reserved Value + } + if (!custom_IDm && !check_last_idm(data, datalen)) { + return PM3_EINVARG; + } + AddCrc(data, datalen); + datalen += 2; + flags |= FELICA_APPEND_CRC; + flags |= FELICA_RAW; + clear_and_send_command(flags, datalen, data, 0); + PacketResponseNG resp; + if (!waitCmdFelica(0, &resp, 1)) { + PrintAndLogEx(ERR, "\nGot no Response from card"); + return PM3_ERFTRANS; + } else { + felica_status_response_t reset_mode_response; + memcpy(&reset_mode_response, (felica_status_response_t *)resp.data.asBytes, sizeof(felica_status_response_t)); + if (reset_mode_response.frame_response.IDm[0] != 0) { + PrintAndLogEx(SUCCESS, "\nGot Request Response:"); + PrintAndLogEx(NORMAL, "\nIDm: %s", sprint_hex(reset_mode_response.frame_response.IDm, sizeof(reset_mode_response.frame_response.IDm))); + PrintAndLogEx(NORMAL, "Status Flag1: %s", sprint_hex(reset_mode_response.status_flags.status_flag1, sizeof(reset_mode_response.status_flags.status_flag1))); + PrintAndLogEx(NORMAL, "Status Flag2: %s\n", sprint_hex(reset_mode_response.status_flags.status_flag2, sizeof(reset_mode_response.status_flags.status_flag2))); + } + } + return PM3_SUCCESS; +} + + + +/** + * Command parser for rqsyscode + * @param Cmd input data of the user. + * @return client result code. + */ +static int CmdHFFelicaRequestSystemCode(const char *Cmd) { + uint8_t data[PM3_CMD_DATA_SIZE]; + bool custom_IDm = false; + strip_cmds(Cmd); + uint16_t datalen = 10; // Length (1), Command ID (1), IDm (8) + uint8_t paramCount = 0; + uint8_t flags = 0; + int i = 0; + while (Cmd[i] != '\0') { + if (Cmd[i] == '-') { + switch (Cmd[i + 1]) { + case 'H': + case 'h': + return usage_hf_felica_request_system_code(); + case 'i': + paramCount++; + custom_IDm = true; + if (!add_param(Cmd, paramCount, data, 2, 16)) { + return PM3_EINVARG; + } + paramCount++; + i += 16; + break; + default: + return usage_hf_felica_request_system_code(); + } + } + i++; + } + data[0] = 0x0A; // Static length + data[1] = 0x0C; // Command ID + if (!custom_IDm && !check_last_idm(data, datalen)) { + return PM3_EINVARG; + } + AddCrc(data, datalen); + datalen += 2; + flags |= FELICA_APPEND_CRC; + flags |= FELICA_RAW; + clear_and_send_command(flags, datalen, data, 0); + PacketResponseNG resp; + if (!waitCmdFelica(0, &resp, 1)) { + PrintAndLogEx(ERR, "\nGot no Response from card"); + return PM3_ERFTRANS; + } else { + felica_syscode_response_t rq_syscode_response; + memcpy(&rq_syscode_response, (felica_syscode_response_t *)resp.data.asBytes, sizeof(felica_syscode_response_t)); + if (rq_syscode_response.frame_response.IDm[0] != 0) { + PrintAndLogEx(SUCCESS, "\nGot Request Response:"); + PrintAndLogEx(NORMAL, "IDm: %s", sprint_hex(rq_syscode_response.frame_response.IDm, sizeof(rq_syscode_response.frame_response.IDm))); + PrintAndLogEx(NORMAL, " - Number of Systems: %s", sprint_hex(rq_syscode_response.number_of_systems, sizeof(rq_syscode_response.number_of_systems))); + PrintAndLogEx(NORMAL, " - System Codes: enumerated in ascending order starting from System 0."); + for (uint8_t i = 0; i < rq_syscode_response.number_of_systems[0]; i++) { + PrintAndLogEx(NORMAL, " - %s", sprint_hex(rq_syscode_response.system_code_list + i * 2, sizeof(uint8_t) * 2)); + } + } + } + return PM3_SUCCESS; +} + /** * Command parser for rqservice. * @param Cmd input data of the user. @@ -1244,15 +1520,15 @@ static command_t CommandTable[] = { {"rdunencrypted", CmdHFFelicaReadWithoutEncryption, IfPm3Felica, "read Block Data from authentication-not-required Service."}, {"wrunencrypted", CmdHFFelicaWriteWithoutEncryption, IfPm3Felica, "write Block Data to an authentication-not-required Service."}, {"scsvcode", CmdHFFelicaNotImplementedYet, IfPm3Felica, "acquire Area Code and Service Code."}, - //{"rqsyscode", CmdHFFelicaNotImplementedYet, IfPm3Felica, "acquire System Code registered to the card."}, + {"rqsyscode", CmdHFFelicaRequestSystemCode, IfPm3Felica, "acquire System Code registered to the card."}, //{"auth1", CmdHFFelicaNotImplementedYet, IfPm3Felica, "authenticate a card."}, //{"auth2", CmdHFFelicaNotImplementedYet, IfPm3Felica, "allow a card to authenticate a Reader/Writer."}, //{"read", CmdHFFelicaNotImplementedYet, IfPm3Felica, "read Block Data from authentication-required Service."}, //{"write", CmdHFFelicaNotImplementedYet, IfPm3Felica, "write Block Data to an authentication-required Service."}, //{"scsvcodev2", CmdHFFelicaNotImplementedYet, IfPm3Felica, "verify the existence of Area or Service, and to acquire Key Version."}, //{"getsysstatus", CmdHFFelicaNotImplementedYet, IfPm3Felica, "acquire the setup information in System."}, - //{"rqspecver", CmdHFFelicaNotImplementedYet, IfPm3Felica, "acquire the version of card OS."}, - //{"resetmode", CmdHFFelicaNotImplementedYet, IfPm3Felica, "reset Mode to Mode 0."}, + {"rqspecver", CmdHFFelicaRequestSpecificationVersion, IfPm3Felica, "acquire the version of card OS."}, + {"resetmode", CmdHFFelicaResetMode, IfPm3Felica, "reset Mode to Mode 0."}, //{"auth1v2", CmdHFFelicaNotImplementedYet, IfPm3Felica, "authenticate a card."}, //{"auth2v2", CmdHFFelicaNotImplementedYet, IfPm3Felica, "allow a card to authenticate a Reader/Writer."}, //{"readv2", CmdHFFelicaNotImplementedYet, IfPm3Felica, "read Block Data from authentication-required Service."}, diff --git a/include/mifare.h b/include/mifare.h index 4a65357e5..e278b3794 100644 --- a/include/mifare.h +++ b/include/mifare.h @@ -205,6 +205,21 @@ typedef struct { felica_status_flags_t status_flags; } PACKED felica_status_response_t; +typedef struct { + felica_frame_response_t frame_response; + uint8_t number_of_systems[1]; + uint8_t system_code_list[32]; +} PACKED felica_syscode_response_t; + +typedef struct { + felica_frame_response_t frame_response; + felica_status_flags_t status_flags; + uint8_t format_version[1]; + uint8_t basic_version[2]; + uint8_t number_of_option[1]; + uint8_t option_version_list[4]; +} PACKED felica_request_spec_response_t; + typedef enum FELICA_COMMAND { FELICA_CONNECT = (1 << 0), FELICA_NO_DISCONNECT = (1 << 1), From c1e88f1a9b43b2009ed902a468eba3e7927d5fcd Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 4 Nov 2019 15:13:59 +0100 Subject: [PATCH 1107/1854] fix: cotag on device side... --- armsrc/lfsampling.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index d168dcc78..48a3f0d97 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -374,8 +374,8 @@ void doT55x7Acquisition(size_t sample_size) { #define COTAG_T1 384 #define COTAG_T2 (COTAG_T1>>1) -#define COTAG_ONE_THRESHOLD 128+30 -#define COTAG_ZERO_THRESHOLD 128-30 +#define COTAG_ONE_THRESHOLD 128+10 +#define COTAG_ZERO_THRESHOLD 128-10 #ifndef COTAG_BITS #define COTAG_BITS 264 #endif @@ -437,6 +437,11 @@ void doCotagAcquisition(size_t sample_size) { dest[i] = dest[i - 1]; } } + + // Ensure that DC offset removal and noise check is performed for any device-side processing + removeSignalOffset(dest, bufsize); + computeSignalProperties(dest, bufsize); + } uint32_t doCotagAcquisitionManchester() { From 68ac8dd979b871697e58e13843aace3d2d4880be Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 4 Nov 2019 15:42:28 +0100 Subject: [PATCH 1108/1854] fix: cotag use NG --- armsrc/lfops.c | 4 ++-- client/cmdlfcotag.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/armsrc/lfops.c b/armsrc/lfops.c index b929f10a4..b5e9b98ec 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -2490,7 +2490,7 @@ void Cotag(uint32_t arg0) { switch (rawsignal) { case 0: - doCotagAcquisition(50000); + doCotagAcquisition(40000); break; case 1: doCotagAcquisitionManchester(); @@ -2502,7 +2502,7 @@ void Cotag(uint32_t arg0) { // Turn the field off FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off - reply_mix(CMD_ACK, 0, 0, 0, 0, 0); + reply_ng(CMD_LF_COTAG_READ, PM3_SUCCESS, NULL, 0); LEDsoff(); } diff --git a/client/cmdlfcotag.c b/client/cmdlfcotag.c index b4e8e96c8..9c55bf453 100644 --- a/client/cmdlfcotag.c +++ b/client/cmdlfcotag.c @@ -86,7 +86,7 @@ static int CmdCOTAGRead(const char *Cmd) { clearCommandBuffer(); SendCommandMIX(CMD_LF_COTAG_READ, rawsignal, 0, 0, NULL, 0); - if (!WaitForResponseTimeout(CMD_ACK, NULL, 7000)) { + if (!WaitForResponseTimeout(CMD_LF_COTAG_READ, NULL, 7000)) { PrintAndLogEx(WARNING, "command execution time out"); return PM3_ETIMEOUT; } From 0980e619bf9e3bab6ec9f0fc3b4cffb5c5c8dd28 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 4 Nov 2019 18:03:23 +0200 Subject: [PATCH 1109/1854] updated aid list --- client/resources/aidlist.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/resources/aidlist.json b/client/resources/aidlist.json index 7ec139d46..86c5ccab1 100644 --- a/client/resources/aidlist.json +++ b/client/resources/aidlist.json @@ -1 +1 @@ -[{"Vendor": "Visa International", "Description": "", "Country": "United States", "AID": "315041592E5359532E4444463031", "Type": "", "Name": "Visa Payment System Environment - PSE (1PAY.SYS.DDF01)"}, {"Vendor": "Visa International", "Description": "Visa payWave for Mobile", "Country": "United States", "AID": "325041592E5359532E4444463031", "Type": "", "Name": "Visa Proximity Payment System Environment - PPSE (2PAY.SYS.DDF01)"}, {"Vendor": "DeviceFidelity", "Description": "http://www.nfcworld.com/2010/11/24/35207/devicefidelity-adds-nfc-support-for-android-and-mifare/", "Country": "United States", "AID": "44464D46412E44466172653234313031", "Type": "", "Name": "DeviceFidelity In2Pay DFare applet"}, {"Vendor": "PBS Danmnt A/S", "Description": "(Unlicensed use of this RID. Proposal to use A000000323 instead)", "Country": "Denmark", "AID": "A00000000101", "Type": "", "Name": "MUSCLE Card Applet"}, {"Vendor": "Visa International", "Description": "Used by most GP2.1.1 cards / Oberthur OP201 cards. Visa Proprietary Card Manager AID for OpenPlatform cards (visa.openplatform).", "Country": "United States", "AID": "A000000003000000", "Type": "GP", "Name": "(VISA) Card Manager"}, {"Vendor": "Visa International", "Description": "", "Country": "United States", "AID": "A00000000300037561", "Type": "", "Name": "Bonuscard"}, {"Vendor": "Visa International", "Description": "", "Country": "United States", "AID": "A00000000305076010", "Type": "EMV", "Name": "VISA ELO Credit"}, {"Vendor": "Visa International", "Description": "Standard/Gold VISA credit card", "Country": "United States", "AID": "A0000000031010", "Type": "EMV", "Name": "VISA Debit/Credit (Classic)"}, {"Vendor": "Visa International", "Description": "", "Country": "United States", "AID": "A000000003101001", "Type": "EMV", "Name": "VISA Credit"}, {"Vendor": "Visa International", "Description": "", "Country": "United States", "AID": "A000000003101002", "Type": "EMV", "Name": "VISA Debit"}, {"Vendor": "Visa International", "Description": "VISA Electron (Debit)", "Country": "United States", "AID": "A0000000032010", "Type": "EMV", "Name": "VISA Electron"}, {"Vendor": "Visa International", "Description": "V PAY", "Country": "United States", "AID": "A0000000032020", "Type": "EMV", "Name": "VISA"}, {"Vendor": "Visa International", "Description": "VISA Interlink", "Country": "United States", "AID": "A0000000033010", "Type": "EMV", "Name": "VISA Interlink"}, {"Vendor": "Visa International", "Description": "Visa Specific", "Country": "United States", "AID": "A0000000034010", "Type": "EMV", "Name": "VISA Specific"}, {"Vendor": "Visa International", "Description": "Visa Specific", "Country": "United States", "AID": "A0000000035010", "Type": "EMV", "Name": "VISA Specific"}, {"Vendor": "Visa International", "Description": "", "Country": "United States", "AID": "A000000003534441", "Type": "GP", "Name": "Schlumberger Security Domain"}, {"Vendor": "Visa International", "Description": "OCS Oberthur Card System Security Domain Package AID / VGP Card Manager (for ISD and ASD)", "Country": "United States", "AID": "A0000000035350", "Type": "GP", "Name": "Security Domain"}, {"Vendor": "Visa International", "Description": "OCS Oberthur Card System Security Domain Applet AID / VGP Card Manager (for ISD and ASD)", "Country": "United States", "AID": "A000000003535041", "Type": "GP", "Name": "Security Domain"}, {"Vendor": "Visa International", "Description": "", "Country": "United States", "AID": "A0000000036010", "Type": "EMV", "Name": "Domestic Visa Cash Stored Value"}, {"Vendor": "Visa International", "Description": "", "Country": "United States", "AID": "A0000000036020", "Type": "EMV", "Name": "International Visa Cash Stored Value"}, {"Vendor": "Visa International", "Description": "VISA Auth dynamic passcode authentication (DPA). Used by Barclays/HBOS", "Country": "United States", "AID": "A0000000038002", "Type": "EMV", "Name": "VISA Auth, VisaRemAuthen EMV-CAP (DPA)"}, {"Vendor": "Visa International", "Description": "VISA plus", "Country": "United States", "AID": "A0000000038010", "Type": "EMV", "Name": "VISA Plus"}, {"Vendor": "Visa International", "Description": "", "Country": "United States", "AID": "A0000000039010", "Type": "EMV", "Name": "VISA Loyalty"}, {"Vendor": "Visa International", "Description": "", "Country": "United States", "AID": "A000000003999910", "Type": "EMV", "Name": "VISA Proprietary ATM"}, {"Vendor": "Mastercard International", "Description": "Security Domain", "Country": "United States", "AID": "A0000000040000", "Type": "GP", "Name": "MasterCard Card Manager"}, {"Vendor": "Mastercard International", "Description": "AEPM (Association Europenne Payez Mobile)", "Country": "United States", "AID": "A00000000401", "Type": "EMV", "Name": "MasterCard PayPass"}, {"Vendor": "Mastercard International", "Description": "Standard MasterCard", "Country": "United States", "AID": "A0000000041010", "Type": "EMV", "Name": "MasterCard Credit"}, {"Vendor": "Mastercard International", "Description": "Standard MasterCard", "Country": "United States", "AID": "A00000000410101213", "Type": "EMV", "Name": "MasterCard Credit"}, {"Vendor": "Mastercard International", "Description": "Standard MasterCard", "Country": "United States", "AID": "A00000000410101215", "Type": "EMV", "Name": "MasterCard Credit"}, {"Vendor": "Mastercard International", "Description": "Some co-branded card?", "Country": "United States", "AID": "A0000000041010BB5449435301", "Type": "", "Name": "[UNKNOWN]"}, {"Vendor": "Mastercard International", "Description": "MasterCard Specific", "Country": "United States", "AID": "A0000000042010", "Type": "EMV", "Name": "MasterCard Specific"}, {"Vendor": "Mastercard International", "Description": "MasterCard U.S. Maestro", "Country": "United States", "AID": "A0000000042203", "Type": "", "Name": "MasterCard Specific"}, {"Vendor": "Mastercard International", "Description": "MasterCard Specific", "Country": "United States", "AID": "A0000000043010", "Type": "EMV", "Name": "MasterCard Specific"}, {"Vendor": "Mastercard International", "Description": "Maestro (Debit) Card", "Country": "United States", "AID": "A0000000043060", "Type": "EMV", "Name": "Maestro (Debit)"}, {"Vendor": "Mastercard International", "Description": "Maestro (Debit) Card", "Country": "United States", "AID": "A000000004306001", "Type": "EMV", "Name": "Maestro (Debit)"}, {"Vendor": "Mastercard International", "Description": "MasterCard Specific", "Country": "United States", "AID": "A0000000044010", "Type": "EMV", "Name": "MasterCard Specific"}, {"Vendor": "Mastercard International", "Description": "MasterCard Specific", "Country": "United States", "AID": "A0000000045010", "Type": "EMV", "Name": "MasterCard Specific"}, {"Vendor": "Mastercard International", "Description": "AID on Cirrus Test Card", "Country": "United States", "AID": "A0000000045555", "Type": "", "Name": "APDULogger"}, {"Vendor": "Mastercard International", "Description": "Mastercard Cirrus (Interbank Network) ATM card only", "Country": "United States", "AID": "A0000000046000", "Type": "EMV", "Name": "Cirrus"}, {"Vendor": "Mastercard International", "Description": "Chip Authentication Protocol (CAP). Works with NatWest or SecureCode Aut", "Country": "United States", "AID": "A0000000048002", "Type": "EMV", "Name": "SecureCode Auth EMV-CAP"}, {"Vendor": "Mastercard International", "Description": "", "Country": "United States", "AID": "A0000000049999", "Type": "EMV", "Name": "MasterCard PayPass??"}, {"Vendor": "Switch Card Services Ltd.", "Description": "UK Domestic Maestro - Switch (debit card)", "Country": "United Kingdom", "AID": "A0000000050001", "Type": "EMV", "Name": "Maestro UK"}, {"Vendor": "Switch Card Services Ltd.", "Description": "UK Domestic Maestro - Switch (debit card)", "Country": "United Kingdom", "AID": "A0000000050002", "Type": "EMV", "Name": "Solo"}, {"Vendor": "ETSI", "Description": "Orange UK", "Country": "France", "AID": "A0000000090001FF44FF1289", "Type": "", "Name": "Orange"}, {"Vendor": "Europay International", "Description": "", "Country": "Belgium", "AID": "A0000000101030", "Type": "", "Name": "Maestro-CH"}, {"Vendor": "GEMPLUS", "Description": "", "Country": "France", "AID": "A00000001800", "Type": "", "Name": "Gemplus ?"}, {"Vendor": "GEMPLUS", "Description": "", "Country": "France", "AID": "A0000000181001", "Type": "", "Name": "com.gemplus.javacard.util packages"}, {"Vendor": "GEMPLUS", "Description": "434D = CM (ascii). Security domain for some GCX/GXP cards (GemXpresso Pro) (Gemalto)", "Country": "France", "AID": "A000000018434D", "Type": "GP", "Name": "Gemplus card manager"}, {"Vendor": "GEMPLUS", "Description": "(Gemalto)", "Country": "France", "AID": "A000000018434D00", "Type": "GP", "Name": "Gemplus Security Domain"}, {"Vendor": "Midland Bank Plc", "Description": "", "Country": "United Kingdom", "AID": "A00000002401", "Type": "EMV", "Name": "Self Service"}, {"Vendor": "American Express", "Description": "", "Country": "United Kingdom", "AID": "A000000025", "Type": "EMV", "Name": "American Express"}, {"Vendor": "American Express", "Description": "American Express (Credit/Debit)", "Country": "United Kingdom", "AID": "A0000000250000", "Type": "EMV", "Name": "American Express"}, {"Vendor": "American Express", "Description": "AEIPS-compliant (A-E contact EMV) payment application", "Country": "United Kingdom", "AID": "A00000002501", "Type": "EMV", "Name": "American Express"}, {"Vendor": "American Express", "Description": "", "Country": "United Kingdom", "AID": "A000000025010104", "Type": "", "Name": "American Express"}, {"Vendor": "American Express", "Description": "", "Country": "United Kingdom", "AID": "A000000025010402", "Type": "EMV", "Name": "American Express"}, {"Vendor": "American Express", "Description": "", "Country": "United Kingdom", "AID": "A000000025010701", "Type": "EMV", "Name": "ExpressPay"}, {"Vendor": "American Express", "Description": "", "Country": "United Kingdom", "AID": "A000000025010801", "Type": "EMV", "Name": "American Express"}, {"Vendor": "LINK Interchange Network Ltd", "Description": "Link (UK) ATM Network, or AMEX (Portugal?)", "Country": "United Kingdom", "AID": "A0000000291010", "Type": "EMV", "Name": "Link / American Express"}, {"Vendor": "LINK Interchange Network Ltd", "Description": "", "Country": "United Kingdom", "AID": "A00000002945087510100000", "Type": "", "Name": "CO-OP"}, {"Vendor": "LINK Interchange Network Ltd", "Description": "", "Country": "United Kingdom", "AID": "A00000002949034010100001", "Type": "", "Name": "HSBC"}, {"Vendor": "LINK Interchange Network Ltd", "Description": "", "Country": "United Kingdom", "AID": "A00000002949282010100000", "Type": "", "Name": "Barclay"}, {"Vendor": "LINK Interchange Network Ltd", "Description": "", "Country": "United Kingdom", "AID": "A000000029564182", "Type": "", "Name": "HAFX"}, {"Vendor": "Schlumberger Industries Identif d'Encarteur PR050", "Description": "Schlumberger (Gemalto) RID", "Country": "France", "AID": "A00000003029057000AD13100101FF", "Type": "", "Name": "BelPIC (Belgian Personal Identity Card) JavaCard Applet"}, {"Vendor": "Schlumberger Industries Identif d'Encarteur PR050", "Description": "", "Country": "France", "AID": "A0000000308000000000280101", "Type": "", "Name": "Gemalto .NET Card AID"}, {"Vendor": "Groupement des Cartes Bancaires \"CB\"", "Description": "Groupement des Cartes Bancaires (France)", "Country": "France", "AID": "A0000000421010", "Type": "EMV", "Name": "Cartes Bancaire EMV Card"}, {"Vendor": "Groupement des Cartes Bancaires \"CB\"", "Description": "", "Country": "France", "AID": "A0000000422010", "Type": "EMV", "Name": ""}, {"Vendor": "Groupement des Cartes Bancaires \"CB\"", "Description": "", "Country": "France", "AID": "A0000000423010", "Type": "EMV", "Name": ""}, {"Vendor": "Groupement des Cartes Bancaires \"CB\"", "Description": "", "Country": "France", "AID": "A0000000424010", "Type": "EMV", "Name": ""}, {"Vendor": "Groupement des Cartes Bancaires \"CB\"", "Description": "", "Country": "France", "AID": "A0000000425010", "Type": "EMV", "Name": ""}, {"Vendor": "Zentraler Kreditausschuss (ZKA)", "Description": "", "Country": "Germany", "AID": "A00000005945430100", "Type": "", "Name": "Girocard Electronic Cash"}, {"Vendor": "RSA Laboratories", "Description": "RSA PKCS-15 PKI application (Predecessor to ISO7816-15) / ID-card in Finland", "Country": "United States", "AID": "A000000063504B43532D3135", "Type": "", "Name": "PKCS-15"}, {"Vendor": "RSA Laboratories", "Description": "WAP (Wireless Application Protocol) Identity Module / Wireless Identification Module", "Country": "United States", "AID": "A0000000635741502D57494D", "Type": "", "Name": "WAP-WIM"}, {"Vendor": "JCB CO., LTD.", "Description": "Japan Credit Bureau", "Country": "Japan", "AID": "A00000006510", "Type": "EMV", "Name": "JCB"}, {"Vendor": "JCB CO., LTD.", "Description": "Japan Credit Bureau", "Country": "Japan", "AID": "A0000000651010", "Type": "EMV", "Name": "JCB J Smart Credit"}, {"Vendor": "Socit Europenne de Monnaie Electronique SEME", "Description": "", "Country": "France", "AID": "A00000006900", "Type": "EMV", "Name": "Moneo"}, {"Vendor": "Oberthur Technologies", "Description": "", "Country": "France", "AID": "A000000077010000021000000000003B", "Type": "EMV", "Name": "Visa AEPN"}, {"Vendor": "Activcard Europe S.A.", "Description": "Identity Key", "Country": "France", "AID": "A0000000790100", "Type": "", "Name": "CACv2 PKI ID"}, {"Vendor": "Activcard Europe S.A.", "Description": "Digital Signature Key", "Country": "France", "AID": "A0000000790101", "Type": "", "Name": "CACv2 PKI Sign"}, {"Vendor": "Activcard Europe S.A.", "Description": "Key Management Key", "Country": "France", "AID": "A0000000790102", "Type": "", "Name": "CACv2 PKI Enc"}, {"Vendor": "Activcard Europe S.A.", "Description": "Re-directs to CACv2 PKI Identity key", "Country": "France", "AID": "A00000007901F0", "Type": "", "Name": "CACv1 PKI Identity Key"}, {"Vendor": "Activcard Europe S.A.", "Description": "Re-directs to CACv2 Digital Signature key", "Country": "France", "AID": "A00000007901F1", "Type": "", "Name": "CACv1 PKI Digital Signature Key"}, {"Vendor": "Activcard Europe S.A.", "Description": "Re-directs to CACv2 Key Management key", "Country": "France", "AID": "A00000007901F2", "Type": "", "Name": "CACv1 PKI Key Management Key"}, {"Vendor": "Activcard Europe S.A.", "Description": "DoD Demographic", "Country": "France", "AID": "A0000000790200", "Type": "", "Name": "CACv2 DoD Person"}, {"Vendor": "Activcard Europe S.A.", "Description": "DoD Demographic", "Country": "France", "AID": "A0000000790201", "Type": "", "Name": "CACv2 DoD Personnel"}, {"Vendor": "Activcard Europe S.A.", "Description": "General Configuration", "Country": "France", "AID": "A00000007902FB", "Type": "", "Name": "CACv1 BC"}, {"Vendor": "Activcard Europe S.A.", "Description": "PKI Certificate Attributes", "Country": "France", "AID": "A00000007902FD", "Type": "", "Name": "CACv1 BC"}, {"Vendor": "Activcard Europe S.A.", "Description": "PKI Cert", "Country": "France", "AID": "A00000007902FE", "Type": "", "Name": "CACv1 BC"}, {"Vendor": "Activcard Europe S.A.", "Description": "CAC PIN / ID PIN Management Applet", "Country": "France", "AID": "A0000000790300", "Type": "", "Name": "CACv2 Access Control Applet"}, {"Vendor": "Activcard Europe S.A.", "Description": "Joint Data Model. BCAdmin", "Country": "France", "AID": "A0000000791201", "Type": "", "Name": "CAC JDM"}, {"Vendor": "Activcard Europe S.A.", "Description": "Joint Data Model. BCMedical", "Country": "France", "AID": "A0000000791202", "Type": "", "Name": "CAC JDM"}, {"Vendor": "Third Generation Partnership Project (3GPP)", "Description": "", "Country": "France", "AID": "A0000000871002FF49FF0589", "Type": "USIM", "Name": "Telenor USIM"}, {"Vendor": "Buypass AS", "Description": "Used by norwegian public betting company Norsk-Tipping?", "Country": "Norway", "AID": "A00000008810200105C100", "Type": "BuyPass", "Name": "BuyPass BIDA"}, {"Vendor": "Buypass AS", "Description": "", "Country": "Norway", "AID": "A000000088102201034221", "Type": "BuyPass", "Name": "BuyPass BEID (BuyPass Electronic ID?)"}, {"Vendor": "Buypass AS", "Description": "", "Country": "Norway", "AID": "A000000088102201034321", "Type": "BuyPass", "Name": "BuyPass BEID (BuyPass Electronic ID?)"}, {"Vendor": "Sa Proton World International N.V.", "Description": "Proton, which is owned in part by Visa International and American Express Co., is in three other European countries: the original Proton program in Belgium, Chipknip in the Netherlands, and Cash in Switzerland", "Country": "Belgium", "AID": "A0000000960200", "Type": "GP", "Name": "Proton World International Security Domain"}, {"Vendor": "Visa USA", "Description": "Bank of America Debit Card", "Country": "United States", "AID": "A000000098", "Type": "EMV", "Name": "Debit Card"}, {"Vendor": "Visa USA", "Description": "", "Country": "United States", "AID": "A0000000980840", "Type": "", "Name": "Visa Common Debit"}, {"Vendor": "Visa USA", "Description": "Schwab Bank Debit Card", "Country": "United States", "AID": "A0000000980848", "Type": "EMV", "Name": "Debit Card"}, {"Vendor": "Die Post Postfinance", "Description": "", "Country": "Switzerland", "AID": "A0000001110101", "Type": "", "Name": "Postcard"}, {"Vendor": "GSA - TFCS", "Description": "CHUID", "Country": "United States", "AID": "A0000001160300", "Type": "", "Name": "PIV CHUID"}, {"Vendor": "GSA - TFCS", "Description": "Fingerprints", "Country": "United States", "AID": "A0000001166010", "Type": "", "Name": "PIV Fingerprints"}, {"Vendor": "GSA - TFCS", "Description": "Facial Image", "Country": "United States", "AID": "A0000001166030", "Type": "", "Name": "PIV Facial Image"}, {"Vendor": "GSA - TFCS", "Description": "Security Object", "Country": "United States", "AID": "A0000001169000", "Type": "", "Name": "PIV Security Object"}, {"Vendor": "GSA - TFCS", "Description": "PIV Authentication Key", "Country": "United States", "AID": "A000000116A001", "Type": "", "Name": "PIV Authentication Key"}, {"Vendor": "GSA - TFCS", "Description": "Card Capability Container", "Country": "United States", "AID": "A000000116DB00", "Type": "", "Name": "CCC"}, {"Vendor": "Austria Card", "Description": "Domestic Loyalty Program (Version 1.3)", "Country": "Austria", "AID": "A000000118010000", "Type": "", "Name": "DF_Verkehr"}, {"Vendor": "Austria Card", "Description": "Domestic Loyalty Program (Version 1.3)", "Country": "Austria", "AID": "A000000118020000", "Type": "", "Name": "DF_Partner"}, {"Vendor": "Austria Card", "Description": "Domestic Loyalty Program (Version 1.3)", "Country": "Austria", "AID": "A000000118030000", "Type": "", "Name": "DF_Schlerdaten"}, {"Vendor": "Austria Card", "Description": "Domestic Loyalty Program (Version 1.32)", "Country": "Austria", "AID": "A000000118040000", "Type": "", "Name": "DF_KEP_SIG"}, {"Vendor": "Austria Card", "Description": "Digital Signature Application", "Country": "Austria", "AID": "A0000001184543", "Type": "", "Name": "Digital Signature (SSCA)"}, {"Vendor": "Austria Card", "Description": "Encryption Application (Version 1.10)", "Country": "Austria", "AID": "A000000118454E", "Type": "", "Name": "Encryption Application"}, {"Vendor": "PBS Danmark A/S", "Description": "Danish domestic debit card", "Country": "Denmark", "AID": "A0000001211010", "Type": "EMV", "Name": "Dankort (VISA GEM Vision)"}, {"Vendor": "Java Card Forum", "Description": "", "Country": "United States", "AID": "A0000001320001", "Type": "", "Name": "org.javacardforum.javacard.biometry"}, {"Vendor": "TDS TODOS DATA SYSTEM AB", "Description": "", "Country": "Sweden", "AID": "A0000001408001", "Type": "", "Name": "eCode"}, {"Vendor": "Associazione Bancaria Italiana", "Description": "CoGeBan Consorzio BANCOMAT (Italian domestic debit card)", "Country": "Italy", "AID": "A0000001410001", "Type": "EMV", "Name": "PagoBANCOMAT"}, {"Vendor": "GlobalPlatform, Inc.", "Description": "GP Card Manager", "Country": "United States", "AID": "A0000001510000", "Type": "GP", "Name": "Global Platform Security Domain AID"}, {"Vendor": "GlobalPlatform, Inc.", "Description": "SPCASD", "Country": "United States", "AID": "A00000015153504341534400", "Type": "GP", "Name": "CASD_AID"}, {"Vendor": "Diners Club International Ltd.", "Description": "Discover Card", "Country": "United States", "AID": "A0000001523010", "Type": "EMV", "Name": "Discover, Pulse D Pas"}, {"Vendor": "Diners Club International Ltd.", "Description": "Discover Debit Common Card", "Country": "United States", "AID": "A0000001524010", "Type": "EMV", "Name": "Discover"}, {"Vendor": "Banrisul - Banco do Estado do Rio Grande do SUL - S.A.", "Description": "Banrisul (Brazil)", "Country": "Brazil", "AID": "A0000001544442", "Type": "EMV", "Name": "Banricompras Debito"}, {"Vendor": "Zhlke Engineering AG", "Description": "", "Country": "Switzerland", "AID": "A0000001570010", "Type": "", "Name": "AMEX"}, {"Vendor": "Zhlke Engineering AG", "Description": "", "Country": "Switzerland", "AID": "A0000001570020", "Type": "", "Name": "MasterCard"}, {"Vendor": "Zhlke Engineering AG", "Description": "", "Country": "Switzerland", "AID": "A0000001570021", "Type": "", "Name": "Maestro"}, {"Vendor": "Zhlke Engineering AG", "Description": "", "Country": "Switzerland", "AID": "A0000001570022", "Type": "", "Name": "Maestro"}, {"Vendor": "Zhlke Engineering AG", "Description": "", "Country": "Switzerland", "AID": "A0000001570023", "Type": "", "Name": "CASH"}, {"Vendor": "Zhlke Engineering AG", "Description": "", "Country": "Switzerland", "AID": "A0000001570030", "Type": "", "Name": "VISA"}, {"Vendor": "Zhlke Engineering AG", "Description": "", "Country": "Switzerland", "AID": "A0000001570031", "Type": "", "Name": "VISA"}, {"Vendor": "Zhlke Engineering AG", "Description": "", "Country": "Switzerland", "AID": "A0000001570040", "Type": "", "Name": "JCB"}, {"Vendor": "Zhlke Engineering AG", "Description": "", "Country": "Switzerland", "AID": "A0000001570050", "Type": "", "Name": "Postcard"}, {"Vendor": "Zhlke Engineering AG", "Description": "", "Country": "Switzerland", "AID": "A0000001570051", "Type": "", "Name": "Postcard"}, {"Vendor": "Zhlke Engineering AG", "Description": "", "Country": "Switzerland", "AID": "A0000001570100", "Type": "", "Name": "MCard"}, {"Vendor": "Zhlke Engineering AG", "Description": "", "Country": "Switzerland", "AID": "A0000001570104", "Type": "", "Name": "MyOne"}, {"Vendor": "Zhlke Engineering AG", "Description": "", "Country": "Switzerland", "AID": "A0000001570109", "Type": "", "Name": "Mediamarkt Card"}, {"Vendor": "Zhlke Engineering AG", "Description": "", "Country": "Switzerland", "AID": "A000000157010A", "Type": "", "Name": "Gift Card"}, {"Vendor": "Zhlke Engineering AG", "Description": "", "Country": "Switzerland", "AID": "A000000157010B", "Type": "", "Name": "Bonuscard"}, {"Vendor": "Zhlke Engineering AG", "Description": "", "Country": "Switzerland", "AID": "A000000157010C", "Type": "", "Name": "WIRCard"}, {"Vendor": "Zhlke Engineering AG", "Description": "", "Country": "Switzerland", "AID": "A000000157010D", "Type": "", "Name": "Power Card"}, {"Vendor": "Zhlke Engineering AG", "Description": "", "Country": "Switzerland", "AID": "A0000001574443", "Type": "", "Name": "DINERS CLUB"}, {"Vendor": "Zhlke Engineering AG", "Description": "", "Country": "Switzerland", "AID": "A0000001574444", "Type": "", "Name": "Supercard Plus"}, {"Vendor": "IBM", "Description": "identify in JCOP-tools returns eg 27 34 01 2E 00 00 00 00 4E 58 37 35 31 41 00 03 28 62 B3 6A 82", "Country": "Germany", "AID": "A000000167413000FF", "Type": "JCOP", "Name": "JCOP Identify Applet"}, {"Vendor": "IBM", "Description": "?", "Country": "Germany", "AID": "A000000167413001", "Type": "", "Name": "FIPS 140-2"}, {"Vendor": "Financial Information Service Co. Ltd.", "Description": "The Bankers Association of the Republic of China", "Country": "Taiwan", "AID": "A000000172950001", "Type": "EMV", "Name": "BAROC Financial Application Taiwan"}, {"Vendor": "Ministre de L'Intrieur", "Description": "", "Country": "Belgium", "AID": "A000000177504B43532D3135", "Type": "", "Name": "BelPIC (Belgian Personal Identity Card)"}, {"Vendor": "Post Office Limited", "Description": "", "Country": "United Kingdom", "AID": "A0000001850002", "Type": "EMV", "Name": "UK Post Office Account card"}, {"Vendor": "Diners Club Switzerland Ltd", "Description": "", "Country": "Switzerland", "AID": "A0000001884443", "Type": "", "Name": "DINERS CLUB"}, {"Vendor": "Association for Payment Clearing Services", "Description": "", "Country": "United Kingdom", "AID": "A0000002040000", "Type": "", "Name": "?"}, {"Vendor": "Saudi Arabian Monetary Agency (SAMA)", "Description": "SPAN2 (Saudi Payments Network) - Saudi Arabia domestic credit/debit card (Saudi Arabia Monetary Agency)", "Country": "Kingdom of Saudi Arabia", "AID": "A0000002281010", "Type": "EMV", "Name": "SPAN (M/Chip)"}, {"Vendor": "Saudi Arabian Monetary Agency (SAMA)", "Description": "SPAN2 (Saudi Payments Network) - Saudi Arabia domestic credit/debit card (Saudi Arabia Monetary Agency)", "Country": "Kingdom of Saudi Arabia", "AID": "A0000002282010", "Type": "EMV", "Name": "SPAN (VIS)"}, {"Vendor": "Saudi Arabian Monetary Agency (SAMA)", "Description": "SPAN2 (Saudi Payments Network) - Saudi Arabia domestic credit/debit card (Saudi Arabia Monetary Agency)", "Country": "Kingdom of Saudi Arabia", "AID": "A00000022820101010", "Type": "", "Name": "SPAN"}, {"Vendor": "ISO JTC1/SC17/WG3", "Description": "Electronic (Biometric) Passport. Issuer stored data application (The last three digits of the PIX shall be used to denote future version levels.)", "Country": "United Kingdom", "AID": "A0000002471001", "Type": "MRTD", "Name": "Machine Readable Travel Documents (MRTD)"}, {"Vendor": "ISO JTC1/SC17/WG3", "Description": "Electronic (Biometric) Passport. Application for hashes, digital signature, and certificate (The last three digits of the PIX shall be used to denote future version levels.)", "Country": "United Kingdom", "AID": "A0000002472001", "Type": "MRTD", "Name": "Machine Readable Travel Documents (MRTD)"}, {"Vendor": "Interac Association", "Description": "Canadian domestic credit/debit card", "Country": "Canada", "AID": "A0000002771010", "Type": "EMV", "Name": "INTERAC"}, {"Vendor": "PS/SC Workgroup", "Description": "Possibly not an application...", "Country": "United States", "AID": "A00000030600000000000000", "Type": "", "Name": "PC/SC Initial access data AID"}, {"Vendor": "National Institute of Standards and Technology", "Description": "PIV End Point Applet. Last 2 bytes designate version?", "Country": "United States", "AID": "A000000308000010000100", "Type": "", "Name": "Personal Identity Verification (PIV) / ID-ONE PIV BIO"}, {"Vendor": "Currence Holding/PIN BV", "Description": "", "Country": "The Netherlands", "AID": "A00000031510100528", "Type": "EMV", "Name": "Currence PuC"}, {"Vendor": "Currence Holding/PIN BV", "Description": "", "Country": "The Netherlands", "AID": "A0000003156020", "Type": "EMV", "Name": "Chipknip"}, {"Vendor": "Identity Alliance", "Description": "http://osdir.com/ml/lib.muscle/2005-12/msg00066.html", "Country": "United States", "AID": "A00000032301", "Type": "", "Name": "MUSCLE Applet Package"}, {"Vendor": "Identity Alliance", "Description": "http://osdir.com/ml/lib.muscle/2005-12/msg00066.html", "Country": "United States", "AID": "A0000003230101", "Type": "", "Name": "MUSCLE Applet Instance"}, {"Vendor": "Discover Financial Services LLC", "Description": "", "Country": "United States", "AID": "A0000003241010", "Type": "", "Name": "Discover Expresspay (ZIP)"}, {"Vendor": "China Unionpay Co. Ltd", "Description": "", "Country": "China", "AID": "A000000333010101", "Type": "", "Name": "UnionPay Debit"}, {"Vendor": "China Unionpay Co. Ltd", "Description": "", "Country": "China", "AID": "A000000333010102", "Type": "", "Name": "UnionPay Credit"}, {"Vendor": "China Unionpay Co. Ltd", "Description": "", "Country": "China", "AID": "A000000333010103", "Type": "", "Name": "UnionPay Quasi Credit"}, {"Vendor": "China Unionpay Co. Ltd", "Description": "", "Country": "China", "AID": "A000000333010106", "Type": "", "Name": "UnionPay Electronic Cash"}, {"Vendor": "China Unionpay Co. Ltd", "Description": "", "Country": "China", "AID": "A000000333010108", "Type": "", "Name": "U.S. UnionPay Common Debit AID"}, {"Vendor": "Euro Alliance of Payment Schemes s.c.r.l. - EAPS", "Description": "Unknown", "Country": "Belgium", "AID": "A0000003591010", "Type": "", "Name": ""}, {"Vendor": "Euro Alliance of Payment Schemes s.c.r.l. - EAPS", "Description": "ZKA (Germany)", "Country": "Belgium", "AID": "A0000003591010028001", "Type": "EMV", "Name": "Girocard EAPS"}, {"Vendor": "Euro Alliance of Payment Schemes s.c.r.l. - EAPS", "Description": "PagoBANCOMAT", "Country": "Belgium", "AID": "A00000035910100380", "Type": "", "Name": ""}, {"Vendor": "Poste Italiane S.P.A", "Description": "", "Country": "Italy", "AID": "A0000003660001", "Type": "", "Name": "Postamat"}, {"Vendor": "Poste Italiane S.P.A", "Description": "", "Country": "Italy", "AID": "A0000003660002", "Type": "", "Name": "Postamat VISA"}, {"Vendor": "Interswitch Limited", "Description": "Nigerian local switch company", "Country": "Nigeria", "AID": "A0000003710001", "Type": "EMV", "Name": "InterSwitch Verve Card"}, {"Vendor": "NXP Semiconductors Germany GmbH", "Description": "NXP Mf4M", "Country": "Germany", "AID": "A0000003964D66344D0002", "Type": "", "Name": "MIFARE4MOBILE"}, {"Vendor": "Microsoft Corporation", "Description": "Identity Device With Microsoft Generic Profile application. 2 bytes can be added at the end. This byte must be set to the IDMP specification revision number which is currently 0x01. The second byte (yy) is reserved for use by the card application.", "Country": "United States", "AID": "A00000039742544659", "Type": "", "Name": "Microsoft IDMP AID"}, {"Vendor": "Microsoft Corporation", "Description": "MS Plug and Play", "Country": "United States", "AID": "A0000003974349445F0100", "Type": "", "Name": "Microsoft PNP AID"}, {"Vendor": "Unibanco (Hipercard)", "Description": "", "Country": "Brazil", "AID": "A0000004271010", "Type": "", "Name": "Hiperchip"}, {"Vendor": "100", "Description": "", "Country": "Russia", "AID": "A0000004320001", "Type": "", "Name": "Universal Electronic Card"}, {"Vendor": "Edenred", "Description": "", "Country": "Belgium", "AID": "A0000004360100", "Type": "", "Name": "Ticket Restaurant"}, {"Vendor": "ACCEL/Exchange", "Description": "The Exchange Network ATM Network", "Country": "United States", "AID": "A0000004391010", "Type": "", "Name": "Exchange ATM card"}, {"Vendor": "eTranzact", "Description": "Nigerian local switch company", "Country": "Nigeria", "AID": "A0000004540010", "Type": "EMV", "Name": "Etranzact Genesis Card"}, {"Vendor": "eTranzact", "Description": "Nigerian local switch company", "Country": "Nigeria", "AID": "A0000004540011", "Type": "EMV", "Name": "Etranzact Genesis Card 2"}, {"Vendor": "Google", "Description": "GOOGLE_LOCKET_AID", "Country": "United States", "AID": "A0000004762010", "Type": "", "Name": "GOOGLE_CONTROLLER_AID"}, {"Vendor": "Google", "Description": "", "Country": "United States", "AID": "A0000004763030", "Type": "", "Name": "GOOGLE_MIFARE_MANAGER_AID"}, {"Vendor": "Google", "Description": "", "Country": "United States", "AID": "A0000004766C", "Type": "EMV", "Name": "GOOGLE_PAYMENT_AID"}, {"Vendor": "Google", "Description": "", "Country": "United States", "AID": "A000000476A010", "Type": "GP", "Name": "GSD_MANAGER_AID"}, {"Vendor": "Google", "Description": "", "Country": "United States", "AID": "A000000476A110", "Type": "GP", "Name": "GSD_MANAGER_AID"}, {"Vendor": "JVL Ventures, LLC (Softcard)", "Description": "", "Country": "United States", "AID": "A000000485", "Type": "", "Name": "Softcard SmartTap"}, {"Vendor": "RuPay", "Description": "RuPay (India)", "Country": "India", "AID": "A0000005241010", "Type": "EMV", "Name": "RuPay"}, {"Vendor": "Yubico", "Description": "Universal 2-Factor Proof-of-concept/Demo", "Country": "Sweden", "AID": "A0000005271002", "Type": "YKNEO", "Name": "Yubikey NEO U2F Demo applet"}, {"Vendor": "Yubico", "Description": "Javacard Applet AID", "Country": "Sweden", "AID": "A000000527200101", "Type": "YKNEO", "Name": "Yubikey NEO Yubikey2 applet interface"}, {"Vendor": "Yubico", "Description": "Javacard Applet AID", "Country": "Sweden", "AID": "A000000527210101", "Type": "YKNEO", "Name": "Yubikey NEO OATH Applet"}, {"Vendor": "GSMA (GSM Association)", "Description": "", "Country": "United Kingdom", "AID": "A0000005591010FFFFFFFF8900000100", "Type": "", "Name": "ISD-R Application. Used as TAR."}, {"Vendor": "GSMA (GSM Association)", "Description": "", "Country": "United Kingdom", "AID": "A0000005591010FFFFFFFF8900000200", "Type": "", "Name": "ECASD Application. Used as TAR."}, {"Vendor": "GSMA (GSM Association)", "Description": "", "Country": "United Kingdom", "AID": "A0000005591010FFFFFFFF8900000D00", "Type": "", "Name": "ISD-P Executable Load File."}, {"Vendor": "GSMA (GSM Association)", "Description": "", "Country": "United Kingdom", "AID": "A0000005591010FFFFFFFF8900000E00", "Type": "", "Name": "ISD-P Executable Module."}, {"Vendor": "GSMA (GSM Association)", "Description": "", "Country": "United Kingdom", "AID": "A0000005591010FFFFFFFF8900000F00", "Type": "", "Name": "Reserved value for the Profile's ISD-P"}, {"Vendor": "GSMA (GSM Association)", "Description": "", "Country": "United Kingdom", "AID": "A0000005591010FFFFFFFF8900001000", "Type": "", "Name": "ISD-P Application ('1010FFFFFFFF89000010' to '1010FFFFFFFF8900FFFF'. Used as TAR. The value is allocated during the 'Profile Download and Installation procedure'"}, {"Vendor": "Fidesmo", "Description": "", "Country": "Sweden", "AID": "A00000061700", "Type": "", "Name": "Fidesmo javacard"}, {"Vendor": "Debit Network Alliance (DNA)", "Description": "Common U.S. Debit", "Country": "United States", "AID": "A0000006200620", "Type": "", "Name": "Debit Network Alliance (DNA)"}, {"Vendor": "MIR", "Description": "", "Country": "Russia", "AID": "A0000006581010", "Type": "", "Name": "MIR Credit"}, {"Vendor": "MIR", "Description": "", "Country": "Russia", "AID": "A0000006582010", "Type": "", "Name": "MIR Debit"}, {"Vendor": "TROY", "Description": "Turkey's Payment Method", "Country": "Turkey", "AID": "A0000006723010", "Type": "EMV", "Name": "TROY chip credit card"}, {"Vendor": "TROY", "Description": "Turkey's Payment Method", "Country": "Turkey", "AID": "A0000006723020", "Type": "EMV", "Name": "TROY chip debit card"}, {"Vendor": "Indian Oil Corporation Limited", "Description": "Indian Oils Pre Paid Program", "Country": "India", "AID": "A0000007705850", "Type": "EMV", "Name": "XTRAPOWER Fleet Card Program"}, {"Vendor": "MasterCard International", "Description": "Used for development", "Country": "United States", "AID": "B012345678", "Type": "EMV", "Name": "Maestro TEST"}, {"Vendor": "Paylife", "Description": "Domestic Payment System (Version 2.1)", "Country": "Austria", "AID": "D040000001000002", "Type": "", "Name": "Paylife Quick (IEP). Preloaded Electronic Purse"}, {"Vendor": "Austria Card", "Description": "Domestic Payment System (Version 2.1)", "Country": "Austria", "AID": "D040000002000002", "Type": "", "Name": "RFU"}, {"Vendor": "Austria Card", "Description": "Domestic Payment System (Version 2.1)", "Country": "Austria", "AID": "D040000003000002", "Type": "", "Name": "POS"}, {"Vendor": "Austria Card", "Description": "Domestic Payment System (Version 2.1)", "Country": "Austria", "AID": "D040000004000002", "Type": "", "Name": "ATM"}, {"Vendor": "Austria Card", "Description": "Domestic Loyalty Program (Version 2.1)", "Country": "Austria", "AID": "D04000000B000002", "Type": "", "Name": "Retail"}, {"Vendor": "Austria Card", "Description": "Domestic Loyalty Program (Version 2.1)", "Country": "Austria", "AID": "D04000000C000002", "Type": "", "Name": "Bank_Data"}, {"Vendor": "Austria Card", "Description": "Domestic Loyalty Program (Version 2.1)", "Country": "Austria", "AID": "D04000000D000002", "Type": "", "Name": "Shopping"}, {"Vendor": "Austria Card", "Description": "Domestic Loyalty Program (Version 2.0)", "Country": "Austria", "AID": "D040000013000001", "Type": "", "Name": "DF_UNI_Kepler1"}, {"Vendor": "Austria Card", "Description": "Domestic Loyalty Program (Version 1.3)", "Country": "Austria", "AID": "D040000013000001", "Type": "", "Name": "DF_Schler1"}, {"Vendor": "Austria Card", "Description": "Domestic Loyalty Program (Version 2.0)", "Country": "Austria", "AID": "D040000013000002", "Type": "", "Name": "DF_UNI_Kepler2"}, {"Vendor": "Austria Card", "Description": "Domestic Loyalty Program (Version 1.3)", "Country": "Austria", "AID": "D040000013000002", "Type": "", "Name": "DF_Schler2"}, {"Vendor": "Austria Card", "Description": "Domestic Loyalty Program (Version 2.0)", "Country": "Austria", "AID": "D040000014000001", "Type": "", "Name": "DF_Mensa"}, {"Vendor": "Austria Card", "Description": "Domestic Loyalty Program (Version 2.0)", "Country": "Austria", "AID": "D040000015000001", "Type": "", "Name": "DF_UNI_Ausweis"}, {"Vendor": "Austria Card", "Description": "Domestic Loyalty Program (Version 1.3)", "Country": "Austria", "AID": "D040000015000001", "Type": "", "Name": "DF_Ausweis"}, {"Vendor": "Austria Card", "Description": "Domestic EMV Application (Version 2.1)", "Country": "Austria", "AID": "D0400000190001", "Type": "", "Name": "EMV ATM Maestro"}, {"Vendor": "Austria Card", "Description": "Domestic EMV Application (Version 2.1)", "Country": "Austria", "AID": "D0400000190002", "Type": "", "Name": "EMV POS Maestro"}, {"Vendor": "Austria Card", "Description": "Domestic EMV Application (Version 2.1)", "Country": "Austria", "AID": "D0400000190003", "Type": "", "Name": "EMV ATM MasterCard"}, {"Vendor": "Austria Card", "Description": "Domestic EMV Application (Version 2.1)", "Country": "Austria", "AID": "D0400000190004", "Type": "", "Name": "EMV POS MasterCard"}, {"Vendor": "Austria Card", "Description": "Domestic Payment System (Version 2.1)", "Country": "Austria", "AID": "D0400000190010", "Type": "", "Name": "Digital ID"}, {"Vendor": "Ministry of Finance of Georgia", "Description": "Georgia Revenue Service application for fiscal cash registers", "Country": "Georgia", "AID": "D268000001", "Type": "", "Name": "Fiscal module application"}, {"Vendor": "Giesecke&Devrient", "Description": "Giesecke & Devrient", "Country": "Germany", "AID": "D276000005", "Type": "", "Name": ""}, {"Vendor": "Giesecke&Devrient", "Description": "", "Country": "Germany", "AID": "D276000005AA040360010410", "Type": "", "Name": "G D App Nokia 6212"}, {"Vendor": "Giesecke&Devrient", "Description": "", "Country": "Germany", "AID": "D276000005AA0503E00401", "Type": "", "Name": "G D App Nokia 6212"}, {"Vendor": "Giesecke&Devrient", "Description": "", "Country": "Germany", "AID": "D276000005AA0503E00501", "Type": "", "Name": "G D App Nokia 6212"}, {"Vendor": "Giesecke&Devrient", "Description": "", "Country": "Germany", "AID": "D276000005AA0503E0050101", "Type": "", "Name": "G D App Nokia 6212"}, {"Vendor": "Giesecke&Devrient", "Description": "", "Country": "Germany", "AID": "D276000005AB0503E0040101", "Type": "", "Name": "G D App Nokia 6212"}, {"Vendor": "IBM Laboratories", "Description": "IBM Test card from the book 'Smart Card Application Development Using Java'", "Country": "Germany", "AID": "D27600002200000001", "Type": "", "Name": "SCT LOYALTY"}, {"Vendor": "IBM Laboratories", "Description": "IBM Test card from the book 'Smart Card Application Development Using Java'", "Country": "Germany", "AID": "D27600002200000002", "Type": "", "Name": "BUSINESS CARD"}, {"Vendor": "IBM Laboratories", "Description": "IBM Test card from the book 'Smart Card Application Development Using Java'", "Country": "Germany", "AID": "D27600002200000060", "Type": "", "Name": "PKCS#11 Token"}, {"Vendor": "ZKA", "Description": "Girocard (Geldkarte) in Germany", "Country": "Germany", "AID": "D276000025", "Type": "", "Name": "Girocard"}, {"Vendor": "ZKA", "Description": "Unknown", "Country": "Germany", "AID": "D27600002545410100", "Type": "", "Name": ""}, {"Vendor": "ZKA", "Description": "ZKA Girocard (Geldkarte) (Germany)", "Country": "Germany", "AID": "D27600002545500100", "Type": "EMV", "Name": "Girocard"}, {"Vendor": "ZKA", "Description": "", "Country": "Germany", "AID": "D27600002547410100", "Type": "", "Name": "Girocard ATM"}, {"Vendor": "Wolfgang Rankl", "Description": "", "Country": "Germany", "AID": "D276000060", "Type": "", "Name": ""}, {"Vendor": "NXP Semiconductors / NFC Forum", "Description": "NFC Forum Type 4 Tag", "Country": "Germany", "AID": "D2760000850100", "Type": "", "Name": "NDEF Tag Application / Mifare DESFire Tag Application"}, {"Vendor": "NXP Semiconductors / NFC Forum", "Description": "NFC Tag type 4 tag", "Country": "Germany", "AID": "D2760000850101", "Type": "", "Name": "NDEF Tag Application"}, {"Vendor": "Giesecke&Devrient Java Card Telecommunikation", "Description": "", "Country": "Germany", "AID": "D276000118", "Type": "", "Name": ""}, {"Vendor": "Giesecke&Devrient Java Card Telecommunikation", "Description": "Devrient Test Applet?", "Country": "Germany", "AID": "D2760001180101", "Type": "", "Name": "Giesecke &"}, {"Vendor": "fsfEurope", "Description": "For selection when not knowing the exact full AID", "Country": "Germany", "AID": "D27600012401", "Type": "OpenPGP", "Name": "OpenPGP Card"}, {"Vendor": "fsfEurope", "Description": "Version 1", "Country": "Germany", "AID": "D276000124010101FFFF000000010000", "Type": "OpenPGP", "Name": "OpenPGP Card"}, {"Vendor": "fsfEurope", "Description": "Version 2", "Country": "Germany", "AID": "D2760001240102000000000000010000", "Type": "OpenPGP", "Name": "OpenPGP Card"}, {"Vendor": "fsfEurope", "Description": "http://smartchess.de/englisch/SmartChess_1.0.pdf", "Country": "Germany", "AID": "D27600012402", "Type": "SmartChess", "Name": "SmartChess"}, {"Vendor": "fsfEurope", "Description": "http://smartchess.de/englisch/SmartChess_1.0.pdf", "Country": "Germany", "AID": "D2760001240200010000000000000000", "Type": "SmartChess", "Name": "SmartChess"}, {"Vendor": "", "Description": "", "Country": "Republic of Korea", "AID": "D4100000011010", "Type": "", "Name": ""}, {"Vendor": "", "Description": "(Netherlands)", "Country": "The Netherlands", "AID": "D5280050218002", "Type": "EMV", "Name": "?"}, {"Vendor": "Bankaxept", "Description": "Norwegian domestic debit card", "Country": "Norway", "AID": "D5780000021010", "Type": "EMV", "Name": "Bankaxept"}, {"Vendor": "Swiss Travel Fund (Reka)", "Description": "prepaid functional debit card", "Country": "Switzerland", "AID": "D7560000010101", "Type": "", "Name": "Reka Card"}, {"Vendor": "Migros (FCM, GE Money Bank and MasterCard)", "Description": "", "Country": "Switzerland", "AID": "D7560000300101", "Type": "", "Name": "M Budget"}, {"Vendor": "", "Description": "German eID", "Country": "", "AID": "E80704007F00070302", "Type": "", "Name": "nPA"}, {"Vendor": "", "Description": "", "Country": "", "AID": "E82881C11702", "Type": "", "Name": "AlphaCard application"}, {"Vendor": "", "Description": "Iso adoption of PKCS-15", "Country": "", "AID": "E828BD080F", "Type": "", "Name": "ISO-7816-15 EF.DIR"}, {"Vendor": "", "Description": "Brazilian Bank Banco Bradesco", "Country": "", "AID": "F0000000030001", "Type": "EMV", "Name": "BRADESCO"}] \ No newline at end of file +[{"AID":"315041592E5359532E4444463031","Vendor":"Visa International","Country":"United States","Name":"Visa Payment System Environment PSE (1PAY.SYS.DDF01)","Description":"","Type":""},{"AID":"325041592E5359532E4444463031","Vendor":"Visa International","Country":"United States","Name":"Visa Proximity Payment System Environment PPSE (2PAY.SYS.DDF01)","Description":"Visa payWave for Mobile","Type":""},{"AID":"44464D46412E44466172653234313031","Vendor":"DeviceFidelity","Country":"United States","Name":"DeviceFidelity In2Pay DFare applet","Description":"http://www.nfcworld.com/2010/11/24/35207/devicefidelity-adds-nfc-support-for-android-and-mifare/","Type":""},{"AID":"A00000000101","Vendor":"PBS Danm?nt A/S","Country":"Denmark","Name":"MUSCLE Card Applet","Description":"(Unlicensed use of this RID. Proposal to use A000000323 instead)","Type":""},{"AID":"A000000003000000","Vendor":"Visa International","Country":"United States","Name":"(VISA) Card Manager","Description":"Used by most GP2.1.1 cards / Oberthur OP201 cards. Visa Proprietary Card Manager AID for OpenPlatform cards (visa.openplatform).","Type":"GP"},{"AID":"A00000000300037561","Vendor":"Visa International","Country":"United States","Name":"Bonuscard","Description":"","Type":""},{"AID":"A00000000305076010","Vendor":"Visa International","Country":"United States","Name":"VISA ELO Credit","Description":"","Type":"EMV"},{"AID":"A0000000031010","Vendor":"Visa International","Country":"United States","Name":"VISA Debit/Credit (Classic)","Description":"Standard/Gold VISA credit card","Type":"EMV"},{"AID":"A000000003101001","Vendor":"Visa International","Country":"United States","Name":"VISA Credit","Description":"","Type":"EMV"},{"AID":"A000000003101002","Vendor":"Visa International","Country":"United States","Name":"VISA Debit","Description":"","Type":"EMV"},{"AID":"A0000000032010","Vendor":"Visa International","Country":"United States","Name":"VISA Electron","Description":"VISA Electron (Debit)","Type":"EMV"},{"AID":"A0000000032020","Vendor":"Visa International","Country":"United States","Name":"VISA","Description":"V PAY","Type":"EMV"},{"AID":"A0000000033010","Vendor":"Visa International","Country":"United States","Name":"VISA Interlink","Description":"VISA Interlink","Type":"EMV"},{"AID":"A0000000034010","Vendor":"Visa International","Country":"United States","Name":"VISA Specific","Description":"Visa Specific","Type":"EMV"},{"AID":"A0000000035010","Vendor":"Visa International","Country":"United States","Name":"VISA Specific","Description":"Visa Specific","Type":"EMV"},{"AID":"A000000003534441","Vendor":"Visa International","Country":"United States","Name":"Schlumberger Security Domain","Description":"","Type":"GP"},{"AID":"A0000000035350","Vendor":"Visa International","Country":"United States","Name":"Security Domain","Description":"OCS Oberthur Card System Security Domain Package AID / VGP Card Manager (for ISD and ASD)","Type":"GP"},{"AID":"A000000003535041","Vendor":"Visa International","Country":"United States","Name":"Security Domain","Description":"OCS Oberthur Card System Security Domain Applet AID / VGP Card Manager (for ISD and ASD)","Type":"GP"},{"AID":"A0000000036010","Vendor":"Visa International","Country":"United States","Name":"Domestic Visa Cash Stored Value","Description":"","Type":"EMV"},{"AID":"A0000000036020","Vendor":"Visa International","Country":"United States","Name":"International Visa Cash Stored Value","Description":"","Type":"EMV"},{"AID":"A0000000038002","Vendor":"Visa International","Country":"United States","Name":"VISA Auth, VisaRemAuthen EMV-CAP (DPA)","Description":"VISA Auth dynamic passcode authentication (DPA). Used by Barclays/HBOS","Type":"EMV"},{"AID":"A0000000038010","Vendor":"Visa International","Country":"United States","Name":"VISA Plus","Description":"VISA plus","Type":"EMV"},{"AID":"A0000000039010","Vendor":"Visa International","Country":"United States","Name":"VISA Loyalty","Description":"","Type":"EMV"},{"AID":"A000000003999910","Vendor":"Visa International","Country":"United States","Name":"VISA Proprietary ATM","Description":"","Type":"EMV"},{"AID":"A0000000040000","Vendor":"Mastercard International","Country":"United States","Name":"MasterCard Card Manager","Description":"Security Domain","Type":"GP"},{"AID":"A00000000401","Vendor":"Mastercard International","Country":"United States","Name":"MasterCard PayPass","Description":"AEPM (Association Europ?enne Payez Mobile)","Type":"EMV"},{"AID":"A0000000041010","Vendor":"Mastercard International","Country":"United States","Name":"MasterCard Credit/Debit (Global)","Description":"Standard MasterCard","Type":"EMV"},{"AID":"A00000000410101213","Vendor":"Mastercard International","Country":"United States","Name":"MasterCard Credit","Description":"Standard MasterCard","Type":"EMV"},{"AID":"A00000000410101215","Vendor":"Mastercard International","Country":"United States","Name":"MasterCard Credit","Description":"Standard MasterCard","Type":"EMV"},{"AID":"A0000000041010BB5449435301","Vendor":"Mastercard International","Country":"United States","Name":"[UNKNOWN]","Description":"Some co-branded card?","Type":""},{"AID":"A0000000042010","Vendor":"Mastercard International","Country":"United States","Name":"MasterCard Specific","Description":"MasterCard Specific","Type":"EMV"},{"AID":"A0000000042203","Vendor":"Mastercard International","Country":"United States","Name":"MasterCard Specific","Description":"MasterCard U.S. Maestro","Type":""},{"AID":"A0000000043010","Vendor":"Mastercard International","Country":"United States","Name":"MasterCard Specific","Description":"MasterCard Specific","Type":"EMV"},{"AID":"A0000000043060","Vendor":"Mastercard International","Country":"United States","Name":"Maestro (Debit)","Description":"Maestro (Debit) Card","Type":"EMV"},{"AID":"A000000004306001","Vendor":"Mastercard International","Country":"United States","Name":"Maestro (Debit)","Description":"Maestro (Debit) Card","Type":"EMV"},{"AID":"A0000000044010","Vendor":"Mastercard International","Country":"United States","Name":"MasterCard Specific","Description":"MasterCard Specific","Type":"EMV"},{"AID":"A0000000045010","Vendor":"Mastercard International","Country":"United States","Name":"MasterCard Specific","Description":"MasterCard Specific","Type":"EMV"},{"AID":"A0000000045555","Vendor":"Mastercard International","Country":"United States","Name":"APDULogger","Description":"AID on Cirrus Test Card","Type":""},{"AID":"A0000000046000","Vendor":"Mastercard International","Country":"United States","Name":"Cirrus","Description":"Mastercard Cirrus (Interbank Network) ATM card only","Type":"EMV"},{"AID":"A0000000048002","Vendor":"Mastercard International","Country":"United States","Name":"SecureCode Auth EMV-CAP","Description":"Chip Authentication Protocol (CAP). Works with NatWest or SecureCode Aut","Type":"EMV"},{"AID":"A0000000049999","Vendor":"Mastercard International","Country":"United States","Name":"MasterCard PayPass??","Description":"","Type":"EMV"},{"AID":"A0000000050001","Vendor":"Switch Card Services Ltd.","Country":"United Kingdom","Name":"Maestro UK","Description":"UK Domestic Maestro Switch (debit card)","Type":"EMV"},{"AID":"A0000000050002","Vendor":"Switch Card Services Ltd.","Country":"United Kingdom","Name":"Solo","Description":"UK Domestic Maestro Switch (debit card)","Type":"EMV"},{"AID":"A0000000090001FF44FF1289","Vendor":"ETSI","Country":"France","Name":"Orange","Description":"Orange UK","Type":""},{"AID":"A0000000101030","Vendor":"Europay International","Country":"Belgium","Name":"Maestro-CH","Description":"","Type":""},{"AID":"A00000001800","Vendor":"GEMPLUS","Country":"France","Name":"Gemplus ?","Description":"","Type":""},{"AID":"A0000000181001","Vendor":"GEMPLUS","Country":"France","Name":"com.gemplus.javacard.util packages","Description":"","Type":""},{"AID":"A000000018434D","Vendor":"GEMPLUS","Country":"France","Name":"Gemplus card manager","Description":"434D = CM (ascii). Security domain for some GCX/GXP cards (GemXpresso Pro) (Gemalto)","Type":"GP"},{"AID":"A000000018434D00","Vendor":"GEMPLUS","Country":"France","Name":"Gemplus Security Domain","Description":"(Gemalto)","Type":"GP"},{"AID":"A00000002401","Vendor":"Midland Bank Plc","Country":"United Kingdom","Name":"Self Service","Description":"","Type":"EMV"},{"AID":"A000000025","Vendor":"American Express","Country":"United Kingdom","Name":"American Express","Description":"","Type":"EMV"},{"AID":"A0000000250000","Vendor":"American Express","Country":"United Kingdom","Name":"American Express","Description":"American Express (Credit/Debit)","Type":"EMV"},{"AID":"A00000002501","Vendor":"American Express","Country":"United Kingdom","Name":"American Express","Description":"AEIPS-compliant (A-E contact EMV) payment application","Type":"EMV"},{"AID":"A000000025010104","Vendor":"American Express","Country":"United Kingdom","Name":"American Express","Description":"","Type":""},{"AID":"A000000025010402","Vendor":"American Express","Country":"United Kingdom","Name":"American Express","Description":"","Type":"EMV"},{"AID":"A000000025010701","Vendor":"American Express","Country":"United Kingdom","Name":"ExpressPay","Description":"","Type":"EMV"},{"AID":"A000000025010801","Vendor":"American Express","Country":"United Kingdom","Name":"American Express","Description":"","Type":"EMV"},{"AID":"A0000000291010","Vendor":"LINK Interchange Network Ltd","Country":"United Kingdom","Name":"Link / American Express","Description":"Link (UK) ATM Network, or AMEX (Portugal?)","Type":"EMV"},{"AID":"A00000002945087510100000","Vendor":"LINK Interchange Network Ltd","Country":"United Kingdom","Name":"CO-OP","Description":"","Type":""},{"AID":"A00000002949034010100001","Vendor":"LINK Interchange Network Ltd","Country":"United Kingdom","Name":"HSBC","Description":"","Type":""},{"AID":"A00000002949282010100000","Vendor":"LINK Interchange Network Ltd","Country":"United Kingdom","Name":"Barclay","Description":"","Type":""},{"AID":"A000000029564182","Vendor":"LINK Interchange Network Ltd","Country":"United Kingdom","Name":"HAFX","Description":"","Type":""},{"AID":"A00000003029057000AD13100101FF","Vendor":"Schlumberger Industries Identif dEncarteur PR050","Country":"France","Name":"BelPIC (Belgian Personal Identity Card) JavaCard Applet","Description":"Schlumberger (Gemalto) RID","Type":""},{"AID":"A0000000308000000000280101","Vendor":"Schlumberger Industries Identif dEncarteur PR050","Country":"France","Name":"Gemalto .NET Card AID","Description":"","Type":""},{"AID":"A0000000421010","Vendor":"Groupement des Cartes Bancaires CB","Country":"France","Name":"Cartes Bancaire EMV Card","Description":"Groupement des Cartes Bancaires (France)","Type":"EMV"},{"AID":"A0000000422010","Vendor":"Groupement des Cartes Bancaires CB","Country":"France","Name":"","Description":"","Type":"EMV"},{"AID":"A0000000423010","Vendor":"Groupement des Cartes Bancaires CB","Country":"France","Name":"","Description":"","Type":"EMV"},{"AID":"A0000000424010","Vendor":"Groupement des Cartes Bancaires CB","Country":"France","Name":"","Description":"","Type":"EMV"},{"AID":"A0000000425010","Vendor":"Groupement des Cartes Bancaires CB","Country":"France","Name":"","Description":"","Type":"EMV"},{"AID":"A0000000426010","Vendor":"Groupement des Cartes Bancaires CB","Country":"France","Name":"Contactless payment using Apple Pay","Description":"","Type":"EMV"},{"AID":"A00000005945430100","Vendor":"Zentraler Kreditausschuss (ZKA)","Country":"Germany","Name":"Girocard Electronic Cash","Description":"","Type":""},{"AID":"A000000063504B43532D3135","Vendor":"RSA Laboratories","Country":"United States","Name":"PKCS-15","Description":"RSA PKCS-15 PKI application (Predecessor to ISO7816-15) / ID-card in Finland","Type":""},{"AID":"A0000000635741502D57494D","Vendor":"RSA Laboratories","Country":"United States","Name":"WAP-WIM","Description":"WAP (Wireless Application Protocol) Identity Module / Wireless Identification Module","Type":""},{"AID":"A00000006510","Vendor":"JCB CO., LTD.","Country":"Japan","Name":"JCB","Description":"Japan Credit Bureau","Type":"EMV"},{"AID":"A0000000651010","Vendor":"JCB CO., LTD.","Country":"Japan","Name":"JCB J Smart Credit","Description":"Japan Credit Bureau","Type":"EMV"},{"AID":"A00000006900","Vendor":"Soci?t? Europ?enne de Monnaie Electronique SEME","Country":"France","Name":"Moneo","Description":"","Type":"EMV"},{"AID":"A000000077010000021000000000003B","Vendor":"Oberthur Technologies","Country":"France","Name":"Visa AEPN","Description":"","Type":"EMV"},{"AID":"A0000000790100","Vendor":"Activcard Europe S.A.","Country":"France","Name":"CACv2 PKI ID","Description":"Identity Key","Type":""},{"AID":"A0000000790101","Vendor":"Activcard Europe S.A.","Country":"France","Name":"CACv2 PKI Sign","Description":"Digital Signature Key","Type":""},{"AID":"A0000000790102","Vendor":"Activcard Europe S.A.","Country":"France","Name":"CACv2 PKI Enc","Description":"Key Management Key","Type":""},{"AID":"A00000007901F0","Vendor":"Activcard Europe S.A.","Country":"France","Name":"CACv1 PKI Identity Key","Description":"Re-directs to CACv2 PKI Identity key","Type":""},{"AID":"A00000007901F1","Vendor":"Activcard Europe S.A.","Country":"France","Name":"CACv1 PKI Digital Signature Key","Description":"Re-directs to CACv2 Digital Signature key","Type":""},{"AID":"A00000007901F2","Vendor":"Activcard Europe S.A.","Country":"France","Name":"CACv1 PKI Key Management Key","Description":"Re-directs to CACv2 Key Management key","Type":""},{"AID":"A0000000790200","Vendor":"Activcard Europe S.A.","Country":"France","Name":"CACv2 DoD Person","Description":"DoD Demographic","Type":""},{"AID":"A0000000790201","Vendor":"Activcard Europe S.A.","Country":"France","Name":"CACv2 DoD Personnel","Description":"DoD Demographic","Type":""},{"AID":"A00000007902FB","Vendor":"Activcard Europe S.A.","Country":"France","Name":"CACv1 BC","Description":"General Configuration","Type":""},{"AID":"A00000007902FD","Vendor":"Activcard Europe S.A.","Country":"France","Name":"CACv1 BC","Description":"PKI Certificate Attributes","Type":""},{"AID":"A00000007902FE","Vendor":"Activcard Europe S.A.","Country":"France","Name":"CACv1 BC","Description":"PKI Cert","Type":""},{"AID":"A0000000790300","Vendor":"Activcard Europe S.A.","Country":"France","Name":"CACv2 Access Control Applet","Description":"CAC PIN / ID PIN Management Applet","Type":""},{"AID":"A0000000791201","Vendor":"Activcard Europe S.A.","Country":"France","Name":"CAC JDM","Description":"Joint Data Model. BCAdmin","Type":""},{"AID":"A0000000791202","Vendor":"Activcard Europe S.A.","Country":"France","Name":"CAC JDM","Description":"Joint Data Model. BCMedical","Type":""},{"AID":"A0000000871002FF49FF0589","Vendor":"Third Generation Partnership Project (3GPP)","Country":"France","Name":"Telenor USIM","Description":"","Type":"USIM"},{"AID":"A00000008810200105C100","Vendor":"Buypass AS","Country":"Norway","Name":"BuyPass BIDA","Description":"Used by norwegian public betting company Norsk-Tipping?","Type":"BuyPass"},{"AID":"A000000088102201034221","Vendor":"Buypass AS","Country":"Norway","Name":"BuyPass BEID (BuyPass Electronic ID?)","Description":"","Type":"BuyPass"},{"AID":"A000000088102201034321","Vendor":"Buypass AS","Country":"Norway","Name":"BuyPass BEID (BuyPass Electronic ID?)","Description":"","Type":"BuyPass"},{"AID":"A0000000960200","Vendor":"Sa Proton World International N.V.","Country":"Belgium","Name":"Proton World International Security Domain","Description":"Proton, which is owned in part by Visa International and American Express Co., is in three other European countries: the original Proton program in Belgium, Chipknip in the Netherlands, and Cash in Switzerland","Type":"GP"},{"AID":"A000000098","Vendor":"Visa USA","Country":"United States","Name":"Debit Card","Description":"Bank of America Debit Card","Type":"EMV"},{"AID":"A0000000980840","Vendor":"Visa USA","Country":"United States","Name":"Visa Common Debit","Description":"","Type":""},{"AID":"A0000000980848","Vendor":"Visa USA","Country":"United States","Name":"Debit Card","Description":"Schwab Bank Debit Card","Type":"EMV"},{"AID":"A0000001110101","Vendor":"Die Post Postfinance","Country":"Switzerland","Name":"Postcard","Description":"","Type":""},{"AID":"A0000001160300","Vendor":"GSA TFCS","Country":"United States","Name":"PIV CHUID","Description":"CHUID","Type":""},{"AID":"A0000001166010","Vendor":"GSA TFCS","Country":"United States","Name":"PIV Fingerprints","Description":"Fingerprints","Type":""},{"AID":"A0000001166030","Vendor":"GSA TFCS","Country":"United States","Name":"PIV Facial Image","Description":"Facial Image","Type":""},{"AID":"A0000001169000","Vendor":"GSA TFCS","Country":"United States","Name":"PIV Security Object","Description":"Security Object","Type":""},{"AID":"A000000116A001","Vendor":"GSA TFCS","Country":"United States","Name":"PIV Authentication Key","Description":"PIV Authentication Key","Type":""},{"AID":"A000000116DB00","Vendor":"GSA TFCS","Country":"United States","Name":"CCC","Description":"Card Capability Container","Type":""},{"AID":"A000000118010000","Vendor":"Austria Card","Country":"Austria","Name":"DF_Verkehr","Description":"Domestic Loyalty Program (Version 1.3)","Type":""},{"AID":"A000000118020000","Vendor":"Austria Card","Country":"Austria","Name":"DF_Partner","Description":"Domestic Loyalty Program (Version 1.3)","Type":""},{"AID":"A000000118030000","Vendor":"Austria Card","Country":"Austria","Name":"DF_Sch?lerdaten","Description":"Domestic Loyalty Program (Version 1.3)","Type":""},{"AID":"A000000118040000","Vendor":"Austria Card","Country":"Austria","Name":"DF_KEP_SIG","Description":"Domestic Loyalty Program (Version 1.32)","Type":""},{"AID":"A0000001184543","Vendor":"Austria Card","Country":"Austria","Name":"Digital Signature (SSCA)","Description":"Digital Signature Application","Type":""},{"AID":"A000000118454E","Vendor":"Austria Card","Country":"Austria","Name":"Encryption Application","Description":"Encryption Application (Version 1.10)","Type":""},{"AID":"A0000001211010","Vendor":"PBS Danmark A/S","Country":"Denmark","Name":"Dankort (VISA GEM Vision)","Description":"Danish domestic debit card","Type":"EMV"},{"AID":"A0000001320001","Vendor":"Java Card Forum","Country":"United States","Name":"org.javacardforum.javacard.biometry","Description":"","Type":""},{"AID":"A0000001408001","Vendor":"TDS TODOS DATA SYSTEM AB","Country":"Sweden","Name":"eCode","Description":"","Type":""},{"AID":"A0000001410001","Vendor":"Associazione Bancaria Italiana","Country":"Italy","Name":"PagoBANCOMAT","Description":"CoGeBan Consorzio BANCOMAT (Italian domestic debit card)","Type":"EMV"},{"AID":"A0000001510000","Vendor":"GlobalPlatform, Inc.","Country":"United States","Name":"Global Platform Security Domain AID","Description":"GP Card Manager","Type":"GP"},{"AID":"A00000015153504341534400","Vendor":"GlobalPlatform, Inc.","Country":"United States","Name":"CASD_AID","Description":"SPCASD","Type":"GP"},{"AID":"A0000001523010","Vendor":"Diners Club International Ltd.","Country":"United States","Name":"Discover, Pulse D Pas","Description":"Discover Card","Type":"EMV"},{"AID":"A0000001524010","Vendor":"Diners Club International Ltd.","Country":"United States","Name":"Discover","Description":"Discover Debit Common Card","Type":"EMV"},{"AID":"A0000001544442","Vendor":"Banrisul Banco do Estado do Rio Grande do SUL S.A.","Country":"Brazil","Name":"Banricompras Debito","Description":"Banrisul (Brazil)","Type":"EMV"},{"AID":"A0000001570010","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"AMEX","Description":"","Type":""},{"AID":"A0000001570020","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"MasterCard","Description":"","Type":""},{"AID":"A0000001570021","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"Maestro","Description":"","Type":""},{"AID":"A0000001570022","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"Maestro","Description":"","Type":""},{"AID":"A0000001570023","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"CASH","Description":"","Type":""},{"AID":"A0000001570030","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"VISA","Description":"","Type":""},{"AID":"A0000001570031","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"VISA","Description":"","Type":""},{"AID":"A0000001570040","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"JCB","Description":"","Type":""},{"AID":"A0000001570050","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"Postcard","Description":"","Type":""},{"AID":"A0000001570051","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"Postcard","Description":"","Type":""},{"AID":"A0000001570100","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"MCard","Description":"","Type":""},{"AID":"A0000001570104","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"MyOne","Description":"","Type":""},{"AID":"A0000001570109","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"Mediamarkt Card","Description":"","Type":""},{"AID":"A000000157010A","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"Gift Card","Description":"","Type":""},{"AID":"A000000157010B","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"Bonuscard","Description":"","Type":""},{"AID":"A000000157010C","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"WIRCard","Description":"","Type":""},{"AID":"A000000157010D","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"Power Card","Description":"","Type":""},{"AID":"A0000001574443","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"DINERS CLUB","Description":"","Type":""},{"AID":"A0000001574444","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"Supercard Plus","Description":"","Type":""},{"AID":"A000000167413000FF","Vendor":"IBM","Country":"Germany","Name":"JCOP Identify Applet","Description":"identify in JCOP-tools returns eg 27 34 01 2E 00 00 00 00 4E 58 37 35 31 41 00 03 28 62 B3 6A 82","Type":"JCOP"},{"AID":"A000000167413001","Vendor":"IBM","Country":"Germany","Name":"FIPS 140-2","Description":"?","Type":""},{"AID":"A000000172950001","Vendor":"Financial Information Service Co. Ltd.","Country":"Taiwan","Name":"BAROC Financial Application Taiwan","Description":"The Bankers Association of the Republic of China","Type":"EMV"},{"AID":"A000000177504B43532D3135","Vendor":"Minist?re de LInt?rieur","Country":"Belgium","Name":"BelPIC (Belgian Personal Identity Card)","Description":"","Type":""},{"AID":"A0000001850002","Vendor":"Post Office Limited","Country":"United Kingdom","Name":"UK Post Office Account card","Description":"","Type":"EMV"},{"AID":"A0000001884443","Vendor":"Diners Club Switzerland Ltd","Country":"Switzerland","Name":"DINERS CLUB","Description":"","Type":""},{"AID":"A0000002040000","Vendor":"Association for Payment Clearing Services","Country":"United Kingdom","Name":"?","Description":"","Type":""},{"AID":"A0000002281010","Vendor":"Saudi Arabian Monetary Agency (SAMA)","Country":"Kingdom of Saudi Arabia","Name":"SPAN (M/Chip)","Description":"SPAN2 (Saudi Payments Network) Saudi Arabia domestic credit/debit card (Saudi Arabia Monetary Agency)","Type":"EMV"},{"AID":"A0000002282010","Vendor":"Saudi Arabian Monetary Agency (SAMA)","Country":"Kingdom of Saudi Arabia","Name":"SPAN (VIS)","Description":"SPAN2 (Saudi Payments Network) Saudi Arabia domestic credit/debit card (Saudi Arabia Monetary Agency)","Type":"EMV"},{"AID":"A00000022820101010","Vendor":"Saudi Arabian Monetary Agency (SAMA)","Country":"Kingdom of Saudi Arabia","Name":"SPAN","Description":"SPAN2 (Saudi Payments Network) Saudi Arabia domestic credit/debit card (Saudi Arabia Monetary Agency)","Type":""},{"AID":"A0000002471001","Vendor":"ISO JTC1/SC17/WG3","Country":"United Kingdom","Name":"Machine Readable Travel Documents (MRTD)","Description":"Electronic (Biometric) Passport. Issuer stored data application (The last three digits of the PIX shall be used to denote future version levels.)","Type":"MRTD"},{"AID":"A0000002472001","Vendor":"ISO JTC1/SC17/WG3","Country":"United Kingdom","Name":"Machine Readable Travel Documents (MRTD)","Description":"Electronic (Biometric) Passport. Application for hashes, digital signature, and certificate (The last three digits of the PIX shall be used to denote future version levels.)","Type":"MRTD"},{"AID":"A0000002771010","Vendor":"Interac Association","Country":"Canada","Name":"INTERAC","Description":"Canadian domestic credit/debit card","Type":"EMV"},{"AID":"A00000030600000000000000","Vendor":"PS/SC Workgroup","Country":"United States","Name":"PC/SC Initial access data AID","Description":"Possibly not an application","Type":""},{"AID":"A000000308000010000100","Vendor":"National Institute of Standards and Technology","Country":"United States","Name":"Personal Identity Verification (PIV) / ID-ONE PIV BIO","Description":"PIV End Point Applet. Last 2 bytes designate version?","Type":""},{"AID":"A00000031510100528","Vendor":"Currence Holding/PIN BV","Country":"The Netherlands","Name":"Currence PuC","Description":"","Type":"EMV"},{"AID":"A0000003156020","Vendor":"Currence Holding/PIN BV","Country":"The Netherlands","Name":"Chipknip","Description":"","Type":"EMV"},{"AID":"A00000032301","Vendor":"Identity Alliance","Country":"United States","Name":"MUSCLE Applet Package","Description":"http://osdir.com/ml/lib.muscle/2005-12/msg00066.html","Type":""},{"AID":"A0000003230101","Vendor":"Identity Alliance","Country":"United States","Name":"MUSCLE Applet Instance","Description":"http://osdir.com/ml/lib.muscle/2005-12/msg00066.html","Type":""},{"AID":"A0000003241010","Vendor":"Discover Financial Services LLC","Country":"United States","Name":"Discover Expresspay (ZIP)","Description":"","Type":""},{"AID":"A000000333010101","Vendor":"China Unionpay Co. Ltd","Country":"China","Name":"UnionPay Debit","Description":"","Type":""},{"AID":"A000000333010102","Vendor":"China Unionpay Co. Ltd","Country":"China","Name":"UnionPay Credit","Description":"","Type":""},{"AID":"A000000333010103","Vendor":"China Unionpay Co. Ltd","Country":"China","Name":"UnionPay Quasi Credit","Description":"","Type":""},{"AID":"A000000333010106","Vendor":"China Unionpay Co. Ltd","Country":"China","Name":"UnionPay Electronic Cash","Description":"","Type":""},{"AID":"A000000333010108","Vendor":"China Unionpay Co. Ltd","Country":"China","Name":"U.S. UnionPay Common Debit AID","Description":"","Type":""},{"AID":"A000000337301000","Vendor":"Groupment Interbancaire Mon?tique de l UEMOA","Country":"Senegal","Name":"Retrait","Description":"","Type":""},{"AID":"A000000337101000","Vendor":"Groupment Interbancaire Mon?tique de l UEMOA","Country":"Senegal","Name":"Standard","Description":"","Type":""},{"AID":"A000000337102000","Vendor":"Groupment Interbancaire Mon?tique de l UEMOA","Country":"Senegal","Name":"Classic","Description":"","Type":""},{"AID":"A000000337101001","Vendor":"Groupment Interbancaire Mon?tique de l UEMOA","Country":"Senegal","Name":"Prepaye Online","Description":"","Type":""},{"AID":"A000000337102001","Vendor":"Groupment Interbancaire Mon?tique de l UEMOA","Country":"Senegal","Name":"Prepaye Possibile Offiline","Description":"","Type":""},{"AID":"A000000337601001","Vendor":"Groupment Interbancaire Mon?tique de l UEMOA","Country":"Senegal","Name":"Porte Monnaie Electronique","Description":"","Type":""},{"AID":"A0000003591010","Vendor":"Euro Alliance of Payment Schemes s.c.r.l. EAPS","Country":"Belgium","Name":"","Description":"Unknown","Type":""},{"AID":"A0000003591010028001","Vendor":"Euro Alliance of Payment Schemes s.c.r.l. EAPS","Country":"Belgium","Name":"Girocard EAPS","Description":"ZKA (Germany)","Type":"EMV"},{"AID":"A00000035910100380","Vendor":"Euro Alliance of Payment Schemes s.c.r.l. EAPS","Country":"Belgium","Name":"","Description":"PagoBANCOMAT","Type":""},{"AID":"A0000003660001","Vendor":"Poste Italiane S.P.A","Country":"Italy","Name":"Postamat","Description":"","Type":""},{"AID":"A0000003660002","Vendor":"Poste Italiane S.P.A","Country":"Italy","Name":"Postamat VISA","Description":"","Type":""},{"AID":"A0000003710001","Vendor":"Verve","Country":"Nigeria","Name":"InterSwitch Verve Card","Description":"Nigerian local switch company","Type":"EMV"},{"AID":"A00000038410","Vendor":"eftpos, Australian Payments Clearing Association Ltd","Country":"Australia","Name":"Savings (debit card)","Description":"","Type":""},{"AID":"A00000038420","Vendor":"eftpos, Australian Payments Clearing Association Ltd","Country":"Australia","Name":"Cheque (debit card)","Description":"","Type":""},{"AID":"A0000003964D66344D0002","Vendor":"NXP Semiconductors Germany GmbH","Country":"Germany","Name":"MIFARE4MOBILE","Description":"NXP Mf4M","Type":""},{"AID":"A00000039742544659","Vendor":"Microsoft Corporation","Country":"United States","Name":"Microsoft IDMP AID","Description":"Identity Device With Microsoft Generic Profile application. 2 bytes can be added at the end. This byte must be set to the IDMP specification revision number which is currently 0x01. The second byte (yy) is reserved for use by the card application.","Type":""},{"AID":"A0000003974349445F0100","Vendor":"Microsoft Corporation","Country":"United States","Name":"Microsoft PNP AID","Description":"MS Plug and Play","Type":""},{"AID":"A0000004271010","Vendor":"Unibanco (Hipercard)","Country":"Brazil","Name":"Hiperchip","Description":"","Type":""},{"AID":"A0000004320001","Vendor":"100","Country":"Russia","Name":"Universal Electronic Card","Description":"","Type":""},{"AID":"A0000004360100","Vendor":"Edenred","Country":"Belgium","Name":"Ticket Restaurant","Description":"","Type":""},{"AID":"A0000004391010","Vendor":"ACCEL/Exchange","Country":"United States","Name":"Exchange ATM card","Description":"The Exchange Network ATM Network","Type":""},{"AID":"A0000004540010","Vendor":"eTranzact","Country":"Nigeria","Name":"Etranzact Genesis Card","Description":"Nigerian local switch company","Type":"EMV"},{"AID":"A0000004540011","Vendor":"eTranzact","Country":"Nigeria","Name":"Etranzact Genesis Card 2","Description":"Nigerian local switch company","Type":"EMV"},{"AID":"A0000004762010","Vendor":"Google","Country":"United States","Name":"GOOGLE_CONTROLLER_AID","Description":"GOOGLE_LOCKET_AID","Type":""},{"AID":"A0000004763030","Vendor":"Google","Country":"United States","Name":"GOOGLE_MIFARE_MANAGER_AID","Description":"","Type":""},{"AID":"A0000004766C","Vendor":"Google","Country":"United States","Name":"GOOGLE_PAYMENT_AID","Description":"","Type":"EMV"},{"AID":"A000000476A010","Vendor":"Google","Country":"United States","Name":"GSD_MANAGER_AID","Description":"","Type":"GP"},{"AID":"A000000476A110","Vendor":"Google","Country":"United States","Name":"GSD_MANAGER_AID","Description":"","Type":"GP"},{"AID":"A000000485","Vendor":"JVL Ventures, LLC (Softcard)","Country":"United States","Name":"Softcard SmartTap","Description":"","Type":""},{"AID":"A0000005241010","Vendor":"RuPay","Country":"India","Name":"RuPay","Description":"RuPay (India)","Type":"EMV"},{"AID":"A0000005271002","Vendor":"Yubico","Country":"Sweden","Name":"Yubikey NEO U2F Demo applet","Description":"Universal 2-Factor Proof-of-concept/Demo","Type":"YKNEO"},{"AID":"A000000527200101","Vendor":"Yubico","Country":"Sweden","Name":"Yubikey NEO Yubikey2 applet interface","Description":"Javacard Applet AID","Type":"YKNEO"},{"AID":"A000000527210101","Vendor":"Yubico","Country":"Sweden","Name":"Yubikey NEO OATH Applet","Description":"Javacard Applet AID","Type":"YKNEO"},{"AID":"A0000005591010FFFFFFFF8900000100","Vendor":"GSMA (GSM Association)","Country":"United Kingdom","Name":"ISD-R Application. Used as TAR.","Description":"","Type":""},{"AID":"A0000005591010FFFFFFFF8900000200","Vendor":"GSMA (GSM Association)","Country":"United Kingdom","Name":"ECASD Application. Used as TAR.","Description":"","Type":""},{"AID":"A0000005591010FFFFFFFF8900000D00","Vendor":"GSMA (GSM Association)","Country":"United Kingdom","Name":"ISD-P Executable Load File.","Description":"","Type":""},{"AID":"A0000005591010FFFFFFFF8900000E00","Vendor":"GSMA (GSM Association)","Country":"United Kingdom","Name":"ISD-P Executable Module.","Description":"","Type":""},{"AID":"A0000005591010FFFFFFFF8900000F00","Vendor":"GSMA (GSM Association)","Country":"United Kingdom","Name":"Reserved value for the Profiles ISD-P","Description":"","Type":""},{"AID":"A0000005591010FFFFFFFF8900001000","Vendor":"GSMA (GSM Association)","Country":"United Kingdom","Name":"ISD-P Application (1010FFFFFFFF89000010 to 1010FFFFFFFF8900FFFF. Used as TAR. The value is allocated during the Profile Download and Installation procedure","Description":"","Type":""},{"AID":"A00000061700","Vendor":"Fidesmo","Country":"Sweden","Name":"Fidesmo javacard","Description":"","Type":""},{"AID":"A0000006200620","Vendor":"Debit Network Alliance (DNA)","Country":"United States","Name":"Debit Network Alliance (DNA)","Description":"Common U.S. Debit","Type":""},{"AID":"A0000006581010","Vendor":"MIR","Country":"Russia","Name":"MIR Credit","Description":"","Type":""},{"AID":"A0000006581011","Vendor":"MIR","Country":"Russia","Name":"MIR Credit","Description":"","Type":""},{"AID":"A0000006582010","Vendor":"MIR","Country":"Russia","Name":"MIR Debit","Description":"","Type":""},{"AID":"A0000006723010","Vendor":"TROY","Country":"Turkey","Name":"TROY chip credit card","Description":"Turkeys Payment Method","Type":"EMV"},{"AID":"A0000006723020","Vendor":"TROY","Country":"Turkey","Name":"TROY chip debit card","Description":"Turkeys Payment Method","Type":"EMV"},{"AID":"A0000007705850","Vendor":"Indian Oil Corporation Limited","Country":"India","Name":"XTRAPOWER Fleet Card Program","Description":"Indian Oils Pre Paid Program","Type":"EMV"},{"AID":"A0000007790000","Vendor":"Zimswitch","Country":"Zimbabwe","Name":"","Description":"","Type":""},{"AID":"B012345678","Vendor":"MasterCard International","Country":"United States","Name":"Maestro TEST","Description":"Used for development","Type":"EMV"},{"AID":"D040000001000002","Vendor":"Paylife","Country":"Austria","Name":"Paylife Quick (IEP). Preloaded Electronic Purse","Description":"Domestic Payment System (Version 2.1)","Type":""},{"AID":"D040000002000002","Vendor":"Austria Card","Country":"Austria","Name":"RFU","Description":"Domestic Payment System (Version 2.1)","Type":""},{"AID":"D040000003000002","Vendor":"Austria Card","Country":"Austria","Name":"POS","Description":"Domestic Payment System (Version 2.1)","Type":""},{"AID":"D040000004000002","Vendor":"Austria Card","Country":"Austria","Name":"ATM","Description":"Domestic Payment System (Version 2.1)","Type":""},{"AID":"D04000000B000002","Vendor":"Austria Card","Country":"Austria","Name":"Retail","Description":"Domestic Loyalty Program (Version 2.1)","Type":""},{"AID":"D04000000C000002","Vendor":"Austria Card","Country":"Austria","Name":"Bank_Data","Description":"Domestic Loyalty Program (Version 2.1)","Type":""},{"AID":"D04000000D000002","Vendor":"Austria Card","Country":"Austria","Name":"Shopping","Description":"Domestic Loyalty Program (Version 2.1)","Type":""},{"AID":"D040000013000001","Vendor":"Austria Card","Country":"Austria","Name":"DF_UNI_Kepler1","Description":"Domestic Loyalty Program (Version 2.0)","Type":""},{"AID":"D040000013000001","Vendor":"Austria Card","Country":"Austria","Name":"DF_Sch?ler1","Description":"Domestic Loyalty Program (Version 1.3)","Type":""},{"AID":"D040000013000002","Vendor":"Austria Card","Country":"Austria","Name":"DF_UNI_Kepler2","Description":"Domestic Loyalty Program (Version 2.0)","Type":""},{"AID":"D040000013000002","Vendor":"Austria Card","Country":"Austria","Name":"DF_Sch?ler2","Description":"Domestic Loyalty Program (Version 1.3)","Type":""},{"AID":"D040000014000001","Vendor":"Austria Card","Country":"Austria","Name":"DF_Mensa","Description":"Domestic Loyalty Program (Version 2.0)","Type":""},{"AID":"D040000015000001","Vendor":"Austria Card","Country":"Austria","Name":"DF_UNI_Ausweis","Description":"Domestic Loyalty Program (Version 2.0)","Type":""},{"AID":"D040000015000001","Vendor":"Austria Card","Country":"Austria","Name":"DF_Ausweis","Description":"Domestic Loyalty Program (Version 1.3)","Type":""},{"AID":"D0400000190001","Vendor":"Austria Card","Country":"Austria","Name":"EMV ATM Maestro","Description":"Domestic EMV Application (Version 2.1)","Type":""},{"AID":"D0400000190002","Vendor":"Austria Card","Country":"Austria","Name":"EMV POS Maestro","Description":"Domestic EMV Application (Version 2.1)","Type":""},{"AID":"D0400000190003","Vendor":"Austria Card","Country":"Austria","Name":"EMV ATM MasterCard","Description":"Domestic EMV Application (Version 2.1)","Type":""},{"AID":"D0400000190004","Vendor":"Austria Card","Country":"Austria","Name":"EMV POS MasterCard","Description":"Domestic EMV Application (Version 2.1)","Type":""},{"AID":"D0400000190010","Vendor":"Austria Card","Country":"Austria","Name":"Digital ID","Description":"Domestic Payment System (Version 2.1)","Type":""},{"AID":"D268000001","Vendor":"Ministry of Finance of Georgia","Country":"Georgia","Name":"Fiscal module application","Description":"Georgia Revenue Service application for fiscal cash registers","Type":""},{"AID":"D276000005","Vendor":"Giesecke&Devrient","Country":"Germany","Name":"","Description":"Giesecke & Devrient","Type":""},{"AID":"D276000005AA040360010410","Vendor":"Giesecke&Devrient","Country":"Germany","Name":"G D App Nokia 6212","Description":"","Type":""},{"AID":"D276000005AA0503E00401","Vendor":"Giesecke&Devrient","Country":"Germany","Name":"G D App Nokia 6212","Description":"","Type":""},{"AID":"D276000005AA0503E00501","Vendor":"Giesecke&Devrient","Country":"Germany","Name":"G D App Nokia 6212","Description":"","Type":""},{"AID":"D276000005AA0503E0050101","Vendor":"Giesecke&Devrient","Country":"Germany","Name":"G D App Nokia 6212","Description":"","Type":""},{"AID":"D276000005AB0503E0040101","Vendor":"Giesecke&Devrient","Country":"Germany","Name":"G D App Nokia 6212","Description":"","Type":""},{"AID":"D27600002200000001","Vendor":"IBM Laboratories","Country":"Germany","Name":"SCT LOYALTY","Description":"IBM Test card from the book Smart Card Application Development Using Java","Type":""},{"AID":"D27600002200000002","Vendor":"IBM Laboratories","Country":"Germany","Name":"BUSINESS CARD","Description":"IBM Test card from the book Smart Card Application Development Using Java","Type":""},{"AID":"D27600002200000060","Vendor":"IBM Laboratories","Country":"Germany","Name":"PKCS#11 Token","Description":"IBM Test card from the book Smart Card Application Development Using Java","Type":""},{"AID":"D276000025","Vendor":"ZKA","Country":"Germany","Name":"Girocard","Description":"Girocard (Geldkarte) in Germany","Type":""},{"AID":"D27600002545410100","Vendor":"ZKA","Country":"Germany","Name":"","Description":"Unknown","Type":""},{"AID":"D27600002545500100","Vendor":"ZKA","Country":"Germany","Name":"Girocard","Description":"ZKA Girocard (Geldkarte) (Germany)","Type":"EMV"},{"AID":"D27600002547410100","Vendor":"ZKA","Country":"Germany","Name":"Girocard ATM","Description":"","Type":""},{"AID":"D276000060","Vendor":"Wolfgang Rankl","Country":"Germany","Name":"","Description":"","Type":""},{"AID":"D2760000850100","Vendor":"NXP Semiconductors / NFC Forum","Country":"Germany","Name":"NDEF Tag Application / Mifare DESFire Tag Application","Description":"NFC Forum Type 4 Tag","Type":""},{"AID":"D2760000850101","Vendor":"NXP Semiconductors / NFC Forum","Country":"Germany","Name":"NDEF Tag Application","Description":"NFC Tag type 4 tag","Type":""},{"AID":"D276000118","Vendor":"Giesecke&Devrient Java Card Telecommunikation","Country":"Germany","Name":"","Description":"","Type":""},{"AID":"D2760001180101","Vendor":"Giesecke&Devrient Java Card Telecommunikation","Country":"Germany","Name":"Giesecke &","Description":"Devrient Test Applet?","Type":""},{"AID":"D27600012401","Vendor":"fsfEurope","Country":"Germany","Name":"OpenPGP Card","Description":"For selection when not knowing the exact full AID","Type":"OpenPGP"},{"AID":"D276000124010101FFFF000000010000","Vendor":"fsfEurope","Country":"Germany","Name":"OpenPGP Card","Description":"Version 1","Type":"OpenPGP"},{"AID":"D2760001240102000000000000010000","Vendor":"fsfEurope","Country":"Germany","Name":"OpenPGP Card","Description":"Version 2","Type":"OpenPGP"},{"AID":"D27600012402","Vendor":"fsfEurope","Country":"Germany","Name":"SmartChess","Description":"http://smartchess.de/englisch/SmartChess_1.0.pdf","Type":"SmartChess"},{"AID":"D2760001240200010000000000000000","Vendor":"fsfEurope","Country":"Germany","Name":"SmartChess","Description":"http://smartchess.de/englisch/SmartChess_1.0.pdf","Type":"SmartChess"},{"AID":"D4100000011010","Vendor":"","Country":"Republic of Korea","Name":"","Description":"","Type":""},{"AID":"D5280050218002","Vendor":"","Country":"The Netherlands","Name":"?","Description":"(Netherlands)","Type":"EMV"},{"AID":"D5780000021010","Vendor":"Bankaxept","Country":"Norway","Name":"Bankaxept","Description":"Norwegian domestic debit card","Type":"EMV"},{"AID":"D7560000010101","Vendor":"Swiss Travel Fund (Reka)","Country":"Switzerland","Name":"Reka Card","Description":"prepaid functional debit card","Type":""},{"AID":"D7560000300101","Vendor":"Migros (FCM, GE Money Bank and MasterCard)","Country":"Switzerland","Name":"M Budget","Description":"","Type":""},{"AID":"E80704007F00070302","Vendor":"","Country":"","Name":"nPA","Description":"German eID","Type":""},{"AID":"E82881C11702","Vendor":"","Country":"","Name":"AlphaCard application","Description":"","Type":""},{"AID":"E828BD080F","Vendor":"","Country":"","Name":"ISO-7816-15 EF.DIR","Description":"Iso adoption of PKCS-15","Type":""},{"AID":"F0000000030001","Vendor":"","Country":"","Name":"BRADESCO","Description":"Brazilian Bank Banco Bradesco","Type":"EMV"}] \ No newline at end of file From 032019763e1a439920c34220faffc1edd49bced6 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 4 Nov 2019 18:08:46 +0200 Subject: [PATCH 1110/1854] add tesla https://gist.github.com/darconeous/2cd2de11148e3a75685940158bddf933 --- client/resources/aidlist.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/resources/aidlist.json b/client/resources/aidlist.json index 86c5ccab1..10ca4e8b0 100644 --- a/client/resources/aidlist.json +++ b/client/resources/aidlist.json @@ -1 +1 @@ -[{"AID":"315041592E5359532E4444463031","Vendor":"Visa International","Country":"United States","Name":"Visa Payment System Environment PSE (1PAY.SYS.DDF01)","Description":"","Type":""},{"AID":"325041592E5359532E4444463031","Vendor":"Visa International","Country":"United States","Name":"Visa Proximity Payment System Environment PPSE (2PAY.SYS.DDF01)","Description":"Visa payWave for Mobile","Type":""},{"AID":"44464D46412E44466172653234313031","Vendor":"DeviceFidelity","Country":"United States","Name":"DeviceFidelity In2Pay DFare applet","Description":"http://www.nfcworld.com/2010/11/24/35207/devicefidelity-adds-nfc-support-for-android-and-mifare/","Type":""},{"AID":"A00000000101","Vendor":"PBS Danm?nt A/S","Country":"Denmark","Name":"MUSCLE Card Applet","Description":"(Unlicensed use of this RID. Proposal to use A000000323 instead)","Type":""},{"AID":"A000000003000000","Vendor":"Visa International","Country":"United States","Name":"(VISA) Card Manager","Description":"Used by most GP2.1.1 cards / Oberthur OP201 cards. Visa Proprietary Card Manager AID for OpenPlatform cards (visa.openplatform).","Type":"GP"},{"AID":"A00000000300037561","Vendor":"Visa International","Country":"United States","Name":"Bonuscard","Description":"","Type":""},{"AID":"A00000000305076010","Vendor":"Visa International","Country":"United States","Name":"VISA ELO Credit","Description":"","Type":"EMV"},{"AID":"A0000000031010","Vendor":"Visa International","Country":"United States","Name":"VISA Debit/Credit (Classic)","Description":"Standard/Gold VISA credit card","Type":"EMV"},{"AID":"A000000003101001","Vendor":"Visa International","Country":"United States","Name":"VISA Credit","Description":"","Type":"EMV"},{"AID":"A000000003101002","Vendor":"Visa International","Country":"United States","Name":"VISA Debit","Description":"","Type":"EMV"},{"AID":"A0000000032010","Vendor":"Visa International","Country":"United States","Name":"VISA Electron","Description":"VISA Electron (Debit)","Type":"EMV"},{"AID":"A0000000032020","Vendor":"Visa International","Country":"United States","Name":"VISA","Description":"V PAY","Type":"EMV"},{"AID":"A0000000033010","Vendor":"Visa International","Country":"United States","Name":"VISA Interlink","Description":"VISA Interlink","Type":"EMV"},{"AID":"A0000000034010","Vendor":"Visa International","Country":"United States","Name":"VISA Specific","Description":"Visa Specific","Type":"EMV"},{"AID":"A0000000035010","Vendor":"Visa International","Country":"United States","Name":"VISA Specific","Description":"Visa Specific","Type":"EMV"},{"AID":"A000000003534441","Vendor":"Visa International","Country":"United States","Name":"Schlumberger Security Domain","Description":"","Type":"GP"},{"AID":"A0000000035350","Vendor":"Visa International","Country":"United States","Name":"Security Domain","Description":"OCS Oberthur Card System Security Domain Package AID / VGP Card Manager (for ISD and ASD)","Type":"GP"},{"AID":"A000000003535041","Vendor":"Visa International","Country":"United States","Name":"Security Domain","Description":"OCS Oberthur Card System Security Domain Applet AID / VGP Card Manager (for ISD and ASD)","Type":"GP"},{"AID":"A0000000036010","Vendor":"Visa International","Country":"United States","Name":"Domestic Visa Cash Stored Value","Description":"","Type":"EMV"},{"AID":"A0000000036020","Vendor":"Visa International","Country":"United States","Name":"International Visa Cash Stored Value","Description":"","Type":"EMV"},{"AID":"A0000000038002","Vendor":"Visa International","Country":"United States","Name":"VISA Auth, VisaRemAuthen EMV-CAP (DPA)","Description":"VISA Auth dynamic passcode authentication (DPA). Used by Barclays/HBOS","Type":"EMV"},{"AID":"A0000000038010","Vendor":"Visa International","Country":"United States","Name":"VISA Plus","Description":"VISA plus","Type":"EMV"},{"AID":"A0000000039010","Vendor":"Visa International","Country":"United States","Name":"VISA Loyalty","Description":"","Type":"EMV"},{"AID":"A000000003999910","Vendor":"Visa International","Country":"United States","Name":"VISA Proprietary ATM","Description":"","Type":"EMV"},{"AID":"A0000000040000","Vendor":"Mastercard International","Country":"United States","Name":"MasterCard Card Manager","Description":"Security Domain","Type":"GP"},{"AID":"A00000000401","Vendor":"Mastercard International","Country":"United States","Name":"MasterCard PayPass","Description":"AEPM (Association Europ?enne Payez Mobile)","Type":"EMV"},{"AID":"A0000000041010","Vendor":"Mastercard International","Country":"United States","Name":"MasterCard Credit/Debit (Global)","Description":"Standard MasterCard","Type":"EMV"},{"AID":"A00000000410101213","Vendor":"Mastercard International","Country":"United States","Name":"MasterCard Credit","Description":"Standard MasterCard","Type":"EMV"},{"AID":"A00000000410101215","Vendor":"Mastercard International","Country":"United States","Name":"MasterCard Credit","Description":"Standard MasterCard","Type":"EMV"},{"AID":"A0000000041010BB5449435301","Vendor":"Mastercard International","Country":"United States","Name":"[UNKNOWN]","Description":"Some co-branded card?","Type":""},{"AID":"A0000000042010","Vendor":"Mastercard International","Country":"United States","Name":"MasterCard Specific","Description":"MasterCard Specific","Type":"EMV"},{"AID":"A0000000042203","Vendor":"Mastercard International","Country":"United States","Name":"MasterCard Specific","Description":"MasterCard U.S. Maestro","Type":""},{"AID":"A0000000043010","Vendor":"Mastercard International","Country":"United States","Name":"MasterCard Specific","Description":"MasterCard Specific","Type":"EMV"},{"AID":"A0000000043060","Vendor":"Mastercard International","Country":"United States","Name":"Maestro (Debit)","Description":"Maestro (Debit) Card","Type":"EMV"},{"AID":"A000000004306001","Vendor":"Mastercard International","Country":"United States","Name":"Maestro (Debit)","Description":"Maestro (Debit) Card","Type":"EMV"},{"AID":"A0000000044010","Vendor":"Mastercard International","Country":"United States","Name":"MasterCard Specific","Description":"MasterCard Specific","Type":"EMV"},{"AID":"A0000000045010","Vendor":"Mastercard International","Country":"United States","Name":"MasterCard Specific","Description":"MasterCard Specific","Type":"EMV"},{"AID":"A0000000045555","Vendor":"Mastercard International","Country":"United States","Name":"APDULogger","Description":"AID on Cirrus Test Card","Type":""},{"AID":"A0000000046000","Vendor":"Mastercard International","Country":"United States","Name":"Cirrus","Description":"Mastercard Cirrus (Interbank Network) ATM card only","Type":"EMV"},{"AID":"A0000000048002","Vendor":"Mastercard International","Country":"United States","Name":"SecureCode Auth EMV-CAP","Description":"Chip Authentication Protocol (CAP). Works with NatWest or SecureCode Aut","Type":"EMV"},{"AID":"A0000000049999","Vendor":"Mastercard International","Country":"United States","Name":"MasterCard PayPass??","Description":"","Type":"EMV"},{"AID":"A0000000050001","Vendor":"Switch Card Services Ltd.","Country":"United Kingdom","Name":"Maestro UK","Description":"UK Domestic Maestro Switch (debit card)","Type":"EMV"},{"AID":"A0000000050002","Vendor":"Switch Card Services Ltd.","Country":"United Kingdom","Name":"Solo","Description":"UK Domestic Maestro Switch (debit card)","Type":"EMV"},{"AID":"A0000000090001FF44FF1289","Vendor":"ETSI","Country":"France","Name":"Orange","Description":"Orange UK","Type":""},{"AID":"A0000000101030","Vendor":"Europay International","Country":"Belgium","Name":"Maestro-CH","Description":"","Type":""},{"AID":"A00000001800","Vendor":"GEMPLUS","Country":"France","Name":"Gemplus ?","Description":"","Type":""},{"AID":"A0000000181001","Vendor":"GEMPLUS","Country":"France","Name":"com.gemplus.javacard.util packages","Description":"","Type":""},{"AID":"A000000018434D","Vendor":"GEMPLUS","Country":"France","Name":"Gemplus card manager","Description":"434D = CM (ascii). Security domain for some GCX/GXP cards (GemXpresso Pro) (Gemalto)","Type":"GP"},{"AID":"A000000018434D00","Vendor":"GEMPLUS","Country":"France","Name":"Gemplus Security Domain","Description":"(Gemalto)","Type":"GP"},{"AID":"A00000002401","Vendor":"Midland Bank Plc","Country":"United Kingdom","Name":"Self Service","Description":"","Type":"EMV"},{"AID":"A000000025","Vendor":"American Express","Country":"United Kingdom","Name":"American Express","Description":"","Type":"EMV"},{"AID":"A0000000250000","Vendor":"American Express","Country":"United Kingdom","Name":"American Express","Description":"American Express (Credit/Debit)","Type":"EMV"},{"AID":"A00000002501","Vendor":"American Express","Country":"United Kingdom","Name":"American Express","Description":"AEIPS-compliant (A-E contact EMV) payment application","Type":"EMV"},{"AID":"A000000025010104","Vendor":"American Express","Country":"United Kingdom","Name":"American Express","Description":"","Type":""},{"AID":"A000000025010402","Vendor":"American Express","Country":"United Kingdom","Name":"American Express","Description":"","Type":"EMV"},{"AID":"A000000025010701","Vendor":"American Express","Country":"United Kingdom","Name":"ExpressPay","Description":"","Type":"EMV"},{"AID":"A000000025010801","Vendor":"American Express","Country":"United Kingdom","Name":"American Express","Description":"","Type":"EMV"},{"AID":"A0000000291010","Vendor":"LINK Interchange Network Ltd","Country":"United Kingdom","Name":"Link / American Express","Description":"Link (UK) ATM Network, or AMEX (Portugal?)","Type":"EMV"},{"AID":"A00000002945087510100000","Vendor":"LINK Interchange Network Ltd","Country":"United Kingdom","Name":"CO-OP","Description":"","Type":""},{"AID":"A00000002949034010100001","Vendor":"LINK Interchange Network Ltd","Country":"United Kingdom","Name":"HSBC","Description":"","Type":""},{"AID":"A00000002949282010100000","Vendor":"LINK Interchange Network Ltd","Country":"United Kingdom","Name":"Barclay","Description":"","Type":""},{"AID":"A000000029564182","Vendor":"LINK Interchange Network Ltd","Country":"United Kingdom","Name":"HAFX","Description":"","Type":""},{"AID":"A00000003029057000AD13100101FF","Vendor":"Schlumberger Industries Identif dEncarteur PR050","Country":"France","Name":"BelPIC (Belgian Personal Identity Card) JavaCard Applet","Description":"Schlumberger (Gemalto) RID","Type":""},{"AID":"A0000000308000000000280101","Vendor":"Schlumberger Industries Identif dEncarteur PR050","Country":"France","Name":"Gemalto .NET Card AID","Description":"","Type":""},{"AID":"A0000000421010","Vendor":"Groupement des Cartes Bancaires CB","Country":"France","Name":"Cartes Bancaire EMV Card","Description":"Groupement des Cartes Bancaires (France)","Type":"EMV"},{"AID":"A0000000422010","Vendor":"Groupement des Cartes Bancaires CB","Country":"France","Name":"","Description":"","Type":"EMV"},{"AID":"A0000000423010","Vendor":"Groupement des Cartes Bancaires CB","Country":"France","Name":"","Description":"","Type":"EMV"},{"AID":"A0000000424010","Vendor":"Groupement des Cartes Bancaires CB","Country":"France","Name":"","Description":"","Type":"EMV"},{"AID":"A0000000425010","Vendor":"Groupement des Cartes Bancaires CB","Country":"France","Name":"","Description":"","Type":"EMV"},{"AID":"A0000000426010","Vendor":"Groupement des Cartes Bancaires CB","Country":"France","Name":"Contactless payment using Apple Pay","Description":"","Type":"EMV"},{"AID":"A00000005945430100","Vendor":"Zentraler Kreditausschuss (ZKA)","Country":"Germany","Name":"Girocard Electronic Cash","Description":"","Type":""},{"AID":"A000000063504B43532D3135","Vendor":"RSA Laboratories","Country":"United States","Name":"PKCS-15","Description":"RSA PKCS-15 PKI application (Predecessor to ISO7816-15) / ID-card in Finland","Type":""},{"AID":"A0000000635741502D57494D","Vendor":"RSA Laboratories","Country":"United States","Name":"WAP-WIM","Description":"WAP (Wireless Application Protocol) Identity Module / Wireless Identification Module","Type":""},{"AID":"A00000006510","Vendor":"JCB CO., LTD.","Country":"Japan","Name":"JCB","Description":"Japan Credit Bureau","Type":"EMV"},{"AID":"A0000000651010","Vendor":"JCB CO., LTD.","Country":"Japan","Name":"JCB J Smart Credit","Description":"Japan Credit Bureau","Type":"EMV"},{"AID":"A00000006900","Vendor":"Soci?t? Europ?enne de Monnaie Electronique SEME","Country":"France","Name":"Moneo","Description":"","Type":"EMV"},{"AID":"A000000077010000021000000000003B","Vendor":"Oberthur Technologies","Country":"France","Name":"Visa AEPN","Description":"","Type":"EMV"},{"AID":"A0000000790100","Vendor":"Activcard Europe S.A.","Country":"France","Name":"CACv2 PKI ID","Description":"Identity Key","Type":""},{"AID":"A0000000790101","Vendor":"Activcard Europe S.A.","Country":"France","Name":"CACv2 PKI Sign","Description":"Digital Signature Key","Type":""},{"AID":"A0000000790102","Vendor":"Activcard Europe S.A.","Country":"France","Name":"CACv2 PKI Enc","Description":"Key Management Key","Type":""},{"AID":"A00000007901F0","Vendor":"Activcard Europe S.A.","Country":"France","Name":"CACv1 PKI Identity Key","Description":"Re-directs to CACv2 PKI Identity key","Type":""},{"AID":"A00000007901F1","Vendor":"Activcard Europe S.A.","Country":"France","Name":"CACv1 PKI Digital Signature Key","Description":"Re-directs to CACv2 Digital Signature key","Type":""},{"AID":"A00000007901F2","Vendor":"Activcard Europe S.A.","Country":"France","Name":"CACv1 PKI Key Management Key","Description":"Re-directs to CACv2 Key Management key","Type":""},{"AID":"A0000000790200","Vendor":"Activcard Europe S.A.","Country":"France","Name":"CACv2 DoD Person","Description":"DoD Demographic","Type":""},{"AID":"A0000000790201","Vendor":"Activcard Europe S.A.","Country":"France","Name":"CACv2 DoD Personnel","Description":"DoD Demographic","Type":""},{"AID":"A00000007902FB","Vendor":"Activcard Europe S.A.","Country":"France","Name":"CACv1 BC","Description":"General Configuration","Type":""},{"AID":"A00000007902FD","Vendor":"Activcard Europe S.A.","Country":"France","Name":"CACv1 BC","Description":"PKI Certificate Attributes","Type":""},{"AID":"A00000007902FE","Vendor":"Activcard Europe S.A.","Country":"France","Name":"CACv1 BC","Description":"PKI Cert","Type":""},{"AID":"A0000000790300","Vendor":"Activcard Europe S.A.","Country":"France","Name":"CACv2 Access Control Applet","Description":"CAC PIN / ID PIN Management Applet","Type":""},{"AID":"A0000000791201","Vendor":"Activcard Europe S.A.","Country":"France","Name":"CAC JDM","Description":"Joint Data Model. BCAdmin","Type":""},{"AID":"A0000000791202","Vendor":"Activcard Europe S.A.","Country":"France","Name":"CAC JDM","Description":"Joint Data Model. BCMedical","Type":""},{"AID":"A0000000871002FF49FF0589","Vendor":"Third Generation Partnership Project (3GPP)","Country":"France","Name":"Telenor USIM","Description":"","Type":"USIM"},{"AID":"A00000008810200105C100","Vendor":"Buypass AS","Country":"Norway","Name":"BuyPass BIDA","Description":"Used by norwegian public betting company Norsk-Tipping?","Type":"BuyPass"},{"AID":"A000000088102201034221","Vendor":"Buypass AS","Country":"Norway","Name":"BuyPass BEID (BuyPass Electronic ID?)","Description":"","Type":"BuyPass"},{"AID":"A000000088102201034321","Vendor":"Buypass AS","Country":"Norway","Name":"BuyPass BEID (BuyPass Electronic ID?)","Description":"","Type":"BuyPass"},{"AID":"A0000000960200","Vendor":"Sa Proton World International N.V.","Country":"Belgium","Name":"Proton World International Security Domain","Description":"Proton, which is owned in part by Visa International and American Express Co., is in three other European countries: the original Proton program in Belgium, Chipknip in the Netherlands, and Cash in Switzerland","Type":"GP"},{"AID":"A000000098","Vendor":"Visa USA","Country":"United States","Name":"Debit Card","Description":"Bank of America Debit Card","Type":"EMV"},{"AID":"A0000000980840","Vendor":"Visa USA","Country":"United States","Name":"Visa Common Debit","Description":"","Type":""},{"AID":"A0000000980848","Vendor":"Visa USA","Country":"United States","Name":"Debit Card","Description":"Schwab Bank Debit Card","Type":"EMV"},{"AID":"A0000001110101","Vendor":"Die Post Postfinance","Country":"Switzerland","Name":"Postcard","Description":"","Type":""},{"AID":"A0000001160300","Vendor":"GSA TFCS","Country":"United States","Name":"PIV CHUID","Description":"CHUID","Type":""},{"AID":"A0000001166010","Vendor":"GSA TFCS","Country":"United States","Name":"PIV Fingerprints","Description":"Fingerprints","Type":""},{"AID":"A0000001166030","Vendor":"GSA TFCS","Country":"United States","Name":"PIV Facial Image","Description":"Facial Image","Type":""},{"AID":"A0000001169000","Vendor":"GSA TFCS","Country":"United States","Name":"PIV Security Object","Description":"Security Object","Type":""},{"AID":"A000000116A001","Vendor":"GSA TFCS","Country":"United States","Name":"PIV Authentication Key","Description":"PIV Authentication Key","Type":""},{"AID":"A000000116DB00","Vendor":"GSA TFCS","Country":"United States","Name":"CCC","Description":"Card Capability Container","Type":""},{"AID":"A000000118010000","Vendor":"Austria Card","Country":"Austria","Name":"DF_Verkehr","Description":"Domestic Loyalty Program (Version 1.3)","Type":""},{"AID":"A000000118020000","Vendor":"Austria Card","Country":"Austria","Name":"DF_Partner","Description":"Domestic Loyalty Program (Version 1.3)","Type":""},{"AID":"A000000118030000","Vendor":"Austria Card","Country":"Austria","Name":"DF_Sch?lerdaten","Description":"Domestic Loyalty Program (Version 1.3)","Type":""},{"AID":"A000000118040000","Vendor":"Austria Card","Country":"Austria","Name":"DF_KEP_SIG","Description":"Domestic Loyalty Program (Version 1.32)","Type":""},{"AID":"A0000001184543","Vendor":"Austria Card","Country":"Austria","Name":"Digital Signature (SSCA)","Description":"Digital Signature Application","Type":""},{"AID":"A000000118454E","Vendor":"Austria Card","Country":"Austria","Name":"Encryption Application","Description":"Encryption Application (Version 1.10)","Type":""},{"AID":"A0000001211010","Vendor":"PBS Danmark A/S","Country":"Denmark","Name":"Dankort (VISA GEM Vision)","Description":"Danish domestic debit card","Type":"EMV"},{"AID":"A0000001320001","Vendor":"Java Card Forum","Country":"United States","Name":"org.javacardforum.javacard.biometry","Description":"","Type":""},{"AID":"A0000001408001","Vendor":"TDS TODOS DATA SYSTEM AB","Country":"Sweden","Name":"eCode","Description":"","Type":""},{"AID":"A0000001410001","Vendor":"Associazione Bancaria Italiana","Country":"Italy","Name":"PagoBANCOMAT","Description":"CoGeBan Consorzio BANCOMAT (Italian domestic debit card)","Type":"EMV"},{"AID":"A0000001510000","Vendor":"GlobalPlatform, Inc.","Country":"United States","Name":"Global Platform Security Domain AID","Description":"GP Card Manager","Type":"GP"},{"AID":"A00000015153504341534400","Vendor":"GlobalPlatform, Inc.","Country":"United States","Name":"CASD_AID","Description":"SPCASD","Type":"GP"},{"AID":"A0000001523010","Vendor":"Diners Club International Ltd.","Country":"United States","Name":"Discover, Pulse D Pas","Description":"Discover Card","Type":"EMV"},{"AID":"A0000001524010","Vendor":"Diners Club International Ltd.","Country":"United States","Name":"Discover","Description":"Discover Debit Common Card","Type":"EMV"},{"AID":"A0000001544442","Vendor":"Banrisul Banco do Estado do Rio Grande do SUL S.A.","Country":"Brazil","Name":"Banricompras Debito","Description":"Banrisul (Brazil)","Type":"EMV"},{"AID":"A0000001570010","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"AMEX","Description":"","Type":""},{"AID":"A0000001570020","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"MasterCard","Description":"","Type":""},{"AID":"A0000001570021","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"Maestro","Description":"","Type":""},{"AID":"A0000001570022","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"Maestro","Description":"","Type":""},{"AID":"A0000001570023","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"CASH","Description":"","Type":""},{"AID":"A0000001570030","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"VISA","Description":"","Type":""},{"AID":"A0000001570031","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"VISA","Description":"","Type":""},{"AID":"A0000001570040","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"JCB","Description":"","Type":""},{"AID":"A0000001570050","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"Postcard","Description":"","Type":""},{"AID":"A0000001570051","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"Postcard","Description":"","Type":""},{"AID":"A0000001570100","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"MCard","Description":"","Type":""},{"AID":"A0000001570104","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"MyOne","Description":"","Type":""},{"AID":"A0000001570109","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"Mediamarkt Card","Description":"","Type":""},{"AID":"A000000157010A","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"Gift Card","Description":"","Type":""},{"AID":"A000000157010B","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"Bonuscard","Description":"","Type":""},{"AID":"A000000157010C","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"WIRCard","Description":"","Type":""},{"AID":"A000000157010D","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"Power Card","Description":"","Type":""},{"AID":"A0000001574443","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"DINERS CLUB","Description":"","Type":""},{"AID":"A0000001574444","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"Supercard Plus","Description":"","Type":""},{"AID":"A000000167413000FF","Vendor":"IBM","Country":"Germany","Name":"JCOP Identify Applet","Description":"identify in JCOP-tools returns eg 27 34 01 2E 00 00 00 00 4E 58 37 35 31 41 00 03 28 62 B3 6A 82","Type":"JCOP"},{"AID":"A000000167413001","Vendor":"IBM","Country":"Germany","Name":"FIPS 140-2","Description":"?","Type":""},{"AID":"A000000172950001","Vendor":"Financial Information Service Co. Ltd.","Country":"Taiwan","Name":"BAROC Financial Application Taiwan","Description":"The Bankers Association of the Republic of China","Type":"EMV"},{"AID":"A000000177504B43532D3135","Vendor":"Minist?re de LInt?rieur","Country":"Belgium","Name":"BelPIC (Belgian Personal Identity Card)","Description":"","Type":""},{"AID":"A0000001850002","Vendor":"Post Office Limited","Country":"United Kingdom","Name":"UK Post Office Account card","Description":"","Type":"EMV"},{"AID":"A0000001884443","Vendor":"Diners Club Switzerland Ltd","Country":"Switzerland","Name":"DINERS CLUB","Description":"","Type":""},{"AID":"A0000002040000","Vendor":"Association for Payment Clearing Services","Country":"United Kingdom","Name":"?","Description":"","Type":""},{"AID":"A0000002281010","Vendor":"Saudi Arabian Monetary Agency (SAMA)","Country":"Kingdom of Saudi Arabia","Name":"SPAN (M/Chip)","Description":"SPAN2 (Saudi Payments Network) Saudi Arabia domestic credit/debit card (Saudi Arabia Monetary Agency)","Type":"EMV"},{"AID":"A0000002282010","Vendor":"Saudi Arabian Monetary Agency (SAMA)","Country":"Kingdom of Saudi Arabia","Name":"SPAN (VIS)","Description":"SPAN2 (Saudi Payments Network) Saudi Arabia domestic credit/debit card (Saudi Arabia Monetary Agency)","Type":"EMV"},{"AID":"A00000022820101010","Vendor":"Saudi Arabian Monetary Agency (SAMA)","Country":"Kingdom of Saudi Arabia","Name":"SPAN","Description":"SPAN2 (Saudi Payments Network) Saudi Arabia domestic credit/debit card (Saudi Arabia Monetary Agency)","Type":""},{"AID":"A0000002471001","Vendor":"ISO JTC1/SC17/WG3","Country":"United Kingdom","Name":"Machine Readable Travel Documents (MRTD)","Description":"Electronic (Biometric) Passport. Issuer stored data application (The last three digits of the PIX shall be used to denote future version levels.)","Type":"MRTD"},{"AID":"A0000002472001","Vendor":"ISO JTC1/SC17/WG3","Country":"United Kingdom","Name":"Machine Readable Travel Documents (MRTD)","Description":"Electronic (Biometric) Passport. Application for hashes, digital signature, and certificate (The last three digits of the PIX shall be used to denote future version levels.)","Type":"MRTD"},{"AID":"A0000002771010","Vendor":"Interac Association","Country":"Canada","Name":"INTERAC","Description":"Canadian domestic credit/debit card","Type":"EMV"},{"AID":"A00000030600000000000000","Vendor":"PS/SC Workgroup","Country":"United States","Name":"PC/SC Initial access data AID","Description":"Possibly not an application","Type":""},{"AID":"A000000308000010000100","Vendor":"National Institute of Standards and Technology","Country":"United States","Name":"Personal Identity Verification (PIV) / ID-ONE PIV BIO","Description":"PIV End Point Applet. Last 2 bytes designate version?","Type":""},{"AID":"A00000031510100528","Vendor":"Currence Holding/PIN BV","Country":"The Netherlands","Name":"Currence PuC","Description":"","Type":"EMV"},{"AID":"A0000003156020","Vendor":"Currence Holding/PIN BV","Country":"The Netherlands","Name":"Chipknip","Description":"","Type":"EMV"},{"AID":"A00000032301","Vendor":"Identity Alliance","Country":"United States","Name":"MUSCLE Applet Package","Description":"http://osdir.com/ml/lib.muscle/2005-12/msg00066.html","Type":""},{"AID":"A0000003230101","Vendor":"Identity Alliance","Country":"United States","Name":"MUSCLE Applet Instance","Description":"http://osdir.com/ml/lib.muscle/2005-12/msg00066.html","Type":""},{"AID":"A0000003241010","Vendor":"Discover Financial Services LLC","Country":"United States","Name":"Discover Expresspay (ZIP)","Description":"","Type":""},{"AID":"A000000333010101","Vendor":"China Unionpay Co. Ltd","Country":"China","Name":"UnionPay Debit","Description":"","Type":""},{"AID":"A000000333010102","Vendor":"China Unionpay Co. Ltd","Country":"China","Name":"UnionPay Credit","Description":"","Type":""},{"AID":"A000000333010103","Vendor":"China Unionpay Co. Ltd","Country":"China","Name":"UnionPay Quasi Credit","Description":"","Type":""},{"AID":"A000000333010106","Vendor":"China Unionpay Co. Ltd","Country":"China","Name":"UnionPay Electronic Cash","Description":"","Type":""},{"AID":"A000000333010108","Vendor":"China Unionpay Co. Ltd","Country":"China","Name":"U.S. UnionPay Common Debit AID","Description":"","Type":""},{"AID":"A000000337301000","Vendor":"Groupment Interbancaire Mon?tique de l UEMOA","Country":"Senegal","Name":"Retrait","Description":"","Type":""},{"AID":"A000000337101000","Vendor":"Groupment Interbancaire Mon?tique de l UEMOA","Country":"Senegal","Name":"Standard","Description":"","Type":""},{"AID":"A000000337102000","Vendor":"Groupment Interbancaire Mon?tique de l UEMOA","Country":"Senegal","Name":"Classic","Description":"","Type":""},{"AID":"A000000337101001","Vendor":"Groupment Interbancaire Mon?tique de l UEMOA","Country":"Senegal","Name":"Prepaye Online","Description":"","Type":""},{"AID":"A000000337102001","Vendor":"Groupment Interbancaire Mon?tique de l UEMOA","Country":"Senegal","Name":"Prepaye Possibile Offiline","Description":"","Type":""},{"AID":"A000000337601001","Vendor":"Groupment Interbancaire Mon?tique de l UEMOA","Country":"Senegal","Name":"Porte Monnaie Electronique","Description":"","Type":""},{"AID":"A0000003591010","Vendor":"Euro Alliance of Payment Schemes s.c.r.l. EAPS","Country":"Belgium","Name":"","Description":"Unknown","Type":""},{"AID":"A0000003591010028001","Vendor":"Euro Alliance of Payment Schemes s.c.r.l. EAPS","Country":"Belgium","Name":"Girocard EAPS","Description":"ZKA (Germany)","Type":"EMV"},{"AID":"A00000035910100380","Vendor":"Euro Alliance of Payment Schemes s.c.r.l. EAPS","Country":"Belgium","Name":"","Description":"PagoBANCOMAT","Type":""},{"AID":"A0000003660001","Vendor":"Poste Italiane S.P.A","Country":"Italy","Name":"Postamat","Description":"","Type":""},{"AID":"A0000003660002","Vendor":"Poste Italiane S.P.A","Country":"Italy","Name":"Postamat VISA","Description":"","Type":""},{"AID":"A0000003710001","Vendor":"Verve","Country":"Nigeria","Name":"InterSwitch Verve Card","Description":"Nigerian local switch company","Type":"EMV"},{"AID":"A00000038410","Vendor":"eftpos, Australian Payments Clearing Association Ltd","Country":"Australia","Name":"Savings (debit card)","Description":"","Type":""},{"AID":"A00000038420","Vendor":"eftpos, Australian Payments Clearing Association Ltd","Country":"Australia","Name":"Cheque (debit card)","Description":"","Type":""},{"AID":"A0000003964D66344D0002","Vendor":"NXP Semiconductors Germany GmbH","Country":"Germany","Name":"MIFARE4MOBILE","Description":"NXP Mf4M","Type":""},{"AID":"A00000039742544659","Vendor":"Microsoft Corporation","Country":"United States","Name":"Microsoft IDMP AID","Description":"Identity Device With Microsoft Generic Profile application. 2 bytes can be added at the end. This byte must be set to the IDMP specification revision number which is currently 0x01. The second byte (yy) is reserved for use by the card application.","Type":""},{"AID":"A0000003974349445F0100","Vendor":"Microsoft Corporation","Country":"United States","Name":"Microsoft PNP AID","Description":"MS Plug and Play","Type":""},{"AID":"A0000004271010","Vendor":"Unibanco (Hipercard)","Country":"Brazil","Name":"Hiperchip","Description":"","Type":""},{"AID":"A0000004320001","Vendor":"100","Country":"Russia","Name":"Universal Electronic Card","Description":"","Type":""},{"AID":"A0000004360100","Vendor":"Edenred","Country":"Belgium","Name":"Ticket Restaurant","Description":"","Type":""},{"AID":"A0000004391010","Vendor":"ACCEL/Exchange","Country":"United States","Name":"Exchange ATM card","Description":"The Exchange Network ATM Network","Type":""},{"AID":"A0000004540010","Vendor":"eTranzact","Country":"Nigeria","Name":"Etranzact Genesis Card","Description":"Nigerian local switch company","Type":"EMV"},{"AID":"A0000004540011","Vendor":"eTranzact","Country":"Nigeria","Name":"Etranzact Genesis Card 2","Description":"Nigerian local switch company","Type":"EMV"},{"AID":"A0000004762010","Vendor":"Google","Country":"United States","Name":"GOOGLE_CONTROLLER_AID","Description":"GOOGLE_LOCKET_AID","Type":""},{"AID":"A0000004763030","Vendor":"Google","Country":"United States","Name":"GOOGLE_MIFARE_MANAGER_AID","Description":"","Type":""},{"AID":"A0000004766C","Vendor":"Google","Country":"United States","Name":"GOOGLE_PAYMENT_AID","Description":"","Type":"EMV"},{"AID":"A000000476A010","Vendor":"Google","Country":"United States","Name":"GSD_MANAGER_AID","Description":"","Type":"GP"},{"AID":"A000000476A110","Vendor":"Google","Country":"United States","Name":"GSD_MANAGER_AID","Description":"","Type":"GP"},{"AID":"A000000485","Vendor":"JVL Ventures, LLC (Softcard)","Country":"United States","Name":"Softcard SmartTap","Description":"","Type":""},{"AID":"A0000005241010","Vendor":"RuPay","Country":"India","Name":"RuPay","Description":"RuPay (India)","Type":"EMV"},{"AID":"A0000005271002","Vendor":"Yubico","Country":"Sweden","Name":"Yubikey NEO U2F Demo applet","Description":"Universal 2-Factor Proof-of-concept/Demo","Type":"YKNEO"},{"AID":"A000000527200101","Vendor":"Yubico","Country":"Sweden","Name":"Yubikey NEO Yubikey2 applet interface","Description":"Javacard Applet AID","Type":"YKNEO"},{"AID":"A000000527210101","Vendor":"Yubico","Country":"Sweden","Name":"Yubikey NEO OATH Applet","Description":"Javacard Applet AID","Type":"YKNEO"},{"AID":"A0000005591010FFFFFFFF8900000100","Vendor":"GSMA (GSM Association)","Country":"United Kingdom","Name":"ISD-R Application. Used as TAR.","Description":"","Type":""},{"AID":"A0000005591010FFFFFFFF8900000200","Vendor":"GSMA (GSM Association)","Country":"United Kingdom","Name":"ECASD Application. Used as TAR.","Description":"","Type":""},{"AID":"A0000005591010FFFFFFFF8900000D00","Vendor":"GSMA (GSM Association)","Country":"United Kingdom","Name":"ISD-P Executable Load File.","Description":"","Type":""},{"AID":"A0000005591010FFFFFFFF8900000E00","Vendor":"GSMA (GSM Association)","Country":"United Kingdom","Name":"ISD-P Executable Module.","Description":"","Type":""},{"AID":"A0000005591010FFFFFFFF8900000F00","Vendor":"GSMA (GSM Association)","Country":"United Kingdom","Name":"Reserved value for the Profiles ISD-P","Description":"","Type":""},{"AID":"A0000005591010FFFFFFFF8900001000","Vendor":"GSMA (GSM Association)","Country":"United Kingdom","Name":"ISD-P Application (1010FFFFFFFF89000010 to 1010FFFFFFFF8900FFFF. Used as TAR. The value is allocated during the Profile Download and Installation procedure","Description":"","Type":""},{"AID":"A00000061700","Vendor":"Fidesmo","Country":"Sweden","Name":"Fidesmo javacard","Description":"","Type":""},{"AID":"A0000006200620","Vendor":"Debit Network Alliance (DNA)","Country":"United States","Name":"Debit Network Alliance (DNA)","Description":"Common U.S. Debit","Type":""},{"AID":"A0000006581010","Vendor":"MIR","Country":"Russia","Name":"MIR Credit","Description":"","Type":""},{"AID":"A0000006581011","Vendor":"MIR","Country":"Russia","Name":"MIR Credit","Description":"","Type":""},{"AID":"A0000006582010","Vendor":"MIR","Country":"Russia","Name":"MIR Debit","Description":"","Type":""},{"AID":"A0000006723010","Vendor":"TROY","Country":"Turkey","Name":"TROY chip credit card","Description":"Turkeys Payment Method","Type":"EMV"},{"AID":"A0000006723020","Vendor":"TROY","Country":"Turkey","Name":"TROY chip debit card","Description":"Turkeys Payment Method","Type":"EMV"},{"AID":"A0000007705850","Vendor":"Indian Oil Corporation Limited","Country":"India","Name":"XTRAPOWER Fleet Card Program","Description":"Indian Oils Pre Paid Program","Type":"EMV"},{"AID":"A0000007790000","Vendor":"Zimswitch","Country":"Zimbabwe","Name":"","Description":"","Type":""},{"AID":"B012345678","Vendor":"MasterCard International","Country":"United States","Name":"Maestro TEST","Description":"Used for development","Type":"EMV"},{"AID":"D040000001000002","Vendor":"Paylife","Country":"Austria","Name":"Paylife Quick (IEP). Preloaded Electronic Purse","Description":"Domestic Payment System (Version 2.1)","Type":""},{"AID":"D040000002000002","Vendor":"Austria Card","Country":"Austria","Name":"RFU","Description":"Domestic Payment System (Version 2.1)","Type":""},{"AID":"D040000003000002","Vendor":"Austria Card","Country":"Austria","Name":"POS","Description":"Domestic Payment System (Version 2.1)","Type":""},{"AID":"D040000004000002","Vendor":"Austria Card","Country":"Austria","Name":"ATM","Description":"Domestic Payment System (Version 2.1)","Type":""},{"AID":"D04000000B000002","Vendor":"Austria Card","Country":"Austria","Name":"Retail","Description":"Domestic Loyalty Program (Version 2.1)","Type":""},{"AID":"D04000000C000002","Vendor":"Austria Card","Country":"Austria","Name":"Bank_Data","Description":"Domestic Loyalty Program (Version 2.1)","Type":""},{"AID":"D04000000D000002","Vendor":"Austria Card","Country":"Austria","Name":"Shopping","Description":"Domestic Loyalty Program (Version 2.1)","Type":""},{"AID":"D040000013000001","Vendor":"Austria Card","Country":"Austria","Name":"DF_UNI_Kepler1","Description":"Domestic Loyalty Program (Version 2.0)","Type":""},{"AID":"D040000013000001","Vendor":"Austria Card","Country":"Austria","Name":"DF_Sch?ler1","Description":"Domestic Loyalty Program (Version 1.3)","Type":""},{"AID":"D040000013000002","Vendor":"Austria Card","Country":"Austria","Name":"DF_UNI_Kepler2","Description":"Domestic Loyalty Program (Version 2.0)","Type":""},{"AID":"D040000013000002","Vendor":"Austria Card","Country":"Austria","Name":"DF_Sch?ler2","Description":"Domestic Loyalty Program (Version 1.3)","Type":""},{"AID":"D040000014000001","Vendor":"Austria Card","Country":"Austria","Name":"DF_Mensa","Description":"Domestic Loyalty Program (Version 2.0)","Type":""},{"AID":"D040000015000001","Vendor":"Austria Card","Country":"Austria","Name":"DF_UNI_Ausweis","Description":"Domestic Loyalty Program (Version 2.0)","Type":""},{"AID":"D040000015000001","Vendor":"Austria Card","Country":"Austria","Name":"DF_Ausweis","Description":"Domestic Loyalty Program (Version 1.3)","Type":""},{"AID":"D0400000190001","Vendor":"Austria Card","Country":"Austria","Name":"EMV ATM Maestro","Description":"Domestic EMV Application (Version 2.1)","Type":""},{"AID":"D0400000190002","Vendor":"Austria Card","Country":"Austria","Name":"EMV POS Maestro","Description":"Domestic EMV Application (Version 2.1)","Type":""},{"AID":"D0400000190003","Vendor":"Austria Card","Country":"Austria","Name":"EMV ATM MasterCard","Description":"Domestic EMV Application (Version 2.1)","Type":""},{"AID":"D0400000190004","Vendor":"Austria Card","Country":"Austria","Name":"EMV POS MasterCard","Description":"Domestic EMV Application (Version 2.1)","Type":""},{"AID":"D0400000190010","Vendor":"Austria Card","Country":"Austria","Name":"Digital ID","Description":"Domestic Payment System (Version 2.1)","Type":""},{"AID":"D268000001","Vendor":"Ministry of Finance of Georgia","Country":"Georgia","Name":"Fiscal module application","Description":"Georgia Revenue Service application for fiscal cash registers","Type":""},{"AID":"D276000005","Vendor":"Giesecke&Devrient","Country":"Germany","Name":"","Description":"Giesecke & Devrient","Type":""},{"AID":"D276000005AA040360010410","Vendor":"Giesecke&Devrient","Country":"Germany","Name":"G D App Nokia 6212","Description":"","Type":""},{"AID":"D276000005AA0503E00401","Vendor":"Giesecke&Devrient","Country":"Germany","Name":"G D App Nokia 6212","Description":"","Type":""},{"AID":"D276000005AA0503E00501","Vendor":"Giesecke&Devrient","Country":"Germany","Name":"G D App Nokia 6212","Description":"","Type":""},{"AID":"D276000005AA0503E0050101","Vendor":"Giesecke&Devrient","Country":"Germany","Name":"G D App Nokia 6212","Description":"","Type":""},{"AID":"D276000005AB0503E0040101","Vendor":"Giesecke&Devrient","Country":"Germany","Name":"G D App Nokia 6212","Description":"","Type":""},{"AID":"D27600002200000001","Vendor":"IBM Laboratories","Country":"Germany","Name":"SCT LOYALTY","Description":"IBM Test card from the book Smart Card Application Development Using Java","Type":""},{"AID":"D27600002200000002","Vendor":"IBM Laboratories","Country":"Germany","Name":"BUSINESS CARD","Description":"IBM Test card from the book Smart Card Application Development Using Java","Type":""},{"AID":"D27600002200000060","Vendor":"IBM Laboratories","Country":"Germany","Name":"PKCS#11 Token","Description":"IBM Test card from the book Smart Card Application Development Using Java","Type":""},{"AID":"D276000025","Vendor":"ZKA","Country":"Germany","Name":"Girocard","Description":"Girocard (Geldkarte) in Germany","Type":""},{"AID":"D27600002545410100","Vendor":"ZKA","Country":"Germany","Name":"","Description":"Unknown","Type":""},{"AID":"D27600002545500100","Vendor":"ZKA","Country":"Germany","Name":"Girocard","Description":"ZKA Girocard (Geldkarte) (Germany)","Type":"EMV"},{"AID":"D27600002547410100","Vendor":"ZKA","Country":"Germany","Name":"Girocard ATM","Description":"","Type":""},{"AID":"D276000060","Vendor":"Wolfgang Rankl","Country":"Germany","Name":"","Description":"","Type":""},{"AID":"D2760000850100","Vendor":"NXP Semiconductors / NFC Forum","Country":"Germany","Name":"NDEF Tag Application / Mifare DESFire Tag Application","Description":"NFC Forum Type 4 Tag","Type":""},{"AID":"D2760000850101","Vendor":"NXP Semiconductors / NFC Forum","Country":"Germany","Name":"NDEF Tag Application","Description":"NFC Tag type 4 tag","Type":""},{"AID":"D276000118","Vendor":"Giesecke&Devrient Java Card Telecommunikation","Country":"Germany","Name":"","Description":"","Type":""},{"AID":"D2760001180101","Vendor":"Giesecke&Devrient Java Card Telecommunikation","Country":"Germany","Name":"Giesecke &","Description":"Devrient Test Applet?","Type":""},{"AID":"D27600012401","Vendor":"fsfEurope","Country":"Germany","Name":"OpenPGP Card","Description":"For selection when not knowing the exact full AID","Type":"OpenPGP"},{"AID":"D276000124010101FFFF000000010000","Vendor":"fsfEurope","Country":"Germany","Name":"OpenPGP Card","Description":"Version 1","Type":"OpenPGP"},{"AID":"D2760001240102000000000000010000","Vendor":"fsfEurope","Country":"Germany","Name":"OpenPGP Card","Description":"Version 2","Type":"OpenPGP"},{"AID":"D27600012402","Vendor":"fsfEurope","Country":"Germany","Name":"SmartChess","Description":"http://smartchess.de/englisch/SmartChess_1.0.pdf","Type":"SmartChess"},{"AID":"D2760001240200010000000000000000","Vendor":"fsfEurope","Country":"Germany","Name":"SmartChess","Description":"http://smartchess.de/englisch/SmartChess_1.0.pdf","Type":"SmartChess"},{"AID":"D4100000011010","Vendor":"","Country":"Republic of Korea","Name":"","Description":"","Type":""},{"AID":"D5280050218002","Vendor":"","Country":"The Netherlands","Name":"?","Description":"(Netherlands)","Type":"EMV"},{"AID":"D5780000021010","Vendor":"Bankaxept","Country":"Norway","Name":"Bankaxept","Description":"Norwegian domestic debit card","Type":"EMV"},{"AID":"D7560000010101","Vendor":"Swiss Travel Fund (Reka)","Country":"Switzerland","Name":"Reka Card","Description":"prepaid functional debit card","Type":""},{"AID":"D7560000300101","Vendor":"Migros (FCM, GE Money Bank and MasterCard)","Country":"Switzerland","Name":"M Budget","Description":"","Type":""},{"AID":"E80704007F00070302","Vendor":"","Country":"","Name":"nPA","Description":"German eID","Type":""},{"AID":"E82881C11702","Vendor":"","Country":"","Name":"AlphaCard application","Description":"","Type":""},{"AID":"E828BD080F","Vendor":"","Country":"","Name":"ISO-7816-15 EF.DIR","Description":"Iso adoption of PKCS-15","Type":""},{"AID":"F0000000030001","Vendor":"","Country":"","Name":"BRADESCO","Description":"Brazilian Bank Banco Bradesco","Type":"EMV"}] \ No newline at end of file +[{"AID":"315041592E5359532E4444463031","Vendor":"Visa International","Country":"United States","Name":"Visa Payment System Environment PSE (1PAY.SYS.DDF01)","Description":"","Type":""},{"AID":"325041592E5359532E4444463031","Vendor":"Visa International","Country":"United States","Name":"Visa Proximity Payment System Environment PPSE (2PAY.SYS.DDF01)","Description":"Visa payWave for Mobile","Type":""},{"AID":"44464D46412E44466172653234313031","Vendor":"DeviceFidelity","Country":"United States","Name":"DeviceFidelity In2Pay DFare applet","Description":"http://www.nfcworld.com/2010/11/24/35207/devicefidelity-adds-nfc-support-for-android-and-mifare/","Type":""},{"AID":"A00000000101","Vendor":"PBS Danm?nt A/S","Country":"Denmark","Name":"MUSCLE Card Applet","Description":"(Unlicensed use of this RID. Proposal to use A000000323 instead)","Type":""},{"AID":"A000000003000000","Vendor":"Visa International","Country":"United States","Name":"(VISA) Card Manager","Description":"Used by most GP2.1.1 cards / Oberthur OP201 cards. Visa Proprietary Card Manager AID for OpenPlatform cards (visa.openplatform).","Type":"GP"},{"AID":"A00000000300037561","Vendor":"Visa International","Country":"United States","Name":"Bonuscard","Description":"","Type":""},{"AID":"A00000000305076010","Vendor":"Visa International","Country":"United States","Name":"VISA ELO Credit","Description":"","Type":"EMV"},{"AID":"A0000000031010","Vendor":"Visa International","Country":"United States","Name":"VISA Debit/Credit (Classic)","Description":"Standard/Gold VISA credit card","Type":"EMV"},{"AID":"A000000003101001","Vendor":"Visa International","Country":"United States","Name":"VISA Credit","Description":"","Type":"EMV"},{"AID":"A000000003101002","Vendor":"Visa International","Country":"United States","Name":"VISA Debit","Description":"","Type":"EMV"},{"AID":"A0000000032010","Vendor":"Visa International","Country":"United States","Name":"VISA Electron","Description":"VISA Electron (Debit)","Type":"EMV"},{"AID":"A0000000032020","Vendor":"Visa International","Country":"United States","Name":"VISA","Description":"V PAY","Type":"EMV"},{"AID":"A0000000033010","Vendor":"Visa International","Country":"United States","Name":"VISA Interlink","Description":"VISA Interlink","Type":"EMV"},{"AID":"A0000000034010","Vendor":"Visa International","Country":"United States","Name":"VISA Specific","Description":"Visa Specific","Type":"EMV"},{"AID":"A0000000035010","Vendor":"Visa International","Country":"United States","Name":"VISA Specific","Description":"Visa Specific","Type":"EMV"},{"AID":"A000000003534441","Vendor":"Visa International","Country":"United States","Name":"Schlumberger Security Domain","Description":"","Type":"GP"},{"AID":"A0000000035350","Vendor":"Visa International","Country":"United States","Name":"Security Domain","Description":"OCS Oberthur Card System Security Domain Package AID / VGP Card Manager (for ISD and ASD)","Type":"GP"},{"AID":"A000000003535041","Vendor":"Visa International","Country":"United States","Name":"Security Domain","Description":"OCS Oberthur Card System Security Domain Applet AID / VGP Card Manager (for ISD and ASD)","Type":"GP"},{"AID":"A0000000036010","Vendor":"Visa International","Country":"United States","Name":"Domestic Visa Cash Stored Value","Description":"","Type":"EMV"},{"AID":"A0000000036020","Vendor":"Visa International","Country":"United States","Name":"International Visa Cash Stored Value","Description":"","Type":"EMV"},{"AID":"A0000000038002","Vendor":"Visa International","Country":"United States","Name":"VISA Auth, VisaRemAuthen EMV-CAP (DPA)","Description":"VISA Auth dynamic passcode authentication (DPA). Used by Barclays/HBOS","Type":"EMV"},{"AID":"A0000000038010","Vendor":"Visa International","Country":"United States","Name":"VISA Plus","Description":"VISA plus","Type":"EMV"},{"AID":"A0000000039010","Vendor":"Visa International","Country":"United States","Name":"VISA Loyalty","Description":"","Type":"EMV"},{"AID":"A000000003999910","Vendor":"Visa International","Country":"United States","Name":"VISA Proprietary ATM","Description":"","Type":"EMV"},{"AID":"A0000000040000","Vendor":"Mastercard International","Country":"United States","Name":"MasterCard Card Manager","Description":"Security Domain","Type":"GP"},{"AID":"A00000000401","Vendor":"Mastercard International","Country":"United States","Name":"MasterCard PayPass","Description":"AEPM (Association Europ?enne Payez Mobile)","Type":"EMV"},{"AID":"A0000000041010","Vendor":"Mastercard International","Country":"United States","Name":"MasterCard Credit/Debit (Global)","Description":"Standard MasterCard","Type":"EMV"},{"AID":"A00000000410101213","Vendor":"Mastercard International","Country":"United States","Name":"MasterCard Credit","Description":"Standard MasterCard","Type":"EMV"},{"AID":"A00000000410101215","Vendor":"Mastercard International","Country":"United States","Name":"MasterCard Credit","Description":"Standard MasterCard","Type":"EMV"},{"AID":"A0000000041010BB5449435301","Vendor":"Mastercard International","Country":"United States","Name":"[UNKNOWN]","Description":"Some co-branded card?","Type":""},{"AID":"A0000000042010","Vendor":"Mastercard International","Country":"United States","Name":"MasterCard Specific","Description":"MasterCard Specific","Type":"EMV"},{"AID":"A0000000042203","Vendor":"Mastercard International","Country":"United States","Name":"MasterCard Specific","Description":"MasterCard U.S. Maestro","Type":""},{"AID":"A0000000043010","Vendor":"Mastercard International","Country":"United States","Name":"MasterCard Specific","Description":"MasterCard Specific","Type":"EMV"},{"AID":"A0000000043060","Vendor":"Mastercard International","Country":"United States","Name":"Maestro (Debit)","Description":"Maestro (Debit) Card","Type":"EMV"},{"AID":"A000000004306001","Vendor":"Mastercard International","Country":"United States","Name":"Maestro (Debit)","Description":"Maestro (Debit) Card","Type":"EMV"},{"AID":"A0000000044010","Vendor":"Mastercard International","Country":"United States","Name":"MasterCard Specific","Description":"MasterCard Specific","Type":"EMV"},{"AID":"A0000000045010","Vendor":"Mastercard International","Country":"United States","Name":"MasterCard Specific","Description":"MasterCard Specific","Type":"EMV"},{"AID":"A0000000045555","Vendor":"Mastercard International","Country":"United States","Name":"APDULogger","Description":"AID on Cirrus Test Card","Type":""},{"AID":"A0000000046000","Vendor":"Mastercard International","Country":"United States","Name":"Cirrus","Description":"Mastercard Cirrus (Interbank Network) ATM card only","Type":"EMV"},{"AID":"A0000000048002","Vendor":"Mastercard International","Country":"United States","Name":"SecureCode Auth EMV-CAP","Description":"Chip Authentication Protocol (CAP). Works with NatWest or SecureCode Aut","Type":"EMV"},{"AID":"A0000000049999","Vendor":"Mastercard International","Country":"United States","Name":"MasterCard PayPass??","Description":"","Type":"EMV"},{"AID":"A0000000050001","Vendor":"Switch Card Services Ltd.","Country":"United Kingdom","Name":"Maestro UK","Description":"UK Domestic Maestro Switch (debit card)","Type":"EMV"},{"AID":"A0000000050002","Vendor":"Switch Card Services Ltd.","Country":"United Kingdom","Name":"Solo","Description":"UK Domestic Maestro Switch (debit card)","Type":"EMV"},{"AID":"A0000000090001FF44FF1289","Vendor":"ETSI","Country":"France","Name":"Orange","Description":"Orange UK","Type":""},{"AID":"A0000000101030","Vendor":"Europay International","Country":"Belgium","Name":"Maestro-CH","Description":"","Type":""},{"AID":"A00000001800","Vendor":"GEMPLUS","Country":"France","Name":"Gemplus ?","Description":"","Type":""},{"AID":"A0000000181001","Vendor":"GEMPLUS","Country":"France","Name":"com.gemplus.javacard.util packages","Description":"","Type":""},{"AID":"A000000018434D","Vendor":"GEMPLUS","Country":"France","Name":"Gemplus card manager","Description":"434D = CM (ascii). Security domain for some GCX/GXP cards (GemXpresso Pro) (Gemalto)","Type":"GP"},{"AID":"A000000018434D00","Vendor":"GEMPLUS","Country":"France","Name":"Gemplus Security Domain","Description":"(Gemalto)","Type":"GP"},{"AID":"A00000002401","Vendor":"Midland Bank Plc","Country":"United Kingdom","Name":"Self Service","Description":"","Type":"EMV"},{"AID":"A000000025","Vendor":"American Express","Country":"United Kingdom","Name":"American Express","Description":"","Type":"EMV"},{"AID":"A0000000250000","Vendor":"American Express","Country":"United Kingdom","Name":"American Express","Description":"American Express (Credit/Debit)","Type":"EMV"},{"AID":"A00000002501","Vendor":"American Express","Country":"United Kingdom","Name":"American Express","Description":"AEIPS-compliant (A-E contact EMV) payment application","Type":"EMV"},{"AID":"A000000025010104","Vendor":"American Express","Country":"United Kingdom","Name":"American Express","Description":"","Type":""},{"AID":"A000000025010402","Vendor":"American Express","Country":"United Kingdom","Name":"American Express","Description":"","Type":"EMV"},{"AID":"A000000025010701","Vendor":"American Express","Country":"United Kingdom","Name":"ExpressPay","Description":"","Type":"EMV"},{"AID":"A000000025010801","Vendor":"American Express","Country":"United Kingdom","Name":"American Express","Description":"","Type":"EMV"},{"AID":"A0000000291010","Vendor":"LINK Interchange Network Ltd","Country":"United Kingdom","Name":"Link / American Express","Description":"Link (UK) ATM Network, or AMEX (Portugal?)","Type":"EMV"},{"AID":"A00000002945087510100000","Vendor":"LINK Interchange Network Ltd","Country":"United Kingdom","Name":"CO-OP","Description":"","Type":""},{"AID":"A00000002949034010100001","Vendor":"LINK Interchange Network Ltd","Country":"United Kingdom","Name":"HSBC","Description":"","Type":""},{"AID":"A00000002949282010100000","Vendor":"LINK Interchange Network Ltd","Country":"United Kingdom","Name":"Barclay","Description":"","Type":""},{"AID":"A000000029564182","Vendor":"LINK Interchange Network Ltd","Country":"United Kingdom","Name":"HAFX","Description":"","Type":""},{"AID":"A00000003029057000AD13100101FF","Vendor":"Schlumberger Industries Identif dEncarteur PR050","Country":"France","Name":"BelPIC (Belgian Personal Identity Card) JavaCard Applet","Description":"Schlumberger (Gemalto) RID","Type":""},{"AID":"A0000000308000000000280101","Vendor":"Schlumberger Industries Identif dEncarteur PR050","Country":"France","Name":"Gemalto .NET Card AID","Description":"","Type":""},{"AID":"A0000000421010","Vendor":"Groupement des Cartes Bancaires CB","Country":"France","Name":"Cartes Bancaire EMV Card","Description":"Groupement des Cartes Bancaires (France)","Type":"EMV"},{"AID":"A0000000422010","Vendor":"Groupement des Cartes Bancaires CB","Country":"France","Name":"","Description":"","Type":"EMV"},{"AID":"A0000000423010","Vendor":"Groupement des Cartes Bancaires CB","Country":"France","Name":"","Description":"","Type":"EMV"},{"AID":"A0000000424010","Vendor":"Groupement des Cartes Bancaires CB","Country":"France","Name":"","Description":"","Type":"EMV"},{"AID":"A0000000425010","Vendor":"Groupement des Cartes Bancaires CB","Country":"France","Name":"","Description":"","Type":"EMV"},{"AID":"A0000000426010","Vendor":"Groupement des Cartes Bancaires CB","Country":"France","Name":"Contactless payment using Apple Pay","Description":"","Type":"EMV"},{"AID":"A00000005945430100","Vendor":"Zentraler Kreditausschuss (ZKA)","Country":"Germany","Name":"Girocard Electronic Cash","Description":"","Type":""},{"AID":"A000000063504B43532D3135","Vendor":"RSA Laboratories","Country":"United States","Name":"PKCS-15","Description":"RSA PKCS-15 PKI application (Predecessor to ISO7816-15) / ID-card in Finland","Type":""},{"AID":"A0000000635741502D57494D","Vendor":"RSA Laboratories","Country":"United States","Name":"WAP-WIM","Description":"WAP (Wireless Application Protocol) Identity Module / Wireless Identification Module","Type":""},{"AID":"A00000006510","Vendor":"JCB CO., LTD.","Country":"Japan","Name":"JCB","Description":"Japan Credit Bureau","Type":"EMV"},{"AID":"A0000000651010","Vendor":"JCB CO., LTD.","Country":"Japan","Name":"JCB J Smart Credit","Description":"Japan Credit Bureau","Type":"EMV"},{"AID":"A00000006900","Vendor":"Soci?t? Europ?enne de Monnaie Electronique SEME","Country":"France","Name":"Moneo","Description":"","Type":"EMV"},{"AID":"A000000077010000021000000000003B","Vendor":"Oberthur Technologies","Country":"France","Name":"Visa AEPN","Description":"","Type":"EMV"},{"AID":"A0000000790100","Vendor":"Activcard Europe S.A.","Country":"France","Name":"CACv2 PKI ID","Description":"Identity Key","Type":""},{"AID":"A0000000790101","Vendor":"Activcard Europe S.A.","Country":"France","Name":"CACv2 PKI Sign","Description":"Digital Signature Key","Type":""},{"AID":"A0000000790102","Vendor":"Activcard Europe S.A.","Country":"France","Name":"CACv2 PKI Enc","Description":"Key Management Key","Type":""},{"AID":"A00000007901F0","Vendor":"Activcard Europe S.A.","Country":"France","Name":"CACv1 PKI Identity Key","Description":"Re-directs to CACv2 PKI Identity key","Type":""},{"AID":"A00000007901F1","Vendor":"Activcard Europe S.A.","Country":"France","Name":"CACv1 PKI Digital Signature Key","Description":"Re-directs to CACv2 Digital Signature key","Type":""},{"AID":"A00000007901F2","Vendor":"Activcard Europe S.A.","Country":"France","Name":"CACv1 PKI Key Management Key","Description":"Re-directs to CACv2 Key Management key","Type":""},{"AID":"A0000000790200","Vendor":"Activcard Europe S.A.","Country":"France","Name":"CACv2 DoD Person","Description":"DoD Demographic","Type":""},{"AID":"A0000000790201","Vendor":"Activcard Europe S.A.","Country":"France","Name":"CACv2 DoD Personnel","Description":"DoD Demographic","Type":""},{"AID":"A00000007902FB","Vendor":"Activcard Europe S.A.","Country":"France","Name":"CACv1 BC","Description":"General Configuration","Type":""},{"AID":"A00000007902FD","Vendor":"Activcard Europe S.A.","Country":"France","Name":"CACv1 BC","Description":"PKI Certificate Attributes","Type":""},{"AID":"A00000007902FE","Vendor":"Activcard Europe S.A.","Country":"France","Name":"CACv1 BC","Description":"PKI Cert","Type":""},{"AID":"A0000000790300","Vendor":"Activcard Europe S.A.","Country":"France","Name":"CACv2 Access Control Applet","Description":"CAC PIN / ID PIN Management Applet","Type":""},{"AID":"A0000000791201","Vendor":"Activcard Europe S.A.","Country":"France","Name":"CAC JDM","Description":"Joint Data Model. BCAdmin","Type":""},{"AID":"A0000000791202","Vendor":"Activcard Europe S.A.","Country":"France","Name":"CAC JDM","Description":"Joint Data Model. BCMedical","Type":""},{"AID":"A0000000871002FF49FF0589","Vendor":"Third Generation Partnership Project (3GPP)","Country":"France","Name":"Telenor USIM","Description":"","Type":"USIM"},{"AID":"A00000008810200105C100","Vendor":"Buypass AS","Country":"Norway","Name":"BuyPass BIDA","Description":"Used by norwegian public betting company Norsk-Tipping?","Type":"BuyPass"},{"AID":"A000000088102201034221","Vendor":"Buypass AS","Country":"Norway","Name":"BuyPass BEID (BuyPass Electronic ID?)","Description":"","Type":"BuyPass"},{"AID":"A000000088102201034321","Vendor":"Buypass AS","Country":"Norway","Name":"BuyPass BEID (BuyPass Electronic ID?)","Description":"","Type":"BuyPass"},{"AID":"A0000000960200","Vendor":"Sa Proton World International N.V.","Country":"Belgium","Name":"Proton World International Security Domain","Description":"Proton, which is owned in part by Visa International and American Express Co., is in three other European countries: the original Proton program in Belgium, Chipknip in the Netherlands, and Cash in Switzerland","Type":"GP"},{"AID":"A000000098","Vendor":"Visa USA","Country":"United States","Name":"Debit Card","Description":"Bank of America Debit Card","Type":"EMV"},{"AID":"A0000000980840","Vendor":"Visa USA","Country":"United States","Name":"Visa Common Debit","Description":"","Type":""},{"AID":"A0000000980848","Vendor":"Visa USA","Country":"United States","Name":"Debit Card","Description":"Schwab Bank Debit Card","Type":"EMV"},{"AID":"A0000001110101","Vendor":"Die Post Postfinance","Country":"Switzerland","Name":"Postcard","Description":"","Type":""},{"AID":"A0000001160300","Vendor":"GSA TFCS","Country":"United States","Name":"PIV CHUID","Description":"CHUID","Type":""},{"AID":"A0000001166010","Vendor":"GSA TFCS","Country":"United States","Name":"PIV Fingerprints","Description":"Fingerprints","Type":""},{"AID":"A0000001166030","Vendor":"GSA TFCS","Country":"United States","Name":"PIV Facial Image","Description":"Facial Image","Type":""},{"AID":"A0000001169000","Vendor":"GSA TFCS","Country":"United States","Name":"PIV Security Object","Description":"Security Object","Type":""},{"AID":"A000000116A001","Vendor":"GSA TFCS","Country":"United States","Name":"PIV Authentication Key","Description":"PIV Authentication Key","Type":""},{"AID":"A000000116DB00","Vendor":"GSA TFCS","Country":"United States","Name":"CCC","Description":"Card Capability Container","Type":""},{"AID":"A000000118010000","Vendor":"Austria Card","Country":"Austria","Name":"DF_Verkehr","Description":"Domestic Loyalty Program (Version 1.3)","Type":""},{"AID":"A000000118020000","Vendor":"Austria Card","Country":"Austria","Name":"DF_Partner","Description":"Domestic Loyalty Program (Version 1.3)","Type":""},{"AID":"A000000118030000","Vendor":"Austria Card","Country":"Austria","Name":"DF_Sch?lerdaten","Description":"Domestic Loyalty Program (Version 1.3)","Type":""},{"AID":"A000000118040000","Vendor":"Austria Card","Country":"Austria","Name":"DF_KEP_SIG","Description":"Domestic Loyalty Program (Version 1.32)","Type":""},{"AID":"A0000001184543","Vendor":"Austria Card","Country":"Austria","Name":"Digital Signature (SSCA)","Description":"Digital Signature Application","Type":""},{"AID":"A000000118454E","Vendor":"Austria Card","Country":"Austria","Name":"Encryption Application","Description":"Encryption Application (Version 1.10)","Type":""},{"AID":"A0000001211010","Vendor":"PBS Danmark A/S","Country":"Denmark","Name":"Dankort (VISA GEM Vision)","Description":"Danish domestic debit card","Type":"EMV"},{"AID":"A0000001320001","Vendor":"Java Card Forum","Country":"United States","Name":"org.javacardforum.javacard.biometry","Description":"","Type":""},{"AID":"A0000001408001","Vendor":"TDS TODOS DATA SYSTEM AB","Country":"Sweden","Name":"eCode","Description":"","Type":""},{"AID":"A0000001410001","Vendor":"Associazione Bancaria Italiana","Country":"Italy","Name":"PagoBANCOMAT","Description":"CoGeBan Consorzio BANCOMAT (Italian domestic debit card)","Type":"EMV"},{"AID":"A0000001510000","Vendor":"GlobalPlatform, Inc.","Country":"United States","Name":"Global Platform Security Domain AID","Description":"GP Card Manager","Type":"GP"},{"AID":"A00000015153504341534400","Vendor":"GlobalPlatform, Inc.","Country":"United States","Name":"CASD_AID","Description":"SPCASD","Type":"GP"},{"AID":"A0000001523010","Vendor":"Diners Club International Ltd.","Country":"United States","Name":"Discover, Pulse D Pas","Description":"Discover Card","Type":"EMV"},{"AID":"A0000001524010","Vendor":"Diners Club International Ltd.","Country":"United States","Name":"Discover","Description":"Discover Debit Common Card","Type":"EMV"},{"AID":"A0000001544442","Vendor":"Banrisul Banco do Estado do Rio Grande do SUL S.A.","Country":"Brazil","Name":"Banricompras Debito","Description":"Banrisul (Brazil)","Type":"EMV"},{"AID":"A0000001570010","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"AMEX","Description":"","Type":""},{"AID":"A0000001570020","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"MasterCard","Description":"","Type":""},{"AID":"A0000001570021","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"Maestro","Description":"","Type":""},{"AID":"A0000001570022","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"Maestro","Description":"","Type":""},{"AID":"A0000001570023","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"CASH","Description":"","Type":""},{"AID":"A0000001570030","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"VISA","Description":"","Type":""},{"AID":"A0000001570031","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"VISA","Description":"","Type":""},{"AID":"A0000001570040","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"JCB","Description":"","Type":""},{"AID":"A0000001570050","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"Postcard","Description":"","Type":""},{"AID":"A0000001570051","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"Postcard","Description":"","Type":""},{"AID":"A0000001570100","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"MCard","Description":"","Type":""},{"AID":"A0000001570104","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"MyOne","Description":"","Type":""},{"AID":"A0000001570109","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"Mediamarkt Card","Description":"","Type":""},{"AID":"A000000157010A","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"Gift Card","Description":"","Type":""},{"AID":"A000000157010B","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"Bonuscard","Description":"","Type":""},{"AID":"A000000157010C","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"WIRCard","Description":"","Type":""},{"AID":"A000000157010D","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"Power Card","Description":"","Type":""},{"AID":"A0000001574443","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"DINERS CLUB","Description":"","Type":""},{"AID":"A0000001574444","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"Supercard Plus","Description":"","Type":""},{"AID":"A000000167413000FF","Vendor":"IBM","Country":"Germany","Name":"JCOP Identify Applet","Description":"identify in JCOP-tools returns eg 27 34 01 2E 00 00 00 00 4E 58 37 35 31 41 00 03 28 62 B3 6A 82","Type":"JCOP"},{"AID":"A000000167413001","Vendor":"IBM","Country":"Germany","Name":"FIPS 140-2","Description":"?","Type":""},{"AID":"A000000172950001","Vendor":"Financial Information Service Co. Ltd.","Country":"Taiwan","Name":"BAROC Financial Application Taiwan","Description":"The Bankers Association of the Republic of China","Type":"EMV"},{"AID":"A000000177504B43532D3135","Vendor":"Minist?re de LInt?rieur","Country":"Belgium","Name":"BelPIC (Belgian Personal Identity Card)","Description":"","Type":""},{"AID":"A0000001850002","Vendor":"Post Office Limited","Country":"United Kingdom","Name":"UK Post Office Account card","Description":"","Type":"EMV"},{"AID":"A0000001884443","Vendor":"Diners Club Switzerland Ltd","Country":"Switzerland","Name":"DINERS CLUB","Description":"","Type":""},{"AID":"A0000002040000","Vendor":"Association for Payment Clearing Services","Country":"United Kingdom","Name":"?","Description":"","Type":""},{"AID":"A0000002281010","Vendor":"Saudi Arabian Monetary Agency (SAMA)","Country":"Kingdom of Saudi Arabia","Name":"SPAN (M/Chip)","Description":"SPAN2 (Saudi Payments Network) Saudi Arabia domestic credit/debit card (Saudi Arabia Monetary Agency)","Type":"EMV"},{"AID":"A0000002282010","Vendor":"Saudi Arabian Monetary Agency (SAMA)","Country":"Kingdom of Saudi Arabia","Name":"SPAN (VIS)","Description":"SPAN2 (Saudi Payments Network) Saudi Arabia domestic credit/debit card (Saudi Arabia Monetary Agency)","Type":"EMV"},{"AID":"A00000022820101010","Vendor":"Saudi Arabian Monetary Agency (SAMA)","Country":"Kingdom of Saudi Arabia","Name":"SPAN","Description":"SPAN2 (Saudi Payments Network) Saudi Arabia domestic credit/debit card (Saudi Arabia Monetary Agency)","Type":""},{"AID":"A0000002471001","Vendor":"ISO JTC1/SC17/WG3","Country":"United Kingdom","Name":"Machine Readable Travel Documents (MRTD)","Description":"Electronic (Biometric) Passport. Issuer stored data application (The last three digits of the PIX shall be used to denote future version levels.)","Type":"MRTD"},{"AID":"A0000002472001","Vendor":"ISO JTC1/SC17/WG3","Country":"United Kingdom","Name":"Machine Readable Travel Documents (MRTD)","Description":"Electronic (Biometric) Passport. Application for hashes, digital signature, and certificate (The last three digits of the PIX shall be used to denote future version levels.)","Type":"MRTD"},{"AID":"A0000002771010","Vendor":"Interac Association","Country":"Canada","Name":"INTERAC","Description":"Canadian domestic credit/debit card","Type":"EMV"},{"AID":"A00000030600000000000000","Vendor":"PS/SC Workgroup","Country":"United States","Name":"PC/SC Initial access data AID","Description":"Possibly not an application","Type":""},{"AID":"A000000308000010000100","Vendor":"National Institute of Standards and Technology","Country":"United States","Name":"Personal Identity Verification (PIV) / ID-ONE PIV BIO","Description":"PIV End Point Applet. Last 2 bytes designate version?","Type":""},{"AID":"A00000031510100528","Vendor":"Currence Holding/PIN BV","Country":"The Netherlands","Name":"Currence PuC","Description":"","Type":"EMV"},{"AID":"A0000003156020","Vendor":"Currence Holding/PIN BV","Country":"The Netherlands","Name":"Chipknip","Description":"","Type":"EMV"},{"AID":"A00000032301","Vendor":"Identity Alliance","Country":"United States","Name":"MUSCLE Applet Package","Description":"http://osdir.com/ml/lib.muscle/2005-12/msg00066.html","Type":""},{"AID":"A0000003230101","Vendor":"Identity Alliance","Country":"United States","Name":"MUSCLE Applet Instance","Description":"http://osdir.com/ml/lib.muscle/2005-12/msg00066.html","Type":""},{"AID":"A0000003241010","Vendor":"Discover Financial Services LLC","Country":"United States","Name":"Discover Expresspay (ZIP)","Description":"","Type":""},{"AID":"A000000333010101","Vendor":"China Unionpay Co. Ltd","Country":"China","Name":"UnionPay Debit","Description":"","Type":""},{"AID":"A000000333010102","Vendor":"China Unionpay Co. Ltd","Country":"China","Name":"UnionPay Credit","Description":"","Type":""},{"AID":"A000000333010103","Vendor":"China Unionpay Co. Ltd","Country":"China","Name":"UnionPay Quasi Credit","Description":"","Type":""},{"AID":"A000000333010106","Vendor":"China Unionpay Co. Ltd","Country":"China","Name":"UnionPay Electronic Cash","Description":"","Type":""},{"AID":"A000000333010108","Vendor":"China Unionpay Co. Ltd","Country":"China","Name":"U.S. UnionPay Common Debit AID","Description":"","Type":""},{"AID":"A000000337301000","Vendor":"Groupment Interbancaire Mon?tique de l UEMOA","Country":"Senegal","Name":"Retrait","Description":"","Type":""},{"AID":"A000000337101000","Vendor":"Groupment Interbancaire Mon?tique de l UEMOA","Country":"Senegal","Name":"Standard","Description":"","Type":""},{"AID":"A000000337102000","Vendor":"Groupment Interbancaire Mon?tique de l UEMOA","Country":"Senegal","Name":"Classic","Description":"","Type":""},{"AID":"A000000337101001","Vendor":"Groupment Interbancaire Mon?tique de l UEMOA","Country":"Senegal","Name":"Prepaye Online","Description":"","Type":""},{"AID":"A000000337102001","Vendor":"Groupment Interbancaire Mon?tique de l UEMOA","Country":"Senegal","Name":"Prepaye Possibile Offiline","Description":"","Type":""},{"AID":"A000000337601001","Vendor":"Groupment Interbancaire Mon?tique de l UEMOA","Country":"Senegal","Name":"Porte Monnaie Electronique","Description":"","Type":""},{"AID":"A0000003591010","Vendor":"Euro Alliance of Payment Schemes s.c.r.l. EAPS","Country":"Belgium","Name":"","Description":"Unknown","Type":""},{"AID":"A0000003591010028001","Vendor":"Euro Alliance of Payment Schemes s.c.r.l. EAPS","Country":"Belgium","Name":"Girocard EAPS","Description":"ZKA (Germany)","Type":"EMV"},{"AID":"A00000035910100380","Vendor":"Euro Alliance of Payment Schemes s.c.r.l. EAPS","Country":"Belgium","Name":"","Description":"PagoBANCOMAT","Type":""},{"AID":"A0000003660001","Vendor":"Poste Italiane S.P.A","Country":"Italy","Name":"Postamat","Description":"","Type":""},{"AID":"A0000003660002","Vendor":"Poste Italiane S.P.A","Country":"Italy","Name":"Postamat VISA","Description":"","Type":""},{"AID":"A0000003710001","Vendor":"Verve","Country":"Nigeria","Name":"InterSwitch Verve Card","Description":"Nigerian local switch company","Type":"EMV"},{"AID":"A00000038410","Vendor":"eftpos, Australian Payments Clearing Association Ltd","Country":"Australia","Name":"Savings (debit card)","Description":"","Type":""},{"AID":"A00000038420","Vendor":"eftpos, Australian Payments Clearing Association Ltd","Country":"Australia","Name":"Cheque (debit card)","Description":"","Type":""},{"AID":"A0000003964D66344D0002","Vendor":"NXP Semiconductors Germany GmbH","Country":"Germany","Name":"MIFARE4MOBILE","Description":"NXP Mf4M","Type":""},{"AID":"A00000039742544659","Vendor":"Microsoft Corporation","Country":"United States","Name":"Microsoft IDMP AID","Description":"Identity Device With Microsoft Generic Profile application. 2 bytes can be added at the end. This byte must be set to the IDMP specification revision number which is currently 0x01. The second byte (yy) is reserved for use by the card application.","Type":""},{"AID":"A0000003974349445F0100","Vendor":"Microsoft Corporation","Country":"United States","Name":"Microsoft PNP AID","Description":"MS Plug and Play","Type":""},{"AID":"A0000004271010","Vendor":"Unibanco (Hipercard)","Country":"Brazil","Name":"Hiperchip","Description":"","Type":""},{"AID":"A0000004320001","Vendor":"100","Country":"Russia","Name":"Universal Electronic Card","Description":"","Type":""},{"AID":"A0000004360100","Vendor":"Edenred","Country":"Belgium","Name":"Ticket Restaurant","Description":"","Type":""},{"AID":"A0000004391010","Vendor":"ACCEL/Exchange","Country":"United States","Name":"Exchange ATM card","Description":"The Exchange Network ATM Network","Type":""},{"AID":"A0000004540010","Vendor":"eTranzact","Country":"Nigeria","Name":"Etranzact Genesis Card","Description":"Nigerian local switch company","Type":"EMV"},{"AID":"A0000004540011","Vendor":"eTranzact","Country":"Nigeria","Name":"Etranzact Genesis Card 2","Description":"Nigerian local switch company","Type":"EMV"},{"AID":"A0000004762010","Vendor":"Google","Country":"United States","Name":"GOOGLE_CONTROLLER_AID","Description":"GOOGLE_LOCKET_AID","Type":""},{"AID":"A0000004763030","Vendor":"Google","Country":"United States","Name":"GOOGLE_MIFARE_MANAGER_AID","Description":"","Type":""},{"AID":"A0000004766C","Vendor":"Google","Country":"United States","Name":"GOOGLE_PAYMENT_AID","Description":"","Type":"EMV"},{"AID":"A000000476A010","Vendor":"Google","Country":"United States","Name":"GSD_MANAGER_AID","Description":"","Type":"GP"},{"AID":"A000000476A110","Vendor":"Google","Country":"United States","Name":"GSD_MANAGER_AID","Description":"","Type":"GP"},{"AID":"A000000485","Vendor":"JVL Ventures, LLC (Softcard)","Country":"United States","Name":"Softcard SmartTap","Description":"","Type":""},{"AID":"A0000005241010","Vendor":"RuPay","Country":"India","Name":"RuPay","Description":"RuPay (India)","Type":"EMV"},{"AID":"A0000005271002","Vendor":"Yubico","Country":"Sweden","Name":"Yubikey NEO U2F Demo applet","Description":"Universal 2-Factor Proof-of-concept/Demo","Type":"YKNEO"},{"AID":"A000000527200101","Vendor":"Yubico","Country":"Sweden","Name":"Yubikey NEO Yubikey2 applet interface","Description":"Javacard Applet AID","Type":"YKNEO"},{"AID":"A000000527210101","Vendor":"Yubico","Country":"Sweden","Name":"Yubikey NEO OATH Applet","Description":"Javacard Applet AID","Type":"YKNEO"},{"AID":"A0000005591010FFFFFFFF8900000100","Vendor":"GSMA (GSM Association)","Country":"United Kingdom","Name":"ISD-R Application. Used as TAR.","Description":"","Type":""},{"AID":"A0000005591010FFFFFFFF8900000200","Vendor":"GSMA (GSM Association)","Country":"United Kingdom","Name":"ECASD Application. Used as TAR.","Description":"","Type":""},{"AID":"A0000005591010FFFFFFFF8900000D00","Vendor":"GSMA (GSM Association)","Country":"United Kingdom","Name":"ISD-P Executable Load File.","Description":"","Type":""},{"AID":"A0000005591010FFFFFFFF8900000E00","Vendor":"GSMA (GSM Association)","Country":"United Kingdom","Name":"ISD-P Executable Module.","Description":"","Type":""},{"AID":"A0000005591010FFFFFFFF8900000F00","Vendor":"GSMA (GSM Association)","Country":"United Kingdom","Name":"Reserved value for the Profiles ISD-P","Description":"","Type":""},{"AID":"A0000005591010FFFFFFFF8900001000","Vendor":"GSMA (GSM Association)","Country":"United Kingdom","Name":"ISD-P Application (1010FFFFFFFF89000010 to 1010FFFFFFFF8900FFFF. Used as TAR. The value is allocated during the Profile Download and Installation procedure","Description":"","Type":""},{"AID":"A00000061700","Vendor":"Fidesmo","Country":"Sweden","Name":"Fidesmo javacard","Description":"","Type":""},{"AID":"A0000006200620","Vendor":"Debit Network Alliance (DNA)","Country":"United States","Name":"Debit Network Alliance (DNA)","Description":"Common U.S. Debit","Type":""},{"AID":"A0000006581010","Vendor":"MIR","Country":"Russia","Name":"MIR Credit","Description":"","Type":""},{"AID":"A0000006581011","Vendor":"MIR","Country":"Russia","Name":"MIR Credit","Description":"","Type":""},{"AID":"A0000006582010","Vendor":"MIR","Country":"Russia","Name":"MIR Debit","Description":"","Type":""},{"AID":"A0000006723010","Vendor":"TROY","Country":"Turkey","Name":"TROY chip credit card","Description":"Turkeys Payment Method","Type":"EMV"},{"AID":"A0000006723020","Vendor":"TROY","Country":"Turkey","Name":"TROY chip debit card","Description":"Turkeys Payment Method","Type":"EMV"},{"AID":"A0000007705850","Vendor":"Indian Oil Corporation Limited","Country":"India","Name":"XTRAPOWER Fleet Card Program","Description":"Indian Oils Pre Paid Program","Type":"EMV"},{"AID":"A0000007790000","Vendor":"Zimswitch","Country":"Zimbabwe","Name":"","Description":"","Type":""},{"AID":"B012345678","Vendor":"MasterCard International","Country":"United States","Name":"Maestro TEST","Description":"Used for development","Type":"EMV"},{"AID":"D040000001000002","Vendor":"Paylife","Country":"Austria","Name":"Paylife Quick (IEP). Preloaded Electronic Purse","Description":"Domestic Payment System (Version 2.1)","Type":""},{"AID":"D040000002000002","Vendor":"Austria Card","Country":"Austria","Name":"RFU","Description":"Domestic Payment System (Version 2.1)","Type":""},{"AID":"D040000003000002","Vendor":"Austria Card","Country":"Austria","Name":"POS","Description":"Domestic Payment System (Version 2.1)","Type":""},{"AID":"D040000004000002","Vendor":"Austria Card","Country":"Austria","Name":"ATM","Description":"Domestic Payment System (Version 2.1)","Type":""},{"AID":"D04000000B000002","Vendor":"Austria Card","Country":"Austria","Name":"Retail","Description":"Domestic Loyalty Program (Version 2.1)","Type":""},{"AID":"D04000000C000002","Vendor":"Austria Card","Country":"Austria","Name":"Bank_Data","Description":"Domestic Loyalty Program (Version 2.1)","Type":""},{"AID":"D04000000D000002","Vendor":"Austria Card","Country":"Austria","Name":"Shopping","Description":"Domestic Loyalty Program (Version 2.1)","Type":""},{"AID":"D040000013000001","Vendor":"Austria Card","Country":"Austria","Name":"DF_UNI_Kepler1","Description":"Domestic Loyalty Program (Version 2.0)","Type":""},{"AID":"D040000013000001","Vendor":"Austria Card","Country":"Austria","Name":"DF_Sch?ler1","Description":"Domestic Loyalty Program (Version 1.3)","Type":""},{"AID":"D040000013000002","Vendor":"Austria Card","Country":"Austria","Name":"DF_UNI_Kepler2","Description":"Domestic Loyalty Program (Version 2.0)","Type":""},{"AID":"D040000013000002","Vendor":"Austria Card","Country":"Austria","Name":"DF_Sch?ler2","Description":"Domestic Loyalty Program (Version 1.3)","Type":""},{"AID":"D040000014000001","Vendor":"Austria Card","Country":"Austria","Name":"DF_Mensa","Description":"Domestic Loyalty Program (Version 2.0)","Type":""},{"AID":"D040000015000001","Vendor":"Austria Card","Country":"Austria","Name":"DF_UNI_Ausweis","Description":"Domestic Loyalty Program (Version 2.0)","Type":""},{"AID":"D040000015000001","Vendor":"Austria Card","Country":"Austria","Name":"DF_Ausweis","Description":"Domestic Loyalty Program (Version 1.3)","Type":""},{"AID":"D0400000190001","Vendor":"Austria Card","Country":"Austria","Name":"EMV ATM Maestro","Description":"Domestic EMV Application (Version 2.1)","Type":""},{"AID":"D0400000190002","Vendor":"Austria Card","Country":"Austria","Name":"EMV POS Maestro","Description":"Domestic EMV Application (Version 2.1)","Type":""},{"AID":"D0400000190003","Vendor":"Austria Card","Country":"Austria","Name":"EMV ATM MasterCard","Description":"Domestic EMV Application (Version 2.1)","Type":""},{"AID":"D0400000190004","Vendor":"Austria Card","Country":"Austria","Name":"EMV POS MasterCard","Description":"Domestic EMV Application (Version 2.1)","Type":""},{"AID":"D0400000190010","Vendor":"Austria Card","Country":"Austria","Name":"Digital ID","Description":"Domestic Payment System (Version 2.1)","Type":""},{"AID":"D268000001","Vendor":"Ministry of Finance of Georgia","Country":"Georgia","Name":"Fiscal module application","Description":"Georgia Revenue Service application for fiscal cash registers","Type":""},{"AID":"D276000005","Vendor":"Giesecke&Devrient","Country":"Germany","Name":"","Description":"Giesecke & Devrient","Type":""},{"AID":"D276000005AA040360010410","Vendor":"Giesecke&Devrient","Country":"Germany","Name":"G D App Nokia 6212","Description":"","Type":""},{"AID":"D276000005AA0503E00401","Vendor":"Giesecke&Devrient","Country":"Germany","Name":"G D App Nokia 6212","Description":"","Type":""},{"AID":"D276000005AA0503E00501","Vendor":"Giesecke&Devrient","Country":"Germany","Name":"G D App Nokia 6212","Description":"","Type":""},{"AID":"D276000005AA0503E0050101","Vendor":"Giesecke&Devrient","Country":"Germany","Name":"G D App Nokia 6212","Description":"","Type":""},{"AID":"D276000005AB0503E0040101","Vendor":"Giesecke&Devrient","Country":"Germany","Name":"G D App Nokia 6212","Description":"","Type":""},{"AID":"D27600002200000001","Vendor":"IBM Laboratories","Country":"Germany","Name":"SCT LOYALTY","Description":"IBM Test card from the book Smart Card Application Development Using Java","Type":""},{"AID":"D27600002200000002","Vendor":"IBM Laboratories","Country":"Germany","Name":"BUSINESS CARD","Description":"IBM Test card from the book Smart Card Application Development Using Java","Type":""},{"AID":"D27600002200000060","Vendor":"IBM Laboratories","Country":"Germany","Name":"PKCS#11 Token","Description":"IBM Test card from the book Smart Card Application Development Using Java","Type":""},{"AID":"D276000025","Vendor":"ZKA","Country":"Germany","Name":"Girocard","Description":"Girocard (Geldkarte) in Germany","Type":""},{"AID":"D27600002545410100","Vendor":"ZKA","Country":"Germany","Name":"","Description":"Unknown","Type":""},{"AID":"D27600002545500100","Vendor":"ZKA","Country":"Germany","Name":"Girocard","Description":"ZKA Girocard (Geldkarte) (Germany)","Type":"EMV"},{"AID":"D27600002547410100","Vendor":"ZKA","Country":"Germany","Name":"Girocard ATM","Description":"","Type":""},{"AID":"D276000060","Vendor":"Wolfgang Rankl","Country":"Germany","Name":"","Description":"","Type":""},{"AID":"D2760000850100","Vendor":"NXP Semiconductors / NFC Forum","Country":"Germany","Name":"NDEF Tag Application / Mifare DESFire Tag Application","Description":"NFC Forum Type 4 Tag","Type":""},{"AID":"D2760000850101","Vendor":"NXP Semiconductors / NFC Forum","Country":"Germany","Name":"NDEF Tag Application","Description":"NFC Tag type 4 tag","Type":""},{"AID":"D276000118","Vendor":"Giesecke&Devrient Java Card Telecommunikation","Country":"Germany","Name":"","Description":"","Type":""},{"AID":"D2760001180101","Vendor":"Giesecke&Devrient Java Card Telecommunikation","Country":"Germany","Name":"Giesecke &","Description":"Devrient Test Applet?","Type":""},{"AID":"D27600012401","Vendor":"fsfEurope","Country":"Germany","Name":"OpenPGP Card","Description":"For selection when not knowing the exact full AID","Type":"OpenPGP"},{"AID":"D276000124010101FFFF000000010000","Vendor":"fsfEurope","Country":"Germany","Name":"OpenPGP Card","Description":"Version 1","Type":"OpenPGP"},{"AID":"D2760001240102000000000000010000","Vendor":"fsfEurope","Country":"Germany","Name":"OpenPGP Card","Description":"Version 2","Type":"OpenPGP"},{"AID":"D27600012402","Vendor":"fsfEurope","Country":"Germany","Name":"SmartChess","Description":"http://smartchess.de/englisch/SmartChess_1.0.pdf","Type":"SmartChess"},{"AID":"D2760001240200010000000000000000","Vendor":"fsfEurope","Country":"Germany","Name":"SmartChess","Description":"http://smartchess.de/englisch/SmartChess_1.0.pdf","Type":"SmartChess"},{"AID":"D4100000011010","Vendor":"","Country":"Republic of Korea","Name":"","Description":"","Type":""},{"AID":"D5280050218002","Vendor":"","Country":"The Netherlands","Name":"?","Description":"(Netherlands)","Type":"EMV"},{"AID":"D5780000021010","Vendor":"Bankaxept","Country":"Norway","Name":"Bankaxept","Description":"Norwegian domestic debit card","Type":"EMV"},{"AID":"D7560000010101","Vendor":"Swiss Travel Fund (Reka)","Country":"Switzerland","Name":"Reka Card","Description":"prepaid functional debit card","Type":""},{"AID":"D7560000300101","Vendor":"Migros (FCM, GE Money Bank and MasterCard)","Country":"Switzerland","Name":"M Budget","Description":"","Type":""},{"AID":"E80704007F00070302","Vendor":"","Country":"","Name":"nPA","Description":"German eID","Type":""},{"AID":"E82881C11702","Vendor":"","Country":"","Name":"AlphaCard application","Description":"","Type":""},{"AID":"E828BD080F","Vendor":"","Country":"","Name":"ISO-7816-15 EF.DIR","Description":"Iso adoption of PKCS-15","Type":""},{"AID":"F0000000030001","Vendor":"","Country":"","Name":"BRADESCO","Description":"Brazilian Bank Banco Bradesco","Type":"EMV"},{"AID":"7465736C6153746F7265303032","Vendor":"Tesla","Country":"","Name":"teslaStore002","Description":"Tesla car key","Type":"Tesla"},{"AID":"7465736C614C6F67696330303201","Vendor":"Tesla","Country":"","Name":"teslaLogic002","Description":"Tesla car key","Type":"Tesla"}] \ No newline at end of file From 59730ee4fdbee3643bda979711c4edc345bd2250 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 4 Nov 2019 18:31:44 +0100 Subject: [PATCH 1111/1854] =?UTF-8?q?mfc=20keys=20dict:=20-=E2=98=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/dictionaries/mfc_default_keys.dic | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index ab113b0f5..6d8180e3a 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -22,7 +22,7 @@ a0478cc39091 # d2ece8b9395e # lib # NSCP default key -☻1494E81663D7 +1494E81663D7 # # more Keys from mfc_default_keys.lua 000000000001 From 706d8cc3324ebb7c5cd117f36015c648e954f2fa Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 4 Nov 2019 19:53:53 +0200 Subject: [PATCH 1112/1854] fix aidlist --- client/resources/aidlist.json | 2147 ++++++++++++++++++++++++++++++++- 1 file changed, 2146 insertions(+), 1 deletion(-) diff --git a/client/resources/aidlist.json b/client/resources/aidlist.json index 10ca4e8b0..3cb5c2e03 100644 --- a/client/resources/aidlist.json +++ b/client/resources/aidlist.json @@ -1 +1,2146 @@ -[{"AID":"315041592E5359532E4444463031","Vendor":"Visa International","Country":"United States","Name":"Visa Payment System Environment PSE (1PAY.SYS.DDF01)","Description":"","Type":""},{"AID":"325041592E5359532E4444463031","Vendor":"Visa International","Country":"United States","Name":"Visa Proximity Payment System Environment PPSE (2PAY.SYS.DDF01)","Description":"Visa payWave for Mobile","Type":""},{"AID":"44464D46412E44466172653234313031","Vendor":"DeviceFidelity","Country":"United States","Name":"DeviceFidelity In2Pay DFare applet","Description":"http://www.nfcworld.com/2010/11/24/35207/devicefidelity-adds-nfc-support-for-android-and-mifare/","Type":""},{"AID":"A00000000101","Vendor":"PBS Danm?nt A/S","Country":"Denmark","Name":"MUSCLE Card Applet","Description":"(Unlicensed use of this RID. Proposal to use A000000323 instead)","Type":""},{"AID":"A000000003000000","Vendor":"Visa International","Country":"United States","Name":"(VISA) Card Manager","Description":"Used by most GP2.1.1 cards / Oberthur OP201 cards. Visa Proprietary Card Manager AID for OpenPlatform cards (visa.openplatform).","Type":"GP"},{"AID":"A00000000300037561","Vendor":"Visa International","Country":"United States","Name":"Bonuscard","Description":"","Type":""},{"AID":"A00000000305076010","Vendor":"Visa International","Country":"United States","Name":"VISA ELO Credit","Description":"","Type":"EMV"},{"AID":"A0000000031010","Vendor":"Visa International","Country":"United States","Name":"VISA Debit/Credit (Classic)","Description":"Standard/Gold VISA credit card","Type":"EMV"},{"AID":"A000000003101001","Vendor":"Visa International","Country":"United States","Name":"VISA Credit","Description":"","Type":"EMV"},{"AID":"A000000003101002","Vendor":"Visa International","Country":"United States","Name":"VISA Debit","Description":"","Type":"EMV"},{"AID":"A0000000032010","Vendor":"Visa International","Country":"United States","Name":"VISA Electron","Description":"VISA Electron (Debit)","Type":"EMV"},{"AID":"A0000000032020","Vendor":"Visa International","Country":"United States","Name":"VISA","Description":"V PAY","Type":"EMV"},{"AID":"A0000000033010","Vendor":"Visa International","Country":"United States","Name":"VISA Interlink","Description":"VISA Interlink","Type":"EMV"},{"AID":"A0000000034010","Vendor":"Visa International","Country":"United States","Name":"VISA Specific","Description":"Visa Specific","Type":"EMV"},{"AID":"A0000000035010","Vendor":"Visa International","Country":"United States","Name":"VISA Specific","Description":"Visa Specific","Type":"EMV"},{"AID":"A000000003534441","Vendor":"Visa International","Country":"United States","Name":"Schlumberger Security Domain","Description":"","Type":"GP"},{"AID":"A0000000035350","Vendor":"Visa International","Country":"United States","Name":"Security Domain","Description":"OCS Oberthur Card System Security Domain Package AID / VGP Card Manager (for ISD and ASD)","Type":"GP"},{"AID":"A000000003535041","Vendor":"Visa International","Country":"United States","Name":"Security Domain","Description":"OCS Oberthur Card System Security Domain Applet AID / VGP Card Manager (for ISD and ASD)","Type":"GP"},{"AID":"A0000000036010","Vendor":"Visa International","Country":"United States","Name":"Domestic Visa Cash Stored Value","Description":"","Type":"EMV"},{"AID":"A0000000036020","Vendor":"Visa International","Country":"United States","Name":"International Visa Cash Stored Value","Description":"","Type":"EMV"},{"AID":"A0000000038002","Vendor":"Visa International","Country":"United States","Name":"VISA Auth, VisaRemAuthen EMV-CAP (DPA)","Description":"VISA Auth dynamic passcode authentication (DPA). Used by Barclays/HBOS","Type":"EMV"},{"AID":"A0000000038010","Vendor":"Visa International","Country":"United States","Name":"VISA Plus","Description":"VISA plus","Type":"EMV"},{"AID":"A0000000039010","Vendor":"Visa International","Country":"United States","Name":"VISA Loyalty","Description":"","Type":"EMV"},{"AID":"A000000003999910","Vendor":"Visa International","Country":"United States","Name":"VISA Proprietary ATM","Description":"","Type":"EMV"},{"AID":"A0000000040000","Vendor":"Mastercard International","Country":"United States","Name":"MasterCard Card Manager","Description":"Security Domain","Type":"GP"},{"AID":"A00000000401","Vendor":"Mastercard International","Country":"United States","Name":"MasterCard PayPass","Description":"AEPM (Association Europ?enne Payez Mobile)","Type":"EMV"},{"AID":"A0000000041010","Vendor":"Mastercard International","Country":"United States","Name":"MasterCard Credit/Debit (Global)","Description":"Standard MasterCard","Type":"EMV"},{"AID":"A00000000410101213","Vendor":"Mastercard International","Country":"United States","Name":"MasterCard Credit","Description":"Standard MasterCard","Type":"EMV"},{"AID":"A00000000410101215","Vendor":"Mastercard International","Country":"United States","Name":"MasterCard Credit","Description":"Standard MasterCard","Type":"EMV"},{"AID":"A0000000041010BB5449435301","Vendor":"Mastercard International","Country":"United States","Name":"[UNKNOWN]","Description":"Some co-branded card?","Type":""},{"AID":"A0000000042010","Vendor":"Mastercard International","Country":"United States","Name":"MasterCard Specific","Description":"MasterCard Specific","Type":"EMV"},{"AID":"A0000000042203","Vendor":"Mastercard International","Country":"United States","Name":"MasterCard Specific","Description":"MasterCard U.S. Maestro","Type":""},{"AID":"A0000000043010","Vendor":"Mastercard International","Country":"United States","Name":"MasterCard Specific","Description":"MasterCard Specific","Type":"EMV"},{"AID":"A0000000043060","Vendor":"Mastercard International","Country":"United States","Name":"Maestro (Debit)","Description":"Maestro (Debit) Card","Type":"EMV"},{"AID":"A000000004306001","Vendor":"Mastercard International","Country":"United States","Name":"Maestro (Debit)","Description":"Maestro (Debit) Card","Type":"EMV"},{"AID":"A0000000044010","Vendor":"Mastercard International","Country":"United States","Name":"MasterCard Specific","Description":"MasterCard Specific","Type":"EMV"},{"AID":"A0000000045010","Vendor":"Mastercard International","Country":"United States","Name":"MasterCard Specific","Description":"MasterCard Specific","Type":"EMV"},{"AID":"A0000000045555","Vendor":"Mastercard International","Country":"United States","Name":"APDULogger","Description":"AID on Cirrus Test Card","Type":""},{"AID":"A0000000046000","Vendor":"Mastercard International","Country":"United States","Name":"Cirrus","Description":"Mastercard Cirrus (Interbank Network) ATM card only","Type":"EMV"},{"AID":"A0000000048002","Vendor":"Mastercard International","Country":"United States","Name":"SecureCode Auth EMV-CAP","Description":"Chip Authentication Protocol (CAP). Works with NatWest or SecureCode Aut","Type":"EMV"},{"AID":"A0000000049999","Vendor":"Mastercard International","Country":"United States","Name":"MasterCard PayPass??","Description":"","Type":"EMV"},{"AID":"A0000000050001","Vendor":"Switch Card Services Ltd.","Country":"United Kingdom","Name":"Maestro UK","Description":"UK Domestic Maestro Switch (debit card)","Type":"EMV"},{"AID":"A0000000050002","Vendor":"Switch Card Services Ltd.","Country":"United Kingdom","Name":"Solo","Description":"UK Domestic Maestro Switch (debit card)","Type":"EMV"},{"AID":"A0000000090001FF44FF1289","Vendor":"ETSI","Country":"France","Name":"Orange","Description":"Orange UK","Type":""},{"AID":"A0000000101030","Vendor":"Europay International","Country":"Belgium","Name":"Maestro-CH","Description":"","Type":""},{"AID":"A00000001800","Vendor":"GEMPLUS","Country":"France","Name":"Gemplus ?","Description":"","Type":""},{"AID":"A0000000181001","Vendor":"GEMPLUS","Country":"France","Name":"com.gemplus.javacard.util packages","Description":"","Type":""},{"AID":"A000000018434D","Vendor":"GEMPLUS","Country":"France","Name":"Gemplus card manager","Description":"434D = CM (ascii). Security domain for some GCX/GXP cards (GemXpresso Pro) (Gemalto)","Type":"GP"},{"AID":"A000000018434D00","Vendor":"GEMPLUS","Country":"France","Name":"Gemplus Security Domain","Description":"(Gemalto)","Type":"GP"},{"AID":"A00000002401","Vendor":"Midland Bank Plc","Country":"United Kingdom","Name":"Self Service","Description":"","Type":"EMV"},{"AID":"A000000025","Vendor":"American Express","Country":"United Kingdom","Name":"American Express","Description":"","Type":"EMV"},{"AID":"A0000000250000","Vendor":"American Express","Country":"United Kingdom","Name":"American Express","Description":"American Express (Credit/Debit)","Type":"EMV"},{"AID":"A00000002501","Vendor":"American Express","Country":"United Kingdom","Name":"American Express","Description":"AEIPS-compliant (A-E contact EMV) payment application","Type":"EMV"},{"AID":"A000000025010104","Vendor":"American Express","Country":"United Kingdom","Name":"American Express","Description":"","Type":""},{"AID":"A000000025010402","Vendor":"American Express","Country":"United Kingdom","Name":"American Express","Description":"","Type":"EMV"},{"AID":"A000000025010701","Vendor":"American Express","Country":"United Kingdom","Name":"ExpressPay","Description":"","Type":"EMV"},{"AID":"A000000025010801","Vendor":"American Express","Country":"United Kingdom","Name":"American Express","Description":"","Type":"EMV"},{"AID":"A0000000291010","Vendor":"LINK Interchange Network Ltd","Country":"United Kingdom","Name":"Link / American Express","Description":"Link (UK) ATM Network, or AMEX (Portugal?)","Type":"EMV"},{"AID":"A00000002945087510100000","Vendor":"LINK Interchange Network Ltd","Country":"United Kingdom","Name":"CO-OP","Description":"","Type":""},{"AID":"A00000002949034010100001","Vendor":"LINK Interchange Network Ltd","Country":"United Kingdom","Name":"HSBC","Description":"","Type":""},{"AID":"A00000002949282010100000","Vendor":"LINK Interchange Network Ltd","Country":"United Kingdom","Name":"Barclay","Description":"","Type":""},{"AID":"A000000029564182","Vendor":"LINK Interchange Network Ltd","Country":"United Kingdom","Name":"HAFX","Description":"","Type":""},{"AID":"A00000003029057000AD13100101FF","Vendor":"Schlumberger Industries Identif dEncarteur PR050","Country":"France","Name":"BelPIC (Belgian Personal Identity Card) JavaCard Applet","Description":"Schlumberger (Gemalto) RID","Type":""},{"AID":"A0000000308000000000280101","Vendor":"Schlumberger Industries Identif dEncarteur PR050","Country":"France","Name":"Gemalto .NET Card AID","Description":"","Type":""},{"AID":"A0000000421010","Vendor":"Groupement des Cartes Bancaires CB","Country":"France","Name":"Cartes Bancaire EMV Card","Description":"Groupement des Cartes Bancaires (France)","Type":"EMV"},{"AID":"A0000000422010","Vendor":"Groupement des Cartes Bancaires CB","Country":"France","Name":"","Description":"","Type":"EMV"},{"AID":"A0000000423010","Vendor":"Groupement des Cartes Bancaires CB","Country":"France","Name":"","Description":"","Type":"EMV"},{"AID":"A0000000424010","Vendor":"Groupement des Cartes Bancaires CB","Country":"France","Name":"","Description":"","Type":"EMV"},{"AID":"A0000000425010","Vendor":"Groupement des Cartes Bancaires CB","Country":"France","Name":"","Description":"","Type":"EMV"},{"AID":"A0000000426010","Vendor":"Groupement des Cartes Bancaires CB","Country":"France","Name":"Contactless payment using Apple Pay","Description":"","Type":"EMV"},{"AID":"A00000005945430100","Vendor":"Zentraler Kreditausschuss (ZKA)","Country":"Germany","Name":"Girocard Electronic Cash","Description":"","Type":""},{"AID":"A000000063504B43532D3135","Vendor":"RSA Laboratories","Country":"United States","Name":"PKCS-15","Description":"RSA PKCS-15 PKI application (Predecessor to ISO7816-15) / ID-card in Finland","Type":""},{"AID":"A0000000635741502D57494D","Vendor":"RSA Laboratories","Country":"United States","Name":"WAP-WIM","Description":"WAP (Wireless Application Protocol) Identity Module / Wireless Identification Module","Type":""},{"AID":"A00000006510","Vendor":"JCB CO., LTD.","Country":"Japan","Name":"JCB","Description":"Japan Credit Bureau","Type":"EMV"},{"AID":"A0000000651010","Vendor":"JCB CO., LTD.","Country":"Japan","Name":"JCB J Smart Credit","Description":"Japan Credit Bureau","Type":"EMV"},{"AID":"A00000006900","Vendor":"Soci?t? Europ?enne de Monnaie Electronique SEME","Country":"France","Name":"Moneo","Description":"","Type":"EMV"},{"AID":"A000000077010000021000000000003B","Vendor":"Oberthur Technologies","Country":"France","Name":"Visa AEPN","Description":"","Type":"EMV"},{"AID":"A0000000790100","Vendor":"Activcard Europe S.A.","Country":"France","Name":"CACv2 PKI ID","Description":"Identity Key","Type":""},{"AID":"A0000000790101","Vendor":"Activcard Europe S.A.","Country":"France","Name":"CACv2 PKI Sign","Description":"Digital Signature Key","Type":""},{"AID":"A0000000790102","Vendor":"Activcard Europe S.A.","Country":"France","Name":"CACv2 PKI Enc","Description":"Key Management Key","Type":""},{"AID":"A00000007901F0","Vendor":"Activcard Europe S.A.","Country":"France","Name":"CACv1 PKI Identity Key","Description":"Re-directs to CACv2 PKI Identity key","Type":""},{"AID":"A00000007901F1","Vendor":"Activcard Europe S.A.","Country":"France","Name":"CACv1 PKI Digital Signature Key","Description":"Re-directs to CACv2 Digital Signature key","Type":""},{"AID":"A00000007901F2","Vendor":"Activcard Europe S.A.","Country":"France","Name":"CACv1 PKI Key Management Key","Description":"Re-directs to CACv2 Key Management key","Type":""},{"AID":"A0000000790200","Vendor":"Activcard Europe S.A.","Country":"France","Name":"CACv2 DoD Person","Description":"DoD Demographic","Type":""},{"AID":"A0000000790201","Vendor":"Activcard Europe S.A.","Country":"France","Name":"CACv2 DoD Personnel","Description":"DoD Demographic","Type":""},{"AID":"A00000007902FB","Vendor":"Activcard Europe S.A.","Country":"France","Name":"CACv1 BC","Description":"General Configuration","Type":""},{"AID":"A00000007902FD","Vendor":"Activcard Europe S.A.","Country":"France","Name":"CACv1 BC","Description":"PKI Certificate Attributes","Type":""},{"AID":"A00000007902FE","Vendor":"Activcard Europe S.A.","Country":"France","Name":"CACv1 BC","Description":"PKI Cert","Type":""},{"AID":"A0000000790300","Vendor":"Activcard Europe S.A.","Country":"France","Name":"CACv2 Access Control Applet","Description":"CAC PIN / ID PIN Management Applet","Type":""},{"AID":"A0000000791201","Vendor":"Activcard Europe S.A.","Country":"France","Name":"CAC JDM","Description":"Joint Data Model. BCAdmin","Type":""},{"AID":"A0000000791202","Vendor":"Activcard Europe S.A.","Country":"France","Name":"CAC JDM","Description":"Joint Data Model. BCMedical","Type":""},{"AID":"A0000000871002FF49FF0589","Vendor":"Third Generation Partnership Project (3GPP)","Country":"France","Name":"Telenor USIM","Description":"","Type":"USIM"},{"AID":"A00000008810200105C100","Vendor":"Buypass AS","Country":"Norway","Name":"BuyPass BIDA","Description":"Used by norwegian public betting company Norsk-Tipping?","Type":"BuyPass"},{"AID":"A000000088102201034221","Vendor":"Buypass AS","Country":"Norway","Name":"BuyPass BEID (BuyPass Electronic ID?)","Description":"","Type":"BuyPass"},{"AID":"A000000088102201034321","Vendor":"Buypass AS","Country":"Norway","Name":"BuyPass BEID (BuyPass Electronic ID?)","Description":"","Type":"BuyPass"},{"AID":"A0000000960200","Vendor":"Sa Proton World International N.V.","Country":"Belgium","Name":"Proton World International Security Domain","Description":"Proton, which is owned in part by Visa International and American Express Co., is in three other European countries: the original Proton program in Belgium, Chipknip in the Netherlands, and Cash in Switzerland","Type":"GP"},{"AID":"A000000098","Vendor":"Visa USA","Country":"United States","Name":"Debit Card","Description":"Bank of America Debit Card","Type":"EMV"},{"AID":"A0000000980840","Vendor":"Visa USA","Country":"United States","Name":"Visa Common Debit","Description":"","Type":""},{"AID":"A0000000980848","Vendor":"Visa USA","Country":"United States","Name":"Debit Card","Description":"Schwab Bank Debit Card","Type":"EMV"},{"AID":"A0000001110101","Vendor":"Die Post Postfinance","Country":"Switzerland","Name":"Postcard","Description":"","Type":""},{"AID":"A0000001160300","Vendor":"GSA TFCS","Country":"United States","Name":"PIV CHUID","Description":"CHUID","Type":""},{"AID":"A0000001166010","Vendor":"GSA TFCS","Country":"United States","Name":"PIV Fingerprints","Description":"Fingerprints","Type":""},{"AID":"A0000001166030","Vendor":"GSA TFCS","Country":"United States","Name":"PIV Facial Image","Description":"Facial Image","Type":""},{"AID":"A0000001169000","Vendor":"GSA TFCS","Country":"United States","Name":"PIV Security Object","Description":"Security Object","Type":""},{"AID":"A000000116A001","Vendor":"GSA TFCS","Country":"United States","Name":"PIV Authentication Key","Description":"PIV Authentication Key","Type":""},{"AID":"A000000116DB00","Vendor":"GSA TFCS","Country":"United States","Name":"CCC","Description":"Card Capability Container","Type":""},{"AID":"A000000118010000","Vendor":"Austria Card","Country":"Austria","Name":"DF_Verkehr","Description":"Domestic Loyalty Program (Version 1.3)","Type":""},{"AID":"A000000118020000","Vendor":"Austria Card","Country":"Austria","Name":"DF_Partner","Description":"Domestic Loyalty Program (Version 1.3)","Type":""},{"AID":"A000000118030000","Vendor":"Austria Card","Country":"Austria","Name":"DF_Sch?lerdaten","Description":"Domestic Loyalty Program (Version 1.3)","Type":""},{"AID":"A000000118040000","Vendor":"Austria Card","Country":"Austria","Name":"DF_KEP_SIG","Description":"Domestic Loyalty Program (Version 1.32)","Type":""},{"AID":"A0000001184543","Vendor":"Austria Card","Country":"Austria","Name":"Digital Signature (SSCA)","Description":"Digital Signature Application","Type":""},{"AID":"A000000118454E","Vendor":"Austria Card","Country":"Austria","Name":"Encryption Application","Description":"Encryption Application (Version 1.10)","Type":""},{"AID":"A0000001211010","Vendor":"PBS Danmark A/S","Country":"Denmark","Name":"Dankort (VISA GEM Vision)","Description":"Danish domestic debit card","Type":"EMV"},{"AID":"A0000001320001","Vendor":"Java Card Forum","Country":"United States","Name":"org.javacardforum.javacard.biometry","Description":"","Type":""},{"AID":"A0000001408001","Vendor":"TDS TODOS DATA SYSTEM AB","Country":"Sweden","Name":"eCode","Description":"","Type":""},{"AID":"A0000001410001","Vendor":"Associazione Bancaria Italiana","Country":"Italy","Name":"PagoBANCOMAT","Description":"CoGeBan Consorzio BANCOMAT (Italian domestic debit card)","Type":"EMV"},{"AID":"A0000001510000","Vendor":"GlobalPlatform, Inc.","Country":"United States","Name":"Global Platform Security Domain AID","Description":"GP Card Manager","Type":"GP"},{"AID":"A00000015153504341534400","Vendor":"GlobalPlatform, Inc.","Country":"United States","Name":"CASD_AID","Description":"SPCASD","Type":"GP"},{"AID":"A0000001523010","Vendor":"Diners Club International Ltd.","Country":"United States","Name":"Discover, Pulse D Pas","Description":"Discover Card","Type":"EMV"},{"AID":"A0000001524010","Vendor":"Diners Club International Ltd.","Country":"United States","Name":"Discover","Description":"Discover Debit Common Card","Type":"EMV"},{"AID":"A0000001544442","Vendor":"Banrisul Banco do Estado do Rio Grande do SUL S.A.","Country":"Brazil","Name":"Banricompras Debito","Description":"Banrisul (Brazil)","Type":"EMV"},{"AID":"A0000001570010","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"AMEX","Description":"","Type":""},{"AID":"A0000001570020","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"MasterCard","Description":"","Type":""},{"AID":"A0000001570021","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"Maestro","Description":"","Type":""},{"AID":"A0000001570022","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"Maestro","Description":"","Type":""},{"AID":"A0000001570023","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"CASH","Description":"","Type":""},{"AID":"A0000001570030","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"VISA","Description":"","Type":""},{"AID":"A0000001570031","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"VISA","Description":"","Type":""},{"AID":"A0000001570040","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"JCB","Description":"","Type":""},{"AID":"A0000001570050","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"Postcard","Description":"","Type":""},{"AID":"A0000001570051","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"Postcard","Description":"","Type":""},{"AID":"A0000001570100","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"MCard","Description":"","Type":""},{"AID":"A0000001570104","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"MyOne","Description":"","Type":""},{"AID":"A0000001570109","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"Mediamarkt Card","Description":"","Type":""},{"AID":"A000000157010A","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"Gift Card","Description":"","Type":""},{"AID":"A000000157010B","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"Bonuscard","Description":"","Type":""},{"AID":"A000000157010C","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"WIRCard","Description":"","Type":""},{"AID":"A000000157010D","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"Power Card","Description":"","Type":""},{"AID":"A0000001574443","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"DINERS CLUB","Description":"","Type":""},{"AID":"A0000001574444","Vendor":"Z?hlke Engineering AG","Country":"Switzerland","Name":"Supercard Plus","Description":"","Type":""},{"AID":"A000000167413000FF","Vendor":"IBM","Country":"Germany","Name":"JCOP Identify Applet","Description":"identify in JCOP-tools returns eg 27 34 01 2E 00 00 00 00 4E 58 37 35 31 41 00 03 28 62 B3 6A 82","Type":"JCOP"},{"AID":"A000000167413001","Vendor":"IBM","Country":"Germany","Name":"FIPS 140-2","Description":"?","Type":""},{"AID":"A000000172950001","Vendor":"Financial Information Service Co. Ltd.","Country":"Taiwan","Name":"BAROC Financial Application Taiwan","Description":"The Bankers Association of the Republic of China","Type":"EMV"},{"AID":"A000000177504B43532D3135","Vendor":"Minist?re de LInt?rieur","Country":"Belgium","Name":"BelPIC (Belgian Personal Identity Card)","Description":"","Type":""},{"AID":"A0000001850002","Vendor":"Post Office Limited","Country":"United Kingdom","Name":"UK Post Office Account card","Description":"","Type":"EMV"},{"AID":"A0000001884443","Vendor":"Diners Club Switzerland Ltd","Country":"Switzerland","Name":"DINERS CLUB","Description":"","Type":""},{"AID":"A0000002040000","Vendor":"Association for Payment Clearing Services","Country":"United Kingdom","Name":"?","Description":"","Type":""},{"AID":"A0000002281010","Vendor":"Saudi Arabian Monetary Agency (SAMA)","Country":"Kingdom of Saudi Arabia","Name":"SPAN (M/Chip)","Description":"SPAN2 (Saudi Payments Network) Saudi Arabia domestic credit/debit card (Saudi Arabia Monetary Agency)","Type":"EMV"},{"AID":"A0000002282010","Vendor":"Saudi Arabian Monetary Agency (SAMA)","Country":"Kingdom of Saudi Arabia","Name":"SPAN (VIS)","Description":"SPAN2 (Saudi Payments Network) Saudi Arabia domestic credit/debit card (Saudi Arabia Monetary Agency)","Type":"EMV"},{"AID":"A00000022820101010","Vendor":"Saudi Arabian Monetary Agency (SAMA)","Country":"Kingdom of Saudi Arabia","Name":"SPAN","Description":"SPAN2 (Saudi Payments Network) Saudi Arabia domestic credit/debit card (Saudi Arabia Monetary Agency)","Type":""},{"AID":"A0000002471001","Vendor":"ISO JTC1/SC17/WG3","Country":"United Kingdom","Name":"Machine Readable Travel Documents (MRTD)","Description":"Electronic (Biometric) Passport. Issuer stored data application (The last three digits of the PIX shall be used to denote future version levels.)","Type":"MRTD"},{"AID":"A0000002472001","Vendor":"ISO JTC1/SC17/WG3","Country":"United Kingdom","Name":"Machine Readable Travel Documents (MRTD)","Description":"Electronic (Biometric) Passport. Application for hashes, digital signature, and certificate (The last three digits of the PIX shall be used to denote future version levels.)","Type":"MRTD"},{"AID":"A0000002771010","Vendor":"Interac Association","Country":"Canada","Name":"INTERAC","Description":"Canadian domestic credit/debit card","Type":"EMV"},{"AID":"A00000030600000000000000","Vendor":"PS/SC Workgroup","Country":"United States","Name":"PC/SC Initial access data AID","Description":"Possibly not an application","Type":""},{"AID":"A000000308000010000100","Vendor":"National Institute of Standards and Technology","Country":"United States","Name":"Personal Identity Verification (PIV) / ID-ONE PIV BIO","Description":"PIV End Point Applet. Last 2 bytes designate version?","Type":""},{"AID":"A00000031510100528","Vendor":"Currence Holding/PIN BV","Country":"The Netherlands","Name":"Currence PuC","Description":"","Type":"EMV"},{"AID":"A0000003156020","Vendor":"Currence Holding/PIN BV","Country":"The Netherlands","Name":"Chipknip","Description":"","Type":"EMV"},{"AID":"A00000032301","Vendor":"Identity Alliance","Country":"United States","Name":"MUSCLE Applet Package","Description":"http://osdir.com/ml/lib.muscle/2005-12/msg00066.html","Type":""},{"AID":"A0000003230101","Vendor":"Identity Alliance","Country":"United States","Name":"MUSCLE Applet Instance","Description":"http://osdir.com/ml/lib.muscle/2005-12/msg00066.html","Type":""},{"AID":"A0000003241010","Vendor":"Discover Financial Services LLC","Country":"United States","Name":"Discover Expresspay (ZIP)","Description":"","Type":""},{"AID":"A000000333010101","Vendor":"China Unionpay Co. Ltd","Country":"China","Name":"UnionPay Debit","Description":"","Type":""},{"AID":"A000000333010102","Vendor":"China Unionpay Co. Ltd","Country":"China","Name":"UnionPay Credit","Description":"","Type":""},{"AID":"A000000333010103","Vendor":"China Unionpay Co. Ltd","Country":"China","Name":"UnionPay Quasi Credit","Description":"","Type":""},{"AID":"A000000333010106","Vendor":"China Unionpay Co. Ltd","Country":"China","Name":"UnionPay Electronic Cash","Description":"","Type":""},{"AID":"A000000333010108","Vendor":"China Unionpay Co. Ltd","Country":"China","Name":"U.S. UnionPay Common Debit AID","Description":"","Type":""},{"AID":"A000000337301000","Vendor":"Groupment Interbancaire Mon?tique de l UEMOA","Country":"Senegal","Name":"Retrait","Description":"","Type":""},{"AID":"A000000337101000","Vendor":"Groupment Interbancaire Mon?tique de l UEMOA","Country":"Senegal","Name":"Standard","Description":"","Type":""},{"AID":"A000000337102000","Vendor":"Groupment Interbancaire Mon?tique de l UEMOA","Country":"Senegal","Name":"Classic","Description":"","Type":""},{"AID":"A000000337101001","Vendor":"Groupment Interbancaire Mon?tique de l UEMOA","Country":"Senegal","Name":"Prepaye Online","Description":"","Type":""},{"AID":"A000000337102001","Vendor":"Groupment Interbancaire Mon?tique de l UEMOA","Country":"Senegal","Name":"Prepaye Possibile Offiline","Description":"","Type":""},{"AID":"A000000337601001","Vendor":"Groupment Interbancaire Mon?tique de l UEMOA","Country":"Senegal","Name":"Porte Monnaie Electronique","Description":"","Type":""},{"AID":"A0000003591010","Vendor":"Euro Alliance of Payment Schemes s.c.r.l. EAPS","Country":"Belgium","Name":"","Description":"Unknown","Type":""},{"AID":"A0000003591010028001","Vendor":"Euro Alliance of Payment Schemes s.c.r.l. EAPS","Country":"Belgium","Name":"Girocard EAPS","Description":"ZKA (Germany)","Type":"EMV"},{"AID":"A00000035910100380","Vendor":"Euro Alliance of Payment Schemes s.c.r.l. EAPS","Country":"Belgium","Name":"","Description":"PagoBANCOMAT","Type":""},{"AID":"A0000003660001","Vendor":"Poste Italiane S.P.A","Country":"Italy","Name":"Postamat","Description":"","Type":""},{"AID":"A0000003660002","Vendor":"Poste Italiane S.P.A","Country":"Italy","Name":"Postamat VISA","Description":"","Type":""},{"AID":"A0000003710001","Vendor":"Verve","Country":"Nigeria","Name":"InterSwitch Verve Card","Description":"Nigerian local switch company","Type":"EMV"},{"AID":"A00000038410","Vendor":"eftpos, Australian Payments Clearing Association Ltd","Country":"Australia","Name":"Savings (debit card)","Description":"","Type":""},{"AID":"A00000038420","Vendor":"eftpos, Australian Payments Clearing Association Ltd","Country":"Australia","Name":"Cheque (debit card)","Description":"","Type":""},{"AID":"A0000003964D66344D0002","Vendor":"NXP Semiconductors Germany GmbH","Country":"Germany","Name":"MIFARE4MOBILE","Description":"NXP Mf4M","Type":""},{"AID":"A00000039742544659","Vendor":"Microsoft Corporation","Country":"United States","Name":"Microsoft IDMP AID","Description":"Identity Device With Microsoft Generic Profile application. 2 bytes can be added at the end. This byte must be set to the IDMP specification revision number which is currently 0x01. The second byte (yy) is reserved for use by the card application.","Type":""},{"AID":"A0000003974349445F0100","Vendor":"Microsoft Corporation","Country":"United States","Name":"Microsoft PNP AID","Description":"MS Plug and Play","Type":""},{"AID":"A0000004271010","Vendor":"Unibanco (Hipercard)","Country":"Brazil","Name":"Hiperchip","Description":"","Type":""},{"AID":"A0000004320001","Vendor":"100","Country":"Russia","Name":"Universal Electronic Card","Description":"","Type":""},{"AID":"A0000004360100","Vendor":"Edenred","Country":"Belgium","Name":"Ticket Restaurant","Description":"","Type":""},{"AID":"A0000004391010","Vendor":"ACCEL/Exchange","Country":"United States","Name":"Exchange ATM card","Description":"The Exchange Network ATM Network","Type":""},{"AID":"A0000004540010","Vendor":"eTranzact","Country":"Nigeria","Name":"Etranzact Genesis Card","Description":"Nigerian local switch company","Type":"EMV"},{"AID":"A0000004540011","Vendor":"eTranzact","Country":"Nigeria","Name":"Etranzact Genesis Card 2","Description":"Nigerian local switch company","Type":"EMV"},{"AID":"A0000004762010","Vendor":"Google","Country":"United States","Name":"GOOGLE_CONTROLLER_AID","Description":"GOOGLE_LOCKET_AID","Type":""},{"AID":"A0000004763030","Vendor":"Google","Country":"United States","Name":"GOOGLE_MIFARE_MANAGER_AID","Description":"","Type":""},{"AID":"A0000004766C","Vendor":"Google","Country":"United States","Name":"GOOGLE_PAYMENT_AID","Description":"","Type":"EMV"},{"AID":"A000000476A010","Vendor":"Google","Country":"United States","Name":"GSD_MANAGER_AID","Description":"","Type":"GP"},{"AID":"A000000476A110","Vendor":"Google","Country":"United States","Name":"GSD_MANAGER_AID","Description":"","Type":"GP"},{"AID":"A000000485","Vendor":"JVL Ventures, LLC (Softcard)","Country":"United States","Name":"Softcard SmartTap","Description":"","Type":""},{"AID":"A0000005241010","Vendor":"RuPay","Country":"India","Name":"RuPay","Description":"RuPay (India)","Type":"EMV"},{"AID":"A0000005271002","Vendor":"Yubico","Country":"Sweden","Name":"Yubikey NEO U2F Demo applet","Description":"Universal 2-Factor Proof-of-concept/Demo","Type":"YKNEO"},{"AID":"A000000527200101","Vendor":"Yubico","Country":"Sweden","Name":"Yubikey NEO Yubikey2 applet interface","Description":"Javacard Applet AID","Type":"YKNEO"},{"AID":"A000000527210101","Vendor":"Yubico","Country":"Sweden","Name":"Yubikey NEO OATH Applet","Description":"Javacard Applet AID","Type":"YKNEO"},{"AID":"A0000005591010FFFFFFFF8900000100","Vendor":"GSMA (GSM Association)","Country":"United Kingdom","Name":"ISD-R Application. Used as TAR.","Description":"","Type":""},{"AID":"A0000005591010FFFFFFFF8900000200","Vendor":"GSMA (GSM Association)","Country":"United Kingdom","Name":"ECASD Application. Used as TAR.","Description":"","Type":""},{"AID":"A0000005591010FFFFFFFF8900000D00","Vendor":"GSMA (GSM Association)","Country":"United Kingdom","Name":"ISD-P Executable Load File.","Description":"","Type":""},{"AID":"A0000005591010FFFFFFFF8900000E00","Vendor":"GSMA (GSM Association)","Country":"United Kingdom","Name":"ISD-P Executable Module.","Description":"","Type":""},{"AID":"A0000005591010FFFFFFFF8900000F00","Vendor":"GSMA (GSM Association)","Country":"United Kingdom","Name":"Reserved value for the Profiles ISD-P","Description":"","Type":""},{"AID":"A0000005591010FFFFFFFF8900001000","Vendor":"GSMA (GSM Association)","Country":"United Kingdom","Name":"ISD-P Application (1010FFFFFFFF89000010 to 1010FFFFFFFF8900FFFF. Used as TAR. The value is allocated during the Profile Download and Installation procedure","Description":"","Type":""},{"AID":"A00000061700","Vendor":"Fidesmo","Country":"Sweden","Name":"Fidesmo javacard","Description":"","Type":""},{"AID":"A0000006200620","Vendor":"Debit Network Alliance (DNA)","Country":"United States","Name":"Debit Network Alliance (DNA)","Description":"Common U.S. Debit","Type":""},{"AID":"A0000006581010","Vendor":"MIR","Country":"Russia","Name":"MIR Credit","Description":"","Type":""},{"AID":"A0000006581011","Vendor":"MIR","Country":"Russia","Name":"MIR Credit","Description":"","Type":""},{"AID":"A0000006582010","Vendor":"MIR","Country":"Russia","Name":"MIR Debit","Description":"","Type":""},{"AID":"A0000006723010","Vendor":"TROY","Country":"Turkey","Name":"TROY chip credit card","Description":"Turkeys Payment Method","Type":"EMV"},{"AID":"A0000006723020","Vendor":"TROY","Country":"Turkey","Name":"TROY chip debit card","Description":"Turkeys Payment Method","Type":"EMV"},{"AID":"A0000007705850","Vendor":"Indian Oil Corporation Limited","Country":"India","Name":"XTRAPOWER Fleet Card Program","Description":"Indian Oils Pre Paid Program","Type":"EMV"},{"AID":"A0000007790000","Vendor":"Zimswitch","Country":"Zimbabwe","Name":"","Description":"","Type":""},{"AID":"B012345678","Vendor":"MasterCard International","Country":"United States","Name":"Maestro TEST","Description":"Used for development","Type":"EMV"},{"AID":"D040000001000002","Vendor":"Paylife","Country":"Austria","Name":"Paylife Quick (IEP). Preloaded Electronic Purse","Description":"Domestic Payment System (Version 2.1)","Type":""},{"AID":"D040000002000002","Vendor":"Austria Card","Country":"Austria","Name":"RFU","Description":"Domestic Payment System (Version 2.1)","Type":""},{"AID":"D040000003000002","Vendor":"Austria Card","Country":"Austria","Name":"POS","Description":"Domestic Payment System (Version 2.1)","Type":""},{"AID":"D040000004000002","Vendor":"Austria Card","Country":"Austria","Name":"ATM","Description":"Domestic Payment System (Version 2.1)","Type":""},{"AID":"D04000000B000002","Vendor":"Austria Card","Country":"Austria","Name":"Retail","Description":"Domestic Loyalty Program (Version 2.1)","Type":""},{"AID":"D04000000C000002","Vendor":"Austria Card","Country":"Austria","Name":"Bank_Data","Description":"Domestic Loyalty Program (Version 2.1)","Type":""},{"AID":"D04000000D000002","Vendor":"Austria Card","Country":"Austria","Name":"Shopping","Description":"Domestic Loyalty Program (Version 2.1)","Type":""},{"AID":"D040000013000001","Vendor":"Austria Card","Country":"Austria","Name":"DF_UNI_Kepler1","Description":"Domestic Loyalty Program (Version 2.0)","Type":""},{"AID":"D040000013000001","Vendor":"Austria Card","Country":"Austria","Name":"DF_Sch?ler1","Description":"Domestic Loyalty Program (Version 1.3)","Type":""},{"AID":"D040000013000002","Vendor":"Austria Card","Country":"Austria","Name":"DF_UNI_Kepler2","Description":"Domestic Loyalty Program (Version 2.0)","Type":""},{"AID":"D040000013000002","Vendor":"Austria Card","Country":"Austria","Name":"DF_Sch?ler2","Description":"Domestic Loyalty Program (Version 1.3)","Type":""},{"AID":"D040000014000001","Vendor":"Austria Card","Country":"Austria","Name":"DF_Mensa","Description":"Domestic Loyalty Program (Version 2.0)","Type":""},{"AID":"D040000015000001","Vendor":"Austria Card","Country":"Austria","Name":"DF_UNI_Ausweis","Description":"Domestic Loyalty Program (Version 2.0)","Type":""},{"AID":"D040000015000001","Vendor":"Austria Card","Country":"Austria","Name":"DF_Ausweis","Description":"Domestic Loyalty Program (Version 1.3)","Type":""},{"AID":"D0400000190001","Vendor":"Austria Card","Country":"Austria","Name":"EMV ATM Maestro","Description":"Domestic EMV Application (Version 2.1)","Type":""},{"AID":"D0400000190002","Vendor":"Austria Card","Country":"Austria","Name":"EMV POS Maestro","Description":"Domestic EMV Application (Version 2.1)","Type":""},{"AID":"D0400000190003","Vendor":"Austria Card","Country":"Austria","Name":"EMV ATM MasterCard","Description":"Domestic EMV Application (Version 2.1)","Type":""},{"AID":"D0400000190004","Vendor":"Austria Card","Country":"Austria","Name":"EMV POS MasterCard","Description":"Domestic EMV Application (Version 2.1)","Type":""},{"AID":"D0400000190010","Vendor":"Austria Card","Country":"Austria","Name":"Digital ID","Description":"Domestic Payment System (Version 2.1)","Type":""},{"AID":"D268000001","Vendor":"Ministry of Finance of Georgia","Country":"Georgia","Name":"Fiscal module application","Description":"Georgia Revenue Service application for fiscal cash registers","Type":""},{"AID":"D276000005","Vendor":"Giesecke&Devrient","Country":"Germany","Name":"","Description":"Giesecke & Devrient","Type":""},{"AID":"D276000005AA040360010410","Vendor":"Giesecke&Devrient","Country":"Germany","Name":"G D App Nokia 6212","Description":"","Type":""},{"AID":"D276000005AA0503E00401","Vendor":"Giesecke&Devrient","Country":"Germany","Name":"G D App Nokia 6212","Description":"","Type":""},{"AID":"D276000005AA0503E00501","Vendor":"Giesecke&Devrient","Country":"Germany","Name":"G D App Nokia 6212","Description":"","Type":""},{"AID":"D276000005AA0503E0050101","Vendor":"Giesecke&Devrient","Country":"Germany","Name":"G D App Nokia 6212","Description":"","Type":""},{"AID":"D276000005AB0503E0040101","Vendor":"Giesecke&Devrient","Country":"Germany","Name":"G D App Nokia 6212","Description":"","Type":""},{"AID":"D27600002200000001","Vendor":"IBM Laboratories","Country":"Germany","Name":"SCT LOYALTY","Description":"IBM Test card from the book Smart Card Application Development Using Java","Type":""},{"AID":"D27600002200000002","Vendor":"IBM Laboratories","Country":"Germany","Name":"BUSINESS CARD","Description":"IBM Test card from the book Smart Card Application Development Using Java","Type":""},{"AID":"D27600002200000060","Vendor":"IBM Laboratories","Country":"Germany","Name":"PKCS#11 Token","Description":"IBM Test card from the book Smart Card Application Development Using Java","Type":""},{"AID":"D276000025","Vendor":"ZKA","Country":"Germany","Name":"Girocard","Description":"Girocard (Geldkarte) in Germany","Type":""},{"AID":"D27600002545410100","Vendor":"ZKA","Country":"Germany","Name":"","Description":"Unknown","Type":""},{"AID":"D27600002545500100","Vendor":"ZKA","Country":"Germany","Name":"Girocard","Description":"ZKA Girocard (Geldkarte) (Germany)","Type":"EMV"},{"AID":"D27600002547410100","Vendor":"ZKA","Country":"Germany","Name":"Girocard ATM","Description":"","Type":""},{"AID":"D276000060","Vendor":"Wolfgang Rankl","Country":"Germany","Name":"","Description":"","Type":""},{"AID":"D2760000850100","Vendor":"NXP Semiconductors / NFC Forum","Country":"Germany","Name":"NDEF Tag Application / Mifare DESFire Tag Application","Description":"NFC Forum Type 4 Tag","Type":""},{"AID":"D2760000850101","Vendor":"NXP Semiconductors / NFC Forum","Country":"Germany","Name":"NDEF Tag Application","Description":"NFC Tag type 4 tag","Type":""},{"AID":"D276000118","Vendor":"Giesecke&Devrient Java Card Telecommunikation","Country":"Germany","Name":"","Description":"","Type":""},{"AID":"D2760001180101","Vendor":"Giesecke&Devrient Java Card Telecommunikation","Country":"Germany","Name":"Giesecke &","Description":"Devrient Test Applet?","Type":""},{"AID":"D27600012401","Vendor":"fsfEurope","Country":"Germany","Name":"OpenPGP Card","Description":"For selection when not knowing the exact full AID","Type":"OpenPGP"},{"AID":"D276000124010101FFFF000000010000","Vendor":"fsfEurope","Country":"Germany","Name":"OpenPGP Card","Description":"Version 1","Type":"OpenPGP"},{"AID":"D2760001240102000000000000010000","Vendor":"fsfEurope","Country":"Germany","Name":"OpenPGP Card","Description":"Version 2","Type":"OpenPGP"},{"AID":"D27600012402","Vendor":"fsfEurope","Country":"Germany","Name":"SmartChess","Description":"http://smartchess.de/englisch/SmartChess_1.0.pdf","Type":"SmartChess"},{"AID":"D2760001240200010000000000000000","Vendor":"fsfEurope","Country":"Germany","Name":"SmartChess","Description":"http://smartchess.de/englisch/SmartChess_1.0.pdf","Type":"SmartChess"},{"AID":"D4100000011010","Vendor":"","Country":"Republic of Korea","Name":"","Description":"","Type":""},{"AID":"D5280050218002","Vendor":"","Country":"The Netherlands","Name":"?","Description":"(Netherlands)","Type":"EMV"},{"AID":"D5780000021010","Vendor":"Bankaxept","Country":"Norway","Name":"Bankaxept","Description":"Norwegian domestic debit card","Type":"EMV"},{"AID":"D7560000010101","Vendor":"Swiss Travel Fund (Reka)","Country":"Switzerland","Name":"Reka Card","Description":"prepaid functional debit card","Type":""},{"AID":"D7560000300101","Vendor":"Migros (FCM, GE Money Bank and MasterCard)","Country":"Switzerland","Name":"M Budget","Description":"","Type":""},{"AID":"E80704007F00070302","Vendor":"","Country":"","Name":"nPA","Description":"German eID","Type":""},{"AID":"E82881C11702","Vendor":"","Country":"","Name":"AlphaCard application","Description":"","Type":""},{"AID":"E828BD080F","Vendor":"","Country":"","Name":"ISO-7816-15 EF.DIR","Description":"Iso adoption of PKCS-15","Type":""},{"AID":"F0000000030001","Vendor":"","Country":"","Name":"BRADESCO","Description":"Brazilian Bank Banco Bradesco","Type":"EMV"},{"AID":"7465736C6153746F7265303032","Vendor":"Tesla","Country":"","Name":"teslaStore002","Description":"Tesla car key","Type":"Tesla"},{"AID":"7465736C614C6F67696330303201","Vendor":"Tesla","Country":"","Name":"teslaLogic002","Description":"Tesla car key","Type":"Tesla"}] \ No newline at end of file +[ + { + "AID": "315041592E5359532E4444463031", + "Vendor": "Visa International", + "Country": "United States", + "Name": "Visa Payment System Environment - PSE (1PAY.SYS.DDF01)", + "Description": "", + "Type": "" + }, + { + "AID": "325041592E5359532E4444463031", + "Vendor": "Visa International", + "Country": "United States", + "Name": "Visa Proximity Payment System Environment - PPSE (2PAY.SYS.DDF01)", + "Description": "Visa payWave for Mobile", + "Type": "" + }, + { + "AID": "44464D46412E44466172653234313031", + "Vendor": "DeviceFidelity", + "Country": "United States", + "Name": "DeviceFidelity In2Pay DFare applet", + "Description": "http://www.nfcworld.com/2010/11/24/35207/devicefidelity-adds-nfc-support-for-android-and-mifare/", + "Type": "" + }, + { + "AID": "A00000000101", + "Vendor": "PBS Danmnt A/S", + "Country": "Denmark", + "Name": "MUSCLE Card Applet", + "Description": "(Unlicensed use of this RID. Proposal to use A000000323 instead)", + "Type": "" + }, + { + "AID": "A000000003000000", + "Vendor": "Visa International", + "Country": "United States", + "Name": "(VISA) Card Manager", + "Description": "Used by most GP2.1.1 cards / Oberthur OP201 cards. Visa Proprietary Card Manager AID for OpenPlatform cards (visa.openplatform).", + "Type": "GP" + }, + { + "AID": "A00000000300037561", + "Vendor": "Visa International", + "Country": "United States", + "Name": "Bonuscard", + "Description": "", + "Type": "" + }, + { + "AID": "A00000000305076010", + "Vendor": "Visa International", + "Country": "United States", + "Name": "VISA ELO Credit", + "Description": "", + "Type": "EMV" + }, + { + "AID": "A0000000031010", + "Vendor": "Visa International", + "Country": "United States", + "Name": "VISA Debit/Credit (Classic)", + "Description": "Standard/Gold VISA credit card", + "Type": "EMV" + }, + { + "AID": "A000000003101001", + "Vendor": "Visa International", + "Country": "United States", + "Name": "VISA Credit", + "Description": "", + "Type": "EMV" + }, + { + "AID": "A000000003101002", + "Vendor": "Visa International", + "Country": "United States", + "Name": "VISA Debit", + "Description": "", + "Type": "EMV" + }, + { + "AID": "A0000000032010", + "Vendor": "Visa International", + "Country": "United States", + "Name": "VISA Electron", + "Description": "VISA Electron (Debit)", + "Type": "EMV" + }, + { + "AID": "A0000000032020", + "Vendor": "Visa International", + "Country": "United States", + "Name": "VISA", + "Description": "V PAY", + "Type": "EMV" + }, + { + "AID": "A0000000033010", + "Vendor": "Visa International", + "Country": "United States", + "Name": "VISA Interlink", + "Description": "VISA Interlink", + "Type": "EMV" + }, + { + "AID": "A0000000034010", + "Vendor": "Visa International", + "Country": "United States", + "Name": "VISA Specific", + "Description": "Visa Specific", + "Type": "EMV" + }, + { + "AID": "A0000000035010", + "Vendor": "Visa International", + "Country": "United States", + "Name": "VISA Specific", + "Description": "Visa Specific", + "Type": "EMV" + }, + { + "AID": "A000000003534441", + "Vendor": "Visa International", + "Country": "United States", + "Name": "Schlumberger Security Domain", + "Description": "", + "Type": "GP" + }, + { + "AID": "A0000000035350", + "Vendor": "Visa International", + "Country": "United States", + "Name": "Security Domain", + "Description": "OCS Oberthur Card System Security Domain Package AID / VGP Card Manager (for ISD and ASD)", + "Type": "GP" + }, + { + "AID": "A000000003535041", + "Vendor": "Visa International", + "Country": "United States", + "Name": "Security Domain", + "Description": "OCS Oberthur Card System Security Domain Applet AID / VGP Card Manager (for ISD and ASD)", + "Type": "GP" + }, + { + "AID": "A0000000036010", + "Vendor": "Visa International", + "Country": "United States", + "Name": "Domestic Visa Cash Stored Value", + "Description": "", + "Type": "EMV" + }, + { + "AID": "A0000000036020", + "Vendor": "Visa International", + "Country": "United States", + "Name": "International Visa Cash Stored Value", + "Description": "", + "Type": "EMV" + }, + { + "AID": "A0000000038002", + "Vendor": "Visa International", + "Country": "United States", + "Name": "VISA Auth, VisaRemAuthen EMV-CAP (DPA)", + "Description": "VISA Auth dynamic passcode authentication (DPA). Used by Barclays/HBOS", + "Type": "EMV" + }, + { + "AID": "A0000000038010", + "Vendor": "Visa International", + "Country": "United States", + "Name": "VISA Plus", + "Description": "VISA plus", + "Type": "EMV" + }, + { + "AID": "A0000000039010", + "Vendor": "Visa International", + "Country": "United States", + "Name": "VISA Loyalty", + "Description": "", + "Type": "EMV" + }, + { + "AID": "A000000003999910", + "Vendor": "Visa International", + "Country": "United States", + "Name": "VISA Proprietary ATM", + "Description": "", + "Type": "EMV" + }, + { + "AID": "A0000000040000", + "Vendor": "Mastercard International", + "Country": "United States", + "Name": "MasterCard Card Manager", + "Description": "Security Domain", + "Type": "GP" + }, + { + "AID": "A00000000401", + "Vendor": "Mastercard International", + "Country": "United States", + "Name": "MasterCard PayPass", + "Description": "AEPM (Association Europenne Payez Mobile)", + "Type": "EMV" + }, + { + "AID": "A0000000041010", + "Vendor": "Mastercard International", + "Country": "United States", + "Name": "MasterCard Credit/Debit (Global)", + "Description": "Standard MasterCard", + "Type": "EMV" + }, + { + "AID": "A00000000410101213", + "Vendor": "Mastercard International", + "Country": "United States", + "Name": "MasterCard Credit", + "Description": "Standard MasterCard", + "Type": "EMV" + }, + { + "AID": "A00000000410101215", + "Vendor": "Mastercard International", + "Country": "United States", + "Name": "MasterCard Credit", + "Description": "Standard MasterCard", + "Type": "EMV" + }, + { + "AID": "A0000000041010BB5449435301", + "Vendor": "Mastercard International", + "Country": "United States", + "Name": "[UNKNOWN]", + "Description": "Some co-branded card", + "Type": "" + }, + { + "AID": "A0000000042010", + "Vendor": "Mastercard International", + "Country": "United States", + "Name": "MasterCard Specific", + "Description": "MasterCard Specific", + "Type": "EMV" + }, + { + "AID": "A0000000042203", + "Vendor": "Mastercard International", + "Country": "United States", + "Name": "MasterCard Specific", + "Description": "MasterCard U.S. Maestro", + "Type": "" + }, + { + "AID": "A0000000043010", + "Vendor": "Mastercard International", + "Country": "United States", + "Name": "MasterCard Specific", + "Description": "MasterCard Specific", + "Type": "EMV" + }, + { + "AID": "A0000000043060", + "Vendor": "Mastercard International", + "Country": "United States", + "Name": "Maestro (Debit)", + "Description": "Maestro (Debit) Card", + "Type": "EMV" + }, + { + "AID": "A000000004306001", + "Vendor": "Mastercard International", + "Country": "United States", + "Name": "Maestro (Debit)", + "Description": "Maestro (Debit) Card", + "Type": "EMV" + }, + { + "AID": "A0000000044010", + "Vendor": "Mastercard International", + "Country": "United States", + "Name": "MasterCard Specific", + "Description": "MasterCard Specific", + "Type": "EMV" + }, + { + "AID": "A0000000045010", + "Vendor": "Mastercard International", + "Country": "United States", + "Name": "MasterCard Specific", + "Description": "MasterCard Specific", + "Type": "EMV" + }, + { + "AID": "A0000000045555", + "Vendor": "Mastercard International", + "Country": "United States", + "Name": "APDULogger", + "Description": "AID on Cirrus Test Card", + "Type": "" + }, + { + "AID": "A0000000046000", + "Vendor": "Mastercard International", + "Country": "United States", + "Name": "Cirrus", + "Description": "Mastercard Cirrus (Interbank Network) ATM card only", + "Type": "EMV" + }, + { + "AID": "A0000000048002", + "Vendor": "Mastercard International", + "Country": "United States", + "Name": "SecureCode Auth EMV-CAP", + "Description": "Chip Authentication Protocol (CAP). Works with NatWest or SecureCode Aut", + "Type": "EMV" + }, + { + "AID": "A0000000049999", + "Vendor": "Mastercard International", + "Country": "United States", + "Name": "MasterCard PayPass", + "Description": "", + "Type": "EMV" + }, + { + "AID": "A0000000050001", + "Vendor": "Switch Card Services Ltd.", + "Country": "United Kingdom", + "Name": "Maestro UK", + "Description": "UK Domestic Maestro - Switch (debit card)", + "Type": "EMV" + }, + { + "AID": "A0000000050002", + "Vendor": "Switch Card Services Ltd.", + "Country": "United Kingdom", + "Name": "Solo", + "Description": "UK Domestic Maestro - Switch (debit card)", + "Type": "EMV" + }, + { + "AID": "A0000000090001FF44FF1289", + "Vendor": "ETSI", + "Country": "France", + "Name": "Orange", + "Description": "Orange UK", + "Type": "" + }, + { + "AID": "A0000000101030", + "Vendor": "Europay International", + "Country": "Belgium", + "Name": "Maestro-CH", + "Description": "", + "Type": "" + }, + { + "AID": "A00000001800", + "Vendor": "GEMPLUS", + "Country": "France", + "Name": "Gemplus ", + "Description": "", + "Type": "" + }, + { + "AID": "A0000000181001", + "Vendor": "GEMPLUS", + "Country": "France", + "Name": "com.gemplus.javacard.util packages", + "Description": "", + "Type": "" + }, + { + "AID": "A000000018434D", + "Vendor": "GEMPLUS", + "Country": "France", + "Name": "Gemplus card manager", + "Description": "434D = CM (ascii). Security domain for some GCX/GXP cards (GemXpresso Pro) (Gemalto)", + "Type": "GP" + }, + { + "AID": "A000000018434D00", + "Vendor": "GEMPLUS", + "Country": "France", + "Name": "Gemplus Security Domain", + "Description": "(Gemalto)", + "Type": "GP" + }, + { + "AID": "A00000002401", + "Vendor": "Midland Bank Plc", + "Country": "United Kingdom", + "Name": "Self Service", + "Description": "", + "Type": "EMV" + }, + { + "AID": "A000000025", + "Vendor": "American Express", + "Country": "United Kingdom", + "Name": "American Express", + "Description": "", + "Type": "EMV" + }, + { + "AID": "A0000000250000", + "Vendor": "American Express", + "Country": "United Kingdom", + "Name": "American Express", + "Description": "American Express (Credit/Debit)", + "Type": "EMV" + }, + { + "AID": "A00000002501", + "Vendor": "American Express", + "Country": "United Kingdom", + "Name": "American Express", + "Description": "AEIPS-compliant (A-E contact EMV) payment application", + "Type": "EMV" + }, + { + "AID": "A000000025010104", + "Vendor": "American Express", + "Country": "United Kingdom", + "Name": "American Express", + "Description": "", + "Type": "" + }, + { + "AID": "A000000025010402", + "Vendor": "American Express", + "Country": "United Kingdom", + "Name": "American Express", + "Description": "", + "Type": "EMV" + }, + { + "AID": "A000000025010701", + "Vendor": "American Express", + "Country": "United Kingdom", + "Name": "ExpressPay", + "Description": "", + "Type": "EMV" + }, + { + "AID": "A000000025010801", + "Vendor": "American Express", + "Country": "United Kingdom", + "Name": "American Express", + "Description": "", + "Type": "EMV" + }, + { + "AID": "A0000000291010", + "Vendor": "LINK Interchange Network Ltd", + "Country": "United Kingdom", + "Name": "Link / American Express", + "Description": "Link (UK) ATM Network, or AMEX (Portugal)", + "Type": "EMV" + }, + { + "AID": "A00000002945087510100000", + "Vendor": "LINK Interchange Network Ltd", + "Country": "United Kingdom", + "Name": "CO-OP", + "Description": "", + "Type": "" + }, + { + "AID": "A00000002949034010100001", + "Vendor": "LINK Interchange Network Ltd", + "Country": "United Kingdom", + "Name": "HSBC", + "Description": "", + "Type": "" + }, + { + "AID": "A00000002949282010100000", + "Vendor": "LINK Interchange Network Ltd", + "Country": "United Kingdom", + "Name": "Barclay", + "Description": "", + "Type": "" + }, + { + "AID": "A000000029564182", + "Vendor": "LINK Interchange Network Ltd", + "Country": "United Kingdom", + "Name": "HAFX", + "Description": "", + "Type": "" + }, + { + "AID": "A00000003029057000AD13100101FF", + "Vendor": "Schlumberger Industries Identif d'Encarteur PR050", + "Country": "France", + "Name": "BelPIC (Belgian Personal Identity Card) JavaCard Applet", + "Description": "Schlumberger (Gemalto) RID", + "Type": "" + }, + { + "AID": "A0000000308000000000280101", + "Vendor": "Schlumberger Industries Identif d'Encarteur PR050", + "Country": "France", + "Name": "Gemalto .NET Card AID", + "Description": "", + "Type": "" + }, + { + "AID": "A0000000421010", + "Vendor": "Groupement des Cartes Bancaires 'CB'", + "Country": "France", + "Name": "Cartes Bancaire EMV Card", + "Description": "Groupement des Cartes Bancaires (France)", + "Type": "EMV" + }, + { + "AID": "A0000000422010", + "Vendor": "Groupement des Cartes Bancaires 'CB'", + "Country": "France", + "Name": "", + "Description": "", + "Type": "EMV" + }, + { + "AID": "A0000000423010", + "Vendor": "Groupement des Cartes Bancaires 'CB'", + "Country": "France", + "Name": "", + "Description": "", + "Type": "EMV" + }, + { + "AID": "A0000000424010", + "Vendor": "Groupement des Cartes Bancaires 'CB'", + "Country": "France", + "Name": "", + "Description": "", + "Type": "EMV" + }, + { + "AID": "A0000000425010", + "Vendor": "Groupement des Cartes Bancaires 'CB'", + "Country": "France", + "Name": "", + "Description": "", + "Type": "EMV" + }, + { + "AID": "A0000000426010", + "Vendor": "Groupement des Cartes Bancaires 'CB'", + "Country": "France", + "Name": "Contactless payment using Apple Pay", + "Description": "", + "Type": "EMV" + }, + { + "AID": "A00000005945430100", + "Vendor": "Zentraler Kreditausschuss (ZKA)", + "Country": "Germany", + "Name": "Girocard Electronic Cash", + "Description": "", + "Type": "" + }, + { + "AID": "A000000063504B43532D3135", + "Vendor": "RSA Laboratories", + "Country": "United States", + "Name": "PKCS-15", + "Description": "RSA PKCS-15 PKI application (Predecessor to ISO7816-15) / ID-card in Finland", + "Type": "" + }, + { + "AID": "A0000000635741502D57494D", + "Vendor": "RSA Laboratories", + "Country": "United States", + "Name": "WAP-WIM", + "Description": "WAP (Wireless Application Protocol) Identity Module / Wireless Identification Module", + "Type": "" + }, + { + "AID": "A00000006510", + "Vendor": "JCB CO., LTD.", + "Country": "Japan", + "Name": "JCB", + "Description": "Japan Credit Bureau", + "Type": "EMV" + }, + { + "AID": "A0000000651010", + "Vendor": "JCB CO., LTD.", + "Country": "Japan", + "Name": "JCB J Smart Credit", + "Description": "Japan Credit Bureau", + "Type": "EMV" + }, + { + "AID": "A00000006900", + "Vendor": "Socit Europenne de Monnaie Electronique SEME", + "Country": "France", + "Name": "Moneo", + "Description": "", + "Type": "EMV" + }, + { + "AID": "A000000077010000021000000000003B", + "Vendor": "Oberthur Technologies", + "Country": "France", + "Name": "Visa AEPN", + "Description": "", + "Type": "EMV" + }, + { + "AID": "A0000000790100", + "Vendor": "Activcard Europe S.A.", + "Country": "France", + "Name": "CACv2 PKI ID", + "Description": "Identity Key", + "Type": "" + }, + { + "AID": "A0000000790101", + "Vendor": "Activcard Europe S.A.", + "Country": "France", + "Name": "CACv2 PKI Sign", + "Description": "Digital Signature Key", + "Type": "" + }, + { + "AID": "A0000000790102", + "Vendor": "Activcard Europe S.A.", + "Country": "France", + "Name": "CACv2 PKI Enc", + "Description": "Key Management Key", + "Type": "" + }, + { + "AID": "A00000007901F0", + "Vendor": "Activcard Europe S.A.", + "Country": "France", + "Name": "CACv1 PKI Identity Key", + "Description": "Re-directs to CACv2 PKI Identity key", + "Type": "" + }, + { + "AID": "A00000007901F1", + "Vendor": "Activcard Europe S.A.", + "Country": "France", + "Name": "CACv1 PKI Digital Signature Key", + "Description": "Re-directs to CACv2 Digital Signature key", + "Type": "" + }, + { + "AID": "A00000007901F2", + "Vendor": "Activcard Europe S.A.", + "Country": "France", + "Name": "CACv1 PKI Key Management Key", + "Description": "Re-directs to CACv2 Key Management key", + "Type": "" + }, + { + "AID": "A0000000790200", + "Vendor": "Activcard Europe S.A.", + "Country": "France", + "Name": "CACv2 DoD Person", + "Description": "DoD Demographic", + "Type": "" + }, + { + "AID": "A0000000790201", + "Vendor": "Activcard Europe S.A.", + "Country": "France", + "Name": "CACv2 DoD Personnel", + "Description": "DoD Demographic", + "Type": "" + }, + { + "AID": "A00000007902FB", + "Vendor": "Activcard Europe S.A.", + "Country": "France", + "Name": "CACv1 BC", + "Description": "General Configuration", + "Type": "" + }, + { + "AID": "A00000007902FD", + "Vendor": "Activcard Europe S.A.", + "Country": "France", + "Name": "CACv1 BC", + "Description": "PKI Certificate Attributes", + "Type": "" + }, + { + "AID": "A00000007902FE", + "Vendor": "Activcard Europe S.A.", + "Country": "France", + "Name": "CACv1 BC", + "Description": "PKI Cert", + "Type": "" + }, + { + "AID": "A0000000790300", + "Vendor": "Activcard Europe S.A.", + "Country": "France", + "Name": "CACv2 Access Control Applet", + "Description": "CAC PIN / ID PIN Management Applet", + "Type": "" + }, + { + "AID": "A0000000791201", + "Vendor": "Activcard Europe S.A.", + "Country": "France", + "Name": "CAC JDM", + "Description": "Joint Data Model. BCAdmin", + "Type": "" + }, + { + "AID": "A0000000791202", + "Vendor": "Activcard Europe S.A.", + "Country": "France", + "Name": "CAC JDM", + "Description": "Joint Data Model. BCMedical", + "Type": "" + }, + { + "AID": "A0000000871002FF49FF0589", + "Vendor": "Third Generation Partnership Project (3GPP)", + "Country": "France", + "Name": "Telenor USIM", + "Description": "", + "Type": "USIM" + }, + { + "AID": "A00000008810200105C100", + "Vendor": "Buypass AS", + "Country": "Norway", + "Name": "BuyPass BIDA", + "Description": "Used by norwegian public betting company Norsk-Tipping", + "Type": "BuyPass" + }, + { + "AID": "A000000088102201034221", + "Vendor": "Buypass AS", + "Country": "Norway", + "Name": "BuyPass BEID (BuyPass Electronic ID)", + "Description": "", + "Type": "BuyPass" + }, + { + "AID": "A000000088102201034321", + "Vendor": "Buypass AS", + "Country": "Norway", + "Name": "BuyPass BEID (BuyPass Electronic ID)", + "Description": "", + "Type": "BuyPass" + }, + { + "AID": "A0000000960200", + "Vendor": "Sa Proton World International N.V.", + "Country": "Belgium", + "Name": "Proton World International Security Domain", + "Description": "Proton, which is owned in part by Visa International and American Express Co., is in three other European countries: the original Proton program in Belgium, Chipknip in the Netherlands, and Cash in Switzerland", + "Type": "GP" + }, + { + "AID": "A000000098", + "Vendor": "Visa USA", + "Country": "United States", + "Name": "Debit Card", + "Description": "Bank of America Debit Card", + "Type": "EMV" + }, + { + "AID": "A0000000980840", + "Vendor": "Visa USA", + "Country": "United States", + "Name": "Visa Common Debit", + "Description": "", + "Type": "" + }, + { + "AID": "A0000000980848", + "Vendor": "Visa USA", + "Country": "United States", + "Name": "Debit Card", + "Description": "Schwab Bank Debit Card", + "Type": "EMV" + }, + { + "AID": "A0000001110101", + "Vendor": "Die Post Postfinance", + "Country": "Switzerland", + "Name": "Postcard", + "Description": "", + "Type": "" + }, + { + "AID": "A0000001160300", + "Vendor": "GSA - TFCS", + "Country": "United States", + "Name": "PIV CHUID", + "Description": "CHUID", + "Type": "" + }, + { + "AID": "A0000001166010", + "Vendor": "GSA - TFCS", + "Country": "United States", + "Name": "PIV Fingerprints", + "Description": "Fingerprints", + "Type": "" + }, + { + "AID": "A0000001166030", + "Vendor": "GSA - TFCS", + "Country": "United States", + "Name": "PIV Facial Image", + "Description": "Facial Image", + "Type": "" + }, + { + "AID": "A0000001169000", + "Vendor": "GSA - TFCS", + "Country": "United States", + "Name": "PIV Security Object", + "Description": "Security Object", + "Type": "" + }, + { + "AID": "A000000116A001", + "Vendor": "GSA - TFCS", + "Country": "United States", + "Name": "PIV Authentication Key", + "Description": "PIV Authentication Key", + "Type": "" + }, + { + "AID": "A000000116DB00", + "Vendor": "GSA - TFCS", + "Country": "United States", + "Name": "CCC", + "Description": "Card Capability Container", + "Type": "" + }, + { + "AID": "A000000118010000", + "Vendor": "Austria Card", + "Country": "Austria", + "Name": "DF_Verkehr", + "Description": "Domestic Loyalty Program (Version 1.3)", + "Type": "" + }, + { + "AID": "A000000118020000", + "Vendor": "Austria Card", + "Country": "Austria", + "Name": "DF_Partner", + "Description": "Domestic Loyalty Program (Version 1.3)", + "Type": "" + }, + { + "AID": "A000000118030000", + "Vendor": "Austria Card", + "Country": "Austria", + "Name": "DF_Schlerdaten", + "Description": "Domestic Loyalty Program (Version 1.3)", + "Type": "" + }, + { + "AID": "A000000118040000", + "Vendor": "Austria Card", + "Country": "Austria", + "Name": "DF_KEP_SIG", + "Description": "Domestic Loyalty Program (Version 1.32)", + "Type": "" + }, + { + "AID": "A0000001184543", + "Vendor": "Austria Card", + "Country": "Austria", + "Name": "Digital Signature (SSCA)", + "Description": "Digital Signature Application", + "Type": "" + }, + { + "AID": "A000000118454E", + "Vendor": "Austria Card", + "Country": "Austria", + "Name": "Encryption Application", + "Description": "Encryption Application (Version 1.10)", + "Type": "" + }, + { + "AID": "A0000001211010", + "Vendor": "PBS Danmark A/S", + "Country": "Denmark", + "Name": "Dankort (VISA GEM Vision)", + "Description": "Danish domestic debit card", + "Type": "EMV" + }, + { + "AID": "A0000001320001", + "Vendor": "Java Card Forum", + "Country": "United States", + "Name": "org.javacardforum.javacard.biometry", + "Description": "", + "Type": "" + }, + { + "AID": "A0000001408001", + "Vendor": "TDS TODOS DATA SYSTEM AB", + "Country": "Sweden", + "Name": "eCode", + "Description": "", + "Type": "" + }, + { + "AID": "A0000001410001", + "Vendor": "Associazione Bancaria Italiana", + "Country": "Italy", + "Name": "PagoBANCOMAT", + "Description": "CoGeBan Consorzio BANCOMAT (Italian domestic debit card)", + "Type": "EMV" + }, + { + "AID": "A0000001510000", + "Vendor": "GlobalPlatform, Inc.", + "Country": "United States", + "Name": "Global Platform Security Domain AID", + "Description": "GP Card Manager", + "Type": "GP" + }, + { + "AID": "A00000015153504341534400", + "Vendor": "GlobalPlatform, Inc.", + "Country": "United States", + "Name": "CASD_AID", + "Description": "SPCASD", + "Type": "GP" + }, + { + "AID": "A0000001523010", + "Vendor": "Diners Club International Ltd.", + "Country": "United States", + "Name": "Discover, Pulse D Pas", + "Description": "Discover Card", + "Type": "EMV" + }, + { + "AID": "A0000001524010", + "Vendor": "Diners Club International Ltd.", + "Country": "United States", + "Name": "Discover", + "Description": "Discover Debit Common Card", + "Type": "EMV" + }, + { + "AID": "A0000001544442", + "Vendor": "Banrisul - Banco do Estado do Rio Grande do SUL - S.A.", + "Country": "Brazil", + "Name": "Banricompras Debito", + "Description": "Banrisul (Brazil)", + "Type": "EMV" + }, + { + "AID": "A0000001570010", + "Vendor": "Zhlke Engineering AG", + "Country": "Switzerland", + "Name": "AMEX", + "Description": "", + "Type": "" + }, + { + "AID": "A0000001570020", + "Vendor": "Zhlke Engineering AG", + "Country": "Switzerland", + "Name": "MasterCard", + "Description": "", + "Type": "" + }, + { + "AID": "A0000001570021", + "Vendor": "Zhlke Engineering AG", + "Country": "Switzerland", + "Name": "Maestro", + "Description": "", + "Type": "" + }, + { + "AID": "A0000001570022", + "Vendor": "Zhlke Engineering AG", + "Country": "Switzerland", + "Name": "Maestro", + "Description": "", + "Type": "" + }, + { + "AID": "A0000001570023", + "Vendor": "Zhlke Engineering AG", + "Country": "Switzerland", + "Name": "CASH", + "Description": "", + "Type": "" + }, + { + "AID": "A0000001570030", + "Vendor": "Zhlke Engineering AG", + "Country": "Switzerland", + "Name": "VISA", + "Description": "", + "Type": "" + }, + { + "AID": "A0000001570031", + "Vendor": "Zhlke Engineering AG", + "Country": "Switzerland", + "Name": "VISA", + "Description": "", + "Type": "" + }, + { + "AID": "A0000001570040", + "Vendor": "Zhlke Engineering AG", + "Country": "Switzerland", + "Name": "JCB", + "Description": "", + "Type": "" + }, + { + "AID": "A0000001570050", + "Vendor": "Zhlke Engineering AG", + "Country": "Switzerland", + "Name": "Postcard", + "Description": "", + "Type": "" + }, + { + "AID": "A0000001570051", + "Vendor": "Zhlke Engineering AG", + "Country": "Switzerland", + "Name": "Postcard", + "Description": "", + "Type": "" + }, + { + "AID": "A0000001570100", + "Vendor": "Zhlke Engineering AG", + "Country": "Switzerland", + "Name": "MCard", + "Description": "", + "Type": "" + }, + { + "AID": "A0000001570104", + "Vendor": "Zhlke Engineering AG", + "Country": "Switzerland", + "Name": "MyOne", + "Description": "", + "Type": "" + }, + { + "AID": "A0000001570109", + "Vendor": "Zhlke Engineering AG", + "Country": "Switzerland", + "Name": "Mediamarkt Card", + "Description": "", + "Type": "" + }, + { + "AID": "A000000157010A", + "Vendor": "Zhlke Engineering AG", + "Country": "Switzerland", + "Name": "Gift Card", + "Description": "", + "Type": "" + }, + { + "AID": "A000000157010B", + "Vendor": "Zhlke Engineering AG", + "Country": "Switzerland", + "Name": "Bonuscard", + "Description": "", + "Type": "" + }, + { + "AID": "A000000157010C", + "Vendor": "Zhlke Engineering AG", + "Country": "Switzerland", + "Name": "WIRCard", + "Description": "", + "Type": "" + }, + { + "AID": "A000000157010D", + "Vendor": "Zhlke Engineering AG", + "Country": "Switzerland", + "Name": "Power Card", + "Description": "", + "Type": "" + }, + { + "AID": "A0000001574443", + "Vendor": "Zhlke Engineering AG", + "Country": "Switzerland", + "Name": "DINERS CLUB", + "Description": "", + "Type": "" + }, + { + "AID": "A0000001574444", + "Vendor": "Zhlke Engineering AG", + "Country": "Switzerland", + "Name": "Supercard Plus", + "Description": "", + "Type": "" + }, + { + "AID": "A000000167413000FF", + "Vendor": "IBM", + "Country": "Germany", + "Name": "JCOP Identify Applet", + "Description": "identify in JCOP-tools returns eg 27 34 01 2E 00 00 00 00 4E 58 37 35 31 41 00 03 28 62 B3 6A 82", + "Type": "JCOP" + }, + { + "AID": "A000000167413001", + "Vendor": "IBM", + "Country": "Germany", + "Name": "FIPS 140-2", + "Description": "", + "Type": "" + }, + { + "AID": "A000000172950001", + "Vendor": "Financial Information Service Co. Ltd.", + "Country": "Taiwan", + "Name": "BAROC Financial Application Taiwan", + "Description": "The Bankers Association of the Republic of China", + "Type": "EMV" + }, + { + "AID": "A000000177504B43532D3135", + "Vendor": "Ministre de L'Intrieur", + "Country": "Belgium", + "Name": "BelPIC (Belgian Personal Identity Card)", + "Description": "", + "Type": "" + }, + { + "AID": "A0000001850002", + "Vendor": "Post Office Limited", + "Country": "United Kingdom", + "Name": "UK Post Office Account card", + "Description": "", + "Type": "EMV" + }, + { + "AID": "A0000001884443", + "Vendor": "Diners Club Switzerland Ltd", + "Country": "Switzerland", + "Name": "DINERS CLUB", + "Description": "", + "Type": "" + }, + { + "AID": "A0000002040000", + "Vendor": "Association for Payment Clearing Services", + "Country": "United Kingdom", + "Name": "", + "Description": "", + "Type": "" + }, + { + "AID": "A0000002281010", + "Vendor": "Saudi Arabian Monetary Agency (SAMA)", + "Country": "Kingdom of Saudi Arabia", + "Name": "SPAN (M/Chip)", + "Description": "SPAN2 (Saudi Payments Network) - Saudi Arabia domestic credit/debit card (Saudi Arabia Monetary Agency)", + "Type": "EMV" + }, + { + "AID": "A0000002282010", + "Vendor": "Saudi Arabian Monetary Agency (SAMA)", + "Country": "Kingdom of Saudi Arabia", + "Name": "SPAN (VIS)", + "Description": "SPAN2 (Saudi Payments Network) - Saudi Arabia domestic credit/debit card (Saudi Arabia Monetary Agency)", + "Type": "EMV" + }, + { + "AID": "A00000022820101010", + "Vendor": "Saudi Arabian Monetary Agency (SAMA)", + "Country": "Kingdom of Saudi Arabia", + "Name": "SPAN", + "Description": "SPAN2 (Saudi Payments Network) - Saudi Arabia domestic credit/debit card (Saudi Arabia Monetary Agency)", + "Type": "" + }, + { + "AID": "A0000002471001", + "Vendor": "ISO JTC1/SC17/WG3", + "Country": "United Kingdom", + "Name": "Machine Readable Travel Documents (MRTD)", + "Description": "Electronic (Biometric) Passport. Issuer stored data application (The last three digits of the PIX shall be used to denote future version levels.)", + "Type": "MRTD" + }, + { + "AID": "A0000002472001", + "Vendor": "ISO JTC1/SC17/WG3", + "Country": "United Kingdom", + "Name": "Machine Readable Travel Documents (MRTD)", + "Description": "Electronic (Biometric) Passport. Application for hashes, digital signature, and certificate (The last three digits of the PIX shall be used to denote future version levels.)", + "Type": "MRTD" + }, + { + "AID": "A0000002771010", + "Vendor": "Interac Association", + "Country": "Canada", + "Name": "INTERAC", + "Description": "Canadian domestic credit/debit card", + "Type": "EMV" + }, + { + "AID": "A00000030600000000000000", + "Vendor": "PS/SC Workgroup", + "Country": "United States", + "Name": "PC/SC Initial access data AID", + "Description": "Possibly not an application...", + "Type": "" + }, + { + "AID": "A000000308000010000100", + "Vendor": "National Institute of Standards and Technology", + "Country": "United States", + "Name": "Personal Identity Verification (PIV) / ID-ONE PIV BIO", + "Description": "PIV End Point Applet. Last 2 bytes designate version", + "Type": "" + }, + { + "AID": "A00000031510100528", + "Vendor": "Currence Holding/PIN BV", + "Country": "The Netherlands", + "Name": "Currence PuC", + "Description": "", + "Type": "EMV" + }, + { + "AID": "A0000003156020", + "Vendor": "Currence Holding/PIN BV", + "Country": "The Netherlands", + "Name": "Chipknip", + "Description": "", + "Type": "EMV" + }, + { + "AID": "A00000032301", + "Vendor": "Identity Alliance", + "Country": "United States", + "Name": "MUSCLE Applet Package", + "Description": "http://osdir.com/ml/lib.muscle/2005-12/msg00066.html", + "Type": "" + }, + { + "AID": "A0000003230101", + "Vendor": "Identity Alliance", + "Country": "United States", + "Name": "MUSCLE Applet Instance", + "Description": "http://osdir.com/ml/lib.muscle/2005-12/msg00066.html", + "Type": "" + }, + { + "AID": "A0000003241010", + "Vendor": "Discover Financial Services LLC", + "Country": "United States", + "Name": "Discover Expresspay (ZIP)", + "Description": "", + "Type": "" + }, + { + "AID": "A000000333010101", + "Vendor": "China Unionpay Co. Ltd", + "Country": "China", + "Name": "UnionPay Debit", + "Description": "", + "Type": "" + }, + { + "AID": "A000000333010102", + "Vendor": "China Unionpay Co. Ltd", + "Country": "China", + "Name": "UnionPay Credit", + "Description": "", + "Type": "" + }, + { + "AID": "A000000333010103", + "Vendor": "China Unionpay Co. Ltd", + "Country": "China", + "Name": "UnionPay Quasi Credit", + "Description": "", + "Type": "" + }, + { + "AID": "A000000333010106", + "Vendor": "China Unionpay Co. Ltd", + "Country": "China", + "Name": "UnionPay Electronic Cash", + "Description": "", + "Type": "" + }, + { + "AID": "A000000333010108", + "Vendor": "China Unionpay Co. Ltd", + "Country": "China", + "Name": "U.S. UnionPay Common Debit AID", + "Description": "", + "Type": "" + }, + { + "AID": "A000000337301000", + "Vendor": "Groupment Interbancaire Montique de l' UEMOA", + "Country": "Senegal", + "Name": "Retrait", + "Description": "", + "Type": "" + }, + { + "AID": "A000000337101000", + "Vendor": "Groupment Interbancaire Montique de l' UEMOA", + "Country": "Senegal", + "Name": "Standard", + "Description": "", + "Type": "" + }, + { + "AID": "A000000337102000", + "Vendor": "Groupment Interbancaire Montique de l' UEMOA", + "Country": "Senegal", + "Name": "Classic", + "Description": "", + "Type": "" + }, + { + "AID": "A000000337101001", + "Vendor": "Groupment Interbancaire Montique de l' UEMOA", + "Country": "Senegal", + "Name": "Prepaye Online", + "Description": "", + "Type": "" + }, + { + "AID": "A000000337102001", + "Vendor": "Groupment Interbancaire Montique de l' UEMOA", + "Country": "Senegal", + "Name": "Prepaye Possibile Offiline", + "Description": "", + "Type": "" + }, + { + "AID": "A000000337601001", + "Vendor": "Groupment Interbancaire Montique de l' UEMOA", + "Country": "Senegal", + "Name": "Porte Monnaie Electronique", + "Description": "", + "Type": "" + }, + { + "AID": "A0000003591010", + "Vendor": "Euro Alliance of Payment Schemes s.c.r.l. - EAPS", + "Country": "Belgium", + "Name": "", + "Description": "Unknown", + "Type": "" + }, + { + "AID": "A0000003591010028001", + "Vendor": "Euro Alliance of Payment Schemes s.c.r.l. - EAPS", + "Country": "Belgium", + "Name": "Girocard EAPS", + "Description": "ZKA (Germany)", + "Type": "EMV" + }, + { + "AID": "A00000035910100380", + "Vendor": "Euro Alliance of Payment Schemes s.c.r.l. - EAPS", + "Country": "Belgium", + "Name": "", + "Description": "PagoBANCOMAT", + "Type": "" + }, + { + "AID": "A0000003660001", + "Vendor": "Poste Italiane S.P.A", + "Country": "Italy", + "Name": "Postamat", + "Description": "", + "Type": "" + }, + { + "AID": "A0000003660002", + "Vendor": "Poste Italiane S.P.A", + "Country": "Italy", + "Name": "Postamat VISA", + "Description": "", + "Type": "" + }, + { + "AID": "A0000003710001", + "Vendor": "Verve", + "Country": "Nigeria", + "Name": "InterSwitch Verve Card", + "Description": "Nigerian local switch company", + "Type": "EMV" + }, + { + "AID": "A00000038410", + "Vendor": "eftpos, Australian Payments Clearing Association Ltd", + "Country": "Australia", + "Name": "Savings (debit card)", + "Description": "", + "Type": "" + }, + { + "AID": "A00000038420", + "Vendor": "eftpos, Australian Payments Clearing Association Ltd", + "Country": "Australia", + "Name": "Cheque (debit card)", + "Description": "", + "Type": "" + }, + { + "AID": "A0000003964D66344D0002", + "Vendor": "NXP Semiconductors Germany GmbH", + "Country": "Germany", + "Name": "MIFARE4MOBILE", + "Description": "NXP Mf4M", + "Type": "" + }, + { + "AID": "A00000039742544659", + "Vendor": "Microsoft Corporation", + "Country": "United States", + "Name": "Microsoft IDMP AID", + "Description": "Identity Device With Microsoft Generic Profile application. 2 bytes can be added at the end. This byte must be set to the IDMP specification revision number which is currently 0x01. The second byte (yy) is reserved for use by the card application.", + "Type": "" + }, + { + "AID": "A0000003974349445F0100", + "Vendor": "Microsoft Corporation", + "Country": "United States", + "Name": "Microsoft PNP AID", + "Description": "MS Plug and Play", + "Type": "" + }, + { + "AID": "A0000004271010", + "Vendor": "Unibanco (Hipercard)", + "Country": "Brazil", + "Name": "Hiperchip", + "Description": "", + "Type": "" + }, + { + "AID": "A0000004320001", + "Vendor": "PRO100", + "Country": "Russia", + "Name": "Universal Electronic Card", + "Description": "", + "Type": "" + }, + { + "AID": "A0000004360100", + "Vendor": "Edenred", + "Country": "Belgium", + "Name": "Ticket Restaurant", + "Description": "", + "Type": "" + }, + { + "AID": "A0000004391010", + "Vendor": "ACCEL/Exchange", + "Country": "United States", + "Name": "Exchange ATM card", + "Description": "The Exchange Network ATM Network", + "Type": "" + }, + { + "AID": "A0000004540010", + "Vendor": "eTranzact", + "Country": "Nigeria", + "Name": "Etranzact Genesis Card", + "Description": "Nigerian local switch company", + "Type": "EMV" + }, + { + "AID": "A0000004540011", + "Vendor": "eTranzact", + "Country": "Nigeria", + "Name": "Etranzact Genesis Card 2", + "Description": "Nigerian local switch company", + "Type": "EMV" + }, + { + "AID": "A0000004762010", + "Vendor": "Google", + "Country": "United States", + "Name": "GOOGLE_CONTROLLER_AID", + "Description": "GOOGLE_LOCKET_AID", + "Type": "" + }, + { + "AID": "A0000004763030", + "Vendor": "Google", + "Country": "United States", + "Name": "GOOGLE_MIFARE_MANAGER_AID", + "Description": "", + "Type": "" + }, + { + "AID": "A0000004766C", + "Vendor": "Google", + "Country": "United States", + "Name": "GOOGLE_PAYMENT_AID", + "Description": "", + "Type": "EMV" + }, + { + "AID": "A000000476A010", + "Vendor": "Google", + "Country": "United States", + "Name": "GSD_MANAGER_AID", + "Description": "", + "Type": "GP" + }, + { + "AID": "A000000476A110", + "Vendor": "Google", + "Country": "United States", + "Name": "GSD_MANAGER_AID", + "Description": "", + "Type": "GP" + }, + { + "AID": "A000000485", + "Vendor": "JVL Ventures, LLC (Softcard)", + "Country": "United States", + "Name": "Softcard SmartTap", + "Description": "", + "Type": "" + }, + { + "AID": "A0000005241010", + "Vendor": "RuPay", + "Country": "India", + "Name": "RuPay", + "Description": "RuPay (India)", + "Type": "EMV" + }, + { + "AID": "A0000005271002", + "Vendor": "Yubico", + "Country": "Sweden", + "Name": "Yubikey NEO U2F Demo applet", + "Description": "Universal 2-Factor Proof-of-concept/Demo", + "Type": "YKNEO" + }, + { + "AID": "A000000527200101", + "Vendor": "Yubico", + "Country": "Sweden", + "Name": "Yubikey NEO Yubikey2 applet interface", + "Description": "Javacard Applet AID", + "Type": "YKNEO" + }, + { + "AID": "A000000527210101", + "Vendor": "Yubico", + "Country": "Sweden", + "Name": "Yubikey NEO OATH Applet", + "Description": "Javacard Applet AID", + "Type": "YKNEO" + }, + { + "AID": "A0000005591010FFFFFFFF8900000100", + "Vendor": "GSMA (GSM Association)", + "Country": "United Kingdom", + "Name": "ISD-R Application. Used as TAR.", + "Description": "", + "Type": "" + }, + { + "AID": "A0000005591010FFFFFFFF8900000200", + "Vendor": "GSMA (GSM Association)", + "Country": "United Kingdom", + "Name": "ECASD Application. Used as TAR.", + "Description": "", + "Type": "" + }, + { + "AID": "A0000005591010FFFFFFFF8900000D00", + "Vendor": "GSMA (GSM Association)", + "Country": "United Kingdom", + "Name": "ISD-P Executable Load File.", + "Description": "", + "Type": "" + }, + { + "AID": "A0000005591010FFFFFFFF8900000E00", + "Vendor": "GSMA (GSM Association)", + "Country": "United Kingdom", + "Name": "ISD-P Executable Module.", + "Description": "", + "Type": "" + }, + { + "AID": "A0000005591010FFFFFFFF8900000F00", + "Vendor": "GSMA (GSM Association)", + "Country": "United Kingdom", + "Name": "Reserved value for the Profile's ISD-P", + "Description": "", + "Type": "" + }, + { + "AID": "A0000005591010FFFFFFFF8900001000", + "Vendor": "GSMA (GSM Association)", + "Country": "United Kingdom", + "Name": "ISD-P Application ('1010FFFFFFFF89000010' to '1010FFFFFFFF8900FFFF'. Used as TAR. The value is allocated during the 'Profile Download and Installation procedure'", + "Description": "", + "Type": "" + }, + { + "AID": "A00000061700", + "Vendor": "Fidesmo", + "Country": "Sweden", + "Name": "Fidesmo javacard", + "Description": "", + "Type": "" + }, + { + "AID": "A0000006200620", + "Vendor": "Debit Network Alliance (DNA)", + "Country": "United States", + "Name": "Debit Network Alliance (DNA)", + "Description": "Common U.S. Debit", + "Type": "" + }, + { + "AID": "A0000006581010", + "Vendor": "MIR", + "Country": "Russia", + "Name": "MIR Credit", + "Description": "", + "Type": "" + }, + { + "AID": "A0000006581011", + "Vendor": "MIR", + "Country": "Russia", + "Name": "MIR Credit", + "Description": "", + "Type": "" + }, + { + "AID": "A0000006582010", + "Vendor": "MIR", + "Country": "Russia", + "Name": "MIR Debit", + "Description": "", + "Type": "" + }, + { + "AID": "A0000006723010", + "Vendor": "TROY", + "Country": "Turkey", + "Name": "TROY chip credit card", + "Description": "Turkey's Payment Method", + "Type": "EMV" + }, + { + "AID": "A0000006723020", + "Vendor": "TROY", + "Country": "Turkey", + "Name": "TROY chip debit card", + "Description": "Turkey's Payment Method", + "Type": "EMV" + }, + { + "AID": "A0000007705850", + "Vendor": "Indian Oil Corporation Limited", + "Country": "India", + "Name": "XTRAPOWER Fleet Card Program", + "Description": "Indian Oil's Pre Paid Program", + "Type": "EMV" + }, + { + "AID": "A0000007790000", + "Vendor": "Zimswitch", + "Country": "Zimbabwe", + "Name": "", + "Description": "", + "Type": "" + }, + { + "AID": "B012345678", + "Vendor": "MasterCard International", + "Country": "United States", + "Name": "Maestro TEST", + "Description": "Used for development", + "Type": "EMV" + }, + { + "AID": "D040000001000002", + "Vendor": "Paylife", + "Country": "Austria", + "Name": "Paylife Quick (IEP). Preloaded Electronic Purse", + "Description": "Domestic Payment System (Version 2.1)", + "Type": "" + }, + { + "AID": "D040000002000002", + "Vendor": "Austria Card", + "Country": "Austria", + "Name": "RFU", + "Description": "Domestic Payment System (Version 2.1)", + "Type": "" + }, + { + "AID": "D040000003000002", + "Vendor": "Austria Card", + "Country": "Austria", + "Name": "POS", + "Description": "Domestic Payment System (Version 2.1)", + "Type": "" + }, + { + "AID": "D040000004000002", + "Vendor": "Austria Card", + "Country": "Austria", + "Name": "ATM", + "Description": "Domestic Payment System (Version 2.1)", + "Type": "" + }, + { + "AID": "D04000000B000002", + "Vendor": "Austria Card", + "Country": "Austria", + "Name": "Retail", + "Description": "Domestic Loyalty Program (Version 2.1)", + "Type": "" + }, + { + "AID": "D04000000C000002", + "Vendor": "Austria Card", + "Country": "Austria", + "Name": "Bank_Data", + "Description": "Domestic Loyalty Program (Version 2.1)", + "Type": "" + }, + { + "AID": "D04000000D000002", + "Vendor": "Austria Card", + "Country": "Austria", + "Name": "Shopping", + "Description": "Domestic Loyalty Program (Version 2.1)", + "Type": "" + }, + { + "AID": "D040000013000001", + "Vendor": "Austria Card", + "Country": "Austria", + "Name": "DF_UNI_Kepler1", + "Description": "Domestic Loyalty Program (Version 2.0)", + "Type": "" + }, + { + "AID": "D040000013000001", + "Vendor": "Austria Card", + "Country": "Austria", + "Name": "DF_Schler1", + "Description": "Domestic Loyalty Program (Version 1.3)", + "Type": "" + }, + { + "AID": "D040000013000002", + "Vendor": "Austria Card", + "Country": "Austria", + "Name": "DF_UNI_Kepler2", + "Description": "Domestic Loyalty Program (Version 2.0)", + "Type": "" + }, + { + "AID": "D040000013000002", + "Vendor": "Austria Card", + "Country": "Austria", + "Name": "DF_Schler2", + "Description": "Domestic Loyalty Program (Version 1.3)", + "Type": "" + }, + { + "AID": "D040000014000001", + "Vendor": "Austria Card", + "Country": "Austria", + "Name": "DF_Mensa", + "Description": "Domestic Loyalty Program (Version 2.0)", + "Type": "" + }, + { + "AID": "D040000015000001", + "Vendor": "Austria Card", + "Country": "Austria", + "Name": "DF_UNI_Ausweis", + "Description": "Domestic Loyalty Program (Version 2.0)", + "Type": "" + }, + { + "AID": "D040000015000001", + "Vendor": "Austria Card", + "Country": "Austria", + "Name": "DF_Ausweis", + "Description": "Domestic Loyalty Program (Version 1.3)", + "Type": "" + }, + { + "AID": "D0400000190001", + "Vendor": "Austria Card", + "Country": "Austria", + "Name": "EMV ATM Maestro", + "Description": "Domestic EMV Application (Version 2.1)", + "Type": "" + }, + { + "AID": "D0400000190002", + "Vendor": "Austria Card", + "Country": "Austria", + "Name": "EMV POS Maestro", + "Description": "Domestic EMV Application (Version 2.1)", + "Type": "" + }, + { + "AID": "D0400000190003", + "Vendor": "Austria Card", + "Country": "Austria", + "Name": "EMV ATM MasterCard", + "Description": "Domestic EMV Application (Version 2.1)", + "Type": "" + }, + { + "AID": "D0400000190004", + "Vendor": "Austria Card", + "Country": "Austria", + "Name": "EMV POS MasterCard", + "Description": "Domestic EMV Application (Version 2.1)", + "Type": "" + }, + { + "AID": "D0400000190010", + "Vendor": "Austria Card", + "Country": "Austria", + "Name": "Digital ID", + "Description": "Domestic Payment System (Version 2.1)", + "Type": "" + }, + { + "AID": "D268000001", + "Vendor": "Ministry of Finance of Georgia", + "Country": "Georgia", + "Name": "Fiscal module application", + "Description": "Georgia Revenue Service application for fiscal cash registers", + "Type": "" + }, + { + "AID": "D276000005", + "Vendor": "Giesecke&Devrient", + "Country": "Germany", + "Name": "", + "Description": "Giesecke & Devrient", + "Type": "" + }, + { + "AID": "D276000005AA040360010410", + "Vendor": "Giesecke&Devrient", + "Country": "Germany", + "Name": "G D App Nokia 6212", + "Description": "", + "Type": "" + }, + { + "AID": "D276000005AA0503E00401", + "Vendor": "Giesecke&Devrient", + "Country": "Germany", + "Name": "G D App Nokia 6212", + "Description": "", + "Type": "" + }, + { + "AID": "D276000005AA0503E00501", + "Vendor": "Giesecke&Devrient", + "Country": "Germany", + "Name": "G D App Nokia 6212", + "Description": "", + "Type": "" + }, + { + "AID": "D276000005AA0503E0050101", + "Vendor": "Giesecke&Devrient", + "Country": "Germany", + "Name": "G D App Nokia 6212", + "Description": "", + "Type": "" + }, + { + "AID": "D276000005AB0503E0040101", + "Vendor": "Giesecke&Devrient", + "Country": "Germany", + "Name": "G D App Nokia 6212", + "Description": "", + "Type": "" + }, + { + "AID": "D27600002200000001", + "Vendor": "IBM Laboratories", + "Country": "Germany", + "Name": "SCT LOYALTY", + "Description": "IBM Test card from the book 'Smart Card Application Development Using Java'", + "Type": "" + }, + { + "AID": "D27600002200000002", + "Vendor": "IBM Laboratories", + "Country": "Germany", + "Name": "BUSINESS CARD", + "Description": "IBM Test card from the book 'Smart Card Application Development Using Java'", + "Type": "" + }, + { + "AID": "D27600002200000060", + "Vendor": "IBM Laboratories", + "Country": "Germany", + "Name": "PKCS#11 Token", + "Description": "IBM Test card from the book 'Smart Card Application Development Using Java'", + "Type": "" + }, + { + "AID": "D276000025", + "Vendor": "ZKA", + "Country": "Germany", + "Name": "Girocard", + "Description": "Girocard (Geldkarte) in Germany", + "Type": "" + }, + { + "AID": "D27600002545410100", + "Vendor": "ZKA", + "Country": "Germany", + "Name": "", + "Description": "Unknown", + "Type": "" + }, + { + "AID": "D27600002545500100", + "Vendor": "ZKA", + "Country": "Germany", + "Name": "Girocard", + "Description": "ZKA Girocard (Geldkarte) (Germany)", + "Type": "EMV" + }, + { + "AID": "D27600002547410100", + "Vendor": "ZKA", + "Country": "Germany", + "Name": "Girocard ATM", + "Description": "", + "Type": "" + }, + { + "AID": "D276000060", + "Vendor": "Wolfgang Rankl", + "Country": "Germany", + "Name": "", + "Description": "", + "Type": "" + }, + { + "AID": "D2760000850100", + "Vendor": "NXP Semiconductors / NFC Forum", + "Country": "Germany", + "Name": "NDEF Tag Application / Mifare DESFire Tag Application", + "Description": "NFC Forum Type 4 Tag", + "Type": "" + }, + { + "AID": "D2760000850101", + "Vendor": "NXP Semiconductors / NFC Forum", + "Country": "Germany", + "Name": "NDEF Tag Application", + "Description": "NFC Tag type 4 tag", + "Type": "" + }, + { + "AID": "D276000118", + "Vendor": "Giesecke&Devrient Java Card Telecommunikation", + "Country": "Germany", + "Name": "", + "Description": "", + "Type": "" + }, + { + "AID": "D2760001180101", + "Vendor": "Giesecke&Devrient Java Card Telecommunikation", + "Country": "Germany", + "Name": "Giesecke &", + "Description": "Devrient Test Applet", + "Type": "" + }, + { + "AID": "D27600012401", + "Vendor": "fsfEurope", + "Country": "Germany", + "Name": "OpenPGP Card", + "Description": "For selection when not knowing the exact full AID", + "Type": "OpenPGP" + }, + { + "AID": "D276000124010101FFFF000000010000", + "Vendor": "fsfEurope", + "Country": "Germany", + "Name": "OpenPGP Card", + "Description": "Version 1", + "Type": "OpenPGP" + }, + { + "AID": "D2760001240102000000000000010000", + "Vendor": "fsfEurope", + "Country": "Germany", + "Name": "OpenPGP Card", + "Description": "Version 2", + "Type": "OpenPGP" + }, + { + "AID": "D27600012402", + "Vendor": "fsfEurope", + "Country": "Germany", + "Name": "SmartChess", + "Description": "http://smartchess.de/englisch/SmartChess_1.0.pdf", + "Type": "SmartChess" + }, + { + "AID": "D2760001240200010000000000000000", + "Vendor": "fsfEurope", + "Country": "Germany", + "Name": "SmartChess", + "Description": "http://smartchess.de/englisch/SmartChess_1.0.pdf", + "Type": "SmartChess" + }, + { + "AID": "D4100000011010", + "Vendor": "", + "Country": "Republic of Korea", + "Name": "", + "Description": "", + "Type": "" + }, + { + "AID": "D5280050218002", + "Vendor": "", + "Country": "The Netherlands", + "Name": "", + "Description": "(Netherlands)", + "Type": "EMV" + }, + { + "AID": "D5780000021010", + "Vendor": "Bankaxept", + "Country": "Norway", + "Name": "Bankaxept", + "Description": "Norwegian domestic debit card", + "Type": "EMV" + }, + { + "AID": "D7560000010101", + "Vendor": "Swiss Travel Fund (Reka)", + "Country": "Switzerland", + "Name": "Reka Card", + "Description": "prepaid functional debit card", + "Type": "" + }, + { + "AID": "D7560000300101", + "Vendor": "Migros (FCM, GE Money Bank and MasterCard)", + "Country": "Switzerland", + "Name": "M Budget", + "Description": "", + "Type": "" + }, + { + "AID": "E80704007F00070302", + "Vendor": "", + "Country": "", + "Name": "nPA", + "Description": "German eID", + "Type": "" + }, + { + "AID": "E82881C11702", + "Vendor": "", + "Country": "", + "Name": "AlphaCard application", + "Description": "", + "Type": "" + }, + { + "AID": "E828BD080F", + "Vendor": "", + "Country": "", + "Name": "ISO-7816-15 EF.DIR", + "Description": "Iso adoption of PKCS-15", + "Type": "" + }, + { + "AID": "F0000000030001", + "Vendor": "", + "Country": "", + "Name": "BRADESCO", + "Description": "Brazilian Bank Banco Bradesco", + "Type": "EMV" + }, + { + "AID": "7465736C6153746F7265303032", + "Vendor": "Tesla", + "Country": "", + "Name": "teslaStore002", + "Description": "Tesla car key", + "Type": "Tesla" + }, + { + "AID": "7465736C614C6F67696330303201", + "Vendor": "Tesla", + "Country": "", + "Name": "teslaLogic002", + "Description": "Tesla car key", + "Type": "Tesla" + } +] \ No newline at end of file From d14644c09f46ff265ec096849d8c5a9ca0941b89 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 4 Nov 2019 19:54:23 +0200 Subject: [PATCH 1113/1854] add aidsearch sketch --- client/Makefile | 1 + client/aidsearch.c | 151 +++++++++++++++++++++++++++++++++++++++++++++ client/aidsearch.h | 26 ++++++++ 3 files changed, 178 insertions(+) create mode 100644 client/aidsearch.c create mode 100644 client/aidsearch.h diff --git a/client/Makefile b/client/Makefile index 1fef2cd9b..a6d987560 100644 --- a/client/Makefile +++ b/client/Makefile @@ -186,6 +186,7 @@ CMDSRCS = crapto1/crapto1.c \ cmdanalyse.c \ cmdhf.c \ cmdhflist.c \ + aidsearch.c \ cmdhf14a.c \ cmdhf14b.c \ cmdhf15.c \ diff --git a/client/aidsearch.c b/client/aidsearch.c new file mode 100644 index 000000000..48d275a17 --- /dev/null +++ b/client/aidsearch.c @@ -0,0 +1,151 @@ +//----------------------------------------------------------------------------- +// Copyright (C) 2019 merlokk +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// Proxmark3 RDV40 AID list library +//----------------------------------------------------------------------------- +#include "aidsearch.h" + +#include +#include + +#include "fileutils.h" +#include "pm3_cmd.h" + + +int openAIDFile(json_t *root) { + json_error_t error; + + char *path; + int res = searchFile(&path, RESOURCES_SUBDIR, "aidlist", ".json", false); + if (res != PM3_SUCCESS) { + return PM3_EFILE; + } + + int retval = PM3_SUCCESS; + root = json_load_file(path, 0, &error); + if (!root) { + PrintAndLogEx(ERR, "json (%s) error on line %d: %s", path, error.line, error.text); + retval = PM3_ESOFT; + goto out; + } + + if (!json_is_array(root)) { + PrintAndLogEx(ERR, "Invalid json (%s) format. root must be an array.", path); + retval = PM3_ESOFT; + goto out; + } + + PrintAndLogEx(SUCCESS, "Loaded file (%s) OK.", path); +out: + free(path); + return retval; +} + +int closeAIDFile(json_t *root) { + + json_decref(root); + return PM3_SUCCESS; +} + +json_t *AIDSearchInit(json_t *root) { + int res = openAIDFile(root); + if (res != PM3_SUCCESS) + return NULL; + + return AIDSearchGetElm(root, 0); +} + +json_t *AIDSearchGetElm(json_t *root, int elmindx) { + json_t *data = json_array_get(root, elmindx); + if (!json_is_object(data)) { + PrintAndLogEx(ERR, "data [%d] is not an object\n", elmindx); + return NULL; + } + return data; +} + +int AIDSearchFree(json_t *root) { + + return closeAIDFile(root); +} + +const char * jsonStrGet(json_t *data, char *name) { + json_t *jstr; + + jstr = json_object_get(data, name); + if (!json_is_string(jstr)) { + PrintAndLogEx(ERR, "`%s` is not a string", name); + return NULL; + } + + const char *cstr = json_string_value(jstr); + if (strlen(cstr) == 0) + return NULL; + return cstr; +} + +bool aidCompare(const char *aidlarge, const char *aidsmall) { + if (strcmp(aidlarge, aidsmall) == 0) + return true; + + if (strlen(aidlarge) > strlen(aidsmall)) + if (strncmp(aidlarge, aidsmall, strlen(aidsmall)) == 0) + return true; + + return false; +} + +int PrintAIDDescription(char *aid, bool verbose) { + json_t *root = NULL; + int retval = PM3_SUCCESS; + + int elmindx = 0; + json_t *data = AIDSearchInit(root); + if (data == NULL) + goto out; + + while (aidCompare(jsonStrGet(data, "AID"), aid)) { + elmindx++; + if (elmindx > json_array_size(root)) + goto out; + data = AIDSearchGetElm(root, elmindx); + + if (data == NULL) + goto out; + } + + // print here + const char *vaid = jsonStrGet(data, "AID"); + const char *vendor = jsonStrGet(data, "Vendor"); + const char *name = jsonStrGet(data, "Name"); + const char *country = jsonStrGet(data, "Country"); + const char *description = jsonStrGet(data, "Description"); + const char *type = jsonStrGet(data, "Type"); + + if (!verbose) { + PrintAndLogEx(SUCCESS, "AID %s | %s | %s", vaid, vendor, name); + } else { + if (aid) + PrintAndLogEx(SUCCESS, "AID: %s\n", vaid); + if (vendor) + PrintAndLogEx(SUCCESS, "Vendor: %s\n", vendor); + if (type) + PrintAndLogEx(SUCCESS, "Type: %s\n", type); + if (name) + PrintAndLogEx(SUCCESS, "Name: %s\n", name); + if (country) + PrintAndLogEx(SUCCESS, "Country: %s\n", country); + if (description) + PrintAndLogEx(SUCCESS, "Description: %s\n", description); + } + +out: + AIDSearchFree(root); + return retval; +} + + diff --git a/client/aidsearch.h b/client/aidsearch.h new file mode 100644 index 000000000..b07dea6e2 --- /dev/null +++ b/client/aidsearch.h @@ -0,0 +1,26 @@ +//----------------------------------------------------------------------------- +// Copyright (C) 2019 merlokk +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// Proxmark3 RDV40 AID list library +//----------------------------------------------------------------------------- + +#ifndef AIDSEARCH_H__ +#define AIDSEARCH_H__ + +#include "common.h" + +#include +#include + +#include + +int PrintAIDDescription(char *aid, bool verbose); +json_t *AIDSearchInit(json_t *root); +json_t *AIDSearchGetElm(json_t *root, int elmindx); +int AIDSearchFree(); + +#endif \ No newline at end of file From b07e33bcdb1aa19edfb63e77cf14e41541040d3e Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 4 Nov 2019 19:54:51 +0200 Subject: [PATCH 1114/1854] changed signature of `hf info` --- client/cmdhf.c | 2 +- client/cmdhf14a.c | 9 +++++++-- client/cmdhf14a.h | 2 +- client/cmdhffido.c | 2 +- client/cmdhfmfp.c | 2 +- 5 files changed, 11 insertions(+), 6 deletions(-) diff --git a/client/cmdhf.c b/client/cmdhf.c index 1960de2ee..dd21c2649 100644 --- a/client/cmdhf.c +++ b/client/cmdhf.c @@ -91,7 +91,7 @@ int CmdHFSearch(const char *Cmd) { PROMPT_CLEARLINE; PrintAndLogEx(INPLACE, "Searching for ISO14443-A tag..."); if (IfPm3Iso14443a()) { - if (infoHF14A(false, false) > 0) { + if (infoHF14A(false, false, false) > 0) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("ISO14443-A tag") " found\n"); return PM3_SUCCESS; } diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index 519a8b0f2..39167056a 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -26,6 +26,7 @@ #include "ui.h" #include "crc16.h" #include "util_posix.h" // msclock +#include "aidsearch.h" bool APDUInFramingEnable = true; @@ -372,7 +373,7 @@ static int CmdHF14AInfo(const char *Cmd) { bool verbose = !(Cmd[0] == 's' || Cmd[0] == 'S'); bool do_nack_test = (Cmd[0] == 'n' || Cmd[0] == 'N'); - infoHF14A(verbose, do_nack_test); + infoHF14A(verbose, do_nack_test, true); return 0; } @@ -1225,7 +1226,7 @@ int CmdHF14A(const char *Cmd) { return CmdsParse(CommandTable, Cmd); } -int infoHF14A(bool verbose, bool do_nack_test) { +int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { clearCommandBuffer(); SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0, NULL, 0); PacketResponseNG resp; @@ -1493,6 +1494,10 @@ int infoHF14A(bool verbose, bool do_nack_test) { } } } + + if (do_aid_search) { + PrintAIDDescription("315041592E5359532E4444463031", true); + } } else { PrintAndLogEx(INFO, "proprietary non iso14443-4 card found, RATS not supported"); } diff --git a/client/cmdhf14a.h b/client/cmdhf14a.h index 9c42b9afd..fcea5f5cf 100644 --- a/client/cmdhf14a.h +++ b/client/cmdhf14a.h @@ -26,7 +26,7 @@ int CmdHF14A(const char *Cmd); int CmdHF14ASniff(const char *Cmd); // used by hf topaz sniff int CmdHF14ASim(const char *Cmd); // used by hf mfu sim -int infoHF14A(bool verbose, bool do_nack_test); +int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search); const char *getTagInfo(uint8_t uid); int Hf14443_4aGetCardData(iso14a_card_select_t *card); int ExchangeAPDU14a(uint8_t *datain, int datainlen, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen); diff --git a/client/cmdhffido.c b/client/cmdhffido.c index 8930e237d..a0a8793c0 100644 --- a/client/cmdhffido.c +++ b/client/cmdhffido.c @@ -47,7 +47,7 @@ static int CmdHFFidoInfo(const char *cmd) { PrintAndLogEx(WARNING, "WARNING: command doesn't have any parameters.\n"); // info about 14a part - infoHF14A(false, false); + infoHF14A(false, false, false); // FIDO info PrintAndLogEx(NORMAL, "--------------------------------------------"); diff --git a/client/cmdhfmfp.c b/client/cmdhfmfp.c index 58eb5db1a..c6af6305a 100644 --- a/client/cmdhfmfp.c +++ b/client/cmdhfmfp.c @@ -36,7 +36,7 @@ static int CmdHFMFPInfo(const char *cmd) { PrintAndLogEx(WARNING, "command don't have any parameters.\n"); // info about 14a part - infoHF14A(false, false); + infoHF14A(false, false, false); // Mifare Plus info SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0, NULL, 0); From c861f68a87da40442d0f3b962eed4139e3a201fb Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 4 Nov 2019 20:14:43 +0200 Subject: [PATCH 1115/1854] fix aidlist --- client/resources/aidlist.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/resources/aidlist.json b/client/resources/aidlist.json index 3cb5c2e03..bfe8511be 100644 --- a/client/resources/aidlist.json +++ b/client/resources/aidlist.json @@ -1,17 +1,17 @@ [ { "AID": "315041592E5359532E4444463031", - "Vendor": "Visa International", + "Vendor": "EMV", "Country": "United States", - "Name": "Visa Payment System Environment - PSE (1PAY.SYS.DDF01)", + "Name": "EMV Payment System Environment - PSE (1PAY.SYS.DDF01)", "Description": "", "Type": "" }, { "AID": "325041592E5359532E4444463031", - "Vendor": "Visa International", + "Vendor": "EMV", "Country": "United States", - "Name": "Visa Proximity Payment System Environment - PPSE (2PAY.SYS.DDF01)", + "Name": "EMV Proximity Payment System Environment - PPSE (2PAY.SYS.DDF01)", "Description": "Visa payWave for Mobile", "Type": "" }, From 0b5cc59bcd8fa0d2f4ba590c82057706a320c023 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 4 Nov 2019 20:15:09 +0200 Subject: [PATCH 1116/1854] aidsearch works --- client/aidsearch.c | 34 +++++++++++++++++++--------------- client/aidsearch.h | 2 +- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/client/aidsearch.c b/client/aidsearch.c index 48d275a17..af17fb4d9 100644 --- a/client/aidsearch.c +++ b/client/aidsearch.c @@ -16,7 +16,7 @@ #include "pm3_cmd.h" -int openAIDFile(json_t *root) { +int openAIDFile(json_t **root) { json_error_t error; char *path; @@ -26,14 +26,14 @@ int openAIDFile(json_t *root) { } int retval = PM3_SUCCESS; - root = json_load_file(path, 0, &error); - if (!root) { + *root = json_load_file(path, 0, &error); + if (!*root) { PrintAndLogEx(ERR, "json (%s) error on line %d: %s", path, error.line, error.text); retval = PM3_ESOFT; goto out; } - if (!json_is_array(root)) { + if (!json_is_array(*root)) { PrintAndLogEx(ERR, "Invalid json (%s) format. root must be an array.", path); retval = PM3_ESOFT; goto out; @@ -51,12 +51,13 @@ int closeAIDFile(json_t *root) { return PM3_SUCCESS; } -json_t *AIDSearchInit(json_t *root) { - int res = openAIDFile(root); +json_t *AIDSearchInit() { + json_t *root = NULL; + int res = openAIDFile(&root); if (res != PM3_SUCCESS) return NULL; - return AIDSearchGetElm(root, 0); + return root; } json_t *AIDSearchGetElm(json_t *root, int elmindx) { @@ -77,6 +78,8 @@ const char * jsonStrGet(json_t *data, char *name) { json_t *jstr; jstr = json_object_get(data, name); + if (jstr == NULL) + return NULL; if (!json_is_string(jstr)) { PrintAndLogEx(ERR, "`%s` is not a string", name); return NULL; @@ -100,11 +103,11 @@ bool aidCompare(const char *aidlarge, const char *aidsmall) { } int PrintAIDDescription(char *aid, bool verbose) { - json_t *root = NULL; int retval = PM3_SUCCESS; int elmindx = 0; - json_t *data = AIDSearchInit(root); + json_t *root = AIDSearchInit(); + json_t *data = AIDSearchGetElm(root, elmindx); if (data == NULL) goto out; @@ -129,18 +132,19 @@ int PrintAIDDescription(char *aid, bool verbose) { if (!verbose) { PrintAndLogEx(SUCCESS, "AID %s | %s | %s", vaid, vendor, name); } else { + PrintAndLogEx(NORMAL, "----------------------------------------"); if (aid) - PrintAndLogEx(SUCCESS, "AID: %s\n", vaid); + PrintAndLogEx(SUCCESS, "Found AID: %s", vaid); if (vendor) - PrintAndLogEx(SUCCESS, "Vendor: %s\n", vendor); + PrintAndLogEx(SUCCESS, "Vendor: %s", vendor); if (type) - PrintAndLogEx(SUCCESS, "Type: %s\n", type); + PrintAndLogEx(SUCCESS, "Type: %s", type); if (name) - PrintAndLogEx(SUCCESS, "Name: %s\n", name); + PrintAndLogEx(SUCCESS, "Name: %s", name); if (country) - PrintAndLogEx(SUCCESS, "Country: %s\n", country); + PrintAndLogEx(SUCCESS, "Country: %s", country); if (description) - PrintAndLogEx(SUCCESS, "Description: %s\n", description); + PrintAndLogEx(SUCCESS, "Description: %s", description); } out: diff --git a/client/aidsearch.h b/client/aidsearch.h index b07dea6e2..c8ad8e1ad 100644 --- a/client/aidsearch.h +++ b/client/aidsearch.h @@ -19,7 +19,7 @@ #include int PrintAIDDescription(char *aid, bool verbose); -json_t *AIDSearchInit(json_t *root); +json_t *AIDSearchInit(); json_t *AIDSearchGetElm(json_t *root, int elmindx); int AIDSearchFree(); From 766262033ad6f5f3def88fa021a926812a9795d8 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 4 Nov 2019 20:20:42 +0200 Subject: [PATCH 1117/1854] some text improvements --- client/aidsearch.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/aidsearch.c b/client/aidsearch.c index af17fb4d9..d139eebea 100644 --- a/client/aidsearch.c +++ b/client/aidsearch.c @@ -39,7 +39,7 @@ int openAIDFile(json_t **root) { goto out; } - PrintAndLogEx(SUCCESS, "Loaded file (%s) OK.", path); + PrintAndLogEx(SUCCESS, "Loaded file (%s) OK. %d records.", path, json_array_size(*root)); out: free(path); return retval; @@ -133,6 +133,7 @@ int PrintAIDDescription(char *aid, bool verbose) { PrintAndLogEx(SUCCESS, "AID %s | %s | %s", vaid, vendor, name); } else { PrintAndLogEx(NORMAL, "----------------------------------------"); + PrintAndLogEx(SUCCESS, "Input AID: %s", aid); if (aid) PrintAndLogEx(SUCCESS, "Found AID: %s", vaid); if (vendor) From 2a4a9745c95ec70f494ff803236f241fbfc0956b Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 4 Nov 2019 21:18:37 +0200 Subject: [PATCH 1118/1854] aid search works --- client/aidsearch.c | 51 ++++++++++++++++++++++++++++++---------------- client/aidsearch.h | 2 ++ client/cmdhf14a.c | 34 ++++++++++++++++++++++++++++++- 3 files changed, 69 insertions(+), 18 deletions(-) diff --git a/client/aidsearch.c b/client/aidsearch.c index d139eebea..04aec92a5 100644 --- a/client/aidsearch.c +++ b/client/aidsearch.c @@ -102,37 +102,51 @@ bool aidCompare(const char *aidlarge, const char *aidsmall) { return false; } +bool AIDGetFromElm(json_t *data, uint8_t *aid, size_t aidmaxlen, int *aidlen) { + *aidlen = 0; + const char *hexaid = jsonStrGet(data, "AID"); + if (hexaid == NULL || strlen(hexaid) == 0) + return false; + + int res = param_gethex_to_eol(hexaid, 0, aid, aidmaxlen, aidlen); + if (res) + return false; + + return true; +} + int PrintAIDDescription(char *aid, bool verbose) { int retval = PM3_SUCCESS; - int elmindx = 0; json_t *root = AIDSearchInit(); - json_t *data = AIDSearchGetElm(root, elmindx); - if (data == NULL) + if (root == NULL) goto out; - while (aidCompare(jsonStrGet(data, "AID"), aid)) { - elmindx++; - if (elmindx > json_array_size(root)) - goto out; - data = AIDSearchGetElm(root, elmindx); - + json_t *elm = NULL; + for (int elmindx = 0; elmindx < json_array_size(root); elmindx++) { + json_t *data = AIDSearchGetElm(root, elmindx); if (data == NULL) - goto out; + continue; + if (aidCompare(jsonStrGet(data, "AID"), aid)) { + elm = data; + break; + } } + if (elm == NULL) + goto out; + // print here - const char *vaid = jsonStrGet(data, "AID"); - const char *vendor = jsonStrGet(data, "Vendor"); - const char *name = jsonStrGet(data, "Name"); - const char *country = jsonStrGet(data, "Country"); - const char *description = jsonStrGet(data, "Description"); - const char *type = jsonStrGet(data, "Type"); + const char *vaid = jsonStrGet(elm, "AID"); + const char *vendor = jsonStrGet(elm, "Vendor"); + const char *name = jsonStrGet(elm, "Name"); + const char *country = jsonStrGet(elm, "Country"); + const char *description = jsonStrGet(elm, "Description"); + const char *type = jsonStrGet(elm, "Type"); if (!verbose) { PrintAndLogEx(SUCCESS, "AID %s | %s | %s", vaid, vendor, name); } else { - PrintAndLogEx(NORMAL, "----------------------------------------"); PrintAndLogEx(SUCCESS, "Input AID: %s", aid); if (aid) PrintAndLogEx(SUCCESS, "Found AID: %s", vaid); @@ -153,4 +167,7 @@ out: return retval; } +int PrintAIDDescriptionBuf(uint8_t *aid, size_t aidlen, bool verbose) { + return PrintAIDDescription(sprint_hex_inrow(aid, aidlen), verbose); +} diff --git a/client/aidsearch.h b/client/aidsearch.h index c8ad8e1ad..4e6eaf8f9 100644 --- a/client/aidsearch.h +++ b/client/aidsearch.h @@ -19,8 +19,10 @@ #include int PrintAIDDescription(char *aid, bool verbose); +int PrintAIDDescriptionBuf(uint8_t *aid, size_t aidlen, bool verbose); json_t *AIDSearchInit(); json_t *AIDSearchGetElm(json_t *root, int elmindx); +bool AIDGetFromElm(json_t *data, uint8_t *aid, size_t aidmaxlen, int *aidlen); int AIDSearchFree(); #endif \ No newline at end of file diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index 39167056a..2d2b90178 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -1496,7 +1496,39 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { } if (do_aid_search) { - PrintAIDDescription("315041592E5359532E4444463031", true); + int elmindx = 0; + json_t *root = AIDSearchInit(); + if (root != NULL) { + bool ActivateField = true; + for (elmindx = 0; elmindx < json_array_size(root); elmindx++) { + json_t *data = AIDSearchGetElm(root, elmindx); + uint8_t vaid[200] = {0}; + int vaidlen = 0; + if (!AIDGetFromElm(data, vaid, sizeof(vaid), &vaidlen) || !vaidlen) + continue; + + uint16_t sw = 0; + uint8_t result[1024] = {0}; + size_t resultlen = 0; + int res = EMVSelect(ECC_CONTACTLESS, ActivateField, true, vaid, vaidlen, result, sizeof(result), &resultlen, &sw, NULL); + ActivateField = false; + if (res) + continue; + + if (sw == 0x9000) { + PrintAndLogEx(NORMAL, "------------- Application OK -----------"); + PrintAndLogEx(NORMAL, "res: %s", sprint_hex(result, resultlen)); + PrintAIDDescriptionBuf(vaid, vaidlen, true); + } + + if (sw == 0x6283 || sw == 0x6285) { + PrintAndLogEx(NORMAL, "----------- Application blocked --------"); + PrintAIDDescriptionBuf(vaid, vaidlen, true); + } + + } + DropField(); + } } } else { PrintAndLogEx(INFO, "proprietary non iso14443-4 card found, RATS not supported"); From a5a77199554f9fdd892b5fe5ab350dafc4b25c94 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 4 Nov 2019 21:11:41 +0100 Subject: [PATCH 1119/1854] windows instructions: rephrase to avoid confusion with installation commands --- .../Windows-Installation-Instructions.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/doc/md/Installation_Instructions/Windows-Installation-Instructions.md b/doc/md/Installation_Instructions/Windows-Installation-Instructions.md index d77a2dfae..9d94490f5 100644 --- a/doc/md/Installation_Instructions/Windows-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Windows-Installation-Instructions.md @@ -52,11 +52,7 @@ pacman -S mingw-w64-x86_64-astyle ## Compile and use the project -To use the compiled client, the only differences are that executables end with `.exe` (e.g. `proxmark3.exe`) and that the Proxmark3 port is one of your `comX` ports where "X" is the com port number assigned to proxmark3 under Windows, so commands become: - -```sh -proxmark3 /dev/ttyACM0 => proxmark3.exe comX -``` +To use the compiled client, the only differences are that executables end with `.exe` (e.g. `proxmark3.exe`) and that the Proxmark3 port is one of your `comX` ports where "X" is the com port number assigned to proxmark3 under Windows, so commands like `proxmark3 /dev/ttyACMX` become `proxmark3.exe comX`. Now you're ready to follow the [compilation instructions](/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md). From 6eb7c8e7a5195464e64febb9251a0f4013029c76 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 4 Nov 2019 23:21:02 +0200 Subject: [PATCH 1120/1854] fixed aid selection --- client/aidsearch.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/client/aidsearch.c b/client/aidsearch.c index 04aec92a5..54b970187 100644 --- a/client/aidsearch.c +++ b/client/aidsearch.c @@ -123,13 +123,17 @@ int PrintAIDDescription(char *aid, bool verbose) { goto out; json_t *elm = NULL; + int maxaidlen = 0; for (int elmindx = 0; elmindx < json_array_size(root); elmindx++) { json_t *data = AIDSearchGetElm(root, elmindx); if (data == NULL) continue; - if (aidCompare(jsonStrGet(data, "AID"), aid)) { - elm = data; - break; + const char *dictaid = jsonStrGet(data, "AID"); + if (aidCompare(aid, dictaid)) { // dictaid may be less length than requested aid + if (maxaidlen < strlen(dictaid) && strlen(dictaid) <= strlen(aid)) { + maxaidlen = strlen(dictaid); + elm = data; + } } } From 8befad6d34b0617838566b947754923a040024d3 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Tue, 5 Nov 2019 00:06:51 +0200 Subject: [PATCH 1121/1854] hf 14a info: added verbose, command optimization, move it to cliparser --- client/aidsearch.c | 21 ++++++++++++--------- client/aidsearch.h | 6 +++--- client/cmdhf14a.c | 43 +++++++++++++++++++++++++++---------------- 3 files changed, 42 insertions(+), 28 deletions(-) diff --git a/client/aidsearch.c b/client/aidsearch.c index 54b970187..a25a25547 100644 --- a/client/aidsearch.c +++ b/client/aidsearch.c @@ -16,7 +16,7 @@ #include "pm3_cmd.h" -int openAIDFile(json_t **root) { +int openAIDFile(json_t **root, bool verbose) { json_error_t error; char *path; @@ -39,7 +39,7 @@ int openAIDFile(json_t **root) { goto out; } - PrintAndLogEx(SUCCESS, "Loaded file (%s) OK. %d records.", path, json_array_size(*root)); + if (verbose) PrintAndLogEx(SUCCESS, "Loaded file (%s) OK. %d records.", path, json_array_size(*root)); out: free(path); return retval; @@ -51,9 +51,9 @@ int closeAIDFile(json_t *root) { return PM3_SUCCESS; } -json_t *AIDSearchInit() { +json_t *AIDSearchInit(bool verbose) { json_t *root = NULL; - int res = openAIDFile(&root); + int res = openAIDFile(&root, verbose); if (res != PM3_SUCCESS) return NULL; @@ -115,10 +115,12 @@ bool AIDGetFromElm(json_t *data, uint8_t *aid, size_t aidmaxlen, int *aidlen) { return true; } -int PrintAIDDescription(char *aid, bool verbose) { +int PrintAIDDescription(json_t *xroot, char *aid, bool verbose) { int retval = PM3_SUCCESS; - json_t *root = AIDSearchInit(); + json_t *root = xroot; + if (root == NULL) + root = AIDSearchInit(verbose); if (root == NULL) goto out; @@ -167,11 +169,12 @@ int PrintAIDDescription(char *aid, bool verbose) { } out: - AIDSearchFree(root); + if (xroot == NULL) + AIDSearchFree(root); return retval; } -int PrintAIDDescriptionBuf(uint8_t *aid, size_t aidlen, bool verbose) { - return PrintAIDDescription(sprint_hex_inrow(aid, aidlen), verbose); +int PrintAIDDescriptionBuf(json_t *root, uint8_t *aid, size_t aidlen, bool verbose) { + return PrintAIDDescription(root, sprint_hex_inrow(aid, aidlen), verbose); } diff --git a/client/aidsearch.h b/client/aidsearch.h index 4e6eaf8f9..88b79b8bc 100644 --- a/client/aidsearch.h +++ b/client/aidsearch.h @@ -18,9 +18,9 @@ #include -int PrintAIDDescription(char *aid, bool verbose); -int PrintAIDDescriptionBuf(uint8_t *aid, size_t aidlen, bool verbose); -json_t *AIDSearchInit(); +int PrintAIDDescription(json_t *root, char *aid, bool verbose); +int PrintAIDDescriptionBuf(json_t *root, uint8_t *aid, size_t aidlen, bool verbose); +json_t *AIDSearchInit(bool verbose); json_t *AIDSearchGetElm(json_t *root, int elmindx); bool AIDGetFromElm(json_t *data, uint8_t *aid, size_t aidmaxlen, int *aidlen); int AIDSearchFree(); diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index 2d2b90178..78e1c82f2 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -227,13 +227,6 @@ static int usage_hf_14a_reader(void) { PrintAndLogEx(NORMAL, " 3 ISO14443-3 select only (skip RATS)"); return 0; } -static int usage_hf_14a_info(void) { - PrintAndLogEx(NORMAL, "This command makes more extensive tests against a ISO14443a tag in order to collect information"); - PrintAndLogEx(NORMAL, "Usage: hf 14a info [h|s]"); - PrintAndLogEx(NORMAL, " s silent (no messages)"); - PrintAndLogEx(NORMAL, " n test for nack bug"); - return 0; -} static int CmdHF14AList(const char *Cmd) { (void)Cmd; // Cmd is not used so far @@ -368,12 +361,30 @@ static int CmdHF14AReader(const char *Cmd) { } static int CmdHF14AInfo(const char *Cmd) { + bool verbose = false; + bool do_nack_test = false; + bool do_aid_search = false; - if (Cmd[0] == 'h' || Cmd[0] == 'H') return usage_hf_14a_info(); + CLIParserInit("hf 14a info", + "This command makes more extensive tests against a ISO14443a tag in order to collect information", + "Sample:\n\thf 14a info -nsv - shows full information about the card\n"); - bool verbose = !(Cmd[0] == 's' || Cmd[0] == 'S'); - bool do_nack_test = (Cmd[0] == 'n' || Cmd[0] == 'N'); - infoHF14A(verbose, do_nack_test, true); + void *argtable[] = { + arg_param_begin, + arg_lit0("vV", "verbose", "adds some information to results"), + arg_lit0("nN", "naktest", "test for nack bug"), + arg_lit0("sS", "aidsearch", "checks if AIDs from aidlist.json is present on the card and prints information about found AIDs"), + arg_param_end + }; + CLIExecWithReturn(Cmd, argtable, true); + + verbose = arg_get_lit(1); + do_nack_test = arg_get_lit(2); + do_aid_search = arg_get_lit(3); + + CLIParserFree(); + + infoHF14A(verbose, do_nack_test, do_aid_search); return 0; } @@ -1497,7 +1508,7 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { if (do_aid_search) { int elmindx = 0; - json_t *root = AIDSearchInit(); + json_t *root = AIDSearchInit(verbose); if (root != NULL) { bool ActivateField = true; for (elmindx = 0; elmindx < json_array_size(root); elmindx++) { @@ -1516,14 +1527,14 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { continue; if (sw == 0x9000) { - PrintAndLogEx(NORMAL, "------------- Application OK -----------"); + if (verbose) PrintAndLogEx(NORMAL, "------------- Application OK -----------"); PrintAndLogEx(NORMAL, "res: %s", sprint_hex(result, resultlen)); - PrintAIDDescriptionBuf(vaid, vaidlen, true); + PrintAIDDescriptionBuf(root, vaid, vaidlen, verbose); } if (sw == 0x6283 || sw == 0x6285) { - PrintAndLogEx(NORMAL, "----------- Application blocked --------"); - PrintAIDDescriptionBuf(vaid, vaidlen, true); + if (verbose) PrintAndLogEx(NORMAL, "----------- Application blocked --------"); + PrintAIDDescriptionBuf(root, vaid, vaidlen, verbose); } } From 12cae27862c4c3b00a4a7264e53664e346407df5 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Tue, 5 Nov 2019 00:40:58 +0200 Subject: [PATCH 1122/1854] select result tlv decode and some diags print --- client/cmdhf14a.c | 42 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index 78e1c82f2..47a150030 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -1526,15 +1526,45 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { if (res) continue; - if (sw == 0x9000) { - if (verbose) PrintAndLogEx(NORMAL, "------------- Application OK -----------"); - PrintAndLogEx(NORMAL, "res: %s", sprint_hex(result, resultlen)); - PrintAIDDescriptionBuf(root, vaid, vaidlen, verbose); + uint8_t dfname[200] = {0}; + size_t dfnamelen = 0; + if (resultlen > 3) { + struct tlvdb *tlv = tlvdb_parse_multi(result, resultlen); + if (tlv) { + // 0x84 Dedicated File (DF) Name + const struct tlv *dfnametlv = tlvdb_get_tlv(tlvdb_find_full(tlv, 0x84)); + if (dfnametlv) { + dfnamelen = dfnametlv->len; + memcpy(dfname, dfnametlv->value, dfnamelen); + } + tlvdb_free(tlv); + } } - if (sw == 0x6283 || sw == 0x6285) { - if (verbose) PrintAndLogEx(NORMAL, "----------- Application blocked --------"); + if (sw == 0x9000 || sw == 0x6283 || sw == 0x6285) { + if (sw == 0x9000) { + if (verbose) PrintAndLogEx(NORMAL, "------------- Application OK -----------"); + } else { + if (verbose) PrintAndLogEx(NORMAL, "----------- Application blocked --------"); + } + PrintAIDDescriptionBuf(root, vaid, vaidlen, verbose); + + if (dfnamelen) { + if (dfnamelen == vaidlen) { + if (memcmp(dfname, vaid, vaidlen) == 0) { + if (verbose) PrintAndLogEx(INFO, "(DF) Name found and equal to AID"); + } else { + PrintAndLogEx(INFO, "(DF) Name not equal to AID: %s :", sprint_hex(dfname, dfnamelen)); + PrintAIDDescriptionBuf(root, dfname, dfnamelen, verbose); + } + } else { + PrintAndLogEx(INFO, "(DF) Name not equal to AID: %s :", sprint_hex(dfname, dfnamelen)); + PrintAIDDescriptionBuf(root, dfname, dfnamelen, verbose); + } + } else { + if (verbose) PrintAndLogEx(INFO, "(DF) Name not found"); + } } } From 485eccd670d3f3bc7741504d6e71d1c301e8015e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 5 Nov 2019 10:44:55 +0100 Subject: [PATCH 1123/1854] textual --- client/cmdhf14a.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index 47a150030..7ddf97b49 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -372,7 +372,7 @@ static int CmdHF14AInfo(const char *Cmd) { void *argtable[] = { arg_param_begin, arg_lit0("vV", "verbose", "adds some information to results"), - arg_lit0("nN", "naktest", "test for nack bug"), + arg_lit0("nN", "nacktest", "test for nack bug"), arg_lit0("sS", "aidsearch", "checks if AIDs from aidlist.json is present on the card and prints information about found AIDs"), arg_param_end }; @@ -382,8 +382,8 @@ static int CmdHF14AInfo(const char *Cmd) { do_nack_test = arg_get_lit(2); do_aid_search = arg_get_lit(3); - CLIParserFree(); - + CLIParserFree(); + infoHF14A(verbose, do_nack_test, do_aid_search); return 0; } From aabf3ecafad4ebcb37ce640ab6dad126b6e26cfb Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 5 Nov 2019 10:51:27 +0100 Subject: [PATCH 1124/1854] removed problematic code. Attribution to @jamchamb for his amii lua scripts --- client/libluamiibo.so | Bin 23648 -> 0 bytes client/lualibs/amiibolib.lua | 90 -------------- client/lualibs/emulator.lua | 84 ------------- client/luascripts/amiibo.lua | 235 ----------------------------------- 4 files changed, 409 deletions(-) delete mode 100644 client/libluamiibo.so delete mode 100644 client/lualibs/amiibolib.lua delete mode 100644 client/lualibs/emulator.lua delete mode 100644 client/luascripts/amiibo.lua diff --git a/client/libluamiibo.so b/client/libluamiibo.so deleted file mode 100644 index 2cd716aa08e79dba46e064f833fcfa2facce5fac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23648 zcmeHPeRx#WnLm>dKnx_sj|N1!Dj@g~622-5HA5J@V895(RjXbm$%F)xOm;pHthCV( zn=#Hl(Hb{xbvL!OwO!rPx+12E5tLBvN3>RvRhzcT&Ir|LMX7bo{@(YTbLY;@OlzP0 zXPU;aw?@oH+tWUv?4Lojr5I>g*&I4%=T{xmYke<=(8Rp6QOc_T}?_h*qG%p!k97JMQa zI#an9WRd?MOS!9%kM4UAu>%c%!{$E2=d9~pNF&5^S`s?^IR7BRaxX0XQ}_cXTh(@VplYa z{K;A516kzbS?Zt1_0JclO@#nLK6nb`v&mwjIQd*=?XNqP{LN=b=ysJdhRe+tp0g$J zdGHi0C4bxLlD|t5@pFa0JzWC7Q~150lQYa4cd)%vM6cISl9D{2@_A~eu_@SWg(Ln@#Il4{*U;P`td;9mTeX2uU}Hl# z5(uqdUEUaM4y^ZAHwI){<`k=Di=Q&^H#Xb^!Bv~BwJL}5Mt?XQ2#e;rn)$U>ZK!&q zg>oV&op6*~=Wl2fO@XGGmaW2E?Jc*;*Iy+?d{#Rm3S)(-`nKN0lVyuK`D`HU^plA!K1yZ;hb77CENo2CJt223bWZdP86< z1g(}(pv4~wSm8jRmMc%ScSD|6j`vU}7w`D?i4MN0_Q*F(M~8mX!Gha^xZ8l(OSG-aUXhQ@FN zG8-l04{d}I!H{V3H^L4At(IuGUJJqCfDKj$gVc?PCvRAw+`24K1J^_X5gsR87+Se5 z+FTPBjSbaoZ?HHVEG{iBDK24%xJAMWpx650%j$4gjzmDswIrdlhoHE;(zj;ax(bWb zOVhX#acRZMW#!hq;?f0nG!>gyyigAJ9A1yosx${HSo)JOok}SZmnm{BPw|u_CM1!E zcLUGg`IjT=d9IXe-80YIgk^i4ct~Le^SPprvPbZs#4oEf;_trm9>|Xs`xSO_L&HR> z-LDlNo!W2$)&6y*uitOzb)h~)M=aOZpCpaU-;K@|=-aOXO3 z$bmbT_(f#~Ytp-ndXzD5IB?~9#%DY55=P`#i37jLfnVsr>77W2G6zoYLpqoaoP41} zr30tB>Ts0<*KJQ}8yq+~kR9qB_yijjqQ!xq=)ku)@O%f}>cG)q?a<-CC)ubFT@HMS z1MhL*&UJ6E1E+UR9UgSx`hAkpb~tc)kJVw919vVB`yIIIvaGV-fuEu?0UdPU^lqcW z0S8X+xjGCv@C!5unsDH1h;r(%16NBo#*aC0wbYZjc@3u27p8JdevS7U93fmS^_Va8 z8cYfQBFE%ck=Nh|;q;EKgW)weO87L6$*Hcn za`;mKGtVNPri$bc^HYhZDIz(@{AA)M6W`DL1mbDRPwrqohj^MIlD*7-d>(ij>d7wV z-zT1ic(RrGw~42rnrvbI_r%i>O>SWRAn`Obladd%b0(Tcp8ey66W_1PeUqc zFyBW!4W(ou^FJY;hEP&4|3l(w=p={#o9w@zc!T&M=D$fi4VB~|^LG(XT|U{*{O!b3 zS5NL>{#N3tD<^xIzlnJ2!pSb?L&Q_pO|~+>iFoR=$rk3TiKiiw+`#-b#M9F~S;_ob z;?E_%jQLf>(-fO5VSX9$^e9Xk%wI(O1;iIJKacog;sx{P5%ed&_J)Hfi%I7*@rQp<#8xbt6M{1=E)caot`TMRmmm)3+l_ z47K>uSI;H=g)f3Y|5MU``qNx9Hf%nfxWx4AGhg^LQiRNsvt?%aGBc^~&aZW84Ec!Y zIcD3^r=Wl=V{b+B&CaEpfG2#gAYtO`x_x;Y0C@g1x<1}nD5vcb5j`<^JtSqlQU2Ac z{3K;LGI$-2FN$LhDKTT)V0m=dj8!Gf*y^E*nD2nuw(XdRPB-HdXQBW1Q6Gbyn=m$D z^#dS@N$@D7hNYAsDe8HUS}vtJNhOqp)O;V_D!A`bqdw=9?VrBV{ zQziQ7Yd3wFsLmQx=kSRnBAwx3<;U0=bx$Y8OA|V}*m}xWCTVykIVAw z1hX^c!gz}LJWM>)56dq2`v#?Vs+5+|VohwII@Cn=ZdH!d{eRfDFKFk>&1#M9h3-IQ*| zR}Y$TL%RP? zDfL^D@=2-vQfeGYohhYmkW$Z))O0D;FQtA5sE-~LXiA@ydW59@{1G|ahx+-3K`|a% z3WlaM-mUuYOYIF55^|J(Bdw0-iH~iei@)$hGEa*^z0*R;wITk9WY_WL+67I zoAH~@Ul~J(dAhFyHBY?s0b4$7c9LiUO$ebOos?X{wx~Fqln>cl4&RsOY1GzY=-T z7BLra5qbZCL}wv8qy#MLQWn8QP?t>|H`hzG*GP>PXe#5aP|Iv1a-yL~o_1tI2na=g2Rl;d$ZNpNp|n7f@y zH!CsL`SBKSmomJjiLne9sg>jHoRu6Ai>Zuw`ykhBATbqeBJe)db`M~gUyGq6^wQ@A zo}6hKIVh`07U`}nGjsOq-=qn#zm*VLMR$xL6q-2vo-SEh`&UZd;LOyVqiWdqTWS_* z+VyD?>QnO*}=F2 zx$Hk3_9yCxKXVhjPX1B_s(Ed6;~#K1Rk|u3r{1QX{anvCQD)-ZcXh#kv)9!+3r@9t zXR7V1vz2OakKv7!04!7XZgQ=9B zMlbYH-`m~GrVk``QVr09Poly|zY2v&rHeJRjEsUZEyk7<-iTLDjt7?%Zl0WIM+O68 zJ+hNpdEB?{-aE|YJb58rH!OvXDr&#g0X|}MMdnD#H-N2j$R@4l!UXV6jD7quRE5px1bZC zsRw-2G~)1;&>e0YDxl4b2~Qb-64jKg>@dT;wiQ@{!~5~2GsmcAPW7xW-D^GjmiHE#&i_Hn6@m&93~ekW2R>_=4B+<#uzY$Dw*KXWmoIPx7n>UpQZJrJ&*bG%k5V8)ZG>j!sSy4WJ zxwU-lvP-Si-m9#2KHqX{-O6ixA{dR}Kj`U-tS!`;fz&|`#}NuXjp5++f9aK`B>xM0 z_qCggy*!}i|H{!o8*oEH8S!N=pE=mpMdT`N0^4`;1I^- z63}xn$6X6LACvISpdaEHaWCjyct}41Is@yS*FZZ!KLMSL72q_Ct`9+%fWCso@U@^5 z@q%i?L6mAEljeiQB zo7M`?mO{^I`QyfSQ9XdsrhM0-k&!~kiAjYkCKatJIPu2ut>TiY7oR(S##umFW;tjF z2Erof3GbxB+j7b$j?FFgAS+I<1^h4Y2cNyN)2G|%+mU`h{Nx3-^=~F^ng4e|_adFo zw%PjQZ2f1D{v-I8&v4o4yY2Khk-irGz8BQaKj)vh0J3om>itWk-<6ggx6`TK^enGU zOSkOwPT|NVCUboOr?`qM~S`p29;1K13tA3}PEGu_vg zoAVVGA(ZP;0l5{&virFa>3fj=3uit#`|Wz%f%G8yaklh_kUkClyDCk;($@bu(yu_e z*O{*R5kbepaSt5#z;O>8_rP%v9QVL+4;=TvaSt5#z;O>8_rU)@59r?k=yU(tLVey} zpYPY_`StmIeO_Om&)0gI;#HahpCCm{^IxVt5(GL)++kK}ibw zcMPXV*8V-fRK@GxGtm1!1=<^-aP-rWAkkq}5jwa^p+^bO!Bq-7@NP_jcCslXRsBws ztSC}c!PxLH7*T4Xb&M3y`$cpBmV!RB-LDMSc#ASr*RxX9?*yr4mxr?;Tz~vjkpp%i znAhcE+l2XBl_Rk|z`V{!W%qxE=-7(H^fs?iZJq zmtSPeuBwhUN212U;swPe7c7c0SNfIGMa3lxiWkq3xG}G!bWzEolEtj|*S>Nw3+&eu zfkTjfOQpx91I90&a_#Y$j*qd&Z91MObpKDsF}n4H;z-EFO$2)UIbf7JUg&X}j-O!9 zPwDssu|f5_bo@loqWqeU<9DqY@zK9SCcRwDmd3fx9ArFK6xjDdI8$@+tL7ba5XTjA zaSMZOtO>7&9cS@6S*=L`4! z0!J0@{vCcE79R9FeD{3^(|{YJN)_U~EchiVpXZg5z87E}S8RqE+GU`#A2)lFx1>@4i1`AdCFLEch|tg_z%Zy+)c5WAGx9sl84Ho~i$o zFrF`pX3A{%f0c+{s&M!H9sdA4Q~m*#Ppb+uw`9S)v*0_j;Lidld)@bsJeNiO4aQ;D z8M02bs%q~m+*RcHP`PQE$|F$goe?5!*PqN@6Jg;V0 zPu7GY;Ruda;5>(Attww@RjgdM9v6|MZXdBCO}ME8_m9wZ9JN7fV`H$|-)PlFf}ybG zk8Tk)!KRkRKqOFG{Dp;!7i1RVdrd5VDCFOYs}&-lt+>X*-xRQFqfJd)q2l29+L1I- zb;8E7D%bkfufN(_QMIOg{mRSNSXS{D=FcmEdd7r>*%B5D`wUBF)rF-(-YNmFL?aE2 zAo?24SHua4vPGRtQw z0dx6UVO?5r`7&>Xb@_@F>wN32_156tqb*LYX2ELWFn zl$Gf#DCo8c+~k6*FVZphEhg^6L(0O`Eh+A+X|moYqcoKt((aT=uY$bYM%@aMo$sH8*oWjE@Wlsg-o^0J)Qilkl5;=Tdq zuie{&j7D8p;<^omE;>oCo%2}KXTJF-Jqz2wOips#+>&OPy7(pyXNFI zow#vF6ovAfqs7(HhQ`_p8fpb|_5N_ZD6ZYw3{6RKFA}G0 z4uryVk&=_KkQNFw`bj~>S{fswn1+-nMznZi5Rph=3%+pyR|ABCe5X)xpk6)O>T8jS z=A^28$Vm+y-&6xJQl$cs3s(*kYz-7455h1K7Q(7prh5##lO zgWfmObcVt;!SXUK(EbFDvIVui-e1$SUrA$m&Oz@#E0*utq&;t~ulL0@O<-L{fyyNr zt*`gT%YaedT3_$8YpVCvA;JO6p|oIvqdjh|ulMyd{fd&-_1AKm(tAJcnQPwO|5N*b zElS^Ae+7$LM06TqdY@2Jy-%;pciZ2r^p}w`g5FQml-@%qkUsryz^%Up82JRtM-F9b zgGN)m|Duw)t~yRMjE_@a?@wyVXH^{vdd;jU`PZqh_c1lqaykoLf6af*rLXtZG`&l2 zI4K2pesPz+{y&hW?*D5jck1HB*Ok6*f4zUIDgBVq8QkT6%cbwWhxZAmGUD#?f8f&B z`>~oH(G^qqxc&DCaQat~?q7P}R^QL-mUr_{LASu6ulIMmmI6d@%e(pKAww?G@ zp3kU1=+f8w#l1?u4C&5bI2puW$A|j9E?@5}+xIW4_S1gX_1EoqD|DUp*Za@?mmmRQ zwj}nq*4Ok9Qk?qsK3$nq=~3nD478r6@4EE$zFm)3YG^sPzUGf2LNeO^UatWT`=Uy} zpSjeRk&1HcV|-H;OI*0t$3r?TXmd2htrT|IPQlmLNiJ6lszevdWxKjKOCIn_g);RI h)ziUVjF0w*etyvS*0xIx`CYVH(r5L=s1n`f{|~k-bZh_s diff --git a/client/lualibs/amiibolib.lua b/client/lualibs/amiibolib.lua deleted file mode 100644 index c5cccb81c..000000000 --- a/client/lualibs/amiibolib.lua +++ /dev/null @@ -1,90 +0,0 @@ -local luamiibo_open, err = package.loadlib("./libluamiibo.so", "luaopen_luamiibo") - -if err then - print(err) - return -end - -local luamiibo = luamiibo_open() - -local FLAG_SETTINGS_INITIALIZED = 4 -local FLAG_APPDATA_INITIALIZED = 3 - -local Amiibo = {} -Amiibo.__index = Amiibo - -function Amiibo:new (o) - o = o or {} - setmetatable(o, self) - - if o.tag ~= nil then - o:load_tag(o.tag) - end - return o -end - -function Amiibo:load_tag (tag) - self.plain = luamiibo.unpack(tag) - - -- UID - local raw_uid = string.sub(self.plain, 469, 469 + 8) - self.uid = string.sub(raw_uid, 1, 3) .. string.sub(raw_uid, 5, 8) - - -- Settings - local count, flags = bin.unpack('C', string.sub(self.plain, 45, 45)) - self.setting_flags = flags - self.settings_initialized = self:check_flag(FLAG_SETTINGS_INITIALIZED) - self.appdata_initialized = self:check_flag(FLAG_APPDATA_INITIALIZED) - - local _, appdatacounter = bin.unpack('>S', string.sub(self.plain, 49, 50)) - self.appdata_counter = appdatacounter - - self.figure_id = string.sub(self.plain, 477, 477 + 8) - - -- UTF-16 nickname string - self.nickname = string.sub(self.plain, 57, 76) -end - - -function Amiibo:export_tag () - return luamiibo.pack(self.plain) -end - - -function Amiibo:check_flag (power) - local flag = math.pow(2, power) - return flag == bit32.band(self.setting_flags, flag) -end - - -function Amiibo:get_pwd () - local xorkey = "\xaa\x55\xaa\x55" - - local result = '' - for i = 1, 4 do - result = result .. - bin.pack('C', - bit32.bxor(self.uid:byte(i+1), - self.uid:byte(i+3), - xorkey:byte(i))) - end - - return result -end - --- Hack to make UTF-16 nicknames into regular char string --- Only works for ASCII nicknames -function Amiibo:display_nickname() - local nickname_tmp = self.nickname - - local nickname = '' - for i = 1, nickname_tmp:len() do - if i % 2 == 0 then - nickname = nickname .. nickname_tmp:sub(i, i) - end - end - - return nickname -end - -return Amiibo diff --git a/client/lualibs/emulator.lua b/client/lualibs/emulator.lua deleted file mode 100644 index d43f5da92..000000000 --- a/client/lualibs/emulator.lua +++ /dev/null @@ -1,84 +0,0 @@ -local cmds = require('commands') -local utils = require('utils') -local reader = require('read14a') - -local Emulator = { - _VERSION = 'emulator.lua 0.1.0', - _DESCRIPTION = 'emulator memory interface', - BLOCK_SZ = 512, - BLOCK_COUNT = 512 / 16 -} - -function Emulator:set_mem (data, clear_first) - if clear_first then - -- Clear out the emulator memory first - local memclrCmd = Command:newMIX{cmd = cmds.CMD_HF_MIFARE_EML_MEMCLR} - - local _, err = memclrCmd:sendMIX() - if err then - print('Failed to clear emulator memory:', err) - return false - else - print('Cleared emulator memory') - end - end - - -- Can fit 32 16 byte blocks per command (512 total bytes max) - for i = 0, (data:len() / self.BLOCK_SZ) do - local cur_out_block = data:sub((i*self.BLOCK_SZ) + 1, (i*self.BLOCK_SZ) + self.BLOCK_SZ) - print(string.format('Transmission #%u: %u bytes', i, cur_out_block:len())) - - -- arg1: start block number - -- arg2: block count - local memsetCmd = Command:newMIX{cmd = cmds.CMD_HF_MIFARE_EML_MEMSET, - data = utils.hexlify(cur_out_block), - arg1 = i * self.BLOCK_COUNT, - arg2 = self.BLOCK_COUNT} - - -- Send command and wait for response - local _, err = memsetCmd:sendMIX() - if err then - print('Failed setting memory', err) - return false - end - end - - print('Emulator memory set') - return true -end - --- Read bytes from emulator memory -function Emulator:get_mem (size) - local MAX_BLOCKS = 4 - local result = '' - - -- We can request a maximum of 4 blocks (16 bytes each) per command, - -- according to mifarecmd.c - for i = 0, (size / (MAX_BLOCKS * 16)) do - -- arg1: start block number - -- arg2: block count (max 4) - local getmemCmd = Command:newMIX{cmd = cmds.CMD_HF_MIFARE_EML_MEMGET, - arg1 = i * MAX_BLOCKS, - arg2 = MAX_BLOCKS, - arg3 = 0} - - local response, err = getmemCmd:sendMIX() - if err then - print('Failed getting memory:', err) - return false - end - - -- USB data begins after four 64-bit values - local data_begin = ((64/8) * 4) + 1 - response = string.sub(response, data_begin) - - -- Truncate to the received 16 byte blocks - response = string.sub(response, 1, 16 * MAX_BLOCKS) - - result = result .. response - end - - return string.sub(result, 1, size) -end - -return Emulator diff --git a/client/luascripts/amiibo.lua b/client/luascripts/amiibo.lua deleted file mode 100644 index 10ede4008..000000000 --- a/client/luascripts/amiibo.lua +++ /dev/null @@ -1,235 +0,0 @@ -local utils = require('utils') -local cmds = require('commands') -local Amiibo = require('amiibolib') -local reader = require('read14a') -local bin = require('bin') -local emu = require('emulator') -local luamiibo_open, err = package.loadlib("./libluamiibo.so", "luaopen_luamiibo") - -if err then - print(err) - return -end - -local luamiibo = luamiibo_open() - -local function nfc_read_amiibo () - - local command = Command:newMIX{ - cmd = cmds.CMD_HF_MIFAREU_READCARD, - arg1 = 0, - arg2 = 135 - } - - local result, err = command:sendMIX() - if result then - -- Do Mifare Ultralight read - local count, cmd, arg0, data_len, offset = bin.unpack('LLLL', result) - - if arg0 == 0 then - return nil, "Card select failed" - end - - -- Do GetFromBigBuf - local data = core.GetFromBigBuf(offset, data_len) - - return data, err - else - return nil, "Couldn't read Amiibo" - end -end - - -local function emulate_amiibo (amiibo_data) - -- Make UID args - -- Use known ID/sig for known ECDSA signature - REPLACE ME! - local uid_bytes = '\x00\x04\xFF\xFF\xFF\xFF\xFF\xFF' - local ecc_sig = '' - .. '\x00\x00\x00\x00\x00\x00\x00\x00' - .. '\x00\x00\x00\x00\x00\x00\x00\x00' - .. '\x00\x00\x00\x00\x00\x00\x00\x00' - .. '\x00\x00\x00\x00\x00\x00\x00\x00' - - if amiibo_data:len() == 520 then - -- Add common ending bytes - print('Added missing ending bytes') - amiibo_data = amiibo_data - .. '\x01\x00\x0F\xBD\x00\x00\x00\x04' - .. '\x5F\x00\x00\x00\x00\x00\x00\x00' - .. '\x00\x00\x00\x00' - end - - if amiibo_data:len() == 572 then - -- Get ECC signature and use original serial - uid_bytes = '\x00' .. amiibo_data:sub(1,3) .. amiibo_data:sub(5,8) - ecc_sig = amiibo_data:sub(541, 572) - print('Amiibo image contains ECC signature', hexlify(ecc_sig)) - --amiibo_data = amiibo_data:sub(1,540) - elseif amiibo_data:len() == 540 then - if uid_bytes ~= '\x00\x04\xFF\xFF\xFF\xFF\xFF\xFF' then - print('Using known ECC sig pair') - else - print('No known ECC/sig pair; using null signature') - uid_bytes = '\x00' .. amiibo_data:sub(1,3) .. amiibo_data:sub(5,8) - end - amiibo_data = amiibo_data .. ecc_sig - else - print('Unusual Amiibo image size', amiibo_data:len()) - end - - -- Send amiibo data to emulator memory. If the Amiibo was just scanned, this - -- is already set! - if not emu:set_mem(amiibo_data, false) then - print('Failed to set emulator card memory') - return - end - - -- Get UID parts - local count, uid_first, uid_second = bin.unpack('>I>I', uid_bytes) - print(string.format('Simulating with UID: 0x%04x 0x%04x', uid_first, uid_second)) - - -- Begin simulating NTAG215 - local simCmd = Command:newMIX{ - cmd = cmds.CMD_HF_ISO14443A_SIMULATE, - arg1 = 7, - arg2 = uid_first, - arg3 = uid_second - } - local _, err = simCmd:sendMIX() - if err then - print('Failed to start simulator', err) - return - else - print('Starting simulator') - end -end - - -local function test_packing() - -- Load Pikachu dump instead - local dumpfile = io.open("pika.bin", "rb") - local pikachu = dumpfile:read("*all") - - local unpacked_pika = luamiibo.unpack(pikachu) - local packed_data = luamiibo.pack(unpacked_pika) - - print('Original', utils.hexlify(pikachu)) - print('Unpacked', utils.hexlify(unpacked_pika)) - print('Packed', utils.hexlify(packed_data)) -end - - -local function load_sim(argv) - local tag = assert(io.open(argv[2], "rb")) - local data = tag:read("*all") - tag:close() - - emulate_amiibo(data) - return -end - - -local function dump_sim(argv) - local keypath = argv[2] - if keypath == nil then - keypath = 'amiitool_keys.bin' - end - luamiibo.load_keys(keypath) - - -- Read all 135 pages - dump = emu:get_mem(540) - - if dump == false then - print('Failed to read emulator memory') - else - local amiiboData = Amiibo:new{tag = dump} - print('Dumped ' .. dump:len() .. ' bytes') - print(hexlify(dump)) - print('Nickname: ' .. utils.hexlify(amiiboData:display_nickname())) - - -- Write dump to file - local filename = argv[2] - if filename ~= nil then - local outfile = assert(io.open(filename, "wb")) - outfile:write(dump) - outfile:close() - print('Wrote to ' .. filename) - else - print('No output file specified') - end - end -end - - -local function main(args) - argv = {} - for arg in string.gmatch(args, "%S+") do - table.insert(argv, arg) - end - - -- Load and emulate Amiibo from image - if argv[1] == 'help' then - print('read - scan amiibo') - print('load - load and simulate amiibo') - print('dump [output_file] - dump card memory') - print('help - print this help') - return - elseif argv[1] == 'load' then - load_sim(argv) - return - elseif argv[1] == 'dump' then - dump_sim(argv) - return - elseif argv[1] ~= 'read' and argv[1] ~= nil then - print('Unknown command') - end - - local keypath = argv[2] - if keypath == nil then - keypath = 'amiitool_keys.bin' - end - - if luamiibo.load_keys(keypath) then - print('Loaded retail keys from ' .. keypath) - else - print('Failed to load retail keys from ' .. keypath) - return - end - - local tag, err = nfc_read_amiibo() - if err then - print(err) - return - elseif tag:len() ~= 540 then - print('Incorrect tag data size ' .. tag:len()) - return - end - - parsed_tag = reader.parse14443a(tag) - print('Tag type:', parsed_tag.name) - print('Tag UID:', parsed_tag.uid) - print('Tag len:', tag:len()) - --print('Tag data:', utils.hexlify(tag)) - - local amiiboData = Amiibo:new{tag = tag} - - --print('Unpacked:', utils.hexlify(amiiboData.plain)) - --print('Repacked:', utils.hexlify(amiiboData:export_tag())) - - print('Figure ID:', utils.hexlify(amiiboData.figure_id)) - print('Settings init:', amiiboData.settings_initialized) - - if amiiboData.settings_initialized then - print('Nickname:', amiiboData:display_nickname()) - print('Appdata writes:', amiiboData.appdata_counter) - end - - print('UID:', utils.hexlify(amiiboData.uid)) - print('Write key:', utils.hexlify(amiiboData:get_pwd())) - - --print('Attempting emulation...') - --emulate_amiibo(amiiboData:export_tag()) - return -end - -main(args) From 7ea2c0753ca380b6a652102c774e2c57026932f1 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Tue, 5 Nov 2019 16:01:05 +0200 Subject: [PATCH 1125/1854] aidlist --- client/resources/aidlist.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/client/resources/aidlist.json b/client/resources/aidlist.json index bfe8511be..13e140e49 100644 --- a/client/resources/aidlist.json +++ b/client/resources/aidlist.json @@ -2142,5 +2142,13 @@ "Name": "teslaLogic002", "Description": "Tesla car key", "Type": "Tesla" + }, + { + "AID": "7465736C61", + "Vendor": "Tesla", + "Country": "", + "Name": "tesla", + "Description": "Tesla car key generic AID", + "Type": "Tesla" } ] \ No newline at end of file From 50bf809a4b4814b3dc3d944969a05518d34300a6 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 5 Nov 2019 20:04:29 +0100 Subject: [PATCH 1126/1854] textual --- client/cmddata.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/cmddata.c b/client/cmddata.c index 499db7128..d13eee46d 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -812,7 +812,7 @@ int AutoCorrelate(const int *in, int *out, size_t len, size_t window, bool SaveG // sanity check if (window > len) window = len; - if (verbose) PrintAndLogEx(INFO, "performing " _YELLOW_("%zu")" correlations", GraphTraceLen - window); + if (verbose) PrintAndLogEx(INFO, "performing " _YELLOW_("%zu") "correlations", GraphTraceLen - window); //test double autocv = 0.0; // Autocovariance value @@ -868,9 +868,9 @@ int AutoCorrelate(const int *in, int *out, size_t len, size_t window, bool SaveG if (verbose && foo < bar) { distance = idx_1 - idx; - PrintAndLogEx(SUCCESS, "possible visible correlation %4d samples", distance); + PrintAndLogEx(SUCCESS, "possible visible correlation "_YELLOW_("%4d") "samples", distance); } else if (verbose && (correlation > 1)) { - PrintAndLogEx(SUCCESS, "possible correlation %4zu samples", correlation); + PrintAndLogEx(SUCCESS, "possible correlation " _YELLOW_("%4zu") "samples", correlation); } else { PrintAndLogEx(FAILED, "no repeating pattern found, try increasing window size"); } From ad475a224e7577dbb14843c4a91eccdc02078ff3 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 5 Nov 2019 23:15:01 +0100 Subject: [PATCH 1127/1854] hf mf wrbl: don't give as example how to write a block0 with faulty BCC, remove mfc stuff in df --- client/cmdhfmf.c | 2 +- client/cmdhfmfdes.c | 93 --------------------------------------------- 2 files changed, 1 insertion(+), 94 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 47b591875..23b418599 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -533,7 +533,7 @@ static int CmdHF14AMfWrBl(const char *Cmd) { if (strlen(Cmd) < 3) { PrintAndLogEx(NORMAL, "Usage: hf mf wrbl "); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf mf wrbl 0 A FFFFFFFFFFFF 000102030405060708090A0B0C0D0E0F"); + PrintAndLogEx(NORMAL, " hf mf wrbl 1 A FFFFFFFFFFFF 000102030405060708090A0B0C0D0E0F"); return 0; } diff --git a/client/cmdhfmfdes.c b/client/cmdhfmfdes.c index f46384d12..17dd97289 100644 --- a/client/cmdhfmfdes.c +++ b/client/cmdhfmfdes.c @@ -24,100 +24,7 @@ uint8_t key_defa_data[16] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x uint8_t key_picc_data[16] = { 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f }; static int CmdHelp(const char *Cmd); -/* -static int CmdHF14ADesWb(const char *Cmd) { - uint8_t blockNo = 0; - uint8_t keyType = 0; - uint8_t key[6] = {0, 0, 0, 0, 0, 0}; - uint8_t bldata[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - char cmdp = 0x00; - - if (strlen(Cmd)<3) { - PrintAndLogEx(NORMAL, "Usage: hf mf wrbl "); - PrintAndLogEx(NORMAL, " sample: hf mf wrbl 0 A FFFFFFFFFFFF 000102030405060708090A0B0C0D0E0F"); - return 0; - } - - blockNo = param_get8(Cmd, 0); - cmdp = param_getchar(Cmd, 1); - if (cmdp == 0x00) { - PrintAndLogEx(NORMAL, "Key type must be A or B"); - return 1; - } - if (cmdp != 'A' && cmdp != 'a') keyType = 1; - if (param_gethex(Cmd, 2, key, 12)) { - PrintAndLogEx(NORMAL, "Key must include 12 HEX symbols"); - return 1; - } - if (param_gethex(Cmd, 3, bldata, 32)) { - PrintAndLogEx(NORMAL, "Block data must include 32 HEX symbols"); - return 1; - } - PrintAndLogEx(NORMAL, "--block no:%02x key type:%02x key:%s", blockNo, keyType, sprint_hex(key, 6)); - PrintAndLogEx(NORMAL, "--data: %s", sprint_hex(bldata, 16)); - - uint8_t data[26]; - memcpy(data, key, 6); - memcpy(data + 10, bldata, 16); - SendCommandOLD(CMD_HF_MIFARE_WRITEBL, blockNo, keyType, 0, data, sizeof(data)); - - PacketResponseNG resp; - if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { - uint8_t isOK = resp.oldarg[0] & 0xff; - PrintAndLogEx(NORMAL, "isOk:%02x", isOK); - } else { - PrintAndLogEx(NORMAL, "Command execute timeout"); - } - return 0; -} - -static int CmdHF14ADesRb(const char *Cmd) { - uint8_t blockNo = 0; - uint8_t keyType = 0; - uint8_t key[6] = {0, 0, 0, 0, 0, 0}; - - char cmdp = 0x00; - - - if (strlen(Cmd)<3) { - PrintAndLogEx(NORMAL, "Usage: hf mf rdbl "); - PrintAndLogEx(NORMAL, " sample: hf mf rdbl 0 A FFFFFFFFFFFF "); - return 0; - } - - blockNo = param_get8(Cmd, 0); - cmdp = param_getchar(Cmd, 1); - if (cmdp == 0x00) { - PrintAndLogEx(NORMAL, "Key type must be A or B"); - return 1; - } - if (cmdp != 'A' && cmdp != 'a') keyType = 1; - if (param_gethex(Cmd, 2, key, 12)) { - PrintAndLogEx(NORMAL, "Key must include 12 HEX symbols"); - return 1; - } - PrintAndLogEx(NORMAL, "--block no:%02x key type:%02x key:%s ", blockNo, keyType, sprint_hex(key, 6)); - - - mf_readblock_t payload = { blockNo, keyType, key }; - SendCommandNG(CMD_HF_MIFARE_READBL, (uint8_t *)payload, sizeof(mf_readblock_t) ); - - PacketResponseNG resp; - if (WaitForResponseTimeout(CMD_HF_MIFARE_READBL, &resp, 1500)) { - uint8_t * data = resp.data.asBytes; - - if (resp.status == PM3_SUCCESS) - PrintAndLogEx(NORMAL, "isOk:%02x data:%s", isOK, sprint_hex(data, 16)); - else - PrintAndLogEx(NORMAL, "isOk:%02x", isOK); - } else { - PrintAndLogEx(NORMAL, "Command execute timeout"); - } - - return 0; -} -*/ static int CmdHF14ADesInfo(const char *Cmd) { (void)Cmd; // Cmd is not used so far From a0204386f04fb1c7835f07b935ebfebbea0eadf2 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 7 Nov 2019 07:23:13 +0100 Subject: [PATCH 1128/1854] chg: new samples has less similar preamble --- client/cmdlfgallagher.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/client/cmdlfgallagher.c b/client/cmdlfgallagher.c index f8d513a13..9704afc60 100644 --- a/client/cmdlfgallagher.c +++ b/client/cmdlfgallagher.c @@ -6,7 +6,8 @@ // the license. //----------------------------------------------------------------------------- // Low frequency GALLAGHER tag commands -// NRZ, RF/32, 128 bits long (unknown cs) +// ASK/MAN, RF/32, 96 bits long (unknown cs) (0x00088060) +// sample Q5 , ASK RF/32, STT, 96 bits (3blocks) ( 0x9000F006) //----------------------------------------------------------------------------- #include "cmdlfgallagher.h" @@ -157,10 +158,11 @@ int detectGallagher(uint8_t *dest, size_t *size) { if (*size < 96) return -1; //make sure buffer has data size_t startIdx = 0; uint8_t preamble[] = { - 0, 0, 0, 0, 1, 1, 1, 1, + //0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 1 + 0, 1, 1, 0, 0, 0 }; if (!preambleSearch(dest, preamble, sizeof(preamble), size, &startIdx)) return -2; //preamble not found From 014a3dee992f4deaa4d1220d229995c8fb8e6e3d Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 7 Nov 2019 09:43:32 +0100 Subject: [PATCH 1129/1854] fix: iclass simulation (iceman) --- armsrc/iclass.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/armsrc/iclass.c b/armsrc/iclass.c index 33ea46e85..6cbf804ef 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -1306,6 +1306,7 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) { AddCrc(csn_data, 8); uint8_t diversified_key[8] = { 0 }; + // e-Purse uint8_t card_challenge_data[8] = { 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; //uint8_t card_challenge_data[8] = { 0 }; @@ -1316,6 +1317,7 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) { //Card challenge, a.k.a e-purse is on block 2 memcpy(card_challenge_data, emulator + (8 * 2), 8); + //Precalculate the cipher state, feeding it the CC cipher_state = opt_doTagMAC_1(card_challenge_data, diversified_key); } @@ -1351,7 +1353,7 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) { uint8_t *resp_csn = BigBuf_malloc(28); int resp_csn_len; - // configuration picopass 2ks + // configuration Picopass 2ks uint8_t *resp_conf = BigBuf_malloc(28); int resp_conf_len; uint8_t conf_data[10] = {0x12, 0xFF, 0xFF, 0xFF, 0x7F, 0x1F, 0xFF, 0x3C, 0x00, 0x00}; @@ -1366,6 +1368,14 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) { uint8_t *resp_aia = BigBuf_malloc(28); int resp_aia_len; uint8_t aia_data[10] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00}; + if (simulationMode == MODE_FULLSIM) { + + // (iceman) this only works for 2KS / 16KS tags. + // Use application data from block 5 + memcpy(aia_data, emulator + (8 * 5), 8); + + // older 2K / 16K tags has its application issuer data on block 2 + } AddCrc(aia_data, 8); // receive command From 33fe2b890b83c6e73f1bb842254fb4028337c6a5 Mon Sep 17 00:00:00 2001 From: RFID Research Group Date: Thu, 7 Nov 2019 17:18:16 +0100 Subject: [PATCH 1130/1854] Update FUNDING.yml --- .github/FUNDING.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 2f13a259a..ceee38f85 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -9,4 +9,4 @@ community_bridge: # Replace with a single Community Bridge project-name e.g., cl liberapay: # Replace with a single Liberapay username issuehunt: # Replace with a single IssueHunt username otechie: # Replace with a single Otechie username -custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] +custom: ["https://www.paypal.me/iceman1001"] From 5cca8616cb4c3ed3d5bbbbb0a27755561ac6bd4b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 8 Nov 2019 10:28:29 +0100 Subject: [PATCH 1131/1854] Add: 'hf mfu otptear' - draft of @fukmar implementation for a tear-off attack against OTP block on Mifare Ultralight based card. --- armsrc/appmain.c | 32 ++++++++++++---------- armsrc/mifarecmd.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++ armsrc/mifarecmd.h | 3 +++ client/cmdhfmfu.c | 43 +++++++++++++++++++++++++++++ include/pm3_cmd.h | 3 +++ 5 files changed, 134 insertions(+), 14 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 5011c1979..ef96d9fef 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -696,10 +696,23 @@ static void PacketReceived(PacketCommandNG *packet) { */ switch (packet->cmd) { - case CMD_QUIT_SESSION: + case CMD_QUIT_SESSION: { reply_via_fpc = false; reply_via_usb = false; break; + } + // emulator + case CMD_SET_DBGMODE: { + DBGLEVEL = packet->data.asBytes[0]; + Dbprintf("Debug level: %d", DBGLEVEL); + reply_ng(CMD_SET_DBGMODE, PM3_SUCCESS, NULL, 0); + break; + } + // always available + case CMD_HF_DROPFIELD: { + hf_field_off(); + break; + } #ifdef WITH_LF case CMD_LF_T55XX_SET_CONFIG: { setT55xxConfig(packet->oldarg[0], (t55xx_configurations_t *) packet->data.asBytes); @@ -1034,12 +1047,6 @@ static void PacketReceived(PacketCommandNG *packet) { } #endif -// always available - case CMD_HF_DROPFIELD: { - hf_field_off(); - break; - } - #ifdef WITH_ISO14443a case CMD_HF_ISO14443A_SNIFF: { SniffIso14443a(packet->data.asBytes[0]); @@ -1155,13 +1162,6 @@ static void PacketReceived(PacketCommandNG *packet) { Mifare1ksim(payload->flags, payload->exitAfter, payload->uid, payload->atqa, payload->sak); break; } - // emulator - case CMD_SET_DBGMODE: { - DBGLEVEL = packet->data.asBytes[0]; - Dbprintf("Debug level: %d", DBGLEVEL); - reply_ng(CMD_SET_DBGMODE, PM3_SUCCESS, NULL, 0); - break; - } case CMD_HF_MIFARE_EML_MEMCLR: { MifareEMemClr(); reply_ng(CMD_HF_MIFARE_EML_MEMCLR, PM3_SUCCESS, NULL, 0); @@ -1245,6 +1245,10 @@ static void PacketReceived(PacketCommandNG *packet) { DetectNACKbug(); break; } + case CMD_HF_MFU_OTP_TEAROFF: { + MifareU_Otp_Tearoff(); + break; + } #endif #ifdef WITH_NFCBARCODE diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index f5e3fe961..0b840e2fb 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -2173,3 +2173,70 @@ void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain) { LEDsoff(); set_tracing(false); } + +// +// Tear-off attack against MFU. +// - Mobius et al +void MifareU_Otp_Tearoff() { + +// should the +// optional time be configurable via client side? +// optional authentication before? +// optional data to be written? + + if (DBGLEVEL >= DBG_ERROR) DbpString("Preparing OTP tear-off"); + + LEDsoff(); + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + clear_trace(); + set_tracing(true); + + StartTicks(); + +#define OTP_TEAR_OFF_TIME 1000 +#define OTP_BLK_NO 3 + + // write cmd to send, include CRC + // 1b write, 1b block, 4b data, 2 crc + uint8_t cmd[] = {MIFARE_ULC_WRITE, OTP_BLK_NO, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0}; + +// User specific data to write? +// memcpy(block + 2, blockData, 4); + + AddCrc14A(cmd, sizeof(cmd) - 2); + + if (DBGLEVEL >= DBG_ERROR) DbpString("Transmitting"); + + // anticollision / select card + if (!iso14443a_select_card(NULL, NULL, NULL, true, 0, true)) { + if (DBGLEVEL >= DBG_ERROR) Dbprintf("Can't select card"); + OnError(1); + return; + }; + + /* + // UL-EV1 / NTAG authentication + if (usePwd) { + uint8_t pwd[4] = {0x00}; + memcpy(pwd, datain + 4, 4); + uint8_t pack[4] = {0, 0, 0, 0}; + if (!mifare_ul_ev1_auth(pwd, pack)) { + OnError(1); + return; + } + } + */ + + // send + ReaderTransmit(cmd, sizeof(cmd), NULL); + + // Wait before cutting power. aka tear-off + LED_D_ON(); + WaitUS(OTP_TEAR_OFF_TIME); + switch_off(); + + reply_ng(CMD_HF_MFU_OTP_TEAROFF, PM3_SUCCESS, NULL, 0); + StopTicks(); + + if (DBGLEVEL >= DBG_ERROR) DbpString("Done"); +} diff --git a/armsrc/mifarecmd.h b/armsrc/mifarecmd.h index 0b8e2acd3..6b730fb58 100644 --- a/armsrc/mifarecmd.h +++ b/armsrc/mifarecmd.h @@ -52,4 +52,7 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype); void Mifare_DES_Auth1(uint8_t arg0, uint8_t *datain); void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain); +// Tear-off test for MFU +void MifareU_Otp_Tearoff(); + #endif diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index 06f44e35d..3107dd585 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -221,6 +221,16 @@ static int usage_hf_mfu_pwdgen(void) { return PM3_SUCCESS; } +static int usage_hf_mfu_otp_tearoff(void) { + PrintAndLogEx(NORMAL, "Tear-off test against OTP block on MFU tags - More help sooner or later\n"); + PrintAndLogEx(NORMAL, "Usage: hf mfu otptear [h]"); + PrintAndLogEx(NORMAL, "Options:"); + PrintAndLogEx(NORMAL, " h : this help"); + PrintAndLogEx(NORMAL, "Examples:"); + PrintAndLogEx(NORMAL, " hf mfu otptear"); + return PM3_SUCCESS; +} + uint8_t default_3des_keys[][16] = { { 0x42, 0x52, 0x45, 0x41, 0x4b, 0x4d, 0x45, 0x49, 0x46, 0x59, 0x4f, 0x55, 0x43, 0x41, 0x4e, 0x21 }, // 3des std key @@ -2740,6 +2750,38 @@ static int CmdHF14AMfUPwdGen(const char *Cmd) { PrintAndLogEx(NORMAL, "--------------------"); return PM3_SUCCESS; } + +// +// MFU TearOff against OTP +// Mobeius et al +// +static int CmdHF14AMfuOtpTearoff(const char *Cmd){ + uint8_t cmdp = 0; + bool errors = 0; + uint32_t len = strtol(Cmd, NULL, 0); + uint8_t data[PM3_CMD_DATA_SIZE] = {0}; + + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { + case 'h': + return usage_hf_mfu_otp_tearoff(); + default: + break; + } + } + + if (errors) return usage_hf_mfu_otp_tearoff(); + + clearCommandBuffer(); + SendCommandNG(CMD_HF_MFU_OTP_TEAROFF, data, len); + PacketResponseNG resp; + if (!WaitForResponseTimeout(CMD_HF_MFU_OTP_TEAROFF, &resp, 4000)) { + PrintAndLogEx(WARNING, "Failed"); + return PM3_ESOFT; + } + return PM3_SUCCESS; +} + //------------------------------------ // Menu Stuff //------------------------------------ @@ -2757,6 +2799,7 @@ static command_t CommandTable[] = { {"sim", CmdHF14AMfUSim, IfPm3Iso14443a, "Simulate Ultralight from emulator memory"}, {"gen", CmdHF14AMfUGenDiverseKeys, AlwaysAvailable, "Generate 3des mifare diversified keys"}, {"pwdgen", CmdHF14AMfUPwdGen, AlwaysAvailable, "Generate pwd from known algos"}, + {"otptear", CmdHF14AMfuOtpTearoff, IfPm3Iso14443a, "Tear-off test on OTP bits"}, {NULL, NULL, NULL, NULL} }; diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 544d5e5c2..0f7212600 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -507,6 +507,9 @@ typedef struct { #define CMD_HF_MIFARE_NACK_DETECT 0x0730 +// MFU OTP TearOff +#define CMD_HF_MFU_OTP_TEAROFF 0x0740 + #define CMD_HF_SNIFF 0x0800 // For ThinFilm Kovio From 182f239d21390e6c66b071e1637b0f3593972d09 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 8 Nov 2019 12:00:21 +0100 Subject: [PATCH 1132/1854] make style --- armsrc/iclass.c | 2 +- armsrc/lfops.c | 14 ++++++------ armsrc/mifarecmd.c | 30 +++++++++++++------------- client/aidsearch.c | 22 +++++++++---------- client/cmdhfmfu.c | 48 ++++++++++++++++++++--------------------- client/cmdlfjablotron.c | 2 +- client/scripting.c | 46 +++++++++++++++++++-------------------- 7 files changed, 82 insertions(+), 82 deletions(-) diff --git a/armsrc/iclass.c b/armsrc/iclass.c index 6cbf804ef..9ab2b5013 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -1374,7 +1374,7 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) { // Use application data from block 5 memcpy(aia_data, emulator + (8 * 5), 8); - // older 2K / 16K tags has its application issuer data on block 2 + // older 2K / 16K tags has its application issuer data on block 2 } AddCrc(aia_data, 8); diff --git a/armsrc/lfops.c b/armsrc/lfops.c index b5e9b98ec..8aa86a43b 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -1101,13 +1101,13 @@ void CmdASKsimTAG(uint8_t encoding, uint8_t invert, uint8_t separator, uint8_t c WDT_HIT(); Dbprintf("Simulating with clk: %d, invert: %d, encoding: %s (%d), separator: %d, n: %d" - , clk - , invert - , (encoding == 2) ? "BI" : (encoding == 1) ? "ASK" : "RAW" - , encoding - , separator - , n - ); + , clk + , invert + , (encoding == 2) ? "BI" : (encoding == 1) ? "ASK" : "RAW" + , encoding + , separator + , n + ); if (ledcontrol) LED_A_ON(); SimulateTagLowFrequency(n, 0, ledcontrol); diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 0b840e2fb..bb4fb343d 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -2176,7 +2176,7 @@ void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain) { // // Tear-off attack against MFU. -// - Mobius et al +// - Moebius et al void MifareU_Otp_Tearoff() { // should the @@ -2184,8 +2184,8 @@ void MifareU_Otp_Tearoff() { // optional authentication before? // optional data to be written? - if (DBGLEVEL >= DBG_ERROR) DbpString("Preparing OTP tear-off"); - + if (DBGLEVEL >= DBG_ERROR) DbpString("Preparing OTP tear-off"); + LEDsoff(); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); clear_trace(); @@ -2197,17 +2197,17 @@ void MifareU_Otp_Tearoff() { #define OTP_BLK_NO 3 // write cmd to send, include CRC - // 1b write, 1b block, 4b data, 2 crc + // 1b write, 1b block, 4b data, 2 crc uint8_t cmd[] = {MIFARE_ULC_WRITE, OTP_BLK_NO, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0}; -// User specific data to write? +// User specific data to write? // memcpy(block + 2, blockData, 4); AddCrc14A(cmd, sizeof(cmd) - 2); if (DBGLEVEL >= DBG_ERROR) DbpString("Transmitting"); - // anticollision / select card + // anticollision / select card if (!iso14443a_select_card(NULL, NULL, NULL, true, 0, true)) { if (DBGLEVEL >= DBG_ERROR) Dbprintf("Can't select card"); OnError(1); @@ -2225,18 +2225,18 @@ void MifareU_Otp_Tearoff() { return; } } - */ + */ - // send + // send ReaderTransmit(cmd, sizeof(cmd), NULL); - + // Wait before cutting power. aka tear-off - LED_D_ON(); - WaitUS(OTP_TEAR_OFF_TIME); + LED_D_ON(); + WaitUS(OTP_TEAR_OFF_TIME); switch_off(); - + reply_ng(CMD_HF_MFU_OTP_TEAROFF, PM3_SUCCESS, NULL, 0); - StopTicks(); - - if (DBGLEVEL >= DBG_ERROR) DbpString("Done"); + StopTicks(); + + if (DBGLEVEL >= DBG_ERROR) DbpString("Done"); } diff --git a/client/aidsearch.c b/client/aidsearch.c index a25a25547..ecaa6e6c8 100644 --- a/client/aidsearch.c +++ b/client/aidsearch.c @@ -70,13 +70,13 @@ json_t *AIDSearchGetElm(json_t *root, int elmindx) { } int AIDSearchFree(json_t *root) { - + return closeAIDFile(root); } -const char * jsonStrGet(json_t *data, char *name) { +const char *jsonStrGet(json_t *data, char *name) { json_t *jstr; - + jstr = json_object_get(data, name); if (jstr == NULL) return NULL; @@ -94,11 +94,11 @@ const char * jsonStrGet(json_t *data, char *name) { bool aidCompare(const char *aidlarge, const char *aidsmall) { if (strcmp(aidlarge, aidsmall) == 0) return true; - + if (strlen(aidlarge) > strlen(aidsmall)) if (strncmp(aidlarge, aidsmall, strlen(aidsmall)) == 0) return true; - + return false; } @@ -107,7 +107,7 @@ bool AIDGetFromElm(json_t *data, uint8_t *aid, size_t aidmaxlen, int *aidlen) { const char *hexaid = jsonStrGet(data, "AID"); if (hexaid == NULL || strlen(hexaid) == 0) return false; - + int res = param_gethex_to_eol(hexaid, 0, aid, aidmaxlen, aidlen); if (res) return false; @@ -117,13 +117,13 @@ bool AIDGetFromElm(json_t *data, uint8_t *aid, size_t aidmaxlen, int *aidlen) { int PrintAIDDescription(json_t *xroot, char *aid, bool verbose) { int retval = PM3_SUCCESS; - + json_t *root = xroot; if (root == NULL) root = AIDSearchInit(verbose); if (root == NULL) goto out; - + json_t *elm = NULL; int maxaidlen = 0; for (int elmindx = 0; elmindx < json_array_size(root); elmindx++) { @@ -138,10 +138,10 @@ int PrintAIDDescription(json_t *xroot, char *aid, bool verbose) { } } } - + if (elm == NULL) goto out; - + // print here const char *vaid = jsonStrGet(elm, "AID"); const char *vendor = jsonStrGet(elm, "Vendor"); @@ -167,7 +167,7 @@ int PrintAIDDescription(json_t *xroot, char *aid, bool verbose) { if (description) PrintAndLogEx(SUCCESS, "Description: %s", description); } - + out: if (xroot == NULL) AIDSearchFree(root); diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index 3107dd585..d7bdce1fc 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -2753,33 +2753,33 @@ static int CmdHF14AMfUPwdGen(const char *Cmd) { // // MFU TearOff against OTP -// Mobeius et al +// Moebius et al // -static int CmdHF14AMfuOtpTearoff(const char *Cmd){ - uint8_t cmdp = 0; - bool errors = 0; - uint32_t len = strtol(Cmd, NULL, 0); - uint8_t data[PM3_CMD_DATA_SIZE] = {0}; - - while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { - switch (tolower(param_getchar(Cmd, cmdp))) { - case 'h': - return usage_hf_mfu_otp_tearoff(); - default: - break; - } - } +static int CmdHF14AMfuOtpTearoff(const char *Cmd) { + uint8_t cmdp = 0; + bool errors = 0; + uint32_t len = strtol(Cmd, NULL, 0); + uint8_t data[PM3_CMD_DATA_SIZE] = {0}; - if (errors) return usage_hf_mfu_otp_tearoff(); + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { + case 'h': + return usage_hf_mfu_otp_tearoff(); + default: + break; + } + } - clearCommandBuffer(); - SendCommandNG(CMD_HF_MFU_OTP_TEAROFF, data, len); - PacketResponseNG resp; - if (!WaitForResponseTimeout(CMD_HF_MFU_OTP_TEAROFF, &resp, 4000)) { - PrintAndLogEx(WARNING, "Failed"); - return PM3_ESOFT; - } - return PM3_SUCCESS; + if (errors) return usage_hf_mfu_otp_tearoff(); + + clearCommandBuffer(); + SendCommandNG(CMD_HF_MFU_OTP_TEAROFF, data, len); + PacketResponseNG resp; + if (!WaitForResponseTimeout(CMD_HF_MFU_OTP_TEAROFF, &resp, 4000)) { + PrintAndLogEx(WARNING, "Failed"); + return PM3_ESOFT; + } + return PM3_SUCCESS; } //------------------------------------ diff --git a/client/cmdlfjablotron.c b/client/cmdlfjablotron.c index a3692fb60..f2f93c513 100644 --- a/client/cmdlfjablotron.c +++ b/client/cmdlfjablotron.c @@ -121,7 +121,7 @@ static int CmdJablotronDemod(const char *Cmd) { uint8_t chksum = raw2 & 0xFF; bool isok = (chksum == jablontron_chksum(DemodBuffer)); - PrintAndLogEx( isok ? SUCCESS : INFO, + PrintAndLogEx(isok ? SUCCESS : INFO, "Checksum: %02X [ %s]", chksum, isok ? _GREEN_("OK") : _RED_("Fail") diff --git a/client/scripting.c b/client/scripting.c index 6ad9bc0fc..45451b241 100644 --- a/client/scripting.c +++ b/client/scripting.c @@ -314,44 +314,44 @@ static int l_GetFromFlashMemSpiffs(lua_State *L) { if (IfPm3Flash()) { uint32_t start_index = 0, len = 0x40000; //FLASH_MEM_MAX_SIZE - char destfilename[32] = {0}; - size_t size; + char destfilename[32] = {0}; + size_t size; int n = lua_gettop(L); if (n == 0) return returnToLuaWithError(L, "You need to supply the destination filename"); if (n >= 1) { - const char *p_filename = luaL_checklstring(L, 1, &size); - if (size != 0) - memcpy(destfilename, p_filename, 31); - } - - if (destfilename[0] == '\0') - return returnToLuaWithError(L, "Filename missing or invalid"); - - // get size from spiffs itself ! - SendCommandMIX(CMD_SPIFFS_STAT, 0, 0, 0, (uint8_t *)destfilename, 32); - PacketResponseNG resp; - if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) - return returnToLuaWithError(L, "No response from the device"); + const char *p_filename = luaL_checklstring(L, 1, &size); + if (size != 0) + memcpy(destfilename, p_filename, 31); + } + + if (destfilename[0] == '\0') + return returnToLuaWithError(L, "Filename missing or invalid"); + + // get size from spiffs itself ! + SendCommandMIX(CMD_SPIFFS_STAT, 0, 0, 0, (uint8_t *)destfilename, 32); + PacketResponseNG resp; + if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) + return returnToLuaWithError(L, "No response from the device"); + + len = resp.oldarg[0]; - len = resp.oldarg[0]; - if (len <= 0) return returnToLuaWithError(L, "Filename invalid or empty"); - + uint8_t *data = calloc(len, sizeof(uint8_t)); if (!data) return returnToLuaWithError(L, "Allocating memory failed"); - if (!GetFromDevice(SPIFFS, data, len, start_index, (uint8_t *)destfilename, 32, NULL, -1, true)) { - free(data); - return returnToLuaWithError(L, "ERROR; downloading from spiffs(flashmemory)"); - } + if (!GetFromDevice(SPIFFS, data, len, start_index, (uint8_t *)destfilename, 32, NULL, -1, true)) { + free(data); + return returnToLuaWithError(L, "ERROR; downloading from spiffs(flashmemory)"); + } lua_pushlstring(L, (const char *)data, len); - lua_pushunsigned(L, len); + lua_pushunsigned(L, len); free(data); return 2; } else { From 2c0a8bbd91dd0257c47f3de22a8a84e59a7b6d97 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 8 Nov 2019 12:01:46 +0100 Subject: [PATCH 1133/1854] make style --- client/aidsearch.h | 2 +- client/cmdhf14a.c | 10 +++++----- client/luascripts/read_pwd_mem_spiffs.lua | 10 +++++----- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/client/aidsearch.h b/client/aidsearch.h index 88b79b8bc..9997d3868 100644 --- a/client/aidsearch.h +++ b/client/aidsearch.h @@ -25,4 +25,4 @@ json_t *AIDSearchGetElm(json_t *root, int elmindx); bool AIDGetFromElm(json_t *data, uint8_t *aid, size_t aidmaxlen, int *aidlen); int AIDSearchFree(); -#endif \ No newline at end of file +#endif diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index 7ddf97b49..2f8473d1c 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -1505,7 +1505,7 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { } } } - + if (do_aid_search) { int elmindx = 0; json_t *root = AIDSearchInit(verbose); @@ -1517,7 +1517,7 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { int vaidlen = 0; if (!AIDGetFromElm(data, vaid, sizeof(vaid), &vaidlen) || !vaidlen) continue; - + uint16_t sw = 0; uint8_t result[1024] = {0}; size_t resultlen = 0; @@ -1525,7 +1525,7 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { ActivateField = false; if (res) continue; - + uint8_t dfname[200] = {0}; size_t dfnamelen = 0; if (resultlen > 3) { @@ -1540,7 +1540,7 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { tlvdb_free(tlv); } } - + if (sw == 0x9000 || sw == 0x6283 || sw == 0x6285) { if (sw == 0x9000) { if (verbose) PrintAndLogEx(NORMAL, "------------- Application OK -----------"); @@ -1566,7 +1566,7 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { if (verbose) PrintAndLogEx(INFO, "(DF) Name not found"); } } - + } DropField(); } diff --git a/client/luascripts/read_pwd_mem_spiffs.lua b/client/luascripts/read_pwd_mem_spiffs.lua index 8dbdac691..d316d7766 100644 --- a/client/luascripts/read_pwd_mem_spiffs.lua +++ b/client/luascripts/read_pwd_mem_spiffs.lua @@ -59,21 +59,21 @@ local function main(args) local keylength = 4 for o, a in getopt.getopt(args, 'f:h') do - + -- help if o == 'h' then return help() end -- offset if o == 'f' then filename = a end - + end - + data, length, err = core.GetFromFlashMemSpiffs(filename) if data == nil then return oops('Problem while reading file from SPIFFS') end - --print('Filename', filename) + --print('Filename', filename) --print('Filesize (B)', length) - + _, s = bin.unpack('H'..length, data) local cnt = 0, i From 5e72d6e7147e9a77ad4d15351a475184f649bc6e Mon Sep 17 00:00:00 2001 From: bogiton <34060135+bogiton@users.noreply.github.com> Date: Fri, 8 Nov 2019 17:42:17 +0000 Subject: [PATCH 1134/1854] Update hf_bog.c --- armsrc/Standalone/hf_bog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/Standalone/hf_bog.c b/armsrc/Standalone/hf_bog.c index ac0bb7749..d1cc2e202 100644 --- a/armsrc/Standalone/hf_bog.c +++ b/armsrc/Standalone/hf_bog.c @@ -249,5 +249,5 @@ void RunMod() { LEDsoff(); SpinDelay(300); Dbprintf("- [ End ] -> You can take shell back ..."); - Dbprintf("- [ ! ] -> use 'script run read_pwd_mem' to print passwords"); + Dbprintf("- [ ! ] -> use 'script run read_pwd_mem_spiffs' to print passwords"); } From 11b0a69869ded8f437c459c8dc02e6fd8393b0a8 Mon Sep 17 00:00:00 2001 From: bogiton <34060135+bogiton@users.noreply.github.com> Date: Fri, 8 Nov 2019 17:44:52 +0000 Subject: [PATCH 1135/1854] Update read_pwd_mem.lua --- client/luascripts/read_pwd_mem.lua | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/client/luascripts/read_pwd_mem.lua b/client/luascripts/read_pwd_mem.lua index 4a097d26d..8456fd51f 100644 --- a/client/luascripts/read_pwd_mem.lua +++ b/client/luascripts/read_pwd_mem.lua @@ -3,11 +3,13 @@ local bin = require('bin') copyright = 'Copyright (c) 2018 Bogito. All rights reserved.' author = 'Bogito' -version = 'v1.0.2' +version = 'v1.0.3' desc = [[ -This script will read the flash memory of RDV4 and print the stored passwords. -It was meant to be used as a help tool after using the BogRun standalone mode. +This script will read the flash memory of RDV4 and print the stored passwords/keys. + +It was meant to be used as a help tool after using the BogRun standalone mode before SPIFFS. +You should now use read_pwd_mem_spiffs instead after the updated BogRun standalone mode. (Iceman) script adapted to read and print keys in the default dictionary flashmemory sections. ]] @@ -22,8 +24,14 @@ example = -- This will scan 32 bytes of flash memory at offset 64 for stored passwords script run read_pwd_mem -o 64 -l 32 - -- This will print found - script run read_pwd_mem -o 241664 -k 6 + -- This will print the stored Mifare dictionary keys + script run read_pwd_mem -m + + -- This will print the stored t55xx dictionary passwords + script run read_pwd_mem -t + + -- This will print the stored iClass dictionary keys + script run read_pwd_mem -i ]] usage = [[ @@ -66,7 +74,6 @@ local function main(args) print() local data, err, quadlet - local cnt = 0 local offset = 0 local length = 256 local keylength = 4 From a0168441d86c74092b7754c4c70e311e0893e57a Mon Sep 17 00:00:00 2001 From: bogiton <34060135+bogiton@users.noreply.github.com> Date: Fri, 8 Nov 2019 17:46:15 +0000 Subject: [PATCH 1136/1854] Update read_pwd_mem_spiffs.lua --- client/luascripts/read_pwd_mem_spiffs.lua | 49 ++++++++++++++--------- 1 file changed, 30 insertions(+), 19 deletions(-) diff --git a/client/luascripts/read_pwd_mem_spiffs.lua b/client/luascripts/read_pwd_mem_spiffs.lua index d316d7766..33afa0fe9 100644 --- a/client/luascripts/read_pwd_mem_spiffs.lua +++ b/client/luascripts/read_pwd_mem_spiffs.lua @@ -3,7 +3,7 @@ local bin = require('bin') copyright = 'Copyright (c) 2019 Bogito. All rights reserved.' author = 'Bogito' -version = 'v1.1.0' +version = 'v1.1.1' desc = [[ This script will read the flash memory of RDV4 using SPIFFS and print the stored passwords. @@ -16,15 +16,19 @@ example = -- This will read the other.log file in SPIFFS and print the stored passwords script run read_pwd_mem_spiffs -f other.log + + -- This will delete the hf_bog.log file from SPIFFS + script run read_pwd_mem_spiffs -r ]] usage = [[ Usage: - script run read_pwd_mem_spiffs -h -f + script run read_pwd_mem_spiffs -h -f -r Arguments: -h : this help -f : filename in SPIFFS + -r : delete filename from SPIFFS ]] --- -- This is only meant to be used when errors occur @@ -49,42 +53,49 @@ end local function main(args) print( string.rep('--',20) ) - print('Read passwords stored in memory (SPIFFS)') + print('Read passwords stored in memory (SPIFFS)') print( string.rep('--',20) ) print() - local data, length, err - local cnt = 0 + local data, length, err, removeflag local filename = 'hf_bog.log' - local keylength = 4 + local keylength = 4 - for o, a in getopt.getopt(args, 'f:h') do + for o, a in getopt.getopt(args, 'rf:h') do -- help if o == 'h' then return help() end -- offset if o == 'f' then filename = a end + + -- remove + if o == 'r' then removeflag = true end - end + end + if removeflag then + print('Deleting file '..filename.. ' from SPIFFS if exists') + core.console("mem spiffs remove " ..filename) + return + end + data, length, err = core.GetFromFlashMemSpiffs(filename) if data == nil then return oops('Problem while reading file from SPIFFS') end --print('Filename', filename) - --print('Filesize (B)', length) + --print('Filesize (B)', length) - _, s = bin.unpack('H'..length, data) + _, s = bin.unpack('H'..length, data) - local cnt = 0, i - for i = 1, length/keylength do - key = string.sub(s, (i-1)*8+1, i*8) - if key == 'FFFFFFFF' then break end - print(string.format('[%02d] %s',i, key)) - cnt = cnt + 1 - end - print( string.rep('--',20) ) - print( ('[+] found %d passwords'):format(cnt)) + local cnt = 0, i + for i = 1, length/keylength do + key = string.sub(s, (i-1)*8+1, i*8) + print(string.format('[%02d] %s',i, key)) + cnt = cnt + 1 + end + print( string.rep('--',20) ) + print( ('[+] found %d passwords'):format(cnt)) end From 24638a832d0f6a79d9a44736b13cf2b15db37926 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 11 Nov 2019 16:42:25 +0100 Subject: [PATCH 1137/1854] more keys --- client/dictionaries/mfc_default_keys.dic | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index 6d8180e3a..eeecff9ba 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -126,6 +126,13 @@ fb0b20df1f34 # S6 B # a9f953def0a3 # +# Data from forum +74a386ad0a6d +3f7a5c2dbd81 +21edf95e7433 +c121ff19f681 +3d5d9996359a +# # Here be BIP keys... 3A42F33AF429 1FC235AC1309 From f7ad5747f37197101bc2a35587d9b944e0c83d45 Mon Sep 17 00:00:00 2001 From: Iceman Date: Tue, 12 Nov 2019 04:25:30 +0100 Subject: [PATCH 1138/1854] Update 4_Advanced-compilation-parameters.md --- doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md b/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md index 977af704c..3b0599de5 100644 --- a/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md +++ b/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md @@ -48,6 +48,7 @@ Known issues: * 256kb Arm chip devices: The compiled firmware image from this repo may/will be too large for your device. * PM3 Evo: it has a different led/button pin assignment. It tends to be messed up. +* Proxmark Pro: it has different fpga and unknown pin assignments. Will most certainly mess up ## PLATFORM_EXTRAS From 93c9dc571ff30c45f7b6f9ab008fb80ae082e7f6 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 12 Nov 2019 19:27:34 +0100 Subject: [PATCH 1139/1854] chg t55 timings to match offical repo when compiling for PM3OTHER --- armsrc/lfops.c | 25 ++++++++++++++++++------- client/cmdlft55xx.c | 14 +++++++------- 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 8aa86a43b..4c869d9d6 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -52,11 +52,11 @@ SAM7S has several timers, we will use the source TIMER_CLOCK1 (aka AT91C_TC_CLKS TIMER_CLOCK1 = MCK/2, MCK is running at 48 MHz, Timer is running at 48/2 = 24 MHz New timer implemenation in ticks.c, which is used in LFOPS.c - 1us = 1.5ticks - 1fc = 8us = 12ticks + 1 μs = 1.5 ticks + 1 fc = 8 μs = 12 ticks Terms you find in different datasheets and how they match. -1 Cycle = 8 microseconds(us) == 1 field clock (fc) +1 Cycle = 8 microseconds (μs) == 1 field clock (fc) Note about HITAG timing Hitag units (T0) have duration of 8 microseconds (us), which is 1/125000 per second (carrier) @@ -135,19 +135,30 @@ Initial values if not in flash RG = Read gap Explainations for array T55xx_Timing below - SG WG Bit 0/00 Bit 1/01 Bit 10 Bit 11 RG + + 0 1 2 3 + SG WG Bit 00 Bit 01 Bit 10 Bit 11 RG -------------------------------------------------------------------- { 29 , 17 , 15 , 47 , 0 , 0 , 15 }, // Default Fixed - { 31 , 20 , 18 , 50 , 0 , 0 , 15 }, // Long Leading Ref. - { 31 , 20 , 18 , 40 , 0 , 0 , 15 }, // Leading 0 + { 29 , 17 , 15 , 50 , 0 , 0 , 15 }, // Long Leading Ref. + { 29 , 17 , 15 , 40 , 0 , 0 , 15 }, // Leading 0 { 29 , 17 , 15 , 31 , 47 , 63 , 15 } // 1 of 4 */ t55xx_configurations_t T55xx_Timing = { { +#ifdef WITH_FLASH +// PM3RDV4 { 29 * 8, 17 * 8, 15 * 8, 47 * 8, 15 * 8, 0, 0 }, // Default Fixed + { 29 * 8, 17 * 8, 15 * 8, 47 * 8, 15 * 8, 0, 0 }, // Long Leading Ref. + { 29 * 8, 17 * 8, 15 * 8, 40 * 8, 15 * 8, 0, 0 }, // Leading 0 + { 29 * 8, 17 * 8, 15 * 8, 31 * 8, 15 * 8, 47 * 8, 63 * 8 } // 1 of 4 +#else +// PM3OTHER or like offical repo + { 31 * 8, 20 * 8, 18 * 8, 50 * 8, 15 * 8, 0, 0 }, // Default Fixed { 31 * 8, 20 * 8, 18 * 8, 50 * 8, 15 * 8, 0, 0 }, // Long Leading Ref. { 31 * 8, 20 * 8, 18 * 8, 40 * 8, 15 * 8, 0, 0 }, // Leading 0 - { 29 * 8, 17 * 8, 15 * 8, 31 * 8, 15 * 8, 47 * 8, 63 * 8 } // 1 of 4 + { 31 * 8, 20 * 8, 18 * 8, 34 * 8, 15 * 8, 50 * 8, 66 * 8 } // 1 of 4 +#endif } }; diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 9175bdaf5..9135ab957 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -3582,18 +3582,18 @@ static int CmdT55xxSetDeviceConfig(const char *Cmd) { configurations.m[T55XX_DLMODE_FIXED].write_3 = 0; // long leading reference - configurations.m[T55XX_DLMODE_LLR].start_gap = 31 * 8; - configurations.m[T55XX_DLMODE_LLR].write_gap = 20 * 8; - configurations.m[T55XX_DLMODE_LLR].write_0 = 18 * 8; - configurations.m[T55XX_DLMODE_LLR].write_1 = 50 * 8; + configurations.m[T55XX_DLMODE_LLR].start_gap = 29 * 8; + configurations.m[T55XX_DLMODE_LLR].write_gap = 17 * 8; + configurations.m[T55XX_DLMODE_LLR].write_0 = 15 * 8; + configurations.m[T55XX_DLMODE_LLR].write_1 = 47 * 8; configurations.m[T55XX_DLMODE_LLR].read_gap = 15 * 8; configurations.m[T55XX_DLMODE_LLR].write_2 = 0; configurations.m[T55XX_DLMODE_LLR].write_3 = 0; // leading zero - configurations.m[T55XX_DLMODE_LEADING_ZERO].start_gap = 31 * 8; - configurations.m[T55XX_DLMODE_LEADING_ZERO].write_gap = 20 * 8; - configurations.m[T55XX_DLMODE_LEADING_ZERO].write_0 = 18 * 8; + configurations.m[T55XX_DLMODE_LEADING_ZERO].start_gap = 29 * 8; + configurations.m[T55XX_DLMODE_LEADING_ZERO].write_gap = 17 * 8; + configurations.m[T55XX_DLMODE_LEADING_ZERO].write_0 = 15 * 8; configurations.m[T55XX_DLMODE_LEADING_ZERO].write_1 = 40 * 8; configurations.m[T55XX_DLMODE_LEADING_ZERO].read_gap = 15 * 8; configurations.m[T55XX_DLMODE_LEADING_ZERO].write_2 = 0; From e0d4e69cb9c263c6728ee7fb49ff1a5eeb113f5f Mon Sep 17 00:00:00 2001 From: Iceman Date: Wed, 13 Nov 2019 16:21:28 +0100 Subject: [PATCH 1140/1854] Update Mac-OS-X-Homebrew-Installation-Instructions.md textual --- .../Mac-OS-X-Homebrew-Installation-Instructions.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md b/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md index f78016df9..76f5ee6f3 100644 --- a/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md @@ -9,7 +9,11 @@ For further questions about Mac & Homebrew, contact @Chrisfu (https://github.c 2. Tap this repo: `brew tap RfidResearchGroup/proxmark3` -3. Install Proxmark3: `brew install proxmark3` for stable release or `brew install --HEAD proxmark3` for latest non-stable from GitHub. +3. Install Proxmark3: + - (Optional) `export HOMEBREW_PROXMARK3_PLATFORM=xxxxxx` to specify [platform](https://github.com/RfidResearchGroup/proxmark3/blob/master/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md#platform), default value is `PM3RDV4` if none + - `brew install proxmark3` for stable release + - `brew install --HEAD proxmark3` for latest non-stable from GitHub (use this if previous command fails) + - `brew install --with-blueshark proxmark3` for blueshark support For more info, go to https://github.com/RfidResearchGroup/homebrew-proxmark3 From ead825720d9d3928ad4183a8be9a47078794f48c Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 17 Nov 2019 11:45:20 +0100 Subject: [PATCH 1141/1854] covsubmit: avoid aborting when previous data are not present --- covsubmit.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/covsubmit.sh b/covsubmit.sh index dcfda0999..e39240954 100755 --- a/covsubmit.sh +++ b/covsubmit.sh @@ -6,7 +6,7 @@ set -e pre_submit_hook ## delete all previous tarballs -rm proxmark3.all.*.tgz proxmark3.all.*.log +rm -f proxmark3.all.*.tgz proxmark3.all.*.log TODAY="$(date --date now +%Y%m%d.%H%M)" VERSION="0.1.$TODAY" From 5dc2c7c3929c42ae0749c85e8d806938a6ac8c9b Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 17 Nov 2019 11:47:08 +0100 Subject: [PATCH 1142/1854] pm3 serial detection on Linux more robust. Fixes #475 Official firmwares < 2018.02 had a different USB Model string (PM3<>proxmark3). Better to detect based on the vendor string (proxmark.org) which is more stable, to ease reflashing devices with old firmwares to the RDV4 firmware. Thanks @fishilico for having pointed it out. --- pm3 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pm3 b/pm3 index c3bed278e..a03b3351e 100755 --- a/pm3 +++ b/pm3 @@ -21,7 +21,7 @@ PM3LIST=() function get_pm3_list_Linux { PM3LIST=() for DEV in $(find /dev/ttyACM* 2>/dev/null); do - if udevadm info -q property -n "$DEV" |grep -q "ID_MODEL=proxmark3"; then + if udevadm info -q property -n "$DEV" |grep -q "ID_VENDOR=proxmark.org"; then PM3LIST+=("$DEV") fi done From dec0b0202a5cd0fa3aaba53e34f4dacf8f5fb5ab Mon Sep 17 00:00:00 2001 From: Denis Bodor Date: Sun, 17 Nov 2019 12:58:30 +0100 Subject: [PATCH 1143/1854] Add Luxeo dump script --- client/luascripts/luxeodump.lua | 309 ++++++++++++++++++++++++++++++++ 1 file changed, 309 insertions(+) create mode 100644 client/luascripts/luxeodump.lua diff --git a/client/luascripts/luxeodump.lua b/client/luascripts/luxeodump.lua new file mode 100644 index 000000000..182af67d4 --- /dev/null +++ b/client/luascripts/luxeodump.lua @@ -0,0 +1,309 @@ +--- +-- This Lua script is designed to run with Iceman/RRG Proxmark3 fork +-- Just copy luxeodump.lua to client/luascripts/ +-- and run "script run luxeodump" + +-- requirements +local cmds = require('commands') +local getopt = require('getopt') +local utils = require('utils') +local lib14a = require('read14a') +local ansicolors = require('ansicolors') + +copyright = '' +author = '0xdrrb' +version = 'v0.1.0' +desc = [[ +This is a script to dump and decrypt the data of a specific type of Mifare laundromat token. +]] +example = [[ + script run luxeodump +]] +usage = [[ +script run luxeodump +]] + +local PM3_SUCCESS = 0 + +-- Some shortcuts +local band = bit32.band +local bor = bit32.bor +local bnot = bit32.bnot +local bxor = bit32.bxor +local lsh = bit32.lshift +local rsh = bit32.rshift + +local acgreen = ansicolors.bright..ansicolors.green +local accyan = ansicolors.bright..ansicolors.cyan +local acred = ansicolors.red +local acyellow = ansicolors.bright..ansicolors.yellow +local acblue = ansicolors.bright..ansicolors.blue +local acmagenta = ansicolors.bright..ansicolors.magenta +local acoff = ansicolors.reset + + +-- This is only meant to be used when errors occur +local function oops(err) + print('ERROR: ', err) + core.clearCommandBuffer() + return nil, err +end + +local function setdevicedebug( status ) + local c = 'hw dbg ' + if status then + c = c..'1' + else + c = c..'0' + end + core.console(c) +end + +local function xteaCrypt(num_rounds, v, key) + local v0 = v[0] + local v1 = v[1] + local delta = 0x9E3779B9 + local sum = 0 + + for i = 0, num_rounds-1 do + -- v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]); + v0 = band(bxor(bxor(lsh(v1,4), rsh(v1,5)) + v1, sum + key[band(sum,3)]) + v0, 0xFFFFFFFF) + sum = band(sum + delta, 0xFFFFFFFF) + -- v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum>>11) & 3]); + v1 = band(bxor(bxor(lsh(v0,4), rsh(v0,5)) + v0, sum + key[band(rsh(sum,11),3)]) + v1, 0xFFFFFFFF) + end + v[0]=v0 + v[1]=v1 +end + +local function xteaDecrypt(num_rounds, v, key) + local v0 = v[0] + local v1 = v[1] + local delta = 0x9E3779B9 + local sum = band(delta * num_rounds, 0xFFFFFFFF) + + for i = 0, num_rounds-1 do + -- v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum>>11) & 3]); + v1 = band(v1 - bxor(bxor(lsh(v0,4), rsh(v0,5)) + v0, sum + key[band(rsh(sum,11),3)]), 0xFFFFFFFF) + sum = band(sum - delta, 0xFFFFFFFF) + -- v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]); + v0 = band(v0 - bxor(bxor(lsh(v1,4), rsh(v1,5)) + v1, sum + key[band(sum,3)]), 0xFFFFFFFF) + end + v[0]=v0 + v[1]=v1 +end + +local function createxteakey(mfuid) + local xteakey = {} + local buid = {} + local tmpkey = {} + local uid = {} + + -- Warning ! "it is customary in Lua to START ARRAYS WITH ONE" + buid = utils.ConvertHexToBytes(mfuid) + uid[0] = bor(buid[1], lsh(buid[2], 8)) + uid[1] = bor(buid[3], lsh(buid[4], 8)) + + tmpkey[0] = 0x198B + tmpkey[1] = uid[0] + tmpkey[2] = 0x46D8 + tmpkey[3] = uid[1] + tmpkey[4] = 0x5310 + tmpkey[5] = bxor(uid[0], 0xA312) + tmpkey[6] = 0xFFCB + tmpkey[7] = bxor(uid[1], 0x55AA) + + xteakey[0] = bor(lsh(tmpkey[1], 16), tmpkey[0]) + xteakey[1] = bor(lsh(tmpkey[3], 16), tmpkey[2]) + xteakey[2] = bor(lsh(tmpkey[5], 16), tmpkey[4]) + xteakey[3] = bor(lsh(tmpkey[7], 16), tmpkey[6]) + + return xteakey +end + +-- CRC16/ARC from core.reveng_runmodel() does not seem to return the right values. +-- So here is an implementation in Lua. +local function bitreflect(data, nbits) + local output = 0 + for i = 0, nbits-1 do + if bit.band(data,1) ~= 0 then + output = bit32.bor(output, bit32.lshift(1,((nbits - 1) - i))) + else + end + data = bit32.rshift(data,1) + end + return output +end + +local function crc16arc(s) + assert(type(s) == 'string') + local crc = 0x0000 + for i = 1, #s do + local c = s:byte(i) + dbyte = bitreflect(c, 8) + crc = bit32.bxor(crc, bit32.lshift(dbyte,8)) + for j = 0, 7 do + local mix = bit32.band(crc, 0x8000) + crc = bit32.lshift(crc,1) + if mix ~= 0 then + crc = bit32.bxor(crc, 0x8005) + end + end + end + return bitreflect(crc, 16) +end + +local function getblockdata(response) + if not response then + return nil, 'No response from device' + end + if response.Status == PM3_SUCCESS then + return response.Data + else + return nil, "Couldn't read block.. ["..response.Status.."]" + end +end + +local function readblock(blockno, key) + -- Read block N + local keytype = '01' -- key B + local data = ('%02x%s%s'):format(blockno, keytype, key) + local c = Command:newNG{cmd = cmds.CMD_HF_MIFARE_READBL, data = data} + local b, err = getblockdata(c:sendNG(false)) + if not b then return oops(err) end + return b +end + +local function readtag(mfkey,xteakey) + local tagdata = {} + local cleardata = {} + local v = {} + local vv = {} + + -- Read 4 sectors and build table + for sect = 8, 11 do + for blockn = sect*4, (sect*4)+2 do + local blockdata = readblock(blockn, mfkey) + if not blockdata then return oops('[!] failed reading block') end + table.insert(tagdata, blockdata) + end + end + + -- Decrypt data and build clear table + for key,value in ipairs(tagdata) do + local clearblockdata + v[0]=utils.SwapEndianness(value:sub(1,8),32) + v[1]=utils.SwapEndianness(value:sub(9,16),32) + xteaDecrypt(16, v, xteakey) + vv[0]=utils.SwapEndianness(value:sub(17,24),32) + vv[1]=utils.SwapEndianness(value:sub(25,32),32) + xteaDecrypt(16, vv, xteakey) + clearblockdata=string.format("%08X%08X%08X%08X", + utils.SwapEndianness(string.format("%08X", v[0]),32), + utils.SwapEndianness(string.format("%08X", v[1]),32), + utils.SwapEndianness(string.format("%08X", vv[0]),32), + utils.SwapEndianness(string.format("%08X", vv[1]),32)) + table.insert(cleardata, clearblockdata) + end + + return tagdata,cleardata + +end + + +local function main(args) + local xteakey = {} + -- local v = {} + local edata = {} + local cdata = {} + + -- Turn off Debug + setdevicedebug(false) + + -- GET TAG UID + tag, err = lib14a.read(false, true) + if err then + lib14a.disconnect() + return oops(err) + end + core.clearCommandBuffer() + + -- simple tag check + if 0x08 ~= tag.sak then + if 0x0400 ~= tag.atqa then + return oops(('[fail] found tag %s :: looking for Mifare S50 1k'):format(tag.name)) + end + end + + xteakey = createxteakey(tag.uid) + print(acblue.."UID: "..tag.uid..acoff) + print(acblue..string.format("XTEA key: %08X %08X %08X %08X", xteakey[0], xteakey[1], xteakey[2], xteakey[3])..acoff) + + edata, cdata = readtag("415A54454B4D",xteakey) + + if edata == nil or cdata == nil then + print("ERROR Reading tag!") + return nil + end + + print("Ciphered data:") + for key,value in ipairs(edata) do + print(value) + if key % 3 == 0 then print("") end + end + + -- compute CRC for each segment + crcH = crc16arc(utils.ConvertHexToAscii(cdata[1]..cdata[2]..cdata[3]:sub(1,28))) + crcA = crc16arc(utils.ConvertHexToAscii(cdata[4]..cdata[5]..cdata[6]..cdata[7]:sub(1,28))) + crcB = crc16arc(utils.ConvertHexToAscii(cdata[8]..cdata[9]..cdata[10]..cdata[11]:sub(1,28))) + + print("\nHeader:") + for key,value in ipairs(cdata) do + if key == 3 then + print(value:sub(1,28)..acmagenta..value:sub(29,32)..acoff) + if utils.SwapEndianness(value:sub(29,32),16) == crcH then strcrc = " OK" else strcrc = acred.." CRCERROR !!" end + print(acmagenta.."CRC16/ARC = "..string.format("0x%04X", crcH)..strcrc..acoff) + print("\nDataA:") + elseif key == 4 then + print(acgreen..value:sub(1,4)..acoff..value:sub(5,16)..accyan..value:sub(17,24)..acoff..value:sub(25,26)..accyan..value:sub(27,28)..acoff..value:sub(29,32)) + versionA = utils.SwapEndianness(value:sub(1,4),16) + dateA = string.format("%d/%02d/%02d %02d:%02d", tonumber(value:sub(17,18),10)+2000, tonumber(value:sub(19,20),10), + tonumber(string.format("%02X", band(tonumber(value:sub(21,22),16),0x3f)),10), + tonumber(value:sub(23,24),10), tonumber(value:sub(27,28),10)) + elseif key == 8 then + print(acgreen..value:sub(1,4)..acoff..value:sub(5,16)..accyan..value:sub(17,24)..acoff..value:sub(25,26)..accyan..value:sub(27,28)..acoff..value:sub(29,32)) + versionB = utils.SwapEndianness(value:sub(1,4),16) + dateB = string.format("%d/%02d/%02d %02d:%02d", tonumber(value:sub(17,18),10)+2000, tonumber(value:sub(19,20),10), + tonumber(string.format("%02X", band(tonumber(value:sub(21,22),16),0x3f)),10), + tonumber(value:sub(23,24),10), tonumber(value:sub(27,28),10)) + elseif key == 5 then + print(acyellow..value:sub(1,4)..acoff..value:sub(5,32)) + creditA = utils.SwapEndianness(value:sub(1,4),16)/100 + elseif key == 9 then + print(acyellow..value:sub(1,4)..acoff..value:sub(5,32)) + creditB = utils.SwapEndianness(value:sub(1,4),16)/100 + elseif key == 7 then + print(value:sub(1,28)..acmagenta..value:sub(29,32)..acoff) + print(acgreen.."Version "..string.format("0x%04X", versionA)..acoff) + print(acyellow.."Credit : "..creditA..acoff) + if utils.SwapEndianness(value:sub(29,32),16) == crcA then strcrc = " OK" else strcrc = acred.." CRCERROR !!" end + print(acmagenta.."CRC16/ARC = "..string.format("0x%04X", crcA)..strcrc..acoff) + print(accyan.."Date: "..dateA..acoff) + print("\nDataB:") + elseif key == 11 then + print(value:sub(1,28)..acmagenta..value:sub(29,32)..acoff) + print(acgreen.."Version "..string.format("0x%04X", versionB)..acoff) + print(acyellow.."Credit : "..creditB..acoff) + if utils.SwapEndianness(value:sub(29,32),16) == crcB then strcrc = " OK" else strcrc = acred.." CRCERROR !!" end + print(acmagenta.."CRC16/ARC = "..string.format("0x%04X", crcB)..strcrc..acoff) + print(accyan.."Date: "..dateB..acoff) + print("\nFooter:") + else + print(value) + end + end + + return +end + +main(args) From 5e85d53c3e272f280f689d7f38dc2ce48e9aecbb Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 18 Nov 2019 13:11:28 +0100 Subject: [PATCH 1144/1854] pm3 serial detection on OS X more robust Official firmwares < 2018.02 had a different USB Model string (PM3<>proxmark3). Better to detect based on the vendor string (proxmark.org) which is more stable, to ease reflashing devices with old firmwares to the RDV4 firmware. --- pm3 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pm3 b/pm3 index a03b3351e..d40fb0a91 100755 --- a/pm3 +++ b/pm3 @@ -29,7 +29,9 @@ function get_pm3_list_Linux { function get_pm3_list_macOS { PM3LIST=() - for DEV in $(ioreg -r -n proxmark3 -l|awk -F '"' '/IODialinDevice/{print $4}'); do + for DEV in $(ioreg -r -c "IOUSBHostDevice" -l|awk -F '"' ' + $2=="USB Vendor Name"{b=($4=="proxmark.org")} + b==1 && $2=="IODialinDevice"{print $4}'); do PM3LIST+=("$DEV") done } From 585ce7556c8aeb8d592085633d51fed70fb233df Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 18 Nov 2019 18:48:21 +0100 Subject: [PATCH 1145/1854] add empty command to enable client side to break loops on device side, like sim --- armsrc/appmain.c | 2 ++ include/pm3_cmd.h | 3 +++ 2 files changed, 5 insertions(+) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index ef96d9fef..ef4dc6a6c 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -696,6 +696,8 @@ static void PacketReceived(PacketCommandNG *packet) { */ switch (packet->cmd) { + case CMD_BREAK_LOOP: + break; case CMD_QUIT_SESSION: { reply_via_fpc = false; reply_via_usb = false; diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 0f7212600..892ec533f 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -288,6 +288,7 @@ typedef struct { #define CMD_STANDALONE 0x0115 #define CMD_WTX 0x0116 #define CMD_TIA 0x0117 +#define CMD_BREAK_LOOP 0x0118 // RDV40, Flash memory operations #define CMD_FLASHMEM_WRITE 0x0121 @@ -550,6 +551,8 @@ typedef struct { // Error codes Usages: +// Success, transfer nonces pm3: Sending nonces back to client +#define PM3_SNONCES 1 // Success (no error) #define PM3_SUCCESS 0 From c36b414f0f3674a0ecc18fae3b40be58743285ef Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 19 Nov 2019 08:32:30 +0100 Subject: [PATCH 1146/1854] ignore old/swp files --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 348195eba..092ad9619 100644 --- a/.gitignore +++ b/.gitignore @@ -26,6 +26,8 @@ *.dsym version.c *.json +*.old +*.swp # new build file for add-ons. Makefile.platform From d8a26e2b8b7ef7dfe4411cb5e069c2730d177941 Mon Sep 17 00:00:00 2001 From: Denis Bodor Date: Tue, 19 Nov 2019 10:55:17 +0100 Subject: [PATCH 1147/1854] switch from lua CRC16/ARC to CRC RevEng --- CHANGELOG.md | 1 + client/luascripts/luxeodump.lua | 38 +++------------------------------ 2 files changed, 4 insertions(+), 35 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 89a04d651..16354bcac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -372,6 +372,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Added `hf fido` `assert` and `make` commands from fido2 protocol (authenticatorMakeCredential and authenticatorGetAssertion) (@merlokk) - Added trailer block decoding to `hf mf rdbl` and `hf mf cgetbl` (@merlokk) - Added `hf mf mad` and `hf mfp mad` MAD decode, check and print commands (@merlokk) + - Add `script run luxeodump` (@0xdrrb) ### Fixed diff --git a/client/luascripts/luxeodump.lua b/client/luascripts/luxeodump.lua index 182af67d4..6b7254801 100644 --- a/client/luascripts/luxeodump.lua +++ b/client/luascripts/luxeodump.lua @@ -121,38 +121,6 @@ local function createxteakey(mfuid) return xteakey end --- CRC16/ARC from core.reveng_runmodel() does not seem to return the right values. --- So here is an implementation in Lua. -local function bitreflect(data, nbits) - local output = 0 - for i = 0, nbits-1 do - if bit.band(data,1) ~= 0 then - output = bit32.bor(output, bit32.lshift(1,((nbits - 1) - i))) - else - end - data = bit32.rshift(data,1) - end - return output -end - -local function crc16arc(s) - assert(type(s) == 'string') - local crc = 0x0000 - for i = 1, #s do - local c = s:byte(i) - dbyte = bitreflect(c, 8) - crc = bit32.bxor(crc, bit32.lshift(dbyte,8)) - for j = 0, 7 do - local mix = bit32.band(crc, 0x8000) - crc = bit32.lshift(crc,1) - if mix ~= 0 then - crc = bit32.bxor(crc, 0x8005) - end - end - end - return bitreflect(crc, 16) -end - local function getblockdata(response) if not response then return nil, 'No response from device' @@ -253,9 +221,9 @@ local function main(args) end -- compute CRC for each segment - crcH = crc16arc(utils.ConvertHexToAscii(cdata[1]..cdata[2]..cdata[3]:sub(1,28))) - crcA = crc16arc(utils.ConvertHexToAscii(cdata[4]..cdata[5]..cdata[6]..cdata[7]:sub(1,28))) - crcB = crc16arc(utils.ConvertHexToAscii(cdata[8]..cdata[9]..cdata[10]..cdata[11]:sub(1,28))) + crcH = utils.SwapEndianness(core.reveng_runmodel("CRC-16/ARC", cdata[1]..cdata[2]..cdata[3]:sub(1,28), false, '0'),16) + crcA = utils.SwapEndianness(core.reveng_runmodel("CRC-16/ARC", cdata[4]..cdata[5]..cdata[6]..cdata[7]:sub(1,28), false, '0'),16) + crcB = utils.SwapEndianness(core.reveng_runmodel("CRC-16/ARC", cdata[8]..cdata[9]..cdata[10]..cdata[11]:sub(1,28), false, '0'),16) print("\nHeader:") for key,value in ipairs(cdata) do From 290c6f6c3126efe50dc04cbf236a76a24e5afdf6 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 19 Nov 2019 12:01:04 +0100 Subject: [PATCH 1148/1854] chg: hf 14a sim x - device simulation loop exited when client exits --- client/cmdhf14a.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index 2f8473d1c..777b7d25c 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -512,8 +512,9 @@ int CmdHF14ASim(const char *Cmd) { PacketResponseNG resp; PrintAndLogEx(SUCCESS, "press pm3-button to abort simulation"); + bool keypress = kbd_enter_pressed(); + while (!keypress) { - while (!kbd_enter_pressed()) { if (WaitForResponseTimeout(CMD_HF_MIFARE_SIMULATE, &resp, 1500) == 0) continue; if (resp.status != PM3_SUCCESS) break; @@ -521,7 +522,15 @@ int CmdHF14ASim(const char *Cmd) { nonces_t *data = (nonces_t *)resp.data.asBytes; readerAttack(data[0], setEmulatorMem, verbose); + + keypress = kbd_enter_pressed(); } + + if (keypress && (flags & FLAG_NR_AR_ATTACK) == FLAG_NR_AR_ATTACK) { + // inform device to break the sim loop since client has exited + SendCommandNG(CMD_BREAK_LOOP, NULL, 0); + } + if (resp.status == PM3_EOPABORTED && ((flags & FLAG_NR_AR_ATTACK) == FLAG_NR_AR_ATTACK)) showSectorTable(); From 3a7a6cce38331e06de0673fd51285d1ce05a1ce8 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 19 Nov 2019 12:14:58 +0100 Subject: [PATCH 1149/1854] chg: hf thin info - honor verbose --- client/cmdhfthinfilm.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/client/cmdhfthinfilm.c b/client/cmdhfthinfilm.c index 6f36a0a9b..dad67509b 100644 --- a/client/cmdhfthinfilm.c +++ b/client/cmdhfthinfilm.c @@ -155,10 +155,12 @@ int infoThinFilm(bool verbose) { } if (resp.status == PM3_SUCCESS) { - if (resp.length == 16 || resp.length == 32 || verbose) { + if (resp.length == 16 || resp.length == 32) { print_barcode(resp.data.asBytes, resp.length, verbose); } else { - PrintAndLogEx(WARNING, "Response is wrong length. (%d)", resp.length); + if (verbose) + PrintAndLogEx(WARNING, "Response is wrong length. (%d)", resp.length); + return PM3_ESOFT; } } From 41e0bf9a5056333fb9838b04dbb9288bc6105f77 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 19 Nov 2019 12:17:08 +0100 Subject: [PATCH 1150/1854] chg: odl flexpass code removed --- client/cmdlf.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/client/cmdlf.c b/client/cmdlf.c index e0238b0d6..236bfc526 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -1054,10 +1054,9 @@ int CmdLFSimBidir(const char *Cmd) { return PM3_SUCCESS; } -// ICEMAN, todo, swap from Graphbuffer. -// according to Westhus this demod uses decimated samples / 2. -// need to do complete rewrite. Need access to reader / chip -// should be extracted to seperate files aswell +// ICEMAN, Verichip is Animal tag. Tested against correct reader +/* + int CmdVchDemod(const char *Cmd) { if (GraphTraceLen < 4096) { @@ -1081,6 +1080,8 @@ int CmdVchDemod(const char *Cmd) { 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, }; + // iceman, using correlate as preamble detect seems way better than our current memcompare + // So first, we correlate for the sync pattern, and mark that. int bestCorrel = 0, bestPos = 0; int i, j, sum = 0; @@ -1135,6 +1136,7 @@ int CmdVchDemod(const char *Cmd) { } return PM3_SUCCESS; } +*/ static bool CheckChipType(bool getDeviceData) { @@ -1168,6 +1170,7 @@ out: } int CmdLFfind(const char *Cmd) { + int retval = PM3_SUCCESS; int ans = 0; size_t minLength = 2000; char cmdp = tolower(param_getchar(Cmd, 0)); @@ -1208,7 +1211,7 @@ int CmdLFfind(const char *Cmd) { } if (readMotorolaUid()) { - PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Motorola ID") "found!"); + PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Motorola FlexPass ID") "found!"); return PM3_SUCCESS; } @@ -1250,7 +1253,6 @@ int CmdLFfind(const char *Cmd) { if (demodGallagher() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("GALLAGHER ID") "found!"); goto out;} // if (demodTI() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Texas Instrument ID") "found!"); goto out;} //if (demodFermax() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Fermax ID") "found!"); goto out;} - //if (demodFlex() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Motorola FlexPass ID") "found!"); goto out;} PrintAndLogEx(FAILED, _RED_("No known 125/134 kHz tags found!")); @@ -1291,12 +1293,15 @@ int CmdLFfind(const char *Cmd) { PrintAndLogEx(FAILED, _RED_("\nNo data found!")); } + + retval = PM3_ESOFT; + out: // identify chipset if (CheckChipType(isOnline) == false) { PrintAndLogEx(DEBUG, "Automatic chip type detection " _RED_("failed")); } - return PM3_SUCCESS; + return retval; } static command_t CommandTable[] = { @@ -1340,7 +1345,7 @@ static command_t CommandTable[] = { {"sniff", CmdLFSniff, IfPm3Lf, "Sniff LF traffic between reader and tag"}, {"tune", CmdLFTune, IfPm3Lf, "Continuously measure LF antenna tuning"}, // {"vchdemod", CmdVchDemod, AlwaysAvailable, "['clone'] -- Demodulate samples for VeriChip"}, - {"flexdemod", CmdFlexdemod, AlwaysAvailable, "Demodulate samples for Motorola FlexPass"}, +// {"flexdemod", CmdFlexdemod, AlwaysAvailable, "Demodulate samples for Motorola FlexPass"}, {NULL, NULL, NULL, NULL} }; From 1b6566cd5c0afc30cbfd7e2d341b71ef74e0ab48 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 22 Nov 2019 13:55:09 +0200 Subject: [PATCH 1151/1854] Added support for some ISO15693 custom NXP commands --- client/cmdhf15.c | 80 +++++++++++++++++++++++++----------------- client/cmdhflist.c | 72 +++++++++++++++++++++++++++++++++++++ common/iso15693tools.h | 54 ++++++++++++++++++++-------- include/protocols.h | 50 +++++++++++++++++++------- 4 files changed, 195 insertions(+), 61 deletions(-) diff --git a/client/cmdhf15.c b/client/cmdhf15.c index f6c298f63..883364607 100644 --- a/client/cmdhf15.c +++ b/client/cmdhf15.c @@ -85,10 +85,11 @@ const productName uidmapping[] = { //I-Code SLI-S [IC id = 02] //I-Code SLI-L [IC id = 03] //I-Code SLIX [IC id = 01 + bit36 set to 1 (starting from bit0 - different from normal SLI)] + //I-Code SLIX2 [IC id = 01 + bit35 set to 1 + bit36 set to 0] //I-Code SLIX-S [IC id = 02 + bit36 set to 1] //I-Code SLIX-L [IC id = 03 + bit36 set to 1] { 0xE004000000000000LL, 16, "NXP Semiconductors Germany (Philips)" }, - { 0xE004010000000000LL, 24, "NXP(Philips); IC SL2 ICS20/ICS21(SLI) ICS2002/ICS2102(SLIX)" }, + { 0xE004010000000000LL, 24, "NXP(Philips); IC SL2 ICS20/ICS21(SLI) ICS2002/ICS2102(SLIX) ICS2602(SLIX2)" }, { 0xE004020000000000LL, 24, "NXP(Philips); IC SL2 ICS53/ICS54(SLI-S) ICS5302/ICS5402(SLIX-S)" }, { 0xE004030000000000LL, 24, "NXP(Philips); IC SL2 ICS50/ICS51(SLI-L) ICS5002/ICS5102(SLIX-L)" }, @@ -237,7 +238,7 @@ static int getUID(uint8_t *buf) { } } // retry - return 0; + return PM3_SUCCESS; } // get a product description based on the UID @@ -297,12 +298,12 @@ static int CmdHF15Help(const char *Cmd); static int usage_15_demod(void) { PrintAndLogEx(NORMAL, "Tries to demodulate / decode ISO15693, from downloaded samples.\n" "Gather samples with 'hf 15 read' / 'hf 15 record'"); - return 0; + return PM3_SUCCESS; } static int usage_15_samples(void) { PrintAndLogEx(NORMAL, "Acquire samples as Reader (enables carrier, send inquiry\n" "and download it to graphbuffer. Try 'hf 15 demod' to try to demodulate/decode signal"); - return 0; + return PM3_SUCCESS; } static int usage_15_info(void) { PrintAndLogEx(NORMAL, "Uses the optional command 'get_systeminfo' 0x2B to try and extract information\n" @@ -318,11 +319,11 @@ static int usage_15_info(void) { "\t * scan for tag\n" "Examples:\n" "\thf 15 info u"); - return 0; + return PM3_SUCCESS; } static int usage_15_record(void) { - PrintAndLogEx(NORMAL, "Record activity without enableing carrier"); - return 0; + PrintAndLogEx(NORMAL, "Record activity without enabling carrier"); + return PM3_SUCCESS; } static int usage_15_reader(void) { PrintAndLogEx(NORMAL, "This command identifies a ISO 15693 tag\n" @@ -333,23 +334,25 @@ static int usage_15_reader(void) { "\n" "Example:\n" "\thf 15 reader"); - return 0; + return PM3_SUCCESS; } static int usage_15_sim(void) { PrintAndLogEx(NORMAL, "Usage: hf 15 sim \n" "\n" "Example:\n" "\thf 15 sim E016240000000000"); - return 0; + return PM3_SUCCESS; } static int usage_15_findafi(void) { - PrintAndLogEx(NORMAL, "'hf 15 finafi' This command needs a helptext. Feel free to add one!"); - return 0; + PrintAndLogEx(NORMAL, "This command attempts to brute force AFI of an ISO15693 tag\n" + "\n" + "Usage: hf 15 findafi"); + return PM3_SUCCESS; } static int usage_15_dump(void) { PrintAndLogEx(NORMAL, "This command dumps the contents of a ISO-15693 tag and save it to file\n" "\n" - "Usage: hf 15 dump [h] \n" + "Usage: hf 15 dump [h] \n" "Options:\n" "\th this help\n" "\tf filename, if no UID will be used as filename\n" @@ -357,7 +360,7 @@ static int usage_15_dump(void) { "Example:\n" "\thf 15 dump f\n" "\thf 15 dump f mydump"); - return 0; + return PM3_SUCCESS; } static int usage_15_restore(void) { const char *options[][2] = { @@ -371,7 +374,7 @@ static int usage_15_restore(void) { }; PrintAndLogEx(NORMAL, "Usage: hf 15 restore [-2] [-o] [h] [r ] [u ] [f ] [b ]"); PrintAndLogOptions(options, 7, 3); - return 0; + return PM3_SUCCESS; } static int usage_15_raw(void) { const char *options[][2] = { @@ -382,7 +385,7 @@ static int usage_15_raw(void) { }; PrintAndLogEx(NORMAL, "Usage: hf 15 raw [-r] [-2] [-c] <0A 0B 0C ... hex>\n"); PrintAndLogOptions(options, 4, 3); - return 0; + return PM3_SUCCESS; } static int usage_15_read(void) { PrintAndLogEx(NORMAL, "Usage: hf 15 read [options] \n" @@ -393,7 +396,7 @@ static int usage_15_read(void) { "\t u unaddressed mode\n" "\t * scan for tag\n" "\tpage#: page number 0-255"); - return 0; + return PM3_SUCCESS; } static int usage_15_write(void) { PrintAndLogEx(NORMAL, "Usage: hf 15 write [options] \n" @@ -406,7 +409,7 @@ static int usage_15_write(void) { "\t * scan for tag\n" "\tpage#: page number 0-255\n" "\thexdata: data to be written eg AA BB CC DD"); - return 0; + return PM3_SUCCESS; } static int usage_15_readmulti(void) { PrintAndLogEx(NORMAL, "Usage: hf 15 readmulti [options] \n" @@ -418,7 +421,7 @@ static int usage_15_readmulti(void) { "\t * scan for tag\n" "\tstart#: page number to start 0-255\n" "\tcount#: number of pages"); - return 0; + return PM3_SUCCESS; } static int usage_15_csetuid(void) { PrintAndLogEx(NORMAL, "Set UID for magic Chinese card (only works with such cards)\n" @@ -429,7 +432,7 @@ static int usage_15_csetuid(void) { "\n" "Example:\n" "\thf 15 csetuid E011223344556677"); - return 0; + return PM3_SUCCESS; } /** @@ -686,7 +689,7 @@ static int CmdHF15Info(const char *Cmd) { return 0; } -// Record Activity without enabeling carrier +// Record Activity without enabling carrier //helptext static int CmdHF15Record(const char *Cmd) { char cmdp = tolower(param_getchar(Cmd, 0)); @@ -724,8 +727,8 @@ static int CmdHF15Sim(const char *Cmd) { return 0; } -// finds the AFI (Application Family Idendifier) of a card, by trying all values -// (There is no standard way of reading the AFI, allthough some tags support this) +// finds the AFI (Application Family Identifier) of a card, by trying all values +// (There is no standard way of reading the AFI, although some tags support this) // helptext static int CmdHF15Afi(const char *Cmd) { char cmdp = tolower(param_getchar(Cmd, 0)); @@ -856,16 +859,26 @@ static int CmdHF15Dump(const char *Cmd) { size_t datalen = blocknum * 4; saveFileEML(filename, data, datalen, 4); saveFile(filename, ".bin", data, datalen); - return 0; + return PM3_SUCCESS; } static int CmdHF15List(const char *Cmd) { (void)Cmd; // Cmd is not used so far //PrintAndLogEx(WARNING, "Deprecated command, use 'hf list 15' instead"); CmdTraceList("15"); - return 0; + return PM3_SUCCESS; } +/* +// Record Activity without enabling carrier +static int CmdHF15Sniff(const char *Cmd) +{ + clearCommandBuffer(); + SendCommandNG(CMD_HF_ISO15693_SNIFF, NULL, 0); + return PM3_SUCCESS; +} +*/ + static int CmdHF15Raw(const char *Cmd) { char cmdp = param_getchar(Cmd, 0); @@ -939,7 +952,7 @@ static int CmdHF15Raw(const char *Cmd) { PrintAndLogEx(WARNING, "timeout while waiting for reply."); } } - return 0; + return PM3_SUCCESS; } /** @@ -1020,7 +1033,7 @@ static int CmdHF15Readmulti(const char *Cmd) { currblock++; } - return 0; + return PM3_SUCCESS; } /** @@ -1092,7 +1105,7 @@ static int CmdHF15Read(const char *Cmd) { PrintAndLogEx(NORMAL, "------------+---+------"); PrintAndLogEx(NORMAL, "%s| %d | %s", sprint_hex(recv + 2, status - 4), recv[1], sprint_ascii(recv + 2, status - 4)); PrintAndLogEx(NORMAL, ""); - return 0; + return PM3_SUCCESS; } /** @@ -1170,7 +1183,7 @@ static int CmdHF15Write(const char *Cmd) { } PrintAndLogEx(NORMAL, "OK"); - return 0; + return PM3_SUCCESS; } static int CmdHF15Restore(const char *Cmd) { @@ -1257,7 +1270,7 @@ static int CmdHF15Restore(const char *Cmd) { if (bytes_read == 0) { PrintAndLogEx(SUCCESS, "File reading done `%s`", filename); fclose(f); - return 0; + return PM3_SUCCESS; } else if (bytes_read != blocksize) { PrintAndLogEx(ERR, "File reading error (%s), %zu bytes read instead of %zu bytes.", filename, bytes_read, blocksize); fclose(f); @@ -1290,7 +1303,7 @@ static int CmdHF15Restore(const char *Cmd) { } fclose(f); PrintAndLogEx(INFO, "Finish restore"); - return 0; + return PM3_SUCCESS; } /** @@ -1396,7 +1409,8 @@ static command_t CommandTable[] = { {"dump", CmdHF15Dump, IfPm3Iso15693, "Read all memory pages of an ISO15693 tag, save to file"}, {"findafi", CmdHF15Afi, IfPm3Iso15693, "Brute force AFI of an ISO15693 tag"}, {"info", CmdHF15Info, IfPm3Iso15693, "Tag information"}, - {"list", CmdHF15List, AlwaysAvailable, "List ISO15693 history"}, +// {"sniff", CmdHF15Sniff, IfPm3Iso15693, "Sniff ISO15693 traffic"}, + {"list", CmdHF15List, AlwaysAvailable, "List ISO15693 history"}, {"raw", CmdHF15Raw, IfPm3Iso15693, "Send raw hex data to tag"}, {"reader", CmdHF15Reader, IfPm3Iso15693, "Act like an ISO15693 reader"}, {"record", CmdHF15Record, IfPm3Iso15693, "Record Samples (ISO15693)"}, @@ -1406,14 +1420,14 @@ static command_t CommandTable[] = { {"read", CmdHF15Read, IfPm3Iso15693, "Read a block"}, {"write", CmdHF15Write, IfPm3Iso15693, "Write a block"}, {"readmulti", CmdHF15Readmulti, IfPm3Iso15693, "Reads multiple Blocks"}, - {"csetuid", CmdHF15CSetUID, IfPm3Iso15693, "Set UID for magic Chinese card"}, + {"csetuid", CmdHF15CSetUID, IfPm3Iso15693, "Set UID for magic Chinese card"}, {NULL, NULL, NULL, NULL} }; static int CmdHF15Help(const char *Cmd) { (void)Cmd; // Cmd is not used so far CmdsHelp(CommandTable); - return 0; + return PM3_SUCCESS; } int CmdHF15(const char *Cmd) { diff --git a/client/cmdhflist.c b/client/cmdhflist.c index 71ae81926..9f1d9ce23 100644 --- a/client/cmdhflist.c +++ b/client/cmdhflist.c @@ -428,6 +428,78 @@ void annotateIso15693(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) { case ISO15693_READ_MULTI_SECSTATUS: snprintf(exp, size, "READ_MULTI_SECSTATUS"); return; + case ISO15693_INVENTORY_READ: + snprintf(exp, size, "INVENTORY_READ"); + return; + case ISO15693_FAST_INVENTORY_READ: + snprintf(exp, size, "FAST_INVENTORY_READ"); + return; + case ISO15693_SET_EAS: + snprintf(exp, size, "SET_EAS"); + return; + case ISO15693_RESET_EAS: + snprintf(exp, size, "RESET_EAS"); + return; + case ISO15693_LOCK_EAS: + snprintf(exp, size, "LOCK_EAS"); + return; + case ISO15693_EAS_ALARM: + snprintf(exp, size, "EAS_ALARM"); + return; + case ISO15693_PASSWORD_PROTECT_EAS: + snprintf(exp, size, "PASSWORD_PROTECT_EAS"); + return; + case ISO15693_WRITE_EAS_ID: + snprintf(exp, size, "WRITE_EAS_ID"); + return; + case ISO15693_READ_EPC: + snprintf(exp, size, "READ_EPC"); + return; + case ISO15693_GET_NXP_SYSTEM_INFO: + snprintf(exp, size, "GET_NXP_SYSTEM_INFO"); + return; + case ISO15693_INVENTORY_PAGE_READ: + snprintf(exp, size, "INVENTORY_PAGE_READ"); + return; + case ISO15693_FAST_INVENTORY_PAGE_READ: + snprintf(exp, size, "FAST_INVENTORY_PAGE_READ"); + return; + case ISO15693_GET_RANDOM_NUMBER: + snprintf(exp, size, "GET_RANDOM_NUMBER"); + return; + case ISO15693_SET_PASSWORD: + snprintf(exp, size, "SET_PASSWORD"); + return; + case ISO15693_WRITE_PASSWORD: + snprintf(exp, size, "WRITE_PASSWORD"); + return; + case ISO15693_LOCK_PASSWORD: + snprintf(exp, size, "LOCK_PASSWORD"); + return; + case ISO15693_PROTECT_PAGE: + snprintf(exp, size, "PROTECT_PAGE"); + return; + case ISO15693_LOCK_PAGE_PROTECTION: + snprintf(exp, size, "LOCK_PAGE_PROTECTION"); + return; + case ISO15693_GET_MULTI_BLOCK_PROTECTION: + snprintf(exp, size, "GET_MULTI_BLOCK_PROTECTION"); + return; + case ISO15693_DESTROY: + snprintf(exp, size, "DESTROY"); + return; + case ISO15693_ENABLE_PRIVACY: + snprintf(exp, size, "ENABLE_PRIVACY"); + return; + case ISO15693_64BIT_PASSWORD_PROTECTION: + snprintf(exp, size, "64BIT_PASSWORD_PROTECTION"); + return; + case ISO15693_STAYQUIET_PERSISTENT: + snprintf(exp, size, "STAYQUIET_PERSISTENT"); + return; + case ISO15693_READ_SIGNATURE: + snprintf(exp, size, "READ_SIGNATURE"); + return; default: break; } diff --git a/common/iso15693tools.h b/common/iso15693tools.h index 42b2152cc..62ad85499 100644 --- a/common/iso15693tools.h +++ b/common/iso15693tools.h @@ -51,21 +51,45 @@ #define ISO15_ERROR_BLOCL_WRITELOCK 0x14 // Locking was unsuccessful // COMMAND CODES -#define ISO15_CMD_INVENTORY 0x01 -#define ISO15_CMD_STAYQUIET 0x02 -#define ISO15_CMD_READ 0x20 -#define ISO15_CMD_WRITE 0x21 -#define ISO15_CMD_LOCK 0x22 -#define ISO15_CMD_READMULTI 0x23 -#define ISO15_CMD_WRITEMULTI 0x24 -#define ISO15_CMD_SELECT 0x25 -#define ISO15_CMD_RESET 0x26 -#define ISO15_CMD_WRITEAFI 0x27 -#define ISO15_CMD_LOCKAFI 0x28 -#define ISO15_CMD_WRITEDSFID 0x29 -#define ISO15_CMD_LOCKDSFID 0x2A -#define ISO15_CMD_SYSINFO 0x2B -#define ISO15_CMD_SECSTATUS 0x2C +#define ISO15_CMD_INVENTORY 0x01 +#define ISO15_CMD_STAYQUIET 0x02 +#define ISO15_CMD_READ 0x20 +#define ISO15_CMD_WRITE 0x21 +#define ISO15_CMD_LOCK 0x22 +#define ISO15_CMD_READMULTI 0x23 +#define ISO15_CMD_WRITEMULTI 0x24 +#define ISO15_CMD_SELECT 0x25 +#define ISO15_CMD_RESET 0x26 +#define ISO15_CMD_WRITEAFI 0x27 +#define ISO15_CMD_LOCKAFI 0x28 +#define ISO15_CMD_WRITEDSFID 0x29 +#define ISO15_CMD_LOCKDSFID 0x2A +#define ISO15_CMD_SYSINFO 0x2B +#define ISO15_CMD_SECSTATUS 0x2C +#define ISO15_CMD_INVENTORYREAD 0xA0 +#define ISO15_CMD_FASTINVENTORYREAD 0xA1 +#define ISO15_CMD_SETEAS 0xA2 +#define ISO15_CMD_RESETEAS 0xA3 +#define ISO15_CMD_LOCKEAS 0xA4 +#define ISO15_CMD_EASALARM 0xA5 +#define ISO15_CMD_PASSWORDPROTECTEAS 0xA6 +#define ISO15_CMD_WRITEEASID 0xA7 +#define ISO15_CMD_READEPC 0xA8 +#define ISO15_CMD_GETNXPSYSTEMINFO 0xAB +#define ISO15_CMD_INVENTORYPAGEREAD 0xB0 +#define ISO15_CMD_FASTINVENTORYPAGEREAD 0xB1 +#define ISO15_CMD_GETRANDOMNUMBER 0xB2 +#define ISO15_CMD_SETPASSWORD 0xB3 +#define ISO15_CMD_WRITEPASSWORD 0xB4 +#define ISO15_CMD_LOCKPASSWORD 0xB5 +#define ISO15_CMD_PROTECTPAGE 0xB6 +#define ISO15_CMD_LOCKPAGEPROTECTION 0xB7 +#define ISO15_CMD_GETMULTIBLOCKPROTECTION 0xB8 +#define ISO15_CMD_DESTROY 0xB9 +#define ISO15_CMD_ENABLEPRIVACY 0xBA +#define ISO15_CMD_64BITPASSWORDPROTECTION 0xBB +#define ISO15_CMD_STAYQUIETPERSISTENT 0xBC +#define ISO15_CMD_READSIGNATURE 0xBD //----------------------------------------------------------------------------- // Map a sequence of octets (~layer 2 command) into the set of bits to feed diff --git a/include/protocols.h b/include/protocols.h index 2547f01de..8018ae62e 100644 --- a/include/protocols.h +++ b/include/protocols.h @@ -239,19 +239,43 @@ ISO 7816-4 Basic interindustry commands. For command APDU's. #define ISO15693_INVENTORY 0x01 #define ISO15693_STAYQUIET 0x02 //First byte is 02 -#define ISO15693_READBLOCK 0x20 -#define ISO15693_WRITEBLOCK 0x21 -#define ISO15693_LOCKBLOCK 0x22 -#define ISO15693_READ_MULTI_BLOCK 0x23 -#define ISO15693_SELECT 0x25 -#define ISO15693_RESET_TO_READY 0x26 -#define ISO15693_WRITE_AFI 0x27 -#define ISO15693_LOCK_AFI 0x28 -#define ISO15693_WRITE_DSFID 0x29 -#define ISO15693_LOCK_DSFID 0x2A -#define ISO15693_GET_SYSTEM_INFO 0x2B -#define ISO15693_READ_MULTI_SECSTATUS 0x2C - +#define ISO15693_READBLOCK 0x20 +#define ISO15693_WRITEBLOCK 0x21 +#define ISO15693_LOCKBLOCK 0x22 +#define ISO15693_READ_MULTI_BLOCK 0x23 +#define ISO15693_SELECT 0x25 +#define ISO15693_RESET_TO_READY 0x26 +#define ISO15693_WRITE_AFI 0x27 +#define ISO15693_LOCK_AFI 0x28 +#define ISO15693_WRITE_DSFID 0x29 +#define ISO15693_LOCK_DSFID 0x2A +#define ISO15693_GET_SYSTEM_INFO 0x2B +#define ISO15693_READ_MULTI_SECSTATUS 0x2C +// NXP/Philips custom commands +#define ISO15693_INVENTORY_READ 0xA0 +#define ISO15693_FAST_INVENTORY_READ 0xA1 +#define ISO15693_SET_EAS 0xA2 +#define ISO15693_RESET_EAS 0xA3 +#define ISO15693_LOCK_EAS 0xA4 +#define ISO15693_EAS_ALARM 0xA5 +#define ISO15693_PASSWORD_PROTECT_EAS 0xA6 +#define ISO15693_WRITE_EAS_ID 0xA7 +#define ISO15693_READ_EPC 0xA8 +#define ISO15693_GET_NXP_SYSTEM_INFO 0xAB +#define ISO15693_INVENTORY_PAGE_READ 0xB0 +#define ISO15693_FAST_INVENTORY_PAGE_READ 0xB1 +#define ISO15693_GET_RANDOM_NUMBER 0xB2 +#define ISO15693_SET_PASSWORD 0xB3 +#define ISO15693_WRITE_PASSWORD 0xB4 +#define ISO15693_LOCK_PASSWORD 0xB5 +#define ISO15693_PROTECT_PAGE 0xB6 +#define ISO15693_LOCK_PAGE_PROTECTION 0xB7 +#define ISO15693_GET_MULTI_BLOCK_PROTECTION 0xB8 +#define ISO15693_DESTROY 0xB9 +#define ISO15693_ENABLE_PRIVACY 0xBA +#define ISO15693_64BIT_PASSWORD_PROTECTION 0xBB +#define ISO15693_STAYQUIET_PERSISTENT 0xBC +#define ISO15693_READ_SIGNATURE 0xBD // Topaz command set: #define TOPAZ_REQA 0x26 // Request From ef19979c34bdd89edbfeec222a8daad914f28fc0 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 24 Nov 2019 19:27:08 +0100 Subject: [PATCH 1152/1854] chg: hf 14b write - adding colors --- client/cmdhf14b.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/cmdhf14b.c b/client/cmdhf14b.c index ba8db1f92..d02d563f4 100644 --- a/client/cmdhf14b.c +++ b/client/cmdhf14b.c @@ -808,13 +808,13 @@ static int CmdHF14BWriteSri(const char *Cmd) { } if (blockno == 0xff) { - PrintAndLogEx(SUCCESS, "[%s] Write special block %02X [ %s ]", + PrintAndLogEx(SUCCESS, "[%s] Write special block %02X [ " _YELLOW_("%s")" ]", (isSrix4k) ? "SRIX4K" : "SRI512", blockno, sprint_hex(data, 4) ); } else { - PrintAndLogEx(SUCCESS, "[%s] Write block %02X [ %s ]", + PrintAndLogEx(SUCCESS, "[%s] Write block %02X [ " _YELLOW_("%s")" ]", (isSrix4k) ? "SRIX4K" : "SRI512", blockno, sprint_hex(data, 4) From 13c16e9af75311db8b6424de4bdcb1c89d809f12 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 24 Nov 2019 21:14:27 +0100 Subject: [PATCH 1153/1854] return codes --- client/cmdtrace.c | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/client/cmdtrace.c b/client/cmdtrace.c index 67f15be59..7e9b53548 100644 --- a/client/cmdtrace.c +++ b/client/cmdtrace.c @@ -50,21 +50,21 @@ static int usage_trace_list() { PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " trace list 14a f"); PrintAndLogEx(NORMAL, " trace list iclass"); - return 0; + return PM3_SUCCESS; } static int usage_trace_load() { PrintAndLogEx(NORMAL, "Load protocol data from file to trace buffer."); PrintAndLogEx(NORMAL, "Usage: trace load "); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " trace load mytracefile.bin"); - return 0; + return PM3_SUCCESS; } static int usage_trace_save() { PrintAndLogEx(NORMAL, "Save protocol data from trace buffer to file."); PrintAndLogEx(NORMAL, "Usage: trace save "); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " trace save mytracefile.bin"); - return 0; + return PM3_SUCCESS; } static bool is_last_record(uint16_t tracepos, uint8_t *trace, uint16_t traceLen) { @@ -450,7 +450,7 @@ static int CmdTraceLoad(const char *Cmd) { if ((f = fopen(filename, "rb")) == NULL) { PrintAndLogEx(FAILED, "Could not open file " _YELLOW_("%s"), filename); - return 0; + return PM3_EIO; } // get filesize in order to malloc memory @@ -461,12 +461,12 @@ static int CmdTraceLoad(const char *Cmd) { if (fsize < 0) { PrintAndLogEx(FAILED, "error, when getting filesize"); fclose(f); - return 3; + return PM3_EIO; } if (fsize < 4) { PrintAndLogEx(FAILED, "error, file is too small"); fclose(f); - return 4; + return PM3_ESOFT; } if (trace) @@ -476,21 +476,21 @@ static int CmdTraceLoad(const char *Cmd) { if (!trace) { PrintAndLogEx(FAILED, "Cannot allocate memory for trace"); fclose(f); - return 2; + return PM3_EMALLOC; } size_t bytes_read = fread(trace, 1, fsize, f); traceLen = bytes_read; fclose(f); PrintAndLogEx(SUCCESS, "Recorded Activity (TraceLen = %lu bytes) loaded from file %s", traceLen, filename); - return 0; + return PM3_SUCCESS; } static int CmdTraceSave(const char *Cmd) { if (traceLen == 0) { PrintAndLogEx(WARNING, "trace is empty, nothing to save"); - return 0; + return PM3_SUCCESS; } char filename[FILE_PATH_SIZE]; @@ -499,7 +499,7 @@ static int CmdTraceSave(const char *Cmd) { param_getstr(Cmd, 0, filename, sizeof(filename)); saveFile(filename, ".bin", trace, traceLen); - return 0; + return PM3_SUCCESS; } static command_t CommandTable[] = { @@ -513,7 +513,7 @@ static command_t CommandTable[] = { static int CmdHelp(const char *Cmd) { (void)Cmd; // Cmd is not used so far CmdsHelp(CommandTable); - return 0; + return PM3_SUCCESS; } int CmdTrace(const char *Cmd) { @@ -604,15 +604,20 @@ int CmdTraceList(const char *Cmd) { uint16_t tracepos = 0; // reserv some space. - if (!trace) + if (!trace) { trace = calloc(PM3_CMD_DATA_SIZE, sizeof(uint8_t)); + if (trace == NULL) { + PrintAndLogEx(FAILED, "Cannot allocate memory for trace"); + return PM3_EMALLOC; + } + } if (isOnline) { // Query for the size of the trace, downloading PM3_CMD_DATA_SIZE PacketResponseNG response; if (!GetFromDevice(BIG_BUF, trace, PM3_CMD_DATA_SIZE, 0, NULL, 0, &response, 4000, true)) { PrintAndLogEx(WARNING, "timeout while waiting for reply."); - return 1; + return PM3_ETIMEOUT; } traceLen = response.oldarg[2]; @@ -621,13 +626,13 @@ int CmdTraceList(const char *Cmd) { if (p == NULL) { PrintAndLogEx(FAILED, "Cannot allocate memory for trace"); free(trace); - return 2; + return PM3_EMALLOC; } trace = p; if (!GetFromDevice(BIG_BUF, trace, traceLen, 0, NULL, 0, NULL, 2500, false)) { PrintAndLogEx(WARNING, "command execution time out"); free(trace); - return 3; + return PM3_ETIMEOUT; } } } @@ -678,6 +683,6 @@ int CmdTraceList(const char *Cmd) { break; } } - return 0; + return PM3_SUCCESS; } From 16e4cf96796944d4dfc7b1a9de89cb6a7362ec6c Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 25 Nov 2019 20:53:06 +0200 Subject: [PATCH 1154/1854] Add ISO15693 write AFI/DSFID commands and NXP Sysinfo for Slix2 --- client/cmdhf15.c | 334 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 327 insertions(+), 7 deletions(-) diff --git a/client/cmdhf15.c b/client/cmdhf15.c index 883364607..52756215b 100644 --- a/client/cmdhf15.c +++ b/client/cmdhf15.c @@ -31,6 +31,7 @@ #include "comms.h" // clearCommandBuffer #include "cmdtrace.h" #include "iso15693tools.h" +#include "crypto/libpcrypto.h" #include "graph.h" #include "crc16.h" // iso15 crc @@ -207,6 +208,16 @@ const productName uidmapping[] = { { 0, 0, "no tag-info available" } // must be the last entry }; +uint8_t nxp_public_keys[][33] = { + // ICODE SLIX2 / DNA + { + 0x04, 0x88, 0x78, 0xA2, 0xA2, 0xD3, 0xEE, 0xC3, + 0x36, 0xB4, 0xF2, 0x61, 0xA0, 0x82, 0xBD, 0x71, + 0xF9, 0xBE, 0x11, 0xC4, 0xE2, 0xE8, 0x96, 0x64, + 0x8B, 0x32, 0xEF, 0xA5, 0x9C, 0xEA, 0x6E, 0x59, 0xF0 + }, +}; + // fast method to just read the UID of a tag (collission detection not supported) // *buf should be large enough to fit the 64bit uid // returns 1 if suceeded @@ -349,6 +360,24 @@ static int usage_15_findafi(void) { "Usage: hf 15 findafi"); return PM3_SUCCESS; } +static int usage_15_writeafi(void) { + PrintAndLogEx(NORMAL, "Usage: hf 15 writeafi \n" + "\tuid (either): \n" + "\t <8B hex> full UID eg E011223344556677\n" + "\t u unaddressed mode\n" + "\t * scan for tag\n" + "\tafi#: AFI number 0-255"); + return PM3_SUCCESS; +} +static int usage_15_writedsfid(void) { + PrintAndLogEx(NORMAL, "Usage: hf 15 writedsfid \n" + "\tuid (either): \n" + "\t <8B hex> full UID eg E011223344556677\n" + "\t u unaddressed mode\n" + "\t * scan for tag\n" + "\tdsfid#: DSFID number 0-255"); + return PM3_SUCCESS; +} static int usage_15_dump(void) { PrintAndLogEx(NORMAL, "This command dumps the contents of a ISO-15693 tag and save it to file\n" "\n" @@ -605,6 +634,174 @@ static int CmdHF15Samples(const char *Cmd) { return 0; } +// Get NXP system information from SLIX2 tag/VICC +static int NxpSysInfo(uint8_t *uid) { + PacketResponseNG resp; + uint8_t *recv; + uint8_t req[PM3_CMD_DATA_SIZE] = {0}; + uint16_t reqlen; + uint8_t arg1 = 1; + + if (uid != NULL) { + reqlen = 0; + req[reqlen++] |= ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH | ISO15_REQ_NONINVENTORY | ISO15_REQ_ADDRESS; + req[reqlen++] = ISO15_CMD_GETNXPSYSTEMINFO; + req[reqlen++] = 0x04; // IC manufacturer code + memcpy(req + 3, uid, 8); // add UID + reqlen += 8; + + AddCrc15(req, reqlen); + reqlen += 2; + + //PrintAndLogEx(NORMAL, "cmd %s", sprint_hex(req, reqlen) ); + + clearCommandBuffer(); + SendCommandOLD(CMD_HF_ISO15693_COMMAND, reqlen, arg1, 1, req, reqlen); + + if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { + PrintAndLogEx(WARNING, "iso15693 card select failed"); + return 1; + } + + uint32_t status = resp.oldarg[0]; + + if (status < 2) { + PrintAndLogEx(WARNING, "iso15693 card doesn't answer to NXP systeminfo command"); + return 1; + } + + recv = resp.data.asBytes; + + if (recv[0] & ISO15_RES_ERROR) { + PrintAndLogEx(ERR, "iso15693 card returned error %i: %s", recv[0], TagErrorStr(recv[0])); + return 3; + } + + bool signature = false; + bool easmode = false; + + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, " NXP SYSINFO : %s", sprint_hex(recv, 8)); + PrintAndLogEx(NORMAL, " Password protection configuration:"); + PrintAndLogEx(NORMAL, " * Page L read%s password protected", (recv[2] & 0x01 ? "" : " not")); + PrintAndLogEx(NORMAL, " * Page L write%s password protected", (recv[2] & 0x02 ? "" : " not")); + PrintAndLogEx(NORMAL, " * Page H read%s password protected", (recv[2] & 0x08 ? "" : " not")); + PrintAndLogEx(NORMAL, " * Page H write%s password protected", (recv[2] & 0x20 ? "" : " not")); + + PrintAndLogEx(NORMAL, " Lock bits:"); + PrintAndLogEx(NORMAL, " * AFI%s locked", (recv[3] & 0x01 ? "" : " not")); // AFI lock bit + PrintAndLogEx(NORMAL, " * EAS%s locked", (recv[3] & 0x02 ? "" : " not")); // EAS lock bit + PrintAndLogEx(NORMAL, " * DSFID%s locked", (recv[3] & 0x03 ? "" : " not")); // DSFID lock bit + PrintAndLogEx(NORMAL, " * Password protection configuration%s locked", (recv[3] & 0x04 ? "" : " not")); // Password protection pointer address and access conditions lock bit + + PrintAndLogEx(NORMAL, " Features:"); + PrintAndLogEx(NORMAL, " * User memory password protection%s supported", (recv[4] & 0x01 ? "" : " not")); + PrintAndLogEx(NORMAL, " * Counter feature%s supported", (recv[4] & 0x02 ? "" : " not")); + PrintAndLogEx(NORMAL, " * EAS ID%s supported by EAS ALARM command", (recv[4] & 0x03 ? "" : " not")); + easmode = (recv[4] & 0x03 ? true : false); + PrintAndLogEx(NORMAL, " * EAS password protection%s supported", (recv[4] & 0x04 ? "" : " not")); + PrintAndLogEx(NORMAL, " * AFI password protection%s supported", (recv[4] & 0x10 ? "" : " not")); + PrintAndLogEx(NORMAL, " * Extended mode%s supported by INVENTORY READ command", (recv[4] & 0x20 ? "" : " not")); + PrintAndLogEx(NORMAL, " * EAS selection%s supported by extended mode in INVENTORY READ command", (recv[4] & 0x40 ? "" : " not")); + PrintAndLogEx(NORMAL, " * READ SIGNATURE command%s supported", (recv[5] & 0x01 ? "" : " not")); + signature = (recv[5] & 0x01 ? true : false); + PrintAndLogEx(NORMAL, " * Password protection for READ SIGNATURE command%s supported", (recv[5] & 0x02 ? "" : " not")); + PrintAndLogEx(NORMAL, " * STAY QUIET PERSISTENT command%s supported", (recv[5] & 0x03 ? "" : " not")); + PrintAndLogEx(NORMAL, " * ENABLE PRIVACY command%s supported", (recv[5] & 0x10 ? "" : " not")); + PrintAndLogEx(NORMAL, " * DESTROY command%s supported", (recv[5] & 0x20 ? "" : " not")); + PrintAndLogEx(NORMAL, " * Additional 32 bits feature flags are%s transmitted", (recv[5] & 0x80 ? "" : " not")); + + if (easmode) { + reqlen = 0; + req[reqlen++] |= ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH | ISO15_REQ_NONINVENTORY | ISO15_REQ_ADDRESS; + req[reqlen++] = ISO15_CMD_EASALARM; + req[reqlen++] = 0x04; // IC manufacturer code + memcpy(req + 3, uid, 8); // add UID + reqlen += 8; + + AddCrc15(req, reqlen); + reqlen += 2; + + //PrintAndLogEx(NORMAL, "cmd %s", sprint_hex(req, reqlen) ); + + clearCommandBuffer(); + SendCommandOLD(CMD_HF_ISO15693_COMMAND, reqlen, arg1, 1, req, reqlen); + + if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { + PrintAndLogEx(WARNING, "iso15693 card select failed"); + } else { + uint32_t status = resp.oldarg[0]; + + PrintAndLogEx(NORMAL, ""); + + if (status < 2) { + PrintAndLogEx(NORMAL, " EAS (Electronic Article Surveillance) is not active"); + } else { + recv = resp.data.asBytes; + + if (!(recv[0] & ISO15_RES_ERROR)) { + PrintAndLogEx(NORMAL, " EAS (Electronic Article Surveillance) is active."); + PrintAndLogEx(NORMAL, " EAS sequence: %s", sprint_hex(recv + 1, 32)); + } + } + } + } + + if (signature) { + // Check if we can also read the signature + reqlen = 0; + req[reqlen++] |= ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH | ISO15_REQ_NONINVENTORY | ISO15_REQ_ADDRESS; + req[reqlen++] = ISO15_CMD_READSIGNATURE; + req[reqlen++] = 0x04; // IC manufacturer code + memcpy(req + 3, uid, 8); // add UID + reqlen += 8; + + AddCrc15(req, reqlen); + reqlen += 2; + + //PrintAndLogEx(NORMAL, "cmd %s", sprint_hex(req, reqlen) ); + + clearCommandBuffer(); + SendCommandOLD(CMD_HF_ISO15693_COMMAND, reqlen, arg1, 1, req, reqlen); + + if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { + PrintAndLogEx(WARNING, "iso15693 card select failed"); + return 1; + } + + uint32_t status = resp.oldarg[0]; + + if (status < 2) { + PrintAndLogEx(WARNING, "iso15693 card doesn't answer to READ SIGNATURE command"); + return 1; + } + + recv = resp.data.asBytes; + + if (recv[0] & ISO15_RES_ERROR) { + PrintAndLogEx(ERR, "iso15693 card returned error %i: %s", recv[0], TagErrorStr(recv[0])); + return 3; + } + + uint8_t signature[32] = {0x00}; + memcpy(signature, recv + 1, 32); + + int res = ecdsa_signature_r_s_verify(MBEDTLS_ECP_DP_SECP128R1, nxp_public_keys[0], uid, 8, signature, 32, false); + bool is_valid = (res == 0); + + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, " Tag Signature"); + PrintAndLogEx(NORMAL, " IC signature public key name : NXP ICODE SLIX2 / DNA"); + PrintAndLogEx(NORMAL, " IC signature public key value : %s", sprint_hex(nxp_public_keys[0], 33)); + PrintAndLogEx(NORMAL, " Elliptic curve parameters : NID_secp128r1"); + PrintAndLogEx(NORMAL, " TAG IC Signature : %s", sprint_hex(signature, 32)); + PrintAndLogEx(NORMAL, " Signature verification %s", (is_valid) ? _GREEN_("successful") : _RED_("failed")); + } + } + + return PM3_SUCCESS; +} + /** * Commandline handling: HF15 CMD SYSINFO * get system information from tag/VICC @@ -621,6 +818,7 @@ static int CmdHF15Info(const char *Cmd) { uint8_t arg1 = 1; char cmdbuf[100] = {0}; char *cmd = cmdbuf; + uint8_t uid[8] = {0, 0, 0, 0, 0, 0, 0, 0}; strncpy(cmd, Cmd, sizeof(cmdbuf) - 1); @@ -654,7 +852,9 @@ static int CmdHF15Info(const char *Cmd) { return 3; } - PrintAndLogEx(NORMAL, " UID : %s", sprintUID(NULL, recv + 2)); + memcpy(uid, recv + 2, sizeof(uid)); + + PrintAndLogEx(NORMAL, " UID : %s", sprintUID(NULL, uid)); PrintAndLogEx(NORMAL, " TYPE : %s", getTagInfo_15(recv + 2)); PrintAndLogEx(NORMAL, " SYSINFO : %s", sprint_hex(recv, status - 2)); @@ -685,8 +885,15 @@ static int CmdHF15Info(const char *Cmd) { } else { PrintAndLogEx(NORMAL, " - Tag does not provide information on memory layout"); } - PrintAndLogEx(NORMAL, "\n"); - return 0; + + // Check if SLIX2 and attempt to get NXP System Information + if (recv[8] == 0x04 && recv[7] == 0x01 && recv[4] & 0x80) { + return NxpSysInfo(uid); + } + + PrintAndLogEx(NORMAL, ""); + + return PM3_SUCCESS; } // Record Activity without enabling carrier @@ -730,7 +937,7 @@ static int CmdHF15Sim(const char *Cmd) { // finds the AFI (Application Family Identifier) of a card, by trying all values // (There is no standard way of reading the AFI, although some tags support this) // helptext -static int CmdHF15Afi(const char *Cmd) { +static int CmdHF15FindAfi(const char *Cmd) { char cmdp = tolower(param_getchar(Cmd, 0)); if (cmdp == 'h') return usage_15_findafi(); @@ -741,6 +948,118 @@ static int CmdHF15Afi(const char *Cmd) { return 0; } +// Writes the AFI (Application Family Identifier) of a card +static int CmdHF15WriteAfi(const char *Cmd) { + + char cmdp = param_getchar(Cmd, 0); + if (strlen(Cmd) < 3 || cmdp == 'h' || cmdp == 'H') return usage_15_writeafi(); + + PacketResponseNG resp; + uint8_t *recv; + + // 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 req[PM3_CMD_DATA_SIZE] = {0}; + uint16_t reqlen = 0; + uint8_t arg1 = 1; + int afinum; + char cmdbuf[100] = {0}; + char *cmd = cmdbuf; + strncpy(cmd, Cmd, sizeof(cmdbuf) - 1); + + if (!prepareHF15Cmd(&cmd, &reqlen, &arg1, req, ISO15_CMD_WRITEAFI)) + return 0; + + req[0] |= ISO15_REQ_OPTION; // Since we are writing + + afinum = strtol(cmd, NULL, 0); + + req[reqlen++] = (uint8_t)afinum; + + AddCrc15(req, reqlen); + reqlen += 2; + + //PrintAndLogEx(NORMAL, "cmd %s", sprint_hex(req, reqlen) ); + + clearCommandBuffer(); + SendCommandOLD(CMD_HF_ISO15693_COMMAND, reqlen, arg1, 1, req, reqlen); + + if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { + PrintAndLogEx(NORMAL, "iso15693 card select failed"); + return 1; + } + + recv = resp.data.asBytes; + + if (recv[0] & ISO15_RES_ERROR) { + PrintAndLogEx(ERR, "iso15693 card returned error %i: %s", recv[0], TagErrorStr(recv[0])); + return 3; + } + + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(SUCCESS, "Wrote AFI 0x%02X", afinum); + + return PM3_SUCCESS; +} + +// Writes the DSFID (Data Storage Format Identifier) of a card +static int CmdHF15WriteDsfid(const char *Cmd) { + + char cmdp = param_getchar(Cmd, 0); + if (strlen(Cmd) < 3 || cmdp == 'h' || cmdp == 'H') return usage_15_writedsfid(); + + PacketResponseNG resp; + uint8_t *recv; + + // 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 req[PM3_CMD_DATA_SIZE] = {0}; + uint16_t reqlen = 0; + uint8_t arg1 = 1; + int dsfidnum; + char cmdbuf[100] = {0}; + char *cmd = cmdbuf; + strncpy(cmd, Cmd, sizeof(cmdbuf) - 1); + + if (!prepareHF15Cmd(&cmd, &reqlen, &arg1, req, ISO15_CMD_WRITEDSFID)) + return 0; + + req[0] |= ISO15_REQ_OPTION; // Since we are writing + + dsfidnum = strtol(cmd, NULL, 0); + + req[reqlen++] = (uint8_t)dsfidnum; + + AddCrc15(req, reqlen); + reqlen += 2; + + //PrintAndLogEx(NORMAL, "cmd %s", sprint_hex(req, reqlen) ); + + clearCommandBuffer(); + SendCommandOLD(CMD_HF_ISO15693_COMMAND, reqlen, arg1, 1, req, reqlen); + + if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { + PrintAndLogEx(NORMAL, "iso15693 card select failed"); + return 1; + } + + recv = resp.data.asBytes; + + if (recv[0] & ISO15_RES_ERROR) { + PrintAndLogEx(ERR, "iso15693 card returned error %i: %s", recv[0], TagErrorStr(recv[0])); + return 3; + } + + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(SUCCESS, "Wrote DSFID 0x%02X", dsfidnum); + + return PM3_SUCCESS; +} + typedef struct { uint8_t lock; uint8_t block[4]; @@ -871,8 +1190,7 @@ static int CmdHF15List(const char *Cmd) { /* // Record Activity without enabling carrier -static int CmdHF15Sniff(const char *Cmd) -{ +static int CmdHF15Sniff(const char *Cmd) { clearCommandBuffer(); SendCommandNG(CMD_HF_ISO15693_SNIFF, NULL, 0); return PM3_SUCCESS; @@ -1407,7 +1725,9 @@ static command_t CommandTable[] = { {"help", CmdHF15Help, AlwaysAvailable, "This help"}, {"demod", CmdHF15Demod, AlwaysAvailable, "Demodulate ISO15693 from tag"}, {"dump", CmdHF15Dump, IfPm3Iso15693, "Read all memory pages of an ISO15693 tag, save to file"}, - {"findafi", CmdHF15Afi, IfPm3Iso15693, "Brute force AFI of an ISO15693 tag"}, + {"findafi", CmdHF15FindAfi, IfPm3Iso15693, "Brute force AFI of an ISO15693 tag"}, + {"writeafi", CmdHF15WriteAfi, IfPm3Iso15693, "Writes the AFI on an ISO15693 tag"}, + {"writedsfid", CmdHF15WriteDsfid, IfPm3Iso15693, "Writes the DSFID on an ISO15693 tag"}, {"info", CmdHF15Info, IfPm3Iso15693, "Tag information"}, // {"sniff", CmdHF15Sniff, IfPm3Iso15693, "Sniff ISO15693 traffic"}, {"list", CmdHF15List, AlwaysAvailable, "List ISO15693 history"}, From cef28ad2416babef558e8ebd1c329b55bf616647 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 26 Nov 2019 22:11:02 +0200 Subject: [PATCH 1155/1854] HF15 cmds return codes and dropfield where needed --- client/cmdhf.c | 5 +- client/cmdhf15.c | 152 ++++++++++++++++++++++++++++------------------- client/cmdhf15.h | 2 +- 3 files changed, 94 insertions(+), 65 deletions(-) diff --git a/client/cmdhf.c b/client/cmdhf.c index dd21c2649..7a1aaa868 100644 --- a/client/cmdhf.c +++ b/client/cmdhf.c @@ -100,13 +100,10 @@ int CmdHFSearch(const char *Cmd) { PROMPT_CLEARLINE; PrintAndLogEx(INPLACE, "Searching for ISO15693 tag..."); if (IfPm3Iso15693()) { - if (readHF15Uid(false) == 1) { + if (readHF15Uid(false)) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("ISO15693 tag") " found\n"); - DropField(); return PM3_SUCCESS; } - // until refactoring of ISO15693 cmds, this is needed. - DropField(); } PROMPT_CLEARLINE; diff --git a/client/cmdhf15.c b/client/cmdhf15.c index 52756215b..5a69c1343 100644 --- a/client/cmdhf15.c +++ b/client/cmdhf15.c @@ -218,10 +218,10 @@ uint8_t nxp_public_keys[][33] = { }, }; -// fast method to just read the UID of a tag (collission detection not supported) +// fast method to just read the UID of a tag (collision detection not supported) // *buf should be large enough to fit the 64bit uid -// returns 1 if suceeded -static int getUID(uint8_t *buf) { +// returns 1 if succeeded +static bool getUID(uint8_t *buf) { PacketResponseNG resp; uint8_t data[5]; @@ -244,12 +244,14 @@ static int getUID(uint8_t *buf) { uint8_t resplen = resp.oldarg[0]; if (resplen >= 12 && CheckCrc15(resp.data.asBytes, 12)) { memcpy(buf, resp.data.asBytes + 2, 8); - return 1; + DropField(); + return true; } } } // retry - return PM3_SUCCESS; + DropField(); + return false; } // get a product description based on the UID @@ -284,7 +286,7 @@ static const char *TagErrorStr(uint8_t error) { case 0x01: return "The command is not supported"; case 0x02: - return "The command is not recognised"; + return "The command is not recognized"; case 0x03: return "The option is not supported."; case 0x0f: @@ -469,7 +471,7 @@ static int usage_15_csetuid(void) { * Parameters: * **cmd command line */ -static int prepareHF15Cmd(char **cmd, uint16_t *reqlen, uint8_t *arg1, uint8_t *req, uint8_t iso15cmd) { // reqlen arg0 +static bool prepareHF15Cmd(char **cmd, uint16_t *reqlen, uint8_t *arg1, uint8_t *req, uint8_t iso15cmd) { // reqlen arg0 int temp; uint8_t uid[8] = {0x00}; uint32_t tmpreqlen = 0; @@ -496,7 +498,7 @@ static int prepareHF15Cmd(char **cmd, uint16_t *reqlen, uint8_t *arg1, uint8_t * switch (**cmd) { case 0: PrintAndLogEx(WARNING, "missing addr"); - return 0; + return false; break; case 'u': case 'U': @@ -511,7 +513,7 @@ static int prepareHF15Cmd(char **cmd, uint16_t *reqlen, uint8_t *arg1, uint8_t * if (!getUID(uid)) { PrintAndLogEx(WARNING, "No tag found"); - return 0; + return false; } memcpy(&req[tmpreqlen], uid, sizeof(uid)); PrintAndLogEx(NORMAL, "Detected UID %s", sprintUID(NULL, uid)); @@ -538,7 +540,7 @@ static int prepareHF15Cmd(char **cmd, uint16_t *reqlen, uint8_t *arg1, uint8_t * while (**cmd == ' ' || **cmd == '\t')(*cmd)++; *reqlen = tmpreqlen; - return 1; + return true; } // Mode 3 @@ -552,7 +554,7 @@ static int CmdHF15Demod(const char *Cmd) { int max = 0, maxPos = 0; int skip = 4; - if (GraphTraceLen < 1000) return 0; + if (GraphTraceLen < 1000) return PM3_ESOFT; // First, correlate for SOF for (i = 0; i < 1000; i++) { @@ -618,7 +620,7 @@ static int CmdHF15Demod(const char *Cmd) { PrintAndLogEx(NORMAL, "# %2d: %02x ", i, outBuf[i]); PrintAndLogEx(NORMAL, "CRC %04x", Crc15(outBuf, k - 2)); - return 0; + return PM3_SUCCESS; } // * Acquire Samples as Reader (enables carrier, sends inquiry) @@ -631,7 +633,7 @@ static int CmdHF15Samples(const char *Cmd) { SendCommandNG(CMD_HF_ISO15693_ACQ_RAW_ADC, NULL, 0); getSamples(0, false); - return 0; + return PM3_SUCCESS; } // Get NXP system information from SLIX2 tag/VICC @@ -660,21 +662,24 @@ static int NxpSysInfo(uint8_t *uid) { if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { PrintAndLogEx(WARNING, "iso15693 card select failed"); - return 1; + DropField(); + return PM3_ETIMEOUT; } + DropField(); + uint32_t status = resp.oldarg[0]; if (status < 2) { PrintAndLogEx(WARNING, "iso15693 card doesn't answer to NXP systeminfo command"); - return 1; + return PM3_EWRONGANSVER; } recv = resp.data.asBytes; if (recv[0] & ISO15_RES_ERROR) { PrintAndLogEx(ERR, "iso15693 card returned error %i: %s", recv[0], TagErrorStr(recv[0])); - return 3; + return PM3_EWRONGANSVER; } bool signature = false; @@ -766,21 +771,24 @@ static int NxpSysInfo(uint8_t *uid) { if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { PrintAndLogEx(WARNING, "iso15693 card select failed"); - return 1; + DropField(); + return PM3_ETIMEOUT; } + DropField(); + uint32_t status = resp.oldarg[0]; if (status < 2) { PrintAndLogEx(WARNING, "iso15693 card doesn't answer to READ SIGNATURE command"); - return 1; + return PM3_EWRONGANSVER; } recv = resp.data.asBytes; if (recv[0] & ISO15_RES_ERROR) { PrintAndLogEx(ERR, "iso15693 card returned error %i: %s", recv[0], TagErrorStr(recv[0])); - return 3; + return PM3_EWRONGANSVER; } uint8_t signature[32] = {0x00}; @@ -823,7 +831,7 @@ static int CmdHF15Info(const char *Cmd) { strncpy(cmd, Cmd, sizeof(cmdbuf) - 1); if (!prepareHF15Cmd(&cmd, &reqlen, &arg1, req, ISO15_CMD_SYSINFO)) - return 0; + return PM3_SUCCESS; AddCrc15(req, reqlen); reqlen += 2; @@ -835,21 +843,24 @@ static int CmdHF15Info(const char *Cmd) { if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { PrintAndLogEx(WARNING, "iso15693 card select failed"); - return 1; + DropField(); + return PM3_ETIMEOUT; } + DropField(); + uint32_t status = resp.oldarg[0]; if (status < 2) { PrintAndLogEx(WARNING, "iso15693 card doesn't answer to systeminfo command"); - return 1; + return PM3_EWRONGANSVER; } recv = resp.data.asBytes; if (recv[0] & ISO15_RES_ERROR) { PrintAndLogEx(ERR, "iso15693 card returned error %i: %s", recv[0], TagErrorStr(recv[0])); - return 3; + return PM3_EWRONGANSVER; } memcpy(uid, recv + 2, sizeof(uid)); @@ -904,7 +915,7 @@ static int CmdHF15Record(const char *Cmd) { clearCommandBuffer(); SendCommandNG(CMD_HF_ISO15693_RAWADC, NULL, 0); - return 0; + return PM3_SUCCESS; } static int CmdHF15Reader(const char *Cmd) { @@ -912,7 +923,7 @@ static int CmdHF15Reader(const char *Cmd) { if (cmdp == 'h') return usage_15_reader(); readHF15Uid(true); - return 0; + return PM3_SUCCESS; } // Simulation is still not working very good @@ -924,14 +935,14 @@ static int CmdHF15Sim(const char *Cmd) { uint8_t uid[8] = {0, 0, 0, 0, 0, 0, 0, 0}; if (param_gethex(Cmd, 0, uid, 16)) { PrintAndLogEx(WARNING, "UID must include 16 HEX symbols"); - return 0; + return PM3_EINVARG; } PrintAndLogEx(SUCCESS, "Starting simulating UID %s", sprint_hex(uid, sizeof(uid))); clearCommandBuffer(); SendCommandOLD(CMD_HF_ISO15693_SIMULATE, 0, 0, 0, uid, 8); - return 0; + return PM3_SUCCESS; } // finds the AFI (Application Family Identifier) of a card, by trying all values @@ -945,7 +956,8 @@ static int CmdHF15FindAfi(const char *Cmd) { clearCommandBuffer(); SendCommandMIX(CMD_HF_ISO15693_FINDAFI, strtol(Cmd, NULL, 0), 0, 0, NULL, 0); - return 0; + DropField(); + return PM3_SUCCESS; } // Writes the AFI (Application Family Identifier) of a card @@ -970,7 +982,7 @@ static int CmdHF15WriteAfi(const char *Cmd) { strncpy(cmd, Cmd, sizeof(cmdbuf) - 1); if (!prepareHF15Cmd(&cmd, &reqlen, &arg1, req, ISO15_CMD_WRITEAFI)) - return 0; + return PM3_SUCCESS; req[0] |= ISO15_REQ_OPTION; // Since we are writing @@ -988,14 +1000,17 @@ static int CmdHF15WriteAfi(const char *Cmd) { if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { PrintAndLogEx(NORMAL, "iso15693 card select failed"); - return 1; + DropField(); + return PM3_ETIMEOUT; } + DropField(); + recv = resp.data.asBytes; if (recv[0] & ISO15_RES_ERROR) { PrintAndLogEx(ERR, "iso15693 card returned error %i: %s", recv[0], TagErrorStr(recv[0])); - return 3; + return PM3_EWRONGANSVER; } PrintAndLogEx(NORMAL, ""); @@ -1026,7 +1041,7 @@ static int CmdHF15WriteDsfid(const char *Cmd) { strncpy(cmd, Cmd, sizeof(cmdbuf) - 1); if (!prepareHF15Cmd(&cmd, &reqlen, &arg1, req, ISO15_CMD_WRITEDSFID)) - return 0; + return PM3_SUCCESS; req[0] |= ISO15_REQ_OPTION; // Since we are writing @@ -1044,14 +1059,17 @@ static int CmdHF15WriteDsfid(const char *Cmd) { if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { PrintAndLogEx(NORMAL, "iso15693 card select failed"); - return 1; + DropField(); + return PM3_ETIMEOUT; } + DropField(); + recv = resp.data.asBytes; if (recv[0] & ISO15_RES_ERROR) { PrintAndLogEx(ERR, "iso15693 card returned error %i: %s", recv[0], TagErrorStr(recv[0])); - return 3; + return PM3_EWRONGANSVER; } PrintAndLogEx(NORMAL, ""); @@ -1096,7 +1114,7 @@ static int CmdHF15Dump(const char *Cmd) { if (!getUID(uid)) { PrintAndLogEx(WARNING, "No tag found."); - return 1; + return PM3_ESOFT; } if (fileNameLen < 1) { @@ -1166,6 +1184,9 @@ static int CmdHF15Dump(const char *Cmd) { fflush(stdout); } } + + DropField(); + PrintAndLogEx(NORMAL, "\n"); PrintAndLogEx(NORMAL, "block# | data |lck| ascii"); @@ -1229,7 +1250,7 @@ static int CmdHF15Raw(const char *Cmd) { break; default: PrintAndLogEx(WARNING, "Invalid option"); - return 0; + return PM3_EINVARG; } i += 2; continue; @@ -1250,7 +1271,7 @@ static int CmdHF15Raw(const char *Cmd) { continue; } PrintAndLogEx(WARNING, "Invalid char on input"); - return 0; + return PM3_EINVARG; } if (crc) { @@ -1270,6 +1291,8 @@ static int CmdHF15Raw(const char *Cmd) { PrintAndLogEx(WARNING, "timeout while waiting for reply."); } } + + DropField(); return PM3_SUCCESS; } @@ -1293,7 +1316,7 @@ static int CmdHF15Readmulti(const char *Cmd) { strncpy(cmd, Cmd, sizeof(cmdbuf) - 1); if (!prepareHF15Cmd(&cmd, &reqlen, &arg1, req, ISO15_CMD_READMULTI)) - return 0; + return PM3_SUCCESS; // add OPTION flag, in order to get lock-info req[0] |= ISO15_REQ_OPTION; @@ -1318,25 +1341,28 @@ static int CmdHF15Readmulti(const char *Cmd) { if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { PrintAndLogEx(FAILED, "iso15693 card select failed"); - return 1; + DropField(); + return PM3_ETIMEOUT; } + DropField(); + uint32_t status = resp.oldarg[0]; if (status < 2) { PrintAndLogEx(FAILED, "iso15693 card select failed"); - return 1; + return PM3_EWRONGANSVER; } recv = resp.data.asBytes; if (!CheckCrc15(recv, status)) { PrintAndLogEx(FAILED, "CRC failed"); - return 2; + return PM3_ESOFT; } if (recv[0] & ISO15_RES_ERROR) { PrintAndLogEx(FAILED, "iso15693 card returned error %i: %s", recv[0], TagErrorStr(recv[0])); - return 3; + return PM3_EWRONGANSVER; } int start = 1; // skip status byte @@ -1379,7 +1405,7 @@ static int CmdHF15Read(const char *Cmd) { strncpy(cmd, Cmd, sizeof(cmdbuf) - 1); if (!prepareHF15Cmd(&cmd, &reqlen, &arg1, req, ISO15_CMD_READ)) - return 0; + return PM3_SUCCESS; // add OPTION flag, in order to get lock-info req[0] |= ISO15_REQ_OPTION; @@ -1396,25 +1422,28 @@ static int CmdHF15Read(const char *Cmd) { if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { PrintAndLogEx(NORMAL, "iso15693 card select failed"); - return 1; + DropField(); + return PM3_ETIMEOUT; } + DropField(); + uint32_t status = resp.oldarg[0]; if (status < 2) { PrintAndLogEx(NORMAL, "iso15693 card select failed"); - return 1; + return PM3_EWRONGANSVER; } recv = resp.data.asBytes; if (!CheckCrc15(recv, status)) { PrintAndLogEx(NORMAL, "CRC failed"); - return 2; + return PM3_ESOFT; } if (recv[0] & ISO15_RES_ERROR) { PrintAndLogEx(ERR, "iso15693 card returned error %i: %s", recv[0], TagErrorStr(recv[0])); - return 3; + return PM3_EWRONGANSVER; } // print response @@ -1448,7 +1477,7 @@ static int CmdHF15Write(const char *Cmd) { strncpy(cmd, Cmd, sizeof(cmdbuf) - 1); if (!prepareHF15Cmd(&cmd, &reqlen, &arg1, req, ISO15_CMD_WRITE)) - return 0; + return PM3_SUCCESS; // *cmd -> page num ; *cmd2 -> data cmd2 = cmd; @@ -1479,25 +1508,28 @@ static int CmdHF15Write(const char *Cmd) { if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { PrintAndLogEx(FAILED, "iso15693 card timeout, data may be written anyway"); - return 1; + DropField(); + return PM3_ETIMEOUT; } + DropField(); + uint32_t status = resp.oldarg[0]; if (status < 2) { PrintAndLogEx(FAILED, "iso15693 card select failed"); - return 1; + return PM3_EWRONGANSVER; } recv = resp.data.asBytes; if (!CheckCrc15(recv, status)) { PrintAndLogEx(FAILED, "CRC failed"); - return 2; + return PM3_ESOFT; } if (recv[0] & ISO15_RES_ERROR) { PrintAndLogEx(NORMAL, "iso15693 card returned error %i: %s", recv[0], TagErrorStr(recv[0])); - return 3; + return PM3_EWRONGANSVER; } PrintAndLogEx(NORMAL, "OK"); @@ -1568,13 +1600,13 @@ static int CmdHF15Restore(const char *Cmd) { if ((f = fopen(filename, "rb")) == NULL) { PrintAndLogEx(WARNING, "Could not find file %s", filename); - return 2; + return PM3_EFILE; } if (!getUID(uid)) { PrintAndLogEx(WARNING, "No tag found"); fclose(f); - return 3; + return PM3_ESOFT; } PrintAndLogEx(INFO, "Restoring data blocks."); @@ -1592,7 +1624,7 @@ static int CmdHF15Restore(const char *Cmd) { } else if (bytes_read != blocksize) { PrintAndLogEx(ERR, "File reading error (%s), %zu bytes read instead of %zu bytes.", filename, bytes_read, blocksize); fclose(f); - return 2; + return PM3_EFILE; } for (int j = 0; j < blocksize; j++) @@ -1640,12 +1672,12 @@ static int CmdHF15CSetUID(const char *Cmd) { if (param_gethex(Cmd, 0, uid, 16)) { PrintAndLogEx(WARNING, "UID must include 16 HEX symbols"); - return 1; + return PM3_EINVARG; } if (uid[0] != 0xe0) { PrintAndLogEx(WARNING, "UID must begin with the byte " _YELLOW_("E0")); - return 1; + return PM3_EINVARG; } PrintAndLogEx(SUCCESS, "new UID | %s", sprint_hex(uid, sizeof(uid))); @@ -1756,14 +1788,14 @@ int CmdHF15(const char *Cmd) { } // used with 'hf search' -int readHF15Uid(bool verbose) { +bool readHF15Uid(bool verbose) { uint8_t uid[8] = {0, 0, 0, 0, 0, 0, 0, 0}; if (!getUID(uid)) { if (verbose) PrintAndLogEx(WARNING, "No tag found."); - return 0; + return false; } PrintAndLogEx(NORMAL, " UID : %s", sprintUID(NULL, uid)); PrintAndLogEx(NORMAL, " TYPE : %s", getTagInfo_15(uid)); - return 1; + return true; } diff --git a/client/cmdhf15.h b/client/cmdhf15.h index b3f64ac70..81530a58c 100644 --- a/client/cmdhf15.h +++ b/client/cmdhf15.h @@ -15,6 +15,6 @@ int CmdHF15(const char *Cmd); -int readHF15Uid(bool verbose); +bool readHF15Uid(bool verbose); #endif From 931d115ef8f237c966c24cb67972b6edde7fb782 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 27 Nov 2019 15:11:43 +0200 Subject: [PATCH 1156/1854] HF15FindAfi now uses reply_ng and added LeaveFieldOn option for HF15Raw --- CHANGELOG.md | 1 + armsrc/iso15693.c | 8 ++++++++ client/cmdhf15.c | 20 +++++++++++++++++--- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 16354bcac..8b4ff5dcc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Added `hf 15 writeafi`, `hf 15 writedsfid` and detailed info for SLIX2 tags in `hf 15 info`. Also did some refactoring in HF15 commands. (@grspy) - Fix hf list felica and hf felica sniff (@7homasSutter) - Added hf felica wrunencrypted (@7homasSutter) - Added hf felica rdunencrypted (@7homasSutter) diff --git a/armsrc/iso15693.c b/armsrc/iso15693.c index f1fd3eb9c..3dc64b8b8 100644 --- a/armsrc/iso15693.c +++ b/armsrc/iso15693.c @@ -929,6 +929,7 @@ void BruteforceIso15693Afi(uint32_t speed) { uint8_t buf[ISO15_MAX_FRAME]; memset(buf, 0x00, sizeof(buf)); int datalen = 0, recvlen = 0; + bool aborted = false; Iso15693InitReader(); @@ -968,12 +969,19 @@ void BruteforceIso15693Afi(uint32_t speed) { if (BUTTON_PRESS()) { DbpString("button pressed, aborting.."); + aborted = true; break; } } DbpString("AFI Bruteforcing done."); switch_off(); + + if (aborted) { + reply_ng(CMD_ACK, PM3_EOPABORTED, NULL, 0); + } else { + reply_ng(CMD_ACK, PM3_SUCCESS, NULL, 0); + } } // Allows to directly send commands to the tag via the client diff --git a/client/cmdhf15.c b/client/cmdhf15.c index 5a69c1343..8dba0d565 100644 --- a/client/cmdhf15.c +++ b/client/cmdhf15.c @@ -412,6 +412,7 @@ static int usage_15_raw(void) { {"-r", "do not read response" }, {"-2", "use slower '1 out of 256' mode" }, {"-c", "calculate and append CRC" }, + {"-p", "leave the signal field ON" }, {"", "Tip: turn on debugging for verbose output"}, }; PrintAndLogEx(NORMAL, "Usage: hf 15 raw [-r] [-2] [-c] <0A 0B 0C ... hex>\n"); @@ -949,6 +950,7 @@ static int CmdHF15Sim(const char *Cmd) { // (There is no standard way of reading the AFI, although some tags support this) // helptext static int CmdHF15FindAfi(const char *Cmd) { + PacketResponseNG resp; char cmdp = tolower(param_getchar(Cmd, 0)); if (cmdp == 'h') return usage_15_findafi(); @@ -956,8 +958,14 @@ static int CmdHF15FindAfi(const char *Cmd) { clearCommandBuffer(); SendCommandMIX(CMD_HF_ISO15693_FINDAFI, strtol(Cmd, NULL, 0), 0, 0, NULL, 0); + + if (WaitForResponseTimeout(CMD_ACK, &resp, 120000)) { // 2 minutes should be enough + DropField(); + return resp.status; // PM3_EOPABORTED or PM3_SUCCESS + } + DropField(); - return PM3_SUCCESS; + return PM3_ETIMEOUT; } // Writes the AFI (Application Family Identifier) of a card @@ -1225,7 +1233,7 @@ static int CmdHF15Raw(const char *Cmd) { PacketResponseNG resp; int reply = 1, fast = 1, i = 0; - bool crc = false; + bool crc = false, leaveSignalON = false; char buf[5] = ""; uint8_t data[100]; uint32_t datalen = 0, temp; @@ -1248,6 +1256,10 @@ static int CmdHF15Raw(const char *Cmd) { case 'C': crc = true; break; + case 'p': + case 'P': + leaveSignalON = true; + break; default: PrintAndLogEx(WARNING, "Invalid option"); return PM3_EINVARG; @@ -1292,7 +1304,9 @@ static int CmdHF15Raw(const char *Cmd) { } } - DropField(); + if (!leaveSignalON) + DropField(); + return PM3_SUCCESS; } From ecaf91936563579f0d9a9afbeda4519d86f52267 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 27 Nov 2019 21:14:31 +0200 Subject: [PATCH 1157/1854] Hf15FindAfi WaitForResponse loop --- CHANGELOG.md | 4 +++- armsrc/iso15693.c | 5 +++-- client/cmdhf15.c | 16 ++++++++++++---- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b4ff5dcc..2360c615d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,9 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] - - Added `hf 15 writeafi`, `hf 15 writedsfid` and detailed info for SLIX2 tags in `hf 15 info`. Also did some refactoring in HF15 commands. (@grspy) + - Change `hf 15` - some refactoring (@grspy) + - Added `hf 15 writeafi` and `hf 15 writedsfid` (@grspy) + - Added detailed info for SLIX2 tags in `hf 15 info` (@grspy) - Fix hf list felica and hf felica sniff (@7homasSutter) - Added hf felica wrunencrypted (@7homasSutter) - Added hf felica rdunencrypted (@7homasSutter) diff --git a/armsrc/iso15693.c b/armsrc/iso15693.c index 3dc64b8b8..7ea08e59c 100644 --- a/armsrc/iso15693.c +++ b/armsrc/iso15693.c @@ -967,9 +967,10 @@ void BruteforceIso15693Afi(uint32_t speed) { Dbprintf("AFI = %i UID = %s", i, sprintUID(NULL, buf + 2)); } - if (BUTTON_PRESS()) { + aborted = BUTTON_PRESS(); + + if (aborted) { DbpString("button pressed, aborting.."); - aborted = true; break; } } diff --git a/client/cmdhf15.c b/client/cmdhf15.c index 8dba0d565..1650aefd4 100644 --- a/client/cmdhf15.c +++ b/client/cmdhf15.c @@ -951,6 +951,8 @@ static int CmdHF15Sim(const char *Cmd) { // helptext static int CmdHF15FindAfi(const char *Cmd) { PacketResponseNG resp; + uint32_t timeout = 0; + char cmdp = tolower(param_getchar(Cmd, 0)); if (cmdp == 'h') return usage_15_findafi(); @@ -959,13 +961,19 @@ static int CmdHF15FindAfi(const char *Cmd) { clearCommandBuffer(); SendCommandMIX(CMD_HF_ISO15693_FINDAFI, strtol(Cmd, NULL, 0), 0, 0, NULL, 0); - if (WaitForResponseTimeout(CMD_ACK, &resp, 120000)) { // 2 minutes should be enough - DropField(); - return resp.status; // PM3_EOPABORTED or PM3_SUCCESS + while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { + timeout++; + + // should be done in about 2 minutes + if (timeout > 180) { + PrintAndLogEx(WARNING, "\nNo response from Proxmark3. Aborting..."); + DropField(); + return PM3_ETIMEOUT; + } } DropField(); - return PM3_ETIMEOUT; + return resp.status; // PM3_EOPABORTED or PM3_SUCCESS } // Writes the AFI (Application Family Identifier) of a card From 8cb28a21c6a5cc3bfcca4a2a1db2d3fdcca7f4f0 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Thu, 28 Nov 2019 00:48:39 +0200 Subject: [PATCH 1158/1854] add mfp default keys --- client/mifare/mifaredefault.c | 39 +++++++++++++++++++++++++++++++++++ client/mifare/mifaredefault.h | 3 +++ 2 files changed, 42 insertions(+) create mode 100644 client/mifare/mifaredefault.c diff --git a/client/mifare/mifaredefault.c b/client/mifare/mifaredefault.c new file mode 100644 index 000000000..9d3b77d4f --- /dev/null +++ b/client/mifare/mifaredefault.c @@ -0,0 +1,39 @@ +//----------------------------------------------------------------------------- +// Copyright (C) 2017 Merlok +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// Mifare default constants +//----------------------------------------------------------------------------- + +#include "mifaredefault.h" +#include "commonutil.h" // ARRAYLEN + +const char* g_mifare_plus_default_keys[] = { + "ffffffffffffffffffffffffffffffff", // default key + "00000000000000000000000000000000", + "a0a1a2a3a4a5a6a7a0a1a2a3a4a5a6a7", // MAD key + "b0b1b2b3b4b5b6b7b0b1b2b3b4b5b6b7", + "d3f7d3f7d3f7d3f7d3f7d3f7d3f7d3f7", // NDEF key + "11111111111111111111111111111111", + "22222222222222222222222222222222", + "33333333333333333333333333333333", + "44444444444444444444444444444444", + "55555555555555555555555555555555", + "66666666666666666666666666666666", + "77777777777777777777777777777777", + "88888888888888888888888888888888", + "99999999999999999999999999999999", + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "cccccccccccccccccccccccccccccccc", + "dddddddddddddddddddddddddddddddd", + "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", + "000102030405060708090a0b0c0d0e0f", + "0102030405060708090a0b0c0d0e0f10", + "00010203040506070809101112131415", + "01020304050607080910111213141516" +}; +size_t g_mifare_plus_default_keys_len = ARRAYLEN(g_mifare_plus_default_keys); \ No newline at end of file diff --git a/client/mifare/mifaredefault.h b/client/mifare/mifaredefault.h index 7232510a0..fdccfe22b 100644 --- a/client/mifare/mifaredefault.h +++ b/client/mifare/mifaredefault.h @@ -44,4 +44,7 @@ static const uint8_t g_mifare_ndef_key[] = {0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7}; static const uint8_t g_mifarep_mad_key[] = {0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7}; static const uint8_t g_mifarep_ndef_key[] = {0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7}; +extern const char* g_mifare_plus_default_keys[]; +extern size_t g_mifare_plus_default_keys_len; + #endif From 17a2379ddd8f2eb8b1564794daca157441859d67 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Thu, 28 Nov 2019 00:49:12 +0200 Subject: [PATCH 1159/1854] hf mfp check sketch --- client/Makefile | 1 + client/cmdhf14a.c | 23 ++++++++------- client/cmdhf14a.h | 2 +- client/cmdhfmf.c | 4 +-- client/cmdhfmfp.c | 62 +++++++++++++++++++++++++++++++---------- client/mifare/mifare4.c | 37 +++++++++++++----------- client/mifare/mifare4.h | 2 +- 7 files changed, 84 insertions(+), 47 deletions(-) diff --git a/client/Makefile b/client/Makefile index a6d987560..4babb528f 100644 --- a/client/Makefile +++ b/client/Makefile @@ -134,6 +134,7 @@ CORESRCS = uart_posix.c \ CMDSRCS = crapto1/crapto1.c \ crapto1/crypto1.c \ + mifare/mifaredefault.c \ mifare/mfkey.c \ tea.c \ fido/additional_ca.c \ diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index 777b7d25c..9c1004439 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -551,30 +551,29 @@ int CmdHF14ASniff(const char *Cmd) { return PM3_SUCCESS; } -int ExchangeRAW14a(uint8_t *datain, int datainlen, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen) { +int ExchangeRAW14a(uint8_t *datain, int datainlen, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, bool silentMode) { static uint8_t responseNum = 0; uint16_t cmdc = 0; *dataoutlen = 0; if (activateField) { - responseNum = 1; PacketResponseNG resp; // Anticollision + SELECT card SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0, NULL, 0); if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { - PrintAndLogEx(ERR, "Proxmark3 connection timeout."); + if (!silentMode) PrintAndLogEx(ERR, "Proxmark3 connection timeout."); return 1; } // check result if (resp.oldarg[0] == 0) { - PrintAndLogEx(ERR, "No card in field."); + if (!silentMode) PrintAndLogEx(ERR, "No card in field."); return 1; } if (resp.oldarg[0] != 1 && resp.oldarg[0] != 2) { - PrintAndLogEx(ERR, "Card not in iso14443-4. res=%" PRId64 ".", resp.oldarg[0]); + if (!silentMode) PrintAndLogEx(ERR, "Card not in iso14443-4. res=%" PRId64 ".", resp.oldarg[0]); return 1; } @@ -583,12 +582,12 @@ int ExchangeRAW14a(uint8_t *datain, int datainlen, bool activateField, bool leav uint8_t rats[] = { 0xE0, 0x80 }; // FSDI=8 (FSD=256), CID=0 SendCommandOLD(CMD_HF_ISO14443A_READER, ISO14A_RAW | ISO14A_APPEND_CRC | ISO14A_NO_DISCONNECT, 2, 0, rats, 2); if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { - PrintAndLogEx(ERR, "Proxmark3 connection timeout."); + if (!silentMode) PrintAndLogEx(ERR, "Proxmark3 connection timeout."); return 1; } if (resp.oldarg[0] == 0) { // ats_len - PrintAndLogEx(ERR, "Can't get ATS."); + if (!silentMode) PrintAndLogEx(ERR, "Can't get ATS."); return 1; } } @@ -610,7 +609,7 @@ int ExchangeRAW14a(uint8_t *datain, int datainlen, bool activateField, bool leav int iLen = resp.oldarg[0]; if (!iLen) { - PrintAndLogEx(ERR, "No card response."); + if (!silentMode) PrintAndLogEx(ERR, "No card response."); return 1; } @@ -619,12 +618,12 @@ int ExchangeRAW14a(uint8_t *datain, int datainlen, bool activateField, bool leav *dataoutlen = 0; if (maxdataoutlen && *dataoutlen > maxdataoutlen) { - PrintAndLogEx(ERR, "Buffer too small(%d). Needs %d bytes", *dataoutlen, maxdataoutlen); + if (!silentMode) PrintAndLogEx(ERR, "Buffer too small(%d). Needs %d bytes", *dataoutlen, maxdataoutlen); return 2; } if (recv[0] != data[0]) { - PrintAndLogEx(ERR, "iso14443-4 framing error. Card send %2x must be %2x", dataout[0], data[0]); + if (!silentMode) PrintAndLogEx(ERR, "iso14443-4 framing error. Card send %2x must be %2x", dataout[0], data[0]); return 2; } @@ -632,12 +631,12 @@ int ExchangeRAW14a(uint8_t *datain, int datainlen, bool activateField, bool leav // CRC Check if (iLen == -1) { - PrintAndLogEx(ERR, "ISO 14443A CRC error."); + if (!silentMode) PrintAndLogEx(ERR, "ISO 14443A CRC error."); return 3; } } else { - PrintAndLogEx(ERR, "Reply timeout."); + if (!silentMode) PrintAndLogEx(ERR, "Reply timeout."); return 4; } diff --git a/client/cmdhf14a.h b/client/cmdhf14a.h index fcea5f5cf..f40ea46f0 100644 --- a/client/cmdhf14a.h +++ b/client/cmdhf14a.h @@ -30,6 +30,6 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search); const char *getTagInfo(uint8_t uid); int Hf14443_4aGetCardData(iso14a_card_select_t *card); int ExchangeAPDU14a(uint8_t *datain, int datainlen, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen); -int ExchangeRAW14a(uint8_t *datain, int datainlen, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen); +int ExchangeRAW14a(uint8_t *datain, int datainlen, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, bool silentMode); #endif diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 23b418599..ad6fe31b2 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -13,7 +13,7 @@ #include #include "cmdparser.h" // command_t -#include "commonutil.h" // ARRAYLEN +#include "commonutil.h" // ARRAYLEN #include "comms.h" // clearCommandBuffer #include "fileutils.h" #include "cmdtrace.h" @@ -4211,7 +4211,7 @@ static int CmdHF14AMfAuth4(const char *Cmd) { return PM3_ESOFT; } - return MifareAuth4(NULL, keyn, key, true, false, true); + return MifareAuth4(NULL, keyn, key, true, false, true, true, false); } // https://www.nxp.com/docs/en/application-note/AN10787.pdf diff --git a/client/cmdhfmfp.c b/client/cmdhfmfp.c index c6af6305a..affd9dd6c 100644 --- a/client/cmdhfmfp.c +++ b/client/cmdhfmfp.c @@ -88,7 +88,7 @@ static int CmdHFMFPInfo(const char *cmd) { int datalen = 0; // https://github.com/Proxmark/proxmark3/blob/master/client/luascripts/mifarePlus.lua#L161 uint8_t cmd[3 + 16] = {0xa8, 0x90, 0x90, 0x00}; - int res = ExchangeRAW14a(cmd, sizeof(cmd), false, false, data, sizeof(data), &datalen); + int res = ExchangeRAW14a(cmd, sizeof(cmd), false, false, data, sizeof(data), &datalen, false); if (!res && datalen > 1 && data[0] == 0x09) { SLmode = 0; } @@ -105,7 +105,7 @@ static int CmdHFMFPInfo(const char *cmd) { DropField(); - return 0; + return PM3_SUCCESS; } static int CmdHFMFPWritePerso(const char *cmd) { @@ -169,7 +169,7 @@ static int CmdHFMFPWritePerso(const char *cmd) { } PrintAndLogEx(INFO, "Write OK."); - return 0; + return PM3_SUCCESS; } uint16_t CardAddresses[] = {0x9000, 0x9001, 0x9002, 0x9003, 0x9004, 0xA000, 0xA001, 0xA080, 0xA081, 0xC000, 0xC001}; @@ -245,7 +245,7 @@ static int CmdHFMFPInitPerso(const char *cmd) { PrintAndLogEx(INFO, "Done."); - return 0; + return PM3_SUCCESS; } static int CmdHFMFPCommitPerso(const char *cmd) { @@ -286,7 +286,7 @@ static int CmdHFMFPCommitPerso(const char *cmd) { } PrintAndLogEx(INFO, "Switch level OK."); - return 0; + return PM3_SUCCESS; } static int CmdHFMFPAuth(const char *cmd) { @@ -324,7 +324,7 @@ static int CmdHFMFPAuth(const char *cmd) { return 1; } - return MifareAuth4(NULL, keyn, key, true, false, verbose); + return MifareAuth4(NULL, keyn, key, true, false, true, verbose, false); } static int CmdHFMFPRdbl(const char *cmd) { @@ -392,7 +392,7 @@ static int CmdHFMFPRdbl(const char *cmd) { PrintAndLogEx(INFO, "--block:%d sector[%d]:%02x key:%04x", blockn, mfNumBlocksPerSector(sectorNum), sectorNum, uKeyNum); mf4Session mf4session; - int res = MifareAuth4(&mf4session, keyn, key, true, true, verbose); + int res = MifareAuth4(&mf4session, keyn, key, true, true, true, verbose, false); if (res) { PrintAndLogEx(ERR, "Authentication error: %d", res); return res; @@ -491,7 +491,7 @@ static int CmdHFMFPRdsc(const char *cmd) { PrintAndLogEx(INFO, "--sector[%d]:%02x key:%04x", mfNumBlocksPerSector(sectorNum), sectorNum, uKeyNum); mf4Session mf4session; - int res = MifareAuth4(&mf4session, keyn, key, true, true, verbose); + int res = MifareAuth4(&mf4session, keyn, key, true, true, true, verbose, false); if (res) { PrintAndLogEx(ERR, "Authentication error: %d", res); return res; @@ -532,7 +532,7 @@ static int CmdHFMFPRdsc(const char *cmd) { } DropField(); - return 0; + return PM3_SUCCESS; } static int CmdHFMFPWrbl(const char *cmd) { @@ -595,7 +595,7 @@ static int CmdHFMFPWrbl(const char *cmd) { PrintAndLogEx(INFO, "--block:%d sector[%d]:%02x key:%04x", blockNum & 0xff, mfNumBlocksPerSector(sectorNum), sectorNum, uKeyNum); mf4Session mf4session; - int res = MifareAuth4(&mf4session, keyn, key, true, true, verbose); + int res = MifareAuth4(&mf4session, keyn, key, true, true, true, verbose, false); if (res) { PrintAndLogEx(ERR, "Authentication error: %d", res); return res; @@ -634,7 +634,40 @@ static int CmdHFMFPWrbl(const char *cmd) { DropField(); PrintAndLogEx(INFO, "Write OK."); - return 0; + return PM3_SUCCESS; +} + +static int CmdHFMFPChk() { + int res; + bool selectCard = true; + + uint8_t startSector = 0; + uint8_t endSector = 0; + uint8_t startKeyAB = 0; + uint8_t endKeyAB = 0; + + + uint8_t keyn[2] = {0}; + uint8_t key[16] = {0}; + // sector number from 0 + for (uint8_t sector = startSector; sector <= endSector; sector++) { + // 0-keyA 1-keyB + for(uint8_t keyAB = startKeyAB; keyAB <= endKeyAB; keyAB++) { + // main cycle with key check + for (int i = 0; i < g_mifare_plus_default_keys_len; i++) { + uint16_t uKeyNum = 0x4000 + sector * 2 + keyAB; + keyn[0] = uKeyNum >> 8; + keyn[1] = uKeyNum & 0xff; + res = MifareAuth4(NULL, keyn, key, selectCard, true, false, false, true); + selectCard = false; + PrintAndLogEx(WARNING, "sector %d key %d [%s] res: %d", sector, key, g_mifare_plus_default_keys[i], res); + } + } + } + + DropField(); + + return PM3_SUCCESS; } static int CmdHFMFPMAD(const char *cmd) { @@ -728,7 +761,7 @@ static int CmdHFMFPMAD(const char *cmd) { } } - return 0; + return PM3_SUCCESS; } static int CmdHFMFPNDEF(const char *cmd) { @@ -832,7 +865,7 @@ static int CmdHFMFPNDEF(const char *cmd) { NDEFDecodeAndPrint(data, datalen, verbose); - return 0; + return PM3_SUCCESS; } static command_t CommandTable[] = { @@ -845,6 +878,7 @@ static command_t CommandTable[] = { {"rdbl", CmdHFMFPRdbl, IfPm3Iso14443a, "Read blocks"}, {"rdsc", CmdHFMFPRdsc, IfPm3Iso14443a, "Read sectors"}, {"wrbl", CmdHFMFPWrbl, IfPm3Iso14443a, "Write blocks"}, + {"chk", CmdHFMFPChk, IfPm3Iso14443a, "Check keys"}, {"mad", CmdHFMFPMAD, IfPm3Iso14443a, "Checks and prints MAD"}, {"ndef", CmdHFMFPNDEF, IfPm3Iso14443a, "Prints NDEF records from card"}, {NULL, NULL, 0, NULL} @@ -853,7 +887,7 @@ static command_t CommandTable[] = { static int CmdHelp(const char *Cmd) { (void)Cmd; // Cmd is not used so far CmdsHelp(CommandTable); - return 0; + return PM3_SUCCESS; } int CmdHFMFP(const char *Cmd) { diff --git a/client/mifare/mifare4.c b/client/mifare/mifare4.c index 5cdca2e14..7eecbe751 100644 --- a/client/mifare/mifare4.c +++ b/client/mifare/mifare4.c @@ -168,21 +168,24 @@ int CalculateMAC(mf4Session *session, MACType_t mtype, uint8_t blockNum, uint8_t return aes_cmac8(NULL, session->Kmac, macdata, mac, macdatalen); } -int MifareAuth4(mf4Session *session, uint8_t *keyn, uint8_t *key, bool activateField, bool leaveSignalON, bool verbose) { +int MifareAuth4(mf4Session *session, uint8_t *keyn, uint8_t *key, bool activateField, bool leaveSignalON, bool dropFieldIfError, bool verbose, bool silentMode) { uint8_t data[257] = {0}; int datalen = 0; uint8_t RndA[17] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00}; uint8_t RndB[17] = {0}; + if (silentMode) + verbose = false; + if (session) session->Authenticated = false; uint8_t cmd1[] = {0x70, keyn[1], keyn[0], 0x00}; - int res = ExchangeRAW14a(cmd1, sizeof(cmd1), activateField, true, data, sizeof(data), &datalen); + int res = ExchangeRAW14a(cmd1, sizeof(cmd1), activateField, true, data, sizeof(data), &datalen, silentMode); if (res) { - PrintAndLogEx(ERR, "Exchande raw error: %d", res); - DropField(); + if (!silentMode) PrintAndLogEx(ERR, "Exchande raw error: %d", res); + if (dropFieldIfError) DropField(); return 2; } @@ -190,20 +193,20 @@ int MifareAuth4(mf4Session *session, uint8_t *keyn, uint8_t *key, bool activateF PrintAndLogEx(INFO, "phase2: %s", sprint_hex(cmd2, 33)); - res = ExchangeRAW14a(cmd2, sizeof(cmd2), false, true, data, sizeof(data), &datalen); + res = ExchangeRAW14a(cmd2, sizeof(cmd2), false, true, data, sizeof(data), &datalen, silentMode); if (res) { - PrintAndLogEx(ERR, "Exchande raw error: %d", res); - DropField(); + if (!silentMode) PrintAndLogEx(ERR, "Exchande raw error: %d", res); + if (dropFieldIfError) DropField(); return 4; } @@ -241,12 +244,12 @@ int MifareAuth4(mf4Session *session, uint8_t *keyn, uint8_t *key, bool activateF } if (memcmp(&raw[4], &RndA[1], 16)) { - PrintAndLogEx(ERR, "\nAuthentication FAILED. rnd not equal"); + if (!silentMode) PrintAndLogEx(ERR, "\nAuthentication FAILED. rnd is not equal"); if (verbose) { PrintAndLogEx(ERR, "RndA reader: %s", sprint_hex(&RndA[1], 16)); PrintAndLogEx(ERR, "RndA card: %s", sprint_hex(&raw[4], 16)); } - DropField(); + if (dropFieldIfError) DropField(); return 5; } @@ -311,7 +314,7 @@ static int intExchangeRAW14aPlus(uint8_t *datain, int datainlen, bool activateFi if (VerboseMode) PrintAndLogEx(INFO, ">>> %s", sprint_hex(datain, datainlen)); - int res = ExchangeRAW14a(datain, datainlen, activateField, leaveSignalON, dataout, maxdataoutlen, dataoutlen); + int res = ExchangeRAW14a(datain, datainlen, activateField, leaveSignalON, dataout, maxdataoutlen, dataoutlen, false); if (VerboseMode) PrintAndLogEx(INFO, "<<< %s", sprint_hex(dataout, *dataoutlen)); @@ -380,7 +383,7 @@ int mfpReadSector(uint8_t sectorNo, uint8_t keyType, uint8_t *key, uint8_t *data PrintAndLogEx(INFO, "--sector[%d]:%02x key:%04x", mfNumBlocksPerSector(sectorNo), sectorNo, uKeyNum); mf4Session session; - int res = MifareAuth4(&session, keyn, key, true, true, verbose); + int res = MifareAuth4(&session, keyn, key, true, true, true, verbose, false); if (res) { PrintAndLogEx(ERR, "Sector %d authentication error: %d", sectorNo, res); return res; diff --git a/client/mifare/mifare4.h b/client/mifare/mifare4.h index 31eac1fdb..fe07aceaf 100644 --- a/client/mifare/mifare4.h +++ b/client/mifare/mifare4.h @@ -45,7 +45,7 @@ void mfpSetVerboseMode(bool verbose); const char *mfpGetErrorDescription(uint8_t errorCode); int CalculateMAC(mf4Session *session, MACType_t mtype, uint8_t blockNum, uint8_t blockCount, uint8_t *data, int datalen, uint8_t *mac, bool verbose); -int MifareAuth4(mf4Session *session, uint8_t *keyn, uint8_t *key, bool activateField, bool leaveSignalON, bool verbose); +int MifareAuth4(mf4Session *session, uint8_t *keyn, uint8_t *key, bool activateField, bool leaveSignalON, bool dropFieldIfError, bool verbose, bool silentMode); int MFPWritePerso(uint8_t *keyNum, uint8_t *key, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen); int MFPCommitPerso(bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen); From 698b4a5f6410fe5d7f398d84b08d4761a5886235 Mon Sep 17 00:00:00 2001 From: Iceman Date: Thu, 28 Nov 2019 09:15:03 +0100 Subject: [PATCH 1160/1854] Update jtag_notes.md --- doc/jtag_notes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/jtag_notes.md b/doc/jtag_notes.md index 8e31f1112..5f59aa5e2 100644 --- a/doc/jtag_notes.md +++ b/doc/jtag_notes.md @@ -63,6 +63,9 @@ GND | 6 ## Third party notes on using a BusPirate * https://github.com/Proxmark/proxmark3/wiki/Debricking-Proxmark3-with-buspirate +* https://b4cktr4ck2.github.io/De-Brickify-Pm3-RDV2/ +* https://scund00r.com/all/rfid/2018/05/18/debrick-proxmark.html +* https://joanbono.github.io/PoC/Flashing_Proxmark3.html ## Third party notes on using a J-Link From 0fb7f98fc2fba780bdf3bcf2ed93debedf18033a Mon Sep 17 00:00:00 2001 From: Iceman Date: Thu, 28 Nov 2019 09:15:19 +0100 Subject: [PATCH 1161/1854] Update jtag_notes.md --- doc/jtag_notes.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/doc/jtag_notes.md b/doc/jtag_notes.md index 5f59aa5e2..42001d91d 100644 --- a/doc/jtag_notes.md +++ b/doc/jtag_notes.md @@ -75,8 +75,6 @@ GND | 6 * http://www.lucasoldi.com/2017/01/17/unbrick-proxmark3-with-a-raspberry-pi-and-openocd/ -# Windows - ## Third party notes on using a J-Link on Windows * https://github.com/Proxmark/proxmark3/wiki/De-Bricking-Segger From 133d59e4830eb700a216c9bf58f401ee925e4132 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Thu, 28 Nov 2019 14:16:53 +0200 Subject: [PATCH 1162/1854] added command parsing and result printing --- client/cmdhfmfp.c | 79 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 73 insertions(+), 6 deletions(-) diff --git a/client/cmdhfmfp.c b/client/cmdhfmfp.c index affd9dd6c..f5d122991 100644 --- a/client/cmdhfmfp.c +++ b/client/cmdhfmfp.c @@ -637,16 +637,47 @@ static int CmdHFMFPWrbl(const char *cmd) { return PM3_SUCCESS; } -static int CmdHFMFPChk() { +static int CmdHFMFPChk(const char *cmd) { int res; bool selectCard = true; + char* foundKeys[2][64] = {NULL}; - uint8_t startSector = 0; - uint8_t endSector = 0; + CLIParserInit("hf mfp check", + "Checks keys with Mifare Plus card.", + "Usage:\n\thf mfp check -k 000102030405060708090a0b0c0d0e0f -> check key on sector 0 as key A and B\n" + "\thf mfp check -s 2 -a -> check default key list \n"); + + void *argtable[] = { + arg_param_begin, + arg_lit0("aA", "keya", "check only key A (by default check all keys)."), + arg_lit0("bB", "keyb", "check only key B (by default check all keys)."), + arg_int0("sS", "startsec", "Start sector Num (0..255)", NULL), + arg_int0("eE", "endsec", "End sector Num (0..255)", NULL), + arg_str0("kK", "key", "", NULL), + arg_str0(NULL, NULL, "", NULL), + arg_param_end + }; + CLIExecWithReturn(cmd, argtable, true); + + bool keyA = arg_get_lit(1); + bool keyB = arg_get_lit(2); + uint8_t startSector = arg_get_int_def(3, 0); + uint8_t endSector = arg_get_int_def(4, 0); + uint8_t vkey[16] = {0}; + int vkeylen = 0; + CLIGetHexWithReturn(5, vkey, &vkeylen); + CLIParserFree(); + uint8_t startKeyAB = 0; - uint8_t endKeyAB = 0; - + uint8_t endKeyAB = 1; + if (keyA && !keyB) + endKeyAB = 0; + if (!keyA && keyB) + startKeyAB = 1; + if (endSector < startSector) + endSector = startSector; + uint8_t keyn[2] = {0}; uint8_t key[16] = {0}; // sector number from 0 @@ -655,17 +686,53 @@ static int CmdHFMFPChk() { for(uint8_t keyAB = startKeyAB; keyAB <= endKeyAB; keyAB++) { // main cycle with key check for (int i = 0; i < g_mifare_plus_default_keys_len; i++) { + int datalen = 0; + if (param_gethex_to_eol((char *)g_mifare_plus_default_keys[i], 0, (uint8_t *)key, 16, &datalen) > 0) + break; + if (datalen != 16) + break; + uint16_t uKeyNum = 0x4000 + sector * 2 + keyAB; keyn[0] = uKeyNum >> 8; keyn[1] = uKeyNum & 0xff; res = MifareAuth4(NULL, keyn, key, selectCard, true, false, false, true); + if (res == 0) { + PrintAndLogEx(INFO, "Found key for sector %d key %s [%s]", sector, keyAB == 0 ? "A" : "B", sprint_hex_inrow(key, 16)); + foundKeys[keyAB][sector] = (char*)g_mifare_plus_default_keys[i]; + break; + } + + if (res != 5) + break; + selectCard = false; - PrintAndLogEx(WARNING, "sector %d key %d [%s] res: %d", sector, key, g_mifare_plus_default_keys[i], res); + PrintAndLogEx(WARNING, "sector %d key %d [%s] res: %d", sector, keyAB, sprint_hex_inrow(key, 16), res); } } } DropField(); + + // print result + bool printedHeader = false; + for (uint8_t sector = startSector; sector <= endSector; sector++) { + if (foundKeys[0][sector] != NULL || foundKeys[1][sector] != NULL) { + if (!printedHeader) { + PrintAndLogEx(INFO, ".------.--------------------------------.--------------------------------."); + PrintAndLogEx(INFO, "|sector| key A | key B |"); + PrintAndLogEx(INFO, "|------|--------------------------------|--------------------------------|"); + printedHeader = true; + } + PrintAndLogEx(INFO, "| %02d |%32s|%32s|", + sector, + (foundKeys[0][sector] == NULL) ? "----- " : foundKeys[0][sector], + (foundKeys[1][sector] == NULL) ? "----- " : foundKeys[1][sector]); + } + } + if (!printedHeader) + PrintAndLogEx(INFO, "No keys found("); + else + PrintAndLogEx(INFO, "'------'--------------------------------'--------------------------------'"); return PM3_SUCCESS; } From 2c101ebbb9a2dd79afac5417bcc91a4152c84065 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Thu, 28 Nov 2019 15:16:11 +0200 Subject: [PATCH 1163/1854] internal keys search works --- client/cmdhfmfp.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/client/cmdhfmfp.c b/client/cmdhfmfp.c index f5d122991..c3944e12d 100644 --- a/client/cmdhfmfp.c +++ b/client/cmdhfmfp.c @@ -25,6 +25,7 @@ #include "cliparser/cliparser.h" #include "emv/dump.h" #include "mifare/mifaredefault.h" +#include "util_posix.h" static const uint8_t DefaultKey[16] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; @@ -645,7 +646,7 @@ static int CmdHFMFPChk(const char *cmd) { CLIParserInit("hf mfp check", "Checks keys with Mifare Plus card.", "Usage:\n\thf mfp check -k 000102030405060708090a0b0c0d0e0f -> check key on sector 0 as key A and B\n" - "\thf mfp check -s 2 -a -> check default key list \n"); + "\thf mfp check -s 2 -a -> check default key list on sector 2, key A\n"); void *argtable[] = { arg_param_begin, @@ -655,6 +656,8 @@ static int CmdHFMFPChk(const char *cmd) { arg_int0("eE", "endsec", "End sector Num (0..255)", NULL), arg_str0("kK", "key", "", NULL), arg_str0(NULL, NULL, "", NULL), + arg_lit0(NULL, "pattern1b", "check all 1-byte combinations of key (0000...0000, 0101...0101, 0202...0202, ...)"), + arg_lit0(NULL, "pattern2b", "check all 2-byte combinations of key (0000...0000, 0001...0001, 0002...0002, ...)"), arg_param_end }; CLIExecWithReturn(cmd, argtable, true); @@ -666,6 +669,8 @@ static int CmdHFMFPChk(const char *cmd) { uint8_t vkey[16] = {0}; int vkeylen = 0; CLIGetHexWithReturn(5, vkey, &vkeylen); + bool pattern1b = arg_get_lit(7); + bool pattern2b = arg_get_lit(8); CLIParserFree(); uint8_t startKeyAB = 0; @@ -695,10 +700,15 @@ static int CmdHFMFPChk(const char *cmd) { uint16_t uKeyNum = 0x4000 + sector * 2 + keyAB; keyn[0] = uKeyNum >> 8; keyn[1] = uKeyNum & 0xff; + res = MifareAuth4(NULL, keyn, key, selectCard, true, false, false, true); + PrintAndLogEx(WARNING, "sector %d key %d [%s] res: %d", sector, keyAB, sprint_hex_inrow(key, 16), res); if (res == 0) { PrintAndLogEx(INFO, "Found key for sector %d key %s [%s]", sector, keyAB == 0 ? "A" : "B", sprint_hex_inrow(key, 16)); foundKeys[keyAB][sector] = (char*)g_mifare_plus_default_keys[i]; + DropField(); + selectCard = true; + msleep(50); break; } @@ -706,7 +716,6 @@ static int CmdHFMFPChk(const char *cmd) { break; selectCard = false; - PrintAndLogEx(WARNING, "sector %d key %d [%s] res: %d", sector, keyAB, sprint_hex_inrow(key, 16), res); } } } @@ -725,8 +734,8 @@ static int CmdHFMFPChk(const char *cmd) { } PrintAndLogEx(INFO, "| %02d |%32s|%32s|", sector, - (foundKeys[0][sector] == NULL) ? "----- " : foundKeys[0][sector], - (foundKeys[1][sector] == NULL) ? "----- " : foundKeys[1][sector]); + (foundKeys[0][sector] == NULL) ? "------ " : foundKeys[0][sector], + (foundKeys[1][sector] == NULL) ? "------ " : foundKeys[1][sector]); } } if (!printedHeader) From 9f8a8cce96a74f5fe24b788701fdc50de8078d74 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Thu, 28 Nov 2019 15:36:52 +0200 Subject: [PATCH 1164/1854] refactoring. move key list to uint8_t[16] array --- client/cmdhfmfp.c | 60 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 42 insertions(+), 18 deletions(-) diff --git a/client/cmdhfmfp.c b/client/cmdhfmfp.c index c3944e12d..b1a764cac 100644 --- a/client/cmdhfmfp.c +++ b/client/cmdhfmfp.c @@ -638,10 +638,15 @@ static int CmdHFMFPWrbl(const char *cmd) { return PM3_SUCCESS; } +#define AES_KEY_LEN 16 +#define MAX_KEYS_LIST_LEN 1024 + static int CmdHFMFPChk(const char *cmd) { int res; bool selectCard = true; - char* foundKeys[2][64] = {NULL}; + uint8_t keysList[MAX_KEYS_LIST_LEN][AES_KEY_LEN] = {0}; + size_t keysListLen = 0; + uint8_t foundKeys[2][64][AES_KEY_LEN + 1] = {0}; CLIParserInit("hf mfp check", "Checks keys with Mifare Plus card.", @@ -682,30 +687,49 @@ static int CmdHFMFPChk(const char *cmd) { if (endSector < startSector) endSector = startSector; + + if (pattern1b || pattern2b) { + for (int i = 0; i < 0x100; i++) + memset(keysList[i], i, 16); + + keysListLen = 0x100; + } + + if (keysListLen == 0) { + for (int i = 0; i < g_mifare_plus_default_keys_len; i++) { + int datalen = 0; + if (param_gethex_to_eol(g_mifare_plus_default_keys[i], 0, keysList[keysListLen], 16, &datalen) > 0) + break; + if (datalen != 16) + break; + + keysListLen++; + } + } + + if (keysListLen == 0) { + PrintAndLogEx(ERROR, "Key list is empty. Nothing to check."); + return 1; + } + uint8_t keyn[2] = {0}; - uint8_t key[16] = {0}; // sector number from 0 for (uint8_t sector = startSector; sector <= endSector; sector++) { // 0-keyA 1-keyB for(uint8_t keyAB = startKeyAB; keyAB <= endKeyAB; keyAB++) { // main cycle with key check - for (int i = 0; i < g_mifare_plus_default_keys_len; i++) { - int datalen = 0; - if (param_gethex_to_eol((char *)g_mifare_plus_default_keys[i], 0, (uint8_t *)key, 16, &datalen) > 0) - break; - if (datalen != 16) - break; - + for (int i = 0; i < keysListLen; i++) { uint16_t uKeyNum = 0x4000 + sector * 2 + keyAB; keyn[0] = uKeyNum >> 8; keyn[1] = uKeyNum & 0xff; - res = MifareAuth4(NULL, keyn, key, selectCard, true, false, false, true); - PrintAndLogEx(WARNING, "sector %d key %d [%s] res: %d", sector, keyAB, sprint_hex_inrow(key, 16), res); + res = MifareAuth4(NULL, keyn, keysList[i], selectCard, true, false, false, true); + PrintAndLogEx(WARNING, "sector %d key %d [%s] res: %d", sector, keyAB, sprint_hex_inrow(keysList[i], 16), res); if (res == 0) { - PrintAndLogEx(INFO, "Found key for sector %d key %s [%s]", sector, keyAB == 0 ? "A" : "B", sprint_hex_inrow(key, 16)); - foundKeys[keyAB][sector] = (char*)g_mifare_plus_default_keys[i]; + PrintAndLogEx(INFO, "Found key for sector %d key %s [%s]", sector, keyAB == 0 ? "A" : "B", sprint_hex_inrow(keysList[i], 16)); + foundKeys[keyAB][sector][0] = 0x01; + memcpy(&foundKeys[keyAB][sector][1], keysList[i], AES_KEY_LEN); DropField(); selectCard = true; msleep(50); @@ -725,23 +749,23 @@ static int CmdHFMFPChk(const char *cmd) { // print result bool printedHeader = false; for (uint8_t sector = startSector; sector <= endSector; sector++) { - if (foundKeys[0][sector] != NULL || foundKeys[1][sector] != NULL) { + if (foundKeys[0][sector][0] || foundKeys[1][sector][0]) { if (!printedHeader) { - PrintAndLogEx(INFO, ".------.--------------------------------.--------------------------------."); + PrintAndLogEx(INFO, "\n.------.--------------------------------.--------------------------------."); PrintAndLogEx(INFO, "|sector| key A | key B |"); PrintAndLogEx(INFO, "|------|--------------------------------|--------------------------------|"); printedHeader = true; } PrintAndLogEx(INFO, "| %02d |%32s|%32s|", sector, - (foundKeys[0][sector] == NULL) ? "------ " : foundKeys[0][sector], - (foundKeys[1][sector] == NULL) ? "------ " : foundKeys[1][sector]); + (foundKeys[0][sector][0] == 0) ? "------ " : sprint_hex_inrow(&foundKeys[0][sector][1], AES_KEY_LEN), + (foundKeys[1][sector][0] == 0) ? "------ " : sprint_hex_inrow(&foundKeys[1][sector][1], AES_KEY_LEN)); } } if (!printedHeader) PrintAndLogEx(INFO, "No keys found("); else - PrintAndLogEx(INFO, "'------'--------------------------------'--------------------------------'"); + PrintAndLogEx(INFO, "'------'--------------------------------'--------------------------------'\n"); return PM3_SUCCESS; } From 385a747dbd7460749f3a73bdc3b8ea47c3a627f1 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Thu, 28 Nov 2019 16:24:39 +0200 Subject: [PATCH 1165/1854] added search 2-byte pattern --- client/cmdhfmfp.c | 50 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 15 deletions(-) diff --git a/client/cmdhfmfp.c b/client/cmdhfmfp.c index b1a764cac..db8df3e29 100644 --- a/client/cmdhfmfp.c +++ b/client/cmdhfmfp.c @@ -644,8 +644,8 @@ static int CmdHFMFPWrbl(const char *cmd) { static int CmdHFMFPChk(const char *cmd) { int res; bool selectCard = true; - uint8_t keysList[MAX_KEYS_LIST_LEN][AES_KEY_LEN] = {0}; - size_t keysListLen = 0; + uint8_t keyList[MAX_KEYS_LIST_LEN][AES_KEY_LEN] = {0}; + size_t keyListLen = 0; uint8_t foundKeys[2][64][AES_KEY_LEN + 1] = {0}; CLIParserInit("hf mfp check", @@ -663,6 +663,7 @@ static int CmdHFMFPChk(const char *cmd) { arg_str0(NULL, NULL, "", NULL), arg_lit0(NULL, "pattern1b", "check all 1-byte combinations of key (0000...0000, 0101...0101, 0202...0202, ...)"), arg_lit0(NULL, "pattern2b", "check all 2-byte combinations of key (0000...0000, 0001...0001, 0002...0002, ...)"), + arg_str0(NULL, "startp2b", " start pattern for 2-byte search key", NULL), arg_param_end }; CLIExecWithReturn(cmd, argtable, true); @@ -676,6 +677,12 @@ static int CmdHFMFPChk(const char *cmd) { CLIGetHexWithReturn(5, vkey, &vkeylen); bool pattern1b = arg_get_lit(7); bool pattern2b = arg_get_lit(8); + uint16_t startPattern = 0x0000; + uint8_t vpattern[2]; + int vpatternlen = 0; + CLIGetHexWithReturn(9, vpattern, &vpatternlen); + if (vpatternlen > 0 && vpatternlen <= 2) + startPattern = (vpattern[0] << 8) + vpattern[1]; CLIParserFree(); uint8_t startKeyAB = 0; @@ -688,48 +695,61 @@ static int CmdHFMFPChk(const char *cmd) { if (endSector < startSector) endSector = startSector; - if (pattern1b || pattern2b) { + if (pattern1b) { for (int i = 0; i < 0x100; i++) - memset(keysList[i], i, 16); + memset(keyList[i], i, 16); - keysListLen = 0x100; + keyListLen = 0x100; + } + + if (pattern2b) { + for (uint32_t i = startPattern; i < 0x10000; i++) { + keyList[keyListLen][0] = (i >> 8) & 0xff; + keyList[keyListLen][1] = i & 0xff; + memcpy(&keyList[keyListLen][2], &keyList[keyListLen][0], 2); + memcpy(&keyList[keyListLen][4], &keyList[keyListLen][0], 4); + memcpy(&keyList[keyListLen][8], &keyList[keyListLen][0], 8); + keyListLen++; + if (keyListLen == MAX_KEYS_LIST_LEN) + break; + } + startPattern = (keyList[keyListLen - 1][0] << 8) + keyList[keyListLen - 1][1]; } - if (keysListLen == 0) { + if (keyListLen == 0) { for (int i = 0; i < g_mifare_plus_default_keys_len; i++) { int datalen = 0; - if (param_gethex_to_eol(g_mifare_plus_default_keys[i], 0, keysList[keysListLen], 16, &datalen) > 0) + if (param_gethex_to_eol(g_mifare_plus_default_keys[i], 0, keyList[keyListLen], 16, &datalen) > 0) break; if (datalen != 16) break; - keysListLen++; + keyListLen++; } } - if (keysListLen == 0) { + if (keyListLen == 0) { PrintAndLogEx(ERROR, "Key list is empty. Nothing to check."); return 1; } - uint8_t keyn[2] = {0}; // sector number from 0 for (uint8_t sector = startSector; sector <= endSector; sector++) { // 0-keyA 1-keyB for(uint8_t keyAB = startKeyAB; keyAB <= endKeyAB; keyAB++) { // main cycle with key check - for (int i = 0; i < keysListLen; i++) { + for (int i = 0; i < keyListLen; i++) { uint16_t uKeyNum = 0x4000 + sector * 2 + keyAB; keyn[0] = uKeyNum >> 8; keyn[1] = uKeyNum & 0xff; - res = MifareAuth4(NULL, keyn, keysList[i], selectCard, true, false, false, true); - PrintAndLogEx(WARNING, "sector %d key %d [%s] res: %d", sector, keyAB, sprint_hex_inrow(keysList[i], 16), res); + res = MifareAuth4(NULL, keyn, keyList[i], selectCard, true, false, false, true); + PrintAndLogEx(WARNING, "sector %d key %d [%s] res: %d", sector, keyAB, sprint_hex_inrow(keyList[i], 16), res); if (res == 0) { - PrintAndLogEx(INFO, "Found key for sector %d key %s [%s]", sector, keyAB == 0 ? "A" : "B", sprint_hex_inrow(keysList[i], 16)); + PrintAndLogEx(INFO, "Found key for sector %d key %s [%s]", sector, keyAB == 0 ? "A" : "B", sprint_hex_inrow(keyList[i], 16)); foundKeys[keyAB][sector][0] = 0x01; - memcpy(&foundKeys[keyAB][sector][1], keysList[i], AES_KEY_LEN); + memcpy(&foundKeys[keyAB][sector][1], keyList[i], AES_KEY_LEN); DropField(); selectCard = true; msleep(50); From 1efc731fac29867e64686979cb35ae840851d428 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 29 Nov 2019 17:23:30 +0200 Subject: [PATCH 1166/1854] refactoring and break operation via keyboard --- client/cmdhfmfp.c | 103 +++++++++++++++++++++++++++++++--------------- include/pm3_cmd.h | 2 + 2 files changed, 71 insertions(+), 34 deletions(-) diff --git a/client/cmdhfmfp.c b/client/cmdhfmfp.c index db8df3e29..6a64b01f5 100644 --- a/client/cmdhfmfp.c +++ b/client/cmdhfmfp.c @@ -641,9 +641,72 @@ static int CmdHFMFPWrbl(const char *cmd) { #define AES_KEY_LEN 16 #define MAX_KEYS_LIST_LEN 1024 -static int CmdHFMFPChk(const char *cmd) { + int MFPKeyCheck(uint8_t startSector, uint8_t endSector, uint8_t startKeyAB, uint8_t endKeyAB, + uint8_t keyList[MAX_KEYS_LIST_LEN][AES_KEY_LEN], size_t keyListLen, uint8_t foundKeys[2][64][AES_KEY_LEN + 1]) { int res; bool selectCard = true; + uint8_t keyn[2] = {0}; + + // sector number from 0 + for (uint8_t sector = startSector; sector <= endSector; sector++) { + // 0-keyA 1-keyB + for(uint8_t keyAB = startKeyAB; keyAB <= endKeyAB; keyAB++) { + // main cycle with key check + for (int i = 0; i < keyListLen; i++) { + if (i % 10 == 0) { + if (kbd_enter_pressed()) { + PrintAndLogEx(WARNING, "\nAborted via keyboard!\n"); + DropField(); + return PM3_EOPABORTED; + } + } + + uint16_t uKeyNum = 0x4000 + sector * 2 + keyAB; + keyn[0] = uKeyNum >> 8; + keyn[1] = uKeyNum & 0xff; + + for (int retry = 0; retry < 4; retry++) { + res = MifareAuth4(NULL, keyn, keyList[i], selectCard, true, false, false, true); + if (res != 2) + break; + + printf("retried[%d]...\n", retry); + + DropField(); + selectCard = true; + msleep(100); + } + + PrintAndLogEx(WARNING, "sector %d key %d [%s] res: %d", sector, keyAB, sprint_hex_inrow(keyList[i], 16), res); + + // key for [sector,keyAB] found + if (res == 0) { + PrintAndLogEx(INFO, "Found key for sector %d key %s [%s]", sector, keyAB == 0 ? "A" : "B", sprint_hex_inrow(keyList[i], 16)); + foundKeys[keyAB][sector][0] = 0x01; + memcpy(&foundKeys[keyAB][sector][1], keyList[i], AES_KEY_LEN); + DropField(); + selectCard = true; + msleep(50); + break; + } + + // 5 - auth error (rnd not equal) + if (res != 5) { + DropField(); + return PM3_ECARDEXCHANGE; + } + + selectCard = false; + } + } + } + + DropField(); + return PM3_SUCCESS; +} + +static int CmdHFMFPChk(const char *cmd) { + int res; uint8_t keyList[MAX_KEYS_LIST_LEN][AES_KEY_LEN] = {0}; size_t keyListLen = 0; uint8_t foundKeys[2][64][AES_KEY_LEN + 1] = {0}; @@ -733,45 +796,17 @@ static int CmdHFMFPChk(const char *cmd) { return 1; } - uint8_t keyn[2] = {0}; - // sector number from 0 - for (uint8_t sector = startSector; sector <= endSector; sector++) { - // 0-keyA 1-keyB - for(uint8_t keyAB = startKeyAB; keyAB <= endKeyAB; keyAB++) { - // main cycle with key check - for (int i = 0; i < keyListLen; i++) { - uint16_t uKeyNum = 0x4000 + sector * 2 + keyAB; - keyn[0] = uKeyNum >> 8; - keyn[1] = uKeyNum & 0xff; - - res = MifareAuth4(NULL, keyn, keyList[i], selectCard, true, false, false, true); - PrintAndLogEx(WARNING, "sector %d key %d [%s] res: %d", sector, keyAB, sprint_hex_inrow(keyList[i], 16), res); - if (res == 0) { - PrintAndLogEx(INFO, "Found key for sector %d key %s [%s]", sector, keyAB == 0 ? "A" : "B", sprint_hex_inrow(keyList[i], 16)); - foundKeys[keyAB][sector][0] = 0x01; - memcpy(&foundKeys[keyAB][sector][1], keyList[i], AES_KEY_LEN); - DropField(); - selectCard = true; - msleep(50); - break; - } - - if (res != 5) - break; - - selectCard = false; - } - } - } - - DropField(); + + res = MFPKeyCheck(startSector, endSector, startKeyAB, endKeyAB, keyList, keyListLen, foundKeys); + printf("--- res: %d\n", res); // print result bool printedHeader = false; for (uint8_t sector = startSector; sector <= endSector; sector++) { if (foundKeys[0][sector][0] || foundKeys[1][sector][0]) { if (!printedHeader) { - PrintAndLogEx(INFO, "\n.------.--------------------------------.--------------------------------."); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, ".------.--------------------------------.--------------------------------."); PrintAndLogEx(INFO, "|sector| key A | key B |"); PrintAndLogEx(INFO, "|------|--------------------------------|--------------------------------|"); printedHeader = true; diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 892ec533f..e775b3413 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -590,6 +590,8 @@ typedef struct { #define PM3_EWRONGANSVER -16 // Memory out-of-bounds error client/pm3: error when a read/write is outside the expected array #define PM3_EOUTOFBOUND -17 +// exchange with card error client/pm3: error when cant get answer from card or got an incorrect answer +#define PM3_ECARDEXCHANGE -18 // No data pm3: no data available, no host frame available (not really an error) #define PM3_ENODATA -98 // Quit program client: reserved, order to quit the program From a861d2971cff72b8c0fd196bd62540c90186da9c Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 29 Nov 2019 17:29:36 +0200 Subject: [PATCH 1167/1854] specify key in the command line --- client/cmdhfmfp.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/client/cmdhfmfp.c b/client/cmdhfmfp.c index 6a64b01f5..f3ad37405 100644 --- a/client/cmdhfmfp.c +++ b/client/cmdhfmfp.c @@ -735,17 +735,30 @@ static int CmdHFMFPChk(const char *cmd) { bool keyB = arg_get_lit(2); uint8_t startSector = arg_get_int_def(3, 0); uint8_t endSector = arg_get_int_def(4, 0); + uint8_t vkey[16] = {0}; int vkeylen = 0; CLIGetHexWithReturn(5, vkey, &vkeylen); + if (vkeylen > 0) { + if (vkeylen == 16) { + memcpy(&keyList[keyListLen], vkey, 16); + keyListLen++; + } else { + PrintAndLogEx(ERROR, "Specified key must have 16 bytes length."); + return PM3_EINVARG; + } + } + bool pattern1b = arg_get_lit(7); bool pattern2b = arg_get_lit(8); + uint16_t startPattern = 0x0000; uint8_t vpattern[2]; int vpatternlen = 0; CLIGetHexWithReturn(9, vpattern, &vpatternlen); if (vpatternlen > 0 && vpatternlen <= 2) startPattern = (vpattern[0] << 8) + vpattern[1]; + CLIParserFree(); uint8_t startKeyAB = 0; @@ -793,7 +806,7 @@ static int CmdHFMFPChk(const char *cmd) { if (keyListLen == 0) { PrintAndLogEx(ERROR, "Key list is empty. Nothing to check."); - return 1; + return PM3_EINVARG; } From 8e6f08835d81684c91c47a388b8769803d5fbd19 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 29 Nov 2019 17:34:54 +0200 Subject: [PATCH 1168/1854] added some error handling --- client/cmdhfmfp.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/client/cmdhfmfp.c b/client/cmdhfmfp.c index f3ad37405..3d1f41b8f 100644 --- a/client/cmdhfmfp.c +++ b/client/cmdhfmfp.c @@ -751,13 +751,26 @@ static int CmdHFMFPChk(const char *cmd) { bool pattern1b = arg_get_lit(7); bool pattern2b = arg_get_lit(8); + + if (pattern1b && pattern2b) { + PrintAndLogEx(ERROR, "Pattern search mode must be 2-byte or 1-byte only."); + return PM3_EINVARG; + } uint16_t startPattern = 0x0000; uint8_t vpattern[2]; int vpatternlen = 0; CLIGetHexWithReturn(9, vpattern, &vpatternlen); - if (vpatternlen > 0 && vpatternlen <= 2) - startPattern = (vpattern[0] << 8) + vpattern[1]; + if (vpatternlen > 0) { + if (vpatternlen > 0 && vpatternlen <= 2) { + startPattern = (vpattern[0] << 8) + vpattern[1]; + } else { + PrintAndLogEx(ERROR, "Pattern must be 2-byte length."); + return PM3_EINVARG; + } + if (!pattern2b) + PrintAndLogEx(WARNING, "Pattern entered, but search mode not is 2-byte search."); + } CLIParserFree(); @@ -809,7 +822,6 @@ static int CmdHFMFPChk(const char *cmd) { return PM3_EINVARG; } - res = MFPKeyCheck(startSector, endSector, startKeyAB, endKeyAB, keyList, keyListLen, foundKeys); printf("--- res: %d\n", res); From b8a339361b00e9cca8794b204c18a5e39ea1f4b4 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 30 Nov 2019 17:06:03 +0100 Subject: [PATCH 1169/1854] textual --- client/cmdhficlass.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index b57996af1..ae1109717 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -334,15 +334,15 @@ static void fuse_config(const picopass_hdr *hdr) { if (isset(fuses, FUSE_FPERS)) PrintAndLogEx(SUCCESS, " Mode: Personalization [Programmable]"); else - PrintAndLogEx(NORMAL, " Mode: Application [Locked]"); + PrintAndLogEx(SUCCESS, " Mode: Application [Locked]"); if (isset(fuses, FUSE_CODING1)) { - PrintAndLogEx(NORMAL, " Coding: RFU"); + PrintAndLogEx(SUCCESS, " Coding: RFU"); } else { if (isset(fuses, FUSE_CODING0)) - PrintAndLogEx(NORMAL, " Coding: ISO 14443-2 B/ISO 15693"); + PrintAndLogEx(SUCCESS, " Coding: ISO 14443-2 B/ISO 15693"); else - PrintAndLogEx(NORMAL, " Coding: ISO 14443B only"); + PrintAndLogEx(SUCCESS, " Coding: ISO 14443B only"); } // 1 1 if (isset(fuses, FUSE_CRYPT1) && isset(fuses, FUSE_CRYPT0)) PrintAndLogEx(SUCCESS, " Crypt: Secured page, keys not locked"); @@ -354,7 +354,7 @@ static void fuse_config(const picopass_hdr *hdr) { if (notset(fuses, FUSE_CRYPT1) && notset(fuses, FUSE_CRYPT0)) PrintAndLogEx(NORMAL, " Crypt: No auth possible. Read only if RA is enabled"); if (isset(fuses, FUSE_RA)) - PrintAndLogEx(NORMAL, " RA: Read access enabled"); + PrintAndLogEx(SUCCESS, " RA: Read access enabled"); else PrintAndLogEx(WARNING, " RA: Read access not enabled"); } @@ -2827,12 +2827,13 @@ int readIclass(bool loop, bool verbose) { } if (readStatus & FLAG_ICLASS_READER_CSN) { - PrintAndLogEx(NORMAL, " CSN: %s", sprint_hex(data, 8)); + PrintAndLogEx(NORMAL, "\n"); + PrintAndLogEx(SUCCESS, " CSN: %s", sprint_hex(data, 8)); tagFound = true; } if (readStatus & FLAG_ICLASS_READER_CC) { - PrintAndLogEx(NORMAL, " CC: %s", sprint_hex(data + 16, 8)); + PrintAndLogEx(SUCCESS, " CC: %s", sprint_hex(data + 16, 8)); } if (readStatus & FLAG_ICLASS_READER_CONF) { @@ -2847,7 +2848,7 @@ int readIclass(bool loop, bool verbose) { bool se_enabled = (memcmp((uint8_t *)(data + 8 * 5), "\xff\xff\xff\x00\x06\xff\xff\xff", 8) == 0); - PrintAndLogEx(NORMAL, " App IA: %s", sprint_hex(data + 8 * 5, 8)); + PrintAndLogEx(SUCCESS, " App IA: %s", sprint_hex(data + 8 * 5, 8)); if (isHidRange) { if (legacy) From 3ad7c0d319c45cb5157eb684842d247dfc4ac745 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 30 Nov 2019 19:57:29 +0100 Subject: [PATCH 1170/1854] textual --- client/cmdhf15.c | 64 ++++++++++++++++++++++++------------------------ 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/client/cmdhf15.c b/client/cmdhf15.c index 1650aefd4..eed6bf3d7 100644 --- a/client/cmdhf15.c +++ b/client/cmdhf15.c @@ -517,7 +517,7 @@ static bool prepareHF15Cmd(char **cmd, uint16_t *reqlen, uint8_t *arg1, uint8_t return false; } memcpy(&req[tmpreqlen], uid, sizeof(uid)); - PrintAndLogEx(NORMAL, "Detected UID %s", sprintUID(NULL, uid)); + PrintAndLogEx(SUCCESS, "Detected UID %s", sprintUID(NULL, uid)); tmpreqlen += sizeof(uid); break; default: @@ -530,7 +530,7 @@ static bool prepareHF15Cmd(char **cmd, uint16_t *reqlen, uint8_t *arg1, uint8_t uid[7 - i] = temp & 0xff; } - PrintAndLogEx(NORMAL, "Using UID %s", sprintUID(NULL, uid)); + PrintAndLogEx(SUCCESS, "Using UID %s", sprintUID(NULL, uid)); memcpy(&req[tmpreqlen], uid, sizeof(uid)); tmpreqlen += sizeof(uid); break; @@ -569,7 +569,7 @@ static int CmdHF15Demod(const char *Cmd) { } } - PrintAndLogEx(NORMAL, "SOF at %d, correlation %zu", maxPos, max / (ARRAYLEN(FrameSOF) / skip)); + PrintAndLogEx(INFO, "SOF at %d, correlation %zu", maxPos, max / (ARRAYLEN(FrameSOF) / skip)); i = maxPos + ARRAYLEN(FrameSOF) / skip; int k = 0; @@ -592,7 +592,7 @@ static int CmdHF15Demod(const char *Cmd) { corr1 *= 4; if (corrEOF > corr1 && corrEOF > corr0) { - PrintAndLogEx(NORMAL, "EOF at %d", i); + PrintAndLogEx(INFO, "EOF at %d", i); break; } else if (corr1 > corr0) { i += ARRAYLEN(Logic1) / skip; @@ -606,21 +606,21 @@ static int CmdHF15Demod(const char *Cmd) { mask = 0x01; } if ((i + (int)ARRAYLEN(FrameEOF)) >= GraphTraceLen) { - PrintAndLogEx(NORMAL, "ran off end!"); + PrintAndLogEx(INFO, "ran off end!"); break; } } if (mask != 0x01) { PrintAndLogEx(WARNING, "Warning, uneven octet! (discard extra bits!)"); - PrintAndLogEx(NORMAL, " mask = %02x", mask); + PrintAndLogEx(INFO, " mask = %02x", mask); } - PrintAndLogEx(NORMAL, "%d octets", k); + PrintAndLogEx(INFO, "%d octets", k); for (i = 0; i < k; i++) - PrintAndLogEx(NORMAL, "# %2d: %02x ", i, outBuf[i]); + PrintAndLogEx(SUCCESS, "# %2d: %02x ", i, outBuf[i]); - PrintAndLogEx(NORMAL, "CRC %04x", Crc15(outBuf, k - 2)); + PrintAndLogEx(SUCCESS, "CRC %04x", Crc15(outBuf, k - 2)); return PM3_SUCCESS; } @@ -741,13 +741,13 @@ static int NxpSysInfo(uint8_t *uid) { PrintAndLogEx(NORMAL, ""); if (status < 2) { - PrintAndLogEx(NORMAL, " EAS (Electronic Article Surveillance) is not active"); + PrintAndLogEx(INFO, " EAS (Electronic Article Surveillance) is not active"); } else { recv = resp.data.asBytes; if (!(recv[0] & ISO15_RES_ERROR)) { - PrintAndLogEx(NORMAL, " EAS (Electronic Article Surveillance) is active."); - PrintAndLogEx(NORMAL, " EAS sequence: %s", sprint_hex(recv + 1, 32)); + PrintAndLogEx(INFO, " EAS (Electronic Article Surveillance) is active."); + PrintAndLogEx(INFO, " EAS sequence: %s", sprint_hex(recv + 1, 32)); } } } @@ -866,36 +866,36 @@ static int CmdHF15Info(const char *Cmd) { memcpy(uid, recv + 2, sizeof(uid)); - PrintAndLogEx(NORMAL, " UID : %s", sprintUID(NULL, uid)); - PrintAndLogEx(NORMAL, " TYPE : %s", getTagInfo_15(recv + 2)); - PrintAndLogEx(NORMAL, " SYSINFO : %s", sprint_hex(recv, status - 2)); + PrintAndLogEx(SUCCESS, " UID : %s", sprintUID(NULL, uid)); + PrintAndLogEx(SUCCESS, " TYPE : %s", getTagInfo_15(recv + 2)); + PrintAndLogEx(SUCCESS, " SYSINFO : %s", sprint_hex(recv, status - 2)); // DSFID if (recv[1] & 0x01) - PrintAndLogEx(NORMAL, " - DSFID supported [0x%02X]", recv[10]); + PrintAndLogEx(SUCCESS, " - DSFID supported [0x%02X]", recv[10]); else - PrintAndLogEx(NORMAL, " - DSFID not supported"); + PrintAndLogEx(SUCCESS, " - DSFID not supported"); // AFI if (recv[1] & 0x02) - PrintAndLogEx(NORMAL, " - AFI supported [0x%02X]", recv[11]); + PrintAndLogEx(SUCCESS, " - AFI supported [0x%02X]", recv[11]); else - PrintAndLogEx(NORMAL, " - AFI not supported"); + PrintAndLogEx(SUCCESS, " - AFI not supported"); // IC reference if (recv[1] & 0x08) - PrintAndLogEx(NORMAL, " - IC reference supported [0x%02X]", recv[14]); + PrintAndLogEx(SUCCESS, " - IC reference supported [0x%02X]", recv[14]); else - PrintAndLogEx(NORMAL, " - IC reference not supported"); + PrintAndLogEx(SUCCESS, " - IC reference not supported"); // memory if (recv[1] & 0x04) { - PrintAndLogEx(NORMAL, " - Tag provides info on memory layout (vendor dependent)"); + PrintAndLogEx(SUCCESS, " - Tag provides info on memory layout (vendor dependent)"); uint8_t blocks = recv[12] + 1; uint8_t size = (recv[13] & 0x1F); - PrintAndLogEx(NORMAL, " %u (or %u) bytes/blocks x %u blocks", size + 1, size, blocks); + PrintAndLogEx(SUCCESS, " %u (or %u) bytes/blocks x %u blocks", size + 1, size, blocks); } else { - PrintAndLogEx(NORMAL, " - Tag does not provide information on memory layout"); + PrintAndLogEx(SUCCESS, " - Tag does not provide information on memory layout"); } // Check if SLIX2 and attempt to get NXP System Information @@ -1015,7 +1015,7 @@ static int CmdHF15WriteAfi(const char *Cmd) { SendCommandOLD(CMD_HF_ISO15693_COMMAND, reqlen, arg1, 1, req, reqlen); if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { - PrintAndLogEx(NORMAL, "iso15693 card select failed"); + PrintAndLogEx(ERR, "iso15693 card select failed"); DropField(); return PM3_ETIMEOUT; } @@ -1074,7 +1074,7 @@ static int CmdHF15WriteDsfid(const char *Cmd) { SendCommandOLD(CMD_HF_ISO15693_COMMAND, reqlen, arg1, 1, req, reqlen); if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { - PrintAndLogEx(NORMAL, "iso15693 card select failed"); + PrintAndLogEx(ERR, "iso15693 card select failed"); DropField(); return PM3_ETIMEOUT; } @@ -1142,7 +1142,7 @@ static int CmdHF15Dump(const char *Cmd) { } // detect blocksize from card :) - PrintAndLogEx(NORMAL, "Reading memory from tag UID " _YELLOW_("%s"), sprintUID(NULL, uid)); + PrintAndLogEx(SUCCESS, "Reading memory from tag UID " _YELLOW_("%s"), sprintUID(NULL, uid)); int blocknum = 0; uint8_t *recv = NULL; @@ -1523,7 +1523,7 @@ static int CmdHF15Write(const char *Cmd) { AddCrc15(req, reqlen); reqlen += 2; - PrintAndLogEx(NORMAL, "iso15693 writing to page %02d (0x%02X) | data ", pagenum, pagenum); + PrintAndLogEx(INFO, "iso15693 writing to page %02d (0x%02X) | data ", pagenum, pagenum); clearCommandBuffer(); SendCommandOLD(CMD_HF_ISO15693_COMMAND, reqlen, arg1, 1, req, reqlen); @@ -1550,7 +1550,7 @@ static int CmdHF15Write(const char *Cmd) { } if (recv[0] & ISO15_RES_ERROR) { - PrintAndLogEx(NORMAL, "iso15693 card returned error %i: %s", recv[0], TagErrorStr(recv[0])); + PrintAndLogEx(ERR, "iso15693 card returned error %i: %s", recv[0], TagErrorStr(recv[0])); return PM3_EWRONGANSVER; } @@ -1703,7 +1703,7 @@ static int CmdHF15CSetUID(const char *Cmd) { } PrintAndLogEx(SUCCESS, "new UID | %s", sprint_hex(uid, sizeof(uid))); - PrintAndLogEx(NORMAL, "Using backdoor Magic tag function"); + PrintAndLogEx(INFO, "Using backdoor Magic tag function"); if (!getUID(oldUid)) { PrintAndLogEx(FAILED, "Can't get old UID."); @@ -1755,8 +1755,8 @@ static int CmdHF15CSetUID(const char *Cmd) { if (reply) { if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { uint8_t len = resp.oldarg[0]; - PrintAndLogEx(NORMAL, "received %i octets", len); - PrintAndLogEx(NORMAL, "%s", sprint_hex(resp.data.asBytes, len)); + PrintAndLogEx(INFO, "received %i octets", len); + PrintAndLogEx(INFO, "%s", sprint_hex(resp.data.asBytes, len)); } else { PrintAndLogEx(WARNING, "timeout while waiting for reply."); } From bd80fa254ea677e169c8a4bbb2241adf22901aa6 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 30 Nov 2019 20:02:02 +0100 Subject: [PATCH 1171/1854] textual --- client/cmdhf15.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/client/cmdhf15.c b/client/cmdhf15.c index eed6bf3d7..999c10e1f 100644 --- a/client/cmdhf15.c +++ b/client/cmdhf15.c @@ -1203,8 +1203,7 @@ static int CmdHF15Dump(const char *Cmd) { DropField(); - PrintAndLogEx(NORMAL, "\n"); - + PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "block# | data |lck| ascii"); PrintAndLogEx(NORMAL, "---------+--------------+---+----------"); for (int i = 0; i < blocknum; i++) { @@ -1305,8 +1304,8 @@ static int CmdHF15Raw(const char *Cmd) { if (reply) { if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { uint8_t len = resp.oldarg[0]; - PrintAndLogEx(NORMAL, "received %i octets", len); - PrintAndLogEx(NORMAL, "%s", sprint_hex(resp.data.asBytes, len)); + PrintAndLogEx(INFO, "received %i octets", len); + PrintAndLogEx(SUCCESS, "%s", sprint_hex(resp.data.asBytes, len)); } else { PrintAndLogEx(WARNING, "timeout while waiting for reply."); } @@ -1443,7 +1442,7 @@ static int CmdHF15Read(const char *Cmd) { SendCommandOLD(CMD_HF_ISO15693_COMMAND, reqlen, arg1, 1, req, reqlen); if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { - PrintAndLogEx(NORMAL, "iso15693 card select failed"); + PrintAndLogEx(ERR, "iso15693 card select failed"); DropField(); return PM3_ETIMEOUT; } @@ -1452,14 +1451,14 @@ static int CmdHF15Read(const char *Cmd) { uint32_t status = resp.oldarg[0]; if (status < 2) { - PrintAndLogEx(NORMAL, "iso15693 card select failed"); + PrintAndLogEx(ERR, "iso15693 card select failed"); return PM3_EWRONGANSVER; } recv = resp.data.asBytes; if (!CheckCrc15(recv, status)) { - PrintAndLogEx(NORMAL, "CRC failed"); + PrintAndLogEx(ERR, "CRC failed"); return PM3_ESOFT; } @@ -1817,7 +1816,7 @@ bool readHF15Uid(bool verbose) { return false; } - PrintAndLogEx(NORMAL, " UID : %s", sprintUID(NULL, uid)); - PrintAndLogEx(NORMAL, " TYPE : %s", getTagInfo_15(uid)); + PrintAndLogEx(SUCCESS, " UID : %s", sprintUID(NULL, uid)); + PrintAndLogEx(SUCCESS, " TYPE : %s", getTagInfo_15(uid)); return true; } From 6166849382de01c9f107e355e9328ed59ffa69c6 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 30 Nov 2019 20:04:37 +0100 Subject: [PATCH 1172/1854] textual --- client/cmdhf15.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdhf15.c b/client/cmdhf15.c index 999c10e1f..25fc00264 100644 --- a/client/cmdhf15.c +++ b/client/cmdhf15.c @@ -1815,7 +1815,7 @@ bool readHF15Uid(bool verbose) { if (verbose) PrintAndLogEx(WARNING, "No tag found."); return false; } - + PrintAndLogEx(NORMAL, ""); PrintAndLogEx(SUCCESS, " UID : %s", sprintUID(NULL, uid)); PrintAndLogEx(SUCCESS, " TYPE : %s", getTagInfo_15(uid)); return true; From 1a052b26078fc3b993d541e9c10fca0b4bf79a74 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 30 Nov 2019 20:15:50 +0100 Subject: [PATCH 1173/1854] textual --- client/cmdhf14a.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index 777b7d25c..b5eb8c28b 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -256,20 +256,20 @@ int Hf14443_4aGetCardData(iso14a_card_select_t *card) { } if (select_status == 3) { - PrintAndLogEx(NORMAL, "E->Card doesn't support standard iso14443-3 anticollision"); - PrintAndLogEx(NORMAL, "\tATQA : %02x %02x", card->atqa[1], card->atqa[0]); + PrintAndLogEx(INFO, "E->Card doesn't support standard iso14443-3 anticollision"); + PrintAndLogEx(SUCCESS, "\tATQA : %02x %02x", card->atqa[1], card->atqa[0]); return 1; } - PrintAndLogEx(NORMAL, " UID: %s", sprint_hex(card->uid, card->uidlen)); - PrintAndLogEx(NORMAL, "ATQA: %02x %02x", card->atqa[1], card->atqa[0]); - PrintAndLogEx(NORMAL, " SAK: %02x [%" PRIu64 "]", card->sak, resp.oldarg[0]); + PrintAndLogEx(SUCCESS, " UID: %s", sprint_hex(card->uid, card->uidlen)); + PrintAndLogEx(SUCCESS, "ATQA: %02x %02x", card->atqa[1], card->atqa[0]); + PrintAndLogEx(SUCCESS, " SAK: %02x [%" PRIu64 "]", card->sak, resp.oldarg[0]); if (card->ats_len < 3) { // a valid ATS consists of at least the length byte (TL) and 2 CRC bytes - PrintAndLogEx(NORMAL, "E-> Error ATS length(%d) : %s", card->ats_len, sprint_hex(card->ats, card->ats_len)); + PrintAndLogEx(INFO, "E-> Error ATS length(%d) : %s", card->ats_len, sprint_hex(card->ats, card->ats_len)); return 1; } - PrintAndLogEx(NORMAL, " ATS: %s", sprint_hex(card->ats, card->ats_len)); + PrintAndLogEx(SUCCESS, " ATS: %s", sprint_hex(card->ats, card->ats_len)); return 0; } @@ -334,18 +334,18 @@ static int CmdHF14AReader(const char *Cmd) { } if (select_status == 3) { - PrintAndLogEx(NORMAL, "Card doesn't support standard iso14443-3 anticollision"); - PrintAndLogEx(NORMAL, "ATQA : %02x %02x", card.atqa[1], card.atqa[0]); + PrintAndLogEx(INFO, "Card doesn't support standard iso14443-3 anticollision"); + PrintAndLogEx(SUCCESS, "ATQA : %02x %02x", card.atqa[1], card.atqa[0]); DropField(); return 1; } - PrintAndLogEx(NORMAL, " UID : %s", sprint_hex(card.uid, card.uidlen)); - PrintAndLogEx(NORMAL, "ATQA : %02x %02x", card.atqa[1], card.atqa[0]); - PrintAndLogEx(NORMAL, " SAK : %02x [%" PRIu64 "]", card.sak, resp.oldarg[0]); + PrintAndLogEx(SUCCESS, " UID : %s", sprint_hex(card.uid, card.uidlen)); + PrintAndLogEx(SUCCESS, "ATQA : %02x %02x", card.atqa[1], card.atqa[0]); + PrintAndLogEx(SUCCESS, " SAK : %02x [%" PRIu64 "]", card.sak, resp.oldarg[0]); if (card.ats_len >= 3) { // a valid ATS consists of at least the length byte (TL) and 2 CRC bytes - PrintAndLogEx(NORMAL, " ATS : %s", sprint_hex(card.ats, card.ats_len)); + PrintAndLogEx(SUCCESS, " ATS : %s", sprint_hex(card.ats, card.ats_len)); } if (!disconnectAfter) { @@ -422,7 +422,7 @@ static int CmdHF14ACUIDs(const char *Cmd) { for (uint16_t m = 0; m < card->uidlen; m++) { sprintf(&uid_string[2 * m], "%02X", card->uid[m]); } - PrintAndLogEx(NORMAL, "%s", uid_string); + PrintAndLogEx(SUCCESS, "%s", uid_string); } } PrintAndLogEx(SUCCESS, "end: %" PRIu64 " seconds", (msclock() - t1) / 1000); @@ -528,9 +528,9 @@ int CmdHF14ASim(const char *Cmd) { if (keypress && (flags & FLAG_NR_AR_ATTACK) == FLAG_NR_AR_ATTACK) { // inform device to break the sim loop since client has exited - SendCommandNG(CMD_BREAK_LOOP, NULL, 0); + SendCommandNG(CMD_BREAK_LOOP, NULL, 0); } - + if (resp.status == PM3_EOPABORTED && ((flags & FLAG_NR_AR_ATTACK) == FLAG_NR_AR_ATTACK)) showSectorTable(); From 5fa2eb9db8d62104a79881b80bedd1feb2dc1bc2 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 30 Nov 2019 22:25:53 +0100 Subject: [PATCH 1174/1854] textual --- client/cmdhf14a.c | 98 +++++++++++++++++++++++------------------------ 1 file changed, 49 insertions(+), 49 deletions(-) diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index b5eb8c28b..c8f8093d6 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -1274,15 +1274,15 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { } if (select_status == 3) { - PrintAndLogEx(NORMAL, "Card doesn't support standard iso14443-3 anticollision"); - PrintAndLogEx(NORMAL, "ATQA : %02x %02x", card.atqa[1], card.atqa[0]); + PrintAndLogEx(INFO, "Card doesn't support standard iso14443-3 anticollision"); + PrintAndLogEx(SUCCESS, "ATQA : %02x %02x", card.atqa[1], card.atqa[0]); DropField(); return select_status; } - PrintAndLogEx(NORMAL, " UID : %s", sprint_hex(card.uid, card.uidlen)); - PrintAndLogEx(NORMAL, "ATQA : %02x %02x", card.atqa[1], card.atqa[0]); - PrintAndLogEx(NORMAL, " SAK : %02x [%" PRIu64 "]", card.sak, resp.oldarg[0]); + PrintAndLogEx(SUCCESS, " UID : %s", sprint_hex(card.uid, card.uidlen)); + PrintAndLogEx(SUCCESS, "ATQA : %02x %02x", card.atqa[1], card.atqa[0]); + PrintAndLogEx(SUCCESS, " SAK : %02x [%" PRIu64 "]", card.sak, resp.oldarg[0]); bool isMifareClassic = true; switch (card.sak) { @@ -1296,7 +1296,7 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { if (tagT != UL_ERROR) ul_print_type(tagT, 0); else - PrintAndLogEx(NORMAL, "TYPE: Possible AZTEK (iso14443a compliant)"); + PrintAndLogEx(SUCCESS, "TYPE: Possible AZTEK (iso14443a compliant)"); // reconnect for further tests clearCommandBuffer(); @@ -1313,49 +1313,49 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { } break; case 0x01: - PrintAndLogEx(NORMAL, "TYPE : NXP TNP3xxx Activision Game Appliance"); + PrintAndLogEx(SUCCESS, "TYPE : NXP TNP3xxx Activision Game Appliance"); break; case 0x04: - PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE (various !DESFire !DESFire EV1)"); + PrintAndLogEx(SUCCESS, "TYPE : NXP MIFARE (various !DESFire !DESFire EV1)"); isMifareClassic = false; break; case 0x08: - PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE CLASSIC 1k | Plus 2k SL1 | 1k Ev1"); + PrintAndLogEx(SUCCESS, "TYPE : NXP MIFARE CLASSIC 1k | Plus 2k SL1 | 1k Ev1"); break; case 0x09: - PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE Mini 0.3k"); + PrintAndLogEx(SUCCESS, "TYPE : NXP MIFARE Mini 0.3k"); break; case 0x0A: - PrintAndLogEx(NORMAL, "TYPE : FM11RF005SH (Shanghai Metro)"); + PrintAndLogEx(SUCCESS, "TYPE : FM11RF005SH (Shanghai Metro)"); break; case 0x10: - PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE Plus 2k SL2"); + PrintAndLogEx(SUCCESS, "TYPE : NXP MIFARE Plus 2k SL2"); break; case 0x11: - PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE Plus 4k SL2"); + PrintAndLogEx(SUCCESS, "TYPE : NXP MIFARE Plus 4k SL2"); break; case 0x18: - PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE Classic 4k | Plus 4k SL1 | 4k Ev1"); + PrintAndLogEx(SUCCESS, "TYPE : NXP MIFARE Classic 4k | Plus 4k SL1 | 4k Ev1"); break; case 0x20: - PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE DESFire 4k | DESFire EV1 2k/4k/8k | Plus 2k/4k SL3 | JCOP 31/41"); + PrintAndLogEx(SUCCESS, "TYPE : NXP MIFARE DESFire 4k | DESFire EV1 2k/4k/8k | Plus 2k/4k SL3 | JCOP 31/41"); isMifareClassic = false; break; case 0x24: - PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE DESFire | DESFire EV1"); + PrintAndLogEx(SUCCESS, "TYPE : NXP MIFARE DESFire | DESFire EV1"); isMifareClassic = false; break; case 0x28: - PrintAndLogEx(NORMAL, "TYPE : JCOP31 or JCOP41 v2.3.1"); + PrintAndLogEx(SUCCESS, "TYPE : JCOP31 or JCOP41 v2.3.1"); break; case 0x38: - PrintAndLogEx(NORMAL, "TYPE : Nokia 6212 or 6131 MIFARE CLASSIC 4K"); + PrintAndLogEx(SUCCESS, "TYPE : Nokia 6212 or 6131 MIFARE CLASSIC 4K"); break; case 0x88: - PrintAndLogEx(NORMAL, "TYPE : Infineon MIFARE CLASSIC 1K"); + PrintAndLogEx(SUCCESS, "TYPE : Infineon MIFARE CLASSIC 1K"); break; case 0x98: - PrintAndLogEx(NORMAL, "TYPE : Gemplus MPCOS"); + PrintAndLogEx(SUCCESS, "TYPE : Gemplus MPCOS"); break; default: ; @@ -1363,7 +1363,7 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { // Double & triple sized UID, can be mapped to a manufacturer. if (card.uidlen > 4) { - PrintAndLogEx(NORMAL, "MANUFACTURER : %s", getTagInfo(card.uid[0])); + PrintAndLogEx(SUCCESS, "MANUFACTURER : %s", getTagInfo(card.uid[0])); } // try to request ATS even if tag claims not to support it @@ -1382,12 +1382,12 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { int pos; if (select_status == 2) { - PrintAndLogEx(NORMAL, "SAK incorrectly claims that card doesn't support RATS"); + PrintAndLogEx(INFO, "SAK incorrectly claims that card doesn't support RATS"); } - PrintAndLogEx(NORMAL, " ATS : %s", sprint_hex(card.ats, card.ats_len)); - PrintAndLogEx(NORMAL, " - TL : length is %d bytes", card.ats[0]); + PrintAndLogEx(SUCCESS, " ATS : %s", sprint_hex(card.ats, card.ats_len)); + PrintAndLogEx(SUCCESS, " - TL : length is %d bytes", card.ats[0]); if (card.ats[0] != card.ats_len - 2) { - PrintAndLogEx(NORMAL, "ATS may be corrupted. Length of ATS (%d bytes incl. 2 Bytes CRC) doesn't match TL", card.ats_len); + PrintAndLogEx(SUCCESS, "ATS may be corrupted. Length of ATS (%d bytes incl. 2 Bytes CRC) doesn't match TL", card.ats_len); } if (card.ats[0] > 1) { // there is a format byte (T0) @@ -1396,7 +1396,7 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { tc1 = (card.ats[1] & 0x40) == 0x40; int16_t fsci = card.ats[1] & 0x0f; - PrintAndLogEx(NORMAL, " - T0 : TA1 is%s present, TB1 is%s present, " + PrintAndLogEx(SUCCESS, " - T0 : TA1 is%s present, TB1 is%s present, " "TC1 is%s present, FSCI is %d (FSC = %d)", (ta1 ? "" : " NOT"), (tb1 ? "" : " NOT"), @@ -1417,7 +1417,7 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { if (card.ats[pos] & 0x04) strcat(dr, "8, "); if (strlen(ds) != 0) ds[strlen(ds) - 2] = '\0'; if (strlen(dr) != 0) dr[strlen(dr) - 2] = '\0'; - PrintAndLogEx(NORMAL, " - TA1 : different divisors are%s supported, " + PrintAndLogEx(SUCCESS, " - TA1 : different divisors are%s supported, " "DR: [%s], DS: [%s]", ((card.ats[pos] & 0x80) ? " NOT" : ""), dr, @@ -1429,7 +1429,7 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { if (tb1) { uint32_t sfgi = card.ats[pos] & 0x0F; uint32_t fwi = card.ats[pos] >> 4; - PrintAndLogEx(NORMAL, " - TB1 : SFGI = %d (SFGT = %s%d/fc), FWI = %d (FWT = %d/fc)", + PrintAndLogEx(SUCCESS, " - TB1 : SFGI = %d (SFGT = %s%d/fc), FWI = %d (FWT = %d/fc)", (sfgi), sfgi ? "" : "(not needed) ", sfgi ? (1 << 12) << sfgi : 0, @@ -1439,7 +1439,7 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { pos++; } if (tc1) { - PrintAndLogEx(NORMAL, " - TC1 : NAD is%s supported, CID is%s supported", + PrintAndLogEx(SUCCESS, " - TC1 : NAD is%s supported, CID is%s supported", (card.ats[pos] & 0x01) ? "" : " NOT", (card.ats[pos] & 0x02) ? "" : " NOT"); pos++; @@ -1453,63 +1453,63 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { tip = "-> MIFARE Plus S 2K or 4K"; } } - PrintAndLogEx(NORMAL, " - HB : %s%s", sprint_hex(card.ats + pos, card.ats[0] - pos), tip); + PrintAndLogEx(SUCCESS, " - HB : %s%s", sprint_hex(card.ats + pos, card.ats[0] - pos), tip); if (card.ats[pos] == 0xC1) { - PrintAndLogEx(NORMAL, " c1 -> Mifare or (multiple) virtual cards of various type"); - PrintAndLogEx(NORMAL, " %02x -> Length is %d bytes", card.ats[pos + 1], card.ats[pos + 1]); + PrintAndLogEx(SUCCESS, " c1 -> Mifare or (multiple) virtual cards of various type"); + PrintAndLogEx(SUCCESS, " %02x -> Length is %d bytes", card.ats[pos + 1], card.ats[pos + 1]); switch (card.ats[pos + 2] & 0xf0) { case 0x10: - PrintAndLogEx(NORMAL, " 1x -> MIFARE DESFire"); + PrintAndLogEx(SUCCESS, " 1x -> MIFARE DESFire"); break; case 0x20: - PrintAndLogEx(NORMAL, " 2x -> MIFARE Plus"); + PrintAndLogEx(SUCCESS, " 2x -> MIFARE Plus"); break; } switch (card.ats[pos + 2] & 0x0f) { case 0x00: - PrintAndLogEx(NORMAL, " x0 -> <1 kByte"); + PrintAndLogEx(SUCCESS, " x0 -> <1 kByte"); break; case 0x01: - PrintAndLogEx(NORMAL, " x1 -> 1 kByte"); + PrintAndLogEx(SUCCESS, " x1 -> 1 kByte"); break; case 0x02: - PrintAndLogEx(NORMAL, " x2 -> 2 kByte"); + PrintAndLogEx(SUCCESS, " x2 -> 2 kByte"); break; case 0x03: - PrintAndLogEx(NORMAL, " x3 -> 4 kByte"); + PrintAndLogEx(SUCCESS, " x3 -> 4 kByte"); break; case 0x04: - PrintAndLogEx(NORMAL, " x4 -> 8 kByte"); + PrintAndLogEx(SUCCESS, " x4 -> 8 kByte"); break; } switch (card.ats[pos + 3] & 0xf0) { case 0x00: - PrintAndLogEx(NORMAL, " 0x -> Engineering sample"); + PrintAndLogEx(SUCCESS, " 0x -> Engineering sample"); break; case 0x20: - PrintAndLogEx(NORMAL, " 2x -> Released"); + PrintAndLogEx(SUCCESS, " 2x -> Released"); break; } switch (card.ats[pos + 3] & 0x0f) { case 0x00: - PrintAndLogEx(NORMAL, " x0 -> Generation 1"); + PrintAndLogEx(SUCCESS, " x0 -> Generation 1"); break; case 0x01: - PrintAndLogEx(NORMAL, " x1 -> Generation 2"); + PrintAndLogEx(SUCCESS, " x1 -> Generation 2"); break; case 0x02: - PrintAndLogEx(NORMAL, " x2 -> Generation 3"); + PrintAndLogEx(SUCCESS, " x2 -> Generation 3"); break; } switch (card.ats[pos + 4] & 0x0f) { case 0x00: - PrintAndLogEx(NORMAL, " x0 -> Only VCSL supported"); + PrintAndLogEx(SUCCESS, " x0 -> Only VCSL supported"); break; case 0x01: - PrintAndLogEx(NORMAL, " x1 -> VCS, VCSL, and SVC supported"); + PrintAndLogEx(SUCCESS, " x1 -> VCS, VCSL, and SVC supported"); break; case 0x0E: - PrintAndLogEx(NORMAL, " xE -> no VCS command supported"); + PrintAndLogEx(SUCCESS, " xE -> no VCS command supported"); break; } } @@ -1552,9 +1552,9 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { if (sw == 0x9000 || sw == 0x6283 || sw == 0x6285) { if (sw == 0x9000) { - if (verbose) PrintAndLogEx(NORMAL, "------------- Application OK -----------"); + if (verbose) PrintAndLogEx(SUCCESS, "------------- Application OK -----------"); } else { - if (verbose) PrintAndLogEx(NORMAL, "----------- Application blocked --------"); + if (verbose) PrintAndLogEx(WARNING, "----------- Application blocked --------"); } PrintAIDDescriptionBuf(root, vaid, vaidlen, verbose); From 34e38c9dc5449fa2a20fbe020560c135e53a24c6 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sat, 30 Nov 2019 23:45:51 +0200 Subject: [PATCH 1175/1854] added json save mfp --- client/fileutils.c | 30 ++++++++++++++++++++++++++++++ client/fileutils.h | 1 + 2 files changed, 31 insertions(+) diff --git a/client/fileutils.c b/client/fileutils.c index ebdb662ca..092e0fb66 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -352,6 +352,36 @@ int saveFileJSON(const char *preferredName, JSONFileType ftype, uint8_t *data, s case jsf15: case jsfLegic: case jsfT5555: + case jsfMfPlusKeys: + JsonSaveStr(root, "FileType", "mfp"); + + JsonSaveBufAsHexCompact(root, "$.Card.UID", &data[0], 7); + JsonSaveBufAsHexCompact(root, "$.Card.SAK", &data[10], 1); + JsonSaveBufAsHexCompact(root, "$.Card.ATQA", &data[11], 2); + uint8_t atslen = data[13]; + if (atslen > 0) + JsonSaveBufAsHexCompact(root, "$.Card.ATS", &data[14], atslen); + + uint8_t vdata[2][64][16 + 1] = {0}; + memcpy(vdata, &data[14 + atslen], 2 * 64 * 17); + + for (size_t i = 0; i < datalen; i++) { + char path[PATH_MAX_LENGTH] = {0}; + + if (vdata[0][i][0]) { + memset(path, 0x00, sizeof(path)); + sprintf(path, "$.SectorKeys.%d.KeyA", mfSectorNum(i)); + JsonSaveBufAsHexCompact(root, path, &vdata[0][i][1], 16); + } + + if (vdata[1][i][0]) { + memset(path, 0x00, sizeof(path)); + sprintf(path, "$.SectorKeys.%d.KeyB", mfSectorNum(i)); + JsonSaveBufAsHexCompact(root, path, &vdata[1][i][1], 16); + } + + } + break; default: break; } diff --git a/client/fileutils.h b/client/fileutils.h index eb4b57c82..bfd418a2c 100644 --- a/client/fileutils.h +++ b/client/fileutils.h @@ -61,6 +61,7 @@ typedef enum { jsfLegic, jsfT55x7, jsfT5555, + jsfMfPlusKeys, } JSONFileType; typedef enum { From 0cb7637e1f9acc127c7ff46d419103a54f10d6a6 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sat, 30 Nov 2019 23:46:37 +0200 Subject: [PATCH 1176/1854] added save keys to json for mfp check --- client/cmdhf14a.h | 4 +- client/cmdhfmfp.c | 122 ++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 105 insertions(+), 21 deletions(-) diff --git a/client/cmdhf14a.h b/client/cmdhf14a.h index f40ea46f0..83fb2c69d 100644 --- a/client/cmdhf14a.h +++ b/client/cmdhf14a.h @@ -1,7 +1,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 2010 iZsh -// 2011, Merlok -// 2015,216,2017 iceman, marshmellow, piwi +// 2011,2019 Merlok +// 2015,2016,2017 iceman, marshmellow, piwi // This code is licensed to you under the terms of the GNU GPL, version 2 or, // at your option, any later version. See the LICENSE.txt file for the text of // the license. diff --git a/client/cmdhfmfp.c b/client/cmdhfmfp.c index 3d1f41b8f..6a7a7e411 100644 --- a/client/cmdhfmfp.c +++ b/client/cmdhfmfp.c @@ -26,6 +26,7 @@ #include "emv/dump.h" #include "mifare/mifaredefault.h" #include "util_posix.h" +#include "fileutils.h" static const uint8_t DefaultKey[16] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; @@ -705,6 +706,21 @@ static int CmdHFMFPWrbl(const char *cmd) { return PM3_SUCCESS; } +void Fill2bPattern(uint8_t keyList[MAX_KEYS_LIST_LEN][AES_KEY_LEN], size_t *keyListLen, uint32_t *startPattern) { + for (uint32_t pt = *startPattern; pt < 0x10000; pt++) { + keyList[*keyListLen][0] = (pt >> 8) & 0xff; + keyList[*keyListLen][1] = pt & 0xff; + memcpy(&keyList[*keyListLen][2], &keyList[*keyListLen][0], 2); + memcpy(&keyList[*keyListLen][4], &keyList[*keyListLen][0], 4); + memcpy(&keyList[*keyListLen][8], &keyList[*keyListLen][0], 8); + (*keyListLen)++; + *startPattern = pt; + if (*keyListLen == MAX_KEYS_LIST_LEN) + break; + } + (*startPattern)++; +} + static int CmdHFMFPChk(const char *cmd) { int res; uint8_t keyList[MAX_KEYS_LIST_LEN][AES_KEY_LEN] = {0}; @@ -722,11 +738,12 @@ static int CmdHFMFPChk(const char *cmd) { arg_lit0("bB", "keyb", "check only key B (by default check all keys)."), arg_int0("sS", "startsec", "Start sector Num (0..255)", NULL), arg_int0("eE", "endsec", "End sector Num (0..255)", NULL), - arg_str0("kK", "key", "", NULL), - arg_str0(NULL, NULL, "", NULL), + arg_str0("kK", "key", "", "Key for checking (HEX 16 bytes)"), + arg_str0("dD", "dict", "", "file with keys dictionary"), arg_lit0(NULL, "pattern1b", "check all 1-byte combinations of key (0000...0000, 0101...0101, 0202...0202, ...)"), arg_lit0(NULL, "pattern2b", "check all 2-byte combinations of key (0000...0000, 0001...0001, 0002...0002, ...)"), - arg_str0(NULL, "startp2b", " start pattern for 2-byte search key", NULL), + arg_str0(NULL, "startp2b", "", "Start key (2-byte HEX) for 2-byte search (use with `--pattern2b`)"), + arg_str0("jJ", "json", "", "json file to save keys"), arg_param_end }; CLIExecWithReturn(cmd, argtable, true); @@ -745,19 +762,47 @@ static int CmdHFMFPChk(const char *cmd) { keyListLen++; } else { PrintAndLogEx(ERROR, "Specified key must have 16 bytes length."); + CLIParserFree(); return PM3_EINVARG; } } + uint8_t dict_filename[FILE_PATH_SIZE + 2] = {0}; + int dict_filenamelen = 0; + if (CLIParamStrToBuf(arg_get_str(6), dict_filename, FILE_PATH_SIZE, &dict_filenamelen)) { + PrintAndLogEx(FAILED, "File name too long or invalid."); + CLIParserFree(); + return PM3_EINVARG; + } + +/* char *dict_path; + int res = searchFile(&dict_path, DICTIONARIES_SUBDIR, filename, ".dic", false); + if (res != PM3_SUCCESS) { + CLIParserFree(); + return PM3_EFILE; + } + f = fopen(dict_path, "r"); + if (!f) { + PrintAndLogEx(FAILED, "File: " _YELLOW_("%s") ": not found or locked.", dict_path); + free(dict_path); + CLIParserFree(); + return PM3_EFILE; + } + free(dict_path); + + + */ + bool pattern1b = arg_get_lit(7); bool pattern2b = arg_get_lit(8); if (pattern1b && pattern2b) { PrintAndLogEx(ERROR, "Pattern search mode must be 2-byte or 1-byte only."); + CLIParserFree(); return PM3_EINVARG; } - uint16_t startPattern = 0x0000; + uint32_t startPattern = 0x0000; uint8_t vpattern[2]; int vpatternlen = 0; CLIGetHexWithReturn(9, vpattern, &vpatternlen); @@ -766,12 +811,22 @@ static int CmdHFMFPChk(const char *cmd) { startPattern = (vpattern[0] << 8) + vpattern[1]; } else { PrintAndLogEx(ERROR, "Pattern must be 2-byte length."); + CLIParserFree(); return PM3_EINVARG; } if (!pattern2b) PrintAndLogEx(WARNING, "Pattern entered, but search mode not is 2-byte search."); } + uint8_t jsonname[250] = {0}; + int jsonnamelen = 0; + if (CLIParamStrToBuf(arg_get_str(10), jsonname, sizeof(jsonname), &jsonnamelen)) { + PrintAndLogEx(ERROR, "Invalid json name."); + CLIParserFree(); + return PM3_EINVARG; + } + jsonname[jsonnamelen] = 0; + CLIParserFree(); uint8_t startKeyAB = 0; @@ -791,19 +846,8 @@ static int CmdHFMFPChk(const char *cmd) { keyListLen = 0x100; } - if (pattern2b) { - for (uint32_t i = startPattern; i < 0x10000; i++) { - keyList[keyListLen][0] = (i >> 8) & 0xff; - keyList[keyListLen][1] = i & 0xff; - memcpy(&keyList[keyListLen][2], &keyList[keyListLen][0], 2); - memcpy(&keyList[keyListLen][4], &keyList[keyListLen][0], 4); - memcpy(&keyList[keyListLen][8], &keyList[keyListLen][0], 8); - keyListLen++; - if (keyListLen == MAX_KEYS_LIST_LEN) - break; - } - startPattern = (keyList[keyListLen - 1][0] << 8) + keyList[keyListLen - 1][1]; - } + if (pattern2b) + Fill2bPattern(keyList, &keyListLen, &startPattern); if (keyListLen == 0) { for (int i = 0; i < g_mifare_plus_default_keys_len; i++) { @@ -822,8 +866,18 @@ static int CmdHFMFPChk(const char *cmd) { return PM3_EINVARG; } - res = MFPKeyCheck(startSector, endSector, startKeyAB, endKeyAB, keyList, keyListLen, foundKeys); - printf("--- res: %d\n", res); + while (true) { + res = MFPKeyCheck(startSector, endSector, startKeyAB, endKeyAB, keyList, keyListLen, foundKeys); + printf("--- res: %d\n", res); + if (res == PM3_EOPABORTED) + break; + if (pattern2b && startPattern < 0x10000) { + keyListLen = 0; + Fill2bPattern(keyList, &keyListLen, &startPattern); + continue; + } + break; + } // print result bool printedHeader = false; @@ -847,6 +901,36 @@ static int CmdHFMFPChk(const char *cmd) { else PrintAndLogEx(INFO, "'------'--------------------------------'--------------------------------'\n"); + // save keys to json + if ((jsonnamelen > 0) && printedHeader) { + // Mifare Plus info + SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT, 0, 0, NULL, 0); + + PacketResponseNG resp; + WaitForResponse(CMD_ACK, &resp); + + iso14a_card_select_t card; + memcpy(&card, (iso14a_card_select_t *)resp.data.asBytes, sizeof(iso14a_card_select_t)); + + uint64_t select_status = resp.oldarg[0]; // 0: couldn't read, 1: OK, with ATS, 2: OK, no ATS, 3: proprietary Anticollision + + uint8_t data[10 + 1 + 2 + 1 + 256 + 2 * 64 * (AES_KEY_LEN + 1)] = {0}; + uint8_t atslen = 0; + if (select_status == 1 || select_status == 2) { + memcpy(data, card.uid, card.uidlen); + data[10] = card.sak; + data[11] = card.atqa[1]; + data[12] = card.atqa[0]; + atslen = card.ats_len; + data[13] = atslen; + memcpy(&data[14], card.ats, atslen); + } + + // length: UID(10b)+SAK(1b)+ATQA(2b)+ATSlen(1b)+ATS(atslen)+foundKeys[2][64][AES_KEY_LEN + 1] + memcpy(&data[14 + atslen], foundKeys, 2 * 64 * (AES_KEY_LEN + 1)); + saveFileJSON((char *)jsonname, jsfMfPlusKeys, data, 64); + } + return PM3_SUCCESS; } From de52ebc3d54562c47ebc4baf37047bd781c16e72 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sun, 1 Dec 2019 00:30:35 +0200 Subject: [PATCH 1177/1854] 1dd 16 byte key for dictionaries --- client/fileutils.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/client/fileutils.c b/client/fileutils.c index 092e0fb66..1d3af28da 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -753,9 +753,10 @@ int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, u // t5577 == 4bytes // mifare == 6 bytes + // mf plus == 16 bytes // iclass == 8 bytes // default to 6 bytes. - if (keylen != 4 && keylen != 6 && keylen != 8) { + if (keylen != 4 && keylen != 6 && keylen != 8 && keylen != 16) { keylen = 6; } @@ -820,9 +821,10 @@ int loadFileDICTIONARY_safe(const char *preferredName, void **pdata, uint8_t key // t5577 == 4bytes // mifare == 6 bytes + // mf plus == 16 bytes // iclass == 8 bytes // default to 6 bytes. - if (keylen != 4 && keylen != 6 && keylen != 8) { + if (keylen != 4 && keylen != 6 && keylen != 8 && keylen != 16) { keylen = 6; } From a6a16cfd0ce62994f20e393ce088302aca3633d9 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sun, 1 Dec 2019 00:36:28 +0200 Subject: [PATCH 1178/1854] add dictionary search check hex --- client/fileutils.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/client/fileutils.c b/client/fileutils.c index 1d3af28da..83f3635a4 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -789,10 +789,17 @@ int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, u if (line[0] == '#') continue; - if (!isxdigit(line[0])) { - PrintAndLogEx(FAILED, "file content error. '%s' must include " _BLUE_("%2d") "HEX symbols", line, keylen); - continue; + bool searchFail = false; + for (int i = 0; i < keylen; i++) { + if (!isxdigit(line[i])) { + PrintAndLogEx(FAILED, "file content error (pos %d). '%s' must include " _BLUE_("%2d") "HEX symbols", i + 1, line, keylen); + searchFail = true; + break; + } } + if (searchFail) + continue; + uint64_t key = strtoull(line, NULL, 16); @@ -880,10 +887,16 @@ int loadFileDICTIONARY_safe(const char *preferredName, void **pdata, uint8_t key if (line[0] == '#') continue; - if (!isxdigit(line[0])) { - PrintAndLogEx(FAILED, "file content error. '%s' must include " _BLUE_("%2d") "HEX symbols", line, keylen); - continue; + bool searchFail = false; + for (int i = 0; i < keylen; i++) { + if (!isxdigit(line[i])) { + PrintAndLogEx(FAILED, "file content error (pos %d). '%s' must include " _BLUE_("%2d") "HEX symbols", i + 1, line, keylen); + searchFail = true; + break; + } } + if (searchFail) + continue; uint64_t key = strtoull(line, NULL, 16); From e88f4e4cd861fe30b06db994798d9cef8842824a Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sun, 1 Dec 2019 01:22:05 +0200 Subject: [PATCH 1179/1854] added hex_to_bytes --- client/util.c | 41 +++++++++++++++++++++++++++++++++++++++++ client/util.h | 1 + 2 files changed, 42 insertions(+) diff --git a/client/util.c b/client/util.c index 58dce8eca..c65f281fe 100644 --- a/client/util.c +++ b/client/util.c @@ -394,6 +394,47 @@ void print_blocks(uint32_t *data, size_t len) { } } +int hex_to_bytes(const char *hexValue, uint8_t *bytesValue, size_t maxBytesValueLen) { + char buf[3]; + int indx = 0; + int bytesValueLen = 0; + while (hexValue[indx]) { + if (hexValue[indx] == '\t' || hexValue[indx] == ' ') { + indx++; + continue; + } + + if (isxdigit(hexValue[indx])) { + buf[strlen(buf) + 1] = 0x00; + buf[strlen(buf)] = hexValue[indx]; + } else { + // if we have symbols other than spaces and hex + return -1; + } + + if (maxBytesValueLen && bytesValueLen >= maxBytesValueLen) { + // if we dont have space in buffer and have symbols to translate + return -2; + } + + if (strlen(buf) >= 2) { + uint32_t temp = 0; + sscanf(buf, "%x", &temp); + bytesValue[bytesValueLen] = (uint8_t)(temp & 0xff); + buf[0] = 0; + bytesValueLen++; + } + + indx++; + } + + if (strlen(buf) > 0) + //error when not completed hex bytes + return -3; + + return bytesValueLen; +} + // takes a number (uint64_t) and creates a binarray in dest. void num_to_bytebits(uint64_t n, size_t len, uint8_t *dest) { while (len--) { diff --git a/client/util.h b/client/util.h index d549458c4..afa12811b 100644 --- a/client/util.h +++ b/client/util.h @@ -55,6 +55,7 @@ char *sprint_ascii_ex(const uint8_t *data, const size_t len, const size_t min_st void print_blocks(uint32_t *data, size_t len); +int hex_to_bytes(const char *hexValue, uint8_t *bytesValue, size_t maxBytesValueLen); void num_to_bytebits(uint64_t n, size_t len, uint8_t *dest); void num_to_bytebitsLSBF(uint64_t n, size_t len, uint8_t *dest); uint8_t *SwapEndian64(const uint8_t *src, const size_t len, const uint8_t blockSize); From 1daf155b9c7618987178d2194bc9c46e29c440fc Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sun, 1 Dec 2019 10:45:02 +0200 Subject: [PATCH 1180/1854] added dictionary --- client/cmdhfmfp.c | 29 +++++++++++++++------ client/fileutils.c | 65 +++++++++++++++++++++++++--------------------- client/fileutils.h | 18 ++++++++++++- 3 files changed, 73 insertions(+), 39 deletions(-) diff --git a/client/cmdhfmfp.c b/client/cmdhfmfp.c index 6a7a7e411..f185d4456 100644 --- a/client/cmdhfmfp.c +++ b/client/cmdhfmfp.c @@ -723,6 +723,7 @@ void Fill2bPattern(uint8_t keyList[MAX_KEYS_LIST_LEN][AES_KEY_LEN], size_t *keyL static int CmdHFMFPChk(const char *cmd) { int res; + FILE *dictionary_file = NULL; uint8_t keyList[MAX_KEYS_LIST_LEN][AES_KEY_LEN] = {0}; size_t keyListLen = 0; uint8_t foundKeys[2][64][AES_KEY_LEN + 1] = {0}; @@ -775,23 +776,20 @@ static int CmdHFMFPChk(const char *cmd) { return PM3_EINVARG; } -/* char *dict_path; - int res = searchFile(&dict_path, DICTIONARIES_SUBDIR, filename, ".dic", false); + char *dict_path; + res = searchFile(&dict_path, DICTIONARIES_SUBDIR, (char *)dict_filename, ".dic", false); if (res != PM3_SUCCESS) { CLIParserFree(); return PM3_EFILE; } - f = fopen(dict_path, "r"); - if (!f) { + dictionary_file = fopen(dict_path, "r"); + if (!dictionary_file) { PrintAndLogEx(FAILED, "File: " _YELLOW_("%s") ": not found or locked.", dict_path); free(dict_path); CLIParserFree(); return PM3_EFILE; } - free(dict_path); - - - */ + free(dict_path); bool pattern1b = arg_get_lit(7); bool pattern2b = arg_get_lit(8); @@ -801,6 +799,12 @@ static int CmdHFMFPChk(const char *cmd) { CLIParserFree(); return PM3_EINVARG; } + + if (dictionary_file && (pattern1b || pattern2b)) { + PrintAndLogEx(ERROR, "Pattern search mode and dictionary mode can't be used in one command."); + CLIParserFree(); + return PM3_EINVARG; + } uint32_t startPattern = 0x0000; uint8_t vpattern[2]; @@ -839,6 +843,7 @@ static int CmdHFMFPChk(const char *cmd) { if (endSector < startSector) endSector = startSector; + // 1-byte pattern search mode if (pattern1b) { for (int i = 0; i < 0x100; i++) memset(keyList[i], i, 16); @@ -846,8 +851,16 @@ static int CmdHFMFPChk(const char *cmd) { keyListLen = 0x100; } + // 2-byte pattern search mode if (pattern2b) Fill2bPattern(keyList, &keyListLen, &startPattern); + + // dictionary mode + if (dictionary_file) { + size_t endFilePosition = 0; + res = loadFileDICTIONARYEx((char *)dict_filename, keyList, sizeof(keyList), &keyListLen, 16, NULL, 0, &endFilePosition); + printf("---endFilePosition %d", endFilePosition); + } if (keyListLen == 0) { for (int i = 0; i < g_mifare_plus_default_keys_len; i++) { diff --git a/client/fileutils.c b/client/fileutils.c index 83f3635a4..a69de8d96 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -745,12 +745,6 @@ out: } int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, uint8_t keylen, uint16_t *keycnt) { - - if (data == NULL) return PM3_EINVARG; - char *path; - if (searchFile(&path, DICTIONARIES_SUBDIR, preferredName, ".dic", false) != PM3_SUCCESS) - return PM3_EFILE; - // t5577 == 4bytes // mifare == 6 bytes // mf plus == 16 bytes @@ -759,6 +753,20 @@ int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, u if (keylen != 4 && keylen != 6 && keylen != 8 && keylen != 16) { keylen = 6; } + + return loadFileDICTIONARYEx(preferredName, data, 0, datalen, keylen, keycnt, 0, NULL); +} + +int loadFileDICTIONARYEx(const char *preferredName, void *data, size_t maxdatalen, size_t *datalen, uint8_t keylen, uint16_t *keycnt, + size_t startFilePosition, size_t *endFilePosition) { + if (endFilePosition) + *endFilePosition = 0; + if (data == NULL) return PM3_EINVARG; + uint16_t vkeycnt = 0; + + char *path; + if (searchFile(&path, DICTIONARIES_SUBDIR, preferredName, ".dic", false) != PM3_SUCCESS) + return PM3_EFILE; // double up since its chars keylen <<= 1; @@ -774,7 +782,10 @@ int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, u retval = PM3_EFILE; goto out; } - + + if (startFilePosition) + fseek(f, startFilePosition, SEEK_SET); + // read file while (fgets(line, sizeof(line), f)) { @@ -789,30 +800,32 @@ int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, u if (line[0] == '#') continue; - bool searchFail = false; - for (int i = 0; i < keylen; i++) { - if (!isxdigit(line[i])) { - PrintAndLogEx(FAILED, "file content error (pos %d). '%s' must include " _BLUE_("%2d") "HEX symbols", i + 1, line, keylen); - searchFail = true; - break; - } - } - if (searchFail) + if (CheckStringIsHEXValue(line)) continue; + // cant store more data + if (maxdatalen && (counter + keylen > maxdatalen)) { + retval = 1; + int pos = ftell(f) - strlen(line) - 2; // 2 - `\r\n` + if (endFilePosition && (pos > 0)) + *endFilePosition = pos; + break; + } - uint64_t key = strtoull(line, NULL, 16); - - num_to_bytes(key, keylen >> 1, data + counter); - (*keycnt)++; + if (hex_to_bytes(line, data + counter, keylen >> 1) != (keylen >> 1)) + continue; + + vkeycnt++; memset(line, 0, sizeof(line)); counter += (keylen >> 1); } fclose(f); - PrintAndLogEx(SUCCESS, "loaded " _GREEN_("%2d") "keys from dictionary file " _YELLOW_("%s"), *keycnt, path); + PrintAndLogEx(SUCCESS, "loaded " _GREEN_("%2d") "keys from dictionary file " _YELLOW_("%s"), vkeycnt, path); if (datalen) *datalen = counter; + if (keycnt) + *keycnt = vkeycnt; out: free(path); return retval; @@ -887,15 +900,7 @@ int loadFileDICTIONARY_safe(const char *preferredName, void **pdata, uint8_t key if (line[0] == '#') continue; - bool searchFail = false; - for (int i = 0; i < keylen; i++) { - if (!isxdigit(line[i])) { - PrintAndLogEx(FAILED, "file content error (pos %d). '%s' must include " _BLUE_("%2d") "HEX symbols", i + 1, line, keylen); - searchFail = true; - break; - } - } - if (searchFail) + if (CheckStringIsHEXValue(line)) continue; uint64_t key = strtoull(line, NULL, 16); diff --git a/client/fileutils.h b/client/fileutils.h index bfd418a2c..58d05d366 100644 --- a/client/fileutils.h +++ b/client/fileutils.h @@ -176,13 +176,29 @@ int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_ * * @param preferredName * @param data The data array to store the loaded bytes from file - * @param maxdatalen maximum size of data array in bytes * @param datalen the number of bytes loaded from file * @param keylen the number of bytes a key per row is * @return 0 for ok, 1 for failz */ int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, uint8_t keylen, uint16_t *keycnt); +/** + * @brief Utility function to load data from a DICTIONARY textfile. This method takes a preferred name. + * E.g. mfc_default_keys.dic + * can be executed several times for big dictionaries and checks length of buffer + * + * @param preferredName + * @param data The data array to store the loaded bytes from file + * @param maxdatalen maximum size of data array in bytes + * @param datalen the number of bytes loaded from file + * @param keylen the number of bytes a key per row is + * @param startFilePosition + * @param endFilePosition + * @return 0 for ok, 1 for failz +*/ +int loadFileDICTIONARYEx(const char *preferredName, void *data, size_t maxdatalen, size_t *datalen, uint8_t keylen, uint16_t *keycnt, + size_t startFilePosition, size_t *endFilePosition); + /** * @brief Utility function to load data safely from a DICTIONARY textfile. This method takes a preferred name. * E.g. mfc_default_keys.dic From ca462424d0773ef0c3551ab0461b03cdc5d41b2b Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sun, 1 Dec 2019 10:56:41 +0200 Subject: [PATCH 1181/1854] refactoring --- client/cmdhfmfp.c | 25 +++---------------------- 1 file changed, 3 insertions(+), 22 deletions(-) diff --git a/client/cmdhfmfp.c b/client/cmdhfmfp.c index f185d4456..80419fa40 100644 --- a/client/cmdhfmfp.c +++ b/client/cmdhfmfp.c @@ -723,7 +723,6 @@ void Fill2bPattern(uint8_t keyList[MAX_KEYS_LIST_LEN][AES_KEY_LEN], size_t *keyL static int CmdHFMFPChk(const char *cmd) { int res; - FILE *dictionary_file = NULL; uint8_t keyList[MAX_KEYS_LIST_LEN][AES_KEY_LEN] = {0}; size_t keyListLen = 0; uint8_t foundKeys[2][64][AES_KEY_LEN + 1] = {0}; @@ -775,21 +774,6 @@ static int CmdHFMFPChk(const char *cmd) { CLIParserFree(); return PM3_EINVARG; } - - char *dict_path; - res = searchFile(&dict_path, DICTIONARIES_SUBDIR, (char *)dict_filename, ".dic", false); - if (res != PM3_SUCCESS) { - CLIParserFree(); - return PM3_EFILE; - } - dictionary_file = fopen(dict_path, "r"); - if (!dictionary_file) { - PrintAndLogEx(FAILED, "File: " _YELLOW_("%s") ": not found or locked.", dict_path); - free(dict_path); - CLIParserFree(); - return PM3_EFILE; - } - free(dict_path); bool pattern1b = arg_get_lit(7); bool pattern2b = arg_get_lit(8); @@ -800,7 +784,7 @@ static int CmdHFMFPChk(const char *cmd) { return PM3_EINVARG; } - if (dictionary_file && (pattern1b || pattern2b)) { + if (dict_filenamelen && (pattern1b || pattern2b)) { PrintAndLogEx(ERROR, "Pattern search mode and dictionary mode can't be used in one command."); CLIParserFree(); return PM3_EINVARG; @@ -856,7 +840,7 @@ static int CmdHFMFPChk(const char *cmd) { Fill2bPattern(keyList, &keyListLen, &startPattern); // dictionary mode - if (dictionary_file) { + if (dict_filenamelen) { size_t endFilePosition = 0; res = loadFileDICTIONARYEx((char *)dict_filename, keyList, sizeof(keyList), &keyListLen, 16, NULL, 0, &endFilePosition); printf("---endFilePosition %d", endFilePosition); @@ -864,10 +848,7 @@ static int CmdHFMFPChk(const char *cmd) { if (keyListLen == 0) { for (int i = 0; i < g_mifare_plus_default_keys_len; i++) { - int datalen = 0; - if (param_gethex_to_eol(g_mifare_plus_default_keys[i], 0, keyList[keyListLen], 16, &datalen) > 0) - break; - if (datalen != 16) + if (hex_to_bytes(g_mifare_plus_default_keys[i], keyList[keyListLen], 16) != 16) break; keyListLen++; From 131730e7dbdc5adfba4bf1ae78e90b47509156e1 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sun, 1 Dec 2019 11:01:56 +0200 Subject: [PATCH 1182/1854] fix docstrings --- client/fileutils.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/client/fileutils.h b/client/fileutils.h index 58d05d366..612c9fee6 100644 --- a/client/fileutils.h +++ b/client/fileutils.h @@ -176,8 +176,9 @@ int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_ * * @param preferredName * @param data The data array to store the loaded bytes from file - * @param datalen the number of bytes loaded from file + * @param datalen the number of bytes loaded from file. may be NULL * @param keylen the number of bytes a key per row is + * @param keycnt key count that lays in data. may be NULL * @return 0 for ok, 1 for failz */ int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, uint8_t keylen, uint16_t *keycnt); @@ -190,10 +191,11 @@ int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, u * @param preferredName * @param data The data array to store the loaded bytes from file * @param maxdatalen maximum size of data array in bytes - * @param datalen the number of bytes loaded from file + * @param datalen the number of bytes loaded from file. may be NULL * @param keylen the number of bytes a key per row is - * @param startFilePosition - * @param endFilePosition + * @param keycnt key count that lays in data. may be NULL + * @param startFilePosition start position in dictionary file. used for big dictionaries. + * @param endFilePosition in case we have keys in file and maxdatalen reached it returns current key position in file. may be NULL * @return 0 for ok, 1 for failz */ int loadFileDICTIONARYEx(const char *preferredName, void *data, size_t maxdatalen, size_t *datalen, uint8_t keylen, uint16_t *keycnt, From fef245be262e8646bb374772014f5ad37ada1bed Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 1 Dec 2019 11:32:49 +0100 Subject: [PATCH 1183/1854] textual --- client/cmdhffelica.c | 132 ++++++++++++++++++++----------------------- 1 file changed, 61 insertions(+), 71 deletions(-) diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index fe11d4c60..eb11dddc6 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -291,12 +291,12 @@ static bool waitCmdFelica(uint8_t iSelect, PacketResponseNG *resp, bool verbose) if (WaitForResponseTimeout(CMD_ACK, resp, 2000)) { uint16_t len = iSelect ? (resp->oldarg[1] & 0xffff) : (resp->oldarg[0] & 0xffff); if (verbose) { - PrintAndLogEx(NORMAL, "Client Received %i octets", len); + PrintAndLogEx(SUCCESS, "Client Received %i octets", len); if (!len || len < 2) { PrintAndLogEx(ERR, "Could not receive data correctly!"); return false; } - PrintAndLogEx(NORMAL, "%s", sprint_hex(resp->data.asBytes, len)); + PrintAndLogEx(SUCCESS, "%s", sprint_hex(resp->data.asBytes, len)); if (!check_crc(CRC_FELICA, resp->data.asBytes + 2, len - 2)) { PrintAndLogEx(WARNING, "Wrong or no CRC bytes"); } @@ -371,7 +371,7 @@ static void clear_and_send_command(uint8_t flags, uint16_t datalen, uint8_t *dat uint16_t numbits = 0; clearCommandBuffer(); if (verbose) { - PrintAndLogEx(NORMAL, "Send Service Request Frame: %s", sprint_hex(data, datalen)); + PrintAndLogEx(INFO, "Send Service Request Frame: %s", sprint_hex(data, datalen)); } SendCommandMIX(CMD_HF_FELICA_COMMAND, flags, (datalen & 0xFFFF) | (uint32_t)(numbits << 16), 0, data, datalen); } @@ -409,11 +409,11 @@ static void print_rd_noEncrpytion_response(felica_read_without_encryption_respon char bl_element_number[4]; temp = sprint_hex(rd_noCry_resp->block_element_number, sizeof(rd_noCry_resp->block_element_number)); strcpy(bl_element_number, temp); - PrintAndLogEx(NORMAL, "\t%s\t| %s ", bl_element_number, bl_data); + PrintAndLogEx(INFO, "\t%s\t| %s ", bl_element_number, bl_data); } else { - PrintAndLogEx(NORMAL, "IDm: %s", sprint_hex(rd_noCry_resp->frame_response.IDm, sizeof(rd_noCry_resp->frame_response.IDm))); - PrintAndLogEx(NORMAL, "Status Flag1: %s", sprint_hex(rd_noCry_resp->status_flags.status_flag1, sizeof(rd_noCry_resp->status_flags.status_flag1))); - PrintAndLogEx(NORMAL, "Status Flag2: %s", sprint_hex(rd_noCry_resp->status_flags.status_flag1, sizeof(rd_noCry_resp->status_flags.status_flag1))); + PrintAndLogEx(SUCCESS, "IDm: %s", sprint_hex(rd_noCry_resp->frame_response.IDm, sizeof(rd_noCry_resp->frame_response.IDm))); + PrintAndLogEx(SUCCESS, "Status Flag1: %s", sprint_hex(rd_noCry_resp->status_flags.status_flag1, sizeof(rd_noCry_resp->status_flags.status_flag1))); + PrintAndLogEx(SUCCESS, "Status Flag2: %s", sprint_hex(rd_noCry_resp->status_flags.status_flag1, sizeof(rd_noCry_resp->status_flags.status_flag1))); } } @@ -425,7 +425,7 @@ int send_request_service(uint8_t flags, uint16_t datalen, uint8_t *data, bool ve PacketResponseNG resp; if (datalen > 0) { if (!waitCmdFelica(0, &resp, 1)) { - PrintAndLogEx(ERR, "\nGot no Response from card"); + PrintAndLogEx(ERR, "\nGot no response from card"); return PM3_ERFTRANS; } felica_request_service_response_t rqs_response; @@ -433,9 +433,9 @@ int send_request_service(uint8_t flags, uint16_t datalen, uint8_t *data, bool ve if (rqs_response.frame_response.IDm[0] != 0) { PrintAndLogEx(SUCCESS, "\nGot Service Response:"); - PrintAndLogEx(NORMAL, "IDm: %s", sprint_hex(rqs_response.frame_response.IDm, sizeof(rqs_response.frame_response.IDm))); - PrintAndLogEx(NORMAL, " -Node Number: %s", sprint_hex(rqs_response.node_number, sizeof(rqs_response.node_number))); - PrintAndLogEx(NORMAL, " -Node Key Version List: %s\n", sprint_hex(rqs_response.node_key_versions, sizeof(rqs_response.node_key_versions))); + PrintAndLogEx(SUCCESS, "IDm: %s", sprint_hex(rqs_response.frame_response.IDm, sizeof(rqs_response.frame_response.IDm))); + PrintAndLogEx(SUCCESS, " -Node Number: %s", sprint_hex(rqs_response.node_number, sizeof(rqs_response.node_number))); + PrintAndLogEx(SUCCESS, " -Node Key Version List: %s\n", sprint_hex(rqs_response.node_key_versions, sizeof(rqs_response.node_key_versions))); } return PM3_SUCCESS; } @@ -455,7 +455,7 @@ int send_rd_unencrypted(uint8_t flags, uint16_t datalen, uint8_t *data, bool ver clear_and_send_command(flags, datalen, data, verbose); PacketResponseNG resp; if (!waitCmdFelica(0, &resp, verbose)) { - PrintAndLogEx(ERR, "\nGot no Response from card"); + PrintAndLogEx(ERR, "\nGot no response from card"); return PM3_ERFTRANS; } else { memcpy(rd_noCry_resp, (felica_read_without_encryption_response_t *)resp.data.asBytes, sizeof(felica_read_without_encryption_response_t)); @@ -493,7 +493,7 @@ int send_wr_unencrypted(uint8_t flags, uint16_t datalen, uint8_t *data, bool ver clear_and_send_command(flags, datalen, data, verbose); PacketResponseNG resp; if (!waitCmdFelica(0, &resp, verbose)) { - PrintAndLogEx(ERR, "\nGot no Response from card"); + PrintAndLogEx(ERR, "\nGot no response from card"); return PM3_ERFTRANS; } else { memcpy(wr_noCry_resp, (felica_status_response_t *)resp.data.asBytes, sizeof(felica_status_response_t)); @@ -518,8 +518,7 @@ static int CmdHFFelicaWriteWithoutEncryption(const char *Cmd) { int i = 0; while (Cmd[i] != '\0') { if (Cmd[i] == '-') { - switch (Cmd[i + 1]) { - case 'H': + switch (tolower(Cmd[i + 1])) { case 'h': return usage_hf_felica_write_without_encryption(); case 'i': @@ -558,9 +557,9 @@ static int CmdHFFelicaWriteWithoutEncryption(const char *Cmd) { datalen += 2; felica_status_response_t wr_noCry_resp; if (send_wr_unencrypted(flags, datalen, data, 1, &wr_noCry_resp) == PM3_SUCCESS) { - PrintAndLogEx(NORMAL, "\nIDm: %s", sprint_hex(wr_noCry_resp.frame_response.IDm, sizeof(wr_noCry_resp.frame_response.IDm))); - PrintAndLogEx(NORMAL, "Status Flag1: %s", sprint_hex(wr_noCry_resp.status_flags.status_flag1, sizeof(wr_noCry_resp.status_flags.status_flag1))); - PrintAndLogEx(NORMAL, "Status Flag2: %s\n", sprint_hex(wr_noCry_resp.status_flags.status_flag2, sizeof(wr_noCry_resp.status_flags.status_flag2))); + PrintAndLogEx(SUCCESS, "\nIDm: %s", sprint_hex(wr_noCry_resp.frame_response.IDm, sizeof(wr_noCry_resp.frame_response.IDm))); + PrintAndLogEx(SUCCESS, "Status Flag1: %s", sprint_hex(wr_noCry_resp.status_flags.status_flag1, sizeof(wr_noCry_resp.status_flags.status_flag1))); + PrintAndLogEx(SUCCESS, "Status Flag2: %s\n", sprint_hex(wr_noCry_resp.status_flags.status_flag2, sizeof(wr_noCry_resp.status_flags.status_flag2))); if (wr_noCry_resp.status_flags.status_flag1[0] == 0x00 && wr_noCry_resp.status_flags.status_flag2[0] == 0x00) { PrintAndLogEx(SUCCESS, "Writing data successful!\n"); } else { @@ -589,8 +588,7 @@ static int CmdHFFelicaReadWithoutEncryption(const char *Cmd) { int i = 0; while (Cmd[i] != '\0') { if (Cmd[i] == '-') { - switch (Cmd[i + 1]) { - case 'H': + switch (tolower(Cmd[i + 1])) { case 'h': return usage_hf_felica_read_without_encryption(); case 'i': @@ -643,7 +641,7 @@ static int CmdHFFelicaReadWithoutEncryption(const char *Cmd) { if (long_block_numbers) { last_block_number = 0xFFFF; } - PrintAndLogEx(NORMAL, "Block Element\t| Data "); + PrintAndLogEx(INFO, "Block Element\t| Data "); for (int i = 0x00; i < last_block_number; i++) { data[15] = i; AddCrc(data, datalen); @@ -665,7 +663,7 @@ static int CmdHFFelicaReadWithoutEncryption(const char *Cmd) { datalen += 2; felica_read_without_encryption_response_t rd_noCry_resp; if (send_rd_unencrypted(flags, datalen, data, 1, &rd_noCry_resp) == PM3_SUCCESS) { - PrintAndLogEx(NORMAL, "Block Element\t| Data "); + PrintAndLogEx(INFO, "Block Element\t| Data "); print_rd_noEncrpytion_response(&rd_noCry_resp); } } @@ -687,8 +685,7 @@ static int CmdHFFelicaRequestResponse(const char *Cmd) { int i = 0; while (Cmd[i] != '\0') { if (Cmd[i] == '-') { - switch (Cmd[i + 1]) { - case 'H': + switch (tolower(Cmd[i + 1])) { case 'h': return usage_hf_felica_request_response(); case 'i': @@ -718,15 +715,15 @@ static int CmdHFFelicaRequestResponse(const char *Cmd) { clear_and_send_command(flags, datalen, data, 0); PacketResponseNG resp; if (!waitCmdFelica(0, &resp, 1)) { - PrintAndLogEx(ERR, "\nGot no Response from card"); + PrintAndLogEx(ERR, "\nGot no response from card"); return PM3_ERFTRANS; } else { felica_request_request_response_t rq_response; memcpy(&rq_response, (felica_request_request_response_t *)resp.data.asBytes, sizeof(felica_request_request_response_t)); if (rq_response.frame_response.IDm[0] != 0) { PrintAndLogEx(SUCCESS, "\nGot Request Response:"); - PrintAndLogEx(NORMAL, "IDm: %s", sprint_hex(rq_response.frame_response.IDm, sizeof(rq_response.frame_response.IDm))); - PrintAndLogEx(NORMAL, " -Mode: %s\n\n", sprint_hex(rq_response.mode, sizeof(rq_response.mode))); + PrintAndLogEx(SUCCESS, "IDm: %s", sprint_hex(rq_response.frame_response.IDm, sizeof(rq_response.frame_response.IDm))); + PrintAndLogEx(SUCCESS, " -Mode: %s\n\n", sprint_hex(rq_response.mode, sizeof(rq_response.mode))); } } return PM3_SUCCESS; @@ -749,8 +746,7 @@ static int CmdHFFelicaRequestSpecificationVersion(const char *Cmd) { int i = 0; while (Cmd[i] != '\0') { if (Cmd[i] == '-') { - switch (Cmd[i + 1]) { - case 'H': + switch (tolower(Cmd[i + 1])) { case 'h': return usage_hf_felica_request_specification_version(); case 'i': @@ -793,24 +789,24 @@ static int CmdHFFelicaRequestSpecificationVersion(const char *Cmd) { clear_and_send_command(flags, datalen, data, 0); PacketResponseNG resp; if (!waitCmdFelica(0, &resp, 1)) { - PrintAndLogEx(ERR, "\nGot no Response from card"); + PrintAndLogEx(ERR, "\nGot no response from card"); return PM3_ERFTRANS; } else { felica_request_spec_response_t spec_response; memcpy(&spec_response, (felica_request_spec_response_t *)resp.data.asBytes, sizeof(felica_request_spec_response_t)); if (spec_response.frame_response.IDm[0] != 0) { PrintAndLogEx(SUCCESS, "\nGot Request Response:"); - PrintAndLogEx(NORMAL, "\nIDm: %s", sprint_hex(spec_response.frame_response.IDm, sizeof(spec_response.frame_response.IDm))); - PrintAndLogEx(NORMAL, "Status Flag1: %s", sprint_hex(spec_response.status_flags.status_flag1, sizeof(spec_response.status_flags.status_flag1))); - PrintAndLogEx(NORMAL, "Status Flag2: %s", sprint_hex(spec_response.status_flags.status_flag2, sizeof(spec_response.status_flags.status_flag2))); + PrintAndLogEx(SUCCESS, "\nIDm: %s", sprint_hex(spec_response.frame_response.IDm, sizeof(spec_response.frame_response.IDm))); + PrintAndLogEx(SUCCESS, "Status Flag1: %s", sprint_hex(spec_response.status_flags.status_flag1, sizeof(spec_response.status_flags.status_flag1))); + PrintAndLogEx(SUCCESS, "Status Flag2: %s", sprint_hex(spec_response.status_flags.status_flag2, sizeof(spec_response.status_flags.status_flag2))); if (spec_response.status_flags.status_flag1[0] == 0x00) { - PrintAndLogEx(NORMAL, "Format Version: %s", sprint_hex(spec_response.format_version, sizeof(spec_response.format_version))); - PrintAndLogEx(NORMAL, "Basic Version: %s", sprint_hex(spec_response.basic_version, sizeof(spec_response.basic_version))); - PrintAndLogEx(NORMAL, "Number of Option: %s", sprint_hex(spec_response.number_of_option, sizeof(spec_response.number_of_option))); + PrintAndLogEx(SUCCESS, "Format Version: %s", sprint_hex(spec_response.format_version, sizeof(spec_response.format_version))); + PrintAndLogEx(SUCCESS, "Basic Version: %s", sprint_hex(spec_response.basic_version, sizeof(spec_response.basic_version))); + PrintAndLogEx(SUCCESS, "Number of Option: %s", sprint_hex(spec_response.number_of_option, sizeof(spec_response.number_of_option))); if (spec_response.number_of_option[0] == 0x01) { - PrintAndLogEx(NORMAL, "Option Version List:"); + PrintAndLogEx(SUCCESS, "Option Version List:"); for (uint8_t i = 0; i < spec_response.number_of_option[0]; i++) { - PrintAndLogEx(NORMAL, " - %s", sprint_hex(spec_response.option_version_list + i * 2, sizeof(uint8_t) * 2)); + PrintAndLogEx(SUCCESS, " - %s", sprint_hex(spec_response.option_version_list + i * 2, sizeof(uint8_t) * 2)); } } } @@ -836,8 +832,7 @@ static int CmdHFFelicaResetMode(const char *Cmd) { int i = 0; while (Cmd[i] != '\0') { if (Cmd[i] == '-') { - switch (Cmd[i + 1]) { - case 'H': + switch (tolower(Cmd[i + 1])) { case 'h': return usage_hf_felica_reset_mode(); case 'i': @@ -880,16 +875,16 @@ static int CmdHFFelicaResetMode(const char *Cmd) { clear_and_send_command(flags, datalen, data, 0); PacketResponseNG resp; if (!waitCmdFelica(0, &resp, 1)) { - PrintAndLogEx(ERR, "\nGot no Response from card"); + PrintAndLogEx(ERR, "\nGot no response from card"); return PM3_ERFTRANS; } else { felica_status_response_t reset_mode_response; memcpy(&reset_mode_response, (felica_status_response_t *)resp.data.asBytes, sizeof(felica_status_response_t)); if (reset_mode_response.frame_response.IDm[0] != 0) { PrintAndLogEx(SUCCESS, "\nGot Request Response:"); - PrintAndLogEx(NORMAL, "\nIDm: %s", sprint_hex(reset_mode_response.frame_response.IDm, sizeof(reset_mode_response.frame_response.IDm))); - PrintAndLogEx(NORMAL, "Status Flag1: %s", sprint_hex(reset_mode_response.status_flags.status_flag1, sizeof(reset_mode_response.status_flags.status_flag1))); - PrintAndLogEx(NORMAL, "Status Flag2: %s\n", sprint_hex(reset_mode_response.status_flags.status_flag2, sizeof(reset_mode_response.status_flags.status_flag2))); + PrintAndLogEx(SUCCESS, "\nIDm: %s", sprint_hex(reset_mode_response.frame_response.IDm, sizeof(reset_mode_response.frame_response.IDm))); + PrintAndLogEx(SUCCESS, "Status Flag1: %s", sprint_hex(reset_mode_response.status_flags.status_flag1, sizeof(reset_mode_response.status_flags.status_flag1))); + PrintAndLogEx(SUCCESS, "Status Flag2: %s\n", sprint_hex(reset_mode_response.status_flags.status_flag2, sizeof(reset_mode_response.status_flags.status_flag2))); } } return PM3_SUCCESS; @@ -912,8 +907,7 @@ static int CmdHFFelicaRequestSystemCode(const char *Cmd) { int i = 0; while (Cmd[i] != '\0') { if (Cmd[i] == '-') { - switch (Cmd[i + 1]) { - case 'H': + switch (tolower(Cmd[i + 1])) { case 'h': return usage_hf_felica_request_system_code(); case 'i': @@ -943,18 +937,18 @@ static int CmdHFFelicaRequestSystemCode(const char *Cmd) { clear_and_send_command(flags, datalen, data, 0); PacketResponseNG resp; if (!waitCmdFelica(0, &resp, 1)) { - PrintAndLogEx(ERR, "\nGot no Response from card"); + PrintAndLogEx(ERR, "\nGot no response from card"); return PM3_ERFTRANS; } else { felica_syscode_response_t rq_syscode_response; memcpy(&rq_syscode_response, (felica_syscode_response_t *)resp.data.asBytes, sizeof(felica_syscode_response_t)); if (rq_syscode_response.frame_response.IDm[0] != 0) { PrintAndLogEx(SUCCESS, "\nGot Request Response:"); - PrintAndLogEx(NORMAL, "IDm: %s", sprint_hex(rq_syscode_response.frame_response.IDm, sizeof(rq_syscode_response.frame_response.IDm))); - PrintAndLogEx(NORMAL, " - Number of Systems: %s", sprint_hex(rq_syscode_response.number_of_systems, sizeof(rq_syscode_response.number_of_systems))); - PrintAndLogEx(NORMAL, " - System Codes: enumerated in ascending order starting from System 0."); + PrintAndLogEx(SUCCESS, "IDm: %s", sprint_hex(rq_syscode_response.frame_response.IDm, sizeof(rq_syscode_response.frame_response.IDm))); + PrintAndLogEx(SUCCESS, " - Number of Systems: %s", sprint_hex(rq_syscode_response.number_of_systems, sizeof(rq_syscode_response.number_of_systems))); + PrintAndLogEx(SUCCESS, " - System Codes: enumerated in ascending order starting from System 0."); for (uint8_t i = 0; i < rq_syscode_response.number_of_systems[0]; i++) { - PrintAndLogEx(NORMAL, " - %s", sprint_hex(rq_syscode_response.system_code_list + i * 2, sizeof(uint8_t) * 2)); + PrintAndLogEx(SUCCESS, " - %s", sprint_hex(rq_syscode_response.system_code_list + i * 2, sizeof(uint8_t) * 2)); } } } @@ -978,8 +972,7 @@ static int CmdHFFelicaRequestService(const char *Cmd) { strip_cmds(Cmd); while (Cmd[i] != '\0') { if (Cmd[i] == '-') { - switch (Cmd[i + 1]) { - case 'H': + switch (tolower(Cmd[i + 1])) { case 'h': return usage_hf_felica_request_service(); case 'i': @@ -1051,7 +1044,8 @@ static int CmdHFFelicaRequestService(const char *Cmd) { } static int CmdHFFelicaNotImplementedYet(const char *Cmd) { - PrintAndLogEx(NORMAL, "Feature not implemented Yet!"); + PrintAndLogEx(INFO, "Feature not implemented yet."); + PrintAndLogEx(INFO, "Feel free to contribute!"); return PM3_SUCCESS; } @@ -1063,12 +1057,10 @@ static int CmdHFFelicaSniff(const char *Cmd) { int i = 0; while (Cmd[i] != '\0') { if (Cmd[i] == '-') { - switch (Cmd[i + 1]) { - case 'h': + switch (tolower(Cmd[i + 1])) { case 'H': return usage_hf_felica_sniff(); case 's': - case 'S': paramCount++; if (param_getlength(Cmd, paramCount) < 5) { samples2skip = param_get32ex(Cmd, paramCount++, 0, 10); @@ -1078,7 +1070,6 @@ static int CmdHFFelicaSniff(const char *Cmd) { } break; case 't': - case 'T': paramCount++; if (param_getlength(Cmd, paramCount) < 5) { triggers2skip = param_get32ex(Cmd, paramCount++, 0, 10); @@ -1124,7 +1115,7 @@ static int CmdHFFelicaSimLite(const char *Cmd) { } static void printSep() { - PrintAndLogEx(NORMAL, "------------------------------------------------------------------------------------"); + PrintAndLogEx(INFO, "------------------------------------------------------------------------------------"); } static uint16_t PrintFliteBlock(uint16_t tracepos, uint8_t *trace, uint16_t tracelen) { @@ -1360,8 +1351,7 @@ static int CmdHFFelicaCmdRaw(const char *Cmd) { while (Cmd[i] != '\0') { if (Cmd[i] == ' ' || Cmd[i] == '\t') { i++; continue; } if (Cmd[i] == '-') { - switch (Cmd[i + 1]) { - case 'H': + switch (tolower(Cmd[i + 1])) { case 'h': return usage_hf_felica_raw(); case 'r': @@ -1405,7 +1395,7 @@ static int CmdHFFelicaCmdRaw(const char *Cmd) { *buf = 0; if (++datalen >= sizeof(data)) { if (crc) - PrintAndLogEx(NORMAL, "Buffer is full, we can't add CRC to your data"); + PrintAndLogEx(WARNING, "Buffer is full, we can't add CRC to your data"); break; } } @@ -1439,12 +1429,12 @@ static int CmdHFFelicaCmdRaw(const char *Cmd) { datalen = (datalen > PM3_CMD_DATA_SIZE) ? PM3_CMD_DATA_SIZE : datalen; clearCommandBuffer(); - PrintAndLogEx(NORMAL, "Data: %s", sprint_hex(data, datalen)); + PrintAndLogEx(SUCCESS, "Data: %s", sprint_hex(data, datalen)); SendCommandMIX(CMD_HF_FELICA_COMMAND, flags, (datalen & 0xFFFF) | (uint32_t)(numbits << 16), 0, data, datalen); if (reply) { if (active_select) { - PrintAndLogEx(NORMAL, "Active select wait for FeliCa."); + PrintAndLogEx(SUCCESS, "Active select wait for FeliCa."); PacketResponseNG resp_IDm; waitCmdFelica(1, &resp_IDm, 1); } @@ -1490,15 +1480,15 @@ int readFelicaUid(bool verbose) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(SUCCESS, "FeliCa tag info"); - PrintAndLogEx(NORMAL, "IDm %s", sprint_hex(card.IDm, sizeof(card.IDm))); - PrintAndLogEx(NORMAL, " - CODE %s", sprint_hex(card.code, sizeof(card.code))); - PrintAndLogEx(NORMAL, " - NFCID2 %s", sprint_hex(card.uid, sizeof(card.uid))); + PrintAndLogEx(SUCCESS, "IDm %s", sprint_hex(card.IDm, sizeof(card.IDm))); + PrintAndLogEx(SUCCESS, " - CODE %s", sprint_hex(card.code, sizeof(card.code))); + PrintAndLogEx(SUCCESS, " - NFCID2 %s", sprint_hex(card.uid, sizeof(card.uid))); - PrintAndLogEx(NORMAL, "Parameter (PAD) | %s", sprint_hex(card.PMm, sizeof(card.PMm))); - PrintAndLogEx(NORMAL, " - IC CODE %s", sprint_hex(card.iccode, sizeof(card.iccode))); - PrintAndLogEx(NORMAL, " - MRT %s", sprint_hex(card.mrt, sizeof(card.mrt))); + PrintAndLogEx(SUCCESS, "Parameter (PAD) | %s", sprint_hex(card.PMm, sizeof(card.PMm))); + PrintAndLogEx(SUCCESS, " - IC CODE %s", sprint_hex(card.iccode, sizeof(card.iccode))); + PrintAndLogEx(SUCCESS, " - MRT %s", sprint_hex(card.mrt, sizeof(card.mrt))); - PrintAndLogEx(NORMAL, "SERVICE CODE %s", sprint_hex(card.servicecode, sizeof(card.servicecode))); + PrintAndLogEx(SUCCESS, "SERVICE CODE %s", sprint_hex(card.servicecode, sizeof(card.servicecode))); set_last_known_card(card); break; } From 94eb741a4fa8780bef14b4c9e7fa7027bf307b74 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sun, 1 Dec 2019 22:33:50 +0200 Subject: [PATCH 1184/1854] refactoring + make dictionary works --- client/cmdhfmfp.c | 8 ++++++-- client/fileutils.c | 12 ++++++------ client/util.c | 5 ++--- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/client/cmdhfmfp.c b/client/cmdhfmfp.c index 80419fa40..541847897 100644 --- a/client/cmdhfmfp.c +++ b/client/cmdhfmfp.c @@ -842,8 +842,10 @@ static int CmdHFMFPChk(const char *cmd) { // dictionary mode if (dict_filenamelen) { size_t endFilePosition = 0; - res = loadFileDICTIONARYEx((char *)dict_filename, keyList, sizeof(keyList), &keyListLen, 16, NULL, 0, &endFilePosition); - printf("---endFilePosition %d", endFilePosition); + uint16_t keycnt = 0; + res = loadFileDICTIONARYEx((char *)dict_filename, keyList, sizeof(keyList), NULL, 16, &keycnt, 0, &endFilePosition); + keyListLen = keycnt; + printf("---endFilePosition %d\n", endFilePosition); } if (keyListLen == 0) { @@ -870,6 +872,8 @@ static int CmdHFMFPChk(const char *cmd) { Fill2bPattern(keyList, &keyListLen, &startPattern); continue; } + if (dict_filenamelen) { + } break; } diff --git a/client/fileutils.c b/client/fileutils.c index a69de8d96..ebe29f0bd 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -785,10 +785,10 @@ int loadFileDICTIONARYEx(const char *preferredName, void *data, size_t maxdatale if (startFilePosition) fseek(f, startFilePosition, SEEK_SET); - + // read file - while (fgets(line, sizeof(line), f)) { - + while (!feof(f) && fgets(line, sizeof(line), f)) { + // add null terminator line[keylen] = 0; @@ -800,7 +800,7 @@ int loadFileDICTIONARYEx(const char *preferredName, void *data, size_t maxdatale if (line[0] == '#') continue; - if (CheckStringIsHEXValue(line)) + if (!CheckStringIsHEXValue(line)) continue; // cant store more data @@ -811,10 +811,10 @@ int loadFileDICTIONARYEx(const char *preferredName, void *data, size_t maxdatale *endFilePosition = pos; break; } - + if (hex_to_bytes(line, data + counter, keylen >> 1) != (keylen >> 1)) continue; - + vkeycnt++; memset(line, 0, sizeof(line)); counter += (keylen >> 1); diff --git a/client/util.c b/client/util.c index c65f281fe..887f52857 100644 --- a/client/util.c +++ b/client/util.c @@ -395,7 +395,7 @@ void print_blocks(uint32_t *data, size_t len) { } int hex_to_bytes(const char *hexValue, uint8_t *bytesValue, size_t maxBytesValueLen) { - char buf[3]; + char buf[4] = {0}; int indx = 0; int bytesValueLen = 0; while (hexValue[indx]) { @@ -405,7 +405,6 @@ int hex_to_bytes(const char *hexValue, uint8_t *bytesValue, size_t maxBytesValue } if (isxdigit(hexValue[indx])) { - buf[strlen(buf) + 1] = 0x00; buf[strlen(buf)] = hexValue[indx]; } else { // if we have symbols other than spaces and hex @@ -421,7 +420,7 @@ int hex_to_bytes(const char *hexValue, uint8_t *bytesValue, size_t maxBytesValue uint32_t temp = 0; sscanf(buf, "%x", &temp); bytesValue[bytesValueLen] = (uint8_t)(temp & 0xff); - buf[0] = 0; + memset(buf, 0, sizeof(buf)); bytesValueLen++; } From 2dfbe151b9e6511d627c895107308f7612f5f9bc Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sun, 1 Dec 2019 23:21:00 +0200 Subject: [PATCH 1185/1854] hf mfp check: dictionary works, verbose mode works --- client/cmdhfmfp.c | 49 +++++++++++++++++++----- client/dictionaries/mfp_default_keys.dic | 27 +++++++++++++ client/fileutils.c | 22 +++++++---- client/fileutils.h | 3 +- 4 files changed, 82 insertions(+), 19 deletions(-) create mode 100644 client/dictionaries/mfp_default_keys.dic diff --git a/client/cmdhfmfp.c b/client/cmdhfmfp.c index 541847897..a616fcc00 100644 --- a/client/cmdhfmfp.c +++ b/client/cmdhfmfp.c @@ -643,7 +643,8 @@ static int CmdHFMFPWrbl(const char *cmd) { #define MAX_KEYS_LIST_LEN 1024 int MFPKeyCheck(uint8_t startSector, uint8_t endSector, uint8_t startKeyAB, uint8_t endKeyAB, - uint8_t keyList[MAX_KEYS_LIST_LEN][AES_KEY_LEN], size_t keyListLen, uint8_t foundKeys[2][64][AES_KEY_LEN + 1]) { + uint8_t keyList[MAX_KEYS_LIST_LEN][AES_KEY_LEN], size_t keyListLen, uint8_t foundKeys[2][64][AES_KEY_LEN + 1], + bool verbose) { int res; bool selectCard = true; uint8_t keyn[2] = {0}; @@ -655,6 +656,8 @@ static int CmdHFMFPWrbl(const char *cmd) { // main cycle with key check for (int i = 0; i < keyListLen; i++) { if (i % 10 == 0) { + if (!verbose) + printf("."); if (kbd_enter_pressed()) { PrintAndLogEx(WARNING, "\nAborted via keyboard!\n"); DropField(); @@ -671,18 +674,25 @@ static int CmdHFMFPWrbl(const char *cmd) { if (res != 2) break; - printf("retried[%d]...\n", retry); + if (verbose) + PrintAndLogEx(WARNING, "retried[%d]...", retry); + else + printf("R"); DropField(); selectCard = true; msleep(100); } - PrintAndLogEx(WARNING, "sector %d key %d [%s] res: %d", sector, keyAB, sprint_hex_inrow(keyList[i], 16), res); + if (verbose) + PrintAndLogEx(WARNING, "sector %02d key %d [%s] res: %d", sector, keyAB, sprint_hex_inrow(keyList[i], 16), res); // key for [sector,keyAB] found if (res == 0) { - PrintAndLogEx(INFO, "Found key for sector %d key %s [%s]", sector, keyAB == 0 ? "A" : "B", sprint_hex_inrow(keyList[i], 16)); + if (verbose) + PrintAndLogEx(INFO, "Found key for sector %d key %s [%s]", sector, keyAB == 0 ? "A" : "B", sprint_hex_inrow(keyList[i], 16)); + else + printf("+"); foundKeys[keyAB][sector][0] = 0x01; memcpy(&foundKeys[keyAB][sector][1], keyList[i], AES_KEY_LEN); DropField(); @@ -693,6 +703,10 @@ static int CmdHFMFPWrbl(const char *cmd) { // 5 - auth error (rnd not equal) if (res != 5) { + if (verbose) + PrintAndLogEx(ERR, "Exchange error. Aborted."); + else + printf("E"); DropField(); return PM3_ECARDEXCHANGE; } @@ -744,6 +758,7 @@ static int CmdHFMFPChk(const char *cmd) { arg_lit0(NULL, "pattern2b", "check all 2-byte combinations of key (0000...0000, 0001...0001, 0002...0002, ...)"), arg_str0(NULL, "startp2b", "", "Start key (2-byte HEX) for 2-byte search (use with `--pattern2b`)"), arg_str0("jJ", "json", "", "json file to save keys"), + arg_lit0("vV", "verbose", "verbose mode."), arg_param_end }; CLIExecWithReturn(cmd, argtable, true); @@ -815,6 +830,8 @@ static int CmdHFMFPChk(const char *cmd) { } jsonname[jsonnamelen] = 0; + bool verbose = arg_get_lit(11); + CLIParserFree(); uint8_t startKeyAB = 0; @@ -840,12 +857,13 @@ static int CmdHFMFPChk(const char *cmd) { Fill2bPattern(keyList, &keyListLen, &startPattern); // dictionary mode + size_t endFilePosition = 0; if (dict_filenamelen) { - size_t endFilePosition = 0; uint16_t keycnt = 0; - res = loadFileDICTIONARYEx((char *)dict_filename, keyList, sizeof(keyList), NULL, 16, &keycnt, 0, &endFilePosition); + res = loadFileDICTIONARYEx((char *)dict_filename, keyList, sizeof(keyList), NULL, 16, &keycnt, 0, &endFilePosition, true); keyListLen = keycnt; - printf("---endFilePosition %d\n", endFilePosition); + if (endFilePosition) + PrintAndLogEx(SUCCESS, "First part of dictionary successfully loaded."); } if (keyListLen == 0) { @@ -862,20 +880,31 @@ static int CmdHFMFPChk(const char *cmd) { return PM3_EINVARG; } + if (!verbose) + printf("Search keys:"); while (true) { - res = MFPKeyCheck(startSector, endSector, startKeyAB, endKeyAB, keyList, keyListLen, foundKeys); - printf("--- res: %d\n", res); + res = MFPKeyCheck(startSector, endSector, startKeyAB, endKeyAB, keyList, keyListLen, foundKeys, verbose); if (res == PM3_EOPABORTED) break; if (pattern2b && startPattern < 0x10000) { + if (!verbose) + printf("p"); keyListLen = 0; Fill2bPattern(keyList, &keyListLen, &startPattern); continue; } - if (dict_filenamelen) { + if (dict_filenamelen && endFilePosition) { + if (!verbose) + printf("d"); + uint16_t keycnt = 0; + res = loadFileDICTIONARYEx((char *)dict_filename, keyList, sizeof(keyList), NULL, 16, &keycnt, endFilePosition, &endFilePosition, false); + keyListLen = keycnt; + continue; } break; } + if (!verbose) + printf("\n"); // print result bool printedHeader = false; diff --git a/client/dictionaries/mfp_default_keys.dic b/client/dictionaries/mfp_default_keys.dic new file mode 100644 index 000000000..0f20b69bf --- /dev/null +++ b/client/dictionaries/mfp_default_keys.dic @@ -0,0 +1,27 @@ +ffffffffffffffffffffffffffffffff +00000000000000000000000000000000 +a0a1a2a3a4a5a6a7a0a1a2a3a4a5a6a7 +b0b1b2b3b4b5b6b7b0b1b2b3b4b5b6b7 +d3f7d3f7d3f7d3f7d3f7d3f7d3f7d3f7 +11111111111111111111111111111111 +22222222222222222222222222222222 +33333333333333333333333333333333 +44444444444444444444444444444444 +55555555555555555555555555555555 +66666666666666666666666666666666 +77777777777777777777777777777777 +88888888888888888888888888888888 +99999999999999999999999999999999 +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +cccccccccccccccccccccccccccccccc +dddddddddddddddddddddddddddddddd +eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee +000102030405060708090a0b0c0d0e0f +0102030405060708090a0b0c0d0e0f10 +00010203040506070809101112131415 +01020304050607080910111213141516 +16151413121110090807060504030201 +15141312111009080706050403020100 +0f0e0d0c0b0a09080706050403020100 +100f0e0d0c0b0a090807060504030201 diff --git a/client/fileutils.c b/client/fileutils.c index ebe29f0bd..624c0259d 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -754,11 +754,11 @@ int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, u keylen = 6; } - return loadFileDICTIONARYEx(preferredName, data, 0, datalen, keylen, keycnt, 0, NULL); + return loadFileDICTIONARYEx(preferredName, data, 0, datalen, keylen, keycnt, 0, NULL, true); } int loadFileDICTIONARYEx(const char *preferredName, void *data, size_t maxdatalen, size_t *datalen, uint8_t keylen, uint16_t *keycnt, - size_t startFilePosition, size_t *endFilePosition) { + size_t startFilePosition, size_t *endFilePosition, bool verbose) { if (endFilePosition) *endFilePosition = 0; if (data == NULL) return PM3_EINVARG; @@ -787,7 +787,13 @@ int loadFileDICTIONARYEx(const char *preferredName, void *data, size_t maxdatale fseek(f, startFilePosition, SEEK_SET); // read file - while (!feof(f) && fgets(line, sizeof(line), f)) { + while (!feof(f)) { + size_t filepos = ftell(f); + if (!fgets(line, sizeof(line), f)) { + if (endFilePosition) + *endFilePosition = 0; + break; + } // add null terminator line[keylen] = 0; @@ -804,11 +810,10 @@ int loadFileDICTIONARYEx(const char *preferredName, void *data, size_t maxdatale continue; // cant store more data - if (maxdatalen && (counter + keylen > maxdatalen)) { + if (maxdatalen && (counter + (keylen >> 1) > maxdatalen)) { retval = 1; - int pos = ftell(f) - strlen(line) - 2; // 2 - `\r\n` - if (endFilePosition && (pos > 0)) - *endFilePosition = pos; + if (endFilePosition) + *endFilePosition = filepos; break; } @@ -820,7 +825,8 @@ int loadFileDICTIONARYEx(const char *preferredName, void *data, size_t maxdatale counter += (keylen >> 1); } fclose(f); - PrintAndLogEx(SUCCESS, "loaded " _GREEN_("%2d") "keys from dictionary file " _YELLOW_("%s"), vkeycnt, path); + if (verbose) + PrintAndLogEx(SUCCESS, "loaded " _GREEN_("%2d") "keys from dictionary file " _YELLOW_("%s"), vkeycnt, path); if (datalen) *datalen = counter; diff --git a/client/fileutils.h b/client/fileutils.h index 612c9fee6..c9de3b4fb 100644 --- a/client/fileutils.h +++ b/client/fileutils.h @@ -196,10 +196,11 @@ int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, u * @param keycnt key count that lays in data. may be NULL * @param startFilePosition start position in dictionary file. used for big dictionaries. * @param endFilePosition in case we have keys in file and maxdatalen reached it returns current key position in file. may be NULL + * @param verbose print messages if true * @return 0 for ok, 1 for failz */ int loadFileDICTIONARYEx(const char *preferredName, void *data, size_t maxdatalen, size_t *datalen, uint8_t keylen, uint16_t *keycnt, - size_t startFilePosition, size_t *endFilePosition); + size_t startFilePosition, size_t *endFilePosition, bool verbose); /** * @brief Utility function to load data safely from a DICTIONARY textfile. This method takes a preferred name. From bc27b0e910790be0ffe78f36200c3c1a1bf820b7 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sun, 1 Dec 2019 23:36:34 +0200 Subject: [PATCH 1186/1854] add some help --- client/cmdhfmfp.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/client/cmdhfmfp.c b/client/cmdhfmfp.c index a616fcc00..9187c5ce7 100644 --- a/client/cmdhfmfp.c +++ b/client/cmdhfmfp.c @@ -741,10 +741,14 @@ static int CmdHFMFPChk(const char *cmd) { size_t keyListLen = 0; uint8_t foundKeys[2][64][AES_KEY_LEN + 1] = {0}; - CLIParserInit("hf mfp check", + CLIParserInit("hf mfp chk", "Checks keys with Mifare Plus card.", - "Usage:\n\thf mfp check -k 000102030405060708090a0b0c0d0e0f -> check key on sector 0 as key A and B\n" - "\thf mfp check -s 2 -a -> check default key list on sector 2, key A\n"); + "Usage:\n" + " hf mfp chk -k 000102030405060708090a0b0c0d0e0f -> check key on sector 0 as key A and B\n" + " hf mfp chk -s 2 -a -> check default key list on sector 2, key A\n" + " hf mfp chk -d mfp_default_keys -s0 -e6 -> check keys from dictionary against sectors 0-6\n" + " hf mfp chk --pattern1b -j keys -> check all 1-byte keys pattern and save found keys to json\n" + " hf mfp chk --pattern2b --startp2b FA00 -> check all 2-byte keys pattern. Start from key FA00FA00...FA00\n"); void *argtable[] = { arg_param_begin, From 256782402eaf3792a0592de167804a090f69d348 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sun, 1 Dec 2019 23:39:41 +0200 Subject: [PATCH 1187/1854] fix linux make errors --- client/cmdhfmfp.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/client/cmdhfmfp.c b/client/cmdhfmfp.c index 9187c5ce7..3081f77f4 100644 --- a/client/cmdhfmfp.c +++ b/client/cmdhfmfp.c @@ -780,7 +780,7 @@ static int CmdHFMFPChk(const char *cmd) { memcpy(&keyList[keyListLen], vkey, 16); keyListLen++; } else { - PrintAndLogEx(ERROR, "Specified key must have 16 bytes length."); + PrintAndLogEx(ERR, "Specified key must have 16 bytes length."); CLIParserFree(); return PM3_EINVARG; } @@ -798,13 +798,13 @@ static int CmdHFMFPChk(const char *cmd) { bool pattern2b = arg_get_lit(8); if (pattern1b && pattern2b) { - PrintAndLogEx(ERROR, "Pattern search mode must be 2-byte or 1-byte only."); + PrintAndLogEx(ERR, "Pattern search mode must be 2-byte or 1-byte only."); CLIParserFree(); return PM3_EINVARG; } if (dict_filenamelen && (pattern1b || pattern2b)) { - PrintAndLogEx(ERROR, "Pattern search mode and dictionary mode can't be used in one command."); + PrintAndLogEx(ERR, "Pattern search mode and dictionary mode can't be used in one command."); CLIParserFree(); return PM3_EINVARG; } @@ -817,7 +817,7 @@ static int CmdHFMFPChk(const char *cmd) { if (vpatternlen > 0 && vpatternlen <= 2) { startPattern = (vpattern[0] << 8) + vpattern[1]; } else { - PrintAndLogEx(ERROR, "Pattern must be 2-byte length."); + PrintAndLogEx(ERR, "Pattern must be 2-byte length."); CLIParserFree(); return PM3_EINVARG; } @@ -828,7 +828,7 @@ static int CmdHFMFPChk(const char *cmd) { uint8_t jsonname[250] = {0}; int jsonnamelen = 0; if (CLIParamStrToBuf(arg_get_str(10), jsonname, sizeof(jsonname), &jsonnamelen)) { - PrintAndLogEx(ERROR, "Invalid json name."); + PrintAndLogEx(ERR, "Invalid json name."); CLIParserFree(); return PM3_EINVARG; } @@ -880,7 +880,7 @@ static int CmdHFMFPChk(const char *cmd) { } if (keyListLen == 0) { - PrintAndLogEx(ERROR, "Key list is empty. Nothing to check."); + PrintAndLogEx(ERR, "Key list is empty. Nothing to check."); return PM3_EINVARG; } From 8132de9b4fe29b97020eb72b7f3cf6cef73aa32c Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sun, 1 Dec 2019 23:43:47 +0200 Subject: [PATCH 1188/1854] fix braces --- client/cmdhfmfp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/cmdhfmfp.c b/client/cmdhfmfp.c index 3081f77f4..2c0fc56eb 100644 --- a/client/cmdhfmfp.c +++ b/client/cmdhfmfp.c @@ -737,9 +737,9 @@ void Fill2bPattern(uint8_t keyList[MAX_KEYS_LIST_LEN][AES_KEY_LEN], size_t *keyL static int CmdHFMFPChk(const char *cmd) { int res; - uint8_t keyList[MAX_KEYS_LIST_LEN][AES_KEY_LEN] = {0}; + uint8_t keyList[MAX_KEYS_LIST_LEN][AES_KEY_LEN] = {{0}}; size_t keyListLen = 0; - uint8_t foundKeys[2][64][AES_KEY_LEN + 1] = {0}; + uint8_t foundKeys[2][64][AES_KEY_LEN + 1] = {{{0}}}; CLIParserInit("hf mfp chk", "Checks keys with Mifare Plus card.", From a0f0345169f6dd8fa681ae5f2716ab079960306e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 2 Dec 2019 10:20:07 +0100 Subject: [PATCH 1189/1854] fix travis --- client/fileutils.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/client/fileutils.c b/client/fileutils.c index 624c0259d..d82c00a48 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -354,17 +354,16 @@ int saveFileJSON(const char *preferredName, JSONFileType ftype, uint8_t *data, s case jsfT5555: case jsfMfPlusKeys: JsonSaveStr(root, "FileType", "mfp"); - JsonSaveBufAsHexCompact(root, "$.Card.UID", &data[0], 7); JsonSaveBufAsHexCompact(root, "$.Card.SAK", &data[10], 1); JsonSaveBufAsHexCompact(root, "$.Card.ATQA", &data[11], 2); uint8_t atslen = data[13]; if (atslen > 0) JsonSaveBufAsHexCompact(root, "$.Card.ATS", &data[14], atslen); - - uint8_t vdata[2][64][16 + 1] = {0}; + + uint8_t vdata[2][64][16 + 1] = {{{0}}}; memcpy(vdata, &data[14 + atslen], 2 * 64 * 17); - + for (size_t i = 0; i < datalen; i++) { char path[PATH_MAX_LENGTH] = {0}; @@ -379,7 +378,6 @@ int saveFileJSON(const char *preferredName, JSONFileType ftype, uint8_t *data, s sprintf(path, "$.SectorKeys.%d.KeyB", mfSectorNum(i)); JsonSaveBufAsHexCompact(root, path, &vdata[1][i][1], 16); } - } break; default: From 56c4343081372141e46e05472f9f242f043f650e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 2 Dec 2019 10:21:32 +0100 Subject: [PATCH 1190/1854] chg: hf 15 csetuid - verify uid is the same after writting --- client/cmdhf15.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/client/cmdhf15.c b/client/cmdhf15.c index 25fc00264..13bc02fa8 100644 --- a/client/cmdhf15.c +++ b/client/cmdhf15.c @@ -1701,14 +1701,15 @@ static int CmdHF15CSetUID(const char *Cmd) { return PM3_EINVARG; } - PrintAndLogEx(SUCCESS, "new UID | %s", sprint_hex(uid, sizeof(uid))); - PrintAndLogEx(INFO, "Using backdoor Magic tag function"); + PrintAndLogEx(SUCCESS, "Input new UID | %s", sprint_hex(uid, sizeof(uid))); if (!getUID(oldUid)) { - PrintAndLogEx(FAILED, "Can't get old UID."); + PrintAndLogEx(FAILED, "Can't get old/current UID."); return PM3_ESOFT; } + PrintAndLogEx(INFO, "Using backdoor magic tag function"); + // Command 1 : 02213E00000000 data[0][0] = 0x02; data[0][1] = 0x21; @@ -1767,11 +1768,14 @@ static int CmdHF15CSetUID(const char *Cmd) { return PM3_ESOFT; } - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(SUCCESS, "old UID : %02X %02X %02X %02X %02X %02X %02X %02X", oldUid[7], oldUid[6], oldUid[5], oldUid[4], oldUid[3], oldUid[2], oldUid[1], oldUid[0]); - PrintAndLogEx(SUCCESS, "new UID : %02X %02X %02X %02X %02X %02X %02X %02X", newUid[7], newUid[6], newUid[5], newUid[4], newUid[3], newUid[2], newUid[1], newUid[0]); - - return PM3_SUCCESS; + if (memcmp(newUid, uid, 8) != 0) { + PrintAndLogEx(FAILED, "Setting UID on tag failed."); + return PM3_ESOFT; + } else { + PrintAndLogEx(SUCCESS, "old UID : %02X %02X %02X %02X %02X %02X %02X %02X", oldUid[7], oldUid[6], oldUid[5], oldUid[4], oldUid[3], oldUid[2], oldUid[1], oldUid[0]); + PrintAndLogEx(SUCCESS, "new UID : %02X %02X %02X %02X %02X %02X %02X %02X", newUid[7], newUid[6], newUid[5], newUid[4], newUid[3], newUid[2], newUid[1], newUid[0]); + return PM3_SUCCESS; + } } static command_t CommandTable[] = { From 535298820bf2e821eb6702af1bf7bf7bb14a8aad Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 2 Dec 2019 11:40:22 +0100 Subject: [PATCH 1191/1854] chg: return codes etc --- client/cmdhfmfu.c | 64 +++++++++++++++++++++++------------------------ 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index d7bdce1fc..7d2b8cfc6 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -445,7 +445,7 @@ static int ul_ev1_pwdgen_selftest() { uint8_t uid4[] = {0x04, 0xC5, 0xDF, 0x4A, 0x6D, 0x51, 0x80}; uint32_t pwd4 = ul_ev1_pwdgenD(uid4); PrintAndLogEx(NORMAL, "UID | %s | %08X | %s", sprint_hex(uid4, 7), pwd4, (pwd4 == 0x72B1EC61) ? "OK" : "->72B1EC61<--"); - return 0; + return PM3_SUCCESS; } //------------------------------------ @@ -565,7 +565,7 @@ static int ulc_requestAuthentication(uint8_t *nonce, uint16_t nonceLength) { static int ulc_authentication(uint8_t *key, bool switch_off_field) { clearCommandBuffer(); - SendCommandOLD(CMD_HF_MIFAREUC_AUTH, switch_off_field, 0, 0, key, 16); + SendCommandMIX(CMD_HF_MIFAREUC_AUTH, switch_off_field, 0, 0, key, 16); PacketResponseNG resp; if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) return 0; if (resp.oldarg[0] == 1) return 1; @@ -2262,7 +2262,7 @@ static int CmdHF14AMfURestore(const char *Cmd) { PrintAndLogEx(NORMAL, "special PWD block written 0x%X - %s\n", MFU_NTAG_SPECIAL_PWD, sprint_hex(data, 4)); clearCommandBuffer(); - SendCommandOLD(CMD_HF_MIFAREU_WRITEBL, MFU_NTAG_SPECIAL_PWD, keytype, 0, data, sizeof(data)); + SendCommandMIX(CMD_HF_MIFAREU_WRITEBL, MFU_NTAG_SPECIAL_PWD, keytype, 0, data, sizeof(data)); wait4response(MFU_NTAG_SPECIAL_PWD); @@ -2278,7 +2278,7 @@ static int CmdHF14AMfURestore(const char *Cmd) { data[3] = 0; PrintAndLogEx(NORMAL, "special PACK block written 0x%X - %s\n", MFU_NTAG_SPECIAL_PACK, sprint_hex(data, 4)); clearCommandBuffer(); - SendCommandOLD(CMD_HF_MIFAREU_WRITEBL, MFU_NTAG_SPECIAL_PACK, keytype, 0, data, sizeof(data)); + SendCommandMIX(CMD_HF_MIFAREU_WRITEBL, MFU_NTAG_SPECIAL_PACK, keytype, 0, data, sizeof(data)); wait4response(MFU_NTAG_SPECIAL_PACK); // Signature @@ -2286,7 +2286,7 @@ static int CmdHF14AMfURestore(const char *Cmd) { memcpy(data, mem->signature + i, 4); PrintAndLogEx(NORMAL, "special SIG block written 0x%X - %s\n", s, sprint_hex(data, 4)); clearCommandBuffer(); - SendCommandOLD(CMD_HF_MIFAREU_WRITEBL, s, keytype, 0, data, sizeof(data)); + SendCommandMIX(CMD_HF_MIFAREU_WRITEBL, s, keytype, 0, data, sizeof(data)); wait4response(s); } @@ -2295,7 +2295,7 @@ static int CmdHF14AMfURestore(const char *Cmd) { memcpy(data, mem->version + i, 4); PrintAndLogEx(NORMAL, "special VERSION block written 0x%X - %s\n", s, sprint_hex(data, 4)); clearCommandBuffer(); - SendCommandOLD(CMD_HF_MIFAREU_WRITEBL, s, keytype, 0, data, sizeof(data)); + SendCommandMIX(CMD_HF_MIFAREU_WRITEBL, s, keytype, 0, data, sizeof(data)); wait4response(s); } } @@ -2309,7 +2309,7 @@ static int CmdHF14AMfURestore(const char *Cmd) { //Send write Block memcpy(data, mem->data + (b * 4), 4); clearCommandBuffer(); - SendCommandOLD(CMD_HF_MIFAREU_WRITEBL, b, keytype, 0, data, sizeof(data)); + SendCommandMIX(CMD_HF_MIFAREU_WRITEBL, b, keytype, 0, data, sizeof(data)); wait4response(b); printf("."); fflush(stdout); @@ -2329,7 +2329,7 @@ static int CmdHF14AMfURestore(const char *Cmd) { uint8_t b = blocks[i]; memcpy(data, mem->data + (b * 4), 4); clearCommandBuffer(); - SendCommandOLD(CMD_HF_MIFAREU_WRITEBL, b, keytype, 0, data, sizeof(data)); + SendCommandMIX(CMD_HF_MIFAREU_WRITEBL, b, keytype, 0, data, sizeof(data)); wait4response(b); PrintAndLogEx(NORMAL, "special block written %u - %s\n", b, sprint_hex(data, 4)); } @@ -2338,7 +2338,7 @@ static int CmdHF14AMfURestore(const char *Cmd) { DropField(); free(dump); PrintAndLogEx(INFO, "Finish restore"); - return 0; + return PM3_SUCCESS; } // // Load emulator with dump file @@ -2388,7 +2388,7 @@ static int CmdHF14AMfUCAuth(const char *Cmd) { else PrintAndLogEx(WARNING, "Authentication failed"); - return 0; + return PM3_SUCCESS; } /** @@ -2500,11 +2500,11 @@ static int CmdHF14AMfUCSetPwd(const char *Cmd) { if (param_gethex(Cmd, 0, pwd, 32)) { PrintAndLogEx(WARNING, "Password must include 32 HEX symbols"); - return 1; + return PM3_EINVARG; } clearCommandBuffer(); - SendCommandOLD(CMD_HF_MIFAREUC_SETPWD, 0, 0, 0, pwd, 16); + SendCommandMIX(CMD_HF_MIFAREUC_SETPWD, 0, 0, 0, pwd, 16); PacketResponseNG resp; if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { @@ -2512,13 +2512,13 @@ static int CmdHF14AMfUCSetPwd(const char *Cmd) { PrintAndLogEx(INFO, "Ultralight-C new password: %s", sprint_hex(pwd, 16)); } else { PrintAndLogEx(WARNING, "Failed writing at block %u", (uint8_t)(resp.oldarg[1] & 0xff)); - return 1; + return PM3_ESOFT; } } else { PrintAndLogEx(WARNING, "command execution time out"); - return 1; + return PM3_ETIMEOUT; } - return 0; + return PM3_SUCCESS; } // @@ -2556,7 +2556,7 @@ static int CmdHF14AMfUCSetUid(const char *Cmd) { data[2] = uid[2]; data[3] = 0x88 ^ uid[0] ^ uid[1] ^ uid[2]; clearCommandBuffer(); - SendCommandOLD(CMD_HF_MIFAREU_WRITEBL, 0, 0, 0, data, sizeof(data)); + SendCommandMIX(CMD_HF_MIFAREU_WRITEBL, 0, 0, 0, data, sizeof(data)); if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { PrintAndLogEx(WARNING, "Command execute timeout"); return PM3_ETIMEOUT; @@ -2568,7 +2568,7 @@ static int CmdHF14AMfUCSetUid(const char *Cmd) { data[2] = uid[5]; data[3] = uid[6]; clearCommandBuffer(); - SendCommandOLD(CMD_HF_MIFAREU_WRITEBL, 1, 0, 0, data, sizeof(data)); + SendCommandMIX(CMD_HF_MIFAREU_WRITEBL, 1, 0, 0, data, sizeof(data)); if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { PrintAndLogEx(WARNING, "Command execute timeout"); return PM3_ETIMEOUT; @@ -2580,7 +2580,7 @@ static int CmdHF14AMfUCSetUid(const char *Cmd) { data[2] = oldblock2[2]; data[3] = oldblock2[3]; clearCommandBuffer(); - SendCommandOLD(CMD_HF_MIFAREU_WRITEBL, 2, 0, 0, data, sizeof(data)); + SendCommandMIX(CMD_HF_MIFAREU_WRITEBL, 2, 0, 0, data, sizeof(data)); if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { PrintAndLogEx(WARNING, "Command execute timeout"); return PM3_ETIMEOUT; @@ -2611,11 +2611,11 @@ static int CmdHF14AMfUGenDiverseKeys(const char *Cmd) { if (select_status == 0) { PrintAndLogEx(WARNING, "iso14443a card select failed"); - return 1; + return PM3_ESOFT; } if (card.uidlen != 4) { PrintAndLogEx(WARNING, "Wrong sized UID, expected 4bytes got %d", card.uidlen); - return 1; + return PM3_ESOFT; } memcpy(uid, card.uid, sizeof(uid)); } else { @@ -2654,13 +2654,13 @@ static int CmdHF14AMfUGenDiverseKeys(const char *Cmd) { , divkey // output ); - PrintAndLogEx(NORMAL, "-- 3DES version"); - PrintAndLogEx(NORMAL, "Masterkey :\t %s", sprint_hex(masterkey, sizeof(masterkey))); - PrintAndLogEx(NORMAL, "UID :\t %s", sprint_hex(uid, sizeof(uid))); - PrintAndLogEx(NORMAL, "block :\t %0d", block); - PrintAndLogEx(NORMAL, "Mifare key :\t %s", sprint_hex(mifarekeyA, sizeof(mifarekeyA))); - PrintAndLogEx(NORMAL, "Message :\t %s", sprint_hex(mix, sizeof(mix))); - PrintAndLogEx(NORMAL, "Diversified key: %s", sprint_hex(divkey + 1, 6)); + PrintAndLogEx(SUCCESS, "-- 3DES version"); + PrintAndLogEx(SUCCESS, "Masterkey :\t %s", sprint_hex(masterkey, sizeof(masterkey))); + PrintAndLogEx(SUCCESS, "UID :\t %s", sprint_hex(uid, sizeof(uid))); + PrintAndLogEx(SUCCESS, "block :\t %0d", block); + PrintAndLogEx(SUCCESS, "Mifare key :\t %s", sprint_hex(mifarekeyA, sizeof(mifarekeyA))); + PrintAndLogEx(SUCCESS, "Message :\t %s", sprint_hex(mix, sizeof(mix))); + PrintAndLogEx(SUCCESS, "Diversified key: %s", sprint_hex(divkey + 1, 6)); for (int i = 0; i < ARRAYLEN(mifarekeyA); ++i) { dkeyA[i] = (mifarekeyA[i] << 1) & 0xff; @@ -2690,11 +2690,11 @@ static int CmdHF14AMfUGenDiverseKeys(const char *Cmd) { , newpwd // output ); - PrintAndLogEx(NORMAL, "\n-- DES version"); - PrintAndLogEx(NORMAL, "Mifare dkeyA :\t %s", sprint_hex(dkeyA, sizeof(dkeyA))); - PrintAndLogEx(NORMAL, "Mifare dkeyB :\t %s", sprint_hex(dkeyB, sizeof(dkeyB))); - PrintAndLogEx(NORMAL, "Mifare ABA :\t %s", sprint_hex(dmkey, sizeof(dmkey))); - PrintAndLogEx(NORMAL, "Mifare Pwd :\t %s", sprint_hex(newpwd, sizeof(newpwd))); + PrintAndLogEx(SUCCESS, "\n-- DES version"); + PrintAndLogEx(SUCCESS, "Mifare dkeyA :\t %s", sprint_hex(dkeyA, sizeof(dkeyA))); + PrintAndLogEx(SUCCESS, "Mifare dkeyB :\t %s", sprint_hex(dkeyB, sizeof(dkeyB))); + PrintAndLogEx(SUCCESS, "Mifare ABA :\t %s", sprint_hex(dmkey, sizeof(dmkey))); + PrintAndLogEx(SUCCESS, "Mifare Pwd :\t %s", sprint_hex(newpwd, sizeof(newpwd))); mbedtls_des3_free(&ctx); // next. from the diversify_key method. From e812726c703130930a1c63bddf811ccfe8e96a45 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 2 Dec 2019 11:47:43 +0100 Subject: [PATCH 1192/1854] chg: return codes etc --- client/cmdhfmfdes.c | 73 +++++++++++++++++++++++---------------------- 1 file changed, 38 insertions(+), 35 deletions(-) diff --git a/client/cmdhfmfdes.c b/client/cmdhfmfdes.c index 17dd97289..d1b1b5dd8 100644 --- a/client/cmdhfmfdes.c +++ b/client/cmdhfmfdes.c @@ -33,7 +33,7 @@ static int CmdHF14ADesInfo(const char *Cmd) { if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { PrintAndLogEx(WARNING, "Command execute timeout"); - return 0; + return PM3_ETIMEOUT; } uint8_t isOK = resp.oldarg[0] & 0xff; if (!isOK) { @@ -49,7 +49,7 @@ static int CmdHF14ADesInfo(const char *Cmd) { PrintAndLogEx(WARNING, "Command unsuccessful"); break; } - return 0; + return PM3_ESOFT; } PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "-- Desfire Information --------------------------------------"); @@ -82,7 +82,7 @@ static int CmdHF14ADesInfo(const char *Cmd) { uint8_t data[1] = {GET_FREE_MEMORY}; SendCommandOLD(CMD_HF_DESFIRE_COMMAND, (INIT | DISCONNECT), 0x01, 0, data, sizeof(data)); if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) - return 0; + return PM3_ETIMEOUT; uint8_t tmp[3]; memcpy(tmp, resp.data.asBytes + 3, 3); @@ -105,7 +105,7 @@ static int CmdHF14ADesInfo(const char *Cmd) { */ - return 1; + return PM3_SUCCESS; } /* @@ -189,10 +189,12 @@ void getKeySettings(uint8_t *aid) { PrintAndLogEx(NORMAL, " [0x02] Directory list access with CMK : %s", str); str = (resp.data.asBytes[3] & (1 << 0)) ? "YES" : "NO"; PrintAndLogEx(NORMAL, " [0x01] CMK is changeable : %s", str); + { uint8_t data[2] = {GET_KEY_VERSION, 0}; // 0x64 - SendCommandOLD(CMD_HF_DESFIRE_COMMAND, INIT | DISCONNECT, sizeof(data), 0, data, sizeof(data)); + SendCommandMIX(CMD_HF_DESFIRE_COMMAND, INIT | DISCONNECT, sizeof(data), 0, data, sizeof(data)); } + if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)) { return; } isOK = resp.oldarg[0] & 0xff; if (!isOK) { @@ -206,24 +208,27 @@ void getKeySettings(uint8_t *aid) { { uint8_t data[2] = {AUTHENTICATE, 0}; // 0x0A, KEY 0 - SendCommandOLD(CMD_HF_DESFIRE_COMMAND, INIT | DISCONNECT, sizeof(data), 0, data, sizeof(data)); + SendCommandMIX(CMD_HF_DESFIRE_COMMAND, INIT | DISCONNECT, sizeof(data), 0, data, sizeof(data)); } + if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)) {return;} isOK = resp.data.asBytes[2] & 0xff; PrintAndLogEx(NORMAL, " [0x0A] Authenticate : %s", (isOK == 0xAE) ? "NO" : "YES"); { uint8_t data[2] = {AUTHENTICATE_ISO, 0}; // 0x1A, KEY 0 - SendCommandOLD(CMD_HF_DESFIRE_COMMAND, INIT | DISCONNECT, sizeof(data), 0, data, sizeof(data)); + SendCommandMIX(CMD_HF_DESFIRE_COMMAND, INIT | DISCONNECT, sizeof(data), 0, data, sizeof(data)); } + if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)) {return;} isOK = resp.data.asBytes[2] & 0xff; PrintAndLogEx(NORMAL, " [0x1A] Authenticate ISO : %s", (isOK == 0xAE) ? "NO" : "YES"); { uint8_t data[2] = {AUTHENTICATE_AES, 0}; // 0xAA, KEY 0 - SendCommandOLD(CMD_HF_DESFIRE_COMMAND, INIT | DISCONNECT, sizeof(data), 0, data, sizeof(data)); + SendCommandMIX(CMD_HF_DESFIRE_COMMAND, INIT | DISCONNECT, sizeof(data), 0, data, sizeof(data)); } + if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)) {return;} isOK = resp.data.asBytes[2] & 0xff; PrintAndLogEx(NORMAL, " [0xAA] Authenticate AES : %s", (isOK == 0xAE) ? "NO" : "YES"); @@ -237,7 +242,7 @@ void getKeySettings(uint8_t *aid) { { uint8_t data[4] = {SELECT_APPLICATION}; // 0x5a memcpy(data + 1, aid, 3); - SendCommandOLD(CMD_HF_DESFIRE_COMMAND, INIT | CLEARTRACE, sizeof(data), 0, data, sizeof(data)); + SendCommandMIX(CMD_HF_DESFIRE_COMMAND, INIT | CLEARTRACE, sizeof(data), 0, data, sizeof(data)); } if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { PrintAndLogEx(WARNING, " Timed-out"); @@ -252,8 +257,9 @@ void getKeySettings(uint8_t *aid) { // KEY SETTINGS { uint8_t data[1] = {GET_KEY_SETTINGS}; // 0x45 - SendCommandOLD(CMD_HF_DESFIRE_COMMAND, NONE, sizeof(data), 0, data, sizeof(data)); + SendCommandMIX(CMD_HF_DESFIRE_COMMAND, NONE, sizeof(data), 0, data, sizeof(data)); } + if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { return; } @@ -294,8 +300,9 @@ void getKeySettings(uint8_t *aid) { // KEY VERSION - AMK { uint8_t data[2] = {GET_KEY_VERSION, 0}; // 0x64 - SendCommandOLD(CMD_HF_DESFIRE_COMMAND, NONE, sizeof(data), 0, data, sizeof(data)); + SendCommandMIX(CMD_HF_DESFIRE_COMMAND, NONE, sizeof(data), 0, data, sizeof(data)); } + if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { PrintAndLogEx(WARNING, " Timed-out"); return; @@ -318,11 +325,10 @@ void getKeySettings(uint8_t *aid) { // LOOP over numOfKeys that we got before. // From 0x01 to numOfKeys. We already got 0x00. (AMK) // TODO (iceman) +/* for (int i = 0x01; i <= 0x0f; ++i) { - } - - +*/ } } @@ -333,17 +339,18 @@ static int CmdHF14ADesEnumApplications(const char *Cmd) { uint8_t aid[3]; { uint8_t data[1] = {GET_APPLICATION_IDS}; //0x6a - SendCommandOLD(CMD_HF_DESFIRE_COMMAND, INIT | DISCONNECT, sizeof(data), 0, data, sizeof(data)); + SendCommandMIX(CMD_HF_DESFIRE_COMMAND, INIT | DISCONNECT, sizeof(data), 0, data, sizeof(data)); } PacketResponseNG resp; if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { - return 0; + return PM3_ETIMEOUT; } + isOK = resp.oldarg[0] & 0xff; if (!isOK) { PrintAndLogEx(NORMAL, "Command unsuccessful"); - return 0; + return PM3_ESOFT; } PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "-- Desfire Enumerate Applications ---------------------------"); @@ -368,7 +375,7 @@ static int CmdHF14ADesEnumApplications(const char *Cmd) { { uint8_t data[4] = {SELECT_APPLICATION}; // 0x5a memcpy(data + 1, &resp.data.asBytes[i], 3); - SendCommandOLD(CMD_HF_DESFIRE_COMMAND, INIT, sizeof(data), 0, data, sizeof(data)); + SendCommandMIX(CMD_HF_DESFIRE_COMMAND, INIT, sizeof(data), 0, data, sizeof(data)); } if (!WaitForResponseTimeout(CMD_ACK, &respAid, 1500)) { @@ -384,7 +391,7 @@ static int CmdHF14ADesEnumApplications(const char *Cmd) { // Get File IDs { uint8_t data[1] = {GET_FILE_IDS}; // 0x6f - SendCommandOLD(CMD_HF_DESFIRE_COMMAND, NONE, sizeof(data), 0, data, sizeof(data)); + SendCommandMIX(CMD_HF_DESFIRE_COMMAND, NONE, sizeof(data), 0, data, sizeof(data)); } if (!WaitForResponseTimeout(CMD_ACK, &respFiles, 1500)) { @@ -405,7 +412,7 @@ static int CmdHF14ADesEnumApplications(const char *Cmd) { // Get ISO File IDs { uint8_t data[1] = {GET_ISOFILE_IDS}; // 0x61 - SendCommandOLD(CMD_HF_DESFIRE_COMMAND, DISCONNECT, sizeof(data), 0, data, sizeof(data)); + SendCommandMIX(CMD_HF_DESFIRE_COMMAND, DISCONNECT, sizeof(data), 0, data, sizeof(data)); } if (!WaitForResponseTimeout(CMD_ACK, &respFiles, 1500)) { @@ -422,13 +429,9 @@ static int CmdHF14ADesEnumApplications(const char *Cmd) { } } } - - } PrintAndLogEx(NORMAL, "-------------------------------------------------------------"); - - - return 1; + return PM3_SUCCESS; } // MIAFRE DesFire Authentication @@ -456,7 +459,7 @@ static int CmdHF14ADesAuth(const char *Cmd) { PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf mfdes auth 1 1 0 11223344"); PrintAndLogEx(NORMAL, " hf mfdes auth 3 4 0 404142434445464748494a4b4c4d4e4f"); - return 0; + return PM3_SUCCESS; } uint8_t cmdAuthMode = param_get8(Cmd, 0); uint8_t cmdAuthAlgo = param_get8(Cmd, 1); @@ -466,25 +469,24 @@ static int CmdHF14ADesAuth(const char *Cmd) { case 1: if (cmdAuthAlgo != 1 && cmdAuthAlgo != 2) { PrintAndLogEx(NORMAL, "Crypto algo not valid for the auth mode"); - return 1; + return PM3_EINVARG; } break; case 2: if (cmdAuthAlgo != 1 && cmdAuthAlgo != 2 && cmdAuthAlgo != 3) { PrintAndLogEx(NORMAL, "Crypto algo not valid for the auth mode"); - return 1; + return PM3_EINVARG; } break; case 3: if (cmdAuthAlgo != 4) { PrintAndLogEx(NORMAL, "Crypto algo not valid for the auth mode"); - return 1; + return PM3_EINVARG; } break; default: PrintAndLogEx(WARNING, "Wrong Auth mode"); - return 1; - break; + return PM3_EINVARG; } switch (cmdAuthAlgo) { @@ -510,8 +512,9 @@ static int CmdHF14ADesAuth(const char *Cmd) { // key if (param_gethex(Cmd, 3, key, keylength * 2)) { PrintAndLogEx(WARNING, "Key must include %d HEX symbols", keylength); - return 1; + return PM3_EINVARG; } + // algo, keylength, uint8_t data[25] = {keylength}; // max length: 1 + 24 (3k3DES) memcpy(data + 1, key, keylength); @@ -521,7 +524,7 @@ static int CmdHF14ADesAuth(const char *Cmd) { if (!WaitForResponseTimeout(CMD_ACK, &resp, 3000)) { PrintAndLogEx(WARNING, "Client command execute timeout"); - return 0; + return PM3_ETIMEOUT; } uint8_t isOK = resp.oldarg[0] & 0xff; @@ -536,7 +539,7 @@ static int CmdHF14ADesAuth(const char *Cmd) { PrintAndLogEx(NORMAL, "Client command failed."); } PrintAndLogEx(NORMAL, "-------------------------------------------------------------"); - return 1; + return PM3_SUCCESS; } @@ -553,7 +556,7 @@ static command_t CommandTable[] = { static int CmdHelp(const char *Cmd) { (void)Cmd; // Cmd is not used so far CmdsHelp(CommandTable); - return 0; + return PM3_SUCCESS; } int CmdHFMFDes(const char *Cmd) { From 85ff07caa62992fc73e1ec27e4f0de18af445295 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 2 Dec 2019 11:53:50 +0100 Subject: [PATCH 1193/1854] chg: return codes etc --- client/cmdhfepa.c | 52 +++++++++++++++++++++++------------------------ 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/client/cmdhfepa.c b/client/cmdhfepa.c index af5d26eaf..e83ee39bf 100644 --- a/client/cmdhfepa.c +++ b/client/cmdhfepa.c @@ -16,7 +16,7 @@ #include #include "cmdparser.h" // command_t -#include "commonutil.h" // ARRAYLEN +#include "commonutil.h" // ARRAYLEN #include "comms.h" // clearCommandBuffer #include "ui.h" #include "util_posix.h" @@ -38,8 +38,8 @@ static int CmdHFEPACollectPACENonces(const char *Cmd) { m = m > 0 ? m : 1; n = n > 0 ? n : 1; - PrintAndLogEx(NORMAL, "Collecting %u %u byte nonces", n, m); - PrintAndLogEx(NORMAL, "Start: %" PRIu64, msclock() / 1000); + PrintAndLogEx(SUCCESS, "Collecting %u %u byte nonces", n, m); + PrintAndLogEx(SUCCESS, "Start: %" PRIu64, msclock() / 1000); // repeat n times for (uint32_t i = 0; i < n; i++) { // execute PACE @@ -58,15 +58,15 @@ static int CmdHFEPACollectPACENonces(const char *Cmd) { sprintf(nonce + (2 * j), "%02X", resp.data.asBytes[j]); } // print nonce - PrintAndLogEx(NORMAL, "Length: %zu, Nonce: %s", nonce_length, nonce); + PrintAndLogEx(SUCCESS, "Length: %zu, Nonce: %s", nonce_length, nonce); free(nonce); } if (i < n - 1) { sleep(d); } } - PrintAndLogEx(NORMAL, "End: %" PRIu64, msclock() / 1000); - return 1; + PrintAndLogEx(SUCCESS, "End: %" PRIu64, msclock() / 1000); + return PM3_SUCCESS; } // perform the PACE protocol by replaying APDUs @@ -98,9 +98,9 @@ static int CmdHFEPAPACEReplay(const char *Cmd) { ); if (scan_return < 1) { - PrintAndLogEx(NORMAL, (char *)usage_msg); + PrintAndLogEx(INFO, (char *)usage_msg); PrintAndLogEx(WARNING, "Not enough APDUs! Try again!"); - return 0; + return PM3_SUCCESS; } skip += skip_add; apdu_lengths[i]++; @@ -110,8 +110,8 @@ static int CmdHFEPAPACEReplay(const char *Cmd) { if (Cmd[skip] == '\0') { if (i < ARRAYLEN(apdu_lengths) - 1) { - PrintAndLogEx(NORMAL, (char *)usage_msg); - return 0; + PrintAndLogEx(INFO, (char *)usage_msg); + return PM3_SUCCESS; } break; } @@ -146,7 +146,7 @@ static int CmdHFEPAPACEReplay(const char *Cmd) { WaitForResponse(CMD_ACK, &resp); if (resp.oldarg[0] != 0) { PrintAndLogEx(WARNING, "Transfer of APDU #%d Part %d failed!", i, j); - return 0; + return PM3_ESOFT; } } } @@ -156,22 +156,22 @@ static int CmdHFEPAPACEReplay(const char *Cmd) { SendCommandMIX(CMD_HF_EPA_REPLAY, 0, 0, 0, NULL, 0); WaitForResponse(CMD_ACK, &resp); if (resp.oldarg[0] != 0) { - PrintAndLogEx(NORMAL, "\nPACE replay failed in step %u!", (uint32_t)resp.oldarg[0]); - PrintAndLogEx(NORMAL, "Measured times:"); - PrintAndLogEx(NORMAL, "MSE Set AT: %u us", resp.data.asDwords[0]); - PrintAndLogEx(NORMAL, "GA Get Nonce: %u us", resp.data.asDwords[1]); - PrintAndLogEx(NORMAL, "GA Map Nonce: %u us", resp.data.asDwords[2]); - PrintAndLogEx(NORMAL, "GA Perform Key Agreement: %u us", resp.data.asDwords[3]); - PrintAndLogEx(NORMAL, "GA Mutual Authenticate: %u us", resp.data.asDwords[4]); + PrintAndLogEx(SUCCESS, "\nPACE replay failed in step %u!", (uint32_t)resp.oldarg[0]); + PrintAndLogEx(SUCCESS, "Measured times:"); + PrintAndLogEx(SUCCESS, "MSE Set AT: %u us", resp.data.asDwords[0]); + PrintAndLogEx(SUCCESS, "GA Get Nonce: %u us", resp.data.asDwords[1]); + PrintAndLogEx(SUCCESS, "GA Map Nonce: %u us", resp.data.asDwords[2]); + PrintAndLogEx(SUCCESS, "GA Perform Key Agreement: %u us", resp.data.asDwords[3]); + PrintAndLogEx(SUCCESS, "GA Mutual Authenticate: %u us", resp.data.asDwords[4]); } else { - PrintAndLogEx(NORMAL, "PACE replay successful!"); - PrintAndLogEx(NORMAL, "MSE Set AT: %u us", resp.data.asDwords[0]); - PrintAndLogEx(NORMAL, "GA Get Nonce: %u us", resp.data.asDwords[1]); - PrintAndLogEx(NORMAL, "GA Map Nonce: %u us", resp.data.asDwords[2]); - PrintAndLogEx(NORMAL, "GA Perform Key Agreement: %u us", resp.data.asDwords[3]); - PrintAndLogEx(NORMAL, "GA Mutual Authenticate: %u us", resp.data.asDwords[4]); + PrintAndLogEx(SUCCESS, "PACE replay successful!"); + PrintAndLogEx(SUCCESS, "MSE Set AT: %u us", resp.data.asDwords[0]); + PrintAndLogEx(SUCCESS, "GA Get Nonce: %u us", resp.data.asDwords[1]); + PrintAndLogEx(SUCCESS, "GA Map Nonce: %u us", resp.data.asDwords[2]); + PrintAndLogEx(SUCCESS, "GA Perform Key Agreement: %u us", resp.data.asDwords[3]); + PrintAndLogEx(SUCCESS, "GA Mutual Authenticate: %u us", resp.data.asDwords[4]); } - return 1; + return PM3_SUCCESS; } static command_t CommandTable[] = { @@ -184,7 +184,7 @@ static command_t CommandTable[] = { static int CmdHelp(const char *Cmd) { (void)Cmd; // Cmd is not used so far CmdsHelp(CommandTable); - return 0; + return PM3_SUCCESS; } int CmdHFEPA(const char *Cmd) { From 14f7b04edb665e03467d820762a99c8ade150b48 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 2 Dec 2019 16:42:55 +0200 Subject: [PATCH 1194/1854] add changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2360c615d..161c581c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Added mf plus command `hf mfp chk` for check keys from public keys list, from dictionary or 1 and 2-byte bruteforce (@merlokk) - Change `hf 15` - some refactoring (@grspy) - Added `hf 15 writeafi` and `hf 15 writedsfid` (@grspy) - Added detailed info for SLIX2 tags in `hf 15 info` (@grspy) From 917fc80b90ffd359b51233793a9c180c1187aa26 Mon Sep 17 00:00:00 2001 From: Iceman Date: Mon, 2 Dec 2019 20:26:04 +0100 Subject: [PATCH 1195/1854] Update README.md --- README.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/README.md b/README.md index b306ad542..f400633d5 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,5 @@ # RRG / Iceman repo - Proxmark3 -This repo is based on iceman fork for Proxmark3. - -It supports RDV4.0 and other Proxmark3 platforms as well. - - | Releases | Linux & OSX CI | Windows CI | Coverity | | ------------------- |:-------------------:| -------------------:| -------------------:| | [![Latest release](https://img.shields.io/github/release/RfidResearchGroup/proxmark3.svg)](https://github.com/RfidResearchGroup/proxmark3/releases/latest) | [![Build status](https://travis-ci.org/RfidResearchGroup/proxmark3.svg?branch=master)](https://travis-ci.org/RfidResearchGroup/proxmark3) | [![Build status](https://ci.appveyor.com/api/projects/status/b4gwrhq3nc876cuu/branch/master?svg=true)](https://ci.appveyor.com/project/RfidResearchGroup/proxmark3/branch/master) | [![Coverity Status](https://scan.coverity.com/projects/19334/badge.svg)](https://scan.coverity.com/projects/proxmark3-rrg-iceman-repo)| @@ -110,4 +105,3 @@ Nothing says thank you as much as a donation. So if you feel the love, do feel f https://www.patreon.com/iceman1001 -All support is welcome! From 26ffd5fad5d0c79523de46df9626a0a777b39d2b Mon Sep 17 00:00:00 2001 From: Iceman Date: Mon, 2 Dec 2019 20:28:29 +0100 Subject: [PATCH 1196/1854] Update README.md --- README.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f400633d5..7e4c28145 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,11 @@ # RRG / Iceman repo - Proxmark3 + | Releases | Linux & OSX CI | Windows CI | Coverity | | ------------------- |:-------------------:| -------------------:| -------------------:| | [![Latest release](https://img.shields.io/github/release/RfidResearchGroup/proxmark3.svg)](https://github.com/RfidResearchGroup/proxmark3/releases/latest) | [![Build status](https://travis-ci.org/RfidResearchGroup/proxmark3.svg?branch=master)](https://travis-ci.org/RfidResearchGroup/proxmark3) | [![Build status](https://ci.appveyor.com/api/projects/status/b4gwrhq3nc876cuu/branch/master?svg=true)](https://ci.appveyor.com/project/RfidResearchGroup/proxmark3/branch/master) | [![Coverity Status](https://scan.coverity.com/projects/19334/badge.svg)](https://scan.coverity.com/projects/proxmark3-rrg-iceman-repo)| ---- + + # PROXMARK INSTALLATION AND OVERVIEW @@ -24,10 +26,12 @@ |[Developing standalone mode](/armsrc/Standalone/readme.md)|[Wiki about standalone mode](https://github.com/RfidResearchGroup/proxmark3/wiki/Standalone-mode) || |[Donations](#Donations)||| -## Support on other Proxmark3 platforms + +## Build for non-RDV4 Proxmark3 platforms In order to build this repo for other Proxmark3 platforms we urge you to read [Advanced compilation parameters](/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md) + ## What has changed? On the hardware side: From 46ba161ba299ad07f80b4dd24ecf60c9ea8536d7 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 3 Dec 2019 14:47:34 +0100 Subject: [PATCH 1197/1854] ADD file --- tools/pm3_mf7b_wipe.py | 150 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 tools/pm3_mf7b_wipe.py diff --git a/tools/pm3_mf7b_wipe.py b/tools/pm3_mf7b_wipe.py new file mode 100644 index 000000000..bfa1f2524 --- /dev/null +++ b/tools/pm3_mf7b_wipe.py @@ -0,0 +1,150 @@ +#! /usr/bin/env python3.6 +# -*- coding: utf-8 -*- +# +# VULNERS OPENSOURCE +# __________________ +# +# Vulners Project [https://vulners.com] +# All Rights Reserved. +# +# Author: Kir [isox@vulners.com] +# Credits: Dennis Goh [dennis@rfidresearchgroup.com] +# +# This helper script is made for wiping S50 7byte UID cards with Gen2 magic commands from restored state to blank one. +# +# Scenario: +# You want to clone 7byte Mifare 1k card using RfidResearchGroup Proxmark3 RDV4.0 +# +# Step 1: Dumping original card and making a Mifare 7byte UID clone using S50 7byte UID +# +# Place original card to the reader. +# Dump data and recover keys +# +# hf mf autopwn +# +# You will get data, EML and key file. Backup this file, you will need them to wipe the card back to blank state. +# Place blank S50 card to the reader. +# +# Get first line from EML file (block0) and write it down using command +# +# Place it here +# | +# | +# v +# hf mf wrbl 0 B FFFFFFFFFFFF 046E46AAA53480084400120111003113 +# +# Now restore all the data using built-in restore command +# +# hf mf restore +# +# Step 2: Recovering S50 7byte UID card to the blank state +# +# Find current card data files from Step 1 in your backup or if you lost them create them again using 'hf mf autopwn' command. +# Place them in current working directory. +# +# Read hf-mf-CARD_UID-data.eml file and copy it content with CTRL-C. +# Place it to the eml variable in this script. +# +# Check execution command and check device and command name: 'proxmark3 -c "%s" /dev/tty.usbmodemiceman1' +# +# Run script and review key blocks returning to default FFFFFFFFFFFF state. +# Be patient! It is executing aprox 3 minutes. +# Success one result looks like: +# +# Block 0: Success: isOk:01 +# Block 3: Success: isOk:01 +# Block 7: Success: isOk:01 +# Block 11: Success: isOk:01 +# Block 15: Success: isOk:01 +# Block 19: Success: isOk:01 +# Block 23: Success: isOk:01 +# Block 27: Success: isOk:01 +# Block 31: Success: isOk:01 +# Block 35: Success: isOk:01 +# Block 39: Success: isOk:01 +# Block 43: Success: isOk:01 +# Block 47: Success: isOk:01 +# Block 51: Success: isOk:01 +# Block 55: Success: isOk:01 +# Block 59: Success: isOk:01 +# Block 63: Success: isOk:01 +# +# Thats it! Your S50 7byte UID card is wiped back. Now you can return back to Step 1 of this manual. +# +# + + + + +import subprocess + +# EML data var te get keys of +EML_FILE_DATA = """PLACE RAW hf-mf-CARD_UID-data.eml FILE CONTENT OF CURRENTLY LOADED CARD HERE""" +# Change your device name here if it differs from the default Proxmark3 RDV4.0 +PROXMARK_BIN_EXEC_STRING = 'proxmark3 -c "%s" /dev/tty.usbmodemiceman1' +# Constants +DEFAULT_ACCESS_BLOCK = "FFFFFFFFFFFFFF078000FFFFFFFFFFFF" +F12_KEY = "FFFFFFFFFFFF" + +def exec_proxmark_cmd(command, retry = 2, input=""): + exec_ok = False + retry_c = 0 + while not exec_ok and retry_c < retry: + sh_command = PROXMARK_BIN_EXEC_STRING % command + rst = subprocess.run(sh_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, input=input.encode("utf-8")) + + proxmark_reply = rst.stdout.decode("utf-8") + proxmark_status = proxmark_reply.splitlines()[-1:][0].strip() + if proxmark_status == "isOk:01": + return True, "Success: " + proxmark_status + retry_c += 1 + return False, "Error: %s , status %s" % (proxmark_reply.splitlines()[-2:][0], proxmark_status) + + +def chunk(iterable,n): + """assumes n is an integer>0 + """ + iterable=iter(iterable) + while True: + result=[] + for i in range(n): + try: + a=next(iterable) + except StopIteration: + break + else: + result.append(a) + if result: + yield result + else: + break + +sector_array = [sector for sector in chunk(EML_FILE_DATA.splitlines(), 4)] +block = 0 +block_success = {} + +for sector in sector_array: + key_A = sector[3][:12] + key_B = sector[3][-12:] + for _block in range(0,4): + if sector_array.index(sector) == 0 and block == 0: + write_status, verbose = exec_proxmark_cmd("hf mf wrbl %s B %s %s" % (block, key_B, sector[0])) + if not write_status: + write_status, verbose = exec_proxmark_cmd("hf mf wrbl %s A %s %s" % (block, key_A, sector[0])) + if not write_status: + write_status, verbose = exec_proxmark_cmd("hf mf wrbl %s A %s %s" % (block, F12_KEY, sector[0])) + block_success[block] = verbose + + elif _block == 3: + write_status, verbose = exec_proxmark_cmd("hf mf wrbl %s B %s %s" % (block, key_B, DEFAULT_ACCESS_BLOCK)) + if not write_status: + write_status, verbose = exec_proxmark_cmd("hf mf wrbl %s A %s %s" % (block, key_A, DEFAULT_ACCESS_BLOCK)) + if not write_status: + write_status, verbose = exec_proxmark_cmd("hf mf wrbl %s A %s %s" % (block, F12_KEY, DEFAULT_ACCESS_BLOCK)) + block_success[block] = verbose + + _block += 1 + block += 1 + +for block in block_success: + print("Block %s: %s" % (block ,block_success[block])) \ No newline at end of file From bb5c4d6162c8037244a93d428972f7be5db64801 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 3 Dec 2019 14:50:48 +0100 Subject: [PATCH 1198/1854] Add python script to wipe S70 7b Gen2 magic tags. Thanks @vulnersCom --- CHANGELOG.md | 3 ++- tools/pm3_mf7b_wipe.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 161c581c2..296c892dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,8 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] - - Added mf plus command `hf mfp chk` for check keys from public keys list, from dictionary or 1 and 2-byte bruteforce (@merlokk) + - Added 'pm3_mf7b_wipe.py' python script. Wipes magic S70 7B Gen2 card. (@vulnersCom) + - Added `hf mfp chk` Mifare plus command for check keys from public keys list, from dictionary or 1 and 2-byte bruteforce (@merlokk) - Change `hf 15` - some refactoring (@grspy) - Added `hf 15 writeafi` and `hf 15 writedsfid` (@grspy) - Added detailed info for SLIX2 tags in `hf 15 info` (@grspy) diff --git a/tools/pm3_mf7b_wipe.py b/tools/pm3_mf7b_wipe.py index bfa1f2524..f4c58ce01 100644 --- a/tools/pm3_mf7b_wipe.py +++ b/tools/pm3_mf7b_wipe.py @@ -147,4 +147,4 @@ for sector in sector_array: block += 1 for block in block_success: - print("Block %s: %s" % (block ,block_success[block])) \ No newline at end of file + print("Block %s: %s" % (block ,block_success[block])) From b5be8a3663181035b093136df82541c3d203dbb0 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 3 Dec 2019 14:51:55 +0100 Subject: [PATCH 1199/1854] style --- client/cmdhfmfdes.c | 8 ++--- client/cmdhfmfp.c | 70 ++++++++++++++++++++--------------------- client/fileutils.c | 20 ++++++------ client/fileutils.h | 4 +-- client/mifare/mifare4.c | 2 +- 5 files changed, 52 insertions(+), 52 deletions(-) diff --git a/client/cmdhfmfdes.c b/client/cmdhfmfdes.c index d1b1b5dd8..63e5a5be5 100644 --- a/client/cmdhfmfdes.c +++ b/client/cmdhfmfdes.c @@ -325,10 +325,10 @@ void getKeySettings(uint8_t *aid) { // LOOP over numOfKeys that we got before. // From 0x01 to numOfKeys. We already got 0x00. (AMK) // TODO (iceman) -/* - for (int i = 0x01; i <= 0x0f; ++i) { - } -*/ + /* + for (int i = 0x01; i <= 0x0f; ++i) { + } + */ } } diff --git a/client/cmdhfmfp.c b/client/cmdhfmfp.c index 2c0fc56eb..ec7c4cc72 100644 --- a/client/cmdhfmfp.c +++ b/client/cmdhfmfp.c @@ -642,9 +642,9 @@ static int CmdHFMFPWrbl(const char *cmd) { #define AES_KEY_LEN 16 #define MAX_KEYS_LIST_LEN 1024 - int MFPKeyCheck(uint8_t startSector, uint8_t endSector, uint8_t startKeyAB, uint8_t endKeyAB, - uint8_t keyList[MAX_KEYS_LIST_LEN][AES_KEY_LEN], size_t keyListLen, uint8_t foundKeys[2][64][AES_KEY_LEN + 1], - bool verbose) { +int MFPKeyCheck(uint8_t startSector, uint8_t endSector, uint8_t startKeyAB, uint8_t endKeyAB, + uint8_t keyList[MAX_KEYS_LIST_LEN][AES_KEY_LEN], size_t keyListLen, uint8_t foundKeys[2][64][AES_KEY_LEN + 1], + bool verbose) { int res; bool selectCard = true; uint8_t keyn[2] = {0}; @@ -652,7 +652,7 @@ static int CmdHFMFPWrbl(const char *cmd) { // sector number from 0 for (uint8_t sector = startSector; sector <= endSector; sector++) { // 0-keyA 1-keyB - for(uint8_t keyAB = startKeyAB; keyAB <= endKeyAB; keyAB++) { + for (uint8_t keyAB = startKeyAB; keyAB <= endKeyAB; keyAB++) { // main cycle with key check for (int i = 0; i < keyListLen; i++) { if (i % 10 == 0) { @@ -668,25 +668,25 @@ static int CmdHFMFPWrbl(const char *cmd) { uint16_t uKeyNum = 0x4000 + sector * 2 + keyAB; keyn[0] = uKeyNum >> 8; keyn[1] = uKeyNum & 0xff; - + for (int retry = 0; retry < 4; retry++) { res = MifareAuth4(NULL, keyn, keyList[i], selectCard, true, false, false, true); if (res != 2) break; - + if (verbose) PrintAndLogEx(WARNING, "retried[%d]...", retry); else printf("R"); - + DropField(); selectCard = true; msleep(100); } - + if (verbose) PrintAndLogEx(WARNING, "sector %02d key %d [%s] res: %d", sector, keyAB, sprint_hex_inrow(keyList[i], 16), res); - + // key for [sector,keyAB] found if (res == 0) { if (verbose) @@ -700,7 +700,7 @@ static int CmdHFMFPWrbl(const char *cmd) { msleep(50); break; } - + // 5 - auth error (rnd not equal) if (res != 5) { if (verbose) @@ -710,12 +710,12 @@ static int CmdHFMFPWrbl(const char *cmd) { DropField(); return PM3_ECARDEXCHANGE; } - + selectCard = false; } } } - + DropField(); return PM3_SUCCESS; } @@ -740,7 +740,7 @@ static int CmdHFMFPChk(const char *cmd) { uint8_t keyList[MAX_KEYS_LIST_LEN][AES_KEY_LEN] = {{0}}; size_t keyListLen = 0; uint8_t foundKeys[2][64][AES_KEY_LEN + 1] = {{{0}}}; - + CLIParserInit("hf mfp chk", "Checks keys with Mifare Plus card.", "Usage:\n" @@ -771,8 +771,8 @@ static int CmdHFMFPChk(const char *cmd) { bool keyB = arg_get_lit(2); uint8_t startSector = arg_get_int_def(3, 0); uint8_t endSector = arg_get_int_def(4, 0); - - uint8_t vkey[16] = {0}; + + uint8_t vkey[16] = {0}; int vkeylen = 0; CLIGetHexWithReturn(5, vkey, &vkeylen); if (vkeylen > 0) { @@ -785,7 +785,7 @@ static int CmdHFMFPChk(const char *cmd) { return PM3_EINVARG; } } - + uint8_t dict_filename[FILE_PATH_SIZE + 2] = {0}; int dict_filenamelen = 0; if (CLIParamStrToBuf(arg_get_str(6), dict_filename, FILE_PATH_SIZE, &dict_filenamelen)) { @@ -793,7 +793,7 @@ static int CmdHFMFPChk(const char *cmd) { CLIParserFree(); return PM3_EINVARG; } - + bool pattern1b = arg_get_lit(7); bool pattern2b = arg_get_lit(8); @@ -808,7 +808,7 @@ static int CmdHFMFPChk(const char *cmd) { CLIParserFree(); return PM3_EINVARG; } - + uint32_t startPattern = 0x0000; uint8_t vpattern[2]; int vpatternlen = 0; @@ -824,7 +824,7 @@ static int CmdHFMFPChk(const char *cmd) { if (!pattern2b) PrintAndLogEx(WARNING, "Pattern entered, but search mode not is 2-byte search."); } - + uint8_t jsonname[250] = {0}; int jsonnamelen = 0; if (CLIParamStrToBuf(arg_get_str(10), jsonname, sizeof(jsonname), &jsonnamelen)) { @@ -833,9 +833,9 @@ static int CmdHFMFPChk(const char *cmd) { return PM3_EINVARG; } jsonname[jsonnamelen] = 0; - + bool verbose = arg_get_lit(11); - + CLIParserFree(); uint8_t startKeyAB = 0; @@ -844,22 +844,22 @@ static int CmdHFMFPChk(const char *cmd) { endKeyAB = 0; if (!keyA && keyB) startKeyAB = 1; - + if (endSector < startSector) endSector = startSector; - + // 1-byte pattern search mode if (pattern1b) { for (int i = 0; i < 0x100; i++) memset(keyList[i], i, 16); - + keyListLen = 0x100; } - + // 2-byte pattern search mode if (pattern2b) Fill2bPattern(keyList, &keyListLen, &startPattern); - + // dictionary mode size_t endFilePosition = 0; if (dict_filenamelen) { @@ -874,7 +874,7 @@ static int CmdHFMFPChk(const char *cmd) { for (int i = 0; i < g_mifare_plus_default_keys_len; i++) { if (hex_to_bytes(g_mifare_plus_default_keys[i], keyList[keyListLen], 16) != 16) break; - + keyListLen++; } } @@ -921,17 +921,17 @@ static int CmdHFMFPChk(const char *cmd) { PrintAndLogEx(INFO, "|------|--------------------------------|--------------------------------|"); printedHeader = true; } - PrintAndLogEx(INFO, "| %02d |%32s|%32s|", - sector, - (foundKeys[0][sector][0] == 0) ? "------ " : sprint_hex_inrow(&foundKeys[0][sector][1], AES_KEY_LEN), - (foundKeys[1][sector][0] == 0) ? "------ " : sprint_hex_inrow(&foundKeys[1][sector][1], AES_KEY_LEN)); + PrintAndLogEx(INFO, "| %02d |%32s|%32s|", + sector, + (foundKeys[0][sector][0] == 0) ? "------ " : sprint_hex_inrow(&foundKeys[0][sector][1], AES_KEY_LEN), + (foundKeys[1][sector][0] == 0) ? "------ " : sprint_hex_inrow(&foundKeys[1][sector][1], AES_KEY_LEN)); } } if (!printedHeader) PrintAndLogEx(INFO, "No keys found("); else PrintAndLogEx(INFO, "'------'--------------------------------'--------------------------------'\n"); - + // save keys to json if ((jsonnamelen > 0) && printedHeader) { // Mifare Plus info @@ -955,13 +955,13 @@ static int CmdHFMFPChk(const char *cmd) { atslen = card.ats_len; data[13] = atslen; memcpy(&data[14], card.ats, atslen); - } - + } + // length: UID(10b)+SAK(1b)+ATQA(2b)+ATSlen(1b)+ATS(atslen)+foundKeys[2][64][AES_KEY_LEN + 1] memcpy(&data[14 + atslen], foundKeys, 2 * 64 * (AES_KEY_LEN + 1)); saveFileJSON((char *)jsonname, jsfMfPlusKeys, data, 64); } - + return PM3_SUCCESS; } diff --git a/client/fileutils.c b/client/fileutils.c index d82c00a48..7c10fe50c 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -751,17 +751,17 @@ int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, u if (keylen != 4 && keylen != 6 && keylen != 8 && keylen != 16) { keylen = 6; } - + return loadFileDICTIONARYEx(preferredName, data, 0, datalen, keylen, keycnt, 0, NULL, true); } -int loadFileDICTIONARYEx(const char *preferredName, void *data, size_t maxdatalen, size_t *datalen, uint8_t keylen, uint16_t *keycnt, - size_t startFilePosition, size_t *endFilePosition, bool verbose) { +int loadFileDICTIONARYEx(const char *preferredName, void *data, size_t maxdatalen, size_t *datalen, uint8_t keylen, uint16_t *keycnt, + size_t startFilePosition, size_t *endFilePosition, bool verbose) { if (endFilePosition) *endFilePosition = 0; if (data == NULL) return PM3_EINVARG; uint16_t vkeycnt = 0; - + char *path; if (searchFile(&path, DICTIONARIES_SUBDIR, preferredName, ".dic", false) != PM3_SUCCESS) return PM3_EFILE; @@ -780,10 +780,10 @@ int loadFileDICTIONARYEx(const char *preferredName, void *data, size_t maxdatale retval = PM3_EFILE; goto out; } - + if (startFilePosition) fseek(f, startFilePosition, SEEK_SET); - + // read file while (!feof(f)) { size_t filepos = ftell(f); @@ -791,8 +791,8 @@ int loadFileDICTIONARYEx(const char *preferredName, void *data, size_t maxdatale if (endFilePosition) *endFilePosition = 0; break; - } - + } + // add null terminator line[keylen] = 0; @@ -814,10 +814,10 @@ int loadFileDICTIONARYEx(const char *preferredName, void *data, size_t maxdatale *endFilePosition = filepos; break; } - + if (hex_to_bytes(line, data + counter, keylen >> 1) != (keylen >> 1)) continue; - + vkeycnt++; memset(line, 0, sizeof(line)); counter += (keylen >> 1); diff --git a/client/fileutils.h b/client/fileutils.h index c9de3b4fb..523e957a7 100644 --- a/client/fileutils.h +++ b/client/fileutils.h @@ -199,8 +199,8 @@ int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, u * @param verbose print messages if true * @return 0 for ok, 1 for failz */ -int loadFileDICTIONARYEx(const char *preferredName, void *data, size_t maxdatalen, size_t *datalen, uint8_t keylen, uint16_t *keycnt, - size_t startFilePosition, size_t *endFilePosition, bool verbose); +int loadFileDICTIONARYEx(const char *preferredName, void *data, size_t maxdatalen, size_t *datalen, uint8_t keylen, uint16_t *keycnt, + size_t startFilePosition, size_t *endFilePosition, bool verbose); /** * @brief Utility function to load data safely from a DICTIONARY textfile. This method takes a preferred name. diff --git a/client/mifare/mifare4.c b/client/mifare/mifare4.c index 7eecbe751..8bf0788b4 100644 --- a/client/mifare/mifare4.c +++ b/client/mifare/mifare4.c @@ -175,7 +175,7 @@ int MifareAuth4(mf4Session *session, uint8_t *keyn, uint8_t *key, bool activateF uint8_t RndA[17] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00}; uint8_t RndB[17] = {0}; - if (silentMode) + if (silentMode) verbose = false; if (session) From 9782f447eb5803b99679630a6feb0a8b3433937a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 3 Dec 2019 14:52:17 +0100 Subject: [PATCH 1200/1854] style --- client/mifare/mifaredefault.c | 4 ++-- client/mifare/mifaredefault.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/client/mifare/mifaredefault.c b/client/mifare/mifaredefault.c index 9d3b77d4f..b41859f09 100644 --- a/client/mifare/mifaredefault.c +++ b/client/mifare/mifaredefault.c @@ -11,7 +11,7 @@ #include "mifaredefault.h" #include "commonutil.h" // ARRAYLEN -const char* g_mifare_plus_default_keys[] = { +const char *g_mifare_plus_default_keys[] = { "ffffffffffffffffffffffffffffffff", // default key "00000000000000000000000000000000", "a0a1a2a3a4a5a6a7a0a1a2a3a4a5a6a7", // MAD key @@ -36,4 +36,4 @@ const char* g_mifare_plus_default_keys[] = { "00010203040506070809101112131415", "01020304050607080910111213141516" }; -size_t g_mifare_plus_default_keys_len = ARRAYLEN(g_mifare_plus_default_keys); \ No newline at end of file +size_t g_mifare_plus_default_keys_len = ARRAYLEN(g_mifare_plus_default_keys); diff --git a/client/mifare/mifaredefault.h b/client/mifare/mifaredefault.h index fdccfe22b..cdc103676 100644 --- a/client/mifare/mifaredefault.h +++ b/client/mifare/mifaredefault.h @@ -44,7 +44,7 @@ static const uint8_t g_mifare_ndef_key[] = {0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7}; static const uint8_t g_mifarep_mad_key[] = {0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7}; static const uint8_t g_mifarep_ndef_key[] = {0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7}; -extern const char* g_mifare_plus_default_keys[]; +extern const char *g_mifare_plus_default_keys[]; extern size_t g_mifare_plus_default_keys_len; #endif From 3d4a63f46a7512a48c8622871e28f0435e0e2340 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 3 Dec 2019 14:52:34 +0100 Subject: [PATCH 1201/1854] style --- client/util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/util.c b/client/util.c index 887f52857..856091231 100644 --- a/client/util.c +++ b/client/util.c @@ -431,7 +431,7 @@ int hex_to_bytes(const char *hexValue, uint8_t *bytesValue, size_t maxBytesValue //error when not completed hex bytes return -3; - return bytesValueLen; + return bytesValueLen; } // takes a number (uint64_t) and creates a binarray in dest. From 3d366d50ef225fff6e5dc61f0decf718b2a0a5f7 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 3 Dec 2019 14:53:08 +0100 Subject: [PATCH 1202/1854] style --- client/luascripts/read_pwd_mem.lua | 4 ++-- client/luascripts/read_pwd_mem_spiffs.lua | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/client/luascripts/read_pwd_mem.lua b/client/luascripts/read_pwd_mem.lua index 8456fd51f..ffc00a998 100644 --- a/client/luascripts/read_pwd_mem.lua +++ b/client/luascripts/read_pwd_mem.lua @@ -26,10 +26,10 @@ example = -- This will print the stored Mifare dictionary keys script run read_pwd_mem -m - + -- This will print the stored t55xx dictionary passwords script run read_pwd_mem -t - + -- This will print the stored iClass dictionary keys script run read_pwd_mem -i ]] diff --git a/client/luascripts/read_pwd_mem_spiffs.lua b/client/luascripts/read_pwd_mem_spiffs.lua index 33afa0fe9..89ef64e6d 100644 --- a/client/luascripts/read_pwd_mem_spiffs.lua +++ b/client/luascripts/read_pwd_mem_spiffs.lua @@ -16,7 +16,7 @@ example = -- This will read the other.log file in SPIFFS and print the stored passwords script run read_pwd_mem_spiffs -f other.log - + -- This will delete the hf_bog.log file from SPIFFS script run read_pwd_mem_spiffs -r ]] @@ -68,7 +68,7 @@ local function main(args) -- offset if o == 'f' then filename = a end - + -- remove if o == 'r' then removeflag = true end @@ -79,7 +79,7 @@ local function main(args) core.console("mem spiffs remove " ..filename) return end - + data, length, err = core.GetFromFlashMemSpiffs(filename) if data == nil then return oops('Problem while reading file from SPIFFS') end From 5773919f580adfa2090107f276d5b06082210bbd Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 6 Dec 2019 08:51:24 +0100 Subject: [PATCH 1203/1854] textual --- client/proxmark3.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/client/proxmark3.c b/client/proxmark3.c index bb291ee6c..7cefc6638 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -33,24 +33,24 @@ static void showBanner(void) { PrintAndLogEx(NORMAL, "\n"); #if defined(__linux__) || (__APPLE__) || (_WIN32) - PrintAndLogEx(NORMAL, _BLUE_("██████╗ ███╗ ███╗ ████╗ ") " ...iceman fork"); - PrintAndLogEx(NORMAL, _BLUE_("██╔══██╗████╗ ████║ ══█║") " ...dedicated to " _BLUE_("RDV40")); - PrintAndLogEx(NORMAL, _BLUE_("██████╔╝██╔████╔██║ ████╔╝")); - PrintAndLogEx(NORMAL, _BLUE_("██╔═══╝ ██║╚██╔╝██║ ══█║") " iceman@icesql.net"); - PrintAndLogEx(NORMAL, _BLUE_("██║ ██║ ╚═╝ ██║ ████╔╝") " https://github.com/rfidresearchgroup/proxmark3/"); - PrintAndLogEx(NORMAL, _BLUE_("╚═╝ ╚═╝ ╚═╝ ╚═══╝ ") "pre-release v4.0"); + PrintAndLogEx(NORMAL, " " _BLUE_("██████╗ ███╗ ███╗ ████╗ ") " ...iceman repo"); + PrintAndLogEx(NORMAL, " " _BLUE_("██╔══██╗████╗ ████║ ══█║")); + PrintAndLogEx(NORMAL, " " _BLUE_("██████╔╝██╔████╔██║ ████╔╝")); + PrintAndLogEx(NORMAL, " " _BLUE_("██╔═══╝ ██║╚██╔╝██║ ══█║") " iceman@icesql.net"); + PrintAndLogEx(NORMAL, " " _BLUE_("██║ ██║ ╚═╝ ██║ ████╔╝") " https://github.com/rfidresearchgroup/proxmark3/"); + PrintAndLogEx(NORMAL, " " _BLUE_("╚═╝ ╚═╝ ╚═╝ ╚═══╝ ") "pre-release v4.0"); #else - PrintAndLogEx(NORMAL, "======. ===. ===. ====. ...iceman fork"); - PrintAndLogEx(NORMAL, "==...==.====. ====. ..=. ...dedicated to RDV40"); - PrintAndLogEx(NORMAL, "======..==.====.==. ====.."); - PrintAndLogEx(NORMAL, "==..... ==..==..==. ..=. iceman@icesql.net"); - PrintAndLogEx(NORMAL, "==. ==. ... ==. ====.. https://github.com/rfidresearchgroup/proxmark3/"); - PrintAndLogEx(NORMAL, "... ... ... ..... pre-release v4.0"); + PrintAndLogEx(NORMAL, " ======. ===. ===. ====. ...iceman repo"); + PrintAndLogEx(NORMAL, " ==...==.====. ====. ..=."); + PrintAndLogEx(NORMAL, " ======..==.====.==. ====.."); + PrintAndLogEx(NORMAL, " ==..... ==..==..==. ..=. iceman@icesql.net"); + PrintAndLogEx(NORMAL, " ==. ==. ... ==. ====.. https://github.com/rfidresearchgroup/proxmark3/"); + PrintAndLogEx(NORMAL, " ... ... ... ..... pre-release v4.0"); #endif - PrintAndLogEx(NORMAL, "\nSupport iceman on patreon - https://www.patreon.com/iceman1001/"); - PrintAndLogEx(NORMAL, " on paypal - https://www.paypal.me/iceman1001"); +// PrintAndLogEx(NORMAL, "\nSupport iceman on patreon - https://www.patreon.com/iceman1001/"); +// PrintAndLogEx(NORMAL, " on paypal - https://www.paypal.me/iceman1001"); // printf("\nMonero: 43mNJLpgBVaTvyZmX9ajcohpvVkaRy1kbZPm8tqAb7itZgfuYecgkRF36rXrKFUkwEGeZedPsASRxgv4HPBHvJwyJdyvQuP"); - PrintAndLogEx(NORMAL, "\n"); + PrintAndLogEx(NORMAL, ""); fflush(stdout); g_printAndLog = PRINTANDLOG_PRINT | PRINTANDLOG_LOG; @@ -807,7 +807,7 @@ int main(int argc, char *argv[]) { exit(EXIT_FAILURE); if (!session.pm3_present) - PrintAndLogEx(INFO, "Running in " _YELLOW_("OFFLINE") "mode. Check \"%s -h\" if it's not what you want.\n", exec_name); + PrintAndLogEx(INFO, "Running in " _YELLOW_("OFFLINE") "mode. Check " _YELLOW_("\"%s -h\"") " if it's not what you want.\n", exec_name); #ifdef HAVE_GUI From 326e6aa9f2b38bd818f39c2bc45be9443393f60f Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 6 Dec 2019 17:04:22 +0200 Subject: [PATCH 1204/1854] added hf mf cwipe --- client/cmdhfmf.c | 51 ++++++++++++++++++++++++++++++++++++++ client/mifare/mifarehost.c | 44 ++++++++++++++++++++++++++++++++ client/mifare/mifarehost.h | 1 + 3 files changed, 96 insertions(+) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index ad6fe31b2..680b9da19 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -3665,6 +3665,56 @@ static int CmdHF14AMfCSetUID(const char *Cmd) { return PM3_SUCCESS; } +static int CmdHF14AMfCWipe(const char *cmd) { + uint8_t uid[8] = {0x00}; + int uidLen = 0; + uint8_t atqa[2] = {0x00}; + int atqaLen = 0; + uint8_t sak[1] = {0x00}; + int sakLen = 0; + + CLIParserInit("hf mf cwipe", + "Wipe Gen1 magic cheneese card. Set UID/ATQA/SAK/Data/Keys/Access to default values.", + "Usage:\n\thf mf cwipe -> wipe card.\n" + "\thf mfp mf cwipe -u 09080706 -a 0004 -s 18 -> set UID, ATQA and SAK and wipe card."); + + void *argtable[] = { + arg_param_begin, + arg_str0("uU", "uid", "", "UID for card"), + arg_str0("aA", "atqa", "", "ATQA for card"), + arg_str0("sS", "sak", "", "SAK for card"), + arg_param_end + }; + CLIExecWithReturn(cmd, argtable, true); + + CLIGetHexWithReturn(1, uid, &uidLen); + CLIGetHexWithReturn(2, atqa, &atqaLen); + CLIGetHexWithReturn(3, sak, &sakLen); + CLIParserFree(); + + if (uidLen && uidLen != 4) { + PrintAndLogEx(ERR, "UID length must be 4 bytes instead of: %d", uidLen); + return PM3_EINVARG; + } + if (atqaLen && atqaLen != 2) { + PrintAndLogEx(ERR, "UID length must be 2 bytes instead of: %d", atqaLen); + return PM3_EINVARG; + } + if (sakLen && sakLen != 1) { + PrintAndLogEx(ERR, "UID length must be 1 byte instead of: %d", sakLen); + return PM3_EINVARG; + } + + int res = mfCWipe((uidLen)? uid : NULL, (atqaLen) ? atqa : NULL, (sakLen) ? sak : NULL); + if (res) { + PrintAndLogEx(ERR, "Can't wipe card. error=%d", res); + return PM3_ESOFT; + } + + PrintAndLogEx(SUCCESS, "Card wiped successfully"); + return PM3_SUCCESS; +} + static int CmdHF14AMfCSetBlk(const char *Cmd) { uint8_t block[16] = {0x00}; uint8_t blockNo = 0; @@ -4446,6 +4496,7 @@ static command_t CommandTable[] = { {"ekeyprn", CmdHF14AMfEKeyPrn, IfPm3Iso14443a, "Print keys from simulator memory"}, {"-----------", CmdHelp, IfPm3Iso14443a, ""}, {"csetuid", CmdHF14AMfCSetUID, IfPm3Iso14443a, "Set UID (magic chinese card)"}, + {"cwipe", CmdHF14AMfCWipe, IfPm3Iso14443a, "Wipe card to default UID/Sectors/Keys"}, {"csetblk", CmdHF14AMfCSetBlk, IfPm3Iso14443a, "Write block (magic chinese card)"}, {"cgetblk", CmdHF14AMfCGetBlk, IfPm3Iso14443a, "Read block (magic chinese card)"}, {"cgetsc", CmdHF14AMfCGetSc, IfPm3Iso14443a, "Read sector (magic chinese card)"}, diff --git a/client/mifare/mifarehost.c b/client/mifare/mifarehost.c index 39d2d6001..151ac72cf 100644 --- a/client/mifare/mifarehost.c +++ b/client/mifare/mifarehost.c @@ -615,6 +615,50 @@ int mfCSetUID(uint8_t *uid, uint8_t *atqa, uint8_t *sak, uint8_t *oldUID, uint8_ return mfCSetBlock(0, block0, oldUID, params); } +int mfCWipe(uint8_t *uid, uint8_t *atqa, uint8_t *sak) { + uint8_t block0[16] = {0x01, 0x02, 0x03, 0x04, 0x04, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBE, 0xAF}; + uint8_t blockD[16] = {0x00}; + uint8_t blockK[16] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x08, 0x77, 0x8F, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + uint8_t params = MAGIC_SINGLE; + + if (uid != NULL) { + memcpy(block0, uid, 4); + block0[4] = block0[0] ^ block0[1] ^ block0[2] ^ block0[3]; + } + if (sak != NULL) + block0[5] = sak[0]; + + if (atqa != NULL) { + block0[6] = atqa[1]; + block0[7] = atqa[0]; + } + int res; + for (int blockNo = 0; blockNo < 4 * 16; blockNo++) { + for (int retry = 0; retry < 3; retry++) { + if (blockNo == 0) { + res = mfCSetBlock(blockNo, block0, NULL, params); + } else { + if (mfIsSectorTrailer(blockNo)) + res = mfCSetBlock(blockNo, blockK, NULL, params); + else + res = mfCSetBlock(blockNo, blockD, NULL, params); + } + + if (res == PM3_SUCCESS) + break; + PrintAndLogEx(WARNING, "Retry block[%d]...", blockNo); + } + + if (res) { + PrintAndLogEx(ERR, "Error setting block[%d]: %d", blockNo, res); + return res; + } + } + DropField(); + + return PM3_SUCCESS; +} + int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, uint8_t params) { clearCommandBuffer(); diff --git a/client/mifare/mifarehost.h b/client/mifare/mifarehost.h index 11bd3f29c..50ed9d8e2 100644 --- a/client/mifare/mifarehost.h +++ b/client/mifare/mifarehost.h @@ -73,6 +73,7 @@ int mfEmlSetMem(uint8_t *data, int blockNum, int blocksCount); int mfEmlSetMem_xt(uint8_t *data, int blockNum, int blocksCount, int blockBtWidth); int mfCSetUID(uint8_t *uid, uint8_t *atqa, uint8_t *sak, uint8_t *oldUID, uint8_t wipecard); +int mfCWipe(uint8_t *uid, uint8_t *atqa, uint8_t *sak); int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, uint8_t params); int mfCGetBlock(uint8_t blockNo, uint8_t *data, uint8_t params); From 45926261dbbeec4ed28fce9adeb28b803a8255b9 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 6 Dec 2019 17:12:29 +0200 Subject: [PATCH 1205/1854] style --- client/cmdhfmf.c | 4 ++-- client/mifare/mifarehost.c | 14 +++++++------- tools/pm3_mf7b_wipe.py | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 680b9da19..2ace2d214 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -3691,7 +3691,7 @@ static int CmdHF14AMfCWipe(const char *cmd) { CLIGetHexWithReturn(2, atqa, &atqaLen); CLIGetHexWithReturn(3, sak, &sakLen); CLIParserFree(); - + if (uidLen && uidLen != 4) { PrintAndLogEx(ERR, "UID length must be 4 bytes instead of: %d", uidLen); return PM3_EINVARG; @@ -3705,7 +3705,7 @@ static int CmdHF14AMfCWipe(const char *cmd) { return PM3_EINVARG; } - int res = mfCWipe((uidLen)? uid : NULL, (atqaLen) ? atqa : NULL, (sakLen) ? sak : NULL); + int res = mfCWipe((uidLen) ? uid : NULL, (atqaLen) ? atqa : NULL, (sakLen) ? sak : NULL); if (res) { PrintAndLogEx(ERR, "Can't wipe card. error=%d", res); return PM3_ESOFT; diff --git a/client/mifare/mifarehost.c b/client/mifare/mifarehost.c index 151ac72cf..e9baa7ee7 100644 --- a/client/mifare/mifarehost.c +++ b/client/mifare/mifarehost.c @@ -616,9 +616,9 @@ int mfCSetUID(uint8_t *uid, uint8_t *atqa, uint8_t *sak, uint8_t *oldUID, uint8_ } int mfCWipe(uint8_t *uid, uint8_t *atqa, uint8_t *sak) { - uint8_t block0[16] = {0x01, 0x02, 0x03, 0x04, 0x04, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBE, 0xAF}; - uint8_t blockD[16] = {0x00}; - uint8_t blockK[16] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x08, 0x77, 0x8F, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + uint8_t block0[16] = {0x01, 0x02, 0x03, 0x04, 0x04, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBE, 0xAF}; + uint8_t blockD[16] = {0x00}; + uint8_t blockK[16] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x08, 0x77, 0x8F, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; uint8_t params = MAGIC_SINGLE; if (uid != NULL) { @@ -632,7 +632,7 @@ int mfCWipe(uint8_t *uid, uint8_t *atqa, uint8_t *sak) { block0[6] = atqa[1]; block0[7] = atqa[0]; } - int res; + int res; for (int blockNo = 0; blockNo < 4 * 16; blockNo++) { for (int retry = 0; retry < 3; retry++) { if (blockNo == 0) { @@ -643,19 +643,19 @@ int mfCWipe(uint8_t *uid, uint8_t *atqa, uint8_t *sak) { else res = mfCSetBlock(blockNo, blockD, NULL, params); } - + if (res == PM3_SUCCESS) break; PrintAndLogEx(WARNING, "Retry block[%d]...", blockNo); } - + if (res) { PrintAndLogEx(ERR, "Error setting block[%d]: %d", blockNo, res); return res; } } DropField(); - + return PM3_SUCCESS; } diff --git a/tools/pm3_mf7b_wipe.py b/tools/pm3_mf7b_wipe.py index f4c58ce01..9f7b29c6b 100644 --- a/tools/pm3_mf7b_wipe.py +++ b/tools/pm3_mf7b_wipe.py @@ -71,7 +71,7 @@ # # Thats it! Your S50 7byte UID card is wiped back. Now you can return back to Step 1 of this manual. # -# +# From 1d1700db8dce594231e133edf642f3f0dd291e11 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 6 Dec 2019 17:14:50 +0200 Subject: [PATCH 1206/1854] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 296c892dc..e1f3cf2c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Added `hf mf cwipe` magic chinese card (gen1a) wipe to default state (@merlokk) - Added 'pm3_mf7b_wipe.py' python script. Wipes magic S70 7B Gen2 card. (@vulnersCom) - Added `hf mfp chk` Mifare plus command for check keys from public keys list, from dictionary or 1 and 2-byte bruteforce (@merlokk) - Change `hf 15` - some refactoring (@grspy) From 8425de08fdf965862bb5e9fa528e8e70c0ee6606 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 6 Dec 2019 17:21:45 +0200 Subject: [PATCH 1207/1854] textual --- client/cmdhfmf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 2ace2d214..dc42cae62 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -3674,7 +3674,7 @@ static int CmdHF14AMfCWipe(const char *cmd) { int sakLen = 0; CLIParserInit("hf mf cwipe", - "Wipe Gen1 magic cheneese card. Set UID/ATQA/SAK/Data/Keys/Access to default values.", + "Wipe gen1 magic chinese card. Set UID/ATQA/SAK/Data/Keys/Access to default values.", "Usage:\n\thf mf cwipe -> wipe card.\n" "\thf mfp mf cwipe -u 09080706 -a 0004 -s 18 -> set UID, ATQA and SAK and wipe card."); From b748a7989ea7587ab885b92f74ccb2e08008543c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 8 Dec 2019 18:49:26 +0100 Subject: [PATCH 1208/1854] nexwatch textual, wrong endianess --- client/cmddata.c | 8 ++++---- client/cmdlfnexwatch.c | 5 +++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/client/cmddata.c b/client/cmddata.c index d13eee46d..cb78642b2 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -406,7 +406,7 @@ static int CmdSetDebugMode(const char *Cmd) { void printDemodBuff(void) { int len = DemodBufferLen; if (len < 1) { - PrintAndLogEx(NORMAL, "(printDemodBuff) no bits found in demod buffer"); + PrintAndLogEx(INFO, "(printDemodBuff) no bits found in demod buffer"); return; } if (len > 512) len = 512; @@ -458,7 +458,7 @@ int CmdPrintDemodBuff(const char *Cmd) { if (errors) return usage_data_printdemodbuf(); if (DemodBufferLen == 0) { - PrintAndLogEx(NORMAL, "Demodbuffer is empty"); + PrintAndLogEx(WARNING, "Demodbuffer is empty"); return PM3_ESOFT; } if (lstrip) { @@ -491,9 +491,9 @@ int CmdPrintDemodBuff(const char *Cmd) { if (numBits == 0) { return PM3_ESOFT; } - PrintAndLogEx(NORMAL, "DemodBuffer: %s", hex); + PrintAndLogEx(SUCCESS, "DemodBuffer: %s", hex); } else { - PrintAndLogEx(NORMAL, "DemodBuffer:\n%s", sprint_bin_break(DemodBuffer + offset, length, 32)); + PrintAndLogEx(SUCCESS, "DemodBuffer:\n%s", sprint_bin_break(DemodBuffer + offset, length, 32)); } return PM3_SUCCESS; } diff --git a/client/cmdlfnexwatch.c b/client/cmdlfnexwatch.c index 1a204ed41..717bf2587 100644 --- a/client/cmdlfnexwatch.c +++ b/client/cmdlfnexwatch.c @@ -9,6 +9,7 @@ //----------------------------------------------------------------------------- #include "cmdlfnexwatch.h" +#include // PRIu #include // tolower #include "commonutil.h" // ARRAYLEN @@ -80,9 +81,9 @@ static int CmdNexWatchDemod(const char *Cmd) { //checksum check (TBD) //output - PrintAndLogEx(NORMAL, "NexWatch ID: %d", ID); + PrintAndLogEx(SUCCESS, "NexWatch ID: " _YELLOW_("%"PRIu32) , ID); if (invert) { - PrintAndLogEx(NORMAL, "Had to Invert - probably NexKey"); + PrintAndLogEx(INFO, "Had to Invert - probably NexKey"); for (size_t i = 0; i < size; i++) DemodBuffer[i] ^= 1; } From 3dd380e9850219b4485d2c0e988edcdd84e0f688 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 10 Dec 2019 18:13:21 +0100 Subject: [PATCH 1209/1854] newline --- client/cmdhf14a.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index 73b19ae0f..4aac73855 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -1272,6 +1272,8 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { return select_status; } + PrintAndLogEx(NORMAL, ""); + if (select_status == 3) { PrintAndLogEx(INFO, "Card doesn't support standard iso14443-3 anticollision"); PrintAndLogEx(SUCCESS, "ATQA : %02x %02x", card.atqa[1], card.atqa[0]); From a66944f7e78c38fd2b939f47d5a44b81f929c050 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 10 Dec 2019 18:15:51 +0100 Subject: [PATCH 1210/1854] newline --- client/cmdhf14b.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/client/cmdhf14b.c b/client/cmdhf14b.c index d02d563f4..c57055e4b 100644 --- a/client/cmdhf14b.c +++ b/client/cmdhf14b.c @@ -528,9 +528,10 @@ static bool HF14B_Std_Info(bool verbose) { switch (status) { case 0: - PrintAndLogEx(NORMAL, " UID : %s", sprint_hex(card.uid, card.uidlen)); - PrintAndLogEx(NORMAL, " ATQB : %s", sprint_hex(card.atqb, sizeof(card.atqb))); - PrintAndLogEx(NORMAL, " CHIPID : %02X", card.chipid); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(SUCCESS, " UID : %s", sprint_hex(card.uid, card.uidlen)); + PrintAndLogEx(SUCCESS, " ATQB : %s", sprint_hex(card.atqb, sizeof(card.atqb))); + PrintAndLogEx(SUCCESS, " CHIPID : %02X", card.chipid); print_atqb_resp(card.atqb, card.cid); isSuccess = true; break; @@ -662,9 +663,10 @@ static bool HF14B_Std_Reader(bool verbose) { switch (status) { case 0: - PrintAndLogEx(NORMAL, " UID : %s", sprint_hex(card.uid, card.uidlen)); - PrintAndLogEx(NORMAL, " ATQB : %s", sprint_hex(card.atqb, sizeof(card.atqb))); - PrintAndLogEx(NORMAL, " CHIPID : %02X", card.chipid); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(SUCCESS, " UID : %s", sprint_hex(card.uid, card.uidlen)); + PrintAndLogEx(SUCCESS, " ATQB : %s", sprint_hex(card.atqb, sizeof(card.atqb))); + PrintAndLogEx(SUCCESS, " CHIPID : %02X", card.chipid); print_atqb_resp(card.atqb, card.cid); isSuccess = true; break; From 24d3bf5d9dff8b40f91c2e42a16625229921a574 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 10 Dec 2019 18:26:09 +0100 Subject: [PATCH 1211/1854] textual --- client/cmdhflegic.c | 46 ++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/client/cmdhflegic.c b/client/cmdhflegic.c index 4a72397e3..022857584 100644 --- a/client/cmdhflegic.c +++ b/client/cmdhflegic.c @@ -210,7 +210,7 @@ static int CmdLegicInfo(const char *Cmd) { crc = data[4]; uint32_t calc_crc = CRC8Legic(data, 4); - PrintAndLogEx(NORMAL, _YELLOW_("CDF: System Area")); + PrintAndLogEx(SUCCESS, _YELLOW_("CDF: System Area")); PrintAndLogEx(NORMAL, "------------------------------------------------------"); PrintAndLogEx(NORMAL, "MCD: %02x, MSN: %02x %02x %02x, MCC: %02x %s", data[0], @@ -229,7 +229,7 @@ static int CmdLegicInfo(const char *Cmd) { // New unwritten media? if (dcf == 0xFFFF) { - PrintAndLogEx(NORMAL, "DCF: %d (%02x %02x), Token Type=NM (New Media)", + PrintAndLogEx(SUCCESS, "DCF: %d (%02x %02x), Token Type=NM (New Media)", dcf, data[5], data[6] @@ -262,7 +262,7 @@ static int CmdLegicInfo(const char *Cmd) { stamp_len = 0xfc - data[6]; } - PrintAndLogEx(NORMAL, "DCF: %d (%02x %02x), Token Type=" _YELLOW_("%s") " (OLE=%01u), OL=%02u, FL=%02u", + PrintAndLogEx(SUCCESS, "DCF: %d (%02x %02x), Token Type=" _YELLOW_("%s") " (OLE=%01u), OL=%02u, FL=%02u", dcf, data[5], data[6], @@ -281,7 +281,7 @@ static int CmdLegicInfo(const char *Cmd) { strncpy(token_type, "IM", sizeof(token_type) - 1); } - PrintAndLogEx(NORMAL, "DCF: %d (%02x %02x), Token Type = %s (OLE = %01u)", + PrintAndLogEx(SUCCESS, "DCF: %d (%02x %02x), Token Type = %s (OLE = %01u)", dcf, data[5], data[6], @@ -294,7 +294,7 @@ static int CmdLegicInfo(const char *Cmd) { if (dcf != 0xFFFF) { if (bIsSegmented) { - PrintAndLogEx(NORMAL, "WRP = %02u, WRC = %01u, RD = %01u, SSC = %02X", + PrintAndLogEx(SUCCESS, "WRP = %02u, WRC = %01u, RD = %01u, SSC = %02X", data[7] & 0x0f, (data[7] & 0x70) >> 4, (data[7] & 0x80) >> 7, @@ -305,11 +305,11 @@ static int CmdLegicInfo(const char *Cmd) { // Header area is only available on IM-S cards, on master tokens this data is the master token data itself if (bIsSegmented || dcf > 60000) { if (dcf > 60000) { - PrintAndLogEx(NORMAL, "Master token data"); - PrintAndLogEx(NORMAL, "%s", sprint_hex(data + 8, 14)); + PrintAndLogEx(SUCCESS, "Master token data"); + PrintAndLogEx(SUCCESS, "%s", sprint_hex(data + 8, 14)); } else { - PrintAndLogEx(NORMAL, "Remaining Header Area"); - PrintAndLogEx(NORMAL, "%s", sprint_hex(data + 9, 13)); + PrintAndLogEx(SUCCESS, "Remaining Header Area"); + PrintAndLogEx(SUCCESS, "%s", sprint_hex(data + 9, 13)); } } } @@ -323,7 +323,7 @@ static int CmdLegicInfo(const char *Cmd) { if (dcf > 60000) goto out; - PrintAndLogEx(NORMAL, _YELLOW_("\nADF: User Area")); + PrintAndLogEx(SUCCESS, _YELLOW_("\nADF: User Area")); PrintAndLogEx(NORMAL, "------------------------------------------------------"); if (bIsSegmented) { @@ -356,20 +356,20 @@ static int CmdLegicInfo(const char *Cmd) { segCalcCRC = CRC8Legic(segCrcBytes, 8); segCRC = data[i + 4] ^ crc; - PrintAndLogEx(NORMAL, "Segment | %02u ", segmentNum); - PrintAndLogEx(NORMAL, "raw header | 0x%02X 0x%02X 0x%02X 0x%02X", + PrintAndLogEx(SUCCESS, "Segment | %02u ", segmentNum); + PrintAndLogEx(SUCCESS, "raw header | 0x%02X 0x%02X 0x%02X 0x%02X", data[i] ^ crc, data[i + 1] ^ crc, data[i + 2] ^ crc, data[i + 3] ^ crc ); - PrintAndLogEx(NORMAL, "Segment len | %u, Flag: 0x%X (valid:%01u, last:%01u)", + PrintAndLogEx(SUCCESS, "Segment len | %u, Flag: 0x%X (valid:%01u, last:%01u)", segment_len, segment_flag, (segment_flag & 0x4) >> 2, (segment_flag & 0x8) >> 3 ); - PrintAndLogEx(NORMAL, " | WRP: %02u, WRC: %02u, RD: %01u, CRC: 0x%02X (%s)", + PrintAndLogEx(SUCCESS, " | WRP: %02u, WRC: %02u, RD: %01u, CRC: 0x%02X (%s)", wrp, wrc, ((data[i + 3] ^ crc) & 0x80) >> 7, @@ -380,7 +380,7 @@ static int CmdLegicInfo(const char *Cmd) { i += 5; if (hasWRC) { - PrintAndLogEx(NORMAL, "\nWRC protected area: (I %d | K %d| WRC %d)", i, k, wrc); + PrintAndLogEx(SUCCESS, "\nWRC protected area: (I %d | K %d| WRC %d)", i, k, wrc); PrintAndLogEx(NORMAL, "\nrow | data"); PrintAndLogEx(NORMAL, "-----+------------------------------------------------"); @@ -393,7 +393,7 @@ static int CmdLegicInfo(const char *Cmd) { } if (hasWRP) { - PrintAndLogEx(NORMAL, "Remaining write protected area: (I %d | K %d | WRC %d | WRP %d WRP_LEN %d)", i, k, wrc, wrp, wrp_len); + PrintAndLogEx(SUCCESS, "Remaining write protected area: (I %d | K %d | WRC %d | WRP %d WRP_LEN %d)", i, k, wrc, wrp, wrp_len); PrintAndLogEx(NORMAL, "\nrow | data"); PrintAndLogEx(NORMAL, "-----+------------------------------------------------"); @@ -406,7 +406,7 @@ static int CmdLegicInfo(const char *Cmd) { // does this one work? (Answer: Only if KGH/BGH is used with BCD encoded card number! So maybe this will show just garbage...) if (wrp_len == 8) { - PrintAndLogEx(NORMAL, "Card ID: " _YELLOW_("%2X%02X%02X"), + PrintAndLogEx(SUCCESS, "Card ID: " _YELLOW_("%2X%02X%02X"), data[i - 4] ^ crc, data[i - 3] ^ crc, data[i - 2] ^ crc @@ -414,7 +414,7 @@ static int CmdLegicInfo(const char *Cmd) { } } if (remain_seg_payload_len > 0) { - PrintAndLogEx(NORMAL, "Remaining segment payload: (I %d | K %d | Remain LEN %d)", i, k, remain_seg_payload_len); + PrintAndLogEx(SUCCESS, "Remaining segment payload: (I %d | K %d | Remain LEN %d)", i, k, remain_seg_payload_len); PrintAndLogEx(NORMAL, "\nrow | data"); PrintAndLogEx(NORMAL, "-----+------------------------------------------------"); @@ -444,14 +444,14 @@ static int CmdLegicInfo(const char *Cmd) { int wrp_len = (wrp - wrc); int remain_seg_payload_len = (card.cardsize - 22 - wrp); - PrintAndLogEx(NORMAL, "Unsegmented card - WRP: %02u, WRC: %02u, RD: %01u", + PrintAndLogEx(SUCCESS, "Unsegmented card - WRP: %02u, WRC: %02u, RD: %01u", wrp, wrc, (data[7] & 0x80) >> 7 ); if (hasWRC) { - PrintAndLogEx(NORMAL, "WRC protected area: (I %d | WRC %d)", i, wrc); + PrintAndLogEx(SUCCESS, "WRC protected area: (I %d | WRC %d)", i, wrc); PrintAndLogEx(NORMAL, "\nrow | data"); PrintAndLogEx(NORMAL, "-----+------------------------------------------------"); print_hex_break(data + i, wrc, 16); @@ -460,7 +460,7 @@ static int CmdLegicInfo(const char *Cmd) { } if (hasWRP) { - PrintAndLogEx(NORMAL, "Remaining write protected area: (I %d | WRC %d | WRP %d | WRP_LEN %d)", i, wrc, wrp, wrp_len); + PrintAndLogEx(SUCCESS, "Remaining write protected area: (I %d | WRC %d | WRP %d | WRP_LEN %d)", i, wrc, wrp, wrp_len); PrintAndLogEx(NORMAL, "\nrow | data"); PrintAndLogEx(NORMAL, "-----+------------------------------------------------"); print_hex_break(data + i, wrp_len, 16); @@ -470,7 +470,7 @@ static int CmdLegicInfo(const char *Cmd) { // Q: does this one work? // A: Only if KGH/BGH is used with BCD encoded card number. Maybe this will show just garbage if (wrp_len == 8) { - PrintAndLogEx(NORMAL, "Card ID: " _YELLOW_("%2X%02X%02X"), + PrintAndLogEx(SUCCESS, "Card ID: " _YELLOW_("%2X%02X%02X"), data[i - 4], data[i - 3], data[i - 2] @@ -479,7 +479,7 @@ static int CmdLegicInfo(const char *Cmd) { } if (remain_seg_payload_len > 0) { - PrintAndLogEx(NORMAL, "Remaining segment payload: (I %d | Remain LEN %d)", i, remain_seg_payload_len); + PrintAndLogEx(SUCCESS, "Remaining segment payload: (I %d | Remain LEN %d)", i, remain_seg_payload_len); PrintAndLogEx(NORMAL, "\nrow | data"); PrintAndLogEx(NORMAL, "-----+------------------------------------------------"); print_hex_break(data + i, remain_seg_payload_len, 16); From 9f47a0a8f493c2c9c7ee797ef96d1d9405da40a2 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 10 Dec 2019 18:26:22 +0100 Subject: [PATCH 1212/1854] textual --- client/cmdhftopaz.c | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/client/cmdhftopaz.c b/client/cmdhftopaz.c index ae404b22d..98de42b7b 100644 --- a/client/cmdhftopaz.c +++ b/client/cmdhftopaz.c @@ -220,14 +220,14 @@ static int topaz_print_CC(uint8_t *data) { return PM3_ESOFT; // no NDEF message } - PrintAndLogEx(NORMAL, "Capability Container: %02x %02x %02x %02x", data[0], data[1], data[2], data[3]); - PrintAndLogEx(NORMAL, " %02x: NDEF Magic Number", data[0]); - PrintAndLogEx(NORMAL, " %02x: version %d.%d supported by tag", data[1], (data[1] & 0xF0) >> 4, data[1] & 0x0f); + PrintAndLogEx(SUCCESS, "Capability Container: %02x %02x %02x %02x", data[0], data[1], data[2], data[3]); + PrintAndLogEx(SUCCESS, " %02x: NDEF Magic Number", data[0]); + PrintAndLogEx(SUCCESS, " %02x: version %d.%d supported by tag", data[1], (data[1] & 0xF0) >> 4, data[1] & 0x0f); uint16_t memsize = (data[2] + 1) * 8; topaz_tag.size = memsize; topaz_tag.dynamic_memory = calloc(memsize - TOPAZ_STATIC_MEMORY, sizeof(uint8_t)); - PrintAndLogEx(NORMAL, " %02x: Physical Memory Size of this tag: %d bytes", data[2], memsize); - PrintAndLogEx(NORMAL, " %02x: %s / %s", data[3], + PrintAndLogEx(SUCCESS, " %02x: Physical Memory Size of this tag: %d bytes", data[2], memsize); + PrintAndLogEx(SUCCESS, " %02x: %s / %s", data[3], (data[3] & 0xF0) ? "(RFU)" : "Read access granted without any security", (data[3] & 0x0F) == 0 ? "Write access granted without any security" : (data[3] & 0x0F) == 0x0F ? "No write access granted at all" : "(RFU)"); return PM3_SUCCESS; @@ -301,7 +301,7 @@ static void topaz_print_control_TLVs(uint8_t *memory) { uint16_t bytes_per_page = 1 << (TLV_value[2] & 0x0f); uint16_t bytes_locked_per_bit = 1 << (TLV_value[2] >> 4); uint16_t area_start = pages_addr * bytes_per_page + byte_offset; - PrintAndLogEx(NORMAL, "Lock Area of %d bits at byte offset 0x%04x. Each Lock Bit locks %d bytes.", + PrintAndLogEx(SUCCESS, "Lock Area of %d bits at byte offset 0x%04x. Each Lock Bit locks %d bytes.", size_in_bits, area_start, bytes_locked_per_bit); @@ -333,7 +333,7 @@ static void topaz_print_control_TLVs(uint8_t *memory) { uint16_t size_in_bytes = TLV_value[1] ? TLV_value[1] : 256; uint8_t bytes_per_page = 1 << (TLV_value[2] & 0x0f); uint16_t area_start = pages_addr * bytes_per_page + byte_offset; - PrintAndLogEx(NORMAL, "Reserved Memory of %d bytes at byte offset 0x%02x.", + PrintAndLogEx(SUCCESS, "Reserved Memory of %d bytes at byte offset 0x%02x.", size_in_bytes, area_start); reserved_memory_control_TLV_present = true; @@ -345,11 +345,11 @@ static void topaz_print_control_TLVs(uint8_t *memory) { } if (!lock_TLV_present) { - PrintAndLogEx(NORMAL, "(No Lock Control TLV present)"); + PrintAndLogEx(SUCCESS, "(No Lock Control TLV present)"); } if (!reserved_memory_control_TLV_present) { - PrintAndLogEx(NORMAL, "(No Reserved Memory Control TLV present)"); + PrintAndLogEx(SUCCESS, "(No Reserved Memory Control TLV present)"); } } @@ -376,7 +376,7 @@ static int topaz_read_dynamic_data(void) { // read and print the dynamic memory static void topaz_print_dynamic_data(void) { if (topaz_tag.size > TOPAZ_STATIC_MEMORY) { - PrintAndLogEx(NORMAL, "Dynamic Data blocks:"); + PrintAndLogEx(SUCCESS, "Dynamic Data blocks:"); if (topaz_read_dynamic_data() == 0) { PrintAndLogEx(NORMAL, "block# | offset | Data | Locked(y/n)"); PrintAndLogEx(NORMAL, "-------+--------+-------------------------+------------"); @@ -435,19 +435,19 @@ static int CmdHFTopazReader(const char *Cmd) { } PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "ATQA : %02x %02x", atqa[1], atqa[0]); + PrintAndLogEx(SUCCESS, "ATQA : %02x %02x", atqa[1], atqa[0]); topaz_tag.HR01[0] = rid_response[0]; topaz_tag.HR01[1] = rid_response[1]; // ToDo: CRC check - PrintAndLogEx(NORMAL, "HR0 : %02x (%sa Topaz tag (%scapable of carrying a NDEF message), %s memory map)", + PrintAndLogEx(SUCCESS, "HR0 : %02x (%sa Topaz tag (%scapable of carrying a NDEF message), %s memory map)", rid_response[0], (rid_response[0] & 0xF0) == 0x10 ? "" : "not ", (rid_response[0] & 0xF0) == 0x10 ? "" : "not ", (rid_response[0] & 0x0F) == 0x01 ? "static" : "dynamic"); - PrintAndLogEx(NORMAL, "HR1 : %02x", rid_response[1]); + PrintAndLogEx(SUCCESS, "HR1 : %02x", rid_response[1]); status = topaz_rall(uid_echo, rall_response); @@ -458,7 +458,7 @@ static int CmdHFTopazReader(const char *Cmd) { } memcpy(topaz_tag.uid, rall_response + 2, 7); - PrintAndLogEx(NORMAL, "UID : %02x %02x %02x %02x %02x %02x %02x", + PrintAndLogEx(SUCCESS, "UID : %02x %02x %02x %02x %02x %02x %02x", topaz_tag.uid[6], topaz_tag.uid[5], topaz_tag.uid[4], @@ -467,13 +467,13 @@ static int CmdHFTopazReader(const char *Cmd) { topaz_tag.uid[1], topaz_tag.uid[0]); - PrintAndLogEx(NORMAL, " UID[6] (Manufacturer Byte) = " _YELLOW_("%02x")", Manufacturer: " _YELLOW_("%s"), + PrintAndLogEx(SUCCESS, " UID[6] (Manufacturer Byte) = " _YELLOW_("%02x")", Manufacturer: " _YELLOW_("%s"), topaz_tag.uid[6], getTagInfo(topaz_tag.uid[6])); memcpy(topaz_tag.data_blocks, rall_response + 2, 0x0f * 8); PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Static Data blocks " _YELLOW_("0x00") "to " _YELLOW_("0x0C")":"); + PrintAndLogEx(SUCCESS, "Static Data blocks " _YELLOW_("0x00") "to " _YELLOW_("0x0C")":"); PrintAndLogEx(NORMAL, "block# | offset | Data | Locked"); PrintAndLogEx(NORMAL, "-------+--------+-------------------------+------------"); char line[80]; @@ -488,7 +488,7 @@ static int CmdHFTopazReader(const char *Cmd) { } PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Static Reserved block " _YELLOW_("0x0D")":"); + PrintAndLogEx(SUCCESS, "Static Reserved block " _YELLOW_("0x0D")":"); for (uint16_t j = 0; j < 8; j++) { sprintf(&line[3 * j], "%02x ", topaz_tag.data_blocks[0x0d][j]); } @@ -496,7 +496,7 @@ static int CmdHFTopazReader(const char *Cmd) { PrintAndLogEx(NORMAL, " 0x%02x | 0x%02x | %s| %-3s", 0x0d, 0x0d * 8, line, "n/a"); PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Static Lockbits and OTP Bytes:"); + PrintAndLogEx(SUCCESS, "Static Lockbits and OTP Bytes:"); for (uint16_t j = 0; j < 8; j++) { sprintf(&line[3 * j], "%02x ", topaz_tag.data_blocks[0x0e][j]); } @@ -507,7 +507,7 @@ static int CmdHFTopazReader(const char *Cmd) { status = topaz_print_CC(&topaz_tag.data_blocks[1][0]); if (status == PM3_ESOFT) { - PrintAndLogEx(NORMAL, "No NDEF message data present"); + PrintAndLogEx(SUCCESS, "No NDEF message data present"); topaz_switch_off_field(); return PM3_SUCCESS; } @@ -528,13 +528,13 @@ static int CmdHFTopazReader(const char *Cmd) { static int CmdHFTopazSim(const char *Cmd) { (void)Cmd; // Cmd is not used so far - PrintAndLogEx(NORMAL, "not yet implemented"); + PrintAndLogEx(INFO, "not yet implemented"); return PM3_SUCCESS; } static int CmdHFTopazCmdRaw(const char *Cmd) { (void)Cmd; // Cmd is not used so far - PrintAndLogEx(NORMAL, "not yet implemented. Use hf 14 raw with option -T."); + PrintAndLogEx(INFO, "not yet implemented. Use hf 14 raw with option -T."); return PM3_SUCCESS; } From 75a5b2efb31ff6a01db69b550f29d2de69e70605 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 10 Dec 2019 18:30:18 +0100 Subject: [PATCH 1213/1854] textual --- client/cmdhf15.c | 1 + 1 file changed, 1 insertion(+) diff --git a/client/cmdhf15.c b/client/cmdhf15.c index 13bc02fa8..c2bd777e3 100644 --- a/client/cmdhf15.c +++ b/client/cmdhf15.c @@ -866,6 +866,7 @@ static int CmdHF15Info(const char *Cmd) { memcpy(uid, recv + 2, sizeof(uid)); + PrintAndLogEx(NORMAL, ""); PrintAndLogEx(SUCCESS, " UID : %s", sprintUID(NULL, uid)); PrintAndLogEx(SUCCESS, " TYPE : %s", getTagInfo_15(recv + 2)); PrintAndLogEx(SUCCESS, " SYSINFO : %s", sprint_hex(recv, status - 2)); From 64d08de6a63c0ccd174f58bac8d21198a0911fb0 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 11 Dec 2019 15:56:36 +0100 Subject: [PATCH 1214/1854] textual --- client/cmdhw.c | 24 +++++++++++------------- client/proxmark3.c | 5 ++--- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/client/cmdhw.c b/client/cmdhw.c index 5eb6c7100..3c5e65f17 100644 --- a/client/cmdhw.c +++ b/client/cmdhw.c @@ -86,7 +86,7 @@ static void lookupChipID(uint32_t iChipID, uint32_t mem_used) { char asBuff[120]; memset(asBuff, 0, sizeof(asBuff)); uint32_t mem_avail = 0; - PrintAndLogEx(NORMAL, "\n [ Hardware ] "); + PrintAndLogEx(NORMAL, "\n " _YELLOW_("[ Hardware ]")); switch (iChipID) { case 0x270B0A40: @@ -447,13 +447,13 @@ static int CmdSetDivisor(const char *Cmd) { uint8_t arg = param_get8ex(Cmd, 0, 95, 10); if (arg < 19) { - PrintAndLogEx(ERR, "divisor must be between 19 and 255"); + PrintAndLogEx(ERR, "divisor must be between" _YELLOW_("19") " and " _YELLOW_("255") ); return PM3_EINVARG; } // 12 000 000 (12MHz) clearCommandBuffer(); SendCommandNG(CMD_LF_SET_DIVISOR, (uint8_t *)&arg, sizeof(arg)); - PrintAndLogEx(SUCCESS, "Divisor set, expected %.1f kHz", ((double)12000 / (arg + 1))); + PrintAndLogEx(SUCCESS, "Divisor set, expected " _YELLOW_("%.1f")" kHz", ((double)12000 / (arg + 1))); return PM3_SUCCESS; } @@ -514,11 +514,11 @@ static int CmdStatus(const char *Cmd) { static int CmdTia(const char *Cmd) { (void)Cmd; // Cmd is not used so far clearCommandBuffer(); - PrintAndLogEx(INFO, "Triggering new Timing Interval Acquisition..."); + PrintAndLogEx(INFO, "Triggering new Timing Interval Acquisition (TIA)..."); PacketResponseNG resp; SendCommandNG(CMD_TIA, NULL, 0); if (WaitForResponseTimeout(CMD_TIA, &resp, 2000) == false) - PrintAndLogEx(WARNING, "Tia command failed. You probably need to unplug the Proxmark3."); + PrintAndLogEx(WARNING, "TIA command failed. You probably need to unplug the Proxmark3."); PrintAndLogEx(INFO, "TIA done."); return PM3_SUCCESS; } @@ -528,7 +528,7 @@ static int CmdPing(const char *Cmd) { if (len > PM3_CMD_DATA_SIZE) len = PM3_CMD_DATA_SIZE; if (len) { - PrintAndLogEx(INFO, "Ping sent with payload len=%d", len); + PrintAndLogEx(INFO, "Ping sent with payload len = %d", len); } else { PrintAndLogEx(INFO, "Ping sent"); } @@ -702,26 +702,24 @@ void pm3_version(bool verbose, bool oneliner) { SendCommandNG(CMD_VERSION, NULL, 0); if (WaitForResponseTimeout(CMD_VERSION, &resp, 1000)) { - PrintAndLogEx(NORMAL, "\n" _BLUE_(" [ Proxmark3 RFID instrument ]") "\n"); - PrintAndLogEx(NORMAL, "\n [ CLIENT ]"); + PrintAndLogEx(NORMAL, "\n " _YELLOW_("[ Proxmark3 RFID instrument ]")); + PrintAndLogEx(NORMAL, "\n " _YELLOW_("[ CLIENT ]")); PrintAndLogEx(NORMAL, " client: RRG/Iceman"); // TODO version info? PrintAndLogEx(NORMAL, " compiled with " PM3CLIENTCOMPILER __VERSION__ PM3HOSTOS PM3HOSTARCH); -//#if PLATFORM == PM3RDV4 if (IfPm3Flash() == false && IfPm3Smartcard() == false && IfPm3FpcUsartHost() == false) { - PrintAndLogEx(NORMAL, "\n [ PROXMARK3 ]"); + PrintAndLogEx(NORMAL, "\n " _YELLOW_("[ PROXMARK3 ]")); } else { - PrintAndLogEx(NORMAL, "\n [ PROXMARK3 RDV4 ]"); + PrintAndLogEx(NORMAL, "\n " _YELLOW_("[ PROXMARK3 RDV4 ]")); PrintAndLogEx(NORMAL, " external flash: %s", IfPm3Flash() ? _GREEN_("present") : _YELLOW_("absent")); PrintAndLogEx(NORMAL, " smartcard reader: %s", IfPm3Smartcard() ? _GREEN_("present") : _YELLOW_("absent")); - PrintAndLogEx(NORMAL, "\n [ PROXMARK3 RDV4 Extras ]"); + PrintAndLogEx(NORMAL, "\n " _YELLOW_("[ PROXMARK3 RDV4 Extras ]")); PrintAndLogEx(NORMAL, " FPC USART for BT add-on support: %s", IfPm3FpcUsartHost() ? _GREEN_("present") : _YELLOW_("absent")); if (IfPm3FpcUsartDevFromUsb()) { PrintAndLogEx(NORMAL, " FPC USART for developer support: %s", _GREEN_("present")); } } -//#endif PrintAndLogEx(NORMAL, ""); diff --git a/client/proxmark3.c b/client/proxmark3.c index 7cefc6638..c28a93396 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -33,14 +33,14 @@ static void showBanner(void) { PrintAndLogEx(NORMAL, "\n"); #if defined(__linux__) || (__APPLE__) || (_WIN32) - PrintAndLogEx(NORMAL, " " _BLUE_("██████╗ ███╗ ███╗ ████╗ ") " ...iceman repo"); + PrintAndLogEx(NORMAL, " " _BLUE_("██████╗ ███╗ ███╗ ████╗ ")); PrintAndLogEx(NORMAL, " " _BLUE_("██╔══██╗████╗ ████║ ══█║")); PrintAndLogEx(NORMAL, " " _BLUE_("██████╔╝██╔████╔██║ ████╔╝")); PrintAndLogEx(NORMAL, " " _BLUE_("██╔═══╝ ██║╚██╔╝██║ ══█║") " iceman@icesql.net"); PrintAndLogEx(NORMAL, " " _BLUE_("██║ ██║ ╚═╝ ██║ ████╔╝") " https://github.com/rfidresearchgroup/proxmark3/"); PrintAndLogEx(NORMAL, " " _BLUE_("╚═╝ ╚═╝ ╚═╝ ╚═══╝ ") "pre-release v4.0"); #else - PrintAndLogEx(NORMAL, " ======. ===. ===. ====. ...iceman repo"); + PrintAndLogEx(NORMAL, " ======. ===. ===. ====."); PrintAndLogEx(NORMAL, " ==...==.====. ====. ..=."); PrintAndLogEx(NORMAL, " ======..==.====.==. ====.."); PrintAndLogEx(NORMAL, " ==..... ==..==..==. ..=. iceman@icesql.net"); @@ -52,7 +52,6 @@ static void showBanner(void) { // printf("\nMonero: 43mNJLpgBVaTvyZmX9ajcohpvVkaRy1kbZPm8tqAb7itZgfuYecgkRF36rXrKFUkwEGeZedPsASRxgv4HPBHvJwyJdyvQuP"); PrintAndLogEx(NORMAL, ""); fflush(stdout); - g_printAndLog = PRINTANDLOG_PRINT | PRINTANDLOG_LOG; } From bd70689de23f44ec13fd4421bb6d6b75a2e6105b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 14 Dec 2019 12:45:07 +0100 Subject: [PATCH 1215/1854] hf mf nested: break bad loop if timeout (@uzlonewolf) --- armsrc/mifarecmd.c | 9 ++++++++- client/mifare/mifarehost.c | 6 ++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index bb4fb343d..ea7e8482a 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -32,6 +32,7 @@ #include "crc16.h" #include "dbprint.h" #include "ticks.h" +#include "usb_cdc.h" // usb_poll_validate_length #ifndef HARDNESTED_AUTHENTICATION_TIMEOUT # define HARDNESTED_AUTHENTICATION_TIMEOUT 848 // card times out 1ms after wrong authentication (according to NXP documentation) @@ -918,7 +919,7 @@ void MifareNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8 for (rtr = 0; rtr < 17; rtr++) { // Test if the action was cancelled - if (BUTTON_PRESS()) { + if (BUTTON_PRESS() || usb_poll_validate_length()) { isOK = -2; break; } @@ -998,6 +999,12 @@ void MifareNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8 target_nt[i] = 0; while (target_nt[i] == 0) { // continue until we have an unambiguous nonce + // Test if the action was cancelled + if (BUTTON_PRESS() || usb_poll_validate_length()) { + isOK = -2; + break; + } + // prepare next select. No need to power down the card. if (mifare_classic_halt(pcs, cuid)) { if (DBGLEVEL >= DBG_INFO) Dbprintf("Nested: Halt error"); diff --git a/client/mifare/mifarehost.c b/client/mifare/mifarehost.c index e9baa7ee7..86676696d 100644 --- a/client/mifare/mifarehost.c +++ b/client/mifare/mifarehost.c @@ -24,7 +24,6 @@ #include "mfkey.h" #include "util_posix.h" // msclock - int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) { uint32_t uid = 0; uint32_t nt = 0, nr = 0, ar = 0; @@ -361,7 +360,10 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, clearCommandBuffer(); SendCommandNG(CMD_HF_MIFARE_NESTED, (uint8_t *)&payload, sizeof(payload)); - if (!WaitForResponseTimeout(CMD_HF_MIFARE_NESTED, &resp, 1500)) return PM3_ETIMEOUT; + if (!WaitForResponseTimeout(CMD_HF_MIFARE_NESTED, &resp, 2000)) { + SendCommandNG(CMD_BREAK_LOOP, NULL, 0); + return PM3_ETIMEOUT; + } if (resp.status != PM3_SUCCESS) return PM3_ESOFT; From f4427b05b2f7bccf7a4f070307b4a79285c7b4a8 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 14 Dec 2019 12:56:19 +0100 Subject: [PATCH 1216/1854] hf seach - textual --- client/cmdhf.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/client/cmdhf.c b/client/cmdhf.c index 7a1aaa868..06ad64317 100644 --- a/client/cmdhf.c +++ b/client/cmdhf.c @@ -77,7 +77,7 @@ int CmdHFSearch(const char *Cmd) { char cmdp = tolower(param_getchar(Cmd, 0)); if (cmdp == 'h') return usage_hf_search(); - PrintAndLogEx(INFO, "Checking for known tags...\n"); + PrintAndLogEx(INFO, "Checking for known tags..."); PROMPT_CLEARLINE; PrintAndLogEx(INPLACE, "Searching for ThinFilm tag..."); @@ -152,8 +152,10 @@ int CmdHFSearch(const char *Cmd) { } } - PrintAndLogEx(INPLACE, "No known/supported 13.56 MHz tags found"); + PROMPT_CLEARLINE; + PrintAndLogEx(INPLACE, "done"); PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(FAILED, _RED_("No known/supported 13.56 MHz tags found")); return PM3_ESOFT; } @@ -163,7 +165,7 @@ int CmdHFTune(const char *Cmd) { int iter = param_get32ex(Cmd, 0, 0, 10); PacketResponseNG resp; - PrintAndLogEx(SUCCESS, "Measuring HF antenna, click button or press Enter to exit"); + PrintAndLogEx(SUCCESS, "Measuring HF antenna," _YELLOW_("click button") " or press" _YELLOW_("Enter") "to exit"); clearCommandBuffer(); uint8_t mode[] = {1}; SendCommandNG(CMD_MEASURE_ANTENNA_TUNING_HF, mode, sizeof(mode)); From 8e45e0e56bd7e4953300b3ef2f6d9ee3add7063b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 14 Dec 2019 12:57:25 +0100 Subject: [PATCH 1217/1854] textual --- client/cmdlf.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/client/cmdlf.c b/client/cmdlf.c index 236bfc526..7c454a7a0 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -798,7 +798,7 @@ int CmdLFfskSim(const char *Cmd) { size_t size = DemodBufferLen; if (size > (PM3_CMD_DATA_SIZE - sizeof(lf_fsksim_t))) { - PrintAndLogEx(NORMAL, "DemodBuffer too long for current implementation - length: %zu - max: %zu", size, PM3_CMD_DATA_SIZE - sizeof(lf_fsksim_t)); + PrintAndLogEx(WARNING, "DemodBuffer too long for current implementation - length: %zu - max: %zu", size, PM3_CMD_DATA_SIZE - sizeof(lf_fsksim_t)); size = PM3_CMD_DATA_SIZE - sizeof(lf_fsksim_t); } @@ -900,7 +900,7 @@ int CmdLFaskSim(const char *Cmd) { size_t size = DemodBufferLen; if (size > (PM3_CMD_DATA_SIZE - sizeof(lf_asksim_t))) { - PrintAndLogEx(NORMAL, "DemodBuffer too long for current implementation - length: %zu - max: %zu", size, PM3_CMD_DATA_SIZE - sizeof(lf_asksim_t)); + PrintAndLogEx(WARNING, "DemodBuffer too long for current implementation - length: %zu - max: %zu", size, PM3_CMD_DATA_SIZE - sizeof(lf_asksim_t)); size = PM3_CMD_DATA_SIZE - sizeof(lf_asksim_t); } @@ -993,13 +993,13 @@ int CmdLFpskSim(const char *Cmd) { if (errors) return usage_lf_simpsk(); if (dataLen == 0) { //using DemodBuffer - PrintAndLogEx(NORMAL, "Getting Clocks"); + PrintAndLogEx(INFO, "Getting Clocks"); if (clk == 0) clk = GetPskClock("", false); - PrintAndLogEx(NORMAL, "clk: %d", clk); + PrintAndLogEx(INFO, "clk: %d", clk); if (!carrier) carrier = GetPskCarrier("", false); - PrintAndLogEx(NORMAL, "carrier: %d", carrier); + PrintAndLogEx(INFO, "carrier: %d", carrier); } else { setDemodBuff(data, dataLen, 0); @@ -1015,12 +1015,12 @@ int CmdLFpskSim(const char *Cmd) { //need to convert psk2 to psk1 data before sim psk2TOpsk1(DemodBuffer, DemodBufferLen); } else { - PrintAndLogEx(NORMAL, "Sorry, PSK3 not yet available"); + PrintAndLogEx(WARNING, "Sorry, PSK3 not yet available"); } } size_t size = DemodBufferLen; if (size > (PM3_CMD_DATA_SIZE - sizeof(lf_psksim_t))) { - PrintAndLogEx(NORMAL, "DemodBuffer too long for current implementation - length: %zu - max: %zu", size, PM3_CMD_DATA_SIZE - sizeof(lf_psksim_t)); + PrintAndLogEx(WARNING, "DemodBuffer too long for current implementation - length: %zu - max: %zu", size, PM3_CMD_DATA_SIZE - sizeof(lf_psksim_t)); size = PM3_CMD_DATA_SIZE - sizeof(lf_psksim_t); } From 3f3366429ff2e0c608b1a57de9ffb03e1a8d6691 Mon Sep 17 00:00:00 2001 From: Thomas Sutter Date: Mon, 16 Dec 2019 11:06:48 +0100 Subject: [PATCH 1218/1854] Add Auth1 Command (Alpha). Untested. --- client/cmdhffelica.c | 151 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 143 insertions(+), 8 deletions(-) diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index fe11d4c60..8c8b83b89 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -22,6 +22,7 @@ #include "util.h" #include "ui.h" #include "mifare.h" // felica_card_select_t struct +#include "mbedtls/des.h" #define AddCrc(data, len) compute_crc(CRC_FELICA, (data), (len), (data)+(len)+1, (data)+(len)) static int CmdHelp(const char *Cmd); @@ -282,6 +283,34 @@ static int usage_hf_felica_request_specification_version() { return PM3_SUCCESS; } +static int usage_hf_felica_authentication1() { + PrintAndLogEx(NORMAL, "\nInfo: Initiate mutual authentication. This command must always be executed before Authentication2 command" + ", and mutual authentication is achieve only after Authentication2 command has succeeded."); + PrintAndLogEx(NORMAL, " - Auth1 Parameters:"); + PrintAndLogEx(NORMAL, " - Number of Areas n: 1-byte (1 <= n <= 8)"); + PrintAndLogEx(NORMAL, " - Area Code List: 2n byte"); + PrintAndLogEx(NORMAL, " - Number of Services m: 1-byte (1 <= n <= 8)"); + PrintAndLogEx(NORMAL, " - Service Code List: 2n byte"); + PrintAndLogEx(NORMAL, " - 3DES-Key: 128-bit master secret used for the encryption"); + PrintAndLogEx(NORMAL, " - M1c: Encrypted random number (challenge for tag authentication) 8-byte"); + PrintAndLogEx(NORMAL, " - Response:"); + PrintAndLogEx(NORMAL, " - Response Code: 11h 1-byte"); + PrintAndLogEx(NORMAL, " - Manufacture ID(IDm): 8-byte"); + PrintAndLogEx(NORMAL, " - M2c: 8-byte"); + PrintAndLogEx(NORMAL, " - M3c: 8-byte"); + PrintAndLogEx(NORMAL, " - Success: Card Mode switches to Mode1. You can check this with the request response command."); + PrintAndLogEx(NORMAL, " - Unsuccessful: Card should not respond at all."); + + PrintAndLogEx(NORMAL, "\nUsage: hf felica auth1 [-h][-i] <01 Number of Areas hex> <0A0B... Area Code List hex> <01 Number of Services hex> <0A0B... Service Code List hex> <0x0102030405060809 3DES-key hex (128bit)>"); + PrintAndLogEx(NORMAL, " -h this help"); + PrintAndLogEx(NORMAL, " -i <0A0B0C ... hex> set custom IDm to use"); + PrintAndLogEx(NORMAL, "\nExamples: "); + PrintAndLogEx(NORMAL, " hf felica auth1 01 0000 01 8B00 FFFFFFFFFFFFFFFF "); + PrintAndLogEx(NORMAL, " hf felica auth1 01 0000 01 8B00 FFFFFFFFAAAAAAAAFFFFFFFF "); + PrintAndLogEx(NORMAL, " hf felica auth1 -i 11100910C11BC407 01 0000 01 8B00 FFFFFFFFFFFFFFFF\n\n"); + return PM3_SUCCESS; +} + /** * Wait for response from pm3 or timeout. * Checks if receveid bytes have a valid CRC. @@ -371,7 +400,7 @@ static void clear_and_send_command(uint8_t flags, uint16_t datalen, uint8_t *dat uint16_t numbits = 0; clearCommandBuffer(); if (verbose) { - PrintAndLogEx(NORMAL, "Send Service Request Frame: %s", sprint_hex(data, datalen)); + PrintAndLogEx(NORMAL, "Send RAW COMMAND - Frame: %s", sprint_hex(data, datalen)); } SendCommandMIX(CMD_HF_FELICA_COMMAND, flags, (datalen & 0xFFFF) | (uint32_t)(numbits << 16), 0, data, datalen); } @@ -501,6 +530,115 @@ int send_wr_unencrypted(uint8_t flags, uint16_t datalen, uint8_t *data, bool ver } } +/** + * Command parser for auth1 + * @param Cmd input data of the user. + * @return client result code. + */ +static int CmdHFFelicaAuthentication1(const char *Cmd) { + if (strlen(Cmd) < 4){ + return usage_hf_felica_authentication1(); + } + uint8_t data[PM3_CMD_DATA_SIZE]; + bool custom_IDm = false; + strip_cmds(Cmd); + uint16_t datalen = 24; // Length (1), Command ID (1), IDm (8), Number of Area (1), Area Code List (2), Number of Service (1), Service Code List (2), M1c (8) + uint8_t paramCount = 0; + uint8_t flags = 0; + int i = 0; + while (Cmd[i] != '\0') { + if (Cmd[i] == '-') { + switch (Cmd[i + 1]) { + case 'H': + case 'h': + return usage_hf_felica_authentication1(); + case 'i': + paramCount++; + custom_IDm = true; + if (!add_param(Cmd, paramCount, data, 2, 16)) { + return PM3_EINVARG; + } + paramCount++; + i += 16; + break; + default: + return usage_hf_felica_authentication1(); + } + } + i++; + } + data[0] = int_to_hex(&datalen); + data[1] = 0x10; // Command ID + if (!custom_IDm && !check_last_idm(data, datalen)) { + return PM3_EINVARG; + } + // Number of Area (1), Area Code List (2), Number of Service (1), Service Code List (2), M1c (8) + uint8_t lengths[] = {2, 4, 2, 4}; + uint8_t dataPositions[] = {10, 11, 13, 14}; + for (int i = 0; i < 4; i++) { + if (add_param(Cmd, paramCount, data, dataPositions[i], lengths[i])) { + paramCount++; + } else { + return PM3_EINVARG; + } + } + + // READER CHALLENGE - (RANDOM To Encrypt) + unsigned char input[8]; + input[0] = 0x1; + input[1] = 0x2; + input[2] = 0x3; + input[3] = 0x4; + input[4] = 0x5; + input[5] = 0x6; + input[6] = 0x7; + input[7] = 0x8; + unsigned char output[8]; + // Create M1c Challenge with 3DES (3 Keys = 24, 2 Keys = 16) + uint8_t master_key[PM3_CMD_DATA_SIZE]; + mbedtls_des3_context des3_ctx; + mbedtls_des3_init(&des3_ctx); + if(param_getlength(Cmd, paramCount) == 24){ + param_gethex(Cmd, paramCount, master_key, 24); + mbedtls_des3_set3key_enc(&des3_ctx, master_key); + PrintAndLogEx(NORMAL, "3DES Master Secret: %s", sprint_hex(master_key, 12)); + } + else if (param_getlength(Cmd, paramCount) == 16) { + param_gethex(Cmd, paramCount, master_key, 16); + mbedtls_des3_set2key_enc(&des3_ctx, master_key); + PrintAndLogEx(NORMAL, "3DES Master Secret: %s", sprint_hex(master_key, 8)); + }else{ + PrintAndLogEx(ERR, "Invalid Key length"); + return PM3_EINVARG; + } + + mbedtls_des3_crypt_ecb(&des3_ctx, input, output); + PrintAndLogEx(NORMAL, "3DES ENCRYPTED M1c: %s", sprint_hex(output, 8)); + // Add M1c Challenge to frame + int frame_position = 16; + for(int i=0; i < 8; i++){ + data[frame_position++] = output[i]; + } + + AddCrc(data, datalen); + datalen += 2; + flags |= FELICA_APPEND_CRC; + flags |= FELICA_RAW; + + PrintAndLogEx(NORMAL, "Client Send AUTH1 Frame: %s", sprint_hex(data, datalen)); + clear_and_send_command(flags, datalen, data, 0); + + PacketResponseNG resp; + if (!waitCmdFelica(0, &resp, 1)) { + PrintAndLogEx(ERR, "\nGot no Response from card"); + return PM3_ERFTRANS; + } else { + PrintAndLogEx(NORMAL, "AUTH1 SUCCESS!"); + PrintAndLogEx(NORMAL, "%s", sprint_hex(resp.data.asBytes, 256)); + } + return PM3_SUCCESS; +} + /** * Command parser for wrunencrypted. * @param Cmd input data of the user. @@ -895,8 +1033,6 @@ static int CmdHFFelicaResetMode(const char *Cmd) { return PM3_SUCCESS; } - - /** * Command parser for rqsyscode * @param Cmd input data of the user. @@ -1012,11 +1148,10 @@ static int CmdHFFelicaRequestService(const char *Cmd) { } } - // Node Code List if (param_getlength(Cmd, paramCount) == 4) { param_gethex(Cmd, paramCount++, data + 11, 4); } else { - PrintAndLogEx(ERR, "Incorrect Node Code List length!"); + PrintAndLogEx(ERR, "Incorrect Parameter length!"); return PM3_EINVARG; } @@ -1521,9 +1656,9 @@ static command_t CommandTable[] = { {"wrunencrypted", CmdHFFelicaWriteWithoutEncryption, IfPm3Felica, "write Block Data to an authentication-not-required Service."}, {"scsvcode", CmdHFFelicaNotImplementedYet, IfPm3Felica, "acquire Area Code and Service Code."}, {"rqsyscode", CmdHFFelicaRequestSystemCode, IfPm3Felica, "acquire System Code registered to the card."}, - //{"auth1", CmdHFFelicaNotImplementedYet, IfPm3Felica, "authenticate a card."}, - //{"auth2", CmdHFFelicaNotImplementedYet, IfPm3Felica, "allow a card to authenticate a Reader/Writer."}, - //{"read", CmdHFFelicaNotImplementedYet, IfPm3Felica, "read Block Data from authentication-required Service."}, + {"auth1", CmdHFFelicaAuthentication1, IfPm3Felica, "authenticate a card. Start mutual authentication with Auth1 (v1)"}, + {"auth2", CmdHFFelicaNotImplementedYet, IfPm3Felica, "allow a card to authenticate a Reader/Writer. Auth2 (v1)"}, + {"read", CmdHFFelicaNotImplementedYet, IfPm3Felica, "read Block Data from authentication-required Service."}, //{"write", CmdHFFelicaNotImplementedYet, IfPm3Felica, "write Block Data to an authentication-required Service."}, //{"scsvcodev2", CmdHFFelicaNotImplementedYet, IfPm3Felica, "verify the existence of Area or Service, and to acquire Key Version."}, //{"getsysstatus", CmdHFFelicaNotImplementedYet, IfPm3Felica, "acquire the setup information in System."}, From d1906aa03e008168db620f2bda6d6af8d2825430 Mon Sep 17 00:00:00 2001 From: Thomas Sutter Date: Mon, 16 Dec 2019 11:25:15 +0100 Subject: [PATCH 1219/1854] Change logs to info. Make style. --- client/cmdhffelica.c | 23 +++++++++++------------ client/cmdhw.c | 2 +- client/cmdlfnexwatch.c | 2 +- 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index 5144902ad..99ca6194e 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -285,7 +285,7 @@ static int usage_hf_felica_request_specification_version() { static int usage_hf_felica_authentication1() { PrintAndLogEx(NORMAL, "\nInfo: Initiate mutual authentication. This command must always be executed before Authentication2 command" - ", and mutual authentication is achieve only after Authentication2 command has succeeded."); + ", and mutual authentication is achieve only after Authentication2 command has succeeded."); PrintAndLogEx(NORMAL, " - Auth1 Parameters:"); PrintAndLogEx(NORMAL, " - Number of Areas n: 1-byte (1 <= n <= 8)"); PrintAndLogEx(NORMAL, " - Area Code List: 2n byte"); @@ -536,7 +536,7 @@ int send_wr_unencrypted(uint8_t flags, uint16_t datalen, uint8_t *data, bool ver * @return client result code. */ static int CmdHFFelicaAuthentication1(const char *Cmd) { - if (strlen(Cmd) < 4){ + if (strlen(Cmd) < 4) { return usage_hf_felica_authentication1(); } uint8_t data[PM3_CMD_DATA_SIZE]; @@ -597,25 +597,24 @@ static int CmdHFFelicaAuthentication1(const char *Cmd) { uint8_t master_key[PM3_CMD_DATA_SIZE]; mbedtls_des3_context des3_ctx; mbedtls_des3_init(&des3_ctx); - if(param_getlength(Cmd, paramCount) == 24){ + if (param_getlength(Cmd, paramCount) == 24) { param_gethex(Cmd, paramCount, master_key, 24); mbedtls_des3_set3key_enc(&des3_ctx, master_key); - PrintAndLogEx(NORMAL, "3DES Master Secret: %s", sprint_hex(master_key, 12)); - } - else if (param_getlength(Cmd, paramCount) == 16) { + PrintAndLogEx(INFO, "3DES Master Secret: %s", sprint_hex(master_key, 12)); + } else if (param_getlength(Cmd, paramCount) == 16) { param_gethex(Cmd, paramCount, master_key, 16); mbedtls_des3_set2key_enc(&des3_ctx, master_key); - PrintAndLogEx(NORMAL, "3DES Master Secret: %s", sprint_hex(master_key, 8)); - }else{ - PrintAndLogEx(ERR, "Invalid Key length"); + PrintAndLogEx(INFO, "3DES Master Secret: %s", sprint_hex(master_key, 8)); + } else { + PrintAndLogEx(ERR, "Invalid key length"); return PM3_EINVARG; } mbedtls_des3_crypt_ecb(&des3_ctx, input, output); - PrintAndLogEx(NORMAL, "3DES ENCRYPTED M1c: %s", sprint_hex(output, 8)); + PrintAndLogEx(INFO, "3DES ENCRYPTED M1c: %s", sprint_hex(output, 8)); // Add M1c Challenge to frame int frame_position = 16; - for(int i=0; i < 8; i++){ + for (int i = 0; i < 8; i++) { data[frame_position++] = output[i]; } @@ -624,7 +623,7 @@ static int CmdHFFelicaAuthentication1(const char *Cmd) { flags |= FELICA_APPEND_CRC; flags |= FELICA_RAW; - PrintAndLogEx(NORMAL, "Client Send AUTH1 Frame: %s", sprint_hex(data, datalen)); + PrintAndLogEx(INFO, "Client Send AUTH1 Frame: %s", sprint_hex(data, datalen)); clear_and_send_command(flags, datalen, data, 0); PacketResponseNG resp; diff --git a/client/cmdhw.c b/client/cmdhw.c index 3c5e65f17..a35f15b5e 100644 --- a/client/cmdhw.c +++ b/client/cmdhw.c @@ -447,7 +447,7 @@ static int CmdSetDivisor(const char *Cmd) { uint8_t arg = param_get8ex(Cmd, 0, 95, 10); if (arg < 19) { - PrintAndLogEx(ERR, "divisor must be between" _YELLOW_("19") " and " _YELLOW_("255") ); + PrintAndLogEx(ERR, "divisor must be between" _YELLOW_("19") " and " _YELLOW_("255")); return PM3_EINVARG; } // 12 000 000 (12MHz) diff --git a/client/cmdlfnexwatch.c b/client/cmdlfnexwatch.c index 717bf2587..e30a37a80 100644 --- a/client/cmdlfnexwatch.c +++ b/client/cmdlfnexwatch.c @@ -81,7 +81,7 @@ static int CmdNexWatchDemod(const char *Cmd) { //checksum check (TBD) //output - PrintAndLogEx(SUCCESS, "NexWatch ID: " _YELLOW_("%"PRIu32) , ID); + PrintAndLogEx(SUCCESS, "NexWatch ID: " _YELLOW_("%"PRIu32), ID); if (invert) { PrintAndLogEx(INFO, "Had to Invert - probably NexKey"); for (size_t i = 0; i < size; i++) From 50d1dfea775c9220513070b567d9d1054ed93186 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 16 Dec 2019 13:26:13 +0100 Subject: [PATCH 1220/1854] add cardx crc skeleton, will need to adapt --- common/crc.c | 8 ++++++++ common/crc.h | 2 ++ 2 files changed, 10 insertions(+) diff --git a/common/crc.c b/common/crc.c index 0237fb36a..22bfad035 100644 --- a/common/crc.c +++ b/common/crc.c @@ -126,3 +126,11 @@ uint32_t CRC8Legic(uint8_t *buff, size_t size) { crc_update2(&crc, buff[i], 8); return reflect8(crc_finish(&crc)); } +// width=8 poly=0x107, init=0x2C refin=true refout=true xorout=0x0000 check=0 name="CRC-8/CARDX" +uint32_t CRC8Cardx(uint8_t *buff, size_t size) { + crc_t crc; + crc_init_ref(&crc, 8, 0x107, 0x2C, 0, true, true); + for (size_t i = 0; i < size; ++i) + crc_update2(&crc, buff[i], 8); + return crc_finish(&crc); +} diff --git a/common/crc.h b/common/crc.h index 6dcfe918f..772c278b8 100644 --- a/common/crc.h +++ b/common/crc.h @@ -73,4 +73,6 @@ uint32_t CRC4Legic(uint8_t *buff, size_t size); // Calculate CRC-8/Legic checksum uint32_t CRC8Legic(uint8_t *buff, size_t size); +// Calculate CRC-8/Cardx checksum +uint32_t CRC8Cardx(uint8_t *buff, size_t size); #endif /* __CRC_H */ From 6a21c780fa652f338c0755ee44b3c465f44a43ba Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 16 Dec 2019 13:51:10 +0100 Subject: [PATCH 1221/1854] chg: lf gallagher demod - using the research from Matt, @megabug, to get better support. WIP. --- client/cmdlfgallagher.c | 77 +++++++++++++++++++++++++++++++++-------- 1 file changed, 63 insertions(+), 14 deletions(-) diff --git a/client/cmdlfgallagher.c b/client/cmdlfgallagher.c index 9704afc60..4752343d5 100644 --- a/client/cmdlfgallagher.c +++ b/client/cmdlfgallagher.c @@ -12,7 +12,7 @@ #include "cmdlfgallagher.h" #include //tolower - +#include #include "commonutil.h" // ARRAYLEN #include "common.h" #include "cmdparser.h" // command_t @@ -23,6 +23,7 @@ #include "lfdemod.h" // preamble test #include "protocols.h" // t55xx defines #include "cmdlft55xx.h" // clone.. +#include "crc.h" // CRC8/Cardx static int CmdHelp(const char *Cmd); @@ -39,6 +40,32 @@ static int usage_lf_gallagher_clone(void) { return PM3_SUCCESS; } +static void descramble( uint8_t *arr, uint8_t len) { + + uint8_t lut[] = { + 0xa3, 0xb0, 0x80, 0xc6, 0xb2, 0xf4, 0x5c, 0x6c, 0x81, 0xf1, 0xbb, 0xeb, 0x55, 0x67, 0x3c, 0x05, + 0x1a, 0x0e, 0x61, 0xf6, 0x22, 0xce, 0xaa, 0x8f, 0xbd, 0x3b, 0x1f, 0x5e, 0x44, 0x04, 0x51, 0x2e, + 0x4d, 0x9a, 0x84, 0xea, 0xf8, 0x66, 0x74, 0x29, 0x7f, 0x70, 0xd8, 0x31, 0x7a, 0x6d, 0xa4, 0x00, + 0x82, 0xb9, 0x5f, 0xb4, 0x16, 0xab, 0xff, 0xc2, 0x39, 0xdc, 0x19, 0x65, 0x57, 0x7c, 0x20, 0xfa, + 0x5a, 0x49, 0x13, 0xd0, 0xfb, 0xa8, 0x91, 0x73, 0xb1, 0x33, 0x18, 0xbe, 0x21, 0x72, 0x48, 0xb6, + 0xdb, 0xa0, 0x5d, 0xcc, 0xe6, 0x17, 0x27, 0xe5, 0xd4, 0x53, 0x42, 0xf3, 0xdd, 0x7b, 0x24, 0xac, + 0x2b, 0x58, 0x1e, 0xa7, 0xe7, 0x86, 0x40, 0xd3, 0x98, 0x97, 0x71, 0xcb, 0x3a, 0x0f, 0x01, 0x9b, + 0x6e, 0x1b, 0xfc, 0x34, 0xa6, 0xda, 0x07, 0x0c, 0xae, 0x37, 0xca, 0x54, 0xfd, 0x26, 0xfe, 0x0a, + 0x45, 0xa2, 0x2a, 0xc4, 0x12, 0x0d, 0xf5, 0x4f, 0x69, 0xe0, 0x8a, 0x77, 0x60, 0x3f, 0x99, 0x95, + 0xd2, 0x38, 0x36, 0x62, 0xb7, 0x32, 0x7e, 0x79, 0xc0, 0x46, 0x93, 0x2f, 0xa5, 0xba, 0x5b, 0xaf, + 0x52, 0x1d, 0xc3, 0x75, 0xcf, 0xd6, 0x4c, 0x83, 0xe8, 0x3d, 0x30, 0x4e, 0xbc, 0x08, 0x2d, 0x09, + 0x06, 0xd9, 0x25, 0x9e, 0x89, 0xf2, 0x96, 0x88, 0xc1, 0x8c, 0x94, 0x0b, 0x28, 0xf0, 0x47, 0x63, + 0xd5, 0xb3, 0x68, 0x56, 0x9c, 0xf9, 0x6f, 0x41, 0x50, 0x85, 0x8b, 0x9d, 0x59, 0xbf, 0x9f, 0xe2, + 0x8e, 0x6a, 0x11, 0x23, 0xa1, 0xcd, 0xb5, 0x7d, 0xc7, 0xa9, 0xc8, 0xef, 0xdf, 0x02, 0xb8, 0x03, + 0x6b, 0x35, 0x3e, 0x2c, 0x76, 0xc9, 0xde, 0x1c, 0x4b, 0xd1, 0xed, 0x14, 0xc5, 0xad, 0xe9, 0x64, + 0x4a, 0xec, 0x8d, 0xf7, 0x10, 0x43, 0x78, 0x15, 0x87, 0xe4, 0xd7, 0x92, 0xe1, 0xee, 0xe3, 0x90 + }; + + for (int i = 0; i < len; i++) { + arr[i] = lut[arr[i]]; + } +} + //see ASK/MAN Demod for what args are accepted static int CmdGallagherDemod(const char *Cmd) { @@ -71,10 +98,39 @@ static int CmdGallagherDemod(const char *Cmd) { uint32_t raw2 = bytebits_to_byte(DemodBuffer + 32, 32); uint32_t raw3 = bytebits_to_byte(DemodBuffer + 64, 32); - // preamble CS? + // bytes + uint8_t arr[8] = {0}; + for(int i = 0, pos = 0; i < ARRAYLEN(arr); i++) { + pos = (i * 8) + i; + arr[i] = bytebits_to_byte(DemodBuffer + pos, 8); + printf("%d -", pos ); + } + printf("\n"); - PrintAndLogEx(SUCCESS, "GALLAGHER Tag Found -- Raw: %08X%08X%08X", raw1, raw2, raw3); - PrintAndLogEx(INFO, "How the Raw ID is translated by the reader is unknown. Share your trace file on forum"); + // crc + uint8_t crc = bytebits_to_byte(DemodBuffer + 72, 8); + uint8_t calc_crc = CRC8Cardx(arr, ARRAYLEN(arr) ); + + PrintAndLogEx(INFO, " Before: %s", sprint_hex(arr, 8)); + descramble(arr, ARRAYLEN(arr)); + PrintAndLogEx(INFO, " After : %s", sprint_hex(arr, 8)); + + // 4bit region code + uint8_t rc = (arr[3] & 0x0E) >> 1; + + // 16bit FC + uint16_t fc = (arr[5] & 0x0F) << 12 | arr[1] << 4 | ((arr[7] >> 4) & 0x0F); + + // 24bit CN + uint32_t cn = arr[0] << 16 | (arr[4] & 0x1F) << 11 | arr[2] << 3 | (arr[3] & 0xE0) >> 4; + + // 4bit issue level + uint8_t il = arr[7] & 0x0F; + + PrintAndLogEx(SUCCESS, "GALLAGHER Tag Found -- Region: %u FC: %u CN: %u Issue Level: %u", rc, fc, cn, il); + PrintAndLogEx(SUCCESS, " Printed: %C%u", rc + 0x40, fc); + PrintAndLogEx(SUCCESS, " Raw: %08X%08X%08X", raw1, raw2, raw3); + PrintAndLogEx(SUCCESS, " CRC: %02X - %02X (%s)", crc, calc_crc, (crc == calc_crc) ? "OK":"Failed"); return PM3_SUCCESS; } @@ -126,7 +182,6 @@ static int CmdGallagherClone(const char *Cmd) { } static int CmdGallagherSim(const char *Cmd) { - // ASK/MAN sim. PrintAndLogEx(INFO, " To be implemented, feel free to contribute!"); return PM3_SUCCESS; @@ -152,20 +207,14 @@ int CmdLFGallagher(const char *Cmd) { return CmdsParse(CommandTable, Cmd); } -// by marshmellow -// find PAC preamble in already demoded data +// find Gallagher preamble in already demoded data int detectGallagher(uint8_t *dest, size_t *size) { if (*size < 96) return -1; //make sure buffer has data size_t startIdx = 0; - uint8_t preamble[] = { - //0, 0, 0, 0, - 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 0, 1, - 0, 1, 0, 1, 0, 1, 0, 0, - 0, 1, 1, 0, 0, 0 - }; + uint8_t preamble[] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0 }; if (!preambleSearch(dest, preamble, sizeof(preamble), size, &startIdx)) return -2; //preamble not found + if (*size != 96) return -3; //wrong demoded size //return start position return (int)startIdx; From 47a416a3ac4f1a166e500f2fc3a8e19a79c27765 Mon Sep 17 00:00:00 2001 From: Thomas Sutter Date: Mon, 16 Dec 2019 14:08:30 +0100 Subject: [PATCH 1222/1854] Fix key length in auth1 command. --- client/cmdhffelica.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index 99ca6194e..19bc807df 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -305,9 +305,9 @@ static int usage_hf_felica_authentication1() { PrintAndLogEx(NORMAL, " -h this help"); PrintAndLogEx(NORMAL, " -i <0A0B0C ... hex> set custom IDm to use"); PrintAndLogEx(NORMAL, "\nExamples: "); - PrintAndLogEx(NORMAL, " hf felica auth1 01 0000 01 8B00 FFFFFFFFFFFFFFFF "); - PrintAndLogEx(NORMAL, " hf felica auth1 01 0000 01 8B00 FFFFFFFFAAAAAAAAFFFFFFFF "); - PrintAndLogEx(NORMAL, " hf felica auth1 -i 11100910C11BC407 01 0000 01 8B00 FFFFFFFFFFFFFFFF\n\n"); + PrintAndLogEx(NORMAL, " hf felica auth1 01 0000 01 8B00 AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBB "); + PrintAndLogEx(NORMAL, " hf felica auth1 01 0000 01 8B00 AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBAAAAAAAAAAAAAAAA "); + PrintAndLogEx(NORMAL, " hf felica auth1 -i 11100910C11BC407 01 0000 01 8B00 AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBB\n\n"); return PM3_SUCCESS; } @@ -597,14 +597,14 @@ static int CmdHFFelicaAuthentication1(const char *Cmd) { uint8_t master_key[PM3_CMD_DATA_SIZE]; mbedtls_des3_context des3_ctx; mbedtls_des3_init(&des3_ctx); - if (param_getlength(Cmd, paramCount) == 24) { - param_gethex(Cmd, paramCount, master_key, 24); + if (param_getlength(Cmd, paramCount) == 48) { + param_gethex(Cmd, paramCount, master_key, 48); mbedtls_des3_set3key_enc(&des3_ctx, master_key); - PrintAndLogEx(INFO, "3DES Master Secret: %s", sprint_hex(master_key, 12)); - } else if (param_getlength(Cmd, paramCount) == 16) { - param_gethex(Cmd, paramCount, master_key, 16); + PrintAndLogEx(INFO, "3DES Master Secret: %s", sprint_hex(master_key, 24)); + } else if (param_getlength(Cmd, paramCount) == 32) { + param_gethex(Cmd, paramCount, master_key, 32); mbedtls_des3_set2key_enc(&des3_ctx, master_key); - PrintAndLogEx(INFO, "3DES Master Secret: %s", sprint_hex(master_key, 8)); + PrintAndLogEx(INFO, "3DES Master Secret: %s", sprint_hex(master_key, 16)); } else { PrintAndLogEx(ERR, "Invalid key length"); return PM3_EINVARG; From a65cfc5f4b45c603336057da66b54bed071eb86f Mon Sep 17 00:00:00 2001 From: Thomas Sutter Date: Tue, 17 Dec 2019 08:19:42 +0100 Subject: [PATCH 1223/1854] Fix auth1 response. --- client/cmdhffelica.c | 10 ++++++++-- include/mifare.h | 6 ++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index 19bc807df..1986cb9b8 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -631,8 +631,14 @@ static int CmdHFFelicaAuthentication1(const char *Cmd) { PrintAndLogEx(ERR, "\nGot no Response from card"); return PM3_ERFTRANS; } else { - PrintAndLogEx(NORMAL, "AUTH1 SUCCESS!"); - PrintAndLogEx(NORMAL, "%s", sprint_hex(resp.data.asBytes, 256)); + felica_auth1_response_t auth1_response; + memcpy(&auth1_response, (felica_auth1_response_t *)resp.data.asBytes, sizeof(felica_auth1_response_t)); + if (auth1_response.frame_response.IDm[0] != 0) { + PrintAndLogEx(SUCCESS, "\nGot auth1 response:"); + PrintAndLogEx(SUCCESS, "IDm: %s", sprint_hex(auth1_response.frame_response.IDm, sizeof(auth1_response.frame_response.IDm))); + PrintAndLogEx(SUCCESS, "M2C: %s", sprint_hex(auth1_response.m2c, sizeof(auth1_response.m2c))); + PrintAndLogEx(SUCCESS, "M3C: %s", sprint_hex(auth1_response.m3c, sizeof(auth1_response.m3c))); + } } return PM3_SUCCESS; } diff --git a/include/mifare.h b/include/mifare.h index e278b3794..0f2758f56 100644 --- a/include/mifare.h +++ b/include/mifare.h @@ -220,6 +220,12 @@ typedef struct { uint8_t option_version_list[4]; } PACKED felica_request_spec_response_t; +typedef struct { + felica_frame_response_t frame_response; + uint8_t m2c[8]; + uint8_t m3c[8]; +} PACKED felica_auth1_response_t; + typedef enum FELICA_COMMAND { FELICA_CONNECT = (1 << 0), FELICA_NO_DISCONNECT = (1 << 1), From bb53a40adbbc7cb46ad962a2aa62ac7d5d024fe4 Mon Sep 17 00:00:00 2001 From: Thomas Sutter Date: Tue, 17 Dec 2019 13:09:14 +0100 Subject: [PATCH 1224/1854] Add auth1 output - experimental. Add auth2 command - experimental. --- client/cmdhffelica.c | 173 +++++++++++++++++++++++++++++++++++++++++-- include/mifare.h | 8 ++ 2 files changed, 176 insertions(+), 5 deletions(-) diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index 1986cb9b8..a8835e1e7 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -292,7 +292,7 @@ static int usage_hf_felica_authentication1() { PrintAndLogEx(NORMAL, " - Number of Services m: 1-byte (1 <= n <= 8)"); PrintAndLogEx(NORMAL, " - Service Code List: 2n byte"); PrintAndLogEx(NORMAL, " - 3DES-Key: 128-bit master secret used for the encryption"); - PrintAndLogEx(NORMAL, " - M1c: Encrypted random number (challenge for tag authentication) 8-byte"); + PrintAndLogEx(NORMAL, " - M1c: Encrypted random number - challenge for tag authentication (8-byte)"); PrintAndLogEx(NORMAL, " - Response:"); PrintAndLogEx(NORMAL, " - Response Code: 11h 1-byte"); PrintAndLogEx(NORMAL, " - Manufacture ID(IDm): 8-byte"); @@ -301,7 +301,7 @@ static int usage_hf_felica_authentication1() { PrintAndLogEx(NORMAL, " - Success: Card Mode switches to Mode1. You can check this with the request response command."); PrintAndLogEx(NORMAL, " - Unsuccessful: Card should not respond at all."); - PrintAndLogEx(NORMAL, "\nUsage: hf felica auth1 [-h][-i] <01 Number of Areas hex> <0A0B... Area Code List hex> <01 Number of Services hex> <0A0B... Service Code List hex> <0x0102030405060809 3DES-key hex (128bit)>"); + PrintAndLogEx(NORMAL, "\nUsage: hf felica auth1 [-h][-i] <01 Number of Areas hex> <0A0B... Area Code List hex> <01 Number of Services hex> <0A0B... Service Code List hex> <0x0102030405060809... 3DES-key hex (16-byte)>"); PrintAndLogEx(NORMAL, " -h this help"); PrintAndLogEx(NORMAL, " -i <0A0B0C ... hex> set custom IDm to use"); PrintAndLogEx(NORMAL, "\nExamples: "); @@ -311,6 +311,30 @@ static int usage_hf_felica_authentication1() { return PM3_SUCCESS; } +static int usage_hf_felica_authentication2() { + PrintAndLogEx(NORMAL, "\nInfo: Complete mutual authentication. This command can only be executed subsquent to Authentication1" + " command."); + PrintAndLogEx(NORMAL, " - Auth2 Parameters:"); + PrintAndLogEx(NORMAL, " - Manufacturer IDm: (8-byte)"); + PrintAndLogEx(NORMAL, " - M3c: card challenge (8-byte)"); + PrintAndLogEx(NORMAL, " - 3DES Key: key used for decryption of M3c (16-byte)"); + PrintAndLogEx(NORMAL, " - Response (encrypted):"); + PrintAndLogEx(NORMAL, " - Response Code: 13h (1-byte)"); + PrintAndLogEx(NORMAL, " - IDtc: (8-byte)"); + PrintAndLogEx(NORMAL, " - IDi (encrypted): (8-byte)"); + PrintAndLogEx(NORMAL, " - PMi (encrypted): (8-byte)"); + PrintAndLogEx(NORMAL, " - Success: Card switches to mode2 and sends response frame."); + PrintAndLogEx(NORMAL, " - Unsuccessful: Card should not respond at all."); + PrintAndLogEx(NORMAL, "\nUsage: hf felica auth2 [-h][-i] <0102030405060708 M3c hex> <0x0102030405060809... 3DES-key hex (16-byte)>"); + PrintAndLogEx(NORMAL, " -h this help"); + PrintAndLogEx(NORMAL, " -i <0A0B0C ... hex> set custom IDm to use"); + PrintAndLogEx(NORMAL, "\nExamples: "); + PrintAndLogEx(NORMAL, " hf felica auth2 0102030405060708 AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBB"); + PrintAndLogEx(NORMAL, " hf felica auth2 -i 11100910C11BC407 0102030405060708 AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBB\n\n"); + + return PM3_SUCCESS; +} + /** * Wait for response from pm3 or timeout. * Checks if receveid bytes have a valid CRC. @@ -530,6 +554,12 @@ int send_wr_unencrypted(uint8_t flags, uint16_t datalen, uint8_t *data, bool ver } } +static void reverse_3des_key(uint8_t *master_key, int length, uint8_t *reverse_master_key){ + for(int i=0; i Date: Tue, 17 Dec 2019 13:10:06 +0100 Subject: [PATCH 1225/1854] Make style. --- client/cmdhffelica.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index a8835e1e7..1013518a8 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -313,7 +313,7 @@ static int usage_hf_felica_authentication1() { static int usage_hf_felica_authentication2() { PrintAndLogEx(NORMAL, "\nInfo: Complete mutual authentication. This command can only be executed subsquent to Authentication1" - " command."); + " command."); PrintAndLogEx(NORMAL, " - Auth2 Parameters:"); PrintAndLogEx(NORMAL, " - Manufacturer IDm: (8-byte)"); PrintAndLogEx(NORMAL, " - M3c: card challenge (8-byte)"); @@ -554,9 +554,9 @@ int send_wr_unencrypted(uint8_t flags, uint16_t datalen, uint8_t *data, bool ver } } -static void reverse_3des_key(uint8_t *master_key, int length, uint8_t *reverse_master_key){ - for(int i=0; i Date: Tue, 17 Dec 2019 13:18:00 +0100 Subject: [PATCH 1226/1854] Fix swapping. Make Style. --- client/cmdhffelica.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index 1013518a8..398b771d3 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -554,9 +554,15 @@ int send_wr_unencrypted(uint8_t flags, uint16_t datalen, uint8_t *data, bool ver } } +/** + * Reverses the master secret. Example: AA AA AA AA AA AA AA BB to BB AA AA AA AA AA AA AA + * @param master_key the secret which order will be reversed. + * @param length in bytes of the master secret. + * @param reverse_master_key output in which the reversed secret is stored. + */ static void reverse_3des_key(uint8_t *master_key, int length, uint8_t *reverse_master_key) { for (int i = 0; i < length; i++) { - reverse_master_key[i] = master_key[(length + 1) - i]; + reverse_master_key[i] = master_key[(length - 1) - i]; } }; @@ -689,7 +695,8 @@ static int CmdHFFelicaAuthentication1(const char *Cmd) { if (isKeyCorrect) { PrintAndLogEx(SUCCESS, "\nAuth1 done with correct key material! Use Auth2 now with M3C and same key"); } else { - PrintAndLogEx(INFO, "\n\nP2c: %s", sprint_hex(p2c, 8)); + PrintAndLogEx(INFO, "3DES secret (swapped decryption): %s", sprint_hex(reverse_master_key, 16)); + PrintAndLogEx(INFO, "P2c: %s", sprint_hex(p2c, 8)); PrintAndLogEx(ERR, "Can't decrypt M2C with master secret (P1c != P2c)! Probably wrong keys or wrong decryption method"); } } From 08f411de6572debda720e9b670057a1351207575 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 18 Dec 2019 10:13:41 +0100 Subject: [PATCH 1227/1854] textual --- client/luascripts/ufodump.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/luascripts/ufodump.lua b/client/luascripts/ufodump.lua index 140652492..ccf20f6b4 100644 --- a/client/luascripts/ufodump.lua +++ b/client/luascripts/ufodump.lua @@ -7,8 +7,8 @@ copyright = '' author = 'Iceman' version = 'v1.0.1' desc = [[ -This is a script that reads AZTEK iso14443a tags. -It starts from block 0, and ends at default block 20. Use 'b' to say different endblock. +This is a script that reads AZTEK ISO14443a tags. +It starts from block 0 and ends at default block 20. Use 'b' to say different endblock. xor: the first three block (0,1,2) is not XORED. The rest seems to be xored. ]] example = [[ From 0cb57915a1095dcf6dbc52aed1304389e829c1e4 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 18 Dec 2019 10:14:35 +0100 Subject: [PATCH 1228/1854] lto-cm lua script by @kevin. reworked to be more flexble. wip. --- client/luascripts/lto_dump.lua | 182 +++++++++++++++++++++++++++++++++ 1 file changed, 182 insertions(+) create mode 100644 client/luascripts/lto_dump.lua diff --git a/client/luascripts/lto_dump.lua b/client/luascripts/lto_dump.lua new file mode 100644 index 000000000..18542ce1f --- /dev/null +++ b/client/luascripts/lto_dump.lua @@ -0,0 +1,182 @@ +local cmds = require('commands') +local getopt = require('getopt') +local lib14a = require('read14a') +local utils = require('utils') + +copyright = '' +author = 'Kevin' +version = 'v1.0' +desc = [[ +This is a script that reads LTO-CM ISO14443a tags. +It starts from block 0 and ends at default block 20. +]] +example = [[ + -- default + script run lto_dump + + -- stop at block 10 + script run lto_dump -e 10 +]] +usage = [[ +script run lto_dump -h -s -e + +Arguments: + h this helptext + s start block in decimal + e end block in decimal +]] + +-- Some globals +local DEBUG = false -- the debug flag +local lshift = bit32.lshift + +--- +-- A debug printout-function +local function dbg(args) + if not DEBUG then return end + if type(args) == 'table' then + local i = 1 + while args[i] do + dbg(args[i]) + i = i+1 + end + else + print('###', args) + end +end +--- +-- This is only meant to be used when errors occur +local function oops(err) + print('ERROR:', err) + core.clearCommandBuffer() + return nil, err +end +--- +-- Usage help +local function help() + print(copyright) + print(author) + print(version) + print(desc) + print('Example usage') + print(example) + print(usage) +end + +function sendRaw(rawdata, options) + local flags = lib14a.ISO14A_COMMAND.ISO14A_NO_DISCONNECT + lib14a.ISO14A_COMMAND.ISO14A_RAW + + if options.append_crc then + flags = flags + lib14a.ISO14A_COMMAND.ISO14A_APPEND_CRC + end + + print ('flags:', string:format("%08x",flags)) + if options.bits7 then + flags = lshift(7, 16) + flags + print ('bit 7:', string:format("%08x",flags)) + end + + local command = Command:newMIX{cmd = cmds.CMD_HF_ISO14443A_READER, + arg1 = flags, -- Send raw + -- arg2 contains the length, which is half the length + -- of the ASCII-string rawdata + arg2 = string.len(rawdata)/2, + data = rawdata} + return command:sendMIX(options.ignore_response) +end + +--- +-- get hex data from response +local function getdata(usbpacket) + local cmd_response = Command.parse(usbpacket) + local len = tonumber(cmd_response.arg1) * 2 + return string.sub(tostring(cmd_response.data), 0, len) +end + +--- +-- helper function to send payloads easier +local function send(payload, options) + local res, err = sendRaw(payload, options) + if err then + lib14a.disconnect() + return oops(err) + end + core.clearCommandBuffer() + if (options.ignore_response) + return "ok", nil + else + return res, err + end +end + +--- +-- The main entry point +function main(args) + + local startblock = 0 + local endblock = 254 + + -- Read the parameters + for o, a in getopt.getopt(args, 'hs:e:') do + if o == 'h' then return help() end + if o == 's' then startblock = a end + if o == 'e' then endblock = a end + end + +-- Original loop +-- core.console("hf 14a raw -a -p -b 7 45") +-- local cmd_select = string.format("hf 14a raw -c -p 9370%s", serial_number) +-- core.console(cmd_select) +-- for i = 0, 254 do +-- local cmd_rd_blk = string.format("hf 14a raw -c -p 30 %02x", i) +-- core.console(cmd_rd_blk) +-- core.console("hf 14a raw -p 80") +-- end +-- core.console("hf 14a raw -r") + + -- Wakeup + local payload = "45" + local res, err = send(payload,{ignore_response = false, append_crc = false, bits7 = true}) + if err then return end + + -- start selecting + payload = "9320" + res, err = send(payload,{ignore_response = false, append_crc = false}) + if err then return end + + local serial_number = getdata(res) + payload = "9370"..serial_number + res, err = send(payload,{ignore_response = false, append_crc = true}) + if err then return end + + -- Show tag info + print(('\nFound LTO-CM serial number: [%s]\n'):format(serial_number)) + + -- Dumping data + print('blk | data ') + print('----+------------------') + local block_data = {} + for block = startblock, endblock do + + payload = string.format('30%02x', block) + res, err = send(payload , {ignore_response = false, append_crc = true}) + if err then return end + + payload = "80" + res, err = send(cmd , {ignore_response = true, append_crc = false}) + if err then return end + + local data = getdata(res) + print(block, data) + table.insert(block_data, data) + end + print("----+------------------") + lib14a.disconnect() + + local filename, err = utils.WriteDumpFile(serial_number, block_data) + if err then return oops(err) end + + print(string.format('\nDumped data into %s', filename)) +end + +main(args) \ No newline at end of file From 39b765852809947d43808a64d9d0dbdcabcd4819 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 19 Dec 2019 21:03:07 +0100 Subject: [PATCH 1229/1854] lto_dump fixes - wrong if-statement, wrong argument for 7bit --- client/luascripts/lto_dump.lua | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/client/luascripts/lto_dump.lua b/client/luascripts/lto_dump.lua index 18542ce1f..7d938e060 100644 --- a/client/luascripts/lto_dump.lua +++ b/client/luascripts/lto_dump.lua @@ -5,7 +5,7 @@ local utils = require('utils') copyright = '' author = 'Kevin' -version = 'v1.0' +version = 'v1.0.1' desc = [[ This is a script that reads LTO-CM ISO14443a tags. It starts from block 0 and ends at default block 20. @@ -29,7 +29,7 @@ Arguments: -- Some globals local DEBUG = false -- the debug flag local lshift = bit32.lshift - +local band = bit32.band --- -- A debug printout-function local function dbg(args) @@ -63,24 +63,24 @@ local function help() print(usage) end -function sendRaw(rawdata, options) +local function sendRaw(rawdata, options) local flags = lib14a.ISO14A_COMMAND.ISO14A_NO_DISCONNECT + lib14a.ISO14A_COMMAND.ISO14A_RAW if options.append_crc then flags = flags + lib14a.ISO14A_COMMAND.ISO14A_APPEND_CRC end - - print ('flags:', string:format("%08x",flags)) + + local arg2 = #rawdata / 2 if options.bits7 then - flags = lshift(7, 16) + flags - print ('bit 7:', string:format("%08x",flags)) + arg2 = arg2 + tonumber(lshift(7, 16)) +-- print('bit 7:', ("%08x"):format(arg2)) end local command = Command:newMIX{cmd = cmds.CMD_HF_ISO14443A_READER, arg1 = flags, -- Send raw -- arg2 contains the length, which is half the length -- of the ASCII-string rawdata - arg2 = string.len(rawdata)/2, + arg2 = arg2, data = rawdata} return command:sendMIX(options.ignore_response) end @@ -102,7 +102,7 @@ local function send(payload, options) return oops(err) end core.clearCommandBuffer() - if (options.ignore_response) + if options.ignore_response then return "ok", nil else return res, err @@ -115,7 +115,6 @@ function main(args) local startblock = 0 local endblock = 254 - -- Read the parameters for o, a in getopt.getopt(args, 'hs:e:') do if o == 'h' then return help() end @@ -163,7 +162,7 @@ function main(args) if err then return end payload = "80" - res, err = send(cmd , {ignore_response = true, append_crc = false}) + res, err = send(payload, {ignore_response = true, append_crc = false}) if err then return end local data = getdata(res) @@ -179,4 +178,4 @@ function main(args) print(string.format('\nDumped data into %s', filename)) end -main(args) \ No newline at end of file +main(args) From d3723c2649ffd72302149dd2d33cd0995949ab48 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 19 Dec 2019 21:59:45 +0100 Subject: [PATCH 1230/1854] lto_dump - added 14a connect, no_select options --- client/luascripts/lto_dump.lua | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/client/luascripts/lto_dump.lua b/client/luascripts/lto_dump.lua index 7d938e060..ccf0a678e 100644 --- a/client/luascripts/lto_dump.lua +++ b/client/luascripts/lto_dump.lua @@ -64,8 +64,17 @@ local function help() end local function sendRaw(rawdata, options) + local flags = lib14a.ISO14A_COMMAND.ISO14A_NO_DISCONNECT + lib14a.ISO14A_COMMAND.ISO14A_RAW + if options.connect then + flags = flags + lib14a.ISO14A_COMMAND.ISO14A_CONNECT + end + + if options.no_select then + flags = flags + lib14a.ISO14A_COMMAND.ISO14A_NO_SELECT + end + if options.append_crc then flags = flags + lib14a.ISO14A_COMMAND.ISO14A_APPEND_CRC end @@ -73,7 +82,7 @@ local function sendRaw(rawdata, options) local arg2 = #rawdata / 2 if options.bits7 then arg2 = arg2 + tonumber(lshift(7, 16)) --- print('bit 7:', ("%08x"):format(arg2)) + print('bit 7:', ("%08x %08x"):format(flags, arg2)) end local command = Command:newMIX{cmd = cmds.CMD_HF_ISO14443A_READER, @@ -135,8 +144,8 @@ function main(args) -- Wakeup local payload = "45" - local res, err = send(payload,{ignore_response = false, append_crc = false, bits7 = true}) - if err then return end + local res, err = send(payload,{connect = true, no_select = true, ignore_response = false, append_crc = false, bits7 = true}) + if not err then return end -- start selecting payload = "9320" From 72d51a7774cf141107d955c706e6ac010cdc5258 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 19 Dec 2019 22:11:35 +0100 Subject: [PATCH 1231/1854] more fixes --- client/luascripts/lto_dump.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/luascripts/lto_dump.lua b/client/luascripts/lto_dump.lua index ccf0a678e..9fda6ee1c 100644 --- a/client/luascripts/lto_dump.lua +++ b/client/luascripts/lto_dump.lua @@ -8,7 +8,7 @@ author = 'Kevin' version = 'v1.0.1' desc = [[ This is a script that reads LTO-CM ISO14443a tags. -It starts from block 0 and ends at default block 20. +It starts from block 0 and ends at default block 254. ]] example = [[ -- default @@ -82,7 +82,6 @@ local function sendRaw(rawdata, options) local arg2 = #rawdata / 2 if options.bits7 then arg2 = arg2 + tonumber(lshift(7, 16)) - print('bit 7:', ("%08x %08x"):format(flags, arg2)) end local command = Command:newMIX{cmd = cmds.CMD_HF_ISO14443A_READER, @@ -145,7 +144,7 @@ function main(args) -- Wakeup local payload = "45" local res, err = send(payload,{connect = true, no_select = true, ignore_response = false, append_crc = false, bits7 = true}) - if not err then return end + if err then return end -- start selecting payload = "9320" @@ -169,12 +168,13 @@ function main(args) payload = string.format('30%02x', block) res, err = send(payload , {ignore_response = false, append_crc = true}) if err then return end + + local data = getdata(res) payload = "80" res, err = send(payload, {ignore_response = true, append_crc = false}) if err then return end - local data = getdata(res) print(block, data) table.insert(block_data, data) end From cbff5bcace3ec7138980988891bcf8ba342bc940 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 19 Dec 2019 22:24:03 +0100 Subject: [PATCH 1232/1854] fixng the read command 0-31bytes --- client/luascripts/lto_dump.lua | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/client/luascripts/lto_dump.lua b/client/luascripts/lto_dump.lua index 9fda6ee1c..5280e99d9 100644 --- a/client/luascripts/lto_dump.lua +++ b/client/luascripts/lto_dump.lua @@ -169,14 +169,16 @@ function main(args) res, err = send(payload , {ignore_response = false, append_crc = true}) if err then return end - local data = getdata(res) + local d0_d15 = getdata(res) payload = "80" - res, err = send(payload, {ignore_response = true, append_crc = false}) + res, err = send(payload, {ignore_response = false, append_crc = false}) if err then return end - print(block, data) - table.insert(block_data, data) + local d16_d31 = getdata(res) + + print(block, d0_d15, d16_d31) + table.insert(block_data, d0_d15..d16_31) end print("----+------------------") lib14a.disconnect() From 46783e519ae9ac426e1f40cbe24c3e2ed5539727 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 19 Dec 2019 22:32:00 +0100 Subject: [PATCH 1233/1854] removing some crc --- client/luascripts/lto_dump.lua | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/client/luascripts/lto_dump.lua b/client/luascripts/lto_dump.lua index 5280e99d9..0ecb07ef6 100644 --- a/client/luascripts/lto_dump.lua +++ b/client/luascripts/lto_dump.lua @@ -172,11 +172,15 @@ function main(args) local d0_d15 = getdata(res) payload = "80" - res, err = send(payload, {ignore_response = false, append_crc = false}) + res, err = send(payload, {ignore_response = false, append_crc = true}) if err then return end local d16_d31 = getdata(res) + -- remove crc bytes + d0_d15 = string.sub(d0_d15, 0, #d0_d15 - 4) + d16_d31 = string.sub(d16_d31, 0, #d16_d31 - 4) + print(block, d0_d15, d16_d31) table.insert(block_data, d0_d15..d16_31) end From 818de78a1c68cb015dc2527106a04d98d9305184 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 19 Dec 2019 22:34:07 +0100 Subject: [PATCH 1234/1854] fix wrong vars name --- client/luascripts/lto_dump.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/luascripts/lto_dump.lua b/client/luascripts/lto_dump.lua index 0ecb07ef6..03982cee1 100644 --- a/client/luascripts/lto_dump.lua +++ b/client/luascripts/lto_dump.lua @@ -182,7 +182,7 @@ function main(args) d16_d31 = string.sub(d16_d31, 0, #d16_d31 - 4) print(block, d0_d15, d16_d31) - table.insert(block_data, d0_d15..d16_31) + table.insert(block_data, d0_d15..d16_d31) end print("----+------------------") lib14a.disconnect() From 25b2a8b06ba42a5e6a412ed72592dfe9b3dacdce Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 19 Dec 2019 22:51:41 +0100 Subject: [PATCH 1235/1854] nice output --- client/luascripts/lto_dump.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/luascripts/lto_dump.lua b/client/luascripts/lto_dump.lua index 03982cee1..456cb2cb1 100644 --- a/client/luascripts/lto_dump.lua +++ b/client/luascripts/lto_dump.lua @@ -181,7 +181,7 @@ function main(args) d0_d15 = string.sub(d0_d15, 0, #d0_d15 - 4) d16_d31 = string.sub(d16_d31, 0, #d16_d31 - 4) - print(block, d0_d15, d16_d31) + print(block, d0_d15..d16_d31) table.insert(block_data, d0_d15..d16_d31) end print("----+------------------") From 85170f914e577a26916584d02af8233a816ee9ec Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 20 Dec 2019 11:19:58 +0100 Subject: [PATCH 1236/1854] b0 doesnt use crc --- client/luascripts/lto_dump.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/luascripts/lto_dump.lua b/client/luascripts/lto_dump.lua index 456cb2cb1..2e8510129 100644 --- a/client/luascripts/lto_dump.lua +++ b/client/luascripts/lto_dump.lua @@ -172,7 +172,7 @@ function main(args) local d0_d15 = getdata(res) payload = "80" - res, err = send(payload, {ignore_response = false, append_crc = true}) + res, err = send(payload, {ignore_response = false, append_crc = false}) if err then return end local d16_d31 = getdata(res) From 3ddf7a0ce550f7d26b0405e65eb0d4d8c11988df Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 20 Dec 2019 11:23:27 +0100 Subject: [PATCH 1237/1854] iso15 - add some annotation for write mulit --- client/cmdhflist.c | 3 +++ include/protocols.h | 2 ++ 2 files changed, 5 insertions(+) diff --git a/client/cmdhflist.c b/client/cmdhflist.c index 9f1d9ce23..7a46b5deb 100644 --- a/client/cmdhflist.c +++ b/client/cmdhflist.c @@ -404,6 +404,9 @@ void annotateIso15693(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) { case ISO15693_READ_MULTI_BLOCK: snprintf(exp, size, "READ_MULTI_BLOCK"); return; + case ISO15693_WRITE_MULTI_BLOCK: + snprintf(exp, size, "WRITE_MULTI_BLOCK"); + return; case ISO15693_SELECT: snprintf(exp, size, "SELECT"); return; diff --git a/include/protocols.h b/include/protocols.h index 8018ae62e..691d2757e 100644 --- a/include/protocols.h +++ b/include/protocols.h @@ -56,6 +56,7 @@ ISO15693 21 = Write Block (usage: 0221+1byte block number+4bytes data+2bytes ISO15693-CRC - answer: 4bytes) 22 = Lock Block 23 = Read Multiple Blocks (usage: 0223+1byte 1st block to read+1byte last block to read+2bytes ISO15693-CRC) + 24 = Write Multiple Blocks 25 = Select 26 = Reset to Ready 27 = Write AFI @@ -243,6 +244,7 @@ ISO 7816-4 Basic interindustry commands. For command APDU's. #define ISO15693_WRITEBLOCK 0x21 #define ISO15693_LOCKBLOCK 0x22 #define ISO15693_READ_MULTI_BLOCK 0x23 +#define ISO15693_WRITE_MULTI_BLOCK 0x24 #define ISO15693_SELECT 0x25 #define ISO15693_RESET_TO_READY 0x26 #define ISO15693_WRITE_AFI 0x27 From 203a70d5da548948332f733c332802fcb1065240 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 20 Dec 2019 12:39:54 +0100 Subject: [PATCH 1238/1854] textual --- CHANGELOG.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e1f3cf2c7..6fc26d884 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,20 +3,22 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Added ISO15_WRITE annotation (@pwipiw) + - Added `lto_dump.lua` @kevin - Added `hf mf cwipe` magic chinese card (gen1a) wipe to default state (@merlokk) - Added 'pm3_mf7b_wipe.py' python script. Wipes magic S70 7B Gen2 card. (@vulnersCom) - Added `hf mfp chk` Mifare plus command for check keys from public keys list, from dictionary or 1 and 2-byte bruteforce (@merlokk) - Change `hf 15` - some refactoring (@grspy) - Added `hf 15 writeafi` and `hf 15 writedsfid` (@grspy) - Added detailed info for SLIX2 tags in `hf 15 info` (@grspy) - - Fix hf list felica and hf felica sniff (@7homasSutter) - - Added hf felica wrunencrypted (@7homasSutter) - - Added hf felica rdunencrypted (@7homasSutter) - - Added hf felica rqresponse (@7homasSutter) - - Added hf felica rqservice (@7homasSutter) + - Fix `hf list felica` and `hf felica sniff` (@7homasSutter) + - Added `hf felica wrunencrypted` (@7homasSutter) + - Added `hf felica rdunencrypted` (@7homasSutter) + - Added `hf felica rqresponse` (@7homasSutter) + - Added `hf felica rqservice` (@7homasSutter) - Added polling for felica standard (@7homasSutter) - - Added lf t55xx dump save and lf t55xx restore for .bin and .eml files (@mwalker33) - - Added lf t55xx detected to try without password first (@mwalker33) + - Added `lf t55xx dump save` and `lf t55xx restore` for .bin and .eml files (@mwalker33) + - Added `lf t55xx detected` to try without password first (@mwalker33) - Chg `lf indala read` - added indala 26bit decoding (@martinbeier) - Chg `lf t55xx detect` to try without password first (@mwalker33) - Display high bit for detected Kastle HIDs to allow `lf hid clone [id]` to work properly (@swg0101) From 337a1d1dca6089efcab4bd57b3561b66469cae19 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 21 Dec 2019 18:17:03 +0100 Subject: [PATCH 1239/1854] more --- client/dictionaries/mfc_default_keys.dic | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index eeecff9ba..dda7a5126 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -1035,3 +1035,10 @@ bb2c0007d022 # Hotel Berlin Classic room B KEY # 0734bfb93dab 85a438f72a8a +# +# Data from forum, Chinese hotel +58ac17bf3629 +b62307b62307 +# +a2a3cca2a3cc + From 286333ca912ebc8f992236f7edce73d7e32890d9 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 22 Dec 2019 11:16:59 +0100 Subject: [PATCH 1240/1854] add: hf lto info - skeleton to add LTO-CM (Cartridge memort) to PM3 --- client/Makefile | 3 +- client/cmdhf.c | 12 +++ client/cmdhflto.c | 199 ++++++++++++++++++++++++++++++++++++++++++++++ client/cmdhflto.h | 20 +++++ 4 files changed, 233 insertions(+), 1 deletion(-) create mode 100644 client/cmdhflto.c create mode 100644 client/cmdhflto.h diff --git a/client/Makefile b/client/Makefile index 4babb528f..23c8359b9 100644 --- a/client/Makefile +++ b/client/Makefile @@ -22,7 +22,7 @@ vpath %.dic dictionaries OBJDIR = obj LDLIBS ?= -L/usr/local/lib -LDLIBS += -lreadline -lpthread -lm +LDLIBS += -lreadline -lsndfile -lpthread -lm # RPi Zero gcc requires -latomic # but MacOSX /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld @@ -204,6 +204,7 @@ CMDSRCS = crapto1/crapto1.c \ cmdhffido.c \ cmdhffelica.c \ cmdhfthinfilm.c \ + cmdhflto.c \ cmdhw.c \ cmdlf.c \ cmdlfawid.c \ diff --git a/client/cmdhf.c b/client/cmdhf.c index 06ad64317..6ef589d26 100644 --- a/client/cmdhf.c +++ b/client/cmdhf.c @@ -1,6 +1,8 @@ //----------------------------------------------------------------------------- // Copyright (C) 2010 iZsh // Merlok - 2017 +// Doegox - 2019 +// Iceman - 2019 // // This code is licensed to you under the terms of the GNU GPL, version 2 or, // at your option, any later version. See the LICENSE.txt file for the text of @@ -29,6 +31,7 @@ #include "cmdhffelica.h" // ISO18092 / FeliCa #include "cmdhffido.h" // FIDO authenticators #include "cmdhfthinfilm.h" // Thinfilm +#include "cmdhflto.h" // LTO-CM #include "cmdtrace.h" // trace list #include "ui.h" @@ -88,6 +91,15 @@ int CmdHFSearch(const char *Cmd) { } } + PROMPT_CLEARLINE; + PrintAndLogEx(INPLACE, "Searching for LTO-CM tag..."); + if (IfPm3Iso14443a()) { + if (infoLTO(false) == PM3_SUCCESS) { + PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("LTO-CM tag") " found\n"); + return PM3_SUCCESS; + } + } + PROMPT_CLEARLINE; PrintAndLogEx(INPLACE, "Searching for ISO14443-A tag..."); if (IfPm3Iso14443a()) { diff --git a/client/cmdhflto.c b/client/cmdhflto.c new file mode 100644 index 000000000..828fb0268 --- /dev/null +++ b/client/cmdhflto.c @@ -0,0 +1,199 @@ +//----------------------------------------------------------------------------- +// Copyright (C) 2019 iceman +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// LTO-CM commands +// LTO Cartridge memory +//----------------------------------------------------------------------------- +#include "cmdhflto.h" +#include +#include +#include +#include +#include "cmdparser.h" // command_t +#include "comms.h" +#include "cmdtrace.h" +#include "crc16.h" +#include "ui.h" +#include "cmdhf14a.h" +#include "protocols.h" + +static int CmdHelp(const char *Cmd); + +static int usage_lto_info(void) { + PrintAndLogEx(NORMAL, "Usage: hf lto info [h]"); + PrintAndLogEx(NORMAL, "Options:"); + PrintAndLogEx(NORMAL, " h this help"); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Examples:"); + PrintAndLogEx(NORMAL, " hf lto info"); + return PM3_SUCCESS; +} + +static void lto_switch_off_field(void) { + SendCommandMIX(CMD_HF_ISO14443A_READER, 0, 0, 0, NULL, 0); +} + +static void lto_switch_on_field(void) { + SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT | ISO14A_NO_SELECT | ISO14A_NO_DISCONNECT | ISO14A_NO_RATS, 0, 0, NULL, 0); +} + +// send a raw LTO-CM command, returns the length of the response (0 in case of error) +static int lto_send_cmd_raw(uint8_t *cmd, uint8_t len, uint8_t *response, uint16_t *response_len, bool verbose) { + + SendCommandOLD(CMD_HF_ISO14443A_READER, ISO14A_RAW | ISO14A_NO_DISCONNECT | ISO14A_NO_RATS, len, 0, cmd, len); + PacketResponseNG resp; + + if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { + if (verbose) PrintAndLogEx(WARNING, "timeout while waiting for reply."); + return PM3_ETIMEOUT; + } + + if (resp.oldarg[0] == *response_len) { + *response_len = resp.oldarg[0]; + + PrintAndLogEx(INFO, "%s", sprint_hex(resp.data.asBytes, *response_len)); + if (*response_len > 0) { + memcpy(response, resp.data.asBytes, *response_len); + } + } else { + if (verbose) PrintAndLogEx(WARNING, "Wrong response length (%d != %" PRIu64 ")", *response_len, resp.oldarg[0]); + return PM3_ESOFT; + } + return PM3_SUCCESS; +} + + +// select a LTO-CM tag. Send WUPA and RID. +static int topaz_select(uint8_t *id_response, uint8_t id_len, bool verbose) { + // Todo: implement anticollision + + uint8_t resp[] = {0,0}; + uint16_t resp_len; + uint8_t wupa_cmd[] = {LTO_REQ_STANDARD}; + uint8_t select_cmd[] = {LTO_SELECT, 0x20}; + uint8_t select_1_cmd[] = {LTO_SELECT_1, 0x70, 0, 0, 0, 0, 0}; + + lto_switch_on_field(); + + resp_len = 2; + int status = lto_send_cmd_raw(wupa_cmd, sizeof(wupa_cmd), resp, &resp_len, verbose); + if (status == PM3_ETIMEOUT || status == PM3_ESOFT) { + lto_switch_off_field(); + return PM3_ESOFT; // WUPA failed + } + + resp_len = id_len; + status = lto_send_cmd_raw(select_cmd, sizeof(select_cmd), id_response, &resp_len, verbose); + if (status == PM3_ETIMEOUT || status == PM3_ESOFT) { + lto_switch_off_field(); + return PM3_EWRONGANSVER; // SELECT failed + } + + resp_len = 1; + status = lto_send_cmd_raw(select_1_cmd, sizeof(select_1_cmd), resp, &resp_len, verbose); + if (status == PM3_ETIMEOUT || status == PM3_ESOFT || resp[0] != 0x0A) { + lto_switch_off_field(); + return PM3_EWRONGANSVER; // SELECT failed + } + + // tag is now INIT and SELECTED. + return PM3_SUCCESS; +} + + +static int CmdHfLTOInfo(const char *Cmd) { + + uint8_t cmdp = 0; + bool errors = false; + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { + case 'h': + return usage_lto_info(); + default: + PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } + } + + //Validations + if (errors) { + usage_lto_info(); + return PM3_EINVARG; + } + + return infoLTO(true); +} + +int infoLTO(bool verbose) { + + clearCommandBuffer(); + + uint8_t serial_number[5]; + uint8_t serial_len = 0; + + topaz_select(serial_number, serial_len, verbose); + + lto_switch_off_field(); +/* + +-- "hf 14a raw -a -p -b 7 45" +-- "hf 14a raw -c -p 9320" +-- "hf 14a raw -c -p 9370%s", serial_number +-- "disconnect" + + + SendCommandNG(CMD_HF_THINFILM_READ, NULL, 0); + PacketResponseNG resp; + if (!WaitForResponseTimeout(CMD_HF_THINFILM_READ, &resp, 1500)) { + PrintAndLogEx(WARNING, "timeout while waiting for reply."); + return PM3_ETIMEOUT; + } + + if (resp.status == PM3_SUCCESS) { + if (resp.length == 16 || resp.length == 32) { + print_barcode(resp.data.asBytes, resp.length, verbose); + } else { + if (verbose) + PrintAndLogEx(WARNING, "Response is wrong length. (%d)", resp.length); + + return PM3_ESOFT; + } + } + + return resp.status; +*/ + return PM3_SUCCESS; +} + +static int CmdHfLTOList(const char *Cmd) { + (void)Cmd; // Cmd is not used so far + CmdTraceList("14a"); +// CmdTraceList("lto"); + return PM3_SUCCESS; +} + +static command_t CommandTable[] = { + {"help", CmdHelp, AlwaysAvailable, "This help"}, + {"info", CmdHfLTOInfo, IfPm3Iso14443a, "Tag information"}, +// {"rdbl", CmdHfLTOReadBlock, IfPm3Iso14443a, "Read block"}, +// {"wrbl", CmdHfLTOWriteBlock, IfPm3Iso14443a, "Write block"}, +// {"sim", CmdHfLTOSim, IfPm3Iso14443a, " Simulate LTO-CM tag"}, + {"list", CmdHfLTOList, AlwaysAvailable, "List LTO-CM history"}, + {NULL, NULL, NULL, NULL} +}; + +static int CmdHelp(const char *Cmd) { + (void)Cmd; // Cmd is not used so far + CmdsHelp(CommandTable); + return PM3_SUCCESS; +} + +int CmdHFLTO(const char *Cmd) { + clearCommandBuffer(); + return CmdsParse(CommandTable, Cmd); +} diff --git a/client/cmdhflto.h b/client/cmdhflto.h new file mode 100644 index 000000000..52c22da0d --- /dev/null +++ b/client/cmdhflto.h @@ -0,0 +1,20 @@ +//----------------------------------------------------------------------------- +// Copyright (C) 2019 iceman +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// LTO-CM commands +//----------------------------------------------------------------------------- + +#ifndef CMDHFLTO_H__ +#define CMDHFLTO_H__ + +#include "common.h" + +int infoLTO(bool verbose); + +int CmdHFLTO(const char *Cmd); + +#endif From a4407ae9f1912ddc142ed139933efdda44ef9415 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 22 Dec 2019 11:19:06 +0100 Subject: [PATCH 1241/1854] add: saving as wave format for LF traces, thanks (@anon)\n chg: 'data save f w - reword the params to command --- client/cmddata.c | 69 ++++++++++++++++++++++++++++++++++------------ client/fileutils.c | 64 ++++++++++++++++++++++++++++++++++++++++++ client/fileutils.h | 24 ++++++++++++++++ 3 files changed, 140 insertions(+), 17 deletions(-) diff --git a/client/cmddata.c b/client/cmddata.c index cb78642b2..7af5c686e 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -1,6 +1,8 @@ //----------------------------------------------------------------------------- // Copyright (C) 2010 iZsh // +// iceman 2019 +// // This code is licensed to you under the terms of the GNU GPL, version 2 or, // at your option, any later version. See the LICENSE.txt file for the text of // the license. @@ -32,6 +34,21 @@ int g_DemodClock = 0; static int CmdHelp(const char *Cmd); +static int usage_data_save(void) { + PrintAndLogEx(NORMAL, "Save trace from graph window , i.e. the GraphBuffer"); + PrintAndLogEx(NORMAL, "This is a text file with number -127 to 127. With the option `w` you can save it as wave file"); + PrintAndLogEx(NORMAL, "Filename should be without file extension"); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Usage: data save [h] [w] [f ]"); + PrintAndLogEx(NORMAL, "Options:"); + PrintAndLogEx(NORMAL, " h this help"); + PrintAndLogEx(NORMAL, " w save as wave format (.wav)"); + PrintAndLogEx(NORMAL, " f save file name"); + PrintAndLogEx(NORMAL, "Samples:"); + PrintAndLogEx(NORMAL, " data save f mytrace - save graphbuffer to file"); + PrintAndLogEx(NORMAL, " data save f mytrace w - save graphbuffer to wave file"); + return PM3_SUCCESS; +} static int usage_data_scale(void) { PrintAndLogEx(NORMAL, "Set cursor display scale."); PrintAndLogEx(NORMAL, "Setting the scale makes the differential `dt` reading between the yellow and purple markers meaningful. "); @@ -40,8 +57,8 @@ static int usage_data_scale(void) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Usage: data scale [h] "); PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " h This help"); - PrintAndLogEx(NORMAL, " Sets scale of carrier frequency expressed in kHz"); + PrintAndLogEx(NORMAL, " h this help"); + PrintAndLogEx(NORMAL, " sets scale of carrier frequency expressed in kHz"); PrintAndLogEx(NORMAL, "Samples:"); PrintAndLogEx(NORMAL, " data scale 125 - if sampled in 125kHz"); return PM3_SUCCESS; @@ -49,7 +66,7 @@ static int usage_data_scale(void) { static int usage_data_printdemodbuf(void) { PrintAndLogEx(NORMAL, "Usage: data printdemodbuffer x o l "); PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " h This help"); + PrintAndLogEx(NORMAL, " h this help"); PrintAndLogEx(NORMAL, " i invert Demodbuffer before printing"); PrintAndLogEx(NORMAL, " x output in hex (omit for binary output)"); PrintAndLogEx(NORMAL, " o enter offset in # of bits"); @@ -1876,24 +1893,42 @@ int CmdSave(const char *Cmd) { int len = 0; char filename[FILE_PATH_SIZE] = {0x00}; + uint8_t cmdp = 0; + bool errors = false, as_wave = false, has_name = false; - len = strlen(Cmd); - if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE; - memcpy(filename, Cmd, len); - - FILE *f = fopen(filename, "w"); - if (!f) { - PrintAndLogEx(WARNING, "couldn't open '%s'", filename); - return PM3_EFILE; + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + char ctmp = tolower(param_getchar(Cmd, cmdp)); + switch (ctmp) { + case 'h': + return usage_data_save(); + case 'f': + len = param_getstr(Cmd, cmdp + 1, filename, FILE_PATH_SIZE); + if (len < 1) { + errors = true; + break; + } + has_name = true; + cmdp += 2; + break; + case 'w': + as_wave = true; + cmdp++; + break; + default: + PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } } - for (uint32_t i = 0; i < GraphTraceLen; i++) - fprintf(f, "%d\n", GraphBuffer[i]); + if (!has_name) errors = true; - fclose(f); + if (errors || cmdp == 0) return usage_data_save(); - PrintAndLogEx(SUCCESS, "saved to " _YELLOW_("'%s'"), Cmd); - return PM3_SUCCESS; + if ( as_wave ) + return saveFileWAVE(filename, GraphBuffer, GraphTraceLen); + else + return saveFilePM3(filename, GraphBuffer, GraphTraceLen); } static int CmdScale(const char *Cmd) { @@ -2269,7 +2304,7 @@ static command_t CommandTable[] = { {"printdemodbuffer", CmdPrintDemodBuff, AlwaysAvailable, "[x] [o] [l] -- print the data in the DemodBuffer - 'x' for hex output"}, {"rawdemod", CmdRawDemod, AlwaysAvailable, "[modulation] ... -see help (h option) -- Demodulate the data in the GraphBuffer and output binary"}, {"samples", CmdSamples, IfPm3Present, "[512 - 40000] -- Get raw samples for graph window (GraphBuffer)"}, - {"save", CmdSave, AlwaysAvailable, " -- Save trace (from graph window)"}, + {"save", CmdSave, AlwaysAvailable, "Save trace (from graph window)"}, {"setgraphmarkers", CmdSetGraphMarkers, AlwaysAvailable, "[orange_marker] [blue_marker] (in graph window)"}, {"scale", CmdScale, AlwaysAvailable, " -- Set cursor display scale in carrier frequency expressed in kHz"}, {"setdebugmode", CmdSetDebugMode, AlwaysAvailable, "<0|1|2> -- Set Debugging Level on client side"}, diff --git a/client/fileutils.c b/client/fileutils.c index 7c10fe50c..a56745148 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -41,6 +41,7 @@ #include #include +#include #include "pm3_cmd.h" #include "commonutil.h" @@ -399,6 +400,69 @@ out: return retval; } +int saveFileWAVE(const char *preferredName, int *data, size_t datalen) { + + if (data == NULL) return PM3_EINVARG; + char *fileName = newfilenamemcopy(preferredName, ".wav"); + if (fileName == NULL) return PM3_EMALLOC; + + int retval = PM3_SUCCESS; + + SF_INFO wave_info; + + // TODO update for other tag types + wave_info.samplerate = 125000; + wave_info.channels = 1; + wave_info.format = SF_FORMAT_WAV | SF_FORMAT_PCM_U8; + SNDFILE* wave_file = sf_open(fileName, SFM_WRITE, &wave_info); + + if (!wave_file) { + PrintAndLogEx(WARNING, "file not found or locked. "_YELLOW_("'%s'"), fileName); + retval = PM3_EFILE; + goto out; + } + + // unfortunately need to upconvert to 16-bit samples because libsndfile doesn't do 8-bit(?) + for (int i = 0; i < datalen; i++) { + short sample = data[i] * 256; + sf_write_short(wave_file, &sample, 1); + } + + sf_close(wave_file); + PrintAndLogEx(SUCCESS, "saved " _YELLOW_("%d")" bytes to wave file " _YELLOW_("'%s'"), 2 * datalen, fileName); + +out: + free(fileName); + return retval; +} + +int saveFilePM3(const char *preferredName, int *data, size_t datalen) { + + if (data == NULL) return PM3_EINVARG; + char *fileName = newfilenamemcopy(preferredName, ".pm3"); + if (fileName == NULL) return PM3_EMALLOC; + + int retval = PM3_SUCCESS; + + FILE *f = fopen(fileName, "w"); + if (!f) { + PrintAndLogEx(WARNING, "file not found or locked. "_YELLOW_("'%s'"), fileName); + retval = PM3_EFILE; + goto out; + } + + for (uint32_t i = 0; i < datalen; i++) + fprintf(f, "%d\n", data[i]); + + fflush(f); + fclose(f); + PrintAndLogEx(SUCCESS, "saved " _YELLOW_("%d")" bytes to PM3 file " _YELLOW_("'%s'"), datalen, fileName); + +out: + free(fileName); + return retval; +} + int createMfcKeyDump(uint8_t sectorsCnt, sector_t *e_sector, char *fptr) { uint8_t tmpKey[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; int i; diff --git a/client/fileutils.h b/client/fileutils.h index 523e957a7..baff10bca 100644 --- a/client/fileutils.h +++ b/client/fileutils.h @@ -112,6 +112,30 @@ int saveFileEML(const char *preferredName, uint8_t *data, size_t datalen, size_t */ int saveFileJSON(const char *preferredName, JSONFileType ftype, uint8_t *data, size_t datalen); +/** STUB + * @brief Utility function to save WAVE data to a file. This method takes a preferred name, but if that + * file already exists, it tries with another name until it finds something suitable. + * E.g. dumpdata-15.wav + * + * @param preferredName + * @param data The binary data to write to the file + * @param datalen the length of the data + * @return 0 for ok + */ +int saveFileWAVE(const char *preferredName, int *data, size_t datalen); + +/** STUB + * @brief Utility function to save PM3 data to a file. This method takes a preferred name, but if that + * file already exists, it tries with another name until it finds something suitable. + * E.g. dump_trace.pm3 + * + * @param preferredName + * @param data The binary data to write to the file + * @param datalen the length of the data + * @return 0 for ok + */ +int saveFilePM3(const char *preferredName, int *data, size_t datalen); + /** * @brief Utility function to save a keydump. * From 96d3bbc35310307b03ccfca0e8d1a21a908718ab Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 22 Dec 2019 11:20:17 +0100 Subject: [PATCH 1242/1854] chg: update instructions for dependecies. sudo apt-get install libsndfile1-dev --- .../Linux-Installation-Instructions.md | 2 +- .../Mac-OS-X-Homebrew-Installation-Instructions.md | 2 +- .../Windows-Installation-Instructions.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/md/Installation_Instructions/Linux-Installation-Instructions.md b/doc/md/Installation_Instructions/Linux-Installation-Instructions.md index d56d1056c..08c7fe474 100644 --- a/doc/md/Installation_Instructions/Linux-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Linux-Installation-Instructions.md @@ -25,7 +25,7 @@ Install the requirements ```sh sudo apt-get install --no-install-recommends git ca-certificates build-essential pkg-config \ -libreadline-dev gcc-arm-none-eabi libnewlib-dev qtbase5-dev +libreadline-dev gcc-arm-none-eabi libnewlib-dev qtbase5-dev libsndfile1-dev ``` If you don't need the graphical components of the Proxmark3 client, you can skip the installation of `qtbase5-dev`. diff --git a/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md b/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md index 76f5ee6f3..846383658 100644 --- a/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md @@ -82,7 +82,7 @@ These instructions will show how to setup the environment on OSX to the point wh 2. Install dependencies: ``` -brew install readline qt5 pkgconfig +brew install readline qt5 pkgconfig libsndfile brew install RfidResearchGroup/proxmark3/arm-none-eabi-gcc ``` diff --git a/doc/md/Installation_Instructions/Windows-Installation-Instructions.md b/doc/md/Installation_Instructions/Windows-Installation-Instructions.md index 9d94490f5..4065e0d27 100644 --- a/doc/md/Installation_Instructions/Windows-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Windows-Installation-Instructions.md @@ -77,7 +77,7 @@ Enter WSL prompt (`wsl`) and from there, follow the [Linux Installation Instruct ```sh sudo apt-get update sudo apt-get install --no-install-recommends git ca-certificates build-essential pkg-config \ -libreadline-dev gcc-arm-none-eabi libnewlib-dev qtbase5-dev +libreadline-dev gcc-arm-none-eabi libnewlib-dev qtbase5-dev libsndfile1-dev ``` If you don't need the graphical components of the Proxmark3 client, you can skip the installation of `qtbase5-dev`. From bd50760a243ac1ce3492b92d6fa9ddb7e019c4ad Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 22 Dec 2019 11:20:39 +0100 Subject: [PATCH 1243/1854] LTO-CM commands defines --- include/protocols.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/include/protocols.h b/include/protocols.h index 691d2757e..d04173557 100644 --- a/include/protocols.h +++ b/include/protocols.h @@ -593,5 +593,23 @@ ISO 7816-4 Basic interindustry commands. For command APDU's. #define HITAG2_WRITE_PAGE 0x82 // page number in bits 5 to 3, page number inverted in bit 0 and following 2 bits #define HITAG2_HALT 0x00 // left 5 bits only + +// LTO-CM commands +#define LTO_REQ_STANDARD 0x45 +#define LTO_REQ_ALL 0x4A +#define LTO_READWORD 0x40 // read 2 bytes (word) +#define LTO_READBLOCK 0x30 +#define LTO_READBLOCK_CONT 0x80 +#define LTO_SELECT 0x93 +#define LTO_SELECT_1 0x97 +#define LTO_WRITEWORD 0xB0 // write 2 bytes (word) +#define LTO_WRITEBLOCK 0xA0 +#define LTO_HALT 0x50 +#define LTO_TEST_CMD_1 0x0E +#define LTO_TEST_CMD_2 0x6C + +// 0x0A = ACK +// 0x05 = NACK + #endif // PROTOCOLS_H From 2716e2f7f429caac426301c5d56f3363b98cd7ac Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 22 Dec 2019 11:25:18 +0100 Subject: [PATCH 1244/1854] textual --- CHANGELOG.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6fc26d884..c4e0e9d35 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,10 +3,14 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Chg `data save f w` - params reworked. (@iceman1001) + - Chg `hf search` - now should detect LTO-CM tags (@iceman1001) + - Added `hf lto info` - skeleton support for LTO Cartridge memory (@iceman1001) + - Added saving as wave format (@anon) - Added ISO15_WRITE annotation (@pwipiw) - Added `lto_dump.lua` @kevin - Added `hf mf cwipe` magic chinese card (gen1a) wipe to default state (@merlokk) - - Added 'pm3_mf7b_wipe.py' python script. Wipes magic S70 7B Gen2 card. (@vulnersCom) + - Added `pm3_mf7b_wipe.py` python script. Wipes magic S70 7B Gen2 card. (@vulnersCom) - Added `hf mfp chk` Mifare plus command for check keys from public keys list, from dictionary or 1 and 2-byte bruteforce (@merlokk) - Change `hf 15` - some refactoring (@grspy) - Added `hf 15 writeafi` and `hf 15 writedsfid` (@grspy) From 3c93361ca33702fec75824a9506a5686df291e22 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 22 Dec 2019 11:29:06 +0100 Subject: [PATCH 1245/1854] adapt to libsnd.. --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index c75bffe9b..1cb60f8e9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,9 +33,11 @@ addons: packages: - gcc-arm-none-eabi - libnewlib-dev + - libsndfile1-dev homebrew: packages: - readline + - libsndfile - qt5 - RfidResearchGroup/proxmark3/arm-none-eabi-gcc taps: RfidResearchGroup/proxmark3 From 88f4de3ef9fb9f1acd0539e568265de60f7d08ba Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 22 Dec 2019 12:47:57 +0100 Subject: [PATCH 1246/1854] add: note of new wave format PCM8 --- doc/extensions_notes.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/extensions_notes.md b/doc/extensions_notes.md index 41365849b..f42823d64 100644 --- a/doc/extensions_notes.md +++ b/doc/extensions_notes.md @@ -13,7 +13,8 @@ The Proxmark3 client uses a wide range of files. Here is a brief recap to get yo | .elf | binary proxmark3 device firmware file. | | .cmd | text file, contains proxmark3 client commands used to call client with -s | | .lua | text file, contains lua script to be run inside client. or called with -l | -| .pm3 | text file, with numbers ranging 0-255 or -127 - 128. Contains trace signal data for low frequency tags (data load) | +| .pm3 | text file, with numbers ranging 0-255 or -127 - 128. Contains trace signal data for low frequency tags (data load / data save) | +| .wav | binary file, PCM8 with samplerate 125000, one channel. (data save) | .trace | binary file, contains trace log data usually from high frequency tags. (hw trace load) | | .log | text file, our log file, contains the output from almost all commands you run inside Proxmark3 client | -| .history | text file, our command log file, contains the commands you ran inside Proxmark3 client | +| .history | text file, our command log file, contains the commands you ran inside Proxmark3 client | \ No newline at end of file From ea5680dba8414da43644cbb111bfabc70bfbbac7 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 22 Dec 2019 12:51:40 +0100 Subject: [PATCH 1247/1854] style --- client/Makefile | 2 +- client/cmddata.c | 10 +++--- client/cmdhflto.c | 58 +++++++++++++++++----------------- client/fileutils.c | 8 ++--- client/luascripts/lto_dump.lua | 4 +-- 5 files changed, 41 insertions(+), 41 deletions(-) diff --git a/client/Makefile b/client/Makefile index 23c8359b9..891a8b1e5 100644 --- a/client/Makefile +++ b/client/Makefile @@ -22,7 +22,7 @@ vpath %.dic dictionaries OBJDIR = obj LDLIBS ?= -L/usr/local/lib -LDLIBS += -lreadline -lsndfile -lpthread -lm +LDLIBS += -lreadline -lsndfile -lpthread -lm # RPi Zero gcc requires -latomic # but MacOSX /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld diff --git a/client/cmddata.c b/client/cmddata.c index 7af5c686e..a9b38b105 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -37,13 +37,13 @@ static int CmdHelp(const char *Cmd); static int usage_data_save(void) { PrintAndLogEx(NORMAL, "Save trace from graph window , i.e. the GraphBuffer"); PrintAndLogEx(NORMAL, "This is a text file with number -127 to 127. With the option `w` you can save it as wave file"); - PrintAndLogEx(NORMAL, "Filename should be without file extension"); + PrintAndLogEx(NORMAL, "Filename should be without file extension"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Usage: data save [h] [w] [f ]"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h this help"); PrintAndLogEx(NORMAL, " w save as wave format (.wav)"); - PrintAndLogEx(NORMAL, " f save file name"); + PrintAndLogEx(NORMAL, " f save file name"); PrintAndLogEx(NORMAL, "Samples:"); PrintAndLogEx(NORMAL, " data save f mytrace - save graphbuffer to file"); PrintAndLogEx(NORMAL, " data save f mytrace w - save graphbuffer to wave file"); @@ -1925,10 +1925,10 @@ int CmdSave(const char *Cmd) { if (errors || cmdp == 0) return usage_data_save(); - if ( as_wave ) - return saveFileWAVE(filename, GraphBuffer, GraphTraceLen); + if (as_wave) + return saveFileWAVE(filename, GraphBuffer, GraphTraceLen); else - return saveFilePM3(filename, GraphBuffer, GraphTraceLen); + return saveFilePM3(filename, GraphBuffer, GraphTraceLen); } static int CmdScale(const char *Cmd) { diff --git a/client/cmdhflto.c b/client/cmdhflto.c index 828fb0268..0fc676edb 100644 --- a/client/cmdhflto.c +++ b/client/cmdhflto.c @@ -19,7 +19,7 @@ #include "crc16.h" #include "ui.h" #include "cmdhf14a.h" -#include "protocols.h" +#include "protocols.h" static int CmdHelp(const char *Cmd); @@ -43,8 +43,8 @@ static void lto_switch_on_field(void) { // send a raw LTO-CM command, returns the length of the response (0 in case of error) static int lto_send_cmd_raw(uint8_t *cmd, uint8_t len, uint8_t *response, uint16_t *response_len, bool verbose) { - - SendCommandOLD(CMD_HF_ISO14443A_READER, ISO14A_RAW | ISO14A_NO_DISCONNECT | ISO14A_NO_RATS, len, 0, cmd, len); + + SendCommandOLD(CMD_HF_ISO14443A_READER, ISO14A_RAW | ISO14A_NO_DISCONNECT | ISO14A_NO_RATS, len, 0, cmd, len); PacketResponseNG resp; if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { @@ -71,7 +71,7 @@ static int lto_send_cmd_raw(uint8_t *cmd, uint8_t len, uint8_t *response, uint16 static int topaz_select(uint8_t *id_response, uint8_t id_len, bool verbose) { // Todo: implement anticollision - uint8_t resp[] = {0,0}; + uint8_t resp[] = {0, 0}; uint16_t resp_len; uint8_t wupa_cmd[] = {LTO_REQ_STANDARD}; uint8_t select_cmd[] = {LTO_SELECT, 0x20}; @@ -132,41 +132,41 @@ static int CmdHfLTOInfo(const char *Cmd) { int infoLTO(bool verbose) { clearCommandBuffer(); - + uint8_t serial_number[5]; uint8_t serial_len = 0; topaz_select(serial_number, serial_len, verbose); - lto_switch_off_field(); -/* + lto_switch_off_field(); + /* --- "hf 14a raw -a -p -b 7 45" --- "hf 14a raw -c -p 9320" --- "hf 14a raw -c -p 9370%s", serial_number --- "disconnect" + -- "hf 14a raw -a -p -b 7 45" + -- "hf 14a raw -c -p 9320" + -- "hf 14a raw -c -p 9370%s", serial_number + -- "disconnect" - SendCommandNG(CMD_HF_THINFILM_READ, NULL, 0); - PacketResponseNG resp; - if (!WaitForResponseTimeout(CMD_HF_THINFILM_READ, &resp, 1500)) { - PrintAndLogEx(WARNING, "timeout while waiting for reply."); - return PM3_ETIMEOUT; - } - - if (resp.status == PM3_SUCCESS) { - if (resp.length == 16 || resp.length == 32) { - print_barcode(resp.data.asBytes, resp.length, verbose); - } else { - if (verbose) - PrintAndLogEx(WARNING, "Response is wrong length. (%d)", resp.length); - - return PM3_ESOFT; + SendCommandNG(CMD_HF_THINFILM_READ, NULL, 0); + PacketResponseNG resp; + if (!WaitForResponseTimeout(CMD_HF_THINFILM_READ, &resp, 1500)) { + PrintAndLogEx(WARNING, "timeout while waiting for reply."); + return PM3_ETIMEOUT; } - } - return resp.status; -*/ + if (resp.status == PM3_SUCCESS) { + if (resp.length == 16 || resp.length == 32) { + print_barcode(resp.data.asBytes, resp.length, verbose); + } else { + if (verbose) + PrintAndLogEx(WARNING, "Response is wrong length. (%d)", resp.length); + + return PM3_ESOFT; + } + } + + return resp.status; + */ return PM3_SUCCESS; } diff --git a/client/fileutils.c b/client/fileutils.c index a56745148..74cd6ab21 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -401,20 +401,20 @@ out: } int saveFileWAVE(const char *preferredName, int *data, size_t datalen) { - + if (data == NULL) return PM3_EINVARG; char *fileName = newfilenamemcopy(preferredName, ".wav"); if (fileName == NULL) return PM3_EMALLOC; int retval = PM3_SUCCESS; - + SF_INFO wave_info; // TODO update for other tag types wave_info.samplerate = 125000; wave_info.channels = 1; wave_info.format = SF_FORMAT_WAV | SF_FORMAT_PCM_U8; - SNDFILE* wave_file = sf_open(fileName, SFM_WRITE, &wave_info); + SNDFILE *wave_file = sf_open(fileName, SFM_WRITE, &wave_info); if (!wave_file) { PrintAndLogEx(WARNING, "file not found or locked. "_YELLOW_("'%s'"), fileName); @@ -437,7 +437,7 @@ out: } int saveFilePM3(const char *preferredName, int *data, size_t datalen) { - + if (data == NULL) return PM3_EINVARG; char *fileName = newfilenamemcopy(preferredName, ".pm3"); if (fileName == NULL) return PM3_EMALLOC; diff --git a/client/luascripts/lto_dump.lua b/client/luascripts/lto_dump.lua index 2e8510129..a384a4f9b 100644 --- a/client/luascripts/lto_dump.lua +++ b/client/luascripts/lto_dump.lua @@ -78,7 +78,7 @@ local function sendRaw(rawdata, options) if options.append_crc then flags = flags + lib14a.ISO14A_COMMAND.ISO14A_APPEND_CRC end - + local arg2 = #rawdata / 2 if options.bits7 then arg2 = arg2 + tonumber(lshift(7, 16)) @@ -170,7 +170,7 @@ function main(args) if err then return end local d0_d15 = getdata(res) - + payload = "80" res, err = send(payload, {ignore_response = false, append_crc = false}) if err then return end From 66426cee1ec60698348f46f9c8dcb22a6ab4a51c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 22 Dec 2019 12:56:51 +0100 Subject: [PATCH 1248/1854] chg: - adapt to new data save parameter --- client/cmdmain.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdmain.c b/client/cmdmain.c index 802d09fa9..06f44e1aa 100644 --- a/client/cmdmain.c +++ b/client/cmdmain.c @@ -96,7 +96,7 @@ static int CmdAuto(const char *Cmd) { CmdPlot(""); lf_read(true, 40000); char *fname = calloc(100, sizeof(uint8_t)); - AppendDate(fname, 100, "lf_unknown_%Y-%m-%d_%H:%M.pm3"); + AppendDate(fname, 100, "f lf_unknown_%Y-%m-%d_%H:%M"); CmdSave(fname); free(fname); return PM3_SUCCESS; From a098fb948544899b923bc6b6b4a31c23fd9cab2a Mon Sep 17 00:00:00 2001 From: Iceman Date: Sun, 22 Dec 2019 21:39:27 +0100 Subject: [PATCH 1249/1854] Update Linux-Installation-Instructions.md add libsndfile for ArchLinux / Fedora (@doegox ) --- .../Linux-Installation-Instructions.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/md/Installation_Instructions/Linux-Installation-Instructions.md b/doc/md/Installation_Instructions/Linux-Installation-Instructions.md index 08c7fe474..b48b8e9f5 100644 --- a/doc/md/Installation_Instructions/Linux-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Linux-Installation-Instructions.md @@ -35,7 +35,7 @@ If you get some (non blocking) error at runtime such as _Gtk-Message: Failed to ## On ArchLinux ```sh -sudo pacman -Sy base-devel readline arm-none-eabi-gcc arm-none-eabi-newlib git --needed +sudo pacman -Sy base-devel readline arm-none-eabi-gcc arm-none-eabi-newlib libsndfile git --needed ``` If you want graphical output (such as in `hw tune`): ```sh @@ -45,7 +45,7 @@ sudo pacman -Su qt5-base ## On Fedora ```sh -sudo dnf install git make gcc gcc-c++ arm-none-eabi-gcc-cs arm-none-eabi-newlib readline-devel qt5-qtbase-devel libatomic +sudo dnf install git make gcc gcc-c++ arm-none-eabi-gcc-cs arm-none-eabi-newlib readline-devel qt5-qtbase-devel libatomic libsndfile ``` If you don't need the graphical components of the Proxmark3 client, you can skip the installation of `qt5-qtbase-devel`. From 9a68c524389f240e6d104488ebe4326fb7bdc111 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 23 Dec 2019 10:41:54 +0100 Subject: [PATCH 1250/1854] inline some compare --- client/mifare/mfkey.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/mifare/mfkey.c b/client/mifare/mfkey.c index ee0c9f052..7d04762b8 100644 --- a/client/mifare/mfkey.c +++ b/client/mifare/mfkey.c @@ -14,7 +14,7 @@ #include "crapto1/crapto1.h" // MIFARE -int compare_uint64(const void *a, const void *b) { +int inline compare_uint64(const void *a, const void *b) { if (*(uint64_t *)b == *(uint64_t *)a) return 0; if (*(uint64_t *)b < * (uint64_t *)a) return 1; return -1; From 07b3b6ed4edd3aaf724797f3f77c76344688d263 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 23 Dec 2019 10:42:42 +0100 Subject: [PATCH 1251/1854] textual --- client/mifare/mifarehost.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/mifare/mifarehost.c b/client/mifare/mifarehost.c index 86676696d..2aa56507c 100644 --- a/client/mifare/mifarehost.c +++ b/client/mifare/mifarehost.c @@ -478,7 +478,7 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, free(statelists[1].head.slhead); num_to_bytes(key64, 6, resultKey); - PrintAndLogEx(SUCCESS, "target block:%3u key type: %c -- found valid key [%012" PRIx64 "]", + PrintAndLogEx(SUCCESS, "target block:%3u key type: %c -- found valid key [ %012" PRIx64 " ]", (uint16_t)resp.oldarg[2] & 0xff, (resp.oldarg[2] >> 8) ? 'B' : 'A', key64 From a6a48f0e6d294ba7432076a93efa03c274489000 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 23 Dec 2019 15:23:04 +0100 Subject: [PATCH 1252/1854] Chg 'hf 14a info' - static/fixed nonce detection --- armsrc/appmain.c | 4 +++ armsrc/mifarecmd.c | 51 ++++++++++++++++++++++++++++++++++++++ armsrc/mifarecmd.h | 1 + client/mifare/mifarehost.c | 28 +++++++++++++++++++++ client/mifare/mifarehost.h | 1 + include/pm3_cmd.h | 1 + 6 files changed, 86 insertions(+) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index ef4dc6a6c..62feed4d0 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1251,6 +1251,10 @@ static void PacketReceived(PacketCommandNG *packet) { MifareU_Otp_Tearoff(); break; } + case CMD_HF_MIFARE_STATIC_NONCE: { + MifareHasStaticNonce(); + break; + } #endif #ifdef WITH_NFCBARCODE diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index ea7e8482a..d0dd27be8 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -2057,6 +2057,57 @@ OUT: BigBuf_Clear_ext(false); } +void MifareHasStaticNonce() { + + // variables + int retval = PM3_SUCCESS, len; + + uint32_t nt = 0 ; + uint8_t rec[1] = {0x00}; + uint8_t recpar[1] = {0x00}; + uint8_t *uid = BigBuf_malloc(10); + uint8_t data[1] = {0x00}; + + struct Crypto1State mpcs = {0, 0}; + struct Crypto1State *pcs; + pcs = &mpcs; + iso14a_card_select_t card_info; + + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + + for (int i = 0; i < 3; i++) { + if (!iso14443a_select_card(uid, &card_info, NULL, true, 0, true)) { + retval = PM3_ESOFT; + goto OUT; + } + + // Transmit MIFARE_CLASSIC_AUTH + len = mifare_sendcmd_short(pcs, false, 0x60, 0, rec, recpar, NULL); + if (len != 4) { + retval = PM3_ESOFT; + goto OUT; + } + + // Save the tag nonce (nt) + if (nt == bytes_to_num(rec, 4)) { + data[0]++; + } + + nt = bytes_to_num(rec, 4); + + CHK_TIMEOUT(); + } + +OUT: + reply_ng(CMD_HF_MIFARE_STATIC_NONCE, retval, data, sizeof(data)); + // turns off + OnSuccessMagic(); + BigBuf_free(); + BigBuf_Clear_ext(false); + + crypto1_deinit(pcs); +} + void OnSuccessMagic() { FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); diff --git a/armsrc/mifarecmd.h b/armsrc/mifarecmd.h index 6b730fb58..2cb22d28b 100644 --- a/armsrc/mifarecmd.h +++ b/armsrc/mifarecmd.h @@ -39,6 +39,7 @@ int MifareECardLoadExt(uint8_t numSectors, uint8_t keyType); void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain); // Work with "magic Chinese" card void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain); void MifareCIdent(); // is "magic chinese" card? +void MifareHasStaticNonce(); // Has the tag a static nonce? void MifareSetMod(uint8_t *datain); void MifareUSetPwd(uint8_t arg0, uint8_t *datain); diff --git a/client/mifare/mifarehost.c b/client/mifare/mifarehost.c index 2aa56507c..8017af076 100644 --- a/client/mifare/mifarehost.c +++ b/client/mifare/mifarehost.c @@ -1132,6 +1132,34 @@ int detect_classic_nackbug(bool verbose) { } return PM3_SUCCESS; } + +/* Detect Mifare Classic Static / Fixed nonce +detects special magic cards that has a static / fixed nonce +returns: +0 = has normal nonce +1 = has static/fixed nonce +2 = cmd failed +*/ +int detect_classic_static_nonce(void) { + + clearCommandBuffer(); + SendCommandNG(CMD_HF_MIFARE_STATIC_NONCE, NULL, 0); + PacketResponseNG resp; + + if (WaitForResponseTimeout(CMD_HF_MIFARE_STATIC_NONCE, &resp, 500)) { + + if (resp.status == PM3_ESOFT) + return 2; + + if (resp.data.asBytes[0] == 0) + return 0; + + if (resp.data.asBytes[0] != 0) + return 1; + } + return 2; +} + /* try to see if card responses to "chinese magic backdoor" commands. */ void detect_classic_magic(void) { diff --git a/client/mifare/mifarehost.h b/client/mifare/mifarehost.h index 50ed9d8e2..d81595942 100644 --- a/client/mifare/mifarehost.h +++ b/client/mifare/mifarehost.h @@ -90,5 +90,6 @@ int tryDecryptWord(uint32_t nt, uint32_t ar_enc, uint32_t at_enc, uint8_t *data, int detect_classic_prng(void); int detect_classic_nackbug(bool verbose); void detect_classic_magic(void); +int detect_classic_static_nonce(void); void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *data, int len, bool isEncrypted); #endif diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index e775b3413..64a0c5fd1 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -507,6 +507,7 @@ typedef struct { #define CMD_HF_DESFIRE_COMMAND 0x072e #define CMD_HF_MIFARE_NACK_DETECT 0x0730 +#define CMD_HF_MIFARE_STATIC_NONCE 0x0731 // MFU OTP TearOff #define CMD_HF_MFU_OTP_TEAROFF 0x0740 From ed3e0895b5e1e161533ea7faf30a967effbf3cf2 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 23 Dec 2019 22:00:34 +0100 Subject: [PATCH 1253/1854] hook it up --- client/cmdhf14a.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index 4aac73855..6744916f7 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -1598,6 +1598,12 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { if (do_nack_test) detect_classic_nackbug(!verbose); + + res = detect_classic_static_nonce(); + if (res == 1) + PrintAndLogEx(SUCCESS, "Static/Fixed nonce detected"); + if (res == 2 && verbose) + PrintAndLogEx(SUCCESS, "Static/Fixed nonce detection failed"); } return select_status; From 15cafbe6c28f5dde4795c78d4f4236ea8dba61c2 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 23 Dec 2019 22:24:11 +0100 Subject: [PATCH 1254/1854] fix: hw search for lto --- client/cmdhflto.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/client/cmdhflto.c b/client/cmdhflto.c index 0fc676edb..8a1e914aa 100644 --- a/client/cmdhflto.c +++ b/client/cmdhflto.c @@ -68,7 +68,7 @@ static int lto_send_cmd_raw(uint8_t *cmd, uint8_t len, uint8_t *response, uint16 // select a LTO-CM tag. Send WUPA and RID. -static int topaz_select(uint8_t *id_response, uint8_t id_len, bool verbose) { +static int lto_select(uint8_t *id_response, uint8_t id_len, bool verbose) { // Todo: implement anticollision uint8_t resp[] = {0, 0}; @@ -136,7 +136,7 @@ int infoLTO(bool verbose) { uint8_t serial_number[5]; uint8_t serial_len = 0; - topaz_select(serial_number, serial_len, verbose); + int ret_val = lto_select(serial_number, serial_len, verbose); lto_switch_off_field(); /* @@ -167,7 +167,7 @@ int infoLTO(bool verbose) { return resp.status; */ - return PM3_SUCCESS; + return ret_val; } static int CmdHfLTOList(const char *Cmd) { @@ -197,3 +197,4 @@ int CmdHFLTO(const char *Cmd) { clearCommandBuffer(); return CmdsParse(CommandTable, Cmd); } + From db32e20554a1d47245c06832beb961cecb9fde30 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 23 Dec 2019 22:24:45 +0100 Subject: [PATCH 1255/1854] spaces --- client/cmdhf.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/client/cmdhf.c b/client/cmdhf.c index 6ef589d26..181b10858 100644 --- a/client/cmdhf.c +++ b/client/cmdhf.c @@ -86,7 +86,7 @@ int CmdHFSearch(const char *Cmd) { PrintAndLogEx(INPLACE, "Searching for ThinFilm tag..."); if (IfPm3NfcBarcode()) { if (infoThinFilm(false) == PM3_SUCCESS) { - PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Thinfilm tag") " found\n"); + PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Thinfilm tag") "found\n"); return PM3_SUCCESS; } } @@ -95,7 +95,7 @@ int CmdHFSearch(const char *Cmd) { PrintAndLogEx(INPLACE, "Searching for LTO-CM tag..."); if (IfPm3Iso14443a()) { if (infoLTO(false) == PM3_SUCCESS) { - PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("LTO-CM tag") " found\n"); + PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("LTO-CM tag") "found\n"); return PM3_SUCCESS; } } @@ -104,7 +104,7 @@ int CmdHFSearch(const char *Cmd) { PrintAndLogEx(INPLACE, "Searching for ISO14443-A tag..."); if (IfPm3Iso14443a()) { if (infoHF14A(false, false, false) > 0) { - PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("ISO14443-A tag") " found\n"); + PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("ISO14443-A tag") "found\n"); return PM3_SUCCESS; } } @@ -113,7 +113,7 @@ int CmdHFSearch(const char *Cmd) { PrintAndLogEx(INPLACE, "Searching for ISO15693 tag..."); if (IfPm3Iso15693()) { if (readHF15Uid(false)) { - PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("ISO15693 tag") " found\n"); + PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("ISO15693 tag") "found\n"); return PM3_SUCCESS; } } @@ -122,7 +122,7 @@ int CmdHFSearch(const char *Cmd) { PrintAndLogEx(INPLACE, "Searching for LEGIC tag..."); if (IfPm3Legicrf()) { if (readLegicUid(false) == PM3_SUCCESS) { - PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("LEGIC tag") " found\n"); + PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("LEGIC tag") "found\n"); return PM3_SUCCESS; } } @@ -131,7 +131,7 @@ int CmdHFSearch(const char *Cmd) { PrintAndLogEx(INPLACE, "Searching for Topaz tag..."); if (IfPm3Iso14443a()) { if (readTopazUid() == PM3_SUCCESS) { - PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Topaz tag") " found\n"); + PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Topaz tag") "found\n"); return PM3_SUCCESS; } } @@ -140,7 +140,7 @@ int CmdHFSearch(const char *Cmd) { PrintAndLogEx(INPLACE, "Searching for FeliCa tag..."); if (IfPm3Felica()) { if (readFelicaUid(false) == PM3_SUCCESS) { - PrintAndLogEx(NORMAL, "\nValid " _GREEN_("ISO18092 / FeliCa tag") " found\n"); + PrintAndLogEx(NORMAL, "\nValid " _GREEN_("ISO18092 / FeliCa tag") "found\n"); return PM3_SUCCESS; } } @@ -150,7 +150,7 @@ int CmdHFSearch(const char *Cmd) { PrintAndLogEx(INPLACE, "Searching for ISO14443-B tag..."); if (IfPm3Iso14443a()) { if (readHF14B(false) == 1) { - PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("ISO14443-B tag") " found\n"); + PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("ISO14443-B tag") "found\n"); return PM3_SUCCESS; } } @@ -159,7 +159,7 @@ int CmdHFSearch(const char *Cmd) { PrintAndLogEx(INPLACE, "Searching for iClass / PicoPass tag..."); if (IfPm3Iclass()) { if (readIclass(false, false) == 1) { - PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("iClass tag / PicoPass tag") " found\n"); + PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("iClass tag / PicoPass tag") "found\n"); return PM3_SUCCESS; } } From 1472922c9ed546a70ab0e540fe7e5ded67d52aa6 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 23 Dec 2019 22:52:50 +0100 Subject: [PATCH 1256/1854] Add: two perl scripts from https://github.com/samyk/samytools/. Thanks @samyk! \n pm3_cs8.pl converts pm3 files to wave. \npm3_amii_bin2eml.pl convert / decrypts amiiboo dumps to eml format used when simulating. --- tools/pm3_amii_bin2eml.pl | 681 ++++++++++++++++++++++++++++++++++++++ tools/pm3_cs8.pl | 43 +++ 2 files changed, 724 insertions(+) create mode 100755 tools/pm3_amii_bin2eml.pl create mode 100755 tools/pm3_cs8.pl diff --git a/tools/pm3_amii_bin2eml.pl b/tools/pm3_amii_bin2eml.pl new file mode 100755 index 000000000..bb16960d4 --- /dev/null +++ b/tools/pm3_amii_bin2eml.pl @@ -0,0 +1,681 @@ +#!/usr/bin/perl +# +# Read Amiibo data, decrypt, and produce EML file +# Convert proxmark MFU (MIFARE Ultralight) .bin to .eml format +# for proxmark3 loading and simulation +# +# -samy kamkar 05/28/2017 +# +# hf mf eload u FILENAME_MINUS_EML +# hf 14a sim t 7 u UID + +# perl -lne 'chomp; s/\s+(\S+)$//;$f=$1;if($f=~s/-(\S+)//){$g=hex($1);}else{$g=hex($f)}$f=hex($f); for$m($f..$g){print "0x" . substr(unpack("H4",pack("n",$m)),1) ." => \"$_\","}' /tmp/game >> game2 +# perl -lne 'if(/^(\S.*?)\s+\w?\w\w\w\w(\s*-\s*\w?\w\w\w\w)?\s*$/){$l=$1} s/(\w{4,5}\s*-\s*)?(\w{4,5})$//; $a=$1;$b=$2; $b=hex($b); $a=$a?hex($a):$b; for$m($a..$b){print "0x" . substr(unpack("H4",pack("n",$m)),0) ." => \"$l\","}' /tmp/g2 + +my $BLOCKS = 255; +my $UIDLOC = -540; # UID is 540 bytes from the end +my $BLOCKSIZE = 4; # in bytes +my $AMIITOOL = '../client/amiitool/amiitool'; # path to amiitool (unless in $PATH) +my $KEYFILE = '../client/amiitool/key_retail.bin'; # path to retail key file +my $ADDHDR = 1; # add 48 byte header? +my $DECRYPT = 0; # auto-decrypt + +my %game = ( +0x000 => "Mario", +0x001 => "Mario", +0x008 => "Yoshi's Woolly World", +0x010 => "The Legend of Zelda", +0x014 => "Breath of the Wild", +0x018 => "Animal Crossing", +0x019 => "Animal Crossing", +0x01a => "Animal Crossing", +0x01b => "Animal Crossing", +0x01c => "Animal Crossing", +0x01d => "Animal Crossing", +0x01e => "Animal Crossing", +0x01f => "Animal Crossing", +0x020 => "Animal Crossing", +0x021 => "Animal Crossing", +0x022 => "Animal Crossing", +0x023 => "Animal Crossing", +0x024 => "Animal Crossing", +0x025 => "Animal Crossing", +0x026 => "Animal Crossing", +0x027 => "Animal Crossing", +0x028 => "Animal Crossing", +0x029 => "Animal Crossing", +0x02a => "Animal Crossing", +0x02b => "Animal Crossing", +0x02c => "Animal Crossing", +0x02d => "Animal Crossing", +0x02e => "Animal Crossing", +0x02f => "Animal Crossing", +0x030 => "Animal Crossing", +0x031 => "Animal Crossing", +0x032 => "Animal Crossing", +0x033 => "Animal Crossing", +0x034 => "Animal Crossing", +0x035 => "Animal Crossing", +0x036 => "Animal Crossing", +0x037 => "Animal Crossing", +0x038 => "Animal Crossing", +0x039 => "Animal Crossing", +0x03a => "Animal Crossing", +0x03b => "Animal Crossing", +0x03c => "Animal Crossing", +0x03d => "Animal Crossing", +0x03e => "Animal Crossing", +0x03f => "Animal Crossing", +0x040 => "Animal Crossing", +0x041 => "Animal Crossing", +0x042 => "Animal Crossing", +0x043 => "Animal Crossing", +0x044 => "Animal Crossing", +0x045 => "Animal Crossing", +0x046 => "Animal Crossing", +0x047 => "Animal Crossing", +0x048 => "Animal Crossing", +0x049 => "Animal Crossing", +0x04a => "Animal Crossing", +0x04b => "Animal Crossing", +0x04c => "Animal Crossing", +0x04d => "Animal Crossing", +0x04e => "Animal Crossing", +0x04f => "Animal Crossing", +0x050 => "Animal Crossing", +0x051 => "Animal Crossing", +0x058 => "Star Fox", +0x05c => "Metroid", +0x060 => "F-Zero", +0x064 => "Pikmin", +0x06c => "Punch Out", +0x070 => "Wii Fit", +0x074 => "Kid Icarus", +0x078 => "Classic Nintendo", +0x07c => "Mii", +0x080 => "Splatoon", +0x09c => "Mario Sports Superstars", +0x09d => "Mario Sports Superstars", +0x190 => "Pokemon", +0x191 => "Pokemon", +0x192 => "Pokemon", +0x193 => "Pokemon", +0x194 => "Pokemon", +0x195 => "Pokemon", +0x196 => "Pokemon", +0x197 => "Pokemon", +0x198 => "Pokemon", +0x199 => "Pokemon", +0x19a => "Pokemon", +0x19b => "Pokemon", +0x19c => "Pokemon", +0x19d => "Pokemon", +0x19e => "Pokemon", +0x19f => "Pokemon", +0x1a0 => "Pokemon", +0x1a1 => "Pokemon", +0x1a2 => "Pokemon", +0x1a3 => "Pokemon", +0x1a4 => "Pokemon", +0x1a5 => "Pokemon", +0x1a6 => "Pokemon", +0x1a7 => "Pokemon", +0x1a8 => "Pokemon", +0x1a9 => "Pokemon", +0x1aa => "Pokemon", +0x1ab => "Pokemon", +0x1ac => "Pokemon", +0x1ad => "Pokemon", +0x1ae => "Pokemon", +0x1af => "Pokemon", +0x1b0 => "Pokemon", +0x1b1 => "Pokemon", +0x1b2 => "Pokemon", +0x1b3 => "Pokemon", +0x1b4 => "Pokemon", +0x1b5 => "Pokemon", +0x1b6 => "Pokemon", +0x1b7 => "Pokemon", +0x1b8 => "Pokemon", +0x1b9 => "Pokemon", +0x1ba => "Pokemon", +0x1bb => "Pokemon", +0x1bc => "Pokemon", +0x1bd => "Pokemon", +0x1d0 => "Pokken", +0x1f0 => "Kirby", +0x1f4 => "BoxBoy!", +0x210 => "Fire Emblem", +0x224 => "Xenoblade", +0x228 => "Earthbound", +0x22c => "Chibi Robo", +0x320 => "Sonic", +0x334 => "Pac-man", +0x348 => "Megaman", +0x34c => "Street fighter", +0x350 => "Monster Hunter", +0x35c => "Shovel Knight", +); + +my %type = ( +0x00 => "Figure", +0x01 => "Card", +0x02 => "Yarn", +); + +my %amiibo = ( +0x0000 => "Super Smash Bros.", +0x0001 => "Super Smash Bros.", +0x0002 => "Super Smash Bros.", +0x0003 => "Super Smash Bros.", +0x0004 => "Super Smash Bros.", +0x0005 => "Super Smash Bros.", +0x0006 => "Super Smash Bros.", +0x0007 => "Super Smash Bros.", +0x0008 => "Super Smash Bros.", +0x0009 => "Super Smash Bros.", +0x000a => "Super Smash Bros.", +0x000b => "Super Smash Bros.", +0x000c => "Super Smash Bros.", +0x000d => "Super Smash Bros.", +0x000e => "Super Smash Bros.", +0x000f => "Super Smash Bros.", +0x0010 => "Super Smash Bros.", +0x0011 => "Super Smash Bros.", +0x0012 => "Super Smash Bros.", +0x0013 => "Super Smash Bros.", +0x0014 => "Super Smash Bros.", +0x0015 => "Super Smash Bros.", +0x0016 => "Super Smash Bros.", +0x0017 => "Super Smash Bros.", +0x0018 => "Super Smash Bros.", +0x0019 => "Super Smash Bros.", +0x001a => "Super Smash Bros.", +0x001b => "Super Smash Bros.", +0x001c => "Super Smash Bros.", +0x001d => "Super Smash Bros.", +0x001e => "Super Smash Bros.", +0x001f => "Super Smash Bros.", +0x0020 => "Super Smash Bros.", +0x0021 => "Super Smash Bros.", +0x0022 => "Super Smash Bros.", +0x0023 => "Super Smash Bros.", +0x0024 => "Super Smash Bros.", +0x0025 => "Super Smash Bros.", +0x0026 => "Super Smash Bros.", +0x0027 => "Super Smash Bros.", +0x0028 => "Super Smash Bros.", +0x0029 => "Super Smash Bros.", +0x002a => "Super Smash Bros.", +0x002b => "Super Smash Bros.", +0x002c => "Super Smash Bros.", +0x002d => "Super Smash Bros.", +0x002e => "Super Smash Bros.", +0x002f => "Super Smash Bros.", +0x0030 => "Super Smash Bros.", +0x0031 => "Super Smash Bros.", +0x0032 => "Super Smash Bros.", +0x0033 => "Super Smash Bros.", +0x023d => "Super Smash Bros.", +0x0251 => "Super Smash Bros.", +0x0252 => "Super Smash Bros.", +0x0253 => "Super Smash Bros.", +0x0258 => "Super Smash Bros.", +0x0034 => "Super Mario", +0x0035 => "Super Mario", +0x0036 => "Super Mario", +0x0037 => "Super Mario", +0x0038 => "Super Mario", +0x0039 => "Super Mario", +0x0262 => "Super Mario", +0x0263 => "Super Mario", +0x0028 => "Super Mario", +0x003c => "Super Mario", +0x003d => "Super Mario", +0x003a => "Chibi Robo", +0x003e => "Splatoon", +0x003f => "Splatoon", +0x0040 => "Splatoon", +0x025d => "Splatoon", +0x025e => "Splatoon", +0x025f => "Splatoon", +0x0260 => "Splatoon", +0x0261 => "Splatoon", +0x0044 => "Animal Crossing Cards", +0x0045 => "Animal Crossing Cards", +0x0046 => "Animal Crossing Cards", +0x0047 => "Animal Crossing Cards", +0x0048 => "Animal Crossing Cards", +0x0049 => "Animal Crossing Cards", +0x004a => "Animal Crossing Cards", +0x004b => "Animal Crossing Cards", +0x004c => "Animal Crossing Cards", +0x004d => "Animal Crossing Cards", +0x004e => "Animal Crossing Cards", +0x004f => "Animal Crossing Cards", +0x0050 => "Animal Crossing Cards", +0x0051 => "Animal Crossing Cards", +0x0052 => "Animal Crossing Cards", +0x0053 => "Animal Crossing Cards", +0x0054 => "Animal Crossing Cards", +0x0055 => "Animal Crossing Cards", +0x0056 => "Animal Crossing Cards", +0x0057 => "Animal Crossing Cards", +0x0058 => "Animal Crossing Cards", +0x0059 => "Animal Crossing Cards", +0x005a => "Animal Crossing Cards", +0x005b => "Animal Crossing Cards", +0x005c => "Animal Crossing Cards", +0x005d => "Animal Crossing Cards", +0x005e => "Animal Crossing Cards", +0x005f => "Animal Crossing Cards", +0x0060 => "Animal Crossing Cards", +0x0061 => "Animal Crossing Cards", +0x0062 => "Animal Crossing Cards", +0x0063 => "Animal Crossing Cards", +0x0064 => "Animal Crossing Cards", +0x0065 => "Animal Crossing Cards", +0x0066 => "Animal Crossing Cards", +0x0067 => "Animal Crossing Cards", +0x0068 => "Animal Crossing Cards", +0x0069 => "Animal Crossing Cards", +0x006a => "Animal Crossing Cards", +0x006b => "Animal Crossing Cards", +0x006c => "Animal Crossing Cards", +0x006d => "Animal Crossing Cards", +0x006e => "Animal Crossing Cards", +0x006f => "Animal Crossing Cards", +0x0070 => "Animal Crossing Cards", +0x0071 => "Animal Crossing Cards", +0x0072 => "Animal Crossing Cards", +0x0073 => "Animal Crossing Cards", +0x0074 => "Animal Crossing Cards", +0x0075 => "Animal Crossing Cards", +0x0076 => "Animal Crossing Cards", +0x0077 => "Animal Crossing Cards", +0x0078 => "Animal Crossing Cards", +0x0079 => "Animal Crossing Cards", +0x007a => "Animal Crossing Cards", +0x007b => "Animal Crossing Cards", +0x007c => "Animal Crossing Cards", +0x007d => "Animal Crossing Cards", +0x007e => "Animal Crossing Cards", +0x007f => "Animal Crossing Cards", +0x0080 => "Animal Crossing Cards", +0x0081 => "Animal Crossing Cards", +0x0082 => "Animal Crossing Cards", +0x0083 => "Animal Crossing Cards", +0x0084 => "Animal Crossing Cards", +0x0085 => "Animal Crossing Cards", +0x0086 => "Animal Crossing Cards", +0x0087 => "Animal Crossing Cards", +0x0088 => "Animal Crossing Cards", +0x0089 => "Animal Crossing Cards", +0x008a => "Animal Crossing Cards", +0x008b => "Animal Crossing Cards", +0x008c => "Animal Crossing Cards", +0x008d => "Animal Crossing Cards", +0x008e => "Animal Crossing Cards", +0x008f => "Animal Crossing Cards", +0x0090 => "Animal Crossing Cards", +0x0091 => "Animal Crossing Cards", +0x0092 => "Animal Crossing Cards", +0x0093 => "Animal Crossing Cards", +0x0094 => "Animal Crossing Cards", +0x0095 => "Animal Crossing Cards", +0x0096 => "Animal Crossing Cards", +0x0097 => "Animal Crossing Cards", +0x0098 => "Animal Crossing Cards", +0x0099 => "Animal Crossing Cards", +0x009a => "Animal Crossing Cards", +0x009b => "Animal Crossing Cards", +0x009c => "Animal Crossing Cards", +0x009d => "Animal Crossing Cards", +0x009e => "Animal Crossing Cards", +0x009f => "Animal Crossing Cards", +0x00a0 => "Animal Crossing Cards", +0x00a1 => "Animal Crossing Cards", +0x00a2 => "Animal Crossing Cards", +0x00a3 => "Animal Crossing Cards", +0x00a4 => "Animal Crossing Cards", +0x00a5 => "Animal Crossing Cards", +0x00a6 => "Animal Crossing Cards", +0x00a7 => "Animal Crossing Cards", +0x00a8 => "Animal Crossing Cards", +0x00a9 => "Animal Crossing Cards", +0x00aa => "Animal Crossing Cards", +0x00ab => "Animal Crossing Cards", +0x00ac => "Animal Crossing Cards", +0x00ad => "Animal Crossing Cards", +0x00ae => "Animal Crossing Cards", +0x00af => "Animal Crossing Cards", +0x00b0 => "Animal Crossing Cards", +0x00b1 => "Animal Crossing Cards", +0x00b2 => "Animal Crossing Cards", +0x00b3 => "Animal Crossing Cards", +0x00b4 => "Animal Crossing Cards", +0x00b5 => "Animal Crossing Cards", +0x00b6 => "Animal Crossing Cards", +0x00b7 => "Animal Crossing Cards", +0x00b8 => "Animal Crossing Cards", +0x00b9 => "Animal Crossing Cards", +0x00ba => "Animal Crossing Cards", +0x00bb => "Animal Crossing Cards", +0x00bc => "Animal Crossing Cards", +0x00bd => "Animal Crossing Cards", +0x00be => "Animal Crossing Cards", +0x00bf => "Animal Crossing Cards", +0x00c0 => "Animal Crossing Cards", +0x00c1 => "Animal Crossing Cards", +0x00c2 => "Animal Crossing Cards", +0x00c3 => "Animal Crossing Cards", +0x00c4 => "Animal Crossing Cards", +0x00c5 => "Animal Crossing Cards", +0x00c6 => "Animal Crossing Cards", +0x00c7 => "Animal Crossing Cards", +0x00c8 => "Animal Crossing Cards", +0x00c9 => "Animal Crossing Cards", +0x00ca => "Animal Crossing Cards", +0x00cb => "Animal Crossing Cards", +0x00cc => "Animal Crossing Cards", +0x00cd => "Animal Crossing Cards", +0x00ce => "Animal Crossing Cards", +0x00cf => "Animal Crossing Cards", +0x00d0 => "Animal Crossing Cards", +0x00d1 => "Animal Crossing Cards", +0x00d2 => "Animal Crossing Cards", +0x00d3 => "Animal Crossing Cards", +0x00d4 => "Animal Crossing Cards", +0x00d5 => "Animal Crossing Cards", +0x00d6 => "Animal Crossing Cards", +0x00d7 => "Animal Crossing Cards", +0x00d8 => "Animal Crossing Cards", +0x00d9 => "Animal Crossing Cards", +0x00da => "Animal Crossing Cards", +0x00db => "Animal Crossing Cards", +0x00dc => "Animal Crossing Cards", +0x00dd => "Animal Crossing Cards", +0x00de => "Animal Crossing Cards", +0x00df => "Animal Crossing Cards", +0x00e0 => "Animal Crossing Cards", +0x00e1 => "Animal Crossing Cards", +0x00e2 => "Animal Crossing Cards", +0x00e3 => "Animal Crossing Cards", +0x00e4 => "Animal Crossing Cards", +0x00e5 => "Animal Crossing Cards", +0x00e6 => "Animal Crossing Cards", +0x00e7 => "Animal Crossing Cards", +0x00e8 => "Animal Crossing Cards", +0x00e9 => "Animal Crossing Cards", +0x00ea => "Animal Crossing Cards", +0x00eb => "Animal Crossing Cards", +0x00ec => "Animal Crossing Cards", +0x00ed => "Animal Crossing Cards", +0x00ee => "Animal Crossing Cards", +0x00ef => "Animal Crossing Cards", +0x00f0 => "Animal Crossing Cards", +0x00f1 => "Animal Crossing Cards", +0x00f2 => "Animal Crossing Cards", +0x00f3 => "Animal Crossing Cards", +0x00f4 => "Animal Crossing Cards", +0x00f5 => "Animal Crossing Cards", +0x00f6 => "Animal Crossing Cards", +0x00f7 => "Animal Crossing Cards", +0x00f8 => "Animal Crossing Cards", +0x00f9 => "Animal Crossing Cards", +0x00fa => "Animal Crossing Cards", +0x00fb => "Animal Crossing Cards", +0x00fc => "Animal Crossing Cards", +0x00fd => "Animal Crossing Cards", +0x00fe => "Animal Crossing Cards", +0x00ff => "Animal Crossing Cards", +0x0100 => "Animal Crossing Cards", +0x0101 => "Animal Crossing Cards", +0x0102 => "Animal Crossing Cards", +0x0103 => "Animal Crossing Cards", +0x0104 => "Animal Crossing Cards", +0x0105 => "Animal Crossing Cards", +0x0106 => "Animal Crossing Cards", +0x0107 => "Animal Crossing Cards", +0x0108 => "Animal Crossing Cards", +0x0109 => "Animal Crossing Cards", +0x010a => "Animal Crossing Cards", +0x010b => "Animal Crossing Cards", +0x01d4 => "Animal Crossing Cards", +0x01d5 => "Animal Crossing Cards", +0x01d6 => "Animal Crossing Cards", +0x01d7 => "Animal Crossing Cards", +0x01d8 => "Animal Crossing Cards", +0x0041 => "Yoshi's Woolly World", +0x0042 => "Yoshi's Woolly World", +0x0043 => "Yoshi's Woolly World", +0x023e => "Yoshi's Woolly World", +0x035d => "Yoshi's Woolly World", +0x0238 => "8 - Bit Mario", +0x0239 => "8 - Bit Mario", +0x023a => "Skylanders", +0x023b => "Skylanders", +0x023f => "Animal Crossing Figures", +0x0240 => "Animal Crossing Figures", +0x0241 => "Animal Crossing Figures", +0x0242 => "Animal Crossing Figures", +0x0243 => "Animal Crossing Figures", +0x0244 => "Animal Crossing Figures", +0x0245 => "Animal Crossing Figures", +0x0246 => "Animal Crossing Figures", +0x0247 => "Animal Crossing Figures", +0x0248 => "Animal Crossing Figures", +0x0249 => "Animal Crossing Figures", +0x024a => "Animal Crossing Figures", +0x024f => "The Legend of Zelda", +0x034b => "The Legend of Zelda", +0x034c => "The Legend of Zelda", +0x034d => "The Legend of Zelda", +0x034e => "The Legend of Zelda", +0x034f => "The Legend of Zelda", +0x0350 => "The Legend of Zelda", +0x0351 => "The Legend of Zelda", +0x0352 => "The Legend of Zelda", +0x0353 => "The Legend of Zelda", +0x0354 => "The Legend of Zelda", +0x0355 => "The Legend of Zelda", +0x0356 => "The Legend of Zelda", +0x0357 => "The Legend of Zelda", +0x0358 => "The Legend of Zelda", +0x0359 => "The Legend of Zelda", +0x035a => "The Legend of Zelda", +0x035b => "The Legend of Zelda", +0x035c => "The Legend of Zelda", +0x0250 => "Shovel Knight", +0x0254 => "Kirby", +0x0255 => "Kirby", +0x0256 => "Kirby", +0x0257 => "Kirby", +0x025c => "Pokken", +0x02e1 => "Monster Hunter Stories", +0x02e2 => "Monster Hunter Stories", +0x02e3 => "Monster Hunter Stories", +0x0319 => "Animal Crossing Sanrio", +0x031a => "Animal Crossing Sanrio", +0x031b => "Animal Crossing Sanrio", +0x031c => "Animal Crossing Sanrio", +0x031d => "Animal Crossing Sanrio", +0x031e => "Animal Crossing Sanrio", +0x035e => "BoxBoy!", +0x0360 => "Fire Emblem", +0x0361 => "Fire Emblem", +); + +my %amiiboseries = ( +0x00 => "Super Smash Bros.", +0x01 => "Super Mario", +0x02 => "Chibi-Robo", +0x03 => "Yoshi's Woolly World", +0x04 => "Splatoon", +0x05 => "Animal Crossing", +0x06 => "8 - Bit Mario", +0x07 => "Skylanders", +0x08 => "???", +0x09 => "The Legend Of Zelda", +0x0A => "Shovel Knight", +0x0B => "??? (Pikmin?)", +0x0C => "Kirby", +0x0D => "Pokken", +0x0E => "Mario Sports Superstars", +0x0F => "Monster Hunter", +0x10 => "BoxBoy!", +0x11 => "???", +0x12 => "Fire Emblem", +); + +use strict; +my @err; +sub err { push @err, @_ } + +die "usage: $0 \n" unless @ARGV == 1; +my $input = shift; + +open(IN, "<$input") || die "Can't read $input$!"; +my $file = join "", ; +close(IN); + +sub bytes { return substr($file, ((length($file) + $UIDLOC) + $_[0]), $_[1] || 1) } + +# check for crypto +#my $dec_check = substr($file, ((length($file) + $UIDLOC) + 3 ), 1) eq "\xE0"; +#my $enc_check = substr($file, ((length($file) + $UIDLOC) + 3 + 8), 1) eq "\xE0"; +my $dec_check = bytes(3 + 0, 1) eq "\xE0"; +my $enc_check = bytes(3 + 8, 1) eq "\xE0"; + +my $game = ( unpack("H3", bytes(84 + 0, 2))); +my $char = (substr(unpack("H2", bytes(84 + 1)), 1)); +my $cvar = ( unpack("H2", bytes(84 + 2))); +my $type = ( unpack("H2", bytes(84 + 3))); +my $amii = ( unpack("H4", bytes(84 + 4, 2))); +my $amis = ( unpack("H2", bytes(84 + 6))); +my $last = ( unpack("H2", bytes(84 + 7))); +err "Character / info: " . join(" ", map { unpack("H2", $_) } split(//, bytes(84, 8))); +err "Game : $game $game{hex($game)}"; +err "Character: $char --"; +err "Variation: $cvar --"; +err "Type : $type $type{hex($type)}"; +err "Amiibo : $amii $amiibo{hex($amii)}"; +err "Series : $amis $amiiboseries{hex($amis)}"; +err "Last : $last (should be 02)"; +err ""; + +# looks like encrypted file +my $run; +if ($enc_check && !$dec_check) +{ + if ($DECRYPT) + { + $run = "'$AMIITOOL' -d -k '$KEYFILE' -i '$input'"; + err "Looks like encrypted file, decrypting"; + err "Running: $run"; + $file = `$run`; + } + else + { + err "Looks like encrypted file but setting preventing us from decrypting"; + } +} +elsif ($enc_check && $dec_check) +{ + $run = "'$AMIITOOL' -d -k '$KEYFILE' -i '$input'"; + err "Looks like encrypted AND decrypted file, will try decrypting first"; + err "Running: $run"; + my $tmp = `$run`; + if (!$tmp) + { + err "Decryption failed, assuming file is already decrypted"; + } + else + { + err "Decryption succeeded, loading decrypted contents"; + $file = $tmp; + } +} +elsif ($dec_check && !$enc_check) +{ + err "Looks like decrypted file, great!"; +} +elsif (!$dec_check && !$enc_check) +{ + die "Does not look like proper file format! Exiting.\n"; +} + +my $lines = $BLOCKS; +my $uid = unpack("H14", + substr($file, length($file) + $UIDLOC, 3) . + substr($file, (length($file) + $UIDLOC) + 4, 4)); +my $pwd = unpack("H8", substr($file, length($file) - 8, 4)); + +# file does not contain our 48 byte header, let's add it +if ($ADDHDR && length($file) == -1 * $UIDLOC) +{ + err "Does not contain header, adding"; + while () + { + $lines--; + chomp; # there may not be a newline so chomp and add below + print "$_\n"; + } +} + +while (length($file)) +{ + my $out = substr($file, 0, $BLOCKSIZE, ""); # was 16 + $out = unpack("H*", $out); + print "$out\n"; + + # grab UID +=cut + if ($BLOCKS - $lines == 12) + { + $uid = substr($out, 0, 6); + } + elsif ($BLOCKS - $lines == 13) + { + $uid .= substr($out, 0, 8); + } +=cut + + $lines--; +} + +# still need to pad to 255 4-byte (8 hex char) blocks +if ($lines > 0) +{ + while ($lines--) + { + print "00000000\n"; + } +} + + +print STDERR "\n"; +print STDERR "$_\n" for @err; +print STDERR "UID: $uid\n"; +print STDERR "PWD: $pwd\n"; +print STDERR "\n"; +$uid = uc $uid; +#print STDERR "amiitool -d -k ../client/amiitool/key_retail.bin -i $input -o $input.decrypted\n"; +$input =~ s/\....$//; +print STDERR "hf mf eload u $input\n"; +print STDERR "hf 14a sim t 7 u $uid\n"; + + +__DATA__ +00040402 +01001103 +01000000 +00808000 +92580b4c +45a9c42f +a90145ce +5e5f9c43 +09a43d47 +d232a3d1 +68cbade6 +7f8185c6 diff --git a/tools/pm3_cs8.pl b/tools/pm3_cs8.pl new file mode 100755 index 000000000..2d10c07d0 --- /dev/null +++ b/tools/pm3_cs8.pl @@ -0,0 +1,43 @@ +#!/usr/bin/perl + +use strict; + +die "usage: $0 \n" unless @ARGV == 1; +# Convert proxmark3 trace to cs8 (complex int8/hackrf fmt) for inspectrum +# From miek + +if ($ARGV[0] =~ /wav$/) +{ + system("sox $ARGV[0] -t raw -e signed-integer -b 16 $ARGV[0].cs16"); +} +else +{ + #perl -ne 'chomp; print pack "c", $_' p.trace > p.c8 + my $f = "/tmp/pm3.trace." . rand(); + open(F, ">$f") || die $!; + open(IN, "<$ARGV[0]"); + while () + { + chomp; + print F pack "c", $_; + } + close(IN); + close(F); + +# upsample 100x and pad 2nd channel with zeroes + system("sox -t s8 -r 1 -c 1 -v 0.5 $f -t s8 -r 100 -c 2 $f.cs8 remix 1 0"); + + open(OUT, ">$ARGV[0].cs8") || die $!; + open(IN, "<$f.cs8") || die $!; + print OUT while ; + print OUT "\0" x (1024 * 1024); + close(IN); + close(OUT); + + unlink($f, "$f.cs8"); + +# pad file since inspectrum doesn't handle small files so well +#system("dd if=/dev/zero of=$f.pad bs=1m count=1 >>/dev/null"); + +#system("cat $f.cs8 $f.pad > $ARGV[1]"); +} \ No newline at end of file From 9e41221be1ab6dd14052ab50f1448f86bf455e3f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 23 Dec 2019 22:53:10 +0100 Subject: [PATCH 1257/1854] chmod --- tools/pm3_eml_mfd_test.py | 0 tools/pm3_mf7b_wipe.py | 0 2 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 tools/pm3_eml_mfd_test.py mode change 100644 => 100755 tools/pm3_mf7b_wipe.py diff --git a/tools/pm3_eml_mfd_test.py b/tools/pm3_eml_mfd_test.py old mode 100644 new mode 100755 diff --git a/tools/pm3_mf7b_wipe.py b/tools/pm3_mf7b_wipe.py old mode 100644 new mode 100755 From 89cacceb5a07da5e21bac64cd39e928ac497a1de Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 23 Dec 2019 22:56:49 +0100 Subject: [PATCH 1258/1854] textual: linking to file formats --- README.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 7e4c28145..2c9a129e0 100644 --- a/README.md +++ b/README.md @@ -61,17 +61,17 @@ The [public roadmap](https://github.com/RfidResearchGroup/proxmark3/wiki/Public- We usually merge your contributions fast since we do like the idea of getting a functionality in the Proxmark3 and weed out the bugs afterwards. ## Notes / helpful documents -- Internal notes on [Coverity Scan Config & Run](/doc/md/Development/Coverity-Scan-Config-%26-Run.md). -- Internal notes on [UART](/doc/uart_notes.md) -- Internal notes on [Frame format](/doc/new_frame_format.md) -- Internal notes on [external flash](/doc/ext_flash_notes.md) -- Internal notes on [standalone mode](https://github.com/RfidResearchGroup/proxmark3/wiki/Standalone-mode) -- Internal notes on [Termux / Android](/doc/termux_notes.md) -- Internal notes on [Wireshark / tracedata](/doc/trace_wireshark_notes.md) -- Internal notes on [loclass](/doc/loclass_notes.md) -- Internal notes on [EMV](/doc/emv_notes.md) -- Internal notes on [Paths](/doc/path_notes.md) - +- notes on [Coverity Scan Config & Run](/doc/md/Development/Coverity-Scan-Config-%26-Run.md). +- notes on [UART](/doc/uart_notes.md) +- notes on [Frame format](/doc/new_frame_format.md) +- notes on [external flash](/doc/ext_flash_notes.md) +- notes on [standalone mode](https://github.com/RfidResearchGroup/proxmark3/wiki/Standalone-mode) +- notes on [Termux / Android](/doc/termux_notes.md) +- notes on [Wireshark / tracedata](/doc/trace_wireshark_notes.md) +- notes on [loclass](/doc/loclass_notes.md) +- notes on [EMV](/doc/emv_notes.md) +- notes on [Paths](/doc/path_notes.md) +- notes on [file formats used with Proxmark3](/doc/extensions_notes.md) ## Cheat sheet Thanks to Alex Dibs, you can enjoy a [command cheat sheet](/doc/cheatsheet.md) From 406d048059db261e24c0cdb5c9b53f12e3f30ab7 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 23 Dec 2019 23:12:29 +0100 Subject: [PATCH 1259/1854] textual --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c4e0e9d35..853a63a91 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,9 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Add `tools\pm3_cs8.pl` - convert .pm3 files to wave format (@samyk) + - Add `tools\pm3_amii_bin2eml.pl` - amiibo convering script (@samyk) + - Chg `hf 14a info` - now detects "static / fixed" nonce tags (@iceman1001) - Chg `data save f w` - params reworked. (@iceman1001) - Chg `hf search` - now should detect LTO-CM tags (@iceman1001) - Added `hf lto info` - skeleton support for LTO Cartridge memory (@iceman1001) From 5f7fe45f589a51bfbe436c1c613311cac197a16c Mon Sep 17 00:00:00 2001 From: Samy Kamkar Date: Mon, 23 Dec 2019 15:43:49 -0800 Subject: [PATCH 1260/1854] Support multiple files, sanitize input, detect sox --- tools/pm3_cs8.pl | 81 +++++++++++++++++++++++++++++++----------------- 1 file changed, 52 insertions(+), 29 deletions(-) diff --git a/tools/pm3_cs8.pl b/tools/pm3_cs8.pl index 2d10c07d0..398e06f31 100755 --- a/tools/pm3_cs8.pl +++ b/tools/pm3_cs8.pl @@ -1,43 +1,66 @@ #!/usr/bin/perl +# +# Convert proxmark3 trace or wav files to formats to be used by Inspectrum +# +# Converts proxmark3 trace to cs8 (Complex 8-bit signed integer samples, eg HackRF IQ format) +# and .wav to cs16 (Complex 16-bit signed integer samples, eg BladeRF IQ format) +# +# -samy kamkar, https://samy.pl + +# we use `sox` to convert, set this to full path if preferred +my $SOX = "sox"; use strict; -die "usage: $0 \n" unless @ARGV == 1; -# Convert proxmark3 trace to cs8 (complex int8/hackrf fmt) for inspectrum -# From miek +die "usage: $0 [/path/to/sox (optional)] [...more traces]\n" unless @ARGV; +$SOX = shift if $ARGV[0] =~ m/(?:[\/\\]|^)sox$/; +trace_conv($_) for @ARGV; -if ($ARGV[0] =~ /wav$/) +sub trace_conv { - system("sox $ARGV[0] -t raw -e signed-integer -b 16 $ARGV[0].cs16"); -} -else -{ - #perl -ne 'chomp; print pack "c", $_' p.trace > p.c8 - my $f = "/tmp/pm3.trace." . rand(); - open(F, ">$f") || die $!; - open(IN, "<$ARGV[0]"); - while () + my $file = shift; + if ($file =~ /wav$/i) { - chomp; - print F pack "c", $_; + my @run = ($SOX, qw/$file -t raw -e signed-integer -b 16 $file.cs16/); + run_rewrite($file, @run); + print "Wrote $file.cs16\n\n"; } - close(IN); - close(F); + else + { + my $f = "/tmp/pm3.trace." . rand(); + open(F, ">$f") || die "Can't write to $f: $!"; + open(IN, "<$file") || die "Can't read $file: $!"; + while () + { + chomp; + print F pack "c", $_; + } + close(IN); + close(F); -# upsample 100x and pad 2nd channel with zeroes - system("sox -t s8 -r 1 -c 1 -v 0.5 $f -t s8 -r 100 -c 2 $f.cs8 remix 1 0"); + # upsample 100x and pad 2nd channel with zeroes + my @run = ($SOX, qw/-t s8 -r 1 -c 1 -v 0.5 $file -t s8 -r 100 -c 2 $file.cs8 remix 1 0/); + run_rewrite($f, @run); - open(OUT, ">$ARGV[0].cs8") || die $!; - open(IN, "<$f.cs8") || die $!; - print OUT while ; - print OUT "\0" x (1024 * 1024); - close(IN); - close(OUT); + # pad file since inspectrum doesn't handle small files so well + open(OUT, ">$file.cs8") || die $!; + open(IN, "<$f.cs8") || die $!; + print OUT while ; + print OUT "\0" x (1024 * 1024); + close(IN); + close(OUT); - unlink($f, "$f.cs8"); + unlink($f, "$f.cs8"); + print "Wrote $file.cs8\n\n"; + } +} -# pad file since inspectrum doesn't handle small files so well -#system("dd if=/dev/zero of=$f.pad bs=1m count=1 >>/dev/null"); +sub run_rewrite +{ + my ($file, @run) = @_; + s/\$file/$file/ foreach @run; + print "Running: @run\n"; -#system("cat $f.cs8 $f.pad > $ARGV[1]"); + my $ret = system(@run); + die "Failed: $! ($ret)\ndo you have $run[0] installed?\n" if $ret; } \ No newline at end of file From aeb3f74c106c6412b53a6bbf1594b2a6912b416a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 24 Dec 2019 00:57:15 +0100 Subject: [PATCH 1261/1854] Add: 'hf lto list' - annotation for LTO-CM --- client/cmdhflist.c | 43 +++++++++++++++++++++++++++++++++++++++++++ client/cmdhflist.h | 1 + client/cmdtrace.c | 8 +++++++- include/protocols.h | 1 + 4 files changed, 52 insertions(+), 1 deletion(-) diff --git a/client/cmdhflist.c b/client/cmdhflist.c index 7a46b5deb..589a81365 100644 --- a/client/cmdhflist.c +++ b/client/cmdhflist.c @@ -1095,6 +1095,49 @@ void annotateFelica(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) { } } +void annotateLTO(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) { + switch (cmd[0]) { + case LTO_REQ_STANDARD: + snprintf(exp, size, "REQ Standard"); + break; + case LTO_SELECT: + snprintf(exp, size, "SELECT"); + break; + case LTO_SELECT_1: + snprintf(exp, size, "SELECT_1"); + break; + case LTO_REQ_ALL: + snprintf(exp, size, "REQ All"); + break; + case LTO_TEST_CMD_1: + snprintf(exp, size, "TEST CMD 1"); + break; + case LTO_TEST_CMD_2: + snprintf(exp, size, "TEST CMD 2"); + break; + case LTO_READWORD: + snprintf(exp, size, "READWORD"); + break; + case (LTO_READBLOCK & 0xF0): + snprintf(exp, size, "READBLOCK"); + break; + case LTO_READBLOCK_CONT: + snprintf(exp, size, "READBLOCK CONT"); + break; + case LTO_WRITEWORD: + snprintf(exp, size, "WRITEWORD"); + break; + case (LTO_WRITEBLOCK & 0xF0): + snprintf(exp, size, "WRITEBLOCK"); + break; + case LTO_HALT: + snprintf(exp, size, "HALT"); + break; + default: + break; + } +} + void annotateMifare(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize, uint8_t *parity, uint8_t paritysize, bool isResponse) { if (!isResponse && cmdsize == 1) { switch (cmd[0]) { diff --git a/client/cmdhflist.h b/client/cmdhflist.h index 42ae6e83b..d13285bc4 100644 --- a/client/cmdhflist.h +++ b/client/cmdhflist.h @@ -48,6 +48,7 @@ void annotateIso14443b(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize); void annotateIso14443a(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize); void annotateMfDesfire(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize); void annotateMifare(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize, uint8_t *parity, uint8_t paritysize, bool isResponse); +void annotateLTO(char *explanation, size_t size, uint8_t *cmd, uint8_t cmdsize); bool DecodeMifareData(uint8_t *cmd, uint8_t cmdsize, uint8_t *parity, bool isResponse, uint8_t *mfData, size_t *mfDataLen); bool NTParityChk(TAuthData *ad, uint32_t ntx); diff --git a/client/cmdtrace.c b/client/cmdtrace.c index 7e9b53548..51f5fad28 100644 --- a/client/cmdtrace.c +++ b/client/cmdtrace.c @@ -46,6 +46,7 @@ static int usage_trace_list() { PrintAndLogEx(NORMAL, " legic - interpret data as LEGIC communications"); PrintAndLogEx(NORMAL, " felica - interpret data as ISO18092 / FeliCa communications"); PrintAndLogEx(NORMAL, " hitag - interpret data as Hitag2 / HitagS communications"); + PrintAndLogEx(NORMAL, " lto - interpret data as LTO-CM communications"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " trace list 14a f"); @@ -264,6 +265,7 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr break; case ISO_14443A: case MFDES: + case LTO: crcStatus = iso14443A_CRC_check(isResponse, frame, data_len); break; case THINFILM: @@ -302,6 +304,7 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr && protocol != PROTO_HITAG && protocol != THINFILM && protocol != FELICA + && protocol != LTO && (isResponse || protocol == ISO_14443A) && (oddparity8(frame[j]) != ((parityBits >> (7 - (j & 0x0007))) & 0x01))) { @@ -378,6 +381,8 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr break; case FELICA: annotateFelica(explanation, sizeof(explanation), frame, data_len); + case LTO: + annotateLTO(explanation, sizeof(explanation), frame, data_len); break; default: break; @@ -589,6 +594,7 @@ int CmdTraceList(const char *Cmd) { else if (strcmp(type, "mf") == 0) protocol = PROTO_MIFARE; else if (strcmp(type, "hitag") == 0) protocol = PROTO_HITAG; else if (strcmp(type, "thinfilm") == 0) protocol = THINFILM; + else if (strcmp(type, "lto") == 0) protocol = LTO; else if (strcmp(type, "raw") == 0) protocol = -1; //No crc, no annotations else errors = true; @@ -651,7 +657,7 @@ int CmdTraceList(const char *Cmd) { } } else { PrintAndLogEx(NORMAL, "Start = Start of Start Bit, End = End of last modulation. Src = Source of Transfer"); - if (protocol == ISO_14443A || protocol == PROTO_MIFARE || protocol == MFDES || protocol == TOPAZ) + if (protocol == ISO_14443A || protocol == PROTO_MIFARE || protocol == MFDES || protocol == TOPAZ || protocol == LTO) PrintAndLogEx(NORMAL, "ISO14443A - All times are in carrier periods (1/13.56MHz)"); if (protocol == THINFILM) PrintAndLogEx(NORMAL, "Thinfilm - All times are in carrier periods (1/13.56MHz)"); diff --git a/include/protocols.h b/include/protocols.h index d04173557..857cb2a4a 100644 --- a/include/protocols.h +++ b/include/protocols.h @@ -307,6 +307,7 @@ ISO 7816-4 Basic interindustry commands. For command APDU's. #define PROTO_MIFARE 9 #define PROTO_HITAG 10 #define THINFILM 11 +#define LTO 12 //-- Picopass fuses #define FUSE_FPERS 0x80 From 7bb5f513402f7278e45cfc89465f541671086ed6 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 24 Dec 2019 09:52:11 +0100 Subject: [PATCH 1262/1854] style --- client/luascripts/hf_bruteforce.lua | 105 ++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 client/luascripts/hf_bruteforce.lua diff --git a/client/luascripts/hf_bruteforce.lua b/client/luascripts/hf_bruteforce.lua new file mode 100644 index 000000000..5ba6d9802 --- /dev/null +++ b/client/luascripts/hf_bruteforce.lua @@ -0,0 +1,105 @@ +-- Run me like this: proxmark3 /dev/rfcomm0 -l ./hf_bruteforce.lua + +local getopt = require('getopt') + +copyright = '' +author = 'Keld Norman' +version = 'v1.0.0' +desc = [[ + +]] +example = [[ + -- (the above example would bruteforce card number, starting at 1, ending at 10, and waiting 1 second between each card) + + script run hf_bruteforce -s 1 -e 10 -t 1000 +]] +usage = [[ + +script run hf_bruteforce -s start_id -e end_id -t timeout -d direction + +Arguments: + -h this help + -s 0-0xFFFFFFFF start id + -e 0-0xFFFFFFFF end id + -t 0-99999, pause timeout (ms) between cards (use the word 'pause' to wait for user input) +]] + + +local DEBUG = true + +--- +-- Debug print function +local function dbg(args) + if not DEBUG then return end + if type(args) == 'table' then + local i = 1 + while result[i] do + dbg(result[i]) + i = i+1 + end + else + print('###', args) + end +end +--- +-- When errors occur +local function oops(err) + print('ERROR:', err) + core.clearCommandBuffer() + return nil, err +end +--- +-- Usage help +local function help() + print(copyright) + print(author) + print(version) + print(desc) + print('Example usage') + print(example) + print(usage) +end +--- +-- Exit message +local function exitMsg(msg) + print( string.rep('--',20) ) + print(msg) + print( string.rep('--',20) ) + print() +end +--- +-- Start +local function main(args) + + print( string.rep('--',20) ) + print( string.rep('--',20) ) + print() + local timeout = 0 + local start_id = 0 + local end_id = 0xFFFFFFFF + + for o, a in getopt.getopt(args, 'e:s:t:h') do + if o == 's' then start_id = a end + if o == 'e' then end_id = a end + if o == 't' then timeout = a end + if o == 'h' then return print(usage) end + end + + -- template + local command = 'hf 14a sim t 1 u %08X' + + print(' Bruteforcing MFC card numbers from 00000000 to FFFFFFFF using delay: '..timeout) + print('') + print( string.rep('--',20) ) + + for n = start_id, end_id do + local c = string.format( command, n ) + print(' Running: "'..c..'"') + core.console(c) + core.console('msleep '..timeout); + core.console('hw ping') + end + +end +main(args) + From 648c6a6adc7a8968aec73824c10f49e50c1436ef Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 24 Dec 2019 09:52:27 +0100 Subject: [PATCH 1263/1854] style --- client/cmdhflist.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/cmdhflist.c b/client/cmdhflist.c index 589a81365..c9d0f2bb7 100644 --- a/client/cmdhflist.c +++ b/client/cmdhflist.c @@ -1096,7 +1096,7 @@ void annotateFelica(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) { } void annotateLTO(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) { - switch (cmd[0]) { + switch (cmd[0]) { case LTO_REQ_STANDARD: snprintf(exp, size, "REQ Standard"); break; @@ -1111,7 +1111,7 @@ void annotateLTO(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) { break; case LTO_TEST_CMD_1: snprintf(exp, size, "TEST CMD 1"); - break; + break; case LTO_TEST_CMD_2: snprintf(exp, size, "TEST CMD 2"); break; @@ -1120,10 +1120,10 @@ void annotateLTO(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) { break; case (LTO_READBLOCK & 0xF0): snprintf(exp, size, "READBLOCK"); - break; + break; case LTO_READBLOCK_CONT: snprintf(exp, size, "READBLOCK CONT"); - break; + break; case LTO_WRITEWORD: snprintf(exp, size, "WRITEWORD"); break; From d2330aa393c762a99a7903e2f7a6a6ea740df019 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 24 Dec 2019 09:54:45 +0100 Subject: [PATCH 1264/1854] text --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 853a63a91..4f9f00c43 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Add `hf_bruteforce.lua` - script bruteforces uid for 14a using hf 14a sim (@keld) - Add `tools\pm3_cs8.pl` - convert .pm3 files to wave format (@samyk) - Add `tools\pm3_amii_bin2eml.pl` - amiibo convering script (@samyk) - Chg `hf 14a info` - now detects "static / fixed" nonce tags (@iceman1001) From 094c9905b0bd83f2dc690d45d2a4ee3f53ea2240 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 24 Dec 2019 10:20:07 +0100 Subject: [PATCH 1265/1854] hitag rework - WIP --- armsrc/lfadc.c | 241 +++++++++++++++++++++++++++++++++++++++++++++++++ armsrc/lfadc.h | 32 +++++++ 2 files changed, 273 insertions(+) create mode 100644 armsrc/lfadc.c create mode 100644 armsrc/lfadc.h diff --git a/armsrc/lfadc.c b/armsrc/lfadc.c new file mode 100644 index 000000000..c192087c4 --- /dev/null +++ b/armsrc/lfadc.c @@ -0,0 +1,241 @@ +//----------------------------------------------------------------------------- +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// LF ADC read/write implementation +//----------------------------------------------------------------------------- + +#include "lfadc.h" +#include "lfsampling.h" +#include "fpgaloader.h" +#include "ticks.h" + +// Sam7s has several timers, we will use the source TIMER_CLOCK1 (aka AT91C_TC_CLKS_TIMER_DIV1_CLOCK) +// TIMER_CLOCK1 = MCK/2, MCK is running at 48 MHz, Timer is running at 48/2 = 24 MHz +// Carrier periods (T0) have duration of 8 microseconds (us), which is 1/125000 per second +// T0 = TIMER_CLOCK1 / 125000 = 192 +//#define T0 192 + +// Sam7s has three counters, we will use the first TIMER_COUNTER_0 (aka TC0) +// using TIMER_CLOCK3 (aka AT91C_TC_CLKS_TIMER_DIV3_CLOCK) +// as a counting signal. TIMER_CLOCK3 = MCK/32, MCK is running at 48 MHz, so the timer is running at 48/32 = 1500 kHz +// Carrier period (T0) have duration of 8 microseconds (us), which is 1/125000 per second (125 kHz frequency) +// T0 = timer/carrier = 1500kHz/125kHz = 1500000/125000 = 6 +#define T0 3 + +////////////////////////////////////////////////////////////////////////////// +// Global variables +////////////////////////////////////////////////////////////////////////////// + +bool rising_edge = false; +bool logging = true; +bool reader_mode = false; + +////////////////////////////////////////////////////////////////////////////// +// Auxiliary functions +////////////////////////////////////////////////////////////////////////////// + +bool lf_test_periods(size_t expected, size_t count) { + // Compute 10% deviation (integer operation, so rounded down) + size_t diviation = expected / 10; + return ((count > (expected - diviation)) && (count < (expected + diviation))); +} + +////////////////////////////////////////////////////////////////////////////// +// Low frequency (LF) adc passthrough functionality +////////////////////////////////////////////////////////////////////////////// +uint8_t previous_adc_val = 0; + +size_t lf_count_edge_periods_ex(size_t max, bool wait, bool detect_gap) { + size_t periods = 0; + volatile uint8_t adc_val; + //uint8_t avg_peak = 140, avg_through = 96; + uint8_t avg_peak = 130, avg_through = 106; + + while (!BUTTON_PRESS()) { + // Watchdog hit + WDT_HIT(); + + if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { + adc_val = AT91C_BASE_SSC->SSC_RHR; + periods++; + + if (logging) logSample(adc_val, 1, 8, 0, 0); + + // Only test field changes if state of adc values matter + if (!wait) { + // Test if we are locating a field modulation (100% ASK = complete field drop) + if (detect_gap) { + // Only return when the field completely dissapeared + if (adc_val == 0) { + return periods; + } + } else { + // Trigger on a modulation swap by observing an edge change + if (rising_edge) { + if ((previous_adc_val > avg_peak) && (adc_val <= previous_adc_val)) { + rising_edge = false; + return periods; + } + } else { + if ((previous_adc_val < avg_through) && (adc_val >= previous_adc_val)) { + rising_edge = true; + return periods; + } + } + } + } + + previous_adc_val = adc_val; + if (periods == max) return 0; + } + } + if (logging) logSample(255, 1, 8, 0, 0); + return 0; +} + +size_t lf_count_edge_periods(size_t max) { + return lf_count_edge_periods_ex(max, false, false); +} + +size_t lf_detect_gap(size_t max) { + return lf_count_edge_periods_ex(max, false, true); +} + +void lf_reset_counter() { + // TODO: find out the correct reset settings for tag and reader mode + if (reader_mode) { + // Reset values for reader mode + rising_edge = false; + previous_adc_val = 0xFF; + } else { + // Reset values for tag/transponder mode + rising_edge = false; + previous_adc_val = 0xFF; + } +} + +bool lf_get_tag_modulation() { + return (rising_edge == false); +} + +void lf_wait_periods(size_t periods) { + lf_count_edge_periods_ex(periods, true, false); +} + +void lf_init(bool reader) { + reader_mode = reader; + + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + if (reader) { + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + } else { + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC); + } + + // Connect the A/D to the peak-detected low-frequency path. + SetAdcMuxFor(GPIO_MUXSEL_LOPKD); + + // Now set up the SSC to get the ADC samples that are now streaming at us. + FpgaSetupSsc(); + + // When in reader mode, give the field a bit of time to settle. + if (reader) SpinDelay(50); + + // Steal this pin from the SSP (SPI communication channel with fpga) and use it to control the modulation + AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; + AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; + LOW(GPIO_SSC_DOUT); + + // Enable peripheral Clock for TIMER_CLOCK0 + AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC0); + AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; + AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV4_CLOCK; + + // Enable peripheral Clock for TIMER_CLOCK0 + AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC1); + AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; + AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_TIMER_DIV4_CLOCK; + + // Clear all leds + LEDsoff(); + + // Reset and enable timers + AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; + AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; + + // Prepare data trace + if (logging) initSamplingBuffer(); + +} + +void lf_finalize() { + // Disable timers + AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; + AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; + + // return stolen pin to SSP + AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DOUT; + AT91C_BASE_PIOA->PIO_ASR = GPIO_SSC_DIN | GPIO_SSC_DOUT; + + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + + LEDsoff(); +} + +size_t lf_detect_field_drop(size_t max) { + size_t periods = 0; + volatile uint8_t adc_val; + + // usb check? + while (!BUTTON_PRESS()) { + // Watchdog hit + WDT_HIT(); + + if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { + periods++; + adc_val = AT91C_BASE_SSC->SSC_RHR; + + if (logging) logSample(adc_val, 1, 8, 0, 0); + + if (adc_val == 0) { + rising_edge = false; + return periods; + } + + if (periods == max) return 0; + } + } + return 0; +} + +inline void lf_modulation(bool modulation) { + if (modulation) { + HIGH(GPIO_SSC_DOUT); + } else { + LOW(GPIO_SSC_DOUT); + } +} + +inline void lf_manchester_send_bit(uint8_t bit) { + lf_modulation(bit != 0); + lf_wait_periods(16); + lf_modulation(bit == 0); + lf_wait_periods(16); +} + +bool lf_manchester_send_bytes(const uint8_t *frame, size_t frame_len) { + + LED_B_ON(); + + // Send the content of the frame + for (size_t i = 0; i < frame_len; i++) { + lf_manchester_send_bit((frame[i / 8] >> (7 - (i % 8))) & 1); + } + + LED_B_OFF(); + return true; +} diff --git a/armsrc/lfadc.h b/armsrc/lfadc.h new file mode 100644 index 000000000..603d689a4 --- /dev/null +++ b/armsrc/lfadc.h @@ -0,0 +1,32 @@ +//----------------------------------------------------------------------------- +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// LF ADC read/write implementation +//----------------------------------------------------------------------------- + +#ifndef __LFADC_H__ +#define __LFADC_H__ + +#include "proxmark3_arm.h" +#include "common.h" +#include "cmd.h" +#include "util.h" +#include "string.h" + +extern bool logging; + +bool lf_test_periods(size_t expected, size_t count); +size_t lf_count_edge_periods(size_t max); +size_t lf_detect_gap(size_t max); +void lf_reset_counter(); +bool lf_get_tag_modulation(); +void lf_wait_periods(size_t periods); +void lf_init(bool reader); +void lf_finalize(); +size_t lf_detect_field_drop(size_t max); +bool lf_manchester_send_bytes(const uint8_t *frame, size_t frame_len); +void lf_modulation(bool mod); + +#endif // __LFADC_H__ From e701022257b221762c642d1143b4906ac4b71134 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 24 Dec 2019 11:30:07 +0100 Subject: [PATCH 1266/1854] fix: hf search - iClass wrong return code check --- client/cmdhf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdhf.c b/client/cmdhf.c index 181b10858..7f6c7facf 100644 --- a/client/cmdhf.c +++ b/client/cmdhf.c @@ -158,7 +158,7 @@ int CmdHFSearch(const char *Cmd) { PROMPT_CLEARLINE; PrintAndLogEx(INPLACE, "Searching for iClass / PicoPass tag..."); if (IfPm3Iclass()) { - if (readIclass(false, false) == 1) { + if (readIclass(false, false) == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("iClass tag / PicoPass tag") "found\n"); return PM3_SUCCESS; } From 0219c6b1250086b9828000fee45d7f7146ce6139 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 24 Dec 2019 11:30:46 +0100 Subject: [PATCH 1267/1854] more defines --- include/common.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/common.h b/include/common.h index 627846ff2..653000409 100644 --- a/include/common.h +++ b/include/common.h @@ -141,4 +141,10 @@ extern int DBGLEVEL; # define DEC2BCD(dec) HornerScheme(dec, 10, 0x10) #endif +// bit stream operations +#define TEST_BIT(data, i) (*(data + (i / 8)) >> (7 - (i % 8))) & 1 +#define SET_BIT(data, i) *(data + (i / 8)) |= (1 << (7 - (i % 8))) +#define CLEAR_BIT(data, i) *(data + (i / 8)) &= ~(1 << (7 - (i % 8))) +#define FLIP_BIT(data, i) *(data + (i / 8)) ^= (1 << (7 - (i % 8))) + #endif From c70ab5f5d4ea761be7b29a4c82471bf57f7987d6 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 25 Dec 2019 14:01:37 +0100 Subject: [PATCH 1268/1854] fix: hf mf chk / hf mf fchk / hf mf autopwn - Now correctly writes 0xFF's instead of zeros for unknown keys in binary key file.\nChg: hf mf nested - check for static/fixed nonce added --- client/cmdhfmf.c | 105 +++++++++++++++++++++------------------------ client/fileutils.c | 48 +++++++++++++-------- client/fileutils.h | 6 +-- 3 files changed, 80 insertions(+), 79 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index dc42cae62..5a70488fe 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -483,6 +483,24 @@ static char *GenerateFilename(const char *prefix, const char *suffix) { return fptr; } +static int32_t initSectorTable(sector_t **src, int32_t items) { + + // initialize storage + (*src) = calloc(items, sizeof(sector_t)); + + if (*src == NULL) + return -1; + + // empty e_sector + for (int i = 0; i < items; ++i) { + for (int j = 0; j < 2; ++j) { + (*src)[i].Key[j] = 0xffffffffffff; + (*src)[i].foundKey[j] = false; + } + } + return items; +} + static int CmdHF14AMfDarkside(const char *Cmd) { uint8_t blockno = 0, key_type = MIFARE_AUTH_KEYA; uint64_t key = 0; @@ -1223,10 +1241,16 @@ static int CmdHF14AMfNested(const char *Cmd) { j++; } + // check if tag doesn't have static/fixed nonce + if (detect_classic_static_nonce() != 0) { + PrintAndLogEx(WARNING, "Static/fixed nonce detected. Quitting..."); + return PM3_EOPABORTED; + } + // check if we can authenticate to sector if (mfCheckKeys(blockNo, keyType, true, 1, key, &key64) != PM3_SUCCESS) { PrintAndLogEx(WARNING, "Wrong key. Can't authenticate to block:%3d key type:%c", blockNo, keyType ? 'B' : 'A'); - return 3; + return PM3_EOPABORTED; } if (cmdp == 'o') { @@ -1767,16 +1791,10 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { return usage_hf14_autopwn(); } - // Create the key storage stucture - e_sector = calloc(sectors_cnt, sizeof(sector_t)); - if (e_sector == NULL) return PM3_EMALLOC; - - // clear the key storage - for (int i = 0; i < sectors_cnt; i++) { - for (int j = 0; j < 2; j++) { - e_sector[i].Key[j] = 0; - e_sector[i].foundKey[j] = 0; - } + // create/initialize key storage structure + int32_t res = initSectorTable(&e_sector, sectors_cnt); + if (res != sectors_cnt) { + return PM3_EMALLOC; } // card prng type (weak=1 / hard=0 / select/card comm error = negative value) @@ -2252,11 +2270,10 @@ all_found: _YELLOW_("A") ":keyA " ")" ); - + // Dump the keys PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(INFO, "saving keys"); - createMfcKeyDump(sectors_cnt, e_sector, GenerateFilename("hf-mf-", "-key.bin")); + createMfcKeyDump(GenerateFilename("hf-mf-", "-key"), sectors_cnt, e_sector); PrintAndLogEx(SUCCESS, "transferring keys to simulator memory (Cmd Error: 04 can occur)"); @@ -2343,7 +2360,6 @@ static int CmdHF14AMfChk_fast(const char *Cmd) { FILE *f; char filename[FILE_PATH_SIZE] = {0}; char buf[13]; - char *fptr; uint8_t *keyBlock, *p; uint8_t sectorsCnt = 1; int i, keycnt = 0; @@ -2472,9 +2488,9 @@ static int CmdHF14AMfChk_fast(const char *Cmd) { (keyBlock + 6 * keycnt)[3], (keyBlock + 6 * keycnt)[4], (keyBlock + 6 * keycnt)[5]); } - // // initialize storage for found keys - e_sector = calloc(sectorsCnt, sizeof(sector_t)); - if (e_sector == NULL) { + // create/initialize key storage structure + int32_t res = initSectorTable(&e_sector, sectorsCnt); + if (res != sectorsCnt) { free(keyBlock); return PM3_EMALLOC; } @@ -2573,10 +2589,8 @@ out: } } - if (createDumpFile) { - fptr = GenerateFilename("hf-mf-", "-key.bin"); - createMfcKeyDump(sectorsCnt, e_sector, fptr); - } + if (createDumpFile) + createMfcKeyDump(GenerateFilename("hf-mf-", "-key"), sectorsCnt, e_sector); } free(keyBlock); @@ -2601,7 +2615,6 @@ static int CmdHF14AMfChk(const char *Cmd) { uint8_t keyType = 0; uint32_t keyitems = ARRAYLEN(g_mifare_default_keys); uint64_t key64 = 0; - char *fptr; int clen = 0; int transferToEml = 0; int createDumpFile = 0; @@ -2744,22 +2757,13 @@ static int CmdHF14AMfChk(const char *Cmd) { ); } - // initialize storage for found keys - e_sector = calloc(SectorsCnt, sizeof(sector_t)); - if (e_sector == NULL) { + // create/initialize key storage structure + int32_t res = initSectorTable(&e_sector, SectorsCnt); + if (res != SectorsCnt) { free(keyBlock); return PM3_EMALLOC; } - // empty e_sector - for (i = 0; i < SectorsCnt; ++i) { - e_sector[i].Key[0] = 0xffffffffffff; - e_sector[i].Key[1] = 0xffffffffffff; - e_sector[i].foundKey[0] = false; - e_sector[i].foundKey[1] = false; - } - - uint8_t trgKeyType = 0; uint16_t max_keys = keycnt > KEYS_IN_BLOCK ? KEYS_IN_BLOCK : keycnt; @@ -2866,10 +2870,9 @@ out: PrintAndLogEx(SUCCESS, "Found keys have been transferred to the emulator memory"); } - if (createDumpFile) { - fptr = GenerateFilename("hf-mf-", "-key.bin"); - createMfcKeyDump(SectorsCnt, e_sector, fptr); - } + if (createDumpFile) + createMfcKeyDump(GenerateFilename("hf-mf-", "-key"), SectorsCnt, e_sector); + free(keyBlock); free(e_sector); @@ -2887,22 +2890,6 @@ out: sector_t *k_sector = NULL; uint8_t k_sectorsCount = 16; -static void emptySectorTable() { - - // initialize storage for found keys - if (k_sector == NULL) - k_sector = calloc(k_sectorsCount, sizeof(sector_t)); - if (k_sector == NULL) - return; - - // empty e_sector - for (int i = 0; i < k_sectorsCount; ++i) { - k_sector[i].Key[0] = 0xffffffffffff; - k_sector[i].Key[1] = 0xffffffffffff; - k_sector[i].foundKey[0] = false; - k_sector[i].foundKey[1] = false; - } -} void showSectorTable() { if (k_sector != NULL) { @@ -2917,8 +2904,12 @@ void readerAttack(nonces_t data, bool setEmulatorMem, bool verbose) { uint64_t key = 0; bool success = false; - if (k_sector == NULL) - emptySectorTable(); + if (k_sector == NULL) { + int32_t res = initSectorTable(&k_sector, k_sectorsCount); + if (res != k_sectorsCount) { + return; + } + } success = mfkey32_moebius(&data, &key); if (success) { diff --git a/client/fileutils.c b/client/fileutils.c index 74cd6ab21..1677fe388 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -463,33 +463,43 @@ out: return retval; } -int createMfcKeyDump(uint8_t sectorsCnt, sector_t *e_sector, char *fptr) { - uint8_t tmpKey[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; - int i; +int createMfcKeyDump(const char *preferredName, uint8_t sectorsCnt, sector_t *e_sector) { - if (fptr == NULL) { - return PM3_EINVARG; - } - - FILE *fkeys = fopen(fptr, "wb"); - if (fkeys == NULL) { - PrintAndLogEx(WARNING, "Could not create file " _YELLOW_("%s"), fptr); + if (e_sector == NULL) return PM3_EINVARG; + + char *fileName = newfilenamemcopy(preferredName, ".bin"); + if (fileName == NULL) return PM3_EMALLOC; + + FILE *f = fopen(fileName, "wb"); + if (f == NULL) { + PrintAndLogEx(WARNING, "Could not create file " _YELLOW_("%s"), fileName); return PM3_EFILE; } - PrintAndLogEx(SUCCESS, "Printing keys to binary file " _YELLOW_("%s")"...", fptr); + PrintAndLogEx(SUCCESS, "Generating binary key file"); - for (i = 0; i < sectorsCnt; i++) { - num_to_bytes(e_sector[i].Key[0], 6, tmpKey); - fwrite(tmpKey, 1, 6, fkeys); + uint8_t empty[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + uint8_t tmp[6] = {0, 0, 0, 0, 0, 0}; + + for (int i = 0; i < sectorsCnt; i++) { + if (e_sector[i].foundKey[0]) + num_to_bytes(e_sector[i].Key[0], sizeof(tmp), tmp); + else + memcpy(tmp, empty, sizeof(tmp)); + fwrite(tmp, 1, sizeof(tmp), f); } - for (i = 0; i < sectorsCnt; i++) { - num_to_bytes(e_sector[i].Key[1], 6, tmpKey); - fwrite(tmpKey, 1, 6, fkeys); + for (int i = 0; i < sectorsCnt; i++) { + if (e_sector[i].foundKey[0]) + num_to_bytes(e_sector[i].Key[1], sizeof(tmp), tmp); + else + memcpy(tmp, empty, sizeof(tmp)); + fwrite(tmp, 1, sizeof(tmp), f); } - fclose(fkeys); - PrintAndLogEx(SUCCESS, "Found keys have been dumped to " _YELLOW_("%s")" --> 0xffffffffffff has been inserted for unknown keys.", fptr); + fflush(f); + fclose(f); + PrintAndLogEx(SUCCESS, "Found keys have been dumped to " _YELLOW_("%s")"--> 0xffffffffffff has been inserted for unknown keys.", fileName); + free(fileName); return PM3_SUCCESS; } diff --git a/client/fileutils.h b/client/fileutils.h index baff10bca..3747e0850 100644 --- a/client/fileutils.h +++ b/client/fileutils.h @@ -137,14 +137,14 @@ int saveFileWAVE(const char *preferredName, int *data, size_t datalen); int saveFilePM3(const char *preferredName, int *data, size_t datalen); /** - * @brief Utility function to save a keydump. + * @brief Utility function to save a keydump into a binary file. * + * @param preferredName * @param sectorsCnt the used sectors * @param e_sector the keys in question - * @param fptr string pointer to the filename * @return 0 for ok, 1 for failz */ -int createMfcKeyDump(uint8_t sectorsCnt, sector_t *e_sector, char *fptr); +int createMfcKeyDump(const char *preferredName, uint8_t sectorsCnt, sector_t *e_sector); /** * @brief Utility function to load data from a binary file. This method takes a preferred name. From c2006e380855216bf3b868e025c2260c1f1e8faa Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 26 Dec 2019 00:09:44 +0100 Subject: [PATCH 1269/1854] add: mfu_magic.lua - script to talk with your Magic NTAG tag. --- client/luascripts/mfu_magic.lua | 658 ++++++++++++++++++++++++++++++++ 1 file changed, 658 insertions(+) create mode 100644 client/luascripts/mfu_magic.lua diff --git a/client/luascripts/mfu_magic.lua b/client/luascripts/mfu_magic.lua new file mode 100644 index 000000000..a10b5776d --- /dev/null +++ b/client/luascripts/mfu_magic.lua @@ -0,0 +1,658 @@ +local cmds = require('commands') +local getopt = require('getopt') +local lib14a = require('read14a') +local utils = require('utils') + +-- global +local DEBUG = false -- the debug flag +local bxor = bit32.bxor +local _password = nil +local err_lock = 'use -k or change cfg0 block' + +copyright = 'Copyright (c) 2017 IceSQL AB. All rights reserved.' +author = 'Christian Herrmann' +version = 'v1.1.1' +desc = 'This script enables easy programming of a MAGIC NTAG 21* card' +example = +[[ + -- wipe tag + script run mfu_magic -w + + -- wipe a locked down tag by giving the password + script run mfu_magic -k ffffffff -w + + --read magic tag configuration + script run mfu_magic -c + + -- set uid + script run mfu_magic -u 04112233445566 + + -- set pwd / pack + script run mfu_magic -p 11223344 -a 8080 + + -- set version to NTAG213 + script run mfu_magic -v 0004040201000f03 + + -- set signature + script run mfu_magic -s 1122334455667788990011223344556677889900112233445566778899001122 +]] +usage = +[[ +Usage: +script run mfu_magic -h -k -c -w -u -t -p -a -s -o -v + +Arguments: + -h this help + -c read magic configuration + -u UID (14 hexsymbols), set UID on tag + -t tag type to impersonate + 1 = UL_EV1 48k + 2 = UL_EV1 128k + 3 = NTAG 210 + 4 = NTAG 212 + 5 = NTAG 213 (true) + 6 = NTAG 215 (true) + 7 = NTAG 216 (true) + 8 = NTAG I2C 1K + 9 = NTAG I2C 2K + 10 = NTAG I2C 1K PLUS + 11 = NTAG I2C 2K PLUS + 12 = NTAG 213F (true) + 13 = NTAG 216F (true) + -p password (8 hexsymbols), set password on tag. + -a pack ( 4 hexsymbols), set pack on tag. + -s signature data (64 hexsymbols), set signature data on tag. + -o OTP data (8 hexsymbols), set one-time-pad data on tag. + -v version data (16 hexsymbols), set version data on tag. + -w wipe tag. You can specify password if the tag has been locked down. Fills tag with zeros and put default values for NTAG213 (like -t 5) + -k pwd to use with the wipe option +]] +--- +-- A debug printout-function +local function dbg(args) + if not DEBUG then return end + if type(args) == 'table' then + local i = 1 + while result[i] do + dbg(result[i]) + i = i+1 + end + else + print('###', args) + end +end +-- This is only meant to be used when errors occur +local function oops(err) + print("ERROR: ",err) + core.clearCommandBuffer() + return nil, err +end +--- +-- Usage help +local function help() + print(copyright) + print(author) + print(version) + print(desc) + print('Example usage') + print(example) + print(usage) +end +--- +-- set the global password variable +local function set_password(pwd) + if pwd == nil then _password = nil; return true, 'Ok' end + if #pwd ~= 8 then return nil, 'password wrong length. Must be 4 hex bytes' end + if #pwd == 0 then _password = nil end + _password = pwd + return true, 'Ok' +end +--- Picks out and displays the data read from a tag +-- Specifically, takes a usb packet, converts to a Command +-- (as in commands.lua), takes the data-array and +-- reads the number of bytes specified in arg1 (arg0 in c-struct) +-- @param usbpacket the data received from the device +local function getResponseData(usbpacket) + local resp = Command.parse(usbpacket) + local len = tonumber(resp.arg1) * 2 + return string.sub(tostring(resp.data), 0, len); +end +--- +-- +local function sendRaw(rawdata, options) + + local flags = lib14a.ISO14A_COMMAND.ISO14A_NO_DISCONNECT + + lib14a.ISO14A_COMMAND.ISO14A_RAW + + lib14a.ISO14A_COMMAND.ISO14A_APPEND_CRC + + local c = Command:newMIX{cmd = cmds.CMD_READER_ISO_14443a, + arg1 = flags, + -- arg2 contains the length, which is half the length of the ASCII-string rawdata + arg2 = string.len(rawdata)/2, + data = rawdata} + + return c:sendMIX(options.ignore_response) +end +--- +-- +local function send(payload) + local usb, err = sendRaw(payload,{ignore_response = false}) + if err then return oops(err) end + return getResponseData(usb) +end +--- +-- select tag and if password is set, authenticate +local function connect() + core.clearCommandBuffer() + + -- First of all, connect + info, err = lib14a.read(true, true) + if err then + lib14a.disconnect() + return oops(err) + end + core.clearCommandBuffer() + + --authenticate if needed using global variable + if _password then + send('1B'.._password) + end + return true +end +-- +-- Read magic configuration +local function read_config() + local info = connect() + if not info then return false, "Can't select card" end + + -- read PWD + local pwd = send("30F0"):sub(1,8) + + -- 04 response indicates that blocks has been locked down. + if pwd == '04' then lib14a.disconnect(); return nil, "can't read configuration, "..err_lock end + + -- read PACK + local pack = send("30F1"):sub(1,4) + + -- read SIGNATURE + local signature1 = send('30F2'):sub(1,32) + local signature2 = send('30F6'):sub(1,32) + + -- read VERSION + local version = send('30FA'):sub(1,16) + -- read config + local cardtype = send('30FC'):sub(1,2) + + local typestr = '' + if cardtype == '00' then typestr = 'NTAG 213' + elseif cardtype == '01' then typestr = 'NTAG 215' + elseif cardtype == '02' then typestr = 'NTAG 216' + end + + print('Magic NTAG 21* Configuration') + print(' - Type ', typestr, '(geniune cardtype)') + print(' - Password', pwd) + print(' - Pack ', pack) + print(' - Version ', version) + print(' - Signature', signature1..signature2) + + lib14a.disconnect() + return true, 'Ok' +end +--- +-- Write SIGNATURE data +local function write_signature(data) + + -- uid string checks + if data == nil then return nil, 'empty data string' end + if #data == 0 then return nil, 'empty data string' end + if #data ~= 64 then return nil, 'data wrong length. Should be 32 hex bytes' end + + local info = connect() + if not info then return false, "Can't select card" end + + print('Writing new signature') + + local b,c + local cmd = 'A2F%d%s' + local j = 2 + for i = 1, #data, 8 do + b = data:sub(i,i+7) + c = cmd:format(j,b) + local resp = send(c) + if resp == '04' then lib14a.disconnect(); return nil, 'Failed to write signature' end + j = j + 1 + end + lib14a.disconnect() + return true, 'Ok' +end +--- +-- Write PWD +local function write_pwd(pwd) + -- PWD string checks + if pwd == nil then return nil, 'empty PWD string' end + if #pwd == 0 then return nil, 'empty PWD string' end + if #pwd ~= 8 then return nil, 'PWD wrong length. Should be 4 hex bytes' end + + local info = connect() + if not info then return false, "Can't select card" end + + print('Writing new PWD ', pwd) + + local resp = send('A2F0'..pwd) + lib14a.disconnect() + if resp == '04' then + return nil, 'Failed to write password' + else + return true, 'Ok' + end +end +--- +-- Write PACK +local function write_pack(pack) + -- PACK string checks + if pack == nil then return nil, 'empty PACK string' end + if #pack == 0 then return nil, 'empty PACK string' end + if #pack ~= 4 then return nil, 'PACK wrong length. Should be 4 hex bytes' end + + local info = connect() + if not info then return false, "Can't select card" end + + print('Writing new PACK', pack) + + local resp = send('A2F1'..pack..'0000') + lib14a.disconnect() + if resp == '04' then + return nil, 'Failed to write pack' + else + return true, 'Ok' + end +end +-- +-- Write OTP block +local function write_otp(block3) + + -- OTP string checks + if block3 == nil then return nil, 'empty OTP string' end + if #block3 == 0 then return nil, 'empty OTP string' end + if #block3 ~= 8 then return nil, 'OTP wrong length. Should be 4 hex bytes' end + + local info = connect() + if not info then return false, "Can't select card" end + + print('Writing new OTP ', block3) + + local resp = send('A203'..block3) + lib14a.disconnect() + if resp == '04' then + return nil, 'Failed to write OTP' + else + return true, 'Ok' + end +end +-- +-- Writes a UID with bcc1, bcc2. Needs a magic tag. +local function write_uid(uid) + -- uid string checks + if uid == nil then return nil, 'empty uid string' end + if #uid == 0 then return nil, 'empty uid string' end + if #uid ~= 14 then return nil, 'uid wrong length. Should be 7 hex bytes' end + + local info = connect() + if not info then return false, "Can't select card" end + + print('Writing new UID ', uid) + + local uidbytes = utils.ConvertHexToBytes(uid) + local bcc1 = bxor(bxor(bxor(uidbytes[1], uidbytes[2]), uidbytes[3]), 0x88) + local bcc2 = bxor(bxor(bxor(uidbytes[4], uidbytes[5]), uidbytes[6]), uidbytes[7]) + local block0 = string.format('%02X%02X%02X%02X', uidbytes[1], uidbytes[2], uidbytes[3], bcc1) + local block1 = string.format('%02X%02X%02X%02X', uidbytes[4], uidbytes[5], uidbytes[6], uidbytes[7]) + local block2 = string.format('%02X%02X%02X%02X', bcc2, 0x48, 0x00, 0x00) + local resp + + resp = send('A200'..block0) + resp = send('A201'..block1) + resp = send('A202'..block2) + lib14a.disconnect() + + if resp == '04' then + return nil, 'Failed to write new uid' + else + return true, 'Ok' + end +end +--- +-- Write VERSION data, +-- make sure you have correct version data +local function write_version(data) + -- version string checks + if data == nil then return nil, 'empty version string' end + if #data == 0 then return nil, 'empty version string' end + if #data ~= 16 then return nil, 'version wrong length. Should be 8 hex bytes' end + + local info = connect() + if not info then return false, "Can't select card" end + + print('Writing new version', data) + + local b1 = data:sub(1,8) + local b2 = data:sub(9,16) + local resp + resp = send('A2FA'..b1) + resp = send('A2FB'..b2) + lib14a.disconnect() + if resp == '04' then + return nil, 'Failed to write version' + else + return true, 'Ok' + end +end +--- +-- writen TYPE which card is based on. +-- 00 = 213, 01 = 215, 02 = 216 +local function write_type(data) + -- type string checks + if data == nil then return nil, 'empty type string' end + if #data == 0 then return nil, 'empty type string' end + if #data ~= 2 then return nil, 'type wrong length. Should be 1 hex byte' end + + local info = connect() + if not info then return false, "Can't select card" end + print('Writing new type', data) + + local resp = send('A2FC'..data..'000000') + lib14a.disconnect() + if resp == '04' then + return nil, 'Failed to write type' + else + return true, 'Ok' + end +end +--- +-- Set tag type. Predefinde version data together with magic type set. +-- Since cmd always gives 10 bytes len (data+crc) we can impersonate the following types +-- we only truely be three types NTAG 213,215 and 216 +local function set_type(tagtype) + + -- tagtype checks + if type(tagtype) == 'string' then tagtype = tonumber(tagtype, 10) end + if tagtype == nil then return nil, 'empty tagtype' end + + if tagtype == 1 then + print('Setting: UL-EV1 48') + write_otp('00000000') -- Setting OTP to default 00 00 00 00 + write_version('0004030101000b03') -- UL-EV1 (48) 00 04 03 01 01 00 0b 03 + write_type('00') -- based on NTAG213.. + + -- Setting UL-Ev1 default config bl 16,17 + connect() + send('a210000000FF') + send('a21100050000') + + elseif tagtype == 2 then + print('Setting: UL-EV1 128') + write_otp('00000000') -- Setting OTP to default 00 00 00 00 + write_version('0004030101000e03') -- UL-EV1 (128) 00 04 03 01 01 00 0e 03 + write_type('01') + + -- Setting UL-Ev1 default config bl 37,38 + connect() + send('a225000000FF') + send('a22600050000') + elseif tagtype == 3 then + print('Setting: NTAG 210') + write_version('0004040101000b03') -- NTAG210 00 04 04 01 01 00 0b 03 + write_type('00') + + -- Setting NTAG210 default CC block456 + connect() + send('a203e1100600') + send('a2040300fe00') + send('a20500000000') + -- Setting cfg1/cfg2 + send('a210000000FF') + send('a21100050000') + elseif tagtype == 4 then + print('Setting: NTAG 212') + write_version('0004040101000E03') -- NTAG212 00 04 04 01 01 00 0E 03 + write_type('00') + + -- Setting NTAG212 default CC block456 + connect() + send('a203e1101000') + send('a2040103900a') + send('a205340300fe') + -- Setting cfg1/cfg2 + send('a225000000FF') + send('a22600050000') + elseif tagtype == 5 then + print('Setting: NTAG 213') + write_version('0004040201000F03') -- NTAG213 00 04 04 02 01 00 0f 03 + write_type('00') + + -- Setting NTAG213 default CC block456 + connect() + send('a203e1101200') + send('a2040103a00c') + send('a205340300fe') + -- setting cfg1/cfg2 + send('a229000000ff') + send('a22a00050000') + elseif tagtype == 6 then + print('Setting: NTAG 215') + write_version('0004040201001103') -- NTAG215 00 04 04 02 01 00 11 03 + write_type('01') + + -- Setting NTAG215 default CC block456 + connect() + send('a203e1103e00') + send('a2040300fe00') + send('a20500000000') + -- setting cfg1/cfg2 + send('a283000000ff') + send('a28400050000') + elseif tagtype == 7 then + print('Setting: NTAG 216') + write_version('0004040201001303') -- NTAG216 00 04 04 02 01 00 13 03 + write_type('02') + + -- Setting NTAG216 default CC block456 + connect() + send('a203e1106d00') + send('a2040300fe00') + send('a20500000000') + -- setting cfg1/cfg2 + send('a2e3000000ff') + send('a2e400050000') + elseif tagtype == 8 then + print('Setting: NTAG I2C 1K') + write_version('0004040502011303') -- NTAG_I2C_1K 00 04 04 05 02 01 13 03 + write_type('02') + + -- Setting NTAG I2C 1K default CC block456 + connect() + send('a203e1106D00') + send('a2040300fe00') + send('a20500000000') + elseif tagtype == 9 then + print('Setting: NTAG I2C 2K') + write_version('0004040502011503') -- NTAG_I2C_2K 00 04 04 05 02 01 15 03 + write_type('02') + + -- Setting NTAG I2C 2K default CC block456 + connect() + send('a203e110EA00') + send('a2040300fe00') + send('a20500000000') + elseif tagtype == 10 then + print('Setting: NTAG I2C plus 1K') + write_version('0004040502021303') -- NTAG_I2C_1K 00 04 04 05 02 02 13 03 + write_type('02') + + -- Setting NTAG I2C 1K default CC block456 + connect() + send('a203e1106D00') + send('a2040300fe00') + send('a20500000000') + elseif tagtype == 11 then + print('Setting: NTAG I2C plus 2K') + write_version('0004040502021503') -- NTAG_I2C_2K 00 04 04 05 02 02 15 03 + write_type('02') + + -- Setting NTAG I2C 2K default CC block456 + connect() + send('a203e1106D00') + send('a2040300fe00') + send('a20500000000') + elseif tagtype == 12 then + print('Setting: NTAG 213F') + write_version('0004040401000F03') -- NTAG213F 00 04 04 04 01 00 0f 03 + write_type('00') + + -- Setting NTAG213 default CC block456 + connect() + send('a203e1101200') + send('a2040103a00c') + send('a205340300fe') + -- setting cfg1/cfg2 + send('a229000000ff') + send('a22a00050000') + elseif tagtype == 13 then + print('Setting: NTAG 216F') + write_version('0004040401001303') -- NTAG216F 00 04 04 04 01 00 13 03 + write_type('02') + + -- Setting NTAG216 default CC block456 + connect() + send('a203e1106d00') + send('a2040300fe00') + send('a20500000000') + -- setting cfg1/cfg2 + send('a2e3000000ff') + send('a2e400050000') + end + + lib14a.disconnect() + if resp == '04' then + return nil, 'Failed to set type' + else + return true, 'Ok' + end +end +--- +-- wipe tag +local function wipe() + + local info = connect() + if not info then return false, "Can't select card" end + + local err, msg, resp + local cmd_empty = 'A2%02X00000000' + local cmd_cfg1 = 'A2%02X000000FF' + local cmd_cfg2 = 'A2%02X00050000' + + print('Wiping tag') + + for b = 3, 0xFB do + --configuration block 0 + if b == 0x29 or b == 0x83 or b == 0xe3 then + local cmd = (cmd_cfg1):format(b) + resp = send(cmd) + --configuration block 1 + elseif b == 0x2a or b == 0x84 or b == 0xe4 then + local cmd = (cmd_cfg2):format(b) + resp = send(cmd) + else + resp = send(cmd_empty:format(b)) + end + if resp == '04' or #resp == 0 then + io.write('\nwrote block '..b, ' failed\n') + err = true + else + io.write('.') + end + io.flush() + end + io.write('\r\n') + + lib14a.disconnect() + + if err then return nil, "Tag locked down, "..err_lock end + + print('setting default values...') + + set_password(nil) + + -- set NTAG213 default values + err, msg = set_type(5) + if err == nil then return err, msg end + + --set UID + err, msg = write_uid('04112233445566') + if err == nil then return err, msg end + + --set pwd + err, msg = write_pwd('FFFFFFFF') + if err == nil then return err, msg end + + --set pack + err, msg = write_pack('0000') + if err == nil then return err, msg end + + return true, 'Ok' +end +--- +-- The main entry point +function main(args) + + print( string.rep('--',20) ) + print( string.rep('--',20) ) + print() + + local err, msg + + if #args == 0 then return help() end + + -- Read the parameters + for o, a in getopt.getopt(args, 'hck:u:t:p:a:s:o:v:w') do + + -- help + if o == "h" then return help() end + + --key + if o == 'k' then err, msg = set_password(a) end + + -- configuration + if o == "c" then err, msg = read_config() end + + --wipe tag + if o == "w" then err, msg = wipe() end + + -- write uid + if o == "u" then err, msg = write_uid(a) end + + -- write type/version + if o == "t" then err, msg = set_type(a) end + + -- write pwd + if o == "p" then err, msg = write_pwd(a) end + + -- write pack + if o == "a" then err, msg = write_pack(a) end + + -- write signature + if o == "s" then err, msg = write_signature(a) end + + -- write otp + if o == "o" then err, msg = write_otp(a) end + + -- write version + if o == "v" then err, msg = write_version(a) end + + if err == nil then return oops(msg) end + end + +end + +main(args) From 315291e201efd1d96ac724dbd2478966408beb27 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 26 Dec 2019 00:11:16 +0100 Subject: [PATCH 1270/1854] textual --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f9f00c43..200da096e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Add mfu_magic.lua - script to interact with your magic NTAG tag. (@iceman1001) - Add `hf_bruteforce.lua` - script bruteforces uid for 14a using hf 14a sim (@keld) - Add `tools\pm3_cs8.pl` - convert .pm3 files to wave format (@samyk) - Add `tools\pm3_amii_bin2eml.pl` - amiibo convering script (@samyk) From 03495f0b1413abdc1cd925a6052417b71873e521 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 26 Dec 2019 00:22:21 +0100 Subject: [PATCH 1271/1854] style --- client/fileutils.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/client/fileutils.c b/client/fileutils.c index 1677fe388..c8cdb3462 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -466,10 +466,10 @@ out: int createMfcKeyDump(const char *preferredName, uint8_t sectorsCnt, sector_t *e_sector) { if (e_sector == NULL) return PM3_EINVARG; - + char *fileName = newfilenamemcopy(preferredName, ".bin"); if (fileName == NULL) return PM3_EMALLOC; - + FILE *f = fopen(fileName, "wb"); if (f == NULL) { PrintAndLogEx(WARNING, "Could not create file " _YELLOW_("%s"), fileName); @@ -479,20 +479,20 @@ int createMfcKeyDump(const char *preferredName, uint8_t sectorsCnt, sector_t *e_ uint8_t empty[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; uint8_t tmp[6] = {0, 0, 0, 0, 0, 0}; - + for (int i = 0; i < sectorsCnt; i++) { - if (e_sector[i].foundKey[0]) + if (e_sector[i].foundKey[0]) num_to_bytes(e_sector[i].Key[0], sizeof(tmp), tmp); - else - memcpy(tmp, empty, sizeof(tmp)); + else + memcpy(tmp, empty, sizeof(tmp)); fwrite(tmp, 1, sizeof(tmp), f); } for (int i = 0; i < sectorsCnt; i++) { - if (e_sector[i].foundKey[0]) + if (e_sector[i].foundKey[0]) num_to_bytes(e_sector[i].Key[1], sizeof(tmp), tmp); - else - memcpy(tmp, empty, sizeof(tmp)); + else + memcpy(tmp, empty, sizeof(tmp)); fwrite(tmp, 1, sizeof(tmp), f); } From 83e8eeb1f8e7de69adfdf79afcf913d88169fc6e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 26 Dec 2019 00:23:01 +0100 Subject: [PATCH 1272/1854] Chg: 'lf t55xx dump' - now saves as JSON format aswell --- client/cmdlft55xx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 9135ab957..72dc7befe 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -2325,6 +2325,7 @@ static int CmdT55xxDump(const char *Cmd) { for (int i = 0; i < T55x7_BLOCK_COUNT; i++) data[i] = BSWAP_32(cardmem[i].blockdata); + saveFileJSON(preferredName, jsfT55x7, (uint8_t *)data, T55x7_BLOCK_COUNT * sizeof(uint32_t)); saveFileEML(preferredName, (uint8_t *)data, T55x7_BLOCK_COUNT * sizeof(uint32_t), sizeof(uint32_t)); saveFile(preferredName, ".bin", data, sizeof(data)); } From 657061f8d5c9c94897d417c22b50554e74897239 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 26 Dec 2019 23:41:30 +0100 Subject: [PATCH 1273/1854] fix: use defines.. --- armsrc/Standalone/hf_colin.c | 2 +- armsrc/Standalone/hf_mattyrun.c | 2 +- armsrc/mifarecmd.c | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/armsrc/Standalone/hf_colin.c b/armsrc/Standalone/hf_colin.c index 8efcb1003..ffe2a613f 100644 --- a/armsrc/Standalone/hf_colin.c +++ b/armsrc/Standalone/hf_colin.c @@ -1059,7 +1059,7 @@ int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *data }; } - if ((mifare_sendcmd_short(NULL, 0, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 1) || + if ((mifare_sendcmd_short(NULL, CRYPT_NONE, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 1) || (receivedAnswer[0] != 0x0a)) { DbprintfEx(FLAG_NEWLINE, "write block send command error"); break; diff --git a/armsrc/Standalone/hf_mattyrun.c b/armsrc/Standalone/hf_mattyrun.c index 9fff4a226..3e53fffe9 100644 --- a/armsrc/Standalone/hf_mattyrun.c +++ b/armsrc/Standalone/hf_mattyrun.c @@ -136,7 +136,7 @@ static int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_ }; } - if ((mifare_sendcmd_short(NULL, 0, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 1) || (receivedAnswer[0] != 0x0a)) { + if ((mifare_sendcmd_short(NULL, CRYPT_NONE, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 1) || (receivedAnswer[0] != 0x0a)) { DbprintfEx(FLAG_NEWLINE, "write block send command error"); break; }; diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index d0dd27be8..47c353855 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -1889,7 +1889,7 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain) { } } - if ((mifare_sendcmd_short(NULL, 0, ISO14443A_CMD_WRITEBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 1) || (receivedAnswer[0] != 0x0a)) { + if ((mifare_sendcmd_short(NULL, CRYPT_NONE, ISO14443A_CMD_WRITEBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 1) || (receivedAnswer[0] != 0x0a)) { if (DBGLEVEL >= DBG_ERROR) Dbprintf("write block send command error"); errormsg = 4; break; @@ -1968,7 +1968,7 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain) { } // read block - if ((mifare_sendcmd_short(NULL, 0, ISO14443A_CMD_READBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 18)) { + if ((mifare_sendcmd_short(NULL, CRYPT_NONE, ISO14443A_CMD_READBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 18)) { if (DBGLEVEL >= DBG_ERROR) Dbprintf("read block send command error"); errormsg = 0; break; @@ -2154,7 +2154,7 @@ void MifareSetMod(uint8_t *datain) { } int respLen; - if (((respLen = mifare_sendcmd_short(pcs, 1, 0x43, mod, receivedAnswer, receivedAnswerPar, NULL)) != 1) || (receivedAnswer[0] != 0x0a)) { + if (((respLen = mifare_sendcmd_short(pcs, CRYPT_ALL, 0x43, mod, receivedAnswer, receivedAnswerPar, NULL)) != 1) || (receivedAnswer[0] != 0x0a)) { if (DBGLEVEL >= 1) Dbprintf("SetMod error; response[0]: %hhX, len: %d", receivedAnswer[0], respLen); break; } From ac6afe9c0488798cfb78ce7e93fef01582ddf569 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 28 Dec 2019 21:40:52 +0100 Subject: [PATCH 1274/1854] Chg: 'lf t55xx dump - updated json format --- client/fileutils.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/fileutils.c b/client/fileutils.c index c8cdb3462..a11dbcd2a 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -338,9 +338,9 @@ int saveFileJSON(const char *preferredName, JSONFileType ftype, uint8_t *data, s } case jsfT55x7: { JsonSaveStr(root, "FileType", "t55x7"); - uint8_t id[4] = {0}; - memcpy(id, data, 4); - JsonSaveBufAsHexCompact(root, "$.Card.ID", id, sizeof(id)); + uint8_t conf[4] = {0}; + memcpy(conf, data, 4); + JsonSaveBufAsHexCompact(root, "$.Card.ConfigBlock", conf, sizeof(conf)); for (size_t i = 0; i < (datalen / 4); i++) { char path[PATH_MAX_LENGTH] = {0}; From 072255d04fa0ca56fce6adb22da65c66a297d91e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 28 Dec 2019 23:51:17 +0100 Subject: [PATCH 1275/1854] fix: 'hf mf chk' - reading block B ... https://github.com/RfidResearchGroup/proxmark3/issues/489 --- client/cmdhfmf.c | 260 +++++++++++++++++++++++++++++++++-------------- client/cmdhfmf.h | 1 + 2 files changed, 184 insertions(+), 77 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 5a70488fe..910763a23 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -49,7 +49,7 @@ static int usage_hf14_ice(void) { PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf mf ice"); PrintAndLogEx(NORMAL, " hf mf ice f nonces.bin"); - return 0; + return PM3_SUCCESS; } static int usage_hf14_dump(void) { @@ -61,7 +61,7 @@ static int usage_hf14_dump(void) { PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf mf dump"); PrintAndLogEx(NORMAL, " hf mf dump 4"); - return 0; + return PM3_SUCCESS; } static int usage_hf14_mifare(void) { @@ -74,7 +74,7 @@ static int usage_hf14_mifare(void) { PrintAndLogEx(NORMAL, " hf mf darkside"); PrintAndLogEx(NORMAL, " hf mf darkside 16"); PrintAndLogEx(NORMAL, " hf mf darkside 16 B"); - return 0; + return PM3_SUCCESS; } static int usage_hf14_mfsim(void) { PrintAndLogEx(NORMAL, "Usage: hf mf sim [u ] [n ] [t] [a ] [s ] [i] [x] [e] [v]"); @@ -98,7 +98,7 @@ static int usage_hf14_mfsim(void) { PrintAndLogEx(NORMAL, " hf mf sim u 11223344556677"); PrintAndLogEx(NORMAL, " hf mf sim u 112233445566778899AA"); PrintAndLogEx(NORMAL, " hf mf sim u 11223344 i x"); - return 0; + return PM3_SUCCESS; } /* * static int usage_hf14_sniff(void) { @@ -112,14 +112,13 @@ static int usage_hf14_mfsim(void) { PrintAndLogEx(NORMAL, " f decrypt sequence, collect read and write commands and save the result of the sequence to emulator dump file `uid.eml`"); PrintAndLogEx(NORMAL, "Example:"); PrintAndLogEx(NORMAL, " hf mf sniff l d f"); - return 0; + return PM3_SUCCESS; } */ static int usage_hf14_nested(void) { PrintAndLogEx(NORMAL, "Usage:"); - PrintAndLogEx(NORMAL, " all sectors: hf mf nested [t,d]"); - PrintAndLogEx(NORMAL, " one sector: hf mf nested o "); - PrintAndLogEx(NORMAL, " [t]"); + PrintAndLogEx(NORMAL, " all sectors: hf mf nested [t,d]"); + PrintAndLogEx(NORMAL, " one sector: hf mf nested o [t]"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h this help"); PrintAndLogEx(NORMAL, " card memory - 0 - MINI(320 bytes), 1 - 1K, 2 - 2K, 4 - 4K, - 1K"); @@ -127,11 +126,11 @@ static int usage_hf14_nested(void) { PrintAndLogEx(NORMAL, " d write keys to binary file `hf-mf--key.bin`"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf mf nested 1 0 A FFFFFFFFFFFF -- nested attack against 1k,block 0, Key A using key FFFFFFFFFFFF"); - PrintAndLogEx(NORMAL, " hf mf nested 1 0 A FFFFFFFFFFFF t -- and transfer keys into emulator memory"); - PrintAndLogEx(NORMAL, " hf mf nested 1 0 A FFFFFFFFFFFF d -- or write keys to binary file "); - PrintAndLogEx(NORMAL, " hf mf nested o 0 A FFFFFFFFFFFF 4 A"); - return 0; + PrintAndLogEx(NORMAL, " hf mf nested 1 0 A FFFFFFFFFFFF -- nested attack against 1K, block 0, Key A using key FFFFFFFFFFFF"); + PrintAndLogEx(NORMAL, " hf mf nested 1 0 A FFFFFFFFFFFF t -- and transfer keys into emulator memory"); + PrintAndLogEx(NORMAL, " hf mf nested 1 0 A FFFFFFFFFFFF d -- or write keys to binary file "); + PrintAndLogEx(NORMAL, " hf mf nested o 0 A FFFFFFFFFFFF 4 A -- nested attack against ONE sector. Use block 0 Key A to find block 4 Key A"); + return PM3_SUCCESS; } static int usage_hf14_hardnested(void) { PrintAndLogEx(NORMAL, "Usage:"); @@ -164,7 +163,7 @@ static int usage_hf14_hardnested(void) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Add the known target key to check if it is present in the remaining key space:"); PrintAndLogEx(NORMAL, " hf mf hardnested 0 A A0A1A2A3A4A5 4 A FFFFFFFFFFFF"); - return 0; + return PM3_SUCCESS; } static int usage_hf14_autopwn(void) { PrintAndLogEx(NORMAL, "Usage:"); @@ -200,7 +199,7 @@ static int usage_hf14_autopwn(void) { PrintAndLogEx(NORMAL, " hf mf autopwn * 1 f mfc_default_keys -- target Mifare classic card (size 1k) with default dictionary"); PrintAndLogEx(NORMAL, " hf mf autopwn k 0 A FFFFFFFFFFFF -- target Mifare classic card with Sector0 typeA with known key 'FFFFFFFFFFFF'"); PrintAndLogEx(NORMAL, " hf mf autopwn k 0 A FFFFFFFFFFFF * 1 f mfc_default_keys -- this command combines the two above (reduce the need for nested / hardnested attacks, by using a dictionary)"); - return 0; + return PM3_SUCCESS; } static int usage_hf14_chk(void) { PrintAndLogEx(NORMAL, "Usage: hf mf chk [h] |<*card memory> [t|d] [] []"); @@ -219,7 +218,7 @@ static int usage_hf14_chk(void) { PrintAndLogEx(NORMAL, " hf mf chk 0 A mfc_default_keys.dic -- target block 0, Key A using default dictionary file"); PrintAndLogEx(NORMAL, " hf mf chk *1 ? t -- target all blocks, all keys, 1K, write to emulator memory"); PrintAndLogEx(NORMAL, " hf mf chk *1 ? d -- target all blocks, all keys, 1K, write to file"); - return 0; + return PM3_SUCCESS; } static int usage_hf14_chk_fast(void) { PrintAndLogEx(NORMAL, "This is a improved checkkeys method speedwise. It checks Mifare Classic tags sector keys against a dictionary file with keys"); @@ -242,7 +241,7 @@ static int usage_hf14_chk_fast(void) { PrintAndLogEx(NORMAL, " hf mf fchk 1 d -- target 1K, write to file"); if (IfPm3Flash()) PrintAndLogEx(NORMAL, " hf mf fchk 1 m -- target 1K, use dictionary from flashmemory"); - return 0; + return PM3_SUCCESS; } /* static int usage_hf14_keybrute(void) { @@ -276,7 +275,7 @@ static int usage_hf14_restore(void) { PrintAndLogEx(NORMAL, " hf mf restore 1 u 12345678 -- restore from hf-mf-12345678-key.bin and hf-mf-12345678-data.bin"); PrintAndLogEx(NORMAL, " hf mf restore 1 u 12345678 k dumpkey.bin -- restore from dumpkey.bin and hf-mf-12345678-data.bin"); PrintAndLogEx(NORMAL, " hf mf restore 4 -- read the UID from tag with 4K memory first, then restore from hf-mf--key.bin and and hf-mf--data.bin"); - return 0; + return PM3_SUCCESS; } static int usage_hf14_decryptbytes(void) { PrintAndLogEx(NORMAL, "Decrypt Crypto-1 encrypted bytes given some known state of crypto. See tracelog to gather needed values\n"); @@ -290,25 +289,25 @@ static int usage_hf14_decryptbytes(void) { PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf mf decrypt b830049b 9248314a 9280e203 41e586f9\n"); PrintAndLogEx(NORMAL, " this sample decrypts 41e586f9 -> 3003999a Annotated: 30 03 [99 9a] auth block 3 [crc]"); - return 0; + return PM3_SUCCESS; } static int usage_hf14_eget(void) { PrintAndLogEx(NORMAL, "Usage: hf mf eget "); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf mf eget 0 "); - return 0; + return PM3_SUCCESS; } static int usage_hf14_eclr(void) { PrintAndLogEx(NORMAL, "It set card emulator memory to empty data blocks and key A/B FFFFFFFFFFFF \n"); PrintAndLogEx(NORMAL, "Usage: hf mf eclr"); - return 0; + return PM3_SUCCESS; } static int usage_hf14_eset(void) { PrintAndLogEx(NORMAL, "Usage: hf mf eset "); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf mf eset 1 000102030405060708090a0b0c0d0e0f "); - return 0; + return PM3_SUCCESS; } static int usage_hf14_eload(void) { PrintAndLogEx(NORMAL, "It loads emul dump from the file `filename.eml`"); @@ -318,7 +317,7 @@ static int usage_hf14_eload(void) { PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf mf eload filename"); PrintAndLogEx(NORMAL, " hf mf eload 4 filename"); - return 0; + return PM3_SUCCESS; } static int usage_hf14_esave(void) { PrintAndLogEx(NORMAL, "It saves emul dump into the file `filename.eml` or `cardID.eml`"); @@ -329,7 +328,7 @@ static int usage_hf14_esave(void) { PrintAndLogEx(NORMAL, " hf mf esave "); PrintAndLogEx(NORMAL, " hf mf esave 4"); PrintAndLogEx(NORMAL, " hf mf esave 4 filename"); - return 0; + return PM3_SUCCESS; } static int usage_hf14_ecfill(void) { PrintAndLogEx(NORMAL, "Read card and transfer its data to emulator memory."); @@ -340,16 +339,20 @@ static int usage_hf14_ecfill(void) { PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf mf ecfill A"); PrintAndLogEx(NORMAL, " hf mf ecfill A 4"); - return 0; + return PM3_SUCCESS; } static int usage_hf14_ekeyprn(void) { PrintAndLogEx(NORMAL, "It prints the keys loaded in the emulator memory"); - PrintAndLogEx(NORMAL, "Usage: hf mf ekeyprn [card memory]"); - PrintAndLogEx(NORMAL, " [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K"); + PrintAndLogEx(NORMAL, "Usage: hf mf ekeyprn [card memory] [d]"); + PrintAndLogEx(NORMAL, "Options:"); + PrintAndLogEx(NORMAL, " h this help"); + PrintAndLogEx(NORMAL, " card memory - 0 - MINI(320 bytes), 1 - 1K, 2 - 2K, 4 - 4K, - 1K"); + PrintAndLogEx(NORMAL, " d write keys to binary file `hf-mf--key.bin`"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf mf ekeyprn 1"); - return 0; + PrintAndLogEx(NORMAL, " hf mf ekeyprn 1"); + PrintAndLogEx(NORMAL, " hf mf ekeyprn d"); + return PM3_SUCCESS; } static int usage_hf14_csetuid(void) { @@ -365,7 +368,7 @@ static int usage_hf14_csetuid(void) { PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf mf csetuid 01020304"); PrintAndLogEx(NORMAL, " hf mf csetuid 01020304 0004 08 w"); - return 0; + return PM3_SUCCESS; } static int usage_hf14_csetblk(void) { PrintAndLogEx(NORMAL, "Set block data for magic Chinese card. Only works with magic cards"); @@ -379,7 +382,7 @@ static int usage_hf14_csetblk(void) { PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf mf csetblk 1 01020304050607080910111213141516"); PrintAndLogEx(NORMAL, " hf mf csetblk 1 01020304050607080910111213141516 w"); - return 0; + return PM3_SUCCESS; } static int usage_hf14_cload(void) { PrintAndLogEx(NORMAL, "It loads magic Chinese card from the file `filename.eml`"); @@ -395,7 +398,7 @@ static int usage_hf14_cload(void) { PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf mf cload mydump"); PrintAndLogEx(NORMAL, " hf mf cload e"); - return 0; + return PM3_SUCCESS; } static int usage_hf14_cgetblk(void) { PrintAndLogEx(NORMAL, "Get block data from magic Chinese card. Only works with magic cards\n"); @@ -406,7 +409,7 @@ static int usage_hf14_cgetblk(void) { PrintAndLogEx(NORMAL, " block number"); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf mf cgetblk 1"); - return 0; + return PM3_SUCCESS; } static int usage_hf14_cgetsc(void) { PrintAndLogEx(NORMAL, "Get sector data from magic Chinese card. Only works with magic cards\n"); @@ -417,7 +420,7 @@ static int usage_hf14_cgetsc(void) { PrintAndLogEx(NORMAL, " sector number"); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf mf cgetsc 0"); - return 0; + return PM3_SUCCESS; } static int usage_hf14_csave(void) { PrintAndLogEx(NORMAL, "It saves `magic Chinese` card dump into the file `filename.eml` or `cardID.eml`"); @@ -435,7 +438,7 @@ static int usage_hf14_csave(void) { PrintAndLogEx(NORMAL, " hf mf csave u 1"); PrintAndLogEx(NORMAL, " hf mf csave e 1"); PrintAndLogEx(NORMAL, " hf mf csave 4 o filename"); - return 0; + return PM3_SUCCESS; } static int usage_hf14_nack(void) { PrintAndLogEx(NORMAL, "Test a mifare classic based card for the NACK bug."); @@ -446,7 +449,7 @@ static int usage_hf14_nack(void) { PrintAndLogEx(NORMAL, " v verbose"); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf mf nack"); - return 0; + return PM3_SUCCESS; } static int GetHFMF14AUID(uint8_t *uid, int *uidlen) { @@ -1373,9 +1376,12 @@ static int CmdHF14AMfNested(const char *Cmd) { // 20160116 If Sector A is found, but not Sector B, try just reading it of the tag? PrintAndLogEx(INFO, "trying to read key B..."); for (int i = 0; i < SectorsCnt; i++) { - // KEY A but not KEY B + // KEY A but not KEY B if (e_sector[i].foundKey[0] && !e_sector[i].foundKey[1]) { +// 0 - n +//GetSectorFromBlockNo(blockNo) + uint8_t sectrail = (FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1); PrintAndLogEx(SUCCESS, "reading block %d", sectrail); @@ -1616,6 +1622,13 @@ static int CmdHF14AMfNestedHard(const char *Cmd) { } if (!know_target_key && nonce_file_read == false) { + + // check if tag doesn't have static/fixed nonce + if (detect_classic_static_nonce() != 0) { + PrintAndLogEx(WARNING, "Static/fixed nonce detected. Quitting..."); + return PM3_EOPABORTED; + } + uint64_t key64 = 0; // check if we can authenticate to sector if (mfCheckKeys(blockNo, keyType, true, 1, key, &key64) != PM3_SUCCESS) { @@ -2270,7 +2283,7 @@ all_found: _YELLOW_("A") ":keyA " ")" ); - + // Dump the keys PrintAndLogEx(NORMAL, ""); createMfcKeyDump(GenerateFilename("hf-mf-", "-key"), sectors_cnt, e_sector); @@ -2620,17 +2633,10 @@ static int CmdHF14AMfChk(const char *Cmd) { int createDumpFile = 0; int i, keycnt = 0; - keyBlock = calloc(ARRAYLEN(g_mifare_default_keys), 6); - if (keyBlock == NULL) return PM3_EMALLOC; - - for (int cnt = 0; cnt < ARRAYLEN(g_mifare_default_keys); cnt++) - num_to_bytes(g_mifare_default_keys[cnt], 6, (uint8_t *)(keyBlock + cnt * 6)); - if (param_getchar(Cmd, 0) == '*') { blockNo = 3; SectorsCnt = NumOfSectors(param_getchar(Cmd + 1, 0)); if (SectorsCnt == 0) { - free(keyBlock); return usage_hf14_chk(); } } else { @@ -2652,11 +2658,18 @@ static int CmdHF14AMfChk(const char *Cmd) { break; default: PrintAndLogEx(FAILED, "Key type must be A , B or ?"); - free(keyBlock); return PM3_ESOFT; }; } + // Allocate memory for keys to be tested + keyBlock = calloc(ARRAYLEN(g_mifare_default_keys), 6); + if (keyBlock == NULL) return PM3_EMALLOC; + + // Copy default keys to list + for (int cnt = 0; cnt < ARRAYLEN(g_mifare_default_keys); cnt++) + num_to_bytes(g_mifare_default_keys[cnt], 6, (uint8_t *)(keyBlock + cnt * 6)); + for (i = 2; param_getchar(Cmd, i); i++) { ctmp = tolower(param_getchar(Cmd, i)); @@ -2778,6 +2791,7 @@ static int CmdHF14AMfChk(const char *Cmd) { // check keys. for (trgKeyType = (keyType == 2) ? 0 : keyType; trgKeyType < 2; (keyType == 2) ? (++trgKeyType) : (trgKeyType = 2)) { + // loop sectors but block is used as to keep track of from which blocks to test int b = blockNo; for (i = 0; i < SectorsCnt; ++i) { @@ -2813,19 +2827,25 @@ static int CmdHF14AMfChk(const char *Cmd) { // 20160116 If Sector A is found, but not Sector B, try just reading it of the tag? if (keyType != 1) { PrintAndLogEx(INFO, "testing to read key B..."); + + // loop sectors but block is used as to keep track of from which blocks to test + int b = blockNo; for (i = 0; i < SectorsCnt; i++) { - // KEY A but not KEY B + + // KEY A but not KEY B if (e_sector[i].foundKey[0] && !e_sector[i].foundKey[1]) { - uint8_t sectrail = (FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1); - - PrintAndLogEx(NORMAL, "Reading block %d", sectrail); + uint8_t s = GetSectorFromBlockNo(b); + uint8_t sectrail = (FirstBlockOfSector(s) + NumBlocksPerSector(s) - 1); + PrintAndLogEx(INFO, "Sector %u, First block of sector %u, Num of block %u", s, FirstBlockOfSector(s), NumBlocksPerSector(s)); + PrintAndLogEx(INFO, "Reading block %d", sectrail); mf_readblock_t payload; payload.blockno = sectrail; payload.keytype = 0; - num_to_bytes(e_sector[i].Key[0], 6, payload.key); // KEY A + // Use key A + num_to_bytes(e_sector[i].Key[0], 6, payload.key); clearCommandBuffer(); SendCommandNG(CMD_HF_MIFARE_READBL, (uint8_t *)&payload, sizeof(mf_readblock_t)); @@ -2843,12 +2863,16 @@ static int CmdHF14AMfChk(const char *Cmd) { e_sector[i].Key[1] = key64; } } + b < 127 ? (b += 4) : (b += 16); } } out: //print keys - printKeyTable(SectorsCnt, e_sector); + if ( SectorsCnt == 1) + printKeyTableEx(SectorsCnt, e_sector, GetSectorFromBlockNo(blockNo)); + else + printKeyTable(SectorsCnt, e_sector); if (transferToEml) { // fast push mode @@ -2857,11 +2881,14 @@ out: for (i = 0; i < SectorsCnt; ++i) { uint8_t blockno = FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1; mfEmlGetMem(block, blockno, 1); - if (e_sector[i].foundKey[0]) + + if (e_sector[i].foundKey[0]) num_to_bytes(e_sector[i].Key[0], 6, block); + if (e_sector[i].foundKey[1]) num_to_bytes(e_sector[i].Key[1], 6, block + 10); - if (i == SectorsCnt - 1) { + + if (i == SectorsCnt - 1) { // Disable fast mode on last packet conn.block_after_ACK = false; } @@ -3298,6 +3325,9 @@ static int CmdHF14AMfKeyBrute(const char *Cmd) { */ void printKeyTable(uint8_t sectorscnt, sector_t *e_sector) { + return printKeyTableEx(sectorscnt, e_sector, 0); +} +void printKeyTableEx(uint8_t sectorscnt, sector_t *e_sector, uint8_t start_sector) { char strA[12 + 1] = {0}; char strB[12 + 1] = {0}; PrintAndLogEx(NORMAL, "|---|----------------|---|----------------|---|"); @@ -3316,7 +3346,7 @@ void printKeyTable(uint8_t sectorscnt, sector_t *e_sector) { PrintAndLogEx(NORMAL, "|%03d| %s | %d | %s | %d |" - , i + , start_sector , strA, e_sector[i].foundKey[0] , strB, e_sector[i].foundKey[1] ); @@ -3564,34 +3594,85 @@ static int CmdHF14AMfECFill(const char *Cmd) { } static int CmdHF14AMfEKeyPrn(const char *Cmd) { - int i; - uint8_t numSectors; + + char filename[FILE_PATH_SIZE]; + char *fptr = filename; + uint8_t sectors_cnt = MIFARE_1K_MAXSECTOR; uint8_t data[16]; + uint8_t uid[4]; + uint8_t cmdp = 0; + bool errors = false, createDumpFile = false; - char c = tolower(param_getchar(Cmd, 0)); - if (c == 'h') - return usage_hf14_ekeyprn(); - - if (c != 0) { - numSectors = NumOfSectors(c); - if (numSectors == 0) return usage_hf14_ekeyprn(); - } else { - numSectors = MIFARE_1K_MAXSECTOR; + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + char ctmp = tolower(param_getchar(Cmd, cmdp)); + switch (ctmp) { + case 'd': + createDumpFile = true; + cmdp++; + break; + case 'h': + return usage_hf14_ekeyprn(); + case '0': + case '1': + case '2': + case '4': + sectors_cnt = NumOfSectors(ctmp); + if (sectors_cnt == 0) return usage_hf14_ekeyprn(); + cmdp++; + break; + default: + PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } } + // validations + if (errors) return usage_hf14_ekeyprn(); + + sector_t *e_sector = NULL; + + // create/initialize key storage structure + int32_t res = initSectorTable(&e_sector, sectors_cnt); + if (res != sectors_cnt) + return PM3_EMALLOC; + + // read UID from EMUL + if (mfEmlGetMem(data, 0, 1) != PM3_SUCCESS) { + PrintAndLogEx(WARNING, "error get block %d", 0); + free(e_sector); + return PM3_ESOFT; + } + + memcpy(uid, data, sizeof(uid)); + + // download keys from EMUL + for (int i = 0; i < sectors_cnt; i++) { - PrintAndLogEx(NORMAL, "|---|----------------|----------------|"); - PrintAndLogEx(NORMAL, "|sec|key A |key B |"); - PrintAndLogEx(NORMAL, "|---|----------------|----------------|"); - for (i = 0; i < numSectors; i++) { if (mfEmlGetMem(data, FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1, 1) != PM3_SUCCESS) { PrintAndLogEx(WARNING, "error get block %d", FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1); - break; - } - uint64_t keyA = bytes_to_num(data, 6); - uint64_t keyB = bytes_to_num(data + 10, 6); - PrintAndLogEx(NORMAL, "|%03d| %012" PRIx64 " | %012" PRIx64 " |", i, keyA, keyB); + e_sector[i].foundKey[0] = false; + e_sector[i].foundKey[1] = false; + } else { + e_sector[i].foundKey[0] = true; + e_sector[i].Key[0] = bytes_to_num(data, 6); + e_sector[i].foundKey[1] = true; + e_sector[i].Key[1] = bytes_to_num(data + 10, 6); + } } - PrintAndLogEx(NORMAL, "|---|----------------|----------------|"); + + // print keys + printKeyTable(sectors_cnt, e_sector); + + // dump the keys + if (createDumpFile) { + + fptr += sprintf(fptr, "hf-mf-"); + FillFileNameByUID(fptr + strlen(fptr), uid, "-key", sizeof(uid)); + + createMfcKeyDump(filename, sectors_cnt, e_sector); + } + + free(e_sector); return PM3_SUCCESS; } @@ -3985,6 +4066,31 @@ static int CmdHF14AMfCSave(const char *Cmd) { return PM3_EMALLOC; } + // Select card to get UID/UIDLEN information + clearCommandBuffer(); + SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT, 0, 0, NULL, 0); + PacketResponseNG resp; + if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { + PrintAndLogEx(WARNING, "iso14443a card select failed"); + return PM3_ESOFT; + } + + /* + 0: couldn't read + 1: OK, with ATS + 2: OK, no ATS + 3: proprietary Anticollision + */ + uint64_t select_status = resp.oldarg[0]; + + if (select_status == 0) { + PrintAndLogEx(WARNING, "iso14443a card select failed"); + return select_status; + } + + iso14a_card_select_t card; + memcpy(&card, (iso14a_card_select_t *)resp.data.asBytes, sizeof(iso14a_card_select_t)); + flags = MAGIC_INIT + MAGIC_WUPC; for (i = 0; i < numblocks; i++) { if (i == 1) flags = 0; @@ -3999,7 +4105,7 @@ static int CmdHF14AMfCSave(const char *Cmd) { if (useuid) { fnameptr += sprintf(fnameptr, "hf-mf-"); - FillFileNameByUID(fnameptr, dump, "-dump", 4); + FillFileNameByUID(fnameptr, card.uid, "-dump", card.uidlen); } if (fillEmulator) { diff --git a/client/cmdhfmf.h b/client/cmdhfmf.h index 55997bd87..c650b90f9 100644 --- a/client/cmdhfmf.h +++ b/client/cmdhfmf.h @@ -22,5 +22,6 @@ int CmdHF14AMfDbg(const char *Cmd); // used by cmd hf mfu dbg void showSectorTable(void); void readerAttack(nonces_t data, bool setEmulatorMem, bool verbose); void printKeyTable(uint8_t sectorscnt, sector_t *e_sector); +void printKeyTableEx(uint8_t sectorscnt, sector_t *e_sector, uint8_t start_sector); void printKeyTable_fast(uint8_t sectorscnt, icesector_t *e_sector, uint64_t bar, uint64_t foo); #endif From fc4c975b71787c01c21df022a55549da4ed80782 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 29 Dec 2019 00:01:03 +0100 Subject: [PATCH 1276/1854] textual --- CHANGELOG.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 200da096e..63b209d90 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,11 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] - - Add mfu_magic.lua - script to interact with your magic NTAG tag. (@iceman1001) + - Chg `hf mf hardnested` - now detects "static / fixed" nonce tags and exits (@iceman1001) + - Chg `hf mf csave` - now uses UID in filename (@iceman1001) + - Fix `hf mf chk` - read block B logical error. #489 (@iceman1001) + - Add `hf mf ekeyprn d` - new parameter to save keys to file (@iceman100) + - Add `mfu_magic.lua` - script to interact with your magic NTAG tag. (@iceman1001) - Add `hf_bruteforce.lua` - script bruteforces uid for 14a using hf 14a sim (@keld) - Add `tools\pm3_cs8.pl` - convert .pm3 files to wave format (@samyk) - Add `tools\pm3_amii_bin2eml.pl` - amiibo convering script (@samyk) From 55d93cd81e10f1fed8b580ae12617840be045128 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 29 Dec 2019 00:01:35 +0100 Subject: [PATCH 1277/1854] textual --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 63b209d90..a4a91d13c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Chg `hf mf hardnested` - now detects "static / fixed" nonce tags and exits (@iceman1001) - Chg `hf mf csave` - now uses UID in filename (@iceman1001) - Fix `hf mf chk` - read block B logical error. #489 (@iceman1001) - - Add `hf mf ekeyprn d` - new parameter to save keys to file (@iceman100) + - Add `hf mf ekeyprn d` - new parameter to save keys to file (@iceman1001) - Add `mfu_magic.lua` - script to interact with your magic NTAG tag. (@iceman1001) - Add `hf_bruteforce.lua` - script bruteforces uid for 14a using hf 14a sim (@keld) - Add `tools\pm3_cs8.pl` - convert .pm3 files to wave format (@samyk) From f8876bf7482f8929dfeef783de70262693012c35 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 29 Dec 2019 12:00:39 +0100 Subject: [PATCH 1278/1854] fix: hf mf nested - now print correct blockno/keytype. Unified output to autopwn style --- client/mifare/mifarehost.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/client/mifare/mifarehost.c b/client/mifare/mifarehost.c index 8017af076..6e3db481f 100644 --- a/client/mifare/mifarehost.c +++ b/client/mifare/mifarehost.c @@ -478,10 +478,10 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, free(statelists[1].head.slhead); num_to_bytes(key64, 6, resultKey); - PrintAndLogEx(SUCCESS, "target block:%3u key type: %c -- found valid key [ %012" PRIx64 " ]", - (uint16_t)resp.oldarg[2] & 0xff, - (resp.oldarg[2] >> 8) ? 'B' : 'A', - key64 + PrintAndLogEx(SUCCESS, "target block:%3u key type: %c -- found valid key [ " _YELLOW_("%s") "]", + package->block, + package->keytype ? 'B' : 'A', + sprint_hex(resultKey, 6) ); return -5; } @@ -489,8 +489,8 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, out: PrintAndLogEx(SUCCESS, "target block:%3u key type: %c", - (uint16_t)resp.oldarg[2] & 0xff, - (resp.oldarg[2] >> 8) ? 'B' : 'A' + package->block, + package->keytype ? 'B' : 'A' ); free(statelists[0].head.slhead); @@ -498,6 +498,7 @@ out: return -4; } + // MIFARE int mfReadSector(uint8_t sectorNo, uint8_t keyType, uint8_t *key, uint8_t *data) { From 9c8abd20912b592cd19603528f3fb8aa494f55ea Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 29 Dec 2019 12:03:06 +0100 Subject: [PATCH 1279/1854] chg: refactor printkeytable\n fix: potential crete key null bug\nHelpt text changes --- client/cmdhfmf.c | 170 +++++++++++++++++++++++++---------------------- 1 file changed, 91 insertions(+), 79 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 910763a23..a7df93ed8 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -126,10 +126,10 @@ static int usage_hf14_nested(void) { PrintAndLogEx(NORMAL, " d write keys to binary file `hf-mf--key.bin`"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf mf nested 1 0 A FFFFFFFFFFFF -- nested attack against 1K, block 0, Key A using key FFFFFFFFFFFF"); + PrintAndLogEx(NORMAL, " hf mf nested 1 0 A FFFFFFFFFFFF -- key recovery against 1K, block 0, Key A using key FFFFFFFFFFFF"); PrintAndLogEx(NORMAL, " hf mf nested 1 0 A FFFFFFFFFFFF t -- and transfer keys into emulator memory"); PrintAndLogEx(NORMAL, " hf mf nested 1 0 A FFFFFFFFFFFF d -- or write keys to binary file "); - PrintAndLogEx(NORMAL, " hf mf nested o 0 A FFFFFFFFFFFF 4 A -- nested attack against ONE sector. Use block 0 Key A to find block 4 Key A"); + PrintAndLogEx(NORMAL, " hf mf nested o 0 A FFFFFFFFFFFF 4 A -- one sector key recovery. Use block 0 Key A to find block 4 Key A"); return PM3_SUCCESS; } static int usage_hf14_hardnested(void) { @@ -165,6 +165,25 @@ static int usage_hf14_hardnested(void) { PrintAndLogEx(NORMAL, " hf mf hardnested 0 A A0A1A2A3A4A5 4 A FFFFFFFFFFFF"); return PM3_SUCCESS; } +/* +static int usage_hf14_fixednested(void) { + PrintAndLogEx(NORMAL, "Usage:"); + PrintAndLogEx(NORMAL, " all sectors: hf mf fixed [t,d]"); + PrintAndLogEx(NORMAL, " one sector: hf mf fixed o [t]"); + PrintAndLogEx(NORMAL, "Options:"); + PrintAndLogEx(NORMAL, " h this help"); + PrintAndLogEx(NORMAL, " card memory - 0 - MINI(320 bytes), 1 - 1K, 2 - 2K, 4 - 4K, - 1K"); + PrintAndLogEx(NORMAL, " t transfer keys into emulator memory"); + PrintAndLogEx(NORMAL, " d write keys to binary file `hf-mf--key.bin`"); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Examples:"); + PrintAndLogEx(NORMAL, " hf mf fixed 1 0 A FFFFFFFFFFFF -- key recovery against 1K, block 0, Key A using key FFFFFFFFFFFF"); + PrintAndLogEx(NORMAL, " hf mf fixed 1 0 A FFFFFFFFFFFF t -- and transfer keys into emulator memory"); + PrintAndLogEx(NORMAL, " hf mf fixed 1 0 A FFFFFFFFFFFF d -- or write keys to binary file "); + PrintAndLogEx(NORMAL, " hf mf fixed o 0 A FFFFFFFFFFFF 4 A -- one sector key recovery. Use block 0 Key A to find block 4 Key A"); + return PM3_SUCCESS; +} +*/ static int usage_hf14_autopwn(void) { PrintAndLogEx(NORMAL, "Usage:"); PrintAndLogEx(NORMAL, " hf mf autopwn [k] "); @@ -342,7 +361,7 @@ static int usage_hf14_ecfill(void) { return PM3_SUCCESS; } static int usage_hf14_ekeyprn(void) { - PrintAndLogEx(NORMAL, "It prints the keys loaded in the emulator memory"); + PrintAndLogEx(NORMAL, "Download and print the keys from emulator memory"); PrintAndLogEx(NORMAL, "Usage: hf mf ekeyprn [card memory] [d]"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h this help"); @@ -1379,9 +1398,6 @@ static int CmdHF14AMfNested(const char *Cmd) { // KEY A but not KEY B if (e_sector[i].foundKey[0] && !e_sector[i].foundKey[1]) { -// 0 - n -//GetSectorFromBlockNo(blockNo) - uint8_t sectrail = (FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1); PrintAndLogEx(SUCCESS, "reading block %d", sectrail); @@ -1412,6 +1428,9 @@ static int CmdHF14AMfNested(const char *Cmd) { jumptoend: + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "found keys:"); + //print them printKeyTable(SectorsCnt, e_sector); @@ -1440,38 +1459,11 @@ jumptoend: // Create dump file if (createDumpFile) { char *fptr = GenerateFilename("hf-mf-", "-key.bin"); - if (fptr == NULL) { + if (createMfcKeyDump(fptr, SectorsCnt, e_sector) != PM3_SUCCESS) { + PrintAndLogEx(ERR, "Failed to save keys to file"); free(e_sector); return PM3_ESOFT; } - FILE *fkeys; - if ((fkeys = fopen(fptr, "wb")) == NULL) { - PrintAndLogEx(WARNING, "could not create file " _YELLOW_("%s"), fptr); - free(e_sector); - return PM3_EFILE; - } - - PrintAndLogEx(SUCCESS, "saving keys to binary file " _YELLOW_("%s"), fptr); - uint8_t standard[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; - uint8_t tempkey[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; - for (int i = 0; i < SectorsCnt; i++) { - if (e_sector[i].foundKey[0]) { - num_to_bytes(e_sector[i].Key[0], 6, tempkey); - fwrite(tempkey, 1, 6, fkeys); - } else { - fwrite(&standard, 1, 6, fkeys); - } - } - for (int i = 0; i < SectorsCnt; i++) { - if (e_sector[i].foundKey[1]) { - num_to_bytes(e_sector[i].Key[1], 6, tempkey); - fwrite(tempkey, 1, 6, fkeys); - } else { - fwrite(&standard, 1, 6, fkeys); - } - } - fflush(fkeys); - fclose(fkeys); } free(e_sector); } @@ -2247,46 +2239,17 @@ all_found: // Show the results to the user PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(INFO, "found Keys:"); + PrintAndLogEx(INFO, "found keys:"); - char strA[12 + 1] = {0}; - char strB[12 + 1] = {0}; - PrintAndLogEx(NORMAL, "|---|----------------|---|----------------|---|"); - PrintAndLogEx(NORMAL, "|sec|key A |res|key B |res|"); - PrintAndLogEx(NORMAL, "|---|----------------|---|----------------|---|"); - for (uint8_t i = 0; i < sectors_cnt; ++i) { - - snprintf(strA, sizeof(strA), "------------"); - snprintf(strB, sizeof(strB), "------------"); - - if (e_sector[i].foundKey[0]) - snprintf(strA, sizeof(strA), "%012" PRIx64, e_sector[i].Key[0]); - - if (e_sector[i].foundKey[1]) - snprintf(strB, sizeof(strB), "%012" PRIx64, e_sector[i].Key[1]); - - - PrintAndLogEx(NORMAL, "|%03d| %s | " _YELLOW_("%c")"| %s | " _YELLOW_("%c")"|" - , i - , strA, e_sector[i].foundKey[0] - , strB, e_sector[i].foundKey[1] - ); - } - PrintAndLogEx(NORMAL, "|---|----------------|---|----------------|---|"); - PrintAndLogEx(NORMAL, "( " - _YELLOW_("D") ":Dictionary / " - _YELLOW_("S") ":darkSide / " - _YELLOW_("U") ":User / " - _YELLOW_("R") ":Reused / " - _YELLOW_("N") ":Nested / " - _YELLOW_("H") ":Hardnested / " - _YELLOW_("A") ":keyA " - ")" - ); + printKeyTable(sectors_cnt, e_sector); // Dump the keys PrintAndLogEx(NORMAL, ""); - createMfcKeyDump(GenerateFilename("hf-mf-", "-key"), sectors_cnt, e_sector); + + char *fptr = GenerateFilename("hf-mf-", "-key.bin"); + if (createMfcKeyDump(fptr, sectors_cnt, e_sector) != PM3_SUCCESS) { + PrintAndLogEx(ERR, "Failed to save keys to file"); + } PrintAndLogEx(SUCCESS, "transferring keys to simulator memory (Cmd Error: 04 can occur)"); @@ -2334,13 +2297,20 @@ all_found: // Generate and show statistics t1 = msclock() - t1; - PrintAndLogEx(INFO, "autopwn execution time: " _YELLOW_("%.0f") " seconds", (float)t1 / 1000.0); + PrintAndLogEx(INFO, "autopwn execution time: " _YELLOW_("%.0f") "seconds", (float)t1 / 1000.0); free(dump); free(e_sector); return PM3_SUCCESS; } +/* +static int CmdHF14AMfNestedFixed(const char *Cmd){ + + if (strlen(Cmd) < 3) return usage_hf14_fixednested(); + return PM3_SUCCESS; +} +*/ /* static int randInRange(int min, int max) { return min + (int)(rand() / (double)(RAND_MAX) * (max - min + 1)); @@ -2569,6 +2539,9 @@ out: PrintAndLogEx(WARNING, "No keys found"); } else { + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "found keys:"); + printKeyTable(sectorsCnt, e_sector); if (use_flashmemory && found_keys == (sectorsCnt << 1)) { @@ -2585,10 +2558,13 @@ out: for (i = 0; i < sectorsCnt; ++i) { uint8_t blockno = FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1; mfEmlGetMem(block, blockno, 1); + if (e_sector[i].foundKey[0]) num_to_bytes(e_sector[i].Key[0], 6, block); + if (e_sector[i].foundKey[1]) num_to_bytes(e_sector[i].Key[1], 6, block + 10); + if (i == sectorsCnt - 1) { // Disable fast mode on last packet conn.block_after_ACK = false; @@ -2602,8 +2578,13 @@ out: } } - if (createDumpFile) - createMfcKeyDump(GenerateFilename("hf-mf-", "-key"), sectorsCnt, e_sector); + if (createDumpFile) { + + char *fptr = GenerateFilename("hf-mf-", "-key.bin"); + if (createMfcKeyDump(fptr, sectorsCnt, e_sector) != PM3_SUCCESS) { + PrintAndLogEx(ERR, "Failed to save keys to file"); + } + } } free(keyBlock); @@ -2788,6 +2769,7 @@ static int CmdHF14AMfChk(const char *Cmd) { // clear trace log by first check keys call only bool clearLog = true; + // check keys. for (trgKeyType = (keyType == 2) ? 0 : keyType; trgKeyType < 2; (keyType == 2) ? (++trgKeyType) : (trgKeyType = 2)) { @@ -2868,6 +2850,9 @@ static int CmdHF14AMfChk(const char *Cmd) { } out: + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "found keys:"); + //print keys if ( SectorsCnt == 1) printKeyTableEx(SectorsCnt, e_sector, GetSectorFromBlockNo(blockNo)); @@ -2897,8 +2882,12 @@ out: PrintAndLogEx(SUCCESS, "Found keys have been transferred to the emulator memory"); } - if (createDumpFile) - createMfcKeyDump(GenerateFilename("hf-mf-", "-key"), SectorsCnt, e_sector); + if (createDumpFile) { + char *fptr = GenerateFilename("hf-mf-", "-key.bin"); + if (createMfcKeyDump(fptr, SectorsCnt, e_sector) != PM3_SUCCESS) { + PrintAndLogEx(ERR, "Failed to save keys to file"); + } + } free(keyBlock); free(e_sector); @@ -3331,7 +3320,7 @@ void printKeyTableEx(uint8_t sectorscnt, sector_t *e_sector, uint8_t start_secto char strA[12 + 1] = {0}; char strB[12 + 1] = {0}; PrintAndLogEx(NORMAL, "|---|----------------|---|----------------|---|"); - PrintAndLogEx(NORMAL, "|sec|key A |res|key B |res|"); + PrintAndLogEx(NORMAL, "|sec| key A |res| key B |res|"); PrintAndLogEx(NORMAL, "|---|----------------|---|----------------|---|"); for (uint8_t i = 0; i < sectorscnt; ++i) { @@ -3344,14 +3333,36 @@ void printKeyTableEx(uint8_t sectorscnt, sector_t *e_sector, uint8_t start_secto if (e_sector[i].foundKey[1]) snprintf(strB, sizeof(strB), "%012" PRIx64, e_sector[i].Key[1]); - - PrintAndLogEx(NORMAL, "|%03d| %s | %d | %s | %d |" + if (e_sector[i].foundKey[0] > 1) { + PrintAndLogEx(NORMAL, "|%03d| %s | " _YELLOW_("%c")"| %s | " _YELLOW_("%c")"|" + , i + , strA, e_sector[i].foundKey[0] + , strB, e_sector[i].foundKey[1] + ); + } else { + PrintAndLogEx(NORMAL, "|%03d| %s | " _YELLOW_("%d")"| %s | " _YELLOW_("%d")"|" , start_sector , strA, e_sector[i].foundKey[0] , strB, e_sector[i].foundKey[1] ); + } } PrintAndLogEx(NORMAL, "|---|----------------|---|----------------|---|"); + + if (e_sector[0].foundKey[0] > 1) { + PrintAndLogEx(NORMAL, "( " + _YELLOW_("D") ":Dictionary / " + _YELLOW_("S") ":darkSide / " + _YELLOW_("U") ":User / " + _YELLOW_("R") ":Reused / " + _YELLOW_("N") ":Nested / " + _YELLOW_("H") ":Hardnested / " + _YELLOW_("A") ":keyA " + ")" + ); + } else { + PrintAndLogEx(NORMAL, "(" _YELLOW_("0") ": Failed / " _YELLOW_("1") ": Success)"); + } } @@ -4567,6 +4578,7 @@ static command_t CommandTable[] = { {"darkside", CmdHF14AMfDarkside, IfPm3Iso14443a, "Darkside attack"}, {"nested", CmdHF14AMfNested, IfPm3Iso14443a, "Nested attack"}, {"hardnested", CmdHF14AMfNestedHard, AlwaysAvailable, "Nested attack for hardened MIFARE Classic cards"}, +// {"fixednested", CmdHF14AMfNestedFixed, IfPm3Iso14443a, "Nested attack against static/fixed nonce Mifare Classic cards"}, {"autopwn", CmdHF14AMfAutoPWN, IfPm3Iso14443a, "Automatic key recovery tool for MIFARE Classic"}, // {"keybrute", CmdHF14AMfKeyBrute, IfPm3Iso14443a, "J_Run's 2nd phase of multiple sector nested authentication key recovery"}, {"nack", CmdHf14AMfNack, IfPm3Iso14443a, "Test for MIFARE NACK bug"}, From 6121d816e783b23efa8674ea4bf7c7edccfe0c07 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 30 Dec 2019 12:50:44 +0100 Subject: [PATCH 1280/1854] Chg: faster authentication by lower timeout limit. (@pwpiwi) --- armsrc/mifareutil.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/armsrc/mifareutil.c b/armsrc/mifareutil.c index 3ccf25737..2e6ba8ade 100644 --- a/armsrc/mifareutil.c +++ b/armsrc/mifareutil.c @@ -127,7 +127,7 @@ int mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, int mifare_classic_auth(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested) { return mifare_classic_authex(pcs, uid, blockNo, keyType, ui64Key, isNested, NULL, NULL); } - + int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested, uint32_t *ntptr, uint32_t *timing) { int len; uint32_t pos, nt, ntpp; // Supplied tag nonce @@ -190,8 +190,17 @@ int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockN // Transmit reader nonce and reader answer ReaderTransmitPar(mf_nr_ar, sizeof(mf_nr_ar), par, NULL); + // save standard timeout + uint32_t save_timeout = iso14a_get_timeout(); + + // set timeout for authentication response + iso14a_set_timeout(106); + // Receive 4 byte tag answer len = ReaderReceive(receivedAnswer, receivedAnswerPar); + + iso14a_set_timeout(save_timeout); + if (!len) { if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("Authentication failed. Card timeout."); return 2; From 0c8ead0bd66d87fed5d26ee64e1a23dc63bf7ee6 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 30 Dec 2019 13:11:44 +0100 Subject: [PATCH 1281/1854] fix: forgot some changes --- armsrc/iso14443a.c | 3 --- armsrc/iso14443a.h | 3 +++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 38eb2ecb6..bd5f9ba37 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -1669,9 +1669,6 @@ static void TransmitFor14443a(const uint8_t *cmd, uint16_t len, uint32_t *timing LastTimeProxToAirStart = ThisTransferTime; } - // clear TXRDY - AT91C_BASE_SSC->SSC_THR = SEC_Y; - uint16_t c = 0; while (c < len) { if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { diff --git a/armsrc/iso14443a.h b/armsrc/iso14443a.h index 1bea3a1b9..33e5b2995 100644 --- a/armsrc/iso14443a.h +++ b/armsrc/iso14443a.h @@ -96,6 +96,9 @@ typedef struct { # define CheckCrc14A(data, len) check_crc(CRC_14443_A, (data), (len)) #endif +void iso14a_set_timeout(uint32_t timeout); +uint32_t iso14a_get_timeout(void); + void GetParity(const uint8_t *pbtCmd, uint16_t len, uint8_t *par); tDemod14a *GetDemod14a(void); From 3a18fe6ea1fbf350bdc0ecbace271eb5919bb9be Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 30 Dec 2019 13:25:15 +0100 Subject: [PATCH 1282/1854] fix: some more adaptations --- armsrc/mifarecmd.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 47c353855..572fb42d9 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -919,7 +919,7 @@ void MifareNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8 for (rtr = 0; rtr < 17; rtr++) { // Test if the action was cancelled - if (BUTTON_PRESS() || usb_poll_validate_length()) { + if (BUTTON_PRESS() || data_available()) { isOK = -2; break; } @@ -1000,7 +1000,7 @@ void MifareNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8 while (target_nt[i] == 0) { // continue until we have an unambiguous nonce // Test if the action was cancelled - if (BUTTON_PRESS() || usb_poll_validate_length()) { + if (BUTTON_PRESS() || data_available()) { isOK = -2; break; } @@ -1274,6 +1274,8 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da static uint8_t found[80]; static uint8_t *uid; + int oldbg = DBGLEVEL; + #ifdef WITH_FLASH if (use_flashmem) { BigBuf_free(); @@ -1341,6 +1343,9 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da CHK_TIMEOUT(); } + // clear debug level. We are expecting lots of authentication failures... + DBGLEVEL = DBG_NONE; + // set check struct. chk_data.uid = uid; chk_data.cuid = cuid; @@ -1365,7 +1370,7 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da for (uint16_t i = s_point; i < keyCount; ++i) { // Allow button press / usb cmd to interrupt device - if (BUTTON_PRESS() && !data_available()) { + if (BUTTON_PRESS() && data_available()) { goto OUT; } @@ -1457,7 +1462,7 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da for (uint16_t i = 0; i < keyCount; i++) { // Allow button press / usb cmd to interrupt device - if (BUTTON_PRESS() && !data_available()) break; + if (BUTTON_PRESS() && data_available()) break; // found all keys? if (foundkeys == allkeys) @@ -1566,16 +1571,16 @@ OUT: emlSetMem_xt(block, blockno, 1, sizeof(block)); } - int oldbg = DBGLEVEL; - DBGLEVEL = DBG_NONE; + MifareECardLoad(sectorcnt, 0); MifareECardLoad(sectorcnt, 1); - DBGLEVEL = oldbg; } } else { // partial/none keys found reply_mix(CMD_ACK, foundkeys, 0, 0, 0, 0); } + + DBGLEVEL = oldbg; } void MifareChkKeys(uint8_t *datain) { @@ -1614,7 +1619,10 @@ void MifareChkKeys(uint8_t *datain) { if (clearTrace) clear_trace(); - set_tracing(true); + int oldbg = DBGLEVEL; + DBGLEVEL = DBG_NONE; + + set_tracing(false); for (i = 0; i < keyCount; i++) { @@ -1655,6 +1663,7 @@ void MifareChkKeys(uint8_t *datain) { if (res) continue; + memcpy(keyresult.key, datain + i * 6, 6); keyresult.found = true; break; @@ -1668,6 +1677,8 @@ void MifareChkKeys(uint8_t *datain) { set_tracing(false); crypto1_deinit(pcs); + + DBGLEVEL = oldbg; } //----------------------------------------------------------------------------- From fb0eb3571022175f88cfd6561c0a93cb7f02d43c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 30 Dec 2019 16:27:51 +0100 Subject: [PATCH 1283/1854] style --- armsrc/mifarecmd.c | 4 +- armsrc/mifareutil.c | 4 +- client/cmdhfmf.c | 156 ++++++++++++++++++------------------- client/mifare/mifarehost.c | 12 +-- client/mifare/mifarehost.h | 2 +- 5 files changed, 89 insertions(+), 89 deletions(-) diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 572fb42d9..643454672 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -1275,7 +1275,7 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da static uint8_t *uid; int oldbg = DBGLEVEL; - + #ifdef WITH_FLASH if (use_flashmem) { BigBuf_free(); @@ -1345,7 +1345,7 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da // clear debug level. We are expecting lots of authentication failures... DBGLEVEL = DBG_NONE; - + // set check struct. chk_data.uid = uid; chk_data.cuid = cuid; diff --git a/armsrc/mifareutil.c b/armsrc/mifareutil.c index 2e6ba8ade..97ac6ee90 100644 --- a/armsrc/mifareutil.c +++ b/armsrc/mifareutil.c @@ -127,7 +127,7 @@ int mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, int mifare_classic_auth(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested) { return mifare_classic_authex(pcs, uid, blockNo, keyType, ui64Key, isNested, NULL, NULL); } - + int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested, uint32_t *ntptr, uint32_t *timing) { int len; uint32_t pos, nt, ntpp; // Supplied tag nonce @@ -198,7 +198,7 @@ int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockN // Receive 4 byte tag answer len = ReaderReceive(receivedAnswer, receivedAnswerPar); - + iso14a_set_timeout(save_timeout); if (!len) { diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index a7df93ed8..486457fed 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -370,7 +370,7 @@ static int usage_hf14_ekeyprn(void) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf mf ekeyprn 1"); - PrintAndLogEx(NORMAL, " hf mf ekeyprn d"); + PrintAndLogEx(NORMAL, " hf mf ekeyprn d"); return PM3_SUCCESS; } @@ -1430,7 +1430,7 @@ jumptoend: PrintAndLogEx(NORMAL, ""); PrintAndLogEx(INFO, "found keys:"); - + //print them printKeyTable(SectorsCnt, e_sector); @@ -1615,12 +1615,12 @@ static int CmdHF14AMfNestedHard(const char *Cmd) { if (!know_target_key && nonce_file_read == false) { - // check if tag doesn't have static/fixed nonce - if (detect_classic_static_nonce() != 0) { - PrintAndLogEx(WARNING, "Static/fixed nonce detected. Quitting..."); - return PM3_EOPABORTED; - } - + // check if tag doesn't have static/fixed nonce + if (detect_classic_static_nonce() != 0) { + PrintAndLogEx(WARNING, "Static/fixed nonce detected. Quitting..."); + return PM3_EOPABORTED; + } + uint64_t key64 = 0; // check if we can authenticate to sector if (mfCheckKeys(blockNo, keyType, true, 1, key, &key64) != PM3_SUCCESS) { @@ -2245,7 +2245,7 @@ all_found: // Dump the keys PrintAndLogEx(NORMAL, ""); - + char *fptr = GenerateFilename("hf-mf-", "-key.bin"); if (createMfcKeyDump(fptr, sectors_cnt, e_sector) != PM3_SUCCESS) { PrintAndLogEx(ERR, "Failed to save keys to file"); @@ -2305,7 +2305,7 @@ all_found: } /* static int CmdHF14AMfNestedFixed(const char *Cmd){ - + if (strlen(Cmd) < 3) return usage_hf14_fixednested(); return PM3_SUCCESS; @@ -2541,7 +2541,7 @@ out: PrintAndLogEx(NORMAL, ""); PrintAndLogEx(INFO, "found keys:"); - + printKeyTable(sectorsCnt, e_sector); if (use_flashmemory && found_keys == (sectorsCnt << 1)) { @@ -2558,13 +2558,13 @@ out: for (i = 0; i < sectorsCnt; ++i) { uint8_t blockno = FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1; mfEmlGetMem(block, blockno, 1); - + if (e_sector[i].foundKey[0]) num_to_bytes(e_sector[i].Key[0], 6, block); - + if (e_sector[i].foundKey[1]) num_to_bytes(e_sector[i].Key[1], 6, block + 10); - + if (i == sectorsCnt - 1) { // Disable fast mode on last packet conn.block_after_ACK = false; @@ -2579,12 +2579,12 @@ out: } if (createDumpFile) { - - char *fptr = GenerateFilename("hf-mf-", "-key.bin"); - if (createMfcKeyDump(fptr, sectorsCnt, e_sector) != PM3_SUCCESS) { + + char *fptr = GenerateFilename("hf-mf-", "-key.bin"); + if (createMfcKeyDump(fptr, sectorsCnt, e_sector) != PM3_SUCCESS) { PrintAndLogEx(ERR, "Failed to save keys to file"); } - } + } } free(keyBlock); @@ -2813,7 +2813,7 @@ static int CmdHF14AMfChk(const char *Cmd) { // loop sectors but block is used as to keep track of from which blocks to test int b = blockNo; for (i = 0; i < SectorsCnt; i++) { - + // KEY A but not KEY B if (e_sector[i].foundKey[0] && !e_sector[i].foundKey[1]) { @@ -2852,12 +2852,12 @@ static int CmdHF14AMfChk(const char *Cmd) { out: PrintAndLogEx(NORMAL, ""); PrintAndLogEx(INFO, "found keys:"); - + //print keys - if ( SectorsCnt == 1) - printKeyTableEx(SectorsCnt, e_sector, GetSectorFromBlockNo(blockNo)); + if (SectorsCnt == 1) + printKeyTableEx(SectorsCnt, e_sector, GetSectorFromBlockNo(blockNo)); else - printKeyTable(SectorsCnt, e_sector); + printKeyTable(SectorsCnt, e_sector); if (transferToEml) { // fast push mode @@ -2866,14 +2866,14 @@ out: for (i = 0; i < SectorsCnt; ++i) { uint8_t blockno = FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1; mfEmlGetMem(block, blockno, 1); - - if (e_sector[i].foundKey[0]) + + if (e_sector[i].foundKey[0]) num_to_bytes(e_sector[i].Key[0], 6, block); - + if (e_sector[i].foundKey[1]) num_to_bytes(e_sector[i].Key[1], 6, block + 10); - - if (i == SectorsCnt - 1) { + + if (i == SectorsCnt - 1) { // Disable fast mode on last packet conn.block_after_ACK = false; } @@ -2887,7 +2887,7 @@ out: if (createMfcKeyDump(fptr, SectorsCnt, e_sector) != PM3_SUCCESS) { PrintAndLogEx(ERR, "Failed to save keys to file"); } - } + } free(keyBlock); free(e_sector); @@ -3314,7 +3314,7 @@ static int CmdHF14AMfKeyBrute(const char *Cmd) { */ void printKeyTable(uint8_t sectorscnt, sector_t *e_sector) { - return printKeyTableEx(sectorscnt, e_sector, 0); + return printKeyTableEx(sectorscnt, e_sector, 0); } void printKeyTableEx(uint8_t sectorscnt, sector_t *e_sector, uint8_t start_sector) { char strA[12 + 1] = {0}; @@ -3335,31 +3335,31 @@ void printKeyTableEx(uint8_t sectorscnt, sector_t *e_sector, uint8_t start_secto if (e_sector[i].foundKey[0] > 1) { PrintAndLogEx(NORMAL, "|%03d| %s | " _YELLOW_("%c")"| %s | " _YELLOW_("%c")"|" - , i - , strA, e_sector[i].foundKey[0] - , strB, e_sector[i].foundKey[1] - ); + , i + , strA, e_sector[i].foundKey[0] + , strB, e_sector[i].foundKey[1] + ); } else { PrintAndLogEx(NORMAL, "|%03d| %s | " _YELLOW_("%d")"| %s | " _YELLOW_("%d")"|" - , start_sector - , strA, e_sector[i].foundKey[0] - , strB, e_sector[i].foundKey[1] - ); + , start_sector + , strA, e_sector[i].foundKey[0] + , strB, e_sector[i].foundKey[1] + ); } } PrintAndLogEx(NORMAL, "|---|----------------|---|----------------|---|"); if (e_sector[0].foundKey[0] > 1) { PrintAndLogEx(NORMAL, "( " - _YELLOW_("D") ":Dictionary / " - _YELLOW_("S") ":darkSide / " - _YELLOW_("U") ":User / " - _YELLOW_("R") ":Reused / " - _YELLOW_("N") ":Nested / " - _YELLOW_("H") ":Hardnested / " - _YELLOW_("A") ":keyA " - ")" - ); + _YELLOW_("D") ":Dictionary / " + _YELLOW_("S") ":darkSide / " + _YELLOW_("U") ":User / " + _YELLOW_("R") ":Reused / " + _YELLOW_("N") ":Nested / " + _YELLOW_("H") ":Hardnested / " + _YELLOW_("A") ":keyA " + ")" + ); } else { PrintAndLogEx(NORMAL, "(" _YELLOW_("0") ": Failed / " _YELLOW_("1") ": Success)"); } @@ -3615,7 +3615,7 @@ static int CmdHF14AMfEKeyPrn(const char *Cmd) { bool errors = false, createDumpFile = false; while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { - char ctmp = tolower(param_getchar(Cmd, cmdp)); + char ctmp = tolower(param_getchar(Cmd, cmdp)); switch (ctmp) { case 'd': createDumpFile = true; @@ -3623,18 +3623,18 @@ static int CmdHF14AMfEKeyPrn(const char *Cmd) { break; case 'h': return usage_hf14_ekeyprn(); - case '0': - case '1': - case '2': - case '4': - sectors_cnt = NumOfSectors(ctmp); - if (sectors_cnt == 0) return usage_hf14_ekeyprn(); - cmdp++; - break; + case '0': + case '1': + case '2': + case '4': + sectors_cnt = NumOfSectors(ctmp); + if (sectors_cnt == 0) return usage_hf14_ekeyprn(); + cmdp++; + break; default: - PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); - errors = true; - break; + PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; } } // validations @@ -3646,15 +3646,15 @@ static int CmdHF14AMfEKeyPrn(const char *Cmd) { int32_t res = initSectorTable(&e_sector, sectors_cnt); if (res != sectors_cnt) return PM3_EMALLOC; - - // read UID from EMUL + + // read UID from EMUL if (mfEmlGetMem(data, 0, 1) != PM3_SUCCESS) { - PrintAndLogEx(WARNING, "error get block %d", 0); - free(e_sector); - return PM3_ESOFT; + PrintAndLogEx(WARNING, "error get block %d", 0); + free(e_sector); + return PM3_ESOFT; } - - memcpy(uid, data, sizeof(uid)); + + memcpy(uid, data, sizeof(uid)); // download keys from EMUL for (int i = 0; i < sectors_cnt; i++) { @@ -3662,26 +3662,26 @@ static int CmdHF14AMfEKeyPrn(const char *Cmd) { if (mfEmlGetMem(data, FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1, 1) != PM3_SUCCESS) { PrintAndLogEx(WARNING, "error get block %d", FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1); e_sector[i].foundKey[0] = false; - e_sector[i].foundKey[1] = false; + e_sector[i].foundKey[1] = false; } else { - e_sector[i].foundKey[0] = true; - e_sector[i].Key[0] = bytes_to_num(data, 6); - e_sector[i].foundKey[1] = true; - e_sector[i].Key[1] = bytes_to_num(data + 10, 6); - } + e_sector[i].foundKey[0] = true; + e_sector[i].Key[0] = bytes_to_num(data, 6); + e_sector[i].foundKey[1] = true; + e_sector[i].Key[1] = bytes_to_num(data + 10, 6); + } } // print keys printKeyTable(sectors_cnt, e_sector); - // dump the keys + // dump the keys if (createDumpFile) { - - fptr += sprintf(fptr, "hf-mf-"); - FillFileNameByUID(fptr + strlen(fptr), uid, "-key", sizeof(uid)); - createMfcKeyDump(filename, sectors_cnt, e_sector); - } + fptr += sprintf(fptr, "hf-mf-"); + FillFileNameByUID(fptr + strlen(fptr), uid, "-key", sizeof(uid)); + + createMfcKeyDump(filename, sectors_cnt, e_sector); + } free(e_sector); return PM3_SUCCESS; diff --git a/client/mifare/mifarehost.c b/client/mifare/mifarehost.c index 6e3db481f..4b29920ee 100644 --- a/client/mifare/mifarehost.c +++ b/client/mifare/mifarehost.c @@ -324,7 +324,7 @@ __attribute__((force_align_arg_pointer)) *nested_worker_thread(void *arg) { struct Crypto1State *p1; StateList_t *statelist = arg; - statelist->head.slhead = lfsr_recovery32(statelist->ks1, statelist->nt ^ statelist->uid); + statelist->head.slhead = lfsr_recovery32(statelist->ks1, statelist->nt_enc ^ statelist->uid); for (p1 = statelist->head.slhead; * (uint64_t *)p1 != 0; p1++) {}; @@ -391,10 +391,10 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, statelists[i].uid = uid; } - memcpy(&statelists[0].nt, package->nt_a, sizeof(package->nt_a)); + memcpy(&statelists[0].nt_enc, package->nt_a, sizeof(package->nt_a)); memcpy(&statelists[0].ks1, package->ks_a, sizeof(package->ks_a)); - memcpy(&statelists[1].nt, package->nt_b, sizeof(package->nt_b)); + memcpy(&statelists[1].nt_enc, package->nt_b, sizeof(package->nt_b)); memcpy(&statelists[1].ks1, package->ks_b, sizeof(package->ks_b)); @@ -422,14 +422,14 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, savestate = *p1; while (Compare16Bits(p1, &savestate) == 0 && p1 <= statelists[0].tail.sltail) { *p3 = *p1; - lfsr_rollback_word(p3, statelists[0].nt ^ statelists[0].uid, 0); + lfsr_rollback_word(p3, statelists[0].nt_enc ^ statelists[0].uid, 0); p3++; p1++; } savestate = *p2; while (Compare16Bits(p2, &savestate) == 0 && p2 <= statelists[1].tail.sltail) { *p4 = *p2; - lfsr_rollback_word(p4, statelists[1].nt ^ statelists[1].uid, 0); + lfsr_rollback_word(p4, statelists[1].nt_enc ^ statelists[1].uid, 0); p4++; p2++; } @@ -481,7 +481,7 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, PrintAndLogEx(SUCCESS, "target block:%3u key type: %c -- found valid key [ " _YELLOW_("%s") "]", package->block, package->keytype ? 'B' : 'A', - sprint_hex(resultKey, 6) + sprint_hex(resultKey, 6) ); return -5; } diff --git a/client/mifare/mifarehost.h b/client/mifare/mifarehost.h index d81595942..a17e4b099 100644 --- a/client/mifare/mifarehost.h +++ b/client/mifare/mifarehost.h @@ -39,7 +39,7 @@ typedef struct { uint32_t uid; uint32_t blockNo; uint32_t keyType; - uint32_t nt; + uint32_t nt_enc; uint32_t ks1; } StateList_t; From 88237e60c138aa7eb54c8601ff8f6b556f3009aa Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 30 Dec 2019 16:41:13 +0100 Subject: [PATCH 1284/1854] cppcheck --- client/wiegand_formats.h | 2 +- common/crapto1/crapto1.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/client/wiegand_formats.h b/client/wiegand_formats.h index b75f5e491..2b9b3df05 100644 --- a/client/wiegand_formats.h +++ b/client/wiegand_formats.h @@ -42,7 +42,7 @@ typedef struct { void HIDListFormats(); int HIDFindCardFormat(const char *format); cardformat_t HIDGetCardFormat(int idx); -bool HIDPack(int FormatIndex, wiegand_card_t *card, wiegand_message_t *packed); +bool HIDPack(int format_idx, wiegand_card_t *card, wiegand_message_t *packed); bool HIDTryUnpack(wiegand_message_t *packed, bool ignore_parity); #endif diff --git a/common/crapto1/crapto1.h b/common/crapto1/crapto1.h index 7fa16539e..b6be544a5 100644 --- a/common/crapto1/crapto1.h +++ b/common/crapto1/crapto1.h @@ -25,7 +25,7 @@ #include struct Crypto1State {uint32_t odd, even;}; -void crypto1_init(struct Crypto1State *s, uint64_t key); +void crypto1_init(struct Crypto1State *state, uint64_t key); void crypto1_deinit(struct Crypto1State *); #if !defined(__arm__) || defined(__linux__) || defined(_WIN32) || defined(__APPLE__) // bare metal ARM Proxmark lacks malloc()/free() struct Crypto1State *crypto1_create(uint64_t key); From a3ce88eaecef36bb1cfd961c1e35fa143a12082f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 30 Dec 2019 16:46:13 +0100 Subject: [PATCH 1285/1854] fix: cppcheck, bool vs & --- client/loclass/cipherutils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/loclass/cipherutils.c b/client/loclass/cipherutils.c index c2a802c7a..d291c4886 100644 --- a/client/loclass/cipherutils.c +++ b/client/loclass/cipherutils.c @@ -74,7 +74,7 @@ bool tailBit(BitstreamIn *stream) { void pushBit(BitstreamOut *stream, bool bit) { int bytepos = stream->position >> 3; // divide by 8 int bitpos = stream->position & 7; - *(stream->buffer + bytepos) |= (bit & 1) << (7 - bitpos); + *(stream->buffer + bytepos) |= (bit) << (7 - bitpos); stream->position++; stream->numbits++; } From c857cf49f38dff4b25bfde8bdc9dc29563e88091 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 30 Dec 2019 16:50:53 +0100 Subject: [PATCH 1286/1854] fix: cppcheck negative compare w u32 --- client/scripting.c | 87 +++++++++++++++++++++++----------------------- 1 file changed, 43 insertions(+), 44 deletions(-) diff --git a/client/scripting.c b/client/scripting.c index 45451b241..e531acd97 100644 --- a/client/scripting.c +++ b/client/scripting.c @@ -303,7 +303,6 @@ static int l_GetFromFlashMem(lua_State *L) { } } - /** * @brief The following params expected: * uint8_t *destfilename @@ -312,51 +311,51 @@ static int l_GetFromFlashMem(lua_State *L) { */ static int l_GetFromFlashMemSpiffs(lua_State *L) { - if (IfPm3Flash()) { - uint32_t start_index = 0, len = 0x40000; //FLASH_MEM_MAX_SIZE - char destfilename[32] = {0}; - size_t size; - - int n = lua_gettop(L); - if (n == 0) - return returnToLuaWithError(L, "You need to supply the destination filename"); - - if (n >= 1) { - const char *p_filename = luaL_checklstring(L, 1, &size); - if (size != 0) - memcpy(destfilename, p_filename, 31); - } - - if (destfilename[0] == '\0') - return returnToLuaWithError(L, "Filename missing or invalid"); - - // get size from spiffs itself ! - SendCommandMIX(CMD_SPIFFS_STAT, 0, 0, 0, (uint8_t *)destfilename, 32); - PacketResponseNG resp; - if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) - return returnToLuaWithError(L, "No response from the device"); - - len = resp.oldarg[0]; - - if (len <= 0) - return returnToLuaWithError(L, "Filename invalid or empty"); - - uint8_t *data = calloc(len, sizeof(uint8_t)); - if (!data) - return returnToLuaWithError(L, "Allocating memory failed"); - - if (!GetFromDevice(SPIFFS, data, len, start_index, (uint8_t *)destfilename, 32, NULL, -1, true)) { - free(data); - return returnToLuaWithError(L, "ERROR; downloading from spiffs(flashmemory)"); - } - - lua_pushlstring(L, (const char *)data, len); - lua_pushunsigned(L, len); - free(data); - return 2; - } else { + if (IfPm3Flash() == false) { return returnToLuaWithError(L, "No FLASH MEM support"); } + + uint32_t start_index = 0, len = 0x40000; //FLASH_MEM_MAX_SIZE + char destfilename[32] = {0}; + size_t size; + + int n = lua_gettop(L); + if (n == 0) + return returnToLuaWithError(L, "You need to supply the destination filename"); + + if (n >= 1) { + const char *p_filename = luaL_checklstring(L, 1, &size); + if (size != 0) + memcpy(destfilename, p_filename, 31); + } + + if (destfilename[0] == '\0') + return returnToLuaWithError(L, "Filename missing or invalid"); + + // get size from spiffs itself ! + SendCommandMIX(CMD_SPIFFS_STAT, 0, 0, 0, (uint8_t *)destfilename, 32); + PacketResponseNG resp; + if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) + return returnToLuaWithError(L, "No response from the device"); + + len = resp.oldarg[0]; + + if (len == 0) + return returnToLuaWithError(L, "Filename invalid or empty"); + + uint8_t *data = calloc(len, sizeof(uint8_t)); + if (!data) + return returnToLuaWithError(L, "Allocating memory failed"); + + if (!GetFromDevice(SPIFFS, data, len, start_index, (uint8_t *)destfilename, 32, NULL, -1, true)) { + free(data); + return returnToLuaWithError(L, "ERROR; downloading from spiffs(flashmemory)"); + } + + lua_pushlstring(L, (const char *)data, len); + lua_pushunsigned(L, len); + free(data); + return 2; } /** From f428b016c12e4cec979a228beeea29175bd6f5c6 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 30 Dec 2019 21:11:18 +0100 Subject: [PATCH 1287/1854] cppcheck --- armsrc/frozen.c | 18 +++++++++--------- armsrc/frozen.h | 5 ++--- client/cmdhfmfp.c | 6 +++--- client/mifare/mifare4.c | 14 +++++++------- client/mifare/mifare4.h | 10 +++++----- 5 files changed, 26 insertions(+), 27 deletions(-) diff --git a/armsrc/frozen.c b/armsrc/frozen.c index a43300319..41f2179cd 100644 --- a/armsrc/frozen.c +++ b/armsrc/frozen.c @@ -437,27 +437,27 @@ static int json_doit(struct frozen *f) { } int json_escape(struct json_out *out, const char *p, size_t len) WEAK; -int json_escape(struct json_out *out, const char *p, size_t len) { +int json_escape(struct json_out *out, const char *str, size_t str_len) { size_t i, cl, n = 0; const char *hex_digits = "0123456789abcdef"; const char *specials = "btnvfr"; - for (i = 0; i < len; i++) { - unsigned char ch = ((unsigned char *) p)[i]; + for (i = 0; i < str_len; i++) { + unsigned char ch = ((unsigned char *) str)[i]; if (ch == '"' || ch == '\\') { n += out->printer(out, "\\", 1); - n += out->printer(out, p + i, 1); + n += out->printer(out, str + i, 1); } else if (ch >= '\b' && ch <= '\r') { n += out->printer(out, "\\", 1); n += out->printer(out, &specials[ch - '\b'], 1); } else if (c_isprint(ch)) { - n += out->printer(out, p + i, 1); + n += out->printer(out, str + i, 1); } else if ((cl = json_get_utf8_char_len(ch)) == 1) { n += out->printer(out, "\\u00", 4); n += out->printer(out, &hex_digits[(ch >> 4) % 0xf], 1); n += out->printer(out, &hex_digits[ch % 0xf], 1); } else { - n += out->printer(out, p + i, cl); + n += out->printer(out, str + i, cl); i += cl - 1; } } @@ -1032,8 +1032,8 @@ static void json_scanf_cb(void *callback_data, const char *name, } } -int json_vscanf(const char *s, int len, const char *fmt, va_list ap) WEAK; -int json_vscanf(const char *s, int len, const char *fmt, va_list ap) { +int json_vscanf(const char *str, int len, const char *fmt, va_list ap) WEAK; +int json_vscanf(const char *str, int len, const char *fmt, va_list ap) { char path[JSON_MAX_PATH_LEN] = "", fmtbuf[20]; int i = 0; char *p = NULL; @@ -1070,7 +1070,7 @@ int json_vscanf(const char *s, int len, const char *fmt, va_list ap) { break; } } - json_walk(s, len, json_scanf_cb, &info); + json_walk(str, len, json_scanf_cb, &info); } else if (json_isalpha(fmt[i]) || json_get_utf8_char_len(fmt[i]) > 1) { char *pe; const char *delims = ": \r\n\t"; diff --git a/armsrc/frozen.h b/armsrc/frozen.h index a81522a64..fc6fd3b3b 100644 --- a/armsrc/frozen.h +++ b/armsrc/frozen.h @@ -144,7 +144,7 @@ typedef int (*json_printf_callback_t)(struct json_out *, va_list *ap); * overflown bytes are not printed. */ int json_printf(struct json_out *, const char *fmt, ...); -int json_vprintf(struct json_out *, const char *fmt, va_list ap); +int json_vprintf(struct json_out *, const char *fmt, va_list xap); /* * Same as json_printf, but prints to a file. @@ -212,8 +212,7 @@ typedef void (*json_scanner_t)(const char *str, int len, void *user_data); * Fills `token` with the matched JSON token. * Return -1 if no array element found, otherwise non-negative token length. */ -int json_scanf_array_elem(const char *s, int len, const char *path, int index, - struct json_token *token); +int json_scanf_array_elem(const char *s, int len, const char *path, int idx, struct json_token *token); /* * Unescape JSON-encoded string src,slen into dst, dlen. diff --git a/client/cmdhfmfp.c b/client/cmdhfmfp.c index ec7c4cc72..c6d24135c 100644 --- a/client/cmdhfmfp.c +++ b/client/cmdhfmfp.c @@ -393,7 +393,7 @@ static int CmdHFMFPRdbl(const char *cmd) { if (verbose) PrintAndLogEx(INFO, "--block:%d sector[%d]:%02x key:%04x", blockn, mfNumBlocksPerSector(sectorNum), sectorNum, uKeyNum); - mf4Session mf4session; + mf4Session_t mf4session; int res = MifareAuth4(&mf4session, keyn, key, true, true, true, verbose, false); if (res) { PrintAndLogEx(ERR, "Authentication error: %d", res); @@ -492,7 +492,7 @@ static int CmdHFMFPRdsc(const char *cmd) { if (verbose) PrintAndLogEx(INFO, "--sector[%d]:%02x key:%04x", mfNumBlocksPerSector(sectorNum), sectorNum, uKeyNum); - mf4Session mf4session; + mf4Session_t mf4session; int res = MifareAuth4(&mf4session, keyn, key, true, true, true, verbose, false); if (res) { PrintAndLogEx(ERR, "Authentication error: %d", res); @@ -596,7 +596,7 @@ static int CmdHFMFPWrbl(const char *cmd) { if (verbose) PrintAndLogEx(INFO, "--block:%d sector[%d]:%02x key:%04x", blockNum & 0xff, mfNumBlocksPerSector(sectorNum), sectorNum, uKeyNum); - mf4Session mf4session; + mf4Session_t mf4session; int res = MifareAuth4(&mf4session, keyn, key, true, true, true, verbose, false); if (res) { PrintAndLogEx(ERR, "Authentication error: %d", res); diff --git a/client/mifare/mifare4.c b/client/mifare/mifare4.c index 8bf0788b4..84f509078 100644 --- a/client/mifare/mifare4.c +++ b/client/mifare/mifare4.c @@ -95,7 +95,7 @@ const char *mfGetAccessConditionsDesc(uint8_t blockn, uint8_t *data) { return StaticNone; }; /* -static int CalculateEncIVCommand(mf4Session *session, uint8_t *iv, bool verbose) { +static int CalculateEncIVCommand(mf4Session_t *session, uint8_t *iv, bool verbose) { memcpy(&iv[0], session->TI, 4); memcpy(&iv[4], &session->R_Ctr, 2); memcpy(&iv[6], &session->W_Ctr, 2); @@ -120,8 +120,8 @@ static int CalculateEncIVResponse(mf4Session *session, uint8_t *iv, bool verbose } */ -int CalculateMAC(mf4Session *session, MACType_t mtype, uint8_t blockNum, uint8_t blockCount, uint8_t *data, int datalen, uint8_t *mac, bool verbose) { - if (!session || !session->Authenticated || !mac || !data || !datalen || datalen < 1) +int CalculateMAC(mf4Session_t *session, MACType_t mtype, uint8_t blockNum, uint8_t blockCount, uint8_t *data, int datalen, uint8_t *mac, bool verbose) { + if (!session || !session->Authenticated || !mac || !data || !datalen) return 1; memset(mac, 0x00, 8); @@ -168,7 +168,7 @@ int CalculateMAC(mf4Session *session, MACType_t mtype, uint8_t blockNum, uint8_t return aes_cmac8(NULL, session->Kmac, macdata, mac, macdatalen); } -int MifareAuth4(mf4Session *session, uint8_t *keyn, uint8_t *key, bool activateField, bool leaveSignalON, bool dropFieldIfError, bool verbose, bool silentMode) { +int MifareAuth4(mf4Session_t *session, uint8_t *keyn, uint8_t *key, bool activateField, bool leaveSignalON, bool dropFieldIfError, bool verbose, bool silentMode) { uint8_t data[257] = {0}; int datalen = 0; @@ -335,7 +335,7 @@ int MFPCommitPerso(bool activateField, bool leaveSignalON, uint8_t *dataout, int return intExchangeRAW14aPlus(rcmd, sizeof(rcmd), activateField, leaveSignalON, dataout, maxdataoutlen, dataoutlen); } -int MFPReadBlock(mf4Session *session, bool plain, uint8_t blockNum, uint8_t blockCount, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, uint8_t *mac) { +int MFPReadBlock(mf4Session_t *session, bool plain, uint8_t blockNum, uint8_t blockCount, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, uint8_t *mac) { uint8_t rcmd[4 + 8] = {(plain ? (0x37) : (0x33)), blockNum, 0x00, blockCount}; if (!plain && session) CalculateMAC(session, mtypReadCmd, blockNum, blockCount, rcmd, 4, &rcmd[4], VerboseMode); @@ -353,7 +353,7 @@ int MFPReadBlock(mf4Session *session, bool plain, uint8_t blockNum, uint8_t bloc return 0; } -int MFPWriteBlock(mf4Session *session, uint8_t blockNum, uint8_t *data, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, uint8_t *mac) { +int MFPWriteBlock(mf4Session_t *session, uint8_t blockNum, uint8_t *data, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, uint8_t *mac) { uint8_t rcmd[1 + 2 + 16 + 8] = {0xA3, blockNum, 0x00}; memmove(&rcmd[3], data, 16); if (session) @@ -382,7 +382,7 @@ int mfpReadSector(uint8_t sectorNo, uint8_t keyType, uint8_t *key, uint8_t *data if (verbose) PrintAndLogEx(INFO, "--sector[%d]:%02x key:%04x", mfNumBlocksPerSector(sectorNo), sectorNo, uKeyNum); - mf4Session session; + mf4Session_t session; int res = MifareAuth4(&session, keyn, key, true, true, true, verbose, false); if (res) { PrintAndLogEx(ERR, "Sector %d authentication error: %d", sectorNo, res); diff --git a/client/mifare/mifare4.h b/client/mifare/mifare4.h index fe07aceaf..3efb9e43a 100644 --- a/client/mifare/mifare4.h +++ b/client/mifare/mifare4.h @@ -27,7 +27,7 @@ typedef struct { uint8_t Kmac[16]; uint16_t R_Ctr; uint16_t W_Ctr; -} mf4Session; +} mf4Session_t; typedef enum { mtypReadCmd, @@ -44,13 +44,13 @@ typedef struct { void mfpSetVerboseMode(bool verbose); const char *mfpGetErrorDescription(uint8_t errorCode); -int CalculateMAC(mf4Session *session, MACType_t mtype, uint8_t blockNum, uint8_t blockCount, uint8_t *data, int datalen, uint8_t *mac, bool verbose); -int MifareAuth4(mf4Session *session, uint8_t *keyn, uint8_t *key, bool activateField, bool leaveSignalON, bool dropFieldIfError, bool verbose, bool silentMode); +int CalculateMAC(mf4Session_t *session, MACType_t mtype, uint8_t blockNum, uint8_t blockCount, uint8_t *data, int datalen, uint8_t *mac, bool verbose); +int MifareAuth4(mf4Session_t *session, uint8_t *keyn, uint8_t *key, bool activateField, bool leaveSignalON, bool dropFieldIfError, bool verbose, bool silentMode); int MFPWritePerso(uint8_t *keyNum, uint8_t *key, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen); int MFPCommitPerso(bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen); -int MFPReadBlock(mf4Session *session, bool plain, uint8_t blockNum, uint8_t blockCount, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, uint8_t *mac); -int MFPWriteBlock(mf4Session *session, uint8_t blockNum, uint8_t *data, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, uint8_t *mac); +int MFPReadBlock(mf4Session_t *session, bool plain, uint8_t blockNum, uint8_t blockCount, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, uint8_t *mac); +int MFPWriteBlock(mf4Session_t *session, uint8_t blockNum, uint8_t *data, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, uint8_t *mac); int mfpReadSector(uint8_t sectorNo, uint8_t keyType, uint8_t *key, uint8_t *dataout, bool verbose); const char *mfGetAccessConditionsDesc(uint8_t blockn, uint8_t *data); From 1c9405605766fa8b07a499afd052a4ae41a9c7cd Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 30 Dec 2019 21:17:02 +0100 Subject: [PATCH 1288/1854] cppcheck --- armsrc/legicrfsim.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/legicrfsim.h b/armsrc/legicrfsim.h index 3d25fae0c..f7be94165 100644 --- a/armsrc/legicrfsim.h +++ b/armsrc/legicrfsim.h @@ -14,6 +14,6 @@ #include "common.h" -void LegicRfSimulate(uint8_t tagtype); +void LegicRfSimulate(uint8_t cardtype); #endif /* __LEGICRFSIM_H */ From 60719c77889ee53217304117ada1e3d61149976d Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 30 Dec 2019 21:17:37 +0100 Subject: [PATCH 1289/1854] cppcheck --- armsrc/lfadc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/lfadc.h b/armsrc/lfadc.h index 603d689a4..2d7836a38 100644 --- a/armsrc/lfadc.h +++ b/armsrc/lfadc.h @@ -27,6 +27,6 @@ void lf_init(bool reader); void lf_finalize(); size_t lf_detect_field_drop(size_t max); bool lf_manchester_send_bytes(const uint8_t *frame, size_t frame_len); -void lf_modulation(bool mod); +void lf_modulation(bool modulation); #endif // __LFADC_H__ From 7eac4818abd4d3811bcb21d39d3ab4b980e2aca0 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 30 Dec 2019 21:19:51 +0100 Subject: [PATCH 1290/1854] cppcheck --- armsrc/mifarecmd.c | 8 ++++---- armsrc/mifarecmd.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 643454672..ec561df3d 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -1727,13 +1727,13 @@ void MifareEMemGet(uint8_t blockno, uint8_t blockcnt) { // Load a card into the emulator memory // //----------------------------------------------------------------------------- -int MifareECardLoadExt(uint8_t numSectors, uint8_t keyType) { - int retval = MifareECardLoad(numSectors, keyType); +int MifareECardLoadExt(uint8_t sectorcnt, uint8_t keyType) { + int retval = MifareECardLoad(sectorcnt, keyType); reply_ng(CMD_HF_MIFARE_EML_LOAD, retval, NULL, 0); return retval; } -int MifareECardLoad(uint8_t numSectors, uint8_t keyType) { +int MifareECardLoad(uint8_t sectorcnt, uint8_t keyType) { uint32_t cuid = 0; struct Crypto1State mpcs = {0, 0}; @@ -1759,7 +1759,7 @@ int MifareECardLoad(uint8_t numSectors, uint8_t keyType) { goto out; } - for (uint8_t sectorNo = 0; sectorNo < numSectors; sectorNo++) { + for (uint8_t sectorNo = 0; sectorNo < sectorcnt; sectorNo++) { uint64_t ui64Key = emlGetKey(sectorNo, keyType); if (sectorNo == 0) { if (mifare_classic_auth(pcs, cuid, FirstBlockOfSector(sectorNo), keyType, ui64Key, AUTH_FIRST)) { diff --git a/armsrc/mifarecmd.h b/armsrc/mifarecmd.h index 2cb22d28b..5e5e4150e 100644 --- a/armsrc/mifarecmd.h +++ b/armsrc/mifarecmd.h @@ -34,7 +34,7 @@ void MifareEMemClr(void); void MifareEMemSet(uint8_t blockno, uint8_t blockcnt, uint8_t blockwidth, uint8_t *datain); void MifareEMemGet(uint8_t blockno, uint8_t blockcnt); int MifareECardLoad(uint8_t sectorcnt, uint8_t keytype); -int MifareECardLoadExt(uint8_t numSectors, uint8_t keyType); +int MifareECardLoadExt(uint8_t sectorcnt, uint8_t keyType); void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain); // Work with "magic Chinese" card void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain); From ddaa88406414ebdee6dc74d6f99e7177d780bdea Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 30 Dec 2019 21:22:51 +0100 Subject: [PATCH 1291/1854] cppcheck --- armsrc/spiffs_nucleus.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/spiffs_nucleus.h b/armsrc/spiffs_nucleus.h index c437faf30..d4ac87234 100644 --- a/armsrc/spiffs_nucleus.h +++ b/armsrc/spiffs_nucleus.h @@ -758,7 +758,7 @@ s32_t spiffs_gc_erase_page_stats( s32_t spiffs_gc_find_candidate( spiffs *fs, - spiffs_block_ix **block_candidate, + spiffs_block_ix **block_candidates, int *candidate_count, char fs_crammed); From e2f59d215fed5dbba2e68e21e6c14120587a305f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 30 Dec 2019 21:29:04 +0100 Subject: [PATCH 1292/1854] cppcheck --- armsrc/mifareutil.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/mifareutil.c b/armsrc/mifareutil.c index 97ac6ee90..cfd8f4b35 100644 --- a/armsrc/mifareutil.c +++ b/armsrc/mifareutil.c @@ -92,7 +92,7 @@ int mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, AddCrc14A(dcmd, 2); memcpy(ecmd, dcmd, sizeof(dcmd)); - if (crypted) { + if (pcs && crypted) { par[0] = 0; for (pos = 0; pos < 4; pos++) { ecmd[pos] = crypto1_byte(pcs, 0x00, 0) ^ dcmd[pos]; From e5db57747c1568ad44788a2673c82f52192957c9 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 30 Dec 2019 21:31:56 +0100 Subject: [PATCH 1293/1854] cppcheck --- armsrc/mifarecmd.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index ec561df3d..9bcec8862 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -1727,13 +1727,13 @@ void MifareEMemGet(uint8_t blockno, uint8_t blockcnt) { // Load a card into the emulator memory // //----------------------------------------------------------------------------- -int MifareECardLoadExt(uint8_t sectorcnt, uint8_t keyType) { - int retval = MifareECardLoad(sectorcnt, keyType); +int MifareECardLoadExt(uint8_t sectorcnt, uint8_t keytype) { + int retval = MifareECardLoad(sectorcnt, keytype); reply_ng(CMD_HF_MIFARE_EML_LOAD, retval, NULL, 0); return retval; } -int MifareECardLoad(uint8_t sectorcnt, uint8_t keyType) { +int MifareECardLoad(uint8_t sectorcnt, uint8_t keytype) { uint32_t cuid = 0; struct Crypto1State mpcs = {0, 0}; @@ -1760,14 +1760,14 @@ int MifareECardLoad(uint8_t sectorcnt, uint8_t keyType) { } for (uint8_t sectorNo = 0; sectorNo < sectorcnt; sectorNo++) { - uint64_t ui64Key = emlGetKey(sectorNo, keyType); + uint64_t ui64Key = emlGetKey(sectorNo, keytype); if (sectorNo == 0) { - if (mifare_classic_auth(pcs, cuid, FirstBlockOfSector(sectorNo), keyType, ui64Key, AUTH_FIRST)) { + if (mifare_classic_auth(pcs, cuid, FirstBlockOfSector(sectorNo), keytype, ui64Key, AUTH_FIRST)) { if (DBGLEVEL > DBG_ERROR) Dbprintf("Sector[%2d]. Auth error", sectorNo); break; } } else { - if (mifare_classic_auth(pcs, cuid, FirstBlockOfSector(sectorNo), keyType, ui64Key, AUTH_NESTED)) { + if (mifare_classic_auth(pcs, cuid, FirstBlockOfSector(sectorNo), keytype, ui64Key, AUTH_NESTED)) { retval = PM3_ESOFT; if (DBGLEVEL > DBG_ERROR) Dbprintf("Sector[%2d]. Auth nested error", sectorNo); goto out; From 2cfe4d33c5a9091611c1c9476d28c9b32f1ce9f0 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 30 Dec 2019 21:31:59 +0100 Subject: [PATCH 1294/1854] cppcheck --- armsrc/mifarecmd.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/mifarecmd.h b/armsrc/mifarecmd.h index 5e5e4150e..a127e79af 100644 --- a/armsrc/mifarecmd.h +++ b/armsrc/mifarecmd.h @@ -34,7 +34,7 @@ void MifareEMemClr(void); void MifareEMemSet(uint8_t blockno, uint8_t blockcnt, uint8_t blockwidth, uint8_t *datain); void MifareEMemGet(uint8_t blockno, uint8_t blockcnt); int MifareECardLoad(uint8_t sectorcnt, uint8_t keytype); -int MifareECardLoadExt(uint8_t sectorcnt, uint8_t keyType); +int MifareECardLoadExt(uint8_t sectorcnt, uint8_t keytype); void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain); // Work with "magic Chinese" card void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain); From eb635a2efc9c12f515f946ff9f7c82883b1e9017 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 30 Dec 2019 21:37:56 +0100 Subject: [PATCH 1295/1854] cppcheck --- armsrc/spiffs.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/armsrc/spiffs.h b/armsrc/spiffs.h index d75335e40..f10c86db0 100644 --- a/armsrc/spiffs.h +++ b/armsrc/spiffs.h @@ -577,7 +577,7 @@ s32_t SPIFFS_close(spiffs *fs, spiffs_file fh); * @param old path of file to rename * @param newPath new path of file */ -s32_t SPIFFS_rename(spiffs *fs, const char *old, const char *newPath); +s32_t SPIFFS_rename(spiffs *fs, const char *old_path, const char *new_path); #if SPIFFS_OBJ_META_LEN /** @@ -801,7 +801,7 @@ s32_t SPIFFS_ix_unmap(spiffs *fs, spiffs_file fh); * @param fh the mapped file handle of the file to remap * @param offset new absolute file offset where to start the index map */ -s32_t SPIFFS_ix_remap(spiffs *fs, spiffs_file fh, u32_t offs); +s32_t SPIFFS_ix_remap(spiffs *fs, spiffs_file fh, u32_t offset); /** * Utility function to get number of spiffs_page_ix entries a map buffer must From fd4edc390f537c82110f7169b6bdf60f77a9571d Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 30 Dec 2019 21:39:48 +0100 Subject: [PATCH 1296/1854] cppcheck --- armsrc/spiffs_nucleus.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/armsrc/spiffs_nucleus.h b/armsrc/spiffs_nucleus.h index d4ac87234..7fbf98acf 100644 --- a/armsrc/spiffs_nucleus.h +++ b/armsrc/spiffs_nucleus.h @@ -699,7 +699,7 @@ void spiffs_cb_object_event( spiffs *fs, spiffs_page_object_ix *objix, int ev, - spiffs_obj_id obj_id, + spiffs_obj_id obj_id_raw, spiffs_span_ix spix, spiffs_page_ix new_pix, u32_t new_size); @@ -707,14 +707,14 @@ void spiffs_cb_object_event( s32_t spiffs_object_open_by_id( spiffs *fs, spiffs_obj_id obj_id, - spiffs_fd *f, + spiffs_fd *fd, spiffs_flags flags, spiffs_mode mode); s32_t spiffs_object_open_by_page( spiffs *fs, spiffs_page_ix pix, - spiffs_fd *f, + spiffs_fd *fd, spiffs_flags flags, spiffs_mode mode); @@ -738,8 +738,8 @@ s32_t spiffs_object_read( s32_t spiffs_object_truncate( spiffs_fd *fd, - u32_t new_len, - u8_t remove_object); + u32_t new_size, + u8_t remove_full); s32_t spiffs_object_find_object_index_header_by_name( spiffs *fs, From 56d25b0786527f92cea417423c0fc1d46587ebdc Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 30 Dec 2019 21:40:31 +0100 Subject: [PATCH 1297/1854] cppcheck --- armsrc/string.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/string.h b/armsrc/string.h index 781641fb9..0ebb4ab54 100644 --- a/armsrc/string.h +++ b/armsrc/string.h @@ -24,7 +24,7 @@ char *strcat(char *dest, const char *src); void strreverse(char s[]); void itoa(int n, char s[]); char *strcpy(char *dst, const char *src); -char *strncpy(char *destination, const char *source, size_t num); +char *strncpy(char *dst, const char *src, size_t n); int strcmp(const char *s1, const char *s2); char *strtok(char *s, const char *delim); char *strchr(const char *s, int c); From c193eef3261d00d58a07a3f3169b31e583713198 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 30 Dec 2019 21:42:27 +0100 Subject: [PATCH 1298/1854] cppcheck --- client/aidsearch.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/aidsearch.h b/client/aidsearch.h index 9997d3868..00d2b134a 100644 --- a/client/aidsearch.h +++ b/client/aidsearch.h @@ -18,7 +18,7 @@ #include -int PrintAIDDescription(json_t *root, char *aid, bool verbose); +int PrintAIDDescription(json_t *xroot, char *aid, bool verbose); int PrintAIDDescriptionBuf(json_t *root, uint8_t *aid, size_t aidlen, bool verbose); json_t *AIDSearchInit(bool verbose); json_t *AIDSearchGetElm(json_t *root, int elmindx); From 2137e2b6c871ebaae3029188db091cf5f278a8dd Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 30 Dec 2019 21:43:03 +0100 Subject: [PATCH 1299/1854] cppcheck --- client/cmdhflist.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdhflist.h b/client/cmdhflist.h index d13285bc4..fbc8700d6 100644 --- a/client/cmdhflist.h +++ b/client/cmdhflist.h @@ -48,7 +48,7 @@ void annotateIso14443b(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize); void annotateIso14443a(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize); void annotateMfDesfire(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize); void annotateMifare(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize, uint8_t *parity, uint8_t paritysize, bool isResponse); -void annotateLTO(char *explanation, size_t size, uint8_t *cmd, uint8_t cmdsize); +void annotateLTO(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize); bool DecodeMifareData(uint8_t *cmd, uint8_t cmdsize, uint8_t *parity, bool isResponse, uint8_t *mfData, size_t *mfDataLen); bool NTParityChk(TAuthData *ad, uint32_t ntx); From 7a867cadcd992f9186d5178310c3a572f99977c5 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 30 Dec 2019 21:43:34 +0100 Subject: [PATCH 1300/1854] cppcheck --- client/cmdlffdx.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdlffdx.h b/client/cmdlffdx.h index d8b666ccb..63043c7c2 100644 --- a/client/cmdlffdx.h +++ b/client/cmdlffdx.h @@ -14,7 +14,7 @@ int CmdLFFdx(const char *Cmd); int detectFDXB(uint8_t *dest, size_t *size); int demodFDX(void); -int getFDXBits(uint64_t national_id, uint16_t country, uint8_t isanimal, uint8_t isextended, uint32_t extended, uint8_t *bits); +int getFDXBits(uint64_t national_id, uint16_t country, uint8_t is_animal, uint8_t is_extended, uint32_t extended, uint8_t *bits); #endif From 5de11784660df530bbe260007c0a23ff7ecc25d1 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 30 Dec 2019 21:44:42 +0100 Subject: [PATCH 1301/1854] cppcheck --- client/emv/apduinfo.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/emv/apduinfo.h b/client/emv/apduinfo.h index 590c72885..d319b4e43 100644 --- a/client/emv/apduinfo.h +++ b/client/emv/apduinfo.h @@ -59,7 +59,7 @@ typedef struct { extern int APDUDecode(uint8_t *data, int len, APDUStruct *apdu); extern int APDUEncode(APDUStruct *apdu, uint8_t *data, int *len); -extern int APDUEncodeS(sAPDU *apdu, bool extended, uint16_t le, uint8_t *data, int *len); +extern int APDUEncodeS(sAPDU *sapdu, bool extended, uint16_t le, uint8_t *data, int *len); extern void APDUPrint(APDUStruct apdu); extern void APDUPrintEx(APDUStruct apdu, size_t maxdatalen); From 155444440eb134bdb70127a6a022819aca1528ac Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 30 Dec 2019 21:45:18 +0100 Subject: [PATCH 1302/1854] cppcheck --- client/emv/emv_pk.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/emv/emv_pk.h b/client/emv/emv_pk.h index 015a06dd6..eda5883a8 100644 --- a/client/emv/emv_pk.h +++ b/client/emv/emv_pk.h @@ -35,7 +35,7 @@ struct emv_pk { #define EXPIRE(yy, mm, dd) 0x ## yy ## mm ## dd -struct emv_pk *emv_pk_parse_pk(char *bufm, size_t buflen); +struct emv_pk *emv_pk_parse_pk(char *buf, size_t buflen); struct emv_pk *emv_pk_new(size_t modlen, size_t explen); void emv_pk_free(struct emv_pk *pk); char *emv_pk_dump_pk(const struct emv_pk *pk); From 025c98fc53c1433f2babe6a79a1542eca695c33f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 30 Dec 2019 21:47:18 +0100 Subject: [PATCH 1303/1854] cppcheck --- client/hardnested/hardnested_bruteforce.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/hardnested/hardnested_bruteforce.c b/client/hardnested/hardnested_bruteforce.c index 682257415..159454110 100644 --- a/client/hardnested/hardnested_bruteforce.c +++ b/client/hardnested/hardnested_bruteforce.c @@ -294,7 +294,7 @@ static void write_benchfile(statelist_t *candidates) { #endif -bool brute_force_bs(float *bf_rate, statelist_t *candidates, uint32_t cuid, uint32_t num_acquired_nonces, uint64_t maximum_states, noncelist_t *nonces, uint8_t *best_first_bytes, uint64_t *foundkey) { +bool brute_force_bs(float *bf_rate, statelist_t *candidates, uint32_t cuid, uint32_t num_acquired_nonces, uint64_t maximum_states, noncelist_t *nonces, uint8_t *best_first_bytes, uint64_t *found_key) { #if defined (WRITE_BENCH_FILE) write_benchfile(candidates); #endif @@ -353,7 +353,7 @@ bool brute_force_bs(float *bf_rate, statelist_t *candidates, uint32_t cuid, uint *bf_rate = (float)num_keys_tested / ((float)elapsed_time / 1000.0); if (keys_found > 0) - *foundkey = found_bs_key; + *found_key = found_bs_key; return (keys_found != 0); } From 7dc65bf0f7806e6272dce2ab76a80851def76fcd Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 30 Dec 2019 22:21:41 +0100 Subject: [PATCH 1304/1854] cppcheck --- armsrc/cmd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/armsrc/cmd.c b/armsrc/cmd.c index 4b6dd3c1c..61ceda2f0 100644 --- a/armsrc/cmd.c +++ b/armsrc/cmd.c @@ -43,10 +43,10 @@ bool reply_via_fpc = false; bool reply_via_usb = false; int reply_old(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len) { - PacketResponseOLD txcmd; + PacketResponseOLD txcmd = {0}; - for (size_t i = 0; i < sizeof(PacketResponseOLD); i++) - ((uint8_t *)&txcmd)[i] = 0x00; +// for (size_t i = 0; i < sizeof(PacketResponseOLD); i++) +// ((uint8_t *)&txcmd)[i] = 0x00; // Compose the outgoing command frame txcmd.cmd = cmd; From 49d02981297e551171d7c156cf8878696bcfa4a0 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 31 Dec 2019 15:24:01 +0100 Subject: [PATCH 1305/1854] textual --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a4a91d13c..e29cf56b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Chg `hf mf chk | fchk` faster authentication by lower timeout limit. (@pwpiwi) - Chg `hf mf hardnested` - now detects "static / fixed" nonce tags and exits (@iceman1001) - Chg `hf mf csave` - now uses UID in filename (@iceman1001) - Fix `hf mf chk` - read block B logical error. #489 (@iceman1001) From b37383c48bd9d6b2fb7373f9650b37337fbc9a13 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 31 Dec 2019 15:25:22 +0100 Subject: [PATCH 1306/1854] textual --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e29cf56b6..0eac26074 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Chg `lf t55xx dump` - now supports saving to JSON (@iceman1001) - Chg `hf mf chk | fchk` faster authentication by lower timeout limit. (@pwpiwi) - Chg `hf mf hardnested` - now detects "static / fixed" nonce tags and exits (@iceman1001) - Chg `hf mf csave` - now uses UID in filename (@iceman1001) From 4677016aa6d3c1f97628d144edc1c8e38edde3f9 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 31 Dec 2019 15:27:57 +0100 Subject: [PATCH 1307/1854] textual --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0eac26074..ee2468215 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Chg mifare classic keytable output refactored and uses colors (@iceman1001) + - Fix `hf mf nested` - now writes the correct blockno (@iceman1001) - Chg `lf t55xx dump` - now supports saving to JSON (@iceman1001) - Chg `hf mf chk | fchk` faster authentication by lower timeout limit. (@pwpiwi) - Chg `hf mf hardnested` - now detects "static / fixed" nonce tags and exits (@iceman1001) From d748b2c8aba6df1a596951bd505bd1c600fa0b00 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 31 Dec 2019 15:29:46 +0100 Subject: [PATCH 1308/1854] textual --- client/cmdhfmf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 486457fed..9b43f5a3d 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -3350,7 +3350,7 @@ void printKeyTableEx(uint8_t sectorscnt, sector_t *e_sector, uint8_t start_secto PrintAndLogEx(NORMAL, "|---|----------------|---|----------------|---|"); if (e_sector[0].foundKey[0] > 1) { - PrintAndLogEx(NORMAL, "( " + PrintAndLogEx(INFO, "( " _YELLOW_("D") ":Dictionary / " _YELLOW_("S") ":darkSide / " _YELLOW_("U") ":User / " @@ -3361,7 +3361,7 @@ void printKeyTableEx(uint8_t sectorscnt, sector_t *e_sector, uint8_t start_secto ")" ); } else { - PrintAndLogEx(NORMAL, "(" _YELLOW_("0") ": Failed / " _YELLOW_("1") ": Success)"); + PrintAndLogEx(INFO, "( " _YELLOW_("0") ":Failed / " _YELLOW_("1") ":Success)"); } } From 714d5105e7517d056b379345e78ea7b134fafdc4 Mon Sep 17 00:00:00 2001 From: Thorsten Bosbach Date: Tue, 31 Dec 2019 17:22:10 +0100 Subject: [PATCH 1309/1854] fix hitagS read/info output --- armsrc/hitagS.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/armsrc/hitagS.c b/armsrc/hitagS.c index 7c8a01523..9d86be616 100644 --- a/armsrc/hitagS.c +++ b/armsrc/hitagS.c @@ -1273,7 +1273,7 @@ void ReadHitagS(hitag_function htf, hitag_data *htd) { } else if (tag.pstate == HT_SELECTED && tag.tstate == HT_READING_PAGE && rxlen > 0) { - //save received data + //save received data - 40 bits z = 0; for (i = 0; i < 5; i++) { for (j = 0; j < 8; j++) { @@ -1284,33 +1284,33 @@ void ReadHitagS(hitag_function htf, hitag_data *htd) { } } k = 0; - for (i = 4; i < 36; i++) { + for (i = 4; i < 36; i++) { // ignore first 4 bits: SOF pageData[k] = response_bit[i]; k++; } - for (i = 0; i < 4; i++) - tag.pages[sendNum / 4][sendNum % 4] = 0x0; - for (i = 0; i < 4; i++) { - tag.pages[sendNum / 4][sendNum % 4] += ((pageData[i * 8] << 7) - | (pageData[1 + (i * 8)] << 6) - | (pageData[2 + (i * 8)] << 5) - | (pageData[3 + (i * 8)] << 4) - | (pageData[4 + (i * 8)] << 3) - | (pageData[5 + (i * 8)] << 2) - | (pageData[6 + (i * 8)] << 1) | pageData[7 + (i * 8)]) - << (i * 8); + for (i = 0; i < 4; i++) // set page bytes to 0 + tag.pages[sendNum][i] = 0x0; + for (i = 0; i < 4; i++) { // set page bytes from recieved bits + tag.pages[sendNum][i] += ((pageData[i * 8] << 7) + | (pageData[1 + (i * 8)] << 6) + | (pageData[2 + (i * 8)] << 5) + | (pageData[3 + (i * 8)] << 4) + | (pageData[4 + (i * 8)] << 3) + | (pageData[5 + (i * 8)] << 2) + | (pageData[6 + (i * 8)] << 1) + | pageData[7 + (i * 8)]); } if (tag.auth && tag.LKP && sendNum == 1) { Dbprintf("Page[%2d]: %02X %02X %02X %02X", sendNum, pwdh0, - (tag.pages[sendNum / 4][sendNum % 4] >> 16) & 0xff, - (tag.pages[sendNum / 4][sendNum % 4] >> 8) & 0xff, - tag.pages[sendNum / 4][sendNum % 4] & 0xff); + (tag.pages[sendNum][2]) & 0xff, + (tag.pages[sendNum][1]) & 0xff, + tag.pages[sendNum][0] & 0xff); } else { Dbprintf("Page[%2d]: %02X %02X %02X %02X", sendNum, - (tag.pages[sendNum / 4][sendNum % 4] >> 24) & 0xff, - (tag.pages[sendNum / 4][sendNum % 4] >> 16) & 0xff, - (tag.pages[sendNum / 4][sendNum % 4] >> 8) & 0xff, - tag.pages[sendNum / 4][sendNum % 4] & 0xff); + (tag.pages[sendNum][3]) & 0xff, + (tag.pages[sendNum][2]) & 0xff, + (tag.pages[sendNum][1]) & 0xff, + tag.pages[sendNum][0] & 0xff); } sendNum++; From 944242d9290e3af2a3895ee9e0a2c1cb1f7519a8 Mon Sep 17 00:00:00 2001 From: "osboxes.org" Date: Tue, 31 Dec 2019 21:32:24 +0100 Subject: [PATCH 1310/1854] style --- armsrc/spiffs_nucleus.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/armsrc/spiffs_nucleus.c b/armsrc/spiffs_nucleus.c index 459222d5b..74c5ade09 100644 --- a/armsrc/spiffs_nucleus.c +++ b/armsrc/spiffs_nucleus.c @@ -2244,7 +2244,7 @@ s32_t spiffs_fd_find_new(spiffs *fs, spiffs_fd **fd, const char *name) { #if SPIFFS_TEMPORAL_FD_CACHE u32_t i; u16_t min_score = 0xffff; - u32_t cand_ix = (u32_t) -1; + u32_t cand_ix = (u32_t) - 1; u32_t name_hash = name ? spiffs_hash(fs, (const u8_t *)name) : 0; spiffs_fd *fds = (spiffs_fd *)fs->fd_space; @@ -2275,7 +2275,7 @@ s32_t spiffs_fd_find_new(spiffs *fs, spiffs_fd **fd, const char *name) { } } - if (cand_ix != (u32_t) -1) { + if (cand_ix != (u32_t) - 1) { spiffs_fd *cur_fd = &fds[cand_ix]; if (name) { if (cur_fd->name_hash == name_hash && cur_fd->score > 0) { From cabbed8b911c24405c7195e7a348d54b6d5826b0 Mon Sep 17 00:00:00 2001 From: "osboxes.org" Date: Tue, 31 Dec 2019 21:37:57 +0100 Subject: [PATCH 1311/1854] style --- client/cmdlfkeri.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/cmdlfkeri.c b/client/cmdlfkeri.c index b36be56b9..394d16330 100644 --- a/client/cmdlfkeri.c +++ b/client/cmdlfkeri.c @@ -128,8 +128,8 @@ static int CmdKeriClone(const char *Cmd) { T55x7_MODULATION_PSK1 | T55x7_PSKCF_RF_2 | 2 << T55x7_MAXBLOCK_SHIFT, - 0, - 0 + 0, + 0 }; // dynamic bitrate used From 56673c29d390192451599b11bf2e748d14da0db9 Mon Sep 17 00:00:00 2001 From: "osboxes.org" Date: Tue, 31 Dec 2019 21:38:13 +0100 Subject: [PATCH 1312/1854] style --- client/comms.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/comms.c b/client/comms.c index d39680c6c..cbabe3354 100644 --- a/client/comms.c +++ b/client/comms.c @@ -725,7 +725,7 @@ bool WaitForResponseTimeoutW(uint32_t cmd, PacketResponseNG *response, size_t ms } uint64_t tmp_clk = __atomic_load_n(&timeout_start_time, __ATOMIC_SEQ_CST); - if ((ms_timeout != (size_t) -1) && (msclock() - tmp_clk > ms_timeout)) + if ((ms_timeout != (size_t) - 1) && (msclock() - tmp_clk > ms_timeout)) break; if (msclock() - tmp_clk > 3000 && show_warning) { @@ -807,7 +807,7 @@ static bool dl_it(uint8_t *dest, uint32_t bytes, PacketResponseNG *response, siz __atomic_store_n(&timeout_start_time, msclock(), __ATOMIC_SEQ_CST); // Add delay depending on the communication channel & speed - if (ms_timeout != (size_t) -1) + if (ms_timeout != (size_t) - 1) ms_timeout += communication_delay(); while (true) { From 48eeceae58c84bafa3e5319b11270622257c4404 Mon Sep 17 00:00:00 2001 From: "osboxes.org" Date: Tue, 31 Dec 2019 21:38:45 +0100 Subject: [PATCH 1313/1854] style --- client/fido/cose.c | 66 +++++++++++++++++++++++----------------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/client/fido/cose.c b/client/fido/cose.c index 0812288e3..9caa0f4cc 100644 --- a/client/fido/cose.c +++ b/client/fido/cose.c @@ -81,39 +81,39 @@ const char *GetCOSECurveDescription(int id) { // RFC8152 https://www.iana.org/assignments/cose/cose.xhtml#algorithms COSEValueNameDesc_t COSEAlg[] = { - {-65536, "Unassigned", "Unassigned"}, - {-65535, "RS1", "RSASSA-PKCS1-v1_5 w/ SHA-1"}, - {-259, "RS512", "RSASSA-PKCS1-v1_5 w/ SHA-512"}, - {-258, "RS384", "RSASSA-PKCS1-v1_5 w/ SHA-384"}, - {-257, "RS256", "RSASSA-PKCS1-v1_5 w/ SHA-256"}, - {-42, "RSAES-OAEP w/ SHA-512", "RSAES-OAEP w/ SHA-512"}, - {-41, "RSAES-OAEP w/ SHA-256", "RSAES-OAEP w/ SHA-256"}, - {-40, "RSAES-OAEP w/ RFC 8017 def param", "RSAES-OAEP w/ SHA-1"}, - {-39, "PS512", "RSASSA-PSS w/ SHA-512"}, - {-38, "PS384", "RSASSA-PSS w/ SHA-384"}, - {-37, "PS256", "RSASSA-PSS w/ SHA-256"}, - {-36, "ES512", "ECDSA w/ SHA-512"}, - {-35, "ES384", "ECDSA w/ SHA-384"}, - {-34, "ECDH-SS + A256KW", "ECDH SS w/ Concat KDF and AES Key Wrap w/ 256-bit key"}, - {-33, "ECDH-SS + A192KW", "ECDH SS w/ Concat KDF and AES Key Wrap w/ 192-bit key"}, - {-32, "ECDH-SS + A128KW", "ECDH SS w/ Concat KDF and AES Key Wrap w/ 128-bit key"}, - {-31, "ECDH-ES + A256KW", "ECDH ES w/ Concat KDF and AES Key Wrap w/ 256-bit key"}, - {-30, "ECDH-ES + A192KW", "ECDH ES w/ Concat KDF and AES Key Wrap w/ 192-bit key"}, - {-29, "ECDH-ES + A128KW", "ECDH ES w/ Concat KDF and AES Key Wrap w/ 128-bit key"}, - {-28, "ECDH-SS + HKDF-512", "ECDH SS w/ HKDF - generate key directly"}, - {-27, "ECDH-SS + HKDF-256", "ECDH SS w/ HKDF - generate key directly"}, - {-26, "ECDH-ES + HKDF-512", "ECDH ES w/ HKDF - generate key directly"}, - {-25, "ECDH-ES + HKDF-256", "ECDH ES w/ HKDF - generate key directly"}, - {-13, "direct+HKDF-AES-256", "Shared secret w/ AES-MAC 256-bit key"}, - {-12, "direct+HKDF-AES-128", "Shared secret w/ AES-MAC 128-bit key"}, - {-11, "direct+HKDF-SHA-512", "Shared secret w/ HKDF and SHA-512"}, - {-10, "direct+HKDF-SHA-256", "Shared secret w/ HKDF and SHA-256"}, - {-8, "EdDSA", "EdDSA"}, - {-7, "ES256", "ECDSA w/ SHA-256"}, - {-6, "direct", "Direct use of CEK"}, - {-5, "A256KW", "AES Key Wrap w/ 256-bit key"}, - {-4, "A192KW", "AES Key Wrap w/ 192-bit key"}, - {-3, "A128KW", "AES Key Wrap w/ 128-bit key"}, + { -65536, "Unassigned", "Unassigned"}, + { -65535, "RS1", "RSASSA-PKCS1-v1_5 w/ SHA-1"}, + { -259, "RS512", "RSASSA-PKCS1-v1_5 w/ SHA-512"}, + { -258, "RS384", "RSASSA-PKCS1-v1_5 w/ SHA-384"}, + { -257, "RS256", "RSASSA-PKCS1-v1_5 w/ SHA-256"}, + { -42, "RSAES-OAEP w/ SHA-512", "RSAES-OAEP w/ SHA-512"}, + { -41, "RSAES-OAEP w/ SHA-256", "RSAES-OAEP w/ SHA-256"}, + { -40, "RSAES-OAEP w/ RFC 8017 def param", "RSAES-OAEP w/ SHA-1"}, + { -39, "PS512", "RSASSA-PSS w/ SHA-512"}, + { -38, "PS384", "RSASSA-PSS w/ SHA-384"}, + { -37, "PS256", "RSASSA-PSS w/ SHA-256"}, + { -36, "ES512", "ECDSA w/ SHA-512"}, + { -35, "ES384", "ECDSA w/ SHA-384"}, + { -34, "ECDH-SS + A256KW", "ECDH SS w/ Concat KDF and AES Key Wrap w/ 256-bit key"}, + { -33, "ECDH-SS + A192KW", "ECDH SS w/ Concat KDF and AES Key Wrap w/ 192-bit key"}, + { -32, "ECDH-SS + A128KW", "ECDH SS w/ Concat KDF and AES Key Wrap w/ 128-bit key"}, + { -31, "ECDH-ES + A256KW", "ECDH ES w/ Concat KDF and AES Key Wrap w/ 256-bit key"}, + { -30, "ECDH-ES + A192KW", "ECDH ES w/ Concat KDF and AES Key Wrap w/ 192-bit key"}, + { -29, "ECDH-ES + A128KW", "ECDH ES w/ Concat KDF and AES Key Wrap w/ 128-bit key"}, + { -28, "ECDH-SS + HKDF-512", "ECDH SS w/ HKDF - generate key directly"}, + { -27, "ECDH-SS + HKDF-256", "ECDH SS w/ HKDF - generate key directly"}, + { -26, "ECDH-ES + HKDF-512", "ECDH ES w/ HKDF - generate key directly"}, + { -25, "ECDH-ES + HKDF-256", "ECDH ES w/ HKDF - generate key directly"}, + { -13, "direct+HKDF-AES-256", "Shared secret w/ AES-MAC 256-bit key"}, + { -12, "direct+HKDF-AES-128", "Shared secret w/ AES-MAC 128-bit key"}, + { -11, "direct+HKDF-SHA-512", "Shared secret w/ HKDF and SHA-512"}, + { -10, "direct+HKDF-SHA-256", "Shared secret w/ HKDF and SHA-256"}, + { -8, "EdDSA", "EdDSA"}, + { -7, "ES256", "ECDSA w/ SHA-256"}, + { -6, "direct", "Direct use of CEK"}, + { -5, "A256KW", "AES Key Wrap w/ 256-bit key"}, + { -4, "A192KW", "AES Key Wrap w/ 192-bit key"}, + { -3, "A128KW", "AES Key Wrap w/ 128-bit key"}, {0, "Reserved", "Reserved"}, {1, "A128GCM", "AES-GCM mode w/ 128-bit key, 128-bit tag"}, {2, "A192GCM", "AES-GCM mode w/ 192-bit key, 128-bit tag"}, From bd1244287f07821d95813508433a7776874cbfe5 Mon Sep 17 00:00:00 2001 From: "osboxes.org" Date: Tue, 31 Dec 2019 21:39:37 +0100 Subject: [PATCH 1314/1854] style --- client/jansson/hashtable.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/jansson/hashtable.c b/client/jansson/hashtable.c index aee159242..071ba585f 100644 --- a/client/jansson/hashtable.c +++ b/client/jansson/hashtable.c @@ -222,7 +222,7 @@ int hashtable_set(hashtable_t *hashtable, const char *key, json_t *value) { allocated. */ size_t len = strlen(key); - if (len >= (size_t) -1 - offsetof(pair_t, key)) { + if (len >= (size_t) - 1 - offsetof(pair_t, key)) { /* Avoid an overflow if the key is very long */ return -1; } From 1ec7bd1388fc9d3f3427b4419261de41391cf5c9 Mon Sep 17 00:00:00 2001 From: "osboxes.org" Date: Tue, 31 Dec 2019 21:39:55 +0100 Subject: [PATCH 1315/1854] style --- client/jansson/jansson.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/jansson/jansson.h b/client/jansson/jansson.h index 6f42d68c1..0f868c2f2 100644 --- a/client/jansson/jansson.h +++ b/client/jansson/jansson.h @@ -119,7 +119,7 @@ json_t *json_null(void); static JSON_INLINE json_t *json_incref(json_t *json) { - if (json && json->refcount != (size_t) -1) + if (json && json->refcount != (size_t) - 1) JSON_INTERNAL_INCREF(json); return json; } @@ -129,7 +129,7 @@ void json_delete(json_t *json); static JSON_INLINE void json_decref(json_t *json) { - if (json && json->refcount != (size_t) -1 && JSON_INTERNAL_DECREF(json) == 0) + if (json && json->refcount != (size_t) - 1 && JSON_INTERNAL_DECREF(json) == 0) json_delete(json); } From 855aee04ddf7e0898beeebbfa5fa88b68d566cb9 Mon Sep 17 00:00:00 2001 From: "osboxes.org" Date: Tue, 31 Dec 2019 21:40:12 +0100 Subject: [PATCH 1316/1854] style --- client/jansson/load.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/jansson/load.c b/client/jansson/load.c index 4e05dc87b..7f3fa7458 100644 --- a/client/jansson/load.c +++ b/client/jansson/load.c @@ -1079,7 +1079,7 @@ static int callback_get(void *data) { if (stream->pos >= stream->len) { stream->pos = 0; stream->len = stream->callback(stream->data, MAX_BUF_LEN, stream->arg); - if (stream->len == 0 || stream->len == (size_t) -1) + if (stream->len == 0 || stream->len == (size_t) - 1) return EOF; } From bd38d68bd4fd604f972cb2b37e36703e20e8e0bb Mon Sep 17 00:00:00 2001 From: "osboxes.org" Date: Tue, 31 Dec 2019 21:40:27 +0100 Subject: [PATCH 1317/1854] style --- client/jansson/value.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/jansson/value.c b/client/jansson/value.c index fcc0caa2c..7c1bc9438 100644 --- a/client/jansson/value.c +++ b/client/jansson/value.c @@ -861,19 +861,19 @@ double json_number_value(const json_t *json) { /*** simple values ***/ json_t *json_true(void) { - static json_t the_true = {JSON_TRUE, (size_t) -1}; + static json_t the_true = {JSON_TRUE, (size_t) - 1}; return &the_true; } json_t *json_false(void) { - static json_t the_false = {JSON_FALSE, (size_t) -1}; + static json_t the_false = {JSON_FALSE, (size_t) - 1}; return &the_false; } json_t *json_null(void) { - static json_t the_null = {JSON_NULL, (size_t) -1}; + static json_t the_null = {JSON_NULL, (size_t) - 1}; return &the_null; } From 795cc1bc62abb0e4c900a58528e2f03f7f4de3a8 Mon Sep 17 00:00:00 2001 From: "osboxes.org" Date: Tue, 31 Dec 2019 21:41:36 +0100 Subject: [PATCH 1318/1854] style --- client/luascripts/hf_bruteforce.lua | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/client/luascripts/hf_bruteforce.lua b/client/luascripts/hf_bruteforce.lua index 5ba6d9802..a3a6636b8 100644 --- a/client/luascripts/hf_bruteforce.lua +++ b/client/luascripts/hf_bruteforce.lua @@ -1,4 +1,4 @@ --- Run me like this: proxmark3 /dev/rfcomm0 -l ./hf_bruteforce.lua +-- Run me like this: proxmark3 /dev/rfcomm0 -l ./hf_bruteforce.lua local getopt = require('getopt') @@ -19,7 +19,7 @@ script run hf_bruteforce -s start_id -e end_id -t timeout -d direction Arguments: -h this help - -s 0-0xFFFFFFFF start id + -s 0-0xFFFFFFFF start id -e 0-0xFFFFFFFF end id -t 0-99999, pause timeout (ms) between cards (use the word 'pause' to wait for user input) ]] @@ -77,21 +77,21 @@ local function main(args) local timeout = 0 local start_id = 0 local end_id = 0xFFFFFFFF - - for o, a in getopt.getopt(args, 'e:s:t:h') do + + for o, a in getopt.getopt(args, 'e:s:t:h') do if o == 's' then start_id = a end if o == 'e' then end_id = a end if o == 't' then timeout = a end if o == 'h' then return print(usage) end end - + -- template local command = 'hf 14a sim t 1 u %08X' - + print(' Bruteforcing MFC card numbers from 00000000 to FFFFFFFF using delay: '..timeout) print('') print( string.rep('--',20) ) - + for n = start_id, end_id do local c = string.format( command, n ) print(' Running: "'..c..'"') From e7056a035df6921362883136160c8d4d4c02ba67 Mon Sep 17 00:00:00 2001 From: "osboxes.org" Date: Tue, 31 Dec 2019 21:42:53 +0100 Subject: [PATCH 1319/1854] style --- client/luascripts/mfu_magic.lua | 280 ++++++++++++++++---------------- 1 file changed, 140 insertions(+), 140 deletions(-) diff --git a/client/luascripts/mfu_magic.lua b/client/luascripts/mfu_magic.lua index a10b5776d..d8eff1f40 100644 --- a/client/luascripts/mfu_magic.lua +++ b/client/luascripts/mfu_magic.lua @@ -17,22 +17,22 @@ example = [[ -- wipe tag script run mfu_magic -w - + -- wipe a locked down tag by giving the password script run mfu_magic -k ffffffff -w - + --read magic tag configuration - script run mfu_magic -c - + script run mfu_magic -c + -- set uid script run mfu_magic -u 04112233445566 - + -- set pwd / pack script run mfu_magic -p 11223344 -a 8080 - + -- set version to NTAG213 script run mfu_magic -v 0004040201000f03 - + -- set signature script run mfu_magic -s 1122334455667788990011223344556677889900112233445566778899001122 ]] @@ -40,7 +40,7 @@ usage = [[ Usage: script run mfu_magic -h -k -c -w -u -t -p -a -s -o -v - + Arguments: -h this help -c read magic configuration @@ -64,10 +64,10 @@ Arguments: -s signature data (64 hexsymbols), set signature data on tag. -o OTP data (8 hexsymbols), set one-time-pad data on tag. -v version data (16 hexsymbols), set version data on tag. - -w wipe tag. You can specify password if the tag has been locked down. Fills tag with zeros and put default values for NTAG213 (like -t 5) + -w wipe tag. You can specify password if the tag has been locked down. Fills tag with zeros and put default values for NTAG213 (like -t 5) -k pwd to use with the wipe option ]] ---- +--- -- A debug printout-function local function dbg(args) if not DEBUG then return end @@ -80,14 +80,14 @@ local function dbg(args) else print('###', args) end -end +end -- This is only meant to be used when errors occur local function oops(err) print("ERROR: ",err) core.clearCommandBuffer() return nil, err end ---- +--- -- Usage help local function help() print(copyright) @@ -109,7 +109,7 @@ local function set_password(pwd) end --- Picks out and displays the data read from a tag -- Specifically, takes a usb packet, converts to a Command --- (as in commands.lua), takes the data-array and +-- (as in commands.lua), takes the data-array and -- reads the number of bytes specified in arg1 (arg0 in c-struct) -- @param usbpacket the data received from the device local function getResponseData(usbpacket) @@ -122,15 +122,15 @@ end local function sendRaw(rawdata, options) local flags = lib14a.ISO14A_COMMAND.ISO14A_NO_DISCONNECT - + lib14a.ISO14A_COMMAND.ISO14A_RAW + + lib14a.ISO14A_COMMAND.ISO14A_RAW + lib14a.ISO14A_COMMAND.ISO14A_APPEND_CRC - local c = Command:newMIX{cmd = cmds.CMD_READER_ISO_14443a, + local c = Command:newMIX{cmd = cmds.CMD_READER_ISO_14443a, arg1 = flags, -- arg2 contains the length, which is half the length of the ASCII-string rawdata - arg2 = string.len(rawdata)/2, + arg2 = string.len(rawdata)/2, data = rawdata} - + return c:sendMIX(options.ignore_response) end --- @@ -138,7 +138,7 @@ end local function send(payload) local usb, err = sendRaw(payload,{ignore_response = false}) if err then return oops(err) end - return getResponseData(usb) + return getResponseData(usb) end --- -- select tag and if password is set, authenticate @@ -152,7 +152,7 @@ local function connect() return oops(err) end core.clearCommandBuffer() - + --authenticate if needed using global variable if _password then send('1B'.._password) @@ -170,7 +170,7 @@ local function read_config() -- 04 response indicates that blocks has been locked down. if pwd == '04' then lib14a.disconnect(); return nil, "can't read configuration, "..err_lock end - + -- read PACK local pack = send("30F1"):sub(1,4) @@ -188,13 +188,13 @@ local function read_config() elseif cardtype == '01' then typestr = 'NTAG 215' elseif cardtype == '02' then typestr = 'NTAG 216' end - + print('Magic NTAG 21* Configuration') print(' - Type ', typestr, '(geniune cardtype)') print(' - Password', pwd) print(' - Pack ', pack) print(' - Version ', version) - print(' - Signature', signature1..signature2) + print(' - Signature', signature1..signature2) lib14a.disconnect() return true, 'Ok' @@ -212,13 +212,13 @@ local function write_signature(data) if not info then return false, "Can't select card" end print('Writing new signature') - + local b,c local cmd = 'A2F%d%s' local j = 2 for i = 1, #data, 8 do b = data:sub(i,i+7) - c = cmd:format(j,b) + c = cmd:format(j,b) local resp = send(c) if resp == '04' then lib14a.disconnect(); return nil, 'Failed to write signature' end j = j + 1 @@ -228,20 +228,20 @@ local function write_signature(data) end --- -- Write PWD -local function write_pwd(pwd) +local function write_pwd(pwd) -- PWD string checks if pwd == nil then return nil, 'empty PWD string' end if #pwd == 0 then return nil, 'empty PWD string' end if #pwd ~= 8 then return nil, 'PWD wrong length. Should be 4 hex bytes' end - + local info = connect() if not info then return false, "Can't select card" end - + print('Writing new PWD ', pwd) - + local resp = send('A2F0'..pwd) lib14a.disconnect() - if resp == '04' then + if resp == '04' then return nil, 'Failed to write password' else return true, 'Ok' @@ -249,7 +249,7 @@ local function write_pwd(pwd) end --- -- Write PACK -local function write_pack(pack) +local function write_pack(pack) -- PACK string checks if pack == nil then return nil, 'empty PACK string' end if #pack == 0 then return nil, 'empty PACK string' end @@ -257,16 +257,16 @@ local function write_pack(pack) local info = connect() if not info then return false, "Can't select card" end - + print('Writing new PACK', pack) - + local resp = send('A2F1'..pack..'0000') lib14a.disconnect() - if resp == '04' then + if resp == '04' then return nil, 'Failed to write pack' else return true, 'Ok' - end + end end -- -- Write OTP block @@ -279,16 +279,16 @@ local function write_otp(block3) local info = connect() if not info then return false, "Can't select card" end - + print('Writing new OTP ', block3) local resp = send('A203'..block3) lib14a.disconnect() - if resp == '04' then + if resp == '04' then return nil, 'Failed to write OTP' else return true, 'Ok' - end + end end -- -- Writes a UID with bcc1, bcc2. Needs a magic tag. @@ -300,8 +300,8 @@ local function write_uid(uid) local info = connect() if not info then return false, "Can't select card" end - - print('Writing new UID ', uid) + + print('Writing new UID ', uid) local uidbytes = utils.ConvertHexToBytes(uid) local bcc1 = bxor(bxor(bxor(uidbytes[1], uidbytes[2]), uidbytes[3]), 0x88) @@ -313,14 +313,14 @@ local function write_uid(uid) resp = send('A200'..block0) resp = send('A201'..block1) - resp = send('A202'..block2) + resp = send('A202'..block2) lib14a.disconnect() - - if resp == '04' then + + if resp == '04' then return nil, 'Failed to write new uid' else return true, 'Ok' - end + end end --- -- Write VERSION data, @@ -333,54 +333,54 @@ local function write_version(data) local info = connect() if not info then return false, "Can't select card" end - + print('Writing new version', data) - + local b1 = data:sub(1,8) local b2 = data:sub(9,16) local resp resp = send('A2FA'..b1) resp = send('A2FB'..b2) lib14a.disconnect() - if resp == '04' then + if resp == '04' then return nil, 'Failed to write version' else return true, 'Ok' - end + end end --- --- writen TYPE which card is based on. +-- writen TYPE which card is based on. -- 00 = 213, 01 = 215, 02 = 216 -local function write_type(data) +local function write_type(data) -- type string checks if data == nil then return nil, 'empty type string' end if #data == 0 then return nil, 'empty type string' end if #data ~= 2 then return nil, 'type wrong length. Should be 1 hex byte' end - + local info = connect() if not info then return false, "Can't select card" end print('Writing new type', data) local resp = send('A2FC'..data..'000000') lib14a.disconnect() - if resp == '04' then + if resp == '04' then return nil, 'Failed to write type' else return true, 'Ok' - end + end end --- -- Set tag type. Predefinde version data together with magic type set. -- Since cmd always gives 10 bytes len (data+crc) we can impersonate the following types --- we only truely be three types NTAG 213,215 and 216 +-- we only truely be three types NTAG 213,215 and 216 local function set_type(tagtype) -- tagtype checks - if type(tagtype) == 'string' then tagtype = tonumber(tagtype, 10) end - if tagtype == nil then return nil, 'empty tagtype' end - - if tagtype == 1 then - print('Setting: UL-EV1 48') + if type(tagtype) == 'string' then tagtype = tonumber(tagtype, 10) end + if tagtype == nil then return nil, 'empty tagtype' end + + if tagtype == 1 then + print('Setting: UL-EV1 48') write_otp('00000000') -- Setting OTP to default 00 00 00 00 write_version('0004030101000b03') -- UL-EV1 (48) 00 04 03 01 01 00 0b 03 write_type('00') -- based on NTAG213.. @@ -389,9 +389,9 @@ local function set_type(tagtype) connect() send('a210000000FF') send('a21100050000') - - elseif tagtype == 2 then - print('Setting: UL-EV1 128') + + elseif tagtype == 2 then + print('Setting: UL-EV1 128') write_otp('00000000') -- Setting OTP to default 00 00 00 00 write_version('0004030101000e03') -- UL-EV1 (128) 00 04 03 01 01 00 0e 03 write_type('01') @@ -399,146 +399,146 @@ local function set_type(tagtype) -- Setting UL-Ev1 default config bl 37,38 connect() send('a225000000FF') - send('a22600050000') - elseif tagtype == 3 then + send('a22600050000') + elseif tagtype == 3 then print('Setting: NTAG 210') - write_version('0004040101000b03') -- NTAG210 00 04 04 01 01 00 0b 03 + write_version('0004040101000b03') -- NTAG210 00 04 04 01 01 00 0b 03 write_type('00') - + -- Setting NTAG210 default CC block456 - connect() + connect() send('a203e1100600') send('a2040300fe00') send('a20500000000') -- Setting cfg1/cfg2 send('a210000000FF') - send('a21100050000') - elseif tagtype == 4 then + send('a21100050000') + elseif tagtype == 4 then print('Setting: NTAG 212') - write_version('0004040101000E03') -- NTAG212 00 04 04 01 01 00 0E 03 + write_version('0004040101000E03') -- NTAG212 00 04 04 01 01 00 0E 03 write_type('00') -- Setting NTAG212 default CC block456 - connect() + connect() send('a203e1101000') send('a2040103900a') send('a205340300fe') -- Setting cfg1/cfg2 send('a225000000FF') - send('a22600050000') - elseif tagtype == 5 then + send('a22600050000') + elseif tagtype == 5 then print('Setting: NTAG 213') - write_version('0004040201000F03') -- NTAG213 00 04 04 02 01 00 0f 03 + write_version('0004040201000F03') -- NTAG213 00 04 04 02 01 00 0f 03 write_type('00') - + -- Setting NTAG213 default CC block456 connect() send('a203e1101200') send('a2040103a00c') send('a205340300fe') - -- setting cfg1/cfg2 + -- setting cfg1/cfg2 send('a229000000ff') - send('a22a00050000') + send('a22a00050000') elseif tagtype == 6 then - print('Setting: NTAG 215') + print('Setting: NTAG 215') write_version('0004040201001103') -- NTAG215 00 04 04 02 01 00 11 03 write_type('01') -- Setting NTAG215 default CC block456 - connect() + connect() send('a203e1103e00') send('a2040300fe00') send('a20500000000') - -- setting cfg1/cfg2 + -- setting cfg1/cfg2 send('a283000000ff') send('a28400050000') elseif tagtype == 7 then - print('Setting: NTAG 216') + print('Setting: NTAG 216') write_version('0004040201001303') -- NTAG216 00 04 04 02 01 00 13 03 write_type('02') - + -- Setting NTAG216 default CC block456 - connect() + connect() send('a203e1106d00') send('a2040300fe00') send('a20500000000') - -- setting cfg1/cfg2 + -- setting cfg1/cfg2 send('a2e3000000ff') send('a2e400050000') elseif tagtype == 8 then - print('Setting: NTAG I2C 1K') + print('Setting: NTAG I2C 1K') write_version('0004040502011303') -- NTAG_I2C_1K 00 04 04 05 02 01 13 03 write_type('02') - + -- Setting NTAG I2C 1K default CC block456 - connect() + connect() send('a203e1106D00') send('a2040300fe00') - send('a20500000000') - elseif tagtype == 9 then - print('Setting: NTAG I2C 2K') + send('a20500000000') + elseif tagtype == 9 then + print('Setting: NTAG I2C 2K') write_version('0004040502011503') -- NTAG_I2C_2K 00 04 04 05 02 01 15 03 write_type('02') - + -- Setting NTAG I2C 2K default CC block456 - connect() + connect() send('a203e110EA00') send('a2040300fe00') send('a20500000000') elseif tagtype == 10 then - print('Setting: NTAG I2C plus 1K') + print('Setting: NTAG I2C plus 1K') write_version('0004040502021303') -- NTAG_I2C_1K 00 04 04 05 02 02 13 03 - write_type('02') + write_type('02') -- Setting NTAG I2C 1K default CC block456 - connect() + connect() send('a203e1106D00') send('a2040300fe00') - send('a20500000000') - elseif tagtype == 11 then - print('Setting: NTAG I2C plus 2K') + send('a20500000000') + elseif tagtype == 11 then + print('Setting: NTAG I2C plus 2K') write_version('0004040502021503') -- NTAG_I2C_2K 00 04 04 05 02 02 15 03 write_type('02') - + -- Setting NTAG I2C 2K default CC block456 - connect() + connect() send('a203e1106D00') send('a2040300fe00') - send('a20500000000') - elseif tagtype == 12 then + send('a20500000000') + elseif tagtype == 12 then print('Setting: NTAG 213F') write_version('0004040401000F03') -- NTAG213F 00 04 04 04 01 00 0f 03 write_type('00') - + -- Setting NTAG213 default CC block456 - connect() + connect() send('a203e1101200') send('a2040103a00c') send('a205340300fe') - -- setting cfg1/cfg2 + -- setting cfg1/cfg2 send('a229000000ff') send('a22a00050000') elseif tagtype == 13 then - print('Setting: NTAG 216F') + print('Setting: NTAG 216F') write_version('0004040401001303') -- NTAG216F 00 04 04 04 01 00 13 03 - write_type('02') - + write_type('02') + -- Setting NTAG216 default CC block456 - connect() + connect() send('a203e1106d00') send('a2040300fe00') send('a20500000000') - -- setting cfg1/cfg2 + -- setting cfg1/cfg2 send('a2e3000000ff') send('a2e400050000') end lib14a.disconnect() - if resp == '04' then + if resp == '04' then return nil, 'Failed to set type' else return true, 'Ok' - end + end end --- -- wipe tag @@ -546,15 +546,15 @@ local function wipe() local info = connect() if not info then return false, "Can't select card" end - + local err, msg, resp local cmd_empty = 'A2%02X00000000' local cmd_cfg1 = 'A2%02X000000FF' local cmd_cfg2 = 'A2%02X00050000' print('Wiping tag') - - for b = 3, 0xFB do + + for b = 3, 0xFB do --configuration block 0 if b == 0x29 or b == 0x83 or b == 0xe3 then local cmd = (cmd_cfg1):format(b) @@ -563,7 +563,7 @@ local function wipe() elseif b == 0x2a or b == 0x84 or b == 0xe4 then local cmd = (cmd_cfg2):format(b) resp = send(cmd) - else + else resp = send(cmd_empty:format(b)) end if resp == '04' or #resp == 0 then @@ -575,72 +575,72 @@ local function wipe() io.flush() end io.write('\r\n') - + lib14a.disconnect() - + if err then return nil, "Tag locked down, "..err_lock end - + print('setting default values...') - + set_password(nil) - + -- set NTAG213 default values err, msg = set_type(5) if err == nil then return err, msg end - + --set UID err, msg = write_uid('04112233445566') if err == nil then return err, msg end - + --set pwd err, msg = write_pwd('FFFFFFFF') if err == nil then return err, msg end - + --set pack - err, msg = write_pack('0000') - if err == nil then return err, msg end + err, msg = write_pack('0000') + if err == nil then return err, msg end return true, 'Ok' end ---- +--- -- The main entry point function main(args) print( string.rep('--',20) ) - print( string.rep('--',20) ) + print( string.rep('--',20) ) print() local err, msg - + if #args == 0 then return help() end - + -- Read the parameters for o, a in getopt.getopt(args, 'hck:u:t:p:a:s:o:v:w') do -- help if o == "h" then return help() end - --key + --key if o == 'k' then err, msg = set_password(a) end - + -- configuration if o == "c" then err, msg = read_config() end - + --wipe tag if o == "w" then err, msg = wipe() end - + -- write uid if o == "u" then err, msg = write_uid(a) end - -- write type/version + -- write type/version if o == "t" then err, msg = set_type(a) end - + -- write pwd if o == "p" then err, msg = write_pwd(a) end - + -- write pack if o == "a" then err, msg = write_pack(a) end - + -- write signature if o == "s" then err, msg = write_signature(a) end @@ -649,10 +649,10 @@ function main(args) -- write version if o == "v" then err, msg = write_version(a) end - + if err == nil then return oops(msg) end - end - + end + end main(args) From 1aefc4e05651ddd0aca68e70c817318f7ddafa02 Mon Sep 17 00:00:00 2001 From: "osboxes.org" Date: Tue, 31 Dec 2019 22:19:03 +0100 Subject: [PATCH 1320/1854] style --- client/scripting.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/scripting.c b/client/scripting.c index e531acd97..7ba38ee8b 100644 --- a/client/scripting.c +++ b/client/scripting.c @@ -314,7 +314,7 @@ static int l_GetFromFlashMemSpiffs(lua_State *L) { if (IfPm3Flash() == false) { return returnToLuaWithError(L, "No FLASH MEM support"); } - + uint32_t start_index = 0, len = 0x40000; //FLASH_MEM_MAX_SIZE char destfilename[32] = {0}; size_t size; From 911cfb9d3f35bfe0bba989cf579a81a6495a2ff1 Mon Sep 17 00:00:00 2001 From: "osboxes.org" Date: Tue, 31 Dec 2019 22:19:28 +0100 Subject: [PATCH 1321/1854] style --- common/iso15693tools.h | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/common/iso15693tools.h b/common/iso15693tools.h index 62ad85499..7c5380904 100644 --- a/common/iso15693tools.h +++ b/common/iso15693tools.h @@ -106,14 +106,14 @@ static const int Iso15693FrameSOF[] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - -1, -1, -1, -1, - -1, -1, -1, -1, - 1, 1, 1, 1, - 1, 1, 1, 1 - }; + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + -1, -1, -1, -1, + -1, -1, -1, -1, + 1, 1, 1, 1, + 1, 1, 1, 1 +}; static const int Iso15693Logic0[] = { 1, 1, 1, 1, 1, 1, 1, 1, @@ -122,10 +122,10 @@ static const int Iso15693Logic0[] = { }; static const int Iso15693Logic1[] = { -1, -1, -1, -1, - -1, -1, -1, -1, - 1, 1, 1, 1, - 1, 1, 1, 1 - }; + -1, -1, -1, -1, + 1, 1, 1, 1, + 1, 1, 1, 1 +}; // EOF defined as // 1) logic '0' (8 pulses of 423.75kHz followed by unmodulated for 18.88us) From 6293749ffd7c7f81a627f15a48ddd323cfa438f5 Mon Sep 17 00:00:00 2001 From: "osboxes.org" Date: Tue, 31 Dec 2019 22:19:54 +0100 Subject: [PATCH 1322/1854] style --- common_arm/usb_cdc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common_arm/usb_cdc.c b/common_arm/usb_cdc.c index dd8d2f7c4..b146715a1 100644 --- a/common_arm/usb_cdc.c +++ b/common_arm/usb_cdc.c @@ -573,7 +573,7 @@ bool usb_check() { if (isr & AT91C_UDP_ENDBUSRES) { pUdp->UDP_ICR = AT91C_UDP_ENDBUSRES; // reset all endpoints - pUdp->UDP_RSTEP = (unsigned int) -1; + pUdp->UDP_RSTEP = (unsigned int) - 1; pUdp->UDP_RSTEP = 0; // Enable the function pUdp->UDP_FADDR = AT91C_UDP_FEN; From 26fa587dbf5d5bd9e8e732578a1d951d73ec31fd Mon Sep 17 00:00:00 2001 From: "osboxes.org" Date: Tue, 31 Dec 2019 22:20:27 +0100 Subject: [PATCH 1323/1854] style --- common/zlib/inflate.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/common/zlib/inflate.c b/common/zlib/inflate.c index 0eb9ed787..adbe00146 100644 --- a/common/zlib/inflate.c +++ b/common/zlib/inflate.c @@ -1060,7 +1060,7 @@ int flush; last = here; for (;;) { here = state->lencode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; + (BITS(last.bits + last.op) >> last.bits)]; if ((unsigned)(last.bits + here.bits) <= bits) break; PULLBYTE(); } @@ -1110,7 +1110,7 @@ int flush; last = here; for (;;) { here = state->distcode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; + (BITS(last.bits + last.op) >> last.bits)]; if ((unsigned)(last.bits + here.bits) <= bits) break; PULLBYTE(); } @@ -1555,7 +1555,7 @@ unsigned long ZEXPORT inflateCodesUsed(strm) z_streamp strm; { struct inflate_state FAR *state; - if (inflateStateCheck(strm)) return (unsigned long) -1; + if (inflateStateCheck(strm)) return (unsigned long) - 1; state = (struct inflate_state FAR *)strm->state; return (unsigned long)(state->next - state->codes); } From eb1596dc9fea49c535607739aacd75bbda376ffc Mon Sep 17 00:00:00 2001 From: "osboxes.org" Date: Tue, 31 Dec 2019 22:22:03 +0100 Subject: [PATCH 1324/1854] style --- common/mbedtls/camellia.c | 16 ++++++++-------- common/mbedtls/x509_crt.c | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/common/mbedtls/camellia.c b/common/mbedtls/camellia.c index bb4169ab4..c0597d8fa 100644 --- a/common/mbedtls/camellia.c +++ b/common/mbedtls/camellia.c @@ -217,16 +217,16 @@ static const signed char indexes[2][4][20] = { }, /* KL -> RK */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 - }, /* KR -> RK */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 + }, /* KR -> RK */ { 4, 5, 6, 7, 12, 13, 14, 15, 16, 17, 18, 19, -1, 24, 25, -1, 31, 28, 29, 30 }, /* KA -> RK */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 - } /* KB -> RK */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 + } /* KB -> RK */ }, { { @@ -235,12 +235,12 @@ static const signed char indexes[2][4][20] = { }, /* KL -> RK */ { -1, -1, -1, -1, 8, 9, 10, 11, 16, 17, - 18, 19, -1, -1, -1, -1, 39, 36, 37, 38 - }, /* KR -> RK */ + 18, 19, -1, -1, -1, -1, 39, 36, 37, 38 + }, /* KR -> RK */ { -1, -1, -1, -1, 12, 13, 14, 15, 58, 59, - 56, 57, 31, 28, 29, 30, -1, -1, -1, -1 - }, /* KA -> RK */ + 56, 57, 31, 28, 29, 30, -1, -1, -1, -1 + }, /* KA -> RK */ { 4, 5, 6, 7, 65, 66, 67, 64, 20, 21, 22, 23, -1, -1, -1, -1, 43, 40, 41, 42 diff --git a/common/mbedtls/x509_crt.c b/common/mbedtls/x509_crt.c index de3e5ece8..9f8e64ed6 100644 --- a/common/mbedtls/x509_crt.c +++ b/common/mbedtls/x509_crt.c @@ -2223,7 +2223,7 @@ exit: ret = MBEDTLS_ERR_X509_FATAL_ERROR; if (ret != 0) { - *flags = (uint32_t) -1; + *flags = (uint32_t) - 1; return (ret); } From 33436ae2c2e807c85e967208f871e5323fe91ee4 Mon Sep 17 00:00:00 2001 From: "osboxes.org" Date: Tue, 31 Dec 2019 22:25:50 +0100 Subject: [PATCH 1325/1854] rmdir soft --- fpga/Makefile | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/fpga/Makefile b/fpga/Makefile index 06cdec2ee..8ea5d89f0 100644 --- a/fpga/Makefile +++ b/fpga/Makefile @@ -1,7 +1,15 @@ +# +# FPGA Makefile +# +RMDIR = rm -rf +# rmdir only if dir is empty, tolerate failure +RMDIR_SOFT = -rmdir +# all: fpga_lf.bit fpga_hf.bit clean: $(Q)$(RM) *.bgn *.drc *.ncd *.ngd *_par.xrpt *-placed.* *-placed_pad.* *_usage.xml xst_hf.srp xst_lf.srp - $(Q)$(RM) *.map *.ngc *.xrpt *.pcf *.rbt *_auto_* *.bld *.mrp *.ngm *.unroutes *_summary.xml netlist.lst xst + $(Q)$(RM) *.map *.ngc *.xrpt *.pcf *.rbt *.bld *.mrp *.ngm *.unroutes *_summary.xml netlist.lst + $(Q)$(RMDIR) *_auto_* xst fpga_hf.ngc: fpga_hf.v fpga.ucf xst_hf.scr util.v hi_simulate.v hi_read_tx.v hi_read_rx_xcorr.v hi_iso14443a.v hi_sniffer.v hi_flite.v $(Q)$(RM) $@ From b205833df4c2172d673fd76ae8dbb81fe5535a1d Mon Sep 17 00:00:00 2001 From: "osboxes.org" Date: Tue, 31 Dec 2019 22:30:59 +0100 Subject: [PATCH 1326/1854] style --- tools/pm3_cs8.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/pm3_cs8.pl b/tools/pm3_cs8.pl index 398e06f31..f1bfaf81d 100755 --- a/tools/pm3_cs8.pl +++ b/tools/pm3_cs8.pl @@ -63,4 +63,4 @@ sub run_rewrite my $ret = system(@run); die "Failed: $! ($ret)\ndo you have $run[0] installed?\n" if $ret; -} \ No newline at end of file +} From 7a22d334e27ab350b1f7d34065114928a575bfd8 Mon Sep 17 00:00:00 2001 From: "osboxes.org" Date: Tue, 31 Dec 2019 22:31:43 +0100 Subject: [PATCH 1327/1854] style --- armsrc/nprintf.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/armsrc/nprintf.c b/armsrc/nprintf.c index b61ad794d..f86406322 100644 --- a/armsrc/nprintf.c +++ b/armsrc/nprintf.c @@ -782,7 +782,7 @@ static int _vsnprintf(out_fct_type out, char *buffer, const size_t maxlen, const case 's' : { const char *p = va_arg(va, char *); - unsigned int l = _strnlen_s(p, precision ? precision : (size_t) -1); + unsigned int l = _strnlen_s(p, precision ? precision : (size_t) - 1); // pre padding if (flags & FLAGS_PRECISION) { l = (l < precision ? l : precision); @@ -849,7 +849,7 @@ int printf_(const char *format, ...) { va_list va; va_start(va, format); char buffer[1]; - const int ret = _vsnprintf(_out_char, buffer, (size_t) -1, format, va); + const int ret = _vsnprintf(_out_char, buffer, (size_t) - 1, format, va); va_end(va); return ret; } @@ -858,7 +858,7 @@ int printf_(const char *format, ...) { int sprintf_(char *buffer, const char *format, ...) { va_list va; va_start(va, format); - const int ret = _vsnprintf(_out_buffer, buffer, (size_t) -1, format, va); + const int ret = _vsnprintf(_out_buffer, buffer, (size_t) - 1, format, va); va_end(va); return ret; } @@ -875,7 +875,7 @@ int snprintf_(char *buffer, size_t count, const char *format, ...) { int vprintf_(const char *format, va_list va) { char buffer[1]; - return _vsnprintf(_out_char, buffer, (size_t) -1, format, va); + return _vsnprintf(_out_char, buffer, (size_t) - 1, format, va); } @@ -888,7 +888,7 @@ int fctprintf(void (*out)(char character, void *arg), void *arg, const char *for va_list va; va_start(va, format); const out_fct_wrap_type out_fct_wrap = { out, arg }; - const int ret = _vsnprintf(_out_fct, (char *)(uintptr_t)&out_fct_wrap, (size_t) -1, format, va); + const int ret = _vsnprintf(_out_fct, (char *)(uintptr_t)&out_fct_wrap, (size_t) - 1, format, va); va_end(va); return ret; } From aa33f8cc2f6605b7e6383c3e676f874ff1fe803f Mon Sep 17 00:00:00 2001 From: "osboxes.org" Date: Tue, 31 Dec 2019 22:32:12 +0100 Subject: [PATCH 1328/1854] style --- client/reveng/preset.c | 458 ++++++++++++++++++++--------------------- 1 file changed, 229 insertions(+), 229 deletions(-) diff --git a/client/reveng/preset.c b/client/reveng/preset.c index 6f41ac9f5..1897ebcee 100644 --- a/client/reveng/preset.c +++ b/client/reveng/preset.c @@ -137,19 +137,19 @@ static const bmp_t b40c[] = { # else /* BMP_BIT */ static const bmp_t b40[] = { BMP_C(0x00048200) << (BMP_BIT - 32) | BMP_C(0x04) >> (39 - BMP_BIT), - BMP_C(0x09) << (BMP_BIT * 2 - 40), + BMP_C(0x09) << (BMP_BIT * 2 - 40), }; static const bmp_t b40a[] = { BMP_C(0xffffffff) << (BMP_BIT - 32) | BMP_C(0x7f) >> (39 - BMP_BIT), - BMP_C(0xff) << (BMP_BIT * 2 - 40), + BMP_C(0xff) << (BMP_BIT * 2 - 40), }; static const bmp_t b40b[] = { BMP_C(0xd4164fc6) << (BMP_BIT - 32) | BMP_C(0x23) >> (39 - BMP_BIT), - BMP_C(0x46) << (BMP_BIT * 2 - 40), + BMP_C(0x46) << (BMP_BIT * 2 - 40), }; static const bmp_t b40c[] = { BMP_C(0xc4ff8071) << (BMP_BIT - 32) | BMP_C(0x7f) >> (39 - BMP_BIT), - BMP_C(0xff) << (BMP_BIT * 2 - 40), + BMP_C(0xff) << (BMP_BIT * 2 - 40), }; # endif /* BMP_BIT */ @@ -187,43 +187,43 @@ static const bmp_t b64i[] = { # else /* BMP_BIT */ static const bmp_t b64[] = { BMP_C(0x00000000) << (BMP_BIT - 32) | BMP_C(0x0000000d) >> (63 - BMP_BIT), - BMP_C(0x0000001b) << (BMP_BIT * 2 - 64), + BMP_C(0x0000001b) << (BMP_BIT * 2 - 64), }; static const bmp_t b64a[] = { BMP_C(0xffffffff) << (BMP_BIT - 32) | BMP_C(0x7fffffff) >> (63 - BMP_BIT), - BMP_C(0xffffffff) << (BMP_BIT * 2 - 64), + BMP_C(0xffffffff) << (BMP_BIT * 2 - 64), }; static const bmp_t b64b[] = { BMP_C(0xb90956c7) << (BMP_BIT - 32) | BMP_C(0x3ad20800) >> (63 - BMP_BIT), - BMP_C(0x75a41001) << (BMP_BIT * 2 - 64), + BMP_C(0x75a41001) << (BMP_BIT * 2 - 64), }; static const bmp_t b64c[] = { BMP_C(0x53000000) << (BMP_BIT - 32) | BMP_C(0x00000000) >> (63 - BMP_BIT), - BMP_C(0x00000000) << (BMP_BIT * 2 - 64), + BMP_C(0x00000000) << (BMP_BIT * 2 - 64), }; static const bmp_t b64d[] = { BMP_C(0x42f0e1eb) << (BMP_BIT - 32) | BMP_C(0x54f51b49) >> (63 - BMP_BIT), - BMP_C(0xa9ea3693) << (BMP_BIT * 2 - 64), + BMP_C(0xa9ea3693) << (BMP_BIT * 2 - 64), }; static const bmp_t b64e[] = { BMP_C(0x6c40df5f) << (BMP_BIT - 32) | BMP_C(0x05a4b9a3) >> (63 - BMP_BIT), - BMP_C(0x0b497347) << (BMP_BIT * 2 - 64), + BMP_C(0x0b497347) << (BMP_BIT * 2 - 64), }; static const bmp_t b64f[] = { BMP_C(0x62ec59e3) << (BMP_BIT - 32) | BMP_C(0x78d27805) >> (63 - BMP_BIT), - BMP_C(0xf1a4f00a) << (BMP_BIT * 2 - 64), + BMP_C(0xf1a4f00a) << (BMP_BIT * 2 - 64), }; static const bmp_t b64g[] = { BMP_C(0xfcacbebd) << (BMP_BIT - 32) | BMP_C(0x2c98d4c9) >> (63 - BMP_BIT), - BMP_C(0x5931a992) << (BMP_BIT * 2 - 64), + BMP_C(0x5931a992) << (BMP_BIT * 2 - 64), }; static const bmp_t b64h[] = { BMP_C(0x995dc9bb) << (BMP_BIT - 32) | BMP_C(0x6f8c9cfd) >> (63 - BMP_BIT), - BMP_C(0xdf1939fa) << (BMP_BIT * 2 - 64), + BMP_C(0xdf1939fa) << (BMP_BIT * 2 - 64), }; static const bmp_t b64i[] = { BMP_C(0x49958c9a) << (BMP_BIT - 32) | BMP_C(0x5ebe9a9f) >> (63 - BMP_BIT), - BMP_C(0xbd7d353f) << (BMP_BIT * 2 - 64), + BMP_C(0xbd7d353f) << (BMP_BIT * 2 - 64), }; # endif /* BMP_BIT */ @@ -237,22 +237,22 @@ static const bmp_t b82a[] = { # elif BMP_BIT >= 41 static const bmp_t b82[] = { BMP_C(0x01846008880) << (BMP_BIT - 41) | BMP_C(0x08a00a20208) >> (81 - BMP_BIT), - BMP_C(0x11401440411) << (BMP_BIT * 2 - 82), + BMP_C(0x11401440411) << (BMP_BIT * 2 - 82), }; static const bmp_t b82a[] = { BMP_C(0x04f541fb128) << (BMP_BIT - 41) | BMP_C(0x011c00feb09) >> (81 - BMP_BIT), - BMP_C(0x023801fd612) << (BMP_BIT * 2 - 82), + BMP_C(0x023801fd612) << (BMP_BIT * 2 - 82), }; # else /* BMP_BIT */ static const bmp_t b82[] = { BMP_C(0x0c230044) << (BMP_BIT - 32) | BMP_C(0x040) >> (40 - BMP_BIT), - BMP_C(0x40450051) << (BMP_BIT * 2 - 64) | BMP_C(0x00104) >> (80 - BMP_BIT * 2), - BMP_C(0x00411) << (BMP_BIT * 3 - 82), + BMP_C(0x40450051) << (BMP_BIT * 2 - 64) | BMP_C(0x00104) >> (80 - BMP_BIT * 2), + BMP_C(0x00411) << (BMP_BIT * 3 - 82), }; static const bmp_t b82a[] = { BMP_C(0x27aa0fd8) << (BMP_BIT - 32) | BMP_C(0x094) >> (40 - BMP_BIT), - BMP_C(0x9408e007) << (BMP_BIT * 2 - 64) | BMP_C(0x0f584) >> (80 - BMP_BIT * 2), - BMP_C(0x3d612) << (BMP_BIT * 3 - 82), + BMP_C(0x9408e007) << (BMP_BIT * 2 - 64) | BMP_C(0x0f584) >> (80 - BMP_BIT * 2), + BMP_C(0x3d612) << (BMP_BIT * 3 - 82), }; # endif /* BMP_BIT */ @@ -262,215 +262,215 @@ static const bmp_t b82a[] = { /* Array of the polynomial bitmaps used in the model table. */ static const bmp_t b32[] = { BMP_C(0x000000af) << (BMP_BIT - 32), /* 0 -- 32,000000af */ - BMP_C(0x00010000) << (BMP_BIT - 32), /* 1 -- 16, 0001 */ - BMP_C(0x00020000) << (BMP_BIT - 32), /* 2 -- 15, 0001 */ - BMP_C(0x00065b00) << (BMP_BIT - 32), /* 3 -- 24, 00065b */ - BMP_C(0x007e0000) << (BMP_BIT - 32), /* 4 -- 16, 007e */ - BMP_C(0x007f0000) << (BMP_BIT - 32), /* 5 -- 16, 007f */ - BMP_C(0x03400000) << (BMP_BIT - 32), /* 6 -- 11, 01a */ - BMP_C(0x0376e6e7) << (BMP_BIT - 32), /* 7 -- 32,0376e6e7 */ - BMP_C(0x04c11db7) << (BMP_BIT - 32), /* 8 -- 32,04c11db7 */ - BMP_C(0x05890000) << (BMP_BIT - 32), /* 9 -- 16, 0589 */ - BMP_C(0x07000000) << (BMP_BIT - 32), /* 10 -- 8, 07 */ - BMP_C(0x080b0000) << (BMP_BIT - 32), /* 11 -- 16, 080b */ - BMP_C(0x09823b6e) << (BMP_BIT - 32), /* 12 -- 31,04c11db7 */ - BMP_C(0x0b3c0000) << (BMP_BIT - 32), /* 13 -- 15, 059e */ - BMP_C(0x0c000000) << (BMP_BIT - 32), /* 14 -- 6, 03 */ - BMP_C(0x0c200000) << (BMP_BIT - 32), /* 15 -- 11, 061 */ - BMP_C(0x0c780000) << (BMP_BIT - 32), /* 16 -- 14, 031e */ - BMP_C(0x0fb30000) << (BMP_BIT - 32), /* 17 -- 16, 0fb3 */ - BMP_C(0x10210000) << (BMP_BIT - 32), /* 18 -- 16, 1021 */ - BMP_C(0x12000000) << (BMP_BIT - 32), /* 19 -- 7, 09 */ - BMP_C(0x130d2afc) << (BMP_BIT - 32), /* 20 -- 30,04c34abf */ - BMP_C(0x144e6300) << (BMP_BIT - 32), /* 21 -- 24, 144e63 */ - BMP_C(0x15000000) << (BMP_BIT - 32), /* 22 -- 8, 15 */ - BMP_C(0x1697d06a) << (BMP_BIT - 32), /* 23 -- 32,1697d06a */ - BMP_C(0x17800000) << (BMP_BIT - 32), /* 24 -- 12, 178 */ - BMP_C(0x18000000) << (BMP_BIT - 32), /* 25 -- 6, 06 */ - BMP_C(0x19d3c8d8) << (BMP_BIT - 32), /* 26 -- 31,0ce9e46c */ - BMP_C(0x1c000000) << (BMP_BIT - 32), /* 27 -- 6, 07 */ - BMP_C(0x1d000000) << (BMP_BIT - 32), /* 28 -- 8, 1d */ - BMP_C(0x1d0f0000) << (BMP_BIT - 32), /* 29 -- 16, 1d0f */ - BMP_C(0x1dcf0000) << (BMP_BIT - 32), /* 30 -- 16, 1dcf */ - BMP_C(0x1edc6f41) << (BMP_BIT - 32), /* 31 -- 32,1edc6f41 */ - BMP_C(0x1f23b800) << (BMP_BIT - 32), /* 32 -- 24, 1f23b8 */ - BMP_C(0x20000000) << (BMP_BIT - 32), /* 33 -- 4, 2 */ - BMP_C(0x200fa500) << (BMP_BIT - 32), /* 34 -- 24, 200fa5 */ - BMP_C(0x20140000) << (BMP_BIT - 32), /* 35 -- 14, 0805 */ - BMP_C(0x20b40000) << (BMP_BIT - 32), /* 36 -- 14, 082d */ - BMP_C(0x20fe0000) << (BMP_BIT - 32), /* 37 -- 16, 20fe */ - BMP_C(0x21890000) << (BMP_BIT - 32), /* 38 -- 16, 2189 */ - BMP_C(0x21cf0200) << (BMP_BIT - 32), /* 39 -- 24, 21cf02 */ - BMP_C(0x23ef5200) << (BMP_BIT - 32), /* 40 -- 24, 23ef52 */ - BMP_C(0x25000000) << (BMP_BIT - 32), /* 41 -- 8, 25 */ - BMP_C(0x26000000) << (BMP_BIT - 32), /* 42 -- 8, 26 */ - BMP_C(0x26b10000) << (BMP_BIT - 32), /* 43 -- 16, 26b1 */ - BMP_C(0x27818000) << (BMP_BIT - 32), /* 44 -- 17, 04f03 */ - BMP_C(0x27d00000) << (BMP_BIT - 32), /* 45 -- 13, 04fa */ - BMP_C(0x28000000) << (BMP_BIT - 32), /* 46 -- 5, 05 */ - BMP_C(0x29b10000) << (BMP_BIT - 32), /* 47 -- 16, 29b1 */ - BMP_C(0x2f000000) << (BMP_BIT - 32), /* 48 -- 8, 2f */ - BMP_C(0x30000000) << (BMP_BIT - 32), /* 49 -- 4, 3/ 5, 6 */ - BMP_C(0x3010bf7f) << (BMP_BIT - 32), /* 50 -- 32,3010bf7f */ - BMP_C(0x31000000) << (BMP_BIT - 32), /* 51 -- 8, 31 */ - BMP_C(0x31800000) << (BMP_BIT - 32), /* 52 -- 10, 0c6 */ - BMP_C(0x31c30000) << (BMP_BIT - 32), /* 53 -- 16, 31c3 */ - BMP_C(0x328b6300) << (BMP_BIT - 32), /* 54 -- 24, 328b63 */ - BMP_C(0x34000000) << (BMP_BIT - 32), /* 55 -- 6, 0d */ - BMP_C(0x340bc6d9) << (BMP_BIT - 32), /* 56 -- 32,340bc6d9 */ - BMP_C(0x37000000) << (BMP_BIT - 32), /* 57 -- 8, 37 */ - BMP_C(0x38000000) << (BMP_BIT - 32), /* 58 -- 5, 07 */ - BMP_C(0x39000000) << (BMP_BIT - 32), /* 59 -- 8, 39 */ - BMP_C(0x3d650000) << (BMP_BIT - 32), /* 60 -- 16, 3d65 */ - BMP_C(0x3e000000) << (BMP_BIT - 32), /* 61 -- 8, 3e */ - BMP_C(0x40000000) << (BMP_BIT - 32), /* 62 -- 3, 2 */ - BMP_C(0x42000000) << (BMP_BIT - 32), /* 63 -- 8, 42 */ - BMP_C(0x44c20000) << (BMP_BIT - 32), /* 64 -- 16, 44c2 */ - BMP_C(0x45270551) << (BMP_BIT - 32), /* 65 -- 32,45270551 */ - BMP_C(0x48000000) << (BMP_BIT - 32), /* 66 -- 5, 09 */ - BMP_C(0x49000000) << (BMP_BIT - 32), /* 67 -- 8, 49 */ - BMP_C(0x4a800000) << (BMP_BIT - 32), /* 68 -- 10, 12a */ - BMP_C(0x4acc0000) << (BMP_BIT - 32), /* 69 -- 15, 2566 */ - BMP_C(0x4b000000) << (BMP_BIT - 32), /* 70 -- 8, 4b */ - BMP_C(0x4b370000) << (BMP_BIT - 32), /* 71 -- 16, 4b37 */ - BMP_C(0x4c000000) << (BMP_BIT - 32), /* 72 -- 6, 13 */ - BMP_C(0x4c060000) << (BMP_BIT - 32), /* 73 -- 16, 4c06 */ - BMP_C(0x53000000) << (BMP_BIT - 32), /* 74 -- 8, 53 */ - BMP_C(0x55000000) << (BMP_BIT - 32), /* 75 -- 8, 55 */ - BMP_C(0x55555500) << (BMP_BIT - 32), /* 76 -- 24, 555555 */ - BMP_C(0x59350000) << (BMP_BIT - 32), /* 77 -- 16, 5935 */ - BMP_C(0x5d380000) << (BMP_BIT - 32), /* 78 -- 16, 5d38 */ - BMP_C(0x5d400000) << (BMP_BIT - 32), /* 79 -- 10, 175 */ - BMP_C(0x5d6dcb00) << (BMP_BIT - 32), /* 80 -- 24, 5d6dcb */ - BMP_C(0x60000000) << (BMP_BIT - 32), /* 81 -- 3, 3 */ - BMP_C(0x60e00000) << (BMP_BIT - 32), /* 82 -- 11, 307 */ - BMP_C(0x63d00000) << (BMP_BIT - 32), /* 83 -- 16, 63d0 */ - BMP_C(0x64000000) << (BMP_BIT - 32), /* 84 -- 6, 19 */ - BMP_C(0x66400000) << (BMP_BIT - 32), /* 85 -- 10, 199 */ - BMP_C(0x66c50000) << (BMP_BIT - 32), /* 86 -- 16, 66c5 */ - BMP_C(0x6f630000) << (BMP_BIT - 32), /* 87 -- 16, 6f63 */ - BMP_C(0x6f910000) << (BMP_BIT - 32), /* 88 -- 16, 6f91 */ - BMP_C(0x70000000) << (BMP_BIT - 32), /* 89 -- 4, 7 */ - BMP_C(0x70a00000) << (BMP_BIT - 32), /* 90 -- 11, 385 */ - BMP_C(0x755b0000) << (BMP_BIT - 32), /* 91 -- 16, 755b */ - BMP_C(0x765e7680) << (BMP_BIT - 32), /* 92 -- 32,765e7680 */ - BMP_C(0x76c20800) << (BMP_BIT - 32), /* 93 -- 32, 0ed841 */ - BMP_C(0x7979bd00) << (BMP_BIT - 32), /* 94 -- 24, 7979bd */ - BMP_C(0x7e000000) << (BMP_BIT - 32), /* 95 -- 8, 7e */ - BMP_C(0x80000000) << (BMP_BIT - 32), /* 96 -- 3, 4 */ - BMP_C(0x80006300) << (BMP_BIT - 32), /* 97 -- 24, 800063 */ - BMP_C(0x80050000) << (BMP_BIT - 32), /* 98 -- 16, 8005 */ - BMP_C(0x800d0000) << (BMP_BIT - 32), /* 99 -- 16, 800d */ - BMP_C(0x800fe300) << (BMP_BIT - 32), /* 100 -- 24, 800fe3 */ - BMP_C(0x80b40000) << (BMP_BIT - 32), /* 101 -- 14, 202d */ - BMP_C(0x80c2e71c) << (BMP_BIT - 32), /* 102 -- 30,2030b9c7 */ - BMP_C(0x80f00000) << (BMP_BIT - 32), /* 103 -- 12, 80f */ - BMP_C(0x814141ab) << (BMP_BIT - 32), /* 104 -- 32,814141ab */ - BMP_C(0x8144c800) << (BMP_BIT - 32), /* 105 -- 21, 102899 */ - BMP_C(0x864cfb00) << (BMP_BIT - 32), /* 106 -- 24, 864cfb */ - BMP_C(0x87315576) << (BMP_BIT - 32), /* 107 -- 32,87315576 */ - BMP_C(0x89ec0000) << (BMP_BIT - 32), /* 108 -- 16, 89ec */ - BMP_C(0x8a000000) << (BMP_BIT - 32), /* 109 -- 7, 45 */ - BMP_C(0x8b320000) << (BMP_BIT - 32), /* 110 -- 15, 4599 */ - BMP_C(0x8bb70000) << (BMP_BIT - 32), /* 111 -- 16, 8bb7 */ - BMP_C(0x8cc00000) << (BMP_BIT - 32), /* 112 -- 10, 233 */ - BMP_C(0x904cddbf) << (BMP_BIT - 32), /* 113 -- 32,904cddbf */ - BMP_C(0x906e0000) << (BMP_BIT - 32), /* 114 -- 16, 906e */ - BMP_C(0x94000000) << (BMP_BIT - 32), /* 115 -- 8, 94 */ - BMP_C(0x97000000) << (BMP_BIT - 32), /* 116 -- 8, 97 */ - BMP_C(0x98000000) << (BMP_BIT - 32), /* 117 -- 6, 26 */ - BMP_C(0x99000000) << (BMP_BIT - 32), /* 118 -- 8, 99 */ - BMP_C(0x9b000000) << (BMP_BIT - 32), /* 119 -- 8, 9b */ - BMP_C(0x9c000000) << (BMP_BIT - 32), /* 120 -- 6, 27 */ - BMP_C(0x9d5e4de2) << (BMP_BIT - 32), /* 121 -- 31,4eaf26f1 */ - BMP_C(0x9e000000) << (BMP_BIT - 32), /* 122 -- 7, 4f */ - BMP_C(0x9ecf0000) << (BMP_BIT - 32), /* 123 -- 16, 9ecf */ - BMP_C(0xa0660000) << (BMP_BIT - 32), /* 124 -- 16, a066 */ - BMP_C(0xa0970000) << (BMP_BIT - 32), /* 125 -- 16, a097 */ - BMP_C(0xa1000000) << (BMP_BIT - 32), /* 126 -- 8, a1 */ - BMP_C(0xa3660000) << (BMP_BIT - 32), /* 127 -- 16, a366 */ - BMP_C(0xa6000000) << (BMP_BIT - 32), /* 128 -- 7, 53 */ - BMP_C(0xa7000000) << (BMP_BIT - 32), /* 129 -- 8, a7 */ - BMP_C(0xa8000000) << (BMP_BIT - 32), /* 130 -- 5, 15 */ - BMP_C(0xa8190000) << (BMP_BIT - 32), /* 131 -- 16, a819 */ - BMP_C(0xa833982b) << (BMP_BIT - 32), /* 132 -- 32,a833982b */ - BMP_C(0xabcdef00) << (BMP_BIT - 32), /* 133 -- 24, abcdef */ - BMP_C(0xac000000) << (BMP_BIT - 32), /* 134 -- 8, ac */ - BMP_C(0xaee70000) << (BMP_BIT - 32), /* 135 -- 16, aee7 */ - BMP_C(0xb0000000) << (BMP_BIT - 32), /* 136 -- 4, b */ - BMP_C(0xb0010000) << (BMP_BIT - 32), /* 137 -- 16, b001 */ - BMP_C(0xb2aa0000) << (BMP_BIT - 32), /* 138 -- 16, b2aa */ - BMP_C(0xb3400000) << (BMP_BIT - 32), /* 139 -- 12, b34 */ - BMP_C(0xb42d8000) << (BMP_BIT - 32), /* 140 -- 17, 1685b */ - BMP_C(0xb4600000) << (BMP_BIT - 32), /* 141 -- 11, 5a3 */ - BMP_C(0xb4c80000) << (BMP_BIT - 32), /* 142 -- 16, b4c8 */ - BMP_C(0xb4f3e600) << (BMP_BIT - 32), /* 143 -- 24, b4f3e6 */ - BMP_C(0xb704ce00) << (BMP_BIT - 32), /* 144 -- 24, b704ce */ - BMP_C(0xb798b438) << (BMP_BIT - 32), /* 145 -- 32,b798b438 */ - BMP_C(0xbb3d0000) << (BMP_BIT - 32), /* 146 -- 16, bb3d */ - BMP_C(0xbc000000) << (BMP_BIT - 32), /* 147 -- 6,2f/ 8,bc */ - BMP_C(0xbd0be338) << (BMP_BIT - 32), /* 148 -- 32,bd0be338 */ - BMP_C(0xbdf40000) << (BMP_BIT - 32), /* 149 -- 16, bdf4 */ - BMP_C(0xbf050000) << (BMP_BIT - 32), /* 150 -- 16, bf05 */ - BMP_C(0xc0000000) << (BMP_BIT - 32), /* 151 -- 3, 6 */ - BMP_C(0xc2000000) << (BMP_BIT - 32), /* 152 -- 7, 61 */ - BMP_C(0xc25a5600) << (BMP_BIT - 32), /* 153 -- 24, c25a56 */ - BMP_C(0xc2b70000) << (BMP_BIT - 32), /* 154 -- 16, c2b7 */ - BMP_C(0xc2b80000) << (BMP_BIT - 32), /* 155 -- 14, 30ae */ - BMP_C(0xc4000000) << (BMP_BIT - 32), /* 156 -- 8, c4 */ - BMP_C(0xc6c60000) << (BMP_BIT - 32), /* 157 -- 16, c6c6 */ - BMP_C(0xc7000000) << (BMP_BIT - 32), /* 158 -- 8, c7 */ - BMP_C(0xc704dd7b) << (BMP_BIT - 32), /* 159 -- 32,c704dd7b */ - BMP_C(0xc8000000) << (BMP_BIT - 32), /* 160 -- 5, 19 */ - BMP_C(0xc8670000) << (BMP_BIT - 32), /* 161 -- 16, c867 */ - BMP_C(0xcbf43926) << (BMP_BIT - 32), /* 162 -- 32,cbf43926 */ - BMP_C(0xcde70300) << (BMP_BIT - 32), /* 163 -- 24, cde703 */ - BMP_C(0xce3c0000) << (BMP_BIT - 32), /* 164 -- 16, ce3c */ - BMP_C(0xd0000000) << (BMP_BIT - 32), /* 165 -- 8, d0 */ - BMP_C(0xd02a0000) << (BMP_BIT - 32), /* 166 -- 15, 6815 */ - BMP_C(0xd0db0000) << (BMP_BIT - 32), /* 167 -- 16, d0db */ - BMP_C(0xd3100000) << (BMP_BIT - 32), /* 168 -- 12, d31 */ - BMP_C(0xd3be9568) << (BMP_BIT - 32), /* 169 -- 30,34efa55a */ - BMP_C(0xd4d00000) << (BMP_BIT - 32), /* 170 -- 12, d4d */ - BMP_C(0xd5000000) << (BMP_BIT - 32), /* 171 -- 8, d5 */ - BMP_C(0xd64e0000) << (BMP_BIT - 32), /* 172 -- 16, d64e */ - BMP_C(0xda000000) << (BMP_BIT - 32), /* 173 -- 8, da */ - BMP_C(0xdaf00000) << (BMP_BIT - 32), /* 174 -- 12, daf */ - BMP_C(0xdebb20e3) << (BMP_BIT - 32), /* 175 -- 32,debb20e3 */ - BMP_C(0xdf000000) << (BMP_BIT - 32), /* 176 -- 8, df */ - BMP_C(0xe0000000) << (BMP_BIT - 32), /* 177 -- 3, 7 */ - BMP_C(0xe3069283) << (BMP_BIT - 32), /* 178 -- 32,e3069283 */ - BMP_C(0xe3940000) << (BMP_BIT - 32), /* 179 -- 16, e394 */ - BMP_C(0xe5cc0000) << (BMP_BIT - 32), /* 180 -- 16, e5cc */ - BMP_C(0xe7a80000) << (BMP_BIT - 32), /* 181 -- 13, 1cf5 */ - BMP_C(0xe8000000) << (BMP_BIT - 32), /* 182 -- 6, 3a */ - BMP_C(0xea000000) << (BMP_BIT - 32), /* 183 -- 7, 75 */ - BMP_C(0xea820000) << (BMP_BIT - 32), /* 184 -- 16, ea82 */ - BMP_C(0xec000000) << (BMP_BIT - 32), /* 185 -- 6, 3b */ - BMP_C(0xf0000000) << (BMP_BIT - 32), /* 186 -- 4, f */ - BMP_C(0xf0b80000) << (BMP_BIT - 32), /* 187 -- 16, f0b8 */ - BMP_C(0xf1300000) << (BMP_BIT - 32), /* 188 -- 12, f13 */ - BMP_C(0xf4000000) << (BMP_BIT - 32), /* 189 -- 8, f4 */ - BMP_C(0xf4acfb13) << (BMP_BIT - 32), /* 190 -- 32,f4acfb13 */ - BMP_C(0xf5b00000) << (BMP_BIT - 32), /* 191 -- 12, f5b */ - BMP_C(0xf6400000) << (BMP_BIT - 32), /* 192 -- 10, 3d9 */ - BMP_C(0xf7000000) << (BMP_BIT - 32), /* 193 -- 8, f7 */ - BMP_C(0xf8000000) << (BMP_BIT - 32), /* 194 -- 5, 1f */ - BMP_C(0xfc000000) << (BMP_BIT - 32), /* 195 -- 6, 3f */ - BMP_C(0xfc891918) << (BMP_BIT - 32), /* 196 -- 32,fc891918 */ - BMP_C(0xfd000000) << (BMP_BIT - 32), /* 197 -- 8, fd */ - BMP_C(0xfe000000) << (BMP_BIT - 32), /* 198 -- 7, 7f */ - BMP_C(0xfedcba00) << (BMP_BIT - 32), /* 199 -- 24, fedcba */ - BMP_C(0xfee80000) << (BMP_BIT - 32), /* 200 -- 16, fee8 */ - BMP_C(0xff000000) << (BMP_BIT - 32), /* 201 -- 8, ff */ - BMP_C(0xffc00000) << (BMP_BIT - 32), /* 202 -- 10, 3ff */ - BMP_C(0xfff00000) << (BMP_BIT - 32), /* 203 -- 12, fff */ - BMP_C(0xfffc0000) << (BMP_BIT - 32), /* 204 -- 14, 3fff */ - BMP_C(0xffff0000) << (BMP_BIT - 32), /* 205 -- 16, ffff */ - BMP_C(0xffffff00) << (BMP_BIT - 32), /* 206 -- 24, ffffff */ - BMP_C(0xfffffffc) << (BMP_BIT - 32), /* 207 -- 30,3fffffff */ - BMP_C(0xfffffffe) << (BMP_BIT - 32), /* 208 -- 31,7fffffff */ - BMP_C(0xffffffff) << (BMP_BIT - 32), /* 209 -- 32,ffffffff */ + BMP_C(0x00010000) << (BMP_BIT - 32), /* 1 -- 16, 0001 */ + BMP_C(0x00020000) << (BMP_BIT - 32), /* 2 -- 15, 0001 */ + BMP_C(0x00065b00) << (BMP_BIT - 32), /* 3 -- 24, 00065b */ + BMP_C(0x007e0000) << (BMP_BIT - 32), /* 4 -- 16, 007e */ + BMP_C(0x007f0000) << (BMP_BIT - 32), /* 5 -- 16, 007f */ + BMP_C(0x03400000) << (BMP_BIT - 32), /* 6 -- 11, 01a */ + BMP_C(0x0376e6e7) << (BMP_BIT - 32), /* 7 -- 32,0376e6e7 */ + BMP_C(0x04c11db7) << (BMP_BIT - 32), /* 8 -- 32,04c11db7 */ + BMP_C(0x05890000) << (BMP_BIT - 32), /* 9 -- 16, 0589 */ + BMP_C(0x07000000) << (BMP_BIT - 32), /* 10 -- 8, 07 */ + BMP_C(0x080b0000) << (BMP_BIT - 32), /* 11 -- 16, 080b */ + BMP_C(0x09823b6e) << (BMP_BIT - 32), /* 12 -- 31,04c11db7 */ + BMP_C(0x0b3c0000) << (BMP_BIT - 32), /* 13 -- 15, 059e */ + BMP_C(0x0c000000) << (BMP_BIT - 32), /* 14 -- 6, 03 */ + BMP_C(0x0c200000) << (BMP_BIT - 32), /* 15 -- 11, 061 */ + BMP_C(0x0c780000) << (BMP_BIT - 32), /* 16 -- 14, 031e */ + BMP_C(0x0fb30000) << (BMP_BIT - 32), /* 17 -- 16, 0fb3 */ + BMP_C(0x10210000) << (BMP_BIT - 32), /* 18 -- 16, 1021 */ + BMP_C(0x12000000) << (BMP_BIT - 32), /* 19 -- 7, 09 */ + BMP_C(0x130d2afc) << (BMP_BIT - 32), /* 20 -- 30,04c34abf */ + BMP_C(0x144e6300) << (BMP_BIT - 32), /* 21 -- 24, 144e63 */ + BMP_C(0x15000000) << (BMP_BIT - 32), /* 22 -- 8, 15 */ + BMP_C(0x1697d06a) << (BMP_BIT - 32), /* 23 -- 32,1697d06a */ + BMP_C(0x17800000) << (BMP_BIT - 32), /* 24 -- 12, 178 */ + BMP_C(0x18000000) << (BMP_BIT - 32), /* 25 -- 6, 06 */ + BMP_C(0x19d3c8d8) << (BMP_BIT - 32), /* 26 -- 31,0ce9e46c */ + BMP_C(0x1c000000) << (BMP_BIT - 32), /* 27 -- 6, 07 */ + BMP_C(0x1d000000) << (BMP_BIT - 32), /* 28 -- 8, 1d */ + BMP_C(0x1d0f0000) << (BMP_BIT - 32), /* 29 -- 16, 1d0f */ + BMP_C(0x1dcf0000) << (BMP_BIT - 32), /* 30 -- 16, 1dcf */ + BMP_C(0x1edc6f41) << (BMP_BIT - 32), /* 31 -- 32,1edc6f41 */ + BMP_C(0x1f23b800) << (BMP_BIT - 32), /* 32 -- 24, 1f23b8 */ + BMP_C(0x20000000) << (BMP_BIT - 32), /* 33 -- 4, 2 */ + BMP_C(0x200fa500) << (BMP_BIT - 32), /* 34 -- 24, 200fa5 */ + BMP_C(0x20140000) << (BMP_BIT - 32), /* 35 -- 14, 0805 */ + BMP_C(0x20b40000) << (BMP_BIT - 32), /* 36 -- 14, 082d */ + BMP_C(0x20fe0000) << (BMP_BIT - 32), /* 37 -- 16, 20fe */ + BMP_C(0x21890000) << (BMP_BIT - 32), /* 38 -- 16, 2189 */ + BMP_C(0x21cf0200) << (BMP_BIT - 32), /* 39 -- 24, 21cf02 */ + BMP_C(0x23ef5200) << (BMP_BIT - 32), /* 40 -- 24, 23ef52 */ + BMP_C(0x25000000) << (BMP_BIT - 32), /* 41 -- 8, 25 */ + BMP_C(0x26000000) << (BMP_BIT - 32), /* 42 -- 8, 26 */ + BMP_C(0x26b10000) << (BMP_BIT - 32), /* 43 -- 16, 26b1 */ + BMP_C(0x27818000) << (BMP_BIT - 32), /* 44 -- 17, 04f03 */ + BMP_C(0x27d00000) << (BMP_BIT - 32), /* 45 -- 13, 04fa */ + BMP_C(0x28000000) << (BMP_BIT - 32), /* 46 -- 5, 05 */ + BMP_C(0x29b10000) << (BMP_BIT - 32), /* 47 -- 16, 29b1 */ + BMP_C(0x2f000000) << (BMP_BIT - 32), /* 48 -- 8, 2f */ + BMP_C(0x30000000) << (BMP_BIT - 32), /* 49 -- 4, 3/ 5, 6 */ + BMP_C(0x3010bf7f) << (BMP_BIT - 32), /* 50 -- 32,3010bf7f */ + BMP_C(0x31000000) << (BMP_BIT - 32), /* 51 -- 8, 31 */ + BMP_C(0x31800000) << (BMP_BIT - 32), /* 52 -- 10, 0c6 */ + BMP_C(0x31c30000) << (BMP_BIT - 32), /* 53 -- 16, 31c3 */ + BMP_C(0x328b6300) << (BMP_BIT - 32), /* 54 -- 24, 328b63 */ + BMP_C(0x34000000) << (BMP_BIT - 32), /* 55 -- 6, 0d */ + BMP_C(0x340bc6d9) << (BMP_BIT - 32), /* 56 -- 32,340bc6d9 */ + BMP_C(0x37000000) << (BMP_BIT - 32), /* 57 -- 8, 37 */ + BMP_C(0x38000000) << (BMP_BIT - 32), /* 58 -- 5, 07 */ + BMP_C(0x39000000) << (BMP_BIT - 32), /* 59 -- 8, 39 */ + BMP_C(0x3d650000) << (BMP_BIT - 32), /* 60 -- 16, 3d65 */ + BMP_C(0x3e000000) << (BMP_BIT - 32), /* 61 -- 8, 3e */ + BMP_C(0x40000000) << (BMP_BIT - 32), /* 62 -- 3, 2 */ + BMP_C(0x42000000) << (BMP_BIT - 32), /* 63 -- 8, 42 */ + BMP_C(0x44c20000) << (BMP_BIT - 32), /* 64 -- 16, 44c2 */ + BMP_C(0x45270551) << (BMP_BIT - 32), /* 65 -- 32,45270551 */ + BMP_C(0x48000000) << (BMP_BIT - 32), /* 66 -- 5, 09 */ + BMP_C(0x49000000) << (BMP_BIT - 32), /* 67 -- 8, 49 */ + BMP_C(0x4a800000) << (BMP_BIT - 32), /* 68 -- 10, 12a */ + BMP_C(0x4acc0000) << (BMP_BIT - 32), /* 69 -- 15, 2566 */ + BMP_C(0x4b000000) << (BMP_BIT - 32), /* 70 -- 8, 4b */ + BMP_C(0x4b370000) << (BMP_BIT - 32), /* 71 -- 16, 4b37 */ + BMP_C(0x4c000000) << (BMP_BIT - 32), /* 72 -- 6, 13 */ + BMP_C(0x4c060000) << (BMP_BIT - 32), /* 73 -- 16, 4c06 */ + BMP_C(0x53000000) << (BMP_BIT - 32), /* 74 -- 8, 53 */ + BMP_C(0x55000000) << (BMP_BIT - 32), /* 75 -- 8, 55 */ + BMP_C(0x55555500) << (BMP_BIT - 32), /* 76 -- 24, 555555 */ + BMP_C(0x59350000) << (BMP_BIT - 32), /* 77 -- 16, 5935 */ + BMP_C(0x5d380000) << (BMP_BIT - 32), /* 78 -- 16, 5d38 */ + BMP_C(0x5d400000) << (BMP_BIT - 32), /* 79 -- 10, 175 */ + BMP_C(0x5d6dcb00) << (BMP_BIT - 32), /* 80 -- 24, 5d6dcb */ + BMP_C(0x60000000) << (BMP_BIT - 32), /* 81 -- 3, 3 */ + BMP_C(0x60e00000) << (BMP_BIT - 32), /* 82 -- 11, 307 */ + BMP_C(0x63d00000) << (BMP_BIT - 32), /* 83 -- 16, 63d0 */ + BMP_C(0x64000000) << (BMP_BIT - 32), /* 84 -- 6, 19 */ + BMP_C(0x66400000) << (BMP_BIT - 32), /* 85 -- 10, 199 */ + BMP_C(0x66c50000) << (BMP_BIT - 32), /* 86 -- 16, 66c5 */ + BMP_C(0x6f630000) << (BMP_BIT - 32), /* 87 -- 16, 6f63 */ + BMP_C(0x6f910000) << (BMP_BIT - 32), /* 88 -- 16, 6f91 */ + BMP_C(0x70000000) << (BMP_BIT - 32), /* 89 -- 4, 7 */ + BMP_C(0x70a00000) << (BMP_BIT - 32), /* 90 -- 11, 385 */ + BMP_C(0x755b0000) << (BMP_BIT - 32), /* 91 -- 16, 755b */ + BMP_C(0x765e7680) << (BMP_BIT - 32), /* 92 -- 32,765e7680 */ + BMP_C(0x76c20800) << (BMP_BIT - 32), /* 93 -- 32, 0ed841 */ + BMP_C(0x7979bd00) << (BMP_BIT - 32), /* 94 -- 24, 7979bd */ + BMP_C(0x7e000000) << (BMP_BIT - 32), /* 95 -- 8, 7e */ + BMP_C(0x80000000) << (BMP_BIT - 32), /* 96 -- 3, 4 */ + BMP_C(0x80006300) << (BMP_BIT - 32), /* 97 -- 24, 800063 */ + BMP_C(0x80050000) << (BMP_BIT - 32), /* 98 -- 16, 8005 */ + BMP_C(0x800d0000) << (BMP_BIT - 32), /* 99 -- 16, 800d */ + BMP_C(0x800fe300) << (BMP_BIT - 32), /* 100 -- 24, 800fe3 */ + BMP_C(0x80b40000) << (BMP_BIT - 32), /* 101 -- 14, 202d */ + BMP_C(0x80c2e71c) << (BMP_BIT - 32), /* 102 -- 30,2030b9c7 */ + BMP_C(0x80f00000) << (BMP_BIT - 32), /* 103 -- 12, 80f */ + BMP_C(0x814141ab) << (BMP_BIT - 32), /* 104 -- 32,814141ab */ + BMP_C(0x8144c800) << (BMP_BIT - 32), /* 105 -- 21, 102899 */ + BMP_C(0x864cfb00) << (BMP_BIT - 32), /* 106 -- 24, 864cfb */ + BMP_C(0x87315576) << (BMP_BIT - 32), /* 107 -- 32,87315576 */ + BMP_C(0x89ec0000) << (BMP_BIT - 32), /* 108 -- 16, 89ec */ + BMP_C(0x8a000000) << (BMP_BIT - 32), /* 109 -- 7, 45 */ + BMP_C(0x8b320000) << (BMP_BIT - 32), /* 110 -- 15, 4599 */ + BMP_C(0x8bb70000) << (BMP_BIT - 32), /* 111 -- 16, 8bb7 */ + BMP_C(0x8cc00000) << (BMP_BIT - 32), /* 112 -- 10, 233 */ + BMP_C(0x904cddbf) << (BMP_BIT - 32), /* 113 -- 32,904cddbf */ + BMP_C(0x906e0000) << (BMP_BIT - 32), /* 114 -- 16, 906e */ + BMP_C(0x94000000) << (BMP_BIT - 32), /* 115 -- 8, 94 */ + BMP_C(0x97000000) << (BMP_BIT - 32), /* 116 -- 8, 97 */ + BMP_C(0x98000000) << (BMP_BIT - 32), /* 117 -- 6, 26 */ + BMP_C(0x99000000) << (BMP_BIT - 32), /* 118 -- 8, 99 */ + BMP_C(0x9b000000) << (BMP_BIT - 32), /* 119 -- 8, 9b */ + BMP_C(0x9c000000) << (BMP_BIT - 32), /* 120 -- 6, 27 */ + BMP_C(0x9d5e4de2) << (BMP_BIT - 32), /* 121 -- 31,4eaf26f1 */ + BMP_C(0x9e000000) << (BMP_BIT - 32), /* 122 -- 7, 4f */ + BMP_C(0x9ecf0000) << (BMP_BIT - 32), /* 123 -- 16, 9ecf */ + BMP_C(0xa0660000) << (BMP_BIT - 32), /* 124 -- 16, a066 */ + BMP_C(0xa0970000) << (BMP_BIT - 32), /* 125 -- 16, a097 */ + BMP_C(0xa1000000) << (BMP_BIT - 32), /* 126 -- 8, a1 */ + BMP_C(0xa3660000) << (BMP_BIT - 32), /* 127 -- 16, a366 */ + BMP_C(0xa6000000) << (BMP_BIT - 32), /* 128 -- 7, 53 */ + BMP_C(0xa7000000) << (BMP_BIT - 32), /* 129 -- 8, a7 */ + BMP_C(0xa8000000) << (BMP_BIT - 32), /* 130 -- 5, 15 */ + BMP_C(0xa8190000) << (BMP_BIT - 32), /* 131 -- 16, a819 */ + BMP_C(0xa833982b) << (BMP_BIT - 32), /* 132 -- 32,a833982b */ + BMP_C(0xabcdef00) << (BMP_BIT - 32), /* 133 -- 24, abcdef */ + BMP_C(0xac000000) << (BMP_BIT - 32), /* 134 -- 8, ac */ + BMP_C(0xaee70000) << (BMP_BIT - 32), /* 135 -- 16, aee7 */ + BMP_C(0xb0000000) << (BMP_BIT - 32), /* 136 -- 4, b */ + BMP_C(0xb0010000) << (BMP_BIT - 32), /* 137 -- 16, b001 */ + BMP_C(0xb2aa0000) << (BMP_BIT - 32), /* 138 -- 16, b2aa */ + BMP_C(0xb3400000) << (BMP_BIT - 32), /* 139 -- 12, b34 */ + BMP_C(0xb42d8000) << (BMP_BIT - 32), /* 140 -- 17, 1685b */ + BMP_C(0xb4600000) << (BMP_BIT - 32), /* 141 -- 11, 5a3 */ + BMP_C(0xb4c80000) << (BMP_BIT - 32), /* 142 -- 16, b4c8 */ + BMP_C(0xb4f3e600) << (BMP_BIT - 32), /* 143 -- 24, b4f3e6 */ + BMP_C(0xb704ce00) << (BMP_BIT - 32), /* 144 -- 24, b704ce */ + BMP_C(0xb798b438) << (BMP_BIT - 32), /* 145 -- 32,b798b438 */ + BMP_C(0xbb3d0000) << (BMP_BIT - 32), /* 146 -- 16, bb3d */ + BMP_C(0xbc000000) << (BMP_BIT - 32), /* 147 -- 6,2f/ 8,bc */ + BMP_C(0xbd0be338) << (BMP_BIT - 32), /* 148 -- 32,bd0be338 */ + BMP_C(0xbdf40000) << (BMP_BIT - 32), /* 149 -- 16, bdf4 */ + BMP_C(0xbf050000) << (BMP_BIT - 32), /* 150 -- 16, bf05 */ + BMP_C(0xc0000000) << (BMP_BIT - 32), /* 151 -- 3, 6 */ + BMP_C(0xc2000000) << (BMP_BIT - 32), /* 152 -- 7, 61 */ + BMP_C(0xc25a5600) << (BMP_BIT - 32), /* 153 -- 24, c25a56 */ + BMP_C(0xc2b70000) << (BMP_BIT - 32), /* 154 -- 16, c2b7 */ + BMP_C(0xc2b80000) << (BMP_BIT - 32), /* 155 -- 14, 30ae */ + BMP_C(0xc4000000) << (BMP_BIT - 32), /* 156 -- 8, c4 */ + BMP_C(0xc6c60000) << (BMP_BIT - 32), /* 157 -- 16, c6c6 */ + BMP_C(0xc7000000) << (BMP_BIT - 32), /* 158 -- 8, c7 */ + BMP_C(0xc704dd7b) << (BMP_BIT - 32), /* 159 -- 32,c704dd7b */ + BMP_C(0xc8000000) << (BMP_BIT - 32), /* 160 -- 5, 19 */ + BMP_C(0xc8670000) << (BMP_BIT - 32), /* 161 -- 16, c867 */ + BMP_C(0xcbf43926) << (BMP_BIT - 32), /* 162 -- 32,cbf43926 */ + BMP_C(0xcde70300) << (BMP_BIT - 32), /* 163 -- 24, cde703 */ + BMP_C(0xce3c0000) << (BMP_BIT - 32), /* 164 -- 16, ce3c */ + BMP_C(0xd0000000) << (BMP_BIT - 32), /* 165 -- 8, d0 */ + BMP_C(0xd02a0000) << (BMP_BIT - 32), /* 166 -- 15, 6815 */ + BMP_C(0xd0db0000) << (BMP_BIT - 32), /* 167 -- 16, d0db */ + BMP_C(0xd3100000) << (BMP_BIT - 32), /* 168 -- 12, d31 */ + BMP_C(0xd3be9568) << (BMP_BIT - 32), /* 169 -- 30,34efa55a */ + BMP_C(0xd4d00000) << (BMP_BIT - 32), /* 170 -- 12, d4d */ + BMP_C(0xd5000000) << (BMP_BIT - 32), /* 171 -- 8, d5 */ + BMP_C(0xd64e0000) << (BMP_BIT - 32), /* 172 -- 16, d64e */ + BMP_C(0xda000000) << (BMP_BIT - 32), /* 173 -- 8, da */ + BMP_C(0xdaf00000) << (BMP_BIT - 32), /* 174 -- 12, daf */ + BMP_C(0xdebb20e3) << (BMP_BIT - 32), /* 175 -- 32,debb20e3 */ + BMP_C(0xdf000000) << (BMP_BIT - 32), /* 176 -- 8, df */ + BMP_C(0xe0000000) << (BMP_BIT - 32), /* 177 -- 3, 7 */ + BMP_C(0xe3069283) << (BMP_BIT - 32), /* 178 -- 32,e3069283 */ + BMP_C(0xe3940000) << (BMP_BIT - 32), /* 179 -- 16, e394 */ + BMP_C(0xe5cc0000) << (BMP_BIT - 32), /* 180 -- 16, e5cc */ + BMP_C(0xe7a80000) << (BMP_BIT - 32), /* 181 -- 13, 1cf5 */ + BMP_C(0xe8000000) << (BMP_BIT - 32), /* 182 -- 6, 3a */ + BMP_C(0xea000000) << (BMP_BIT - 32), /* 183 -- 7, 75 */ + BMP_C(0xea820000) << (BMP_BIT - 32), /* 184 -- 16, ea82 */ + BMP_C(0xec000000) << (BMP_BIT - 32), /* 185 -- 6, 3b */ + BMP_C(0xf0000000) << (BMP_BIT - 32), /* 186 -- 4, f */ + BMP_C(0xf0b80000) << (BMP_BIT - 32), /* 187 -- 16, f0b8 */ + BMP_C(0xf1300000) << (BMP_BIT - 32), /* 188 -- 12, f13 */ + BMP_C(0xf4000000) << (BMP_BIT - 32), /* 189 -- 8, f4 */ + BMP_C(0xf4acfb13) << (BMP_BIT - 32), /* 190 -- 32,f4acfb13 */ + BMP_C(0xf5b00000) << (BMP_BIT - 32), /* 191 -- 12, f5b */ + BMP_C(0xf6400000) << (BMP_BIT - 32), /* 192 -- 10, 3d9 */ + BMP_C(0xf7000000) << (BMP_BIT - 32), /* 193 -- 8, f7 */ + BMP_C(0xf8000000) << (BMP_BIT - 32), /* 194 -- 5, 1f */ + BMP_C(0xfc000000) << (BMP_BIT - 32), /* 195 -- 6, 3f */ + BMP_C(0xfc891918) << (BMP_BIT - 32), /* 196 -- 32,fc891918 */ + BMP_C(0xfd000000) << (BMP_BIT - 32), /* 197 -- 8, fd */ + BMP_C(0xfe000000) << (BMP_BIT - 32), /* 198 -- 7, 7f */ + BMP_C(0xfedcba00) << (BMP_BIT - 32), /* 199 -- 24, fedcba */ + BMP_C(0xfee80000) << (BMP_BIT - 32), /* 200 -- 16, fee8 */ + BMP_C(0xff000000) << (BMP_BIT - 32), /* 201 -- 8, ff */ + BMP_C(0xffc00000) << (BMP_BIT - 32), /* 202 -- 10, 3ff */ + BMP_C(0xfff00000) << (BMP_BIT - 32), /* 203 -- 12, fff */ + BMP_C(0xfffc0000) << (BMP_BIT - 32), /* 204 -- 14, 3fff */ + BMP_C(0xffff0000) << (BMP_BIT - 32), /* 205 -- 16, ffff */ + BMP_C(0xffffff00) << (BMP_BIT - 32), /* 206 -- 24, ffffff */ + BMP_C(0xfffffffc) << (BMP_BIT - 32), /* 207 -- 30,3fffffff */ + BMP_C(0xfffffffe) << (BMP_BIT - 32), /* 208 -- 31,7fffffff */ + BMP_C(0xffffffff) << (BMP_BIT - 32), /* 209 -- 32,ffffffff */ }; static const struct malias aliases[]; From c87e8faefca62c29c6908ddde0cff982de679ac2 Mon Sep 17 00:00:00 2001 From: "osboxes.org" Date: Tue, 31 Dec 2019 22:32:54 +0100 Subject: [PATCH 1329/1854] style --- client/cmdlfgallagher.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/client/cmdlfgallagher.c b/client/cmdlfgallagher.c index 4752343d5..df822f24a 100644 --- a/client/cmdlfgallagher.c +++ b/client/cmdlfgallagher.c @@ -40,7 +40,7 @@ static int usage_lf_gallagher_clone(void) { return PM3_SUCCESS; } -static void descramble( uint8_t *arr, uint8_t len) { +static void descramble(uint8_t *arr, uint8_t len) { uint8_t lut[] = { 0xa3, 0xb0, 0x80, 0xc6, 0xb2, 0xf4, 0x5c, 0x6c, 0x81, 0xf1, 0xbb, 0xeb, 0x55, 0x67, 0x3c, 0x05, @@ -100,16 +100,16 @@ static int CmdGallagherDemod(const char *Cmd) { // bytes uint8_t arr[8] = {0}; - for(int i = 0, pos = 0; i < ARRAYLEN(arr); i++) { - pos = (i * 8) + i; + for (int i = 0, pos = 0; i < ARRAYLEN(arr); i++) { + pos = (i * 8) + i; arr[i] = bytebits_to_byte(DemodBuffer + pos, 8); - printf("%d -", pos ); + printf("%d -", pos); } printf("\n"); // crc uint8_t crc = bytebits_to_byte(DemodBuffer + 72, 8); - uint8_t calc_crc = CRC8Cardx(arr, ARRAYLEN(arr) ); + uint8_t calc_crc = CRC8Cardx(arr, ARRAYLEN(arr)); PrintAndLogEx(INFO, " Before: %s", sprint_hex(arr, 8)); descramble(arr, ARRAYLEN(arr)); @@ -130,7 +130,7 @@ static int CmdGallagherDemod(const char *Cmd) { PrintAndLogEx(SUCCESS, "GALLAGHER Tag Found -- Region: %u FC: %u CN: %u Issue Level: %u", rc, fc, cn, il); PrintAndLogEx(SUCCESS, " Printed: %C%u", rc + 0x40, fc); PrintAndLogEx(SUCCESS, " Raw: %08X%08X%08X", raw1, raw2, raw3); - PrintAndLogEx(SUCCESS, " CRC: %02X - %02X (%s)", crc, calc_crc, (crc == calc_crc) ? "OK":"Failed"); + PrintAndLogEx(SUCCESS, " CRC: %02X - %02X (%s)", crc, calc_crc, (crc == calc_crc) ? "OK" : "Failed"); return PM3_SUCCESS; } @@ -214,7 +214,7 @@ int detectGallagher(uint8_t *dest, size_t *size) { uint8_t preamble[] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0 }; if (!preambleSearch(dest, preamble, sizeof(preamble), size, &startIdx)) return -2; //preamble not found - + if (*size != 96) return -3; //wrong demoded size //return start position return (int)startIdx; From a290d18918aaec9b945176928ca05e4d9efbe9d6 Mon Sep 17 00:00:00 2001 From: danshuk Date: Wed, 1 Jan 2020 00:12:09 +0000 Subject: [PATCH 1330/1854] cmdlfpac - add decode / encode card ID --- client/cmdlfpac.c | 135 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 120 insertions(+), 15 deletions(-) diff --git a/client/cmdlfpac.c b/client/cmdlfpac.c index eb1b20cd9..04ff13633 100644 --- a/client/cmdlfpac.c +++ b/client/cmdlfpac.c @@ -4,8 +4,8 @@ // at your option, any later version. See the LICENSE.txt file for the text of // the license. //----------------------------------------------------------------------------- -// Low frequency Stanley/PAC tag commands -// NRZ, RF/32, 128 bits long (unknown cs) +// Low frequency PAC/Stanley tag commands +// NRZ, RF/32, 128 bits long //----------------------------------------------------------------------------- #include "cmdlfpac.h" @@ -21,22 +21,111 @@ #include "lfdemod.h" // preamble test #include "protocols.h" // t55xx defines #include "cmdlft55xx.h" // clone.. +#include "parity.h" static int CmdHelp(const char *Cmd); static int usage_lf_pac_clone(void) { - PrintAndLogEx(NORMAL, "clone a Stanley/PAC tag to a T55x7 tag."); + PrintAndLogEx(NORMAL, "clone a PAC/Stanley tag to a T55x7 tag."); PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Usage: lf pac clone [h] [b ]"); + PrintAndLogEx(NORMAL, "Usage: lf pac clone [h] [c ] [b ]"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h : this help"); - PrintAndLogEx(NORMAL, " b : raw hex data. 12 bytes max"); + PrintAndLogEx(NORMAL, " c : 8 byte card ID"); + PrintAndLogEx(NORMAL, " b : raw hex data. 16 bytes max"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); + PrintAndLogEx(NORMAL, " lf pac clone c CD4F5552 "); PrintAndLogEx(NORMAL, " lf pac clone b FF2049906D8511C593155B56D5B2649F "); return PM3_SUCCESS; } +// by danshuk +// PAC_8byte format: preamble (8 mark/idle bits), ascii STX (02), ascii '2' (32), ascii '0' (30), ascii bytes 0..7 (cardid), then xor checksum of cardid bytes +// all bytes following 8 bit preamble are one start bit (0), 7 data bits (lsb first), odd parity bit, and one stop bit (1) +static int demodbuf_to_pacid(uint8_t *src, const size_t src_size, uint8_t *dst, const size_t dst_size) { + const size_t byteLength = 10; // start bit, 7 data bits, parity bit, stop bit + const size_t startIndex = 8 + (3 * byteLength) + 1; // skip 8 bits preamble, STX, '2', '0', and first start bit + const size_t dataLength = 9; + + if (startIndex + byteLength * (dataLength - 1) > src_size) { + PrintAndLogEx(DEBUG, "DEBUG: Error - PAC: Source buffer too small"); + return PM3_EOVFLOW; + } + if (dataLength > dst_size) { + PrintAndLogEx(DEBUG, "DEBUG: Error - PAC: Destination buffer too small"); + return PM3_EOVFLOW; + } + + uint8_t checksum = 0; + for (size_t idx = 0; idx < dataLength; idx++) { + uint8_t byte = (uint8_t)bytebits_to_byteLSBF(src + startIndex + (byteLength * idx), 8); + dst[idx] = byte & 0x7F; // discard the parity bit + if (oddparity8(dst[idx]) != (byte & 0x80) >> 7) { + PrintAndLogEx(DEBUG, "DEBUG: Error - PAC: Parity check failed"); + return PM3_ESOFT; + } + if (idx < dataLength - 1) checksum ^= byte; + } + if (dst[dataLength - 1] != checksum) { + PrintAndLogEx(DEBUG, "DEBUG: Error - PAC: Bad checksum - expected: %02X, actual: %02X", dst[dataLength - 1], checksum); + return PM3_ESOFT; + } + dst[dataLength - 1] = 0; // overwrite checksum byte with null terminator + + return PM3_SUCCESS; +} + +/* +// convert a 16 byte array of raw demod data (FF204990XX...) to 8 bytes of PAC_8byte ID +// performs no parity or checksum validation +static void pacRawToCardId(uint8_t* outCardId, const uint8_t* rawBytes) { + for (int i = 4; i < 12; i++) { + uint8_t shift = 7 - (i + 3) % 4 * 2; + size_t index = i + (i - 1) / 4; + + outCardId[i - 4] = reflect8((((rawBytes[index] << 8) | (rawBytes[index + 1])) >> shift) & 0xFE); + } +} +*/ + +// convert 8 bytes of PAC_8byte ID to 16 byte array of raw data (FF204990XX...) +static void pacCardIdToRaw(uint8_t* outRawBytes, const char* cardId) { + uint8_t idbytes[10]; + + // prepend PAC_8byte card type "20" + idbytes[0] = '2'; + idbytes[1] = '0'; + for (size_t i = 0; i < 8; i++) + idbytes[i + 2] = toupper(cardId[i]); + + // initialise array with start and stop bits + for (size_t i = 0; i < 16; i++) + outRawBytes[i] = 0x40 >> (i + 3) % 5 * 2; + + outRawBytes[0] = 0xFF; // mark + stop + outRawBytes[1] = 0x20; // start + reflect8(STX) + + uint8_t checksum = 0; + for (size_t i = 2; i < 13; i++) { + uint8_t shift = 7 - (i + 3) % 4 * 2; + uint8_t index = i + (i - 1) / 4; + + uint16_t pattern; + if (i < 12) { + pattern = reflect8(idbytes[i - 2]); + pattern |= oddparity8(pattern); + if (i > 3) checksum ^= idbytes[i - 2]; + } + else + pattern = (reflect8(checksum) & 0xFE) | oddparity8(checksum); + pattern <<= shift; + + outRawBytes[index] |= pattern >> 8 & 0xFF; + outRawBytes[index + 1] |= pattern & 0xFF; + } +} + //see NRZDemod for what args are accepted static int CmdPacDemod(const char *Cmd) { @@ -68,13 +157,14 @@ static int CmdPacDemod(const char *Cmd) { uint32_t raw3 = bytebits_to_byte(DemodBuffer + 64, 32); uint32_t raw4 = bytebits_to_byte(DemodBuffer + 96, 32); - // preamble then appears to have marker bits of "10" CS? - // 11111111001000000 10 01001100 10 00001101 10 00001101 10 00001101 10 00001101 10 00001101 10 00001101 10 00001101 10 00001101 10 10001100 10 100000001 - // unknown checksum 9 bits at the end + const size_t idLen = 9; // 8 bytes + null terminator + uint8_t cardid[idLen]; + int retval = demodbuf_to_pacid(DemodBuffer, DemodBufferLen, cardid, sizeof(cardid)); + + if (retval == PM3_SUCCESS) + PrintAndLogEx(SUCCESS, "PAC/Stanley Tag Found -- Card ID: %s, Raw: %08X%08X%08X%08X", cardid, raw1, raw2, raw3, raw4); - PrintAndLogEx(SUCCESS, "PAC/Stanley Tag Found -- Raw: %08X%08X%08X%08X", raw1, raw2, raw3, raw4); - PrintAndLogEx(INFO, "How the Raw ID is translated by the reader is unknown. Share your trace file on forum"); - return PM3_SUCCESS; + return retval; } static int CmdPacRead(const char *Cmd) { @@ -93,6 +183,21 @@ static int CmdPacClone(const char *Cmd) { switch (tolower(param_getchar(Cmd, cmdp))) { case 'h': return usage_lf_pac_clone(); + case 'c': { + // skip first block, 4*4 = 16 bytes left + uint8_t rawhex[16] = {0}; + char cardid[9]; + int res = param_getstr(Cmd, cmdp + 1, cardid, sizeof(cardid)); + if (res < 8) + errors = true; + + pacCardIdToRaw(rawhex, cardid); + for (uint8_t i = 1; i < ARRAYLEN(blocks); i++) { + blocks[i] = bytes_to_num(rawhex + ((i - 1) * 4), sizeof(uint32_t)); + } + cmdp += 2; + break; + } case 'b': { // skip first block, 4*4 = 16 bytes left uint8_t rawhex[16] = {0}; @@ -115,10 +220,10 @@ static int CmdPacClone(const char *Cmd) { if (errors || cmdp == 0) return usage_lf_pac_clone(); - //Pac - compat mode, NRZ, data rate 40, 3 data blocks - blocks[0] = T55x7_MODULATION_DIRECT | T55x7_BITRATE_RF_40 | 4 << T55x7_MAXBLOCK_SHIFT; + //Pac - compat mode, NRZ, data rate 32, 3 data blocks + blocks[0] = T55x7_MODULATION_DIRECT | T55x7_BITRATE_RF_32 | 4 << T55x7_MAXBLOCK_SHIFT; - PrintAndLogEx(INFO, "Preparing to clone Securakey to T55x7 with raw hex"); + PrintAndLogEx(INFO, "Preparing to clone PAC/Stanley tag to T55x7 with raw hex"); print_blocks(blocks, ARRAYLEN(blocks)); return clone_t55xx_tag(blocks, ARRAYLEN(blocks)); @@ -133,7 +238,7 @@ static int CmdPacSim(const char *Cmd) { static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, - {"demod", CmdPacDemod, AlwaysAvailable, "Demodulate an PAC tag from the GraphBuffer"}, + {"demod", CmdPacDemod, AlwaysAvailable, "Demodulate a PAC tag from the GraphBuffer"}, {"read", CmdPacRead, IfPm3Lf, "Attempt to read and extract tag data from the antenna"}, {"clone", CmdPacClone, IfPm3Lf, "clone PAC tag to T55x7"}, {"sim", CmdPacSim, IfPm3Lf, "simulate PAC tag"}, From f0051dc5862600244e595631309504697cfd4ffa Mon Sep 17 00:00:00 2001 From: danshuk Date: Wed, 1 Jan 2020 11:15:06 +0000 Subject: [PATCH 1331/1854] update changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ee2468215..595064b8b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Added `c ` option to `lf pac clone` to allow cloning PAC/Stanley tag from card ID (@danshuk) + - Added decoded PAC/Stanley card ID to `lf pac read` (@danshuk) - Chg mifare classic keytable output refactored and uses colors (@iceman1001) - Fix `hf mf nested` - now writes the correct blockno (@iceman1001) - Chg `lf t55xx dump` - now supports saving to JSON (@iceman1001) From 21ffdec1cdbabd6e18620c82ce662fd835a398d0 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 1 Jan 2020 18:18:34 +0100 Subject: [PATCH 1332/1854] chg: hitag refactoring (@anon) --- armsrc/appmain.c | 4 +-- armsrc/fpgaloader.h | 3 +- armsrc/lfops.c | 8 ++--- armsrc/lfsampling.c | 2 +- fpga/fpga_lf.v | 80 ++++++++++++++++++++++++++++-------------- fpga/lo_adc.v | 48 +++++++++++++++---------- fpga/min_max_tracker.v | 6 ++-- 7 files changed, 95 insertions(+), 56 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 62feed4d0..a405db12e 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -175,7 +175,7 @@ void MeasureAntennaTuning(void) { */ FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_ADC_READER_FIELD); SpinDelay(50); for (uint8_t i = 255; i >= 19; i--) { @@ -1518,7 +1518,7 @@ static void PacketReceived(PacketCommandNG *packet) { case 1: // MEASURE_ANTENNA_TUNING_LF_START // Let the FPGA drive the low-frequency antenna around 125kHz FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_ADC_READER_FIELD); FpgaSendCommand(FPGA_CMD_SET_DIVISOR, packet->data.asBytes[1]); reply_ng(CMD_MEASURE_ANTENNA_TUNING_LF, PM3_SUCCESS, NULL, 0); break; diff --git a/armsrc/fpgaloader.h b/armsrc/fpgaloader.h index 83c5bb2e4..6f27c10ee 100644 --- a/armsrc/fpgaloader.h +++ b/armsrc/fpgaloader.h @@ -28,9 +28,10 @@ #define FPGA_CMD_SET_USER_BYTE1 (3<<12) // Definitions for the FPGA configuration word. // LF -#define FPGA_MAJOR_MODE_LF_ADC (0<<5) +#define FPGA_MAJOR_MODE_LF_READER (0<<5) #define FPGA_MAJOR_MODE_LF_EDGE_DETECT (1<<5) #define FPGA_MAJOR_MODE_LF_PASSTHRU (2<<5) +#define FPGA_MAJOR_MODE_LF_ADC (3<<5) // HF #define FPGA_MAJOR_MODE_HF_READER_TX (0<<5) #define FPGA_MAJOR_MODE_HF_READER_RX_XCORR (1<<5) diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 4c869d9d6..94f7ece2a 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -446,7 +446,7 @@ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint } else { // if field already on leave alone (affects timing otherwise) if (off) { - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_ADC_READER_FIELD); LED_D_ON(); off = false; } @@ -470,7 +470,7 @@ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint FpgaSendCommand(FPGA_CMD_SET_DIVISOR, sc->divisor); } - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_ADC_READER_FIELD); // now do the read DoAcquisition_config(false, 0); @@ -1524,7 +1524,7 @@ void CmdIOdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol) { */ void TurnReadLFOn(uint32_t delay) { - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_ADC_READER_FIELD); // measure antenna strength. //int adcval = ((MAX_ADC_LF_VOLTAGE * AvgAdc(ADC_CHAN_LF)) >> 10); @@ -2482,7 +2482,7 @@ void Cotag(uint32_t arg0) { # define OFF(x) { FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); WaitUS((x)); } #endif #ifndef ON -# define ON(x) { FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); WaitUS((x)); } +# define ON(x) { FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_ADC_READER_FIELD); WaitUS((x)); } #endif uint8_t rawsignal = arg0 & 0xF; diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index 48a3f0d97..bdce67ef9 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -104,7 +104,7 @@ void LFSetupFPGAForADC(int divisor, bool lf_field) { else FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor); - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | (lf_field ? FPGA_LF_ADC_READER_FIELD : 0)); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | (lf_field ? FPGA_LF_ADC_READER_FIELD : 0)); // Connect the A/D to the peak-detected low-frequency path. SetAdcMuxFor(GPIO_MUXSEL_LOPKD); diff --git a/fpga/fpga_lf.v b/fpga/fpga_lf.v index 88b22b7ca..9c1c2528f 100644 --- a/fpga/fpga_lf.v +++ b/fpga/fpga_lf.v @@ -1,7 +1,29 @@ //----------------------------------------------------------------------------- // Jonathan Westhues, March 2006 // iZsh , June 2014 +// Piwi, Feb 2019 +// Anon, 2019 //----------------------------------------------------------------------------- +// Defining commands, modes and options. This must be aligned to the definitions in fpgaloader.h +// Note: the definitions here are without shifts + +// Commands: +`define FPGA_CMD_SET_CONFREG 1 +`define FPGA_CMD_SET_DIVISOR 2 +`define FPGA_CMD_SET_EDGE_DETECT_THRESHOLD 3 + +// Major modes: +`define FPGA_MAJOR_MODE_LF_READER 0 +`define FPGA_MAJOR_MODE_LF_EDGE_DETECT 1 +`define FPGA_MAJOR_MODE_LF_PASSTHRU 2 +`define FPGA_MAJOR_MODE_LF_ADC 3 + +// Options for LF_ADC +`define FPGA_LF_ADC_READER_FIELD 1 + +// Options for LF_EDGE_DETECT +`define FPGA_LF_EDGE_DETECT_READER_FIELD 1 +`define FPGA_LF_EDGE_DETECT_TOGGLE_MODE 2 `include "lo_read.v" `include "lo_passthru.v" @@ -30,39 +52,44 @@ module fpga_lf( reg [15:0] shift_reg; reg [7:0] divisor; -reg [7:0] conf_word; -reg [7:0] user_byte1; +reg [8:0] conf_word; + +// threshold edge detect +reg [7:0] lf_ed_threshold; always @(posedge ncs) begin - case(shift_reg[15:12]) - 4'b0001: + case (shift_reg[15:12]) + `FPGA_CMD_SET_CONFREG: + begin + conf_word <= shift_reg[8:0]; + if (shift_reg[8:6] == `FPGA_MAJOR_MODE_LF_EDGE_DETECT) begin - conf_word <= shift_reg[7:0]; - if (shift_reg[7:0] == 8'b00000001) begin // LF edge detect - user_byte1 <= 127; // default threshold - end + lf_ed_threshold <= 127; // default threshold end - 4'b0010: divisor <= shift_reg[7:0]; // FPGA_CMD_SET_DIVISOR - 4'b0011: user_byte1 <= shift_reg[7:0]; // FPGA_CMD_SET_USER_BYTE1 + end + `FPGA_CMD_SET_DIVISOR: + divisor <= shift_reg[7:0]; + `FPGA_CMD_SET_EDGE_DETECT_THRESHOLD: + lf_ed_threshold <= shift_reg[7:0]; endcase end +// always @(posedge spck) begin - if(~ncs) + if (~ncs) begin shift_reg[15:1] <= shift_reg[14:0]; shift_reg[0] <= mosi; end end -wire [2:0] major_mode = conf_word[7:5]; +wire [2:0] major_mode = conf_word[8:6]; // For the low-frequency configuration: wire lf_field = conf_word[0]; wire lf_ed_toggle_mode = conf_word[1]; // for lo_edge_detect -wire [7:0] lf_ed_threshold = user_byte1; //----------------------------------------------------------------------------- // And then we instantiate the modules corresponding to each of the FPGA's @@ -106,9 +133,8 @@ lo_adc la( la_pwr_lo, la_pwr_hi, la_pwr_oe1, la_pwr_oe2, la_pwr_oe3, la_pwr_oe4, adc_d, la_adc_clk, la_ssp_frame, la_ssp_din, ssp_dout, la_ssp_clk, - cross_hi, cross_lo, la_dbg, divisor, - lo_is_125khz, lf_field + lf_field ); // Major modes: @@ -118,18 +144,18 @@ lo_adc la( // 011 -- LF ADC (read/write) // 110 -- FPGA_MAJOR_MODE_OFF_LF (rdv40 specific) // 111 -- FPGA_MAJOR_MODE_OFF -// 000 001 010 011 100 101 110 111 -mux8 mux_ssp_clk (major_mode, ssp_clk, lr_ssp_clk, le_ssp_clk, 1'b0, la_ssp_clk, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_ssp_din (major_mode, ssp_din, lr_ssp_din, 1'b0, lp_ssp_din, la_ssp_din, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_ssp_frame (major_mode, ssp_frame, lr_ssp_frame, le_ssp_frame, 1'b0, la_ssp_frame, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_pwr_oe1 (major_mode, pwr_oe1, lr_pwr_oe1, le_pwr_oe1, lp_pwr_oe1, la_pwr_oe1, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_pwr_oe2 (major_mode, pwr_oe2, lr_pwr_oe2, le_pwr_oe2, lp_pwr_oe2, la_pwr_oe2, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_pwr_oe3 (major_mode, pwr_oe3, lr_pwr_oe3, le_pwr_oe3, lp_pwr_oe3, la_pwr_oe3, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_pwr_oe4 (major_mode, pwr_oe4, lr_pwr_oe4, le_pwr_oe4, lp_pwr_oe4, la_pwr_oe4, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_pwr_lo (major_mode, pwr_lo, lr_pwr_lo, le_pwr_lo, lp_pwr_lo, la_pwr_lo, 1'b0, 1'b0, 1'b1, 1'b0); -mux8 mux_pwr_hi (major_mode, pwr_hi, lr_pwr_hi, le_pwr_hi, lp_pwr_hi, la_pwr_hi, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_adc_clk (major_mode, adc_clk, lr_adc_clk, le_adc_clk, lp_adc_clk, la_adc_clk, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_dbg (major_mode, dbg, lr_dbg, le_dbg, lp_dbg, la_dbg, 1'b0, 1'b0, 1'b0, 1'b0); +// 000 001 010 011 100 101 110 111 +mux8 mux_ssp_clk (major_mode, ssp_clk, lr_ssp_clk, le_ssp_clk, 1'b0, la_ssp_clk, 1'b0, 1'b0, 1'b0, 1'b0); +mux8 mux_ssp_din (major_mode, ssp_din, lr_ssp_din, 1'b0, lp_ssp_din, la_ssp_din, 1'b0, 1'b0, 1'b0, 1'b0); +mux8 mux_ssp_frame (major_mode, ssp_frame, lr_ssp_frame, le_ssp_frame, 1'b0, la_ssp_frame, 1'b0, 1'b0, 1'b0, 1'b0); +mux8 mux_pwr_oe1 (major_mode, pwr_oe1, lr_pwr_oe1, le_pwr_oe1, lp_pwr_oe1, la_pwr_oe1, 1'b0, 1'b0, 1'b0, 1'b0); +mux8 mux_pwr_oe2 (major_mode, pwr_oe2, lr_pwr_oe2, le_pwr_oe2, lp_pwr_oe2, la_pwr_oe2, 1'b0, 1'b0, 1'b0, 1'b0); +mux8 mux_pwr_oe3 (major_mode, pwr_oe3, lr_pwr_oe3, le_pwr_oe3, lp_pwr_oe3, la_pwr_oe3, 1'b0, 1'b0, 1'b0, 1'b0); +mux8 mux_pwr_oe4 (major_mode, pwr_oe4, lr_pwr_oe4, le_pwr_oe4, lp_pwr_oe4, la_pwr_oe4, 1'b0, 1'b0, 1'b0, 1'b0); +mux8 mux_pwr_lo (major_mode, pwr_lo, lr_pwr_lo, le_pwr_lo, lp_pwr_lo, la_pwr_lo, 1'b0, 1'b0, 1'b1, 1'b0); +mux8 mux_pwr_hi (major_mode, pwr_hi, lr_pwr_hi, le_pwr_hi, lp_pwr_hi, la_pwr_hi, 1'b0, 1'b0, 1'b0, 1'b0); +mux8 mux_adc_clk (major_mode, adc_clk, lr_adc_clk, le_adc_clk, lp_adc_clk, la_adc_clk, 1'b0, 1'b0, 1'b0, 1'b0); +mux8 mux_dbg (major_mode, dbg, lr_dbg, le_dbg, lp_dbg, la_dbg, 1'b0, 1'b0, 1'b0, 1'b0); // In all modes, let the ADC's outputs be enabled. assign adc_noe = 1'b0; diff --git a/fpga/lo_adc.v b/fpga/lo_adc.v index 57e9eebc8..8c1dd12e2 100644 --- a/fpga/lo_adc.v +++ b/fpga/lo_adc.v @@ -11,9 +11,8 @@ module lo_adc( pwr_lo, pwr_hi, pwr_oe1, pwr_oe2, pwr_oe3, pwr_oe4, adc_d, adc_clk, ssp_frame, ssp_din, ssp_dout, ssp_clk, - cross_hi, cross_lo, dbg, divisor, - lo_is_125khz, lf_field + lf_field ); input pck0; output pwr_lo, pwr_hi, pwr_oe1, pwr_oe2, pwr_oe3, pwr_oe4; @@ -21,10 +20,8 @@ module lo_adc( output adc_clk; input ssp_dout; output ssp_frame, ssp_din, ssp_clk; - input cross_hi, cross_lo; output dbg; input [7:0] divisor; - input lo_is_125khz; // redundant signal, no longer used anywhere input lf_field; reg [7:0] to_arm_shiftreg; @@ -34,28 +31,39 @@ reg clk_state; // Antenna logic, depending on "lf_field" (in arm defined as FPGA_LF_READER_FIELD) wire tag_modulation; assign tag_modulation = ssp_dout & !lf_field; + wire reader_modulation; assign reader_modulation = !ssp_dout & lf_field & clk_state; -assign pwr_oe1 = 1'b0; // not used in LF mode -assign pwr_oe2 = 1'b0; //tag_modulation; -assign pwr_oe3 = tag_modulation; -assign pwr_oe4 = 1'b0; //tag_modulation; -assign pwr_lo = reader_modulation; + +// always on (High Frequency outputs, unused) +assign pwr_oe1 = 1'b0; assign pwr_hi = 1'b0; + +// low frequency outputs +assign pwr_lo = reader_modulation; +assign pwr_oe2 = 1'b0; // 33 Ohms +assign pwr_oe3 = tag_modulation; // base antenna load = 33 Ohms +assign pwr_oe4 = 1'b0; // 10k Ohms + +// Debug Output ADC clock assign dbg = adc_clk; // ADC clock out of phase with antenna driver assign adc_clk = ~clk_state; + // serialized SSP data is gated by clk_state to suppress unwanted signal assign ssp_din = to_arm_shiftreg[7] && !clk_state; + // SSP clock always runs at 24MHz assign ssp_clk = pck0; + // SSP frame is gated by clk_state and goes high when pck_divider=8..15 assign ssp_frame = (pck_divider[7:3] == 5'd1) && !clk_state; +// divide 24mhz down to 3mhz always @(posedge pck0) begin - if(pck_divider == divisor[7:0]) + if (pck_divider == divisor[7:0]) begin pck_divider <= 8'd0; clk_state = !clk_state; @@ -66,16 +74,20 @@ begin end end +// this task also runs at pck0 frequency (24Mhz) and is used to serialize +// the ADC output which is then clocked into the ARM SSP. always @(posedge pck0) begin - if((pck_divider == 8'd7) && !clk_state) - begin - to_arm_shiftreg <= adc_d; - end - else - begin - to_arm_shiftreg[7:1] <= to_arm_shiftreg[6:0]; - to_arm_shiftreg[0] <= 1'b0; + if ((pck_divider == 8'd7) && !clk_state) + to_arm_shiftreg <= adc_d; + else begin + to_arm_shiftreg[7:1] <= to_arm_shiftreg[6:0]; + // simulation showed a glitch occuring due to the LSB of the shifter + // not being set as we shift bits out + // this ensures the ssp_din remains low after a transfer and suppresses + // the glitch that would occur when the last data shifted out ended in + // a 1 bit and the next data shifted out started with a 0 bit + to_arm_shiftreg[0] <= 1'b0; end end diff --git a/fpga/min_max_tracker.v b/fpga/min_max_tracker.v index 06a395a70..5e8bbedf1 100644 --- a/fpga/min_max_tracker.v +++ b/fpga/min_max_tracker.v @@ -25,7 +25,7 @@ module min_max_tracker(input clk, input [7:0] adc_d, input [7:0] threshold, always @(posedge clk) begin case (state) - 0: + 0: // initialize begin if (cur_max_val >= ({1'b0, adc_d} + threshold)) state <= 2; @@ -36,7 +36,7 @@ module min_max_tracker(input clk, input [7:0] adc_d, input [7:0] threshold, else if (adc_d <= cur_min_val) cur_min_val <= adc_d; end - 1: + 1: // high phase begin if (cur_max_val <= adc_d) cur_max_val <= adc_d; @@ -46,7 +46,7 @@ module min_max_tracker(input clk, input [7:0] adc_d, input [7:0] threshold, max_val <= cur_max_val; end end - 2: + 2: // low phase begin if (adc_d <= cur_min_val) cur_min_val <= adc_d; From dd36ab39f9def186888b2455240813de34cb307e Mon Sep 17 00:00:00 2001 From: danshuk Date: Wed, 1 Jan 2020 19:43:48 +0000 Subject: [PATCH 1333/1854] add pac trace file --- traces/pac-8E4C058E.pm3 | 30000 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 30000 insertions(+) create mode 100644 traces/pac-8E4C058E.pm3 diff --git a/traces/pac-8E4C058E.pm3 b/traces/pac-8E4C058E.pm3 new file mode 100644 index 000000000..6683686f0 --- /dev/null +++ b/traces/pac-8E4C058E.pm3 @@ -0,0 +1,30000 @@ +50 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +82 +-16 +-103 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +69 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +118 +111 +104 +98 +92 +86 +79 +74 +69 +65 +60 +57 +53 +50 +47 +45 +42 +39 +37 +36 +33 +32 +31 +29 +27 +26 +25 +24 +-59 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-118 +-109 +-99 +-91 +-84 +-77 +-71 +-65 +-60 +-55 +-48 +-44 +-40 +-36 +-32 +-29 +-26 +-24 +-20 +-17 +-15 +25 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +80 +-18 +-105 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +68 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +118 +111 +104 +98 +90 +84 +79 +74 +69 +65 +60 +58 +53 +50 +47 +45 +43 +40 +37 +36 +35 +34 +31 +29 +27 +27 +24 +24 +-60 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-118 +-109 +-100 +-92 +-84 +-77 +-71 +-66 +-60 +-54 +-48 +-44 +-40 +-37 +-33 +-29 +-25 +-22 +-19 +-17 +-15 +-13 +-11 +-11 +-9 +-7 +-5 +-4 +-2 +-1 +1 +1 +2 +3 +5 +5 +5 +6 +7 +6 +6 +7 +9 +9 +9 +10 +10 +10 +10 +11 +12 +11 +12 +12 +13 +11 +11 +12 +14 +13 +14 +14 +14 +14 +14 +14 +14 +14 +15 +14 +13 +13 +13 +13 +14 +14 +14 +14 +14 +13 +14 +14 +15 +14 +15 +53 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +81 +-17 +-105 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +68 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +60 +-36 +-122 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-117 +-108 +-99 +-90 +-82 +-75 +-69 +-63 +-59 +-54 +-49 +-43 +-39 +-35 +-32 +-28 +-26 +-23 +-20 +-16 +-15 +-12 +-11 +-9 +-8 +-7 +-5 +-2 +-1 +0 +1 +2 +3 +3 +4 +5 +6 +6 +6 +7 +7 +7 +8 +9 +10 +11 +10 +11 +11 +11 +11 +11 +12 +13 +12 +12 +11 +12 +12 +13 +13 +14 +13 +13 +13 +14 +13 +13 +14 +14 +14 +13 +12 +13 +13 +14 +14 +15 +14 +14 +14 +15 +14 +14 +14 +15 +14 +14 +13 +14 +14 +15 +15 +15 +15 +15 +14 +15 +15 +15 +14 +15 +15 +14 +13 +13 +14 +14 +14 +15 +15 +14 +14 +14 +14 +15 +14 +14 +53 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +125 +116 +109 +101 +95 +89 +83 +78 +73 +68 +65 +60 +57 +54 +51 +47 +45 +42 +40 +37 +36 +34 +32 +30 +29 +28 +26 +-58 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +43 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +124 +116 +109 +100 +94 +88 +82 +77 +72 +68 +64 +59 +56 +54 +51 +47 +45 +42 +40 +37 +36 +34 +32 +30 +29 +28 +26 +25 +24 +-59 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +41 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +57 +-39 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +66 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +59 +-36 +-122 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +67 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +126 +117 +110 +103 +96 +90 +85 +79 +74 +69 +65 +61 +57 +53 +50 +47 +44 +41 +40 +37 +35 +33 +32 +30 +30 +28 +28 +26 +24 +-59 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +41 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +126 +118 +110 +102 +95 +89 +82 +76 +72 +67 +63 +59 +55 +52 +50 +47 +44 +42 +40 +37 +35 +33 +32 +30 +28 +27 +27 +26 +25 +-58 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-119 +-109 +-101 +-92 +-84 +-77 +-72 +-67 +-60 +-54 +-49 +-45 +-40 +-36 +-33 +-30 +-27 +-23 +-20 +-18 +-15 +-13 +-11 +-11 +-9 +-6 +-4 +-3 +-2 +0 +1 +1 +2 +3 +5 +5 +6 +6 +7 +6 +6 +8 +9 +9 +10 +10 +10 +10 +10 +11 +11 +11 +12 +12 +12 +11 +12 +13 +14 +13 +13 +13 +14 +13 +13 +13 +14 +14 +14 +14 +14 +13 +13 +13 +14 +14 +15 +13 +14 +14 +14 +14 +14 +14 +15 +53 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +117 +110 +102 +97 +90 +85 +79 +74 +70 +65 +61 +58 +54 +51 +47 +45 +42 +41 +38 +36 +34 +33 +31 +31 +29 +28 +25 +25 +23 +21 +20 +19 +18 +18 +17 +16 +16 +16 +15 +15 +15 +15 +14 +14 +14 +14 +12 +12 +12 +12 +11 +11 +11 +11 +10 +11 +10 +10 +-65 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-120 +-111 +-102 +-94 +-86 +-79 +-72 +-67 +-60 +-54 +-49 +-45 +-40 +-37 +-34 +-31 +-27 +-25 +-22 +-19 +-16 +24 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +81 +-17 +-105 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +67 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +60 +-36 +-121 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +65 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +60 +-36 +-122 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-118 +-108 +-99 +-90 +-83 +-76 +-70 +-63 +-59 +-54 +-49 +-43 +-39 +-35 +-32 +-29 +-26 +-23 +-21 +-18 +-15 +-12 +-11 +-10 +-9 +-7 +-4 +-3 +-2 +0 +1 +2 +2 +3 +4 +5 +5 +6 +7 +8 +6 +7 +8 +10 +10 +10 +10 +11 +11 +11 +11 +12 +12 +12 +51 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +81 +-17 +-105 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +68 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +60 +-36 +-121 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-117 +-108 +-100 +-91 +-83 +-76 +-70 +-64 +-59 +-54 +-49 +-44 +-39 +-34 +-31 +-27 +-24 +-21 +-19 +-17 +-15 +-13 +27 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +80 +-18 +-106 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-115 +-106 +-97 +-89 +-81 +-74 +-68 +-63 +-58 +-53 +-48 +-43 +-39 +-34 +-31 +-28 +-26 +-22 +-20 +-17 +-15 +-12 +28 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +125 +116 +109 +102 +96 +89 +83 +78 +74 +68 +64 +60 +57 +53 +50 +47 +45 +42 +40 +38 +37 +34 +32 +30 +29 +27 +26 +24 +24 +22 +21 +20 +20 +19 +18 +17 +17 +16 +16 +15 +15 +14 +15 +14 +14 +13 +13 +13 +12 +11 +12 +11 +11 +11 +11 +11 +11 +10 +11 +10 +10 +10 +10 +10 +10 +9 +10 +10 +10 +9 +10 +10 +10 +9 +10 +10 +10 +9 +9 +9 +9 +9 +9 +9 +9 +8 +9 +9 +10 +9 +9 +9 +9 +9 +9 +9 +9 +8 +9 +9 +9 +8 +8 +8 +8 +8 +9 +8 +8 +8 +9 +9 +9 +9 +9 +9 +9 +9 +9 +9 +9 +9 +9 +8 +9 +9 +9 +8 +9 +8 +8 +8 +8 +8 +8 +8 +8 +8 +8 +8 +9 +9 +8 +8 +9 +9 +8 +8 +9 +9 +9 +8 +9 +9 +9 +8 +8 +8 +9 +8 +8 +8 +9 +8 +8 +8 +9 +9 +9 +9 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +8 +8 +9 +9 +9 +9 +9 +9 +9 +8 +9 +9 +8 +8 +9 +8 +8 +8 +9 +9 +9 +8 +9 +9 +8 +8 +9 +8 +8 +8 +9 +9 +9 +9 +9 +10 +10 +10 +10 +9 +9 +9 +9 +8 +8 +8 +8 +8 +8 +8 +9 +9 +9 +9 +9 +9 +9 +9 +10 +9 +9 +9 +10 +9 +9 +9 +9 +9 +9 +9 +9 +9 +8 +8 +9 +8 +8 +8 +9 +8 +8 +8 +9 +8 +8 +8 +9 +9 +9 +9 +9 +9 +10 +9 +10 +9 +9 +8 +8 +8 +8 +8 +9 +8 +9 +9 +9 +9 +9 +9 +9 +9 +9 +9 +9 +9 +9 +9 +9 +9 +9 +8 +9 +9 +8 +8 +9 +8 +8 +8 +8 +8 +8 +7 +8 +8 +8 +8 +9 +9 +8 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +8 +8 +9 +9 +8 +8 +9 +8 +8 +8 +9 +8 +8 +8 +9 +9 +8 +8 +8 +8 +8 +8 +8 +8 +8 +8 +9 +9 +9 +8 +9 +9 +8 +8 +8 +9 +9 +8 +8 +8 +10 +10 +11 +11 +11 +10 +10 +-69 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-121 +-111 +-101 +-94 +-86 +-79 +-72 +-67 +-61 +-56 +-50 +-45 +-40 +-36 +-32 +-29 +-26 +-24 +-21 +-19 +-16 +25 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +81 +-17 +-105 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-115 +-106 +-97 +-89 +-82 +-75 +-68 +-63 +-59 +-53 +-48 +-43 +-39 +-34 +-31 +-28 +-26 +-22 +-19 +-17 +-15 +-12 +-11 +-10 +-9 +-7 +-5 +-3 +-2 +0 +1 +2 +2 +3 +4 +5 +5 +6 +7 +7 +6 +7 +8 +9 +9 +10 +11 +11 +10 +11 +11 +12 +12 +12 +12 +13 +11 +11 +12 +14 +14 +14 +14 +14 +14 +13 +13 +14 +14 +14 +14 +14 +13 +13 +13 +15 +15 +14 +14 +14 +14 +14 +13 +14 +15 +15 +14 +14 +13 +13 +13 +14 +15 +15 +14 +14 +14 +15 +14 +15 +15 +15 +14 +14 +14 +14 +14 +14 +15 +16 +15 +14 +14 +15 +14 +14 +14 +15 +14 +14 +13 +14 +14 +14 +15 +15 +14 +14 +14 +15 +14 +14 +14 +15 +15 +14 +13 +14 +14 +15 +15 +16 +15 +15 +14 +15 +15 +15 +14 +15 +54 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +82 +-16 +-104 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-115 +-105 +-97 +-89 +-82 +-75 +-68 +-63 +-59 +-53 +-48 +-43 +-39 +-35 +-31 +-28 +-26 +-23 +-20 +-16 +-15 +-13 +28 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +81 +-17 +-105 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-114 +-105 +-97 +-89 +-82 +-75 +-69 +-63 +-59 +-54 +-48 +-43 +-39 +-35 +-31 +-28 +-26 +-23 +-20 +-17 +-15 +-13 +28 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +125 +117 +110 +102 +96 +90 +84 +78 +74 +69 +66 +61 +57 +53 +51 +48 +45 +42 +40 +38 +36 +33 +32 +31 +29 +27 +27 +-57 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-119 +-109 +-100 +-92 +-84 +-78 +-71 +-66 +-60 +-55 +-49 +-44 +-39 +-36 +-33 +-30 +-26 +-23 +-21 +-18 +-15 +26 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +80 +-18 +-105 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-116 +-106 +-96 +-88 +-82 +-75 +-68 +-62 +-58 +-52 +-47 +-42 +-38 +-35 +-31 +-28 +-27 +-23 +-20 +-17 +-15 +-13 +-11 +-9 +-9 +-7 +-4 +-3 +-2 +0 +2 +2 +2 +4 +5 +5 +5 +6 +7 +8 +8 +8 +9 +10 +10 +11 +10 +10 +10 +11 +11 +12 +12 +12 +12 +13 +11 +11 +12 +13 +13 +14 +14 +14 +13 +13 +14 +14 +14 +14 +14 +14 +12 +13 +14 +14 +14 +15 +15 +14 +13 +14 +15 +14 +14 +14 +14 +14 +13 +13 +14 +15 +15 +15 +14 +15 +15 +15 +14 +15 +15 +15 +14 +14 +13 +14 +14 +14 +15 +15 +14 +14 +14 +15 +14 +15 +14 +15 +54 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +126 +117 +110 +102 +96 +90 +84 +78 +74 +69 +66 +62 +59 +55 +51 +48 +45 +42 +40 +38 +36 +33 +32 +30 +29 +27 +26 +-58 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +40 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +125 +117 +110 +102 +95 +89 +84 +77 +73 +68 +64 +60 +57 +53 +50 +47 +45 +43 +41 +39 +37 +34 +32 +30 +29 +27 +26 +24 +24 +-60 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-118 +-109 +-100 +-92 +-84 +-77 +-71 +-67 +-60 +-54 +-48 +-43 +-38 +-35 +-32 +-29 +-26 +-24 +-21 +-18 +-16 +-14 +-11 +-11 +-9 +-7 +-5 +-4 +-2 +0 +0 +1 +2 +3 +4 +5 +6 +6 +6 +6 +7 +8 +9 +9 +10 +10 +10 +10 +11 +11 +12 +12 +11 +11 +12 +11 +11 +12 +13 +13 +13 +14 +14 +13 +13 +14 +14 +13 +14 +14 +14 +12 +13 +14 +15 +14 +14 +14 +15 +14 +14 +14 +15 +15 +15 +53 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +126 +117 +110 +102 +96 +89 +84 +78 +74 +69 +65 +61 +58 +54 +51 +48 +46 +42 +40 +38 +36 +34 +32 +31 +29 +27 +26 +25 +23 +22 +22 +21 +20 +19 +18 +18 +18 +16 +16 +16 +16 +16 +16 +15 +14 +14 +13 +12 +12 +12 +11 +11 +11 +11 +11 +10 +11 +11 +10 +-65 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-122 +-111 +-102 +-94 +-86 +-79 +-72 +-68 +-62 +-56 +-49 +-45 +-41 +-37 +-33 +-30 +-27 +-25 +-21 +-19 +-16 +24 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +81 +-17 +-104 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +68 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +60 +-36 +-121 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +64 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +60 +-36 +-121 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-116 +-108 +-99 +-90 +-83 +-76 +-70 +-63 +-60 +-54 +-48 +-43 +-39 +-35 +-31 +-28 +-26 +-23 +-20 +-18 +-15 +-12 +-10 +-9 +-9 +-7 +-4 +-2 +0 +2 +1 +2 +3 +3 +4 +6 +6 +6 +6 +7 +6 +7 +8 +10 +10 +10 +11 +12 +12 +12 +12 +12 +12 +12 +50 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +81 +-17 +-104 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +70 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +60 +-36 +-122 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-116 +-107 +-98 +-90 +-83 +-76 +-70 +-64 +-59 +-54 +-49 +-43 +-39 +-35 +-32 +-28 +-26 +-23 +-20 +-17 +-14 +-13 +-12 +-9 +-8 +-7 +-5 +-3 +-1 +0 +0 +2 +2 +4 +4 +5 +6 +7 +7 +7 +6 +8 +8 +9 +9 +11 +10 +10 +10 +11 +11 +11 +11 +12 +50 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +81 +-17 +-105 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +68 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +120 +112 +104 +98 +91 +84 +78 +74 +68 +64 +60 +57 +53 +50 +48 +46 +43 +41 +38 +36 +34 +32 +30 +29 +27 +26 +25 +24 +-60 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-119 +-110 +-100 +-92 +-84 +-77 +-72 +-67 +-60 +-55 +-49 +-45 +-40 +-36 +-32 +-30 +-27 +-23 +-20 +-18 +-15 +25 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +80 +-18 +-105 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +68 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +118 +110 +103 +97 +85 +79 +75 +70 +67 +62 +58 +54 +52 +49 +45 +42 +40 +38 +36 +33 +32 +31 +29 +27 +26 +25 +24 +-60 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-119 +-109 +-100 +-93 +-85 +-77 +-71 +-66 +-61 +-55 +-49 +-44 +-40 +-36 +-32 +-30 +-26 +-23 +-20 +-18 +-16 +-14 +-11 +-11 +-10 +-7 +-4 +-3 +-2 +-1 +1 +2 +3 +3 +4 +5 +6 +6 +6 +6 +7 +7 +8 +9 +10 +10 +10 +10 +11 +11 +11 +12 +12 +12 +12 +11 +12 +12 +12 +13 +14 +13 +13 +12 +13 +13 +14 +13 +14 +14 +13 +12 +13 +14 +14 +14 +15 +15 +15 +14 +14 +14 +15 +15 +15 +53 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +81 +-17 +-105 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +68 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +60 +-36 +-122 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-117 +-107 +-99 +-91 +-83 +-75 +-69 +-63 +-59 +-54 +-49 +-43 +-39 +-36 +-32 +-28 +-26 +-23 +-20 +-17 +-15 +-13 +-11 +-9 +-8 +-7 +-5 +-2 +-2 +0 +1 +2 +2 +3 +4 +6 +6 +6 +6 +7 +7 +7 +8 +10 +10 +10 +10 +11 +11 +11 +10 +11 +12 +13 +12 +12 +12 +12 +13 +13 +14 +14 +13 +13 +13 +14 +13 +13 +14 +14 +14 +13 +12 +13 +13 +14 +14 +15 +15 +14 +14 +14 +14 +14 +14 +15 +15 +15 +13 +14 +14 +15 +14 +15 +15 +15 +14 +14 +15 +15 +14 +15 +15 +15 +13 +14 +14 +15 +14 +15 +15 +15 +14 +14 +14 +15 +14 +14 +53 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +126 +117 +110 +103 +96 +89 +84 +79 +74 +68 +64 +60 +57 +53 +50 +47 +45 +42 +40 +37 +36 +34 +32 +30 +29 +28 +26 +-58 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +43 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +124 +115 +108 +101 +95 +88 +83 +78 +73 +68 +64 +60 +57 +53 +50 +47 +45 +42 +40 +37 +36 +34 +32 +30 +30 +28 +27 +25 +25 +-59 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +40 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +58 +-38 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +65 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +59 +-37 +-122 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +65 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +117 +110 +103 +97 +91 +86 +80 +74 +69 +65 +60 +57 +53 +50 +47 +45 +42 +40 +37 +36 +34 +32 +30 +29 +27 +26 +25 +24 +-60 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +43 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +124 +115 +108 +101 +95 +88 +83 +77 +73 +67 +64 +60 +57 +53 +49 +47 +45 +42 +39 +37 +36 +33 +32 +30 +29 +27 +26 +25 +24 +-60 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-119 +-109 +-100 +-92 +-85 +-77 +-71 +-65 +-60 +-55 +-49 +-44 +-39 +-36 +-32 +-30 +-26 +-23 +-20 +-18 +-16 +-13 +-11 +-10 +-8 +-5 +-3 +-2 +-1 +0 +1 +1 +3 +3 +4 +4 +6 +5 +6 +6 +7 +7 +9 +10 +10 +10 +10 +10 +11 +11 +12 +12 +12 +12 +12 +12 +12 +12 +13 +14 +14 +13 +14 +14 +14 +14 +14 +14 +15 +14 +14 +13 +14 +14 +14 +15 +15 +15 +14 +14 +15 +14 +14 +14 +15 +53 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +126 +118 +110 +102 +96 +90 +84 +78 +74 +69 +65 +60 +57 +54 +51 +47 +45 +42 +40 +37 +36 +34 +32 +30 +29 +28 +26 +24 +23 +23 +22 +20 +20 +19 +19 +17 +17 +17 +16 +15 +15 +15 +15 +13 +13 +13 +13 +13 +14 +13 +12 +11 +12 +11 +11 +11 +10 +10 +11 +-64 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-120 +-111 +-102 +-94 +-86 +-78 +-72 +-67 +-61 +-55 +-49 +-44 +-40 +-37 +-33 +-30 +-27 +-24 +-20 +-18 +-15 +25 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +81 +-17 +-105 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +68 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +60 +-36 +-121 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +66 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +60 +-36 +-121 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-117 +-108 +-100 +-91 +-83 +-76 +-70 +-64 +-59 +-54 +-49 +-44 +-39 +-35 +-32 +-29 +-26 +-23 +-21 +-18 +-15 +-12 +-11 +-10 +-9 +-6 +-5 +-3 +-1 +1 +1 +1 +2 +4 +4 +5 +6 +7 +7 +7 +7 +8 +8 +9 +10 +11 +10 +10 +10 +11 +11 +11 +12 +13 +52 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +81 +-17 +-105 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +69 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +60 +-36 +-122 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-118 +-108 +-99 +-90 +-83 +-76 +-69 +-63 +-59 +-54 +-48 +-43 +-38 +-35 +-31 +-28 +-25 +-23 +-20 +-17 +-15 +-13 +28 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +82 +-17 +-104 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-117 +-107 +-98 +-89 +-82 +-75 +-69 +-62 +-58 +-54 +-48 +-42 +-38 +-34 +-31 +-28 +-25 +-23 +-20 +-17 +-15 +-13 +28 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +125 +116 +109 +102 +96 +89 +84 +78 +74 +70 +65 +60 +57 +54 +51 +47 +45 +42 +40 +37 +36 +34 +33 +30 +29 +28 +27 +25 +24 +23 +23 +21 +20 +19 +19 +18 +17 +16 +17 +16 +15 +14 +15 +14 +14 +13 +14 +13 +13 +12 +13 +12 +12 +11 +11 +11 +10 +10 +10 +10 +10 +9 +10 +10 +10 +9 +10 +10 +9 +9 +10 +10 +9 +9 +10 +9 +9 +9 +10 +9 +9 +9 +10 +9 +9 +8 +9 +9 +8 +8 +9 +9 +9 +9 +9 +9 +8 +8 +9 +8 +8 +8 +9 +8 +8 +8 +9 +8 +9 +9 +10 +9 +9 +9 +10 +9 +9 +9 +9 +9 +9 +9 +9 +8 +8 +8 +9 +8 +8 +8 +9 +8 +8 +8 +9 +8 +8 +8 +10 +9 +9 +9 +10 +9 +9 +9 +9 +9 +9 +9 +10 +9 +9 +9 +10 +9 +9 +9 +9 +9 +8 +8 +9 +9 +8 +8 +9 +9 +8 +8 +9 +9 +9 +8 +8 +9 +9 +8 +8 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +9 +9 +9 +9 +8 +9 +9 +8 +8 +9 +9 +8 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +8 +8 +8 +9 +10 +10 +10 +10 +9 +9 +8 +8 +8 +8 +8 +9 +8 +8 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +8 +8 +9 +9 +9 +9 +9 +9 +9 +8 +9 +9 +8 +8 +9 +9 +8 +8 +9 +9 +8 +8 +9 +9 +8 +8 +9 +9 +8 +8 +8 +8 +8 +8 +8 +8 +8 +8 +8 +9 +9 +8 +8 +9 +10 +10 +10 +9 +9 +9 +8 +8 +8 +7 +8 +8 +8 +8 +9 +8 +8 +8 +9 +8 +8 +8 +9 +9 +8 +8 +9 +10 +10 +9 +9 +9 +8 +8 +8 +8 +8 +8 +9 +9 +9 +9 +9 +9 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +-70 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-121 +-112 +-102 +-94 +-86 +-80 +-73 +-67 +-61 +-56 +-50 +-45 +-40 +-37 +-34 +-31 +-27 +-24 +-20 +-17 +-15 +25 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +80 +-18 +-105 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-115 +-106 +-97 +-88 +-81 +-73 +-68 +-63 +-58 +-53 +-48 +-43 +-39 +-34 +-31 +-27 +-25 +-22 +-19 +-16 +-14 +-13 +-10 +-8 +-9 +-7 +-5 +-2 +-2 +0 +0 +2 +2 +3 +4 +5 +6 +6 +6 +7 +7 +7 +8 +9 +10 +10 +10 +11 +11 +11 +11 +12 +11 +12 +12 +12 +11 +11 +12 +14 +13 +13 +13 +14 +13 +13 +14 +14 +13 +14 +14 +14 +13 +13 +14 +15 +14 +14 +14 +15 +14 +14 +14 +14 +15 +14 +14 +14 +13 +13 +14 +15 +15 +15 +14 +14 +14 +14 +14 +14 +15 +15 +14 +14 +14 +14 +14 +15 +15 +15 +15 +15 +15 +15 +14 +14 +15 +15 +14 +14 +13 +14 +15 +16 +16 +17 +17 +17 +16 +15 +15 +14 +14 +14 +13 +14 +12 +13 +14 +14 +14 +15 +15 +14 +15 +15 +14 +15 +15 +15 +53 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +81 +-17 +-105 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-115 +-105 +-97 +-89 +-81 +-74 +-69 +-63 +-58 +-53 +-48 +-43 +-39 +-34 +-31 +-28 +-26 +-23 +-20 +-17 +-15 +-13 +28 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +81 +-17 +-105 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-116 +-106 +-97 +-90 +-82 +-74 +-68 +-63 +-59 +-53 +-48 +-43 +-39 +-35 +-31 +-28 +-26 +-23 +-19 +-17 +-15 +-13 +28 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +125 +117 +110 +101 +95 +89 +84 +78 +74 +68 +64 +61 +58 +53 +50 +47 +45 +42 +40 +37 +36 +34 +32 +30 +29 +28 +26 +-58 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-119 +-109 +-100 +-92 +-84 +-77 +-71 +-66 +-60 +-54 +-48 +-44 +-40 +-36 +-32 +-29 +-26 +-24 +-20 +-18 +-16 +25 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +81 +-17 +-105 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-115 +-105 +-97 +-89 +-82 +-75 +-68 +-62 +-59 +-53 +-47 +-42 +-38 +-34 +-31 +-27 +-25 +-23 +-20 +-16 +-14 +-12 +-9 +-9 +-9 +-6 +-5 +-3 +-2 +0 +0 +1 +2 +3 +3 +5 +6 +6 +7 +8 +7 +7 +8 +10 +10 +11 +11 +11 +11 +11 +11 +12 +12 +12 +12 +12 +11 +11 +12 +14 +14 +13 +13 +14 +14 +13 +13 +15 +14 +14 +14 +14 +13 +13 +13 +15 +14 +14 +14 +15 +14 +14 +14 +15 +14 +14 +14 +14 +13 +13 +13 +15 +15 +15 +14 +14 +14 +15 +14 +15 +15 +15 +14 +14 +13 +14 +14 +15 +14 +15 +15 +15 +14 +14 +14 +15 +14 +15 +54 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +118 +110 +102 +96 +89 +84 +79 +74 +68 +65 +61 +57 +53 +51 +48 +45 +42 +41 +38 +36 +34 +33 +31 +29 +27 +26 +-57 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +42 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +124 +115 +109 +101 +95 +88 +84 +78 +73 +68 +64 +60 +56 +53 +50 +47 +45 +42 +40 +38 +36 +33 +32 +29 +28 +27 +26 +24 +23 +-60 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-120 +-110 +-100 +-93 +-85 +-78 +-71 +-66 +-60 +-55 +-48 +-44 +-40 +-36 +-32 +-29 +-26 +-23 +-19 +-17 +-15 +-14 +-11 +-10 +-9 +-7 +-5 +-3 +-1 +-1 +0 +1 +3 +3 +4 +4 +6 +6 +6 +6 +7 +8 +9 +9 +10 +11 +10 +10 +11 +11 +12 +11 +12 +12 +13 +12 +13 +13 +14 +14 +14 +13 +13 +13 +13 +13 +14 +14 +14 +14 +15 +13 +13 +14 +15 +14 +15 +14 +15 +14 +14 +14 +15 +14 +14 +53 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +126 +117 +109 +102 +96 +90 +85 +79 +74 +68 +64 +60 +57 +52 +50 +47 +44 +41 +40 +37 +35 +33 +32 +31 +29 +27 +27 +25 +24 +22 +22 +21 +20 +19 +19 +19 +18 +18 +18 +17 +16 +15 +15 +13 +13 +12 +12 +11 +11 +11 +11 +11 +11 +10 +11 +10 +11 +11 +11 +-64 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-121 +-111 +-102 +-93 +-86 +-79 +-72 +-67 +-61 +-56 +-50 +-45 +-40 +-37 +-33 +-30 +-26 +-24 +-21 +-19 +-15 +25 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +80 +-18 +-105 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +69 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +60 +-36 +-122 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +64 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +59 +-36 +-122 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-117 +-107 +-99 +-90 +-83 +-76 +-69 +-63 +-59 +-54 +-48 +-42 +-38 +-34 +-31 +-27 +-25 +-22 +-20 +-16 +-15 +-13 +-11 +-9 +-9 +-7 +-5 +-3 +-2 +0 +1 +2 +2 +3 +4 +6 +5 +6 +6 +7 +6 +7 +8 +9 +10 +10 +10 +11 +11 +11 +11 +12 +12 +12 +50 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +81 +-17 +-105 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +70 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +61 +-35 +-120 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-117 +-108 +-99 +-90 +-83 +-76 +-70 +-63 +-58 +-53 +-48 +-43 +-39 +-35 +-32 +-29 +-26 +-23 +-20 +-18 +-15 +-13 +-12 +-10 +-9 +-7 +-4 +-2 +-1 +0 +1 +2 +2 +3 +4 +5 +5 +7 +7 +8 +6 +7 +8 +9 +9 +10 +11 +12 +12 +12 +12 +12 +13 +12 +51 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +81 +-17 +-105 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +69 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +118 +110 +102 +96 +90 +84 +78 +74 +69 +65 +61 +57 +54 +51 +47 +45 +42 +40 +37 +35 +33 +33 +30 +29 +27 +27 +25 +24 +-59 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-119 +-109 +-100 +-92 +-85 +-77 +-71 +-65 +-60 +-55 +-49 +-44 +-40 +-36 +-33 +-29 +-26 +-23 +-21 +-18 +-15 +26 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +82 +-16 +-104 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +69 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +118 +111 +103 +97 +91 +85 +79 +74 +69 +65 +61 +57 +53 +51 +48 +45 +42 +40 +38 +36 +33 +32 +30 +29 +27 +26 +25 +24 +-60 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-118 +-108 +-100 +-92 +-85 +-77 +-71 +-67 +-61 +-55 +-49 +-44 +-40 +-36 +-32 +-29 +-26 +-23 +-20 +-18 +-16 +-14 +-12 +-10 +-9 +-7 +-5 +-3 +-1 +-1 +0 +1 +3 +3 +4 +4 +6 +6 +6 +5 +6 +8 +10 +10 +11 +11 +11 +10 +11 +10 +11 +11 +11 +11 +12 +10 +11 +12 +13 +12 +13 +13 +13 +13 +13 +13 +13 +14 +14 +13 +14 +13 +13 +13 +14 +15 +15 +14 +15 +14 +15 +14 +14 +14 +15 +53 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +82 +-17 +-104 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +69 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +61 +-35 +-121 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-116 +-107 +-99 +-90 +-82 +-76 +-70 +-59 +-54 +-49 +-43 +-39 +-35 +-32 +-28 +-25 +-23 +-21 +-17 +-15 +-13 +-12 +-10 +-9 +-7 +-6 +-3 +-1 +0 +0 +1 +2 +4 +4 +5 +5 +7 +7 +7 +6 +8 +9 +9 +9 +10 +11 +10 +10 +11 +11 +11 +11 +12 +12 +13 +12 +13 +13 +13 +14 +14 +13 +13 +13 +13 +13 +14 +14 +14 +14 +14 +13 +13 +14 +15 +14 +14 +14 +15 +14 +14 +14 +15 +14 +14 +15 +15 +13 +13 +14 +15 +15 +15 +14 +15 +14 +14 +14 +15 +15 +14 +14 +15 +14 +13 +14 +15 +15 +15 +14 +15 +14 +14 +14 +15 +15 +15 +53 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +126 +117 +110 +102 +97 +89 +84 +78 +74 +69 +65 +60 +57 +53 +50 +47 +46 +42 +40 +37 +36 +34 +32 +30 +29 +28 +26 +-58 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +41 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +125 +116 +109 +102 +96 +89 +83 +77 +73 +69 +66 +61 +57 +53 +50 +47 +44 +41 +39 +36 +35 +33 +31 +29 +28 +27 +26 +24 +24 +-60 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +41 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +57 +-39 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +65 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +60 +-36 +-122 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +66 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +126 +118 +110 +102 +96 +90 +84 +78 +74 +69 +66 +62 +59 +55 +51 +48 +46 +42 +40 +37 +36 +33 +32 +30 +29 +27 +26 +25 +24 +-59 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +42 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +125 +117 +109 +101 +95 +89 +84 +78 +72 +68 +64 +61 +58 +54 +51 +47 +45 +41 +39 +36 +35 +33 +31 +30 +28 +26 +26 +25 +23 +-60 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-118 +-109 +-100 +-92 +-84 +-77 +-71 +-66 +-60 +-54 +-49 +-45 +-40 +-36 +-32 +-30 +-26 +-23 +-20 +-18 +-16 +-13 +-11 +-11 +-9 +-7 +-4 +-3 +-2 +-1 +0 +1 +2 +2 +4 +5 +6 +6 +6 +6 +7 +7 +9 +9 +11 +10 +10 +10 +11 +11 +11 +11 +13 +12 +12 +11 +12 +12 +13 +13 +14 +14 +13 +13 +14 +14 +14 +13 +14 +14 +14 +12 +13 +14 +15 +14 +14 +15 +14 +13 +14 +14 +14 +13 +14 +53 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +126 +118 +111 +103 +96 +90 +84 +78 +73 +69 +65 +60 +57 +54 +51 +47 +45 +42 +40 +37 +36 +34 +32 +30 +29 +27 +27 +25 +24 +23 +22 +21 +20 +19 +19 +17 +17 +16 +16 +15 +15 +15 +15 +14 +13 +13 +13 +12 +13 +12 +12 +11 +11 +11 +12 +11 +11 +11 +11 +-64 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-120 +-111 +-102 +-94 +-86 +-79 +-73 +-68 +-62 +-55 +-49 +-44 +-39 +-35 +-32 +-30 +-27 +-24 +-22 +-19 +-16 +24 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +81 +-17 +-105 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +69 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +59 +-36 +-122 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +65 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +59 +-36 +-122 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-116 +-107 +-99 +-90 +-82 +-76 +-69 +-63 +-59 +-54 +-49 +-43 +-38 +-35 +-32 +-28 +-25 +-23 +-21 +-17 +-15 +-13 +-12 +-10 +-9 +-7 +-5 +-3 +-1 +0 +0 +2 +3 +3 +3 +5 +6 +7 +7 +7 +7 +8 +8 +9 +10 +11 +11 +11 +11 +12 +11 +12 +12 +13 +51 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +80 +-18 +-105 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +69 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +60 +-36 +-122 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-117 +-107 +-98 +-90 +-83 +-76 +-69 +-63 +-59 +-54 +-49 +-43 +-39 +-34 +-32 +-29 +-27 +-23 +-20 +-16 +-14 +-12 +28 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +80 +-18 +-105 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-115 +-106 +-97 +-89 +-81 +-75 +-69 +-63 +-58 +-53 +-48 +-43 +-38 +-34 +-31 +-28 +-25 +-22 +-19 +-17 +-15 +-12 +29 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +125 +116 +109 +102 +96 +89 +84 +78 +74 +68 +64 +60 +57 +53 +50 +47 +45 +43 +40 +37 +36 +34 +32 +30 +29 +27 +26 +24 +23 +22 +22 +20 +20 +19 +19 +17 +17 +16 +16 +15 +15 +15 +15 +14 +14 +14 +14 +13 +13 +12 +13 +12 +12 +11 +12 +11 +11 +10 +11 +10 +10 +10 +11 +10 +10 +10 +11 +10 +10 +10 +9 +9 +10 +9 +9 +9 +9 +9 +9 +9 +9 +8 +9 +9 +9 +9 +9 +9 +10 +9 +9 +8 +9 +9 +9 +8 +9 +9 +8 +8 +9 +9 +8 +8 +9 +9 +9 +8 +9 +9 +10 +10 +9 +9 +9 +9 +8 +8 +8 +8 +8 +8 +8 +8 +8 +8 +9 +8 +8 +8 +9 +8 +8 +8 +9 +8 +8 +9 +9 +8 +9 +9 +10 +8 +9 +9 +10 +9 +9 +9 +10 +9 +9 +9 +10 +9 +9 +9 +10 +9 +9 +9 +9 +8 +8 +8 +8 +8 +8 +8 +9 +8 +8 +9 +9 +8 +8 +9 +9 +8 +9 +9 +10 +9 +9 +10 +10 +9 +9 +9 +10 +8 +9 +9 +9 +8 +8 +8 +9 +8 +8 +8 +9 +8 +8 +8 +9 +9 +8 +8 +9 +8 +8 +8 +9 +8 +8 +9 +9 +9 +9 +9 +10 +9 +9 +9 +9 +8 +8 +8 +9 +8 +8 +8 +9 +8 +8 +8 +9 +8 +8 +9 +9 +9 +9 +9 +10 +9 +9 +9 +10 +9 +9 +9 +9 +8 +8 +8 +9 +8 +8 +8 +9 +8 +8 +8 +9 +8 +8 +9 +9 +8 +9 +9 +10 +9 +9 +9 +9 +8 +8 +8 +9 +9 +8 +8 +9 +9 +9 +9 +9 +9 +9 +8 +9 +9 +8 +8 +9 +9 +9 +9 +9 +9 +9 +8 +8 +8 +8 +8 +8 +8 +8 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +8 +8 +8 +8 +8 +8 +8 +8 +8 +8 +8 +8 +8 +8 +9 +8 +8 +8 +9 +8 +8 +8 +9 +8 +8 +8 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +-69 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-120 +-110 +-101 +-94 +-86 +-79 +-72 +-67 +-61 +-56 +-50 +-44 +-40 +-37 +-33 +-30 +-26 +-24 +-21 +-18 +-15 +25 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +80 +-18 +-105 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-116 +-106 +-97 +-90 +-82 +-75 +-69 +-62 +-58 +-53 +-48 +-42 +-38 +-34 +-31 +-28 +-25 +-22 +-20 +-17 +-14 +-12 +-11 +-9 +-8 +-6 +-5 +-3 +-2 +1 +1 +1 +2 +4 +4 +5 +6 +7 +7 +7 +7 +8 +9 +10 +9 +10 +11 +11 +10 +10 +11 +12 +12 +12 +12 +13 +12 +13 +13 +13 +14 +14 +13 +13 +13 +13 +13 +14 +14 +14 +14 +14 +13 +13 +13 +15 +15 +15 +14 +15 +15 +15 +14 +15 +15 +15 +14 +14 +13 +14 +14 +15 +15 +15 +15 +14 +14 +14 +14 +14 +14 +15 +14 +14 +14 +14 +14 +15 +15 +15 +15 +15 +15 +14 +14 +15 +15 +14 +13 +14 +13 +13 +13 +14 +15 +15 +14 +14 +14 +15 +15 +16 +16 +15 +14 +14 +13 +13 +13 +15 +14 +14 +15 +15 +14 +14 +15 +15 +14 +15 +54 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +80 +-18 +-105 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-114 +-104 +-96 +-88 +-82 +-74 +-69 +-64 +-59 +-54 +-49 +-44 +-39 +-34 +-31 +-28 +-25 +-21 +-19 +-17 +-14 +-12 +29 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +80 +-18 +-105 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-116 +-106 +-97 +-88 +-81 +-75 +-68 +-62 +-58 +-53 +-48 +-43 +-38 +-34 +-31 +-28 +-25 +-22 +-20 +-17 +-15 +-12 +29 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +125 +117 +110 +101 +95 +89 +84 +78 +73 +68 +65 +61 +58 +55 +51 +48 +45 +42 +40 +37 +36 +33 +32 +30 +29 +27 +26 +-57 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-119 +-109 +-99 +-92 +-84 +-77 +-70 +-65 +-60 +-55 +-49 +-44 +-39 +-35 +-31 +-28 +-25 +-23 +-20 +-18 +-16 +25 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +80 +-18 +-105 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-115 +-106 +-97 +-88 +-81 +-75 +-69 +-63 +-58 +-53 +-48 +-43 +-38 +-34 +-31 +-28 +-25 +-22 +-19 +-17 +-15 +-12 +-10 +-9 +-9 +-7 +-5 +-3 +-2 +0 +1 +2 +2 +4 +4 +5 +5 +7 +7 +7 +6 +7 +9 +9 +9 +11 +11 +11 +10 +11 +11 +12 +12 +12 +13 +13 +11 +11 +12 +13 +13 +14 +14 +14 +13 +13 +14 +15 +14 +14 +14 +14 +13 +13 +13 +15 +15 +15 +14 +15 +14 +14 +14 +14 +14 +15 +14 +14 +13 +14 +14 +15 +15 +16 +15 +15 +14 +15 +14 +14 +14 +15 +15 +14 +13 +14 +14 +14 +15 +15 +15 +14 +14 +15 +14 +14 +15 +15 +54 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +124 +116 +109 +101 +96 +89 +84 +79 +74 +69 +65 +61 +58 +54 +50 +47 +45 +42 +40 +38 +36 +33 +32 +30 +30 +28 +26 +-58 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +42 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +125 +116 +109 +102 +95 +88 +83 +78 +73 +68 +64 +61 +57 +53 +50 +47 +45 +42 +40 +38 +36 +33 +32 +30 +29 +27 +26 +25 +24 +-60 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-119 +-109 +-100 +-93 +-85 +-77 +-71 +-66 +-61 +-55 +-48 +-44 +-40 +-36 +-32 +-29 +-26 +-24 +-20 +-17 +-15 +-14 +-12 +-10 +-9 +-7 +-5 +-3 +-1 +-1 +0 +1 +3 +3 +4 +5 +7 +6 +6 +6 +7 +7 +8 +9 +10 +10 +10 +10 +11 +11 +11 +11 +13 +12 +11 +11 +12 +12 +13 +13 +14 +13 +13 +13 +14 +13 +13 +13 +14 +14 +13 +12 +13 +13 +14 +14 +14 +14 +14 +13 +14 +14 +14 +14 +15 +54 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +117 +110 +101 +95 +89 +83 +77 +72 +68 +64 +59 +57 +53 +50 +47 +45 +42 +40 +38 +36 +35 +33 +30 +29 +28 +27 +25 +24 +23 +22 +21 +20 +19 +19 +18 +17 +16 +16 +15 +15 +14 +14 +13 +13 +13 +13 +12 +12 +12 +12 +11 +11 +11 +11 +10 +10 +10 +10 +-65 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-120 +-110 +-101 +-93 +-85 +-78 +-72 +-67 +-61 +-55 +-49 +-45 +-41 +-36 +-32 +-29 +-27 +-24 +-20 +-18 +-16 +25 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +82 +-16 +-104 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +68 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +61 +-35 +-121 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +65 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +60 +-36 +-122 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-117 +-107 +-98 +-90 +-83 +-76 +-70 +-63 +-59 +-54 +-49 +-43 +-39 +-35 +-32 +-29 +-26 +-23 +-21 +-18 +-15 +-12 +-11 +-10 +-9 +-6 +-4 +-2 +-2 +0 +1 +1 +2 +3 +4 +5 +5 +7 +7 +7 +7 +8 +9 +9 +9 +11 +11 +11 +10 +11 +12 +12 +12 +13 +52 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +80 +-18 +-105 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +69 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +61 +-35 +-120 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-117 +-108 +-99 +-90 +-83 +-76 +-70 +-64 +-59 +-53 +-48 +-44 +-39 +-34 +-31 +-28 +-26 +-23 +-19 +-16 +-14 +-11 +-10 +-9 +-9 +-7 +-6 +-3 +-2 +-1 +1 +2 +2 +3 +4 +5 +5 +6 +7 +7 +6 +7 +8 +9 +9 +10 +10 +11 +10 +11 +12 +12 +12 +12 +51 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +81 +-17 +-105 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +70 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +126 +117 +110 +102 +97 +90 +84 +79 +75 +69 +65 +61 +58 +54 +51 +48 +46 +43 +40 +37 +36 +34 +32 +30 +29 +28 +27 +25 +24 +-59 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-118 +-109 +-100 +-92 +-85 +-77 +-71 +-67 +-61 +-54 +-49 +-45 +-40 +-36 +-32 +-30 +-27 +-24 +-20 +-18 +-16 +25 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +80 +-18 +-105 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +69 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +126 +118 +112 +104 +97 +90 +85 +79 +74 +69 +65 +60 +57 +53 +51 +47 +45 +43 +40 +37 +36 +35 +33 +31 +30 +28 +27 +25 +24 +-59 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-118 +-109 +-101 +-92 +-84 +-77 +-71 +-66 +-60 +-55 +-49 +-44 +-40 +-37 +-32 +-30 +-26 +-23 +-20 +-18 +-16 +-14 +-11 +-10 +-9 +-8 +-4 +-2 +-1 +-1 +1 +1 +2 +3 +4 +5 +6 +6 +6 +6 +7 +7 +8 +9 +10 +10 +10 +11 +11 +11 +12 +12 +12 +12 +12 +12 +12 +12 +13 +13 +14 +15 +15 +14 +14 +14 +15 +14 +14 +14 +13 +12 +13 +13 +14 +14 +14 +14 +14 +14 +14 +14 +15 +15 +15 +53 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +82 +-16 +-104 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +69 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +59 +-36 +-122 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-117 +-108 +-99 +-90 +-83 +-75 +-70 +-64 +-59 +-54 +-48 +-43 +-39 +-35 +-31 +-28 +-26 +-23 +-20 +-17 +-14 +-12 +-10 +-8 +-8 +-6 +-4 +-3 +-2 +0 +0 +1 +2 +3 +3 +5 +6 +7 +7 +7 +8 +8 +8 +10 +10 +11 +10 +11 +11 +11 +11 +12 +12 +12 +11 +12 +11 +12 +12 +13 +14 +14 +13 +13 +13 +14 +13 +14 +14 +15 +14 +14 +13 +13 +13 +14 +14 +15 +14 +14 +14 +15 +14 +14 +14 +15 +15 +14 +13 +14 +14 +14 +14 +15 +15 +14 +14 +14 +15 +14 +14 +14 +14 +14 +13 +13 +14 +15 +14 +15 +15 +15 +14 +14 +15 +15 +14 +14 +53 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +125 +117 +109 +101 +95 +89 +83 +77 +74 +69 +64 +60 +57 +54 +51 +47 +46 +42 +40 +38 +37 +34 +34 +32 +31 +28 +27 +-57 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +41 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +125 +116 +109 +101 +95 +89 +83 +77 +73 +69 +64 +60 +57 +53 +50 +47 +45 +42 +40 +37 +36 +34 +32 +29 +29 +28 +28 +26 +25 +-59 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +42 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +57 +-38 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +66 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +59 +-37 +-122 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +66 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +118 +111 +102 +96 +90 +85 +79 +74 +69 +65 +61 +58 +54 +51 +49 +46 +43 +41 +38 +37 +34 +32 +31 +29 +27 +26 +25 +25 +-59 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +41 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +124 +115 +109 +101 +95 +88 +83 +78 +73 +68 +64 +60 +56 +52 +50 +47 +44 +41 +40 +37 +35 +33 +32 +30 +29 +28 +27 +25 +24 +-59 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-119 +-109 +-100 +-92 +-85 +-78 +-71 +-65 +-59 +-54 +-48 +-44 +-39 +-36 +-33 +-30 +-26 +-24 +-21 +-18 +-15 +-14 +-12 +-11 +-9 +-7 +-5 +-3 +-1 +0 +0 +1 +2 +3 +4 +4 +5 +6 +7 +7 +8 +9 +10 +10 +11 +10 +10 +10 +11 +10 +11 +12 +12 +12 +13 +11 +11 +12 +14 +14 +14 +14 +15 +14 +14 +14 +15 +14 +14 +14 +14 +12 +12 +13 +14 +14 +14 +14 +14 +13 +13 +13 +14 +14 +14 +53 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +126 +117 +110 +102 +97 +89 +84 +79 +74 +69 +65 +61 +58 +54 +50 +47 +45 +42 +40 +37 +36 +34 +32 +30 +30 +27 +26 +25 +24 +23 +22 +21 +21 +19 +19 +18 +18 +16 +16 +16 +16 +15 +15 +14 +14 +13 +13 +12 +13 +12 +11 +11 +12 +11 +11 +10 +11 +10 +10 +-65 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-120 +-110 +-101 +-93 +-85 +-78 +-72 +-67 +-62 +-56 +-50 +-45 +-41 +-36 +-33 +-30 +-27 +-23 +-20 +-19 +-16 +25 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +80 +-18 +-105 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +70 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +59 +-36 +-122 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +66 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +59 +-37 +-122 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-117 +-107 +-98 +-90 +-83 +-76 +-70 +-63 +-59 +-54 +-49 +-43 +-38 +-35 +-32 +-28 +-25 +-22 +-20 +-17 +-14 +-12 +-11 +-9 +-8 +-6 +-5 +-3 +-1 +0 +0 +2 +3 +4 +4 +5 +6 +7 +6 +7 +7 +8 +9 +10 +11 +11 +10 +11 +10 +10 +11 +11 +11 +12 +51 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +82 +-16 +-104 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +69 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +60 +-36 +-122 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-117 +-107 +-98 +-90 +-83 +-76 +-69 +-63 +-58 +-53 +-48 +-43 +-39 +-34 +-32 +-29 +-26 +-22 +-20 +-17 +-15 +-12 +28 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +81 +-17 +-105 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-115 +-106 +-97 +-89 +-81 +-75 +-69 +-63 +-58 +-53 +-48 +-43 +-38 +-34 +-31 +-28 +-25 +-21 +-19 +-17 +-15 +-12 +28 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +125 +116 +110 +102 +96 +89 +84 +79 +74 +68 +64 +60 +58 +54 +52 +49 +46 +43 +41 +38 +36 +33 +32 +29 +28 +27 +26 +24 +23 +23 +22 +20 +20 +20 +19 +18 +17 +17 +17 +15 +15 +15 +15 +14 +14 +13 +13 +12 +13 +12 +11 +11 +12 +11 +11 +11 +11 +10 +10 +10 +10 +9 +10 +10 +10 +9 +9 +10 +9 +9 +10 +10 +9 +9 +10 +9 +9 +9 +9 +10 +10 +9 +9 +9 +9 +9 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +9 +9 +9 +9 +9 +9 +9 +9 +9 +9 +9 +8 +8 +9 +9 +9 +8 +9 +9 +8 +8 +9 +8 +8 +8 +8 +8 +8 +8 +9 +8 +8 +8 +9 +8 +8 +8 +9 +8 +8 +9 +8 +8 +9 +9 +9 +8 +8 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +8 +8 +8 +9 +8 +9 +9 +9 +8 +9 +9 +9 +9 +9 +9 +10 +9 +9 +9 +10 +9 +9 +9 +9 +9 +9 +8 +9 +8 +8 +8 +9 +8 +8 +8 +9 +8 +8 +8 +9 +8 +8 +8 +9 +8 +8 +8 +9 +8 +8 +8 +9 +9 +9 +8 +10 +9 +9 +9 +9 +8 +8 +8 +9 +9 +9 +9 +9 +9 +9 +9 +10 +9 +9 +8 +9 +8 +8 +8 +9 +8 +8 +8 +9 +9 +9 +8 +9 +9 +9 +9 +9 +9 +9 +9 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +9 +10 +9 +9 +9 +9 +9 +9 +8 +9 +9 +10 +10 +10 +9 +9 +9 +8 +8 +8 +8 +8 +8 +8 +8 +8 +8 +8 +8 +9 +8 +8 +8 +9 +8 +8 +8 +9 +9 +9 +9 +9 +9 +9 +9 +9 +8 +9 +9 +9 +8 +8 +8 +9 +8 +8 +9 +9 +8 +9 +9 +9 +-70 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-120 +-110 +-101 +-94 +-86 +-78 +-72 +-67 +-61 +-55 +-50 +-45 +-40 +-36 +-33 +-31 +-27 +-24 +-21 +-19 +-16 +25 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +80 +-18 +-105 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-114 +-104 +-96 +-89 +-81 +-75 +-69 +-63 +-58 +-53 +-48 +-42 +-38 +-34 +-31 +-27 +-25 +-22 +-19 +-16 +-14 +-12 +-11 +-9 +-7 +-6 +-5 +-2 +0 +1 +1 +2 +3 +4 +4 +5 +6 +6 +6 +7 +7 +7 +8 +9 +10 +10 +10 +10 +11 +11 +10 +11 +12 +13 +12 +12 +11 +12 +12 +13 +13 +14 +13 +13 +12 +13 +14 +14 +13 +13 +14 +14 +14 +14 +14 +14 +15 +15 +14 +14 +14 +14 +14 +15 +14 +14 +14 +15 +13 +13 +14 +15 +14 +15 +15 +15 +14 +14 +15 +16 +15 +15 +15 +15 +13 +13 +14 +15 +15 +15 +15 +15 +14 +14 +15 +15 +14 +15 +15 +15 +13 +13 +14 +15 +15 +15 +15 +15 +14 +14 +14 +15 +15 +15 +14 +15 +13 +13 +13 +15 +14 +14 +14 +15 +14 +14 +14 +15 +15 +15 +53 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +82 +-16 +-104 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-114 +-104 +-96 +-88 +-81 +-74 +-68 +-63 +-58 +-53 +-48 +-43 +-38 +-34 +-31 +-28 +-25 +-22 +-19 +-17 +-15 +-12 +28 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +80 +-18 +-105 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-115 +-106 +-97 +-89 +-82 +-75 +-68 +-63 +-59 +-53 +-47 +-42 +-39 +-35 +-31 +-28 +-26 +-22 +-19 +-16 +-15 +-13 +28 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +125 +116 +109 +102 +96 +89 +84 +78 +74 +68 +65 +61 +57 +53 +50 +48 +45 +42 +40 +38 +36 +34 +32 +31 +30 +27 +26 +-58 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-119 +-109 +-100 +-92 +-84 +-77 +-71 +-66 +-60 +-54 +-49 +-44 +-40 +-36 +-32 +-30 +-27 +-24 +-20 +-18 +-16 +25 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +81 +-17 +-105 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-115 +-105 +-97 +-90 +-82 +-75 +-68 +-62 +-59 +-54 +-48 +-42 +-38 +-34 +-31 +-28 +-25 +-22 +-19 +-16 +-14 +-11 +-10 +-9 +-8 +-6 +-5 +-3 +-2 +1 +1 +2 +2 +4 +4 +5 +6 +7 +7 +7 +7 +8 +8 +9 +10 +11 +11 +10 +10 +11 +11 +12 +11 +12 +13 +12 +10 +12 +13 +13 +13 +14 +14 +14 +13 +13 +14 +14 +13 +14 +14 +14 +13 +13 +14 +15 +15 +15 +14 +15 +14 +14 +14 +15 +14 +14 +14 +14 +13 +13 +14 +15 +15 +15 +15 +15 +15 +14 +14 +15 +15 +15 +15 +15 +13 +13 +13 +15 +15 +15 +14 +15 +15 +14 +14 +15 +15 +15 +53 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +125 +116 +109 +102 +96 +89 +84 +79 +74 +68 +64 +61 +57 +53 +50 +48 +45 +42 +40 +38 +36 +33 +32 +30 +29 +27 +26 +-58 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +42 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +125 +116 +108 +101 +95 +89 +84 +79 +74 +68 +64 +60 +56 +52 +50 +47 +44 +41 +40 +37 +35 +33 +32 +30 +29 +27 +26 +25 +25 +-58 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-118 +-109 +-99 +-92 +-85 +-78 +-72 +-67 +-61 +-54 +-49 +-44 +-40 +-35 +-32 +-30 +-26 +-23 +-20 +-18 +-16 +-13 +-12 +-11 +-9 +-7 +-4 +-3 +-1 +-1 +0 +1 +1 +2 +4 +4 +5 +5 +6 +6 +6 +7 +9 +9 +10 +10 +11 +10 +10 +11 +12 +11 +12 +12 +12 +11 +11 +12 +14 +13 +13 +13 +14 +13 +13 +13 +14 +14 +14 +13 +14 +13 +13 +13 +15 +15 +15 +14 +15 +15 +15 +14 +15 +15 +15 +53 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +119 +112 +104 +98 +90 +85 +79 +73 +68 +64 +60 +56 +53 +50 +46 +45 +42 +40 +37 +36 +33 +32 +30 +29 +27 +26 +25 +25 +23 +22 +21 +20 +19 +18 +18 +17 +16 +16 +15 +15 +14 +14 +13 +13 +13 +13 +12 +12 +11 +12 +11 +11 +11 +11 +10 +10 +10 +11 +-64 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-120 +-111 +-101 +-93 +-86 +-79 +-72 +-67 +-62 +-56 +-49 +-45 +-41 +-37 +-33 +-30 +-27 +-24 +-21 +-18 +-16 +25 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +81 +-17 +-104 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +69 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +60 +-36 +-121 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +67 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +60 +-35 +-121 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-117 +-107 +-98 +-90 +-83 +-76 +-70 +-64 +-59 +-53 +-48 +-43 +-39 +-34 +-31 +-28 +-26 +-23 +-20 +-17 +-16 +-13 +-11 +-9 +-9 +-7 +-5 +-3 +-2 +0 +1 +2 +2 +3 +4 +5 +5 +6 +7 +8 +7 +7 +8 +10 +10 +10 +10 +11 +11 +11 +11 +12 +12 +12 +51 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +81 +-17 +-105 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +69 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +60 +-36 +-122 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-116 +-107 +-98 +-90 +-83 +-76 +-69 +-64 +-60 +-54 +-48 +-43 +-39 +-35 +-31 +-28 +-26 +-23 +-20 +-17 +-15 +-13 +-11 +-9 +-9 +-7 +-5 +-3 +-2 +0 +1 +2 +2 +3 +4 +5 +6 +6 +6 +7 +7 +8 +9 +10 +10 +11 +11 +11 +11 +11 +11 +11 +12 +12 +51 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +81 +-17 +-104 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +68 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +126 +118 +110 +102 +96 +90 +85 +79 +74 +70 +66 +61 +58 +55 +51 +48 +46 +43 +41 +37 +36 +34 +32 +30 +29 +28 +27 +25 +24 +-59 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-118 +-109 +-100 +-92 +-84 +-78 +-72 +-66 +-60 +-55 +-49 +-44 +-39 +-36 +-33 +-30 +-26 +-24 +-21 +-18 +-15 +25 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +81 +-17 +-105 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +70 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +126 +117 +110 +103 +96 +90 +85 +79 +74 +69 +65 +61 +57 +54 +52 +48 +45 +43 +41 +38 +36 +34 +33 +30 +29 +27 +26 +24 +23 +-60 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-118 +-108 +-99 +-92 +-84 +-77 +-70 +-65 +-60 +-54 +-48 +-44 +-40 +-36 +-32 +-29 +-26 +-23 +-20 +-18 +-15 +-13 +-12 +-11 +-8 +-6 +-4 +-3 +-1 +0 +0 +0 +2 +3 +5 +6 +7 +7 +7 +6 +7 +7 +8 +9 +9 +9 +10 +9 +10 +11 +11 +11 +12 +12 +12 +11 +11 +12 +13 +13 +14 +14 +13 +13 +13 +13 +14 +13 +14 +14 +14 +13 +13 +14 +14 +14 +15 +15 +15 +15 +15 +14 +14 +15 +14 +52 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +81 +-17 +-105 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +69 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +60 +-36 +-121 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-116 +-107 +-99 +-91 +-83 +-75 +-69 +-63 +-58 +-53 +-48 +-43 +-38 +-35 +-32 +-28 +-25 +-22 +-20 +-17 +-15 +-13 +-12 +-10 +-9 +-7 +-5 +-3 +-1 +0 +1 +2 +3 +4 +4 +5 +6 +7 +7 +7 +7 +8 +8 +9 +10 +10 +10 +11 +11 +11 +10 +11 +12 +12 +11 +12 +11 +11 +11 +13 +13 +14 +13 +13 +13 +14 +14 +14 +14 +14 +14 +13 +12 +13 +13 +14 +14 +15 +15 +15 +14 +14 +15 +15 +14 +14 +15 +15 +13 +14 +14 +15 +15 +15 +15 +15 +13 +14 +14 +14 +13 +14 +14 +14 +13 +13 +14 +14 +14 +15 +15 +15 +14 +14 +15 +15 +14 +15 +53 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +126 +117 +110 +102 +96 +89 +84 +78 +74 +69 +65 +61 +58 +54 +51 +48 +46 +43 +42 +39 +38 +35 +33 +31 +29 +27 +26 +-58 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +43 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +124 +115 +109 +101 +95 +88 +83 +78 +74 +68 +64 +61 +57 +53 +50 +47 +45 +42 +39 +37 +36 +33 +31 +30 +29 +27 +26 +24 +24 +-60 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +42 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +57 +-39 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +65 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +59 +-37 +-122 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +65 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +126 +117 +110 +103 +97 +91 +85 +79 +74 +69 +65 +60 +58 +53 +50 +47 +45 +42 +39 +37 +36 +33 +31 +30 +29 +27 +26 +25 +24 +-59 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +42 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +124 +116 +108 +100 +94 +89 +83 +77 +73 +69 +65 +60 +57 +54 +50 +47 +44 +42 +40 +37 +35 +34 +33 +30 +29 +28 +27 +25 +24 +-59 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-119 +-109 +-100 +-92 +-85 +-78 +-71 +-66 +-61 +-55 +-49 +-44 +-39 +-36 +-33 +-29 +-26 +-23 +-20 +-18 +-15 +-13 +-12 +-11 +-9 +-7 +-5 +-4 +-2 +0 +1 +1 +2 +3 +5 +5 +6 +6 +7 +6 +6 +8 +10 +10 +11 +11 +11 +10 +11 +11 +11 +12 +12 +11 +12 +11 +11 +11 +13 +13 +13 +13 +14 +13 +13 +13 +14 +13 +14 +14 +14 +13 +13 +13 +15 +15 +15 +15 +15 +14 +14 +14 +15 +14 +14 +53 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +125 +117 +110 +102 +95 +88 +83 +72 +68 +65 +61 +57 +53 +51 +47 +45 +42 +40 +38 +36 +34 +33 +30 +29 +28 +27 +25 +24 +23 +23 +22 +21 +20 +19 +18 +18 +16 +16 +15 +15 +14 +14 +14 +14 +13 +13 +13 +12 +12 +13 +12 +12 +11 +12 +11 +11 +10 +11 +-64 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-120 +-110 +-100 +-92 +-84 +-78 +-72 +-67 +-61 +-56 +-50 +-45 +-41 +-38 +-33 +-30 +-27 +-24 +-21 +-18 +-16 +25 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +80 +-18 +-105 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +70 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +60 +-36 +-122 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +65 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +59 +-36 +-122 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-116 +-107 +-98 +-90 +-82 +-75 +-69 +-63 +-59 +-54 +-48 +-43 +-39 +-35 +-32 +-28 +-25 +-22 +-20 +-17 +-14 +-12 +-11 +-9 +-9 +-7 +-5 +-4 +-2 +0 +0 +1 +1 +3 +3 +4 +5 +6 +7 +7 +6 +7 +8 +9 +9 +11 +11 +11 +10 +11 +12 +12 +11 +12 +51 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +82 +-16 +-103 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +69 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +61 +-35 +-121 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-117 +-108 +-98 +-90 +-83 +-76 +-70 +-63 +-59 +-54 +-49 +-43 +-38 +-35 +-32 +-28 +-25 +-22 +-20 +-17 +-15 +-12 +28 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +80 +-18 +-106 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-115 +-106 +-98 +-89 +-82 +-74 +-68 +-63 +-58 +-52 +-47 +-43 +-38 +-33 +-30 +-27 +-24 +-21 +-19 +-16 +-15 +-13 +28 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +126 +117 +110 +102 +95 +89 +84 +77 +72 +68 +64 +60 +57 +53 +51 +48 +45 +42 +40 +38 +36 +34 +33 +30 +29 +27 +27 +25 +24 +22 +22 +21 +20 +19 +19 +17 +17 +16 +16 +15 +15 +14 +15 +14 +13 +13 +14 +13 +12 +12 +12 +12 +11 +11 +11 +10 +10 +10 +11 +10 +10 +10 +11 +10 +10 +10 +11 +10 +10 +9 +10 +9 +9 +9 +9 +9 +9 +9 +9 +8 +9 +9 +9 +9 +8 +8 +9 +9 +9 +9 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +8 +8 +9 +8 +8 +8 +9 +8 +8 +8 +9 +9 +8 +8 +9 +9 +8 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +8 +8 +9 +8 +8 +8 +9 +8 +9 +9 +10 +9 +9 +9 +10 +10 +11 +10 +10 +9 +9 +8 +8 +8 +8 +8 +8 +8 +8 +8 +8 +8 +9 +8 +8 +9 +9 +8 +9 +9 +9 +8 +9 +9 +8 +8 +8 +8 +9 +8 +8 +9 +9 +8 +9 +9 +9 +8 +8 +8 +9 +8 +8 +8 +9 +8 +8 +8 +9 +8 +8 +8 +9 +9 +8 +8 +9 +9 +10 +10 +10 +9 +9 +9 +8 +8 +8 +8 +8 +9 +9 +8 +9 +9 +9 +8 +9 +9 +8 +8 +9 +8 +8 +8 +9 +9 +9 +9 +10 +9 +9 +9 +10 +9 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +9 +9 +9 +9 +9 +9 +9 +9 +8 +8 +9 +9 +8 +8 +8 +9 +8 +8 +8 +8 +8 +8 +8 +8 +8 +8 +8 +9 +8 +8 +8 +9 +9 +10 +10 +9 +8 +9 +8 +8 +8 +8 +8 +8 +8 +8 +8 +8 +8 +8 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +9 +9 +9 +10 +9 +9 +9 +9 +9 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +8 +8 +9 +9 +8 +8 +9 +9 +8 +9 +9 +9 +9 +9 +9 +9 +9 +9 +9 +9 +9 +10 +10 +11 +11 +11 +9 +10 +8 +8 +-70 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-119 +-110 +-101 +-93 +-85 +-79 +-73 +-67 +-61 +-55 +-50 +-45 +-40 +-37 +-34 +-31 +-27 +-24 +-21 +-19 +-16 +25 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +81 +-17 +-105 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-116 +-106 +-97 +-89 +-82 +-75 +-68 +-62 +-58 +-53 +-48 +-42 +-38 +-35 +-32 +-28 +-25 +-22 +-20 +-17 +-15 +-12 +-10 +-9 +-8 +-6 +-4 +-2 +-1 +0 +2 +3 +2 +4 +5 +6 +6 +7 +7 +8 +7 +7 +8 +10 +10 +10 +11 +11 +10 +11 +11 +12 +12 +12 +12 +12 +11 +11 +12 +13 +13 +14 +14 +14 +13 +13 +13 +14 +14 +14 +14 +15 +13 +13 +13 +15 +15 +15 +14 +15 +15 +14 +14 +15 +15 +15 +14 +14 +13 +13 +13 +14 +15 +15 +15 +14 +14 +15 +14 +14 +14 +15 +14 +14 +13 +14 +14 +14 +14 +15 +15 +14 +14 +14 +15 +15 +14 +15 +15 +14 +13 +13 +14 +15 +14 +15 +15 +15 +14 +14 +15 +15 +14 +14 +15 +14 +13 +13 +14 +15 +15 +15 +15 +15 +14 +14 +14 +15 +14 +15 +53 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +81 +-17 +-105 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-116 +-106 +-97 +-88 +-82 +-75 +-68 +-62 +-57 +-51 +-46 +-41 +-38 +-33 +-31 +-28 +-26 +-23 +-21 +-17 +-15 +-13 +28 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +80 +-18 +-106 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-113 +-104 +-97 +-89 +-82 +-75 +-69 +-63 +-59 +-54 +-48 +-43 +-38 +-34 +-31 +-27 +-25 +-22 +-20 +-16 +-14 +-13 +28 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +126 +117 +110 +102 +95 +89 +84 +78 +73 +68 +65 +60 +57 +54 +51 +47 +45 +42 +40 +37 +36 +34 +32 +29 +28 +27 +27 +-57 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-119 +-109 +-100 +-92 +-84 +-77 +-70 +-66 +-61 +-55 +-48 +-44 +-39 +-36 +-32 +-29 +-26 +-23 +-20 +-18 +-15 +26 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +82 +-17 +-104 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-114 +-106 +-98 +-89 +-81 +-75 +-69 +-63 +-58 +-53 +-48 +-43 +-38 +-34 +-31 +-28 +-25 +-22 +-19 +-17 +-15 +-12 +-10 +-9 +-9 +-6 +-4 +-3 +-2 +0 +1 +2 +2 +4 +4 +5 +5 +7 +7 +7 +6 +7 +8 +8 +9 +10 +10 +10 +10 +11 +11 +11 +12 +13 +13 +12 +10 +11 +12 +13 +13 +14 +13 +13 +13 +14 +13 +13 +13 +14 +14 +14 +12 +12 +13 +15 +14 +14 +14 +15 +14 +14 +14 +15 +14 +14 +15 +15 +14 +13 +14 +15 +15 +15 +15 +15 +15 +14 +14 +15 +15 +15 +15 +15 +14 +13 +13 +15 +15 +15 +14 +14 +15 +15 +14 +14 +14 +15 +53 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +126 +117 +111 +103 +98 +92 +86 +79 +74 +69 +65 +60 +57 +52 +50 +47 +44 +41 +40 +37 +36 +33 +33 +30 +29 +27 +27 +-57 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +43 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +125 +116 +108 +100 +95 +89 +84 +77 +73 +68 +65 +61 +57 +53 +51 +48 +46 +42 +40 +37 +36 +33 +31 +30 +29 +26 +26 +25 +24 +-60 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-119 +-109 +-101 +-93 +-85 +-78 +-72 +-67 +-60 +-54 +-49 +-45 +-40 +-35 +-32 +-30 +-26 +-23 +-19 +-17 +-15 +-13 +-11 +-11 +-9 +-6 +-4 +-3 +-2 +0 +1 +2 +2 +3 +4 +5 +5 +6 +7 +6 +6 +8 +9 +9 +10 +10 +10 +9 +10 +11 +12 +11 +12 +12 +12 +11 +11 +12 +13 +13 +13 +13 +14 +13 +13 +13 +14 +14 +13 +13 +14 +12 +12 +13 +14 +15 +15 +14 +14 +14 +15 +14 +14 +14 +15 +53 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +126 +117 +109 +102 +96 +90 +85 +80 +76 +70 +66 +61 +58 +53 +50 +47 +44 +41 +40 +37 +35 +33 +32 +30 +29 +28 +27 +25 +24 +23 +22 +21 +20 +20 +19 +18 +18 +17 +16 +15 +15 +14 +14 +13 +13 +13 +12 +12 +13 +12 +11 +11 +12 +11 +11 +10 +11 +11 +11 +-64 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-121 +-111 +-102 +-94 +-86 +-78 +-72 +-67 +-61 +-55 +-50 +-45 +-40 +-37 +-34 +-31 +-26 +-24 +-21 +-19 +-15 +25 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +80 +-18 +-105 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +68 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +59 +-37 +-122 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +66 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +59 +-37 +-122 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-117 +-108 +-99 +-90 +-83 +-76 +-69 +-64 +-60 +-54 +-48 +-44 +-40 +-35 +-32 +-29 +-26 +-23 +-20 +-17 +-15 +-13 +-11 +-9 +-9 +-7 +-5 +-2 +-1 +0 +1 +2 +2 +3 +4 +6 +6 +6 +7 +8 +7 +7 +8 +10 +10 +10 +10 +11 +11 +11 +11 +12 +12 +12 +51 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +81 +-18 +-105 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +70 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +61 +-35 +-121 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-116 +-106 +-98 +-90 +-83 +-75 +-69 +-64 +-60 +-54 +-48 +-43 +-39 +-35 +-32 +-28 +-26 +-23 +-21 +-18 +-15 +-13 +-12 +-10 +-9 +-7 +-5 +-3 +-2 +0 +1 +1 +2 +3 +4 +5 +5 +6 +7 +7 +6 +7 +8 +9 +9 +10 +11 +11 +10 +11 +11 +12 +12 +12 +51 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +80 +-18 +-105 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +69 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +119 +112 +104 +97 +90 +85 +79 +74 +69 +65 +60 +58 +55 +52 +48 +45 +43 +40 +37 +36 +34 +32 +30 +29 +28 +26 +24 +24 +-59 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-119 +-109 +-100 +-93 +-85 +-77 +-71 +-66 +-60 +-55 +-49 +-44 +-40 +-36 +-32 +-29 +-26 +-23 +-20 +-18 +-16 +25 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +81 +-17 +-105 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +69 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +118 +111 +103 +97 +90 +84 +78 +74 +69 +65 +61 +58 +54 +51 +48 +45 +42 +40 +37 +36 +34 +32 +30 +29 +28 +26 +25 +24 +-59 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-119 +-109 +-100 +-93 +-85 +-78 +-71 +-66 +-60 +-55 +-49 +-43 +-39 +-36 +-32 +-29 +-25 +-23 +-20 +-18 +-15 +-13 +-12 +-11 +-9 +-6 +-5 +-3 +-2 +0 +0 +1 +2 +3 +4 +4 +6 +7 +7 +5 +6 +8 +9 +10 +11 +11 +11 +11 +11 +11 +11 +11 +12 +11 +11 +11 +11 +11 +13 +13 +13 +13 +14 +14 +13 +13 +14 +14 +14 +14 +14 +13 +13 +13 +14 +15 +15 +14 +14 +14 +14 +14 +14 +15 +14 +53 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +82 +-16 +-104 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +69 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +61 +-35 +-121 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-116 +-106 +-98 +-91 +-84 +-76 +-69 +-64 +-59 +-54 +-49 +-43 +-39 +-35 +-32 +-28 +-26 +-23 +-20 +-17 +-15 +-13 +-11 +-9 +-9 +-7 +-5 +-2 +-1 +0 +1 +3 +3 +4 +5 +6 +6 +6 +7 +8 +7 +7 +8 +10 +10 +10 +10 +11 +11 +11 +11 +12 +12 +12 +12 +12 +12 +11 +12 +13 +14 +14 +13 +13 +13 +14 +13 +14 +14 +14 +14 +14 +13 +14 +15 +16 +16 +16 +15 +15 +14 +14 +14 +14 +14 +14 +14 +14 +12 +13 +14 +14 +14 +15 +14 +14 +14 +15 +14 +14 +14 +15 +14 +14 +13 +13 +14 +14 +14 +15 +14 +14 +14 +15 +14 +14 +14 +15 +53 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +126 +117 +111 +103 +97 +90 +84 +79 +74 +68 +64 +61 +57 +53 +50 +47 +45 +41 +40 +38 +36 +33 +32 +30 +29 +27 +26 +-57 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +41 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +125 +116 +109 +101 +96 +88 +83 +78 +74 +68 +64 +60 +57 +53 +50 +47 +45 +42 +40 +37 +36 +34 +32 +30 +29 +28 +27 +25 +24 +-59 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +42 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +57 +-39 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +64 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +59 +-37 +-122 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +66 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +126 +117 +110 +101 +95 +89 +84 +78 +73 +69 +65 +60 +57 +54 +52 +49 +45 +42 +41 +38 +36 +34 +33 +31 +30 +28 +26 +25 +24 +-60 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +43 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +125 +117 +109 +101 +95 +88 +82 +77 +72 +67 +63 +59 +56 +52 +49 +47 +44 +41 +40 +38 +36 +33 +32 +31 +29 +27 +26 +25 +24 +-60 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-119 +-109 +-100 +-92 +-84 +-78 +-71 +-66 +-60 +-55 +-49 +-44 +-39 +-36 +-33 +-30 +-26 +-23 +-20 +-18 +-15 +-13 +-11 +-11 +-9 +-6 +-4 +-3 +-2 +0 +0 +0 +2 +3 +4 +4 +5 +6 +7 +5 +6 +7 +9 +9 +10 +10 +11 +10 +10 +11 +12 +12 +12 +12 +13 +11 +11 +12 +13 +14 +14 +13 +13 +13 +13 +13 +13 +14 +14 +13 +13 +13 +13 +13 +14 +14 +15 +14 +14 +14 +15 +14 +14 +14 +15 +54 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +126 +117 +110 +103 +97 +90 +84 +78 +74 +69 +65 +60 +57 +54 +50 +47 +44 +42 +39 +36 +35 +34 +32 +30 +29 +28 +27 +25 +24 +23 +22 +20 +20 +19 +18 +17 +17 +17 +16 +15 +15 +14 +14 +14 +14 +13 +13 +13 +13 +11 +12 +12 +11 +11 +11 +11 +10 +10 +11 +-64 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-121 +-111 +-101 +-93 +-86 +-78 +-71 +-66 +-61 +-55 +-49 +-44 +-40 +-37 +-33 +-30 +-27 +-24 +-21 +-18 +-16 +25 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +81 +-17 +-105 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +71 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +59 +-36 +-122 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +66 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +61 +-35 +-121 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-117 +-107 +-97 +-89 +-82 +-75 +-69 +-63 +-60 +-54 +-49 +-43 +-40 +-35 +-31 +-28 +-26 +-23 +-20 +-17 +-15 +-13 +-11 +-9 +-9 +-7 +-5 +-2 +-2 +0 +1 +2 +3 +4 +4 +6 +6 +7 +7 +7 +7 +7 +7 +9 +10 +10 +10 +11 +11 +10 +11 +12 +12 +12 +51 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +83 +-16 +-103 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +69 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +60 +-36 +-122 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-117 +-108 +-99 +-90 +-83 +-76 +-69 +-63 +-59 +-54 +-49 +-43 +-39 +-35 +-32 +-28 +-26 +-23 +-21 +-18 +-15 +-13 +27 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +81 +-17 +-105 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-114 +-105 +-97 +-89 +-81 +-74 +-68 +-62 +-58 +-52 +-47 +-43 +-39 +-34 +-31 +-28 +-25 +-22 +-19 +-17 +-15 +-12 +29 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +125 +117 +109 +101 +95 +89 +84 +78 +73 +69 +66 +62 +59 +55 +52 +48 +45 +42 +39 +36 +35 +32 +31 +30 +28 +26 +26 +25 +24 +23 +22 +21 +20 +19 +19 +18 +17 +16 +16 +15 +15 +14 +14 +13 +13 +12 +13 +12 +12 +12 +13 +12 +11 +11 +12 +11 +11 +11 +11 +10 +10 +10 +10 +10 +10 +10 +10 +9 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +10 +10 +11 +11 +10 +9 +9 +9 +8 +8 +8 +8 +8 +8 +8 +8 +9 +8 +8 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +9 +9 +9 +9 +9 +9 +9 +8 +8 +9 +8 +8 +8 +9 +8 +8 +8 +8 +8 +8 +8 +9 +9 +8 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +9 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +8 +8 +9 +8 +8 +8 +8 +8 +8 +8 +8 +9 +8 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +9 +9 +9 +9 +9 +9 +8 +8 +8 +9 +8 +8 +8 +9 +8 +9 +9 +10 +9 +9 +9 +10 +9 +9 +9 +9 +9 +8 +8 +9 +9 +9 +8 +9 +9 +10 +10 +11 +10 +10 +9 +9 +8 +9 +8 +8 +8 +8 +8 +9 +9 +8 +8 +9 +9 +9 +9 +9 +8 +9 +9 +9 +8 +8 +8 +9 +8 +8 +8 +9 +8 +8 +8 +9 +8 +8 +8 +9 +8 +8 +8 +9 +8 +8 +8 +9 +9 +9 +8 +9 +8 +8 +8 +9 +9 +10 +10 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +8 +9 +10 +9 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +8 +8 +8 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +9 +9 +9 +9 +8 +9 +8 +8 +8 +8 +8 +8 +8 +9 +9 +9 +8 +9 +-70 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-119 +-110 +-101 +-93 +-85 +-78 +-72 +-67 +-61 +-55 +-49 +-45 +-41 +-37 +-33 +-30 +-27 +-24 +-20 +-18 +-16 +25 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +80 +-18 +-105 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-115 +-105 +-97 +-89 +-82 +-74 +-68 +-62 +-58 +-53 +-47 +-43 +-39 +-34 +-31 +-28 +-25 +-22 +-19 +-16 +-15 +-13 +-11 +-8 +-8 +-7 +-5 +-2 +-1 +0 +1 +2 +3 +4 +4 +5 +6 +7 +7 +7 +7 +8 +8 +9 +10 +11 +11 +11 +10 +11 +12 +13 +13 +13 +13 +13 +12 +12 +12 +14 +13 +13 +13 +14 +13 +13 +14 +14 +14 +14 +14 +14 +13 +13 +13 +14 +14 +14 +14 +15 +14 +14 +14 +14 +14 +14 +14 +14 +12 +13 +14 +15 +14 +15 +15 +14 +14 +15 +14 +14 +14 +15 +15 +14 +13 +13 +14 +15 +15 +15 +15 +15 +14 +14 +14 +15 +15 +14 +14 +15 +14 +14 +15 +15 +15 +15 +14 +14 +14 +14 +14 +14 +14 +15 +14 +14 +14 +14 +13 +14 +15 +15 +14 +14 +14 +14 +14 +15 +15 +15 +53 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +80 +-18 +-105 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-113 +-104 +-97 +-88 +-81 +-74 +-69 +-62 +-58 +-53 +-48 +-42 +-38 +-34 +-31 +-27 +-24 +-22 +-20 +-17 +-14 +-12 +28 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +80 +-18 +-106 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-115 +-106 +-97 +-89 +-81 +-75 +-69 +-63 +-58 +-53 +-48 +-43 +-39 +-34 +-31 +-28 +-26 +-22 +-19 +-17 +-15 +-12 +29 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +125 +116 +109 +102 +96 +90 +84 +78 +74 +69 +66 +62 +59 +54 +51 +48 +45 +41 +39 +37 +35 +33 +32 +30 +28 +27 +27 +-57 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-118 +-108 +-100 +-92 +-84 +-77 +-71 +-66 +-60 +-54 +-49 +-44 +-40 +-35 +-32 +-30 +-26 +-23 +-20 +-18 +-16 +26 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +80 +-18 +-105 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-115 +-105 +-97 +-89 +-82 +-75 +-68 +-63 +-59 +-53 +-48 +-42 +-38 +-34 +-31 +-28 +-25 +-22 +-19 +-17 +-15 +-12 +-10 +-9 +-9 +-6 +-4 +-2 +-1 +0 +1 +2 +2 +3 +4 +6 +5 +6 +6 +7 +6 +6 +7 +10 +10 +10 +10 +11 +11 +11 +11 +13 +12 +12 +12 +13 +11 +11 +12 +14 +14 +14 +14 +15 +14 +14 +14 +15 +14 +14 +14 +14 +13 +13 +13 +14 +14 +14 +14 +15 +14 +14 +14 +15 +14 +14 +14 +15 +13 +13 +14 +15 +14 +15 +15 +15 +14 +14 +14 +15 +14 +14 +14 +14 +12 +13 +14 +15 +14 +15 +15 +15 +14 +14 +15 +15 +14 +14 +53 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +118 +111 +102 +96 +89 +83 +77 +73 +68 +64 +60 +57 +53 +50 +47 +45 +42 +40 +38 +36 +33 +32 +31 +29 +27 +26 +-57 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +43 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +124 +116 +109 +101 +94 +88 +83 +77 +72 +68 +64 +60 +56 +53 +51 +48 +45 +42 +40 +37 +36 +33 +32 +30 +29 +27 +26 +25 +23 +-60 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-119 +-109 +-101 +-93 +-84 +-77 +-70 +-65 +-59 +-53 +-47 +-43 +-39 +-36 +-33 +-30 +-27 +-24 +-20 +-18 +-16 +-14 +-11 +-11 +-9 +-7 +-4 +-2 +0 +1 +2 +1 +3 +3 +4 +4 +5 +5 +6 +5 +6 +7 +8 +9 +9 +10 +10 +10 +10 +11 +12 +11 +12 +12 +13 +11 +11 +11 +13 +13 +13 +13 +14 +13 +13 +13 +14 +14 +14 +13 +14 +13 +13 +13 +14 +15 +15 +14 +15 +14 +14 +14 +14 +15 +15 +53 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +126 +117 +109 +102 +96 +89 +84 +79 +74 +69 +66 +61 +57 +53 +50 +46 +44 +41 +39 +36 +35 +34 +32 +30 +29 +28 +26 +25 +24 +23 +22 +20 +20 +19 +18 +17 +17 +16 +16 +15 +15 +14 +14 +13 +14 +13 +13 +12 +13 +12 +12 +11 +12 +11 +11 +10 +11 +10 +10 +-64 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-121 +-111 +-102 +-94 +-86 +-79 +-72 +-68 +-61 +-55 +-50 +-45 +-40 +-36 +-33 +-30 +-26 +-24 +-21 +-19 +-15 +25 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +79 +-19 +-106 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +70 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +60 +-36 +-121 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +66 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +59 +-37 +-122 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-117 +-108 +-99 +-90 +-83 +-76 +-70 +-63 +-59 +-54 +-49 +-43 +-38 +-34 +-32 +-28 +-25 +-22 +-20 +-17 +-15 +-12 +-11 +-10 +-9 +-6 +-5 +-3 +-2 +0 +1 +1 +2 +4 +4 +5 +5 +6 +7 +7 +6 +7 +8 +9 +9 +10 +11 +11 +10 +11 +12 +12 +11 +12 +52 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +81 +-17 +-105 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +68 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +61 +-35 +-121 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-117 +-108 +-98 +-90 +-84 +-76 +-70 +-63 +-59 +-54 +-49 +-43 +-38 +-34 +-30 +-28 +-26 +-22 +-19 +-17 +-16 +-13 +-11 +-10 +-9 +-7 +-5 +-3 +-2 +1 +1 +1 +2 +4 +4 +5 +5 +7 +6 +7 +6 +7 +8 +9 +10 +11 +10 +10 +11 +12 +11 +12 +12 +13 +51 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +81 +-17 +-104 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +70 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +118 +111 +103 +97 +90 +85 +79 +74 +69 +66 +61 +57 +54 +52 +48 +45 +43 +41 +39 +37 +34 +33 +31 +30 +28 +27 +25 +24 +-59 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-119 +-109 +-100 +-93 +-85 +-77 +-71 +-66 +-61 +-55 +-48 +-44 +-40 +-36 +-32 +-29 +-27 +-24 +-20 +-18 +-16 +25 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +81 +-17 +-105 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +69 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +118 +111 +104 +98 +91 +85 +79 +75 +70 +66 +61 +58 +55 +52 +49 +47 +43 +40 +38 +36 +33 +32 +30 +29 +27 +27 +25 +24 +-60 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-119 +-109 +-99 +-91 +-84 +-77 +-71 +-65 +-60 +-54 +-49 +-44 +-40 +-36 +-32 +-30 +-26 +-23 +-20 +-18 +-16 +-14 +-11 +-11 +-9 +-7 +-4 +-3 +-2 +-1 +1 +1 +2 +3 +4 +5 +5 +6 +7 +6 +7 +8 +9 +10 +11 +10 +10 +11 +11 +11 +11 +11 +12 +12 +13 +11 +11 +12 +14 +14 +14 +14 +14 +13 +13 +13 +14 +14 +14 +13 +14 +12 +12 +13 +14 +14 +14 +14 +14 +14 +14 +13 +14 +14 +14 +52 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +81 +-17 +-105 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +69 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +60 +-36 +-121 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-116 +-106 +-97 +-90 +-83 +-75 +-69 +-64 +-59 +-53 +-48 +-44 +-39 +-35 +-31 +-28 +-25 +-23 +-19 +-17 +-15 +-13 +-10 +-9 +-9 +-7 +-5 +-3 +-2 +0 +1 +2 +2 +3 +4 +5 +5 +6 +7 +7 +6 +7 +8 +9 +9 +10 +11 +11 +10 +11 +11 +11 +11 +12 +12 +12 +11 +12 +12 +13 +13 +14 +14 +13 +13 +14 +14 +14 +14 +14 +14 +14 +12 +13 +14 +14 +14 +14 +14 +15 +13 +14 +14 +15 +14 +14 +14 +15 +13 +13 +13 +15 +15 +15 +14 +14 +14 +14 +14 +15 +15 +15 +14 +15 +14 +13 +13 +15 +15 +15 +14 +15 +15 +15 +14 +15 +15 +14 +53 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +118 +110 +102 +96 +89 +83 +77 +73 +68 +64 +60 +57 +54 +51 +47 +45 +42 +40 +37 +35 +34 +32 +30 +29 +27 +26 +-58 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +43 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +125 +116 +109 +101 +95 +89 +83 +77 +73 +68 +64 +60 +57 +53 +50 +47 +45 +42 +39 +37 +36 +33 +31 +30 +29 +27 +26 +24 +24 +-59 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +41 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +57 +-39 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +66 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +60 +-35 +-121 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +67 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +119 +111 +103 +96 +90 +85 +79 +74 +69 +65 +61 +58 +54 +51 +48 +46 +43 +40 +37 +36 +33 +32 +30 +29 +27 +26 +25 +24 +-60 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +43 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +125 +117 +109 +101 +96 +89 +83 +78 +73 +68 +64 +60 +57 +53 +50 +47 +45 +41 +39 +37 +36 +33 +31 +30 +29 +27 +26 +25 +24 +-59 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-118 +-108 +-100 +-92 +-85 +-78 +-72 +-67 +-61 +-55 +-49 +-45 +-40 +-36 +-32 +-30 +-26 +-23 +-20 +-18 +-16 +-13 +-11 +-11 +-9 +-7 +-4 +-3 +-2 +-1 +1 +1 +2 +3 +5 +5 +6 +6 +7 +6 +7 +7 +9 +9 +10 +9 +10 +10 +11 +10 +11 +11 +12 +11 +11 +11 +11 +11 +12 +13 +13 +12 +13 +13 +13 +13 +13 +14 +14 +13 +13 +13 +13 +13 +14 +14 +15 +14 +14 +14 +14 +14 +14 +15 +15 +53 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +125 +116 +109 +102 +96 +89 +84 +79 +75 +69 +65 +61 +58 +54 +51 +47 +46 +43 +40 +37 +36 +34 +32 +30 +29 +28 +26 +24 +24 +23 +22 +20 +20 +19 +18 +17 +17 +16 +16 +15 +15 +14 +14 +14 +14 +13 +13 +13 +13 +13 +13 +12 +12 +11 +11 +10 +10 +11 +11 +-64 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-120 +-111 +-102 +-93 +-85 +-78 +-72 +-67 +-61 +-55 +-49 +-45 +-41 +-37 +-32 +-29 +-25 +-22 +-20 +-18 +-15 +25 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +80 +-18 +-106 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +69 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +61 +-35 +-121 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +65 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +60 +-36 +-122 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-117 +-108 +-99 +-90 +-82 +-76 +-69 +-63 +-59 +-54 +-49 +-43 +-39 +-35 +-32 +-28 +-25 +-22 +-21 +-18 +-15 +-13 +-12 +-10 +-9 +-7 +-5 +-3 +-2 +0 +1 +1 +2 +4 +4 +5 +5 +7 +7 +7 +6 +7 +9 +10 +10 +11 +11 +11 +10 +11 +12 +12 +12 +12 +52 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +81 +-17 +-104 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +70 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +61 +-35 +-121 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-116 +-107 +-98 +-90 +-82 +-75 +-70 +-64 +-60 +-54 +-49 +-44 +-39 +-35 +-31 +-28 +-26 +-23 +-19 +-16 +-15 +-13 +28 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +79 +-19 +-106 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-115 +-105 +-97 +-89 +-82 +-74 +-68 +-63 +-59 +-53 +-47 +-42 +-38 +-34 +-31 +-27 +-25 +-22 +-19 +-16 +-14 +-13 +28 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +125 +116 +109 +102 +95 +88 +83 +78 +74 +68 +64 +60 +57 +54 +52 +49 +46 +43 +41 +38 +36 +33 +33 +30 +29 +28 +27 +25 +24 +23 +23 +22 +21 +19 +19 +19 +18 +16 +16 +15 +15 +14 +14 +13 +13 +13 +13 +12 +12 +12 +13 +12 +12 +11 +11 +11 +11 +11 +11 +10 +10 +10 +10 +10 +10 +9 +10 +10 +10 +9 +9 +9 +9 +8 +9 +9 +10 +10 +9 +9 +9 +8 +8 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +8 +8 +9 +9 +8 +8 +10 +9 +9 +9 +9 +8 +8 +9 +9 +8 +8 +8 +8 +8 +8 +8 +8 +8 +8 +8 +8 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +10 +10 +10 +9 +9 +9 +8 +8 +9 +8 +8 +8 +9 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +9 +9 +9 +9 +8 +9 +8 +9 +8 +8 +8 +9 +8 +8 +8 +9 +8 +8 +8 +9 +9 +8 +8 +9 +8 +8 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +8 +8 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +8 +8 +9 +8 +9 +9 +9 +8 +9 +8 +9 +8 +8 +8 +9 +8 +9 +9 +9 +8 +8 +9 +9 +8 +8 +9 +9 +8 +8 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +9 +10 +10 +9 +8 +9 +8 +8 +8 +8 +8 +9 +8 +8 +9 +9 +9 +9 +9 +9 +9 +9 +9 +8 +8 +9 +9 +8 +8 +9 +8 +8 +8 +9 +9 +9 +9 +9 +9 +9 +9 +9 +8 +9 +8 +8 +8 +9 +8 +8 +8 +9 +8 +8 +8 +9 +8 +8 +8 +9 +9 +9 +9 +10 +9 +9 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +8 +8 +8 +8 +8 +8 +8 +8 +8 +8 +9 +9 +8 +9 +9 +9 +8 +9 +9 +9 +9 +9 +9 +9 +8 +8 +9 +9 +8 +8 +9 +10 +10 +10 +-68 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-120 +-110 +-101 +-93 +-86 +-78 +-71 +-67 +-61 +-56 +-49 +-44 +-40 +-37 +-33 +-29 +-27 +-24 +-21 +-18 +-15 +25 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +80 +-18 +-105 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-115 +-106 +-98 +-89 +-81 +-75 +-69 +-63 +-58 +-53 +-48 +-43 +-38 +-34 +-31 +-28 +-25 +-22 +-20 +-17 +-15 +-12 +-11 +-10 +-9 +-7 +-5 +-3 +-2 +0 +1 +2 +2 +4 +4 +5 +5 +7 +7 +7 +6 +7 +8 +10 +10 +10 +10 +11 +11 +11 +11 +12 +12 +12 +12 +13 +12 +12 +12 +14 +14 +14 +13 +14 +14 +14 +14 +14 +14 +15 +14 +13 +13 +13 +13 +14 +15 +15 +14 +14 +14 +14 +14 +14 +15 +15 +14 +14 +13 +13 +13 +15 +15 +15 +14 +15 +14 +14 +14 +14 +15 +15 +14 +14 +13 +14 +13 +14 +14 +15 +16 +15 +14 +15 +15 +15 +14 +15 +14 +14 +13 +13 +13 +14 +14 +15 +14 +14 +14 +15 +14 +14 +15 +14 +14 +15 +14 +13 +13 +15 +15 +15 +15 +15 +15 +14 +14 +15 +15 +15 +53 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +82 +-16 +-104 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-115 +-106 +-97 +-90 +-82 +-75 +-68 +-62 +-58 +-53 +-48 +-42 +-39 +-35 +-31 +-28 +-24 +-21 +-18 +-16 +-14 +-12 +28 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +81 +-17 +-105 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-113 +-104 +-96 +-89 +-81 +-75 +-69 +-63 +-58 +-53 +-48 +-42 +-38 +-35 +-31 +-27 +-25 +-22 +-20 +-16 +-15 +-12 +29 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +125 +116 +109 +102 +96 +89 +83 +78 +74 +68 +65 +61 +58 +53 +50 +47 +45 +42 +39 +37 +36 +34 +32 +30 +29 +27 +26 +-58 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-118 +-109 +-100 +-92 +-85 +-77 +-71 +-66 +-60 +-54 +-49 +-44 +-40 +-35 +-32 +-30 +-26 +-23 +-20 +-19 +-16 +26 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +81 +-17 +-105 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-115 +-105 +-97 +-89 +-81 +-74 +-68 +-62 +-58 +-53 +-47 +-43 +-39 +-34 +-31 +-28 +-25 +-22 +-20 +-16 +-15 +-12 +-10 +-8 +-8 +-6 +-5 +-2 +-1 +0 +0 +2 +3 +3 +4 +5 +6 +7 +6 +7 +7 +8 +8 +9 +10 +11 +10 +10 +10 +11 +11 +11 +12 +13 +12 +12 +11 +12 +12 +13 +13 +14 +14 +13 +13 +13 +14 +14 +13 +14 +14 +14 +12 +12 +13 +14 +14 +14 +14 +14 +13 +14 +14 +14 +14 +15 +15 +14 +13 +13 +14 +15 +14 +15 +15 +15 +14 +15 +15 +15 +14 +15 +15 +15 +13 +13 +14 +15 +15 +15 +14 +15 +14 +14 +14 +15 +15 +15 +53 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +126 +118 +110 +102 +96 +89 +84 +78 +74 +68 +64 +60 +57 +54 +50 +47 +45 +42 +40 +37 +36 +34 +32 +30 +30 +28 +26 +-57 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +43 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +124 +116 +109 +101 +95 +88 +84 +78 +73 +68 +64 +60 +57 +53 +50 +47 +44 +41 +39 +37 +35 +33 +32 +30 +29 +27 +26 +25 +24 +-60 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-119 +-109 +-100 +-92 +-83 +-77 +-71 +-66 +-60 +-54 +-48 +-44 +-40 +-36 +-32 +-29 +-26 +-23 +-19 +-17 +-15 +-13 +-11 +-10 +-9 +-7 +-4 +-3 +-2 +-1 +0 +1 +2 +2 +4 +5 +6 +5 +6 +6 +7 +7 +8 +9 +10 +10 +10 +10 +11 +11 +11 +11 +12 +12 +12 +11 +12 +12 +13 +13 +14 +13 +13 +12 +13 +13 +14 +13 +14 +14 +14 +12 +13 +14 +15 +15 +15 +14 +15 +14 +14 +13 +14 +14 +14 +53 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +125 +117 +110 +103 +96 +89 +84 +79 +74 +68 +65 +61 +58 +54 +51 +48 +46 +43 +40 +38 +37 +34 +32 +30 +30 +28 +26 +25 +25 +23 +22 +21 +21 +19 +19 +18 +17 +16 +15 +15 +15 +14 +13 +13 +13 +13 +12 +12 +12 +12 +12 +11 +12 +11 +11 +11 +11 +11 +10 +-64 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-121 +-111 +-102 +-94 +-85 +-78 +-72 +-67 +-61 +-55 +-50 +-45 +-41 +-36 +-32 +-29 +-26 +-23 +-21 +-18 +-15 +25 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +80 +-18 +-106 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +69 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +61 +-35 +-121 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +67 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +59 +-36 +-122 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-117 +-107 +-98 +-90 +-84 +-76 +-69 +-64 +-60 +-54 +-49 +-43 +-39 +-35 +-32 +-28 +-26 +-23 +-20 +-16 +-14 +-13 +-11 +-9 +-8 +-7 +-5 +-3 +-1 +0 +1 +2 +3 +3 +4 +6 +6 +6 +7 +8 +7 +7 +8 +10 +10 +12 +12 +12 +12 +12 +11 +12 +11 +11 +51 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +80 +-18 +-105 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +69 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +60 +-36 +-122 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-117 +-107 +-98 +-89 +-82 +-76 +-69 +-63 +-58 +-53 +-48 +-43 +-39 +-34 +-31 +-27 +-25 +-22 +-19 +-16 +-15 +-13 +-11 +-9 +-9 +-7 +-5 +-3 +-2 +0 +1 +2 +2 +4 +4 +5 +5 +7 +6 +6 +6 +7 +8 +9 +10 +11 +10 +11 +10 +11 +12 +13 +13 +14 +52 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +82 +-16 +-104 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +70 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +118 +111 +103 +98 +90 +85 +79 +75 +69 +65 +61 +58 +54 +51 +48 +46 +43 +40 +38 +36 +34 +32 +30 +29 +28 +26 +25 +24 +-59 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-118 +-109 +-100 +-93 +-84 +-77 +-71 +-66 +-60 +-54 +-48 +-43 +-39 +-36 +-32 +-29 +-26 +-24 +-20 +-18 +-16 +25 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +80 +-18 +-105 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +71 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +119 +112 +105 +98 +90 +85 +79 +74 +68 +65 +61 +57 +53 +51 +48 +45 +42 +40 +38 +36 +34 +33 +31 +30 +28 +27 +26 +24 +-60 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-118 +-108 +-99 +-90 +-82 +-76 +-69 +-65 +-60 +-55 +-50 +-45 +-40 +-37 +-33 +-30 +-27 +-24 +-20 +-18 +-15 +-13 +-11 +-11 +-9 +-6 +-4 +-3 +-2 +-1 +0 +1 +2 +3 +4 +4 +5 +6 +6 +5 +7 +8 +9 +9 +10 +10 +10 +10 +10 +11 +12 +11 +12 +12 +12 +12 +13 +13 +14 +14 +13 +13 +13 +12 +13 +13 +13 +13 +14 +13 +13 +13 +12 +13 +14 +14 +14 +14 +14 +14 +14 +14 +15 +15 +15 +53 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +81 +-17 +-105 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +71 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +61 +-35 +-121 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-116 +-107 +-98 +-90 +-83 +-76 +-69 +-63 +-59 +-54 +-48 +-43 +-39 +-35 +-31 +-28 +-26 +-23 +-20 +-17 +-15 +-13 +-11 +-9 +-8 +-7 +-4 +-2 +-1 +0 +1 +2 +3 +3 +4 +5 +6 +6 +6 +7 +7 +7 +8 +9 +10 +11 +10 +11 +11 +12 +11 +12 +12 +13 +12 +12 +11 +12 +12 +13 +13 +14 +13 +13 +13 +14 +14 +13 +13 +14 +14 +14 +12 +13 +14 +14 +14 +14 +14 +15 +14 +14 +14 +15 +14 +14 +14 +14 +14 +14 +14 +14 +15 +14 +14 +14 +14 +14 +13 +14 +15 +15 +14 +15 +14 +15 +14 +15 +15 +16 +15 +15 +15 +15 +14 +15 +15 +15 +53 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +126 +117 +109 +102 +96 +89 +83 +78 +74 +68 +65 +61 +58 +54 +50 +48 +45 +42 +39 +37 +36 +33 +32 +30 +29 +27 +26 +-58 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +43 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +125 +116 +108 +101 +95 +89 +83 +77 +72 +68 +64 +60 +56 +53 +51 +47 +44 +41 +40 +37 +35 +33 +32 +30 +28 +27 +26 +24 +23 +-60 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +43 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +58 +-38 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +66 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +60 +-36 +-122 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +67 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +118 +111 +104 +98 +90 +84 +79 +74 +68 +65 +60 +57 +54 +50 +47 +45 +42 +40 +37 +36 +34 +32 +30 +30 +28 +26 +25 +24 +-59 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +42 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +124 +115 +108 +101 +94 +88 +82 +77 +73 +68 +64 +60 +57 +53 +50 +47 +45 +42 +39 +37 +36 +33 +31 +30 +29 +28 +28 +27 +26 +-58 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-123 +-119 +-109 +-100 +-91 +-84 +-77 +-71 +-65 +-59 +-54 +-49 +-44 +-39 +-35 +-32 +-30 +-26 +-23 +-20 +-18 +-15 +-13 +-11 +-11 +-9 +-6 +-4 +-4 +-2 +0 +1 +1 +2 +3 +5 +5 +5 +6 +7 +7 +8 +9 +10 +10 +10 +10 +10 +9 +10 +10 +11 +11 +12 +12 +11 +11 +12 +11 +13 +13 +14 +13 +13 +13 +13 +13 +13 +14 +14 +13 +13 +12 +13 +13 +14 +14 +15 +14 +14 +14 +14 +14 +14 +14 +15 +54 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 +127 From e84f3bb467784700cb8099b93706ff00b8cdf86c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 1 Jan 2020 20:44:51 +0100 Subject: [PATCH 1334/1854] add hf plot fpga stuff (@piwi) --- fpga/hi_get_trace.v | 155 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100755 fpga/hi_get_trace.v diff --git a/fpga/hi_get_trace.v b/fpga/hi_get_trace.v new file mode 100755 index 000000000..3e7412f7a --- /dev/null +++ b/fpga/hi_get_trace.v @@ -0,0 +1,155 @@ +//----------------------------------------------------------------------------- +// +// piwi, Feb 2019 +//----------------------------------------------------------------------------- + +module hi_get_trace( + ck_1356megb, + adc_d, trace_enable, major_mode, + ssp_frame, ssp_din, ssp_clk +); + input ck_1356megb; + input [7:0] adc_d; + input trace_enable; + input [2:0] major_mode; + output ssp_frame, ssp_din, ssp_clk; + +// clock divider +reg [6:0] clock_cnt; +always @(negedge ck_1356megb) +begin + clock_cnt <= clock_cnt + 1; +end + +// sample at 13,56MHz / 8. The highest signal frequency (subcarrier) is 848,5kHz, i.e. in this case we oversample by a factor of 2 +reg [2:0] sample_clock; +always @(negedge ck_1356megb) +begin + if (sample_clock == 3'd7) + sample_clock <= 3'd0; + else + sample_clock <= sample_clock + 1; +end + + +reg [11:0] addr; +reg [11:0] start_addr; +reg [2:0] previous_major_mode; +reg write_enable1; +reg write_enable2; +always @(negedge ck_1356megb) +begin + previous_major_mode <= major_mode; + if (major_mode == `FPGA_MAJOR_MODE_HF_GET_TRACE) + begin + write_enable1 <= 1'b0; + write_enable2 <= 1'b0; + if (previous_major_mode != `FPGA_MAJOR_MODE_HF_GET_TRACE) // just switched into GET_TRACE mode + addr <= start_addr; + if (clock_cnt == 7'd0) + begin + if (addr == 12'd3071) + addr <= 12'd0; + else + addr <= addr + 1; + end + end + else if (major_mode != `FPGA_MAJOR_MODE_OFF) + begin + if (trace_enable) + begin + if (addr[11] == 1'b0) + begin + write_enable1 <= 1'b1; + write_enable2 <= 1'b0; + end + else + begin + write_enable1 <= 1'b0; + write_enable2 <= 1'b1; + end + if (sample_clock == 3'b000) + begin + if (addr == 12'd3071) + begin + addr <= 12'd0; + write_enable1 <= 1'b1; + write_enable2 <= 1'b0; + end + else + addr <= addr + 1; + end + end + else + begin + write_enable1 <= 1'b0; + write_enable2 <= 1'b0; + start_addr <= addr; + end + end + else // major_mode == `FPGA_MAJOR_MODE_OFF + begin + write_enable1 <= 1'b0; + write_enable2 <= 1'b0; + if (previous_major_mode != `FPGA_MAJOR_MODE_OFF && previous_major_mode != `FPGA_MAJOR_MODE_HF_GET_TRACE) // just switched off + start_addr <= addr; + end +end + + +// (2+1)k RAM +reg [7:0] D_out1, D_out2; +reg [7:0] ram1 [2047:0]; +reg [7:0] ram2 [1023:0]; + +always @(negedge ck_1356megb) +begin + if (write_enable1) + begin + ram1[addr[10:0]] <= adc_d; + D_out1 <= adc_d; + end + else + D_out1 <= ram1[addr[10:0]]; + if (write_enable2) + begin + ram2[addr[9:0]] <= adc_d; + D_out2 <= adc_d; + end + else + D_out2 <= ram2[addr[9:0]]; +end + + +// SSC communication to ARM +reg ssp_clk; +reg ssp_frame; +reg [7:0] shift_out; + +always @(negedge ck_1356megb) +begin + if(clock_cnt[3:0] == 4'd0) // update shift register every 16 clock cycles + begin + if(clock_cnt[6:4] == 3'd0) // either load new value + begin + if (addr[11] == 1'b0) + shift_out <= D_out1; + else + shift_out <= D_out2; + end + else // or shift left + shift_out[7:1] <= shift_out[6:0]; + end + + ssp_clk <= ~clock_cnt[3]; // ssp_clk frequency = 13,56MHz / 16 = 847,5 kHz + + if(clock_cnt[6:4] == 3'b000) // set ssp_frame for 0...31 + ssp_frame <= 1'b1; + else + ssp_frame <= 1'b0; + +end + +assign ssp_din = shift_out[7]; + +endmodule From 796fdb90854d3c890fa3962da8022e2dacd97113 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 1 Jan 2020 20:46:26 +0100 Subject: [PATCH 1335/1854] style --- client/cmdlfpac.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/client/cmdlfpac.c b/client/cmdlfpac.c index 04ff13633..00d4d4ae6 100644 --- a/client/cmdlfpac.c +++ b/client/cmdlfpac.c @@ -90,15 +90,15 @@ static void pacRawToCardId(uint8_t* outCardId, const uint8_t* rawBytes) { */ // convert 8 bytes of PAC_8byte ID to 16 byte array of raw data (FF204990XX...) -static void pacCardIdToRaw(uint8_t* outRawBytes, const char* cardId) { +static void pacCardIdToRaw(uint8_t *outRawBytes, const char *cardId) { uint8_t idbytes[10]; - + // prepend PAC_8byte card type "20" idbytes[0] = '2'; idbytes[1] = '0'; for (size_t i = 0; i < 8; i++) idbytes[i + 2] = toupper(cardId[i]); - + // initialise array with start and stop bits for (size_t i = 0; i < 16; i++) outRawBytes[i] = 0x40 >> (i + 3) % 5 * 2; @@ -116,8 +116,7 @@ static void pacCardIdToRaw(uint8_t* outRawBytes, const char* cardId) { pattern = reflect8(idbytes[i - 2]); pattern |= oddparity8(pattern); if (i > 3) checksum ^= idbytes[i - 2]; - } - else + } else pattern = (reflect8(checksum) & 0xFE) | oddparity8(checksum); pattern <<= shift; @@ -160,7 +159,7 @@ static int CmdPacDemod(const char *Cmd) { const size_t idLen = 9; // 8 bytes + null terminator uint8_t cardid[idLen]; int retval = demodbuf_to_pacid(DemodBuffer, DemodBufferLen, cardid, sizeof(cardid)); - + if (retval == PM3_SUCCESS) PrintAndLogEx(SUCCESS, "PAC/Stanley Tag Found -- Card ID: %s, Raw: %08X%08X%08X%08X", cardid, raw1, raw2, raw3, raw4); @@ -190,7 +189,7 @@ static int CmdPacClone(const char *Cmd) { int res = param_getstr(Cmd, cmdp + 1, cardid, sizeof(cardid)); if (res < 8) errors = true; - + pacCardIdToRaw(rawhex, cardid); for (uint8_t i = 1; i < ARRAYLEN(blocks); i++) { blocks[i] = bytes_to_num(rawhex + ((i - 1) * 4), sizeof(uint32_t)); From 9f02aeb85ef2fe91ff8327c14ff95396aa60b61e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 1 Jan 2020 20:46:51 +0100 Subject: [PATCH 1336/1854] style --- fpga/fpga_lf.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fpga/fpga_lf.v b/fpga/fpga_lf.v index 9c1c2528f..1df5394b6 100644 --- a/fpga/fpga_lf.v +++ b/fpga/fpga_lf.v @@ -75,7 +75,7 @@ begin endcase end -// +// always @(posedge spck) begin if (~ncs) From ca855593091fb9cf0a15fe4273a31dbabccc2643 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 1 Jan 2020 20:47:27 +0100 Subject: [PATCH 1337/1854] some function def (hitag) --- armsrc/lfsampling.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/armsrc/lfsampling.h b/armsrc/lfsampling.h index b17a871ba..21968cdd2 100644 --- a/armsrc/lfsampling.h +++ b/armsrc/lfsampling.h @@ -52,6 +52,13 @@ uint32_t DoAcquisition_default(int trigger_threshold, bool silent); uint32_t DoAcquisition_config(bool silent, int sample_size); +/** + * Refactoring of lf sampling buffer + */ +void initSamplingBuffer(void); +void logSample(uint8_t sample, uint8_t decimation, uint32_t bits_per_sample, bool averaging, int trigger_threshold); +uint32_t getSampleCounter(); + /** * Setup the FPGA to listen for samples. This method downloads the FPGA bitstream * if not already loaded, sets divisor and starts up the antenna. From 27f7dd6dec8b7fdcbbe7613507f44211c7796900 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 1 Jan 2020 20:47:39 +0100 Subject: [PATCH 1338/1854] some function def (hitag) --- armsrc/BigBuf.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/armsrc/BigBuf.c b/armsrc/BigBuf.c index a0a25d1fe..765d230a5 100644 --- a/armsrc/BigBuf.c +++ b/armsrc/BigBuf.c @@ -115,9 +115,11 @@ uint16_t BigBuf_max_traceLen(void) { void clear_trace(void) { traceLen = 0; } + void set_tracelen(uint32_t value) { traceLen = value; } + void set_tracing(bool enable) { tracing = enable; } From ffb596373f11fd1a58aded452a26a666c552003d Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 1 Jan 2020 20:48:11 +0100 Subject: [PATCH 1339/1854] cppcheck --- armsrc/des.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/des.c b/armsrc/des.c index b84bc4c30..ccd32be7d 100644 --- a/armsrc/des.c +++ b/armsrc/des.c @@ -272,7 +272,7 @@ uint8_t substitute(uint8_t a, uint8_t *sbp) { uint32_t des_f(uint32_t r, uint8_t *kr) { uint8_t i; uint32_t t = 0, ret; - uint64_t data; + uint64_t data = 0; uint8_t *sbp; /* sboxpointer */ permute((uint8_t *)e_permtab, (uint8_t *)&r, (uint8_t *)&data); for (i = 0; i < 6; ++i) From 0dc6f38741b6220ce5a119df5548539b8dcdd4ff Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 1 Jan 2020 20:48:21 +0100 Subject: [PATCH 1340/1854] cppcheck --- armsrc/cmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/cmd.c b/armsrc/cmd.c index 61ceda2f0..c7f76960b 100644 --- a/armsrc/cmd.c +++ b/armsrc/cmd.c @@ -43,7 +43,7 @@ bool reply_via_fpc = false; bool reply_via_usb = false; int reply_old(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len) { - PacketResponseOLD txcmd = {0}; + PacketResponseOLD txcmd = {CMD_UNKNOWN, {0, 0, 0}, {{0}}}; // for (size_t i = 0; i < sizeof(PacketResponseOLD); i++) // ((uint8_t *)&txcmd)[i] = 0x00; From 05f2fbc75a5e89f7f45b7f70e90852f82f6968ae Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 1 Jan 2020 20:52:32 +0100 Subject: [PATCH 1341/1854] hitag adaptations (@anon) --- fpga/fpga_lf.bit | Bin 42175 -> 42175 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/fpga/fpga_lf.bit b/fpga/fpga_lf.bit index f694ad4cf7e0cafa299260f536faa36113164ba4..8f63e1eff913c347cbdbdf4bedec56e8988b482b 100644 GIT binary patch literal 42175 zcmeIb4Rl;*buPTmdyeEI&B${s+gvqq;Ao_ni5bab*>T(;OUJU34za-kLYq=n?kX2lVF0Ox$VR;ARzRPe@L7kl4C^)6Guq~*Q<5Ggo!IsB{-?# z7?5qn{+|7wGiOFtLc3P8*6ms!Y8PydUZ3;+?fvX$@BO}_y2zyWe?;2NH2+im|KsNW ze(R^&`ft7YlYg|a{ZBu+k#3>-jz3?X_@AFymPpViDb$hZNG!FN;s0qP)paDUy?WWT zE3T$LBHG)35kKGl>c>8nAgK}2oP?I*|27kvt&!|*OOVU|oBZF`B?!+e|65CtLw(fx zNoutC@!R|uQvIT_?`?k1j}3|cAQI|7-{wCYsebWm+mP3$@oiqA9vkme8}+t}jZQrY zi4WUkvXG+~T}$;+&ym|bq}sUJ1-dA^UyMxY)AEEkK=IRq7fd`U;mIWRb0cZJMvut$ zQs|I)GiS=EZBC1mv|F~@bs14I65J+JGe-EwZYUwf`m&V5N(nsC;_l@MaZ*$7aTnfC zk5Ky)p*()I)sFU>`NooSh}x-6ib*5I@1cdK=sdN%k-UD2j#Gyn&g&C&mbyL?$>~Ky zy{Du-N*AfyjZC7=Y1x&7@Dja1-7<1apTf8C<5>6OJzYiho>yp@8$Z-CK_76s`WpB> zHn%C%#JN8%`ZHa#y}#p_c}BcsY}4B1+^jf_4TPUk&3Yc!ag1Wj$Wf~i>*yJE(iE2= zOH5&l;m6kAO%KYp(&e{_7if!YE}6I0o~O;SEmgls6ukE&%`m+|oidWp$LKyfD8mVT zRE*$BgQXw!HjZ;eFs^CiBE4rcGO0~DZ&J4tnb3Cn0QJ*&Sv$t(UNv z7=_#Nny%J;_Z6zo+{5vlTBhv$ae5tZ#*>$7`}sXhHGZ2S#`VwC;jGW<8_6HnQ{H;5 zvP#5S5Rw>0hN5Ijkq{a6M1Rg3yIC_D^qIa)&1+(P7}o&4wcSFWy>Bht%VY21v1@nG zeU4ca2i5%G$?e`+bl2h;u+FOLC;FU%Y$UBv$8yqxN%u^aMX~xA%()|2^ir=~r@fDRPs3L5|DS zb~uTx^{XK~xlMn?(=YQ1WfMj)idX69JU~_=SP2$-YE!&kPK~mMrMb81-SnJ%e=a+^>IvHk(&FSc_x5TP&qtOT2j|Qab3?^@~N~i!c{v3g%+x zf|ik{N%Y3%Z>2o_`r+><#I5Fl+q%)T#FOrzV^5jah&pfGhha0(Ls^#>omlR!6xQn{ zTANFh!iR+aElFw=N9%Yv=TcpFMfU11(~rGzl>m|W(X44@GZ#(HKSi(7awk&M&zR4f z%iSH5I`yhH1IDf9BQO_Dd2x!i*(+sePftNUL(#)9=C)(;dt}Y6Y%@p9{b=(Yx@82$ zlLaVRUfAARm=tE4={CV`m>Fs%yrM+gy*9$rFEVeX^IDf1%j?thFVx|!#m^zYvXQ4> zx!>YGuXbVHr+stLGD-g`@T6a#@bt^YdOa_@8LckRwCsMeVM3p_pOf7b27U>p7mQ!q zJ^Xr!9+FFsnK}B2m67c!^AI#njXeXqI*2}p64;{qDPH)16&)kkdBWHO{Mtd=4aSQe zz*a1N*vvMbg2G~B=No^>eg^zYj4=yDm)Lr>Lu`S|6A`bE(>2q254Mmpu~rtLC*dG^P{ueMU?Ht`R1Fw-_+ z7NURa?2yeV^m!(J@tQtiOmeG93S(TVS$-|9R=otw-m{Q49bpBeb|kcBqco*DzY&Z*B<@XM%R0oL>e*bT#CEU0HJ;MXvI8B@j= zwD(B8G;fMJ&9Izri-OTbbEW>8rq*5Im!Yh>0;wA|+_n8@xwF*W*N~n6l7|HWelbkE z2?%H?&R+pse$OopS^ZM{a@9U;XZ*4mzbps=ejTIlQJWL$696(9cj_!Lr0@$ufL{mc z`;63+z$ON9VE2&1F9=Wh__a`Vm67OY@~n&g+_QZz@T>EGqCXRc8dpqH_{D9|*zI(7 z-Zi+9&I;&P6@KN*9tifKg=rbmZ5#M*!H+8ASB=6iMym-0Tjsd_mjJS**c%o6awrcg z5h5|BvC*r4v?tOxXtai73A9oD$!Q9|ct3lvWqvOD39$vUf&J{`*RXjR{Zh82B1!!P z09p6s+^J9({XnkBg{$yOjZ6Bl)qNx~`MyIYTTwh2sZFVcuQ|+xy5WNe6U}7yBc|yNYIW=S#RA$w zpLWq_*TXM+f$~Y@+JrUMI3VF4nt--J8E22NU?jLd!|+MqZ^$iq`!#x|c#YezKNN>O z#60KqpL^eu^fH}uun&jyQ_gwox7pyIq4P%9dW@?YzeIQGJyR_Jh1za6enem7JWs1- zcv5$J)wc$Wo9R%p-41OPr_4t*==+dp0eZFrWkjirU&=omQn2+1{VAJ*SSwp~*vyiT zUxvvL;P9FP$ZmBrB*^*_78h&k>lZZuzhLJ>jJanu*k=ma^o;0oF)mm4*8Pe}?6JS5 zIqsZk=ne=A4530{46q8nF3M|4JE!z7H2qXAXCmgW;PJQMU$3D*Q6^%q8H$k&&*WdN z4s6|e`Vz%l2qS7|UQQMKy5I8o&MA67EphccJO_Ty<%dKSex0Y4M=|ra(jU;ZE@+qH zUrt1>orzzdC&1;4^q?ClVZGS-pMhUIKSj(2?4iAq-?Pa+YqPZ(EE+cN4Ud1#JzTH4 zLBfTiEtU_Dz#0#yXYwyzrZIZN-N@q_ZP@R|?*=2Q;1_|**ua7pj0eHLLWk_H(f2Y9 zsZdhP#4kpxF?z#X0U*;x=`?l9h&_{kt){u&xD>&>jrmt^uw&KL7-DF# z+@CW4()RL`k~c05s*XzlIckJtm_JWHE#J*Y+y>S`U*F zw|I}yBgHuH)nJc3GXuZM`}r!?(?vB8*0+sdhX?qj_}50TtrzH`RJ7|d`hVo=)GYpW zlhU2D#7Yzz=jee%=L7sw{L6;-?h!GBK2Dn#2D&@ideIuzpXpIoqr7 zi`y)mGe7e{iGZLyZSk;zYX(wpJ#wL43L0e&fN zlMvdD&k?6 z^~=XEO|8Wg?AXpc^x`~yfd?4im*QWf`aDgKqtAdO1f3{Stl-x)jmc}+-}o#6zgoiu zy^)@k%Zd4y=Wj^sl(}6-OWO}cUo#)Jm$>zZ8rzL+LkJ{-e;Eq9Iexf}{U{r2ai57O zlocgQ!qJG$;9pxYWHr+LM$E0hSH$T%B03M)UBR!WLhs5{B)c|cJ!5ppFxAC?ga>ZK z3I_Ofzlpsu6e+>Cc?^rPf&Go2P}eQsDFOf5OGiwYi~Qgz8&q0CVK=3pvEXm;du+l_ zp{A9#%JyBMv^Z%)t(?$z7mre=uRV|cRN>b^F`f$<;xKTz)!Et{t#RNi&E#KnJ6k`- zf(O3bmJ8h^enhtqwe6Y7zn-8~>A$o8+nD(eR%c(sGW|Mo7c5FH0{?=_;)nSc*p@S= zs7=xZ3j=iZsa`}%dDjK_^%}fota27R^E}plM^0^8I56N}-g+_rx}DLA)oQ) zXnYSbnWn1v;oZ?KK&$QC=f`F9Np$rE`@wCBGY0rIN>aodLk2YNVOngPBu1=!DL$2) z!M~1B*8t;}#rPFxf8(6feV09hfBDfu4l${)A$wMxZ1iU1*GurnI-Kx5`nY798NL+1 z*es9tK13_QFQNztVBx?os_^Uk6mc#u(i!}!#W9PBvwh!d6T}aV99x@EUzADBl@8{I zg}7rfmr-kRsKJqbGz@*#5{LllC2LxAu~5dZ-#U}?t@^leHr91RB>PFW^WA;#$*!%6 zA98dK+mC47*Ci6*_}(v8(D$9CYiIJWr)8J(!QJ}5j-I9c&W7xE^vCJyk2C*L?*ac3 z?CFK>La3@dKnR^1(fKO;DzB+AMf)i{%C^Pnwy>tv{Hw1$9r}8j`Bzjn7W^x5Rp|qcC|WCchtI&TgL1VE{`DieD3?!! zZ_@wK_rOT-eNUx|qDC$eY&lNvinQ1$r~vol|Z+(kQ3rPU+{IH?vDO#;f?( zJPL%=TH{D6{8eGDFw? zu{l}4l(v_mMXZjGUlTP+k}k4cV37`txoiG5B50Cw;~1CEzw%nUvpL&#GxA>-8n z#o83xsA0^r3)sRa#^@Q@VMZR%Ilii%`1n--er={^LhPbQL)6?8`g1W>KZyJnw8_tZ zNf?wb%4Qo3@igs7H|Iis0U+b#9Z)#HFQmQ5E^hCPzSc9Cu?raTb1B5}2R7lXcy3+?BU+IEa^Yw^Zbl9dPKs&kaW-)-O3DK1Dh%BBT=3jR>Ej_CkwqVQ| z+Q!9J81r@6o&djA;8%dQn}7wI>3xpbxL+m0oKO{hrKkXH+5y-S1-N{i{~9XT`?=2n zevQM0c+6qim3!Ujaw0|jjChkCTZ29a_;rSULCc&lenrnB?*KUFe3JsQD*R&F1+*&B zw`mVSiAt2A7S4$I@xvtYUk_2vF|Ec?jNNvc`our-Dtmoay4c=UWu* z1$JK$oCw4GRK*WpcM>=4xJQ3dayNFU{*+XIeEiy^?PYuDZ1@_wdbSbc%Ic%^x~qg| zy!f-qe3RY(lJ}G_~zkwr(3i@n_)I0mnXRCemT} zhp=@HHSDn&_|-CEeqJm>2(HatciZAcwSy)C3p4QRS8`bi(ZVkJCkg%))3?#6 zT$Y=OUsLq=Zo~>9Cc|8Y#}2`PHU<343mdMV(z}cw;Dzzy`hFzBmfNt0Rs8FA%zUO# zETk=>xz9}LCk(6w_ooWKZpYZ`9MNfSfnZLG-E_OtEYYUIzog9B_Ej~aRt`!#VN&gA z-vB!&75rLw2R&0roM>33FQq3^9Vf9Nzk&S|U4uSX@JsM|&1L*LZ$8$CUrj_$yN>~h z^eX&%)>@w1Q5swc2w1)+T+-L$Jdu9e(GGJ5FVk_o^T-Dc z6b76{KtSn*v|gp{M}c35dfJf)>nMeG*RSS`m=k+gl^e>n2b2$23S6Unj}{0m`2iP=C{mCbvW?Yz_F#Pe&5 zhRwFFP-D>J*V);1g#Pe^L(Qkfk5kA_2KZH~ap*v{^?^{`$0H*al?W#8lo(hOPf@;% zUtayjm3sl}9rSk$0lzPv>-(~7o2=$v2I@Cf$dILn>4zR{jrBa?c=<12K7LgG%Y6Sp zq_nn3FR5kvooVNB&)+E4rnt>;%^5_A7v(nR^bgTdiMY)nJ-+AZGzuQ_`jUWui7mM{ zY4!<=O&rv!{t7un_sWJz(df;y3x>8uF3o*)YVjAe$K{o!byK&`m0M&>%Dk;UK{kIY zx!^eqIZX-LMU=<0(5h&h29wc=x&+>n;5HKrAC}->vLU8#qH`Hc_^=*BhH&}ra8AG0 z`&N=p!n5k44Ts?ot>`uv95#lncUHyFRhlu5ywPSCY#O{t(Mep>Ip$B4oDG280l z`V9qJ6ZE5bD*si_Gf0H`4S{Sjg{aX5_{Ch9?o+53i+x(iyYUwqhl6!jqvTo_H()VFu;TuBVd68Eb#S<%=MlN zfwfSAN`w`tlfwPr3ToYRSCq>(u*Xo(<^s07Cp&>(bNabIF7lOQ3|ocy9p<#`ws*Sv z7qAnS7ufNEpPO$9@T(y; z*th5P&?@n7$ZfTs34K?b%I-5(zF3W4Jv<89j?kGmE)CWhfy6Y{BFKMr)NlS$bARab zJwK)I4Yj2%2bXcazx%zpYWy-myAnMSO^n&EgMUR<=wrQaSSzw~tN7PF^ecr{Yq7_K zqRG?FMGFI*ti%r|=!nswVP~GCf`s4VgxVRP9XzST4~;Dv!&c)7D1Nh>hi({r?JPh`{J z6g`(&F2kGj82r@(uv!)Vg%pX?WkoXc%Yt4qr_8PRb*EQpT@VVhV#_8Hlq1+U`mlF!;9f2bc0M$z>Z{GbzEp7|8ZZ^tsHxt~f@& zfTsuA1p&c52%|a1ulLNrFW8?o;p|!iehbR0vij%fNdczG{ZacF^@jrSLk(zUH*TXn zGU@i%79-jXRrvKwEag%+Hd)_k++no1vHobU8bz`SzwVKD+_JP_PKs;j4%w2-6r&ia z9d+vQEzj2F7QO^;u=AF%)iQ?;%Z^m|OZrA}*v|LvVEj`3LHtlvYdp{8l!}O1p>Z2R zNw10@?x*Qww}!mK8wA=Vc8<2>fbVcPXYj9wHO8;#gxE%Q7F*&ktS|ONhqhnBzv4%E zkI~?9-fW_s(w1#O2>6#p2Mt6EoyH;!8O^lL7Qatlq~z80VuUV7yJOPC#^-f>`(ha32I>ocOxzA8fh22)hiMoi3CcJg$`on^RKMy3t zI`4NeoKxnrR>BSELsl8T9_4Bc%)CD?2q)-#rfXzrz6!rgm>oBKV18UYV}pM&&=*9< z;ds8q^7>q;S>!yNYPZcD91gWre=g8qs)a2;hqo4`nh#Rmj>{McVN1t$u>{Z2;7D!~ zi?XWhAHJIo%B364b4ZWuWd4O*(z~{#xsYC%UL7OXAD*^5pIV;?go*R`glr?7qk|84U6U9G!K{2_fsUa9)*?oGE%H2sxGST=u4 z)z51-nbasLC)C(cQ|cgyTE)MH>4Lpqw&g;b%%k*xL^;X?y(GHi{kc%UzW`gVm-a#! z9wiV`$CK7h7Ap9~rm_#Jx0haa0moUrmY%lQ&TGO@`$rn6Kcx7FW7Z8dcWrf|OvDyD zTV<4y$S(7*R{2$PaZf#$j(?Z9O?|7_di|aola{!>tY5XceSjOY4wR;=W0y2ntHLkpa+YRM-r$W(l<0M_vIkG9@?TSq%1z|Om^VKqDmd)A>Sg{_ zvx**b+F_!_l4zPxkDU`G@x>e8w;K_ddT%XaH5=RmO)5(BMH+q z0`-RmDpe@vU}p}|m2RlN=R|I^bCp~78O)f&ZHB%2d3)|n`qu>Ts|473?)Il-BGon( zS|Yd!fqxln6C%0LD1sqOYV=dLoMwZcAFRT!SF@{2;oDl?ML$R{AIE#TOvDetzjO-t z7j5oq6Q(1Y1mg29_*W-3*VS(F^=kgL*IH`CewenL9hqkLat1O)9Y=v^KL4^&KQCpx z5Q|+Fb_a7xzfj+sZiPQzZ+h#__46+mx+cSWLrduySJ}fj9VsPbHUC2X%Z6Ir&1$8_ z6*?u(CDrMn0KdkuOx<*=tFJQPZ@6qT1tKRUAR6^5{TeW?H!|tCn^_Sx%t6mSzt*#D zpxs?k#lIF4Y6e_0m)^^;W1{r*Da^x(An zJRNYur}Y(5WzDMi*S|P$<*ttH=xHuyjzyQ%-_g^OgvN0pV#%B5OpQx98V2gry96R; z!Qh8!UoD7Og@4VvzjZt9an1c!+z4UpNAlQyk2JI!!0v#5y+{-Gwc&^yJehLy9kK9s z_$R3QvgcOuuSd-{vYjsb8{%SS_2kk+`m6M&^@SWralpTJ!UK8O<$6DHUUWbR+2#@C zE7f~!p65bMOk^@qGd9#{o5vk2T3WQy_U5R>TKM@d#1G+C4BIgwT#s9dY;M!}o`-q8CaB@(sB;LH=um&RD=@=ZT_y=6V2` z6PmOqw65A2_$8jELp^bX1Z$rLQ4OQL!2o2w zf5`Y%upj1QU%7O_egHx!fhR~fR`IVhC^hMF=2-K`zk%`wg$49xY-ap$nmFwhF9N@w zr2|g5sIP#~;q0uAA6gks6G%ag$BjK8Vo^AFcv8uKar|&V+K$;I*f`j!7%&%t0^cBh zxVLtzwkHX@F^9hDMthU@)WX_Cqifey@vm{`>1@YMnBFVtX$S7XE_Cea7dt+T{sjE% z8y;+ZEx@nPxQ>WoGE&9Aa`2z`FIy^6_Kbuq&KE!^Bvec|$bXrXrsm;IH{TUQ?6x_* z$rh&ZMahf|rqf{^n+TiuwZn zHJ6@{3BXq9J?;-6#8>HmD1IQ32&=B27l31T17K^2VGBiKsE$wuzrw#zb~uEx`LoEQ zJ)c#u)kSjQrOD)4r?DIEe$PudIUnnKb;M9Q$E|ZluVR6F}9smatLArQ;IDU9uc1*TC8tNwCS1J4`fb49p z>vb6XApiA}eBJ2$a3mT!m4%ahSEO<6DHMg`^iWm&5Pp_Te=Q zWC8zze<=5?O72L<#c(p3h-K^Jv^CYvAQkYhxbuhwQ#k;h0v$B!_d)m;5RKbZ@M|B? zAVyfz9RAO=)VUkAroMg=@C)TkOuH5toM^^|jH6>K8OQ?ug+6P_@0~VO+N%isg1~(a z_*Zb=!55M`BEYnKd`Cg}^&3^^mxF`MuTe%u3&|?{Dv+v>ObC~-1lY}D3|2H(z^<#r z4{e~{5VZ1D?GXnQc$YXO8KA4=6ADZtaM zD66QBANEonIWyEBK1s_c?C1+9Om`*G=PLZVj8J)=0`2+{Js{gaMe0{l8dzX{ptj(x zDf2Ic4P8`gjFyEk9fji&POJ^;H}W3;I*d_(h!Jw)$5_C6tu5B3xX;6|WAK`CSa%gS zc3@IoQ-?7(BwB*}*KXokHK0|IP&O|^DF`^9;vx}N;a`X!wlPEG`uR5IUl-_`83>u@?TtSsD|SU zqdFW#Q!Q>a|Kjz^wzT>_zs|XJC|VW&+DH$j+t-A$J*}2nuiavt9&&(a7JNU8=clO# z6?e4M2^G2Yj)kM##)Rd^8Q!vfEwKE`^9AhKJ1{9+l&GpENyUMmRZ1Buyebg z!m^rwovrO$1Is_oMMu0A$LMS?gkr$IYDO`fb_eP?4mehAz}h6^7x1*7`>f6{3-A=# zGYJ>4onfm)ULk$CeuMcJcNLuR7+@>z0BX@^X9j-F+pC6b7R4F*7Cs8d#@GS$P_(M} z;aL+|;JdL8gZ{jZc?M?;@M~{I4F@HlycWsG!z>u+{9V=chhti|g>=It%#K=0UQ=a} z0{n_0Y#7glhQ%xNBbv*{Ql{uJiprVizod36TzTGF3|qwRxMOonCcv*o;8$BQ^f~bp zLfXqkVbXE)AT>{5hX?r8NKeVtUi?tO78fG^QZ9d``utap*McqN7`7JU*C6T-=`ptR z0slH}ehzjXW%K70Y_Z^67+QX^8o#oM2WgoTx=|c69$bX{*Uj7?`|1KVQc%Bx{uB}E0b6q zsDtb(;gHuWFpMBjRrrM{=*Mwv`Rh+iWY3#jha+j7?-0NM4`I_P9Mr5L#}9dDE`Wfu zr6px#6cG#XD`m-4luh?lIQ|SsI)v%n?=GpvFU=<8fJW9K&SvANtQ*>cHV?yQR^yiq zzr}{RxYkCh1#4>ano^9%72sEjvmQK(I0SSxrwqOtSAbttc0(oan4Wm{u!3JN(DU}P z6xeYWHo$VG$t!?gu$karj?yo#Kiny!d|H|7H&ohdF-dQLC2uVXHDhp}U?mbF%$;ZR zPH2P91HT4rEEl<`1qJ1FfDUmM7$#y6FbT}R)VBu;jqTnRz_;r(iU5LG)xPrHDvJ9S&0O{y6yz3z@JB3|>S_#@`DYEb9za}+gj${k7truuWHjhKN z3_#Y*piuDaD)1}GVZ%81;GQ4aiKoKLLS(-VA{GIcspaY6`VH$>zt!!|eO*5RgTMMo z1b(NG2>WXuU~x{0+o__P-g_BN!wzLB}NWPU;%6}U6xW%SwCFT@Xx16mGC+32llautT- z`^Nrzy!$s2nQ%^zS+BVrGCZswm(QgXkOlmUEx&K#R+WXRBr;+%|~I)(sFdjShta|5v)A7mb>;c52n->^FX{yKMF#Sd+H1pF&r#lJXg zc!%>LYwf7PXOm$Zj+t+&LVEqAw^w)9Fa)S@=(ym*iH7VSv|4Y{ffUA7#xDX|A%xAa zWgxE3L@c533qnwT$QAzgIw8id%|^3R*C%#)m}`ln<@h1v7wR{%z%Nx`$w5@ccZ~g| zs`w#wqyV*}beIxOLzDhZ$vuoS|FU`Ps6RA)wx#gPL5;^od3Lzd!N2;Ex5vEuH-J{a zFMHbTM*ZR7B!P$-n4b!M(Zlv0Mym-Ejw@&vy+U8i+?Q4O#h(KIawv~i#!})i!BMo} zC^C@Q85ocwp6=x4S!mOoGgAWf^Ne5p;-}2W2>9je*DzgXoJlXUk$wei4Xw^aHleKd zxy{S(1%4e77JtjcT`^Pi=s+ajQua6IjCoFSfL{*k0WQb`_VW`hzjU}TJMzysbB!Aw zaCjrm`t_&r$!?$0uQO?nU@fnVb^o$Jox$>Cm`+eqWnyjzN> zw;5jq|BxNU2|DCr;qn#!)e5!R;mtG053v?D+$TQApd+7YKjtsQ2ReA+H!1rf>7YHO;o}LzJS|~phy~P|J`L_KXuRjy? zf86_CGEa+@o~UD_sA>6riWIERqE^iVG8=mp_@#Zs^AElIqdNL#yp4GSpx(xb zFVcngElHn}`)En3ez*Q96=s-^6}i*Dt1N&}kmQ#t!(`y9o93DIELyUGl?*TnWE#X8e#QjdrPAeZ{}>`fI&P zI9SPlA$}-V=YV?eHiL_ap5KLx*pzOS@heLRYpnU8^U*%*pFI7VPHj%``LFqZ;>|M< zgC2C+Eb~V3-^x08Lg80znJ_&4vRS{f@$tH=M6#@3rv&?l!0wNG>pr}2h)z45#c-=0 zD%-IOgnMb&9xm~|CFy6-6sXlM{b%Hl3kR7UWe>+a{nD&6sIyw`sPzK>Vw;J`cCK57 z`%yTduyVloA8DM=m1Z92n|ynC%J`1cUNZANInS4nHBsVHQg|Q%^*BY_O|*e`U)C>D zJ2PfoX3%{e7K~XCN*I?P-yrDM5rY3Cb*>LrT}6F3?m~&@ar|28R}S}Y_~A9*404}U zBxkZEz_01tm|UF*pI+OMydYP*IKTXY#W!*=|0?6xMarbx&Dfjuwmc-4o-s4xB>RVU zC{xLQakMb54TE-N0ktlIPGh)jLvh9+eu(-FfokWxK;TXy2?&Q%9*X@5t&`>a7jgZD z)0GJ4=iBBv+3Cgyfjj4&$0j!95cg9!SkfLfFJ!xicINdn4tzfsSJM3w7V?@a;VcFC zwS#a@(*oZ?x|0q5P$=d+qpft~xk~*;r`YbG8u8l!&O{?(hDeBI}a_?K^JZI%) zo2@6si1DzDj921^FVfTi^ozJ`zE@o_G%2TP4uW!nLHuykVJjMjzoGC8M2v+-elp_Y zm+?o7y=xD#f3`a9o03`4YHXzyY@aLqi?*ku4z5OQHMd6FQGeKTHQk}TkF9!zf9>I1 zQmiq}DWv!ftNQ8}fUqoeVtwWKhRT0w30joK+8hxmo0oil6kQ7wTd6-B7tpUGsA@R# zjbCWUe_1+WdRMIkqLuM$cg-1uYy5Gk^Ix3*LSO;odT*J3StTQ*+1Ot<*u?xRCSeMO zehD7?u*H;<(0PnqVN*RgV+FsqI*e9`uWmJ>YcMUX+P7$la|5`ix9+)x zqnK6r30d73ecIgbtj{vf1)|N(2KOIod;M~h7RF@&wDKiTMG2u&zabgc!=xka#R9gw zUq3%T;9sl6?OGhRu096Sz4UI7tm8IU)SEdR&T_Ej!M`@(M2521$bSvQos5+}EWf11 zU8;&7F0$c<6~ML@jchUFj@c)sw69o8T|5c!Yp!6}LfWfK{y?_n!Z*$TN5Kcds^f?E zb0+-+yxdpqbM$UGCo9HO>>W?io`2}nARZ+TybiQ_H-zQ6ctOX3DSl5?{oy_4?M=-i z$^OPg&K9~_n!Vx*MGVoOfPZBj4t>B}bkdhiP(@etp^fUZ&%ZVSzi{4a68aSf++hQd zNZJR?_(`*?lK(;+Nh~j#`RHo%$1>`KbD^72rQBJ7o%g?$MS&6ACl{kQC0|K(-ifPk z{tqG8=puVkB85%TI&M5GmX83fIuTy$lIu(QN_kOR?uI8T`L9i;)S`!z`Dna8)6;%v z*k1c*^f>rML%zblVo}r|y0LtHyl!g-hpP51RtLerAfbb5O-;iT8N=qWbEyFCw9MB! z;3<3DI`A)zmmU0zt=7HnqWqjrB!9cKaDHtJ;H!9ws|WaXMnP?88n+Q30nrag@*VpC zzkW$vt`olv<)(qZ!4>sj;sO79No*a$X_U+jQN$11OCV6Vkptrb3g$mhRsY_MeV zaR9$R@Hco|U$4|3_96#lyLF9N3x8bjH#FPL*k$~(wRh1SsHdoV8UKotN?tCB>o+DE zO>a$;ra>dI#QFv}ndI}YF*@Sx&xY;60KayD`F8J^JE^}=UZ$VWU!wviQVJD4{Ti+r zhZRjopq?K$hBAt05T!;0FTk%|w3)7U8dAbS%1`mH6BcK{8%h=Yx|{xf;5+tZ$=dze zH$DFK0y^JZ%518_FSt+lBb!{m1GFpdhE#2s8KpYA!oR*vuV|~Xb94G`1cwy=nxN+j z%d_EB1;0u?yXn1Vjf;J76KoyAhNUFNgtrs$qXz!9^Su{30$f!nGSWgQ$9IiivuFcDR-L!+JYSd$Q1Olf3w$ z;6nO6vcA+4)E|BXrh9KwGlkb{yvIkFSxWQy zWu=2f`(RUxg(wXHtMFqlI3fn9HD@-74`Ikkzg)`O0J1C!T@u^|_aDl`*8ZXJywF_7 zw`0%Ic^5a>LEpVKW&U-p7v9C*%DB`3OOYH-tf==e|N1H6c*`W}H+=pz$#o8RQmH@e zwKK@a)enjL%l2^6+6%sniydso;{M2*IDIu7EtuJK#b%;0ye4+K9ByM8VFE{^CAqox zm&e6-{O)l8&_d%T#P>)2n6)5Zv127d{Fz|cNbln&h#%H6+uGphC(8EF417|Lou|or~Gkvj@C$>u90hV zeneGq%hrq~>qAq47S!*Lf1;`1){SWrLT zPPogWl=;h^7Yy9RlndRK?w}pA#jeJ$Fszn}7LLg`FtdmsnpiK`Ln{>E*Q3S-_&Xb( z_@o++6PX-5;iwZ~6BYh7My|wr@@pBtI&TPf47Sob_P%5VzwQD5YNn)vKfb_+D3krd z6K2$Jh#`5e9V>|C+EDt>ayYhpE#b~#8#i)P_!kY@_ET8OhUURt@p0u)4Z=5Gm*}ak z-=IW3yjTy>NDqi%4g?bwCNub#OVhpBhwk>tTJU9BYUq=Q$8$wTg@26`PAlWsSIgoI z4uU!1uj&Rf1t*dXmE(uTMq}$}yOZ247R#-!jr)5qYXyN)NiMr`e=nHSDA-mf8}k&F zX$1>T2sXT|Un`M9LM=K<6D=J0P2v7|ZlkhGzJ7815ThW_3LD!7*Qup-=3n5sP6fZl z1)KM!*5#uR9&?r!=a1&ja{lYC3Vw}Z6bUB`{K5{}?_jwZ$P^>1@GrntREx<*TPeQj z*7`z_|1!bjHe(b(q6H9|S*XR>?UY%?zjpCRljdZ4g$7{+lVCVtnjoPS{x#0~Fd5!8 zzg2of3_Q;7Po;h%dUouwp2$55ZDl+&@cva!mZ3 z9y=V_6?#>iw;wAkJy5CN@Q#m#pAL1<(9nU_@Cg(KaQ$KA^YA?T*>0%w%T{wC^XFob z++w37-VuwO2d%bI6w>>cLWnS8YmHznI-7Uaw2UHo=Y#K=`T)NQB;8yh78aNT2lsCz zDC``t;-jH`75v&k1-Ap-L2sdg)6s;D)J+%N?nzj`0KagRoYi$aa&SIiOLi4^l732} zdTmDi;S@d3p{l7t#Nv|OCnMhm5%akW^(u@TfPNv)HZQb8yf})Be3yl|P{B*|RPYOD zVPoybLVW)`e#NB%1Yk>I8~b->8nM;Frr4gt zyqHzzMuYqpkLz)_nt$bJs;6T_aq8ebKLX<8%>jNjI|urr(a>h`FVfG)O#@i>xS_un z`#oD%s&TNRfXf=JkG}+C^finTOCD{Nig5J9B`EV18bMrG+Px z(}VNNDn8F9&aZvy7cWSTW`L0$^?WwYf0h4!3IxR&U!dDD3UiZ~1YqOG%YVgf(-c8Y z6H(#};sAD~eqP$Fy?BP2o0{k*mEnlc8 zR>CVMX&*Eu`{#2j;68>6@=Y0MJf@!P90sqR=w9RE3ddVrT zsfS-x{L8c-b{A(+e|S9LUmkvyL=Zo8{L^Uz@;^pkFz`WeF-ihWobYec)dr;9p@| zg{pEQxT9lSs2r;lId3gY(1RQSzbxS@P8~`Jj&H=6qop-oF2%o|p=)^w*r2JkC}ICV zzp}d2`?v|`zdSD&^u&j)NiUFC)Hl_tJ{Oc5mhGLppkpJT0q;S>Mc@LmDujeDR zA3yB#{{EMXa?=SWswD=p@_QCwg7Fjl{jY=Q&yVe>yPf&qc7gr`=a(mt|H8Pm5Tz%2 z?!=I>7Mx@K24|Oi{Nnn<2j!=2RkrbEKmY`e#a;O#t*X>-_<#S))+c27{wVZkg=-`# z_{I9=sTI9pDFOSCt{p`jJBT0h6W|xD4VxV|yb1(d{i}V0K7R52hg|X$>leR;_y*S> zmVLj^iqoDQ^Xd>AcBSU!!7{x_W9+1tfKNJzUy<|=CMI2IxcL8<-@2i4eUZ`rfZcG1w?YQ8A zy<4mDUmJ-_p4QD1i_NV~NTg=r2>JC1rAqve+W^{H1q99kjWbVin1ht{3-yN{1mGem z2r=N7*QPN&;^~)HzrkU#ke!`^qX^hy{Q|#8SLMIZXZTTldU5YBjMWbFl-${?_#)p* z{>z89VyHvB%8iS9x%f?g$@33Y{XD6#VHDSHuz>rc{J#k1=f9GO&!f*M2?KuJ>vdi| zabP8?>JQ6fH@D(%$Dr}JnlT7L{!8`erpTSZua}7-Ny8JIV%wQT{h_i6s6XVj;G0iQ z%Ci}6vleYoe1a!c^&1t~!u()OQ)*2i1o^L+2U{sIiD25&Jur+D^e`$YAXJ_IQafrz z`ZbUczKBC8jblX%>NgZ~ISl-IGwmG%5hr+ub3N@u8Nby1^Bgw(DdI@0S@`eHufDbV zl{r=CzXJU_0o&r~mpq?RwYz@(eEIKxfwlRxOT`Z}-K7mv^NRuh;;)Y)o!4orOOY0N*f1eRmBh0noz7x5h~Y@|nX44h=V=5sk&gqSmGO)F4BF-5R|?1iJ6~0QsPL=ghk3ha z2$N<070|BPf{k%`RE)@d)6^wMYFay7Q z+7b`FjCep;Fp|fmIM1d8^3~I1;T9n3Lqd5X5rUc z^!YVUzpDR!B^&%1eXinPs&cPtIKj9o@k7%`s{pnFp;EuW`_KVe1ziniMy3J*0bW$$*BN;=!`2IB{uKzXc>2ZnAL7&@AOJS=QX}Kz7r~#$HF`75U|=EL z3Vs2S-nu_k`1Q7JeEhP3UkIp1`Qw&U{ki}PP^+h@0eUw|z)@>X_!qE`7@ z^yC^Hmpxe57`W`AENGr^g}Y4IReG|w<}=zSoZqt+j#dfCui%NhOxbXfLbGMkZbYPe zmLP5KJ(9E(68P_;8W{*R-jjvpHcuvNKC68~{+_+CP!T>ti{!`b;9E~Rl%gi8B~4Zd zn)jsK=cKAX=8NRY0$c$NnKs*!va|W#Zjqw^Pk1MQwls@Jz zOw_FRgnkIWM~*u$VK~9K$btKBkOmO)1k-ZJGUur>9O)agFmJ-TO$R8K>DoMw-Ov4jC zVlEJxAwOVSNu%86$?NqG%VVjln;NQx0rjN(ttYRq`OLs4Qoq-<@Tr>5NKcsKKXLu_ zy6$@YGx9|0nx=-Q0zu=(c;e3U=J2}e_xLX~J~I&JH@ovZ{UR|-t0-~1pOW@bd~T?vLF!e>EK(}^$;&Xt%>c)g4($$ ztQVfha-Vw)UcnyIN-IGvoV~e;pH$l5PYw0iH<}9t3yF_~7xrk*;T!o0mB*!PeeR8k zh2fgDRf4?HUTD@hp6bA(ryjDD`m(@^W|E^>vewqhL%*&^kd!tDyIIKDF;CzpU_%x-qTXE>F~!Bzq@1MeGo451y?oo|ec}+ujQhCpHee-TKKBg^n0$~k5xeiat z-%=s#^a6V`FMeNop}jfT+!MZ$pOl+Wy(T2?DvBANK)8tmPl%rcZNmCT>6m+UqG7!f zniJ;w`5)DW_(|nk6$mJU!W>_4%P(qaNZn*dl z7tdULbG8t)`Hu+kABR>x@oN6Stt^Z@TP+0te0k^k=jXpMI`+B}mRAcwoA-a=LqGk} zgX6EBW#O)C#_u@${@apI&EGeE>Mw#en&@}#vEFOc9lk_ZQ0JB#8C7t62|x#J-pXz$ zq;4`~`8`wxqqBh3Z)6&u)fUO$vF8YBzbUbG-$&@6aOcpuKd zx1X=!; z)7v+10Z@3}TL|U#s`ACE*Bstic`fKtTn+%bg3HczAJjkU94lVEqG7h+l*g5v1pxsl zxL%)$7>*muxI9BxQ*QE(;_^&5E(7%c3cfWPj>}Kp4BE`Vzi4kiobA9F}FQ^tu}=8)ZNdV-jzo|KzZ-lG{|c6pWW zd&zq|pHFQmqq5t^6pDE-ssc38<25&W%3IO@mg%{Ts*HSKiA@<|MQ+`g2-ToU=+BWx>VFt0yBKVpP4y+7k0$h|;<0_fRk@61snL zw=n#9_4|YW;!*N&t-)4*o`>+nD32U1$_5saZu|dG_xuAaW%-H!i>j?qe&YXkXJ_yr zA@SK6EhCZOm%h;LE_N<`cIp2%>0P-?pUwK;u~-<>^;SRK7cX9P`4@rkp7N8RdGM=1 zSbFiN-oN@aZGy)CSK3tRa-h_{5cCHttPy#tH$$*1x;$gAs;w1h_rL$1>g6r(v0$?y zuEsj(?|9Zhh;Px#-<#@d)w*0(VMPkxMwe&3(*K%Cf#%K@f;KaBd8Ydow3$6W!IN^E ziY~ilr4EGIx*YuTK=9vFt;@3}sc$*}s=L2us=r_Ok%?$iz27WUGznOvG%)oDE z;5Rey|Kk}@{t_G}_)AXpH0b2IVY4cgQ~k^TxQy4}!YoRJ|KtDUEn5oBNy`P55Y}5Z z`VTxrfA~HB>Hg4vvH4N`NxU<|aue^+i{63#^G=QHo!UQmkBj;FPwT}ywSV5J`S~yT zo_ApX{Ko$LdZYMG&Cffvf7q=4SF%6v)cm|t_6Pm>4SxNaE&ZR`KZxQZ`1|o!5+w28 ggs8q#_iMft{K{`%lb{^`JFYswe;=--rTmuvADgvpBLDyZ literal 42175 zcmeIb4Rl=PbvC-sdyd4>%t&)A%T(d_Xe7v>j-;_E z+eK1^^!7S!+P?Y$kAH{ap=bwNY<7U+aWO zNXn8;rYDS2GlirsDc?P!+PD?x=)COCN9Xi&G(V(-w`pE>+tCwxK^x#k(t48~m#z8m ze(@&lCkUeu)RR$>H7&>op^!X#e7GU4Mcd6*ujRyUjz zvnJl-hO=Ut4p3_rZ!Q=qZbM6E=`3}*(VYGUolYrXn&zmBqEeqSRDbf?6Lg-s-Dp9d zqjy=zL-3!d_c+$W{(Fqmz03K933-OPoM;B`vH7beDiVHw=p$Opy*w*+(t-Zg2g3g# z-o^&PCttBPFs>a7Q@HZuA)a}OFq0oyyWbY4Lm6@iK zpQBy!I@S5olL9sjK7Domnm$K4$9BWEaCvblY~Vd=O=p&j5@r?OzW6og73W6o#*Fu5 zhknNUu0G1E6}&|1FI%@qu#_V@_84_j)YXr9d&9KUD0p?=be`ju6^HI(=ks^>zC~E$F3bP)I_PVyWy#!XS}t@8oPM6@VCE8|BmT}Fzt9x8fQHH zij&_4#f%) z>z7dah5lF&QlgIga~Q(w-aHc(b?}Sg1Yw!j=$&LiLMvTQzfxuWnqakpO$fR6o^;|< z;Yu;#t@|i!X3-wLyy~n#pR@W;`4 zXdxH>!Z|NHU_75*X2J3w+E&orUe#vMxU*yre=2jdoclaV`!lUpctqqKwdZBoX3o%e z?HFu$rCMc&+jwhXQlw-vC$MRo4q*d~@a~l`o<;ql$epEe@g8gEwMckRvbwAH^ZvLiU=xPDufZdqVXDSD{O#r_R(s}!aR5gIid10_SAD+_-LbWO3SIvIWN>9mH z59LH&q-CoePS+OaCxBmDX|L7fRwajK2M1ZvlHwIlze@OZORhFyJg(WUiTBWEqje}O zYm4~hl<|ufZn;~X!x9{&uBqtgh4@v&<0`_|Bm)^me+VFRcwA-t(q`#Pbd`Gvzh{D# zG5gz7hRtn!{Aw4o^wg9Gtn{pe#$|fmwj6G=0KfK*sNqb~*LW?g_rfoFG~JR4Z|HfO zMkIvw7vdLSYf=H(tq{Zy%}$D1u;J>n0Kd-HD}XN0IR>&Bj6KDTeEeFW^ZclFx9Kvn zvJv?n_yxsJLf;GG3A&pa9CP43@avnf8^GKRqSk&;Hri&NxEQ~%A+=aOoQr*rhWoN^ zJb590!Mu;cSnZUTWc6lx(P@{F?1lIR69))zx(sFOPV#z9ya#?w(_8XJr!u2A*+*;z zWEbNXpzY%^$IR3=(V)HaeejFEZZ$ihj95nZQlk@|T7X}?Gl2!PJ8nB63-;$;%n$HA zfL}$gDNiTt8|k+s(3^ow;g`~{0Desyr;X^E>idVMvu}9@|EHdQ)mIepYYK48KZ;}k z{zoVV;bQ!{6!@jxNpLo8N>hyD^1bkjcA)d7B@7zGdrT{K0e)Rxf_2qqlg1MzO8DjD zDWLx~(aPOuqC?c)3!#KxnvY-8Y*N;>0psYbebBizqnGf@D&rS`teqlqwaxlP+oX?Q z6-E3S9h#xXoMvfe7q73}tU-6O;sX4Fm4M$1dx)(Sp&@0=(Z;i58n!V*KtCX0U;4U9 z^RC!e()ZxWmH|=3uTh0xEeu;P8K=@qUypo6zsfo6A=-ubmC<1{ZJ3lthTm|{u4f=y zUBoXc;}`sS*`1HDWB)gq4i?C>hYG(+{dvS`ar*|)v3snBG3ZybhwlOWLZ7X+@esH9 zJ8E>zf`H4*x@?#5%c`BEJs9$3N%7n&z27dF*9+4~a+?5t&C&*#g4TlmW14bfg~$_n zvu6_m_%%xfr^~I%EuJ;7dl?iiz^|+4^m%LEV*JwQ?Mbs^EK(SzUiDo*e(e{t#sL@D zl&hVk*KdcRPS)BN;MaYynFom5KuA+F8*{seUq%tXEHP>9p_Gfot7yVg$(wLyT+(=F*&0F^?i{^a_c7C2#sy>5D{e>GH&}Zrf_%)1Q%Db3=OMG75 zV8f&^|H69VYdwF1@oPWOYD*eS>T!Y{V@J8-DO78n0errgfL^z$#yq#uWpt3*E!MM6rIPo zfL{)TQ*_>a%8hOa&w2ZY@#~D!m4Rn9YoE1lbRo>p+yLJ50N!Ks*cE=63bx*$$NOW1 z{!G*3&Q6}^c5f{hzjEn>0E=`%IpYK?HV%Uyo2(+SqU0Z5Wx{)Bv^oX~11z{*ylCtj zY{*yD3)6cK^RKrE{EKuK<67ZFlZ(gcY=3g1dYN8}9gWXI{Gx6NQ#r>ztqY`{s!VYk z#;*dk%S2Xxg`TC(EQDD$GH!J?-0ZEF$G;j}XwymB2p8S#7gMwk8fPX&tvAoizn+o} zg{lqWoV`)D|m*QV=iK~{17lwu@Vb^04v>b@Dd1Ga*x9-fp&dH_n z-ZvUgvzsv#0S%PQ$f{r0Z}h%P@h_{3Y7~AkY`Mx;SL`Opzq0M?VMW>C-{oMvAUHRs zB9<<^?*jiacMru2#?Jif0D1@{0%QxD^~=z9^Aig;!TYWy;9qv^HuC{-jod=9o^WQU ziFQ}2->UT1A`AR_E5D~d@j&>)fYJ8;=mWqnIKWQg8+zQ^KXGjrot8YD)o6^X%6R(Jy2dO2;z;7IMpzk)|=AdlMwPZ!eTMNa% z%*4rXGByeQvf0*6!U2wto5|4T3-D_IT;@@8ha2XN{U|lKRRbdKy~o2ZkAK-u$)yU& zz{qaOM^@qgTTrX&fuWQ1WPJxTuJ$|LJbU=n=m4#*(C(%-{HW)o{U|nDd|)VmUpXgR z8&8U;%u?i3)e7-E?RRW4+eO-2cZFXLtQP2r@vP{|NA~M)(pkCOHTMPaYtDkL+dce- zGpF&m7Gr>YUHypm1n}$Kba#Igutn!HonzI7;d%RA9x3pmH_7wE__g1;)@DeOF!*c+ zXK8v5~vcRu-T0%gplgbRL&OgBhq_BX0QAY{3x?R9=!J5q6kgss{0Di$@ z7hy}b9XIDio;KOBy!lutfM0tJTT`&bfyBOKj|*i45u?ou@C%T=Q_N-&CppxY6K@P{ zF@eiFh64BnT2Tww`iUABhLfiwQ_I}y$sm3Kwx(3f6Z>$iEeC9R5_Ue?7sRi3tac-M zpZ+q;`$t^7XPJcmJQ1B*Ql7a_fuOQo2>=DUu+_p4dT~c#~uqe4Lxt?3^U)i z>|2eF)a)Mu(aQM6SYQLT7{6Lx0Tx`UkI06X!wc~19m=`bQBY4>;YN~S6aGfdy*haT ze!;viF7yJnp4s+ueSS6KhvPMG1@TM86BxGUsQX0CBa5G?1W$1{PA$Z*7J^wue1qD? ztM3w5(7%`s?&Vexze+Jr>(P;xeDjx~J0tQsCSqm$GO&~shMPl4tm(It)>_JlxEp?A zD1cv#R^e>pjCqDyWlgpNK;}FqqqE^4e)+H^x~!;NE!{c$T8a+7C;x(x>AkbI@mlj) zss%`ehdfFI!}cbMIW-yRj>S6Y#Shz@@RSN0CVKi{@J9xz znZfR!l71PqJE5Y53|omcrd4BP2Wiv^F&6M^RQwQrlm}Z+P?s5zi|rv-yHShYt$)wc zFQ0$q7EfDewXQYMy2Yniarjf>towj-|X4LK>V-( ztV{s5#Ef+U!H)3VB7k3Bv@mv@LotA@%5m_ogaeHW@GnG4y|Htk6<{|_Uw2v&DHQ?y z@*(K}Kq|t4#3K$s>KpILzfRkotNu8rPfHa)yg!Iv^JcdheFm<`oO6``tZT6etz95E z95QU4L*N%Z=Co#R*#+2ojM`*+*XlpFHXC{tj$#16a!$emDRnh$w&SKPK0(7|!}^6n z7vUGf7TmD)L;pK%%r%Sw$O8EF3)zy5u1DCA1BrmGo9Tt@?uO_Yy?FtCIm(qiiw)Vf zYj~QTvSIM|1^L&zvO9(B3HMvPNJFa zd7hszqUAl?G6DZE%N`>MX-aHAKBISbbh2e zkMP<#Iz57giD@Zq-Lw0f!h!)6y0k){7N1viow34F7 z!{C+FJ&tkt{A*JEI^Zt?{)P8^RZjpo)ch3lUlWTmG=dAm@L~Qn+-r}S$)0K&{uGB1M8w&fR%;r_e~o36 z`y->nzbVJu_R+|9^k(y%vqvIO@8`b?V&3ky+FtO*8UEvp|Mn*74#B;RO)$`_D zOc9MY1NfzNIe+YR6%b${4)Cs*R4U__ID}C|tgs5xIgu&wo!7i^1@d2MBc@^d*;bk! zV*DZ_t;OgTKmXNN@vn5ZY;f1#F0K#=1-t1a;-Y_Fig_yis$cRgx>q(1^c@p7)Zd$G zOvSfjfd80kToo>mA3q$YBb4knx9iu?5x4zz#51p@*QAQm7UPHOHSjNt>(=f1w9NvR z;HUE62~QTp4=3#oGcvI_Y0gszd=i+8@l=Nia$U-QRm8>6*v^dE9IB!{hq9UQIsn<` z-Wa@{VEk~{;;q$FZSJ+R6XEulOHu;As2o4+q_64?wBD_?B2SnN65Dv5Hm+)LZ&?sO zgdNL9`t({lC6}&K`7c-QW<-0vgkM|f40SrN035QYu^`NdvxXXAnSY7Ha<6^ogx)U3 z2lv{EIS4Ndb)*oOD(AnP5vu`6RC^_Dv>Keyz|a*mVqG^9{$e@*^#pC@t@W1p3T>lC zX|59coQk!O-!lhK3vKbdEpuE^Sb+B$lN@oSgvJ~#_EOm;d-!}F6b9fkHgNO?QGEQ za<}FD{MVHyy!ghzbtld9v~pFA)5tm2zk-J!>gO{tEzozmbqI_&$C;OphBo z-EfxJsTVFN=eYfKQ#p!7{GuhZ#xc7+U2W^8yoD}3RGrgb7AKreCvm^-dhwRL_5_Uk z)y^eT;ZuUiNSI0S|A2!BfDXnFy~x0f`vP@LY|ZJfxo7&Z%Gol0CFp=enp?t6-PqqS zVSc~%Ke&Fw!devZi{pp8EqJ*kejpx_@hLNoG|Fz7u*0DeexZKDdStw1$1PtLFFOAK z3e&fqUhI2huqA)XhFTxL5I?k`JC;69KQZ@DG&K!RuKf~yMMjgu0sKO?3#0gr6ZGT$ z8{BAqaiM>HQFkxa%f~OMo@jTsjW&LPew;%1dUWx%=8+NDAE^iGH}+8jh5LbD!-R3! z`t5X&rW8L=zwx+KX!U>4-)8LTsu^*Wxe-rpS%6>rE!z&8FsH+s?N-^ssgs(rEdl&G zBll#ZqmAq3i((I4U_B1QGn5J9SDxk_RG}Qgj+!$%sYWg?81vd+2{6qve$nYHThU8k zJn2S9;TM>~D(GndzYa*HDbwH}F^^vqD>{7qYN98BU#NFEMIWJNZi5;IsaT1RUj}Gb zgR=!;LlgP0H7iv81_G^^v7&x?@xwiYSqi?WS1yrxEx z)QrF_~BlPJI$5~ zbs}`;#XQmH+k^QpgyoAvCfzZoYJb6F_i9&C+~;f^PcQm&Kiq>aQ_i^;*aR);N=3JW zf7#r|tKayZqi3{fS_;_05`a8XR}X}vFPQTNoa6}~zl^y2 zDk!;`6*F=(#US*|Sg7CFsql-x3LNcbVhQGzi?fTAzqhLhMvYMyQFQf4j_ zW~%2U`UkqsH3w*lmQf3Z9Z}S;xVfAT%kG)P`VSwYX}Q9V^l2|z|JR6$C>|~0*Dir@ z&2%(-$t3-Vmb<{OX$#QrUr@t=a$-K%ij5r_lznf;2X*S}(5OP~|8#Mw%m=^A23dq1Lp7U#6G; zigF5x^Y{^tv&|WQ$!p=lZsEi6!*ldk+-Fr9#IVKw{Y`GPpv_dKxDE1Ox4n_MX&`~L zSI=x_Z&S??{ZE}2^d9SamLlUpuI^zuD}`Qr6n}A#+50 zOAb5nWN1PC;oX3(_?g(js*&77c4&_N#@;wsmDe_u^o#RfKcP;ihIC2a9YA=vw(4Q= ztX7|H4e~GNJU!(`@6ta*KTfW6s|WP2;E77M2Jq`yEce>n>IB_FwG_#&PAozqOv45U z;MYd2!Ho~VSKp{z@5T$FlM`Vw;`1-ge{GZx<;|~zx@e=@m`BX>D%v>IlKs#E{2C@i zi916rnc#r(=KQ^-w%?l)6X%F~GlymR~`D z)5ResJaLfa4Dv5Jl5J1be0>;n07Ojjf+I4S0+5yQ%N#tkbHJ>-?8C<3;Lh9nwudTd z(2cDHNcs3>h)quHwoqp18t2<_yWgyp>zqyf%BuVLRS6%GvqC+F65pnk(8q`fqg@D)R3OO$OSX~ICkgACSh+-<HBCpXcBcmYseJ8|?VpTfv?l#! zYG0SgXcyFP{1alHf^oSm6P-3s(?JM}{rZiaG+EJYwz+yv%sP85;8)U_sB0IPpEX4s ztoTj(4mD@ie@h^-XvFsSJuKqlt8xb;+ELF}k5~Lw|M0}a5RRQ?OOlOE>o+>au}sJ4xV+xRGW`in8r{8EcOSpFegjauzxGW7fmjY3 zHeu#lUyBFvivYC~=<1k}k?ZWslcF~}WPn@M2l?0j=AC#CFcAbs8_5=LN*snA{ff;ppZ>ahWH^Khl4``6=fvOe2 zWdwR0vr`1}Uyo!G`83Kl=pNaSt@^UKs^{+Q4eOdW+;4hyjEr9e>U1Lw;9rL*=~O2X zP;&coy@_PF*3&Pp-#}f88=Y#LGtXH!$(n&icuiJ!@2!FOA?i2e9yglPJRh=p1=j0% zV~>l(ZlHbxZlMeBbc#l(fmnAC#AuN5fu2D9#zC;H%TczWJt{xXVZ%>p=zPJPgYi@! zRlnhISOXfDg<7piiWV_^%+8y3D3Jd;XSGXsdJ_gzhJ`QF^OtsH6E82Q-=I!-=Bo?z zApHha$VM)@?y_%PfM0AXBTNU5fPd9IpikR}cC-(GcbD;t4)he$I#`R_RDS2%PCOM4 z;8zo=)DQTVb1(g7e+W4sv8i_R4RjSiNj(C#d)v#_?2R|#b}j>0lA54 zB+S02mS?mVxc&PVe99W@2>CuWVpYKU(>J>UCfDQ>AzE}Ta5wA=SDjy zlGLBkQasV6{MRR>a1E#xnJ(A&QY?*~c|rZWX|*3W{u)%Vs$YydgR~RLJM>wt7}w7u zZQ)dba%%Td+bVNPjMJw2m=nKmLH%J$&GR({ubjZ#}5hR<@w0m z;&b$GgG=+(oSQ&mh2Im%e*uXYl72`d4)hE8FZnNjc)bL|7IRXneuLwp1K5YaFRJPj zC$)|AhxeF;AwU1ZuaS~(Ui02 zM0HMom!9ptQ6`=Y)^D7)!M}1)8N{Om+`?IU%f57|?STM(VIL|_7<{?@CW=n!Cy{UJ z$lW;=rV@VLNxNOd$8zF1P=DBGkR$86ZY*nFz99c4*>uNd%u&&-+7Lit5PQ}3)`IId zP+7!lI*v6(xW*Ebl{?5D1TqSZhpy@mi)HgJ&CrcZyH3&(ZRsHNi%R%4Pd_KvL*SRe zIXf2ki3AawsT|b@X;JwE82|1waQk`M0*0l$n^+uUBt ze+BC2C#{@RRFUX@LV^$HzclZ=yz^h2>6^9o+pUMf$(|;AiwT8&Fo<8OJ^^b1Aj6^* z^f)Wpbagt&ztnK%7oYb?aY27&}YuGbp*8_0=EyL!q z`}OnakK)4N0>-sPL$ojx#4n^Ec`Z;vW2;5co$ORXhV1};8LAfI%i<+^QmUZbWnecg zP2o8>R1SZafBtJJ@at{LA=$b*0wwCSq6_d#jq9z|r|6fZ^}@IalQ318;`ea<;X6E> z?U)u-KfhZ?T_q*uy;A=pQuFN9AMS7w&8RmXg%b$HKLMe^NDnNm-?%0p{*3UFci}%n z=l99RY}LFN@bnA#W$iVZTx>sK>>aV)Ej$T(rET|d9i!4O@BA0sjM4Dr_Bpd1#!5fq z9;95ZIxAwy={5g02{^9xTyL=FA z0e%7FcxO(V@6sM;+c%Im=ZZuOu+m$v5`Ntxdk{a=VmMw`YvX`qOhaTlP`|-t8(52R zHV#g>F2tjNkckOTzkpv>F`7Ef@t;*&z$+yRYk5CcdTYV;hwLZt^djb|=J^^ru&Vt} zqnC!`0sKOnTQjTC*kEDtPmzl}ct?0a{f3IB%3+&Ss0s>!iE6KhewFiI99fd#nW4Dx z2n$)L%vbY`EcpCuEvgNnU!9={ht62hOd7Vc1qj9XVOG1sRQ2;4;D#yTE^%2Ca!LKz z*fXAg7^pui9t8VyoZEU%F3oS-P|klnY$)4e>9d}Y(`N;8)odJs_?5Xj4>!KcctHun zXJ8@!YC6cj9;ELtY8emr>z_#-?}q^WQU}3q3Gy$mtF9ONaFH5Q2f<``V953Ki}6cE z)kypnWgIp3XK0UgXFA+j=3fs(%~cQKTK7UI0FoYayK>_h^>r}R5yCmCDF{CQQaKlw zp^dmkF`NT=+-xJhfHo!lV*J8zD8^-nYFs2xYb3FzKL5JY>ocI%QhhGyyno;T=gRpn zc<*o&);ZfcBhcK>L9%(*$Du`e3NvdFW zvJT^W4Zr7Ej2$nu%J_AlxApe$jmYaUA4E6iX>e<++q|HDez%iIAtJqv9-_D#;&H)I zbgFWp0RQ^__Lfw52B^1Hq9}rE(Scv`1O|6*^gYwh{0Konxu|O46CcIIv1=z z1lw|=FY70OUn}z%*L)1St~XeJ_&kc0V0I+%i(~ls^*0IeIvL3Y`4?z~3$?1FBL6xG z0S8t3gZTB=>4wzhedzOp^1s!CBNJJ3LkL8gv4Hv4*QA|CZF2-ehNFnFTXG^% z0PnuvTX)8<7isVQ=r!T%oEPbOS)B!*KA-R2ANfxBF(1FgOi$N`qT}$0)Ovx`2rqu9 zeTtOsl+G{XbVHNEuLuL#Y3g*=mhp?$LBA4?xqWdjsiRLGHnlpTjE`RxMgEoPS!Sr( zj8YpgpfY|{?Zx(s7sPFJFFoX#9w;Q7(8BsdO{JA>F`*&9gFbUirY=ztZq@sFez^Wn z`G*#Kk|O_l)p}QSe=<51;5 z9uPkNswJFOPDM8?t`+|#p*uJTM&q(GADIvT5#EiDd1aPYP{Ov%65?zwOeM}qnO$Qz z2sY&Thg6|%Z)jROvACAFunlJL96g`u&L`${pMPcOQ4M8~DC?D6l3@;rlZbGl(D#dF z{*|Hcn=L){h03Ic`VFrQpII{l_46(qBWRpCg!-sHE|h|Pp*Wy$-HP)0FZ5aBn2e#f z2u>V8&1aE$?4Cl${Q5(6Y`G8hhd;65wC8zT_$}o61M$NG%zMW~q_DVCf_Ax)0_@Lo zvfE9d-mkZaUn$C2Di2Gx(s#Dc-*s9Kp}NK{<-ctBBr%R`15Z7hIZK_Yu2X^B;p&o$w*LkD+5Corp zy~N|nciyFUiXTW2)wysx0hieWDL4bX?ykCj19_0SHC>>Jji=1f+GbWXRe$K&x(VQy z;=)Tq5r@Z)6iJ+7O3A)d7=T&yt~oYd0c4)&;kDSGrR{U6CW1O+U?_sClDu@_!Pef zaY)sl6B@c<+Y>cE7oFmtoyL5mMH~ikW~V{~>Ng&ul#6QKZ3t`FbD)!BB0~v~$I4>; zVF7lID<48%7BvoPA@b(!;w6U&M`2f=*WmYJT&3Ll z1kR_ZN~dMwiXo+6{o;h!DDL2Ttz+KUC4EzHsU&*%O>{mxgJa9bXkJPD$ zTawKle#LQARxK|4sN#EoU&c|?=^<=5Y96I_8OiIXo#&H#_=#VCh-??(WGm?|giZqZ z=Ba=u3;35f;_-rOC4}|nH}q@BtLP}l4|_qWTAlC%v1`R9(V7~q2VX8$bolu%WU{zT z20vmU#5v6ars5#acs7&Ie<=uP-^^w6i8X*fa2XtAhWAzU51D^)Srq&qTTX~BvqtJR zG5<`tM9PC+)jd$k~0MsH;g@Nh<6ilz9dfxiTABzxXn7 zct`=+QDO0SnM;cJl?zV`!0{@za9F`Z(cC3P{^cP5g;P;B&VMa8Ul{66p^WVpbbhEi zfAwj7%Jb((7i|ZgB8!LfU(SftGGgAr{0kks+~;2wZRZ*x1CVqD`kZh>z_^sE@fheS z>eu?Z3AULSSBwazl0t@Xx8eW=tWCLoV;58g-bGf2AB7EBGot^5{>)MK@MoUQ%pm^- zTz1=RK+;+2bgOg2z^|-olcyAqU0SF3<_ZTTVR1I^tf%|Mq}JhXE9i%MZPf<#z3?|+ z{hFHuifSDAbq1j@o9$tcf3be$kU~;zGGZ5fquy&n{rn!&sKK}rd5ps3abbWE?xQS^ zYs}y#ByoOO=??Pvz~wH+<%i)3D?1jb-+&wMZVS|JaIuiG^Tk+q;QVqsA*sZ$1uT#_ z?{F5LmC`|VetAftRV&UID&ZUpuc7cJXC%2l%)gW$CDGO0hFXG2hrL|0L$rJP#rJQ3 zmhx;|Q=BN^I}uK@?uQZoO-L?s*RJR8pOL-Z#f-UT-`ol+f}=S6X=3&Hqd zu8=r|XyFfB>3HKJ6{t@l7^2pT?~mFiTloCfnc5<3G5>1IgVc0-HnWufirT}IFrJ+* z9|RLmLqH{bApfO&+9_xX3K6~GbbISHRhi;>=J+AT!8W-?h2jn`f@yK%aqMH=kQn?(@*+Q|3otMQ#2r#xJ#|#-(nBlstA^ z6u@Ke%LU_yZ?jL^pwG})1VR=94l<8I<8Ji6%Znd^CcC)NW!9--2w)&ncQq`CA1-GL z*@TU)%qd&`E+>%*3q$QOb^eQD&Xx>x=RnGf9|EKj4q}6)_+bTpL?3p;;2_$QXskF0 z0~s#sDDyA0!EGB;fPg0{>j1XKu_$PBX~{qI;)l!8RfNUnsh#_rXGBB(E6Bf~gKP%J zRlzxgSJ8P`iTi^5i_0mMsVu^lH?C-=@mf#6y!fF)s{+dNl#r()5&Nn)cCJ5slCE>Y z$l0Ou*;P2o$9?9AVyM>BFV25GNsT-%uDvXeJ%vfQ$6E_^e%b2}hXlQOR)_{}^&b2y zecDt2jREpVE#Oy*_Xgt^_NvKiN^_2aEze7d$YB2Kv3^x;__}@2ZuR&VGcq`?KL1)< z++#yyR)LW&_wiDB;Z|{Iai8(|Lx48!a~roY$mafV{19b_$*PEW1{sCY*hQ*_Y|>w~-^vv27$5SA6vD0En)3Y{Se@}2q!Q%me!opuzAf2UuHRsj zLJ?P$K&V6*>^$DHHm4V3Xexe)Z#Q$G$@^V(f0SpR*XP11&zF#}nU8~Upv^2DNGsU# z+Te-pt%Y}fxs~|31GrdCup2;1Z%u1^G##(-pIJ8YMFI>I{n!(@-l*7HVlGkdS?)gkM>EOFVWozUOGG!1=FN z;<-?>0sK0Iu@~z%XvxpWb=obI3&QVpAs{Sf&$()(QziU*z$xbJyd}Vq1JQT z=U@Lw&pMcm{X8u_UE@)St6e4>REFe`N3(fc6BRb4?ZhIJdd6(z?CkK8o)23uRy4Zl zLYaT{lI%;=gLb(f*9pQ}5Df{CN5B3srQJvy?*m$WrROCFwGgMmuZhd8zX2mdAaTN5 z(>{|BE$qZy7VweYae!Z>lXO!cm<#F;aax&b+||WvzK(}a@UC;O{`s(vU(@ugOajgI z=f%@9mrvB|-?2atCZL0U{l@mth-e_Bxu;0Q4;}G<^)34R@yqWj#}DtP5qXX6(XOF8 zlID7G8J@JvgjR^8r(b<_vp}m|lkuhExzunyc;!-YkIiv_aB@vK|0RwVmggb~{b%N8 zw>=vf)o+r|)G8qJ@vDHiEK#z^)=y(ja&H@o5J%C?F1c$1I8NWPIqY^Zc%<3|J ziA@%KzXxz_)N4-bCqcwGK8E^)%$gE@X*k;@{>f@HG=(vBlSbqrqg%IUpCps0bgIeu%5>tAe8sOGI{LnR-c7>rkigtmBW!bZ$ zbm0DtX&|)?IIfI9^)MWq#e;E3IB|}7Dm|@V^7n)?q~7p-jPKkg6Z?mX1GaLcE6ezG z#BT44*6L02ElT!9E@S>>C`MMsuh406kn1=810`WyH*e!&`_r=10SX7=hZ9xpwg>By zCu;a7<^&=U+XDDyihJ^na?5M?&(K$8+fLA)Ir!K$3}gZP8fMRYnV1yAoCr(yOq2qN zW&Dx|Ba8vI&VkE(p7HB#FOb-dAdkbk4E(Y=+!yAs;SVJ6YrX!Wi9q69^v`|#s(u)d z4fCE|JxhNs)E4DSe!5<~dUpxGP(R;}Yd3t@n#OT}WAtO$&4}j54y^82=noa(&JhC82aqv*Tddy$XJufaZwPlS^2mP zEb#G*`4@H+C8WA0ZV%(~o2p_#;g0GL^DlS~1Qed5b6JJU;P?{jRaoug*Td>Pk=?@y z0|m@33_b%r_)Y-766j9?e7APzx}Af~r$VYf>?19RAM(t{O`+5M6HR#xXVTmYf|*Xn zit$75{@%8{`Dfyr4la_)hc@*5n3&xJ@hgJ3D6_4_X3sHm+1S>kKI!n2L=e9)E_fF` zi%&UkSRWY&9KY)nd8LnE-u%GJH9#j-+!z}hS_ys{sGmnPgIf50o8xr7YvS%2j&J-3 zzF*+{*Q2s6hHAquZJYeV{AC*|aeq`=^||2b7xS;Z)Kb5R1Q9}}ZYbFUMmEUtaJ)z9 zg;&4PDI<3HIx*%vCR>?*@tr)0i{ghx{JNAXBx8XxdO`eR*ouIE*+)#3j+sTxwt6z= zeV50-TAlTo%SI|UQC8I!(gCe?6|gA~KP=WC0?2TO5`Kj9O~m{QUarG-gX4$0330Y5 zu@48C)%}ND6p`pR7sL-)t-!Wy!EQ1pocTp3c4j$#2&+z=&aGC*wDFc;^S&6>hH>26 zgX)M%wO9H6C^ZTT>&0~`7~njf>|vo4Kjiy+4MwYQN~FaN2qgCK6BS5YP=AO~^w%!a z?$)m3%dfc4wxjy&eHZxG0nzHD@2mY2#|tFFwiL1ZnKFKHpA(m&{PhT}0KH|S=eDy@ zjLE3_!=ej;t}0TD`#0KLzR}jqLQTk;DiJn0H zJZu72p=9;E`FnIJ+sqk@Z32V<|6;ZknHuhLo-=Ww85_@HBFybox~%R$6tHZ&VvXh* zCno!H;%D}EVW?pbOYuYGToj^ZM4}EhT;fNsBWC5bDd|@P9=P!rWK24V9=Jrjs@#Cls!x};ywpaH26GnGy; z7lNNYe(f?Ir=2d2Pe*`@4X}f&_)ABk^NDzc{uzq8>AGD(L{%W}` zWxtK>_a^S&uv69h^}D>a$X7TRg&j{vYBd^m>?w1(I4p-#_U%{{KYn-87U8wnS>0q&|;wpQuL?Z0V*oWwI0~ndlzYs07?AJ`L$mQfFn<|4B7eMCMZ)~UM zS9RPUnI8TK0v#$5_WC_XjpSe?UydKXLUVSP)i!bq$_^dAKdMB;+#r4-T9`up2JYXm z+fxxsX9KJ3d>Oy$5G~vQi(T2YDP{M?Gqn{X#X^oUehEYi@uN`F&6{XvZ#olVAZui_ z^6{$)kvD~C5aK%>(5^bVTZbX)FXz9&zfjT?$?7&u*n9ZeLmP!0?by*}{Nl68E1f9U zAF8k+xE}BVc0O0euSs=W0+Bbqe62$yn(#R+kri}>~TbnnPRsV#_|3a(3mle~@nM@C5D{-*eKM3E-DtMux6>;0rj0fG5?N)dBuBS&vfy?r_qbHz7zp ziNs2Wh>Qp0hd`^e8IS!YAucM-o%$c8H)W*1!^N;h(Lg@wL*SY(Rqa#e*R%tNVgO}+}`{Bc9b1{ zN#IIDt%1T09K{iPM{g)_{|3hxIdosit|P7vm<@9&3!{I3?)8x-O<$UQ;9|3 zUr#roX3B+7Lo#jmBL)({FU03rW%$aPb|;+ETkQ!q)>{*(Kb*k!>&kfm^mvkF4IG5OznB7Ky@}0RK`|ULr9Z&c=R1k8xV|ehOh+K7M8CtOct+f@yg+34GtBx6o0o{g`@>&GR!+5tI9+?V322OIuvj z2<1fU$d4#?41!<3(L=dB+Tg?%yU>Sl_kIFaJ)6h4eEwBSeE*?&3u@67e$BwS`)0Ob z0skUciJTkn*b<374FUGqWZcoN2=K2QowHUN(bf7CmI-dgKzM%We3MFq`S_KmF^Q-n z;}_#QOrNP9KVCmdnXKWNv_z+YA8zuX}Ix}Ua5^bq`O(Z-QGUd2JMtBCKs z0%!F3mrGK!sfvA)hX`?O!j*JGZmb?-_xV?vj>vOb8Chh=!jUZl!{LTZhyJ^sg z^~3)u;}_klwe{i*?=k?{PSlwr*}BPV6TmNAsp`c0Ll5BCm%S!zAqTBaGza+?C<61Z z)hh@EDkjH!;T?09dg>o zBMbQ#>kjY>M^_L?+#HIDboQZaT$b^R*%sZ1K1IsfJJuQfE7V*L_piCv>G z{Y^6VJAhLQAjuE`;|5fl9DPk_t#djT2jXP(^yIhhIni1}9dQvOVp9BxN%*z^@sphO<`(U#6}RjLXNb zcj%niEg}=c;FSaelGj&==TW~A#IF=RmT$E}Pm1sL?|^-dr{KzN1>uD~Ea6v$O$Zwf zVXrnpWdH#nVg~pZahno;5g}|SLrJXrPKt9I10G{D#RK@2DxnqpL)bBF8 zetGqW?9Y4l(8Wb)il+qd3-QBvM}cWFaZ;&zPJdUvV5>l4F@DJPhuzYi09qkzC|ljo zesNN6ld&-zWG)y<4-1$JqYYC07L(#C{4D^&qnKYBx+ZBSli5x=1 z&p-6)H*Cf)gbgWXE1_7wQH&qI3VBjPFtoiD}@z52t0K7KXvxCF+HTjwP3i_b6rK<+&S<}y{{U*J~B9ULv>{s5a&V!n?HebFBu zzaGRg?Qn~2;2WdQg4=BI@hgS+A^ysMr(b(0mIu&J!cEHZ*iU$N)r%hjWpb;z&+V_k zEu4ov?BKwQk6$YPU1Cqr67sd}I@?XCM!A%tK>mW7xn!MhLC#sMm?|qj<{_C-Z z7*`|kwNW4%wn(79McL<~e#wdiQ)$nJqs>Gp3x8e_u>gKWEYzix#>F8xCf9g^aTWE8 z>ksD;Elhah>T+wc;ZF1!{Q>6cMgE2Q4Q18Q=U*`G%0sv?e(1p#XqR$4>?kMMCuyk@ zTz3q#_ZA zL?BTDzorajpVj$gr}a3r$?s1BL~N%7!UplHFOd&lBYt3Wx*SU&4C%r``uOGl{Yu=w zVLu{Uvf&k>T6^Rh4eNkk6J`8*$Lt(K$b#|fD}3#|Ar9eIl^}i<$MwTTTqVZ|zPI#K z0w=1~;sO4}_=Qx$F0}-l6UV{5qlEi67UCDz zLa6!;4dY^4hs*O>2;vtH$7*b1P=KH}Ift|)TiSB`(AzeEBnUNZmanBvPVTTqBa+8mQ~){kNDw2{NkmY3aR=HC;X|Qy6oNY>%6-x7`nat=fS_wL!0I}_O1%) z8#)%=ALVtGA;2^5<$#;dzq}u9^V@u5_}VNS`}L72J(&NZR@86A3cxQ2BjP&z4Yi#T zKo-b6?Pcu70d0l&3-C)Jk>BSE`gbSUk9mHt z{MP{wws4;Vgtm+x;9qKsVofD{egdg!5EITG3#uRT^ebM0`{$`OixmIQBm{;n+=%EX z{uT1{g7aVS)d}W;|L#)4tA3sDGoLZ(-{h`{}N$k~oaFH+eY9M~d_4Bwt z3iXF_C7=I-zRP45h}JCBng;IQD4F;08&d7wWC_1Geu(>svbgQAXc*`8Zcc<{69N9k z`gOgtMg4sT?+;nlLBFmafqn(>>j^^G5U}MbBga67@C0pq{>A#$#36z)dv7{1g|SD_ zrYVcD2jYkD=lQP#ykehCE2@})ezosseJ}ZJJyLX@pSs#cLXfAF4a^*_S9nEyjho6~^WBFNI&8-6+DA0$&MxSghZm z!>jZG=cM&vqxz5%eglHWPyTPC+Fh#FoeuX_d{O(1^SjoP@qj?;iMv!`B}t(nu5H(v z#?VEAw7vI8(o%FgaRT2LD)`Co;7PH~;l7Hyw9m-jwU`xJWv-Wg5OPq#1IRZS@(YHivK4KPiu= zuCK55gd12`G^n1GzU%PK6<-|uOzL;*mplXE3ME{!6i+@@kG<;6&qr_8zbH?pZm6$% zrYKZAL*A1s-9@D~!S{GCtXnE0{6cq;r(Yy4QmY|tV8mpNlh||WQ>on{Z%VK8d8Eh2*CrOL{ct&~0|FSwW?7=~};gTXIRH zVs$`}x7ka~3a8j-LWM9{N_|;?qM>FOipEb$O+MNqNJ`r_O~FFeM#Yt&L21WKv-DjU zdrD(#vqTon4)m+^q&Tj_j((wjv9X#^8dv%p2mvxhkh^lJ6o4Ll;88w{zbPLpVpQ*zOag) zd=yVg-(@!Rn223_i{C%A#J;<)_~hG(Q@3{R@Z(yovnvlmTVB)FwE@B1D`>f*;N!Lg6aMImMRZJLcWgSFY- z(M1;vrMI{dQl=}Zt-VNaissNIVmS73xhyyul#)ND>#L2YEzqB`;I}bS@GfqqMe<_7 zYh!7SNYQq>ma61M!jSqZaz6T=xa=Wy(e^rMdND5hPt=PXbTA1tR{{461y?mu-{r&T zg@W{KucN&uE_)t|^xo62^_1cGqW6@(%Q5=3I{GLrx>)G(zN?QaX_d56M!j~i;Jt?W zfN>Y%vj3#m#sQu#z-1qxAvi@$(QY;vjz3nv=$VTIx7cUxX7NS&VCuub<%@)3oBoe3 zz;_?$l`vME!}rAHh5F@S?03leRAs$(&qadt`a>U085IA1t^7qoaSrQH_1=E$Pqiv(GmL(O40E}Iik1ZeMxdXb~`F&r}rD_mY6$kKN? zz5R>ofWnL3Lny6Rz!wXy`B1<|x)7IrfQI0G73{_*^xt-lPhG#P`eMN;jjQh>2=GC{ zExw2tj%!P}yg*o0YVv{N@u-|A^5QIuELKSEOrJb1N2|X;t8qBSDQfjjBJ(C`ofy2_5 z@IwD1d6RW4*jp-|jwjyd{dSSFsIrWuoUPQr+m%0NaW8i)*woje z9uqzA+u-OMYLT60DffJoFL-w0|6cmYBj1!4KD^-nZLKNnZw&Rb?(^r*yDVKSsGq<0kGjwQmG@h} zvQ6>L|DUv3pv%5eE5Yv%E!5?bLn#qID7W#q77Jyi<^nGN^WN_vexd&CeJblGq7feRO_u>ZvWF8|5J!hhK|e#hQdKv}=W3!J2$kH2rDU;p6OGw|yf z`1K6@dIo+y1HYbuU(dk*k7q#nOK_OrFFEfy4LZ4Q#PnlF@7d-*@er@kDMHD}f1>TL zY9cgeNY<5OS--07ulgDK!|(ZD?hpMJn;+GmH~9g*=mXe4AJn)$sQrWYxR{^+ zWxe>I_Rj}3KmR4)^8xIiU)!HwWetg!{R6SjAJqO~v-)4j{(MmL^Fi4k^yk<3^((gY t|IGeLs$#weS0+hnc(tA+r|MUHh5w^s`-&uG`S-Z$0RKHyPD>SA{=f6eg$V!v From 181573078386bd50a85ea482a6c43c3e512d5854 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 1 Jan 2020 20:54:10 +0100 Subject: [PATCH 1342/1854] style --- armsrc/fpgaloader.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/armsrc/fpgaloader.h b/armsrc/fpgaloader.h index 6f27c10ee..c91fb3315 100644 --- a/armsrc/fpgaloader.h +++ b/armsrc/fpgaloader.h @@ -20,12 +20,12 @@ // definitions for multiple FPGA config files support #define FPGA_BITSTREAM_LF 1 #define FPGA_BITSTREAM_HF 2 -//#define FPGA_BITSTREAM_FELICA 3 // Definitions for the FPGA commands. #define FPGA_CMD_SET_CONFREG (1<<12) #define FPGA_CMD_SET_DIVISOR (2<<12) #define FPGA_CMD_SET_USER_BYTE1 (3<<12) + // Definitions for the FPGA configuration word. // LF #define FPGA_MAJOR_MODE_LF_READER (0<<5) @@ -43,18 +43,22 @@ #define FPGA_MAJOR_MODE_OFF_LF (6<<5) #define FPGA_MAJOR_MODE_OFF (7<<5) -// Options for LF_ADC +// Options for LF_READER #define FPGA_LF_ADC_READER_FIELD (1<<0) + // Options for LF_EDGE_DETECT #define FPGA_CMD_SET_EDGE_DETECT_THRESHOLD FPGA_CMD_SET_USER_BYTE1 #define FPGA_LF_EDGE_DETECT_READER_FIELD (1<<0) #define FPGA_LF_EDGE_DETECT_TOGGLE_MODE (1<<1) + // Options for the HF reader, tx to tag #define FPGA_HF_READER_TX_SHALLOW_MOD (1<<0) + // Options for the HF reader, correlating against rx from tag #define FPGA_HF_READER_RX_XCORR_848_KHZ (1<<0) #define FPGA_HF_READER_RX_XCORR_SNOOP (1<<1) #define FPGA_HF_READER_RX_XCORR_QUARTER (1<<2) + // Options for the HF simulated tag, how to modulate #define FPGA_HF_SIMULATOR_NO_MODULATION 0x0 // 0000 #define FPGA_HF_SIMULATOR_MODULATE_BPSK 0x1 // 0001 From 3e90f831ffc17f64d88df4ce1bd1fa1314ed41d0 Mon Sep 17 00:00:00 2001 From: Thorsten Bosbach Date: Wed, 1 Jan 2020 21:15:40 +0100 Subject: [PATCH 1343/1854] changelog entry + print load file content --- CHANGELOG.md | 1 + armsrc/hitagS.c | 52 +++++++++++++++++++++++++++---------------------- 2 files changed, 30 insertions(+), 23 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ee2468215..258887ca2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -398,6 +398,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Added trailer block decoding to `hf mf rdbl` and `hf mf cgetbl` (@merlokk) - Added `hf mf mad` and `hf mfp mad` MAD decode, check and print commands (@merlokk) - Add `script run luxeodump` (@0xdrrb) + - Fix `lf hitag reader 02` - print all bytes (@bosb) ### Fixed diff --git a/armsrc/hitagS.c b/armsrc/hitagS.c index 9d86be616..c4a4a48cb 100644 --- a/armsrc/hitagS.c +++ b/armsrc/hitagS.c @@ -953,6 +953,12 @@ void SimulateHitagSTag(bool tag_mem_supplied, uint8_t *data) { tag.max_page = 8; if ((tag.pages[1][3] & 0x2) == 0 && (tag.pages[1][3] & 0x1) == 0) tag.max_page = 0; + for (i = 0; i < tag.max_page; i++) + Dbprintf("Page[%2d]: %02X %02X %02X %02X", i, + (tag.pages[i][3]) & 0xff, + (tag.pages[i][2]) & 0xff, + (tag.pages[i][1]) & 0xff, + tag.pages[i][0] & 0xff); //con1 tag.auth = 0; if ((tag.pages[1][2] & 0x80) == 0x80) @@ -1145,7 +1151,7 @@ void ReadHitagS(hitag_function htf, hitag_data *htd) { int reset_sof = 1; int t_wait = HITAG_T_WAIT_MAX; bool bStop = false; - int sendNum = 0; + int pageNum = 0; unsigned char mask = 1; unsigned char crc; unsigned char pageData[32]; @@ -1265,10 +1271,10 @@ void ReadHitagS(hitag_function htf, hitag_data *htd) { tag.tstate = HT_READING_PAGE; txlen = 20; crc = CRC_PRESET; - tx[0] = 0xc0 + (sendNum / 16); + tx[0] = 0xc0 + (pageNum / 16); calc_crc(&crc, tx[0], 8); - calc_crc(&crc, 0x00 + ((sendNum % 16) * 16), 4); - tx[1] = 0x00 + ((sendNum % 16) * 16) + (crc / 16); + calc_crc(&crc, 0x00 + ((pageNum % 16) * 16), 4); + tx[1] = 0x00 + ((pageNum % 16) * 16) + (crc / 16); tx[2] = 0x00 + (crc % 16) * 16; } else if (tag.pstate == HT_SELECTED && tag.tstate == HT_READING_PAGE @@ -1284,14 +1290,14 @@ void ReadHitagS(hitag_function htf, hitag_data *htd) { } } k = 0; - for (i = 4; i < 36; i++) { // ignore first 4 bits: SOF + for (i = 4; i < 36; i++) { // ignore first 4 bits: SOF (actualy 1 or 6 depending on response protocol) pageData[k] = response_bit[i]; k++; } for (i = 0; i < 4; i++) // set page bytes to 0 - tag.pages[sendNum][i] = 0x0; + tag.pages[pageNum][i] = 0x0; for (i = 0; i < 4; i++) { // set page bytes from recieved bits - tag.pages[sendNum][i] += ((pageData[i * 8] << 7) + tag.pages[pageNum][i] += ((pageData[i * 8] << 7) | (pageData[1 + (i * 8)] << 6) | (pageData[2 + (i * 8)] << 5) | (pageData[3 + (i * 8)] << 4) @@ -1300,22 +1306,22 @@ void ReadHitagS(hitag_function htf, hitag_data *htd) { | (pageData[6 + (i * 8)] << 1) | pageData[7 + (i * 8)]); } - if (tag.auth && tag.LKP && sendNum == 1) { - Dbprintf("Page[%2d]: %02X %02X %02X %02X", sendNum, pwdh0, - (tag.pages[sendNum][2]) & 0xff, - (tag.pages[sendNum][1]) & 0xff, - tag.pages[sendNum][0] & 0xff); + if (tag.auth && tag.LKP && pageNum == 1) { + Dbprintf("Page[%2d]: %02X %02X %02X %02X", pageNum, pwdh0, + (tag.pages[pageNum][2]) & 0xff, + (tag.pages[pageNum][1]) & 0xff, + tag.pages[pageNum][0] & 0xff); } else { - Dbprintf("Page[%2d]: %02X %02X %02X %02X", sendNum, - (tag.pages[sendNum][3]) & 0xff, - (tag.pages[sendNum][2]) & 0xff, - (tag.pages[sendNum][1]) & 0xff, - tag.pages[sendNum][0] & 0xff); + Dbprintf("Page[%2d]: %02X %02X %02X %02X", pageNum, + (tag.pages[pageNum][3]) & 0xff, + (tag.pages[pageNum][2]) & 0xff, + (tag.pages[pageNum][1]) & 0xff, + tag.pages[pageNum][0] & 0xff); } - sendNum++; + pageNum++; //display key and password if possible - if (sendNum == 2 && tag.auth == 1 && tag.LKP) { + if (pageNum == 2 && tag.auth == 1 && tag.LKP) { if (htf == RHTSF_KEY) { Dbprintf("Page[ 2]: %02X %02X %02X %02X", (uint8_t)(key >> 8) & 0xff, @@ -1338,12 +1344,12 @@ void ReadHitagS(hitag_function htf, hitag_data *htd) { txlen = 20; crc = CRC_PRESET; - tx[0] = 0xc0 + (sendNum / 16); + tx[0] = 0xc0 + (pageNum / 16); calc_crc(&crc, tx[0], 8); - calc_crc(&crc, 0x00 + ((sendNum % 16) * 16), 4); - tx[1] = 0x00 + ((sendNum % 16) * 16) + (crc / 16); + calc_crc(&crc, 0x00 + ((pageNum % 16) * 16), 4); + tx[1] = 0x00 + ((pageNum % 16) * 16) + (crc / 16); tx[2] = 0x00 + (crc % 16) * 16; - if (sendNum >= tag.max_page) { + if (pageNum >= tag.max_page) { bStop = !false; } } From e50c2f00ccda2e28c1f9d6bf5ef18bd79ea520fa Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 1 Jan 2020 21:19:59 +0100 Subject: [PATCH 1344/1854] cppcheck --- client/cmdhf15.c | 60 ++++++++++++++++++++++++------------------------ 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/client/cmdhf15.c b/client/cmdhf15.c index c2bd777e3..559c48709 100644 --- a/client/cmdhf15.c +++ b/client/cmdhf15.c @@ -218,6 +218,8 @@ uint8_t nxp_public_keys[][33] = { }, }; +static int CmdHF15Help(const char *Cmd); + // fast method to just read the UID of a tag (collision detection not supported) // *buf should be large enough to fit the 64bit uid // returns 1 if succeeded @@ -306,8 +308,6 @@ static const char *TagErrorStr(uint8_t error) { } } -static int CmdHF15Help(const char *Cmd); - static int usage_15_demod(void) { PrintAndLogEx(NORMAL, "Tries to demodulate / decode ISO15693, from downloaded samples.\n" "Gather samples with 'hf 15 read' / 'hf 15 record'"); @@ -683,41 +683,41 @@ static int NxpSysInfo(uint8_t *uid) { return PM3_EWRONGANSVER; } - bool signature = false; - bool easmode = false; - + bool support_signature = (recv[5] & 0x01); + bool support_easmode = (recv[4] & 0x03); + PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, " NXP SYSINFO : %s", sprint_hex(recv, 8)); PrintAndLogEx(NORMAL, " Password protection configuration:"); - PrintAndLogEx(NORMAL, " * Page L read%s password protected", (recv[2] & 0x01 ? "" : " not")); - PrintAndLogEx(NORMAL, " * Page L write%s password protected", (recv[2] & 0x02 ? "" : " not")); - PrintAndLogEx(NORMAL, " * Page H read%s password protected", (recv[2] & 0x08 ? "" : " not")); - PrintAndLogEx(NORMAL, " * Page H write%s password protected", (recv[2] & 0x20 ? "" : " not")); + PrintAndLogEx(NORMAL, " * Page L read%s password protected", ((recv[2] & 0x01) ? "" : " not")); + PrintAndLogEx(NORMAL, " * Page L write%s password protected", ((recv[2] & 0x02) ? "" : " not")); + PrintAndLogEx(NORMAL, " * Page H read%s password protected", ((recv[2] & 0x08) ? "" : " not")); + PrintAndLogEx(NORMAL, " * Page H write%s password protected", ((recv[2] & 0x20) ? "" : " not")); PrintAndLogEx(NORMAL, " Lock bits:"); - PrintAndLogEx(NORMAL, " * AFI%s locked", (recv[3] & 0x01 ? "" : " not")); // AFI lock bit - PrintAndLogEx(NORMAL, " * EAS%s locked", (recv[3] & 0x02 ? "" : " not")); // EAS lock bit - PrintAndLogEx(NORMAL, " * DSFID%s locked", (recv[3] & 0x03 ? "" : " not")); // DSFID lock bit - PrintAndLogEx(NORMAL, " * Password protection configuration%s locked", (recv[3] & 0x04 ? "" : " not")); // Password protection pointer address and access conditions lock bit + PrintAndLogEx(NORMAL, " * AFI%s locked", ((recv[3] & 0x01) ? "" : " not")); // AFI lock bit + PrintAndLogEx(NORMAL, " * EAS%s locked", ((recv[3] & 0x02) ? "" : " not")); // EAS lock bit + PrintAndLogEx(NORMAL, " * DSFID%s locked", ((recv[3] & 0x03) ? "" : " not")); // DSFID lock bit + PrintAndLogEx(NORMAL, " * Password protection configuration%s locked", ((recv[3] & 0x04) ? "" : " not")); // Password protection pointer address and access conditions lock bit PrintAndLogEx(NORMAL, " Features:"); - PrintAndLogEx(NORMAL, " * User memory password protection%s supported", (recv[4] & 0x01 ? "" : " not")); - PrintAndLogEx(NORMAL, " * Counter feature%s supported", (recv[4] & 0x02 ? "" : " not")); - PrintAndLogEx(NORMAL, " * EAS ID%s supported by EAS ALARM command", (recv[4] & 0x03 ? "" : " not")); - easmode = (recv[4] & 0x03 ? true : false); - PrintAndLogEx(NORMAL, " * EAS password protection%s supported", (recv[4] & 0x04 ? "" : " not")); - PrintAndLogEx(NORMAL, " * AFI password protection%s supported", (recv[4] & 0x10 ? "" : " not")); - PrintAndLogEx(NORMAL, " * Extended mode%s supported by INVENTORY READ command", (recv[4] & 0x20 ? "" : " not")); - PrintAndLogEx(NORMAL, " * EAS selection%s supported by extended mode in INVENTORY READ command", (recv[4] & 0x40 ? "" : " not")); - PrintAndLogEx(NORMAL, " * READ SIGNATURE command%s supported", (recv[5] & 0x01 ? "" : " not")); - signature = (recv[5] & 0x01 ? true : false); - PrintAndLogEx(NORMAL, " * Password protection for READ SIGNATURE command%s supported", (recv[5] & 0x02 ? "" : " not")); - PrintAndLogEx(NORMAL, " * STAY QUIET PERSISTENT command%s supported", (recv[5] & 0x03 ? "" : " not")); - PrintAndLogEx(NORMAL, " * ENABLE PRIVACY command%s supported", (recv[5] & 0x10 ? "" : " not")); - PrintAndLogEx(NORMAL, " * DESTROY command%s supported", (recv[5] & 0x20 ? "" : " not")); - PrintAndLogEx(NORMAL, " * Additional 32 bits feature flags are%s transmitted", (recv[5] & 0x80 ? "" : " not")); + PrintAndLogEx(NORMAL, " * User memory password protection%s supported", ((recv[4] & 0x01) ? "" : " not")); + PrintAndLogEx(NORMAL, " * Counter feature%s supported", ((recv[4] & 0x02) ? "" : " not")); + PrintAndLogEx(NORMAL, " * EAS ID%s supported by EAS ALARM command", support_easmode ? "" : " not"); - if (easmode) { + PrintAndLogEx(NORMAL, " * EAS password protection%s supported", ((recv[4] & 0x04) ? "" : " not")); + PrintAndLogEx(NORMAL, " * AFI password protection%s supported", ((recv[4] & 0x10) ? "" : " not")); + PrintAndLogEx(NORMAL, " * Extended mode%s supported by INVENTORY READ command", ((recv[4] & 0x20) ? "" : " not")); + PrintAndLogEx(NORMAL, " * EAS selection%s supported by extended mode in INVENTORY READ command", ((recv[4] & 0x40) ? "" : " not")); + PrintAndLogEx(NORMAL, " * READ SIGNATURE command%s supported", support_signature ? "" : " not"); + + PrintAndLogEx(NORMAL, " * Password protection for READ SIGNATURE command%s supported", ((recv[5] & 0x02) ? "" : " not")); + PrintAndLogEx(NORMAL, " * STAY QUIET PERSISTENT command%s supported", ((recv[5] & 0x03) ? "" : " not")); + PrintAndLogEx(NORMAL, " * ENABLE PRIVACY command%s supported", ((recv[5] & 0x10) ? "" : " not")); + PrintAndLogEx(NORMAL, " * DESTROY command%s supported", ((recv[5] & 0x20) ? "" : " not")); + PrintAndLogEx(NORMAL, " * Additional 32 bits feature flags are%s transmitted", ((recv[5] & 0x80) ? "" : " not")); + + if (support_easmode) { reqlen = 0; req[reqlen++] |= ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH | ISO15_REQ_NONINVENTORY | ISO15_REQ_ADDRESS; req[reqlen++] = ISO15_CMD_EASALARM; @@ -753,7 +753,7 @@ static int NxpSysInfo(uint8_t *uid) { } } - if (signature) { + if (support_signature) { // Check if we can also read the signature reqlen = 0; req[reqlen++] |= ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH | ISO15_REQ_NONINVENTORY | ISO15_REQ_ADDRESS; From 866df868258c2f427493a7f81a4fe23f3281c291 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 1 Jan 2020 21:22:01 +0100 Subject: [PATCH 1345/1854] cppcheck --- client/cmdhf15.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/client/cmdhf15.c b/client/cmdhf15.c index 559c48709..2e02aff68 100644 --- a/client/cmdhf15.c +++ b/client/cmdhf15.c @@ -643,6 +643,7 @@ static int NxpSysInfo(uint8_t *uid) { uint8_t *recv; uint8_t req[PM3_CMD_DATA_SIZE] = {0}; uint16_t reqlen; + uint32_t status; uint8_t arg1 = 1; if (uid != NULL) { @@ -669,7 +670,7 @@ static int NxpSysInfo(uint8_t *uid) { DropField(); - uint32_t status = resp.oldarg[0]; + status = resp.oldarg[0]; if (status < 2) { PrintAndLogEx(WARNING, "iso15693 card doesn't answer to NXP systeminfo command"); @@ -736,7 +737,7 @@ static int NxpSysInfo(uint8_t *uid) { if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { PrintAndLogEx(WARNING, "iso15693 card select failed"); } else { - uint32_t status = resp.oldarg[0]; + status = resp.oldarg[0]; PrintAndLogEx(NORMAL, ""); @@ -778,7 +779,7 @@ static int NxpSysInfo(uint8_t *uid) { DropField(); - uint32_t status = resp.oldarg[0]; + status = resp.oldarg[0]; if (status < 2) { PrintAndLogEx(WARNING, "iso15693 card doesn't answer to READ SIGNATURE command"); From fea3185922d51a3432938010ad269ecf5aa466f7 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 1 Jan 2020 21:28:02 +0100 Subject: [PATCH 1346/1854] cppcheck --- client/emv/emvcore.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/client/emv/emvcore.c b/client/emv/emvcore.c index c18521b6c..74b78f797 100644 --- a/client/emv/emvcore.c +++ b/client/emv/emvcore.c @@ -490,10 +490,10 @@ int EMVSearchPSE(EMVCommandChannel channel, bool ActivateField, bool LeaveFieldO for (uint8_t ui = 0x01; ui <= 0x10; ui++) { if (sfidatalen[ui]) { - struct tlvdb *tsfi = NULL; - tsfi = tlvdb_parse_multi(sfidata[ui], sfidatalen[ui]); - if (tsfi) { - struct tlvdb *tsfitmp = tlvdb_find_path(tsfi, (tlv_tag_t[]) {0x70, 0x61, 0x00}); + + struct tlvdb *tsfi_a = tlvdb_parse_multi(sfidata[ui], sfidatalen[ui]); + if (tsfi_a) { + struct tlvdb *tsfitmp = tlvdb_find_path(tsfi_a, (tlv_tag_t[]) {0x70, 0x61, 0x00}); if (!tsfitmp) { PrintAndLogEx(FAILED, "SFI 0x%02zu doesn't have any records.", sfidatalen[ui]); continue; @@ -501,7 +501,7 @@ int EMVSearchPSE(EMVCommandChannel channel, bool ActivateField, bool LeaveFieldO res = EMVCheckAID(channel, decodeTLV, tsfitmp, tlv); fileFound = true; } - tlvdb_free(tsfi); + tlvdb_free(tsfi_a); } } } From 4eb5907637e22924967f212f79ba23ffa053fa2f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 1 Jan 2020 21:32:41 +0100 Subject: [PATCH 1347/1854] cppcheck --- client/cmdhfmfp.c | 48 +++++++++++++++++++++++------------------------ client/cmdhfmfp.h | 1 - 2 files changed, 24 insertions(+), 25 deletions(-) diff --git a/client/cmdhfmfp.c b/client/cmdhfmfp.c index c6d24135c..9c7b9cb3c 100644 --- a/client/cmdhfmfp.c +++ b/client/cmdhfmfp.c @@ -30,11 +30,13 @@ static const uint8_t DefaultKey[16] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; +uint16_t CardAddresses[] = {0x9000, 0x9001, 0x9002, 0x9003, 0x9004, 0xA000, 0xA001, 0xA080, 0xA081, 0xC000, 0xC001}; + static int CmdHelp(const char *Cmd); -static int CmdHFMFPInfo(const char *cmd) { +static int CmdHFMFPInfo(const char *Cmd) { - if (cmd && strlen(cmd) > 0) + if (Cmd && strlen(Cmd) > 0) PrintAndLogEx(WARNING, "command don't have any parameters.\n"); // info about 14a part @@ -110,7 +112,7 @@ static int CmdHFMFPInfo(const char *cmd) { return PM3_SUCCESS; } -static int CmdHFMFPWritePerso(const char *cmd) { +static int CmdHFMFPWritePerso(const char *Cmd) { uint8_t keyNum[64] = {0}; int keyNumLen = 0; uint8_t key[64] = {0}; @@ -128,7 +130,7 @@ static int CmdHFMFPWritePerso(const char *cmd) { arg_strx0(NULL, NULL, "", NULL), arg_param_end }; - CLIExecWithReturn(cmd, argtable, true); + CLIExecWithReturn(Cmd, argtable, true); bool verbose = arg_get_lit(1); CLIGetHexWithReturn(2, keyNum, &keyNumLen); @@ -174,9 +176,7 @@ static int CmdHFMFPWritePerso(const char *cmd) { return PM3_SUCCESS; } -uint16_t CardAddresses[] = {0x9000, 0x9001, 0x9002, 0x9003, 0x9004, 0xA000, 0xA001, 0xA080, 0xA081, 0xC000, 0xC001}; - -static int CmdHFMFPInitPerso(const char *cmd) { +static int CmdHFMFPInitPerso(const char *Cmd) { int res; uint8_t key[256] = {0}; int keyLen = 0; @@ -195,7 +195,7 @@ static int CmdHFMFPInitPerso(const char *cmd) { arg_strx0(NULL, NULL, "", NULL), arg_param_end }; - CLIExecWithReturn(cmd, argtable, true); + CLIExecWithReturn(Cmd, argtable, true); bool verbose = arg_get_lit(1); bool verbose2 = arg_get_lit(1) > 1; @@ -250,7 +250,7 @@ static int CmdHFMFPInitPerso(const char *cmd) { return PM3_SUCCESS; } -static int CmdHFMFPCommitPerso(const char *cmd) { +static int CmdHFMFPCommitPerso(const char *Cmd) { CLIParserInit("hf mfp commitp", "Executes Commit Perso command. Can be used in SL0 mode only.", "Usage:\n\thf mfp commitp -> \n"); @@ -261,7 +261,7 @@ static int CmdHFMFPCommitPerso(const char *cmd) { arg_int0(NULL, NULL, "SL mode", NULL), arg_param_end }; - CLIExecWithReturn(cmd, argtable, true); + CLIExecWithReturn(Cmd, argtable, true); bool verbose = arg_get_lit(1); CLIParserFree(); @@ -291,7 +291,7 @@ static int CmdHFMFPCommitPerso(const char *cmd) { return PM3_SUCCESS; } -static int CmdHFMFPAuth(const char *cmd) { +static int CmdHFMFPAuth(const char *Cmd) { uint8_t keyn[250] = {0}; int keynlen = 0; uint8_t key[250] = {0}; @@ -309,7 +309,7 @@ static int CmdHFMFPAuth(const char *cmd) { arg_str1(NULL, NULL, "", NULL), arg_param_end }; - CLIExecWithReturn(cmd, argtable, true); + CLIExecWithReturn(Cmd, argtable, true); bool verbose = arg_get_lit(1); CLIGetHexWithReturn(2, keyn, &keynlen); @@ -329,7 +329,7 @@ static int CmdHFMFPAuth(const char *cmd) { return MifareAuth4(NULL, keyn, key, true, false, true, verbose, false); } -static int CmdHFMFPRdbl(const char *cmd) { +static int CmdHFMFPRdbl(const char *Cmd) { uint8_t keyn[2] = {0}; uint8_t key[250] = {0}; int keylen = 0; @@ -349,7 +349,7 @@ static int CmdHFMFPRdbl(const char *cmd) { arg_str0(NULL, NULL, "", NULL), arg_param_end }; - CLIExecWithReturn(cmd, argtable, false); + CLIExecWithReturn(Cmd, argtable, false); bool verbose = arg_get_lit(1); int blocksCount = arg_get_int_def(2, 1); @@ -441,7 +441,7 @@ static int CmdHFMFPRdbl(const char *cmd) { return 0; } -static int CmdHFMFPRdsc(const char *cmd) { +static int CmdHFMFPRdsc(const char *Cmd) { uint8_t keyn[2] = {0}; uint8_t key[250] = {0}; int keylen = 0; @@ -460,7 +460,7 @@ static int CmdHFMFPRdsc(const char *cmd) { arg_str0(NULL, NULL, "", NULL), arg_param_end }; - CLIExecWithReturn(cmd, argtable, false); + CLIExecWithReturn(Cmd, argtable, false); bool verbose = arg_get_lit(1); bool keyB = arg_get_lit(2); @@ -537,7 +537,7 @@ static int CmdHFMFPRdsc(const char *cmd) { return PM3_SUCCESS; } -static int CmdHFMFPWrbl(const char *cmd) { +static int CmdHFMFPWrbl(const char *Cmd) { uint8_t keyn[2] = {0}; uint8_t key[250] = {0}; int keylen = 0; @@ -558,7 +558,7 @@ static int CmdHFMFPWrbl(const char *cmd) { arg_str0(NULL, NULL, "", NULL), arg_param_end }; - CLIExecWithReturn(cmd, argtable, false); + CLIExecWithReturn(Cmd, argtable, false); bool verbose = arg_get_lit(1); bool keyB = arg_get_lit(2); @@ -735,7 +735,7 @@ void Fill2bPattern(uint8_t keyList[MAX_KEYS_LIST_LEN][AES_KEY_LEN], size_t *keyL (*startPattern)++; } -static int CmdHFMFPChk(const char *cmd) { +static int CmdHFMFPChk(const char *Cmd) { int res; uint8_t keyList[MAX_KEYS_LIST_LEN][AES_KEY_LEN] = {{0}}; size_t keyListLen = 0; @@ -765,7 +765,7 @@ static int CmdHFMFPChk(const char *cmd) { arg_lit0("vV", "verbose", "verbose mode."), arg_param_end }; - CLIExecWithReturn(cmd, argtable, true); + CLIExecWithReturn(Cmd, argtable, true); bool keyA = arg_get_lit(1); bool keyB = arg_get_lit(2); @@ -965,7 +965,7 @@ static int CmdHFMFPChk(const char *cmd) { return PM3_SUCCESS; } -static int CmdHFMFPMAD(const char *cmd) { +static int CmdHFMFPMAD(const char *Cmd) { CLIParserInit("hf mfp mad", "Checks and prints Mifare Application Directory (MAD)", @@ -980,7 +980,7 @@ static int CmdHFMFPMAD(const char *cmd) { arg_lit0("bB", "keyb", "use key B for access printing sectors (by default: key A)"), arg_param_end }; - CLIExecWithReturn(cmd, argtable, true); + CLIExecWithReturn(Cmd, argtable, true); bool verbose = arg_get_lit(1); uint8_t aid[2] = {0}; @@ -1059,7 +1059,7 @@ static int CmdHFMFPMAD(const char *cmd) { return PM3_SUCCESS; } -static int CmdHFMFPNDEF(const char *cmd) { +static int CmdHFMFPNDEF(const char *Cmd) { CLIParserInit("hf mfp ndef", "Prints NFC Data Exchange Format (NDEF)", @@ -1074,7 +1074,7 @@ static int CmdHFMFPNDEF(const char *cmd) { arg_lit0("bB", "keyb", "use key B for access sectors (by default: key A)"), arg_param_end }; - CLIExecWithReturn(cmd, argtable, true); + CLIExecWithReturn(Cmd, argtable, true); bool verbose = arg_get_lit(1); bool verbose2 = arg_get_lit(1) > 1; diff --git a/client/cmdhfmfp.h b/client/cmdhfmfp.h index 6ba2af504..a26aeab87 100644 --- a/client/cmdhfmfp.h +++ b/client/cmdhfmfp.h @@ -14,5 +14,4 @@ int CmdHFMFP(const char *Cmd); - #endif From 1d9c771a4354e6e76f1896a553ea446f9e51c509 Mon Sep 17 00:00:00 2001 From: Thorsten Bosbach Date: Wed, 1 Jan 2020 22:11:50 +0100 Subject: [PATCH 1348/1854] guard debug output --- armsrc/hitagS.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/armsrc/hitagS.c b/armsrc/hitagS.c index c4a4a48cb..b44bffa45 100644 --- a/armsrc/hitagS.c +++ b/armsrc/hitagS.c @@ -953,12 +953,13 @@ void SimulateHitagSTag(bool tag_mem_supplied, uint8_t *data) { tag.max_page = 8; if ((tag.pages[1][3] & 0x2) == 0 && (tag.pages[1][3] & 0x1) == 0) tag.max_page = 0; - for (i = 0; i < tag.max_page; i++) - Dbprintf("Page[%2d]: %02X %02X %02X %02X", i, - (tag.pages[i][3]) & 0xff, - (tag.pages[i][2]) & 0xff, - (tag.pages[i][1]) & 0xff, - tag.pages[i][0] & 0xff); + if (DBGLEVEL >= DBG_EXTENDED) + for (i = 0; i < tag.max_page; i++) + Dbprintf("Page[%2d]: %02X %02X %02X %02X", i, + (tag.pages[i][3]) & 0xff, + (tag.pages[i][2]) & 0xff, + (tag.pages[i][1]) & 0xff, + tag.pages[i][0] & 0xff); //con1 tag.auth = 0; if ((tag.pages[1][2] & 0x80) == 0x80) From 608d38c4b58daa1e4b6d51bc6c02ca182a323ca8 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 1 Jan 2020 22:13:24 +0100 Subject: [PATCH 1349/1854] cppcheck --- armsrc/felica.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/armsrc/felica.c b/armsrc/felica.c index 1a3b6f6ac..4b1db7f61 100644 --- a/armsrc/felica.c +++ b/armsrc/felica.c @@ -409,6 +409,8 @@ bool WaitForFelicaReply(uint16_t maxbytes) { // clear RXRDY: uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + (void)b; + uint32_t timeout = iso18092_get_timeout(); for (;;) { From 9fac23567be04ffceaaa61891fff530e2b40e0fa Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 1 Jan 2020 22:44:50 +0100 Subject: [PATCH 1350/1854] cppcheck --- armsrc/lfops.c | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 94f7ece2a..c4cd6eaa4 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -1269,10 +1269,7 @@ void CmdHIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol) void CmdAWIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol) { uint8_t *dest = BigBuf_get_addr(); - - //big enough to catch 2 sequences of largest format but don't exeed whats available in bigbuff. - size_t size = MIN(12800, BigBuf_max_traceLen()); //50 * 128 * 2; - + size_t size; int dummyIdx = 0; BigBuf_Clear_keep_EM(); @@ -1287,10 +1284,9 @@ void CmdAWIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol) DoAcquisition_default(-1, true); // FSK demodulator - size = BigBuf_max_traceLen(); - //askdemod and manchester decode - if (size > 12800) size = 12800; //big enough to catch 2 sequences of largest format + size = MIN(12800, BigBuf_max_traceLen()); + //askdemod and manchester decode int idx = detectAWID(dest, &size, &dummyIdx); if (idx <= 0 || size != 96) continue; @@ -1378,9 +1374,9 @@ void CmdEM410xdemod(int findone, uint32_t *high, uint64_t *low, int ledcontrol) DoAcquisition_default(-1, true); - size = BigBuf_max_traceLen(); - //askdemod and manchester decode - if (size > 16385) size = 16385; //big enough to catch 2 sequences of largest format + size = MIN(16385, BigBuf_max_traceLen()); + + //askdemod and manchester decode int errCnt = askdemod(dest, &size, &clk, &invert, maxErr, 0, 1); WDT_HIT(); @@ -1443,11 +1439,9 @@ void CmdIOdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol) { DoAcquisition_default(-1, true); + size = MIN(12000, BigBuf_max_traceLen()); + //fskdemod and get start index - size = BigBuf_max_traceLen(); - //askdemod and manchester decode - if (size > 12000) size = 12000; //big enough to catch 2 sequences of largest format - int idx = detectIOProx(dest, &size, &dummyIdx); if (idx < 0) continue; //valid tag found From 52d19766be6051e91bf14e210697b76f1d5987fe Mon Sep 17 00:00:00 2001 From: danshuk Date: Wed, 1 Jan 2020 22:28:37 +0000 Subject: [PATCH 1351/1854] update readme --- traces/README.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/traces/README.txt b/traces/README.txt index 63ebe18ee..0f89925a4 100644 --- a/traces/README.txt +++ b/traces/README.txt @@ -1,3 +1,4 @@ +pac-8E4C058E.pm3: PAC/Stanley 20204/21020 PAC8 tag (ID: 8E4C058E) em4102-clamshell.pm3: Samy's clamshell EM4102 tag (ID: 1f00d9b3a5) em4102-thin.pm3: Samy's thin credit-card style EM4102 tag (ID: 1a0041375d) EM4102-1.pm3: credit card style card EM4102 tag (ID: 010872e77c) From 1c98888ee5ea0de531f2c3cb8f7df37fff0db7fa Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 2 Jan 2020 11:42:57 +0100 Subject: [PATCH 1352/1854] Chg: key gen algo refactoring. This will help in next step when implementing new json key template formats --- common/generator.c | 301 +++++++++++++++++++++++++++++++++++++++++++++ common/generator.h | 48 ++++++++ 2 files changed, 349 insertions(+) create mode 100644 common/generator.c create mode 100644 common/generator.h diff --git a/common/generator.c b/common/generator.c new file mode 100644 index 000000000..060f126ca --- /dev/null +++ b/common/generator.c @@ -0,0 +1,301 @@ +//----------------------------------------------------------------------------- +// Copyright (C) 2019 iceman +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// Generator commands +//----------------------------------------------------------------------------- +#include "generator.h" + +#include +#include +#include +#include +#include +#include +#include "commonutil.h" +#include "util.h" +#include "pm3_cmd.h" +#include "ui.h" + +// Implemetation tips: +// For each implementation of the algos, I recommend adding a self test for easy "simple unit" tests when Travic CI / Appveyour runs. +// See special note for MFC based algos. + +//------------------------------------ +// MFU/NTAG PWD/PACK generation stuff +// Italian transport system +// Amiibo +// Lego Dimension +// XYZ 3D printing +// Vinglock +//------------------------------------ +const uint32_t c_D[] = { + 0x6D835AFC, 0x7D15CD97, 0x0942B409, 0x32F9C923, 0xA811FB02, 0x64F121E8, + 0xD1CC8B4E, 0xE8873E6F, 0x61399BBB, 0xF1B91926, 0xAC661520, 0xA21A31C9, + 0xD424808D, 0xFE118E07, 0xD18E728D, 0xABAC9E17, 0x18066433, 0x00E18E79, + 0x65A77305, 0x5AE9E297, 0x11FC628C, 0x7BB3431F, 0x942A8308, 0xB2F8FD20, + 0x5728B869, 0x30726D5A +}; + +static void transform_D(uint8_t *ru) { + //Transform + uint8_t i; + uint8_t p = 0; + uint32_t v1 = ((ru[3] << 24) | (ru[2] << 16) | (ru[1] << 8) | ru[0]) + c_D[p++]; + uint32_t v2 = ((ru[7] << 24) | (ru[6] << 16) | (ru[5] << 8) | ru[4]) + c_D[p++]; + + for (i = 0; i < 12; i += 2) { + uint32_t xor1 = v1 ^ v2; + uint32_t t1 = ROTL(xor1, v2 & 0x1F) + c_D[p++]; + uint32_t xor2 = v2 ^ t1; + uint32_t t2 = ROTL(xor2, t1 & 0x1F) + c_D[p++]; + uint32_t xor3 = t1 ^ t2; + uint32_t xor4 = t2 ^ v1; + v1 = ROTL(xor3, t2 & 0x1F) + c_D[p++]; + v2 = ROTL(xor4, v1 & 0x1F) + c_D[p++]; + } + + //Re-use ru + ru[0] = v1 & 0xFF; + ru[1] = (v1 >> 8) & 0xFF; + ru[2] = (v1 >> 16) & 0xFF; + ru[3] = (v1 >> 24) & 0xFF; + ru[4] = v2 & 0xFF; + ru[5] = (v2 >> 8) & 0xFF; + ru[6] = (v2 >> 16) & 0xFF; + ru[7] = (v2 >> 24) & 0xFF; +} + +// Transport system (IT) pwd generation algo nickname A. +uint32_t ul_ev1_pwdgenA(uint8_t *uid) { + + uint8_t pos = (uid[3] ^ uid[4] ^ uid[5] ^ uid[6]) % 32; + + uint32_t xortable[] = { + 0x4f2711c1, 0x07D7BB83, 0x9636EF07, 0xB5F4460E, 0xF271141C, 0x7D7BB038, 0x636EF871, 0x5F4468E3, + 0x271149C7, 0xD7BB0B8F, 0x36EF8F1E, 0xF446863D, 0x7114947A, 0x7BB0B0F5, 0x6EF8F9EB, 0x44686BD7, + 0x11494fAF, 0xBB0B075F, 0xEF8F96BE, 0x4686B57C, 0x1494F2F9, 0xB0B07DF3, 0xF8F963E6, 0x686B5FCC, + 0x494F2799, 0x0B07D733, 0x8F963667, 0x86B5F4CE, 0x94F2719C, 0xB07D7B38, 0xF9636E70, 0x6B5F44E0 + }; + + uint8_t entry[] = {0x00, 0x00, 0x00, 0x00}; + uint8_t pwd[] = {0x00, 0x00, 0x00, 0x00}; + + num_to_bytes(xortable[pos], 4, entry); + + pwd[0] = entry[0] ^ uid[1] ^ uid[2] ^ uid[3]; + pwd[1] = entry[1] ^ uid[0] ^ uid[2] ^ uid[4]; + pwd[2] = entry[2] ^ uid[0] ^ uid[1] ^ uid[5]; + pwd[3] = entry[3] ^ uid[6]; + + return (uint32_t)bytes_to_num(pwd, 4); +} + +// Amiibo pwd generation algo nickname B. (very simple) +uint32_t ul_ev1_pwdgenB(uint8_t *uid) { + + uint8_t pwd[] = {0x00, 0x00, 0x00, 0x00}; + + pwd[0] = uid[1] ^ uid[3] ^ 0xAA; + pwd[1] = uid[2] ^ uid[4] ^ 0x55; + pwd[2] = uid[3] ^ uid[5] ^ 0xAA; + pwd[3] = uid[4] ^ uid[6] ^ 0x55; + return (uint32_t)bytes_to_num(pwd, 4); +} + +// Lego Dimension pwd generation algo nickname C. +uint32_t ul_ev1_pwdgenC(uint8_t *uid) { + uint32_t pwd = 0; + uint8_t base[] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x28, + 0x63, 0x29, 0x20, 0x43, 0x6f, 0x70, 0x79, 0x72, + 0x69, 0x67, 0x68, 0x74, 0x20, 0x4c, 0x45, 0x47, + 0x4f, 0x20, 0x32, 0x30, 0x31, 0x34, 0xaa, 0xaa + }; + + memcpy(base, uid, 7); + + for (int i = 0; i < 32; i += 4) { + uint32_t b = *(uint32_t *)(base + i); + pwd = b + ROTR(pwd, 25) + ROTR(pwd, 10) - pwd; + } + return BSWAP_32(pwd); +} + +// XYZ 3d printing pwd generation algo nickname D. +uint32_t ul_ev1_pwdgenD(uint8_t *uid) { + uint8_t i; + uint8_t r = (uid[1] + uid[3] + uid[5]) & 7; // rotation offset + uint8_t ru[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // rotated UID + for (i = 0; i < 7; i++) + ru[(i + r) & 7] = uid[i]; + + transform_D(ru); + + // calc key + uint32_t pwd = 0; + r = (ru[0] + ru[2] + ru[4] + ru[6]) & 3; // offset + for (i = 0; i < 4; i++) + pwd = ru[i + r] + (pwd << 8); + + return BSWAP_32(pwd); +} + +// pack generation for algo 1-3 +uint16_t ul_ev1_packgenA(uint8_t *uid) { + uint16_t pack = (uid[0] ^ uid[1] ^ uid[2]) << 8 | (uid[2] ^ 8); + return pack; +} +uint16_t ul_ev1_packgenB(uint8_t *uid) { + return 0x8080; +} +uint16_t ul_ev1_packgenC(uint8_t *uid) { + return 0xaa55; +} +uint16_t ul_ev1_packgenD(uint8_t *uid) { + uint8_t i; + //Rotate + uint8_t r = (uid[2] + uid[5]) & 7; //Rotation offset + uint8_t ru[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; //Rotated UID + for (i = 0; i < 7; i++) + ru[(i + r) & 7] = uid[i]; + + transform_D(ru); + + //Calc pack + uint32_t p = 0; + for (i = 0; i < 8; i++) + p += ru[i] * 13; + + p ^= 0x5555; + return BSWAP_16(p & 0xFFFF); +} + +//------------------------------------ +// MFC key generation stuff +// Each algo implementation should offer two key generation functions. +// 1. function that returns all keys +// 2. function that returns one key, target sector | block +//------------------------------------ + +//------------------------------------ +// MFC keyfile generation stuff +//------------------------------------ +// Vinglock +void mfc_algo_ving_one(uint8_t *uid, uint8_t sector) { + return 0; +} +void mfc_algo_ving_all(uint8_t *uid, uint8_t *keys) {} + +// Yale Doorman +void mfc_algo_yale_one(uint8_t *uid, uint8_t sector) { + return 0; +} +void mfc_algo_yale_all(uint8_t *uid, uint8_t *keys) {} + +// Saflok / Maid UID to key. +uint64_t mfc_algo_saflok_one(uint8_t *uid, uint8_t sector) { + return 0; +} +void mfc_algo_saflok_all(uint8_t *uid, uint8_t *keys) { +} + +// MIZIP algo +void mfc_algo_mizip_one(uint8_t *uid, uint8_t sector) { + return 0; +} +// returns all Mifare Mini (MFM) 10 keys. +// keys must have 5*2*6 = 60bytes space +void mfc_algo_mizip_all(uint8_t *uid, uint8_t *keys) { + + uint64_t xor_tbl[] = { + 0x09125a2589e5ULL, 0xF12C8453D821ULL, + 0xAB75C937922FULL, 0x73E799FE3241ULL, + 0xE27241AF2C09ULL, 0xAA4D137656AEULL, + 0x317AB72F4490ULL, 0xB01327272DFDULL + }; + + // A + num_to_bytes(0xA0A1A2A3A4A5ULL, 6, keys); + for (uint8_t i = 0; i < 4; i++) { + uint64_t a = + (uint64_t)(uid[0] ^ xor_tbl[i]) << 40 | + (uint64_t)(uid[1] ^ xor_tbl[i]) << 32 | + (uint64_t)(uid[2] ^ xor_tbl[i]) << 24 | + (uint64_t)(uid[3] ^ xor_tbl[i]) << 16 | + (uint64_t)(uid[1] ^ xor_tbl[i]) << 8 | + (uint64_t)(uid[2] ^ xor_tbl[i]) + ; + num_to_bytes(a, 6, keys + (1 * i * 6)); + } + + // B + num_to_bytes(0xB4C132439eefULL, 6, keys + (5 * 6)); + for (uint8_t i = 0; i < 4; i++) { + uint64_t b = + (uint64_t)(uid[2] ^ xor_tbl[i + 1]) << 40 | + (uint64_t)(uid[3] ^ xor_tbl[i + 1]) << 32 | + (uint64_t)(uid[0] ^ xor_tbl[i + 1]) << 24 | + (uint64_t)(uid[1] ^ xor_tbl[i + 1]) << 16 | + (uint64_t)(uid[2] ^ xor_tbl[i + 1]) << 8 | + (uint64_t)(uid[3] ^ xor_tbl[i + 1]) + ; + num_to_bytes(b, 6, keys + 30 + (1 * i * 6)); + } +} + +// Disney Infinity algo +void mfc_algo_di_one(uint8_t *uid, uint8_t sector) { + return 0; +} +void mfc_algo_di_all(uint8_t *uid, uint8_t *keys) {} + +// Skylanders +void mfc_algo_sky_one(uint8_t *uid, uint8_t sector) { + return 0; +} +void mfc_algo_sky_all(uint8_t *uid, uint8_t *keys) {} + + +//------------------------------------ +// Self tests +//------------------------------------ +int generator_selftest() { + + PrintAndLogEx(SUCCESS, "Generators selftest"); + PrintAndLogEx(SUCCESS, "-------------------"); + + bool success; + + uint8_t uid1[] = {0x04, 0x11, 0x12, 0x11, 0x12, 0x11, 0x10}; + uint32_t pwd1 = ul_ev1_pwdgenA(uid1); + success = (pwd1 == 0x8432EB17); + PrintAndLogEx(success ? SUCCESS : WARNING, "UID | %s | %08X | %s", sprint_hex(uid1, 7), pwd1, success ? "OK" : "->8432EB17<-"); + + uint8_t uid2[] = {0x04, 0x1f, 0x98, 0xea, 0x1e, 0x3e, 0x81}; + uint32_t pwd2 = ul_ev1_pwdgenB(uid2); + success = (pwd2 == 0x5fd37eca); + PrintAndLogEx(success ? SUCCESS : WARNING, "UID | %s | %08X | %s", sprint_hex(uid2, 7), pwd2, success ? "OK" : "->5fd37eca<--"); + + uint8_t uid3[] = {0x04, 0x62, 0xB6, 0x8A, 0xB4, 0x42, 0x80}; + uint32_t pwd3 = ul_ev1_pwdgenC(uid3); + success = (pwd3 == 0x5a349515); + PrintAndLogEx(success ? SUCCESS : WARNING, "UID | %s | %08X | %s", sprint_hex(uid3, 7), pwd3, success ? "OK" : "->5a349515<--"); + + uint8_t uid4[] = {0x04, 0xC5, 0xDF, 0x4A, 0x6D, 0x51, 0x80}; + uint32_t pwd4 = ul_ev1_pwdgenD(uid4); + success = (pwd4 == 0x72B1EC61); + PrintAndLogEx(success ? SUCCESS : WARNING, "UID | %s | %08X | %s", sprint_hex(uid4, 7), pwd4, success ? "OK" : "->72B1EC61<--"); + + uint8_t uid5[] = {0x11, 0x22, 0x33, 0x44}; + uint64_t key1 = mfc_algo_a(uid5); + success = (key1 == 0xD1E2AA68E39A); + PrintAndLogEx(success ? SUCCESS : WARNING, "UID | %s | %"PRIx64" | %s", sprint_hex(uid5, 4), key1, success ? "OK" : "->D1E2AA68E39A<--"); + + PrintAndLogEx(SUCCESS, "-------------------"); + return PM3_SUCCESS; +} + diff --git a/common/generator.h b/common/generator.h new file mode 100644 index 000000000..3ab678b73 --- /dev/null +++ b/common/generator.h @@ -0,0 +1,48 @@ +//----------------------------------------------------------------------------- +// Copyright (C) 2019 iceman +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// Generator commands +//----------------------------------------------------------------------------- + +#ifndef GENERATOR_H__ +#define GENERATOR_H__ + +#include "common.h" + +uint32_t ul_ev1_pwdgenA(uint8_t *uid); +uint32_t ul_ev1_pwdgenB(uint8_t *uid); +uint32_t ul_ev1_pwdgenC(uint8_t *uid); +uint32_t ul_ev1_pwdgenD(uint8_t *uid); + +uint16_t ul_ev1_packgenA(uint8_t *uid); +uint16_t ul_ev1_packgenB(uint8_t *uid); +uint16_t ul_ev1_packgenC(uint8_t *uid); +uint16_t ul_ev1_packgenD(uint8_t *uid); + +uint64_t mfc_algo_ving_one(uint8_t *uid, uint8_t sector); +void mfc_algo_ving_all(uint8_t *uid, uint8_t *keys); + +uint64_t mfc_algo_yale_one(uint8_t *uid, uint8_t sector); +void mfc_algo_yale_all(uint8_t *uid, uint8_t *keys); + +uint64_t mfc_algo_saflok_one(uint8_t *uid, uint8_t sector); +void mfc_algo_saflok_all(uint8_t *uid, uint8_t *keys); + +uint64_t mfc_algo_saflok_one(uint8_t *uid, uint8_t sector); +void mfc_algo_saflok_all(uint8_t *uid, uint8_t *keys); + +uint64_t mfc_algo_mizip_one(uint8_t *uid, uint8_t sector); +void mfc_algo_mizip_all(uint8_t *uid, uint8_t *keys); + +uint64_t mfc_algo_di_one(uint8_t *uid, uint8_t sector); +void mfc_algo_di_all(uint8_t *uid, uint8_t *keys); + +uint64_t mfc_algo_sky_one(uint8_t *uid, uint8_t sector); +void mfc_algo_sky_all(uint8_t *uid, uint8_t *keys); + +int generator_selftest(); +#endif From 01f215a924084083912777ad326b7d7e8a78acee Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 2 Jan 2020 15:29:15 +0100 Subject: [PATCH 1353/1854] Chg: hooked up generator --- client/Makefile | 1 + client/cmdhfmfu.c | 150 ++------------------------------------------- common/generator.c | 74 +++++++++++++++------- common/generator.h | 28 ++++----- 4 files changed, 70 insertions(+), 183 deletions(-) diff --git a/client/Makefile b/client/Makefile index 891a8b1e5..483856b8f 100644 --- a/client/Makefile +++ b/client/Makefile @@ -159,6 +159,7 @@ CMDSRCS = crapto1/crapto1.c \ legic_prng.c \ iso15693tools.c \ prng.c \ + generator.c \ graph.c \ cmddata.c \ lfdemod.c \ diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index 7d2b8cfc6..b761494f5 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -20,6 +20,7 @@ #include "comms.h" #include "fileutils.h" #include "protocols.h" +#include "generator.h" #define MAX_UL_BLOCKS 0x0F #define MAX_ULC_BLOCKS 0x2B @@ -283,151 +284,6 @@ uint8_t UL_MEMORY_ARRAY[ARRAYLEN(UL_TYPES_ARRAY)] = { MAX_ULEV1a_BLOCKS, MAX_NTAG_213, MAX_NTAG_216, MAX_UL_NANO_40, MAX_NTAG_I2C_1K }; -//------------------------------------ -// Pwd & Pack generation Stuff -//------------------------------------ -const uint32_t c_D[] = { - 0x6D835AFC, 0x7D15CD97, 0x0942B409, 0x32F9C923, 0xA811FB02, 0x64F121E8, - 0xD1CC8B4E, 0xE8873E6F, 0x61399BBB, 0xF1B91926, 0xAC661520, 0xA21A31C9, - 0xD424808D, 0xFE118E07, 0xD18E728D, 0xABAC9E17, 0x18066433, 0x00E18E79, - 0x65A77305, 0x5AE9E297, 0x11FC628C, 0x7BB3431F, 0x942A8308, 0xB2F8FD20, - 0x5728B869, 0x30726D5A -}; - -static void transform_D(uint8_t *ru) { - //Transform - uint8_t i; - uint8_t p = 0; - uint32_t v1 = ((ru[3] << 24) | (ru[2] << 16) | (ru[1] << 8) | ru[0]) + c_D[p++]; - uint32_t v2 = ((ru[7] << 24) | (ru[6] << 16) | (ru[5] << 8) | ru[4]) + c_D[p++]; - for (i = 0; i < 12; i += 2) { - - uint32_t xor1 = v1 ^ v2; - uint32_t t1 = ROTL(xor1, v2 & 0x1F) + c_D[p++]; - uint32_t xor2 = v2 ^ t1; - uint32_t t2 = ROTL(xor2, t1 & 0x1F) + c_D[p++]; - uint32_t xor3 = t1 ^ t2; - uint32_t xor4 = t2 ^ v1; - v1 = ROTL(xor3, t2 & 0x1F) + c_D[p++]; - v2 = ROTL(xor4, v1 & 0x1F) + c_D[p++]; - } - - //Re-use ru - ru[0] = v1 & 0xFF; - ru[1] = (v1 >> 8) & 0xFF; - ru[2] = (v1 >> 16) & 0xFF; - ru[3] = (v1 >> 24) & 0xFF; - ru[4] = v2 & 0xFF; - ru[5] = (v2 >> 8) & 0xFF; - ru[6] = (v2 >> 16) & 0xFF; - ru[7] = (v2 >> 24) & 0xFF; -} - -// Certain pwd generation algo nickname A. -uint32_t ul_ev1_pwdgenA(uint8_t *uid) { - - uint8_t pos = (uid[3] ^ uid[4] ^ uid[5] ^ uid[6]) % 32; - - uint32_t xortable[] = { - 0x4f2711c1, 0x07D7BB83, 0x9636EF07, 0xB5F4460E, 0xF271141C, 0x7D7BB038, 0x636EF871, 0x5F4468E3, - 0x271149C7, 0xD7BB0B8F, 0x36EF8F1E, 0xF446863D, 0x7114947A, 0x7BB0B0F5, 0x6EF8F9EB, 0x44686BD7, - 0x11494fAF, 0xBB0B075F, 0xEF8F96BE, 0x4686B57C, 0x1494F2F9, 0xB0B07DF3, 0xF8F963E6, 0x686B5FCC, - 0x494F2799, 0x0B07D733, 0x8F963667, 0x86B5F4CE, 0x94F2719C, 0xB07D7B38, 0xF9636E70, 0x6B5F44E0 - }; - - uint8_t entry[] = {0x00, 0x00, 0x00, 0x00}; - uint8_t pwd[] = {0x00, 0x00, 0x00, 0x00}; - - num_to_bytes(xortable[pos], 4, entry); - - pwd[0] = entry[0] ^ uid[1] ^ uid[2] ^ uid[3]; - pwd[1] = entry[1] ^ uid[0] ^ uid[2] ^ uid[4]; - pwd[2] = entry[2] ^ uid[0] ^ uid[1] ^ uid[5]; - pwd[3] = entry[3] ^ uid[6]; - - return (uint32_t)bytes_to_num(pwd, 4); -} - -// Certain pwd generation algo nickname B. (very simple) -static uint32_t ul_ev1_pwdgenB(uint8_t *uid) { - - uint8_t pwd[] = {0x00, 0x00, 0x00, 0x00}; - - pwd[0] = uid[1] ^ uid[3] ^ 0xAA; - pwd[1] = uid[2] ^ uid[4] ^ 0x55; - pwd[2] = uid[3] ^ uid[5] ^ 0xAA; - pwd[3] = uid[4] ^ uid[6] ^ 0x55; - return (uint32_t)bytes_to_num(pwd, 4); -} - -// Certain pwd generation algo nickname C. -uint32_t ul_ev1_pwdgenC(uint8_t *uid) { - uint32_t pwd = 0; - uint8_t base[] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x28, - 0x63, 0x29, 0x20, 0x43, 0x6f, 0x70, 0x79, 0x72, - 0x69, 0x67, 0x68, 0x74, 0x20, 0x4c, 0x45, 0x47, - 0x4f, 0x20, 0x32, 0x30, 0x31, 0x34, 0xaa, 0xaa - }; - - memcpy(base, uid, 7); - - for (int i = 0; i < 32; i += 4) { - uint32_t b = *(uint32_t *)(base + i); - pwd = b + ROTR(pwd, 25) + ROTR(pwd, 10) - pwd; - } - return BSWAP_32(pwd); -} -// Certain pwd generation algo nickname D. -// a.k.a xzy -uint32_t ul_ev1_pwdgenD(uint8_t *uid) { - uint8_t i; - //Rotate - uint8_t r = (uid[1] + uid[3] + uid[5]) & 7; //Rotation offset - uint8_t ru[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; //Rotated UID - for (i = 0; i < 7; i++) - ru[(i + r) & 7] = uid[i]; - - transform_D(ru); - - //Calc key - uint32_t pwd = 0; //Key as int - r = (ru[0] + ru[2] + ru[4] + ru[6]) & 3; //Offset - for (i = 0; i < 4; i++) - pwd = ru[i + r] + (pwd << 8); - - return BSWAP_32(pwd); -} -// pack generation for algo 1-3 -uint16_t ul_ev1_packgenA(uint8_t *uid) { - uint16_t pack = (uid[0] ^ uid[1] ^ uid[2]) << 8 | (uid[2] ^ 8); - return pack; -} -uint16_t ul_ev1_packgenB(uint8_t *uid) { - return 0x8080; -} -uint16_t ul_ev1_packgenC(uint8_t *uid) { - return 0xaa55; -} -uint16_t ul_ev1_packgenD(uint8_t *uid) { - uint8_t i; - //Rotate - uint8_t r = (uid[2] + uid[5]) & 7; //Rotation offset - uint8_t ru[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; //Rotated UID - for (i = 0; i < 7; i++) - ru[(i + r) & 7] = uid[i]; - - transform_D(ru); - - //Calc pack - uint32_t p = 0; - for (i = 0; i < 8; i++) - p += ru[i] * 13; - - p ^= 0x5555; - return BSWAP_16(p & 0xFFFF); -} - static int ul_ev1_pwdgen_selftest() { uint8_t uid1[] = {0x04, 0x11, 0x12, 0x11, 0x12, 0x11, 0x10}; @@ -2613,11 +2469,13 @@ static int CmdHF14AMfUGenDiverseKeys(const char *Cmd) { PrintAndLogEx(WARNING, "iso14443a card select failed"); return PM3_ESOFT; } +/* if (card.uidlen != 4) { PrintAndLogEx(WARNING, "Wrong sized UID, expected 4bytes got %d", card.uidlen); return PM3_ESOFT; } - memcpy(uid, card.uid, sizeof(uid)); +*/ + memcpy(uid, card.uid, card.uidlen); } else { if (param_gethex(Cmd, 0, uid, 8)) return usage_hf_mfu_gendiverse(); } diff --git a/common/generator.c b/common/generator.c index 060f126ca..f2bf33626 100644 --- a/common/generator.c +++ b/common/generator.c @@ -185,32 +185,49 @@ uint16_t ul_ev1_packgenD(uint8_t *uid) { // MFC keyfile generation stuff //------------------------------------ // Vinglock -void mfc_algo_ving_one(uint8_t *uid, uint8_t sector) { - return 0; +int mfc_algo_ving_one(uint8_t *uid, uint8_t sector, uint64_t *key) { + if (sector > 15) return PM3_EINVARG; + if (key == NULL) return PM3_EINVARG; + return PM3_SUCCESS; +} +int mfc_algo_ving_all(uint8_t *uid, uint8_t *keys) { + if (keys == NULL) return PM3_EINVARG; + return PM3_SUCCESS; } -void mfc_algo_ving_all(uint8_t *uid, uint8_t *keys) {} // Yale Doorman -void mfc_algo_yale_one(uint8_t *uid, uint8_t sector) { - return 0; +int mfc_algo_yale_one(uint8_t *uid, uint8_t sector, uint64_t *key) { + if (sector > 15) return PM3_EINVARG; + if (key == NULL) return PM3_EINVARG; + return PM3_SUCCESS; +} +int mfc_algo_yale_all(uint8_t *uid, uint8_t *keys) { + if (keys == NULL) return PM3_EINVARG; + return PM3_SUCCESS; } -void mfc_algo_yale_all(uint8_t *uid, uint8_t *keys) {} // Saflok / Maid UID to key. -uint64_t mfc_algo_saflok_one(uint8_t *uid, uint8_t sector) { - return 0; +int mfc_algo_saflok_one(uint8_t *uid, uint8_t sector, uint64_t *key) { + if (sector > 15) return PM3_EINVARG; + if (key == NULL) return PM3_EINVARG; + return PM3_SUCCESS; } -void mfc_algo_saflok_all(uint8_t *uid, uint8_t *keys) { +int mfc_algo_saflok_all(uint8_t *uid, uint8_t *keys) { + if (keys == NULL) return PM3_EINVARG; + return PM3_SUCCESS; } // MIZIP algo -void mfc_algo_mizip_one(uint8_t *uid, uint8_t sector) { - return 0; +int mfc_algo_mizip_one(uint8_t *uid, uint8_t sector, uint64_t *key) { + if (sector > 4) return PM3_EINVARG; + if (key == NULL) return PM3_EINVARG; + return PM3_SUCCESS; } // returns all Mifare Mini (MFM) 10 keys. // keys must have 5*2*6 = 60bytes space -void mfc_algo_mizip_all(uint8_t *uid, uint8_t *keys) { - +int mfc_algo_mizip_all(uint8_t *uid, uint8_t *keys) { + if (keys == NULL) return PM3_EINVARG; + uint64_t xor_tbl[] = { 0x09125a2589e5ULL, 0xF12C8453D821ULL, 0xAB75C937922FULL, 0x73E799FE3241ULL, @@ -245,19 +262,30 @@ void mfc_algo_mizip_all(uint8_t *uid, uint8_t *keys) { ; num_to_bytes(b, 6, keys + 30 + (1 * i * 6)); } + return PM3_SUCCESS; } // Disney Infinity algo -void mfc_algo_di_one(uint8_t *uid, uint8_t sector) { - return 0; +int mfc_algo_di_one(uint8_t *uid, uint8_t sector, uint64_t *key) { + if (sector > 15) return PM3_EINVARG; + if (key == NULL) return PM3_EINVARG; + return PM3_SUCCESS; +} +int mfc_algo_di_all(uint8_t *uid, uint8_t *keys) { + if (keys == NULL) return PM3_EINVARG; + return PM3_SUCCESS; } -void mfc_algo_di_all(uint8_t *uid, uint8_t *keys) {} // Skylanders -void mfc_algo_sky_one(uint8_t *uid, uint8_t sector) { - return 0; +int mfc_algo_sky_one(uint8_t *uid, uint8_t sector, uint64_t *key) { + if (sector > 15) return PM3_EINVARG; + if (key == NULL) return PM3_EINVARG; + return PM3_SUCCESS; +} +int mfc_algo_sky_all(uint8_t *uid, uint8_t *keys) { + if (keys == NULL) return PM3_EINVARG; + return PM3_SUCCESS; } -void mfc_algo_sky_all(uint8_t *uid, uint8_t *keys) {} //------------------------------------ @@ -290,10 +318,10 @@ int generator_selftest() { success = (pwd4 == 0x72B1EC61); PrintAndLogEx(success ? SUCCESS : WARNING, "UID | %s | %08X | %s", sprint_hex(uid4, 7), pwd4, success ? "OK" : "->72B1EC61<--"); - uint8_t uid5[] = {0x11, 0x22, 0x33, 0x44}; - uint64_t key1 = mfc_algo_a(uid5); - success = (key1 == 0xD1E2AA68E39A); - PrintAndLogEx(success ? SUCCESS : WARNING, "UID | %s | %"PRIx64" | %s", sprint_hex(uid5, 4), key1, success ? "OK" : "->D1E2AA68E39A<--"); +// uint8_t uid5[] = {0x11, 0x22, 0x33, 0x44}; +// uint64_t key1 = mfc_algo_a(uid5); +// success = (key1 == 0xD1E2AA68E39A); +// PrintAndLogEx(success ? SUCCESS : WARNING, "UID | %s | %"PRIx64" | %s", sprint_hex(uid5, 4), key1, success ? "OK" : "->D1E2AA68E39A<--"); PrintAndLogEx(SUCCESS, "-------------------"); return PM3_SUCCESS; diff --git a/common/generator.h b/common/generator.h index 3ab678b73..8643c0de9 100644 --- a/common/generator.h +++ b/common/generator.h @@ -23,26 +23,26 @@ uint16_t ul_ev1_packgenB(uint8_t *uid); uint16_t ul_ev1_packgenC(uint8_t *uid); uint16_t ul_ev1_packgenD(uint8_t *uid); -uint64_t mfc_algo_ving_one(uint8_t *uid, uint8_t sector); -void mfc_algo_ving_all(uint8_t *uid, uint8_t *keys); +int mfc_algo_ving_one(uint8_t *uid, uint8_t sector, uint64_t *key); +int mfc_algo_ving_all(uint8_t *uid, uint8_t *keys); -uint64_t mfc_algo_yale_one(uint8_t *uid, uint8_t sector); -void mfc_algo_yale_all(uint8_t *uid, uint8_t *keys); +int mfc_algo_yale_one(uint8_t *uid, uint8_t sector, uint64_t *key); +int mfc_algo_yale_all(uint8_t *uid, uint8_t *keys); -uint64_t mfc_algo_saflok_one(uint8_t *uid, uint8_t sector); -void mfc_algo_saflok_all(uint8_t *uid, uint8_t *keys); +int mfc_algo_saflok_one(uint8_t *uid, uint8_t sector, uint64_t *key); +int mfc_algo_saflok_all(uint8_t *uid, uint8_t *keys); -uint64_t mfc_algo_saflok_one(uint8_t *uid, uint8_t sector); -void mfc_algo_saflok_all(uint8_t *uid, uint8_t *keys); +int mfc_algo_saflok_one(uint8_t *uid, uint8_t sector, uint64_t *key); +int mfc_algo_saflok_all(uint8_t *uid, uint8_t *keys); -uint64_t mfc_algo_mizip_one(uint8_t *uid, uint8_t sector); -void mfc_algo_mizip_all(uint8_t *uid, uint8_t *keys); +int mfc_algo_mizip_one(uint8_t *uid, uint8_t sector, uint64_t *key); +int mfc_algo_mizip_all(uint8_t *uid, uint8_t *keys); -uint64_t mfc_algo_di_one(uint8_t *uid, uint8_t sector); -void mfc_algo_di_all(uint8_t *uid, uint8_t *keys); +int mfc_algo_di_one(uint8_t *uid, uint8_t sector, uint64_t *key); +int mfc_algo_di_all(uint8_t *uid, uint8_t *keys); -uint64_t mfc_algo_sky_one(uint8_t *uid, uint8_t sector); -void mfc_algo_sky_all(uint8_t *uid, uint8_t *keys); +int mfc_algo_sky_one(uint8_t *uid, uint8_t sector, uint64_t *key); +int mfc_algo_sky_all(uint8_t *uid, uint8_t *keys); int generator_selftest(); #endif From 5b51f4b4ee948fb85a52d5d16881be0a15de1f61 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 2 Jan 2020 15:34:50 +0100 Subject: [PATCH 1354/1854] cppcheck --- armsrc/nprintf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/armsrc/nprintf.c b/armsrc/nprintf.c index f86406322..645454b4e 100644 --- a/armsrc/nprintf.c +++ b/armsrc/nprintf.c @@ -281,7 +281,7 @@ static size_t _ntoa_long(out_fct_type out, char *buffer, size_t idx, size_t maxl if (!(flags & FLAGS_PRECISION) || value) { do { const char digit = (char)(value % base); - buf[len++] = digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10; + buf[len++] = digit < 10 ? '0' + digit : ((flags & FLAGS_UPPERCASE) ? 'A' : 'a') + digit - 10; value /= base; } while (value && (len < PRINTF_NTOA_BUFFER_SIZE)); } @@ -305,7 +305,7 @@ static size_t _ntoa_long_long(out_fct_type out, char *buffer, size_t idx, size_t if (!(flags & FLAGS_PRECISION) || value) { do { const char digit = (char)(value % base); - buf[len++] = digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10; + buf[len++] = digit < 10 ? '0' + digit : ((flags & FLAGS_UPPERCASE) ? 'A' : 'a') + digit - 10; value /= base; } while (value && (len < PRINTF_NTOA_BUFFER_SIZE)); } From 1abcae291cfaace63daca69ca0c138c578614c50 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 2 Jan 2020 16:07:35 +0100 Subject: [PATCH 1355/1854] cppcheck --- client/emv/crypto_polarssl.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/client/emv/crypto_polarssl.c b/client/emv/crypto_polarssl.c index a6f69a529..8ed38fb05 100644 --- a/client/emv/crypto_polarssl.c +++ b/client/emv/crypto_polarssl.c @@ -150,9 +150,7 @@ static struct crypto_pk *crypto_pk_polarssl_open_priv_rsa(va_list vl) { static int myrand(void *rng_state, unsigned char *output, size_t len) { size_t i; - - if (rng_state != NULL) - rng_state = NULL; + rng_state = NULL; for (i = 0; i < len; ++i) output[i] = rand(); From 1f9ec97dfd5c12bdf43b8d970b10d6cf6a5fb959 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 2 Jan 2020 16:12:19 +0100 Subject: [PATCH 1356/1854] cppcheck --- client/cmdhffelica.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index 398b771d3..eedfea573 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -1395,11 +1395,11 @@ static int CmdHFFelicaSniff(const char *Cmd) { } i++; } - if (samples2skip <= 0) { + if (samples2skip == 0) { samples2skip = 10; PrintAndLogEx(INFO, "Set default samples2skip: %i", samples2skip); } - if (triggers2skip <= 0) { + if (triggers2skip == 0) { triggers2skip = 5000; PrintAndLogEx(INFO, "Set default triggers2skip: %i", triggers2skip); } From 0fcd79617d4cec8109377d0194d7e038f43c2fca Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 2 Jan 2020 16:17:46 +0100 Subject: [PATCH 1357/1854] cppcheck --- client/cmdhffelica.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index eedfea573..f34046799 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -345,7 +345,7 @@ static bool waitCmdFelica(uint8_t iSelect, PacketResponseNG *resp, bool verbose) uint16_t len = iSelect ? (resp->oldarg[1] & 0xffff) : (resp->oldarg[0] & 0xffff); if (verbose) { PrintAndLogEx(SUCCESS, "Client Received %i octets", len); - if (!len || len < 2) { + if (len == 0 || len == 1) { PrintAndLogEx(ERR, "Could not receive data correctly!"); return false; } @@ -575,6 +575,7 @@ static int CmdHFFelicaAuthentication1(const char *Cmd) { if (strlen(Cmd) < 4) { return usage_hf_felica_authentication1(); } + PrintAndLogEx(INFO, "EXPERIMENTAL COMMAND"); uint8_t data[PM3_CMD_DATA_SIZE]; bool custom_IDm = false; @@ -611,7 +612,7 @@ static int CmdHFFelicaAuthentication1(const char *Cmd) { // Number of Area (1), Area Code List (2), Number of Service (1), Service Code List (2), M1c (8) uint8_t lengths[] = {2, 4, 2, 4}; uint8_t dataPositions[] = {10, 11, 13, 14}; - for (int i = 0; i < 4; i++) { + for (i = 0; i < 4; i++) { if (add_param(Cmd, paramCount, data, dataPositions[i], lengths[i])) { paramCount++; } else { @@ -653,7 +654,7 @@ static int CmdHFFelicaAuthentication1(const char *Cmd) { PrintAndLogEx(INFO, "3DES ENCRYPTED M1c: %s", sprint_hex(output, 8)); // Add M1c Challenge to frame int frame_position = 16; - for (int i = 0; i < 8; i++) { + for (i = 0; i < 8; i++) { data[frame_position++] = output[i]; } @@ -684,7 +685,7 @@ static int CmdHFFelicaAuthentication1(const char *Cmd) { bool isKeyCorrect = false; unsigned char p2c[8]; mbedtls_des3_crypt_ecb(&des3_ctx, auth1_response.m2c, p2c); - for (int i = 0; i < 8; i++) { + for (i = 0; i < 8; i++) { if (p2c[i] != input[i]) { isKeyCorrect = false; break; @@ -781,7 +782,7 @@ static int CmdHFFelicaAuthentication2(const char *Cmd) { // Add M4c Challenge to frame int frame_position = 10; - for (int i = 0; i < 8; i++) { + for (i = 0; i < 8; i++) { data[frame_position++] = m4c[i]; } @@ -856,7 +857,7 @@ static int CmdHFFelicaWriteWithoutEncryption(const char *Cmd) { // Number of Service 2, Service Code List 4, Number of Block 2, Block List Element 4, Data 16 uint8_t lengths[] = {2, 4, 2, 4, 32}; uint8_t dataPositions[] = {10, 11, 13, 14, 16}; - for (int i = 0; i < 5; i++) { + for (i = 0; i < 5; i++) { if (add_param(Cmd, paramCount, data, dataPositions[i], lengths[i])) { paramCount++; } else { @@ -938,7 +939,7 @@ static int CmdHFFelicaReadWithoutEncryption(const char *Cmd) { datalen += 1; lengths[3] = 6; } - for (int i = 0; i < 4; i++) { + for (i = 0; i < 4; i++) { if (add_param(Cmd, paramCount, data, dataPositions[i], lengths[i])) { paramCount++; } else { @@ -954,7 +955,7 @@ static int CmdHFFelicaReadWithoutEncryption(const char *Cmd) { last_block_number = 0xFFFF; } PrintAndLogEx(INFO, "Block Element\t| Data "); - for (int i = 0x00; i < last_block_number; i++) { + for (i = 0x00; i < last_block_number; i++) { data[15] = i; AddCrc(data, datalen); datalen += 2; @@ -1106,6 +1107,7 @@ static int CmdHFFelicaRequestSpecificationVersion(const char *Cmd) { } else { felica_request_spec_response_t spec_response; memcpy(&spec_response, (felica_request_spec_response_t *)resp.data.asBytes, sizeof(felica_request_spec_response_t)); + if (spec_response.frame_response.IDm[0] != 0) { PrintAndLogEx(SUCCESS, "\nGot Request Response:"); PrintAndLogEx(SUCCESS, "\nIDm: %s", sprint_hex(spec_response.frame_response.IDm, sizeof(spec_response.frame_response.IDm))); @@ -1117,7 +1119,7 @@ static int CmdHFFelicaRequestSpecificationVersion(const char *Cmd) { PrintAndLogEx(SUCCESS, "Number of Option: %s", sprint_hex(spec_response.number_of_option, sizeof(spec_response.number_of_option))); if (spec_response.number_of_option[0] == 0x01) { PrintAndLogEx(SUCCESS, "Option Version List:"); - for (uint8_t i = 0; i < spec_response.number_of_option[0]; i++) { + for (i = 0; i < spec_response.number_of_option[0]; i++) { PrintAndLogEx(SUCCESS, " - %s", sprint_hex(spec_response.option_version_list + i * 2, sizeof(uint8_t) * 2)); } } @@ -1252,12 +1254,13 @@ static int CmdHFFelicaRequestSystemCode(const char *Cmd) { } else { felica_syscode_response_t rq_syscode_response; memcpy(&rq_syscode_response, (felica_syscode_response_t *)resp.data.asBytes, sizeof(felica_syscode_response_t)); + if (rq_syscode_response.frame_response.IDm[0] != 0) { PrintAndLogEx(SUCCESS, "\nGot Request Response:"); PrintAndLogEx(SUCCESS, "IDm: %s", sprint_hex(rq_syscode_response.frame_response.IDm, sizeof(rq_syscode_response.frame_response.IDm))); PrintAndLogEx(SUCCESS, " - Number of Systems: %s", sprint_hex(rq_syscode_response.number_of_systems, sizeof(rq_syscode_response.number_of_systems))); PrintAndLogEx(SUCCESS, " - System Codes: enumerated in ascending order starting from System 0."); - for (uint8_t i = 0; i < rq_syscode_response.number_of_systems[0]; i++) { + for (i = 0; i < rq_syscode_response.number_of_systems[0]; i++) { PrintAndLogEx(SUCCESS, " - %s", sprint_hex(rq_syscode_response.system_code_list + i * 2, sizeof(uint8_t) * 2)); } } From ac8e74c1d9de2e74f0ca87b6484ad650cba12837 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 2 Jan 2020 19:52:23 +0100 Subject: [PATCH 1358/1854] cppcheck --- client/cmdlft55xx.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 72dc7befe..d992b6d58 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -3062,8 +3062,6 @@ static int CmdT55xxChkPwds(const char *Cmd) { return PM3_ESOFT; } - // loop - uint64_t curr_password = 0x00; for (uint16_t c = 0; c < keycount; ++c) { if (!session.pm3_present) { @@ -3077,7 +3075,7 @@ static int CmdT55xxChkPwds(const char *Cmd) { return PM3_EOPABORTED; } - curr_password = bytes_to_num(keyBlock + 4 * c, 4); + uint64_t curr_password = bytes_to_num(keyBlock + 4 * c, 4); PrintAndLogEx(INFO, "Testing %08"PRIX64, curr_password); for (dl_mode = downlink_mode; dl_mode <= 3; dl_mode++) { @@ -3485,14 +3483,20 @@ static int CmdT55xxDetectPage1(const char *Cmd) { if (!useGB) { for (dl_mode = downlink_mode; dl_mode < 4; dl_mode++) { found = AcquireData(T55x7_PAGE1, T55x7_TRACE_BLOCK1, usepwd, password, dl_mode); - //return PM3_ENODATA; - if (tryDetectP1(false)) { //tryDetectModulation()) + if (found == false) + continue; + + if (tryDetectP1(false)) { found = true; found_mode = dl_mode; dl_mode = 4; - } else found = false; + } else { + found = false; + } - if (!try_all_dl_modes) dl_mode = 4; + if (!try_all_dl_modes) { + dl_mode = 4; + } } } else { From e1503a255b8d719d19d4de6c76743eecbf05ac5c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 3 Jan 2020 17:40:03 +0100 Subject: [PATCH 1359/1854] covery 263989 --- client/cmdhffelica.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index f34046799..017c34c0e 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -528,7 +528,7 @@ static bool check_last_idm(uint8_t *data, uint16_t datalen) { PrintAndLogEx(ERR, "No last known card! Use reader first or set a custom IDm!"); return 0; } else { - PrintAndLogEx(INFO, "Used last known IDm.", sprint_hex(data, datalen)); + PrintAndLogEx(INFO, "Used last known IDm. %s", sprint_hex(data, datalen)); return 1; } } From 78aae857ac92c19d9995d3bd3de806dd02439b04 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 3 Jan 2020 17:46:50 +0100 Subject: [PATCH 1360/1854] covery 263985 --- client/cmdhffelica.c | 39 ++++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index 017c34c0e..f0691c06f 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -440,8 +440,12 @@ static void clear_and_send_command(uint8_t flags, uint16_t datalen, uint8_t *dat */ static bool add_param(const char *Cmd, uint8_t paramCount, uint8_t *data, uint8_t dataPosition, uint8_t length) { if (param_getlength(Cmd, paramCount) == length) { - param_gethex(Cmd, paramCount, data + dataPosition, length); - return true; + + if (param_gethex(Cmd, paramCount, data + dataPosition, length) == 1) + return false; + else + return true; + } else { PrintAndLogEx(ERR, "Param %s", Cmd); PrintAndLogEx(ERR, "Incorrect Parameter length! Param %i should be %i", paramCount, length); @@ -637,11 +641,19 @@ static int CmdHFFelicaAuthentication1(const char *Cmd) { mbedtls_des3_context des3_ctx; mbedtls_des3_init(&des3_ctx); if (param_getlength(Cmd, paramCount) == 48) { - param_gethex(Cmd, paramCount, master_key, 48); + if (param_gethex(Cmd, paramCount, master_key, 48) == 1) { + PrintAndLogEx(ERR, "Failed param key"); + return PM3_EINVARG; + } mbedtls_des3_set3key_enc(&des3_ctx, master_key); PrintAndLogEx(INFO, "3DES Master Secret: %s", sprint_hex(master_key, 24)); } else if (param_getlength(Cmd, paramCount) == 32) { - param_gethex(Cmd, paramCount, master_key, 32); + + if (param_gethex(Cmd, paramCount, master_key, 32) == 1) { + PrintAndLogEx(ERR, "Failed param key"); + return PM3_EINVARG; + } + // Assumption: Master secret split in half for Kac, Kbc mbedtls_des3_set2key_enc(&des3_ctx, master_key); PrintAndLogEx(INFO, "3DES Master Secret: %s", sprint_hex(master_key, 16)); @@ -761,7 +773,11 @@ static int CmdHFFelicaAuthentication2(const char *Cmd) { mbedtls_des3_init(&des3_ctx); unsigned char p3c[8]; if (param_getlength(Cmd, paramCount) == 32) { - param_gethex(Cmd, paramCount, master_key, 32); + + if (param_gethex(Cmd, paramCount, master_key, 32)) == 1) { + PrintAndLogEx(ERR, "Failed param key"); + return PM3_EINVARG; + } reverse_3des_key(master_key, 16, reverse_master_key); mbedtls_des3_set2key_dec(&des3_ctx, reverse_master_key); mbedtls_des3_set2key_enc(&des3_ctx, master_key); @@ -1311,7 +1327,12 @@ static int CmdHFFelicaRequestService(const char *Cmd) { if (!all_nodes) { // Node Number if (param_getlength(Cmd, paramCount) == 2) { - param_gethex(Cmd, paramCount++, data + 10, 2); + + if (param_gethex(Cmd, paramCount++, data + 10, 2) == 1) { + PrintAndLogEx(ERR, "Failed param key"); + return PM3_EINVARG; + } + } else { PrintAndLogEx(ERR, "Incorrect Node number length!"); return PM3_EINVARG; @@ -1319,7 +1340,11 @@ static int CmdHFFelicaRequestService(const char *Cmd) { } if (param_getlength(Cmd, paramCount) == 4) { - param_gethex(Cmd, paramCount++, data + 11, 4); + + if (param_gethex(Cmd, paramCount++, data + 11, 4) == 1) { + PrintAndLogEx(ERR, "Failed param key"); + return PM3_EINVARG; + } } else { PrintAndLogEx(ERR, "Incorrect parameter length!"); return PM3_EINVARG; From c1f9e076a8d8ce31141179d051c4e8302a1e3ae9 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 3 Jan 2020 17:53:03 +0100 Subject: [PATCH 1361/1854] covery --- client/cmdhffelica.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index f0691c06f..32a6fe164 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -458,14 +458,19 @@ static bool add_param(const char *Cmd, uint8_t paramCount, uint8_t *data, uint8_ * @param rd_noCry_resp Response frame. */ static void print_rd_noEncrpytion_response(felica_read_without_encryption_response_t *rd_noCry_resp) { - if (rd_noCry_resp->status_flags.status_flag1[0] == 00 && rd_noCry_resp->status_flags.status_flag2[0] == 00) { + + if (rd_noCry_resp->status_flags.status_flag1[0] == 00 && + rd_noCry_resp->status_flags.status_flag2[0] == 00) { + char *temp = sprint_hex(rd_noCry_resp->block_data, sizeof(rd_noCry_resp->block_data)); + char bl_data[256]; strcpy(bl_data, temp); char bl_element_number[4]; temp = sprint_hex(rd_noCry_resp->block_element_number, sizeof(rd_noCry_resp->block_element_number)); strcpy(bl_element_number, temp); + PrintAndLogEx(INFO, "\t%s\t| %s ", bl_element_number, bl_data); } else { PrintAndLogEx(SUCCESS, "IDm: %s", sprint_hex(rd_noCry_resp->frame_response.IDm, sizeof(rd_noCry_resp->frame_response.IDm))); @@ -754,11 +759,13 @@ static int CmdHFFelicaAuthentication2(const char *Cmd) { } i++; } + data[0] = int_to_hex(&datalen); data[1] = 0x12; // Command ID if (!custom_IDm && !check_last_idm(data, datalen)) { return PM3_EINVARG; } + // M3c (8) unsigned char m3c[8]; if (add_param(Cmd, paramCount, m3c, 0, 16)) { @@ -766,6 +773,7 @@ static int CmdHFFelicaAuthentication2(const char *Cmd) { } else { return PM3_EINVARG; } + // Create M4c challenge response with 3DES uint8_t master_key[PM3_CMD_DATA_SIZE]; uint8_t reverse_master_key[PM3_CMD_DATA_SIZE]; @@ -774,7 +782,7 @@ static int CmdHFFelicaAuthentication2(const char *Cmd) { unsigned char p3c[8]; if (param_getlength(Cmd, paramCount) == 32) { - if (param_gethex(Cmd, paramCount, master_key, 32)) == 1) { + if (param_gethex(Cmd, paramCount, master_key, 32) == 1) { PrintAndLogEx(ERR, "Failed param key"); return PM3_EINVARG; } @@ -1354,9 +1362,11 @@ static int CmdHFFelicaRequestService(const char *Cmd) { if (custom_IDm) { flags |= FELICA_NO_SELECT; } + if (datalen > 0) { flags |= FELICA_RAW; } + datalen = (datalen > PM3_CMD_DATA_SIZE) ? PM3_CMD_DATA_SIZE : datalen; if (!custom_IDm && !check_last_idm(data, datalen)) { return PM3_EINVARG; @@ -1423,13 +1433,15 @@ static int CmdHFFelicaSniff(const char *Cmd) { } i++; } + if (samples2skip == 0) { samples2skip = 10; - PrintAndLogEx(INFO, "Set default samples2skip: %i", samples2skip); + PrintAndLogEx(INFO, "Set default samples2skip: %" PRIu64, samples2skip); } + if (triggers2skip == 0) { triggers2skip = 5000; - PrintAndLogEx(INFO, "Set default triggers2skip: %i", triggers2skip); + PrintAndLogEx(INFO, "Set default triggers2skip: %" PRIu64, triggers2skip); } PrintAndLogEx(INFO, "Start Sniffing now. You can stop sniffing with clicking the PM3 Button"); From 9020df5b302d061408489cfc28ecd8295157fce6 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 3 Jan 2020 17:57:45 +0100 Subject: [PATCH 1362/1854] covery --- client/aidsearch.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/client/aidsearch.c b/client/aidsearch.c index ecaa6e6c8..676db4cc7 100644 --- a/client/aidsearch.c +++ b/client/aidsearch.c @@ -8,14 +8,11 @@ // Proxmark3 RDV40 AID list library //----------------------------------------------------------------------------- #include "aidsearch.h" - #include #include - #include "fileutils.h" #include "pm3_cmd.h" - int openAIDFile(json_t **root, bool verbose) { json_error_t error; @@ -39,7 +36,7 @@ int openAIDFile(json_t **root, bool verbose) { goto out; } - if (verbose) PrintAndLogEx(SUCCESS, "Loaded file (%s) OK. %d records.", path, json_array_size(*root)); + if (verbose) PrintAndLogEx(SUCCESS, "Loaded file (%s) OK. %zu records.", path, json_array_size(*root)); out: free(path); return retval; From 21de7a265bed95d1034ee8087ffbd754b7fe95cd Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 3 Jan 2020 18:07:31 +0100 Subject: [PATCH 1363/1854] covery 265055, 265056, 265059 resource leak --- client/cmdhfmf.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 9b43f5a3d..a8960d5d0 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -1799,6 +1799,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { // create/initialize key storage structure int32_t res = initSectorTable(&e_sector, sectors_cnt); if (res != sectors_cnt) { + free(e_sector); return PM3_EMALLOC; } @@ -3644,8 +3645,10 @@ static int CmdHF14AMfEKeyPrn(const char *Cmd) { // create/initialize key storage structure int32_t res = initSectorTable(&e_sector, sectors_cnt); - if (res != sectors_cnt) + if (res != sectors_cnt) { + free(e_sector); return PM3_EMALLOC; + } // read UID from EMUL if (mfEmlGetMem(data, 0, 1) != PM3_SUCCESS) { @@ -4083,6 +4086,7 @@ static int CmdHF14AMfCSave(const char *Cmd) { PacketResponseNG resp; if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { PrintAndLogEx(WARNING, "iso14443a card select failed"); + free(dump); return PM3_ESOFT; } From b7e8ee86a042da0d1a03ae308047cde7f59e8861 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 3 Jan 2020 18:08:42 +0100 Subject: [PATCH 1364/1854] covery 265060 resource leak --- client/fileutils.c | 1 + 1 file changed, 1 insertion(+) diff --git a/client/fileutils.c b/client/fileutils.c index a11dbcd2a..b13a092eb 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -473,6 +473,7 @@ int createMfcKeyDump(const char *preferredName, uint8_t sectorsCnt, sector_t *e_ FILE *f = fopen(fileName, "wb"); if (f == NULL) { PrintAndLogEx(WARNING, "Could not create file " _YELLOW_("%s"), fileName); + free(fileName); return PM3_EFILE; } PrintAndLogEx(SUCCESS, "Generating binary key file"); From 30c45c4741c6ec7faaead6e3e080f498dce65fe6 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 3 Jan 2020 18:13:05 +0100 Subject: [PATCH 1365/1854] covery 265057 - fseek --- client/fileutils.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/client/fileutils.c b/client/fileutils.c index b13a092eb..dcdffb401 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -856,9 +856,13 @@ int loadFileDICTIONARYEx(const char *preferredName, void *data, size_t maxdatale goto out; } - if (startFilePosition) - fseek(f, startFilePosition, SEEK_SET); - + if (startFilePosition) { + if (fseek(f, startFilePosition, SEEK_SET) < 0){ + retval = PM3_EFILE; + goto out; + } + } + // read file while (!feof(f)) { size_t filepos = ftell(f); From 217c8d043cf01208dd456da96c02fb806bf7f9de Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 3 Jan 2020 18:18:37 +0100 Subject: [PATCH 1366/1854] covery 265061 --- client/fileutils.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/fileutils.c b/client/fileutils.c index dcdffb401..d0428a9a6 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -161,7 +161,7 @@ int saveFile(const char *preferredName, const char *suffix, const void *data, si fwrite(data, 1, datalen, f); fflush(f); fclose(f); - PrintAndLogEx(SUCCESS, "saved %zu bytes to binary file " _YELLOW_("%s"), datalen, fileName); + PrintAndLogEx(SUCCESS, "saved " _YELLOW_("%" PRIu16 )" bytes to binary file " _YELLOW_("%s"), datalen, fileName); free(fileName); return PM3_SUCCESS; } @@ -204,7 +204,7 @@ int saveFileEML(const char *preferredName, uint8_t *data, size_t datalen, size_t } fflush(f); fclose(f); - PrintAndLogEx(SUCCESS, "saved %d blocks to text file " _YELLOW_("%s"), blocks, fileName); + PrintAndLogEx(SUCCESS, "saved " _YELLOW_("%" PRId32 )" blocks to text file " _YELLOW_("%s"), blocks, fileName); out: free(fileName); @@ -429,7 +429,7 @@ int saveFileWAVE(const char *preferredName, int *data, size_t datalen) { } sf_close(wave_file); - PrintAndLogEx(SUCCESS, "saved " _YELLOW_("%d")" bytes to wave file " _YELLOW_("'%s'"), 2 * datalen, fileName); + PrintAndLogEx(SUCCESS, "saved " _YELLOW_("%" PRIu32 )" bytes to wave file " _YELLOW_("'%s'"), 2 * datalen, fileName); out: free(fileName); @@ -456,7 +456,7 @@ int saveFilePM3(const char *preferredName, int *data, size_t datalen) { fflush(f); fclose(f); - PrintAndLogEx(SUCCESS, "saved " _YELLOW_("%d")" bytes to PM3 file " _YELLOW_("'%s'"), datalen, fileName); + PrintAndLogEx(SUCCESS, "saved " _YELLOW_("%" PRIu16 )" bytes to PM3 file " _YELLOW_("'%s'"), datalen, fileName); out: free(fileName); From c2e3f8c7d5621f70d02b71b2359320b49ba72d13 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 3 Jan 2020 18:19:42 +0100 Subject: [PATCH 1367/1854] covery 265061 --- client/cmdtrace.c | 1 + 1 file changed, 1 insertion(+) diff --git a/client/cmdtrace.c b/client/cmdtrace.c index 51f5fad28..a13a82809 100644 --- a/client/cmdtrace.c +++ b/client/cmdtrace.c @@ -381,6 +381,7 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr break; case FELICA: annotateFelica(explanation, sizeof(explanation), frame, data_len); + break; case LTO: annotateLTO(explanation, sizeof(explanation), frame, data_len); break; From 12885d6726be8c089da378147a86b3e54ddc1e49 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 3 Jan 2020 18:41:53 +0100 Subject: [PATCH 1368/1854] covery 263986 --- client/cmdhffelica.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index 32a6fe164..734962651 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -1332,6 +1332,7 @@ static int CmdHFFelicaRequestService(const char *Cmd) { } i++; } + if (!all_nodes) { // Node Number if (param_getlength(Cmd, paramCount) == 2) { @@ -1366,11 +1367,12 @@ static int CmdHFFelicaRequestService(const char *Cmd) { if (datalen > 0) { flags |= FELICA_RAW; } - + datalen = (datalen > PM3_CMD_DATA_SIZE) ? PM3_CMD_DATA_SIZE : datalen; if (!custom_IDm && !check_last_idm(data, datalen)) { return PM3_EINVARG; } + data[0] = int_to_hex(&datalen); data[1] = 0x02; // Service Request Command ID if (all_nodes) { @@ -1742,7 +1744,7 @@ static int CmdHFFelicaCmdRaw(const char *Cmd) { sscanf(buf, "%x", &temp); data[datalen] = (uint8_t)(temp & 0xff); *buf = 0; - if (++datalen >= sizeof(data)) { + if (++datalen >= (sizeof(data) - 2)) { if (crc) PrintAndLogEx(WARNING, "Buffer is full, we can't add CRC to your data"); break; From 5f1ef5f5903a4a43a0fd20283dd4b79296632822 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 3 Jan 2020 19:50:27 +0200 Subject: [PATCH 1369/1854] fix `shadow variable` thanks @iceman1001 ) --- client/emv/dol.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/emv/dol.c b/client/emv/dol.c index c7f8fd563..973349e56 100644 --- a/client/emv/dol.c +++ b/client/emv/dol.c @@ -32,14 +32,14 @@ static size_t dol_calculate_len(const struct tlv *tlv, size_t data_len) { size_t count = 0; while (left) { - struct tlv tlv; - if (!tlv_parse_tl(&buf, &left, &tlv)) + struct tlv cur_tlv; + if (!tlv_parse_tl(&buf, &left, &cur_tlv)) return 0; - count += tlv.len; + count += cur_tlv.len; /* Last tag can be of variable length */ - if (tlv.len == 0 && left == 0) + if (cur_tlv.len == 0 && left == 0) count = data_len; } From 51ad5c23321b2f1a22f4b6f371f9a8e438dcbcac Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 3 Jan 2020 18:55:13 +0100 Subject: [PATCH 1370/1854] cppcheck --- armsrc/usart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/usart.c b/armsrc/usart.c index f3abb40a1..2062c9441 100644 --- a/armsrc/usart.c +++ b/armsrc/usart.c @@ -49,7 +49,7 @@ static size_t us_rxfifo_high = 0; static void usart_fill_rxfifo(void) { - uint16_t rxfifo_free = 0; + uint16_t rxfifo_free ; if (pUS1->US_RNCR == 0) { // One buffer got filled, backup buffer being used if (us_rxfifo_low > us_rxfifo_high) rxfifo_free = us_rxfifo_low - us_rxfifo_high; From 15597c6c38e02ec9a456a22487b9e2f84d771a69 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 3 Jan 2020 18:59:41 +0100 Subject: [PATCH 1371/1854] cppcheck --- client/cmdhw.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/client/cmdhw.c b/client/cmdhw.c index a35f15b5e..b71512432 100644 --- a/client/cmdhw.c +++ b/client/cmdhw.c @@ -539,9 +539,8 @@ static int CmdPing(const char *Cmd) { data[i] = i & 0xFF; SendCommandNG(CMD_PING, data, len); if (WaitForResponseTimeout(CMD_PING, &resp, 1000)) { - bool error = false; if (len) { - error = memcmp(data, resp.data.asBytes, len) != 0; + bool error = (memcmp(data, resp.data.asBytes, len) != 0); PrintAndLogEx((error) ? ERR : SUCCESS, "Ping response " _GREEN_("received") "and content is %s", error ? _RED_("NOT ok") : _GREEN_("OK")); } else { PrintAndLogEx(SUCCESS, "Ping response " _GREEN_("received")); From 4523350471c5a76b433d6e369b36c006d6af9e03 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 3 Jan 2020 19:07:00 +0100 Subject: [PATCH 1372/1854] coverty 265064, 226284 --- client/fileutils.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/fileutils.c b/client/fileutils.c index d0428a9a6..64e5607a8 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -161,7 +161,7 @@ int saveFile(const char *preferredName, const char *suffix, const void *data, si fwrite(data, 1, datalen, f); fflush(f); fclose(f); - PrintAndLogEx(SUCCESS, "saved " _YELLOW_("%" PRIu16 )" bytes to binary file " _YELLOW_("%s"), datalen, fileName); + PrintAndLogEx(SUCCESS, "saved " _YELLOW_("%" PRIu32 )" bytes to binary file " _YELLOW_("%s"), datalen, fileName); free(fileName); return PM3_SUCCESS; } @@ -858,6 +858,7 @@ int loadFileDICTIONARYEx(const char *preferredName, void *data, size_t maxdatale if (startFilePosition) { if (fseek(f, startFilePosition, SEEK_SET) < 0){ + fclose(f); retval = PM3_EFILE; goto out; } From 6f9b9335a144fd9b51a471c8e86aadf269c758d3 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 3 Jan 2020 19:13:35 +0100 Subject: [PATCH 1373/1854] coverty 226291 --- client/emv/crypto_polarssl.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/client/emv/crypto_polarssl.c b/client/emv/crypto_polarssl.c index 8ed38fb05..b0cb59baa 100644 --- a/client/emv/crypto_polarssl.c +++ b/client/emv/crypto_polarssl.c @@ -136,9 +136,15 @@ static struct crypto_pk *crypto_pk_polarssl_open_priv_rsa(va_list vl) { mbedtls_mpi_read_binary(&cp->ctx.Q, (const unsigned char *)q, qlen); mbedtls_mpi_read_binary(&cp->ctx.DP, (const unsigned char *)dp, dplen); mbedtls_mpi_read_binary(&cp->ctx.DQ, (const unsigned char *)dq, dqlen); - mbedtls_mpi_inv_mod(&cp->ctx.QP, &cp->ctx.Q, &cp->ctx.P); + + int res = mbedtls_mpi_inv_mod(&cp->ctx.QP, &cp->ctx.Q, &cp->ctx.P); + if (res != 0) { + fprintf(stderr, "PolarSSL private key error res=%x exp=%d mod=%d.\n", res * -1, explen, modlen); + free(cp); + return NULL; + } - int res = mbedtls_rsa_check_privkey(&cp->ctx); + res = mbedtls_rsa_check_privkey(&cp->ctx); if (res != 0) { fprintf(stderr, "PolarSSL private key error res=%x exp=%d mod=%d.\n", res * -1, explen, modlen); free(cp); From 0684060ec047b526636d8e330f18d093f058e59f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 3 Jan 2020 19:16:13 +0100 Subject: [PATCH 1374/1854] coverty 226411 --- client/loclass/cipherutils.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/client/loclass/cipherutils.c b/client/loclass/cipherutils.c index d291c4886..5f16b68fd 100644 --- a/client/loclass/cipherutils.c +++ b/client/loclass/cipherutils.c @@ -169,6 +169,9 @@ void printvar(const char *name, uint8_t *arr, int len) { } void printarr_human_readable(const char *title, uint8_t *arr, int len) { + + if (arr == NULL) return; + int cx = 0, i; size_t outsize = 100 + strlen(title) + len * 4; char *output = calloc(outsize, sizeof(char)); From a0b6061b86c9dc33a88cc8e106e3cb6afbfb0db8 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 3 Jan 2020 19:22:04 +0100 Subject: [PATCH 1375/1854] coverty --- client/fileutils.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/fileutils.c b/client/fileutils.c index 64e5607a8..2710998b5 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -161,7 +161,7 @@ int saveFile(const char *preferredName, const char *suffix, const void *data, si fwrite(data, 1, datalen, f); fflush(f); fclose(f); - PrintAndLogEx(SUCCESS, "saved " _YELLOW_("%" PRIu32 )" bytes to binary file " _YELLOW_("%s"), datalen, fileName); + PrintAndLogEx(SUCCESS, "saved " _YELLOW_("%zu")" bytes to binary file " _YELLOW_("%s"), datalen, fileName); free(fileName); return PM3_SUCCESS; } @@ -429,7 +429,7 @@ int saveFileWAVE(const char *preferredName, int *data, size_t datalen) { } sf_close(wave_file); - PrintAndLogEx(SUCCESS, "saved " _YELLOW_("%" PRIu32 )" bytes to wave file " _YELLOW_("'%s'"), 2 * datalen, fileName); + PrintAndLogEx(SUCCESS, "saved " _YELLOW_("%zu")" bytes to wave file " _YELLOW_("'%s'"), 2 * datalen, fileName); out: free(fileName); @@ -456,7 +456,7 @@ int saveFilePM3(const char *preferredName, int *data, size_t datalen) { fflush(f); fclose(f); - PrintAndLogEx(SUCCESS, "saved " _YELLOW_("%" PRIu16 )" bytes to PM3 file " _YELLOW_("'%s'"), datalen, fileName); + PrintAndLogEx(SUCCESS, "saved " _YELLOW_("%zu")" bytes to PM3 file " _YELLOW_("'%s'"), datalen, fileName); out: free(fileName); From 5bc2aea1b494c375c8bbd31cf012d0dfe81fd1fd Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 4 Jan 2020 12:50:54 +0100 Subject: [PATCH 1376/1854] add a document with all commands, generated with the XX_internal_command_dump_markdown_XX --- doc/commands.md | 920 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 920 insertions(+) create mode 100644 doc/commands.md diff --git a/doc/commands.md b/doc/commands.md new file mode 100644 index 000000000..50cd0e805 --- /dev/null +++ b/doc/commands.md @@ -0,0 +1,920 @@ +[=] Session log /home/iceman/.proxmark3/log_20200104.txt +[+] execute command from commandline: XX_internal_command_dump_markdown_XX + +[=] Using UART port /dev/ttyS7 +[=] Communicating with PM3 over USB-CDC +pm3 --> XX_internal_command_dump_markdown_XX +|command |offline |description +|------- |------- |----------- +|`help `|Y |`This help. Use ' help' for details of a particular command.` +|`auto `|Y |`Automated detection process for unknown tags` +|` `|Y |`` +|`msleep `|Y |`Add a pause in milliseconds` +|`rem `|Y |`Add a text line in log file` +|`quit `|Y |`` +|`exit `|Y |`Exit program` + + +### analyse + + { Analyse utils... } + +|command |offline |description +|------- |------- |----------- +|`analyse help `|Y |`This help` +|`analyse lcr `|Y |`Generate final byte for XOR LRC` +|`analyse crc `|Y |`Stub method for CRC evaluations` +|`analyse chksum `|Y |`Checksum with adding, masking and one's complement` +|`analyse dates `|Y |`Look for datestamps in a given array of bytes` +|`analyse tea `|Y |`Crypto TEA test` +|`analyse lfsr `|Y |`LFSR tests` +|`analyse a `|Y |`num bits test` +|`analyse nuid `|Y |`create NUID from 7byte UID` +|`analyse demodbuff `|Y |`Load binary string to demodbuffer` + + +### data + + { Plot window / data buffer manipulation... } + +|command |offline |description +|------- |------- |----------- +|`data help `|Y |`This help` +|`data askedgedetect `|Y |`[threshold] Adjust Graph for manual ASK demod using the length of sample differences to detect the edge of a wave (use 20-45, def:25)` +|`data autocorr `|Y |`[window length] [g] -- Autocorrelation over window - g to save back to GraphBuffer (overwrite)` +|`data biphaserawdecode `|Y |`[offset] [invert<0|1>] [maxErr] -- Biphase decode bin stream in DemodBuffer (offset = 0|1 bits to shift the decode start)` +|`data bin2hex `|Y |` -- Converts binary to hexadecimal` +|`data bitsamples `|Y |`Get raw samples as bitstring` +|`data buffclear `|Y |`Clears bigbuff on deviceside and graph window` +|`data convertbitstream `|Y |`Convert GraphBuffer's 0/1 values to 127 / -127` +|`data dec `|Y |`Decimate samples` +|`data detectclock `|Y |`[] Detect ASK, FSK, NRZ, PSK clock rate of wave in GraphBuffer` +|`data fsktonrz `|Y |`Convert fsk2 to nrz wave for alternate fsk demodulating (for weak fsk)` +|`data getbitstream `|Y |`Convert GraphBuffer's >=1 values to 1 and <1 to 0` +|`data grid `|Y |` -- overlay grid on graph window, use zero value to turn off either` +|`data hexsamples `|Y |` [] -- Dump big buffer as hex bytes` +|`data hex2bin `|Y |` -- Converts hexadecimal to binary` +|`data hide `|Y |`Hide graph window` +|`data hpf `|Y |`Remove DC offset from trace` +|`data load `|Y |` -- Load trace (to graph window` +|`data ltrim `|Y |` -- Trim samples from left of trace` +|`data rtrim `|Y |` -- Trim samples from right of trace` +|`data mtrim `|Y |` -- Trim out samples from the specified start to the specified stop` +|`data manrawdecode `|Y |`[invert] [maxErr] -- Manchester decode binary stream in DemodBuffer` +|`data norm `|Y |`Normalize max/min to +/-128` +|`data plot `|Y |`Show graph window (hit 'h' in window for keystroke help)` +|`data printdemodbuffer `|Y |`[x] [o] [l] -- print the data in the DemodBuffer - 'x' for hex output` +|`data rawdemod `|Y |`[modulation] ... -see help (h option) -- Demodulate the data in the GraphBuffer and output binary` +|`data samples `|Y |`[512 - 40000] -- Get raw samples for graph window (GraphBuffer)` +|`data save `|Y |`Save trace (from graph window)` +|`data setgraphmarkers `|Y |`[orange_marker] [blue_marker] (in graph window)` +|`data scale `|Y |` -- Set cursor display scale in carrier frequency expressed in kHz` +|`data setdebugmode `|Y |`<0|1|2> -- Set Debugging Level on client side` +|`data shiftgraphzero `|Y |` -- Shift 0 for Graphed wave + or - shift value` +|`data dirthreshold `|Y |` -- Max rising higher up-thres/ Min falling lower down-thres, keep rest as prev.` +|`data tune `|Y |`Get hw tune samples for graph window` +|`data undec `|Y |`Un-decimate samples by 2` +|`data zerocrossings `|Y |`Count time between zero-crossings` +|`data iir `|Y |`apply IIR buttersworth filter on plotdata` + + +### emv + + { EMV ISO-14443 / ISO-7816... } + +|command |offline |description +|------- |------- |----------- +|`emv help `|Y |`This help` +|`emv exec `|Y |`Executes EMV contactless transaction.` +|`emv pse `|Y |`Execute PPSE. It selects 2PAY.SYS.DDF01 or 1PAY.SYS.DDF01 directory.` +|`emv search `|Y |`Try to select all applets from applets list and print installed applets.` +|`emv select `|Y |`Select applet.` +|`emv gpo `|Y |`Execute GetProcessingOptions.` +|`emv readrec `|Y |`Read files from card.` +|`emv genac `|Y |`Generate ApplicationCryptogram.` +|`emv challenge `|Y |`Generate challenge.` +|`emv intauth `|Y |`Internal authentication.` +|`emv scan `|Y |`Scan EMV card and save it contents to json file for emulator.` +|`emv test `|Y |`Crypto logic test.` +|`emv list `|Y |`List ISO7816 history` +|`emv roca `|Y |`Extract public keys and run ROCA test` + + +### hf + + { High frequency commands... } + +|command |offline |description +|------- |------- |----------- +|`hf help `|Y |`This help` +|`hf list `|Y |`List protocol data in trace buffer` +|`hf tune `|Y |`Continuously measure HF antenna tuning` +|`hf search `|Y |`Search for known HF tags` +|`hf sniff `|Y |` Generic HF Sniff` + + +### hf 14a + + { ISO14443A RFIDs... } + +|command |offline |description +|------- |------- |----------- +|`hf 14a help `|Y |`This help` +|`hf 14a list `|Y |`List ISO 14443-a history` +|`hf 14a info `|Y |`Tag information` +|`hf 14a reader `|Y |`Act like an ISO14443-a reader` +|`hf 14a cuids `|Y |` Collect n>0 ISO14443-a UIDs in one go` +|`hf 14a sim `|Y |` -- Simulate ISO 14443-a tag` +|`hf 14a sniff `|Y |`sniff ISO 14443-a traffic` +|`hf 14a apdu `|Y |`Send ISO 14443-4 APDU to tag` +|`hf 14a chaining `|Y |`Control ISO 14443-4 input chaining` +|`hf 14a raw `|Y |`Send raw hex data to tag` +|`hf 14a antifuzz `|Y |`Fuzzing the anticollision phase. Warning! Readers may react strange` + + +### hf 14b + + { ISO14443B RFIDs... } + +|command |offline |description +|------- |------- |----------- +|`hf 14b help `|Y |`This help` +|`hf 14b dump `|Y |`Read all memory pages of an ISO14443-B tag, save to file` +|`hf 14b info `|Y |`Tag information` +|`hf 14b list `|Y |`List ISO 14443B history` +|`hf 14b raw `|Y |`Send raw hex data to tag` +|`hf 14b reader `|Y |`Act as a 14443B reader to identify a tag` +|`hf 14b sim `|Y |`Fake ISO 14443B tag` +|`hf 14b sniff `|Y |`Eavesdrop ISO 14443B` +|`hf 14b sriread `|Y |`Read contents of a SRI512 | SRIX4K tag` +|`hf 14b sriwrite `|Y |`Write data to a SRI512 | SRIX4K tag` + + +### hf 15 + + { ISO15693 RFIDs... } + +|command |offline |description +|------- |------- |----------- +|`hf 15 help `|Y |`This help` +|`hf 15 demod `|Y |`Demodulate ISO15693 from tag` +|`hf 15 dump `|Y |`Read all memory pages of an ISO15693 tag, save to file` +|`hf 15 findafi `|Y |`Brute force AFI of an ISO15693 tag` +|`hf 15 writeafi `|Y |`Writes the AFI on an ISO15693 tag` +|`hf 15 writedsfid `|Y |`Writes the DSFID on an ISO15693 tag` +|`hf 15 info `|Y |`Tag information` +|`hf 15 list `|Y |`List ISO15693 history` +|`hf 15 raw `|Y |`Send raw hex data to tag` +|`hf 15 reader `|Y |`Act like an ISO15693 reader` +|`hf 15 record `|Y |`Record Samples (ISO15693)` +|`hf 15 restore `|Y |`Restore from file to all memory pages of an ISO15693 tag` +|`hf 15 sim `|Y |`Fake an ISO15693 tag` +|`hf 15 samples `|Y |`Acquire Samples as Reader (enables carrier, sends inquiry)` +|`hf 15 read `|Y |`Read a block` +|`hf 15 write `|Y |`Write a block` +|`hf 15 readmulti `|Y |`Reads multiple Blocks` +|`hf 15 csetuid `|Y |`Set UID for magic Chinese card` + + +### hf epa + + { German Identification Card... } + +|command |offline |description +|------- |------- |----------- +|`hf epa help `|Y |`This help` +|`hf epa cnonces `|Y |` Acquire n>0 encrypted PACE nonces of size m>0 with d sec pauses` +|`hf epa preplay `|Y |` Perform PACE protocol by replaying given APDUs` + + +### hf felica + + { ISO18092 / Felica RFIDs... } + +|command |offline |description +|------- |------- |----------- +|`hf felica ----------- General -----------`|Y |`` +|`hf felica help `|Y |`This help` +|`hf felica list `|Y |`List ISO 18092/FeliCa history` +|`hf felica reader `|Y |`Act like an ISO18092/FeliCa reader` +|`hf felica sniff `|Y |`Sniff ISO 18092/FeliCa traffic` +|`hf felica raw `|Y |`Send raw hex data to tag` +|`hf felica ----------- FeliCa Standard (support in progress) -----------`|Y |`` +|`hf felica rqservice `|Y |`verify the existence of Area and Service, and to acquire Key Version.` +|`hf felica rqresponse `|Y |`verify the existence of a card and its Mode.` +|`hf felica rdunencrypted`|Y |`read Block Data from authentication-not-required Service.` +|`hf felica wrunencrypted`|Y |`write Block Data to an authentication-not-required Service.` +|`hf felica scsvcode `|Y |`acquire Area Code and Service Code.` +|`hf felica rqsyscode `|Y |`acquire System Code registered to the card.` +|`hf felica auth1 `|Y |`authenticate a card. Start mutual authentication with Auth1` +|`hf felica auth2 `|Y |`allow a card to authenticate a Reader/Writer. Complete mutual authentication` +|`hf felica read `|Y |`read Block Data from authentication-required Service.` +|`hf felica rqspecver `|Y |`acquire the version of card OS.` +|`hf felica resetmode `|Y |`reset Mode to Mode 0.` +|`hf felica ----------- FeliCa Light -----------`|Y |`` +|`hf felica litesim `|Y |` - only reply to poll request` +|`hf felica litedump `|Y |`Wait for and try dumping FelicaLite` + + +### hf legic + + { LEGIC RFIDs... } + +|command |offline |description +|------- |------- |----------- +|`hf legic help `|Y |`This help` +|`hf legic reader `|Y |`LEGIC Prime Reader UID and tag info` +|`hf legic info `|Y |`Display deobfuscated and decoded LEGIC Prime tag data` +|`hf legic dump `|Y |`Dump LEGIC Prime tag to binary file` +|`hf legic restore `|Y |`Restore a dump file onto a LEGIC Prime tag` +|`hf legic rdmem `|Y |`Read bytes from a LEGIC Prime tag` +|`hf legic sim `|Y |`Start tag simulator` +|`hf legic write `|Y |`Write data to a LEGIC Prime tag` +|`hf legic crc `|Y |`Calculate Legic CRC over given bytes` +|`hf legic eload `|Y |`Load binary dump to emulator memory` +|`hf legic esave `|Y |`Save emulator memory to binary file` +|`hf legic list `|Y |`List LEGIC history` +|`hf legic wipe `|Y |`Wipe a LEGIC Prime tag` + + +### hf iclass + + { ICLASS RFIDs... } + +|command |offline |description +|------- |------- |----------- +|`hf iclass help `|Y |`This help` +|`hf iclass calcnewkey `|Y |`[options..] Calc diversified keys (blocks 3 & 4) to write new keys` +|`hf iclass chk `|Y |`[options..] Check keys` +|`hf iclass clone `|Y |`[options..] Restore a dump file onto a iClass tag` +|`hf iclass decrypt `|Y |`[options..] Decrypt given block data or tag dump file` +|`hf iclass dump `|Y |`[options..] Dump iClass tag to file` +|`hf iclass eload `|Y |`[f ] Load iClass dump file into emulator memory` +|`hf iclass encrypt `|Y |`[options..] Encrypt given block data` +|`hf iclass info `|Y |` Tag information` +|`hf iclass list `|Y |` List iClass history` +|`hf iclass loclass `|Y |`[options..] Use loclass to perform bruteforce reader attack` +|`hf iclass lookup `|Y |`[options..] Uses authentication trace to check for key in dictionary file` +|`hf iclass managekeys `|Y |`[options..] Manage keys to use with iClass` +|`hf iclass permutekey `|Y |` Permute function from 'heart of darkness' paper` +|`hf iclass rdbl `|Y |`[options..] Read iClass block` +|`hf iclass reader `|Y |` Act like an iClass reader` +|`hf iclass readtagfile `|Y |`[options..] Display content from tag dump file` +|`hf iclass replay `|Y |` Read iClass tag via replay attack` +|`hf iclass sim `|Y |`[options..] Simulate iClass tag` +|`hf iclass sniff `|Y |` Eavesdrop iClass communication` +|`hf iclass wrbl `|Y |`[options..] Write iClass block` + + +### hf mf + + { MIFARE RFIDs... } + +|command |offline |description +|------- |------- |----------- +|`hf mf help `|Y |`This help` +|`hf mf list `|Y |`List MIFARE history` +|`hf mf darkside `|Y |`Darkside attack` +|`hf mf nested `|Y |`Nested attack` +|`hf mf hardnested `|Y |`Nested attack for hardened MIFARE Classic cards` +|`hf mf autopwn `|Y |`Automatic key recovery tool for MIFARE Classic` +|`hf mf nack `|Y |`Test for MIFARE NACK bug` +|`hf mf chk `|Y |`Check keys` +|`hf mf fchk `|Y |`Check keys fast, targets all keys on card` +|`hf mf decrypt `|Y |`[nt] [ar_enc] [at_enc] [data] - to decrypt sniff or trace` +|`hf mf ----------- `|Y |`` +|`hf mf rdbl `|Y |`Read MIFARE classic block` +|`hf mf rdsc `|Y |`Read MIFARE classic sector` +|`hf mf dump `|Y |`Dump MIFARE classic tag to binary file` +|`hf mf restore `|Y |`Restore MIFARE classic binary file to BLANK tag` +|`hf mf wrbl `|Y |`Write MIFARE classic block` +|`hf mf setmod `|Y |`Set MIFARE Classic EV1 load modulation strength` +|`hf mf auth4 `|Y |`ISO14443-4 AES authentication` +|`hf mf ----------- `|Y |`` +|`hf mf sim `|Y |`Simulate MIFARE card` +|`hf mf eclr `|Y |`Clear simulator memory` +|`hf mf eget `|Y |`Get simulator memory block` +|`hf mf eset `|Y |`Set simulator memory block` +|`hf mf eload `|Y |`Load from file emul dump` +|`hf mf esave `|Y |`Save to file emul dump` +|`hf mf ecfill `|Y |`Fill simulator memory with help of keys from simulator` +|`hf mf ekeyprn `|Y |`Print keys from simulator memory` +|`hf mf ----------- `|Y |`` +|`hf mf csetuid `|Y |`Set UID (magic chinese card)` +|`hf mf cwipe `|Y |`Wipe card to default UID/Sectors/Keys` +|`hf mf csetblk `|Y |`Write block (magic chinese card)` +|`hf mf cgetblk `|Y |`Read block (magic chinese card)` +|`hf mf cgetsc `|Y |`Read sector (magic chinese card)` +|`hf mf cload `|Y |`Load dump (magic chinese card)` +|`hf mf csave `|Y |`Save dump from magic chinese card into file or emulator` +|`hf mf ----------- `|Y |`` +|`hf mf mad `|Y |`Checks and prints MAD` +|`hf mf ndef `|Y |`Prints NDEF records from card` +|`hf mf ice `|Y |`collect MIFARE Classic nonces to file` + + +### hf mfp + + { MIFARE Plus RFIDs... } + +|command |offline |description +|------- |------- |----------- +|`hf mfp help `|Y |`This help` +|`hf mfp info `|Y |`Info about Mifare Plus tag` +|`hf mfp wrp `|Y |`Write Perso command` +|`hf mfp initp `|Y |`Fills all the card's keys` +|`hf mfp commitp `|Y |`Move card to SL1 or SL3 mode` +|`hf mfp auth `|Y |`Authentication` +|`hf mfp rdbl `|Y |`Read blocks` +|`hf mfp rdsc `|Y |`Read sectors` +|`hf mfp wrbl `|Y |`Write blocks` +|`hf mfp chk `|Y |`Check keys` +|`hf mfp mad `|Y |`Checks and prints MAD` +|`hf mfp ndef `|Y |`Prints NDEF records from card` + + +### hf mfu + + { MIFARE Ultralight RFIDs... } + +|command |offline |description +|------- |------- |----------- +|`hf mfu help `|Y |`This help` +|`hf mfu info `|Y |`Tag information` +|`hf mfu dump `|Y |`Dump Ultralight / Ultralight-C / NTAG tag to binary file` +|`hf mfu restore `|Y |`Restore a dump onto a MFU MAGIC tag` +|`hf mfu eload `|Y |`load Ultralight .eml dump file into emulator memory` +|`hf mfu rdbl `|Y |`Read block` +|`hf mfu wrbl `|Y |`Write block` +|`hf mfu cauth `|Y |`Authentication - Ultralight C` +|`hf mfu setpwd `|Y |`Set 3des password - Ultralight-C` +|`hf mfu setuid `|Y |`Set UID - MAGIC tags only` +|`hf mfu sim `|Y |`Simulate Ultralight from emulator memory` +|`hf mfu gen `|Y |`Generate 3des mifare diversified keys` +|`hf mfu pwdgen `|Y |`Generate pwd from known algos` +|`hf mfu otptear `|Y |`Tear-off test on OTP bits` + + +### hf mfdes + + { MIFARE Desfire RFIDs... } + +|command |offline |description +|------- |------- |----------- +|`hf mfdes help `|Y |`This help` +|`hf mfdes info `|Y |`Tag information` +|`hf mfdes enum `|Y |`Tries enumerate all applications` +|`hf mfdes auth `|Y |`Tries a MIFARE DesFire Authentication` + + +### hf topaz + + { TOPAZ (NFC Type 1) RFIDs... } + +|command |offline |description +|------- |------- |----------- +|`hf topaz help `|Y |`This help` +|`hf topaz reader `|Y |`Act like a Topaz reader` +|`hf topaz sim `|Y |` -- Simulate Topaz tag` +|`hf topaz sniff `|Y |`Sniff Topaz reader-tag communication` +|`hf topaz raw `|Y |`Send raw hex data to tag` +|`hf topaz list `|Y |`List Topaz history` + + +### hf fido + + { FIDO and FIDO2 authenticators... } + +|command |offline |description +|------- |------- |----------- +|`hf fido help `|Y |`This help.` +|`hf fido info `|Y |`Info about FIDO tag.` +|`hf fido reg `|Y |`FIDO U2F Registration Message.` +|`hf fido auth `|Y |`FIDO U2F Authentication Message.` +|`hf fido make `|Y |`FIDO2 MakeCredential command.` +|`hf fido assert `|Y |`FIDO2 GetAssertion command.` + + +### hf thinfilm + + { Thinfilm RFIDs... } + +|command |offline |description +|------- |------- |----------- +|`hf thinfilm help `|Y |`This help` +|`hf thinfilm info `|Y |`Tag information` +|`hf thinfilm list `|Y |`List NFC Barcode / Thinfilm history - not correct` +|`hf thinfilm sim `|Y |`Fake Thinfilm tag` + + +### hw + + { Hardware commands... } + +|command |offline |description +|------- |------- |----------- +|`hw help `|Y |`This help` +|`hw connect `|Y |`connect Proxmark3 to serial port` +|`hw dbg `|Y |`Set Proxmark3 debug level` +|`hw detectreader `|Y |`['l'|'h'] -- Detect external reader field (option 'l' or 'h' to limit to LF or HF)` +|`hw fpgaoff `|Y |`Set FPGA off` +|`hw lcd `|N |` -- Send command/data to LCD` +|`hw lcdreset `|N |`Hardware reset LCD` +|`hw ping `|Y |`Test if the Proxmark3 is responsive` +|`hw readmem `|Y |`[address] -- Read memory at decimal address from flash` +|`hw reset `|Y |`Reset the Proxmark3` +|`hw setlfdivisor `|Y |`<19 - 255> -- Drive LF antenna at 12MHz/(divisor+1)` +|`hw setmux `|Y |`Set the ADC mux to a specific value` +|`hw standalone `|Y |`Jump to the standalone mode` +|`hw status `|Y |`Show runtime status information about the connected Proxmark3` +|`hw tia `|Y |`Trigger a Timing Interval Acquisition to re-adjust the RealTimeCounter divider` +|`hw tune `|Y |`Measure antenna tuning` +|`hw version `|Y |`Show version information about the connected Proxmark3` + + +### lf + + { Low frequency commands... } + +|command |offline |description +|------- |------- |----------- +|`lf help `|Y |`This help` +|`lf `|Y |`` +|`lf config `|Y |`Get/Set config for LF sampling, bit/sample, decimation, frequency` +|`lf cmdread `|Y |` <'0' period> <'1' period> ['h' 134] + -- Modulate LF reader field to send command before read (all periods in microseconds)` +|`lf read `|Y |`['s' silent] Read 125/134 kHz LF ID-only tag. Do 'lf read h' for help` +|`lf search `|Y |`[offline] ['u'] Read and Search for valid known tag (in offline mode it you can load first then search) + -- 'u' to search for unknown tags` +|`lf sim `|Y |`[GAP] -- Simulate LF tag from buffer with optional GAP (in microseconds)` +|`lf simask `|Y |`[clock] [invert <1|0>] [biphase/manchester/raw <'b'|'m'|'r'>] [msg separator 's'] [d ] + -- Simulate LF ASK tag from demodbuffer or input` +|`lf simfsk `|Y |`[c ] [i] [H ] [L ] [d ] + -- Simulate LF FSK tag from demodbuffer or input` +|`lf simpsk `|Y |`[1|2|3] [c ] [i] [r ] [d ] + -- Simulate LF PSK tag from demodbuffer or input` +|`lf simbidir `|Y |`Simulate LF tag (with bidirectional data transmission between reader and tag)` +|`lf sniff `|Y |`Sniff LF traffic between reader and tag` +|`lf tune `|Y |`Continuously measure LF antenna tuning` + + +### lf awid + + { AWID RFIDs... } + +|command |offline |description +|------- |------- |----------- +|`lf awid help `|Y |`this help` +|`lf awid demod `|Y |`demodulate an AWID FSK tag from the GraphBuffer` +|`lf awid read `|Y |`attempt to read and extract tag data` +|`lf awid clone `|Y |`clone AWID tag to T55x7 (or to q5/T5555)` +|`lf awid sim `|Y |`simulate AWID tag` +|`lf awid brute `|Y |`Bruteforce card number against reader` +|`lf awid watch `|Y |`continuously watch for cards. Reader mode` + + +### lf cotag + + { COTAG CHIPs... } + +|command |offline |description +|------- |------- |----------- +|`lf cotag help `|Y |`This help` +|`lf cotag demod `|Y |`Tries to decode a COTAG signal` +|`lf cotag read `|Y |`Attempt to read and extract tag data` + + +### lf em + + { EM4X CHIPs & RFIDs... } + +|command |offline |description +|------- |------- |----------- +|`lf em help `|Y |`This help` +|`lf em 410x_demod `|Y |`demodulate a EM410x tag from the GraphBuffer` +|`lf em 410x_read `|Y |`attempt to read and extract tag data` +|`lf em 410x_sim `|Y |`simulate EM410x tag` +|`lf em 410x_brute `|Y |`reader bruteforce attack by simulating EM410x tags` +|`lf em 410x_watch `|Y |`watches for EM410x 125/134 kHz tags (option 'h' for 134)` +|`lf em 410x_spoof `|Y |`watches for EM410x 125/134 kHz tags, and replays them. (option 'h' for 134)` +|`lf em 410x_write `|Y |`write EM410x UID to T5555(Q5) or T55x7 tag` +|`lf em 4x05_demod `|Y |`demodulate a EM4x05/EM4x69 tag from the GraphBuffer` +|`lf em 4x05_dump `|Y |`dump EM4x05/EM4x69 tag` +|`lf em 4x05_wipe `|Y |`wipe EM4x05/EM4x69 tag` +|`lf em 4x05_info `|Y |`tag information EM4x05/EM4x69` +|`lf em 4x05_read `|Y |`read word data from EM4x05/EM4x69` +|`lf em 4x05_write `|Y |`write word data to EM4x05/EM4x69` +|`lf em 4x50_demod `|Y |`demodulate a EM4x50 tag from the GraphBuffer` +|`lf em 4x50_dump `|Y |`dump EM4x50 tag` +|`lf em 4x50_read `|Y |`read word data from EM4x50` +|`lf em 4x50_write `|Y |`write word data to EM4x50` + + +### lf fdx + + { FDX-B RFIDs... } + +|command |offline |description +|------- |------- |----------- +|`lf fdx help `|Y |`this help` +|`lf fdx demod `|Y |`demodulate a FDX-B ISO11784/85 tag from the GraphBuffer` +|`lf fdx read `|Y |`attempt to read and extract tag data` +|`lf fdx clone `|Y |`clone animal ID tag to T55x7 (or to q5/T5555)` +|`lf fdx sim `|Y |`simulate Animal ID tag` + + +### lf gallagher + + { GALLAGHER RFIDs... } + +|command |offline |description +|------- |------- |----------- +|`lf gallagher help `|Y |`This help` +|`lf gallagher demod `|Y |`Demodulate an GALLAGHER tag from the GraphBuffer` +|`lf gallagher read `|Y |`Attempt to read and extract tag data from the antenna` +|`lf gallagher clone `|Y |`clone GALLAGHER tag to T55x7` +|`lf gallagher sim `|Y |`simulate GALLAGHER tag` + + +### lf gproxii + + { Guardall Prox II RFIDs... } + +|command |offline |description +|------- |------- |----------- +|`lf gproxii help `|Y |`this help` +|`lf gproxii demod `|Y |`demodulate a G Prox II tag from the GraphBuffer` +|`lf gproxii read `|Y |`attempt to read and extract tag data from the antenna` +|`lf gproxii clone `|Y |`clone Guardall tag to T55x7` +|`lf gproxii sim `|Y |`simulate Guardall tag` + + +### lf hid + + { HID RFIDs... } + +|command |offline |description +|------- |------- |----------- +|`lf hid help `|Y |`this help` +|`lf hid demod `|Y |`demodulate HID Prox tag from the GraphBuffer` +|`lf hid read `|Y |`attempt to read and extract tag data` +|`lf hid clone `|Y |`clone HID tag to T55x7` +|`lf hid sim `|Y |`simulate HID tag` +|`lf hid brute `|Y |`bruteforce card number against reader` +|`lf hid watch `|Y |`continuously watch for cards. Reader mode` + + +### lf hitag + + { Hitag CHIPs... } + +|command |offline |description +|------- |------- |----------- +|`lf hitag help `|Y |`This help` +|`lf hitag list `|Y |`List Hitag trace history` +|`lf hitag info `|Y |`Tag information` +|`lf hitag reader `|Y |`Act like a Hitag Reader` +|`lf hitag sim `|Y |`Simulate Hitag transponder` +|`lf hitag sniff `|Y |`Eavesdrop Hitag communication` +|`lf hitag writer `|Y |`Act like a Hitag Writer` +|`lf hitag cc `|Y |`Test all challenges` + + +### lf indala + + { Indala RFIDs... } + +|command |offline |description +|------- |------- |----------- +|`lf indala help `|Y |`this help` +|`lf indala demod `|Y |`demodulate an indala tag (PSK1) from GraphBuffer` +|`lf indala altdemod `|Y |`alternative method to Demodulate samples for Indala 64 bit UID (option '224' for 224 bit)` +|`lf indala read `|Y |`read an Indala Prox tag from the antenna` +|`lf indala clone `|Y |`clone Indala tag to T55x7` +|`lf indala sim `|Y |`simulate Indala tag` + + +### lf io + + { ioProx RFIDs... } + +|command |offline |description +|------- |------- |----------- +|`lf io help `|Y |`this help` +|`lf io demod `|Y |`demodulate an IOProx tag from the GraphBuffer` +|`lf io read `|Y |`attempt to read and extract tag data` +|`lf io clone `|Y |`clone IOProx tag to T55x7 (or to q5/T5555)` +|`lf io sim `|Y |`simulate IOProx tag` +|`lf io watch `|Y |`continuously watch for cards. Reader mode` + + +### lf jablotron + + { Jablotron RFIDs... } + +|command |offline |description +|------- |------- |----------- +|`lf jablotron help `|Y |`This help` +|`lf jablotron slurdge `|Y |`Demod slurdge ..` +|`lf jablotron demod `|Y |`Demodulate an Jablotron tag from the GraphBuffer` +|`lf jablotron read `|Y |`Attempt to read and extract tag data from the antenna` +|`lf jablotron clone `|Y |`clone jablotron tag to T55x7 (or to q5/T5555)` +|`lf jablotron sim `|Y |`simulate jablotron tag` + + +### lf keri + + { KERI RFIDs... } + +|command |offline |description +|------- |------- |----------- +|`lf keri help `|Y |`This help` +|`lf keri demod `|Y |`Demodulate an KERI tag from the GraphBuffer` +|`lf keri read `|Y |`Attempt to read and extract tag data from the antenna` +|`lf keri clone `|Y |`clone KERI tag to T55x7 (or to q5/T5555)` +|`lf keri sim `|Y |`simulate KERI tag` + + +### lf nedap + + { Nedap RFIDs... } + +|command |offline |description +|------- |------- |----------- +|`lf nedap help `|Y |`This help` +|`lf nedap demod `|Y |`Demodulate Nedap tag from the GraphBuffer` +|`lf nedap generate `|Y |`Generate Nedap bitstream in DemodBuffer` +|`lf nedap read `|Y |`Attempt to read and extract tag data from the antenna` +|`lf nedap clone `|Y |`Clone Nedap tag to T55x7` +|`lf nedap sim `|Y |`Simulate Nedap tag` + + +### lf nexwatch + + { NexWatch RFIDs... } + +|command |offline |description +|------- |------- |----------- +|`lf nexwatch help `|Y |`This help` +|`lf nexwatch demod `|Y |`Demodulate a NexWatch tag (nexkey, quadrakey) from the GraphBuffer` +|`lf nexwatch read `|Y |`Attempt to Read and Extract tag data from the antenna` +|`lf nexwatch clone `|Y |`clone NexWatch tag to T55x7` +|`lf nexwatch sim `|Y |`simulate NexWatch tag` + + +### lf noralsy + + { Noralsy RFIDs... } + +|command |offline |description +|------- |------- |----------- +|`lf noralsy help `|Y |`This help` +|`lf noralsy demod `|Y |`Demodulate an Noralsy tag from the GraphBuffer` +|`lf noralsy read `|Y |`Attempt to read and extract tag data from the antenna` +|`lf noralsy clone `|Y |`clone Noralsy tag to T55x7 (or to q5/T5555)` +|`lf noralsy sim `|Y |`simulate Noralsy tag` + + +### lf motorola + + { Motorola RFIDs... } + +|command |offline |description +|------- |------- |----------- +|`lf motorola help `|Y |`This help` +|`lf motorola demod `|Y |`Demodulate an MOTOROLA tag from the GraphBuffer` +|`lf motorola read `|Y |`Attempt to read and extract tag data from the antenna` +|`lf motorola clone `|Y |`clone MOTOROLA tag to T55x7` +|`lf motorola sim `|Y |`simulate MOTOROLA tag` + + +### lf pac + + { PAC/Stanley RFIDs... } + +|command |offline |description +|------- |------- |----------- +|`lf pac help `|Y |`This help` +|`lf pac demod `|Y |`Demodulate a PAC tag from the GraphBuffer` +|`lf pac read `|Y |`Attempt to read and extract tag data from the antenna` +|`lf pac clone `|Y |`clone PAC tag to T55x7` +|`lf pac sim `|Y |`simulate PAC tag` + + +### lf paradox + + { Paradox RFIDs... } + +|command |offline |description +|------- |------- |----------- +|`lf paradox help `|Y |`This help` +|`lf paradox demod `|Y |`Demodulate a Paradox FSK tag from the GraphBuffer` +|`lf paradox read `|Y |`Attempt to read and Extract tag data from the antenna` +|`lf paradox clone `|Y |`clone paradox tag to T55x7` +|`lf paradox sim `|Y |`simulate paradox tag` + + +### lf pcf7931 + + { PCF7931 CHIPs... } + +|command |offline |description +|------- |------- |----------- +|`lf pcf7931 help `|Y |`This help` +|`lf pcf7931 read `|Y |`Read content of a PCF7931 transponder` +|`lf pcf7931 write `|Y |`Write data on a PCF7931 transponder.` +|`lf pcf7931 config `|Y |`Configure the password, the tags initialization delay and time offsets (optional)` + + +### lf presco + + { Presco RFIDs... } + +|command |offline |description +|------- |------- |----------- +|`lf presco help `|Y |`This help` +|`lf presco read `|Y |`Attempt to read and Extract tag data` +|`lf presco clone `|Y |`clone presco tag to T55x7 (or to q5/T5555)` +|`lf presco sim `|Y |`simulate presco tag` + + +### lf pyramid + + { Farpointe/Pyramid RFIDs... } + +|command |offline |description +|------- |------- |----------- +|`lf pyramid help `|Y |`this help` +|`lf pyramid demod `|Y |`demodulate a Pyramid FSK tag from the GraphBuffer` +|`lf pyramid read `|Y |`attempt to read and extract tag data` +|`lf pyramid clone `|Y |`clone pyramid tag to T55x7 (or to q5/T5555)` +|`lf pyramid sim `|Y |`simulate pyramid tag` + + +### lf securakey + + { Securakey RFIDs... } + +|command |offline |description +|------- |------- |----------- +|`lf securakey help `|Y |`This help` +|`lf securakey demod `|Y |`Demodulate an Securakey tag from the GraphBuffer` +|`lf securakey read `|Y |`Attempt to read and extract tag data from the antenna` +|`lf securakey clone `|Y |`clone Securakey tag to T55x7` +|`lf securakey sim `|Y |`simulate Securakey tag` + + +### lf ti + + { TI CHIPs... } + +|command |offline |description +|------- |------- |----------- +|`lf ti help `|Y |`This help` +|`lf ti demod `|Y |`Demodulate raw bits for TI-type LF tag from the GraphBuffer` +|`lf ti read `|Y |`Read and decode a TI 134 kHz tag` +|`lf ti write `|Y |`Write new data to a r/w TI 134 kHz tag` + + +### lf t55xx + + { T55xx CHIPs... } + +|command |offline |description +|------- |------- |----------- +|`lf t55xx help `|Y |`This help` +|`lf t55xx bruteforce `|Y |` Simple bruteforce attack to find password` +|`lf t55xx config `|Y |`Set/Get T55XX configuration (modulation, inverted, offset, rate)` +|`lf t55xx chk `|Y |`Check passwords from dictionary/flash` +|`lf t55xx clonehelp `|Y |`Shows the available clone commands` +|`lf t55xx dangerraw `|Y |`Sends raw bitstream. Dangerous, do not use!! b t ` +|`lf t55xx detect `|Y |`[1] Try detecting the tag modulation from reading the configuration block.` +|`lf t55xx deviceconfig `|Y |`Set/Get T55XX device configuration (startgap, writegap, write0, write1, readgap` +|`lf t55xx dump `|Y |`[password] [o] Dump T55xx card Page 0 block 0-7. Optional [password], [override]` +|`lf t55xx restore `|Y |`f [p ] Restore T55xx card Page 0 / Page 1 blocks` +|`lf t55xx info `|Y |`[1] Show T55x7 configuration data (page 0/ blk 0)` +|`lf t55xx p1detect `|Y |`[1] Try detecting if this is a t55xx tag by reading page 1` +|`lf t55xx protect `|Y |`Password protect tag` +|`lf t55xx read `|Y |`b p [password] [o] [1] -- Read T55xx block data. Optional [p password], [override], [page1]` +|`lf t55xx resetread `|Y |`Send Reset Cmd then lf read the stream to attempt to identify the start of it (needs a demod and/or plot after)` +|`lf t55xx recoverpw `|Y |`[password] Try to recover from bad password write from a cloner. Only use on PW protected chips!` +|`lf t55xx special `|Y |`Show block changes with 64 different offsets` +|`lf t55xx trace `|Y |`[1] Show T55x7 traceability data (page 1/ blk 0-1)` +|`lf t55xx wakeup `|Y |`Send AOR wakeup command` +|`lf t55xx wipe `|Y |`[q] Wipe a T55xx tag and set defaults (will destroy any data on tag)` +|`lf t55xx write `|Y |`b d p [password] [1] -- Write T55xx block data. Optional [p password], [page1]` + + +### lf viking + + { Viking RFIDs... } + +|command |offline |description +|------- |------- |----------- +|`lf viking help `|Y |`This help` +|`lf viking demod `|Y |`Demodulate a Viking tag from the GraphBuffer` +|`lf viking read `|Y |`Attempt to read and Extract tag data from the antenna` +|`lf viking clone `|Y |`clone Viking tag to T55x7 (or to q5/T5555)` +|`lf viking sim `|Y |`simulate Viking tag` + + +### lf visa2000 + + { Visa2000 RFIDs... } + +|command |offline |description +|------- |------- |----------- +|`lf visa2000 help `|Y |`This help` +|`lf visa2000 demod `|Y |`demodulate an VISA2000 tag from the GraphBuffer` +|`lf visa2000 read `|Y |`attempt to read and extract tag data from the antenna` +|`lf visa2000 clone `|Y |`clone Visa2000 tag to T55x7 (or to q5/T5555)` +|`lf visa2000 sim `|Y |`simulate Visa2000 tag` + + +### mem + + { Flash Memory manipulation... } + +|command |offline |description +|------- |------- |----------- +|`mem help `|Y |`This help` +|`mem spiffs `|Y |`High level SPI FileSystem Flash manipulation [rdv40]` +|`mem spibaud `|Y |`Set Flash memory Spi baudrate [rdv40]` +|`mem info `|Y |`Flash memory information [rdv40]` +|`mem load `|Y |`Load data into flash memory [rdv40]` +|`mem dump `|Y |`Dump data from flash memory [rdv40]` +|`mem wipe `|Y |`Wipe data from flash memory [rdv40]` + + +### reveng + + { CRC calculations from RevEng software } + +### sc + + { Smart card ISO-7816 commands... } + +|command |offline |description +|------- |------- |----------- +|`sc help `|Y |`This help` +|`sc list `|Y |`List ISO 7816 history` +|`sc info `|Y |`Tag information` +|`sc reader `|Y |`Act like an IS07816 reader` +|`sc raw `|Y |`Send raw hex data to tag` +|`sc upgrade `|Y |`Upgrade sim module firmware` +|`sc setclock `|Y |`Set clock speed` +|`sc brute `|Y |`Bruteforce SFI` + + +### script + + { Scripting commands } + +|command |offline |description +|------- |------- |----------- +|`script help `|Y |`This help` +|`script list `|Y |`List available scripts` +|`script run `|Y |` -- Execute a script` + + +### trace + + { Trace manipulation... } + +|command |offline |description +|------- |------- |----------- +|`trace help `|Y |`This help` +|`trace list `|Y |`List protocol data in trace buffer` +|`trace load `|Y |`Load trace from file` +|`trace save `|Y |`Save trace buffer to file` + + +### usart + + { USART commands... } + +|command |offline |description +|------- |------- |----------- +|`usart help `|Y |`This help` +|`usart btpin `|N |`Change BT add-on PIN` +|`usart btfactory `|N |`Reset BT add-on to factory settings` +|`usart tx `|N |`Send string over USART` +|`usart rx `|N |`Receive string over USART` +|`usart txrx `|N |`Send string over USART and wait for response` +|`usart txhex `|N |`Send bytes over USART` +|`usart rxhex `|N |`Receive bytes over USART` +|`usart config `|N |`Configure USART` + + +### wiegand + + { Wiegand format manipulation... } + +|command |offline |description +|------- |------- |----------- +|`wiegand help `|Y |`This help` +|`wiegand list `|Y |`List available wiegand formats` +|`wiegand encode `|Y |`Convert ` +|`wiegand decode `|Y |`Convert raw hex to wiegand format` + + From ea25474731651e049f5c05bab5f4a51f43a9ad0a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 4 Jan 2020 12:56:31 +0100 Subject: [PATCH 1377/1854] text --- CHANGELOG.md | 53 ++++++++++++++++++++++++++-------------------------- README.md | 2 +- 2 files changed, 28 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 81f5d86d6..6abb5e47b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,23 +3,24 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] - - Added `c ` option to `lf pac clone` to allow cloning PAC/Stanley tag from card ID (@danshuk) - - Added decoded PAC/Stanley card ID to `lf pac read` (@danshuk) - - Chg mifare classic keytable output refactored and uses colors (@iceman1001) + - Add `commands.md` - document with all proxmark client commands. Generated with XX_internal_command_dump_markdown_XX. (@iceman1001) + - Change `lf pac clone` - new option `c ` to allow cloning PAC/Stanley tag from card ID (@danshuk) + - Change `lf pac read` - decoded PAC/Stanley card ID (@danshuk) + - Change mifare classic keytable output refactored and uses colors (@iceman1001) - Fix `hf mf nested` - now writes the correct blockno (@iceman1001) - - Chg `lf t55xx dump` - now supports saving to JSON (@iceman1001) - - Chg `hf mf chk | fchk` faster authentication by lower timeout limit. (@pwpiwi) - - Chg `hf mf hardnested` - now detects "static / fixed" nonce tags and exits (@iceman1001) - - Chg `hf mf csave` - now uses UID in filename (@iceman1001) + - Change `lf t55xx dump` - now supports saving to JSON (@iceman1001) + - Change `hf mf chk | fchk` faster authentication by lower timeout limit. (@pwpiwi) + - Change `hf mf hardnested` - now detects "static / fixed" nonce tags and exits (@iceman1001) + - Change `hf mf csave` - now uses UID in filename (@iceman1001) - Fix `hf mf chk` - read block B logical error. #489 (@iceman1001) - Add `hf mf ekeyprn d` - new parameter to save keys to file (@iceman1001) - Add `mfu_magic.lua` - script to interact with your magic NTAG tag. (@iceman1001) - Add `hf_bruteforce.lua` - script bruteforces uid for 14a using hf 14a sim (@keld) - Add `tools\pm3_cs8.pl` - convert .pm3 files to wave format (@samyk) - Add `tools\pm3_amii_bin2eml.pl` - amiibo convering script (@samyk) - - Chg `hf 14a info` - now detects "static / fixed" nonce tags (@iceman1001) - - Chg `data save f w` - params reworked. (@iceman1001) - - Chg `hf search` - now should detect LTO-CM tags (@iceman1001) + - Change `hf 14a info` - now detects "static / fixed" nonce tags (@iceman1001) + - Change `data save f w` - params reworked. (@iceman1001) + - Change `hf search` - now should detect LTO-CM tags (@iceman1001) - Added `hf lto info` - skeleton support for LTO Cartridge memory (@iceman1001) - Added saving as wave format (@anon) - Added ISO15_WRITE annotation (@pwipiw) @@ -38,8 +39,8 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Added polling for felica standard (@7homasSutter) - Added `lf t55xx dump save` and `lf t55xx restore` for .bin and .eml files (@mwalker33) - Added `lf t55xx detected` to try without password first (@mwalker33) - - Chg `lf indala read` - added indala 26bit decoding (@martinbeier) - - Chg `lf t55xx detect` to try without password first (@mwalker33) + - Change `lf indala read` - added indala 26bit decoding (@martinbeier) + - Change `lf t55xx detect` to try without password first (@mwalker33) - Display high bit for detected Kastle HIDs to allow `lf hid clone [id]` to work properly (@swg0101) - Add option `-n` to scripts pm3* (@doegox) - Add `wiegand list/encode/decode` - wiegand format manipulation. Adapted to fit here. (@grauerfuchs) @@ -51,28 +52,28 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Fix T55xx config getting displayed when using password when no password needed on read. (@mwalker33) - Added T55x7 downlink mode auto usage via mode detected (lf t55 detect) (@mwalker33) - Add `lf t55xx protect` - sets password and enables password protection on t55x7 tag (@iceman1001) - - Chg `lf t55xx wipe` - now accepts user provided configuration block (@iceman1001) + - Change `lf t55xx wipe` - now accepts user provided configuration block (@iceman1001) - Added T55x7 downlink mode support r 0 Default, 1 Long Leading 0, 2 Leading 0, 3 1 of 4 and 4 (in some commands) try all. (@mwalker33) - - Chg proxmark3-flasher is now merged into proxmark3 client. Add pm3-flash (@doegox) - - Chg `hf iclass clone\dump\rdbl\wrbl` - now uses NG (@iceman1001) + - Change proxmark3-flasher is now merged into proxmark3 client. Add pm3-flash (@doegox) + - Change `hf iclass clone\dump\rdbl\wrbl` - now uses NG (@iceman1001) - Fix `hf iclass clone` - last block always fails (@iceman1001) - - Chg `hf iclass clone` - retries ten times, less output (honor verbose) (@iceman1001) - - Chg `hf iclass dump` - retries ten times, less output (honor verbose) (@iceman1001) + - Change `hf iclass clone` - retries ten times, less output (honor verbose) (@iceman1001) + - Change `hf iclass dump` - retries ten times, less output (honor verbose) (@iceman1001) - Rename `hf iclass writeblk` -> `hf iclass wrbl` to match hf mf wrbl (@iceman1001) - Rename `hf iclass readblk` -> `hf iclass rdbl` to match hf mf rdbl (@iceman1001) - Add cmdscript example and show usage with shebang (@doegox) - Add instructions for Fedora (@doegox) - - Chg reduce the list of requirements to the minimum and move to QT5 (@doegox) + - Change reduce the list of requirements to the minimum and move to QT5 (@doegox) - Add `make install` and reorganize/rename stuffs accordingly (@doegox) - Add searchFile for several types of files (@doegox / @iceman1001) - - Chg posix sh version of mkversion (@doegox) - - Chg remove entirely ncurses, not needed nowadays (@doegox) - - Chg remove deprecated termcap, use ncurses instead (@ZeroChaos-) - - Chg `hf iclass encrypt` - now takes transport key as param. (@iceman1001) - - Chg `hf iclass decrypt` - now takes transport key as param. (@iceman1001) - - Chg `hf mf fchk m` - now secretly dumps card to emul, if all keys are found (@iceman1001) - - Chg history and logfile are now saved into $HOME/.proxmark3/ (@doegox) - - Chg optimization of iclass mac calculations on deviceside (@pwpiwi) + - Change posix sh version of mkversion (@doegox) + - Change remove entirely ncurses, not needed nowadays (@doegox) + - Change remove deprecated termcap, use ncurses instead (@ZeroChaos-) + - Change `hf iclass encrypt` - now takes transport key as param. (@iceman1001) + - Change `hf iclass decrypt` - now takes transport key as param. (@iceman1001) + - Change `hf mf fchk m` - now secretly dumps card to emul, if all keys are found (@iceman1001) + - Change history and logfile are now saved into $HOME/.proxmark3/ (@doegox) + - Change optimization of iclass mac calculations on deviceside (@pwpiwi) - Add `hf mf autopwn` - Autopwn function for Mifare Classic, extract all keys and dump card memory (@matthiaskonrath) - Add Lua paths: look for scripts also in ~/.proxmark/lua{scripts,libs} and /usr/local/share/proxmark3/lua{scripts,libs} (@doegox) - Change Lua directory scripts/ to luascript/ (@doegox) diff --git a/README.md b/README.md index 2c9a129e0..96a8d2693 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ |[Notes on external flash](/doc/ext_flash_notes.md)||[EMV](/doc/emv_notes.md)| |[Notes on Termux / Android](/doc/termux_notes.md)||[Troubleshooting](/doc/md/Installation_Instructions/Troubleshooting.md)| |[Notes on wireshark / tracedata](/doc/trace_wireshark_notes.md)||[JTAG](/doc/jtag_notes.md)| -|[Notes on loclass](/doc/loclass_notes.md)||| +|[Notes on loclass](/doc/loclass_notes.md)||[Complete client command set](/doc/commands.md)| |[Notes on paths](/doc/path_notes.md)||| |[Developing standalone mode](/armsrc/Standalone/readme.md)|[Wiki about standalone mode](https://github.com/RfidResearchGroup/proxmark3/wiki/Standalone-mode) || |[Donations](#Donations)||| From b98fdedb1867ce42371816b1b3ba54e46f505679 Mon Sep 17 00:00:00 2001 From: Iceman Date: Sat, 4 Jan 2020 12:58:19 +0100 Subject: [PATCH 1378/1854] Update commands.md --- doc/commands.md | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/doc/commands.md b/doc/commands.md index 50cd0e805..c2fd651f8 100644 --- a/doc/commands.md +++ b/doc/commands.md @@ -1,9 +1,4 @@ -[=] Session log /home/iceman/.proxmark3/log_20200104.txt -[+] execute command from commandline: XX_internal_command_dump_markdown_XX - -[=] Using UART port /dev/ttyS7 -[=] Communicating with PM3 over USB-CDC -pm3 --> XX_internal_command_dump_markdown_XX + |command |offline |description |------- |------- |----------- |`help `|Y |`This help. Use ' help' for details of a particular command.` From d938732a39cea90525b75352066264cf0f9de29a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 4 Jan 2020 13:07:45 +0100 Subject: [PATCH 1379/1854] textual --- doc/commands.md | 9 --------- 1 file changed, 9 deletions(-) diff --git a/doc/commands.md b/doc/commands.md index c2fd651f8..b4980fd41 100644 --- a/doc/commands.md +++ b/doc/commands.md @@ -3,7 +3,6 @@ |------- |------- |----------- |`help `|Y |`This help. Use ' help' for details of a particular command.` |`auto `|Y |`Automated detection process for unknown tags` -|` `|Y |`` |`msleep `|Y |`Add a pause in milliseconds` |`rem `|Y |`Add a text line in log file` |`quit `|Y |`` @@ -188,13 +187,11 @@ |command |offline |description |------- |------- |----------- -|`hf felica ----------- General -----------`|Y |`` |`hf felica help `|Y |`This help` |`hf felica list `|Y |`List ISO 18092/FeliCa history` |`hf felica reader `|Y |`Act like an ISO18092/FeliCa reader` |`hf felica sniff `|Y |`Sniff ISO 18092/FeliCa traffic` |`hf felica raw `|Y |`Send raw hex data to tag` -|`hf felica ----------- FeliCa Standard (support in progress) -----------`|Y |`` |`hf felica rqservice `|Y |`verify the existence of Area and Service, and to acquire Key Version.` |`hf felica rqresponse `|Y |`verify the existence of a card and its Mode.` |`hf felica rdunencrypted`|Y |`read Block Data from authentication-not-required Service.` @@ -206,7 +203,6 @@ |`hf felica read `|Y |`read Block Data from authentication-required Service.` |`hf felica rqspecver `|Y |`acquire the version of card OS.` |`hf felica resetmode `|Y |`reset Mode to Mode 0.` -|`hf felica ----------- FeliCa Light -----------`|Y |`` |`hf felica litesim `|Y |` - only reply to poll request` |`hf felica litedump `|Y |`Wait for and try dumping FelicaLite` @@ -277,7 +273,6 @@ |`hf mf chk `|Y |`Check keys` |`hf mf fchk `|Y |`Check keys fast, targets all keys on card` |`hf mf decrypt `|Y |`[nt] [ar_enc] [at_enc] [data] - to decrypt sniff or trace` -|`hf mf ----------- `|Y |`` |`hf mf rdbl `|Y |`Read MIFARE classic block` |`hf mf rdsc `|Y |`Read MIFARE classic sector` |`hf mf dump `|Y |`Dump MIFARE classic tag to binary file` @@ -285,7 +280,6 @@ |`hf mf wrbl `|Y |`Write MIFARE classic block` |`hf mf setmod `|Y |`Set MIFARE Classic EV1 load modulation strength` |`hf mf auth4 `|Y |`ISO14443-4 AES authentication` -|`hf mf ----------- `|Y |`` |`hf mf sim `|Y |`Simulate MIFARE card` |`hf mf eclr `|Y |`Clear simulator memory` |`hf mf eget `|Y |`Get simulator memory block` @@ -294,7 +288,6 @@ |`hf mf esave `|Y |`Save to file emul dump` |`hf mf ecfill `|Y |`Fill simulator memory with help of keys from simulator` |`hf mf ekeyprn `|Y |`Print keys from simulator memory` -|`hf mf ----------- `|Y |`` |`hf mf csetuid `|Y |`Set UID (magic chinese card)` |`hf mf cwipe `|Y |`Wipe card to default UID/Sectors/Keys` |`hf mf csetblk `|Y |`Write block (magic chinese card)` @@ -302,7 +295,6 @@ |`hf mf cgetsc `|Y |`Read sector (magic chinese card)` |`hf mf cload `|Y |`Load dump (magic chinese card)` |`hf mf csave `|Y |`Save dump from magic chinese card into file or emulator` -|`hf mf ----------- `|Y |`` |`hf mf mad `|Y |`Checks and prints MAD` |`hf mf ndef `|Y |`Prints NDEF records from card` |`hf mf ice `|Y |`collect MIFARE Classic nonces to file` @@ -434,7 +426,6 @@ |command |offline |description |------- |------- |----------- |`lf help `|Y |`This help` -|`lf `|Y |`` |`lf config `|Y |`Get/Set config for LF sampling, bit/sample, decimation, frequency` |`lf cmdread `|Y |` <'0' period> <'1' period> ['h' 134] -- Modulate LF reader field to send command before read (all periods in microseconds)` From da6360d123214afa6c8593b5fa84c4f9e9e015e8 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 4 Jan 2020 15:53:09 +0100 Subject: [PATCH 1380/1854] coverty 263987 --- client/cmdhffelica.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index 734962651..07a1ac18b 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -465,11 +465,11 @@ static void print_rd_noEncrpytion_response(felica_read_without_encryption_respon char *temp = sprint_hex(rd_noCry_resp->block_data, sizeof(rd_noCry_resp->block_data)); char bl_data[256]; - strcpy(bl_data, temp); + strncpy(bl_data, temp, sizeof(bl_data) - 1); char bl_element_number[4]; temp = sprint_hex(rd_noCry_resp->block_element_number, sizeof(rd_noCry_resp->block_element_number)); - strcpy(bl_element_number, temp); + strncpy(bl_element_number, temp, sizeof(bl_element_number) - 1); PrintAndLogEx(INFO, "\t%s\t| %s ", bl_element_number, bl_data); } else { From 110446799c8f72dc13d4d4605a3eadd50405ff40 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 4 Jan 2020 15:55:50 +0100 Subject: [PATCH 1381/1854] coverty 263981 --- armsrc/felica.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/felica.c b/armsrc/felica.c index 4b1db7f61..91b58d97f 100644 --- a/armsrc/felica.c +++ b/armsrc/felica.c @@ -588,7 +588,7 @@ void felica_sniff(uint32_t samplesToSkip, uint32_t triggersToSkip) { if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { uint8_t dist = (uint8_t)(AT91C_BASE_SSC->SSC_RHR); Process18092Byte(dist); - if ((MAX(dist & 0xff, dist >> 8) >= 178) && (++trigger_cnt > triggersToSkip)) { + if ((dist >= 178) && (++trigger_cnt > triggersToSkip)) { Dbprintf("triggersToSkip kicked %d", dist); break; } From d39b113b4075ee8afe78d228a8c130cedc071626 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 4 Jan 2020 16:07:57 +0100 Subject: [PATCH 1382/1854] cppcheck --- client/fileutils.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/client/fileutils.c b/client/fileutils.c index 2710998b5..17b3da4bf 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -618,6 +618,7 @@ int loadFile_safe(const char *preferredName, const char *suffix, void **pdata, s int loadFileEML(const char *preferredName, void *data, size_t *datalen) { if (data == NULL) return PM3_EINVARG; + char *fileName = filenamemcopy(preferredName, ".eml"); if (fileName == NULL) return PM3_EMALLOC; @@ -636,6 +637,8 @@ int loadFileEML(const char *preferredName, void *data, size_t *datalen) { memset(line, 0, sizeof(line)); uint8_t buf[64] = {0x00}; + uint8_t *udata = (uint8_t*)data; + while (!feof(f)) { memset(line, 0, sizeof(line)); @@ -654,7 +657,7 @@ int loadFileEML(const char *preferredName, void *data, size_t *datalen) { int res = param_gethex_to_eol(line, 0, buf, sizeof(buf), &hexlen); if (res == 0 || res == 1) { - memcpy(data + counter, buf, hexlen); + memcpy(udata + counter, buf, hexlen); counter += hexlen; } } @@ -832,10 +835,11 @@ int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, u int loadFileDICTIONARYEx(const char *preferredName, void *data, size_t maxdatalen, size_t *datalen, uint8_t keylen, uint16_t *keycnt, size_t startFilePosition, size_t *endFilePosition, bool verbose) { + + if (data == NULL) return PM3_EINVARG; + if (endFilePosition) *endFilePosition = 0; - if (data == NULL) return PM3_EINVARG; - uint16_t vkeycnt = 0; char *path; if (searchFile(&path, DICTIONARIES_SUBDIR, preferredName, ".dic", false) != PM3_SUCCESS) @@ -845,7 +849,7 @@ int loadFileDICTIONARYEx(const char *preferredName, void *data, size_t maxdatale keylen <<= 1; char line[255]; - + uint16_t vkeycnt = 0; size_t counter = 0; int retval = PM3_SUCCESS; @@ -863,6 +867,8 @@ int loadFileDICTIONARYEx(const char *preferredName, void *data, size_t maxdatale goto out; } } + + uint8_t *udata = (uint8_t*)data; // read file while (!feof(f)) { @@ -895,7 +901,7 @@ int loadFileDICTIONARYEx(const char *preferredName, void *data, size_t maxdatale break; } - if (hex_to_bytes(line, data + counter, keylen >> 1) != (keylen >> 1)) + if (hex_to_bytes(line, udata + counter, keylen >> 1) != (keylen >> 1)) continue; vkeycnt++; From c97775e90775aa5aa65ad481867c1605cbd7085a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 4 Jan 2020 16:16:43 +0100 Subject: [PATCH 1383/1854] style --- armsrc/string.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/armsrc/string.c b/armsrc/string.c index 4caa027a2..8dbe26808 100644 --- a/armsrc/string.c +++ b/armsrc/string.c @@ -50,8 +50,7 @@ void memxor(uint8_t *dest, uint8_t *src, size_t len) { int strlen(const char *str) { const char *p; - for (p = str; *p != '\0'; ++p) { - } + for (p = str; *p != '\0'; ++p) {}; return p - str; } From 6905cfd5486f5fa26f6f9adb3c21a217c9724f02 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 4 Jan 2020 16:25:31 +0100 Subject: [PATCH 1384/1854] style --- client/proxmark3.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/client/proxmark3.c b/client/proxmark3.c index c28a93396..7beb5196c 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -177,10 +177,13 @@ check_script: if (execCommand) { if ((cmd = strmcopy(script_cmd)) != NULL) printprompt = true; + uint16_t len = strlen(script_cmd) + 1; script_cmd += len; + if (script_cmd_len == len - 1) execCommand = false; + script_cmd_len -= len; } else { // exit after exec command @@ -210,8 +213,9 @@ check_script: prompt = PROXPROMPT_USB; else prompt = PROXPROMPT_FPC; - } else + } else { prompt = PROXPROMPT_OFFLINE; + } cmd = readline(prompt); fflush(NULL); } @@ -228,15 +232,20 @@ check_script: } // ltrim size_t off = 0; - while ((cmd[off] != '\0') && isspace(cmd[off])) + while ((cmd[off] != '\0') && isspace(cmd[off])) { off++; - for (size_t i = 0; i < strlen(cmd) - off; i++) + } + + for (size_t i = 0; i < strlen(cmd) - off; i++) { cmd[i] = cmd[i + off]; + } + cmd[strlen(cmd) - off] = '\0'; if (cmd[0] != '\0') { - if (!printprompt) + if (!printprompt) { g_printAndLog = PRINTANDLOG_LOG; + } PrintAndLogEx(NORMAL, "%s%s", prompt, cmd); g_printAndLog = PRINTANDLOG_PRINT | PRINTANDLOG_LOG; @@ -244,8 +253,9 @@ check_script: if (!current_cmdscriptfile()) { HIST_ENTRY *entry = history_get(history_length); // add if not identical to latest recorded cmd - if ((!entry) || (strcmp(entry->line, cmd) != 0)) + if ((!entry) || (strcmp(entry->line, cmd) != 0)) { add_history(cmd); + } } // process cmd int ret = CommandReceived(cmd); @@ -277,6 +287,7 @@ check_script: write_history(my_history_path); free(my_history_path); } + if (cmd) { free(cmd); cmd = NULL; From 4da12a6089d049c52d12d0addac36a05f9a9f1dd Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 4 Jan 2020 16:25:38 +0100 Subject: [PATCH 1385/1854] style --- client/cmdparser.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/client/cmdparser.c b/client/cmdparser.c index 72628f2fb..3f9412374 100644 --- a/client/cmdparser.c +++ b/client/cmdparser.c @@ -174,14 +174,21 @@ int CmdsParse(const command_t Commands[], const char *Cmd) { dumpCommandsRecursive(Commands, 1); return PM3_SUCCESS; } + char cmd_name[128]; - int len = 0; memset(cmd_name, 0, sizeof(cmd_name)); + + int len = 0; + // %n == receives an integer of value equal to the number of chars read so far. + // len = max 127 sscanf(Cmd, "%127s%n", cmd_name, &len); + str_lower(cmd_name); + // Comment if (cmd_name[0] == '#') return PM3_SUCCESS; + int i = 0; while (Commands[i].Name) { if (0 == strcmp(Commands[i].Name, cmd_name)) { @@ -241,8 +248,11 @@ void dumpCommandsRecursive(const command_t cmds[], int markdown) { } while (cmds[i].Name) { - const char *cmd_offline = "N"; + + if ((cmds[i].Name[0] == '-' || strlen(cmds[i].Name) == 0) && ++i) continue; if (cmds[i].Help[0] == '{' && ++i) continue; + + const char *cmd_offline = "N"; if (cmds[i].IsAvailable()) cmd_offline = "Y"; @@ -257,6 +267,8 @@ void dumpCommandsRecursive(const command_t cmds[], int markdown) { // Then, print the categories. These will go into subsections with their own tables while (cmds[i].Name) { + + if ((cmds[i].Name[0] == '-' || strlen(cmds[i].Name) == 0) && ++i) continue; if (cmds[i].Help[0] != '{' && ++i) continue; PrintAndLogEx(NORMAL, "### %s%s\n\n %s\n", parent, cmds[i].Name, cmds[i].Help); From 3b792f8b040d8748f6f9fee9b5f59d6c124717cb Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 4 Jan 2020 16:29:17 +0100 Subject: [PATCH 1386/1854] safer string copy --- client/util.c | 12 ++++++------ client/util.h | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/client/util.c b/client/util.c index 856091231..e07fe5d21 100644 --- a/client/util.c +++ b/client/util.c @@ -918,13 +918,13 @@ void strcreplace(char *buf, size_t len, char from, char to) { } } -char *strmcopy(const char *buf) { - char *str = (char *) calloc(strlen(buf) + 1, sizeof(uint8_t)); - if (str != NULL) { - memset(str, 0, strlen(buf) + 1); - strcpy(str, buf); +char *strmcopy(const char *src) { + char *dest = (char *) calloc(strlen(src) + 1, sizeof(uint8_t)); + if (dest != NULL) { + memset(dest, 0, strlen(src) + 1); + strncat(dest, src, strlen(src)); } - return str; + return dest; } /** diff --git a/client/util.h b/client/util.h index afa12811b..043f08e5d 100644 --- a/client/util.h +++ b/client/util.h @@ -99,6 +99,6 @@ bool str_endswith(const char *s, const char *suffix); // check for suffix in void clean_ascii(unsigned char *buf, size_t len); void strcleanrn(char *buf, size_t len); void strcreplace(char *buf, size_t len, char from, char to); -char *strmcopy(const char *buf); +char *strmcopy(const char *src); int hexstring_to_u96(uint32_t *hi2, uint32_t *hi, uint32_t *lo, const char *str); #endif From e612ae3de4275e675fc4a2591769c375d6b4fc82 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 4 Jan 2020 16:57:15 +0100 Subject: [PATCH 1387/1854] chg: adapting luascript to use new filename template for key files. --- client/luascripts/calc_di.lua | 9 ++++++--- client/luascripts/calc_mizip.lua | 7 ++++--- client/luascripts/mfckeys.lua | 11 ++++++----- client/luascripts/mifare_autopwn.lua | 4 ++-- client/luascripts/tnp3dump.lua | 20 ++++++++++++-------- 5 files changed, 30 insertions(+), 21 deletions(-) diff --git a/client/luascripts/calc_di.lua b/client/luascripts/calc_di.lua index 7b8c304db..416a3dd0f 100644 --- a/client/luascripts/calc_di.lua +++ b/client/luascripts/calc_di.lua @@ -71,11 +71,14 @@ local function exitMsg(msg) end --- -- dumps all keys to file -local function dumptofile(keys) +local function dumptofile(uid, keys) dbg('dumping keys to file') if utils.confirm('Do you wish to save the keys to dumpfile?') then - local destination = utils.input('Select a filename to store to', 'dumpkeys.bin') + + local filename = ('hf-mf-%s-key.bin'):format(uid); + + local destination = utils.input('Select a filename to store to', filename) local file = io.open(destination, 'wb') if file == nil then print('Could not write to file ', destination) @@ -172,7 +175,7 @@ local function main(args) local keys, err = createKeys( uid ) printKeys( keys ) - dumptofile( keys ) + dumptofile( uid, keys ) end main(args) diff --git a/client/luascripts/calc_mizip.lua b/client/luascripts/calc_mizip.lua index f0c76bc57..bff493131 100644 --- a/client/luascripts/calc_mizip.lua +++ b/client/luascripts/calc_mizip.lua @@ -76,11 +76,12 @@ local function exitMsg(msg) end -- -- dumps all keys to file -local function dumptofile(keys) +local function dumptofile(uid, keys) dbg('dumping keys to file') if utils.confirm('Do you wish to save the keys to dumpfile?') then - local destination = utils.input('Select a filename to store to', 'dumpkeys.bin') + local filename = ('hf-mf-%s-key.bin'):format(uid); + local destination = utils.input('Select a filename to store to', filename) local file = io.open(destination, 'wb') if file == nil then print('Could not write to file ', destination) @@ -194,7 +195,7 @@ local function main(args) local keys, err = createKeys( uid ) printKeys( keys ) - dumptofile( keys ) + dumptofile( uid, keys ) end main(args) diff --git a/client/luascripts/mfckeys.lua b/client/luascripts/mfckeys.lua index 128967c37..32808b62d 100644 --- a/client/luascripts/mfckeys.lua +++ b/client/luascripts/mfckeys.lua @@ -159,9 +159,10 @@ end end -- -- dumps all keys to file -local function dumptofile(keys) +local function dumptofile(uid, keys) if utils.confirm('Do you wish to save the keys to dumpfile?') then - local destination = utils.input('Select a filename to store to', 'dumpkeys.bin') + local filename = ('hf-mf-%s-key.bin'):format(uid); + local destination = utils.input('Select a filename to store to', filename) local file = io.open(destination, 'wb') if file == nil then print('Could not write to file ', destination) @@ -192,7 +193,7 @@ local function printkeys() end --- -- -local function perform_check(numsectors) +local function perform_check(uid, numsectors) local keyType = 0 -- A=0, B=1 @@ -237,7 +238,7 @@ local function perform_check(numsectors) display_results(keys) -- save to dumpkeys.bin - dumptofile(keys) + dumptofile(uid, keys) end -- -- shows tag information @@ -282,7 +283,7 @@ local function main(args) -- detect sectors and print taginfo numsectors = taginfo(tag) - perform_check(numsectors) + perform_check(tag.uid, numsectors) end main( args) diff --git a/client/luascripts/mifare_autopwn.lua b/client/luascripts/mifare_autopwn.lua index 2c9146e2b..624cea419 100644 --- a/client/luascripts/mifare_autopwn.lua +++ b/client/luascripts/mifare_autopwn.lua @@ -97,7 +97,7 @@ local function nested(key,sak) core.console(cmd) end -local function dump(uid, numsectors) +local function dump_tag(uid, numsectors) dbg('dumping tag memory') local typ = 1 @@ -203,7 +203,7 @@ local function main(args) -- Use nested attack nested(key, sak) -- Dump info - dump(uid, sak) + dump_tag(uid, sak) if #key == 12 then _exit = true end else diff --git a/client/luascripts/tnp3dump.lua b/client/luascripts/tnp3dump.lua index 488d2f5f9..9a7a9bc8f 100644 --- a/client/luascripts/tnp3dump.lua +++ b/client/luascripts/tnp3dump.lua @@ -109,7 +109,6 @@ local function main(args) local useNested = false local usePreCalc = false local cmdReadBlockString = 'hf mf rdbl %d A %s' - local input = "dumpkeys.bin" local outputTemplate = os.date("toydump_%Y-%m-%d_%H%M%S"); -- Arguments for the script @@ -132,13 +131,13 @@ local function main(args) core.console( cmdSetDbgOff) utils.Sleep(0.5) - result, err = lib14a.read(false, true) - if not result then return oops(err) end + tag, err = lib14a.read(false, true) + if not tag then return oops(err) end core.clearCommandBuffer() -- Show tag info - print((' Found tag %s'):format(result.name)) + print((' Found tag %s'):format(tag.name)) dbg(('Using keyA : %s'):format(keyA)) @@ -152,13 +151,18 @@ local function main(args) local akeys = '' if usePreCalc then local pre = require('precalc') - akeys = pre.GetAll(result.uid) + akeys = pre.GetAll(tag.uid) dbg(akeys) else - print('Loading dumpkeys.bin') - local hex, err = utils.ReadDumpFile(input) + local filename = ('hf-mf-%s-key.bin'):format(tag.uid); + print('loading '..filename) + local hex, err = utils.ReadDumpFile(filename) if not hex then - return oops(err) + print('loading dumpkeys.bin') + hex, err = utils.ReadDumpFile('dumpkeys.bin') + if not hex then + return oops(err) + end end akeys = hex:sub(0,12*16) end From eec1a93b41b8ddf398f0833160fb5f0ec7e9b64c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 4 Jan 2020 18:47:52 +0100 Subject: [PATCH 1388/1854] fix appveyor --- client/util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/util.c b/client/util.c index e07fe5d21..924f91ee8 100644 --- a/client/util.c +++ b/client/util.c @@ -922,7 +922,7 @@ char *strmcopy(const char *src) { char *dest = (char *) calloc(strlen(src) + 1, sizeof(uint8_t)); if (dest != NULL) { memset(dest, 0, strlen(src) + 1); - strncat(dest, src, strlen(src)); + strncat(dest, src, strlen(dest)); } return dest; } From eb2130af4b2c908e3915e01d651f2b3ca86715e9 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 4 Jan 2020 19:59:36 +0100 Subject: [PATCH 1389/1854] chg: swapped banner placement\nchg: console -c prompt got [con]. --- client/proxmark3.c | 10 +++++----- client/proxmark3.h | 2 +- client/util.c | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/client/proxmark3.c b/client/proxmark3.c index 7beb5196c..5d0b47fb3 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -150,7 +150,7 @@ main_loop(char *script_cmds_file, char *script_cmd, bool stayInCommandLoop) { // loops every time enter is pressed... while (1) { bool printprompt = false; - const char *prompt = PROXPROMPT; + const char *prompt = PROXPROMPT_CON; check_script: // If there is a script file @@ -765,10 +765,6 @@ int main(int argc, char *argv[]) { if (session.stdinOnTTY && session.stdoutOnTTY) session.supports_colors = true; #endif - // ascii art only in interactive client - if (!script_cmds_file && !script_cmd && session.stdinOnTTY && session.stdoutOnTTY && !flash_mode) - showBanner(); - // Let's take a baudrate ok for real UART, USB-CDC & BT don't use that info anyway if (speed == 0) speed = USART_BAUD_RATE; @@ -819,6 +815,10 @@ int main(int argc, char *argv[]) { if (!session.pm3_present) PrintAndLogEx(INFO, "Running in " _YELLOW_("OFFLINE") "mode. Check " _YELLOW_("\"%s -h\"") " if it's not what you want.\n", exec_name); + // ascii art only in interactive client + if (!script_cmds_file && !script_cmd && session.stdinOnTTY && session.stdoutOnTTY && !flash_mode) + showBanner(); + #ifdef HAVE_GUI # ifdef _WIN32 diff --git a/client/proxmark3.h b/client/proxmark3.h index 9313e4c28..d3e3629ec 100644 --- a/client/proxmark3.h +++ b/client/proxmark3.h @@ -14,7 +14,7 @@ #include "common.h" -#define PROXPROMPT "pm3 --> " +#define PROXPROMPT_CON "[con] pm3 --> " #define PROXPROMPT_USB "[usb] pm3 --> " #define PROXPROMPT_FPC "[fpc] pm3 --> " #define PROXPROMPT_OFFLINE "[offline] pm3 --> " diff --git a/client/util.c b/client/util.c index 924f91ee8..e5446313d 100644 --- a/client/util.c +++ b/client/util.c @@ -919,10 +919,10 @@ void strcreplace(char *buf, size_t len, char from, char to) { } char *strmcopy(const char *src) { - char *dest = (char *) calloc(strlen(src) + 1, sizeof(uint8_t)); + int len = strlen(src) + 1; + char *dest = (char *) calloc(len, sizeof(uint8_t)); if (dest != NULL) { - memset(dest, 0, strlen(src) + 1); - strncat(dest, src, strlen(dest)); + strncat(dest, src, len); } return dest; } From f304528fc0fe54ec45166a71112e560ee8fa18d9 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 4 Jan 2020 20:00:37 +0100 Subject: [PATCH 1390/1854] add: added nrz simulation for lf. *wip* needs pattern for nrz. --- armsrc/lfops.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++- armsrc/lfops.h | 3 ++- include/pm3_cmd.h | 13 ++++++++++-- 3 files changed, 63 insertions(+), 4 deletions(-) diff --git a/armsrc/lfops.c b/armsrc/lfops.c index c4cd6eaa4..12cd82e43 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -1149,7 +1149,7 @@ static void pskSimBit(uint8_t waveLen, int *n, uint8_t clk, uint8_t *curPhase, b } // args clock, carrier, invert, -void CmdPSKsimTag(uint8_t carrier, uint8_t invert, uint8_t clk, uint16_t size, uint8_t *bits, bool ledcontrol) { +void CmdPSKsimTAG(uint8_t carrier, uint8_t invert, uint8_t clk, uint16_t size, uint8_t *bits, bool ledcontrol) { FpgaDownloadAndGo(FPGA_BITSTREAM_LF); set_tracing(false); @@ -1173,6 +1173,55 @@ void CmdPSKsimTag(uint8_t carrier, uint8_t invert, uint8_t clk, uint16_t size, u reply_ng(CMD_LF_PSK_SIMULATE, PM3_EOPABORTED, NULL, 0); } +// compose nrz waveform for one bit(NRZ) +static void nrzSimBit(uint8_t c, int *n, uint8_t clock) { + uint8_t *dest = BigBuf_get_addr(); +// uint8_t halfClk = clock / 2; + // c = current bit 1 or 0 + memset(dest + (*n), c, clock); + *n += clock; +} + +// args clock, +void CmdNRZsimTAG(uint8_t invert, uint8_t separator, uint8_t clk, uint16_t size, uint8_t *bits, bool ledcontrol) { + + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + set_tracing(false); + + int n = 0, i = 0; + + // NRZ + + leadingZeroAskSimBits(&n, clk); + + for (i = 0; i < size; i++) { + nrzSimBit(bits[i] ^ invert, &n, clk); + } + + if (bits[0] == bits[size - 1]) { //run a second set inverted (for ask/raw || biphase phase) + for (i = 0; i < size; i++) { + nrzSimBit(bits[i] ^ invert ^ 1, &n, clk); + } + } + + if (separator == 1) + Dbprintf("sorry but separator option not yet available"); + + WDT_HIT(); + + Dbprintf("Simulating with clk: %d, invert: %d, separator: %d, n: %d" + , clk + , invert + , separator + , n + ); + + if (ledcontrol) LED_A_ON(); + SimulateTagLowFrequency(n, 0, ledcontrol); + if (ledcontrol) LED_A_OFF(); + reply_ng(CMD_LF_NRZ_SIMULATE, PM3_EOPABORTED, NULL, 0); +} + // loop to get raw HID waveform then FSK demodulate the TAG ID from it void CmdHIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol) { uint8_t *dest = BigBuf_get_addr(); diff --git a/armsrc/lfops.h b/armsrc/lfops.h index f81d1e7ab..b697cffd1 100644 --- a/armsrc/lfops.h +++ b/armsrc/lfops.h @@ -36,7 +36,8 @@ void CmdHIDsimTAG(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT, bool void CmdFSKsimTAGEx(uint8_t fchigh, uint8_t fclow, uint8_t separator, uint8_t clk, uint16_t bitslen, uint8_t *bits, bool ledcontrol, int numcycles); void CmdFSKsimTAG(uint8_t fchigh, uint8_t fclow, uint8_t separator, uint8_t clk, uint16_t bitslen, uint8_t *bits, bool ledcontrol); void CmdASKsimTAG(uint8_t encoding, uint8_t invert, uint8_t separator, uint8_t clk, uint16_t size, uint8_t *bits, bool ledcontrol); -void CmdPSKsimTag(uint8_t carrier, uint8_t invert, uint8_t clk, uint16_t size, uint8_t *bits, bool ledcontrol); +void CmdPSKsimTAG(uint8_t carrier, uint8_t invert, uint8_t clk, uint16_t size, uint8_t *bits, bool ledcontrol); +void CmdNRZsimTAG(uint8_t invert, uint8_t separator, uint8_t clk, uint16_t size, uint8_t *bits, bool ledcontrol); void CmdHIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol); void CmdAWIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol); // Realtime demodulation mode for AWID26 diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 64a0c5fd1..44747b1ea 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -239,6 +239,14 @@ typedef struct { uint8_t data[]; } PACKED lf_psksim_t; +// For CMD_LF_NRZ_SIMULATE (NRZ) +typedef struct { + uint8_t invert; + uint8_t separator; + uint8_t clock; + uint8_t data[]; +} PACKED lf_nrzsim_t; + typedef struct { uint8_t blockno; uint8_t keytype; @@ -371,12 +379,13 @@ typedef struct { #define CMD_LF_EM4X_READWORD 0x0218 #define CMD_LF_EM4X_WRITEWORD 0x0219 #define CMD_LF_IO_DEMOD 0x021A -#define CMD_LF_EM410X_DEMOD 0x021c +#define CMD_LF_EM410X_DEMOD 0x021C // 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_ASK_SIMULATE 0x021F #define CMD_LF_PSK_SIMULATE 0x0220 +#define CMD_LF_NRZ_SIMULATE 0x0232 #define CMD_LF_AWID_DEMOD 0x0221 #define CMD_LF_VIKING_CLONE 0x0222 #define CMD_LF_T55XX_WAKEUP 0x0224 From a62aed9fe903696b153883e73f6c42fc59dfd453 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 4 Jan 2020 20:01:06 +0100 Subject: [PATCH 1391/1854] add: added nrz simulation for lf. *wip* --- armsrc/appmain.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index a405db12e..20c26eb4d 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -775,7 +775,12 @@ static void PacketReceived(PacketCommandNG *packet) { } case CMD_LF_PSK_SIMULATE: { lf_psksim_t *payload = (lf_psksim_t *)packet->data.asBytes; - CmdPSKsimTag(payload->carrier, payload->invert, payload->clock, packet->length - sizeof(lf_psksim_t), payload->data, true); + CmdPSKsimTAG(payload->carrier, payload->invert, payload->clock, packet->length - sizeof(lf_psksim_t), payload->data, true); + break; + } + case CMD_LF_NRZ_SIMULATE: { + lf_nrzsim_t *payload = (lf_nrzsim_t *)packet->data.asBytes; + CmdNRZsimTAG(payload->invert, payload->separator, payload->clock, packet->length - sizeof(lf_asksim_t), payload->data, true); break; } case CMD_LF_HID_CLONE: { @@ -1598,6 +1603,8 @@ static void PacketReceived(PacketCommandNG *packet) { BigBuf_Clear_ext(false); BigBuf_free(); } + + // 40 000 - (512-3) 509 = 39491 uint16_t offset = MIN(BIGBUF_SIZE - PM3_CMD_DATA_SIZE - 3, payload->offset); // need to copy len bytes of data, not PM3_CMD_DATA_SIZE - 3 - offset @@ -1605,6 +1612,8 @@ static void PacketReceived(PacketCommandNG *packet) { uint16_t len = MIN(BIGBUF_SIZE - offset, PM3_CMD_DATA_SIZE - 3); uint8_t *mem = BigBuf_get_addr(); + + // x + 394 memcpy(mem + offset, &payload->data, len); // memcpy(mem + offset, &payload->data, PM3_CMD_DATA_SIZE - 3 - offset); reply_ng(CMD_LF_UPLOAD_SIM_SAMPLES, PM3_SUCCESS, NULL, 0); From 990cd3590a1d54df11d75cb6fbb22d003746d2e4 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 4 Jan 2020 20:01:33 +0100 Subject: [PATCH 1392/1854] add: lf pac sim *wip* --- client/cmdlfpac.c | 49 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/client/cmdlfpac.c b/client/cmdlfpac.c index 00d4d4ae6..92a7f18ea 100644 --- a/client/cmdlfpac.c +++ b/client/cmdlfpac.c @@ -10,6 +10,8 @@ #include "cmdlfpac.h" #include //tolower +#include +#include #include "commonutil.h" // ARRAYLEN #include "common.h" @@ -39,7 +41,19 @@ static int usage_lf_pac_clone(void) { PrintAndLogEx(NORMAL, " lf pac clone b FF2049906D8511C593155B56D5B2649F "); return PM3_SUCCESS; } - +static int usage_lf_pac_sim(void) { + PrintAndLogEx(NORMAL, "Enables simulation of PAC/Stanley card with specified card number."); + PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued."); + PrintAndLogEx(NORMAL, "The card ID is 8 byte number. Larger values are truncated."); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Usage: lf pac sim "); + PrintAndLogEx(NORMAL, "Options:"); + PrintAndLogEx(NORMAL, " : 8 byte PAC/Stanley card id"); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Examples:"); + PrintAndLogEx(NORMAL, " lf pac sim 1A337"); + return PM3_SUCCESS; +} // by danshuk // PAC_8byte format: preamble (8 mark/idle bits), ascii STX (02), ascii '2' (32), ascii '0' (30), ascii bytes 0..7 (cardid), then xor checksum of cardid bytes // all bytes following 8 bit preamble are one start bit (0), 7 data bits (lsb first), odd parity bit, and one stop bit (1) @@ -231,7 +245,38 @@ static int CmdPacClone(const char *Cmd) { static int CmdPacSim(const char *Cmd) { // NRZ sim. - PrintAndLogEx(INFO, " To be implemented, feel free to contribute!"); + uint32_t id = 0; + uint64_t rawID = 0; + char cmdp = tolower(param_getchar(Cmd, 0)); + if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_pac_sim(); + + id = param_get32ex(Cmd, 0, 0, 16); + if (id == 0) return usage_lf_pac_sim(); + + //rawID = pacCardIdToRaw(id); + + PrintAndLogEx(SUCCESS, "Simulating PAC/Stanley - ID " _YELLOW_("%08X")" raw "_YELLOW_("%08X%08X"), id, (uint32_t)(rawID >> 32), (uint32_t)(rawID & 0xFFFFFFFF)); + + uint8_t bs[128]; + num_to_bytebits(rawID, sizeof(bs), bs); + + lf_nrzsim_t *payload = calloc(1, sizeof(lf_nrzsim_t) + sizeof(bs)); + payload->invert = 0; + payload->separator = 0; + payload->clock = 32; + memcpy(payload->data, bs, sizeof(bs)); + + clearCommandBuffer(); + SendCommandNG(CMD_LF_NRZ_SIMULATE, (uint8_t *)payload, sizeof(lf_nrzsim_t) + sizeof(bs)); + free(payload); + + PacketResponseNG resp; + WaitForResponse(CMD_LF_NRZ_SIMULATE, &resp); + + PrintAndLogEx(INFO, "Done"); + if (resp.status != PM3_EOPABORTED) + return resp.status; + return PM3_SUCCESS; } From 731f6fc3223613900fca653c897653faa76e2991 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 4 Jan 2020 20:21:10 +0100 Subject: [PATCH 1393/1854] textual --- client/cmddata.c | 116 ++++++++++++++++++++++++++--------------------- 1 file changed, 65 insertions(+), 51 deletions(-) diff --git a/client/cmddata.c b/client/cmddata.c index a9b38b105..0469bf837 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -100,19 +100,26 @@ static int usage_data_biphaserawdecode(void) { } static int usage_data_rawdemod(void) { PrintAndLogEx(NORMAL, "Usage: data rawdemod [modulation] |"); - PrintAndLogEx(NORMAL, " [modulation] as 2 char, 'ab' for ask/biphase, 'am' for ask/manchester, 'ar' for ask/raw, 'fs' for fsk, ..."); - PrintAndLogEx(NORMAL, " 'nr' for nrz/direct, 'p1' for psk1, 'p2' for psk2"); + PrintAndLogEx(NORMAL, " [modulation] as 2 char,"); + PrintAndLogEx(NORMAL, " "_YELLOW_("ab")"- ask/biphase"); + PrintAndLogEx(NORMAL, " "_YELLOW_("am")"- ask/manchester"); + PrintAndLogEx(NORMAL, " "_YELLOW_("ar")"- ask/raw"); + PrintAndLogEx(NORMAL, " "_YELLOW_("fs")"- fsk"); + PrintAndLogEx(NORMAL, " "_YELLOW_("nr")"- nrz/direct"); + PrintAndLogEx(NORMAL, " "_YELLOW_("p1")"- psk1"); + PrintAndLogEx(NORMAL, " "_YELLOW_("p2")"- psk2"); PrintAndLogEx(NORMAL, " as 'h', prints the help for the specific modulation"); PrintAndLogEx(NORMAL, " see specific modulation help for optional parameters"); PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, " Example: data rawdemod fs h = print help specific to fsk demod"); - PrintAndLogEx(NORMAL, " : data rawdemod fs = demod GraphBuffer using: fsk - autodetect"); - PrintAndLogEx(NORMAL, " : data rawdemod ab = demod GraphBuffer using: ask/biphase - autodetect"); - PrintAndLogEx(NORMAL, " : data rawdemod am = demod GraphBuffer using: ask/manchester - autodetect"); - PrintAndLogEx(NORMAL, " : data rawdemod ar = demod GraphBuffer using: ask/raw - autodetect"); - PrintAndLogEx(NORMAL, " : data rawdemod nr = demod GraphBuffer using: nrz/direct - autodetect"); - PrintAndLogEx(NORMAL, " : data rawdemod p1 = demod GraphBuffer using: psk1 - autodetect"); - PrintAndLogEx(NORMAL, " : data rawdemod p2 = demod GraphBuffer using: psk2 - autodetect"); + PrintAndLogEx(NORMAL, "Example:"); + PrintAndLogEx(NORMAL, " data rawdemod fs h = print help specific to fsk demod"); + PrintAndLogEx(NORMAL, " data rawdemod fs = demod GraphBuffer using: fsk - autodetect"); + PrintAndLogEx(NORMAL, " data rawdemod ab = demod GraphBuffer using: ask/biphase - autodetect"); + PrintAndLogEx(NORMAL, " data rawdemod am = demod GraphBuffer using: ask/manchester - autodetect"); + PrintAndLogEx(NORMAL, " data rawdemod ar = demod GraphBuffer using: ask/raw - autodetect"); + PrintAndLogEx(NORMAL, " data rawdemod nr = demod GraphBuffer using: nrz/direct - autodetect"); + PrintAndLogEx(NORMAL, " data rawdemod p1 = demod GraphBuffer using: psk1 - autodetect"); + PrintAndLogEx(NORMAL, " data rawdemod p2 = demod GraphBuffer using: psk2 - autodetect"); return PM3_SUCCESS; } static int usage_data_rawdemod_am(void) { @@ -124,11 +131,12 @@ static int usage_data_rawdemod_am(void) { PrintAndLogEx(NORMAL, " [set maximum Samples to read], default = 32768 (512 bits at rf/64)"); PrintAndLogEx(NORMAL, " , 'a' to attempt demod with ask amplification, default = no amp"); PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, " Example: data rawdemod am = demod an ask/manchester tag from GraphBuffer"); - PrintAndLogEx(NORMAL, " : data rawdemod am 32 = demod an ask/manchester tag from GraphBuffer using a clock of RF/32"); - PrintAndLogEx(NORMAL, " : data rawdemod am 32 1 = demod an ask/manchester tag from GraphBuffer using a clock of RF/32 and inverting data"); - PrintAndLogEx(NORMAL, " : data rawdemod am 1 = demod an ask/manchester tag from GraphBuffer while inverting data"); - PrintAndLogEx(NORMAL, " : data rawdemod am 64 1 0 = demod an ask/manchester tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors"); + PrintAndLogEx(NORMAL, "Example:"); + PrintAndLogEx(NORMAL, " data rawdemod am = demod an ask/manchester tag from GraphBuffer"); + PrintAndLogEx(NORMAL, " data rawdemod am 32 = demod an ask/manchester tag from GraphBuffer using a clock of RF/32"); + PrintAndLogEx(NORMAL, " data rawdemod am 32 1 = demod an ask/manchester tag from GraphBuffer using a clock of RF/32 and inverting data"); + PrintAndLogEx(NORMAL, " data rawdemod am 1 = demod an ask/manchester tag from GraphBuffer while inverting data"); + PrintAndLogEx(NORMAL, " data rawdemod am 64 1 0 = demod an ask/manchester tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors"); return PM3_SUCCESS; } static int usage_data_rawdemod_ab(void) { @@ -145,13 +153,14 @@ static int usage_data_rawdemod_ab(void) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, " NOTE: --invert for Conditional Dephase Encoding (CDP) AKA Differential Manchester"); PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, " Example: data rawdemod ab = demod an ask/biph tag from GraphBuffer"); - PrintAndLogEx(NORMAL, " : data rawdemod ab 0 a = demod an ask/biph tag from GraphBuffer, amplified"); - PrintAndLogEx(NORMAL, " : data rawdemod ab 1 32 = demod an ask/biph tag from GraphBuffer using an offset of 1 and a clock of RF/32"); - PrintAndLogEx(NORMAL, " : data rawdemod ab 0 32 1 = demod an ask/biph tag from GraphBuffer using a clock of RF/32 and inverting data"); - PrintAndLogEx(NORMAL, " : data rawdemod ab 0 1 = demod an ask/biph tag from GraphBuffer while inverting data"); - PrintAndLogEx(NORMAL, " : data rawdemod ab 0 64 1 0 = demod an ask/biph tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors"); - PrintAndLogEx(NORMAL, " : data rawdemod ab 0 64 1 0 0 a = demod an ask/biph tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors, and amp"); + PrintAndLogEx(NORMAL, "Example:"); + PrintAndLogEx(NORMAL, " data rawdemod ab = demod an ask/biph tag from GraphBuffer"); + PrintAndLogEx(NORMAL, " data rawdemod ab 0 a = demod an ask/biph tag from GraphBuffer, amplified"); + PrintAndLogEx(NORMAL, " data rawdemod ab 1 32 = demod an ask/biph tag from GraphBuffer using an offset of 1 and a clock of RF/32"); + PrintAndLogEx(NORMAL, " data rawdemod ab 0 32 1 = demod an ask/biph tag from GraphBuffer using a clock of RF/32 and inverting data"); + PrintAndLogEx(NORMAL, " data rawdemod ab 0 1 = demod an ask/biph tag from GraphBuffer while inverting data"); + PrintAndLogEx(NORMAL, " data rawdemod ab 0 64 1 0 = demod an ask/biph tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors"); + PrintAndLogEx(NORMAL, " data rawdemod ab 0 64 1 0 0 a = demod an ask/biph tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors, and amp"); return PM3_SUCCESS; } static int usage_data_rawdemod_ar(void) { @@ -162,13 +171,14 @@ static int usage_data_rawdemod_ar(void) { PrintAndLogEx(NORMAL, " [set maximum Samples to read], default = 32768 (1024 bits at rf/64)"); PrintAndLogEx(NORMAL, " , 'a' to attempt demod with ask amplification, default = no amp"); PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, " Example: data rawdemod ar = demod an ask tag from GraphBuffer"); - PrintAndLogEx(NORMAL, " : data rawdemod ar a = demod an ask tag from GraphBuffer, amplified"); - PrintAndLogEx(NORMAL, " : data rawdemod ar 32 = demod an ask tag from GraphBuffer using a clock of RF/32"); - PrintAndLogEx(NORMAL, " : data rawdemod ar 32 1 = demod an ask tag from GraphBuffer using a clock of RF/32 and inverting data"); - PrintAndLogEx(NORMAL, " : data rawdemod ar 1 = demod an ask tag from GraphBuffer while inverting data"); - PrintAndLogEx(NORMAL, " : data rawdemod ar 64 1 0 = demod an ask tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors"); - PrintAndLogEx(NORMAL, " : data rawdemod ar 64 1 0 0 a = demod an ask tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors, and amp"); + PrintAndLogEx(NORMAL, "Example:"); + PrintAndLogEx(NORMAL, " data rawdemod ar = demod an ask tag from GraphBuffer"); + PrintAndLogEx(NORMAL, " data rawdemod ar a = demod an ask tag from GraphBuffer, amplified"); + PrintAndLogEx(NORMAL, " data rawdemod ar 32 = demod an ask tag from GraphBuffer using a clock of RF/32"); + PrintAndLogEx(NORMAL, " data rawdemod ar 32 1 = demod an ask tag from GraphBuffer using a clock of RF/32 and inverting data"); + PrintAndLogEx(NORMAL, " data rawdemod ar 1 = demod an ask tag from GraphBuffer while inverting data"); + PrintAndLogEx(NORMAL, " data rawdemod ar 64 1 0 = demod an ask tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors"); + PrintAndLogEx(NORMAL, " data rawdemod ar 64 1 0 0 a = demod an ask tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors, and amp"); return PM3_SUCCESS; } static int usage_data_rawdemod_fs(void) { @@ -178,13 +188,14 @@ static int usage_data_rawdemod_fs(void) { PrintAndLogEx(NORMAL, " [fchigh], larger field clock length, omit for autodetect"); PrintAndLogEx(NORMAL, " [fclow], small field clock length, omit for autodetect"); PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, " Example: data rawdemod fs = demod an fsk tag from GraphBuffer using autodetect"); - PrintAndLogEx(NORMAL, " : data rawdemod fs 32 = demod an fsk tag from GraphBuffer using a clock of RF/32, autodetect fc"); - PrintAndLogEx(NORMAL, " : data rawdemod fs 1 = demod an fsk tag from GraphBuffer using autodetect, invert output"); - PrintAndLogEx(NORMAL, " : data rawdemod fs 32 1 = demod an fsk tag from GraphBuffer using a clock of RF/32, invert output, autodetect fc"); - PrintAndLogEx(NORMAL, " : data rawdemod fs 64 0 8 5 = demod an fsk1 RF/64 tag from GraphBuffer"); - PrintAndLogEx(NORMAL, " : data rawdemod fs 50 0 10 8 = demod an fsk2 RF/50 tag from GraphBuffer"); - PrintAndLogEx(NORMAL, " : data rawdemod fs 50 1 10 8 = demod an fsk2a RF/50 tag from GraphBuffer"); + PrintAndLogEx(NORMAL, "Example:"); + PrintAndLogEx(NORMAL, " data rawdemod fs = demod an fsk tag from GraphBuffer using autodetect"); + PrintAndLogEx(NORMAL, " data rawdemod fs 32 = demod an fsk tag from GraphBuffer using a clock of RF/32, autodetect fc"); + PrintAndLogEx(NORMAL, " data rawdemod fs 1 = demod an fsk tag from GraphBuffer using autodetect, invert output"); + PrintAndLogEx(NORMAL, " data rawdemod fs 32 1 = demod an fsk tag from GraphBuffer using a clock of RF/32, invert output, autodetect fc"); + PrintAndLogEx(NORMAL, " data rawdemod fs 64 0 8 5 = demod an fsk1 RF/64 tag from GraphBuffer"); + PrintAndLogEx(NORMAL, " data rawdemod fs 50 0 10 8 = demod an fsk2 RF/50 tag from GraphBuffer"); + PrintAndLogEx(NORMAL, " data rawdemod fs 50 1 10 8 = demod an fsk2a RF/50 tag from GraphBuffer"); return PM3_SUCCESS; } static int usage_data_rawdemod_nr(void) { @@ -193,11 +204,12 @@ static int usage_data_rawdemod_nr(void) { PrintAndLogEx(NORMAL, " , 1 for invert output"); PrintAndLogEx(NORMAL, " [set maximum allowed errors], default = 100."); PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, " Example: data rawdemod nr = demod a nrz/direct tag from GraphBuffer"); - PrintAndLogEx(NORMAL, " : data rawdemod nr 32 = demod a nrz/direct tag from GraphBuffer using a clock of RF/32"); - PrintAndLogEx(NORMAL, " : data rawdemod nr 32 1 = demod a nrz/direct tag from GraphBuffer using a clock of RF/32 and inverting data"); - PrintAndLogEx(NORMAL, " : data rawdemod nr 1 = demod a nrz/direct tag from GraphBuffer while inverting data"); - PrintAndLogEx(NORMAL, " : data rawdemod nr 64 1 0 = demod a nrz/direct tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors"); + PrintAndLogEx(NORMAL, "Example:"); + PrintAndLogEx(NORMAL, " data rawdemod nr = demod a nrz/direct tag from GraphBuffer"); + PrintAndLogEx(NORMAL, " data rawdemod nr 32 = demod a nrz/direct tag from GraphBuffer using a clock of RF/32"); + PrintAndLogEx(NORMAL, " data rawdemod nr 32 1 = demod a nrz/direct tag from GraphBuffer using a clock of RF/32 and inverting data"); + PrintAndLogEx(NORMAL, " data rawdemod nr 1 = demod a nrz/direct tag from GraphBuffer while inverting data"); + PrintAndLogEx(NORMAL, " data rawdemod nr 64 1 0 = demod a nrz/direct tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors"); return PM3_SUCCESS; } static int usage_data_rawdemod_p1(void) { @@ -206,11 +218,12 @@ static int usage_data_rawdemod_p1(void) { PrintAndLogEx(NORMAL, " , 1 for invert output"); PrintAndLogEx(NORMAL, " [set maximum allowed errors], default = 100."); PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, " Example: data rawdemod p1 = demod a psk1 tag from GraphBuffer"); - PrintAndLogEx(NORMAL, " : data rawdemod p1 32 = demod a psk1 tag from GraphBuffer using a clock of RF/32"); - PrintAndLogEx(NORMAL, " : data rawdemod p1 32 1 = demod a psk1 tag from GraphBuffer using a clock of RF/32 and inverting data"); - PrintAndLogEx(NORMAL, " : data rawdemod p1 1 = demod a psk1 tag from GraphBuffer while inverting data"); - PrintAndLogEx(NORMAL, " : data rawdemod p1 64 1 0 = demod a psk1 tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors"); + PrintAndLogEx(NORMAL, "Example:"); + PrintAndLogEx(NORMAL, " data rawdemod p1 = demod a psk1 tag from GraphBuffer"); + PrintAndLogEx(NORMAL, " data rawdemod p1 32 = demod a psk1 tag from GraphBuffer using a clock of RF/32"); + PrintAndLogEx(NORMAL, " data rawdemod p1 32 1 = demod a psk1 tag from GraphBuffer using a clock of RF/32 and inverting data"); + PrintAndLogEx(NORMAL, " data rawdemod p1 1 = demod a psk1 tag from GraphBuffer while inverting data"); + PrintAndLogEx(NORMAL, " data rawdemod p1 64 1 0 = demod a psk1 tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors"); return PM3_SUCCESS; } static int usage_data_rawdemod_p2(void) { @@ -219,11 +232,12 @@ static int usage_data_rawdemod_p2(void) { PrintAndLogEx(NORMAL, " , 1 for invert output"); PrintAndLogEx(NORMAL, " [set maximum allowed errors], default = 100."); PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, " Example: data rawdemod p2 = demod a psk2 tag from GraphBuffer, autodetect clock"); - PrintAndLogEx(NORMAL, " : data rawdemod p2 32 = demod a psk2 tag from GraphBuffer using a clock of RF/32"); - PrintAndLogEx(NORMAL, " : data rawdemod p2 32 1 = demod a psk2 tag from GraphBuffer using a clock of RF/32 and inverting output"); - PrintAndLogEx(NORMAL, " : data rawdemod p2 1 = demod a psk2 tag from GraphBuffer, autodetect clock and invert output"); - PrintAndLogEx(NORMAL, " : data rawdemod p2 64 1 0 = demod a psk2 tag from GraphBuffer using a clock of RF/64, inverting output and allowing 0 demod errors"); + PrintAndLogEx(NORMAL, "Example:"); + PrintAndLogEx(NORMAL, " data rawdemod p2 = demod a psk2 tag from GraphBuffer, autodetect clock"); + PrintAndLogEx(NORMAL, " data rawdemod p2 32 = demod a psk2 tag from GraphBuffer using a clock of RF/32"); + PrintAndLogEx(NORMAL, " data rawdemod p2 32 1 = demod a psk2 tag from GraphBuffer using a clock of RF/32 and inverting output"); + PrintAndLogEx(NORMAL, " data rawdemod p2 1 = demod a psk2 tag from GraphBuffer, autodetect clock and invert output"); + PrintAndLogEx(NORMAL, " data rawdemod p2 64 1 0 = demod a psk2 tag from GraphBuffer using a clock of RF/64, inverting output and allowing 0 demod errors"); return PM3_SUCCESS; } static int usage_data_autocorr(void) { From eb4573b06c5bd95124fdc89527057fef9ad60a59 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 5 Jan 2020 21:45:29 +0100 Subject: [PATCH 1394/1854] strdup --- client/proxmark3.c | 16 ++++++++++------ client/util.c | 13 +++++++++---- client/util.h | 3 ++- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/client/proxmark3.c b/client/proxmark3.c index 5d0b47fb3..76048952f 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -10,9 +10,10 @@ //----------------------------------------------------------------------------- #include "proxmark3.h" -#include -#include // for Mingw readline + #include +#include // for Mingw readline +#include #include #include #include @@ -27,7 +28,6 @@ #include "fileutils.h" #include "flash.h" - static void showBanner(void) { g_printAndLog = PRINTANDLOG_PRINT; @@ -169,13 +169,16 @@ check_script: // remove linebreaks strcleanrn(script_cmd_buf, sizeof(script_cmd_buf)); - if ((cmd = strmcopy(script_cmd_buf)) != NULL) + cmd = strdup(script_cmd_buf); + if (cmd != NULL) printprompt = true; } } else { // If there is a script command if (execCommand) { - if ((cmd = strmcopy(script_cmd)) != NULL) + + cmd = strdup(script_cmd); + if (cmd != NULL) printprompt = true; uint16_t len = strlen(script_cmd) + 1; @@ -203,7 +206,8 @@ check_script: // remove linebreaks strcleanrn(script_cmd_buf, sizeof(script_cmd_buf)); - if ((cmd = strmcopy(script_cmd_buf)) != NULL) + cmd = strdup(script_cmd_buf); + if (cmd != NULL) printprompt = true; } else { diff --git a/client/util.c b/client/util.c index e5446313d..41ee8f0d8 100644 --- a/client/util.c +++ b/client/util.c @@ -918,11 +918,16 @@ void strcreplace(char *buf, size_t len, char from, char to) { } } -char *strmcopy(const char *src) { - int len = strlen(src) + 1; - char *dest = (char *) calloc(len, sizeof(uint8_t)); + +char *strdup(const char *src) { + return strndup(src, strlen(src)); +} +char *strndup(const char *src, size_t len) { + + char *dest = (char *) calloc(len + 1, sizeof(uint8_t)); if (dest != NULL) { - strncat(dest, src, len); + memcpy(dest, src, len); + dest[len] = '\0'; } return dest; } diff --git a/client/util.h b/client/util.h index 043f08e5d..b5a4be4a6 100644 --- a/client/util.h +++ b/client/util.h @@ -99,6 +99,7 @@ bool str_endswith(const char *s, const char *suffix); // check for suffix in void clean_ascii(unsigned char *buf, size_t len); void strcleanrn(char *buf, size_t len); void strcreplace(char *buf, size_t len, char from, char to); -char *strmcopy(const char *src); +char *strdup(const char *src); +char *strndup(const char *src, size_t len); int hexstring_to_u96(uint32_t *hi2, uint32_t *hi, uint32_t *lo, const char *str); #endif From 719fcf91abe843204e6a70b2c84641103d7a1cc3 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 5 Jan 2020 22:24:24 +0100 Subject: [PATCH 1395/1854] strdup name confusing --- client/proxmark3.c | 6 +++--- client/util.c | 6 +++--- client/util.h | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/client/proxmark3.c b/client/proxmark3.c index 76048952f..d582bafc0 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -169,7 +169,7 @@ check_script: // remove linebreaks strcleanrn(script_cmd_buf, sizeof(script_cmd_buf)); - cmd = strdup(script_cmd_buf); + cmd = str_dup(script_cmd_buf); if (cmd != NULL) printprompt = true; } @@ -177,7 +177,7 @@ check_script: // If there is a script command if (execCommand) { - cmd = strdup(script_cmd); + cmd = str_dup(script_cmd); if (cmd != NULL) printprompt = true; @@ -206,7 +206,7 @@ check_script: // remove linebreaks strcleanrn(script_cmd_buf, sizeof(script_cmd_buf)); - cmd = strdup(script_cmd_buf); + cmd = str_dup(script_cmd_buf); if (cmd != NULL) printprompt = true; diff --git a/client/util.c b/client/util.c index 41ee8f0d8..226255536 100644 --- a/client/util.c +++ b/client/util.c @@ -919,10 +919,10 @@ void strcreplace(char *buf, size_t len, char from, char to) { } -char *strdup(const char *src) { - return strndup(src, strlen(src)); +char *str_dup(const char *src) { + return str_ndup(src, strlen(src)); } -char *strndup(const char *src, size_t len) { +char *str_ndup(const char *src, size_t len) { char *dest = (char *) calloc(len + 1, sizeof(uint8_t)); if (dest != NULL) { diff --git a/client/util.h b/client/util.h index b5a4be4a6..21db9198f 100644 --- a/client/util.h +++ b/client/util.h @@ -99,7 +99,7 @@ bool str_endswith(const char *s, const char *suffix); // check for suffix in void clean_ascii(unsigned char *buf, size_t len); void strcleanrn(char *buf, size_t len); void strcreplace(char *buf, size_t len, char from, char to); -char *strdup(const char *src); -char *strndup(const char *src, size_t len); +char *str_dup(const char *src); +char *str_ndup(const char *src, size_t len); int hexstring_to_u96(uint32_t *hi2, uint32_t *hi, uint32_t *lo, const char *str); #endif From b3b1e103300de3eb85365e0220ed4d6a915937b5 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 5 Jan 2020 22:54:31 +0100 Subject: [PATCH 1396/1854] shadowing --- client/mifare/mifare4.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/client/mifare/mifare4.c b/client/mifare/mifare4.c index 84f509078..966a2027d 100644 --- a/client/mifare/mifare4.c +++ b/client/mifare/mifare4.c @@ -22,12 +22,7 @@ void mfpSetVerboseMode(bool verbose) { VerboseMode = verbose; } -typedef struct { - uint8_t Code; - const char *Description; -} PlusErrorsElm; - -static const PlusErrorsElm PlusErrors[] = { +static const PlusErrorsElm_t PlusErrors[] = { {0xFF, ""}, {0x00, "Transfer cannot be granted within the current authentication."}, {0x06, "Access Conditions not fulfilled. Block does not exist, block is not a value block."}, @@ -96,7 +91,7 @@ const char *mfGetAccessConditionsDesc(uint8_t blockn, uint8_t *data) { }; /* static int CalculateEncIVCommand(mf4Session_t *session, uint8_t *iv, bool verbose) { - memcpy(&iv[0], session->TI, 4); + memcpy(&iv[0], &session->TI, 4); memcpy(&iv[4], &session->R_Ctr, 2); memcpy(&iv[6], &session->W_Ctr, 2); memcpy(&iv[8], &session->R_Ctr, 2); @@ -114,7 +109,7 @@ static int CalculateEncIVResponse(mf4Session *session, uint8_t *iv, bool verbose memcpy(&iv[6], &session->W_Ctr, 2); memcpy(&iv[8], &session->R_Ctr, 2); memcpy(&iv[10], &session->W_Ctr, 2); - memcpy(&iv[12], session->TI, 4); + memcpy(&iv[12], &session->TI, 4); return 0; } @@ -382,8 +377,8 @@ int mfpReadSector(uint8_t sectorNo, uint8_t keyType, uint8_t *key, uint8_t *data if (verbose) PrintAndLogEx(INFO, "--sector[%d]:%02x key:%04x", mfNumBlocksPerSector(sectorNo), sectorNo, uKeyNum); - mf4Session_t session; - int res = MifareAuth4(&session, keyn, key, true, true, true, verbose, false); + mf4Session_t _session; + int res = MifareAuth4(&_session, keyn, key, true, true, true, verbose, false); if (res) { PrintAndLogEx(ERR, "Sector %d authentication error: %d", sectorNo, res); return res; @@ -394,7 +389,7 @@ int mfpReadSector(uint8_t sectorNo, uint8_t keyType, uint8_t *key, uint8_t *data uint8_t mac[8] = {0}; uint8_t firstBlockNo = mfFirstBlockOfSector(sectorNo); for (int n = firstBlockNo; n < firstBlockNo + mfNumBlocksPerSector(sectorNo); n++) { - res = MFPReadBlock(&session, plain, n & 0xff, 1, false, true, data, sizeof(data), &datalen, mac); + res = MFPReadBlock(&_session, plain, n & 0xff, 1, false, true, data, sizeof(data), &datalen, mac); if (res) { PrintAndLogEx(ERR, "Sector %d read error: %d", sectorNo, res); DropField(); From 42ed891f30a2125afe81825766ad008d76495205 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 5 Jan 2020 22:55:10 +0100 Subject: [PATCH 1397/1854] shadowing --- client/mifare/mifare4.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/client/mifare/mifare4.h b/client/mifare/mifare4.h index 3efb9e43a..cb2c8d652 100644 --- a/client/mifare/mifare4.h +++ b/client/mifare/mifare4.h @@ -41,6 +41,12 @@ typedef struct { const char *description; } AccessConditions_t; + +typedef struct { + uint8_t Code; + const char *Description; +} PlusErrorsElm_t; + void mfpSetVerboseMode(bool verbose); const char *mfpGetErrorDescription(uint8_t errorCode); From 30de7f5082f312b632d1c2ab98433598ec4b6567 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 5 Jan 2020 23:07:33 +0100 Subject: [PATCH 1398/1854] shadow --- client/cmdhfmfdes.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/cmdhfmfdes.c b/client/cmdhfmfdes.c index 63e5a5be5..9c35a195d 100644 --- a/client/cmdhfmfdes.c +++ b/client/cmdhfmfdes.c @@ -529,10 +529,10 @@ static int CmdHF14ADesAuth(const char *Cmd) { uint8_t isOK = resp.oldarg[0] & 0xff; if (isOK) { - uint8_t *session = resp.data.asBytes; + uint8_t *session_key = resp.data.asBytes; PrintAndLogEx(NORMAL, " Key :%s", sprint_hex(key, keylength)); - PrintAndLogEx(NORMAL, " SESSION :%s", sprint_hex(session, keylength)); + PrintAndLogEx(NORMAL, " SESSION :%s", sprint_hex(session_key, keylength)); PrintAndLogEx(NORMAL, "-------------------------------------------------------------"); //PrintAndLogEx(NORMAL, " Expected :B5 21 9E E8 1A A7 49 9D 21 96 68 7E 13 97 38 56"); } else { From a1d93567d2330286a1d6238f076f5b256eec1eca Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 5 Jan 2020 23:14:24 +0100 Subject: [PATCH 1399/1854] shadowing --- client/cmdhfmf.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index a8960d5d0..4fe5370fc 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -1750,7 +1750,6 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { if (param_gethex(Cmd, cmdp + 3, key, 12)) { PrintAndLogEx(WARNING, "Key must include 12 HEX symbols"); errors = true; - return PM3_EINVARG; } know_target_key = true; cmdp += 3; @@ -1896,7 +1895,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { bool load_success = true; // Load the dictionary if (has_filename) { - int res = loadFileDICTIONARY_safe(filename, (void **) &keyBlock, 6, &key_cnt); + res = loadFileDICTIONARY_safe(filename, (void **) &keyBlock, 6, &key_cnt); if (res != PM3_SUCCESS || key_cnt == 0 || keyBlock == NULL) { PrintAndLogEx(FAILED, "An error occurred while loading the dictionary! (we will use the default keys now)"); if (keyBlock != NULL) @@ -1965,7 +1964,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { if (size == key_cnt - i) lastChunk = true; - int res = mfCheckKeys_fast(sectors_cnt, firstChunk, lastChunk, strategy, size, keyBlock + (i * 6), e_sector, false); + res = mfCheckKeys_fast(sectors_cnt, firstChunk, lastChunk, strategy, size, keyBlock + (i * 6), e_sector, false); if (firstChunk) firstChunk = false; // all keys, aborted @@ -2016,7 +2015,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { // Check if the darkside attack can be used if (prng_type) { if (verbose) PrintAndLogEx(INFO, _YELLOW_("======================= START DARKSIDE ATTACK =======================")); - int isOK = mfDarkside(FirstBlockOfSector(blockNo), keyType, &key64); + isOK = mfDarkside(FirstBlockOfSector(blockNo), keyType, &key64); if (verbose) PrintAndLogEx(INFO, _YELLOW_("======================= STOP DARKSIDE ATTACK =======================")); switch (isOK) { case -1 : @@ -2508,7 +2507,7 @@ static int CmdHF14AMfChk_fast(const char *Cmd) { if (size == keycnt - i) lastChunk = true; - int res = mfCheckKeys_fast(sectorsCnt, firstChunk, lastChunk, strategy, size, keyBlock + (i * 6), e_sector, false); + res = mfCheckKeys_fast(sectorsCnt, firstChunk, lastChunk, strategy, size, keyBlock + (i * 6), e_sector, false); if (firstChunk) firstChunk = false; @@ -4310,10 +4309,8 @@ static int CmdHF14AMfice(const char *Cmd) { if (resp.oldarg[0]) goto out; uint32_t items = resp.oldarg[2]; - if (fnonces) { - fwrite(resp.data.asBytes, 1, items * 4, fnonces); - fflush(fnonces); - } + fwrite(resp.data.asBytes, 1, items * 4, fnonces); + fflush(fnonces); total_num_nonces += items; if (total_num_nonces > part_limit) { From 2cac27ed5372d5a536a62dd3407537492e670c3a Mon Sep 17 00:00:00 2001 From: danshuk Date: Mon, 6 Jan 2020 19:38:44 +0000 Subject: [PATCH 1400/1854] chg: lf pac sim *wip* --- armsrc/appmain.c | 2 +- client/cmdlfpac.c | 23 +++++++++++++---------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 20c26eb4d..4ed7f7dc3 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -780,7 +780,7 @@ static void PacketReceived(PacketCommandNG *packet) { } case CMD_LF_NRZ_SIMULATE: { lf_nrzsim_t *payload = (lf_nrzsim_t *)packet->data.asBytes; - CmdNRZsimTAG(payload->invert, payload->separator, payload->clock, packet->length - sizeof(lf_asksim_t), payload->data, true); + CmdNRZsimTAG(payload->invert, payload->separator, payload->clock, packet->length - sizeof(lf_nrzsim_t), payload->data, true); break; } case CMD_LF_HID_CLONE: { diff --git a/client/cmdlfpac.c b/client/cmdlfpac.c index 92a7f18ea..040c8af0a 100644 --- a/client/cmdlfpac.c +++ b/client/cmdlfpac.c @@ -51,7 +51,7 @@ static int usage_lf_pac_sim(void) { PrintAndLogEx(NORMAL, " : 8 byte PAC/Stanley card id"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " lf pac sim 1A337"); + PrintAndLogEx(NORMAL, " lf pac sim 12345678"); return PM3_SUCCESS; } // by danshuk @@ -245,20 +245,23 @@ static int CmdPacClone(const char *Cmd) { static int CmdPacSim(const char *Cmd) { // NRZ sim. - uint32_t id = 0; - uint64_t rawID = 0; + char cardid[9] = { 0 }; + uint8_t rawBytes[16] = { 0 }; + uint32_t rawBlocks[4]; char cmdp = tolower(param_getchar(Cmd, 0)); if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_pac_sim(); - id = param_get32ex(Cmd, 0, 0, 16); - if (id == 0) return usage_lf_pac_sim(); - - //rawID = pacCardIdToRaw(id); - - PrintAndLogEx(SUCCESS, "Simulating PAC/Stanley - ID " _YELLOW_("%08X")" raw "_YELLOW_("%08X%08X"), id, (uint32_t)(rawID >> 32), (uint32_t)(rawID & 0xFFFFFFFF)); + int res = param_getstr(Cmd, 0, cardid, sizeof(cardid)); + if (res < 8) return usage_lf_pac_sim(); uint8_t bs[128]; - num_to_bytebits(rawID, sizeof(bs), bs); + pacCardIdToRaw(rawBytes, cardid); + for (size_t i = 0; i < ARRAYLEN(rawBlocks); i++) { + rawBlocks[i] = bytes_to_num(rawBytes + (i * sizeof(uint32_t)), sizeof(uint32_t)); + num_to_bytebits(rawBlocks[i], sizeof(uint32_t) * 8, bs + (i * sizeof(uint32_t) * 8)); + } + + PrintAndLogEx(SUCCESS, "Simulating PAC/Stanley - ID " _YELLOW_("%s")" raw "_YELLOW_("%08X%08X%08X%08X"), cardid, rawBlocks[0], rawBlocks[1], rawBlocks[2], rawBlocks[3]); lf_nrzsim_t *payload = calloc(1, sizeof(lf_nrzsim_t) + sizeof(bs)); payload->invert = 0; From e9960ed0a039efd1ba002b2ad44b9889daccf21f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 7 Jan 2020 09:19:59 +0100 Subject: [PATCH 1401/1854] Fix: lf io sim/clone - now takes same input format (decimal/hex) as outputted --- client/cmdlfio.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/client/cmdlfio.c b/client/cmdlfio.c index 57a8a64d1..b640bed41 100644 --- a/client/cmdlfio.c +++ b/client/cmdlfio.c @@ -47,9 +47,9 @@ static int usage_lf_io_sim(void) { PrintAndLogEx(NORMAL, "Usage: lf io sim [h] "); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h : This help"); - PrintAndLogEx(NORMAL, " : 8bit version"); - PrintAndLogEx(NORMAL, " : 8bit value facility code"); - PrintAndLogEx(NORMAL, " : 16bit value card number"); + PrintAndLogEx(NORMAL, " : 8bit version (decimal)"); + PrintAndLogEx(NORMAL, " : 8bit value facility code (hex)"); + PrintAndLogEx(NORMAL, " : 16bit value card number (decimal)"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf io sim 26 101 1337"); @@ -63,9 +63,9 @@ static int usage_lf_io_clone(void) { PrintAndLogEx(NORMAL, "Usage: lf io clone [h] [Q5]"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h : This help"); - PrintAndLogEx(NORMAL, " : 8bit version"); - PrintAndLogEx(NORMAL, " : 8bit value facility code"); - PrintAndLogEx(NORMAL, " : 16bit value card number"); + PrintAndLogEx(NORMAL, " : 8bit version (decimal)"); + PrintAndLogEx(NORMAL, " : 8bit value facility code (hex)"); + PrintAndLogEx(NORMAL, " : 16bit value card number (decimal)"); PrintAndLogEx(NORMAL, " Q5 : optional - clone to Q5 (T5555) instead of T55x7 chip"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); @@ -197,7 +197,7 @@ static int CmdIOProxSim(const char *Cmd) { if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_io_sim(); version = param_get8(Cmd, 0); - fc = param_get8(Cmd, 1); + fc = param_get8ex(Cmd, 1, 0, 16); cn = param_get32ex(Cmd, 2, 0, 10); if (!version || !fc || !cn) return usage_lf_io_sim(); @@ -249,7 +249,7 @@ static int CmdIOProxClone(const char *Cmd) { if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_io_clone(); version = param_get8(Cmd, 0); - fc = param_get8(Cmd, 1); + fc = param_get8ex(Cmd, 1, 0, 16); cn = param_get32ex(Cmd, 2, 0, 10); if (!version || !fc || !cn) return usage_lf_io_clone(); From f7156e7485e03b22d9f8077caccd0a173328b28f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 7 Jan 2020 22:05:01 +0100 Subject: [PATCH 1402/1854] chg: adapted lfsampling, and swapped from 'silent' logic to the more natural 'verbose' logic --- armsrc/appmain.c | 6 +- armsrc/lfadc.c | 24 +++-- armsrc/lfops.c | 34 +++--- armsrc/lfsampling.c | 246 ++++++++++++++++++++++++++------------------ armsrc/lfsampling.h | 32 ++++-- client/cmddata.c | 12 +-- client/cmddata.h | 2 +- client/cmdhf15.c | 6 +- client/cmdlf.c | 32 +++--- client/cmdlf.h | 2 +- client/cmdlfcotag.c | 2 +- client/cmdlft55xx.c | 4 +- 12 files changed, 236 insertions(+), 166 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 20c26eb4d..a54967262 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -730,11 +730,11 @@ static void PacketReceived(PacketCommandNG *packet) { } case CMD_LF_ACQ_RAW_ADC: { struct p { - uint8_t silent; + uint8_t verbose; uint32_t samples; } PACKED; struct p *payload = (struct p *)packet->data.asBytes; - uint32_t bits = SampleLF(payload->silent, payload->samples); + uint32_t bits = SampleLF(payload->verbose, payload->samples); reply_ng(CMD_LF_ACQ_RAW_ADC, PM3_SUCCESS, (uint8_t *)&bits, sizeof(bits)); break; } @@ -1603,7 +1603,7 @@ static void PacketReceived(PacketCommandNG *packet) { BigBuf_Clear_ext(false); BigBuf_free(); } - + // 40 000 - (512-3) 509 = 39491 uint16_t offset = MIN(BIGBUF_SIZE - PM3_CMD_DATA_SIZE - 3, payload->offset); diff --git a/armsrc/lfadc.c b/armsrc/lfadc.c index c192087c4..a42fe8c52 100644 --- a/armsrc/lfadc.c +++ b/armsrc/lfadc.c @@ -61,7 +61,7 @@ size_t lf_count_edge_periods_ex(size_t max, bool wait, bool detect_gap) { adc_val = AT91C_BASE_SSC->SSC_RHR; periods++; - if (logging) logSample(adc_val, 1, 8, 0, 0); + if (logging) logSample(adc_val, 1, 8, 0); // Only test field changes if state of adc values matter if (!wait) { @@ -91,7 +91,7 @@ size_t lf_count_edge_periods_ex(size_t max, bool wait, bool detect_gap) { if (periods == max) return 0; } } - if (logging) logSample(255, 1, 8, 0, 0); + if (logging) logSample(255, 1, 8, 0); return 0; } @@ -168,7 +168,7 @@ void lf_init(bool reader) { AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; // Prepare data trace - if (logging) initSamplingBuffer(); + if (logging) initSamplingBuffer(NULL); } @@ -189,9 +189,21 @@ void lf_finalize() { size_t lf_detect_field_drop(size_t max) { size_t periods = 0; volatile uint8_t adc_val; + int16_t checked = 0; + + while (true) { + + // only every 1000th times, in order to save time when collecting samples. + if (checked == 1000) { + if (BUTTON_PRESS() || data_available()) { + checked = -1; + break; + } else { + checked = 0; + } + } + ++checked; - // usb check? - while (!BUTTON_PRESS()) { // Watchdog hit WDT_HIT(); @@ -199,7 +211,7 @@ size_t lf_detect_field_drop(size_t max) { periods++; adc_val = AT91C_BASE_SSC->SSC_RHR; - if (logging) logSample(adc_val, 1, 8, 0, 0); + if (logging) logSample(adc_val, 1, 8, 0); if (adc_val == 0) { rising_edge = false; diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 12cd82e43..ed23e75ea 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -473,7 +473,7 @@ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_ADC_READER_FIELD); // now do the read - DoAcquisition_config(false, 0); + DoAcquisition_config(true, 0); // Turn off antenna FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); @@ -1182,7 +1182,7 @@ static void nrzSimBit(uint8_t c, int *n, uint8_t clock) { *n += clock; } -// args clock, +// args clock, void CmdNRZsimTAG(uint8_t invert, uint8_t separator, uint8_t clk, uint16_t size, uint8_t *bits, bool ledcontrol) { FpgaDownloadAndGo(FPGA_BITSTREAM_LF); @@ -1198,7 +1198,7 @@ void CmdNRZsimTAG(uint8_t invert, uint8_t separator, uint8_t clk, uint16_t size, nrzSimBit(bits[i] ^ invert, &n, clk); } - if (bits[0] == bits[size - 1]) { //run a second set inverted (for ask/raw || biphase phase) + if (bits[0] == bits[size - 1]) { for (i = 0; i < size; i++) { nrzSimBit(bits[i] ^ invert ^ 1, &n, clk); } @@ -1239,7 +1239,7 @@ void CmdHIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol) WDT_HIT(); if (ledcontrol) LED_A_ON(); - DoAcquisition_default(-1, true); + DoAcquisition_default(-1, false); // FSK demodulator size = 50 * 128 * 2; //big enough to catch 2 sequences of largest format int idx = HIDdemodFSK(dest, &size, &hi2, &hi, &lo, &dummyIdx); @@ -1330,7 +1330,7 @@ void CmdAWIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol) WDT_HIT(); if (ledcontrol) LED_A_ON(); - DoAcquisition_default(-1, true); + DoAcquisition_default(-1, false); // FSK demodulator size = MIN(12800, BigBuf_max_traceLen()); @@ -1421,11 +1421,11 @@ void CmdEM410xdemod(int findone, uint32_t *high, uint64_t *low, int ledcontrol) WDT_HIT(); if (ledcontrol) LED_A_ON(); - DoAcquisition_default(-1, true); + DoAcquisition_default(-1, false); size = MIN(16385, BigBuf_max_traceLen()); - - //askdemod and manchester decode + + //askdemod and manchester decode int errCnt = askdemod(dest, &size, &clk, &invert, maxErr, 0, 1); WDT_HIT(); @@ -1486,10 +1486,10 @@ void CmdIOdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol) { WDT_HIT(); if (ledcontrol) LED_A_ON(); - DoAcquisition_default(-1, true); + DoAcquisition_default(-1, false); size = MIN(12000, BigBuf_max_traceLen()); - + //fskdemod and get start index int idx = detectIOProx(dest, &size, &dummyIdx); if (idx < 0) continue; @@ -1772,7 +1772,7 @@ void T55xxResetRead(uint8_t flags) { TurnReadLFOn(T55xx_Timing.m[downlink_mode].read_gap); // Acquisition - DoPartialAcquisition(0, true, BigBuf_max_traceLen(), 0); + DoPartialAcquisition(0, false, BigBuf_max_traceLen(), 0); // Turn the field off FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); @@ -1869,7 +1869,7 @@ void T55xxWriteBlock(uint8_t *data) { // response should be (for t55x7) a 0 bit then (ST if on) // block data written in on repeat until reset. - //DoPartialAcquisition(20, true, 12000); + //DoPartialAcquisition(20, false, 12000); } // turn field off FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); @@ -1930,7 +1930,7 @@ bool brute_mem = (flags & 0x0100) >> 8; // Acquisition // Now do the acquisition - DoPartialAcquisition(0, true, samples, 0); + DoPartialAcquisition(0, false, samples, 0); // Turn the field off if (!brute_mem) { @@ -1990,7 +1990,7 @@ void T55xxReadBlock(uint8_t page, bool pwd_mode, bool brute_mem, uint8_t block, // Acquisition // Now do the acquisition - DoPartialAcquisition(0, true, samples, 0); + DoPartialAcquisition(0, false, samples, 0); // Turn the field off if (!brute_mem) { @@ -2447,7 +2447,7 @@ void EM4xReadWord(uint8_t addr, uint32_t pwd, uint8_t usepwd) { WaitUS(400); - DoPartialAcquisition(20, true, 6000, 1000); + DoPartialAcquisition(20, false, 6000, 1000); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); reply_ng(CMD_LF_EM4X_READWORD, PM3_SUCCESS, NULL, 0); @@ -2480,7 +2480,7 @@ void EM4xWriteWord(uint8_t addr, uint32_t data, uint32_t pwd, uint8_t usepwd) { //Wait 20ms for write to complete? WaitMS(7); - DoPartialAcquisition(20, true, 6000, 1000); + DoPartialAcquisition(20, false, 6000, 1000); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); reply_ng(CMD_LF_EM4X_WRITEWORD, PM3_SUCCESS, NULL, 0); @@ -2550,7 +2550,7 @@ void Cotag(uint32_t arg0) { doCotagAcquisitionManchester(); break; case 2: - DoAcquisition_config(true, 0); + DoAcquisition_config(true, true); break; } diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index bdce67ef9..d836accfa 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -15,6 +15,7 @@ #include "dbprint.h" #include "util.h" #include "lfdemod.h" +#include "string.h" // memset /* Default LF config is set to: @@ -32,7 +33,7 @@ void printConfig() { uint32_t d = config.divisor; DbpString(_BLUE_("LF Sampling config")); Dbprintf(" [q] divisor.............%d ( "_GREEN_("%d.%02d kHz")")", d, 12000 / (d + 1), ((1200000 + (d + 1) / 2) / (d + 1)) - ((12000 / (d + 1)) * 100)); - Dbprintf(" [b] bps.................%d", config.bits_per_sample); + Dbprintf(" [b] bits per sample.....%d", config.bits_per_sample); Dbprintf(" [d] decimation..........%d", config.decimation); Dbprintf(" [a] averaging...........%s", (config.averaging) ? "Yes" : "No"); Dbprintf(" [t] trigger threshold...%d", config.trigger_threshold); @@ -69,12 +70,6 @@ sample_config *getSamplingConfig() { return &config; } -struct BitstreamOut { - uint8_t *buffer; - uint32_t numbits; - uint32_t position; -}; - /** * @brief Pushes bit onto the stream * @param stream @@ -88,6 +83,87 @@ void pushBit(BitstreamOut *stream, uint8_t bit) { stream->numbits++; } +// Holds bit packed struct of samples. +BitstreamOut data = {0, 0, 0}; + +// internal struct to keep track of samples gathered +sampling_t samples = {0, 0, 0, 0}; + +void initSampleBuffer(uint32_t *sample_size) { + + if (sample_size == NULL || *sample_size == 0) { + *sample_size = BigBuf_max_traceLen(); + } else { + *sample_size = MIN(*sample_size, BigBuf_max_traceLen()); + } + + // use a bitstream to handle the output + data.buffer = BigBuf_get_addr(); + + memset(data.buffer, 0, *sample_size); + + // + samples.dec_counter = 0; + samples.sum = 0; + samples.counter = 0; + samples.total_saved = 0; +} + +uint32_t getSampleCounter() { + return samples.total_saved; +} + +void logSample(uint8_t sample, uint8_t decimation, uint32_t bits_per_sample, bool avg) { + + if (!data.buffer) return; + + if (bits_per_sample == 0) bits_per_sample = 1; + if (bits_per_sample > 8) bits_per_sample = 8; + if (decimation == 0) decimation = 1; + + // keep track of total gather samples regardless how many was discarded. + samples.counter++; + + if (avg) { + samples.sum += sample; + } + + // check decimation + if (decimation > 1) { + samples.dec_counter++; + + if (samples.dec_counter < decimation) return; + + samples.dec_counter = 0; + } + + // averaging + if (avg && decimation > 1) { + sample = samples.sum / decimation; + samples.sum = 0; + } + + // store the sample + samples.total_saved++; + + if (bits_per_sample == 8) { + + data.buffer[samples.total_saved - 1] = sample; + + // add number of bits. + data.numbits = samples.total_saved << 3; + + } else { + pushBit(&data, sample & 0x80); + if (bits_per_sample > 1) pushBit(&data, sample & 0x40); + if (bits_per_sample > 2) pushBit(&data, sample & 0x20); + if (bits_per_sample > 3) pushBit(&data, sample & 0x10); + if (bits_per_sample > 4) pushBit(&data, sample & 0x08); + if (bits_per_sample > 5) pushBit(&data, sample & 0x04); + if (bits_per_sample > 6) pushBit(&data, sample & 0x02); + } +} + /** * Setup the FPGA to listen for samples. This method downloads the FPGA bitstream * if not already loaded, sets divisor and starts up the antenna. @@ -128,45 +204,39 @@ void LFSetupFPGAForADC(int divisor, bool lf_field) { * value that will be used is the average value of the three samples. * @param trigger_threshold - a threshold. The sampling won't commence until this threshold has been reached. Set * to -1 to ignore threshold. - * @param silent - is true, now outputs are made. If false, dbprints the status + * @param verbose - is true, dbprints the status, else no outputs * @return the number of bits occupied by the samples. */ -uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averaging, int trigger_threshold, bool silent, int bufsize, uint32_t cancel_after, uint32_t samples_to_skip) { +uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool avg, int trigger_threshold, + bool verbose, uint32_t sample_size, uint32_t cancel_after, uint32_t samples_to_skip) { - uint8_t *dest = BigBuf_get_addr(); - bufsize = (bufsize > 0 && bufsize < BigBuf_max_traceLen()) ? bufsize : BigBuf_max_traceLen(); + initSampleBuffer(&sample_size); - if (bits_per_sample < 1) bits_per_sample = 1; - if (bits_per_sample > 8) bits_per_sample = 8; - - if (decimation < 1) decimation = 1; - - // use a bit stream to handle the output - BitstreamOut data = { dest, 0, 0}; - int sample_counter = 0; - uint8_t sample; - - // if we want to do averaging - uint32_t sample_sum = 0 ; - uint32_t sample_total_numbers = 0; - uint32_t sample_total_saved = 0; uint32_t cancel_counter = 0; - - uint16_t checked = 0; + int16_t checked = 0; while (true) { + + // only every 1000th times, in order to save time when collecting samples. if (checked == 1000) { - if (BUTTON_PRESS() || data_available()) + if (BUTTON_PRESS() || data_available()) { + checked = -1; break; - else + } else { checked = 0; + } } ++checked; WDT_HIT(); + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { +// AT91C_BASE_SSC->SSC_THR = 0x43; + LED_D_ON(); + } + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + volatile uint8_t sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR; // Testpoint 8 (TP8) can be used to trigger oscilliscope LED_D_OFF(); @@ -188,57 +258,23 @@ uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averag continue; } - sample_total_numbers++; + logSample(sample, decimation, bits_per_sample, avg); - if (averaging) - sample_sum += sample; - - // check decimation - if (decimation > 1) { - sample_counter++; - if (sample_counter < decimation) continue; - sample_counter = 0; - } - - // averaging - if (averaging && decimation > 1) { - sample = sample_sum / decimation; - sample_sum = 0; - } - - // store the sample - sample_total_saved ++; - - if (bits_per_sample == 8) { - dest[sample_total_saved - 1] = sample; - - // Get the return value correct - data.numbits = sample_total_saved << 3; - if (sample_total_saved >= bufsize) break; - - } else { - pushBit(&data, sample & 0x80); - if (bits_per_sample > 1) pushBit(&data, sample & 0x40); - if (bits_per_sample > 2) pushBit(&data, sample & 0x20); - if (bits_per_sample > 3) pushBit(&data, sample & 0x10); - if (bits_per_sample > 4) pushBit(&data, sample & 0x08); - if (bits_per_sample > 5) pushBit(&data, sample & 0x04); - if (bits_per_sample > 6) pushBit(&data, sample & 0x02); - - if ((data.numbits >> 3) + 1 >= bufsize) break; - } + if (samples.total_saved >= sample_size) break; } } - if (!silent) { - Dbprintf("Done, saved " _YELLOW_("%d")"out of " _YELLOW_("%d")"seen samples at " _YELLOW_("%d")"bits/sample", sample_total_saved, sample_total_numbers, bits_per_sample); - Dbprintf("buffer samples: %02x %02x %02x %02x %02x %02x %02x %02x ...", - dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]); + if (checked == -1 && verbose) { + Dbprintf("lf sampling aborted"); + } + + if (verbose) { + Dbprintf("Done, saved " _YELLOW_("%d")"out of " _YELLOW_("%d")"seen samples at " _YELLOW_("%d")"bits/sample", samples.total_saved, samples.counter, bits_per_sample); } // Ensure that DC offset removal and noise check is performed for any device-side processing - removeSignalOffset(dest, bufsize); - computeSignalProperties(dest, bufsize); + removeSignalOffset(data.buffer, samples.total_saved); + computeSignalProperties(data.buffer, samples.total_saved); return data.numbits; } @@ -247,32 +283,33 @@ uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averag * This method is typically used by tag-specific readers who just wants to read the samples * the normal way * @param trigger_threshold - * @param silent + * @param verbose * @return number of bits sampled */ -uint32_t DoAcquisition_default(int trigger_threshold, bool silent) { - return DoAcquisition(1, 8, 0, trigger_threshold, silent, 0, 0, 0); +uint32_t DoAcquisition_default(int trigger_threshold, bool verbose) { + return DoAcquisition(1, 8, 0, trigger_threshold, verbose, 0, 0, 0); } -uint32_t DoAcquisition_config(bool silent, int sample_size) { +uint32_t DoAcquisition_config(bool verbose, uint32_t sample_size) { return DoAcquisition(config.decimation , config.bits_per_sample , config.averaging , config.trigger_threshold - , silent + , verbose , sample_size , 0 , config.samples_to_skip); } -uint32_t DoPartialAcquisition(int trigger_threshold, bool silent, int sample_size, uint32_t cancel_after) { - return DoAcquisition(1, 8, 0, trigger_threshold, silent, sample_size, cancel_after, 0); +uint32_t DoPartialAcquisition(int trigger_threshold, bool verbose, uint32_t sample_size, uint32_t cancel_after) { + return DoAcquisition(1, 8, 0, trigger_threshold, verbose, sample_size, cancel_after, 0); } -uint32_t ReadLF(bool activeField, bool silent, int sample_size) { - if (!silent) +uint32_t ReadLF(bool activeField, bool verbose, uint32_t sample_size) { + if (verbose) printConfig(); + LFSetupFPGAForADC(config.divisor, activeField); - uint32_t ret = DoAcquisition_config(silent, sample_size); + uint32_t ret = DoAcquisition_config(verbose, sample_size); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); return ret; } @@ -281,9 +318,9 @@ uint32_t ReadLF(bool activeField, bool silent, int sample_size) { * Initializes the FPGA for reader-mode (field on), and acquires the samples. * @return number of bits sampled **/ -uint32_t SampleLF(bool silent, int sample_size) { +uint32_t SampleLF(bool verbose, uint32_t sample_size) { BigBuf_Clear_ext(false); - return ReadLF(true, silent, sample_size); + return ReadLF(true, verbose, sample_size); } /** * Initializes the FPGA for sniffer-mode (field off), and acquires the samples. @@ -310,7 +347,7 @@ void doT55x7Acquisition(size_t sample_size) { if (bufsize > sample_size) bufsize = sample_size; - uint8_t curSample, lastSample = 0; + uint8_t lastSample = 0; uint16_t i = 0, skipCnt = 0; bool startFound = false; bool highFound = false; @@ -330,24 +367,24 @@ void doT55x7Acquisition(size_t sample_size) { WDT_HIT(); + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { + LED_D_ON(); + } if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - curSample = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + volatile uint8_t sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR; LED_D_OFF(); // skip until the first high sample above threshold - if (!startFound && curSample > T55xx_READ_UPPER_THRESHOLD) { - //if (curSample > lastSample) - // lastSample = curSample; + if (!startFound && sample > T55xx_READ_UPPER_THRESHOLD) { highFound = true; } else if (!highFound) { skipCnt++; continue; } // skip until the first low sample below threshold - if (!startFound && curSample < T55xx_READ_LOWER_THRESHOLD) { - //if (curSample > lastSample) - lastSample = curSample; + if (!startFound && sample < T55xx_READ_LOWER_THRESHOLD) { + lastSample = sample; lowFound = true; } else if (!lowFound) { skipCnt++; @@ -355,14 +392,14 @@ void doT55x7Acquisition(size_t sample_size) { } // skip until first high samples begin to change - if (startFound || curSample > T55xx_READ_LOWER_THRESHOLD + T55xx_READ_TOL) { + if (startFound || sample > T55xx_READ_LOWER_THRESHOLD + T55xx_READ_TOL) { // if just found start - recover last sample if (!startFound) { dest[i++] = lastSample; startFound = true; } // collect samples - dest[i++] = curSample; + dest[i++] = sample; } } } @@ -388,7 +425,7 @@ void doCotagAcquisition(size_t sample_size) { bufsize = sample_size; dest[0] = 0; - uint8_t sample, firsthigh = 0, firstlow = 0; + uint8_t firsthigh = 0, firstlow = 0; uint16_t i = 0; uint16_t noise_counter = 0; @@ -406,8 +443,12 @@ void doCotagAcquisition(size_t sample_size) { WDT_HIT(); + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { + LED_D_ON(); + } + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + volatile uint8_t sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR; // find first peak if (!firsthigh) { @@ -441,7 +482,6 @@ void doCotagAcquisition(size_t sample_size) { // Ensure that DC offset removal and noise check is performed for any device-side processing removeSignalOffset(dest, bufsize); computeSignalProperties(dest, bufsize); - } uint32_t doCotagAcquisitionManchester() { @@ -453,7 +493,7 @@ uint32_t doCotagAcquisitionManchester() { bufsize = COTAG_BITS; dest[0] = 0; - uint8_t sample, firsthigh = 0, firstlow = 0; + uint8_t firsthigh = 0, firstlow = 0; uint16_t sample_counter = 0, period = 0; uint8_t curr = 0, prev = 0; uint16_t noise_counter = 0; @@ -471,8 +511,12 @@ uint32_t doCotagAcquisitionManchester() { WDT_HIT(); + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { + LED_D_ON(); + } + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + volatile uint8_t sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR; // find first peak if (!firsthigh) { diff --git a/armsrc/lfsampling.h b/armsrc/lfsampling.h index 21968cdd2..8ccaa5579 100644 --- a/armsrc/lfsampling.h +++ b/armsrc/lfsampling.h @@ -4,7 +4,18 @@ #include "common.h" #include "pm3_cmd.h" -typedef struct BitstreamOut BitstreamOut; +typedef struct { + uint8_t *buffer; + uint32_t numbits; + uint32_t position; +} BitstreamOut; + +typedef struct { + int dec_counter; + uint32_t sum; + uint32_t counter; + uint32_t total_saved; +} sampling_t; /** * acquisition of Cotag LF signal. Similar to other LF, since the Cotag has such long datarate RF/384 @@ -23,7 +34,7 @@ void doT55x7Acquisition(size_t sample_size); * Initializes the FPGA for reader-mode (field on), and acquires the samples. * @return number of bits sampled **/ -uint32_t SampleLF(bool silent, int sample_size); +uint32_t SampleLF(bool verbose, uint32_t sample_size); /** * Initializes the FPGA for sniff-mode (field off), and acquires the samples. @@ -31,32 +42,35 @@ uint32_t SampleLF(bool silent, int sample_size); **/ uint32_t SniffLF(); +uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool avg, int trigger_threshold, + bool verbose, uint32_t sample_size, uint32_t cancel_after, uint32_t samples_to_skip); + // adds sample size to default options -uint32_t DoPartialAcquisition(int trigger_threshold, bool silent, int sample_size, uint32_t cancel_after); +uint32_t DoPartialAcquisition(int trigger_threshold, bool verbose, uint32_t sample_size, uint32_t cancel_after); /** * @brief Does sample acquisition, ignoring the config values set in the sample_config. * This method is typically used by tag-specific readers who just wants to read the samples * the normal way * @param trigger_threshold - * @param silent + * @param verbose * @return number of bits sampled */ -uint32_t DoAcquisition_default(int trigger_threshold, bool silent); +uint32_t DoAcquisition_default(int trigger_threshold, bool verbose); /** * @brief Does sample acquisition, using the config values set in the sample_config. * @param trigger_threshold - * @param silent + * @param verbose * @return number of bits sampled */ -uint32_t DoAcquisition_config(bool silent, int sample_size); +uint32_t DoAcquisition_config(bool verbose, uint32_t sample_size); /** * Refactoring of lf sampling buffer */ -void initSamplingBuffer(void); -void logSample(uint8_t sample, uint8_t decimation, uint32_t bits_per_sample, bool averaging, int trigger_threshold); +void initSamplingBuffer(uint32_t *sample_size); +void logSample(uint8_t sample, uint8_t decimation, uint32_t bits_per_sample, bool avg); uint32_t getSampleCounter(); /** diff --git a/client/cmddata.c b/client/cmddata.c index 0469bf837..ddd87fdb8 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -1589,7 +1589,7 @@ static uint8_t getByte(uint8_t bits_per_sample, BitstreamOut *b) { return val; } -int getSamples(uint32_t n, bool silent) { +int getSamples(uint32_t n, bool verbose) { //If we get all but the last byte in bigbuf, // we don't have to worry about remaining trash // in the last byte in case the bits-per-sample @@ -1599,7 +1599,7 @@ int getSamples(uint32_t n, bool silent) { if (n == 0 || n > sizeof(got)) n = sizeof(got); - if (!silent) PrintAndLogEx(NORMAL, "Reading %d bytes from device memory\n", n); + if (verbose) PrintAndLogEx(NORMAL, "Reading %d bytes from device memory\n", n); PacketResponseNG response; if (!GetFromDevice(BIG_BUF, got, n, 0, NULL, 0, &response, 10000, true)) { @@ -1607,20 +1607,20 @@ int getSamples(uint32_t n, bool silent) { return PM3_ETIMEOUT; } - if (!silent) PrintAndLogEx(NORMAL, "Data fetched"); + if (verbose) PrintAndLogEx(NORMAL, "Data fetched"); uint8_t bits_per_sample = 8; //Old devices without this feature would send 0 at arg[0] if (response.oldarg[0] > 0) { sample_config *sc = (sample_config *) response.data.asBytes; - if (!silent) PrintAndLogEx(NORMAL, "Samples @ %d bits/smpl, decimation 1:%d ", sc->bits_per_sample, sc->decimation); + if (verbose) PrintAndLogEx(NORMAL, "Samples @ %d bits/smpl, decimation 1:%d ", sc->bits_per_sample, sc->decimation); bits_per_sample = sc->bits_per_sample; } if (bits_per_sample < 8) { - if (!silent) PrintAndLogEx(NORMAL, "Unpacking..."); + if (verbose) PrintAndLogEx(NORMAL, "Unpacking..."); BitstreamOut bout = { got, bits_per_sample * n, 0}; int j = 0; @@ -1630,7 +1630,7 @@ int getSamples(uint32_t n, bool silent) { } GraphTraceLen = j; - if (!silent) PrintAndLogEx(NORMAL, "Unpacked %d samples", j); + if (verbose) PrintAndLogEx(NORMAL, "Unpacked %d samples", j); } else { for (int j = 0; j < n; j++) { diff --git a/client/cmddata.h b/client/cmddata.h index a4bba407c..a19bead27 100644 --- a/client/cmddata.h +++ b/client/cmddata.h @@ -68,7 +68,7 @@ void setDemodBuff(uint8_t *buff, size_t size, size_t start_idx); bool getDemodBuff(uint8_t *buff, size_t *size); void save_restoreDB(uint8_t saveOpt);// option '1' to save DemodBuffer any other to restore int AutoCorrelate(const int *in, int *out, size_t len, size_t window, bool SaveGrph, bool verbose); -int getSamples(uint32_t n, bool silent); +int getSamples(uint32_t n, bool verbose); void setClockGrid(uint32_t clk, int offset); int directionalThreshold(const int *in, int *out, size_t len, int8_t up, int8_t down); int AskEdgeDetect(const int *in, int *out, int len, int threshold); diff --git a/client/cmdhf15.c b/client/cmdhf15.c index 2e02aff68..9a5665a31 100644 --- a/client/cmdhf15.c +++ b/client/cmdhf15.c @@ -633,7 +633,7 @@ static int CmdHF15Samples(const char *Cmd) { clearCommandBuffer(); SendCommandNG(CMD_HF_ISO15693_ACQ_RAW_ADC, NULL, 0); - getSamples(0, false); + getSamples(0, true); return PM3_SUCCESS; } @@ -684,9 +684,9 @@ static int NxpSysInfo(uint8_t *uid) { return PM3_EWRONGANSVER; } - bool support_signature = (recv[5] & 0x01); + bool support_signature = (recv[5] & 0x01); bool support_easmode = (recv[4] & 0x03); - + PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, " NXP SYSINFO : %s", sprint_hex(recv, 8)); PrintAndLogEx(NORMAL, " Password protection configuration:"); diff --git a/client/cmdlf.c b/client/cmdlf.c index 7c454a7a0..64ff0ed9a 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -77,13 +77,13 @@ static int usage_lf_read(void) { PrintAndLogEx(NORMAL, "Usage: lf read [h] [s] [d numofsamples]"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h This help"); - PrintAndLogEx(NORMAL, " s silent run, no printout"); PrintAndLogEx(NORMAL, " d #samples # samples to collect (optional)"); + PrintAndLogEx(NORMAL, " s silent"); PrintAndLogEx(NORMAL, "Use 'lf config' to set parameters."); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " lf read s d 12000 - collects 12000samples silent"); - PrintAndLogEx(NORMAL, " lf read s"); + PrintAndLogEx(NORMAL, " lf read s d 12000 - collects 12000 samples silent"); + PrintAndLogEx(NORMAL, " lf read"); return PM3_SUCCESS; } static int usage_lf_sim(void) { @@ -367,7 +367,7 @@ int CmdLFCommandRead(const char *Cmd) { if (resp.status == PM3_SUCCESS) { if (i) { PrintAndLogEx(SUCCESS, "Downloading response signal data"); - getSamples(0, true); + getSamples(0, false); return PM3_SUCCESS; } else { PrintAndLogEx(WARNING, "timeout while waiting for reply."); @@ -552,16 +552,16 @@ int CmdLFConfig(const char *Cmd) { return lf_config(&config); } -int lf_read(bool silent, uint32_t samples) { +int lf_read(bool verbose, uint32_t samples) { if (!session.pm3_present) return PM3_ENOTTY; struct p { - uint8_t silent; + uint8_t verbose; uint32_t samples; } PACKED; struct p payload; - payload.silent = silent; + payload.verbose = verbose; payload.samples = samples; clearCommandBuffer(); @@ -579,7 +579,7 @@ int lf_read(bool silent, uint32_t samples) { // resp.oldarg[0] is bits read not bytes read. uint32_t bits = (resp.data.asDwords[0] / 8); - getSamples(bits, silent); + getSamples(bits, verbose); return PM3_SUCCESS; } @@ -589,21 +589,21 @@ int CmdLFRead(const char *Cmd) { if (!session.pm3_present) return PM3_ENOTTY; bool errors = false; - bool silent = false; + bool verbose = true; uint32_t samples = 0; uint8_t cmdp = 0; while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { case 'h': return usage_lf_read(); - case 's': - silent = true; - cmdp++; - break; case 'd': samples = param_get32ex(Cmd, cmdp + 1, 0, 10); cmdp += 2; break; + case 's': + verbose = false; + cmdp++; + break; default: PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); errors = true; @@ -614,7 +614,7 @@ int CmdLFRead(const char *Cmd) { //Validations if (errors) return usage_lf_read(); - return lf_read(silent, samples); + return lf_read(verbose, samples); } int CmdLFSniff(const char *Cmd) { @@ -627,7 +627,7 @@ int CmdLFSniff(const char *Cmd) { clearCommandBuffer(); SendCommandNG(CMD_LF_SNIFF_RAW_ADC, NULL, 0); WaitForResponse(CMD_ACK, NULL); - getSamples(0, false); + getSamples(0, true); return PM3_SUCCESS; } @@ -1183,7 +1183,7 @@ int CmdLFfind(const char *Cmd) { bool isOnline = (session.pm3_present && (cmdp != '1')); if (isOnline) - lf_read(true, 30000); + lf_read(false, 30000); if (GraphTraceLen < minLength) { PrintAndLogEx(FAILED, "Data in Graphbuffer was too small."); diff --git a/client/cmdlf.h b/client/cmdlf.h index 3f0670d1f..7393405ba 100644 --- a/client/cmdlf.h +++ b/client/cmdlf.h @@ -32,7 +32,7 @@ int CmdLFSniff(const char *Cmd); int CmdVchDemod(const char *Cmd); int CmdLFfind(const char *Cmd); -int lf_read(bool silent, uint32_t samples); +int lf_read(bool verbose, uint32_t samples); int lf_config(sample_config *config); #endif diff --git a/client/cmdlfcotag.c b/client/cmdlfcotag.c index 9c55bf453..abe78a4ea 100644 --- a/client/cmdlfcotag.c +++ b/client/cmdlfcotag.c @@ -96,7 +96,7 @@ static int CmdCOTAGRead(const char *Cmd) { case 2: { CmdPlot(""); CmdGrid("384"); - getSamples(0, true); + getSamples(0, false); break; } case 1: { diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index d992b6d58..f25626d94 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -2528,7 +2528,7 @@ bool AcquireData(uint8_t page, uint8_t block, bool pwdmode, uint32_t password, u return false; } - getSamples(12000, true); + getSamples(12000, false); return !getSignalProperties()->isnoise; } @@ -3485,7 +3485,7 @@ static int CmdT55xxDetectPage1(const char *Cmd) { found = AcquireData(T55x7_PAGE1, T55x7_TRACE_BLOCK1, usepwd, password, dl_mode); if (found == false) continue; - + if (tryDetectP1(false)) { found = true; found_mode = dl_mode; From 47eab16881d7e4fd0b98880d067f5ad9ebfefb5c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 7 Jan 2020 22:14:01 +0100 Subject: [PATCH 1403/1854] style --- client/emv/emvcore.c | 2 +- client/luascripts/calc_di.lua | 4 +- client/reveng/preset.c | 458 +++++++++++++++++----------------- common/mbedtls/camellia.c | 16 +- common/zlib/inflate.c | 4 +- 5 files changed, 242 insertions(+), 242 deletions(-) diff --git a/client/emv/emvcore.c b/client/emv/emvcore.c index 74b78f797..5bf330fe4 100644 --- a/client/emv/emvcore.c +++ b/client/emv/emvcore.c @@ -490,7 +490,7 @@ int EMVSearchPSE(EMVCommandChannel channel, bool ActivateField, bool LeaveFieldO for (uint8_t ui = 0x01; ui <= 0x10; ui++) { if (sfidatalen[ui]) { - + struct tlvdb *tsfi_a = tlvdb_parse_multi(sfidata[ui], sfidatalen[ui]); if (tsfi_a) { struct tlvdb *tsfitmp = tlvdb_find_path(tsfi_a, (tlv_tag_t[]) {0x70, 0x61, 0x00}); diff --git a/client/luascripts/calc_di.lua b/client/luascripts/calc_di.lua index 416a3dd0f..d2e712563 100644 --- a/client/luascripts/calc_di.lua +++ b/client/luascripts/calc_di.lua @@ -75,9 +75,9 @@ local function dumptofile(uid, keys) dbg('dumping keys to file') if utils.confirm('Do you wish to save the keys to dumpfile?') then - + local filename = ('hf-mf-%s-key.bin'):format(uid); - + local destination = utils.input('Select a filename to store to', filename) local file = io.open(destination, 'wb') if file == nil then diff --git a/client/reveng/preset.c b/client/reveng/preset.c index 1897ebcee..6f41ac9f5 100644 --- a/client/reveng/preset.c +++ b/client/reveng/preset.c @@ -137,19 +137,19 @@ static const bmp_t b40c[] = { # else /* BMP_BIT */ static const bmp_t b40[] = { BMP_C(0x00048200) << (BMP_BIT - 32) | BMP_C(0x04) >> (39 - BMP_BIT), - BMP_C(0x09) << (BMP_BIT * 2 - 40), + BMP_C(0x09) << (BMP_BIT * 2 - 40), }; static const bmp_t b40a[] = { BMP_C(0xffffffff) << (BMP_BIT - 32) | BMP_C(0x7f) >> (39 - BMP_BIT), - BMP_C(0xff) << (BMP_BIT * 2 - 40), + BMP_C(0xff) << (BMP_BIT * 2 - 40), }; static const bmp_t b40b[] = { BMP_C(0xd4164fc6) << (BMP_BIT - 32) | BMP_C(0x23) >> (39 - BMP_BIT), - BMP_C(0x46) << (BMP_BIT * 2 - 40), + BMP_C(0x46) << (BMP_BIT * 2 - 40), }; static const bmp_t b40c[] = { BMP_C(0xc4ff8071) << (BMP_BIT - 32) | BMP_C(0x7f) >> (39 - BMP_BIT), - BMP_C(0xff) << (BMP_BIT * 2 - 40), + BMP_C(0xff) << (BMP_BIT * 2 - 40), }; # endif /* BMP_BIT */ @@ -187,43 +187,43 @@ static const bmp_t b64i[] = { # else /* BMP_BIT */ static const bmp_t b64[] = { BMP_C(0x00000000) << (BMP_BIT - 32) | BMP_C(0x0000000d) >> (63 - BMP_BIT), - BMP_C(0x0000001b) << (BMP_BIT * 2 - 64), + BMP_C(0x0000001b) << (BMP_BIT * 2 - 64), }; static const bmp_t b64a[] = { BMP_C(0xffffffff) << (BMP_BIT - 32) | BMP_C(0x7fffffff) >> (63 - BMP_BIT), - BMP_C(0xffffffff) << (BMP_BIT * 2 - 64), + BMP_C(0xffffffff) << (BMP_BIT * 2 - 64), }; static const bmp_t b64b[] = { BMP_C(0xb90956c7) << (BMP_BIT - 32) | BMP_C(0x3ad20800) >> (63 - BMP_BIT), - BMP_C(0x75a41001) << (BMP_BIT * 2 - 64), + BMP_C(0x75a41001) << (BMP_BIT * 2 - 64), }; static const bmp_t b64c[] = { BMP_C(0x53000000) << (BMP_BIT - 32) | BMP_C(0x00000000) >> (63 - BMP_BIT), - BMP_C(0x00000000) << (BMP_BIT * 2 - 64), + BMP_C(0x00000000) << (BMP_BIT * 2 - 64), }; static const bmp_t b64d[] = { BMP_C(0x42f0e1eb) << (BMP_BIT - 32) | BMP_C(0x54f51b49) >> (63 - BMP_BIT), - BMP_C(0xa9ea3693) << (BMP_BIT * 2 - 64), + BMP_C(0xa9ea3693) << (BMP_BIT * 2 - 64), }; static const bmp_t b64e[] = { BMP_C(0x6c40df5f) << (BMP_BIT - 32) | BMP_C(0x05a4b9a3) >> (63 - BMP_BIT), - BMP_C(0x0b497347) << (BMP_BIT * 2 - 64), + BMP_C(0x0b497347) << (BMP_BIT * 2 - 64), }; static const bmp_t b64f[] = { BMP_C(0x62ec59e3) << (BMP_BIT - 32) | BMP_C(0x78d27805) >> (63 - BMP_BIT), - BMP_C(0xf1a4f00a) << (BMP_BIT * 2 - 64), + BMP_C(0xf1a4f00a) << (BMP_BIT * 2 - 64), }; static const bmp_t b64g[] = { BMP_C(0xfcacbebd) << (BMP_BIT - 32) | BMP_C(0x2c98d4c9) >> (63 - BMP_BIT), - BMP_C(0x5931a992) << (BMP_BIT * 2 - 64), + BMP_C(0x5931a992) << (BMP_BIT * 2 - 64), }; static const bmp_t b64h[] = { BMP_C(0x995dc9bb) << (BMP_BIT - 32) | BMP_C(0x6f8c9cfd) >> (63 - BMP_BIT), - BMP_C(0xdf1939fa) << (BMP_BIT * 2 - 64), + BMP_C(0xdf1939fa) << (BMP_BIT * 2 - 64), }; static const bmp_t b64i[] = { BMP_C(0x49958c9a) << (BMP_BIT - 32) | BMP_C(0x5ebe9a9f) >> (63 - BMP_BIT), - BMP_C(0xbd7d353f) << (BMP_BIT * 2 - 64), + BMP_C(0xbd7d353f) << (BMP_BIT * 2 - 64), }; # endif /* BMP_BIT */ @@ -237,22 +237,22 @@ static const bmp_t b82a[] = { # elif BMP_BIT >= 41 static const bmp_t b82[] = { BMP_C(0x01846008880) << (BMP_BIT - 41) | BMP_C(0x08a00a20208) >> (81 - BMP_BIT), - BMP_C(0x11401440411) << (BMP_BIT * 2 - 82), + BMP_C(0x11401440411) << (BMP_BIT * 2 - 82), }; static const bmp_t b82a[] = { BMP_C(0x04f541fb128) << (BMP_BIT - 41) | BMP_C(0x011c00feb09) >> (81 - BMP_BIT), - BMP_C(0x023801fd612) << (BMP_BIT * 2 - 82), + BMP_C(0x023801fd612) << (BMP_BIT * 2 - 82), }; # else /* BMP_BIT */ static const bmp_t b82[] = { BMP_C(0x0c230044) << (BMP_BIT - 32) | BMP_C(0x040) >> (40 - BMP_BIT), - BMP_C(0x40450051) << (BMP_BIT * 2 - 64) | BMP_C(0x00104) >> (80 - BMP_BIT * 2), - BMP_C(0x00411) << (BMP_BIT * 3 - 82), + BMP_C(0x40450051) << (BMP_BIT * 2 - 64) | BMP_C(0x00104) >> (80 - BMP_BIT * 2), + BMP_C(0x00411) << (BMP_BIT * 3 - 82), }; static const bmp_t b82a[] = { BMP_C(0x27aa0fd8) << (BMP_BIT - 32) | BMP_C(0x094) >> (40 - BMP_BIT), - BMP_C(0x9408e007) << (BMP_BIT * 2 - 64) | BMP_C(0x0f584) >> (80 - BMP_BIT * 2), - BMP_C(0x3d612) << (BMP_BIT * 3 - 82), + BMP_C(0x9408e007) << (BMP_BIT * 2 - 64) | BMP_C(0x0f584) >> (80 - BMP_BIT * 2), + BMP_C(0x3d612) << (BMP_BIT * 3 - 82), }; # endif /* BMP_BIT */ @@ -262,215 +262,215 @@ static const bmp_t b82a[] = { /* Array of the polynomial bitmaps used in the model table. */ static const bmp_t b32[] = { BMP_C(0x000000af) << (BMP_BIT - 32), /* 0 -- 32,000000af */ - BMP_C(0x00010000) << (BMP_BIT - 32), /* 1 -- 16, 0001 */ - BMP_C(0x00020000) << (BMP_BIT - 32), /* 2 -- 15, 0001 */ - BMP_C(0x00065b00) << (BMP_BIT - 32), /* 3 -- 24, 00065b */ - BMP_C(0x007e0000) << (BMP_BIT - 32), /* 4 -- 16, 007e */ - BMP_C(0x007f0000) << (BMP_BIT - 32), /* 5 -- 16, 007f */ - BMP_C(0x03400000) << (BMP_BIT - 32), /* 6 -- 11, 01a */ - BMP_C(0x0376e6e7) << (BMP_BIT - 32), /* 7 -- 32,0376e6e7 */ - BMP_C(0x04c11db7) << (BMP_BIT - 32), /* 8 -- 32,04c11db7 */ - BMP_C(0x05890000) << (BMP_BIT - 32), /* 9 -- 16, 0589 */ - BMP_C(0x07000000) << (BMP_BIT - 32), /* 10 -- 8, 07 */ - BMP_C(0x080b0000) << (BMP_BIT - 32), /* 11 -- 16, 080b */ - BMP_C(0x09823b6e) << (BMP_BIT - 32), /* 12 -- 31,04c11db7 */ - BMP_C(0x0b3c0000) << (BMP_BIT - 32), /* 13 -- 15, 059e */ - BMP_C(0x0c000000) << (BMP_BIT - 32), /* 14 -- 6, 03 */ - BMP_C(0x0c200000) << (BMP_BIT - 32), /* 15 -- 11, 061 */ - BMP_C(0x0c780000) << (BMP_BIT - 32), /* 16 -- 14, 031e */ - BMP_C(0x0fb30000) << (BMP_BIT - 32), /* 17 -- 16, 0fb3 */ - BMP_C(0x10210000) << (BMP_BIT - 32), /* 18 -- 16, 1021 */ - BMP_C(0x12000000) << (BMP_BIT - 32), /* 19 -- 7, 09 */ - BMP_C(0x130d2afc) << (BMP_BIT - 32), /* 20 -- 30,04c34abf */ - BMP_C(0x144e6300) << (BMP_BIT - 32), /* 21 -- 24, 144e63 */ - BMP_C(0x15000000) << (BMP_BIT - 32), /* 22 -- 8, 15 */ - BMP_C(0x1697d06a) << (BMP_BIT - 32), /* 23 -- 32,1697d06a */ - BMP_C(0x17800000) << (BMP_BIT - 32), /* 24 -- 12, 178 */ - BMP_C(0x18000000) << (BMP_BIT - 32), /* 25 -- 6, 06 */ - BMP_C(0x19d3c8d8) << (BMP_BIT - 32), /* 26 -- 31,0ce9e46c */ - BMP_C(0x1c000000) << (BMP_BIT - 32), /* 27 -- 6, 07 */ - BMP_C(0x1d000000) << (BMP_BIT - 32), /* 28 -- 8, 1d */ - BMP_C(0x1d0f0000) << (BMP_BIT - 32), /* 29 -- 16, 1d0f */ - BMP_C(0x1dcf0000) << (BMP_BIT - 32), /* 30 -- 16, 1dcf */ - BMP_C(0x1edc6f41) << (BMP_BIT - 32), /* 31 -- 32,1edc6f41 */ - BMP_C(0x1f23b800) << (BMP_BIT - 32), /* 32 -- 24, 1f23b8 */ - BMP_C(0x20000000) << (BMP_BIT - 32), /* 33 -- 4, 2 */ - BMP_C(0x200fa500) << (BMP_BIT - 32), /* 34 -- 24, 200fa5 */ - BMP_C(0x20140000) << (BMP_BIT - 32), /* 35 -- 14, 0805 */ - BMP_C(0x20b40000) << (BMP_BIT - 32), /* 36 -- 14, 082d */ - BMP_C(0x20fe0000) << (BMP_BIT - 32), /* 37 -- 16, 20fe */ - BMP_C(0x21890000) << (BMP_BIT - 32), /* 38 -- 16, 2189 */ - BMP_C(0x21cf0200) << (BMP_BIT - 32), /* 39 -- 24, 21cf02 */ - BMP_C(0x23ef5200) << (BMP_BIT - 32), /* 40 -- 24, 23ef52 */ - BMP_C(0x25000000) << (BMP_BIT - 32), /* 41 -- 8, 25 */ - BMP_C(0x26000000) << (BMP_BIT - 32), /* 42 -- 8, 26 */ - BMP_C(0x26b10000) << (BMP_BIT - 32), /* 43 -- 16, 26b1 */ - BMP_C(0x27818000) << (BMP_BIT - 32), /* 44 -- 17, 04f03 */ - BMP_C(0x27d00000) << (BMP_BIT - 32), /* 45 -- 13, 04fa */ - BMP_C(0x28000000) << (BMP_BIT - 32), /* 46 -- 5, 05 */ - BMP_C(0x29b10000) << (BMP_BIT - 32), /* 47 -- 16, 29b1 */ - BMP_C(0x2f000000) << (BMP_BIT - 32), /* 48 -- 8, 2f */ - BMP_C(0x30000000) << (BMP_BIT - 32), /* 49 -- 4, 3/ 5, 6 */ - BMP_C(0x3010bf7f) << (BMP_BIT - 32), /* 50 -- 32,3010bf7f */ - BMP_C(0x31000000) << (BMP_BIT - 32), /* 51 -- 8, 31 */ - BMP_C(0x31800000) << (BMP_BIT - 32), /* 52 -- 10, 0c6 */ - BMP_C(0x31c30000) << (BMP_BIT - 32), /* 53 -- 16, 31c3 */ - BMP_C(0x328b6300) << (BMP_BIT - 32), /* 54 -- 24, 328b63 */ - BMP_C(0x34000000) << (BMP_BIT - 32), /* 55 -- 6, 0d */ - BMP_C(0x340bc6d9) << (BMP_BIT - 32), /* 56 -- 32,340bc6d9 */ - BMP_C(0x37000000) << (BMP_BIT - 32), /* 57 -- 8, 37 */ - BMP_C(0x38000000) << (BMP_BIT - 32), /* 58 -- 5, 07 */ - BMP_C(0x39000000) << (BMP_BIT - 32), /* 59 -- 8, 39 */ - BMP_C(0x3d650000) << (BMP_BIT - 32), /* 60 -- 16, 3d65 */ - BMP_C(0x3e000000) << (BMP_BIT - 32), /* 61 -- 8, 3e */ - BMP_C(0x40000000) << (BMP_BIT - 32), /* 62 -- 3, 2 */ - BMP_C(0x42000000) << (BMP_BIT - 32), /* 63 -- 8, 42 */ - BMP_C(0x44c20000) << (BMP_BIT - 32), /* 64 -- 16, 44c2 */ - BMP_C(0x45270551) << (BMP_BIT - 32), /* 65 -- 32,45270551 */ - BMP_C(0x48000000) << (BMP_BIT - 32), /* 66 -- 5, 09 */ - BMP_C(0x49000000) << (BMP_BIT - 32), /* 67 -- 8, 49 */ - BMP_C(0x4a800000) << (BMP_BIT - 32), /* 68 -- 10, 12a */ - BMP_C(0x4acc0000) << (BMP_BIT - 32), /* 69 -- 15, 2566 */ - BMP_C(0x4b000000) << (BMP_BIT - 32), /* 70 -- 8, 4b */ - BMP_C(0x4b370000) << (BMP_BIT - 32), /* 71 -- 16, 4b37 */ - BMP_C(0x4c000000) << (BMP_BIT - 32), /* 72 -- 6, 13 */ - BMP_C(0x4c060000) << (BMP_BIT - 32), /* 73 -- 16, 4c06 */ - BMP_C(0x53000000) << (BMP_BIT - 32), /* 74 -- 8, 53 */ - BMP_C(0x55000000) << (BMP_BIT - 32), /* 75 -- 8, 55 */ - BMP_C(0x55555500) << (BMP_BIT - 32), /* 76 -- 24, 555555 */ - BMP_C(0x59350000) << (BMP_BIT - 32), /* 77 -- 16, 5935 */ - BMP_C(0x5d380000) << (BMP_BIT - 32), /* 78 -- 16, 5d38 */ - BMP_C(0x5d400000) << (BMP_BIT - 32), /* 79 -- 10, 175 */ - BMP_C(0x5d6dcb00) << (BMP_BIT - 32), /* 80 -- 24, 5d6dcb */ - BMP_C(0x60000000) << (BMP_BIT - 32), /* 81 -- 3, 3 */ - BMP_C(0x60e00000) << (BMP_BIT - 32), /* 82 -- 11, 307 */ - BMP_C(0x63d00000) << (BMP_BIT - 32), /* 83 -- 16, 63d0 */ - BMP_C(0x64000000) << (BMP_BIT - 32), /* 84 -- 6, 19 */ - BMP_C(0x66400000) << (BMP_BIT - 32), /* 85 -- 10, 199 */ - BMP_C(0x66c50000) << (BMP_BIT - 32), /* 86 -- 16, 66c5 */ - BMP_C(0x6f630000) << (BMP_BIT - 32), /* 87 -- 16, 6f63 */ - BMP_C(0x6f910000) << (BMP_BIT - 32), /* 88 -- 16, 6f91 */ - BMP_C(0x70000000) << (BMP_BIT - 32), /* 89 -- 4, 7 */ - BMP_C(0x70a00000) << (BMP_BIT - 32), /* 90 -- 11, 385 */ - BMP_C(0x755b0000) << (BMP_BIT - 32), /* 91 -- 16, 755b */ - BMP_C(0x765e7680) << (BMP_BIT - 32), /* 92 -- 32,765e7680 */ - BMP_C(0x76c20800) << (BMP_BIT - 32), /* 93 -- 32, 0ed841 */ - BMP_C(0x7979bd00) << (BMP_BIT - 32), /* 94 -- 24, 7979bd */ - BMP_C(0x7e000000) << (BMP_BIT - 32), /* 95 -- 8, 7e */ - BMP_C(0x80000000) << (BMP_BIT - 32), /* 96 -- 3, 4 */ - BMP_C(0x80006300) << (BMP_BIT - 32), /* 97 -- 24, 800063 */ - BMP_C(0x80050000) << (BMP_BIT - 32), /* 98 -- 16, 8005 */ - BMP_C(0x800d0000) << (BMP_BIT - 32), /* 99 -- 16, 800d */ - BMP_C(0x800fe300) << (BMP_BIT - 32), /* 100 -- 24, 800fe3 */ - BMP_C(0x80b40000) << (BMP_BIT - 32), /* 101 -- 14, 202d */ - BMP_C(0x80c2e71c) << (BMP_BIT - 32), /* 102 -- 30,2030b9c7 */ - BMP_C(0x80f00000) << (BMP_BIT - 32), /* 103 -- 12, 80f */ - BMP_C(0x814141ab) << (BMP_BIT - 32), /* 104 -- 32,814141ab */ - BMP_C(0x8144c800) << (BMP_BIT - 32), /* 105 -- 21, 102899 */ - BMP_C(0x864cfb00) << (BMP_BIT - 32), /* 106 -- 24, 864cfb */ - BMP_C(0x87315576) << (BMP_BIT - 32), /* 107 -- 32,87315576 */ - BMP_C(0x89ec0000) << (BMP_BIT - 32), /* 108 -- 16, 89ec */ - BMP_C(0x8a000000) << (BMP_BIT - 32), /* 109 -- 7, 45 */ - BMP_C(0x8b320000) << (BMP_BIT - 32), /* 110 -- 15, 4599 */ - BMP_C(0x8bb70000) << (BMP_BIT - 32), /* 111 -- 16, 8bb7 */ - BMP_C(0x8cc00000) << (BMP_BIT - 32), /* 112 -- 10, 233 */ - BMP_C(0x904cddbf) << (BMP_BIT - 32), /* 113 -- 32,904cddbf */ - BMP_C(0x906e0000) << (BMP_BIT - 32), /* 114 -- 16, 906e */ - BMP_C(0x94000000) << (BMP_BIT - 32), /* 115 -- 8, 94 */ - BMP_C(0x97000000) << (BMP_BIT - 32), /* 116 -- 8, 97 */ - BMP_C(0x98000000) << (BMP_BIT - 32), /* 117 -- 6, 26 */ - BMP_C(0x99000000) << (BMP_BIT - 32), /* 118 -- 8, 99 */ - BMP_C(0x9b000000) << (BMP_BIT - 32), /* 119 -- 8, 9b */ - BMP_C(0x9c000000) << (BMP_BIT - 32), /* 120 -- 6, 27 */ - BMP_C(0x9d5e4de2) << (BMP_BIT - 32), /* 121 -- 31,4eaf26f1 */ - BMP_C(0x9e000000) << (BMP_BIT - 32), /* 122 -- 7, 4f */ - BMP_C(0x9ecf0000) << (BMP_BIT - 32), /* 123 -- 16, 9ecf */ - BMP_C(0xa0660000) << (BMP_BIT - 32), /* 124 -- 16, a066 */ - BMP_C(0xa0970000) << (BMP_BIT - 32), /* 125 -- 16, a097 */ - BMP_C(0xa1000000) << (BMP_BIT - 32), /* 126 -- 8, a1 */ - BMP_C(0xa3660000) << (BMP_BIT - 32), /* 127 -- 16, a366 */ - BMP_C(0xa6000000) << (BMP_BIT - 32), /* 128 -- 7, 53 */ - BMP_C(0xa7000000) << (BMP_BIT - 32), /* 129 -- 8, a7 */ - BMP_C(0xa8000000) << (BMP_BIT - 32), /* 130 -- 5, 15 */ - BMP_C(0xa8190000) << (BMP_BIT - 32), /* 131 -- 16, a819 */ - BMP_C(0xa833982b) << (BMP_BIT - 32), /* 132 -- 32,a833982b */ - BMP_C(0xabcdef00) << (BMP_BIT - 32), /* 133 -- 24, abcdef */ - BMP_C(0xac000000) << (BMP_BIT - 32), /* 134 -- 8, ac */ - BMP_C(0xaee70000) << (BMP_BIT - 32), /* 135 -- 16, aee7 */ - BMP_C(0xb0000000) << (BMP_BIT - 32), /* 136 -- 4, b */ - BMP_C(0xb0010000) << (BMP_BIT - 32), /* 137 -- 16, b001 */ - BMP_C(0xb2aa0000) << (BMP_BIT - 32), /* 138 -- 16, b2aa */ - BMP_C(0xb3400000) << (BMP_BIT - 32), /* 139 -- 12, b34 */ - BMP_C(0xb42d8000) << (BMP_BIT - 32), /* 140 -- 17, 1685b */ - BMP_C(0xb4600000) << (BMP_BIT - 32), /* 141 -- 11, 5a3 */ - BMP_C(0xb4c80000) << (BMP_BIT - 32), /* 142 -- 16, b4c8 */ - BMP_C(0xb4f3e600) << (BMP_BIT - 32), /* 143 -- 24, b4f3e6 */ - BMP_C(0xb704ce00) << (BMP_BIT - 32), /* 144 -- 24, b704ce */ - BMP_C(0xb798b438) << (BMP_BIT - 32), /* 145 -- 32,b798b438 */ - BMP_C(0xbb3d0000) << (BMP_BIT - 32), /* 146 -- 16, bb3d */ - BMP_C(0xbc000000) << (BMP_BIT - 32), /* 147 -- 6,2f/ 8,bc */ - BMP_C(0xbd0be338) << (BMP_BIT - 32), /* 148 -- 32,bd0be338 */ - BMP_C(0xbdf40000) << (BMP_BIT - 32), /* 149 -- 16, bdf4 */ - BMP_C(0xbf050000) << (BMP_BIT - 32), /* 150 -- 16, bf05 */ - BMP_C(0xc0000000) << (BMP_BIT - 32), /* 151 -- 3, 6 */ - BMP_C(0xc2000000) << (BMP_BIT - 32), /* 152 -- 7, 61 */ - BMP_C(0xc25a5600) << (BMP_BIT - 32), /* 153 -- 24, c25a56 */ - BMP_C(0xc2b70000) << (BMP_BIT - 32), /* 154 -- 16, c2b7 */ - BMP_C(0xc2b80000) << (BMP_BIT - 32), /* 155 -- 14, 30ae */ - BMP_C(0xc4000000) << (BMP_BIT - 32), /* 156 -- 8, c4 */ - BMP_C(0xc6c60000) << (BMP_BIT - 32), /* 157 -- 16, c6c6 */ - BMP_C(0xc7000000) << (BMP_BIT - 32), /* 158 -- 8, c7 */ - BMP_C(0xc704dd7b) << (BMP_BIT - 32), /* 159 -- 32,c704dd7b */ - BMP_C(0xc8000000) << (BMP_BIT - 32), /* 160 -- 5, 19 */ - BMP_C(0xc8670000) << (BMP_BIT - 32), /* 161 -- 16, c867 */ - BMP_C(0xcbf43926) << (BMP_BIT - 32), /* 162 -- 32,cbf43926 */ - BMP_C(0xcde70300) << (BMP_BIT - 32), /* 163 -- 24, cde703 */ - BMP_C(0xce3c0000) << (BMP_BIT - 32), /* 164 -- 16, ce3c */ - BMP_C(0xd0000000) << (BMP_BIT - 32), /* 165 -- 8, d0 */ - BMP_C(0xd02a0000) << (BMP_BIT - 32), /* 166 -- 15, 6815 */ - BMP_C(0xd0db0000) << (BMP_BIT - 32), /* 167 -- 16, d0db */ - BMP_C(0xd3100000) << (BMP_BIT - 32), /* 168 -- 12, d31 */ - BMP_C(0xd3be9568) << (BMP_BIT - 32), /* 169 -- 30,34efa55a */ - BMP_C(0xd4d00000) << (BMP_BIT - 32), /* 170 -- 12, d4d */ - BMP_C(0xd5000000) << (BMP_BIT - 32), /* 171 -- 8, d5 */ - BMP_C(0xd64e0000) << (BMP_BIT - 32), /* 172 -- 16, d64e */ - BMP_C(0xda000000) << (BMP_BIT - 32), /* 173 -- 8, da */ - BMP_C(0xdaf00000) << (BMP_BIT - 32), /* 174 -- 12, daf */ - BMP_C(0xdebb20e3) << (BMP_BIT - 32), /* 175 -- 32,debb20e3 */ - BMP_C(0xdf000000) << (BMP_BIT - 32), /* 176 -- 8, df */ - BMP_C(0xe0000000) << (BMP_BIT - 32), /* 177 -- 3, 7 */ - BMP_C(0xe3069283) << (BMP_BIT - 32), /* 178 -- 32,e3069283 */ - BMP_C(0xe3940000) << (BMP_BIT - 32), /* 179 -- 16, e394 */ - BMP_C(0xe5cc0000) << (BMP_BIT - 32), /* 180 -- 16, e5cc */ - BMP_C(0xe7a80000) << (BMP_BIT - 32), /* 181 -- 13, 1cf5 */ - BMP_C(0xe8000000) << (BMP_BIT - 32), /* 182 -- 6, 3a */ - BMP_C(0xea000000) << (BMP_BIT - 32), /* 183 -- 7, 75 */ - BMP_C(0xea820000) << (BMP_BIT - 32), /* 184 -- 16, ea82 */ - BMP_C(0xec000000) << (BMP_BIT - 32), /* 185 -- 6, 3b */ - BMP_C(0xf0000000) << (BMP_BIT - 32), /* 186 -- 4, f */ - BMP_C(0xf0b80000) << (BMP_BIT - 32), /* 187 -- 16, f0b8 */ - BMP_C(0xf1300000) << (BMP_BIT - 32), /* 188 -- 12, f13 */ - BMP_C(0xf4000000) << (BMP_BIT - 32), /* 189 -- 8, f4 */ - BMP_C(0xf4acfb13) << (BMP_BIT - 32), /* 190 -- 32,f4acfb13 */ - BMP_C(0xf5b00000) << (BMP_BIT - 32), /* 191 -- 12, f5b */ - BMP_C(0xf6400000) << (BMP_BIT - 32), /* 192 -- 10, 3d9 */ - BMP_C(0xf7000000) << (BMP_BIT - 32), /* 193 -- 8, f7 */ - BMP_C(0xf8000000) << (BMP_BIT - 32), /* 194 -- 5, 1f */ - BMP_C(0xfc000000) << (BMP_BIT - 32), /* 195 -- 6, 3f */ - BMP_C(0xfc891918) << (BMP_BIT - 32), /* 196 -- 32,fc891918 */ - BMP_C(0xfd000000) << (BMP_BIT - 32), /* 197 -- 8, fd */ - BMP_C(0xfe000000) << (BMP_BIT - 32), /* 198 -- 7, 7f */ - BMP_C(0xfedcba00) << (BMP_BIT - 32), /* 199 -- 24, fedcba */ - BMP_C(0xfee80000) << (BMP_BIT - 32), /* 200 -- 16, fee8 */ - BMP_C(0xff000000) << (BMP_BIT - 32), /* 201 -- 8, ff */ - BMP_C(0xffc00000) << (BMP_BIT - 32), /* 202 -- 10, 3ff */ - BMP_C(0xfff00000) << (BMP_BIT - 32), /* 203 -- 12, fff */ - BMP_C(0xfffc0000) << (BMP_BIT - 32), /* 204 -- 14, 3fff */ - BMP_C(0xffff0000) << (BMP_BIT - 32), /* 205 -- 16, ffff */ - BMP_C(0xffffff00) << (BMP_BIT - 32), /* 206 -- 24, ffffff */ - BMP_C(0xfffffffc) << (BMP_BIT - 32), /* 207 -- 30,3fffffff */ - BMP_C(0xfffffffe) << (BMP_BIT - 32), /* 208 -- 31,7fffffff */ - BMP_C(0xffffffff) << (BMP_BIT - 32), /* 209 -- 32,ffffffff */ + BMP_C(0x00010000) << (BMP_BIT - 32), /* 1 -- 16, 0001 */ + BMP_C(0x00020000) << (BMP_BIT - 32), /* 2 -- 15, 0001 */ + BMP_C(0x00065b00) << (BMP_BIT - 32), /* 3 -- 24, 00065b */ + BMP_C(0x007e0000) << (BMP_BIT - 32), /* 4 -- 16, 007e */ + BMP_C(0x007f0000) << (BMP_BIT - 32), /* 5 -- 16, 007f */ + BMP_C(0x03400000) << (BMP_BIT - 32), /* 6 -- 11, 01a */ + BMP_C(0x0376e6e7) << (BMP_BIT - 32), /* 7 -- 32,0376e6e7 */ + BMP_C(0x04c11db7) << (BMP_BIT - 32), /* 8 -- 32,04c11db7 */ + BMP_C(0x05890000) << (BMP_BIT - 32), /* 9 -- 16, 0589 */ + BMP_C(0x07000000) << (BMP_BIT - 32), /* 10 -- 8, 07 */ + BMP_C(0x080b0000) << (BMP_BIT - 32), /* 11 -- 16, 080b */ + BMP_C(0x09823b6e) << (BMP_BIT - 32), /* 12 -- 31,04c11db7 */ + BMP_C(0x0b3c0000) << (BMP_BIT - 32), /* 13 -- 15, 059e */ + BMP_C(0x0c000000) << (BMP_BIT - 32), /* 14 -- 6, 03 */ + BMP_C(0x0c200000) << (BMP_BIT - 32), /* 15 -- 11, 061 */ + BMP_C(0x0c780000) << (BMP_BIT - 32), /* 16 -- 14, 031e */ + BMP_C(0x0fb30000) << (BMP_BIT - 32), /* 17 -- 16, 0fb3 */ + BMP_C(0x10210000) << (BMP_BIT - 32), /* 18 -- 16, 1021 */ + BMP_C(0x12000000) << (BMP_BIT - 32), /* 19 -- 7, 09 */ + BMP_C(0x130d2afc) << (BMP_BIT - 32), /* 20 -- 30,04c34abf */ + BMP_C(0x144e6300) << (BMP_BIT - 32), /* 21 -- 24, 144e63 */ + BMP_C(0x15000000) << (BMP_BIT - 32), /* 22 -- 8, 15 */ + BMP_C(0x1697d06a) << (BMP_BIT - 32), /* 23 -- 32,1697d06a */ + BMP_C(0x17800000) << (BMP_BIT - 32), /* 24 -- 12, 178 */ + BMP_C(0x18000000) << (BMP_BIT - 32), /* 25 -- 6, 06 */ + BMP_C(0x19d3c8d8) << (BMP_BIT - 32), /* 26 -- 31,0ce9e46c */ + BMP_C(0x1c000000) << (BMP_BIT - 32), /* 27 -- 6, 07 */ + BMP_C(0x1d000000) << (BMP_BIT - 32), /* 28 -- 8, 1d */ + BMP_C(0x1d0f0000) << (BMP_BIT - 32), /* 29 -- 16, 1d0f */ + BMP_C(0x1dcf0000) << (BMP_BIT - 32), /* 30 -- 16, 1dcf */ + BMP_C(0x1edc6f41) << (BMP_BIT - 32), /* 31 -- 32,1edc6f41 */ + BMP_C(0x1f23b800) << (BMP_BIT - 32), /* 32 -- 24, 1f23b8 */ + BMP_C(0x20000000) << (BMP_BIT - 32), /* 33 -- 4, 2 */ + BMP_C(0x200fa500) << (BMP_BIT - 32), /* 34 -- 24, 200fa5 */ + BMP_C(0x20140000) << (BMP_BIT - 32), /* 35 -- 14, 0805 */ + BMP_C(0x20b40000) << (BMP_BIT - 32), /* 36 -- 14, 082d */ + BMP_C(0x20fe0000) << (BMP_BIT - 32), /* 37 -- 16, 20fe */ + BMP_C(0x21890000) << (BMP_BIT - 32), /* 38 -- 16, 2189 */ + BMP_C(0x21cf0200) << (BMP_BIT - 32), /* 39 -- 24, 21cf02 */ + BMP_C(0x23ef5200) << (BMP_BIT - 32), /* 40 -- 24, 23ef52 */ + BMP_C(0x25000000) << (BMP_BIT - 32), /* 41 -- 8, 25 */ + BMP_C(0x26000000) << (BMP_BIT - 32), /* 42 -- 8, 26 */ + BMP_C(0x26b10000) << (BMP_BIT - 32), /* 43 -- 16, 26b1 */ + BMP_C(0x27818000) << (BMP_BIT - 32), /* 44 -- 17, 04f03 */ + BMP_C(0x27d00000) << (BMP_BIT - 32), /* 45 -- 13, 04fa */ + BMP_C(0x28000000) << (BMP_BIT - 32), /* 46 -- 5, 05 */ + BMP_C(0x29b10000) << (BMP_BIT - 32), /* 47 -- 16, 29b1 */ + BMP_C(0x2f000000) << (BMP_BIT - 32), /* 48 -- 8, 2f */ + BMP_C(0x30000000) << (BMP_BIT - 32), /* 49 -- 4, 3/ 5, 6 */ + BMP_C(0x3010bf7f) << (BMP_BIT - 32), /* 50 -- 32,3010bf7f */ + BMP_C(0x31000000) << (BMP_BIT - 32), /* 51 -- 8, 31 */ + BMP_C(0x31800000) << (BMP_BIT - 32), /* 52 -- 10, 0c6 */ + BMP_C(0x31c30000) << (BMP_BIT - 32), /* 53 -- 16, 31c3 */ + BMP_C(0x328b6300) << (BMP_BIT - 32), /* 54 -- 24, 328b63 */ + BMP_C(0x34000000) << (BMP_BIT - 32), /* 55 -- 6, 0d */ + BMP_C(0x340bc6d9) << (BMP_BIT - 32), /* 56 -- 32,340bc6d9 */ + BMP_C(0x37000000) << (BMP_BIT - 32), /* 57 -- 8, 37 */ + BMP_C(0x38000000) << (BMP_BIT - 32), /* 58 -- 5, 07 */ + BMP_C(0x39000000) << (BMP_BIT - 32), /* 59 -- 8, 39 */ + BMP_C(0x3d650000) << (BMP_BIT - 32), /* 60 -- 16, 3d65 */ + BMP_C(0x3e000000) << (BMP_BIT - 32), /* 61 -- 8, 3e */ + BMP_C(0x40000000) << (BMP_BIT - 32), /* 62 -- 3, 2 */ + BMP_C(0x42000000) << (BMP_BIT - 32), /* 63 -- 8, 42 */ + BMP_C(0x44c20000) << (BMP_BIT - 32), /* 64 -- 16, 44c2 */ + BMP_C(0x45270551) << (BMP_BIT - 32), /* 65 -- 32,45270551 */ + BMP_C(0x48000000) << (BMP_BIT - 32), /* 66 -- 5, 09 */ + BMP_C(0x49000000) << (BMP_BIT - 32), /* 67 -- 8, 49 */ + BMP_C(0x4a800000) << (BMP_BIT - 32), /* 68 -- 10, 12a */ + BMP_C(0x4acc0000) << (BMP_BIT - 32), /* 69 -- 15, 2566 */ + BMP_C(0x4b000000) << (BMP_BIT - 32), /* 70 -- 8, 4b */ + BMP_C(0x4b370000) << (BMP_BIT - 32), /* 71 -- 16, 4b37 */ + BMP_C(0x4c000000) << (BMP_BIT - 32), /* 72 -- 6, 13 */ + BMP_C(0x4c060000) << (BMP_BIT - 32), /* 73 -- 16, 4c06 */ + BMP_C(0x53000000) << (BMP_BIT - 32), /* 74 -- 8, 53 */ + BMP_C(0x55000000) << (BMP_BIT - 32), /* 75 -- 8, 55 */ + BMP_C(0x55555500) << (BMP_BIT - 32), /* 76 -- 24, 555555 */ + BMP_C(0x59350000) << (BMP_BIT - 32), /* 77 -- 16, 5935 */ + BMP_C(0x5d380000) << (BMP_BIT - 32), /* 78 -- 16, 5d38 */ + BMP_C(0x5d400000) << (BMP_BIT - 32), /* 79 -- 10, 175 */ + BMP_C(0x5d6dcb00) << (BMP_BIT - 32), /* 80 -- 24, 5d6dcb */ + BMP_C(0x60000000) << (BMP_BIT - 32), /* 81 -- 3, 3 */ + BMP_C(0x60e00000) << (BMP_BIT - 32), /* 82 -- 11, 307 */ + BMP_C(0x63d00000) << (BMP_BIT - 32), /* 83 -- 16, 63d0 */ + BMP_C(0x64000000) << (BMP_BIT - 32), /* 84 -- 6, 19 */ + BMP_C(0x66400000) << (BMP_BIT - 32), /* 85 -- 10, 199 */ + BMP_C(0x66c50000) << (BMP_BIT - 32), /* 86 -- 16, 66c5 */ + BMP_C(0x6f630000) << (BMP_BIT - 32), /* 87 -- 16, 6f63 */ + BMP_C(0x6f910000) << (BMP_BIT - 32), /* 88 -- 16, 6f91 */ + BMP_C(0x70000000) << (BMP_BIT - 32), /* 89 -- 4, 7 */ + BMP_C(0x70a00000) << (BMP_BIT - 32), /* 90 -- 11, 385 */ + BMP_C(0x755b0000) << (BMP_BIT - 32), /* 91 -- 16, 755b */ + BMP_C(0x765e7680) << (BMP_BIT - 32), /* 92 -- 32,765e7680 */ + BMP_C(0x76c20800) << (BMP_BIT - 32), /* 93 -- 32, 0ed841 */ + BMP_C(0x7979bd00) << (BMP_BIT - 32), /* 94 -- 24, 7979bd */ + BMP_C(0x7e000000) << (BMP_BIT - 32), /* 95 -- 8, 7e */ + BMP_C(0x80000000) << (BMP_BIT - 32), /* 96 -- 3, 4 */ + BMP_C(0x80006300) << (BMP_BIT - 32), /* 97 -- 24, 800063 */ + BMP_C(0x80050000) << (BMP_BIT - 32), /* 98 -- 16, 8005 */ + BMP_C(0x800d0000) << (BMP_BIT - 32), /* 99 -- 16, 800d */ + BMP_C(0x800fe300) << (BMP_BIT - 32), /* 100 -- 24, 800fe3 */ + BMP_C(0x80b40000) << (BMP_BIT - 32), /* 101 -- 14, 202d */ + BMP_C(0x80c2e71c) << (BMP_BIT - 32), /* 102 -- 30,2030b9c7 */ + BMP_C(0x80f00000) << (BMP_BIT - 32), /* 103 -- 12, 80f */ + BMP_C(0x814141ab) << (BMP_BIT - 32), /* 104 -- 32,814141ab */ + BMP_C(0x8144c800) << (BMP_BIT - 32), /* 105 -- 21, 102899 */ + BMP_C(0x864cfb00) << (BMP_BIT - 32), /* 106 -- 24, 864cfb */ + BMP_C(0x87315576) << (BMP_BIT - 32), /* 107 -- 32,87315576 */ + BMP_C(0x89ec0000) << (BMP_BIT - 32), /* 108 -- 16, 89ec */ + BMP_C(0x8a000000) << (BMP_BIT - 32), /* 109 -- 7, 45 */ + BMP_C(0x8b320000) << (BMP_BIT - 32), /* 110 -- 15, 4599 */ + BMP_C(0x8bb70000) << (BMP_BIT - 32), /* 111 -- 16, 8bb7 */ + BMP_C(0x8cc00000) << (BMP_BIT - 32), /* 112 -- 10, 233 */ + BMP_C(0x904cddbf) << (BMP_BIT - 32), /* 113 -- 32,904cddbf */ + BMP_C(0x906e0000) << (BMP_BIT - 32), /* 114 -- 16, 906e */ + BMP_C(0x94000000) << (BMP_BIT - 32), /* 115 -- 8, 94 */ + BMP_C(0x97000000) << (BMP_BIT - 32), /* 116 -- 8, 97 */ + BMP_C(0x98000000) << (BMP_BIT - 32), /* 117 -- 6, 26 */ + BMP_C(0x99000000) << (BMP_BIT - 32), /* 118 -- 8, 99 */ + BMP_C(0x9b000000) << (BMP_BIT - 32), /* 119 -- 8, 9b */ + BMP_C(0x9c000000) << (BMP_BIT - 32), /* 120 -- 6, 27 */ + BMP_C(0x9d5e4de2) << (BMP_BIT - 32), /* 121 -- 31,4eaf26f1 */ + BMP_C(0x9e000000) << (BMP_BIT - 32), /* 122 -- 7, 4f */ + BMP_C(0x9ecf0000) << (BMP_BIT - 32), /* 123 -- 16, 9ecf */ + BMP_C(0xa0660000) << (BMP_BIT - 32), /* 124 -- 16, a066 */ + BMP_C(0xa0970000) << (BMP_BIT - 32), /* 125 -- 16, a097 */ + BMP_C(0xa1000000) << (BMP_BIT - 32), /* 126 -- 8, a1 */ + BMP_C(0xa3660000) << (BMP_BIT - 32), /* 127 -- 16, a366 */ + BMP_C(0xa6000000) << (BMP_BIT - 32), /* 128 -- 7, 53 */ + BMP_C(0xa7000000) << (BMP_BIT - 32), /* 129 -- 8, a7 */ + BMP_C(0xa8000000) << (BMP_BIT - 32), /* 130 -- 5, 15 */ + BMP_C(0xa8190000) << (BMP_BIT - 32), /* 131 -- 16, a819 */ + BMP_C(0xa833982b) << (BMP_BIT - 32), /* 132 -- 32,a833982b */ + BMP_C(0xabcdef00) << (BMP_BIT - 32), /* 133 -- 24, abcdef */ + BMP_C(0xac000000) << (BMP_BIT - 32), /* 134 -- 8, ac */ + BMP_C(0xaee70000) << (BMP_BIT - 32), /* 135 -- 16, aee7 */ + BMP_C(0xb0000000) << (BMP_BIT - 32), /* 136 -- 4, b */ + BMP_C(0xb0010000) << (BMP_BIT - 32), /* 137 -- 16, b001 */ + BMP_C(0xb2aa0000) << (BMP_BIT - 32), /* 138 -- 16, b2aa */ + BMP_C(0xb3400000) << (BMP_BIT - 32), /* 139 -- 12, b34 */ + BMP_C(0xb42d8000) << (BMP_BIT - 32), /* 140 -- 17, 1685b */ + BMP_C(0xb4600000) << (BMP_BIT - 32), /* 141 -- 11, 5a3 */ + BMP_C(0xb4c80000) << (BMP_BIT - 32), /* 142 -- 16, b4c8 */ + BMP_C(0xb4f3e600) << (BMP_BIT - 32), /* 143 -- 24, b4f3e6 */ + BMP_C(0xb704ce00) << (BMP_BIT - 32), /* 144 -- 24, b704ce */ + BMP_C(0xb798b438) << (BMP_BIT - 32), /* 145 -- 32,b798b438 */ + BMP_C(0xbb3d0000) << (BMP_BIT - 32), /* 146 -- 16, bb3d */ + BMP_C(0xbc000000) << (BMP_BIT - 32), /* 147 -- 6,2f/ 8,bc */ + BMP_C(0xbd0be338) << (BMP_BIT - 32), /* 148 -- 32,bd0be338 */ + BMP_C(0xbdf40000) << (BMP_BIT - 32), /* 149 -- 16, bdf4 */ + BMP_C(0xbf050000) << (BMP_BIT - 32), /* 150 -- 16, bf05 */ + BMP_C(0xc0000000) << (BMP_BIT - 32), /* 151 -- 3, 6 */ + BMP_C(0xc2000000) << (BMP_BIT - 32), /* 152 -- 7, 61 */ + BMP_C(0xc25a5600) << (BMP_BIT - 32), /* 153 -- 24, c25a56 */ + BMP_C(0xc2b70000) << (BMP_BIT - 32), /* 154 -- 16, c2b7 */ + BMP_C(0xc2b80000) << (BMP_BIT - 32), /* 155 -- 14, 30ae */ + BMP_C(0xc4000000) << (BMP_BIT - 32), /* 156 -- 8, c4 */ + BMP_C(0xc6c60000) << (BMP_BIT - 32), /* 157 -- 16, c6c6 */ + BMP_C(0xc7000000) << (BMP_BIT - 32), /* 158 -- 8, c7 */ + BMP_C(0xc704dd7b) << (BMP_BIT - 32), /* 159 -- 32,c704dd7b */ + BMP_C(0xc8000000) << (BMP_BIT - 32), /* 160 -- 5, 19 */ + BMP_C(0xc8670000) << (BMP_BIT - 32), /* 161 -- 16, c867 */ + BMP_C(0xcbf43926) << (BMP_BIT - 32), /* 162 -- 32,cbf43926 */ + BMP_C(0xcde70300) << (BMP_BIT - 32), /* 163 -- 24, cde703 */ + BMP_C(0xce3c0000) << (BMP_BIT - 32), /* 164 -- 16, ce3c */ + BMP_C(0xd0000000) << (BMP_BIT - 32), /* 165 -- 8, d0 */ + BMP_C(0xd02a0000) << (BMP_BIT - 32), /* 166 -- 15, 6815 */ + BMP_C(0xd0db0000) << (BMP_BIT - 32), /* 167 -- 16, d0db */ + BMP_C(0xd3100000) << (BMP_BIT - 32), /* 168 -- 12, d31 */ + BMP_C(0xd3be9568) << (BMP_BIT - 32), /* 169 -- 30,34efa55a */ + BMP_C(0xd4d00000) << (BMP_BIT - 32), /* 170 -- 12, d4d */ + BMP_C(0xd5000000) << (BMP_BIT - 32), /* 171 -- 8, d5 */ + BMP_C(0xd64e0000) << (BMP_BIT - 32), /* 172 -- 16, d64e */ + BMP_C(0xda000000) << (BMP_BIT - 32), /* 173 -- 8, da */ + BMP_C(0xdaf00000) << (BMP_BIT - 32), /* 174 -- 12, daf */ + BMP_C(0xdebb20e3) << (BMP_BIT - 32), /* 175 -- 32,debb20e3 */ + BMP_C(0xdf000000) << (BMP_BIT - 32), /* 176 -- 8, df */ + BMP_C(0xe0000000) << (BMP_BIT - 32), /* 177 -- 3, 7 */ + BMP_C(0xe3069283) << (BMP_BIT - 32), /* 178 -- 32,e3069283 */ + BMP_C(0xe3940000) << (BMP_BIT - 32), /* 179 -- 16, e394 */ + BMP_C(0xe5cc0000) << (BMP_BIT - 32), /* 180 -- 16, e5cc */ + BMP_C(0xe7a80000) << (BMP_BIT - 32), /* 181 -- 13, 1cf5 */ + BMP_C(0xe8000000) << (BMP_BIT - 32), /* 182 -- 6, 3a */ + BMP_C(0xea000000) << (BMP_BIT - 32), /* 183 -- 7, 75 */ + BMP_C(0xea820000) << (BMP_BIT - 32), /* 184 -- 16, ea82 */ + BMP_C(0xec000000) << (BMP_BIT - 32), /* 185 -- 6, 3b */ + BMP_C(0xf0000000) << (BMP_BIT - 32), /* 186 -- 4, f */ + BMP_C(0xf0b80000) << (BMP_BIT - 32), /* 187 -- 16, f0b8 */ + BMP_C(0xf1300000) << (BMP_BIT - 32), /* 188 -- 12, f13 */ + BMP_C(0xf4000000) << (BMP_BIT - 32), /* 189 -- 8, f4 */ + BMP_C(0xf4acfb13) << (BMP_BIT - 32), /* 190 -- 32,f4acfb13 */ + BMP_C(0xf5b00000) << (BMP_BIT - 32), /* 191 -- 12, f5b */ + BMP_C(0xf6400000) << (BMP_BIT - 32), /* 192 -- 10, 3d9 */ + BMP_C(0xf7000000) << (BMP_BIT - 32), /* 193 -- 8, f7 */ + BMP_C(0xf8000000) << (BMP_BIT - 32), /* 194 -- 5, 1f */ + BMP_C(0xfc000000) << (BMP_BIT - 32), /* 195 -- 6, 3f */ + BMP_C(0xfc891918) << (BMP_BIT - 32), /* 196 -- 32,fc891918 */ + BMP_C(0xfd000000) << (BMP_BIT - 32), /* 197 -- 8, fd */ + BMP_C(0xfe000000) << (BMP_BIT - 32), /* 198 -- 7, 7f */ + BMP_C(0xfedcba00) << (BMP_BIT - 32), /* 199 -- 24, fedcba */ + BMP_C(0xfee80000) << (BMP_BIT - 32), /* 200 -- 16, fee8 */ + BMP_C(0xff000000) << (BMP_BIT - 32), /* 201 -- 8, ff */ + BMP_C(0xffc00000) << (BMP_BIT - 32), /* 202 -- 10, 3ff */ + BMP_C(0xfff00000) << (BMP_BIT - 32), /* 203 -- 12, fff */ + BMP_C(0xfffc0000) << (BMP_BIT - 32), /* 204 -- 14, 3fff */ + BMP_C(0xffff0000) << (BMP_BIT - 32), /* 205 -- 16, ffff */ + BMP_C(0xffffff00) << (BMP_BIT - 32), /* 206 -- 24, ffffff */ + BMP_C(0xfffffffc) << (BMP_BIT - 32), /* 207 -- 30,3fffffff */ + BMP_C(0xfffffffe) << (BMP_BIT - 32), /* 208 -- 31,7fffffff */ + BMP_C(0xffffffff) << (BMP_BIT - 32), /* 209 -- 32,ffffffff */ }; static const struct malias aliases[]; diff --git a/common/mbedtls/camellia.c b/common/mbedtls/camellia.c index c0597d8fa..bb4169ab4 100644 --- a/common/mbedtls/camellia.c +++ b/common/mbedtls/camellia.c @@ -217,16 +217,16 @@ static const signed char indexes[2][4][20] = { }, /* KL -> RK */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 - }, /* KR -> RK */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 + }, /* KR -> RK */ { 4, 5, 6, 7, 12, 13, 14, 15, 16, 17, 18, 19, -1, 24, 25, -1, 31, 28, 29, 30 }, /* KA -> RK */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 - } /* KB -> RK */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 + } /* KB -> RK */ }, { { @@ -235,12 +235,12 @@ static const signed char indexes[2][4][20] = { }, /* KL -> RK */ { -1, -1, -1, -1, 8, 9, 10, 11, 16, 17, - 18, 19, -1, -1, -1, -1, 39, 36, 37, 38 - }, /* KR -> RK */ + 18, 19, -1, -1, -1, -1, 39, 36, 37, 38 + }, /* KR -> RK */ { -1, -1, -1, -1, 12, 13, 14, 15, 58, 59, - 56, 57, 31, 28, 29, 30, -1, -1, -1, -1 - }, /* KA -> RK */ + 56, 57, 31, 28, 29, 30, -1, -1, -1, -1 + }, /* KA -> RK */ { 4, 5, 6, 7, 65, 66, 67, 64, 20, 21, 22, 23, -1, -1, -1, -1, 43, 40, 41, 42 diff --git a/common/zlib/inflate.c b/common/zlib/inflate.c index adbe00146..753671080 100644 --- a/common/zlib/inflate.c +++ b/common/zlib/inflate.c @@ -1060,7 +1060,7 @@ int flush; last = here; for (;;) { here = state->lencode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; + (BITS(last.bits + last.op) >> last.bits)]; if ((unsigned)(last.bits + here.bits) <= bits) break; PULLBYTE(); } @@ -1110,7 +1110,7 @@ int flush; last = here; for (;;) { here = state->distcode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; + (BITS(last.bits + last.op) >> last.bits)]; if ((unsigned)(last.bits + here.bits) <= bits) break; PULLBYTE(); } From 2a0d1557e1e9ef3aca759aa26b886a82014a10d4 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 7 Jan 2020 22:18:27 +0100 Subject: [PATCH 1404/1854] style --- client/cmdparser.c | 6 +++--- client/emv/crypto_polarssl.c | 2 +- client/fileutils.c | 12 ++++++------ common/generator.c | 6 +++--- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/client/cmdparser.c b/client/cmdparser.c index 3f9412374..fca6fb772 100644 --- a/client/cmdparser.c +++ b/client/cmdparser.c @@ -178,7 +178,7 @@ int CmdsParse(const command_t Commands[], const char *Cmd) { char cmd_name[128]; memset(cmd_name, 0, sizeof(cmd_name)); - int len = 0; + int len = 0; // %n == receives an integer of value equal to the number of chars read so far. // len = max 127 sscanf(Cmd, "%127s%n", cmd_name, &len); @@ -248,10 +248,10 @@ void dumpCommandsRecursive(const command_t cmds[], int markdown) { } while (cmds[i].Name) { - + if ((cmds[i].Name[0] == '-' || strlen(cmds[i].Name) == 0) && ++i) continue; if (cmds[i].Help[0] == '{' && ++i) continue; - + const char *cmd_offline = "N"; if (cmds[i].IsAvailable()) diff --git a/client/emv/crypto_polarssl.c b/client/emv/crypto_polarssl.c index b0cb59baa..e258f1bbb 100644 --- a/client/emv/crypto_polarssl.c +++ b/client/emv/crypto_polarssl.c @@ -136,7 +136,7 @@ static struct crypto_pk *crypto_pk_polarssl_open_priv_rsa(va_list vl) { mbedtls_mpi_read_binary(&cp->ctx.Q, (const unsigned char *)q, qlen); mbedtls_mpi_read_binary(&cp->ctx.DP, (const unsigned char *)dp, dplen); mbedtls_mpi_read_binary(&cp->ctx.DQ, (const unsigned char *)dq, dqlen); - + int res = mbedtls_mpi_inv_mod(&cp->ctx.QP, &cp->ctx.Q, &cp->ctx.P); if (res != 0) { fprintf(stderr, "PolarSSL private key error res=%x exp=%d mod=%d.\n", res * -1, explen, modlen); diff --git a/client/fileutils.c b/client/fileutils.c index 17b3da4bf..4847d52b8 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -204,7 +204,7 @@ int saveFileEML(const char *preferredName, uint8_t *data, size_t datalen, size_t } fflush(f); fclose(f); - PrintAndLogEx(SUCCESS, "saved " _YELLOW_("%" PRId32 )" blocks to text file " _YELLOW_("%s"), blocks, fileName); + PrintAndLogEx(SUCCESS, "saved " _YELLOW_("%" PRId32)" blocks to text file " _YELLOW_("%s"), blocks, fileName); out: free(fileName); @@ -618,7 +618,7 @@ int loadFile_safe(const char *preferredName, const char *suffix, void **pdata, s int loadFileEML(const char *preferredName, void *data, size_t *datalen) { if (data == NULL) return PM3_EINVARG; - + char *fileName = filenamemcopy(preferredName, ".eml"); if (fileName == NULL) return PM3_EMALLOC; @@ -637,7 +637,7 @@ int loadFileEML(const char *preferredName, void *data, size_t *datalen) { memset(line, 0, sizeof(line)); uint8_t buf[64] = {0x00}; - uint8_t *udata = (uint8_t*)data; + uint8_t *udata = (uint8_t *)data; while (!feof(f)) { @@ -861,15 +861,15 @@ int loadFileDICTIONARYEx(const char *preferredName, void *data, size_t maxdatale } if (startFilePosition) { - if (fseek(f, startFilePosition, SEEK_SET) < 0){ + if (fseek(f, startFilePosition, SEEK_SET) < 0) { fclose(f); retval = PM3_EFILE; goto out; } } - uint8_t *udata = (uint8_t*)data; - + uint8_t *udata = (uint8_t *)data; + // read file while (!feof(f)) { size_t filepos = ftell(f); diff --git a/common/generator.c b/common/generator.c index f2bf33626..174657573 100644 --- a/common/generator.c +++ b/common/generator.c @@ -26,7 +26,7 @@ //------------------------------------ // MFU/NTAG PWD/PACK generation stuff -// Italian transport system +// Italian transport system // Amiibo // Lego Dimension // XYZ 3D printing @@ -225,9 +225,9 @@ int mfc_algo_mizip_one(uint8_t *uid, uint8_t sector, uint64_t *key) { } // returns all Mifare Mini (MFM) 10 keys. // keys must have 5*2*6 = 60bytes space -int mfc_algo_mizip_all(uint8_t *uid, uint8_t *keys) { +int mfc_algo_mizip_all(uint8_t *uid, uint8_t *keys) { if (keys == NULL) return PM3_EINVARG; - + uint64_t xor_tbl[] = { 0x09125a2589e5ULL, 0xF12C8453D821ULL, 0xAB75C937922FULL, 0x73E799FE3241ULL, From 68e41492ad0238b78dc773ea5ba4b52b579898e2 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 7 Jan 2020 22:19:28 +0100 Subject: [PATCH 1405/1854] style --- client/cmdhffelica.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index 07a1ac18b..94f5c2ca4 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -440,10 +440,10 @@ static void clear_and_send_command(uint8_t flags, uint16_t datalen, uint8_t *dat */ static bool add_param(const char *Cmd, uint8_t paramCount, uint8_t *data, uint8_t dataPosition, uint8_t length) { if (param_getlength(Cmd, paramCount) == length) { - + if (param_gethex(Cmd, paramCount, data + dataPosition, length) == 1) - return false; - else + return false; + else return true; } else { @@ -460,7 +460,7 @@ static bool add_param(const char *Cmd, uint8_t paramCount, uint8_t *data, uint8_ static void print_rd_noEncrpytion_response(felica_read_without_encryption_response_t *rd_noCry_resp) { if (rd_noCry_resp->status_flags.status_flag1[0] == 00 && - rd_noCry_resp->status_flags.status_flag2[0] == 00) { + rd_noCry_resp->status_flags.status_flag2[0] == 00) { char *temp = sprint_hex(rd_noCry_resp->block_data, sizeof(rd_noCry_resp->block_data)); @@ -653,7 +653,7 @@ static int CmdHFFelicaAuthentication1(const char *Cmd) { mbedtls_des3_set3key_enc(&des3_ctx, master_key); PrintAndLogEx(INFO, "3DES Master Secret: %s", sprint_hex(master_key, 24)); } else if (param_getlength(Cmd, paramCount) == 32) { - + if (param_gethex(Cmd, paramCount, master_key, 32) == 1) { PrintAndLogEx(ERR, "Failed param key"); return PM3_EINVARG; @@ -781,7 +781,7 @@ static int CmdHFFelicaAuthentication2(const char *Cmd) { mbedtls_des3_init(&des3_ctx); unsigned char p3c[8]; if (param_getlength(Cmd, paramCount) == 32) { - + if (param_gethex(Cmd, paramCount, master_key, 32) == 1) { PrintAndLogEx(ERR, "Failed param key"); return PM3_EINVARG; @@ -1131,7 +1131,7 @@ static int CmdHFFelicaRequestSpecificationVersion(const char *Cmd) { } else { felica_request_spec_response_t spec_response; memcpy(&spec_response, (felica_request_spec_response_t *)resp.data.asBytes, sizeof(felica_request_spec_response_t)); - + if (spec_response.frame_response.IDm[0] != 0) { PrintAndLogEx(SUCCESS, "\nGot Request Response:"); PrintAndLogEx(SUCCESS, "\nIDm: %s", sprint_hex(spec_response.frame_response.IDm, sizeof(spec_response.frame_response.IDm))); @@ -1336,12 +1336,12 @@ static int CmdHFFelicaRequestService(const char *Cmd) { if (!all_nodes) { // Node Number if (param_getlength(Cmd, paramCount) == 2) { - + if (param_gethex(Cmd, paramCount++, data + 10, 2) == 1) { PrintAndLogEx(ERR, "Failed param key"); return PM3_EINVARG; } - + } else { PrintAndLogEx(ERR, "Incorrect Node number length!"); return PM3_EINVARG; @@ -1349,7 +1349,7 @@ static int CmdHFFelicaRequestService(const char *Cmd) { } if (param_getlength(Cmd, paramCount) == 4) { - + if (param_gethex(Cmd, paramCount++, data + 11, 4) == 1) { PrintAndLogEx(ERR, "Failed param key"); return PM3_EINVARG; @@ -1372,7 +1372,7 @@ static int CmdHFFelicaRequestService(const char *Cmd) { if (!custom_IDm && !check_last_idm(data, datalen)) { return PM3_EINVARG; } - + data[0] = int_to_hex(&datalen); data[1] = 0x02; // Service Request Command ID if (all_nodes) { @@ -1435,12 +1435,12 @@ static int CmdHFFelicaSniff(const char *Cmd) { } i++; } - + if (samples2skip == 0) { samples2skip = 10; PrintAndLogEx(INFO, "Set default samples2skip: %" PRIu64, samples2skip); } - + if (triggers2skip == 0) { triggers2skip = 5000; PrintAndLogEx(INFO, "Set default triggers2skip: %" PRIu64, triggers2skip); From 9662556ccbd4e2716ce32218a8c8b8a2931d5b9f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 7 Jan 2020 22:19:59 +0100 Subject: [PATCH 1406/1854] style --- armsrc/hitagS.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/armsrc/hitagS.c b/armsrc/hitagS.c index b44bffa45..836df6e82 100644 --- a/armsrc/hitagS.c +++ b/armsrc/hitagS.c @@ -1299,13 +1299,13 @@ void ReadHitagS(hitag_function htf, hitag_data *htd) { tag.pages[pageNum][i] = 0x0; for (i = 0; i < 4; i++) { // set page bytes from recieved bits tag.pages[pageNum][i] += ((pageData[i * 8] << 7) - | (pageData[1 + (i * 8)] << 6) - | (pageData[2 + (i * 8)] << 5) - | (pageData[3 + (i * 8)] << 4) - | (pageData[4 + (i * 8)] << 3) - | (pageData[5 + (i * 8)] << 2) - | (pageData[6 + (i * 8)] << 1) - | pageData[7 + (i * 8)]); + | (pageData[1 + (i * 8)] << 6) + | (pageData[2 + (i * 8)] << 5) + | (pageData[3 + (i * 8)] << 4) + | (pageData[4 + (i * 8)] << 3) + | (pageData[5 + (i * 8)] << 2) + | (pageData[6 + (i * 8)] << 1) + | pageData[7 + (i * 8)]); } if (tag.auth && tag.LKP && pageNum == 1) { Dbprintf("Page[%2d]: %02X %02X %02X %02X", pageNum, pwdh0, From 5799ca38e11b0b9f3809fbfbcb35365078fafca0 Mon Sep 17 00:00:00 2001 From: hamperfait <9727671+hamperfait@users.noreply.github.com> Date: Thu, 9 Jan 2020 08:00:58 +0100 Subject: [PATCH 1407/1854] Update mfc_default_keys.dic Added Granada, ES transport Card keys --- client/dictionaries/mfc_default_keys.dic | 36 +++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index dda7a5126..15aa66993 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -1041,4 +1041,38 @@ bb2c0007d022 # Hotel Berlin Classic room B KEY b62307b62307 # a2a3cca2a3cc - +# +# Granada, ES Transport Card +000000270000 +0172066b2f03 +0172066b2f33 +066b2f230172 +0b0172066b2f +0f385ffb6529 +172066b2f2f0 +2066b2f27017 +29173860fc76 +2f130172066b +2fca8492f386 +385efa542907 +3864fcba5937 +3b0172066b2f +3f3865fccb69 +5c8ff9990da2 +6291b3860fc8 +63fca9492f38 +66b2f1f01720 +6b2f1b017206 +70172066b2f0 +70172066b2f3 +72066b2f2b01 +863fcb959373 +87291f3861fc +913385ffb752 +b2f170172066 +b385efa64290 +c9739233861f +f0f0172066b2 +f3864fcca693 +f3f0172066b2 +fc9839273862 From 413af36dcc8c3f60fb6a742fdb97a6753357c46d Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 9 Jan 2020 11:45:53 +0100 Subject: [PATCH 1408/1854] Chg: 'lf indala demod' - added Heden-2L descramble\n ref: http://www.proxmark.org/forum/viewtopic.php?pid=37833#p37833 --- client/cmdlfindala.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/client/cmdlfindala.c b/client/cmdlfindala.c index 443435f88..4746fa3f3 100644 --- a/client/cmdlfindala.c +++ b/client/cmdlfindala.c @@ -68,6 +68,36 @@ static int usage_lf_indala_sim(void) { return PM3_SUCCESS; } +/* +static void encodeHeden2L(uint8_t *bits) { + +} +*/ +static void decodeHeden2L(uint8_t *bits) { + + uint32_t cardnumber = 0; + uint8_t offset = 31; + + if ( bits[offset + 8] ) cardnumber += 1; + if ( bits[offset + 10] ) cardnumber += 2; + if ( bits[offset + 14] ) cardnumber += 4; + if ( bits[offset + 15] ) cardnumber += 8; + if ( bits[offset + 12] ) cardnumber += 16; + if ( bits[offset + 28] ) cardnumber += 32; + if ( bits[offset + 3] ) cardnumber += 64; + if ( bits[offset + 11] ) cardnumber += 128; + if ( bits[offset + 19] ) cardnumber += 256; + if ( bits[offset + 26] ) cardnumber += 512; + if ( bits[offset + 17] ) cardnumber += 1024; + if ( bits[offset + 18] ) cardnumber += 2048; + if ( bits[offset + 20] ) cardnumber += 4096; + if ( bits[offset + 13] ) cardnumber += 8192; + if ( bits[offset + 7] ) cardnumber += 16384; + if ( bits[offset + 23] ) cardnumber += 32768; + + PrintAndLogEx(SUCCESS, "\tHeden-2L | %u", cardnumber); +} + // Indala 26 bit decode // by marshmellow, martinbeier // optional arguments - same as PSKDemod (clock & invert & maxerr) @@ -172,8 +202,11 @@ static int CmdIndalaDemod(const char *Cmd) { PrintAndLogEx(SUCCESS, "Possible de-scramble patterns"); PrintAndLogEx(SUCCESS, "\tPrinted | __%04d__ [0x%X]", p1, p1); PrintAndLogEx(SUCCESS, "\tInternal ID | %" PRIu64, foo); + decodeHeden2L(DemodBuffer); + PrintAndLogEx(SUCCESS, "Fmt 26 bit FC %u , CSN %u , checksum %1d%1d", fc, csn, checksum >> 1 & 0x01, checksum & 0x01); + } else { uint32_t uid3 = bytebits_to_byte(DemodBuffer + 64, 32); uint32_t uid4 = bytebits_to_byte(DemodBuffer + 96, 32); From 3b51d18f925217d7fd80bfc5d93a2c4c9ab458be Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 9 Jan 2020 12:59:29 +0100 Subject: [PATCH 1409/1854] textual --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6abb5e47b..9f3f908e3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Change `lf indala demod` - added @randomdude42's decode Heden 2L/Hedengren format (@iceman) Thanks to @randomdude42 - Add `commands.md` - document with all proxmark client commands. Generated with XX_internal_command_dump_markdown_XX. (@iceman1001) - Change `lf pac clone` - new option `c ` to allow cloning PAC/Stanley tag from card ID (@danshuk) - Change `lf pac read` - decoded PAC/Stanley card ID (@danshuk) From 68eb66052a9dc2e22412ac5b35b880e6fc4cd52a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 9 Jan 2020 14:26:52 +0100 Subject: [PATCH 1410/1854] cliparser updates --- client/cliparser/argtable3.c | 50 +++++++++++++++--------------------- 1 file changed, 20 insertions(+), 30 deletions(-) diff --git a/client/cliparser/argtable3.c b/client/cliparser/argtable3.c index b6284fd07..a5fb7a023 100644 --- a/client/cliparser/argtable3.c +++ b/client/cliparser/argtable3.c @@ -3421,7 +3421,7 @@ TRexBool trex_searchrange(TRex *exp, const TRexChar *text_begin, const TRexChar if (!cur) break; node = exp->_nodes[node].next; - } + } text_begin++; } while (cur == NULL && text_begin != text_end); @@ -3484,8 +3484,12 @@ TRexBool trex_getsubexp(TRex *exp, int n, TRexMatch *subexp) { static void arg_str_resetfn(struct arg_str *parent) { + int i; ARG_TRACE(("%s:resetfn(%p)\n", __FILE__, parent)); parent->count = 0; + for (i = 0; i < parent->count; i++) { + parent->sval[i] = ""; + } } @@ -3671,8 +3675,7 @@ void arg_register_error(struct arg_end *end, * Return index of first table entry with a matching short option * or -1 if no match was found. */ -static -int find_shortoption(struct arg_hdr * *table, char shortopt) { +static int find_shortoption(struct arg_hdr** table, char shortopt) { int tabindex; for (tabindex = 0; !(table[tabindex]->flag & ARG_TERMINATOR); tabindex++) { if (table[tabindex]->shortopts && @@ -3682,7 +3685,6 @@ int find_shortoption(struct arg_hdr * *table, char shortopt) { return -1; } - struct longoptions { int getoptval; int noptions; @@ -3706,8 +3708,7 @@ void dump_longoptions(struct longoptions *longoptions) { } #endif -static -struct longoptions *alloc_longoptions(struct arg_hdr * *table) { +static struct longoptions* alloc_longoptions(struct arg_hdr** table) { struct longoptions *result; size_t nbytes; int noptions = 1; @@ -3789,8 +3790,7 @@ struct longoptions *alloc_longoptions(struct arg_hdr * *table) { return result; } -static -char *alloc_shortoptions(struct arg_hdr * *table) { +static char* alloc_shortoptions(struct arg_hdr** table) { char *result; size_t len = 2; int tabindex; @@ -3830,8 +3830,7 @@ char *alloc_shortoptions(struct arg_hdr * *table) { /* return index of the table terminator entry */ -static -int arg_endindex(struct arg_hdr * *table) { +static int arg_endindex(struct arg_hdr** table) { int tabindex = 0; while (!(table[tabindex]->flag & ARG_TERMINATOR)) tabindex++; @@ -3839,10 +3838,9 @@ int arg_endindex(struct arg_hdr * *table) { } -static -void arg_parse_tagged(int argc, - char * *argv, - struct arg_hdr * *table, +static void arg_parse_tagged(int argc, + char **argv, + struct arg_hdr **table, struct arg_end *endtable) { struct longoptions *longoptions; char *shortoptions; @@ -3953,10 +3951,9 @@ void arg_parse_tagged(int argc, } -static -void arg_parse_untagged(int argc, - char * *argv, - struct arg_hdr * *table, +static void arg_parse_untagged(int argc, + char **argv, + struct arg_hdr **table, struct arg_end *endtable) { int tabindex = 0; int errorlast = 0; @@ -4010,7 +4007,6 @@ void arg_parse_untagged(int argc, optarglast = argv[optind]; parentlast = parent; } - } /* if a tenative error still remains at this point then register it as a proper error */ @@ -4030,8 +4026,7 @@ void arg_parse_untagged(int argc, } -static -void arg_parse_check(struct arg_hdr * *table, struct arg_end *endtable) { +static void arg_parse_check(struct arg_hdr **table, struct arg_end *endtable) { int tabindex = 0; /* printf("arg_parse_check()\n"); */ do { @@ -4045,8 +4040,7 @@ void arg_parse_check(struct arg_hdr * *table, struct arg_end *endtable) { } -static -void arg_reset(void * *argtable) { +static void arg_reset(void **argtable) { struct arg_hdr * *table = (struct arg_hdr * *)argtable; int tabindex = 0; /*printf("arg_reset(%p)\n",argtable);*/ @@ -4138,8 +4132,7 @@ int arg_parse(int argc, char * *argv, void * *argtable) { * dest[] == "goodbye cruel world!" * ndest == 10 */ -static -void arg_cat(char * *pdest, const char *src, size_t *pndest) { +static void arg_cat(char **pdest, const char *src, size_t *pndest) { char *dest = *pdest; char *end = dest + *pndest; @@ -4160,8 +4153,7 @@ void arg_cat(char * *pdest, const char *src, size_t *pndest) { } -static -void arg_cat_option(char *dest, +static void arg_cat_option(char *dest, size_t ndest, const char *shortopts, const char *longopts, @@ -4219,8 +4211,7 @@ void arg_cat_option(char *dest, } } -static -void arg_cat_optionv(char *dest, +static void arg_cat_optionv(char *dest, size_t ndest, const char *shortopts, const char *longopts, @@ -4666,7 +4657,6 @@ int arg_nullcheck(void * *argtable) { return 0; } - /* * arg_free() is deprecated in favour of arg_freetable() due to a flaw in its design. * The flaw results in memory leak in the (very rare) case that an intermediate From 76fa7efe72cac094555426eaa026caf4eb6d98e1 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 9 Jan 2020 19:25:34 +0100 Subject: [PATCH 1411/1854] Chg: 'lf indala clone' - new param '-c' for encode heden2l format and param '--Q5' to write to t5555 cards --- client/cmdlfindala.c | 129 +++++++++++++++++++++++++++++++------------ 1 file changed, 94 insertions(+), 35 deletions(-) diff --git a/client/cmdlfindala.c b/client/cmdlfindala.c index 4746fa3f3..c5c32d62d 100644 --- a/client/cmdlfindala.c +++ b/client/cmdlfindala.c @@ -58,25 +58,70 @@ static int usage_lf_indala_sim(void) { PrintAndLogEx(NORMAL, "Enables simulation of Indala card with specified uid."); PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued."); PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Usage: lf indala sim [h] "); + PrintAndLogEx(NORMAL, "Usage: lf indala sim [h] "); PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " h : This help"); - PrintAndLogEx(NORMAL, " : 64/224 UID"); + PrintAndLogEx(NORMAL, " h : This help"); + PrintAndLogEx(NORMAL, " u : 64/224 UID"); + PrintAndLogEx(NORMAL, " c : Cardnumber for Heden 2L format (decimal)"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf indala sim deadc0de"); return PM3_SUCCESS; } -/* -static void encodeHeden2L(uint8_t *bits) { +#define HEDEN2L_OFFSET 31 +static void encodeHeden2L(uint8_t *dest, uint32_t cardnumber) { + uint8_t template[] = { + 1,0,1,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 1,0,0,0,1,0,0,0, + 1,0,0,0,0,0,0,0, + 0,0,0,0,1,0,0,1, + 0,0,0,0,0,0,1,0 + }; + uint8_t cardbits[32]; + + num_to_bytebits(cardnumber, sizeof(cardbits), cardbits); + + if (cardbits[31] == 1) template[HEDEN2L_OFFSET + 8] = 0x1; + if (cardbits[30] == 1) template[HEDEN2L_OFFSET + 10] = 0x1; + if (cardbits[29] == 1) template[HEDEN2L_OFFSET + 14] = 0x1; + if (cardbits[28] == 1) template[HEDEN2L_OFFSET + 15] = 0x1; + if (cardbits[27] == 1) template[HEDEN2L_OFFSET + 12] = 0x1; + if (cardbits[26] == 1) template[HEDEN2L_OFFSET + 28] = 0x1; + if (cardbits[25] == 1) template[HEDEN2L_OFFSET + 3] = 0x1; + if (cardbits[24] == 1) template[HEDEN2L_OFFSET + 11] = 0x1; + if (cardbits[23] == 1) template[HEDEN2L_OFFSET + 19] = 0x1; + if (cardbits[22] == 1) template[HEDEN2L_OFFSET + 26] = 0x1; + if (cardbits[21] == 1) template[HEDEN2L_OFFSET + 17] = 0x1; + if (cardbits[20] == 1) template[HEDEN2L_OFFSET + 18] = 0x1; + if (cardbits[19] == 1) template[HEDEN2L_OFFSET + 20] = 0x1; + if (cardbits[18] == 1) template[HEDEN2L_OFFSET + 13] = 0x1; + if (cardbits[17] == 1) template[HEDEN2L_OFFSET + 7] = 0x1; + if (cardbits[16] == 1) template[HEDEN2L_OFFSET + 23] = 0x1; + + // Parity + uint8_t counter = 0; + for (int i=0; i< sizeof(template) - HEDEN2L_OFFSET; i++) { + if (template[i]) + counter++; + } + template[63] = (counter & 0x1); + + for (int i = 0; i< sizeof(template); i += 8) { + dest[i/8] = bytebits_to_byte(template + i, 8); + } + + PrintAndLogEx(INFO, "Heden2L Cardnumber %u ; RawID %s", cardnumber, sprint_hex(dest, 8)); } -*/ + static void decodeHeden2L(uint8_t *bits) { uint32_t cardnumber = 0; - uint8_t offset = 31; + uint8_t offset = HEDEN2L_OFFSET; if ( bits[offset + 8] ) cardnumber += 1; if ( bits[offset + 10] ) cardnumber += 2; @@ -497,49 +542,55 @@ static int CmdIndalaSim(const char *Cmd) { static int CmdIndalaClone(const char *Cmd) { - bool isLongUid = false; + bool is_long_uid = false, got_cn = false; + bool is_t5555 = false; + int32_t cardnumber; uint32_t blocks[8] = {0}; uint8_t max = 0; - uint8_t data[7 * 4]; int datalen = 0; CLIParserInit("lf indala clone", - "Enables cloning of Indala card with specified uid onto T55x7\n" - "defaults to 64.\n", - "\n" - "Samples:\n" - "\tlf indala clone a0000000a0002021\n" - "\tlf indala clone -l 80000001b23523a6c2e31eba3cbee4afb3c6ad1fcf649393928c14e5"); + "clone INDALA tag to T55x7 (or to q5/T5555)", + "Examples:\n" + "\tlf indala clone -c 888\n" + "\tlf indala clone -r a0000000a0002021\n" + "\tlf indala clone -l -r 80000001b23523a6c2e31eba3cbee4afb3c6ad1fcf649393928c14e5"); void *argtable[] = { arg_param_begin, - arg_lit0("lL", "long", "long UID 224 bits"), - arg_strx1(NULL, NULL, "", NULL), + arg_lit0("lL", "long", "optional - long UID 224 bits"), + arg_int0("cC", "cn", "", "Cardnumber for Heden 2L format"), + arg_strx0("rR", "raw", "", "raw bytes"), + arg_lit0("qQ", "Q5", "optional - specify write to Q5 (t5555 instead of t55x7)"), arg_param_end }; CLIExecWithReturn(Cmd, argtable, false); - isLongUid = arg_get_lit(1); - CLIGetHexWithReturn(2, data, &datalen); + is_long_uid = arg_get_lit(1); + if (is_long_uid == false) { + cardnumber = arg_get_int_def(2, -1); + got_cn = (cardnumber != -1); + } + + if (got_cn == false) { + CLIGetHexWithReturn(3, data, &datalen); + } + + is_t5555 = arg_get_lit(4); + CLIParserFree(); - /* - //TODO add selection of chip for Q5 or T55x7 - - // data[0] = T5555_SET_BITRATE(32 | T5555_MODULATION_PSK2 | 7 << T5555_MAXBLOCK_SHIFT; - //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=7;Inverse data) - // T5567WriteBlock(0x603E10E2,0); - - // data[0] = T5555_SET_BITRATE(32 | T5555_MODULATION_PSK1 | 2 << T5555_MAXBLOCK_SHIFT; - //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=2;Inverse data) - // T5567WriteBlock(0x603E1042,0); - */ - - if (isLongUid) { + if (is_long_uid) { + // 224 BIT UID // config for Indala (RF/32;PSK2 with RF/2;Maxblock=7) PrintAndLogEx(INFO, "Preparing to clone Indala 224bit tag with RawID %s", sprint_hex(data, datalen)); - blocks[0] = T55x7_BITRATE_RF_32 | T55x7_MODULATION_PSK2 | (7 << T55x7_MAXBLOCK_SHIFT); + + if (is_t5555) + blocks[0] = T5555_SET_BITRATE(32) | T5555_MODULATION_PSK2 | (7 << T5555_MAXBLOCK_SHIFT); + else + blocks[0] = T55x7_BITRATE_RF_32 | T55x7_MODULATION_PSK2 | (7 << T55x7_MAXBLOCK_SHIFT); + blocks[1] = bytes_to_num(data, 4); blocks[2] = bytes_to_num(data + 4, 4); blocks[3] = bytes_to_num(data + 8, 4); @@ -549,16 +600,24 @@ static int CmdIndalaClone(const char *Cmd) { blocks[7] = bytes_to_num(data + 24, 4); max = 8; } else { + // 64 BIT UID + if (got_cn) + encodeHeden2L(data, cardnumber); + // config for Indala 64 format (RF/32;PSK1 with RF/2;Maxblock=2) PrintAndLogEx(INFO, "Preparing to clone Indala 64bit tag with RawID %s", sprint_hex(data, datalen)); - blocks[0] = T55x7_BITRATE_RF_32 | T55x7_MODULATION_PSK1 | (2 << T55x7_MAXBLOCK_SHIFT); + + if (is_t5555) + blocks[0] = T5555_SET_BITRATE(32) | T5555_MODULATION_PSK1 | (2 << T5555_MAXBLOCK_SHIFT); + else + blocks[0] = T55x7_BITRATE_RF_32 | T55x7_MODULATION_PSK1 | (2 << T55x7_MAXBLOCK_SHIFT); + blocks[1] = bytes_to_num(data, 4); blocks[2] = bytes_to_num(data + 4, 4); max = 3; } print_blocks(blocks, max); - return clone_t55xx_tag(blocks, max); } From 1d6ef96d1259d81f70b846d35e6ce966ad2a2467 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 9 Jan 2020 19:26:12 +0100 Subject: [PATCH 1412/1854] Chg: fixes from original repo --- client/cliparser/argtable3.h | 16 ++++++++++++++++ client/cliparser/cliparser.h | 14 +++++++------- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/client/cliparser/argtable3.h b/client/cliparser/argtable3.h index c3ec479ea..d8e3c53cc 100644 --- a/client/cliparser/argtable3.h +++ b/client/cliparser/argtable3.h @@ -1,4 +1,6 @@ /******************************************************************************* + * argtable3: Declares the main interfaces of the library + * * This file is part of the argtable3 library. * * Copyright (C) 1998-2001,2003-2011,2013 Stewart Heitmann @@ -39,6 +41,13 @@ extern "C" { #endif #define ARG_REX_ICASE 1 +#define ARG_DSTR_SIZE 200 +#define ARG_CMD_NAME_LEN 100 +#define ARG_CMD_DESCRIPTION_LEN 256 + +#ifndef ARG_REPLACE_GETOPT +#define ARG_REPLACE_GETOPT 1 /* use the embedded getopt as the system getopt(3) */ +#endif /* ARG_REPLACE_GETOPT */ /* bit masks for arg_hdr.flag */ enum { @@ -143,6 +152,13 @@ struct arg_end { const char **argval; /* Array of pointers to offending argv[] string */ }; +/* +typedef struct arg_cmd_info { + char name[ARG_CMD_NAME_LEN]; + char description[ARG_CMD_DESCRIPTION_LEN]; + arg_cmdfn* proc; +} arg_cmd_info_t; +*/ /**** arg_xxx constructor functions *********************************/ diff --git a/client/cliparser/cliparser.h b/client/cliparser/cliparser.h index c67488d59..866ee07d6 100644 --- a/client/cliparser/cliparser.h +++ b/client/cliparser/cliparser.h @@ -13,16 +13,16 @@ #include "argtable3.h" #include "util.h" -#define arg_param_begin arg_lit0("hH", "help", "print this help and exit") +#define arg_param_begin arg_lit0("hH", "help", "This help") #define arg_param_end arg_end(20) -#define arg_getsize(a) (sizeof(a) / sizeof(a[0])) -#define arg_get_lit(n)(((struct arg_lit*)argtable[n])->count) +#define arg_getsize(a) (sizeof(a) / sizeof(a[0])) +#define arg_get_lit(n) (((struct arg_lit*)argtable[n])->count) #define arg_get_int_count(n)(((struct arg_int*)argtable[n])->count) -#define arg_get_int(n)(((struct arg_int*)argtable[n])->ival[0]) -#define arg_get_int_def(n,def)(arg_get_int_count(n)?(arg_get_int(n)):(def)) -#define arg_get_str(n)((struct arg_str*)argtable[n]) -#define arg_get_str_len(n)(strlen(((struct arg_str*)argtable[n])->sval[0])) +#define arg_get_int(n) (((struct arg_int*)argtable[n])->ival[0]) +#define arg_get_int_def(n, def)(arg_get_int_count(n) ? (arg_get_int(n)) : (def)) +#define arg_get_str(n) ((struct arg_str*)argtable[n]) +#define arg_get_str_len(n) (strlen(((struct arg_str*)argtable[n])->sval[0])) #define arg_strx1(shortopts, longopts, datatype, glossary) (arg_strn((shortopts), (longopts), (datatype), 1, 250, (glossary))) #define arg_strx0(shortopts, longopts, datatype, glossary) (arg_strn((shortopts), (longopts), (datatype), 0, 250, (glossary))) From 0869cbc6ad4a6c493b8fe934c581f1abb88fcd0a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 9 Jan 2020 19:28:44 +0100 Subject: [PATCH 1413/1854] Fix: 'lf config' - calling without param messes up all device settings. --- armsrc/lfadc.c | 6 +- armsrc/lfsampling.c | 41 +++++++++----- armsrc/lfsampling.h | 8 +-- client/cmdlf.c | 134 +++++++++++++++++++++++++------------------- include/pm3_cmd.h | 12 ++-- 5 files changed, 116 insertions(+), 85 deletions(-) diff --git a/armsrc/lfadc.c b/armsrc/lfadc.c index a42fe8c52..d59fae07d 100644 --- a/armsrc/lfadc.c +++ b/armsrc/lfadc.c @@ -150,12 +150,12 @@ void lf_init(bool reader) { AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; LOW(GPIO_SSC_DOUT); - // Enable peripheral Clock for TIMER_CLOCK0 + // Enable peripheral Clock for TIMER_CLOCK 0 AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC0); AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV4_CLOCK; - // Enable peripheral Clock for TIMER_CLOCK0 + // Enable peripheral Clock for TIMER_CLOCK 1 AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC1); AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_TIMER_DIV4_CLOCK; @@ -168,7 +168,7 @@ void lf_init(bool reader) { AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; // Prepare data trace - if (logging) initSamplingBuffer(NULL); + if (logging) initSampleBuffer(NULL); } diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index d836accfa..32865d204 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -42,25 +42,40 @@ void printConfig() { /** * Called from the USB-handler to set the sampling configuration - * The sampling config is used for std reading and sniffing. + * The sampling config is used for standard reading and sniffing. * * Other functions may read samples and ignore the sampling config, * such as functions to read the UID from a prox tag or similar. * - * Values set to '0' implies no change (except for averaging) + * Values set to '-1' implies no change * @brief setSamplingConfig * @param sc */ void setSamplingConfig(sample_config *sc) { - if (sc->divisor != 0) config.divisor = sc->divisor; - if (sc->bits_per_sample != 0) config.bits_per_sample = sc->bits_per_sample; - if (sc->trigger_threshold != -1) config.trigger_threshold = sc->trigger_threshold; -// if (sc->samples_to_skip == 0xffffffff) // if needed to not update if not supplied - config.samples_to_skip = sc->samples_to_skip; - config.decimation = (sc->decimation != 0) ? sc->decimation : 1; - config.averaging = sc->averaging; - if (config.bits_per_sample > 8) config.bits_per_sample = 8; + // decimation (1-8) how many bits of adc sample value to save + if (sc->decimation > 0 && sc->decimation < 8) + config.decimation = sc->decimation; + + // bits per sample (1-8) + if (sc->bits_per_sample > 0 && sc->bits_per_sample < 8) + config.bits_per_sample = sc->bits_per_sample; + + // + if (sc->averaging > -1) + config.averaging = (sc->averaging > 0) ? 1 : 0; + + // Frequency divisor (19 - 255) + if (sc->divisor > 18 && sc->divisor < 256) + config.divisor = sc->divisor; + + // Start saving samples when adc value larger than trigger_threshold + if (sc->trigger_threshold > -1) + config.trigger_threshold = sc->trigger_threshold; + + // Skip n adc samples before saving + if (sc->samples_to_skip > -1) + config.samples_to_skip = sc->samples_to_skip; if (sc->verbose) printConfig(); @@ -113,7 +128,7 @@ uint32_t getSampleCounter() { return samples.total_saved; } -void logSample(uint8_t sample, uint8_t decimation, uint32_t bits_per_sample, bool avg) { +void logSample(uint8_t sample, uint8_t decimation, uint8_t bits_per_sample, bool avg) { if (!data.buffer) return; @@ -207,8 +222,8 @@ void LFSetupFPGAForADC(int divisor, bool lf_field) { * @param verbose - is true, dbprints the status, else no outputs * @return the number of bits occupied by the samples. */ -uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool avg, int trigger_threshold, - bool verbose, uint32_t sample_size, uint32_t cancel_after, uint32_t samples_to_skip) { +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) { initSampleBuffer(&sample_size); diff --git a/armsrc/lfsampling.h b/armsrc/lfsampling.h index 8ccaa5579..e97a3ac1a 100644 --- a/armsrc/lfsampling.h +++ b/armsrc/lfsampling.h @@ -42,8 +42,8 @@ uint32_t SampleLF(bool verbose, uint32_t sample_size); **/ uint32_t SniffLF(); -uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool avg, int trigger_threshold, - bool verbose, uint32_t sample_size, uint32_t cancel_after, uint32_t samples_to_skip); +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); // adds sample size to default options uint32_t DoPartialAcquisition(int trigger_threshold, bool verbose, uint32_t sample_size, uint32_t cancel_after); @@ -69,8 +69,8 @@ uint32_t DoAcquisition_config(bool verbose, uint32_t sample_size); /** * Refactoring of lf sampling buffer */ -void initSamplingBuffer(uint32_t *sample_size); -void logSample(uint8_t sample, uint8_t decimation, uint32_t bits_per_sample, bool avg); +void initSampleBuffer(uint32_t *sample_size); +void logSample(uint8_t sample, uint8_t decimation, uint8_t bits_per_sample, bool avg); uint32_t getSampleCounter(); /** diff --git a/client/cmdlf.c b/client/cmdlf.c index 64ff0ed9a..337444f1e 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -68,9 +68,10 @@ static int usage_lf_cmdread(void) { PrintAndLogEx(NORMAL, " c Command bytes (in ones and zeros)"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, " ************* " _YELLOW_("All periods in microseconds (us)")); - PrintAndLogEx(NORMAL, " ************* Use " _YELLOW_("'lf config'") "to configure options."); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf cmdread d 80 z 100 o 200 c 11000"); + PrintAndLogEx(NORMAL, "Extras:"); + PrintAndLogEx(NORMAL, " use " _YELLOW_("'lf config'")"to set parameters."); return PM3_SUCCESS; } static int usage_lf_read(void) { @@ -79,16 +80,16 @@ static int usage_lf_read(void) { PrintAndLogEx(NORMAL, " h This help"); PrintAndLogEx(NORMAL, " d #samples # samples to collect (optional)"); PrintAndLogEx(NORMAL, " s silent"); - PrintAndLogEx(NORMAL, "Use 'lf config' to set parameters."); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf read s d 12000 - collects 12000 samples silent"); PrintAndLogEx(NORMAL, " lf read"); + PrintAndLogEx(NORMAL, "Extras:"); + PrintAndLogEx(NORMAL, " use " _YELLOW_("'lf config'")"to set parameters."); return PM3_SUCCESS; } static int usage_lf_sim(void) { PrintAndLogEx(NORMAL, "Simulate low frequence tag from graphbuffer."); - PrintAndLogEx(NORMAL, "Use " _YELLOW_("'lf config'")" to set parameters."); PrintAndLogEx(NORMAL, "Usage: lf sim [h] "); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h This help"); @@ -96,16 +97,19 @@ static int usage_lf_sim(void) { PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf sim 240 - start simulating with 240ms gap"); PrintAndLogEx(NORMAL, " lf sim"); + PrintAndLogEx(NORMAL, "Extras:"); + PrintAndLogEx(NORMAL, " use " _YELLOW_("'lf config'")"to set parameters."); return PM3_SUCCESS; } static int usage_lf_sniff(void) { PrintAndLogEx(NORMAL, "Sniff low frequence signal."); - PrintAndLogEx(NORMAL, "Use " _YELLOW_("'lf config'")" to set parameters."); - PrintAndLogEx(NORMAL, "Use " _YELLOW_("'data samples'")" command to download from device, and " _YELLOW_("'data plot'")" to look at it"); - PrintAndLogEx(NORMAL, "Usage: lf sniff [h]"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h This help"); + PrintAndLogEx(NORMAL, "Extras:"); + PrintAndLogEx(NORMAL, " use " _YELLOW_("'lf config'")"to set parameters."); + PrintAndLogEx(NORMAL, " use " _YELLOW_("'data samples'")"command to download from device"); + PrintAndLogEx(NORMAL, " use " _YELLOW_("'data plot'")"to look at it"); return PM3_SUCCESS; } static int usage_lf_config(void) { @@ -117,22 +121,17 @@ static int usage_lf_config(void) { PrintAndLogEx(NORMAL, " q Manually set freq divisor. %d -> 134 kHz, %d -> 125 kHz", LF_DIVISOR_134, LF_DIVISOR_125); PrintAndLogEx(NORMAL, " f Manually set frequency in kHz"); PrintAndLogEx(NORMAL, " b Sets resolution of bits per sample. Default (max): 8"); - PrintAndLogEx(NORMAL, " d Sets decimation. A value of N saves only 1 in N samples. Default: 1"); + PrintAndLogEx(NORMAL, " d Sets decimation. A value of N saves only 1 in N samples. Default: 1"); PrintAndLogEx(NORMAL, " a [0|1] Averaging - if set, will average the stored sample value when decimating. Default: 1"); PrintAndLogEx(NORMAL, " t Sets trigger threshold. 0 means no threshold (range: 0-128)"); PrintAndLogEx(NORMAL, " s Sets a number of samples to skip before capture. Default: 0"); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " lf config"); - PrintAndLogEx(NORMAL, " Shows current config"); - PrintAndLogEx(NORMAL, " lf config b 8 L"); - PrintAndLogEx(NORMAL, " Samples at 125 kHz, 8bps."); - PrintAndLogEx(NORMAL, " lf config H b 4 d 3"); - PrintAndLogEx(NORMAL, " Samples at 134 kHz, averages three samples into one, stored with "); - PrintAndLogEx(NORMAL, " a resolution of 4 bits per sample."); - PrintAndLogEx(NORMAL, " lf read"); - PrintAndLogEx(NORMAL, " Performs a read (active field)"); - PrintAndLogEx(NORMAL, " lf sniff"); - PrintAndLogEx(NORMAL, " Performs a sniff (no active field)"); + PrintAndLogEx(NORMAL, " lf config - shows current config"); + PrintAndLogEx(NORMAL, " lf config b 8 L - samples at 125 kHz, 8bps."); + PrintAndLogEx(NORMAL, " lf config H b 4 d 3 - samples at 134 kHz, averages three samples into one, stored with "); + PrintAndLogEx(NORMAL, " a resolution of 4 bits per sample."); + PrintAndLogEx(NORMAL, " lf read - performs a read (active field)"); + PrintAndLogEx(NORMAL, " lf sniff - performs a sniff (no active field)"); return PM3_SUCCESS; } static int usage_lf_simfsk(void) { @@ -457,7 +456,11 @@ int lf_config(sample_config *config) { if (!session.pm3_present) return PM3_ENOTTY; clearCommandBuffer(); - SendCommandNG(CMD_LF_SAMPLING_SET_CONFIG, (uint8_t *)config, sizeof(sample_config)); + if (config != NULL) + SendCommandNG(CMD_LF_SAMPLING_SET_CONFIG, (uint8_t *)config, sizeof(sample_config)); + else + SendCommandNG(CMD_LF_SAMPLING_GET_CONFIG, NULL, 0); + return PM3_SUCCESS; } @@ -465,15 +468,22 @@ int CmdLFConfig(const char *Cmd) { if (!session.pm3_present) return PM3_ENOTTY; - uint8_t divisor = 0;//Frequency divisor - uint8_t bps = 0; // Bits per sample - uint8_t decimation = 0; //How many to keep - bool averaging = 1; // Defaults to true - bool errors = false; - int trigger_threshold = -1;//Means no change - uint8_t unsigned_trigg = 0; - uint32_t samples_to_skip = 0; // will return offset to 0 if not supplied. Could set to 0xffffffff if needed to not update + // if called with no params, just print the device config + if (strlen(Cmd) == 0) { + return lf_config(NULL); + } + sample_config config = { + .decimation = -1, + .bits_per_sample = -1, + .averaging = -1, + .divisor = -1, + .trigger_threshold = -1, + .samples_to_skip = -1, + .verbose = true + }; + + bool errors = false; uint8_t cmdp = 0; while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { @@ -481,16 +491,16 @@ int CmdLFConfig(const char *Cmd) { case 'h': return usage_lf_config(); case 'H': - divisor = LF_DIVISOR_134; + config.divisor = LF_DIVISOR_134; cmdp++; break; case 'L': - divisor = LF_DIVISOR_125; + config.divisor = LF_DIVISOR_125; cmdp++; break; case 'q': - errors |= param_getdec(Cmd, cmdp + 1, &divisor); - if (divisor < 19) { + config.divisor = param_get8ex(Cmd, cmdp + 1, 95, 10); + if (config.divisor < 19) { PrintAndLogEx(ERR, "divisor must be between 19 and 255"); return PM3_EINVARG; } @@ -498,36 +508,50 @@ int CmdLFConfig(const char *Cmd) { break; case 'f': { int freq = param_get32ex(Cmd, cmdp + 1, 125, 10); - divisor = LF_FREQ2DIV(freq); - if (divisor < 19) { + config.divisor = LF_FREQ2DIV(freq); + if (config.divisor < 19) { PrintAndLogEx(ERR, "freq must be between 47 and 600"); return PM3_EINVARG; } cmdp += 2; break; } - case 't': - errors |= param_getdec(Cmd, cmdp + 1, &unsigned_trigg); + case 't': { + uint8_t trigg = 0; + errors |= param_getdec(Cmd, cmdp + 1, &trigg); cmdp += 2; if (!errors) { - trigger_threshold = unsigned_trigg; - g_lf_threshold_set = (trigger_threshold > 0); + config.trigger_threshold = trigg; + g_lf_threshold_set = (config.trigger_threshold > 0); } break; - case 'b': - errors |= param_getdec(Cmd, cmdp + 1, &bps); + } + case 'b': { + config.bits_per_sample = param_get8ex(Cmd, cmdp + 1, 8, 10); + + // bps is limited to 8 + if (config.bits_per_sample >> 4) + config.bits_per_sample = 8; + cmdp += 2; break; - case 'd': - errors |= param_getdec(Cmd, cmdp + 1, &decimation); + } + case 'd': { + config.decimation = param_get8ex(Cmd, cmdp + 1, 1, 10); + + // decimation is limited to 255 + if (config.decimation >> 4) + config.decimation = 8; + cmdp += 2; break; + } case 'a': - averaging = param_getchar(Cmd, cmdp + 1) == '1'; + config.averaging = (param_getchar(Cmd, cmdp + 1) == '1'); cmdp += 2; break; case 's': - samples_to_skip = param_get32ex(Cmd, cmdp + 1, 0, 10); + config.samples_to_skip = param_get32ex(Cmd, cmdp + 1, 0, 10); cmdp += 2; break; default: @@ -540,15 +564,6 @@ int CmdLFConfig(const char *Cmd) { // validations if (errors) return usage_lf_config(); - // print current settings. - if (cmdp == 0) - return lf_config(NULL); - - // bps is limited to 8 - if (bps >> 4) bps = 8; - - sample_config config = { decimation, bps, averaging, divisor, trigger_threshold, samples_to_skip, true }; - return lf_config(&config); } @@ -1334,13 +1349,14 @@ static command_t CommandTable[] = { {"visa2000", CmdLFVisa2k, AlwaysAvailable, "{ Visa2000 RFIDs... }"}, {"", CmdHelp, AlwaysAvailable, ""}, {"config", CmdLFConfig, IfPm3Lf, "Get/Set config for LF sampling, bit/sample, decimation, frequency"}, - {"cmdread", CmdLFCommandRead, IfPm3Lf, " <'0' period> <'1' period> ['h' 134] \n\t\t-- Modulate LF reader field to send command before read (all periods in microseconds)"}, - {"read", CmdLFRead, IfPm3Lf, "['s' silent] Read 125/134 kHz LF ID-only tag. Do 'lf read h' for help"}, - {"search", CmdLFfind, AlwaysAvailable, "[offline] ['u'] Read and Search for valid known tag (in offline mode it you can load first then search) \n\t\t-- 'u' to search for unknown tags"}, - {"sim", CmdLFSim, IfPm3Lf, "[GAP] -- Simulate LF tag from buffer with optional GAP (in microseconds)"}, - {"simask", CmdLFaskSim, IfPm3Lf, "[clock] [invert <1|0>] [biphase/manchester/raw <'b'|'m'|'r'>] [msg separator 's'] [d ] \n\t\t-- Simulate LF ASK tag from demodbuffer or input"}, - {"simfsk", CmdLFfskSim, IfPm3Lf, "[c ] [i] [H ] [L ] [d ] \n\t\t-- Simulate LF FSK tag from demodbuffer or input"}, - {"simpsk", CmdLFpskSim, IfPm3Lf, "[1|2|3] [c ] [i] [r ] [d ] \n\t\t-- Simulate LF PSK tag from demodbuffer or input"}, + {"cmdread", CmdLFCommandRead, IfPm3Lf, "Modulate LF reader field to send command before read (all periods in microseconds)"}, + {"read", CmdLFRead, IfPm3Lf, "Read LF tag"}, + {"search", CmdLFfind, AlwaysAvailable, "Read and Search for valid known tag (in offline mode it you can load first then search)"}, + {"sim", CmdLFSim, IfPm3Lf, "Simulate LF tag from buffer with optional GAP (in microseconds)"}, + {"simask", CmdLFaskSim, IfPm3Lf, "Simulate LF ASK tag from demodbuffer or input"}, + {"simfsk", CmdLFfskSim, IfPm3Lf, "Simulate LF FSK tag from demodbuffer or input"}, + {"simpsk", CmdLFpskSim, IfPm3Lf, "Simulate LF PSK tag from demodbuffer or input"}, +// {"simpsk", CmdLFnrzSim, IfPm3Lf, "Simulate LF NRZ tag from demodbuffer or input"}, {"simbidir", CmdLFSimBidir, IfPm3Lf, "Simulate LF tag (with bidirectional data transmission between reader and tag)"}, {"sniff", CmdLFSniff, IfPm3Lf, "Sniff LF traffic between reader and tag"}, {"tune", CmdLFTune, IfPm3Lf, "Continuously measure LF antenna tuning"}, diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 44747b1ea..9100348bc 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -113,12 +113,12 @@ typedef struct { // A struct used to send sample-configs over USB typedef struct { - uint8_t decimation; - uint8_t bits_per_sample; - bool averaging; - int divisor; - int trigger_threshold; - uint32_t samples_to_skip; + int8_t decimation; + int8_t bits_per_sample; + int8_t averaging; + int16_t divisor; + int16_t trigger_threshold; + int32_t samples_to_skip; bool verbose; } PACKED sample_config; /* From 52aa2c77bca6afe675e8eca7b01d8d0d69fa142e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 9 Jan 2020 19:38:19 +0100 Subject: [PATCH 1414/1854] textual --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f3f908e3..44607add4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,10 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] - - Change `lf indala demod` - added @randomdude42's decode Heden 2L/Hedengren format (@iceman) Thanks to @randomdude42 + - Fix `lf config` - when called with no params, it no longer mess up all device lf config settings. (@iceman1001) + - Change `lf indala clone` - new option `--Q5` writes to q5/T5555 tags. (@iceman1001) + - Change `lf indala clone` - new option `-c ` allows cloning INDALA tag from Heden2L/Hedengren ID format (@iceman1001) - Thanks to @randomdude42 for solution + - Change `lf indala demod` - added decode Heden2L/Hedengren format (@iceman1001) - Thanks to @randomdude42 for solution - Add `commands.md` - document with all proxmark client commands. Generated with XX_internal_command_dump_markdown_XX. (@iceman1001) - Change `lf pac clone` - new option `c ` to allow cloning PAC/Stanley tag from card ID (@danshuk) - Change `lf pac read` - decoded PAC/Stanley card ID (@danshuk) From 3e7f687e485144bd63fe464ff593ab9c8ac756d5 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 9 Jan 2020 20:02:01 +0100 Subject: [PATCH 1415/1854] not verbose --- client/cmdlfawid.c | 2 +- client/cmdlffdx.c | 2 +- client/cmdlfgallagher.c | 2 +- client/cmdlfguard.c | 2 +- client/cmdlfhid.c | 2 +- client/cmdlfindala.c | 8 +++++--- client/cmdlfio.c | 2 +- client/cmdlfkeri.c | 2 +- client/cmdlfmotorola.c | 6 +++--- client/cmdlfnedap.c | 2 +- client/cmdlfnoralsy.c | 2 +- client/cmdlfpac.c | 2 +- client/cmdlfparadox.c | 2 +- client/cmdlfpresco.c | 2 +- client/cmdlfpyramid.c | 2 +- client/cmdlfsecurakey.c | 2 +- client/cmdlfviking.c | 2 +- client/cmdlfvisa2000.c | 2 +- client/cmdmain.c | 2 +- 19 files changed, 25 insertions(+), 23 deletions(-) diff --git a/client/cmdlfawid.c b/client/cmdlfawid.c index e9fe6d6e1..38c3675d1 100644 --- a/client/cmdlfawid.c +++ b/client/cmdlfawid.c @@ -333,7 +333,7 @@ static int CmdAWIDDemod(const char *Cmd) { // this read is the "normal" read, which download lf signal and tries to demod here. static int CmdAWIDRead(const char *Cmd) { - lf_read(true, 12000); + lf_read(false, 12000); return CmdAWIDDemod(Cmd); } diff --git a/client/cmdlffdx.c b/client/cmdlffdx.c index 06e45f515..2f3f81d1d 100644 --- a/client/cmdlffdx.c +++ b/client/cmdlffdx.c @@ -258,7 +258,7 @@ static int CmdFdxDemod(const char *Cmd) { } static int CmdFdxRead(const char *Cmd) { - lf_read(true, 10000); + lf_read(false, 10000); return CmdFdxDemod(Cmd); } diff --git a/client/cmdlfgallagher.c b/client/cmdlfgallagher.c index df822f24a..ef28f1326 100644 --- a/client/cmdlfgallagher.c +++ b/client/cmdlfgallagher.c @@ -135,7 +135,7 @@ static int CmdGallagherDemod(const char *Cmd) { } static int CmdGallagherRead(const char *Cmd) { - lf_read(true, 4096 * 2 + 20); + lf_read(false, 4096 * 2 + 20); return CmdGallagherDemod(Cmd); } diff --git a/client/cmdlfguard.c b/client/cmdlfguard.c index 79ec13c71..8597f4759 100644 --- a/client/cmdlfguard.c +++ b/client/cmdlfguard.c @@ -147,7 +147,7 @@ static int CmdGuardDemod(const char *Cmd) { } static int CmdGuardRead(const char *Cmd) { - lf_read(true, 10000); + lf_read(false, 10000); return CmdGuardDemod(Cmd); } diff --git a/client/cmdlfhid.c b/client/cmdlfhid.c index f5ad3717b..a41d183e7 100644 --- a/client/cmdlfhid.c +++ b/client/cmdlfhid.c @@ -255,7 +255,7 @@ static int CmdHIDDemod(const char *Cmd) { // this read is the "normal" read, which download lf signal and tries to demod here. static int CmdHIDRead(const char *Cmd) { - lf_read(true, 12000); + lf_read(false, 12000); return CmdHIDDemod(Cmd); } diff --git a/client/cmdlfindala.c b/client/cmdlfindala.c index c5c32d62d..11950a0c5 100644 --- a/client/cmdlfindala.c +++ b/client/cmdlfindala.c @@ -115,7 +115,7 @@ static void encodeHeden2L(uint8_t *dest, uint32_t cardnumber) { dest[i/8] = bytebits_to_byte(template + i, 8); } - PrintAndLogEx(INFO, "Heden2L Cardnumber %u ; RawID %s", cardnumber, sprint_hex(dest, 8)); + PrintAndLogEx(INFO, "Heden-2L card number %u", cardnumber); } static void decodeHeden2L(uint8_t *bits) { @@ -483,7 +483,7 @@ static int CmdIndalaDemodAlt(const char *Cmd) { // this read is the "normal" read, which download lf signal and tries to demod here. static int CmdIndalaRead(const char *Cmd) { - lf_read(true, 30000); + lf_read(false, 30000); return CmdIndalaDemod(Cmd); } @@ -601,8 +601,10 @@ static int CmdIndalaClone(const char *Cmd) { max = 8; } else { // 64 BIT UID - if (got_cn) + if (got_cn) { encodeHeden2L(data, cardnumber); + datalen = 8; + } // config for Indala 64 format (RF/32;PSK1 with RF/2;Maxblock=2) PrintAndLogEx(INFO, "Preparing to clone Indala 64bit tag with RawID %s", sprint_hex(data, datalen)); diff --git a/client/cmdlfio.c b/client/cmdlfio.c index b640bed41..1a25fca17 100644 --- a/client/cmdlfio.c +++ b/client/cmdlfio.c @@ -184,7 +184,7 @@ static int CmdIOProxDemod(const char *Cmd) { // this read is the "normal" read, which download lf signal and tries to demod here. static int CmdIOProxRead(const char *Cmd) { - lf_read(true, 12000); + lf_read(false, 12000); return CmdIOProxDemod(Cmd); } static int CmdIOProxSim(const char *Cmd) { diff --git a/client/cmdlfkeri.c b/client/cmdlfkeri.c index 394d16330..4846b5378 100644 --- a/client/cmdlfkeri.c +++ b/client/cmdlfkeri.c @@ -115,7 +115,7 @@ static int CmdKeriDemod(const char *Cmd) { } static int CmdKeriRead(const char *Cmd) { - lf_read(true, 10000); + lf_read(false, 10000); return CmdKeriDemod(Cmd); } diff --git a/client/cmdlfmotorola.c b/client/cmdlfmotorola.c index dbcf28e40..9f0ee1f41 100644 --- a/client/cmdlfmotorola.c +++ b/client/cmdlfmotorola.c @@ -124,8 +124,8 @@ static int CmdMotorolaRead(const char *Cmd) { // Motorola Flexpass seem to work at 74 kHz // and take about 4400 samples to befor modulating sample_config sc = { - .decimation = 0, - .bits_per_sample = 0, + .decimation = -1, + .bits_per_sample = -1, .averaging = false, .divisor = LF_FREQ2DIV(74), .trigger_threshold = -1, @@ -135,7 +135,7 @@ static int CmdMotorolaRead(const char *Cmd) { lf_config(&sc); // 64 * 32 * 2 * n-ish - lf_read(true, 5000); + lf_read(false, 5000); // reset back to 125 kHz sc.divisor = LF_DIVISOR_125; diff --git a/client/cmdlfnedap.c b/client/cmdlfnedap.c index 84b433a0c..c3d6d1ace 100644 --- a/client/cmdlfnedap.c +++ b/client/cmdlfnedap.c @@ -299,7 +299,7 @@ lf t55xx wr b 4 d 4c0003ff */ static int CmdLFNedapRead(const char *Cmd) { - lf_read(true, 16000); + lf_read(false, 16000); return CmdLFNedapDemod(Cmd); } diff --git a/client/cmdlfnoralsy.c b/client/cmdlfnoralsy.c index ceebb8e2d..d7728a3d9 100644 --- a/client/cmdlfnoralsy.c +++ b/client/cmdlfnoralsy.c @@ -133,7 +133,7 @@ static int CmdNoralsyDemod(const char *Cmd) { } static int CmdNoralsyRead(const char *Cmd) { - lf_read(true, 8000); + lf_read(false, 8000); return CmdNoralsyDemod(Cmd); } diff --git a/client/cmdlfpac.c b/client/cmdlfpac.c index 040c8af0a..63a3e16cd 100644 --- a/client/cmdlfpac.c +++ b/client/cmdlfpac.c @@ -181,7 +181,7 @@ static int CmdPacDemod(const char *Cmd) { } static int CmdPacRead(const char *Cmd) { - lf_read(true, 4096 * 2 + 20); + lf_read(false, 4096 * 2 + 20); return CmdPacDemod(Cmd); } diff --git a/client/cmdlfparadox.c b/client/cmdlfparadox.c index c154e7efa..29e247b59 100644 --- a/client/cmdlfparadox.c +++ b/client/cmdlfparadox.c @@ -126,7 +126,7 @@ static int CmdParadoxDemod(const char *Cmd) { //by marshmellow //see ASKDemod for what args are accepted static int CmdParadoxRead(const char *Cmd) { - lf_read(true, 10000); + lf_read(false, 10000); return CmdParadoxDemod(Cmd); } diff --git a/client/cmdlfpresco.c b/client/cmdlfpresco.c index abce377f4..a0619d794 100644 --- a/client/cmdlfpresco.c +++ b/client/cmdlfpresco.c @@ -100,7 +100,7 @@ static int CmdPrescoDemod(const char *Cmd) { //see ASKDemod for what args are accepted static int CmdPrescoRead(const char *Cmd) { // Presco Number: 123456789 --> Sitecode 30 | usercode 8665 - lf_read(true, 12000); + lf_read(false, 12000); return CmdPrescoDemod(Cmd); } diff --git a/client/cmdlfpyramid.c b/client/cmdlfpyramid.c index a36bd34e3..5737c87b9 100644 --- a/client/cmdlfpyramid.c +++ b/client/cmdlfpyramid.c @@ -209,7 +209,7 @@ static int CmdPyramidDemod(const char *Cmd) { } static int CmdPyramidRead(const char *Cmd) { - lf_read(true, 15000); + lf_read(false, 15000); return CmdPyramidDemod(Cmd); } diff --git a/client/cmdlfsecurakey.c b/client/cmdlfsecurakey.c index 48ec731ce..ef4b5be8e 100644 --- a/client/cmdlfsecurakey.c +++ b/client/cmdlfsecurakey.c @@ -125,7 +125,7 @@ static int CmdSecurakeyDemod(const char *Cmd) { } static int CmdSecurakeyRead(const char *Cmd) { - lf_read(true, 8000); + lf_read(false, 8000); return CmdSecurakeyDemod(Cmd); } diff --git a/client/cmdlfviking.c b/client/cmdlfviking.c index c404b4f0a..69d8aee65 100644 --- a/client/cmdlfviking.c +++ b/client/cmdlfviking.c @@ -79,7 +79,7 @@ static int CmdVikingDemod(const char *Cmd) { //by marshmellow //see ASKDemod for what args are accepted static int CmdVikingRead(const char *Cmd) { - lf_read(true, 10000); + lf_read(false, 10000); return CmdVikingDemod(Cmd); } diff --git a/client/cmdlfvisa2000.c b/client/cmdlfvisa2000.c index 677562e12..551a1efbb 100644 --- a/client/cmdlfvisa2000.c +++ b/client/cmdlfvisa2000.c @@ -159,7 +159,7 @@ static int CmdVisa2kDemod(const char *Cmd) { // 64*96*2=12288 samples just in case we just missed the first preamble we can still catch 2 of them static int CmdVisa2kRead(const char *Cmd) { - lf_read(true, 20000); + lf_read(false, 20000); return CmdVisa2kDemod(Cmd); } diff --git a/client/cmdmain.c b/client/cmdmain.c index 06f44e1aa..c2364d8f1 100644 --- a/client/cmdmain.c +++ b/client/cmdmain.c @@ -94,7 +94,7 @@ static int CmdAuto(const char *Cmd) { PrintAndLogEx(INFO, "Trying 'lf read' and save a trace for you..."); CmdPlot(""); - lf_read(true, 40000); + lf_read(false, 40000); char *fname = calloc(100, sizeof(uint8_t)); AppendDate(fname, 100, "f lf_unknown_%Y-%m-%d_%H:%M"); CmdSave(fname); From 57f026312b0ed715b23ba3cd092c18da15a121ee Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 9 Jan 2020 22:58:12 +0100 Subject: [PATCH 1416/1854] Chg: generators from luascripts into client --- common/generator.c | 215 ++++++++++++++++++++++++++++++++++++--------- common/generator.h | 14 +-- 2 files changed, 180 insertions(+), 49 deletions(-) diff --git a/common/generator.c b/common/generator.c index 174657573..9226964d9 100644 --- a/common/generator.c +++ b/common/generator.c @@ -15,10 +15,19 @@ #include #include #include -#include "commonutil.h" +#include "commonutil.h" //BSWAP_16 +#include "common.h" //BSWAP_32/64 #include "util.h" #include "pm3_cmd.h" #include "ui.h" +#include "mbedtls/sha1.h" + +#if defined(__APPLE__) +#include +#define BSWAP_16(x) OSSwapInt16(x) +#define BSWAP_32(x) OSSwapInt32(x) +#define BSWAP_64(x) OSSwapInt64(x) +#endif // Implemetation tips: // For each implementation of the algos, I recommend adding a self test for easy "simple unit" tests when Travic CI / Appveyour runs. @@ -32,6 +41,8 @@ // XYZ 3D printing // Vinglock //------------------------------------ +static void transform_D(uint8_t *ru) { + const uint32_t c_D[] = { 0x6D835AFC, 0x7D15CD97, 0x0942B409, 0x32F9C923, 0xA811FB02, 0x64F121E8, 0xD1CC8B4E, 0xE8873E6F, 0x61399BBB, 0xF1B91926, 0xAC661520, 0xA21A31C9, @@ -40,7 +51,6 @@ const uint32_t c_D[] = { 0x5728B869, 0x30726D5A }; -static void transform_D(uint8_t *ru) { //Transform uint8_t i; uint8_t p = 0; @@ -185,42 +195,120 @@ uint16_t ul_ev1_packgenD(uint8_t *uid) { // MFC keyfile generation stuff //------------------------------------ // Vinglock -int mfc_algo_ving_one(uint8_t *uid, uint8_t sector, uint64_t *key) { +int mfc_algo_ving_one(uint8_t *uid, uint8_t sector, uint8_t keytype, uint64_t *key) { if (sector > 15) return PM3_EINVARG; if (key == NULL) return PM3_EINVARG; + *key = 0; return PM3_SUCCESS; } int mfc_algo_ving_all(uint8_t *uid, uint8_t *keys) { if (keys == NULL) return PM3_EINVARG; + for (int keytype = 0; keytype < 2; keytype++) { + for (int sector = 0; sector < 16; sector++){ + uint64_t key = 0; + mfc_algo_ving_one(uid, sector, keytype, &key ); + num_to_bytes(key, 6, keys + (keytype * 16 * 6) + (sector * 6)); + } + } return PM3_SUCCESS; } // Yale Doorman -int mfc_algo_yale_one(uint8_t *uid, uint8_t sector, uint64_t *key) { +int mfc_algo_yale_one(uint8_t *uid, uint8_t sector, uint8_t keytype, uint64_t *key) { if (sector > 15) return PM3_EINVARG; if (key == NULL) return PM3_EINVARG; + *key = 0; return PM3_SUCCESS; } int mfc_algo_yale_all(uint8_t *uid, uint8_t *keys) { if (keys == NULL) return PM3_EINVARG; + for (int keytype = 0; keytype < 2; keytype++) { + for (int sector = 0; sector < 16; sector++){ + uint64_t key = 0; + mfc_algo_yale_one(uid, sector, keytype, &key ); + num_to_bytes(key, 6, keys + (keytype * 16 * 6) + (sector * 6)); + } + } return PM3_SUCCESS; } // Saflok / Maid UID to key. -int mfc_algo_saflok_one(uint8_t *uid, uint8_t sector, uint64_t *key) { +int mfc_algo_saflok_one(uint8_t *uid, uint8_t sector, uint8_t keytype, uint64_t *key) { if (sector > 15) return PM3_EINVARG; if (key == NULL) return PM3_EINVARG; + *key = 0; return PM3_SUCCESS; } int mfc_algo_saflok_all(uint8_t *uid, uint8_t *keys) { if (keys == NULL) return PM3_EINVARG; + for (int keytype = 0; keytype < 2; keytype++) { + for (int sector = 0; sector < 16; sector++){ + uint64_t key = 0; + mfc_algo_saflok_one(uid, sector, keytype, &key ); + num_to_bytes(key, 6, keys + (keytype * 16 * 6) + (sector * 6)); + } + } return PM3_SUCCESS; } // MIZIP algo -int mfc_algo_mizip_one(uint8_t *uid, uint8_t sector, uint64_t *key) { +int mfc_algo_mizip_one(uint8_t *uid, uint8_t sector, uint8_t keytype, uint64_t *key) { if (sector > 4) return PM3_EINVARG; if (key == NULL) return PM3_EINVARG; + + if (sector == 0) { + // A + if (keytype == 0) + *key = 0xA0A1A2A3A4A5U; + else // B + *key = 0xB4C132439eef; + + } else { + + uint8_t xor[6]; + + if ( keytype == 0 ) { + + uint64_t xor_tbl_a[] = { + 0x09125a2589e5, + 0xAB75C937922F, + 0xE27241AF2C09, + 0x317AB72F4490, + }; + + num_to_bytes(xor_tbl_a[sector - 1], 6, xor); + + *key = + (uint64_t)(uid[0] ^ xor[0] ) << 40 | + (uint64_t)(uid[1] ^ xor[1]) << 32 | + (uint64_t)(uid[2] ^ xor[2]) << 24 | + (uint64_t)(uid[3] ^ xor[3]) << 16 | + (uint64_t)(uid[0] ^ xor[4]) << 8 | + (uint64_t)(uid[1] ^ xor[5]) + ; + + } else { + uint64_t xor_tbl_b[] = { + 0xF12C8453D821, + 0x73E799FE3241, + 0xAA4D137656AE, + 0xB01327272DFD + }; + + // B + num_to_bytes(xor_tbl_b[sector - 1], 6, xor); + + *key = + (uint64_t)(uid[2] ^ xor[0]) << 40 | + (uint64_t)(uid[3] ^ xor[1]) << 32 | + (uint64_t)(uid[0] ^ xor[2]) << 24 | + (uint64_t)(uid[1] ^ xor[3]) << 16 | + (uint64_t)(uid[2] ^ xor[4]) << 8 | + (uint64_t)(uid[3] ^ xor[5]) + ; + + } + } return PM3_SUCCESS; } // returns all Mifare Mini (MFM) 10 keys. @@ -228,66 +316,103 @@ int mfc_algo_mizip_one(uint8_t *uid, uint8_t sector, uint64_t *key) { int mfc_algo_mizip_all(uint8_t *uid, uint8_t *keys) { if (keys == NULL) return PM3_EINVARG; - uint64_t xor_tbl[] = { - 0x09125a2589e5ULL, 0xF12C8453D821ULL, - 0xAB75C937922FULL, 0x73E799FE3241ULL, - 0xE27241AF2C09ULL, 0xAA4D137656AEULL, - 0x317AB72F4490ULL, 0xB01327272DFDULL - }; - - // A - num_to_bytes(0xA0A1A2A3A4A5ULL, 6, keys); - for (uint8_t i = 0; i < 4; i++) { - uint64_t a = - (uint64_t)(uid[0] ^ xor_tbl[i]) << 40 | - (uint64_t)(uid[1] ^ xor_tbl[i]) << 32 | - (uint64_t)(uid[2] ^ xor_tbl[i]) << 24 | - (uint64_t)(uid[3] ^ xor_tbl[i]) << 16 | - (uint64_t)(uid[1] ^ xor_tbl[i]) << 8 | - (uint64_t)(uid[2] ^ xor_tbl[i]) - ; - num_to_bytes(a, 6, keys + (1 * i * 6)); + for (int keytype = 0; keytype < 2; keytype++) { + for (int sector = 0; sector < 5; sector++){ + uint64_t key = 0; + mfc_algo_mizip_one(uid, sector, keytype, &key); + num_to_bytes(key, 6, keys + (keytype * 5 * 6) + (sector * 6)); } - - // B - num_to_bytes(0xB4C132439eefULL, 6, keys + (5 * 6)); - for (uint8_t i = 0; i < 4; i++) { - uint64_t b = - (uint64_t)(uid[2] ^ xor_tbl[i + 1]) << 40 | - (uint64_t)(uid[3] ^ xor_tbl[i + 1]) << 32 | - (uint64_t)(uid[0] ^ xor_tbl[i + 1]) << 24 | - (uint64_t)(uid[1] ^ xor_tbl[i + 1]) << 16 | - (uint64_t)(uid[2] ^ xor_tbl[i + 1]) << 8 | - (uint64_t)(uid[3] ^ xor_tbl[i + 1]) - ; - num_to_bytes(b, 6, keys + 30 + (1 * i * 6)); } return PM3_SUCCESS; } // Disney Infinity algo -int mfc_algo_di_one(uint8_t *uid, uint8_t sector, uint64_t *key) { - if (sector > 15) return PM3_EINVARG; +int mfc_algo_di_one(uint8_t *uid, uint8_t sector, uint8_t keytype, uint64_t *key) { + if (sector > 4) return PM3_EINVARG; if (key == NULL) return PM3_EINVARG; + + uint8_t hash[64]; + uint8_t input[] = { + 0x0A, 0x14, 0xFD, 0x05, 0x07, 0xFF, 0x4B, 0xCD, + 0x02, 0x6B, 0xA8, 0x3F, 0x0A, 0x3B, 0x89, 0xA9, + uid[0], uid[1], uid[2], uid[3], uid[4], uid[5], uid[6], + 0x28, 0x63, 0x29, 0x20, 0x44, 0x69, 0x73, 0x6E, + 0x65, 0x79, 0x20, 0x32, 0x30, 0x31, 0x33 + }; + + mbedtls_sha1(input, sizeof(input), hash); + + *key = ( + (uint64_t)hash[3] << 40 | + (uint64_t)hash[2] << 32 | + (uint64_t)hash[1] << 24 | + (uint64_t)hash[0] << 16 | + (uint64_t)hash[7] << 8 | + hash[6] + ); + return PM3_SUCCESS; } int mfc_algo_di_all(uint8_t *uid, uint8_t *keys) { if (keys == NULL) return PM3_EINVARG; + for (int keytype = 0; keytype < 2; keytype++) { + for (int sector = 0; sector < 5; sector++){ + uint64_t key = 0; + mfc_algo_di_one(uid, sector, keytype, &key); + num_to_bytes(key, 6, keys + (keytype * 5 * 6) + (sector * 6)); + } + } return PM3_SUCCESS; } // Skylanders -int mfc_algo_sky_one(uint8_t *uid, uint8_t sector, uint64_t *key) { +static uint64_t sky_crc64_like(uint64_t result, uint8_t sector) { + #define SKY_POLY UINT64_C(0x42f0e1eba9ea3693) + #define SKY_TOP UINT64_C(0x800000000000) + result ^= (uint64_t)sector << 40; + for(int i = 0; i < 8; i++) { + result = (result & SKY_TOP) ? (result << 1) ^ SKY_POLY : result << 1; + } + return result; +} +int mfc_algo_sky_one(uint8_t *uid, uint8_t sector, uint8_t keytype, uint64_t *key) { + +#define SKY_KEY_MASK 0xFFFFFFFFFFFF + if (sector > 15) return PM3_EINVARG; if (key == NULL) return PM3_EINVARG; + + if (sector == 0 && keytype == 0) { + *key = 0x4B0B20107CCB; + return PM3_SUCCESS; + } + if (keytype == 1) { + *key = 0x000000000000; + return PM3_SUCCESS; + } + + // hash UID + uint64_t hash = 0x9AE903260CC4; + for(int i = 0; i < 4; i++) { + hash = sky_crc64_like(hash, uid[i]); + } + + uint64_t sectorhash = sky_crc64_like(hash, sector); + *key = BSWAP_64(sectorhash & SKY_KEY_MASK) >> 16; return PM3_SUCCESS; } int mfc_algo_sky_all(uint8_t *uid, uint8_t *keys) { if (keys == NULL) return PM3_EINVARG; + for (int keytype = 0; keytype < 2; keytype++) { + for (int sector = 0; sector < 16; sector++){ + uint64_t key = 0; + mfc_algo_sky_one(uid, sector, keytype, &key); + num_to_bytes(key, 6, keys + (keytype * 16 * 6) + (sector * 6)); + } + } return PM3_SUCCESS; } - //------------------------------------ // Self tests //------------------------------------ @@ -323,6 +448,12 @@ int generator_selftest() { // success = (key1 == 0xD1E2AA68E39A); // PrintAndLogEx(success ? SUCCESS : WARNING, "UID | %s | %"PRIx64" | %s", sprint_hex(uid5, 4), key1, success ? "OK" : "->D1E2AA68E39A<--"); + uint8_t uid6[] = {0x74, 0x57, 0xCA, 0xA9}; + uint64_t key6 = 0; + mfc_algo_sky_one(uid6, 15, 0, &key6); + success = (key6 == 0x82c7e64bc565); + PrintAndLogEx(success ? SUCCESS : WARNING, "UID | %s | %"PRIx64" | %s", sprint_hex(uid6, 4), key6, success ? "OK" : "->82C7E64BC565<--"); + PrintAndLogEx(SUCCESS, "-------------------"); return PM3_SUCCESS; } diff --git a/common/generator.h b/common/generator.h index 8643c0de9..d7ca2b8ee 100644 --- a/common/generator.h +++ b/common/generator.h @@ -23,25 +23,25 @@ uint16_t ul_ev1_packgenB(uint8_t *uid); uint16_t ul_ev1_packgenC(uint8_t *uid); uint16_t ul_ev1_packgenD(uint8_t *uid); -int mfc_algo_ving_one(uint8_t *uid, uint8_t sector, uint64_t *key); +int mfc_algo_ving_one(uint8_t *uid, uint8_t sector, uint8_t keytype, uint64_t *key); int mfc_algo_ving_all(uint8_t *uid, uint8_t *keys); -int mfc_algo_yale_one(uint8_t *uid, uint8_t sector, uint64_t *key); +int mfc_algo_yale_one(uint8_t *uid, uint8_t sector, uint8_t keytype, uint64_t *key); int mfc_algo_yale_all(uint8_t *uid, uint8_t *keys); -int mfc_algo_saflok_one(uint8_t *uid, uint8_t sector, uint64_t *key); +int mfc_algo_saflok_one(uint8_t *uid, uint8_t sector, uint8_t keytype, uint64_t *key); int mfc_algo_saflok_all(uint8_t *uid, uint8_t *keys); -int mfc_algo_saflok_one(uint8_t *uid, uint8_t sector, uint64_t *key); +int mfc_algo_saflok_one(uint8_t *uid, uint8_t sector, uint8_t keytype, uint64_t *key); int mfc_algo_saflok_all(uint8_t *uid, uint8_t *keys); -int mfc_algo_mizip_one(uint8_t *uid, uint8_t sector, uint64_t *key); +int mfc_algo_mizip_one(uint8_t *uid, uint8_t sector, uint8_t keytype, uint64_t *key); int mfc_algo_mizip_all(uint8_t *uid, uint8_t *keys); -int mfc_algo_di_one(uint8_t *uid, uint8_t sector, uint64_t *key); +int mfc_algo_di_one(uint8_t *uid, uint8_t sector, uint8_t keytype, uint64_t *key); int mfc_algo_di_all(uint8_t *uid, uint8_t *keys); -int mfc_algo_sky_one(uint8_t *uid, uint8_t sector, uint64_t *key); +int mfc_algo_sky_one(uint8_t *uid, uint8_t sector, uint8_t keytype, uint64_t *key); int mfc_algo_sky_all(uint8_t *uid, uint8_t *keys); int generator_selftest(); From 07dfe8493c8af4f29a9595877494b1fd1a27232f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 9 Jan 2020 22:58:49 +0100 Subject: [PATCH 1417/1854] lf read no verbose --- client/cmdlfem4x.c | 4 ++-- client/cmdlfnexwatch.c | 2 +- client/cmdlfverichip.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c index 5493b124d..a8d7e06e3 100644 --- a/client/cmdlfem4x.c +++ b/client/cmdlfem4x.c @@ -468,7 +468,7 @@ static int CmdEM410xDemod(const char *Cmd) { // this read is the "normal" read, which download lf signal and tries to demod here. static int CmdEM410xRead(const char *Cmd) { - lf_read(true, 12288); + lf_read(false, 12288); return CmdEM410xDemod(Cmd); } @@ -625,7 +625,7 @@ static int CmdEM410xWatch(const char *Cmd) { PrintAndLogEx(WARNING, "\naborted via keyboard!\n"); break; } - lf_read(true, 12288); + lf_read(false, 12288); } while (CmdEM410xRead("") != PM3_SUCCESS); return PM3_SUCCESS; diff --git a/client/cmdlfnexwatch.c b/client/cmdlfnexwatch.c index e30a37a80..58ec81852 100644 --- a/client/cmdlfnexwatch.c +++ b/client/cmdlfnexwatch.c @@ -95,7 +95,7 @@ static int CmdNexWatchDemod(const char *Cmd) { //by marshmellow //see ASKDemod for what args are accepted static int CmdNexWatchRead(const char *Cmd) { - lf_read(true, 10000); + lf_read(false, 10000); return CmdNexWatchDemod(Cmd); } diff --git a/client/cmdlfverichip.c b/client/cmdlfverichip.c index 9bccefde4..fb2e4e777 100644 --- a/client/cmdlfverichip.c +++ b/client/cmdlfverichip.c @@ -78,7 +78,7 @@ static int CmdVerichipDemod(const char *Cmd) { } static int CmdVerichipRead(const char *Cmd) { - lf_read(true, 4096 * 2 + 20); + lf_read(false, 4096 * 2 + 20); return CmdVerichipDemod(Cmd); } From a459d150935b3cabac6947340eceea24a33d1911 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 9 Jan 2020 23:33:23 +0100 Subject: [PATCH 1418/1854] fix: osx doesnt need own bswap.. --- common/generator.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/common/generator.c b/common/generator.c index 9226964d9..22c63add5 100644 --- a/common/generator.c +++ b/common/generator.c @@ -22,13 +22,6 @@ #include "ui.h" #include "mbedtls/sha1.h" -#if defined(__APPLE__) -#include -#define BSWAP_16(x) OSSwapInt16(x) -#define BSWAP_32(x) OSSwapInt32(x) -#define BSWAP_64(x) OSSwapInt64(x) -#endif - // Implemetation tips: // For each implementation of the algos, I recommend adding a self test for easy "simple unit" tests when Travic CI / Appveyour runs. // See special note for MFC based algos. @@ -241,6 +234,7 @@ int mfc_algo_saflok_one(uint8_t *uid, uint8_t sector, uint8_t keytype, uint64_t } int mfc_algo_saflok_all(uint8_t *uid, uint8_t *keys) { if (keys == NULL) return PM3_EINVARG; + for (int keytype = 0; keytype < 2; keytype++) { for (int sector = 0; sector < 16; sector++){ uint64_t key = 0; From dd12b2db6efabeccf4bf243db958696c90e10b1b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 10 Jan 2020 15:43:12 +0100 Subject: [PATCH 1419/1854] textual --- doc/commands.md | 613 ++++++++++++++++++++++++------------------------ 1 file changed, 308 insertions(+), 305 deletions(-) diff --git a/doc/commands.md b/doc/commands.md index b4980fd41..ba9f14c93 100644 --- a/doc/commands.md +++ b/doc/commands.md @@ -1,8 +1,17 @@ - + +# Proxmark3 command dump + + +Some commands are available only if a Proxmark3 is actually connected. + +Check column "offline" for their availability. + + + |command |offline |description |------- |------- |----------- |`help `|Y |`This help. Use ' help' for details of a particular command.` -|`auto `|Y |`Automated detection process for unknown tags` +|`auto `|N |`Automated detection process for unknown tags` |`msleep `|Y |`Add a pause in milliseconds` |`rem `|Y |`Add a text line in log file` |`quit `|Y |`` @@ -38,7 +47,7 @@ |`data autocorr `|Y |`[window length] [g] -- Autocorrelation over window - g to save back to GraphBuffer (overwrite)` |`data biphaserawdecode `|Y |`[offset] [invert<0|1>] [maxErr] -- Biphase decode bin stream in DemodBuffer (offset = 0|1 bits to shift the decode start)` |`data bin2hex `|Y |` -- Converts binary to hexadecimal` -|`data bitsamples `|Y |`Get raw samples as bitstring` +|`data bitsamples `|N |`Get raw samples as bitstring` |`data buffclear `|Y |`Clears bigbuff on deviceside and graph window` |`data convertbitstream `|Y |`Convert GraphBuffer's 0/1 values to 127 / -127` |`data dec `|Y |`Decimate samples` @@ -46,7 +55,7 @@ |`data fsktonrz `|Y |`Convert fsk2 to nrz wave for alternate fsk demodulating (for weak fsk)` |`data getbitstream `|Y |`Convert GraphBuffer's >=1 values to 1 and <1 to 0` |`data grid `|Y |` -- overlay grid on graph window, use zero value to turn off either` -|`data hexsamples `|Y |` [] -- Dump big buffer as hex bytes` +|`data hexsamples `|N |` [] -- Dump big buffer as hex bytes` |`data hex2bin `|Y |` -- Converts hexadecimal to binary` |`data hide `|Y |`Hide graph window` |`data hpf `|Y |`Remove DC offset from trace` @@ -59,14 +68,14 @@ |`data plot `|Y |`Show graph window (hit 'h' in window for keystroke help)` |`data printdemodbuffer `|Y |`[x] [o] [l] -- print the data in the DemodBuffer - 'x' for hex output` |`data rawdemod `|Y |`[modulation] ... -see help (h option) -- Demodulate the data in the GraphBuffer and output binary` -|`data samples `|Y |`[512 - 40000] -- Get raw samples for graph window (GraphBuffer)` +|`data samples `|N |`[512 - 40000] -- Get raw samples for graph window (GraphBuffer)` |`data save `|Y |`Save trace (from graph window)` |`data setgraphmarkers `|Y |`[orange_marker] [blue_marker] (in graph window)` |`data scale `|Y |` -- Set cursor display scale in carrier frequency expressed in kHz` |`data setdebugmode `|Y |`<0|1|2> -- Set Debugging Level on client side` |`data shiftgraphzero `|Y |` -- Shift 0 for Graphed wave + or - shift value` |`data dirthreshold `|Y |` -- Max rising higher up-thres/ Min falling lower down-thres, keep rest as prev.` -|`data tune `|Y |`Get hw tune samples for graph window` +|`data tune `|N |`Get hw tune samples for graph window` |`data undec `|Y |`Un-decimate samples by 2` |`data zerocrossings `|Y |`Count time between zero-crossings` |`data iir `|Y |`apply IIR buttersworth filter on plotdata` @@ -79,19 +88,19 @@ |command |offline |description |------- |------- |----------- |`emv help `|Y |`This help` -|`emv exec `|Y |`Executes EMV contactless transaction.` -|`emv pse `|Y |`Execute PPSE. It selects 2PAY.SYS.DDF01 or 1PAY.SYS.DDF01 directory.` -|`emv search `|Y |`Try to select all applets from applets list and print installed applets.` -|`emv select `|Y |`Select applet.` -|`emv gpo `|Y |`Execute GetProcessingOptions.` -|`emv readrec `|Y |`Read files from card.` -|`emv genac `|Y |`Generate ApplicationCryptogram.` -|`emv challenge `|Y |`Generate challenge.` -|`emv intauth `|Y |`Internal authentication.` -|`emv scan `|Y |`Scan EMV card and save it contents to json file for emulator.` +|`emv exec `|N |`Executes EMV contactless transaction.` +|`emv pse `|N |`Execute PPSE. It selects 2PAY.SYS.DDF01 or 1PAY.SYS.DDF01 directory.` +|`emv search `|N |`Try to select all applets from applets list and print installed applets.` +|`emv select `|N |`Select applet.` +|`emv gpo `|N |`Execute GetProcessingOptions.` +|`emv readrec `|N |`Read files from card.` +|`emv genac `|N |`Generate ApplicationCryptogram.` +|`emv challenge `|N |`Generate challenge.` +|`emv intauth `|N |`Internal authentication.` +|`emv scan `|N |`Scan EMV card and save it contents to json file for emulator.` |`emv test `|Y |`Crypto logic test.` |`emv list `|Y |`List ISO7816 history` -|`emv roca `|Y |`Extract public keys and run ROCA test` +|`emv roca `|N |`Extract public keys and run ROCA test` ### hf @@ -102,9 +111,9 @@ |------- |------- |----------- |`hf help `|Y |`This help` |`hf list `|Y |`List protocol data in trace buffer` -|`hf tune `|Y |`Continuously measure HF antenna tuning` +|`hf tune `|N |`Continuously measure HF antenna tuning` |`hf search `|Y |`Search for known HF tags` -|`hf sniff `|Y |` Generic HF Sniff` +|`hf sniff `|N |` Generic HF Sniff` ### hf 14a @@ -115,15 +124,15 @@ |------- |------- |----------- |`hf 14a help `|Y |`This help` |`hf 14a list `|Y |`List ISO 14443-a history` -|`hf 14a info `|Y |`Tag information` -|`hf 14a reader `|Y |`Act like an ISO14443-a reader` -|`hf 14a cuids `|Y |` Collect n>0 ISO14443-a UIDs in one go` -|`hf 14a sim `|Y |` -- Simulate ISO 14443-a tag` -|`hf 14a sniff `|Y |`sniff ISO 14443-a traffic` -|`hf 14a apdu `|Y |`Send ISO 14443-4 APDU to tag` -|`hf 14a chaining `|Y |`Control ISO 14443-4 input chaining` -|`hf 14a raw `|Y |`Send raw hex data to tag` -|`hf 14a antifuzz `|Y |`Fuzzing the anticollision phase. Warning! Readers may react strange` +|`hf 14a info `|N |`Tag information` +|`hf 14a reader `|N |`Act like an ISO14443-a reader` +|`hf 14a cuids `|N |` Collect n>0 ISO14443-a UIDs in one go` +|`hf 14a sim `|N |` -- Simulate ISO 14443-a tag` +|`hf 14a sniff `|N |`sniff ISO 14443-a traffic` +|`hf 14a apdu `|N |`Send ISO 14443-4 APDU to tag` +|`hf 14a chaining `|N |`Control ISO 14443-4 input chaining` +|`hf 14a raw `|N |`Send raw hex data to tag` +|`hf 14a antifuzz `|N |`Fuzzing the anticollision phase. Warning! Readers may react strange` ### hf 14b @@ -133,15 +142,15 @@ |command |offline |description |------- |------- |----------- |`hf 14b help `|Y |`This help` -|`hf 14b dump `|Y |`Read all memory pages of an ISO14443-B tag, save to file` -|`hf 14b info `|Y |`Tag information` +|`hf 14b dump `|N |`Read all memory pages of an ISO14443-B tag, save to file` +|`hf 14b info `|N |`Tag information` |`hf 14b list `|Y |`List ISO 14443B history` -|`hf 14b raw `|Y |`Send raw hex data to tag` -|`hf 14b reader `|Y |`Act as a 14443B reader to identify a tag` -|`hf 14b sim `|Y |`Fake ISO 14443B tag` -|`hf 14b sniff `|Y |`Eavesdrop ISO 14443B` -|`hf 14b sriread `|Y |`Read contents of a SRI512 | SRIX4K tag` -|`hf 14b sriwrite `|Y |`Write data to a SRI512 | SRIX4K tag` +|`hf 14b raw `|N |`Send raw hex data to tag` +|`hf 14b reader `|N |`Act as a 14443B reader to identify a tag` +|`hf 14b sim `|N |`Fake ISO 14443B tag` +|`hf 14b sniff `|N |`Eavesdrop ISO 14443B` +|`hf 14b sriread `|N |`Read contents of a SRI512 | SRIX4K tag` +|`hf 14b sriwrite `|N |`Write data to a SRI512 | SRIX4K tag` ### hf 15 @@ -152,22 +161,22 @@ |------- |------- |----------- |`hf 15 help `|Y |`This help` |`hf 15 demod `|Y |`Demodulate ISO15693 from tag` -|`hf 15 dump `|Y |`Read all memory pages of an ISO15693 tag, save to file` -|`hf 15 findafi `|Y |`Brute force AFI of an ISO15693 tag` -|`hf 15 writeafi `|Y |`Writes the AFI on an ISO15693 tag` -|`hf 15 writedsfid `|Y |`Writes the DSFID on an ISO15693 tag` -|`hf 15 info `|Y |`Tag information` +|`hf 15 dump `|N |`Read all memory pages of an ISO15693 tag, save to file` +|`hf 15 findafi `|N |`Brute force AFI of an ISO15693 tag` +|`hf 15 writeafi `|N |`Writes the AFI on an ISO15693 tag` +|`hf 15 writedsfid `|N |`Writes the DSFID on an ISO15693 tag` +|`hf 15 info `|N |`Tag information` |`hf 15 list `|Y |`List ISO15693 history` -|`hf 15 raw `|Y |`Send raw hex data to tag` -|`hf 15 reader `|Y |`Act like an ISO15693 reader` -|`hf 15 record `|Y |`Record Samples (ISO15693)` -|`hf 15 restore `|Y |`Restore from file to all memory pages of an ISO15693 tag` -|`hf 15 sim `|Y |`Fake an ISO15693 tag` -|`hf 15 samples `|Y |`Acquire Samples as Reader (enables carrier, sends inquiry)` -|`hf 15 read `|Y |`Read a block` -|`hf 15 write `|Y |`Write a block` -|`hf 15 readmulti `|Y |`Reads multiple Blocks` -|`hf 15 csetuid `|Y |`Set UID for magic Chinese card` +|`hf 15 raw `|N |`Send raw hex data to tag` +|`hf 15 reader `|N |`Act like an ISO15693 reader` +|`hf 15 record `|N |`Record Samples (ISO15693)` +|`hf 15 restore `|N |`Restore from file to all memory pages of an ISO15693 tag` +|`hf 15 sim `|N |`Fake an ISO15693 tag` +|`hf 15 samples `|N |`Acquire Samples as Reader (enables carrier, sends inquiry)` +|`hf 15 read `|N |`Read a block` +|`hf 15 write `|N |`Write a block` +|`hf 15 readmulti `|N |`Reads multiple Blocks` +|`hf 15 csetuid `|N |`Set UID for magic Chinese card` ### hf epa @@ -177,8 +186,8 @@ |command |offline |description |------- |------- |----------- |`hf epa help `|Y |`This help` -|`hf epa cnonces `|Y |` Acquire n>0 encrypted PACE nonces of size m>0 with d sec pauses` -|`hf epa preplay `|Y |` Perform PACE protocol by replaying given APDUs` +|`hf epa cnonces `|N |` Acquire n>0 encrypted PACE nonces of size m>0 with d sec pauses` +|`hf epa preplay `|N |` Perform PACE protocol by replaying given APDUs` ### hf felica @@ -189,22 +198,22 @@ |------- |------- |----------- |`hf felica help `|Y |`This help` |`hf felica list `|Y |`List ISO 18092/FeliCa history` -|`hf felica reader `|Y |`Act like an ISO18092/FeliCa reader` -|`hf felica sniff `|Y |`Sniff ISO 18092/FeliCa traffic` -|`hf felica raw `|Y |`Send raw hex data to tag` -|`hf felica rqservice `|Y |`verify the existence of Area and Service, and to acquire Key Version.` -|`hf felica rqresponse `|Y |`verify the existence of a card and its Mode.` -|`hf felica rdunencrypted`|Y |`read Block Data from authentication-not-required Service.` -|`hf felica wrunencrypted`|Y |`write Block Data to an authentication-not-required Service.` -|`hf felica scsvcode `|Y |`acquire Area Code and Service Code.` -|`hf felica rqsyscode `|Y |`acquire System Code registered to the card.` -|`hf felica auth1 `|Y |`authenticate a card. Start mutual authentication with Auth1` -|`hf felica auth2 `|Y |`allow a card to authenticate a Reader/Writer. Complete mutual authentication` -|`hf felica read `|Y |`read Block Data from authentication-required Service.` -|`hf felica rqspecver `|Y |`acquire the version of card OS.` -|`hf felica resetmode `|Y |`reset Mode to Mode 0.` -|`hf felica litesim `|Y |` - only reply to poll request` -|`hf felica litedump `|Y |`Wait for and try dumping FelicaLite` +|`hf felica reader `|N |`Act like an ISO18092/FeliCa reader` +|`hf felica sniff `|N |`Sniff ISO 18092/FeliCa traffic` +|`hf felica raw `|N |`Send raw hex data to tag` +|`hf felica rqservice `|N |`verify the existence of Area and Service, and to acquire Key Version.` +|`hf felica rqresponse `|N |`verify the existence of a card and its Mode.` +|`hf felica rdunencrypted`|N |`read Block Data from authentication-not-required Service.` +|`hf felica wrunencrypted`|N |`write Block Data to an authentication-not-required Service.` +|`hf felica scsvcode `|N |`acquire Area Code and Service Code.` +|`hf felica rqsyscode `|N |`acquire System Code registered to the card.` +|`hf felica auth1 `|N |`authenticate a card. Start mutual authentication with Auth1` +|`hf felica auth2 `|N |`allow a card to authenticate a Reader/Writer. Complete mutual authentication` +|`hf felica read `|N |`read Block Data from authentication-required Service.` +|`hf felica rqspecver `|N |`acquire the version of card OS.` +|`hf felica resetmode `|N |`reset Mode to Mode 0.` +|`hf felica litesim `|N |` - only reply to poll request` +|`hf felica litedump `|N |`Wait for and try dumping FelicaLite` ### hf legic @@ -214,18 +223,18 @@ |command |offline |description |------- |------- |----------- |`hf legic help `|Y |`This help` -|`hf legic reader `|Y |`LEGIC Prime Reader UID and tag info` -|`hf legic info `|Y |`Display deobfuscated and decoded LEGIC Prime tag data` -|`hf legic dump `|Y |`Dump LEGIC Prime tag to binary file` -|`hf legic restore `|Y |`Restore a dump file onto a LEGIC Prime tag` -|`hf legic rdmem `|Y |`Read bytes from a LEGIC Prime tag` -|`hf legic sim `|Y |`Start tag simulator` -|`hf legic write `|Y |`Write data to a LEGIC Prime tag` +|`hf legic reader `|N |`LEGIC Prime Reader UID and tag info` +|`hf legic info `|N |`Display deobfuscated and decoded LEGIC Prime tag data` +|`hf legic dump `|N |`Dump LEGIC Prime tag to binary file` +|`hf legic restore `|N |`Restore a dump file onto a LEGIC Prime tag` +|`hf legic rdmem `|N |`Read bytes from a LEGIC Prime tag` +|`hf legic sim `|N |`Start tag simulator` +|`hf legic write `|N |`Write data to a LEGIC Prime tag` |`hf legic crc `|Y |`Calculate Legic CRC over given bytes` -|`hf legic eload `|Y |`Load binary dump to emulator memory` -|`hf legic esave `|Y |`Save emulator memory to binary file` +|`hf legic eload `|N |`Load binary dump to emulator memory` +|`hf legic esave `|N |`Save emulator memory to binary file` |`hf legic list `|Y |`List LEGIC history` -|`hf legic wipe `|Y |`Wipe a LEGIC Prime tag` +|`hf legic wipe `|N |`Wipe a LEGIC Prime tag` ### hf iclass @@ -237,24 +246,24 @@ |`hf iclass help `|Y |`This help` |`hf iclass calcnewkey `|Y |`[options..] Calc diversified keys (blocks 3 & 4) to write new keys` |`hf iclass chk `|Y |`[options..] Check keys` -|`hf iclass clone `|Y |`[options..] Restore a dump file onto a iClass tag` +|`hf iclass clone `|N |`[options..] Restore a dump file onto a iClass tag` |`hf iclass decrypt `|Y |`[options..] Decrypt given block data or tag dump file` -|`hf iclass dump `|Y |`[options..] Dump iClass tag to file` -|`hf iclass eload `|Y |`[f ] Load iClass dump file into emulator memory` +|`hf iclass dump `|N |`[options..] Dump iClass tag to file` +|`hf iclass eload `|N |`[f ] Load iClass dump file into emulator memory` |`hf iclass encrypt `|Y |`[options..] Encrypt given block data` |`hf iclass info `|Y |` Tag information` |`hf iclass list `|Y |` List iClass history` |`hf iclass loclass `|Y |`[options..] Use loclass to perform bruteforce reader attack` |`hf iclass lookup `|Y |`[options..] Uses authentication trace to check for key in dictionary file` |`hf iclass managekeys `|Y |`[options..] Manage keys to use with iClass` -|`hf iclass permutekey `|Y |` Permute function from 'heart of darkness' paper` -|`hf iclass rdbl `|Y |`[options..] Read iClass block` -|`hf iclass reader `|Y |` Act like an iClass reader` +|`hf iclass permutekey `|N |` Permute function from 'heart of darkness' paper` +|`hf iclass rdbl `|N |`[options..] Read iClass block` +|`hf iclass reader `|N |` Act like an iClass reader` |`hf iclass readtagfile `|Y |`[options..] Display content from tag dump file` -|`hf iclass replay `|Y |` Read iClass tag via replay attack` -|`hf iclass sim `|Y |`[options..] Simulate iClass tag` -|`hf iclass sniff `|Y |` Eavesdrop iClass communication` -|`hf iclass wrbl `|Y |`[options..] Write iClass block` +|`hf iclass replay `|N |` Read iClass tag via replay attack` +|`hf iclass sim `|N |`[options..] Simulate iClass tag` +|`hf iclass sniff `|N |` Eavesdrop iClass communication` +|`hf iclass wrbl `|N |`[options..] Write iClass block` ### hf mf @@ -265,39 +274,39 @@ |------- |------- |----------- |`hf mf help `|Y |`This help` |`hf mf list `|Y |`List MIFARE history` -|`hf mf darkside `|Y |`Darkside attack` -|`hf mf nested `|Y |`Nested attack` +|`hf mf darkside `|N |`Darkside attack` +|`hf mf nested `|N |`Nested attack` |`hf mf hardnested `|Y |`Nested attack for hardened MIFARE Classic cards` -|`hf mf autopwn `|Y |`Automatic key recovery tool for MIFARE Classic` -|`hf mf nack `|Y |`Test for MIFARE NACK bug` -|`hf mf chk `|Y |`Check keys` -|`hf mf fchk `|Y |`Check keys fast, targets all keys on card` +|`hf mf autopwn `|N |`Automatic key recovery tool for MIFARE Classic` +|`hf mf nack `|N |`Test for MIFARE NACK bug` +|`hf mf chk `|N |`Check keys` +|`hf mf fchk `|N |`Check keys fast, targets all keys on card` |`hf mf decrypt `|Y |`[nt] [ar_enc] [at_enc] [data] - to decrypt sniff or trace` -|`hf mf rdbl `|Y |`Read MIFARE classic block` -|`hf mf rdsc `|Y |`Read MIFARE classic sector` -|`hf mf dump `|Y |`Dump MIFARE classic tag to binary file` -|`hf mf restore `|Y |`Restore MIFARE classic binary file to BLANK tag` -|`hf mf wrbl `|Y |`Write MIFARE classic block` -|`hf mf setmod `|Y |`Set MIFARE Classic EV1 load modulation strength` -|`hf mf auth4 `|Y |`ISO14443-4 AES authentication` -|`hf mf sim `|Y |`Simulate MIFARE card` -|`hf mf eclr `|Y |`Clear simulator memory` -|`hf mf eget `|Y |`Get simulator memory block` -|`hf mf eset `|Y |`Set simulator memory block` -|`hf mf eload `|Y |`Load from file emul dump` -|`hf mf esave `|Y |`Save to file emul dump` -|`hf mf ecfill `|Y |`Fill simulator memory with help of keys from simulator` -|`hf mf ekeyprn `|Y |`Print keys from simulator memory` -|`hf mf csetuid `|Y |`Set UID (magic chinese card)` -|`hf mf cwipe `|Y |`Wipe card to default UID/Sectors/Keys` -|`hf mf csetblk `|Y |`Write block (magic chinese card)` -|`hf mf cgetblk `|Y |`Read block (magic chinese card)` -|`hf mf cgetsc `|Y |`Read sector (magic chinese card)` -|`hf mf cload `|Y |`Load dump (magic chinese card)` -|`hf mf csave `|Y |`Save dump from magic chinese card into file or emulator` -|`hf mf mad `|Y |`Checks and prints MAD` -|`hf mf ndef `|Y |`Prints NDEF records from card` -|`hf mf ice `|Y |`collect MIFARE Classic nonces to file` +|`hf mf rdbl `|N |`Read MIFARE classic block` +|`hf mf rdsc `|N |`Read MIFARE classic sector` +|`hf mf dump `|N |`Dump MIFARE classic tag to binary file` +|`hf mf restore `|N |`Restore MIFARE classic binary file to BLANK tag` +|`hf mf wrbl `|N |`Write MIFARE classic block` +|`hf mf setmod `|N |`Set MIFARE Classic EV1 load modulation strength` +|`hf mf auth4 `|N |`ISO14443-4 AES authentication` +|`hf mf sim `|N |`Simulate MIFARE card` +|`hf mf eclr `|N |`Clear simulator memory` +|`hf mf eget `|N |`Get simulator memory block` +|`hf mf eset `|N |`Set simulator memory block` +|`hf mf eload `|N |`Load from file emul dump` +|`hf mf esave `|N |`Save to file emul dump` +|`hf mf ecfill `|N |`Fill simulator memory with help of keys from simulator` +|`hf mf ekeyprn `|N |`Print keys from simulator memory` +|`hf mf csetuid `|N |`Set UID (magic chinese card)` +|`hf mf cwipe `|N |`Wipe card to default UID/Sectors/Keys` +|`hf mf csetblk `|N |`Write block (magic chinese card)` +|`hf mf cgetblk `|N |`Read block (magic chinese card)` +|`hf mf cgetsc `|N |`Read sector (magic chinese card)` +|`hf mf cload `|N |`Load dump (magic chinese card)` +|`hf mf csave `|N |`Save dump from magic chinese card into file or emulator` +|`hf mf mad `|N |`Checks and prints MAD` +|`hf mf ndef `|N |`Prints NDEF records from card` +|`hf mf ice `|N |`collect MIFARE Classic nonces to file` ### hf mfp @@ -307,17 +316,17 @@ |command |offline |description |------- |------- |----------- |`hf mfp help `|Y |`This help` -|`hf mfp info `|Y |`Info about Mifare Plus tag` -|`hf mfp wrp `|Y |`Write Perso command` -|`hf mfp initp `|Y |`Fills all the card's keys` -|`hf mfp commitp `|Y |`Move card to SL1 or SL3 mode` -|`hf mfp auth `|Y |`Authentication` -|`hf mfp rdbl `|Y |`Read blocks` -|`hf mfp rdsc `|Y |`Read sectors` -|`hf mfp wrbl `|Y |`Write blocks` -|`hf mfp chk `|Y |`Check keys` -|`hf mfp mad `|Y |`Checks and prints MAD` -|`hf mfp ndef `|Y |`Prints NDEF records from card` +|`hf mfp info `|N |`Info about Mifare Plus tag` +|`hf mfp wrp `|N |`Write Perso command` +|`hf mfp initp `|N |`Fills all the card's keys` +|`hf mfp commitp `|N |`Move card to SL1 or SL3 mode` +|`hf mfp auth `|N |`Authentication` +|`hf mfp rdbl `|N |`Read blocks` +|`hf mfp rdsc `|N |`Read sectors` +|`hf mfp wrbl `|N |`Write blocks` +|`hf mfp chk `|N |`Check keys` +|`hf mfp mad `|N |`Checks and prints MAD` +|`hf mfp ndef `|N |`Prints NDEF records from card` ### hf mfu @@ -327,19 +336,19 @@ |command |offline |description |------- |------- |----------- |`hf mfu help `|Y |`This help` -|`hf mfu info `|Y |`Tag information` -|`hf mfu dump `|Y |`Dump Ultralight / Ultralight-C / NTAG tag to binary file` -|`hf mfu restore `|Y |`Restore a dump onto a MFU MAGIC tag` -|`hf mfu eload `|Y |`load Ultralight .eml dump file into emulator memory` -|`hf mfu rdbl `|Y |`Read block` -|`hf mfu wrbl `|Y |`Write block` -|`hf mfu cauth `|Y |`Authentication - Ultralight C` -|`hf mfu setpwd `|Y |`Set 3des password - Ultralight-C` -|`hf mfu setuid `|Y |`Set UID - MAGIC tags only` -|`hf mfu sim `|Y |`Simulate Ultralight from emulator memory` +|`hf mfu info `|N |`Tag information` +|`hf mfu dump `|N |`Dump Ultralight / Ultralight-C / NTAG tag to binary file` +|`hf mfu restore `|N |`Restore a dump onto a MFU MAGIC tag` +|`hf mfu eload `|N |`load Ultralight .eml dump file into emulator memory` +|`hf mfu rdbl `|N |`Read block` +|`hf mfu wrbl `|N |`Write block` +|`hf mfu cauth `|N |`Authentication - Ultralight C` +|`hf mfu setpwd `|N |`Set 3des password - Ultralight-C` +|`hf mfu setuid `|N |`Set UID - MAGIC tags only` +|`hf mfu sim `|N |`Simulate Ultralight from emulator memory` |`hf mfu gen `|Y |`Generate 3des mifare diversified keys` |`hf mfu pwdgen `|Y |`Generate pwd from known algos` -|`hf mfu otptear `|Y |`Tear-off test on OTP bits` +|`hf mfu otptear `|N |`Tear-off test on OTP bits` ### hf mfdes @@ -349,9 +358,9 @@ |command |offline |description |------- |------- |----------- |`hf mfdes help `|Y |`This help` -|`hf mfdes info `|Y |`Tag information` -|`hf mfdes enum `|Y |`Tries enumerate all applications` -|`hf mfdes auth `|Y |`Tries a MIFARE DesFire Authentication` +|`hf mfdes info `|N |`Tag information` +|`hf mfdes enum `|N |`Tries enumerate all applications` +|`hf mfdes auth `|N |`Tries a MIFARE DesFire Authentication` ### hf topaz @@ -361,10 +370,10 @@ |command |offline |description |------- |------- |----------- |`hf topaz help `|Y |`This help` -|`hf topaz reader `|Y |`Act like a Topaz reader` -|`hf topaz sim `|Y |` -- Simulate Topaz tag` -|`hf topaz sniff `|Y |`Sniff Topaz reader-tag communication` -|`hf topaz raw `|Y |`Send raw hex data to tag` +|`hf topaz reader `|N |`Act like a Topaz reader` +|`hf topaz sim `|N |` -- Simulate Topaz tag` +|`hf topaz sniff `|N |`Sniff Topaz reader-tag communication` +|`hf topaz raw `|N |`Send raw hex data to tag` |`hf topaz list `|Y |`List Topaz history` @@ -375,11 +384,11 @@ |command |offline |description |------- |------- |----------- |`hf fido help `|Y |`This help.` -|`hf fido info `|Y |`Info about FIDO tag.` -|`hf fido reg `|Y |`FIDO U2F Registration Message.` -|`hf fido auth `|Y |`FIDO U2F Authentication Message.` -|`hf fido make `|Y |`FIDO2 MakeCredential command.` -|`hf fido assert `|Y |`FIDO2 GetAssertion command.` +|`hf fido info `|N |`Info about FIDO tag.` +|`hf fido reg `|N |`FIDO U2F Registration Message.` +|`hf fido auth `|N |`FIDO U2F Authentication Message.` +|`hf fido make `|N |`FIDO2 MakeCredential command.` +|`hf fido assert `|N |`FIDO2 GetAssertion command.` ### hf thinfilm @@ -389,9 +398,9 @@ |command |offline |description |------- |------- |----------- |`hf thinfilm help `|Y |`This help` -|`hf thinfilm info `|Y |`Tag information` +|`hf thinfilm info `|N |`Tag information` |`hf thinfilm list `|Y |`List NFC Barcode / Thinfilm history - not correct` -|`hf thinfilm sim `|Y |`Fake Thinfilm tag` +|`hf thinfilm sim `|N |`Fake Thinfilm tag` ### hw @@ -402,21 +411,21 @@ |------- |------- |----------- |`hw help `|Y |`This help` |`hw connect `|Y |`connect Proxmark3 to serial port` -|`hw dbg `|Y |`Set Proxmark3 debug level` -|`hw detectreader `|Y |`['l'|'h'] -- Detect external reader field (option 'l' or 'h' to limit to LF or HF)` -|`hw fpgaoff `|Y |`Set FPGA off` +|`hw dbg `|N |`Set Proxmark3 debug level` +|`hw detectreader `|N |`['l'|'h'] -- Detect external reader field (option 'l' or 'h' to limit to LF or HF)` +|`hw fpgaoff `|N |`Set FPGA off` |`hw lcd `|N |` -- Send command/data to LCD` |`hw lcdreset `|N |`Hardware reset LCD` -|`hw ping `|Y |`Test if the Proxmark3 is responsive` -|`hw readmem `|Y |`[address] -- Read memory at decimal address from flash` -|`hw reset `|Y |`Reset the Proxmark3` -|`hw setlfdivisor `|Y |`<19 - 255> -- Drive LF antenna at 12MHz/(divisor+1)` -|`hw setmux `|Y |`Set the ADC mux to a specific value` -|`hw standalone `|Y |`Jump to the standalone mode` -|`hw status `|Y |`Show runtime status information about the connected Proxmark3` -|`hw tia `|Y |`Trigger a Timing Interval Acquisition to re-adjust the RealTimeCounter divider` -|`hw tune `|Y |`Measure antenna tuning` -|`hw version `|Y |`Show version information about the connected Proxmark3` +|`hw ping `|N |`Test if the Proxmark3 is responsive` +|`hw readmem `|N |`[address] -- Read memory at decimal address from flash` +|`hw reset `|N |`Reset the Proxmark3` +|`hw setlfdivisor `|N |`<19 - 255> -- Drive LF antenna at 12MHz/(divisor+1)` +|`hw setmux `|N |`Set the ADC mux to a specific value` +|`hw standalone `|N |`Jump to the standalone mode` +|`hw status `|N |`Show runtime status information about the connected Proxmark3` +|`hw tia `|N |`Trigger a Timing Interval Acquisition to re-adjust the RealTimeCounter divider` +|`hw tune `|N |`Measure antenna tuning` +|`hw version `|N |`Show version information about the connected Proxmark3` ### lf @@ -426,22 +435,17 @@ |command |offline |description |------- |------- |----------- |`lf help `|Y |`This help` -|`lf config `|Y |`Get/Set config for LF sampling, bit/sample, decimation, frequency` -|`lf cmdread `|Y |` <'0' period> <'1' period> ['h' 134] - -- Modulate LF reader field to send command before read (all periods in microseconds)` -|`lf read `|Y |`['s' silent] Read 125/134 kHz LF ID-only tag. Do 'lf read h' for help` -|`lf search `|Y |`[offline] ['u'] Read and Search for valid known tag (in offline mode it you can load first then search) - -- 'u' to search for unknown tags` -|`lf sim `|Y |`[GAP] -- Simulate LF tag from buffer with optional GAP (in microseconds)` -|`lf simask `|Y |`[clock] [invert <1|0>] [biphase/manchester/raw <'b'|'m'|'r'>] [msg separator 's'] [d ] - -- Simulate LF ASK tag from demodbuffer or input` -|`lf simfsk `|Y |`[c ] [i] [H ] [L ] [d ] - -- Simulate LF FSK tag from demodbuffer or input` -|`lf simpsk `|Y |`[1|2|3] [c ] [i] [r ] [d ] - -- Simulate LF PSK tag from demodbuffer or input` -|`lf simbidir `|Y |`Simulate LF tag (with bidirectional data transmission between reader and tag)` -|`lf sniff `|Y |`Sniff LF traffic between reader and tag` -|`lf tune `|Y |`Continuously measure LF antenna tuning` +|`lf config `|N |`Get/Set config for LF sampling, bit/sample, decimation, frequency` +|`lf cmdread `|N |`Modulate LF reader field to send command before read (all periods in microseconds)` +|`lf read `|N |`Read LF tag` +|`lf search `|Y |`Read and Search for valid known tag (in offline mode it you can load first then search)` +|`lf sim `|N |`Simulate LF tag from buffer with optional GAP (in microseconds)` +|`lf simask `|N |`Simulate LF ASK tag from demodbuffer or input` +|`lf simfsk `|N |`Simulate LF FSK tag from demodbuffer or input` +|`lf simpsk `|N |`Simulate LF PSK tag from demodbuffer or input` +|`lf simbidir `|N |`Simulate LF tag (with bidirectional data transmission between reader and tag)` +|`lf sniff `|N |`Sniff LF traffic between reader and tag` +|`lf tune `|N |`Continuously measure LF antenna tuning` ### lf awid @@ -452,11 +456,11 @@ |------- |------- |----------- |`lf awid help `|Y |`this help` |`lf awid demod `|Y |`demodulate an AWID FSK tag from the GraphBuffer` -|`lf awid read `|Y |`attempt to read and extract tag data` -|`lf awid clone `|Y |`clone AWID tag to T55x7 (or to q5/T5555)` -|`lf awid sim `|Y |`simulate AWID tag` -|`lf awid brute `|Y |`Bruteforce card number against reader` -|`lf awid watch `|Y |`continuously watch for cards. Reader mode` +|`lf awid read `|N |`attempt to read and extract tag data` +|`lf awid clone `|N |`clone AWID tag to T55x7 (or to q5/T5555)` +|`lf awid sim `|N |`simulate AWID tag` +|`lf awid brute `|N |`Bruteforce card number against reader` +|`lf awid watch `|N |`continuously watch for cards. Reader mode` ### lf cotag @@ -467,7 +471,7 @@ |------- |------- |----------- |`lf cotag help `|Y |`This help` |`lf cotag demod `|Y |`Tries to decode a COTAG signal` -|`lf cotag read `|Y |`Attempt to read and extract tag data` +|`lf cotag read `|N |`Attempt to read and extract tag data` ### lf em @@ -478,22 +482,22 @@ |------- |------- |----------- |`lf em help `|Y |`This help` |`lf em 410x_demod `|Y |`demodulate a EM410x tag from the GraphBuffer` -|`lf em 410x_read `|Y |`attempt to read and extract tag data` -|`lf em 410x_sim `|Y |`simulate EM410x tag` -|`lf em 410x_brute `|Y |`reader bruteforce attack by simulating EM410x tags` -|`lf em 410x_watch `|Y |`watches for EM410x 125/134 kHz tags (option 'h' for 134)` -|`lf em 410x_spoof `|Y |`watches for EM410x 125/134 kHz tags, and replays them. (option 'h' for 134)` -|`lf em 410x_write `|Y |`write EM410x UID to T5555(Q5) or T55x7 tag` +|`lf em 410x_read `|N |`attempt to read and extract tag data` +|`lf em 410x_sim `|N |`simulate EM410x tag` +|`lf em 410x_brute `|N |`reader bruteforce attack by simulating EM410x tags` +|`lf em 410x_watch `|N |`watches for EM410x 125/134 kHz tags (option 'h' for 134)` +|`lf em 410x_spoof `|N |`watches for EM410x 125/134 kHz tags, and replays them. (option 'h' for 134)` +|`lf em 410x_write `|N |`write EM410x UID to T5555(Q5) or T55x7 tag` |`lf em 4x05_demod `|Y |`demodulate a EM4x05/EM4x69 tag from the GraphBuffer` -|`lf em 4x05_dump `|Y |`dump EM4x05/EM4x69 tag` -|`lf em 4x05_wipe `|Y |`wipe EM4x05/EM4x69 tag` -|`lf em 4x05_info `|Y |`tag information EM4x05/EM4x69` -|`lf em 4x05_read `|Y |`read word data from EM4x05/EM4x69` -|`lf em 4x05_write `|Y |`write word data to EM4x05/EM4x69` +|`lf em 4x05_dump `|N |`dump EM4x05/EM4x69 tag` +|`lf em 4x05_wipe `|N |`wipe EM4x05/EM4x69 tag` +|`lf em 4x05_info `|N |`tag information EM4x05/EM4x69` +|`lf em 4x05_read `|N |`read word data from EM4x05/EM4x69` +|`lf em 4x05_write `|N |`write word data to EM4x05/EM4x69` |`lf em 4x50_demod `|Y |`demodulate a EM4x50 tag from the GraphBuffer` -|`lf em 4x50_dump `|Y |`dump EM4x50 tag` -|`lf em 4x50_read `|Y |`read word data from EM4x50` -|`lf em 4x50_write `|Y |`write word data to EM4x50` +|`lf em 4x50_dump `|N |`dump EM4x50 tag` +|`lf em 4x50_read `|N |`read word data from EM4x50` +|`lf em 4x50_write `|N |`write word data to EM4x50` ### lf fdx @@ -504,9 +508,9 @@ |------- |------- |----------- |`lf fdx help `|Y |`this help` |`lf fdx demod `|Y |`demodulate a FDX-B ISO11784/85 tag from the GraphBuffer` -|`lf fdx read `|Y |`attempt to read and extract tag data` -|`lf fdx clone `|Y |`clone animal ID tag to T55x7 (or to q5/T5555)` -|`lf fdx sim `|Y |`simulate Animal ID tag` +|`lf fdx read `|N |`attempt to read and extract tag data` +|`lf fdx clone `|N |`clone animal ID tag to T55x7 (or to q5/T5555)` +|`lf fdx sim `|N |`simulate Animal ID tag` ### lf gallagher @@ -517,9 +521,9 @@ |------- |------- |----------- |`lf gallagher help `|Y |`This help` |`lf gallagher demod `|Y |`Demodulate an GALLAGHER tag from the GraphBuffer` -|`lf gallagher read `|Y |`Attempt to read and extract tag data from the antenna` -|`lf gallagher clone `|Y |`clone GALLAGHER tag to T55x7` -|`lf gallagher sim `|Y |`simulate GALLAGHER tag` +|`lf gallagher read `|N |`Attempt to read and extract tag data from the antenna` +|`lf gallagher clone `|N |`clone GALLAGHER tag to T55x7` +|`lf gallagher sim `|N |`simulate GALLAGHER tag` ### lf gproxii @@ -530,9 +534,9 @@ |------- |------- |----------- |`lf gproxii help `|Y |`this help` |`lf gproxii demod `|Y |`demodulate a G Prox II tag from the GraphBuffer` -|`lf gproxii read `|Y |`attempt to read and extract tag data from the antenna` -|`lf gproxii clone `|Y |`clone Guardall tag to T55x7` -|`lf gproxii sim `|Y |`simulate Guardall tag` +|`lf gproxii read `|N |`attempt to read and extract tag data from the antenna` +|`lf gproxii clone `|N |`clone Guardall tag to T55x7` +|`lf gproxii sim `|N |`simulate Guardall tag` ### lf hid @@ -543,11 +547,11 @@ |------- |------- |----------- |`lf hid help `|Y |`this help` |`lf hid demod `|Y |`demodulate HID Prox tag from the GraphBuffer` -|`lf hid read `|Y |`attempt to read and extract tag data` -|`lf hid clone `|Y |`clone HID tag to T55x7` -|`lf hid sim `|Y |`simulate HID tag` -|`lf hid brute `|Y |`bruteforce card number against reader` -|`lf hid watch `|Y |`continuously watch for cards. Reader mode` +|`lf hid read `|N |`attempt to read and extract tag data` +|`lf hid clone `|N |`clone HID tag to T55x7` +|`lf hid sim `|N |`simulate HID tag` +|`lf hid brute `|N |`bruteforce card number against reader` +|`lf hid watch `|N |`continuously watch for cards. Reader mode` ### lf hitag @@ -557,13 +561,13 @@ |command |offline |description |------- |------- |----------- |`lf hitag help `|Y |`This help` -|`lf hitag list `|Y |`List Hitag trace history` -|`lf hitag info `|Y |`Tag information` -|`lf hitag reader `|Y |`Act like a Hitag Reader` -|`lf hitag sim `|Y |`Simulate Hitag transponder` -|`lf hitag sniff `|Y |`Eavesdrop Hitag communication` -|`lf hitag writer `|Y |`Act like a Hitag Writer` -|`lf hitag cc `|Y |`Test all challenges` +|`lf hitag list `|N |`List Hitag trace history` +|`lf hitag info `|N |`Tag information` +|`lf hitag reader `|N |`Act like a Hitag Reader` +|`lf hitag sim `|N |`Simulate Hitag transponder` +|`lf hitag sniff `|N |`Eavesdrop Hitag communication` +|`lf hitag writer `|N |`Act like a Hitag Writer` +|`lf hitag cc `|N |`Test all challenges` ### lf indala @@ -575,9 +579,9 @@ |`lf indala help `|Y |`this help` |`lf indala demod `|Y |`demodulate an indala tag (PSK1) from GraphBuffer` |`lf indala altdemod `|Y |`alternative method to Demodulate samples for Indala 64 bit UID (option '224' for 224 bit)` -|`lf indala read `|Y |`read an Indala Prox tag from the antenna` -|`lf indala clone `|Y |`clone Indala tag to T55x7` -|`lf indala sim `|Y |`simulate Indala tag` +|`lf indala read `|N |`read an Indala Prox tag from the antenna` +|`lf indala clone `|N |`clone Indala tag to T55x7` +|`lf indala sim `|N |`simulate Indala tag` ### lf io @@ -588,10 +592,10 @@ |------- |------- |----------- |`lf io help `|Y |`this help` |`lf io demod `|Y |`demodulate an IOProx tag from the GraphBuffer` -|`lf io read `|Y |`attempt to read and extract tag data` -|`lf io clone `|Y |`clone IOProx tag to T55x7 (or to q5/T5555)` -|`lf io sim `|Y |`simulate IOProx tag` -|`lf io watch `|Y |`continuously watch for cards. Reader mode` +|`lf io read `|N |`attempt to read and extract tag data` +|`lf io clone `|N |`clone IOProx tag to T55x7 (or to q5/T5555)` +|`lf io sim `|N |`simulate IOProx tag` +|`lf io watch `|N |`continuously watch for cards. Reader mode` ### lf jablotron @@ -601,11 +605,10 @@ |command |offline |description |------- |------- |----------- |`lf jablotron help `|Y |`This help` -|`lf jablotron slurdge `|Y |`Demod slurdge ..` |`lf jablotron demod `|Y |`Demodulate an Jablotron tag from the GraphBuffer` -|`lf jablotron read `|Y |`Attempt to read and extract tag data from the antenna` -|`lf jablotron clone `|Y |`clone jablotron tag to T55x7 (or to q5/T5555)` -|`lf jablotron sim `|Y |`simulate jablotron tag` +|`lf jablotron read `|N |`Attempt to read and extract tag data from the antenna` +|`lf jablotron clone `|N |`clone jablotron tag to T55x7 (or to q5/T5555)` +|`lf jablotron sim `|N |`simulate jablotron tag` ### lf keri @@ -616,9 +619,9 @@ |------- |------- |----------- |`lf keri help `|Y |`This help` |`lf keri demod `|Y |`Demodulate an KERI tag from the GraphBuffer` -|`lf keri read `|Y |`Attempt to read and extract tag data from the antenna` -|`lf keri clone `|Y |`clone KERI tag to T55x7 (or to q5/T5555)` -|`lf keri sim `|Y |`simulate KERI tag` +|`lf keri read `|N |`Attempt to read and extract tag data from the antenna` +|`lf keri clone `|N |`clone KERI tag to T55x7 (or to q5/T5555)` +|`lf keri sim `|N |`simulate KERI tag` ### lf nedap @@ -630,9 +633,9 @@ |`lf nedap help `|Y |`This help` |`lf nedap demod `|Y |`Demodulate Nedap tag from the GraphBuffer` |`lf nedap generate `|Y |`Generate Nedap bitstream in DemodBuffer` -|`lf nedap read `|Y |`Attempt to read and extract tag data from the antenna` -|`lf nedap clone `|Y |`Clone Nedap tag to T55x7` -|`lf nedap sim `|Y |`Simulate Nedap tag` +|`lf nedap read `|N |`Attempt to read and extract tag data from the antenna` +|`lf nedap clone `|N |`Clone Nedap tag to T55x7` +|`lf nedap sim `|N |`Simulate Nedap tag` ### lf nexwatch @@ -643,9 +646,9 @@ |------- |------- |----------- |`lf nexwatch help `|Y |`This help` |`lf nexwatch demod `|Y |`Demodulate a NexWatch tag (nexkey, quadrakey) from the GraphBuffer` -|`lf nexwatch read `|Y |`Attempt to Read and Extract tag data from the antenna` -|`lf nexwatch clone `|Y |`clone NexWatch tag to T55x7` -|`lf nexwatch sim `|Y |`simulate NexWatch tag` +|`lf nexwatch read `|N |`Attempt to Read and Extract tag data from the antenna` +|`lf nexwatch clone `|N |`clone NexWatch tag to T55x7` +|`lf nexwatch sim `|N |`simulate NexWatch tag` ### lf noralsy @@ -656,9 +659,9 @@ |------- |------- |----------- |`lf noralsy help `|Y |`This help` |`lf noralsy demod `|Y |`Demodulate an Noralsy tag from the GraphBuffer` -|`lf noralsy read `|Y |`Attempt to read and extract tag data from the antenna` -|`lf noralsy clone `|Y |`clone Noralsy tag to T55x7 (or to q5/T5555)` -|`lf noralsy sim `|Y |`simulate Noralsy tag` +|`lf noralsy read `|N |`Attempt to read and extract tag data from the antenna` +|`lf noralsy clone `|N |`clone Noralsy tag to T55x7 (or to q5/T5555)` +|`lf noralsy sim `|N |`simulate Noralsy tag` ### lf motorola @@ -669,9 +672,9 @@ |------- |------- |----------- |`lf motorola help `|Y |`This help` |`lf motorola demod `|Y |`Demodulate an MOTOROLA tag from the GraphBuffer` -|`lf motorola read `|Y |`Attempt to read and extract tag data from the antenna` -|`lf motorola clone `|Y |`clone MOTOROLA tag to T55x7` -|`lf motorola sim `|Y |`simulate MOTOROLA tag` +|`lf motorola read `|N |`Attempt to read and extract tag data from the antenna` +|`lf motorola clone `|N |`clone MOTOROLA tag to T55x7` +|`lf motorola sim `|N |`simulate MOTOROLA tag` ### lf pac @@ -682,9 +685,9 @@ |------- |------- |----------- |`lf pac help `|Y |`This help` |`lf pac demod `|Y |`Demodulate a PAC tag from the GraphBuffer` -|`lf pac read `|Y |`Attempt to read and extract tag data from the antenna` -|`lf pac clone `|Y |`clone PAC tag to T55x7` -|`lf pac sim `|Y |`simulate PAC tag` +|`lf pac read `|N |`Attempt to read and extract tag data from the antenna` +|`lf pac clone `|N |`clone PAC tag to T55x7` +|`lf pac sim `|N |`simulate PAC tag` ### lf paradox @@ -695,9 +698,9 @@ |------- |------- |----------- |`lf paradox help `|Y |`This help` |`lf paradox demod `|Y |`Demodulate a Paradox FSK tag from the GraphBuffer` -|`lf paradox read `|Y |`Attempt to read and Extract tag data from the antenna` -|`lf paradox clone `|Y |`clone paradox tag to T55x7` -|`lf paradox sim `|Y |`simulate paradox tag` +|`lf paradox read `|N |`Attempt to read and Extract tag data from the antenna` +|`lf paradox clone `|N |`clone paradox tag to T55x7` +|`lf paradox sim `|N |`simulate paradox tag` ### lf pcf7931 @@ -707,8 +710,8 @@ |command |offline |description |------- |------- |----------- |`lf pcf7931 help `|Y |`This help` -|`lf pcf7931 read `|Y |`Read content of a PCF7931 transponder` -|`lf pcf7931 write `|Y |`Write data on a PCF7931 transponder.` +|`lf pcf7931 read `|N |`Read content of a PCF7931 transponder` +|`lf pcf7931 write `|N |`Write data on a PCF7931 transponder.` |`lf pcf7931 config `|Y |`Configure the password, the tags initialization delay and time offsets (optional)` @@ -719,9 +722,9 @@ |command |offline |description |------- |------- |----------- |`lf presco help `|Y |`This help` -|`lf presco read `|Y |`Attempt to read and Extract tag data` -|`lf presco clone `|Y |`clone presco tag to T55x7 (or to q5/T5555)` -|`lf presco sim `|Y |`simulate presco tag` +|`lf presco read `|N |`Attempt to read and Extract tag data` +|`lf presco clone `|N |`clone presco tag to T55x7 (or to q5/T5555)` +|`lf presco sim `|N |`simulate presco tag` ### lf pyramid @@ -732,9 +735,9 @@ |------- |------- |----------- |`lf pyramid help `|Y |`this help` |`lf pyramid demod `|Y |`demodulate a Pyramid FSK tag from the GraphBuffer` -|`lf pyramid read `|Y |`attempt to read and extract tag data` -|`lf pyramid clone `|Y |`clone pyramid tag to T55x7 (or to q5/T5555)` -|`lf pyramid sim `|Y |`simulate pyramid tag` +|`lf pyramid read `|N |`attempt to read and extract tag data` +|`lf pyramid clone `|N |`clone pyramid tag to T55x7 (or to q5/T5555)` +|`lf pyramid sim `|N |`simulate pyramid tag` ### lf securakey @@ -745,9 +748,9 @@ |------- |------- |----------- |`lf securakey help `|Y |`This help` |`lf securakey demod `|Y |`Demodulate an Securakey tag from the GraphBuffer` -|`lf securakey read `|Y |`Attempt to read and extract tag data from the antenna` -|`lf securakey clone `|Y |`clone Securakey tag to T55x7` -|`lf securakey sim `|Y |`simulate Securakey tag` +|`lf securakey read `|N |`Attempt to read and extract tag data from the antenna` +|`lf securakey clone `|N |`clone Securakey tag to T55x7` +|`lf securakey sim `|N |`simulate Securakey tag` ### lf ti @@ -758,8 +761,8 @@ |------- |------- |----------- |`lf ti help `|Y |`This help` |`lf ti demod `|Y |`Demodulate raw bits for TI-type LF tag from the GraphBuffer` -|`lf ti read `|Y |`Read and decode a TI 134 kHz tag` -|`lf ti write `|Y |`Write new data to a r/w TI 134 kHz tag` +|`lf ti read `|N |`Read and decode a TI 134 kHz tag` +|`lf ti write `|N |`Write new data to a r/w TI 134 kHz tag` ### lf t55xx @@ -769,26 +772,26 @@ |command |offline |description |------- |------- |----------- |`lf t55xx help `|Y |`This help` -|`lf t55xx bruteforce `|Y |` Simple bruteforce attack to find password` +|`lf t55xx bruteforce `|N |` Simple bruteforce attack to find password` |`lf t55xx config `|Y |`Set/Get T55XX configuration (modulation, inverted, offset, rate)` -|`lf t55xx chk `|Y |`Check passwords from dictionary/flash` -|`lf t55xx clonehelp `|Y |`Shows the available clone commands` -|`lf t55xx dangerraw `|Y |`Sends raw bitstream. Dangerous, do not use!! b t ` +|`lf t55xx chk `|N |`Check passwords from dictionary/flash` +|`lf t55xx clonehelp `|N |`Shows the available clone commands` +|`lf t55xx dangerraw `|N |`Sends raw bitstream. Dangerous, do not use!! b t ` |`lf t55xx detect `|Y |`[1] Try detecting the tag modulation from reading the configuration block.` -|`lf t55xx deviceconfig `|Y |`Set/Get T55XX device configuration (startgap, writegap, write0, write1, readgap` -|`lf t55xx dump `|Y |`[password] [o] Dump T55xx card Page 0 block 0-7. Optional [password], [override]` -|`lf t55xx restore `|Y |`f [p ] Restore T55xx card Page 0 / Page 1 blocks` +|`lf t55xx deviceconfig `|N |`Set/Get T55XX device configuration (startgap, writegap, write0, write1, readgap` +|`lf t55xx dump `|N |`[password] [o] Dump T55xx card Page 0 block 0-7. Optional [password], [override]` +|`lf t55xx restore `|N |`f [p ] Restore T55xx card Page 0 / Page 1 blocks` |`lf t55xx info `|Y |`[1] Show T55x7 configuration data (page 0/ blk 0)` -|`lf t55xx p1detect `|Y |`[1] Try detecting if this is a t55xx tag by reading page 1` -|`lf t55xx protect `|Y |`Password protect tag` -|`lf t55xx read `|Y |`b p [password] [o] [1] -- Read T55xx block data. Optional [p password], [override], [page1]` -|`lf t55xx resetread `|Y |`Send Reset Cmd then lf read the stream to attempt to identify the start of it (needs a demod and/or plot after)` -|`lf t55xx recoverpw `|Y |`[password] Try to recover from bad password write from a cloner. Only use on PW protected chips!` -|`lf t55xx special `|Y |`Show block changes with 64 different offsets` +|`lf t55xx p1detect `|N |`[1] Try detecting if this is a t55xx tag by reading page 1` +|`lf t55xx protect `|N |`Password protect tag` +|`lf t55xx read `|N |`b p [password] [o] [1] -- Read T55xx block data. Optional [p password], [override], [page1]` +|`lf t55xx resetread `|N |`Send Reset Cmd then lf read the stream to attempt to identify the start of it (needs a demod and/or plot after)` +|`lf t55xx recoverpw `|N |`[password] Try to recover from bad password write from a cloner. Only use on PW protected chips!` +|`lf t55xx special `|N |`Show block changes with 64 different offsets` |`lf t55xx trace `|Y |`[1] Show T55x7 traceability data (page 1/ blk 0-1)` -|`lf t55xx wakeup `|Y |`Send AOR wakeup command` -|`lf t55xx wipe `|Y |`[q] Wipe a T55xx tag and set defaults (will destroy any data on tag)` -|`lf t55xx write `|Y |`b d p [password] [1] -- Write T55xx block data. Optional [p password], [page1]` +|`lf t55xx wakeup `|N |`Send AOR wakeup command` +|`lf t55xx wipe `|N |`[q] Wipe a T55xx tag and set defaults (will destroy any data on tag)` +|`lf t55xx write `|N |`b d p [password] [1] -- Write T55xx block data. Optional [p password], [page1]` ### lf viking @@ -799,9 +802,9 @@ |------- |------- |----------- |`lf viking help `|Y |`This help` |`lf viking demod `|Y |`Demodulate a Viking tag from the GraphBuffer` -|`lf viking read `|Y |`Attempt to read and Extract tag data from the antenna` -|`lf viking clone `|Y |`clone Viking tag to T55x7 (or to q5/T5555)` -|`lf viking sim `|Y |`simulate Viking tag` +|`lf viking read `|N |`Attempt to read and Extract tag data from the antenna` +|`lf viking clone `|N |`clone Viking tag to T55x7 (or to q5/T5555)` +|`lf viking sim `|N |`simulate Viking tag` ### lf visa2000 @@ -812,9 +815,9 @@ |------- |------- |----------- |`lf visa2000 help `|Y |`This help` |`lf visa2000 demod `|Y |`demodulate an VISA2000 tag from the GraphBuffer` -|`lf visa2000 read `|Y |`attempt to read and extract tag data from the antenna` -|`lf visa2000 clone `|Y |`clone Visa2000 tag to T55x7 (or to q5/T5555)` -|`lf visa2000 sim `|Y |`simulate Visa2000 tag` +|`lf visa2000 read `|N |`attempt to read and extract tag data from the antenna` +|`lf visa2000 clone `|N |`clone Visa2000 tag to T55x7 (or to q5/T5555)` +|`lf visa2000 sim `|N |`simulate Visa2000 tag` ### mem @@ -824,12 +827,12 @@ |command |offline |description |------- |------- |----------- |`mem help `|Y |`This help` -|`mem spiffs `|Y |`High level SPI FileSystem Flash manipulation [rdv40]` -|`mem spibaud `|Y |`Set Flash memory Spi baudrate [rdv40]` -|`mem info `|Y |`Flash memory information [rdv40]` -|`mem load `|Y |`Load data into flash memory [rdv40]` -|`mem dump `|Y |`Dump data from flash memory [rdv40]` -|`mem wipe `|Y |`Wipe data from flash memory [rdv40]` +|`mem spiffs `|N |`High level SPI FileSystem Flash manipulation [rdv40]` +|`mem spibaud `|N |`Set Flash memory Spi baudrate [rdv40]` +|`mem info `|N |`Flash memory information [rdv40]` +|`mem load `|N |`Load data into flash memory [rdv40]` +|`mem dump `|N |`Dump data from flash memory [rdv40]` +|`mem wipe `|N |`Wipe data from flash memory [rdv40]` ### reveng @@ -843,13 +846,13 @@ |command |offline |description |------- |------- |----------- |`sc help `|Y |`This help` -|`sc list `|Y |`List ISO 7816 history` -|`sc info `|Y |`Tag information` -|`sc reader `|Y |`Act like an IS07816 reader` -|`sc raw `|Y |`Send raw hex data to tag` +|`sc list `|N |`List ISO 7816 history` +|`sc info `|N |`Tag information` +|`sc reader `|N |`Act like an IS07816 reader` +|`sc raw `|N |`Send raw hex data to tag` |`sc upgrade `|Y |`Upgrade sim module firmware` -|`sc setclock `|Y |`Set clock speed` -|`sc brute `|Y |`Bruteforce SFI` +|`sc setclock `|N |`Set clock speed` +|`sc brute `|N |`Bruteforce SFI` ### script From a88ec7c58a4264056980bc0c4f73feaa7802a755 Mon Sep 17 00:00:00 2001 From: Nick Date: Fri, 10 Jan 2020 15:00:50 +0000 Subject: [PATCH 1420/1854] Correct usage for 'hf mf csave' Corrected csave usage to show `o` flag for output file instead of `i`. --- client/cmdhfmf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 4fe5370fc..9733059e9 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -445,7 +445,7 @@ static int usage_hf14_csave(void) { PrintAndLogEx(NORMAL, "It saves `magic Chinese` card dump into the file `filename.eml` or `cardID.eml`"); PrintAndLogEx(NORMAL, "or into emulator memory"); PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Usage: hf mf csave [h] [e] [u] [card memory] i "); + PrintAndLogEx(NORMAL, "Usage: hf mf csave [h] [e] [u] [card memory] o "); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h this help"); PrintAndLogEx(NORMAL, " e save data to emulator memory"); From 442bab070646ad3febc12f91b41ba111da9e004f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 12 Jan 2020 00:18:34 +0100 Subject: [PATCH 1421/1854] style --- fpga/hi_get_trace.v | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/fpga/hi_get_trace.v b/fpga/hi_get_trace.v index 3e7412f7a..aae4054cf 100755 --- a/fpga/hi_get_trace.v +++ b/fpga/hi_get_trace.v @@ -77,7 +77,9 @@ begin write_enable2 <= 1'b0; end else + begin addr <= addr + 1; + end end end else @@ -92,15 +94,17 @@ begin write_enable1 <= 1'b0; write_enable2 <= 1'b0; if (previous_major_mode != `FPGA_MAJOR_MODE_OFF && previous_major_mode != `FPGA_MAJOR_MODE_HF_GET_TRACE) // just switched off + begin start_addr <= addr; + end end end // (2+1)k RAM reg [7:0] D_out1, D_out2; -reg [7:0] ram1 [2047:0]; -reg [7:0] ram2 [1023:0]; +reg [7:0] ram1 [2047:0]; // 2048 u8 +reg [7:0] ram2 [1023:0]; // 1024 u8 always @(negedge ck_1356megb) begin @@ -112,7 +116,7 @@ begin else D_out1 <= ram1[addr[10:0]]; if (write_enable2) - begin +begin ram2[addr[9:0]] <= adc_d; D_out2 <= adc_d; end @@ -128,22 +132,25 @@ reg [7:0] shift_out; always @(negedge ck_1356megb) begin - if(clock_cnt[3:0] == 4'd0) // update shift register every 16 clock cycles + if (clock_cnt[3:0] == 4'd0) // update shift register every 16 clock cycles begin - if(clock_cnt[6:4] == 3'd0) // either load new value + if (clock_cnt[6:4] == 3'd0) // either load new value begin - if (addr[11] == 1'b0) - shift_out <= D_out1; - else - shift_out <= D_out2; + if (addr[11] == 1'b0) + shift_out <= D_out1; + else + shift_out <= D_out2; end - else // or shift left - shift_out[7:1] <= shift_out[6:0]; + else + begin + // or shift left + shift_out[7:1] <= shift_out[6:0]; + end end ssp_clk <= ~clock_cnt[3]; // ssp_clk frequency = 13,56MHz / 16 = 847,5 kHz - if(clock_cnt[6:4] == 3'b000) // set ssp_frame for 0...31 + if (clock_cnt[6:4] == 3'b000) // set ssp_frame for 0...31 ssp_frame <= 1'b1; else ssp_frame <= 1'b0; From 5b7882fc4fe6274890105578040d3592bc5dc3db Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 12 Jan 2020 00:19:12 +0100 Subject: [PATCH 1422/1854] style --- fpga/hi_flite.v | 304 ++++++++++++++++++++---------------------------- 1 file changed, 129 insertions(+), 175 deletions(-) diff --git a/fpga/hi_flite.v b/fpga/hi_flite.v index 18d3a46ac..aa1f12925 100644 --- a/fpga/hi_flite.v +++ b/fpga/hi_flite.v @@ -1,11 +1,17 @@ +/* + This code demodulates and modulates signal as described in ISO/IEC 18092. + That includes packets used for Felica, NFC Tag 3, etc. (which do overlap) + simple envelope following algorithm is used (modification of fail0verflow LF one) + is used to combat some nasty aliasing effect with testing phone (envelope looked like sine wave) -//this code demodulates and modulates signal as described in ISO/IEC 18092. That includes packets used for Felica, NFC Tag 3, etc. (which do overlap) -//simple envelope following algorithm is used (modification of fail0verflow LF one) is used to combat some nasty aliasing effect with testing phone (envelope looked like sine wave) -// only 212 kbps (fc/64) for now 414 is relatively straightforward... though for reader, the selection has to come from ARM -// modulation waits for -//market sprocket -doesn't really mean anything ;) -//redefining mod_type: bits 210: bit 2 - reader drive/power on/off, bit 1 - speed bit, 0:212, 1 -424 bit 0: listen or modulate + Speeds supported: only 212 kbps (fc/64) for now. Todo: 414 kbps + though for reader, the selection has to come from ARM. modulation waits for market sprocket -doesn't really mean anything + mod_type: bits 210: + bit 2 : reader drive/power on/off + bit 1 : speed bit, 0 : 212, 1 :424 + bit 0 : listen or modulate +*/ module hi_flite( pck0, ck_1356meg, ck_1356megb, @@ -14,7 +20,7 @@ module hi_flite( ssp_frame, ssp_din, ssp_dout, ssp_clk, cross_hi, cross_lo, dbg, - mod_type // used + mod_type ); input pck0, ck_1356meg, ck_1356megb; @@ -25,79 +31,69 @@ module hi_flite( output ssp_frame, ssp_din, ssp_clk; input cross_hi, cross_lo; output dbg; - input [2:0] mod_type; // used. + input [2:0] mod_type; assign dbg=0; -wire power= mod_type[2]; -wire speed= mod_type[1]; -wire disabl= mod_type[0]; +wire power = mod_type[2]; +wire speed = mod_type[1]; +wire disabl = mod_type[0]; // Most off, oe4 for modulation; // Trying reader emulation (would presumably just require switching power on, but I am not sure) - //;// 1'b0; assign pwr_lo = 1'b0; - - -//512x64/fc -wait before ts0, 32768 ticks -//tslot: 256*64/fc - +// 512x64/fc -wait before ts0, 32768 ticks +// tslot: 256*64/fc assign adc_clk = ck_1356meg; - ///heuristic values for initial thresholds. seem to work OK -`define imin 70//(13'd256) -`define imax 180//(-13'd256) -`define ithrmin 91//-13'd8 -`define ithrmax 160// 13'd8 +`define imin 70 // (13'd256) +`define imax 180 // (-13'd256) +`define ithrmin 91 // -13'd8 +`define ithrmax 160 // 13'd8 `define min_bitdelay_212 8 //minimum values and corresponding thresholds reg [8:0] curmin=`imin; - reg [8:0] curminthres=`ithrmin; - reg [8:0] curmaxthres=`ithrmax; reg [8:0] curmax=`imax; - //signal state, 1-not modulated, 0 -modulated reg after_hysteresis = 1'b1; //state machine for envelope tracking reg [1:0] state=1'd0; - //lower edge detected, trying to detect first bit of SYNC (b24d, 1011001001001101) reg try_sync=1'b0; //detected first sync bit, phase frozen reg did_sync=0; +`define bithalf_212 32 // half-bit length for 212 kbit +`define bitmlen_212 63 // bit transition edge -`define bithalf_212 32 //half-bit length for 212 kbit -`define bitmlen_212 63 //bit transition edge +`define bithalf_424 16 // half-bit length for 212 kbit +`define bitmlen_424 31 // bit transition edge -`define bithalf_424 16 //half-bit length for 212 kbit -`define bitmlen_424 31 //bit transition edge - -wire [7:0]bithalf= speed ? `bithalf_424 : `bithalf_212; -wire [7:0]bitmlen= speed ? `bitmlen_424 : `bitmlen_212; +wire [7:0] bithalf = speed ? `bithalf_424 : `bithalf_212; +wire [7:0] bitmlen = speed ? `bitmlen_424 : `bitmlen_212; //ssp clock and current values reg ssp_clk; reg ssp_frame; -reg curbit=1'b0; +reg curbit = 1'b0; -reg [7:0] fccount=8'd0; // in-bit tick counter. Counts carrier cycles from the first lower edge detected, reset on every manchester bit detected +reg [7:0] fccount = 8'd0; // in-bit tick counter. Counts carrier cycles from the first lower edge detected, reset on every manchester bit detected -reg [7:0] tsinceedge=8'd0;// ticks from last edge, desync if the valye is too large +reg [7:0] tsinceedge = 8'd0;// ticks from last edge, desync if the valye is too large -reg zero=1'b0; // Manchester first halfbit low second high corresponds to this value. It has been known to change. SYNC is used to set it +reg zero = 1'b0; // Manchester first halfbit low second high corresponds to this value. It has been known to change. SYNC is used to set it //ssp counter for transfer and framing -reg [8:0] ssp_cnt=9'd0; +reg [8:0] ssp_cnt = 9'd0; always @(posedge adc_clk) ssp_cnt <= (ssp_cnt + 1); @@ -108,238 +104,202 @@ always @(posedge adc_clk) always @(negedge adc_clk) begin //count fc/64 - transfer bits to ARM at the rate they are received - if( ((~speed) && (ssp_cnt[5:0] == 6'b000000)) || (speed &&(ssp_cnt[4:0] == 5'b00000))) + if( ((~speed) && (ssp_cnt[5:0] == 6'b000000)) || (speed && (ssp_cnt[4:0] == 5'b00000))) begin ssp_clk <= 1'b1; - // if(mod_type[2]) - // begin - // ssp_din<=outp[0];//after_hysteresis; - - //outp<={1'b0,outp[7:1]}; - // end - // else ssp_din <= curbit; - - //sample ssp_dout - end if( ( (~speed) && (ssp_cnt[5:0] == 6'b100000)) ||(speed && ssp_cnt[4:0] == 5'b10000)) ssp_clk <= 1'b0; //create frame pulses. TBH, I still don't know what they do exactly, but they are crucial for ARM->FPGA transfer. If the frame is in the beginning of the byte, transfer slows to a crawl for some reason // took me a day to figure THAT out. - if(( (~speed) && (ssp_cnt[8:0] == 9'd31))||(speed && ssp_cnt[7:0] == 8'd15)) + if(( (~speed) && (ssp_cnt[8:0] == 9'd31)) || (speed && ssp_cnt[7:0] == 8'd15)) begin ssp_frame <= 1'b1; end - if(( (~speed) && (ssp_cnt[8:0] == 9'b1011111))||(speed &&ssp_cnt[7:0] == 8'b101111) ) + if(( (~speed) && (ssp_cnt[8:0] == 9'b1011111)) || (speed &&ssp_cnt[7:0] == 8'b101111) ) begin ssp_frame <= 1'b0; end end - - - //send current bit (detected in SNIFF mode or the one being modulated in MOD mode, 0 otherwise) -reg ssp_din;//= outp[0]; - - +reg ssp_din; //previous signal value, mostly to detect SYNC -reg prv =1'b1; - - -reg[7:0] mid=8'd128; //for simple error correction in mod/demod detection, use maximum of modded/demodded in given interval. Maybe 1 bit is extra? but better safe than sorry. +reg prv = 1'b1; +// for simple error correction in mod/demod detection, use maximum of modded/demodded in given interval. Maybe 1 bit is extra? but better safe than sorry. +reg[7:0] mid = 8'd128; // set TAGSIM__MODULATE on ARM if we want to write... (frame would get lost if done mid-frame...) // start sending over 1s on ssp->arm when we start sending preamble - -reg counting_desync=1'b0; // are we counting bits since last frame? -reg sending=1'b0; // are we actively modulating? -reg [11:0] bit_counts=12'd0;///for timeslots... only support ts=0 for now, at 212 speed -512 fullbits from end of frame. One hopes. might remove those? +// reg sending = 1'b0; // are we actively modulating? +reg [11:0] bit_counts = 12'd0; // for timeslots. only support ts=0 for now, at 212 speed -512 fullbits from end of frame. One hopes. might remove those? -//reg [2:0]old_mod; - -//always @(mod_type) //when moving from modulate_mode -//begin -//if (mod_type[2]==1&&old_mod[2]==0) -// bit_counts=0; -//old_mod=mod_type; -//end //we need some way to flush bit_counts triggers on mod_type changes don't compile reg dlay; -always @(negedge adc_clk) //every data ping? +always @(negedge adc_clk) // every data ping? begin //envelope follow code... //////////// - - //move the counter to the outside... - // if (adc_d>=curminthres||try_sync) - if(fccount==bitmlen) + if (fccount == bitmlen) begin - if((~try_sync)&&(adc_d768) // should be over ts0 now, without ARM interference... stop counting... + dlay <= ssp_dout; + if (bit_counts > 768) // should be over ts0 now, without ARM interference... stop counting... begin - bit_counts<=0; - // counting_desync<=0; + bit_counts <= 0; end else - if((power)) - bit_counts<=0; + if (power) + bit_counts <= 0; else - bit_counts<=bit_counts+1; - // end + bit_counts <= bit_counts + 1; end else begin - if((~try_sync)&&(adc_dcurmaxthres) //rising edge + // rising edge + if (adc_d > curmaxthres) begin case (state) 0: begin - curmax <= adc_d>`imax? adc_d :`imax; + curmax <= adc_d > `imax? adc_d : `imax; state <= 2; end 1: begin - curminthres <= ( (curmin>>1)+(curmin>>2)+(curmin>>4)+(curmax>>3)+(curmax>>4)); //threshold: 0.1875 max + 0.8125 min - curmaxthres <= ( (curmax>>1)+(curmax>>2)+(curmax>>4)+(curmin>>3)+(curmin>>4)); - curmax <= adc_d>155? adc_d :155; // to hopefully prevent overflow from spikes going up to 255 + curminthres <= ((curmin >> 1) + (curmin >> 2) + (curmin >> 4) + (curmax >> 3) + (curmax >> 4)); //threshold: 0.1875 max + 0.8125 min + curmaxthres <= ((curmax >> 1) + (curmax >> 2) + (curmax >> 4) + (curmin >> 3) + (curmin >> 4)); + curmax <= adc_d > 155 ? adc_d : 155; // to hopefully prevent overflow from spikes going up to 255 state <= 2; end 2: begin - if (adc_d>curmax) + if (adc_d > curmax) curmax <= adc_d; end default: begin end endcase - after_hysteresis <=1'b1; + after_hysteresis <= 1'b1; if(try_sync) - tsinceedge<=0; + tsinceedge <= 0; end else if (adc_d>1)+(curmin>>2)+(curmin>>4)+(curmax>>3)+(curmax>>4)); - curmaxthres <= ( (curmax>>1)+(curmax>>2)+(curmax>>4)+(curmin>>3)+(curmin>>4)); - curmin <=adc_d<`imin? adc_d :`imin; - state <=1; + curminthres <= ( (curmin >> 1) + (curmin >> 2) + (curmin >> 4) + (curmax >> 3) + (curmax >> 4)); + curmaxthres <= ( (curmax >> 1) + (curmax >> 2) + (curmax >> 4) + (curmin >> 3) + (curmin >> 4)); + curmin <= adc_d < `imin ? adc_d : `imin; + state <= 1; end default: begin end endcase - after_hysteresis <=0; + after_hysteresis <= 0; if (~try_sync ) //begin modulation, lower edge... begin - try_sync <=1; - //counting_desync<=1'b0; + try_sync <= 1; fccount <= 1; - did_sync<=0; - curbit<=0; - mid <=8'd127; - tsinceedge<=0; - prv <=1; + did_sync <= 0; + curbit <= 0; + mid <= 8'd127; + tsinceedge <= 0; + prv <= 1; end else begin - tsinceedge<=0; + tsinceedge <= 0; end end else //stable state, low or high begin - curminthres <= ( (curmin>>1)+(curmin>>2)+(curmin>>4)+(curmax>>3)+(curmax>>4)); - curmaxthres <= ( (curmax>>1)+(curmax>>2)+(curmax>>4)+(curmin>>3)+(curmin>>4)); - state <=0; + curminthres <= ( (curmin >> 1) + (curmin >> 2) + (curmin >> 4) + (curmax >> 3) + (curmax >> 4)); + curmaxthres <= ( (curmax >> 1) + (curmax >> 2) + (curmax >> 4) + (curmin >> 3) + (curmin >> 4)); + state <= 0; if (try_sync ) begin - if (tsinceedge>=(128)) + if (tsinceedge >= (128)) begin //we might need to start counting... assuming ARM wants to reply to the frame. - // counting_desync<=1'b1; - bit_counts<=1;// i think? 128 is about 2 bits passed... but 1 also works - try_sync<=0; - did_sync<=0;//desync - curmin <=`imin; //reset envelope - curmax <=`imax; - curminthres <=`ithrmin; - curmaxthres <=`ithrmax; - prv <=1; - tsinceedge <=0; - after_hysteresis <=1'b1; - curbit <=0; - mid <=8'd128; + bit_counts <= 1;// i think? 128 is about 2 bits passed... but 1 also works + try_sync <= 0; + did_sync <= 0;//desync + curmin <= `imin; //reset envelope + curmax <= `imax; + curminthres <= `ithrmin; + curmaxthres <= `ithrmax; + prv <= 1; + tsinceedge <= 0; + after_hysteresis <= 1'b1; + curbit <= 0; + mid <= 8'd128; end else - tsinceedge<=(tsinceedge+1); + tsinceedge <= (tsinceedge + 1); end end - - - if (try_sync && tsinceedge<128) + if (try_sync && tsinceedge < 128) begin //detect bits in their middle ssp sampling is in sync, so it would sample all bits in order - if (fccount==bithalf) + if (fccount == bithalf) begin - if ((~did_sync) && ((prv==1&&(mid>128))||(prv==0&&(mid<=128)))) + if ((~did_sync) && ((prv == 1 && (mid > 128))||(prv == 0 && (mid <= 128)))) begin //sync the Zero, and set curbit roperly - did_sync <=1'b1; + did_sync <= 1'b1; zero <= ~prv;// 1-prv - curbit <=1; + curbit <= 1; end else - curbit <= (mid>128) ? (~zero):zero; + curbit <= (mid > 128) ? (~zero) : zero; - prv <=(mid>128) ?1:0; + prv <= (mid > 128) ? 1 : 0; - if(adc_d>curmaxthres) - mid <=8'd129; - else if (adc_d curmaxthres) + mid <= 8'd129; + else if (adc_d < curminthres) + mid <= 8'd127; else begin if (after_hysteresis) begin - mid <=8'd129; + mid <= 8'd129; end else begin - mid<=8'd127; + mid <= 8'd127; end end @@ -348,26 +308,26 @@ begin begin if (fccount==bitmlen) begin - // fccount <=0; - prv <=(mid>128)?1:0; - mid <=128; + // fccount <= 0; + prv <= (mid > 128) ? 1 : 0; + mid <= 128; end else begin // minimum-maximum calc - if(adc_d>curmaxthres) - mid <=mid+1; - else if (adc_d curmaxthres) + mid <= mid + 1; + else if (adc_d < curminthres) + mid <= mid - 1; else begin if (after_hysteresis) begin - mid <=mid+1; + mid <= mid + 1; end else begin - mid<=mid-1; + mid <= mid - 1; end end end @@ -376,7 +336,7 @@ begin else begin end - sending <=0; +// sending <= 0; end //put modulation here to maintain the correct clock. Seems that some readers are sensitive to that reg pwr_hi; @@ -385,32 +345,26 @@ reg pwr_oe2; reg pwr_oe3; reg pwr_oe4; -wire mod=((fccount>=bithalf)^dlay)&(~disabl); +wire mod = ((fccount >= bithalf) ^ dlay) & (~disabl); always @(ck_1356megb or ssp_dout or power or disabl or mod) +begin + if (power) begin -if (power) - begin pwr_hi <= ck_1356megb; pwr_oe1 <= 1'b0;//mod; pwr_oe2 <= 1'b0;//mod; pwr_oe3 <= 1'b0;//mod; pwr_oe4 <= mod;//1'b0; - end -else - begin - pwr_hi <= 1'b0; + end + else + begin + pwr_hi <= 1'b0; pwr_oe1 <= 1'b0; pwr_oe2 <= 1'b0; pwr_oe3 <= 1'b0; pwr_oe4 <= mod; - end - end -//assign pwr_oe4 = 1'b0;// mod_sig_coil & (modulate_mode)&sending & (~mod_type[2]); -//try shallow mod for reader? -//assign pwr_hi= (mod_type[2]) & ck_1356megb; -//assign pwr_oe1= 1'b0; //mod_sig_coil & (modulate_mode)&sending & (mod_type[2]); -//assign pwr_oe2 = 1'b0;// mod_sig_coil & (modulate_mode)&sending & (mod_type[2]); -//assign pwr_oe3 = 1'b0; //mod_sig_coil & (modulate_mode)&sending & (mod_type[2]); + end +end endmodule From 621eb129764b90ac464d91b134f06291b01b082f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 12 Jan 2020 00:30:23 +0100 Subject: [PATCH 1423/1854] fix: lf simulation, wrong offsets in majormode --- armsrc/felica.c | 8 ++-- armsrc/fpgaloader.h | 80 ++++++++++++++++++++++------------ fpga/fpga_hf.bit | Bin 42175 -> 42175 bytes fpga/fpga_lf.bit | Bin 42175 -> 42175 bytes fpga/fpga_lf.v | 104 ++++++++++++++++++++++++++++++++++++-------- 5 files changed, 144 insertions(+), 48 deletions(-) diff --git a/armsrc/felica.c b/armsrc/felica.c index 91b58d97f..d42640532 100644 --- a/armsrc/felica.c +++ b/armsrc/felica.c @@ -337,7 +337,7 @@ static void BuildFliteRdblk(uint8_t *idm, int blocknum, uint16_t *blocks) { } static void TransmitFor18092_AsReader(uint8_t *frame, int len, uint32_t *timing, uint8_t power, uint8_t highspeed) { - uint8_t flags = FPGA_MAJOR_MODE_ISO18092; + uint8_t flags = FPGA_MAJOR_MODE_HF_ISO18092; if (power) flags |= FPGA_HF_ISO18092_FLAG_READER; if (highspeed) @@ -404,7 +404,7 @@ bool WaitForFelicaReply(uint16_t maxbytes) { Dbprintf("WaitForFelicaReply Start"); uint32_t c = 0; // power, no modulation - FpgaWriteConfWord(FPGA_MAJOR_MODE_ISO18092 | FPGA_HF_ISO18092_FLAG_READER | FPGA_HF_ISO18092_FLAG_NOMOD); + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO18092 | FPGA_HF_ISO18092_FLAG_READER | FPGA_HF_ISO18092_FLAG_NOMOD); FelicaFrameReset(); // clear RXRDY: @@ -471,7 +471,7 @@ static void iso18092_setup(uint8_t fpga_minor_mode) { AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(8) | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0); // Signal field is on with the appropriate LED - FpgaWriteConfWord(FPGA_MAJOR_MODE_ISO18092 | fpga_minor_mode); + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO18092 | fpga_minor_mode); //20.4 ms generate field, start sending polling command afterwars. SpinDelay(100); @@ -720,7 +720,7 @@ void felica_sim_lite(uint64_t uid) { TransmitFor18092_AsReader(curresp, curlen, NULL, 0, 0); //switch back - FpgaWriteConfWord(FPGA_MAJOR_MODE_ISO18092 | FPGA_HF_ISO18092_FLAG_NOMOD); + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO18092 | FPGA_HF_ISO18092_FLAG_NOMOD); FelicaFrameReset(); listenmode = true; diff --git a/armsrc/fpgaloader.h b/armsrc/fpgaloader.h index c91fb3315..90d020333 100644 --- a/armsrc/fpgaloader.h +++ b/armsrc/fpgaloader.h @@ -21,10 +21,35 @@ #define FPGA_BITSTREAM_LF 1 #define FPGA_BITSTREAM_HF 2 +/* + Communication between ARM / FPGA is done inside armsrc/fpgaloader.c (function FpgaSendCommand) + Send 16 bit command / data pair to FPGA + The bit format is: C3 C2 C1 C0 D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0 + where + C is 4bit command + D is 12bit data + +-----+--------- frame layout -------------------- +bit | 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +-----+------------------------------------------- +cmd | x x x x +major| x x x +opt | x x +divi | x x x x x x x x +thres| x x x x x x x x +-----+------------------------------------------- +*/ + // Definitions for the FPGA commands. -#define FPGA_CMD_SET_CONFREG (1<<12) -#define FPGA_CMD_SET_DIVISOR (2<<12) -#define FPGA_CMD_SET_USER_BYTE1 (3<<12) +// HF / LF +#define FPGA_CMD_SET_CONFREG (1<<12) // C + +// LF +#define FPGA_CMD_SET_DIVISOR (2<<12) // C +#define FPGA_CMD_SET_USER_BYTE1 (3<<12) // C + +// HF +#define FPGA_CMD_TRACE_ENABLE (2<<12) // C // Definitions for the FPGA configuration word. // LF @@ -32,32 +57,34 @@ #define FPGA_MAJOR_MODE_LF_EDGE_DETECT (1<<5) #define FPGA_MAJOR_MODE_LF_PASSTHRU (2<<5) #define FPGA_MAJOR_MODE_LF_ADC (3<<5) + // HF -#define FPGA_MAJOR_MODE_HF_READER_TX (0<<5) -#define FPGA_MAJOR_MODE_HF_READER_RX_XCORR (1<<5) -#define FPGA_MAJOR_MODE_HF_SIMULATOR (2<<5) -#define FPGA_MAJOR_MODE_HF_ISO14443A (3<<5) -#define FPGA_MAJOR_MODE_HF_SNOOP (4<<5) -#define FPGA_MAJOR_MODE_HF_FELICA (5<<5) +#define FPGA_MAJOR_MODE_HF_READER_TX (0<<5) // D +#define FPGA_MAJOR_MODE_HF_READER_RX_XCORR (1<<5) // D +#define FPGA_MAJOR_MODE_HF_SIMULATOR (2<<5) // D +#define FPGA_MAJOR_MODE_HF_ISO14443A (3<<5) // D +#define FPGA_MAJOR_MODE_HF_SNOOP (4<<5) // D +#define FPGA_MAJOR_MODE_HF_ISO18092 (5<<5) // D +#define FPGA_MAJOR_MODE_HF_GET_TRACE (6<<5) // D + // BOTH -#define FPGA_MAJOR_MODE_OFF_LF (6<<5) -#define FPGA_MAJOR_MODE_OFF (7<<5) +#define FPGA_MAJOR_MODE_OFF (7<<5) // D // Options for LF_READER -#define FPGA_LF_ADC_READER_FIELD (1<<0) +#define FPGA_LF_ADC_READER_FIELD 0x1 // Options for LF_EDGE_DETECT #define FPGA_CMD_SET_EDGE_DETECT_THRESHOLD FPGA_CMD_SET_USER_BYTE1 -#define FPGA_LF_EDGE_DETECT_READER_FIELD (1<<0) -#define FPGA_LF_EDGE_DETECT_TOGGLE_MODE (1<<1) +#define FPGA_LF_EDGE_DETECT_READER_FIELD 0x1 +#define FPGA_LF_EDGE_DETECT_TOGGLE_MODE 0x2 // Options for the HF reader, tx to tag -#define FPGA_HF_READER_TX_SHALLOW_MOD (1<<0) +#define FPGA_HF_READER_TX_SHALLOW_MOD 0x1 // Options for the HF reader, correlating against rx from tag -#define FPGA_HF_READER_RX_XCORR_848_KHZ (1<<0) -#define FPGA_HF_READER_RX_XCORR_SNOOP (1<<1) -#define FPGA_HF_READER_RX_XCORR_QUARTER (1<<2) +#define FPGA_HF_READER_RX_XCORR_848_KHZ 0x1 +#define FPGA_HF_READER_RX_XCORR_SNOOP 0x2 +#define FPGA_HF_READER_RX_XCORR_QUARTER 0x4 // Options for the HF simulated tag, how to modulate #define FPGA_HF_SIMULATOR_NO_MODULATION 0x0 // 0000 @@ -68,17 +95,16 @@ // no 848K // Options for ISO14443A -#define FPGA_HF_ISO14443A_SNIFFER (0<<0) -#define FPGA_HF_ISO14443A_TAGSIM_LISTEN (1<<0) -#define FPGA_HF_ISO14443A_TAGSIM_MOD (2<<0) -#define FPGA_HF_ISO14443A_READER_LISTEN (3<<0) -#define FPGA_HF_ISO14443A_READER_MOD (4<<0) +#define FPGA_HF_ISO14443A_SNIFFER 0x0 +#define FPGA_HF_ISO14443A_TAGSIM_LISTEN 0x1 +#define FPGA_HF_ISO14443A_TAGSIM_MOD 0x2 +#define FPGA_HF_ISO14443A_READER_LISTEN 0x3 +#define FPGA_HF_ISO14443A_READER_MOD 0x4 //options for Felica. -#define FPGA_MAJOR_MODE_ISO18092 (5<<5) // 01010 0000 -#define FPGA_HF_ISO18092_FLAG_NOMOD (1<<0) // 0001 disable modulation module -#define FPGA_HF_ISO18092_FLAG_424K (2<<0) // 0010 should enable 414k mode (untested). No autodetect -#define FPGA_HF_ISO18092_FLAG_READER (4<<0) // 0100 enables antenna power, to act as a reader instead of tag +#define FPGA_HF_ISO18092_FLAG_NOMOD 0x1 // 0001 disable modulation module +#define FPGA_HF_ISO18092_FLAG_424K 0x2 // 0010 should enable 414k mode (untested). No autodetect +#define FPGA_HF_ISO18092_FLAG_READER 0x4 // 0100 enables antenna power, to act as a reader instead of tag void FpgaSendCommand(uint16_t cmd, uint16_t v); void FpgaWriteConfWord(uint8_t v); diff --git a/fpga/fpga_hf.bit b/fpga/fpga_hf.bit index 7e3fc14e2223e60a37b3427515e38c4d3dd62f4b..ae66d510fa02ca3e7181036f0f8e2bf134ebf884 100644 GIT binary patch delta 33 pcmdmgl4<`*rU|AZMh5x{hWds^3@Hqp3IqqkPoTHI!#2=dpCMjv%d}B;fk~rxYumOYZ3zl7hv8}jX4RKsDc4Sv}NFo#B z2#n45+vnbyxdYVgde3XUuJuJ(%h_BV?mhqZ{_Wr1`y8k)KJNdI$heuN{8{gx-~8Wi z|FfCBx8Hp0pWfE?nOkq8TPV{0S98*TeaGx{nr@|Nd%8V6%bh)Ic01ihb#8h=`_&8P z&Y?dg+S+>tKi~e^@BdkvltDz3(nf~=-%cB@L8^0Rnmqn91;4LL6P{Q8Y@|t254GM( zjSfHlcYZ9Tf6>_U@BE%0TMGXn68gXA|Bp~g|Kfw%5czEy&;JVlsr6yC(XTtxCAAN6%`jP)or|*_vwu4EXG%vrw_c4+d&Nz=5ac$I^FmYbKL0VM#}j) z?Nx2X=x*_zx6VzFy-fs9wuz$Ua+|@L!}Ktvyl7e+rhalGk#wVHZKo7PNxX*Tz>hcW zA$pA3yl6qUNr+@#9HTwdz;7P6GTeqHAES439bSC9dCYp&XrJ0vFyEk)G+o9wnIo3& zPtn-NefHu-^BA3>Mc%BUIU(PtPK75Eq~9Z*hv;3xdkSWXo~8DYSiu}s?>Ze_@d3QY z7=B!1I_*+3N29B1|Abbn=Ayk){0l$HL~jzq{(HLZ80Kf;P&{qM6#C=YX>-^) zP7AZ~+2)J>#*r8ABaGtdOUBL9bVhUzVK^t`d(^o!?wKRC8UEI`nq!!ajv|J0O#PHP z2ttaVc=5dX7U}uvo_s$&LNh)44)I)KHH4(w(nF8ZOp5l17yWtm=z;LM`EN*qz+IM3Dw5p==1&Zfc{bC!Y7mZr2Q9T(0gj^+AaAh?jVkrS7x;t!bDI=Q7L& z#@X&1x^j6E)+BjOor ze_Vc_5Bd6)bn@l-pMr>T>$riXm}N?J+UPHnkpUX0ON9v2Ib4YnyfIpnWJ zvSvB2MPqcHIBfS*-oqaADA;3%O8RvX?ULBNz2X&Xb-LNJGmWpfyRfnGWGr}(J)M4~ z7Tps6l=*(*1(hzwR+|4};7JCS?JdDeLH5PkCdl{}^Jns1yW?eS(J_CoD)WG^UlR84 z*J_R%A2U1X1=aal!&u7#dS79$4x668UfZBwyXY#4e$M=)VEwW)=8e1-2hg9l{COtg zHkWdrFQU~jAd$SdNTSaYPds10GSIIbUMofCHZG@rkvd|#w?MygsY0|?U{1Nu+h8+K z%6Sx@Yc8Z0sMBjGmsq&10>51#I0mXqvq~fGh}q9c!>6DL!H2S@jl#?ElP*`qhK@l z0?A>+S(A#>~?guouKa*L5a{G7&J#) z?0k!7_VBmz7sCwlj_PH5sQX;nVT4_7gCaqLYK9xRL%3oPb{kKM{yZ~&J&3N>rLVgUou9!*uhn@#tdtN!_{BrE2Sk#9 zq*Ej5+9YkE8QG@65`IbG*H3AoS3lQWNpH*fUaSyJ;>iLJ7BY-qJe)rB1Rdo8j!$}t zUZMYo;v?1gwScE3pLvrO48_N%xG*5|Zq)B_d0dQNdI|0_KhF9!H##n6$;ie;-p+;a z3rmpn>PW<#L^??qrp0o~<`R8%&N=usk-dTL0e)S$O5EVym46^pw^D@g>z6d&s~4uF zUZeRGO-FB|VVS0SCyZagG995`Ih~{Nx6R%1OzSmX!&n%kpqgE~TZHh7 zw_hYJ>eKzI)q_2ZiFLHaOQ!K2z2_Of9s^p{=gn?)|bdL1&h^a04K@r&w)%(r3U zu3=DM0Sh-gD5*xC5S_PG`Km4MK7nK(GSr57MobhLg2 z_yvod-Rb@#UCE87X790Dx@_3+K))=@$FC7U+gz9?70U!(E7wr7v3rED~=qq%o1o&DO1DWl>CivfC{G!ib?6q_09)|3k zuxO3pdYGRQeofQ;S&TkkM?VzvFwfD}nuE@EnaY_Z{4#)FhDO*?b<%?1n4<$H2k&Gc ztHQ54slhV~r8RZkVbN}E5mf8OTETwL_#-goH8*%7$Ku z-=*&?cHg$sT>*aO4d55eR8Y^0=tGHn@*?^}X2{KEC_-g*GGE{~@1{mpa^74$!S4^0t7> z%YAkkzbK`mty!BMP%g$LOj8ZI?K2h%+t)9~FX+39C(XZ5Z@crx;^WacJ!QLvWd(DF zkChs~42@``^tbFN_L}c`tY0;SFn+{<_qpZ3>6PCLfq@-VKSK!E#3rVBfdCj+Jv z;$J=-|J**qjmIDK0eZ#aYW&jgd6S-nU5yo59vVC);hb#8dt9EM0KbY@rekn^6B+w% z(PHm8(l!*`*VXQ?1^5?_YY1D*14nE9YuggpYadpzV$=}xOa9?>i?IOAR&~l-}gBq`b@h9^e7O_;QlcG3fA;_?>;fZ0Et(W<27B_(CDu_<5$48Cg>2gE5KI3 zzef8P_}>cn7sD3#m&CY+%w8Bhc#PR|_*V{C@MhPYD`Q_XVMW>UPd0`Bt$=^ASq8Uq zKa;VW0Azby@UQ!^Nwj{I@r&Dht7g_yfUTY2AZW9xtJYr&yM$j3^Di+|0@kO(e};e9 zxHizQF#l3xl!BRoeg%DQGqrv(|Kc7_%C(%Z?npK)i#PU<`kZmZ{AO)0&!LZBu#mYa zqx3VtR>O#S8!^EI7S#IdA)nO(m?24$4uIx?F796yZr%6@KYH z8xz>-^*J*JL*3zR0Dk%U72uZy^*CL3+UleYvL)d7o;g;l^~=XE@a17YY5CI$+O-0RgGWqHzenb`#v@ zJbtwYW)P6Q5{~o?_@Y(#)s6T@-h7pvKri(*bBy+j^k~cpBX`paIgsmR)z5k+lKANC;~XMyuo`TaSkL(yAZ~&APPE! zJ%&D8V8{I){N4p2{Gy$TEq~+7#6V_$Otib}0c7AZA^bXSE$o8@IP4tfarK$jzyYV1 zV)_0Me!&7rjA9%nx6_M0-7;bQ%30(gmK(yaQ<;toV1kWj=S#8N;v^jVc6nDWj9)vU zDRz%I!ePUqh=hHm6r8}=H=^6*%W8|N|F&6$Uu@a1{l4e|wiFBjaG8ND z#J_;czFlSG8QW!zV*$5I!dsE|9)#uKT-J7604(q#*U!Wc%;JC|iL z(kvq*q6)vX<>wGwYMJc-r2VsJ1>4QklD^h zm__P{qNu{JZpJUQ$JK`Mn6*a&(Hv1*!7rGmjE=9K?CX%NU+KThc^mUQX;U;A!Y|KX z3+tqUu-Uv_outbc(Zc*obQl{3ZY?$;&}zg6Ot)vkn(o8~qG9|JZE9UUF=hj{RQSE}<>Bt*ja<(qfLug=3yk4N*oC@+22tHQ5=ON#L4H4%Gz z`6{tsDHz!}5Uqk=&Mv3^ndlwj6%Gk{kuI@G?&_N5**A!Q6KVXi;V}Z^++8;82FRle zup6>_6Jh-FQX|oY;(6LpM4&?<9Qkk$8m|xYum4GHqi5mQ0fY^GS3h=m$-F#r6JBcksW5(tHm`(DUcCYl z+nYti?DdFSg7?}~Z@E*A zUtjX#&A4Z`p~Wy}J}Y9A^IIwsy}*3+d*YSK4;Fa0l|#>eX@lQ0po4uN@*G z2MY-s(B=+c?3dAZY$kLR372_rTwUqN;>3PMOJEEDciF7-~wwqVT{muejMV_V_I&y(PBE&_?$F|H*+{BT(FuVybf-nh_OZCvHm_lhQQ zF9M0srXc^N=<9&3me-K~`g)0fHPBbk=j!~|4v{ZnnPQ?JOZl;MW1H9S2RcIW!&91e zwd@hk%Q?AJ-n_;*>b9Sq|B?u6446fC!tM}05rch(P{A+fB(-Pae`~hNgHF4Q<;+Xz zpsh1C2dp&Dq2^y*TUHHj7PW~!<#uiRO5#%bmbZl&M=1XVtG@Kg+-n?T+|nI!vMIN3 zCcGxZ(EPRV`InBowQ6@If014Z5Ju-nLe4&}d2 zCKoN6wei6d`S+5Y%j!4wv!E@11;3zi95zI__#o+VwTgqBiKvPn7GNprRm8Q9P=b;K zpJ6>B>+r0C_+dBr*A5OF_J|t+#}7(4Cy03}SFWpyA3jVinYtb^kN#e?Wb9tC5RLt@ zSMcj3&0CDGqd%$<^DHit+%Y@}Vlpd@tvZVbv;v*%Vj>nDvQIjCTw(lDbL`jwGc6Ch zopuU>I*b{^{FL%vHQ-mP{R+hoAEhfODHCaD0F=O%!fC#nuHgMV=C3L9uXofOH#Qt?MEK}QH`R@>#$h$P zxZ&*hAvDE2EZ(JgEFha4(Uw2Nzux!XvmNizFKidjDFpK;OwYH6%)cHnnn&!Lr>bUTlI*x&Qazo1{(8|JI9CGGQL>cWIT@|QdRmcOPPKV)CMp%4WY40eog{wp^z zsK-^szvc|3kREb>A?F;h#*t8ap5}P<%|uPJ1W8U zFqHp#*g-@ZHbH$yBwkuOTg2qL$%*~krlemnDkzsOpaw;XQU*eB3cFdaX`o*mKP*74 zVq}tC!~h$V34TEvz50UbnZDoh+nlr0*6+0V5?3|AxGC+z}&WC_wF$N>Lj6j`UBK;4&MTE zDc5hTr)Q0h0~-qFsGk-rn6J~{r8}~SAC6dh|8V?p&}(aq-j#jR)%|%yjP|Tsn%W#q zh4D)@f%)3vkQ-eGOUmP|J#`Qya#_8-qUT>r}!)-Wz2zQs~XDpZ>LXtwY+j>81 zKOu-8Dromhr9dJRjb@5w#EbrWbo|ioGxIOq`InJJYtEzQB$WRG|7yhc$)tDQ`FYYt!yx;i|82tD6$w-KQ;a58C6|@N&GlD#0 zWcXV?|4I<7`ZzKFVg=DeEb5i;i{pon`}h^~nLE$U|AoECe`$Pgnzj|I+#;hR<*{FO zLOpJ4Hd@Mmas9?k=+BqU*HtjjZ`dGN+@CRDFHpZ>;a9ztap^w09UqHt1pjim&xjuy z$E1!HzU{B6GJlC00e;e7!Y?antfe+at1%8Fs<;-w$f8?;P5KA%Lp#sfRNiAQHXC*w zKMC-Q>!Y|#0{fZy7x+#|xV~2e`jxaB=pWP~u0uOY;9te)O1MTR)FLC6WKq)oUD&()Mr+c_JWV9{A-{@C)4-V*cgp*B#j=`G|eh;_IdP z7e1zx;)mrvM~m<`o}gyV;syLG!}xV1<-)c+`@oPeMq~q(& z*QD<1HZw^lWugbGQ{i7cio@|8CgO)YoHRCM5Y?~3FCPnh+ftk~pY42Ce5Bu7s=vkY z!(jUr5vyb(R=ZU%99FQ5Uua|LEgH1RC)$u6Mq{)wBrhu0Z)kIo1_WrK0Q^EFm>X?s zJfN2yjc(^YGYSVwkVn2rKgk2X9B#$&Lw`q=>|rm2)AS`H-V=@=!rx%F^*+Leot*A` z2elA$NN2=)`8|wZdj=Bj;9%l4dobJPb`LhbhLJ+!%KVG-UyrF7Mw5MAk@D7Oj3&Bn zcyhtYNFZ8>f9+8-nD6{N{T;7u+};O3Ebw~@BE-K?=isbYrblCPp%YUmMEubM?YVfN zIaI$fA+8>ckGGt5Ku`1ae8Sb-Rf7m{P`T3dquGc;epTwmJr+sRw%)c1F z;BVAL2eUtM<{Jq&I)Iv!-93r9z}yi3diZn1_;mp8LaPI{`nW8pRu_(9sQ&N?)jYB8 z^NFLMd-D627NhTF|Cn~DON(GPA^duq(nF{=Wc-@TdraC8Mq*+9#o^HU`2Hp1&WW09 zU<$6^iOqJ6hjCTm7x-7&j5$wb+r9Yw$fdb=h29BO^&8D_QzMQTK;U^D{8h<{4{Zw7 zAMR9FxRLIUG&)?iv94SEZEV+C4P+tw+R>f#B3ET&vcK1T2|=Fqw6`1i!K(U=m-jI_H!=YIvrxQ@P!oTQbu6=PV zx1<$3rQ z^$wCj`fpY6iyl`k_*LUPgbimd22XiO^d(&mB!>9c1l+>)s)gM`)Oo5U<22mb&V`5} z{Cb-f%D)UCNzP({i5P54sQ&O*G~0`f-1-tdUAsue#&5ldo&*1ija1cdfPW#gwUEu-pf)sext!u-p{Yz&yq zNKdy52u03Qv%;3}t0sx?bu(uW=3DpP*u34o8IW}E!C80XNfrOvT1?Joj_+(8PtFz3 zi~HQvIP@#Tzn-May}^m>LfVkM+{1dkN667O9Ljva0Kfm&Eh zRq?M0YXQa6*E4=CfD^c6l-{!L?1PmE@h{XL7UL63I_Qj=^D4|>M~?=wRc0lANIRPz zsEz(!SB6Q-rNIMWU8^t(K;C5m(RakTG!M? zRIpqlDiBhBxR~mNeueX2s=WxWyTSgYVmoHcR3``9{yJVL#VVP9>G>dB?Gm3xdBY3&9c)q-(t9okuS)zYz%L`(BwC!oYZFG462Px#fL4VH zej#SXXq6MGEONDd_*KgJnr!Pmi+{lbxjuJ;OM`~%UQdDxIpC9|OZvt9OZPAbv&>~1 z8`P3kXTrKuVJ%AhtAt-YChQ@*MlyQB`J(Y9Lcv~$f4$%^OUf^zw8QkQm6mM|zy$ea55u{VewRA?V)@vnyf6Zq>7Ykb%5Nz%(SXMHSR$$zz~y@0JHie7Wm zBcREDEs})5W+Aez|Fa~yKgF8gRj?cFQ7ikD>nQS~3nBtedu!TuYb*5|v?JGy`gw7* zY1g0*!L>JkLtVNuvQl*W@6qu?C!Jm4P8z1;l=pyNWF4oSlya-;H>P$jMqclP^&Z#H zkN1y=|K?nC@RC=<_=Wgk24=^i{mLJg^RzL?!??=z8=Gi{(X8xDSCe%&J>W%qBTZb0 zD3N!l)NdHO5G`D=s^RPAF7+v{nY@7R&1Q59jJL(Q^LlRqWMHvBK-?b(hFE62-RyL z{CY!iI20E0o21Jde%rh)gSggh>+g>W|69uXbC~5sx4E%vD7VIKV{SExpUC896gZXf zYYknlIY{;%LYqzE)6^%n$fjH<|CR4cHiLh4y#)M9NzkrK$sjj_Hp1X#2me}$fzIQu z=IJo-3xX8gJ;;ULRmp#y$e&Culwi;Sx0-6ACRuj=UYLKK(8EbNQ4Sj-OgCbFgAV5B zWMWIh^&5aKqgyq)w4U8LHD#GtD}i5G5vt$l181~*8aEktQIh*SKz-8f0ip?Cznb8y z1GX~u5%DP9qh|2@ETuK>mTn5?zt9cjPd87woA&p?hUd(0SO?|y%+g#X|25##$=s6L zAbgVt2rdl#ngwj~{llcQ1!f0ct_Lfj%UYoRz^?*;-Yn<8=4YWz>Ux)u_HseHj%Aa% zZxiyc3W_gzo|82nC(fv%R&2SmL$#tbNHh@QhnpkwBN6K1HhE(ztAJRZSag0y1JbaXbAsw<&a`uD_2G1wtasUki@UgLWCP>e7b7>_`1! z%D^hCZRy%BKfXcrE7^rm*e#$Hcn|EnYyB7zpyj<$GJE)2`HLrD)fY)1>^}Onp~>U8 zje|uBPs;f9K7oH_VnKDo@ zAV50TOu^t^&6&Os|KhTZSrgIs#To0#*W+)Rr%}J52N>dCz^^RI08$EddS2}Q{#F_u zUNE%2ihrR$6F3FnT7zsZlt@`?RZG#{9_C-$DNlBDL`dbjWVgam+z5cK=3kGg=8XLc zO88duUq>yU`!_%b`|~2izkZ3WgesI6Jw@sLF#+Ml^n(4>{7bJ_M$=^Y8!sW=`wK@C z%#qp*uPMh5b!0&EZfl{34d4^-*nIOZ{Pp7aA<8!P!z~=4onj^>d&DdDF8cIvvNwcZ zgs@>g+AUr*cB)yfjWcWRBZDdKd@s5Dt)TvJ9A|T&Xp|bUXA1-bWQ@mN!7ub@;l}t@ z^U%nt}*7}#<+7j)=9I57{6`?C=68bFGSu_nhrn! z|9XSoR2@r!)M5T*wDsB-B`&8mvQ0+5Du&!OG9~T%!~AOx&C1x{kIV&r;Sj-y7?t1Z zY3rhm;r!Pl1Zp;pJkebPGhr4%Sok0qu%L>6b*Sa6Uz&e;=<^t%kRu=FUqJ{?oMn|*#1iyJPFrtSPWZTu7i>%s#j2=Ad(Zpui*Sw zE4u1RbXA`M=!u5#i|gl+?b;+--F2?pUB?Fv_DqJ60e1Uqq3aJht2oU>dXd_1ifu-l zlYMOfsS18=1#CS5XuBSvX%;p{N9DV41~9HNe&u0y+8M2yCHv2TAp*Nm=2}bdAFe;# zPA%E)Vq;VH-F*oa`Ly_`e2iN1(PFlYU(2zzkYi0Z)>FTc$JUBOsW6z#N7Dd5-;Nn5 zo2TX?cJD=EgKRz=IU#l!K8EyqpJvdXFBK-r<#AwX4ckWF%i=*y!gPEwjwea;$OQQc!U2#IO-9n#j9T| z99r#un$VvR|Jp_1_~UCG_euMK1GXocXcNusTbB{i*DvN@DAi8ewlJxn663!egDa9f z1fD|S{1^Py*N{DFqjx>@XP23Dj|?;BmSUBff6)_J3h;NOSPM(okgz z_?Lpep-tt1`f>PL2!@PQ^Dl5K5xooAgze`oQ{tbjwFs0&|Nbog#n~>@C^`VLg7}%* zmideV-zb*wE5_!6N8u4@mxsd8!h@s@>mgOL?ur{G!j^4N9!u&>SMU%RtN zg#A)<^lZqq93MO#&VQlUT>*2+;yz>hp-wO39){7Y@Gpl`5_T@afjh=-kz#z`k4Z@T z`X!P7I)$*|Lpi|K#Bj%ctVIf$tadL|sPM0S^d7@;u|F8sc*`q5b9Si0@xxQH9bSrg zObxs3I5^yra)BUtPlbP_Xph<=leMC#)^yJ+g6uyIO=3jIpMarAWN%*Q~)eii0lzofj3z99id7iA#aX5?1xpU@aYkx@FWp`Em;ls+!*k6y-(waQDRZe^p zj3Xh}=ED4Iue!WgcLdn9Mxl)Z`^;@-R#Uu=lJ0xbS3(nmzin{Rwa9^IzfmL+V(%BFFU`JT4T?ij%aDg%Ez7 zcIVj3QB$gh9iE>hu6@J@vNHc-{Bl*dD~6qWsV$2X$uuo$u-(>#vS&^gFqItM3{gG|{d$!q)@VXz#&s=4` zEWR1=FZ%JTb0&a9W&V|?x2^dStbYh4Ptcw1(bv^AEQI2RFVgF3P6l-#^Tg5IqGIZF z|21^RLt-VwzjE?!j*Fr!D)UUEK7X-U$LH~+%)fH`OA`M&sKdKkX$nisr3)GA4 zsyo#qHJWcuT9L(#iruiZ7_fH;fC7S7{`O6q8@t~2A`eeb=)6ts}lcm>1)_gejDi5wgOy;bpShVQ_?R&6e|hM5yJ#5ki-J2 zBY0dve1mX5z>h#-F!R7%?6Fv{nZyBY^rsLd)Aw60X7hd(!iMGuL#;&T5oZ&crJM#T z?r;+39h(;VwFLs69KtAGQ+mDp^IsSR!`5Rw37oV0j?o4*?;7`G?*#l}Bm(ZFU6M(pi5l8amt>%1cxYtLJnX7b~JuU=f4_wnJ})UdR%AdOJ4l# zNj;M?+@^H?3-iO{nlEE{Ow|AM^Is8PFZ}w$nO=Rbc!i!o{>#popR{%vQ2g=QM!$_; ze>jub)=}%xfluYZzx+`||7S_ReE!wu)up=*V@)$Tkn80-`h7j~FPHmMs^0+H8m4#X zntZB=edy1+O#r22W=gm%H$at7$NZW}p ze&uCys%SLyx43?T{lky?Wi1H~En4=Md0Z$m^!=97`7h)dxnqy@>Us7j9Q@1WIn?!s zSPMYyC@)-63jvV5?C+n_`LFe=pO;dX9WqhfPH?0{`7bWph!hiJ@K;@8{Gx9Izmi2! zso#J$@g9R(?Nz>iNDs1q=%S5Y)BNO%2-(}i>#(1jcFE>Lh{fGc|KK(c56UgWew%H` z9&p)4J=brXDbAjVp8^s4MQ+YmY^8As(19Nt@m1J_BOlLA;d^_Y@Zyh}KU44C*zqrM zH6>KP0qZwzoivWh7u1wu{It>Ou3!r}_FE&qKhO1toK0r^k{fgxr1?eb2hcARM!x0G za})V(?964a)N%b`6y#A?p}?#3{5i~M{+05spxVPQ@5vWoQkK(wBIPAX9P#Zc;)k$) zj8?dw;weJDpci?o7igAe=gpt`_Ap1jWy1|c$AmVOXzbg}9CmMp$F73>SL_h}`Wc#o z+=MTH1(^Gny1I>ZyVmX`WmB{_$6+zp=e+{LfzwiXs&(4E`Ab91s*}+0y6sd>b z6P*9r51&7VHV6(EB8&xj56LpI=_&VYj5PD8abSAXB_TnVxSCgY#eBBydLb z`AH9bX5mZTB_pL=Eua7T1?}J}o#Uhn5l@=Gr1c=q(N$n=S}%0{p@;GYu0Pa;h#-%S zPK50iw+^DE!0d>G=0nAHT{%fJAd5QFUBvhEs7TCm;z*vV15pz;T!WL zl;eko>8Bt+@L&(Pha`^R70jR0Q%AOY5UTOZh>x|LhTmJlWyY@)75?=--m9_rm;0Mt znA1W0_3sj1=mE&4`FhIr8@ps%I=Z!SrrI-ti-|NJl)$fiHUHAti+ku{FV%zLtf%{M zpaa4xf4zeHqul5b1Qu~@IS<&HZhe*U>qz8_B(YpU{ro}#Y^|rayBA6%<{py&+_caG zXS~5*uK>R&J`(L^{2I{frEz)0%++T2JsQ8%e7B)sKJPrsfLJicV2C=rNvNmw*GtzQ zE^a1h(+CaFOu~_qpirtu9QXB$`PYv8l`b%s&oATtC zQUu52pejg=ow6_b>#p(3SfCp6*ii>)VLp{NPtyAZ5V6s4{RZ4Z0_z_a`q-C(TJe(& z;ry4>7E)sYHLmpSs?t_896xk4tr(>}ixYh9##R83eiEwRU>hFg8obBlci41;?<94b zO8thjgR2cW|MfUsnMpcGgE6UDR~kU# z^8HZ_496!?wgD`N(ZAvegg5;4Lj57C4Z(8}HnjG!f+#aHmHAggRsF`pbgPVjGdhn0 zl3)s2>F<2uMPI*s{6frXBr+G{$}&IwQxv)&{tMVky%wiNT`}Pp{B`0iT$^F=lo~WB?*waFYe|2QqzBM>QyovK) zv-sF@lJ2H91)&^2T!x5rieRxl1z(+Q!g7KEVf_m6uU)X%gXL}fS%HHgOvEPeLdkm- z{7VAA+*r5yA|G4M;NFZsN&FKK4ROB^{|b)xvhRlh?ly6e6m$oPuyX$EI6aZ;%;Wy3 zcL?#QOnk!Zpx@y{*o0ZeuN>poP0<_05ec_YM#sfMj7x)5fL}ytW1ylVBT)KlqYdyY za~IvrKsMy-7xS+j7WUyZF)X(arZN~ZVpc8;{_F~V<=Kw$>GHSeltL}dc(hYI>uGx! zd`t5$35~;xh%$XMX9(?uB9 zVRlYhd| z$-11ljrO>$ycVxj@C)%(HYpDwevnY`=acM@d76J^c%GSm!S7Y|u6cXp5b=FP=1Od~ zc|5LA{!0(XL;Z%vFLrMK)gM=ge@zhbgL%+_pVIcj>v5qX@%e839+y9*>klabyAer3 zWn9OOWj)M2@M~NI{7c6ViL+gaq@6FiE-RV{^efQKWD1_k&4 zFnN-{<;M@_bM!JsuSU{Kkq8^I_XB`{Um^bWC5B^;9|FG=TqBTuJ+A(d3Vy*QR)|C1 zP6yO>6?ah@d5Figy*hpf*pi5F^0iUX9@IYFMW6N%)UDKS&`xh=-X4qmvEVx!qpK3r zZG8&h3!+@Vf%@JoY>N_27UqXHBw?apTdK}4AMaVXDfSKXQ_BynZQl~#mY?As%4=;Z z*Ke?k&X#Qo@Jp6Aq_%Zc{A+=1U^|bv*3yPe=2lz~v4E|p@UhareY#hMkmDFF;5$RATx&nm$1jAT zn3}B-dZGaIvQ1uCo&SOka(@#0X`W2sVi5bJ)Sa)6AEJk_e*U=n10ftgv?eeufb~~F zyE^J(;3_uzBzO|SFXmrK9?rea%z}Na>spok-FXmsJr(<6*f9yOnuqco7U;jeC9_)OrenF*v z!{=Y|olpHN!Ab;EfWtMJJAc^rXn!^TdKJ|g9pahn)kVc$FDN~ z0_}1RvuzoHc|T(Tzj{mY!@KBqf_+9d2j_>7_SzE7XNz_~vdZy8R4ib1(8HJ*9Bj*D ziym_WjB`obx`2Oio8^Qnm?-MUtTcWF@eQAUfmimL7xDfffG?Bchjo8S_~o-Lpw&K@ z!9}#eLtP5TPQ&;W+}7KT{MUP`liiHq;6qjY2A}qd?(Rz1IJ^%5M9hBzwx#iXuttYE z*~H-p0|uxuH;A*9@oTHQ*X6$+nPGG857>3u5p3$h?<#+-Xt0cLh<@lT|Xwx zWvcKCxAg*U?z3-3(X|KI8m8bzsWN^QjQ5;Qc?oi=jLSTn@_Lo=Ym~Er#r3>1gK-TJ z7pP!dW&X9NNh+ zGhyO1kfHN|5W+8xV)+mdU_sYG)v*#!O8kp%i!hsrvR%cs&kRX#SX^-jq0GPL8utL3 zq9X}zqiNSDt?^k~nSV{?YwH$+e*qK>h5+#la8L_@f5`VoaWpLMO(}P^NW-w$2!2-h zmyM-d9M3J;iK|fcW;+2=qlK#c7eARY#OuWaJRyR_(=%oMMLt?}jr+&GR9BI>kRHb2 zd0)SPU)CeI>MGiUGlmRg=<`se&pv)l-U`|^%jceZTpoMl>vD~yC!t(F&$nUgZoJNi zytqHFv%|nbnSX6n{HqN)gX=eR*~T0GAbY@x$x$;w|@O zYGc~($BTFp;$Oje z*i&>y?O=O|49fuO0Yc}Ob8@v`3I9?vLlPeZ0};DQ*7ug;hu~i>hd!czWe$G{>7eygPC6mbIK-e%9spnW`JMJzi=JaSZt#IgcU%*X?h{Ajf}Tc+weZT zZntc6x(7A}=V1%d08!qi#+%|#=H_$HMbR#I|3l;w56s#1j1T(?7wB7i* z!}%`^FvP#OhZse9Ez11DE8*7&?JM!GU;FlOoPJGIMS@-O;y zB~K`R2()tT!LEcg*q6AudvhZMg^PTv?(YQ`c5UB9M{YtPz5!=aB92|guZI{Nnv=O@ zt{8N;Nc+oOHsU`svXNX@Iew^zqhf2!me%3n_S<3#_onty+KcTD^Dn&wa3Kb8jd|C9 z=YsR2Jko;zvJCH4KL7P2>c}IfnZk18S}oikpn^;;IgnlMlx_s;?&>m4%kiM`i<2CGvAIP|8MQg&CFalfi%;4 zb$M^yF`&8R{xJW-X=N2}7BP2+z3@QXjamslQns8b^&9v5-o+iC0BqHC4z0e!&=>g* z#ZQLoH{J#Otci!buz%!TIG9etlgdEQbw2 zyPC%b$HWb^Pu+?WVHNyhPOW_{_{K%I*p0hY)ehs_`i)K%%d||;y)L@pMpx2tx1bs_ z75viC!t`Gbnm_r-1U*5s6kqykbyCzbL-@ruGj@N=<#bTB_paEe18(hd{aO4gb%VVb zW%GSr0v9D+(29zngsjhr>ikzGnTuR1kpF@WujOD`i|if=^Dl+~yr4r2J&BCn18|gaaU3EFPi0rJ>ZP1jVokR4|3um z{^g%vuJu7&%pLeHT`6sh-CuXke+6N~QQ9xrVVF`Y4$8-5YGYOXA>eq${Y(DMJ~;z1 zE1!tXV_zavzcIn}^ZWZ}yWrFoU&KL&jZW;BYW%_xp?t(vAY!?sYko?;NU=?J2H2$a z!oUB}eGy0FW3)r1ChD%@gJ5_IYsTzaBy)=ZVED3RC#1^NYNOyWvB!AJqUKsW!uUN{C0Hem=kc zpxG#Kp2$_h(F^D~wI~lF=K21HpZ{uJ3O;xd!kEp&xHbxRYY+-KG8O!~pHOM(*&JHj z0AX`RtP*!QvlQ->E8`cZmGe}xnbgFDMWCR_o?F4MhZwC!)(@C29IAG*bLMrlRxQk= z_Ehjo+e|yYeag=)6w;3X$hPE8<~z2<2jM7cY~uPuL<|q7JQh=>3e035V&&0@JzP2b)bYvl_R`l1@=U?t( zn-U1uST5OV@RWYl=3P;_e;)ZSRC!6Tbzi@jzr%CU{Jo4{+~-9q-m8yCJ?>r7gZkdH z`PWe-qpoq+54Ut!XR@8_Z!AE5a84fnMg_k_Ic%tDR{;UHbrJ!dPSa2fmXQS0ZSD_k{RYk&1+}1lvGa0&oYe(G0}>U>HOE zt3YRLP~hWB%Jk&4z_?VLiJ0Dp692x#vrhYgSg!wejbC_AlH-T|dtBbC!!?MT(-tT4 zkl;mO{?(Nd8?avJPnmylG~P`Qri5?IasPZ0eQw)`MJe;I4*3tc2S+1+q{|LxGKIOI z8?m@8K!;HL5M}e(Si1kP)U=EH^A!4%s)`?;AecdEeleiQQSeGzC&ET*^|-dx6tPWk zKF+-`C~NV@rRS&2zfhe;ID66qwciks-Kvu@D`@}!0<|6W6LD>eM{{oQZ z(dRP%deOz$9fV9_TX;Rvol+tGRYdsu zNpKlxQ;C1cv-uaZfOc8Wq}g=WeZOm~&%e;dUK4RS`d#KOF)F zgRT;JE>bih{uNLvgrU%9P?(MDPHZ_j!#}@V>tjj{m!qWR?aq}vE=_YRIw;cs4zt3) z;F~|n-+}|ov}z>{RzIw|N;lf1rY2e@~aox{=6j z{@5Mh@;w5GhOt-h>tG>$8^YJ+{#=G0Zs-0~_!n-X(_Ib51^iM0uMFYW;mp+p*vgdV zhYjowAbthEY|0KMw%DUk8Q>T5ucY&By7B=8NJIG5f1tHEI5*+{Lq!)dkm0OQ9{N?m zFVxpOKuKBJ&z}P*JV;k=!G12|S0m8ssyvSW{0Rbypj~6QNNPyUE}{Uw%)b;O0T@@Q zlna91klw5i|9W2>Ru5;Eubk3h>oT?@2qeCscDP~wbwBhA+EmuB-xC+f4Rkeihxk{4 z))QhN-K9QD;m`mzXVB*|etC9(ck2;*UP-?Q_q{7Za5%)j9-?R6v=^KIpznvnj?HqP zrL;mgpjw_`h({G28{6rk?wZ%aPasCoBGmP`22_aA~C+l4GHcvRpQ^F;%}(e~=A z@QcTlw6W_7l&2&uBhjC4^)Rjgzx?{cS+2cY{4?$Hn#b*K@UOp7mlo@|IzsZd{QTEK zsp}7M@fQoWddisVF@A9iLj9rcGqxY^Lj%L%!`J+8$Kc6`Z-4yy!-dkGZ^m%YyCWal zEr9QC$6=iR3hL)e^@mAZJ1_LVPt*$~THTmB6zLV){r6Pr4{w+b*qT*LPSoCMtuD+g z0>4~xxj(`Aua}zUU|RZzQ$zOLyH{Wz;y?%2;p=rr{f2Xj;GK?{AEoEJ;a&}{`iKXCQ97z0(4C9vt*g_r_bV;nCyo@@v2qY#`%j&A| zi+c!bT!horZooLe*0~*L-M@h=l;x}uq_o~+$D@~C!neZs<>$XTB<1*eQjK4WN9m)` z)6|Grso&7Bg{+Y4sJN82=PM^l>+A(Ed=Fc*9dL5Q9mETFTef}b!acrP8c*T{7R)K!uX~2 zikE6DSc6+GJP~v990d{!xaO_LEjN$Os!nKF=u7uryV4Z}}P{ywy|D{lt z34)pLd<{J1N%#G}?O=$d`VHmRAIj?o#H+2l?Y4O=xH}$T`&`m5Rik06C%Uuin9}(5 zC<2L(x$ge8+(xq92=ZTj*OTxZID8bPE(8)0x4EE zyHzveSDAm6ha3n6fqzf{Ynlx4FFx(1Y1dduxQ3pAl>&a1^IzJ_#TI1<04T&&v?RdV zXdEp4`<3vD%053Aa%j6+%70k_t;iu9p>tc{Rsf(x4?MjJ|MGtoYEy$4NWO}HF@6Op zq(DHy1F#@+4t|CDY?3{U&cZ%d@?QZYRruFwzQ0%BA647S>(vDQ1qfiv9|&JIaX~S) zF9lvy_?Hh`9!62(Ur3I(xE1`eYy5wzBibVXwcPm|#MCd}MGtUAN11=^EWuVVKj2@A z3wX}KuTX#VJ<0w&hxu1kpUa&O#SakyR-JrrYI!M{e<4B@;$LOj<==k@{xt)j)S|-t zOOkKmO8UhYS|~F^IA1BT zI_3D`xL@CcPcJrmbH z(}qF<=_lT7jg_Q?!6y|PZ7X|@pj`bLQeZs zg7sOt2u~)LzV)=E3^h?L87d?g{*zLlyDhFP#Ek}nB|-67Tz;ZTZI;z^_4VX$OiqiG z1YyX&p2Cf(X;d0l%=iTTzBet6e~4KNy%7G8q&GQj$?~{JB79|$L0VW!hK-J)YL#el z(B|n3;;FFx3i-gYkTkN?tn9_Xx1N?Y8RL)W4``b51vyPky3Od;PfC53W(H@2_+)KK z7&J17Kk<`Nn=UKe7ju``4lI9JQ2I$}4i&L2X439egmx>&efC_3_y=p6R?FQfHUi>- z@KjB^r=NJPZbDCY)nxi^a{s`dmMsbWR>rgWi7Jh&>#T9}1f=`)OoaNJ>1%SYvnOY* zvM{%=&b_XCa=A^W<|gA0=vp<+7k*z&&KONb7eSDv^{O=%tDel%rkX0@Mt(v;pD`{{ z67^nINU+pm*Xg!OZJxf){5|zj=BlRpu+X=OpOn7!^mR3N^nEh(hfUL-DGQT=Ctk1? z*IsAdpT{RnVgEDk{>ms>- zDxTC(X>pBBMW^&U2o>bm* zZO`Nzt!s^GQVYLtOqP?gV|c3q*H!U zZWA*47oCi-!2phDqtfOhha?a7kbl=Y_~l-pRq z8M=-pt8)dvjbliWfzNsw)v0rYto{_qYtM_zK0tfEJ(OsAE-sg!=od+JFby;}Z4ltI z1y488-zvlC*@6nb1>~&uN6LITN0i_5{2pp68co(GqGq?Q4u7}r^M^j(zsouM1bxceMI`Te15GuA3&I{l8CTs%i8 z?G3C~6)u+nnsM2GkHmUa;c^+E8JB}L*oP8Gz0{s8&Jn0IE|Yq^sp*=SvE&><2Jblw zm&*Vh!e#9FDqJoDGz+C~8S-4UDnALn^+Ecjf;O1L`9=dRQBLt3A(+D+g62zPPjUO| zIf56whiYiHjP;mP>FINX1Ep^*u`>Ic($~c%!`(egP{AA;lHs^wPO2@9evve~8IBo+ zH7-{Ps`M?nv}f{E;PT}22&MH3`C{QU&xU-YvvIi$&=CAj!EXGn`3d>b$W?Re&lO~8 zT;1nDKp7Og;6=o6+*rcpDq(S{$%l%|)o@$_=>Jvz*12$8dh%YmO%*Pe0a^>?HbE*I zp)Q@%?qVVKFp}Gm0Cl)!1!=I~XfgY&4g^M{@(+^9G$<1e(vc95+O&rf2A(vB+El+s zgP99Qwdy_UoK4n))zsV0|JJ{=15uifPj%t&NFAuc>L#cg>tKNf7N;BOa9;bz&62~|F5(;OP8U-vEq*ftznOvG%)oDE;5Reyn;H1c4E+CZ2DHBfhY9|YJn!gHBJIWOa_s25ZT=Gv z@fwq2l#cx;+I~js9s0xX`9JOtQhooW=12D@{oxGDOMgf&`VjWd zhc&JbYyaRq9_Hu&ST8=T{qteX&wt7Hda)tReBTe<=3(!`eS=R{ty6pATz( zJ}mo#{`>~NK444#@9dwnF6R5Azf6-t?3c_m$+{2tMEO@i`T(;OUJU34za-kLYq=n?kX2lVF0Ox$VR;ARzRPe@L7kl4C^)6Guq~*Q<5Ggo!IsB{-?# z7?5qn{+|7wGiOFtLc3P8*6ms!Y8PydUZ3;+?fvX$@BO}_y2zyWe?;2NH2+im|KsNW ze(R^&`ft7YlYg|a{ZBu+k#3>-jz3?X_@AFymPpViDb$hZNG!FN;s0qP)paDUy?WWT zE3T$LBHG)35kKGl>c>8nAgK}2oP?I*|27kvt&!|*OOVU|oBZF`B?!+e|65CtLw(fx zNoutC@!R|uQvIT_?`?k1j}3|cAQI|7-{wCYsebWm+mP3$@oiqA9vkme8}+t}jZQrY zi4WUkvXG+~T}$;+&ym|bq}sUJ1-dA^UyMxY)AEEkK=IRq7fd`U;mIWRb0cZJMvut$ zQs|I)GiS=EZBC1mv|F~@bs14I65J+JGe-EwZYUwf`m&V5N(nsC;_l@MaZ*$7aTnfC zk5Ky)p*()I)sFU>`NooSh}x-6ib*5I@1cdK=sdN%k-UD2j#Gyn&g&C&mbyL?$>~Ky zy{Du-N*AfyjZC7=Y1x&7@Dja1-7<1apTf8C<5>6OJzYiho>yp@8$Z-CK_76s`WpB> zHn%C%#JN8%`ZHa#y}#p_c}BcsY}4B1+^jf_4TPUk&3Yc!ag1Wj$Wf~i>*yJE(iE2= zOH5&l;m6kAO%KYp(&e{_7if!YE}6I0o~O;SEmgls6ukE&%`m+|oidWp$LKyfD8mVT zRE*$BgQXw!HjZ;eFs^CiBE4rcGO0~DZ&J4tnb3Cn0QJ*&Sv$t(UNv z7=_#Nny%J;_Z6zo+{5vlTBhv$ae5tZ#*>$7`}sXhHGZ2S#`VwC;jGW<8_6HnQ{H;5 zvP#5S5Rw>0hN5Ijkq{a6M1Rg3yIC_D^qIa)&1+(P7}o&4wcSFWy>Bht%VY21v1@nG zeU4ca2i5%G$?e`+bl2h;u+FOLC;FU%Y$UBv$8yqxN%u^aMX~xA%()|2^ir=~r@fDRPs3L5|DS zb~uTx^{XK~xlMn?(=YQ1WfMj)idX69JU~_=SP2$-YE!&kPK~mMrMb81-SnJ%e=a+^>IvHk(&FSc_x5TP&qtOT2j|Qab3?^@~N~i!c{v3g%+x zf|ik{N%Y3%Z>2o_`r+><#I5Fl+q%)T#FOrzV^5jah&pfGhha0(Ls^#>omlR!6xQn{ zTANFh!iR+aElFw=N9%Yv=TcpFMfU11(~rGzl>m|W(X44@GZ#(HKSi(7awk&M&zR4f z%iSH5I`yhH1IDf9BQO_Dd2x!i*(+sePftNUL(#)9=C)(;dt}Y6Y%@p9{b=(Yx@82$ zlLaVRUfAARm=tE4={CV`m>Fs%yrM+gy*9$rFEVeX^IDf1%j?thFVx|!#m^zYvXQ4> zx!>YGuXbVHr+stLGD-g`@T6a#@bt^YdOa_@8LckRwCsMeVM3p_pOf7b27U>p7mQ!q zJ^Xr!9+FFsnK}B2m67c!^AI#njXeXqI*2}p64;{qDPH)16&)kkdBWHO{Mtd=4aSQe zz*a1N*vvMbg2G~B=No^>eg^zYj4=yDm)Lr>Lu`S|6A`bE(>2q254Mmpu~rtLC*dG^P{ueMU?Ht`R1Fw-_+ z7NURa?2yeV^m!(J@tQtiOmeG93S(TVS$-|9R=otw-m{Q49bpBeb|kcBqco*DzY&Z*B<@XM%R0oL>e*bT#CEU0HJ;MXvI8B@j= zwD(B8G;fMJ&9Izri-OTbbEW>8rq*5Im!Yh>0;wA|+_n8@xwF*W*N~n6l7|HWelbkE z2?%H?&R+pse$OopS^ZM{a@9U;XZ*4mzbps=ejTIlQJWL$696(9cj_!Lr0@$ufL{mc z`;63+z$ON9VE2&1F9=Wh__a`Vm67OY@~n&g+_QZz@T>EGqCXRc8dpqH_{D9|*zI(7 z-Zi+9&I;&P6@KN*9tifKg=rbmZ5#M*!H+8ASB=6iMym-0Tjsd_mjJS**c%o6awrcg z5h5|BvC*r4v?tOxXtai73A9oD$!Q9|ct3lvWqvOD39$vUf&J{`*RXjR{Zh82B1!!P z09p6s+^J9({XnkBg{$yOjZ6Bl)qNx~`MyIYTTwh2sZFVcuQ|+xy5WNe6U}7yBc|yNYIW=S#RA$w zpLWq_*TXM+f$~Y@+JrUMI3VF4nt--J8E22NU?jLd!|+MqZ^$iq`!#x|c#YezKNN>O z#60KqpL^eu^fH}uun&jyQ_gwox7pyIq4P%9dW@?YzeIQGJyR_Jh1za6enem7JWs1- zcv5$J)wc$Wo9R%p-41OPr_4t*==+dp0eZFrWkjirU&=omQn2+1{VAJ*SSwp~*vyiT zUxvvL;P9FP$ZmBrB*^*_78h&k>lZZuzhLJ>jJanu*k=ma^o;0oF)mm4*8Pe}?6JS5 zIqsZk=ne=A4530{46q8nF3M|4JE!z7H2qXAXCmgW;PJQMU$3D*Q6^%q8H$k&&*WdN z4s6|e`Vz%l2qS7|UQQMKy5I8o&MA67EphccJO_Ty<%dKSex0Y4M=|ra(jU;ZE@+qH zUrt1>orzzdC&1;4^q?ClVZGS-pMhUIKSj(2?4iAq-?Pa+YqPZ(EE+cN4Ud1#JzTH4 zLBfTiEtU_Dz#0#yXYwyzrZIZN-N@q_ZP@R|?*=2Q;1_|**ua7pj0eHLLWk_H(f2Y9 zsZdhP#4kpxF?z#X0U*;x=`?l9h&_{kt){u&xD>&>jrmt^uw&KL7-DF# z+@CW4()RL`k~c05s*XzlIckJtm_JWHE#J*Y+y>S`U*F zw|I}yBgHuH)nJc3GXuZM`}r!?(?vB8*0+sdhX?qj_}50TtrzH`RJ7|d`hVo=)GYpW zlhU2D#7Yzz=jee%=L7sw{L6;-?h!GBK2Dn#2D&@ideIuzpXpIoqr7 zi`y)mGe7e{iGZLyZSk;zYX(wpJ#wL43L0e&fN zlMvdD&k?6 z^~=XEO|8Wg?AXpc^x`~yfd?4im*QWf`aDgKqtAdO1f3{Stl-x)jmc}+-}o#6zgoiu zy^)@k%Zd4y=Wj^sl(}6-OWO}cUo#)Jm$>zZ8rzL+LkJ{-e;Eq9Iexf}{U{r2ai57O zlocgQ!qJG$;9pxYWHr+LM$E0hSH$T%B03M)UBR!WLhs5{B)c|cJ!5ppFxAC?ga>ZK z3I_Ofzlpsu6e+>Cc?^rPf&Go2P}eQsDFOf5OGiwYi~Qgz8&q0CVK=3pvEXm;du+l_ zp{A9#%JyBMv^Z%)t(?$z7mre=uRV|cRN>b^F`f$<;xKTz)!Et{t#RNi&E#KnJ6k`- zf(O3bmJ8h^enhtqwe6Y7zn-8~>A$o8+nD(eR%c(sGW|Mo7c5FH0{?=_;)nSc*p@S= zs7=xZ3j=iZsa`}%dDjK_^%}fota27R^E}plM^0^8I56N}-g+_rx}DLA)oQ) zXnYSbnWn1v;oZ?KK&$QC=f`F9Np$rE`@wCBGY0rIN>aodLk2YNVOngPBu1=!DL$2) z!M~1B*8t;}#rPFxf8(6feV09hfBDfu4l${)A$wMxZ1iU1*GurnI-Kx5`nY798NL+1 z*es9tK13_QFQNztVBx?os_^Uk6mc#u(i!}!#W9PBvwh!d6T}aV99x@EUzADBl@8{I zg}7rfmr-kRsKJqbGz@*#5{LllC2LxAu~5dZ-#U}?t@^leHr91RB>PFW^WA;#$*!%6 zA98dK+mC47*Ci6*_}(v8(D$9CYiIJWr)8J(!QJ}5j-I9c&W7xE^vCJyk2C*L?*ac3 z?CFK>La3@dKnR^1(fKO;DzB+AMf)i{%C^Pnwy>tv{Hw1$9r}8j`Bzjn7W^x5Rp|qcC|WCchtI&TgL1VE{`DieD3?!! zZ_@wK_rOT-eNUx|qDC$eY&lNvinQ1$r~vol|Z+(kQ3rPU+{IH?vDO#;f?( zJPL%=TH{D6{8eGDFw? zu{l}4l(v_mMXZjGUlTP+k}k4cV37`txoiG5B50Cw;~1CEzw%nUvpL&#GxA>-8n z#o83xsA0^r3)sRa#^@Q@VMZR%Ilii%`1n--er={^LhPbQL)6?8`g1W>KZyJnw8_tZ zNf?wb%4Qo3@igs7H|Iis0U+b#9Z)#HFQmQ5E^hCPzSc9Cu?raTb1B5}2R7lXcy3+?BU+IEa^Yw^Zbl9dPKs&kaW-)-O3DK1Dh%BBT=3jR>Ej_CkwqVQ| z+Q!9J81r@6o&djA;8%dQn}7wI>3xpbxL+m0oKO{hrKkXH+5y-S1-N{i{~9XT`?=2n zevQM0c+6qim3!Ujaw0|jjChkCTZ29a_;rSULCc&lenrnB?*KUFe3JsQD*R&F1+*&B zw`mVSiAt2A7S4$I@xvtYUk_2vF|Ec?jNNvc`our-Dtmoay4c=UWu* z1$JK$oCw4GRK*WpcM>=4xJQ3dayNFU{*+XIeEiy^?PYuDZ1@_wdbSbc%Ic%^x~qg| zy!f-qe3RY(lJ}G_~zkwr(3i@n_)I0mnXRCemT} zhp=@HHSDn&_|-CEeqJm>2(HatciZAcwSy)C3p4QRS8`bi(ZVkJCkg%))3?#6 zT$Y=OUsLq=Zo~>9Cc|8Y#}2`PHU<343mdMV(z}cw;Dzzy`hFzBmfNt0Rs8FA%zUO# zETk=>xz9}LCk(6w_ooWKZpYZ`9MNfSfnZLG-E_OtEYYUIzog9B_Ej~aRt`!#VN&gA z-vB!&75rLw2R&0roM>33FQq3^9Vf9Nzk&S|U4uSX@JsM|&1L*LZ$8$CUrj_$yN>~h z^eX&%)>@w1Q5swc2w1)+T+-L$Jdu9e(GGJ5FVk_o^T-Dc z6b76{KtSn*v|gp{M}c35dfJf)>nMeG*RSS`m=k+gl^e>n2b2$23S6Unj}{0m`2iP=C{mCbvW?Yz_F#Pe&5 zhRwFFP-D>J*V);1g#Pe^L(Qkfk5kA_2KZH~ap*v{^?^{`$0H*al?W#8lo(hOPf@;% zUtayjm3sl}9rSk$0lzPv>-(~7o2=$v2I@Cf$dILn>4zR{jrBa?c=<12K7LgG%Y6Sp zq_nn3FR5kvooVNB&)+E4rnt>;%^5_A7v(nR^bgTdiMY)nJ-+AZGzuQ_`jUWui7mM{ zY4!<=O&rv!{t7un_sWJz(df;y3x>8uF3o*)YVjAe$K{o!byK&`m0M&>%Dk;UK{kIY zx!^eqIZX-LMU=<0(5h&h29wc=x&+>n;5HKrAC}->vLU8#qH`Hc_^=*BhH&}ra8AG0 z`&N=p!n5k44Ts?ot>`uv95#lncUHyFRhlu5ywPSCY#O{t(Mep>Ip$B4oDG280l z`V9qJ6ZE5bD*si_Gf0H`4S{Sjg{aX5_{Ch9?o+53i+x(iyYUwqhl6!jqvTo_H()VFu;TuBVd68Eb#S<%=MlN zfwfSAN`w`tlfwPr3ToYRSCq>(u*Xo(<^s07Cp&>(bNabIF7lOQ3|ocy9p<#`ws*Sv z7qAnS7ufNEpPO$9@T(y; z*th5P&?@n7$ZfTs34K?b%I-5(zF3W4Jv<89j?kGmE)CWhfy6Y{BFKMr)NlS$bARab zJwK)I4Yj2%2bXcazx%zpYWy-myAnMSO^n&EgMUR<=wrQaSSzw~tN7PF^ecr{Yq7_K zqRG?FMGFI*ti%r|=!nswVP~GCf`s4VgxVRP9XzST4~;Dv!&c)7D1Nh>hi({r?JPh`{J z6g`(&F2kGj82r@(uv!)Vg%pX?WkoXc%Yt4qr_8PRb*EQpT@VVhV#_8Hlq1+U`mlF!;9f2bc0M$z>Z{GbzEp7|8ZZ^tsHxt~f@& zfTsuA1p&c52%|a1ulLNrFW8?o;p|!iehbR0vij%fNdczG{ZacF^@jrSLk(zUH*TXn zGU@i%79-jXRrvKwEag%+Hd)_k++no1vHobU8bz`SzwVKD+_JP_PKs;j4%w2-6r&ia z9d+vQEzj2F7QO^;u=AF%)iQ?;%Z^m|OZrA}*v|LvVEj`3LHtlvYdp{8l!}O1p>Z2R zNw10@?x*Qww}!mK8wA=Vc8<2>fbVcPXYj9wHO8;#gxE%Q7F*&ktS|ONhqhnBzv4%E zkI~?9-fW_s(w1#O2>6#p2Mt6EoyH;!8O^lL7Qatlq~z80VuUV7yJOPC#^-f>`(ha32I>ocOxzA8fh22)hiMoi3CcJg$`on^RKMy3t zI`4NeoKxnrR>BSELsl8T9_4Bc%)CD?2q)-#rfXzrz6!rgm>oBKV18UYV}pM&&=*9< z;ds8q^7>q;S>!yNYPZcD91gWre=g8qs)a2;hqo4`nh#Rmj>{McVN1t$u>{Z2;7D!~ zi?XWhAHJIo%B364b4ZWuWd4O*(z~{#xsYC%UL7OXAD*^5pIV;?go*R`glr?7qk|84U6U9G!K{2_fsUa9)*?oGE%H2sxGST=u4 z)z51-nbasLC)C(cQ|cgyTE)MH>4Lpqw&g;b%%k*xL^;X?y(GHi{kc%UzW`gVm-a#! z9wiV`$CK7h7Ap9~rm_#Jx0haa0moUrmY%lQ&TGO@`$rn6Kcx7FW7Z8dcWrf|OvDyD zTV<4y$S(7*R{2$PaZf#$j(?Z9O?|7_di|aola{!>tY5XceSjOY4wR;=W0y2ntHLkpa+YRM-r$W(l<0M_vIkG9@?TSq%1z|Om^VKqDmd)A>Sg{_ zvx**b+F_!_l4zPxkDU`G@x>e8w;K_ddT%XaH5=RmO)5(BMH+q z0`-RmDpe@vU}p}|m2RlN=R|I^bCp~78O)f&ZHB%2d3)|n`qu>Ts|473?)Il-BGon( zS|Yd!fqxln6C%0LD1sqOYV=dLoMwZcAFRT!SF@{2;oDl?ML$R{AIE#TOvDetzjO-t z7j5oq6Q(1Y1mg29_*W-3*VS(F^=kgL*IH`CewenL9hqkLat1O)9Y=v^KL4^&KQCpx z5Q|+Fb_a7xzfj+sZiPQzZ+h#__46+mx+cSWLrduySJ}fj9VsPbHUC2X%Z6Ir&1$8_ z6*?u(CDrMn0KdkuOx<*=tFJQPZ@6qT1tKRUAR6^5{TeW?H!|tCn^_Sx%t6mSzt*#D zpxs?k#lIF4Y6e_0m)^^;W1{r*Da^x(An zJRNYur}Y(5WzDMi*S|P$<*ttH=xHuyjzyQ%-_g^OgvN0pV#%B5OpQx98V2gry96R; z!Qh8!UoD7Og@4VvzjZt9an1c!+z4UpNAlQyk2JI!!0v#5y+{-Gwc&^yJehLy9kK9s z_$R3QvgcOuuSd-{vYjsb8{%SS_2kk+`m6M&^@SWralpTJ!UK8O<$6DHUUWbR+2#@C zE7f~!p65bMOk^@qGd9#{o5vk2T3WQy_U5R>TKM@d#1G+C4BIgwT#s9dY;M!}o`-q8CaB@(sB;LH=um&RD=@=ZT_y=6V2` z6PmOqw65A2_$8jELp^bX1Z$rLQ4OQL!2o2w zf5`Y%upj1QU%7O_egHx!fhR~fR`IVhC^hMF=2-K`zk%`wg$49xY-ap$nmFwhF9N@w zr2|g5sIP#~;q0uAA6gks6G%ag$BjK8Vo^AFcv8uKar|&V+K$;I*f`j!7%&%t0^cBh zxVLtzwkHX@F^9hDMthU@)WX_Cqifey@vm{`>1@YMnBFVtX$S7XE_Cea7dt+T{sjE% z8y;+ZEx@nPxQ>WoGE&9Aa`2z`FIy^6_Kbuq&KE!^Bvec|$bXrXrsm;IH{TUQ?6x_* z$rh&ZMahf|rqf{^n+TiuwZn zHJ6@{3BXq9J?;-6#8>HmD1IQ32&=B27l31T17K^2VGBiKsE$wuzrw#zb~uEx`LoEQ zJ)c#u)kSjQrOD)4r?DIEe$PudIUnnKb;M9Q$E|ZluVR6F}9smatLArQ;IDU9uc1*TC8tNwCS1J4`fb49p z>vb6XApiA}eBJ2$a3mT!m4%ahSEO<6DHMg`^iWm&5Pp_Te=Q zWC8zze<=5?O72L<#c(p3h-K^Jv^CYvAQkYhxbuhwQ#k;h0v$B!_d)m;5RKbZ@M|B? zAVyfz9RAO=)VUkAroMg=@C)TkOuH5toM^^|jH6>K8OQ?ug+6P_@0~VO+N%isg1~(a z_*Zb=!55M`BEYnKd`Cg}^&3^^mxF`MuTe%u3&|?{Dv+v>ObC~-1lY}D3|2H(z^<#r z4{e~{5VZ1D?GXnQc$YXO8KA4=6ADZtaM zD66QBANEonIWyEBK1s_c?C1+9Om`*G=PLZVj8J)=0`2+{Js{gaMe0{l8dzX{ptj(x zDf2Ic4P8`gjFyEk9fji&POJ^;H}W3;I*d_(h!Jw)$5_C6tu5B3xX;6|WAK`CSa%gS zc3@IoQ-?7(BwB*}*KXokHK0|IP&O|^DF`^9;vx}N;a`X!wlPEG`uR5IUl-_`83>u@?TtSsD|SU zqdFW#Q!Q>a|Kjz^wzT>_zs|XJC|VW&+DH$j+t-A$J*}2nuiavt9&&(a7JNU8=clO# z6?e4M2^G2Yj)kM##)Rd^8Q!vfEwKE`^9AhKJ1{9+l&GpENyUMmRZ1Buyebg z!m^rwovrO$1Is_oMMu0A$LMS?gkr$IYDO`fb_eP?4mehAz}h6^7x1*7`>f6{3-A=# zGYJ>4onfm)ULk$CeuMcJcNLuR7+@>z0BX@^X9j-F+pC6b7R4F*7Cs8d#@GS$P_(M} z;aL+|;JdL8gZ{jZc?M?;@M~{I4F@HlycWsG!z>u+{9V=chhti|g>=It%#K=0UQ=a} z0{n_0Y#7glhQ%xNBbv*{Ql{uJiprVizod36TzTGF3|qwRxMOonCcv*o;8$BQ^f~bp zLfXqkVbXE)AT>{5hX?r8NKeVtUi?tO78fG^QZ9d``utap*McqN7`7JU*C6T-=`ptR z0slH}ehzjXW%K70Y_Z^67+QX^8o#oM2WgoTx=|c69$bX{*Uj7?`|1KVQc%Bx{uB}E0b6q zsDtb(;gHuWFpMBjRrrM{=*Mwv`Rh+iWY3#jha+j7?-0NM4`I_P9Mr5L#}9dDE`Wfu zr6px#6cG#XD`m-4luh?lIQ|SsI)v%n?=GpvFU=<8fJW9K&SvANtQ*>cHV?yQR^yiq zzr}{RxYkCh1#4>ano^9%72sEjvmQK(I0SSxrwqOtSAbttc0(oan4Wm{u!3JN(DU}P z6xeYWHo$VG$t!?gu$karj?yo#Kiny!d|H|7H&ohdF-dQLC2uVXHDhp}U?mbF%$;ZR zPH2P91HT4rEEl<`1qJ1FfDUmM7$#y6FbT}R)VBu;jqTnRz_;r(iU5LG)xPrHDvJ9S&0O{y6yz3z@JB3|>S_#@`DYEb9za}+gj${k7truuWHjhKN z3_#Y*piuDaD)1}GVZ%81;GQ4aiKoKLLS(-VA{GIcspaY6`VH$>zt!!|eO*5RgTMMo z1b(NG2>WXuU~x{0+o__P-g_BN!wzLB}NWPU;%6}U6xW%SwCFT@Xx16mGC+32llautT- z`^Nrzy!$s2nQ%^zS+BVrGCZswm(QgXkOlmUEx&K#R+WXRBr;+%|~I)(sFdjShta|5v)A7mb>;c52n->^FX{yKMF#Sd+H1pF&r#lJXg zc!%>LYwf7PXOm$Zj+t+&LVEqAw^w)9Fa)S@=(ym*iH7VSv|4Y{ffUA7#xDX|A%xAa zWgxE3L@c533qnwT$QAzgIw8id%|^3R*C%#)m}`ln<@h1v7wR{%z%Nx`$w5@ccZ~g| zs`w#wqyV*}beIxOLzDhZ$vuoS|FU`Ps6RA)wx#gPL5;^od3Lzd!N2;Ex5vEuH-J{a zFMHbTM*ZR7B!P$-n4b!M(Zlv0Mym-Ejw@&vy+U8i+?Q4O#h(KIawv~i#!})i!BMo} zC^C@Q85ocwp6=x4S!mOoGgAWf^Ne5p;-}2W2>9je*DzgXoJlXUk$wei4Xw^aHleKd zxy{S(1%4e77JtjcT`^Pi=s+ajQua6IjCoFSfL{*k0WQb`_VW`hzjU}TJMzysbB!Aw zaCjrm`t_&r$!?$0uQO?nU@fnVb^o$Jox$>Cm`+eqWnyjzN> zw;5jq|BxNU2|DCr;qn#!)e5!R;mtG053v?D+$TQApd+7YKjtsQ2ReA+H!1rf>7YHO;o}LzJS|~phy~P|J`L_KXuRjy? zf86_CGEa+@o~UD_sA>6riWIERqE^iVG8=mp_@#Zs^AElIqdNL#yp4GSpx(xb zFVcngElHn}`)En3ez*Q96=s-^6}i*Dt1N&}kmQ#t!(`y9o93DIELyUGl?*TnWE#X8e#QjdrPAeZ{}>`fI&P zI9SPlA$}-V=YV?eHiL_ap5KLx*pzOS@heLRYpnU8^U*%*pFI7VPHj%``LFqZ;>|M< zgC2C+Eb~V3-^x08Lg80znJ_&4vRS{f@$tH=M6#@3rv&?l!0wNG>pr}2h)z45#c-=0 zD%-IOgnMb&9xm~|CFy6-6sXlM{b%Hl3kR7UWe>+a{nD&6sIyw`sPzK>Vw;J`cCK57 z`%yTduyVloA8DM=m1Z92n|ynC%J`1cUNZANInS4nHBsVHQg|Q%^*BY_O|*e`U)C>D zJ2PfoX3%{e7K~XCN*I?P-yrDM5rY3Cb*>LrT}6F3?m~&@ar|28R}S}Y_~A9*404}U zBxkZEz_01tm|UF*pI+OMydYP*IKTXY#W!*=|0?6xMarbx&Dfjuwmc-4o-s4xB>RVU zC{xLQakMb54TE-N0ktlIPGh)jLvh9+eu(-FfokWxK;TXy2?&Q%9*X@5t&`>a7jgZD z)0GJ4=iBBv+3Cgyfjj4&$0j!95cg9!SkfLfFJ!xicINdn4tzfsSJM3w7V?@a;VcFC zwS#a@(*oZ?x|0q5P$=d+qpft~xk~*;r`YbG8u8l!&O{?(hDeBI}a_?K^JZI%) zo2@6si1DzDj921^FVfTi^ozJ`zE@o_G%2TP4uW!nLHuykVJjMjzoGC8M2v+-elp_Y zm+?o7y=xD#f3`a9o03`4YHXzyY@aLqi?*ku4z5OQHMd6FQGeKTHQk}TkF9!zf9>I1 zQmiq}DWv!ftNQ8}fUqoeVtwWKhRT0w30joK+8hxmo0oil6kQ7wTd6-B7tpUGsA@R# zjbCWUe_1+WdRMIkqLuM$cg-1uYy5Gk^Ix3*LSO;odT*J3StTQ*+1Ot<*u?xRCSeMO zehD7?u*H;<(0PnqVN*RgV+FsqI*e9`uWmJ>YcMUX+P7$la|5`ix9+)x zqnK6r30d73ecIgbtj{vf1)|N(2KOIod;M~h7RF@&wDKiTMG2u&zabgc!=xka#R9gw zUq3%T;9sl6?OGhRu096Sz4UI7tm8IU)SEdR&T_Ej!M`@(M2521$bSvQos5+}EWf11 zU8;&7F0$c<6~ML@jchUFj@c)sw69o8T|5c!Yp!6}LfWfK{y?_n!Z*$TN5Kcds^f?E zb0+-+yxdpqbM$UGCo9HO>>W?io`2}nARZ+TybiQ_H-zQ6ctOX3DSl5?{oy_4?M=-i z$^OPg&K9~_n!Vx*MGVoOfPZBj4t>B}bkdhiP(@etp^fUZ&%ZVSzi{4a68aSf++hQd zNZJR?_(`*?lK(;+Nh~j#`RHo%$1>`KbD^72rQBJ7o%g?$MS&6ACl{kQC0|K(-ifPk z{tqG8=puVkB85%TI&M5GmX83fIuTy$lIu(QN_kOR?uI8T`L9i;)S`!z`Dna8)6;%v z*k1c*^f>rML%zblVo}r|y0LtHyl!g-hpP51RtLerAfbb5O-;iT8N=qWbEyFCw9MB! z;3<3DI`A)zmmU0zt=7HnqWqjrB!9cKaDHtJ;H!9ws|WaXMnP?88n+Q30nrag@*VpC zzkW$vt`olv<)(qZ!4>sj;sO79No*a$X_U+jQN$11OCV6Vkptrb3g$mhRsY_MeV zaR9$R@Hco|U$4|3_96#lyLF9N3x8bjH#FPL*k$~(wRh1SsHdoV8UKotN?tCB>o+DE zO>a$;ra>dI#QFv}ndI}YF*@Sx&xY;60KayD`F8J^JE^}=UZ$VWU!wviQVJD4{Ti+r zhZRjopq?K$hBAt05T!;0FTk%|w3)7U8dAbS%1`mH6BcK{8%h=Yx|{xf;5+tZ$=dze zH$DFK0y^JZ%518_FSt+lBb!{m1GFpdhE#2s8KpYA!oR*vuV|~Xb94G`1cwy=nxN+j z%d_EB1;0u?yXn1Vjf;J76KoyAhNUFNgtrs$qXz!9^Su{30$f!nGSWgQ$9IiivuFcDR-L!+JYSd$Q1Olf3w$ z;6nO6vcA+4)E|BXrh9KwGlkb{yvIkFSxWQy zWu=2f`(RUxg(wXHtMFqlI3fn9HD@-74`Ikkzg)`O0J1C!T@u^|_aDl`*8ZXJywF_7 zw`0%Ic^5a>LEpVKW&U-p7v9C*%DB`3OOYH-tf==e|N1H6c*`W}H+=pz$#o8RQmH@e zwKK@a)enjL%l2^6+6%sniydso;{M2*IDIu7EtuJK#b%;0ye4+K9ByM8VFE{^CAqox zm&e6-{O)l8&_d%T#P>)2n6)5Zv127d{Fz|cNbln&h#%H6+uGphC(8EF417|Lou|or~Gkvj@C$>u90hV zeneGq%hrq~>qAq47S!*Lf1;`1){SWrLT zPPogWl=;h^7Yy9RlndRK?w}pA#jeJ$Fszn}7LLg`FtdmsnpiK`Ln{>E*Q3S-_&Xb( z_@o++6PX-5;iwZ~6BYh7My|wr@@pBtI&TPf47Sob_P%5VzwQD5YNn)vKfb_+D3krd z6K2$Jh#`5e9V>|C+EDt>ayYhpE#b~#8#i)P_!kY@_ET8OhUURt@p0u)4Z=5Gm*}ak z-=IW3yjTy>NDqi%4g?bwCNub#OVhpBhwk>tTJU9BYUq=Q$8$wTg@26`PAlWsSIgoI z4uU!1uj&Rf1t*dXmE(uTMq}$}yOZ247R#-!jr)5qYXyN)NiMr`e=nHSDA-mf8}k&F zX$1>T2sXT|Un`M9LM=K<6D=J0P2v7|ZlkhGzJ7815ThW_3LD!7*Qup-=3n5sP6fZl z1)KM!*5#uR9&?r!=a1&ja{lYC3Vw}Z6bUB`{K5{}?_jwZ$P^>1@GrntREx<*TPeQj z*7`z_|1!bjHe(b(q6H9|S*XR>?UY%?zjpCRljdZ4g$7{+lVCVtnjoPS{x#0~Fd5!8 zzg2of3_Q;7Po;h%dUouwp2$55ZDl+&@cva!mZ3 z9y=V_6?#>iw;wAkJy5CN@Q#m#pAL1<(9nU_@Cg(KaQ$KA^YA?T*>0%w%T{wC^XFob z++w37-VuwO2d%bI6w>>cLWnS8YmHznI-7Uaw2UHo=Y#K=`T)NQB;8yh78aNT2lsCz zDC``t;-jH`75v&k1-Ap-L2sdg)6s;D)J+%N?nzj`0KagRoYi$aa&SIiOLi4^l732} zdTmDi;S@d3p{l7t#Nv|OCnMhm5%akW^(u@TfPNv)HZQb8yf})Be3yl|P{B*|RPYOD zVPoybLVW)`e#NB%1Yk>I8~b->8nM;Frr4gt zyqHzzMuYqpkLz)_nt$bJs;6T_aq8ebKLX<8%>jNjI|urr(a>h`FVfG)O#@i>xS_un z`#oD%s&TNRfXf=JkG}+C^finTOCD{Nig5J9B`EV18bMrG+Px z(}VNNDn8F9&aZvy7cWSTW`L0$^?WwYf0h4!3IxR&U!dDD3UiZ~1YqOG%YVgf(-c8Y z6H(#};sAD~eqP$Fy?BP2o0{k*mEnlc8 zR>CVMX&*Eu`{#2j;68>6@=Y0MJf@!P90sqR=w9RE3ddVrT zsfS-x{L8c-b{A(+e|S9LUmkvyL=Zo8{L^Uz@;^pkFz`WeF-ihWobYec)dr;9p@| zg{pEQxT9lSs2r;lId3gY(1RQSzbxS@P8~`Jj&H=6qop-oF2%o|p=)^w*r2JkC}ICV zzp}d2`?v|`zdSD&^u&j)NiUFC)Hl_tJ{Oc5mhGLppkpJT0q;S>Mc@LmDujeDR zA3yB#{{EMXa?=SWswD=p@_QCwg7Fjl{jY=Q&yVe>yPf&qc7gr`=a(mt|H8Pm5Tz%2 z?!=I>7Mx@K24|Oi{Nnn<2j!=2RkrbEKmY`e#a;O#t*X>-_<#S))+c27{wVZkg=-`# z_{I9=sTI9pDFOSCt{p`jJBT0h6W|xD4VxV|yb1(d{i}V0K7R52hg|X$>leR;_y*S> zmVLj^iqoDQ^Xd>AcBSU!!7{x_W9+1tfKNJzUy<|=CMI2IxcL8<-@2i4eUZ`rfZcG1w?YQ8A zy<4mDUmJ-_p4QD1i_NV~NTg=r2>JC1rAqve+W^{H1q99kjWbVin1ht{3-yN{1mGem z2r=N7*QPN&;^~)HzrkU#ke!`^qX^hy{Q|#8SLMIZXZTTldU5YBjMWbFl-${?_#)p* z{>z89VyHvB%8iS9x%f?g$@33Y{XD6#VHDSHuz>rc{J#k1=f9GO&!f*M2?KuJ>vdi| zabP8?>JQ6fH@D(%$Dr}JnlT7L{!8`erpTSZua}7-Ny8JIV%wQT{h_i6s6XVj;G0iQ z%Ci}6vleYoe1a!c^&1t~!u()OQ)*2i1o^L+2U{sIiD25&Jur+D^e`$YAXJ_IQafrz z`ZbUczKBC8jblX%>NgZ~ISl-IGwmG%5hr+ub3N@u8Nby1^Bgw(DdI@0S@`eHufDbV zl{r=CzXJU_0o&r~mpq?RwYz@(eEIKxfwlRxOT`Z}-K7mv^NRuh;;)Y)o!4orOOY0N*f1eRmBh0noz7x5h~Y@|nX44h=V=5sk&gqSmGO)F4BF-5R|?1iJ6~0QsPL=ghk3ha z2$N<070|BPf{k%`RE)@d)6^wMYFay7Q z+7b`FjCep;Fp|fmIM1d8^3~I1;T9n3Lqd5X5rUc z^!YVUzpDR!B^&%1eXinPs&cPtIKj9o@k7%`s{pnFp;EuW`_KVe1ziniMy3J*0bW$$*BN;=!`2IB{uKzXc>2ZnAL7&@AOJS=QX}Kz7r~#$HF`75U|=EL z3Vs2S-nu_k`1Q7JeEhP3UkIp1`Qw&U{ki}PP^+h@0eUw|z)@>X_!qE`7@ z^yC^Hmpxe57`W`AENGr^g}Y4IReG|w<}=zSoZqt+j#dfCui%NhOxbXfLbGMkZbYPe zmLP5KJ(9E(68P_;8W{*R-jjvpHcuvNKC68~{+_+CP!T>ti{!`b;9E~Rl%gi8B~4Zd zn)jsK=cKAX=8NRY0$c$NnKs*!va|W#Zjqw^Pk1MQwls@Jz zOw_FRgnkIWM~*u$VK~9K$btKBkOmO)1k-ZJGUur>9O)agFmJ-TO$R8K>DoMw-Ov4jC zVlEJxAwOVSNu%86$?NqG%VVjln;NQx0rjN(ttYRq`OLs4Qoq-<@Tr>5NKcsKKXLu_ zy6$@YGx9|0nx=-Q0zu=(c;e3U=J2}e_xLX~J~I&JH@ovZ{UR|-t0-~1pOW@bd~T?vLF!e>EK(}^$;&Xt%>c)g4($$ ztQVfha-Vw)UcnyIN-IGvoV~e;pH$l5PYw0iH<}9t3yF_~7xrk*;T!o0mB*!PeeR8k zh2fgDRf4?HUTD@hp6bA(ryjDD`m(@^W|E^>vewqhL%*&^kd!tDyIIKDF;CzpU_%x-qTXE>F~!Bzq@1MeGo451y?oo|ec}+ujQhCpHee-TKKBg^n0$~k5xeiat z-%=s#^a6V`FMeNop}jfT+!MZ$pOl+Wy(T2?DvBANK)8tmPl%rcZNmCT>6m+UqG7!f zniJ;w`5)DW_(|nk6$mJU!W>_4%P(qaNZn*dl z7tdULbG8t)`Hu+kABR>x@oN6Stt^Z@TP+0te0k^k=jXpMI`+B}mRAcwoA-a=LqGk} zgX6EBW#O)C#_u@${@apI&EGeE>Mw#en&@}#vEFOc9lk_ZQ0JB#8C7t62|x#J-pXz$ zq;4`~`8`wxqqBh3Z)6&u)fUO$vF8YBzbUbG-$&@6aOcpuKd zx1X=!; z)7v+10Z@3}TL|U#s`ACE*Bstic`fKtTn+%bg3HczAJjkU94lVEqG7h+l*g5v1pxsl zxL%)$7>*muxI9BxQ*QE(;_^&5E(7%c3cfWPj>}Kp4BE`Vzi4kiobA9F}FQ^tu}=8)ZNdV-jzo|KzZ-lG{|c6pWW zd&zq|pHFQmqq5t^6pDE-ssc38<25&W%3IO@mg%{Ts*HSKiA@<|MQ+`g2-ToU=+BWx>VFt0yBKVpP4y+7k0$h|;<0_fRk@61snL zw=n#9_4|YW;!*N&t-)4*o`>+nD32U1$_5saZu|dG_xuAaW%-H!i>j?qe&YXkXJ_yr zA@SK6EhCZOm%h;LE_N<`cIp2%>0P-?pUwK;u~-<>^;SRK7cX9P`4@rkp7N8RdGM=1 zSbFiN-oN@aZGy)CSK3tRa-h_{5cCHttPy#tH$$*1x;$gAs;w1h_rL$1>g6r(v0$?y zuEsj(?|9Zhh;Px#-<#@d)w*0(VMPkxMwe&3(*K%Cf#%K@f;KaBd8Ydow3$6W!IN^E ziY~ilr4EGIx*YuTK=9vFt;@3}sc$*}s=L2us=r_Ok%?$iz27WUGznOvG%)oDE z;5Rey|Kk}@{t_G}_)AXpH0b2IVY4cgQ~k^TxQy4}!YoRJ|KtDUEn5oBNy`P55Y}5Z z`VTxrfA~HB>Hg4vvH4N`NxU<|aue^+i{63#^G=QHo!UQmkBj;FPwT}ywSV5J`S~yT zo_ApX{Ko$LdZYMG&Cffvf7q=4SF%6v)cm|t_6Pm>4SxNaE&ZR`KZxQZ`1|o!5+w28 ggs8q#_iMft{K{`%lb{^`JFYswe;=--rTmuvADgvpBLDyZ diff --git a/fpga/fpga_lf.v b/fpga/fpga_lf.v index 1df5394b6..da681321c 100644 --- a/fpga/fpga_lf.v +++ b/fpga/fpga_lf.v @@ -18,7 +18,7 @@ `define FPGA_MAJOR_MODE_LF_PASSTHRU 2 `define FPGA_MAJOR_MODE_LF_ADC 3 -// Options for LF_ADC +// Options for LF_READER `define FPGA_LF_ADC_READER_FIELD 1 // Options for LF_EDGE_DETECT @@ -50,32 +50,106 @@ module fpga_lf( // to the configuration bits, for use below. //----------------------------------------------------------------------------- +/* + Attempt to write up how its hooked up. Iceman 2020. + + Communication between ARM / FPGA is done inside armsrc/fpgaloader.c see: function FpgaSendCommand() + Send 16 bit command / data pair to FPGA + The bit format is: C3 C2 C1 C0 D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0 + where + C is 4bit command + D is 12bit data + + shift_reg receive this 16bit frame + + LF command + ---------- + shift_reg[15:12] == 4bit command + LF has three commands (FPGA_CMD_SET_CONFREG, FPGA_CMD_SET_DIVISOR, FPGA_CMD_SET_EDGE_DETECT_THRESHOLD) + Current commands uses only 2bits. We have room for up to 4bits of commands total (7). + + LF data + ------- + shift_reg[11:0] == 12bit data + lf data is divided into MAJOR MODES and configuration values. + + The major modes uses 3bits (0,1,2,3,7 | 000, 001, 010, 011, 111) + 000 FPGA_MAJOR_MODE_LF_READER = Act as LF reader (modulate) + 001 FPGA_MAJOR_MODE_LF_EDGE_DETECT = Simulate LF + 010 FPGA_MAJOR_MODE_LF_PASSTHRU = Passthrough mode, CROSS_LO line connected to SSP_DIN. SSP_DOUT logic level controls if we modulate / listening + 011 FPGA_MAJOR_MODE_LF_ADC = refactor hitag2, clear ADC sampling + 111 FPGA_MAJOR_MODE_OFF = turn off sampling. + + Each one of this major modes can have options. Currently these two major modes uses options. + - FPGA_MAJOR_MODE_LF_READER + - FPGA_MAJOR_MODE_LF_EDGE_DETECT + + FPGA_MAJOR_MODE_LF_READER + ------------------------------------- + lf_field = 1bit (FPGA_LF_ADC_READER_FIELD) + + You can send FPGA_CMD_SET_DIVISOR to set with FREQUENCY the fpga should sample at + divisor = 8bits shift_reg[7:0] + + FPGA_MAJOR_MODE_LF_EDGE_DETECT + ------------------------------------------ + lf_ed_toggle_mode = 1bits + lf_ed_threshold = 8bits threshold defaults to 127 + + You can send FPGA_CMD_SET_EDGE_DETECT_THRESHOLD to set a custom threshold + lf_ed_threshold = 8bits threshold value. + + conf_word 12bits + conf_word[7:5] = 3bit major mode. + conf_word[0] = 1bit lf_field + conf_word[1] = 1bit lf_ed_toggle_mode + conf_word[7:0] = 8bit divisor + conf_word[7:0] = 8bit threshold + +-----+--------- frame layout -------------------- +bit | 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +-----+------------------------------------------- +cmd | x x x x +major| x x x +opt | x x +divi | x x x x x x x x +thres| x x x x x x x x +-----+------------------------------------------- +*/ + reg [15:0] shift_reg; reg [7:0] divisor; -reg [8:0] conf_word; - -// threshold edge detect reg [7:0] lf_ed_threshold; +reg [11:0] conf_word; +wire [2:0] major_mode = conf_word[7:5]; +wire lf_field = conf_word[0]; +wire lf_ed_toggle_mode = conf_word[1]; + +// Handles cmd / data frame from ARM always @(posedge ncs) begin + // 4 bit command case (shift_reg[15:12]) `FPGA_CMD_SET_CONFREG: begin - conf_word <= shift_reg[8:0]; - if (shift_reg[8:6] == `FPGA_MAJOR_MODE_LF_EDGE_DETECT) + // 12 bit data + conf_word <= shift_reg[11:0]; + if (shift_reg[7:5] == `FPGA_MAJOR_MODE_LF_EDGE_DETECT) begin - lf_ed_threshold <= 127; // default threshold + lf_ed_threshold <= 127; // default threshold end end + `FPGA_CMD_SET_DIVISOR: - divisor <= shift_reg[7:0]; + divisor <= shift_reg[7:0]; // 8bits + `FPGA_CMD_SET_EDGE_DETECT_THRESHOLD: - lf_ed_threshold <= shift_reg[7:0]; + lf_ed_threshold <= shift_reg[7:0]; // 8 bits endcase end -// +// Receive 16bits of data from ARM here. always @(posedge spck) begin if (~ncs) @@ -85,12 +159,6 @@ begin end end -wire [2:0] major_mode = conf_word[8:6]; - -// For the low-frequency configuration: -wire lf_field = conf_word[0]; -wire lf_ed_toggle_mode = conf_word[1]; // for lo_edge_detect - //----------------------------------------------------------------------------- // And then we instantiate the modules corresponding to each of the FPGA's // major modes, and use muxes to connect the outputs of the active mode to @@ -142,7 +210,9 @@ lo_adc la( // 001 -- LF edge detect (generic) // 010 -- LF passthrough // 011 -- LF ADC (read/write) -// 110 -- FPGA_MAJOR_MODE_OFF_LF (rdv40 specific) +// 100 -- unused +// 101 -- unused +// 110 -- unused // 111 -- FPGA_MAJOR_MODE_OFF // 000 001 010 011 100 101 110 111 mux8 mux_ssp_clk (major_mode, ssp_clk, lr_ssp_clk, le_ssp_clk, 1'b0, la_ssp_clk, 1'b0, 1'b0, 1'b0, 1'b0); From e4bd3544d555126157f70b292a9ec7ef248b5090 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 12 Jan 2020 00:31:08 +0100 Subject: [PATCH 1424/1854] style --- fpga/fpga_hf.v | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/fpga/fpga_hf.v b/fpga/fpga_hf.v index 0dc26b6ec..e3ff6dafd 100644 --- a/fpga/fpga_hf.v +++ b/fpga/fpga_hf.v @@ -13,6 +13,8 @@ // iZsh , June 2014 //----------------------------------------------------------------------------- +`define FPGA_CMD_SET_CONFREG 1 + `include "hi_read_tx.v" `include "hi_read_rx_xcorr.v" `include "hi_simulate.v" @@ -48,7 +50,10 @@ reg [7:0] conf_word; always @(posedge ncs) begin case(shift_reg[15:12]) - 4'b0001: conf_word <= shift_reg[7:0]; // FPGA_CMD_SET_CONFREG + `FPGA_CMD_SET_CONFREG: + begin + conf_word <= shift_reg[7:0]; + end endcase end @@ -61,8 +66,7 @@ begin end end -wire [2:0] major_mode; -assign major_mode = conf_word[7:5]; +wire [2:0] major_mode = conf_word[7:5]; // For the high-frequency transmit configuration: modulation depth, either // 100% (just quite driving antenna, steady LOW), or shallower (tri-state @@ -72,8 +76,10 @@ wire hi_read_tx_shallow_modulation = conf_word[0]; // For the high-frequency receive correlator: frequency against which to // correlate. wire hi_read_rx_xcorr_848 = conf_word[0]; + // and whether to drive the coil (reader) or just short it (snooper) wire hi_read_rx_xcorr_snoop = conf_word[1]; + // divide subcarrier frequency by 4 wire hi_read_rx_xcorr_quarter = conf_word[2]; @@ -157,17 +163,17 @@ hi_flite hfl( // 110 -- none // 111 -- everything off -mux8 mux_ssp_clk (major_mode, ssp_clk, ht_ssp_clk, hrxc_ssp_clk, hs_ssp_clk, hisn_ssp_clk, he_ssp_clk, hfl_ssp_clk, 1'b0, 1'b0); -mux8 mux_ssp_din (major_mode, ssp_din, ht_ssp_din, hrxc_ssp_din, hs_ssp_din, hisn_ssp_din, he_ssp_din, hfl_ssp_din, 1'b0, 1'b0); -mux8 mux_ssp_frame (major_mode, ssp_frame, ht_ssp_frame, hrxc_ssp_frame, hs_ssp_frame, hisn_ssp_frame, he_ssp_frame, hfl_ssp_frame, 1'b0, 1'b0); -mux8 mux_pwr_oe1 (major_mode, pwr_oe1, ht_pwr_oe1, hrxc_pwr_oe1, hs_pwr_oe1, hisn_pwr_oe1, he_pwr_oe1, hfl_pwr_oe1, 1'b0, 1'b0); -mux8 mux_pwr_oe2 (major_mode, pwr_oe2, ht_pwr_oe2, hrxc_pwr_oe2, hs_pwr_oe2, hisn_pwr_oe2, he_pwr_oe2, hfl_pwr_oe2, 1'b0, 1'b0); -mux8 mux_pwr_oe3 (major_mode, pwr_oe3, ht_pwr_oe3, hrxc_pwr_oe3, hs_pwr_oe3, hisn_pwr_oe3, he_pwr_oe3, hfl_pwr_oe3, 1'b0, 1'b0); -mux8 mux_pwr_oe4 (major_mode, pwr_oe4, ht_pwr_oe4, hrxc_pwr_oe4, hs_pwr_oe4, hisn_pwr_oe4, he_pwr_oe4, hfl_pwr_oe4, 1'b0, 1'b0); -mux8 mux_pwr_lo (major_mode, pwr_lo, ht_pwr_lo, hrxc_pwr_lo, hs_pwr_lo, hisn_pwr_lo, he_pwr_lo, hfl_pwr_lo, 1'b0, 1'b0); -mux8 mux_pwr_hi (major_mode, pwr_hi, ht_pwr_hi, hrxc_pwr_hi, hs_pwr_hi, hisn_pwr_hi, he_pwr_hi, hfl_pwr_hi, 1'b0, 1'b0); -mux8 mux_adc_clk (major_mode, adc_clk, ht_adc_clk, hrxc_adc_clk, hs_adc_clk, hisn_adc_clk, he_adc_clk, hfl_adc_clk, 1'b0, 1'b0); -mux8 mux_dbg (major_mode, dbg, ht_dbg, hrxc_dbg, hs_dbg, hisn_dbg, he_dbg, hfl_dbg, 1'b0, 1'b0); +mux8 mux_ssp_clk (major_mode, ssp_clk, ht_ssp_clk, hrxc_ssp_clk, hs_ssp_clk, hisn_ssp_clk, he_ssp_clk, hfl_ssp_clk, 1'b0, 1'b0); +mux8 mux_ssp_din (major_mode, ssp_din, ht_ssp_din, hrxc_ssp_din, hs_ssp_din, hisn_ssp_din, he_ssp_din, hfl_ssp_din, 1'b0, 1'b0); +mux8 mux_ssp_frame (major_mode, ssp_frame, ht_ssp_frame, hrxc_ssp_frame, hs_ssp_frame, hisn_ssp_frame, he_ssp_frame, hfl_ssp_frame, 1'b0, 1'b0); +mux8 mux_pwr_oe1 (major_mode, pwr_oe1, ht_pwr_oe1, hrxc_pwr_oe1, hs_pwr_oe1, hisn_pwr_oe1, he_pwr_oe1, hfl_pwr_oe1, 1'b0, 1'b0); +mux8 mux_pwr_oe2 (major_mode, pwr_oe2, ht_pwr_oe2, hrxc_pwr_oe2, hs_pwr_oe2, hisn_pwr_oe2, he_pwr_oe2, hfl_pwr_oe2, 1'b0, 1'b0); +mux8 mux_pwr_oe3 (major_mode, pwr_oe3, ht_pwr_oe3, hrxc_pwr_oe3, hs_pwr_oe3, hisn_pwr_oe3, he_pwr_oe3, hfl_pwr_oe3, 1'b0, 1'b0); +mux8 mux_pwr_oe4 (major_mode, pwr_oe4, ht_pwr_oe4, hrxc_pwr_oe4, hs_pwr_oe4, hisn_pwr_oe4, he_pwr_oe4, hfl_pwr_oe4, 1'b0, 1'b0); +mux8 mux_pwr_lo (major_mode, pwr_lo, ht_pwr_lo, hrxc_pwr_lo, hs_pwr_lo, hisn_pwr_lo, he_pwr_lo, hfl_pwr_lo, 1'b0, 1'b0); +mux8 mux_pwr_hi (major_mode, pwr_hi, ht_pwr_hi, hrxc_pwr_hi, hs_pwr_hi, hisn_pwr_hi, he_pwr_hi, hfl_pwr_hi, 1'b0, 1'b0); +mux8 mux_adc_clk (major_mode, adc_clk, ht_adc_clk, hrxc_adc_clk, hs_adc_clk, hisn_adc_clk, he_adc_clk, hfl_adc_clk, 1'b0, 1'b0); +mux8 mux_dbg (major_mode, dbg, ht_dbg, hrxc_dbg, hs_dbg, hisn_dbg, he_dbg, hfl_dbg, 1'b0, 1'b0); // In all modes, let the ADC's outputs be enabled. assign adc_noe = 1'b0; From 0e96b8c8a28404e6090cdecbd02311175cbfc357 Mon Sep 17 00:00:00 2001 From: h4waii <30473690+h4waii@users.noreply.github.com> Date: Sun, 12 Jan 2020 13:46:20 +1300 Subject: [PATCH 1425/1854] Update termux_notes.md Add libsndfile dependency --- doc/termux_notes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/termux_notes.md b/doc/termux_notes.md index d86ec7f08..2d2147513 100644 --- a/doc/termux_notes.md +++ b/doc/termux_notes.md @@ -33,7 +33,7 @@ ref : https://github.com/Proxmark/proxmark3/wiki/android 1. Install [Termux](https://play.google.com/store/apps/details?id=com.termux) and start it 2. Run the following commands: ``` -pkg install make clang clang++ readline libc++ git tsu +pkg install make clang clang++ readline libc++ git tsu libsndfile git clone https://github.com/RfidResearchGroup/proxmark3.git ``` ### Building Proxmark3 client From 2e37c04a1579153e8d4cd05932e994883ca5a013 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 12 Jan 2020 15:33:06 +0100 Subject: [PATCH 1426/1854] Add: 'hf plot' - implement function from offical repo (piwi) --- armsrc/fpgaloader.c | 19 +++++++- armsrc/fpgaloader.h | 8 ++-- fpga/Makefile | 2 +- fpga/fpga_hf.bit | Bin 42175 -> 42175 bytes fpga/fpga_hf.v | 108 +++++++++++++++++++++++++++++++++++++------- fpga/fpga_lf.bit | Bin 42175 -> 42175 bytes fpga/hi_get_trace.v | 0 7 files changed, 115 insertions(+), 22 deletions(-) mode change 100755 => 100644 fpga/hi_get_trace.v diff --git a/armsrc/fpgaloader.c b/armsrc/fpgaloader.c index 87213df96..9b7e83470 100644 --- a/armsrc/fpgaloader.c +++ b/armsrc/fpgaloader.c @@ -400,8 +400,10 @@ static int bitparse_find_section(int bitstream_version, char section_name, uint3 void FpgaDownloadAndGo(int bitstream_version) { // check whether or not the bitstream is already loaded - if (downloaded_bitstream == bitstream_version) + if (downloaded_bitstream == bitstream_version) { + FpgaEnableTracing(); return; + } // Send waiting time extension request as this will take a while send_wtx(1500); @@ -437,6 +439,8 @@ void FpgaDownloadAndGo(int bitstream_version) { // Send a 16 bit command/data pair to the FPGA. // The bit format is: C3 C2 C1 C0 D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0 // where C is the 4 bit command and D is the 12 bit data +// +// @params cmd and v gets or over eachother. Take careful note of overlapping bits. //----------------------------------------------------------------------------- void FpgaSendCommand(uint16_t cmd, uint16_t v) { SetupSpi(SPI_FPGA_MODE); @@ -449,10 +453,21 @@ void FpgaSendCommand(uint16_t cmd, uint16_t v) { // vs. clone vs. etc.). This is now a special case of FpgaSendCommand() to // avoid changing this function's occurence everywhere in the source code. //----------------------------------------------------------------------------- -void FpgaWriteConfWord(uint8_t v) { +void FpgaWriteConfWord(uint16_t v) { FpgaSendCommand(FPGA_CMD_SET_CONFREG, v); } +//----------------------------------------------------------------------------- +// enable/disable FPGA internal tracing +//----------------------------------------------------------------------------- +void FpgaEnableTracing(void) { + FpgaSendCommand(FPGA_CMD_TRACE_ENABLE, 1); +} + +void FpgaDisableTracing(void) { + FpgaSendCommand(FPGA_CMD_TRACE_ENABLE, 0); +} + //----------------------------------------------------------------------------- // Set up the CMOS switches that mux the ADC: four switches, independently // closable, but should only close one at a time. Not an FPGA thing, but diff --git a/armsrc/fpgaloader.h b/armsrc/fpgaloader.h index 90d020333..5399db4ed 100644 --- a/armsrc/fpgaloader.h +++ b/armsrc/fpgaloader.h @@ -41,7 +41,7 @@ thres| x x x x x x x x */ // Definitions for the FPGA commands. -// HF / LF +// BOTH HF / LF #define FPGA_CMD_SET_CONFREG (1<<12) // C // LF @@ -67,7 +67,7 @@ thres| x x x x x x x x #define FPGA_MAJOR_MODE_HF_ISO18092 (5<<5) // D #define FPGA_MAJOR_MODE_HF_GET_TRACE (6<<5) // D -// BOTH +// BOTH HF / LF #define FPGA_MAJOR_MODE_OFF (7<<5) // D // Options for LF_READER @@ -107,7 +107,9 @@ thres| x x x x x x x x #define FPGA_HF_ISO18092_FLAG_READER 0x4 // 0100 enables antenna power, to act as a reader instead of tag void FpgaSendCommand(uint16_t cmd, uint16_t v); -void FpgaWriteConfWord(uint8_t v); +void FpgaWriteConfWord(uint16_t v); +void FpgaEnableTracing(void); +void FpgaDisableTracing(void); void FpgaDownloadAndGo(int bitstream_version); // void FpgaGatherVersion(int bitstream_version, char *dst, int len); void FpgaSetupSsc(void); diff --git a/fpga/Makefile b/fpga/Makefile index 8ea5d89f0..0d2bb1625 100644 --- a/fpga/Makefile +++ b/fpga/Makefile @@ -11,7 +11,7 @@ clean: $(Q)$(RM) *.map *.ngc *.xrpt *.pcf *.rbt *.bld *.mrp *.ngm *.unroutes *_summary.xml netlist.lst $(Q)$(RMDIR) *_auto_* xst -fpga_hf.ngc: fpga_hf.v fpga.ucf xst_hf.scr util.v hi_simulate.v hi_read_tx.v hi_read_rx_xcorr.v hi_iso14443a.v hi_sniffer.v hi_flite.v +fpga_hf.ngc: fpga_hf.v fpga.ucf xst_hf.scr util.v hi_simulate.v hi_read_tx.v hi_read_rx_xcorr.v hi_iso14443a.v hi_sniffer.v hi_flite.v hi_get_trace.v $(Q)$(RM) $@ $(info [-] XST $@) $(Q)$(XILINX_TOOLS_PREFIX)xst -ifn xst_hf.scr diff --git a/fpga/fpga_hf.bit b/fpga/fpga_hf.bit index ae66d510fa02ca3e7181036f0f8e2bf134ebf884..9a054eec60c9bb30acbe343f4c6685039cd9d260 100644 GIT binary patch literal 42175 zcma%jeS90$neIDh#%3(Z*2EvI8z77&#Y~LsD0WCf;>gF2w^xNwRLb68wzt2%N*cN@ zrL9Z5y(yR7J(itBw)3Hc&>A-Foj8V?kW$47Ap{yG#!%%0P}7u#Y)X~XP?M&`umPO! z`-~Jz-aqdCuJ(_eI>XGIbKduT-sgGWbEwEYp8Y=}X*rdBz5O4T|IfCs*S0^j{A&-a zto!!YR?-S`)PJub@PqHp2?XeC~N1&C9ad|#td&HnTMbW)=ZJ-%M|BppMtt_19RVg*UsUgNvV5r{73+jRe7wVt`wbgKHn>46@PlzEO- zv4c8D=W1N>lh6%Pg+s?*s#A_37EmJgbEx91_%qGBxn!i{Au)(=cNueZ^+;&QD%m4z zO6ECfX`gmA-jpuxlFzNUAm&>ekM~}tE41jCdzCyvndflr8TxZ&eXJyL!(VBvs$Oz! zll9gkYS41+^=gW4zbaWUi+ZVMJoLn{U+K1fV5wW2F1B7ge8M;&*TaDDOBZ}YY>(=J z=>zQNwB0f+qq6j9S0~jSloogvz{K#=r5Utw)2s*7W$dT4LCn%a-(Z_ZI{KLnNPap@L0T$gosJj*%e6~>FuPu%XtUJ=rW0g!N&3;a0!A$BEJ0o9-uTYfrE-(MW zui0GX=d`U^jkCh+TBwRI+^d;?>zKp3zVP!KtHSF2tb(56%fp7k*fjeww9i#lZtHJk1;ehs&Y5&bTi9B%MJ~{~`HFDkR=F^{UJJBgGiKHqYD{jSQ^KRGs>8!# zrfC?5SxI*6YQcH&xbZFC_Lbqe+Ip(tciq=gE>=rb5%nvKW&NwNVt}uwT3&gAeP8}2Ne`=W*~t2rK~EQ6a0Ns6 zYTMuE7o;F}$2&*03uIs1bU5o@hGvQ}T1YP8jL?|ApWIeiKshQcBA2zqk@YV_sWEzd z9^o+M5RVF7I88^7=rIvVOy`W@+e)31cf`k#CD>2mRpmDv;M^kj?r6UQDo_bB|o4y#BS4dLVkqa z6?1ggm`vIA8l1L;uh!>?;x9YH=DT!*?A_~MP2kQuJY;2v;n%k ztEinVV?U;uOy&3*-Tvl?W>GAydn5(#-fa2%KBq( zwral$4j&==)7->VHlfsu;zXH?{!I0j62C#nVfz;ImT|gFO)xFlzE~{ovApft%l2Q= z@>tfttb$YQ4QhzATC82Utb4~@9~Z$6<4yVvmYl<{ziKhzAvIR2n=e_nr`27hI>o4t zO4gN{S^tU^q?s9|v`P*x;@n6%0$NNnJ$~*~3Um1NGa3{gQ4?!1Xg}2)RCT35dq&h% zIRr~&*Me7kOurCAE7f(6wTlz!1(wk-?`r)s)y3W2dHhPyakWWbZuqlNiM|XB%sxb>y{{u9Lpc zyR9H$bw19nMH>DkvAVRASTPL|9h~0CUb|29`I$4oCMNxBMre&$o9+!oOX)|ks*ltQ zrC*`Kj@pQG)#haOIU&_W9jbrCtvS^A$CR*20-Z;N1^jYPlaIlo@dJL*WxdH-dk`r6 zSM3gKL;I3P>6+S*a;KK0vi@b`*Abd`|Ghem0u<_#zCqb1jTV$ z6)HbW9e@d^pB0NlTt8^2Y-wrd(mG3R#B(w>KUVRQ^=9*s>3&e|6IW?S6pt-wV*pmM zbccK~`>qUrMHVVIh{v|UMS@h^@tBE^4^mw;k6*9192E1oyYKd|D~CjVtADe6lyDJ2 z-ZGqhmr%a0AdgDly``mE{5o#7`?s+7s8e_jx_-*i*YQj8QFqwW>U^B73(n8^=qJ89%FweRcqlJc3us5?~R|`gp?6v6A zn4-QYnS24Uzm+=3&u`M$tJB(T`vHCd@pW#**Z6!d67Xwt)P=v)9CU7GuV>f7oc2C- zEA=Z~TjZH^L9gfjzOt{2LsIbmjd6MGI(|v39lHh(tk|f@qv8TJHs4B*jYc#0l_<;O z7oEUtxYo#3(IgGITte2Do#4T8c-&z{x4*|ISQvheJaP5RO^=8**6j(^V*9Cw>b5vd zm>jnVUAJa6G8gR*`7LK4I-K<{Q<}!MQ|I1EjpAAo^tP<#4jp1NgpO|`dFD@^XQy-EWLC>ny0=gnj-Eg_|?bPhO4aN zhuO_tU4%rjUH&TTDymhS-24_Yfy z#vW#Z1$aWvZSX;Eze{Z;N?=@wqA|&&8Y>iNNm3N}B~#&H$-afCIHJ6xc#+buo$451 z%axE#Iz;sx_G8Im`xYC&My16_oVfEU&WCM3-dHmw+-%MQ#QHz5O za$P*r#bhBObsVuShhL?9?WU^H&;oX&{a(}nZ(cew&`%_M$pjz;PEr20K}+pR&5u<)NryXz zgv&%sxJV$pJIWrUi!3438hK&%T_HNHkE=~I+wzXnqtv7q^WKDhx!C?o9=}F`R(rWC zE)UQJZEia*su4Vc_)DIDtu(s1!Hq3!ChdxOKpEI=^rBRUd-D7X_*HpZt9qR6@%@sj zTZ~lU9rR0@&DGQt{#Cl3&q}FZViiTt^KIPbU()kb8=iIlWPS+zqNLbUq+@f^pR)^ySK`J(k}2|`;5Lkex0W`n3ubMEq|Zh zqdAe1zAsdZLuSKwT`BqXEM6?o(iDSVIAidO9`b0a!m8Lh?g^;Cufohcs|BOfO(q9d zZ$)yehaJaTDrhy=m#La(SjzY^@QVSmBhIbJjqMA}&s=3a{3{e^uV;CaS@E8ZD6#C` zE%F1jO$_lFaqzE0xG;cUS^F`h0R!QkyS1_r<-*J$2eggQN1n#ETjO#bzxWBY{zlkg zm7J93!C}3+dQJ@zfXtD#AERJ8dyc#bbri6*AzUS5ru-oF@H(+!3jg|B7GJHm58lC4 z65Pif?abY=jr%P%(BhoLFSYO)6-+Z+_ykCem#fR!DRVW|Cc7WOjB(pmZTvbeOw%<1 ztLqZar=NR74(ji9G^YJmr|>U!#U7VE(#weR?g9B*95!~WWN+tn{zV0!($VN5U7e6G z(q(aH#Btdh1QBaGgD26&5_l-c0_HD?#RwF(H1?!zuMUe z+QW)0jLSudX7OK+%Y+&>}b_!nHS^+2n8vwWE@>cM_@|B`bG2gEd=L3-tp4UN>Yeg@gZK;V;a}vLN zfHuz=bssxN`$0yE5)PNL1F!-9rC-M{MIjS;lp0_oG}NUFRma%-$qyi#^e-x23A74W zOB2YNCTPeiwu#|cT5S2-Ws<`7{Ft{KhpN`Z+DiS*zihhH0XJSU+JZ8k)&3K=1R+_;lgbaW@!b^VZ6e1<$>SHjf@ zFE}mFPa{5`V@HtKuS>8Te!a~8!yd&6@5lNTt!bd=MJ(JU2L5HQPQ)HN*M3e%A`hE( zTvd*^8eenmDf5RfQ9`)t!Q*uMo@9Yv>*Zdo4*LM#Jlixb0t;SI8@8wy9rf9@NEdvb zkoO9eJO@dnjALrO<4j<8QXhcgF-1RIE2{Q{ma(^K4`56EVc}+aK~xQ>cfwY={jQMe z?>~t7ap~+R9i)XLfE$bc13>1VbK7*>g&+8ra!o^aF^=K(N5RwaedU8!>>_f z@Aa0SWQ9)Ja_A6v_T&$X{JhhHz#TI8#0*i%kxcrB^(J(YxvaVtdKoPPLI9p5~z zj(HByTHzlzRz;_?wWe-9@d(S|*PB|W&`+!T92=vZ|?uI?k7}BSEqw+YPVBlX<^~08f1ho*b1;cKPl*Hwg z%+AML@g+I_^+3E^xA{fs4dPj3xV+@t!1Tt!I^S=E+nj!Jd{42;uldo~Id&>FhkRL#;m+2Ll7p_&9$ zkm>Q*jxYCQ{lX}C22FkFOW(}+VyYQ>DcBCqa zHAQ|H@FsiPO9!*h8B}M0e>J52k2wE@{t(|b=$|eRF)Kc&(H)Y{X8lXOWgWX@dB3JN{~#64c1urkumCqx1&ihHHHLRXVCSz2^F^yqGSP*9(^>=kV)a zW8EE9+>t1~to|WcmvF>tytL2qEO!hza{8gcdxuwW#LRRT#4AfRTOQJ0B2Q9HL?hX? zP!(dG6lv}WfJMgPPe7WmgnxK%v|+>GI(2_Ggus$pDM3z<*yFS{z# zbP!?iRKaCC3|evmiANI^Tk>FGyZspOFM88hth$Ef`E(_|$OSuWA2}*!ce#=Xp4oe} zGrY&Do2%Zy{PdFUJ+6K-+{m|A&F%vVU&pUxL2`N~#A$0>n|45sb}+`Z4z(_h9CAh0 zzpRRF)Z6iG7K%sx>VDEK#~x;Dr*%T@n#8ZxiuWiPLs;$xl>7%Rv`S3*Aux_c;a8#i zWxgjZ{RmQ3(}>&Zyhhig`BWUgA+2ALAZTC6jQcI zwNLq-^b&Wc{|7tFokar3U=WXEEY~V#O1|{dZewdur zMXTW{&heI;=XOd68CF!I)rx;>&%@E{`k|no(&~dVmpf6j(>I8!bl)RvhPk$*)~sB` z#$jssh05Qc4n1=J-5M*A*L2}IY70e$>+Is95l zFUI;q&NzEdg)FvA{SkUca zvz)z0>sw}p9pGQe^SmysR!-3mX#!|f9Fr|zZhcK%%*h5X1BDT>^ZFrOX>AJ2r`Y@I zm9Ajqo~`VCx*(d`F^U|1ouguE;I5Q&Zsj3f%7I@#Ffw~wa!x-?t33rkD^ZG^PRujZ z9#${l7ZMWS>-ZHa7=ean!hV=CXMNZ5mZEU9+}A-5al^*kj9*k%JdLWahdbg7wLk4P zn{t-ZGgQ}n*QT6)Sb=G=0=(wmn2$l8#rHVv93aTmt&{p;o3u{-b-a!jSC+lcKk7yp z)Z~?@e>L*rzRo=V(kD3dLwil3W79eTxn_b75fDG89~wrmc{_58!ZF&6^r|1za=WtSb*+oQ+n1wJ!{i%R{4 zSk+NA939I(2l%Cb7M)|d+SoC=CSEZ8W6%$;iTP=NTOPl5mIJ?p8>~eA-!xqyyxRdk zcyjidSBF`|wjc1X&^_^nG}OXR>2jAh;y!^=IDjnenkcif@o;e3Ci-pQ4&nSKc3j(| zSA{m-=WGYUf?Gw{*{tS3v|h7wNN0ql^gZeW)XS^?dt^0%SGF@N>tA|#QtpiSFmd?H zKH<|GO3Tcyj)>oC^RuK9us>%IF|%9M@u|o_F45liocq}~Sg#%M_sZAbCFl%Y;K8^% zjeO&hv~a{7kjJ!30t7RT)yX_Z(k3AL>^5Ad0Revi{JGPeFVkCij{j_@)tb3SDBqx$ zgohkE5dk(r+`Bu?8tLC{kPfI7)&dkhlwpHrr#TN&kX=XuCOV9$%QEA##&R0f^W*dLgXrnxg*24^pGGw8E+I-)I9J;9mrQo;!?AjFZfMjLp9|7L?L>VZ^>C)4!nwLo+m|fh2kE6aFDQ=SV0x>`vTpHakC|X?=XJ z?^}Osw71+W?V_qJ>bzks<6qA9!eiOzSirC6g+HyHDE;rs3&K07KEn2E&^*(3uPV&p z*HMv(!ZLM7GwtRP0s7|9kfm6?x3ZI2zZk1{hOUZQVML@=%2l>otV`a$z;n0~QDPEbX+4$A1*YUgKg!(dL&4UTS_kqm@kh zmr}Bc>cZ#)>7rec6+A@1!4Ac5D{sA$J7%>#5XxRqoB*^(9F6za>Ue-&o^3-vF)iwsog3h~YKOfzt~Twe|Rx=AZ#QpT4n zE1m*&`*}<&^yx3s?VR3b->0A0W1luuSe{u6vwVO)vKEGm|Bv%&enDNpH^jXPKXf9< zom-to)-MbipiBC^4-n_y*DshTO2!cwFDSuwcb`0*jlFjNMv~XxXo#|HG!Fjd2mjKK zNyg^ZcdkqqTI@i$%0G=oLjKcnD_)EU=P>K$v61nO~O zdSkShI$@cJ>PII1tBf{M6@^mletkDpMbWjR(LhmwaJIAS`JtUK|0M6J2e+58%z)nr%aXVyhtue-O%JF-|Q;9vhnjdbr2eaZQ=L!l3HdsHq5g%6s%M{?Sn*s0lu9fXr5EYfYJHWn zL(b`kE0kUzOf=4P^(EM95ui_z+MpbC1x@#k)H^5!Yr9LP4v}@bOLbvuWND zH9_g@JVQU!d+l%5qG{;Z`m*U!c9eIhx>{7v&PdsJRhS$~jx{U6s;S%1o7FyG_YSJI zFw*htTJVau=t#UiV@1rML$F}P_I8;JhWs?98(vG;?1%vaD)Q!y2K>^N)~upqa3rkx8+aN8}e)kZRz+P zol?9!Cgh=PtVvy>faAW`m2Z=5Nta zhl}g{%f_#@;TM z(5tXszsauqSiwvBo7M}W_^f;r`)l`nbLr@-20bVO!ez?)vuld_mzdx|bvELbZt#Wl z9Rbt2pI)JRtsH)#9R+MFR-kR?kuZqZ z{q%ful}*H$WDgzq6#>H5!M|ivwS+BxF6mdsM4+l_046)ViUycBf&m3q2R5d1j># z_;sLaQ3rUXBfAzx!CflyLoWI0&C)nMcw-SoiFUJx1o+qW{zFr$RMrxzFyUxQyn?dV zvX9x#XwUt|I`zBx`d5$vtm>yuZuRMi){Y&;g)~hze0Pv>hHd4aX|p$|?edDO%@fE;msUkJ%cGYg>)A{=qv!jydfKdxqI~^JdyB*| zUp%B0TC|z_Fe6VMqFrIXiQ0rZiC^34Rj#M%-eG6>o6Rp!EZO-WKVmiQ@?W0RDh2%O z5?}avjBDIZpRAIE?BnbBfTgXQ8(+O(&b{;q-a_<+1Bu0kxm~Mcb^@*!PTyUh2=>lU-Are+m09 z8biY{8T19cWmGAZeD<0SXZ-F}YH&d`3f zggf_@8X`tD+_BcP50$LC6ylgZiC-2b%B9{!jH~^+9#R?G*#$dXT4b>PN&Fg+_QMCA z35NmLs^QbuAuK*iUpxVOPF%;YX{eQWkeQRWl_shJk}KwYR=Y$^+C9P>pTw^h5Y?O7 z+~b{>>6F@JxGm?|*#F?c$am82RTQzmnQNwmn5np9@=7|)=MfrxpHYv{!iP(=JpZa* ziSLONC7e4U*BqdkF~Ci)HY_+g9 zUGzitZ~Uov?fXS-Jx^+D2Wm%q|9&z*45=#LMUbXR){%J3v)1>^v7T3{(W;x1*AIVb z-;VdE$ztlZ#+rQi&|4nmd*o^Z8OnoauZ)Gyy=={EP&97pRFJ6Mq&-C zdkFO}k3esjN}Z?CcoWF?Z#+X6DQKhBEIZBEQvBY=QtfDZwBZg1-02iK5f^( zv=Z^lgLS?)W2vY)&iYQn*1l~Xa(8tV|I@{ z6tm4Nryu&I7wNWE=PAGz#?C{fcMY&!t)>;pQm+2xqUW_Ll#oh)4_XS15rwd*5PG|# zeA2%%_yx0Z3$KnfY*1V=CnifQ{7>~Se6xxE4NZn@s2&Kp-}a6VU*=8YZZskmW_+ho z8l~knT7{AK{+^+|DkYzf{#rDgagED`S$nqoH%^d;kTypM{zWL@>7fbo1d7dk|NN-Z zA$d5(OBD?XRkPC$4x3273$>C-{HhqhUp&A#YNcMihNJBeYHGw2Dbn)zHHs(!w2I4F z{m{MT)s^fW8sbWyY-Ii2kapT(kh?Rq3t~P7_#XQY6wB&1%Q^jUn?5EzOzVK}`UzU7 zxH`%rn5g<`u)|#atB4Lr-nbEQETlCs5_M2sMLp{p9#_xi^}|-`Cw=qunQPYZO+sIQ z;TV80s83V$!<*?qpel;&YpaAd2}7OcS;p6r9(S~}oPKyCy)U-wC9Bv0{(G@o_dinR z82(j!PNc4F$yxX=e(Ehh@3JMGdlF?2*aMvIj@$Uf_ET{p*MInTpV8~q9Mko`<)HSf zScBK@pI81MZXLiyPCwjAZ_liV(Ra)47bwhWu6FqZ|5UF%YBaNNX5$a~H)w<874$G9 zxL;`AuA(nFmeG&tTT~fgR@T4Jzo9)D_w^ZfMn6y6rJBB2dGwIj-B-7z(qN%%TpcVJ zpf?5Fe5>q_q5)p7{c7h|94C0tbPeV8!@mgI2ikPBranpJNa~Z}yPCuVu3S zRWK8o6f6_YzvHUZ`Y=3?dWt6nJo7O;^Uq(E@EJa2>xY{zNBOz2w@`?W3`1 z<8jA;gg)wy!2O1HL$3byqVIzK3T-?uO+d?Ss=8$YLgE!I7%4tpmh0d61*P@+Sh46F zq?1y83jOov*dcW&>>AATFCX1`RJYW*o~l%lgaLN3zfwnRZwM2f!!J(#+@}@Y%zWym zKC@cWVSZ6$#=4%zuhPCfV&)3<8->$HHi!q(`l`ZXku`CkLmOP0+x8OzsXjw{Qujzb zhWL#Q^`&yUWmwx6b5S0@66>zfBFp_Xp^u?o>_4*%uw4?z9=H*^|dFpRil+jN{BNbxXHfMaP&=U$1#v z@n7ZeOK|`K?D9|rCTbRUeu+J9t~RRfMow})KeYP~4~u%+n{3%|Ar+65d16Tu6@>p> z|Kf}Jy_)e&O7Kmsz*&f%6A=J4aa^=u{};`Zj9mQ-{EIq-C!%VlUC3$cnjzG?#5Rn=z&B6!&+puakkZ-~ zha754rjSQ4KlC)-MU(yW74Oj@9*Cf7{}ekE5As6jnVAXq%e^U&U)wP)LD+&fEs`!<3id*AMMQF~%h$gaC>!+I{puLI=-UvgHJ!`h zG8>SYxAm_$ob?N%U@42DTi&=6{cIiFKki(Nr*sNn-haX`v`Gly*Mx1@ac4V-PnSAt z_^$8e@vD$t7mH6XUA5$08WD?4TQ%ZfO{EtttzuZ*(=8kk>A|k2R({Y@Js4QMW_g!y#o8c4CnwB+eT&@wmOMl z6&tZ${lfKf=WV4YLcx9a_Q_+|2ULH|bv%z>r|D8Nh9kVE=`6<oq6wOF@Lh4hWNxeL;{G9b^(Bt;(WOW}2xO zT@4CopegI@a3MR`!~)JI<#%Jh2bc0w0TfG8tg`n9RE5Ch=hL$Y&RZM08)LWb=2LphaB*@Y@QH< zf5Dpwsv7Q-aE}IOM3m@LDOdlR_MDEkL#B$T4)?@GoYi@{rRpxnU||lwUZ*jwAzm_y z$$N`-$JeEu)%04tLHDoQs7>;(eOjhlBU65rn#8?k8LD{Hl%Ac=i=J?lPK9u&4sxPuS-nm7$YG$GNztg2ZF)QFG%dY!a#eTY|2L&|y zS?n;cAFLad7XZ=bCtQEc_aB}{i6qmlkv1kA2ebmK^9)Ti2eqmAHL70{^=+;vWm`Y2 zZ})3u)pT%kptWvOUO#+*UQ7eOGX3G)^F!ka&kf4@8xYkiVQiW`KbigwP3P)y&st4MS06S^wHs{2)z4>jVCE&Q3~N zXgf^Wjwb5O=LVg*{`pVnf)!jf`={PNi3{mq`@Q9M9@YFx`xO3FFbZ#KT4C?Y7KhA+ zHrGkHoZb=*E7u)&=Jqc`KO~o?c47b5Dc--p=qfd7kUVpXV|o4s{31WU>;7!p{8uW= z!96>;9&%`fQ}|c!mjGL6Sy3M+#$$0dpgn_okRML&Uq*gt%d;hR+lH-Yf`}C$LJlpf z)AIV^x~Sc)f#?TOml|8#ac`#n#cQYPhb&oHuV(Q5GSY3ouc8@%ZI>`{7*S6O$pv$pJW(7(Ztia8NO&9rU2xUzUb*;i2i+6^Vp`C!(+ zz`ty*fV%}cRW8wu))y1IFw$t&zwG|QtKxeD?g{Ta!iK4|>w>(W-VpQAzai)J z!=FU<>Qyf1M-*4O^r}{*h3|;p(yWnC`=q8vw3YU@R!L6I%4t&+!6A&o(rUWR!s-wL zC4M^ejUik*3D&zwSz)Q#a1spKz(rm^e2!08pzXH5pQL)rRVnv|umg0T>rVOhELI9M zD_;~Z+xLv21^ob@y$Px8rS=0S+>gs?3fS+Gv=fN)O(8^ezl638?oY`J=vOpn%+;6U zU&=!?Xw^jw!3@?*vyZ7;JHN@gt?kL;j~u!Bmml%~Qmg>-`IvmX8dq@K9;wm{pcJrGB^?M3_CDEY-`|%;gYJwel4cj2CbwVaN6IX#>=-5P- zYvb1yWwE%yx;vG@FLyf6zdmkRC+^T)tK@d|_o6{99+uDB0Nv_3C*ez{Tbf_K^ z3Jgj^gm4j!z7gn^>gZm8l$p6FS%Cg|rCMO-p>a@6*jdJ26GHX3#dP$~>lhZH|4{B3 z_VCy~yZ$9SyvJ^0>E(8vIvU7g6HR-I4z8Zp;Zo!lO2ro5hdni?DHIK+)pfEuiC=pK zcqPBr?zg!@dsm`VH=$fJ7yC+1LU4=N@8a4o^ux5U75Ehar(T#W*#dH%R6!61^7w_b z8Z`a9y86pL>M2CuhI?-pj#NU^!>y_F^>3)*QQ z>tAVUI{RtdI}jVYZ#tp=HM;B@o_AGKct64U8*27B_WtEzS|D82kMaIz)deGtJLD1R zk6Pe06tJcj+OGnB^|?O8xUgQAK?KoY`JQ~9|A7{dpf6>z{#7tWX)#y00!vmg(Cr9h z1fPbT+7<-T>-%n!)B5PQgwP!ZY^_mday25~%(|$S!*@!Nf8ZzR6++o7qMkq`StBy7 zCaBqoHWPa9b^o&U!_7iJ-Zu9xx851^CDpm5z;5QJqTu9n?DIGN%I_F(JtW`hdEIJ? z8w1Wq*t@hy%zDV1-~S~hDsBEHn=}@lr)^|Q&a{kCP%r6_bNuU1^bQ!b>&eFoqle6g z+u@9@cBE}XfX&sv{uX9a2U)`do3|h&Vk4N+t^1qriQ^Oq%^p{#e}ig1uf_{OJruh? zD*7$8TSru%f?u^%Mw!2KQ8(A`a+a@ zZV^c{X!v{b`@i0%zYI26|ClQKCw5INMxChh)6y%0O%HB7A)m?Shkep{c1T*xohf-# z`8CbALE#ha5OPS@l>UvhZqqKOD20^^k9~25qO1-XljHjN8zJO}*zv@jVRoDzS6A|0 zjg5#7Bo;*)E0x+aV~2jYp4UZsHhH|>_vU7IveZEijl~nFjDlm{GRnr zGX&es@@wJ{uj94loqE_z{^=CSa6WkV8j z%~6_H4xv7+CnH0ezblVl3kd!mS9h|c8f|Xag@pWq)bnIb4f3H@E{a?&4 zV4_Dgn}`{DNz{H5-c`JkpfK3E1QK#AN^u;x1F}!9v{z);%e>`0vya_y+kJXhBpb-2 z3DxeOcc*X2@h{ZB(1KoMtA*I6w-W1>;a@)Jz2n*S!ue6LeWL$7BKB>_#}GG6BufAw za>Us9B>%FihA>q{#HyQn$v}|{_wKpO;fa?j_n#8Y!cFnZ61N4s3FFE!}rM;Kw zGIq$`n)2rG%jBQYytuo|xl@BC%-#EdUq`f{hIp9D`YHN1=%p{|aje&)6s5YjbCCU+ ztrm529f|0tS=>SYhCl~fX_3N~s+-8KI(7CY-^T0oSUseNu)P+#R7!i-R7ISjo_~-Y z7qz;xja?%Y!c0dSU7f@)qK_-*mb%Td82yGCHFsdiQT|5?7DCB62E@RR-?B^nRJ&;e z`1P`#ENSl3@+tlY#U5ZDzi?uJ9-LT;Hg;RXx8+dm0%)x#_fTg}KaA5_)!zzQakId- zT*~mTJzAA;wzH2FZokW-A^pc4wdu+vo54}MTT!$O{Og5Rs}iW$rL+DODj%lD#6x41 zWez9pLx2Ue;cNu6f6O_hf4+xKjtBc5dPrWNU!`EY_^fjQqC|t~Hd(%Zo{hC4N(gzm zJ^>4D4*RyM(Dw%FW?%d*NML{h? zyGHDbcG&8$WKU0~e*^u8`WJ<>Mx7ui-nOG%9IUr5a{cq~vpa3MW*I`k6&1F+3_kb~ zb4M_WoPG%Y)zQG^l(P$PoQWHAl`H0=FxLHjDPq4Xvwu14k(^Z4h8(+2w+Ra-e4$Y+ zCi~}Y{jigC{`a6%2r@XIO=Ak}1{uM{F)3g_r?R3;;Or60hAn!6A@7Z25?+ed@Xu{( z$?1ph(?Ky5DeiNww$lTS^cx3pm+=X|(5UZ9u-9}HTUU0^!#x@QGNqeoFIDM9VFp3eyxnrNv$tu3=nzE{ zljld-`@cT!SfJPb&{?Yg#agTzA^BbQdC_1Nuaaxc!UoAL;K zjNn<4=p8PMWNs?BhZ?pEUxv zI*yAwwm82w*%OHV4cepDiZ7g5qtV8eD&~xM&Qq7R96(k&qUrX#aQ+5uCVxN;Fo7Z0 z=+2)yHDHUe^y>4+q?@*k8wZF!jsLnz`7W*^_=#b97tAid4@7E1Iq{&1( z#B4&quQsBVH{k4up3eH0DDdgnwydlDEyxemx`?_4!8|6abp-r$c1*2 z8~JsW?(!*ueB4Q;*Zqr%TM;FoHm99vu*4E|;9bG36~k&b@~PzK|My@5&mdY?`T&o~q_pD#*q zkS}$EMA5z89$XR`1qGTQRqqW7c|7)kL(?o2BcJG4x{^dP%Wg8SaLi+SB zWJ9d!Is2PU6vuP;wUbVAZIeqZSwKb&v_*FIsUbjHcR@lSsFXX2E8c#L>VI!xr9@TF39>UJB*{+_1ruVY$(-$TyV)YB5^l21}RX?m1nvqovwzxXYC_!VsXDmf-U z%74#xkIaU#fqylOxZCsib=VF&k}HMybQjeh!~i`-hZP75iK3i-xCQ;aiv{@C4BANB zEh7xvi7KWr+QFM5_Sh}{q_NuauTUR#%!sWO%TGJnN`ES??wA!pZ7ZiAzDAt~jd3GL zCDhrB{dx(9n>v%wHyZQ(8~fRt*6dBLh_s;RivjPpk}-Lo=S_9dI@h@=`k|QcG%|M= z;s!P{mlq?}0m!OpSbnYI;%a4-IaCA!+uwDkUF(k@{a%6T{WCO*XSJJad@Ro~iobZi*oCJBpP}1bwx1 zvtsTt^t)oEQ8tNRZ9rJahB4WLo)heEa>zB}gjsL6dh+_=dGsGPg*V@+_`izL?wvwOobYR}=Ue;EaLsvEd$s$(sS=y0`1 zAdUZk_EU*K0(>|d>x_cd%I&n$at0h9P-nW@Y74Zyq3kBt=_OO@UyU&1nb9I2TcCE) zQ&h=WN|{Twnv+MzvdZ!UO#-AzK~>T#{guHUakz!G!gX1#J~9N-Z;5`c?!-ju#;K? z_V;usOAPQYLK}dLdG=bdacIWXwCoZR?F-l0I)$EH z3svz`kI;pom8zg8XUSpLT(&DN?$jprd4c{7yPAXk-Zm{MEksW1L=lGozKOhkm_q;I zt#qq(Bih&s|H&#Im&Z}ZYohML5|E99L9eVE+{Cdao zju#KLVE?l4v=qlZe%hc1lIl>8p7pO-frS!3LV*}wHw`Vjqz;v;9X*B-nqHd2uW2Tj zrsr@Gj*SwyCsnkE)nXEiG}EHj@rzG8OTS9aNx2H;r|D8;D24EaGd8t_>AL5=x%$_T zz&RCZ_r*^bMfu>CaODxP3D{OT7+LJuEvnJ7-eQhH-!bu|Bv=kaTdeMo_nOI_keTV}8sVaK4uU#PbL;yL`n-hUwtLvpv< zi~-3g9MGB-w(yd}FA(5gh^jQ&=5Hl5B6>3XYs28IG@Ac&`1Ph9wfE+ro0oQnu{~<9 zqlEQ{nzVCo9>2Qv_m#ka>qF44s}@Lc8h-I6y_9gD>&@$jG|_UPd^RYIK=F>;g3|f~ z-B^f3F{dBe-LpX9ID4NCaa+8CE{X>4Hf&_h;nxE=`4+wdCM6&whHd>2jI6&M_3lah zD)2?S%RM%1jSBQIKtnsL;MA!dDaV#Pez|O&gd6t$WpEk0f4+b^xDl?IQvZsee`82T zdXQ#zqrwd&6H7+nXq3mV5&EndCmEiQKc#=R^QaTfPt{MX`H|uillWCxaNLfEkz2NS zXJ)nlgHF!GLB7D{sraR!|FB$DTbRvrbt48`h>89hzvD>xzATRF{Ob@NV_K zHFGy%mqe)OK45MpuHyVC(5`;&&|01X_XPh+t(hyWmbQh9!o&Ic7e5rQ|GxV%`6;>p zZsmI1S*;zasJA=njU0Z_1<}ZV-sgM>MahiVi1QD{0bVktf5W6?2ziuPqTBPME$wnH zC-iRs$nyNFlAcz-vxS@bEW)vez%OqM7XY#;^{)`55C4b}a1=_9k;?*={vuevZlMQn z3jg{US|CCXv%jGqt7xoEv7gY7xz|!xGGh|IZlqrcf7bJTVD)p>+6Wx8a-2|Y^e zPP>zG4!?eK|5~l;l=_iF)7R1+BkFz8a=y9}2fnq?b^XxpKSXPgWwb}j>F1C>9Ffm! zsEJiE#|acSbo*U;`L8%Q^|;y?b?Dn8zCKl9UOg^VYY6yL`Zo^qg~xCnh#wol0%uC* zE}5ufg(T*RH{2-=QSVtP%=U=#Z17aTF0hF#;%1^ksx zTQ=-mh2+11xyI!jetjLfANGWfmo^zMiP<7%p+RK>-A*bv8rSS^76o-0Dn}7;MjtKG z>MS+U;zR#Nja4b~_@%H;n4b{<4A@(MV{xWPXr#9cQ8=8{=QHO=F_<6Tjy>0Y;n$ad zQ4mgqj_2_!lMNEamDva;+?I13h=v>~oX4+m_HKN>t@k#D-=g`N&A<3jnnO!ddHgy( zhEjrV*B$r{BnuGS2)L7}h~@E1+hkUg8uzRtQRkDKgtLaClF^J4M^|M1%c>B(NAY~5 z?r9m&ageX<6dptGp$8AD@!?7Qsz@WXo*VGHoIBVNYks+Vbjch#sxP9YzXk4O{4^~k z=&FfP9GAaW4M9Lh=uWZo(hFjCU;g~V1S}KPJOn%t%+BSs(;UJq}9=x1L%dw;g^K(!FgYE%8m*%Ja@$I--sT;RJ@^kbNnlTHnv+V zRJ$OD0+%&mR3@G&FvOtxThufvC39mp| zn7B#SgcMww?n$@Vt>B~(*aXtjvI!*d{_eaaC-k)E?EcrxANJ?#Pj_bSz2E(Pulq?s z7&i&0cT+h$9)AcsKNjg&Zw0?ncNm)?JHW4piCOv}o*8?cfREa%38~_z$(uXtzx!uF>yJzfpwyIve_~Io!UzN5iM zeMJ2N;rv(joV^wQVNlKW0OMj!I{|<3rRQFg|3>MlWPEAcHF?*+v8{e7r0I*)j_NUR zK5QL}Yz(X(JyP15Y}j4#AHLCaOw{wcrUL)d^v50DpM!aF(*wuGF6VIOSNRWLrjPLO z6x=n3snbOM#*?L=$wZEQ75l5KL7E8lH&C`$O=yxJkxm$hq`UDi=|8+(Ym>NKfPVvL zCmRvbME*wK(&kG3#)IkG7{b%|zJMB}tng&ft}nVeTUV980rh}go*rooJ(&3HZis^c zMN!s2TwlcbWm~?GKd&Ea=;oK8Y}A(DmAbGWF5i(q#=6oM8Ot8P+eTO6K8ya<$RrkJF@=#*VCo_$$51Rw56|P zos0UtDw19Is%@&DzcEMOptW#4J8zEqkPbI^Dt|A~0s2^0UE|?b1KTg=v+zo_Q~hyn z{%et2fjj?JKtybDC4b}lsKVZz!x@&N>VAUaG2VNlepKm_^OaXkxj)PN4Pj=>rqf}xrC&>`xM77?-d$w|0FYJ`RD+IQ_`{jh_N#A}zfa zlZE01c)_qX!N#|v9=?xX&pwXOYA*6>?+J-tBJ%3&1fDF&<-_q04B2_D`wyOqE2 z5Pf6#VyGGL&&~0Yo7oq!?mR$c~5V0+?V?c1G@s<_(Ueu{T zGJ}a-V!bC{L4r-4y%O@3&QTnOSDjr8m%|XtJM!h!??qG*5tO6_|6#j;eC?sFvgXx~ z0`|O*p7#dw5C7GKG`(${$aH1lhI&JN+JZl-%Kkcl*Fnss7^`qnqR^@M4 z_?9T-B@6Xc8iOM-DFUWGEZV4UW8jm{I7|G3smSXL#E%th1=t**Mji!dICD{o9*}iTvN%p66A?T4NO5+n`hu3qV&ACX7k!|2Pu#UN z0JDp_ICP0UOrBp3RplR+*rd{F+*Jsa)k(IMmI;}EsCI@UGw^GpmDqIU7I;PO6fGnA z=hTaecTOgXp(^|9Dvr50f*ib;Fe%Bh-hs6`#F!Nt1IF3ojQUZu!HVZYgX$i(LBG(_ z2cZ_ulK53+f6e8)zA=AQ-~M`^PKX6Z!kLz{=x1U+@()AZ^s<5du*&`_(o+hS&04jY|I)a0Z{00w zjBiL@Xoa}vKa}yWCybWsbPMOdMx+c54$Oh$WfeibxQAbs{+L?ofq3f3d26-mAgAgk zGl`+B*k6x8P37tRW6tyy}_RZ)%vPsYo+6hgbP?7I=L7 z>nOdy4&hfTFhzSxYbRm&%;o=yylH@fZ-0GGY|FJ5VN!iY?$2cuK5eHv1f;2N$n@;5 zRpu_Ao4CE&{-SZ}AiNi+JVAd3eqkqhzzR`K+QToCj>269 zu{uaEQi8V^17Ua+7xAmg75ht~)yF7;Gi&Pq(DT-;EEM|_+DEO(UFGkX`(fSv=*+5YufqkYR6=#c=r)Uz9@Qt|GclW6rR)j zS;VrtY2^M;3!A*6dp;7J{QQk)Wt4#;KW{nSibO;$vK{z!a?=tPd98w9KQcaw(ZCE& z@_)?Wd}VQHCx3w>qvM-_y&isDLO;Rq0zD5Skv@Jz~5|_|BK{UZg9pcy8*dCjy6La1$-Q z{iPhxj;RZII2FLb;WF0qwm=)s)h;p-scCB(l>JOLK1(RkAjKT{#?&IiUOF~!ctIKJ z5}T4o(6{I*ae=hI?w6(HN+{lV7Ue9QVq2*)Vv;A*{Emt94kq-C4wR&0ujr|oFdNcs zkB4u6ZBtMoBoDoA%y?hhS`0rBTFhQ5TsDrD3VsjqVUew?;MZ@V zMMC?!2MXScaDB9n4`C1pMopFdbt6O=+cNwBIJRsj5FQ{T_nTLKOD!9Qd}b&AFkxX2 z2Y!JETQ~AIK!i{O(3w+RgZzV)xOX05Bf%sQD5)mu**BWSph%dvhU$Vx! zlMQu4uZj1Oe+WbDZN;AV(evJ;!#PAo_62UD55~GbSAS1c{L8UrM*IID!+9L&0JmYY zO|;65NVd##Nd`VE*!UuD zV!r(R!w2>6#c{$&`i*n6nd``w#r^}!WvY@tzl+`!o!Rhxx8ZqsB8#lI^Ht=}XWQ@d z>@VaWieHK6OxRxsnsA)07gMlPp8r}CiB;uq#Nh2Q!iB(Es3HrDcDZjLwytA8^x|Lr zi-qkiEJ4%5q1SN~ZD=ck5Rkat&Rn4WMm`{tW%!zQ6KW0Z)ltt}f6Pcug%*Lw9_Nx` z7#n!YgkDaMCQ$;HR&v#@g-gJTgHAulKctt%)8%C=Xa9$eI7oTq*1$Q)==g{kxuW{~ z7s}gO5t%1*l%9if60p~pfPA_5#gV^pLM-{r$kD*>`=(0^;*ovJ-_uVNmy{w0vGd#V zHP%?mRzMy@n_A=R%n&FkDg3j+#kw%_E(HX*%Ne0dNhlZl23KU3ICcxA$r8W zva03Cm)ZQ5fqF6=TO|siDr^d{^)vmkzV=r_t?E8UZ`l@ogr1q|5Lyb5gqYnF)MlJL zvAR={`zrYx2k3p^7xuct>|H5VX9eD&cZZP;H3mUTNx2Zl@x)6Kt)@aDb!1R zp^x=g5k%R!m(c#6kX=&@S?b61=ONGVFeW7uYK^G!FmaHX}h- zBH13No)i4`e8v8f`wJt?GE$7FWFfeTTnNDg46zACc7y!GHHwrkEUi|=#5?J`_@XO` z)E4HV9LP$Z(s@UX;~MY_We*98y#*liW2^^j1|<(N64{~T0)51qH8^#g0Tg7~Ar2oA zv`QDhgz*j{yieY!-&^;fwT;V|0v>f66vYtiO6T2&g9mAg0`sJGK&SEa=QTX4ENIr6 z1Ae`xIQNP^vSlOPWZfg^hxm8{4{cQsvY*hrJd&JU{NjzjrbFYmoFCqytfCKC_ohf` z2tj{ZWFUYwF%i?#1jI)-1kCBPQ0LRe|?`OC?&!VLn=R@f57B6zF7b| zY_j`d^4%wcNp&N2PO7Ea&qBT~w=gNF^l0MyiN@0&ekmCRnKM+YtAgRX*a+{nlaP*P zLSuCCizy8jc9Pa}&p}$$6U7T9kf9KLvEB@2FbG`U3-vd|c6yxZ7Y2su2rcGF+t|Zy zp{@ydGkpAdR(ut>-0<(AuRzT}8UP&H922)A@`8_F!2<*{#|jr(=7|?eox_pK0}mi? z2m4`F{7ar+zSO#75c=Ve0mXGK7E(bf?N$E6``M6S<=VySTtX^x8Id+rlp=s{)%h>j zU*ds%q14iP8nRe9v>3WE>X=!2vdVv`?%v$F?T#M=F66t*onsIgX_28$@>>=EAta8v zs8&E%KdNKj$Op=(IRQblD)@DPwi|d0qeU*`xpEo9A}gi1UX{Pm2S~ErVh^&Xk@$!B z*Kg_j`9vB%#!CE4McEB2HU;^5ns-duJZRx{*u$NjcPFauf3cdvo7C7ka&q?KBXb#Y|4CNhJ_OPd37NUPw*e|%-(SMSL5Eg^~ z$BM9oj1PuIAVrhrlR5^0an>yzUs?IJz3oJ4pzZ%r-V!Rx_Rc$a{7fVVV2San| z)#9V&$c*#L&NR(FER*^~J@PlyU$G@T(k(bjctzSkHeLOe#RDJW>-|vAxS;FTjFlI3i-;@#IT~oG?lzRg?lF zJ4Mz)OFLnfUHqbYsX}ZOST+o{FzT60T>?=CJ~CeMAIfa`O9%*yfDtyvyCjgof5@>h zy7)yqdywO{-?%`l-)<9^X~FHm!Jhrbm$Z6oz8pfLoqfTz$_@N_Bf0}brssO&S`ai0 zB5KXg+B`x9dSzG>Vvrt@_Xxpk7P3ge*o|lcMm3~}Y62&v(c(RGMoTEVNF$=)5kg~1Ot$zuOSN<^TUwEf)&*Tc z4RVnkZ*Gs0_g-OTIbCZ-Q^92pF$m&%;#Oly<8kM`b`Wu>CrBFwp-JLu9WA8b?;hsx z>@?vd$lEqh6%oW~7@_yL_u4^0Q~6tr&-oY@5ZCdjn02F)q3bB>KQo_g2KRxdUIfjc z9L)2E!Msmdgck4J(^@JA0}tmR)sz@vJ^IQC4Oq^4b;D|O=Zm12g(*Oo6^}4rZ#XT^ zGZ$1Pm0QMU>)M2p5;pPEVCQz5u$W;p?Mw$v5o6cs(Y#`cm68|=nmL;g?tAT2PknEU zL`ncnb*g%1+0TI9m?w|WZronW1~QF4kJ-FZyN<3EQBzroLAh2AQ;gEGg?sZ=qx6WZ z*&GW>!k9sjI~Q21Q~+FItp;fwJc+uNZ`2A`Fe9URJUa&hSBt%7G*&;LTrK*{OF;y# z&h3?icdwlT!L{NB^ZHnDS8#1^C5Y&*nzcFEg0RFMGtcKnMv2ungQ|c(J|S!py>vum=tJ_r9Vw11Y^3csvr=t27#|=O(k^QyH`K2 zmkZ}C>^6$rh@@D}a+Xrmd*+=yAjL{bQ@})^>5CwgLD&kig}e*kGD5v%Sj{OVOrHj! znS7XfHGHMAe?hFwYWbR?R?@5Gi-O90-j{7`)^>teW)s0ip5e2bHNT&h;2P^wg99Vc z?`doBW%k#NG`0jY+dl=upHtkCp=T8%APJ!|D$+c!#eE*VZ?zE<1M$Y;zSWJf;D7?c zY>XAqB3u@t{;aV=>sO+@KijxMi-PEpE!TqZcy!wdps{rh5p{?aL$aE*chxCsj+cz2 z213jvJQfNEmeUIB(p3F25PPljQ{nLJ<-u>r7Va_W%FW6gU_o#a5Fm-@WQ~Ikjh4sL z63gr|<`+g*xkPwXi@~j?RAD6UvCxv~tEPW3{fFrjrxQNUUqZD1I<)AghsPiLyd)-m zR!#UHU(mJe<=OA<*z-G^SWr#)JRkk1PyXiXPaQaXOcHlrcHoX^w(OheJOqz?!L5a&ZNI13$iPS!is<^nEKZS^C!s~~sVf0jBb(wTb zK{HUe(V2@1k*v(cU)Im5xa@oCU#>7PhCQj zEj4#kH)`O#Re&3K67c)wx#&x|xJyEvB4K zINeYN7)OFLL+X&H5-tz#cW~K(V*qqD!Cg#IYP7YvIp)V>jl0MrycWxSW@SKiaQWQ~t0DVEsldo+5K-7a{iOZ`bzT4OhV!|CmQcn>p=n`IwaPNh8UnOE@O-xyT8sYL# zzp34-%%zVDrR)-oAV{`&I)I!nsT%pXTupfQQdAe0Ws)+D!TOLx zQ$+~7#l=dl1t<%23x<{6(+KYN1B3w_OB9|#;2<$mh-@ybc?ripF3%vmdnw!%E2Sb< zXvxq3dDz6OaLI@*k^C+CEak;XusN~5PS27ZgB?{ZPJcAIj z7kMv7N$6J^KZNksp`(jc&AC7M&J)X?PKRT=Wiyak{u>wX|3qLp-#c~b!g`MgdPKb| zUwCF4jw=wr&h|mUvb(_#3CB$yF3%u(JeL1gT%HNX9zcK9zt`z-?6sWmd1m0U570K@ z^QZ-FGbPh?&G~{pz6W*U40S^aEpV^+JY<`KJvb<%8IX-E#SBfuG)Oe^uR=qd^mI+L zD73}3VRK%y-lxWCm?tVc%rPmcS=SOljj%NuvlgDxkFD+vFOY7Brqm9p1?r-e?a|?g za4%0Y#FI>5!zX7=%7i2cu+O858U%gR1Wkg_?dXr_aKb=XuJY1tn;RAz1JIo#A;Rft zk0gAax`Mh{8{=(8U7=<(jhSu6r`D+;(BkvxS`BP-d#67OJAD>Ldd*o*i*qa7ixrY_ z6kS#gR$va1MTtaBws`#*hL*%jahfyLs)JZgbF3g!h;E@d6V8g3{pk3{#cR|##SJOM zrg~&Br!~Gz@A3N~YQo_gon50FTTq-gEa6XWWw|~{R4zgBu>NV)$QD{bC@L9+h4EoY zc$dAw?xEQfwgNFEo8V%B#k7O)NTf0OH<7{YUm)Dyo)0X)4@r2kY)C?rBCM|O+N{r% zWjK|HddSE^gu{?!tU6L4jFkx_>AaM(YzS0^45M6uftLC9>aE;Q3!@)=D%PheVIepcgYITYSRi(rK|s;8QH2zbWQ9{Uk*q zWlOia40L=h0Tg23<8`>P-BTM{)ETneuvv`tbQrq}HArpZZF6>SShQK6A{?GEfGyR)C%j0z@Z)0B{cCS;P+2j4wzmXPcZ`LVFU-758&iv=h z2%H&#Gb3FhwQ#Ip|WdpY2~g^|SvAy{voE literal 42175 zcma&P4R}-6nJ)Ti?QLgUTeddFWSj)jW!X^S%0|eP5C`Oip{+tZMa}fwhndsUqfn;x zZ<*3PZpIN;bqz1tG*u)0Qwyj-XEBq$DE< zZOu>MzDu$t_dNHU=P=JR-4z>Yuf5jyz2EzO?^>lYZ#MsbM6QQu_Ln=p^3Z>6|8hge z#)rQ2*BcuD?n@hJJ-I_)Z3_PVBa4GU`VyI;U?{kVFJ81bL>s7#2b)9pG=Fjl{WZ~G z$1VJM_Iv;7%R!PZBDyW;imCrJf-deN+0qasNBwu2`unmV;q&5ucLhmMlA8<@S`?#d zDkYc1#eXJmMw_6A=}uW{yM|gurMk%}xk0bQTQX}WXWyh-blCA^wGf@!+{F9RT97)_ zJ<_^J3E9Zagf>7UZQF4kpDIiyIc8c~9cM|0GSY5=08Du_J z?t7d$dsu=RBj$FN$$gJI)yl~rw%L>v)MM&f1Zb;ljG6yP7wK@qch2}Jn@^_jeZlBvAuJ&L$&|E_JRjI-&Sj_NKF*IB zDQ1vOe(4X!N3g{3hr8}(n`MJ-w)llaFNJ=PsH$$V=N~x(@yaZ zDd>2pOQ+w`vb2Y-+MZuHqWq`y5w$qptace=@1sRo?F_x{`XqTfv}kEe{nk*)`_4%U z3Qx7hD6K#53Zxzg&~+J#d5)U(`T2^>+DThzmrTUiTwNpEF$A;p{Zu0j5wFa@XNUep zZk09MA8}W@b*F|K2CJka@<;sHG(#|{--=Y7qAtlDBgiVK*Wp=Qcxa#PAIC*ye%>eM zB#o0c-m0xNi<8uRV4JP^#kF+v{tA4O|E&mR;+P%F>u6bVgSU{nFm8yC&oW1~*DyEu zV^}ddLBqn6Ts2NtX(=wWI{La3e#E=;OULuSCG`zhWBfrQ$=;$vG$8y*cO5Poh1t(C zWU23|E(x&5sdlCN47-BA`k_dCo-J|x)U{}(ImTYf&xN782=|EkC_6{b`D@k~55}wL zAT>B<2RoiiBQ#RpN@)sFh19Y%X)pDAwrU&;DXbp;11&f2{qsJ=qlU%fNe$1u=jg-U z?{|&UC0Z`LmiBgONB(*KK*uN~yciBUkqSNR>F-*Ne>JQ=c_}|%%d89~5LPM*D3SFo zGqxhERG^s|b~->R~)>@_KUU*=q_SbaPX^!?isZHeL%TG_qtL!MA z&{T5~7Tzbdx8>EkaH}`jbuu4cerp$!5D3Ev)CuyjwI_reG6O-(%d(el8c=-gVkv(Tj3%#?!97NuzQFe>Jk|J*FOq zjCqf@UQ@&2T6cablYf?>>qsEp1FMeb<4cs>!oO;Yc_y``bPEyhIirQ-N3x~P^XK@A z+vUpcMxC#mQp3K9vQ(vq_R5XiC}l=|-iPMAKrafU3tMXxlOmKYe|{BJ zUyCe1?@4J>za=pf7#H{UBiCIQN3m$T-WT`su;zdBbYec z1K`N5%-lWF`VV@+sm&T!*mBWp)b6A!@we%a?yEMXyNF+6*y6fTgSFDdxipsI;fEzJ zHK~YSLr5t;ry4_+(&dwpRO>~4SPqbxVpI4f=1k(5o1DNH)(;Yh9Z0QG02JD|w!4U5 zN9Y~j8lG9?j`Pw{0~eg;WBkTimB%p&pc0GB7H zOxHHoSz~^C(O8-A3y*X^dq z9AwB%Mf^%rN(2_0`kERm!2-5F$h->C&S2~X{2IbsgojWk`0*Gmgg{#sJ55dfsFn)& zm8C0@6_sA6D~oXf0;G0cpX5ia+qM<)3#rl$0k-a{LtYIL()-8hY7$7D)Mnt4i0aR? zIkZ{SrOjdYHhZt1pEN4t1^il1lX92`5}FTb8P6j%pUm1J1!U9sb;nzDRfMD7o!UEe zRkk$t{ae=+`e>--Vei?l0)D-1pRmL2xAp&asdYjRMRK_O3g*j`tu5f!1SMuIBD0(E z)~!Q+l?wc9D-EcN0)D-Y8ElAR$U1d$Ulhp!7sLf}!Zd!(8U%JPQbSgMRWA}2TR=UM zuQZ-y)A%)K+&a-27Hj*>I_rd^Ubs2mIw3+L@cjaQxw`q)8sz!P+HvD5505WObzM|I z=3r80;8z-1A|N$RX)(+_ou1ee#IgMXba*bY< zEfc7O@3wGZd(UY%=@r?O37n}d;8(xcGOOYE17F=f*SE!Lh@*r!Lz~yttTtlt0)F+= z7HUX5(9t?q;9?Z_yh3q-93Dlqa}|TU>I8MA1Jc|dFXvrOz%i`{Pl?VF|6*fq5x@2@ z)bks>H_R4#)c{E0ndzi#-q~gs@#`YLE-+sy?G#-%5MQ?TE~4^wt1qM#@avQsm+)q_ z%oM(?U&O*Jxr}4{Ay}Z#;_fW46 z*i!M;gXC#S#`C$(&<&I#7>+7;alwuLHDuX(fK0>9Tx#e<T}u?_=B z_*i44kv4^2lRzS5^=ux$sL#O#K2g{-F^yk0_|IgM5vbaMCX zu?H-l%dj!_e=?r6jYPbFUsqUKh8&>q9(s?KIDs8qwec}R;CF*JyIUCV#XKPoxEGt zaCbG{m{8LdG3vk~mpGn~=3!eYNEIB~`1OKQbJ3UtB>i)uX5fx?_C+61_=35qwZOkF(mpj`smc;LAblC6$`6o9{EoS# zh+ogjKR6+I%KpS%^tv9B<+k?U=(N)$y>FWZ{K^=UJWPwa5ls`SP~4`S=abdppjUPk z_}AO=1cf6WRhM{CD~)93C{ybhi1yeN|C;kQJ0YGIfuvc-6yXJI;XPBRy>I&r z{IWrTfka(zD}Y|<-LAa@UKx(yV$C%Fvej!b8l}dWqlYYy)H16ljp1s<=`?zQ<+K1()@-*&ajndV>p1|Z2XI@}6I zkr=Y+{>tYyH(*qr)4skW7yvi}UM8LsFJqofx z#PBNjide)%@t>dfp*chBRl3_jIE3XbyGaBF@$lEhaK?K>oBAz@fVn;wnSZ}_k*>SK zX>Xl2ngl>Q7*_$mGJuH{V}VWP@?4Vfoat)T!N>$Me}R8JDtf8WF^(YDsS?6?9Q6;@ znDnPuW*WaZSN9|iimh z!fIU0>5oWyo}|V})#3Q0$iF~ORyf{{znJ1*&~3nOawuHDuQ%DN*5a&Z6TatFYRZW%c$Wx8jN!P4_hDS_54SF)1ou&Se-Xbf%B~s>kAQTkyoEf9Dc4YHTkUvQ_~0C5@+WyvCbodzz4(tBF8Mebe-IcuMs{Y8F; zf->+Ovw&YC0(oB563{%27H82q?V?af?d`vo_dD0`8D z5f8_!QjbHT{0QB$UWhCL?Gm?)`=aGz<|Rd(Bi?tlvC^2jXQ*Ucjp96JS<&rK)U#ci zZ=vp$AU*~BLhQI|go-bxD_A4Sf8nm8{aA;{8wLLLUEgL|ZyTG~-Od&pm*EwkdWO3E`Zay& zPKdV zpT}@Ig}vIapu0Wi|C=@b2e;xQ^=G795b7xM3WZeBd9{Du zP4;`|Xl(6>_Dj0zgd>a2b|KF{6Mh&qQh|SsvzM*r)t)D{1>y~aC+74idWG(R`lXdl z|FSfa6VZ{9)tCE|M3Km+dJBMFo*263xU)6I4 zE1`=<*PLNX_~XnM^(WbU>haZou0B~>I*ngHqZ6)rQLz(x<{RV_4awR;c1(oCr!3Py zr60NmjZ40xq8$360BniAxoR#XbkUTnz`txdXF%R}Q00Q3&MF6x@kwOpHfg%^@#Qb^ z>syH@h%8OLOevzG}@YuqXd)%4CC*=pUcs{z!%Bs`d`_8xB z(2D$v9zl?GXocwOn8ClSSK^E9KX04eq@Rkf;Lv-sbc*fc;Am6$ya+r zHXy7d6lcummUKy)^%}l-*#P5G>Kh}56**vmGto<|2hP;`j~|Bc17F}7|tc|FW@pNkRpD) zFF#C&IM50JjNF3hwgJ#sy)>;KrqTaWlDiReBQc{^K;X}%oQNT&@k>HKd_gwYK&z$H zEf?9wI^Y+C#0%yO{Cb7+ z4|a&3cETxddr?2k@JV`}P^$yKgwhYq^H{54h61?2zf^Sr4I~Mk(u+Lr*`ewDM0MD4 zC;tS$L}S$4ffVriq*JHZD2yG`@ipREkM`nnf||iq0;vMO0FcQreKuhh@at(M8^*k6YX3lQ zsIZD^zhWObz^`)!{F?K&I3Yp`zv=*6Ey5GU#YYSSe7&}SU%#V-98mZbVp|ECj09mx zL9ax@eIg%Uk&;mdsWM^!zwA!64wIES9^NMs)p+JyeONuG8~F!y%Y&tJq@tz%eqS9O zUg;A(PZs!B$v9K}FRXkrH)0f2zvZ%S5LA8X$w1qA6@pva*z9Y_ zE%zN?o1Mllsc*tG)kuGaoul6562}-~Zy|1d$IPr2o916iv+`m6unaggfUKXXcUbR0 zQRMl#fPRR~KOiub8S0`1j-RtpR|;s=n_{gl^*GQEH&WUaqHS_E3Osxd@`mEV&1w|W z_;p7v`=N%MeMOb=4j^eNA7+dAb&XER7I-1x85n)6#pr7XsrkKZ$zbBL`T7w4jYO|( zRBnxngo|MB5OkzNa6T9#?0o(`CrZ-1%cUe-b_&lN(6RiK4iLy-E-p;r*PLyXfMkl* z3weYZ4ReTHCOph%cg83Q#*+PhcF(XI?$%iqeYDC}`DrgL=<_?IyfZSAI|KoteyiOmhwit06rKH31R$fnpw=cn6hRd`XY=ue{+B{40)CCDi*5k) z4F`OA6hJnXe?LPdA27fcd2L`pnwq88p8bIZ<<0RdEAp>|LMsRHb%WtTnz71%*Aa1! z|B-3@a?n2nTB-imo48nb!Cc2~%FT&Ikow#m7$^Qjs#JZ5_#)=OMit1KHS87YOb0Gw zP9MzA`^20fI;qg}+1Y91B;6;y6TXSo(_)3~8PvX!pRWk1u4{|6)|ss?!WLlbJbESQ zFUK`V%<8ucE2rc{kuwMBgk1jRwqz~3OESE=?fF&5^S`C|7u*_A@UL;|5se*yn~Sci zSci$7EaS4&_vHIui{MybSLks+a`=;MoFAHngrADPl%G?NK8K#8hLw0fze2(fi0W!K zO1mf!8&X=F`WhPX#E^}{s8UcKoWeRpqE@COBx+gcf6XnVci0=KWz0K<8tEgpLZNVx zf1$k0LBQ8=(JVaBd#y{R){7Y8h_2!>voH|8wR97$a zstA1^&)lAm3qK9AtFEy4Y!WHux@-CISD#lGPHq$@^Yi7mY{F|H?=daI(otN<+Khz3 z!15OLL)77b;}OLBq`FAq;$3~1YImSUI+=UT;9naRZ23)&QnpJX&`MR_uz+y|{Sf{Q znOn~>Kmab7DJsv=3ouTY9r1L2PW?tW{*qjgLDh7PfM0dq`?WXek8*Lw8*!b?$Cokh z$2M|;gV;fO=U9h3w08%uw}Fw#Y5Wo;H~CH3l0iO1Bg|>x5T=@u@LR@#XjA$R{2St6 zb;E1sYK&`(Xpn}eoGX6A5pn-XdpIAbL_6t#z$bt;jwEujWfM(gVp)PZ)>EHv#vWJ&j)*6{4jPgA>$W2T(|{i{hWiciu!VsYIyf zG4z}qs<0rJKr$H4sC5`ZA}-?U4*V(mCS7xdoR1~7A=G|YKgr6AuIrTZHIbH!W#!+< z=lL9LtssQVIrWL~MvM6M8XN*mvh9BDLAn@gaw;;l@E?kn)j;Zkes}?q;&c4lfjON) zUn()M`^!l9jS&PrjOCb%?Z2?c{7d3njO{D^8A=xWUzL$9V?VrNq*-(2W6}@) z<^I04f5*ZOwvHM3_=*@rFGiPs8h(;jY;cZWd-iGxx<<{%16DyloR@-rc;9HBqaA_4 z@*jR>UUGdC7cIxVzbNvr3&4w9e=tMW^w60Kr5oRZQwAd~=!g9l{8~-|ZDsuc?Q&52 z?a&eLc6qk4pdW6hxKopfY$|O%1g^v%^pfq%WOf8?y_SahcL3jO!v%cF~Kpttprb5F+%{#A03Udc4Y zzA&b}4&b;?c*e9PAY$k{yjj!_Q9eoEV#tOWV~l}z$=U6QucKsC%VgvP9e;0*!rJx^<(utL!n18$WG~F+o zqn}NhItqr6*w$av5BH!FUMjphyWW=9^{^=0C}=Z5@$%D*}WMomv?8Pu^@yA@<@&Th$v zj1&w-QMC?jSH6X0es)2%F=#Aoy~6@Q*lv7WLRgr=zh01gGiKU-JB`a=rY&NAQGciN zUf#CuGxbb;4g80oUF;~Ti`sE^CK9H0N83g>;STwiWY_W1SnekH4_}qAe@u3r6{qCl zSjE)`!gNdiG3~jk75LXqdcxW@3O~u1Ge|W_<1gSXJYv4Y6LvIYH64~Q<;g$!ty zU-lDv(1}VPmC5=GWyvD{(oqd^?oTlv>fUy8TTC(tq!RZ`>xX3U*`1Vp)buF)(}AEH+GN(6quN;v!><5Cg7?&r`v9e*t=CzT+z`zogjza#Lrr#x~kp@8+9j z&A8FdDqFY6T?6PY74XYLFIvEzN;4oGY994)P3;Q^N+8;F|7+fU`pEi;gX#jtQ46#S zLLv~YWe^iLmXEKYl6U#b?V)3VWN)tjlaw8Jfb{Z2y??wN@=8{ z$iM!X9&>6lkPYu9Wu8PmuZY-u8~m$?Uo!4+>90nw7PdnNQ>jeOb?QYG`d>dvo=omT z+iSOw|Ml0h2Q`xWJFHIhNS^|!I#NW#vlFpnsr6i4lJo9n{CQgx^usZ> zq*S@(p(qycOZC5e(R#~W!a9jZBT%=OG0v+Xfd7;YCTUh8%>=O#E8tDAm|K!J3UXX=$$i#h##AX-u%0`XPgI+X&eZ z3B*C(AkpP;js^KA__e6j9Yt38N1C5bL;wL>M2%$x;|2V>Q~WW$0{%nuPI^hgE_jD_ zJN;aycp#z`@axC&y1=;96o9b2>FvJjybp{Fb<{Nfq7t;!(@mL*GvHtFZ)7UcWzEJb zavw)yrGQ`kiv2mpLu^bz(kSY~YKe#=<8$t*o)l3Me^u+al{N7oVh|UrfoL^)S*(a( z$CW>-19j9m?Gw4N3qqXovS*6^!>8meIh?IHtc_dO1^9*3VyNpvR(Yz}|GG#YR)=4~ zxZW}_Uk*f`AL`e|a!-X_#ILNp1$%?%*s2@!Z^j}ADdmguBsFqO9IXzjIqlT{jt&E; zV0n6nLuYfaEu~TRf{6Kd#Q8M;Qq~S&L6Uty|5S~823R}w9B(x62`8bxN9l+AXh5Zl zQF@Y;5pjVB;|fqU-8qe4s1I*ZNXelS)&Hi%w3N0Hc?|l7ZITvM-(%0q;vT3O8Nk+m zsCzolCj$SH$ovKW#;;-9z;=MF8I;)gV0$OEFnuHe&@=Xbz0GDf+vPl11ZfKlw;pnP8v)AT5oRwG?YHaq@>Gw@517{`nXE z9VY`^OIQOG?1XHXv3^0z1%T`|tZ4iZ^Nv*BVmTG`3?{CHAh_lHq6)|g_;re2c7>g` zl&18$unY{Lp?2a_v*@$6_wstL+W++%2WnvlI|CqV5XM+*HFcNNNHfM>%j+A;KflEe zoCkhg18gnoFe21N|4W}-9ad!_@JrQEX)Q%Jc$LZc{aPLL+ehWHvYO2y^%a2VuU-rmRaCmX9?Sg zVnC~#bQ*w&e||d*A^2pXh+p5MZB#1~QTFex-4Vps=PIlCW*3Z7v1v|3v|nIpN${`N zVfI)=*ozkw+blmJ;tKrB(ZQf=jJc(wQi-UBL>Sw9xAr+*7COHS(HDh%f>fuds6`xFLvoo+vcq*vfyS$d_ji9DCOuFw^usne4| z&406OvGj};@oPOBkh??fk=D135wTku<4AEw^;+p3EAX!pzf8nHyVM#xWMPfTf$?0` z6ag0GbDg1cQq094WKK@vMoltmq30spFy!asi-2Dkm*YvHmbk9x<4Y|h3Rp${mDQ2n zg*U5>p+0P(MUIAjqwEC&_!jUht89m;EVL!Yt(qp@c3BImPh#aUT;$?HTJPF@oN;5s zJwS)6ecbqv1zd`i7=u*6uTiI~niEo-EZfU{qB{6pNw`Op)qT2vU)w~lYk;FH98iL! z4w)`c*HadEu&}4`Yt{w&IR!7Ht$cv4iIm)yGIzHoMCj4-%%9*F3(G}sU@mUewX`;* zKv=F*OLnGz-lpFLLvow)16&isjyGl2(1d`W&90rnzxo{bQqI+Eki$K&&1Y8y&=~;= zzg6U45vxnsLtqUa6cv04^xhclhJXY7+LVtkzVc2$Knix^VJ0$B z8p+S8^3Qj1-W>?;E*IBhK>_@Vto|)MPXXTbAXYT~h!K<%qHQ~B z>k=@Y zj)S1q!UcZ@>k!Sd0)CYkovR@&2HiS!ewwc|t6=tcQYnf>|3>+GdQT2>;Fpi(jED)7 z(S$Kfff@SYJNngQEzul)-Kz-8PVFs>0ulFmq5tK2i=lcKo+$f!dY?j~PZj^@!wS#$ zi}-axCZawvWTj1sA-rA!kSRt6=lL}M`qWFg(*O)B^eNXaipB1-*z5G1{*cvO>z^_~S4e1*6+^>b({$cw)9Q8c*Ny(;h)bmb0ALjaB zw5!`#1zXf}Rs)$?Y&Pt!t{HU;_Fn!ytNvFCY^z69R=Ez+-;&wElCf@}UiCU;b*{$F zt6rgD;sf^*D|bD)G7#(y-YF>|d@;9G^dBA(*C=S0TV@0F`K2$d&93@a_OcjGco6UT z-;(%?%Pg!{NbRCjq!_l1wgh-((mMmcZm?7KzEqo|EtMY`Xz*df6nT|{G+Xq~f0GiA z`Gz2`1?Z&nlRPXE_s&F*O z@^l~Jo~&_>R{RNmeMqm!#pH2-R@gpo0ovYF^#(P7e~AwDQ;wC9z1#;)l=&zk8;uA0 z85+&9mP1eA`MF4!z)5KEh@X&)CHW2TlyMp&ziVN2e4vx(zGu$AGKFY{jC1OTVqhlY z@1f&dFW?MG<$L`!=RN-7e)wd@wdHhL+?NEmI!+VLee28nHJQIB;~LR#(hHzeu=T!| zucIKix$fEE9WyskO#K%88+5${Htazy;5sSb>wZr2^OtF{0mM)0T-}p)dE{X}koNeQ zhv4rWFh*MID87z$lpiVL*BaU@ebf$@7b#w85c>>ENqm@n7;(!ZXaam#SM7|I&ZY zTSNt9UV(aJwKwfb(Fe3bP43ujF?EmHzkG~R5~B#vzo7w&W$dR9Wk}Yk+``p8=~*Mx zt)un}BEGsP=m2V~=m6C$^GAU@xqBpipFJ)Yo`=HuS%B|+kVjU@58#>c$y9trs!s6E z$dF^)%hozwNj`2YWZrHF9hc$Tnfe~(pFbUYekcIa$&S+j8OW5~K{xyNZTHONU(lMW zsE;&hP0$kZidERZT(X?75v;(!##`T@VU^VvNEBwd3pydg?HgzEFTFG4Q*L?Sm-LB9 z|Lm`bH!2s!>UUyA<=(Txubw(z>q4AC!5-(e;GXJc%6SwE_%+{h!9Tw+3Vh#8yP`&v zZB#->tbPXnYKN=K$IB8X@T(IAa2oLi=ggn*ubb|VWVoXOT!yX+r5|cnboe)-YtMFF zD9y!Af5|!a?>hRqXLtWWzG64ELpEH(lo1jB$7%jW8A~!>mA{+Sumr^+8zQXGUnbOb z)BeLxsVW!C&$@F|bSkLL3yF=QI>jnox!IdX z3zSNPRzgl6CH0rWzo9Qzur;pdjuU~Ap2JHcu>TADkg>#| zAKH`_Ar_Dt7piRb$W@#seW9wh$BO;0W~#u7@?Suw_<5=waA&l2bTm=>9V4TyQQxBQ z>oaw(7`Ob(*0>3_!}Tc9%W;v(pvUUYC@lk}KT<3>GS?aJ8>>)7XA2ji||_h(ro zf6owsC3V&Y1Dmuv5e~a!746_n%D+**NprK@+A!t}mcl>JfmSF2p+{BNxcDk9cPa|_ z1^)*9vAgMfU=sQvcw7wUcpN48H*gnAVWQ8zv}&50~h z8skDabq^?TEI!7zL>m}B0d%Rc$Ex1NNS`IdsXC_ulgrutnEpU8kzmz&P~9^$XOOb} z_Yt}b6V`PV7lR;TFN)>ko}FEv$mhc(z0a@G0`jJ6)wqBK1GE3NZgM4d)+f6%`FxnP zt|%R#2Hmb^*DWL&NIEwqPKuC})jC&m^;=T^O6fClfPhwh*Wu2_*UVikL(iY|js5vZ zk$*MnJ;zW(rq=l7VJuP9Bshpe`l{Uh%+BXSr62CXa4=s=NQ425e;Q|5&;Xf;FZE0K zE%@ib`U!c=k0KeVK+VN9ETqPiCiC-U&r@evfOe_2m%2b{GzLUlLFG=7f5Am5TVlYk zBXTV@rM;KCmMifpf%(ej=Sy1e;Rzcvi4hj2pKSMKANU$uE)LV8Bu1Lezi0RlDWwz` zV%t>DWwcjqsK>*1V|Fgj%EcG_^O2E6qhqMOZ>SF)aG3yzSfk8+PfU$Vz<)RyU!L)t z()Q5H)N~AsEkL(A!YX4I{D(Q8UK*v*4fUuhy@M}H2m&B1Mf^gx$#_4lo#MY-0KyW~ zHZq*NBm*h%IIeyxU4ks(poBQudPBb2S__#Kpb2H*yV$Y2l!UrxykreY4hfgoDf%|q zlUk7BL@BcE>Lu}I`T63mX3^dMx0g(K`2>jA+vcXyy9xW36&5VFa^C~}kULf&jor$p z#4nAYdY(2qPL`b6|LS+&sDd3i@F`>Q%UlJD8_#OM6Ymcr-pwJZJG8{*Knm`8=lFHcxfdoOff} zGVsfvao>k$KAL~#Og_HgKjd8*xQ4cWC;J^G=2p}zDJGgamLFy9WoZEJU^eF!9B>~ zFXiVH`zuLV(EUn_%YlO8U%T3&F;*4)htN09QkdF?@Kz_~QXIqqAe*qmyv;875AS%L zuv=MptAJmZ;N|O6K=uZKk@Xk&S4nQyhVY(&2l$gz8v`gnuNy)lQcjgzT&VM-uoupS z9T|Drg~i4JWV;CmNuAD*-6(kpj~Wngf{nWH%<3SHD$0qUR{S+r?t7}|JcS`Q3bZXS zc0I>EaZfcmHK`frZ{YO;iSp-kDZ3X6;QT=x+C)Ad`d!Lijx>mSj7xM>pr4{91^g=o z{K~CEgkWzHC<|L6&dr-2?^rAM*VrzM2MiNgM`c|SC+i*O}U$~gUwVSqLg{N^Ec2>S1zXNtYVYkb{^A|%XJrB55SSADiF%ypv$@`ZpnKb zK)@3EhwmPA0vWBEPP=k0f=vFm(Esx6s{{R)?Blf8S>hz1_s)fJbj-Xm9bXbT^DtlF z+}Rm#tT`kWsHIh>srnHADl;8l2Hdk;U>Spd(FP|G#05?l6j-zc{tRG|m09i(hs`q1qf2lNRLN-+Rr7%|+IaUa`C=2@G70|AG2vpqYq9X^ie%TA z&ec6>*IfqM4NsQO*SiE**f-D^jNZSpbS7}9FTvz0iP86UvNGI)%hC+O04CwTou3{E(~w3 z2+rt#!L0$d)uCMz9|;_sl3|n3dqKqDpD&H6XC5lKK`-mM?1$q!oDgdI8k{JFj+mT* zUq6sts;y(8{@F}`n<)D{9nc}dcK~;C-;?*x1KKvRJ8845wR`Z)bg;7_^ZiY}V*d-z zoP(_h!K^3^gNaCr8ksu~FW^@{VK=4RW}DUQWGW;dAL`2Ggk1^w{LW>4A{MkV44>+q5C?J7~b z8vkOZe`A5(!*_#rEm*>O5mw+|SLmm-NOh$P{A+>A{4un><|3>XIc1+O{S`eY8dS54 zxzuY$|7$%ZxNOaujr~c67}wIy`}moLcx{}o)W7Vo5rtx z%-0EfvFfKRMFH#;IDg}7^f>*$qHS!|OVjvuz7nbt!GCCr1dbL3?c!=>s!s~|^%jA4 zeJ)bPbk^yD=ie$-IRQGhReF31zu@1y-Ukb1T$Iq=F_&2Pyv5d-P7k5o^SRlG< zA0im!T;9jDlll1amsD5c*o~x-sa)pz;CO?b$gpO5f@aH#3>J-0?-~2QSZ8N@dk<$G zv3D%+8l>q80rly!IT!cj^O%d=ok%R8Fje$4Yh-uCD(12+biUR7H8zp|9<~4LXNh}x z`6l=e56Tt!K0cg;nYEj0-(%{ha{j}wZwR~Aa=_MA0CYtPMe=plBKrP>fAuA2$8ci6 zQt_&+jhPcJI6Bn%hgY?Neu(n{I%VU1e ze6y%IW_I|_@q@U zaSRdxtaou3>A}&&VXKiF`&)T_E|h;BEOMovkbk!7+@)}tz-|bh(y928s1Jcw5@F@X zJVRGUeCgP{MySJS3cuh#yn={BRv)X(T{y0+KDEQBfM35RsJm@wsYB-NZt_6p#RfNO z;@;Nc`BADJ?6a^>Y5@Vrwn4zTMSYHsn=i$S{Vzll9|PukD4}x&TQDNd!lZN-@#`r# zRR*GFA|7Cg>LJ4STx2HprvSUB`(Jb3rWZ$>u6X^XU%<{(8Q8h%q7J9!5^ti2Uq|r! zpk1KA*#C9UC5!rT)UCgaZiDNg{`M$!=uIt_A%qR&VcP+ z$4=AJPE7`!#K_NS#DLonyK!M##YQk4xQvZp(ce;Vn|H?kv4gW?A=iA@{+ho|k^L`jGYkp$R_r&Q)%Xb40L!Lb;!aKZgYdIZ2dMAqh!}BV>2)n(|>le6?T?z}1R-tGw z@UM61L^8FyJgGH8KMXs_t4iPkD9rHBe+Ajt*OBONy-n{;BR?yWg+x7xCf7{;kbKdy zoW{sE3e;Lyy)})iaZdri)E-RO4wFo`P!=kVHcBW?1R7ye@umFp$Q!&|q7S2FLj>9d zQu~*&4vYSI`bfw5QBei8%IA>P-eOl<@yx~j%fPQ=)bjPuTC0|*dlUpHB`0?=tsmyj z?`<6MOUA7cy-^jw8G?Q&aWUQhDjCJt15vky`Vg{)z+B*&3Ce)dJUdiwfq#SJZNM9k z+;WI2RPS%x0EkB(m^H({K_}oOthifSV5#T%Sid&T)O+rm(f=A$+hBz^^#EF9EO%_w zXztQeYclcfs3kSg)Uu(_|cz`vHku3W3Or8M*BKZoJiY=S-UnorK` ze?{20cPx0cY*{HujLQN4${CnnL(^os|K(cFe$rVJH#&wb)k{iaJ)fhlM2`6Q^YNwd z>o@WqyL_ElNxx65nDA~w9|R}*f6Uo zG}&zzS6!ylvgNX8QoAYsAe%C{pnSc7{ujau<=ofU85)F_4@UZP&OvJ-&fl2U57GbP zeHQLn$;N22)c_+so*9lr!Ud?8nlJRfWY-4Ye%R(6vQ;8lmWwaHCJAk}pd&kUbTcEO4KK z;~u4G)Fnm*KA?gn0%_tHtpsoec|; zyx9i|`1Lyb$n`Pc*KEj!xaYR4OP%P8{#UlBA6}8C_}-ZJ7qe5zmt>3D$c&T37CuKt zyH?;|=WW^Uv&}8MUh%IO>}Lz8H&*X~qrQM&aPYgMb+*>AUaI%uduHGlqF`8^g%U^mLwFaM^Sje$4s^h1H?@B-<4Vzu zL{1LJ1*eYZe$7gGl#s3>6#3UdIz-z%5*fZ4m>q|{zke)vwBYW zvPJ-pdPw-P*tqAx0GBK==Eg($xyY2X;Zf_JF%&MR$oAcZ`jB=zevWY!@T-Y!8JK_3 zIL$sr2ghn+cb%)e-PkfvV#6mq1HX>Zes>#=<);rV_&3P()cuyQ+kOUq_0uhWpMlB& zvSAf~>=EsXfLPuAUyl{>>mt%=DCQAbg28?-Dn{T(Iz#(JV5o>+IsH%=u=P?m^cIAS z>VPj)pA_)xUtC)pwM{?5jOhb8h{MjmMh|#EhjBF zre^4eK&xX)&RPXtfaCa9LtaDk#V^|Wi~8XP3vPL}e|bSGh(^@E(+3ljTq??wNcfh@ z3DqTyz8=H(X;?ezkj#DJ&hN1C)rWZfYGW@e=!eQbkF~lZCu{JS+xj$=9I+=_R?s)p z`SVUE+z6`Yn?RsdpgzPNjb zpcPZ69coMHXE+$&qb_i+3HX;*z%NIKO+@L3+}P^E@2Lw(_2ib71^gOESlI$-rDOk> zZzZNcrziEHl{wBhjbHAb)dPU7lXX=XyP}f;_C38mg2Jre-*`)&h=v|Pt4?PpMC$Va z95|`J5q*BW=g#8(ucxg`33N~H(16PvF}P#ZxO`VG7vAp``PaZ2Y;U2!W2=B)B2?w= zd@<9FQ&y@0^hN$f@M6fsxO{lWTh+p{eude=qN|(FZB; zFI!i>%C%WcB@({84LTAMW7t_#;9v018-Ko|$=uBEal`!BTLct%D#TBrCI zue!i-eqGe8^D#o?Z7L%s(A)Np4b3?J@W=9GGDX;$u|dAv9m+P?+D1Hl^JdTUMgE1b zg7p`;?5Ozat~j9mgf7tn4s0sm*MvB2H`RN_wuI%Y1bfw(7B;RY?v=o0C(pk+^@o(s zW+(bf8%aLm>o6scD}+e*^v_4WKKT5;GfU2tv*K^ z0}%skMIplDz$Pm1tMi=Du+5w|ZSx)nY@Jdk($6^m@RZzI#}mf(O6vYi z?Ad;E+k?9w%mvx@BL7PB0mDxQRT{yrYTj?U7?BiQH(W*hN{9iS%XX`k_&-s7+>~4G zU_$p{UqAuBT;ufK>Slr-RYMO@Q_?$b&T4(d+P6AzW>o>d_S2h&>I%)C1pj&gIn%YC zlx{O)|1#OiZc3hk*){Q(c_{h#p!Sf&K9>mM%hI`eh3OI>xv6olvETf^W#5JYY1FgY zIFduukiG(bwYtE++6=w5oc%~}r>vT-W!q&YwQ$Dyy_K#l@rI1?m#zO7J-r=12W+Ym z-`!gC6i%cs;FpWP$d^Z5tf*~dP2 z+YRx7)v~!_#`%XCXgfjC=GW?smt(`qNS~`@9L#%xe8g_D*rvZjlpBU?rHp* z^{lu?OJun{yS@7?g=FAa5S9yKX%bel!uf~iX%l_#`uq*}{ZL*;Jv+Ws zm&0YxSs1`x>27-1^ZnX_eu%agTjs~%+>G`NEG3*D1tUi*d|yATEa-=-RfiJ;USm7# z%?A7%xt<+R7@5DIAO27r((8qPtbVTbV_JaMg8zM)XISq2yfo$CaN($YTCV&XgP>i* z0tIlLa(*gDeX;+g=UjP7P_rCogw~C{9!JF5~TQwljI9Nt*UfTnK)IE(~YvJnN=)m9mS?ZNO$Eb#X1Dg#ev1kkY zYi`*=qd_J*w(sCi8a1QP!ab>uF*$M%X!bls+%t0SH^n=8_Lv$=SJ5w z|GFayS7*a9{n5%Bbx-k6I;MJ_r>RDGFICp(-?Q=`;+}X}%y&*~W}u2u_64!!PtQNp zf5t&iB%)~o>8eg~&o+X#a}4MA8hTJY^H512p+o01q_lT|=ldM=B2~Nxoj`WR{x5-5 z2P<+dd_=ez<9gh{2De|JxShr?%F^j4as1So+0DK;sma-vG{f}rG3=Ad7Wfy%tc3iy zG@RLwcz(QQse`ZrPm#Ve{u%shp=+xVSPeTHmpD5|-P0gYEUDyB;9uO;iQ!aRY&Fgf zL;|sxNADu6)!?*#NQkeKv|OrXV~k;3Scd_OE0lYlDg3%ax#j;%PMzDMcnV-FccSkM z{`DH+e;oi@a#rPzNy${K(;lUBas~IKUD-TecB~83>j(epZ-su?4XIO!^u67U=ix(} z@^7R|aF5M(RU1>MtI^qNSH`Sl96~*@%XxjnQTjap|Ju9O*tm}CeC}hVOYPFUD{_@B zBD=$f6hfiQrQ{c4*&41$dXvh{rh3-Uk4wR5^+RnbyFlF^afeHaURerE+d?WA0!qnh z!3Ksa%TA)WZgNSH1f3`j?FxmE80c1DTELt>#(E z%QaRq?ltlKFE9Rx`E%oC(cD`6#C(i~P*Ssd=)q7=W&Ghe)KizVrUyTw)8mPi&nM{Z z%w5wDGwZofzxeGhnb4-Lx)-OO~0^_eMtI6v9MWUc;GUU zY0JZ;6~%8%!@nVK_TzonmZ3yG%&r+2V#q$kSAH0dv&?^ZT%7RG_f_F+E4HjzZ2@$T0H*#A{*TyJoSAXl{TcWo#&G%m z3(dgm;fdqTvw{EcVR>M{J!Agxu;Q;E{~_3_{W-Mos()u^oxEp+BT@EC$8VgVl85MP zAN($-G6L{fRoGwmv!_{;aQ+7SGl&cqE9QIbb-R7|@JZ~&T&}U!7-uJa#&A~m>9pIH z1{ik$=CGM-`)ifVCo_`^U2yH=IEG1I-1?b#Usl^+tLS}knzik-er|t^?Q823&F{D$ zAC!Ug+Wx8?47fl}69^h+muL?7OFG;l{*v*Be<5%^wA(`d!(nVP)AiT#Zw+r|2;`Vi z_80O;xhMGV^cGfoh@ZC+$Z>%m%&#YCTx5Tx!Cyb1#-aEX*l6<8VDY}fCoMx9G6$eU zO!nPF{QN6;g({9$iRcy4#-LVHPQTqo@%xZDC*ZHMsZ$*8qu#o~_*%M}L-5H#%oh~o z!@4)h_SY}zLm4f9#`=}G#vXhV-I*&~%VWN@{Us28_@DF-ysl(P7aUaYiZua0z~=AN zU3syj^y?4hIvmDo`B(NjLtvZ0#34{&C47S=*OhG+v39~6yFO%Q0i?{z%O-r(gq@@m z&Z&%#!h1IqXXZ44pb1lX2^JaFsQ3Ni3)dKQ zFak5${xYtN%;yk)__nnPX?r(L;G!7`ib2r02#fejxNou_5pMC$tY~*G3Yb)9tv{9r z@*ji9qP`cQU$3$|`6zNe&;ZhxIm1ms&U_!Ii%XinIJ#Uyrs6jCSG=jKc-Gv<4@>SI z8ISmjgTIiA^0BrH^_v}BwzRf61C8`EW227`?ahSoQ6=N`UYt7R~IjpfOR*8K? z@Z?nFk2+<_{3MB^@fb(?4)9mA5%T+M12Z<0b1`kS&@+t9)S^8!@8i7jeaoX~X5byv z`43Am`9{3AGyQG24F$(0v&l3#&JsTC$|!zA=0AK&G<&~=Z)usYi8Zs%C+6=V5q+af z#4)Y-tA@@QY@#h=Ip#QJ2;cv*&2#C@1Wv;5DE^Z6*8>ynAH+Z9*WDlab$!x*h(sLi z9}LVa^JJSxW4{zXIlX~{2it6X)|2+j1rYRfNby%Ld8Bo~ZRCf&CVW3dzW&o^9l?1O z_Sas-T?F;W_m}^2q_OnHYdGaTBd~$U_>HFoE5Udy$8X^MzV1p zX44pe=C4tl3N{vDCVxe|<-aEA21b z!tC8TY%R0jmJZTk=$Cxc7C`YAJxYhXmOm}dShFh*@g~oCp#YMillbBubSKcSbj&t! z2b697uGup5Lb|D|6*&Nl(vgUFyUPAUqrY=4cN$j6E2JP6eS+cZ3A=Gn)cmzKxa~^F zu)~Yu48uY3Qo+xiX#&vv1zX1d0{n+@_z!V6Q8$CTEgXQozt{Ygj!D|u$PqTbmi@H2 z@rlHYg+#u^4STVRR@z^ZzvTB*5TAaZBamYO5go}ge}(afh)H$}HeT{-mA*k+Hoo() z+obHT)G6$l=;^cHSyOz0)^TUJ@F;^nfya-R`Ag<(JhT1CaQ$+7%zvG?HK0Ax5JM(9 zZGZi35vO+#NB#Hd>an{(TLb6uS5NZ4u87|lq3M@tWf;;&-x{jUc`YNxHN{m z?}hq>{D&rNPpre{QWMtUBe;6T3sWRBAt?T$*gSj7?-)V$vkhkOAxos8CS;^9VL$Z4 z^TufM4I1K&qIR$8ib1xKJAYsvhvqgz(G-74`)i1r$>Aqm8!xYwoD!7ryHW=^n3~DH zQ^RE{5KGrElXxMI@29YnM=*jTxScSkLry8C-oQSVVYnS=rsr(oDEsS# zy`PGH6La2QHwy4&z5-`;@pl~ivtxP6e~52(u%@P(QR!DNVzG^4^Tb;9ap+>voZ83_ zAlEZP+9*N$__`5Xnw&(xuxPVJ&~^F#mrUD&ZyYf5$7Zvi7=isYE%$j*j^7BPuc@wt z*S?;V_e8$+sUba70CUUwf{G?Ptv>#)d#_zP7J(Xo&Y;Ba2%k0C6+2+;;k(?_1OSf! z$&wv@M?Me|rolvxt#oV+3aUgjhV=+CJopM%QA_~r4nRx+7CkE$d(7A)cCpm7tw2!n z5KF0NO>&a;L?4!31XP=Ic9Y?VEOX(Y41qu>Oi&_}%-3Ss{`|=H*3=3GKu-O6+zO;f z^($d)qaA)K6WbbsK7d`sQDXC`&4P$y`?Lvj17H9+XrUwjyEBrR^xzD}Y89AO01S-; zv7n?gde$V5dB*S4PFf>Ez*8djsF6cSO1GI?9`3vDp<1Cp5yBVcAy3O>?M#1yZE;-e z{2HM9osO%J)jeAst(0ECy8W7tSKgm1~s-Wga5CVA!IQxj9?OO!ipc5Es0=)3ueLKPXYp zn(T=k=-=agAsw3vz^-&^YPl?VD2=rmj$wC?bwIr9-J7nRG7t2>>n%?kQ^tY*==G>!D>vuh{LaN_P)M zAT|{1?a$%(l@cMpQ#X(G8GC3KrTkbQ?V)Yd01&L{lzLWomOPPW%N(N+fMDf%m@kx& zYO`sxeurfp5UO0um^g%*VFpnmluR}TZDQMI5CR)Wm`tx-=0Y& zVp}SJ*v?W;jH`Y*lqI)cs;>mpg+}1Dl(Yym&J8->oi#}aoWmSbf)Um#L4Q$}sAr+? zp0OM2MeaYQ1SzpREJ>+0PjYL4eg&IVpMl6qXk73l`H!73610U}zYIM4h#^a~j8rRL zsb4eHf;}N9iG*TC2j7~nZ?Gpdh;>jGuXk--PjhVF*dv*pM^Z1AK`ty2_Y0=Y|EJ|Sa7~d#%dCBx3O0*1h=abtTb{Huxfh|F2-VK4S z2iK1I0`iSG0Z6ffIe_h01qYP~tuRc%N8DCB1juxwOSDYF+C~@ryEC<01F$CJY^~pB z9F-+p2{{oLteMuNuw0UYOYz||3LsYRst<^|C7J_FVBB}_SaV> zc<$cWZ(Y6riQH8EE3=pXT+0|{A3yGX$*vh&1R835C1h9fa!Am2#MD~mM*Bvzfe2L( zQ5ByWOfqcR&@v9_cr`{oDS3Gz@NZI2x#md7QFN?%IRc)mpS8~ZTK~$CuF+&QP__7p zaO=t#TdP2L)RN3bmAp)fpvlJ0k_l>Ze62R5^rsB8jO`g|>Y=2l2BC~=aMPn>(7GB? z1qxxKdG`%@IV5O5+z&ZKH62%jpdyY2W<-Kn4#5&$1pGjR1EG8}w*16~f9nn#>s z^w118pdS2rSYZI7nw*7e`Me-p(yG<1WmXKDCuo!- zId2uvGJ)Z>XoHXTe%+qM!%{I&sveh?XN>bCMTt0&-?PJ)j+qU`hV$?|F<%WRJc;9b({5~|SU@}DWRq{}zj3jS~PUCqsB|3+B9A(u&pvS0mdsipt3 zGy+Q_urvZoBd|0AOCzu}0-xUz2+m75FyXw!Kfj}})bphgSQ>$)5m*|5r4d*ffzRs* oz@3kaoUgu, June 2014 +// Piwi, Feb 2019 //----------------------------------------------------------------------------- + +// Defining commands, modes and options. This must be aligned to the definitions in fpgaloader.h +// Note: the definitions here are without shifts + +// Commands: `define FPGA_CMD_SET_CONFREG 1 +`define FPGA_CMD_TRACE_ENABLE 2 + +// Major modes: +`define FPGA_MAJOR_MODE_HF_READER_TX 0 +`define FPGA_MAJOR_MODE_HF_READER_RX_XCORR 1 +`define FPGA_MAJOR_MODE_HF_SIMULATOR 2 +`define FPGA_MAJOR_MODE_HF_ISO14443A 3 +`define FPGA_MAJOR_MODE_HF_SNOOP 4 +`define FPGA_MAJOR_MODE_HF_ISO18092 5 +`define FPGA_MAJOR_MODE_HF_GET_TRACE 6 +`define FPGA_MAJOR_MODE_OFF 7 + +// Options for the generic HF reader +// Options for the HF reader, tx to tag +`define FPGA_HF_READER_TX_SHALLOW_MOD 1 + +// Options for the HF reader, correlating against rx from tag +`define FPGA_HF_READER_RX_XCORR_848_KHZ 1 +`define FPGA_HF_READER_RX_XCORR_SNOOP 2 +`define FPGA_HF_READER_RX_XCORR_QUARTER 4 + +// Options for the HF simulated tag, how to modulate +`define FPGA_HF_SIMULATOR_NO_MODULATION 0 +`define FPGA_HF_SIMULATOR_MODULATE_BPSK 1 +`define FPGA_HF_SIMULATOR_MODULATE_212K 2 +`define FPGA_HF_SIMULATOR_MODULATE_424K 4 +`define FPGA_HF_SIMULATOR_MODULATE_424K_8BIT 5 + +// Options for ISO14443A +`define FPGA_HF_ISO14443A_SNIFFER 0 +`define FPGA_HF_ISO14443A_TAGSIM_LISTEN 1 +`define FPGA_HF_ISO14443A_TAGSIM_MOD 2 +`define FPGA_HF_ISO14443A_READER_LISTEN 3 +`define FPGA_HF_ISO14443A_READER_MOD 4 + +//options for ISO18092 / Felica +`define FPGA_HF_ISO18092_FLAG_NOMOD 1 // 0001 disable modulation module +`define FPGA_HF_ISO18092_FLAG_424K 2 // 0010 should enable 414k mode (untested). No autodetect +`define FPGA_HF_ISO18092_FLAG_READER 4 // 0100 enables antenna power, to act as a reader instead of tag `include "hi_read_tx.v" `include "hi_read_rx_xcorr.v" @@ -22,6 +67,7 @@ `include "hi_sniffer.v" `include "util.v" `include "hi_flite.v" +`include "hi_get_trace.v" module fpga_hf( input spck, output miso, input mosi, input ncs, @@ -41,8 +87,33 @@ module fpga_hf( // to the configuration bits, for use below. //----------------------------------------------------------------------------- +/* + Attempt to write up how its hooked up. Iceman 2020. + + Communication between ARM / FPGA is done inside armsrc/fpgaloader.c see: function FpgaSendCommand() + Send 16 bit command / data pair to FPGA + The bit format is: C3 C2 C1 C0 D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0 + where + C is 4bit command + D is 12bit data + + shift_reg receive this 16bit frame + + +-----+--------- frame layout -------------------- +bit | 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +-----+------------------------------------------- +cmd | x x x x +major| x x x +opt | x x +divi | x x x x x x x x +thres| x x x x x x x x +-----+------------------------------------------- +*/ + reg [15:0] shift_reg; reg [7:0] conf_word; +reg trace_enable; // We switch modes between transmitting to the 13.56 MHz tag and receiving // from it, which means that we must make sure that we can do so without @@ -50,10 +121,8 @@ reg [7:0] conf_word; always @(posedge ncs) begin case(shift_reg[15:12]) - `FPGA_CMD_SET_CONFREG: - begin - conf_word <= shift_reg[7:0]; - end + `FPGA_CMD_SET_CONFREG: conf_word <= shift_reg[7:0]; + `FPGA_CMD_TRACE_ENABLE: trace_enable <= shift_reg[0]; endcase end @@ -152,6 +221,13 @@ hi_flite hfl( hi_simulate_mod_type ); +hi_get_trace gt( + ck_1356megb, + adc_d, trace_enable, major_mode, + gt_ssp_frame, gt_ssp_din, gt_ssp_clk +); + + // Major modes: // 000 -- HF reader, transmitting to tag; modulation depth selectable @@ -160,20 +236,20 @@ hi_flite hfl( // 011 -- HF ISO14443-A // 100 -- HF Snoop // 101 -- Felica modem, reusing HF reader -// 110 -- none +// 110 -- HF get trace // 111 -- everything off -mux8 mux_ssp_clk (major_mode, ssp_clk, ht_ssp_clk, hrxc_ssp_clk, hs_ssp_clk, hisn_ssp_clk, he_ssp_clk, hfl_ssp_clk, 1'b0, 1'b0); -mux8 mux_ssp_din (major_mode, ssp_din, ht_ssp_din, hrxc_ssp_din, hs_ssp_din, hisn_ssp_din, he_ssp_din, hfl_ssp_din, 1'b0, 1'b0); -mux8 mux_ssp_frame (major_mode, ssp_frame, ht_ssp_frame, hrxc_ssp_frame, hs_ssp_frame, hisn_ssp_frame, he_ssp_frame, hfl_ssp_frame, 1'b0, 1'b0); -mux8 mux_pwr_oe1 (major_mode, pwr_oe1, ht_pwr_oe1, hrxc_pwr_oe1, hs_pwr_oe1, hisn_pwr_oe1, he_pwr_oe1, hfl_pwr_oe1, 1'b0, 1'b0); -mux8 mux_pwr_oe2 (major_mode, pwr_oe2, ht_pwr_oe2, hrxc_pwr_oe2, hs_pwr_oe2, hisn_pwr_oe2, he_pwr_oe2, hfl_pwr_oe2, 1'b0, 1'b0); -mux8 mux_pwr_oe3 (major_mode, pwr_oe3, ht_pwr_oe3, hrxc_pwr_oe3, hs_pwr_oe3, hisn_pwr_oe3, he_pwr_oe3, hfl_pwr_oe3, 1'b0, 1'b0); -mux8 mux_pwr_oe4 (major_mode, pwr_oe4, ht_pwr_oe4, hrxc_pwr_oe4, hs_pwr_oe4, hisn_pwr_oe4, he_pwr_oe4, hfl_pwr_oe4, 1'b0, 1'b0); -mux8 mux_pwr_lo (major_mode, pwr_lo, ht_pwr_lo, hrxc_pwr_lo, hs_pwr_lo, hisn_pwr_lo, he_pwr_lo, hfl_pwr_lo, 1'b0, 1'b0); -mux8 mux_pwr_hi (major_mode, pwr_hi, ht_pwr_hi, hrxc_pwr_hi, hs_pwr_hi, hisn_pwr_hi, he_pwr_hi, hfl_pwr_hi, 1'b0, 1'b0); -mux8 mux_adc_clk (major_mode, adc_clk, ht_adc_clk, hrxc_adc_clk, hs_adc_clk, hisn_adc_clk, he_adc_clk, hfl_adc_clk, 1'b0, 1'b0); -mux8 mux_dbg (major_mode, dbg, ht_dbg, hrxc_dbg, hs_dbg, hisn_dbg, he_dbg, hfl_dbg, 1'b0, 1'b0); +mux8 mux_ssp_clk (major_mode, ssp_clk, ht_ssp_clk, hrxc_ssp_clk, hs_ssp_clk, hisn_ssp_clk, he_ssp_clk, hfl_ssp_clk, gt_ssp_clk, 1'b0); +mux8 mux_ssp_din (major_mode, ssp_din, ht_ssp_din, hrxc_ssp_din, hs_ssp_din, hisn_ssp_din, he_ssp_din, hfl_ssp_din, gt_ssp_din, 1'b0); +mux8 mux_ssp_frame (major_mode, ssp_frame, ht_ssp_frame, hrxc_ssp_frame, hs_ssp_frame, hisn_ssp_frame, he_ssp_frame, hfl_ssp_frame, gt_ssp_frame, 1'b0); +mux8 mux_pwr_oe1 (major_mode, pwr_oe1, ht_pwr_oe1, hrxc_pwr_oe1, hs_pwr_oe1, hisn_pwr_oe1, he_pwr_oe1, hfl_pwr_oe1, 1'b0, 1'b0); +mux8 mux_pwr_oe2 (major_mode, pwr_oe2, ht_pwr_oe2, hrxc_pwr_oe2, hs_pwr_oe2, hisn_pwr_oe2, he_pwr_oe2, hfl_pwr_oe2, 1'b0, 1'b0); +mux8 mux_pwr_oe3 (major_mode, pwr_oe3, ht_pwr_oe3, hrxc_pwr_oe3, hs_pwr_oe3, hisn_pwr_oe3, he_pwr_oe3, hfl_pwr_oe3, 1'b0, 1'b0); +mux8 mux_pwr_oe4 (major_mode, pwr_oe4, ht_pwr_oe4, hrxc_pwr_oe4, hs_pwr_oe4, hisn_pwr_oe4, he_pwr_oe4, hfl_pwr_oe4, 1'b0, 1'b0); +mux8 mux_pwr_lo (major_mode, pwr_lo, ht_pwr_lo, hrxc_pwr_lo, hs_pwr_lo, hisn_pwr_lo, he_pwr_lo, hfl_pwr_lo, 1'b0, 1'b0); +mux8 mux_pwr_hi (major_mode, pwr_hi, ht_pwr_hi, hrxc_pwr_hi, hs_pwr_hi, hisn_pwr_hi, he_pwr_hi, hfl_pwr_hi, 1'b0, 1'b0); +mux8 mux_adc_clk (major_mode, adc_clk, ht_adc_clk, hrxc_adc_clk, hs_adc_clk, hisn_adc_clk, he_adc_clk, hfl_adc_clk, 1'b0, 1'b0); +mux8 mux_dbg (major_mode, dbg, ht_dbg, hrxc_dbg, hs_dbg, hisn_dbg, he_dbg, hfl_dbg, 1'b0, 1'b0); // In all modes, let the ADC's outputs be enabled. assign adc_noe = 1'b0; diff --git a/fpga/fpga_lf.bit b/fpga/fpga_lf.bit index 133e12b828095ae49ec164a1e516727d8d98838e..dd64db8a7762141fcee85b6fb5cb9af3a4705313 100644 GIT binary patch delta 21 dcmdmgl4<`*rU{N5hNf1=hE@tj8$HXG003E#2a*5) delta 21 dcmdmgl4<`*rU{N53I Date: Sun, 12 Jan 2020 16:45:24 +0100 Subject: [PATCH 1427/1854] add 'hf plot' - from offical repo (piwi) --- armsrc/appmain.c | 29 +++++++++++++++------- armsrc/fpgaloader.c | 12 +++++----- armsrc/hfsnoop.c | 53 +++++++++++++++++++++++++++++++++++++++-- armsrc/hfsnoop.h | 3 ++- client/cmdhf.c | 42 ++++++++++++++++++++++++++++---- client/cmdhf.h | 3 ++- client/cmdparser.c | 6 +++++ client/cmdparser.h | 1 + client/comms.c | 4 ++++ client/comms.h | 3 ++- common_arm/Makefile.hal | 3 ++- common_fpga/fpga.h | 2 ++ include/pm3_cmd.h | 8 ++++++- 13 files changed, 144 insertions(+), 25 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 471dbc6be..cc66b37f4 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -17,6 +17,7 @@ #include "dbprint.h" #include "pmflash.h" #include "fpga.h" +#include "fpga.h" #include "fpgaloader.h" #include "string.h" #include "legicrf.h" @@ -440,6 +441,11 @@ void SendCapabilities(void) { #else capabilities.compiled_with_hfsniff = false; #endif +#ifdef WITH_HFPLOT + capabilities.compiled_with_hfplot = true; +#else + capabilities.compiled_with_hfplot = false; +#endif #ifdef WITH_ISO14443a capabilities.compiled_with_iso14443a = true; #else @@ -924,7 +930,7 @@ static void PacketReceived(PacketCommandNG *packet) { #ifdef WITH_HITAG case CMD_LF_HITAG_SNIFF: { // Eavesdrop Hitag tag, args = type - SniffHitag(); + SniffHitag(packet->oldarg[0]); break; } case CMD_LF_HITAG_SIMULATE: { // Simulate Hitag tag, args = memory content @@ -1358,6 +1364,13 @@ static void PacketReceived(PacketCommandNG *packet) { } #endif +#ifdef WITH_HFPLOT + case CMD_FPGAMEM_DOWNLOAD: { + HfPlotDownload(); + break; + } +#endif + #ifdef WITH_SMARTCARD case CMD_SMART_ATR: { SmartCardAtr(); @@ -1637,7 +1650,7 @@ static void PacketReceived(PacketCommandNG *packet) { Dbprintf("transfer to client failed :: | bytes between %d - %d (%d) | result: %d", i, i + len, len, result); } // Trigger a finish downloading signal with an ACK frame - reply_old(CMD_ACK, 1, 0, 0, 0, 0); + reply_mix(CMD_ACK, 1, 0, 0, 0, 0); LED_B_OFF(); break; } @@ -1698,7 +1711,7 @@ static void PacketReceived(PacketCommandNG *packet) { Dbprintf("transfer to client failed :: | bytes between %d - %d (%d) | result: %d", i, i + len, len, result); } // Trigger a finish downloading signal with an ACK frame - reply_old(CMD_ACK, 1, 0, 0, 0, 0); + reply_mix(CMD_ACK, 1, 0, 0, 0, 0); LED_B_OFF(); break; } @@ -1780,7 +1793,7 @@ static void PacketReceived(PacketCommandNG *packet) { } else { rdv40_spiffs_append((char *) filename, (uint8_t *)data, size, RDV40_SPIFFS_SAFETY_SAFE); } - reply_old(CMD_ACK, 1, 0, 0, 0, 0); + reply_mix(CMD_ACK, 1, 0, 0, 0, 0); LED_B_OFF(); break; } @@ -1822,7 +1835,7 @@ static void PacketReceived(PacketCommandNG *packet) { res = Flash_Write(startidx, data, len); isok = (res == len) ? 1 : 0; - reply_old(CMD_ACK, isok, 0, 0, 0, 0); + reply_mix(CMD_ACK, isok, 0, 0, 0, 0); LED_B_OFF(); break; } @@ -1833,14 +1846,14 @@ static void PacketReceived(PacketCommandNG *packet) { bool isok = false; if (initalwipe) { isok = Flash_WipeMemory(); - reply_old(CMD_ACK, isok, 0, 0, 0, 0); + reply_mix(CMD_ACK, isok, 0, 0, 0, 0); LED_B_OFF(); break; } if (page < 3) isok = Flash_WipeMemoryPage(page); - reply_old(CMD_ACK, isok, 0, 0, 0, 0); + reply_mix(CMD_ACK, isok, 0, 0, 0, 0); LED_B_OFF(); break; } @@ -1871,7 +1884,7 @@ static void PacketReceived(PacketCommandNG *packet) { } FlashStop(); - reply_old(CMD_ACK, 1, 0, 0, 0, 0); + reply_mix(CMD_ACK, 1, 0, 0, 0, 0); BigBuf_free(); LED_B_OFF(); break; diff --git a/armsrc/fpgaloader.c b/armsrc/fpgaloader.c index 9b7e83470..a441163e1 100644 --- a/armsrc/fpgaloader.c +++ b/armsrc/fpgaloader.c @@ -124,8 +124,8 @@ void SetupSpi(int mode) { } //----------------------------------------------------------------------------- -// Set up the synchronous serial port, with the one set of options that we -// always use when we are talking to the FPGA. Both RX and TX are enabled. +// Set up the synchronous serial port with the set of options that fits +// the FPGA mode. Both RX and TX are always enabled. //----------------------------------------------------------------------------- void FpgaSetupSsc(void) { // First configure the GPIOs, and get ourselves a clock. @@ -141,16 +141,16 @@ void FpgaSetupSsc(void) { // Now set up the SSC proper, starting from a known state. AT91C_BASE_SSC->SSC_CR = AT91C_SSC_SWRST; - // RX clock comes from TX clock, RX starts when TX starts, data changes - // on RX clock rising edge, sampled on falling edge + // RX clock comes from TX clock, RX starts on Transmit Start, + // data and frame signal is sampled on falling edge of RK AT91C_BASE_SSC->SSC_RCMR = SSC_CLOCK_MODE_SELECT(1) | SSC_CLOCK_MODE_START(1); // 8 bits per transfer, no loopback, MSB first, 1 transfer per sync // pulse, no output sync AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(8) | AT91C_SSC_MSBF | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0); - // clock comes from TK pin, no clock output, outputs change on falling - // edge of TK, sample on rising edge of TK, start on positive-going edge of sync + // TX clock comes from TK pin, no clock output, outputs change on falling + // edge of TK, frame sync is sampled on rising edge of TK, start TX on rising edge of TF AT91C_BASE_SSC->SSC_TCMR = SSC_CLOCK_MODE_SELECT(2) | SSC_CLOCK_MODE_START(5); // tx framing is the same as the rx framing diff --git a/armsrc/hfsnoop.c b/armsrc/hfsnoop.c index 2c96ec218..4ab03cd22 100644 --- a/armsrc/hfsnoop.c +++ b/armsrc/hfsnoop.c @@ -1,3 +1,12 @@ +//----------------------------------------------------------------------------- +// piwi, 2019 +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// Routines to get sample data from FPGA. +//----------------------------------------------------------------------------- #include "hfsnoop.h" #include "proxmark3_arm.h" #include "BigBuf.h" @@ -5,8 +14,9 @@ #include "ticks.h" #include "dbprint.h" #include "util.h" - -static void RAMFUNC optimizedSniff(void); +#include "fpga.h" +#include "appmain.h" +#include "cmd.h" static void RAMFUNC optimizedSniff(void) { int n = BigBuf_max_traceLen() / sizeof(uint16_t); // take all memory @@ -79,3 +89,42 @@ void HfSniff(int samplesToSkip, int triggersToSkip) { FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LED_D_OFF(); } + +void HfPlotDownload(void) { + uint8_t *buf = ToSend; + uint8_t *this_buf = buf; + + FpgaDownloadAndGo(FPGA_BITSTREAM_HF); + + FpgaSetupSsc(); + + AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS; // Disable DMA Transfer + AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) this_buf; // start transfer to this memory address + AT91C_BASE_PDC_SSC->PDC_RCR = PM3_CMD_DATA_SIZE; // transfer this many samples + buf[0] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; // clear receive register + AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTEN; // Start DMA transfer + + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_GET_TRACE); // let FPGA transfer its internal Block-RAM + + LED_B_ON(); + for(size_t i = 0; i < FPGA_TRACE_SIZE; i += PM3_CMD_DATA_SIZE) { + // prepare next DMA transfer: + uint8_t *next_buf = buf + ((i + PM3_CMD_DATA_SIZE) % (2 * PM3_CMD_DATA_SIZE)); + + AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t)next_buf; + AT91C_BASE_PDC_SSC->PDC_RNCR = PM3_CMD_DATA_SIZE; + + size_t len = MIN(FPGA_TRACE_SIZE - i, PM3_CMD_DATA_SIZE); + + while (!(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_ENDRX))) {}; // wait for DMA transfer to complete + + reply_old(CMD_FPGAMEM_DOWNLOADED, i, len, FPGA_TRACE_SIZE, this_buf, len); + this_buf = next_buf; + } + + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + + // Trigger a finish downloading signal with an ACK frame + reply_mix(CMD_ACK, 1, 0, FPGA_TRACE_SIZE, 0, 0); + LED_B_OFF(); +} diff --git a/armsrc/hfsnoop.h b/armsrc/hfsnoop.h index b6fac7eb7..049536940 100644 --- a/armsrc/hfsnoop.h +++ b/armsrc/hfsnoop.h @@ -1,6 +1,7 @@ //----------------------------------------------------------------------------- // Jonathan Westhues, Aug 2005 // Gerhard de Koning Gans, April 2008, May 2011 +// Piwi, Feb 2019 // // This code is licensed to you under the terms of the GNU GPL, version 2 or, // at your option, any later version. See the LICENSE.txt file for the text of @@ -12,5 +13,5 @@ #define __HFSNOOP_H void HfSniff(int, int); - +void HfPlotDownload(void); #endif diff --git a/client/cmdhf.c b/client/cmdhf.c index 7f6c7facf..347e4de46 100644 --- a/client/cmdhf.c +++ b/client/cmdhf.c @@ -3,6 +3,7 @@ // Merlok - 2017 // Doegox - 2019 // Iceman - 2019 +// Piwi - 2019 // // This code is licensed to you under the terms of the GNU GPL, version 2 or, // at your option, any later version. See the LICENSE.txt file for the text of @@ -12,11 +13,11 @@ //----------------------------------------------------------------------------- #include "cmdhf.h" -#include // tolower - -#include "cmdparser.h" // command_t -#include "comms.h" // clearCommandBuffer +#include // tolower +#include "cmdparser.h" // command_t +#include "cliparser/cliparser.h" // parse +#include "comms.h" // clearCommandBuffer #include "cmdhf14a.h" // ISO14443-A #include "cmdhf14b.h" // ISO14443-B #include "cmdhf15.h" // ISO15693 @@ -34,6 +35,9 @@ #include "cmdhflto.h" // LTO-CM #include "cmdtrace.h" // trace list #include "ui.h" +#include "cmddata.h" +#include "graph.h" +#include "../common_fpga/fpga.h" static int CmdHelp(const char *Cmd); @@ -224,6 +228,35 @@ int CmdHFSniff(const char *Cmd) { return PM3_SUCCESS; } +int CmdHFPlot(const char *Cmd) { + CLIParserInit("hf plot", + "Plots HF signal after RF signal path and A/D conversion.", + "This can be used after any hf command and will show the last few milliseconds of the HF signal.\n" + "Note: If the last hf command terminated because of a timeout you will most probably see nothing.\n"); + void* argtable[] = { + arg_param_begin, + arg_param_end + }; + CLIExecWithReturn(Cmd, argtable, true); + + uint8_t buf[FPGA_TRACE_SIZE]; + + PacketResponseNG response; + if (!GetFromDevice(FPGA_MEM, buf, FPGA_TRACE_SIZE, 0, NULL, 0, &response, 4000, true)) { + PrintAndLogEx(WARNING, "timeout while waiting for reply."); + return PM3_ETIMEOUT; + } + + for (size_t i = 0; i < FPGA_TRACE_SIZE; i++) { + GraphBuffer[i] = (int)buf[i] - 128; + } + + GraphTraceLen = FPGA_TRACE_SIZE; + ShowGraphWindow(); + RepaintGraphWindow(); + return PM3_SUCCESS; +} + static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, {"14a", CmdHF14A, AlwaysAvailable, "{ ISO14443A RFIDs... }"}, @@ -241,6 +274,7 @@ static command_t CommandTable[] = { {"fido", CmdHFFido, AlwaysAvailable, "{ FIDO and FIDO2 authenticators... }"}, {"thinfilm", CmdHFThinfilm, AlwaysAvailable, "{ Thinfilm RFIDs... }"}, {"list", CmdTraceList, AlwaysAvailable, "List protocol data in trace buffer"}, + {"plot", CmdHFPlot, IfPm3Hfplot, "Plot signal"}, {"tune", CmdHFTune, IfPm3Present, "Continuously measure HF antenna tuning"}, {"search", CmdHFSearch, AlwaysAvailable, "Search for known HF tags"}, {"sniff", CmdHFSniff, IfPm3Hfsniff, " Generic HF Sniff"}, diff --git a/client/cmdhf.h b/client/cmdhf.h index 14ded8e0e..09af16d5e 100644 --- a/client/cmdhf.h +++ b/client/cmdhf.h @@ -1,6 +1,6 @@ //----------------------------------------------------------------------------- // Copyright (C) 2010 iZsh -// +// Piwi, Feb 2019 // This code is licensed to you under the terms of the GNU GPL, version 2 or, // at your option, any later version. See the LICENSE.txt file for the text of // the license. @@ -17,5 +17,6 @@ int CmdHF(const char *Cmd); int CmdHFTune(const char *Cmd); int CmdHFSearch(const char *Cmd); int CmdHFSniff(const char *Cmd); +int CmdHFPlot(const char *Cmd); #endif diff --git a/client/cmdparser.c b/client/cmdparser.c index fca6fb772..ab9fd3732 100644 --- a/client/cmdparser.c +++ b/client/cmdparser.c @@ -95,6 +95,12 @@ bool IfPm3Hfsniff(void) { return pm3_capabilities.compiled_with_hfsniff; } +bool IfPm3Hfplot(void) { + if (!IfPm3Present()) + return false; + return pm3_capabilities.compiled_with_hfplot; +} + bool IfPm3Iso14443a(void) { if (!IfPm3Present()) return false; diff --git a/client/cmdparser.h b/client/cmdparser.h index b98aef9d4..1105f63ae 100644 --- a/client/cmdparser.h +++ b/client/cmdparser.h @@ -34,6 +34,7 @@ bool IfPm3FpcUsartFromUsb(void); bool IfPm3Lf(void); bool IfPm3Hitag(void); bool IfPm3Hfsniff(void); +bool IfPm3Hfplot(void); bool IfPm3Iso14443a(void); bool IfPm3Iso14443b(void); bool IfPm3Iso14443(void); diff --git a/client/comms.c b/client/comms.c index cbabe3354..9b031eb9e 100644 --- a/client/comms.c +++ b/client/comms.c @@ -797,6 +797,10 @@ bool GetFromDevice(DeviceMemType_t memtype, uint8_t *dest, uint32_t bytes, uint3 //return dl_it(dest, bytes, response, ms_timeout, show_warning, CMD_DOWNLOADED_SIMMEM); return false; } + case FPGA_MEM: { + SendCommandMIX(CMD_FPGAMEM_DOWNLOAD, start_index, bytes, 0, NULL, 0); + return dl_it(dest, bytes, response, ms_timeout, show_warning, CMD_FPGAMEM_DOWNLOADED); + } } return false; } diff --git a/client/comms.h b/client/comms.h index b49ff6d11..eaf9a16c0 100644 --- a/client/comms.h +++ b/client/comms.h @@ -40,7 +40,8 @@ typedef enum { BIG_BUF_EML, FLASH_MEM, SIM_MEM, - SPIFFS + SPIFFS, + FPGA_MEM, } DeviceMemType_t; typedef struct { diff --git a/common_arm/Makefile.hal b/common_arm/Makefile.hal index 22ae385c3..8fe070582 100644 --- a/common_arm/Makefile.hal +++ b/common_arm/Makefile.hal @@ -92,7 +92,8 @@ PLATFORM_DEFS += \ -DWITH_ICLASS \ -DWITH_FELICA \ -DWITH_NFCBARCODE \ - -DWITH_HFSNIFF + -DWITH_HFSNIFF \ + -DWITH_HFPLOT # Standalone mode diff --git a/common_fpga/fpga.h b/common_fpga/fpga.h index 5ab015f57..31580d8c9 100644 --- a/common_fpga/fpga.h +++ b/common_fpga/fpga.h @@ -14,6 +14,8 @@ #define FPGA_INTERLEAVE_SIZE 288 #define FPGA_CONFIG_SIZE 42336L // our current fpga_[lh]f.bit files are 42175 bytes. Rounded up to next multiple of FPGA_INTERLEAVE_SIZE +#define FPGA_TRACE_SIZE 3072 + static const uint8_t bitparse_fixed_header[] = {0x00, 0x09, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x00, 0x00, 0x01}; extern const int fpga_bitstream_num; extern const char *const fpga_version_information[]; diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 9100348bc..ac397ff61 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -174,6 +174,7 @@ typedef struct { bool compiled_with_hitag : 1; // hf bool compiled_with_hfsniff : 1; + bool compiled_with_hfplot : 1; bool compiled_with_iso14443a : 1; bool compiled_with_iso14443b : 1; bool compiled_with_iso15693 : 1; @@ -188,7 +189,7 @@ typedef struct { bool hw_available_flash : 1; bool hw_available_smartcard : 1; } PACKED capabilities_t; -#define CAPABILITIES_VERSION 3 +#define CAPABILITIES_VERSION 4 extern capabilities_t pm3_capabilities; // For CMD_LF_T55XX_WRITEBL @@ -522,6 +523,11 @@ typedef struct { #define CMD_HF_MFU_OTP_TEAROFF 0x0740 #define CMD_HF_SNIFF 0x0800 +#define CMD_HF_PLOT 0x0801 + +// Fpga plot download +#define CMD_FPGAMEM_DOWNLOAD 0x0802 +#define CMD_FPGAMEM_DOWNLOADED 0x0803 // For ThinFilm Kovio #define CMD_HF_THINFILM_READ 0x0810 From c591caa6a0d156265c6a1c542a79ad2f3c249921 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 12 Jan 2020 16:57:27 +0100 Subject: [PATCH 1428/1854] textual --- CHANGELOG.md | 193 ++++++++++++++++++++++++++------------------------- 1 file changed, 97 insertions(+), 96 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 44607add4..24a4c091d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,11 +3,12 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Added `hf plot` (@pwpiwi) - Fix `lf config` - when called with no params, it no longer mess up all device lf config settings. (@iceman1001) - Change `lf indala clone` - new option `--Q5` writes to q5/T5555 tags. (@iceman1001) - Change `lf indala clone` - new option `-c ` allows cloning INDALA tag from Heden2L/Hedengren ID format (@iceman1001) - Thanks to @randomdude42 for solution - Change `lf indala demod` - added decode Heden2L/Hedengren format (@iceman1001) - Thanks to @randomdude42 for solution - - Add `commands.md` - document with all proxmark client commands. Generated with XX_internal_command_dump_markdown_XX. (@iceman1001) + - Added `commands.md` - document with all proxmark client commands. Generated with XX_internal_command_dump_markdown_XX. (@iceman1001) - Change `lf pac clone` - new option `c ` to allow cloning PAC/Stanley tag from card ID (@danshuk) - Change `lf pac read` - decoded PAC/Stanley card ID (@danshuk) - Change mifare classic keytable output refactored and uses colors (@iceman1001) @@ -17,11 +18,11 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Change `hf mf hardnested` - now detects "static / fixed" nonce tags and exits (@iceman1001) - Change `hf mf csave` - now uses UID in filename (@iceman1001) - Fix `hf mf chk` - read block B logical error. #489 (@iceman1001) - - Add `hf mf ekeyprn d` - new parameter to save keys to file (@iceman1001) - - Add `mfu_magic.lua` - script to interact with your magic NTAG tag. (@iceman1001) - - Add `hf_bruteforce.lua` - script bruteforces uid for 14a using hf 14a sim (@keld) - - Add `tools\pm3_cs8.pl` - convert .pm3 files to wave format (@samyk) - - Add `tools\pm3_amii_bin2eml.pl` - amiibo convering script (@samyk) + - Added `hf mf ekeyprn d` - new parameter to save keys to file (@iceman1001) + - Added `mfu_magic.lua` - script to interact with your magic NTAG tag. (@iceman1001) + - Added `hf_bruteforce.lua` - script bruteforces uid for 14a using hf 14a sim (@keld) + - Added `tools\pm3_cs8.pl` - convert .pm3 files to wave format (@samyk) + - Added `tools\pm3_amii_bin2eml.pl` - amiibo convering script (@samyk) - Change `hf 14a info` - now detects "static / fixed" nonce tags (@iceman1001) - Change `data save f w` - params reworked. (@iceman1001) - Change `hf search` - now should detect LTO-CM tags (@iceman1001) @@ -46,16 +47,16 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Change `lf indala read` - added indala 26bit decoding (@martinbeier) - Change `lf t55xx detect` to try without password first (@mwalker33) - Display high bit for detected Kastle HIDs to allow `lf hid clone [id]` to work properly (@swg0101) - - Add option `-n` to scripts pm3* (@doegox) - - Add `wiegand list/encode/decode` - wiegand format manipulation. Adapted to fit here. (@grauerfuchs) + - Added option `-n` to scripts pm3* (@doegox) + - Added `wiegand list/encode/decode` - wiegand format manipulation. Adapted to fit here. (@grauerfuchs) - Added support for color text on windows 10 (@mwalker33) - Added `s` to `lf config` / `lf sniff` to skip samples when sniffing based on same option in Proxmark/proxmark3 by @marshmellow42. (@mwalker33) - Added save to .eml and .bin for `em 4x05_dump` (@mwalker33) - - Add option `-n` to scripts pm3* (@doegox) + - Added option `-n` to scripts pm3* (@doegox) - Fix `em 4x05_dump` to print all blocks read (@mwalker33) - Fix T55xx config getting displayed when using password when no password needed on read. (@mwalker33) - Added T55x7 downlink mode auto usage via mode detected (lf t55 detect) (@mwalker33) - - Add `lf t55xx protect` - sets password and enables password protection on t55x7 tag (@iceman1001) + - Added `lf t55xx protect` - sets password and enables password protection on t55x7 tag (@iceman1001) - Change `lf t55xx wipe` - now accepts user provided configuration block (@iceman1001) - Added T55x7 downlink mode support r 0 Default, 1 Long Leading 0, 2 Leading 0, 3 1 of 4 and 4 (in some commands) try all. (@mwalker33) - Change proxmark3-flasher is now merged into proxmark3 client. Add pm3-flash (@doegox) @@ -65,11 +66,11 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Change `hf iclass dump` - retries ten times, less output (honor verbose) (@iceman1001) - Rename `hf iclass writeblk` -> `hf iclass wrbl` to match hf mf wrbl (@iceman1001) - Rename `hf iclass readblk` -> `hf iclass rdbl` to match hf mf rdbl (@iceman1001) - - Add cmdscript example and show usage with shebang (@doegox) - - Add instructions for Fedora (@doegox) + - Added cmdscript example and show usage with shebang (@doegox) + - Added instructions for Fedora (@doegox) - Change reduce the list of requirements to the minimum and move to QT5 (@doegox) - - Add `make install` and reorganize/rename stuffs accordingly (@doegox) - - Add searchFile for several types of files (@doegox / @iceman1001) + - Added `make install` and reorganize/rename stuffs accordingly (@doegox) + - Added searchFile for several types of files (@doegox / @iceman1001) - Change posix sh version of mkversion (@doegox) - Change remove entirely ncurses, not needed nowadays (@doegox) - Change remove deprecated termcap, use ncurses instead (@ZeroChaos-) @@ -78,158 +79,158 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Change `hf mf fchk m` - now secretly dumps card to emul, if all keys are found (@iceman1001) - Change history and logfile are now saved into $HOME/.proxmark3/ (@doegox) - Change optimization of iclass mac calculations on deviceside (@pwpiwi) - - Add `hf mf autopwn` - Autopwn function for Mifare Classic, extract all keys and dump card memory (@matthiaskonrath) - - Add Lua paths: look for scripts also in ~/.proxmark/lua{scripts,libs} and /usr/local/share/proxmark3/lua{scripts,libs} (@doegox) + - Added `hf mf autopwn` - Autopwn function for Mifare Classic, extract all keys and dump card memory (@matthiaskonrath) + - Added Lua paths: look for scripts also in ~/.proxmark/lua{scripts,libs} and /usr/local/share/proxmark3/lua{scripts,libs} (@doegox) - Change Lua directory scripts/ to luascript/ (@doegox) - Change non-rdv4 PLATFORM must now use the generic PM3OTHER, simpler (@doegox) - Fix reveng integration for all platforms else than WIN32 (@doegox) - - Add cheat sheet for easy operations of the Proxmark3 (scund00r) + - Added cheat sheet for easy operations of the Proxmark3 (scund00r) - Chg commands are now in green in the helptext list (@iceman1001) - Fix `script run ndefdump` - better exit messages when failing (@iceman1001) - Fix `hf iclass dump` - now also saves in EML format (@iceman1001) - Fix `hf iclass sim 3` - now works on legacy readers and legacy SE readers (@iceman1001) - Rework hitag2 read/write help (@ViRb3) - - Add `lf nedap` - encoding / decoding (anon) - - Add client option `-i` to stay in interactive mode after a script or command (@DidierStevens/@doegox) - - Add VSCode tasks (@ViRb3) + - Added `lf nedap` - encoding / decoding (anon) + - Added client option `-i` to stay in interactive mode after a script or command (@DidierStevens/@doegox) + - Added VSCode tasks (@ViRb3) - Better warn user of hardcoded hitag info (@ViRb3) - Format and docs hitag (@ViRb3) - Fix hitag password write offset by 1 (@ViRb3) - Fix momentarily flash read/write of dicts (@doegox/@cjbrigato) - - Add some more default keys (@anon) - - Add `hf thinfilm sim` simulating Thinfilm NFC barcode tags (@doegox) - - Add `hf thinfilm list` specific trace decoding (Thinfilm NFC barcode tags) (@doegox) + - Added some more default keys (@anon) + - Added `hf thinfilm sim` simulating Thinfilm NFC barcode tags (@doegox) + - Added `hf thinfilm list` specific trace decoding (Thinfilm NFC barcode tags) (@doegox) - Fix `hf topaz reader` - don't crash when trying to read a Thinfilm tag (@iceman1001) - - Add `hf thinfilm info` - read / decode Kovio Thinfilm NFC barcode tags (@iceman1001) - - Add FPGA LF adc path (@anon) - - Add ECC support / check for NID_secp128r1 (@pwpiwi) - - Add some more default keys (ollibolli) + - Added `hf thinfilm info` - read / decode Kovio Thinfilm NFC barcode tags (@iceman1001) + - Added FPGA LF adc path (@anon) + - Added ECC support / check for NID_secp128r1 (@pwpiwi) + - Added some more default keys (ollibolli) - Fix T55x7 Downlink timings backward compatible (@mwalker33) - - Add proper Makefile halting when using incompatible STANDALONE and PLATFORM vars (@doegox) - - Add T55x7 Downlink mode support (@mwalker33) - - Add SPIFFS Flash filesystem support (@cjbrigato) + - Added proper Makefile halting when using incompatible STANDALONE and PLATFORM vars (@doegox) + - Added T55x7 Downlink mode support (@mwalker33) + - Added SPIFFS Flash filesystem support (@cjbrigato) - Fix support for flashing 512K units with old bootrom (@slurdge/@doegox) - Fix `hf mf sim` - wrong access rights to write key B in trailer (@McEloff) - - Add option -i to flasher to query Pm3 for its memory size (@doegox) - - Add support for flashing 512K units (@slurdge) - - Add a simple python tool to check the elf sizes (@slurdge) + - Added option -i to flasher to query Pm3 for its memory size (@doegox) + - Added support for flashing 512K units (@slurdge) + - Added a simple python tool to check the elf sizes (@slurdge) - Change: new keys for Vigik badges in default_keys.dict (@luminouw) - - Add `hw standalone` to jump to standalone mode from command line or script (@doegox) - - Add to `hf 14a apdu` print apdu and compose apdu (@merlokk) + - Added `hw standalone` to jump to standalone mode from command line or script (@doegox) + - Added to `hf 14a apdu` print apdu and compose apdu (@merlokk) - Change: buggy `mem read` removed, `mem save` renamed `mem dump`, can now display too (@doegox) - Fix: timeout for mem wipe was too short, thanks @cjbrigato (@doegox) - Fix `hf mf sim` - Mifare Classic simulation more flexible anti-collision check (@McEloff) - Change: `hf mf sim` - Mifare Classic simulation not respond NACK on invalid authentication request (@McEloff) - Change: `read_pwd_mem.lua` now handles Mifare Classic dictionaries large than 4096 bytes (@iceman1001) - Change: Do not clear trace log during `hf mf chk`, to save whole process history (@McEloff) - - Add `msleep` command, for pauses in scripts (@doegox) - - Add support for WSL in proxmark.sh (@doegox) - - Add documentation for usage of Proxmark3 under WSL (@doegox) + - Added `msleep` command, for pauses in scripts (@doegox) + - Added support for WSL in proxmark.sh (@doegox) + - Added documentation for usage of Proxmark3 under WSL (@doegox) - Change: replace aes.c with mbedtls version (@slurdge) - Change: replace ukbhit by kbd_enter_pressed, not requiring tcgetattr (@xianglin1998/@doegox) - - Add config for RaspberryPi in JTAG tools (@doegox) - - Add config for FTDI C232HM-DDHSL-0 in JTAG tools (@doegox) + - Added config for RaspberryPi in JTAG tools (@doegox) + - Added config for FTDI C232HM-DDHSL-0 in JTAG tools (@doegox) - Fix compilation under MacOSX with binutils (@matrix) - - Add dynamic report of the chipID for flashing purposes (@slurdge) + - Added dynamic report of the chipID for flashing purposes (@slurdge) - Fix Clang warnings (@matrix) - Fix EMVGPO bug (@matrix) - - Add hitag2 write password auth (@ViRb3) - - Add check if bootloader segment is within bounds (@slurdge) - - Add `hf 15 csetuid` - set UID on ISO-15693 Magic tags (@t0m4-null) + - Added hitag2 write password auth (@ViRb3) + - Added check if bootloader segment is within bounds (@slurdge) + - Added `hf 15 csetuid` - set UID on ISO-15693 Magic tags (@t0m4-null) - Change: Print help if unknown arg for hitag reader/writer (@ViRb3) - Fix clock deadlock in hitag sniff (@ViRb3) - - Add compiler info in client & ARM sections (@slurdge) - - Add support for automatic COM detection on Windows (@slurdge) - - Add support for compilation on RaspberryPiZero (armv6) (@doegox) + - Added compiler info in client & ARM sections (@slurdge) + - Added support for automatic COM detection on Windows (@slurdge) + - Added support for compilation on RaspberryPiZero (armv6) (@doegox) - Change: updates to README (@iceman1001) - Change: `hf mf/mfu dbg` => `hw dbg` (@doegox) - Change: replace usb_poll_validate_length() by data_available() that supports USART too (@doegox) - Make sure standalone modes can be launched when connected on USB without client (@doegox) - Change: cleaner makefile execution, use `make V=1` if you want to see full lines (@doegox) - Change: automate make clean when platform definitions are changed (@doegox) - - Add STANDALONE option to Makefile.hal (@Fl0-0) + - Added STANDALONE option to Makefile.hal (@Fl0-0) - Change: mem info - production public key to verify rdv4.0 flash signature (@iceman1001) - Fix specify that we need TCP and not UDP connection (@phcoder) - Change: lf cotag demod - adjusted error trigger (@iceman1001) - - Add documentation on BT add-on (@iceman1001/@doegox) + - Added documentation on BT add-on (@iceman1001/@doegox) - Change: new button behaviour in bootloader mode, no need to keep it pressed, press again to interrupt (@doegox) - Change: new keys in dicts, new mem layout to accomodate them (@iceman1001/various) - Fix lf sim - if called with empty graphbuffer all strange things happend, like turning on HF field (@iceman1001) - Change: hf 14a sim / hf mf sim - check buttonpress/usb frame fewer times in order not to disrupt simulation (@McEloff) - Change: data convertbitstream - converts bit to max/min in order to facilitate demodulation of simulation data (@iceman1001) - Change: lf em 410x_demod - now can demod the simulation data (@iceman1001) - - Add HC-06 scripts for BT add-on (@doegox) + - Added HC-06 scripts for BT add-on (@doegox) - Fix lf nedap sim - error when adding parity (@iceman1001) - - Add documentation on UART and baudrates (@doegox/@iceman1001) + - Added documentation on UART and baudrates (@doegox/@iceman1001) - Change: prompt now shows which channel is used (@iceman1001) - Change: USART baudrates computation, up to 6Mbps (@iceman1001/@doegox) - Change: hf mf nack - keep sync if started without card over antenna - - Add usart btfactory - to reset a misconfigured BT add-on (@doegox) + - Added usart btfactory - to reset a misconfigured BT add-on (@doegox) - Change: hw status - now prints number of dictionary keys loaded (@iceman1001) - - Add home, end, pageup, and pagedown keybinds to the plot GUI. Also fix paged movement in GUI. (@mcd1992) + - Added home, end, pageup, and pagedown keybinds to the plot GUI. Also fix paged movement in GUI. (@mcd1992) - Change legic.lua saves data in EML and BIN formats (@iceman1001) - Change hf tune - is now synchronous (for BT add-on) and can be interrupted by kbd (@doegox) - Change: update macOS install instruction (@ Uli Heilmeier) - - Add trace ouput in hexdump format for Wireshark import (@ Uli Heilmeier) - - Add usart btpin - to change BT add-on PIN (@doegox) - - Add reconnection support (@iceman1001/@doegox) - - Add usart tx/rx/... - USART developer commands (@doegox) - - Add PLATFORM_EXTRAS, WITH_FPC_USART_HOST, BTADDON Makefile configuration (@doegox) + - Added trace ouput in hexdump format for Wireshark import (@ Uli Heilmeier) + - Added usart btpin - to change BT add-on PIN (@doegox) + - Added reconnection support (@iceman1001/@doegox) + - Added usart tx/rx/... - USART developer commands (@doegox) + - Added PLATFORM_EXTRAS, WITH_FPC_USART_HOST, BTADDON Makefile configuration (@doegox) - Fix slow reconfigure on mingw of serial port (@iceman1001) - Fix cross thread communictions of timeout variable (@iceman1001) - Change: client is now "universal", adapting to Proxmark3 capabilities (@doegox) - - Add disconnect support to Lua (@iceman1001) + - Added disconnect support to Lua (@iceman1001) - Change: handles FPC/FLASH FW more gracefully on non-RDV4 pm3 (@doegox) - - Add JTAG support for Shikra (@NinjaStyle82) + - Added JTAG support for Shikra (@NinjaStyle82) - Change: smart color handling: only if linux and on real term (@doegox) - Change: reconfigure uart timeouts when compiled for FPC and connecting over USB (@iceman1001) - Change: fast push for many commands (@iceman1001/@doegox) - - Add: fast push for Lua (@iceman1001) - - Add NDEF parser in Lua (@iceman1001) + - Added: fast push for Lua (@iceman1001) + - Added NDEF parser in Lua (@iceman1001) - Change: improve NDEF parser (@iceman1001) - Change: all commands got migrated to MIX/NG packet format (@iceman1001/@doegox) - Fix: Mifare Ultralight read block missing bytes (@doegox) - - Add support new frame format in all Lua scripts (@iceman1001) - - Add CMD_CAPABILITIES for pm3 to inform dynamically the client (@doegox) + - Added support new frame format in all Lua scripts (@iceman1001) + - Added CMD_CAPABILITIES for pm3 to inform dynamically the client (@doegox) - Change baudrate handling, make it clear it is only indicative for USB-CDC & BT (@doegox) - Change: new progressive light scheme for `hw detectreader` (@doegox) - - Add common error definitions system for retvals (@doegox) + - Added common error definitions system for retvals (@doegox) - Change USART RX & TX code and fix delays handling to make it more robust, especially over BT (@doegox) - - Add support for new frames format, speedup & huge changes, see doc/new_frame_format.txt (@doegox) + - Added support for new frames format, speedup & huge changes, see doc/new_frame_format.txt (@doegox) - Change: loadFile* & saveFile* accept filenames with (or still without) extension (@doegox) - Fix LoadEML to accept final "\n", e.g. from pm3_mfd2eml.py (@doegox) - Change: rework shell scripts for easy client or flasher (@doegox) - Fix: stop poking Internet when compiling (@doegox) - - Add support for multiple commands to "-c", e.g. proxmark3 -c "hw ping;hw version" (@doegox) + - Added support for multiple commands to "-c", e.g. proxmark3 -c "hw ping;hw version" (@doegox) - Fix external flash writing bitflips issues at 24MHz (@doegox) - - Add color support to Dbprintf & alike and rework Dbprintf flags (@doegox) + - Added color support to Dbprintf & alike and rework Dbprintf flags (@doegox) - Change: archive (and fix) hid-flasher (@doegox) - - Add standalone placeholder to simplify new standalone integration (@doegox) + - Added standalone placeholder to simplify new standalone integration (@doegox) - Change: refactor standalone mode info string (@iceman1001) - - Add iceman skeleton standalone mode for ppl to use as base for their new modes (@iceman1001) + - Added iceman skeleton standalone mode for ppl to use as base for their new modes (@iceman1001) - Change: move compilation options to Makefile.hal (@doegox) - Fix compilation under OSX (@iceman1001) - - Add openocd config files for JLink (@doegox) + - Added openocd config files for JLink (@doegox) - Fix compilation dependencies for recovery (@doegox) - Fix segfault when loading a file (@doegox) - Change/Add new dump format for Ultralight/NTAG, counters support, simulation (@mceloff) - - Add `hf mf sim` full-byte split anticollision support (@mceloff) + - Added `hf mf sim` full-byte split anticollision support (@mceloff) - Fix/Add `hf mf sim` bugs fix, RATS support, etc (@mceloff) - Fix serial of FPC. (@ryan) - Fix `data shiftgraphzero` corrupting end of GraphBuffer (@doegox) - Fix `hf legic info` - unsegmented card now uses card size to calc remaining length (@iceman1001) - - Add 36bit HID format, extend calcWiegand() to include oem bits (@davidbeauchamp) + - Added 36bit HID format, extend calcWiegand() to include oem bits (@davidbeauchamp) - Fix `hf mf hardnested` - not verify key when reading nonce file (@iceman1001) - Change optimizations for ask/bi (@iceman1001) - Fix `hf mf sim` - bugs fix, refactoring (@mceloff) - - Add WRITE and COMPATIBLE_WRITE support to Mifare Ultralight/NTAG simulation (@mceloff) + - Added WRITE and COMPATIBLE_WRITE support to Mifare Ultralight/NTAG simulation (@mceloff) - Change installation instructions and add video links (@5w0rdfish) - Change `hf mf sim` to support more types (@vratiskol) - Change better strong wave detection for biphase (@iceman1001) - - Add `script run test_t55x7` (@iceman1001) - - Add new lua scripting support for some t55xx commands (@iceman1001) - - Add FPC USART for BT add-on with pm3 client. (@doegox) - - Add `-b baudrate` option to the pm3 client. (@doegox) + - Added `script run test_t55x7` (@iceman1001) + - Added new lua scripting support for some t55xx commands (@iceman1001) + - Added FPC USART for BT add-on with pm3 client. (@doegox) + - Added `-b baudrate` option to the pm3 client. (@doegox) - Change `lf t55xx info`: tell if known configuration block0. (@iceman1001) - Fix/Add FPC usart: fix TX, bring RX, full speed. (@doegox) - Change `lf t55xx config` options: allow to toggle on/off i/q5/st @@ -239,7 +240,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Fix Indala 64 on T55xx: use PSK1. (@doegox) - Force proper Linefeed (LF) handling in ProxSpace. (@vratiskol) - Fix Makefiles race conditions to allow parallel compilation, e.g. `make -j8`. (@doegox) - - Add - dictionary key file for MFU. (not in use at the moment) (@mazodude) + - Added - dictionary key file for MFU. (not in use at the moment) (@mazodude) - Change `lf fdx demod` - better biphase maxerrors. (@MalteHillmann) - Change `hf mf sim` - now works better against android (@mceloff) - Fix `lf t55xx brute` - now works after aquiredata adaptations (@iceman1001) @@ -247,7 +248,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Fix `lf t55xx recoverpwd` - now works after aquiredata adaptations (@iceman1001) - Fix `data detect p` - reverted bad clock detection (@iceman1001) - Change `data detect a` - better clock detection (@iceman1001) - - Add `hf 14a info` - now detects some magic card Gen2 (@iceman1001) + - Added `hf 14a info` - now detects some magic card Gen2 (@iceman1001) - Removed `LCD` code in armsrc compilation (@iceman1001) - Change - Generic fixes of codestyle (@doegox) (@iceman1001) - Change `lf indala demod` - refactoring (@iceman1001) @@ -257,7 +258,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Fix `data rawdemod am` - last bit was missing (@doegox) - Fix `hf 15 dump f` - also selects tag first (@iceman1001) - Fix `hf iclass clone` - missing fileclose (@iceman1001) - - Add `trace list hitag` - old hitag annotations now use the new trace (@iceman1001) + - Added `trace list hitag` - old hitag annotations now use the new trace (@iceman1001) - Change `lf hitag sim` - loads bin/eml/json (@iceman1001) - Change `lf hitag reader 21` - saves in bin/eml/json (@iceman1001) - Change `lf hitag` - refactoring (@iceman1001) @@ -276,12 +277,12 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Fix `mem write` - added extra check (@doegox) - Fix `iso15693` - bad string cpy (@doegox) - Fix `make style` - EOF LF support (@doegox) - - Add `hf 14b raw` - added -t for timeout (@iceman1001) + - Added `hf 14b raw` - added -t for timeout (@iceman1001) - Rename `lf hitag snoop` - renamed to `lf hitag sniff` (@iceman1001) - Rename `lf snoop` - renamed to `lf sniff` (@iceman1001) - Rename `hf snoop` - renamed to `hf sniff` (@iceman1001) - Fix `hf mfp wrbl` - more blocks available (@merlokk) - - Add `make platform` - compile for non-rdv4 devices made simpler (@doegox) + - Added `make platform` - compile for non-rdv4 devices made simpler (@doegox) - Change Makefiles optimizations when recompiling (@doegox) - Fix `data load` - loads TITEST.txt again (@iceman1001) - Change `lf search` - now detects TI (@iceman1001) @@ -289,25 +290,25 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Fix `lf paradox demod` - wrong check (@iceman1001) - Change `lf t55xx` - aquiredata uses getsamples (@iceman1001) - Fix `lf search` - chipset detection restore demod buffer again (@iceman1001) - - Add `make style` (@doegox) + - Added `make style` (@doegox) - Fix mixed tabs vs spaces. Now only use 4 space as tab. (@doegox) - Fix `lf visa2000 read` - too few samples (@iceman1001) - Fix `lf t55xx bruteforce` - infinity loop (@doegox) - Fix `analyse nuid` - correct crc (@doegox) - - Add command history not repeating logged commands (@doegox) + - Added command history not repeating logged commands (@doegox) - Fix path for aidjson (@doegox) - Fix missing init i2x (@doegox) - Fix `14b select card` - (@doegox) - - Add `hf mf ndef` - parsing of NDEF messages (@merlokk) - - Add `hf mf mad` - parsing of Mifare Application Directory (@merlokk) + - Added `hf mf ndef` - parsing of NDEF messages (@merlokk) + - Added `hf mf mad` - parsing of Mifare Application Directory (@merlokk) - Rename `lf snoop` -> `lf sniff` (@iceman1001) - Rename `hf snoop` -> `hf sniff` (@iceman1001) - Change generally added more colors (@iceman1001) - Change `sc upgrade` updated firmware v3.11 (RDV40) (@sentiprox) - Change `data autocorrelate` - better visual representation and added extra peak detection (@iceman1001) - Fix `lf search` - false positive indala identification fixed (@iceman1001) - - Add `lf keri` - basic support for Keri tags (@iceman1001) - - Add `hf mf list` - re-added it again (@iceman1001) + - Added `lf keri` - basic support for Keri tags (@iceman1001) + - Added `hf mf list` - re-added it again (@iceman1001) - Fix - A lot of bugfixes, like memory leaks (@iceman1001) - Change `hf 14a antifuzz` - original implementation (@asfabw), reworked a bit - Fix `hf mf fchk` (@iceman1001) @@ -315,9 +316,9 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Change `lf pcf7931` - improved read code (@sguerrini97) - Change `hf felica list` - started with some FeliCa annotations (@iceman1001) - Fix `hf tune` - now works as expected (@iceman1001) - - Add `option to use flash memory to upload dictionary files` (RDV40) (@iceman1001) + - Added `option to use flash memory to upload dictionary files` (RDV40) (@iceman1001) - Fix `printing percentage now standard compliant` (@fabled) - - Add `emv roca` - command to test for ROCA vuln in public RSA modulus (@merlokk / @iceman1001) + - Added `emv roca` - command to test for ROCA vuln in public RSA modulus (@merlokk / @iceman1001) - Added TCP ports support (on linux) (@phcoder) - Added HF sniff standalone mode with optional storing of ULC/NTAG/ULEV1 authentication attempts (@bogiton) - Fix `Lining up plot and control window` (@anticat) @@ -335,7 +336,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Fix `stand-alone Colin` - remake to benefit from flashmem for persistence. (@cjbrigato) - Fix `LEGIC SIM` - remake of legic sim (@drandreas) - Changed `proxmark3 client threading` - remake from official repo (@micolous) - - Add `rem` - new command that adds a line to the log file (@didierStevens) + - Added `rem` - new command that adds a line to the log file (@didierStevens) - Fix `EM410xdemod empty tag id in lfops.c` (@Defensor7) - Fix `usb device descriptor` - some android phones will enumerate better when iSerialnumber is not a multiple of 8 (@micolous, @megabug) - Fix `StandaloneMode LF` - when collecting signal, justNoise detection is needed (@didierStevens, @Megabug) @@ -404,7 +405,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Added `hf fido` `assert` and `make` commands from fido2 protocol (authenticatorMakeCredential and authenticatorGetAssertion) (@merlokk) - Added trailer block decoding to `hf mf rdbl` and `hf mf cgetbl` (@merlokk) - Added `hf mf mad` and `hf mfp mad` MAD decode, check and print commands (@merlokk) - - Add `script run luxeodump` (@0xdrrb) + - Added `script run luxeodump` (@0xdrrb) - Fix `lf hitag reader 02` - print all bytes (@bosb) @@ -647,9 +648,9 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Implemented better detection of mifare-tags that are not vulnerable to classic attacks (`hf mf mifare`, `hf mf nested`) (@pwpiwi) ### Added - - Add `hf 14b reader` to find and print general info about known 14b tags (@marshmellow42) - - Add `hf 14b info` to find and print info about std 14b tags and sri tags (using 14b raw commands in the client) (@marshmellow42) - - Add PACE replay functionality (@frederikmoellers) + - Added `hf 14b reader` to find and print general info about known 14b tags (@marshmellow42) + - Added `hf 14b info` to find and print info about std 14b tags and sri tags (using 14b raw commands in the client) (@marshmellow42) + - Added PACE replay functionality (@frederikmoellers) ### Fixed - t55xx write timing (@marshmellow42) From b4e0701f27b823206318dfb8ae4e6c5bb5d30b99 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 12 Jan 2020 17:13:02 +0100 Subject: [PATCH 1429/1854] Chg: 'hf plow' - remove signal offset --- client/cmdhf.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/client/cmdhf.c b/client/cmdhf.c index 347e4de46..05d52af5e 100644 --- a/client/cmdhf.c +++ b/client/cmdhf.c @@ -18,6 +18,7 @@ #include "cmdparser.h" // command_t #include "cliparser/cliparser.h" // parse #include "comms.h" // clearCommandBuffer +#include "lfdemod.h" // computeSignalProperties #include "cmdhf14a.h" // ISO14443-A #include "cmdhf14b.h" // ISO14443-B #include "cmdhf15.h" // ISO15693 @@ -248,11 +249,18 @@ int CmdHFPlot(const char *Cmd) { } for (size_t i = 0; i < FPGA_TRACE_SIZE; i++) { - GraphBuffer[i] = (int)buf[i] - 128; + GraphBuffer[i] = ((int)buf[i]) - 127; } GraphTraceLen = FPGA_TRACE_SIZE; + ShowGraphWindow(); + + // remove signal offset + CmdHpf(""); + + setClockGrid(0, 0); + DemodBufferLen = 0; RepaintGraphWindow(); return PM3_SUCCESS; } From 355a7e44582cdd329deb586a40f561829181eb48 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 12 Jan 2020 17:21:19 +0100 Subject: [PATCH 1430/1854] noo --- armsrc/appmain.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index cc66b37f4..73b9fc4a6 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -930,7 +930,8 @@ static void PacketReceived(PacketCommandNG *packet) { #ifdef WITH_HITAG case CMD_LF_HITAG_SNIFF: { // Eavesdrop Hitag tag, args = type - SniffHitag(packet->oldarg[0]); + SniffHitag(); +// SniffHitag(packet->oldarg[0]); break; } case CMD_LF_HITAG_SIMULATE: { // Simulate Hitag tag, args = memory content From ed67936892f4996572100cca57883249686d5e43 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 12 Jan 2020 17:28:12 +0100 Subject: [PATCH 1431/1854] style --- armsrc/appmain.c | 2 +- armsrc/fpgaloader.c | 14 +++---- armsrc/hfsnoop.c | 54 +++++++++++++------------- client/cliparser/argtable3.c | 44 ++++++++++----------- client/cmdhf.c | 24 ++++++------ client/cmdhfmfu.c | 12 +++--- client/cmdlf.c | 28 +++++++------- client/cmdlfindala.c | 74 ++++++++++++++++++------------------ client/cmdlfkeri.c | 4 +- common/generator.c | 74 ++++++++++++++++++------------------ common/iso15693tools.h | 24 ++++++------ 11 files changed, 177 insertions(+), 177 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 73b9fc4a6..8661ffccb 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -930,7 +930,7 @@ static void PacketReceived(PacketCommandNG *packet) { #ifdef WITH_HITAG case CMD_LF_HITAG_SNIFF: { // Eavesdrop Hitag tag, args = type - SniffHitag(); + SniffHitag(); // SniffHitag(packet->oldarg[0]); break; } diff --git a/armsrc/fpgaloader.c b/armsrc/fpgaloader.c index a441163e1..a5ca3f6d1 100644 --- a/armsrc/fpgaloader.c +++ b/armsrc/fpgaloader.c @@ -141,16 +141,16 @@ void FpgaSetupSsc(void) { // Now set up the SSC proper, starting from a known state. AT91C_BASE_SSC->SSC_CR = AT91C_SSC_SWRST; - // RX clock comes from TX clock, RX starts on Transmit Start, - // data and frame signal is sampled on falling edge of RK + // RX clock comes from TX clock, RX starts on Transmit Start, + // data and frame signal is sampled on falling edge of RK AT91C_BASE_SSC->SSC_RCMR = SSC_CLOCK_MODE_SELECT(1) | SSC_CLOCK_MODE_START(1); // 8 bits per transfer, no loopback, MSB first, 1 transfer per sync // pulse, no output sync AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(8) | AT91C_SSC_MSBF | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0); - // TX clock comes from TK pin, no clock output, outputs change on falling - // edge of TK, frame sync is sampled on rising edge of TK, start TX on rising edge of TF + // TX clock comes from TK pin, no clock output, outputs change on falling + // edge of TK, frame sync is sampled on rising edge of TK, start TX on rising edge of TF AT91C_BASE_SSC->SSC_TCMR = SSC_CLOCK_MODE_SELECT(2) | SSC_CLOCK_MODE_START(5); // tx framing is the same as the rx framing @@ -439,7 +439,7 @@ void FpgaDownloadAndGo(int bitstream_version) { // Send a 16 bit command/data pair to the FPGA. // The bit format is: C3 C2 C1 C0 D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0 // where C is the 4 bit command and D is the 12 bit data -// +// // @params cmd and v gets or over eachother. Take careful note of overlapping bits. //----------------------------------------------------------------------------- void FpgaSendCommand(uint16_t cmd, uint16_t v) { @@ -461,11 +461,11 @@ void FpgaWriteConfWord(uint16_t v) { // enable/disable FPGA internal tracing //----------------------------------------------------------------------------- void FpgaEnableTracing(void) { - FpgaSendCommand(FPGA_CMD_TRACE_ENABLE, 1); + FpgaSendCommand(FPGA_CMD_TRACE_ENABLE, 1); } void FpgaDisableTracing(void) { - FpgaSendCommand(FPGA_CMD_TRACE_ENABLE, 0); + FpgaSendCommand(FPGA_CMD_TRACE_ENABLE, 0); } //----------------------------------------------------------------------------- diff --git a/armsrc/hfsnoop.c b/armsrc/hfsnoop.c index 4ab03cd22..770280b9b 100644 --- a/armsrc/hfsnoop.c +++ b/armsrc/hfsnoop.c @@ -91,40 +91,40 @@ void HfSniff(int samplesToSkip, int triggersToSkip) { } void HfPlotDownload(void) { - uint8_t *buf = ToSend; - uint8_t *this_buf = buf; + uint8_t *buf = ToSend; + uint8_t *this_buf = buf; - FpgaDownloadAndGo(FPGA_BITSTREAM_HF); + FpgaDownloadAndGo(FPGA_BITSTREAM_HF); - FpgaSetupSsc(); + FpgaSetupSsc(); - AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS; // Disable DMA Transfer - AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) this_buf; // start transfer to this memory address - AT91C_BASE_PDC_SSC->PDC_RCR = PM3_CMD_DATA_SIZE; // transfer this many samples - buf[0] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; // clear receive register - AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTEN; // Start DMA transfer + AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS; // Disable DMA Transfer + AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) this_buf; // start transfer to this memory address + AT91C_BASE_PDC_SSC->PDC_RCR = PM3_CMD_DATA_SIZE; // transfer this many samples + buf[0] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; // clear receive register + AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTEN; // Start DMA transfer - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_GET_TRACE); // let FPGA transfer its internal Block-RAM + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_GET_TRACE); // let FPGA transfer its internal Block-RAM - LED_B_ON(); - for(size_t i = 0; i < FPGA_TRACE_SIZE; i += PM3_CMD_DATA_SIZE) { - // prepare next DMA transfer: - uint8_t *next_buf = buf + ((i + PM3_CMD_DATA_SIZE) % (2 * PM3_CMD_DATA_SIZE)); - - AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t)next_buf; - AT91C_BASE_PDC_SSC->PDC_RNCR = PM3_CMD_DATA_SIZE; + LED_B_ON(); + for (size_t i = 0; i < FPGA_TRACE_SIZE; i += PM3_CMD_DATA_SIZE) { + // prepare next DMA transfer: + uint8_t *next_buf = buf + ((i + PM3_CMD_DATA_SIZE) % (2 * PM3_CMD_DATA_SIZE)); - size_t len = MIN(FPGA_TRACE_SIZE - i, PM3_CMD_DATA_SIZE); + AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t)next_buf; + AT91C_BASE_PDC_SSC->PDC_RNCR = PM3_CMD_DATA_SIZE; - while (!(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_ENDRX))) {}; // wait for DMA transfer to complete + size_t len = MIN(FPGA_TRACE_SIZE - i, PM3_CMD_DATA_SIZE); - reply_old(CMD_FPGAMEM_DOWNLOADED, i, len, FPGA_TRACE_SIZE, this_buf, len); - this_buf = next_buf; - } + while (!(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_ENDRX))) {}; // wait for DMA transfer to complete - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - - // Trigger a finish downloading signal with an ACK frame - reply_mix(CMD_ACK, 1, 0, FPGA_TRACE_SIZE, 0, 0); - LED_B_OFF(); + reply_old(CMD_FPGAMEM_DOWNLOADED, i, len, FPGA_TRACE_SIZE, this_buf, len); + this_buf = next_buf; + } + + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + + // Trigger a finish downloading signal with an ACK frame + reply_mix(CMD_ACK, 1, 0, FPGA_TRACE_SIZE, 0, 0); + LED_B_OFF(); } diff --git a/client/cliparser/argtable3.c b/client/cliparser/argtable3.c index a5fb7a023..3acbce48e 100644 --- a/client/cliparser/argtable3.c +++ b/client/cliparser/argtable3.c @@ -3421,7 +3421,7 @@ TRexBool trex_searchrange(TRex *exp, const TRexChar *text_begin, const TRexChar if (!cur) break; node = exp->_nodes[node].next; - } + } text_begin++; } while (cur == NULL && text_begin != text_end); @@ -3675,7 +3675,7 @@ void arg_register_error(struct arg_end *end, * Return index of first table entry with a matching short option * or -1 if no match was found. */ -static int find_shortoption(struct arg_hdr** table, char shortopt) { +static int find_shortoption(struct arg_hdr **table, char shortopt) { int tabindex; for (tabindex = 0; !(table[tabindex]->flag & ARG_TERMINATOR); tabindex++) { if (table[tabindex]->shortopts && @@ -3708,7 +3708,7 @@ void dump_longoptions(struct longoptions *longoptions) { } #endif -static struct longoptions* alloc_longoptions(struct arg_hdr** table) { +static struct longoptions *alloc_longoptions(struct arg_hdr **table) { struct longoptions *result; size_t nbytes; int noptions = 1; @@ -3790,7 +3790,7 @@ static struct longoptions* alloc_longoptions(struct arg_hdr** table) { return result; } -static char* alloc_shortoptions(struct arg_hdr** table) { +static char *alloc_shortoptions(struct arg_hdr **table) { char *result; size_t len = 2; int tabindex; @@ -3830,7 +3830,7 @@ static char* alloc_shortoptions(struct arg_hdr** table) { /* return index of the table terminator entry */ -static int arg_endindex(struct arg_hdr** table) { +static int arg_endindex(struct arg_hdr **table) { int tabindex = 0; while (!(table[tabindex]->flag & ARG_TERMINATOR)) tabindex++; @@ -3839,9 +3839,9 @@ static int arg_endindex(struct arg_hdr** table) { static void arg_parse_tagged(int argc, - char **argv, - struct arg_hdr **table, - struct arg_end *endtable) { + char **argv, + struct arg_hdr **table, + struct arg_end *endtable) { struct longoptions *longoptions; char *shortoptions; int copt; @@ -3952,9 +3952,9 @@ static void arg_parse_tagged(int argc, static void arg_parse_untagged(int argc, - char **argv, - struct arg_hdr **table, - struct arg_end *endtable) { + char **argv, + struct arg_hdr **table, + struct arg_end *endtable) { int tabindex = 0; int errorlast = 0; const char *optarglast = NULL; @@ -4154,11 +4154,11 @@ static void arg_cat(char **pdest, const char *src, size_t *pndest) { static void arg_cat_option(char *dest, - size_t ndest, - const char *shortopts, - const char *longopts, - const char *datatype, - int optvalue) { + size_t ndest, + const char *shortopts, + const char *longopts, + const char *datatype, + int optvalue) { if (shortopts) { char option[3]; @@ -4212,12 +4212,12 @@ static void arg_cat_option(char *dest, } static void arg_cat_optionv(char *dest, - size_t ndest, - const char *shortopts, - const char *longopts, - const char *datatype, - int optvalue, - const char *separator) { + size_t ndest, + const char *shortopts, + const char *longopts, + const char *datatype, + int optvalue, + const char *separator) { separator = separator ? separator : ""; if (shortopts) { diff --git a/client/cmdhf.c b/client/cmdhf.c index 05d52af5e..52ad853fa 100644 --- a/client/cmdhf.c +++ b/client/cmdhf.c @@ -230,18 +230,18 @@ int CmdHFSniff(const char *Cmd) { } int CmdHFPlot(const char *Cmd) { - CLIParserInit("hf plot", - "Plots HF signal after RF signal path and A/D conversion.", - "This can be used after any hf command and will show the last few milliseconds of the HF signal.\n" - "Note: If the last hf command terminated because of a timeout you will most probably see nothing.\n"); - void* argtable[] = { - arg_param_begin, - arg_param_end - }; - CLIExecWithReturn(Cmd, argtable, true); + CLIParserInit("hf plot", + "Plots HF signal after RF signal path and A/D conversion.", + "This can be used after any hf command and will show the last few milliseconds of the HF signal.\n" + "Note: If the last hf command terminated because of a timeout you will most probably see nothing.\n"); + void *argtable[] = { + arg_param_begin, + arg_param_end + }; + CLIExecWithReturn(Cmd, argtable, true); + + uint8_t buf[FPGA_TRACE_SIZE]; - uint8_t buf[FPGA_TRACE_SIZE]; - PacketResponseNG response; if (!GetFromDevice(FPGA_MEM, buf, FPGA_TRACE_SIZE, 0, NULL, 0, &response, 4000, true)) { PrintAndLogEx(WARNING, "timeout while waiting for reply."); @@ -262,7 +262,7 @@ int CmdHFPlot(const char *Cmd) { setClockGrid(0, 0); DemodBufferLen = 0; RepaintGraphWindow(); - return PM3_SUCCESS; + return PM3_SUCCESS; } static command_t CommandTable[] = { diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index b761494f5..5387cc855 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -2469,12 +2469,12 @@ static int CmdHF14AMfUGenDiverseKeys(const char *Cmd) { PrintAndLogEx(WARNING, "iso14443a card select failed"); return PM3_ESOFT; } -/* - if (card.uidlen != 4) { - PrintAndLogEx(WARNING, "Wrong sized UID, expected 4bytes got %d", card.uidlen); - return PM3_ESOFT; - } -*/ + /* + if (card.uidlen != 4) { + PrintAndLogEx(WARNING, "Wrong sized UID, expected 4bytes got %d", card.uidlen); + return PM3_ESOFT; + } + */ memcpy(uid, card.uid, card.uidlen); } else { if (param_gethex(Cmd, 0, uid, 8)) return usage_hf_mfu_gendiverse(); diff --git a/client/cmdlf.c b/client/cmdlf.c index 337444f1e..48f1cd235 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -458,9 +458,9 @@ int lf_config(sample_config *config) { clearCommandBuffer(); if (config != NULL) SendCommandNG(CMD_LF_SAMPLING_SET_CONFIG, (uint8_t *)config, sizeof(sample_config)); - else + else SendCommandNG(CMD_LF_SAMPLING_GET_CONFIG, NULL, 0); - + return PM3_SUCCESS; } @@ -474,15 +474,15 @@ int CmdLFConfig(const char *Cmd) { } sample_config config = { - .decimation = -1, - .bits_per_sample = -1, - .averaging = -1, - .divisor = -1, - .trigger_threshold = -1, - .samples_to_skip = -1, - .verbose = true + .decimation = -1, + .bits_per_sample = -1, + .averaging = -1, + .divisor = -1, + .trigger_threshold = -1, + .samples_to_skip = -1, + .verbose = true }; - + bool errors = false; uint8_t cmdp = 0; @@ -527,20 +527,20 @@ int CmdLFConfig(const char *Cmd) { break; } case 'b': { - config.bits_per_sample = param_get8ex(Cmd, cmdp + 1, 8, 10); + config.bits_per_sample = param_get8ex(Cmd, cmdp + 1, 8, 10); // bps is limited to 8 - if (config.bits_per_sample >> 4) + if (config.bits_per_sample >> 4) config.bits_per_sample = 8; cmdp += 2; break; } case 'd': { - config.decimation = param_get8ex(Cmd, cmdp + 1, 1, 10); + config.decimation = param_get8ex(Cmd, cmdp + 1, 1, 10); // decimation is limited to 255 - if (config.decimation >> 4) + if (config.decimation >> 4) config.decimation = 8; cmdp += 2; diff --git a/client/cmdlfindala.c b/client/cmdlfindala.c index 11950a0c5..368e182d7 100644 --- a/client/cmdlfindala.c +++ b/client/cmdlfindala.c @@ -73,19 +73,19 @@ static int usage_lf_indala_sim(void) { static void encodeHeden2L(uint8_t *dest, uint32_t cardnumber) { uint8_t template[] = { - 1,0,1,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - 1,0,0,0,1,0,0,0, - 1,0,0,0,0,0,0,0, - 0,0,0,0,1,0,0,1, - 0,0,0,0,0,0,1,0 + 1, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 1, 0 }; uint8_t cardbits[32]; num_to_bytebits(cardnumber, sizeof(cardbits), cardbits); - + if (cardbits[31] == 1) template[HEDEN2L_OFFSET + 8] = 0x1; if (cardbits[30] == 1) template[HEDEN2L_OFFSET + 10] = 0x1; if (cardbits[29] == 1) template[HEDEN2L_OFFSET + 14] = 0x1; @@ -105,14 +105,14 @@ static void encodeHeden2L(uint8_t *dest, uint32_t cardnumber) { // Parity uint8_t counter = 0; - for (int i=0; i< sizeof(template) - HEDEN2L_OFFSET; i++) { - if (template[i]) - counter++; - } + for (int i = 0; i < sizeof(template) - HEDEN2L_OFFSET; i++) { + if (template[i]) + counter++; + } template[63] = (counter & 0x1); - - for (int i = 0; i< sizeof(template); i += 8) { - dest[i/8] = bytebits_to_byte(template + i, 8); + + for (int i = 0; i < sizeof(template); i += 8) { + dest[i / 8] = bytebits_to_byte(template + i, 8); } PrintAndLogEx(INFO, "Heden-2L card number %u", cardnumber); @@ -123,22 +123,22 @@ static void decodeHeden2L(uint8_t *bits) { uint32_t cardnumber = 0; uint8_t offset = HEDEN2L_OFFSET; - if ( bits[offset + 8] ) cardnumber += 1; - if ( bits[offset + 10] ) cardnumber += 2; - if ( bits[offset + 14] ) cardnumber += 4; - if ( bits[offset + 15] ) cardnumber += 8; - if ( bits[offset + 12] ) cardnumber += 16; - if ( bits[offset + 28] ) cardnumber += 32; - if ( bits[offset + 3] ) cardnumber += 64; - if ( bits[offset + 11] ) cardnumber += 128; - if ( bits[offset + 19] ) cardnumber += 256; - if ( bits[offset + 26] ) cardnumber += 512; - if ( bits[offset + 17] ) cardnumber += 1024; - if ( bits[offset + 18] ) cardnumber += 2048; - if ( bits[offset + 20] ) cardnumber += 4096; - if ( bits[offset + 13] ) cardnumber += 8192; - if ( bits[offset + 7] ) cardnumber += 16384; - if ( bits[offset + 23] ) cardnumber += 32768; + if (bits[offset + 8]) cardnumber += 1; + if (bits[offset + 10]) cardnumber += 2; + if (bits[offset + 14]) cardnumber += 4; + if (bits[offset + 15]) cardnumber += 8; + if (bits[offset + 12]) cardnumber += 16; + if (bits[offset + 28]) cardnumber += 32; + if (bits[offset + 3]) cardnumber += 64; + if (bits[offset + 11]) cardnumber += 128; + if (bits[offset + 19]) cardnumber += 256; + if (bits[offset + 26]) cardnumber += 512; + if (bits[offset + 17]) cardnumber += 1024; + if (bits[offset + 18]) cardnumber += 2048; + if (bits[offset + 20]) cardnumber += 4096; + if (bits[offset + 13]) cardnumber += 8192; + if (bits[offset + 7]) cardnumber += 16384; + if (bits[offset + 23]) cardnumber += 32768; PrintAndLogEx(SUCCESS, "\tHeden-2L | %u", cardnumber); } @@ -576,7 +576,7 @@ static int CmdIndalaClone(const char *Cmd) { if (got_cn == false) { CLIGetHexWithReturn(3, data, &datalen); } - + is_t5555 = arg_get_lit(4); CLIParserFree(); @@ -585,12 +585,12 @@ static int CmdIndalaClone(const char *Cmd) { // 224 BIT UID // config for Indala (RF/32;PSK2 with RF/2;Maxblock=7) PrintAndLogEx(INFO, "Preparing to clone Indala 224bit tag with RawID %s", sprint_hex(data, datalen)); - + if (is_t5555) blocks[0] = T5555_SET_BITRATE(32) | T5555_MODULATION_PSK2 | (7 << T5555_MAXBLOCK_SHIFT); else blocks[0] = T55x7_BITRATE_RF_32 | T55x7_MODULATION_PSK2 | (7 << T55x7_MAXBLOCK_SHIFT); - + blocks[1] = bytes_to_num(data, 4); blocks[2] = bytes_to_num(data + 4, 4); blocks[3] = bytes_to_num(data + 8, 4); @@ -608,12 +608,12 @@ static int CmdIndalaClone(const char *Cmd) { // config for Indala 64 format (RF/32;PSK1 with RF/2;Maxblock=2) PrintAndLogEx(INFO, "Preparing to clone Indala 64bit tag with RawID %s", sprint_hex(data, datalen)); - + if (is_t5555) blocks[0] = T5555_SET_BITRATE(32) | T5555_MODULATION_PSK1 | (2 << T5555_MAXBLOCK_SHIFT); else blocks[0] = T55x7_BITRATE_RF_32 | T55x7_MODULATION_PSK1 | (2 << T55x7_MAXBLOCK_SHIFT); - + blocks[1] = bytes_to_num(data, 4); blocks[2] = bytes_to_num(data + 4, 4); max = 3; diff --git a/client/cmdlfkeri.c b/client/cmdlfkeri.c index 4846b5378..aadc8676d 100644 --- a/client/cmdlfkeri.c +++ b/client/cmdlfkeri.c @@ -128,8 +128,8 @@ static int CmdKeriClone(const char *Cmd) { T55x7_MODULATION_PSK1 | T55x7_PSKCF_RF_2 | 2 << T55x7_MAXBLOCK_SHIFT, - 0, - 0 + 0, + 0 }; // dynamic bitrate used diff --git a/common/generator.c b/common/generator.c index 22c63add5..6dbac2feb 100644 --- a/common/generator.c +++ b/common/generator.c @@ -36,13 +36,13 @@ //------------------------------------ static void transform_D(uint8_t *ru) { -const uint32_t c_D[] = { - 0x6D835AFC, 0x7D15CD97, 0x0942B409, 0x32F9C923, 0xA811FB02, 0x64F121E8, - 0xD1CC8B4E, 0xE8873E6F, 0x61399BBB, 0xF1B91926, 0xAC661520, 0xA21A31C9, - 0xD424808D, 0xFE118E07, 0xD18E728D, 0xABAC9E17, 0x18066433, 0x00E18E79, - 0x65A77305, 0x5AE9E297, 0x11FC628C, 0x7BB3431F, 0x942A8308, 0xB2F8FD20, - 0x5728B869, 0x30726D5A -}; + const uint32_t c_D[] = { + 0x6D835AFC, 0x7D15CD97, 0x0942B409, 0x32F9C923, 0xA811FB02, 0x64F121E8, + 0xD1CC8B4E, 0xE8873E6F, 0x61399BBB, 0xF1B91926, 0xAC661520, 0xA21A31C9, + 0xD424808D, 0xFE118E07, 0xD18E728D, 0xABAC9E17, 0x18066433, 0x00E18E79, + 0x65A77305, 0x5AE9E297, 0x11FC628C, 0x7BB3431F, 0x942A8308, 0xB2F8FD20, + 0x5728B869, 0x30726D5A + }; //Transform uint8_t i; @@ -197,9 +197,9 @@ int mfc_algo_ving_one(uint8_t *uid, uint8_t sector, uint8_t keytype, uint64_t *k int mfc_algo_ving_all(uint8_t *uid, uint8_t *keys) { if (keys == NULL) return PM3_EINVARG; for (int keytype = 0; keytype < 2; keytype++) { - for (int sector = 0; sector < 16; sector++){ + for (int sector = 0; sector < 16; sector++) { uint64_t key = 0; - mfc_algo_ving_one(uid, sector, keytype, &key ); + mfc_algo_ving_one(uid, sector, keytype, &key); num_to_bytes(key, 6, keys + (keytype * 16 * 6) + (sector * 6)); } } @@ -216,9 +216,9 @@ int mfc_algo_yale_one(uint8_t *uid, uint8_t sector, uint8_t keytype, uint64_t *k int mfc_algo_yale_all(uint8_t *uid, uint8_t *keys) { if (keys == NULL) return PM3_EINVARG; for (int keytype = 0; keytype < 2; keytype++) { - for (int sector = 0; sector < 16; sector++){ + for (int sector = 0; sector < 16; sector++) { uint64_t key = 0; - mfc_algo_yale_one(uid, sector, keytype, &key ); + mfc_algo_yale_one(uid, sector, keytype, &key); num_to_bytes(key, 6, keys + (keytype * 16 * 6) + (sector * 6)); } } @@ -236,9 +236,9 @@ int mfc_algo_saflok_all(uint8_t *uid, uint8_t *keys) { if (keys == NULL) return PM3_EINVARG; for (int keytype = 0; keytype < 2; keytype++) { - for (int sector = 0; sector < 16; sector++){ + for (int sector = 0; sector < 16; sector++) { uint64_t key = 0; - mfc_algo_saflok_one(uid, sector, keytype, &key ); + mfc_algo_saflok_one(uid, sector, keytype, &key); num_to_bytes(key, 6, keys + (keytype * 16 * 6) + (sector * 6)); } } @@ -253,15 +253,15 @@ int mfc_algo_mizip_one(uint8_t *uid, uint8_t sector, uint8_t keytype, uint64_t * if (sector == 0) { // A if (keytype == 0) - *key = 0xA0A1A2A3A4A5U; - else // B - *key = 0xB4C132439eef; + *key = 0xA0A1A2A3A4A5U; + else // B + *key = 0xB4C132439eef; } else { - uint8_t xor[6]; + uint8_t xor[6]; - if ( keytype == 0 ) { + if (keytype == 0) { uint64_t xor_tbl_a[] = { 0x09125a2589e5, @@ -273,7 +273,7 @@ int mfc_algo_mizip_one(uint8_t *uid, uint8_t sector, uint8_t keytype, uint64_t * num_to_bytes(xor_tbl_a[sector - 1], 6, xor); *key = - (uint64_t)(uid[0] ^ xor[0] ) << 40 | + (uint64_t)(uid[0] ^ xor[0]) << 40 | (uint64_t)(uid[1] ^ xor[1]) << 32 | (uint64_t)(uid[2] ^ xor[2]) << 24 | (uint64_t)(uid[3] ^ xor[3]) << 16 | @@ -311,11 +311,11 @@ int mfc_algo_mizip_all(uint8_t *uid, uint8_t *keys) { if (keys == NULL) return PM3_EINVARG; for (int keytype = 0; keytype < 2; keytype++) { - for (int sector = 0; sector < 5; sector++){ + for (int sector = 0; sector < 5; sector++) { uint64_t key = 0; mfc_algo_mizip_one(uid, sector, keytype, &key); num_to_bytes(key, 6, keys + (keytype * 5 * 6) + (sector * 6)); - } + } } return PM3_SUCCESS; } @@ -337,20 +337,20 @@ int mfc_algo_di_one(uint8_t *uid, uint8_t sector, uint8_t keytype, uint64_t *key mbedtls_sha1(input, sizeof(input), hash); *key = ( - (uint64_t)hash[3] << 40 | - (uint64_t)hash[2] << 32 | - (uint64_t)hash[1] << 24 | - (uint64_t)hash[0] << 16 | - (uint64_t)hash[7] << 8 | - hash[6] - ); + (uint64_t)hash[3] << 40 | + (uint64_t)hash[2] << 32 | + (uint64_t)hash[1] << 24 | + (uint64_t)hash[0] << 16 | + (uint64_t)hash[7] << 8 | + hash[6] + ); return PM3_SUCCESS; } int mfc_algo_di_all(uint8_t *uid, uint8_t *keys) { if (keys == NULL) return PM3_EINVARG; for (int keytype = 0; keytype < 2; keytype++) { - for (int sector = 0; sector < 5; sector++){ + for (int sector = 0; sector < 5; sector++) { uint64_t key = 0; mfc_algo_di_one(uid, sector, keytype, &key); num_to_bytes(key, 6, keys + (keytype * 5 * 6) + (sector * 6)); @@ -361,10 +361,10 @@ int mfc_algo_di_all(uint8_t *uid, uint8_t *keys) { // Skylanders static uint64_t sky_crc64_like(uint64_t result, uint8_t sector) { - #define SKY_POLY UINT64_C(0x42f0e1eba9ea3693) - #define SKY_TOP UINT64_C(0x800000000000) +#define SKY_POLY UINT64_C(0x42f0e1eba9ea3693) +#define SKY_TOP UINT64_C(0x800000000000) result ^= (uint64_t)sector << 40; - for(int i = 0; i < 8; i++) { + for (int i = 0; i < 8; i++) { result = (result & SKY_TOP) ? (result << 1) ^ SKY_POLY : result << 1; } return result; @@ -375,7 +375,7 @@ int mfc_algo_sky_one(uint8_t *uid, uint8_t sector, uint8_t keytype, uint64_t *ke if (sector > 15) return PM3_EINVARG; if (key == NULL) return PM3_EINVARG; - + if (sector == 0 && keytype == 0) { *key = 0x4B0B20107CCB; return PM3_SUCCESS; @@ -384,21 +384,21 @@ int mfc_algo_sky_one(uint8_t *uid, uint8_t sector, uint8_t keytype, uint64_t *ke *key = 0x000000000000; return PM3_SUCCESS; } - + // hash UID uint64_t hash = 0x9AE903260CC4; - for(int i = 0; i < 4; i++) { + for (int i = 0; i < 4; i++) { hash = sky_crc64_like(hash, uid[i]); } - uint64_t sectorhash = sky_crc64_like(hash, sector); + uint64_t sectorhash = sky_crc64_like(hash, sector); *key = BSWAP_64(sectorhash & SKY_KEY_MASK) >> 16; return PM3_SUCCESS; } int mfc_algo_sky_all(uint8_t *uid, uint8_t *keys) { if (keys == NULL) return PM3_EINVARG; for (int keytype = 0; keytype < 2; keytype++) { - for (int sector = 0; sector < 16; sector++){ + for (int sector = 0; sector < 16; sector++) { uint64_t key = 0; mfc_algo_sky_one(uid, sector, keytype, &key); num_to_bytes(key, 6, keys + (keytype * 16 * 6) + (sector * 6)); diff --git a/common/iso15693tools.h b/common/iso15693tools.h index 7c5380904..62ad85499 100644 --- a/common/iso15693tools.h +++ b/common/iso15693tools.h @@ -106,14 +106,14 @@ static const int Iso15693FrameSOF[] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - -1, -1, -1, -1, - -1, -1, -1, -1, - 1, 1, 1, 1, - 1, 1, 1, 1 -}; + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + -1, -1, -1, -1, + -1, -1, -1, -1, + 1, 1, 1, 1, + 1, 1, 1, 1 + }; static const int Iso15693Logic0[] = { 1, 1, 1, 1, 1, 1, 1, 1, @@ -122,10 +122,10 @@ static const int Iso15693Logic0[] = { }; static const int Iso15693Logic1[] = { -1, -1, -1, -1, - -1, -1, -1, -1, - 1, 1, 1, 1, - 1, 1, 1, 1 -}; + -1, -1, -1, -1, + 1, 1, 1, 1, + 1, 1, 1, 1 + }; // EOF defined as // 1) logic '0' (8 pulses of 423.75kHz followed by unmodulated for 18.88us) From 6fa188062c14b5765dbf8e8aeb50d695bf076911 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 12 Jan 2020 17:30:29 +0100 Subject: [PATCH 1432/1854] style --- armsrc/fpgaloader.h | 6 +++--- armsrc/lfsampling.c | 12 ++++++------ client/cmdlfpac.c | 2 +- fpga/fpga_hf.v | 4 ++-- fpga/fpga_lf.v | 10 +++++----- fpga/hi_flite.v | 10 +++++----- 6 files changed, 22 insertions(+), 22 deletions(-) diff --git a/armsrc/fpgaloader.h b/armsrc/fpgaloader.h index 5399db4ed..636c5b7b7 100644 --- a/armsrc/fpgaloader.h +++ b/armsrc/fpgaloader.h @@ -25,7 +25,7 @@ Communication between ARM / FPGA is done inside armsrc/fpgaloader.c (function FpgaSendCommand) Send 16 bit command / data pair to FPGA The bit format is: C3 C2 C1 C0 D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0 - where + where C is 4bit command D is 12bit data @@ -33,7 +33,7 @@ bit | 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 -----+------------------------------------------- cmd | x x x x -major| x x x +major| x x x opt | x x divi | x x x x x x x x thres| x x x x x x x x @@ -71,7 +71,7 @@ thres| x x x x x x x x #define FPGA_MAJOR_MODE_OFF (7<<5) // D // Options for LF_READER -#define FPGA_LF_ADC_READER_FIELD 0x1 +#define FPGA_LF_ADC_READER_FIELD 0x1 // Options for LF_EDGE_DETECT #define FPGA_CMD_SET_EDGE_DETECT_THRESHOLD FPGA_CMD_SET_USER_BYTE1 diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index 32865d204..3378a9f94 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -54,26 +54,26 @@ void printConfig() { void setSamplingConfig(sample_config *sc) { // decimation (1-8) how many bits of adc sample value to save - if (sc->decimation > 0 && sc->decimation < 8) + if (sc->decimation > 0 && sc->decimation < 8) config.decimation = sc->decimation; // bits per sample (1-8) - if (sc->bits_per_sample > 0 && sc->bits_per_sample < 8) + if (sc->bits_per_sample > 0 && sc->bits_per_sample < 8) config.bits_per_sample = sc->bits_per_sample; // if (sc->averaging > -1) config.averaging = (sc->averaging > 0) ? 1 : 0; - + // Frequency divisor (19 - 255) if (sc->divisor > 18 && sc->divisor < 256) config.divisor = sc->divisor; - + // Start saving samples when adc value larger than trigger_threshold - if (sc->trigger_threshold > -1) + if (sc->trigger_threshold > -1) config.trigger_threshold = sc->trigger_threshold; - // Skip n adc samples before saving + // Skip n adc samples before saving if (sc->samples_to_skip > -1) config.samples_to_skip = sc->samples_to_skip; diff --git a/client/cmdlfpac.c b/client/cmdlfpac.c index 63a3e16cd..24c549a4b 100644 --- a/client/cmdlfpac.c +++ b/client/cmdlfpac.c @@ -260,7 +260,7 @@ static int CmdPacSim(const char *Cmd) { rawBlocks[i] = bytes_to_num(rawBytes + (i * sizeof(uint32_t)), sizeof(uint32_t)); num_to_bytebits(rawBlocks[i], sizeof(uint32_t) * 8, bs + (i * sizeof(uint32_t) * 8)); } - + PrintAndLogEx(SUCCESS, "Simulating PAC/Stanley - ID " _YELLOW_("%s")" raw "_YELLOW_("%08X%08X%08X%08X"), cardid, rawBlocks[0], rawBlocks[1], rawBlocks[2], rawBlocks[3]); lf_nrzsim_t *payload = calloc(1, sizeof(lf_nrzsim_t) + sizeof(bs)); diff --git a/fpga/fpga_hf.v b/fpga/fpga_hf.v index 48ae7b5ec..d23b64a08 100644 --- a/fpga/fpga_hf.v +++ b/fpga/fpga_hf.v @@ -93,7 +93,7 @@ module fpga_hf( Communication between ARM / FPGA is done inside armsrc/fpgaloader.c see: function FpgaSendCommand() Send 16 bit command / data pair to FPGA The bit format is: C3 C2 C1 C0 D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0 - where + where C is 4bit command D is 12bit data @@ -104,7 +104,7 @@ module fpga_hf( bit | 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 -----+------------------------------------------- cmd | x x x x -major| x x x +major| x x x opt | x x divi | x x x x x x x x thres| x x x x x x x x diff --git a/fpga/fpga_lf.v b/fpga/fpga_lf.v index da681321c..dd3fe3b0b 100644 --- a/fpga/fpga_lf.v +++ b/fpga/fpga_lf.v @@ -56,7 +56,7 @@ module fpga_lf( Communication between ARM / FPGA is done inside armsrc/fpgaloader.c see: function FpgaSendCommand() Send 16 bit command / data pair to FPGA The bit format is: C3 C2 C1 C0 D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0 - where + where C is 4bit command D is 12bit data @@ -83,11 +83,11 @@ module fpga_lf( Each one of this major modes can have options. Currently these two major modes uses options. - FPGA_MAJOR_MODE_LF_READER - FPGA_MAJOR_MODE_LF_EDGE_DETECT - + FPGA_MAJOR_MODE_LF_READER ------------------------------------- lf_field = 1bit (FPGA_LF_ADC_READER_FIELD) - + You can send FPGA_CMD_SET_DIVISOR to set with FREQUENCY the fpga should sample at divisor = 8bits shift_reg[7:0] @@ -101,7 +101,7 @@ module fpga_lf( conf_word 12bits conf_word[7:5] = 3bit major mode. - conf_word[0] = 1bit lf_field + conf_word[0] = 1bit lf_field conf_word[1] = 1bit lf_ed_toggle_mode conf_word[7:0] = 8bit divisor conf_word[7:0] = 8bit threshold @@ -110,7 +110,7 @@ module fpga_lf( bit | 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 -----+------------------------------------------- cmd | x x x x -major| x x x +major| x x x opt | x x divi | x x x x x x x x thres| x x x x x x x x diff --git a/fpga/hi_flite.v b/fpga/hi_flite.v index aa1f12925..97d0154ea 100644 --- a/fpga/hi_flite.v +++ b/fpga/hi_flite.v @@ -1,13 +1,13 @@ /* - This code demodulates and modulates signal as described in ISO/IEC 18092. + This code demodulates and modulates signal as described in ISO/IEC 18092. That includes packets used for Felica, NFC Tag 3, etc. (which do overlap) - simple envelope following algorithm is used (modification of fail0verflow LF one) + simple envelope following algorithm is used (modification of fail0verflow LF one) is used to combat some nasty aliasing effect with testing phone (envelope looked like sine wave) Speeds supported: only 212 kbps (fc/64) for now. Todo: 414 kbps - though for reader, the selection has to come from ARM. modulation waits for market sprocket -doesn't really mean anything + though for reader, the selection has to come from ARM. modulation waits for market sprocket -doesn't really mean anything - mod_type: bits 210: + mod_type: bits 210: bit 2 : reader drive/power on/off bit 1 : speed bit, 0 : 212, 1 :424 bit 0 : listen or modulate @@ -130,7 +130,7 @@ reg ssp_din; reg prv = 1'b1; // for simple error correction in mod/demod detection, use maximum of modded/demodded in given interval. Maybe 1 bit is extra? but better safe than sorry. -reg[7:0] mid = 8'd128; +reg[7:0] mid = 8'd128; // set TAGSIM__MODULATE on ARM if we want to write... (frame would get lost if done mid-frame...) // start sending over 1s on ssp->arm when we start sending preamble From d78b308470c1e50a531ef9407e9e794bc64a5a5f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 12 Jan 2020 18:15:25 +0100 Subject: [PATCH 1433/1854] bug: keytable printing --- client/cmdhfmf.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 9733059e9..4a9e8809a 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -1296,6 +1296,7 @@ static int CmdHF14AMfNested(const char *Cmd) { // transfer key to the emulator if (transferToEml) { uint8_t sectortrailer; + if (trgBlockNo < 32 * 4) { // 4 block sector sectortrailer = trgBlockNo | 0x03; } else { // 16 block sector @@ -1307,6 +1308,7 @@ static int CmdHF14AMfNested(const char *Cmd) { num_to_bytes(key64, 6, keyBlock); else num_to_bytes(key64, 6, &keyBlock[10]); + mfEmlSetMem(keyBlock, sectortrailer, 1); PrintAndLogEx(SUCCESS, "Key transferred to emulator memory."); } @@ -3322,7 +3324,7 @@ void printKeyTableEx(uint8_t sectorscnt, sector_t *e_sector, uint8_t start_secto PrintAndLogEx(NORMAL, "|---|----------------|---|----------------|---|"); PrintAndLogEx(NORMAL, "|sec| key A |res| key B |res|"); PrintAndLogEx(NORMAL, "|---|----------------|---|----------------|---|"); - for (uint8_t i = 0; i < sectorscnt; ++i) { + for (uint8_t i = 0; i < sectorscnt; i++) { snprintf(strA, sizeof(strA), "------------"); snprintf(strB, sizeof(strB), "------------"); @@ -3340,8 +3342,14 @@ void printKeyTableEx(uint8_t sectorscnt, sector_t *e_sector, uint8_t start_secto , strB, e_sector[i].foundKey[1] ); } else { + + // keep track if we use start_sector or i... + uint8_t s = start_sector; + if (start_sector == 0) + s = i; + PrintAndLogEx(NORMAL, "|%03d| %s | " _YELLOW_("%d")"| %s | " _YELLOW_("%d")"|" - , start_sector + , s , strA, e_sector[i].foundKey[0] , strB, e_sector[i].foundKey[1] ); From eb9f67635bd52af5540abf4d169fa657f744c16a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 13 Jan 2020 10:34:59 +0100 Subject: [PATCH 1434/1854] chg: enable/disable hf fpga tracing --- armsrc/iso14443a.c | 13 +++++++++-- armsrc/iso14443b.c | 16 +++++++++++--- armsrc/mifaresim.c | 54 ++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 76 insertions(+), 7 deletions(-) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index bd5f9ba37..b68edf58a 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -552,8 +552,6 @@ RAMFUNC int ManchesterDecoding_Thinfilm(uint8_t bit) { return false; // not finished yet, need more data } - - //============================================================================= // Finally, a `sniffer' for ISO 14443 Type A // Both sides of communication! @@ -717,6 +715,8 @@ void RAMFUNC SniffIso14443a(uint8_t param) { } } // end main loop + FpgaDisableTracing(); + if (DBGLEVEL >= DBG_ERROR) { Dbprintf("maxDataLen=%d, Uart.state=%x, Uart.len=%d", maxDataLen, Uart.state, Uart.len); Dbprintf("traceLen=" _YELLOW_("%d")", Uart.output[0]="_YELLOW_("%08x"), BigBuf_get_traceLen(), (uint32_t)Uart.output[0]); @@ -2646,6 +2646,8 @@ void ReaderIso14443a(PacketCommandNG *c) { if (!(param & ISO14A_NO_SELECT)) { iso14a_card_select_t *card = (iso14a_card_select_t *)buf; arg0 = iso14443a_select_card(NULL, card, NULL, true, 0, param & ISO14A_NO_RATS); + FpgaDisableTracing(); + reply_mix(CMD_ACK, arg0, card->uidlen, 0, buf, sizeof(iso14a_card_select_t)); if (arg0 == 0) goto OUT; @@ -2658,6 +2660,8 @@ void ReaderIso14443a(PacketCommandNG *c) { if ((param & ISO14A_APDU)) { uint8_t res; arg0 = iso14_apdu(cmd, len, (param & ISO14A_SEND_CHAINING), buf, &res); + FpgaDisableTracing(); + reply_old(CMD_ACK, arg0, res, 0, buf, sizeof(buf)); } @@ -2702,6 +2706,8 @@ void ReaderIso14443a(PacketCommandNG *c) { } } arg0 = ReaderReceive(buf, par); + FpgaDisableTracing(); + reply_old(CMD_ACK, arg0, 0, 0, buf, sizeof(buf)); } @@ -3013,6 +3019,8 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) { if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("Number of sent auth requests: %u", i); + FpgaDisableTracing(); + struct { int32_t isOK; uint8_t cuid[4]; @@ -3270,6 +3278,7 @@ void DetectNACKbug(void) { // num_nacks = number of nacks recieved. should be only 1. if not its a clone card which always sends NACK (parity == 0) ? // i = number of authentications sent. Not always 256, since we are trying to sync but close to it. + FpgaDisableTracing(); uint8_t *data = BigBuf_malloc(4); data[0] = isOK; diff --git a/armsrc/iso14443b.c b/armsrc/iso14443b.c index 6f19def06..342c68471 100644 --- a/armsrc/iso14443b.c +++ b/armsrc/iso14443b.c @@ -1165,6 +1165,9 @@ uint8_t iso14443b_apdu(uint8_t const *message, size_t message_length, uint8_t *r CodeAndTransmit14443bAsReader(message_frame, message_length + 4); //no // get response GetTagSamplesFor14443bDemod(); //no + + FpgaDisableTracing(); + if (Demod.len < 3) return 0; @@ -1191,6 +1194,7 @@ uint8_t iso14443b_select_srx_card(iso14b_card_select_t *card) { CodeAndTransmit14443bAsReader(init_srx, sizeof(init_srx)); GetTagSamplesFor14443bDemod(); //no + FpgaDisableTracing(); if (Demod.len == 0) return 2; @@ -1204,6 +1208,7 @@ uint8_t iso14443b_select_srx_card(iso14b_card_select_t *card) { CodeAndTransmit14443bAsReader(select_srx, sizeof(select_srx)); GetTagSamplesFor14443bDemod(); //no + FpgaDisableTracing(); if (Demod.len != 3) return 2; @@ -1222,6 +1227,7 @@ uint8_t iso14443b_select_srx_card(iso14b_card_select_t *card) { AddCrc14B(select_srx, 1); CodeAndTransmit14443bAsReader(select_srx, 3); // Only first three bytes for this one GetTagSamplesFor14443bDemod(); //no + FpgaDisableTracing(); if (Demod.len != 10) return 2; @@ -1253,6 +1259,7 @@ uint8_t iso14443b_select_card(iso14b_card_select_t *card) { // first, wake up the tag CodeAndTransmit14443bAsReader(wupb, sizeof(wupb)); GetTagSamplesFor14443bDemod(); //select_card + FpgaDisableTracing(); // ATQB too short? if (Demod.len < 14) @@ -1277,6 +1284,7 @@ uint8_t iso14443b_select_card(iso14b_card_select_t *card) { CodeAndTransmit14443bAsReader(attrib, sizeof(attrib)); GetTagSamplesFor14443bDemod();//select_card + FpgaDisableTracing(); // Answer to ATTRIB too short? if (Demod.len < 3) @@ -1353,6 +1361,7 @@ static bool ReadSTBlock(uint8_t block) { AddCrc14B(cmd, 2); CodeAndTransmit14443bAsReader(cmd, sizeof(cmd)); GetTagSamplesFor14443bDemod(); + FpgaDisableTracing(); // Check if we got an answer from the tag if (Demod.len != 6) { @@ -1602,7 +1611,7 @@ void SendRawCommand14443B_Ex(PacketCommandNG *c) { if ((param & ISO14B_SELECT_STD) == ISO14B_SELECT_STD) { iso14b_card_select_t *card = (iso14b_card_select_t *)buf; status = iso14443b_select_card(card); - reply_old(CMD_ACK, status, sendlen, 0, buf, sendlen); + reply_mix(CMD_ACK, status, sendlen, 0, buf, sendlen); // 0: OK 2: attrib fail, 3:crc fail, if (status > 0) goto out; } @@ -1610,14 +1619,14 @@ void SendRawCommand14443B_Ex(PacketCommandNG *c) { if ((param & ISO14B_SELECT_SR) == ISO14B_SELECT_SR) { iso14b_card_select_t *card = (iso14b_card_select_t *)buf; status = iso14443b_select_srx_card(card); - reply_old(CMD_ACK, status, sendlen, 0, buf, sendlen); + reply_mix(CMD_ACK, status, sendlen, 0, buf, sendlen); // 0: OK 2: demod fail, 3:crc fail, if (status > 0) goto out; } if ((param & ISO14B_APDU) == ISO14B_APDU) { status = iso14443b_apdu(cmd, len, buf); - reply_old(CMD_ACK, status, status, 0, buf, status); + reply_mix(CMD_ACK, status, status, 0, buf, status); } if ((param & ISO14B_RAW) == ISO14B_RAW) { @@ -1628,6 +1637,7 @@ void SendRawCommand14443B_Ex(PacketCommandNG *c) { CodeAndTransmit14443bAsReader(cmd, len); // raw GetTagSamplesFor14443bDemod(); // raw + FpgaDisableTracing(); sendlen = MIN(Demod.len, PM3_CMD_DATA_SIZE); status = (Demod.len > 0) ? 0 : 1; diff --git a/armsrc/mifaresim.c b/armsrc/mifaresim.c index b055be6c7..a6c9c06f5 100644 --- a/armsrc/mifaresim.c +++ b/armsrc/mifaresim.c @@ -435,7 +435,6 @@ static bool MifareSimInit(uint16_t flags, uint8_t *datain, uint16_t atqa, uint8_ return true; } - /** *MIFARE 1K simulate. * @@ -547,16 +546,19 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1 continue; } + FpgaEnableTracing(); //Now, get data int res = EmGetCmd(receivedCmd, &receivedCmd_len, receivedCmd_par); if (res == 2) { //Field is off! + FpgaDisableTracing(); LEDsoff(); cardSTATE = MFEMUL_NOFIELD; if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("cardSTATE = MFEMUL_NOFIELD"); continue; } else if (res == 1) { // button pressed + FpgaDisableTracing(); button_pushed = true; if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("Button pressed"); @@ -570,6 +572,8 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1 Dbprintf("EmSendPrecompiledCmd(&responses[ATQA]);"); EmSendPrecompiledCmd(&responses[ATQA]); + FpgaDisableTracing(); + // init crypto block crypto1_deinit(pcs); cardAUTHKEY = AUTHKEYNONE; @@ -637,6 +641,8 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1 // Incoming SELECT ALL for any cascade level if (receivedCmd_len == 2 && receivedCmd[1] == 0x20) { EmSendPrecompiledCmd(&responses[uid_index]); + FpgaDisableTracing(); + if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("SELECT ALL - EmSendPrecompiledCmd(%02x)", &responses[uid_index]); break; } @@ -648,6 +654,8 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1 (uid_len == 7 && uid_index == UIDBCC2) || (uid_len == 10 && uid_index == UIDBCC3); EmSendPrecompiledCmd(&responses[cl_finished ? SAK : SAKuid]); + FpgaDisableTracing(); + if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("SELECT CLx %02x%02x%02x%02x received", receivedCmd[2], receivedCmd[3], receivedCmd[4], receivedCmd[5]); if (cl_finished) { LED_B_ON(); @@ -670,6 +678,8 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1 if (memcmp(&receivedCmd[2], responses[uid_index].response, receivedCmd_len - 2) == 0) { // response missing part of UID via relative array index EmSendPrecompiledCmd(&responses[uid_index + receivedCmd_len - 2]); + FpgaDisableTracing(); + if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("SELECT ANTICOLLISION - EmSendPrecompiledCmd(%02x)", &responses[uid_index]); } else { // IDLE, not our UID or split-byte frame anti-collision (not supports) @@ -710,6 +720,8 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1 if (!CheckCrc14A(receivedCmd_dec, receivedCmd_len)) { // all commands must have a valid CRC EmSend4bit(encrypted_data ? mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA) : CARD_NACK_NA); + FpgaDisableTracing(); + if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] All commands must have a valid CRC %02X (%d)", receivedCmd_dec, receivedCmd_len); break; } @@ -725,6 +737,8 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1 // if authenticating to a block that shouldn't exist - as long as we are not doing the reader attack if (((flags & FLAG_NR_AR_ATTACK) != FLAG_NR_AR_ATTACK)) { EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA)); + FpgaDisableTracing(); + if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("Reader tried to operate (0x%02x) on out of range block: %d (0x%02x), nacking", receivedCmd_dec[0], receivedCmd_dec[1], receivedCmd_dec[1]); break; } @@ -754,6 +768,8 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1 crypto1_word(pcs, cuid ^ nonce, 0); // rAUTH_NT contains prepared nonce for authenticate EmSendCmd(rAUTH_NT, sizeof(rAUTH_NT)); + FpgaDisableTracing(); + if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] Reader authenticating for block %d (0x%02x) with key %c - nonce: %02X - ciud: %02X", receivedCmd_dec[1], receivedCmd_dec[1], (cardAUTHKEY == 0) ? 'A' : 'B', rAUTH_NT, cuid); } else { // nested authentication @@ -765,6 +781,8 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1 // we need calculate parity bits for non-encrypted sequence mf_crypto1_encryptEx(pcs, rAUTH_NT, rAUTH_NT_keystream, response, 4, response_par); EmSendCmdPar(response, 4, response_par); + FpgaDisableTracing(); + if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] Reader doing nested authentication for block %d (0x%02x) with key %c", receivedCmd_dec[1], receivedCmd_dec[1], (cardAUTHKEY == 0) ? 'A' : 'B'); } @@ -777,12 +795,14 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1 // BUT... ACK --> NACK if (receivedCmd_len == 1 && receivedCmd_dec[0] == CARD_ACK) { EmSend4bit(encrypted_data ? mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA) : CARD_NACK_NA); + FpgaDisableTracing(); break; } // rule 12 of 7.5.3. in ISO 14443-4. R(NAK) --> R(ACK) if (receivedCmd_len == 1 && receivedCmd_dec[0] == CARD_NACK_NA) { EmSend4bit(encrypted_data ? mf_crypto1_encrypt4bit(pcs, CARD_ACK) : CARD_ACK); + FpgaDisableTracing(); break; } @@ -796,6 +816,8 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1 // all other commands must be encrypted (authenticated) if (!encrypted_data) { EmSend4bit(CARD_NACK_NA); + FpgaDisableTracing(); + if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] Commands must be encrypted (authenticated)"); break; } @@ -805,6 +827,7 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1 /* if (receivedCmd_dec[1] > MIFARE_4K_MAXBLOCK) { EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA)); + FpgaDisableTracing(); if (DBGLEVEL >= DBG_ERROR) Dbprintf("[MFEMUL_WORK] Reader tried to operate (0x%02x) on out of range block: %d (0x%02x), nacking", receivedCmd_dec[0], receivedCmd_dec[1], receivedCmd_dec[1]); break; } @@ -812,6 +835,8 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1 if (MifareBlockToSector(receivedCmd_dec[1]) != cardAUTHSC) { EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA)); + FpgaDisableTracing(); + if (DBGLEVEL >= DBG_ERROR) Dbprintf("[MFEMUL_WORK] Reader tried to operate (0x%02x) on block (0x%02x) not authenticated for (0x%02x), nacking", receivedCmd_dec[0], receivedCmd_dec[1], cardAUTHSC); break; } @@ -867,6 +892,8 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1 AddCrc14A(response, 16); mf_crypto1_encrypt(pcs, response, MAX_MIFARE_FRAME_SIZE, response_par); EmSendCmdPar(response, MAX_MIFARE_FRAME_SIZE, response_par); + FpgaDisableTracing(); + if (DBGLEVEL >= DBG_EXTENDED) { Dbprintf("[MFEMUL_WORK - EmSendCmdPar] Data Block[%d]: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", blockNo, response[0], response[1], response[2], response[3], response[4], response[5], response[6], @@ -888,6 +915,8 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1 blockNo = receivedCmd_dec[1]; if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] RECV 0xA0 write block %d (%02x)", blockNo, blockNo); EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_ACK)); + FpgaDisableTracing(); + cardWRBL = blockNo; cardSTATE = MFEMUL_WRITEBL2; if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] cardSTATE = MFEMUL_WRITEBL2"); @@ -901,9 +930,11 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1 if (emlCheckValBl(blockNo)) { if (DBGLEVEL >= DBG_ERROR) Dbprintf("[MFEMUL_WORK] Reader tried to operate on block, but emlCheckValBl failed, nacking"); EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA)); + FpgaDisableTracing(); break; } EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_ACK)); + FpgaDisableTracing(); cardWRBL = blockNo; // INC @@ -936,6 +967,8 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1 EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA)); else EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_ACK)); + + FpgaDisableTracing(); break; } @@ -958,12 +991,15 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1 memcpy(response, rats, rats_len); mf_crypto1_encrypt(pcs, response, rats_len, response_par); EmSendCmdPar(response, rats_len, response_par); + FpgaDisableTracing(); } else EmSendCmd(rats, rats_len); + FpgaDisableTracing(); if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] RCV RATS => ACK"); } else { EmSend4bit(encrypted_data ? mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA) : CARD_NACK_NA); + FpgaDisableTracing(); if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] RCV RATS => NACK"); } @@ -980,10 +1016,14 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1 EmSendCmdPar(response, receivedCmd_len, response_par); } else EmSendCmd(receivedCmd_dec, receivedCmd_len); + + FpgaDisableTracing(); if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] RCV NXP DESELECT => ACK"); } else { EmSend4bit(encrypted_data ? mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA) : CARD_NACK_NA); + FpgaDisableTracing(); + if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] RCV NXP DESELECT => NACK"); } @@ -994,6 +1034,7 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1 if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("Received command not allowed, nacking"); EmSend4bit(encrypted_data ? mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA) : CARD_NACK_NA); + FpgaDisableTracing(); break; } @@ -1101,6 +1142,7 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1 num_to_bytes(ans, 4, response); mf_crypto1_encrypt(pcs, response, 4, response_par); EmSendCmdPar(response, 4, response_par); + FpgaDisableTracing(); if (DBGLEVEL >= DBG_EXTENDED) { Dbprintf("[MFEMUL_AUTH1] AUTH COMPLETED for sector %d with key %c. time=%d", @@ -1138,6 +1180,8 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1 } emlSetMem(receivedCmd_dec, cardWRBL, 1); EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_ACK)); // always ACK? + FpgaDisableTracing(); + cardSTATE = MFEMUL_WORK; if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("[MFEMUL_WRITEBL2] cardSTATE = MFEMUL_WORK"); break; @@ -1155,6 +1199,8 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1 mf_crypto1_decryptEx(pcs, receivedCmd, receivedCmd_len, (uint8_t *)&ans); if (emlGetValBl(&cardINTREG, &cardINTBLOCK, cardWRBL)) { EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA)); + FpgaDisableTracing(); + cardSTATE_TO_IDLE(); break; } @@ -1174,6 +1220,8 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1 mf_crypto1_decryptEx(pcs, receivedCmd, receivedCmd_len, (uint8_t *)&ans); if (emlGetValBl(&cardINTREG, &cardINTBLOCK, cardWRBL)) { EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA)); + FpgaDisableTracing(); + cardSTATE_TO_IDLE(); break; } @@ -1190,6 +1238,8 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1 mf_crypto1_decryptEx(pcs, receivedCmd, receivedCmd_len, (uint8_t *)&ans); if (emlGetValBl(&cardINTREG, &cardINTBLOCK, cardWRBL)) { EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA)); + FpgaDisableTracing(); + cardSTATE_TO_IDLE(); break; } @@ -1245,7 +1295,7 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1 if ((flags & FLAG_INTERACTIVE) == FLAG_INTERACTIVE) { // Interactive mode flag, means we need to send ACK //Send the collected ar_nr in the response - reply_old(CMD_ACK, CMD_HF_MIFARE_SIMULATE, button_pushed, 0, &ar_nr_resp, sizeof(ar_nr_resp)); + reply_mix(CMD_ACK, CMD_HF_MIFARE_SIMULATE, button_pushed, 0, &ar_nr_resp, sizeof(ar_nr_resp)); } FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); From fe5b3b0911a0321fa5407c4e2d2201e3741db8b6 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 13 Jan 2020 11:36:39 +0100 Subject: [PATCH 1435/1854] fix compilation bug --- armsrc/mifaresim.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/armsrc/mifaresim.c b/armsrc/mifaresim.c index a6c9c06f5..3f89cb029 100644 --- a/armsrc/mifaresim.c +++ b/armsrc/mifaresim.c @@ -991,10 +991,10 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1 memcpy(response, rats, rats_len); mf_crypto1_encrypt(pcs, response, rats_len, response_par); EmSendCmdPar(response, rats_len, response_par); - FpgaDisableTracing(); - } else + } else { EmSendCmd(rats, rats_len); - FpgaDisableTracing(); + } + FpgaDisableTracing(); if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] RCV RATS => ACK"); } else { From 5cdc6aab48fa6c35d51b0f199da96ce0a9ae60ac Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 13 Jan 2020 13:49:32 +0100 Subject: [PATCH 1436/1854] Remove libsndfile dep and code our own savewav --- client/Makefile | 2 +- client/fileutils.c | 52 ++++++++++++++----- .../Linux-Installation-Instructions.md | 6 +-- ...OS-X-Homebrew-Installation-Instructions.md | 2 +- .../Windows-Installation-Instructions.md | 2 +- doc/termux_notes.md | 2 +- 6 files changed, 45 insertions(+), 21 deletions(-) diff --git a/client/Makefile b/client/Makefile index 483856b8f..6e2ebd001 100644 --- a/client/Makefile +++ b/client/Makefile @@ -22,7 +22,7 @@ vpath %.dic dictionaries OBJDIR = obj LDLIBS ?= -L/usr/local/lib -LDLIBS += -lreadline -lsndfile -lpthread -lm +LDLIBS += -lreadline -lpthread -lm # RPi Zero gcc requires -latomic # but MacOSX /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld diff --git a/client/fileutils.c b/client/fileutils.c index 4847d52b8..44f397cda 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -41,7 +41,6 @@ #include #include -#include #include "pm3_cmd.h" #include "commonutil.h" @@ -405,30 +404,55 @@ int saveFileWAVE(const char *preferredName, int *data, size_t datalen) { if (data == NULL) return PM3_EINVARG; char *fileName = newfilenamemcopy(preferredName, ".wav"); if (fileName == NULL) return PM3_EMALLOC; - int retval = PM3_SUCCESS; - SF_INFO wave_info; - - // TODO update for other tag types - wave_info.samplerate = 125000; - wave_info.channels = 1; - wave_info.format = SF_FORMAT_WAV | SF_FORMAT_PCM_U8; - SNDFILE *wave_file = sf_open(fileName, SFM_WRITE, &wave_info); + struct wave_info_t { + char signature[4]; + uint32_t filesize; + char type[4]; + struct { + char tag[4]; + uint32_t size; + uint16_t codec; + uint16_t nb_channel; + uint32_t sample_per_sec; + uint32_t byte_per_sec; + uint16_t block_align; + uint16_t bit_per_sample; + } PACKED format; + struct { + char tag[4]; + uint32_t size; + } PACKED audio_data; + } PACKED wave_info = { + .signature = "RIFF", + .filesize = sizeof(wave_info) - sizeof(wave_info.signature) - sizeof(wave_info.filesize) + datalen, + .type = "WAVE", + .format.tag = "fmt ", + .format.size = sizeof(wave_info.format) - sizeof(wave_info.format.tag) - sizeof(wave_info.format.size), + .format.codec = 1, // PCM + .format.nb_channel = 1, + .format.sample_per_sec = 125000, // TODO update for other tag types + .format.byte_per_sec = 125000, // TODO update for other tag types + .format.block_align = 1, + .format.bit_per_sample = 8, + .audio_data.tag = "data", + .audio_data.size = datalen, + }; + FILE *wave_file = fopen(fileName, "wb"); if (!wave_file) { PrintAndLogEx(WARNING, "file not found or locked. "_YELLOW_("'%s'"), fileName); retval = PM3_EFILE; goto out; } - - // unfortunately need to upconvert to 16-bit samples because libsndfile doesn't do 8-bit(?) + fwrite(&wave_info, sizeof(wave_info), 1, wave_file); for (int i = 0; i < datalen; i++) { - short sample = data[i] * 256; - sf_write_short(wave_file, &sample, 1); + uint8_t sample = data[i] + 128; + fwrite(&sample, 1, 1, wave_file); } + fclose(wave_file); - sf_close(wave_file); PrintAndLogEx(SUCCESS, "saved " _YELLOW_("%zu")" bytes to wave file " _YELLOW_("'%s'"), 2 * datalen, fileName); out: diff --git a/doc/md/Installation_Instructions/Linux-Installation-Instructions.md b/doc/md/Installation_Instructions/Linux-Installation-Instructions.md index b48b8e9f5..d56d1056c 100644 --- a/doc/md/Installation_Instructions/Linux-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Linux-Installation-Instructions.md @@ -25,7 +25,7 @@ Install the requirements ```sh sudo apt-get install --no-install-recommends git ca-certificates build-essential pkg-config \ -libreadline-dev gcc-arm-none-eabi libnewlib-dev qtbase5-dev libsndfile1-dev +libreadline-dev gcc-arm-none-eabi libnewlib-dev qtbase5-dev ``` If you don't need the graphical components of the Proxmark3 client, you can skip the installation of `qtbase5-dev`. @@ -35,7 +35,7 @@ If you get some (non blocking) error at runtime such as _Gtk-Message: Failed to ## On ArchLinux ```sh -sudo pacman -Sy base-devel readline arm-none-eabi-gcc arm-none-eabi-newlib libsndfile git --needed +sudo pacman -Sy base-devel readline arm-none-eabi-gcc arm-none-eabi-newlib git --needed ``` If you want graphical output (such as in `hw tune`): ```sh @@ -45,7 +45,7 @@ sudo pacman -Su qt5-base ## On Fedora ```sh -sudo dnf install git make gcc gcc-c++ arm-none-eabi-gcc-cs arm-none-eabi-newlib readline-devel qt5-qtbase-devel libatomic libsndfile +sudo dnf install git make gcc gcc-c++ arm-none-eabi-gcc-cs arm-none-eabi-newlib readline-devel qt5-qtbase-devel libatomic ``` If you don't need the graphical components of the Proxmark3 client, you can skip the installation of `qt5-qtbase-devel`. diff --git a/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md b/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md index 846383658..76f5ee6f3 100644 --- a/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md @@ -82,7 +82,7 @@ These instructions will show how to setup the environment on OSX to the point wh 2. Install dependencies: ``` -brew install readline qt5 pkgconfig libsndfile +brew install readline qt5 pkgconfig brew install RfidResearchGroup/proxmark3/arm-none-eabi-gcc ``` diff --git a/doc/md/Installation_Instructions/Windows-Installation-Instructions.md b/doc/md/Installation_Instructions/Windows-Installation-Instructions.md index 4065e0d27..9d94490f5 100644 --- a/doc/md/Installation_Instructions/Windows-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Windows-Installation-Instructions.md @@ -77,7 +77,7 @@ Enter WSL prompt (`wsl`) and from there, follow the [Linux Installation Instruct ```sh sudo apt-get update sudo apt-get install --no-install-recommends git ca-certificates build-essential pkg-config \ -libreadline-dev gcc-arm-none-eabi libnewlib-dev qtbase5-dev libsndfile1-dev +libreadline-dev gcc-arm-none-eabi libnewlib-dev qtbase5-dev ``` If you don't need the graphical components of the Proxmark3 client, you can skip the installation of `qtbase5-dev`. diff --git a/doc/termux_notes.md b/doc/termux_notes.md index 2d2147513..d86ec7f08 100644 --- a/doc/termux_notes.md +++ b/doc/termux_notes.md @@ -33,7 +33,7 @@ ref : https://github.com/Proxmark/proxmark3/wiki/android 1. Install [Termux](https://play.google.com/store/apps/details?id=com.termux) and start it 2. Run the following commands: ``` -pkg install make clang clang++ readline libc++ git tsu libsndfile +pkg install make clang clang++ readline libc++ git tsu git clone https://github.com/RfidResearchGroup/proxmark3.git ``` ### Building Proxmark3 client From f46a01abfa76d958382fac69516bdc376b78ecca Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 13 Jan 2020 14:03:32 +0100 Subject: [PATCH 1437/1854] Move snd_info struct to top of file --- client/fileutils.c | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/client/fileutils.c b/client/fileutils.c index 44f397cda..982b0f753 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -52,6 +52,26 @@ #define PATH_MAX_LENGTH 200 +struct wave_info_t { + char signature[4]; + uint32_t filesize; + char type[4]; + struct { + char tag[4]; + uint32_t size; + uint16_t codec; + uint16_t nb_channel; + uint32_t sample_per_sec; + uint32_t byte_per_sec; + uint16_t block_align; + uint16_t bit_per_sample; + } PACKED format; + struct { + char tag[4]; + uint32_t size; + } PACKED audio_data; +} PACKED wave_info; + /** * @brief checks if a file exists * @param filename @@ -406,25 +426,7 @@ int saveFileWAVE(const char *preferredName, int *data, size_t datalen) { if (fileName == NULL) return PM3_EMALLOC; int retval = PM3_SUCCESS; - struct wave_info_t { - char signature[4]; - uint32_t filesize; - char type[4]; - struct { - char tag[4]; - uint32_t size; - uint16_t codec; - uint16_t nb_channel; - uint32_t sample_per_sec; - uint32_t byte_per_sec; - uint16_t block_align; - uint16_t bit_per_sample; - } PACKED format; - struct { - char tag[4]; - uint32_t size; - } PACKED audio_data; - } PACKED wave_info = { + struct wave_info_t wave_info = { .signature = "RIFF", .filesize = sizeof(wave_info) - sizeof(wave_info.signature) - sizeof(wave_info.filesize) + datalen, .type = "WAVE", From 81c7c7316deceba5ff76f427489566120e9d08b3 Mon Sep 17 00:00:00 2001 From: h4waii <30473690+h4waii@users.noreply.github.com> Date: Tue, 14 Jan 2020 17:21:49 +1300 Subject: [PATCH 1438/1854] Update mfc_default_keys.dic Added various keys from hotel cards found through hardnested attacks --- client/dictionaries/mfc_default_keys.dic | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index 15aa66993..0d838d435 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -1076,3 +1076,10 @@ f0f0172066b2 f3864fcca693 f3f0172066b2 fc9839273862 + +# various hotel keys +34D3C568B348 +91FF18E63887 +4D8B8B95FDEE +354A787087F1 +4a306e62e9b6 From b37a4c14eb497b431f7443b9f685d7f2e222bfa0 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 14 Jan 2020 16:00:31 +0100 Subject: [PATCH 1439/1854] Add 'hf mf staticnonce' - a nested find all key solution command for tags that has a static nonce. \n See https://github.com/RfidResearchGroup/proxmark3/issues/133 \n See https://github.com/Proxmark/proxmark3/issues/899 \n This solution is based upon the ideas and solutions of @uzlonewolf and @xtigmh . Thanks! --- CHANGELOG.md | 1 + armsrc/appmain.c | 12 ++ armsrc/mifarecmd.c | 110 +++++++++++++++-- armsrc/mifarecmd.h | 2 + client/cmdhf14a.c | 4 +- client/cmdhfmf.c | 233 +++++++++++++++++++++++++++++++++++-- client/mifare/mifarehost.c | 133 ++++++++++++++++++++- client/mifare/mifarehost.h | 1 + include/pm3_cmd.h | 1 + 9 files changed, 478 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 24a4c091d..91d585f28 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Added `hf mf staticnested` - useful when targeting the strange cards with a static nonce. (@iceman100) Thanks to @xtigmh @uzlonewolf for their solutions. - Added `hf plot` (@pwpiwi) - Fix `lf config` - when called with no params, it no longer mess up all device lf config settings. (@iceman1001) - Change `lf indala clone` - new option `--Q5` writes to q5/T5555 tags. (@iceman1001) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 8661ffccb..ab0320e75 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1156,6 +1156,18 @@ static void PacketReceived(PacketCommandNG *packet) { MifareNested(payload->block, payload->keytype, payload->target_block, payload->target_keytype, payload->calibrate, payload->key); break; } + case CMD_HF_MIFARE_STATIC_NESTED: { + struct p { + uint8_t block; + uint8_t keytype; + uint8_t target_block; + uint8_t target_keytype; + uint8_t key[6]; + } PACKED; + struct p *payload = (struct p *) packet->data.asBytes; + MifareStaticNested(payload->block, payload->keytype, payload->target_block, payload->target_keytype, payload->key); + break; + } case CMD_HF_MIFARE_CHKKEYS: { MifareChkKeys(packet->data.asBytes); break; diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 9bcec8862..4d7138565 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -1101,6 +1101,107 @@ void MifareNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8 set_tracing(false); } +void MifareStaticNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8_t targetKeyType, uint8_t *key) { + + LEDsoff(); + + uint64_t ui64Key = 0; + ui64Key = bytes_to_num(key, 6); + + // variables + uint16_t len; + + uint8_t uid[10] = {0x00}; + uint32_t cuid = 0, nt1, nt2; + uint32_t target_nt = {0x00}, target_ks = {0x00}; + uint8_t par[1] = {0x00}; + uint8_t receivedAnswer[10] = {0x00}; + + struct Crypto1State mpcs = {0, 0}; + struct Crypto1State *pcs; + pcs = &mpcs; + + LED_A_ON(); + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + + // free eventually allocated BigBuf memory + BigBuf_free(); + BigBuf_Clear_ext(false); + clear_trace(); + set_tracing(true); + + int16_t isOK = 0; + + LED_C_ON(); + + for (uint8_t retry = 0; retry < 3 && (isOK == 0); retry++) { + + WDT_HIT(); + + // prepare next select. No need to power down the card. + if (mifare_classic_halt(pcs, cuid)) { + if (DBGLEVEL >= DBG_INFO) Dbprintf("Nested: Halt error"); + retry--; + continue; + } + + if (!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) { + if (DBGLEVEL >= DBG_INFO) Dbprintf("Nested: Can't select card"); + retry--; + continue; + }; + + // First authenticatoin. Normal auth. + if (mifare_classic_authex(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST, &nt1, NULL)) { + if (DBGLEVEL >= DBG_INFO) Dbprintf("Nested: Auth1 error"); + retry--; + continue; + }; + + // second authentication. Nested auth + len = mifare_sendcmd_short(pcs, AUTH_NESTED, 0x60 + (targetKeyType & 0x01), targetBlockNo, receivedAnswer, par, NULL); + if (len != 4) { + if (DBGLEVEL >= DBG_INFO) Dbprintf("Nested: Auth2 error len=%d", len); + continue; + }; + + nt2 = bytes_to_num(receivedAnswer, 4); + uint32_t nt_tmp = prng_successor(nt1, 160); + target_ks = nt2 ^ nt_tmp; + target_nt = nt_tmp; + isOK = 1; + + if (DBGLEVEL >= DBG_DEBUG) Dbprintf("Testing nt1=%08x nt2enc=%08x nt2par=%02x ks=%08x", nt1, nt2, par[0], target_ks); + } + + LED_C_OFF(); + + crypto1_deinit(pcs); + + struct p { + int16_t isOK; + uint8_t block; + uint8_t keytype; + uint8_t cuid[4]; + uint8_t nt[4]; + uint8_t ks[4]; + } PACKED payload; + payload.isOK = isOK; + payload.block = targetBlockNo; + payload.keytype = targetKeyType; + + memcpy(payload.cuid, &cuid, 4); + memcpy(payload.nt, &target_nt, 4); + memcpy(payload.ks, &target_ks, 4); + + LED_B_ON(); + reply_ng(CMD_HF_MIFARE_STATIC_NESTED, PM3_SUCCESS, (uint8_t *)&payload, sizeof(payload)); + LED_B_OFF(); + + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LEDsoff(); + set_tracing(false); +} //----------------------------------------------------------------------------- // MIFARE check keys. key count up to 85. // @@ -1241,8 +1342,6 @@ void chkKey_loopBonly(struct chk_t *c, struct sector_t *k_sector, uint8_t *found } } - - // get Chunks of keys, to test authentication against card. // arg0 = antal sectorer // arg0 = first time @@ -2065,7 +2164,6 @@ OUT: // turns off OnSuccessMagic(); BigBuf_free(); - BigBuf_Clear_ext(false); } void MifareHasStaticNonce() { @@ -2092,8 +2190,8 @@ void MifareHasStaticNonce() { goto OUT; } - // Transmit MIFARE_CLASSIC_AUTH - len = mifare_sendcmd_short(pcs, false, 0x60, 0, rec, recpar, NULL); + // Transmit MIFARE_CLASSIC_AUTH 0x60, block 0 + len = mifare_sendcmd_short(pcs, false, MIFARE_AUTH_KEYA, 0, rec, recpar, NULL); if (len != 4) { retval = PM3_ESOFT; goto OUT; @@ -2114,8 +2212,6 @@ OUT: // turns off OnSuccessMagic(); BigBuf_free(); - BigBuf_Clear_ext(false); - crypto1_deinit(pcs); } diff --git a/armsrc/mifarecmd.h b/armsrc/mifarecmd.h index a127e79af..cb60ea7c5 100644 --- a/armsrc/mifarecmd.h +++ b/armsrc/mifarecmd.h @@ -25,6 +25,8 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain); void MifareUWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain); void MifareNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8_t targetKeyType, bool calibrate, uint8_t *key); +void MifareStaticNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8_t targetKeyType, uint8_t *key); + void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, uint8_t *datain); void MifareAcquireNonces(uint32_t arg0, uint32_t flags); void MifareChkKeys(uint8_t *datain); diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index 6744916f7..c611caa1f 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -1601,9 +1601,9 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { res = detect_classic_static_nonce(); if (res == 1) - PrintAndLogEx(SUCCESS, "Static/Fixed nonce detected"); + PrintAndLogEx(SUCCESS, "Static nonce detected"); if (res == 2 && verbose) - PrintAndLogEx(SUCCESS, "Static/Fixed nonce detection failed"); + PrintAndLogEx(SUCCESS, "Static nonce detection failed"); } return select_status; diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 4a9e8809a..e8e27793b 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -132,6 +132,21 @@ static int usage_hf14_nested(void) { PrintAndLogEx(NORMAL, " hf mf nested o 0 A FFFFFFFFFFFF 4 A -- one sector key recovery. Use block 0 Key A to find block 4 Key A"); return PM3_SUCCESS; } +static int usage_hf14_staticnested(void) { + PrintAndLogEx(NORMAL, "Usage:"); + PrintAndLogEx(NORMAL, " all sectors: hf mf staticnested [t,d]"); + PrintAndLogEx(NORMAL, "Options:"); + PrintAndLogEx(NORMAL, " h this help"); + PrintAndLogEx(NORMAL, " card memory - 0 - MINI(320 bytes), 1 - 1K, 2 - 2K, 4 - 4K, - 1K"); + PrintAndLogEx(NORMAL, " t transfer keys into emulator memory"); + PrintAndLogEx(NORMAL, " d write keys to binary file `hf-mf--key.bin`"); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Examples:"); + PrintAndLogEx(NORMAL, " hf mf staticnested 1 0 A FFFFFFFFFFFF -- key recovery against 1K, block 0, Key A using key FFFFFFFFFFFF"); + PrintAndLogEx(NORMAL, " hf mf staticnested 1 0 A FFFFFFFFFFFF t -- and transfer keys into emulator memory"); + PrintAndLogEx(NORMAL, " hf mf staticnested 1 0 A FFFFFFFFFFFF d -- or write keys to binary file "); + return PM3_SUCCESS; +} static int usage_hf14_hardnested(void) { PrintAndLogEx(NORMAL, "Usage:"); PrintAndLogEx(NORMAL, " hf mf hardnested "); @@ -1263,9 +1278,10 @@ static int CmdHF14AMfNested(const char *Cmd) { j++; } - // check if tag doesn't have static/fixed nonce + // check if tag doesn't have static nonce if (detect_classic_static_nonce() != 0) { - PrintAndLogEx(WARNING, "Static/fixed nonce detected. Quitting..."); + PrintAndLogEx(WARNING, "Static nonce detected. Quitting..."); + PrintAndLogEx(INFO, "\t Try use `" _YELLOW_("hf mf staticnested") "`"); return PM3_EOPABORTED; } @@ -1279,7 +1295,7 @@ static int CmdHF14AMfNested(const char *Cmd) { int16_t isOK = mfnested(blockNo, keyType, key, trgBlockNo, trgKeyType, keyBlock, true); switch (isOK) { case -1 : - PrintAndLogEx(ERR, "Error: No response from Proxmark3.\n"); + PrintAndLogEx(ERR, "Command execute timeout\n"); break; case -2 : PrintAndLogEx(WARNING, "Button pressed. Aborted.\n"); @@ -1314,7 +1330,7 @@ static int CmdHF14AMfNested(const char *Cmd) { } return PM3_SUCCESS; default : - PrintAndLogEx(ERR, "Unknown Error.\n"); + PrintAndLogEx(ERR, "Unknown error.\n"); } return PM3_SUCCESS; } else { // ------------------------------------ multiple sectors working @@ -1360,7 +1376,7 @@ static int CmdHF14AMfNested(const char *Cmd) { int16_t isOK = mfnested(blockNo, keyType, key, FirstBlockOfSector(sectorNo), trgKeyType, keyBlock, calibrate); switch (isOK) { case -1 : - PrintAndLogEx(ERR, "error: No response from Proxmark3.\n"); + PrintAndLogEx(ERR, "Command execute timeout\n"); break; case -2 : PrintAndLogEx(WARNING, "button pressed. Aborted.\n"); @@ -1382,7 +1398,7 @@ static int CmdHF14AMfNested(const char *Cmd) { continue; default : - PrintAndLogEx(ERR, "unknown Error.\n"); + PrintAndLogEx(ERR, "Unknown error.\n"); } free(e_sector); return PM3_ESOFT; @@ -1472,6 +1488,204 @@ jumptoend: return PM3_SUCCESS; } +static int CmdHF14AMfNestedStatic(const char *Cmd) { + sector_t *e_sector = NULL; + uint8_t keyType = 0; + uint8_t trgKeyType = 0; + uint8_t SectorsCnt = 0; + uint8_t key[6] = {0, 0, 0, 0, 0, 0}; + uint8_t keyBlock[(ARRAYLEN(g_mifare_default_keys) + 1) * 6]; + uint64_t key64 = 0; + bool transferToEml = false; + bool createDumpFile = false; + + if (strlen(Cmd) < 3) return usage_hf14_staticnested(); + + char cmdp, ctmp; + cmdp = tolower(param_getchar(Cmd, 0)); + uint8_t blockNo = param_get8(Cmd, 1); + ctmp = tolower(param_getchar(Cmd, 2)); + + if (ctmp != 'a' && ctmp != 'b') { + PrintAndLogEx(WARNING, "key type must be A or B"); + return PM3_EINVARG; + } + + if (ctmp != 'a') + keyType = 1; + + if (param_gethex(Cmd, 3, key, 12)) { + PrintAndLogEx(WARNING, "key must include 12 HEX symbols"); + return PM3_EINVARG; + } + + SectorsCnt = NumOfSectors(cmdp); + if (SectorsCnt == 0) return usage_hf14_staticnested(); + + uint8_t j = 4; + while (ctmp != 0x00) { + + ctmp = tolower(param_getchar(Cmd, j)); + transferToEml |= (ctmp == 't'); + createDumpFile |= (ctmp == 'd'); + + j++; + } + + // check if tag have static nonce + if (detect_classic_static_nonce() == 0) { + PrintAndLogEx(WARNING, "Normal nonce detected. Quitting..."); + return PM3_EOPABORTED; + } + + // check if we can authenticate to sector + if (mfCheckKeys(blockNo, keyType, true, 1, key, &key64) != PM3_SUCCESS) { + PrintAndLogEx(WARNING, "Wrong key. Can't authenticate to block:%3d key type:%c", blockNo, keyType ? 'B' : 'A'); + return PM3_EOPABORTED; + } + + uint64_t t1 = msclock(); + + e_sector = calloc(SectorsCnt, sizeof(sector_t)); + if (e_sector == NULL) return PM3_EMALLOC; + + // add our known key + e_sector[GetSectorFromBlockNo(blockNo)].foundKey[keyType] = 1; + e_sector[GetSectorFromBlockNo(blockNo)].Key[keyType] = key64; + + //test current key and additional standard keys first + // add parameter key + memcpy(keyBlock + (ARRAYLEN(g_mifare_default_keys) * 6), key, 6); + + for (int cnt = 0; cnt < ARRAYLEN(g_mifare_default_keys); cnt++) { + num_to_bytes(g_mifare_default_keys[cnt], 6, (uint8_t *)(keyBlock + cnt * 6)); + } + + PrintAndLogEx(SUCCESS, "Testing known keys. Sector count=%d", SectorsCnt); + int res = mfCheckKeys_fast(SectorsCnt, true, true, 1, ARRAYLEN(g_mifare_default_keys) + 1, keyBlock, e_sector, false); + if (res == PM3_SUCCESS) { + // all keys found + PrintAndLogEx(SUCCESS, "Fast check found all keys"); + goto jumptoend; + } + + uint64_t t2 = msclock() - t1; + PrintAndLogEx(SUCCESS, "Time to check %zu known keys: %.0f seconds\n", ARRAYLEN(g_mifare_default_keys), (float)t2 / 1000.0); + PrintAndLogEx(SUCCESS, "enter static nested attack"); + + // nested sectors + for (trgKeyType = 0; trgKeyType < 2; ++trgKeyType) { + for (uint8_t sectorNo = 0; sectorNo < SectorsCnt; ++sectorNo) { + + for (int i = 0; i < 1; i++) { + + if (e_sector[sectorNo].foundKey[trgKeyType]) continue; + + int16_t isOK = mfStaticNested(blockNo, keyType, key, FirstBlockOfSector(sectorNo), trgKeyType, keyBlock); + switch (isOK) { + case PM3_ETIMEOUT : + PrintAndLogEx(ERR, "Command execute timeout"); + break; + case PM3_ESOFT : + continue; + case PM3_SUCCESS : + e_sector[sectorNo].foundKey[trgKeyType] = 1; + e_sector[sectorNo].Key[trgKeyType] = bytes_to_num(keyBlock, 6); + + mfCheckKeys_fast(SectorsCnt, true, true, 2, 1, keyBlock, e_sector, false); + continue; + default : + PrintAndLogEx(ERR, "unknown error.\n"); + } + free(e_sector); + return PM3_ESOFT; + } + } + } + + t1 = msclock() - t1; + PrintAndLogEx(SUCCESS, "time in static nested: %.0f seconds\n", (float)t1 / 1000.0); + + + // 20160116 If Sector A is found, but not Sector B, try just reading it of the tag? + PrintAndLogEx(INFO, "trying to read key B..."); + for (int i = 0; i < SectorsCnt; i++) { + // KEY A but not KEY B + if (e_sector[i].foundKey[0] && !e_sector[i].foundKey[1]) { + + uint8_t sectrail = (FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1); + + PrintAndLogEx(SUCCESS, "reading block %d", sectrail); + + mf_readblock_t payload; + payload.blockno = sectrail; + payload.keytype = 0; + + num_to_bytes(e_sector[i].Key[0], 6, payload.key); // KEY A + + clearCommandBuffer(); + SendCommandNG(CMD_HF_MIFARE_READBL, (uint8_t *)&payload, sizeof(mf_readblock_t)); + + PacketResponseNG resp; + if (!WaitForResponseTimeout(CMD_HF_MIFARE_READBL, &resp, 1500)) continue; + + if (resp.status != PM3_SUCCESS) continue; + + uint8_t *data = resp.data.asBytes; + key64 = bytes_to_num(data + 10, 6); + if (key64) { + PrintAndLogEx(SUCCESS, "data: %s", sprint_hex(data + 10, 6)); + e_sector[i].foundKey[1] = true; + e_sector[i].Key[1] = key64; + } + } + } + +jumptoend: + + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "found keys:"); + + //print them + printKeyTable(SectorsCnt, e_sector); + + // transfer them to the emulator + if (transferToEml) { + // fast push mode + conn.block_after_ACK = true; + for (int i = 0; i < SectorsCnt; i++) { + mfEmlGetMem(keyBlock, FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1, 1); + + if (e_sector[i].foundKey[0]) + num_to_bytes(e_sector[i].Key[0], 6, keyBlock); + + if (e_sector[i].foundKey[1]) + num_to_bytes(e_sector[i].Key[1], 6, &keyBlock[10]); + + if (i == SectorsCnt - 1) { + // Disable fast mode on last packet + conn.block_after_ACK = false; + } + mfEmlSetMem(keyBlock, FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1, 1); + } + PrintAndLogEx(SUCCESS, "keys transferred to emulator memory."); + } + + // Create dump file + if (createDumpFile) { + char *fptr = GenerateFilename("hf-mf-", "-key.bin"); + if (createMfcKeyDump(fptr, SectorsCnt, e_sector) != PM3_SUCCESS) { + PrintAndLogEx(ERR, "Failed to save keys to file"); + free(e_sector); + return PM3_ESOFT; + } + } + free(e_sector); + + return PM3_SUCCESS; +} + + static int CmdHF14AMfNestedHard(const char *Cmd) { uint8_t blockNo = 0; uint8_t keyType = 0; @@ -1617,9 +1831,10 @@ static int CmdHF14AMfNestedHard(const char *Cmd) { if (!know_target_key && nonce_file_read == false) { - // check if tag doesn't have static/fixed nonce + // check if tag doesn't have static nonce if (detect_classic_static_nonce() != 0) { - PrintAndLogEx(WARNING, "Static/fixed nonce detected. Quitting..."); + PrintAndLogEx(WARNING, "Static nonce detected. Quitting..."); + PrintAndLogEx(INFO, "\t Try use `" _YELLOW_("hf mf staticnested") "`"); return PM3_EOPABORTED; } @@ -4587,7 +4802,7 @@ static command_t CommandTable[] = { {"darkside", CmdHF14AMfDarkside, IfPm3Iso14443a, "Darkside attack"}, {"nested", CmdHF14AMfNested, IfPm3Iso14443a, "Nested attack"}, {"hardnested", CmdHF14AMfNestedHard, AlwaysAvailable, "Nested attack for hardened MIFARE Classic cards"}, -// {"fixednested", CmdHF14AMfNestedFixed, IfPm3Iso14443a, "Nested attack against static/fixed nonce Mifare Classic cards"}, + {"staticnested", CmdHF14AMfNestedStatic, IfPm3Iso14443a, "Nested attack against static nonce Mifare Classic cards"}, {"autopwn", CmdHF14AMfAutoPWN, IfPm3Iso14443a, "Automatic key recovery tool for MIFARE Classic"}, // {"keybrute", CmdHF14AMfKeyBrute, IfPm3Iso14443a, "J_Run's 2nd phase of multiple sector nested authentication key recovery"}, {"nack", CmdHf14AMfNack, IfPm3Iso14443a, "Test for MIFARE NACK bug"}, diff --git a/client/mifare/mifarehost.c b/client/mifare/mifarehost.c index 4b29920ee..a4169baa5 100644 --- a/client/mifare/mifarehost.c +++ b/client/mifare/mifarehost.c @@ -470,7 +470,7 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, for (int j = 0; j < size; j++) { crypto1_get_lfsr(statelists[0].head.slhead + i, &key64); - num_to_bytes(key64, 6, keyBlock + i * 6); + num_to_bytes(key64, 6, keyBlock + j * 6); } if (mfCheckKeys(statelists[0].blockNo, statelists[0].keyType, false, size, keyBlock, &key64) == PM3_SUCCESS) { @@ -498,6 +498,137 @@ out: return -4; } +int mfStaticNested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t *resultKey) { + uint16_t i; + uint32_t uid; + StateList_t statelists[1]; + struct Crypto1State *p1, *p3; + + struct { + uint8_t block; + uint8_t keytype; + uint8_t target_block; + uint8_t target_keytype; + uint8_t key[6]; + } PACKED payload; + payload.block = blockNo; + payload.keytype = keyType; + payload.target_block = trgBlockNo; + payload.target_keytype = trgKeyType; + memcpy(payload.key, key, sizeof(payload.key)); + + PacketResponseNG resp; + clearCommandBuffer(); + SendCommandNG(CMD_HF_MIFARE_STATIC_NESTED, (uint8_t *)&payload, sizeof(payload)); + + if (!WaitForResponseTimeout(CMD_HF_MIFARE_STATIC_NESTED, &resp, 2000)) + return PM3_ETIMEOUT; + + if (resp.status != PM3_SUCCESS) + return resp.status; + + struct p { + int16_t isOK; + uint8_t block; + uint8_t keytype; + uint8_t cuid[4]; + uint8_t nt[4]; + uint8_t ks[4]; + } PACKED; + struct p *package = (struct p *)resp.data.asBytes; + + // error during collecting static nested information + if (package->isOK == 0) return PM3_EUNDEF; + + memcpy(&uid, package->cuid, sizeof(package->cuid)); + + statelists[0].blockNo = package->block; + statelists[0].keyType = package->keytype; + statelists[0].uid = uid; + + memcpy(&statelists[0].nt_enc, package->nt, sizeof(package->nt)); + memcpy(&statelists[0].ks1, package->ks, sizeof(package->ks)); + + // calc keys + pthread_t t; + + // create and run worker thread + pthread_create(&t, NULL, nested_worker_thread, &statelists[0]); + + // wait for thread to terminate: + pthread_join(t, (void *)&statelists[0].head.slhead); + + // the first 16 Bits of the cryptostate already contain part of our key. + p1 = p3 = statelists[0].head.slhead; + + // create key candidates. + while (p1 <= statelists[0].tail.sltail) { + struct Crypto1State savestate; + savestate = *p1; + while (Compare16Bits(p1, &savestate) == 0 && p1 <= statelists[0].tail.sltail) { + *p3 = *p1; + lfsr_rollback_word(p3, statelists[0].nt_enc ^ statelists[0].uid, 0); + p3++; + p1++; + } + } + + *(uint64_t *)p3 = -1; + statelists[0].len = p3 - statelists[0].head.slhead; + statelists[0].tail.sltail = --p3; + + uint32_t keycnt = statelists[0].len; + if (keycnt == 0) goto out; + + PrintAndLogEx(SUCCESS, "Found %3u candidate keys", keycnt); + + memset(resultKey, 0, 6); + uint64_t key64 = -1; + + // The list may still contain several key candidates. Test each of them with mfCheckKeys + uint32_t max_keys_slice = keycnt > KEYS_IN_BLOCK ? KEYS_IN_BLOCK : keycnt; + uint8_t keyBlock[PM3_CMD_DATA_SIZE] = {0x00}; + + for (i = 0; i < keycnt; i += max_keys_slice) { + + PrintAndLogEx(INFO, "Testing %u/%u ", i, keycnt); + + key64 = 0; + + int size = keycnt - i > max_keys_slice ? max_keys_slice : keycnt - i; + + // copy x keys to device. + for (int j = 0; j < size; j++) { + crypto1_get_lfsr(statelists[0].head.slhead + i + j, &key64); + num_to_bytes(key64, 6, keyBlock + j * 6); + } + + // check a block of generated candidate keys. + if (mfCheckKeys(statelists[0].blockNo, statelists[0].keyType, false, size, keyBlock, &key64) == PM3_SUCCESS) { + + free(statelists[0].head.slhead); + + num_to_bytes(key64, 6, resultKey); + + PrintAndLogEx(SUCCESS, "target block:%3u key type: %c -- found valid key [ " _YELLOW_("%s") "]", + package->block, + package->keytype ? 'B' : 'A', + sprint_hex(resultKey, 6) + ); + return PM3_SUCCESS; + } + } + +out: + PrintAndLogEx(SUCCESS, "target block:%3u key type: %c", + package->block, + package->keytype ? 'B' : 'A' + ); + + free(statelists[0].head.slhead); + + return PM3_ESOFT; +} // MIFARE int mfReadSector(uint8_t sectorNo, uint8_t keyType, uint8_t *key, uint8_t *data) { diff --git a/client/mifare/mifarehost.h b/client/mifare/mifarehost.h index a17e4b099..846ee4222 100644 --- a/client/mifare/mifarehost.h +++ b/client/mifare/mifarehost.h @@ -61,6 +61,7 @@ extern char logHexFileName[FILE_PATH_SIZE]; int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key); int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t *resultKey, bool calibrate); +int mfStaticNested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t *resultKey); int mfCheckKeys(uint8_t blockNo, uint8_t keyType, bool clear_trace, uint8_t keycnt, uint8_t *keyBlock, uint64_t *key); int mfCheckKeys_fast(uint8_t sectorsCnt, uint8_t firstChunk, uint8_t lastChunk, uint8_t strategy, uint32_t size, uint8_t *keyBlock, sector_t *e_sector, bool use_flashmemory); diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index ac397ff61..7ae6f0779 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -488,6 +488,7 @@ typedef struct { #define CMD_HF_MIFARE_NESTED 0x0612 #define CMD_HF_MIFARE_ACQ_ENCRYPTED_NONCES 0x0613 #define CMD_HF_MIFARE_ACQ_NONCES 0x0614 +#define CMD_HF_MIFARE_STATIC_NESTED 0x0615 #define CMD_HF_MIFARE_READBL 0x0620 #define CMD_HF_MIFAREU_READBL 0x0720 From 32fdde3d00924abf41a3620d5c85ce28e924679a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 14 Jan 2020 17:22:59 +0100 Subject: [PATCH 1440/1854] fix: 'lf indala read' - adapted the long id detection to be less picky --- client/cmdlfindala.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/client/cmdlfindala.c b/client/cmdlfindala.c index 368e182d7..9aa98524c 100644 --- a/client/cmdlfindala.c +++ b/client/cmdlfindala.c @@ -31,7 +31,7 @@ static int CmdHelp(const char *Cmd); //large 224 bit indala formats (different preamble too...) -static uint8_t preamble224[] = {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}; +static uint8_t preamble224[] = {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // standard 64 bit indala formats including 26 bit 40134 format static uint8_t preamble64[] = {1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}; @@ -649,8 +649,7 @@ int CmdLFINDALA(const char *Cmd) { int detectIndala(uint8_t *dest, size_t *size, uint8_t *invert) { uint8_t preamble64_i[] = {0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}; - uint8_t preamble224_i[] = {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}; - + uint8_t preamble224_i[] = {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; size_t idx = 0; size_t found_size = *size; From 2f86ca19d20f797627e38085395702da98e622bd Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 14 Jan 2020 17:24:24 +0100 Subject: [PATCH 1441/1854] textual --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 91d585f28..10e90cc71 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Fix `lf indala read` - long id 224bits preamble identification less strict (@iceman1001) - Added `hf mf staticnested` - useful when targeting the strange cards with a static nonce. (@iceman100) Thanks to @xtigmh @uzlonewolf for their solutions. - Added `hf plot` (@pwpiwi) - Fix `lf config` - when called with no params, it no longer mess up all device lf config settings. (@iceman1001) From b299a31ad791346b6510e1b20a8cfd7e1f9a4acc Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 14 Jan 2020 19:44:29 +0100 Subject: [PATCH 1442/1854] Added: 'lf nextwatch sim' - use rawhex to simulate --- CHANGELOG.md | 1 + client/cmdlfnexwatch.c | 96 ++++++++++++++++++++++++++++++++++++------ 2 files changed, 85 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 10e90cc71..06d3005be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Added `lf nexwatch sim` - use raw hex to simulate (@iceman1001) - Fix `lf indala read` - long id 224bits preamble identification less strict (@iceman1001) - Added `hf mf staticnested` - useful when targeting the strange cards with a static nonce. (@iceman100) Thanks to @xtigmh @uzlonewolf for their solutions. - Added `hf plot` (@pwpiwi) diff --git a/client/cmdlfnexwatch.c b/client/cmdlfnexwatch.c index 58ec81852..69f429ab6 100644 --- a/client/cmdlfnexwatch.c +++ b/client/cmdlfnexwatch.c @@ -10,17 +10,19 @@ #include "cmdlfnexwatch.h" #include // PRIu +#include #include // tolower +#include // free, alloc #include "commonutil.h" // ARRAYLEN -#include "cmdparser.h" // command_t +#include "cmdparser.h" // command_t #include "comms.h" #include "ui.h" -#include "cmddata.h" // preamblesearch +#include "cmddata.h" // preamblesearch #include "cmdlf.h" #include "lfdemod.h" -#include "protocols.h" // t55xx defines -#include "cmdlft55xx.h" // clone.. +#include "protocols.h" // t55xx defines +#include "cmdlft55xx.h" // clone.. static int CmdHelp(const char *Cmd); @@ -29,16 +31,30 @@ static int usage_lf_nexwatch_clone(void) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Usage: lf nexwatch clone [h] [b ]"); PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " h : this help"); - PrintAndLogEx(NORMAL, " b : raw hex data. 12 bytes max"); + PrintAndLogEx(NORMAL, " h : this help"); + PrintAndLogEx(NORMAL, " r : raw hex data. 16 bytes max"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " lf nexwatch clone b 5600000000213C9F8F150C0000000000"); + PrintAndLogEx(NORMAL, " lf nexwatch clone r 5600000000213C9F8F150C0000000000"); + return PM3_SUCCESS; +} + +static int usage_lf_nexwatch_sim(void) { + PrintAndLogEx(NORMAL, "Enables simulation of Nexwatch card"); + PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued."); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Usage: lf nexwatch sim [h] "); + PrintAndLogEx(NORMAL, "Options:"); + PrintAndLogEx(NORMAL, " h : this help"); + PrintAndLogEx(NORMAL, " r : raw hex data. 16 bytes max"); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Examples:"); + PrintAndLogEx(NORMAL, " lf nexwatch sim r 5600000000213C9F8F150C0000000000"); return PM3_SUCCESS; } static int CmdNexWatchDemod(const char *Cmd) { - (void)Cmd; // Cmd is not used so far + (void)Cmd; if (PSKDemod("", false) != PM3_SUCCESS) { PrintAndLogEx(DEBUG, "DEBUG: Error - NexWatch can't demod signal"); @@ -88,14 +104,17 @@ static int CmdNexWatchDemod(const char *Cmd) { DemodBuffer[i] ^= 1; } + // bits to hex CmdPrintDemodBuff("x"); + //PrintAndLogEx(INFO, "Raw: %s", sprint_hex_inrow(DemodBuffer, DemodBufferLen)); + return PM3_SUCCESS; } //by marshmellow //see ASKDemod for what args are accepted static int CmdNexWatchRead(const char *Cmd) { - lf_read(false, 10000); + lf_read(false, 20000); return CmdNexWatchDemod(Cmd); } @@ -111,7 +130,7 @@ static int CmdNexWatchClone(const char *Cmd) { switch (tolower(param_getchar(Cmd, cmdp))) { case 'h': return usage_lf_nexwatch_clone(); - case 'b': { + case 'r': { // skip first block, 4*4 = 16 bytes left uint8_t rawhex[16] = {0}; int res = param_gethex_to_eol(Cmd, cmdp + 1, rawhex, sizeof(rawhex), &datalen); @@ -144,11 +163,64 @@ static int CmdNexWatchClone(const char *Cmd) { } static int CmdNexWatchSim(const char *Cmd) { - PrintAndLogEx(INFO, " To be implemented, feel free to contribute!"); + + uint8_t cmdp = 0; + bool errors = false; + int rawlen = 0; + uint8_t rawhex[16] = {0}; + uint32_t rawblocks[4]; + uint8_t bs[128]; + memset(bs, 0, sizeof(bs)); + + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { + case 'h': + return usage_lf_nexwatch_clone(); + case 'r': { + int res = param_gethex_to_eol(Cmd, cmdp + 1, rawhex, sizeof(rawhex), &rawlen); + if (res != 0) + errors = true; + + cmdp += 2; + break; + } + default: + PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } + } + + if (errors || cmdp == 0) return usage_lf_nexwatch_sim(); + + // hex to bits. + for (size_t i = 0; i < ARRAYLEN(rawblocks); i++) { + rawblocks[i] = bytes_to_num(rawhex + (i * sizeof(uint32_t)), sizeof(uint32_t)); + num_to_bytebits(rawblocks[i], sizeof(uint32_t) * 8, bs + (i * sizeof(uint32_t) * 8)); + } + + PrintAndLogEx(SUCCESS, "Simulating NexWatch - raw: %s", sprint_hex_inrow(rawhex, rawlen)); + + lf_psksim_t *payload = calloc(1, sizeof(lf_psksim_t) + sizeof(bs)); + payload->carrier = 2; + payload->invert = 0; + payload->clock = 32; + memcpy(payload->data, bs, sizeof(bs)); + + clearCommandBuffer(); + SendCommandNG(CMD_LF_PSK_SIMULATE, (uint8_t *)payload, sizeof(lf_psksim_t) + sizeof(bs)); + free(payload); + + PacketResponseNG resp; + WaitForResponse(CMD_LF_PSK_SIMULATE, &resp); + + PrintAndLogEx(INFO, "Done"); + if (resp.status != PM3_EOPABORTED) + return resp.status; + return PM3_SUCCESS; } - static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, {"demod", CmdNexWatchDemod, AlwaysAvailable, "Demodulate a NexWatch tag (nexkey, quadrakey) from the GraphBuffer"}, From e5a1861552713009be7ff51be94ee6e6a340f3de Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 14 Jan 2020 21:17:35 +0100 Subject: [PATCH 1443/1854] textual --- client/mifare/mifarehost.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/client/mifare/mifarehost.c b/client/mifare/mifarehost.c index a4169baa5..795d9eec7 100644 --- a/client/mifare/mifarehost.c +++ b/client/mifare/mifarehost.c @@ -125,7 +125,7 @@ int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) { } } - PrintAndLogEx(SUCCESS, "found %u candidate key%s\n", keycount, (keycount > 1) ? "s." : "."); + PrintAndLogEx(SUCCESS, "found " _YELLOW_("%u") "candidate key%s\n", keycount, (keycount > 1) ? "s." : "."); *key = UINT64_C(-1); uint8_t keyBlock[PM3_CMD_DATA_SIZE]; @@ -478,10 +478,10 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, free(statelists[1].head.slhead); num_to_bytes(key64, 6, resultKey); - PrintAndLogEx(SUCCESS, "target block:%3u key type: %c -- found valid key [ " _YELLOW_("%s") "]", + PrintAndLogEx(SUCCESS, "target block:%3u key type: %c -- found valid key [ " _YELLOW_("%s") "]", package->block, package->keytype ? 'B' : 'A', - sprint_hex(resultKey, 6) + sprint_hex_inrow(resultKey, 6) ); return -5; } @@ -580,7 +580,7 @@ int mfStaticNested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBl uint32_t keycnt = statelists[0].len; if (keycnt == 0) goto out; - PrintAndLogEx(SUCCESS, "Found %3u candidate keys", keycnt); + PrintAndLogEx(SUCCESS, "Found " _YELLOW_("%u") "candidate keys", keycnt); memset(resultKey, 0, 6); uint64_t key64 = -1; @@ -591,7 +591,7 @@ int mfStaticNested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBl for (i = 0; i < keycnt; i += max_keys_slice) { - PrintAndLogEx(INFO, "Testing %u/%u ", i, keycnt); + PrintAndLogEx(INFO, "Testing %u / %u ", i, keycnt); key64 = 0; @@ -610,10 +610,10 @@ int mfStaticNested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBl num_to_bytes(key64, 6, resultKey); - PrintAndLogEx(SUCCESS, "target block:%3u key type: %c -- found valid key [ " _YELLOW_("%s") "]", + PrintAndLogEx(SUCCESS, "target block:%3u key type: %c -- found valid key [ " _YELLOW_("%s") "]", package->block, package->keytype ? 'B' : 'A', - sprint_hex(resultKey, 6) + sprint_hex_inrow(resultKey, 6) ); return PM3_SUCCESS; } From d956e8c2a30d4f74f270da1d84b5ff71d4246757 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 14 Jan 2020 21:17:56 +0100 Subject: [PATCH 1444/1854] textual --- client/cmdhfmf.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index e8e27793b..d48a1fe1e 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -571,7 +571,7 @@ static int CmdHF14AMfDarkside(const char *Cmd) { PrintAndLogEx(WARNING, "aborted via keyboard."); return 1; default : - PrintAndLogEx(SUCCESS, "found valid key: %012" PRIx64 "\n", key); + PrintAndLogEx(SUCCESS, "found valid key: "_YELLOW_("%012" PRIx64), key); break; } PrintAndLogEx(NORMAL, ""); @@ -1281,7 +1281,7 @@ static int CmdHF14AMfNested(const char *Cmd) { // check if tag doesn't have static nonce if (detect_classic_static_nonce() != 0) { PrintAndLogEx(WARNING, "Static nonce detected. Quitting..."); - PrintAndLogEx(INFO, "\t Try use `" _YELLOW_("hf mf staticnested") "`"); + PrintAndLogEx(INFO, "\t Try use " _YELLOW_("`hf mf staticnested`")); return PM3_EOPABORTED; } @@ -1534,7 +1534,8 @@ static int CmdHF14AMfNestedStatic(const char *Cmd) { // check if tag have static nonce if (detect_classic_static_nonce() == 0) { - PrintAndLogEx(WARNING, "Normal nonce detected. Quitting..."); + PrintAndLogEx(WARNING, "None static nonce detected. Quitting..."); + PrintAndLogEx(INFO, "\t Try use " _YELLOW_("`hf mf nested`")); return PM3_EOPABORTED; } @@ -1685,7 +1686,6 @@ jumptoend: return PM3_SUCCESS; } - static int CmdHF14AMfNestedHard(const char *Cmd) { uint8_t blockNo = 0; uint8_t keyType = 0; From 89bae75c55d0427f70d7b54fd484498cc31121c4 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 14 Jan 2020 22:08:43 +0100 Subject: [PATCH 1445/1854] hitag signal refactoring --- armsrc/Makefile | 2 +- armsrc/hitag2.c | 821 ++++++++++++++++++++++++++------------------ armsrc/hitag2.h | 2 +- armsrc/lfadc.c | 4 +- armsrc/lfsampling.c | 16 +- client/cmdlfhitag.c | 7 +- include/hitag.h | 11 + 7 files changed, 523 insertions(+), 340 deletions(-) diff --git a/armsrc/Makefile b/armsrc/Makefile index beb19c243..12819c3d0 100644 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@ -23,7 +23,7 @@ APP_CFLAGS = $(PLATFORM_DEFS) \ -DON_DEVICE \ -fno-strict-aliasing -ffunction-sections -fdata-sections -SRC_LF = lfops.c lfsampling.c pcf7931.c lfdemod.c +SRC_LF = lfops.c lfsampling.c pcf7931.c lfdemod.c lfadc.c SRC_ISO15693 = iso15693.c iso15693tools.c SRC_ISO14443a = iso14443a.c mifareutil.c mifarecmd.c epa.c mifaresim.c #UNUSED: mifaresniff.c desfire_crypto.c diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index 3531ac9ea..60cd76416 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -16,7 +16,8 @@ // (c) 2012 Roel Verdult //----------------------------------------------------------------------------- // Piwi, 2019 -// Iceman, 2019 +// Iceman, 2019 +// Anon, 2019 #include "hitag2.h" #include "hitag2_crypto.h" @@ -28,12 +29,18 @@ #include "ticks.h" #include "dbprint.h" #include "util.h" +#include "lfadc.h" +#include "lfsampling.h" +#include "lfdemod.h" +#include "commonutil.h" // Successful crypto auth static bool bCrypto; // Is in auth stage static bool bAuthenticating; // Successful password auth +bool bSelecting; +bool bCollision; static bool bPwd; static bool bSuccessful; @@ -52,6 +59,7 @@ static struct hitag2_tag tag = { [9] = { 0x00, 0x00, 0x00, 0x00}, // RSK High [10] = { 0x00, 0x00, 0x00, 0x00}, // RCF [11] = { 0x00, 0x00, 0x00, 0x00}, // SYNC + // up to index 15 reserved for HITAG1/HITAGS public data }, }; @@ -73,6 +81,9 @@ static uint8_t password[4]; static uint8_t NrAr[8]; static uint8_t key[8]; static uint8_t writedata[4]; +uint8_t logdata_0[4], logdata_1[4]; +uint8_t nonce[4]; +bool key_no; static uint64_t cipher_state; static int hitag2_reset(void) { @@ -288,29 +299,26 @@ static void hitag2_handle_reader_command(uint8_t *rx, const size_t rxlen, uint8_ // sim static void hitag_reader_send_bit(int bit) { LED_A_ON(); - // Reset clock for the next bit - AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; - - // Binary puls length modulation (BPLM) is used to encode the data stream + // Binary pulse length modulation (BPLM) is used to encode the data stream // This means that a transmission of a one takes longer than that of a zero - // Enable modulation, which means, drop the field - HIGH(GPIO_SSC_DOUT); + // Enable modulation, which means, drop the field + lf_modulation(true); // Wait for 4-10 times the carrier period - while (AT91C_BASE_TC0->TC_CV < T0 * 6) {}; + lf_wait_periods(8); // wait for 4-10 times the carrier period // Disable modulation, just activates the field again - LOW(GPIO_SSC_DOUT); + lf_modulation(false); if (bit == 0) { // Zero bit: |_-| - while (AT91C_BASE_TC0->TC_CV < T0 * 22) {}; - + lf_wait_periods(12); // wait for 18-22 times the carrier period } else { // One bit: |_--| - while (AT91C_BASE_TC0->TC_CV < T0 * 28) {}; + lf_wait_periods(22); // wait for 26-32 times the carrier period } + /*lf_wait_periods(10);*/ LED_A_OFF(); } @@ -320,18 +328,243 @@ static void hitag_reader_send_frame(const uint8_t *frame, size_t frame_len) { for (size_t i = 0; i < frame_len; i++) { hitag_reader_send_bit((frame[i / 8] >> (7 - (i % 8))) & 1); } - // Send EOF - AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; - // Enable modulation, which means, drop the field - HIGH(GPIO_SSC_DOUT); + // Enable modulation, which means, drop the field + lf_modulation(true); // Wait for 4-10 times the carrier period - while (AT91C_BASE_TC0->TC_CV < T0 * 6) {}; + lf_wait_periods(8); // Disable modulation, just activates the field again - LOW(GPIO_SSC_DOUT); + lf_modulation(false); + + // t_stop, high field for stop condition (> 36) + lf_wait_periods(28); } size_t blocknr; +uint8_t hitag_crc(uint8_t *data, size_t length){ + uint8_t crc = 0xff; + unsigned int byte, bit; + for(byte=0; byte<((length+7)/8); byte++){ + crc ^= *(data + byte); + bit = length < (8*(byte+1)) ? (length % 8) : 8; + while(bit--){ + if(crc & 0x80){ + crc<<=1; + crc ^= 0x1d; + } else { + crc<<=1; + } + } + } + return crc; +} + +#define test_bit(data, i) (*(data+(i/8)) >> (7-(i%8))) & 1 +#define set_bit(data, i) *(data+(i/8)) |= (1 << (7-(i%8))) +#define clear_bit(data, i) *(data+(i/8)) &= ~(1 << (7-(i%8))) +#define flip_bit(data, i) *(data+(i/8)) ^= (1 << (7-(i%8))) +void fix_ac_decoding(uint8_t *input, size_t len){ + // Reader routine tries to decode AC data after Manchester decoding + // AC has double the bitrate, extract data from bit-pairs + uint8_t temp[len / 16]; + memset(temp, 0, sizeof(temp)); + + for (size_t i = 1; i < len; i += 2) { + if (test_bit(input, i) && test_bit(input, (i + 1))){ + set_bit(temp, (i / 2)); + } + } + memcpy(input, temp, sizeof(temp)); +} + +bool hitag_plain(uint8_t* rx, const size_t rxlen, uint8_t* tx, size_t* txlen, bool hitag_s) { + uint8_t crc; + *txlen = 0; + switch (rxlen) { + case 0: { + // retry waking up card + /*tx[0] = 0xb0; // Rev 3.0*/ + tx[0] = 0x30; // Rev 2.0 + *txlen = 5; + if(!bCollision) blocknr--; + if(blocknr < 0) { + blocknr = 0; + } + if(!hitag_s){ + if (blocknr > 1 && blocknr < 31) { + blocknr=31; + } + } + bCollision = true; + return true; + } + case 32: { + if(bCollision){ + // Select card by serial from response + tx[0] = 0x00 | rx[0] >> 5; + tx[1] = rx[0] << 3 | rx[1] >> 5; + tx[2] = rx[1] << 3 | rx[2] >> 5; + tx[3] = rx[2] << 3 | rx[3] >> 5; + tx[4] = rx[3] << 3; + crc = hitag_crc(tx,37); + tx[4] |= crc >> 5; + tx[5] = crc << 3; + *txlen = 45; + bCollision = false; + } else { + memcpy(tag.sectors[blocknr], rx, 4); + blocknr++; + if(!hitag_s){ + if (blocknr > 1 && blocknr < 31) { + blocknr=31; + } + } + if (blocknr > 63) { + DbpString("Read succesful!"); + *txlen = 0; + bSuccessful = true; + return false; + } + // read next page of card until done + Dbprintf("Reading page %02u", blocknr); + tx[0] = 0xc0 | blocknr >> 4; // RDPPAGE + tx[1] = blocknr << 4; + crc = hitag_crc(tx,12); + tx[1] |= crc >> 4; + tx[2] = crc << 4; + *txlen = 20; + } + } break; + default: { + Dbprintf("Uknown frame length: %d",rxlen); + return false; + } break; + } + return true; +} + +size_t flipped_bit = 0; + +uint32_t byte_value = 0; +bool hitag1_authenticate(uint8_t* rx, const size_t rxlen, uint8_t* tx, size_t* txlen) { + uint8_t crc; + *txlen = 0; + switch (rxlen) { + case 0: { + // retry waking up card + /*tx[0] = 0xb0; // Rev 3.0*/ + tx[0] = 0x30; // Rev 2.0 + *txlen = 5; + if (bCrypto && byte_value <= 0xff){ + // to retry + bCrypto = false; + } + if(!bCollision) blocknr--; + if(blocknr < 0) { + blocknr = 0; + } + bCollision = true; + // will receive 32-bit UID + } break; + case 2: { + if (bAuthenticating) { + // received Auth init ACK, send nonce + // TODO Roel, bit-manipulation goes here + /*nonce[0] = 0x2d;*/ + /*nonce[1] = 0x74;*/ + /*nonce[2] = 0x80;*/ + /*nonce[3] = 0xa5;*/ + nonce[0]=byte_value; + byte_value++; + /*set_bit(nonce,flipped_bit);*/ + memcpy(tx,nonce,4); + *txlen = 32; + // will receive 32 bit encrypted Logdata + } else if (bCrypto) { + // authed, start reading + tx[0] = 0xe0 | blocknr >> 4; // RDCPAGE + tx[1] = blocknr << 4; + crc = hitag_crc(tx,12); + tx[1] |= crc >> 4; + tx[2] = crc << 4; + *txlen = 20; + // will receive 32-bit encrypted page + } + } break; + case 32: { + if (bCollision){ + // Select card by serial from response + tx[0] = 0x00 | rx[0] >> 5; + tx[1] = rx[0] << 3 | rx[1] >> 5; + tx[2] = rx[1] << 3 | rx[2] >> 5; + tx[3] = rx[2] << 3 | rx[3] >> 5; + tx[4] = rx[3] << 3; + crc = hitag_crc(tx,37); + tx[4] |= crc >> 5; + tx[5] = crc << 3; + *txlen = 45; + bCollision = false; + bSelecting = true; + // will receive 32-bit configuration page + } else if (bSelecting){ + // Initiate auth + tx[0] = 0xa0 | key_no >> 4; // WRCPAGE + tx[1] = blocknr << 4; + crc = hitag_crc(tx,12); + tx[1] |= crc >> 4; + tx[2] = crc << 4; + *txlen = 20; + bSelecting = false; + bAuthenticating = true; + // will receive 2-bit ACK + } else if (bAuthenticating) { + // received 32-bit logdata 0 + // TODO decrypt logdata 0, verify against logdata_0 + memcpy(tag.sectors[0], rx, 4); + memcpy(tag.sectors[1], tx, 4); + Dbprintf("%02x%02x%02x%02x %02x%02x%02x%02x", rx[0], rx[1], rx[2], rx[3], tx[0], tx[1], tx[2], tx[3]); + // TODO replace with secret data stream + // TODO encrypt logdata_1 + memcpy(tx,logdata_1,4); + *txlen = 32; + bAuthenticating = false; + bCrypto = true; + // will receive 2-bit ACK + } else if (bCrypto) { + // received 32-bit encrypted page + // TODO decrypt rx + memcpy(tag.sectors[blocknr],rx,4); + blocknr++; + if (blocknr > 63) { + DbpString("Read succesful!"); + bSuccessful = true; + return false; + } + + // TEST + Dbprintf("Succesfully authenticated with logdata:"); + Dbhexdump(4,logdata_1,false); + bSuccessful = true; + return false; + + // read next page of card until done + tx[0] = 0xe0 | blocknr >> 4; // RDCPAGE + tx[1] = blocknr << 4; + crc = hitag_crc(tx,12); + tx[1] |= crc >> 4; + tx[2] = crc << 4; + *txlen = 20; + } + } break; + default: { + Dbprintf("Uknown frame length: %d",rxlen); + return false; + } break; + } + + return true; +} + //----------------------------------------------------------------------------- // Hitag2 operations //----------------------------------------------------------------------------- @@ -686,9 +919,11 @@ static bool hitag2_read_uid(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t // Store the received block memcpy(tag.sectors[blocknr], rx, 4); blocknr++; + + Dbhexdump(4, rx, false); } if (blocknr > 0) { - // DbpString("Read successful!"); + DbpString("Read successful!"); bSuccessful = true; return false; } @@ -705,21 +940,11 @@ static bool hitag2_read_uid(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t } // Hitag2 Sniffing -void SniffHitag(void) { +void SniffHitag(uint32_t type) { + LEDsoff(); StopTicks(); - - // int frame_count; - int response; - int overflow; - bool rising_edge; - bool reader_frame; - int lastbit; - bool bSkip; - int tag_sof; - uint8_t rx[HITAG_FRAME_LEN]; - size_t rxlen = 0; - + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); BigBuf_free(); BigBuf_Clear_ext(false); @@ -735,143 +960,41 @@ void SniffHitag(void) { DbpString("Starting Hitag2 sniffing"); LED_D_ON(); - // Set up eavesdropping mode, frequency divisor which will drive the FPGA - // and analog mux selection. - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_TOGGLE_MODE); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, LF_DIVISOR_125); - SetAdcMuxFor(GPIO_MUXSEL_LOPKD); + lf_init(false); + logging = false; - // Configure output pin that is connected to the FPGA (for modulating) - AT91C_BASE_PIOA->PIO_OER |= GPIO_SSC_DOUT; - AT91C_BASE_PIOA->PIO_PER |= GPIO_SSC_DOUT; - - // Disable modulation, we are going to eavesdrop, not modulate ;) - LOW(GPIO_SSC_DOUT); - - // Enable Peripheral Clock for TIMER_CLOCK1, used to capture edges of the reader frames - AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC1); - AT91C_BASE_PIOA->PIO_BSR = GPIO_SSC_FRAME; - - // Disable timer during configuration - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; - - // TC1: Capture mode, default timer source = MCK/2 (TIMER_CLOCK1), TIOA is external trigger, - // external trigger rising edge, load RA on rising edge of TIOA. - AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK | AT91C_TC_ETRGEDG_BOTH | AT91C_TC_ABETRG | AT91C_TC_LDRA_BOTH; - - // Enable and reset counter - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; - - // synchronized startup procedure - while (AT91C_BASE_TC1->TC_CV > 0) {}; // wait until TC1 returned to zero - - // Reset the received frame, frame count and timing info - memset(rx, 0x00, sizeof(rx)); - // frame_count = 0; - response = 0; - overflow = 0; - reader_frame = false; - lastbit = 1; - bSkip = true; - tag_sof = 4; + size_t periods = 0; + uint8_t periods_bytes[4]; + /*bool waiting_for_first_edge = true;*/ + LED_C_ON(); + while (!BUTTON_PRESS() && !data_available()) { - // Watchdog hit + WDT_HIT(); - // Receive frame, watch for at most T0*EOF periods - while (AT91C_BASE_TC1->TC_CV < T0 * HITAG_T_EOF) { - // Check if rising edge in modulation is detected - if (AT91C_BASE_TC1->TC_SR & AT91C_TC_LDRAS) { - // Retrieve the new timing values - int ra = (AT91C_BASE_TC1->TC_RA / T0); - - // Find out if we are dealing with a rising or falling edge - rising_edge = (AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_FRAME) > 0; - - // Shorter periods will only happen with reader frames - if (!reader_frame && rising_edge && ra < HITAG_T_TAG_CAPTURE_ONE_HALF) { - // Switch from tag to reader capture - LED_C_OFF(); - reader_frame = true; - memset(rx, 0x00, sizeof(rx)); - rxlen = 0; - } - - // Only handle if reader frame and rising edge, or tag frame and falling edge - if (reader_frame != rising_edge) { - overflow += ra; - continue; - } - - // Add the buffered timing values of earlier captured edges which were skipped - ra += overflow; - overflow = 0; - - if (reader_frame) { - LED_B_ON(); - // Capture reader frame - if (ra >= HITAG_T_STOP) { - if (rxlen != 0) { - //DbpString("wierd0?"); - } - // Capture the T0 periods that have passed since last communication or field drop (reset) - response = (ra - HITAG_T_LOW); - } else if (ra >= HITAG_T_1_MIN) { - // '1' bit - rx[rxlen / 8] |= 1 << (7 - (rxlen % 8)); - rxlen++; - } else if (ra >= HITAG_T_0_MIN) { - // '0' bit - rx[rxlen / 8] |= 0 << (7 - (rxlen % 8)); - rxlen++; - } else { - // Ignore wierd value, is to small to mean anything - } - } else { - LED_C_ON(); - // Capture tag frame (manchester decoding using only falling edges) - if (ra >= HITAG_T_EOF) { - if (rxlen != 0) { - //DbpString("wierd1?"); - } - // Capture the T0 periods that have passed since last communication or field drop (reset) - // We always recieve a 'one' first, which has the falling edge after a half period |-_| - response = ra - HITAG_T_TAG_HALF_PERIOD; - } else if (ra >= HITAG_T_TAG_CAPTURE_FOUR_HALF) { - // Manchester coding example |-_|_-|-_| (101) - rx[rxlen / 8] |= 0 << (7 - (rxlen % 8)); - rxlen++; - rx[rxlen / 8] |= 1 << (7 - (rxlen % 8)); - rxlen++; - } else if (ra >= HITAG_T_TAG_CAPTURE_THREE_HALF) { - // Manchester coding example |_-|...|_-|-_| (0...01) - rx[rxlen / 8] |= 0 << (7 - (rxlen % 8)); - rxlen++; - // We have to skip this half period at start and add the 'one' the second time - if (!bSkip) { - rx[rxlen / 8] |= 1 << (7 - (rxlen % 8)); - rxlen++; - } - lastbit = !lastbit; - bSkip = !bSkip; - } else if (ra >= HITAG_T_TAG_CAPTURE_TWO_HALF) { - // Manchester coding example |_-|_-| (00) or |-_|-_| (11) - if (tag_sof) { - // Ignore bits that are transmitted during SOF - tag_sof--; - } else { - // bit is same as last bit - rx[rxlen / 8] |= lastbit << (7 - (rxlen % 8)); - rxlen++; - } - } else { - // Ignore wierd value, is to small to mean anything - } - } + // Receive frame, watch for at most T0*EOF periods + lf_reset_counter(); + + // Wait "infinite" for reader modulation + periods = lf_detect_gap(20000); + + // Test if we detected the first reader modulation edge + if (periods != 0) { + if (logging == false) { + logging = true; + LED_D_ON(); } } + + /*lf_count_edge_periods(10000);*/ + while ((periods = lf_detect_gap(64)) != 0){ + num_to_bytes(periods, 4, periods_bytes); + LogTrace(periods_bytes, 4, 0, 0, NULL, true); + } + +/* // Check if frame was captured if (rxlen > 0) { // frame_count++; @@ -885,38 +1008,14 @@ void SniffHitag(void) { auth_table_len += 8; } } - - // Reset the received frame and response timing info - memset(rx, 0x00, sizeof(rx)); - response = 0; - reader_frame = false; - lastbit = 1; - bSkip = true; - tag_sof = 4; - overflow = 0; - - LED_B_OFF(); - LED_C_OFF(); - } else { - // Save the timer overflow, will be 0 when frame was received - overflow += (AT91C_BASE_TC1->TC_CV / T0); - } - // Reset the frame length - rxlen = 0; - // Reset the timer to restart while-loop that receives frames - AT91C_BASE_TC1->TC_CCR = AT91C_TC_SWTRG; +*/ } - LEDsoff(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - set_tracing(false); - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; + lf_finalize(); - // release allocated memory from BigBuff. - BigBuf_free(); StartTicks(); - DbpString("Hitag2 sniffing end, use `lf hitag list` for annotations"); + DbpString("Hitag2 sniffing finish. Use `lf hitag list` for annotations"); } // Hitag2 simulation @@ -1098,24 +1197,61 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { StopTicks(); - // int frame_count = 0; - int response = 0; + int frame_count = 0; + int response; uint8_t rx[HITAG_FRAME_LEN]; size_t rxlen = 0; uint8_t txbuf[HITAG_FRAME_LEN]; uint8_t *tx = txbuf; size_t txlen = 0; - int lastbit = 1; - bool bSkip; - int reset_sof; - int tag_sof; - int t_wait = HITAG_T_WAIT_MAX; - bool bStop = false; - + int t_wait_1; + int t_wait_2; + size_t tag_size; + bool bStop = false; + + // Raw demodulation/decoding by sampling edge periods + size_t periods = 0; + + // Reset the return status bSuccessful = false; + bCrypto = false; + + // Clean up trace and prepare it for storing frames + set_tracing(true); + clear_trace(); + + DbpString("Starting Hitag reader family"); // Check configuration switch (htf) { + case RHT1F_PLAIN: { + Dbprintf("Read public blocks in plain mode"); + // this part will be unreadable + memset(tag.sectors+2, 0x0, 30); + blocknr = 0; + } break; + + case RHT1F_AUTHENTICATE: { + Dbprintf("Read all blocks in authed mode"); + memcpy(nonce, htd->ht1auth.nonce, 4); + memcpy(key, htd->ht1auth.key, 4); + memcpy(logdata_0, htd->ht1auth.logdata_0, 4); + memcpy(logdata_1, htd->ht1auth.logdata_1, 4); + // TEST + memset(nonce, 0x0, 4); + memset(logdata_1, 0x00, 4); + byte_value = 0; + key_no = htd->ht1auth.key_no; + Dbprintf("Authenticating using key #%d:", key_no); + Dbhexdump(4, key, false); + DbpString("Nonce:"); + Dbhexdump(4, nonce, false); + DbpString("Logdata_0:"); + Dbhexdump(4, logdata_0, false); + DbpString("Logdata_1:"); + Dbhexdump(4, logdata_1, false); + blocknr = 0; + } break; case RHT2F_PASSWORD: { Dbprintf("List identifier in password mode"); memcpy(password, htd->pwd.password, 4); @@ -1136,6 +1272,9 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { DbpString("Authenticating using key:"); memcpy(key, htd->crypto.key, 6); //HACK; 4 or 6?? I read both in the code. Dbhexdump(6, key, false); + DbpString("Nonce:"); + Dbhexdump(4,nonce,false); + memcpy(nonce,htd->crypto.data,4); blocknr = 0; bCrypto = false; bAuthenticating = false; @@ -1162,71 +1301,45 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { } } - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - BigBuf_free(); - clear_trace(); - set_tracing(true); - LED_D_ON(); hitag2_init(); + // init as reader + lf_init(true); - // Set fpga in edge detect with reader field, we can modulate as reader now - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, LF_DIVISOR_125); //125kHz - SetAdcMuxFor(GPIO_MUXSEL_LOPKD); - - // Configure output and enable pin that is connected to the FPGA (for modulating) - AT91C_BASE_PIOA->PIO_OER |= GPIO_SSC_DOUT; - AT91C_BASE_PIOA->PIO_PER |= GPIO_SSC_DOUT; - - // Disable modulation at default, which means enable the field - LOW(GPIO_SSC_DOUT); - - // Enable Peripheral Clock for - // TIMER_CLOCK0, used to measure exact timing before answering - // TIMER_CLOCK1, used to capture edges of the tag frames - AT91C_BASE_PMC->PMC_PCER |= (1 << AT91C_ID_TC0) | (1 << AT91C_ID_TC1); - - // PIO_A - BSR - AT91C_BASE_PIOA->PIO_BSR = GPIO_SSC_FRAME; - - // Disable timer during configuration - AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; - - // TC0: Capture mode, default timer source = MCK/2 (TIMER_CLOCK1), no triggers - AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK; - - // TC1: Capture mode, default timer source = MCK/2 (TIMER_CLOCK1), TIOA is external trigger, - // external trigger rising edge, load RA on falling edge of TIOA. - AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK | AT91C_TC_ETRGEDG_FALLING | AT91C_TC_ABETRG | AT91C_TC_LDRA_FALLING; - - // Enable and reset counters - AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; - - // synchronized startup procedure - while (AT91C_BASE_TC0->TC_CV > 0) {}; // wait until TC0 returned to zero - + uint8_t attempt_count = 0; + // Tag specific configuration settings (sof, timings, etc.) - if (htf < 10) { + if (htf < 10){ // hitagS settings - reset_sof = 1; - t_wait = 200; + t_wait_1 = 204; + t_wait_2 = 128; + /*tag_size = 256;*/ + flipped_bit = 0; + tag_size = 8; + DbpString("Configured for hitagS reader"); } else if (htf < 20) { // hitag1 settings - reset_sof = 1; - t_wait = 200; + t_wait_1 = 204; + t_wait_2 = 128; + tag_size = 256; + flipped_bit = 0; + DbpString("Configured for hitag1 reader"); } else if (htf < 30) { // hitag2 settings - reset_sof = 4; - t_wait = HITAG_T_WAIT_2; + t_wait_1 = 206; + t_wait_2 = 90; + tag_size = 48; + DbpString("Configured for hitag2 reader"); } else { Dbprintf("Error, unknown hitag reader type: %d", htf); - goto out; + return; } - uint8_t attempt_count = 0; + + uint8_t tag_modulation; + size_t max_nrzs = 8 * HITAG_FRAME_LEN + 5; + uint8_t nrz_samples[max_nrzs]; + size_t nrzs = 0; while (!bStop && !BUTTON_PRESS() && !data_available()) { @@ -1234,13 +1347,23 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { // Check if frame was captured and store it if (rxlen > 0) { - // frame_count++; + frame_count++; + response++; LogTrace(rx, nbytes(rxlen), response, response, NULL, false); + //Dbhexdump(nbytes(rxlen), rx, false); } // By default reset the transmission buffer tx = txbuf; switch (htf) { + case RHT1F_PLAIN: { + bStop = !hitag_plain(rx, rxlen, tx, &txlen, false); + } break; + + case RHT1F_AUTHENTICATE: { + bStop = !hitag1_authenticate(rx, rxlen, tx, &txlen); + } break; + case RHT2F_PASSWORD: { bStop = !hitag2_password(rx, rxlen, tx, &txlen, false); break; @@ -1271,113 +1394,153 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { } } - // Send and store the reader command - // Disable timer 1 with external trigger to avoid triggers during our own modulation - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; - - // Wait for HITAG_T_WAIT_2 carrier periods after the last tag bit before transmitting, - // Since the clock counts since the last falling edge, a 'one' means that the - // falling edge occurred halfway the period. with respect to this falling edge, - // we need to wait (T_Wait2 + half_tag_period) when the last was a 'one'. - // All timer values are in terms of T0 units - while (AT91C_BASE_TC0->TC_CV < T0 * (t_wait + (HITAG_T_TAG_HALF_PERIOD * lastbit))); - + // Wait for t_wait_2 carrier periods after the last tag bit before transmitting, + lf_wait_periods(t_wait_2); + // Transmit the reader frame hitag_reader_send_frame(tx, txlen); - // Enable and reset external trigger in timer for capturing future frames - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; + // Let the antenna and ADC values settle + // And find the position where edge sampling should start + lf_wait_periods(t_wait_1 - 64); - // Add transmitted frame to total count + // Reset the response time (in number of periods) + response = 0; + + // Keep administration of the first edge detection + bool waiting_for_first_edge = true; + + // Did we detected any modulaiton at all + bool detected_tag_modulation = false; + + // Use the current modulation state as starting point + tag_modulation = lf_get_tag_modulation(); + + // Reset the number of NRZ samples and use edge detection to detect them + nrzs = 0; + while (nrzs < max_nrzs) { + // Get the timing of the next edge in number of wave periods + periods = lf_count_edge_periods(128); + + // Are we dealing with the first incoming edge + if (waiting_for_first_edge) { + // Just break out of loop after an initial time-out (tag is probably not available) + if (periods == 0) break; + // Register the number of periods that have passed + response = t_wait_1-64 + periods; + // Indicate that we have dealt with the first edge + waiting_for_first_edge = false; + // The first edge is always a single NRZ bit, force periods on 16 + periods = 16; + // We have received more than 0 periods, so we have detected a tag response + detected_tag_modulation = true; + } else { + // The function lf_count_edge_periods() returns 0 when a time-out occurs + if (periods == 0) { + Dbprintf("Detected timeout after [%d] nrz samples",nrzs); + break; + } + } + + // Evaluate the number of periods before the next edge + if (periods > 24 && periods <= 64){ + // Detected two sequential equal bits and a modulation switch + // NRZ modulation: (11 => --|) or (11 __|) + nrz_samples[nrzs++] = tag_modulation; + nrz_samples[nrzs++] = tag_modulation; + // Invert tag modulation state + tag_modulation ^= 1; + } else if (periods > 0 && periods <= 24){ + // Detected one bit and a modulation switch + // NRZ modulation: (1 => -|) or (0 _|) + nrz_samples[nrzs++] = tag_modulation; + tag_modulation ^= 1; + } else { + tag_modulation ^= 1; + // The function lf_count_edge_periods() returns > 64 periods, this is not a valid number periods + Dbprintf("Detected unexpected period count: %d", periods); + break; + } + } + + // Store the TX frame, we do this now at this point, to avoid delay in processing + // and to be able to overwrite the first samples with the trace (since they currently + // still use the same memory space) if (txlen > 0) { - // frame_count++; + frame_count++; LogTrace(tx, nbytes(txlen), HITAG_T_WAIT_2, HITAG_T_WAIT_2, NULL, true); } // Reset values for receiving frames memset(rx, 0x00, sizeof(rx)); rxlen = 0; - lastbit = 1; - bSkip = true; - tag_sof = reset_sof; - response = 0; - uint32_t errorCount = 0; - // Receive frame, watch for at most T0*EOF periods - while (AT91C_BASE_TC1->TC_CV < T0 * HITAG_T_WAIT_MAX) { + // If there is no response, just repeat the loop + if (!detected_tag_modulation) continue; - // Check if falling edge in tag modulation is detected - if (AT91C_BASE_TC1->TC_SR & AT91C_TC_LDRAS) { - // Retrieve the new timing values - int ra = (AT91C_BASE_TC1->TC_RA / T0); + // Make sure we always have an even number of samples. This fixes the problem + // of ending the manchester decoding with a zero. See the example below where + // the '|' character is end of modulation + // One at the end: ..._-|_____... + // Zero at the end: ...-_|_____... + // The last modulation change of a zero is not detected, but we should take + // the half period in account, otherwise the demodulator will fail. + if ((nrzs % 2) != 0) { + nrz_samples[nrzs++] = tag_modulation; + } - // Reset timer every frame, we have to capture the last edge for timing - AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; + LED_B_ON(); - LED_B_ON(); + // decode bitstream + manrawdecode((uint8_t*)nrz_samples, &nrzs, true, 0); - // Capture tag frame (manchester decoding using only falling edges) - if (ra >= HITAG_T_EOF) { - // Capture the T0 periods that have passed since last communication or field drop (reset) - // We always recieve a 'one' first, which has the falling edge after a half period |-_| - response = ra - HITAG_T_TAG_HALF_PERIOD; - } else if (ra >= HITAG_T_TAG_CAPTURE_FOUR_HALF) { - // Manchester coding example |-_|_-|-_| (101) - rx[rxlen / 8] |= 0 << (7 - (rxlen % 8)); - rxlen++; - rx[rxlen / 8] |= 1 << (7 - (rxlen % 8)); - rxlen++; - } else if (ra >= HITAG_T_TAG_CAPTURE_THREE_HALF) { - // Manchester coding example |_-|...|_-|-_| (0...01) - rx[rxlen / 8] |= 0 << (7 - (rxlen % 8)); - rxlen++; - // We have to skip this half period at start and add the 'one' the second time - if (!bSkip) { - rx[rxlen / 8] |= 1 << (7 - (rxlen % 8)); - rxlen++; - } - lastbit = !lastbit; - bSkip = !bSkip; - } else if (ra >= HITAG_T_TAG_CAPTURE_TWO_HALF) { - // Manchester coding example |_-|_-| (00) or |-_|-_| (11) - if (tag_sof) { - // Ignore bits that are transmitted during SOF - tag_sof--; - } else { - // bit is same as last bit - rx[rxlen / 8] |= lastbit << (7 - (rxlen % 8)); - rxlen++; - } - } else { - errorCount++; - // Ignore wierd value, is to small to mean anything + // decode frame + + // Verify if the header consists of five consecutive ones + if (nrzs < 5) { + Dbprintf("Detected unexpected number of manchester decoded samples [%d]",nrzs); + break; + } else { + for (size_t i = 0; i < 5; i++){ + if (nrz_samples[i] != 1) { + Dbprintf("Detected incorrect header, the bit [%d] is zero instead of one",i); } } - //if we saw over 100 wierd values break it probably isn't hitag... - if (errorCount > 100) break; - // We can break this loop if we received the last bit from a frame - if (AT91C_BASE_TC1->TC_CV > T0 * HITAG_T_EOF) { - if (rxlen > 0) break; - } } - } + + // Pack the response into a byte array + for (size_t i = 5; i < 37; i++){ + uint8_t bit = nrz_samples[i]; + rx[rxlen / 8] |= bit << (7 - (rxlen % 8)); + rxlen++; + } + + // Check if frame was captured and store it + if (rxlen > 0) { + frame_count++; + if (bCollision){ + // AC decoding hack + fix_ac_decoding(rx, 64); + rxlen = 32; + } + + LogTrace(rx, rxlen, response, 0, NULL, false); + //Dbhexdump(rxlen, rx, false); + } + } out: - LEDsoff(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - set_tracing(false); - - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; - AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; + lf_finalize(); + Dbprintf("frame received: %u", frame_count); // release allocated memory from BigBuff. BigBuf_free(); StartTicks(); if (bSuccessful) - reply_old(CMD_ACK, bSuccessful, 0, 0, (uint8_t *)tag.sectors, 48); + reply_old(CMD_ACK, bSuccessful, 0, 0, (uint8_t *)tag.sectors, tag_size); else - reply_old(CMD_ACK, bSuccessful, 0, 0, 0, 0); + reply_mix(CMD_ACK, bSuccessful, 0, 0, 0, 0); } void WriterHitag(hitag_function htf, hitag_data *htd, int page) { diff --git a/armsrc/hitag2.h b/armsrc/hitag2.h index 9e0fb84e6..79ada4ddf 100644 --- a/armsrc/hitag2.h +++ b/armsrc/hitag2.h @@ -14,7 +14,7 @@ #include "common.h" #include "hitag.h" -void SniffHitag(void); +void SniffHitag(uint32_t type); void SimulateHitagTag(bool tag_mem_supplied, uint8_t *data); void ReaderHitag(hitag_function htf, hitag_data *htd); void WriterHitag(hitag_function htf, hitag_data *htd, int page); diff --git a/armsrc/lfadc.c b/armsrc/lfadc.c index d59fae07d..09ee5a2a6 100644 --- a/armsrc/lfadc.c +++ b/armsrc/lfadc.c @@ -168,7 +168,9 @@ void lf_init(bool reader) { AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; // Prepare data trace - if (logging) initSampleBuffer(NULL); + uint32_t bufsize = 20000; + + if (logging) initSampleBuffer(&bufsize); } diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index 3378a9f94..8b0c14d94 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -106,17 +106,23 @@ sampling_t samples = {0, 0, 0, 0}; void initSampleBuffer(uint32_t *sample_size) { + BigBuf_free(); + BigBuf_Clear_ext(false); + if (sample_size == NULL || *sample_size == 0) { *sample_size = BigBuf_max_traceLen(); + + data.buffer = BigBuf_get_addr(); + + memset(data.buffer, 0, *sample_size); } else { *sample_size = MIN(*sample_size, BigBuf_max_traceLen()); + + data.buffer = BigBuf_malloc(*sample_size); + + memset(data.buffer, 0, *sample_size); } - // use a bitstream to handle the output - data.buffer = BigBuf_get_addr(); - - memset(data.buffer, 0, *sample_size); - // samples.dec_counter = 0; samples.sum = 0; diff --git a/client/cmdlfhitag.c b/client/cmdlfhitag.c index 40e909024..625b0bef0 100644 --- a/client/cmdlfhitag.c +++ b/client/cmdlfhitag.c @@ -485,8 +485,9 @@ static int CmdLFHitagInfo(const char *Cmd) { if (getHitagUid(&uid) == false) return 1; - PrintAndLogEx(SUCCESS, "UID: %08X", uid); + PrintAndLogEx(SUCCESS, "UID: " _YELLOW_("%08X"), uid); + return PM3_SUCCESS; // how to detemine Hitag types? // read block3, get configuration byte. PrintAndLogEx(FAILED, _RED_("TODO: This is a hardcoded example!")); @@ -497,7 +498,7 @@ static int CmdLFHitagInfo(const char *Cmd) { //printHitagConfiguration( 0x02 ); //printHitagConfiguration( 0x00 ); //printHitagConfiguration( 0x04 ); - return 0; + return PM3_SUCCESS; } // TODO: iceman @@ -564,7 +565,7 @@ static int CmdLFHitagReader(const char *Cmd) { uint32_t id = bytes_to_num(resp.data.asBytes, 4); - PrintAndLogEx(SUCCESS, "Valid Hitag2 tag found - UID: %08x", id); + PrintAndLogEx(SUCCESS, "Valid Hitag2 tag found - UID: " _YELLOW_("%08x"), id); if (htf != RHT2F_UID_ONLY) { PrintAndLogEx(SUCCESS, "Dumping tag memory..."); diff --git a/include/hitag.h b/include/hitag.h index 9df93fcf7..b8555600b 100644 --- a/include/hitag.h +++ b/include/hitag.h @@ -21,6 +21,8 @@ typedef enum { RHTSF_KEY = 02, WHTSF_CHALLENGE = 03, WHTSF_KEY = 04, + RHT1F_PLAIN = 11, + RHT1F_AUTHENTICATE = 12, RHT2F_PASSWORD = 21, RHT2F_AUTHENTICATE = 22, RHT2F_CRYPTO = 23, @@ -44,8 +46,17 @@ typedef struct { uint8_t data[4]; } PACKED rht2d_crypto; +typedef struct { + bool key_no; + uint8_t logdata_0[4]; + uint8_t logdata_1[4]; + uint8_t nonce[4]; + uint8_t key[4]; +} PACKED rht1d_authenticate; + typedef union { rht2d_password pwd; + rht1d_authenticate ht1auth; rht2d_authenticate auth; rht2d_crypto crypto; } hitag_data; From 4154f3dd1ac1e0ae6edf06f6f00a803ca34f7544 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 14 Jan 2020 22:58:38 +0100 Subject: [PATCH 1446/1854] fix compilation --- armsrc/hitag2.c | 2 +- armsrc/hitag2.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index 60cd76416..f49c4fc38 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -940,7 +940,7 @@ static bool hitag2_read_uid(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t } // Hitag2 Sniffing -void SniffHitag(uint32_t type) { +void SniffHitag(void) { LEDsoff(); StopTicks(); diff --git a/armsrc/hitag2.h b/armsrc/hitag2.h index 79ada4ddf..9e0fb84e6 100644 --- a/armsrc/hitag2.h +++ b/armsrc/hitag2.h @@ -14,7 +14,7 @@ #include "common.h" #include "hitag.h" -void SniffHitag(uint32_t type); +void SniffHitag(void); void SimulateHitagTag(bool tag_mem_supplied, uint8_t *data); void ReaderHitag(hitag_function htf, hitag_data *htd); void WriterHitag(hitag_function htf, hitag_data *htd, int page); From 6c0d6f0655ba7a497d72b9b6ceece2d039fd0687 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 15 Jan 2020 02:02:42 +0100 Subject: [PATCH 1447/1854] hitag: wip --- armsrc/hitag2.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index f49c4fc38..e0635c3a5 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -1337,7 +1337,7 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { } uint8_t tag_modulation; - size_t max_nrzs = 8 * HITAG_FRAME_LEN + 5; + size_t max_nrzs = (8 * HITAG_FRAME_LEN + 5) * 2; // up to 2 nrzs per bit uint8_t nrz_samples[max_nrzs]; size_t nrzs = 0; @@ -1462,7 +1462,7 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { break; } } - + // Store the TX frame, we do this now at this point, to avoid delay in processing // and to be able to overwrite the first samples with the trace (since they currently // still use the same memory space) @@ -1509,23 +1509,25 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { } // Pack the response into a byte array - for (size_t i = 5; i < 37; i++){ + for (size_t i = 5; i < nrzs; i++){ uint8_t bit = nrz_samples[i]; rx[rxlen / 8] |= bit << (7 - (rxlen % 8)); rxlen++; } - + if (rxlen % 8 == 1) // skip spurious bit + rxlen--; + // Check if frame was captured and store it if (rxlen > 0) { frame_count++; - if (bCollision){ - // AC decoding hack - fix_ac_decoding(rx, 64); - rxlen = 32; - } +// if (bCollision){ +// // AC decoding hack +// fix_ac_decoding(rx, 64); +// rxlen = 32; +// } - LogTrace(rx, rxlen, response, 0, NULL, false); - //Dbhexdump(rxlen, rx, false); + LogTrace(rx, nbytes(rxlen), response, 0, NULL, false); + Dbhexdump(nbytes(rxlen), rx, false); } } From 2412961411cd823058b1a4c495a4f988d5649ed4 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 15 Jan 2020 12:47:40 +0100 Subject: [PATCH 1448/1854] only set new timeout if its faster :) --- armsrc/mifareutil.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/armsrc/mifareutil.c b/armsrc/mifareutil.c index cfd8f4b35..e115e965f 100644 --- a/armsrc/mifareutil.c +++ b/armsrc/mifareutil.c @@ -194,7 +194,8 @@ int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockN uint32_t save_timeout = iso14a_get_timeout(); // set timeout for authentication response - iso14a_set_timeout(106); + if (save_timeout > 106) + iso14a_set_timeout(106); // Receive 4 byte tag answer len = ReaderReceive(receivedAnswer, receivedAnswerPar); From 2de3a756cc56f881b6a09ba5eb0f639c061461f9 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 15 Jan 2020 13:07:51 +0100 Subject: [PATCH 1449/1854] chg: 'data samples' - colors --- client/cmddata.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/client/cmddata.c b/client/cmddata.c index ddd87fdb8..613ce11e5 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -1599,7 +1599,7 @@ int getSamples(uint32_t n, bool verbose) { if (n == 0 || n > sizeof(got)) n = sizeof(got); - if (verbose) PrintAndLogEx(NORMAL, "Reading %d bytes from device memory\n", n); + if (verbose) PrintAndLogEx(INFO, "Reading " _YELLOW_("%u") "bytes from device memory", n); PacketResponseNG response; if (!GetFromDevice(BIG_BUF, got, n, 0, NULL, 0, &response, 10000, true)) { @@ -1607,20 +1607,20 @@ int getSamples(uint32_t n, bool verbose) { return PM3_ETIMEOUT; } - if (verbose) PrintAndLogEx(NORMAL, "Data fetched"); + if (verbose) PrintAndLogEx(SUCCESS, "Data fetched"); uint8_t bits_per_sample = 8; //Old devices without this feature would send 0 at arg[0] if (response.oldarg[0] > 0) { sample_config *sc = (sample_config *) response.data.asBytes; - if (verbose) PrintAndLogEx(NORMAL, "Samples @ %d bits/smpl, decimation 1:%d ", sc->bits_per_sample, sc->decimation); + if (verbose) PrintAndLogEx(INFO, "Samples @ " _YELLOW_("%d") "bits/smpl, decimation 1:%d ", sc->bits_per_sample, sc->decimation); bits_per_sample = sc->bits_per_sample; } if (bits_per_sample < 8) { - if (verbose) PrintAndLogEx(NORMAL, "Unpacking..."); + if (verbose) PrintAndLogEx(INFO, "Unpacking..."); BitstreamOut bout = { got, bits_per_sample * n, 0}; int j = 0; @@ -1630,7 +1630,7 @@ int getSamples(uint32_t n, bool verbose) { } GraphTraceLen = j; - if (verbose) PrintAndLogEx(NORMAL, "Unpacked %d samples", j); + if (verbose) PrintAndLogEx(INFO, "Unpacked %d samples", j); } else { for (int j = 0; j < n; j++) { From 33033612bcc311fe9780381ff3794f136382e89c Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 15 Jan 2020 15:03:35 +0100 Subject: [PATCH 1450/1854] Fix delay in acquisition and DoAcquisition_config usage. Fixes #524 --- armsrc/lfops.c | 2 +- armsrc/lfsampling.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/armsrc/lfops.c b/armsrc/lfops.c index ed23e75ea..1cb8406bf 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -2550,7 +2550,7 @@ void Cotag(uint32_t arg0) { doCotagAcquisitionManchester(); break; case 2: - DoAcquisition_config(true, true); + DoAcquisition_config(false, 0); break; } diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index 3378a9f94..5808fff07 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -115,7 +115,8 @@ void initSampleBuffer(uint32_t *sample_size) { // use a bitstream to handle the output data.buffer = BigBuf_get_addr(); - memset(data.buffer, 0, *sample_size); +// We can't erase the buffer now, it would drastically delay the acquisition +// memset(data.buffer, 0, *sample_size); // samples.dec_counter = 0; From 8ec57a7281eea35a9a623bed868f89c53fc89ac1 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 15 Jan 2020 17:29:01 +0100 Subject: [PATCH 1451/1854] clear bit first in pushBit so we don't need initialized buff --- armsrc/lfsampling.c | 1 + 1 file changed, 1 insertion(+) diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index 290542959..f694b01f4 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -93,6 +93,7 @@ sample_config *getSamplingConfig() { void pushBit(BitstreamOut *stream, uint8_t bit) { int bytepos = stream->position >> 3; // divide by 8 int bitpos = stream->position & 7; + *(stream->buffer + bytepos) &= ~(1 << (7 - bitpos)); *(stream->buffer + bytepos) |= (bit > 0) << (7 - bitpos); stream->position++; stream->numbits++; From 5eef25bb5f5ebe483e7df707391f3162a4226bfa Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 15 Jan 2020 19:19:58 +0100 Subject: [PATCH 1452/1854] fix again delay in acquisition --- armsrc/lfsampling.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index f694b01f4..eb3edb029 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -108,7 +108,8 @@ sampling_t samples = {0, 0, 0, 0}; void initSampleBuffer(uint32_t *sample_size) { BigBuf_free(); - BigBuf_Clear_ext(false); +// We can't erase the buffer now, it would drastically delay the acquisition +// BigBuf_Clear_ext(false); if (sample_size == NULL || *sample_size == 0) { *sample_size = BigBuf_max_traceLen(); From 7c33eeb7d5e448fe8b512c3da80a3ba941685a9c Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 15 Jan 2020 19:25:29 +0100 Subject: [PATCH 1453/1854] style --- armsrc/iso14443b.c | 2 +- armsrc/mifarecmd.c | 4 ++-- armsrc/mifaresim.c | 2 +- client/cmdhfmf.c | 6 +++--- client/cmdlfnexwatch.c | 4 ++-- client/mifare/mifarehost.c | 20 ++++++++++---------- 6 files changed, 19 insertions(+), 19 deletions(-) diff --git a/armsrc/iso14443b.c b/armsrc/iso14443b.c index 342c68471..d68ddd044 100644 --- a/armsrc/iso14443b.c +++ b/armsrc/iso14443b.c @@ -1167,7 +1167,7 @@ uint8_t iso14443b_apdu(uint8_t const *message, size_t message_length, uint8_t *r GetTagSamplesFor14443bDemod(); //no FpgaDisableTracing(); - + if (Demod.len < 3) return 0; diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 4d7138565..a0ce705be 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -1157,7 +1157,7 @@ void MifareStaticNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, retry--; continue; }; - + // second authentication. Nested auth len = mifare_sendcmd_short(pcs, AUTH_NESTED, 0x60 + (targetKeyType & 0x01), targetBlockNo, receivedAnswer, par, NULL); if (len != 4) { @@ -1200,7 +1200,7 @@ void MifareStaticNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); - set_tracing(false); + set_tracing(false); } //----------------------------------------------------------------------------- // MIFARE check keys. key count up to 85. diff --git a/armsrc/mifaresim.c b/armsrc/mifaresim.c index 3f89cb029..80881c416 100644 --- a/armsrc/mifaresim.c +++ b/armsrc/mifaresim.c @@ -916,7 +916,7 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1 if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] RECV 0xA0 write block %d (%02x)", blockNo, blockNo); EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_ACK)); FpgaDisableTracing(); - + cardWRBL = blockNo; cardSTATE = MFEMUL_WRITEBL2; if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] cardSTATE = MFEMUL_WRITEBL2"); diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index d48a1fe1e..173184592 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -1578,7 +1578,7 @@ static int CmdHF14AMfNestedStatic(const char *Cmd) { for (trgKeyType = 0; trgKeyType < 2; ++trgKeyType) { for (uint8_t sectorNo = 0; sectorNo < SectorsCnt; ++sectorNo) { - for (int i = 0; i < 1; i++) { + for (int i = 0; i < 1; i++) { if (e_sector[sectorNo].foundKey[trgKeyType]) continue; @@ -3557,12 +3557,12 @@ void printKeyTableEx(uint8_t sectorscnt, sector_t *e_sector, uint8_t start_secto , strB, e_sector[i].foundKey[1] ); } else { - + // keep track if we use start_sector or i... uint8_t s = start_sector; if (start_sector == 0) s = i; - + PrintAndLogEx(NORMAL, "|%03d| %s | " _YELLOW_("%d")"| %s | " _YELLOW_("%d")"|" , s , strA, e_sector[i].foundKey[0] diff --git a/client/cmdlfnexwatch.c b/client/cmdlfnexwatch.c index 69f429ab6..68be0e0bc 100644 --- a/client/cmdlfnexwatch.c +++ b/client/cmdlfnexwatch.c @@ -192,13 +192,13 @@ static int CmdNexWatchSim(const char *Cmd) { } if (errors || cmdp == 0) return usage_lf_nexwatch_sim(); - + // hex to bits. for (size_t i = 0; i < ARRAYLEN(rawblocks); i++) { rawblocks[i] = bytes_to_num(rawhex + (i * sizeof(uint32_t)), sizeof(uint32_t)); num_to_bytebits(rawblocks[i], sizeof(uint32_t) * 8, bs + (i * sizeof(uint32_t) * 8)); } - + PrintAndLogEx(SUCCESS, "Simulating NexWatch - raw: %s", sprint_hex_inrow(rawhex, rawlen)); lf_psksim_t *payload = calloc(1, sizeof(lf_psksim_t) + sizeof(bs)); diff --git a/client/mifare/mifarehost.c b/client/mifare/mifarehost.c index 795d9eec7..5ba245070 100644 --- a/client/mifare/mifarehost.c +++ b/client/mifare/mifarehost.c @@ -563,14 +563,14 @@ int mfStaticNested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBl // create key candidates. while (p1 <= statelists[0].tail.sltail) { - struct Crypto1State savestate; - savestate = *p1; - while (Compare16Bits(p1, &savestate) == 0 && p1 <= statelists[0].tail.sltail) { - *p3 = *p1; - lfsr_rollback_word(p3, statelists[0].nt_enc ^ statelists[0].uid, 0); - p3++; - p1++; - } + struct Crypto1State savestate; + savestate = *p1; + while (Compare16Bits(p1, &savestate) == 0 && p1 <= statelists[0].tail.sltail) { + *p3 = *p1; + lfsr_rollback_word(p3, statelists[0].nt_enc ^ statelists[0].uid, 0); + p3++; + p1++; + } } *(uint64_t *)p3 = -1; @@ -581,14 +581,14 @@ int mfStaticNested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBl if (keycnt == 0) goto out; PrintAndLogEx(SUCCESS, "Found " _YELLOW_("%u") "candidate keys", keycnt); - + memset(resultKey, 0, 6); uint64_t key64 = -1; // The list may still contain several key candidates. Test each of them with mfCheckKeys uint32_t max_keys_slice = keycnt > KEYS_IN_BLOCK ? KEYS_IN_BLOCK : keycnt; uint8_t keyBlock[PM3_CMD_DATA_SIZE] = {0x00}; - + for (i = 0; i < keycnt; i += max_keys_slice) { PrintAndLogEx(INFO, "Testing %u / %u ", i, keycnt); From b57f40e3d78ef067ab6c592cab69255c1db6e86e Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 15 Jan 2020 19:26:12 +0100 Subject: [PATCH 1454/1854] make style --- armsrc/hitag2.c | 616 ++++++++++++++++++++++++------------------------ include/hitag.h | 16 +- 2 files changed, 321 insertions(+), 311 deletions(-) diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index e0635c3a5..474207590 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -16,7 +16,7 @@ // (c) 2012 Roel Verdult //----------------------------------------------------------------------------- // Piwi, 2019 -// Iceman, 2019 +// Iceman, 2019 // Anon, 2019 #include "hitag2.h" @@ -299,10 +299,10 @@ static void hitag2_handle_reader_command(uint8_t *rx, const size_t rxlen, uint8_ // sim static void hitag_reader_send_bit(int bit) { LED_A_ON(); - // Binary pulse length modulation (BPLM) is used to encode the data stream + // Binary pulse length modulation (BPLM) is used to encode the data stream // This means that a transmission of a one takes longer than that of a zero - // Enable modulation, which means, drop the field + // Enable modulation, which means, drop the field lf_modulation(true); // Wait for 4-10 times the carrier period @@ -328,241 +328,247 @@ static void hitag_reader_send_frame(const uint8_t *frame, size_t frame_len) { for (size_t i = 0; i < frame_len; i++) { hitag_reader_send_bit((frame[i / 8] >> (7 - (i % 8))) & 1); } - // Enable modulation, which means, drop the field + // Enable modulation, which means, drop the field lf_modulation(true); // Wait for 4-10 times the carrier period lf_wait_periods(8); // Disable modulation, just activates the field again lf_modulation(false); - + // t_stop, high field for stop condition (> 36) lf_wait_periods(28); } size_t blocknr; -uint8_t hitag_crc(uint8_t *data, size_t length){ - uint8_t crc = 0xff; - unsigned int byte, bit; - for(byte=0; byte<((length+7)/8); byte++){ - crc ^= *(data + byte); - bit = length < (8*(byte+1)) ? (length % 8) : 8; - while(bit--){ - if(crc & 0x80){ - crc<<=1; - crc ^= 0x1d; - } else { - crc<<=1; - } - } - } - return crc; +uint8_t hitag_crc(uint8_t *data, size_t length) { + uint8_t crc = 0xff; + unsigned int byte, bit; + for (byte = 0; byte < ((length + 7) / 8); byte++) { + crc ^= *(data + byte); + bit = length < (8 * (byte + 1)) ? (length % 8) : 8; + while (bit--) { + if (crc & 0x80) { + crc <<= 1; + crc ^= 0x1d; + } else { + crc <<= 1; + } + } + } + return crc; } #define test_bit(data, i) (*(data+(i/8)) >> (7-(i%8))) & 1 #define set_bit(data, i) *(data+(i/8)) |= (1 << (7-(i%8))) #define clear_bit(data, i) *(data+(i/8)) &= ~(1 << (7-(i%8))) #define flip_bit(data, i) *(data+(i/8)) ^= (1 << (7-(i%8))) -void fix_ac_decoding(uint8_t *input, size_t len){ - // Reader routine tries to decode AC data after Manchester decoding - // AC has double the bitrate, extract data from bit-pairs - uint8_t temp[len / 16]; - memset(temp, 0, sizeof(temp)); +void fix_ac_decoding(uint8_t *input, size_t len) { + // Reader routine tries to decode AC data after Manchester decoding + // AC has double the bitrate, extract data from bit-pairs + uint8_t temp[len / 16]; + memset(temp, 0, sizeof(temp)); - for (size_t i = 1; i < len; i += 2) { - if (test_bit(input, i) && test_bit(input, (i + 1))){ - set_bit(temp, (i / 2)); - } - } - memcpy(input, temp, sizeof(temp)); + for (size_t i = 1; i < len; i += 2) { + if (test_bit(input, i) && test_bit(input, (i + 1))) { + set_bit(temp, (i / 2)); + } + } + memcpy(input, temp, sizeof(temp)); } -bool hitag_plain(uint8_t* rx, const size_t rxlen, uint8_t* tx, size_t* txlen, bool hitag_s) { - uint8_t crc; - *txlen = 0; - switch (rxlen) { - case 0: { - // retry waking up card - /*tx[0] = 0xb0; // Rev 3.0*/ - tx[0] = 0x30; // Rev 2.0 - *txlen = 5; - if(!bCollision) blocknr--; - if(blocknr < 0) { - blocknr = 0; - } - if(!hitag_s){ - if (blocknr > 1 && blocknr < 31) { - blocknr=31; - } - } - bCollision = true; - return true; - } - case 32: { - if(bCollision){ - // Select card by serial from response - tx[0] = 0x00 | rx[0] >> 5; - tx[1] = rx[0] << 3 | rx[1] >> 5; - tx[2] = rx[1] << 3 | rx[2] >> 5; - tx[3] = rx[2] << 3 | rx[3] >> 5; - tx[4] = rx[3] << 3; - crc = hitag_crc(tx,37); - tx[4] |= crc >> 5; - tx[5] = crc << 3; - *txlen = 45; - bCollision = false; - } else { - memcpy(tag.sectors[blocknr], rx, 4); - blocknr++; - if(!hitag_s){ - if (blocknr > 1 && blocknr < 31) { - blocknr=31; - } - } - if (blocknr > 63) { - DbpString("Read succesful!"); - *txlen = 0; - bSuccessful = true; - return false; - } - // read next page of card until done - Dbprintf("Reading page %02u", blocknr); - tx[0] = 0xc0 | blocknr >> 4; // RDPPAGE - tx[1] = blocknr << 4; - crc = hitag_crc(tx,12); - tx[1] |= crc >> 4; - tx[2] = crc << 4; - *txlen = 20; - } - } break; - default: { - Dbprintf("Uknown frame length: %d",rxlen); - return false; - } break; - } - return true; +bool hitag_plain(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t *txlen, bool hitag_s) { + uint8_t crc; + *txlen = 0; + switch (rxlen) { + case 0: { + // retry waking up card + /*tx[0] = 0xb0; // Rev 3.0*/ + tx[0] = 0x30; // Rev 2.0 + *txlen = 5; + if (!bCollision) blocknr--; + if (blocknr < 0) { + blocknr = 0; + } + if (!hitag_s) { + if (blocknr > 1 && blocknr < 31) { + blocknr = 31; + } + } + bCollision = true; + return true; + } + case 32: { + if (bCollision) { + // Select card by serial from response + tx[0] = 0x00 | rx[0] >> 5; + tx[1] = rx[0] << 3 | rx[1] >> 5; + tx[2] = rx[1] << 3 | rx[2] >> 5; + tx[3] = rx[2] << 3 | rx[3] >> 5; + tx[4] = rx[3] << 3; + crc = hitag_crc(tx, 37); + tx[4] |= crc >> 5; + tx[5] = crc << 3; + *txlen = 45; + bCollision = false; + } else { + memcpy(tag.sectors[blocknr], rx, 4); + blocknr++; + if (!hitag_s) { + if (blocknr > 1 && blocknr < 31) { + blocknr = 31; + } + } + if (blocknr > 63) { + DbpString("Read succesful!"); + *txlen = 0; + bSuccessful = true; + return false; + } + // read next page of card until done + Dbprintf("Reading page %02u", blocknr); + tx[0] = 0xc0 | blocknr >> 4; // RDPPAGE + tx[1] = blocknr << 4; + crc = hitag_crc(tx, 12); + tx[1] |= crc >> 4; + tx[2] = crc << 4; + *txlen = 20; + } + } + break; + default: { + Dbprintf("Uknown frame length: %d", rxlen); + return false; + } + break; + } + return true; } size_t flipped_bit = 0; uint32_t byte_value = 0; -bool hitag1_authenticate(uint8_t* rx, const size_t rxlen, uint8_t* tx, size_t* txlen) { - uint8_t crc; - *txlen = 0; - switch (rxlen) { - case 0: { - // retry waking up card - /*tx[0] = 0xb0; // Rev 3.0*/ - tx[0] = 0x30; // Rev 2.0 - *txlen = 5; - if (bCrypto && byte_value <= 0xff){ - // to retry - bCrypto = false; - } - if(!bCollision) blocknr--; - if(blocknr < 0) { - blocknr = 0; - } - bCollision = true; - // will receive 32-bit UID - } break; - case 2: { - if (bAuthenticating) { - // received Auth init ACK, send nonce - // TODO Roel, bit-manipulation goes here - /*nonce[0] = 0x2d;*/ - /*nonce[1] = 0x74;*/ - /*nonce[2] = 0x80;*/ - /*nonce[3] = 0xa5;*/ - nonce[0]=byte_value; - byte_value++; - /*set_bit(nonce,flipped_bit);*/ - memcpy(tx,nonce,4); - *txlen = 32; - // will receive 32 bit encrypted Logdata - } else if (bCrypto) { - // authed, start reading - tx[0] = 0xe0 | blocknr >> 4; // RDCPAGE - tx[1] = blocknr << 4; - crc = hitag_crc(tx,12); - tx[1] |= crc >> 4; - tx[2] = crc << 4; - *txlen = 20; - // will receive 32-bit encrypted page - } - } break; - case 32: { - if (bCollision){ - // Select card by serial from response - tx[0] = 0x00 | rx[0] >> 5; - tx[1] = rx[0] << 3 | rx[1] >> 5; - tx[2] = rx[1] << 3 | rx[2] >> 5; - tx[3] = rx[2] << 3 | rx[3] >> 5; - tx[4] = rx[3] << 3; - crc = hitag_crc(tx,37); - tx[4] |= crc >> 5; - tx[5] = crc << 3; - *txlen = 45; - bCollision = false; - bSelecting = true; - // will receive 32-bit configuration page - } else if (bSelecting){ - // Initiate auth - tx[0] = 0xa0 | key_no >> 4; // WRCPAGE - tx[1] = blocknr << 4; - crc = hitag_crc(tx,12); - tx[1] |= crc >> 4; - tx[2] = crc << 4; - *txlen = 20; - bSelecting = false; - bAuthenticating = true; - // will receive 2-bit ACK - } else if (bAuthenticating) { - // received 32-bit logdata 0 - // TODO decrypt logdata 0, verify against logdata_0 - memcpy(tag.sectors[0], rx, 4); - memcpy(tag.sectors[1], tx, 4); - Dbprintf("%02x%02x%02x%02x %02x%02x%02x%02x", rx[0], rx[1], rx[2], rx[3], tx[0], tx[1], tx[2], tx[3]); - // TODO replace with secret data stream - // TODO encrypt logdata_1 - memcpy(tx,logdata_1,4); - *txlen = 32; - bAuthenticating = false; - bCrypto = true; - // will receive 2-bit ACK - } else if (bCrypto) { - // received 32-bit encrypted page - // TODO decrypt rx - memcpy(tag.sectors[blocknr],rx,4); - blocknr++; - if (blocknr > 63) { - DbpString("Read succesful!"); - bSuccessful = true; - return false; - } +bool hitag1_authenticate(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t *txlen) { + uint8_t crc; + *txlen = 0; + switch (rxlen) { + case 0: { + // retry waking up card + /*tx[0] = 0xb0; // Rev 3.0*/ + tx[0] = 0x30; // Rev 2.0 + *txlen = 5; + if (bCrypto && byte_value <= 0xff) { + // to retry + bCrypto = false; + } + if (!bCollision) blocknr--; + if (blocknr < 0) { + blocknr = 0; + } + bCollision = true; + // will receive 32-bit UID + } + break; + case 2: { + if (bAuthenticating) { + // received Auth init ACK, send nonce + // TODO Roel, bit-manipulation goes here + /*nonce[0] = 0x2d;*/ + /*nonce[1] = 0x74;*/ + /*nonce[2] = 0x80;*/ + /*nonce[3] = 0xa5;*/ + nonce[0] = byte_value; + byte_value++; + /*set_bit(nonce,flipped_bit);*/ + memcpy(tx, nonce, 4); + *txlen = 32; + // will receive 32 bit encrypted Logdata + } else if (bCrypto) { + // authed, start reading + tx[0] = 0xe0 | blocknr >> 4; // RDCPAGE + tx[1] = blocknr << 4; + crc = hitag_crc(tx, 12); + tx[1] |= crc >> 4; + tx[2] = crc << 4; + *txlen = 20; + // will receive 32-bit encrypted page + } + } + break; + case 32: { + if (bCollision) { + // Select card by serial from response + tx[0] = 0x00 | rx[0] >> 5; + tx[1] = rx[0] << 3 | rx[1] >> 5; + tx[2] = rx[1] << 3 | rx[2] >> 5; + tx[3] = rx[2] << 3 | rx[3] >> 5; + tx[4] = rx[3] << 3; + crc = hitag_crc(tx, 37); + tx[4] |= crc >> 5; + tx[5] = crc << 3; + *txlen = 45; + bCollision = false; + bSelecting = true; + // will receive 32-bit configuration page + } else if (bSelecting) { + // Initiate auth + tx[0] = 0xa0 | key_no >> 4; // WRCPAGE + tx[1] = blocknr << 4; + crc = hitag_crc(tx, 12); + tx[1] |= crc >> 4; + tx[2] = crc << 4; + *txlen = 20; + bSelecting = false; + bAuthenticating = true; + // will receive 2-bit ACK + } else if (bAuthenticating) { + // received 32-bit logdata 0 + // TODO decrypt logdata 0, verify against logdata_0 + memcpy(tag.sectors[0], rx, 4); + memcpy(tag.sectors[1], tx, 4); + Dbprintf("%02x%02x%02x%02x %02x%02x%02x%02x", rx[0], rx[1], rx[2], rx[3], tx[0], tx[1], tx[2], tx[3]); + // TODO replace with secret data stream + // TODO encrypt logdata_1 + memcpy(tx, logdata_1, 4); + *txlen = 32; + bAuthenticating = false; + bCrypto = true; + // will receive 2-bit ACK + } else if (bCrypto) { + // received 32-bit encrypted page + // TODO decrypt rx + memcpy(tag.sectors[blocknr], rx, 4); + blocknr++; + if (blocknr > 63) { + DbpString("Read succesful!"); + bSuccessful = true; + return false; + } - // TEST - Dbprintf("Succesfully authenticated with logdata:"); - Dbhexdump(4,logdata_1,false); - bSuccessful = true; - return false; + // TEST + Dbprintf("Succesfully authenticated with logdata:"); + Dbhexdump(4, logdata_1, false); + bSuccessful = true; + return false; - // read next page of card until done - tx[0] = 0xe0 | blocknr >> 4; // RDCPAGE - tx[1] = blocknr << 4; - crc = hitag_crc(tx,12); - tx[1] |= crc >> 4; - tx[2] = crc << 4; - *txlen = 20; - } - } break; - default: { - Dbprintf("Uknown frame length: %d",rxlen); - return false; - } break; - } + // read next page of card until done + tx[0] = 0xe0 | blocknr >> 4; // RDCPAGE + tx[1] = blocknr << 4; + crc = hitag_crc(tx, 12); + tx[1] |= crc >> 4; + tx[2] = crc << 4; + *txlen = 20; + } + } + break; + default: { + Dbprintf("Uknown frame length: %d", rxlen); + return false; + } + break; + } - return true; + return true; } //----------------------------------------------------------------------------- @@ -919,7 +925,7 @@ static bool hitag2_read_uid(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t // Store the received block memcpy(tag.sectors[blocknr], rx, 4); blocknr++; - + Dbhexdump(4, rx, false); } if (blocknr > 0) { @@ -944,7 +950,7 @@ void SniffHitag(void) { LEDsoff(); StopTicks(); - + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); BigBuf_free(); BigBuf_Clear_ext(false); @@ -968,17 +974,17 @@ void SniffHitag(void) { /*bool waiting_for_first_edge = true;*/ LED_C_ON(); - + while (!BUTTON_PRESS() && !data_available()) { WDT_HIT(); - // Receive frame, watch for at most T0*EOF periods + // Receive frame, watch for at most T0*EOF periods lf_reset_counter(); - + // Wait "infinite" for reader modulation periods = lf_detect_gap(20000); - + // Test if we detected the first reader modulation edge if (periods != 0) { if (logging == false) { @@ -986,29 +992,29 @@ void SniffHitag(void) { LED_D_ON(); } } - + /*lf_count_edge_periods(10000);*/ - while ((periods = lf_detect_gap(64)) != 0){ + while ((periods = lf_detect_gap(64)) != 0) { num_to_bytes(periods, 4, periods_bytes); LogTrace(periods_bytes, 4, 0, 0, NULL, true); } - -/* - // Check if frame was captured - if (rxlen > 0) { - // frame_count++; - LogTrace(rx, nbytes(rxlen), response, 0, NULL, reader_frame); - // Check if we recognize a valid authentication attempt - if (nbytes(rxlen) == 8) { - // Store the authentication attempt - if (auth_table_len < (AUTH_TABLE_LENGTH - 8)) { - memcpy(auth_table + auth_table_len, rx, 8); - auth_table_len += 8; - } - } -*/ + /* + // Check if frame was captured + if (rxlen > 0) { + // frame_count++; + LogTrace(rx, nbytes(rxlen), response, 0, NULL, reader_frame); + + // Check if we recognize a valid authentication attempt + if (nbytes(rxlen) == 8) { + // Store the authentication attempt + if (auth_table_len < (AUTH_TABLE_LENGTH - 8)) { + memcpy(auth_table + auth_table_len, rx, 8); + auth_table_len += 8; + } + } + */ } lf_finalize(); @@ -1204,54 +1210,56 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { uint8_t txbuf[HITAG_FRAME_LEN]; uint8_t *tx = txbuf; size_t txlen = 0; - int t_wait_1; - int t_wait_2; - size_t tag_size; - bool bStop = false; - + int t_wait_1; + int t_wait_2; + size_t tag_size; + bool bStop = false; + // Raw demodulation/decoding by sampling edge periods size_t periods = 0; - - // Reset the return status - bSuccessful = false; - bCrypto = false; - - // Clean up trace and prepare it for storing frames - set_tracing(true); - clear_trace(); - DbpString("Starting Hitag reader family"); + // Reset the return status + bSuccessful = false; + bCrypto = false; + + // Clean up trace and prepare it for storing frames + set_tracing(true); + clear_trace(); + + DbpString("Starting Hitag reader family"); // Check configuration switch (htf) { - case RHT1F_PLAIN: { - Dbprintf("Read public blocks in plain mode"); - // this part will be unreadable - memset(tag.sectors+2, 0x0, 30); - blocknr = 0; - } break; - - case RHT1F_AUTHENTICATE: { - Dbprintf("Read all blocks in authed mode"); - memcpy(nonce, htd->ht1auth.nonce, 4); - memcpy(key, htd->ht1auth.key, 4); - memcpy(logdata_0, htd->ht1auth.logdata_0, 4); - memcpy(logdata_1, htd->ht1auth.logdata_1, 4); - // TEST - memset(nonce, 0x0, 4); - memset(logdata_1, 0x00, 4); - byte_value = 0; - key_no = htd->ht1auth.key_no; - Dbprintf("Authenticating using key #%d:", key_no); - Dbhexdump(4, key, false); - DbpString("Nonce:"); - Dbhexdump(4, nonce, false); - DbpString("Logdata_0:"); - Dbhexdump(4, logdata_0, false); - DbpString("Logdata_1:"); - Dbhexdump(4, logdata_1, false); + case RHT1F_PLAIN: { + Dbprintf("Read public blocks in plain mode"); + // this part will be unreadable + memset(tag.sectors + 2, 0x0, 30); blocknr = 0; - } break; + } + break; + + case RHT1F_AUTHENTICATE: { + Dbprintf("Read all blocks in authed mode"); + memcpy(nonce, htd->ht1auth.nonce, 4); + memcpy(key, htd->ht1auth.key, 4); + memcpy(logdata_0, htd->ht1auth.logdata_0, 4); + memcpy(logdata_1, htd->ht1auth.logdata_1, 4); + // TEST + memset(nonce, 0x0, 4); + memset(logdata_1, 0x00, 4); + byte_value = 0; + key_no = htd->ht1auth.key_no; + Dbprintf("Authenticating using key #%d:", key_no); + Dbhexdump(4, key, false); + DbpString("Nonce:"); + Dbhexdump(4, nonce, false); + DbpString("Logdata_0:"); + Dbhexdump(4, logdata_0, false); + DbpString("Logdata_1:"); + Dbhexdump(4, logdata_1, false); + blocknr = 0; + } + break; case RHT2F_PASSWORD: { Dbprintf("List identifier in password mode"); memcpy(password, htd->pwd.password, 4); @@ -1272,9 +1280,9 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { DbpString("Authenticating using key:"); memcpy(key, htd->crypto.key, 6); //HACK; 4 or 6?? I read both in the code. Dbhexdump(6, key, false); - DbpString("Nonce:"); - Dbhexdump(4,nonce,false); - memcpy(nonce,htd->crypto.data,4); + DbpString("Nonce:"); + Dbhexdump(4, nonce, false); + memcpy(nonce, htd->crypto.data, 4); blocknr = 0; bCrypto = false; bAuthenticating = false; @@ -1308,9 +1316,9 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { lf_init(true); uint8_t attempt_count = 0; - + // Tag specific configuration settings (sof, timings, etc.) - if (htf < 10){ + if (htf < 10) { // hitagS settings t_wait_1 = 204; t_wait_2 = 128; @@ -1356,14 +1364,16 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { // By default reset the transmission buffer tx = txbuf; switch (htf) { - case RHT1F_PLAIN: { - bStop = !hitag_plain(rx, rxlen, tx, &txlen, false); - } break; - + case RHT1F_PLAIN: { + bStop = !hitag_plain(rx, rxlen, tx, &txlen, false); + } + break; + case RHT1F_AUTHENTICATE: { - bStop = !hitag1_authenticate(rx, rxlen, tx, &txlen); - } break; - + bStop = !hitag1_authenticate(rx, rxlen, tx, &txlen); + } + break; + case RHT2F_PASSWORD: { bStop = !hitag2_password(rx, rxlen, tx, &txlen, false); break; @@ -1396,7 +1406,7 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { // Wait for t_wait_2 carrier periods after the last tag bit before transmitting, lf_wait_periods(t_wait_2); - + // Transmit the reader frame hitag_reader_send_frame(tx, txlen); @@ -1406,13 +1416,13 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { // Reset the response time (in number of periods) response = 0; - + // Keep administration of the first edge detection bool waiting_for_first_edge = true; // Did we detected any modulaiton at all bool detected_tag_modulation = false; - + // Use the current modulation state as starting point tag_modulation = lf_get_tag_modulation(); @@ -1427,7 +1437,7 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { // Just break out of loop after an initial time-out (tag is probably not available) if (periods == 0) break; // Register the number of periods that have passed - response = t_wait_1-64 + periods; + response = t_wait_1 - 64 + periods; // Indicate that we have dealt with the first edge waiting_for_first_edge = false; // The first edge is always a single NRZ bit, force periods on 16 @@ -1437,20 +1447,20 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { } else { // The function lf_count_edge_periods() returns 0 when a time-out occurs if (periods == 0) { - Dbprintf("Detected timeout after [%d] nrz samples",nrzs); + Dbprintf("Detected timeout after [%d] nrz samples", nrzs); break; } } - + // Evaluate the number of periods before the next edge - if (periods > 24 && periods <= 64){ + if (periods > 24 && periods <= 64) { // Detected two sequential equal bits and a modulation switch // NRZ modulation: (11 => --|) or (11 __|) nrz_samples[nrzs++] = tag_modulation; nrz_samples[nrzs++] = tag_modulation; // Invert tag modulation state tag_modulation ^= 1; - } else if (periods > 0 && periods <= 24){ + } else if (periods > 0 && periods <= 24) { // Detected one bit and a modulation switch // NRZ modulation: (1 => -|) or (0 _|) nrz_samples[nrzs++] = tag_modulation; @@ -1492,24 +1502,24 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { LED_B_ON(); // decode bitstream - manrawdecode((uint8_t*)nrz_samples, &nrzs, true, 0); + manrawdecode((uint8_t *)nrz_samples, &nrzs, true, 0); // decode frame - + // Verify if the header consists of five consecutive ones if (nrzs < 5) { - Dbprintf("Detected unexpected number of manchester decoded samples [%d]",nrzs); + Dbprintf("Detected unexpected number of manchester decoded samples [%d]", nrzs); break; } else { - for (size_t i = 0; i < 5; i++){ + for (size_t i = 0; i < 5; i++) { if (nrz_samples[i] != 1) { - Dbprintf("Detected incorrect header, the bit [%d] is zero instead of one",i); + Dbprintf("Detected incorrect header, the bit [%d] is zero instead of one", i); } } } - + // Pack the response into a byte array - for (size_t i = 5; i < nrzs; i++){ + for (size_t i = 5; i < nrzs; i++) { uint8_t bit = nrz_samples[i]; rx[rxlen / 8] |= bit << (7 - (rxlen % 8)); rxlen++; @@ -1529,11 +1539,11 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { LogTrace(rx, nbytes(rxlen), response, 0, NULL, false); Dbhexdump(nbytes(rxlen), rx, false); } - } + } out: lf_finalize(); - Dbprintf("frame received: %u", frame_count); + Dbprintf("frame received: %u", frame_count); // release allocated memory from BigBuff. BigBuf_free(); diff --git a/include/hitag.h b/include/hitag.h index b8555600b..af90c9f88 100644 --- a/include/hitag.h +++ b/include/hitag.h @@ -21,8 +21,8 @@ typedef enum { RHTSF_KEY = 02, WHTSF_CHALLENGE = 03, WHTSF_KEY = 04, - RHT1F_PLAIN = 11, - RHT1F_AUTHENTICATE = 12, + RHT1F_PLAIN = 11, + RHT1F_AUTHENTICATE = 12, RHT2F_PASSWORD = 21, RHT2F_AUTHENTICATE = 22, RHT2F_CRYPTO = 23, @@ -47,16 +47,16 @@ typedef struct { } PACKED rht2d_crypto; typedef struct { - bool key_no; - uint8_t logdata_0[4]; - uint8_t logdata_1[4]; - uint8_t nonce[4]; - uint8_t key[4]; + bool key_no; + uint8_t logdata_0[4]; + uint8_t logdata_1[4]; + uint8_t nonce[4]; + uint8_t key[4]; } PACKED rht1d_authenticate; typedef union { rht2d_password pwd; - rht1d_authenticate ht1auth; + rht1d_authenticate ht1auth; rht2d_authenticate auth; rht2d_crypto crypto; } hitag_data; From b2db893e836c0f37f6d0c2ea1ebe72aaf02d3fa7 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 15 Jan 2020 21:14:16 +0100 Subject: [PATCH 1455/1854] fix hitag demodulation when ending on unexpected period count + completion with last half --- armsrc/hitag2.c | 1 - 1 file changed, 1 deletion(-) diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index 474207590..b9aeafd2b 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -1466,7 +1466,6 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { nrz_samples[nrzs++] = tag_modulation; tag_modulation ^= 1; } else { - tag_modulation ^= 1; // The function lf_count_edge_periods() returns > 64 periods, this is not a valid number periods Dbprintf("Detected unexpected period count: %d", periods); break; From da048ea49144d585ccb49ff2395d5d94b5f67d8d Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 15 Jan 2020 22:07:49 +0100 Subject: [PATCH 1456/1854] fix hitag demodulation when first positive period is not detected --- armsrc/hitag2.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index b9aeafd2b..13681c803 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -1436,8 +1436,18 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { if (waiting_for_first_edge) { // Just break out of loop after an initial time-out (tag is probably not available) if (periods == 0) break; - // Register the number of periods that have passed - response = t_wait_1 - 64 + periods; + if (tag_modulation == 0) { + // hitag replies always start with 11111 == 1010101010, if we see 0 + // it means we missed the first period, e.g. if the signal never crossed 0 since reader signal + // so let's add it: + nrz_samples[nrzs++] = tag_modulation ^ 1; + // Register the number of periods that have passed + // we missed the begin of response but we know it happened one period of 16 earlier + response = t_wait_1 - 64 + periods - 16; + } else { + // Register the number of periods that have passed + response = t_wait_1 - 64 + periods; + } // Indicate that we have dealt with the first edge waiting_for_first_edge = false; // The first edge is always a single NRZ bit, force periods on 16 From aa0879eee42aca4515e608f172d6136f82f77841 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 15 Jan 2020 23:22:42 +0100 Subject: [PATCH 1457/1854] reduce window included in wait_1 before response to avoid phantom symbols --- armsrc/hitag2.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index 13681c803..9127926d8 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -1211,6 +1211,7 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { uint8_t *tx = txbuf; size_t txlen = 0; int t_wait_1; + int t_wait_1_guard = 8; int t_wait_2; size_t tag_size; bool bStop = false; @@ -1412,7 +1413,7 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { // Let the antenna and ADC values settle // And find the position where edge sampling should start - lf_wait_periods(t_wait_1 - 64); + lf_wait_periods(t_wait_1 - t_wait_1_guard); // Reset the response time (in number of periods) response = 0; @@ -1443,10 +1444,10 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { nrz_samples[nrzs++] = tag_modulation ^ 1; // Register the number of periods that have passed // we missed the begin of response but we know it happened one period of 16 earlier - response = t_wait_1 - 64 + periods - 16; + response = t_wait_1 - t_wait_1_guard + periods - 16; } else { // Register the number of periods that have passed - response = t_wait_1 - 64 + periods; + response = t_wait_1 - t_wait_1_guard + periods; } // Indicate that we have dealt with the first edge waiting_for_first_edge = false; From 65de9ca2c22767ace3544c6656d4c10e1791c3fa Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 15 Jan 2020 23:25:30 +0100 Subject: [PATCH 1458/1854] hitag: RX was logged twice --- armsrc/hitag2.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index 9127926d8..f61cdf432 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -1354,14 +1354,6 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { WDT_HIT(); - // Check if frame was captured and store it - if (rxlen > 0) { - frame_count++; - response++; - LogTrace(rx, nbytes(rxlen), response, response, NULL, false); - //Dbhexdump(nbytes(rxlen), rx, false); - } - // By default reset the transmission buffer tx = txbuf; switch (htf) { @@ -1546,7 +1538,8 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { // rxlen = 32; // } - LogTrace(rx, nbytes(rxlen), response, 0, NULL, false); + // TODO response times should be cumulative/absolute + LogTrace(rx, nbytes(rxlen), response, response, NULL, false); Dbhexdump(nbytes(rxlen), rx, false); } } From 3d95590fc92c071edaf487838176509770fb4924 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 15 Jan 2020 23:26:02 +0100 Subject: [PATCH 1459/1854] hitag: comment debug messages in critical loop --- armsrc/hitag2.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index f61cdf432..a161b4463 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -1450,7 +1450,7 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { } else { // The function lf_count_edge_periods() returns 0 when a time-out occurs if (periods == 0) { - Dbprintf("Detected timeout after [%d] nrz samples", nrzs); + //Dbprintf("Detected timeout after [%d] nrz samples", nrzs); break; } } @@ -1470,7 +1470,7 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { tag_modulation ^= 1; } else { // The function lf_count_edge_periods() returns > 64 periods, this is not a valid number periods - Dbprintf("Detected unexpected period count: %d", periods); + //Dbprintf("Detected unexpected period count: %d", periods); break; } } @@ -1510,7 +1510,7 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { // Verify if the header consists of five consecutive ones if (nrzs < 5) { - Dbprintf("Detected unexpected number of manchester decoded samples [%d]", nrzs); + //Dbprintf("Detected unexpected number of manchester decoded samples [%d]", nrzs); break; } else { for (size_t i = 0; i < 5; i++) { From 52640422f121f52b9e039a62de058093bc1d504b Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 16 Jan 2020 00:01:03 +0100 Subject: [PATCH 1460/1854] hitag: wip timings in trace, still "lf hitag list" hangs quite often... --- armsrc/hitag2.c | 45 +++++++++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index a161b4463..242f778f4 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -297,7 +297,8 @@ static void hitag2_handle_reader_command(uint8_t *rx, const size_t rxlen, uint8_ } // sim -static void hitag_reader_send_bit(int bit) { +static uint32_t hitag_reader_send_bit(int bit) { + uint32_t wait = 0; LED_A_ON(); // Binary pulse length modulation (BPLM) is used to encode the data stream // This means that a transmission of a one takes longer than that of a zero @@ -307,6 +308,7 @@ static void hitag_reader_send_bit(int bit) { // Wait for 4-10 times the carrier period lf_wait_periods(8); // wait for 4-10 times the carrier period + wait += 8; // Disable modulation, just activates the field again lf_modulation(false); @@ -314,29 +316,36 @@ static void hitag_reader_send_bit(int bit) { if (bit == 0) { // Zero bit: |_-| lf_wait_periods(12); // wait for 18-22 times the carrier period + wait += 12; } else { // One bit: |_--| lf_wait_periods(22); // wait for 26-32 times the carrier period + wait += 22; } /*lf_wait_periods(10);*/ LED_A_OFF(); + return wait; } // sim -static void hitag_reader_send_frame(const uint8_t *frame, size_t frame_len) { +static uint32_t hitag_reader_send_frame(const uint8_t *frame, size_t frame_len) { + uint32_t wait = 0; // Send the content of the frame for (size_t i = 0; i < frame_len; i++) { - hitag_reader_send_bit((frame[i / 8] >> (7 - (i % 8))) & 1); + wait += hitag_reader_send_bit((frame[i / 8] >> (7 - (i % 8))) & 1); } // Enable modulation, which means, drop the field lf_modulation(true); // Wait for 4-10 times the carrier period lf_wait_periods(8); + wait += 8; // Disable modulation, just activates the field again lf_modulation(false); // t_stop, high field for stop condition (> 36) lf_wait_periods(28); + wait += 28; + return wait; } size_t blocknr; @@ -1204,7 +1213,10 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { StopTicks(); int frame_count = 0; - int response; + uint32_t command_start = 0; + uint32_t command_duration = 0; + uint32_t response_start = 0; + uint32_t response_duration = 0; uint8_t rx[HITAG_FRAME_LEN]; size_t rxlen = 0; uint8_t txbuf[HITAG_FRAME_LEN]; @@ -1399,16 +1411,16 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { // Wait for t_wait_2 carrier periods after the last tag bit before transmitting, lf_wait_periods(t_wait_2); + command_start += t_wait_2; // Transmit the reader frame - hitag_reader_send_frame(tx, txlen); + command_duration = hitag_reader_send_frame(tx, txlen); + response_start = command_start + command_duration; // Let the antenna and ADC values settle // And find the position where edge sampling should start lf_wait_periods(t_wait_1 - t_wait_1_guard); - - // Reset the response time (in number of periods) - response = 0; + response_start += t_wait_1 - t_wait_1_guard; // Keep administration of the first edge detection bool waiting_for_first_edge = true; @@ -1436,10 +1448,12 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { nrz_samples[nrzs++] = tag_modulation ^ 1; // Register the number of periods that have passed // we missed the begin of response but we know it happened one period of 16 earlier - response = t_wait_1 - t_wait_1_guard + periods - 16; + response_start += periods - 16; + response_duration = response_start; } else { // Register the number of periods that have passed - response = t_wait_1 - t_wait_1_guard + periods; + response_start += periods; + response_duration = response_start; } // Indicate that we have dealt with the first edge waiting_for_first_edge = false; @@ -1454,19 +1468,20 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { break; } } - // Evaluate the number of periods before the next edge if (periods > 24 && periods <= 64) { // Detected two sequential equal bits and a modulation switch // NRZ modulation: (11 => --|) or (11 __|) nrz_samples[nrzs++] = tag_modulation; nrz_samples[nrzs++] = tag_modulation; + response_duration += periods; // Invert tag modulation state tag_modulation ^= 1; } else if (periods > 0 && periods <= 24) { // Detected one bit and a modulation switch // NRZ modulation: (1 => -|) or (0 _|) nrz_samples[nrzs++] = tag_modulation; + response_duration += periods; tag_modulation ^= 1; } else { // The function lf_count_edge_periods() returns > 64 periods, this is not a valid number periods @@ -1480,7 +1495,7 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { // still use the same memory space) if (txlen > 0) { frame_count++; - LogTrace(tx, nbytes(txlen), HITAG_T_WAIT_2, HITAG_T_WAIT_2, NULL, true); + LogTrace(tx, nbytes(txlen), command_start, command_start + command_duration, NULL, true); } // Reset values for receiving frames @@ -1538,8 +1553,10 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { // rxlen = 32; // } - // TODO response times should be cumulative/absolute - LogTrace(rx, nbytes(rxlen), response, response, NULL, false); + LogTrace(rx, nbytes(rxlen), response_start, response_start + response_duration, NULL, false); +// TODO when using cumulative time for command_start, pm3 doesn't reply anymore, e.g. on lf hitag read 23 4F4E4D494B52 +// command_start = response_start + response_duration; + command_start = 0; Dbhexdump(nbytes(rxlen), rx, false); } } From d2fb44710ff936c3b994a1084560fc787425639e Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 16 Jan 2020 00:07:54 +0100 Subject: [PATCH 1461/1854] Abort when Manchester goes wrong rather than outputting wrong values --- armsrc/hitag2.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index 242f778f4..90cdc53c3 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -1538,6 +1538,10 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { // Pack the response into a byte array for (size_t i = 5; i < nrzs; i++) { uint8_t bit = nrz_samples[i]; + if (bit > 1) { // When Manchester detects impossible symbol it writes "7" + //Dbprintf("Error in Manchester decoding, abort"); + break; + } rx[rxlen / 8] |= bit << (7 - (rxlen % 8)); rxlen++; } From 870bbd1f775b82f768426c979cae841f0ec980d0 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 16 Jan 2020 00:09:06 +0100 Subject: [PATCH 1462/1854] hitag: comment data dump --- armsrc/hitag2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index 90cdc53c3..a5a3e92cb 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -1561,7 +1561,7 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { // TODO when using cumulative time for command_start, pm3 doesn't reply anymore, e.g. on lf hitag read 23 4F4E4D494B52 // command_start = response_start + response_duration; command_start = 0; - Dbhexdump(nbytes(rxlen), rx, false); + // Dbhexdump(nbytes(rxlen), rx, false); } } From 7a27f5dddb0033d0fcf1c6d1c77ac078db868bd2 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 16 Jan 2020 00:25:44 +0100 Subject: [PATCH 1463/1854] rephrase debug --- armsrc/hitag2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index a5a3e92cb..3920d0010 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -1567,7 +1567,7 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { out: lf_finalize(); - Dbprintf("frame received: %u", frame_count); + Dbprintf("TX/RX frames recorded: %u", frame_count); // release allocated memory from BigBuff. BigBuf_free(); From 9df6fa8e8e1382c592e74683567dd1517bd74368 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 16 Jan 2020 00:26:15 +0100 Subject: [PATCH 1464/1854] hitag: stop detecting if response header is corrupted --- armsrc/hitag2.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index 3920d0010..4387f109f 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -1528,11 +1528,14 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { //Dbprintf("Detected unexpected number of manchester decoded samples [%d]", nrzs); break; } else { - for (size_t i = 0; i < 5; i++) { + size_t i; + for (i = 0; i < 5; i++) { if (nrz_samples[i] != 1) { - Dbprintf("Detected incorrect header, the bit [%d] is zero instead of one", i); + Dbprintf("Detected incorrect header, the bit [%d] is zero instead of one, abort", i); + break; } } + if (i < 5) break; } // Pack the response into a byte array From f2eec56fb72e30991a7677905886864850f337ea Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 16 Jan 2020 00:49:05 +0100 Subject: [PATCH 1465/1854] hitag: cosmetic --- armsrc/hitag2.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index 4387f109f..b962e04df 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -315,12 +315,12 @@ static uint32_t hitag_reader_send_bit(int bit) { if (bit == 0) { // Zero bit: |_-| - lf_wait_periods(12); // wait for 18-22 times the carrier period - wait += 12; + lf_wait_periods(20-8); // wait for 18-22 times the carrier period + wait += 20-8; } else { // One bit: |_--| - lf_wait_periods(22); // wait for 26-32 times the carrier period - wait += 22; + lf_wait_periods(30-8); // wait for 26-32 times the carrier period + wait += 30-8; } /*lf_wait_periods(10);*/ LED_A_OFF(); @@ -343,8 +343,8 @@ static uint32_t hitag_reader_send_frame(const uint8_t *frame, size_t frame_len) lf_modulation(false); // t_stop, high field for stop condition (> 36) - lf_wait_periods(28); - wait += 28; + lf_wait_periods(36-8); + wait += 36-8; return wait; } From 631c11e22cbdac3c1a3f4d93991e77fd097d816b Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 16 Jan 2020 00:57:21 +0100 Subject: [PATCH 1466/1854] hitag: use defines --- armsrc/hitag2.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index b962e04df..410b7f84b 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -109,11 +109,13 @@ static int hitag2_init(void) { #define HITAG_T_STOP 36 /* T_EOF should be > 36 */ #define HITAG_T_LOW 8 /* T_LOW should be 4..10 */ #define HITAG_T_0_MIN 15 /* T[0] should be 18..22 */ +#define HITAG_T_0 20 /* T[0] should be 18..22 */ #define HITAG_T_1_MIN 25 /* T[1] should be 26..30 */ +#define HITAG_T_1 30 /* T[1] should be 26..30 */ //#define HITAG_T_EOF 40 /* T_EOF should be > 36 */ #define HITAG_T_EOF 80 /* T_EOF should be > 36 */ #define HITAG_T_WAIT_1 200 /* T_wresp should be 199..206 */ -#define HITAG_T_WAIT_2 90 /* T_wresp should be 199..206 */ +#define HITAG_T_WAIT_2 90 /* T_wait2 should be at least 90 */ #define HITAG_T_WAIT_MAX 300 /* bit more than HITAG_T_WAIT_1 + HITAG_T_WAIT_2 */ #define HITAG_T_PROG 614 @@ -315,12 +317,12 @@ static uint32_t hitag_reader_send_bit(int bit) { if (bit == 0) { // Zero bit: |_-| - lf_wait_periods(20-8); // wait for 18-22 times the carrier period - wait += 20-8; + lf_wait_periods(HITAG_T_0-HITAG_T_LOW); // wait for 18-22 times the carrier period + wait += HITAG_T_0-HITAG_T_LOW; } else { // One bit: |_--| - lf_wait_periods(30-8); // wait for 26-32 times the carrier period - wait += 30-8; + lf_wait_periods(HITAG_T_1-HITAG_T_LOW); // wait for 26-32 times the carrier period + wait += HITAG_T_1-HITAG_T_LOW; } /*lf_wait_periods(10);*/ LED_A_OFF(); @@ -337,14 +339,14 @@ static uint32_t hitag_reader_send_frame(const uint8_t *frame, size_t frame_len) // Enable modulation, which means, drop the field lf_modulation(true); // Wait for 4-10 times the carrier period - lf_wait_periods(8); - wait += 8; + lf_wait_periods(HITAG_T_LOW); + wait += HITAG_T_LOW; // Disable modulation, just activates the field again lf_modulation(false); // t_stop, high field for stop condition (> 36) - lf_wait_periods(36-8); - wait += 36-8; + lf_wait_periods(HITAG_T_STOP-HITAG_T_LOW); + wait += HITAG_T_STOP-HITAG_T_LOW; return wait; } @@ -1349,7 +1351,7 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { } else if (htf < 30) { // hitag2 settings t_wait_1 = 206; - t_wait_2 = 90; + t_wait_2 = HITAG_T_WAIT_2; tag_size = 48; DbpString("Configured for hitag2 reader"); } else { From 091a594063afabbc4ff76bf6f9bf2f7d88013062 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 16 Jan 2020 01:12:34 +0100 Subject: [PATCH 1467/1854] hitag: more timings --- armsrc/hitag2.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index 410b7f84b..f27a9cf5e 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -114,8 +114,8 @@ static int hitag2_init(void) { #define HITAG_T_1 30 /* T[1] should be 26..30 */ //#define HITAG_T_EOF 40 /* T_EOF should be > 36 */ #define HITAG_T_EOF 80 /* T_EOF should be > 36 */ -#define HITAG_T_WAIT_1 200 /* T_wresp should be 199..206 */ -#define HITAG_T_WAIT_2 90 /* T_wait2 should be at least 90 */ +#define HITAG_T_WAIT_1_MIN 199 /* T_wresp should be 199..206 */ +#define HITAG_T_WAIT_2_MIN 90 /* T_wait2 should be at least 90 */ #define HITAG_T_WAIT_MAX 300 /* bit more than HITAG_T_WAIT_1 + HITAG_T_WAIT_2 */ #define HITAG_T_PROG 614 @@ -345,8 +345,8 @@ static uint32_t hitag_reader_send_frame(const uint8_t *frame, size_t frame_len) lf_modulation(false); // t_stop, high field for stop condition (> 36) - lf_wait_periods(HITAG_T_STOP-HITAG_T_LOW); - wait += HITAG_T_STOP-HITAG_T_LOW; + lf_wait_periods(HITAG_T_STOP); + wait += HITAG_T_STOP; return wait; } @@ -1172,7 +1172,7 @@ void SimulateHitagTag(bool tag_mem_supplied, uint8_t *data) { // with respect to the falling edge, we need to wait actually (T_Wait1 - T_Low) // periods. The gap time T_Low varies (4..10). All timer values are in // terms of T0 units - while (AT91C_BASE_TC0->TC_CV < T0 * (HITAG_T_WAIT_1 - HITAG_T_LOW)); + while (AT91C_BASE_TC0->TC_CV < T0 * (HITAG_T_WAIT_1_MIN - HITAG_T_LOW)); // Send and store the tag answer (if there is any) if (txlen) { @@ -1350,8 +1350,8 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { DbpString("Configured for hitag1 reader"); } else if (htf < 30) { // hitag2 settings - t_wait_1 = 206; - t_wait_2 = HITAG_T_WAIT_2; + t_wait_1 = HITAG_T_WAIT_1_MIN; + t_wait_2 = HITAG_T_WAIT_2_MIN; tag_size = 48; DbpString("Configured for hitag2 reader"); } else { @@ -1697,7 +1697,7 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) { } else if (htf < 30) { // hitag2 settings reset_sof = 4; - t_wait = HITAG_T_WAIT_2; + t_wait = HITAG_T_WAIT_2_MIN; } else { Dbprintf("Error, unknown hitag reader type: %d", htf); return; @@ -1751,7 +1751,7 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) { // Add transmitted frame to total count if (txlen > 0) { // frame_count++; - LogTrace(tx, nbytes(txlen), HITAG_T_WAIT_2, HITAG_T_WAIT_2, NULL, true); + LogTrace(tx, nbytes(txlen), HITAG_T_WAIT_2_MIN, HITAG_T_WAIT_2_MIN, NULL, true); } // Reset values for receiving frames From 958754edf47157b7136dfb83dbcb30f97a56b0eb Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 16 Jan 2020 10:42:39 +0100 Subject: [PATCH 1468/1854] enforce following lf config --- armsrc/lfadc.c | 7 +++---- armsrc/lfsampling.c | 4 ++++ armsrc/lfsampling.h | 1 + 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/armsrc/lfadc.c b/armsrc/lfadc.c index 09ee5a2a6..c715020a2 100644 --- a/armsrc/lfadc.c +++ b/armsrc/lfadc.c @@ -61,7 +61,7 @@ size_t lf_count_edge_periods_ex(size_t max, bool wait, bool detect_gap) { adc_val = AT91C_BASE_SSC->SSC_RHR; periods++; - if (logging) logSample(adc_val, 1, 8, 0); + if (logging) logSampleSimple(adc_val); // Only test field changes if state of adc values matter if (!wait) { @@ -91,7 +91,7 @@ size_t lf_count_edge_periods_ex(size_t max, bool wait, bool detect_gap) { if (periods == max) return 0; } } - if (logging) logSample(255, 1, 8, 0); + if (logging) logSampleSimple(0xFF); return 0; } @@ -206,14 +206,13 @@ size_t lf_detect_field_drop(size_t max) { } ++checked; - // Watchdog hit WDT_HIT(); if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { periods++; adc_val = AT91C_BASE_SSC->SSC_RHR; - if (logging) logSample(adc_val, 1, 8, 0); + if (logging) logSampleSimple(adc_val); if (adc_val == 0) { rising_edge = false; diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index eb3edb029..2d92cd692 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -138,6 +138,10 @@ uint32_t getSampleCounter() { return samples.total_saved; } +void logSampleSimple(uint8_t sample) { + logSample(sample, config.decimation, config.bits_per_sample, config.averaging); +} + void logSample(uint8_t sample, uint8_t decimation, uint8_t bits_per_sample, bool avg) { if (!data.buffer) return; diff --git a/armsrc/lfsampling.h b/armsrc/lfsampling.h index e97a3ac1a..cd3a8993e 100644 --- a/armsrc/lfsampling.h +++ b/armsrc/lfsampling.h @@ -70,6 +70,7 @@ uint32_t DoAcquisition_config(bool verbose, uint32_t sample_size); * Refactoring of lf sampling buffer */ void initSampleBuffer(uint32_t *sample_size); +void logSampleSimple(uint8_t sample); void logSample(uint8_t sample, uint8_t decimation, uint8_t bits_per_sample, bool avg); uint32_t getSampleCounter(); From 31daa9e302c3efc12aa7511c91c9c16b1ce5349d Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 16 Jan 2020 10:43:13 +0100 Subject: [PATCH 1469/1854] added hitag2crack --- tools/hitag2crack/.gitignore | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tools/hitag2crack/.gitignore diff --git a/tools/hitag2crack/.gitignore b/tools/hitag2crack/.gitignore new file mode 100644 index 000000000..e69de29bb From 329807a21b1cfacbfa3067300c398889a8c38263 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 16 Jan 2020 10:55:39 +0100 Subject: [PATCH 1470/1854] add traces lf sniff ht2 --- traces/sniff-ht2-BC3B8810-acg-reader.pm3 | 2000 +++++++ traces/sniff-ht2-BC3B8810-frosch-reader.pm3 | 5000 ++++++++++++++++++ traces/sniff-ht2-BC3B8810-rfidler-reader.pm3 | 4200 +++++++++++++++ 3 files changed, 11200 insertions(+) create mode 100644 traces/sniff-ht2-BC3B8810-acg-reader.pm3 create mode 100644 traces/sniff-ht2-BC3B8810-frosch-reader.pm3 create mode 100644 traces/sniff-ht2-BC3B8810-rfidler-reader.pm3 diff --git a/traces/sniff-ht2-BC3B8810-acg-reader.pm3 b/traces/sniff-ht2-BC3B8810-acg-reader.pm3 new file mode 100644 index 000000000..720492382 --- /dev/null +++ b/traces/sniff-ht2-BC3B8810-acg-reader.pm3 @@ -0,0 +1,2000 @@ +6 +6 +7 +7 +7 +6 +7 +7 +7 +6 +6 +6 +7 +6 +6 +6 +7 +7 +7 +6 +6 +6 +7 +6 +6 +6 +7 +6 +6 +6 +7 +7 +7 +6 +6 +6 +7 +6 +6 +6 +7 +6 +6 +6 +6 +6 +6 +6 +6 +6 +6 +6 +6 +6 +6 +6 +6 +6 +6 +6 +6 +6 +7 +6 +6 +6 +7 +7 +6 +6 +6 +6 +6 +6 +6 +6 +7 +7 +6 +6 +7 +7 +6 +6 +7 +7 +7 +6 +6 +7 +7 +7 +6 +6 +7 +6 +6 +6 +6 +6 +6 +5 +6 +6 +7 +6 +6 +6 +7 +6 +7 +6 +6 +6 +6 +6 +6 +7 +7 +6 +6 +6 +7 +7 +6 +6 +6 +6 +6 +6 +6 +6 +6 +6 +6 +6 +7 +6 +6 +6 +6 +6 +6 +6 +6 +6 +6 +6 +6 +6 +7 +6 +6 +6 +6 +6 +6 +5 +6 +6 +7 +6 +6 +6 +6 +6 +6 +6 +6 +6 +6 +6 +6 +7 +6 +5 +6 +6 +7 +6 +6 +6 +7 +6 +6 +6 +6 +6 +6 +6 +6 +6 +6 +5 +6 +6 +6 +6 +6 +6 +7 +6 +6 +6 +7 +6 +6 +6 +7 +6 +6 +6 +6 +6 +6 +6 +6 +6 +6 +6 +6 +6 +6 +6 +6 +6 +6 +7 +6 +6 +6 +7 +6 +5 +6 +6 +6 +5 +5 +-17 +-37 +-55 +-71 +-86 +-98 +-110 +-120 +-127 +3 +5 +-17 +-37 +-3 +59 +63 +46 +37 +41 +48 +47 +43 +39 +37 +36 +35 +33 +31 +29 +4 +-18 +-38 +-56 +-72 +-86 +-98 +-110 +-120 +-127 +18 +21 +-3 +-24 +14 +75 +78 +61 +51 +55 +61 +59 +54 +49 +48 +46 +43 +40 +38 +36 +11 +-13 +-33 +-52 +-68 +-82 +-95 +-107 +-117 +-126 +21 +23 +-1 +-23 +17 +77 +80 +63 +53 +56 +29 +4 +-18 +-38 +-55 +-71 +-85 +-98 +-109 +-119 +38 +41 +15 +-8 +31 +92 +94 +76 +65 +68 +40 +14 +-9 +-30 +-48 +-65 +-79 +-93 +-104 +-114 +44 +47 +21 +-3 +37 +97 +99 +79 +69 +72 +43 +17 +-6 +-28 +-46 +-63 +-77 +-91 +-103 +-113 +46 +48 +22 +-2 +38 +98 +99 +80 +70 +73 +77 +74 +68 +63 +60 +57 +54 +51 +48 +44 +42 +39 +38 +35 +33 +30 +30 +28 +37 +44 +50 +54 +55 +53 +52 +49 +48 +46 +44 +41 +39 +37 +35 +33 +31 +29 +28 +26 +25 +24 +23 +22 +20 +19 +19 +18 +17 +15 +15 +15 +14 +13 +13 +12 +12 +11 +11 +10 +11 +10 +10 +9 +9 +9 +9 +8 +8 +8 +8 +7 +7 +7 +7 +7 +6 +6 +7 +7 +7 +6 +6 +7 +7 +7 +6 +6 +6 +6 +6 +5 +6 +5 +6 +5 +5 +5 +6 +5 +5 +5 +6 +5 +6 +5 +5 +6 +6 +5 +5 +5 +6 +5 +5 +5 +6 +5 +5 +5 +6 +6 +6 +5 +5 +6 +6 +5 +5 +6 +6 +5 +5 +5 +5 +6 +5 +5 +5 +5 +6 +5 +5 +5 +6 +5 +5 +5 +5 +5 +5 +4 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +6 +5 +5 +5 +5 +5 +5 +4 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +30 +58 +77 +85 +85 +83 +82 +80 +78 +73 +69 +65 +62 +59 +56 +52 +30 +6 +-14 +-30 +-38 +-42 +-44 +-45 +-44 +-43 +-40 +-37 +-35 +-33 +-31 +-29 +-1 +29 +50 +58 +61 +62 +62 +61 +59 +57 +54 +51 +49 +46 +44 +42 +20 +-3 +-23 +-37 +-45 +-49 +-51 +-51 +-50 +-48 +-46 +-43 +-40 +-37 +-35 +-33 +-5 +26 +48 +56 +58 +58 +60 +59 +57 +54 +52 +49 +47 +44 +41 +39 +18 +-4 +-24 +-39 +-46 +-50 +-52 +-52 +-51 +-48 +-46 +-43 +-41 +-38 +-35 +-33 +-6 +25 +47 +56 +58 +58 +59 +59 +57 +54 +51 +49 +47 +44 +41 +39 +18 +-5 +-24 +-40 +-47 +-50 +-52 +-53 +-51 +-49 +-46 +-44 +-41 +-38 +-35 +-33 +-6 +24 +46 +55 +58 +58 +58 +58 +57 +54 +51 +48 +46 +44 +42 +39 +18 +-4 +-24 +-39 +-46 +-51 +-52 +-52 +-51 +-50 +-46 +-43 +-41 +-39 +-36 +-33 +-6 +25 +46 +55 +58 +58 +59 +58 +57 +54 +52 +48 +46 +44 +42 +39 +18 +-5 +-24 +-39 +-47 +-51 +-52 +-52 +-51 +-49 +-46 +-43 +-41 +-38 +-36 +-34 +-31 +-28 +-26 +-25 +-22 +-20 +-18 +-17 +-16 +-15 +-12 +-11 +-10 +-10 +-8 +-8 +18 +46 +67 +75 +76 +74 +74 +73 +70 +66 +63 +59 +57 +53 +50 +47 +44 +42 +40 +37 +34 +33 +31 +29 +27 +26 +25 +23 +22 +20 +20 +19 +0 +-22 +-40 +-54 +-60 +-64 +-65 +-65 +-62 +-59 +-56 +-53 +-49 +-46 +-43 +-41 +-13 +19 +41 +49 +52 +53 +55 +55 +53 +50 +48 +46 +44 +41 +38 +36 +16 +-7 +-26 +-41 +-48 +-52 +-54 +-55 +-52 +-50 +-47 +-45 +-42 +-39 +-36 +-34 +-7 +24 +46 +55 +57 +56 +58 +58 +56 +53 +51 +48 +46 +43 +41 +39 +18 +-5 +-24 +-39 +-47 +-50 +-52 +-53 +-52 +-49 +-46 +-44 +-42 +-39 +-36 +-34 +-7 +24 +46 +55 +57 +57 +58 +58 +57 +54 +51 +48 +47 +44 +41 +38 +18 +-5 +-25 +-40 +-46 +-50 +-52 +-53 +-51 +-49 +-46 +-44 +-41 +-39 +-36 +-34 +-32 +-29 +-27 +-24 +-23 +-21 +-19 +-17 +-15 +-14 +-13 +-12 +-10 +-9 +-9 +-9 +18 +47 +67 +74 +75 +74 +75 +72 +70 +66 +63 +59 +56 +53 +50 +47 +26 +2 +-18 +-34 +-41 +-45 +-47 +-48 +-47 +-45 +-42 +-40 +-38 +-35 +-33 +-30 +-4 +27 +49 +58 +60 +60 +60 +60 +59 +55 +52 +49 +47 +45 +42 +39 +18 +-4 +-24 +-39 +-46 +-50 +-51 +-52 +-51 +-49 +-45 +-43 +-40 +-39 +-35 +-33 +-6 +24 +46 +55 +58 +58 +58 +58 +57 +54 +51 +48 +46 +43 +41 +38 +17 +-5 +-25 +-40 +-47 +-51 +-52 +-53 +-51 +-49 +-46 +-43 +-41 +-39 +-36 +-33 +-6 +24 +46 +55 +57 +57 +58 +57 +56 +53 +50 +47 +46 +43 +41 +38 +36 +34 +32 +30 +28 +26 +26 +24 +22 +20 +20 +19 +18 +17 +16 +16 +-3 +-24 +-42 +-56 +-63 +-65 +-67 +-67 +-64 +-61 +-57 +-54 +-51 +-48 +-44 +-41 +-14 +17 +40 +49 +52 +52 +53 +53 +53 +50 +47 +44 +43 +40 +38 +35 +14 +-8 +-27 +-42 +-49 +-52 +-53 +-54 +-53 +-50 +-47 +-45 +-43 +-40 +-37 +-34 +-7 +23 +45 +54 +57 +56 +57 +57 +56 +53 +50 +47 +46 +43 +41 +38 +17 +-5 +-25 +-40 +-47 +-51 +-53 +-53 +-52 +-50 +-46 +-44 +-42 +-39 +-36 +-33 +-31 +-29 +-27 +-25 +-22 +-21 +-19 +-18 +-16 +-15 +-14 +-13 +-11 +-10 +-9 +-9 +17 +47 +66 +73 +74 +74 +74 +72 +69 +65 +62 +58 +55 +52 +49 +46 +44 +40 +38 +36 +35 +32 +30 +28 +28 +25 +24 +22 +21 +20 +19 +18 +-2 +-22 +-40 +-54 +-61 +-64 +-65 +-64 +-63 +-59 +-56 +-53 +-50 +-47 +-43 +-40 +-13 +17 +40 +49 +52 +53 +53 +53 +52 +50 +48 +45 +43 +41 +39 +35 +15 +-7 +-27 +-41 +-49 +-52 +-54 +-54 +-53 +-51 +-48 +-45 +-42 +-40 +-37 +-35 +-7 +23 +44 +53 +56 +57 +57 +56 +55 +53 +50 +47 +45 +42 +40 +38 +17 +-5 +-25 +-39 +-47 +-51 +-53 +-53 +-52 +-50 +-47 +-44 +-41 +-39 +-37 +-34 +-31 +-29 +-27 +-25 +-22 +-21 +-19 +-18 +-16 +-15 +-13 +-13 +-11 +-11 +-9 +-9 +17 +46 +66 +73 +74 +73 +73 +72 +69 +65 +62 +59 +56 +52 +49 +46 +25 +1 +-19 +-34 +-42 +-45 +-47 +-48 +-47 +-45 +-42 +-40 +-38 +-36 +-33 +-31 +-3 +26 +47 +56 +59 +58 +59 +58 +57 +54 +52 +48 +46 +44 +41 +39 +18 +-5 +-24 +-39 +-47 +-50 +-52 +-52 +-52 +-49 +-46 +-43 +-41 +-39 +-36 +-34 +-7 +24 +45 +54 +57 +57 +57 +57 +56 +53 +50 +47 +45 +42 +40 +37 +35 +33 +32 +30 +28 +26 +25 +24 +22 +20 +20 +19 +18 +16 +16 +15 +-4 +-25 +-43 +-56 +-63 +-66 +-67 +-67 +-64 +-61 +-58 +-55 +-52 +-48 +-44 +-42 +-39 +-36 +-33 +-31 +-28 +-27 +-24 +-22 +-20 +-19 +-18 +-16 +-14 +-14 +-13 +-12 +15 +44 +63 +70 +72 +72 +72 +70 +68 +64 +61 +57 +54 +51 +49 +46 +24 +0 +-20 +-35 +-42 +-46 +-49 +-49 +-47 +-46 +-43 +-41 +-38 +-36 +-33 +-31 +-5 +27 +48 +56 +58 +58 +59 +58 +56 +54 +51 +49 +46 +43 +41 +39 +18 +-5 +-24 +-39 +-46 +-50 +-52 +-53 +-51 +-49 +-46 +-44 +-42 +-39 +-35 +-33 +-6 +24 +45 +54 +57 +56 +57 +57 +56 +53 +49 +47 +45 +42 +39 +37 +16 +-6 +-25 +-40 +-47 +-51 +-52 +-53 +-52 +-49 +-46 +-44 +-42 +-39 +-36 +-34 +-8 +24 +45 +54 +56 +56 +57 +57 +56 +52 +50 +47 +45 +42 +40 +37 +16 +-6 +-25 +-40 +-47 +-51 +-52 +-53 +-52 +-50 +-46 +-44 +-42 +-39 +-36 +-34 +-7 +23 +45 +54 +56 +57 +57 +57 +56 +53 +50 +47 +45 +43 +40 +37 +16 +-6 +-25 +-40 +-48 +-51 +-53 +-53 +-52 +-50 +-47 +-44 +-41 +-39 +-36 +-34 +-6 +24 +45 +54 +56 +56 +57 +56 +55 +53 +50 +46 +44 +42 +40 +37 +35 +33 +31 +29 +27 +26 +25 +23 +22 +20 +19 +18 +18 +16 +15 +14 +-5 +-25 +-43 +-57 +-63 +-66 +-67 +-67 +-64 +-61 +-57 +-55 +-51 +-48 +-44 +-42 +-39 +-37 +-33 +-31 +-29 +-28 +-25 +-23 +-21 +-20 +-18 +-16 +-14 +-14 +-13 +-12 +14 +43 +63 +70 +72 +71 +71 +69 +67 +64 +60 +56 +53 +51 +48 +45 +23 +0 +-20 +-35 +-43 +-47 +-49 +-49 +-47 +-46 +-44 +-41 +-38 +-36 +-34 +-32 +-4 +26 +47 +55 +57 +58 +59 +58 +56 +53 +51 +48 +45 +42 +40 +39 +17 +-5 +-25 +-39 +-46 +-50 +-52 +-53 +-51 +-49 +-46 +-44 +-42 +-39 +-36 +-34 +-8 +23 +45 +54 +56 +56 +57 +57 +55 +52 +50 +47 +45 +42 +39 +37 +16 +-6 +-26 +-40 +-47 +-51 +-53 +-54 +-52 +-49 +-47 +-45 +-42 +-39 +-36 +-34 +-8 +23 +44 +53 +56 +56 +56 +57 +55 +52 +49 +46 +43 +40 +37 +35 +11 +-13 +-35 +-54 +-71 +-85 +-96 +-104 +-107 +-106 +-103 +-99 +-95 +-89 +-83 +-79 +-74 +-69 +-64 +-60 +-56 +-52 +-49 +-45 +-42 +-39 +-36 +-34 +-31 +-29 +-27 +-25 +-22 +-20 +-19 +-18 +-16 +-14 +-13 +-12 +-11 +-10 +-9 +-8 +-8 +-8 +-6 +-5 +-5 +-5 +-4 +-3 +-2 +-2 +-2 +-2 +-1 +-1 +-1 +-1 +0 +0 +0 +0 +0 +1 +1 +1 +1 +1 +2 +2 +2 +1 +2 +2 +2 +2 +2 +2 +3 +2 +2 +2 +3 +3 +3 +2 +2 +3 +3 +2 +3 +3 +4 +3 +3 +3 +4 +3 +3 +3 +3 +3 +3 +2 +3 +3 +4 +3 +3 +3 +4 +4 +3 +3 +4 +4 +3 +3 +3 +4 +4 +3 +3 +3 +3 +3 +3 +3 +4 +4 +3 +3 +3 +4 +4 +3 +3 +3 +4 +3 +3 +3 +4 +3 +3 +3 +4 +3 +4 +3 +4 +3 +4 +3 +3 +3 +4 +3 +3 +3 +4 +3 +3 +3 +4 +4 +4 +3 +3 +4 +4 +3 +3 +3 +4 +3 +3 +3 +3 +3 +3 +3 +3 +3 +4 +3 +3 +3 +4 +3 +3 +2 +3 +3 +4 +3 +3 +3 +4 +3 +3 +3 +4 +3 +4 +3 +3 +3 +4 +3 +3 +3 +4 +3 +3 +3 +3 +3 +3 +3 +3 +3 +4 +4 +4 +3 +4 +4 +4 +3 +3 +3 +3 +3 +3 +3 +4 +3 +3 +3 +4 +3 +3 +3 +4 +4 +4 +3 +4 +3 +4 +3 diff --git a/traces/sniff-ht2-BC3B8810-frosch-reader.pm3 b/traces/sniff-ht2-BC3B8810-frosch-reader.pm3 new file mode 100644 index 000000000..2a6afbf95 --- /dev/null +++ b/traces/sniff-ht2-BC3B8810-frosch-reader.pm3 @@ -0,0 +1,5000 @@ +14 +14 +15 +15 +14 +14 +14 +15 +14 +14 +13 +14 +14 +14 +13 +14 +14 +14 +14 +14 +14 +15 +14 +14 +14 +15 +15 +14 +14 +15 +14 +15 +14 +15 +14 +15 +14 +14 +14 +15 +14 +14 +14 +15 +15 +14 +14 +14 +14 +14 +13 +14 +14 +15 +14 +14 +14 +15 +13 +13 +13 +14 +14 +14 +13 +14 +14 +14 +14 +14 +14 +14 +13 +13 +13 +14 +14 +13 +13 +14 +14 +14 +13 +14 +13 +14 +13 +14 +14 +14 +14 +13 +13 +14 +14 +14 +14 +14 +14 +13 +13 +13 +13 +14 +13 +13 +13 +14 +14 +14 +13 +14 +14 +14 +13 +14 +14 +15 +14 +14 +14 +14 +14 +13 +14 +14 +14 +13 +13 +13 +13 +13 +13 +13 +13 +14 +13 +13 +13 +14 +13 +13 +13 +14 +13 +13 +13 +14 +14 +14 +13 +13 +13 +13 +13 +13 +13 +14 +14 +13 +13 +14 +14 +14 +13 +14 +14 +14 +13 +13 +13 +14 +13 +14 +13 +14 +12 +13 +12 +13 +13 +13 +13 +14 +13 +13 +13 +13 +13 +13 +13 +13 +13 +13 +13 +12 +12 +13 +13 +13 +13 +14 +14 +13 +13 +13 +13 +14 +13 +14 +13 +14 +13 +14 +13 +14 +14 +13 +13 +13 +13 +13 +13 +13 +13 +13 +12 +12 +12 +13 +13 +13 +13 +13 +13 +13 +13 +13 +13 +13 +13 +13 +13 +13 +12 +12 +13 +13 +13 +12 +13 +13 +12 +12 +12 +13 +13 +13 +12 +13 +13 +13 +12 +13 +13 +13 +13 +13 +13 +13 +13 +12 +12 +13 +13 +12 +12 +12 +13 +13 +12 +13 +13 +14 +13 +13 +13 +13 +12 +12 +12 +12 +12 +12 +12 +12 +12 +12 +12 +12 +13 +13 +13 +13 +13 +13 +12 +12 +12 +13 +12 +12 +12 +12 +12 +12 +12 +12 +13 +13 +12 +13 +13 +13 +12 +12 +12 +13 +13 +12 +12 +12 +12 +12 +12 +13 +12 +13 +11 +12 +12 +12 +12 +12 +12 +12 +13 +12 +12 +12 +13 +12 +12 +12 +13 +13 +12 +12 +12 +12 +11 +12 +12 +12 +12 +11 +11 +12 +12 +12 +12 +12 +12 +12 +12 +12 +12 +12 +11 +11 +12 +12 +11 +12 +12 +12 +12 +12 +11 +12 +12 +12 +11 +12 +12 +12 +11 +11 +12 +12 +12 +12 +11 +12 +12 +12 +11 +12 +12 +12 +11 +11 +11 +12 +12 +11 +11 +12 +12 +11 +11 +12 +12 +12 +11 +12 +11 +12 +11 +11 +11 +12 +12 +12 +12 +12 +12 +11 +11 +11 +12 +11 +11 +11 +12 +11 +11 +11 +11 +12 +11 +11 +11 +12 +11 +11 +11 +12 +12 +12 +11 +11 +11 +11 +10 +11 +11 +12 +11 +11 +11 +12 +11 +11 +11 +11 +11 +11 +11 +11 +12 +12 +12 +12 +11 +12 +11 +11 +11 +11 +11 +11 +10 +11 +11 +12 +11 +11 +11 +12 +11 +11 +11 +12 +12 +12 +11 +11 +11 +11 +10 +11 +10 +11 +10 +10 +11 +11 +11 +-18 +-44 +-67 +-88 +-106 +-122 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-52 +7 +48 +75 +91 +99 +103 +104 +102 +99 +95 +90 +86 +82 +46 +13 +-15 +-41 +-64 +-84 +-102 +-118 +-127 +-127 +-127 +-127 +-127 +-103 +-21 +36 +75 +100 +116 +117 +117 +117 +117 +117 +113 +107 +101 +95 +58 +24 +-6 +-33 +-56 +-77 +-96 +-112 +-127 +-127 +-127 +-127 +-127 +-97 +-15 +42 +80 +105 +117 +117 +117 +117 +87 +51 +18 +-11 +-37 +-60 +-80 +-98 +-114 +-127 +-127 +-127 +-127 +-75 +7 +64 +103 +117 +117 +117 +117 +117 +102 +64 +30 +0 +-27 +-51 +-72 +-91 +-107 +-123 +-127 +-127 +-127 +-68 +14 +71 +109 +117 +117 +117 +117 +117 +117 +102 +64 +30 +0 +-27 +-51 +-72 +-91 +-108 +-123 +-127 +-127 +-127 +-71 +10 +67 +105 +117 +117 +117 +117 +117 +117 +117 +117 +117 +116 +110 +103 +98 +91 +86 +81 +77 +72 +68 +63 +66 +67 +67 +65 +63 +61 +59 +56 +53 +50 +48 +46 +43 +41 +40 +38 +36 +33 +32 +30 +30 +28 +27 +26 +25 +23 +22 +21 +21 +20 +20 +18 +18 +18 +18 +17 +16 +16 +16 +15 +14 +14 +14 +14 +13 +12 +13 +13 +13 +12 +12 +11 +12 +12 +12 +11 +11 +11 +11 +10 +11 +11 +11 +11 +10 +11 +11 +10 +10 +9 +10 +10 +10 +9 +10 +9 +10 +9 +10 +10 +10 +9 +9 +9 +9 +9 +8 +8 +9 +10 +9 +9 +9 +9 +9 +9 +9 +9 +10 +9 +9 +9 +10 +9 +9 +8 +9 +9 +9 +9 +9 +9 +9 +9 +9 +9 +9 +8 +8 +9 +9 +9 +9 +9 +10 +10 +10 +9 +10 +9 +9 +8 +9 +9 +9 +8 +8 +9 +9 +9 +9 +9 +9 +10 +10 +9 +9 +9 +9 +9 +9 +8 +9 +8 +8 +8 +9 +9 +9 +9 +9 +9 +9 +8 +8 +8 +16 +24 +30 +34 +37 +39 +40 +39 +38 +37 +37 +35 +34 +32 +31 +29 +18 +10 +4 +-1 +-5 +-8 +-9 +-9 +-10 +-10 +-9 +-8 +-7 +-7 +-6 +-5 +4 +12 +18 +23 +27 +29 +30 +30 +30 +29 +29 +27 +27 +26 +26 +24 +14 +6 +0 +-5 +-9 +-11 +-12 +-12 +-12 +-12 +-12 +-11 +-9 +-9 +-8 +-7 +2 +10 +17 +22 +26 +28 +29 +29 +29 +29 +28 +27 +27 +26 +25 +24 +14 +6 +-1 +-5 +-9 +-11 +-12 +-12 +-13 +-13 +-12 +-11 +-10 +-10 +-8 +-7 +2 +10 +17 +21 +25 +27 +28 +28 +29 +28 +27 +26 +26 +25 +24 +23 +14 +6 +-1 +-6 +-10 +-11 +-12 +-13 +-13 +-13 +-12 +-11 +-10 +-10 +-9 +-8 +2 +10 +17 +22 +26 +27 +28 +28 +29 +28 +27 +26 +25 +25 +24 +23 +13 +5 +-1 +-6 +-10 +-12 +-13 +-13 +-13 +-14 +-12 +-12 +-10 +-10 +-9 +-8 +2 +10 +16 +21 +25 +27 +28 +29 +29 +29 +28 +26 +26 +25 +24 +22 +13 +5 +-1 +-7 +-11 +-12 +-13 +-14 +-14 +-13 +-12 +-11 +-11 +-11 +-9 +-8 +-7 +-7 +-6 +-5 +-3 +-4 +-3 +-2 +0 +0 +0 +1 +1 +2 +2 +2 +11 +19 +25 +29 +32 +33 +35 +35 +34 +33 +33 +31 +30 +27 +26 +25 +25 +23 +22 +21 +21 +20 +19 +18 +18 +17 +16 +15 +15 +15 +15 +13 +5 +-3 +-9 +-14 +-17 +-19 +-19 +-20 +-19 +-19 +-17 +-16 +-15 +-14 +-13 +-12 +-3 +5 +13 +18 +22 +24 +25 +26 +27 +26 +25 +24 +24 +23 +22 +21 +12 +4 +-3 +-8 +-11 +-13 +-14 +-15 +-15 +-14 +-13 +-13 +-12 +-11 +-9 +-9 +0 +8 +16 +20 +24 +25 +27 +27 +28 +27 +26 +26 +25 +24 +22 +22 +12 +5 +-2 +-8 +-11 +-13 +-14 +-15 +-14 +-14 +-13 +-13 +-12 +-11 +-10 +-10 +-1 +7 +16 +21 +24 +25 +27 +28 +28 +27 +26 +25 +25 +24 +22 +22 +13 +4 +-3 +-8 +-10 +-12 +-13 +-15 +-14 +-14 +-13 +-13 +-12 +-11 +-9 +-9 +-8 +-8 +-7 +-5 +-5 +-4 +-3 +-3 +-2 +-2 +-2 +-1 +0 +0 +1 +1 +10 +17 +24 +27 +31 +32 +33 +33 +33 +32 +32 +30 +28 +27 +26 +25 +15 +7 +0 +-5 +-9 +-11 +-12 +-12 +-12 +-12 +-11 +-11 +-10 +-9 +-9 +-8 +1 +10 +16 +21 +24 +26 +27 +27 +27 +26 +26 +25 +24 +23 +23 +21 +12 +4 +-2 +-7 +-11 +-14 +-14 +-15 +-14 +-14 +-13 +-12 +-12 +-11 +-11 +-10 +-1 +7 +14 +19 +23 +25 +26 +26 +26 +26 +26 +24 +24 +23 +23 +21 +11 +4 +-3 +-8 +-11 +-14 +-15 +-15 +-15 +-15 +-14 +-13 +-12 +-11 +-11 +-11 +-1 +7 +15 +19 +23 +25 +27 +26 +26 +26 +25 +24 +23 +22 +22 +20 +19 +18 +18 +16 +16 +15 +14 +14 +14 +13 +12 +12 +12 +11 +11 +10 +2 +-5 +-11 +-16 +-19 +-20 +-21 +-21 +-21 +-19 +-18 +-18 +-17 +-16 +-14 +-13 +-4 +4 +12 +17 +20 +22 +23 +24 +24 +24 +23 +22 +21 +20 +20 +19 +10 +2 +-4 +-10 +-13 +-15 +-16 +-17 +-16 +-16 +-15 +-14 +-14 +-13 +-11 +-11 +-2 +7 +14 +18 +22 +23 +25 +26 +26 +25 +25 +24 +23 +22 +21 +20 +11 +3 +-4 +-9 +-12 +-14 +-15 +-16 +-16 +-15 +-14 +-14 +-13 +-12 +-11 +-10 +-9 +-8 +-8 +-7 +-6 +-6 +-5 +-4 +-3 +-3 +-3 +-2 +-2 +-2 +-1 +-1 +8 +16 +22 +26 +29 +31 +32 +31 +31 +31 +30 +28 +27 +26 +25 +23 +22 +21 +21 +19 +18 +17 +17 +16 +15 +13 +13 +13 +12 +11 +11 +11 +2 +-6 +-12 +-16 +-19 +-21 +-22 +-22 +-21 +-21 +-20 +-19 +-18 +-17 +-15 +-14 +-5 +4 +11 +15 +19 +22 +24 +24 +24 +23 +23 +22 +21 +20 +20 +19 +10 +1 +-5 +-9 +-12 +-14 +-16 +-17 +-17 +-16 +-16 +-16 +-15 +-14 +-13 +-12 +-3 +6 +13 +18 +21 +23 +26 +26 +26 +24 +24 +23 +22 +20 +20 +19 +10 +2 +-5 +-10 +-12 +-15 +-16 +-17 +-16 +-16 +-16 +-15 +-14 +-13 +-12 +-11 +-10 +-9 +-8 +-8 +-7 +-6 +-5 +-5 +-4 +-3 +-2 +-2 +-2 +-2 +-1 +-1 +8 +15 +21 +25 +28 +30 +30 +30 +30 +29 +28 +27 +26 +25 +24 +23 +14 +5 +-1 +-7 +-10 +-13 +-13 +-14 +-15 +-15 +-14 +-14 +-13 +-12 +-11 +-10 +-1 +6 +13 +18 +22 +24 +25 +25 +26 +25 +23 +22 +22 +21 +20 +19 +10 +2 +-5 +-10 +-13 +-15 +-16 +-18 +-17 +-17 +-16 +-16 +-15 +-13 +-12 +-12 +-4 +5 +12 +17 +21 +22 +24 +24 +24 +23 +23 +23 +22 +21 +20 +19 +18 +17 +16 +15 +15 +14 +14 +12 +12 +11 +11 +10 +10 +9 +9 +9 +0 +-8 +-13 +-17 +-20 +-22 +-22 +-23 +-22 +-22 +-21 +-20 +-18 +-18 +-17 +-16 +-15 +-14 +-12 +-12 +-10 +-9 +-8 +-7 +-7 +-6 +-5 +-5 +-4 +-4 +-3 +-3 +5 +13 +20 +24 +27 +27 +29 +29 +29 +28 +27 +26 +25 +24 +22 +21 +11 +3 +-3 +-8 +-11 +-13 +-14 +-16 +-15 +-15 +-14 +-15 +-14 +-13 +-11 +-11 +-3 +6 +13 +18 +21 +22 +24 +24 +24 +24 +23 +22 +21 +20 +19 +18 +9 +1 +-6 +-11 +-14 +-16 +-17 +-18 +-18 +-17 +-16 +-16 +-16 +-15 +-13 +-12 +-3 +5 +13 +17 +20 +21 +23 +24 +24 +23 +23 +22 +21 +19 +19 +18 +9 +1 +-6 +-11 +-14 +-16 +-17 +-18 +-18 +-17 +-16 +-16 +-16 +-14 +-14 +-13 +-4 +4 +12 +17 +20 +22 +24 +24 +24 +23 +22 +22 +21 +20 +19 +18 +9 +0 +-6 +-11 +-14 +-16 +-18 +-18 +-18 +-17 +-16 +-16 +-14 +-14 +-13 +-13 +-3 +5 +12 +16 +20 +21 +22 +22 +22 +22 +22 +21 +19 +18 +19 +18 +8 +0 +-6 +-11 +-14 +-16 +-17 +-17 +-18 +-18 +-18 +-17 +-15 +-15 +-13 +-13 +-4 +4 +11 +15 +19 +21 +22 +23 +22 +22 +22 +21 +20 +19 +19 +18 +17 +15 +15 +13 +13 +12 +12 +11 +11 +10 +9 +8 +8 +8 +8 +7 +-1 +-9 +-14 +-19 +-22 +-23 +-23 +-24 +-24 +-23 +-22 +-20 +-20 +-19 +-17 +-16 +-15 +-14 +-12 +-12 +-10 +-11 +-10 +-9 +-8 +-7 +-7 +-6 +-5 +-4 +-4 +-5 +4 +12 +18 +22 +26 +27 +29 +28 +27 +26 +26 +25 +23 +22 +21 +20 +10 +2 +-4 +-9 +-12 +-15 +-16 +-17 +-16 +-17 +-16 +-16 +-14 +-13 +-13 +-12 +-4 +5 +11 +16 +19 +21 +22 +22 +23 +22 +22 +20 +20 +19 +19 +17 +8 +-1 +-7 +-12 +-14 +-17 +-17 +-18 +-18 +-18 +-18 +-17 +-16 +-16 +-15 +-14 +-5 +3 +10 +15 +19 +21 +22 +23 +23 +22 +22 +20 +19 +18 +17 +16 +7 +-1 +-7 +-12 +-16 +-17 +-18 +-18 +-19 +-19 +-18 +-17 +-16 +-16 +-14 +-13 +-4 +4 +10 +14 +18 +20 +21 +21 +21 +21 +18 +16 +13 +12 +11 +9 +-9 +-28 +-43 +-55 +-61 +-66 +-66 +-66 +-64 +-62 +-59 +-56 +-52 +-50 +-47 +-44 +-41 +-38 +-36 +-33 +-31 +-29 +-27 +-26 +-23 +-22 +-20 +-19 +-16 +-15 +-14 +-14 +-12 +-11 +-10 +-10 +-9 +-8 +-7 +-7 +-7 +-7 +-6 +-6 +-5 +-5 +-4 +-4 +-4 +-4 +-4 +-3 +-2 +-2 +-2 +-2 +-1 +-1 +-1 +-1 +-1 +-1 +0 +0 +0 +0 +0 +0 +0 +-1 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +1 +0 +1 +1 +1 +1 +0 +1 +1 +1 +0 +1 +1 +2 +1 +1 +1 +1 +1 +1 +1 +2 +1 +0 +0 +0 +0 +0 +0 +1 +1 +1 +1 +2 +1 +1 +0 +1 +1 +1 +1 +1 +1 +2 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +0 +0 +1 +0 +1 +1 +1 +1 +0 +0 +1 +1 +1 +1 +1 +1 +1 +0 +0 +0 +1 +0 +1 +1 +1 +1 +1 +0 +1 +1 +0 +0 +0 +0 +0 +0 +0 +0 +1 +1 +1 +1 +1 +1 +1 +0 +1 +1 +1 +0 +1 +1 +1 +0 +0 +0 +1 +1 +0 +0 +1 +1 +1 +1 +1 +1 +1 +0 +0 +1 +1 +1 +0 +0 +1 +0 +0 +0 +1 +1 +1 +0 +1 +1 +1 +0 +0 +0 +0 +0 +0 +0 +0 +-1 +-1 +0 +0 +0 +0 +0 +1 +1 +1 +0 +1 +0 +1 +0 +0 +0 +1 +0 +0 +0 +0 +0 +0 +0 +0 +1 +0 +0 +1 +1 +2 +1 +1 +0 +1 +0 +0 +0 +1 +0 +0 +0 +0 +0 +0 +-1 +0 +0 +1 +0 +0 +0 +1 +0 +0 +0 +1 +0 +1 +0 +0 +0 +0 +-1 +0 +0 +0 +0 +-1 +-1 +0 +0 +0 +0 +1 +0 +0 +-1 +0 +-1 +0 +-1 +-1 +-1 +0 +0 +0 +0 +0 +1 +0 +0 +0 +1 +0 +0 +0 +0 +0 +0 +0 +0 +1 +0 +0 +0 +0 +-1 +0 +-1 +0 +-1 +0 +-1 +0 +0 +0 +0 +0 +0 +1 +0 +0 +0 +-1 +-1 +-1 +-1 +0 +0 +0 +-1 +0 +0 +0 +-1 +0 +0 +0 +0 +0 +-1 +0 +-1 +-1 +-1 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +-1 +-1 +0 +0 +-27 +-51 +-73 +-92 +-109 +-125 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-64 +-7 +32 +59 +75 +84 +88 +89 +53 +21 +-8 +-34 +-57 +-78 +-96 +-112 +-127 +-127 +-127 +-127 +-127 +-96 +-16 +40 +78 +101 +115 +117 +117 +117 +117 +114 +109 +103 +97 +90 +54 +22 +-7 +-33 +-56 +-77 +-96 +-112 +-127 +-127 +-127 +-127 +-127 +-105 +-26 +30 +69 +92 +107 +113 +116 +115 +112 +74 +40 +8 +-19 +-44 +-65 +-85 +-103 +-118 +-127 +-127 +-127 +-127 +-89 +-11 +45 +82 +106 +117 +117 +117 +117 +86 +50 +18 +-10 +-36 +-58 +-79 +-96 +-113 +-127 +-127 +-127 +-127 +-80 +-1 +54 +91 +114 +117 +117 +117 +117 +117 +117 +117 +111 +103 +97 +90 +54 +21 +-7 +-33 +-56 +-77 +-96 +-112 +-127 +-127 +-127 +-127 +-127 +-104 +-25 +31 +69 +93 +107 +114 +116 +115 +112 +107 +102 +96 +91 +85 +49 +17 +-11 +-37 +-60 +-80 +-98 +-115 +-127 +-127 +-127 +-127 +-127 +-106 +-28 +28 +66 +90 +105 +111 +114 +113 +75 +40 +10 +-18 +-43 +-65 +-84 +-102 +-117 +-127 +-127 +-127 +-127 +-85 +-5 +50 +87 +110 +117 +117 +117 +117 +117 +117 +113 +106 +101 +94 +88 +52 +20 +-9 +-35 +-58 +-78 +-97 +-113 +-127 +-127 +-127 +-127 +-127 +-106 +-27 +30 +67 +91 +105 +113 +115 +114 +75 +41 +9 +-18 +-43 +-64 +-84 +-102 +-117 +-127 +-127 +-127 +-127 +-127 +-81 +0 +56 +95 +117 +117 +117 +117 +117 +117 +117 +117 +112 +106 +99 +62 +28 +-1 +-28 +-51 +-73 +-91 +-109 +-123 +-127 +-127 +-127 +-127 +-101 +-22 +33 +71 +95 +109 +116 +117 +117 +78 +43 +12 +-16 +-41 +-63 +-83 +-101 +-116 +-127 +-127 +-127 +-127 +-84 +-5 +50 +87 +110 +117 +117 +117 +117 +117 +85 +50 +18 +-11 +-36 +-59 +-79 +-97 +-113 +-127 +-127 +-127 +-127 +-83 +-5 +50 +87 +110 +117 +117 +117 +117 +117 +117 +113 +107 +100 +95 +58 +25 +-5 +-31 +-54 +-75 +-94 +-110 +-125 +-127 +-127 +-127 +-127 +-102 +-24 +32 +68 +93 +107 +114 +115 +114 +111 +73 +39 +8 +-19 +-44 +-66 +-85 +-103 +-118 +-127 +-127 +-127 +-127 +-89 +-10 +45 +82 +105 +117 +117 +117 +117 +85 +49 +18 +-11 +-36 +-59 +-79 +-97 +-113 +-127 +-127 +-127 +-127 +-81 +-2 +52 +90 +113 +117 +117 +117 +117 +117 +117 +115 +108 +102 +95 +90 +53 +21 +-8 +-34 +-57 +-78 +-96 +-112 +-127 +-127 +-127 +-127 +-127 +-104 +-27 +29 +66 +90 +104 +112 +113 +113 +74 +40 +9 +-18 +-43 +-65 +-85 +-102 +-118 +-127 +-127 +-127 +-127 +-85 +-6 +49 +86 +108 +117 +117 +117 +117 +117 +117 +112 +106 +99 +93 +56 +24 +-6 +-32 +-55 +-76 +-95 +-111 +-126 +-127 +-127 +-127 +-127 +-103 +-25 +30 +68 +92 +106 +113 +116 +115 +111 +73 +39 +8 +-20 +-44 +-66 +-85 +-103 +-118 +-127 +-127 +-127 +-127 +-89 +-11 +44 +82 +105 +117 +117 +117 +117 +84 +48 +17 +-11 +-37 +-59 +-79 +-97 +-113 +-127 +-127 +-127 +-127 +-82 +-3 +53 +90 +112 +117 +117 +117 +117 +117 +117 +115 +108 +102 +94 +88 +52 +20 +-9 +-35 +-58 +-78 +-97 +-113 +-127 +-127 +-127 +-127 +-127 +-105 +-27 +29 +66 +90 +103 +111 +113 +113 +74 +40 +9 +-18 +-43 +-65 +-85 +-102 +-118 +-127 +-127 +-127 +-127 +-85 +-7 +48 +85 +108 +117 +117 +117 +117 +117 +117 +112 +105 +99 +93 +56 +23 +-6 +-32 +-56 +-76 +-95 +-111 +-126 +-127 +-127 +-127 +-127 +-103 +-25 +30 +67 +91 +104 +112 +114 +112 +109 +105 +100 +95 +89 +83 +78 +44 +12 +-16 +-41 +-64 +-84 +-101 +-117 +-127 +-127 +-127 +-127 +-127 +-109 +-31 +24 +61 +85 +100 +107 +110 +108 +71 +36 +6 +-21 +-46 +-67 +-87 +-104 +-119 +-127 +-127 +-127 +-127 +-87 +-9 +46 +83 +106 +117 +117 +117 +117 +117 +116 +110 +103 +98 +92 +86 +50 +18 +-11 +-37 +-60 +-80 +-98 +-114 +-127 +-127 +-127 +-127 +-127 +-106 +-28 +27 +64 +88 +102 +109 +112 +112 +73 +39 +8 +-19 +-44 +-66 +-85 +-103 +-118 +-127 +-127 +-127 +-127 +-86 +-8 +47 +83 +107 +117 +117 +117 +117 +117 +116 +110 +104 +97 +92 +85 +50 +18 +-11 +-37 +-59 +-80 +-98 +-114 +-127 +-127 +-127 +-127 +-127 +-107 +-29 +26 +63 +87 +102 +109 +111 +110 +72 +37 +7 +-21 +-45 +-67 +-86 +-103 +-118 +-127 +-127 +-127 +-127 +-87 +-9 +47 +84 +107 +117 +117 +117 +117 +86 +50 +19 +-10 +-35 +-58 +-78 +-97 +-112 +-127 +-127 +-127 +-127 +-80 +-3 +52 +88 +111 +117 +117 +117 +117 +117 +117 +114 +106 +100 +93 +88 +51 +20 +-10 +-35 +-58 +-79 +-97 +-113 +-127 +-127 +-127 +-127 +-127 +-105 +-27 +28 +65 +89 +103 +110 +112 +111 +72 +38 +7 +-20 +-44 +-66 +-86 +-103 +-118 +-127 +-127 +-127 +-127 +-87 +-8 +47 +84 +106 +117 +117 +117 +117 +117 +115 +109 +104 +97 +91 +84 +79 +74 +69 +64 +59 +55 +51 +47 +44 +54 +68 +75 +78 +78 +77 +74 +71 +67 +64 +59 +56 +52 +49 +45 +42 +39 +37 +33 +31 +28 +26 +24 +22 +21 +20 +18 +16 +15 +14 +12 +11 +9 +8 +8 +7 +6 +5 +4 +4 +4 +3 +2 +2 +2 +2 +1 +1 +0 +0 +-1 +-1 +-1 +-1 +-1 +-1 +-2 +-1 +-1 +-2 +-2 +-2 +-2 +-3 +-3 +-3 +-3 +-2 +-3 +-3 +-3 +-3 +-3 +-3 +-4 +-3 +-3 +-4 +-4 +-4 +-4 +-4 +-4 +-4 +-4 +-3 +-4 +-4 +-5 +-5 +-5 +-4 +-5 +-5 +-5 +-4 +-5 +-5 +-5 +-4 +-4 +-4 +-4 +-4 +-5 +-4 +-5 +-4 +-4 +-4 +-4 +-4 +-4 +-4 +-4 +-4 +-5 +-5 +-4 +-4 +-5 +-4 +-4 +-4 +-5 +-5 +-5 +-5 +-5 +-5 +-5 +-4 +-4 +-4 +-5 +-4 +-4 +-3 +-5 +-4 +-5 +-4 +-5 +-5 +-5 +-4 +-4 +-4 +-5 +-4 +-5 +-5 +-5 +-5 +-5 +-5 +-5 +-5 +-5 +-5 +-5 +-5 +-5 +-4 +-5 +-5 +2 +11 +16 +20 +22 +24 +24 +24 +23 +22 +21 +21 +19 +17 +16 +15 +6 +-2 +-9 +-14 +-17 +-19 +-22 +-22 +-22 +-22 +-21 +-21 +-21 +-19 +-19 +-18 +-10 +-1 +5 +10 +13 +14 +16 +16 +16 +15 +15 +14 +13 +12 +10 +10 +1 +-6 +-13 +-17 +-20 +-22 +-24 +-24 +-24 +-23 +-23 +-23 +-23 +-21 +-21 +-20 +-12 +-3 +4 +9 +11 +14 +15 +16 +15 +15 +14 +14 +13 +11 +11 +10 +1 +-7 +-13 +-17 +-21 +-23 +-24 +-25 +-24 +-24 +-24 +-23 +-22 +-21 +-21 +-20 +-11 +-3 +4 +9 +11 +14 +15 +16 +15 +14 +14 +13 +12 +11 +10 +10 +1 +-7 +-14 +-18 +-21 +-23 +-25 +-25 +-25 +-24 +-25 +-24 +-23 +-21 +-20 +-19 +-11 +-3 +4 +9 +11 +13 +15 +16 +15 +14 +13 +13 +12 +11 +10 +9 +0 +-7 +-14 +-18 +-21 +-23 +-24 +-24 +-25 +-24 +-24 +-23 +-22 +-21 +-20 +-20 +-19 +-18 +-17 +-16 +-16 +-15 +-14 +-14 +-14 +-13 +-13 +-12 +-12 +-12 +-11 +-10 +-3 +5 +11 +15 +18 +20 +20 +21 +20 +20 +19 +18 +16 +15 +13 +13 +2 +-5 +-11 +-15 +-19 +-21 +-23 +-23 +-23 +-23 +-23 +-22 +-21 +-20 +-20 +-19 +-11 +-2 +4 +9 +12 +14 +15 +15 +15 +15 +14 +14 +12 +12 +11 +10 +0 +-7 +-13 +-18 +-21 +-23 +-24 +-24 +-25 +-24 +-24 +-23 +-22 +-21 +-20 +-20 +-11 +-4 +2 +8 +11 +13 +14 +14 +14 +14 +13 +12 +11 +11 +10 +9 +0 +-7 +-14 +-18 +-22 +-23 +-25 +-25 +-26 +-25 +-24 +-22 +-22 +-22 +-21 +-20 +-12 +-4 +2 +8 +11 +13 +13 +14 +14 +14 +13 +13 +12 +11 +10 +9 +-1 +-8 +-14 +-19 +-22 +-23 +-25 +-25 +-26 +-25 +-25 +-24 +-23 +-23 +-22 +-20 +-12 +-4 +2 +8 +11 +13 +14 +14 +15 +14 +13 +13 +12 +11 +10 +9 +8 +7 +6 +6 +5 +5 +4 +3 +2 +2 +1 +1 +0 +-1 +-1 +0 +-9 +-16 +-22 +-25 +-29 +-31 +-32 +-32 +-31 +-30 +-30 +-29 +-27 +-26 +-25 +-24 +-16 +-7 +0 +4 +8 +11 +13 +13 +12 +12 +12 +11 +10 +9 +8 +8 +-2 +-10 +-15 +-19 +-22 +-24 +-26 +-26 +-26 +-26 +-25 +-24 +-24 +-22 +-22 +-21 +-21 +-19 +-19 +-18 +-17 +-16 +-15 +-15 +-15 +-14 +-13 +-12 +-12 +-12 +-11 +-11 +-3 +4 +11 +15 +18 +19 +20 +20 +20 +19 +18 +17 +15 +15 +13 +12 +11 +10 +9 +8 +7 +6 +5 +4 +3 +3 +2 +2 +1 +1 +0 +0 +-9 +-16 +-22 +-25 +-28 +-30 +-31 +-31 +-30 +-29 +-29 +-28 +-27 +-25 +-25 +-23 +-23 +-21 +-21 +-20 +-19 +-17 +-17 +-16 +-16 +-14 +-14 +-13 +-13 +-12 +-12 +-12 +-5 +4 +10 +14 +16 +18 +19 +19 +18 +17 +16 +16 +14 +13 +12 +12 +10 +9 +8 +7 +6 +6 +5 +4 +4 +3 +2 +2 +1 +1 +1 +0 +-9 +-15 +-21 +-26 +-29 +-30 +-31 +-31 +-31 +-30 +-30 +-28 +-28 +-27 +-25 +-24 +-22 +-22 +-21 +-20 +-19 +-18 +-18 +-17 +-16 +-15 +-14 +-14 +-14 +-13 +-12 +-12 +-5 +4 +9 +14 +16 +18 +19 +19 +18 +18 +17 +16 +14 +13 +12 +11 +10 +9 +8 +7 +6 +5 +4 +4 +3 +3 +1 +1 +1 +1 +0 +-1 +-9 +-16 +-21 +-26 +-29 +-31 +-31 +-31 +-31 +-30 +-29 +-28 +-27 +-26 +-25 +-24 +-22 +-21 +-21 +-20 +-19 +-18 +-18 +-17 +-17 +-15 +-15 +-15 +-14 +-13 +-13 +-13 +-5 +3 +10 +14 +16 +18 +19 +19 +18 +17 +17 +16 +14 +13 +12 +11 +10 +9 +8 +7 +6 +5 +4 +3 +2 +2 +1 +1 +0 +1 +0 +0 +-9 +-16 +-22 +-26 +-30 +-31 +-31 +-31 +-32 +-30 +-30 +-28 +-27 +-26 +-25 +-24 +-23 +-22 +-21 +-20 +-19 +-18 +-18 +-17 +-16 +-15 +-15 +-14 +-13 +-12 +-12 +-12 +-5 +3 +9 +13 +15 +17 +18 +19 +18 +17 +16 +15 +14 +12 +11 +10 +1 +-6 +-13 +-17 +-20 +-22 +-24 +-24 +-25 +-24 +-24 +-24 +-23 +-22 +-21 +-21 +-12 +-4 +3 +7 +10 +12 +13 +14 +13 +13 +12 +12 +10 +9 +8 +8 +7 +6 +5 +5 +4 +3 +2 +2 +1 +1 +-1 +0 +-1 +-1 +-3 +-2 +-11 +-17 +-23 +-27 +-30 +-31 +-32 +-33 +-32 +-31 +-30 +-29 +-28 +-26 +-25 +-23 +-24 +-22 +-21 +-20 +-19 +-18 +-17 +-16 +-16 +-16 +-15 +-14 +-14 +-13 +-13 +-12 +-5 +3 +8 +12 +15 +17 +18 +18 +17 +17 +16 +14 +13 +13 +11 +10 +0 +-7 +-13 +-18 +-22 +-24 +-25 +-25 +-25 +-25 +-25 +-24 +-23 +-22 +-22 +-21 +-12 +-4 +2 +7 +10 +13 +13 +14 +13 +13 +12 +12 +10 +10 +9 +8 +6 +5 +5 +4 +4 +3 +2 +1 +1 +0 +-1 +0 +-1 +0 +-2 +-2 +-11 +-17 +-24 +-28 +-31 +-32 +-33 +-33 +-32 +-31 +-30 +-29 +-28 +-27 +-26 +-25 +-24 +-23 +-21 +-20 +-20 +-19 +-18 +-17 +-17 +-16 +-16 +-14 +-14 +-14 +-14 +-13 +-5 +3 +8 +13 +16 +17 +17 +17 +17 +17 +15 +14 +13 +13 +11 +10 +0 +-7 +-13 +-18 +-21 +-23 +-24 +-25 +-26 +-25 +-25 +-24 +-23 +-22 +-21 +-20 +-12 +-4 +2 +7 +9 +12 +12 +13 +12 +12 +11 +11 +10 +9 +8 +7 +-2 +-9 +-15 +-20 +-23 +-25 +-26 +-26 +-27 +-27 +-26 +-25 +-24 +-23 +-23 +-22 +-13 +-5 +1 +5 +9 +11 +12 +12 +12 +12 +11 +10 +9 +9 +8 +7 +-2 +-10 +-16 +-20 +-24 +-26 +-27 +-27 +-27 +-27 +-26 +-25 +-24 +-24 +-23 +-22 +-13 +-5 +1 +5 +9 +11 +11 +11 +12 +12 +11 +10 +9 +9 +8 +6 +5 +5 +4 +4 +2 +2 +1 +1 +0 +0 +0 +0 +-1 +-2 +-2 +-2 +-11 +-18 +-24 +-28 +-31 +-32 +-33 +-33 +-32 +-31 +-31 +-30 +-29 +-27 +-26 +-25 +-24 +-22 +-22 +-21 +-21 +-20 +-19 +-17 +-17 +-17 +-16 +-15 +-14 +-14 +-14 +-13 +-5 +2 +8 +12 +15 +17 +17 +17 +17 +17 +15 +14 +13 +12 +11 +10 +8 +7 +6 +5 +4 +3 +2 +2 +2 +2 +0 +0 +-1 +-1 +-3 +-3 +-11 +-17 +-23 +-27 +-30 +-32 +-33 +-33 +-33 +-31 +-30 +-29 +-29 +-27 +-26 +-25 +-25 +-23 +-22 +-21 +-20 +-19 +-19 +-17 +-17 +-16 +-16 +-15 +-15 +-15 +-15 +-14 +-7 +1 +7 +11 +14 +17 +16 +17 +16 +16 +15 +14 +12 +12 +11 +9 +8 +7 +6 +5 +4 +3 +3 +2 +1 +0 +0 +0 +-1 +-1 +-3 +-2 +-11 +-18 +-24 +-27 +-30 +-31 +-32 +-32 +-32 +-31 +-30 +-30 +-29 +-28 +-27 +-25 +-25 +-23 +-22 +-21 +-21 +-20 +-19 +-18 +-17 +-16 +-16 +-15 +-15 +-14 +-14 +-14 +-5 +2 +8 +11 +14 +16 +17 +16 +16 +16 +15 +14 +12 +12 +10 +9 +0 +-7 +-14 +-18 +-22 +-24 +-25 +-26 +-27 +-27 +-26 +-25 +-24 +-24 +-23 +-22 +-13 +-5 +1 +6 +9 +11 +11 +12 +12 +12 +8 +5 +3 +2 +1 +0 +-18 +-36 +-51 +-62 +-69 +-72 +-73 +-72 +-71 +-69 +-67 +-63 +-59 +-56 +-54 +-51 +-48 +-45 +-43 +-41 +-39 +-36 +-35 +-33 +-31 +-29 +-28 +-26 +-25 +-24 +-23 +-22 +-22 +-20 +-19 +-18 +-18 +-17 +-17 +-16 +-16 +-15 +-15 +-14 +-13 +-13 +-13 +-13 +-13 +-12 +-13 +-12 +-12 +-11 +-12 +-11 +-11 +-10 +-10 +-10 +-10 +-9 +-9 +-9 +-10 +-9 +-9 +-9 +-9 +-9 +-9 +-9 +-9 +-9 +-9 +-8 +-8 +-8 +-9 +-9 +-9 +-8 +-9 +-8 +-8 +-8 +-9 +-9 +-9 +-9 +-9 +-9 +-9 +-8 +-8 +-8 +-9 +-9 +-9 +-8 +-8 +-9 +-9 +-9 +-8 +-9 +-9 +-9 +-8 +-8 +-8 +-8 +-8 +-8 +-8 +-8 +-8 +-8 +-8 +-7 +-9 +-8 +-8 +-8 +-8 +-8 +-8 +-8 +-8 +-9 +-9 +-9 +-9 +-9 +-9 +-8 +-8 +-7 +-8 +-8 +-8 +-8 +-8 +-8 +-8 +-8 +-8 +-8 +-9 +-8 +-8 +-8 +-9 +-9 +-9 +-8 +-9 +-9 +-9 +-8 +-9 +-8 +-9 +-8 +-8 +-8 +-9 +-8 +-8 +-8 +-8 +-8 +-8 +-7 +-8 +-9 +-9 +-9 +-9 +-9 +-10 +-9 +-9 +-8 +-10 +-9 +-9 +-9 +-9 +-9 +-8 +-8 +-8 +-9 +-9 +-8 +-8 +-8 +-9 +-9 +-8 +-8 +-9 +-9 +-9 +-9 +-9 +-9 +-9 +-8 +-9 +-9 +-9 +-9 +-8 +-8 +-8 +-9 +-9 +-8 +-8 +-9 +-9 +-9 +-8 +-9 +-9 +-9 +-9 +-8 +-8 +-8 +-8 +-8 +-8 +-8 +-9 +-9 +-9 +-9 +-9 +-9 +-9 +-8 +-8 +-9 +-9 +-9 +-9 +-9 +-9 +-9 +-9 +-8 +-8 +-9 +-8 +-8 +-8 +-8 +-8 +-7 +-8 +-8 +-9 +-9 +-9 +-9 +-9 +-9 +-9 +-8 +-8 +-9 +-9 +-9 +-9 +-9 +-9 +-9 +-8 +-8 +-9 +-10 +-9 +-9 +-9 +-10 +-10 +-9 +-9 +-9 +-10 +-9 +-9 +-8 +-9 +-9 +-9 +-9 +-9 +-9 +-9 +-8 +-8 +-8 +-9 +-9 +-9 +-8 +-9 +-9 +-9 +-9 +-9 +-9 +-9 +-8 +-8 +-8 +-9 +-8 +-9 +-9 +-10 +-9 +-9 +-8 +-9 +-9 +-9 +-9 +-10 +-10 +-10 +-9 +-9 +-9 +-9 +-9 +-8 +-9 +-9 +-9 +-8 +-9 +-9 +-9 +-9 +-9 +-9 +-9 +-9 +-8 +-8 +-9 +-9 +-8 +-8 +-8 +-9 +-8 +-9 +-8 +-9 +-9 +-9 +-8 +-9 +-9 +-9 +-9 +-8 +-8 +-8 +-8 +-8 +-8 +-8 +-9 +-8 +-8 +-8 +-8 +-8 +-7 +-7 +-7 +-8 +-7 diff --git a/traces/sniff-ht2-BC3B8810-rfidler-reader.pm3 b/traces/sniff-ht2-BC3B8810-rfidler-reader.pm3 new file mode 100644 index 000000000..3be1e7cb5 --- /dev/null +++ b/traces/sniff-ht2-BC3B8810-rfidler-reader.pm3 @@ -0,0 +1,4200 @@ +-2 +-1 +0 +0 +-1 +0 +-1 +0 +-1 +-2 +-1 +0 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +0 +0 +-1 +-2 +-2 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-2 +-2 +-1 +0 +-1 +-1 +-1 +-1 +-1 +-1 +0 +0 +0 +-1 +-2 +-2 +-1 +-1 +-1 +-1 +0 +-1 +-1 +-2 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-2 +-1 +-1 +0 +-1 +-1 +-2 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-2 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-2 +-1 +-1 +-1 +-1 +-1 +0 +0 +-1 +-1 +-2 +-2 +-2 +-2 +-2 +-2 +-2 +-1 +-2 +-1 +-1 +0 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +0 +-1 +-2 +-2 +-1 +-1 +0 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +0 +-1 +-1 +-1 +-21 +-39 +-55 +-69 +-82 +-94 +-104 +-113 +-113 +2 +57 +66 +53 +36 +22 +13 +12 +16 +20 +22 +22 +21 +19 +18 +16 +14 +13 +12 +12 +10 +-11 +-30 +-47 +-62 +-75 +-88 +-98 +-108 +-106 +10 +64 +72 +60 +42 +28 +19 +18 +20 +24 +26 +27 +25 +23 +21 +18 +17 +16 +14 +14 +13 +-8 +-27 +-44 +-60 +-74 +-86 +-97 +-107 +-105 +9 +61 +68 +56 +39 +26 +19 +18 +21 +25 +27 +28 +26 +3 +-17 +-35 +-52 +-66 +-79 +-91 +-101 +-99 +16 +69 +75 +62 +44 +30 +22 +22 +24 +28 +30 +30 +28 +5 +-15 +-33 +-50 +-65 +-78 +-90 +-100 +-97 +20 +73 +79 +65 +46 +30 +21 +21 +24 +28 +30 +30 +28 +5 +-15 +-34 +-50 +-65 +-78 +-90 +-100 +-96 +21 +75 +82 +68 +49 +32 +22 +21 +25 +29 +31 +31 +29 +27 +23 +22 +20 +19 +17 +15 +14 +13 +12 +11 +11 +10 +9 +8 +12 +17 +22 +28 +31 +33 +33 +33 +31 +30 +28 +28 +26 +24 +22 +20 +20 +18 +17 +16 +15 +14 +12 +11 +10 +10 +10 +9 +8 +7 +6 +5 +5 +5 +5 +5 +3 +3 +3 +3 +2 +3 +2 +2 +2 +1 +1 +2 +2 +1 +-1 +-1 +-1 +-1 +-1 +0 +0 +0 +0 +0 +-1 +0 +1 +0 +-1 +0 +-1 +0 +-1 +0 +0 +0 +-1 +-2 +-2 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-2 +-1 +-1 +0 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +0 +-1 +-1 +-2 +-1 +-1 +-1 +-1 +0 +-1 +-1 +-2 +-2 +-2 +-2 +-5 +-6 +-6 +-4 +-3 +-1 +0 +1 +1 +2 +1 +0 +0 +0 +0 +2 +2 +3 +3 +3 +3 +4 +3 +3 +3 +3 +3 +2 +1 +1 +1 +2 +1 +2 +1 +1 +0 +0 +-1 +0 +0 +0 +0 +0 +0 +0 +-1 +-1 +-1 +0 +0 +0 +-1 +-1 +-1 +-2 +-2 +-2 +5 +24 +42 +57 +66 +69 +68 +65 +61 +57 +53 +50 +46 +44 +40 +37 +27 +10 +-7 +-23 +-36 +-44 +-47 +-46 +-46 +-45 +-43 +-41 +-39 +-37 +-35 +-34 +-25 +-6 +14 +31 +42 +48 +49 +48 +46 +45 +41 +39 +37 +35 +33 +30 +21 +5 +-12 +-27 +-40 +-47 +-49 +-48 +-49 +-47 +-46 +-43 +-41 +-39 +-36 +-35 +-27 +-8 +12 +29 +39 +46 +47 +46 +45 +43 +40 +38 +36 +35 +33 +29 +21 +5 +-13 +-28 +-40 +-47 +-49 +-49 +-50 +-48 +-46 +-43 +-41 +-38 +-36 +-35 +-27 +-9 +13 +30 +40 +46 +46 +46 +43 +41 +38 +37 +36 +35 +32 +28 +20 +4 +-13 +-28 +-40 +-47 +-51 +-52 +-51 +-48 +-45 +-42 +-40 +-38 +-36 +-35 +-27 +-8 +13 +30 +39 +45 +46 +45 +44 +41 +39 +37 +35 +33 +31 +28 +20 +4 +-13 +-29 +-41 +-47 +-50 +-51 +-49 +-47 +-45 +-42 +-41 +-38 +-36 +-35 +-28 +-9 +12 +29 +39 +45 +46 +46 +43 +41 +38 +36 +35 +33 +31 +29 +20 +4 +-13 +-29 +-41 +-48 +-50 +-51 +-50 +-47 +-44 +-42 +-40 +-37 +-36 +-35 +-34 +-33 +-31 +-28 +-27 +-25 +-23 +-21 +-19 +-18 +-17 +-16 +-15 +-13 +-13 +-14 +-6 +12 +31 +47 +56 +61 +61 +58 +55 +52 +49 +46 +43 +42 +39 +36 +32 +29 +26 +26 +24 +23 +22 +21 +20 +18 +16 +16 +14 +14 +12 +10 +3 +-12 +-28 +-42 +-54 +-59 +-62 +-62 +-60 +-57 +-53 +-50 +-48 +-44 +-42 +-41 +-33 +-14 +7 +24 +34 +40 +42 +42 +40 +37 +35 +34 +32 +31 +28 +26 +17 +1 +-16 +-31 +-43 +-49 +-52 +-53 +-51 +-48 +-45 +-43 +-41 +-38 +-37 +-36 +-29 +-10 +12 +29 +39 +45 +47 +45 +42 +39 +37 +37 +34 +33 +30 +28 +19 +3 +-14 +-29 +-41 +-48 +-51 +-52 +-51 +-47 +-44 +-41 +-40 +-37 +-36 +-36 +-28 +-9 +12 +30 +40 +45 +46 +45 +43 +41 +38 +37 +35 +33 +30 +27 +19 +4 +-13 +-28 +-41 +-48 +-52 +-52 +-50 +-46 +-43 +-41 +-40 +-38 +-36 +-35 +-34 +-32 +-30 +-28 +-27 +-26 +-24 +-21 +-19 +-18 +-17 +-15 +-15 +-14 +-14 +-15 +-6 +12 +31 +46 +55 +61 +60 +58 +55 +52 +49 +46 +43 +42 +39 +36 +25 +8 +-10 +-25 +-38 +-45 +-48 +-47 +-46 +-44 +-42 +-39 +-36 +-35 +-34 +-33 +-25 +-5 +15 +33 +43 +49 +48 +46 +44 +42 +39 +37 +35 +34 +31 +28 +18 +2 +-15 +-30 +-42 +-49 +-52 +-52 +-50 +-47 +-44 +-41 +-39 +-37 +-36 +-35 +-26 +-8 +13 +31 +41 +47 +46 +45 +43 +41 +38 +36 +34 +33 +30 +26 +18 +2 +-15 +-30 +-43 +-50 +-53 +-52 +-51 +-47 +-43 +-41 +-39 +-37 +-36 +-35 +-27 +-8 +13 +32 +41 +47 +47 +45 +43 +41 +39 +37 +34 +33 +30 +26 +24 +22 +21 +21 +19 +18 +17 +16 +14 +14 +14 +13 +12 +11 +9 +7 +0 +-14 +-31 +-44 +-55 +-62 +-65 +-64 +-60 +-56 +-53 +-50 +-47 +-45 +-44 +-44 +-35 +-15 +6 +23 +33 +40 +42 +41 +38 +36 +34 +33 +31 +29 +27 +25 +16 +0 +-16 +-31 +-43 +-51 +-54 +-53 +-51 +-48 +-45 +-42 +-40 +-38 +-38 +-37 +-29 +-9 +11 +28 +38 +44 +45 +44 +42 +40 +38 +36 +33 +32 +29 +27 +18 +3 +-15 +-29 +-42 +-49 +-53 +-51 +-49 +-46 +-44 +-42 +-40 +-38 +-37 +-36 +-34 +-32 +-31 +-29 +-28 +-25 +-24 +-21 +-19 +-18 +-17 +-17 +-16 +-14 +-14 +-14 +-7 +12 +31 +46 +55 +60 +60 +58 +54 +51 +48 +45 +43 +40 +38 +35 +32 +28 +26 +25 +24 +23 +21 +20 +19 +18 +16 +16 +15 +14 +12 +9 +1 +-13 +-29 +-43 +-54 +-60 +-63 +-62 +-59 +-56 +-52 +-49 +-47 +-45 +-44 +-43 +-34 +-14 +7 +25 +35 +41 +42 +41 +39 +38 +35 +33 +31 +30 +28 +25 +16 +1 +-16 +-31 +-43 +-51 +-53 +-52 +-51 +-48 +-45 +-43 +-41 +-39 +-38 +-36 +-28 +-10 +11 +27 +38 +44 +45 +44 +42 +40 +37 +35 +33 +32 +30 +27 +19 +3 +-15 +-30 +-42 +-50 +-52 +-51 +-49 +-47 +-44 +-42 +-40 +-38 +-36 +-36 +-34 +-33 +-32 +-29 +-27 +-25 +-23 +-21 +-19 +-18 +-18 +-17 +-16 +-15 +-14 +-15 +-7 +11 +31 +46 +55 +60 +61 +58 +55 +51 +48 +45 +42 +40 +38 +35 +25 +8 +-10 +-26 +-38 +-46 +-49 +-47 +-46 +-44 +-42 +-39 +-37 +-35 +-33 +-33 +-24 +-5 +15 +32 +42 +48 +48 +47 +44 +41 +38 +36 +34 +33 +31 +28 +18 +2 +-15 +-30 +-43 +-50 +-52 +-52 +-50 +-47 +-44 +-41 +-39 +-37 +-36 +-35 +-27 +-8 +13 +31 +41 +47 +47 +45 +43 +41 +38 +36 +34 +33 +30 +26 +24 +22 +21 +20 +18 +18 +16 +16 +14 +14 +13 +13 +11 +10 +9 +7 +-1 +-15 +-31 +-44 +-56 +-63 +-65 +-64 +-61 +-58 +-54 +-51 +-48 +-46 +-44 +-44 +-42 +-39 +-37 +-34 +-33 +-30 +-28 +-26 +-24 +-22 +-20 +-19 +-19 +-18 +-18 +-17 +-10 +9 +29 +45 +53 +58 +58 +56 +53 +49 +46 +44 +41 +39 +36 +33 +24 +7 +-11 +-27 +-39 +-45 +-48 +-49 +-47 +-44 +-42 +-40 +-38 +-35 +-33 +-33 +-25 +-6 +15 +33 +42 +48 +48 +46 +43 +40 +38 +37 +35 +33 +30 +27 +18 +2 +-15 +-30 +-43 +-50 +-53 +-53 +-50 +-46 +-43 +-41 +-40 +-38 +-37 +-36 +-27 +-8 +13 +31 +41 +46 +47 +46 +43 +41 +38 +36 +33 +32 +29 +26 +18 +2 +-15 +-31 +-43 +-50 +-53 +-53 +-51 +-47 +-44 +-42 +-40 +-38 +-36 +-35 +-27 +-8 +13 +30 +40 +45 +46 +45 +43 +40 +37 +35 +33 +32 +30 +27 +18 +2 +-16 +-31 +-43 +-51 +-54 +-53 +-51 +-47 +-44 +-41 +-40 +-38 +-36 +-35 +-27 +-8 +13 +30 +40 +46 +46 +46 +43 +41 +37 +35 +33 +32 +29 +26 +18 +2 +-16 +-31 +-44 +-51 +-54 +-53 +-50 +-47 +-44 +-41 +-40 +-37 +-35 +-34 +-26 +-8 +13 +29 +39 +45 +47 +46 +43 +39 +37 +35 +33 +32 +29 +26 +24 +22 +19 +19 +18 +17 +16 +15 +14 +13 +13 +12 +11 +11 +10 +7 +-1 +-15 +-31 +-45 +-56 +-63 +-65 +-64 +-61 +-58 +-54 +-50 +-48 +-46 +-44 +-43 +-42 +-40 +-38 +-35 +-32 +-29 +-28 +-26 +-25 +-22 +-21 +-20 +-19 +-17 +-17 +-18 +-10 +9 +29 +45 +53 +58 +58 +55 +52 +49 +46 +44 +41 +38 +36 +33 +24 +7 +-11 +-26 +-39 +-47 +-51 +-50 +-47 +-44 +-42 +-40 +-37 +-35 +-35 +-34 +-25 +-5 +15 +31 +41 +47 +48 +46 +44 +41 +38 +36 +34 +32 +30 +28 +18 +2 +-16 +-31 +-43 +-50 +-53 +-52 +-50 +-47 +-45 +-41 +-39 +-36 +-36 +-36 +-27 +-8 +13 +30 +40 +46 +48 +45 +42 +40 +37 +36 +33 +32 +29 +26 +17 +1 +-16 +-31 +-43 +-51 +-54 +-54 +-51 +-47 +-44 +-41 +-40 +-37 +-37 +-36 +-28 +-8 +14 +31 +40 +45 +46 +45 +42 +39 +37 +34 +30 +28 +25 +22 +7 +-13 +-33 +-50 +-66 +-80 +-92 +-101 +-107 +-109 +-108 +-105 +-100 +-93 +-87 +-80 +-76 +-71 +-66 +-62 +-58 +-54 +-50 +-45 +-43 +-40 +-39 +-36 +-34 +-33 +-31 +-28 +-26 +-24 +-24 +-22 +-21 +-20 +-19 +-18 +-16 +-15 +-16 +-15 +-14 +-13 +-13 +-12 +-11 +-10 +-11 +-11 +-10 +-9 +-9 +-8 +-8 +-7 +-8 +-7 +-8 +-8 +-7 +-6 +-6 +-6 +-6 +-6 +-6 +-6 +-6 +-5 +-5 +-4 +-5 +-4 +-5 +-5 +-6 +-6 +-5 +-4 +-4 +-4 +-5 +-4 +-4 +-4 +-4 +-3 +-4 +-3 +-5 +-4 +-4 +-3 +-4 +-3 +-3 +-3 +-3 +-4 +-4 +-3 +-3 +-3 +-4 +-4 +-24 +-41 +-57 +-70 +-83 +-94 +-104 +-112 +-116 +-5 +49 +57 +45 +28 +13 +5 +3 +9 +15 +19 +20 +18 +-4 +-23 +-40 +-56 +-70 +-82 +-93 +-102 +-105 +9 +63 +71 +57 +40 +24 +15 +15 +19 +23 +27 +28 +27 +23 +21 +19 +18 +17 +16 +16 +15 +-6 +-25 +-43 +-58 +-72 +-84 +-95 +-104 +-107 +6 +58 +66 +53 +36 +20 +12 +12 +16 +20 +24 +25 +25 +2 +-18 +-36 +-52 +-66 +-79 +-90 +-100 +-102 +12 +65 +72 +59 +42 +26 +17 +16 +20 +24 +27 +28 +27 +4 +-16 +-34 +-50 +-65 +-78 +-89 +-99 +-101 +14 +67 +74 +60 +42 +27 +18 +17 +21 +25 +29 +29 +28 +25 +23 +21 +19 +18 +18 +17 +16 +-6 +-25 +-42 +-57 +-71 +-83 +-94 +-104 +-107 +7 +60 +68 +54 +37 +21 +13 +13 +18 +22 +25 +26 +25 +22 +20 +18 +17 +16 +15 +14 +14 +-7 +-26 +-43 +-59 +-72 +-84 +-95 +-104 +-107 +6 +60 +67 +53 +36 +21 +12 +11 +17 +21 +25 +25 +23 +1 +-19 +-37 +-53 +-67 +-79 +-91 +-100 +-103 +12 +66 +73 +59 +42 +26 +17 +16 +19 +24 +28 +29 +28 +24 +22 +20 +18 +17 +17 +17 +16 +-6 +-25 +-42 +-57 +-71 +-83 +-94 +-103 +-106 +6 +60 +67 +53 +36 +21 +13 +13 +17 +21 +24 +25 +24 +2 +-18 +-36 +-52 +-66 +-79 +-90 +-100 +-102 +13 +65 +72 +59 +41 +25 +16 +16 +21 +26 +28 +28 +27 +23 +21 +19 +19 +18 +17 +16 +15 +-6 +-26 +-43 +-58 +-72 +-84 +-95 +-104 +-107 +7 +60 +68 +54 +37 +21 +12 +11 +15 +21 +26 +26 +25 +2 +-18 +-36 +-52 +-66 +-79 +-90 +-100 +-103 +11 +65 +73 +59 +41 +25 +17 +15 +19 +24 +28 +29 +27 +4 +-16 +-34 +-50 +-65 +-77 +-89 +-99 +-101 +13 +66 +75 +61 +43 +27 +18 +17 +21 +25 +29 +30 +28 +25 +22 +20 +19 +19 +18 +17 +16 +-6 +-25 +-42 +-57 +-71 +-83 +-94 +-103 +-107 +6 +59 +67 +53 +37 +21 +12 +11 +16 +21 +25 +26 +24 +2 +-18 +-36 +-52 +-66 +-79 +-90 +-100 +-102 +12 +66 +72 +58 +41 +25 +17 +15 +19 +24 +28 +29 +27 +4 +-16 +-34 +-50 +-65 +-78 +-89 +-99 +-101 +14 +66 +74 +59 +41 +26 +18 +17 +21 +25 +29 +29 +27 +24 +22 +21 +20 +18 +17 +16 +16 +-6 +-25 +-43 +-58 +-72 +-83 +-94 +-104 +-106 +7 +60 +68 +54 +36 +21 +12 +12 +17 +22 +25 +25 +24 +1 +-18 +-36 +-52 +-67 +-79 +-90 +-100 +-103 +12 +65 +73 +59 +41 +26 +17 +15 +20 +25 +29 +29 +27 +24 +22 +19 +18 +18 +18 +17 +16 +-6 +-25 +-43 +-58 +-72 +-83 +-95 +-104 +-107 +5 +58 +67 +53 +36 +21 +13 +12 +16 +20 +24 +26 +25 +2 +-18 +-36 +-52 +-66 +-79 +-90 +-100 +-102 +12 +65 +72 +58 +41 +24 +16 +16 +21 +25 +27 +28 +27 +4 +-16 +-35 +-51 +-65 +-78 +-89 +-99 +-101 +14 +67 +74 +60 +42 +26 +17 +16 +21 +26 +29 +29 +28 +24 +22 +20 +19 +18 +18 +16 +15 +-7 +-26 +-43 +-58 +-72 +-84 +-95 +-104 +-107 +6 +60 +67 +54 +36 +21 +13 +12 +17 +22 +25 +26 +24 +1 +-19 +-37 +-52 +-67 +-79 +-91 +-100 +-102 +13 +66 +73 +58 +40 +25 +17 +16 +20 +25 +28 +29 +27 +24 +22 +20 +19 +17 +16 +16 +16 +-6 +-25 +-42 +-57 +-71 +-83 +-94 +-104 +-106 +6 +58 +66 +52 +35 +20 +12 +11 +17 +22 +25 +25 +24 +21 +19 +17 +16 +15 +15 +14 +13 +-8 +-27 +-44 +-59 +-73 +-85 +-96 +-105 +-108 +5 +59 +66 +52 +35 +20 +12 +11 +16 +21 +24 +25 +23 +0 +-19 +-37 +-53 +-67 +-80 +-91 +-100 +-103 +12 +65 +73 +59 +41 +24 +16 +16 +21 +25 +28 +29 +27 +23 +20 +18 +18 +18 +17 +15 +15 +-7 +-26 +-43 +-58 +-72 +-84 +-95 +-104 +-107 +5 +58 +66 +53 +36 +21 +13 +12 +17 +22 +25 +26 +24 +2 +-18 +-36 +-52 +-67 +-79 +-90 +-100 +-102 +13 +65 +72 +58 +40 +24 +16 +15 +20 +25 +28 +28 +26 +23 +22 +20 +19 +18 +17 +15 +14 +-7 +-27 +-44 +-59 +-72 +-84 +-95 +-104 +-107 +5 +59 +67 +54 +36 +20 +12 +11 +16 +21 +25 +26 +24 +1 +-19 +-37 +-52 +-67 +-79 +-91 +-100 +-102 +11 +64 +72 +58 +41 +25 +16 +15 +20 +24 +28 +29 +27 +4 +-16 +-34 +-50 +-65 +-77 +-89 +-99 +-101 +14 +66 +73 +60 +42 +26 +17 +16 +21 +25 +28 +29 +28 +25 +22 +20 +18 +17 +18 +16 +15 +-6 +-26 +-43 +-58 +-72 +-84 +-95 +-104 +-107 +5 +59 +66 +52 +35 +20 +12 +11 +16 +21 +25 +26 +24 +1 +-19 +-37 +-52 +-67 +-79 +-91 +-100 +-102 +13 +65 +73 +59 +41 +25 +17 +16 +20 +24 +28 +30 +28 +24 +22 +20 +19 +17 +16 +16 +16 +14 +13 +11 +11 +10 +9 +8 +8 +15 +26 +36 +46 +54 +60 +62 +61 +60 +56 +52 +48 +45 +43 +41 +38 +35 +33 +30 +29 +26 +24 +23 +21 +19 +17 +16 +15 +15 +14 +12 +11 +9 +9 +8 +7 +6 +5 +3 +0 +-3 +-2 +-1 +1 +2 +3 +3 +3 +2 +2 +2 +3 +2 +2 +1 +1 +1 +0 +0 +0 +0 +0 +-1 +-1 +-2 +-1 +-2 +-2 +-1 +-1 +-2 +-3 +-3 +-2 +-3 +-2 +-3 +-2 +-3 +-2 +-3 +-3 +-3 +-2 +-2 +-3 +-3 +-3 +-3 +-4 +-4 +-3 +-3 +-3 +-3 +-3 +-4 +-4 +-5 +-4 +-3 +-3 +-3 +-4 +-4 +-4 +-4 +-4 +-4 +-3 +-3 +-3 +-4 +-4 +-5 +-4 +-4 +-4 +-4 +-4 +-3 +-3 +-3 +-1 +-1 +0 +-1 +0 +0 +0 +-1 +-1 +-1 +0 +-1 +-1 +-1 +-1 +-2 +-2 +-2 +-1 +-1 +-2 +-3 +-2 +-3 +-2 +-3 +-2 +-2 +-2 +-3 +-4 +-3 +-3 +-3 +-3 +-4 +-3 +-4 +-4 +-5 +-4 +-4 +-3 +3 +21 +40 +54 +62 +65 +63 +61 +57 +54 +50 +47 +44 +41 +37 +34 +25 +8 +-10 +-26 +-39 +-46 +-48 +-47 +-47 +-46 +-45 +-43 +-41 +-39 +-36 +-35 +-27 +-9 +12 +29 +39 +45 +46 +45 +43 +41 +38 +36 +35 +33 +30 +27 +18 +3 +-14 +-29 +-42 +-48 +-51 +-52 +-52 +-49 +-47 +-44 +-43 +-40 +-38 +-38 +-29 +-10 +11 +29 +37 +43 +44 +44 +42 +39 +37 +35 +33 +32 +29 +26 +18 +3 +-15 +-30 +-43 +-49 +-52 +-52 +-51 +-49 +-46 +-45 +-43 +-40 +-38 +-36 +-29 +-10 +10 +27 +37 +42 +44 +44 +41 +38 +36 +34 +33 +31 +28 +26 +18 +2 +-16 +-31 +-43 +-49 +-52 +-53 +-51 +-49 +-47 +-44 +-42 +-39 +-38 +-37 +-30 +-10 +10 +28 +38 +43 +44 +43 +41 +39 +36 +35 +33 +32 +28 +26 +17 +1 +-16 +-31 +-43 +-49 +-52 +-53 +-51 +-49 +-46 +-44 +-42 +-39 +-38 +-38 +-37 +-35 +-33 +-30 +-29 +-27 +-25 +-23 +-21 +-21 +-20 +-18 +-17 +-16 +-16 +-16 +-9 +9 +29 +45 +54 +59 +59 +55 +52 +50 +47 +44 +41 +40 +36 +33 +23 +6 +-11 +-27 +-39 +-46 +-49 +-50 +-48 +-47 +-44 +-41 +-39 +-36 +-36 +-35 +-26 +-7 +14 +30 +41 +47 +46 +44 +42 +40 +38 +36 +33 +32 +29 +26 +16 +1 +-16 +-31 +-43 +-50 +-53 +-53 +-51 +-48 +-46 +-42 +-40 +-39 +-38 +-37 +-28 +-8 +12 +29 +39 +45 +45 +43 +41 +39 +37 +35 +32 +30 +27 +25 +16 +0 +-17 +-32 +-44 +-52 +-54 +-53 +-51 +-48 +-46 +-43 +-41 +-39 +-39 +-37 +-28 +-9 +12 +28 +38 +44 +44 +43 +41 +39 +36 +34 +31 +31 +28 +25 +16 +0 +-17 +-32 +-44 +-52 +-54 +-53 +-51 +-49 +-47 +-44 +-41 +-39 +-38 +-37 +-28 +-9 +11 +28 +38 +45 +45 +44 +40 +39 +36 +34 +32 +31 +29 +25 +22 +21 +19 +19 +17 +15 +14 +14 +13 +12 +11 +11 +10 +9 +6 +5 +-2 +-16 +-32 +-46 +-57 +-64 +-67 +-65 +-62 +-58 +-54 +-52 +-50 +-48 +-45 +-44 +-36 +-16 +4 +22 +31 +37 +39 +39 +37 +35 +32 +30 +28 +27 +25 +22 +14 +-1 +-18 +-32 +-45 +-52 +-55 +-54 +-52 +-49 +-46 +-44 +-43 +-40 +-38 +-37 +-37 +-35 +-33 +-31 +-30 +-28 +-25 +-23 +-21 +-20 +-19 +-19 +-18 +-17 +-17 +-16 +-8 +9 +28 +44 +53 +58 +58 +55 +52 +49 +46 +43 +39 +38 +35 +32 +29 +26 +24 +23 +21 +20 +19 +19 +18 +16 +14 +13 +12 +11 +9 +8 +0 +-14 +-30 +-44 +-56 +-62 +-65 +-64 +-61 +-57 +-54 +-51 +-49 +-45 +-43 +-43 +-42 +-40 +-38 +-36 +-35 +-31 +-29 +-26 +-25 +-24 +-23 +-21 +-20 +-19 +-18 +-18 +-11 +7 +26 +43 +52 +57 +56 +54 +51 +48 +44 +42 +40 +38 +35 +31 +28 +26 +24 +23 +21 +20 +19 +18 +16 +15 +14 +14 +13 +11 +9 +7 +0 +-15 +-31 +-45 +-56 +-62 +-65 +-65 +-62 +-58 +-54 +-51 +-49 +-46 +-45 +-45 +-43 +-40 +-37 +-34 +-33 +-31 +-29 +-27 +-26 +-24 +-22 +-20 +-20 +-19 +-19 +-19 +-11 +7 +27 +43 +52 +56 +55 +54 +51 +48 +45 +42 +39 +38 +35 +31 +29 +26 +24 +22 +20 +19 +18 +18 +16 +15 +14 +14 +12 +11 +9 +7 +0 +-15 +-31 +-45 +-56 +-62 +-65 +-64 +-61 +-57 +-54 +-52 +-49 +-46 +-45 +-45 +-43 +-41 +-38 +-36 +-34 +-31 +-29 +-27 +-26 +-24 +-22 +-20 +-20 +-19 +-18 +-19 +-11 +7 +26 +43 +52 +57 +56 +53 +50 +48 +45 +42 +40 +38 +35 +31 +28 +26 +25 +23 +20 +20 +18 +17 +16 +15 +14 +13 +12 +10 +9 +7 +-1 +-15 +-31 +-44 +-55 +-62 +-66 +-64 +-61 +-57 +-54 +-51 +-49 +-46 +-46 +-45 +-43 +-40 +-38 +-35 +-34 +-31 +-29 +-27 +-26 +-23 +-22 +-20 +-19 +-19 +-19 +-19 +-11 +7 +27 +44 +52 +56 +55 +53 +51 +48 +45 +42 +40 +38 +34 +30 +22 +5 +-12 +-27 +-40 +-47 +-50 +-50 +-49 +-46 +-43 +-40 +-39 +-37 +-36 +-35 +-27 +-8 +13 +30 +40 +46 +46 +44 +42 +39 +36 +34 +32 +31 +28 +25 +22 +21 +20 +19 +16 +16 +15 +14 +13 +12 +11 +11 +10 +8 +7 +5 +-2 +-16 +-32 +-46 +-57 +-63 +-67 +-66 +-63 +-58 +-55 +-52 +-50 +-47 +-46 +-45 +-44 +-41 +-38 +-35 +-34 +-31 +-29 +-27 +-26 +-24 +-22 +-20 +-20 +-20 +-19 +-19 +-11 +7 +27 +43 +52 +56 +55 +54 +51 +48 +45 +42 +39 +37 +34 +31 +22 +6 +-12 +-27 +-40 +-47 +-50 +-50 +-48 +-46 +-43 +-41 +-40 +-37 +-36 +-35 +-26 +-8 +13 +30 +39 +45 +45 +44 +42 +39 +36 +34 +32 +31 +28 +25 +22 +21 +19 +18 +16 +16 +15 +14 +13 +12 +11 +11 +9 +8 +7 +6 +-1 +-16 +-32 +-45 +-56 +-63 +-66 +-65 +-62 +-59 +-56 +-53 +-50 +-47 +-46 +-45 +-44 +-41 +-38 +-36 +-34 +-32 +-30 +-28 +-26 +-24 +-23 +-20 +-20 +-19 +-20 +-19 +-11 +7 +27 +42 +51 +56 +55 +53 +51 +48 +44 +41 +39 +37 +34 +30 +21 +5 +-12 +-28 +-41 +-48 +-50 +-50 +-48 +-46 +-44 +-41 +-39 +-37 +-36 +-35 +-26 +-8 +12 +30 +40 +46 +46 +44 +41 +39 +36 +34 +32 +31 +28 +25 +15 +0 +-17 +-32 +-44 +-51 +-54 +-54 +-52 +-49 +-45 +-43 +-41 +-39 +-38 +-37 +-28 +-9 +12 +29 +39 +44 +43 +42 +40 +38 +35 +33 +32 +30 +27 +24 +15 +0 +-17 +-32 +-45 +-52 +-55 +-54 +-52 +-49 +-45 +-42 +-41 +-39 +-38 +-37 +-28 +-9 +12 +29 +38 +43 +43 +42 +40 +38 +35 +33 +31 +29 +27 +24 +22 +21 +19 +17 +15 +14 +14 +13 +12 +11 +10 +10 +9 +8 +6 +5 +-2 +-17 +-33 +-46 +-57 +-63 +-66 +-65 +-62 +-59 +-55 +-52 +-50 +-47 +-46 +-45 +-43 +-41 +-38 +-36 +-34 +-32 +-30 +-27 +-26 +-24 +-22 +-21 +-20 +-20 +-20 +-19 +-11 +7 +26 +42 +51 +55 +54 +53 +50 +47 +44 +41 +39 +37 +34 +30 +27 +25 +23 +22 +20 +19 +17 +17 +16 +14 +14 +13 +11 +10 +8 +7 +0 +-15 +-31 +-45 +-56 +-62 +-65 +-64 +-61 +-57 +-54 +-52 +-49 +-47 +-46 +-45 +-43 +-41 +-38 +-36 +-34 +-32 +-29 +-27 +-25 +-24 +-22 +-21 +-20 +-19 +-19 +-18 +-11 +6 +26 +41 +51 +56 +55 +53 +50 +48 +45 +42 +39 +37 +34 +30 +27 +25 +23 +22 +19 +19 +18 +17 +16 +14 +13 +13 +11 +10 +8 +7 +0 +-15 +-31 +-45 +-56 +-62 +-65 +-64 +-62 +-58 +-55 +-52 +-50 +-46 +-45 +-44 +-43 +-41 +-39 +-35 +-34 +-31 +-29 +-27 +-25 +-24 +-23 +-21 +-20 +-19 +-19 +-20 +-12 +7 +27 +42 +51 +56 +56 +53 +50 +47 +45 +42 +39 +37 +33 +31 +21 +5 +-12 +-28 +-40 +-47 +-51 +-51 +-48 +-45 +-43 +-41 +-39 +-37 +-37 +-37 +-28 +-8 +13 +29 +39 +44 +45 +44 +41 +39 +36 +33 +29 +26 +23 +20 +5 +-15 +-34 +-51 +-67 +-80 +-93 +-102 +-108 +-110 +-109 +-106 +-102 +-97 +-93 +-88 +-83 +-77 +-73 +-68 +-61 +-56 +-52 +-50 +-49 +-47 +-44 +-41 +-40 +-38 +-36 +-34 +-33 +-31 +-29 +-25 +-23 +-21 +-21 +-20 +-17 +-17 +-17 +-18 +-17 +-16 +-16 +-16 +-17 +-15 +-14 +-12 +-12 +-12 +-12 +-13 +-15 +-14 +-14 +-13 +-14 +-13 +-13 +-12 +-11 +-12 +-11 +-10 +-10 +-10 +-10 +-9 +-9 +-8 +-9 +-9 +-8 +-7 +-7 +-8 +-8 +-7 +-7 +-7 +-7 +-7 +-7 +-7 +-7 +-7 +-6 +-6 +-6 +-7 +-7 +-6 +-6 +-6 +-6 +-6 +-6 +-6 +-6 +-6 +-6 +-5 +-6 +-6 +-5 +-4 +-5 +-5 +-6 +-5 +-5 +-5 +-5 +-6 +-5 +-5 +-6 +-6 +-6 +-5 +-5 +-5 +-6 +-5 +-5 +-5 +-5 +-5 +-5 +-5 +-5 +-5 +-5 +-4 +-5 +-5 +-5 +-5 +-5 +-5 +-5 +-5 +-5 +-5 +-5 +-5 +-5 +-5 +-6 +-5 +-5 +-5 +-6 +-6 +-5 +-4 +-5 +-5 +-5 +-4 +-5 +-5 +-5 +-4 +-5 +-6 +-6 +-5 +-5 +-4 +-6 +-5 +-5 +-5 +-5 +-5 +-5 +-5 +-5 +-5 +-5 +-4 +-4 +-5 +-6 +-5 +-5 +-4 +-5 +-5 +-5 +-5 +-5 +-5 +-5 +-4 +-5 +-5 +-6 +-6 +-5 +-5 +-5 +-5 +-5 +-5 +-5 +-6 +-5 +-4 +-5 +-5 +-6 +-5 +-5 +-5 +-6 +-5 +-5 +-5 +-5 +-5 +-5 +-4 +-5 +-5 +-6 +-5 +-5 +-5 From 317b4c32e5e8eee15050d597e1f9eea1c6faa8c9 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 16 Jan 2020 11:11:14 +0100 Subject: [PATCH 1471/1854] hitag2crack stuff from RFidlar repo --- tools/hitag2crack/crack2/.gitignore | 7 + tools/hitag2crack/crack2/HardwareProfile.h | 524 +++++++++++ tools/hitag2crack/crack2/Makefile | 26 + tools/hitag2crack/crack2/hitagcrypto.c | 487 ++++++++++ tools/hitag2crack/crack2/hitagcrypto.h | 171 ++++ .../hitag2crack/crack2/ht2crack2buildtable.c | 561 +++++++++++ tools/hitag2crack/crack2/ht2crack2gentest.c | 98 ++ tools/hitag2crack/crack2/ht2crack2search.c | 433 +++++++++ tools/hitag2crack/crack2/ht2crack2utils.c | 187 ++++ tools/hitag2crack/crack2/ht2crack2utils.h | 34 + tools/hitag2crack/crack2/readme.md | 68 ++ tools/hitag2crack/crack2/rfidler.h | 412 +++++++++ tools/hitag2crack/crack2/runalltests.sh | 3 + tools/hitag2crack/crack2/runtest.sh | 25 + tools/hitag2crack/crack2/util.h | 206 +++++ tools/hitag2crack/crack2/utilpart.c | 183 ++++ tools/hitag2crack/crack3/.gitignore | 6 + tools/hitag2crack/crack3/HardwareProfile.h | 524 +++++++++++ tools/hitag2crack/crack3/Makefile | 19 + tools/hitag2crack/crack3/hitagcrypto.c | 485 ++++++++++ tools/hitag2crack/crack3/hitagcrypto.h | 171 ++++ tools/hitag2crack/crack3/ht2crack3.c | 466 ++++++++++ tools/hitag2crack/crack3/ht2test.c | 78 ++ tools/hitag2crack/crack3/readme.md | 35 + tools/hitag2crack/crack3/rfidler.h | 412 +++++++++ tools/hitag2crack/crack3/util.h | 147 +++ tools/hitag2crack/crack3/utilpart.c | 183 ++++ tools/hitag2crack/crack4/.gitignore | 3 + tools/hitag2crack/crack4/HardwareProfile.h | 524 +++++++++++ tools/hitag2crack/crack4/Makefile | 20 + tools/hitag2crack/crack4/hitagcrypto.c | 485 ++++++++++ tools/hitag2crack/crack4/hitagcrypto.h | 171 ++++ tools/hitag2crack/crack4/ht2crack2utils.c | 187 ++++ tools/hitag2crack/crack4/ht2crack2utils.h | 34 + tools/hitag2crack/crack4/ht2crack4.c | 868 ++++++++++++++++++ tools/hitag2crack/crack4/readme.md | 29 + tools/hitag2crack/crack4/rfidler.h | 412 +++++++++ tools/hitag2crack/crack4/util.h | 147 +++ tools/hitag2crack/crack4/utilpart.c | 183 ++++ tools/hitag2crack/readme.md | 206 +++++ 40 files changed, 9220 insertions(+) create mode 100644 tools/hitag2crack/crack2/.gitignore create mode 100644 tools/hitag2crack/crack2/HardwareProfile.h create mode 100644 tools/hitag2crack/crack2/Makefile create mode 100644 tools/hitag2crack/crack2/hitagcrypto.c create mode 100644 tools/hitag2crack/crack2/hitagcrypto.h create mode 100644 tools/hitag2crack/crack2/ht2crack2buildtable.c create mode 100644 tools/hitag2crack/crack2/ht2crack2gentest.c create mode 100644 tools/hitag2crack/crack2/ht2crack2search.c create mode 100644 tools/hitag2crack/crack2/ht2crack2utils.c create mode 100644 tools/hitag2crack/crack2/ht2crack2utils.h create mode 100644 tools/hitag2crack/crack2/readme.md create mode 100644 tools/hitag2crack/crack2/rfidler.h create mode 100755 tools/hitag2crack/crack2/runalltests.sh create mode 100755 tools/hitag2crack/crack2/runtest.sh create mode 100644 tools/hitag2crack/crack2/util.h create mode 100644 tools/hitag2crack/crack2/utilpart.c create mode 100644 tools/hitag2crack/crack3/.gitignore create mode 100644 tools/hitag2crack/crack3/HardwareProfile.h create mode 100644 tools/hitag2crack/crack3/Makefile create mode 100644 tools/hitag2crack/crack3/hitagcrypto.c create mode 100644 tools/hitag2crack/crack3/hitagcrypto.h create mode 100644 tools/hitag2crack/crack3/ht2crack3.c create mode 100644 tools/hitag2crack/crack3/ht2test.c create mode 100644 tools/hitag2crack/crack3/readme.md create mode 100644 tools/hitag2crack/crack3/rfidler.h create mode 100644 tools/hitag2crack/crack3/util.h create mode 100644 tools/hitag2crack/crack3/utilpart.c create mode 100644 tools/hitag2crack/crack4/.gitignore create mode 100644 tools/hitag2crack/crack4/HardwareProfile.h create mode 100644 tools/hitag2crack/crack4/Makefile create mode 100644 tools/hitag2crack/crack4/hitagcrypto.c create mode 100644 tools/hitag2crack/crack4/hitagcrypto.h create mode 100644 tools/hitag2crack/crack4/ht2crack2utils.c create mode 100644 tools/hitag2crack/crack4/ht2crack2utils.h create mode 100644 tools/hitag2crack/crack4/ht2crack4.c create mode 100644 tools/hitag2crack/crack4/readme.md create mode 100644 tools/hitag2crack/crack4/rfidler.h create mode 100644 tools/hitag2crack/crack4/util.h create mode 100644 tools/hitag2crack/crack4/utilpart.c create mode 100644 tools/hitag2crack/readme.md diff --git a/tools/hitag2crack/crack2/.gitignore b/tools/hitag2crack/crack2/.gitignore new file mode 100644 index 000000000..71494d126 --- /dev/null +++ b/tools/hitag2crack/crack2/.gitignore @@ -0,0 +1,7 @@ +ht2crack2buildtable +ht2crack2search +ht2crack2gentest + +ht2crack2buildtable.exe +ht2crack2search.exe +ht2crack2gentest.exe diff --git a/tools/hitag2crack/crack2/HardwareProfile.h b/tools/hitag2crack/crack2/HardwareProfile.h new file mode 100644 index 000000000..a2f804be6 --- /dev/null +++ b/tools/hitag2crack/crack2/HardwareProfile.h @@ -0,0 +1,524 @@ +/*************************************************************************** + * A copy of the GNU GPL is appended to this file. * + * * + * This licence is based on the nmap licence, and we express our gratitude * + * for the work that went into producing it. There is no other connection * + * between RFIDler and nmap either expressed or implied. * + * * + ********************** IMPORTANT RFIDler LICENSE TERMS ******************** + * * + * * + * All references to RFIDler herein imply all it's derivatives, namely: * + * * + * o RFIDler-LF Standard * + * o RFIDler-LF Lite * + * o RFIDler-LF Nekkid * + * * + * * + * RFIDler is (C) 2013-2014 Aperture Labs Ltd. * + * * + * This program is free software; you may redistribute and/or modify it * + * under the terms of the GNU General Public License as published by the * + * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE * + * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your * + * right to use, modify, and redistribute this software under certain * + * conditions. If you wish to embed RFIDler technology into proprietary * + * software or hardware, we sell alternative licenses * + * (contact sales@aperturelabs.com). * + * * + * Note that the GPL places important restrictions on "derivative works", * + * yet it does not provide a detailed definition of that term. To avoid * + * misunderstandings, we interpret that term as broadly as copyright law * + * allows. For example, we consider an application to constitute a * + * derivative work for the purpose of this license if it does any of the * + * following with any software or content covered by this license * + * ("Covered Software"): * + * * + * o Integrates source code from Covered Software. * + * * + * o Is designed specifically to execute Covered Software and parse the * + * results (as opposed to typical shell or execution-menu apps, which will * + * execute anything you tell them to). * + * * + * o Includes Covered Software in a proprietary executable installer. The * + * installers produced by InstallShield are an example of this. Including * + * RFIDler with other software in compressed or archival form does not * + * trigger this provision, provided appropriate open source decompression * + * or de-archiving software is widely available for no charge. For the * + * purposes of this license, an installer is considered to include Covered * + * Software even if it actually retrieves a copy of Covered Software from * + * another source during runtime (such as by downloading it from the * + * Internet). * + * * + * o Links (statically or dynamically) to a library which does any of the * + * above. * + * * + * o Executes a helper program, module, or script to do any of the above. * + * * + * This list is not exclusive, but is meant to clarify our interpretation * + * of derived works with some common examples. Other people may interpret * + * the plain GPL differently, so we consider this a special exception to * + * the GPL that we apply to Covered Software. Works which meet any of * + * these conditions must conform to all of the terms of this license, * + * particularly including the GPL Section 3 requirements of providing * + * source code and allowing free redistribution of the work as a whole. * + * * + * As another special exception to the GPL terms, Aperture Labs Ltd. grants* + * permission to link the code of this program with any version of the * + * OpenSSL library which is distributed under a license identical to that * + * listed in the included docs/licenses/OpenSSL.txt file, and distribute * + * linked combinations including the two. * + * * + * Any redistribution of Covered Software, including any derived works, * + * must obey and carry forward all of the terms of this license, including * + * obeying all GPL rules and restrictions. For example, source code of * + * the whole work must be provided and free redistribution must be * + * allowed. All GPL references to "this License", are to be treated as * + * including the terms and conditions of this license text as well. * + * * + * Because this license imposes special exceptions to the GPL, Covered * + * Work may not be combined (even as part of a larger work) with plain GPL * + * software. The terms, conditions, and exceptions of this license must * + * be included as well. This license is incompatible with some other open * + * source licenses as well. In some cases we can relicense portions of * + * RFIDler or grant special permissions to use it in other open source * + * software. Please contact sales@aperturelabs.com with any such requests.* + * Similarly, we don't incorporate incompatible open source software into * + * Covered Software without special permission from the copyright holders. * + * * + * If you have any questions about the licensing restrictions on using * + * RFIDler in other works, are happy to help. As mentioned above, we also * + * offer alternative license to integrate RFIDler into proprietary * + * applications and appliances. These contracts have been sold to dozens * + * of software vendors, and generally include a perpetual license as well * + * as providing for priority support and updates. They also fund the * + * continued development of RFIDler. Please email sales@aperturelabs.com * + * for further information. * + * If you have received a written license agreement or contract for * + * Covered Software stating terms other than these, you may choose to use * + * and redistribute Covered Software under those terms instead of these. * + * * + * Source is provided to this software because we believe users have a * + * right to know exactly what a program is going to do before they run it. * + * This also allows you to audit the software for security holes (none * + * have been found so far). * + * * + * Source code also allows you to port RFIDler to new platforms, fix bugs, * + * and add new features. You are highly encouraged to send your changes * + * to the RFIDler mailing list for possible incorporation into the * + * main distribution. By sending these changes to Aperture Labs Ltd. or * + * one of the Aperture Labs Ltd. development mailing lists, or checking * + * them into the RFIDler source code repository, it is understood (unless * + * you specify otherwise) that you are offering the RFIDler Project * + * (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, * + * modify, and relicense the code. RFIDler will always be available Open * + * Source, but this is important because the inability to relicense code * + * has caused devastating problems for other Free Software projects (such * + * as KDE and NASM). We also occasionally relicense the code to third * + * parties as discussed above. If you wish to specify special license * + * conditions of your contributions, just say so when you send them. * + * * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler * + * license file for more details (it's in a COPYING file included with * + * RFIDler, and also available from * + * https://github.com/ApertureLabsLtd/RFIDler/COPYING * + * * + ***************************************************************************/ + +// Author: Adam Laurie + + + +#ifndef HARDWARE_PROFILE_UBW32_H +#define HARDWARE_PROFILE_UBW32_H + +//#include "plib.h" +typedef char BOOL; +typedef char BYTE; +typedef int rtccTime; +typedef int rtccDate; + + +#ifndef __PIC32MX__ + #define __PIC32MX__ +#endif + +#define GetSystemClock() (80000000ul) +#define GetPeripheralClock() (GetSystemClock()) +#define GetInstructionClock() (GetSystemClock()) + +//#define USE_SELF_POWER_SENSE_IO +#define tris_self_power TRISAbits.TRISA2 // Input +#define self_power 1 + +//#define USE_USB_BUS_SENSE_IO +#define tris_usb_bus_sense TRISBbits.TRISB5 // Input +#define USB_BUS_SENSE 1 + +// LEDs +#define mLED_1 LATEbits.LATE3 + +#define mLED_2 LATEbits.LATE2 +#define mLED_Comms mLED_2 + +#define mLED_3 LATEbits.LATE1 +#define mLED_Clock mLED_3 + +#define mLED_4 LATEbits.LATE0 +#define mLED_Emulate mLED_4 + +#define mLED_5 LATGbits.LATG6 +#define mLED_Read mLED_5 + +#define mLED_6 LATAbits.LATA15 +#define mLED_User mLED_6 + +#define mLED_7 LATDbits.LATD11 +#define mLED_Error mLED_7 + +// active low +#define mLED_ON 0 +#define mLED_OFF 1 + +#define mGetLED_1() mLED_1 +#define mGetLED_USB() mLED_1 +#define mGetLED_2() mLED_2 +#define mGetLED_Comms() mLED_2 +#define mGetLED_3() mLED_3 +#define mGetLED_Clock() mLED_3 +#define mGetLED_4() mLED_4 +#define mGetLED_Emulate() mLED_4 +#define mGetLED_5() mLED_5 +#define mGetLED_Read() mLED_5 +#define mGetLED_6() mLED_6 +#define mGetLED_User() mLED_6 +#define mGetLED_7() mLED_7 +#define mGetLED_Error() mLED_7 + +#define mLED_1_On() mLED_1 = mLED_ON +#define mLED_USB_On() mLED_1_On() +#define mLED_2_On() mLED_2 = mLED_ON +#define mLED_Comms_On() mLED_2_On() +#define mLED_3_On() mLED_3 = mLED_ON +#define mLED_Clock_On() mLED_3_On() +#define mLED_4_On() mLED_4 = mLED_ON +#define mLED_Emulate_On() mLED_4_On() +#define mLED_5_On() mLED_5 = mLED_ON +#define mLED_Read_On() mLED_5_On() +#define mLED_6_On() mLED_6 = mLED_ON +#define mLED_User_On() mLED_6_On() +#define mLED_7_On() mLED_7 = mLED_ON +#define mLED_Error_On() mLED_7_On() + +#define mLED_1_Off() mLED_1 = mLED_OFF +#define mLED_USB_Off() mLED_1_Off() +#define mLED_2_Off() mLED_2 = mLED_OFF +#define mLED_Comms_Off() mLED_2_Off() +#define mLED_3_Off() mLED_3 = mLED_OFF +#define mLED_Clock_Off() mLED_3_Off() +#define mLED_4_Off() mLED_4 = mLED_OFF +#define mLED_Emulate_Off() mLED_4_Off() +#define mLED_5_Off() mLED_5 = mLED_OFF +#define mLED_Read_Off() mLED_5_Off() +#define mLED_6_Off() mLED_6 = mLED_OFF +#define mLED_User_Off() mLED_6_Off() +#define mLED_7_Off() mLED_7 = mLED_OFF +#define mLED_Error_Off() mLED_7_Off() + +#define mLED_1_Toggle() mLED_1 = !mLED_1 +#define mLED_USB_Toggle() mLED_1_Toggle() +#define mLED_2_Toggle() mLED_2 = !mLED_2 +#define mLED_Comms_Toggle() mLED_2_Toggle() +#define mLED_3_Toggle() mLED_3 = !mLED_3 +#define mLED_Clock_Toggle() mLED_3_Toggle() +#define mLED_4_Toggle() mLED_4 = !mLED_4 +#define mLED_Emulate_Toggle() mLED_4_Toggle() +#define mLED_5_Toggle() mLED_5 = !mLED_5 +#define mLED_Read_Toggle( ) mLED_5_Toggle() +#define mLED_6_Toggle() mLED_6 = !mLED_6 +#define mLED_User_Toggle() mLED_6_Toggle() +#define mLED_7_Toggle() mLED_7 = !mLED_7 +#define mLED_Error_Toggle() mLED_7_Toggle() + +#define mLED_All_On() { mLED_1_On(); mLED_2_On(); mLED_3_On(); mLED_4_On(); mLED_5_On(); mLED_6_On(); mLED_7_On(); } +#define mLED_All_Off() { mLED_1_Off(); mLED_2_Off(); mLED_3_Off(); mLED_4_Off(); mLED_5_Off(); mLED_6_Off(); mLED_7_Off(); } + +// usb status lights +#define mLED_Both_Off() {mLED_USB_Off();mLED_Comms_Off();} +#define mLED_Both_On() {mLED_USB_On();mLED_Comms_On();} +#define mLED_Only_USB_On() {mLED_USB_On();mLED_Comms_Off();} +#define mLED_Only_Comms_On() {mLED_USB_Off();mLED_Comms_On();} + +/** SWITCH *********************************************************/ +#define swBootloader PORTEbits.RE7 +#define swUser PORTEbits.RE6 + +/** I/O pin definitions ********************************************/ +#define INPUT_PIN 1 +#define OUTPUT_PIN 0 + +#define TRUE 1 +#define FALSE 0 + +#define ENABLE 1 +#define DISABE 0 + +#define EVEN 0 +#define ODD 1 + +#define LOW FALSE +#define HIGH TRUE + +#define CLOCK_ON LOW +#define CLOCK_OFF HIGH + +// output coil control - select between reader/emulator circuits +#define COIL_MODE LATBbits.LATB4 +#define COIL_MODE_READER() COIL_MODE= LOW +#define COIL_MODE_EMULATOR() COIL_MODE= HIGH + +// coil for emulation +#define COIL_OUT LATGbits.LATG9 +#define COIL_OUT_HIGH() COIL_OUT=HIGH +#define COIL_OUT_LOW() COIL_OUT=LOW + +// door relay (active low) +#define DOOR_RELAY LATAbits.LATA14 +#define DOOR_RELAY_OPEN() DOOR_RELAY= HIGH +#define DOOR_RELAY_CLOSE() DOOR_RELAY= LOW + +// inductance/capacitance freq +#define IC_FREQUENCY PORTAbits.RA2 + +#define SNIFFER_COIL PORTDbits.RD12 // external reader clock detect +#define READER_ANALOGUE PORTBbits.RB11 // reader coil analogue +#define DIV_LOW_ANALOGUE PORTBbits.RB12 // voltage divider LOW analogue +#define DIV_HIGH_ANALOGUE PORTBbits.RB13 // voltage divider HIGH analogue + +// clock coil (normally controlled by OC Module, but defined here so we can force it high or low) +#define CLOCK_COIL PORTDbits.RD4 +#define CLOCK_COIL_MOVED PORTDbits.RD0 // temporary for greenwire + +// digital output after analogue reader circuit +#define READER_DATA PORTDbits.RD8 + +// trace / debug +#define DEBUG_PIN_1 LATCbits.LATC1 +#define DEBUG_PIN_1_TOGGLE() DEBUG_PIN_1= !DEBUG_PIN_1 +#define DEBUG_PIN_2 LATCbits.LATC2 +#define DEBUG_PIN_2_TOGGLE() DEBUG_PIN_2= !DEBUG_PIN_2 +#define DEBUG_PIN_3 LATCbits.LATC3 +#define DEBUG_PIN_3_TOGGLE() DEBUG_PIN_3= !DEBUG_PIN_3 +#define DEBUG_PIN_4 LATEbits.LATE5 +#define DEBUG_PIN_4_TOGGLE() DEBUG_PIN_4= !DEBUG_PIN_4 + +// spi (sdi1) for sd card (not directly referenced) +//#define SD_CARD_RX LATCbits.LATC4 +//#define SD_CARD_TX LATDbits.LATD0 +//#define SD_CARD_CLK LATDbits.LATD10 +//#define SD_CARD_SS LATDbits.LATD9 +// spi for SD card +#define SD_CARD_DET LATFbits.LATF0 +#define SD_CARD_WE LATFbits.LATF1 // write enable - unused for microsd but allocated anyway as library checks it + // (held LOW by default - cut solder bridge to GND to free pin if required) +#define SPI_SD SPI_CHANNEL1 +#define SPI_SD_BUFF SPI1BUF +#define SPI_SD_STAT SPI1STATbits +// see section below for more defines! + +// iso 7816 smartcard +// microchip SC module defines pins so we don't need to, but +// they are listed here to help avoid conflicts +#define ISO_7816_RX LATBbits.LATF2 // RX +#define ISO_7816_TX LATBbits.LATF8 // TX +#define ISO_7816_VCC LATBbits.LATB9 // Power +#define ISO_7816_CLK LATCbits.LATD1 // Clock +#define ISO_7816_RST LATEbits.LATE8 // Reset + +// user LED +#define USER_LED LATDbits.LATD7 +#define USER_LED_ON() LATDbits.LATD7=1 +#define USER_LED_OFF() LATDbits.LATD7=0 + +// LCR +#define LCR_CALIBRATE LATBbits.LATB5 + +// wiegand / clock & data +#define WIEGAND_IN_0 PORTDbits.RD5 +#define WIEGAND_IN_0_PULLUP CNPUEbits.CNPUE14 +#define WIEGAND_IN_0_PULLDOWN CNPDbits.CNPD14 +#define WIEGAND_IN_1 PORTDbits.RD6 +#define WIEGAND_IN_1_PULLUP CNPUEbits.CNPUE15 +#define WIEGAND_IN_1_PULLDOWN CNPDbits.CNPD15 +#define CAND_IN_DATA WIEGAND_IN_0 +#define CAND_IN_CLOCK WIEGAND_IN_1 + +#define WIEGAND_OUT_0 LATDbits.LATD3 +#define WIEGAND_OUT_1 LATDbits.LATD2 +#define WIEGAND_OUT_0_TRIS TRISDbits.TRISD3 +#define WIEGAND_OUT_1_TRIS TRISDbits.TRISD2 +#define CAND_OUT_DATA WIEGAND_OUT_0 +#define CAND_OUT_CLOCK WIEGAND_OUT_1 + +// connect/disconnect reader clock from coil - used to send RWD signals by creating gaps in carrier +#define READER_CLOCK_ENABLE LATEbits.LATE9 +#define READER_CLOCK_ENABLE_ON() READER_CLOCK_ENABLE=CLOCK_ON +#define READER_CLOCK_ENABLE_OFF(x) {READER_CLOCK_ENABLE=CLOCK_OFF; COIL_OUT=x;} + +// these input pins must NEVER bet set to output or they will cause short circuits! +// they can be used to see data from reader before it goes into or gate +#define OR_IN_A PORTAbits.RA4 +#define OR_IN_B PORTAbits.RA5 + + +// CNCON and CNEN are set to allow wiegand input pin weak pullups to be switched on +#define Init_GPIO() { \ + CNCONbits.ON= TRUE; \ + CNENbits.CNEN14= TRUE; \ + CNENbits.CNEN15= TRUE; \ + TRISAbits.TRISA2= INPUT_PIN; \ + TRISAbits.TRISA4= INPUT_PIN; \ + TRISAbits.TRISA5= INPUT_PIN; \ + TRISAbits.TRISA14= OUTPUT_PIN; \ + TRISAbits.TRISA15= OUTPUT_PIN; \ + TRISBbits.TRISB4= OUTPUT_PIN; \ + TRISBbits.TRISB5= OUTPUT_PIN; \ + TRISBbits.TRISB9= OUTPUT_PIN; \ + TRISBbits.TRISB11= INPUT_PIN; \ + TRISBbits.TRISB12= INPUT_PIN; \ + TRISBbits.TRISB13= INPUT_PIN; \ + TRISCbits.TRISC1= OUTPUT_PIN; \ + TRISCbits.TRISC2= OUTPUT_PIN; \ + TRISCbits.TRISC3= OUTPUT_PIN; \ + TRISCbits.TRISC4= INPUT_PIN; \ + TRISDbits.TRISD0= INPUT_PIN; \ + TRISDbits.TRISD1= OUTPUT_PIN; \ + TRISDbits.TRISD2= OUTPUT_PIN; \ + TRISDbits.TRISD3= OUTPUT_PIN; \ + TRISDbits.TRISD4= OUTPUT_PIN; \ + TRISDbits.TRISD5= INPUT_PIN; \ + TRISDbits.TRISD6= INPUT_PIN; \ + TRISDbits.TRISD7= OUTPUT_PIN; \ + TRISDbits.TRISD8= INPUT_PIN; \ + TRISDbits.TRISD11= OUTPUT_PIN; \ + TRISDbits.TRISD12= INPUT_PIN; \ + TRISEbits.TRISE0= OUTPUT_PIN; \ + TRISEbits.TRISE1= OUTPUT_PIN; \ + TRISEbits.TRISE2= OUTPUT_PIN; \ + TRISEbits.TRISE3= OUTPUT_PIN; \ + TRISEbits.TRISE5= OUTPUT_PIN; \ + TRISEbits.TRISE6= INPUT_PIN; \ + TRISEbits.TRISE7= INPUT_PIN; \ + TRISEbits.TRISE8= OUTPUT_PIN; \ + TRISEbits.TRISE9= OUTPUT_PIN; \ + TRISFbits.TRISF0= INPUT_PIN; \ + TRISFbits.TRISF1= INPUT_PIN; \ + TRISFbits.TRISF2= INPUT_PIN; \ + TRISFbits.TRISF8= OUTPUT_PIN; \ + TRISGbits.TRISG6= OUTPUT_PIN; \ + TRISGbits.TRISG12= INPUT_PIN; \ + TRISGbits.TRISG13= INPUT_PIN; \ + TRISGbits.TRISG9= OUTPUT_PIN; \ + LATBbits.LATB9= LOW; \ + LATCbits.LATC1= LOW; \ + LATCbits.LATC2= LOW; \ + LATCbits.LATC3= LOW; \ + LATDbits.LATD2= WIEGAND_IN_1; \ + LATDbits.LATD3= WIEGAND_IN_0; \ + LATEbits.LATE5= LOW; \ + LATEbits.LATE9= HIGH; \ + } + +// uart3 (CLI/API) speed +#define BAUDRATE3 115200UL +#define BRG_DIV3 4 +#define BRGH3 1 + +// spi for potentiometer +#define SPI_POT SPI_CHANNEL4 +#define SPI_POT_BUFF SPI4BUF +#define SPI_POT_STAT SPI4STATbits + +// spi for sd card - defines required for Microchip SD-SPI libs +// define interface type +#define USE_SD_INTERFACE_WITH_SPI + +#define MDD_USE_SPI_1 +#define SPI_START_CFG_1 (PRI_PRESCAL_64_1 | SEC_PRESCAL_8_1 | MASTER_ENABLE_ON | SPI_CKE_ON | SPI_SMP_ON) +#define SPI_START_CFG_2 (SPI_ENABLE) +// Define the SPI frequency +#define SPI_FREQUENCY (20000000) +// Description: SD-SPI Card Detect Input bit +#define SD_CD PORTFbits.RF0 +// Description: SD-SPI Card Detect TRIS bit +#define SD_CD_TRIS TRISFbits.TRISF0 +// Description: SD-SPI Write Protect Check Input bit +#define SD_WE PORTFbits.RF1 +// Description: SD-SPI Write Protect Check TRIS bit +#define SD_WE_TRIS TRISFbits.TRISF1 +// Description: The main SPI control register +#define SPICON1 SPI1CON +// Description: The SPI status register +#define SPISTAT SPI1STAT +// Description: The SPI Buffer +#define SPIBUF SPI1BUF +// Description: The receive buffer full bit in the SPI status register +#define SPISTAT_RBF SPI1STATbits.SPIRBF +// Description: The bitwise define for the SPI control register (i.e. _____bits) +#define SPICON1bits SPI1CONbits +// Description: The bitwise define for the SPI status register (i.e. _____bits) +#define SPISTATbits SPI1STATbits +// Description: The enable bit for the SPI module +#define SPIENABLE SPICON1bits.ON +// Description: The definition for the SPI baud rate generator register (PIC32) +#define SPIBRG SPI1BRG +// Description: The TRIS bit for the SCK pin +#define SPICLOCK TRISDbits.TRISD10 +// Description: The TRIS bit for the SDI pin +#define SPIIN TRISCbits.TRISC4 +// Description: The TRIS bit for the SDO pin +#define SPIOUT TRISDbits.TRISD0 +#define SD_CS LATDbits.LATD9 +// Description: SD-SPI Chip Select TRIS bit +#define SD_CS_TRIS TRISDbits.TRISD9 +//SPI library functions +#define putcSPI putcSPI1 +#define getcSPI getcSPI1 +#define OpenSPI(config1, config2) OpenSPI1(config1, config2) + +// Define setup parameters for OpenADC10 function +// Turn module on | Ouput in integer format | Trigger mode auto | Enable autosample +#define ADC_CONFIG1 (ADC_FORMAT_INTG | ADC_CLK_AUTO | ADC_AUTO_SAMPLING_ON) +// ADC ref external | Disable offset test | Disable scan mode | Perform 2 samples | Use dual buffers | Use alternate mode +#define ADC_CONFIG2 (ADC_VREF_AVDD_AVSS | ADC_OFFSET_CAL_DISABLE | ADC_SCAN_OFF | ADC_SAMPLES_PER_INT_1 | ADC_ALT_BUF_ON | ADC_ALT_INPUT_ON) + +// Use ADC internal clock | Set sample time +#define ADC_CONFIG3 (ADC_CONV_CLK_INTERNAL_RC | ADC_SAMPLE_TIME_0) + +// slow sample rate for tuning coils +#define ADC_CONFIG2_SLOW (ADC_VREF_AVDD_AVSS | ADC_OFFSET_CAL_DISABLE | ADC_SCAN_OFF | ADC_SAMPLES_PER_INT_16 | ADC_ALT_BUF_ON | ADC_ALT_INPUT_ON) +#define ADC_CONFIG3_SLOW (ADC_CONV_CLK_INTERNAL_RC | ADC_SAMPLE_TIME_31) + +// use AN11 +#define ADC_CONFIGPORT ENABLE_AN11_ANA +// Do not assign channels to scan +#define ADC_CONFIGSCAN SKIP_SCAN_ALL + +#define ADC_TO_VOLTS 0.003208F + + +// flash memory - int myvar = *(int*)(myflashmemoryaddress); + +// memory is 0x9D005000 to 0x9D07FFFF + +#define NVM_MEMORY_END 0x9D07FFFF +#define NVM_PAGE_SIZE 4096 +#define NVM_PAGES 2 // config & VTAG +#define RFIDLER_NVM_ADDRESS (NVM_MEMORY_END - (NVM_PAGE_SIZE * NVM_PAGES)) + +// UART timeout in us +#define SERIAL_TIMEOUT 100 + +#endif diff --git a/tools/hitag2crack/crack2/Makefile b/tools/hitag2crack/crack2/Makefile new file mode 100644 index 000000000..3ec604530 --- /dev/null +++ b/tools/hitag2crack/crack2/Makefile @@ -0,0 +1,26 @@ +WARN=-Wall +INCLUDE=-I../include +CFLAGS=-c $(WARN) $(INCLUDE) +# Linux libs +LIBS=-pthread -D_GNU_SOURCE +# Mac libs +# LIBS= + +all: ht2crack2buildtable.c ht2crack2search.c ht2crack2gentest.c hitagcrypto.o utilpart.o ht2crack2utils.o + cc $(WARN) -o ht2crack2buildtable ht2crack2buildtable.c hitagcrypto.o ht2crack2utils.o $(LIBS) + cc $(WARN) -o ht2crack2search ht2crack2search.c hitagcrypto.o utilpart.o ht2crack2utils.o $(LIBS) + cc $(WARN) -o ht2crack2gentest ht2crack2gentest.c hitagcrypto.o utilpart.o ht2crack2utils.o $(LIBS) + +ht2crack2utils.o: ht2crack2utils.c ht2crack2utils.h + cc $(CFLAGS) ht2crack2utils.c + +hitagcrypto.o: hitagcrypto.c hitagcrypto.h + cc $(CFLAGS) hitagcrypto.c + +utilpart.o: utilpart.c util.h + cc $(CFLAGS) utilpart.c + +clean: + rm -rf *.o ht2crack2buildtable ht2crack2search ht2crack2gentest + +fresh: clean all diff --git a/tools/hitag2crack/crack2/hitagcrypto.c b/tools/hitag2crack/crack2/hitagcrypto.c new file mode 100644 index 000000000..2334f8288 --- /dev/null +++ b/tools/hitag2crack/crack2/hitagcrypto.c @@ -0,0 +1,487 @@ +/*************************************************************************** + * A copy of the GNU GPL is appended to this file. * + * * + * This licence is based on the nmap licence, and we express our gratitude * + * for the work that went into producing it. There is no other connection * + * between RFIDler and nmap either expressed or implied. * + * * + ********************** IMPORTANT RFIDler LICENSE TERMS ******************** + * * + * * + * All references to RFIDler herein imply all it's derivatives, namely: * + * * + * o RFIDler-LF Standard * + * o RFIDler-LF Lite * + * o RFIDler-LF Nekkid * + * * + * * + * RFIDler is (C) 2013-2015 Aperture Labs Ltd. * + * * + * This program is free software; you may redistribute and/or modify it * + * under the terms of the GNU General Public License as published by the * + * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE * + * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your * + * right to use, modify, and redistribute this software under certain * + * conditions. If you wish to embed RFIDler technology into proprietary * + * software or hardware, we sell alternative licenses * + * (contact sales@aperturelabs.com). * + * * + * Note that the GPL places important restrictions on "derivative works", * + * yet it does not provide a detailed definition of that term. To avoid * + * misunderstandings, we interpret that term as broadly as copyright law * + * allows. For example, we consider an application to constitute a * + * derivative work for the purpose of this license if it does any of the * + * following with any software or content covered by this license * + * ("Covered Software"): * + * * + * o Integrates source code from Covered Software. * + * * + * o Is designed specifically to execute Covered Software and parse the * + * results (as opposed to typical shell or execution-menu apps, which will * + * execute anything you tell them to). * + * * + * o Includes Covered Software in a proprietary executable installer. The * + * installers produced by InstallShield are an example of this. Including * + * RFIDler with other software in compressed or archival form does not * + * trigger this provision, provided appropriate open source decompression * + * or de-archiving software is widely available for no charge. For the * + * purposes of this license, an installer is considered to include Covered * + * Software even if it actually retrieves a copy of Covered Software from * + * another source during runtime (such as by downloading it from the * + * Internet). * + * * + * o Links (statically or dynamically) to a library which does any of the * + * above. * + * * + * o Executes a helper program, module, or script to do any of the above. * + * * + * This list is not exclusive, but is meant to clarify our interpretation * + * of derived works with some common examples. Other people may interpret * + * the plain GPL differently, so we consider this a special exception to * + * the GPL that we apply to Covered Software. Works which meet any of * + * these conditions must conform to all of the terms of this license, * + * particularly including the GPL Section 3 requirements of providing * + * source code and allowing free redistribution of the work as a whole. * + * * + * As another special exception to the GPL terms, Aperture Labs Ltd. grants* + * permission to link the code of this program with any version of the * + * OpenSSL library which is distributed under a license identical to that * + * listed in the included docs/licenses/OpenSSL.txt file, and distribute * + * linked combinations including the two. * + * * + * Any redistribution of Covered Software, including any derived works, * + * must obey and carry forward all of the terms of this license, including * + * obeying all GPL rules and restrictions. For example, source code of * + * the whole work must be provided and free redistribution must be * + * allowed. All GPL references to "this License", are to be treated as * + * including the terms and conditions of this license text as well. * + * * + * Because this license imposes special exceptions to the GPL, Covered * + * Work may not be combined (even as part of a larger work) with plain GPL * + * software. The terms, conditions, and exceptions of this license must * + * be included as well. This license is incompatible with some other open * + * source licenses as well. In some cases we can relicense portions of * + * RFIDler or grant special permissions to use it in other open source * + * software. Please contact sales@aperturelabs.com with any such requests.* + * Similarly, we don't incorporate incompatible open source software into * + * Covered Software without special permission from the copyright holders. * + * * + * If you have any questions about the licensing restrictions on using * + * RFIDler in other works, are happy to help. As mentioned above, we also * + * offer alternative license to integrate RFIDler into proprietary * + * applications and appliances. These contracts have been sold to dozens * + * of software vendors, and generally include a perpetual license as well * + * as providing for priority support and updates. They also fund the * + * continued development of RFIDler. Please email sales@aperturelabs.com * + * for further information. * + * If you have received a written license agreement or contract for * + * Covered Software stating terms other than these, you may choose to use * + * and redistribute Covered Software under those terms instead of these. * + * * + * Source is provided to this software because we believe users have a * + * right to know exactly what a program is going to do before they run it. * + * This also allows you to audit the software for security holes (none * + * have been found so far). * + * * + * Source code also allows you to port RFIDler to new platforms, fix bugs, * + * and add new features. You are highly encouraged to send your changes * + * to the RFIDler mailing list for possible incorporation into the * + * main distribution. By sending these changes to Aperture Labs Ltd. or * + * one of the Aperture Labs Ltd. development mailing lists, or checking * + * them into the RFIDler source code repository, it is understood (unless * + * you specify otherwise) that you are offering the RFIDler Project * + * (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, * + * modify, and relicense the code. RFIDler will always be available Open * + * Source, but this is important because the inability to relicense code * + * has caused devastating problems for other Free Software projects (such * + * as KDE and NASM). We also occasionally relicense the code to third * + * parties as discussed above. If you wish to specify special license * + * conditions of your contributions, just say so when you send them. * + * * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler * + * license file for more details (it's in a COPYING file included with * + * RFIDler, and also available from * + * https://github.com/ApertureLabsLtd/RFIDler/COPYING * + * * + ***************************************************************************/ + +// Author: unknown. +// Modifications for RFIDler: Tony Naggs , Adam Laurie + +// uncomment this to build file as a standalone crypto test program +// #define UNIT_TEST +// also uncomment to include verbose debug prints +// #define TEST_DEBUG + +//#include +#include "HardwareProfile.h" +#include "rfidler.h" +#include "hitagcrypto.h" +#include "util.h" + +#ifdef UNIT_TEST +#include +#endif + +#if defined(UNIT_TEST) && defined(TEST_DEBUG) +// Note that printf format %I64x prints 64 bit ints in MS Visual C/C++. +// This may need changing for other compilers/platforms. +#define DEBUG_PRINTF(...) printf(__VA_ARGS__) +#else +#define DEBUG_PRINTF(...) +#endif + + +/* Brief info about NXP Hitag 1, Hitag 2, Hitag S and Hitag u (mu) + + Hitag 125kHz RFID was created by a company called Mikron (Mikron Gesellschaft + fur Integrierte Mikroelektronik Mbh), of Austria, for micropayment applications. + At about the same time, late 1980s to early 1990s, Mikron developed the + similarly featured Mifare micropayment card for 13.56MHz RFID. + (Mikron's European Patent EP 0473569 A2 was filed 23 August 1991, with a + priority date of 23 Aug 1990.) + Mikron was subsequently acquired by Philips Semiconductors in 1995. + Philips Semiconductors divsion subsequently became NXP. + + + Modulation read/write device -> transponder: 100 % ASK and binary pulse + length coding + + Modulation transponder -> read/write device: Strong ASK modulation, + selectable Manchester or Biphase coding + + Hitag S, Hitag u; anti-collision procedure + + Fast anti-collision protocol + + Hitag u; optional Cyclic Redundancy Check (CRC) + + Reader Talks First mode + + Hitag 2 & later; Transponder Talks First (TTF) mode + + Temporary switch from Transponder Talks First into Reader Talks First + (RTF) Mode + + Data rate read/write device to transponder: 5.2 kbit/s + + Data rates transponder to read/write device: 2 kbit/s, 4 kbit/s, 8 kbit/s + + 32-bit password feature + + Hitag 2, S = 32-bit Unique Identifier + + Hitag u = 48-bit Unique Identifier + + Selectable password modes for reader / tag mutual authentication + (Hitag 1 has 2 pairs of keys, later versions have 1 pair) + + Hitag 2 & Hitag S; Selectable encrypted mode, 48 bit key + + Known tag types: + + HITAG 1 2048 bits total memory + + HITAG 2 256 Bit total memory Read/Write + 8 pages of 32 bits, inc UID (32), + secret key (64), password (24), config (8) + + HITAG S 32 32 bits Unique Identifier Read Only + HITAG S 256 256 bits total memory Read/Write + HITAG S 2048 2048 bits total memory Read/Write + + HITAG u RO64 64 bits total memory Read Only + HITAG u 128 bits total memory Read/Write + HITAG u Advanced 512 bits total memory Read/Write + HITAG u Advanced+ 1760 bits total memory Read/Write + + Default 48-bit key for Hitag 2, S encryption: + "MIKRON" = O N M I K R + Key = 4F 4E 4D 49 4B 52 + +*/ + + +// We want the crypto functions to be as fast as possible, so optimize! +// The best compiler optimization in Microchip's free XC32 edition is -O1 +//#pragma GCC optimize("O1") + +// private, nonlinear function to generate 1 crypto bit +static uint32_t hitag2_crypt(uint64_t x); + + +// macros to pick out 4 bits in various patterns of 1s & 2s & make a new number +#define pickbits2_2(S, A, B) ( ((S >> A) & 3) | ((S >> (B - 2)) & 0xC) ) +#define pickbits1x4(S, A, B, C, D) ( ((S >> A) & 1) | ((S >> (B - 1)) & 2) | \ + ((S >> (C - 2)) & 4) | ((S >> (D - 3)) & 8) ) +#define pickbits1_1_2(S, A, B, C) ( ((S >> A) & 1) | ((S >> (B - 1)) & 2) | \ + ((S >> (C - 2)) & 0xC) ) +#define pickbits2_1_1(S, A, B, C) ( ((S >> A) & 3) | ((S >> (B - 2)) & 4) | \ + ((S >> (C - 3)) & 8) ) +#define pickbits1_2_1(S, A, B, C) ( ((S >> A) & 1) | ((S >> (B - 1)) & 6) | \ + ((S >> (C - 3)) & 8) ) + + +static uint32_t hitag2_crypt(uint64_t s) +{ + const uint32_t ht2_function4a = 0x2C79; // 0010 1100 0111 1001 + const uint32_t ht2_function4b = 0x6671; // 0110 0110 0111 0001 + const uint32_t ht2_function5c = 0x7907287B; // 0111 1001 0000 0111 0010 1000 0111 1011 + uint32_t bitindex; + + bitindex = (ht2_function4a >> pickbits2_2 (s, 1, 4)) & 1; + bitindex |= ((ht2_function4b << 1) >> pickbits1_1_2 (s, 7, 11, 13)) & 0x02; + bitindex |= ((ht2_function4b << 2) >> pickbits1x4 (s, 16, 20, 22, 25)) & 0x04; + bitindex |= ((ht2_function4b << 3) >> pickbits2_1_1 (s, 27, 30, 32)) & 0x08; + bitindex |= ((ht2_function4a << 4) >> pickbits1_2_1(s, 33, 42, 45)) & 0x10; + + DEBUG_PRINTF("hitag2_crypt bitindex = %02x\n", bitindex); + return (ht2_function5c >> bitindex) & 1; +} + +/* + * Parameters: + * Hitag_State* pstate - output, internal state after initialisation + * uint64_t sharedkey - 48 bit key shared between reader & tag + * uint32_t serialnum - 32 bit tag serial number + * uint32_t initvector - 32 bit random IV from reader, part of tag authentication + */ +void hitag2_init(Hitag_State* pstate, uint64_t sharedkey, uint32_t serialnum, uint32_t initvector) +{ + // init state, from serial number and lowest 16 bits of shared key + uint64_t state = ((sharedkey & 0xFFFF) << 32) | serialnum; + + // mix the initialisation vector and highest 32 bits of the shared key + initvector ^= (uint32_t) (sharedkey >> 16); + + // move 16 bits from (IV xor Shared Key) to top of uint64_t state + // these will be XORed in turn with output of the crypto function + state |= (uint64_t) initvector << 48; + initvector >>= 16; + + // unrolled loop is faster on PIC32 (MIPS), do 32 times + // shift register, then calc new bit + state >>= 1; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + + // highest 16 bits of IV XOR Shared Key + state |= (uint64_t) initvector << 47; + + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state ^= (uint64_t) hitag2_crypt(state) << 47; + + DEBUG_PRINTF("hitag2_init result = %012I64x\n", state); + pstate->shiftreg = state; + /* naive version for reference, LFSR has 16 taps + pstate->lfsr = state ^ (state >> 2) ^ (state >> 3) ^ (state >> 6) + ^ (state >> 7) ^ (state >> 8) ^ (state >> 16) ^ (state >> 22) + ^ (state >> 23) ^ (state >> 26) ^ (state >> 30) ^ (state >> 41) + ^ (state >> 42) ^ (state >> 43) ^ (state >> 46) ^ (state >> 47); + */ + { + // optimise with one 64-bit intermediate + uint64_t temp = state ^ (state >> 1); + pstate->lfsr = state ^ (state >> 6) ^ (state >> 16) + ^ (state >> 26) ^ (state >> 30) ^ (state >> 41) + ^ (temp >> 2) ^ (temp >> 7) ^ (temp >> 22) + ^ (temp >> 42) ^ (temp >> 46); + } +} + + +/* + * Return up to 32 crypto bits. + * Last bit is in least significant bit, earlier bits are shifted left. + * Note that the Hitag transmission protocol is least significant bit, + * so we may want to change this, or add a function, that returns the + * crypto output bits in the other order. + * + * Parameters: + * Hitag_State* pstate - in/out, internal cipher state after initialisation + * uint32_t steps - number of bits requested, (capped at 32) + */ +uint32_t hitag2_nstep(Hitag_State* pstate, uint32_t steps) +{ + uint64_t state = pstate->shiftreg; + uint32_t result = 0; + uint64_t lfsr = pstate->lfsr; + + if (steps == 0) + return 0; + +// commented out the restriction on number of steps so we can step further in one go. +// this still only returns 32 bits obviously +// if (steps > 32) +// steps = 32; + + do { + // update shift registers + if (lfsr & 1) { + state = (state >> 1) | 0x800000000000; + lfsr = (lfsr >> 1) ^ 0xB38083220073; + + // accumulate next bit of crypto + result = (result << 1) | hitag2_crypt(state); + } else { + state >>= 1; + lfsr >>= 1; + + result = (result << 1) | hitag2_crypt(state); + } + } while (--steps); + + DEBUG_PRINTF("hitag2_nstep state = %012I64x, result %02x\n", state, result); + pstate->shiftreg = state; + pstate->lfsr = lfsr; + return result; +} + +// end of crypto core, revert to default optimization level +//#pragma GCC reset_options + + +/* Test code + + Test data and below information about it comes from + http://www.mikrocontroller.net/attachment/102194/hitag2.c + Written by "I.C. Wiener 2006-2007" + + "MIKRON" = O N M I K R + Key = 4F 4E 4D 49 4B 52 - Secret 48-bit key + Serial = 49 43 57 69 - Serial number of the tag, transmitted in clear + Random = 65 6E 45 72 - Random IV, transmitted in clear + ~28~DC~80~31 = D7 23 7F CE - Authenticator value = inverted first 4 bytes of the keystream + + The code below must print out "D7 23 7F CE 8C D0 37 A9 57 49 C1 E6 48 00 8A B6". + The inverse of the first 4 bytes is sent to the tag to authenticate. + The rest is encrypted by XORing it with the subsequent keystream. + +*/ + + +/* +unsigned int hitag2_benchtest_gen32() +{ + const uint64_t key = 0x4ad292b272f2; + const uint32_t serial = 0x96eac292; + const uint32_t initvec = 0x4ea276a6; + Hitag_State state; + + // init crypto + hitag2_init(&state, key, serial, initvec); + + // benchmark: generation of 32 bit stream (excludes initialisation) + GetTimer_us(RESET); + + (void) hitag2_nstep(&state, 32); + + return GetTimer_us(NO_RESET); +} + + +unsigned int hitag2_benchtest(uint32_t count) +{ + const uint64_t key = 0x4ad292b272f2; + const uint32_t serial = 0x96eac292; + const uint32_t initvec = 0x4ea276a6; + Hitag_State state; + uint32_t i; + + // start timer + GetTimer_us(RESET); + + // benchmark: initialise crypto & generate 32 bit authentication + // adding i stops gcc optimizer moving init function call out of loop + for (i = 0; i < count; i++) { + hitag2_init(&state, key, serial, initvec + i); + (void) hitag2_nstep(&state, 32); + } + + return GetTimer_us(NO_RESET); +} + + +unsigned hitag2_verifytest() +{ + uint8_t expected[16] = { 0xD7, 0x23, 0x7F, 0xCE, 0x8C, 0xD0, 0x37, 0xA9, 0x57, 0x49, 0xC1, 0xE6, 0x48, 0x00, 0x8A, 0xB6 }; + // key = 0x4ad292b272f2 after each byte has its bit order reversed + // serial = 0x96eac292 ditto + // initvec = 0x4ea276a6 ditto + const uint64_t key = rev64 (0x524B494D4E4FUL); + const uint32_t serial = rev32 (0x69574349); + const uint32_t initvec = rev32 (0x72456E65); + + uint32_t i; + Hitag_State state; + + // initialise + hitag2_init(&state, key, serial, initvec); + + for (i = 0; i < 16; i++) { + // get 8 bits of keystream + uint8_t x = (uint8_t) hitag2_nstep(&state, 8); + uint8_t y = expected[i]; + + DEBUG_PRINTF ("%02X (%02X) \n", x, y); + if (x != y) + return 0; + } + + return 1; +} +*/ + +#ifdef UNIT_TEST + +int main(int argc, char* argv[]) +{ + unsigned pass = hitag2_verifytest(); + + printf ("Crypto Verify test = %s\n\n", pass ? "PASS" : "FAIL"); + + if (pass) { + hitag2_benchtest(10000); + } + + return 0; +} + +#endif // UNIT_TEST diff --git a/tools/hitag2crack/crack2/hitagcrypto.h b/tools/hitag2crack/crack2/hitagcrypto.h new file mode 100644 index 000000000..d5aa9104c --- /dev/null +++ b/tools/hitag2crack/crack2/hitagcrypto.h @@ -0,0 +1,171 @@ +/*************************************************************************** + * A copy of the GNU GPL is appended to this file. * + * * + * This licence is based on the nmap licence, and we express our gratitude * + * for the work that went into producing it. There is no other connection * + * between RFIDler and nmap either expressed or implied. * + * * + ********************** IMPORTANT RFIDler LICENSE TERMS ******************** + * * + * * + * All references to RFIDler herein imply all it's derivatives, namely: * + * * + * o RFIDler-LF Standard * + * o RFIDler-LF Lite * + * o RFIDler-LF Nekkid * + * * + * * + * RFIDler is (C) 2013-2014 Aperture Labs Ltd. * + * * + * This program is free software; you may redistribute and/or modify it * + * under the terms of the GNU General Public License as published by the * + * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE * + * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your * + * right to use, modify, and redistribute this software under certain * + * conditions. If you wish to embed RFIDler technology into proprietary * + * software or hardware, we sell alternative licenses * + * (contact sales@aperturelabs.com). * + * * + * Note that the GPL places important restrictions on "derivative works", * + * yet it does not provide a detailed definition of that term. To avoid * + * misunderstandings, we interpret that term as broadly as copyright law * + * allows. For example, we consider an application to constitute a * + * derivative work for the purpose of this license if it does any of the * + * following with any software or content covered by this license * + * ("Covered Software"): * + * * + * o Integrates source code from Covered Software. * + * * + * o Is designed specifically to execute Covered Software and parse the * + * results (as opposed to typical shell or execution-menu apps, which will * + * execute anything you tell them to). * + * * + * o Includes Covered Software in a proprietary executable installer. The * + * installers produced by InstallShield are an example of this. Including * + * RFIDler with other software in compressed or archival form does not * + * trigger this provision, provided appropriate open source decompression * + * or de-archiving software is widely available for no charge. For the * + * purposes of this license, an installer is considered to include Covered * + * Software even if it actually retrieves a copy of Covered Software from * + * another source during runtime (such as by downloading it from the * + * Internet). * + * * + * o Links (statically or dynamically) to a library which does any of the * + * above. * + * * + * o Executes a helper program, module, or script to do any of the above. * + * * + * This list is not exclusive, but is meant to clarify our interpretation * + * of derived works with some common examples. Other people may interpret * + * the plain GPL differently, so we consider this a special exception to * + * the GPL that we apply to Covered Software. Works which meet any of * + * these conditions must conform to all of the terms of this license, * + * particularly including the GPL Section 3 requirements of providing * + * source code and allowing free redistribution of the work as a whole. * + * * + * As another special exception to the GPL terms, Aperture Labs Ltd. grants* + * permission to link the code of this program with any version of the * + * OpenSSL library which is distributed under a license identical to that * + * listed in the included docs/licenses/OpenSSL.txt file, and distribute * + * linked combinations including the two. * + * * + * Any redistribution of Covered Software, including any derived works, * + * must obey and carry forward all of the terms of this license, including * + * obeying all GPL rules and restrictions. For example, source code of * + * the whole work must be provided and free redistribution must be * + * allowed. All GPL references to "this License", are to be treated as * + * including the terms and conditions of this license text as well. * + * * + * Because this license imposes special exceptions to the GPL, Covered * + * Work may not be combined (even as part of a larger work) with plain GPL * + * software. The terms, conditions, and exceptions of this license must * + * be included as well. This license is incompatible with some other open * + * source licenses as well. In some cases we can relicense portions of * + * RFIDler or grant special permissions to use it in other open source * + * software. Please contact sales@aperturelabs.com with any such requests.* + * Similarly, we don't incorporate incompatible open source software into * + * Covered Software without special permission from the copyright holders. * + * * + * If you have any questions about the licensing restrictions on using * + * RFIDler in other works, are happy to help. As mentioned above, we also * + * offer alternative license to integrate RFIDler into proprietary * + * applications and appliances. These contracts have been sold to dozens * + * of software vendors, and generally include a perpetual license as well * + * as providing for priority support and updates. They also fund the * + * continued development of RFIDler. Please email sales@aperturelabs.com * + * for further information. * + * If you have received a written license agreement or contract for * + * Covered Software stating terms other than these, you may choose to use * + * and redistribute Covered Software under those terms instead of these. * + * * + * Source is provided to this software because we believe users have a * + * right to know exactly what a program is going to do before they run it. * + * This also allows you to audit the software for security holes (none * + * have been found so far). * + * * + * Source code also allows you to port RFIDler to new platforms, fix bugs, * + * and add new features. You are highly encouraged to send your changes * + * to the RFIDler mailing list for possible incorporation into the * + * main distribution. By sending these changes to Aperture Labs Ltd. or * + * one of the Aperture Labs Ltd. development mailing lists, or checking * + * them into the RFIDler source code repository, it is understood (unless * + * you specify otherwise) that you are offering the RFIDler Project * + * (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, * + * modify, and relicense the code. RFIDler will always be available Open * + * Source, but this is important because the inability to relicense code * + * has caused devastating problems for other Free Software projects (such * + * as KDE and NASM). We also occasionally relicense the code to third * + * parties as discussed above. If you wish to specify special license * + * conditions of your contributions, just say so when you send them. * + * * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler * + * license file for more details (it's in a COPYING file included with * + * RFIDler, and also available from * + * https://github.com/ApertureLabsLtd/RFIDler/COPYING * + * * + ***************************************************************************/ + +// Author: unknown. +// Modifications for RFIDler: Tony Naggs , Adam Laurie + + +#ifndef HITAGCRYPTO_H +#define HITAGCRYPTO_H + +#include + +/* + Our model of Hitag 2 crypto uses 2 parallel shift registers: + a. 48 bit Feedback Shift Register, required for inputs to the nonlinear function. + b. 48 bit Linear Feedback Shift Register (LFSR). + A transform of initial register (a) value, which is then run in parallel. + Enables much faster calculation of the feedback values. + + API: + void hitag2_init(Hitag_State* pstate, uint64_t sharedkey, uint32_t serialnum, + uint32_t initvector); + Initialise state from 48 bit shared (secret) reader/tag key, + 32 bit tag serial number and 32 bit initialisation vector from reader. + + uint32_t hitag2_nstep(Hitag_State* pstate, uint32_t steps); + update shift register state and generate N cipher bits (N should be <= 32) + */ + + +typedef struct { + uint64_t shiftreg; // naive shift register, required for nonlinear fn input + uint64_t lfsr; // fast lfsr, used to make software faster +} Hitag_State; + +void hitag2_init(Hitag_State* pstate, uint64_t sharedkey, uint32_t serialnum, uint32_t initvector); + +uint32_t hitag2_nstep(Hitag_State* pstate, uint32_t steps); + +unsigned int hitag2_benchtest_gen32(); +unsigned int hitag2_benchtest(uint32_t count); +unsigned hitag2_verifytest(); + +#endif /* HITAGCRYPTO_H */ + diff --git a/tools/hitag2crack/crack2/ht2crack2buildtable.c b/tools/hitag2crack/crack2/ht2crack2buildtable.c new file mode 100644 index 000000000..402c5b245 --- /dev/null +++ b/tools/hitag2crack/crack2/ht2crack2buildtable.c @@ -0,0 +1,561 @@ +/* + * ht2crack2buildtable.c + * This builds the 1.2TB table and sorts it. + */ + +#include "ht2crack2utils.h" + + +// DATAMAX is the size of each bucket (bytes). There are 65536 buckets so choose a value such that +// DATAMAX * 65536 < RAM available. For ex, if you want to use 12GB of RAM (for a 16GB machine +// leaving some RAM free for OS and other stuff), DATAMAX = 12GB / 65536 = 196608. Round this down +// to a power of 10; DATAMAX = 196600. +#define DATAMAX 196600 // around 192K rounded down to a power of 10 + +// NUM_BUILD_THREADS and NUM_SORT_THREADS are the number of threads to run concurrently. These should +// ideally be equal to the number of virtual cores you have available. A quad-core machine will +// likely have 8 virtual cores, so set them to 8. +// +// If sorting fails with a 'bus error' then that is likely because your disk I/O can't keep up with +// the read/write demands of the multi-threaded sorting. In this case, reduce the number of sorting +// threads. This will most likely only be a problem with network disks; SATA should be okay; +// USB2/3 should keep up. +// +// These MUST be a power of 2 for the maths to work - you have been warned! +// Also, sort threads MUST be <= build threads or a horrible buffer overflow will happen! +#define NUM_BUILD_THREADS 8 +#define NUM_SORT_THREADS 8 + +// DATASIZE is the number of bytes in an entry. This is 10; 4 bytes of keystream (2 are in the filepath) + +// 6 bytes of PRNG state. +#define DATASIZE 10 + +int debug = 0; + +// table entry for a bucket +struct table { + char path[32]; + pthread_mutex_t mutex; + unsigned char *data; + unsigned char *ptr; +}; + + +// actual table +struct table *t; + +// jump table 1 +uint64_t d[48]; +int nsteps; + +// jump table 2 +uint64_t d2[48]; +int nsteps2; + +// create table entry +void create_table(struct table *t, int d1, int d2) +{ + if (!t) { + printf("create_table: t is NULL\n"); + exit(1); + } + + // create some space + t->data = (unsigned char *)malloc(DATAMAX); + if (!(t->data)) { + printf("create_table: cannot malloc data\n"); + exit(1); + } + + // set data ptr to start of data table + t->ptr = t->data; + + // init the mutex + if (pthread_mutex_init(&(t->mutex), NULL)) { + printf("create_table: cannot init mutex\n"); + exit(1); + } + + // create the path +// sprintf(t->path, "/Volumes/2tb/%02X/%02X.bin", d1 & 0xff, d2 & 0xff); + sprintf(t->path, "table/%02x/%02x.bin", d1 & 0xff, d2 & 0xff); +} + + +// create all table entries +void create_tables(struct table *t) +{ + int i, j; + + if (!t) { + printf("create_tables: t is NULL\n"); + exit(1); + } + + for (i=0; i<0x100; i++) { + for (j=0; j<0x100; j++) { + create_table(t + ((i * 0x100) + j), i, j); + } + } +} + + +// free the table memory +void free_tables(struct table *t) +{ + int i; + struct table *ttmp; + + if (!t) { + printf("free_tables: t is NULL\n"); + exit(1); + } + + for (i=0; i<0x10000; i++) { + ttmp = t + i; + free(ttmp->data); + } +} + + + +// write (partial) table to file +void writetable(struct table *t1) +{ + int fd; + + if (debug) printf("writetable %s\n", t1->path); + + fd = open(t1->path, O_WRONLY | O_CREAT | O_APPEND, 0644); + if (fd <= 0) { + printf("writetable cannot open file %s for appending\n", t1->path); + exit(1); + } + + if (debug) printf("writetable %s opened\n", t1->path); + + if (write(fd, t1->data, t1->ptr - t1->data) < (t1->ptr - t1->data)) { + printf("writetable cannot write all of the data\n"); + exit(1); + } + + if (debug) printf("writetable %s written\n", t1->path); + + close(fd); +} + + +// store value in table +void store(unsigned char *data) +{ + unsigned char d1, d2; + int offset; + struct table *t1; + + // use the first two bytes as an index + d1 = data[0]; + d2 = data[1]; + offset = (d1 * 0x100) + d2; + + if (debug) printf("store, d1=%02X, d2=%02X, offset = %d\n", d1, d2, offset); + + // get pointer to table entry + t1 = t + offset; + + // wait for a lock on this entry + if (pthread_mutex_lock(&(t1->mutex))) { + printf("store: cannot lock mutex at offset %d\n", offset); + exit(1); + } + + if (debug) printf("store, offset = %d, got lock\n", offset); + + // store the entry + memcpy(t1->ptr, data+2, 10); + + if (debug) printf("store, offset = %d, copied data\n", offset); + + // update the ptr + t1->ptr += 10; + + // check if table is full + if ((t1->ptr - t1->data) >= DATAMAX) { + // write the table to disk + writetable(t1); + // reset ptr + t1->ptr = t1->data; + } + + if (debug) printf("store, offset = %d, after possible write\n", offset); + + // release the lock + if (pthread_mutex_unlock(&(t1->mutex))) { + printf("store: cannot unlock mutex at offset %d\n", offset); + exit(1); + } + + if (debug) printf("store, offset = %d, unlocked\n", offset); + +} + +// writes the ks (keystream) and s (state) +void write_ks_s(uint32_t ks1, uint32_t ks2, uint64_t shiftreg) +{ + unsigned char buf[16]; + + // create buffer + writebuf(buf, ks1, 3); + writebuf(buf+3, ks2, 3); + writebuf(buf+6, shiftreg, 6); + + // store buffer + store(buf); + +} + + +// builds the di table for jumping +void builddi(int steps, int table) +{ + uint64_t statemask; + int i; + Hitag_State mystate; + uint64_t *thisd = NULL; + + statemask = 1; + + // select jump table + if (table == 1) { + nsteps = steps; + thisd = d; + } else if (table == 2) { + nsteps2 = steps; + thisd = d2; + } else { + printf("builddi: invalid table num\n"); + exit(1); + } + + // build di states + for (i=0; i<48; i++) { + mystate.shiftreg = statemask; + buildlfsr(&mystate); + hitag2_nstep(&mystate, steps); + thisd[i] = mystate.shiftreg; + + statemask = statemask << 1; + } +} + +// jump function - quickly jumps a load of steps +void jumpnsteps(Hitag_State *hstate, int table) +{ + uint64_t output = 0; + uint64_t bitmask; + int i; + uint64_t *thisd = NULL; + + + // select jump table + if (table == 1) { + thisd = d; + } else if (table == 2) { + thisd = d2; + } else { + printf("jumpnsteps: invalid table num\n"); + exit(1); + } + + // xor all di.si where di is a d state and si is a bit + // we do this by multiplying di by si: + // if si is 1, di.si = di; if si is 0, di.si = 0 + + bitmask = 1; + for (i=0; i<48; i++) { + if (hstate->shiftreg & bitmask) { + output = output ^ thisd[i]; + } + + bitmask = bitmask << 1; + } + + hstate->shiftreg = output; + buildlfsr(hstate); +} + + +// thread to build a part of the table +void *buildtable(void *d) +{ + Hitag_State hstate; + Hitag_State hstate2; + unsigned long i; + unsigned long maxentries = 1; + uint32_t ks1; + uint32_t ks2; + int index = (int)(long)d; + int tnum = NUM_BUILD_THREADS; + + /* set random state */ + hstate.shiftreg = 0x123456789abc; + buildlfsr(&hstate); + + /* jump to offset using jump table 2 (2048) */ + for (i=0; i> 1; + tnum = tnum >> 1; + } + + /* make the entries */ + for (i=0; iptr > t1->data) { + writetable(t1); + } + } + + // dump the memory + free_tables(t); + free(t); + + + + // now for the sorting + + + // start the threads + for (i=0; i 32)) { + printf("makerandom: len must be between 1 and 32 inclusive\n"); + exit(1); + } + + if (read(fd, raw, len) != len) { + printf("makerandom: cannot read random bytes\n"); + exit(1); + } + + for (i=0; ilen = filestat.st_size / 2; +// printf("r->len = %d\n", r->len); + + r->data = (unsigned char *)malloc(r->len); + if (!(r->data)) { + printf("cannot malloc\n"); + exit(1); + } + + j = 0; + nibble = 0; + for (i=0; (ilen); i++) { + if ((data[i] != 0x0a) && (data[i] != 0x0d) && (data[i] != 0x20)) { + if (!nibble) { + r->data[j] = hex2bin(data[i]) << 4; + nibble = 1; + } else { + r->data[j] |= hex2bin(data[i]); + nibble = 0; + j++; + } + } + } + + r->len = j; + + munmap(data, filestat.st_size); + close(fd); + + return 1; +} + +int makecand(unsigned char *c, struct rngdata *r, int bitoffset) +{ + int bytenum; + int bitnum; + int i; + + if (!c || !r || (bitoffset > ((r->len * 8) - 48))) { + printf("makecand: invalid params\n"); + return 0; + } + + bytenum = bitoffset / 8; + bitnum = bitoffset % 8; + + for (i=0; i<6; i++) { + if (!bitnum) { + c[i] = r->data[bytenum + i]; + } else { + c[i] = (r->data[bytenum + i] << bitnum) | (r->data[bytenum + i + 1] >> (8 - bitnum)); + } + } + + return 1; +} + + +// test the candidate against the next or previous rng data +int testcand(unsigned char *f, unsigned char *rt, int fwd) +{ + Hitag_State hstate; + int i; + uint32_t ks1; + uint32_t ks2; + unsigned char buf[6]; + + // build the prng state at the candidate + hstate.shiftreg = 0; + for (i=0; i<6; i++) { + hstate.shiftreg = (hstate.shiftreg << 8) | f[i+4]; + } + buildlfsr(&hstate); + + if (fwd) { + // roll forwards 48 bits + hitag2_nstep(&hstate, 48); + } else { + // roll backwards 48 bits + rollback(&hstate, 48); + buildlfsr(&hstate); + } + + // get 48 bits of RNG from the rolled to state + ks1 = hitag2_nstep(&hstate, 24); + ks2 = hitag2_nstep(&hstate, 24); + + writebuf(buf, ks1, 3); + writebuf(buf+3, ks2, 3); + + // compare them + if (!memcmp(buf, rt, 6)) { + return 1; + } else { + return 0; + } +} + +int searchcand(unsigned char *c, unsigned char *rt, int fwd, unsigned char *m, unsigned char *s) +{ + int fd; + struct stat filestat; + char file[64]; + unsigned char *data; + unsigned char item[10]; + unsigned char *found = NULL; + + + if (!c || !rt || !m || !s) { + printf("searchcand: invalid params\n"); + return 0; + } + + sprintf(file, INPUTFILE, c[0], c[1]); + + fd = open(file, O_RDONLY); + if (fd <= 0) { + printf("cannot open table file %s\n", file); + exit(1); + } + + if (fstat(fd, &filestat)) { + printf("cannot stat file %s\n", file); + exit(1); + } + + data = mmap((caddr_t)0, filestat.st_size, PROT_READ, MAP_PRIVATE, fd, 0); + if (data == MAP_FAILED) { + printf("cannot mmap file %s\n", file); + exit(1); + } + + memcpy(item, c+2, 4); + + found = (unsigned char *)bsearch(item, data, filestat.st_size / DATASIZE, DATASIZE, datacmp); + + if (found) { + + // our candidate is in the table + // go backwards and see if there are other matches + while (((found - data) >= DATASIZE) && (!memcmp(found - DATASIZE, item, 4))) { + found = found - DATASIZE; + } + + // now test all matches + while (((found - data) <= (filestat.st_size - DATASIZE)) && (!memcmp(found, item, 4))) { + if (testcand(found, rt, fwd)) { + memcpy(m, c, 2); + memcpy(m+2, found, 4); + memcpy(s, found+4, 6); + + munmap(data, filestat.st_size); + close(fd); + return 1; + } + + found = found + DATASIZE; + } + } + + munmap(data, filestat.st_size); + close(fd); + + return 0; + +} + +int findmatch(struct rngdata *r, unsigned char *outmatch, unsigned char *outstate, int *bitoffset) +{ + int i; + int bitlen; + unsigned char cand[6]; + unsigned char rngtest[6]; + int fwd; + + if (!r || !outmatch || !outstate || !bitoffset) { + printf("findmatch: invalid params\n"); + return 0; + } + + bitlen = r->len * 8; + + for (i=0; i<=bitlen - 48; i++) { + // print progress + if ((i % 100) == 0) { + printf("searching on bit %d\n", i); + } + + if (!makecand(cand, r, i)) { + printf("cannot makecand, %d\n", i); + return 0; + } +// printf("cand: %02x %02x %02x %02x %02x %02x : ", cand[0], cand[1], cand[2], cand[3], cand[4], cand[5]); +// printbin(cand); + + /* make following or preceding RNG test data to confirm match */ + if (i < (bitlen - 96)) { + if (!makecand(rngtest, r, i + 48)) { + printf("cannot makecand rngtest %d + 48\n", i); + return 0; + } + fwd = 1; + } else { + if (!makecand(rngtest, r, i - 48)) { + printf("cannot makecand rngtest %d - 48\n", i); + return 0; + } + fwd = 0; + } + + if (searchcand(cand, rngtest, fwd, outmatch, outstate)) { + *bitoffset = i; + return 1; + } + } + + return 0; +} + + + + +void rollbackrng(Hitag_State *hstate, unsigned char *s, int offset) +{ + int i; + + if (!s) { + printf("rollbackrng: invalid params\n"); + return; + } + + // build prng at recovered offset + hstate->shiftreg = 0; + for (i=0; i<6; i++) { + hstate->shiftreg = (hstate->shiftreg << 8) | s[i]; + } + + printf("recovered prng state at offset %d:\n", offset); + printstate(hstate); + + // rollback to state after auth + rollback(hstate, offset); + + // rollback through auth (aR, p3) + rollback(hstate, 64); + + printf("prng state after initialisation:\n"); + printstate(hstate); + + +} + +uint64_t recoverkey(Hitag_State *hstate, char *uidstr, char *nRstr) +{ + uint64_t key; + uint64_t keyupper; + uint32_t uid; + uint32_t uidtmp; + uint32_t nRenc; + uint32_t nR; + uint32_t nRxork; + uint32_t b = 0; + int i; + + // key lower 16 bits are lower 16 bits of prng state + key = hstate->shiftreg & 0xffff; + nRxork = (hstate->shiftreg >> 16) & 0xffffffff; + uid = rev32(hexreversetoulong(uidstr)); + nRenc = rev32(hexreversetoulong(nRstr)); + + uidtmp = uid; + // rollback and extract bits b + for (i=0; i<32; i++) { + hstate->shiftreg = ((hstate->shiftreg) << 1) | ((uidtmp >> 31) & 0x1); + uidtmp = uidtmp << 1; + b = (b << 1) | fnf(hstate->shiftreg); + } + + printf("end state:\n"); + printstate(hstate); + printf("b:\t\t"); + printbin2(b, 32); + printf("\n"); + printf("nRenc:\t\t"); + printbin2(nRenc, 32); + printf("\n"); + + nR = nRenc ^ b; + + printf("nR:\t\t"); + printbin2(nR, 32); + printf("\n"); + + keyupper = nRxork ^ nR; + key = key | (keyupper << 16); + printf("key:\t\t"); + printbin2(key, 48); + printf("\n"); + + return key; +} + + +int main(int argc, char *argv[]) +{ + Hitag_State hstate; + struct rngdata rng; + int bitoffset = 0; + unsigned char rngmatch[6]; + unsigned char rngstate[6]; + char *uidstr; + char *nRstr; + uint64_t keyrev; + uint64_t key; + int i; + + if (argc < 4) { + printf("ht2crack2search rngdatafile UID nR\n"); + exit(1); + } + + if (!loadrngdata(&rng, argv[1])) { + printf("loadrngdata failed\n"); + exit(1); + } + + if (!strncmp(argv[2], "0x", 2)) { + uidstr = argv[2] + 2; + } else { + uidstr = argv[2]; + } + + if (!strncmp(argv[3], "0x", 2)) { + nRstr = argv[3] + 2; + } else { + nRstr = argv[3]; + } + + + if (!findmatch(&rng, rngmatch, rngstate, &bitoffset)) { + printf("couldn't find a match\n"); + exit(1); + } + + printf("found match:\n"); + printf("rngmatch = %02x %02x %02x %02x %02x %02x\n", rngmatch[0], rngmatch[1], rngmatch[2], rngmatch[3], rngmatch[4], rngmatch[5]); + printf("rngstate = %02x %02x %02x %02x %02x %02x\n", rngstate[0], rngstate[1], rngstate[2], rngstate[3], rngstate[4], rngstate[5]); + printf("bitoffset = %d\n", bitoffset); + + rollbackrng(&hstate, rngstate, bitoffset); + + keyrev = recoverkey(&hstate, uidstr, nRstr); + key = rev64(keyrev); + + printf("keyrev:\t\t"); + printbin2(key, 48); + printf("\n"); + + printf("KEY:\t\t"); + for (i=0; i<6; i++) { + printf("%02X", (int)(key & 0xff)); + key = key >> 8; + } + printf("\n"); + + return 0; + +} + + diff --git a/tools/hitag2crack/crack2/ht2crack2utils.c b/tools/hitag2crack/crack2/ht2crack2utils.c new file mode 100644 index 000000000..2152f8ef3 --- /dev/null +++ b/tools/hitag2crack/crack2/ht2crack2utils.c @@ -0,0 +1,187 @@ +#include "ht2crack2utils.h" + +// writes a value into a buffer as a series of bytes +void writebuf(unsigned char *buf, uint64_t val, unsigned int len) +{ + int i; + char c; + + for (i=len-1; i>=0; i--) + { + c = val & 0xff; + buf[i] = c; + val = val >> 8; + } + +} + + +/* simple hexdump for testing purposes */ +void shexdump(unsigned char *data, int data_len) +{ + int i; + + if (!data || (data_len <= 0)) { + printf("shexdump: invalid parameters\n"); + return; + } + + printf("Hexdump from %p:\n", data); + + for (i=0; i> 7); + x = x << 1; + } + } + printf("\n"); +} + + +void printbin2(uint64_t val, unsigned int size) +{ + int i; + uint64_t mask = 1; + + mask = mask << (size - 1); + + for (i=0; ishiftreg, 48); + printf("\n"); +} + + + + +// convert hex char to binary +unsigned char hex2bin(unsigned char c) +{ + if ((c >= '0') && (c <= '9')) { + return (c - '0'); + } else if ((c >= 'a') && (c <= 'f')) { + return (c - 'a' + 10); + } else if ((c >= 'A') && (c <= 'F')) { + return (c - 'A' + 10); + } else { + return 0; + } +} + +// return a single bit from a value +int bitn(uint64_t x, int bit) +{ + uint64_t bitmask = 1; + + bitmask = bitmask << bit; + + if (x & bitmask) { + return 1; + } else { + return 0; + } +} + + +// the sub-function R that rollback depends upon +int fnR(uint64_t x) +{ + // renumbered bits because my state is 0-47, not 1-48 + return (bitn(x, 1) ^ bitn(x, 2) ^ bitn(x, 5) ^ bitn(x, 6) ^ bitn(x, 7) ^ + bitn(x, 15) ^ bitn(x, 21) ^ bitn(x, 22) ^ bitn(x, 25) ^ bitn(x, 29) ^ bitn(x, 40) ^ + bitn(x, 41) ^ bitn(x, 42) ^ bitn(x, 45) ^ bitn(x, 46) ^ bitn(x, 47)); +} + +// the rollback function that lets us go backwards in time +void rollback(Hitag_State *hstate, unsigned int steps) +{ + int i; + + for (i=0; ishiftreg = ((hstate->shiftreg << 1) & 0xffffffffffff) | fnR(hstate->shiftreg); + } + +} + + +// the three filter sub-functions that feed fnf +int fa(unsigned int i) +{ + return bitn(0x2C79, i); +} + +int fb(unsigned int i) +{ + return bitn(0x6671, i); +} + +int fc(unsigned int i) +{ + return bitn(0x7907287B, i); +} + +// the filter function that generates a bit of output from the prng state +int fnf(uint64_t s) +{ + unsigned int x1, x2, x3, x4, x5, x6; + + x1 = (bitn(s, 2) << 0) | (bitn(s, 3) << 1) | (bitn(s, 5) << 2) | (bitn(s, 6) << 3); + x2 = (bitn(s, 8) << 0) | (bitn(s, 12) << 1) | (bitn(s, 14) << 2) | (bitn(s, 15) << 3); + x3 = (bitn(s, 17) << 0) | (bitn(s, 21) << 1) | (bitn(s, 23) << 2) | (bitn(s, 26) << 3); + x4 = (bitn(s, 28) << 0) | (bitn(s, 29) << 1) | (bitn(s, 31) << 2) | (bitn(s, 33) << 3); + x5 = (bitn(s, 34) << 0) | (bitn(s, 43) << 1) | (bitn(s, 44) << 2) | (bitn(s, 46) << 3); + + x6 = (fa(x1) << 0) | (fb(x2) << 1) | (fb(x3) << 2) | (fb(x4) << 3) | (fa(x5) << 4); + + return fc(x6); +} + +// builds the lfsr for the prng (quick calcs for hitag2_nstep()) +void buildlfsr(Hitag_State *hstate) +{ + uint64_t state = hstate->shiftreg; + uint64_t temp; + + temp = state ^ (state >> 1); + hstate->lfsr = state ^ (state >> 6) ^ (state >> 16) + ^ (state >> 26) ^ (state >> 30) ^ (state >> 41) + ^ (temp >> 2) ^ (temp >> 7) ^ (temp >> 22) + ^ (temp >> 42) ^ (temp >> 46); +} + + + diff --git a/tools/hitag2crack/crack2/ht2crack2utils.h b/tools/hitag2crack/crack2/ht2crack2utils.h new file mode 100644 index 000000000..14eea840c --- /dev/null +++ b/tools/hitag2crack/crack2/ht2crack2utils.h @@ -0,0 +1,34 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "HardwareProfile.h" +#include "rfidler.h" +#include "util.h" + +#include "hitagcrypto.h" + +#define HEX_PER_ROW 16 + + + +void writebuf(unsigned char *buf, uint64_t val, unsigned int len); +void shexdump(unsigned char *data, int data_len); +void printbin(unsigned char *c); +void printbin2(uint64_t val, unsigned int size); +void printstate(Hitag_State *hstate); +unsigned char hex2bin(unsigned char c); +int bitn(uint64_t x, int bit); +int fnR(uint64_t x); +void rollback(Hitag_State *hstate, unsigned int steps); +int fa(unsigned int i); +int fb(unsigned int i); +int fc(unsigned int i); +int fnf(uint64_t s); +void buildlfsr(Hitag_State *hstate); diff --git a/tools/hitag2crack/crack2/readme.md b/tools/hitag2crack/crack2/readme.md new file mode 100644 index 000000000..dd0872260 --- /dev/null +++ b/tools/hitag2crack/crack2/readme.md @@ -0,0 +1,68 @@ +ht2crack2 suite + + + +Build +----- + +Edit ht2crack2buildtable.c and set the DATAMAX, NUM_BUILD_THREADS and NUM_SORT_THREADS values. +These are important if you want it to run quickly. Ideally set DATAMAX to the largest value +that you can get away with and set NUM_BUILD_THREADS and NUM_SORT_THREADS to the number of +virtual cores you have available, which MUST be a power of 2. NUM_BUILD_THREADS MUST be >= +NUM_SORT_THREADS. + +Calculate DATAMAX = free RAM available / 65536, and then round down to a power of 10. + +The Makefile is configured for linux. To compile on Mac, edit it and swap the LIBS= lines. + +make clean +make + + +Run ht2crack2buildtable +----------------------- + +Make sure you are in a directory on a disk with at least 1.5TB of space. +./ht2crack2buildtable + +Wait a very long time. Maybe a few days. + +This will create a directory tree called table/ while it is working that will contain +files that will slowly build up in size to approx 20MB each. Once it has finished making +these unsorted files, it will sort them into the directory tree sorted/ and remove the +original files. It will then exit and you'll have your shiny table. + + +Test with ht2crack2gentests +--------------------------- + +./ht2crack2gentests NUMBER_OF_TESTS + +to generate NUMBER_OF_TESTS test files. These will all be named +keystream.key-KEYVALUE.uid-UIDVALUE.nR-NRVALUE + +Test a single test with +./runtest.sh KEYSTREAMFILE + +or manually with +./ht2crack2search KEYSTREAMFILE UIDVALUE NRVALUE + +or run all tests with +./runalltests.sh + +Feel free to edit the shell scripts to find your tools. You might want to create a +symbolic link to your sorted/ directory called 'sorted' to help ht2crack2seach find the +table. + +If the tests work, then the table is sound. + + +Search for key in real keystream +-------------------------------- + +Recover 2048 bits of keystream from the target RFID tag with the RFIDler. You will have had +to supply an NR value and you should know the tag's UID (you can get this using the RFIDler). + +./ht2crack2search KEYSTREAMFILE UIDVALUE NRVALUE + + diff --git a/tools/hitag2crack/crack2/rfidler.h b/tools/hitag2crack/crack2/rfidler.h new file mode 100644 index 000000000..c8ce90396 --- /dev/null +++ b/tools/hitag2crack/crack2/rfidler.h @@ -0,0 +1,412 @@ +/*************************************************************************** + * A copy of the GNU GPL is appended to this file. * + * * + * This licence is based on the nmap licence, and we express our gratitude * + * for the work that went into producing it. There is no other connection * + * between RFIDler and nmap either expressed or implied. * + * * + ********************** IMPORTANT RFIDler LICENSE TERMS ******************** + * * + * * + * All references to RFIDler herein imply all it's derivatives, namely: * + * * + * o RFIDler-LF Standard * + * o RFIDler-LF Lite * + * o RFIDler-LF Nekkid * + * * + * * + * RFIDler is (C) 2013-2015 Aperture Labs Ltd. * + * * + * This program is free software; you may redistribute and/or modify it * + * under the terms of the GNU General Public License as published by the * + * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE * + * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your * + * right to use, modify, and redistribute this software under certain * + * conditions. If you wish to embed RFIDler technology into proprietary * + * software or hardware, we sell alternative licenses * + * (contact sales@aperturelabs.com). * + * * + * Note that the GPL places important restrictions on "derivative works", * + * yet it does not provide a detailed definition of that term. To avoid * + * misunderstandings, we interpret that term as broadly as copyright law * + * allows. For example, we consider an application to constitute a * + * derivative work for the purpose of this license if it does any of the * + * following with any software or content covered by this license * + * ("Covered Software"): * + * * + * o Integrates source code from Covered Software. * + * * + * o Is designed specifically to execute Covered Software and parse the * + * results (as opposed to typical shell or execution-menu apps, which will * + * execute anything you tell them to). * + * * + * o Includes Covered Software in a proprietary executable installer. The * + * installers produced by InstallShield are an example of this. Including * + * RFIDler with other software in compressed or archival form does not * + * trigger this provision, provided appropriate open source decompression * + * or de-archiving software is widely available for no charge. For the * + * purposes of this license, an installer is considered to include Covered * + * Software even if it actually retrieves a copy of Covered Software from * + * another source during runtime (such as by downloading it from the * + * Internet). * + * * + * o Links (statically or dynamically) to a library which does any of the * + * above. * + * * + * o Executes a helper program, module, or script to do any of the above. * + * * + * This list is not exclusive, but is meant to clarify our interpretation * + * of derived works with some common examples. Other people may interpret * + * the plain GPL differently, so we consider this a special exception to * + * the GPL that we apply to Covered Software. Works which meet any of * + * these conditions must conform to all of the terms of this license, * + * particularly including the GPL Section 3 requirements of providing * + * source code and allowing free redistribution of the work as a whole. * + * * + * As another special exception to the GPL terms, Aperture Labs Ltd. grants* + * permission to link the code of this program with any version of the * + * OpenSSL library which is distributed under a license identical to that * + * listed in the included docs/licenses/OpenSSL.txt file, and distribute * + * linked combinations including the two. * + * * + * Any redistribution of Covered Software, including any derived works, * + * must obey and carry forward all of the terms of this license, including * + * obeying all GPL rules and restrictions. For example, source code of * + * the whole work must be provided and free redistribution must be * + * allowed. All GPL references to "this License", are to be treated as * + * including the terms and conditions of this license text as well. * + * * + * Because this license imposes special exceptions to the GPL, Covered * + * Work may not be combined (even as part of a larger work) with plain GPL * + * software. The terms, conditions, and exceptions of this license must * + * be included as well. This license is incompatible with some other open * + * source licenses as well. In some cases we can relicense portions of * + * RFIDler or grant special permissions to use it in other open source * + * software. Please contact sales@aperturelabs.com with any such requests.* + * Similarly, we don't incorporate incompatible open source software into * + * Covered Software without special permission from the copyright holders. * + * * + * If you have any questions about the licensing restrictions on using * + * RFIDler in other works, are happy to help. As mentioned above, we also * + * offer alternative license to integrate RFIDler into proprietary * + * applications and appliances. These contracts have been sold to dozens * + * of software vendors, and generally include a perpetual license as well * + * as providing for priority support and updates. They also fund the * + * continued development of RFIDler. Please email sales@aperturelabs.com * + * for further information. * + * If you have received a written license agreement or contract for * + * Covered Software stating terms other than these, you may choose to use * + * and redistribute Covered Software under those terms instead of these. * + * * + * Source is provided to this software because we believe users have a * + * right to know exactly what a program is going to do before they run it. * + * This also allows you to audit the software for security holes (none * + * have been found so far). * + * * + * Source code also allows you to port RFIDler to new platforms, fix bugs, * + * and add new features. You are highly encouraged to send your changes * + * to the RFIDler mailing list for possible incorporation into the * + * main distribution. By sending these changes to Aperture Labs Ltd. or * + * one of the Aperture Labs Ltd. development mailing lists, or checking * + * them into the RFIDler source code repository, it is understood (unless * + * you specify otherwise) that you are offering the RFIDler Project * + * (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, * + * modify, and relicense the code. RFIDler will always be available Open * + * Source, but this is important because the inability to relicense code * + * has caused devastating problems for other Free Software projects (such * + * as KDE and NASM). We also occasionally relicense the code to third * + * parties as discussed above. If you wish to specify special license * + * conditions of your contributions, just say so when you send them. * + * * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler * + * license file for more details (it's in a COPYING file included with * + * RFIDler, and also available from * + * https://github.com/ApertureLabsLtd/RFIDler/COPYING * + * * + ***************************************************************************/ + +// Author: Adam Laurie + +#include +#include + +// BCD hardware revision for usb descriptor (usb_descriptors.c) +#define RFIDLER_HW_VERSION 0x020 + +// max sizes in BITS +#define MAXBLOCKSIZE 512 +#define MAXTAGSIZE 4096 +#define MAXUID 512 + +#define TMP_LARGE_BUFF_LEN 2048 +#define TMP_SMALL_BUFF_LEN 256 +#define ANALOGUE_BUFF_LEN 8192 + +#define COMMS_BUFFER_SIZE 128 + +#define DETECT_BUFFER_SIZE 512 + +#define SAMPLEMASK ~(BIT_1 | BIT_0) // mask to remove two bottom bits from analogue sample - we will then use those for reader & bit period + +// globals + +extern BOOL WiegandOutput; // Output wiegand data whenenver UID is read +extern BYTE *EMU_Reset_Data; // Pointer to full array of bits as bytes, stored as 0x00/0x01, '*' terminated +extern BYTE *EMU_Data; // Pointer to current location in EMU_Reset_Data +extern BYTE EMU_ThisBit; // The next data bit to transmit +extern BYTE EMU_SubCarrier_T0; // Number of Frame Clocks for sub-carrier '0' +extern BYTE EMU_SubCarrier_T1; // Number of Frame Clocks for sub-carrier '1' +extern unsigned int EMU_Repeat; // Number of times to transmit full data set +extern BOOL EMU_Background; // Emulate in the background until told to stop +extern unsigned int EMU_DataBitRate; // Number of Frame Clocks per bit +extern BYTE TmpBits[TMP_LARGE_BUFF_LEN]; // Shared scratchpad +extern BYTE ReaderPeriod; // Flag for sample display +extern unsigned char Comms_In_Buffer[COMMS_BUFFER_SIZE]; // USB/Serial buffer +extern BYTE Interface; // user interface - CLI or API +extern BYTE CommsChannel; // user comms channel - USB or UART +extern BOOL FakeRead; // flag for analogue sampler to signal it wants access to buffers during read +extern BOOL PWD_Mode; // is this tag password protected? +extern BYTE Password[9]; // 32 bits as HEX string set with LOGIN +extern unsigned int Led_Count; // LED status counter, also used for entropy +extern unsigned long Reader_Bit_Count; // Reader ISR bit counter +extern char Previous; // Reader ISR previous bit type + +// RWD (read/write device) coil state +extern BYTE RWD_State; // current state of RWD coil +extern unsigned int RWD_Fc; // field clock in uS +extern unsigned int RWD_Gap_Period; // length of command gaps in OC5 ticks +extern unsigned int RWD_Zero_Period; // length of '0' in OC5 ticks +extern unsigned int RWD_One_Period; // length of '1' in OC5 ticks +extern unsigned int RWD_Sleep_Period; // length of initial sleep to reset tag in OC5 ticks +extern unsigned int RWD_Wake_Period; // length required for tag to restart in OC5 ticks +extern unsigned int RWD_Wait_Switch_TX_RX; // length to wait when switching from TX to RX in OC5 ticks +extern unsigned int RWD_Wait_Switch_RX_TX; // length to wait when switching from RX to TX in OC5 ticks +extern unsigned int RWD_Post_Wait; // low level ISR wait period in OC5 ticks +extern unsigned int RWD_OC5_config; // Output Compare Module settings +extern unsigned int RWD_OC5_r; // Output Compare Module primary compare value +extern unsigned int RWD_OC5_rs; // Output Compare Module secondary compare value +extern BYTE RWD_Command_Buff[TMP_SMALL_BUFF_LEN]; // Command buffer, array of bits as bytes, stored as 0x00/0x01, '*' terminated +extern BYTE *RWD_Command_ThisBit; // Current command bit +extern BOOL Reader_ISR_State; // current state of reader ISR + +// NVM variables +// timings etc. that want to survive a reboot should go here +typedef struct { + BYTE Name[7]; // will be set to "RFIDler" so we can test for new device + BYTE AutoRun[128]; // optional command to run at startup + unsigned char TagType; + unsigned int PSK_Quality; + unsigned int Timeout; + unsigned int Wiegand_Pulse; + unsigned int Wiegand_Gap; + BOOL Wiegand_IdleState; + unsigned int FrameClock; + unsigned char Modulation; + unsigned int DataRate; + unsigned int DataRateSub0; + unsigned int DataRateSub1; + unsigned int DataBits; + unsigned int DataBlocks; + unsigned int BlockSize; + unsigned char SyncBits; + BYTE Sync[4]; + BOOL BiPhase; + BOOL Invert; + BOOL Manchester; + BOOL HalfDuplex; + unsigned int Repeat; + unsigned int PotLow; + unsigned int PotHigh; + unsigned int RWD_Gap_Period; + unsigned int RWD_Zero_Period; + unsigned int RWD_One_Period; + unsigned int RWD_Sleep_Period; + unsigned int RWD_Wake_Period; + unsigned int RWD_Wait_Switch_TX_RX; + unsigned int RWD_Wait_Switch_RX_TX; +} StoredConfig; + +// somewhere to store TAG data. this will be interpreted according to the TAG +// type. +typedef struct { + BYTE TagType; // raw tag type + BYTE EmulatedTagType; // tag type this tag is configured to emulate + BYTE UID[MAXUID + 1]; // Null-terminated HEX string + BYTE Data[MAXTAGSIZE]; // raw data + unsigned char DataBlocks; // number of blocks in Data field + unsigned int BlockSize; // blocksize in bits +} VirtualTag; + +extern StoredConfig RFIDlerConfig; +extern VirtualTag RFIDlerVTag; +extern BYTE TmpBuff[NVM_PAGE_SIZE]; +extern BYTE DataBuff[ANALOGUE_BUFF_LEN]; +extern unsigned int DataBuffCount; +extern const BYTE *ModulationSchemes[]; +extern const BYTE *OnOff[]; +extern const BYTE *HighLow[]; +extern const BYTE *TagTypes[]; + +// globals for ISRs +extern BYTE EmulationMode; +extern unsigned long HW_Bits; +extern BYTE HW_Skip_Bits; +extern unsigned int PSK_Min_Pulse; +extern BOOL PSK_Read_Error; +extern BOOL Manchester_Error; +extern BOOL SnifferMode; +extern unsigned int Clock_Tick_Counter; +extern BOOL Clock_Tick_Counter_Reset; + +// smart card lib +#define MAX_ATR_LEN (BYTE)33 +extern BYTE scCardATR[MAX_ATR_LEN]; +extern BYTE scATRLength; + +// RTC +extern rtccTime RTC_time; // time structure +extern rtccDate RTC_date; // date structure + +// digital pots +#define POTLOW_DEFAULT 100 +#define POTHIGH_DEFAULT 150 +#define DC_OFFSET 60 // analogue circuit DC offset (as close as we can get without using 2 LSB) +#define VOLTS_TO_POT 0.019607843F + +// RWD/clock states +#define RWD_STATE_INACTIVE 0 // RWD not in use +#define RWD_STATE_GO_TO_SLEEP 1 // RWD coil shutdown request +#define RWD_STATE_SLEEPING 2 // RWD coil shutdown for sleep period +#define RWD_STATE_WAKING 3 // RWD active for pre-determined period after reset +#define RWD_STATE_START_SEND 4 // RWD starting send of data +#define RWD_STATE_SENDING_GAP 5 // RWD sending a gap +#define RWD_STATE_SENDING_BIT 6 // RWD sending a data bit +#define RWD_STATE_POST_WAIT 7 // RWD finished sending data, now in forced wait period +#define RWD_STATE_ACTIVE 8 // RWD finished, now just clocking a carrier + +// reader ISR states +#define READER_STOPPED 0 // reader not in use +#define READER_IDLING 1 // reader ISR running to preserve timing, but not reading +#define READER_RUNNING 2 // reader reading bits + + +// user interface types +#define INTERFACE_API 0 +#define INTERFACE_CLI 1 + +// comms channel +#define COMMS_NONE 0 +#define COMMS_USB 1 +#define COMMS_UART 2 + +#define MAX_HISTORY 2 // disable most of history for now - memory issue + +// tag write retries +#define TAG_WRITE_RETRY 5 + +// modulation modes - uppdate ModulationSchemes[] in tags.c if you change this +#define MOD_MODE_NONE 0 +#define MOD_MODE_ASK_OOK 1 +#define MOD_MODE_FSK1 2 +#define MOD_MODE_FSK2 3 +#define MOD_MODE_PSK1 4 +#define MOD_MODE_PSK2 5 +#define MOD_MODE_PSK3 6 + +// TAG types - update TagTypes[] in tags.c if you add to this list +#define TAG_TYPE_NONE 0 +#define TAG_TYPE_ASK_RAW 1 +#define TAG_TYPE_FSK1_RAW 2 +#define TAG_TYPE_FSK2_RAW 3 +#define TAG_TYPE_PSK1_RAW 4 +#define TAG_TYPE_PSK2_RAW 5 +#define TAG_TYPE_PSK3_RAW 6 +#define TAG_TYPE_HITAG1 7 +#define TAG_TYPE_HITAG2 8 +#define TAG_TYPE_EM4X02 9 +#define TAG_TYPE_Q5 10 +#define TAG_TYPE_HID_26 11 +#define TAG_TYPE_INDALA_64 12 +#define TAG_TYPE_INDALA_224 13 +#define TAG_TYPE_UNIQUE 14 +#define TAG_TYPE_FDXB 15 +#define TAG_TYPE_T55X7 16 // same as Q5 but different timings and no modulation-defeat +#define TAG_TYPE_AWID_26 17 +#define TAG_TYPE_EM4X05 18 +#define TAG_TYPE_TAMAGOTCHI 19 +#define TAG_TYPE_HDX 20 // same underlying data as FDX-B, but different modulation & telegram + +// various + +#define BINARY 0 +#define HEX 1 + +#define NO_ADDRESS -1 + +#define ACK TRUE +#define NO_ACK FALSE + +#define BLOCK TRUE +#define NO_BLOCK FALSE + +#define DATA TRUE +#define NO_DATA FALSE + +#define DEBUG_PIN_ON HIGH +#define DEBUG_PIN_OFF LOW + +#define FAST FALSE +#define SLOW TRUE + +#define NO_TRIGGER 0 + +#define LOCK TRUE +#define NO_LOCK FALSE + +#define NFC_MODE TRUE +#define NO_NFC_MODE FALSE + +#define ONESHOT_READ TRUE +#define NO_ONESHOT_READ FALSE + +#define RESET TRUE +#define NO_RESET FALSE + +#define SHUTDOWN_CLOCK TRUE +#define NO_SHUTDOWN_CLOCK FALSE + +#define SYNC TRUE +#define NO_SYNC FALSE + +#define VERIFY TRUE +#define NO_VERIFY FALSE + +#define VOLATILE FALSE +#define NON_VOLATILE TRUE + +#define NEWLINE TRUE +#define NO_NEWLINE FALSE + +#define WAIT TRUE +#define NO_WAIT FALSE + +#define WIPER_HIGH 0 +#define WIPER_LOW 1 + +// conversion for time to ticks +#define US_TO_TICKS 1000000L +#define US_OVER_10_TO_TICKS 10000000L +#define US_OVER_100_TO_TICKS 100000000L +// we can't get down to this level on pic, but we want to standardise on timings, so for now we fudge it +#define CONVERT_TO_TICKS(x) ((x / 10) * (GetSystemClock() / US_OVER_10_TO_TICKS)) +#define CONVERT_TICKS_TO_US(x) (x / (GetSystemClock() / US_TO_TICKS)) +#define TIMER5_PRESCALER 16 +#define MAX_TIMER5_TICKS (65535 * TIMER5_PRESCALER) + +// other conversions + +// bits to hex digits +#define HEXDIGITS(x) (x / 4) +#define HEXTOBITS(x) (x * 4) diff --git a/tools/hitag2crack/crack2/runalltests.sh b/tools/hitag2crack/crack2/runalltests.sh new file mode 100755 index 000000000..945873cfb --- /dev/null +++ b/tools/hitag2crack/crack2/runalltests.sh @@ -0,0 +1,3 @@ +for i in keystream*; do +./runtest.sh $i +done diff --git a/tools/hitag2crack/crack2/runtest.sh b/tools/hitag2crack/crack2/runtest.sh new file mode 100755 index 000000000..bcc08727c --- /dev/null +++ b/tools/hitag2crack/crack2/runtest.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +if [ "$1" == "" ]; then +echo "runtest.sh testfile" +echo "testfile name should be of the form:" +echo "keystream.key-KEY.uid-UID.nR-NR" +exit 1 +fi + +filename=$1 + +UIDV=`echo $1 | cut -d'-' -f3 | cut -d'.' -f1` +NR=`echo $1 | cut -d'-' -f4` +KEYV=`echo $1 | cut -d'-' -f2 | cut -d'.' -f1` + +echo "********************" +echo "FILENAME = $filename" +echo "UID = $UIDV" +echo "NR = $NR" +echo "Expected KEY = $KEYV" + +./ht2crack2search $filename $UIDV $NR +echo "Expected KEY = $KEYV" +echo "********************" +echo "" diff --git a/tools/hitag2crack/crack2/util.h b/tools/hitag2crack/crack2/util.h new file mode 100644 index 000000000..c0d4c156a --- /dev/null +++ b/tools/hitag2crack/crack2/util.h @@ -0,0 +1,206 @@ +/*************************************************************************** + * A copy of the GNU GPL is appended to this file. * + * * + * This licence is based on the nmap licence, and we express our gratitude * + * for the work that went into producing it. There is no other connection * + * between RFIDler and nmap either expressed or implied. * + * * + ********************** IMPORTANT RFIDler LICENSE TERMS ******************** + * * + * * + * All references to RFIDler herein imply all it's derivatives, namely: * + * * + * o RFIDler-LF Standard * + * o RFIDler-LF Lite * + * o RFIDler-LF Nekkid * + * * + * * + * RFIDler is (C) 2013-2015 Aperture Labs Ltd. * + * * + * This program is free software; you may redistribute and/or modify it * + * under the terms of the GNU General Public License as published by the * + * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE * + * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your * + * right to use, modify, and redistribute this software under certain * + * conditions. If you wish to embed RFIDler technology into proprietary * + * software or hardware, we sell alternative licenses * + * (contact sales@aperturelabs.com). * + * * + * Note that the GPL places important restrictions on "derivative works", * + * yet it does not provide a detailed definition of that term. To avoid * + * misunderstandings, we interpret that term as broadly as copyright law * + * allows. For example, we consider an application to constitute a * + * derivative work for the purpose of this license if it does any of the * + * following with any software or content covered by this license * + * ("Covered Software"): * + * * + * o Integrates source code from Covered Software. * + * * + * o Is designed specifically to execute Covered Software and parse the * + * results (as opposed to typical shell or execution-menu apps, which will * + * execute anything you tell them to). * + * * + * o Includes Covered Software in a proprietary executable installer. The * + * installers produced by InstallShield are an example of this. Including * + * RFIDler with other software in compressed or archival form does not * + * trigger this provision, provided appropriate open source decompression * + * or de-archiving software is widely available for no charge. For the * + * purposes of this license, an installer is considered to include Covered * + * Software even if it actually retrieves a copy of Covered Software from * + * another source during runtime (such as by downloading it from the * + * Internet). * + * * + * o Links (statically or dynamically) to a library which does any of the * + * above. * + * * + * o Executes a helper program, module, or script to do any of the above. * + * * + * This list is not exclusive, but is meant to clarify our interpretation * + * of derived works with some common examples. Other people may interpret * + * the plain GPL differently, so we consider this a special exception to * + * the GPL that we apply to Covered Software. Works which meet any of * + * these conditions must conform to all of the terms of this license, * + * particularly including the GPL Section 3 requirements of providing * + * source code and allowing free redistribution of the work as a whole. * + * * + * As another special exception to the GPL terms, Aperture Labs Ltd. grants* + * permission to link the code of this program with any version of the * + * OpenSSL library which is distributed under a license identical to that * + * listed in the included docs/licenses/OpenSSL.txt file, and distribute * + * linked combinations including the two. * + * * + * Any redistribution of Covered Software, including any derived works, * + * must obey and carry forward all of the terms of this license, including * + * obeying all GPL rules and restrictions. For example, source code of * + * the whole work must be provided and free redistribution must be * + * allowed. All GPL references to "this License", are to be treated as * + * including the terms and conditions of this license text as well. * + * * + * Because this license imposes special exceptions to the GPL, Covered * + * Work may not be combined (even as part of a larger work) with plain GPL * + * software. The terms, conditions, and exceptions of this license must * + * be included as well. This license is incompatible with some other open * + * source licenses as well. In some cases we can relicense portions of * + * RFIDler or grant special permissions to use it in other open source * + * software. Please contact sales@aperturelabs.com with any such requests.* + * Similarly, we don't incorporate incompatible open source software into * + * Covered Software without special permission from the copyright holders. * + * * + * If you have any questions about the licensing restrictions on using * + * RFIDler in other works, are happy to help. As mentioned above, we also * + * offer alternative license to integrate RFIDler into proprietary * + * applications and appliances. These contracts have been sold to dozens * + * of software vendors, and generally include a perpetual license as well * + * as providing for priority support and updates. They also fund the * + * continued development of RFIDler. Please email sales@aperturelabs.com * + * for further information. * + * If you have received a written license agreement or contract for * + * Covered Software stating terms other than these, you may choose to use * + * and redistribute Covered Software under those terms instead of these. * + * * + * Source is provided to this software because we believe users have a * + * right to know exactly what a program is going to do before they run it. * + * This also allows you to audit the software for security holes (none * + * have been found so far). * + * * + * Source code also allows you to port RFIDler to new platforms, fix bugs, * + * and add new features. You are highly encouraged to send your changes * + * to the RFIDler mailing list for possible incorporation into the * + * main distribution. By sending these changes to Aperture Labs Ltd. or * + * one of the Aperture Labs Ltd. development mailing lists, or checking * + * them into the RFIDler source code repository, it is understood (unless * + * you specify otherwise) that you are offering the RFIDler Project * + * (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, * + * modify, and relicense the code. RFIDler will always be available Open * + * Source, but this is important because the inability to relicense code * + * has caused devastating problems for other Free Software projects (such * + * as KDE and NASM). We also occasionally relicense the code to third * + * parties as discussed above. If you wish to specify special license * + * conditions of your contributions, just say so when you send them. * + * * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler * + * license file for more details (it's in a COPYING file included with * + * RFIDler, and also available from * + * https://github.com/ApertureLabsLtd/RFIDler/COPYING * + * * + ***************************************************************************/ + +// Author: Adam Laurie + +#define CRC16_MASK_CCITT 0x1021 // CRC-CCITT mask (ISO 3309, used in X25, HDLC) +#define CRC16_MASK_ISO_11785 0x8408 // ISO 11785 animal tags +#define CRC16_MASK_CRC16 0xA001 // standard CRC16 mask (used in ARC files) + +/* + * Hitag Crypto support macros + * These macros reverse the bit order in a byte, or *within* each byte of a + * 16 , 32 or 64 bit unsigned integer. (Not across the whole 16 etc bits.) + */ +#define rev8(X) ((((X) >> 7) &1) + (((X) >> 5) &2) + (((X) >> 3) &4) \ + + (((X) >> 1) &8) + (((X) << 1) &16) + (((X) << 3) &32) \ + + (((X) << 5) &64) + (((X) << 7) &128) ) +#define rev16(X) (rev8 (X) + (rev8 (X >> 8) << 8)) +#define rev32(X) (rev16(X) + (rev16(X >> 16) << 16)) +#define rev64(X) (rev32(X) + (rev32(X >> 32) << 32)) + + +BYTE approx(unsigned long number, unsigned long target, unsigned char percentage); +unsigned int bcdtouint(BYTE *bcd, BYTE length); +unsigned long long bcdtoulonglong(BYTE *bcd, BYTE length); +void inttobinarray(BYTE *target, unsigned int source, unsigned int bits); +void ulongtobinarray(BYTE *target, unsigned long source, unsigned int bits); +void ulonglongtobinarray(BYTE *target, unsigned long long source, unsigned int bits); +void inttobinstring(BYTE *target, unsigned int source, unsigned int bits); +void ulongtobinstring(BYTE *target, unsigned long source, unsigned int bits); +BOOL ulongtohex(BYTE *target, unsigned long source); +unsigned int binarraytoint(BYTE *bin, BYTE length); +unsigned long long binarraytolonglong(BYTE *bin, BYTE length); +unsigned long binarraytoulong(BYTE *bin, BYTE length); +BYTE hextobyte(BYTE *hex); +void printhexreadable(BYTE *hex, BYTE maxlength); +unsigned long hextoulong(BYTE *hex); +unsigned long hexreversetoulong(BYTE *hex); +unsigned long long hextoulonglong(BYTE *hex); +unsigned long long hexreversetoulonglong(BYTE *hex); +char hextolonglong(unsigned long long *out, unsigned char *hex); +unsigned int hextobinarray(unsigned char *target, unsigned char *source); +unsigned int hextobinstring(unsigned char *target, unsigned char *source); +unsigned int binarraytohex(unsigned char *target, unsigned char *source, unsigned int length); +void hexprintbinarray(BYTE *bin, unsigned int length); +unsigned int binstringtohex(unsigned char *target, unsigned char *source); +unsigned int binstringtobinarray(BYTE *target, BYTE *source); +void binstringtobyte(BYTE *target, unsigned char *source, BYTE length); +void binarraytobinstring(BYTE *target, BYTE *source, unsigned int length); +void printhexasbin(unsigned char *hex); +void printbinashex(unsigned char *bin); +void invertbinarray(BYTE *target, BYTE *source, unsigned int length); +void invertbinstring(BYTE *target, BYTE *source); +void printbinarray(unsigned char *bin, unsigned int length); +unsigned char getbit(unsigned char byte, unsigned char bit); +void bytestohex(unsigned char *target, unsigned char *source, unsigned int length); +unsigned int manchester_encode(unsigned char *target, unsigned char *source, unsigned int length); +unsigned int manchester_decode(unsigned char *target, unsigned char *source, unsigned int length); +char * strip_newline(char *buff); +BOOL command_ack(BOOL data); +BOOL command_nack(BYTE *reason); +BOOL command_unknown(void); +void ToUpper(char *string); +void string_reverse(unsigned char *string, unsigned int length); +BOOL string_byteswap(unsigned char *string, unsigned int length); +BYTE parity(unsigned char *string, BYTE type, unsigned int length); +unsigned long get_reader_pulse(unsigned int timeout_us); +unsigned long get_reader_gap(unsigned int timeout_us); +unsigned int crc_ccitt(BYTE *data, unsigned int length); +unsigned int crc16(unsigned int crc, BYTE *data, unsigned int length, unsigned int mask); +void space_indent(BYTE count); +void xml_version(void); +void xml_header(BYTE *item, BYTE *indent); +void xml_footer(BYTE *item, BYTE *indent, BOOL newline); +void xml_indented_text(BYTE *data, BYTE indent); +void xml_item_text(BYTE *item, BYTE *data, BYTE *indent); +void xml_item_decimal(BYTE *item, BYTE num, BYTE *indent); +void xml_indented_array(BYTE *data, BYTE mask, unsigned int length, BYTE indent); +void xml_item_array(BYTE *item, BYTE *data, BYTE mask, unsigned int length, BYTE *indent); + diff --git a/tools/hitag2crack/crack2/utilpart.c b/tools/hitag2crack/crack2/utilpart.c new file mode 100644 index 000000000..210853ec1 --- /dev/null +++ b/tools/hitag2crack/crack2/utilpart.c @@ -0,0 +1,183 @@ +/*************************************************************************** + * A copy of the GNU GPL is appended to this file. * + * * + * This licence is based on the nmap licence, and we express our gratitude * + * for the work that went into producing it. There is no other connection * + * between RFIDler and nmap either expressed or implied. * + * * + ********************** IMPORTANT RFIDler LICENSE TERMS ******************** + * * + * * + * All references to RFIDler herein imply all it's derivatives, namely: * + * * + * o RFIDler-LF Standard * + * o RFIDler-LF Lite * + * o RFIDler-LF Nekkid * + * * + * * + * RFIDler is (C) 2013-2014 Aperture Labs Ltd. * + * * + * This program is free software; you may redistribute and/or modify it * + * under the terms of the GNU General Public License as published by the * + * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE * + * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your * + * right to use, modify, and redistribute this software under certain * + * conditions. If you wish to embed RFIDler technology into proprietary * + * software or hardware, we sell alternative licenses * + * (contact sales@aperturelabs.com). * + * * + * Note that the GPL places important restrictions on "derivative works", * + * yet it does not provide a detailed definition of that term. To avoid * + * misunderstandings, we interpret that term as broadly as copyright law * + * allows. For example, we consider an application to constitute a * + * derivative work for the purpose of this license if it does any of the * + * following with any software or content covered by this license * + * ("Covered Software"): * + * * + * o Integrates source code from Covered Software. * + * * + * o Is designed specifically to execute Covered Software and parse the * + * results (as opposed to typical shell or execution-menu apps, which will * + * execute anything you tell them to). * + * * + * o Includes Covered Software in a proprietary executable installer. The * + * installers produced by InstallShield are an example of this. Including * + * RFIDler with other software in compressed or archival form does not * + * trigger this provision, provided appropriate open source decompression * + * or de-archiving software is widely available for no charge. For the * + * purposes of this license, an installer is considered to include Covered * + * Software even if it actually retrieves a copy of Covered Software from * + * another source during runtime (such as by downloading it from the * + * Internet). * + * * + * o Links (statically or dynamically) to a library which does any of the * + * above. * + * * + * o Executes a helper program, module, or script to do any of the above. * + * * + * This list is not exclusive, but is meant to clarify our interpretation * + * of derived works with some common examples. Other people may interpret * + * the plain GPL differently, so we consider this a special exception to * + * the GPL that we apply to Covered Software. Works which meet any of * + * these conditions must conform to all of the terms of this license, * + * particularly including the GPL Section 3 requirements of providing * + * source code and allowing free redistribution of the work as a whole. * + * * + * As another special exception to the GPL terms, Aperture Labs Ltd. grants* + * permission to link the code of this program with any version of the * + * OpenSSL library which is distributed under a license identical to that * + * listed in the included docs/licenses/OpenSSL.txt file, and distribute * + * linked combinations including the two. * + * * + * Any redistribution of Covered Software, including any derived works, * + * must obey and carry forward all of the terms of this license, including * + * obeying all GPL rules and restrictions. For example, source code of * + * the whole work must be provided and free redistribution must be * + * allowed. All GPL references to "this License", are to be treated as * + * including the terms and conditions of this license text as well. * + * * + * Because this license imposes special exceptions to the GPL, Covered * + * Work may not be combined (even as part of a larger work) with plain GPL * + * software. The terms, conditions, and exceptions of this license must * + * be included as well. This license is incompatible with some other open * + * source licenses as well. In some cases we can relicense portions of * + * RFIDler or grant special permissions to use it in other open source * + * software. Please contact sales@aperturelabs.com with any such requests.* + * Similarly, we don't incorporate incompatible open source software into * + * Covered Software without special permission from the copyright holders. * + * * + * If you have any questions about the licensing restrictions on using * + * RFIDler in other works, are happy to help. As mentioned above, we also * + * offer alternative license to integrate RFIDler into proprietary * + * applications and appliances. These contracts have been sold to dozens * + * of software vendors, and generally include a perpetual license as well * + * as providing for priority support and updates. They also fund the * + * continued development of RFIDler. Please email sales@aperturelabs.com * + * for further information. * + * If you have received a written license agreement or contract for * + * Covered Software stating terms other than these, you may choose to use * + * and redistribute Covered Software under those terms instead of these. * + * * + * Source is provided to this software because we believe users have a * + * right to know exactly what a program is going to do before they run it. * + * This also allows you to audit the software for security holes (none * + * have been found so far). * + * * + * Source code also allows you to port RFIDler to new platforms, fix bugs, * + * and add new features. You are highly encouraged to send your changes * + * to the RFIDler mailing list for possible incorporation into the * + * main distribution. By sending these changes to Aperture Labs Ltd. or * + * one of the Aperture Labs Ltd. development mailing lists, or checking * + * them into the RFIDler source code repository, it is understood (unless * + * you specify otherwise) that you are offering the RFIDler Project * + * (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, * + * modify, and relicense the code. RFIDler will always be available Open * + * Source, but this is important because the inability to relicense code * + * has caused devastating problems for other Free Software projects (such * + * as KDE and NASM). We also occasionally relicense the code to third * + * parties as discussed above. If you wish to specify special license * + * conditions of your contributions, just say so when you send them. * + * * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler * + * license file for more details (it's in a COPYING file included with * + * RFIDler, and also available from * + * https://github.com/ApertureLabsLtd/RFIDler/COPYING * + * * + ***************************************************************************/ + +// Author: Adam Laurie + + +#include +#include +#include "HardwareProfile.h" +#include "util.h" +#include "rfidler.h" +//#include "comms.h" + +// rtc +rtccTime RTC_time; // time structure +rtccDate RTC_date; // date structure + +// convert byte-reversed 8 digit hex to unsigned long +unsigned long hexreversetoulong(BYTE *hex) +{ + unsigned long ret= 0L; + unsigned int x; + BYTE i; + + if(strlen(hex) != 8) + return 0L; + + for(i= 0 ; i < 4 ; ++i) + { + if(sscanf(hex, "%2X", &x) != 1) + return 0L; + ret += ((unsigned long) x) << i * 8; + hex += 2; + } + return ret; +} + +// convert byte-reversed 12 digit hex to unsigned long +unsigned long long hexreversetoulonglong(BYTE *hex) +{ + unsigned long long ret= 0LL; + BYTE tmp[9]; + + // this may seem an odd way to do it, but weird compiler issues were + // breaking direct conversion! + + tmp[8]= '\0'; + memset(tmp + 4, '0', 4); + memcpy(tmp, hex + 8, 4); + ret= hexreversetoulong(tmp); + ret <<= 32; + memcpy(tmp, hex, 8); + ret += hexreversetoulong(tmp); + return ret; +} + + diff --git a/tools/hitag2crack/crack3/.gitignore b/tools/hitag2crack/crack3/.gitignore new file mode 100644 index 000000000..c993f2fe3 --- /dev/null +++ b/tools/hitag2crack/crack3/.gitignore @@ -0,0 +1,6 @@ +ht2crack3 +ht2test + +ht2crack3.exe +ht2test.exe + diff --git a/tools/hitag2crack/crack3/HardwareProfile.h b/tools/hitag2crack/crack3/HardwareProfile.h new file mode 100644 index 000000000..a2f804be6 --- /dev/null +++ b/tools/hitag2crack/crack3/HardwareProfile.h @@ -0,0 +1,524 @@ +/*************************************************************************** + * A copy of the GNU GPL is appended to this file. * + * * + * This licence is based on the nmap licence, and we express our gratitude * + * for the work that went into producing it. There is no other connection * + * between RFIDler and nmap either expressed or implied. * + * * + ********************** IMPORTANT RFIDler LICENSE TERMS ******************** + * * + * * + * All references to RFIDler herein imply all it's derivatives, namely: * + * * + * o RFIDler-LF Standard * + * o RFIDler-LF Lite * + * o RFIDler-LF Nekkid * + * * + * * + * RFIDler is (C) 2013-2014 Aperture Labs Ltd. * + * * + * This program is free software; you may redistribute and/or modify it * + * under the terms of the GNU General Public License as published by the * + * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE * + * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your * + * right to use, modify, and redistribute this software under certain * + * conditions. If you wish to embed RFIDler technology into proprietary * + * software or hardware, we sell alternative licenses * + * (contact sales@aperturelabs.com). * + * * + * Note that the GPL places important restrictions on "derivative works", * + * yet it does not provide a detailed definition of that term. To avoid * + * misunderstandings, we interpret that term as broadly as copyright law * + * allows. For example, we consider an application to constitute a * + * derivative work for the purpose of this license if it does any of the * + * following with any software or content covered by this license * + * ("Covered Software"): * + * * + * o Integrates source code from Covered Software. * + * * + * o Is designed specifically to execute Covered Software and parse the * + * results (as opposed to typical shell or execution-menu apps, which will * + * execute anything you tell them to). * + * * + * o Includes Covered Software in a proprietary executable installer. The * + * installers produced by InstallShield are an example of this. Including * + * RFIDler with other software in compressed or archival form does not * + * trigger this provision, provided appropriate open source decompression * + * or de-archiving software is widely available for no charge. For the * + * purposes of this license, an installer is considered to include Covered * + * Software even if it actually retrieves a copy of Covered Software from * + * another source during runtime (such as by downloading it from the * + * Internet). * + * * + * o Links (statically or dynamically) to a library which does any of the * + * above. * + * * + * o Executes a helper program, module, or script to do any of the above. * + * * + * This list is not exclusive, but is meant to clarify our interpretation * + * of derived works with some common examples. Other people may interpret * + * the plain GPL differently, so we consider this a special exception to * + * the GPL that we apply to Covered Software. Works which meet any of * + * these conditions must conform to all of the terms of this license, * + * particularly including the GPL Section 3 requirements of providing * + * source code and allowing free redistribution of the work as a whole. * + * * + * As another special exception to the GPL terms, Aperture Labs Ltd. grants* + * permission to link the code of this program with any version of the * + * OpenSSL library which is distributed under a license identical to that * + * listed in the included docs/licenses/OpenSSL.txt file, and distribute * + * linked combinations including the two. * + * * + * Any redistribution of Covered Software, including any derived works, * + * must obey and carry forward all of the terms of this license, including * + * obeying all GPL rules and restrictions. For example, source code of * + * the whole work must be provided and free redistribution must be * + * allowed. All GPL references to "this License", are to be treated as * + * including the terms and conditions of this license text as well. * + * * + * Because this license imposes special exceptions to the GPL, Covered * + * Work may not be combined (even as part of a larger work) with plain GPL * + * software. The terms, conditions, and exceptions of this license must * + * be included as well. This license is incompatible with some other open * + * source licenses as well. In some cases we can relicense portions of * + * RFIDler or grant special permissions to use it in other open source * + * software. Please contact sales@aperturelabs.com with any such requests.* + * Similarly, we don't incorporate incompatible open source software into * + * Covered Software without special permission from the copyright holders. * + * * + * If you have any questions about the licensing restrictions on using * + * RFIDler in other works, are happy to help. As mentioned above, we also * + * offer alternative license to integrate RFIDler into proprietary * + * applications and appliances. These contracts have been sold to dozens * + * of software vendors, and generally include a perpetual license as well * + * as providing for priority support and updates. They also fund the * + * continued development of RFIDler. Please email sales@aperturelabs.com * + * for further information. * + * If you have received a written license agreement or contract for * + * Covered Software stating terms other than these, you may choose to use * + * and redistribute Covered Software under those terms instead of these. * + * * + * Source is provided to this software because we believe users have a * + * right to know exactly what a program is going to do before they run it. * + * This also allows you to audit the software for security holes (none * + * have been found so far). * + * * + * Source code also allows you to port RFIDler to new platforms, fix bugs, * + * and add new features. You are highly encouraged to send your changes * + * to the RFIDler mailing list for possible incorporation into the * + * main distribution. By sending these changes to Aperture Labs Ltd. or * + * one of the Aperture Labs Ltd. development mailing lists, or checking * + * them into the RFIDler source code repository, it is understood (unless * + * you specify otherwise) that you are offering the RFIDler Project * + * (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, * + * modify, and relicense the code. RFIDler will always be available Open * + * Source, but this is important because the inability to relicense code * + * has caused devastating problems for other Free Software projects (such * + * as KDE and NASM). We also occasionally relicense the code to third * + * parties as discussed above. If you wish to specify special license * + * conditions of your contributions, just say so when you send them. * + * * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler * + * license file for more details (it's in a COPYING file included with * + * RFIDler, and also available from * + * https://github.com/ApertureLabsLtd/RFIDler/COPYING * + * * + ***************************************************************************/ + +// Author: Adam Laurie + + + +#ifndef HARDWARE_PROFILE_UBW32_H +#define HARDWARE_PROFILE_UBW32_H + +//#include "plib.h" +typedef char BOOL; +typedef char BYTE; +typedef int rtccTime; +typedef int rtccDate; + + +#ifndef __PIC32MX__ + #define __PIC32MX__ +#endif + +#define GetSystemClock() (80000000ul) +#define GetPeripheralClock() (GetSystemClock()) +#define GetInstructionClock() (GetSystemClock()) + +//#define USE_SELF_POWER_SENSE_IO +#define tris_self_power TRISAbits.TRISA2 // Input +#define self_power 1 + +//#define USE_USB_BUS_SENSE_IO +#define tris_usb_bus_sense TRISBbits.TRISB5 // Input +#define USB_BUS_SENSE 1 + +// LEDs +#define mLED_1 LATEbits.LATE3 + +#define mLED_2 LATEbits.LATE2 +#define mLED_Comms mLED_2 + +#define mLED_3 LATEbits.LATE1 +#define mLED_Clock mLED_3 + +#define mLED_4 LATEbits.LATE0 +#define mLED_Emulate mLED_4 + +#define mLED_5 LATGbits.LATG6 +#define mLED_Read mLED_5 + +#define mLED_6 LATAbits.LATA15 +#define mLED_User mLED_6 + +#define mLED_7 LATDbits.LATD11 +#define mLED_Error mLED_7 + +// active low +#define mLED_ON 0 +#define mLED_OFF 1 + +#define mGetLED_1() mLED_1 +#define mGetLED_USB() mLED_1 +#define mGetLED_2() mLED_2 +#define mGetLED_Comms() mLED_2 +#define mGetLED_3() mLED_3 +#define mGetLED_Clock() mLED_3 +#define mGetLED_4() mLED_4 +#define mGetLED_Emulate() mLED_4 +#define mGetLED_5() mLED_5 +#define mGetLED_Read() mLED_5 +#define mGetLED_6() mLED_6 +#define mGetLED_User() mLED_6 +#define mGetLED_7() mLED_7 +#define mGetLED_Error() mLED_7 + +#define mLED_1_On() mLED_1 = mLED_ON +#define mLED_USB_On() mLED_1_On() +#define mLED_2_On() mLED_2 = mLED_ON +#define mLED_Comms_On() mLED_2_On() +#define mLED_3_On() mLED_3 = mLED_ON +#define mLED_Clock_On() mLED_3_On() +#define mLED_4_On() mLED_4 = mLED_ON +#define mLED_Emulate_On() mLED_4_On() +#define mLED_5_On() mLED_5 = mLED_ON +#define mLED_Read_On() mLED_5_On() +#define mLED_6_On() mLED_6 = mLED_ON +#define mLED_User_On() mLED_6_On() +#define mLED_7_On() mLED_7 = mLED_ON +#define mLED_Error_On() mLED_7_On() + +#define mLED_1_Off() mLED_1 = mLED_OFF +#define mLED_USB_Off() mLED_1_Off() +#define mLED_2_Off() mLED_2 = mLED_OFF +#define mLED_Comms_Off() mLED_2_Off() +#define mLED_3_Off() mLED_3 = mLED_OFF +#define mLED_Clock_Off() mLED_3_Off() +#define mLED_4_Off() mLED_4 = mLED_OFF +#define mLED_Emulate_Off() mLED_4_Off() +#define mLED_5_Off() mLED_5 = mLED_OFF +#define mLED_Read_Off() mLED_5_Off() +#define mLED_6_Off() mLED_6 = mLED_OFF +#define mLED_User_Off() mLED_6_Off() +#define mLED_7_Off() mLED_7 = mLED_OFF +#define mLED_Error_Off() mLED_7_Off() + +#define mLED_1_Toggle() mLED_1 = !mLED_1 +#define mLED_USB_Toggle() mLED_1_Toggle() +#define mLED_2_Toggle() mLED_2 = !mLED_2 +#define mLED_Comms_Toggle() mLED_2_Toggle() +#define mLED_3_Toggle() mLED_3 = !mLED_3 +#define mLED_Clock_Toggle() mLED_3_Toggle() +#define mLED_4_Toggle() mLED_4 = !mLED_4 +#define mLED_Emulate_Toggle() mLED_4_Toggle() +#define mLED_5_Toggle() mLED_5 = !mLED_5 +#define mLED_Read_Toggle( ) mLED_5_Toggle() +#define mLED_6_Toggle() mLED_6 = !mLED_6 +#define mLED_User_Toggle() mLED_6_Toggle() +#define mLED_7_Toggle() mLED_7 = !mLED_7 +#define mLED_Error_Toggle() mLED_7_Toggle() + +#define mLED_All_On() { mLED_1_On(); mLED_2_On(); mLED_3_On(); mLED_4_On(); mLED_5_On(); mLED_6_On(); mLED_7_On(); } +#define mLED_All_Off() { mLED_1_Off(); mLED_2_Off(); mLED_3_Off(); mLED_4_Off(); mLED_5_Off(); mLED_6_Off(); mLED_7_Off(); } + +// usb status lights +#define mLED_Both_Off() {mLED_USB_Off();mLED_Comms_Off();} +#define mLED_Both_On() {mLED_USB_On();mLED_Comms_On();} +#define mLED_Only_USB_On() {mLED_USB_On();mLED_Comms_Off();} +#define mLED_Only_Comms_On() {mLED_USB_Off();mLED_Comms_On();} + +/** SWITCH *********************************************************/ +#define swBootloader PORTEbits.RE7 +#define swUser PORTEbits.RE6 + +/** I/O pin definitions ********************************************/ +#define INPUT_PIN 1 +#define OUTPUT_PIN 0 + +#define TRUE 1 +#define FALSE 0 + +#define ENABLE 1 +#define DISABE 0 + +#define EVEN 0 +#define ODD 1 + +#define LOW FALSE +#define HIGH TRUE + +#define CLOCK_ON LOW +#define CLOCK_OFF HIGH + +// output coil control - select between reader/emulator circuits +#define COIL_MODE LATBbits.LATB4 +#define COIL_MODE_READER() COIL_MODE= LOW +#define COIL_MODE_EMULATOR() COIL_MODE= HIGH + +// coil for emulation +#define COIL_OUT LATGbits.LATG9 +#define COIL_OUT_HIGH() COIL_OUT=HIGH +#define COIL_OUT_LOW() COIL_OUT=LOW + +// door relay (active low) +#define DOOR_RELAY LATAbits.LATA14 +#define DOOR_RELAY_OPEN() DOOR_RELAY= HIGH +#define DOOR_RELAY_CLOSE() DOOR_RELAY= LOW + +// inductance/capacitance freq +#define IC_FREQUENCY PORTAbits.RA2 + +#define SNIFFER_COIL PORTDbits.RD12 // external reader clock detect +#define READER_ANALOGUE PORTBbits.RB11 // reader coil analogue +#define DIV_LOW_ANALOGUE PORTBbits.RB12 // voltage divider LOW analogue +#define DIV_HIGH_ANALOGUE PORTBbits.RB13 // voltage divider HIGH analogue + +// clock coil (normally controlled by OC Module, but defined here so we can force it high or low) +#define CLOCK_COIL PORTDbits.RD4 +#define CLOCK_COIL_MOVED PORTDbits.RD0 // temporary for greenwire + +// digital output after analogue reader circuit +#define READER_DATA PORTDbits.RD8 + +// trace / debug +#define DEBUG_PIN_1 LATCbits.LATC1 +#define DEBUG_PIN_1_TOGGLE() DEBUG_PIN_1= !DEBUG_PIN_1 +#define DEBUG_PIN_2 LATCbits.LATC2 +#define DEBUG_PIN_2_TOGGLE() DEBUG_PIN_2= !DEBUG_PIN_2 +#define DEBUG_PIN_3 LATCbits.LATC3 +#define DEBUG_PIN_3_TOGGLE() DEBUG_PIN_3= !DEBUG_PIN_3 +#define DEBUG_PIN_4 LATEbits.LATE5 +#define DEBUG_PIN_4_TOGGLE() DEBUG_PIN_4= !DEBUG_PIN_4 + +// spi (sdi1) for sd card (not directly referenced) +//#define SD_CARD_RX LATCbits.LATC4 +//#define SD_CARD_TX LATDbits.LATD0 +//#define SD_CARD_CLK LATDbits.LATD10 +//#define SD_CARD_SS LATDbits.LATD9 +// spi for SD card +#define SD_CARD_DET LATFbits.LATF0 +#define SD_CARD_WE LATFbits.LATF1 // write enable - unused for microsd but allocated anyway as library checks it + // (held LOW by default - cut solder bridge to GND to free pin if required) +#define SPI_SD SPI_CHANNEL1 +#define SPI_SD_BUFF SPI1BUF +#define SPI_SD_STAT SPI1STATbits +// see section below for more defines! + +// iso 7816 smartcard +// microchip SC module defines pins so we don't need to, but +// they are listed here to help avoid conflicts +#define ISO_7816_RX LATBbits.LATF2 // RX +#define ISO_7816_TX LATBbits.LATF8 // TX +#define ISO_7816_VCC LATBbits.LATB9 // Power +#define ISO_7816_CLK LATCbits.LATD1 // Clock +#define ISO_7816_RST LATEbits.LATE8 // Reset + +// user LED +#define USER_LED LATDbits.LATD7 +#define USER_LED_ON() LATDbits.LATD7=1 +#define USER_LED_OFF() LATDbits.LATD7=0 + +// LCR +#define LCR_CALIBRATE LATBbits.LATB5 + +// wiegand / clock & data +#define WIEGAND_IN_0 PORTDbits.RD5 +#define WIEGAND_IN_0_PULLUP CNPUEbits.CNPUE14 +#define WIEGAND_IN_0_PULLDOWN CNPDbits.CNPD14 +#define WIEGAND_IN_1 PORTDbits.RD6 +#define WIEGAND_IN_1_PULLUP CNPUEbits.CNPUE15 +#define WIEGAND_IN_1_PULLDOWN CNPDbits.CNPD15 +#define CAND_IN_DATA WIEGAND_IN_0 +#define CAND_IN_CLOCK WIEGAND_IN_1 + +#define WIEGAND_OUT_0 LATDbits.LATD3 +#define WIEGAND_OUT_1 LATDbits.LATD2 +#define WIEGAND_OUT_0_TRIS TRISDbits.TRISD3 +#define WIEGAND_OUT_1_TRIS TRISDbits.TRISD2 +#define CAND_OUT_DATA WIEGAND_OUT_0 +#define CAND_OUT_CLOCK WIEGAND_OUT_1 + +// connect/disconnect reader clock from coil - used to send RWD signals by creating gaps in carrier +#define READER_CLOCK_ENABLE LATEbits.LATE9 +#define READER_CLOCK_ENABLE_ON() READER_CLOCK_ENABLE=CLOCK_ON +#define READER_CLOCK_ENABLE_OFF(x) {READER_CLOCK_ENABLE=CLOCK_OFF; COIL_OUT=x;} + +// these input pins must NEVER bet set to output or they will cause short circuits! +// they can be used to see data from reader before it goes into or gate +#define OR_IN_A PORTAbits.RA4 +#define OR_IN_B PORTAbits.RA5 + + +// CNCON and CNEN are set to allow wiegand input pin weak pullups to be switched on +#define Init_GPIO() { \ + CNCONbits.ON= TRUE; \ + CNENbits.CNEN14= TRUE; \ + CNENbits.CNEN15= TRUE; \ + TRISAbits.TRISA2= INPUT_PIN; \ + TRISAbits.TRISA4= INPUT_PIN; \ + TRISAbits.TRISA5= INPUT_PIN; \ + TRISAbits.TRISA14= OUTPUT_PIN; \ + TRISAbits.TRISA15= OUTPUT_PIN; \ + TRISBbits.TRISB4= OUTPUT_PIN; \ + TRISBbits.TRISB5= OUTPUT_PIN; \ + TRISBbits.TRISB9= OUTPUT_PIN; \ + TRISBbits.TRISB11= INPUT_PIN; \ + TRISBbits.TRISB12= INPUT_PIN; \ + TRISBbits.TRISB13= INPUT_PIN; \ + TRISCbits.TRISC1= OUTPUT_PIN; \ + TRISCbits.TRISC2= OUTPUT_PIN; \ + TRISCbits.TRISC3= OUTPUT_PIN; \ + TRISCbits.TRISC4= INPUT_PIN; \ + TRISDbits.TRISD0= INPUT_PIN; \ + TRISDbits.TRISD1= OUTPUT_PIN; \ + TRISDbits.TRISD2= OUTPUT_PIN; \ + TRISDbits.TRISD3= OUTPUT_PIN; \ + TRISDbits.TRISD4= OUTPUT_PIN; \ + TRISDbits.TRISD5= INPUT_PIN; \ + TRISDbits.TRISD6= INPUT_PIN; \ + TRISDbits.TRISD7= OUTPUT_PIN; \ + TRISDbits.TRISD8= INPUT_PIN; \ + TRISDbits.TRISD11= OUTPUT_PIN; \ + TRISDbits.TRISD12= INPUT_PIN; \ + TRISEbits.TRISE0= OUTPUT_PIN; \ + TRISEbits.TRISE1= OUTPUT_PIN; \ + TRISEbits.TRISE2= OUTPUT_PIN; \ + TRISEbits.TRISE3= OUTPUT_PIN; \ + TRISEbits.TRISE5= OUTPUT_PIN; \ + TRISEbits.TRISE6= INPUT_PIN; \ + TRISEbits.TRISE7= INPUT_PIN; \ + TRISEbits.TRISE8= OUTPUT_PIN; \ + TRISEbits.TRISE9= OUTPUT_PIN; \ + TRISFbits.TRISF0= INPUT_PIN; \ + TRISFbits.TRISF1= INPUT_PIN; \ + TRISFbits.TRISF2= INPUT_PIN; \ + TRISFbits.TRISF8= OUTPUT_PIN; \ + TRISGbits.TRISG6= OUTPUT_PIN; \ + TRISGbits.TRISG12= INPUT_PIN; \ + TRISGbits.TRISG13= INPUT_PIN; \ + TRISGbits.TRISG9= OUTPUT_PIN; \ + LATBbits.LATB9= LOW; \ + LATCbits.LATC1= LOW; \ + LATCbits.LATC2= LOW; \ + LATCbits.LATC3= LOW; \ + LATDbits.LATD2= WIEGAND_IN_1; \ + LATDbits.LATD3= WIEGAND_IN_0; \ + LATEbits.LATE5= LOW; \ + LATEbits.LATE9= HIGH; \ + } + +// uart3 (CLI/API) speed +#define BAUDRATE3 115200UL +#define BRG_DIV3 4 +#define BRGH3 1 + +// spi for potentiometer +#define SPI_POT SPI_CHANNEL4 +#define SPI_POT_BUFF SPI4BUF +#define SPI_POT_STAT SPI4STATbits + +// spi for sd card - defines required for Microchip SD-SPI libs +// define interface type +#define USE_SD_INTERFACE_WITH_SPI + +#define MDD_USE_SPI_1 +#define SPI_START_CFG_1 (PRI_PRESCAL_64_1 | SEC_PRESCAL_8_1 | MASTER_ENABLE_ON | SPI_CKE_ON | SPI_SMP_ON) +#define SPI_START_CFG_2 (SPI_ENABLE) +// Define the SPI frequency +#define SPI_FREQUENCY (20000000) +// Description: SD-SPI Card Detect Input bit +#define SD_CD PORTFbits.RF0 +// Description: SD-SPI Card Detect TRIS bit +#define SD_CD_TRIS TRISFbits.TRISF0 +// Description: SD-SPI Write Protect Check Input bit +#define SD_WE PORTFbits.RF1 +// Description: SD-SPI Write Protect Check TRIS bit +#define SD_WE_TRIS TRISFbits.TRISF1 +// Description: The main SPI control register +#define SPICON1 SPI1CON +// Description: The SPI status register +#define SPISTAT SPI1STAT +// Description: The SPI Buffer +#define SPIBUF SPI1BUF +// Description: The receive buffer full bit in the SPI status register +#define SPISTAT_RBF SPI1STATbits.SPIRBF +// Description: The bitwise define for the SPI control register (i.e. _____bits) +#define SPICON1bits SPI1CONbits +// Description: The bitwise define for the SPI status register (i.e. _____bits) +#define SPISTATbits SPI1STATbits +// Description: The enable bit for the SPI module +#define SPIENABLE SPICON1bits.ON +// Description: The definition for the SPI baud rate generator register (PIC32) +#define SPIBRG SPI1BRG +// Description: The TRIS bit for the SCK pin +#define SPICLOCK TRISDbits.TRISD10 +// Description: The TRIS bit for the SDI pin +#define SPIIN TRISCbits.TRISC4 +// Description: The TRIS bit for the SDO pin +#define SPIOUT TRISDbits.TRISD0 +#define SD_CS LATDbits.LATD9 +// Description: SD-SPI Chip Select TRIS bit +#define SD_CS_TRIS TRISDbits.TRISD9 +//SPI library functions +#define putcSPI putcSPI1 +#define getcSPI getcSPI1 +#define OpenSPI(config1, config2) OpenSPI1(config1, config2) + +// Define setup parameters for OpenADC10 function +// Turn module on | Ouput in integer format | Trigger mode auto | Enable autosample +#define ADC_CONFIG1 (ADC_FORMAT_INTG | ADC_CLK_AUTO | ADC_AUTO_SAMPLING_ON) +// ADC ref external | Disable offset test | Disable scan mode | Perform 2 samples | Use dual buffers | Use alternate mode +#define ADC_CONFIG2 (ADC_VREF_AVDD_AVSS | ADC_OFFSET_CAL_DISABLE | ADC_SCAN_OFF | ADC_SAMPLES_PER_INT_1 | ADC_ALT_BUF_ON | ADC_ALT_INPUT_ON) + +// Use ADC internal clock | Set sample time +#define ADC_CONFIG3 (ADC_CONV_CLK_INTERNAL_RC | ADC_SAMPLE_TIME_0) + +// slow sample rate for tuning coils +#define ADC_CONFIG2_SLOW (ADC_VREF_AVDD_AVSS | ADC_OFFSET_CAL_DISABLE | ADC_SCAN_OFF | ADC_SAMPLES_PER_INT_16 | ADC_ALT_BUF_ON | ADC_ALT_INPUT_ON) +#define ADC_CONFIG3_SLOW (ADC_CONV_CLK_INTERNAL_RC | ADC_SAMPLE_TIME_31) + +// use AN11 +#define ADC_CONFIGPORT ENABLE_AN11_ANA +// Do not assign channels to scan +#define ADC_CONFIGSCAN SKIP_SCAN_ALL + +#define ADC_TO_VOLTS 0.003208F + + +// flash memory - int myvar = *(int*)(myflashmemoryaddress); + +// memory is 0x9D005000 to 0x9D07FFFF + +#define NVM_MEMORY_END 0x9D07FFFF +#define NVM_PAGE_SIZE 4096 +#define NVM_PAGES 2 // config & VTAG +#define RFIDLER_NVM_ADDRESS (NVM_MEMORY_END - (NVM_PAGE_SIZE * NVM_PAGES)) + +// UART timeout in us +#define SERIAL_TIMEOUT 100 + +#endif diff --git a/tools/hitag2crack/crack3/Makefile b/tools/hitag2crack/crack3/Makefile new file mode 100644 index 000000000..6f6b7b57c --- /dev/null +++ b/tools/hitag2crack/crack3/Makefile @@ -0,0 +1,19 @@ +WARN=-Wall +INCLUDE=-I../include +CFLAGS=-c $(WARN) $(INCLUDE) +LIBS= + +all: ht2crack3.c ht2test.c hitagcrypto.o utilpart.o + cc $(WARN) -o ht2crack3 ht2crack3.c hitagcrypto.o utilpart.o -lpthread $(LIBS) + cc $(WARN) -o ht2test ht2test.c hitagcrypto.o utilpart.o $(LIBS) + +hitagcrypto.o: hitagcrypto.c hitagcrypto.h + cc $(CFLAGS) hitagcrypto.c + +utilpart.o: utilpart.c util.h + cc $(CFLAGS) utilpart.c + +clean: + rm -rf *.o ht2crack3 ht2test + +fresh: clean all diff --git a/tools/hitag2crack/crack3/hitagcrypto.c b/tools/hitag2crack/crack3/hitagcrypto.c new file mode 100644 index 000000000..422efbe92 --- /dev/null +++ b/tools/hitag2crack/crack3/hitagcrypto.c @@ -0,0 +1,485 @@ +/*************************************************************************** + * A copy of the GNU GPL is appended to this file. * + * * + * This licence is based on the nmap licence, and we express our gratitude * + * for the work that went into producing it. There is no other connection * + * between RFIDler and nmap either expressed or implied. * + * * + ********************** IMPORTANT RFIDler LICENSE TERMS ******************** + * * + * * + * All references to RFIDler herein imply all it's derivatives, namely: * + * * + * o RFIDler-LF Standard * + * o RFIDler-LF Lite * + * o RFIDler-LF Nekkid * + * * + * * + * RFIDler is (C) 2013-2015 Aperture Labs Ltd. * + * * + * This program is free software; you may redistribute and/or modify it * + * under the terms of the GNU General Public License as published by the * + * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE * + * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your * + * right to use, modify, and redistribute this software under certain * + * conditions. If you wish to embed RFIDler technology into proprietary * + * software or hardware, we sell alternative licenses * + * (contact sales@aperturelabs.com). * + * * + * Note that the GPL places important restrictions on "derivative works", * + * yet it does not provide a detailed definition of that term. To avoid * + * misunderstandings, we interpret that term as broadly as copyright law * + * allows. For example, we consider an application to constitute a * + * derivative work for the purpose of this license if it does any of the * + * following with any software or content covered by this license * + * ("Covered Software"): * + * * + * o Integrates source code from Covered Software. * + * * + * o Is designed specifically to execute Covered Software and parse the * + * results (as opposed to typical shell or execution-menu apps, which will * + * execute anything you tell them to). * + * * + * o Includes Covered Software in a proprietary executable installer. The * + * installers produced by InstallShield are an example of this. Including * + * RFIDler with other software in compressed or archival form does not * + * trigger this provision, provided appropriate open source decompression * + * or de-archiving software is widely available for no charge. For the * + * purposes of this license, an installer is considered to include Covered * + * Software even if it actually retrieves a copy of Covered Software from * + * another source during runtime (such as by downloading it from the * + * Internet). * + * * + * o Links (statically or dynamically) to a library which does any of the * + * above. * + * * + * o Executes a helper program, module, or script to do any of the above. * + * * + * This list is not exclusive, but is meant to clarify our interpretation * + * of derived works with some common examples. Other people may interpret * + * the plain GPL differently, so we consider this a special exception to * + * the GPL that we apply to Covered Software. Works which meet any of * + * these conditions must conform to all of the terms of this license, * + * particularly including the GPL Section 3 requirements of providing * + * source code and allowing free redistribution of the work as a whole. * + * * + * As another special exception to the GPL terms, Aperture Labs Ltd. grants* + * permission to link the code of this program with any version of the * + * OpenSSL library which is distributed under a license identical to that * + * listed in the included docs/licenses/OpenSSL.txt file, and distribute * + * linked combinations including the two. * + * * + * Any redistribution of Covered Software, including any derived works, * + * must obey and carry forward all of the terms of this license, including * + * obeying all GPL rules and restrictions. For example, source code of * + * the whole work must be provided and free redistribution must be * + * allowed. All GPL references to "this License", are to be treated as * + * including the terms and conditions of this license text as well. * + * * + * Because this license imposes special exceptions to the GPL, Covered * + * Work may not be combined (even as part of a larger work) with plain GPL * + * software. The terms, conditions, and exceptions of this license must * + * be included as well. This license is incompatible with some other open * + * source licenses as well. In some cases we can relicense portions of * + * RFIDler or grant special permissions to use it in other open source * + * software. Please contact sales@aperturelabs.com with any such requests.* + * Similarly, we don't incorporate incompatible open source software into * + * Covered Software without special permission from the copyright holders. * + * * + * If you have any questions about the licensing restrictions on using * + * RFIDler in other works, are happy to help. As mentioned above, we also * + * offer alternative license to integrate RFIDler into proprietary * + * applications and appliances. These contracts have been sold to dozens * + * of software vendors, and generally include a perpetual license as well * + * as providing for priority support and updates. They also fund the * + * continued development of RFIDler. Please email sales@aperturelabs.com * + * for further information. * + * If you have received a written license agreement or contract for * + * Covered Software stating terms other than these, you may choose to use * + * and redistribute Covered Software under those terms instead of these. * + * * + * Source is provided to this software because we believe users have a * + * right to know exactly what a program is going to do before they run it. * + * This also allows you to audit the software for security holes (none * + * have been found so far). * + * * + * Source code also allows you to port RFIDler to new platforms, fix bugs, * + * and add new features. You are highly encouraged to send your changes * + * to the RFIDler mailing list for possible incorporation into the * + * main distribution. By sending these changes to Aperture Labs Ltd. or * + * one of the Aperture Labs Ltd. development mailing lists, or checking * + * them into the RFIDler source code repository, it is understood (unless * + * you specify otherwise) that you are offering the RFIDler Project * + * (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, * + * modify, and relicense the code. RFIDler will always be available Open * + * Source, but this is important because the inability to relicense code * + * has caused devastating problems for other Free Software projects (such * + * as KDE and NASM). We also occasionally relicense the code to third * + * parties as discussed above. If you wish to specify special license * + * conditions of your contributions, just say so when you send them. * + * * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler * + * license file for more details (it's in a COPYING file included with * + * RFIDler, and also available from * + * https://github.com/ApertureLabsLtd/RFIDler/COPYING * + * * + ***************************************************************************/ + +// Author: unknown. +// Modifications for RFIDler: Tony Naggs , Adam Laurie + +// uncomment this to build file as a standalone crypto test program +// #define UNIT_TEST +// also uncomment to include verbose debug prints +// #define TEST_DEBUG + +//#include +#include "HardwareProfile.h" +#include "rfidler.h" +#include "hitagcrypto.h" +#include "util.h" + +#ifdef UNIT_TEST +#include +#endif + +#if defined(UNIT_TEST) && defined(TEST_DEBUG) +// Note that printf format %I64x prints 64 bit ints in MS Visual C/C++. +// This may need changing for other compilers/platforms. +#define DEBUG_PRINTF(...) printf(__VA_ARGS__) +#else +#define DEBUG_PRINTF(...) +#endif + + +/* Brief info about NXP Hitag 1, Hitag 2, Hitag S and Hitag u (mu) + + Hitag 125kHz RFID was created by a company called Mikron (Mikron Gesellschaft + fur Integrierte Mikroelektronik Mbh), of Austria, for micropayment applications. + At about the same time, late 1980s to early 1990s, Mikron developed the + similarly featured Mifare micropayment card for 13.56MHz RFID. + (Mikron's European Patent EP 0473569 A2 was filed 23 August 1991, with a + priority date of 23 Aug 1990.) + Mikron was subsequently acquired by Philips Semiconductors in 1995. + Philips Semiconductors divsion subsequently became NXP. + + + Modulation read/write device -> transponder: 100 % ASK and binary pulse + length coding + + Modulation transponder -> read/write device: Strong ASK modulation, + selectable Manchester or Biphase coding + + Hitag S, Hitag u; anti-collision procedure + + Fast anti-collision protocol + + Hitag u; optional Cyclic Redundancy Check (CRC) + + Reader Talks First mode + + Hitag 2 & later; Transponder Talks First (TTF) mode + + Temporary switch from Transponder Talks First into Reader Talks First + (RTF) Mode + + Data rate read/write device to transponder: 5.2 kbit/s + + Data rates transponder to read/write device: 2 kbit/s, 4 kbit/s, 8 kbit/s + + 32-bit password feature + + Hitag 2, S = 32-bit Unique Identifier + + Hitag u = 48-bit Unique Identifier + + Selectable password modes for reader / tag mutual authentication + (Hitag 1 has 2 pairs of keys, later versions have 1 pair) + + Hitag 2 & Hitag S; Selectable encrypted mode, 48 bit key + + Known tag types: + + HITAG 1 2048 bits total memory + + HITAG 2 256 Bit total memory Read/Write + 8 pages of 32 bits, inc UID (32), + secret key (64), password (24), config (8) + + HITAG S 32 32 bits Unique Identifier Read Only + HITAG S 256 256 bits total memory Read/Write + HITAG S 2048 2048 bits total memory Read/Write + + HITAG u RO64 64 bits total memory Read Only + HITAG u 128 bits total memory Read/Write + HITAG u Advanced 512 bits total memory Read/Write + HITAG u Advanced+ 1760 bits total memory Read/Write + + Default 48-bit key for Hitag 2, S encryption: + "MIKRON" = O N M I K R + Key = 4F 4E 4D 49 4B 52 + +*/ + + +// We want the crypto functions to be as fast as possible, so optimize! +// The best compiler optimization in Microchip's free XC32 edition is -O1 +#pragma GCC optimize("O1") + +// private, nonlinear function to generate 1 crypto bit +static uint32_t hitag2_crypt(uint64_t x); + + +// macros to pick out 4 bits in various patterns of 1s & 2s & make a new number +#define pickbits2_2(S, A, B) ( ((S >> A) & 3) | ((S >> (B - 2)) & 0xC) ) +#define pickbits1x4(S, A, B, C, D) ( ((S >> A) & 1) | ((S >> (B - 1)) & 2) | \ + ((S >> (C - 2)) & 4) | ((S >> (D - 3)) & 8) ) +#define pickbits1_1_2(S, A, B, C) ( ((S >> A) & 1) | ((S >> (B - 1)) & 2) | \ + ((S >> (C - 2)) & 0xC) ) +#define pickbits2_1_1(S, A, B, C) ( ((S >> A) & 3) | ((S >> (B - 2)) & 4) | \ + ((S >> (C - 3)) & 8) ) +#define pickbits1_2_1(S, A, B, C) ( ((S >> A) & 1) | ((S >> (B - 1)) & 6) | \ + ((S >> (C - 3)) & 8) ) + + +static uint32_t hitag2_crypt(uint64_t s) +{ + const uint32_t ht2_function4a = 0x2C79; // 0010 1100 0111 1001 + const uint32_t ht2_function4b = 0x6671; // 0110 0110 0111 0001 + const uint32_t ht2_function5c = 0x7907287B; // 0111 1001 0000 0111 0010 1000 0111 1011 + uint32_t bitindex; + + bitindex = (ht2_function4a >> pickbits2_2 (s, 1, 4)) & 1; + bitindex |= ((ht2_function4b << 1) >> pickbits1_1_2 (s, 7, 11, 13)) & 0x02; + bitindex |= ((ht2_function4b << 2) >> pickbits1x4 (s, 16, 20, 22, 25)) & 0x04; + bitindex |= ((ht2_function4b << 3) >> pickbits2_1_1 (s, 27, 30, 32)) & 0x08; + bitindex |= ((ht2_function4a << 4) >> pickbits1_2_1(s, 33, 42, 45)) & 0x10; + + DEBUG_PRINTF("hitag2_crypt bitindex = %02x\n", bitindex); + return (ht2_function5c >> bitindex) & 1; +} + +/* + * Parameters: + * Hitag_State* pstate - output, internal state after initialisation + * uint64_t sharedkey - 48 bit key shared between reader & tag + * uint32_t serialnum - 32 bit tag serial number + * uint32_t initvector - 32 bit random IV from reader, part of tag authentication + */ +void hitag2_init(Hitag_State* pstate, uint64_t sharedkey, uint32_t serialnum, uint32_t initvector) +{ + // init state, from serial number and lowest 16 bits of shared key + uint64_t state = ((sharedkey & 0xFFFF) << 32) | serialnum; + + // mix the initialisation vector and highest 32 bits of the shared key + initvector ^= (uint32_t) (sharedkey >> 16); + + // move 16 bits from (IV xor Shared Key) to top of uint64_t state + // these will be XORed in turn with output of the crypto function + state |= (uint64_t) initvector << 48; + initvector >>= 16; + + // unrolled loop is faster on PIC32 (MIPS), do 32 times + // shift register, then calc new bit + state >>= 1; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + + // highest 16 bits of IV XOR Shared Key + state |= (uint64_t) initvector << 47; + + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state ^= (uint64_t) hitag2_crypt(state) << 47; + + DEBUG_PRINTF("hitag2_init result = %012I64x\n", state); + pstate->shiftreg = state; + /* naive version for reference, LFSR has 16 taps + pstate->lfsr = state ^ (state >> 2) ^ (state >> 3) ^ (state >> 6) + ^ (state >> 7) ^ (state >> 8) ^ (state >> 16) ^ (state >> 22) + ^ (state >> 23) ^ (state >> 26) ^ (state >> 30) ^ (state >> 41) + ^ (state >> 42) ^ (state >> 43) ^ (state >> 46) ^ (state >> 47); + */ + { + // optimise with one 64-bit intermediate + uint64_t temp = state ^ (state >> 1); + pstate->lfsr = state ^ (state >> 6) ^ (state >> 16) + ^ (state >> 26) ^ (state >> 30) ^ (state >> 41) + ^ (temp >> 2) ^ (temp >> 7) ^ (temp >> 22) + ^ (temp >> 42) ^ (temp >> 46); + } +} + + +/* + * Return up to 32 crypto bits. + * Last bit is in least significant bit, earlier bits are shifted left. + * Note that the Hitag transmission protocol is least significant bit, + * so we may want to change this, or add a function, that returns the + * crypto output bits in the other order. + * + * Parameters: + * Hitag_State* pstate - in/out, internal cipher state after initialisation + * uint32_t steps - number of bits requested, (capped at 32) + */ +uint32_t hitag2_nstep(Hitag_State* pstate, uint32_t steps) +{ + uint64_t state = pstate->shiftreg; + uint32_t result = 0; + uint64_t lfsr = pstate->lfsr; + + if (steps == 0) + return 0; + +// if (steps > 32) +// steps = 32; + + do { + // update shift registers + if (lfsr & 1) { + state = (state >> 1) | 0x800000000000; + lfsr = (lfsr >> 1) ^ 0xB38083220073; + + // accumulate next bit of crypto + result = (result << 1) | hitag2_crypt(state); + } else { + state >>= 1; + lfsr >>= 1; + + result = (result << 1) | hitag2_crypt(state); + } + } while (--steps); + + DEBUG_PRINTF("hitag2_nstep state = %012I64x, result %02x\n", state, result); + pstate->shiftreg = state; + pstate->lfsr = lfsr; + return result; +} + +// end of crypto core, revert to default optimization level +#pragma GCC reset_options + + +/* Test code + + Test data and below information about it comes from + http://www.mikrocontroller.net/attachment/102194/hitag2.c + Written by "I.C. Wiener 2006-2007" + + "MIKRON" = O N M I K R + Key = 4F 4E 4D 49 4B 52 - Secret 48-bit key + Serial = 49 43 57 69 - Serial number of the tag, transmitted in clear + Random = 65 6E 45 72 - Random IV, transmitted in clear + ~28~DC~80~31 = D7 23 7F CE - Authenticator value = inverted first 4 bytes of the keystream + + The code below must print out "D7 23 7F CE 8C D0 37 A9 57 49 C1 E6 48 00 8A B6". + The inverse of the first 4 bytes is sent to the tag to authenticate. + The rest is encrypted by XORing it with the subsequent keystream. + +*/ + + +/* +unsigned int hitag2_benchtest_gen32() +{ + const uint64_t key = 0x4ad292b272f2; + const uint32_t serial = 0x96eac292; + const uint32_t initvec = 0x4ea276a6; + Hitag_State state; + + // init crypto + hitag2_init(&state, key, serial, initvec); + + // benchmark: generation of 32 bit stream (excludes initialisation) + GetTimer_us(RESET); + + (void) hitag2_nstep(&state, 32); + + return GetTimer_us(NO_RESET); +} + + +unsigned int hitag2_benchtest(uint32_t count) +{ + const uint64_t key = 0x4ad292b272f2; + const uint32_t serial = 0x96eac292; + const uint32_t initvec = 0x4ea276a6; + Hitag_State state; + uint32_t i; + + // start timer + GetTimer_us(RESET); + + // benchmark: initialise crypto & generate 32 bit authentication + // adding i stops gcc optimizer moving init function call out of loop + for (i = 0; i < count; i++) { + hitag2_init(&state, key, serial, initvec + i); + (void) hitag2_nstep(&state, 32); + } + + return GetTimer_us(NO_RESET); +} + + +unsigned hitag2_verifytest() +{ + uint8_t expected[16] = { 0xD7, 0x23, 0x7F, 0xCE, 0x8C, 0xD0, 0x37, 0xA9, 0x57, 0x49, 0xC1, 0xE6, 0x48, 0x00, 0x8A, 0xB6 }; + // key = 0x4ad292b272f2 after each byte has its bit order reversed + // serial = 0x96eac292 ditto + // initvec = 0x4ea276a6 ditto + const uint64_t key = rev64 (0x524B494D4E4FUL); + const uint32_t serial = rev32 (0x69574349); + const uint32_t initvec = rev32 (0x72456E65); + + uint32_t i; + Hitag_State state; + + // initialise + hitag2_init(&state, key, serial, initvec); + + for (i = 0; i < 16; i++) { + // get 8 bits of keystream + uint8_t x = (uint8_t) hitag2_nstep(&state, 8); + uint8_t y = expected[i]; + + DEBUG_PRINTF ("%02X (%02X) \n", x, y); + if (x != y) + return 0; + } + + return 1; +} +*/ + +#ifdef UNIT_TEST + +int main(int argc, char* argv[]) +{ + unsigned pass = hitag2_verifytest(); + + printf ("Crypto Verify test = %s\n\n", pass ? "PASS" : "FAIL"); + + if (pass) { + hitag2_benchtest(10000); + } + + return 0; +} + +#endif // UNIT_TEST diff --git a/tools/hitag2crack/crack3/hitagcrypto.h b/tools/hitag2crack/crack3/hitagcrypto.h new file mode 100644 index 000000000..d5aa9104c --- /dev/null +++ b/tools/hitag2crack/crack3/hitagcrypto.h @@ -0,0 +1,171 @@ +/*************************************************************************** + * A copy of the GNU GPL is appended to this file. * + * * + * This licence is based on the nmap licence, and we express our gratitude * + * for the work that went into producing it. There is no other connection * + * between RFIDler and nmap either expressed or implied. * + * * + ********************** IMPORTANT RFIDler LICENSE TERMS ******************** + * * + * * + * All references to RFIDler herein imply all it's derivatives, namely: * + * * + * o RFIDler-LF Standard * + * o RFIDler-LF Lite * + * o RFIDler-LF Nekkid * + * * + * * + * RFIDler is (C) 2013-2014 Aperture Labs Ltd. * + * * + * This program is free software; you may redistribute and/or modify it * + * under the terms of the GNU General Public License as published by the * + * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE * + * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your * + * right to use, modify, and redistribute this software under certain * + * conditions. If you wish to embed RFIDler technology into proprietary * + * software or hardware, we sell alternative licenses * + * (contact sales@aperturelabs.com). * + * * + * Note that the GPL places important restrictions on "derivative works", * + * yet it does not provide a detailed definition of that term. To avoid * + * misunderstandings, we interpret that term as broadly as copyright law * + * allows. For example, we consider an application to constitute a * + * derivative work for the purpose of this license if it does any of the * + * following with any software or content covered by this license * + * ("Covered Software"): * + * * + * o Integrates source code from Covered Software. * + * * + * o Is designed specifically to execute Covered Software and parse the * + * results (as opposed to typical shell or execution-menu apps, which will * + * execute anything you tell them to). * + * * + * o Includes Covered Software in a proprietary executable installer. The * + * installers produced by InstallShield are an example of this. Including * + * RFIDler with other software in compressed or archival form does not * + * trigger this provision, provided appropriate open source decompression * + * or de-archiving software is widely available for no charge. For the * + * purposes of this license, an installer is considered to include Covered * + * Software even if it actually retrieves a copy of Covered Software from * + * another source during runtime (such as by downloading it from the * + * Internet). * + * * + * o Links (statically or dynamically) to a library which does any of the * + * above. * + * * + * o Executes a helper program, module, or script to do any of the above. * + * * + * This list is not exclusive, but is meant to clarify our interpretation * + * of derived works with some common examples. Other people may interpret * + * the plain GPL differently, so we consider this a special exception to * + * the GPL that we apply to Covered Software. Works which meet any of * + * these conditions must conform to all of the terms of this license, * + * particularly including the GPL Section 3 requirements of providing * + * source code and allowing free redistribution of the work as a whole. * + * * + * As another special exception to the GPL terms, Aperture Labs Ltd. grants* + * permission to link the code of this program with any version of the * + * OpenSSL library which is distributed under a license identical to that * + * listed in the included docs/licenses/OpenSSL.txt file, and distribute * + * linked combinations including the two. * + * * + * Any redistribution of Covered Software, including any derived works, * + * must obey and carry forward all of the terms of this license, including * + * obeying all GPL rules and restrictions. For example, source code of * + * the whole work must be provided and free redistribution must be * + * allowed. All GPL references to "this License", are to be treated as * + * including the terms and conditions of this license text as well. * + * * + * Because this license imposes special exceptions to the GPL, Covered * + * Work may not be combined (even as part of a larger work) with plain GPL * + * software. The terms, conditions, and exceptions of this license must * + * be included as well. This license is incompatible with some other open * + * source licenses as well. In some cases we can relicense portions of * + * RFIDler or grant special permissions to use it in other open source * + * software. Please contact sales@aperturelabs.com with any such requests.* + * Similarly, we don't incorporate incompatible open source software into * + * Covered Software without special permission from the copyright holders. * + * * + * If you have any questions about the licensing restrictions on using * + * RFIDler in other works, are happy to help. As mentioned above, we also * + * offer alternative license to integrate RFIDler into proprietary * + * applications and appliances. These contracts have been sold to dozens * + * of software vendors, and generally include a perpetual license as well * + * as providing for priority support and updates. They also fund the * + * continued development of RFIDler. Please email sales@aperturelabs.com * + * for further information. * + * If you have received a written license agreement or contract for * + * Covered Software stating terms other than these, you may choose to use * + * and redistribute Covered Software under those terms instead of these. * + * * + * Source is provided to this software because we believe users have a * + * right to know exactly what a program is going to do before they run it. * + * This also allows you to audit the software for security holes (none * + * have been found so far). * + * * + * Source code also allows you to port RFIDler to new platforms, fix bugs, * + * and add new features. You are highly encouraged to send your changes * + * to the RFIDler mailing list for possible incorporation into the * + * main distribution. By sending these changes to Aperture Labs Ltd. or * + * one of the Aperture Labs Ltd. development mailing lists, or checking * + * them into the RFIDler source code repository, it is understood (unless * + * you specify otherwise) that you are offering the RFIDler Project * + * (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, * + * modify, and relicense the code. RFIDler will always be available Open * + * Source, but this is important because the inability to relicense code * + * has caused devastating problems for other Free Software projects (such * + * as KDE and NASM). We also occasionally relicense the code to third * + * parties as discussed above. If you wish to specify special license * + * conditions of your contributions, just say so when you send them. * + * * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler * + * license file for more details (it's in a COPYING file included with * + * RFIDler, and also available from * + * https://github.com/ApertureLabsLtd/RFIDler/COPYING * + * * + ***************************************************************************/ + +// Author: unknown. +// Modifications for RFIDler: Tony Naggs , Adam Laurie + + +#ifndef HITAGCRYPTO_H +#define HITAGCRYPTO_H + +#include + +/* + Our model of Hitag 2 crypto uses 2 parallel shift registers: + a. 48 bit Feedback Shift Register, required for inputs to the nonlinear function. + b. 48 bit Linear Feedback Shift Register (LFSR). + A transform of initial register (a) value, which is then run in parallel. + Enables much faster calculation of the feedback values. + + API: + void hitag2_init(Hitag_State* pstate, uint64_t sharedkey, uint32_t serialnum, + uint32_t initvector); + Initialise state from 48 bit shared (secret) reader/tag key, + 32 bit tag serial number and 32 bit initialisation vector from reader. + + uint32_t hitag2_nstep(Hitag_State* pstate, uint32_t steps); + update shift register state and generate N cipher bits (N should be <= 32) + */ + + +typedef struct { + uint64_t shiftreg; // naive shift register, required for nonlinear fn input + uint64_t lfsr; // fast lfsr, used to make software faster +} Hitag_State; + +void hitag2_init(Hitag_State* pstate, uint64_t sharedkey, uint32_t serialnum, uint32_t initvector); + +uint32_t hitag2_nstep(Hitag_State* pstate, uint32_t steps); + +unsigned int hitag2_benchtest_gen32(); +unsigned int hitag2_benchtest(uint32_t count); +unsigned hitag2_verifytest(); + +#endif /* HITAGCRYPTO_H */ + diff --git a/tools/hitag2crack/crack3/ht2crack3.c b/tools/hitag2crack/crack3/ht2crack3.c new file mode 100644 index 000000000..190f8197d --- /dev/null +++ b/tools/hitag2crack/crack3/ht2crack3.c @@ -0,0 +1,466 @@ +#include +#include +#include + +#include "HardwareProfile.h" +#include "rfidler.h" +#include "hitagcrypto.h" +#include "util.h" + +// max number of NrAr pairs to load - you only need 136 good pairs, but this +// is the max +#define NUM_NRAR 1024 +#define NUM_THREADS 8 + +// table entry for Tkleft +struct Tklower { + uint64_t yxorb; + char notb32; + uint64_t klowery; +}; + +// table entry for nR aR pair +struct nRaR { + uint64_t nR; + uint64_t aR; +}; + +// struct to hold data for thread +struct threaddata { + uint64_t uid; + struct nRaR *TnRaR; + unsigned int numnrar; + uint64_t klowerstart; + uint64_t klowerrange; +}; + +void printbin(uint64_t val) +{ + int i; + + for (i=0; i<64; i++) { + if (val & 0x8000000000000000) { + printf("1"); + } else { + printf("0"); + } + val = val << 1; + } +} + +void printstate(Hitag_State *hstate) +{ + printf("shiftreg =\t"); + printbin(hstate->shiftreg); + printf("\n"); +} + + + +// macros to pick out 4 bits in various patterns of 1s & 2s & make a new number +// these and the following hitag2_crypt function taken from Rfidler +#define pickbits2_2(S, A, B) ( ((S >> A) & 3) | ((S >> (B - 2)) & 0xC) ) +#define pickbits1x4(S, A, B, C, D) ( ((S >> A) & 1) | ((S >> (B - 1)) & 2) | \ + ((S >> (C - 2)) & 4) | ((S >> (D - 3)) & 8) ) +#define pickbits1_1_2(S, A, B, C) ( ((S >> A) & 1) | ((S >> (B - 1)) & 2) | \ + ((S >> (C - 2)) & 0xC) ) +#define pickbits2_1_1(S, A, B, C) ( ((S >> A) & 3) | ((S >> (B - 2)) & 4) | \ + ((S >> (C - 3)) & 8) ) +#define pickbits1_2_1(S, A, B, C) ( ((S >> A) & 1) | ((S >> (B - 1)) & 6) | \ + ((S >> (C - 3)) & 8) ) + + +static uint32_t hitag2_crypt(uint64_t s) +{ + const uint32_t ht2_function4a = 0x2C79; // 0010 1100 0111 1001 + const uint32_t ht2_function4b = 0x6671; // 0110 0110 0111 0001 + const uint32_t ht2_function5c = 0x7907287B; // 0111 1001 0000 0111 0010 1000 0111 1011 + uint32_t bitindex; + + bitindex = (ht2_function4a >> pickbits2_2 (s, 1, 4)) & 1; + bitindex |= ((ht2_function4b << 1) >> pickbits1_1_2 (s, 7, 11, 13)) & 0x02; + bitindex |= ((ht2_function4b << 2) >> pickbits1x4 (s, 16, 20, 22, 25)) & 0x04; + bitindex |= ((ht2_function4b << 3) >> pickbits2_1_1 (s, 27, 30, 32)) & 0x08; + bitindex |= ((ht2_function4a << 4) >> pickbits1_2_1(s, 33, 42, 45)) & 0x10; + + return (ht2_function5c >> bitindex) & 1; +} + + +// this function is a modification of the filter function f, based heavily +// on the hitag2_crypt function in Rfidler +int fnP(uint64_t klowery) +{ + const uint32_t ht2_function4a = 0x2C79; // 0010 1100 0111 1001 + const uint32_t ht2_function4b = 0x6671; // 0110 0110 0111 0001 + const uint32_t ht2_function4p = 0xAE83; // 1010 1110 1000 0011 + uint32_t i; + + i = (ht2_function4a >> pickbits2_2 (klowery, 2, 5)) & 1; + i |= ((ht2_function4b << 1) >> pickbits1_1_2 (klowery, 8, 12, 14)) & 0x02; + i |= ((ht2_function4b << 2) >> pickbits1x4 (klowery, 17, 21, 23, 26)) & 0x04; + i |= ((ht2_function4b << 3) >> pickbits2_1_1 (klowery, 28, 31, 33)) & 0x08; + + // modified to use reference implementation approach + // orig fc table is 0x7907287B = 0111 1001 0000 0111 0010 1000 0111 1011 + // we ignore the top bit (bit 4) of the parameter, so therefore create a new + // table that indicates which bit positions are the same if the top bit is 1 or 0 + return (ht2_function4p >> i) & 1; +} + +// comparison function for sorting/searching Tklower entries +int Tk_cmp(const void *v1, const void *v2) +{ + const struct Tklower *Tk1 = (struct Tklower *)v1; + const struct Tklower *Tk2 = (struct Tklower *)v2; + + if (Tk1->yxorb < Tk2->yxorb) { + return -1; + } else if (Tk1->yxorb > Tk2->yxorb) { + return 1; + } + + return 0; +} + +// test for bad guesses of kmiddle +int is_kmiddle_badguess(uint64_t z, struct Tklower *Tk, int max, int aR0) { + + struct Tklower *result, target; + + // "If there is an entry in Tklower for which y ^ b = z but !b32 != aR[0] + // then the attacker learns that kmiddle is a bad guess... otherwise, if + // !b32 == aR[0] then kmiddle is still a viable guess." + + target.yxorb = z; + target.notb32 = 0; + result = (struct Tklower *)bsearch(&target, Tk, max, sizeof(struct Tklower), Tk_cmp); + + if (result) { + if (result->notb32 != aR0) { + return 1; + } + } else { + return 2; + } + + return 0; +} + +// function to test if a partial key is valid +int testkey(uint64_t *out, uint64_t uid, uint64_t pkey, uint64_t nR, uint64_t aR) +{ + uint64_t kupper; + uint64_t key; + Hitag_State hstate; + uint64_t b; + uint32_t revaR; + uint32_t normaR; + + // normalise aR + revaR = rev32(aR); + normaR = ((revaR >> 24) | ((revaR >> 8) & 0xff00) | ((revaR << 8) & 0xff0000) | (revaR << 24)); + + // search for remaining 14 bits + for (kupper=0; kupper < 0x3fff; kupper++) { + key = (kupper << 34) | pkey; + hitag2_init(&hstate, key, uid, nR); + b = hitag2_nstep(&hstate, 32); + if ((normaR ^ b) == 0xffffffff) { + *out = key; + return 1; + } + } + return 0; +} + + + + + + + +// some notes on how I think this attack should work. +// due to the way fc works, in a number of cases, it doesn't matter what +// the most significant bits are doing for it to produce the same result. +// These are the most sig 14 bits to be clear. Looking at fc it is poss +// to see cases where the most sig bit of the input to fc (which is made +// from fa on 4 of the most sig bits from bit 34 onwards) does not affect +// whether it gives a 0 or 1 as the input 0b0ABCD gives the same bit value +// as input 0b1ABCD. +// The PRNG is initialised by setting the lower 32 bits to the UID, with +// the upper 16 bits set to the lower 16 bits of the key. Next the 32 +// upper bits of the key are XORed with the private nonce and these are +// shifted in, with the PRNG outputting bits b0 to b31. These bits are +// used to encrypt (XOR with) the nonce to produce nR, which is sent to +// the card. +// (The card should init the PRNG with the same UID and lower 16 bits of +// the key, receive the nR, then shift it in bit by bit while xoring each +// bit with its output, and the key - this essentially decrypts the nR to +// the nonce XOR the upper 32 bits of the key, while shifting it in. +// The card's PRNG will then be in the same state as the RWD.) +// By knowing the UID and guessing the lower 16 bits of the key, and +// focusing on nR values that don't affect the upper bits of fc, we can +// limit our guesses to a smaller set than a full brute force and +// effectively work out candidates for the lower 34 bits of the key. + + +void *crack(void *d) +{ + struct threaddata *data = (struct threaddata *)d; + uint64_t uid; + struct nRaR *TnRaR; + unsigned int numnrar; + + Hitag_State hstate; + int i, j; + + uint64_t klower; + uint64_t kmiddle; + uint64_t y; + uint64_t ytmp; + uint64_t klowery; + unsigned int count = 0; + uint64_t bit; + uint64_t b; + uint64_t z; + uint64_t foundkey; + uint64_t revkey; + int ret; + unsigned int found = 0; + unsigned int badguess = 0; + + struct Tklower *Tk = NULL; + + if (!data) { + printf("Thread data is NULL\n"); + exit(1); + } + + uid = data->uid; + TnRaR = data->TnRaR; + numnrar = data->numnrar; + + // create space for tables + Tk = (struct Tklower *)malloc(sizeof(struct Tklower) * 0x40000); + if (!Tk) { + printf("cannot malloc Tk\n"); + exit(1); + } + + // find keys + for (klower=data->klowerstart; klower < (data->klowerstart + data->klowerrange); klower++) { + printf("trying klower = 0x%05lx\n", klower); + // build table + count = 0; + for (y=0; y<0x40000; y++) { + // create klowery + klowery = (y << 16) | klower; + // check for cases where right most bit of fc doesn't matter + + if (fnP(klowery)) { + // store klowery + Tk[count].klowery = klowery; + // build the initial prng state + hstate.shiftreg = (klower << 32) | uid; + // zero the lfsr so only 0s are inserted + hstate.lfsr = 0; + // insert y into shiftreg and extract keystream, reversed order + b = 0; + ytmp = y; + for (j=0; j<2; j++) { + hstate.shiftreg = hstate.shiftreg | ((ytmp & 0xffff) << 48); + for (i=0; i<16; i++) { + hstate.shiftreg = hstate.shiftreg >> 1; + bit = hitag2_crypt(hstate.shiftreg); + b = (b >> 1) | (bit << 31); + } + ytmp = ytmp >> 16; + } + + // store the xor of y and b0-17 + Tk[count].yxorb = y ^ (b & 0x3ffff); + + // get and store inverse of next bit from prng + // don't need to worry about shifting in the new bit because + // it doesn't affect the filter function anyway + hstate.shiftreg = hstate.shiftreg >> 1; + Tk[count].notb32 = hitag2_crypt(hstate.shiftreg) ^ 0x1; + + // increase count + count++; + } + } + + qsort(Tk, count, sizeof(struct Tklower), Tk_cmp); + + // look for matches + for (kmiddle=0; kmiddle<0x40000; kmiddle++) { + // loop over nRaR pairs + badguess = 0; + found = 0; + for (i=0; (i> 40) & 0xff) | ((revkey >> 24) & 0xff00) | ((revkey >> 8) & 0xff0000) | ((revkey << 8) & 0xff000000) | ((revkey << 24) & 0xff00000000) | ((revkey << 40) & 0xff0000000000); + printf("\n\nSuccess - key = %012lX\n", foundkey); + exit(0); + + return (void *)foundkey; + } + + } + + } + } + + return NULL; +} +int main(int argc, char *argv[]) +{ + FILE *fp; + int i; + pthread_t threads[NUM_THREADS]; + void *status; + + uint64_t uid; + uint64_t klowerstart; + unsigned int numnrar = 0; + char *buf = NULL; + char *buft1 = NULL; + char *buft2 = NULL; + size_t lenbuf = 64; + + struct nRaR *TnRaR = NULL; + struct threaddata *tdata = NULL; + + if (argc < 3) { + printf("ht2crack3 uid nRaRfile\n"); + exit(1); + } + + // read the UID into internal format + if (!strncmp(argv[1], "0x", 2)) { + uid = rev32(hexreversetoulong(argv[1] + 2)); + } else { + uid = rev32(hexreversetoulong(argv[1])); + } + + // create table of nR aR pairs + TnRaR = (struct nRaR *)malloc(sizeof(struct nRaR) * NUM_NRAR); + + // open file + fp = fopen(argv[2], "r"); + if (!fp) { + printf("cannot open nRaRfile\n"); + exit(1); + } + + // set klowerstart (for debugging) + if (argc > 3) { + klowerstart = strtol(argv[3], NULL, 0); + } else { + klowerstart = 0; + } + + // read in nR aR pairs + numnrar = 0; + buf = (char *)malloc(lenbuf); + if (!buf) { + printf("cannot malloc buf\n"); + exit(1); + } + + while (getline(&buf, &lenbuf, fp) > 0) { + buft1 = strchr(buf, ' '); + if (!buft1) { + printf("invalid file input on line %d\n", numnrar + 1); + exit(1); + } + *buft1 = 0x00; + buft1++; + buft2 = strchr(buft1, '\n'); + if (!buft2) { + printf("no CR on line %d\n", numnrar + 1); + exit(1); + } + *buft2 = 0x00; + if (!strncmp(buf, "0x", 2)) { + TnRaR[numnrar].nR = rev32(hexreversetoulong(buf+2)); + TnRaR[numnrar].aR = rev32(hexreversetoulong(buft1+2)); + } else { + TnRaR[numnrar].nR = rev32(hexreversetoulong(buf)); + TnRaR[numnrar].aR = rev32(hexreversetoulong(buft1)); + } + numnrar++; + } + + // close file + fclose(fp); + fp = NULL; + + printf("Loaded %d NrAr pairs\n", numnrar); + + // create table of thread data + tdata = (struct threaddata *)malloc(sizeof(struct threaddata) * NUM_THREADS); + if (!tdata) { + printf("cannot malloc threaddata\n"); + exit(1); + } + + for (i=0; i +#include + + +#include "HardwareProfile.h" +#include "rfidler.h" +#include "hitagcrypto.h" +#include "util.h" + + + +int main(int argc, char *argv[]) +{ + Hitag_State hstate; + FILE *fp; + char *line = NULL; + size_t linelen = 0; + long len = 0; + char *nr = NULL; + char *ar = NULL; + uint32_t arval; + uint32_t ks; + char *key; + char *uid; + + if (argc < 4) { + printf("ht2test nRaRfile KEY UID\n"); + exit(1); + } + + fp = fopen(argv[1], "r"); + if (!fp) { + printf("cannot open file\n"); + exit(1); + } + + if (!strncmp(argv[2], "0x", 2)) { + key = argv[2] + 2; + } else { + key = argv[2]; + } + + if (!strncmp(argv[3], "0x", 2)) { + uid = argv[3] + 2; + } else { + uid = argv[3]; + } + + while ((len = getline(&line, &linelen, fp)) > 0) { + if (len > 16) { + ar = strchr(line, ' '); + *ar = 0x00; + ar++; + ar[strlen(ar)-1] = 0x00; + if (!strncmp(line, "0x", 2)) { + nr = line + 2; + } else { + nr = line; + } + hitag2_init(&hstate, rev64(hexreversetoulonglong(key)), rev32(hexreversetoulong(uid)), rev32(hexreversetoulong(nr))); + + arval = strtol(ar, NULL, 16); + ks = hitag2_nstep(&hstate, 32); + + + if ((arval ^ ks) != 0xffffffff) { + printf("FAIL! nR = %s, aR = %s\n", line, ar); + } else { + printf("SUCCESS! nR = %s, aR = %s\n", line, ar); + } + } + } + + fclose(fp); + + return 0; +} + diff --git a/tools/hitag2crack/crack3/readme.md b/tools/hitag2crack/crack3/readme.md new file mode 100644 index 000000000..4d35ad7e0 --- /dev/null +++ b/tools/hitag2crack/crack3/readme.md @@ -0,0 +1,35 @@ +ht2crack3 + + + +Build +----- + +make clean +make + + +Run +--- + +You'll need a file consisting of 136 (or more) nR aR pairs. These are the +encrypted nonces and challenge response values. They should be in hex with +one pair per line, e.g.: +0x12345678 0x9abcdef0 + +./ht2crack3 UID NRARFILE + +UID is the UID of the tag that you used to gather the nR aR values. +NRARFILE is the file containing the nR aR values. + + +Tests +----- + +If you happen to know the key and want to check that all your nR aR values +are valid (for high-powered demonstrations only, really) then you can use +the ht2test program to check them. It's otherwise massively pointless and a +complete waste of space. + +./ht2test NRARFILE KEY UID + diff --git a/tools/hitag2crack/crack3/rfidler.h b/tools/hitag2crack/crack3/rfidler.h new file mode 100644 index 000000000..c8ce90396 --- /dev/null +++ b/tools/hitag2crack/crack3/rfidler.h @@ -0,0 +1,412 @@ +/*************************************************************************** + * A copy of the GNU GPL is appended to this file. * + * * + * This licence is based on the nmap licence, and we express our gratitude * + * for the work that went into producing it. There is no other connection * + * between RFIDler and nmap either expressed or implied. * + * * + ********************** IMPORTANT RFIDler LICENSE TERMS ******************** + * * + * * + * All references to RFIDler herein imply all it's derivatives, namely: * + * * + * o RFIDler-LF Standard * + * o RFIDler-LF Lite * + * o RFIDler-LF Nekkid * + * * + * * + * RFIDler is (C) 2013-2015 Aperture Labs Ltd. * + * * + * This program is free software; you may redistribute and/or modify it * + * under the terms of the GNU General Public License as published by the * + * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE * + * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your * + * right to use, modify, and redistribute this software under certain * + * conditions. If you wish to embed RFIDler technology into proprietary * + * software or hardware, we sell alternative licenses * + * (contact sales@aperturelabs.com). * + * * + * Note that the GPL places important restrictions on "derivative works", * + * yet it does not provide a detailed definition of that term. To avoid * + * misunderstandings, we interpret that term as broadly as copyright law * + * allows. For example, we consider an application to constitute a * + * derivative work for the purpose of this license if it does any of the * + * following with any software or content covered by this license * + * ("Covered Software"): * + * * + * o Integrates source code from Covered Software. * + * * + * o Is designed specifically to execute Covered Software and parse the * + * results (as opposed to typical shell or execution-menu apps, which will * + * execute anything you tell them to). * + * * + * o Includes Covered Software in a proprietary executable installer. The * + * installers produced by InstallShield are an example of this. Including * + * RFIDler with other software in compressed or archival form does not * + * trigger this provision, provided appropriate open source decompression * + * or de-archiving software is widely available for no charge. For the * + * purposes of this license, an installer is considered to include Covered * + * Software even if it actually retrieves a copy of Covered Software from * + * another source during runtime (such as by downloading it from the * + * Internet). * + * * + * o Links (statically or dynamically) to a library which does any of the * + * above. * + * * + * o Executes a helper program, module, or script to do any of the above. * + * * + * This list is not exclusive, but is meant to clarify our interpretation * + * of derived works with some common examples. Other people may interpret * + * the plain GPL differently, so we consider this a special exception to * + * the GPL that we apply to Covered Software. Works which meet any of * + * these conditions must conform to all of the terms of this license, * + * particularly including the GPL Section 3 requirements of providing * + * source code and allowing free redistribution of the work as a whole. * + * * + * As another special exception to the GPL terms, Aperture Labs Ltd. grants* + * permission to link the code of this program with any version of the * + * OpenSSL library which is distributed under a license identical to that * + * listed in the included docs/licenses/OpenSSL.txt file, and distribute * + * linked combinations including the two. * + * * + * Any redistribution of Covered Software, including any derived works, * + * must obey and carry forward all of the terms of this license, including * + * obeying all GPL rules and restrictions. For example, source code of * + * the whole work must be provided and free redistribution must be * + * allowed. All GPL references to "this License", are to be treated as * + * including the terms and conditions of this license text as well. * + * * + * Because this license imposes special exceptions to the GPL, Covered * + * Work may not be combined (even as part of a larger work) with plain GPL * + * software. The terms, conditions, and exceptions of this license must * + * be included as well. This license is incompatible with some other open * + * source licenses as well. In some cases we can relicense portions of * + * RFIDler or grant special permissions to use it in other open source * + * software. Please contact sales@aperturelabs.com with any such requests.* + * Similarly, we don't incorporate incompatible open source software into * + * Covered Software without special permission from the copyright holders. * + * * + * If you have any questions about the licensing restrictions on using * + * RFIDler in other works, are happy to help. As mentioned above, we also * + * offer alternative license to integrate RFIDler into proprietary * + * applications and appliances. These contracts have been sold to dozens * + * of software vendors, and generally include a perpetual license as well * + * as providing for priority support and updates. They also fund the * + * continued development of RFIDler. Please email sales@aperturelabs.com * + * for further information. * + * If you have received a written license agreement or contract for * + * Covered Software stating terms other than these, you may choose to use * + * and redistribute Covered Software under those terms instead of these. * + * * + * Source is provided to this software because we believe users have a * + * right to know exactly what a program is going to do before they run it. * + * This also allows you to audit the software for security holes (none * + * have been found so far). * + * * + * Source code also allows you to port RFIDler to new platforms, fix bugs, * + * and add new features. You are highly encouraged to send your changes * + * to the RFIDler mailing list for possible incorporation into the * + * main distribution. By sending these changes to Aperture Labs Ltd. or * + * one of the Aperture Labs Ltd. development mailing lists, or checking * + * them into the RFIDler source code repository, it is understood (unless * + * you specify otherwise) that you are offering the RFIDler Project * + * (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, * + * modify, and relicense the code. RFIDler will always be available Open * + * Source, but this is important because the inability to relicense code * + * has caused devastating problems for other Free Software projects (such * + * as KDE and NASM). We also occasionally relicense the code to third * + * parties as discussed above. If you wish to specify special license * + * conditions of your contributions, just say so when you send them. * + * * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler * + * license file for more details (it's in a COPYING file included with * + * RFIDler, and also available from * + * https://github.com/ApertureLabsLtd/RFIDler/COPYING * + * * + ***************************************************************************/ + +// Author: Adam Laurie + +#include +#include + +// BCD hardware revision for usb descriptor (usb_descriptors.c) +#define RFIDLER_HW_VERSION 0x020 + +// max sizes in BITS +#define MAXBLOCKSIZE 512 +#define MAXTAGSIZE 4096 +#define MAXUID 512 + +#define TMP_LARGE_BUFF_LEN 2048 +#define TMP_SMALL_BUFF_LEN 256 +#define ANALOGUE_BUFF_LEN 8192 + +#define COMMS_BUFFER_SIZE 128 + +#define DETECT_BUFFER_SIZE 512 + +#define SAMPLEMASK ~(BIT_1 | BIT_0) // mask to remove two bottom bits from analogue sample - we will then use those for reader & bit period + +// globals + +extern BOOL WiegandOutput; // Output wiegand data whenenver UID is read +extern BYTE *EMU_Reset_Data; // Pointer to full array of bits as bytes, stored as 0x00/0x01, '*' terminated +extern BYTE *EMU_Data; // Pointer to current location in EMU_Reset_Data +extern BYTE EMU_ThisBit; // The next data bit to transmit +extern BYTE EMU_SubCarrier_T0; // Number of Frame Clocks for sub-carrier '0' +extern BYTE EMU_SubCarrier_T1; // Number of Frame Clocks for sub-carrier '1' +extern unsigned int EMU_Repeat; // Number of times to transmit full data set +extern BOOL EMU_Background; // Emulate in the background until told to stop +extern unsigned int EMU_DataBitRate; // Number of Frame Clocks per bit +extern BYTE TmpBits[TMP_LARGE_BUFF_LEN]; // Shared scratchpad +extern BYTE ReaderPeriod; // Flag for sample display +extern unsigned char Comms_In_Buffer[COMMS_BUFFER_SIZE]; // USB/Serial buffer +extern BYTE Interface; // user interface - CLI or API +extern BYTE CommsChannel; // user comms channel - USB or UART +extern BOOL FakeRead; // flag for analogue sampler to signal it wants access to buffers during read +extern BOOL PWD_Mode; // is this tag password protected? +extern BYTE Password[9]; // 32 bits as HEX string set with LOGIN +extern unsigned int Led_Count; // LED status counter, also used for entropy +extern unsigned long Reader_Bit_Count; // Reader ISR bit counter +extern char Previous; // Reader ISR previous bit type + +// RWD (read/write device) coil state +extern BYTE RWD_State; // current state of RWD coil +extern unsigned int RWD_Fc; // field clock in uS +extern unsigned int RWD_Gap_Period; // length of command gaps in OC5 ticks +extern unsigned int RWD_Zero_Period; // length of '0' in OC5 ticks +extern unsigned int RWD_One_Period; // length of '1' in OC5 ticks +extern unsigned int RWD_Sleep_Period; // length of initial sleep to reset tag in OC5 ticks +extern unsigned int RWD_Wake_Period; // length required for tag to restart in OC5 ticks +extern unsigned int RWD_Wait_Switch_TX_RX; // length to wait when switching from TX to RX in OC5 ticks +extern unsigned int RWD_Wait_Switch_RX_TX; // length to wait when switching from RX to TX in OC5 ticks +extern unsigned int RWD_Post_Wait; // low level ISR wait period in OC5 ticks +extern unsigned int RWD_OC5_config; // Output Compare Module settings +extern unsigned int RWD_OC5_r; // Output Compare Module primary compare value +extern unsigned int RWD_OC5_rs; // Output Compare Module secondary compare value +extern BYTE RWD_Command_Buff[TMP_SMALL_BUFF_LEN]; // Command buffer, array of bits as bytes, stored as 0x00/0x01, '*' terminated +extern BYTE *RWD_Command_ThisBit; // Current command bit +extern BOOL Reader_ISR_State; // current state of reader ISR + +// NVM variables +// timings etc. that want to survive a reboot should go here +typedef struct { + BYTE Name[7]; // will be set to "RFIDler" so we can test for new device + BYTE AutoRun[128]; // optional command to run at startup + unsigned char TagType; + unsigned int PSK_Quality; + unsigned int Timeout; + unsigned int Wiegand_Pulse; + unsigned int Wiegand_Gap; + BOOL Wiegand_IdleState; + unsigned int FrameClock; + unsigned char Modulation; + unsigned int DataRate; + unsigned int DataRateSub0; + unsigned int DataRateSub1; + unsigned int DataBits; + unsigned int DataBlocks; + unsigned int BlockSize; + unsigned char SyncBits; + BYTE Sync[4]; + BOOL BiPhase; + BOOL Invert; + BOOL Manchester; + BOOL HalfDuplex; + unsigned int Repeat; + unsigned int PotLow; + unsigned int PotHigh; + unsigned int RWD_Gap_Period; + unsigned int RWD_Zero_Period; + unsigned int RWD_One_Period; + unsigned int RWD_Sleep_Period; + unsigned int RWD_Wake_Period; + unsigned int RWD_Wait_Switch_TX_RX; + unsigned int RWD_Wait_Switch_RX_TX; +} StoredConfig; + +// somewhere to store TAG data. this will be interpreted according to the TAG +// type. +typedef struct { + BYTE TagType; // raw tag type + BYTE EmulatedTagType; // tag type this tag is configured to emulate + BYTE UID[MAXUID + 1]; // Null-terminated HEX string + BYTE Data[MAXTAGSIZE]; // raw data + unsigned char DataBlocks; // number of blocks in Data field + unsigned int BlockSize; // blocksize in bits +} VirtualTag; + +extern StoredConfig RFIDlerConfig; +extern VirtualTag RFIDlerVTag; +extern BYTE TmpBuff[NVM_PAGE_SIZE]; +extern BYTE DataBuff[ANALOGUE_BUFF_LEN]; +extern unsigned int DataBuffCount; +extern const BYTE *ModulationSchemes[]; +extern const BYTE *OnOff[]; +extern const BYTE *HighLow[]; +extern const BYTE *TagTypes[]; + +// globals for ISRs +extern BYTE EmulationMode; +extern unsigned long HW_Bits; +extern BYTE HW_Skip_Bits; +extern unsigned int PSK_Min_Pulse; +extern BOOL PSK_Read_Error; +extern BOOL Manchester_Error; +extern BOOL SnifferMode; +extern unsigned int Clock_Tick_Counter; +extern BOOL Clock_Tick_Counter_Reset; + +// smart card lib +#define MAX_ATR_LEN (BYTE)33 +extern BYTE scCardATR[MAX_ATR_LEN]; +extern BYTE scATRLength; + +// RTC +extern rtccTime RTC_time; // time structure +extern rtccDate RTC_date; // date structure + +// digital pots +#define POTLOW_DEFAULT 100 +#define POTHIGH_DEFAULT 150 +#define DC_OFFSET 60 // analogue circuit DC offset (as close as we can get without using 2 LSB) +#define VOLTS_TO_POT 0.019607843F + +// RWD/clock states +#define RWD_STATE_INACTIVE 0 // RWD not in use +#define RWD_STATE_GO_TO_SLEEP 1 // RWD coil shutdown request +#define RWD_STATE_SLEEPING 2 // RWD coil shutdown for sleep period +#define RWD_STATE_WAKING 3 // RWD active for pre-determined period after reset +#define RWD_STATE_START_SEND 4 // RWD starting send of data +#define RWD_STATE_SENDING_GAP 5 // RWD sending a gap +#define RWD_STATE_SENDING_BIT 6 // RWD sending a data bit +#define RWD_STATE_POST_WAIT 7 // RWD finished sending data, now in forced wait period +#define RWD_STATE_ACTIVE 8 // RWD finished, now just clocking a carrier + +// reader ISR states +#define READER_STOPPED 0 // reader not in use +#define READER_IDLING 1 // reader ISR running to preserve timing, but not reading +#define READER_RUNNING 2 // reader reading bits + + +// user interface types +#define INTERFACE_API 0 +#define INTERFACE_CLI 1 + +// comms channel +#define COMMS_NONE 0 +#define COMMS_USB 1 +#define COMMS_UART 2 + +#define MAX_HISTORY 2 // disable most of history for now - memory issue + +// tag write retries +#define TAG_WRITE_RETRY 5 + +// modulation modes - uppdate ModulationSchemes[] in tags.c if you change this +#define MOD_MODE_NONE 0 +#define MOD_MODE_ASK_OOK 1 +#define MOD_MODE_FSK1 2 +#define MOD_MODE_FSK2 3 +#define MOD_MODE_PSK1 4 +#define MOD_MODE_PSK2 5 +#define MOD_MODE_PSK3 6 + +// TAG types - update TagTypes[] in tags.c if you add to this list +#define TAG_TYPE_NONE 0 +#define TAG_TYPE_ASK_RAW 1 +#define TAG_TYPE_FSK1_RAW 2 +#define TAG_TYPE_FSK2_RAW 3 +#define TAG_TYPE_PSK1_RAW 4 +#define TAG_TYPE_PSK2_RAW 5 +#define TAG_TYPE_PSK3_RAW 6 +#define TAG_TYPE_HITAG1 7 +#define TAG_TYPE_HITAG2 8 +#define TAG_TYPE_EM4X02 9 +#define TAG_TYPE_Q5 10 +#define TAG_TYPE_HID_26 11 +#define TAG_TYPE_INDALA_64 12 +#define TAG_TYPE_INDALA_224 13 +#define TAG_TYPE_UNIQUE 14 +#define TAG_TYPE_FDXB 15 +#define TAG_TYPE_T55X7 16 // same as Q5 but different timings and no modulation-defeat +#define TAG_TYPE_AWID_26 17 +#define TAG_TYPE_EM4X05 18 +#define TAG_TYPE_TAMAGOTCHI 19 +#define TAG_TYPE_HDX 20 // same underlying data as FDX-B, but different modulation & telegram + +// various + +#define BINARY 0 +#define HEX 1 + +#define NO_ADDRESS -1 + +#define ACK TRUE +#define NO_ACK FALSE + +#define BLOCK TRUE +#define NO_BLOCK FALSE + +#define DATA TRUE +#define NO_DATA FALSE + +#define DEBUG_PIN_ON HIGH +#define DEBUG_PIN_OFF LOW + +#define FAST FALSE +#define SLOW TRUE + +#define NO_TRIGGER 0 + +#define LOCK TRUE +#define NO_LOCK FALSE + +#define NFC_MODE TRUE +#define NO_NFC_MODE FALSE + +#define ONESHOT_READ TRUE +#define NO_ONESHOT_READ FALSE + +#define RESET TRUE +#define NO_RESET FALSE + +#define SHUTDOWN_CLOCK TRUE +#define NO_SHUTDOWN_CLOCK FALSE + +#define SYNC TRUE +#define NO_SYNC FALSE + +#define VERIFY TRUE +#define NO_VERIFY FALSE + +#define VOLATILE FALSE +#define NON_VOLATILE TRUE + +#define NEWLINE TRUE +#define NO_NEWLINE FALSE + +#define WAIT TRUE +#define NO_WAIT FALSE + +#define WIPER_HIGH 0 +#define WIPER_LOW 1 + +// conversion for time to ticks +#define US_TO_TICKS 1000000L +#define US_OVER_10_TO_TICKS 10000000L +#define US_OVER_100_TO_TICKS 100000000L +// we can't get down to this level on pic, but we want to standardise on timings, so for now we fudge it +#define CONVERT_TO_TICKS(x) ((x / 10) * (GetSystemClock() / US_OVER_10_TO_TICKS)) +#define CONVERT_TICKS_TO_US(x) (x / (GetSystemClock() / US_TO_TICKS)) +#define TIMER5_PRESCALER 16 +#define MAX_TIMER5_TICKS (65535 * TIMER5_PRESCALER) + +// other conversions + +// bits to hex digits +#define HEXDIGITS(x) (x / 4) +#define HEXTOBITS(x) (x * 4) diff --git a/tools/hitag2crack/crack3/util.h b/tools/hitag2crack/crack3/util.h new file mode 100644 index 000000000..c2399c37c --- /dev/null +++ b/tools/hitag2crack/crack3/util.h @@ -0,0 +1,147 @@ +/*************************************************************************** + * A copy of the GNU GPL is appended to this file. * + * * + * This licence is based on the nmap licence, and we express our gratitude * + * for the work that went into producing it. There is no other connection * + * between RFIDler and nmap either expressed or implied. * + * * + ********************** IMPORTANT RFIDler LICENSE TERMS ******************** + * * + * * + * All references to RFIDler herein imply all it's derivatives, namely: * + * * + * o RFIDler-LF Standard * + * o RFIDler-LF Lite * + * o RFIDler-LF Nekkid * + * * + * * + * RFIDler is (C) 2013-2015 Aperture Labs Ltd. * + * * + * This program is free software; you may redistribute and/or modify it * + * under the terms of the GNU General Public License as published by the * + * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE * + * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your * + * right to use, modify, and redistribute this software under certain * + * conditions. If you wish to embed RFIDler technology into proprietary * + * software or hardware, we sell alternative licenses * + * (contact sales@aperturelabs.com). * + * * + * Note that the GPL places important restrictions on "derivative works", * + * yet it does not provide a detailed definition of that term. To avoid * + * misunderstandings, we interpret that term as broadly as copyright law * + * allows. For example, we consider an application to constitute a * + * derivative work for the purpose of this license if it does any of the * + * following with any software or content covered by this license * + * ("Covered Software"): * + * * + * o Integrates source code from Covered Software. * + * * + * o Is designed specifically to execute Covered Software and parse the * + * results (as opposed to typical shell or execution-menu apps, which will * + * execute anything you tell them to). * + * * + * o Includes Covered Software in a proprietary executable installer. The * + * installers produced by InstallShield are an example of this. Including * + * RFIDler with other software in compressed or archival form does not * + * trigger this provision, provided appropriate open source decompression * + * or de-archiving software is widely available for no charge. For the * + * purposes of this license, an installer is considered to include Covered * + * Software even if it actually retrieves a copy of Covered Software from * + * another source during runtime (such as by downloading it from the * + * Internet). * + * * + * o Links (statically or dynamically) to a library which does any of the * + * above. * + * * + * o Executes a helper program, module, or script to do any of the above. * + * * + * This list is not exclusive, but is meant to clarify our interpretation * + * of derived works with some common examples. Other people may interpret * + * the plain GPL differently, so we consider this a special exception to * + * the GPL that we apply to Covered Software. Works which meet any of * + * these conditions must conform to all of the terms of this license, * + * particularly including the GPL Section 3 requirements of providing * + * source code and allowing free redistribution of the work as a whole. * + * * + * As another special exception to the GPL terms, Aperture Labs Ltd. grants* + * permission to link the code of this program with any version of the * + * OpenSSL library which is distributed under a license identical to that * + * listed in the included docs/licenses/OpenSSL.txt file, and distribute * + * linked combinations including the two. * + * * + * Any redistribution of Covered Software, including any derived works, * + * must obey and carry forward all of the terms of this license, including * + * obeying all GPL rules and restrictions. For example, source code of * + * the whole work must be provided and free redistribution must be * + * allowed. All GPL references to "this License", are to be treated as * + * including the terms and conditions of this license text as well. * + * * + * Because this license imposes special exceptions to the GPL, Covered * + * Work may not be combined (even as part of a larger work) with plain GPL * + * software. The terms, conditions, and exceptions of this license must * + * be included as well. This license is incompatible with some other open * + * source licenses as well. In some cases we can relicense portions of * + * RFIDler or grant special permissions to use it in other open source * + * software. Please contact sales@aperturelabs.com with any such requests.* + * Similarly, we don't incorporate incompatible open source software into * + * Covered Software without special permission from the copyright holders. * + * * + * If you have any questions about the licensing restrictions on using * + * RFIDler in other works, are happy to help. As mentioned above, we also * + * offer alternative license to integrate RFIDler into proprietary * + * applications and appliances. These contracts have been sold to dozens * + * of software vendors, and generally include a perpetual license as well * + * as providing for priority support and updates. They also fund the * + * continued development of RFIDler. Please email sales@aperturelabs.com * + * for further information. * + * If you have received a written license agreement or contract for * + * Covered Software stating terms other than these, you may choose to use * + * and redistribute Covered Software under those terms instead of these. * + * * + * Source is provided to this software because we believe users have a * + * right to know exactly what a program is going to do before they run it. * + * This also allows you to audit the software for security holes (none * + * have been found so far). * + * * + * Source code also allows you to port RFIDler to new platforms, fix bugs, * + * and add new features. You are highly encouraged to send your changes * + * to the RFIDler mailing list for possible incorporation into the * + * main distribution. By sending these changes to Aperture Labs Ltd. or * + * one of the Aperture Labs Ltd. development mailing lists, or checking * + * them into the RFIDler source code repository, it is understood (unless * + * you specify otherwise) that you are offering the RFIDler Project * + * (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, * + * modify, and relicense the code. RFIDler will always be available Open * + * Source, but this is important because the inability to relicense code * + * has caused devastating problems for other Free Software projects (such * + * as KDE and NASM). We also occasionally relicense the code to third * + * parties as discussed above. If you wish to specify special license * + * conditions of your contributions, just say so when you send them. * + * * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler * + * license file for more details (it's in a COPYING file included with * + * RFIDler, and also available from * + * https://github.com/ApertureLabsLtd/RFIDler/COPYING * + * * + ***************************************************************************/ + +// Author: Adam Laurie + +/* + * Hitag Crypto support macros + * These macros reverse the bit order in a byte, or *within* each byte of a + * 16 , 32 or 64 bit unsigned integer. (Not across the whole 16 etc bits.) + */ +#define rev8(X) ((((X) >> 7) &1) + (((X) >> 5) &2) + (((X) >> 3) &4) \ + + (((X) >> 1) &8) + (((X) << 1) &16) + (((X) << 3) &32) \ + + (((X) << 5) &64) + (((X) << 7) &128) ) +#define rev16(X) (rev8 (X) + (rev8 (X >> 8) << 8)) +#define rev32(X) (rev16(X) + (rev16(X >> 16) << 16)) +#define rev64(X) (rev32(X) + (rev32(X >> 32) << 32)) + + +unsigned long hexreversetoulong(BYTE *hex); +unsigned long long hexreversetoulonglong(BYTE *hex); + diff --git a/tools/hitag2crack/crack3/utilpart.c b/tools/hitag2crack/crack3/utilpart.c new file mode 100644 index 000000000..210853ec1 --- /dev/null +++ b/tools/hitag2crack/crack3/utilpart.c @@ -0,0 +1,183 @@ +/*************************************************************************** + * A copy of the GNU GPL is appended to this file. * + * * + * This licence is based on the nmap licence, and we express our gratitude * + * for the work that went into producing it. There is no other connection * + * between RFIDler and nmap either expressed or implied. * + * * + ********************** IMPORTANT RFIDler LICENSE TERMS ******************** + * * + * * + * All references to RFIDler herein imply all it's derivatives, namely: * + * * + * o RFIDler-LF Standard * + * o RFIDler-LF Lite * + * o RFIDler-LF Nekkid * + * * + * * + * RFIDler is (C) 2013-2014 Aperture Labs Ltd. * + * * + * This program is free software; you may redistribute and/or modify it * + * under the terms of the GNU General Public License as published by the * + * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE * + * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your * + * right to use, modify, and redistribute this software under certain * + * conditions. If you wish to embed RFIDler technology into proprietary * + * software or hardware, we sell alternative licenses * + * (contact sales@aperturelabs.com). * + * * + * Note that the GPL places important restrictions on "derivative works", * + * yet it does not provide a detailed definition of that term. To avoid * + * misunderstandings, we interpret that term as broadly as copyright law * + * allows. For example, we consider an application to constitute a * + * derivative work for the purpose of this license if it does any of the * + * following with any software or content covered by this license * + * ("Covered Software"): * + * * + * o Integrates source code from Covered Software. * + * * + * o Is designed specifically to execute Covered Software and parse the * + * results (as opposed to typical shell or execution-menu apps, which will * + * execute anything you tell them to). * + * * + * o Includes Covered Software in a proprietary executable installer. The * + * installers produced by InstallShield are an example of this. Including * + * RFIDler with other software in compressed or archival form does not * + * trigger this provision, provided appropriate open source decompression * + * or de-archiving software is widely available for no charge. For the * + * purposes of this license, an installer is considered to include Covered * + * Software even if it actually retrieves a copy of Covered Software from * + * another source during runtime (such as by downloading it from the * + * Internet). * + * * + * o Links (statically or dynamically) to a library which does any of the * + * above. * + * * + * o Executes a helper program, module, or script to do any of the above. * + * * + * This list is not exclusive, but is meant to clarify our interpretation * + * of derived works with some common examples. Other people may interpret * + * the plain GPL differently, so we consider this a special exception to * + * the GPL that we apply to Covered Software. Works which meet any of * + * these conditions must conform to all of the terms of this license, * + * particularly including the GPL Section 3 requirements of providing * + * source code and allowing free redistribution of the work as a whole. * + * * + * As another special exception to the GPL terms, Aperture Labs Ltd. grants* + * permission to link the code of this program with any version of the * + * OpenSSL library which is distributed under a license identical to that * + * listed in the included docs/licenses/OpenSSL.txt file, and distribute * + * linked combinations including the two. * + * * + * Any redistribution of Covered Software, including any derived works, * + * must obey and carry forward all of the terms of this license, including * + * obeying all GPL rules and restrictions. For example, source code of * + * the whole work must be provided and free redistribution must be * + * allowed. All GPL references to "this License", are to be treated as * + * including the terms and conditions of this license text as well. * + * * + * Because this license imposes special exceptions to the GPL, Covered * + * Work may not be combined (even as part of a larger work) with plain GPL * + * software. The terms, conditions, and exceptions of this license must * + * be included as well. This license is incompatible with some other open * + * source licenses as well. In some cases we can relicense portions of * + * RFIDler or grant special permissions to use it in other open source * + * software. Please contact sales@aperturelabs.com with any such requests.* + * Similarly, we don't incorporate incompatible open source software into * + * Covered Software without special permission from the copyright holders. * + * * + * If you have any questions about the licensing restrictions on using * + * RFIDler in other works, are happy to help. As mentioned above, we also * + * offer alternative license to integrate RFIDler into proprietary * + * applications and appliances. These contracts have been sold to dozens * + * of software vendors, and generally include a perpetual license as well * + * as providing for priority support and updates. They also fund the * + * continued development of RFIDler. Please email sales@aperturelabs.com * + * for further information. * + * If you have received a written license agreement or contract for * + * Covered Software stating terms other than these, you may choose to use * + * and redistribute Covered Software under those terms instead of these. * + * * + * Source is provided to this software because we believe users have a * + * right to know exactly what a program is going to do before they run it. * + * This also allows you to audit the software for security holes (none * + * have been found so far). * + * * + * Source code also allows you to port RFIDler to new platforms, fix bugs, * + * and add new features. You are highly encouraged to send your changes * + * to the RFIDler mailing list for possible incorporation into the * + * main distribution. By sending these changes to Aperture Labs Ltd. or * + * one of the Aperture Labs Ltd. development mailing lists, or checking * + * them into the RFIDler source code repository, it is understood (unless * + * you specify otherwise) that you are offering the RFIDler Project * + * (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, * + * modify, and relicense the code. RFIDler will always be available Open * + * Source, but this is important because the inability to relicense code * + * has caused devastating problems for other Free Software projects (such * + * as KDE and NASM). We also occasionally relicense the code to third * + * parties as discussed above. If you wish to specify special license * + * conditions of your contributions, just say so when you send them. * + * * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler * + * license file for more details (it's in a COPYING file included with * + * RFIDler, and also available from * + * https://github.com/ApertureLabsLtd/RFIDler/COPYING * + * * + ***************************************************************************/ + +// Author: Adam Laurie + + +#include +#include +#include "HardwareProfile.h" +#include "util.h" +#include "rfidler.h" +//#include "comms.h" + +// rtc +rtccTime RTC_time; // time structure +rtccDate RTC_date; // date structure + +// convert byte-reversed 8 digit hex to unsigned long +unsigned long hexreversetoulong(BYTE *hex) +{ + unsigned long ret= 0L; + unsigned int x; + BYTE i; + + if(strlen(hex) != 8) + return 0L; + + for(i= 0 ; i < 4 ; ++i) + { + if(sscanf(hex, "%2X", &x) != 1) + return 0L; + ret += ((unsigned long) x) << i * 8; + hex += 2; + } + return ret; +} + +// convert byte-reversed 12 digit hex to unsigned long +unsigned long long hexreversetoulonglong(BYTE *hex) +{ + unsigned long long ret= 0LL; + BYTE tmp[9]; + + // this may seem an odd way to do it, but weird compiler issues were + // breaking direct conversion! + + tmp[8]= '\0'; + memset(tmp + 4, '0', 4); + memcpy(tmp, hex + 8, 4); + ret= hexreversetoulong(tmp); + ret <<= 32; + memcpy(tmp, hex, 8); + ret += hexreversetoulong(tmp); + return ret; +} + + diff --git a/tools/hitag2crack/crack4/.gitignore b/tools/hitag2crack/crack4/.gitignore new file mode 100644 index 000000000..f7ca5917b --- /dev/null +++ b/tools/hitag2crack/crack4/.gitignore @@ -0,0 +1,3 @@ +ht2crack4 + +ht2crack4.exe diff --git a/tools/hitag2crack/crack4/HardwareProfile.h b/tools/hitag2crack/crack4/HardwareProfile.h new file mode 100644 index 000000000..a2f804be6 --- /dev/null +++ b/tools/hitag2crack/crack4/HardwareProfile.h @@ -0,0 +1,524 @@ +/*************************************************************************** + * A copy of the GNU GPL is appended to this file. * + * * + * This licence is based on the nmap licence, and we express our gratitude * + * for the work that went into producing it. There is no other connection * + * between RFIDler and nmap either expressed or implied. * + * * + ********************** IMPORTANT RFIDler LICENSE TERMS ******************** + * * + * * + * All references to RFIDler herein imply all it's derivatives, namely: * + * * + * o RFIDler-LF Standard * + * o RFIDler-LF Lite * + * o RFIDler-LF Nekkid * + * * + * * + * RFIDler is (C) 2013-2014 Aperture Labs Ltd. * + * * + * This program is free software; you may redistribute and/or modify it * + * under the terms of the GNU General Public License as published by the * + * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE * + * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your * + * right to use, modify, and redistribute this software under certain * + * conditions. If you wish to embed RFIDler technology into proprietary * + * software or hardware, we sell alternative licenses * + * (contact sales@aperturelabs.com). * + * * + * Note that the GPL places important restrictions on "derivative works", * + * yet it does not provide a detailed definition of that term. To avoid * + * misunderstandings, we interpret that term as broadly as copyright law * + * allows. For example, we consider an application to constitute a * + * derivative work for the purpose of this license if it does any of the * + * following with any software or content covered by this license * + * ("Covered Software"): * + * * + * o Integrates source code from Covered Software. * + * * + * o Is designed specifically to execute Covered Software and parse the * + * results (as opposed to typical shell or execution-menu apps, which will * + * execute anything you tell them to). * + * * + * o Includes Covered Software in a proprietary executable installer. The * + * installers produced by InstallShield are an example of this. Including * + * RFIDler with other software in compressed or archival form does not * + * trigger this provision, provided appropriate open source decompression * + * or de-archiving software is widely available for no charge. For the * + * purposes of this license, an installer is considered to include Covered * + * Software even if it actually retrieves a copy of Covered Software from * + * another source during runtime (such as by downloading it from the * + * Internet). * + * * + * o Links (statically or dynamically) to a library which does any of the * + * above. * + * * + * o Executes a helper program, module, or script to do any of the above. * + * * + * This list is not exclusive, but is meant to clarify our interpretation * + * of derived works with some common examples. Other people may interpret * + * the plain GPL differently, so we consider this a special exception to * + * the GPL that we apply to Covered Software. Works which meet any of * + * these conditions must conform to all of the terms of this license, * + * particularly including the GPL Section 3 requirements of providing * + * source code and allowing free redistribution of the work as a whole. * + * * + * As another special exception to the GPL terms, Aperture Labs Ltd. grants* + * permission to link the code of this program with any version of the * + * OpenSSL library which is distributed under a license identical to that * + * listed in the included docs/licenses/OpenSSL.txt file, and distribute * + * linked combinations including the two. * + * * + * Any redistribution of Covered Software, including any derived works, * + * must obey and carry forward all of the terms of this license, including * + * obeying all GPL rules and restrictions. For example, source code of * + * the whole work must be provided and free redistribution must be * + * allowed. All GPL references to "this License", are to be treated as * + * including the terms and conditions of this license text as well. * + * * + * Because this license imposes special exceptions to the GPL, Covered * + * Work may not be combined (even as part of a larger work) with plain GPL * + * software. The terms, conditions, and exceptions of this license must * + * be included as well. This license is incompatible with some other open * + * source licenses as well. In some cases we can relicense portions of * + * RFIDler or grant special permissions to use it in other open source * + * software. Please contact sales@aperturelabs.com with any such requests.* + * Similarly, we don't incorporate incompatible open source software into * + * Covered Software without special permission from the copyright holders. * + * * + * If you have any questions about the licensing restrictions on using * + * RFIDler in other works, are happy to help. As mentioned above, we also * + * offer alternative license to integrate RFIDler into proprietary * + * applications and appliances. These contracts have been sold to dozens * + * of software vendors, and generally include a perpetual license as well * + * as providing for priority support and updates. They also fund the * + * continued development of RFIDler. Please email sales@aperturelabs.com * + * for further information. * + * If you have received a written license agreement or contract for * + * Covered Software stating terms other than these, you may choose to use * + * and redistribute Covered Software under those terms instead of these. * + * * + * Source is provided to this software because we believe users have a * + * right to know exactly what a program is going to do before they run it. * + * This also allows you to audit the software for security holes (none * + * have been found so far). * + * * + * Source code also allows you to port RFIDler to new platforms, fix bugs, * + * and add new features. You are highly encouraged to send your changes * + * to the RFIDler mailing list for possible incorporation into the * + * main distribution. By sending these changes to Aperture Labs Ltd. or * + * one of the Aperture Labs Ltd. development mailing lists, or checking * + * them into the RFIDler source code repository, it is understood (unless * + * you specify otherwise) that you are offering the RFIDler Project * + * (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, * + * modify, and relicense the code. RFIDler will always be available Open * + * Source, but this is important because the inability to relicense code * + * has caused devastating problems for other Free Software projects (such * + * as KDE and NASM). We also occasionally relicense the code to third * + * parties as discussed above. If you wish to specify special license * + * conditions of your contributions, just say so when you send them. * + * * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler * + * license file for more details (it's in a COPYING file included with * + * RFIDler, and also available from * + * https://github.com/ApertureLabsLtd/RFIDler/COPYING * + * * + ***************************************************************************/ + +// Author: Adam Laurie + + + +#ifndef HARDWARE_PROFILE_UBW32_H +#define HARDWARE_PROFILE_UBW32_H + +//#include "plib.h" +typedef char BOOL; +typedef char BYTE; +typedef int rtccTime; +typedef int rtccDate; + + +#ifndef __PIC32MX__ + #define __PIC32MX__ +#endif + +#define GetSystemClock() (80000000ul) +#define GetPeripheralClock() (GetSystemClock()) +#define GetInstructionClock() (GetSystemClock()) + +//#define USE_SELF_POWER_SENSE_IO +#define tris_self_power TRISAbits.TRISA2 // Input +#define self_power 1 + +//#define USE_USB_BUS_SENSE_IO +#define tris_usb_bus_sense TRISBbits.TRISB5 // Input +#define USB_BUS_SENSE 1 + +// LEDs +#define mLED_1 LATEbits.LATE3 + +#define mLED_2 LATEbits.LATE2 +#define mLED_Comms mLED_2 + +#define mLED_3 LATEbits.LATE1 +#define mLED_Clock mLED_3 + +#define mLED_4 LATEbits.LATE0 +#define mLED_Emulate mLED_4 + +#define mLED_5 LATGbits.LATG6 +#define mLED_Read mLED_5 + +#define mLED_6 LATAbits.LATA15 +#define mLED_User mLED_6 + +#define mLED_7 LATDbits.LATD11 +#define mLED_Error mLED_7 + +// active low +#define mLED_ON 0 +#define mLED_OFF 1 + +#define mGetLED_1() mLED_1 +#define mGetLED_USB() mLED_1 +#define mGetLED_2() mLED_2 +#define mGetLED_Comms() mLED_2 +#define mGetLED_3() mLED_3 +#define mGetLED_Clock() mLED_3 +#define mGetLED_4() mLED_4 +#define mGetLED_Emulate() mLED_4 +#define mGetLED_5() mLED_5 +#define mGetLED_Read() mLED_5 +#define mGetLED_6() mLED_6 +#define mGetLED_User() mLED_6 +#define mGetLED_7() mLED_7 +#define mGetLED_Error() mLED_7 + +#define mLED_1_On() mLED_1 = mLED_ON +#define mLED_USB_On() mLED_1_On() +#define mLED_2_On() mLED_2 = mLED_ON +#define mLED_Comms_On() mLED_2_On() +#define mLED_3_On() mLED_3 = mLED_ON +#define mLED_Clock_On() mLED_3_On() +#define mLED_4_On() mLED_4 = mLED_ON +#define mLED_Emulate_On() mLED_4_On() +#define mLED_5_On() mLED_5 = mLED_ON +#define mLED_Read_On() mLED_5_On() +#define mLED_6_On() mLED_6 = mLED_ON +#define mLED_User_On() mLED_6_On() +#define mLED_7_On() mLED_7 = mLED_ON +#define mLED_Error_On() mLED_7_On() + +#define mLED_1_Off() mLED_1 = mLED_OFF +#define mLED_USB_Off() mLED_1_Off() +#define mLED_2_Off() mLED_2 = mLED_OFF +#define mLED_Comms_Off() mLED_2_Off() +#define mLED_3_Off() mLED_3 = mLED_OFF +#define mLED_Clock_Off() mLED_3_Off() +#define mLED_4_Off() mLED_4 = mLED_OFF +#define mLED_Emulate_Off() mLED_4_Off() +#define mLED_5_Off() mLED_5 = mLED_OFF +#define mLED_Read_Off() mLED_5_Off() +#define mLED_6_Off() mLED_6 = mLED_OFF +#define mLED_User_Off() mLED_6_Off() +#define mLED_7_Off() mLED_7 = mLED_OFF +#define mLED_Error_Off() mLED_7_Off() + +#define mLED_1_Toggle() mLED_1 = !mLED_1 +#define mLED_USB_Toggle() mLED_1_Toggle() +#define mLED_2_Toggle() mLED_2 = !mLED_2 +#define mLED_Comms_Toggle() mLED_2_Toggle() +#define mLED_3_Toggle() mLED_3 = !mLED_3 +#define mLED_Clock_Toggle() mLED_3_Toggle() +#define mLED_4_Toggle() mLED_4 = !mLED_4 +#define mLED_Emulate_Toggle() mLED_4_Toggle() +#define mLED_5_Toggle() mLED_5 = !mLED_5 +#define mLED_Read_Toggle( ) mLED_5_Toggle() +#define mLED_6_Toggle() mLED_6 = !mLED_6 +#define mLED_User_Toggle() mLED_6_Toggle() +#define mLED_7_Toggle() mLED_7 = !mLED_7 +#define mLED_Error_Toggle() mLED_7_Toggle() + +#define mLED_All_On() { mLED_1_On(); mLED_2_On(); mLED_3_On(); mLED_4_On(); mLED_5_On(); mLED_6_On(); mLED_7_On(); } +#define mLED_All_Off() { mLED_1_Off(); mLED_2_Off(); mLED_3_Off(); mLED_4_Off(); mLED_5_Off(); mLED_6_Off(); mLED_7_Off(); } + +// usb status lights +#define mLED_Both_Off() {mLED_USB_Off();mLED_Comms_Off();} +#define mLED_Both_On() {mLED_USB_On();mLED_Comms_On();} +#define mLED_Only_USB_On() {mLED_USB_On();mLED_Comms_Off();} +#define mLED_Only_Comms_On() {mLED_USB_Off();mLED_Comms_On();} + +/** SWITCH *********************************************************/ +#define swBootloader PORTEbits.RE7 +#define swUser PORTEbits.RE6 + +/** I/O pin definitions ********************************************/ +#define INPUT_PIN 1 +#define OUTPUT_PIN 0 + +#define TRUE 1 +#define FALSE 0 + +#define ENABLE 1 +#define DISABE 0 + +#define EVEN 0 +#define ODD 1 + +#define LOW FALSE +#define HIGH TRUE + +#define CLOCK_ON LOW +#define CLOCK_OFF HIGH + +// output coil control - select between reader/emulator circuits +#define COIL_MODE LATBbits.LATB4 +#define COIL_MODE_READER() COIL_MODE= LOW +#define COIL_MODE_EMULATOR() COIL_MODE= HIGH + +// coil for emulation +#define COIL_OUT LATGbits.LATG9 +#define COIL_OUT_HIGH() COIL_OUT=HIGH +#define COIL_OUT_LOW() COIL_OUT=LOW + +// door relay (active low) +#define DOOR_RELAY LATAbits.LATA14 +#define DOOR_RELAY_OPEN() DOOR_RELAY= HIGH +#define DOOR_RELAY_CLOSE() DOOR_RELAY= LOW + +// inductance/capacitance freq +#define IC_FREQUENCY PORTAbits.RA2 + +#define SNIFFER_COIL PORTDbits.RD12 // external reader clock detect +#define READER_ANALOGUE PORTBbits.RB11 // reader coil analogue +#define DIV_LOW_ANALOGUE PORTBbits.RB12 // voltage divider LOW analogue +#define DIV_HIGH_ANALOGUE PORTBbits.RB13 // voltage divider HIGH analogue + +// clock coil (normally controlled by OC Module, but defined here so we can force it high or low) +#define CLOCK_COIL PORTDbits.RD4 +#define CLOCK_COIL_MOVED PORTDbits.RD0 // temporary for greenwire + +// digital output after analogue reader circuit +#define READER_DATA PORTDbits.RD8 + +// trace / debug +#define DEBUG_PIN_1 LATCbits.LATC1 +#define DEBUG_PIN_1_TOGGLE() DEBUG_PIN_1= !DEBUG_PIN_1 +#define DEBUG_PIN_2 LATCbits.LATC2 +#define DEBUG_PIN_2_TOGGLE() DEBUG_PIN_2= !DEBUG_PIN_2 +#define DEBUG_PIN_3 LATCbits.LATC3 +#define DEBUG_PIN_3_TOGGLE() DEBUG_PIN_3= !DEBUG_PIN_3 +#define DEBUG_PIN_4 LATEbits.LATE5 +#define DEBUG_PIN_4_TOGGLE() DEBUG_PIN_4= !DEBUG_PIN_4 + +// spi (sdi1) for sd card (not directly referenced) +//#define SD_CARD_RX LATCbits.LATC4 +//#define SD_CARD_TX LATDbits.LATD0 +//#define SD_CARD_CLK LATDbits.LATD10 +//#define SD_CARD_SS LATDbits.LATD9 +// spi for SD card +#define SD_CARD_DET LATFbits.LATF0 +#define SD_CARD_WE LATFbits.LATF1 // write enable - unused for microsd but allocated anyway as library checks it + // (held LOW by default - cut solder bridge to GND to free pin if required) +#define SPI_SD SPI_CHANNEL1 +#define SPI_SD_BUFF SPI1BUF +#define SPI_SD_STAT SPI1STATbits +// see section below for more defines! + +// iso 7816 smartcard +// microchip SC module defines pins so we don't need to, but +// they are listed here to help avoid conflicts +#define ISO_7816_RX LATBbits.LATF2 // RX +#define ISO_7816_TX LATBbits.LATF8 // TX +#define ISO_7816_VCC LATBbits.LATB9 // Power +#define ISO_7816_CLK LATCbits.LATD1 // Clock +#define ISO_7816_RST LATEbits.LATE8 // Reset + +// user LED +#define USER_LED LATDbits.LATD7 +#define USER_LED_ON() LATDbits.LATD7=1 +#define USER_LED_OFF() LATDbits.LATD7=0 + +// LCR +#define LCR_CALIBRATE LATBbits.LATB5 + +// wiegand / clock & data +#define WIEGAND_IN_0 PORTDbits.RD5 +#define WIEGAND_IN_0_PULLUP CNPUEbits.CNPUE14 +#define WIEGAND_IN_0_PULLDOWN CNPDbits.CNPD14 +#define WIEGAND_IN_1 PORTDbits.RD6 +#define WIEGAND_IN_1_PULLUP CNPUEbits.CNPUE15 +#define WIEGAND_IN_1_PULLDOWN CNPDbits.CNPD15 +#define CAND_IN_DATA WIEGAND_IN_0 +#define CAND_IN_CLOCK WIEGAND_IN_1 + +#define WIEGAND_OUT_0 LATDbits.LATD3 +#define WIEGAND_OUT_1 LATDbits.LATD2 +#define WIEGAND_OUT_0_TRIS TRISDbits.TRISD3 +#define WIEGAND_OUT_1_TRIS TRISDbits.TRISD2 +#define CAND_OUT_DATA WIEGAND_OUT_0 +#define CAND_OUT_CLOCK WIEGAND_OUT_1 + +// connect/disconnect reader clock from coil - used to send RWD signals by creating gaps in carrier +#define READER_CLOCK_ENABLE LATEbits.LATE9 +#define READER_CLOCK_ENABLE_ON() READER_CLOCK_ENABLE=CLOCK_ON +#define READER_CLOCK_ENABLE_OFF(x) {READER_CLOCK_ENABLE=CLOCK_OFF; COIL_OUT=x;} + +// these input pins must NEVER bet set to output or they will cause short circuits! +// they can be used to see data from reader before it goes into or gate +#define OR_IN_A PORTAbits.RA4 +#define OR_IN_B PORTAbits.RA5 + + +// CNCON and CNEN are set to allow wiegand input pin weak pullups to be switched on +#define Init_GPIO() { \ + CNCONbits.ON= TRUE; \ + CNENbits.CNEN14= TRUE; \ + CNENbits.CNEN15= TRUE; \ + TRISAbits.TRISA2= INPUT_PIN; \ + TRISAbits.TRISA4= INPUT_PIN; \ + TRISAbits.TRISA5= INPUT_PIN; \ + TRISAbits.TRISA14= OUTPUT_PIN; \ + TRISAbits.TRISA15= OUTPUT_PIN; \ + TRISBbits.TRISB4= OUTPUT_PIN; \ + TRISBbits.TRISB5= OUTPUT_PIN; \ + TRISBbits.TRISB9= OUTPUT_PIN; \ + TRISBbits.TRISB11= INPUT_PIN; \ + TRISBbits.TRISB12= INPUT_PIN; \ + TRISBbits.TRISB13= INPUT_PIN; \ + TRISCbits.TRISC1= OUTPUT_PIN; \ + TRISCbits.TRISC2= OUTPUT_PIN; \ + TRISCbits.TRISC3= OUTPUT_PIN; \ + TRISCbits.TRISC4= INPUT_PIN; \ + TRISDbits.TRISD0= INPUT_PIN; \ + TRISDbits.TRISD1= OUTPUT_PIN; \ + TRISDbits.TRISD2= OUTPUT_PIN; \ + TRISDbits.TRISD3= OUTPUT_PIN; \ + TRISDbits.TRISD4= OUTPUT_PIN; \ + TRISDbits.TRISD5= INPUT_PIN; \ + TRISDbits.TRISD6= INPUT_PIN; \ + TRISDbits.TRISD7= OUTPUT_PIN; \ + TRISDbits.TRISD8= INPUT_PIN; \ + TRISDbits.TRISD11= OUTPUT_PIN; \ + TRISDbits.TRISD12= INPUT_PIN; \ + TRISEbits.TRISE0= OUTPUT_PIN; \ + TRISEbits.TRISE1= OUTPUT_PIN; \ + TRISEbits.TRISE2= OUTPUT_PIN; \ + TRISEbits.TRISE3= OUTPUT_PIN; \ + TRISEbits.TRISE5= OUTPUT_PIN; \ + TRISEbits.TRISE6= INPUT_PIN; \ + TRISEbits.TRISE7= INPUT_PIN; \ + TRISEbits.TRISE8= OUTPUT_PIN; \ + TRISEbits.TRISE9= OUTPUT_PIN; \ + TRISFbits.TRISF0= INPUT_PIN; \ + TRISFbits.TRISF1= INPUT_PIN; \ + TRISFbits.TRISF2= INPUT_PIN; \ + TRISFbits.TRISF8= OUTPUT_PIN; \ + TRISGbits.TRISG6= OUTPUT_PIN; \ + TRISGbits.TRISG12= INPUT_PIN; \ + TRISGbits.TRISG13= INPUT_PIN; \ + TRISGbits.TRISG9= OUTPUT_PIN; \ + LATBbits.LATB9= LOW; \ + LATCbits.LATC1= LOW; \ + LATCbits.LATC2= LOW; \ + LATCbits.LATC3= LOW; \ + LATDbits.LATD2= WIEGAND_IN_1; \ + LATDbits.LATD3= WIEGAND_IN_0; \ + LATEbits.LATE5= LOW; \ + LATEbits.LATE9= HIGH; \ + } + +// uart3 (CLI/API) speed +#define BAUDRATE3 115200UL +#define BRG_DIV3 4 +#define BRGH3 1 + +// spi for potentiometer +#define SPI_POT SPI_CHANNEL4 +#define SPI_POT_BUFF SPI4BUF +#define SPI_POT_STAT SPI4STATbits + +// spi for sd card - defines required for Microchip SD-SPI libs +// define interface type +#define USE_SD_INTERFACE_WITH_SPI + +#define MDD_USE_SPI_1 +#define SPI_START_CFG_1 (PRI_PRESCAL_64_1 | SEC_PRESCAL_8_1 | MASTER_ENABLE_ON | SPI_CKE_ON | SPI_SMP_ON) +#define SPI_START_CFG_2 (SPI_ENABLE) +// Define the SPI frequency +#define SPI_FREQUENCY (20000000) +// Description: SD-SPI Card Detect Input bit +#define SD_CD PORTFbits.RF0 +// Description: SD-SPI Card Detect TRIS bit +#define SD_CD_TRIS TRISFbits.TRISF0 +// Description: SD-SPI Write Protect Check Input bit +#define SD_WE PORTFbits.RF1 +// Description: SD-SPI Write Protect Check TRIS bit +#define SD_WE_TRIS TRISFbits.TRISF1 +// Description: The main SPI control register +#define SPICON1 SPI1CON +// Description: The SPI status register +#define SPISTAT SPI1STAT +// Description: The SPI Buffer +#define SPIBUF SPI1BUF +// Description: The receive buffer full bit in the SPI status register +#define SPISTAT_RBF SPI1STATbits.SPIRBF +// Description: The bitwise define for the SPI control register (i.e. _____bits) +#define SPICON1bits SPI1CONbits +// Description: The bitwise define for the SPI status register (i.e. _____bits) +#define SPISTATbits SPI1STATbits +// Description: The enable bit for the SPI module +#define SPIENABLE SPICON1bits.ON +// Description: The definition for the SPI baud rate generator register (PIC32) +#define SPIBRG SPI1BRG +// Description: The TRIS bit for the SCK pin +#define SPICLOCK TRISDbits.TRISD10 +// Description: The TRIS bit for the SDI pin +#define SPIIN TRISCbits.TRISC4 +// Description: The TRIS bit for the SDO pin +#define SPIOUT TRISDbits.TRISD0 +#define SD_CS LATDbits.LATD9 +// Description: SD-SPI Chip Select TRIS bit +#define SD_CS_TRIS TRISDbits.TRISD9 +//SPI library functions +#define putcSPI putcSPI1 +#define getcSPI getcSPI1 +#define OpenSPI(config1, config2) OpenSPI1(config1, config2) + +// Define setup parameters for OpenADC10 function +// Turn module on | Ouput in integer format | Trigger mode auto | Enable autosample +#define ADC_CONFIG1 (ADC_FORMAT_INTG | ADC_CLK_AUTO | ADC_AUTO_SAMPLING_ON) +// ADC ref external | Disable offset test | Disable scan mode | Perform 2 samples | Use dual buffers | Use alternate mode +#define ADC_CONFIG2 (ADC_VREF_AVDD_AVSS | ADC_OFFSET_CAL_DISABLE | ADC_SCAN_OFF | ADC_SAMPLES_PER_INT_1 | ADC_ALT_BUF_ON | ADC_ALT_INPUT_ON) + +// Use ADC internal clock | Set sample time +#define ADC_CONFIG3 (ADC_CONV_CLK_INTERNAL_RC | ADC_SAMPLE_TIME_0) + +// slow sample rate for tuning coils +#define ADC_CONFIG2_SLOW (ADC_VREF_AVDD_AVSS | ADC_OFFSET_CAL_DISABLE | ADC_SCAN_OFF | ADC_SAMPLES_PER_INT_16 | ADC_ALT_BUF_ON | ADC_ALT_INPUT_ON) +#define ADC_CONFIG3_SLOW (ADC_CONV_CLK_INTERNAL_RC | ADC_SAMPLE_TIME_31) + +// use AN11 +#define ADC_CONFIGPORT ENABLE_AN11_ANA +// Do not assign channels to scan +#define ADC_CONFIGSCAN SKIP_SCAN_ALL + +#define ADC_TO_VOLTS 0.003208F + + +// flash memory - int myvar = *(int*)(myflashmemoryaddress); + +// memory is 0x9D005000 to 0x9D07FFFF + +#define NVM_MEMORY_END 0x9D07FFFF +#define NVM_PAGE_SIZE 4096 +#define NVM_PAGES 2 // config & VTAG +#define RFIDLER_NVM_ADDRESS (NVM_MEMORY_END - (NVM_PAGE_SIZE * NVM_PAGES)) + +// UART timeout in us +#define SERIAL_TIMEOUT 100 + +#endif diff --git a/tools/hitag2crack/crack4/Makefile b/tools/hitag2crack/crack4/Makefile new file mode 100644 index 000000000..82e7f2560 --- /dev/null +++ b/tools/hitag2crack/crack4/Makefile @@ -0,0 +1,20 @@ +WARN=-Wall +CFLAGS=-c $(WARN) $(INCLUDE) +LIBS=-lpthread + +all: ht2crack4.c HardwareProfile.h rfidler.h util.h utilpart.o hitagcrypto.o ht2crack2utils.o + cc $(WARN) -o ht2crack4 ht2crack4.c utilpart.o hitagcrypto.o ht2crack2utils.o $(LIBS) + +utilpart.o: utilpart.c util.h + cc $(CFLAGS) utilpart.c + +hitagcrypto.o: hitagcrypto.c hitagcrypto.h + cc $(CFLAGS) hitagcrypto.c + +ht2crack2utils.o: ht2crack2utils.c ht2crack2utils.h + cc $(CFLAGS) ht2crack2utils.c + +clean: + rm -rf *.o ht2crack4 + +fresh: clean all diff --git a/tools/hitag2crack/crack4/hitagcrypto.c b/tools/hitag2crack/crack4/hitagcrypto.c new file mode 100644 index 000000000..422efbe92 --- /dev/null +++ b/tools/hitag2crack/crack4/hitagcrypto.c @@ -0,0 +1,485 @@ +/*************************************************************************** + * A copy of the GNU GPL is appended to this file. * + * * + * This licence is based on the nmap licence, and we express our gratitude * + * for the work that went into producing it. There is no other connection * + * between RFIDler and nmap either expressed or implied. * + * * + ********************** IMPORTANT RFIDler LICENSE TERMS ******************** + * * + * * + * All references to RFIDler herein imply all it's derivatives, namely: * + * * + * o RFIDler-LF Standard * + * o RFIDler-LF Lite * + * o RFIDler-LF Nekkid * + * * + * * + * RFIDler is (C) 2013-2015 Aperture Labs Ltd. * + * * + * This program is free software; you may redistribute and/or modify it * + * under the terms of the GNU General Public License as published by the * + * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE * + * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your * + * right to use, modify, and redistribute this software under certain * + * conditions. If you wish to embed RFIDler technology into proprietary * + * software or hardware, we sell alternative licenses * + * (contact sales@aperturelabs.com). * + * * + * Note that the GPL places important restrictions on "derivative works", * + * yet it does not provide a detailed definition of that term. To avoid * + * misunderstandings, we interpret that term as broadly as copyright law * + * allows. For example, we consider an application to constitute a * + * derivative work for the purpose of this license if it does any of the * + * following with any software or content covered by this license * + * ("Covered Software"): * + * * + * o Integrates source code from Covered Software. * + * * + * o Is designed specifically to execute Covered Software and parse the * + * results (as opposed to typical shell or execution-menu apps, which will * + * execute anything you tell them to). * + * * + * o Includes Covered Software in a proprietary executable installer. The * + * installers produced by InstallShield are an example of this. Including * + * RFIDler with other software in compressed or archival form does not * + * trigger this provision, provided appropriate open source decompression * + * or de-archiving software is widely available for no charge. For the * + * purposes of this license, an installer is considered to include Covered * + * Software even if it actually retrieves a copy of Covered Software from * + * another source during runtime (such as by downloading it from the * + * Internet). * + * * + * o Links (statically or dynamically) to a library which does any of the * + * above. * + * * + * o Executes a helper program, module, or script to do any of the above. * + * * + * This list is not exclusive, but is meant to clarify our interpretation * + * of derived works with some common examples. Other people may interpret * + * the plain GPL differently, so we consider this a special exception to * + * the GPL that we apply to Covered Software. Works which meet any of * + * these conditions must conform to all of the terms of this license, * + * particularly including the GPL Section 3 requirements of providing * + * source code and allowing free redistribution of the work as a whole. * + * * + * As another special exception to the GPL terms, Aperture Labs Ltd. grants* + * permission to link the code of this program with any version of the * + * OpenSSL library which is distributed under a license identical to that * + * listed in the included docs/licenses/OpenSSL.txt file, and distribute * + * linked combinations including the two. * + * * + * Any redistribution of Covered Software, including any derived works, * + * must obey and carry forward all of the terms of this license, including * + * obeying all GPL rules and restrictions. For example, source code of * + * the whole work must be provided and free redistribution must be * + * allowed. All GPL references to "this License", are to be treated as * + * including the terms and conditions of this license text as well. * + * * + * Because this license imposes special exceptions to the GPL, Covered * + * Work may not be combined (even as part of a larger work) with plain GPL * + * software. The terms, conditions, and exceptions of this license must * + * be included as well. This license is incompatible with some other open * + * source licenses as well. In some cases we can relicense portions of * + * RFIDler or grant special permissions to use it in other open source * + * software. Please contact sales@aperturelabs.com with any such requests.* + * Similarly, we don't incorporate incompatible open source software into * + * Covered Software without special permission from the copyright holders. * + * * + * If you have any questions about the licensing restrictions on using * + * RFIDler in other works, are happy to help. As mentioned above, we also * + * offer alternative license to integrate RFIDler into proprietary * + * applications and appliances. These contracts have been sold to dozens * + * of software vendors, and generally include a perpetual license as well * + * as providing for priority support and updates. They also fund the * + * continued development of RFIDler. Please email sales@aperturelabs.com * + * for further information. * + * If you have received a written license agreement or contract for * + * Covered Software stating terms other than these, you may choose to use * + * and redistribute Covered Software under those terms instead of these. * + * * + * Source is provided to this software because we believe users have a * + * right to know exactly what a program is going to do before they run it. * + * This also allows you to audit the software for security holes (none * + * have been found so far). * + * * + * Source code also allows you to port RFIDler to new platforms, fix bugs, * + * and add new features. You are highly encouraged to send your changes * + * to the RFIDler mailing list for possible incorporation into the * + * main distribution. By sending these changes to Aperture Labs Ltd. or * + * one of the Aperture Labs Ltd. development mailing lists, or checking * + * them into the RFIDler source code repository, it is understood (unless * + * you specify otherwise) that you are offering the RFIDler Project * + * (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, * + * modify, and relicense the code. RFIDler will always be available Open * + * Source, but this is important because the inability to relicense code * + * has caused devastating problems for other Free Software projects (such * + * as KDE and NASM). We also occasionally relicense the code to third * + * parties as discussed above. If you wish to specify special license * + * conditions of your contributions, just say so when you send them. * + * * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler * + * license file for more details (it's in a COPYING file included with * + * RFIDler, and also available from * + * https://github.com/ApertureLabsLtd/RFIDler/COPYING * + * * + ***************************************************************************/ + +// Author: unknown. +// Modifications for RFIDler: Tony Naggs , Adam Laurie + +// uncomment this to build file as a standalone crypto test program +// #define UNIT_TEST +// also uncomment to include verbose debug prints +// #define TEST_DEBUG + +//#include +#include "HardwareProfile.h" +#include "rfidler.h" +#include "hitagcrypto.h" +#include "util.h" + +#ifdef UNIT_TEST +#include +#endif + +#if defined(UNIT_TEST) && defined(TEST_DEBUG) +// Note that printf format %I64x prints 64 bit ints in MS Visual C/C++. +// This may need changing for other compilers/platforms. +#define DEBUG_PRINTF(...) printf(__VA_ARGS__) +#else +#define DEBUG_PRINTF(...) +#endif + + +/* Brief info about NXP Hitag 1, Hitag 2, Hitag S and Hitag u (mu) + + Hitag 125kHz RFID was created by a company called Mikron (Mikron Gesellschaft + fur Integrierte Mikroelektronik Mbh), of Austria, for micropayment applications. + At about the same time, late 1980s to early 1990s, Mikron developed the + similarly featured Mifare micropayment card for 13.56MHz RFID. + (Mikron's European Patent EP 0473569 A2 was filed 23 August 1991, with a + priority date of 23 Aug 1990.) + Mikron was subsequently acquired by Philips Semiconductors in 1995. + Philips Semiconductors divsion subsequently became NXP. + + + Modulation read/write device -> transponder: 100 % ASK and binary pulse + length coding + + Modulation transponder -> read/write device: Strong ASK modulation, + selectable Manchester or Biphase coding + + Hitag S, Hitag u; anti-collision procedure + + Fast anti-collision protocol + + Hitag u; optional Cyclic Redundancy Check (CRC) + + Reader Talks First mode + + Hitag 2 & later; Transponder Talks First (TTF) mode + + Temporary switch from Transponder Talks First into Reader Talks First + (RTF) Mode + + Data rate read/write device to transponder: 5.2 kbit/s + + Data rates transponder to read/write device: 2 kbit/s, 4 kbit/s, 8 kbit/s + + 32-bit password feature + + Hitag 2, S = 32-bit Unique Identifier + + Hitag u = 48-bit Unique Identifier + + Selectable password modes for reader / tag mutual authentication + (Hitag 1 has 2 pairs of keys, later versions have 1 pair) + + Hitag 2 & Hitag S; Selectable encrypted mode, 48 bit key + + Known tag types: + + HITAG 1 2048 bits total memory + + HITAG 2 256 Bit total memory Read/Write + 8 pages of 32 bits, inc UID (32), + secret key (64), password (24), config (8) + + HITAG S 32 32 bits Unique Identifier Read Only + HITAG S 256 256 bits total memory Read/Write + HITAG S 2048 2048 bits total memory Read/Write + + HITAG u RO64 64 bits total memory Read Only + HITAG u 128 bits total memory Read/Write + HITAG u Advanced 512 bits total memory Read/Write + HITAG u Advanced+ 1760 bits total memory Read/Write + + Default 48-bit key for Hitag 2, S encryption: + "MIKRON" = O N M I K R + Key = 4F 4E 4D 49 4B 52 + +*/ + + +// We want the crypto functions to be as fast as possible, so optimize! +// The best compiler optimization in Microchip's free XC32 edition is -O1 +#pragma GCC optimize("O1") + +// private, nonlinear function to generate 1 crypto bit +static uint32_t hitag2_crypt(uint64_t x); + + +// macros to pick out 4 bits in various patterns of 1s & 2s & make a new number +#define pickbits2_2(S, A, B) ( ((S >> A) & 3) | ((S >> (B - 2)) & 0xC) ) +#define pickbits1x4(S, A, B, C, D) ( ((S >> A) & 1) | ((S >> (B - 1)) & 2) | \ + ((S >> (C - 2)) & 4) | ((S >> (D - 3)) & 8) ) +#define pickbits1_1_2(S, A, B, C) ( ((S >> A) & 1) | ((S >> (B - 1)) & 2) | \ + ((S >> (C - 2)) & 0xC) ) +#define pickbits2_1_1(S, A, B, C) ( ((S >> A) & 3) | ((S >> (B - 2)) & 4) | \ + ((S >> (C - 3)) & 8) ) +#define pickbits1_2_1(S, A, B, C) ( ((S >> A) & 1) | ((S >> (B - 1)) & 6) | \ + ((S >> (C - 3)) & 8) ) + + +static uint32_t hitag2_crypt(uint64_t s) +{ + const uint32_t ht2_function4a = 0x2C79; // 0010 1100 0111 1001 + const uint32_t ht2_function4b = 0x6671; // 0110 0110 0111 0001 + const uint32_t ht2_function5c = 0x7907287B; // 0111 1001 0000 0111 0010 1000 0111 1011 + uint32_t bitindex; + + bitindex = (ht2_function4a >> pickbits2_2 (s, 1, 4)) & 1; + bitindex |= ((ht2_function4b << 1) >> pickbits1_1_2 (s, 7, 11, 13)) & 0x02; + bitindex |= ((ht2_function4b << 2) >> pickbits1x4 (s, 16, 20, 22, 25)) & 0x04; + bitindex |= ((ht2_function4b << 3) >> pickbits2_1_1 (s, 27, 30, 32)) & 0x08; + bitindex |= ((ht2_function4a << 4) >> pickbits1_2_1(s, 33, 42, 45)) & 0x10; + + DEBUG_PRINTF("hitag2_crypt bitindex = %02x\n", bitindex); + return (ht2_function5c >> bitindex) & 1; +} + +/* + * Parameters: + * Hitag_State* pstate - output, internal state after initialisation + * uint64_t sharedkey - 48 bit key shared between reader & tag + * uint32_t serialnum - 32 bit tag serial number + * uint32_t initvector - 32 bit random IV from reader, part of tag authentication + */ +void hitag2_init(Hitag_State* pstate, uint64_t sharedkey, uint32_t serialnum, uint32_t initvector) +{ + // init state, from serial number and lowest 16 bits of shared key + uint64_t state = ((sharedkey & 0xFFFF) << 32) | serialnum; + + // mix the initialisation vector and highest 32 bits of the shared key + initvector ^= (uint32_t) (sharedkey >> 16); + + // move 16 bits from (IV xor Shared Key) to top of uint64_t state + // these will be XORed in turn with output of the crypto function + state |= (uint64_t) initvector << 48; + initvector >>= 16; + + // unrolled loop is faster on PIC32 (MIPS), do 32 times + // shift register, then calc new bit + state >>= 1; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + + // highest 16 bits of IV XOR Shared Key + state |= (uint64_t) initvector << 47; + + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state ^= (uint64_t) hitag2_crypt(state) << 47; + + DEBUG_PRINTF("hitag2_init result = %012I64x\n", state); + pstate->shiftreg = state; + /* naive version for reference, LFSR has 16 taps + pstate->lfsr = state ^ (state >> 2) ^ (state >> 3) ^ (state >> 6) + ^ (state >> 7) ^ (state >> 8) ^ (state >> 16) ^ (state >> 22) + ^ (state >> 23) ^ (state >> 26) ^ (state >> 30) ^ (state >> 41) + ^ (state >> 42) ^ (state >> 43) ^ (state >> 46) ^ (state >> 47); + */ + { + // optimise with one 64-bit intermediate + uint64_t temp = state ^ (state >> 1); + pstate->lfsr = state ^ (state >> 6) ^ (state >> 16) + ^ (state >> 26) ^ (state >> 30) ^ (state >> 41) + ^ (temp >> 2) ^ (temp >> 7) ^ (temp >> 22) + ^ (temp >> 42) ^ (temp >> 46); + } +} + + +/* + * Return up to 32 crypto bits. + * Last bit is in least significant bit, earlier bits are shifted left. + * Note that the Hitag transmission protocol is least significant bit, + * so we may want to change this, or add a function, that returns the + * crypto output bits in the other order. + * + * Parameters: + * Hitag_State* pstate - in/out, internal cipher state after initialisation + * uint32_t steps - number of bits requested, (capped at 32) + */ +uint32_t hitag2_nstep(Hitag_State* pstate, uint32_t steps) +{ + uint64_t state = pstate->shiftreg; + uint32_t result = 0; + uint64_t lfsr = pstate->lfsr; + + if (steps == 0) + return 0; + +// if (steps > 32) +// steps = 32; + + do { + // update shift registers + if (lfsr & 1) { + state = (state >> 1) | 0x800000000000; + lfsr = (lfsr >> 1) ^ 0xB38083220073; + + // accumulate next bit of crypto + result = (result << 1) | hitag2_crypt(state); + } else { + state >>= 1; + lfsr >>= 1; + + result = (result << 1) | hitag2_crypt(state); + } + } while (--steps); + + DEBUG_PRINTF("hitag2_nstep state = %012I64x, result %02x\n", state, result); + pstate->shiftreg = state; + pstate->lfsr = lfsr; + return result; +} + +// end of crypto core, revert to default optimization level +#pragma GCC reset_options + + +/* Test code + + Test data and below information about it comes from + http://www.mikrocontroller.net/attachment/102194/hitag2.c + Written by "I.C. Wiener 2006-2007" + + "MIKRON" = O N M I K R + Key = 4F 4E 4D 49 4B 52 - Secret 48-bit key + Serial = 49 43 57 69 - Serial number of the tag, transmitted in clear + Random = 65 6E 45 72 - Random IV, transmitted in clear + ~28~DC~80~31 = D7 23 7F CE - Authenticator value = inverted first 4 bytes of the keystream + + The code below must print out "D7 23 7F CE 8C D0 37 A9 57 49 C1 E6 48 00 8A B6". + The inverse of the first 4 bytes is sent to the tag to authenticate. + The rest is encrypted by XORing it with the subsequent keystream. + +*/ + + +/* +unsigned int hitag2_benchtest_gen32() +{ + const uint64_t key = 0x4ad292b272f2; + const uint32_t serial = 0x96eac292; + const uint32_t initvec = 0x4ea276a6; + Hitag_State state; + + // init crypto + hitag2_init(&state, key, serial, initvec); + + // benchmark: generation of 32 bit stream (excludes initialisation) + GetTimer_us(RESET); + + (void) hitag2_nstep(&state, 32); + + return GetTimer_us(NO_RESET); +} + + +unsigned int hitag2_benchtest(uint32_t count) +{ + const uint64_t key = 0x4ad292b272f2; + const uint32_t serial = 0x96eac292; + const uint32_t initvec = 0x4ea276a6; + Hitag_State state; + uint32_t i; + + // start timer + GetTimer_us(RESET); + + // benchmark: initialise crypto & generate 32 bit authentication + // adding i stops gcc optimizer moving init function call out of loop + for (i = 0; i < count; i++) { + hitag2_init(&state, key, serial, initvec + i); + (void) hitag2_nstep(&state, 32); + } + + return GetTimer_us(NO_RESET); +} + + +unsigned hitag2_verifytest() +{ + uint8_t expected[16] = { 0xD7, 0x23, 0x7F, 0xCE, 0x8C, 0xD0, 0x37, 0xA9, 0x57, 0x49, 0xC1, 0xE6, 0x48, 0x00, 0x8A, 0xB6 }; + // key = 0x4ad292b272f2 after each byte has its bit order reversed + // serial = 0x96eac292 ditto + // initvec = 0x4ea276a6 ditto + const uint64_t key = rev64 (0x524B494D4E4FUL); + const uint32_t serial = rev32 (0x69574349); + const uint32_t initvec = rev32 (0x72456E65); + + uint32_t i; + Hitag_State state; + + // initialise + hitag2_init(&state, key, serial, initvec); + + for (i = 0; i < 16; i++) { + // get 8 bits of keystream + uint8_t x = (uint8_t) hitag2_nstep(&state, 8); + uint8_t y = expected[i]; + + DEBUG_PRINTF ("%02X (%02X) \n", x, y); + if (x != y) + return 0; + } + + return 1; +} +*/ + +#ifdef UNIT_TEST + +int main(int argc, char* argv[]) +{ + unsigned pass = hitag2_verifytest(); + + printf ("Crypto Verify test = %s\n\n", pass ? "PASS" : "FAIL"); + + if (pass) { + hitag2_benchtest(10000); + } + + return 0; +} + +#endif // UNIT_TEST diff --git a/tools/hitag2crack/crack4/hitagcrypto.h b/tools/hitag2crack/crack4/hitagcrypto.h new file mode 100644 index 000000000..d5aa9104c --- /dev/null +++ b/tools/hitag2crack/crack4/hitagcrypto.h @@ -0,0 +1,171 @@ +/*************************************************************************** + * A copy of the GNU GPL is appended to this file. * + * * + * This licence is based on the nmap licence, and we express our gratitude * + * for the work that went into producing it. There is no other connection * + * between RFIDler and nmap either expressed or implied. * + * * + ********************** IMPORTANT RFIDler LICENSE TERMS ******************** + * * + * * + * All references to RFIDler herein imply all it's derivatives, namely: * + * * + * o RFIDler-LF Standard * + * o RFIDler-LF Lite * + * o RFIDler-LF Nekkid * + * * + * * + * RFIDler is (C) 2013-2014 Aperture Labs Ltd. * + * * + * This program is free software; you may redistribute and/or modify it * + * under the terms of the GNU General Public License as published by the * + * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE * + * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your * + * right to use, modify, and redistribute this software under certain * + * conditions. If you wish to embed RFIDler technology into proprietary * + * software or hardware, we sell alternative licenses * + * (contact sales@aperturelabs.com). * + * * + * Note that the GPL places important restrictions on "derivative works", * + * yet it does not provide a detailed definition of that term. To avoid * + * misunderstandings, we interpret that term as broadly as copyright law * + * allows. For example, we consider an application to constitute a * + * derivative work for the purpose of this license if it does any of the * + * following with any software or content covered by this license * + * ("Covered Software"): * + * * + * o Integrates source code from Covered Software. * + * * + * o Is designed specifically to execute Covered Software and parse the * + * results (as opposed to typical shell or execution-menu apps, which will * + * execute anything you tell them to). * + * * + * o Includes Covered Software in a proprietary executable installer. The * + * installers produced by InstallShield are an example of this. Including * + * RFIDler with other software in compressed or archival form does not * + * trigger this provision, provided appropriate open source decompression * + * or de-archiving software is widely available for no charge. For the * + * purposes of this license, an installer is considered to include Covered * + * Software even if it actually retrieves a copy of Covered Software from * + * another source during runtime (such as by downloading it from the * + * Internet). * + * * + * o Links (statically or dynamically) to a library which does any of the * + * above. * + * * + * o Executes a helper program, module, or script to do any of the above. * + * * + * This list is not exclusive, but is meant to clarify our interpretation * + * of derived works with some common examples. Other people may interpret * + * the plain GPL differently, so we consider this a special exception to * + * the GPL that we apply to Covered Software. Works which meet any of * + * these conditions must conform to all of the terms of this license, * + * particularly including the GPL Section 3 requirements of providing * + * source code and allowing free redistribution of the work as a whole. * + * * + * As another special exception to the GPL terms, Aperture Labs Ltd. grants* + * permission to link the code of this program with any version of the * + * OpenSSL library which is distributed under a license identical to that * + * listed in the included docs/licenses/OpenSSL.txt file, and distribute * + * linked combinations including the two. * + * * + * Any redistribution of Covered Software, including any derived works, * + * must obey and carry forward all of the terms of this license, including * + * obeying all GPL rules and restrictions. For example, source code of * + * the whole work must be provided and free redistribution must be * + * allowed. All GPL references to "this License", are to be treated as * + * including the terms and conditions of this license text as well. * + * * + * Because this license imposes special exceptions to the GPL, Covered * + * Work may not be combined (even as part of a larger work) with plain GPL * + * software. The terms, conditions, and exceptions of this license must * + * be included as well. This license is incompatible with some other open * + * source licenses as well. In some cases we can relicense portions of * + * RFIDler or grant special permissions to use it in other open source * + * software. Please contact sales@aperturelabs.com with any such requests.* + * Similarly, we don't incorporate incompatible open source software into * + * Covered Software without special permission from the copyright holders. * + * * + * If you have any questions about the licensing restrictions on using * + * RFIDler in other works, are happy to help. As mentioned above, we also * + * offer alternative license to integrate RFIDler into proprietary * + * applications and appliances. These contracts have been sold to dozens * + * of software vendors, and generally include a perpetual license as well * + * as providing for priority support and updates. They also fund the * + * continued development of RFIDler. Please email sales@aperturelabs.com * + * for further information. * + * If you have received a written license agreement or contract for * + * Covered Software stating terms other than these, you may choose to use * + * and redistribute Covered Software under those terms instead of these. * + * * + * Source is provided to this software because we believe users have a * + * right to know exactly what a program is going to do before they run it. * + * This also allows you to audit the software for security holes (none * + * have been found so far). * + * * + * Source code also allows you to port RFIDler to new platforms, fix bugs, * + * and add new features. You are highly encouraged to send your changes * + * to the RFIDler mailing list for possible incorporation into the * + * main distribution. By sending these changes to Aperture Labs Ltd. or * + * one of the Aperture Labs Ltd. development mailing lists, or checking * + * them into the RFIDler source code repository, it is understood (unless * + * you specify otherwise) that you are offering the RFIDler Project * + * (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, * + * modify, and relicense the code. RFIDler will always be available Open * + * Source, but this is important because the inability to relicense code * + * has caused devastating problems for other Free Software projects (such * + * as KDE and NASM). We also occasionally relicense the code to third * + * parties as discussed above. If you wish to specify special license * + * conditions of your contributions, just say so when you send them. * + * * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler * + * license file for more details (it's in a COPYING file included with * + * RFIDler, and also available from * + * https://github.com/ApertureLabsLtd/RFIDler/COPYING * + * * + ***************************************************************************/ + +// Author: unknown. +// Modifications for RFIDler: Tony Naggs , Adam Laurie + + +#ifndef HITAGCRYPTO_H +#define HITAGCRYPTO_H + +#include + +/* + Our model of Hitag 2 crypto uses 2 parallel shift registers: + a. 48 bit Feedback Shift Register, required for inputs to the nonlinear function. + b. 48 bit Linear Feedback Shift Register (LFSR). + A transform of initial register (a) value, which is then run in parallel. + Enables much faster calculation of the feedback values. + + API: + void hitag2_init(Hitag_State* pstate, uint64_t sharedkey, uint32_t serialnum, + uint32_t initvector); + Initialise state from 48 bit shared (secret) reader/tag key, + 32 bit tag serial number and 32 bit initialisation vector from reader. + + uint32_t hitag2_nstep(Hitag_State* pstate, uint32_t steps); + update shift register state and generate N cipher bits (N should be <= 32) + */ + + +typedef struct { + uint64_t shiftreg; // naive shift register, required for nonlinear fn input + uint64_t lfsr; // fast lfsr, used to make software faster +} Hitag_State; + +void hitag2_init(Hitag_State* pstate, uint64_t sharedkey, uint32_t serialnum, uint32_t initvector); + +uint32_t hitag2_nstep(Hitag_State* pstate, uint32_t steps); + +unsigned int hitag2_benchtest_gen32(); +unsigned int hitag2_benchtest(uint32_t count); +unsigned hitag2_verifytest(); + +#endif /* HITAGCRYPTO_H */ + diff --git a/tools/hitag2crack/crack4/ht2crack2utils.c b/tools/hitag2crack/crack4/ht2crack2utils.c new file mode 100644 index 000000000..2152f8ef3 --- /dev/null +++ b/tools/hitag2crack/crack4/ht2crack2utils.c @@ -0,0 +1,187 @@ +#include "ht2crack2utils.h" + +// writes a value into a buffer as a series of bytes +void writebuf(unsigned char *buf, uint64_t val, unsigned int len) +{ + int i; + char c; + + for (i=len-1; i>=0; i--) + { + c = val & 0xff; + buf[i] = c; + val = val >> 8; + } + +} + + +/* simple hexdump for testing purposes */ +void shexdump(unsigned char *data, int data_len) +{ + int i; + + if (!data || (data_len <= 0)) { + printf("shexdump: invalid parameters\n"); + return; + } + + printf("Hexdump from %p:\n", data); + + for (i=0; i> 7); + x = x << 1; + } + } + printf("\n"); +} + + +void printbin2(uint64_t val, unsigned int size) +{ + int i; + uint64_t mask = 1; + + mask = mask << (size - 1); + + for (i=0; ishiftreg, 48); + printf("\n"); +} + + + + +// convert hex char to binary +unsigned char hex2bin(unsigned char c) +{ + if ((c >= '0') && (c <= '9')) { + return (c - '0'); + } else if ((c >= 'a') && (c <= 'f')) { + return (c - 'a' + 10); + } else if ((c >= 'A') && (c <= 'F')) { + return (c - 'A' + 10); + } else { + return 0; + } +} + +// return a single bit from a value +int bitn(uint64_t x, int bit) +{ + uint64_t bitmask = 1; + + bitmask = bitmask << bit; + + if (x & bitmask) { + return 1; + } else { + return 0; + } +} + + +// the sub-function R that rollback depends upon +int fnR(uint64_t x) +{ + // renumbered bits because my state is 0-47, not 1-48 + return (bitn(x, 1) ^ bitn(x, 2) ^ bitn(x, 5) ^ bitn(x, 6) ^ bitn(x, 7) ^ + bitn(x, 15) ^ bitn(x, 21) ^ bitn(x, 22) ^ bitn(x, 25) ^ bitn(x, 29) ^ bitn(x, 40) ^ + bitn(x, 41) ^ bitn(x, 42) ^ bitn(x, 45) ^ bitn(x, 46) ^ bitn(x, 47)); +} + +// the rollback function that lets us go backwards in time +void rollback(Hitag_State *hstate, unsigned int steps) +{ + int i; + + for (i=0; ishiftreg = ((hstate->shiftreg << 1) & 0xffffffffffff) | fnR(hstate->shiftreg); + } + +} + + +// the three filter sub-functions that feed fnf +int fa(unsigned int i) +{ + return bitn(0x2C79, i); +} + +int fb(unsigned int i) +{ + return bitn(0x6671, i); +} + +int fc(unsigned int i) +{ + return bitn(0x7907287B, i); +} + +// the filter function that generates a bit of output from the prng state +int fnf(uint64_t s) +{ + unsigned int x1, x2, x3, x4, x5, x6; + + x1 = (bitn(s, 2) << 0) | (bitn(s, 3) << 1) | (bitn(s, 5) << 2) | (bitn(s, 6) << 3); + x2 = (bitn(s, 8) << 0) | (bitn(s, 12) << 1) | (bitn(s, 14) << 2) | (bitn(s, 15) << 3); + x3 = (bitn(s, 17) << 0) | (bitn(s, 21) << 1) | (bitn(s, 23) << 2) | (bitn(s, 26) << 3); + x4 = (bitn(s, 28) << 0) | (bitn(s, 29) << 1) | (bitn(s, 31) << 2) | (bitn(s, 33) << 3); + x5 = (bitn(s, 34) << 0) | (bitn(s, 43) << 1) | (bitn(s, 44) << 2) | (bitn(s, 46) << 3); + + x6 = (fa(x1) << 0) | (fb(x2) << 1) | (fb(x3) << 2) | (fb(x4) << 3) | (fa(x5) << 4); + + return fc(x6); +} + +// builds the lfsr for the prng (quick calcs for hitag2_nstep()) +void buildlfsr(Hitag_State *hstate) +{ + uint64_t state = hstate->shiftreg; + uint64_t temp; + + temp = state ^ (state >> 1); + hstate->lfsr = state ^ (state >> 6) ^ (state >> 16) + ^ (state >> 26) ^ (state >> 30) ^ (state >> 41) + ^ (temp >> 2) ^ (temp >> 7) ^ (temp >> 22) + ^ (temp >> 42) ^ (temp >> 46); +} + + + diff --git a/tools/hitag2crack/crack4/ht2crack2utils.h b/tools/hitag2crack/crack4/ht2crack2utils.h new file mode 100644 index 000000000..14eea840c --- /dev/null +++ b/tools/hitag2crack/crack4/ht2crack2utils.h @@ -0,0 +1,34 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "HardwareProfile.h" +#include "rfidler.h" +#include "util.h" + +#include "hitagcrypto.h" + +#define HEX_PER_ROW 16 + + + +void writebuf(unsigned char *buf, uint64_t val, unsigned int len); +void shexdump(unsigned char *data, int data_len); +void printbin(unsigned char *c); +void printbin2(uint64_t val, unsigned int size); +void printstate(Hitag_State *hstate); +unsigned char hex2bin(unsigned char c); +int bitn(uint64_t x, int bit); +int fnR(uint64_t x); +void rollback(Hitag_State *hstate, unsigned int steps); +int fa(unsigned int i); +int fb(unsigned int i); +int fc(unsigned int i); +int fnf(uint64_t s); +void buildlfsr(Hitag_State *hstate); diff --git a/tools/hitag2crack/crack4/ht2crack4.c b/tools/hitag2crack/crack4/ht2crack4.c new file mode 100644 index 000000000..da439692f --- /dev/null +++ b/tools/hitag2crack/crack4/ht2crack4.c @@ -0,0 +1,868 @@ +/* ht2crack4.c + * + * This is an implementation of the fast correlation attack in Section 4.4 of the + * paper, Lock It and Still Lose It - On the (In)Security of Automotive Remote + * Keyless Entry Systems by Garcia, Oswald, Kasper and Pavlides. + * It is essentially an attack on the HiTag2 cryptosystem; it uses a small number + * (between 4 and 32) of encrypted nonce and challenge response pairs for the same + * UID to recover the key. + * + * Key recovery is performed by enumerating all 65536 of the first 16 bits of the + * key and then, using the encrypted nonces and challenge response pairs, scoring + * all of the guesses for how likely they are to be the first 16 bits of the actual + * key. The best of these guesses are then expanded by 1 bit and the process + * iterates until all bits have been guessed. The resulting guesses are then searched + * for the one that is actually correct, testing against two pairs. + * + * The program reads in up to 32 encrypted nonce and challenge response pairs from + * the supplied file; the number actually used is specified on the command line + * (defaults to all those read in). The default size of the table is 800000 but this + * can be changed via the command line options. + * + * Using more encrypted nonce and challenge response pairs improves the chances of + * recovering the key and doesn't significantly add to the time it takes. + * + * Using a larger table also improves the chances of recovering the key but + * *significantly* increases the time it takes to run. + * + * Best recommendation is to use as many encrypted nonce and challenge response + * pairs as you can, and start with a table size of about 500000, as this will take + * around 45s to run. If it fails, run it again with a table size of 1000000, + * continuing to double the table size until it succeeds. Alternatively, start with + * a table size of about 3000000 and expect it to take around 4 mins to run, but + * with a high likelihood of success. + * + * Setting table size to a large number (~32000000) will likely blow up the stack + * during the recursive qsort(). This could be fixed by making the stack space + * larger but really, you need a smaller table and more encrypted nonces. + * + * The scoring of the guesses is controversial, having been tweaked over and again + * to find a measure that provides the best results. Feel free to tweak it yourself + * if you don't like it or want to try alternative metrics. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "ht2crack2utils.h" + +/* you could have more than 32 traces, but you shouldn't really need + * more than 16. You can still win with 8 if you're lucky. */ +#define MAX_NONCES 32 + +/* set this to the number of virtual cores you have */ +#define NUM_THREADS 8 + +/* encrypted nonce and keystream storage + * ks is ~enc_aR */ +struct nonce { + uint64_t enc_nR; + uint64_t ks; +}; + +/* guess table entry - we store key guesses and do the maths to convert + * to states in the code + * score is used for sorting purposes + * b0to31 is an array of the keystream generated from the init state + * that is later XORed with the encrypted nonce and key guess + */ +struct guess { + uint64_t key; + double score; + uint64_t b0to31[MAX_NONCES]; +}; + +/* thread_data is the data sent to the scoring threads */ +struct thread_data { + unsigned int start; + unsigned int end; + unsigned int size; +}; + +/* guess table and encrypted nonce/keystream table */ +struct guess *guesses = NULL; +unsigned int num_guesses; +struct nonce nonces[MAX_NONCES]; +unsigned int num_nRaR; +uint64_t uid; +int maxtablesize = 800000; +uint64_t supplied_testkey = 0; + +void usage() +{ + printf("ht2crack4 - K Sheldrake, based on the work of Garcia et al\n\n"); + printf("Cracks a HiTag2 key using a small number (4 to 16) of encrypted\n"); + printf("nonce and challenge response pairs, using a fast correlation\n"); + printf("approach.\n\n"); + printf(" -u UID (required)\n"); + printf(" -n NONCEFILE (required)\n"); + printf(" -N number of nRaR pairs to use (defaults to 32)\n"); + printf(" -t TABLESIZE (defaults to 800000\n"); + printf("Increasing the table size will slow it down but will be more\n"); + printf("successful.\n"); + + exit(1); +} + + +/* macros to select bits from lfsr states - from RFIDler code */ +#define pickbits2_2(S, A, B) ( ((S >> A) & 3) | ((S >> (B - 2)) & 0xC) ) +#define pickbits1x4(S, A, B, C, D) ( ((S >> A) & 1) | ((S >> (B - 1)) & 2) | \ + ((S >> (C - 2)) & 4) | ((S >> (D - 3)) & 8) ) +#define pickbits1_1_2(S, A, B, C) ( ((S >> A) & 1) | ((S >> (B - 1)) & 2) | \ + ((S >> (C - 2)) & 0xC) ) +#define pickbits2_1_1(S, A, B, C) ( ((S >> A) & 3) | ((S >> (B - 2)) & 4) | \ + ((S >> (C - 3)) & 8) ) +#define pickbits1_2_1(S, A, B, C) ( ((S >> A) & 1) | ((S >> (B - 1)) & 6) | \ + ((S >> (C - 3)) & 8) ) + +/* boolean tables for fns a, b and c - from RFIDler code */ +const uint64_t ht2_function4a = 0x2C79; // 0010 1100 0111 1001 +const uint64_t ht2_function4b = 0x6671; // 0110 0110 0111 0001 +const uint64_t ht2_function5c = 0x7907287B; // 0111 1001 0000 0111 0010 1000 0111 1011 + +/* following arrays are the probabilities of getting a 1 from each function, given + * a known least-sig pattern. first index is num bits in known part, second is the + * bit pattern of the known part. */ +double pfna[][8] = { +{0.50000, 0.50000, }, +{0.50000, 0.50000, 0.50000, 0.50000, }, +{0.50000, 0.00000, 0.50000, 1.00000, 0.50000, 1.00000, 0.50000, 0.00000, }, +}; +double pfnb[][8] = { +{0.62500, 0.37500, }, +{0.50000, 0.75000, 0.75000, 0.00000, }, +{0.50000, 0.50000, 0.50000, 0.00000, 0.50000, 1.00000, 1.00000, 0.00000, }, +}; +double pfnc[][16] = { +{0.50000, 0.50000, }, +{0.62500, 0.62500, 0.37500, 0.37500, }, +{0.75000, 0.50000, 0.25000, 0.75000, 0.50000, 0.75000, 0.50000, 0.00000, }, +{1.00000, 1.00000, 0.50000, 0.50000, 0.50000, 0.50000, 0.50000, 0.00000, 0.50000, 0.00000, 0.00000, 1.00000, 0.50000, 1.00000, 0.50000, 0.00000, }, +}; + + +/* hitag2_crypt works on the post-shifted form of the lfsr; this is the ref in rfidler code */ +static uint32_t hitag2_crypt(uint64_t s) +{ + uint32_t bitindex; + + bitindex = (ht2_function4a >> pickbits2_2 (s, 1, 4)) & 1; + bitindex |= ((ht2_function4b << 1) >> pickbits1_1_2 (s, 7, 11, 13)) & 0x02; + bitindex |= ((ht2_function4b << 2) >> pickbits1x4 (s, 16, 20, 22, 25)) & 0x04; + bitindex |= ((ht2_function4b << 3) >> pickbits2_1_1 (s, 27, 30, 32)) & 0x08; + bitindex |= ((ht2_function4a << 4) >> pickbits1_2_1(s, 33, 42, 45)) & 0x10; + + return (ht2_function5c >> bitindex) & 1; +} + +/* ht2crypt works on the pre-shifted form of the lfsr; this is the ref in the paper */ +uint64_t ht2crypt(uint64_t s) +{ + uint64_t bitindex; + + bitindex = (ht2_function4a >> pickbits2_2 (s, 2, 5)) & 1; + bitindex |= ((ht2_function4b << 1) >> pickbits1_1_2 (s, 8, 12, 14)) & 0x02; + bitindex |= ((ht2_function4b << 2) >> pickbits1x4 (s, 17, 21, 23, 26)) & 0x04; + bitindex |= ((ht2_function4b << 3) >> pickbits2_1_1 (s, 28, 31, 33)) & 0x08; + bitindex |= ((ht2_function4a << 4) >> pickbits1_2_1(s, 34, 43, 46)) & 0x10; + + return (ht2_function5c >> bitindex) & 1; +} + + +/* fnL is the feedback function for the reference code */ +uint64_t fnL(uint64_t x) +{ + return (bitn(x, 0) ^ bitn(x, 2) ^ bitn(x, 3) ^ bitn(x, 6) ^ bitn(x, 7) ^ bitn(x, 8) ^ + bitn(x, 16) ^ bitn(x, 22) ^ bitn(x, 23) ^ bitn(x, 26) ^ bitn(x, 30) ^ bitn(x, 41) ^ + bitn(x, 42) ^ bitn(x, 43) ^ bitn(x, 46) ^ bitn(x, 47)); +} + + +/* packed_size is an array that maps the number of confirmed bits in a state to + * the number of relevant bits. + * e.g. if there are 16 confirmed bits in a state, then packed_size[16] = 8 relevant bits. + * this is for pre-shifted lfsr */ +unsigned int packed_size[] = { 0, 0, 0, 1, 2, 2, 3, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8, + 8, 9, 9, 9, 9, 10, 10, 11, 11, 11, 12, 12, 13, 14, 14, 15, + 15, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 18, 19, 19, 20, 20 }; + + +/* f20 is the same as hitag2_crypt except it works on the packed version + * of the state where all 20 relevant bits are squashed together */ +uint64_t f20(uint64_t y) +{ + uint64_t bitindex; + + bitindex = (ht2_function4a >> (y & 0xf)) & 1; + bitindex |= ((ht2_function4b << 1) >> ((y >> 4) & 0xf)) & 0x02; + bitindex |= ((ht2_function4b << 2) >> ((y >> 8) & 0xf)) & 0x04; + bitindex |= ((ht2_function4b << 3) >> ((y >> 12) & 0xf)) & 0x08; + bitindex |= ((ht2_function4a << 4) >> ((y >> 16) & 0xf)) & 0x10; + + return (ht2_function5c >> bitindex) & 1; +} + + +/* packstate packs the relevant bits from LFSR state into 20 bits for pre-shifted lfsr */ +uint64_t packstate(uint64_t s) +{ + uint64_t packed; + + packed = pickbits2_2 (s, 2, 5); + packed |= (pickbits1_1_2 (s, 8, 12, 14) << 4); + packed |= (pickbits1x4 (s, 17, 21, 23, 26) << 8); + packed |= (pickbits2_1_1 (s, 28, 31, 33) << 12); + packed |= (pickbits1_2_1(s, 34, 43, 46) << 16); + + return packed; +} + + +/* create_guess_table mallocs the tables */ +void create_guess_table() +{ + guesses = (struct guess *)malloc(sizeof(struct guess) * maxtablesize); + if (!guesses) { + printf("cannot malloc guess table\n"); + exit(1); + } +} + + +/* init the guess table by reading in the encrypted nR,aR values and + * setting the first 2^16 key guesses */ +void init_guess_table(char *filename, char *uidstr) +{ + unsigned int i, j; + FILE *fp; + char *buf = NULL; + char *buft1 = NULL; + char *buft2 = NULL; + size_t lenbuf = 64; + + if (!guesses) { + printf("guesses is NULL\n"); + exit(1); + } + + // read uid + if (!strncmp(uidstr, "0x", 2)) { + uid = rev32(hexreversetoulong(uidstr + 2)); + } else { + uid = rev32(hexreversetoulong(uidstr)); + } + + + // read encrypted nonces and challenge response values + fp = fopen(filename, "r"); + if (!fp) { + printf("cannot open nRaR file\n"); + exit(1); + } + + num_nRaR = 0; + buf = (char *)malloc(lenbuf); + if (!buf) { + printf("cannot malloc buf\n"); + exit(1); + } + + while ((getline(&buf, &lenbuf, fp) > 0) && (num_nRaR < MAX_NONCES)) { + buft1 = strchr(buf, ' '); + if (!buft1) { + printf("invalid file input on line %d\n", num_nRaR + 1); + exit(1); + } + *buft1 = 0x00; + buft1++; + buft2 = strchr(buft1, '\n'); + if (!buft2) { + printf("no CR on line %d\n", num_nRaR + 1); + exit(1); + } + *buft2 = 0x00; + if (!strncmp(buf, "0x", 2)) { + nonces[num_nRaR].enc_nR = rev32(hexreversetoulong(buf+2)); + nonces[num_nRaR].ks = rev32(hexreversetoulong(buft1+2)) ^ 0xffffffff; + } else { + nonces[num_nRaR].enc_nR = rev32(hexreversetoulong(buf)); + nonces[num_nRaR].ks = rev32(hexreversetoulong(buft1)) ^ 0xffffffff; + } + num_nRaR++; + } + + fclose(fp); + fp = NULL; + + fprintf(stderr, "Loaded %d nRaR pairs\n", num_nRaR); + + // set key and copy in enc_nR and ks values + // set score to -1.0 to distinguish them from 0 scores + for (i=0; i<65536; i++) { + guesses[i].key = i; + guesses[i].score = -1.0; + for (j=0; j> (packed & 0xf)) & 1; + fncinput |= ((ht2_function4b << 1) >> ((packed >> 4) & 0xf)) & 0x02; + fncinput |= ((ht2_function4b << 2) >> ((packed >> 8) & 0xf)) & 0x04; + fncinput |= ((ht2_function4b << 3) >> ((packed >> 12) & 0xf)) & 0x08; + fncinput |= ((ht2_function4a << 4) >> ((packed >> 16) & 0xf)) & 0x10; + + // mask to keep the full nibble bits + fncinput = fncinput & ((1l << (n / 4)) - 1); + + if ((n % 4) == 0) { + // only complete nibbles + prob = pfnc[(n / 4) - 1][fncinput]; + } else { + // one nibble is incomplete + if (n <= 16) { + // it's in the fnb area + nibprob1 = pfnb[(n % 4) - 1][packed >> ((n / 4) * 4)]; + nibprob0 = 1.0 - nibprob1; + prob = (nibprob0 * pfnc[n / 4][fncinput]) + (nibprob1 * pfnc[n / 4][fncinput | (1l << (n / 4))]); + } else { + // it's in the final fna + nibprob1 = pfna[(n % 4) - 1][packed >> 16]; + nibprob0 = 1.0 - nibprob1; + prob = (nibprob0 * ((ht2_function5c >> fncinput) & 0x1)) + (nibprob1 * ((ht2_function5c >> (fncinput | 0x10)) & 0x1)); + } + } + } else { + // n==20 + prob = f20(packed); + } + + if (b1) { + return prob; + } else { + return (1.0 - prob); + } +} + + +/* score is like bit_score but does multiple bit correlation. + * bit_score and then shift and then repeat, adding all + * bit_scores together until no bits remain. bit_scores are + * multiplied by the number of relevant bits in the scored state + * to give weight to more complete states. */ +double score(uint64_t s, unsigned int size, uint64_t ks, unsigned int kssize) +{ + double sc, sc2; + + if ((size == 1) || (kssize == 1)) { + sc = bit_score(s, size, ks & 0x1); + return (sc * (packed_size[size] + 1)); + } else { + // I've introduced a weighting for each score to + // give more significance to bigger windows. + + sc = bit_score(s, size, ks & 0x1); + + // if a bit_score returns a probability of 0 then this can't be a winner + if (sc == 0.0) { + return 0.0; + } else { + + sc2 = score(s >> 1, size - 1, ks >> 1, kssize - 1); + + // if score returns a probability of 0 then this can't be a winner + if (sc2 == 0.0) { + return 0.0; + } else { + return (sc * (packed_size[size] + 1)) + sc2; + } + } + } +} + + +/* score_traces runs score for each encrypted nonce */ +void score_traces(struct guess *g, unsigned int size) +{ + uint64_t lfsr; + unsigned int i; + double sc; + double total_score = 0.0; + + // don't bother scoring traces that are already losers + if (g->score == 0.0) { + return; + } + + for (i=0; i> (size - 16)) | ((g->key << (48 - size)) ^ + ((nonces[i].enc_nR ^ g->b0to31[i]) << (64 - size))); + g->b0to31[i] = g->b0to31[i] | (ht2crypt(lfsr) << (size - 16)); + + // create lfsr - lower 16 bits are lower 16 bits of key + // bits 16-47 are upper bits of key XOR enc_nonce XOR bitstream + lfsr = g->key ^ ((nonces[i].enc_nR ^ g->b0to31[i]) << 16); + + sc = score(lfsr, size, nonces[i].ks, 32); + + // look out for losers + if (sc == 0.0) { + g->score = 0.0; + return; + } + total_score = total_score + sc; + } + + // save average score + g->score = total_score / num_nRaR; + +} + + +/* score_all_traces runs score_traces for every key guess in the table */ +/* this was used in the non-threaded version */ +/* +void score_all_traces(unsigned int size) +{ + unsigned int i; + + for (i=0; istart; iend; i++) { + score_traces(&(guesses[i]), tdata->size); + } + + return NULL; +} + + +/* score_all_traces runs score_traces for every key guess in the table */ +void score_all_traces(unsigned int size) +{ + pthread_t threads[NUM_THREADS]; + void *status; + struct thread_data tdata[NUM_THREADS]; + unsigned int i; + unsigned int chunk_size; + + chunk_size = num_guesses / NUM_THREADS; + + // create thread data + for (i=0; iscore < b1->score) { + return 1; + } else if (a1->score > b1->score) { + return -1; + } else { + return 0; + } +} + + +/* expand all guesses in first half of (sorted) table by + * copying them into the second half and extending the copied + * ones with an extra 1, leaving the first half with an extra 0 */ +void expand_guesses(unsigned int halfsize, unsigned int size) +{ + unsigned int i, j; + + for (i=0; i> 40) & 0xff) | ((revkey >> 24) & 0xff00) | ((revkey >> 8) & 0xff0000) | ((revkey << 8) & 0xff000000) | ((revkey << 24) & 0xff00000000) | ((revkey << 40) & 0xff0000000000); + fprintf(stderr, " guess=%012" PRIx64 ", num_guesses = %d, top score=%1.10f, min score=%1.10f\n", foundkey, num_guesses, guesses[0].score, guesses[num_guesses - 1].score); + } +} + + +/* test function to make sure I know how the LFSR works */ +void testkey(uint64_t key) +{ + uint64_t i; + uint64_t b0to31 = 0; + uint64_t ks = 0; + uint64_t lfsr; + uint64_t nRxorkey; + Hitag_State hstate; + + printf("ORIG REFERENCE\n"); + hitag2_init(&hstate, key, uid, nonces[0].enc_nR); + printf("after init with key, uid, nR:\n"); + printstate(&hstate); + b0to31 = 0; + for (i=0; i<32; i++) { + b0to31 = (b0to31 >> 1) | (hitag2_nstep(&hstate, 1) << 31); + } + printf("ks = 0x%08" PRIx64 ", enc_aR = 0x%08" PRIx64 ", aR = 0x%08" PRIx64 "\n", b0to31, nonces[0].ks ^ 0xffffffff, nonces[0].ks ^ 0xffffffff ^ b0to31); + printstate(&hstate); + + printf("\n"); + + + printf("MY REFERENCE\n"); + // build initial lfsr + lfsr = uid | ((key & 0xffff) << 32); + b0to31 = 0; + // xor upper part of key with encrypted nonce + nRxorkey = nonces[0].enc_nR ^ (key >> 16); + // insert keyupper xor encrypted nonce xor ks + for (i=0; i<32; i++) { + // store ks - when done, the first ks bit will be bit 0 and the last will be bit 31 + b0to31 = (b0to31 >> 1) | (ht2crypt(lfsr) << 31); + // insert new bit + lfsr = lfsr | ((((nRxorkey >> i) & 0x1) ^ ((b0to31 >> 31) & 0x1)) << 48); + // shift lfsr + lfsr = lfsr >> 1; + } + printf("after init with key, uid, nR:\n"); + printf("lfsr =\t\t"); + printbin2(lfsr, 48); + printf("\n"); + + // iterate lfsr with fnL, extracting ks + for (i=0; i<32; i++) { + // store ks - when done, the first ks bit will be bit 0 and the last will be bit 31 + ks = (ks >> 1) | (ht2crypt(lfsr) << 31); + // insert new bit + lfsr = lfsr | (fnL(lfsr) << 48); + // shift lfsr + lfsr = lfsr >> 1; + } + + printf("ks = 0x%08" PRIx64 ", aR = 0x%08" PRIx64 ", ks(orig) = 0x%08" PRIx64 ", aR(orig) = %08" PRIx64 "\n", ks, ks ^ 0xffffffff, nonces[0].ks, nonces[0].ks ^ 0xffffffff); + printf("lfsr = \t\t"); + printbin2(lfsr, 48); + printf("\n\n"); +} + + +/* test function to generate test data */ +void gen_bitstreams_testks(struct guess *g, uint64_t key) +{ + unsigned int i, j; + uint64_t nRxorkey, lfsr, ks; + + for (j=0; jb0to31[j] = 0; + // xor upper part of key with encrypted nonce + nRxorkey = nonces[j].enc_nR ^ (key >> 16); + // insert keyupper xor encrypted nonce xor ks + for (i=0; i<32; i++) { + // store ks - when done, the first ks bit will be bit 0 and the last will be bit 31 + g->b0to31[j] = (g->b0to31[j] >> 1) | (ht2crypt(lfsr) << 31); + // insert new bit + lfsr = lfsr | ((((nRxorkey >> i) & 0x1) ^ ((g->b0to31[j] >> 31) & 0x1)) << 48); + // shift lfsr + lfsr = lfsr >> 1; + } + + ks = 0; + // iterate lfsr with fnL, extracting ks + for (i=0; i<32; i++) { + // store ks - when done, the first ks bit will be bit 0 and the last will be bit 31 + ks = (ks >> 1) | (ht2crypt(lfsr) << 31); + // insert new bit + lfsr = lfsr | (fnL(lfsr) << 48); + // shift lfsr + lfsr = lfsr >> 1; + } + + printf("orig ks = 0x%08" PRIx64 ", gen ks = 0x%08" PRIx64 ", b0to31 = 0x%08" PRIx64 "\n", nonces[j].ks, ks, g->b0to31[j]); + if (nonces[j].ks != ks) { + printf(" FAIL!\n"); + } + } +} + + +/* test function */ +void test() +{ + uint64_t lfsr; + uint64_t packed; + + uint64_t i; + + + for (i=0; i<1000; i++) { + lfsr = ((uint64_t)rand() << 32) | rand(); + packed = packstate(lfsr); + + if (hitag2_crypt(lfsr) != f20(packed)) { + printf(" * * * FAIL: %3" PRIu64 ": 0x%012" PRIx64 " = %d, 0x%012" PRIx64 " = 0x%05" PRIx64 "\n", i, lfsr, hitag2_crypt(lfsr), packed, f20(packed)); + } + } + + printf("test done\n"); +} + + +/* check_key tests the potential key against an encrypted nonce, ks pair */ +int check_key(uint64_t key, uint64_t enc_nR, uint64_t ks) +{ + Hitag_State hstate; + uint64_t bits; + int i; + + hitag2_init(&hstate, key, uid, enc_nR); + bits = 0; + for (i=0; i<32; i++) { + bits = (bits >> 1) | (hitag2_nstep(&hstate, 1) << 31); + } + if (ks == bits) { + return 1; + } else { + return 0; + } +} + + +/* start up */ +int main(int argc, char *argv[]) +{ + unsigned int i; + uint64_t revkey; + uint64_t foundkey; + int tot_nRaR = 0; + char c; + char *uidstr = NULL; + char *noncefilestr = NULL; + +// test(); +// exit(0); + + while ((c = getopt(argc, argv, "u:n:N:t:T:h")) != -1) { + switch(c) { + case 'u': + uidstr = optarg; + break; + case 'n': + noncefilestr = optarg; + break; + case 'N': + tot_nRaR = atoi(optarg); + break; + case 't': + maxtablesize = atoi(optarg); + break; + case 'T': + supplied_testkey = rev64(hexreversetoulonglong(optarg)); + break; + case 'h': + usage(); + break; + default: + usage(); + } + } + + if (!uidstr || !noncefilestr || (maxtablesize <= 0)) { + usage(); + } + + create_guess_table(); + + init_guess_table(noncefilestr, uidstr); + + if ((tot_nRaR > 0) && (tot_nRaR <= num_nRaR)) { + num_nRaR = tot_nRaR; + } + fprintf(stderr, "Using %d nRaR pairs\n", num_nRaR); + + crack(); + + // test all key guesses and stop if one works + for (i=0; i> 40) & 0xff) | ((revkey >> 24) & 0xff00) | ((revkey >> 8) & 0xff0000) | ((revkey << 8) & 0xff000000) | ((revkey << 24) & 0xff00000000) | ((revkey << 40) & 0xff0000000000); + printf("key = %012" PRIX64 "\n", foundkey); + exit(0); + } + } + + printf("FAIL :( - none of the potential keys in the table are correct.\n"); + exit(1); + return 0; +} + + + diff --git a/tools/hitag2crack/crack4/readme.md b/tools/hitag2crack/crack4/readme.md new file mode 100644 index 000000000..a906700b1 --- /dev/null +++ b/tools/hitag2crack/crack4/readme.md @@ -0,0 +1,29 @@ +ht2crack4 + + + +Build +----- + +make clean +make + + +Run +--- + +You'll need a file consisting of 16 (or more) nR aR pairs. These are the +encrypted nonces and challenge response values. They should be in hex with +one pair per line, e.g.: +0x12345678 0x9abcdef0 + +./ht2crack4 -u UID -n NRARFILE [-N nonces to use] [-t table size] + +UID is the UID of the tag that you used to gather the nR aR values. +NRARFILE is the file containing the nR aR values. +The number of nonces to use allows you to use less than 32 nonces to increase +speed. +The table size can be tweaked for speed. Start with 500000 and double it each +time it fails to find the key. + + diff --git a/tools/hitag2crack/crack4/rfidler.h b/tools/hitag2crack/crack4/rfidler.h new file mode 100644 index 000000000..c8ce90396 --- /dev/null +++ b/tools/hitag2crack/crack4/rfidler.h @@ -0,0 +1,412 @@ +/*************************************************************************** + * A copy of the GNU GPL is appended to this file. * + * * + * This licence is based on the nmap licence, and we express our gratitude * + * for the work that went into producing it. There is no other connection * + * between RFIDler and nmap either expressed or implied. * + * * + ********************** IMPORTANT RFIDler LICENSE TERMS ******************** + * * + * * + * All references to RFIDler herein imply all it's derivatives, namely: * + * * + * o RFIDler-LF Standard * + * o RFIDler-LF Lite * + * o RFIDler-LF Nekkid * + * * + * * + * RFIDler is (C) 2013-2015 Aperture Labs Ltd. * + * * + * This program is free software; you may redistribute and/or modify it * + * under the terms of the GNU General Public License as published by the * + * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE * + * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your * + * right to use, modify, and redistribute this software under certain * + * conditions. If you wish to embed RFIDler technology into proprietary * + * software or hardware, we sell alternative licenses * + * (contact sales@aperturelabs.com). * + * * + * Note that the GPL places important restrictions on "derivative works", * + * yet it does not provide a detailed definition of that term. To avoid * + * misunderstandings, we interpret that term as broadly as copyright law * + * allows. For example, we consider an application to constitute a * + * derivative work for the purpose of this license if it does any of the * + * following with any software or content covered by this license * + * ("Covered Software"): * + * * + * o Integrates source code from Covered Software. * + * * + * o Is designed specifically to execute Covered Software and parse the * + * results (as opposed to typical shell or execution-menu apps, which will * + * execute anything you tell them to). * + * * + * o Includes Covered Software in a proprietary executable installer. The * + * installers produced by InstallShield are an example of this. Including * + * RFIDler with other software in compressed or archival form does not * + * trigger this provision, provided appropriate open source decompression * + * or de-archiving software is widely available for no charge. For the * + * purposes of this license, an installer is considered to include Covered * + * Software even if it actually retrieves a copy of Covered Software from * + * another source during runtime (such as by downloading it from the * + * Internet). * + * * + * o Links (statically or dynamically) to a library which does any of the * + * above. * + * * + * o Executes a helper program, module, or script to do any of the above. * + * * + * This list is not exclusive, but is meant to clarify our interpretation * + * of derived works with some common examples. Other people may interpret * + * the plain GPL differently, so we consider this a special exception to * + * the GPL that we apply to Covered Software. Works which meet any of * + * these conditions must conform to all of the terms of this license, * + * particularly including the GPL Section 3 requirements of providing * + * source code and allowing free redistribution of the work as a whole. * + * * + * As another special exception to the GPL terms, Aperture Labs Ltd. grants* + * permission to link the code of this program with any version of the * + * OpenSSL library which is distributed under a license identical to that * + * listed in the included docs/licenses/OpenSSL.txt file, and distribute * + * linked combinations including the two. * + * * + * Any redistribution of Covered Software, including any derived works, * + * must obey and carry forward all of the terms of this license, including * + * obeying all GPL rules and restrictions. For example, source code of * + * the whole work must be provided and free redistribution must be * + * allowed. All GPL references to "this License", are to be treated as * + * including the terms and conditions of this license text as well. * + * * + * Because this license imposes special exceptions to the GPL, Covered * + * Work may not be combined (even as part of a larger work) with plain GPL * + * software. The terms, conditions, and exceptions of this license must * + * be included as well. This license is incompatible with some other open * + * source licenses as well. In some cases we can relicense portions of * + * RFIDler or grant special permissions to use it in other open source * + * software. Please contact sales@aperturelabs.com with any such requests.* + * Similarly, we don't incorporate incompatible open source software into * + * Covered Software without special permission from the copyright holders. * + * * + * If you have any questions about the licensing restrictions on using * + * RFIDler in other works, are happy to help. As mentioned above, we also * + * offer alternative license to integrate RFIDler into proprietary * + * applications and appliances. These contracts have been sold to dozens * + * of software vendors, and generally include a perpetual license as well * + * as providing for priority support and updates. They also fund the * + * continued development of RFIDler. Please email sales@aperturelabs.com * + * for further information. * + * If you have received a written license agreement or contract for * + * Covered Software stating terms other than these, you may choose to use * + * and redistribute Covered Software under those terms instead of these. * + * * + * Source is provided to this software because we believe users have a * + * right to know exactly what a program is going to do before they run it. * + * This also allows you to audit the software for security holes (none * + * have been found so far). * + * * + * Source code also allows you to port RFIDler to new platforms, fix bugs, * + * and add new features. You are highly encouraged to send your changes * + * to the RFIDler mailing list for possible incorporation into the * + * main distribution. By sending these changes to Aperture Labs Ltd. or * + * one of the Aperture Labs Ltd. development mailing lists, or checking * + * them into the RFIDler source code repository, it is understood (unless * + * you specify otherwise) that you are offering the RFIDler Project * + * (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, * + * modify, and relicense the code. RFIDler will always be available Open * + * Source, but this is important because the inability to relicense code * + * has caused devastating problems for other Free Software projects (such * + * as KDE and NASM). We also occasionally relicense the code to third * + * parties as discussed above. If you wish to specify special license * + * conditions of your contributions, just say so when you send them. * + * * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler * + * license file for more details (it's in a COPYING file included with * + * RFIDler, and also available from * + * https://github.com/ApertureLabsLtd/RFIDler/COPYING * + * * + ***************************************************************************/ + +// Author: Adam Laurie + +#include +#include + +// BCD hardware revision for usb descriptor (usb_descriptors.c) +#define RFIDLER_HW_VERSION 0x020 + +// max sizes in BITS +#define MAXBLOCKSIZE 512 +#define MAXTAGSIZE 4096 +#define MAXUID 512 + +#define TMP_LARGE_BUFF_LEN 2048 +#define TMP_SMALL_BUFF_LEN 256 +#define ANALOGUE_BUFF_LEN 8192 + +#define COMMS_BUFFER_SIZE 128 + +#define DETECT_BUFFER_SIZE 512 + +#define SAMPLEMASK ~(BIT_1 | BIT_0) // mask to remove two bottom bits from analogue sample - we will then use those for reader & bit period + +// globals + +extern BOOL WiegandOutput; // Output wiegand data whenenver UID is read +extern BYTE *EMU_Reset_Data; // Pointer to full array of bits as bytes, stored as 0x00/0x01, '*' terminated +extern BYTE *EMU_Data; // Pointer to current location in EMU_Reset_Data +extern BYTE EMU_ThisBit; // The next data bit to transmit +extern BYTE EMU_SubCarrier_T0; // Number of Frame Clocks for sub-carrier '0' +extern BYTE EMU_SubCarrier_T1; // Number of Frame Clocks for sub-carrier '1' +extern unsigned int EMU_Repeat; // Number of times to transmit full data set +extern BOOL EMU_Background; // Emulate in the background until told to stop +extern unsigned int EMU_DataBitRate; // Number of Frame Clocks per bit +extern BYTE TmpBits[TMP_LARGE_BUFF_LEN]; // Shared scratchpad +extern BYTE ReaderPeriod; // Flag for sample display +extern unsigned char Comms_In_Buffer[COMMS_BUFFER_SIZE]; // USB/Serial buffer +extern BYTE Interface; // user interface - CLI or API +extern BYTE CommsChannel; // user comms channel - USB or UART +extern BOOL FakeRead; // flag for analogue sampler to signal it wants access to buffers during read +extern BOOL PWD_Mode; // is this tag password protected? +extern BYTE Password[9]; // 32 bits as HEX string set with LOGIN +extern unsigned int Led_Count; // LED status counter, also used for entropy +extern unsigned long Reader_Bit_Count; // Reader ISR bit counter +extern char Previous; // Reader ISR previous bit type + +// RWD (read/write device) coil state +extern BYTE RWD_State; // current state of RWD coil +extern unsigned int RWD_Fc; // field clock in uS +extern unsigned int RWD_Gap_Period; // length of command gaps in OC5 ticks +extern unsigned int RWD_Zero_Period; // length of '0' in OC5 ticks +extern unsigned int RWD_One_Period; // length of '1' in OC5 ticks +extern unsigned int RWD_Sleep_Period; // length of initial sleep to reset tag in OC5 ticks +extern unsigned int RWD_Wake_Period; // length required for tag to restart in OC5 ticks +extern unsigned int RWD_Wait_Switch_TX_RX; // length to wait when switching from TX to RX in OC5 ticks +extern unsigned int RWD_Wait_Switch_RX_TX; // length to wait when switching from RX to TX in OC5 ticks +extern unsigned int RWD_Post_Wait; // low level ISR wait period in OC5 ticks +extern unsigned int RWD_OC5_config; // Output Compare Module settings +extern unsigned int RWD_OC5_r; // Output Compare Module primary compare value +extern unsigned int RWD_OC5_rs; // Output Compare Module secondary compare value +extern BYTE RWD_Command_Buff[TMP_SMALL_BUFF_LEN]; // Command buffer, array of bits as bytes, stored as 0x00/0x01, '*' terminated +extern BYTE *RWD_Command_ThisBit; // Current command bit +extern BOOL Reader_ISR_State; // current state of reader ISR + +// NVM variables +// timings etc. that want to survive a reboot should go here +typedef struct { + BYTE Name[7]; // will be set to "RFIDler" so we can test for new device + BYTE AutoRun[128]; // optional command to run at startup + unsigned char TagType; + unsigned int PSK_Quality; + unsigned int Timeout; + unsigned int Wiegand_Pulse; + unsigned int Wiegand_Gap; + BOOL Wiegand_IdleState; + unsigned int FrameClock; + unsigned char Modulation; + unsigned int DataRate; + unsigned int DataRateSub0; + unsigned int DataRateSub1; + unsigned int DataBits; + unsigned int DataBlocks; + unsigned int BlockSize; + unsigned char SyncBits; + BYTE Sync[4]; + BOOL BiPhase; + BOOL Invert; + BOOL Manchester; + BOOL HalfDuplex; + unsigned int Repeat; + unsigned int PotLow; + unsigned int PotHigh; + unsigned int RWD_Gap_Period; + unsigned int RWD_Zero_Period; + unsigned int RWD_One_Period; + unsigned int RWD_Sleep_Period; + unsigned int RWD_Wake_Period; + unsigned int RWD_Wait_Switch_TX_RX; + unsigned int RWD_Wait_Switch_RX_TX; +} StoredConfig; + +// somewhere to store TAG data. this will be interpreted according to the TAG +// type. +typedef struct { + BYTE TagType; // raw tag type + BYTE EmulatedTagType; // tag type this tag is configured to emulate + BYTE UID[MAXUID + 1]; // Null-terminated HEX string + BYTE Data[MAXTAGSIZE]; // raw data + unsigned char DataBlocks; // number of blocks in Data field + unsigned int BlockSize; // blocksize in bits +} VirtualTag; + +extern StoredConfig RFIDlerConfig; +extern VirtualTag RFIDlerVTag; +extern BYTE TmpBuff[NVM_PAGE_SIZE]; +extern BYTE DataBuff[ANALOGUE_BUFF_LEN]; +extern unsigned int DataBuffCount; +extern const BYTE *ModulationSchemes[]; +extern const BYTE *OnOff[]; +extern const BYTE *HighLow[]; +extern const BYTE *TagTypes[]; + +// globals for ISRs +extern BYTE EmulationMode; +extern unsigned long HW_Bits; +extern BYTE HW_Skip_Bits; +extern unsigned int PSK_Min_Pulse; +extern BOOL PSK_Read_Error; +extern BOOL Manchester_Error; +extern BOOL SnifferMode; +extern unsigned int Clock_Tick_Counter; +extern BOOL Clock_Tick_Counter_Reset; + +// smart card lib +#define MAX_ATR_LEN (BYTE)33 +extern BYTE scCardATR[MAX_ATR_LEN]; +extern BYTE scATRLength; + +// RTC +extern rtccTime RTC_time; // time structure +extern rtccDate RTC_date; // date structure + +// digital pots +#define POTLOW_DEFAULT 100 +#define POTHIGH_DEFAULT 150 +#define DC_OFFSET 60 // analogue circuit DC offset (as close as we can get without using 2 LSB) +#define VOLTS_TO_POT 0.019607843F + +// RWD/clock states +#define RWD_STATE_INACTIVE 0 // RWD not in use +#define RWD_STATE_GO_TO_SLEEP 1 // RWD coil shutdown request +#define RWD_STATE_SLEEPING 2 // RWD coil shutdown for sleep period +#define RWD_STATE_WAKING 3 // RWD active for pre-determined period after reset +#define RWD_STATE_START_SEND 4 // RWD starting send of data +#define RWD_STATE_SENDING_GAP 5 // RWD sending a gap +#define RWD_STATE_SENDING_BIT 6 // RWD sending a data bit +#define RWD_STATE_POST_WAIT 7 // RWD finished sending data, now in forced wait period +#define RWD_STATE_ACTIVE 8 // RWD finished, now just clocking a carrier + +// reader ISR states +#define READER_STOPPED 0 // reader not in use +#define READER_IDLING 1 // reader ISR running to preserve timing, but not reading +#define READER_RUNNING 2 // reader reading bits + + +// user interface types +#define INTERFACE_API 0 +#define INTERFACE_CLI 1 + +// comms channel +#define COMMS_NONE 0 +#define COMMS_USB 1 +#define COMMS_UART 2 + +#define MAX_HISTORY 2 // disable most of history for now - memory issue + +// tag write retries +#define TAG_WRITE_RETRY 5 + +// modulation modes - uppdate ModulationSchemes[] in tags.c if you change this +#define MOD_MODE_NONE 0 +#define MOD_MODE_ASK_OOK 1 +#define MOD_MODE_FSK1 2 +#define MOD_MODE_FSK2 3 +#define MOD_MODE_PSK1 4 +#define MOD_MODE_PSK2 5 +#define MOD_MODE_PSK3 6 + +// TAG types - update TagTypes[] in tags.c if you add to this list +#define TAG_TYPE_NONE 0 +#define TAG_TYPE_ASK_RAW 1 +#define TAG_TYPE_FSK1_RAW 2 +#define TAG_TYPE_FSK2_RAW 3 +#define TAG_TYPE_PSK1_RAW 4 +#define TAG_TYPE_PSK2_RAW 5 +#define TAG_TYPE_PSK3_RAW 6 +#define TAG_TYPE_HITAG1 7 +#define TAG_TYPE_HITAG2 8 +#define TAG_TYPE_EM4X02 9 +#define TAG_TYPE_Q5 10 +#define TAG_TYPE_HID_26 11 +#define TAG_TYPE_INDALA_64 12 +#define TAG_TYPE_INDALA_224 13 +#define TAG_TYPE_UNIQUE 14 +#define TAG_TYPE_FDXB 15 +#define TAG_TYPE_T55X7 16 // same as Q5 but different timings and no modulation-defeat +#define TAG_TYPE_AWID_26 17 +#define TAG_TYPE_EM4X05 18 +#define TAG_TYPE_TAMAGOTCHI 19 +#define TAG_TYPE_HDX 20 // same underlying data as FDX-B, but different modulation & telegram + +// various + +#define BINARY 0 +#define HEX 1 + +#define NO_ADDRESS -1 + +#define ACK TRUE +#define NO_ACK FALSE + +#define BLOCK TRUE +#define NO_BLOCK FALSE + +#define DATA TRUE +#define NO_DATA FALSE + +#define DEBUG_PIN_ON HIGH +#define DEBUG_PIN_OFF LOW + +#define FAST FALSE +#define SLOW TRUE + +#define NO_TRIGGER 0 + +#define LOCK TRUE +#define NO_LOCK FALSE + +#define NFC_MODE TRUE +#define NO_NFC_MODE FALSE + +#define ONESHOT_READ TRUE +#define NO_ONESHOT_READ FALSE + +#define RESET TRUE +#define NO_RESET FALSE + +#define SHUTDOWN_CLOCK TRUE +#define NO_SHUTDOWN_CLOCK FALSE + +#define SYNC TRUE +#define NO_SYNC FALSE + +#define VERIFY TRUE +#define NO_VERIFY FALSE + +#define VOLATILE FALSE +#define NON_VOLATILE TRUE + +#define NEWLINE TRUE +#define NO_NEWLINE FALSE + +#define WAIT TRUE +#define NO_WAIT FALSE + +#define WIPER_HIGH 0 +#define WIPER_LOW 1 + +// conversion for time to ticks +#define US_TO_TICKS 1000000L +#define US_OVER_10_TO_TICKS 10000000L +#define US_OVER_100_TO_TICKS 100000000L +// we can't get down to this level on pic, but we want to standardise on timings, so for now we fudge it +#define CONVERT_TO_TICKS(x) ((x / 10) * (GetSystemClock() / US_OVER_10_TO_TICKS)) +#define CONVERT_TICKS_TO_US(x) (x / (GetSystemClock() / US_TO_TICKS)) +#define TIMER5_PRESCALER 16 +#define MAX_TIMER5_TICKS (65535 * TIMER5_PRESCALER) + +// other conversions + +// bits to hex digits +#define HEXDIGITS(x) (x / 4) +#define HEXTOBITS(x) (x * 4) diff --git a/tools/hitag2crack/crack4/util.h b/tools/hitag2crack/crack4/util.h new file mode 100644 index 000000000..c2399c37c --- /dev/null +++ b/tools/hitag2crack/crack4/util.h @@ -0,0 +1,147 @@ +/*************************************************************************** + * A copy of the GNU GPL is appended to this file. * + * * + * This licence is based on the nmap licence, and we express our gratitude * + * for the work that went into producing it. There is no other connection * + * between RFIDler and nmap either expressed or implied. * + * * + ********************** IMPORTANT RFIDler LICENSE TERMS ******************** + * * + * * + * All references to RFIDler herein imply all it's derivatives, namely: * + * * + * o RFIDler-LF Standard * + * o RFIDler-LF Lite * + * o RFIDler-LF Nekkid * + * * + * * + * RFIDler is (C) 2013-2015 Aperture Labs Ltd. * + * * + * This program is free software; you may redistribute and/or modify it * + * under the terms of the GNU General Public License as published by the * + * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE * + * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your * + * right to use, modify, and redistribute this software under certain * + * conditions. If you wish to embed RFIDler technology into proprietary * + * software or hardware, we sell alternative licenses * + * (contact sales@aperturelabs.com). * + * * + * Note that the GPL places important restrictions on "derivative works", * + * yet it does not provide a detailed definition of that term. To avoid * + * misunderstandings, we interpret that term as broadly as copyright law * + * allows. For example, we consider an application to constitute a * + * derivative work for the purpose of this license if it does any of the * + * following with any software or content covered by this license * + * ("Covered Software"): * + * * + * o Integrates source code from Covered Software. * + * * + * o Is designed specifically to execute Covered Software and parse the * + * results (as opposed to typical shell or execution-menu apps, which will * + * execute anything you tell them to). * + * * + * o Includes Covered Software in a proprietary executable installer. The * + * installers produced by InstallShield are an example of this. Including * + * RFIDler with other software in compressed or archival form does not * + * trigger this provision, provided appropriate open source decompression * + * or de-archiving software is widely available for no charge. For the * + * purposes of this license, an installer is considered to include Covered * + * Software even if it actually retrieves a copy of Covered Software from * + * another source during runtime (such as by downloading it from the * + * Internet). * + * * + * o Links (statically or dynamically) to a library which does any of the * + * above. * + * * + * o Executes a helper program, module, or script to do any of the above. * + * * + * This list is not exclusive, but is meant to clarify our interpretation * + * of derived works with some common examples. Other people may interpret * + * the plain GPL differently, so we consider this a special exception to * + * the GPL that we apply to Covered Software. Works which meet any of * + * these conditions must conform to all of the terms of this license, * + * particularly including the GPL Section 3 requirements of providing * + * source code and allowing free redistribution of the work as a whole. * + * * + * As another special exception to the GPL terms, Aperture Labs Ltd. grants* + * permission to link the code of this program with any version of the * + * OpenSSL library which is distributed under a license identical to that * + * listed in the included docs/licenses/OpenSSL.txt file, and distribute * + * linked combinations including the two. * + * * + * Any redistribution of Covered Software, including any derived works, * + * must obey and carry forward all of the terms of this license, including * + * obeying all GPL rules and restrictions. For example, source code of * + * the whole work must be provided and free redistribution must be * + * allowed. All GPL references to "this License", are to be treated as * + * including the terms and conditions of this license text as well. * + * * + * Because this license imposes special exceptions to the GPL, Covered * + * Work may not be combined (even as part of a larger work) with plain GPL * + * software. The terms, conditions, and exceptions of this license must * + * be included as well. This license is incompatible with some other open * + * source licenses as well. In some cases we can relicense portions of * + * RFIDler or grant special permissions to use it in other open source * + * software. Please contact sales@aperturelabs.com with any such requests.* + * Similarly, we don't incorporate incompatible open source software into * + * Covered Software without special permission from the copyright holders. * + * * + * If you have any questions about the licensing restrictions on using * + * RFIDler in other works, are happy to help. As mentioned above, we also * + * offer alternative license to integrate RFIDler into proprietary * + * applications and appliances. These contracts have been sold to dozens * + * of software vendors, and generally include a perpetual license as well * + * as providing for priority support and updates. They also fund the * + * continued development of RFIDler. Please email sales@aperturelabs.com * + * for further information. * + * If you have received a written license agreement or contract for * + * Covered Software stating terms other than these, you may choose to use * + * and redistribute Covered Software under those terms instead of these. * + * * + * Source is provided to this software because we believe users have a * + * right to know exactly what a program is going to do before they run it. * + * This also allows you to audit the software for security holes (none * + * have been found so far). * + * * + * Source code also allows you to port RFIDler to new platforms, fix bugs, * + * and add new features. You are highly encouraged to send your changes * + * to the RFIDler mailing list for possible incorporation into the * + * main distribution. By sending these changes to Aperture Labs Ltd. or * + * one of the Aperture Labs Ltd. development mailing lists, or checking * + * them into the RFIDler source code repository, it is understood (unless * + * you specify otherwise) that you are offering the RFIDler Project * + * (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, * + * modify, and relicense the code. RFIDler will always be available Open * + * Source, but this is important because the inability to relicense code * + * has caused devastating problems for other Free Software projects (such * + * as KDE and NASM). We also occasionally relicense the code to third * + * parties as discussed above. If you wish to specify special license * + * conditions of your contributions, just say so when you send them. * + * * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler * + * license file for more details (it's in a COPYING file included with * + * RFIDler, and also available from * + * https://github.com/ApertureLabsLtd/RFIDler/COPYING * + * * + ***************************************************************************/ + +// Author: Adam Laurie + +/* + * Hitag Crypto support macros + * These macros reverse the bit order in a byte, or *within* each byte of a + * 16 , 32 or 64 bit unsigned integer. (Not across the whole 16 etc bits.) + */ +#define rev8(X) ((((X) >> 7) &1) + (((X) >> 5) &2) + (((X) >> 3) &4) \ + + (((X) >> 1) &8) + (((X) << 1) &16) + (((X) << 3) &32) \ + + (((X) << 5) &64) + (((X) << 7) &128) ) +#define rev16(X) (rev8 (X) + (rev8 (X >> 8) << 8)) +#define rev32(X) (rev16(X) + (rev16(X >> 16) << 16)) +#define rev64(X) (rev32(X) + (rev32(X >> 32) << 32)) + + +unsigned long hexreversetoulong(BYTE *hex); +unsigned long long hexreversetoulonglong(BYTE *hex); + diff --git a/tools/hitag2crack/crack4/utilpart.c b/tools/hitag2crack/crack4/utilpart.c new file mode 100644 index 000000000..210853ec1 --- /dev/null +++ b/tools/hitag2crack/crack4/utilpart.c @@ -0,0 +1,183 @@ +/*************************************************************************** + * A copy of the GNU GPL is appended to this file. * + * * + * This licence is based on the nmap licence, and we express our gratitude * + * for the work that went into producing it. There is no other connection * + * between RFIDler and nmap either expressed or implied. * + * * + ********************** IMPORTANT RFIDler LICENSE TERMS ******************** + * * + * * + * All references to RFIDler herein imply all it's derivatives, namely: * + * * + * o RFIDler-LF Standard * + * o RFIDler-LF Lite * + * o RFIDler-LF Nekkid * + * * + * * + * RFIDler is (C) 2013-2014 Aperture Labs Ltd. * + * * + * This program is free software; you may redistribute and/or modify it * + * under the terms of the GNU General Public License as published by the * + * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE * + * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your * + * right to use, modify, and redistribute this software under certain * + * conditions. If you wish to embed RFIDler technology into proprietary * + * software or hardware, we sell alternative licenses * + * (contact sales@aperturelabs.com). * + * * + * Note that the GPL places important restrictions on "derivative works", * + * yet it does not provide a detailed definition of that term. To avoid * + * misunderstandings, we interpret that term as broadly as copyright law * + * allows. For example, we consider an application to constitute a * + * derivative work for the purpose of this license if it does any of the * + * following with any software or content covered by this license * + * ("Covered Software"): * + * * + * o Integrates source code from Covered Software. * + * * + * o Is designed specifically to execute Covered Software and parse the * + * results (as opposed to typical shell or execution-menu apps, which will * + * execute anything you tell them to). * + * * + * o Includes Covered Software in a proprietary executable installer. The * + * installers produced by InstallShield are an example of this. Including * + * RFIDler with other software in compressed or archival form does not * + * trigger this provision, provided appropriate open source decompression * + * or de-archiving software is widely available for no charge. For the * + * purposes of this license, an installer is considered to include Covered * + * Software even if it actually retrieves a copy of Covered Software from * + * another source during runtime (such as by downloading it from the * + * Internet). * + * * + * o Links (statically or dynamically) to a library which does any of the * + * above. * + * * + * o Executes a helper program, module, or script to do any of the above. * + * * + * This list is not exclusive, but is meant to clarify our interpretation * + * of derived works with some common examples. Other people may interpret * + * the plain GPL differently, so we consider this a special exception to * + * the GPL that we apply to Covered Software. Works which meet any of * + * these conditions must conform to all of the terms of this license, * + * particularly including the GPL Section 3 requirements of providing * + * source code and allowing free redistribution of the work as a whole. * + * * + * As another special exception to the GPL terms, Aperture Labs Ltd. grants* + * permission to link the code of this program with any version of the * + * OpenSSL library which is distributed under a license identical to that * + * listed in the included docs/licenses/OpenSSL.txt file, and distribute * + * linked combinations including the two. * + * * + * Any redistribution of Covered Software, including any derived works, * + * must obey and carry forward all of the terms of this license, including * + * obeying all GPL rules and restrictions. For example, source code of * + * the whole work must be provided and free redistribution must be * + * allowed. All GPL references to "this License", are to be treated as * + * including the terms and conditions of this license text as well. * + * * + * Because this license imposes special exceptions to the GPL, Covered * + * Work may not be combined (even as part of a larger work) with plain GPL * + * software. The terms, conditions, and exceptions of this license must * + * be included as well. This license is incompatible with some other open * + * source licenses as well. In some cases we can relicense portions of * + * RFIDler or grant special permissions to use it in other open source * + * software. Please contact sales@aperturelabs.com with any such requests.* + * Similarly, we don't incorporate incompatible open source software into * + * Covered Software without special permission from the copyright holders. * + * * + * If you have any questions about the licensing restrictions on using * + * RFIDler in other works, are happy to help. As mentioned above, we also * + * offer alternative license to integrate RFIDler into proprietary * + * applications and appliances. These contracts have been sold to dozens * + * of software vendors, and generally include a perpetual license as well * + * as providing for priority support and updates. They also fund the * + * continued development of RFIDler. Please email sales@aperturelabs.com * + * for further information. * + * If you have received a written license agreement or contract for * + * Covered Software stating terms other than these, you may choose to use * + * and redistribute Covered Software under those terms instead of these. * + * * + * Source is provided to this software because we believe users have a * + * right to know exactly what a program is going to do before they run it. * + * This also allows you to audit the software for security holes (none * + * have been found so far). * + * * + * Source code also allows you to port RFIDler to new platforms, fix bugs, * + * and add new features. You are highly encouraged to send your changes * + * to the RFIDler mailing list for possible incorporation into the * + * main distribution. By sending these changes to Aperture Labs Ltd. or * + * one of the Aperture Labs Ltd. development mailing lists, or checking * + * them into the RFIDler source code repository, it is understood (unless * + * you specify otherwise) that you are offering the RFIDler Project * + * (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, * + * modify, and relicense the code. RFIDler will always be available Open * + * Source, but this is important because the inability to relicense code * + * has caused devastating problems for other Free Software projects (such * + * as KDE and NASM). We also occasionally relicense the code to third * + * parties as discussed above. If you wish to specify special license * + * conditions of your contributions, just say so when you send them. * + * * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler * + * license file for more details (it's in a COPYING file included with * + * RFIDler, and also available from * + * https://github.com/ApertureLabsLtd/RFIDler/COPYING * + * * + ***************************************************************************/ + +// Author: Adam Laurie + + +#include +#include +#include "HardwareProfile.h" +#include "util.h" +#include "rfidler.h" +//#include "comms.h" + +// rtc +rtccTime RTC_time; // time structure +rtccDate RTC_date; // date structure + +// convert byte-reversed 8 digit hex to unsigned long +unsigned long hexreversetoulong(BYTE *hex) +{ + unsigned long ret= 0L; + unsigned int x; + BYTE i; + + if(strlen(hex) != 8) + return 0L; + + for(i= 0 ; i < 4 ; ++i) + { + if(sscanf(hex, "%2X", &x) != 1) + return 0L; + ret += ((unsigned long) x) << i * 8; + hex += 2; + } + return ret; +} + +// convert byte-reversed 12 digit hex to unsigned long +unsigned long long hexreversetoulonglong(BYTE *hex) +{ + unsigned long long ret= 0LL; + BYTE tmp[9]; + + // this may seem an odd way to do it, but weird compiler issues were + // breaking direct conversion! + + tmp[8]= '\0'; + memset(tmp + 4, '0', 4); + memcpy(tmp, hex + 8, 4); + ret= hexreversetoulong(tmp); + ret <<= 32; + memcpy(tmp, hex, 8); + ret += hexreversetoulong(tmp); + return ret; +} + + diff --git a/tools/hitag2crack/readme.md b/tools/hitag2crack/readme.md new file mode 100644 index 000000000..afbc5f4c3 --- /dev/null +++ b/tools/hitag2crack/readme.md @@ -0,0 +1,206 @@ +HiTag2 Cracking Suite +--------------------- + +Author: Kevin Sheldrake + +Introduction +------------ + +These tools are implementations of the four attacks detailed in the papers, +Gone In 360 Seconds - Hijacking With HiTag 2 by Roel Verdult, Flavio Garcia +and Josep Balasch, and Lock It And Still Lose It - on the (In)Security of +Automotive Remote Keyless Entry Systems by Flavio Garcia, David Oswald, +Timo Kasper and Pierre Pavlides. The first three attacks come from the first +paper and the fourth attack comes from the second paper. + +Attack 1 +-------- + +Attack 1 is a nonce replay and length extension attack. This is an attack on +a single HiTag2 RFID tag, given a single encrypted nonce and challenge +response value pair (nR, aR) for the tag's UID. The attack runs entirely on +the RFIDler with it acting like a RWD that replays the same encrypted nonce +and challenge response pair for every interaction; this fixes the key stream +that the tag's PRNG outputs to the same stream for every interaction. + +By brute forcing a subset of the encrypted command space, the RFIDler finds a +single valid encrypted command - invalid commands return a known unencrypted +error response so finding a valid one is simply a case of trying different +values until a response other than the error response is received. + +It then bit flips the valid encrypted command to find the other 15 valid +encrypted commands. By knowing the contents of page 0 - it's the UID that +is presented in clear at the start of each interaction - it tries each +encrypyted response in turn, assuming each to be the encrypted version of +'read page 0 non-inverted' and each response to be the encrypted version of +page 0. + +For each attempted command, it calculates the key stream that would have +correctly generated the encrypted command and response: +command ++ response XOR key stream = encrypted command ++ encrypted response +therefore: +key stream = command ++ response XOR encrypted command ++ encrypted response + +It then tests the potentially recovered key stream by creating an encrypted +command that consumes as much of it as possible, re-initialising with the same +encrypyted nonce and challenge response pair (to set the key stream to the +same stream as that which produced the encrypted command response it is +testing), and then sending this extended encrypted command. If the response +is not the error response, then the key stream is valid and the response is +the encryption of the page 0 contents (the UID). + +When one of the valid encrypted commands satisfies this situation, the +recovered key stream must be the output of the PRNG for the given encrypted +nonce and challenge response pair. + +The RFIDler then uses this key stream to encrypt commands and decrypt the +responses, and therefore requests the contents of all 8 pages. Pages 1 and 2 +contain the encryption key. + +Attack 2 +-------- + +Attack 2 is a time/space trade off to recover the key for situations where the +tag has been configured to prevent reading of pages 1 and 2. This attack uses +a pre-computed table of 2^37 PRNG states and resultant PRNG output, sorted on +the PRNG output. The RFIDler is used to recover 2048 bits of key stream using +a modification of attack 1 and this is used to search the table for matching +PRNG output. When the output is found, it is tested for validity (by testing +previous or following PRNG output) and then the PRNG state is rolled back to +the initialisation state, from which the unecrypted nonce and key can be +recovered. + +Attack 3 +-------- + +Attack 3 is a cryptanalytic attack that focuses on the RWD and a bias in the +PRNG output. By capturing 136 encrypted nonce and challenge response pairs, +candidates for the first 34 bits of the key can be identified, and for each +the remaining 14 bits can be brute forced. + +Attack 4 +-------- + +Attack 4 is a fast correlative attack on the key based on a number of captured +encrypted nonce and challenge response pairs (up to 32, but 16 usually +sufficient). It starts by guessing the first 16 bits of the key and scores +all these guesses against how likely they are to be the correct key, given the +encrypted nonces and the keystream they should produce. Each guess is then +expanded by 1 bit and the process iterates, with only the best guesses taken +forward to the next iteration. + +Usage details +------------- + +Attack 1 requires a valid tag and a valid encrypted nonce and challenge +response pair. The attacker needs to obtain a valid tag and then use this to +obtain a valid encrypted nonce and challenge response pair. This can be +acheived by using the RFIDler 'SNIFF-PWM S' command (having previously cleared +the nonce storage with 'SNIFF-PWM C'), placing the coil on the RWD and +presenting the valid tag. The encrypted nonce and challenge response pairs +can then be read out with the 'SNIFF-PWM L' command. These values can then +be used to attack the tag with 'HITAG2-CRACK '. + +RFIDler: SET TAG HITAG2 +RFIDler: SNIFF-PWM C +RFIDler: SNIFF-PWM S +Capture encrypted nonce and challenge response pair (nR, aR). +RFIDler: SET TAG HITAG2 +RFIDler: SNIFF-PWM L +RFIDler: HITAG2-CRACK + +Attack 2 requires the same resources as attack 1, plus a pre-computed table. +The table can be generated on a disk with >1.5TB of storage, although it takes +some time (allow a couple of days). +./ht2crack2buildtable +RFIDler: SET TAG HITAG2 +RFIDler: SNIFF-PWM C +RFIDler: SNIFF-PWM S +Capture encrypted nonce and challenge response pair (nR, aR). +RFIDler: SET TAG HITAG2 +RFIDler: SNIFF-PWM L +RFIDler: UID +RFIDler: HITAG2-KEYSTREAM +Copy/paste the key stream to a file. +./ht2crack2search + +Attack 3 requires only interaction with the RWD and does not require a valid +tag, although it does require a HiTag2 tag that the RWD will initially respond +to; e.g. you could potentially use any HiTag2 tag as long as the RWD starts +the crypto handshake with it. It requires >=136 encrypted nonce and challenge +response pairs for the same tag UID. + +RFIDler: SET TAG HITAG2 +RFIDler: SNIFF-PWM C +RFIDler: SNIFF-PWM S +Capture >=136 encrypted nonce and challenge response pairs (nR, aR). +RFIDler: SET TAG HITAG2 +RFIDler: SNIFF-PWM L +RFIDler: UID +Copy/paste the encrypted nonce and challenge response pairs into a file. +./ht2crack3 + +Attack 4 requires the same information as attack 3, but only 16-32 encrypted +nonce and challenge response pairs are required. +./ht2crack4 -u -n [-N ] + [-t ] + +Start with -N 16 and -t 500000. If the attack fails to find the key, double +the table size and try again, repeating if it still fails. + +Once the key has been recovered using one of these attacks, the RFIDler can +be configured to operate as a RWD and will capture tags using that key. +RFIDler: SET TAG HITAG2 +RFIDler: HITAG2-READER + +Both the SNIFF-PWM and HITAG2-READER commands can be used as AUTORUN commands +for when the RFIDler is powered from a USB power supply without interaction. + +RFIDler: SET TAG HITAG2 +RFIDler: SNIFF-PWM C +RFIDler: AUTORUN SNIFF-PWM S +RFIDler: SAVE +Capture encrypted nonce and challenge response pairs. +RFIDler: SET TAG HITAG2 +RFIDler: SNIFF-PWM L + + +RFIDler: SET TAG HITAG2 +RFIDler: HITAG2-CLEARSTOREDTAGS +RFIDler: AUTORUN HITAG2-READER S +RFIDler: SAVE +Capture tags. +RFIDler: HITAG2-COUNTSTOREDTAGS +RFIDler: HITAG2-LISTSTOREDTAGS [START] [END] + + +Tags can be copied with standard RFIDler commands. + +RFIDler: SET TAG HITAG2 +RFIDler: COPY +RFIDler: VTAG +Replace original tag with a blank tag. +RFIDler: CLONE + +OR: + +RFIDler: SET TAG HITAG2 +RFIDler: SET VTAG HITAG2 +RFIDler: VWRITE 0 +RFIDler: VWRITE 1 +... +RFIDler: VWRITE 7 +RFIDler: VTAG +Place blank tag on coil. +RFIDler: CLONE + +OR: + +RFIDler: SET TAG HITAG2 +RFIDler: SET VTAG HITAG2 +RFIDler: VWRITE 0 +RFIDler: VTAG +Place blank tag on coil. +RFIDler: CLONE + + From eb0e0e938d0ec5e92944adaf4caba8780ea963c0 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 16 Jan 2020 12:28:45 +0100 Subject: [PATCH 1472/1854] update traces readme --- traces/README.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/traces/README.txt b/traces/README.txt index 0f89925a4..5eada015d 100644 --- a/traces/README.txt +++ b/traces/README.txt @@ -30,3 +30,7 @@ securakey-64169.pm3 Securakey Tag BitLen: 26, Card ID: 64169, FC: 0x35 motorola_0437_00072.pm3: Motorola Grey clamshell card, old. (RAW: A0000000E308C0C1) verichip_1022000000084146.pm3: VeriChip, epoxy encased glasschip (ID: 1022-00000000084146) + +sniff-ht2-BC3B8810-acg-reader.pm3: sniffing of Hitag2 being read by an HID ACG LF Multitag reader +sniff-ht2-BC3B8810-frosch-reader.pm3: sniffing of Hitag2 being read by a Frosch Hitag reader +sniff-ht2-BC3B8810-rfidler-reader.pm3: sniffing of Hitag2 being read by a RFIDler From 69bb285524b77cb1cad40ed400db6dae8a9d926c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 17 Jan 2020 13:44:41 +0100 Subject: [PATCH 1473/1854] fix: 'hf lto info' - now correctly selects and prints LTO-CM uid. --- client/cmdhf.c | 7 ++++--- client/cmdhficlass.c | 3 ++- client/cmdhflist.c | 8 ++++---- client/cmdhflto.c | 47 ++++++++++++++++++++++++-------------------- include/protocols.h | 1 - 5 files changed, 36 insertions(+), 30 deletions(-) diff --git a/client/cmdhf.c b/client/cmdhf.c index 52ad853fa..d0fbbffb2 100644 --- a/client/cmdhf.c +++ b/client/cmdhf.c @@ -272,15 +272,16 @@ static command_t CommandTable[] = { {"15", CmdHF15, AlwaysAvailable, "{ ISO15693 RFIDs... }"}, {"epa", CmdHFEPA, AlwaysAvailable, "{ German Identification Card... }"}, {"felica", CmdHFFelica, AlwaysAvailable, "{ ISO18092 / Felica RFIDs... }"}, - {"legic", CmdHFLegic, AlwaysAvailable, "{ LEGIC RFIDs... }"}, + {"fido", CmdHFFido, AlwaysAvailable, "{ FIDO and FIDO2 authenticators... }"}, {"iclass", CmdHFiClass, AlwaysAvailable, "{ ICLASS RFIDs... }"}, + {"legic", CmdHFLegic, AlwaysAvailable, "{ LEGIC RFIDs... }"}, + {"lto", CmdHFLTO, AlwaysAvailable, "{ LTO Cartridge Memory RFIDs... }"}, {"mf", CmdHFMF, AlwaysAvailable, "{ MIFARE RFIDs... }"}, {"mfp", CmdHFMFP, AlwaysAvailable, "{ MIFARE Plus RFIDs... }"}, {"mfu", CmdHFMFUltra, AlwaysAvailable, "{ MIFARE Ultralight RFIDs... }"}, {"mfdes", CmdHFMFDes, AlwaysAvailable, "{ MIFARE Desfire RFIDs... }"}, - {"topaz", CmdHFTopaz, AlwaysAvailable, "{ TOPAZ (NFC Type 1) RFIDs... }"}, - {"fido", CmdHFFido, AlwaysAvailable, "{ FIDO and FIDO2 authenticators... }"}, {"thinfilm", CmdHFThinfilm, AlwaysAvailable, "{ Thinfilm RFIDs... }"}, + {"topaz", CmdHFTopaz, AlwaysAvailable, "{ TOPAZ (NFC Type 1) RFIDs... }"}, {"list", CmdTraceList, AlwaysAvailable, "List protocol data in trace buffer"}, {"plot", CmdHFPlot, IfPm3Hfplot, "Plot signal"}, {"tune", CmdHFTune, IfPm3Present, "Continuously measure HF antenna tuning"}, diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index ae1109717..616f5e2e2 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -2805,6 +2805,7 @@ int readIclass(bool loop, bool verbose) { FLAG_ICLASS_READER_CONF | FLAG_ICLASS_READER_ONLY_ONCE | FLAG_ICLASS_READER_ONE_TRY; + uint32_t res = PM3_ETIMEOUT; // loop in client not device - else on windows have a communication error while (!kbd_enter_pressed()) { @@ -2876,6 +2877,6 @@ int readIclass(bool loop, bool verbose) { if (!loop) break; } DropField(); - return PM3_SUCCESS; + return res; } diff --git a/client/cmdhflist.c b/client/cmdhflist.c index c9d0f2bb7..2fde8492c 100644 --- a/client/cmdhflist.c +++ b/client/cmdhflist.c @@ -1101,10 +1101,10 @@ void annotateLTO(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) { snprintf(exp, size, "REQ Standard"); break; case LTO_SELECT: - snprintf(exp, size, "SELECT"); - break; - case LTO_SELECT_1: - snprintf(exp, size, "SELECT_1"); + if (cmd[1] == 0x70) + snprintf(exp, size, "SELECT_UID-2"); + else if (cmd[1] == 0x20) + snprintf(exp, size, "SELECT"); break; case LTO_REQ_ALL: snprintf(exp, size, "REQ All"); diff --git a/client/cmdhflto.c b/client/cmdhflto.c index 8a1e914aa..e60fc4781 100644 --- a/client/cmdhflto.c +++ b/client/cmdhflto.c @@ -42,9 +42,17 @@ static void lto_switch_on_field(void) { } // send a raw LTO-CM command, returns the length of the response (0 in case of error) -static int lto_send_cmd_raw(uint8_t *cmd, uint8_t len, uint8_t *response, uint16_t *response_len, bool verbose) { +static int lto_send_cmd_raw(uint8_t *cmd, uint8_t len, uint8_t *response, uint16_t *response_len, bool addcrc, bool verbose) { + + uint64_t arg0 = ISO14A_RAW | ISO14A_NO_DISCONNECT | ISO14A_NO_RATS; + uint32_t arg1 = (len == 1) ? (7 << 16) : 0; + arg1 |= len; + + if (addcrc) { + arg0 |= ISO14A_APPEND_CRC; + } - SendCommandOLD(CMD_HF_ISO14443A_READER, ISO14A_RAW | ISO14A_NO_DISCONNECT | ISO14A_NO_RATS, len, 0, cmd, len); + SendCommandOLD(CMD_HF_ISO14443A_READER, arg0, arg1, 0, cmd, len); PacketResponseNG resp; if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { @@ -55,7 +63,6 @@ static int lto_send_cmd_raw(uint8_t *cmd, uint8_t len, uint8_t *response, uint16 if (resp.oldarg[0] == *response_len) { *response_len = resp.oldarg[0]; - PrintAndLogEx(INFO, "%s", sprint_hex(resp.data.asBytes, *response_len)); if (*response_len > 0) { memcpy(response, resp.data.asBytes, *response_len); } @@ -66,7 +73,6 @@ static int lto_send_cmd_raw(uint8_t *cmd, uint8_t len, uint8_t *response, uint16 return PM3_SUCCESS; } - // select a LTO-CM tag. Send WUPA and RID. static int lto_select(uint8_t *id_response, uint8_t id_len, bool verbose) { // Todo: implement anticollision @@ -75,26 +81,27 @@ static int lto_select(uint8_t *id_response, uint8_t id_len, bool verbose) { uint16_t resp_len; uint8_t wupa_cmd[] = {LTO_REQ_STANDARD}; uint8_t select_cmd[] = {LTO_SELECT, 0x20}; - uint8_t select_1_cmd[] = {LTO_SELECT_1, 0x70, 0, 0, 0, 0, 0}; + uint8_t select_1_cmd[] = {LTO_SELECT, 0x70, 0, 0, 0, 0, 0}; lto_switch_on_field(); resp_len = 2; - int status = lto_send_cmd_raw(wupa_cmd, sizeof(wupa_cmd), resp, &resp_len, verbose); + int status = lto_send_cmd_raw(wupa_cmd, sizeof(wupa_cmd), resp, &resp_len, false, verbose); if (status == PM3_ETIMEOUT || status == PM3_ESOFT) { lto_switch_off_field(); return PM3_ESOFT; // WUPA failed } resp_len = id_len; - status = lto_send_cmd_raw(select_cmd, sizeof(select_cmd), id_response, &resp_len, verbose); + status = lto_send_cmd_raw(select_cmd, sizeof(select_cmd), id_response, &resp_len, false, verbose); if (status == PM3_ETIMEOUT || status == PM3_ESOFT) { lto_switch_off_field(); return PM3_EWRONGANSVER; // SELECT failed } + memcpy(select_1_cmd + 2, id_response, sizeof(select_1_cmd) - 2); resp_len = 1; - status = lto_send_cmd_raw(select_1_cmd, sizeof(select_1_cmd), resp, &resp_len, verbose); + status = lto_send_cmd_raw(select_1_cmd, sizeof(select_1_cmd), resp, &resp_len, true, verbose); if (status == PM3_ETIMEOUT || status == PM3_ESOFT || resp[0] != 0x0A) { lto_switch_off_field(); return PM3_EWRONGANSVER; // SELECT failed @@ -104,7 +111,6 @@ static int lto_select(uint8_t *id_response, uint8_t id_len, bool verbose) { return PM3_SUCCESS; } - static int CmdHfLTOInfo(const char *Cmd) { uint8_t cmdp = 0; @@ -134,19 +140,18 @@ int infoLTO(bool verbose) { clearCommandBuffer(); uint8_t serial_number[5]; - uint8_t serial_len = 0; - - int ret_val = lto_select(serial_number, serial_len, verbose); - + uint8_t serial_len = sizeof(serial_number); + int ret_val = lto_select(serial_number, serial_len, verbose); lto_switch_off_field(); - /* - - -- "hf 14a raw -a -p -b 7 45" - -- "hf 14a raw -c -p 9320" - -- "hf 14a raw -c -p 9370%s", serial_number - -- "disconnect" - - + + if (ret_val == PM3_SUCCESS) { + PrintAndLogEx(SUCCESS, "\nUID: %s", sprint_hex(serial_number, sizeof(serial_number))); + + // todo: add printing of all configuration + } + + /* read block: + SendCommandNG(CMD_HF_THINFILM_READ, NULL, 0); PacketResponseNG resp; if (!WaitForResponseTimeout(CMD_HF_THINFILM_READ, &resp, 1500)) { diff --git a/include/protocols.h b/include/protocols.h index 857cb2a4a..47e022c28 100644 --- a/include/protocols.h +++ b/include/protocols.h @@ -602,7 +602,6 @@ ISO 7816-4 Basic interindustry commands. For command APDU's. #define LTO_READBLOCK 0x30 #define LTO_READBLOCK_CONT 0x80 #define LTO_SELECT 0x93 -#define LTO_SELECT_1 0x97 #define LTO_WRITEWORD 0xB0 // write 2 bytes (word) #define LTO_WRITEBLOCK 0xA0 #define LTO_HALT 0x50 From 864256269b9faafd3b76b45504dcbf3087cc6c7d Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 17 Jan 2020 14:04:30 +0100 Subject: [PATCH 1474/1854] textual --- client/cmdhflto.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/client/cmdhflto.c b/client/cmdhflto.c index e60fc4781..10847645b 100644 --- a/client/cmdhflto.c +++ b/client/cmdhflto.c @@ -43,11 +43,11 @@ static void lto_switch_on_field(void) { // send a raw LTO-CM command, returns the length of the response (0 in case of error) static int lto_send_cmd_raw(uint8_t *cmd, uint8_t len, uint8_t *response, uint16_t *response_len, bool addcrc, bool verbose) { - + uint64_t arg0 = ISO14A_RAW | ISO14A_NO_DISCONNECT | ISO14A_NO_RATS; uint32_t arg1 = (len == 1) ? (7 << 16) : 0; arg1 |= len; - + if (addcrc) { arg0 |= ISO14A_APPEND_CRC; } @@ -141,17 +141,17 @@ int infoLTO(bool verbose) { uint8_t serial_number[5]; uint8_t serial_len = sizeof(serial_number); - int ret_val = lto_select(serial_number, serial_len, verbose); + int ret_val = lto_select(serial_number, serial_len, verbose); lto_switch_off_field(); - + if (ret_val == PM3_SUCCESS) { - PrintAndLogEx(SUCCESS, "\nUID: %s", sprint_hex(serial_number, sizeof(serial_number))); - + PrintAndLogEx(SUCCESS, "\nUID: " _YELLOW_("%s"), sprint_hex_inrow(serial_number, sizeof(serial_number))); + // todo: add printing of all configuration } - + /* read block: - + SendCommandNG(CMD_HF_THINFILM_READ, NULL, 0); PacketResponseNG resp; if (!WaitForResponseTimeout(CMD_HF_THINFILM_READ, &resp, 1500)) { From 655345e109ef6016bb3e075e3fca2059ec77a80b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 17 Jan 2020 14:05:11 +0100 Subject: [PATCH 1475/1854] Chg 'lf hitag info' - use DEFINES --- client/cmdlfhitag.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/client/cmdlfhitag.c b/client/cmdlfhitag.c index 625b0bef0..c867584fa 100644 --- a/client/cmdlfhitag.c +++ b/client/cmdlfhitag.c @@ -483,7 +483,7 @@ static int CmdLFHitagInfo(const char *Cmd) { // read UID uint32_t uid = 0; if (getHitagUid(&uid) == false) - return 1; + return PM3_ESOFT; PrintAndLogEx(SUCCESS, "UID: " _YELLOW_("%08X"), uid); @@ -551,21 +551,22 @@ static int CmdLFHitagReader(const char *Cmd) { } clearCommandBuffer(); - SendCommandOLD(cmd, htf, 0, 0, &htd, sizeof(htd)); + SendCommandMIX(cmd, htf, 0, 0, &htd, sizeof(htd)); PacketResponseNG resp; if (!WaitForResponseTimeout(CMD_ACK, &resp, 4000)) { PrintAndLogEx(WARNING, "timeout while waiting for reply."); - return 1; + return PM3_ETIMEOUT; } if (resp.oldarg[0] == false) { PrintAndLogEx(DEBUG, "DEBUG: Error - hitag failed"); - return 1; + return PM3_ESOFT; } uint32_t id = bytes_to_num(resp.data.asBytes, 4); - PrintAndLogEx(SUCCESS, "Valid Hitag2 tag found - UID: " _YELLOW_("%08x"), id); + PrintAndLogEx(SUCCESS, " UID: " _YELLOW_("%08x"), id); + if (htf != RHT2F_UID_ONLY) { PrintAndLogEx(SUCCESS, "Dumping tag memory..."); @@ -583,7 +584,7 @@ static int CmdLFHitagReader(const char *Cmd) { // block3, 1 byte printHitagConfiguration(data[4 * 3]); } - return 0; + return PM3_SUCCESS; } static int CmdLFHitagCheckChallenges(const char *Cmd) { @@ -721,5 +722,5 @@ int CmdLFHitag(const char *Cmd) { } int readHitagUid(void) { - return CmdLFHitagReader("26") == 0; + return (CmdLFHitagReader("26") == PM3_SUCCESS); } From d451631b139d736ed57701432e3367199fea0791 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 17 Jan 2020 14:25:07 +0100 Subject: [PATCH 1476/1854] use DEFINES --- client/cmdlfhitag.c | 48 ++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/client/cmdlfhitag.c b/client/cmdlfhitag.c index c867584fa..3ebbe47a6 100644 --- a/client/cmdlfhitag.c +++ b/client/cmdlfhitag.c @@ -35,7 +35,7 @@ static int usage_hitag_sniff(void) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf hitag sniff"); - return 0; + return PM3_SUCCESS; } static int usage_hitag_sim(void) { PrintAndLogEx(NORMAL, "Simulate " _YELLOW_("Hitag2 / HitagS")" transponder"); @@ -49,7 +49,7 @@ static int usage_hitag_sim(void) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf hitag sim 2 b lf-hitag-dump"); - return 0; + return PM3_SUCCESS; } static int usage_hitag_info(void) { PrintAndLogEx(NORMAL, "Usage: lf hitag info [h] p "); @@ -58,7 +58,7 @@ static int usage_hitag_info(void) { PrintAndLogEx(NORMAL, " p password"); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf hitag info"); - return 0; + return PM3_SUCCESS; } /* static int usage_hitag_dump(void) { @@ -71,7 +71,7 @@ static int usage_hitag_dump(void) { PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf hitag dump f mydump"); PrintAndLogEx(NORMAL, " lf hitag dump p 4D494B52 f mydump"); - return 0; + return PM3_SUCCESS; } */ static int usage_hitag_reader(void) { @@ -90,7 +90,7 @@ static int usage_hitag_reader(void) { PrintAndLogEx(NORMAL, " 23 Read all pages, crypto mode. Key format: ISK high + ISK low. Default: 4F4E4D494B52 (\"ONMIKR\")"); PrintAndLogEx(NORMAL, " 25 Test recorded authentications"); PrintAndLogEx(NORMAL, " 26 Just read UID"); - return 0; + return PM3_SUCCESS; } static int usage_hitag_writer(void) { PrintAndLogEx(NORMAL, "Hitag writer functions"); @@ -106,7 +106,7 @@ static int usage_hitag_writer(void) { PrintAndLogEx(NORMAL, " 24 Write page, crypto mode. Key format: ISK high + ISK low."); PrintAndLogEx(NORMAL, " Default: 4F4E4D494B52 (\"ONMIKR\"). Set key=0 for no auth"); PrintAndLogEx(NORMAL, " 27 Write page, password mode. Default: 4D494B52 (\"MIKR\")"); - return 0; + return PM3_SUCCESS; } static int usage_hitag_checkchallenges(void) { PrintAndLogEx(NORMAL, "Check challenges, load a file with save hitag crypto challenges and test them all."); @@ -119,19 +119,19 @@ static int usage_hitag_checkchallenges(void) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf hitag cc f lf-hitag-challenges"); - return 0; + return PM3_SUCCESS; } static int CmdLFHitagList(const char *Cmd) { (void)Cmd; // Cmd is not used so far CmdTraceList("hitag"); - return 0; + return PM3_SUCCESS; /* uint8_t *got = calloc(PM3_CMD_DATA_SIZE, sizeof(uint8_t)); if (!got) { PrintAndLogEx(WARNING, "Cannot allocate memory for trace"); - return 2; + return PM3_EMALLOC; } // Query for the actual size of the trace @@ -139,7 +139,7 @@ static int CmdLFHitagList(const char *Cmd) { if (!GetFromDevice(BIG_BUF, got, PM3_CMD_DATA_SIZE, 0, NULL, 0, &response, 2500, false)) { PrintAndLogEx(WARNING, "command execution time out"); free(got); - return 2; + return PM3_ETIMEOUT; } uint16_t traceLen = response.arg[2]; @@ -148,13 +148,13 @@ static int CmdLFHitagList(const char *Cmd) { if (p == NULL) { PrintAndLogEx(WARNING, "Cannot allocate memory for trace"); free(got); - return 2; + return PM3_EMALLOC; } got = p; if (!GetFromDevice(BIG_BUF, got, traceLen, 0, NULL, 0, NULL, 2500, false)) { PrintAndLogEx(WARNING, "command execution time out"); free(got); - return 2; + return PM3_ETIMEOUT; } } @@ -251,7 +251,7 @@ static int CmdLFHitagList(const char *Cmd) { } free(got); - return 0; + return PM3_SUCCES; */ } @@ -262,7 +262,7 @@ static int CmdLFHitagSniff(const char *Cmd) { clearCommandBuffer(); SendCommandNG(CMD_LF_HITAG_SNIFF, NULL, 0); - return 0; + return PM3_SUCCESS; } static int CmdLFHitagSim(const char *Cmd) { @@ -343,7 +343,7 @@ static int CmdLFHitagSim(const char *Cmd) { } free(data); - return 0; + return PM3_SUCCESS; } static void printHitagConfiguration(uint8_t config) { @@ -487,13 +487,11 @@ static int CmdLFHitagInfo(const char *Cmd) { PrintAndLogEx(SUCCESS, "UID: " _YELLOW_("%08X"), uid); - return PM3_SUCCESS; // how to detemine Hitag types? // read block3, get configuration byte. - PrintAndLogEx(FAILED, _RED_("TODO: This is a hardcoded example!")); // common configurations. - printHitagConfiguration(0x06); + // printHitagConfiguration(0x06); //printHitagConfiguration( 0x0E ); //printHitagConfiguration( 0x02 ); //printHitagConfiguration( 0x00 ); @@ -577,6 +575,8 @@ static int CmdLFHitagReader(const char *Cmd) { fnameptr += sprintf(fnameptr, "lf-hitag-"); FillFileNameByUID(fnameptr, data, "-dump", 4); + + saveFile(filename, ".bin", data, 48); saveFileEML(filename, data, 48, 4); saveFileJSON(filename, jsfHitag, data, 48); @@ -633,7 +633,7 @@ static int CmdLFHitagCheckChallenges(const char *Cmd) { SendCommandMIX(CMD_LF_HITAGS_TEST_TRACES, 0, 0, 0, NULL, 0); free(data); - return 0; + return PM3_SUCCESS; } static int CmdLFHitagWriter(const char *Cmd) { @@ -677,14 +677,14 @@ static int CmdLFHitagWriter(const char *Cmd) { PacketResponseNG resp; if (!WaitForResponseTimeout(CMD_ACK, &resp, 4000)) { PrintAndLogEx(WARNING, "timeout while waiting for reply."); - return 1; + return PM3_ETIMEOUT; } if (resp.oldarg[0] == false) { PrintAndLogEx(DEBUG, "DEBUG: Error - hitag write failed"); - return 1; + return PM3_ESOFT; } - return 0; + return PM3_SUCCESS; } /* @@ -694,7 +694,7 @@ static int CmdLFHitagDump(const char *Cmd) { char ctmp = tolower(param_getchar(Cmd, 0)); if (ctmp == 'h') return usage_hitag_dump(); - return 0; + return PM3_SUCCESS; } */ @@ -713,7 +713,7 @@ static command_t CommandTable[] = { static int CmdHelp(const char *Cmd) { (void)Cmd; // Cmd is not used so far CmdsHelp(CommandTable); - return 0; + return PM3_SUCCESS; } int CmdLFHitag(const char *Cmd) { From 56bb7f21dc75cc53bc2d3470e1c96ba3a55a9475 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 17 Jan 2020 14:25:28 +0100 Subject: [PATCH 1477/1854] rename define T0 --- armsrc/hitag2.c | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index f27a9cf5e..158ffa095 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -18,6 +18,7 @@ // Piwi, 2019 // Iceman, 2019 // Anon, 2019 +// Doegos, 2020 #include "hitag2.h" #include "hitag2_crypto.h" @@ -101,8 +102,8 @@ static int hitag2_init(void) { // TIMER_CLOCK1 = MCK/2, MCK is running at 48 MHz, Timer is running at 48/2 = 24 MHz // Hitag units (T0) have duration of 8 microseconds (us), which is 1/125000 per second (carrier) // T0 = TIMER_CLOCK1 / 125000 = 192 -#ifndef T0 -#define T0 192 +#ifndef HITAG_T0 +#define HITAG_T0 192 #endif #define HITAG_FRAME_LEN 20 @@ -141,15 +142,15 @@ static void hitag_send_bit(int bit) { if (bit == 0) { // Manchester: Unloaded, then loaded |__--| LOW(GPIO_SSC_DOUT); - while (AT91C_BASE_TC0->TC_CV < T0 * HITAG_T_TAG_HALF_PERIOD); + while (AT91C_BASE_TC0->TC_CV < HITAG_T0 * HITAG_T_TAG_HALF_PERIOD); HIGH(GPIO_SSC_DOUT); - while (AT91C_BASE_TC0->TC_CV < T0 * HITAG_T_TAG_FULL_PERIOD); + while (AT91C_BASE_TC0->TC_CV < HITAG_T0 * HITAG_T_TAG_FULL_PERIOD); } else { // Manchester: Loaded, then unloaded |--__| HIGH(GPIO_SSC_DOUT); - while (AT91C_BASE_TC0->TC_CV < T0 * HITAG_T_TAG_HALF_PERIOD); + while (AT91C_BASE_TC0->TC_CV < HITAG_T0 * HITAG_T_TAG_HALF_PERIOD); LOW(GPIO_SSC_DOUT); - while (AT91C_BASE_TC0->TC_CV < T0 * HITAG_T_TAG_FULL_PERIOD); + while (AT91C_BASE_TC0->TC_CV < HITAG_T0 * HITAG_T_TAG_FULL_PERIOD); } LED_A_OFF(); } @@ -1123,11 +1124,11 @@ void SimulateHitagTag(bool tag_mem_supplied, uint8_t *data) { WDT_HIT(); // Receive frame, watch for at most T0*EOF periods - while (AT91C_BASE_TC1->TC_CV < T0 * HITAG_T_EOF) { + while (AT91C_BASE_TC1->TC_CV < HITAG_T0 * HITAG_T_EOF) { // Check if rising edge in modulation is detected if (AT91C_BASE_TC1->TC_SR & AT91C_TC_LDRAS) { // Retrieve the new timing values - int ra = (AT91C_BASE_TC1->TC_RA / T0) + overflow; + int ra = (AT91C_BASE_TC1->TC_RA / HITAG_T0) + overflow; overflow = 0; // Reset timer every frame, we have to capture the last edge for timing @@ -1172,7 +1173,7 @@ void SimulateHitagTag(bool tag_mem_supplied, uint8_t *data) { // with respect to the falling edge, we need to wait actually (T_Wait1 - T_Low) // periods. The gap time T_Low varies (4..10). All timer values are in // terms of T0 units - while (AT91C_BASE_TC0->TC_CV < T0 * (HITAG_T_WAIT_1_MIN - HITAG_T_LOW)); + while (AT91C_BASE_TC0->TC_CV < HITAG_T0 * (HITAG_T_WAIT_1_MIN - HITAG_T_LOW)); // Send and store the tag answer (if there is any) if (txlen) { @@ -1191,7 +1192,7 @@ void SimulateHitagTag(bool tag_mem_supplied, uint8_t *data) { // Reset the frame length rxlen = 0; // Save the timer overflow, will be 0 when frame was received - overflow += (AT91C_BASE_TC1->TC_CV / T0); + overflow += (AT91C_BASE_TC1->TC_CV / HITAG_T0); // Reset the timer to restart while-loop that receives frames AT91C_BASE_TC1->TC_CCR = AT91C_TC_SWTRG; } @@ -1740,7 +1741,7 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) { // falling edge occurred halfway the period. with respect to this falling edge, // we need to wait (T_Wait2 + half_tag_period) when the last was a 'one'. // All timer values are in terms of T0 units - while (AT91C_BASE_TC0->TC_CV < T0 * (t_wait + (HITAG_T_TAG_HALF_PERIOD * lastbit))) {}; + while (AT91C_BASE_TC0->TC_CV < HITAG_T0 * (t_wait + (HITAG_T_TAG_HALF_PERIOD * lastbit))) {}; // Transmit the reader frame hitag_reader_send_frame(tx, txlen); @@ -1764,11 +1765,11 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) { uint32_t errorCount = 0; // Receive frame, watch for at most T0*EOF periods - while (AT91C_BASE_TC1->TC_CV < T0 * HITAG_T_WAIT_MAX) { + while (AT91C_BASE_TC1->TC_CV < HITAG_T0 * HITAG_T_WAIT_MAX) { // Check if falling edge in tag modulation is detected if (AT91C_BASE_TC1->TC_SR & AT91C_TC_LDRAS) { // Retrieve the new timing values - int ra = (AT91C_BASE_TC1->TC_RA / T0); + int ra = (AT91C_BASE_TC1->TC_RA / HITAG_T0); // Reset timer every frame, we have to capture the last edge for timing AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; @@ -1835,7 +1836,7 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) { if (errorCount > 100) break; // We can break this loop if we received the last bit from a frame - if (AT91C_BASE_TC1->TC_CV > T0 * HITAG_T_EOF) { + if (AT91C_BASE_TC1->TC_CV > HITAG_T0 * HITAG_T_EOF) { if (rxlen > 0) break; } } @@ -1843,7 +1844,7 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) { // Wait some extra time for flash to be programmed if ((rxlen == 0) && (writestate == WRITE_STATE_PROG)) { AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; - while (AT91C_BASE_TC0->TC_CV < T0 * (HITAG_T_PROG - HITAG_T_WAIT_MAX)); + while (AT91C_BASE_TC0->TC_CV < HITAG_T0 * (HITAG_T_PROG - HITAG_T_WAIT_MAX)); } } @@ -1856,5 +1857,5 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) { StartTicks(); - reply_old(CMD_ACK, bSuccessful, 0, 0, (uint8_t *)tag.sectors, 48); + reply_mix(CMD_ACK, bSuccessful, 0, 0, (uint8_t *)tag.sectors, 48); } From f25beac361f2032c3c8fab4185a8472baae36d70 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 17 Jan 2020 14:25:57 +0100 Subject: [PATCH 1478/1854] less checks in time critical loops --- armsrc/lfadc.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/armsrc/lfadc.c b/armsrc/lfadc.c index c715020a2..eaaa38631 100644 --- a/armsrc/lfadc.c +++ b/armsrc/lfadc.c @@ -22,7 +22,7 @@ // as a counting signal. TIMER_CLOCK3 = MCK/32, MCK is running at 48 MHz, so the timer is running at 48/32 = 1500 kHz // Carrier period (T0) have duration of 8 microseconds (us), which is 1/125000 per second (125 kHz frequency) // T0 = timer/carrier = 1500kHz/125kHz = 1500000/125000 = 6 -#define T0 3 +//#define HITAG_T0 3 ////////////////////////////////////////////////////////////////////////////// // Global variables @@ -52,9 +52,21 @@ size_t lf_count_edge_periods_ex(size_t max, bool wait, bool detect_gap) { volatile uint8_t adc_val; //uint8_t avg_peak = 140, avg_through = 96; uint8_t avg_peak = 130, avg_through = 106; + int16_t checked = 0; + + while (true) { + + // only every 1000th times, in order to save time when collecting samples. + if (checked == 1000) { + if (BUTTON_PRESS() || data_available()) { + checked = -1; + break; + } else { + checked = 0; + } + } + ++checked; - while (!BUTTON_PRESS()) { - // Watchdog hit WDT_HIT(); if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { From df5083603c9cb98e0a3b11273110293d68e7f5d0 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 17 Jan 2020 15:02:21 +0100 Subject: [PATCH 1479/1854] first attempt --- armsrc/hitag2crack.c | 923 +++++++++++++++++++++++++++++++++++++++++++ armsrc/hitag2crack.h | 31 ++ 2 files changed, 954 insertions(+) create mode 100644 armsrc/hitag2crack.c create mode 100644 armsrc/hitag2crack.h diff --git a/armsrc/hitag2crack.c b/armsrc/hitag2crack.c new file mode 100644 index 000000000..c6b61b019 --- /dev/null +++ b/armsrc/hitag2crack.c @@ -0,0 +1,923 @@ +//----------------------------------------------------------------------------- +// Kevin Sheldrake , Aug 2018 +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +// +// iceman, Jan, 2020 +// doegox, Jan, 2020 +//----------------------------------------------------------------------------- +// hitag2 attack functions +//----------------------------------------------------------------------------- + +#include "hitagcrypto.h" +#include "hitag2crack.h" + +#define READP0CMD "1100000111" +#define ERROR_RESPONSE "F402889C" + +extern const uint8_t Hitag2Sync[5]; +extern bool CryptoActive; +extern Hitag_State Hitag_Crypto_State; + +// hitag2_crack implements the first crack algorithm described in the paper, +// Gone In 360 Seconds by Verdult, Garcia and Balasch. +// response is a multi-line text response containing the 8 pages of the +// cracked tag; +// nrarhex is a string containing hex representations of the 32 bit nR and aR +// values (separated by a space) snooped using SNIFF-PWM. +bool hitag2_crack(uint8_t *response, uint8_t *nrarhex) { + uint8_t uidhex[9]; + uint8_t uid[32]; + uint8_t nrar[64]; + uint8_t e_firstcmd[10]; + uint8_t e_page0cmd[10]; + uint8_t keybits[42]; + uint8_t pagehex[9]; + uint8_t temp[20]; + int i; + uint8_t *spaceptr = NULL; + + // get uid as hexstring + if(!hitag2_get_uid(uidhex)) + { + UserMessage("Cannot get UID\r\n"); + return false; + } + + // convert uid hexstring to binarray + hextobinarray(uid, uidhex); + + // convert nR and aR hexstrings to binarray + spaceptr = strchr(nrarhex, ' '); + if (!spaceptr) + { + UserMessage("Please supply a valid nR aR pair\r\n"); + return false; + } + *spaceptr = 0x00; + + if (hextobinarray(nrar, nrarhex) != 32) + { + UserMessage("nR is not 32 bits long\r\n"); + return false; + } + + if (hextobinarray(nrar + 32, spaceptr + 1) != 32) + { + UserMessage("aR is not 32 bits long\r\n"); + return false; + } + + // find a valid encrypted command + if (!hitag2crack_find_valid_e_cmd(e_firstcmd, nrar)) + { + UserMessage("Cannot find a valid encrypted command\r\n"); + return false; + } + + // find the 'read page 0' command and recover key stream + if (!hitag2crack_find_e_page0_cmd(keybits, e_firstcmd, nrar, uid)) + { + UserMessage("Cannot find encrypted 'read page0' command\r\n"); + return false; + } + + // empty the response string + response[0] = 0x00; + + // read all pages using key stream + for (i=0; i<8; i++) + { + if (hitag2crack_read_page(pagehex, i, nrar, keybits)) + { + sprintf(temp, "%1d: %s\r\n", i, pagehex); + } + else + { + sprintf(temp, "%1d:\r\n", i); + } + // add page string to response + strcat(response, temp); + } + + return true; +} + +// hitag2crack_find_valid_e_cmd repeatedly replays the auth protocol each +// with a different sequential encrypted command value in order to find one +// that returns a valid response. +// e_cmd is the returned binarray of the valid encrypted command; +// nrar is the binarray of the 64 bit nR aR pair. +bool hitag2crack_find_valid_e_cmd(uint8_t e_cmd[], uint8_t nrar[]) { + uint8_t guess[10]; + uint8_t responsestr[9]; + +// UserMessage("Finding valid encrypted command:"); + // we're going to hold bits 5, 7, 8 and 9 and brute force the rest + // e.g. x x x x x 0 x 0 0 0 + for (uint8_t a=0; a<2; a++) { + for (uint8_t b=0; b<2; b++) { + for (uint8_t c=0; c<2; c++) { + for (uint8_t d=0; d<2; d++) { + for (uint8_t e=0; e<2; e++) { + for (uint8_t g=0; g<2; g++) { + // build binarray + guess[0] = a; + guess[1] = b; + guess[2] = c; + guess[3] = d; + guess[4] = e; + guess[5] = 0; + guess[6] = g; + guess[7] = 0; + guess[8] = 0; + guess[9] = 0; + + // send guess + if (hitag2crack_send_e_cmd(responsestr, nrar, guess, 10)) { + // check if it was valid + if (strcmp(responsestr, ERROR_RESPONSE) != 0) { + // return the guess as the encrypted command + memcpy(e_cmd, guess, 10); + return true; + } + } else { +#ifdef RFIDLER_DEBUG + UserMessage("hitag2crack_find_valid_e_cmd:\r\n hitag2crack_send_e_cmd failed\r\n"); +#endif + } + UserMessage("."); + } + } + } + } + } + } +// UserMessage("hitag2crack_find_valid_e_cmd:\r\n no valid encrypted command found\r\n"); + return false; +} + +// hitag2crack_find_e_page0_cmd tries all bit-flipped combinations of the +// valid encrypted command and tests the results by attempting an extended +// command version of the command to see if that produces a valid response. +// keybits is the returned binarray of the recovered key stream; +// e_page0cmd is the returned binarray of the encrypted 'read page 0' command; +// e_firstcmd is the binarray of the first valid encrypted command found; +// nrar is the binarray of the 64 bit nR aR pair; +// uid is the binarray of the 32 bit UID. +bool hitag2crack_find_e_page0_cmd(uint8_t keybits[], uint8_t e_firstcmd[], uint8_t nrar[], uint8_t uid[]) { + uint8_t a, b, c, d; + uint8_t guess[10]; + uint8_t responsestr[9]; + uint8_t e_uid[32]; + + UserMessage("Finding 'read page 0' command:"); + // we're going to brute the missing 4 bits of the valid encrypted command + for (a=0; a<2; a++) + { + for (b=0; b<2; b++) + { + for (c=0; c<2; c++) + { + for (d=0; d<2; d++) + { + // create our guess by bit flipping the pattern of bits + // representing the inverted bit and the 3 page bits + // in both the non-inverted and inverted parts of the + // encrypted command. + memcpy(guess, e_firstcmd, 10); + if (a) + { + guess[5] = !guess[5]; + guess[0] = !guess[0]; + } + if (b) + { + guess[7] = !guess[7]; + guess[2] = !guess[2]; + } + if (c) + { + guess[8] = !guess[8]; + guess[3] = !guess[3]; + } + if (d) + { + guess[9] = !guess[9]; + guess[4] = !guess[4]; + } + + // try the guess + if (hitag2crack_send_e_cmd(responsestr, nrar, guess, 10)) + { + // check if it was valid + if (strcmp(responsestr, ERROR_RESPONSE) != 0) + { + // convert response to binarray + hextobinarray(e_uid, responsestr); + // test if the guess was 'read page 0' command + if (hitag2crack_test_e_p0cmd(keybits, nrar, guess, uid, e_uid)) + { + + return true; + } + } + else + { +#ifdef RFIDLER_DEBUG + UserMessage("hitag2crack_find_e_page0_cmd:\r\n hitag2crack_send_e_cmd returned ERROR_RESPONSE\r\n"); +#endif + } + } + else + { + #ifdef RFIDLER_DEBUG + UserMessage("hitag2crack_find_e_page0_cmd:\r\n hitag2crack_send_e_cmd failed\r\n"); +#endif + } + UserMessage("."); + } + } + } + } + UserMessage("hitag2crack_find_e_page0_cmd:\r\n could not find encrypted 'read page 0' command\r\n"); + return false; +} + +// hitag2crack_test_e_p0cmd XORs the message (command + response) with the +// encrypted version to retrieve the key stream. It then uses this key stream +// to encrypt an extended version of the READP0CMD and tests if the response +// is valid. +// keybits is the returned binarray of the key stream; +// nrar is the 64 bit binarray of nR aR pair; +// e_cmd is the binarray of the encrypted command; +// uid is the binarray of the card UID; +// e_uid is the binarray of the encrypted version of the UID. +bool hitag2crack_test_e_p0cmd(uint8_t *keybits, uint8_t *nrar, uint8_t *e_cmd, uint8_t *uid, uint8_t *e_uid) { + uint8_t cipherbits[42]; + uint8_t plainbits[42]; + uint8_t ext_cmd[40]; + uint8_t e_ext_cmd[40]; + uint8_t responsestr[9]; + int i; + + // copy encrypted cmd to cipherbits + memcpy(cipherbits, e_cmd, 10); + + // copy encrypted uid to cipherbits + memcpy(cipherbits + 10, e_uid, 32); + + // copy cmd to plainbits + binstringtobinarray(plainbits, READP0CMD); + + // copy uid to plainbits + memcpy(plainbits + 10, uid, 32); + + // xor the plainbits with the cipherbits to get keybits + hitag2crack_xor(keybits, plainbits, cipherbits, 42); + + // create extended cmd -> 4 * READP0CMD = 40 bits + for (i=0; i<4; i++) + { + binstringtobinarray(ext_cmd + (i * 10), READP0CMD); + } + + // xor extended cmd with keybits + hitag2crack_xor(e_ext_cmd, ext_cmd, keybits, 40); + + // send extended encrypted cmd + if (hitag2crack_send_e_cmd(responsestr, nrar, e_ext_cmd, 40)) + { + // test if it was valid + if (strcmp(responsestr, ERROR_RESPONSE) != 0) + { + return true; + } + } + else + { +#ifdef RFIDLER_DEBUG + UserMessage("hitag2crack_test_e_p0cmd:\r\n hitag2crack_send_e_cmd failed\r\n"); +#endif + } + + return false; + +} + +// hitag2crack_xor XORs the source with the pad to produce the target. +// source, target and pad are binarrays of length len. +void hitag2crack_xor(uint8_t *target, uint8_t *source, uint8_t *pad, unsigned int len) { + + for (int i=0; i 7)) + { + UserMessage("hitag2crack_read_page:\r\n invalid pagenum\r\n"); + return false; + } + + // create cmd + binstringtobinarray(cmd, READP0CMD); + if (pagenum & 0x1) + { + cmd[9] = !cmd[9]; + cmd[4] = !cmd[4]; + } + if (pagenum & 0x2) + { + cmd[8] = !cmd[8]; + cmd[3] = !cmd[3]; + } + if (pagenum & 0x4) + { + cmd[7] = !cmd[7]; + cmd[2] = !cmd[2]; + } + + // encrypt command + hitag2crack_xor(e_cmd, cmd, keybits, 10); + + // send encrypted command + if (hitag2crack_send_e_cmd(e_responsestr, nrar, e_cmd, 10)) + { + // check if it is valid + if (strcmp(e_responsestr, ERROR_RESPONSE) != 0) + { + // convert to binarray + hextobinarray(e_response, e_responsestr); + // decrypt response + hitag2crack_xor(response, e_response, keybits + 10, 32); + // convert to hexstring + binarraytohex(responsestr, response, 32); + return true; + } + else + { + UserMessage("hitag2crack_read_page:\r\n hitag2crack_send_e_cmd returned ERROR_RESPONSE\r\n"); + } + } + else + { + UserMessage("hitag2crack_read_page:\r\n hitag2crack_send_e_cmd failed\r\n"); + } + + return false; +} + +// hitag2crack_send_e_cmd replays the auth and sends the given encrypted +// command. +// responsestr is the hexstring of the response to the command; +// nrar is the 64 bit binarray of the nR aR pair; +// cmd is the binarray of the encrypted command to send; +// len is the length of the encrypted command. +bool hitag2crack_send_e_cmd(uint8_t *responsestr, uint8_t *nrar, uint8_t *cmd, int len) { + uint8_t tmp[37]; + uint8_t uid[9]; + uint8_t e_page3str[9]; + int ret = 0; + + // get the UID + if(!hitag2_get_uid(uid)) + { + UserMessage("hitag2crack_send_e_cmd:\r\n cannot get UID\r\n"); + return false; + } + + // START_AUTH kills active crypto session + CryptoActive = false; + + // get the UID again + if(!hitag2_get_uid(uid)) + { + UserMessage("hitag2crack_send_e_cmd:\r\n cannot get UID (2nd time)\r\n"); + return false; + } + + // send nrar and receive (useless) encrypted page 3 value + if (!hitag2crack_tx_rx(e_page3str, nrar, 64, RWD_STATE_WAKING, false)) + { + UserMessage("hitag2crack_send_e_cmd:\r\n tx/rx nrar failed\r\n"); + return false; + } + + // send encrypted command + if (!hitag2crack_tx_rx(responsestr, cmd, len, RWD_STATE_WAKING, false)) + { +#ifdef RFIDLER_DEBUG + UserMessage("hitag2crack_send_e_cmd:\r\n tx/rx cmd failed\r\n"); +#endif + return false; + } + + return true; +} + +// hitag2crack_tx_rx transmits a message and receives a response. +// responsestr is the hexstring of the response; +// msg is the binarray of the message to send; +// state is the RWD state; +// reset indicates whether to reset RWD state after. +bool hitag2crack_tx_rx(uint8_t *responsestr, uint8_t *msg, int len, int state, bool reset) { + uint8_t tmp[37]; + int ret = 0; + + // START_AUTH kills active crypto session + CryptoActive= false; + + if(!rwd_send(msg, len, reset, BLOCK, state, RFIDlerConfig.FrameClock, 0, RFIDlerConfig.RWD_Wait_Switch_RX_TX, RFIDlerConfig.RWD_Zero_Period, RFIDlerConfig.RWD_One_Period, RFIDlerConfig.RWD_Gap_Period, RFIDlerConfig.RWD_Wait_Switch_TX_RX)) + { + UserMessage("hitag2crack_tx_rx: rwd_send failed\r\n"); + return false; + } + + // skip 1/2 bit to synchronise manchester + HW_Skip_Bits = 1; + ret = read_ask_data(RFIDlerConfig.FrameClock, RFIDlerConfig.DataRate, tmp, 37, RFIDlerConfig.Sync, RFIDlerConfig.SyncBits, RFIDlerConfig.Timeout, ONESHOT_READ, BINARY); + + // check if response was a valid length (5 sync bits + 32 bits response) + if (ret == 37) + { + // check sync bits + if (memcmp(tmp, Hitag2Sync, 5) != 0) + { + UserMessage("hitag2crack_tx_rx: no sync\r\n"); + return false; + } + + // convert response to hexstring + binarraytohex(responsestr, tmp + 5, 32); + return true; + } + else + { +#ifdef RFIDLER_DEBUG + UserMessage("hitag2crack_tx_rx: wrong rx len\r\n"); +#endif + return false; + } + return false; +} + + +bool hitag2crack_rng_init(uint8_t *response, uint8_t *input) { + uint64_t sharedkey; + uint32_t serialnum; + uint32_t initvector; + uint8_t *spaceptr; + uint8_t *dataptr; + + // extract vals from input + dataptr = input; + spaceptr = strchr(dataptr, ' '); + if (!spaceptr) + { + UserMessage("/r/nformat is 'sharedkey UID nR' in hex\r\n"); + return false; + } + + *spaceptr = 0x00; + + if (strlen(dataptr) != 12) + { + UserMessage("/r/nsharedkey should be 48 bits long (12 hexchars)\r\n"); + return false; + } + + sharedkey = rev64(hexreversetoulonglong(dataptr)); + + dataptr = spaceptr+1; + spaceptr = strchr(dataptr, ' '); + if (!spaceptr) + { + UserMessage("/r/nno UID\r\n"); + return false; + } + + *spaceptr = 0x00; + if (strlen(dataptr) != 8) + { + UserMessage("/r/nUID should be 32 bits long (8 hexchars)\r\n"); + return false; + } + + serialnum = rev32(hexreversetoulong(dataptr)); + + dataptr = spaceptr+1; + + if (strlen(dataptr) != 8) + { + UserMessage("/r/nnR should be 32 bits long (8 hexchars)\r\n"); + return false; + } + + initvector = rev32(hexreversetoulong(dataptr)); + + // start up crypto engine + hitag2_init(&Hitag_Crypto_State, sharedkey, serialnum, initvector); + + strcpy(response, "Success\r\n"); + + return true; +} + +bool hitag2crack_decrypt_hex(uint8_t *response, uint8_t *hex) { + uint8_t bin[32]; + uint8_t binhex[9]; + uint8_t binstr[33]; + uint32_t binulong; + + if (strlen(hex) != 8) + { + UserMessage("/r/nhex must be 32bits (8 hex chars)\r\n"); + return false; + } + + binulong = hextoulong(hex); + + ulongtobinarray(bin, hitag2_crypt(binulong, 32), 32); + binarraytobinstring(binstr, bin, 32); + binarraytohex(binhex, bin, 32); +// UserMessage("ar = %s\r\n", binstr); +// UserMessage("arhex = %s\r\n", binhex); + + strcpy(response, binhex); + return true; +} + +bool hitag2crack_decrypt_bin(uint8_t *response, uint8_t *e_binstr) { + uint8_t bin[32]; + uint8_t e_bin[32]; + uint8_t binstr[33]; + uint32_t binulong; + int len; + + len = strlen(e_binstr); + if (len > 32) + { + UserMessage("\r\nbinary string must be <= 32 bits\r\n"); + return false; + } + + binstringtobinarray(e_bin, e_binstr); + binulong = binarraytoulong(e_bin, len); + + ulongtobinarray(bin, hitag2_crypt(binulong, len), len); + binarraytobinstring(binstr, bin, len); + strcpy(response, binstr); + return true; +} + +bool hitag2crack_encrypt_hex(uint8_t *response, uint8_t *hex) { + // XOR pad so encrypt == decrypt :) + return hitag2crack_decrypt_hex(response, hex); +} + +bool hitag2crack_encrypt_bin(uint8_t *response, uint8_t *e_binstr) { + return hitag2crack_decrypt_bin(response, e_binstr); +} + +// hitag2_keystream uses the first crack algorithm described in the paper, +// Gone In 360 Seconds by Verdult, Garcia and Balasch, to retrieve 2048 bits +// of keystream. +// response is a multi-line text response containing the hex of the keystream; +// nrarhex is a string containing hex representations of the 32 bit nR and aR +// values (separated by a space) snooped using SNIFF-PWM. +bool hitag2_keystream(uint8_t *response, uint8_t *nrarhex) { + uint8_t uidhex[9]; + uint8_t uid[32]; + uint8_t nrar[64]; + uint8_t e_firstcmd[10]; + uint8_t e_page0cmd[10]; +// uint8_t keybits[2080]; + uint8_t *keybits = DataBuff; + uint8_t keybitshex[67]; + int kslen; + int ksoffset; + uint8_t pagehex[9]; + uint8_t temp[20]; + int i; + uint8_t *spaceptr = NULL; + +/* + keybits = malloc(2080); + if (!keybits) { + UserMessage("cannot malloc keybits\r\n"); + return false; + } +*/ + + // get uid as hexstring + if(!hitag2_get_uid(uidhex)) + { + UserMessage("Cannot get UID\r\n"); + return false; + } + + // convert uid hexstring to binarray + hextobinarray(uid, uidhex); + + // convert nR and aR hexstrings to binarray + spaceptr = strchr(nrarhex, ' '); + if (!spaceptr) + { + UserMessage("Please supply a valid nR aR pair\r\n"); + return false; + } + *spaceptr = 0x00; + + if (hextobinarray(nrar, nrarhex) != 32) + { + UserMessage("nR is not 32 bits long\r\n"); + return false; + } + + if (hextobinarray(nrar + 32, spaceptr + 1) != 32) + { + UserMessage("aR is not 32 bits long\r\n"); + return false; + } + + // find a valid encrypted command + if (!hitag2crack_find_valid_e_cmd(e_firstcmd, nrar)) + { + UserMessage("Cannot find a valid encrypted command\r\n"); + return false; + } + + // find the 'read page 0' command and recover key stream + if (!hitag2crack_find_e_page0_cmd(keybits, e_firstcmd, nrar, uid)) + { + UserMessage("Cannot find encrypted 'read page0' command\r\n"); + return false; + } + + // using the 40 bits of keystream in keybits, sending commands with ever + // increasing lengths to acquire 2048 bits of key stream. + kslen = 40; + + while (kslen < 2048) + { + ksoffset = 0; + if (!hitag2crack_send_auth(nrar)) + { + UserMessage("hitag2crack_send_auth failed\r\n"); + return false; + } + // while we have at least 52 bits of keystream, consume it with + // extended read page 0 commands. 52 = 10 (min command len) + + // 32 (response) + 10 (min command len we'll send) + while ((kslen - ksoffset) >= 52) + { + // consume the keystream, updating ksoffset as we go + if (!hitag2crack_consume_keystream(keybits, kslen, &ksoffset, nrar)) + { + UserMessage("hitag2crack_consume_keystream failed\r\n"); + return false; + } + } + // send an extended command to retrieve more keystream, updating kslen + // as we go + if (!hitag2crack_extend_keystream(keybits, &kslen, ksoffset, nrar, uid)) + { + UserMessage("hitag2crack_extend_keystream failed\r\n"); + return false; + } + UserMessage("Recovered %d bits of keystream\r\n", kslen); + + } + + for (i=0; i<2048; i+=256) + { + binarraytohex(keybitshex, keybits + i, 256); + UserMessage("%s\r\n", keybitshex); + } + + response[0] = 0x00; + + return true; +} + +// hitag2crack_send_auth replays the auth and returns. +// nrar is the 64 bit binarray of the nR aR pair; +bool hitag2crack_send_auth(uint8_t *nrar) { + uint8_t uid[9]; + uint8_t e_page3str[9]; + + // get the UID + if(!hitag2_get_uid(uid)) + { + UserMessage("hitag2crack_send_auth:\r\n cannot get UID\r\n"); + return false; + } + + // START_AUTH kills active crypto session + CryptoActive = false; + + // get the UID again + if(!hitag2_get_uid(uid)) + { + UserMessage("hitag2crack_send_auth:\r\n cannot get UID (2nd time)\r\n"); + return false; + } + + // send nrar and receive (useless) encrypted page 3 value + if (!hitag2crack_tx_rx(e_page3str, nrar, 64, RWD_STATE_WAKING, false)) + { + UserMessage("hitag2crack_send_auth:\r\n tx/rx nrar failed\r\n"); + return false; + } + return true; +} + +// hitag2crack_consume_keystream sends an extended command (up to 510 bits in +// length) to consume keystream. +// keybits is the binarray of keystream bits; +// kslen is the length of keystream; +// ksoffset is a pointer to the current keystream offset (updated by this fn); +// nrar is the 64 bit binarray of the nR aR pair. +bool hitag2crack_consume_keystream(uint8_t *keybits, int kslen, int *ksoffset, uint8_t *nrar) { + int conlen; + int numcmds; + int i; + uint8_t ext_cmd[510]; + uint8_t e_ext_cmd[510]; + uint8_t responsestr[9]; + + // calculate the length of keybits to consume with the extended command. + // 42 = 32 bit response + 10 bit command reserved for next command. conlen + // cannot be longer than 510 bits to fit into the small RWD buffer. + conlen = kslen - *ksoffset - 42; + if (conlen < 10) + { + UserMessage("hitag2crack_consume_keystream:\r\n conlen < 10\r\n"); + return false; + } + + // sanitise conlen + if (conlen > 510) + { + conlen = 510; + } + + // calculate how many repeated commands to send in this extended command. + numcmds = conlen / 10; + + // build extended command + for (i=0; i, Aug 2018 +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// Definitions hitag2 attack functions +//----------------------------------------------------------------------------- + +bool hitag2_crack(uint8_t *response, uint8_t *nrarhex); +bool hitag2crack_find_valid_e_cmd(uint8_t e_cmd[], uint8_t nrar[]); +bool hitag2crack_find_e_page0_cmd(uint8_t keybits[], uint8_t e_firstcmd[], uint8_t nrar[], uint8_t uid[]); +bool hitag2crack_test_e_p0cmd(uint8_t *keybits, uint8_t *nrar, uint8_t *e_cmd, uint8_t *uid, uint8_t *e_uid); +void hitag2crack_xor(uint8_t *target, uint8_t *source, uint8_t *pad, unsigned int len); +bool hitag2crack_read_page(uint8_t *responsestr, uint8_t pagenum, uint8_t *nrar, uint8_t *keybits); +bool hitag2crack_send_e_cmd(uint8_t *responsestr, uint8_t *nrar, uint8_t *cmd, int len); +bool hitag2crack_tx_rx(uint8_t *responsestr, uint8_t *msg, int len, int state, bool reset); + +bool hitag2crack_rng_init(uint8_t *response, uint8_t *input); +bool hitag2crack_decrypt_hex(uint8_t *response, uint8_t *hex); +bool hitag2crack_decrypt_bin(uint8_t *response, uint8_t *hex); +bool hitag2crack_encrypt_hex(uint8_t *response, uint8_t *hex); +bool hitag2crack_encrypt_bin(uint8_t *response, uint8_t *hex); + +bool hitag2_keystream(uint8_t *response, uint8_t *nrarhex); +bool hitag2crack_send_auth(uint8_t *nrar); +bool hitag2crack_consume_keystream(uint8_t *keybits, int kslen, int *ksoffset, uint8_t *nrar); +bool hitag2crack_extend_keystream(uint8_t *keybits, int *kslen, int ksoffset, uint8_t *nrar, uint8_t *uid); + +bool hitag2_reader(uint8_t *response, uint8_t *key, bool interactive); From cb67feee197b17c7ca6e9f4316122598b9518c3d Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 17 Jan 2020 17:06:46 +0100 Subject: [PATCH 1480/1854] documentation --- armsrc/hitag2.c | 1 + armsrc/lfadc.c | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index 158ffa095..0e56918a5 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -1326,6 +1326,7 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { } LED_D_ON(); + hitag2_init(); // init as reader diff --git a/armsrc/lfadc.c b/armsrc/lfadc.c index eaaa38631..3e15fdc0b 100644 --- a/armsrc/lfadc.c +++ b/armsrc/lfadc.c @@ -155,7 +155,11 @@ void lf_init(bool reader) { FpgaSetupSsc(); // When in reader mode, give the field a bit of time to settle. - if (reader) SpinDelay(50); + // 313T0 = 313 * 8us = 2504us = 2.5ms Hitag2 tags needs to be fully powered. + if (reader) { + // 50 ms + SpinDelay(50); + } // Steal this pin from the SSP (SPI communication channel with fpga) and use it to control the modulation AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; From 7ef3da91a0e41694d53e88ab3621a8a4a8f6c31b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 17 Jan 2020 17:37:08 +0100 Subject: [PATCH 1481/1854] chg: 'hf search' - textoutput logic --- client/cmdhf.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/client/cmdhf.c b/client/cmdhf.c index d0fbbffb2..e90f2ea28 100644 --- a/client/cmdhf.c +++ b/client/cmdhf.c @@ -85,8 +85,6 @@ int CmdHFSearch(const char *Cmd) { char cmdp = tolower(param_getchar(Cmd, 0)); if (cmdp == 'h') return usage_hf_search(); - PrintAndLogEx(INFO, "Checking for known tags..."); - PROMPT_CLEARLINE; PrintAndLogEx(INPLACE, "Searching for ThinFilm tag..."); if (IfPm3NfcBarcode()) { @@ -170,9 +168,8 @@ int CmdHFSearch(const char *Cmd) { } PROMPT_CLEARLINE; - PrintAndLogEx(INPLACE, "done"); + PrintAndLogEx(INPLACE, _RED_("No known/supported 13.56 MHz tags found")); PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(FAILED, _RED_("No known/supported 13.56 MHz tags found")); return PM3_ESOFT; } From 42c6c1338e98d082a9fbb3d79c481d2965aac2dd Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 17 Jan 2020 17:41:28 +0100 Subject: [PATCH 1482/1854] textual --- client/cmdhflto.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/cmdhflto.c b/client/cmdhflto.c index 10847645b..2cd423ccd 100644 --- a/client/cmdhflto.c +++ b/client/cmdhflto.c @@ -145,7 +145,8 @@ int infoLTO(bool verbose) { lto_switch_off_field(); if (ret_val == PM3_SUCCESS) { - PrintAndLogEx(SUCCESS, "\nUID: " _YELLOW_("%s"), sprint_hex_inrow(serial_number, sizeof(serial_number))); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(SUCCESS, "UID: " _YELLOW_("%s"), sprint_hex_inrow(serial_number, sizeof(serial_number))); // todo: add printing of all configuration } From 505777e3f1fd4bd9738ef5c2bfa13c672c743d00 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 17 Jan 2020 17:54:17 +0100 Subject: [PATCH 1483/1854] text --- client/cmdhflto.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/client/cmdhflto.c b/client/cmdhflto.c index 2cd423ccd..39e9cf30b 100644 --- a/client/cmdhflto.c +++ b/client/cmdhflto.c @@ -132,7 +132,7 @@ static int CmdHfLTOInfo(const char *Cmd) { return PM3_EINVARG; } - return infoLTO(true); + return infoLTO(false); } int infoLTO(bool verbose) { @@ -146,9 +146,11 @@ int infoLTO(bool verbose) { if (ret_val == PM3_SUCCESS) { PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(SUCCESS, "UID: " _YELLOW_("%s"), sprint_hex_inrow(serial_number, sizeof(serial_number))); - + PrintAndLogEx(SUCCESS, " UID : " _YELLOW_("%s"), sprint_hex_inrow(serial_number, sizeof(serial_number))); + PrintAndLogEx(SUCCESS, "TYPE : "); // todo: add printing of all configuration + } else { + if (verbose) PrintAndLogEx(WARNING, "LTO-CM card select failed"); } /* read block: From f8c794208245ef5433a13e5dcbf270e50a22970a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 19 Jan 2020 12:09:56 +0100 Subject: [PATCH 1484/1854] textual --- client/mifare/mifarehost.c | 55 +++++++++++++++++++++++++++----------- 1 file changed, 39 insertions(+), 16 deletions(-) diff --git a/client/mifare/mifarehost.c b/client/mifare/mifarehost.c index 5ba245070..e3021c8f6 100644 --- a/client/mifare/mifarehost.c +++ b/client/mifare/mifarehost.c @@ -125,15 +125,16 @@ int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) { } } - PrintAndLogEx(SUCCESS, "found " _YELLOW_("%u") "candidate key%s\n", keycount, (keycount > 1) ? "s." : "."); + PrintAndLogEx(SUCCESS, "found " _YELLOW_("%u") "candidate key%s", keycount, (keycount > 1) ? "s." : "."); *key = UINT64_C(-1); uint8_t keyBlock[PM3_CMD_DATA_SIZE]; uint32_t max_keys = KEYS_IN_BLOCK; for (uint32_t i = 0; i < keycount; i += max_keys) { - uint32_t size = keycount - i > max_keys ? max_keys : keycount - i; - for (uint32_t j = 0; j < size; j++) { + uint8_t size = keycount - i > max_keys ? max_keys : keycount - i; + register uint8_t j; + for (j = 0; j < size; j++) { if (par_list == 0) { num_to_bytes(last_keylist[i * max_keys + j], 6, keyBlock + (j * 6)); } else { @@ -159,6 +160,7 @@ int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) { free(keylist); return PM3_SUCCESS; } + int mfCheckKeys(uint8_t blockNo, uint8_t keyType, bool clear_trace, uint8_t keycnt, uint8_t *keyBlock, uint64_t *key) { *key = -1; clearCommandBuffer(); @@ -308,7 +310,7 @@ int mfKeyBrute(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint64_t *resultk } // Compare 16 Bits out of cryptostate -static int Compare16Bits(const void *a, const void *b) { +inline static int Compare16Bits(const void *a, const void *b) { if ((*(uint64_t *)b & 0x00ff000000ff0000) == (*(uint64_t *)a & 0x00ff000000ff0000)) return 0; if ((*(uint64_t *)b & 0x00ff000000ff0000) > (*(uint64_t *)a & 0x00ff000000ff0000)) return 1; return -1; @@ -330,13 +332,14 @@ __attribute__((force_align_arg_pointer)) statelist->len = p1 - statelist->head.slhead; statelist->tail.sltail = --p1; + qsort(statelist->head.slhead, statelist->len, sizeof(uint64_t), Compare16Bits); return statelist->head.slhead; } int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t *resultKey, bool calibrate) { - uint16_t i; + uint32_t uid; StateList_t statelists[2]; struct Crypto1State *p1, *p2, *p3, *p4; @@ -385,7 +388,7 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, memcpy(&uid, package->cuid, sizeof(package->cuid)); - for (i = 0; i < 2; i++) { + for (uint8_t i = 0; i < 2; i++) { statelists[i].blockNo = package->block; statelists[i].keyType = package->keytype; statelists[i].uid = uid; @@ -402,11 +405,11 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, pthread_t thread_id[2]; // create and run worker threads - for (i = 0; i < 2; i++) + for (uint8_t i = 0; i < 2; i++) pthread_create(thread_id + i, NULL, nested_worker_thread, &statelists[i]); // wait for threads to terminate: - for (i = 0; i < 2; i++) + for (uint8_t i = 0; i < 2; i++) pthread_join(thread_id[i], (void *)&statelists[i].head.slhead); // the first 16 Bits of the cryptostate already contain part of our key. @@ -457,6 +460,8 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, uint32_t keycnt = statelists[0].len; if (keycnt == 0) goto out; + PrintAndLogEx(SUCCESS, "Found " _YELLOW_("%u") "candidate keys", keycnt); + memset(resultKey, 0, 6); uint64_t key64 = -1; @@ -464,11 +469,14 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, uint32_t max_keys = keycnt > KEYS_IN_BLOCK ? KEYS_IN_BLOCK : keycnt; uint8_t keyBlock[PM3_CMD_DATA_SIZE] = {0x00}; - for (i = 0; i < keycnt; i += max_keys) { + uint64_t start_time = msclock(); - int size = keycnt - i > max_keys ? max_keys : keycnt - i; + for (uint32_t i = 0; i < keycnt; i += max_keys) { - for (int j = 0; j < size; j++) { + uint8_t size = keycnt - i > max_keys ? max_keys : keycnt - i; + + register uint8_t j; + for (j = 0; j < size; j++) { crypto1_get_lfsr(statelists[0].head.slhead + i, &key64); num_to_bytes(key64, 6, keyBlock + j * 6); } @@ -485,6 +493,13 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, ); return -5; } + + float bruteforce_per_second = (float)KEYS_IN_BLOCK / (float)(msclock() - start_time) * 1000.0; + start_time = msclock(); + + if ( i + 1 % 10 == 0) + PrintAndLogEx(INFO, " %8d keys left | %5.1f keys/sec | worst case %6.1f seconds remaining", keycnt - i, bruteforce_per_second, (keycnt-i) / bruteforce_per_second); + } out: @@ -499,7 +514,7 @@ out: } int mfStaticNested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t *resultKey) { - uint16_t i; + uint32_t uid; StateList_t statelists[1]; struct Crypto1State *p1, *p3; @@ -589,16 +604,18 @@ int mfStaticNested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBl uint32_t max_keys_slice = keycnt > KEYS_IN_BLOCK ? KEYS_IN_BLOCK : keycnt; uint8_t keyBlock[PM3_CMD_DATA_SIZE] = {0x00}; - for (i = 0; i < keycnt; i += max_keys_slice) { + uint64_t start_time = msclock(); + for (uint32_t i = 0; i < keycnt; i += max_keys_slice) { - PrintAndLogEx(INFO, "Testing %u / %u ", i, keycnt); +// PrintAndLogEx(INFO, "Testing %u / %u ", i, keycnt); key64 = 0; - int size = keycnt - i > max_keys_slice ? max_keys_slice : keycnt - i; + uint8_t size = keycnt - i > max_keys_slice ? max_keys_slice : keycnt - i; // copy x keys to device. - for (int j = 0; j < size; j++) { + register uint8_t j; + for (j = 0; j < size; j++) { crypto1_get_lfsr(statelists[0].head.slhead + i + j, &key64); num_to_bytes(key64, 6, keyBlock + j * 6); } @@ -617,6 +634,12 @@ int mfStaticNested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBl ); return PM3_SUCCESS; } + float bruteforce_per_second = (float)KEYS_IN_BLOCK / (float)(msclock() - start_time) * 1000.0; + start_time = msclock(); + + if ( i+1 % 10 == 0) + PrintAndLogEx(INFO, " %8d keys left | %5.1f keys/sec | worst case %6.1f seconds remaining", keycnt - i, bruteforce_per_second, (keycnt-i) / bruteforce_per_second); + } out: From dab043a1fc487d51aceaf1b5de17cff55065f077 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 19 Jan 2020 14:51:39 +0100 Subject: [PATCH 1485/1854] textual --- client/cmdlf.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/client/cmdlf.c b/client/cmdlf.c index 48f1cd235..3fee78735 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -339,7 +339,7 @@ int CmdLFCommandRead(const char *Cmd) { // bitbang mode if (payload.delay == 0) { if (payload.zeros < 7 || payload.ones < 7) { - PrintAndLogEx(WARNING, "Warning periods cannot be less than 7us in bit bang mode"); + PrintAndLogEx(WARNING, "warning periods cannot be less than 7us in bit bang mode"); return PM3_EINVARG; } } @@ -347,15 +347,14 @@ int CmdLFCommandRead(const char *Cmd) { //Validations if (errors || cmdp == 0) return usage_lf_cmdread(); - PrintAndLogEx(SUCCESS, "Sending"); + PrintAndLogEx(SUCCESS, "sending"); clearCommandBuffer(); SendCommandNG(CMD_LF_MOD_THEN_ACQ_RAW_ADC, (uint8_t *)&payload, 8 + datalen); - printf("\n"); - PacketResponseNG resp; uint8_t i = 10; + // 20sec wait loop while (!WaitForResponseTimeout(CMD_LF_MOD_THEN_ACQ_RAW_ADC, &resp, 2000) && i != 0) { printf("."); fflush(stdout); @@ -365,15 +364,15 @@ int CmdLFCommandRead(const char *Cmd) { if (resp.status == PM3_SUCCESS) { if (i) { - PrintAndLogEx(SUCCESS, "Downloading response signal data"); - getSamples(0, false); + PrintAndLogEx(SUCCESS, "downloading response signal data"); + getSamples(0, true); return PM3_SUCCESS; } else { PrintAndLogEx(WARNING, "timeout while waiting for reply."); return PM3_ETIMEOUT; } } - PrintAndLogEx(WARNING, "Command failed."); + PrintAndLogEx(WARNING, "command failed."); return PM3_ESOFT; } From e85fabf01512ad678883786991a1ed59ab94de8d Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 20 Jan 2020 11:37:10 +0100 Subject: [PATCH 1486/1854] chg: 'lf hitag list' - improved hitag annotation --- client/cmdlfhitag.c | 47 ++++++++++++++++++++++++++++++++++++++++++--- client/cmdlfhitag.h | 4 +++- client/cmdtrace.c | 28 +++++++++++++++++++++------ include/protocols.h | 19 ++++++++++++------ 4 files changed, 82 insertions(+), 16 deletions(-) diff --git a/client/cmdlfhitag.c b/client/cmdlfhitag.c index 3ebbe47a6..f0a8037dc 100644 --- a/client/cmdlfhitag.c +++ b/client/cmdlfhitag.c @@ -18,6 +18,7 @@ #include "commonutil.h" #include "hitag.h" #include "fileutils.h" // savefile +#include "protocols.h" // defines static int CmdHelp(const char *Cmd); @@ -85,9 +86,9 @@ static int usage_hitag_reader(void) { PrintAndLogEx(NORMAL, " Hitag1 (1*)"); PrintAndLogEx(NORMAL, " Not implemented"); PrintAndLogEx(NORMAL, " Hitag2 (2*)"); - PrintAndLogEx(NORMAL, " 21 Read all pages, password mode. Default: 4D494B52 (\"MIKR\")"); + PrintAndLogEx(NORMAL, " 21 Read all pages, password mode. Default: " _YELLOW_("4D494B52") "(\"MIKR\")"); PrintAndLogEx(NORMAL, " 22 Read all pages, challenge mode"); - PrintAndLogEx(NORMAL, " 23 Read all pages, crypto mode. Key format: ISK high + ISK low. Default: 4F4E4D494B52 (\"ONMIKR\")"); + PrintAndLogEx(NORMAL, " 23 Read all pages, crypto mode. Key format: ISK high + ISK low. Default: " _YELLOW_("4F4E4D494B52") "(\"ONMIKR\")"); PrintAndLogEx(NORMAL, " 25 Test recorded authentications"); PrintAndLogEx(NORMAL, " 26 Just read UID"); return PM3_SUCCESS; @@ -124,7 +125,7 @@ static int usage_hitag_checkchallenges(void) { static int CmdLFHitagList(const char *Cmd) { (void)Cmd; // Cmd is not used so far - CmdTraceList("hitag"); + CmdTraceList("hitag2"); return PM3_SUCCESS; /* @@ -698,6 +699,46 @@ static int CmdLFHitagDump(const char *Cmd) { } */ +// Annotate HITAG protocol +void annotateHitag1(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) { +} + +void annotateHitag2(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) { + + uint8_t cmdbits = (cmd[0] & 0xC0) >> 6; + + if (cmdsize == 1) { + if (cmdbits == HITAG2_START_AUTH) { + snprintf(exp, size, "START AUTH"); + return; + } + if (cmdbits == HITAG2_HALT) { + snprintf(exp, size, "HALT"); + return; + } + } + + if (cmdsize == 2) { + if (cmdbits == HITAG2_START_AUTH) { + // C 1 C 0 + // 1100 0 00 1 1100 000 + uint8_t page = (cmd[0] & 0x38) >> 3; + uint8_t inv_page = ((cmd[0] & 0x1) << 2) | ((cmd[1] & 0xC0) >> 6); + snprintf(exp, size, "READ page(%x) %x", page, inv_page); + return; + } + if (cmdbits == HITAG2_WRITE_PAGE) { + uint8_t page = (cmd[0] & 0x38) >> 3; + uint8_t inv_page = ((cmd[0] & 0x1) << 2) | ((cmd[1] & 0xC0) >> 6); + snprintf(exp, size, "WRITE page(%x) %x", page, inv_page); + return; + } + } +} + +void annotateHitagS(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) { +} + static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help" }, {"list", CmdLFHitagList, IfPm3Hitag, "List Hitag trace history" }, diff --git a/client/cmdlfhitag.h b/client/cmdlfhitag.h index c95c0e334..98b9968e0 100644 --- a/client/cmdlfhitag.h +++ b/client/cmdlfhitag.h @@ -16,5 +16,7 @@ int CmdLFHitag(const char *Cmd); int readHitagUid(void); - +void annotateHitag1(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize); +void annotateHitag2(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize); +void annotateHitagS(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize); #endif diff --git a/client/cmdtrace.c b/client/cmdtrace.c index a13a82809..0e2093d98 100644 --- a/client/cmdtrace.c +++ b/client/cmdtrace.c @@ -17,6 +17,7 @@ #include "cmdhflist.h" // annotations #include "comms.h" // for sending cmds to device. GetFromBigBuf #include "fileutils.h" // for saveFile +#include "cmdlfhitag.h" // annotate hitag static int CmdHelp(const char *Cmd); @@ -281,7 +282,9 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr crcStatus = iso15693_CRC_check(frame, data_len); break; case ISO_7816_4: - case PROTO_HITAG: + case PROTO_HITAG1: + case PROTO_HITAG2: + case PROTO_HITAGS: default: break; } @@ -301,7 +304,9 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr && protocol != ISO_15693 && protocol != ICLASS && protocol != ISO_7816_4 - && protocol != PROTO_HITAG + && protocol != PROTO_HITAG1 + && protocol != PROTO_HITAG2 + && protocol != PROTO_HITAGS && protocol != THINFILM && protocol != FELICA && protocol != LTO @@ -385,6 +390,15 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr case LTO: annotateLTO(explanation, sizeof(explanation), frame, data_len); break; + case PROTO_HITAG1: + annotateHitag1(explanation, sizeof(explanation), frame, data_len); + break; + case PROTO_HITAG2: + annotateHitag2(explanation, sizeof(explanation), frame, data_len); + break; + case PROTO_HITAGS: + annotateHitagS(explanation, sizeof(explanation), frame, data_len); + break; default: break; } @@ -593,7 +607,9 @@ int CmdTraceList(const char *Cmd) { else if (strcmp(type, "15") == 0) protocol = ISO_15693; else if (strcmp(type, "felica") == 0) protocol = FELICA; else if (strcmp(type, "mf") == 0) protocol = PROTO_MIFARE; - else if (strcmp(type, "hitag") == 0) protocol = PROTO_HITAG; + else if (strcmp(type, "hitag1") == 0) protocol = PROTO_HITAG1; + else if (strcmp(type, "hitag2") == 0) protocol = PROTO_HITAG2; + else if (strcmp(type, "hitags") == 0) protocol = PROTO_HITAGS; else if (strcmp(type, "thinfilm") == 0) protocol = THINFILM; else if (strcmp(type, "lto") == 0) protocol = LTO; else if (strcmp(type, "raw") == 0) protocol = -1; //No crc, no annotations @@ -673,11 +689,11 @@ int CmdTraceList(const char *Cmd) { PrintAndLogEx(NORMAL, "ISO15693 - Timings are not as accurate"); if (protocol == ISO_7816_4) PrintAndLogEx(NORMAL, "ISO7816-4 / Smartcard - Timings N/A yet"); - if (protocol == PROTO_HITAG) - PrintAndLogEx(NORMAL, "Hitag2 / HitagS - Timings in ETU (8us)"); + if (protocol == PROTO_HITAG1 || protocol == PROTO_HITAG2 || protocol == PROTO_HITAGS) + PrintAndLogEx(NORMAL, "Hitag1 / Hitag2 / HitagS - Timings in ETU (8us)"); if (protocol == FELICA) PrintAndLogEx(NORMAL, "ISO18092 / FeliCa - Timings are not as accurate"); - + PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, " Start | End | Src | Data (! denotes parity error) | CRC | Annotation"); PrintAndLogEx(NORMAL, "------------+------------+-----+-------------------------------------------------------------------------+-----+--------------------"); diff --git a/include/protocols.h b/include/protocols.h index 47e022c28..222e16ab8 100644 --- a/include/protocols.h +++ b/include/protocols.h @@ -305,9 +305,11 @@ ISO 7816-4 Basic interindustry commands. For command APDU's. #define ISO_15693 7 #define FELICA 8 #define PROTO_MIFARE 9 -#define PROTO_HITAG 10 +#define PROTO_HITAG1 10 #define THINFILM 11 #define LTO 12 +#define PROTO_HITAG2 13 +#define PROTO_HITAGS 14 //-- Picopass fuses #define FUSE_FPERS 0x80 @@ -588,12 +590,17 @@ ISO 7816-4 Basic interindustry commands. For command APDU's. #define HITAG1_HALT 0x70 // left 4 bits only, followed by 8 bits (dummy) page and 8 bits CRC // HITAG2 commands -#define HITAG2_START_AUTH 0xC0 // left 5 bits only -#define HITAG2_READ_PAGE 0xC0 // page number in bits 5 to 3, page number inverted in bit 0 and following 2 bits -#define HITAG2_READ_PAGE_INVERTED 0x44 // page number in bits 5 to 3, page number inverted in bit 0 and following 2 bits -#define HITAG2_WRITE_PAGE 0x82 // page number in bits 5 to 3, page number inverted in bit 0 and following 2 bits -#define HITAG2_HALT 0x00 // left 5 bits only +#define HITAG2_START_AUTH 0x3 // left 5 bits only +#define HITAG2_READ_PAGE 0x3 // page number in bits 5 to 3, page number inverted in bit 0 and following 2 bits +#define HITAG2_READ_PAGE_INVERTED 0x1 // page number in bits 5 to 3, page number inverted in bit 0 and following 2 bits +#define HITAG2_WRITE_PAGE 0x2 // page number in bits 5 to 3, page number +#define HITAG2_HALT 0x0 // left 5 bits only + +// HITAG S commands +#define HITAGS_QUIET 0x70 +//inverted in bit 0 and following 2 bits +#define HITAGS_WRITE_BLOCK 0x90 // LTO-CM commands #define LTO_REQ_STANDARD 0x45 From 3fa5858af904eeb9e55d09e49e4fe61798e67239 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 20 Jan 2020 11:47:13 +0100 Subject: [PATCH 1487/1854] textual --- client/cmdtrace.c | 4 +++- include/protocols.h | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/client/cmdtrace.c b/client/cmdtrace.c index 0e2093d98..76fd05d5d 100644 --- a/client/cmdtrace.c +++ b/client/cmdtrace.c @@ -46,7 +46,9 @@ static int usage_trace_list() { PrintAndLogEx(NORMAL, " iclass - interpret data as iclass communications"); PrintAndLogEx(NORMAL, " legic - interpret data as LEGIC communications"); PrintAndLogEx(NORMAL, " felica - interpret data as ISO18092 / FeliCa communications"); - PrintAndLogEx(NORMAL, " hitag - interpret data as Hitag2 / HitagS communications"); + PrintAndLogEx(NORMAL, " hitag1 - interpret data as Hitag1 communications"); + PrintAndLogEx(NORMAL, " hitag2 - interpret data as Hitag2 communications"); + PrintAndLogEx(NORMAL, " hitags - interpret data as HitagS communications"); PrintAndLogEx(NORMAL, " lto - interpret data as LTO-CM communications"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); diff --git a/include/protocols.h b/include/protocols.h index 222e16ab8..e1d898d53 100644 --- a/include/protocols.h +++ b/include/protocols.h @@ -591,11 +591,12 @@ ISO 7816-4 Basic interindustry commands. For command APDU's. // HITAG2 commands #define HITAG2_START_AUTH 0x3 // left 5 bits only +#define HITAG2_HALT 0x0 // left 5 bits only #define HITAG2_READ_PAGE 0x3 // page number in bits 5 to 3, page number inverted in bit 0 and following 2 bits #define HITAG2_READ_PAGE_INVERTED 0x1 // page number in bits 5 to 3, page number inverted in bit 0 and following 2 bits #define HITAG2_WRITE_PAGE 0x2 // page number in bits 5 to 3, page number -#define HITAG2_HALT 0x0 // left 5 bits only + // HITAG S commands #define HITAGS_QUIET 0x70 From e3ff3a8819ffa85114a33948637f1840a9ca6055 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 20 Jan 2020 11:54:21 +0100 Subject: [PATCH 1488/1854] textual --- client/cmdtrace.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/client/cmdtrace.c b/client/cmdtrace.c index 76fd05d5d..88f55ed3f 100644 --- a/client/cmdtrace.c +++ b/client/cmdtrace.c @@ -662,8 +662,7 @@ int CmdTraceList(const char *Cmd) { } } - PrintAndLogEx(SUCCESS, "Recorded Activity (TraceLen = %lu bytes)", traceLen); - PrintAndLogEx(INFO, ""); + PrintAndLogEx(SUCCESS, "Recorded activity (trace len = " _YELLOW_("%lu") "bytes)", traceLen); /* if (protocol == FELICA) { @@ -675,26 +674,26 @@ int CmdTraceList(const char *Cmd) { tracepos = printHexLine(tracepos, traceLen, trace, protocol); } } else { - PrintAndLogEx(NORMAL, "Start = Start of Start Bit, End = End of last modulation. Src = Source of Transfer"); + PrintAndLogEx(INFO, _YELLOW_("Start") "= Start of Start Bit, " _YELLOW_("End") "= End of last modulation. " _YELLOW_("Src") "= Source of Transfer"); if (protocol == ISO_14443A || protocol == PROTO_MIFARE || protocol == MFDES || protocol == TOPAZ || protocol == LTO) - PrintAndLogEx(NORMAL, "ISO14443A - All times are in carrier periods (1/13.56MHz)"); + PrintAndLogEx(INFO, "ISO14443A - All times are in carrier periods (1/13.56MHz)"); if (protocol == THINFILM) - PrintAndLogEx(NORMAL, "Thinfilm - All times are in carrier periods (1/13.56MHz)"); + PrintAndLogEx(INFO, "Thinfilm - All times are in carrier periods (1/13.56MHz)"); if (protocol == ICLASS) - PrintAndLogEx(NORMAL, "iClass - Timings are not as accurate"); + PrintAndLogEx(INFO, "iClass - Timings are not as accurate"); if (protocol == LEGIC) - PrintAndLogEx(NORMAL, "LEGIC - Reader Mode: Timings are in ticks (1us == 1.5ticks)\n" + PrintAndLogEx(INFO, "LEGIC - Reader Mode: Timings are in ticks (1us == 1.5ticks)\n" " Tag Mode: Timings are in sub carrier periods (1/212 kHz == 4.7us)"); if (protocol == ISO_14443B) - PrintAndLogEx(NORMAL, "ISO14443B"); // Timings ? + PrintAndLogEx(INFO, "ISO14443B"); // Timings ? if (protocol == ISO_15693) - PrintAndLogEx(NORMAL, "ISO15693 - Timings are not as accurate"); + PrintAndLogEx(INFO, "ISO15693 - Timings are not as accurate"); if (protocol == ISO_7816_4) - PrintAndLogEx(NORMAL, "ISO7816-4 / Smartcard - Timings N/A yet"); + PrintAndLogEx(INFO, "ISO7816-4 / Smartcard - Timings N/A yet"); if (protocol == PROTO_HITAG1 || protocol == PROTO_HITAG2 || protocol == PROTO_HITAGS) - PrintAndLogEx(NORMAL, "Hitag1 / Hitag2 / HitagS - Timings in ETU (8us)"); + PrintAndLogEx(INFO, "Hitag1 / Hitag2 / HitagS - Timings in ETU (8us)"); if (protocol == FELICA) - PrintAndLogEx(NORMAL, "ISO18092 / FeliCa - Timings are not as accurate"); + PrintAndLogEx(INFO, "ISO18092 / FeliCa - Timings are not as accurate"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, " Start | End | Src | Data (! denotes parity error) | CRC | Annotation"); From f04be0c0442226149fa24a46a4328fa442646d40 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 20 Jan 2020 11:58:22 +0100 Subject: [PATCH 1489/1854] chg: hitag write - works --- armsrc/hitag2.c | 374 +++++++++++++++++++++++++----------------------- 1 file changed, 195 insertions(+), 179 deletions(-) diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index 0e56918a5..6efe5808d 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -1566,8 +1566,8 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { LogTrace(rx, nbytes(rxlen), response_start, response_start + response_duration, NULL, false); // TODO when using cumulative time for command_start, pm3 doesn't reply anymore, e.g. on lf hitag read 23 4F4E4D494B52 -// command_start = response_start + response_duration; - command_start = 0; + command_start = response_start + response_duration; +// command_start = 0; // Dbhexdump(nbytes(rxlen), rx, false); } } @@ -1590,25 +1590,35 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) { StopTicks(); - // int frame_count = 0; - int response = 0; + int frame_count = 0; + uint32_t command_start = 0; + uint32_t command_duration = 0; + uint32_t response_start = 0; + uint32_t response_duration = 0; uint8_t rx[HITAG_FRAME_LEN]; size_t rxlen = 0; uint8_t txbuf[HITAG_FRAME_LEN]; uint8_t *tx = txbuf; size_t txlen = 0; - int lastbit; - int reset_sof; - int t_wait = HITAG_T_WAIT_MAX; - bool bStop; + int t_wait_1; + int t_wait_1_guard = 8; + int t_wait_2; + size_t tag_size; + bool bStop = false; - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - set_tracing(true); - clear_trace(); + // Raw demodulation/decoding by sampling edge periods + size_t periods = 0; // Reset the return status bSuccessful = false; + bCrypto = false; + // Clean up trace and prepare it for storing frames + set_tracing(true); + clear_trace(); + + DbpString("Starting Hitag writer family"); + // Check configuration switch (htf) { case WHT2F_CRYPTO: { @@ -1642,221 +1652,227 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) { } LED_D_ON(); + hitag2_init(); - // Configure output and enable pin that is connected to the FPGA (for modulating) - AT91C_BASE_PIOA->PIO_OER |= GPIO_SSC_DOUT; - AT91C_BASE_PIOA->PIO_PER |= GPIO_SSC_DOUT; - - // Set fpga in edge detect with reader field, we can modulate as reader now - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, LF_DIVISOR_125); //125kHz - SetAdcMuxFor(GPIO_MUXSEL_LOPKD); - - // Disable modulation at default, which means enable the field - LOW(GPIO_SSC_DOUT); - - // Enable Peripheral Clock for - // TIMER_CLOCK0, used to measure exact timing before answering - // TIMER_CLOCK1, used to capture edges of the tag frames - AT91C_BASE_PMC->PMC_PCER |= (1 << AT91C_ID_TC0) | (1 << AT91C_ID_TC1); - - AT91C_BASE_PIOA->PIO_BSR = GPIO_SSC_FRAME; - - // Disable timer during configuration - AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; - - // TC0: Capture mode, default timer source = MCK/2 (TIMER_CLOCK1), no triggers - AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK; - - // TC1: Capture mode, defaul timer source = MCK/2 (TIMER_CLOCK1), TIOA is external trigger, - // external trigger rising edge, load RA on falling edge of TIOA. - AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK - | AT91C_TC_ETRGEDG_FALLING - | AT91C_TC_ABETRG - | AT91C_TC_LDRA_FALLING; - - // Enable and reset counters - AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; - - while (AT91C_BASE_TC0->TC_CV > 0) {}; - - // Reset the received frame, frame count and timing info - lastbit = 1; - bStop = false; - + // init as reader + lf_init(true); + // Tag specific configuration settings (sof, timings, etc.) if (htf < 10) { // hitagS settings - reset_sof = 1; - t_wait = 200; + t_wait_1 = 204; + t_wait_2 = 128; + /*tag_size = 256;*/ + flipped_bit = 0; + tag_size = 8; + DbpString("Configured for hitagS writer"); } else if (htf < 20) { - // hitag1 settings - reset_sof = 1; - t_wait = 200; + // hitag1 settings + t_wait_1 = 204; + t_wait_2 = 128; + tag_size = 256; + flipped_bit = 0; + DbpString("Configured for hitag1 writer"); } else if (htf < 30) { - // hitag2 settings - reset_sof = 4; - t_wait = HITAG_T_WAIT_2_MIN; + // hitag2 settings + t_wait_1 = HITAG_T_WAIT_1_MIN; + t_wait_2 = HITAG_T_WAIT_2_MIN; + tag_size = 48; + DbpString("Configured for hitag2 writer"); } else { - Dbprintf("Error, unknown hitag reader type: %d", htf); + Dbprintf("Error, unknown hitag writer type: %d", htf); return; } + uint8_t tag_modulation; + size_t max_nrzs = (8 * HITAG_FRAME_LEN + 5) * 2; // up to 2 nrzs per bit + uint8_t nrz_samples[max_nrzs]; + size_t nrzs = 0; + while (!bStop && !BUTTON_PRESS() && !data_available()) { WDT_HIT(); - // Check if frame was captured and store it - if (rxlen > 0) { - // frame_count++; - LogTrace(rx, nbytes(rxlen), response, response, NULL, false); - } - // By default reset the transmission buffer tx = txbuf; switch (htf) { case WHT2F_CRYPTO: { bStop = !hitag2_crypto(rx, rxlen, tx, &txlen, true); + break; } - break; case WHT2F_PASSWORD: { bStop = !hitag2_password(rx, rxlen, tx, &txlen, true); + break; } - break; default: { Dbprintf("Error, unknown function: %d", htf); - return; + goto out; } - break; } - // Send and store the reader command - // Disable timer 1 with external trigger to avoid triggers during our own modulation - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; - - // Wait for HITAG_T_WAIT_2 carrier periods after the last tag bit before transmitting, - // Since the clock counts since the last falling edge, a 'one' means that the - // falling edge occurred halfway the period. with respect to this falling edge, - // we need to wait (T_Wait2 + half_tag_period) when the last was a 'one'. - // All timer values are in terms of T0 units - while (AT91C_BASE_TC0->TC_CV < HITAG_T0 * (t_wait + (HITAG_T_TAG_HALF_PERIOD * lastbit))) {}; + // Wait for t_wait_2 carrier periods after the last tag bit before transmitting, + lf_wait_periods(t_wait_2); + command_start += t_wait_2; // Transmit the reader frame - hitag_reader_send_frame(tx, txlen); + command_duration = hitag_reader_send_frame(tx, txlen); + + response_start = command_start + command_duration; - // Enable and reset external trigger in timer for capturing future frames - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; + // Let the antenna and ADC values settle + // And find the position where edge sampling should start + lf_wait_periods(t_wait_1 - t_wait_1_guard); + response_start += t_wait_1 - t_wait_1_guard; - // Add transmitted frame to total count + // Keep administration of the first edge detection + bool waiting_for_first_edge = true; + + // Did we detected any modulaiton at all + bool detected_tag_modulation = false; + + // Use the current modulation state as starting point + tag_modulation = lf_get_tag_modulation(); + + // Reset the number of NRZ samples and use edge detection to detect them + nrzs = 0; + while (nrzs < max_nrzs) { + // Get the timing of the next edge in number of wave periods + periods = lf_count_edge_periods(128); + + // Are we dealing with the first incoming edge + if (waiting_for_first_edge) { + // Just break out of loop after an initial time-out (tag is probably not available) + if (periods == 0) break; + if (tag_modulation == 0) { + // hitag replies always start with 11111 == 1010101010, if we see 0 + // it means we missed the first period, e.g. if the signal never crossed 0 since reader signal + // so let's add it: + nrz_samples[nrzs++] = tag_modulation ^ 1; + // Register the number of periods that have passed + // we missed the begin of response but we know it happened one period of 16 earlier + response_start += periods - 16; + response_duration = response_start; + } else { + // Register the number of periods that have passed + response_start += periods; + response_duration = response_start; + } + // Indicate that we have dealt with the first edge + waiting_for_first_edge = false; + // The first edge is always a single NRZ bit, force periods on 16 + periods = 16; + // We have received more than 0 periods, so we have detected a tag response + detected_tag_modulation = true; + } else { + // The function lf_count_edge_periods() returns 0 when a time-out occurs + if (periods == 0) { + //Dbprintf("Detected timeout after [%d] nrz samples", nrzs); + break; + } + } + // Evaluate the number of periods before the next edge + if (periods > 24 && periods <= 64) { + // Detected two sequential equal bits and a modulation switch + // NRZ modulation: (11 => --|) or (11 __|) + nrz_samples[nrzs++] = tag_modulation; + nrz_samples[nrzs++] = tag_modulation; + response_duration += periods; + // Invert tag modulation state + tag_modulation ^= 1; + } else if (periods > 0 && periods <= 24) { + // Detected one bit and a modulation switch + // NRZ modulation: (1 => -|) or (0 _|) + nrz_samples[nrzs++] = tag_modulation; + response_duration += periods; + tag_modulation ^= 1; + } else { + // The function lf_count_edge_periods() returns > 64 periods, this is not a valid number periods + //Dbprintf("Detected unexpected period count: %d", periods); + break; + } + } + + // Wait some extra time for flash to be programmed + // + + // Store the TX frame, we do this now at this point, to avoid delay in processing + // and to be able to overwrite the first samples with the trace (since they currently + // still use the same memory space) if (txlen > 0) { - // frame_count++; - LogTrace(tx, nbytes(txlen), HITAG_T_WAIT_2_MIN, HITAG_T_WAIT_2_MIN, NULL, true); + frame_count++; + LogTrace(tx, nbytes(txlen), command_start, command_start + command_duration, NULL, true); } // Reset values for receiving frames memset(rx, 0x00, sizeof(rx)); rxlen = 0; - lastbit = 1; - bool bSkip = true; - int tag_sof = reset_sof; - response = 0; - uint32_t errorCount = 0; - // Receive frame, watch for at most T0*EOF periods - while (AT91C_BASE_TC1->TC_CV < HITAG_T0 * HITAG_T_WAIT_MAX) { - // Check if falling edge in tag modulation is detected - if (AT91C_BASE_TC1->TC_SR & AT91C_TC_LDRAS) { - // Retrieve the new timing values - int ra = (AT91C_BASE_TC1->TC_RA / HITAG_T0); + // If there is no response, just repeat the loop + if (!detected_tag_modulation) continue; - // Reset timer every frame, we have to capture the last edge for timing - AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; - - LED_B_ON(); - - // Capture tag frame (manchester decoding using only falling edges) - if (ra >= HITAG_T_EOF) { - if (rxlen != 0) { - //Dbprintf("DEBUG: Wierd1"); - } - // Capture the T0 periods that have passed since last communication or field drop (reset) - // We always recieve a 'one' first, which has the falling edge after a half period |-_| - response = ra - HITAG_T_TAG_HALF_PERIOD; - } else if (ra >= HITAG_T_TAG_CAPTURE_FOUR_HALF) { - // Manchester coding example |-_|_-|-_| (101) - - // need to test to verify we don't exceed memory... - // if ( ((rxlen+2) / 8) > HITAG_FRAME_LEN) { - // break; - // } - rx[rxlen / 8] |= 0 << (7 - (rxlen % 8)); - rxlen++; - rx[rxlen / 8] |= 1 << (7 - (rxlen % 8)); - rxlen++; - } else if (ra >= HITAG_T_TAG_CAPTURE_THREE_HALF) { - // Manchester coding example |_-|...|_-|-_| (0...01) - - // need to test to verify we don't exceed memory... - // if ( ((rxlen+2) / 8) > HITAG_FRAME_LEN) { - // break; - // } - rx[rxlen / 8] |= 0 << (7 - (rxlen % 8)); - rxlen++; - // We have to skip this half period at start and add the 'one' the second time - if (!bSkip) { - rx[rxlen / 8] |= 1 << (7 - (rxlen % 8)); - rxlen++; - } - lastbit = !lastbit; - bSkip = !bSkip; - } else if (ra >= HITAG_T_TAG_CAPTURE_TWO_HALF) { - // Manchester coding example |_-|_-| (00) or |-_|-_| (11) - - // need to test to verify we don't exceed memory... - // if ( ((rxlen+2) / 8) > HITAG_FRAME_LEN) { - // break; - // } - if (tag_sof) { - // Ignore bits that are transmitted during SOF - tag_sof--; - } else { - // bit is same as last bit - rx[rxlen / 8] |= lastbit << (7 - (rxlen % 8)); - rxlen++; - } - } else { - // Dbprintf("DEBUG: Wierd2"); - errorCount++; - // Ignore wierd value, is to small to mean anything - } - } - // if we saw over 100 wierd values break it probably isn't hitag... - if (errorCount > 100) break; - - // We can break this loop if we received the last bit from a frame - if (AT91C_BASE_TC1->TC_CV > HITAG_T0 * HITAG_T_EOF) { - if (rxlen > 0) break; - } + // Make sure we always have an even number of samples. This fixes the problem + // of ending the manchester decoding with a zero. See the example below where + // the '|' character is end of modulation + // One at the end: ..._-|_____... + // Zero at the end: ...-_|_____... + // The last modulation change of a zero is not detected, but we should take + // the half period in account, otherwise the demodulator will fail. + if ((nrzs % 2) != 0) { + nrz_samples[nrzs++] = tag_modulation; } - // Wait some extra time for flash to be programmed - if ((rxlen == 0) && (writestate == WRITE_STATE_PROG)) { - AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; - while (AT91C_BASE_TC0->TC_CV < HITAG_T0 * (HITAG_T_PROG - HITAG_T_WAIT_MAX)); + LED_B_ON(); + + // decode bitstream + manrawdecode((uint8_t *)nrz_samples, &nrzs, true, 0); + + // decode frame + + // Verify if the header consists of five consecutive ones + if (nrzs < 5) { + break; + } else { + size_t i; + for (i = 0; i < 5; i++) { + if (nrz_samples[i] != 1) { + Dbprintf("Detected incorrect header, the bit [%d] is zero instead of one, abort", i); + break; + } + } + if (i < 5) break; + } + + // Pack the response into a byte array + for (size_t i = 5; i < nrzs; i++) { + uint8_t bit = nrz_samples[i]; + if (bit > 1) { // When Manchester detects impossible symbol it writes "7" + break; + } + rx[rxlen / 8] |= bit << (7 - (rxlen % 8)); + rxlen++; + } + + if (rxlen % 8 == 1) // skip spurious bit + rxlen--; + + // Check if frame was captured and store it + if (rxlen > 0) { + frame_count++; + + LogTrace(rx, nbytes(rxlen), response_start, response_start + response_duration, NULL, false); + command_start = 0; } } - LEDsoff(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - set_tracing(false); - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; - AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; +out: + lf_finalize(); + Dbprintf("TX/RX frames recorded: %u", frame_count); + // release allocated memory from BigBuff. + BigBuf_free(); StartTicks(); - - reply_mix(CMD_ACK, bSuccessful, 0, 0, (uint8_t *)tag.sectors, 48); + + reply_mix(CMD_ACK, bSuccessful, 0, 0, (uint8_t *)tag.sectors, tag_size); } From fc007554ef3c5d0749e45855fab359e985621e01 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 20 Jan 2020 23:12:11 +0100 Subject: [PATCH 1490/1854] Fix compilation under openSUSE, thanks @hsanjuan. Fixes #529 --- CHANGELOG.md | 1 + common_arm/Makefile.common | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 06d3005be..f0b0e3c6f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Fix compilation under openSUSE (@hsanjuan) - Added `lf nexwatch sim` - use raw hex to simulate (@iceman1001) - Fix `lf indala read` - long id 224bits preamble identification less strict (@iceman1001) - Added `hf mf staticnested` - useful when targeting the strange cards with a static nonce. (@iceman100) Thanks to @xtigmh @uzlonewolf for their solutions. diff --git a/common_arm/Makefile.common b/common_arm/Makefile.common index 36887707c..be5d2a847 100644 --- a/common_arm/Makefile.common +++ b/common_arm/Makefile.common @@ -42,7 +42,7 @@ INCLUDES = ../include/proxmark3_arm.h ../include/at91sam7s512.h ../include/confi CFLAGS ?= -Wall -Werror -pedantic -Wunused -Os -mthumb-interwork CFLAGS += -c $(INCLUDE) -std=c99 $(APP_CFLAGS) -LDFLAGS += -nostartfiles -nodefaultlibs -Wl,-gc-sections -n +LDFLAGS += -nostartfiles -nodefaultlibs -Wl,-gc-sections -Wl,--build-id=none -n LIBS = -lgcc # Flags to generate temporary dependency files From 875ad69aee6c770bbeb4a5f6890dca4d8d663738 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 20 Jan 2020 23:13:05 +0100 Subject: [PATCH 1491/1854] Add installation instructions for openSUSE --- .../Linux-Installation-Instructions.md | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/doc/md/Installation_Instructions/Linux-Installation-Instructions.md b/doc/md/Installation_Instructions/Linux-Installation-Instructions.md index d56d1056c..30d4fbf54 100644 --- a/doc/md/Installation_Instructions/Linux-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Linux-Installation-Instructions.md @@ -28,27 +28,33 @@ sudo apt-get install --no-install-recommends git ca-certificates build-essential libreadline-dev gcc-arm-none-eabi libnewlib-dev qtbase5-dev ``` -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 the graphical components of the Proxmark3 client (such as in `hw tune`), you can skip the installation of `qtbase5-dev`. If you get some (non blocking) error at runtime such as _Gtk-Message: Failed to load module "canberra-gtk-module"_ you may have to install `libcanberra-gtk-module`. ## On ArchLinux ```sh -sudo pacman -Sy base-devel readline arm-none-eabi-gcc arm-none-eabi-newlib git --needed -``` -If you want graphical output (such as in `hw tune`): -```sh -sudo pacman -Su qt5-base +sudo pacman -Sy git base-devel readline arm-none-eabi-gcc arm-none-eabi-newlib qt5-base --needed ``` +If you don't need the graphical components of the Proxmark3 client (such as in `hw tune`), you can skip the installation of `qt5-base`. + ## On Fedora ```sh sudo dnf install git make gcc gcc-c++ arm-none-eabi-gcc-cs arm-none-eabi-newlib readline-devel qt5-qtbase-devel libatomic ``` -If you don't need the graphical components of the Proxmark3 client, you can skip the installation of `qt5-qtbase-devel`. +If you don't need the graphical components of the Proxmark3 client (such as in `hw tune`), you can skip the installation of `qt5-qtbase-devel`. + +## On openSUSE + +```sh +sudo zypper install git patterns-devel-base-devel_basis gcc-c++ readline-devel cross-arm-none-gcc9 cross-arm-none-newlib-devel +``` + +If you don't need the graphical components of the Proxmark3 client (such as in `hw tune`), you can skip the installation of `libqt5-qtbase-devel`. # Clone the RRG/Iceman repository From 06e7777deb11e7c45a51797eb8022a12e471896a Mon Sep 17 00:00:00 2001 From: Iceman Date: Tue, 21 Jan 2020 14:56:22 +0100 Subject: [PATCH 1492/1854] Update mfu_magic.lua wrong define used. --- client/luascripts/mfu_magic.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/luascripts/mfu_magic.lua b/client/luascripts/mfu_magic.lua index d8eff1f40..badc691c5 100644 --- a/client/luascripts/mfu_magic.lua +++ b/client/luascripts/mfu_magic.lua @@ -11,7 +11,7 @@ local err_lock = 'use -k or change cfg0 block' copyright = 'Copyright (c) 2017 IceSQL AB. All rights reserved.' author = 'Christian Herrmann' -version = 'v1.1.1' +version = 'v1.1.2' desc = 'This script enables easy programming of a MAGIC NTAG 21* card' example = [[ @@ -125,7 +125,7 @@ local function sendRaw(rawdata, options) + lib14a.ISO14A_COMMAND.ISO14A_RAW + lib14a.ISO14A_COMMAND.ISO14A_APPEND_CRC - local c = Command:newMIX{cmd = cmds.CMD_READER_ISO_14443a, + local c = Command:newMIX{cmd = cmds.CMD_HF_ISO14443A_READER, arg1 = flags, -- arg2 contains the length, which is half the length of the ASCII-string rawdata arg2 = string.len(rawdata)/2, From 15b4b198b02cc4a9b06071e9a99a397f3e93ac96 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 21 Jan 2020 15:22:36 +0100 Subject: [PATCH 1493/1854] chg: 'lf search' - now always check for HITAG --- client/cmdlf.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/client/cmdlf.c b/client/cmdlf.c index 3fee78735..617d87c0e 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -1213,17 +1213,18 @@ int CmdLFfind(const char *Cmd) { // only run these tests if device is online if (isOnline) { + + if (IfPm3Hitag()) { + if (readHitagUid()) { + PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Hitag") "found!"); + return PM3_SUCCESS; + } + } + // only run if graphbuffer is just noise as it should be for hitag // The improved noise detection will find Cotag. if (getSignalProperties()->isnoise) { - if (IfPm3Hitag()) { - if (readHitagUid()) { - PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Hitag") "found!"); - return PM3_SUCCESS; - } - } - if (readMotorolaUid()) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Motorola FlexPass ID") "found!"); return PM3_SUCCESS; From 5a33dca1a3399b288f35bca2de3c67e439f11144 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 21 Jan 2020 15:25:40 +0100 Subject: [PATCH 1494/1854] chg: spiffs load - broke out load --- client/cmdflashmemspiffs.c | 129 ++++++++++++++++++++----------------- client/cmdflashmemspiffs.h | 1 + 2 files changed, 70 insertions(+), 60 deletions(-) diff --git a/client/cmdflashmemspiffs.c b/client/cmdflashmemspiffs.c index 492fc0bcc..5d003bd2c 100644 --- a/client/cmdflashmemspiffs.c +++ b/client/cmdflashmemspiffs.c @@ -314,11 +314,69 @@ static int CmdFlashMemSpiFFSDump(const char *Cmd) { return PM3_SUCCESS; } +int flashmem_spiffs_load(uint8_t *destfn, uint8_t *data, size_t datalen) { + + int ret_val = PM3_SUCCESS; + + // We want to mount before multiple operation so the lazy writes/append will not + // trigger a mount + umount each loop iteration (lazy ops device side) + SendCommandNG(CMD_SPIFFS_MOUNT, NULL, 0); + + // Send to device + uint32_t bytes_sent = 0; + uint32_t bytes_remaining = datalen; + uint32_t append = 0; + + // fast push mode + conn.block_after_ACK = true; + + while (bytes_remaining > 0) { + uint32_t bytes_in_packet = MIN(FLASH_MEM_BLOCK_SIZE, bytes_remaining); + + clearCommandBuffer(); + + char fdata[32 + bytes_in_packet]; + memset(fdata, 0, sizeof(fdata)); + memcpy(fdata, destfn, 32); + memcpy(fdata + 32, data + bytes_sent, bytes_in_packet); + + if (bytes_sent > 0) + append = 1; + + SendCommandOLD(CMD_SPIFFS_WRITE, append, bytes_in_packet, 0, fdata, 32 + bytes_in_packet); + + bytes_remaining -= bytes_in_packet; + bytes_sent += bytes_in_packet; + + PacketResponseNG resp; + if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { + PrintAndLogEx(WARNING, "timeout while waiting for reply."); + ret_val = PM3_ETIMEOUT; + break; + } + + uint8_t isok = resp.oldarg[0] & 0xFF; + if (!isok) { + PrintAndLogEx(FAILED, "Flash write fail [offset %u]", bytes_sent); + ret_val = PM3_EFLASH; + break; + } + } + + // turn off fast push mode + conn.block_after_ACK = false; + + // We want to unmount after these to set things back to normal but more than this + // unmouting ensure that SPIFFS CACHES are all flushed so our file is actually written on memory + SendCommandNG(CMD_SPIFFS_UNMOUNT, NULL, 0); + + return ret_val; +} + static int CmdFlashMemSpiFFSLoad(const char *Cmd) { - uint32_t append = 0; char filename[FILE_PATH_SIZE] = {0}; - char destfilename[32] = {0}; + uint8_t destfilename[32] = {0}; bool errors = false; uint8_t cmdp = 0; @@ -334,8 +392,8 @@ static int CmdFlashMemSpiFFSLoad(const char *Cmd) { cmdp += 2; break; case 'o': - param_getstr(Cmd, cmdp + 1, destfilename, 32); - if (strlen(destfilename) == 0) { + param_getstr(Cmd, cmdp + 1, (char*)destfilename, 32); + if (strlen((char*)destfilename) == 0) { PrintAndLogEx(FAILED, "Destination Filename missing or invalid"); errors = true; } @@ -362,63 +420,14 @@ static int CmdFlashMemSpiFFSLoad(const char *Cmd) { return PM3_EFILE; } - // We want to mount before multiple operation so the lazy writes/append will not - // trigger a mount + umount each loop iteration (lazy ops device side) - SendCommandNG(CMD_SPIFFS_MOUNT, NULL, 0); - - // Send to device - uint32_t bytes_sent = 0; - uint32_t bytes_remaining = datalen; - - // fast push mode - conn.block_after_ACK = true; - - // SendCommandMIX(CMD_SPIFFS_COPY, 0, 0, 0, (uint8_t *)data, 65); - - while (bytes_remaining > 0) { - uint32_t bytes_in_packet = MIN(FLASH_MEM_BLOCK_SIZE, bytes_remaining); - - clearCommandBuffer(); - - char fdata[32 + bytes_in_packet]; - memset(fdata, 0, sizeof(fdata)); - memcpy(fdata, destfilename, 32); - memcpy(fdata + 32, data + bytes_sent, bytes_in_packet); - // sprintf(fdata, "%s%s", destfilename, data + bytes_sent); - - if (bytes_sent > 0) - append = 1; - - SendCommandOLD(CMD_SPIFFS_WRITE, append, bytes_in_packet, 0, fdata, 32 + bytes_in_packet); - - bytes_remaining -= bytes_in_packet; - bytes_sent += bytes_in_packet; - - PacketResponseNG resp; - if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { - PrintAndLogEx(WARNING, "timeout while waiting for reply."); - conn.block_after_ACK = false; - free(data); - return PM3_ETIMEOUT; - } - - uint8_t isok = resp.oldarg[0] & 0xFF; - if (!isok) { - conn.block_after_ACK = false; - PrintAndLogEx(FAILED, "Flash write fail [offset %u]", bytes_sent); - free(data); - return PM3_EFLASH; - } - } - - conn.block_after_ACK = false; + res = flashmem_spiffs_load(destfilename, data, datalen); + free(data); - PrintAndLogEx(SUCCESS, "Wrote "_GREEN_("%zu") "bytes to file "_GREEN_("%s"), datalen, destfilename); - - // We want to unmount after these to set things back to normal but more than this - // unmouting ensure that SPIFFS CACHES are all flushed so our file is actually written on memory - SendCommandNG(CMD_SPIFFS_UNMOUNT, NULL, 0); - return PM3_SUCCESS; + + if ( res == PM3_SUCCESS ) + PrintAndLogEx(SUCCESS, "Wrote "_GREEN_("%zu") "bytes to file "_GREEN_("%s"), datalen, destfilename); + + return res; } static command_t CommandTable[] = { diff --git a/client/cmdflashmemspiffs.h b/client/cmdflashmemspiffs.h index d2dee17ab..9324a541b 100644 --- a/client/cmdflashmemspiffs.h +++ b/client/cmdflashmemspiffs.h @@ -14,5 +14,6 @@ #include "common.h" int CmdFlashMemSpiFFS(const char *Cmd); +int flashmem_spiffs_load(uint8_t *destfn, uint8_t *data, size_t datalen); #endif From 35131a52c9d1e0d6664786115206ce4db82c8c11 Mon Sep 17 00:00:00 2001 From: Thomas Sutter Date: Tue, 21 Jan 2020 18:07:18 +0100 Subject: [PATCH 1495/1854] Fix FeliCa Light Dump function --- armsrc/felica.c | 19 ++++++++----------- client/cmdhffelica.c | 21 ++++++++++----------- 2 files changed, 18 insertions(+), 22 deletions(-) diff --git a/armsrc/felica.c b/armsrc/felica.c index d42640532..b1e0253a2 100644 --- a/armsrc/felica.c +++ b/armsrc/felica.c @@ -26,9 +26,7 @@ #ifndef DELAY_ARM2AIR_AS_READER #define DELAY_ARM2AIR_AS_READER (4*16 + 8*16 + 8 + 8 + 1) // 209 #endif - -// CRC skips two first sync bits in data buffer -#define AddCrc(data, len) compute_crc(CRC_FELICA, (data)+2, (len),(data)+(len)+2, (data)+(len)+3) +#define AddCrc(data, len) compute_crc(CRC_FELICA, (data), (len), (data)+(len)+1, (data)+(len)) static uint32_t felica_timeout; static uint32_t felica_nexttransfertime; @@ -285,12 +283,12 @@ static uint8_t felica_select_card(felica_card_select_t *card) { // 8-byte IDm, number of blocks, blocks numbers // number of blocks limited to 4 for FelicaLite(S) static void BuildFliteRdblk(uint8_t *idm, int blocknum, uint16_t *blocks) { - if (blocknum > 4 || blocknum <= 0) Dbprintf("Invalid number of blocks, %d != 4", blocknum); uint8_t c = 0, i = 0; + // Sync bytes frameSpace[c++] = 0xb2; frameSpace[c++] = 0x4d; @@ -333,7 +331,8 @@ static void BuildFliteRdblk(uint8_t *idm, int blocknum, uint16_t *blocks) { //set length frameSpace[2] = c - 2; - AddCrc(frameSpace, c - 2); + //Add CRC + AddCrc(frameSpace + 2, c - 2); } static void TransmitFor18092_AsReader(uint8_t *frame, int len, uint32_t *timing, uint8_t power, uint8_t highspeed) { @@ -753,28 +752,26 @@ void felica_dump_lite_s() { uint8_t *dest = BigBuf_get_addr(); while (!BUTTON_PRESS() && !data_available()) { - WDT_HIT(); - // polling? //TransmitFor18092_AsReader(poll, 10, GetCountSspClk()+512, 1, 0); TransmitFor18092_AsReader(poll, 10, NULL, 1, 0); if (WaitForFelicaReply(512) && FelicaFrame.framebytes[3] == FELICA_POLL_ACK) { - // copy 8bytes to ndef. memcpy(ndef, FelicaFrame.framebytes + 4, 8); // for (c=0; c < 8; c++) // ndef[c] = FelicaFrame.framebytes[c+4]; for (blknum = 0; blknum < ARRAYLEN(liteblks);) { - // block to read. BuildFliteRdblk(ndef, 1, &liteblks[blknum]); //TransmitFor18092_AsReader(frameSpace, frameSpace[2]+4, GetCountSspClk()+512, 1, 0); - TransmitFor18092_AsReader(frameSpace, frameSpace[2] + 4, NULL, 1, 0); + + + TransmitFor18092_AsReader(frameSpace, frameSpace[2] + 4, NULL, 1, 0); // read block if (WaitForFelicaReply(1024) && FelicaFrame.framebytes[3] == FELICA_RDBLK_ACK) { @@ -803,11 +800,11 @@ void felica_dump_lite_s() { } } } + isOK = true; break; } } - switch_off(); //Resetting Frame mode (First set in fpgaloader.c) diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index 94f5c2ca4..84339a05c 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -585,7 +585,7 @@ static int CmdHFFelicaAuthentication1(const char *Cmd) { return usage_hf_felica_authentication1(); } - PrintAndLogEx(INFO, "EXPERIMENTAL COMMAND"); + PrintAndLogEx(INFO, "INCOMPLETE / EXPERIMENTAL COMMAND!!!"); uint8_t data[PM3_CMD_DATA_SIZE]; bool custom_IDm = false; strip_cmds(Cmd); @@ -731,6 +731,7 @@ static int CmdHFFelicaAuthentication2(const char *Cmd) { if (strlen(Cmd) < 2) { return usage_hf_felica_authentication2(); } + PrintAndLogEx(INFO, "INCOMPLETE / EXPERIMENTAL COMMAND!!!"); PrintAndLogEx(INFO, "EXPERIMENTAL COMMAND - M2c/P2c will be not checked"); uint8_t data[PM3_CMD_DATA_SIZE]; bool custom_IDm = false; @@ -978,7 +979,7 @@ static int CmdHFFelicaReadWithoutEncryption(const char *Cmd) { if (long_block_numbers) { last_block_number = 0xFFFF; } - PrintAndLogEx(INFO, "Block Element\t| Data "); + PrintAndLogEx(INFO, "Block Nr.\t| Data "); for (i = 0x00; i < last_block_number; i++) { data[15] = i; AddCrc(data, datalen); @@ -987,8 +988,6 @@ static int CmdHFFelicaReadWithoutEncryption(const char *Cmd) { if ((send_rd_unencrypted(flags, datalen, data, 0, &rd_noCry_resp) == PM3_SUCCESS)) { if (rd_noCry_resp.status_flags.status_flag1[0] == 00 && rd_noCry_resp.status_flags.status_flag2[0] == 00) { print_rd_noEncrpytion_response(&rd_noCry_resp); - } else { - break; } } else { break; @@ -1000,7 +999,7 @@ static int CmdHFFelicaReadWithoutEncryption(const char *Cmd) { datalen += 2; felica_read_without_encryption_response_t rd_noCry_resp; if (send_rd_unencrypted(flags, datalen, data, 1, &rd_noCry_resp) == PM3_SUCCESS) { - PrintAndLogEx(INFO, "Block Element\t| Data "); + PrintAndLogEx(INFO, "Block Nr.\t| Data "); print_rd_noEncrpytion_response(&rd_noCry_resp); } } @@ -1854,17 +1853,17 @@ static command_t CommandTable[] = { {"reader", CmdHFFelicaReader, IfPm3Felica, "Act like an ISO18092/FeliCa reader"}, {"sniff", CmdHFFelicaSniff, IfPm3Felica, "Sniff ISO 18092/FeliCa traffic"}, {"raw", CmdHFFelicaCmdRaw, IfPm3Felica, "Send raw hex data to tag"}, - {"----------- FeliCa Standard (support in progress) -----------", CmdHelp, IfPm3Iso14443a, ""}, + {"rdunencrypted", CmdHFFelicaReadWithoutEncryption, IfPm3Felica, "read Block Data from authentication-not-required Service."}, + {"wrunencrypted", CmdHFFelicaWriteWithoutEncryption, IfPm3Felica, "write Block Data to an authentication-not-required Service."}, + {"----------- FeliCa Standard -----------", CmdHelp, IfPm3Iso14443a, ""}, //{"dump", CmdHFFelicaDump, IfPm3Felica, "Wait for and try dumping FeliCa"}, {"rqservice", CmdHFFelicaRequestService, IfPm3Felica, "verify the existence of Area and Service, and to acquire Key Version."}, {"rqresponse", CmdHFFelicaRequestResponse, IfPm3Felica, "verify the existence of a card and its Mode."}, - {"rdunencrypted", CmdHFFelicaReadWithoutEncryption, IfPm3Felica, "read Block Data from authentication-not-required Service."}, - {"wrunencrypted", CmdHFFelicaWriteWithoutEncryption, IfPm3Felica, "write Block Data to an authentication-not-required Service."}, {"scsvcode", CmdHFFelicaNotImplementedYet, IfPm3Felica, "acquire Area Code and Service Code."}, {"rqsyscode", CmdHFFelicaRequestSystemCode, IfPm3Felica, "acquire System Code registered to the card."}, - {"auth1", CmdHFFelicaAuthentication1, IfPm3Felica, "authenticate a card. Start mutual authentication with Auth1"}, - {"auth2", CmdHFFelicaAuthentication2, IfPm3Felica, "allow a card to authenticate a Reader/Writer. Complete mutual authentication"}, - {"read", CmdHFFelicaNotImplementedYet, IfPm3Felica, "read Block Data from authentication-required Service."}, + {"auth1", CmdHFFelicaAuthentication1, IfPm3Felica, "authenticate a card. Start mutual authentication with Auth1"}, + {"auth2", CmdHFFelicaAuthentication2, IfPm3Felica, "allow a card to authenticate a Reader/Writer. Complete mutual authentication"}, + //{"read", CmdHFFelicaNotImplementedYet, IfPm3Felica, "read Block Data from authentication-required Service."}, //{"write", CmdHFFelicaNotImplementedYet, IfPm3Felica, "write Block Data to an authentication-required Service."}, //{"scsvcodev2", CmdHFFelicaNotImplementedYet, IfPm3Felica, "verify the existence of Area or Service, and to acquire Key Version."}, //{"getsysstatus", CmdHFFelicaNotImplementedYet, IfPm3Felica, "acquire the setup information in System."}, From f4b3488a093551ef9a78ecbbe97ea79d294685b0 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 22 Jan 2020 13:11:20 +0100 Subject: [PATCH 1496/1854] chg: 'hf mf static' - now uses file on spiffs for key transfers. speedup on RDV4 --- armsrc/appmain.c | 14 +++- armsrc/mifarecmd.c | 29 ++++++++- armsrc/mifarecmd.h | 1 + client/cmdflashmemspiffs.c | 14 +++- client/mifare/mifarehost.c | 127 +++++++++++++++++++++++++++++-------- client/mifare/mifarehost.h | 3 + include/pm3_cmd.h | 1 + 7 files changed, 153 insertions(+), 36 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index ab0320e75..7c58fd7e6 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -930,12 +930,12 @@ static void PacketReceived(PacketCommandNG *packet) { #ifdef WITH_HITAG case CMD_LF_HITAG_SNIFF: { // Eavesdrop Hitag tag, args = type - SniffHitag(); -// SniffHitag(packet->oldarg[0]); + SniffHitag2(); +// SniffHitag2(packet->oldarg[0]); break; } case CMD_LF_HITAG_SIMULATE: { // Simulate Hitag tag, args = memory content - SimulateHitagTag((bool)packet->oldarg[0], packet->data.asBytes); + SimulateHitag2((bool)packet->oldarg[0], packet->data.asBytes); break; } case CMD_LF_HITAG_READER: { // Reader for Hitag tags, args = type and function @@ -1176,6 +1176,14 @@ static void PacketReceived(PacketCommandNG *packet) { MifareChkKeys_fast(packet->oldarg[0], packet->oldarg[1], packet->oldarg[2], packet->data.asBytes); break; } + case CMD_HF_MIFARE_CHKKEYS_FILE: { + struct p { + uint8_t filename[32]; + } PACKED; + struct p *payload = (struct p *) packet->data.asBytes; + MifareChkKeys_file(payload->filename); + break; + } case CMD_HF_MIFARE_SIMULATE: { struct p { uint16_t flags; diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index a0ce705be..cf1115f21 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -33,6 +33,7 @@ #include "dbprint.h" #include "ticks.h" #include "usb_cdc.h" // usb_poll_validate_length +#include "spiffs.h" // spiffs #ifndef HARDNESTED_AUTHENTICATION_TIMEOUT # define HARDNESTED_AUTHENTICATION_TIMEOUT 848 // card times out 1ms after wrong authentication (according to NXP documentation) @@ -1701,14 +1702,15 @@ void MifareChkKeys(uint8_t *datain) { bool found; } PACKED keyresult; keyresult.found = false; - uint8_t blockNo, keyType, keyCount; + uint8_t blockNo, keyType; + uint16_t keyCount; bool clearTrace, have_uid = false; keyType = datain[0]; blockNo = datain[1]; clearTrace = datain[2]; - keyCount = datain[3]; - datain += 4; + keyCount = (datain[3] << 8) | datain[4]; + datain += 5; LEDsoff(); LED_A_ON(); @@ -1780,6 +1782,27 @@ void MifareChkKeys(uint8_t *datain) { DBGLEVEL = oldbg; } +void MifareChkKeys_file(uint8_t *fn) { + + SpinOff(0); + + int changed = rdv40_spiffs_lazy_mount(); + uint32_t size = size_in_spiffs((char *)fn); + uint8_t *mem = BigBuf_malloc(size); + + rdv40_spiffs_read_as_filetype((char *)fn, mem, size, RDV40_SPIFFS_SAFETY_SAFE); + + if (changed) { + rdv40_spiffs_lazy_unmount(); + } + + SpinOff(0); + + MifareChkKeys(mem); + + BigBuf_free(); +} + //----------------------------------------------------------------------------- // Work with emulator memory // diff --git a/armsrc/mifarecmd.h b/armsrc/mifarecmd.h index cb60ea7c5..1f5ee63a4 100644 --- a/armsrc/mifarecmd.h +++ b/armsrc/mifarecmd.h @@ -31,6 +31,7 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, void MifareAcquireNonces(uint32_t arg0, uint32_t flags); void MifareChkKeys(uint8_t *datain); void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain); +void MifareChkKeys_file(uint8_t *fn); void MifareEMemClr(void); void MifareEMemSet(uint8_t blockno, uint8_t blockcnt, uint8_t blockwidth, uint8_t *datain); diff --git a/client/cmdflashmemspiffs.c b/client/cmdflashmemspiffs.c index 5d003bd2c..bdc51dc5d 100644 --- a/client/cmdflashmemspiffs.c +++ b/client/cmdflashmemspiffs.c @@ -349,10 +349,15 @@ int flashmem_spiffs_load(uint8_t *destfn, uint8_t *data, size_t datalen) { bytes_sent += bytes_in_packet; PacketResponseNG resp; - if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { + + uint8_t retry = 3; + while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { PrintAndLogEx(WARNING, "timeout while waiting for reply."); - ret_val = PM3_ETIMEOUT; - break; + retry--; + if (retry == 0) { + ret_val = PM3_ETIMEOUT; + goto out; + } } uint8_t isok = resp.oldarg[0] & 0xFF; @@ -363,6 +368,9 @@ int flashmem_spiffs_load(uint8_t *destfn, uint8_t *data, size_t datalen) { } } +out: + clearCommandBuffer(); + // turn off fast push mode conn.block_after_ACK = false; diff --git a/client/mifare/mifarehost.c b/client/mifare/mifarehost.c index e3021c8f6..df5b2e009 100644 --- a/client/mifare/mifarehost.c +++ b/client/mifare/mifarehost.c @@ -17,12 +17,14 @@ #include "comms.h" #include "commonutil.h" #include "mifare4.h" -#include "ui.h" // PrintAndLog... +#include "ui.h" // PrintAndLog... #include "crapto1/crapto1.h" #include "crc16.h" #include "protocols.h" #include "mfkey.h" -#include "util_posix.h" // msclock +#include "util_posix.h" // msclock +#include "cmdparser.h" // detection of flash capabilities +#include "cmdflashmemspiffs.h" // upload to flash mem int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) { uint32_t uid = 0; @@ -168,9 +170,10 @@ int mfCheckKeys(uint8_t blockNo, uint8_t keyType, bool clear_trace, uint8_t keyc data[0] = keyType; data[1] = blockNo; data[2] = clear_trace; - data[3] = keycnt; - memcpy(data + 4, keyBlock, 6 * keycnt); - SendCommandNG(CMD_HF_MIFARE_CHKKEYS, data, (4 + 6 * keycnt)); + data[3] = 0; + data[4] = keycnt; + memcpy(data + 5, keyBlock, 6 * keycnt); + SendCommandNG(CMD_HF_MIFARE_CHKKEYS, data, (5 + 6 * keycnt)); PacketResponseNG resp; if (!WaitForResponseTimeout(CMD_HF_MIFARE_CHKKEYS, &resp, 2500)) return PM3_ETIMEOUT; @@ -265,6 +268,45 @@ int mfCheckKeys_fast(uint8_t sectorsCnt, uint8_t firstChunk, uint8_t lastChunk, return PM3_ESOFT; } +// Trigger device to use a binary file on flash mem as keylist for mfCheckKeys. +// As of now, 255 keys possible in the file +// 6 * 255 = 1500 bytes +int mfCheckKeys_file(uint8_t *destfn, uint64_t *key) { + *key = -1; + clearCommandBuffer(); + + struct { + uint8_t filename[32]; + } PACKED payload_file; + + strncpy((char*)payload_file.filename, (char*)destfn, sizeof(payload_file.filename)); + + PacketResponseNG resp; + clearCommandBuffer(); + SendCommandNG(CMD_HF_MIFARE_CHKKEYS_FILE, (uint8_t *)&payload_file, sizeof(payload_file)); + + uint8_t retry = 10; + + while (!WaitForResponseTimeout(CMD_HF_MIFARE_CHKKEYS, &resp, 2000)) { + retry--; + if (retry ==0) { + PrintAndLogEx(WARNING, "Chk keys file, timeouted"); + return PM3_ETIMEOUT; + } + } + + if (resp.status != PM3_SUCCESS) return resp.status; + + struct kr { + uint8_t key[6]; + bool found; + } PACKED; + struct kr *keyresult = (struct kr *)&resp.data.asBytes; + if (!keyresult->found) return PM3_ESOFT; + *key = bytes_to_num(keyresult->key, sizeof(keyresult->key)); + return PM3_SUCCESS; +} + // PM3 imp of J-Run mf_key_brute (part 2) // ref: https://github.com/J-Run/mf_key_brute int mfKeyBrute(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint64_t *resultkey) { @@ -461,7 +503,7 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, if (keycnt == 0) goto out; PrintAndLogEx(SUCCESS, "Found " _YELLOW_("%u") "candidate keys", keycnt); - + memset(resultKey, 0, 6); uint64_t key64 = -1; @@ -469,10 +511,10 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, uint32_t max_keys = keycnt > KEYS_IN_BLOCK ? KEYS_IN_BLOCK : keycnt; uint8_t keyBlock[PM3_CMD_DATA_SIZE] = {0x00}; - uint64_t start_time = msclock(); - for (uint32_t i = 0; i < keycnt; i += max_keys) { + uint64_t start_time = msclock(); + uint8_t size = keycnt - i > max_keys ? max_keys : keycnt - i; register uint8_t j; @@ -498,7 +540,7 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, start_time = msclock(); if ( i + 1 % 10 == 0) - PrintAndLogEx(INFO, " %8d keys left | %5.1f keys/sec | worst case %6.1f seconds remaining", keycnt - i, bruteforce_per_second, (keycnt-i) / bruteforce_per_second); + PrintAndLogEx(INFO, " %8d/%u keys | %5.1f keys/sec | worst case %6.1f seconds remaining", i, keycnt , bruteforce_per_second, (keycnt-i) / bruteforce_per_second); } @@ -601,47 +643,79 @@ int mfStaticNested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBl uint64_t key64 = -1; // The list may still contain several key candidates. Test each of them with mfCheckKeys - uint32_t max_keys_slice = keycnt > KEYS_IN_BLOCK ? KEYS_IN_BLOCK : keycnt; - uint8_t keyBlock[PM3_CMD_DATA_SIZE] = {0x00}; + uint32_t maxkeysinblock = IfPm3Flash() ? 1600 : KEYS_IN_BLOCK; + uint32_t max_keys_slice = keycnt > maxkeysinblock ? maxkeysinblock : keycnt; + + uint8_t *mem = calloc( (maxkeysinblock * 6) + 5, sizeof(uint8_t)); + if (mem == NULL) { + free(statelists[0].head.slhead); + return PM3_EMALLOC; + } + + uint8_t *p_keyblock = mem + 5; + mem[0] = statelists[0].keyType; + mem[1] = statelists[0].blockNo; + mem[2] = 1; + mem[3] = ((maxkeysinblock >> 8) & 0xFF); + mem[4] = (maxkeysinblock & 0xFF); + + uint8_t destfn[32]; + strncpy((char*)destfn, "static_nested_000.bin", sizeof(destfn) - 1); - uint64_t start_time = msclock(); for (uint32_t i = 0; i < keycnt; i += max_keys_slice) { -// PrintAndLogEx(INFO, "Testing %u / %u ", i, keycnt); + int res = 0; + uint64_t start_time = msclock(); key64 = 0; - - uint8_t size = keycnt - i > max_keys_slice ? max_keys_slice : keycnt - i; + uint32_t size = keycnt - i > max_keys_slice ? max_keys_slice : keycnt - i; // copy x keys to device. - register uint8_t j; - for (j = 0; j < size; j++) { + for (uint32_t j = 0; j < size; j++) { crypto1_get_lfsr(statelists[0].head.slhead + i + j, &key64); - num_to_bytes(key64, 6, keyBlock + j * 6); + num_to_bytes(key64, 6, p_keyblock + j * 6); } // check a block of generated candidate keys. - if (mfCheckKeys(statelists[0].blockNo, statelists[0].keyType, false, size, keyBlock, &key64) == PM3_SUCCESS) { + if (IfPm3Flash()) { + // upload to flash. + res = flashmem_spiffs_load(destfn, mem, 5 + (size * 6) ); + if (res != PM3_SUCCESS) { + PrintAndLogEx(WARNING, "SPIFFS upload failed"); + return res; + } - free(statelists[0].head.slhead); + res = mfCheckKeys_file(destfn, &key64); + } else { + res = mfCheckKeys(statelists[0].blockNo, statelists[0].keyType, false, size, mem, &key64); + } - num_to_bytes(key64, 6, resultKey); + if (res == PM3_SUCCESS) { + p_keyblock = NULL; + free(statelists[0].head.slhead); + free(mem); - PrintAndLogEx(SUCCESS, "target block:%3u key type: %c -- found valid key [ " _YELLOW_("%s") "]", + num_to_bytes(key64, 6, resultKey); + + PrintAndLogEx(SUCCESS, "target block:%3u key type: %c -- found valid key [ " _YELLOW_("%s") "]", package->block, package->keytype ? 'B' : 'A', sprint_hex_inrow(resultKey, 6) ); return PM3_SUCCESS; + } else if (res == PM3_ETIMEOUT) { + return res; } - float bruteforce_per_second = (float)KEYS_IN_BLOCK / (float)(msclock() - start_time) * 1000.0; + + float bruteforce_per_second = (float)maxkeysinblock / (float)(msclock() - start_time) * 1000.0; start_time = msclock(); - if ( i+1 % 10 == 0) - PrintAndLogEx(INFO, " %8d keys left | %5.1f keys/sec | worst case %6.1f seconds remaining", keycnt - i, bruteforce_per_second, (keycnt-i) / bruteforce_per_second); - + PrintAndLogEx(INFO, "Chunk %8u/%u keys | %5.1f keys/sec | worst case %6.1f seconds remaining", i, keycnt, bruteforce_per_second, (keycnt-i) / bruteforce_per_second); } + p_keyblock = NULL; + free(mem); + out: PrintAndLogEx(SUCCESS, "target block:%3u key type: %c", package->block, @@ -649,7 +723,6 @@ out: ); free(statelists[0].head.slhead); - return PM3_ESOFT; } diff --git a/client/mifare/mifarehost.h b/client/mifare/mifarehost.h index 846ee4222..6f179c573 100644 --- a/client/mifare/mifarehost.h +++ b/client/mifare/mifarehost.h @@ -65,6 +65,9 @@ int mfStaticNested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBl int mfCheckKeys(uint8_t blockNo, uint8_t keyType, bool clear_trace, uint8_t keycnt, uint8_t *keyBlock, uint64_t *key); int mfCheckKeys_fast(uint8_t sectorsCnt, uint8_t firstChunk, uint8_t lastChunk, uint8_t strategy, uint32_t size, uint8_t *keyBlock, sector_t *e_sector, bool use_flashmemory); + +int mfCheckKeys_file(uint8_t *destfn, uint64_t *key); + int mfKeyBrute(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint64_t *resultkey); int mfReadSector(uint8_t sectorNo, uint8_t keyType, uint8_t *key, uint8_t *data); diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 7ae6f0779..32b2ba35c 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -500,6 +500,7 @@ typedef struct { #define CMD_HF_MIFARE_CHKKEYS 0x0623 #define CMD_HF_MIFARE_SETMOD 0x0624 #define CMD_HF_MIFARE_CHKKEYS_FAST 0x0625 +#define CMD_HF_MIFARE_CHKKEYS_FILE 0x0626 #define CMD_HF_MIFARE_SNIFF 0x0630 #define CMD_HF_MIFARE_MFKEY 0x0631 From fc2e11a6cdbc17dc733186ae1df291415f5c9384 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 22 Jan 2020 13:12:09 +0100 Subject: [PATCH 1497/1854] rename function --- armsrc/hitag2.c | 32 +++++++++++++++++++++----------- armsrc/hitag2.h | 4 ++-- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index 6efe5808d..3da970a24 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -35,6 +35,12 @@ #include "lfdemod.h" #include "commonutil.h" + +#define test_bit(data, i) (*(data + (i/8)) >> (7-(i % 8))) & 1 +#define set_bit(data, i) *(data + (i/8)) |= (1 << (7-(i % 8))) +#define clear_bit(data, i) *(data + (i/8)) &= ~(1 << (7-(i % 8))) +#define flip_bit(data, i) *(data + (i/8)) ^= (1 << (7-(i % 8))) + // Successful crypto auth static bool bCrypto; // Is in auth stage @@ -70,7 +76,6 @@ static enum { WRITE_STATE_PROG } writestate; - // ToDo: define a meaningful maximum size for auth_table. The bigger this is, the lower will be the available memory for traces. // Historically it used to be FREE_BUFFER_SIZE, which was 2744. #define AUTH_TABLE_LENGTH 2744 @@ -87,6 +92,11 @@ uint8_t nonce[4]; bool key_no; static uint64_t cipher_state; +size_t blocknr; +size_t flipped_bit = 0; +uint32_t byte_value = 0; + + static int hitag2_reset(void) { tag.state = TAG_STATE_RESET; tag.crypto_active = 0; @@ -135,10 +145,12 @@ static int hitag2_init(void) { static void hitag_send_bit(int bit) { LED_A_ON(); + // Reset clock for the next bit AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; // Fixed modulation, earlier proxmark version used inverted signal + // check datasheet if reader uses BiPhase? if (bit == 0) { // Manchester: Unloaded, then loaded |__--| LOW(GPIO_SSC_DOUT); @@ -351,8 +363,6 @@ static uint32_t hitag_reader_send_frame(const uint8_t *frame, size_t frame_len) return wait; } -size_t blocknr; - uint8_t hitag_crc(uint8_t *data, size_t length) { uint8_t crc = 0xff; unsigned int byte, bit; @@ -371,10 +381,7 @@ uint8_t hitag_crc(uint8_t *data, size_t length) { return crc; } -#define test_bit(data, i) (*(data+(i/8)) >> (7-(i%8))) & 1 -#define set_bit(data, i) *(data+(i/8)) |= (1 << (7-(i%8))) -#define clear_bit(data, i) *(data+(i/8)) &= ~(1 << (7-(i%8))) -#define flip_bit(data, i) *(data+(i/8)) ^= (1 << (7-(i%8))) +/* void fix_ac_decoding(uint8_t *input, size_t len) { // Reader routine tries to decode AC data after Manchester decoding // AC has double the bitrate, extract data from bit-pairs @@ -388,7 +395,12 @@ void fix_ac_decoding(uint8_t *input, size_t len) { } memcpy(input, temp, sizeof(temp)); } +*/ + +// looks at number of received bits. +// 0 = collision? +// 32 = good response bool hitag_plain(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t *txlen, bool hitag_s) { uint8_t crc; *txlen = 0; @@ -457,9 +469,7 @@ bool hitag_plain(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t *txlen, bo return true; } -size_t flipped_bit = 0; -uint32_t byte_value = 0; bool hitag1_authenticate(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t *txlen) { uint8_t crc; *txlen = 0; @@ -958,7 +968,7 @@ static bool hitag2_read_uid(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t } // Hitag2 Sniffing -void SniffHitag(void) { +void SniffHitag2(void) { LEDsoff(); StopTicks(); @@ -1037,7 +1047,7 @@ void SniffHitag(void) { } // Hitag2 simulation -void SimulateHitagTag(bool tag_mem_supplied, uint8_t *data) { +void SimulateHitag2(bool tag_mem_supplied, uint8_t *data) { StopTicks(); diff --git a/armsrc/hitag2.h b/armsrc/hitag2.h index 9e0fb84e6..ec3d0d7f3 100644 --- a/armsrc/hitag2.h +++ b/armsrc/hitag2.h @@ -14,8 +14,8 @@ #include "common.h" #include "hitag.h" -void SniffHitag(void); -void SimulateHitagTag(bool tag_mem_supplied, uint8_t *data); +void SniffHitag2(void); +void SimulateHitag2(bool tag_mem_supplied, uint8_t *data); void ReaderHitag(hitag_function htf, hitag_data *htd); void WriterHitag(hitag_function htf, hitag_data *htd, int page); From e0cd9c38da792a2c66dfc4e632e6fa7e54aa7051 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 22 Jan 2020 13:13:04 +0100 Subject: [PATCH 1498/1854] test: hitag to use decimation on sample to save space --- armsrc/lfadc.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/armsrc/lfadc.c b/armsrc/lfadc.c index 3e15fdc0b..5c5b87fc0 100644 --- a/armsrc/lfadc.c +++ b/armsrc/lfadc.c @@ -188,6 +188,9 @@ void lf_init(bool reader) { if (logging) initSampleBuffer(&bufsize); + sample_config *sc = getSamplingConfig(); + sc->decimation = 2; + sc->averaging = 1; } void lf_finalize() { @@ -202,6 +205,10 @@ void lf_finalize() { FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); + + sample_config *sc = getSamplingConfig(); + sc->decimation = 1; + sc->averaging = 0; } size_t lf_detect_field_drop(size_t max) { From 3fe4582e283bc8ccce70dbded28929cfa0cf6b3e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 22 Jan 2020 13:13:45 +0100 Subject: [PATCH 1499/1854] chg: hitag dump should be in its own command --- client/cmdlfhitag.c | 58 ++++++++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/client/cmdlfhitag.c b/client/cmdlfhitag.c index f0a8037dc..810c0e7b3 100644 --- a/client/cmdlfhitag.c +++ b/client/cmdlfhitag.c @@ -563,25 +563,11 @@ static int CmdLFHitagReader(const char *Cmd) { } uint32_t id = bytes_to_num(resp.data.asBytes, 4); - + uint8_t *data = NULL; PrintAndLogEx(SUCCESS, " UID: " _YELLOW_("%08x"), id); if (htf != RHT2F_UID_ONLY) { - - PrintAndLogEx(SUCCESS, "Dumping tag memory..."); - uint8_t *data = resp.data.asBytes; - - char filename[FILE_PATH_SIZE]; - char *fnameptr = filename; - fnameptr += sprintf(fnameptr, "lf-hitag-"); - FillFileNameByUID(fnameptr, data, "-dump", 4); - - - - saveFile(filename, ".bin", data, 48); - saveFileEML(filename, data, 48, 4); - saveFileJSON(filename, jsfHitag, data, 48); - + // block3, 1 byte printHitagConfiguration(data[4 * 3]); } @@ -688,16 +674,29 @@ static int CmdLFHitagWriter(const char *Cmd) { return PM3_SUCCESS; } -/* -static int CmdLFHitagDump(const char *Cmd) { +static int CmdLFHitag2Dump(const char *Cmd) { PrintAndLogEx(INFO, "Dumping of tag memory"); - PrintAndLogEx(INFO, "To be done!"); char ctmp = tolower(param_getchar(Cmd, 0)); - if (ctmp == 'h') return usage_hitag_dump(); + if (ctmp == 'h') return 0; // usage_hitag_dump(); + + PacketResponseNG resp; + + PrintAndLogEx(SUCCESS, "Dumping tag memory..."); + uint8_t *data = resp.data.asBytes; + + char filename[FILE_PATH_SIZE]; + char *fnameptr = filename; + fnameptr += sprintf(fnameptr, "lf-hitag-"); + FillFileNameByUID(fnameptr, data, "-dump", 4); + + saveFile(filename, ".bin", data, 48); + saveFileEML(filename, data, 48, 4); + saveFileJSON(filename, jsfHitag, data, 48); + return PM3_SUCCESS; } -*/ + // Annotate HITAG protocol void annotateHitag1(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) { @@ -740,14 +739,15 @@ void annotateHitagS(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) { } static command_t CommandTable[] = { - {"help", CmdHelp, AlwaysAvailable, "This help" }, - {"list", CmdLFHitagList, IfPm3Hitag, "List Hitag trace history" }, - {"info", CmdLFHitagInfo, IfPm3Hitag, "Tag information" }, - {"reader", CmdLFHitagReader, IfPm3Hitag, "Act like a Hitag Reader" }, - {"sim", CmdLFHitagSim, IfPm3Hitag, "Simulate Hitag transponder" }, - {"sniff", CmdLFHitagSniff, IfPm3Hitag, "Eavesdrop Hitag communication" }, - {"writer", CmdLFHitagWriter, IfPm3Hitag, "Act like a Hitag Writer" }, - {"cc", CmdLFHitagCheckChallenges, IfPm3Hitag, "Test all challenges" }, + {"help", CmdHelp, AlwaysAvailable, "This help" }, + {"list", CmdLFHitagList, IfPm3Hitag, "List Hitag trace history" }, + {"info", CmdLFHitagInfo, IfPm3Hitag, "Tag information" }, + {"reader", CmdLFHitagReader, IfPm3Hitag, "Act like a Hitag Reader" }, + {"sim", CmdLFHitagSim, IfPm3Hitag, "Simulate Hitag transponder" }, + {"sniff", CmdLFHitagSniff, IfPm3Hitag, "Eavesdrop Hitag communication" }, + {"writer", CmdLFHitagWriter, IfPm3Hitag, "Act like a Hitag Writer" }, + {"dump", CmdLFHitag2Dump, IfPm3Hitag, "Dump Hitag2 tag" }, + {"cc", CmdLFHitagCheckChallenges, IfPm3Hitag, "Test all challenges" }, { NULL, NULL, 0, NULL } }; From e5fbfef59b40687d47ab9aa775ae42ed0e7e0f9e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 22 Jan 2020 17:38:05 +0100 Subject: [PATCH 1500/1854] fix #533 --- client/mifare/mifarehost.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/mifare/mifarehost.c b/client/mifare/mifarehost.c index df5b2e009..3586db8df 100644 --- a/client/mifare/mifarehost.c +++ b/client/mifare/mifarehost.c @@ -279,7 +279,7 @@ int mfCheckKeys_file(uint8_t *destfn, uint64_t *key) { uint8_t filename[32]; } PACKED payload_file; - strncpy((char*)payload_file.filename, (char*)destfn, sizeof(payload_file.filename)); + memcpy(payload_file.filename, destfn, sizeof(payload_file.filename) - 1); PacketResponseNG resp; clearCommandBuffer(); From 5cd5f6dd8f7f6e33bafa342407cd490c455b8934 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 22 Jan 2020 17:39:51 +0100 Subject: [PATCH 1501/1854] one more level --- Makefile.host | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile.host b/Makefile.host index bfadd82b7..6d405ee14 100644 --- a/Makefile.host +++ b/Makefile.host @@ -8,6 +8,9 @@ endif ifeq ($(DEFSBEENHERE),) -include ../../Makefile.defs endif +ifeq ($(DEFSBEENHERE),) + -include ../../../Makefile.defs +endif ifeq ($(DEFSBEENHERE),) $(error Can't find Makefile.defs) endif From 48f7b3bdb690ff5612d634c448df4b376a306936 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 22 Jan 2020 17:41:59 +0100 Subject: [PATCH 1502/1854] same param names --- armsrc/lfsampling.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index 2d92cd692..0679eb368 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -200,7 +200,7 @@ void logSample(uint8_t sample, uint8_t decimation, uint8_t bits_per_sample, bool * 0 or 95 ==> 125 kHz * **/ -void LFSetupFPGAForADC(int divisor, bool lf_field) { +void LFSetupFPGAForADC(int divisor, bool reader_field) { FpgaDownloadAndGo(FPGA_BITSTREAM_LF); if ((divisor == 1) || (divisor < 0) || (divisor > 255)) FpgaSendCommand(FPGA_CMD_SET_DIVISOR, LF_DIVISOR_134); //~134kHz @@ -209,14 +209,17 @@ void LFSetupFPGAForADC(int divisor, bool lf_field) { else FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor); - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | (lf_field ? FPGA_LF_ADC_READER_FIELD : 0)); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | (reader_field ? FPGA_LF_ADC_READER_FIELD : 0)); // Connect the A/D to the peak-detected low-frequency path. SetAdcMuxFor(GPIO_MUXSEL_LOPKD); // 50ms for the resonant antenna to settle. + if (reader_field) SpinDelay(50); + // Now set up the SSC to get the ADC samples that are now streaming at us. FpgaSetupSsc(); + // start a 1.5ticks is 1us StartTicks(); } @@ -333,11 +336,11 @@ uint32_t DoPartialAcquisition(int trigger_threshold, bool verbose, uint32_t samp return DoAcquisition(1, 8, 0, trigger_threshold, verbose, sample_size, cancel_after, 0); } -uint32_t ReadLF(bool activeField, bool verbose, uint32_t sample_size) { +uint32_t ReadLF(bool reader_field, bool verbose, uint32_t sample_size) { if (verbose) printConfig(); - LFSetupFPGAForADC(config.divisor, activeField); + LFSetupFPGAForADC(config.divisor, reader_field); uint32_t ret = DoAcquisition_config(verbose, sample_size); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); return ret; From fc1cede77896be2d432c85e430e6bc9a0160938c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 22 Jan 2020 18:43:20 +0100 Subject: [PATCH 1503/1854] fix: #536 --- armsrc/hitag2.c | 6 +++++- client/cmdlfhitag.c | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index 3da970a24..770c63544 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -1288,7 +1288,11 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { break; case RHT2F_PASSWORD: { Dbprintf("List identifier in password mode"); - memcpy(password, htd->pwd.password, 4); + if (memcmp(htd->pwd.password, "\x00\x00\x00\x00", 4) == 0) + memcpy(password, tag.sectors[1], sizeof(password)); + else + memcpy(password, htd->pwd.password, sizeof(password)); + blocknr = 0; bPwd = false; bAuthenticating = false; diff --git a/client/cmdlfhitag.c b/client/cmdlfhitag.c index 810c0e7b3..4d699541e 100644 --- a/client/cmdlfhitag.c +++ b/client/cmdlfhitag.c @@ -563,7 +563,7 @@ static int CmdLFHitagReader(const char *Cmd) { } uint32_t id = bytes_to_num(resp.data.asBytes, 4); - uint8_t *data = NULL; + uint8_t *data = resp.data.asBytes; PrintAndLogEx(SUCCESS, " UID: " _YELLOW_("%08x"), id); if (htf != RHT2F_UID_ONLY) { From 66803e442d3cedbb5c128e486904720759c12ec1 Mon Sep 17 00:00:00 2001 From: Kevin-Nakamoto Date: Wed, 22 Jan 2020 13:55:37 -0500 Subject: [PATCH 1504/1854] Support LTO-CM read block and add CM-type into hf lto info command. --- client/cmdhflist.c | 4 +- client/cmdhflto.c | 197 ++++++++++++++++++++++++++++++++++----------- client/cmdhflto.h | 3 +- 3 files changed, 152 insertions(+), 52 deletions(-) diff --git a/client/cmdhflist.c b/client/cmdhflist.c index 2fde8492c..b35e4d622 100644 --- a/client/cmdhflist.c +++ b/client/cmdhflist.c @@ -1119,7 +1119,7 @@ void annotateLTO(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) { snprintf(exp, size, "READWORD"); break; case (LTO_READBLOCK & 0xF0): - snprintf(exp, size, "READBLOCK"); + snprintf(exp, size, "READBLOCK(%d)", cmd[1]); break; case LTO_READBLOCK_CONT: snprintf(exp, size, "READBLOCK CONT"); @@ -1128,7 +1128,7 @@ void annotateLTO(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) { snprintf(exp, size, "WRITEWORD"); break; case (LTO_WRITEBLOCK & 0xF0): - snprintf(exp, size, "WRITEBLOCK"); + snprintf(exp, size, "WRITEBLOCK(%d)", cmd[1]); break; case LTO_HALT: snprintf(exp, size, "HALT"); diff --git a/client/cmdhflto.c b/client/cmdhflto.c index 39e9cf30b..e82fee381 100644 --- a/client/cmdhflto.c +++ b/client/cmdhflto.c @@ -33,6 +33,18 @@ static int usage_lto_info(void) { return PM3_SUCCESS; } +static int usage_lto_rdbl(void) { + PrintAndLogEx(NORMAL, "Usage: hf lto rdbl [h] s e "); + PrintAndLogEx(NORMAL, "Options:"); + PrintAndLogEx(NORMAL, " h this help"); + PrintAndLogEx(NORMAL, " s start block in decimal >= 0"); + PrintAndLogEx(NORMAL, " e end block in decimal <= 254"); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Examples:"); + PrintAndLogEx(NORMAL, " hf lto rdbl s 0 e 254 - Read data block from 0 to 254"); + return PM3_SUCCESS; +} + static void lto_switch_off_field(void) { SendCommandMIX(CMD_HF_ISO14443A_READER, 0, 0, 0, NULL, 0); } @@ -42,15 +54,22 @@ static void lto_switch_on_field(void) { } // send a raw LTO-CM command, returns the length of the response (0 in case of error) -static int lto_send_cmd_raw(uint8_t *cmd, uint8_t len, uint8_t *response, uint16_t *response_len, bool addcrc, bool verbose) { +static int lto_send_cmd_raw(uint8_t *cmd, uint8_t len, uint8_t *response, uint16_t *response_len, bool addcrc, bool is7bits, bool verbose) { uint64_t arg0 = ISO14A_RAW | ISO14A_NO_DISCONNECT | ISO14A_NO_RATS; - uint32_t arg1 = (len == 1) ? (7 << 16) : 0; - arg1 |= len; + uint32_t arg1; if (addcrc) { arg0 |= ISO14A_APPEND_CRC; } + + if (is7bits) { + arg1 = 7 << 16; + } else { + arg1 = 0; + } + + arg1 |= len; SendCommandOLD(CMD_HF_ISO14443A_READER, arg0, arg1, 0, cmd, len); PacketResponseNG resp; @@ -62,7 +81,6 @@ static int lto_send_cmd_raw(uint8_t *cmd, uint8_t len, uint8_t *response, uint16 if (resp.oldarg[0] == *response_len) { *response_len = resp.oldarg[0]; - if (*response_len > 0) { memcpy(response, resp.data.asBytes, *response_len); } @@ -70,40 +88,36 @@ static int lto_send_cmd_raw(uint8_t *cmd, uint8_t len, uint8_t *response, uint16 if (verbose) PrintAndLogEx(WARNING, "Wrong response length (%d != %" PRIu64 ")", *response_len, resp.oldarg[0]); return PM3_ESOFT; } + return PM3_SUCCESS; } // select a LTO-CM tag. Send WUPA and RID. -static int lto_select(uint8_t *id_response, uint8_t id_len, bool verbose) { +static int lto_select(uint8_t *id_response, uint8_t id_len, uint8_t *type_response, bool verbose) { // Todo: implement anticollision uint8_t resp[] = {0, 0}; uint16_t resp_len; uint8_t wupa_cmd[] = {LTO_REQ_STANDARD}; - uint8_t select_cmd[] = {LTO_SELECT, 0x20}; - uint8_t select_1_cmd[] = {LTO_SELECT, 0x70, 0, 0, 0, 0, 0}; - - lto_switch_on_field(); + uint8_t select_sn_cmd[] = {LTO_SELECT, 0x20}; + uint8_t select_cmd[] = {LTO_SELECT, 0x70, 0, 0, 0, 0, 0}; resp_len = 2; - int status = lto_send_cmd_raw(wupa_cmd, sizeof(wupa_cmd), resp, &resp_len, false, verbose); + int status = lto_send_cmd_raw(wupa_cmd, sizeof(wupa_cmd), type_response, &resp_len, false, true, verbose); if (status == PM3_ETIMEOUT || status == PM3_ESOFT) { - lto_switch_off_field(); return PM3_ESOFT; // WUPA failed } resp_len = id_len; - status = lto_send_cmd_raw(select_cmd, sizeof(select_cmd), id_response, &resp_len, false, verbose); + status = lto_send_cmd_raw(select_sn_cmd, sizeof(select_sn_cmd), id_response, &resp_len, false, false, verbose); if (status == PM3_ETIMEOUT || status == PM3_ESOFT) { - lto_switch_off_field(); - return PM3_EWRONGANSVER; // SELECT failed + return PM3_EWRONGANSVER; // REQUEST SERIAL NUMBER failed } - memcpy(select_1_cmd + 2, id_response, sizeof(select_1_cmd) - 2); + memcpy(select_cmd + 2, id_response, sizeof(select_cmd) - 2); resp_len = 1; - status = lto_send_cmd_raw(select_1_cmd, sizeof(select_1_cmd), resp, &resp_len, true, verbose); + status = lto_send_cmd_raw(select_cmd, sizeof(select_cmd), resp, &resp_len, true, false, verbose); if (status == PM3_ETIMEOUT || status == PM3_ESOFT || resp[0] != 0x0A) { - lto_switch_off_field(); return PM3_EWRONGANSVER; // SELECT failed } @@ -132,63 +146,148 @@ static int CmdHfLTOInfo(const char *Cmd) { return PM3_EINVARG; } - return infoLTO(false); + return infoLTO(true); } int infoLTO(bool verbose) { clearCommandBuffer(); + lto_switch_on_field(); + uint8_t serial_number[5]; uint8_t serial_len = sizeof(serial_number); - int ret_val = lto_select(serial_number, serial_len, verbose); + uint8_t type_info[2]; + + int ret_val = lto_select(serial_number, serial_len, type_info, verbose); lto_switch_off_field(); if (ret_val == PM3_SUCCESS) { PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(SUCCESS, " UID : " _YELLOW_("%s"), sprint_hex_inrow(serial_number, sizeof(serial_number))); - PrintAndLogEx(SUCCESS, "TYPE : "); - // todo: add printing of all configuration - } else { - if (verbose) PrintAndLogEx(WARNING, "LTO-CM card select failed"); + PrintAndLogEx(SUCCESS, "TYPE INFO: " _YELLOW_("%s"), sprint_hex_inrow(type_info, sizeof(type_info))); + PrintAndLogEx(SUCCESS, "UID: " _YELLOW_("%s"), sprint_hex_inrow(serial_number, sizeof(serial_number))); } - /* read block: - - SendCommandNG(CMD_HF_THINFILM_READ, NULL, 0); - PacketResponseNG resp; - if (!WaitForResponseTimeout(CMD_HF_THINFILM_READ, &resp, 1500)) { - PrintAndLogEx(WARNING, "timeout while waiting for reply."); - return PM3_ETIMEOUT; - } - - if (resp.status == PM3_SUCCESS) { - if (resp.length == 16 || resp.length == 32) { - print_barcode(resp.data.asBytes, resp.length, verbose); - } else { - if (verbose) - PrintAndLogEx(WARNING, "Response is wrong length. (%d)", resp.length); - - return PM3_ESOFT; - } - } - - return resp.status; - */ return ret_val; } static int CmdHfLTOList(const char *Cmd) { (void)Cmd; // Cmd is not used so far - CmdTraceList("14a"); -// CmdTraceList("lto"); + CmdTraceList("lto"); return PM3_SUCCESS; } +static int lto_rdbl(uint8_t blk, uint8_t *block_responce, uint8_t *block_cnt_responce, bool verbose) { + + uint16_t resp_len; + uint8_t rdbl_cmd[] = {0x30, blk}; + uint8_t rdbl_cnt_cmd[] ={0x80}; + + resp_len = 18; + int status = lto_send_cmd_raw(rdbl_cmd, sizeof(rdbl_cmd), block_responce, &resp_len, true, false, verbose); + if (status == PM3_ETIMEOUT || status == PM3_ESOFT ) { + return PM3_EWRONGANSVER; // READ BLOCK failed + } + + resp_len = 18; + status = lto_send_cmd_raw(rdbl_cnt_cmd, sizeof(rdbl_cnt_cmd), block_cnt_responce, &resp_len, false, false, verbose); + if (status == PM3_ETIMEOUT || status == PM3_ESOFT ) { + return PM3_EWRONGANSVER; // READ BLOCK CONTINUE failed + } + + return PM3_SUCCESS; +} + +int rdblLTO(uint8_t st_blk, uint8_t end_blk, bool verbose) { + + clearCommandBuffer(); + + lto_switch_on_field(); + + uint8_t serial_number[5]; + uint8_t serial_len = sizeof(serial_number); + uint8_t type_info[2]; + int ret_val = lto_select(serial_number, serial_len, type_info, verbose); + + if (ret_val != PM3_SUCCESS) { + lto_switch_off_field(); + return ret_val; + } + + uint8_t block_data_d00_d15[18]; + uint8_t block_data_d16_d31[18]; + uint8_t block_data[32]; + + for(uint8_t i = st_blk; i < end_blk + 1; i++) { + + ret_val = lto_rdbl(i, block_data_d00_d15, block_data_d16_d31, verbose); + + if (ret_val == PM3_SUCCESS) { + //Remove CRCs + for (int t = 0; t < 16; t++) { + block_data[t] = block_data_d00_d15[t]; + block_data[t + 16] = block_data_d16_d31[t]; + } + + PrintAndLogEx(SUCCESS, "BLK%03d: " _YELLOW_("%s"), i, sprint_hex_inrow(block_data, sizeof(block_data))); + } else { + lto_switch_off_field(); + return ret_val; + } + } + + lto_switch_off_field(); + return ret_val; +} + +static int CmdHfLTOReadBlock(const char *Cmd) { + + uint8_t cmdp = 0; + bool errors = false; + uint8_t st_blk = 0; + uint8_t end_blk = 254; + + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { + case 'h': + return usage_lto_rdbl(); + case 's': + st_blk = param_get8(Cmd, cmdp+1); + if ( end_blk < st_blk ) { + errors = true; + break; + } + cmdp += 2; + break; + + case 'e': + end_blk = param_get8(Cmd, cmdp+1); + if ( end_blk < st_blk ) { + errors = true; + break; } + cmdp += 2; + break; + + default: + PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } + } + + //Validations + if (errors) { + usage_lto_rdbl(); + return PM3_EINVARG; + } + + return rdblLTO(st_blk, end_blk, true); +} + static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, {"info", CmdHfLTOInfo, IfPm3Iso14443a, "Tag information"}, -// {"rdbl", CmdHfLTOReadBlock, IfPm3Iso14443a, "Read block"}, + {"rdbl", CmdHfLTOReadBlock, IfPm3Iso14443a, "Read block"}, // {"wrbl", CmdHfLTOWriteBlock, IfPm3Iso14443a, "Write block"}, // {"sim", CmdHfLTOSim, IfPm3Iso14443a, " Simulate LTO-CM tag"}, {"list", CmdHfLTOList, AlwaysAvailable, "List LTO-CM history"}, diff --git a/client/cmdhflto.h b/client/cmdhflto.h index 52c22da0d..d54eb75f1 100644 --- a/client/cmdhflto.h +++ b/client/cmdhflto.h @@ -14,7 +14,8 @@ #include "common.h" int infoLTO(bool verbose); - +int rdblLTO(uint8_t st_blk, uint8_t end_blk, bool verbose); int CmdHFLTO(const char *Cmd); #endif + From 688fb78235b59f18a18b12a3dda8d50b6dc16cf9 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 22 Jan 2020 21:14:05 +0100 Subject: [PATCH 1505/1854] fix for compiling with pm3others --- armsrc/mifarecmd.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index cf1115f21..69e3dd04e 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -1783,7 +1783,8 @@ void MifareChkKeys(uint8_t *datain) { } void MifareChkKeys_file(uint8_t *fn) { - + +#ifdef WITH_FLASH SpinOff(0); int changed = rdv40_spiffs_lazy_mount(); @@ -1801,6 +1802,7 @@ void MifareChkKeys_file(uint8_t *fn) { MifareChkKeys(mem); BigBuf_free(); +#endif } //----------------------------------------------------------------------------- From ef8cdc8babf5e5c58c094b3f63546522e73258e3 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 24 Jan 2020 14:48:30 +0100 Subject: [PATCH 1506/1854] textual --- client/cmdhfmf.c | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 173184592..0f8668d2c 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -556,26 +556,26 @@ static int CmdHF14AMfDarkside(const char *Cmd) { switch (isOK) { case -1 : PrintAndLogEx(WARNING, "button pressed. Aborted."); - return 1; + return PM3_ESOFT; case -2 : PrintAndLogEx(FAILED, "card is not vulnerable to Darkside attack (doesn't send NACK on authentication requests)."); - return 1; + return PM3_ESOFT; case -3 : PrintAndLogEx(FAILED, "card is not vulnerable to Darkside attack (its random number generator is not predictable)."); - return 1; + return PM3_ESOFT; case -4 : PrintAndLogEx(FAILED, "card is not vulnerable to Darkside attack (its random number generator seems to be based on the wellknown"); PrintAndLogEx(FAILED, "generating polynomial with 16 effective bits only, but shows unexpected behaviour."); - return 1; + return PM3_ESOFT; case -5 : PrintAndLogEx(WARNING, "aborted via keyboard."); - return 1; + return PM3_ESOFT; default : PrintAndLogEx(SUCCESS, "found valid key: "_YELLOW_("%012" PRIx64), key); break; } PrintAndLogEx(NORMAL, ""); - return 0; + return PM3_SUCCESS; } static int CmdHF14AMfWrBl(const char *Cmd) { @@ -1351,7 +1351,7 @@ static int CmdHF14AMfNested(const char *Cmd) { num_to_bytes(g_mifare_default_keys[cnt], 6, (uint8_t *)(keyBlock + cnt * 6)); } - PrintAndLogEx(SUCCESS, "Testing known keys. Sector count=%d", SectorsCnt); + PrintAndLogEx(SUCCESS, "Testing known keys. Sector count "_YELLOW_("%d"), SectorsCnt); int res = mfCheckKeys_fast(SectorsCnt, true, true, 1, ARRAYLEN(g_mifare_default_keys) + 1, keyBlock, e_sector, false); if (res == PM3_SUCCESS) { // all keys found @@ -1360,8 +1360,8 @@ static int CmdHF14AMfNested(const char *Cmd) { } uint64_t t2 = msclock() - t1; - PrintAndLogEx(SUCCESS, "Time to check %zu known keys: %.0f seconds\n", ARRAYLEN(g_mifare_default_keys), (float)t2 / 1000.0); - PrintAndLogEx(SUCCESS, "enter nested attack"); + PrintAndLogEx(SUCCESS, "Time to check " _YELLOW_("%zu") "known keys: %.0f seconds\n", ARRAYLEN(g_mifare_default_keys), (float)t2 / 1000.0); + PrintAndLogEx(SUCCESS, "enter nested key recovery"); // nested sectors // int iterations = 0; @@ -1407,7 +1407,7 @@ static int CmdHF14AMfNested(const char *Cmd) { } t1 = msclock() - t1; - PrintAndLogEx(SUCCESS, "time in nested: %.0f seconds\n", (float)t1 / 1000.0); + PrintAndLogEx(SUCCESS, "time in nested: " _YELLOW_("%.0f") "seconds\n", (float)t1 / 1000.0); // 20160116 If Sector A is found, but not Sector B, try just reading it of the tag? @@ -1541,7 +1541,7 @@ static int CmdHF14AMfNestedStatic(const char *Cmd) { // check if we can authenticate to sector if (mfCheckKeys(blockNo, keyType, true, 1, key, &key64) != PM3_SUCCESS) { - PrintAndLogEx(WARNING, "Wrong key. Can't authenticate to block:%3d key type:%c", blockNo, keyType ? 'B' : 'A'); + PrintAndLogEx(WARNING, "Wrong key. Can't authenticate to block: %3d key type: %c", blockNo, keyType ? 'B' : 'A'); return PM3_EOPABORTED; } @@ -1562,7 +1562,7 @@ static int CmdHF14AMfNestedStatic(const char *Cmd) { num_to_bytes(g_mifare_default_keys[cnt], 6, (uint8_t *)(keyBlock + cnt * 6)); } - PrintAndLogEx(SUCCESS, "Testing known keys. Sector count=%d", SectorsCnt); + PrintAndLogEx(SUCCESS, "Testing known keys. Sector count "_YELLOW_("%d"), SectorsCnt); int res = mfCheckKeys_fast(SectorsCnt, true, true, 1, ARRAYLEN(g_mifare_default_keys) + 1, keyBlock, e_sector, false); if (res == PM3_SUCCESS) { // all keys found @@ -1571,8 +1571,8 @@ static int CmdHF14AMfNestedStatic(const char *Cmd) { } uint64_t t2 = msclock() - t1; - PrintAndLogEx(SUCCESS, "Time to check %zu known keys: %.0f seconds\n", ARRAYLEN(g_mifare_default_keys), (float)t2 / 1000.0); - PrintAndLogEx(SUCCESS, "enter static nested attack"); + PrintAndLogEx(SUCCESS, "Time to check "_YELLOW_("%zu") "known keys: %.0f seconds\n", ARRAYLEN(g_mifare_default_keys), (float)t2 / 1000.0); + PrintAndLogEx(SUCCESS, "enter static nested key recovery"); // nested sectors for (trgKeyType = 0; trgKeyType < 2; ++trgKeyType) { @@ -1587,6 +1587,9 @@ static int CmdHF14AMfNestedStatic(const char *Cmd) { case PM3_ETIMEOUT : PrintAndLogEx(ERR, "Command execute timeout"); break; + case PM3_EOPABORTED : + PrintAndLogEx(WARNING, "aborted via keyboard."); + break; case PM3_ESOFT : continue; case PM3_SUCCESS : @@ -1605,7 +1608,7 @@ static int CmdHF14AMfNestedStatic(const char *Cmd) { } t1 = msclock() - t1; - PrintAndLogEx(SUCCESS, "time in static nested: %.0f seconds\n", (float)t1 / 1000.0); + PrintAndLogEx(SUCCESS, "time in static nested: " _YELLOW_("%.0f") "seconds\n", (float)t1 / 1000.0); // 20160116 If Sector A is found, but not Sector B, try just reading it of the tag? @@ -1841,7 +1844,7 @@ static int CmdHF14AMfNestedHard(const char *Cmd) { uint64_t key64 = 0; // check if we can authenticate to sector if (mfCheckKeys(blockNo, keyType, true, 1, key, &key64) != PM3_SUCCESS) { - PrintAndLogEx(WARNING, "Key is wrong. Can't authenticate to block:%3d key type:%c", blockNo, keyType ? 'B' : 'A'); + PrintAndLogEx(WARNING, "Key is wrong. Can't authenticate to block: %3d key type: %c", blockNo, keyType ? 'B' : 'A'); return 3; } } @@ -4802,7 +4805,7 @@ static command_t CommandTable[] = { {"darkside", CmdHF14AMfDarkside, IfPm3Iso14443a, "Darkside attack"}, {"nested", CmdHF14AMfNested, IfPm3Iso14443a, "Nested attack"}, {"hardnested", CmdHF14AMfNestedHard, AlwaysAvailable, "Nested attack for hardened MIFARE Classic cards"}, - {"staticnested", CmdHF14AMfNestedStatic, IfPm3Iso14443a, "Nested attack against static nonce Mifare Classic cards"}, + {"staticnested", CmdHF14AMfNestedStatic, IfPm3Iso14443a, "Nested attack against static nonce MIFARE Classic cards"}, {"autopwn", CmdHF14AMfAutoPWN, IfPm3Iso14443a, "Automatic key recovery tool for MIFARE Classic"}, // {"keybrute", CmdHF14AMfKeyBrute, IfPm3Iso14443a, "J_Run's 2nd phase of multiple sector nested authentication key recovery"}, {"nack", CmdHf14AMfNack, IfPm3Iso14443a, "Test for MIFARE NACK bug"}, From 6ad7f1ecf75047c6e2c26237ab9a3723e4820ee5 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 24 Jan 2020 16:28:39 +0100 Subject: [PATCH 1507/1854] textual --- client/flash.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/client/flash.c b/client/flash.c index 5bbb669c0..98375fc3a 100644 --- a/client/flash.c +++ b/client/flash.c @@ -522,8 +522,17 @@ static int write_block(uint32_t address, uint8_t *data, uint32_t length) { return ret; } +const char ice[] = + "...................................................................\n @@@ @@@@@@@ @@@@@@@@ @@@@@@@@@@ @@@@@@ @@@ @@@\n" + " @@! !@@ @@! @@! @@! @@! @@! @@@ @@!@!@@@\n !!@ !@! @!!!:! @!! !!@ @!@ @!@!@!@! @!@@!!@!\n" + " !!: :!! !!: !!: !!: !!: !!! !!: !!!\n : :: :: : : :: ::: : : : : : :: : \n" + " . .. .. . . .. ... . . . . . .. . \n" +; + // Write a file's segments to Flash int flash_write(flash_file_t *ctx) { + int len = 0; + PrintAndLogEx(SUCCESS, "Writing segments for file: %s", ctx->filename); for (int i = 0; i < ctx->num_segs; i++) { flash_seg_t *seg = &ctx->segments[i]; @@ -552,7 +561,11 @@ int flash_write(flash_file_t *ctx) { baddr += block_size; length -= block_size; block++; - fprintf(stdout, "."); + if ( len < strlen(ice) ) + fprintf(stdout, "%c", ice[len++]); + else + fprintf(stdout, "."); + fflush(stdout); } PrintAndLogEx(NORMAL, " " _GREEN_("OK")); From 6ddf9823e9c43fcacc4d14dc2a815c32e873b6bb Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 24 Jan 2020 18:21:57 +0100 Subject: [PATCH 1508/1854] textual --- client/flash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/flash.c b/client/flash.c index 98375fc3a..a3d438757 100644 --- a/client/flash.c +++ b/client/flash.c @@ -526,7 +526,7 @@ const char ice[] = "...................................................................\n @@@ @@@@@@@ @@@@@@@@ @@@@@@@@@@ @@@@@@ @@@ @@@\n" " @@! !@@ @@! @@! @@! @@! @@! @@@ @@!@!@@@\n !!@ !@! @!!!:! @!! !!@ @!@ @!@!@!@! @!@@!!@!\n" " !!: :!! !!: !!: !!: !!: !!! !!: !!!\n : :: :: : : :: ::: : : : : : :: : \n" - " . .. .. . . .. ... . . . . . .. . \n" + _RED_(" . .. .. . . .. ... . . . . . .. . \n") ; // Write a file's segments to Flash From cf65145353ba21da2fc9d121c30c2d1b597abcba Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 24 Jan 2020 20:12:34 +0100 Subject: [PATCH 1509/1854] less waiting --- armsrc/mifarecmd.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 69e3dd04e..9e9c721bd 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -1240,7 +1240,7 @@ uint8_t chkKey(struct chk_t *c) { } res = mifare_classic_authex(c->pcs, c->cuid, c->block, c->keyType, c->key, AUTH_FIRST, NULL, NULL); - CHK_TIMEOUT(); +// CHK_TIMEOUT(); // if successful auth, send HALT // if ( !res ) @@ -1760,7 +1760,7 @@ void MifareChkKeys(uint8_t *datain) { key = bytes_to_num(datain + i * 6, 6); res = mifare_classic_auth(pcs, cuid, blockNo, keyType, key, AUTH_FIRST); - CHK_TIMEOUT(); +// CHK_TIMEOUT(); if (res) continue; @@ -1784,13 +1784,13 @@ void MifareChkKeys(uint8_t *datain) { void MifareChkKeys_file(uint8_t *fn) { -#ifdef WITH_FLASH +#ifdef WITH_FLASH SpinOff(0); int changed = rdv40_spiffs_lazy_mount(); uint32_t size = size_in_spiffs((char *)fn); uint8_t *mem = BigBuf_malloc(size); - + rdv40_spiffs_read_as_filetype((char *)fn, mem, size, RDV40_SPIFFS_SAFETY_SAFE); if (changed) { @@ -2229,7 +2229,7 @@ void MifareHasStaticNonce() { nt = bytes_to_num(rec, 4); - CHK_TIMEOUT(); +// CHK_TIMEOUT(); } OUT: From 28c6a5dc2d7d173bc01d25823311d154b22d4a50 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 25 Jan 2020 14:29:35 +0100 Subject: [PATCH 1510/1854] textual --- client/cmdhfmf.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 0f8668d2c..c8ee0013c 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -1545,6 +1545,10 @@ static int CmdHF14AMfNestedStatic(const char *Cmd) { return PM3_EOPABORTED; } + if (IfPm3Flash()) { + PrintAndLogEx(INFO, "RDV4 with flashmemory supported detected."); + } + uint64_t t1 = msclock(); e_sector = calloc(SectorsCnt, sizeof(sector_t)); @@ -3987,13 +3991,13 @@ static int CmdHF14AMfCWipe(const char *cmd) { CLIParserInit("hf mf cwipe", "Wipe gen1 magic chinese card. Set UID/ATQA/SAK/Data/Keys/Access to default values.", "Usage:\n\thf mf cwipe -> wipe card.\n" - "\thf mfp mf cwipe -u 09080706 -a 0004 -s 18 -> set UID, ATQA and SAK and wipe card."); + "\thf mf cwipe -u 09080706 -a 0004 -s 18 -- set UID, ATQA and SAK and wipe card."); void *argtable[] = { arg_param_begin, - arg_str0("uU", "uid", "", "UID for card"), - arg_str0("aA", "atqa", "", "ATQA for card"), - arg_str0("sS", "sak", "", "SAK for card"), + arg_str0("uU", "uid", "", "UID for card"), + arg_str0("aA", "atqa", "", "ATQA for card"), + arg_str0("sS", "sak", "", "SAK for card"), arg_param_end }; CLIExecWithReturn(cmd, argtable, true); @@ -4008,11 +4012,11 @@ static int CmdHF14AMfCWipe(const char *cmd) { return PM3_EINVARG; } if (atqaLen && atqaLen != 2) { - PrintAndLogEx(ERR, "UID length must be 2 bytes instead of: %d", atqaLen); + PrintAndLogEx(ERR, "ATQA length must be 2 bytes instead of: %d", atqaLen); return PM3_EINVARG; } if (sakLen && sakLen != 1) { - PrintAndLogEx(ERR, "UID length must be 1 byte instead of: %d", sakLen); + PrintAndLogEx(ERR, "SAK length must be 1 byte instead of: %d", sakLen); return PM3_EINVARG; } From 88a976d9ff6630ecccee73ca063a5352c827e85c Mon Sep 17 00:00:00 2001 From: Kevin-Nakamoto Date: Mon, 27 Jan 2020 14:39:38 -0500 Subject: [PATCH 1511/1854] added write block command for LTO-CM --- CHANGELOG.md | 1 + client/cmdhflto.c | 124 ++++++++++++++++++++++++++++++++++++++++++++-- client/cmdhflto.h | 1 + 3 files changed, 121 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f0b0e3c6f..ca80d078f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Added `hf lto wrbl` - write block support for LTO Cartridge memory (@Kevin-Nakamoto) - Fix compilation under openSUSE (@hsanjuan) - Added `lf nexwatch sim` - use raw hex to simulate (@iceman1001) - Fix `lf indala read` - long id 224bits preamble identification less strict (@iceman1001) diff --git a/client/cmdhflto.c b/client/cmdhflto.c index e82fee381..ed61eac70 100644 --- a/client/cmdhflto.c +++ b/client/cmdhflto.c @@ -45,6 +45,19 @@ static int usage_lto_rdbl(void) { return PM3_SUCCESS; } +static int usage_lto_wrbl(void) { + PrintAndLogEx(NORMAL, "Usage: hf lto wrbl [h] b d "); + PrintAndLogEx(NORMAL, "Options:"); + PrintAndLogEx(NORMAL, " h this help"); + PrintAndLogEx(NORMAL, " b block address (decimal, 0 - 254) "); + PrintAndLogEx(NORMAL, " d 32 bytes of data to write (64 hex characters, no space)"); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Examples:"); + PrintAndLogEx(NORMAL, " hf lto wrbl b 128 d 0001020304050607080910111213141516171819202122232425262728293031 - write 00..31 to block address 128"); + PrintAndLogEx(NORMAL, " Use 'hf lto rdbl' for verification"); + return PM3_SUCCESS; +} + static void lto_switch_off_field(void) { SendCommandMIX(CMD_HF_ISO14443A_READER, 0, 0, 0, NULL, 0); } @@ -179,17 +192,15 @@ static int CmdHfLTOList(const char *Cmd) { static int lto_rdbl(uint8_t blk, uint8_t *block_responce, uint8_t *block_cnt_responce, bool verbose) { - uint16_t resp_len; + uint16_t resp_len = 18; uint8_t rdbl_cmd[] = {0x30, blk}; uint8_t rdbl_cnt_cmd[] ={0x80}; - resp_len = 18; int status = lto_send_cmd_raw(rdbl_cmd, sizeof(rdbl_cmd), block_responce, &resp_len, true, false, verbose); if (status == PM3_ETIMEOUT || status == PM3_ESOFT ) { return PM3_EWRONGANSVER; // READ BLOCK failed } - resp_len = 18; status = lto_send_cmd_raw(rdbl_cnt_cmd, sizeof(rdbl_cnt_cmd), block_cnt_responce, &resp_len, false, false, verbose); if (status == PM3_ETIMEOUT || status == PM3_ESOFT ) { return PM3_EWRONGANSVER; // READ BLOCK CONTINUE failed @@ -284,12 +295,115 @@ static int CmdHfLTOReadBlock(const char *Cmd) { return rdblLTO(st_blk, end_blk, true); } +static int lto_wrbl(uint8_t blk, uint8_t *data, bool verbose) { + + uint8_t resp[] = {0, 0}; + uint16_t resp_len = 1; + uint8_t wrbl_cmd[] = {0xA0, blk}; + uint8_t wrbl_d00_d15[16]; + uint8_t wrbl_d16_d31[16]; + + for (int i = 0; i < 16; i++) { + wrbl_d00_d15[i] = data[i]; + wrbl_d16_d31[i] = data[i+16]; + } + + int status = lto_send_cmd_raw(wrbl_cmd, sizeof(wrbl_cmd), resp, &resp_len, true, false, verbose); + if (status == PM3_ETIMEOUT || status == PM3_ESOFT || resp[0] != 0x0A) { + return PM3_EWRONGANSVER; // WRITE BLOCK failed + } + + status = lto_send_cmd_raw(wrbl_d00_d15, sizeof(wrbl_d00_d15), resp, &resp_len, true, false, verbose); + if (status == PM3_ETIMEOUT || status == PM3_ESOFT || resp[0] != 0x0A) { + return PM3_EWRONGANSVER; // WRITE BLOCK failed + } + + status = lto_send_cmd_raw(wrbl_d16_d31, sizeof(wrbl_d16_d31), resp, &resp_len, true, false, verbose); + if (status == PM3_ETIMEOUT || status == PM3_ESOFT || resp[0] != 0x0A) { + return PM3_EWRONGANSVER; // WRITE BLOCK failed + } + + return PM3_SUCCESS; +} + +int wrblLTO(uint8_t blk, uint8_t *data, bool verbose) { + + clearCommandBuffer(); + lto_switch_on_field(); + + uint8_t serial_number[5]; + uint8_t serial_len = sizeof(serial_number); + uint8_t type_info[2]; + int ret_val = lto_select(serial_number, serial_len, type_info, verbose); + + if (ret_val != PM3_SUCCESS) { + lto_switch_off_field(); + return ret_val; + } + + ret_val = lto_wrbl(blk, data, verbose); + lto_switch_off_field(); + + if (ret_val == PM3_SUCCESS) { + PrintAndLogEx(SUCCESS, "BLK%03d: " _YELLOW_("Write Success"), blk); + } else { + PrintAndLogEx(WARNING, "BLK%03d: Write Error. Maybe this is a read-only block address.", blk); + } + + return ret_val; +} + +static int CmdHfLTOWriteBlock(const char *Cmd) { + + uint8_t cmdp = 0; + bool errors = false; + bool b_opt_selected = false; + bool d_opt_selected = false; + uint8_t blk = 128; + uint8_t blkData[32] = {0}; + + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { + case 'h': + return usage_lto_wrbl(); + case 'b': + blk = param_get8(Cmd, cmdp+1); + b_opt_selected = true; + cmdp += 2; + break; + case 'd': + if (param_gethex(Cmd, cmdp+1, blkData, 64)) { + PrintAndLogEx(WARNING, "BlockData must include 64 HEX symbols"); + errors = true; + break; + } + d_opt_selected = true; + cmdp += 2; + break; + default: + PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } + } + + //Validations + if (errors) { + usage_lto_wrbl(); + return PM3_EINVARG; + } else if (b_opt_selected == false || d_opt_selected == false) { + PrintAndLogEx(WARNING, "Need to specify block address and data. See usage, h option"); + return PM3_EINVARG; + } + + return wrblLTO(blk, blkData, true); +} + static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, {"info", CmdHfLTOInfo, IfPm3Iso14443a, "Tag information"}, {"rdbl", CmdHfLTOReadBlock, IfPm3Iso14443a, "Read block"}, -// {"wrbl", CmdHfLTOWriteBlock, IfPm3Iso14443a, "Write block"}, -// {"sim", CmdHfLTOSim, IfPm3Iso14443a, " Simulate LTO-CM tag"}, + {"wrbl", CmdHfLTOWriteBlock, IfPm3Iso14443a, "Write block"}, {"list", CmdHfLTOList, AlwaysAvailable, "List LTO-CM history"}, {NULL, NULL, NULL, NULL} }; diff --git a/client/cmdhflto.h b/client/cmdhflto.h index d54eb75f1..bc35d4378 100644 --- a/client/cmdhflto.h +++ b/client/cmdhflto.h @@ -15,6 +15,7 @@ int infoLTO(bool verbose); int rdblLTO(uint8_t st_blk, uint8_t end_blk, bool verbose); +int wrblLTO(uint8_t blk, uint8_t *data, bool verbose); int CmdHFLTO(const char *Cmd); #endif From aae8f6aebf988f1b07f046860af4dd7688168460 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 28 Jan 2020 08:28:36 +0100 Subject: [PATCH 1512/1854] prepare for LTO dump --- client/cmdhflto.c | 77 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 59 insertions(+), 18 deletions(-) diff --git a/client/cmdhflto.c b/client/cmdhflto.c index ed61eac70..b717eab46 100644 --- a/client/cmdhflto.c +++ b/client/cmdhflto.c @@ -75,8 +75,8 @@ static int lto_send_cmd_raw(uint8_t *cmd, uint8_t len, uint8_t *response, uint16 if (addcrc) { arg0 |= ISO14A_APPEND_CRC; } - - if (is7bits) { + + if (is7bits) { arg1 = 7 << 16; } else { arg1 = 0; @@ -171,14 +171,14 @@ int infoLTO(bool verbose) { uint8_t serial_number[5]; uint8_t serial_len = sizeof(serial_number); uint8_t type_info[2]; - + int ret_val = lto_select(serial_number, serial_len, type_info, verbose); lto_switch_off_field(); if (ret_val == PM3_SUCCESS) { PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(SUCCESS, "TYPE INFO: " _YELLOW_("%s"), sprint_hex_inrow(type_info, sizeof(type_info))); PrintAndLogEx(SUCCESS, "UID: " _YELLOW_("%s"), sprint_hex_inrow(serial_number, sizeof(serial_number))); + PrintAndLogEx(SUCCESS, "TYPE INFO: " _YELLOW_("%s"), sprint_hex_inrow(type_info, sizeof(type_info))); } return ret_val; @@ -230,7 +230,7 @@ int rdblLTO(uint8_t st_blk, uint8_t end_blk, bool verbose) { uint8_t block_data[32]; for(uint8_t i = st_blk; i < end_blk + 1; i++) { - + ret_val = lto_rdbl(i, block_data_d00_d15, block_data_d16_d31, verbose); if (ret_val == PM3_SUCCESS) { @@ -239,11 +239,11 @@ int rdblLTO(uint8_t st_blk, uint8_t end_blk, bool verbose) { block_data[t] = block_data_d00_d15[t]; block_data[t + 16] = block_data_d16_d31[t]; } - - PrintAndLogEx(SUCCESS, "BLK%03d: " _YELLOW_("%s"), i, sprint_hex_inrow(block_data, sizeof(block_data))); + + PrintAndLogEx(SUCCESS, "BLK %03d: " _YELLOW_("%s"), i, sprint_hex_inrow(block_data, sizeof(block_data))); } else { lto_switch_off_field(); - return ret_val; + return ret_val; } } @@ -273,7 +273,7 @@ static int CmdHfLTOReadBlock(const char *Cmd) { case 'e': end_blk = param_get8(Cmd, cmdp+1); - if ( end_blk < st_blk ) { + if ( end_blk < st_blk ) { errors = true; break; } cmdp += 2; @@ -345,9 +345,9 @@ int wrblLTO(uint8_t blk, uint8_t *data, bool verbose) { lto_switch_off_field(); if (ret_val == PM3_SUCCESS) { - PrintAndLogEx(SUCCESS, "BLK%03d: " _YELLOW_("Write Success"), blk); + PrintAndLogEx(SUCCESS, "BLK %03d: " _YELLOW_("write success"), blk); } else { - PrintAndLogEx(WARNING, "BLK%03d: Write Error. Maybe this is a read-only block address.", blk); + PrintAndLogEx(WARNING, "BLK %03d: write error. Maybe this is a read-only block address.", blk); } return ret_val; @@ -373,7 +373,7 @@ static int CmdHfLTOWriteBlock(const char *Cmd) { break; case 'd': if (param_gethex(Cmd, cmdp+1, blkData, 64)) { - PrintAndLogEx(WARNING, "BlockData must include 64 HEX symbols"); + PrintAndLogEx(WARNING, "block data must include 64 HEX symbols"); errors = true; break; } @@ -381,7 +381,7 @@ static int CmdHfLTOWriteBlock(const char *Cmd) { cmdp += 2; break; default: - PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + PrintAndLogEx(WARNING, "unknown parameter '%c'", param_getchar(Cmd, cmdp)); errors = true; break; } @@ -399,12 +399,53 @@ static int CmdHfLTOWriteBlock(const char *Cmd) { return wrblLTO(blk, blkData, true); } +/* +static int CmdHfLTODump(const char *Cmd) { + + uint8_t cmdp = 0; + bool errors = false; + uint8_t blk = 128; + + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { + case 'h': + return usage_lto_dump(); + case 'b': + blk = param_get8(Cmd, cmdp+1); + b_opt_selected = true; + cmdp += 2; + break; + default: + PrintAndLogEx(WARNING, "unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } + } + + //Validations + if (errors) { + usage_lto_dump(); + return PM3_EINVARG; + } + +// alloc memory +// loop all blocks +// save to file +// free memory + + return PM3_SUCCESS; +} +*/ + + static command_t CommandTable[] = { - {"help", CmdHelp, AlwaysAvailable, "This help"}, - {"info", CmdHfLTOInfo, IfPm3Iso14443a, "Tag information"}, - {"rdbl", CmdHfLTOReadBlock, IfPm3Iso14443a, "Read block"}, - {"wrbl", CmdHfLTOWriteBlock, IfPm3Iso14443a, "Write block"}, - {"list", CmdHfLTOList, AlwaysAvailable, "List LTO-CM history"}, + {"help", CmdHelp, AlwaysAvailable, "This help"}, +// {"dump", CmdHfLTDump, IfPm3Iso14443a, "Dump LTO-CM tag to file"}, +// {"restore", CmdHfLTRestore, IfPm3Iso14443a, "Restore dump file to LTO-CM tag"}, + {"info", CmdHfLTOInfo, IfPm3Iso14443a, "Tag information"}, + {"rdbl", CmdHfLTOReadBlock, IfPm3Iso14443a, "Read block"}, + {"wrbl", CmdHfLTOWriteBlock, IfPm3Iso14443a, "Write block"}, + {"list", CmdHfLTOList, AlwaysAvailable, "List LTO-CM history"}, {NULL, NULL, NULL, NULL} }; From d6f552e856ac4b82b195cd9b72cce081d6432f22 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 28 Jan 2020 22:06:40 +0100 Subject: [PATCH 1513/1854] assign direct --- fpga/lo_adc.v | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/fpga/lo_adc.v b/fpga/lo_adc.v index 8c1dd12e2..aba849fcc 100644 --- a/fpga/lo_adc.v +++ b/fpga/lo_adc.v @@ -29,11 +29,8 @@ reg [7:0] pck_divider; reg clk_state; // Antenna logic, depending on "lf_field" (in arm defined as FPGA_LF_READER_FIELD) -wire tag_modulation; -assign tag_modulation = ssp_dout & !lf_field; - -wire reader_modulation; -assign reader_modulation = !ssp_dout & lf_field & clk_state; +wire tag_modulation = ssp_dout & !lf_field; +wire reader_modulation = !ssp_dout & lf_field & clk_state; // always on (High Frequency outputs, unused) assign pwr_oe1 = 1'b0; From 04bca3cdb7b0ef7f6085f39f27ff21753e0bc193 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 29 Jan 2020 04:37:10 +0100 Subject: [PATCH 1514/1854] fix partial data acqusitions not use bigbuff_malloc --- armsrc/lfadc.c | 40 ++++++++++++++++++++++++++++++---------- armsrc/lfsampling.c | 32 +++++++++++++++++++------------- armsrc/lfsampling.h | 1 + 3 files changed, 50 insertions(+), 23 deletions(-) diff --git a/armsrc/lfadc.c b/armsrc/lfadc.c index 5c5b87fc0..60044b6d8 100644 --- a/armsrc/lfadc.c +++ b/armsrc/lfadc.c @@ -51,14 +51,15 @@ size_t lf_count_edge_periods_ex(size_t max, bool wait, bool detect_gap) { size_t periods = 0; volatile uint8_t adc_val; //uint8_t avg_peak = 140, avg_through = 96; - uint8_t avg_peak = 130, avg_through = 106; + // 140 - 127 - 114 + uint8_t avg_peak = 140, avg_through = 106; int16_t checked = 0; - while (true) { + while (!BUTTON_PRESS()) { - // only every 1000th times, in order to save time when collecting samples. + // only every 100th times, in order to save time when collecting samples. if (checked == 1000) { - if (BUTTON_PRESS() || data_available()) { + if (data_available()) { checked = -1; break; } else { @@ -100,7 +101,7 @@ size_t lf_count_edge_periods_ex(size_t max, bool wait, bool detect_gap) { } previous_adc_val = adc_val; - if (periods == max) return 0; + if (periods >= max) return 0; } } if (logging) logSampleSimple(0xFF); @@ -136,7 +137,10 @@ void lf_wait_periods(size_t periods) { lf_count_edge_periods_ex(periods, true, false); } -void lf_init(bool reader) { +void lf_init(bool reader, bool simulate) { + + StopTicks(); + reader_mode = reader; FpgaDownloadAndGo(FPGA_BITSTREAM_LF); @@ -145,7 +149,12 @@ void lf_init(bool reader) { if (reader) { FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); } else { - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC); + if (simulate) +// FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC); + else + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC); + } // Connect the A/D to the peak-detected low-frequency path. @@ -186,11 +195,12 @@ void lf_init(bool reader) { // Prepare data trace uint32_t bufsize = 20000; - if (logging) initSampleBuffer(&bufsize); + // use malloc + if (logging) initSampleBufferEx(&bufsize, true); sample_config *sc = getSamplingConfig(); - sc->decimation = 2; - sc->averaging = 1; + sc->decimation = 1; + sc->averaging = 0; } void lf_finalize() { @@ -209,6 +219,8 @@ void lf_finalize() { sample_config *sc = getSamplingConfig(); sc->decimation = 1; sc->averaging = 0; + + StartTicks(); } size_t lf_detect_field_drop(size_t max) { @@ -256,6 +268,7 @@ inline void lf_modulation(bool modulation) { } } +// simulation inline void lf_manchester_send_bit(uint8_t bit) { lf_modulation(bit != 0); lf_wait_periods(16); @@ -263,10 +276,17 @@ inline void lf_manchester_send_bit(uint8_t bit) { lf_wait_periods(16); } +// simulation bool lf_manchester_send_bytes(const uint8_t *frame, size_t frame_len) { LED_B_ON(); + lf_manchester_send_bit(1); + lf_manchester_send_bit(1); + lf_manchester_send_bit(1); + lf_manchester_send_bit(1); + lf_manchester_send_bit(1); + // Send the content of the frame for (size_t i = 0; i < frame_len; i++) { lf_manchester_send_bit((frame[i / 8] >> (7 - (i % 8))) & 1); diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index 0679eb368..c492a4eda 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -106,25 +106,31 @@ BitstreamOut data = {0, 0, 0}; sampling_t samples = {0, 0, 0, 0}; void initSampleBuffer(uint32_t *sample_size) { + initSampleBufferEx(sample_size, false); +} + +void initSampleBufferEx(uint32_t *sample_size, bool use_malloc) { BigBuf_free(); -// We can't erase the buffer now, it would drastically delay the acquisition -// BigBuf_Clear_ext(false); - if (sample_size == NULL || *sample_size == 0) { - *sample_size = BigBuf_max_traceLen(); + // We can't erase the buffer now, it would drastically delay the acquisition - data.buffer = BigBuf_get_addr(); + if (use_malloc) { + + if (sample_size == NULL || *sample_size == 0 ) { + *sample_size = BigBuf_max_traceLen(); + data.buffer = BigBuf_get_addr(); + } else { + *sample_size = MIN(*sample_size, BigBuf_max_traceLen()); + data.buffer = BigBuf_malloc(*sample_size); + + } -// We can't erase the buffer now, it would drastically delay the acquisition -// memset(data.buffer, 0, *sample_size); } else { - *sample_size = MIN(*sample_size, BigBuf_max_traceLen()); - - data.buffer = BigBuf_malloc(*sample_size); - -// We can't erase the buffer now, it would drastically delay the acquisition -// memset(data.buffer, 0, *sample_size); + if (sample_size == NULL || *sample_size == 0 ) { + *sample_size = BigBuf_max_traceLen(); + } + data.buffer = BigBuf_get_addr(); } // diff --git a/armsrc/lfsampling.h b/armsrc/lfsampling.h index cd3a8993e..570dc20fe 100644 --- a/armsrc/lfsampling.h +++ b/armsrc/lfsampling.h @@ -70,6 +70,7 @@ uint32_t DoAcquisition_config(bool verbose, uint32_t sample_size); * Refactoring of lf sampling buffer */ void initSampleBuffer(uint32_t *sample_size); +void initSampleBufferEx(uint32_t *sample_size, bool use_malloc); void logSampleSimple(uint8_t sample); void logSample(uint8_t sample, uint8_t decimation, uint8_t bits_per_sample, bool avg); uint32_t getSampleCounter(); From a9a57e4a92643919b1ad9786e9542ef4ee0cde97 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 29 Jan 2020 05:12:36 +0100 Subject: [PATCH 1515/1854] forgot header --- armsrc/lfadc.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/armsrc/lfadc.h b/armsrc/lfadc.h index 2d7836a38..d394916ea 100644 --- a/armsrc/lfadc.h +++ b/armsrc/lfadc.h @@ -23,7 +23,8 @@ size_t lf_detect_gap(size_t max); void lf_reset_counter(); bool lf_get_tag_modulation(); void lf_wait_periods(size_t periods); -void lf_init(bool reader); +//void lf_init(bool reader); +void lf_init(bool reader, bool simulate); void lf_finalize(); size_t lf_detect_field_drop(size_t max); bool lf_manchester_send_bytes(const uint8_t *frame, size_t frame_len); From ebc04ea27ecae59a8df8c3307502f5b58e9f4693 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 29 Jan 2020 05:14:18 +0100 Subject: [PATCH 1516/1854] hitag sim changes --- armsrc/hitag2.c | 422 +++++++++++++++++++++++++++--------------------- 1 file changed, 234 insertions(+), 188 deletions(-) diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index 770c63544..8a0d4934a 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -18,7 +18,7 @@ // Piwi, 2019 // Iceman, 2019 // Anon, 2019 -// Doegos, 2020 +// Doegox, 2020 #include "hitag2.h" #include "hitag2_crypto.h" @@ -96,7 +96,6 @@ size_t blocknr; size_t flipped_bit = 0; uint32_t byte_value = 0; - static int hitag2_reset(void) { tag.state = TAG_STATE_RESET; tag.crypto_active = 0; @@ -143,6 +142,8 @@ static int hitag2_init(void) { #define HITAG_T_TAG_CAPTURE_THREE_HALF 41 #define HITAG_T_TAG_CAPTURE_FOUR_HALF 57 +/* +// sim static void hitag_send_bit(int bit) { LED_A_ON(); @@ -167,6 +168,7 @@ static void hitag_send_bit(int bit) { LED_A_OFF(); } +// sim static void hitag_send_frame(const uint8_t *frame, size_t frame_len) { // SOF - send start of frame hitag_send_bit(1); @@ -183,6 +185,7 @@ static void hitag_send_frame(const uint8_t *frame, size_t frame_len) { // Drop the modulation LOW(GPIO_SSC_DOUT); } +*/ // sim static void hitag2_handle_reader_command(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t *txlen) { @@ -215,42 +218,43 @@ static void hitag2_handle_reader_command(uint8_t *rx, const size_t rxlen, uint8_ // Read/Write command: ..xx x..y yy with yyy == ~xxx, xxx is sector number case 10: { - unsigned int sector = (~(((rx[0] << 2) & 0x04) | ((rx[1] >> 6) & 0x03)) & 0x07); + uint16_t sector = (~(((rx[0] << 2) & 0x04) | ((rx[1] >> 6) & 0x03)) & 0x07); + // Verify complement of sector index if (sector != ((rx[0] >> 3) & 0x07)) { - //DbpString("Transmission error (read/write)"); + DbpString("Transmission error (read/write)"); return; } switch (rx[0] & 0xC6) { // Read command: 11xx x00y - case 0xC0: + case 0xC0: { memcpy(tx, tag.sectors[sector], 4); *txlen = 32; break; - + } // Inverted Read command: 01xx x10y - case 0x44: + case 0x44: { for (size_t i = 0; i < 4; i++) { tx[i] = tag.sectors[sector][i] ^ 0xff; } *txlen = 32; break; - + } // Write command: 10xx x01y - case 0x82: + case 0x82: { // Prepare write, acknowledge by repeating command memcpy(tx, rx, nbytes(rxlen)); *txlen = rxlen; tag.active_sector = sector; tag.state = TAG_STATE_WRITING; break; - + } // Unknown command - default: + default: { Dbprintf("Unknown command: %02x %02x", rx[0], rx[1]); return; - break; + } } } break; @@ -284,15 +288,13 @@ static void hitag2_handle_reader_command(uint8_t *rx, const size_t rxlen, uint8_ // Reset the cipher state hitag2_cipher_reset(&tag, rx); + // Check if the authentication was correct if (!hitag2_cipher_authenticate(&(tag.cs), rx + 4)) { // The reader failed to authenticate, do nothing Dbprintf("auth: %02x%02x%02x%02x%02x%02x%02x%02x Failed!", rx[0], rx[1], rx[2], rx[3], rx[4], rx[5], rx[6], rx[7]); return; } - // Succesful, but commented out reporting back to the Host, this may delay to much. - // Dbprintf("auth: %02x%02x%02x%02x%02x%02x%02x%02x OK!",rx[0],rx[1],rx[2],rx[3],rx[4],rx[5],rx[6],rx[7]); - // Activate encryption algorithm for all further communication tag.crypto_active = 1; @@ -303,15 +305,13 @@ static void hitag2_handle_reader_command(uint8_t *rx, const size_t rxlen, uint8_ break; } - // LogTrace(rx, nbytes(rxlen), 0, 0, NULL, false); - // LogTrace(tx, nbytes(txlen), 0, 0, NULL, true); - if (tag.crypto_active) { hitag2_cipher_transcrypt(&(tag.cs), tx, *txlen / 8, *txlen % 8); } } -// sim +// reader/writer +// returns how long it took static uint32_t hitag_reader_send_bit(int bit) { uint32_t wait = 0; LED_A_ON(); @@ -330,36 +330,41 @@ static uint32_t hitag_reader_send_bit(int bit) { if (bit == 0) { // Zero bit: |_-| - lf_wait_periods(HITAG_T_0-HITAG_T_LOW); // wait for 18-22 times the carrier period - wait += HITAG_T_0-HITAG_T_LOW; + lf_wait_periods(HITAG_T_0 - HITAG_T_LOW); // wait for 18-22 times the carrier period + wait += HITAG_T_0 - HITAG_T_LOW; } else { // One bit: |_--| - lf_wait_periods(HITAG_T_1-HITAG_T_LOW); // wait for 26-32 times the carrier period - wait += HITAG_T_1-HITAG_T_LOW; + lf_wait_periods(HITAG_T_1 - HITAG_T_LOW); // wait for 26-32 times the carrier period + wait += HITAG_T_1 - HITAG_T_LOW; } /*lf_wait_periods(10);*/ LED_A_OFF(); return wait; } -// sim +// reader/writer static uint32_t hitag_reader_send_frame(const uint8_t *frame, size_t frame_len) { + uint32_t wait = 0; // Send the content of the frame for (size_t i = 0; i < frame_len; i++) { wait += hitag_reader_send_bit((frame[i / 8] >> (7 - (i % 8))) & 1); } + // Enable modulation, which means, drop the field lf_modulation(true); + // Wait for 4-10 times the carrier period lf_wait_periods(HITAG_T_LOW); wait += HITAG_T_LOW; + // Disable modulation, just activates the field again lf_modulation(false); // t_stop, high field for stop condition (> 36) lf_wait_periods(HITAG_T_STOP); wait += HITAG_T_STOP; + return wait; } @@ -688,10 +693,10 @@ static bool hitag2_password(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t } if (blocknr > 7) { - DbpString("Read successful!"); bSuccessful = true; return false; } + *txlen = 10; tx[0] = 0xC0 | (blocknr << 3) | ((blocknr ^ 7) >> 2); tx[1] = ((blocknr ^ 7) << 6); @@ -951,7 +956,6 @@ static bool hitag2_read_uid(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t Dbhexdump(4, rx, false); } if (blocknr > 0) { - DbpString("Read successful!"); bSuccessful = true; return false; } @@ -970,10 +974,6 @@ static bool hitag2_read_uid(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t // Hitag2 Sniffing void SniffHitag2(void) { - LEDsoff(); - StopTicks(); - - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); BigBuf_free(); BigBuf_Clear_ext(false); clear_trace(); @@ -988,19 +988,34 @@ void SniffHitag2(void) { DbpString("Starting Hitag2 sniffing"); LED_D_ON(); - lf_init(false); + lf_init(false, false); + logging = false; size_t periods = 0; uint8_t periods_bytes[4]; + int16_t checked = 0; + /*bool waiting_for_first_edge = true;*/ LED_C_ON(); - while (!BUTTON_PRESS() && !data_available()) { + while (!BUTTON_PRESS()) { WDT_HIT(); + // only every 1000th times, in order to save time when collecting samples. + if (checked == 1000) { + if (data_available()) { + checked = -1; + break; + } else { + checked = 0; + } + } + ++checked; + + // Receive frame, watch for at most T0*EOF periods lf_reset_counter(); @@ -1021,69 +1036,57 @@ void SniffHitag2(void) { LogTrace(periods_bytes, 4, 0, 0, NULL, true); } - - /* - // Check if frame was captured - if (rxlen > 0) { - // frame_count++; - LogTrace(rx, nbytes(rxlen), response, 0, NULL, reader_frame); - - // Check if we recognize a valid authentication attempt - if (nbytes(rxlen) == 8) { - // Store the authentication attempt - if (auth_table_len < (AUTH_TABLE_LENGTH - 8)) { - memcpy(auth_table + auth_table_len, rx, 8); - auth_table_len += 8; - } - } - */ } lf_finalize(); - StartTicks(); - DbpString("Hitag2 sniffing finish. Use `lf hitag list` for annotations"); } // Hitag2 simulation void SimulateHitag2(bool tag_mem_supplied, uint8_t *data) { - StopTicks(); - - // int frame_count = 0; - int response = 0, overflow = 0; - uint8_t rx[HITAG_FRAME_LEN]; - size_t rxlen = 0; - uint8_t tx[HITAG_FRAME_LEN]; - size_t txlen = 0; - - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); BigBuf_free(); BigBuf_Clear_ext(false); clear_trace(); set_tracing(true); + // empties bigbuff etc + lf_init(false, true); + + int response = 0; + uint8_t rx[HITAG_FRAME_LEN]; + size_t rxlen = 0; + uint8_t tx[HITAG_FRAME_LEN]; + size_t txlen = 0; + auth_table_len = 0; auth_table_pos = 0; - auth_table = BigBuf_malloc(AUTH_TABLE_LENGTH); - memset(auth_table, 0x00, AUTH_TABLE_LENGTH); +// auth_table = BigBuf_malloc(AUTH_TABLE_LENGTH); +// memset(auth_table, 0x00, AUTH_TABLE_LENGTH); // Reset the received frame, frame count and timing info - memset(rx, 0x00, sizeof(rx)); +// memset(rx, 0x00, sizeof(rx)); +// memset(tx, 0x00, sizeof(tx)); DbpString("Starting Hitag2 simulation"); LED_D_ON(); + + // hitag2 state machine? hitag2_init(); + // copy user supplied emulation data if (tag_mem_supplied) { DbpString("Loading hitag2 memory..."); memcpy((uint8_t *)tag.sectors, data, 48); } + // printing uint32_t block = 0; for (size_t i = 0; i < 12; i++) { + + // num2bytes? for (size_t j = 0; j < 4; j++) { block <<= 8; block |= tag.sectors[i][j]; @@ -1091,89 +1094,137 @@ void SimulateHitag2(bool tag_mem_supplied, uint8_t *data) { Dbprintf("| %d | %08x |", i, block); } - // Set up simulator mode, frequency divisor which will drive the FPGA - // and analog mux selection. - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, LF_DIVISOR_125); //125kHz - SetAdcMuxFor(GPIO_MUXSEL_LOPKD); + uint8_t tag_modulation; + size_t max_nrzs = 8 * HITAG_FRAME_LEN + 5; + uint8_t nrz_samples[max_nrzs]; + size_t nrzs = 0, periods = 0; - // Configure output pin that is connected to the FPGA (for modulating) - AT91C_BASE_PIOA->PIO_OER |= GPIO_SSC_DOUT; - AT91C_BASE_PIOA->PIO_PER |= GPIO_SSC_DOUT; +// uint32_t command_start = 0, command_duration = 0; - // Disable modulation at default, which means release resistance - LOW(GPIO_SSC_DOUT); + int16_t checked = 0; - // Enable Peripheral Clock for - // TIMER_CLOCK0, used to measure exact timing before answering - // TIMER_CLOCK1, used to capture edges of the tag frames - AT91C_BASE_PMC->PMC_PCER |= (1 << AT91C_ID_TC0) | (1 << AT91C_ID_TC1); + while (!BUTTON_PRESS()) { - AT91C_BASE_PIOA->PIO_BSR = GPIO_SSC_FRAME; - - // Disable timer during configuration - AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; - - // TC0: Capture mode, default timer source = MCK/2 (TIMER_CLOCK1), no triggers - AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK; - - // TC1: Capture mode, default timer source = MCK/2 (TIMER_CLOCK1), TIOA is external trigger, - // external trigger rising edge, load RA on rising edge of TIOA. - AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK | AT91C_TC_ETRGEDG_RISING | AT91C_TC_ABETRG | AT91C_TC_LDRA_RISING; - - // Enable and reset counter - AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; - - // synchronized startup procedure - while (AT91C_BASE_TC0->TC_CV > 0) {}; // wait until TC0 returned to zero - - while (!BUTTON_PRESS() && !data_available()) { - // Watchdog hit +loop1: + LED_A_OFF(); WDT_HIT(); - // Receive frame, watch for at most T0*EOF periods - while (AT91C_BASE_TC1->TC_CV < HITAG_T0 * HITAG_T_EOF) { - // Check if rising edge in modulation is detected - if (AT91C_BASE_TC1->TC_SR & AT91C_TC_LDRAS) { - // Retrieve the new timing values - int ra = (AT91C_BASE_TC1->TC_RA / HITAG_T0) + overflow; - overflow = 0; + // only every 1000th times, in order to save time when collecting samples. + if (checked == 100) { + if (data_available()) { + checked = -1; + break; + } else { + checked = 0; + } + } + ++checked; - // Reset timer every frame, we have to capture the last edge for timing - AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; + rxlen = 0; - LED_B_ON(); + // Keep administration of the first edge detection + bool waiting_for_first_edge = true; - // Capture reader frame - if (ra >= HITAG_T_STOP) { - if (rxlen != 0) { - //DbpString("wierd0?"); - } - // Capture the T0 periods that have passed since last communication or field drop (reset) - response = (ra - HITAG_T_LOW); - } else if (ra >= HITAG_T_1_MIN) { - // '1' bit - rx[rxlen / 8] |= 1 << (7 - (rxlen % 8)); - rxlen++; - } else if (ra >= HITAG_T_0_MIN) { - // '0' bit - rx[rxlen / 8] |= 0 << (7 - (rxlen % 8)); - rxlen++; - } else { - // Ignore wierd value, is to small to mean anything + // Did we detected any modulaiton at all + bool detected_tag_modulation = false; + + // Use the current modulation state as starting point + tag_modulation = lf_get_tag_modulation(); + + // Receive frame, watch for at most max_nrzs periods + // Reset the number of NRZ samples and use edge detection to detect them + nrzs = 0; + while (nrzs < max_nrzs) { + // Get the timing of the next edge in number of wave periods + periods = lf_count_edge_periods(128); + + // Just break out of loop after an initial time-out (tag is probably not available) + // The function lf_count_edge_periods() returns 0 when a time-out occurs + if (periods == 0) { + goto loop1; //break; + } + + LED_A_ON(); + + // Are we dealing with the first incoming edge + if (waiting_for_first_edge) { + + // Register the number of periods that have passed + response = periods; + + // Indicate that we have dealt with the first edge + waiting_for_first_edge = false; + + // The first edge is always a single NRZ bit, force periods on 16 + periods = 16; + + // We have received more than 0 periods, so we have detected a tag response + detected_tag_modulation = true; + } + + // Evaluate the number of periods before the next edge + if (periods > 24 && periods <= 64) { + // Detected two sequential equal bits and a modulation switch + // NRZ modulation: (11 => --|) or (11 __|) + nrz_samples[nrzs++] = tag_modulation; + nrz_samples[nrzs++] = tag_modulation; + // Invert tag modulation state + tag_modulation ^= 1; + } else if (periods > 0 && periods <= 24) { + // Detected one bit and a modulation switch + // NRZ modulation: (1 => -|) or (0 _|) + nrz_samples[nrzs++] = tag_modulation; + tag_modulation ^= 1; + } else { + tag_modulation ^= 1; + // The function lf_count_edge_periods() returns > 64 periods, this is not a valid number periods + Dbprintf("Detected unexpected period count: %d", periods); + break; + } + } + + // If there is no response, just repeat the loop + if (!detected_tag_modulation) continue; + + // Make sure we always have an even number of samples. This fixes the problem + // of ending the manchester decoding with a zero. See the example below where + // the '|' character is end of modulation + // One at the end: ..._-|_____... + // Zero at the end: ...-_|_____... + // The last modulation change of a zero is not detected, but we should take + // the half period in account, otherwise the demodulator will fail. + if ((nrzs % 2) != 0) { + nrz_samples[nrzs++] = tag_modulation; + } + + LED_B_ON(); + + // decode bitstream + manrawdecode((uint8_t *)nrz_samples, &nrzs, true, 0); + + // Verify if the header consists of five consecutive ones + if (nrzs < 5) { + Dbprintf("Detected unexpected number of manchester decoded samples [%d]", nrzs); + continue; + } else { + for (size_t i = 0; i < 5; i++){ + if (nrz_samples[i] != 1) { + Dbprintf("Detected incorrect header, the bit [%d] is zero instead of one", i); } } } + // Pack the response into a byte array + for (size_t i = 5; i < 37; i++){ + uint8_t bit = nrz_samples[i]; + rx[rxlen / 8] |= bit << (7 - (rxlen % 8)); + rxlen++; + } + // Check if frame was captured if (rxlen > 4) { - // frame_count++; - LogTrace(rx, nbytes(rxlen), response, response, NULL, true); - // Disable timer 1 with external trigger to avoid triggers during our own modulation - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; + LogTrace(rx, nbytes(rxlen), response, 0, NULL, true); // Process the incoming frame (rx) and prepare the outgoing frame (tx) hitag2_handle_reader_command(rx, rxlen, tx, &txlen); @@ -1183,11 +1234,15 @@ void SimulateHitag2(bool tag_mem_supplied, uint8_t *data) { // with respect to the falling edge, we need to wait actually (T_Wait1 - T_Low) // periods. The gap time T_Low varies (4..10). All timer values are in // terms of T0 units - while (AT91C_BASE_TC0->TC_CV < HITAG_T0 * (HITAG_T_WAIT_1_MIN - HITAG_T_LOW)); + lf_wait_periods(200); // Send and store the tag answer (if there is any) if (txlen) { - hitag_send_frame(tx, txlen); + // Transmit the tag frame + //hitag_send_frame(tx, txlen); + lf_manchester_send_bytes(tx, txlen); + + // Store the frame in the trace LogTrace(tx, nbytes(txlen), 0, 0, NULL, false); } @@ -1195,37 +1250,22 @@ void SimulateHitag2(bool tag_mem_supplied, uint8_t *data) { memset(rx, 0x00, sizeof(rx)); response = 0; - // Enable and reset external trigger in timer for capturing future frames - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; LED_B_OFF(); } - // Reset the frame length - rxlen = 0; - // Save the timer overflow, will be 0 when frame was received - overflow += (AT91C_BASE_TC1->TC_CV / HITAG_T0); - // Reset the timer to restart while-loop that receives frames - AT91C_BASE_TC1->TC_CCR = AT91C_TC_SWTRG; } - LEDsoff(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - set_tracing(false); - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; - AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; + lf_finalize(); // release allocated memory from BigBuff. BigBuf_free(); - StartTicks(); + DbpString("Sim stopped"); - DbpString("Sim Stopped"); +// reply_ng(CMD_LF_HITAG_SIMULATE, (checked == -1) ? PM3_EOPABORTED : PM3_SUCCESS, (uint8_t *)tag.sectors, tag_size); } void ReaderHitag(hitag_function htf, hitag_data *htd) { - StopTicks(); - - int frame_count = 0; uint32_t command_start = 0; uint32_t command_duration = 0; uint32_t response_start = 0; @@ -1261,9 +1301,8 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { // this part will be unreadable memset(tag.sectors + 2, 0x0, 30); blocknr = 0; + break; } - break; - case RHT1F_AUTHENTICATE: { Dbprintf("Read all blocks in authed mode"); memcpy(nonce, htd->ht1auth.nonce, 4); @@ -1284,8 +1323,8 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { DbpString("Logdata_1:"); Dbhexdump(4, logdata_1, false); blocknr = 0; + break; } - break; case RHT2F_PASSWORD: { Dbprintf("List identifier in password mode"); if (memcmp(htd->pwd.password, "\x00\x00\x00\x00", 4) == 0) @@ -1334,17 +1373,17 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { default: { Dbprintf("Error, unknown function: %d", htf); set_tracing(false); - StartTicks(); return; } } LED_D_ON(); + // hitag2 state machine? hitag2_init(); // init as reader - lf_init(true); + lf_init(true, false); uint8_t attempt_count = 0; @@ -1379,24 +1418,34 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { size_t max_nrzs = (8 * HITAG_FRAME_LEN + 5) * 2; // up to 2 nrzs per bit uint8_t nrz_samples[max_nrzs]; size_t nrzs = 0; + int16_t checked = 0; - while (!bStop && !BUTTON_PRESS() && !data_available()) { + while (!bStop) { WDT_HIT(); + // only every 1000th times, in order to save time when collecting samples. + if (checked == 1000) { + if (BUTTON_PRESS() || data_available()) { + checked = -1; + break; + } else { + checked = 0; + } + } + ++checked; + // By default reset the transmission buffer tx = txbuf; switch (htf) { case RHT1F_PLAIN: { bStop = !hitag_plain(rx, rxlen, tx, &txlen, false); + break; } - break; - case RHT1F_AUTHENTICATE: { bStop = !hitag1_authenticate(rx, rxlen, tx, &txlen); + break; } - break; - case RHT2F_PASSWORD: { bStop = !hitag2_password(rx, rxlen, tx, &txlen, false); break; @@ -1512,7 +1561,6 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { // and to be able to overwrite the first samples with the trace (since they currently // still use the same memory space) if (txlen > 0) { - frame_count++; LogTrace(tx, nbytes(txlen), command_start, command_start + command_duration, NULL, true); } @@ -1543,7 +1591,7 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { // Verify if the header consists of five consecutive ones if (nrzs < 5) { - //Dbprintf("Detected unexpected number of manchester decoded samples [%d]", nrzs); + Dbprintf("Detected unexpected number of manchester decoded samples [%d]", nrzs); break; } else { size_t i; @@ -1560,51 +1608,43 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { for (size_t i = 5; i < nrzs; i++) { uint8_t bit = nrz_samples[i]; if (bit > 1) { // When Manchester detects impossible symbol it writes "7" - //Dbprintf("Error in Manchester decoding, abort"); + Dbprintf("Error in Manchester decoding, abort"); break; } rx[rxlen / 8] |= bit << (7 - (rxlen % 8)); rxlen++; } + if (rxlen % 8 == 1) // skip spurious bit rxlen--; // Check if frame was captured and store it if (rxlen > 0) { - frame_count++; -// if (bCollision){ -// // AC decoding hack -// fix_ac_decoding(rx, 64); -// rxlen = 32; -// } LogTrace(rx, nbytes(rxlen), response_start, response_start + response_duration, NULL, false); + // TODO when using cumulative time for command_start, pm3 doesn't reply anymore, e.g. on lf hitag read 23 4F4E4D494B52 - command_start = response_start + response_duration; -// command_start = 0; - // Dbhexdump(nbytes(rxlen), rx, false); +// Use delta time? +// command_start = response_start + response_duration; + command_start = 0; + nrzs = 0; } } out: lf_finalize(); - Dbprintf("TX/RX frames recorded: %u", frame_count); // release allocated memory from BigBuff. BigBuf_free(); - StartTicks(); if (bSuccessful) - reply_old(CMD_ACK, bSuccessful, 0, 0, (uint8_t *)tag.sectors, tag_size); + reply_mix(CMD_ACK, bSuccessful, 0, 0, (uint8_t *)tag.sectors, tag_size); else reply_mix(CMD_ACK, bSuccessful, 0, 0, 0, 0); } void WriterHitag(hitag_function htf, hitag_data *htd, int page) { - StopTicks(); - - int frame_count = 0; uint32_t command_start = 0; uint32_t command_duration = 0; uint32_t response_start = 0; @@ -1659,7 +1699,6 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) { break; default: { Dbprintf("Error, unknown function: %d", htf); - StartTicks(); return; } break; @@ -1670,7 +1709,7 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) { hitag2_init(); // init as reader - lf_init(true); + lf_init(true, false); // Tag specific configuration settings (sof, timings, etc.) if (htf < 10) { @@ -1704,7 +1743,19 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) { uint8_t nrz_samples[max_nrzs]; size_t nrzs = 0; - while (!bStop && !BUTTON_PRESS() && !data_available()) { + int16_t checked = 0; + while (!bStop) { + + // only every 1000th times, in order to save time when collecting samples. + if (checked == 1000) { + if (BUTTON_PRESS() || data_available()) { + checked = -1; + break; + } else { + checked = 0; + } + } + ++checked; WDT_HIT(); @@ -1731,7 +1782,7 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) { // Transmit the reader frame command_duration = hitag_reader_send_frame(tx, txlen); - + response_start = command_start + command_duration; // Let the antenna and ADC values settle @@ -1814,7 +1865,6 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) { // and to be able to overwrite the first samples with the trace (since they currently // still use the same memory space) if (txlen > 0) { - frame_count++; LogTrace(tx, nbytes(txlen), command_start, command_start + command_duration, NULL, true); } @@ -1872,8 +1922,6 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) { // Check if frame was captured and store it if (rxlen > 0) { - frame_count++; - LogTrace(rx, nbytes(rxlen), response_start, response_start + response_duration, NULL, false); command_start = 0; } @@ -1882,11 +1930,9 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) { out: lf_finalize(); - Dbprintf("TX/RX frames recorded: %u", frame_count); // release allocated memory from BigBuff. BigBuf_free(); - StartTicks(); - + reply_mix(CMD_ACK, bSuccessful, 0, 0, (uint8_t *)tag.sectors, tag_size); } From 60b444d5d83f1688b4a19352c2c2d8e714c17e09 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 29 Jan 2020 08:18:45 +0100 Subject: [PATCH 1517/1854] no inline --- armsrc/lfadc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/armsrc/lfadc.c b/armsrc/lfadc.c index 60044b6d8..a15aa429b 100644 --- a/armsrc/lfadc.c +++ b/armsrc/lfadc.c @@ -215,11 +215,11 @@ void lf_finalize() { FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); - + sample_config *sc = getSamplingConfig(); sc->decimation = 1; sc->averaging = 0; - + StartTicks(); } @@ -260,7 +260,7 @@ size_t lf_detect_field_drop(size_t max) { return 0; } -inline void lf_modulation(bool modulation) { +void lf_modulation(bool modulation) { if (modulation) { HIGH(GPIO_SSC_DOUT); } else { @@ -269,7 +269,7 @@ inline void lf_modulation(bool modulation) { } // simulation -inline void lf_manchester_send_bit(uint8_t bit) { +static void lf_manchester_send_bit(uint8_t bit) { lf_modulation(bit != 0); lf_wait_periods(16); lf_modulation(bit == 0); From 996b41dce7e69b9ac83aa169a2b2946a877b8035 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 29 Jan 2020 15:16:50 +0100 Subject: [PATCH 1518/1854] chg: write serial port in window title (plot/slider) --- client/comms.c | 5 +++++ client/comms.h | 3 +++ client/proxgui.h | 7 +++++++ client/proxguiqt.cpp | 13 ++++++++++++- client/ui/overlays.ui | 2 +- 5 files changed, 28 insertions(+), 2 deletions(-) diff --git a/client/comms.c b/client/comms.c index 9b031eb9e..ce8223ba3 100644 --- a/client/comms.c +++ b/client/comms.c @@ -24,6 +24,8 @@ //#define COMMS_DEBUG //#define COMMS_DEBUG_RAW +uint8_t gui_serial_port_name[FILE_PATH_SIZE]; + // Serial port that we are communicating with the PM3 on. static serial_port sp = NULL; @@ -568,6 +570,9 @@ bool OpenProxmark(void *port, bool wait_for_port, int timeout, bool flash_mode, uint16_t len = MIN(strlen(portname), FILE_PATH_SIZE - 1); memset(conn.serial_port_name, 0, FILE_PATH_SIZE); memcpy(conn.serial_port_name, portname, len); + + memset(gui_serial_port_name, 0, FILE_PATH_SIZE); + memcpy(gui_serial_port_name, portname, len); } conn.run = true; conn.block_after_ACK = flash_mode; diff --git a/client/comms.h b/client/comms.h index eaf9a16c0..288e8a326 100644 --- a/client/comms.h +++ b/client/comms.h @@ -44,6 +44,7 @@ typedef enum { FPGA_MEM, } DeviceMemType_t; + typedef struct { bool run; // If TRUE, continue running the uart_communication thread bool block_after_ACK; // if true, block after receiving an ACK package @@ -60,6 +61,8 @@ typedef struct { extern communication_arg_t conn; +extern uint8_t gui_serial_port_name[FILE_PATH_SIZE]; + void *uart_receiver(void *targ); void SendCommandBL(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len); void SendCommandOLD(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len); diff --git a/client/proxgui.h b/client/proxgui.h index c4adbeb01..8e0868b12 100644 --- a/client/proxgui.h +++ b/client/proxgui.h @@ -18,6 +18,7 @@ extern "C" { #include #include #include +//#include "comms.h" void ShowGraphWindow(void); void HideGraphWindow(void); @@ -55,6 +56,12 @@ extern size_t g_DemodStartIdx; extern bool showDemod; extern uint8_t g_debugMode; + +#ifndef FILE_PATH_SIZE +#define FILE_PATH_SIZE 1000 +#endif +extern uint8_t gui_serial_port_name[FILE_PATH_SIZE]; + #ifdef __cplusplus } #endif diff --git a/client/proxguiqt.cpp b/client/proxguiqt.cpp index 6bf99f5a1..a481f31d2 100644 --- a/client/proxguiqt.cpp +++ b/client/proxguiqt.cpp @@ -197,11 +197,22 @@ ProxWidget::ProxWidget(QWidget *parent, ProxGuiQT *master) : QWidget(parent) { QVBoxLayout *layout = new QVBoxLayout; layout->addWidget(plot); setLayout(layout); - show(); // places the window on the screen. + + // plot window title + QString pt = QString("[*]Plot [ %1 ]").arg((char*)gui_serial_port_name); + setWindowTitle(pt); + + // shows plot window on the screen. + show(); // Move controller widget below plot controlWidget->move(x(), y() + frameSize().height()); controlWidget->resize(size().width(), 200); + + // Olverlays / slider window title + QString ct = QString("[*]Slider [ %1 ]").arg((char*)gui_serial_port_name); + controlWidget->setWindowTitle(ct); + controlWidget->show(); } diff --git a/client/ui/overlays.ui b/client/ui/overlays.ui index 7cc9043e7..a262e5b93 100644 --- a/client/ui/overlays.ui +++ b/client/ui/overlays.ui @@ -11,7 +11,7 @@ - Overlays + Sliders From b2f368c2c198f9eece32f92c3906b40e09d02003 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 29 Jan 2020 15:18:50 +0100 Subject: [PATCH 1519/1854] textual --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ca80d078f..a9f5c51a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Change `data plot` - write serial port name in window title for plot / slider window (@iceman1001) - Added `hf lto wrbl` - write block support for LTO Cartridge memory (@Kevin-Nakamoto) - Fix compilation under openSUSE (@hsanjuan) - Added `lf nexwatch sim` - use raw hex to simulate (@iceman1001) From 9448ec40523cae5ec57fa9bd247b4b3385910cce Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 29 Jan 2020 17:26:08 +0100 Subject: [PATCH 1520/1854] hitagstuff --- armsrc/lfadc.c | 10 ++++++---- armsrc/lfadc.h | 3 +++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/armsrc/lfadc.c b/armsrc/lfadc.c index a15aa429b..04f293e1d 100644 --- a/armsrc/lfadc.c +++ b/armsrc/lfadc.c @@ -60,7 +60,6 @@ size_t lf_count_edge_periods_ex(size_t max, bool wait, bool detect_gap) { // only every 100th times, in order to save time when collecting samples. if (checked == 1000) { if (data_available()) { - checked = -1; break; } else { checked = 0; @@ -77,7 +76,7 @@ size_t lf_count_edge_periods_ex(size_t max, bool wait, bool detect_gap) { if (logging) logSampleSimple(adc_val); // Only test field changes if state of adc values matter - if (!wait) { + if (wait == false) { // Test if we are locating a field modulation (100% ASK = complete field drop) if (detect_gap) { // Only return when the field completely dissapeared @@ -132,6 +131,9 @@ void lf_reset_counter() { bool lf_get_tag_modulation() { return (rising_edge == false); } +bool lf_get_reader_modulation() { + return rising_edge; +} void lf_wait_periods(size_t periods) { lf_count_edge_periods_ex(periods, true, false); @@ -228,11 +230,11 @@ size_t lf_detect_field_drop(size_t max) { volatile uint8_t adc_val; int16_t checked = 0; - while (true) { + while (!BUTTON_PRESS()) { // only every 1000th times, in order to save time when collecting samples. if (checked == 1000) { - if (BUTTON_PRESS() || data_available()) { + if (data_available()) { checked = -1; break; } else { diff --git a/armsrc/lfadc.h b/armsrc/lfadc.h index d394916ea..8c33aa778 100644 --- a/armsrc/lfadc.h +++ b/armsrc/lfadc.h @@ -21,7 +21,10 @@ bool lf_test_periods(size_t expected, size_t count); size_t lf_count_edge_periods(size_t max); size_t lf_detect_gap(size_t max); void lf_reset_counter(); + bool lf_get_tag_modulation(); +bool lf_get_reader_modulation(); + void lf_wait_periods(size_t periods); //void lf_init(bool reader); void lf_init(bool reader, bool simulate); From e25300843e23c662f41d394edf885a04eb4ffddc Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 29 Jan 2020 17:30:42 +0100 Subject: [PATCH 1521/1854] chg: fchk/chk keys - tiny bit faster --- armsrc/mifareutil.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/armsrc/mifareutil.c b/armsrc/mifareutil.c index e115e965f..b0bf532b0 100644 --- a/armsrc/mifareutil.c +++ b/armsrc/mifareutil.c @@ -194,8 +194,8 @@ int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockN uint32_t save_timeout = iso14a_get_timeout(); // set timeout for authentication response - if (save_timeout > 106) - iso14a_set_timeout(106); + if (save_timeout > 103) + iso14a_set_timeout(103); // Receive 4 byte tag answer len = ReaderReceive(receivedAnswer, receivedAnswerPar); From d5b21cbdd969e269f30014d7f30c2972a8f6807f Mon Sep 17 00:00:00 2001 From: Kevin-Nakamoto Date: Wed, 29 Jan 2020 13:38:24 -0500 Subject: [PATCH 1522/1854] added hf lto dump --- CHANGELOG.md | 1 + client/cmdhflto.c | 97 ++++++++++++++++++++++++++++++++++++++++------- client/cmdhflto.h | 1 + 3 files changed, 86 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a9f5c51a1..828538e8d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Added `hf lto dump` - dump 8160 bytes of data from LTO cartridge memory and save to file (@Kevin-Nakamoto) - Change `data plot` - write serial port name in window title for plot / slider window (@iceman1001) - Added `hf lto wrbl` - write block support for LTO Cartridge memory (@Kevin-Nakamoto) - Fix compilation under openSUSE (@hsanjuan) diff --git a/client/cmdhflto.c b/client/cmdhflto.c index b717eab46..d38cfdf25 100644 --- a/client/cmdhflto.c +++ b/client/cmdhflto.c @@ -20,6 +20,9 @@ #include "ui.h" #include "cmdhf14a.h" #include "protocols.h" +#include "fileutils.h" //saveFile + +#define CM_MEM_MAX_SIZE 0x1FE0 // (32byte/block * 255block = 8160byte) static int CmdHelp(const char *Cmd); @@ -58,6 +61,17 @@ static int usage_lto_wrbl(void) { return PM3_SUCCESS; } +static int usage_lto_dump(void) { + PrintAndLogEx(NORMAL, "Usage: hf lto dump [h|p] f "); + PrintAndLogEx(NORMAL, "Options:"); + PrintAndLogEx(NORMAL, " h this help"); + PrintAndLogEx(NORMAL, " f file name"); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Examples:"); + PrintAndLogEx(NORMAL, " hf lto dump f myfile"); + return PM3_SUCCESS; +} + static void lto_switch_off_field(void) { SendCommandMIX(CMD_HF_ISO14443A_READER, 0, 0, 0, NULL, 0); } @@ -386,7 +400,7 @@ static int CmdHfLTOWriteBlock(const char *Cmd) { break; } } - + //Validations if (errors) { usage_lto_wrbl(); @@ -399,20 +413,60 @@ static int CmdHfLTOWriteBlock(const char *Cmd) { return wrblLTO(blk, blkData, true); } -/* +int dumpLTO(uint8_t *serial_number, uint8_t serial_len, uint8_t *dump, bool verbose) { + + clearCommandBuffer(); + lto_switch_on_field(); + + uint8_t type_info[2]; + int ret_val = lto_select(serial_number, serial_len, type_info, verbose); + + if (ret_val != PM3_SUCCESS) { + lto_switch_off_field(); + return ret_val; + } + + uint8_t block_data_d00_d15[18]; + uint8_t block_data_d16_d31[18]; + + for(uint8_t i = 0; i < 255; i++) { + + ret_val = lto_rdbl(i, block_data_d00_d15, block_data_d16_d31, verbose); + + if (ret_val == PM3_SUCCESS) { + //Remove CRCs + for (int t = 0; t < 16; t++) { + dump[t + i * 32] = block_data_d00_d15[t]; + dump[t + i * 32 + 16] = block_data_d16_d31[t]; + } + } else { + lto_switch_off_field(); + return ret_val; + } + } + + lto_switch_off_field(); + return ret_val; +} + static int CmdHfLTODump(const char *Cmd) { uint8_t cmdp = 0; bool errors = false; - uint8_t blk = 128; + uint32_t dump_len = CM_MEM_MAX_SIZE; + char filename[FILE_PATH_SIZE] = {0}; + uint8_t serial_number[5] = {0}; while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { case 'h': return usage_lto_dump(); - case 'b': - blk = param_get8(Cmd, cmdp+1); - b_opt_selected = true; + case 'f': + if (param_getstr(Cmd, cmdp + 1, filename, FILE_PATH_SIZE) >= FILE_PATH_SIZE) { + PrintAndLogEx(FAILED, "filename too long"); + errors = true; + break; + } cmdp += 2; break; default: @@ -428,19 +482,36 @@ static int CmdHfLTODump(const char *Cmd) { return PM3_EINVARG; } -// alloc memory -// loop all blocks -// save to file -// free memory + // alloc memory + uint8_t *dump = calloc(dump_len, sizeof(uint8_t)); + if (!dump) { + PrintAndLogEx(ERR, "error, cannot allocate memory"); + return PM3_EMALLOC; + } + + // loop all blocks + int ret_val = dumpLTO(serial_number, sizeof(serial_number), dump, true); + if (ret_val != PM3_SUCCESS) { + free(dump); + return ret_val; + } + + // save to file + if (filename[0] == '\0') { + memcpy(filename, sprint_hex_inrow(serial_number, sizeof(serial_number)), sizeof(serial_number) * 2); + } + saveFile(filename, ".bin", dump, dump_len); + saveFileEML(filename, dump, dump_len, 32); + + // free memory + free(dump); return PM3_SUCCESS; } -*/ - static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, -// {"dump", CmdHfLTDump, IfPm3Iso14443a, "Dump LTO-CM tag to file"}, + {"dump", CmdHfLTODump, IfPm3Iso14443a, "Dump LTO-CM tag to file"}, // {"restore", CmdHfLTRestore, IfPm3Iso14443a, "Restore dump file to LTO-CM tag"}, {"info", CmdHfLTOInfo, IfPm3Iso14443a, "Tag information"}, {"rdbl", CmdHfLTOReadBlock, IfPm3Iso14443a, "Read block"}, diff --git a/client/cmdhflto.h b/client/cmdhflto.h index bc35d4378..2b771f0d8 100644 --- a/client/cmdhflto.h +++ b/client/cmdhflto.h @@ -14,6 +14,7 @@ #include "common.h" int infoLTO(bool verbose); +int dumpLTO(uint8_t *serial_number, uint8_t serial_len, uint8_t *dump, bool verbose); int rdblLTO(uint8_t st_blk, uint8_t end_blk, bool verbose); int wrblLTO(uint8_t blk, uint8_t *data, bool verbose); int CmdHFLTO(const char *Cmd); From 833bed7768d7a82297bde815057094e5b45cdbec Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 29 Jan 2020 23:19:05 +0200 Subject: [PATCH 1523/1854] rdp false (+8 squashed commit) Squashed commit: [eb50dade] null err too [f2a413e0] add null [5a38073e] check [efa602f7] MAYBE_FIRST_START [5ab8cc1f] gcc make [7c4aed4d] pacman suu [5e2efdf7] install make [9d22d09c] tst --- appveyor.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/appveyor.yml b/appveyor.yml index a817ff1ac..5070438c9 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -141,6 +141,10 @@ clone_script: ExecUpdate "update1" "C:\ProxSpace\msys2\msys2_shell.cmd -mingw32 -defterm -no-start /dev/null" "terminate?MSYS2" ExecUpdate "update2" "C:\ProxSpace\msys2\msys2_shell.cmd -mingw32 -defterm -no-start /dev/null" "terminate?MSYS2" + + bash -c -i 'pacman -S mingw-w64-i686-readline mingw-w64-i686-gcc git make pkg-config mingw-w64-i686-qt5 --noconfirm' 2>&1>$null + + bash -c -i 'pacman -Suu --noconfirm' 2>&1>$null Write-Host "Update " -NoNewLine From 01560dda8194d0726e535d01204ea0e8f0f32cfc Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 30 Jan 2020 09:20:10 +0100 Subject: [PATCH 1524/1854] textual --- client/mifare/mifarehost.c | 61 +++++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 24 deletions(-) diff --git a/client/mifare/mifarehost.c b/client/mifare/mifarehost.c index 3586db8df..31085a629 100644 --- a/client/mifare/mifarehost.c +++ b/client/mifare/mifarehost.c @@ -34,10 +34,10 @@ int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) { bool first_run = true; // message - PrintAndLogEx(NORMAL, "--------------------------------------------------------------------------------\n"); - PrintAndLogEx(NORMAL, "executing Darkside attack. Expected execution time: 25sec on average"); - PrintAndLogEx(NORMAL, "press pm3-button on the Proxmark3 device to abort both Proxmark3 and client."); - PrintAndLogEx(NORMAL, "--------------------------------------------------------------------------------\n"); + PrintAndLogEx(INFO, "--------------------------------------------------------------------------------\n"); + PrintAndLogEx(INFO, "executing Darkside attack. Expected execution time: 25sec on average"); + PrintAndLogEx(INFO, "press pm3-button on the Proxmark3 device to abort both Proxmark3 and client."); + PrintAndLogEx(INFO, "--------------------------------------------------------------------------------\n"); while (true) { clearCommandBuffer(); @@ -288,9 +288,17 @@ int mfCheckKeys_file(uint8_t *destfn, uint64_t *key) { uint8_t retry = 10; while (!WaitForResponseTimeout(CMD_HF_MIFARE_CHKKEYS, &resp, 2000)) { + + //flush queue + while (kbd_enter_pressed()) { + SendCommandNG(CMD_BREAK_LOOP, NULL, 0); + return PM3_EOPABORTED; + } + retry--; - if (retry ==0) { + if (retry == 0) { PrintAndLogEx(WARNING, "Chk keys file, timeouted"); + SendCommandNG(CMD_BREAK_LOOP, NULL, 0); return PM3_ETIMEOUT; } } @@ -536,11 +544,11 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, return -5; } - float bruteforce_per_second = (float)KEYS_IN_BLOCK / (float)(msclock() - start_time) * 1000.0; - start_time = msclock(); + uint64_t t2 = msclock(); + float bruteforce_per_second = (float)KEYS_IN_BLOCK / (float)(t2 - start_time) * 1000.0; if ( i + 1 % 10 == 0) - PrintAndLogEx(INFO, " %8d/%u keys | %5.1f keys/sec | worst case %6.1f seconds remaining", i, keycnt , bruteforce_per_second, (keycnt-i) / bruteforce_per_second); + PrintAndLogEx(INFO, " %6d/%u keys | %5.1f keys/sec | worst case %6.1f seconds remaining", i, keycnt , bruteforce_per_second, (keycnt-i) / bruteforce_per_second); } @@ -643,8 +651,8 @@ int mfStaticNested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBl uint64_t key64 = -1; // The list may still contain several key candidates. Test each of them with mfCheckKeys - uint32_t maxkeysinblock = IfPm3Flash() ? 1600 : KEYS_IN_BLOCK; - uint32_t max_keys_slice = keycnt > maxkeysinblock ? maxkeysinblock : keycnt; + uint32_t maxkeysinblock = IfPm3Flash() ? 1000 : KEYS_IN_BLOCK; + uint32_t max_keys_chunk = keycnt > maxkeysinblock ? maxkeysinblock : keycnt; uint8_t *mem = calloc( (maxkeysinblock * 6) + 5, sizeof(uint8_t)); if (mem == NULL) { @@ -656,22 +664,27 @@ int mfStaticNested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBl mem[0] = statelists[0].keyType; mem[1] = statelists[0].blockNo; mem[2] = 1; - mem[3] = ((maxkeysinblock >> 8) & 0xFF); - mem[4] = (maxkeysinblock & 0xFF); + mem[3] = ((max_keys_chunk >> 8) & 0xFF); + mem[4] = (max_keys_chunk & 0xFF); uint8_t destfn[32]; strncpy((char*)destfn, "static_nested_000.bin", sizeof(destfn) - 1); - for (uint32_t i = 0; i < keycnt; i += max_keys_slice) { + uint64_t start_time = msclock(); + for (uint32_t i = 0; i < keycnt; i += max_keys_chunk) { + + //flush queue + while (kbd_enter_pressed()) { + SendCommandNG(CMD_BREAK_LOOP, NULL, 0); + return PM3_EOPABORTED; + } int res = 0; - uint64_t start_time = msclock(); - key64 = 0; - uint32_t size = keycnt - i > max_keys_slice ? max_keys_slice : keycnt - i; + uint32_t chunk = keycnt - i > max_keys_chunk ? max_keys_chunk : keycnt - i; // copy x keys to device. - for (uint32_t j = 0; j < size; j++) { + for (uint32_t j = 0; j < chunk; j++) { crypto1_get_lfsr(statelists[0].head.slhead + i + j, &key64); num_to_bytes(key64, 6, p_keyblock + j * 6); } @@ -679,7 +692,7 @@ int mfStaticNested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBl // check a block of generated candidate keys. if (IfPm3Flash()) { // upload to flash. - res = flashmem_spiffs_load(destfn, mem, 5 + (size * 6) ); + res = flashmem_spiffs_load(destfn, mem, 5 + (chunk * 6) ); if (res != PM3_SUCCESS) { PrintAndLogEx(WARNING, "SPIFFS upload failed"); return res; @@ -687,7 +700,7 @@ int mfStaticNested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBl res = mfCheckKeys_file(destfn, &key64); } else { - res = mfCheckKeys(statelists[0].blockNo, statelists[0].keyType, false, size, mem, &key64); + res = mfCheckKeys(statelists[0].blockNo, statelists[0].keyType, false, chunk, mem, &key64); } if (res == PM3_SUCCESS) { @@ -703,14 +716,14 @@ int mfStaticNested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBl sprint_hex_inrow(resultKey, 6) ); return PM3_SUCCESS; - } else if (res == PM3_ETIMEOUT) { + } else if (res == PM3_ETIMEOUT || res == PM3_EOPABORTED) { return res; } - float bruteforce_per_second = (float)maxkeysinblock / (float)(msclock() - start_time) * 1000.0; - start_time = msclock(); - - PrintAndLogEx(INFO, "Chunk %8u/%u keys | %5.1f keys/sec | worst case %6.1f seconds remaining", i, keycnt, bruteforce_per_second, (keycnt-i) / bruteforce_per_second); +// if (i%10 == 0) { + float bruteforce_per_second = (float)i + max_keys_chunk / (float)(msclock() - start_time) * 1000.0; + PrintAndLogEx(INFO, "Chunk %6u/%u keys | %5.1f keys/sec | worst case %6.1f seconds remaining", i, keycnt, bruteforce_per_second, (keycnt-i) / bruteforce_per_second); +// } } p_keyblock = NULL; From 75841e7b20d79a825349b1984923e65765add860 Mon Sep 17 00:00:00 2001 From: Michael Farrell Date: Thu, 30 Jan 2020 21:00:22 +1100 Subject: [PATCH 1525/1854] fix: logic inversion in loadFileDICTIONARY_safe use of CheckStringIsHEXValue --- client/fileutils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/fileutils.c b/client/fileutils.c index 982b0f753..d9e6e4445 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -1016,7 +1016,7 @@ int loadFileDICTIONARY_safe(const char *preferredName, void **pdata, uint8_t key if (line[0] == '#') continue; - if (CheckStringIsHEXValue(line)) + if (!CheckStringIsHEXValue(line)) continue; uint64_t key = strtoull(line, NULL, 16); From 4c76d54c9a924d9da72bffc0b3d46f783ca84845 Mon Sep 17 00:00:00 2001 From: Michael Farrell Date: Thu, 30 Jan 2020 21:41:09 +1100 Subject: [PATCH 1526/1854] add standalone module for sniffing iso14a to flash This module is intentionally simple, and doesn't do anything fancy. --- armsrc/Standalone/Makefile.hal | 7 +- armsrc/Standalone/Makefile.inc | 5 +- armsrc/Standalone/hf_14asniff.c | 124 ++++++++++++++++++++++++++++++++ 3 files changed, 133 insertions(+), 3 deletions(-) create mode 100644 armsrc/Standalone/hf_14asniff.c diff --git a/armsrc/Standalone/Makefile.hal b/armsrc/Standalone/Makefile.hal index f082dd117..fb952179a 100644 --- a/armsrc/Standalone/Makefile.hal +++ b/armsrc/Standalone/Makefile.hal @@ -35,13 +35,16 @@ define KNOWN_STANDALONE_DEFINITIONS | HF_BOG | 14a sniff with ULC/ULEV1/NTAG auth | | (RDV4 only) | storing in flashmem - Bogito | +----------------------------------------------------------+ +| HF_14ASNIFF | 14a sniff to flashmem | +| (RDV4 only) | | ++----------------------------------------------------------+ endef STANDALONE_MODES := LF_SAMYRUN LF_ICERUN LF_PROXBRUTE LF_HIDBRUTE -STANDALONE_MODES += HF_YOUNG HF_MATTYRUN HF_COLIN HF_BOG +STANDALONE_MODES += HF_YOUNG HF_MATTYRUN HF_COLIN HF_BOG HF_14ASNIFF STANDALONE_MODES_REQ_SMARTCARD := -STANDALONE_MODES_REQ_FLASH := HF_COLIN HF_BOG +STANDALONE_MODES_REQ_FLASH := HF_COLIN HF_BOG HF_14ASNIFF ifneq ($(filter $(STANDALONE),$(STANDALONE_MODES)),) STANDALONE_PLATFORM_DEFS += -DWITH_STANDALONE_$(STANDALONE) ifneq ($(filter $(STANDALONE),$(STANDALONE_MODES_REQ_SMARTCARD)),) diff --git a/armsrc/Standalone/Makefile.inc b/armsrc/Standalone/Makefile.inc index 66dfc6da2..c7c5ff327 100644 --- a/armsrc/Standalone/Makefile.inc +++ b/armsrc/Standalone/Makefile.inc @@ -33,4 +33,7 @@ endif ifneq (,$(findstring WITH_STANDALONE_HF_BOG,$(APP_CFLAGS))) SRC_STANDALONE = hf_bog.c endif - +# WITH_STANDALONE_HF_14ASNIFF +ifneq (,$(findstring WITH_STANDALONE_HF_14ASNIFF,$(APP_CFLAGS))) + SRC_STANDALONE = hf_14asniff.c +endif diff --git a/armsrc/Standalone/hf_14asniff.c b/armsrc/Standalone/hf_14asniff.c new file mode 100644 index 000000000..d8bf6ab82 --- /dev/null +++ b/armsrc/Standalone/hf_14asniff.c @@ -0,0 +1,124 @@ +//----------------------------------------------------------------------------- +// Copyright 2020 Michael Farrell +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// main code for standalone HF/iso14a Sniff to flash +//----------------------------------------------------------------------------- + +/* + * `hf_14asniff` passively sniffs ISO14a frames, and stores them in internal + * flash. It requires RDV4 hardware (for flash and battery). + * + * This module is similar to hf_bog (which only logs ULC/NTAG/ULEV1 auth). + * + * On entering stand-alone mode, this module will start sniffing ISO14a frames. + * This will be stored in the normal trace buffer (ie: in RAM -- will be lost + * at power-off). + * + * Short-pressing the button again will stop sniffing, and at _this_ point + * append trace data from RAM to a file in flash (hf_14asniff.trc) and unmount. + * + * Once the data is saved, standalone mode will exit. + * + * LEDs: + * - LED1: sniffing + * - LED2: sniffed tag command, turns off when finished sniffing reader command + * - LED3: sniffed reader command, turns off when finished sniffing tag command + * - LED4: unmounting/sync'ing flash (normally < 100ms) + * + * To retrieve trace data from flash: + * + * 1. mem spiffs dump o hf_14asniff.trc f trace.trc + * Copies trace data file from flash to your PC. + * + * 2. trace load trace.trc + * Loads trace data from a file into PC-side buffers. + * + * 3. For ISO14a: trace list 14a 1 + * For MIFARE Classic: trace list mf 1 + * + * Lists trace data from buffer without requesting it from PM3. + * + * This module emits debug strings during normal operation -- so try it out in + * the lab connected to PM3 client before taking it into the field. + * + * To delete the trace data from flash: + * + * Caveats / notes: + * - Trace buffer will be cleared on starting stand-alone mode. Data in flash + * will remain unless explicitly deleted. + * - This module will terminate if the trace buffer is full (and save data to + * flash). + * - Like normal sniffing mode, timestamps overflow after 5 min 16 sec. + * However, the trace buffer is sequential, so will be in the correct order. + */ + +#include "standalone.h" // standalone definitions +#include "proxmark3_arm.h" +#include "iso14443a.h" +#include "util.h" +#include "spiffs.h" +#include "appmain.h" +#include "dbprint.h" +#include "ticks.h" +#include "BigBuf.h" + +#define HF_14ASNIFF_LOGFILE "hf_14asniff.trc" + +void DownloadTraceInstructions() { + Dbprintf(""); + Dbprintf("To get the trace from flash and display it:"); + Dbprintf("1. mem spiffs dump o "HF_14ASNIFF_LOGFILE" f trace.trc"); + Dbprintf("2. trace load trace.trc"); + Dbprintf("3. trace list 14a 1"); +} + +void ModInfo(void) { + DbpString("hf_14asniff: standalone 'hf 14a sniff', storing in flashmem"); + DownloadTraceInstructions(); +} + +void RunMod() { + StandAloneMode(); + + Dbprintf("Starting standalone mode: hf_14asniff"); + rdv40_spiffs_lazy_mount(); + + SniffIso14443a(0); + + Dbprintf("Stopped sniffing"); + SpinDelay(200); + + // Write stuff to spiffs logfile + uint32_t trace_len = BigBuf_get_traceLen(); + if (trace_len > 0) { + Dbprintf("[!] Trace length (bytes) = %u", trace_len); + + uint8_t* trace_buffer = BigBuf_get_addr(); + if (!exists_in_spiffs(HF_14ASNIFF_LOGFILE)) { + rdv40_spiffs_write( + HF_14ASNIFF_LOGFILE, trace_buffer, trace_len, RDV40_SPIFFS_SAFETY_SAFE); + Dbprintf("[!] Wrote trace to "HF_14ASNIFF_LOGFILE); + } else { + rdv40_spiffs_append( + HF_14ASNIFF_LOGFILE, trace_buffer, trace_len, RDV40_SPIFFS_SAFETY_SAFE); + Dbprintf("[!] Appended trace to "HF_14ASNIFF_LOGFILE); + } + } else { + Dbprintf("[!] Trace buffer is empty, nothing to write!"); + } + + LED_D_ON(); + rdv40_spiffs_lazy_unmount(); + LED_D_OFF(); + + SpinErr(LED_A, 200, 5); + SpinDelay(100); + + LEDsoff(); + SpinDelay(300); + DownloadTraceInstructions(); +} From a612cc9414239615f6ce6b766d501487782c9862 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 30 Jan 2020 16:43:18 +0100 Subject: [PATCH 1527/1854] device side hid demodulate use colors --- armsrc/lfops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 1cb8406bf..b7b928ff2 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -1291,7 +1291,7 @@ void CmdHIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol) cardnum = (lo >> 1) & 0x7FFFF; fac = ((hi & 0xF) << 12) | (lo >> 20); } - Dbprintf("TAG ID: %x%08x (%d) - Format Len: %dbit - FC: %d - Card: %d", + Dbprintf("TAG ID: " _YELLOW_("%x%08x (%d)") "- Format Len: " _YELLOW_("%d") "bit - FC: " _YELLOW_("%d") "- Card: "_YELLOW_("%d"), hi, lo, (lo >> 1) & 0xFFFF, From 4f912abaf6c576e44acfc82be406e9531182894f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 30 Jan 2020 17:05:59 +0100 Subject: [PATCH 1528/1854] Add 'lf_icehid' - new standalone mode for reading lf HID credentials and store it to RDV4 flashmem --- CHANGELOG.md | 2 + armsrc/Standalone/Makefile.hal | 8 +- armsrc/Standalone/Makefile.inc | 4 + armsrc/Standalone/lf_icehid.c | 126 ++++++++++++++++++ .../4_Advanced-compilation-parameters.md | 4 +- 5 files changed, 140 insertions(+), 4 deletions(-) create mode 100644 armsrc/Standalone/lf_icehid.c diff --git a/CHANGELOG.md b/CHANGELOG.md index 828538e8d..77aefb23b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Added `LF_ICEHID` standalone mode which searches for lf HID credentials and store to RDV4 flashmem (@iceman1001) + - Added `HF_14ASNIFF` standalone mode with storing trace to RDV4 flashmem (@micolous) - Added `hf lto dump` - dump 8160 bytes of data from LTO cartridge memory and save to file (@Kevin-Nakamoto) - Change `data plot` - write serial port name in window title for plot / slider window (@iceman1001) - Added `hf lto wrbl` - write block support for LTO Cartridge memory (@Kevin-Nakamoto) diff --git a/armsrc/Standalone/Makefile.hal b/armsrc/Standalone/Makefile.hal index fb952179a..2dec4cfde 100644 --- a/armsrc/Standalone/Makefile.hal +++ b/armsrc/Standalone/Makefile.hal @@ -38,13 +38,15 @@ define KNOWN_STANDALONE_DEFINITIONS | HF_14ASNIFF | 14a sniff to flashmem | | (RDV4 only) | | +----------------------------------------------------------+ - +| LF_ICEHID | LF HID collector to flashmem | +| (RDV4 only) | | ++----------------------------------------------------------+ endef -STANDALONE_MODES := LF_SAMYRUN LF_ICERUN LF_PROXBRUTE LF_HIDBRUTE +STANDALONE_MODES := LF_SAMYRUN LF_ICERUN LF_PROXBRUTE LF_HIDBRUTE LF_ICEHID STANDALONE_MODES += HF_YOUNG HF_MATTYRUN HF_COLIN HF_BOG HF_14ASNIFF STANDALONE_MODES_REQ_SMARTCARD := -STANDALONE_MODES_REQ_FLASH := HF_COLIN HF_BOG HF_14ASNIFF +STANDALONE_MODES_REQ_FLASH := HF_COLIN HF_BOG HF_14ASNIFF LF_ICEHID ifneq ($(filter $(STANDALONE),$(STANDALONE_MODES)),) STANDALONE_PLATFORM_DEFS += -DWITH_STANDALONE_$(STANDALONE) ifneq ($(filter $(STANDALONE),$(STANDALONE_MODES_REQ_SMARTCARD)),) diff --git a/armsrc/Standalone/Makefile.inc b/armsrc/Standalone/Makefile.inc index c7c5ff327..d4de0411e 100644 --- a/armsrc/Standalone/Makefile.inc +++ b/armsrc/Standalone/Makefile.inc @@ -37,3 +37,7 @@ endif ifneq (,$(findstring WITH_STANDALONE_HF_14ASNIFF,$(APP_CFLAGS))) SRC_STANDALONE = hf_14asniff.c endif +# WITH_STANDALONE_LF_ICEHID +ifneq (,$(findstring WITH_STANDALONE_LF_ICEHID,$(APP_CFLAGS))) + SRC_STANDALONE = lf_icehid.c +endif \ No newline at end of file diff --git a/armsrc/Standalone/lf_icehid.c b/armsrc/Standalone/lf_icehid.c new file mode 100644 index 000000000..c490d8d68 --- /dev/null +++ b/armsrc/Standalone/lf_icehid.c @@ -0,0 +1,126 @@ +//----------------------------------------------------------------------------- +// Christian Herrmann, 2020 +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// main code for HID collector aka IceHID by Iceman +//----------------------------------------------------------------------------- +#include "standalone.h" // standalone definitions +#include "proxmark3_arm.h" +#include "appmain.h" +#include "lfops.h" +#include "fpgaloader.h" +#include "util.h" +#include "dbprint.h" +#include "printf.h" +#include "spiffs.h" +#include "ticks.h" + +/* + * `lf_hidcollect` sniffs after LF HID credentials, and stores them in internal + * flash. It requires RDV4 hardware (for flash and battery). + * + * On entering stand-alone mode, this module will start reading/record HID credentials. + * Every found / collected credential will be written/appended to the logfile in flash + * as a text string. + * + * LEDs: + * - LED A: reading / record + * - LED B: writing to flash + * - LED C: unmounting/sync'ing flash (normally < 100ms) + * + * To retrieve log file from flash: + * + * 1. mem spiffs dump o lf_hidcollect.log f lf_hidcollect.log + * Copies log file from flash to your PC. + * + * 2. exit the Proxmark3 client + * + * 3. more lf_hidcollect.log + * + * This module emits debug strings during normal operation -- so try it out in + * the lab connected to PM3 client before taking it into the field. + * + * To delete the log file from flash: + * + * 1. mem spiffs remove lf_hidcollect.log + */ + +#define LF_HIDCOLLECT_LOGFILE "lf_hidcollect.log" + +void DownloadLogInstructions() { + Dbprintf(""); + Dbprintf("[=] To get the logfile from flash and display it:"); + Dbprintf("[=] " _YELLOW_("1.") "mem spiffs dump o "LF_HIDCOLLECT_LOGFILE" f "LF_HIDCOLLECT_LOGFILE); + Dbprintf("[=] " _YELLOW_("2.") "exit proxmark3 client"); + Dbprintf("[=] " _YELLOW_("3.") "cat "LF_HIDCOLLECT_LOGFILE); +} + +void ModInfo(void) { + DbpString(" LF HID collector mode - a.k.a IceHID (Iceman)"); +} + +void RunMod() { + + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + StandAloneMode(); + Dbprintf("[=] LF HID collector a.k.a IceHID started"); + + rdv40_spiffs_lazy_mount(); + + bool log_exists = exists_in_spiffs(LF_HIDCOLLECT_LOGFILE); + + // the main loop for your standalone mode + for (;;) { + WDT_HIT(); + + // exit from IceHID, send a usbcommand. + if (data_available()) break; + + // Was our button held down or pressed? + int button_pressed = BUTTON_HELD(280); + if (button_pressed == BUTTON_HOLD) + break; + + LED_A_ON(); + // findone, high, low, + uint32_t hi = 0, lo = 0; + CmdHIDdemodFSK(1, &hi, &lo, 0); + + LED_A_OFF(); + + //didn't collect any, loop + if (hi == 0 && lo == 0) + continue; + + uint8_t entry[20]; + memset(entry, 0, sizeof(entry)); + sprintf((char *)entry, "%lx%08lx\n", hi, lo); + + LED_B_ON(); + if (!log_exists) { + rdv40_spiffs_write(LF_HIDCOLLECT_LOGFILE, entry, sizeof(entry), RDV40_SPIFFS_SAFETY_SAFE); + log_exists = true; + } else { + rdv40_spiffs_append(LF_HIDCOLLECT_LOGFILE, entry, sizeof(entry), RDV40_SPIFFS_SAFETY_SAFE); + } + LED_B_OFF(); + + SpinErr(LED_A, 250, 2); + } + + LED_C_ON(); + rdv40_spiffs_lazy_unmount(); + LED_C_OFF(); + + SpinErr(LED_A, 200, 5); + SpinDelay(100); + + LEDsoff(); + SpinDelay(300); + DownloadLogInstructions(); + + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); +} diff --git a/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md b/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md index 3b0599de5..01b7d083a 100644 --- a/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md +++ b/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md @@ -73,13 +73,15 @@ Here are the supported values you can assign to `STANDALONE` in `Makefile.platfo |-----------------|----------------------------------------| | | No standalone mode | LF_SAMYRUN (def)| HID26 read/clone/sim - Samy Kamkar -| LF_ICERUN | standalone mode skeleton - iceman +| LF_ICERUN | standalone mode skeleton - Iceman | LF_PROXBRUTE | HID ProxII bruteforce - Brad Antoniewicz | LF_HIDBRUTE | HID corporate 1000 bruteforce - Federico dotta & Maurizio Agazzini | HF_YOUNG | Mifare sniff/simulation - Craig Young | HF_MATTYRUN | Mifare sniff/clone - Matías A. Ré Medina | HF_COLIN | Mifare ultra fast sniff/sim/clone - Colin Brigato | HF_BOG | 14a sniff with ULC/ULEV1/NTAG auth storing in flashmem - Bogito +| HF_14ASNIFF | 14a sniff storing to flashmem - Micolous +| LF_ICEHID | LF HID collector to flashmem - Iceman By default `STANDALONE=LF_SAMYRUN`. From b8a46a6fe3726779f356c2decbc9dfa7d194c828 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 1 Feb 2020 18:23:16 +0100 Subject: [PATCH 1529/1854] fix typo, thanks @neduchaljan! --- client/cmdsmartcard.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdsmartcard.c b/client/cmdsmartcard.c index 21066ffb7..7a892a8e0 100644 --- a/client/cmdsmartcard.c +++ b/client/cmdsmartcard.c @@ -54,7 +54,7 @@ static int usage_sm_reader(void) { return 0; } static int usage_sm_info(void) { - PrintAndLogEx(NORMAL, "Usage: s info [h|s]"); + PrintAndLogEx(NORMAL, "Usage: sc info [h|s]"); PrintAndLogEx(NORMAL, " h : this help"); PrintAndLogEx(NORMAL, " s : silent (no messages)"); PrintAndLogEx(NORMAL, ""); From 3563eb36f9cbc7b9f1273371c51396ff0d6c66cd Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 3 Feb 2020 20:36:23 +0200 Subject: [PATCH 1530/1854] try without pacman install packages --- appveyor.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 5070438c9..f5bb9f32a 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -142,10 +142,6 @@ clone_script: ExecUpdate "update2" "C:\ProxSpace\msys2\msys2_shell.cmd -mingw32 -defterm -no-start /dev/null" "terminate?MSYS2" - bash -c -i 'pacman -S mingw-w64-i686-readline mingw-w64-i686-gcc git make pkg-config mingw-w64-i686-qt5 --noconfirm' 2>&1>$null - - bash -c -i 'pacman -Suu --noconfirm' 2>&1>$null - Write-Host "Update " -NoNewLine Write-Host "[ OK ]" -ForegroundColor Green From e2d2e86df6f4feb089ad108e4eb3f0e260193d92 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 3 Feb 2020 20:53:50 +0100 Subject: [PATCH 1531/1854] textual --- client/cmdlfhid.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/cmdlfhid.c b/client/cmdlfhid.c index a41d183e7..201dcef84 100644 --- a/client/cmdlfhid.c +++ b/client/cmdlfhid.c @@ -342,7 +342,8 @@ static int CmdHIDClone(const char *Cmd) { } clearCommandBuffer(); - SendCommandOLD(CMD_LF_HID_CLONE, hi2, hi, lo, longid, sizeof(longid)); + SendCommandMIX(CMD_LF_HID_CLONE, hi2, hi, lo, longid, sizeof(longid)); + PrintAndLogEx(INFO, "Clone command sent. Try "_YELLOW_("'lf hid read'") " to verify"); return PM3_SUCCESS; } From 4be59e295fa3c94d2e0f9c6ba97e0f512f922273 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 3 Feb 2020 21:37:51 +0100 Subject: [PATCH 1532/1854] whitespace --- armsrc/spiffs.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/armsrc/spiffs.c b/armsrc/spiffs.c index 87321148d..81172476f 100644 --- a/armsrc/spiffs.c +++ b/armsrc/spiffs.c @@ -401,21 +401,21 @@ int rdv40_spiffs_lazy_mount_rollback(int changed) { // TODO : forbid writing to a filename which already exists as lnk ! // TODO : forbid writing to a filename.lnk which already exists without lnk ! int rdv40_spiffs_write(char *filename, uint8_t *src, uint32_t size, RDV40SpiFFSSafetyLevel level) { - RDV40_SPIFFS_SAFE_FUNCTION( // - write_to_spiffs((char *)filename, (uint8_t *)src, size); // + RDV40_SPIFFS_SAFE_FUNCTION( + write_to_spiffs(filename, src, size); ) } int rdv40_spiffs_append(char *filename, uint8_t *src, uint32_t size, RDV40SpiFFSSafetyLevel level) { - RDV40_SPIFFS_SAFE_FUNCTION( // - append_to_spiffs((char *)filename, (uint8_t *)src, size); // + RDV40_SPIFFS_SAFE_FUNCTION( + append_to_spiffs(filename, src, size); ) } // todo integrate reading symlinks transparently int rdv40_spiffs_read(char *filename, uint8_t *dst, uint32_t size, RDV40SpiFFSSafetyLevel level) { - RDV40_SPIFFS_SAFE_FUNCTION( // - read_from_spiffs((char *)filename, (uint8_t *)dst, size); // + RDV40_SPIFFS_SAFE_FUNCTION( + read_from_spiffs(filename, dst, size); ) } From 8696b521ef9481ac77944493553dc1317c4aef30 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 3 Feb 2020 21:38:42 +0100 Subject: [PATCH 1533/1854] protect debug messages --- common/lfdemod.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/common/lfdemod.c b/common/lfdemod.c index 2a9983130..325294258 100644 --- a/common/lfdemod.c +++ b/common/lfdemod.c @@ -206,7 +206,7 @@ void getHiLo(int *high, int *low, uint8_t fuzzHi, uint8_t fuzzLo) { *low = signalprop.low; } - prnt("getHiLo fuzzed: High %d | Low %d", *high, *low); + // prnt("getHiLo fuzzed: High %d | Low %d", *high, *low); } // by marshmellow @@ -1566,7 +1566,7 @@ static uint16_t cleanAskRawDemod(uint8_t *bits, size_t *size, int clk, int inver } if (*startIdx == 0) { *startIdx = i - clk; - prnt("DEBUG ASK: cleanAskRawDemod minus clock [%d]", *startIdx); + if (g_debugMode == 2) prnt("DEBUG ASK: cleanAskRawDemod minus clock [%d]", *startIdx); } waveHigh = !waveHigh; smplCnt = 0; @@ -1587,7 +1587,7 @@ static uint16_t cleanAskRawDemod(uint8_t *bits, size_t *size, int clk, int inver } if (*startIdx == 0) { *startIdx = i - cl_2; - prnt("DEBUG ASK: cleanAskRawDemod minus half clock [%d]", *startIdx); + if (g_debugMode == 2) prnt("DEBUG ASK: cleanAskRawDemod minus half clock [%d]", *startIdx); } waveHigh = !waveHigh; smplCnt = 0; @@ -1651,7 +1651,7 @@ int askdemod_ext(uint8_t *bits, size_t *size, int *clk, int *invert, int maxErr, errCnt = manrawdecode(bits, size, 0, &alignPos); *startIdx += ((*clk / 2) * alignPos); - prnt("DEBUG: (askdemod_ext) CLEAN: startIdx %i, alignPos %u , bestError %zu", *startIdx, alignPos, errCnt); + if (g_debugMode == 2) prnt("DEBUG: (askdemod_ext) CLEAN: startIdx %i, alignPos %u , bestError %zu", *startIdx, alignPos, errCnt); } return errCnt; } From 9bf26c080d40b2c3b0e3c959c79a171b92947312 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 3 Feb 2020 21:39:44 +0100 Subject: [PATCH 1534/1854] chg: icehid now records HID/AWID/IO/EM4100.. --- armsrc/Standalone/lf_icehid.c | 351 ++++++++++++++++++++++++++++++---- 1 file changed, 314 insertions(+), 37 deletions(-) diff --git a/armsrc/Standalone/lf_icehid.c b/armsrc/Standalone/lf_icehid.c index c490d8d68..560630dbb 100644 --- a/armsrc/Standalone/lf_icehid.c +++ b/armsrc/Standalone/lf_icehid.c @@ -11,20 +11,22 @@ #include "proxmark3_arm.h" #include "appmain.h" #include "lfops.h" +#include "lfsampling.h" +#include "BigBuf.h" #include "fpgaloader.h" #include "util.h" #include "dbprint.h" #include "printf.h" #include "spiffs.h" #include "ticks.h" - +#include "lfdemod.h" /* * `lf_hidcollect` sniffs after LF HID credentials, and stores them in internal * flash. It requires RDV4 hardware (for flash and battery). * * On entering stand-alone mode, this module will start reading/record HID credentials. - * Every found / collected credential will be written/appended to the logfile in flash - * as a text string. + * Every found / collected credential will be written/appended to the logfile in flash + * as a text string. * * LEDs: * - LED A: reading / record @@ -43,35 +45,308 @@ * This module emits debug strings during normal operation -- so try it out in * the lab connected to PM3 client before taking it into the field. * - * To delete the log file from flash: - * + * To delete the log file from flash: + * * 1. mem spiffs remove lf_hidcollect.log */ #define LF_HIDCOLLECT_LOGFILE "lf_hidcollect.log" + void DownloadLogInstructions() { Dbprintf(""); Dbprintf("[=] To get the logfile from flash and display it:"); Dbprintf("[=] " _YELLOW_("1.") "mem spiffs dump o "LF_HIDCOLLECT_LOGFILE" f "LF_HIDCOLLECT_LOGFILE); Dbprintf("[=] " _YELLOW_("2.") "exit proxmark3 client"); - Dbprintf("[=] " _YELLOW_("3.") "cat "LF_HIDCOLLECT_LOGFILE); + Dbprintf("[=] " _YELLOW_("3.") "cat "LF_HIDCOLLECT_LOGFILE); +} + +bool log_exists; + +void append(uint8_t* entry, size_t entry_len) { + + LED_B_ON(); + if (log_exists == false) { + rdv40_spiffs_write(LF_HIDCOLLECT_LOGFILE, entry, entry_len, RDV40_SPIFFS_SAFETY_SAFE); + log_exists = true; + } else { + rdv40_spiffs_append(LF_HIDCOLLECT_LOGFILE, entry, entry_len, RDV40_SPIFFS_SAFETY_SAFE); + } + LED_B_OFF(); +} + +uint32_t IceEM410xdemod() { + + uint8_t *dest = BigBuf_get_addr(); + size_t idx = 0; + int clk = 0, invert = 0, maxErr = 20; + uint32_t hi = 0; + uint64_t lo = 0; + + size_t size = MIN(16385, BigBuf_max_traceLen()); + + //askdemod and manchester decode + int errCnt = askdemod(dest, &size, &clk, &invert, maxErr, 0, 1); + + WDT_HIT(); + + if (errCnt > 50) { + BigBuf_free(); + return PM3_ESOFT; + } + + errCnt = Em410xDecode(dest, &size, &idx, &hi, &lo); + if (errCnt != 1) { + BigBuf_free(); + return PM3_ESOFT; + } + + uint8_t entry[60]; + memset(entry, 0, sizeof(entry)); + + if (size == 128) { + sprintf((char *)entry, "EM XL TAG ID: %06lx%08lx%08lx - (%05ld_%03ld_%08ld)", + hi, + (uint32_t)(lo >> 32), + (uint32_t)lo, + (uint32_t)(lo & 0xFFFF), + (uint32_t)((lo >> 16LL) & 0xFF), + (uint32_t)(lo & 0xFFFFFF)); + } else { + sprintf((char *)entry, "EM TAG ID: %02lx%08lx - (%05ld_%03ld_%08ld)", + (uint32_t)(lo >> 32), + (uint32_t)lo, + (uint32_t)(lo & 0xFFFF), + (uint32_t)((lo >> 16LL) & 0xFF), + (uint32_t)(lo & 0xFFFFFF)); + } + + append(entry, strlen((char*)entry)); + Dbprintf("strlen %d", strlen((char*)entry)); + + Dbprintf("%s", entry); + BigBuf_free(); + return PM3_SUCCESS; +} + +uint32_t IceAWIDdemod() { + + uint8_t *dest = BigBuf_get_addr(); + size_t size = MIN(12800, BigBuf_max_traceLen()); + int dummyIdx = 0; + + //askdemod and manchester decode + int idx = detectAWID(dest, &size, &dummyIdx); + + if (idx <= 0 || size != 96) { + BigBuf_free(); + return PM3_ESOFT; + } + + //get raw ID before removing parities + uint32_t rawLo = bytebits_to_byte(dest + idx + 64, 32); + uint32_t rawHi = bytebits_to_byte(dest + idx + 32, 32); + uint32_t rawHi2 = bytebits_to_byte(dest + idx, 32); + + size = removeParity(dest, idx + 8, 4, 1, 88); + if (size != 66) { + BigBuf_free(); + return PM3_ESOFT; + } + + uint8_t entry[110]; + memset(entry, 0, sizeof(entry)); + + uint8_t fmtLen = bytebits_to_byte(dest, 8); + if (fmtLen == 26) { + uint8_t fac = bytebits_to_byte(dest + 9, 8); + uint32_t cardnum = bytebits_to_byte(dest + 17, 16); + uint32_t code1 = bytebits_to_byte(dest + 8, fmtLen); + sprintf((char *)entry, "AWID bit len: %d, FC: %d, Card: %ld - Wiegand: %lx, Raw: %08lx%08lx%08lx \n", fmtLen, fac, cardnum, code1, rawHi2, rawHi, rawLo); + } else { + uint32_t cardnum = bytebits_to_byte(dest + 8 + (fmtLen - 17), 16); + if (fmtLen > 32) { + uint32_t code1 = bytebits_to_byte(dest + 8, fmtLen - 32); + uint32_t code2 = bytebits_to_byte(dest + 8 + (fmtLen - 32), 32); + sprintf((char *)entry, "AWID bit len: %d -unk bit len - Card: %ld - Wiegand: %lx%08lx, Raw: %08lx%08lx%08lx \n", fmtLen, cardnum, code1, code2, rawHi2, rawHi, rawLo); + } else { + uint32_t code1 = bytebits_to_byte(dest + 8, fmtLen); + sprintf((char *)entry, "AWID bit len: %d -unk bit len - Card: %ld - Wiegand: %lx, Raw: %08lx%08lx%08lx \n", fmtLen, cardnum, code1, rawHi2, rawHi, rawLo); + } + } + + append(entry, strlen((char*)entry)); + Dbprintf("%s", entry); + BigBuf_free(); + return PM3_SUCCESS; +} + +uint32_t IceIOdemod() { + + int dummyIdx = 0; + uint8_t version = 0, facilitycode = 0, crc = 0; + uint16_t number = 0, calccrc = 0; + uint32_t hi = 0, lo = 0; + + size_t size = MIN(12000, BigBuf_max_traceLen()); + +// uint8_t *dest = BigBuf_malloc(size); + uint8_t *dest = BigBuf_get_addr(); + + //fskdemod and get start index + int idx = detectIOProx(dest, &size, &dummyIdx); + + if (idx < 0) { + BigBuf_free(); + return PM3_ESOFT; + } + + hi = bytebits_to_byte(dest + idx, 32); + lo = bytebits_to_byte(dest + idx + 32, 32); + + version = bytebits_to_byte(dest + idx + 27, 8); //14,4 + facilitycode = bytebits_to_byte(dest + idx + 18, 8); + number = (bytebits_to_byte(dest + idx + 36, 8) << 8) | (bytebits_to_byte(dest + idx + 45, 8)); //36,9 + + crc = bytebits_to_byte(dest + idx + 54, 8); + for (uint8_t i = 1; i < 6; ++i) + calccrc += bytebits_to_byte(dest + idx + 9 * i, 8); + + calccrc &= 0xff; + calccrc = 0xff - calccrc; + + char *crcStr = (crc == calccrc) ? "ok" : "!crc"; + + uint8_t entry[64]; + memset(entry, 0, sizeof(entry)); + + sprintf((char *)entry, "IO Prox XSF(%02d)%02x:%05d (%08lx%08lx) [%02x %s] \n" + , version + , facilitycode + , number + , hi + , lo + , crc + , crcStr + ); + + append(entry, strlen((char*)entry)); + Dbprintf("%s", entry); + + BigBuf_free(); + return PM3_SUCCESS; +} + +uint32_t IceHIDDemod() { + + int dummyIdx = 0; + + uint32_t hi2 = 0, hi = 0, lo = 0; + + // large enough to catch 2 sequences of largest format + size_t size = 50 * 128 * 2; // 12800 bytes + //uint8_t *dest = BigBuf_malloc(size); + uint8_t *dest = BigBuf_get_addr(); + + // FSK demodulator + int idx = HIDdemodFSK(dest, &size, &hi2, &hi, &lo, &dummyIdx); + if (idx < 0) { + BigBuf_free(); + return PM3_ESOFT; + } + + if ((size == 96 || size == 192)) { + + uint8_t entry[80]; + memset(entry, 0, sizeof(entry)); + + // go over previously decoded manchester data and decode into usable tag ID + if (hi2 != 0) { //extra large HID tags 88/192 bits + + sprintf((char *)entry, "HID large: %lx%08lx%08lx (%ld) \n", + hi2, + hi, + lo, + (lo >> 1) & 0xFFFF + ); + + append(entry, strlen((char*)entry)); + + } else { //standard HID tags 44/96 bits + uint8_t bitlen = 0; + uint32_t fac = 0; + uint32_t cardnum = 0; + + if (((hi >> 5) & 1) == 1) { //if bit 38 is set then < 37 bit format is used + uint32_t lo2 = 0; + lo2 = (((hi & 31) << 12) | (lo >> 20)); //get bits 21-37 to check for format len bit + uint8_t idx3 = 1; + while (lo2 > 1) { //find last bit set to 1 (format len bit) + lo2 >>= 1; + idx3++; + } + bitlen = idx3 + 19; + fac = 0; + cardnum = 0; + if (bitlen == 26) { + cardnum = (lo >> 1) & 0xFFFF; + fac = (lo >> 17) & 0xFF; + } + if (bitlen == 37) { + cardnum = (lo >> 1) & 0x7FFFF; + fac = ((hi & 0xF) << 12) | (lo >> 20); + } + if (bitlen == 34) { + cardnum = (lo >> 1) & 0xFFFF; + fac = ((hi & 1) << 15) | (lo >> 17); + } + if (bitlen == 35) { + cardnum = (lo >> 1) & 0xFFFFF; + fac = ((hi & 1) << 11) | (lo >> 21); + } + } else { //if bit 38 is not set then 37 bit format is used + bitlen = 37; + cardnum = (lo >> 1) & 0x7FFFF; + fac = ((hi & 0xF) << 12) | (lo >> 20); + } + + sprintf((char *)entry, "HID: %lx%08lx (%ld) Format: %d bit FC: %ld Card: %ld \n", + hi, + lo, + (lo >> 1) & 0xFFFF, + bitlen, + fac, + cardnum + ); + + append(entry, strlen((char*)entry)); + } + + Dbprintf("%s", entry); + } + + BigBuf_free(); + return PM3_SUCCESS; } void ModInfo(void) { - DbpString(" LF HID collector mode - a.k.a IceHID (Iceman)"); + DbpString(" LF HID / IOprox / AWID / EM4100 collector mode - a.k.a IceHID (Iceman)"); } void RunMod() { FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + LFSetupFPGAForADC(LF_DIVISOR_125, true); + BigBuf_Clear(); + StandAloneMode(); + Dbprintf("[=] LF HID collector a.k.a IceHID started"); - + rdv40_spiffs_lazy_mount(); - - bool log_exists = exists_in_spiffs(LF_HIDCOLLECT_LOGFILE); - + + log_exists = exists_in_spiffs(LF_HIDCOLLECT_LOGFILE); + // the main loop for your standalone mode for (;;) { WDT_HIT(); @@ -84,43 +359,45 @@ void RunMod() { if (button_pressed == BUTTON_HOLD) break; - LED_A_ON(); - // findone, high, low, - uint32_t hi = 0, lo = 0; - CmdHIDdemodFSK(1, &hi, &lo, 0); + LED_A_ON(); - LED_A_OFF(); - - //didn't collect any, loop - if (hi == 0 && lo == 0) + uint32_t res; + + // since we steal 12800 from bigbuffer, no need to sample it. + DoAcquisition_config(false, 28000); + res = IceHIDDemod(); + if (res == PM3_SUCCESS) { + LED_A_OFF(); continue; - - uint8_t entry[20]; - memset(entry, 0, sizeof(entry)); - sprintf((char *)entry, "%lx%08lx\n", hi, lo); - - LED_B_ON(); - if (!log_exists) { - rdv40_spiffs_write(LF_HIDCOLLECT_LOGFILE, entry, sizeof(entry), RDV40_SPIFFS_SAFETY_SAFE); - log_exists = true; - } else { - rdv40_spiffs_append(LF_HIDCOLLECT_LOGFILE, entry, sizeof(entry), RDV40_SPIFFS_SAFETY_SAFE); } - LED_B_OFF(); - SpinErr(LED_A, 250, 2); + DoAcquisition_config(false, 28000); + res = IceAWIDdemod(); + if (res == PM3_SUCCESS) { + LED_A_OFF(); + continue; + } + + DoAcquisition_config(false, 20000); + res = IceEM410xdemod(); + if (res == PM3_SUCCESS) { + LED_A_OFF(); + continue; + } + + DoAcquisition_config(false, 28000); + res = IceIOdemod(); + if (res == PM3_SUCCESS) { + LED_A_OFF(); + continue; + } } LED_C_ON(); rdv40_spiffs_lazy_unmount(); LED_C_OFF(); - SpinErr(LED_A, 200, 5); - SpinDelay(100); - LEDsoff(); - SpinDelay(300); DownloadLogInstructions(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); } From 5ef1f001dd86d3628520e0802da35ad864a3bbe2 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 3 Feb 2020 22:44:46 +0100 Subject: [PATCH 1535/1854] extra check if malloc failed --- common/crapto1/crapto1.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/common/crapto1/crapto1.c b/common/crapto1/crapto1.c index 43e45c3db..e697b68f0 100644 --- a/common/crapto1/crapto1.c +++ b/common/crapto1/crapto1.c @@ -376,6 +376,7 @@ uint32_t lfsr_rollback_word(struct Crypto1State *s, uint32_t in, int fb) { static uint16_t *dist = 0; int nonce_distance(uint32_t from, uint32_t to) { if (!dist) { + // allocation 2bytes * 0xFFFF times. dist = calloc(2 << 16, sizeof(uint8_t)); if (!dist) return -1; @@ -396,7 +397,8 @@ int nonce_distance(uint32_t from, uint32_t to) { */ bool validate_prng_nonce(uint32_t nonce) { // init prng table: - nonce_distance(nonce, nonce); + if (nonce_distance(nonce, nonce) == -1) + return false; return ((65535 - dist[nonce >> 16] + dist[nonce & 0xffff]) % 65535) == 16; } From 9d2296f88a11eaef0c236e37c73a87083d7c91d8 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Tue, 4 Feb 2020 00:10:00 +0200 Subject: [PATCH 1536/1854] check pm3 dir exist --- appveyor.yml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index f5bb9f32a..d5c610aa0 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -43,12 +43,15 @@ clone_script: Write-Host "[ OK ]" -ForegroundColor Green - Write-Host "Removing pm3 dir..." -NoNewLine + if(Test-Path -Path C:\ProxSpace\pm3){ - Remove-Item -Recurse -Force -Path c:\ProxSpace\pm3\* + Write-Host "Removing pm3 dir..." -NoNewLine - Write-Host "[ OK ]" -ForegroundColor Green + Remove-Item -Recurse -Force -Path C:\ProxSpace\pm3\* + Write-Host "[ OK ]" -ForegroundColor Green + + } Write-Host "Cloning repository <$env:appveyor_repo_name> to $env:appveyor_build_folder ..." -NoNewLine From 5a6230b6234947402e0f4cec71195cc810d80240 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Tue, 4 Feb 2020 00:14:09 +0200 Subject: [PATCH 1537/1854] create pm3 dir --- appveyor.yml | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index d5c610aa0..dac0d6c82 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -43,15 +43,18 @@ clone_script: Write-Host "[ OK ]" -ForegroundColor Green - if(Test-Path -Path C:\ProxSpace\pm3){ + if(!(Test-Path -Path C:\ProxSpace\pm3)){ - Write-Host "Removing pm3 dir..." -NoNewLine + New-Item -ItemType Directory -Force -Path C:\ProxSpace\pm3 - Remove-Item -Recurse -Force -Path C:\ProxSpace\pm3\* + } + + Write-Host "Removing pm3 dir..." -NoNewLine - Write-Host "[ OK ]" -ForegroundColor Green + Remove-Item -Recurse -Force -Path c:\ProxSpace\pm3\* + + Write-Host "[ OK ]" -ForegroundColor Green - } Write-Host "Cloning repository <$env:appveyor_repo_name> to $env:appveyor_build_folder ..." -NoNewLine From 953fcb17a96842298fd3dbdde72d568c757c4560 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Tue, 4 Feb 2020 00:27:16 +0200 Subject: [PATCH 1538/1854] setup --- appveyor.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/appveyor.yml b/appveyor.yml index dac0d6c82..ca4becf1e 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -143,6 +143,8 @@ clone_script: Remove-Job -Force $Job } + + C:\ProxSpace\msys2\ps\setup.cmd ExecUpdate "update1" "C:\ProxSpace\msys2\msys2_shell.cmd -mingw32 -defterm -no-start /dev/null" "terminate?MSYS2" From 6871391284b19acc14775693d2197a8c930b5fd7 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Tue, 4 Feb 2020 00:33:54 +0200 Subject: [PATCH 1539/1854] add cd --- appveyor.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/appveyor.yml b/appveyor.yml index ca4becf1e..7c9eeaccd 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -144,6 +144,8 @@ clone_script: Remove-Job -Force $Job } + cd C:\ProxSpace\ + C:\ProxSpace\msys2\ps\setup.cmd ExecUpdate "update1" "C:\ProxSpace\msys2\msys2_shell.cmd -mingw32 -defterm -no-start /dev/null" "terminate?MSYS2" From aa0054e6b93d15b58f2e21951df95f88cd08c700 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 4 Feb 2020 00:41:57 +0100 Subject: [PATCH 1540/1854] chg: trying to decode block 7 when decrypted.. --- client/cmdhficlass.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 616f5e2e2..567600d15 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -28,7 +28,8 @@ #include "loclass/elite_crack.h" #include "fileutils.h" #include "protocols.h" - +#include "wiegand_formats.h" +#include "wiegand_formatutils.h" #define NUM_CSNS 9 #define ICLASS_KEYS_MAX 8 @@ -918,6 +919,17 @@ static int CmdHFiClassDecrypt(const char *Cmd) { saveFileJSON(fptr, jsfIclass, decrypted, decryptedlen); printIclassDumpContents(decrypted, 1, (decryptedlen / 8), decryptedlen); + + uint32_t top = 0, mid, bot; + mid = bytes_to_num(decrypted + (8*7), 4); + bot = bytes_to_num(decrypted + (8*7) + 4, 4); + + PrintAndLogEx(INFO, ""); + PrintAndLogEx(INFO, "block 7 - Wiegand decode"); + wiegand_message_t packed = initialize_message_object(top, mid, bot); + HIDTryUnpack(&packed, true); + PrintAndLogEx(INFO, "-----------------------------------------------------------------"); + free(decrypted); free(fptr); } @@ -1871,13 +1883,13 @@ void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t e //PrintAndLog ("startblock: %d, endblock: %d, filesize: %d, maxmemcount: %d, filemaxblock: %d",startblock, endblock,filesize, maxmemcount, filemaxblock); int i = startblock; - PrintAndLogEx(NORMAL, "------+--+-------------------------+"); + PrintAndLogEx(INFO, "------+--+-------------------------+----------"); while (i <= endblock) { uint8_t *blk = iclass_dump + (i * 8); - PrintAndLogEx(NORMAL, " |%02X| %s", i, sprint_hex_ascii(blk, 8)); + PrintAndLogEx(INFO, " |%02X| %s", i, sprint_hex_ascii(blk, 8)); i++; } - PrintAndLogEx(NORMAL, "------+--+-------------------------+"); + PrintAndLogEx(INFO, "------+--+-------------------------+----------"); } static int CmdHFiClassReadTagFile(const char *Cmd) { From da88b28b2ea49b2efc3a21c66fc29a0e1ff5bc7e Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Tue, 4 Feb 2020 08:59:57 +0200 Subject: [PATCH 1541/1854] add cd --- appveyor.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/appveyor.yml b/appveyor.yml index 7c9eeaccd..b2ab84fb4 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -183,6 +183,7 @@ build_script: $env:MSYSTEM_CHOST="i686-w64-mingw32" + cd C:\ProxSpace\pm3 #make From a9ffcc68924bef278e445be739945a2d477d3a2e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 4 Feb 2020 17:37:19 +0100 Subject: [PATCH 1542/1854] textual --- armsrc/Standalone/lf_icehid.c | 46 ++++++++++++----------------------- 1 file changed, 16 insertions(+), 30 deletions(-) diff --git a/armsrc/Standalone/lf_icehid.c b/armsrc/Standalone/lf_icehid.c index 560630dbb..69ace7bd8 100644 --- a/armsrc/Standalone/lf_icehid.c +++ b/armsrc/Standalone/lf_icehid.c @@ -105,7 +105,7 @@ uint32_t IceEM410xdemod() { memset(entry, 0, sizeof(entry)); if (size == 128) { - sprintf((char *)entry, "EM XL TAG ID: %06lx%08lx%08lx - (%05ld_%03ld_%08ld)", + sprintf((char *)entry, "EM XL TAG ID: %06lx%08lx%08lx - (%05ld_%03ld_%08ld)\n", hi, (uint32_t)(lo >> 32), (uint32_t)lo, @@ -113,7 +113,7 @@ uint32_t IceEM410xdemod() { (uint32_t)((lo >> 16LL) & 0xFF), (uint32_t)(lo & 0xFFFFFF)); } else { - sprintf((char *)entry, "EM TAG ID: %02lx%08lx - (%05ld_%03ld_%08ld)", + sprintf((char *)entry, "EM TAG ID: %02lx%08lx - (%05ld_%03ld_%08ld)\n", (uint32_t)(lo >> 32), (uint32_t)lo, (uint32_t)(lo & 0xFFFF), @@ -122,8 +122,6 @@ uint32_t IceEM410xdemod() { } append(entry, strlen((char*)entry)); - Dbprintf("strlen %d", strlen((char*)entry)); - Dbprintf("%s", entry); BigBuf_free(); return PM3_SUCCESS; @@ -162,16 +160,16 @@ uint32_t IceAWIDdemod() { uint8_t fac = bytebits_to_byte(dest + 9, 8); uint32_t cardnum = bytebits_to_byte(dest + 17, 16); uint32_t code1 = bytebits_to_byte(dest + 8, fmtLen); - sprintf((char *)entry, "AWID bit len: %d, FC: %d, Card: %ld - Wiegand: %lx, Raw: %08lx%08lx%08lx \n", fmtLen, fac, cardnum, code1, rawHi2, rawHi, rawLo); + sprintf((char *)entry, "AWID bit len: %d, FC: %d, Card: %ld - Wiegand: %lx, Raw: %08lx%08lx%08lx\n", fmtLen, fac, cardnum, code1, rawHi2, rawHi, rawLo); } else { uint32_t cardnum = bytebits_to_byte(dest + 8 + (fmtLen - 17), 16); if (fmtLen > 32) { uint32_t code1 = bytebits_to_byte(dest + 8, fmtLen - 32); uint32_t code2 = bytebits_to_byte(dest + 8 + (fmtLen - 32), 32); - sprintf((char *)entry, "AWID bit len: %d -unk bit len - Card: %ld - Wiegand: %lx%08lx, Raw: %08lx%08lx%08lx \n", fmtLen, cardnum, code1, code2, rawHi2, rawHi, rawLo); + sprintf((char *)entry, "AWID bit len: %d -unk bit len - Card: %ld - Wiegand: %lx%08lx, Raw: %08lx%08lx%08lx\n", fmtLen, cardnum, code1, code2, rawHi2, rawHi, rawLo); } else { uint32_t code1 = bytebits_to_byte(dest + 8, fmtLen); - sprintf((char *)entry, "AWID bit len: %d -unk bit len - Card: %ld - Wiegand: %lx, Raw: %08lx%08lx%08lx \n", fmtLen, cardnum, code1, rawHi2, rawHi, rawLo); + sprintf((char *)entry, "AWID bit len: %d -unk bit len - Card: %ld - Wiegand: %lx, Raw: %08lx%08lx%08lx\n", fmtLen, cardnum, code1, rawHi2, rawHi, rawLo); } } @@ -184,8 +182,8 @@ uint32_t IceAWIDdemod() { uint32_t IceIOdemod() { int dummyIdx = 0; - uint8_t version = 0, facilitycode = 0, crc = 0; - uint16_t number = 0, calccrc = 0; + uint8_t version = 0, facilitycode = 0; + uint16_t number = 0; uint32_t hi = 0, lo = 0; size_t size = MIN(12000, BigBuf_max_traceLen()); @@ -208,31 +206,19 @@ uint32_t IceIOdemod() { facilitycode = bytebits_to_byte(dest + idx + 18, 8); number = (bytebits_to_byte(dest + idx + 36, 8) << 8) | (bytebits_to_byte(dest + idx + 45, 8)); //36,9 - crc = bytebits_to_byte(dest + idx + 54, 8); - for (uint8_t i = 1; i < 6; ++i) - calccrc += bytebits_to_byte(dest + idx + 9 * i, 8); - - calccrc &= 0xff; - calccrc = 0xff - calccrc; - - char *crcStr = (crc == calccrc) ? "ok" : "!crc"; - uint8_t entry[64]; memset(entry, 0, sizeof(entry)); - sprintf((char *)entry, "IO Prox XSF(%02d)%02x:%05d (%08lx%08lx) [%02x %s] \n" + sprintf((char *)entry, "IO Prox XSF(%02d)%02x:%05d (%08lx%08lx)\n" , version , facilitycode , number , hi , lo - , crc - , crcStr ); - + append(entry, strlen((char*)entry)); Dbprintf("%s", entry); - BigBuf_free(); return PM3_SUCCESS; } @@ -263,7 +249,7 @@ uint32_t IceHIDDemod() { // go over previously decoded manchester data and decode into usable tag ID if (hi2 != 0) { //extra large HID tags 88/192 bits - sprintf((char *)entry, "HID large: %lx%08lx%08lx (%ld) \n", + sprintf((char *)entry, "HID large: %lx%08lx%08lx (%ld)\n", hi2, hi, lo, @@ -271,7 +257,7 @@ uint32_t IceHIDDemod() { ); append(entry, strlen((char*)entry)); - + } else { //standard HID tags 44/96 bits uint8_t bitlen = 0; uint32_t fac = 0; @@ -309,8 +295,8 @@ uint32_t IceHIDDemod() { cardnum = (lo >> 1) & 0x7FFFF; fac = ((hi & 0xF) << 12) | (lo >> 20); } - - sprintf((char *)entry, "HID: %lx%08lx (%ld) Format: %d bit FC: %ld Card: %ld \n", + + sprintf((char *)entry, "HID: %lx%08lx (%ld) Format: %d bit FC: %ld Card: %ld\n", hi, lo, (lo >> 1) & 0xFFFF, @@ -318,7 +304,7 @@ uint32_t IceHIDDemod() { fac, cardnum ); - + append(entry, strlen((char*)entry)); } @@ -330,7 +316,7 @@ uint32_t IceHIDDemod() { } void ModInfo(void) { - DbpString(" LF HID / IOprox / AWID / EM4100 collector mode - a.k.a IceHID (Iceman)"); + DbpString(_YELLOW_(" LF HID / IOprox / AWID / EM4100 collector mode") " - a.k.a IceHID (Iceman)"); } void RunMod() { @@ -341,7 +327,7 @@ void RunMod() { StandAloneMode(); - Dbprintf("[=] LF HID collector a.k.a IceHID started"); + Dbprintf(_YELLOW_("[=] Standalone mode IceHID started")); rdv40_spiffs_lazy_mount(); From 0be6737ad903e85340ff8a900d310a492c7cbff4 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 4 Feb 2020 17:38:02 +0100 Subject: [PATCH 1543/1854] debug state --- common/lfdemod.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/lfdemod.c b/common/lfdemod.c index 325294258..4dcd46172 100644 --- a/common/lfdemod.c +++ b/common/lfdemod.c @@ -1656,7 +1656,7 @@ int askdemod_ext(uint8_t *bits, size_t *size, int *clk, int *invert, int maxErr, return errCnt; } - prnt("DEBUG: (askdemod_ext) Weak wave detected: startIdx %i", *startIdx); + if (g_debugMode == 2) prnt("DEBUG: (askdemod_ext) Weak wave detected: startIdx %i", *startIdx); int lastBit; //set first clock check - can go negative size_t i, bitnum = 0; //output counter From 189523b190a05f738ed5c02d3715feb064ef3af8 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 4 Feb 2020 17:38:47 +0100 Subject: [PATCH 1544/1854] textual layout in printing formats --- client/wiegand_formats.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/wiegand_formats.c b/client/wiegand_formats.c index a535bc614..0c3c09fb6 100644 --- a/client/wiegand_formats.c +++ b/client/wiegand_formats.c @@ -687,7 +687,7 @@ static void HIDDisplayUnpackedCard(wiegand_card_t *card, const cardformat_t form if (format.Fields.hasParity) snprintf(s + strlen(s), sizeof(s) - strlen(s), " parity: %s", card->ParityValid ? "valid" : "invalid"); - PrintAndLogEx(SUCCESS, "%s [%s - %s]", s, format.Name, format.Descrp); + PrintAndLogEx(SUCCESS, "[%s] - %s; %s", format.Name, format.Descrp, s); } bool HIDTryUnpack(wiegand_message_t *packed, bool ignore_parity) { From 3e3dc83789d4a45a35d78dabee32847e0faa77c7 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 4 Feb 2020 17:39:59 +0100 Subject: [PATCH 1545/1854] filter ansi --- client/flash.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/client/flash.c b/client/flash.c index a3d438757..1f898f9d3 100644 --- a/client/flash.c +++ b/client/flash.c @@ -13,6 +13,7 @@ #include #include #include +#include #include "ui.h" #include "elf.h" @@ -534,6 +535,9 @@ int flash_write(flash_file_t *ctx) { int len = 0; PrintAndLogEx(SUCCESS, "Writing segments for file: %s", ctx->filename); + + bool filter_ansi = !session.supports_colors; + for (int i = 0; i < ctx->num_segs; i++) { flash_seg_t *seg = &ctx->segments[i]; @@ -561,11 +565,15 @@ int flash_write(flash_file_t *ctx) { baddr += block_size; length -= block_size; block++; - if ( len < strlen(ice) ) - fprintf(stdout, "%c", ice[len++]); - else + if ( len < strlen(ice) ) { + if (filter_ansi && !isalpha(ice[len]) ) { + len++; + } else { + fprintf(stdout, "%c", ice[len++]); + } + } else { fprintf(stdout, "."); - + } fflush(stdout); } PrintAndLogEx(NORMAL, " " _GREEN_("OK")); From 3924d71f3705d15e31415708f1c8ba7cf965b95a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 4 Feb 2020 21:57:33 +0100 Subject: [PATCH 1546/1854] too small chararray --- armsrc/Standalone/lf_icehid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/Standalone/lf_icehid.c b/armsrc/Standalone/lf_icehid.c index 69ace7bd8..77f04024e 100644 --- a/armsrc/Standalone/lf_icehid.c +++ b/armsrc/Standalone/lf_icehid.c @@ -101,7 +101,7 @@ uint32_t IceEM410xdemod() { return PM3_ESOFT; } - uint8_t entry[60]; + uint8_t entry[81]; memset(entry, 0, sizeof(entry)); if (size == 128) { From 7e57bc4ed15a0098f992ebe314b5e5caa9454f43 Mon Sep 17 00:00:00 2001 From: Jan Neduchal Date: Wed, 5 Feb 2020 16:32:21 +0100 Subject: [PATCH 1547/1854] Fixed the url as the service has moved --- client/cmdsmartcard.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdsmartcard.c b/client/cmdsmartcard.c index 7a892a8e0..6422fe605 100644 --- a/client/cmdsmartcard.c +++ b/client/cmdsmartcard.c @@ -740,7 +740,7 @@ static int CmdSmartInfo(const char *Cmd) { PrintAndLogEx(INFO, "--- Smartcard Information ---------"); PrintAndLogEx(INFO, "-------------------------------------------------------------"); PrintAndLogEx(INFO, "ISO7618-3 ATR : %s", sprint_hex(card.atr, card.atr_len)); - PrintAndLogEx(INFO, "\nhttp://smartcard-atr.appspot.com/parse?ATR=%s", sprint_hex_inrow(card.atr, card.atr_len)); + PrintAndLogEx(INFO, "\nhttp://smartcard-atr.apdu.fr/parse?ATR=%s", sprint_hex_inrow(card.atr, card.atr_len)); // print ATR PrintAndLogEx(NORMAL, ""); From 71168956541e5398597c8f1483efb75ac8f2a8e9 Mon Sep 17 00:00:00 2001 From: Kevin-Nakamoto Date: Thu, 6 Feb 2020 13:38:58 -0500 Subject: [PATCH 1548/1854] added hf lto restore and fix filename for dump --- CHANGELOG.md | 1 + client/cmdhflto.c | 134 ++++++++++++++++++++++++++++++++++++++++++---- client/cmdhflto.h | 3 +- 3 files changed, 127 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 77aefb23b..8a36b58da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Added `hf lto restore` - restore LTO cartridge memory from dump file [.bin|.eml] (@Kevin-Nakamoto) - Added `LF_ICEHID` standalone mode which searches for lf HID credentials and store to RDV4 flashmem (@iceman1001) - Added `HF_14ASNIFF` standalone mode with storing trace to RDV4 flashmem (@micolous) - Added `hf lto dump` - dump 8160 bytes of data from LTO cartridge memory and save to file (@Kevin-Nakamoto) diff --git a/client/cmdhflto.c b/client/cmdhflto.c index d38cfdf25..b4700cca0 100644 --- a/client/cmdhflto.c +++ b/client/cmdhflto.c @@ -72,6 +72,17 @@ static int usage_lto_dump(void) { return PM3_SUCCESS; } +static int usage_lto_restore(void) { + PrintAndLogEx(NORMAL, "Usage: hf lto restore [h] f "); + PrintAndLogEx(NORMAL, "Options:"); + PrintAndLogEx(NORMAL, " h this help"); + PrintAndLogEx(NORMAL, " f file name [.bin|.eml]"); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Examples:"); + PrintAndLogEx(NORMAL, " hf lto restore f hf_lto_92C7842CFF.bin|.eml"); + return PM3_SUCCESS; +} + static void lto_switch_off_field(void) { SendCommandMIX(CMD_HF_ISO14443A_READER, 0, 0, 0, NULL, 0); } @@ -179,7 +190,6 @@ static int CmdHfLTOInfo(const char *Cmd) { int infoLTO(bool verbose) { clearCommandBuffer(); - lto_switch_on_field(); uint8_t serial_number[5]; @@ -226,7 +236,6 @@ static int lto_rdbl(uint8_t blk, uint8_t *block_responce, uint8_t *block_cnt_res int rdblLTO(uint8_t st_blk, uint8_t end_blk, bool verbose) { clearCommandBuffer(); - lto_switch_on_field(); uint8_t serial_number[5]; @@ -343,7 +352,7 @@ static int lto_wrbl(uint8_t blk, uint8_t *data, bool verbose) { int wrblLTO(uint8_t blk, uint8_t *data, bool verbose) { clearCommandBuffer(); - lto_switch_on_field(); + lto_switch_on_field(); uint8_t serial_number[5]; uint8_t serial_len = sizeof(serial_number); @@ -413,11 +422,13 @@ static int CmdHfLTOWriteBlock(const char *Cmd) { return wrblLTO(blk, blkData, true); } -int dumpLTO(uint8_t *serial_number, uint8_t serial_len, uint8_t *dump, bool verbose) { +int dumpLTO(uint8_t *dump, bool verbose) { clearCommandBuffer(); lto_switch_on_field(); + uint8_t serial_number[5]; + uint8_t serial_len = sizeof(serial_number); uint8_t type_info[2]; int ret_val = lto_select(serial_number, serial_len, type_info, verbose); @@ -455,7 +466,7 @@ static int CmdHfLTODump(const char *Cmd) { bool errors = false; uint32_t dump_len = CM_MEM_MAX_SIZE; char filename[FILE_PATH_SIZE] = {0}; - uint8_t serial_number[5] = {0}; + char serial_number[10] = {0}; while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { @@ -490,7 +501,7 @@ static int CmdHfLTODump(const char *Cmd) { } // loop all blocks - int ret_val = dumpLTO(serial_number, sizeof(serial_number), dump, true); + int ret_val = dumpLTO(dump, true); if (ret_val != PM3_SUCCESS) { free(dump); return ret_val; @@ -498,7 +509,10 @@ static int CmdHfLTODump(const char *Cmd) { // save to file if (filename[0] == '\0') { - memcpy(filename, sprint_hex_inrow(serial_number, sizeof(serial_number)), sizeof(serial_number) * 2); + memcpy(serial_number, sprint_hex_inrow(dump, sizeof(serial_number)), sizeof(serial_number) * 2); + char tmp_name[17] = "hf_lto_"; + strcat(tmp_name, serial_number); + memcpy(filename, tmp_name, sizeof(tmp_name)); } saveFile(filename, ".bin", dump, dump_len); saveFileEML(filename, dump, dump_len, 32); @@ -509,10 +523,111 @@ static int CmdHfLTODump(const char *Cmd) { return PM3_SUCCESS; } +int restoreLTO(uint8_t *dump_data, bool verbose) { + + clearCommandBuffer(); + lto_switch_on_field(); + + uint8_t type_info[2]; + uint8_t serial_number[5]; + uint8_t serial_len = sizeof(serial_number); + int ret_val = lto_select(serial_number, serial_len, type_info, verbose); + + if (ret_val != PM3_SUCCESS) { + lto_switch_off_field(); + return ret_val; + } + + uint8_t blkData[32] = {0}; + + //Block address 0 and 1 are read-only + for(uint8_t blk = 2; blk < 255; blk++) { + + for (int i = 0; i < 32; i++) { + blkData[i] = dump_data[i + blk * 32]; + } + + ret_val = lto_wrbl(blk, blkData, verbose); + + if (ret_val != PM3_SUCCESS) { + lto_switch_off_field(); + return ret_val; + } + } + + lto_switch_off_field(); + return ret_val; +} + +static int CmdHfLTRestore(const char *Cmd) { + + uint8_t cmdp = 0; + bool errors = false; + int is_data_loaded = PM3_ESOFT; + + char filename[FILE_PATH_SIZE] = {0}; + char extension[FILE_PATH_SIZE] = {0}; + + uint8_t dump_data[CM_MEM_MAX_SIZE] = {0}; + size_t dump_datalen = 0; + + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { + case 'h': + return usage_lto_restore(); + case 'f': + param_getstr(Cmd, cmdp + 1, filename, FILE_PATH_SIZE); + if (strlen(filename) == 0) + errors = true; + cmdp += 2; + break; + default: + PrintAndLogEx(WARNING, "unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } + } + + if (errors || (strlen(filename)) == 0) { + usage_lto_restore(); + return PM3_EINVARG; + } + + // split file name into prefix and ext. + int fnLength; + + fnLength = strlen(filename); + + if (fnLength > 4) { + memcpy(extension, &filename[fnLength - 4], 4); + extension[5] = 0x00; + + // check if valid file extension and attempt to load data + if (memcmp(extension, ".bin", 4) == 0) { + filename[fnLength - 4] = 0x00; + is_data_loaded = loadFile(filename, ".bin", dump_data, sizeof(dump_data), &dump_datalen); + + } else if (memcmp(extension, ".eml", 4) == 0) { + filename[fnLength - 4] = 0x00; + dump_datalen = 12; + is_data_loaded = loadFileEML(filename, (uint8_t *)dump_data, &dump_datalen); + + } else + PrintAndLogEx(WARNING, "\nWarning: invalid dump filename "_YELLOW_("%s")"to restore!\n", filename); + } + + if (is_data_loaded == PM3_SUCCESS) { + return restoreLTO(dump_data, true); + } else { + return PM3_EFILE; + } + +} + static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, - {"dump", CmdHfLTODump, IfPm3Iso14443a, "Dump LTO-CM tag to file"}, -// {"restore", CmdHfLTRestore, IfPm3Iso14443a, "Restore dump file to LTO-CM tag"}, + {"dump", CmdHfLTODump, IfPm3Iso14443a, "Dump LTO-CM tag to file"}, + {"restore", CmdHfLTRestore, IfPm3Iso14443a, "Restore dump file to LTO-CM tag"}, {"info", CmdHfLTOInfo, IfPm3Iso14443a, "Tag information"}, {"rdbl", CmdHfLTOReadBlock, IfPm3Iso14443a, "Read block"}, {"wrbl", CmdHfLTOWriteBlock, IfPm3Iso14443a, "Write block"}, @@ -530,4 +645,3 @@ int CmdHFLTO(const char *Cmd) { clearCommandBuffer(); return CmdsParse(CommandTable, Cmd); } - diff --git a/client/cmdhflto.h b/client/cmdhflto.h index 2b771f0d8..67179c2ae 100644 --- a/client/cmdhflto.h +++ b/client/cmdhflto.h @@ -14,7 +14,8 @@ #include "common.h" int infoLTO(bool verbose); -int dumpLTO(uint8_t *serial_number, uint8_t serial_len, uint8_t *dump, bool verbose); +int dumpLTO(uint8_t *dump, bool verbose); +int restoreLTO(uint8_t *dump, bool verbose); int rdblLTO(uint8_t st_blk, uint8_t end_blk, bool verbose); int wrblLTO(uint8_t blk, uint8_t *data, bool verbose); int CmdHFLTO(const char *Cmd); From 52627833011741546e8a48163f5e41f5c4aa0dfe Mon Sep 17 00:00:00 2001 From: Kevin-Nakamoto Date: Thu, 6 Feb 2020 16:49:26 -0500 Subject: [PATCH 1549/1854] fix filename issue (dump) --- client/cmdhflto.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/client/cmdhflto.c b/client/cmdhflto.c index b4700cca0..7057fab36 100644 --- a/client/cmdhflto.c +++ b/client/cmdhflto.c @@ -509,7 +509,7 @@ static int CmdHfLTODump(const char *Cmd) { // save to file if (filename[0] == '\0') { - memcpy(serial_number, sprint_hex_inrow(dump, sizeof(serial_number)), sizeof(serial_number) * 2); + memcpy(serial_number, sprint_hex_inrow(dump, sizeof(serial_number)), sizeof(serial_number)); char tmp_name[17] = "hf_lto_"; strcat(tmp_name, serial_number); memcpy(filename, tmp_name, sizeof(tmp_name)); @@ -549,7 +549,9 @@ int restoreLTO(uint8_t *dump_data, bool verbose) { ret_val = lto_wrbl(blk, blkData, verbose); - if (ret_val != PM3_SUCCESS) { + if (ret_val == PM3_SUCCESS) { + PrintAndLogEx(SUCCESS, "BLK %03d: " _YELLOW_("write success"), blk); + } else { lto_switch_off_field(); return ret_val; } From 86fdf8e9879af07512fdbaf4df7fbf06df272682 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 12 Feb 2020 02:13:04 +0100 Subject: [PATCH 1550/1854] color --- client/ui.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/client/ui.c b/client/ui.c index 0cd2c589a..215bd66bc 100644 --- a/client/ui.c +++ b/client/ui.c @@ -240,7 +240,13 @@ static void fPrintAndLog(FILE *stream, const char *fmt, ...) { fprintf(stderr, "[-] Can't open logfile %s, logging disabled!\n", my_logfile_path); logging = 0; } else { - printf("[=] Session log %s\n", my_logfile_path); + + if (session.supports_colors) { + printf(_YELLOW_("[=]") "Session log " _YELLOW_("%s") "\n", my_logfile_path); + } else { + printf("[=] Session log %s\n", my_logfile_path); + } + } free(my_logfile_path); } From f32d94b99cf288ba9cebceb42020c285f038714f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 12 Feb 2020 02:26:05 +0100 Subject: [PATCH 1551/1854] textual --- client/flash.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/flash.c b/client/flash.c index 1f898f9d3..698e39187 100644 --- a/client/flash.c +++ b/client/flash.c @@ -527,7 +527,8 @@ const char ice[] = "...................................................................\n @@@ @@@@@@@ @@@@@@@@ @@@@@@@@@@ @@@@@@ @@@ @@@\n" " @@! !@@ @@! @@! @@! @@! @@! @@@ @@!@!@@@\n !!@ !@! @!!!:! @!! !!@ @!@ @!@!@!@! @!@@!!@!\n" " !!: :!! !!: !!: !!: !!: !!! !!: !!!\n : :: :: : : :: ::: : : : : : :: : \n" - _RED_(" . .. .. . . .. ... . . . . . .. . \n") + _RED_(" . .. .. . . .. ... . . . . . .. . ") + "\n...................................................................\n" ; // Write a file's segments to Flash From 31507be5490adb692e8bf02cb7d32c92cf1872c4 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 12 Feb 2020 02:26:44 +0100 Subject: [PATCH 1552/1854] textual --- client/comms.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/comms.c b/client/comms.c index ce8223ba3..7a9086873 100644 --- a/client/comms.c +++ b/client/comms.c @@ -547,6 +547,7 @@ bool OpenProxmark(void *port, bool wait_for_port, int timeout, bool flash_mode, PrintAndLogEx(SUCCESS, "Waiting for Proxmark3 to appear on " _YELLOW_("%s"), portname); fflush(stdout); int openCount = 0; + PrintAndLogEx(INPLACE, ""); do { sp = uart_open(portname, speed); msleep(500); @@ -587,7 +588,6 @@ bool OpenProxmark(void *port, bool wait_for_port, int timeout, bool flash_mode, session.pm3_present = true; fflush(stdout); - return true; } } From bc3f0c4da83757f35e9b7333c518edd9de224417 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 12 Feb 2020 09:52:23 +0100 Subject: [PATCH 1553/1854] fix: #555 fpga_compress missing tarbin directive --- tools/fpga_compress/Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/fpga_compress/Makefile b/tools/fpga_compress/Makefile index 86c995924..47f3c278c 100644 --- a/tools/fpga_compress/Makefile +++ b/tools/fpga_compress/Makefile @@ -19,3 +19,7 @@ fpga_compress: $(OBJDIR)/fpga_compress.o $(MYOBJS) $(OBJDIR)/libz.a: $(info [*] MAKE zlib) $(Q)$(MAKE) --no-print-directory -C $(ZLIBPATH) OBJDIR=$(ROOT_DIR)$(OBJDIR) BINDIR=$(ROOT_DIR)$(OBJDIR) all + +tarbin: $(BINS) + $(info [=] TAR ../proxmark3-$(platform)-bin.tar) + $(Q)$(TAR) $(TARFLAGS) ../../proxmark3-$(platform)-bin.tar $(BINS:%=fpga_compress/%) $(WINBINS:%=fpga_compress/%) \ No newline at end of file From fade194bbe19ee802fe0926c0195189a0f15fbf7 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 12 Feb 2020 09:57:00 +0100 Subject: [PATCH 1554/1854] ignore gz files --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 092ad9619..349ef5efb 100644 --- a/.gitignore +++ b/.gitignore @@ -20,6 +20,7 @@ *.dll *.moc.cpp *.z +*.gz *.Td *.DS_Store *.exe From 36f22341218ed6e2a9a330a4f7ece1823959dd50 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 12 Feb 2020 10:29:00 +0100 Subject: [PATCH 1555/1854] fix HF simulation --- armsrc/appmain.c | 45 ++++++++++++++++++---------------------- armsrc/iso14443a.c | 46 +++++++++++++++++++++++++++++++++++++++-- armsrc/iso14443b.c | 5 +++++ armsrc/mifaresim.c | 8 ++++++- armsrc/thinfilm.c | 12 +++++++---- common_arm/Makefile.hal | 2 +- 6 files changed, 85 insertions(+), 33 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 7c58fd7e6..15d939a35 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -208,12 +208,11 @@ void MeasureAntennaTuning(void) { FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR); SpinDelay(50); +#if defined RDV4 + payload.v_hf = (MAX_ADC_HF_VOLTAGE_RDV40 * AvgAdc(ADC_CHAN_HF_RDV40)) >> 10; +#else payload.v_hf = (MAX_ADC_HF_VOLTAGE * AvgAdc(ADC_CHAN_HF)) >> 10; - - // RDV40 will hit the roof, try other ADC channel used in that hardware revision. - if (payload.v_hf > MAX_ADC_HF_VOLTAGE - 300) { - payload.v_hf = (MAX_ADC_HF_VOLTAGE_RDV40 * AvgAdc(ADC_CHAN_HF_RDV40)) >> 10; - } +#endif FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); reply_ng(CMD_MEASURE_ANTENNA_TUNING, PM3_SUCCESS, (uint8_t *)&payload, sizeof(payload)); @@ -222,16 +221,13 @@ void MeasureAntennaTuning(void) { // Measure HF in milliVolt uint16_t MeasureAntennaTuningHfData(void) { - uint16_t volt = 0; - uint16_t avg = AvgAdc(ADC_CHAN_HF); - volt = (MAX_ADC_HF_VOLTAGE * avg) >> 10; - bool use_high = (volt > MAX_ADC_HF_VOLTAGE - 300); - if (use_high) { - volt = (MAX_ADC_HF_VOLTAGE_RDV40 * AvgAdc(ADC_CHAN_HF_RDV40)) >> 10; -// volt = (MAX_ADC_HF_VOLTAGE * AvgAdc(ADC_CHAN_HF)) >> 10; - } - return volt; +#if defined RDV4 + return (MAX_ADC_HF_VOLTAGE_RDV40 * AvgAdc(ADC_CHAN_HF_RDV40)) >> 10; +#else + return (MAX_ADC_HF_VOLTAGE * AvgAdc(ADC_CHAN_HF)) >> 10; +#endif + } // Measure LF in milliVolt @@ -532,7 +528,6 @@ void ListenReaderField(uint8_t limit) { uint16_t lf_av = 0, lf_av_new, lf_baseline = 0, lf_max = 0; uint16_t hf_av = 0, hf_av_new, hf_baseline = 0, hf_max = 0; uint16_t mode = 1, display_val, display_max; - bool use_high = false; // switch off FPGA - we don't want to measure our own signal // 20180315 - iceman, why load this before and then turn off? @@ -549,15 +544,12 @@ void ListenReaderField(uint8_t limit) { if (limit == HF_ONLY) { - hf_av = hf_max = AvgAdc(ADC_CHAN_HF); - +#if defined RDV4 // iceman, useless, since we are measuring readerfield, not our field. My tests shows a max of 20v from a reader. - // RDV40 will hit the roof, try other ADC channel used in that hardware revision. - use_high = (((MAX_ADC_HF_VOLTAGE * hf_max) >> 10) > MAX_ADC_HF_VOLTAGE - 300); - if (use_high) { - hf_av = hf_max = AvgAdc(ADC_CHAN_HF_RDV40); - } - + hf_av = hf_max = AvgAdc(ADC_CHAN_HF_RDV40); +#else + hf_av = hf_max = AvgAdc(ADC_CHAN_HF); +#endif Dbprintf("HF 13.56MHz Baseline: %dmV", (MAX_ADC_HF_VOLTAGE * hf_av) >> 10); hf_baseline = hf_av; } @@ -608,8 +600,11 @@ void ListenReaderField(uint8_t limit) { LED_B_OFF(); } - hf_av_new = (use_high) ? AvgAdc(ADC_CHAN_HF_RDV40) : AvgAdc(ADC_CHAN_HF); - +#if defined RDV4 + hf_av_new = AvgAdc(ADC_CHAN_HF_RDV40); +#else + hf_av_new = AvgAdc(ADC_CHAN_HF); +#endif // see if there's a significant change if (ABS(hf_av - hf_av_new) > REPORT_CHANGE) { Dbprintf("HF 13.56MHz Field Change: %5dmV", (MAX_ADC_HF_VOLTAGE * hf_av_new) >> 10); diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index b68edf58a..abfe07f10 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -1787,7 +1787,13 @@ int EmGetCmd(uint8_t *received, uint16_t *len, uint8_t *par) { ADC_MODE_PRESCALE(63) | ADC_MODE_STARTUP_TIME(1) | ADC_MODE_SAMPLE_HOLD_TIME(15); + +#if defined RDV4 + AT91C_BASE_ADC->ADC_CHER = ADC_CHANNEL(ADC_CHAN_HF_RDV40); +#else AT91C_BASE_ADC->ADC_CHER = ADC_CHANNEL(ADC_CHAN_HF); +#endif + // start ADC AT91C_BASE_ADC->ADC_CR = AT91C_ADC_START; @@ -1811,12 +1817,19 @@ int EmGetCmd(uint8_t *received, uint16_t *len, uint8_t *par) { ++check; // test if the field exists - if (AT91C_BASE_ADC->ADC_SR & ADC_END_OF_CONVERSION(ADC_CHAN_HF)) { +#if defined RDV4 + if (AT91C_BASE_ADC->ADC_SR & ADC_END_OF_CONVERSION(ADC_CHAN_HF_RDV40)) { + analogCnt++; - analogAVG += AT91C_BASE_ADC->ADC_CDR[ADC_CHAN_HF]; + + analogAVG += AT91C_BASE_ADC->ADC_CDR[ADC_CHAN_HF_RDV40]; + AT91C_BASE_ADC->ADC_CR = AT91C_ADC_START; + if (analogCnt >= 32) { + if ((MAX_ADC_HF_VOLTAGE_RDV40 * (analogAVG / analogCnt) >> 10) < MF_MINFIELDV) { + if (timer == 0) { timer = GetTickCount(); } else { @@ -1832,6 +1845,35 @@ int EmGetCmd(uint8_t *received, uint16_t *len, uint8_t *par) { analogAVG = 0; } } +#else + if (AT91C_BASE_ADC->ADC_SR & ADC_END_OF_CONVERSION(ADC_CHAN_HF)) { + + analogCnt++; + + analogAVG += AT91C_BASE_ADC->ADC_CDR[ADC_CHAN_HF]; + + AT91C_BASE_ADC->ADC_CR = AT91C_ADC_START; + + if (analogCnt >= 32) { + + if ((MAX_ADC_HF_VOLTAGE * (analogAVG / analogCnt) >> 10) < MF_MINFIELDV) { + + if (timer == 0) { + timer = GetTickCount(); + } else { + // 50ms no field --> card to idle state + if (GetTickCountDelta(timer) > 50) { + return 2; + } + } + } else { + timer = 0; + } + analogCnt = 0; + analogAVG = 0; + } + } +#endif // receive and test the miller decoding if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { diff --git a/armsrc/iso14443b.c b/armsrc/iso14443b.c index d68ddd044..31f2cae58 100644 --- a/armsrc/iso14443b.c +++ b/armsrc/iso14443b.c @@ -635,7 +635,12 @@ void SimulateIso14443bTag(uint32_t pupi) { // find reader field if (cardSTATE == SIM_NOFIELD) { + +#if defined RDV4 + vHf = (MAX_ADC_HF_VOLTAGE_RDV40 * AvgAdc(ADC_CHAN_HF_RDV40)) >> 10; +#else vHf = (MAX_ADC_HF_VOLTAGE * AvgAdc(ADC_CHAN_HF)) >> 10; +#endif if (vHf > MF_MINFIELDV) { cardSTATE = SIM_IDLE; LED_A_ON(); diff --git a/armsrc/mifaresim.c b/armsrc/mifaresim.c index 80881c416..0dcbe404a 100644 --- a/armsrc/mifaresim.c +++ b/armsrc/mifaresim.c @@ -537,7 +537,13 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1 // find reader field if (cardSTATE == MFEMUL_NOFIELD) { - vHf = (MAX_ADC_HF_VOLTAGE_RDV40 * AvgAdc(ADC_CHAN_HF)) >> 10; + +#if defined RDV4 + vHf = (MAX_ADC_HF_VOLTAGE_RDV40 * AvgAdc(ADC_CHAN_HF_RDV40)) >> 10; +#else + vHf = (MAX_ADC_HF_VOLTAGE * AvgAdc(ADC_CHAN_HF)) >> 10; +#endif + if (vHf > MF_MINFIELDV) { cardSTATE_TO_IDLE(); LED_A_ON(); diff --git a/armsrc/thinfilm.c b/armsrc/thinfilm.c index 46fa5a920..e4b2e9b23 100644 --- a/armsrc/thinfilm.c +++ b/armsrc/thinfilm.c @@ -52,10 +52,11 @@ void ReadThinFilm(void) { uint16_t FpgaSendQueueDelay; uint16_t ReadReaderField(void) { - uint16_t hf_av = AvgAdc(ADC_CHAN_HF); - if (((MAX_ADC_HF_VOLTAGE * hf_av) >> 10) > MAX_ADC_HF_VOLTAGE - 300) - hf_av = AvgAdc(ADC_CHAN_HF_RDV40); - return hf_av; +#if defined RDV4 + return AvgAdc(ADC_CHAN_HF_RDV40); +#else + return AvgAdc(ADC_CHAN_HF); +#endif } static void CodeThinfilmAsTag(const uint8_t *cmd, uint16_t len) { @@ -119,13 +120,16 @@ void SimulateThinFilm(uint8_t *data, size_t len) { CodeThinfilmAsTag(data, len); FpgaDownloadAndGo(FPGA_BITSTREAM_HF); + // Set up the synchronous serial port FpgaSetupSsc(); + // connect Demodulated Signal to ADC: SetAdcMuxFor(GPIO_MUXSEL_HIPKD); FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_TAGSIM_MOD); SpinDelay(100); + uint16_t hf_baseline = ReadReaderField(); // Start the timer diff --git a/common_arm/Makefile.hal b/common_arm/Makefile.hal index 8fe070582..455672e5f 100644 --- a/common_arm/Makefile.hal +++ b/common_arm/Makefile.hal @@ -56,7 +56,7 @@ endef PLTNAME = Unknown Platform ifeq ($(PLATFORM),PM3RDV4) - PLATFORM_DEFS = -DWITH_SMARTCARD -DWITH_FLASH + PLATFORM_DEFS = -DWITH_SMARTCARD -DWITH_FLASH -DRDV4 PLTNAME = Proxmark3 rdv4 else ifeq ($(PLATFORM),PM3OTHER) PLTNAME = Proxmark3 Generic target From 912cbe971386abc529ae66143edb7ff8763e09b0 Mon Sep 17 00:00:00 2001 From: Thorsten Bosbach Date: Fri, 14 Feb 2020 18:33:13 +0100 Subject: [PATCH 1556/1854] hitagS print whole memory + print succeeded challenges --- armsrc/hitagS.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/armsrc/hitagS.c b/armsrc/hitagS.c index 836df6e82..40cdf47ed 100644 --- a/armsrc/hitagS.c +++ b/armsrc/hitagS.c @@ -1341,6 +1341,8 @@ void ReadHitagS(hitag_function htf, hitag_data *htd) { Dbprintf("Page[ 2]: __ __ __ __"); Dbprintf("Page[ 3]: __ __ __ __"); } + // since page 2+3 are not accessible when LKP == 1 and AUT == 1 fastforward to next readable page + pageNum = 4; } txlen = 20; @@ -1950,6 +1952,11 @@ void check_challenges(bool file_given, uint8_t *data) { u1++; } else if (STATE == 2 && rxlen >= 44) { + Dbprintf("Challenge success: %02X%02X%02X%02X %02X%02X%02X%02X", + unlocker[u1 - 1][0], unlocker[u1 - 1][1], + unlocker[u1 - 1][2], unlocker[u1 - 1][3], + unlocker[u1 - 1][4], unlocker[u1 - 1][5], + unlocker[u1 - 1][6], unlocker[u1 - 1][7]); STATE = 0; } From d7c3cc8028b304fd9f2f06af86274aae5bce05cf Mon Sep 17 00:00:00 2001 From: mwalker33 Date: Sun, 16 Feb 2020 20:48:53 +1100 Subject: [PATCH 1557/1854] Update cmdlfkeri.c --- client/cmdlfkeri.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/client/cmdlfkeri.c b/client/cmdlfkeri.c index aadc8676d..1d49117d1 100644 --- a/client/cmdlfkeri.c +++ b/client/cmdlfkeri.c @@ -53,6 +53,57 @@ static int usage_lf_keri_sim(void) { PrintAndLogEx(NORMAL, " lf keri sim 112233"); return PM3_SUCCESS; } +static int CmdKeriMSDescramble (uint32_t *FC, uint32_t *ID, uint32_t CardID) +{ + uint8_t CardToID [] = { 0xff,0xff,0xff,0xff,0x0d,0x0c,0x11,0x05,0xff,0x06,0xff,0x12,0x08,0xff,0x00,0x07, + 0x0a,0xff,0xff,0x0b,0x04,0x01,0xff,0x13,0xff,0x14,0x02,0xff,0x03,0x09,0xff,0xff }; + uint8_t CardToFC [] = { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0x02,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0xff }; + uint8_t CardIdx; // 0 - 31 + bool BitState; + int idx; + + char IDDecodeState[33] = {0x00}; + char FCDecodeState[33] = {0x00}; + + memset (IDDecodeState,'-',32); + memset (FCDecodeState,'-',32); + + + + *FC = 0; + *ID = 0; + + for (CardIdx = 0; CardIdx < 32; CardIdx++) { + // Get Bit State + BitState = (CardID >> CardIdx) & 1; + //if (BitState) { // its a 1 + idx = CardToID[CardIdx]; + if ((idx >= 0) && (idx <= 32)) { + if (BitState) + *ID = *ID | (1 << idx); + IDDecodeState[idx] = '0'+BitState; + } + //else + // IDDecodeState[CardIdx] = '-'; + + idx = CardToFC[CardIdx]; + if ((idx >= 0) && (idx <= 32)) { + if (BitState) + *FC = *FC | (1 << idx); + FCDecodeState[idx] = '0'+BitState; + } + //else + // IDDecodeState[CardIdx] = '-'; + + // } + } + + PrintAndLogEx(SUCCESS, "BitState ID : %s",IDDecodeState); + PrintAndLogEx(SUCCESS, "BitState FC : %s",FCDecodeState); + + return PM3_SUCCESS; +} static int CmdKeriDemod(const char *Cmd) { (void)Cmd; // Cmd is not used so far @@ -103,6 +154,18 @@ static int CmdKeriDemod(const char *Cmd) { PrintAndLogEx(SUCCESS, "KERI Tag Found -- Internal ID: %u", ID); PrintAndLogEx(SUCCESS, "Raw: %08X%08X", raw1, raw2); +/* + Descramble Data. +*/ + uint32_t fc = 0; + uint32_t imprintID = 0; + + // Just need to the low 32 bits without the 111 trailer + CmdKeriMSDescramble (&fc,&imprintID,raw2); + + PrintAndLogEx (SUCCESS,"Descrambled MS : FC %d - imprint id %d\n",fc,imprintID); + +// End Descramble test if (invert) { PrintAndLogEx(INFO, "Had to Invert - probably KERI"); From c6ceeed6d563760305a3ebf91ecb2d4739d7b504 Mon Sep 17 00:00:00 2001 From: mwalker33 Date: Mon, 17 Feb 2020 21:49:43 +1100 Subject: [PATCH 1558/1854] Update cmdlfkeri.c --- client/cmdlfkeri.c | 131 ++++++++++++++++++++++++++++++++------------- 1 file changed, 95 insertions(+), 36 deletions(-) diff --git a/client/cmdlfkeri.c b/client/cmdlfkeri.c index 1d49117d1..d10063edb 100644 --- a/client/cmdlfkeri.c +++ b/client/cmdlfkeri.c @@ -53,55 +53,112 @@ static int usage_lf_keri_sim(void) { PrintAndLogEx(NORMAL, " lf keri sim 112233"); return PM3_SUCCESS; } -static int CmdKeriMSDescramble (uint32_t *FC, uint32_t *ID, uint32_t CardID) + +typedef enum {Scramble = 0,Descramble = 1} KeriMSScramble_t; + +static int CmdKeriMSScramble (KeriMSScramble_t Action, uint32_t *FC, uint32_t *ID, uint32_t *CardID) { uint8_t CardToID [] = { 0xff,0xff,0xff,0xff,0x0d,0x0c,0x11,0x05,0xff,0x06,0xff,0x12,0x08,0xff,0x00,0x07, 0x0a,0xff,0xff,0x0b,0x04,0x01,0xff,0x13,0xff,0x14,0x02,0xff,0x03,0x09,0xff,0xff }; uint8_t CardToFC [] = { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 0xff,0xff,0x02,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0xff }; + + uint8_t IDToCard [] = { 0x0e,0x15,0x1a,0x1c,0x14,0x07,0x09,0x0f,0x0c,0x1d,0x10,0x13,0x05,0x04,0xff,0xff, + 0xff,0x06,0x0b,0x17,0x19,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff }; + uint8_t FCToCard [] = { 0xff,0x1e,0x12,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff }; + uint8_t CardIdx; // 0 - 31 bool BitState; int idx; - char IDDecodeState[33] = {0x00}; - char FCDecodeState[33] = {0x00}; - - memset (IDDecodeState,'-',32); - memset (FCDecodeState,'-',32); - - + if (Action == Descramble) { + char IDDecodeState[33] = {0x00}; + char FCDecodeState[33] = {0x00}; - *FC = 0; - *ID = 0; + memset (IDDecodeState,'-',32); + memset (FCDecodeState,'-',32); - for (CardIdx = 0; CardIdx < 32; CardIdx++) { - // Get Bit State - BitState = (CardID >> CardIdx) & 1; - //if (BitState) { // its a 1 - idx = CardToID[CardIdx]; - if ((idx >= 0) && (idx <= 32)) { - if (BitState) - *ID = *ID | (1 << idx); - IDDecodeState[idx] = '0'+BitState; + *FC = 0; + *ID = 0; + + for (CardIdx = 0; CardIdx < 32; CardIdx++) { + // Get Bit State + BitState = (*CardID >> CardIdx) & 1; + //if (BitState) { // its a 1 + idx = CardToID[CardIdx]; + if ((idx >= 0) && (idx <= 32)) { + if (BitState) + *ID = *ID | (1 << idx); + IDDecodeState[31-idx] = '0'+BitState; + } + + idx = CardToFC[CardIdx]; + if ((idx >= 0) && (idx <= 32)) { + if (BitState) + *FC = *FC | (1 << idx); + FCDecodeState[31-idx] = '0'+BitState; + } } - //else - // IDDecodeState[CardIdx] = '-'; - - idx = CardToFC[CardIdx]; - if ((idx >= 0) && (idx <= 32)) { - if (BitState) - *FC = *FC | (1 << idx); - FCDecodeState[idx] = '0'+BitState; - } - //else - // IDDecodeState[CardIdx] = '-'; - // } + // Patch for bit order group unknown + // Reverse order for easy mapping for unknowns + // I know that these bit groups are a in the correct location, unknown order. + if (IDDecodeState[31-17] == '1') IDDecodeState[31-17] = '?'; + if (IDDecodeState[31-18] == '1') IDDecodeState[31-18] = '?'; + if (IDDecodeState[31-19] == '1') IDDecodeState[31-19] = '?'; + if (IDDecodeState[31-20] == '1') IDDecodeState[31-20] = '?'; + + if (FCDecodeState[31- 1] == '1') FCDecodeState[31- 1] = '?'; + if (FCDecodeState[31- 2] == '1') FCDecodeState[31- 2] = '?'; + + PrintAndLogEx(SUCCESS, "BitState ID : %s",IDDecodeState); + PrintAndLogEx(SUCCESS, "BitState FC : %s",FCDecodeState); } + if (Action == Scramble) + { + // PrintAndLogEx(SUCCESS, "Scramble FC : %d - ID %d",*FC,*ID); + *CardID = 0; // set to 0 - PrintAndLogEx(SUCCESS, "BitState ID : %s",IDDecodeState); - PrintAndLogEx(SUCCESS, "BitState FC : %s",FCDecodeState); + for (CardIdx = 0; CardIdx < 32; CardIdx++) + { + // Card ID + BitState = (*ID >> CardIdx) & 1; + if (BitState) { + idx = IDToCard[CardIdx]; + if ((idx >= 0) && (idx <= 32)) { + *CardID |= (1 << idx); + } + } + // FC + BitState = (*FC >> CardIdx) & 1; + if (BitState) { + idx = FCToCard[CardIdx]; + if ((idx >= 0) && (idx <= 32)) { + *CardID |= (1 << idx); + } + } + } + // Fixed bits + /* + Add Parity and Fixed bits + Bit 3 - Note Used/Fixed 1 + Bit 31 - 1 Fixed + Bit 0,1 - 2 Bit Parity + */ + *CardID |= (1 << 3); + // Check/Parity Bits + int Parity = 1; + for (CardIdx = 4; CardIdx <= 31; CardIdx += 2) { + Parity = Parity ^ ((*CardID >> CardIdx) & 11); + } + *CardID = *CardID | Parity; + + // Bit 31 was fixed but not in check/parity bits + *CardID |= (1 << 31); + PrintAndLogEx(SUCCESS, "Scrambled FC : %d - Card ID : %d to RAW : E0000000%08X",*FC,*ID,*CardID); + } return PM3_SUCCESS; } @@ -158,13 +215,15 @@ static int CmdKeriDemod(const char *Cmd) { Descramble Data. */ uint32_t fc = 0; - uint32_t imprintID = 0; + uint32_t cardid = 0; // Just need to the low 32 bits without the 111 trailer - CmdKeriMSDescramble (&fc,&imprintID,raw2); + CmdKeriMSScramble (Descramble,&fc,&cardid,&raw2); - PrintAndLogEx (SUCCESS,"Descrambled MS : FC %d - imprint id %d\n",fc,imprintID); + PrintAndLogEx (SUCCESS,"Descrambled MS : FC %d - Card ID %d\n",fc,cardid); + uint32_t testCard = 0; + CmdKeriMSScramble (Scramble,&fc,&cardid,&testCard); // End Descramble test if (invert) { From bf66d66114037461b0e839698bc121b945dab316 Mon Sep 17 00:00:00 2001 From: Iceman Date: Mon, 17 Feb 2020 20:19:40 +0100 Subject: [PATCH 1559/1854] Update Troubleshooting.md --- doc/md/Installation_Instructions/Troubleshooting.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/doc/md/Installation_Instructions/Troubleshooting.md b/doc/md/Installation_Instructions/Troubleshooting.md index ab893d177..e727180bf 100644 --- a/doc/md/Installation_Instructions/Troubleshooting.md +++ b/doc/md/Installation_Instructions/Troubleshooting.md @@ -18,6 +18,7 @@ Always use the latest repository commits from *master* branch. There are always * [File not found](#file-not-found) * [Pixmap / pixbuf warnings](#pixmap--pixbuf-warnings) * [Usb cable](#usb-cable) + * [WSL 2 explorer.exe . doesnt work](WSL-2) ## `pm3` or `pm3-flash*` doesn't see my Proxmark @@ -164,3 +165,11 @@ If you get warnings related to pixmap or pixbuf such as *Pixbuf theme: Cannot lo It's needed to have a good USB cable to connect Proxmark3 to USB. If you have stability problems (Proxmark3 resets, firmware hangs, especially firmware hangs just after start, etc.) - check your cable with a USB tester (or try to change it). It needs to have a resistance smaller or equal to 0.3 Ohm. + +## WSL 2 +When ```explorer.exe .``` doesn't work. +Trying to access the dump files created in WSL, you will need to run ```explorer.exe .``` but sometimes this doesn't work. +[As seen here](https://github.com/microsoft/WSL/issues/4027) they suggest checking the following registry value for *P9NP* + +[](www.icedev.se/proxmark3/rdv40/wsl2_p9np.png) + From 7d157606ee0844491143969a492afe8aef882b98 Mon Sep 17 00:00:00 2001 From: Joe Harrison Date: Mon, 17 Feb 2020 23:49:29 +0000 Subject: [PATCH 1560/1854] Use /usr/bin/env in shebangs Stop assuming that bash is in /bin, and that perl and python are in /usr/bin, etc. Instead, use env command to find these commands in the path. --- client/gen_pm3mfsim_script.sh | 2 +- covbuild.sh | 2 +- covconfig.sh | 2 +- covsubmit.sh | 2 +- pm3 | 2 +- pm3-flash | 2 +- pm3-flash-all | 2 +- pm3-flash-bootrom | 2 +- pm3test.sh | 2 +- tools/analyzesize.py | 2 +- tools/findbits_test.py | 2 +- tools/hitag2crack/crack2/runtest.sh | 2 +- tools/jtag_openocd/openocd_flash_dump.sh | 2 +- tools/jtag_openocd/openocd_flash_recovery.sh | 2 +- tools/jtag_openocd/openocd_interactive.sh | 2 +- tools/mkversion.pl | 2 +- tools/pm3_amii_bin2eml.pl | 2 +- tools/pm3_cs8.pl | 2 +- tools/pm3_eml2lower.sh | 2 +- tools/pm3_eml2upper.sh | 2 +- tools/pm3_eml_mfd_test.py | 2 +- tools/rfidtest.pl | 2 +- tools/xorcheck.py | 2 +- 23 files changed, 23 insertions(+), 23 deletions(-) diff --git a/client/gen_pm3mfsim_script.sh b/client/gen_pm3mfsim_script.sh index 86f368673..73c7a4dd4 100644 --- a/client/gen_pm3mfsim_script.sh +++ b/client/gen_pm3mfsim_script.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # Andrei Costin , 2011 # gen_pm3mfsim_script.sh diff --git a/covbuild.sh b/covbuild.sh index 1899cb8b3..2e18e677f 100755 --- a/covbuild.sh +++ b/covbuild.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e . .coverity.conf || exit 1 diff --git a/covconfig.sh b/covconfig.sh index 24815f200..b762ac6f1 100755 --- a/covconfig.sh +++ b/covconfig.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e . .coverity.conf || exit 1 diff --git a/covsubmit.sh b/covsubmit.sh index e39240954..61ca853f1 100755 --- a/covsubmit.sh +++ b/covsubmit.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e . .coverity.conf || exit 1 diff --git a/pm3 b/pm3 index d40fb0a91..e702e277f 100755 --- a/pm3 +++ b/pm3 @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # Usage: run option -h to get help diff --git a/pm3-flash b/pm3-flash index e5cd5479d..c5e920c24 100755 --- a/pm3-flash +++ b/pm3-flash @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash PM3PATH=$(dirname "$0") . "$PM3PATH/pm3" diff --git a/pm3-flash-all b/pm3-flash-all index e5cd5479d..c5e920c24 100755 --- a/pm3-flash-all +++ b/pm3-flash-all @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash PM3PATH=$(dirname "$0") . "$PM3PATH/pm3" diff --git a/pm3-flash-bootrom b/pm3-flash-bootrom index e5cd5479d..c5e920c24 100755 --- a/pm3-flash-bootrom +++ b/pm3-flash-bootrom @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash PM3PATH=$(dirname "$0") . "$PM3PATH/pm3" diff --git a/pm3test.sh b/pm3test.sh index de9134ba1..146650f71 100755 --- a/pm3test.sh +++ b/pm3test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash PM3PATH=$(dirname "$0") cd "$PM3PATH" || exit 1 diff --git a/tools/analyzesize.py b/tools/analyzesize.py index 889222c01..965fe3d66 100755 --- a/tools/analyzesize.py +++ b/tools/analyzesize.py @@ -1,4 +1,4 @@ -#! /usr/bin/python3 +#! /usr/bin/env python3 import json import subprocess diff --git a/tools/findbits_test.py b/tools/findbits_test.py index db8dda8fa..d52334fd4 100644 --- a/tools/findbits_test.py +++ b/tools/findbits_test.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python from itertools import imap import unittest, sys, findbits diff --git a/tools/hitag2crack/crack2/runtest.sh b/tools/hitag2crack/crack2/runtest.sh index bcc08727c..2d9256d94 100755 --- a/tools/hitag2crack/crack2/runtest.sh +++ b/tools/hitag2crack/crack2/runtest.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash if [ "$1" == "" ]; then echo "runtest.sh testfile" diff --git a/tools/jtag_openocd/openocd_flash_dump.sh b/tools/jtag_openocd/openocd_flash_dump.sh index 650c218f1..4791b9112 100755 --- a/tools/jtag_openocd/openocd_flash_dump.sh +++ b/tools/jtag_openocd/openocd_flash_dump.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash cd $(dirname "$0") . openocd_configuration || exit 1 diff --git a/tools/jtag_openocd/openocd_flash_recovery.sh b/tools/jtag_openocd/openocd_flash_recovery.sh index 80caa08f0..490cf4abd 100755 --- a/tools/jtag_openocd/openocd_flash_recovery.sh +++ b/tools/jtag_openocd/openocd_flash_recovery.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash cd $(dirname "$0") . openocd_configuration || exit 1 diff --git a/tools/jtag_openocd/openocd_interactive.sh b/tools/jtag_openocd/openocd_interactive.sh index ac022f3f2..995ee6913 100755 --- a/tools/jtag_openocd/openocd_interactive.sh +++ b/tools/jtag_openocd/openocd_interactive.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash cd $(dirname "$0") . openocd_configuration || exit 1 diff --git a/tools/mkversion.pl b/tools/mkversion.pl index 997c2081b..95a794697 100644 --- a/tools/mkversion.pl +++ b/tools/mkversion.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl -w +#!/usr/bin/env perl -w # Output a version.c file that includes information about the current build # Normally a couple of lines of bash would be enough (see openpcd project, original firmware by Harald Welte and Milosch Meriac) diff --git a/tools/pm3_amii_bin2eml.pl b/tools/pm3_amii_bin2eml.pl index bb16960d4..b042e1e73 100755 --- a/tools/pm3_amii_bin2eml.pl +++ b/tools/pm3_amii_bin2eml.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl # # Read Amiibo data, decrypt, and produce EML file # Convert proxmark MFU (MIFARE Ultralight) .bin to .eml format diff --git a/tools/pm3_cs8.pl b/tools/pm3_cs8.pl index f1bfaf81d..888e7c360 100755 --- a/tools/pm3_cs8.pl +++ b/tools/pm3_cs8.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl # # Convert proxmark3 trace or wav files to formats to be used by Inspectrum # diff --git a/tools/pm3_eml2lower.sh b/tools/pm3_eml2lower.sh index 086439c3c..b1c8d12f2 100755 --- a/tools/pm3_eml2lower.sh +++ b/tools/pm3_eml2lower.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # Andrei Costin , 2011 # pm3_eml2lower.sh diff --git a/tools/pm3_eml2upper.sh b/tools/pm3_eml2upper.sh index 73b8646b7..bac3237cc 100755 --- a/tools/pm3_eml2upper.sh +++ b/tools/pm3_eml2upper.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # Andrei Costin , 2011 # pm3_eml2upper.sh diff --git a/tools/pm3_eml_mfd_test.py b/tools/pm3_eml_mfd_test.py index 171bad843..4be66e83a 100755 --- a/tools/pm3_eml_mfd_test.py +++ b/tools/pm3_eml_mfd_test.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python from __future__ import with_statement from tempfile import mkdtemp diff --git a/tools/rfidtest.pl b/tools/rfidtest.pl index 304f59454..861f2a20a 100644 --- a/tools/rfidtest.pl +++ b/tools/rfidtest.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl # -samy kamkar, rfid@samy.pl use strict; diff --git a/tools/xorcheck.py b/tools/xorcheck.py index 091998a31..04c031cf1 100755 --- a/tools/xorcheck.py +++ b/tools/xorcheck.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # xorcheck.py - find xor values for 8-bit LRC # From 5e88faa2cf32df0456c6e327313606f5e18ef5e7 Mon Sep 17 00:00:00 2001 From: Joe Harrison Date: Wed, 19 Feb 2020 16:13:17 +0000 Subject: [PATCH 1561/1854] use env in shebangs in pm3-flash-fullimage and rest of tools --- pm3-flash-fullimage | 2 +- tools/findbits.py | 2 +- tools/pm3_eml2mfd.py | 2 +- tools/pm3_mfd2eml.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pm3-flash-fullimage b/pm3-flash-fullimage index e5cd5479d..c5e920c24 100755 --- a/pm3-flash-fullimage +++ b/pm3-flash-fullimage @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash PM3PATH=$(dirname "$0") . "$PM3PATH/pm3" diff --git a/tools/findbits.py b/tools/findbits.py index fb088d739..d3f4c6bcd 100755 --- a/tools/findbits.py +++ b/tools/findbits.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # findbits.py - find Binary, Octal, Decimal or Hex number in bitstream # diff --git a/tools/pm3_eml2mfd.py b/tools/pm3_eml2mfd.py index 86c6df301..4e41604f1 100755 --- a/tools/pm3_eml2mfd.py +++ b/tools/pm3_eml2mfd.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python ''' # Andrei Costin , 2011 diff --git a/tools/pm3_mfd2eml.py b/tools/pm3_mfd2eml.py index 44d60e7d6..a2d8389fa 100755 --- a/tools/pm3_mfd2eml.py +++ b/tools/pm3_mfd2eml.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python ''' # Andrei Costin , 2011 From f32efd10fedaee60c8d3613fd50eaf2c33abbd6e Mon Sep 17 00:00:00 2001 From: mwalker33 Date: Fri, 21 Feb 2020 22:21:56 +1100 Subject: [PATCH 1562/1854] Update cmdlfkeri.c --- client/cmdlfkeri.c | 89 ++++++++++++++++++++-------------------------- 1 file changed, 39 insertions(+), 50 deletions(-) diff --git a/client/cmdlfkeri.c b/client/cmdlfkeri.c index d10063edb..892dfaf5f 100644 --- a/client/cmdlfkeri.c +++ b/client/cmdlfkeri.c @@ -58,50 +58,42 @@ typedef enum {Scramble = 0,Descramble = 1} KeriMSScramble_t; static int CmdKeriMSScramble (KeriMSScramble_t Action, uint32_t *FC, uint32_t *ID, uint32_t *CardID) { - uint8_t CardToID [] = { 0xff,0xff,0xff,0xff,0x0d,0x0c,0x11,0x05,0xff,0x06,0xff,0x12,0x08,0xff,0x00,0x07, - 0x0a,0xff,0xff,0x0b,0x04,0x01,0xff,0x13,0xff,0x14,0x02,0xff,0x03,0x09,0xff,0xff }; - uint8_t CardToFC [] = { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0x02,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0xff }; - - uint8_t IDToCard [] = { 0x0e,0x15,0x1a,0x1c,0x14,0x07,0x09,0x0f,0x0c,0x1d,0x10,0x13,0x05,0x04,0xff,0xff, - 0xff,0x06,0x0b,0x17,0x19,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff }; - uint8_t FCToCard [] = { 0xff,0x1e,0x12,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff }; + // 255 = Not used/Unknown other values are the bit offset in the ID/FC values + uint8_t CardToID [] = { 255,255,255,255, 13, 12, 17, 5,255, 6,255, 18, 8,255, 0, 7, + 10,255,255, 11, 4, 1,255, 19,255, 20, 2,255, 3, 9,255,255 }; + uint8_t CardToFC [] = { 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255, 2,255,255,255,255,255,255,255,255,255,255,255, 1,255 }; uint8_t CardIdx; // 0 - 31 bool BitState; - int idx; + + // Used to track known bit states - remove when all bit maps are known + char IDDecodeState[33] = {0x00}; + char FCDecodeState[33] = {0x00}; + memset (IDDecodeState,'-',32); + memset (FCDecodeState,'-',32); if (Action == Descramble) { - char IDDecodeState[33] = {0x00}; - char FCDecodeState[33] = {0x00}; - - memset (IDDecodeState,'-',32); - memset (FCDecodeState,'-',32); - *FC = 0; *ID = 0; - for (CardIdx = 0; CardIdx < 32; CardIdx++) { // Get Bit State BitState = (*CardID >> CardIdx) & 1; - //if (BitState) { // its a 1 - idx = CardToID[CardIdx]; - if ((idx >= 0) && (idx <= 32)) { - if (BitState) - *ID = *ID | (1 << idx); - IDDecodeState[31-idx] = '0'+BitState; + // Card ID + if (CardToID[CardIdx] < 32) { + *ID = *ID | (BitState << CardToID[CardIdx]); + // Remove when all bits are known + IDDecodeState[31-CardToID[CardIdx]] = '0'+BitState; } - - idx = CardToFC[CardIdx]; - if ((idx >= 0) && (idx <= 32)) { - if (BitState) - *FC = *FC | (1 << idx); - FCDecodeState[31-idx] = '0'+BitState; + // Card FC + if (CardToFC[CardIdx] < 32) { + *FC = *FC | (BitState << CardToFC[CardIdx]); + // Remove when all bits are known + FCDecodeState[31-CardToFC[CardIdx]] = '0'+BitState; } } - // Patch for bit order group unknown + // Patch for bit order group unknown - remove when all Keri MS Bits maps are known // Reverse order for easy mapping for unknowns // I know that these bit groups are a in the correct location, unknown order. if (IDDecodeState[31-17] == '1') IDDecodeState[31-17] = '?'; @@ -115,38 +107,34 @@ static int CmdKeriMSScramble (KeriMSScramble_t Action, uint32_t *FC, uint32_t *I PrintAndLogEx(SUCCESS, "BitState ID : %s",IDDecodeState); PrintAndLogEx(SUCCESS, "BitState FC : %s",FCDecodeState); } + if (Action == Scramble) { - // PrintAndLogEx(SUCCESS, "Scramble FC : %d - ID %d",*FC,*ID); *CardID = 0; // set to 0 for (CardIdx = 0; CardIdx < 32; CardIdx++) { // Card ID - BitState = (*ID >> CardIdx) & 1; - if (BitState) { - idx = IDToCard[CardIdx]; - if ((idx >= 0) && (idx <= 32)) { - *CardID |= (1 << idx); - } - } - // FC - BitState = (*FC >> CardIdx) & 1; - if (BitState) { - idx = FCToCard[CardIdx]; - if ((idx >= 0) && (idx <= 32)) { - *CardID |= (1 << idx); - } - } + if (CardToID[CardIdx] < 32) { + if ((*ID & (1 << CardToID[CardIdx])) > 0) + *CardID |= (1 << CardIdx); + } + // Card FC + if (CardToFC[CardIdx] < 32) { + if ((*ID & (1 << CardToFC[CardIdx])) > 0) + *CardID |= (1 << CardIdx); + } } - // Fixed bits + + // Fixed bits and parity/check bits /* Add Parity and Fixed bits - Bit 3 - Note Used/Fixed 1 - Bit 31 - 1 Fixed + Bit 3 - Note Used/Fixed 1 - TBC + Bit 31 - 1 Fixed Not in check/parity Bit 0,1 - 2 Bit Parity */ *CardID |= (1 << 3); + // Check/Parity Bits int Parity = 1; for (CardIdx = 4; CardIdx <= 31; CardIdx += 2) { @@ -156,7 +144,7 @@ static int CmdKeriMSScramble (KeriMSScramble_t Action, uint32_t *FC, uint32_t *I // Bit 31 was fixed but not in check/parity bits *CardID |= (1 << 31); - + PrintAndLogEx(SUCCESS, "Scrambled FC : %d - Card ID : %d to RAW : E0000000%08X",*FC,*ID,*CardID); } return PM3_SUCCESS; @@ -224,6 +212,7 @@ static int CmdKeriDemod(const char *Cmd) { uint32_t testCard = 0; CmdKeriMSScramble (Scramble,&fc,&cardid,&testCard); + // End Descramble test if (invert) { From 788e8b7eccea38167caf8d6d5baab52cf9f9c872 Mon Sep 17 00:00:00 2001 From: Joe Harrison Date: Fri, 21 Feb 2020 13:37:43 +0000 Subject: [PATCH 1563/1854] Remove potentially undefined exit behaviour from analyzesize tool Python2.7 doc for `sys` module states that "Most systems require [the exit code] to be in the range 0-127, and produce undefined results otherwise". Currently, modern Linux-based systems will exit with code 255, while msys2-based systems such as Proxspace will exit with code 127. Instead, explicitly exit with non-zero exit code of 1. --- tools/analyzesize.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/analyzesize.py b/tools/analyzesize.py index 889222c01..37024f939 100755 --- a/tools/analyzesize.py +++ b/tools/analyzesize.py @@ -17,7 +17,7 @@ except FileNotFoundError: if len(sys.argv) < 3: print("Usage: analyzesize.py ") - exit(-1) + exit(2) action, name = sys.argv[1:3] currentdata = subprocess.run(["arm-none-eabi-size","armsrc/obj/fullimage.stage1.elf"], stdout=subprocess.PIPE).stdout currentdata = currentdata.split(b"\n")[1].strip() From 15b661dbfb72333fd87fd28481a22e0e20a2c9a8 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 21 Feb 2020 15:35:58 +0100 Subject: [PATCH 1564/1854] plot_edgedetect.py converted to python3 --- fpga/tests/plot_edgedetect.py | 36 +++++++++++------------------------ 1 file changed, 11 insertions(+), 25 deletions(-) diff --git a/fpga/tests/plot_edgedetect.py b/fpga/tests/plot_edgedetect.py index 3249de6c2..d5bb34991 100755 --- a/fpga/tests/plot_edgedetect.py +++ b/fpga/tests/plot_edgedetect.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 #----------------------------------------------------------------------------- # Copyright (C) 2014 iZsh # @@ -11,7 +11,7 @@ import matplotlib.pyplot as plt import sys if len(sys.argv) != 2: - print "Usage: %s " % sys.argv[0] + print("Usage: %s " % sys.argv[0]) sys.exit(1) BASENAME = sys.argv[1] @@ -21,29 +21,15 @@ nx = numpy.fromfile(BASENAME + ".time") def plot_time(dat1): plt.plot(nx, dat1) -sig = open(BASENAME + ".filtered").read() -sig = map(lambda x: ord(x), sig) - -min_vals = open(BASENAME + ".min").read() -min_vals = map(lambda x: ord(x), min_vals) - -max_vals = open(BASENAME + ".max").read() -max_vals = map(lambda x: ord(x), max_vals) - -states = open(BASENAME + ".state").read() -states = map(lambda x: ord(x) * 10 + 65, states) - -toggles = open(BASENAME+ ".toggle").read() -toggles = map(lambda x: ord(x) * 10 + 80, toggles) - -high = open(BASENAME + ".high").read() -high = map(lambda x: ord(x), high) -highz = open(BASENAME + ".highz").read() -highz = map(lambda x: ord(x), highz) -lowz = open(BASENAME + ".lowz").read() -lowz = map(lambda x: ord(x), lowz) -low = open(BASENAME + ".low").read() -low = map(lambda x: ord(x), low) +sig = bytearray(open(BASENAME + ".filtered", 'rb').read()) +min_vals = bytearray(open(BASENAME + ".min", 'rb').read()) +max_vals = bytearray(open(BASENAME + ".max", 'rb').read()) +states = bytearray(open(BASENAME + ".state", 'rb').read()) +toggles = bytearray(open(BASENAME+ ".toggle", 'rb').read()) +high = bytearray(open(BASENAME + ".high", 'rb').read()) +highz = bytearray(open(BASENAME + ".highz", 'rb').read()) +lowz = bytearray(open(BASENAME + ".lowz", 'rb').read()) +low = bytearray(open(BASENAME + ".low", 'rb').read()) plot_time(sig) plot_time(min_vals) From 2177211b7a310597ff34ad6ae1eb7765c151019c Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 21 Feb 2020 16:06:40 +0100 Subject: [PATCH 1565/1854] btaddon scripts: warn for pyserial --- tools/btaddon/hc06_console_AT.py | 6 +++++- tools/btaddon/hc06_factory.py | 8 +++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/tools/btaddon/hc06_console_AT.py b/tools/btaddon/hc06_console_AT.py index 6520aa9aa..4b0d7fd96 100755 --- a/tools/btaddon/hc06_console_AT.py +++ b/tools/btaddon/hc06_console_AT.py @@ -2,7 +2,11 @@ import sys import time -import serial +try: + import serial +except ModuleNotFoundError: + print("Please install pyserial module first.") + sys.exit(1) if len(sys.argv) < 2: print('Usage: %s ' % sys.argv[0]) diff --git a/tools/btaddon/hc06_factory.py b/tools/btaddon/hc06_factory.py index f6d0f25b2..093f25322 100755 --- a/tools/btaddon/hc06_factory.py +++ b/tools/btaddon/hc06_factory.py @@ -1,7 +1,13 @@ #!/usr/bin/env python3 import time -import serial +import sys + +try: + import serial +except ModuleNotFoundError: + print("Please install pyserial module first.") + sys.exit(1) name = b'PM3_RDV4.0' pin = b'1234' From af7fb17607e9d6ff07dd3f2d1efa8fc0ce099433 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 21 Feb 2020 16:10:18 +0100 Subject: [PATCH 1566/1854] plotedge script: warn for numpy, matplotlib --- fpga/tests/plot_edgedetect.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/fpga/tests/plot_edgedetect.py b/fpga/tests/plot_edgedetect.py index d5bb34991..63925bd99 100755 --- a/fpga/tests/plot_edgedetect.py +++ b/fpga/tests/plot_edgedetect.py @@ -6,9 +6,19 @@ # at your option, any later version. See the LICENSE.txt file for the text of # the license. #----------------------------------------------------------------------------- -import numpy -import matplotlib.pyplot as plt + import sys +try: + import numpy +except ModuleNotFoundError: + print("Please install numpy module first.") + sys.exit(1) + +try: + import matplotlib.pyplot as plt +except ModuleNotFoundError: + print("Please install matplotlib module first.") + sys.exit(1) if len(sys.argv) != 2: print("Usage: %s " % sys.argv[0]) From 5527cb2428df3bd7c31bbbd12384942b67398248 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 21 Feb 2020 16:17:56 +0100 Subject: [PATCH 1567/1854] pm3_mfdread.py script python3 and warn for bitstring module --- tools/pm3_mfdread.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/tools/pm3_mfdread.py b/tools/pm3_mfdread.py index 4172f1812..7e92ea19a 100755 --- a/tools/pm3_mfdread.py +++ b/tools/pm3_mfdread.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # -*- coding: utf-8 -*- # mfdread.py - Mifare dumps parser in human readable format @@ -18,8 +18,11 @@ import copy import sys from collections import defaultdict -from bitstring import BitArray - +try: + from bitstring import BitArray +except ModuleNotFoundError: + print("Please install bitstring module first.") + sys.exit(1) class Options: FORCE_1K = False @@ -28,7 +31,7 @@ class Options: if len(sys.argv) == 1: sys.exit(''' ------------------ -Usage: mfdread.py ./dump.mfd +Usage: pm3_mfdread.py ./dump.mfd Mifare dumps reader. ''') From aa6fc60a22f3b5cbfd0a0aa4255138c14ff07faa Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 21 Feb 2020 16:29:52 +0100 Subject: [PATCH 1568/1854] xorcheck script converted in python3 + test --- pm3test.sh | 1 + tools/xorcheck.py | 37 +++++++++++++++++-------------------- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/pm3test.sh b/pm3test.sh index 146650f71..7a623183c 100755 --- a/pm3test.sh +++ b/pm3test.sh @@ -116,6 +116,7 @@ while true; do if ! CheckExecute "mfkey64 test" "tools/mfkey/mfkey64 9c599b32 82a4166c a1e458ce 6eea41e0 5cadf439" "Found Key: \[ffffffffffff\]"; then break; fi if ! CheckExecute "mfkey64 long trace test" "tools/mfkey/./mfkey64 14579f69 ce844261 f8049ccb 0525c84f 9431cc40 7093df99 9972428ce2e8523f456b99c831e769dced09 8ca6827b ab797fd369e8b93a86776b40dae3ef686efd c3c381ba 49e2c9def4868d1777670e584c27230286f4 fbdcd7c1 4abd964b07d3563aa066ed0a2eac7f6312bf 9f9149ea" "Found Key: \[091e639cb715\]"; then break; fi if ! CheckExecute "nonce2key test" "tools/nonce2key/nonce2key e9cadd9c a8bf4a12 a020a8285858b090 050f010607060e07 5693be6c00000000" "key recovered: fc00018778f7"; then break; fi + if ! CheckExecute "xorcheck test" "tools/xorcheck.py 04 00 80 64 ba" "final LRC XOR byte value: 5A"; then break; fi printf "\n${C_GREEN}Tests [OK]${C_NC}\n\n" exit 0 done diff --git a/tools/xorcheck.py b/tools/xorcheck.py index 04c031cf1..205e41ccb 100755 --- a/tools/xorcheck.py +++ b/tools/xorcheck.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # xorcheck.py - find xor values for 8-bit LRC # @@ -24,22 +24,21 @@ import sys import os if(len(sys.argv) < 3): - print - print '\t'+sys.argv[0] + ' - Generate final byte for XOR LRC' - print - print 'Usage: ' + sys.argv[0] + ' ... ' - print - print '\tSpecifying the bytes of a UID with a known LRC will find the last byte value' - print '\tneeded to generate that LRC with a rolling XOR. All bytes should be specified in HEX.' - print - print 'Example:' - print - print '\txorcheck.py 04 00 80 64 ba' - print - print 'Should produce the output:' - print - print '\tTarget (BA) requires final LRC XOR byte value: 5A' - print + print(""" +\t{0} - Generate final byte for XOR LRC + +Usage: {0} ... + +\tSpecifying the bytes of a UID with a known LRC will find the last byte value +\tneeded to generate that LRC with a rolling XOR. All bytes should be specified in HEX. + +Example: + +\t{0} 04 00 80 64 ba + +Should produce the output: + +\tTarget (BA) requires final LRC XOR byte value: 5A\n""".format(sys.argv[0])) os._exit(True) target= int(sys.argv[len(sys.argv) - 1],16) @@ -47,6 +46,4 @@ target= int(sys.argv[len(sys.argv) - 1],16) lrc= 0x00 for i in range(len(sys.argv) - 1): lrc ^= int(sys.argv[i + 1],16) -print -print 'Target (%02X) requires final LRC XOR byte value: %02X' % (target,lrc) -print +print('\nTarget (%02X) requires final LRC XOR byte value: %02X\n' % (target,lrc)) From f28404581dce4d1f7f61e6988d6716ce1d92ea0a Mon Sep 17 00:00:00 2001 From: Joe Harrison Date: Fri, 21 Feb 2020 15:09:36 +0000 Subject: [PATCH 1569/1854] convert python2 mfd2eml and eml2mfd scripts to python3 --- tools/pm3_eml2mfd.py | 10 +++++----- tools/pm3_eml_mfd_test.py | 14 +++++++------- tools/pm3_mfd2eml.py | 11 +++++------ 3 files changed, 17 insertions(+), 18 deletions(-) diff --git a/tools/pm3_eml2mfd.py b/tools/pm3_eml2mfd.py index 4e41604f1..0a12f4788 100755 --- a/tools/pm3_eml2mfd.py +++ b/tools/pm3_eml2mfd.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 ''' # Andrei Costin , 2011 @@ -6,20 +6,20 @@ # Converts PM3 Mifare Classic emulator EML text file to MFD binary dump file ''' -from __future__ import with_statement + import sys import binascii def main(argv): argc = len(argv) if argc < 3: - print 'Usage:', argv[0], 'input.eml output.mfd' + print('Usage:', argv[0], 'input.eml output.mfd') sys.exit(1) - with file(argv[1], "r") as file_inp, file(argv[2], "wb") as file_out: + with open(argv[1], "r") as file_inp, open(argv[2], "wb") as file_out: for line in file_inp: line = line.rstrip('\n').rstrip('\r') - print line + print(line) data = binascii.unhexlify(line) file_out.write(data) diff --git a/tools/pm3_eml_mfd_test.py b/tools/pm3_eml_mfd_test.py index 4be66e83a..c08f0f9a1 100755 --- a/tools/pm3_eml_mfd_test.py +++ b/tools/pm3_eml_mfd_test.py @@ -1,9 +1,9 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 + -from __future__ import with_statement from tempfile import mkdtemp from shutil import rmtree -from itertools import imap + from string import hexdigits import unittest, os import pm3_eml2mfd, pm3_mfd2eml @@ -24,18 +24,18 @@ class TestEmlMfd(unittest.TestCase): def test_mfd2eml(self): self.three_argument_test(pm3_mfd2eml.main, - imap(reversed, self.EML2MFD_TESTCASES), c14n=hex_c14n) + map(reversed, self.EML2MFD_TESTCASES), c14n=hex_c14n) def three_argument_test(self, operation, cases, c14n=str): for case_input, case_output in cases: try: inp_name = os.path.join(self.tmpdir, 'input') out_name = os.path.join(self.tmpdir, 'output') - with file(inp_name, 'wb') as in_file: + with open(inp_name, 'w') as in_file: in_file.write(case_input) operation(['', inp_name, out_name]) - with file(out_name, 'rb') as out_file: - self.assertEquals(c14n(case_output), c14n(out_file.read())) + with open(out_name, 'r') as out_file: + self.assertEqual(c14n(case_output), c14n(out_file.read())) finally: for file_name in inp_name, out_name: if os.path.exists(file_name): diff --git a/tools/pm3_mfd2eml.py b/tools/pm3_mfd2eml.py index a2d8389fa..52d858df0 100755 --- a/tools/pm3_mfd2eml.py +++ b/tools/pm3_mfd2eml.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 ''' # Andrei Costin , 2011 @@ -6,24 +6,23 @@ # Converts PM3 Mifare Classic MFD binary dump file to emulator EML text file ''' -from __future__ import with_statement + import sys -import binascii READ_BLOCKSIZE = 16 def main(argv): argc = len(argv) if argc < 3: - print 'Usage:', argv[0], 'input.mfd output.eml' + print('Usage:', argv[0], 'input.mfd output.eml') sys.exit(1) - with file(argv[1], "rb") as file_inp, file(argv[2], "w") as file_out: + with open(argv[1], "rb") as file_inp, open(argv[2], "w") as file_out: while True: byte_s = file_inp.read(READ_BLOCKSIZE) if not byte_s: break - hex_char_repr = binascii.hexlify(byte_s) + hex_char_repr = byte_s.hex() file_out.write(hex_char_repr) file_out.write("\n") From ba6f58cc059fb7ebe097d749d966870a23161fa1 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 21 Feb 2020 16:45:00 +0100 Subject: [PATCH 1570/1854] findbits converted to python3 + tests --- pm3test.sh | 2 ++ tools/findbits.py | 50 ++++++++++++++++++++---------------------- tools/findbits_test.py | 5 ++--- 3 files changed, 28 insertions(+), 29 deletions(-) mode change 100644 => 100755 tools/findbits_test.py diff --git a/pm3test.sh b/pm3test.sh index 7a623183c..cf560e74a 100755 --- a/pm3test.sh +++ b/pm3test.sh @@ -117,6 +117,8 @@ while true; do if ! CheckExecute "mfkey64 long trace test" "tools/mfkey/./mfkey64 14579f69 ce844261 f8049ccb 0525c84f 9431cc40 7093df99 9972428ce2e8523f456b99c831e769dced09 8ca6827b ab797fd369e8b93a86776b40dae3ef686efd c3c381ba 49e2c9def4868d1777670e584c27230286f4 fbdcd7c1 4abd964b07d3563aa066ed0a2eac7f6312bf 9f9149ea" "Found Key: \[091e639cb715\]"; then break; fi if ! CheckExecute "nonce2key test" "tools/nonce2key/nonce2key e9cadd9c a8bf4a12 a020a8285858b090 050f010607060e07 5693be6c00000000" "key recovered: fc00018778f7"; then break; fi if ! CheckExecute "xorcheck test" "tools/xorcheck.py 04 00 80 64 ba" "final LRC XOR byte value: 5A"; then break; fi + if ! CheckExecute "findbits test" "tools/findbits.py 73 0110010101110011" "Match at bit 9: 011001010"; then break; fi + if ! CheckExecute "findbits_test test" "tools/findbits_test.py 2>&1" "OK"; then break; fi printf "\n${C_GREEN}Tests [OK]${C_NC}\n\n" exit 0 done diff --git a/tools/findbits.py b/tools/findbits.py index d3f4c6bcd..809465a2e 100755 --- a/tools/findbits.py +++ b/tools/findbits.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # findbits.py - find Binary, Octal, Decimal or Hex number in bitstream # @@ -31,10 +31,9 @@ def invert(data): def search(target,data): location = data.find(target) if location >= 0: - print '*** Match at bit %d:' % location, - print '%s<%s>%s' % (data[:location],target,data[location+len(target):]) + print('*** Match at bit {:d}: {}<{}>{}'.format(location, data[:location],target,data[location+len(target):])) else: - print 'Not found' + print('Not found') # convert integer to binary string def binstring(number): @@ -49,32 +48,32 @@ def domatch(binary,number): reversed= stringreverse(number) inverted= invert(binary) - print ' Forward: (%s)' % number, + print(' Forward: (%s) ' % number, end = '') search(binary,number) - print ' Reverse: (%s)' % reversed, + print(' Reverse: (%s) ' % reversed, end = '') search(binary,reversed) - print ' Inverse: (%s)' % inverted - print ' Forward: (%s)' % number, + print(' Inverse: (%s) ' % inverted) + print(' Forward: (%s) ' % number, end = '') search(inverted,number) - print ' Reverse: (%s)' % reversed, + print(' Reverse: (%s) ' % reversed, end = '') search(inverted,reversed) def main(): if(len(sys.argv) < 3): - print - print '\t'+sys.argv[0] + ' - Search bitstream for a known number' - print - print 'Usage: ' + sys.argv[0] + ' ' - print - print '\tNUMBER will be converted to it\'s BINARY equivalent for all valid' - print '\tinstances of BINARY, OCTAL, DECIMAL and HEX, and the bitstream' - print '\tand it\'s inverse will be searched for a pattern match. Note that' - print '\tNUMBER must be specified in BINARY to match leading zeros.' - print - print 'Example:' - print - print '\tfindbits.py 73 0110010101110011' - print + print(""" +\t{0} - Search bitstream for a known number + +Usage: {0} + +\tNUMBER will be converted to it\'s BINARY equivalent for all valid +\tinstances of BINARY, OCTAL, DECIMAL and HEX, and the bitstream +\tand it\'s inverse will be searched for a pattern match. Note that +\tNUMBER must be specified in BINARY to match leading zeros. + +Example: + +\t{0} 73 0110010101110011 +""".format(sys.argv[0])) os._exit(True) bases= { @@ -84,11 +83,10 @@ def main(): 16:'HEX', } - for base, base_name in sorted(bases.iteritems()): + for base, base_name in sorted(bases.items()): try: number= int(sys.argv[1],base) - print - print 'Trying', base_name + print('\nTrying ' + base_name) # do BINARY as specified to preserve leading zeros if base == 2: domatch(sys.argv[1],sys.argv[2]) diff --git a/tools/findbits_test.py b/tools/findbits_test.py old mode 100644 new mode 100755 index d52334fd4..403dae413 --- a/tools/findbits_test.py +++ b/tools/findbits_test.py @@ -1,6 +1,5 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 -from itertools import imap import unittest, sys, findbits class TestFindBits(unittest.TestCase): @@ -46,7 +45,7 @@ class TestFindBits(unittest.TestCase): def commutative_test(self, operation, cases): self.unary_operation_test(operation, cases) - self.unary_operation_test(operation, imap(reversed, cases)) + self.unary_operation_test(operation, map(reversed, cases)) def unary_operation_test(self, operation, cases): for case_in, case_out in cases: From efc738ab9311271709e5c34795ca85bc3db4d36e Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 21 Feb 2020 16:52:26 +0100 Subject: [PATCH 1571/1854] add test --- pm3test.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/pm3test.sh b/pm3test.sh index cf560e74a..6a2256192 100755 --- a/pm3test.sh +++ b/pm3test.sh @@ -119,6 +119,7 @@ while true; do if ! CheckExecute "xorcheck test" "tools/xorcheck.py 04 00 80 64 ba" "final LRC XOR byte value: 5A"; then break; fi if ! CheckExecute "findbits test" "tools/findbits.py 73 0110010101110011" "Match at bit 9: 011001010"; then break; fi if ! CheckExecute "findbits_test test" "tools/findbits_test.py 2>&1" "OK"; then break; fi + if ! CheckExecute "pm3_eml_mfd test" "tools/pm3_eml_mfd_test.py 2>&1" "OK"; then break; fi printf "\n${C_GREEN}Tests [OK]${C_NC}\n\n" exit 0 done From a38d5f0839a402945870a85897d2c898e68ff1d5 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 21 Feb 2020 17:07:14 +0100 Subject: [PATCH 1572/1854] attempt to fix travis build on osx --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 1cb60f8e9..663f1036c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -41,6 +41,8 @@ addons: - qt5 - RfidResearchGroup/proxmark3/arm-none-eabi-gcc taps: RfidResearchGroup/proxmark3 +# update trick to fix https://travis-ci.community/t/macos-build-fails-because-of-homebrew-bundle-unknown-command/7296/14 + update: true install: if ! arm-none-eabi-gcc -v; then From ae57feeee6789b35addf09fab00859ab36bfb0a7 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 21 Feb 2020 17:31:55 +0100 Subject: [PATCH 1573/1854] attempt to fix travis build on osx --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 663f1036c..eba0c5d99 100644 --- a/.travis.yml +++ b/.travis.yml @@ -36,6 +36,7 @@ addons: - libsndfile1-dev homebrew: packages: + - python3 - readline - libsndfile - qt5 From 2804a7dbadc9ad08524d0ef8569d7c7a2695e260 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 21 Feb 2020 22:15:35 +0100 Subject: [PATCH 1574/1854] hopefully fixes travis for OSX --- .travis.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index eba0c5d99..5aee2a918 100644 --- a/.travis.yml +++ b/.travis.yml @@ -36,7 +36,6 @@ addons: - libsndfile1-dev homebrew: packages: - - python3 - readline - libsndfile - qt5 @@ -45,6 +44,14 @@ addons: # update trick to fix https://travis-ci.community/t/macos-build-fails-because-of-homebrew-bundle-unknown-command/7296/14 update: true +before_install: + # bug? + # homebrew update replaced python2.7 by python3.7 but + # python3 link failed while python@2 still present, so let's do it again: + if [ "$TRAVIS_OS_NAME" == "osx" ]; then + brew link --overwrite python; + fi + install: if ! arm-none-eabi-gcc -v; then echo "arm-none-eabi-gcc [ERROR]"; From 2ec4bc9a0e5c1b9c9971d0ebfa9ee258aaf05fe6 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 22 Feb 2020 13:14:43 +0100 Subject: [PATCH 1575/1854] old->mix --- armsrc/i2c.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/armsrc/i2c.c b/armsrc/i2c.c index 2cd3c6f3e..3d1f050c3 100644 --- a/armsrc/i2c.c +++ b/armsrc/i2c.c @@ -709,7 +709,7 @@ void SmartCardAtr(void) { set_tracing(true); I2C_Reset_EnterMainProgram(); bool isOK = GetATR(&card); - reply_old(CMD_ACK, isOK, sizeof(smart_card_atr_t), 0, &card, sizeof(smart_card_atr_t)); + reply_mix(CMD_ACK, isOK, sizeof(smart_card_atr_t), 0, &card, sizeof(smart_card_atr_t)); set_tracing(false); LEDsoff(); } @@ -760,7 +760,7 @@ void SmartCardRaw(uint64_t arg0, uint64_t arg1, uint8_t *data) { } } OUT: - reply_old(CMD_ACK, len, 0, 0, resp, len); + reply_mix(CMD_ACK, len, 0, 0, resp, len); BigBuf_free(); set_tracing(false); LEDsoff(); From b304adeecabaceda477ebf019b35437f46f5f78a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 22 Feb 2020 13:16:04 +0100 Subject: [PATCH 1576/1854] hitag, determine adc levels to get better demodulation --- armsrc/lfadc.c | 39 +++++++++++++++++++++++++++++---------- armsrc/lfadc.h | 1 + 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/armsrc/lfadc.c b/armsrc/lfadc.c index 04f293e1d..6b0eb930a 100644 --- a/armsrc/lfadc.c +++ b/armsrc/lfadc.c @@ -10,6 +10,7 @@ #include "lfsampling.h" #include "fpgaloader.h" #include "ticks.h" +#include "dbprint.h" // Sam7s has several timers, we will use the source TIMER_CLOCK1 (aka AT91C_TC_CLKS_TIMER_DIV1_CLOCK) // TIMER_CLOCK1 = MCK/2, MCK is running at 48 MHz, Timer is running at 48/2 = 24 MHz @@ -46,13 +47,28 @@ bool lf_test_periods(size_t expected, size_t count) { // Low frequency (LF) adc passthrough functionality ////////////////////////////////////////////////////////////////////////////// uint8_t previous_adc_val = 0; +uint8_t adc_avg = 0; + +void lf_sample_mean(void) { + uint8_t periods = 0; + uint32_t adc_sum = 0; + while (periods < 32) { + if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { + adc_sum += AT91C_BASE_SSC->SSC_RHR; + periods++; + } + } + // division by 32 + adc_avg = adc_sum >> 5; + + if (DBGLEVEL >= DBG_EXTENDED) + Dbprintf("LF ADC average %u", adc_avg); +} size_t lf_count_edge_periods_ex(size_t max, bool wait, bool detect_gap) { size_t periods = 0; volatile uint8_t adc_val; - //uint8_t avg_peak = 140, avg_through = 96; - // 140 - 127 - 114 - uint8_t avg_peak = 140, avg_through = 106; + uint8_t avg_peak = adc_avg + 3, avg_through = adc_avg - 3; int16_t checked = 0; while (!BUTTON_PRESS()) { @@ -98,8 +114,8 @@ size_t lf_count_edge_periods_ex(size_t max, bool wait, bool detect_gap) { } } } - previous_adc_val = adc_val; + if (periods >= max) return 0; } } @@ -131,8 +147,9 @@ void lf_reset_counter() { bool lf_get_tag_modulation() { return (rising_edge == false); } + bool lf_get_reader_modulation() { - return rising_edge; + return rising_edge; } void lf_wait_periods(size_t periods) { @@ -147,7 +164,7 @@ void lf_init(bool reader, bool simulate) { FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, LF_DIVISOR_134); if (reader) { FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); } else { @@ -168,8 +185,8 @@ void lf_init(bool reader, bool simulate) { // When in reader mode, give the field a bit of time to settle. // 313T0 = 313 * 8us = 2504us = 2.5ms Hitag2 tags needs to be fully powered. if (reader) { - // 50 ms - SpinDelay(50); + // 10 ms + SpinDelay(10); } // Steal this pin from the SSP (SPI communication channel with fpga) and use it to control the modulation @@ -195,7 +212,7 @@ void lf_init(bool reader, bool simulate) { AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; // Prepare data trace - uint32_t bufsize = 20000; + uint32_t bufsize = 10000; // use malloc if (logging) initSampleBufferEx(&bufsize, true); @@ -203,6 +220,8 @@ void lf_init(bool reader, bool simulate) { sample_config *sc = getSamplingConfig(); sc->decimation = 1; sc->averaging = 0; + + lf_sample_mean(); } void lf_finalize() { @@ -275,7 +294,7 @@ static void lf_manchester_send_bit(uint8_t bit) { lf_modulation(bit != 0); lf_wait_periods(16); lf_modulation(bit == 0); - lf_wait_periods(16); + lf_wait_periods(32); } // simulation diff --git a/armsrc/lfadc.h b/armsrc/lfadc.h index 8c33aa778..09e5762c6 100644 --- a/armsrc/lfadc.h +++ b/armsrc/lfadc.h @@ -17,6 +17,7 @@ extern bool logging; +void lf_sample_mean(void); bool lf_test_periods(size_t expected, size_t count); size_t lf_count_edge_periods(size_t max); size_t lf_detect_gap(size_t max); From e56f14fe4d4af39a312ec5ab727548524c741de1 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 22 Feb 2020 13:16:36 +0100 Subject: [PATCH 1577/1854] textual --- client/cmdhf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdhf.c b/client/cmdhf.c index e90f2ea28..78ebbd256 100644 --- a/client/cmdhf.c +++ b/client/cmdhf.c @@ -179,7 +179,7 @@ int CmdHFTune(const char *Cmd) { int iter = param_get32ex(Cmd, 0, 0, 10); PacketResponseNG resp; - PrintAndLogEx(SUCCESS, "Measuring HF antenna," _YELLOW_("click button") " or press" _YELLOW_("Enter") "to exit"); + PrintAndLogEx(SUCCESS, "Measuring HF antenna, " _YELLOW_("click button") " or press " _YELLOW_("Enter") "to exit"); clearCommandBuffer(); uint8_t mode[] = {1}; SendCommandNG(CMD_MEASURE_ANTENNA_TUNING_HF, mode, sizeof(mode)); From 004b4ae3c9a2a5e3047cfcf97447619ad33bb788 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 22 Feb 2020 13:17:36 +0100 Subject: [PATCH 1578/1854] textual --- client/loclass/cipherutils.c | 8 ++++---- client/loclass/ikeys.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/client/loclass/cipherutils.c b/client/loclass/cipherutils.c index 5f16b68fd..09f4bccd7 100644 --- a/client/loclass/cipherutils.c +++ b/client/loclass/cipherutils.c @@ -160,12 +160,12 @@ void printarr(const char *name, uint8_t *arr, int len) { cx += snprintf(output + cx, outsize - cx, "0x%02x,", *(arr + i)); //5 bytes per byte } snprintf(output + cx, outsize - cx, "};"); - PrintAndLogEx(NORMAL, output); + PrintAndLogEx(INFO, output); free(output); } void printvar(const char *name, uint8_t *arr, int len) { - PrintAndLogEx(NORMAL, "%s = " _YELLOW_("%s"), name, sprint_hex(arr, len)); + PrintAndLogEx(INFO, "%s = " _YELLOW_("%s"), name, sprint_hex(arr, len)); } void printarr_human_readable(const char *title, uint8_t *arr, int len) { @@ -175,13 +175,13 @@ void printarr_human_readable(const char *title, uint8_t *arr, int len) { int cx = 0, i; size_t outsize = 100 + strlen(title) + len * 4; char *output = calloc(outsize, sizeof(char)); - PrintAndLogEx(NORMAL, "\n %s", title); + PrintAndLogEx(INFO, "%s", title); for (i = 0; i < len; i++) { if (i % 16 == 0) cx += snprintf(output + cx, outsize - cx, "\n%02x| ", i); cx += snprintf(output + cx, outsize - cx, "%02x ", *(arr + i)); } - PrintAndLogEx(NORMAL, output); + PrintAndLogEx(INFO, output); free(output); } diff --git a/client/loclass/ikeys.c b/client/loclass/ikeys.c index 339ea91f7..9d9926547 100644 --- a/client/loclass/ikeys.c +++ b/client/loclass/ikeys.c @@ -199,7 +199,6 @@ static uint64_t check(uint64_t z) { ck2 &= 0x00000000FFFFFF000000; return ck1 | ck2 >> 24; - } static void permute(BitstreamIn *p_in, uint64_t z, int l, int r, BitstreamOut *out) { @@ -219,6 +218,7 @@ static void permute(BitstreamIn *p_in, uint64_t z, int l, int r, BitstreamOut *o permute(p_in, z, l, r + 1, out); } } + static void printbegin() { if (debug_print < 2) return; From 7378ea531a4d14b346a5e545b59088d29a8f6af2 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 22 Feb 2020 13:18:59 +0100 Subject: [PATCH 1579/1854] hide function xor since it interfers with native xor funtions --- client/util.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/util.h b/client/util.h index 21db9198f..fb31e6013 100644 --- a/client/util.h +++ b/client/util.h @@ -23,6 +23,7 @@ uint8_t g_debugMode; uint8_t g_printAndLog; + #define PRINTANDLOG_PRINT 1 #define PRINTANDLOG_LOG 2 @@ -85,7 +86,7 @@ uint8_t GetParity(uint8_t *bits, uint8_t type, int length); void wiegand_add_parity(uint8_t *target, uint8_t *source, uint8_t length); void wiegand_add_parity_swapped(uint8_t *target, uint8_t *source, uint8_t length); -void xor(unsigned char *dst, unsigned char *src, size_t len); +//void xor(unsigned char *dst, unsigned char *src, size_t len); int32_t le24toh(uint8_t data[3]); uint32_t PackBits(uint8_t start, uint8_t len, uint8_t *bits); From 181a659bc069ac731aee10f42f0efededdfa7eac Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 22 Feb 2020 13:32:42 +0100 Subject: [PATCH 1580/1854] trying another loop --- armsrc/lfsampling.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index c492a4eda..2e33ec434 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -253,11 +253,11 @@ uint32_t DoAcquisition(uint8_t decimation, uint8_t bits_per_sample, bool avg, in uint32_t cancel_counter = 0; int16_t checked = 0; - while (true) { + while (!BUTTON_PRESS()) { // only every 1000th times, in order to save time when collecting samples. if (checked == 1000) { - if (BUTTON_PRESS() || data_available()) { + if (data_available()) { checked = -1; break; } else { From 802e62285baae746a392951d7e2f78626b2eab46 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 22 Feb 2020 13:34:15 +0100 Subject: [PATCH 1581/1854] debug print hitag2 for cleaner client outputs --- armsrc/hitag2.c | 152 ++++++++++++++++++++++++++---------------------- 1 file changed, 81 insertions(+), 71 deletions(-) diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index 8a0d4934a..37c716efb 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -20,6 +20,8 @@ // Anon, 2019 // Doegox, 2020 +#define DBG if (DBGLEVEL >= DBG_EXTENDED) + #include "hitag2.h" #include "hitag2_crypto.h" #include "string.h" @@ -305,6 +307,9 @@ static void hitag2_handle_reader_command(uint8_t *rx, const size_t rxlen, uint8_ break; } + // LogTrace(rx, nbytes(rxlen), 0, 0, NULL, false); + // LogTrace(tx, nbytes(txlen), 0, 0, NULL, true); + if (tag.crypto_active) { hitag2_cipher_transcrypt(&(tag.cs), tx, *txlen / 8, *txlen % 8); } @@ -337,12 +342,12 @@ static uint32_t hitag_reader_send_bit(int bit) { lf_wait_periods(HITAG_T_1 - HITAG_T_LOW); // wait for 26-32 times the carrier period wait += HITAG_T_1 - HITAG_T_LOW; } - /*lf_wait_periods(10);*/ + LED_A_OFF(); return wait; } -// reader/writer +// reader / writer commands static uint32_t hitag_reader_send_frame(const uint8_t *frame, size_t frame_len) { uint32_t wait = 0; @@ -953,17 +958,18 @@ static bool hitag2_read_uid(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t memcpy(tag.sectors[blocknr], rx, 4); blocknr++; - Dbhexdump(4, rx, false); + DBG Dbhexdump(4, rx, false); } if (blocknr > 0) { + DBG DbpString("Read successful!"); bSuccessful = true; - return false; + return true; } } break; // Unexpected response default: { - Dbprintf("Unknown frame length: %d", rxlen); + DBG Dbprintf("Unknown frame length: %d", rxlen); return false; } break; @@ -1017,7 +1023,7 @@ void SniffHitag2(void) { // Receive frame, watch for at most T0*EOF periods - lf_reset_counter(); +// lf_reset_counter(); // Wait "infinite" for reader modulation periods = lf_detect_gap(20000); @@ -1071,8 +1077,6 @@ void SimulateHitag2(bool tag_mem_supplied, uint8_t *data) { DbpString("Starting Hitag2 simulation"); - LED_D_ON(); - // hitag2 state machine? hitag2_init(); @@ -1094,21 +1098,25 @@ void SimulateHitag2(bool tag_mem_supplied, uint8_t *data) { Dbprintf("| %d | %08x |", i, block); } - uint8_t tag_modulation; + uint8_t reader_modulation; size_t max_nrzs = 8 * HITAG_FRAME_LEN + 5; uint8_t nrz_samples[max_nrzs]; size_t nrzs = 0, periods = 0; // uint32_t command_start = 0, command_duration = 0; + // int16_t checked = 0; - int16_t checked = 0; +// SIMULATE while (!BUTTON_PRESS()) { -loop1: + LED_D_ON(); + +// lf_reset_counter(); LED_A_OFF(); WDT_HIT(); +/* // only every 1000th times, in order to save time when collecting samples. if (checked == 100) { if (data_available()) { @@ -1119,6 +1127,7 @@ loop1: } } ++checked; +*/ rxlen = 0; @@ -1126,10 +1135,10 @@ loop1: bool waiting_for_first_edge = true; // Did we detected any modulaiton at all - bool detected_tag_modulation = false; + bool detected_modulation = false; // Use the current modulation state as starting point - tag_modulation = lf_get_tag_modulation(); + reader_modulation = lf_get_reader_modulation(); // Receive frame, watch for at most max_nrzs periods // Reset the number of NRZ samples and use edge detection to detect them @@ -1141,7 +1150,7 @@ loop1: // Just break out of loop after an initial time-out (tag is probably not available) // The function lf_count_edge_periods() returns 0 when a time-out occurs if (periods == 0) { - goto loop1; //break; + break; } LED_A_ON(); @@ -1159,32 +1168,36 @@ loop1: periods = 16; // We have received more than 0 periods, so we have detected a tag response - detected_tag_modulation = true; + detected_modulation = true; } // Evaluate the number of periods before the next edge if (periods > 24 && periods <= 64) { // Detected two sequential equal bits and a modulation switch // NRZ modulation: (11 => --|) or (11 __|) - nrz_samples[nrzs++] = tag_modulation; - nrz_samples[nrzs++] = tag_modulation; + nrz_samples[nrzs++] = reader_modulation; + nrz_samples[nrzs++] = reader_modulation; // Invert tag modulation state - tag_modulation ^= 1; + reader_modulation ^= 1; } else if (periods > 0 && periods <= 24) { // Detected one bit and a modulation switch // NRZ modulation: (1 => -|) or (0 _|) - nrz_samples[nrzs++] = tag_modulation; - tag_modulation ^= 1; + nrz_samples[nrzs++] = reader_modulation; + reader_modulation ^= 1; } else { - tag_modulation ^= 1; + reader_modulation ^= 1; // The function lf_count_edge_periods() returns > 64 periods, this is not a valid number periods Dbprintf("Detected unexpected period count: %d", periods); break; } } + LED_D_OFF(); + // If there is no response, just repeat the loop - if (!detected_tag_modulation) continue; + if (!detected_modulation) continue; + + LED_A_OFF(); // Make sure we always have an even number of samples. This fixes the problem // of ending the manchester decoding with a zero. See the example below where @@ -1194,7 +1207,7 @@ loop1: // The last modulation change of a zero is not detected, but we should take // the half period in account, otherwise the demodulator will fail. if ((nrzs % 2) != 0) { - nrz_samples[nrzs++] = tag_modulation; + nrz_samples[nrzs++] = reader_modulation; } LED_B_ON(); @@ -1233,8 +1246,8 @@ loop1: // not that since the clock counts since the rising edge, but T_Wait1 is // with respect to the falling edge, we need to wait actually (T_Wait1 - T_Low) // periods. The gap time T_Low varies (4..10). All timer values are in - // terms of T0 units - lf_wait_periods(200); + // terms of T0 units (HITAG_T_WAIT_1_MIN - HITAG_T_LOW ) + lf_wait_periods(HITAG_T_WAIT_1_MIN); // Send and store the tag answer (if there is any) if (txlen) { @@ -1266,15 +1279,15 @@ loop1: void ReaderHitag(hitag_function htf, hitag_data *htd) { - uint32_t command_start = 0; - uint32_t command_duration = 0; - uint32_t response_start = 0; - uint32_t response_duration = 0; + uint32_t command_start = 0, command_duration = 0; + uint32_t response_start = 0, response_duration = 0; + uint8_t rx[HITAG_FRAME_LEN]; size_t rxlen = 0; uint8_t txbuf[HITAG_FRAME_LEN]; uint8_t *tx = txbuf; size_t txlen = 0; + int t_wait_1; int t_wait_1_guard = 8; int t_wait_2; @@ -1292,19 +1305,17 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { set_tracing(true); clear_trace(); - DbpString("Starting Hitag reader family"); - // Check configuration switch (htf) { case RHT1F_PLAIN: { - Dbprintf("Read public blocks in plain mode"); + DBG Dbprintf("Read public blocks in plain mode"); // this part will be unreadable memset(tag.sectors + 2, 0x0, 30); blocknr = 0; break; } case RHT1F_AUTHENTICATE: { - Dbprintf("Read all blocks in authed mode"); + DBG Dbprintf("Read all blocks in authed mode"); memcpy(nonce, htd->ht1auth.nonce, 4); memcpy(key, htd->ht1auth.key, 4); memcpy(logdata_0, htd->ht1auth.logdata_0, 4); @@ -1314,19 +1325,19 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { memset(logdata_1, 0x00, 4); byte_value = 0; key_no = htd->ht1auth.key_no; - Dbprintf("Authenticating using key #%d:", key_no); - Dbhexdump(4, key, false); - DbpString("Nonce:"); - Dbhexdump(4, nonce, false); - DbpString("Logdata_0:"); - Dbhexdump(4, logdata_0, false); - DbpString("Logdata_1:"); - Dbhexdump(4, logdata_1, false); + DBG Dbprintf("Authenticating using key #%d:", key_no); + DBG Dbhexdump(4, key, false); + DBG DbpString("Nonce:"); + DBG Dbhexdump(4, nonce, false); + DBG DbpString("Logdata_0:"); + DBG Dbhexdump(4, logdata_0, false); + DBG DbpString("Logdata_1:"); + DBG Dbhexdump(4, logdata_1, false); blocknr = 0; break; } case RHT2F_PASSWORD: { - Dbprintf("List identifier in password mode"); + DBG Dbprintf("List identifier in password mode"); if (memcmp(htd->pwd.password, "\x00\x00\x00\x00", 4) == 0) memcpy(password, tag.sectors[1], sizeof(password)); else @@ -1338,19 +1349,19 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { break; } case RHT2F_AUTHENTICATE: { - DbpString("Authenticating using nr,ar pair:"); + DBG DbpString("Authenticating using nr,ar pair:"); memcpy(NrAr, htd->auth.NrAr, 8); - Dbhexdump(8, NrAr, false); + DBG Dbhexdump(8, NrAr, false); bCrypto = false; bAuthenticating = false; break; } case RHT2F_CRYPTO: { - DbpString("Authenticating using key:"); + DBG DbpString("Authenticating using key:"); memcpy(key, htd->crypto.key, 6); //HACK; 4 or 6?? I read both in the code. - Dbhexdump(6, key, false); - DbpString("Nonce:"); - Dbhexdump(4, nonce, false); + DBG Dbhexdump(6, key, false); + DBG DbpString("Nonce:"); + DBG Dbhexdump(4, nonce, false); memcpy(nonce, htd->crypto.data, 4); blocknr = 0; bCrypto = false; @@ -1358,7 +1369,7 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { break; } case RHT2F_TEST_AUTH_ATTEMPTS: { - Dbprintf("Testing %d authentication attempts", (auth_table_len / 8)); + DBG Dbprintf("Testing %d authentication attempts", (auth_table_len / 8)); auth_table_pos = 0; memcpy(NrAr, auth_table, 8); bCrypto = false; @@ -1371,7 +1382,7 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { break; } default: { - Dbprintf("Error, unknown function: %d", htf); + DBG Dbprintf("Error, unknown function: %d", htf); set_tracing(false); return; } @@ -1382,9 +1393,6 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { // hitag2 state machine? hitag2_init(); - // init as reader - lf_init(true, false); - uint8_t attempt_count = 0; // Tag specific configuration settings (sof, timings, etc.) @@ -1395,38 +1403,41 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { /*tag_size = 256;*/ flipped_bit = 0; tag_size = 8; - DbpString("Configured for hitagS reader"); + DBG DbpString("Configured for hitagS reader"); } else if (htf < 20) { // hitag1 settings t_wait_1 = 204; t_wait_2 = 128; tag_size = 256; flipped_bit = 0; - DbpString("Configured for hitag1 reader"); + DBG DbpString("Configured for hitag1 reader"); } else if (htf < 30) { // hitag2 settings t_wait_1 = HITAG_T_WAIT_1_MIN; t_wait_2 = HITAG_T_WAIT_2_MIN; tag_size = 48; - DbpString("Configured for hitag2 reader"); + DBG DbpString("Configured for hitag2 reader"); } else { - Dbprintf("Error, unknown hitag reader type: %d", htf); + DBG Dbprintf("Error, unknown hitag reader type: %d", htf); return; } + // init as reader + lf_init(true, false); + uint8_t tag_modulation; size_t max_nrzs = (8 * HITAG_FRAME_LEN + 5) * 2; // up to 2 nrzs per bit uint8_t nrz_samples[max_nrzs]; size_t nrzs = 0; int16_t checked = 0; - while (!bStop) { + while (!bStop && !BUTTON_PRESS()) { WDT_HIT(); // only every 1000th times, in order to save time when collecting samples. if (checked == 1000) { - if (BUTTON_PRESS() || data_available()) { + if (data_available()) { checked = -1; break; } else { @@ -1471,7 +1482,7 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { break; } default: { - Dbprintf("Error, unknown function: %d", htf); + DBG Dbprintf("Error, unknown function: %d", htf); goto out; } } @@ -1531,7 +1542,7 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { } else { // The function lf_count_edge_periods() returns 0 when a time-out occurs if (periods == 0) { - //Dbprintf("Detected timeout after [%d] nrz samples", nrzs); + DBG Dbprintf("Detected timeout after [%d] nrz samples", nrzs); break; } } @@ -1552,7 +1563,7 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { tag_modulation ^= 1; } else { // The function lf_count_edge_periods() returns > 64 periods, this is not a valid number periods - //Dbprintf("Detected unexpected period count: %d", periods); + DBG Dbprintf("Detected unexpected period count: %d", periods); break; } } @@ -1591,13 +1602,13 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { // Verify if the header consists of five consecutive ones if (nrzs < 5) { - Dbprintf("Detected unexpected number of manchester decoded samples [%d]", nrzs); + DBG Dbprintf("Detected unexpected number of manchester decoded samples [%d]", nrzs); break; } else { size_t i; for (i = 0; i < 5; i++) { if (nrz_samples[i] != 1) { - Dbprintf("Detected incorrect header, the bit [%d] is zero instead of one, abort", i); + DBG Dbprintf("Detected incorrect header, the bit [%d] is zero instead of one, abort", i); break; } } @@ -1608,7 +1619,7 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { for (size_t i = 5; i < nrzs; i++) { uint8_t bit = nrz_samples[i]; if (bit > 1) { // When Manchester detects impossible symbol it writes "7" - Dbprintf("Error in Manchester decoding, abort"); + DBG Dbprintf("Error in Manchester decoding, abort"); break; } rx[rxlen / 8] |= bit << (7 - (rxlen % 8)); @@ -1671,8 +1682,7 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) { set_tracing(true); clear_trace(); - DbpString("Starting Hitag writer family"); - + // Check configuration switch (htf) { case WHT2F_CRYPTO: { @@ -1710,7 +1720,7 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) { // init as reader lf_init(true, false); - + // Tag specific configuration settings (sof, timings, etc.) if (htf < 10) { // hitagS settings @@ -1734,7 +1744,7 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) { tag_size = 48; DbpString("Configured for hitag2 writer"); } else { - Dbprintf("Error, unknown hitag writer type: %d", htf); + DBG Dbprintf("Error, unknown hitag writer type: %d", htf); return; } @@ -1744,11 +1754,11 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) { size_t nrzs = 0; int16_t checked = 0; - while (!bStop) { + while (!bStop && !BUTTON_PRESS()) { // only every 1000th times, in order to save time when collecting samples. if (checked == 1000) { - if (BUTTON_PRESS() || data_available()) { + if (data_available()) { checked = -1; break; } else { From 3f0f08ffbb95a4d3dc288cbb7f45d1a2bba23316 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 22 Feb 2020 13:34:52 +0100 Subject: [PATCH 1582/1854] updated fpga lf image for hitag --- fpga/fpga_lf.bit | Bin 42175 -> 42175 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/fpga/fpga_lf.bit b/fpga/fpga_lf.bit index dd64db8a7762141fcee85b6fb5cb9af3a4705313..ba6b4322e6d470175b46d7116b49ddceaa3408f3 100644 GIT binary patch literal 42175 zcmb@ve|Q|#c`yFXnOS+XyYh}@iz>l5qm`hGSxIZz7{`&NvFy+dc4L*0)a^IV{Vv39 z-Cmk2(%gHU-rVG9CGZ-VdI7g}5;t8NCs7h7UCR#s!LP9pAdJ9*aubITvQUL6)JYcO zfNTuDpZCn}?8o7z76nN4&X1v~y`Y2v@#u_Te8&rql%(UEAkJK8%sXcN^g=~#LFl9fxA z(Vr3R>$`~GcfRt;KTnX~2kv%l}NJe_xv*v{(LFOOQjo)bbgs zx48Lt{0yo7MSbt@`1jmwNc<0xQ2+Zo{>PE(U;H2Ykk_aFcRWHh8~?BRsHa`5cY-`_ zNj5={B1Z*UL30U0tb0)PaRX=QqU2P8(3$M{oy6sg61tYouS5}u<3!{%3w2W;mdi^tP*njWL5H=gg(%HtT}8Ehc@3W3#X zUbPAFoO6(d-F1nmKd%{VG5l<;o({{_LTHP4g$@rk6|USOUZ8KuYq@3Idrs0MdW$;U zI(#4JEwRFlB=iY-94(PV^9$a_ajrU0H7|dHo-ip={I21^l&pLod%3$KuV2u3UITgk z4R5`Y^L84CwN^LOCtjw*R+GC9g4jx`R}0 z1!Kk@!Qht`HD#@JOg5cSvXPFFN+R)yZ2@L zTS}>}eYhb0Oduh3cu6 zit%*brA6)r7*9&@yfmvwCuyk*n|a(BgnSwPQ!F1*q#7QM6gRf@c>b?A~ zTtkuGQ6rpRR6`9FoBc6Q*Yt58#;*z4-4q$uFUXU(Ep@{)^WQfWqPcpaj9<^ukYu!? zi_VUY=3+3@^BNtIZB4NAw)dSg&{N4HBrFrgJZahx9`IVCW&9fM2U<}mUw>MCgy4O^ zL1?ZW+9?v=x;qW8(bM&?bzhl(T0Db=3+MG|HlK)}1&DmUWl zXX!ob_njS2hkX3n=R9q9JsG(V826Ncg;NIB?#e{61CyS9jR#_Mx7lWe_N6b-4r+Eo ze=nw-qsg|LL%S;Ym6Z26aVr!P6N1-b-3P>z&H*=`3T1?kU(4z5Wosd{5%{%LHWfmf z#Y^;{Y|TON@heO(P^TNQ6>KHk2{B_P9eSu@Jfg zMYBb{_nlq(dIi4@^O!TDgSN{i8$g!#^o#K;pNvz8(!Bk6A4bE$0m`|dCE`9q?PuT@ z>rNTJIv|8%bi#n}%g{0JT}gn}1?twYOs=Jjo~xgs3$oje3~D!f`ej6aN$ zBUEF?yqYjUQJRG%gr{GP4Ts={@!S<;WA2keeGNBc_0)K4k!zST@ttpG7&T{)XSW_J z;g`0LN7%=G#GCY}2V`h*B3}vl_;o;D5ZxB9DPXIE!ehExWr_@jf}VcGpkK$#wwtk%0iDfowv!9T1kjb|*hM)&b+H$CVf?90w!7<`QR zr=?k7f;QV;d%>tYz_tZ*H(0-FO)*ON8g|GK8E@T(8}``e@?9;Fztb7NMr2(^FJz!Z zH%A^TW2L0ibly>xpZj252L^7ZcN@Dh8wN4K1iwqe-hGd{Wu&l`A>g3&oPTaPtNZx1 ziQsRr|8v@U2fpbQ^+v_ad$FGO6l!{JXpf8))THbnful>711;5lPm%dN3!<}3HKDt@Kuia%$d6^E{ z*GjWb|1?@Y>_X#y7k&k|h(&Zb{nv%ixIi$2zfW=juW4!S4^d2-GU{Mw#_B_{V7;eb zj9=_gd+vegkaKg*F-Ej(WJ+II#;;e^3eG8+3oGK=y8Z#5f4yF2B@6*8Q+2ySZ08rH zU`2iWT1($1rC*9$Z83MJ_t8rac6x|bjbHP|jW1E18neBET1o9gco$Xp#Y2Tvhn=^8UpGbW8$gQ&VN&<;3!W7% zN1tW}j&3JBskeX_c7rqO)%;6SY|A5JbyC3ci#9eOW&ZV1=3gzPF=K+J6*Ov@k$ue) zqhju^k%Wo(+~MeR8=2X5u?9#i~_!mMB0 zd9xMGhlR2mXA$uz@voe=pt7Htb~W~86rvSs`v8dQIm70nGFp9|-pO_s!ZSLzbQfB; z=sy3dvIz>vl#vl#?%aF@zh0oHqGdjeEgcA`vF_Zwg3x6hD5|Un29$Amx=K*ehtHXMcoM7 zOy*zVV;_vuyUDIX=s+1O8NWO%@Jw75uKsEIAJjD#Ia0wdnD?@6fiP8fexTDEq_>ed7-S2{j6>LE{uPszKGfDzyG-ooJ_h&k*1|N@3YO;;C)jyz zx!u7`g~rQH^)*5z$6>vpO8X=6`80YMV#uOZc7%Oi&hP&$NU|dpx5z z7VfuOq?r(V%lvD{XzA?JI4?s30)*}oC zB38jK5W#kW=P*OBM?d87|anigFylNmTG_k#k7478?H)5OAlwE@y5L zKXbk*n^M*B!!VV28IS@8MSY5E#IZ>`<*=X5I7RlsMNq6s?aLh$2<+i4I6*X$LIG&rx-se=+31GLOF z`w;g_@w=FR{UgSV5&kFIDccJe^ADLk79sfY!wHfiz92|9YXoxbVD8U3Lu2fmRK*YJ zCF;z9S8j&TEyLis;yLqg^6{MR#}8ct{7b9`9JkD5=Mwy0Aez}FB67ZuUsLo;TItNq z>ic*b_rRPoqOEYkRrs|@Q7Xz}|9FO4{9=%aSg;DeS}^nL95E@*a-Y?JtuY|lV#ln+ z4-I4ZPEeRkA1F*IDE9=OY&${50{%Q4Ka|t7lHeZXc_V2Uvn$5`XeGfu`}}Jv$N04& ztB(P;R>97H=C|~o)7{I1uTj2VV*?_JqQwbV^Ea74COFAi4D4yykqT#({d!z~MdSu_$Of?w~```};j;zk?CRZI)$OWPCJ~vF20r@KLr0usAcj3i66=f1W0+aRmBf4 z(68B&oYOBj@2Nmy^Hk<3bBP-+R`}QL7JN~TEWM^316C?CI7Exxx_pIyweeEASjyAJ zLqY`-3!YU+p9+4B5E!&2Tsk5>QiC-e=EbezUvH?a5KQ+&)Zq>FBm~&8GXMI(1w!-* zu%#C*7!Vg`&9PSeHud~2ehk;F2eDEP>+_SDa@;cUoQApMz+~z2Ke=mjOOZA zKo}Z`=3wv(hQjV~=$F(OYNKJ~wxTZLhbE;7PJ5z?e+l@;J+Zuk^{9lC++uGFE?!-Y zUlUfw>1+uL!0}r=ovhwO-ttJm5O zv(s^3cptvcyVN-z&+FI96RD0}8}b8|VY7`={A**hU_K&#Ll5<~<;;Kx$bM<}h0Y+D z=5U|szIJ`w@e8wfgqI1^vB1Bc*Ne_+ z>m%BRH>>gMJax$JQV+v1>*DVNJJ0dMe3^fZ&)W@e5N=^#bRpeIaaorVr(gl#F`g;& zFA4nOup!WD5n$`Tu<(lZEwqHb&@+pF*=}q_FpSt~Tz;$u8#0Fk2=ZT5{Oj$^lD*-- z(qr^wv`gZHPm4Fih}@A2`TPq}8u6$Fw-ADZ;HL|t_h|vAF$i|Ms znA7_A^S0R9imGKLB!Rb6T9gf$9vuhOJaS)-Z;1^i` zUg!$KhNq|*SP-@8h=%y#on`)&MEvj(YUb%Iz?$xHf>rUuD*Qs9Uh{|1W%N(z4CiDy zJtEsvFhphi0{?o`PV|Kr>INORI-I$?Lf7zjzAfV8*Jf=W#~70;mdi^}#~8;*jXq`k zvU1iJm2DYF&;@fTD3o55FfwpX2CDGuSfMQ&8Wz{lv7DV1->HAYR{5_2u*u?o=vYRL^f9QFGL2MNFsC^wgnqf&M&Z?XNSsO@5w`zLq*Z|rwBV$ASYJ)cCZJ|X)L`6#cg5!rLsXN8C#W^XLjztPXoi^4hfqhttA4=mdiT#bx zp!he+xY1n5s<)Y2oe6EP;8%8OOAXZ|(Rk3x>$Ani4j{%op(U(CN4wt{&P z2h_%ohwS>8$+>*(zI80EKZ&=_&Bbd5iMTY+rI+`0mHeyc@Q4lTg3mgu%bCfAM4dI!mi4avb@} zcj`gJ3V>s9d|tuHniTgL#`l2^Qkd{ro|o`j_Ug8H280gtD(AmGu$!Y{uF@S&d#$?~ zF*ME{*Y%b0tDOIe0l$oYl(!bvZJzr<+A7=g7;_)l{H~-iVdRxhQcs3TG-K|(xP{t$ z@MaHFrUPF73vg_Le~qv&v4T#BRoQS(|65PLP`|_;nu^ z8$Xkjo!|V2fGwj`w$VZ$ESq5YMFqbOXf`t`0FVRN%GS@x!XrxEbU$`f3BQ<{H9NHo zTV9`Fo7g50aLbAsZ%s|Z02b_VYKw@|s1k^J5rD?E-4wKHs_=``I;~Pq0KcGCcjALX zKzuCJru+DHPV02$X6KKQQnY(RX9WidBlQ*h+UMbyr5obM)ZxUldM9se$C#XjU&dbW zubvofhk}?;5FNmO@=Z=N)p#S(jydm*@tne)U1wT9sS2ifqgnUX4F5eqQd|zw|*ra|6zhEVT3GsK> zTAK}UkPz>&d}c+|uisF#i%j4b4N?<@J}2hUx2QcG+a$)lHH~@k!&Go{=R+`FjO>I^?=r7qo6spSoq~zFl*Y&bnD>9D&MaE|`VGX{rZ_$?b8gc5pvn7?Fn3+eeVrvXdV79&0mcmT6>k)a;ilp{7ximt9kty8 z{JO4;UvSawu2|$d`Y$Am!{i3UMU8g@AlHW~_{F|)x6}4Csu(6{Y16{K&$ ze67+!#1Acm4JD##1`SA1#XMg6@1l(ZZhrpjcG&s23}!{n-eyPdHuJ&7Ht;JLI+8As z(hC#T=^*bqTZ93KDHjxmD>^Vi>{V~w$-JGRmKIArhc)bwW?r|sg;&SLI^)Oj!*{e& zKEX|L5-#9GoLhTlj z^q#}~t7rqZkoJ=7UPclFV-Ap7qNSRD*}yM%evt!i5cD_Ai}dBO5B2%@72rC(L;+u8 zf}WAU<%He@zG^^;29q4*21qxQI=S@FY%Ws_|t#Tk1yd>?aMT!}F^ zy#}Yf5NiG?gj)tq&`V}VJ{;GtqxVxw z^P#HvVFBS#p3Wy!LN**ZK2S7gv`*R}tNGWtEN1bQffm#izx@eBNP zb;#o~pj|8+h}k!pj0L>xrTRm53!zpDzvTP`&7hD2_PHECteb)veAMCk4e=&*LeQt^ zJp=d!Qe30;hlfgk~vzl*a`L4f1d8?0c*qD zJzIzR4c?O?55d34E}%4s zX;=7Vsu2=)BgS^aj~_0i$FwGQsIUHIEL?jbSrohJpg_UHCHb! zdRu-N@xyBVH6yzEF$)-c(d9xY;A;RBX2lQRkxQq-Th=T>B5X+^d`j;SsBp7kA^rRp z#}AusOx}8*<=mw;ndYqsY;NsU9%B{%dX$=v!-rgD-;->5-Ylj&5d%?us`ytvYtM@r zLXecUZO#>%)^Emb%-!c-uw!nb7=Bo9r^nsIsc)j_|DbA;P@8R}0Fy#dJ=) zXROXq2tNP1fbG})&G4y#PI?yc!*Bt9)Jal{&fL%gY6;c2^)|djy~yGl47NP!>a^C*sueRNB0;5nFE43J`2CBf0u2{ zzoPU|x_!)iPh2C0GRfA<&$> zxJDZQYlGn97eY*{JDu&e{`)rI*p27)xu_RaxKkBB{0&kq?UP8=!G&;l9QE>gE}Rpe ze<9Z0+vRNEqfaIIIpIWe9KKe<#hOl*@r%*3EtC8w@pFu)-8COUU~`CWcn!5QKL1M6 z0Xv?KEfB5^r^0On7sdqb@lYb|^RFui)rKkaFU1Scop>SkKhlekUAmgHOC|r1@e5%? z8J;Ix7ToYstk=7g7)Sij=U;hVFDLRUI6mez8hI-;<6x$fC`6pBNwHn!`olMwcCCPU z=lEg#fWF;?Fkx2V*G}Nq9zwij0bIWLgn37h>kpOgROP=^*&#wq0#va8+Vvsu(Dnkh#%gqACoN1t->#F`yu^`#WlKU z1Bn!fSf|xgg6=VW$*gCL^VV}2F7 zWAXQC3@o$mA;8w8>JxX&ox!+?KF-}$__eJ5PHJ5p>J?lR5$}!FgV6QUCHXH8wp>_% zlA<*^=K+@yTsU5hUwi0f^KoT2YGF4l5V1sz z(5IKzG^bhK-1}7hVcZ?&!1z`XbK#gxdp2{}tfv>#t8By%Um%nnUTEDI>JldlN236; zH(-ah`zDwOIEy9;ws0W4q-?eLZ+D)X<^@vZJ+PRt?yMP@3vxXiye?FEmqSNzmQpE30LG<2|uVtp8m&Ev5bxGe`9 zyE$Z!jslL`+{G(It2-caWF~}ZB)HFT!(KY)bTmfx>Hmf?ce`_K{YwIQA_`~q(z_%T zob!#C*S+4n-1YE61d{_sWR_o^|&&i6H|JQ39utK)}19Xz-x z^0eOJT#!o>;Ryg4*EXY1pSNDpnvnf1(WEJQNajqa7513Ki7+>Fq*6aWVc%=o&XC0F z&~4Zbw|Q?exequvJjg`sCZIWjjo@DiZ{4~6@W(WgY99>Q zz=sYC>JX=6$u3!!U(@Ty55Yu}EOxJtUkHcFXwmH8xG3#)V@G=6OUSm~P_cqvA5U*{zH@VoqD}RgF(la!iFCSO z#*^S6K7MfuscBQ})4@gJ&fK+|%#Vq$H`esG?irYcU&m>s%d2|#D2=QQC$7uctIf`v z=2YPqbNmmvKw&JCeRvE8|BKH1oCqsc@awd>j)3M_d={K9(8Abb7WOLtSAPA*ZfMFL zH`W(iD0T?c_c}NQiP$>H(b|ChQR9zPa-(09Y5?loE{cFZtAHPs?sljVHDq3m4 z*;_EFChF#4X%Wz_!mksVj=kFp`bzt`?FZA>=Jc3(#{R5?P4MeCP_5y>KSb%Tjj|0m zR0xow#1aVzSR18Zod5b|ZY0%~)i>2VZH;V>TO3FfDiJp7=`!+P=C-G!n_}7Y)y6h= zZz`4*`z&BnZzfy8F9XP(bAr3XUx)z*uF&;QGUz z75;S=_;t*QXG5C+6AwCbnSVVCLloati66R@!6`zMZn9aB841<9Bz_3|`UYL=n7!f_ zx`$~O0*O|?5nr8IP{FT3%%VAIPO>?*kpP{9&D;jC)4l{mtMISA&ID{r`zUP7gpJHF^RMxmE^}^G z{P0@3I}^=ka)7P$>gc`ZzS|ayyKTg%tN7Q)u}t4DT=($J&(%Lbx$$d{fnais8a|Sb zUnoPOCJ}Se_tHMINoZ?(8ttum>!?}9zdlG4lJN^U-qUi49T=}&?mQ&{K$ZH9y8Y(6 z;!(FfAG%%q1jPd|m9Nsf1|n2d{OdeTZXtg7YBm4*d)oS^ z&8N&e?gornd$?>P;oK?U0QXhpzr@z2CP1zDV$W7;c4J7E(N?onppVbLT$1di46f8& z>EtZ)PGP3{Gx2C+75^Hh@ieyI_Ry^~-aBH2w>LM7XJl6qj(v&iNyOgYrAOTjhdBS` zbiEjPP-o`^ryHvImvhoN=*G_tbvh@lrBB9-i1Ys}hkaPA@UPEM#)(?y_H;8zcW(kh zJ3ERNbE`6b8DhYQj-w@vR11>h2e2+jDSm?cRPajzqM66R4O2qcg3|@yDC-y1IpnhW zBB&JvgdCAy{xLJMykEa@)mg#xWCQG>5@6!EninWsgJhq|2i*zuT#@qE_p zMr5giU$0X}c5wVKE;$hvx-WVW1|Li+Q^Bw4d3Qtg7AJ1nE>UakuCvpqBWgjPT+MCs z`WSNEhW*f{Ym$GJ7W?s8zT<{u`m`9b+m4%iYJB{1>2a_mc<=j-H;t8UyhjYY`S6aWp^(ana{t5>4e>p2|qAD&WAqO#d;2w1m}|S zdaq&gc({J!+ZjZkEW|UhOfKT{7cehOP$Hw~aGyfJp?jTNFD(RtI$(s|kcGn<4^Yb# z@XL=ME~f|cO*y2!7y?=gI0*I}-6^lm0SnA>{>!9E9NQ0DYr@uBMyDIG^a=36L&@s; zjotK{#Hz9O=`x*k=e!3*`-ls#DO;1`@eBtF^gMMqVQP+>=On&Qz5YFi56XpB`1!AS zJH-#R>m@XW69-LhsBdprs`FpHQNMovtMd-YZ`&)AbH7fH$!iOtQ{w9YG6*xlKI}RC zP(LpY(th`Y%WL*)pq%dim&2yrmW?6TC2saGWx64Qki|+lH>GnTY$d}MzC3+oIPykS z{)=|g916G^(=K(^wE*z{rj1;GIsau%!Mu;G4twFXE(goBiT;E-`sP%}53M~EbAmg? zK5V2m)T&}^Z@$rkRHLi7nePR&!g<8G^c+MWj zcCMTiKU8HKu5ObTKh#rHG*m><=U-zr@6y9=BpaIA`&+`8v#=XKrN$V&W>=jC8t zn_yDl66e?OOtFI5HC6Q+%(h}KUcvkePGG^aY?b_1;6;r2R;O{YX068j3;S?P%^kb9 zihq5NuH!zNw4*lWz7r%A-{()N@#}Tg0%v=6%_i#$h8pt}9Y^Fg{FMrReN+CJmOJen z4rTs@c}>tc`KbFZRrr;YI0Qp;UESlSa79u!BR+DPKL4sk)QGE6fM3UGt{ljTVPY$> zt^jOu2)|gM7c~O=={gE-w^Z3iLi9KQvau^|^zr;~EkQdF9tjnL3nlZN&=+79w!`n-73!uh=zIj@x$}<8<_XDnGie4oKza9 z2mk7xjuZw;^&9<0QbJgKyjuy#~s< zSH@(z=y59x{EMdp6pkAwto)|%_W8~Bcy9UR_OGm|s^7SX5L~1W^Lm@QQwWew$Dn9~ z5K8!k`a_MMQ1R|gC9R! zujYkWs1R-#bnTk|{>suBO+J2)jFczidk3%o=&m0e)Erjrj2l*NfgqvEz+K&yL;!%1xL}J*DTA z&o9S8yP)`oWjr=;wC9KJ4f(q1%K0ytIMGQkab;U~KY*-JMeM8i7n@4PFJoMG^Z>tV zU};C#cvkoq9Tjb0Qo((qzklz?LObiPk=txlAMVEwTi6vz)uP73+-Bil?Mk;~zsDu}<@C#`##=+b+7OKyG@lk8|%P<$?NPF#&x;;1@#X;uT=fAWrCwSl2&hEQ# zEz(}rm1pS@>gMxbuhl5s*%e?2z_BmJWu#FYlx-Y>4>{6{K4tu(0--cYYlWpZPW2Et)W_gQJx2*%uO#>v!xqqrIb+=2m=%KtGP4Y1FKFsrjSc%Od>>~UrlWlYX9vuC zd*bF%Gs=euUibNzf+RJbr!jaCv3>HK+p%%ZE+~l2??U|{`gCGCz^|EH=ce{u`s<&6 z)9Tt3*{#3i?TzyN8*vG@89;B%9UQpT8NXTKyN_QCTWUJPuw)NNb5s3F`a4pE9GBE@ zpvo&u_sg6MTXz$2-T}f1Pj_!SUYH;@>#LZT;SO{ac>#?5Rm{AIGzY zsvaPEGX0TPkv{vN`=dcP_A`2Q{f5@+-gAfkY5I|M?b_DQiG`^_TjiHaF+B?&+hHsd z`;g97y4I~N+;sim*XiofkRLx(^&1ply$$AF+z+=9F{>I%Pqs{kIz^-BA0F|>%q*!B zj{UJhZI@n0&#%7WY-H8l*LgOxbpFeU!-7Gd57T3Gv=V7J#e}Il}<~ zLP6}Lo+!r;e`5?ikFpIry4O6ChQRknWjHan3-@LucszW66j(n&o5G$Sg(G-0AW{+< z*Wu}x+weUBG*5)=o*W7}+6Ysgw($|tW;R{sU-N!N$mZCvb++==@p<3m@mS%rI+f#x z-Gm}&tcHhHu0Q1a zqoPgH663xGzzZQ{X+cE86hiAuJ`Ug6k#ZhanUEMA}W19e9@GoHQ?bwGl&po*S zM+OZ0xVbD{cYL7FE&#;YQ3MY1JsxV^ryGvg=V|HA_&$_vjJivXU>Gq0fR^#;s``0* zhRc;*Y%SzrMY{)Nk77es;)i1dbGjK^rUj}u;)Fj4gMTiEJkbY3!h4sB9|D^~Rn#fx@6{ z!%#)(_2~tqqrAy_cV}>#DOjO9j}vZ(uCU z^&9OVVrYSd%vSgpQe#H@^qk)O-2`{E|4$?IP`UC~%MVUB~1k zAmckeLQNHZX`QLI?3zJ3uC3tl;QWQt!9vW_FVt^@-$nh#v)TEZ1Rr*8&kl^`-;`J# z3;31dF*AOZXeqn9?7G4^8BdMyhYEW76$`ASyRq0nIFh{qi%?d^yY20i`CX&<6NcoOT1^_}$3)a(KjURM5Cuup9Ep2O#t z$1Y-H-N0T* z_B9;XTme8t;a>p}yabP@-}noe(V_=%pF`9@Ah8}wbe%+orI2|z-Qww&3|vFI=o%ZQ zyH##;qT}eZn1*7}LJ+wmZ!Jut#gdp}C|_f1pxXr6Rhm~KC^UW*@?V>9RAf1A0KX7C z9Sk+5<~293+n#>qpkJ!)tIx9=Y%XSC7!{Ds;$K*uY0&KnxwM53GB3E0T}m6y=steE zPRFF3Mzw}Y7`f(=o4-%T?8W;+XVay*bNwNrG)ds{?VOAqhpjWwXS4Q`r8h-A{c;=j zas45o5A+l{FwmTR@X-EhbSMuTOsRP_oR)7UI=nWPbecd!C<}(@%q_qRwGNj}ziHlkuwaUo8xynrTN}OKNQd z|Hn4A(G@S6ZwEWPwE%u8<=kxd9Jh0+I5iqVvn918aPYhoKTK)$g!+wrnJovm4r znsZ_i9QLaVwI9YuaClxx(}ZQ~bixTSLGb;s{SbtEoR-zpRn;HndA&4Dr)WKlWeT}- z&eA*9DtB&G{%e|0c8Kq@#uYA&P+ZQrruHYYWBfzMD)^P9y9Dqng?cRx8=8GJjkFz# z7W%K1`uStx9{E5jwi)#R|H!a46YQ!V>~DH?=x>7wPrvy7C>5Vi;Z0ezC5h)Q?HTyS zK7M6DZ#!i88~U{Q5(_!h_rBteWDp0aKL4d5Z0OE^lTP#Y8^ea2u@pK~_?LJZmLFDh z3c`pJ|0?5`*;Rm%sp4N85{zYgo-q0y+sQ1{IX2j~Idq?>;$K|D0BAd_-QxhixR4%w zl29~1e#n)3t&X{|=d6L$7-PXL%x-4$FKoXy-hR_KsDgc%gE}xHi-=17#u%^ZI*f3N zH``4x@2G9!i=_PXU*KPu4$y&Xjh=uI?+q=$K3wA5j>7daeiamKB_-+{09%TGnUeNG zK`QtKB!UMLv!X00NMa%ua~iqkU+D$#i?$8gDdY!V2Z%>g3g7#k#cpG^rV78*czDd7 z(A*-Pc2*|wOG?h)&RmjJZKeti263e56*OPcQe$X^MZ1 z$NJJgCKUCJp=_g%WNmk;A;9o}96WE#4 zxZtt#6a?Ion(A`f9xUS*^RIU#$_{5j%jrU{yAVehfs|uEq5JVea4V#}kkYc8L#x|e zbCU|xw>}w4mGfUF_!sKu-B_N$$iDJR_sMutFQFSN<#c`^T5YDPyhB*;Es$46rX zC;6a#`{Ynn{tG!fJO^dQ*T{3D-G#6fGUQ`!7h_W?R+**K4#%1z`vyR}WY<{xH?b)1 zTIjP3LW18V75_q+#5lI`v$ES=UkEJ|C&kiH5Efdi`k?;M;P}|E?9t84Xqy|$MERgo zbTV`#IGcaD=09{SjtwE}iCA0=m>V5K&6|&3ihsE#;Mjum?_#;R#=~|){{0(L@vkqt zVHt{vXHX;`m(4MwbP*!y-ny6W-)MJW)m0b@fy4zMVh${%k6)#m=*D#wNGwDy=ofMb zbZpu_tA3vE?_J0DN3jqZ0c_w##Bm^6!BBJ0c<~J$q34Y$;QOSQOo4icbP<-8w14A|`V&Kl28?+Qu8a`VEEA3Btuj3?IB zMNh6hC=kNM9TfHe`V1v{D)k%A;lb8IXiE>*?n3y2c%^3$!n&&Z4TEi+3kxuTAbd%9 z-0ED57C(M?gqI2DzjV|eT55vt*okmRgF{_ytbwUH_uy9wwOr16on3Km3k; zBGV~%B7S9Wd zVnd1gAo%#Thb}m%5O|VZ5pPZH9u*L%!Y?m=82Y|=gB4#QMbb!V+RFg#;}`Uc)E@I{ z)k29N&VO0pARIsR?3kwR?>&yl+fOaEpZ^wkfeTBgL29Nw9OU}LvvO6gTz|-RY?1lY zwk1XIuQ!BRQ?5V6ELO8gVZn_Y(I*VxR{<@4{_Bju?F}}rfjw_t?C<7_^^ge5A4G+K zUa3E1w{Q&SQ(kmR`qk)cwVIza@2H&r$`Wc$Bu043gDnKgXzOjbGo*;o*gPQAAIbsK zz6~XtW6DVeVL_dqv|<rNjk*QBf?qa)e@WO46_jI}xt$ou@L#1p{UX#Ka@HRA_nsEYd?8_k7BzSu zzb4_&uVTC5UAuuXmv8i~;1}~{tk*dBG9Nq#|LV*FmnXt+0jU*U@coB*juwJ5S@7#1 z)I$-I%`cnph+G-JCa@1}0_K8H zA3+mbbmJA1hZ46{@QWVJHQDB;#T9g?Y|3Re;!rRmiVS4qo_=}t^LaO(2-VW#76|4N zJuDs<3dnr?dYCTSNPFGExV(V(*e5R7k0nt^e|F7eO^WwC=fB?KV_!TSY*8nY6Tiwm zlj?dST*bdQ_TF?n#wx@5wGQ!?^wuUgLZ3(eOFhRszuXMkCH|9#xj4K=Tt9EFgcY^< zUC4hK2lv=+G7}-|GAq zpagI%)lfSKw8EC-h#$_%e;J%pi1flH0JfaDlWSh2FL)Or&cZJ>3(U*#u)t$vv-lUE z>jzpD7{BC|Ikzo4;`3Gf>k)x#Hzvhd=MmAqdT8>- zvx>Dbc6;m2=fB>hkxxbLgFVCt?+xvQz!xU3&xU64FKGB~eJTNeelsr9W~Pb3TNV7u zF@DuYxc(49gGL6jG~?HLIqUx3o7?uR+yB}d)-l!=mcz?!Y@C5xR4I1`#0(*?L%R{h$DT<*s3*+BO?~`p2P7&;1}u-*Sw&F4axaW zMjxNR$*In&_+iPsf8w-PvYVg(s(g3tqo>+^{zc$lZ^I0($F;oedxQK7L)`+sk1Ffiy@MxjTybiv-~~1fPGsua+D5rOtm9Fv0T#f>}V_P8EJJ?Mia| zQ1P!Luu%$pbCvo-UJF!6T38*9hGRpX5D&0m2dnT4ksOasmiX5j^j(5KpDV`?9n^1N zUT)ZC`^<0ynydnVaP0l~A@GZN$|Q8BL{DbuXIad&a0z}f>M1*qHPxrRC-ZaE{^9z= zBiKI(V>a=^v3oF0AECD6!EYcddrQl;< z7{&~puty|jQH5X79nX(~qNznNhH^bc;<9-F*=RZ=_r_u; zD)B?FetxL;3WhB;W>h5FO+Dt#)%f*2>pE}lUhQSinDq^6a?IWee(`yfnbMe{G{$97k$ntuVmE?rX?SXf%OlK+Y!pgfloHYdvbYq}=L z0n!3;TMqAM+}~>?a`D)jAof^EzhJ|`LChHXRQQ((nCMHtY%9J4f6UzKG)*FK=i`^+ zUrmu@^9x@6;TE0$5{kN;YO$wZCH}=K13T~Ojymuw(Nf`G#L>bHGtH%V)QtW#}C>KIh-95jzqAgh^~U@g`a-KDWyvOD^*?sf6N6cVzAhUK7J|J$g>-zF*74mmfy#(SD1el)-irf z$OATLvUl)2@;RV`;$M9KA#U3!;9kclp=={(W_pxhhu-Tc8tVIS{UP|5yN-GY7a`h6 zD&ZU=BK9tT?2P6;2emXuXfM8V(AG0{RK~KHGW;>ZmoLQ+so}I$#I@=XscZK5o`hps zdLaFH5*}<`udY9I7?<@64w9{aE&SP(3-p*oONoE+{fFZYtY3Zr*H4-7=OxnRxF_(o z@R5N975oAU7tBODE(c_E#vBnbQ~8I*GJf&>hj5JwrrASQcF=B)A+KkrQ+C!&lged;o9C&-0Mj6udxKJZwi@d>|Y5+R*xNx zpM(4|!t$<)F>-wrA0XvbPDOrDi60`JXYludA$^7t4wl=+eNC_%N6Yxd^@p7Hg6<$> z0l`c`iEwG2i!qn#HzfAuzeu1J&VMb~(chFZ*NZducG;YWZNZ}0JRa~b8Yo}|yF|Eu z;9i=NoiO7wR|e)C&UVzpQrL zE8^|LS@`v|3!1!3Z;?-19k<1^`aT%g5hh|){A-(L-<)g^0i)lJ_MzxYxIT*i776tt;D)OElsSukm7-xeWtI&& zKWB}jkRx7IfA}Kq)&Ku7qD)f5^;b1J0U>f=4|a*v4xP&jUo{??LBAM4ANb)$*x2C-Wt1e z3EQ!ojVI)RJ>jbR4~GTnD&4ujui$^CM{kCrO^NfoUVi;N=f9rXxwK`@xQ4{a&hEcN zK(dRTIuxaPP9gO5L}S09l0P%bK7{Q8akG-{(fFY`E* zNOYz!<~lLzi~yTLK7O6Xynt4Uf3ef`pgwJ#bC9du2_mNKv*f>@VjnDqiv!?a68CKX z@=C0ic~EX}^@3-^rLmcg*>)^>rzosFVxh=zpJ*|L9K<*HZ=+aj6S)2mH>kL=Lx>+T zewn%YINNZix_+Md7kB{)*Th8}60W`pt;|U{ilZ7oh9vGkJg4FOm(;<(kQ|Tabb_Ld zDCbu1^eXH6*j?+Io9OoznBYS%06}{P?&v;TDZl}e|c~W-sIzQ9ElaKSkV3a7vgMH z^YSKGn(3_gA=VW6uL{uPIpe^=$qIhq^z=Ax?yB-7usTKH=^0Ni`2Hy67A~vIYXW1o zi@@co_@PRBF@-4$&ZBY<-^DcUJ;#e5c8)1*^7+>pN-$czfE|sWcYkkXy=Kj8vL?lS zy!v^}tLppghoY;C=>7Z`#}5_lD*1jz!026sMDwisqsl`qkNNAc0Ikd-{rs1|lqDfA z_;7@ZAHLx2`Eva{EPzT}N(jT|lK@}%hyMBHN{E019oV9L5r-1sBrE;m^UKh|-pE&d zpI>hQVd((ds>UxxyZBgBNw_+=&58D25Mmc^cyrOidl>uXJ zI~Dz^{`-~Xq2i7$@C$fW{`s#mJt>bFe?KLM`i;x-Ur@ctavv_FFV*`!>Dfc|_rDO@ zD8~;ebayZc{`G(zo0b0pRdg}J(wKYG3vA$*cjr|f?+vcsn9WZuT)=Xt0RO_=EAc~* z=gt}rzB3%5+4(Q0ihor)`}r^M0$xF!N%y}G?2iI6zkZ{X|0)1wO8GBFv}QJFRrux8 zE+wqs^UKoCRpZw}-p@{`x6EZeFRmi+uPpYnk6&EBu_}f0U$3xGh@kvcfPZoQ;TxWQ zdG{YGTrSy!(xzo?^7)rCgN#;Pq{=o<=?{u$K?Hy-`do}%F_Iedxh3F9f% zR1hg0{rwaNJf&n0 z3&9oieS+_o7lm^EE6z4NRq101c7$-+3w=CWSFWE&fm+FKuzu~K90e0){3`wZl&Uck z@XLim4)4O%OZau^m`erBPF=AaKcpvC>wV74)(uA8abM6%E$$Nj%tTMD4cwu9+WBLv zVXR7^q|;+HxJ%T#@P{@uTPE##(@0+?NLxLIBxxzyNLNrm`a*zPeh)3BK2IbApVK}q z|JZIAH_AfbbEI0z?|Qoc`YYE%62_&nv8bf++La^RjAqydCH!GvJ) zKd)}`=Ke%Vn6Uk}MD2M+(C(%tX|684>j@{2(*A@#MGevuoCY~(la^F1!fL zNhRQ8X0(*xTGTp!UOh&lKWwitEie~fkgBEp4J83M5DQbArX*NkajL~8^~0JbItO!H`<>v8`33V-asIQK4_8UdG%a6Z+wYFzxonYV@~xq+Bcf> z(uOZ=>aVreB`g6b40wW37SKYK zd69H%%S0_H3#dUCnlZS#$x0gKK2O}J|B-w#b$w%9wa~9x%I|vO#=sr@pHBU8W5bia zFsIbwme%W|H|lrDms2-1);(DgYM<1&<-a#x<<9fI^G7dx&L^KVz+h9KXk6gV^Yn|v zWonhy`mmd>Fay$i3{j1CtK68nqA_q+Nzm>J+$xi)Pc=4_`+U?1^l6`_KcEIgGa!6| zEH}_+tfxQ5E-$_7qdk<8jdqQxrInyIYzpgz7Fiy1k71*w$F$N)Pzz^c1<_LJ6M#0^ zx0oQz5E7pZH}q)E@muT#W`N4`(zRaqmPA81u%=3ox7ZD4z$wqmL{!I8>dOKv8ea?0 z$SvhAAMFt&CGzelB8HH&V=VNmmh!tW_ms9#X_LlghZSv3xurC(Cmem2ez961d^E1~ ztNb!D5?Ywn;L}xv6!e{2{64H-PPKkbQVaU1mQtsHw!~TAJAZ-kgf9e^z^=}>4F5UJ zfz8MNwC_{f8y;XG;R&u1WaV9o?GP+11SxFF^2u8g+*10PYj2y^=-${gFT;Xyqvi>N zXz}~dM|VY+_t8Y3v)lT8qxSeE z!h%}2+{vhd<5>XR*x>j1kL-p*YBD7GzyAPF%LrTQV*-vB%0IC2XAv(IT>mljfAgG6 zak&K0DIB^e{T3TH_1EXt4$r$>DD^PiFih71H;~ZQUnY3279$&7ip!-IM}v0q&vYH7 zB-Q%ksSUUIeGK3X-AMD~<$~A8(j1W@oGhVQd6|$_uOjE8{~<1W0PTAA&_UPBaJkZ= z9^_zv381-d5+78XEx4+SdY2EQmkP4^bFkIYzIxfIdp| zE*E;dcO|KYR!b{oG-{U%-eU+E2nEMJE>{bsJ`V8oKfq-Vshtw0Xg3;n^e;^PLF2q9 zFB9C-n6(?l9ddW-_Zw@Uyi6$d>Af76D?mS5Ua#M&U#1~T@50<~mAJQ}QM>Chq11;y znliR%i|7yJyuxKdd2e97X5q3A(2UEacVWF|;j$0VjLW4y*oRKPWv?~oiOU2k&r7FX zcR?Z$*4A7mIHl)6L#lDv2k0tX#-5*r%RWG}P=1%@T&`ArOX*$zC;gJ8KKO+CEWVWSI4|235!!e_V?RppCSuX(!4N2;K(568aXy$W{Y z5A{ztFHT;+tnPBbDbFi;83g#C;Fcal49E3lT%IMYE_eBVip#U%xD3$$(|_0Ha9nPA z&+jt}mwkX%g5O6Bf{No3C95RVTIq6&--kU^A|HEJYnJ1;_?-~Upp1j-&Ia2c^az}m zMI8&b_+6@=V|x#jmp?~dvdJWSffMFZ>^ARr$qsbEf-8H{@1xvCb$VCMwcQMc;nE&929$K*ja1^2ZJnJ3!&8F_bC&vl7a7Os#tpOF?bFKdk6^@ z3xWm#et)^8{2YtsB(w?o8(QejSyl_K4YwC9#4V#nX*~XaRTdUH>N$TS7LJx)R{0wE zLp7My5|gW-AUI~#T9l`2$(97+&d#h3K~6FZ~&L)Ud}5Nx6oiBTZoDA zlxrv&Xwt^8a#O=34xus?Au?mTZN~mQPwJ~gruVohXU`%V-0=~89 z5>Cs=99)&p?Wn;IHDku(hQSy+Bw8K|(mqeiX-ul+G$y-;Rhb%muC$3gtBv7-O&a)F z|Ay!$#oPO2P-!R#6a)$a1%ZM#@G>^IB9 zjJ|%C?WXx?@3GnBJ7?G!59L`r9_;X~3LiZlyiq&@lAsG+mXetgW#CV)>&nF+e2jeOCuaLq)Z4rMYUcnRM`Adox dM^Q=9V8h{d8RGAx_@sVVOHrPy+m;$q`~o95!odIl literal 42175 zcmeIb4|G)5buYZ{xmV(9W~8|YNLByAS0mXT<3S7pV}e0C2<$4D2Gwy}w=1u2{HHDH za#A_X>qqkPoTHI!#2=dpCMjv%d}B;fk~rxYumOYZ3zl7hv8}jX4RKsDc4Sv}NFo#B z2#n45+vnbyxdYVgde3XUuJuJ(%h_BV?mhqZ{_Wr1`y8k)KJNdI$heuN{8{gx-~8Wi z|FfCBx8Hp0pWfE?nOkq8TPV{0S98*TeaGx{nr@|Nd%8V6%bh)Ic01ihb+fNpFlY7x zx1Ii!Xlw5o{CxXszyD`xQU(!CN*fvee>-is2C2@OY4Z5b6#Tv}O?Y1UvymoAJ=A(D zH9GwG-}$kW{zYTYzw>*3Y$^PQNa+8b|35-0{fiH3L*%zU85r%yFZa8!6}K zv{$tiqr1g>-a0oy_BIhb*(QpX%WVd04%5Sw@}g;RnEJ_$MAD6(wVhHFCGi@T13%uh zhv+eC^P&aaCLxk}ag6p*1HXCP%5WQ+e2m`Bb$IdZ<}vG8qkU>y!F+>G(sUW$WR6(6 zKSg67_t}dV&0}n zmp?UJlcLA++@B?1q;-_=>ht1F+TGKZkM8O^jtzvLV$E`62ajv+H)A|5>_9QxQ;?~A z)D;uhV)${5>9kAD9F4B3{S#WPnv3>I@h|)&6TL|c`|s(tW0;?XL-Dj3Q|OOpr_EvK zI4#V^XPYnj8%JKek1&d-FBvya(;3k@gyEc!?@{N{xMz;kX82p%YK~zxI*J(1G4)gG zAP6ab;>GjkTcqcwd-DDC2+j2DJH&H|)ew?yOAkFtGb!35Ui9bLqp#B=gENcvDsfb; zRx`)#386<(jII*n7$<(Zryiz)N};P*rhaN0wp}5q;IHY6mR{4bY1`1}4wcHAW6oRD znUCeoB%Q(&^yifSt!^sP1a&y^tf>Wx6YsG;?6D#9MW`@-Y-f~5A+cVg_CW}-oY89Q zCpq(g|1D+RhTYQE6W!D}N^7W1+Bvb6_E>E)n#&f+;rBGvv~ruS=q91tEJmBT^f=9u z(FyU4zZSMNzp$_# zpPN1Wt<4vYV*4%Bea@e}qH|e1XJQmWkKzr{>-T4r-lKN80lyLlX}fIDZFroXap9 z7<(Tjq+JjvF!s2Nj)-Ucwa8E1N+)GIe|^+CXtejXapRNDbo{NBF<-xugf_nJ4DoQf z{c-tyKIH3H(#e z$(rT77LCz);;`LMc@KNcqhOC6D(Tlnv`b?5_KH`m)#+x>&NRN_?!v~#ld<4E_H_D{ zT69bNQ|9}L7gV|!TWS7_fhQSQwzmW?1=$yCn;_#`%%913?T(kRMaTTTs>}nveo5HF zU#mH8e9Y{i7gXnK4Pz|}=zWE~I&6CWdToP#?V_tF`Z@EHg7wSJm^boT96*2G^5>a| z+g!?hzKB-CfJE}*B8fgrJn?+}%0Rz%c&!wj+qj(iMe2y{-U9u~r3%qnfjQ+qZ-dP| zDd$mquDOt2piZx$U?$YW2=psw2H#Qyn>iPIb!R^W>KKaeG>^6J6|i;NpmF*=hI1PG zaE^?Rn+u&Ycu#!1{{+2f&0;I+E!A!MtlMb^&5+TZ;vw3r4Rr$R#rtqmwkRF$kAltI z3nYgPXF(ft-DUv0uIR6YO)>l`$!*r-g&Guw=wShkb4&U~vD?wrc7ncN1SLX$V9*?G zvGXmS*~8z;Uko$IJF1uMq3&~OkByjPqLxJ7@v?qXH8E&KT ztFNtS4~hg0su^zN4&jPH*lj#1`t!{A^&q-hm%i>cbbbaKy;kP|u~I?^;TI3t9uP?a zl1`1JYm>BvW@MWNOZX*$Uq7XVUj1BiCA}@@d$B?^i6;v@SjaGb@o@Ug6LgdZI6mnm zdWHTUijP#|*8-lFeCADBFccr3;=+K;yHUT#<#927=_R-v zFDyaQt0NI}66qvem=?<^n@jZ7Ip^TlMD_-{2l#d2Dsh8*SN?%a-AWO{uV2!9uU?pz zdX45&G#$N-hGm-SoiKg{%XEZ(<#dk5-!^y4Gp*Nn4P#;a!YUW*73Sv%&2#JDF_SO` z+Z7CK2)|gn?cT1b)@o|@y61?gbQd*CyElwqK-gkkx43~e4PNfneO|QFfNFN_ZV|#S z-hPp^s89E+RuA?tCf3mwFPX-B^qyz@dJJe)pEtYdMVbcz>vhQ3(gz@`#xJTHGT(-Y zyM{r51uWd~l(X^6S+doBQ_PSna^_{N2lMSKV`t+R+vir`R{}!UW#ZuQmR^8V(b4)9 z;1?`*cBlJ~bR{>Qn!U$r>9S$N1O2irAHPNbZFkY9WVA7>=cmU$2fw1q%+nb6IU7w1 zSQpGk7{5*u@XIlW=xv%S;~V>j@^2;?o2I-`tM#j?2I$~h{@dt>G!MTr`J;0HzSZ~z zE1|kv;MXh&tY21Q27oMtU$FCwFB}n{qp#4V65wlD3}m(go8W(o@ryo#vDeO}dl<5F z!lE^X>tTLM_%%)UXEFMG9sN+u!#qb@YYsZwWh!Tu@XG*x85&_n)kzD2V~!4-9K4f( ztO~#Gqz2C{l-AUBhef-cQf2(ANn&q&hS3UwDweq zewV(p*nQhhcLn&BH-KL>Q$am1q9;|e7fmNF7XP@oxySCs+DO*rZNRTztC{(Ro6N7$ z3H4ET#TTP@I{(%OgLXE4skm!yqhB&WABVa4F?C8A!BsGN zDau0I!M_r|elh>@A-l1d*$dU{R$zx;vuiyde%fCPIqeva%fq;S0s-zDnJ(-+o(z~y zh=2KT{B!#ZHy(e`2j~@xtMN;}=S_MRb~RRLd1&yIgmbbT?{Rs40{kjsnU2BvO=Rr5 zMT@=XNZU|!Ust=o7T{kzt|4qK4;-!auWd_YuYFj>icv$%FZqYlEye;cm!q^g*OE`J z64Q-G`N>Cx?Z1cl*Dq=J%C%)i7;30R*B{~7*a zT|{s^P9E3JcmAh!9wPy zjMC2lTMZ-TZNvl__%?Yr@`i>{XNP|Ci=3gbwNDn}FB2Mk+=q^k1 zuWT5iK0D?z-#%CKFPca7cbRu!e)Oh|`1+NsVf<>#YyNewY#D%K z@|MDrK|G20Yr*_0(67U^ZhvdBZl7Q;;dY9W9r5)mz%LIFa9FIin-5^UUNLrwPxF(c z{~jN|7QMP+)smwy%U2icSDH64BXi^P%^8B1qQt*gQ?wE(=+`mcy&iUE6@D#Zv;vUj zJBz6abAg0CWJDu>y)=G_nM=7FOuJ-#Moi88z~@%q_UAdkFOGryD?Qp8KVWCp&Nm*h z8TGPZ{4!D!9zFsc)aKOLqQ>3sVINv>U((!XAHSxNbm*yOusP!cLdJ7Pb}RHI=Y7Iw(g;>TVQ2T1_Y!gi^d`R+D&kq z^Z3;sm_b1HN;uLp;EPt_S2yAtdGl3v0=?AN%rV+8(xWjaj9>3N@Fhm3oaTU=hkf`t z_kEh=#;f9o&_NGt`X&s1rx(kbz`-UMSQW-EY#X*4qX^*4@&@mX#5s^C?Lrv8f+*+^ z_89tXfgSgI@Ou}8@QZdTw)~AR69bw3G12a>2atiwgz)RQwXhEs;IMO?$JJ+A0|%U5 zisk!5_yr3fF^X}R+)gk0bjyVGD`%01SZ)ZvPGveWfC)C9oiD|5i<5Bd+vQ!kFn;ZX zrr15=2!{=aA`<3Rc*!O7lFCERBFub&Tgbls@Vl23*i@rj3Edtm2C4O zDsm5kJgyfhL_+xW1)83VZ8OHKQ*Z)f--vFLFRLx8{@Z31ez9f4_WPm>*itYAz-0!q z5dQ)$`*xL$XKbfAKnEoZZ0>ycWg|!^?M;naRi8UUc5j02IIQnJet~+7h|?Oj>|B<~ zNVANLh${TjmY+j#sb#hUjJu1jkoM;y=fN*JZFJZv_)!Sze0FMsXP$*$@q(d&Y#H+} zI+?_-%b6AaWt^lt;;8d$wP>timH7whU#ZSlkq`;vmv7z~zd8>;Js!>TqP+B7uL{2gE-AvF*F@~? z<*USkrC?;^K(q>eIlG+tXQFqAS2!f-MY_Z$xvOiIXWt+KPNeb6hQ|nub9dRW8z7G^ zz;4LyO@#5wON~SqisxxZ5rGbcaOA^1XuLkmzy2q+jZfOw{|kE8gB{!5m!Nl5+)Hii zukbGi;ZU}9$JDz7bMX#f3s0VjkDi5J2M{*&UH#bMCG+ygO?avCr^5Ip+Po4rdG!iJ zY;P73v)3bT6@FFPFzvGTD)f2aEc~jhDS}tT-j@eU65?MB$150@wS5K+rIXf|yyZ?c zetpS{j~jlUH+a!;=uYSU4Hf({uuR_78LaYW=~(WX*4SyYmyXfZ?17B?`sE@2wIh*O zHdt8e!U4}yvOVJFzhx(i_U=;raG3d*+uA)NEu@=oUTNFy!X3y{t5?VIL#?OGzjla( z94sVkK$|;&v0p~tv6;|OkpJ@e*F4!)m~x94gR_<@#9QbsZ=ScXa8~?qB`D{w=sgbx zfBd&5=#=dAR*aYU*HX@ZrRNoA?ucf(CerN`+iqSV_d5%Cl}CL4@JJ2fhhAa?qnOpT zPCa%axqEG$TsHzDUl7NAUqbUQby-*4P9Y<^yIj}aDYB$g600ME{8zyMbICQ|W`901 zy?=G?Q=?6vuYF8jhCrgZ3Y1u~4*L9So;R~#eu|FE^jBl)DeJ|4n(s|YhvJ8_in}Yn8qOSwCT3$o`>+2={)j(fCpR4mGdd04HR{=!)_z@Ih6l8 znOwAN*2V`<wu_h{>!pw(2Y%&M&*u^Ha)y)qsD=Z*NY1bH)tH-r_=tTq)MNGZZ}7aQqOFrDVFR&F!a$JdlwF zu?{{G^eYrUe3Y)Bq)eop0Z;;43a9yQx`Oxfn7^jXzur-E+}Lom5#ggJ-BdTi8i&>F z;)b*1htL%Buy~i|v4CuHL|gt4|9anl&vv{=zp!0Arx47aFg@QMGXHwSXdbaYXZ|<& z1K9#>GEdWh3$(hUI{($|)iFoo7=H2&1V8T zpdMEh|C%$DLVC#kg`9K18b?Cyd79(ZkC*aa%DSC)t3-Ondhwtblux8*t`}SE@2CXZ z!%+U~VFwXu*aY<*k$7qCY!Q>|CMWiDo05LTsGwZBfEpAjN*M^jDePvwrh$HO{ICGE zijhfn5d&;cCin$y^y&+yXZn82Z*$I0TffudOZ24oU7qLQNtu70#xiyK{0nYI5w89z zZj%Ro_4@0@@xyiS)tP?pEUV&&3RWH9>km-ZIeZJu zrCh(Uo}M*24s0lxqkdYjV7^X&m+r_SemG+3{loFYL9eYbdRO*MSNG=;G1{|kX=-yc z6~-^s1m3V_pRr(m2uTXnZtMN5 z{e&QXsG!|1l>&)OG@2=z5ik1h(eXpS&&4NCM80itHGVzrf`7dvPVleFZ6GvO@GH+@A7H^tm7v_i z$&|#VJusQ4nej{MuBuX>6PLo{3}7Q>f^-xixor@v8Y$VFODBR?&DX`XYM>Z{}=Wm|E2N0Y1&q-a*K?Pl*fMA z3H7+G*=Q;M#q}FEp+8?XUsu6AzhQ%9aeu~qy+Hkjg;rdbAnw|U6dFRtGR z))e%_w=L}aYa(4CB|4lndMPl&@cD_$?3TtsdytO_p9$#;*z4k&dr7 zUz574+sq`Ll!+d!PKAH*C=SPWn1~|e75sl@sWOSss0wn z4}&`!ki4i|zoE@V8W5m`0`Lo!U~aUj z@qk`-G`gMp%qSczK_2-g{Ui_ka<~=85B(igvWLA8PScl+cuzQf2!Dgw*82z>c5=G& z9n?b1A)OKH<@Ydt?HNe8gM*3J?7?iC+dbI$8b%6@EAubTe?6vV7)|zdMao;BF`DSQ z;mHLnBY|ik{*3E4f^GYT3tAbq58uoRP)5T z&nJ$4?#b_8T8zGz{bSmpE-ixHgz)QaN)Mshknw9S?=fjZ7>R}X7l%XZ!ILU*KP9Gv+*%ZTI5yBbVmh6?!LB)o(PzO^rBW0D%!Cl#bhw{~D!$h=uu=mEdS|s~yxIzCmjSw_KOZ0TA_`=lJ2{^x!SYk;pv3H4OGh z*E>iC>AzLMFM3?H;8%_F5H_5-7(C@A(U){NkQm}$6L1UHs}^<(QRk_ajMH#yI~O8` z@at__DE~5mBsq%(CStHHq58vL(QGd^a_dX4D+w{ z<+07?(}{z_9V;PV!jEjfDaH7u^*w3${A<=m^WW%X0`-UYw~VT{RYwNn3iB@)voT;c zBR$ubL#n*Ug+km~Y*CWAk?VW<*SxVr+7X-e&Z{tk9X%SzR+*LfA?<8> zpf>t@jTdKjW}0iGh|hbE3eIhbZ&&bZA2mBbtBdJLd2=#@4i(>R z9&&xGUUjrfm=IhY@wuwuG&u4z1_9l zY@*D+OuR=%xa|2`G{eJ?BQ$7##02AbwJq+hc`d#Ymi{+!` z`VF?~PpaSL_}rh+F04hAR|obm#J?T_OyI9StnppHCrK~Uob|DMCI8i`_5!w+D0{?C%+{uFC|SHW(yN3HBruA|6{E{F&??X79st*z8=(2iU)>gUDL zrd@+N1lQjD4Rz_t$V$=ezemRpopg4EJ877XQ{Dr9k#(GQQp&BW-G^%C$aB|*C`C4<}y+6aS}9sFx020D+s zny16SF9=d}_aGN~S0(>-B7ZWuP=Y}R+-jg zlZh=2*KYu}jBeHF(t391)Rbjntpt8$MW}wG51i5NY20MoMM>`S0QE_?2Z$zo{c3`* z4%o`rN5rFakD9^rvy|4jTe>Nn|3WvAKixd#Zra}m8=f=2VI7p)GfQ)o{MUd_Cv!_~ zgYZorAhsq0-r+RFv)I+ji5 zzD>x(Dk#3>c}~`RoH(P3TCwHM4%Ld%AkjdGA8wA!k3^`4+vJU@v^tOIfsFJ(VKf9> zME^j|xyUJ+7ed4HmE;oncQMw-B_S8fLzc$g6)LdiBjU(3GO{`xa zVn492x*K>Ja3b(8c#O>|c}wkxxheN44lRz;-w;SZuaJ(*{c)!v?Pa>RA(eSJbDz@s z<)yE;IfZ-}zphcKL+jFh&A@4Me)31~vSTMqTB>!qk3L0vwQFSF&an$G z`Y22REH?UMW~9S?RyA#~3CM`$#O?Ik+@{c#y8b>&6bOkhe=RsZ587qGs!JORvmf<` zDFdslwxw&k{P+gduVfcOVYh%*;61SOuJvO?fR^`0$?V~80uOh9-~W zHVzgkJSpSX`vm@#i5)T7Z<#$Fy9vTO>S_;;$9M_9ehzMxaB=J_;S4I&&<_I0_71?{ zSMjgCuq5!T*x)5>_=hptF0di1_!rucy|F8$FfCp(pG_HiujTmaEg}AOiqeBIt6wOu zfB@-SGX;ZxHD~%l{EN#rW=%xj7iX*|Uyr|Oo<{wK9$<)n0l%^+14t><>3OmH`&(&v zc)`&6D*lE3OyCrNYYnowP$FfmRV_t(dzgQ1r##us5h0c9lHCeNaU%e_ntwf}nltt* zDB)Ype;u`a?%x0%?9Yo3|N14i5~@&Q^c1D{#{`5I(+l=j^Dn(#8BLSnZ@h$f?=Kup zFh^=LyrvvK)R6(ryRC&DHh@pSWAn|w@YjpuhbY_F54UiHc8Zyl>=CcnyXe!y$=(ot z5yFP~Xt#LL*r{f@HqNZMj|`@`^S$Kqw}Se^ah%P8qETwZo-Gg%kTD*61;5arg&X5r z%|j!nmUrA8+h&f@``&aF%eQ>N*Dt^Ru(J`>8spCCSSQUIV*I)ppfFIyzYuv#X*vJ_ z{Ob*RQ*|r_Qiu7M(bj8Ul(?MM$Tk`Isu*(D$dt725A&}*G%I6&KQb5ig+l}*VpM*s zr>%=NhVx&K5UANW@5$ zt>~&N(N%p4peGu_FRq_Qwri7Ub=SFWcO4%z*fSYM2H5Sdg|0v3tl~5i=|yV4DYhAH zPWH6{q$>Ee6|nULpzV5urdik+9hL9G8Nj&8_?3s*X=k)*mh3+Vh6wCNnQJY*f4Kf| zJGErHi;Yd)clRY!%9$PCCrNUq`A58=Nd^={K zY@V8n*u58t4YK)g8aos*U!&p+QoKk&RelnQ!YUK@T2)lR+--};TQX~ z*mZQF2b0n zaA>vrX+nQO{A(A1c`=0As8}J&A-5{MD#9b6SkkXOo@N8)*?_A{rj`{7iYUrqv!z03gTyK zTjnzge4|*xuNa#P9)(AsT^ce~$6FTO4MtXsoq}i8%VXE^!@f43f9=j9 z5%x>b(X%1ba(wV~IRAxWcLmHPi~Ef2hdRBCdl*Kq!oM6&N!Ymv2kscVMT+r#KPDmV z>z73S>lDI<59I(`6T=<*u@)(0vf8~=p~AoR(R&QX#r|Mi<1McM&Do&}#}7}*c6ce~ zF*WSAh$_0YpJr(|yqCIMhOxB8`TGKtR2(te;G^NFZWo!4>qF4j{a^00SiT%{) zxkbQn%)+jNqJ`@Z_ib+3+VpwxzPw9aS_Bc}>WJo1V1ezw$FJW=ABef87uk<)VEe@+ z`ZKgV9c}dWi|gn4bOS8gEA%T3$I;W7GamyH`&F2K{gU!Bk^_vwk@n&{`yaBg!w<(E zG0Xhxez>X3zgVpd_^T({FOs|52ZthQvC*Gr&VS)3O>yn2u8!naaFCh%tajy_$1eCn z7{3Y#YuHwo;oLXMYbp>w6sSL}iXU?Q#=WiP6?9ZWt@0*U)VHgKycxnT4jaawiH@r= z3AIvn5}S4*Eg^HGuV4Q8<$1C`$Kfn4=gygzt^FZwm)%wMhYu?^V}CtTOKbArRypxa zFph*=n+x-=z3TE}-4S5Z8ih6v>@&BSk*lpO>6b;1Sg=1MVrm`KN=B#pT&8 zZe85;{p;p7)=51-40iA;bJg|pL4P#Q^(VZY&wqvM52<76iX7K(@VHPkD^Air7DD)S z+MQ!BM@^|3c6ff4xb_hr$jbbS@yk`+t{8UirM4_mB-<1KTGi*pT7NB)HIfRl)v06s zdN9wvdM(j?2v9)3%KXcLR$lIXthezreUtguXGM-yi{|0F^hdV&@7ZQI!s~t{KXaA& zviN4ezv#!W&Y1ubmHAhm-nQmTu>K*GJVAH1M_*Uhun>wLzDTdDIT_S}%o9g*i;Ah! z{nyYL4~dl!|H{d`IWCH_sLV5s`uxRa9iPXOGXKiaKl+yBi!^Wn{HR_iBgYRhE>JJF ztL{{f)M&mrX+;({Dt5!tV!+-Z0160R`Rl%ITAs!-?QZN|^Hw_KEtD~wV+AXL!7oIE zZzJmp zz%P#O#wMa2^ggUl{8+R@>Ui(CIW9GRas44GBoFEM;bRu!hg-T*>Zi5_prSv|s6VuU zxx-1AcWhed*A@tPatNb%P3iUW&wpVQ3|o)!Byi5|J4PGOyldQ#y%X?@kqEexf*C~Z zlWV46pRvcrP0w#rH1_EgT#W+FM08| zC-qFqaGTQkFU${*Yrc%-F;V~1&woXHz3}S~XL|L$;uU%V`7b+Te$v`yK=H?G8~rwZ z{ozbzTSu)&2R@Yt|MEu>{huZM^7&VrSC{TOj5W>VK(3eT==b%^zg+H5seS`&Yna}l zYx1cg_Mx9UuEY=7#nKRM#b4|nMMSY<*@}(*uhnYZ*<8caY`Tn% zXm|G-;&E9A(H}%SO8g7c587uO$hpEo;+A>(11A#EqZ z_?4H*siM))-{SfW_76Ymm$f7~v}oC1=5e9O(Dz$P=f99=YotLNFDaPTje=TO%l zVl4o*qr7lQEd)UJvcG>y=fBpgeqKslcF06^JHe3-<-fRWBT`I^!C!TW@r%9<{7M!@ zrG5k2#Cr^CwO9H6Aw9_cp^G+pP4km4B4lq5ufu+B+9jJ0Ar^N({e#;)JSeve`)#%% zd%$HI^<2MkrZ{^dehNhF7r8lOv6aRlKnH$o#8+Vxj(j{fh41Zo!izs@{!G1lW5>V5 z)s#^E2CUz>b<#L0Urt|>V zaudD)7GUmQ>gqPu?OMB&lugmz9EZhVpZ5v~k7tV|{K6AhKRXW&g5Z_kW(Ny-QKTMz zPjLQgKYace+8{Vwh%gr9JvfsGYPbn0eSUe7huxCGq6FhQgG})XWqQ6n49vrSrk{fRz=J*D9+EhMS1^B0PaWCrL8!(rBRFCzRnQG4nE+*1^Py)a5)%;6mFYcj-y;Ki|v!3q5 zfer|({Pha%k8-0&5Lm>qvBxLzlm$@e5OBTUn2k zN)a57gQ_4gcFMl!ue-)CV}WYOV@DmJh51z8JW1~tK*UDF^&4;t39Nry=wn|BYQ;}B zg!5lgTS$!s)VR{Ot4dqZaQx8Gv|^O@EKcyX8(RTD`bnsMgKc<}Yw#YI-(k}YzLV5# zD)k%A4z4!j{MX}jWhUt$4aTHqU3L7>En%(&+);e~%SYi*{YItFxXS|PzmWf8%U@N0 z$oEGzFdUym*#@v6M*oT@5Z>_D3-yPnHU!T_*wEU?3Zl%+ROVj|RrMPW)2%WB&geW2 zNP;P7rN8rq7k&Nm@e47lk;q((E6e=!Pf_TCjPs^&{l?o=K!2vRB8;iKVbKqZ+qpmG z`i+NpNAVM29A86(uF8`*GmBBY?At@&mz=PXCHG@HdZKQoVNVMo{?(Cb`_|wL@g~lH z&EjLrNxGZb6ohj8a2X=fDT2lJ6nu5I3Cjrvg!L=Lzjnc550Qwp^-tf%c^ z@GZ^1Bs30ZLR~CeBW&F<7v~*32&0td`C`LwbIUqV-rv%?bzMN{Ko9{daDUE2-jU!?6J1nzT*e*wRKtvZYK zC(SR&A$65oKWyGWuWY&+fy6L=fq!+u6d>HE63{l}zko!CqVHsbu`_;xB!7s#D*`z##_(4L!pHH$s=4t+w;dy5M1;1C-yXNhYL&WzHnJcl` z=JB{f`7b>j5A_=wzu39`SASd~{xw0!59UD!eoEU9ug8Uo#OJ&9dtCmMu0Ny%>_#LB zm2n+Amh~|Az^`!;@Gl)dB+hmvl6Jo6x~ym-(64}hWsK>BSX?IgN0AP`e}mIr8Wi9I zz~o8(mLETy&(X^my&6d`MIvm--VXo*euengml%#YehBH*B?f3kraKGX0S02@vp}TcD|<(N2u79<%^{5VJtX{f6WJi zw79qqtAp<4LXKm!fbR^cjvwOK@;cBiHZt1agMR_Yg7~4&zwVS8j-R8eWQ_MJH(rrj zQsQ6w{=+uvRtXNgB>JEiAS~1dAS>}Njvq4rN;0KdL#@(wU;@PIn>d7+dXknH^7u(z z2){J{8n*vRyrNJq>e#md6cCFWt@~^RznFh@o{oLN{IT=Qz@j|PfBg&nda(1g`UREx z4WEC-cRuyA1S=6t0S?z>?)+ifqy5$V>s3^1bckoNR~JE(U-mE7n|Lss|3VTMAwgUT z<>)}-5n}_e2~UEUoEkr%?>62W@cA za{O?&=8Ut3W5)rJ2e-_-Eq1^737wIs*BU>oex54?j=85Y@cH+dKe7G}_=P7$AHT}{ z3$)8Q%(i6&=KYKX{OT>m5AUMe3HBM;9Go9Q+G|TRpDo$}$tuSWQL%v4K@VeMaIh_p zEqcriFwP}y>jM78ZI%cus+#t?Y#;>jJUYGxRWQNVTKVUa1+!!xH{0rA^=+h`mT3iSo_Snxo?ITs; z7jD#4X3-h99#@y}aI{n53mL!#NoO0KbbYOKp@aH8g!_A07y+rk&u~pEJ@#tbzG$ke zg#$0>MkB^$wH-iz%J{XEwnNFEozW<0c4%C$Vt@gDxyA*~BWh+QdXs1*2*vAHb^Vw$ zm#M-p+|~=YxzD~CMb{o+YnXx?rONnKFy3=Im_3T)i`3{ppyre?-j9HT*bnRCI0n2(iJAF#LK$RfZC%VVhm)WTtDx@ zi*%h~OZ=0&!_jNH-{phM7<-w24bqFWeIWLL`L2S0sIU)zr1&B!2&epSbra&)s?+#O z&xDE7K!(l-LI}S&iseHjiz0rw8m#`W&SmludQ1Q{smAl7y`sIz(Fkp{vqEV#nG_1H>KRwA`Qc0Blub2 zUpAIx@Pr5wPtTP37x`$_HSQn#Qe8#jLV6g7 z=Y9PGep!#;s;g)Z&KNR~q0d8=KKuAJc`InwET4Psae3^Gugf)-o`iD!Jl}?`yYV_7 z^5Xuy&JF_$W&X8Q@vk=I46fhMWgBn!hbXJ+H%^Pd6$xnRPY^8curNPo#SgE~i?`gD zsf}sZ%K&IC9P(|Q&VRvfMhVw__fw3w7IGyjRfKTJk8k7+$Ju4+ZT!CVH`veD_lkej zu{iAKG5C&dJq&CHzax3`u+t3`FcIS>IcVAA*0m9QueZ&i;^4e8Q@C z1Q|??U!IR&?$oDLe_iUC=v-_+PN`$a{IuR2VEzwX)%@q+ zDeYbi`tIu&_!oN)4rYEO%qg3=DPuCQnE`$=|H5@xW3h?;6IK8Lr|E^fHZtB)ZNvNU zy4|wP=^oe^oQEyY^WZ5sFH@-0Z@9E~aoY$g+(5g0(~Y2o-;p%zQhF{J*s`H#2kL1kz0F z)#bf)$AIRN`@{STr82`6!61m~Aa`1N&-upBl7 z?P?w$91}OtK6NWjgjMj1Ikon+;2Rg+VmIzqRXdDx>o+=8EYmVU_qynY8(m4q-GXY! zRPakj3)6o&X#V6Q6Z8blQhe#F)k#s$4B;2s%-H=cm(xMj-n(L>4!E_;^=I*~)D8A# zl+E{f30#zPK`SbP60$xgs`Fo&WG-^4K>iChyq1G$EwXzg%)b}{@Sau+rP>mpFjcpy zI}*M>3Lz%2i58az5l!9z!I}V~#m>4vD&WiS8H;4x5u+BL2m=Jsf|_jhk)Z1_b>T3`{WG7 ztb8Iik9~&+qS_?SfNVd=Up7Haf9is__d)gz^zvfr#ajuK6kXBE>e@8DNvv z3;+H@_eC6ykI@d5ny9;q4}#$>u;FF=()EXgT3N@~X@A2zE* zqn_6EfvoOOq7J-5ydu|249%8f_SwCR9aH!hJ&Y9QITD35f z+Ec+VZ8Poo_9;KJP)I)lAls5VneW&ZAB3Z*v5D&s5iKNC<#i}r4>%S(*?)qbH#%jk z7(V}ndK+)0b-=hx9dT(TZ%Fuuu!j}=N&&XE@YP9dJQE{>`P!mH(UFCyTG3xqpMSZF zZAu_qW4UCf!BhHGn|DR!{(0oTP~|1T)_whA{tnMY^Y=1-ai15dc&|Pl^|*IQ59)i* z=3hsVjJn2MKitw`oym5xzp()M!8v*O8x{N#<*=cqT?GW()=2~atLo<;q-|=OGb6@@ z91OKK^~=0UqJG2IFV24- zZp7lY03AZ{LzK;DW9k0GQqwN(&r|46sw#eXf?x)v`Ne=HN5Ly?od_GL)#KV$Q^YpG z`8fB&psd9om!6+8|3Y;Z;p|Bd)QS_$2!}S=tMgYW09hHo?i2s0nv2MP1!Wt2{tG~s zN1x05>qQr1cMvj#ZQ(U7L=uU0Vk@s{nSZULx2SzngWHm{P6^GwuAxJybV`NzR}tas zC&6W)O(p&%&*opu0@`Igmsxk%B3_*X!w5QajZL18woJF(^D4FCLct&b@+T#k~Kw>wwzxHQeN=%7pkILr$F zf^YsPe+v#U)2_9VM0POW;)eOx2}C$sWO4-YL(RW>vQyo=+~#HI{DBI7{XJbS>qa8C z`D1s0%l8N%8pdA1uY-m3Z3thN`*Rt3xSjh`;a|9kPIomJ7w}63yfTDehcj0bU@KFa zA2zT%fcO>svMD>5*kX@DWq@DIzmm?k>B!YyNCk#GXGMD1YlgH zQZ5L3Lwd79{Of&jSUsFszH&;3t;^VsAdvWi+Tn)z*Zt5hXj56geotH^H_+A89pYaF zT2F|9beH-pg+l|>oI#(<_~qIC-K|ILc_sZK-1n{s!Ql}9dWfEN(_U=;gT5aQJ2uOG zmeMK};$NI|dBOs0X&{5mxzhdJR{E|3pmsmW* zug!oxED9dQm0q$C!Y_wy_#l_wX`AUl;Hn1L%rbtZ#DlQv(9^(fIH(!ury0~;#lLh} zlwZFAJ5MGoG9y}{Qa?Wew)Lb3s~*^SKiP^Cvg6_W*BP}4)CA|UvD};hZL~JHa}F<` z5aUAYpsqh0XlrKv#pl03#6-g0kZTzRevOmHchn!UiL3Y$+Nl6G9l=_J>NjxqEvs*O z984yb*lJ^|#MnK%&=~M9OV=MRq?l!r2f8#DL@Yti3SIYJUB98?2h8J*XVjAq%tD2@ zV3HNauZMUA-;V8E@^hN-P=LCxzb*MxqvqW&SuWv6-+u^pY!|Y);8B5J%ohy=N878f z!Y>|I(#EbUP@a;sj6{FF)x)>~{POD$XSw!r@z1o&YaX||!N2}SU0ST;>Ili-^7CH{ zrLI53#a}Gg>M3Kc$N0r92=#}$&)9yv4-E{54`1`Y9fKz$zWwp*4;M;%z8S+o?~Z(I zw*bDo9fxuLE2y6@)gLBt?Yz+cK2a}}Xmw-iP^4FE_uo^gKfGZ&U~5(}IZ=D3wYo5~ z2>f!%<^BZczg}vZgK6m>P7T>}?_Pm@hyxv5hp*Qi^&8G9f_FM*ew3c?hI{#1^b1+! z<5VnPeSfcxyuIq_K*xZYchANzZ7RD^Z8)k9dhMBp&E}{)>0-u0_~n~rd!u-o`PWU+ z`x-}c93-sIh44$8Zu|>4uRCj&CYFMKaUk(CGK^mqU<-Lz&?T{k@-phwB9NF&Evu`- zFYY0%aS={ey8+_>TjzG1b^ivgP?obskkWdO9gkjm3Ev9im!JRYkd))=Ni}{g9;J^$ zPg5girG7)h7P3OFk6#LAd7lNFP>vt^^@ljKHUda0Uw-unxjc%h`i+^g>HDB&r9k53 z$Jt}7!Y_2A%f8=i&FrC$8{%I>U*KfmN9{M50pY-J zldoTVe-!LkK91TR+U=n>Ly4Oa2iW1&!?7>vGKRxj3)ddfyApN-f^`x?Lm9t<{Fg#m zCJ1J}^EL34C*Ak^wu2#->Nk{Me<-gX5U;lGw%g{h;O=;U?Q==LRE>tMp6Jf5V@l)K zqX;BE=DPdWavRBZBglXCT~ESu;P6qDx)4Z2+~$HZe);(?^cl2^IFafLz|%JL+3ex> zl>hyd-V%NxeXbKL^=IK%XAtI9T3A5Os5$(k!oMiUb_HoKuK9nN=6TiUm$i$Y_V*z# z!8RoCbWk_Mzk-nIG15X>eB1q7x(trJsE!{7Hk_~)1#>O@c^&u-)o+wTxPh<=OjE~l z%lzvh8DzWk;_`dm4A;z*dwbw!JW`J3;)E*dNyZ}~{Q5YDHU0%vC|bWT zE>J4mD!}*Kl=)Yg!W^X_?e#K!Pd)G&*iDFk1=+4r*}OSM2QV%GSvmi;k6ojo_}k_6 z0-eN7`yTE~8L7>1pG)=g7*2UyDLp?JSDAnL@xv(6UM2p;Nn{;+FY_-yeyG!4L7y*h z?^ex>UuFJP9&#WQ1pYw*tZ6dDzxcG5rd?wt;Tn1dRtor4&VOky7h9Ae0H6?8(UJgb zqj9kG?^nVrD*OCg$f50ODgR{!v?7OagwAb&TLFL)J@E7@{LBAUs7(!GAo(i(#rPGZ zkOBb(55R)RIrtUovq|#0ACF zz7%*-;a@&%c^E~Be<3;E;#Tm>uJQk=j%ben)Nekp1c`{^f7u@_zmt?s8u(n{(Cti}PQIA0937FT|0Mz{2^jGXHvr?L3=; zKzH)c!Qe?beu&#&Rc8j*Zs^2H5yGSNoSNgNLiw++fGy8d(M(Cd{C`O9YC?a4oD|XK zlA96epv0LqtVITxTjpOwgri0(C~rV~14#XhS$<9^wpUq25sh|cm88871(J-yiMm9IEgTlM?3@LLd!;E6YzRgmcEr8RdLpOk;- zOdARbq@Q@RHCB=m2A@=Hw5{wpf^zk1NRg4Do9H7{qsl@}=}FM$>F%1(8lO~u=uR6h z3)W}pB0QN~`qtBuGSo!1WT=o}_)kiG?zXtH5H}hOmITFTarucVwOLlv)z_21F*z+# z5`-c9dI~qDrcr5JG2;{T``)xP{vl>9^g{SUlHTOBCClR?iSU(025Dg_88$kGs#T)J zL7S&Dh^NB#E93*qLej`mv$7Wl-+EfsWQ;$eKcH#K7vwZG={BQVKPmNDni-r8;*+%{ zVbI7R{=`p8ZMv*wv$^8R+TDBzgTN%&hC#p2AuCvC?6OiuHGZE@@rmxAp&YqmL z%EH{fI`_Kn$>lbgnwyM2plj7MU-*4BIb$>#T?9dv)~nW7ta>t2n`)|r8~F(Zea5&* zNz{8;A;D6MU8mbBwR!qF^Y_$CnX8)W!$RLCep33@)7RD9(f7&BA2v;UrYuYfo_N7p zTzj2)hk7M*byNK_Wx?Pl^O`R9Ci`=E?Rnlab+(FSmNZTCCj0tD;vBWg8olZ!ULEDX zhN#xKS>2TRNK?(-TBwCkbF=EklW7X;%0Ji2nqK3R^gA@o)50fcDu*?e(;wnV@U3gR zD5IL(S{vJw1-)T2eZ)^xsn1=Oixup`C2?BN3+MJZ{G`&R2HND_XipO?q<=p)t&8OT zsd!RDrE!@?k9T8wTC8SCNKiMr)9f0ldyN0s)J2X~Ulv%=Y*sXWQfhK-mmsBF7nfPE zkarO=5!9!jl)iFT^29trHD&KPPW&w@G_Jz~qQjS_NNBT+7$Xw5~O#NiF=oF4m9Af|h32#k!SMJ=)^Ur5aoO$nDq1@&_Bcy&5o%htw3OjCR;lOiYq5Rk9EL{G=lwS@Vep?H3 z!a}*tHFtje$M@|T{n<$tHeNk?&&g|6bw4xZ;n8ECFSjv7ue{&6+^XAumT*y>S88O1 z;P@rA1ON~HY|z$=`p%0aD2{tO5c)Jk1>_5rOD?CUH-Sasg@Qi zCu21k=L-I7s2dn}E-nX8f;JL(dLCT%ky-|rVq9n4(RWeicbXGV5la`7CY zv^TI`Rk&ORXvSs#Jre6xh0A4tW?T;1U>`~#^-_DXI7gt;xJ>HtrlxCR#*%Xc8NBB# zTrLB22$!+vt8lpt&@7a`Wyo{Ys{ADQ)(7dA3ff=}=Nk>QL^;KCgkTPP2%0aEJ;m*- z=LlZ#9;%_)GS*{GrKisk4wSyN#LDb%N?#Y740rb|K?QSYNQUEzIjOcZ`bE;{W;kXP z*0@|HsM5FO(w@mvfyKUa{Y zadn>q0cB9|f)^3PabpRWtAxd+CLby;SHp1$p#N9-Tj#=Y>B)QLHdVM>252pm+XSg> zgt~N2yNiX`!$@vN0@UG_6{Nv_qs8pAIuIC*%0EaZ)1XW^NJm0IYSSJ{76=7*(pMFwqQ$@T21AiH8Ke)O7DSU}|e(WIY9tchR1ef9ZjckV| zrH#Y%S14sG2_uu{;>lvV=zu@6^S)=PJNYmduVsUeoo7^ylD=#qxmB7Uv^-~?9hGXf zZE094cu&c|27l!Lb1A9+6oXCF!g>Bv8guDa3m2B8%KxVozR$ZS9_?bVV}^X@JGoJW_>dCxg}%q~Ci-*Y|DP-*~>CSm| zIe1gKO+|&zQR;G=^XYQn$CcZhPnQGjF10z2E|-=1gLJuMC4%?Rd2|`S^5>_#6qWfZ zPh43D8l6X%D}Vjp*X2qZUpk*Im)m@RE|=SU=)(E*^#7&~epvnak0&aPJ1Tgaq^av; z|8eWzwD`>o{ALDzGXuYwf#1x)Z)V^(Gw}bv8PNU`947cn^1P!*iL@89%dw;Lw)syy z#A{57Q9AaYX!}7;gdwwPY9*HSL2W Date: Sat, 22 Feb 2020 13:37:48 +0000 Subject: [PATCH 1583/1854] Mention shebang changes and python script porting in CHANGELOG.md Documents changes from issues 560 and 564, and pull requests 561, 563, and 565. --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a36b58da..af8b073ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,9 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Ported all python 2 scripts to python 3 (@doegox and @sigwinch28) + - Removed undefined exit behaviour from `analyzesize` tool: it now exits with code 2 when called with wrong args (@sigwinch28) + - Replaced shebangs in scripts with more portable versions which use `/usr/bin/env` (@sigwinch28) - Added `hf lto restore` - restore LTO cartridge memory from dump file [.bin|.eml] (@Kevin-Nakamoto) - Added `LF_ICEHID` standalone mode which searches for lf HID credentials and store to RDV4 flashmem (@iceman1001) - Added `HF_14ASNIFF` standalone mode with storing trace to RDV4 flashmem (@micolous) From d0241ed24f4c5f704973867d00fac583227995df Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 22 Feb 2020 19:59:54 +0100 Subject: [PATCH 1584/1854] does this solve opensuse warning? --- armsrc/appmain.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 15d939a35..415e03291 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -726,7 +726,10 @@ static void PacketReceived(PacketCommandNG *packet) { break; } case CMD_LF_SAMPLING_SET_CONFIG: { - setSamplingConfig((sample_config *) packet->data.asBytes); + sample_config c; + memcpy(&c, packet->data.asBytes, sizeof(sample_config)); + setSamplingConfig(&c); +// setSamplingConfig((sample_config *) packet->data.asBytes); break; } case CMD_LF_ACQ_RAW_ADC: { From f2ae1ff57abf9eea3a867988921db5a097d4196a Mon Sep 17 00:00:00 2001 From: mwalker33 Date: Sun, 23 Feb 2020 11:21:55 +1100 Subject: [PATCH 1585/1854] Update cmdlfkeri.c --- client/cmdlfkeri.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/client/cmdlfkeri.c b/client/cmdlfkeri.c index 892dfaf5f..b0f45da04 100644 --- a/client/cmdlfkeri.c +++ b/client/cmdlfkeri.c @@ -104,6 +104,7 @@ static int CmdKeriMSScramble (KeriMSScramble_t Action, uint32_t *FC, uint32_t *I if (FCDecodeState[31- 1] == '1') FCDecodeState[31- 1] = '?'; if (FCDecodeState[31- 2] == '1') FCDecodeState[31- 2] = '?'; + PrintAndLogEx(SUCCESS, "Partial Keri MS decode"); PrintAndLogEx(SUCCESS, "BitState ID : %s",IDDecodeState); PrintAndLogEx(SUCCESS, "BitState FC : %s",FCDecodeState); } @@ -210,8 +211,12 @@ static int CmdKeriDemod(const char *Cmd) { PrintAndLogEx (SUCCESS,"Descrambled MS : FC %d - Card ID %d\n",fc,cardid); +/* + Scamble: For dev testing only, will/should move to the create keri-ms code when added. + uint32_t testCard = 0; CmdKeriMSScramble (Scramble,&fc,&cardid,&testCard); +*/ // End Descramble test From 8b10107c405cd1236d6ca3eefa94dd31b54526a6 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 23 Feb 2020 10:28:51 +0100 Subject: [PATCH 1586/1854] fix: #520 - calling init before initialize mutexs is bad --- client/cmdhfmfhard.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/cmdhfmfhard.c b/client/cmdhfmfhard.c index d83c60047..f9e68ca67 100644 --- a/client/cmdhfmfhard.c +++ b/client/cmdhfmfhard.c @@ -2019,12 +2019,12 @@ __attribute__((force_align_arg_pointer)) static void generate_candidates(uint8_t sum_a0_idx, uint8_t sum_a8_idx) { - init_statelist_cache(); - init_book_of_work(); - // create mutexes for accessing the statelist cache and our "book of work" pthread_mutex_init(&statelist_cache_mutex, NULL); pthread_mutex_init(&book_of_work_mutex, NULL); + + init_statelist_cache(); + init_book_of_work(); // create and run worker threads pthread_t thread_id[NUM_REDUCTION_WORKING_THREADS]; From cfcb0494590d8dbe611e9e1eaf60f52495fd69de Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 23 Feb 2020 10:45:23 +0100 Subject: [PATCH 1587/1854] chg: hitag2 now obeys 'lf conf' divisor setting --- armsrc/lfadc.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/armsrc/lfadc.c b/armsrc/lfadc.c index 6b0eb930a..63b246025 100644 --- a/armsrc/lfadc.c +++ b/armsrc/lfadc.c @@ -69,11 +69,12 @@ size_t lf_count_edge_periods_ex(size_t max, bool wait, bool detect_gap) { size_t periods = 0; volatile uint8_t adc_val; uint8_t avg_peak = adc_avg + 3, avg_through = adc_avg - 3; - int16_t checked = 0; +// int16_t checked = 0; while (!BUTTON_PRESS()) { // only every 100th times, in order to save time when collecting samples. +/* if (checked == 1000) { if (data_available()) { break; @@ -82,7 +83,7 @@ size_t lf_count_edge_periods_ex(size_t max, bool wait, bool detect_gap) { } } ++checked; - +*/ WDT_HIT(); if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { @@ -164,7 +165,11 @@ void lf_init(bool reader, bool simulate) { FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, LF_DIVISOR_134); + sample_config *sc = getSamplingConfig(); + sc->decimation = 1; + sc->averaging = 0; + + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, sc->divisor); if (reader) { FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); } else { @@ -217,10 +222,6 @@ void lf_init(bool reader, bool simulate) { // use malloc if (logging) initSampleBufferEx(&bufsize, true); - sample_config *sc = getSamplingConfig(); - sc->decimation = 1; - sc->averaging = 0; - lf_sample_mean(); } @@ -237,20 +238,16 @@ void lf_finalize() { LEDsoff(); - sample_config *sc = getSamplingConfig(); - sc->decimation = 1; - sc->averaging = 0; - StartTicks(); } size_t lf_detect_field_drop(size_t max) { size_t periods = 0; - volatile uint8_t adc_val; - int16_t checked = 0; +// int16_t checked = 0; while (!BUTTON_PRESS()) { +/* // only every 1000th times, in order to save time when collecting samples. if (checked == 1000) { if (data_available()) { @@ -261,12 +258,13 @@ size_t lf_detect_field_drop(size_t max) { } } ++checked; +*/ WDT_HIT(); if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { periods++; - adc_val = AT91C_BASE_SSC->SSC_RHR; + volatile uint8_t adc_val = AT91C_BASE_SSC->SSC_RHR; if (logging) logSampleSimple(adc_val); From d9e073410dc29e24fc644dc5f1d8da2af97255a0 Mon Sep 17 00:00:00 2001 From: h4waii <30473690+h4waii@users.noreply.github.com> Date: Mon, 24 Feb 2020 00:04:06 +1100 Subject: [PATCH 1588/1854] fix: #520 - free mutex after work is done Why not just free after key found or not found? --- client/cmdhfmfhard.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/client/cmdhfmfhard.c b/client/cmdhfmfhard.c index f9e68ca67..32afd8cf2 100644 --- a/client/cmdhfmfhard.c +++ b/client/cmdhfmfhard.c @@ -1845,14 +1845,15 @@ static bool TestIfKeyExists(uint64_t key) { num_keys_tested += count; hardnested_print_progress(num_acquired_nonces, "(Test: Key found)", 0.0, 0); crypto1_destroy(pcs); + pthread_mutex_destroy(&statelist_cache_mutex); return true; } } num_keys_tested += count; hardnested_print_progress(num_acquired_nonces, "(Test: Key NOT found)", 0.0, 0); - crypto1_destroy(pcs); + pthread_mutex_destroy(&statelist_cache_mutex); return false; } @@ -2042,9 +2043,6 @@ static void generate_candidates(uint8_t sum_a0_idx, uint8_t sum_a8_idx) { pthread_join(thread_id[i], NULL); } - // clean up mutex - pthread_mutex_destroy(&statelist_cache_mutex); - maximum_states = 0; for (statelist_t *sl = candidates; sl != NULL; sl = sl->next) { maximum_states += (uint64_t)sl->len[ODD_STATE] * sl->len[EVEN_STATE]; From 87cbe12773eaa4e9468492e30c92c9ba61355af1 Mon Sep 17 00:00:00 2001 From: h4waii <30473690+h4waii@users.noreply.github.com> Date: Mon, 24 Feb 2020 09:23:22 +1100 Subject: [PATCH 1589/1854] Update termux_notes.md --- doc/termux_notes.md | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/doc/termux_notes.md b/doc/termux_notes.md index d86ec7f08..6b3eb132c 100644 --- a/doc/termux_notes.md +++ b/doc/termux_notes.md @@ -27,17 +27,38 @@ ref : https://github.com/Proxmark/proxmark3/wiki/android - [LineageOS (Android 8.1)](https://download.lineageos.org/) - [LineageOS kernel](https://download.lineageos.org/) - [Magisk 19.3](https://github.com/topjohnwu/Magisk/) + +- Xiaomi Mi Mix 2S (arm64, USB-C) + - [LineageOS (Android 9.0)](https://download.lineageos.org/) + - [Magisk 20.3](https://github.com/topjohnwu/Magisk/) + +- OnePlus 5T (arm64, USB-C) + - [LineageOS (Android 9.0)](https://download.lineageos.org/) + - [Franko Kernel](https://franco-lnx.net/) + - [Magisk 20.3](https://github.com/topjohnwu/Magisk/) + +- Samsung Galaxy Tab S2 (arm64, MicroUSB) + - [LineageOS (Android 9.0)](https://download.lineageos.org/) + - [LineageOS kernel](https://download.lineageos.org/) + - [Magisk 20.3](https://github.com/topjohnwu/Magisk/) + + ## Setup ### Setting up Termux -1. Install [Termux](https://play.google.com/store/apps/details?id=com.termux) and start it -2. Run the following commands: +Install [Termux](https://play.google.com/store/apps/details?id=com.termux) and start it +### Install Proxmark3 package +Run the following commands: +``` +pkg install proxmark3 tsu +``` +### Optional: Building Proxmark3 client from source ``` pkg install make clang clang++ readline libc++ git tsu git clone https://github.com/RfidResearchGroup/proxmark3.git +cd proxmark +make clean && make client ``` -### Building Proxmark3 client -1. `make clean && make client` ### USB_ACM You need the `USB_ACM` driver enabled and working to communicate with the Proxmark3. To see if it's working, run `tsudo ls /dev/tty*` and it should list `/dev/ttyACM0` (or similar). If you see this, congratulations, skip this step! From b05042d8963cce38fa747e9d483e666700072648 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 24 Feb 2020 09:44:48 +0100 Subject: [PATCH 1590/1854] textual --- client/cmdhf.c | 16 ++++++++++++---- client/cmdlf.c | 18 ++++++++++++------ 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/client/cmdhf.c b/client/cmdhf.c index 78ebbd256..35b50b852 100644 --- a/client/cmdhf.c +++ b/client/cmdhf.c @@ -178,32 +178,40 @@ int CmdHFTune(const char *Cmd) { if (cmdp == 'h') return usage_hf_tune(); int iter = param_get32ex(Cmd, 0, 0, 10); + PrintAndLogEx(SUCCESS, "Measuring HF antenna, click " _GREEN_("pm3 button") "or press " _GREEN_("Enter") "to exit"); PacketResponseNG resp; - PrintAndLogEx(SUCCESS, "Measuring HF antenna, " _YELLOW_("click button") " or press " _YELLOW_("Enter") "to exit"); clearCommandBuffer(); + uint8_t mode[] = {1}; SendCommandNG(CMD_MEASURE_ANTENNA_TUNING_HF, mode, sizeof(mode)); if (!WaitForResponseTimeout(CMD_MEASURE_ANTENNA_TUNING_HF, &resp, 1000)) { PrintAndLogEx(WARNING, "Timeout while waiting for Proxmark HF initialization, aborting"); return PM3_ETIMEOUT; } + mode[0] = 2; // loop forever (till button pressed) if iter = 0 (default) for (uint8_t i = 0; iter == 0 || i < iter; i++) { - if (kbd_enter_pressed()) { // abort by keyboard press + if (kbd_enter_pressed()) { break; } + SendCommandNG(CMD_MEASURE_ANTENNA_TUNING_HF, mode, sizeof(mode)); if (!WaitForResponseTimeout(CMD_MEASURE_ANTENNA_TUNING_HF, &resp, 1000)) { + PrintAndLogEx(NORMAL, ""); PrintAndLogEx(WARNING, "Timeout while waiting for Proxmark HF measure, aborting"); return PM3_ETIMEOUT; } - if ((resp.status == PM3_EOPABORTED) || (resp.length != sizeof(uint16_t))) + + if ((resp.status == PM3_EOPABORTED) || (resp.length != sizeof(uint16_t))) { break; + } + uint16_t volt = resp.data.asDwords[0] & 0xFFFF; - PrintAndLogEx(INPLACE, "%u mV / %5u V", volt, (uint16_t)(volt / 1000)); + PrintAndLogEx(INPLACE, "%u mV / %2u V", volt, (uint16_t)(volt / 1000)); } mode[0] = 3; + SendCommandNG(CMD_MEASURE_ANTENNA_TUNING_HF, mode, sizeof(mode)); if (!WaitForResponseTimeout(CMD_MEASURE_ANTENNA_TUNING_HF, &resp, 1000)) { PrintAndLogEx(WARNING, "Timeout while waiting for Proxmark HF shutdown, aborting"); diff --git a/client/cmdlf.c b/client/cmdlf.c index 617d87c0e..b83ed0c89 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -253,34 +253,41 @@ static int CmdLFTune(const char *Cmd) { //Validations if (errors) return usage_lf_tune(); - PrintAndLogEx(SUCCESS, "Measuring LF antenna at %.2f kHz, click button or press Enter to exit", LF_DIV2FREQ(divisor)); + PrintAndLogEx(SUCCESS, "Measuring LF antenna at " _YELLOW_("%.2f") "kHz, click " _GREEN_("pm3 button") "or press " _GREEN_("Enter") "to exit", LF_DIV2FREQ(divisor)); uint8_t params[] = {1, 0}; params[1] = divisor; PacketResponseNG resp; - clearCommandBuffer(); + SendCommandNG(CMD_MEASURE_ANTENNA_TUNING_LF, params, sizeof(params)); if (!WaitForResponseTimeout(CMD_MEASURE_ANTENNA_TUNING_LF, &resp, 1000)) { PrintAndLogEx(WARNING, "Timeout while waiting for Proxmark LF initialization, aborting"); return PM3_ETIMEOUT; } + params[0] = 2; // loop forever (till button pressed) if iter = 0 (default) for (uint8_t i = 0; iter == 0 || i < iter; i++) { - if (kbd_enter_pressed()) { // abort by keyboard press + if (kbd_enter_pressed()) { break; } + SendCommandNG(CMD_MEASURE_ANTENNA_TUNING_LF, params, sizeof(params)); if (!WaitForResponseTimeout(CMD_MEASURE_ANTENNA_TUNING_LF, &resp, 1000)) { + PrintAndLogEx(NORMAL, ""); PrintAndLogEx(WARNING, "Timeout while waiting for Proxmark LF measure, aborting"); return PM3_ETIMEOUT; } - if ((resp.status == PM3_EOPABORTED) || (resp.length != sizeof(uint32_t))) + + if ((resp.status == PM3_EOPABORTED) || (resp.length != sizeof(uint32_t))) { break; + } + uint32_t volt = resp.data.asDwords[0]; - PrintAndLogEx(INPLACE, "%u mV / %5u V", volt, (uint32_t)(volt / 1000)); + PrintAndLogEx(INPLACE, "%u mV / %3u V", volt, (uint32_t)(volt / 1000)); } + params[0] = 3; SendCommandNG(CMD_MEASURE_ANTENNA_TUNING_LF, params, sizeof(params)); if (!WaitForResponseTimeout(CMD_MEASURE_ANTENNA_TUNING_LF, &resp, 1000)) { @@ -292,7 +299,6 @@ static int CmdLFTune(const char *Cmd) { return PM3_SUCCESS; } - /* send a LF command before reading */ int CmdLFCommandRead(const char *Cmd) { From 11f50ef7bc4ecd7d4f8c0c6d25f5e9459954b366 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 24 Feb 2020 09:45:56 +0100 Subject: [PATCH 1591/1854] chg: textual and remove adjustment for antenna measures --- client/cmddata.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/client/cmddata.c b/client/cmddata.c index 613ce11e5..14f8ac259 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -1662,16 +1662,15 @@ int CmdTuneSamples(const char *Cmd) { #define LF_MARGINAL_V 10000 #define HF_UNUSABLE_V 3000 #define HF_MARGINAL_V 5000 -#define ANTENNA_ERROR 1.03 // current algo has 3% error margin. +#define ANTENNA_ERROR 1.00 // current algo has 3% error margin. // hide demod plot line DemodBufferLen = 0; setClockGrid(0, 0); RepaintGraphWindow(); - int timeout = 0; - PrintAndLogEx(INFO, "\nMeasuring antenna characteristics, please wait..."); + PrintAndLogEx(INFO, "Measuring antenna characteristics, please wait..."); clearCommandBuffer(); SendCommandNG(CMD_MEASURE_ANTENNA_TUNING, NULL, 0); @@ -1691,7 +1690,7 @@ int CmdTuneSamples(const char *Cmd) { return PM3_ESOFT; } - PrintAndLogEx(NORMAL, "\n"); + PrintAndLogEx(NORMAL, ""); // in mVolt struct p { uint32_t v_lf134; From 7750fe24e19af2d83581a06e31c53d129eda49c1 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 24 Feb 2020 14:33:01 -0500 Subject: [PATCH 1592/1854] timeout --- armsrc/mifarecmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 9e9c721bd..b869489ab 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -2229,7 +2229,7 @@ void MifareHasStaticNonce() { nt = bytes_to_num(rec, 4); -// CHK_TIMEOUT(); + CHK_TIMEOUT(); } OUT: From 743325e90f5f492cd395a26e66855b298b864a1c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 24 Feb 2020 20:39:12 +0100 Subject: [PATCH 1593/1854] chg: make it slower --- armsrc/mifarecmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 9e9c721bd..b869489ab 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -2229,7 +2229,7 @@ void MifareHasStaticNonce() { nt = bytes_to_num(rec, 4); -// CHK_TIMEOUT(); + CHK_TIMEOUT(); } OUT: From 17dd4bc57217d9046f14166b411766b98e52151d Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 24 Feb 2020 20:39:32 +0100 Subject: [PATCH 1594/1854] revert #520 --- client/cmdhfmfhard.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/client/cmdhfmfhard.c b/client/cmdhfmfhard.c index 32afd8cf2..90f686b80 100644 --- a/client/cmdhfmfhard.c +++ b/client/cmdhfmfhard.c @@ -1845,7 +1845,6 @@ static bool TestIfKeyExists(uint64_t key) { num_keys_tested += count; hardnested_print_progress(num_acquired_nonces, "(Test: Key found)", 0.0, 0); crypto1_destroy(pcs); - pthread_mutex_destroy(&statelist_cache_mutex); return true; } } @@ -1853,7 +1852,6 @@ static bool TestIfKeyExists(uint64_t key) { num_keys_tested += count; hardnested_print_progress(num_acquired_nonces, "(Test: Key NOT found)", 0.0, 0); crypto1_destroy(pcs); - pthread_mutex_destroy(&statelist_cache_mutex); return false; } From b87b0313dad220c0c26d3a499e58bdf4b54ea2e4 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 24 Feb 2020 20:39:53 +0100 Subject: [PATCH 1595/1854] chg: tighter detection of static nonce --- client/cmdhfmf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index c8ee0013c..24296b31d 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -1279,7 +1279,7 @@ static int CmdHF14AMfNested(const char *Cmd) { } // check if tag doesn't have static nonce - if (detect_classic_static_nonce() != 0) { + if (detect_classic_static_nonce() == 1) { PrintAndLogEx(WARNING, "Static nonce detected. Quitting..."); PrintAndLogEx(INFO, "\t Try use " _YELLOW_("`hf mf staticnested`")); return PM3_EOPABORTED; @@ -1839,7 +1839,7 @@ static int CmdHF14AMfNestedHard(const char *Cmd) { if (!know_target_key && nonce_file_read == false) { // check if tag doesn't have static nonce - if (detect_classic_static_nonce() != 0) { + if (detect_classic_static_nonce() == 1) { PrintAndLogEx(WARNING, "Static nonce detected. Quitting..."); PrintAndLogEx(INFO, "\t Try use `" _YELLOW_("hf mf staticnested") "`"); return PM3_EOPABORTED; From 2f2443c7fa3c493453dd5f86d5b70a4bd3368ec5 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 24 Feb 2020 21:31:58 +0100 Subject: [PATCH 1596/1854] text --- client/proxmark3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/proxmark3.c b/client/proxmark3.c index d582bafc0..522d982c7 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -61,7 +61,7 @@ static int check_comm(void) { rl_set_prompt(PROXPROMPT_OFFLINE); rl_forced_update_display(); CloseProxmark(); - PrintAndLogEx(INFO, "Running in " _YELLOW_("OFFLINE") "mode. Use \"hw connect\" to reconnect\n"); + PrintAndLogEx(INFO, "Running in " _YELLOW_("OFFLINE") "mode. Use "_YELLOW_("\"hw connect\"") "to reconnect\n"); } return 0; } From 52452c8ddeb0afe94a43e3ef325436833553710b Mon Sep 17 00:00:00 2001 From: Iceman Date: Tue, 25 Feb 2020 15:37:27 +0100 Subject: [PATCH 1597/1854] Update Linux-Installation-Instructions.md --- .../Linux-Installation-Instructions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/md/Installation_Instructions/Linux-Installation-Instructions.md b/doc/md/Installation_Instructions/Linux-Installation-Instructions.md index 30d4fbf54..b381eb7d9 100644 --- a/doc/md/Installation_Instructions/Linux-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Linux-Installation-Instructions.md @@ -51,7 +51,7 @@ If you don't need the graphical components of the Proxmark3 client (such as in ` ## On openSUSE ```sh -sudo zypper install git patterns-devel-base-devel_basis gcc-c++ readline-devel cross-arm-none-gcc9 cross-arm-none-newlib-devel +sudo zypper install git patterns-devel-base-devel_basis gcc-c++ readline-devel cross-arm-none-gcc9 cross-arm-none-newlib-devel libqt5-qtbase-devel ``` If you don't need the graphical components of the Proxmark3 client (such as in `hw tune`), you can skip the installation of `libqt5-qtbase-devel`. From 33ba0c6f3676e2432ba0481a2d006b36a9eea392 Mon Sep 17 00:00:00 2001 From: bosb <12600404+bosb@users.noreply.github.com> Date: Tue, 25 Feb 2020 20:19:00 +0100 Subject: [PATCH 1598/1854] hitags fix uid sim + write --- armsrc/hitagS.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/armsrc/hitagS.c b/armsrc/hitagS.c index 40cdf47ed..68fa825e1 100644 --- a/armsrc/hitagS.c +++ b/armsrc/hitagS.c @@ -940,7 +940,7 @@ void SimulateHitagSTag(bool tag_mem_supplied, uint8_t *data) { memcpy((uint8_t *)tag.pages, data, 4 * 64); } - tag.uid = (uint32_t)tag.pages[0]; + tag.uid = (tag.pages[0][3] << 24 | tag.pages[0][2] << 16 | tag.pages[0][1] << 8 | tag.pages[0][0]); tag.key = (intptr_t)tag.pages[3]; tag.key <<= 16; tag.key += ((tag.pages[2][0]) << 8) + tag.pages[2][1]; @@ -1555,6 +1555,7 @@ void WritePageHitagS(hitag_function htf, hitag_data *htd, int page) { AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; // Capture mode, defaul timer source = MCK/2 (TIMER_CLOCK1), TIOA is external trigger, + AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK; // external trigger rising edge, load RA on falling edge of TIOA. AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK | AT91C_TC_ETRGEDG_FALLING From ab7bf0cb2ad9d8579959f25d05025eeddfd563bd Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 27 Feb 2020 14:26:28 +0100 Subject: [PATCH 1599/1854] fix: hf mf autopwn on debian... --- client/cmdhfmfhard.c | 53 +++++++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 20 deletions(-) diff --git a/client/cmdhfmfhard.c b/client/cmdhfmfhard.c index 90f686b80..beb85df5b 100644 --- a/client/cmdhfmfhard.c +++ b/client/cmdhfmfhard.c @@ -1390,7 +1390,6 @@ static int acquire_nonces(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_ char progress_text[80]; FILE *fnonces = NULL; PacketResponseNG resp; - num_acquired_nonces = 0; clearCommandBuffer(); @@ -1402,24 +1401,35 @@ static int acquire_nonces(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_ flags |= field_off ? 0x0004 : 0; clearCommandBuffer(); - SendCommandMIX(CMD_HF_MIFARE_ACQ_ENCRYPTED_NONCES, blockNo + keyType * 0x100, trgBlockNo + trgKeyType * 0x100, flags, key, 6); - if (field_off) break; + if (field_off) { + SendCommandNG(CMD_FPGA_MAJOR_MODE_OFF, NULL, 0); + break; + } else { + SendCommandMIX(CMD_HF_MIFARE_ACQ_ENCRYPTED_NONCES, blockNo + keyType * 0x100, trgBlockNo + trgKeyType * 0x100, flags, key, 6); + } if (initialize) { + if (!WaitForResponseTimeout(CMD_ACK, &resp, 3000)) { - uint8_t nullkey[6] = {0}; - //strange second call (iceman) clearCommandBuffer(); - SendCommandMIX(CMD_HF_MIFARE_ACQ_ENCRYPTED_NONCES, blockNo + keyType * 0x100, trgBlockNo + trgKeyType * 0x100, 4, nullkey, sizeof(nullkey)); + SendCommandNG(CMD_FPGA_MAJOR_MODE_OFF, NULL, 0); return 1; } - if (resp.oldarg[0]) return resp.oldarg[0]; // error during nested_hard + + // error during nested_hard + if (resp.oldarg[0]) { + clearCommandBuffer(); + SendCommandNG(CMD_FPGA_MAJOR_MODE_OFF, NULL, 0); + return resp.oldarg[0]; + } cuid = resp.oldarg[1]; if (nonce_file_write && fnonces == NULL) { if ((fnonces = fopen(filename, "wb")) == NULL) { PrintAndLogEx(WARNING, "Could not create file %s", filename); + clearCommandBuffer(); + SendCommandNG(CMD_FPGA_MAJOR_MODE_OFF, NULL, 0); return 3; } snprintf(progress_text, 80, "Writing acquired nonces to binary file %s", filename); @@ -1486,17 +1496,24 @@ static int acquire_nonces(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_ } if (!initialize) { + if (!WaitForResponseTimeout(CMD_ACK, &resp, 3000)) { if (nonce_file_write) { fclose(fnonces); } + clearCommandBuffer(); + SendCommandNG(CMD_FPGA_MAJOR_MODE_OFF, NULL, 0); return 1; } + + // error during nested_hard if (resp.oldarg[0]) { if (nonce_file_write) { fclose(fnonces); } - return resp.oldarg[0]; // error during nested_hard + clearCommandBuffer(); + SendCommandNG(CMD_FPGA_MAJOR_MODE_OFF, NULL, 0); + return resp.oldarg[0]; } } @@ -1513,11 +1530,6 @@ static int acquire_nonces(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_ fclose(fnonces); } - // PrintAndLogEx(NORMAL, "Sampled a total of %d nonces in %d seconds (%0.0f nonces/minute)", - // total_num_nonces, - // time(NULL)-time1, - // (float)total_num_nonces*60.0/(time(NULL)-time1)); - return 0; } @@ -1681,11 +1693,12 @@ static bool all_bitflips_match(uint8_t byte, uint32_t state, odd_even_t odd_even for (uint8_t remaining_bits = 0; remaining_bits <= (~mask & 0xff); remaining_bits++) { if (remaining_bits_match(num_common, bytes_diff, state, (state & mask) | remaining_bits, odd_even)) { -#ifdef DEBUG_KEY_ELIMINATION - if (bitflips_match(byte2, (state & mask) | remaining_bits, odd_even, true)) { -#else - if (bitflips_match(byte2, (state & mask) | remaining_bits, odd_even)) { -#endif +# ifdef DEBUG_KEY_ELIMINATION + if (bitflips_match(byte2, (state & mask) | remaining_bits, odd_even, true)) +# else + if (bitflips_match(byte2, (state & mask) | remaining_bits, odd_even)) +# endif + { found_match = true; break; } @@ -1694,7 +1707,7 @@ static bool all_bitflips_match(uint8_t byte, uint32_t state, odd_even_t odd_even if (!found_match) { -#ifdef DEBUG_KEY_ELIMINATION +# ifdef DEBUG_KEY_ELIMINATION if (known_target_key != -1 && state == test_state[odd_even]) { PrintAndLogEx(NORMAL, "all_bitflips_match() 1st Byte: %s test state (0x%06x): Eliminated. Bytes = %02x, %02x, Common Bits = %d\n", odd_even == ODD_STATE ? "odd" : "even", @@ -1706,7 +1719,7 @@ static bool all_bitflips_match(uint8_t byte, uint32_t state, odd_even_t odd_even sprintf(failstr, "Other 1st Byte %s, all_bitflips_match(), no match", odd_even ? "odd" : "even"); } } -#endif +# endif return false; } } From 2886a99350369dd3fbbe151c1a4a1fb63b131883 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 27 Feb 2020 16:35:17 +0100 Subject: [PATCH 1600/1854] add: cryptohelper support --- client/Makefile | 5 +- client/cmdhficlass.c | 172 +++++++++++++++++++++++------------------- client/cmdsmartcard.c | 54 +++++++------ client/cmdsmartcard.h | 2 +- client/emv/emvcore.c | 2 +- common/cardhelper.c | 83 ++++++++++++++++++++ common/cardhelper.h | 21 ++++++ 7 files changed, 231 insertions(+), 108 deletions(-) create mode 100644 common/cardhelper.c create mode 100644 common/cardhelper.h diff --git a/client/Makefile b/client/Makefile index 6e2ebd001..fae411a52 100644 --- a/client/Makefile +++ b/client/Makefile @@ -130,7 +130,7 @@ CORESRCS = uart_posix.c \ util_posix.c \ scandir.c \ crc16.c \ - comms.c + comms.c CMDSRCS = crapto1/crapto1.c \ crapto1/crypto1.c \ @@ -250,7 +250,8 @@ CMDSRCS = crapto1/crapto1.c \ bucketsort.c \ flash.c \ wiegand_formats.c \ - wiegand_formatutils.c + wiegand_formatutils.c \ + cardhelper.c cpu_arch = $(shell uname -m) ifneq ($(findstring 86, $(cpu_arch)), ) diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 567600d15..d69efd475 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -1,8 +1,8 @@ //----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- // Copyright (C) 2010 iZsh , Hagen Fritsch // Copyright (C) 2011 Gerhard de Koning Gans // Copyright (C) 2014 Midnitesnake & Andy Davies & Martin Holst Swende +// Copyright (C) 2020 Iceman // // This code is licensed to you under the terms of the GNU GPL, version 2 or, // at your option, any later version. See the LICENSE.txt file for the text of @@ -12,14 +12,11 @@ //----------------------------------------------------------------------------- #include "cmdhficlass.h" - #include - #include "cmdparser.h" // command_t #include "commonutil.h" // ARRAYLEN #include "cmdtrace.h" #include "util_posix.h" - #include "comms.h" #include "mbedtls/des.h" #include "loclass/cipherutils.h" @@ -28,12 +25,14 @@ #include "loclass/elite_crack.h" #include "fileutils.h" #include "protocols.h" +#include "cardhelper.h" #include "wiegand_formats.h" #include "wiegand_formatutils.h" #define NUM_CSNS 9 #define ICLASS_KEYS_MAX 8 #define ICLASS_AUTH_RETRY 10 +#define ICLASS_DECRYPTION_BIN "iclass_decryptionkey.bin" static int CmdHelp(const char *Cmd); @@ -290,16 +289,6 @@ static int usage_hf_iclass_permutekey(void) { return PM3_SUCCESS; } -/* -static int xorbits_8(uint8_t val) { - uint8_t res = val ^ (val >> 1); //1st pass - res = res ^ (res >> 1); // 2nd pass - res = res ^ (res >> 2); // 3rd pass - res = res ^ (res >> 4); // 4th pass - return res & 1; -} -*/ - // iclass / picopass chip config structures and shared routines typedef struct { uint8_t app_limit; //[8] @@ -311,7 +300,6 @@ typedef struct { uint8_t fuses; //[15] } picopass_conf_block; - typedef struct { uint8_t csn[8]; picopass_conf_block conf; @@ -321,6 +309,13 @@ typedef struct { uint8_t app_issuer_area[8]; } picopass_hdr; +typedef enum { + None = 0, + DES, + RFU, + TRIPLEDES +} BLOCK79ENCRYPTION; + static uint8_t isset(uint8_t val, uint8_t mask) { return (val & mask); } @@ -429,18 +424,18 @@ static void mem_app_config(const picopass_hdr *hdr) { PrintAndLogEx(NORMAL, " Credit - Kc"); } } + static void print_picopass_info(const picopass_hdr *hdr) { fuse_config(hdr); mem_app_config(hdr); } + static void printIclassDumpInfo(uint8_t *iclass_dump) { print_picopass_info((picopass_hdr *) iclass_dump); } - static int CmdHFiClassList(const char *Cmd) { (void)Cmd; // Cmd is not used so far - //PrintAndLogEx(NORMAL, "Deprecated command, use 'hf list iclass' instead"); CmdTraceList("iclass"); return PM3_SUCCESS; } @@ -475,24 +470,9 @@ static int CmdHFiClassSim(const char *Cmd) { return usage_hf_iclass_sim(); } - /* - // pre-defined 8 CSN by Holiman - uint8_t csns[8*NUM_CSNS] = { - 0x00, 0x0B, 0x0F, 0xFF, 0xF7, 0xFF, 0x12, 0xE0, - 0x00, 0x13, 0x94, 0x7E, 0x76, 0xFF, 0x12, 0xE0, - 0x2A, 0x99, 0xAC, 0x79, 0xEC, 0xFF, 0x12, 0xE0, - 0x17, 0x12, 0x01, 0xFD, 0xF7, 0xFF, 0x12, 0xE0, - 0xCD, 0x56, 0x01, 0x7C, 0x6F, 0xFF, 0x12, 0xE0, - 0x4B, 0x5E, 0x0B, 0x72, 0xEF, 0xFF, 0x12, 0xE0, - 0x00, 0x73, 0xD8, 0x75, 0x58, 0xFF, 0x12, 0xE0, - 0x0C, 0x90, 0x32, 0xF3, 0x5D, 0xFF, 0x12, 0xE0 - }; - */ - /* - pre-defined 9 CSN by iceman - only one csn depend on several others. - six depends only on the first csn, (0,1, 0x45) - */ + // remember to change the define NUM_CSNS to match. + + // pre-defined 9 CSN by iceman uint8_t csns[8 * NUM_CSNS] = { 0x01, 0x0A, 0x0F, 0xFF, 0xF7, 0xFF, 0x12, 0xE0, 0x0C, 0x06, 0x0C, 0xFE, 0xF7, 0xFF, 0x12, 0xE0, @@ -505,27 +485,6 @@ static int CmdHFiClassSim(const char *Cmd) { 0xD2, 0x5A, 0x82, 0xF8, 0xF7, 0xFF, 0x12, 0xE0 //0x04, 0x08, 0x9F, 0x78, 0x6E, 0xFF, 0x12, 0xE0 }; - /* - // pre-defined 15 CSN by Carl55 - // remember to change the define NUM_CSNS to match. - uint8_t csns[8*NUM_CSNS] = { - 0x00, 0x0B, 0x0F, 0xFF, 0xF7, 0xFF, 0x12, 0xE0, - 0x00, 0x04, 0x0E, 0x08, 0xF7, 0xFF, 0x12, 0xE0, - 0x00, 0x09, 0x0D, 0x05, 0xF7, 0xFF, 0x12, 0xE0, - 0x00, 0x0A, 0x0C, 0x06, 0xF7, 0xFF, 0x12, 0xE0, - 0x00, 0x0F, 0x0B, 0x03, 0xF7, 0xFF, 0x12, 0xE0, - 0x00, 0x08, 0x0A, 0x0C, 0xF7, 0xFF, 0x12, 0xE0, - 0x00, 0x0D, 0x09, 0x09, 0xF7, 0xFF, 0x12, 0xE0, - 0x00, 0x0E, 0x08, 0x0A, 0xF7, 0xFF, 0x12, 0xE0, - 0x00, 0x03, 0x07, 0x17, 0xF7, 0xFF, 0x12, 0xE0, - 0x00, 0x3C, 0x06, 0xE0, 0xF7, 0xFF, 0x12, 0xE0, - 0x00, 0x01, 0x05, 0x1D, 0xF7, 0xFF, 0x12, 0xE0, - 0x00, 0x02, 0x04, 0x1E, 0xF7, 0xFF, 0x12, 0xE0, - 0x00, 0x07, 0x03, 0x1B, 0xF7, 0xFF, 0x12, 0xE0, - 0x00, 0x00, 0x02, 0x24, 0xF7, 0xFF, 0x12, 0xE0, - 0x00, 0x05, 0x01, 0x21, 0xF7, 0xFF, 0x12, 0xE0 - }; - */ /* DUMPFILE FORMAT: * @@ -801,8 +760,6 @@ static int CmdHFiClassELoad(const char *Cmd) { return PM3_SUCCESS; } -#define ICLASS_DECRYPTION_BIN "iclass_decryptionkey.bin" - static int CmdHFiClassDecrypt(const char *Cmd) { bool errors = false; @@ -812,6 +769,7 @@ static int CmdHFiClassDecrypt(const char *Cmd) { uint8_t cmdp = 0; uint8_t enc_data[8] = {0}; + uint8_t dec_data[8] = {0}; size_t keylen = 0; uint8_t key[32] = {0}; @@ -865,11 +823,14 @@ static int CmdHFiClassDecrypt(const char *Cmd) { if (errors || cmdp < 1) return usage_hf_iclass_decrypt(); - if (have_key == false) { - int res = loadFile_safe(ICLASS_DECRYPTION_BIN, "", (void **)&keyptr, &keylen); - if (res != PM3_SUCCESS) - return PM3_EINVARG; + bool use_sc = IsCryptoHelperPresent(); + if (have_key == false && use_sc == false) { + int res = loadFile_safe(ICLASS_DECRYPTION_BIN, "", (void **)&keyptr, &keylen); + if (res != PM3_SUCCESS) { + PrintAndLogEx(INFO, "Couldn't find any decryption methods"); + return PM3_EINVARG; + } memcpy(key, keyptr, sizeof(key)); free(keyptr); } @@ -878,10 +839,13 @@ static int CmdHFiClassDecrypt(const char *Cmd) { mbedtls_des3_context ctx; mbedtls_des3_set2key_dec(&ctx, key); - uint8_t dec_data[8] = {0}; - if (have_data) { - mbedtls_des3_crypt_ecb(&ctx, enc_data, dec_data); + + if (use_sc) { + Decrypt(enc_data, dec_data); + } else { + mbedtls_des3_crypt_ecb(&ctx, enc_data, dec_data); + } PrintAndLogEx(SUCCESS, "Data: %s", sprint_hex(dec_data, sizeof(dec_data))); } @@ -897,6 +861,8 @@ static int CmdHFiClassDecrypt(const char *Cmd) { getMemConfig(mem, chip, &max_blk, &app_areas, &kb); uint8_t empty[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + + BLOCK79ENCRYPTION aa1_encryption = (decrypted[(6 * 8) + 7] & 0x03); for (uint16_t blocknum = 0; blocknum < applimit; ++blocknum) { @@ -904,8 +870,17 @@ static int CmdHFiClassDecrypt(const char *Cmd) { memcpy(enc_data, decrypted + idx, 8); // block 7 or higher, and not empty 0xFF - if (blocknum > 6 && memcmp(enc_data, empty, 8) != 0) { - mbedtls_des3_crypt_ecb(&ctx, enc_data, decrypted + idx); + // look inside block 6 to determine if aa1 is encrypted. + if (blocknum > 6 && memcmp(enc_data, empty, 8) != 0) { + + if (aa1_encryption == RFU || aa1_encryption == None) + continue; + + if (use_sc) { + Decrypt(enc_data, decrypted + idx); + } else { + mbedtls_des3_crypt_ecb(&ctx, enc_data, decrypted + idx); + } } } @@ -920,16 +895,43 @@ static int CmdHFiClassDecrypt(const char *Cmd) { printIclassDumpContents(decrypted, 1, (decryptedlen / 8), decryptedlen); - uint32_t top = 0, mid, bot; - mid = bytes_to_num(decrypted + (8*7), 4); - bot = bytes_to_num(decrypted + (8*7) + 4, 4); - PrintAndLogEx(INFO, ""); - PrintAndLogEx(INFO, "block 7 - Wiegand decode"); - wiegand_message_t packed = initialize_message_object(top, mid, bot); - HIDTryUnpack(&packed, true); - PrintAndLogEx(INFO, "-----------------------------------------------------------------"); - + // decode block 6 + if (memcmp(decrypted + (8*6), empty, 8) != 0 ) { + if (use_sc) { + DecodeBlock6(decrypted + (8*6)); + } + } + + // decode block 7-8-9 + if (memcmp(decrypted + (8*7), empty, 8) != 0 ) { + + //todo: remove preamble/sentinal + + uint32_t top = 0, mid, bot; + mid = bytes_to_num(decrypted + (8*7), 4); + bot = bytes_to_num(decrypted + (8*7) + 4, 4); + + PrintAndLogEx(INFO, "Block 7 binary"); + + char hexstr[8+1] = {0}; + hex_to_buffer((uint8_t *)hexstr, decrypted + (8*7), 8, sizeof(hexstr) - 1, 0, 0, true); + + char binstr[8*8+1] = {0}; + hextobinstring(binstr, hexstr); + uint8_t i=0; + while (iblockdata, sizeof(result->blockdata))); + + if (blockno == 6) { + if (IsCryptoHelperPresent()) { + DecodeBlock6(result->blockdata); + } + } + return PM3_SUCCESS; } diff --git a/client/cmdsmartcard.c b/client/cmdsmartcard.c index 6422fe605..ba48fae96 100644 --- a/client/cmdsmartcard.c +++ b/client/cmdsmartcard.c @@ -216,23 +216,23 @@ static int PrintATR(uint8_t *atr, size_t atrlen) { bool protocol_T15_present = false; if (T0 & 0x10) { - PrintAndLogEx(NORMAL, "\t- TA1 (Maximum clock frequency, proposed bit duration) [ 0x%02x ]", atr[2 + T1len]); + PrintAndLogEx(INFO, "\t- TA1 (Maximum clock frequency, proposed bit duration) [ 0x%02x ]", atr[2 + T1len]); T1len++; } if (T0 & 0x20) { - PrintAndLogEx(NORMAL, "\t- TB1 (Deprecated: VPP requirements) [ 0x%02x ]", atr[2 + T1len]); + PrintAndLogEx(INFO, "\t- TB1 (Deprecated: VPP requirements) [ 0x%02x ]", atr[2 + T1len]); T1len++; } if (T0 & 0x40) { - PrintAndLogEx(NORMAL, "\t- TC1 (Extra delay between bytes required by card) [ 0x%02x ]", atr[2 + T1len]); + PrintAndLogEx(INFO, "\t- TC1 (Extra delay between bytes required by card) [ 0x%02x ]", atr[2 + T1len]); T1len++; } if (T0 & 0x80) { uint8_t TD1 = atr[2 + T1len]; - PrintAndLogEx(NORMAL, "\t- TD1 (First offered transmission protocol, presence of TA2..TD2) [ 0x%02x ] Protocol T%d", TD1, TD1 & 0x0f); + PrintAndLogEx(INFO, "\t- TD1 (First offered transmission protocol, presence of TA2..TD2) [ 0x%02x ] Protocol T%d", TD1, TD1 & 0x0f); protocol_T0_present = false; if ((TD1 & 0x0f) == 0) { protocol_T0_present = true; @@ -244,20 +244,20 @@ static int PrintATR(uint8_t *atr, size_t atrlen) { T1len++; if (TD1 & 0x10) { - PrintAndLogEx(NORMAL, "\t- TA2 (Specific protocol and parameters to be used after the ATR) [ 0x%02x ]", atr[2 + T1len + TD1len]); + PrintAndLogEx(INFO, "\t- TA2 (Specific protocol and parameters to be used after the ATR) [ 0x%02x ]", atr[2 + T1len + TD1len]); TD1len++; } if (TD1 & 0x20) { - PrintAndLogEx(NORMAL, "\t- TB2 (Deprecated: VPP precise voltage requirement) [ 0x%02x ]", atr[2 + T1len + TD1len]); + PrintAndLogEx(INFO, "\t- TB2 (Deprecated: VPP precise voltage requirement) [ 0x%02x ]", atr[2 + T1len + TD1len]); TD1len++; } if (TD1 & 0x40) { - PrintAndLogEx(NORMAL, "\t- TC2 (Maximum waiting time for protocol T=0) [ 0x%02x ]", atr[2 + T1len + TD1len]); + PrintAndLogEx(INFO, "\t- TC2 (Maximum waiting time for protocol T=0) [ 0x%02x ]", atr[2 + T1len + TD1len]); TD1len++; } if (TD1 & 0x80) { uint8_t TDi = atr[2 + T1len + TD1len]; - PrintAndLogEx(NORMAL, "\t- TD2 (A supported protocol or more global parameters, presence of TA3..TD3) [ 0x%02x ] Protocol T%d", TDi, TDi & 0x0f); + PrintAndLogEx(INFO, "\t- TD2 (A supported protocol or more global parameters, presence of TA3..TD3) [ 0x%02x ] Protocol T%d", TDi, TDi & 0x0f); if ((TDi & 0x0f) == 0) { protocol_T0_present = true; } @@ -271,20 +271,20 @@ static int PrintATR(uint8_t *atr, size_t atrlen) { while (nextCycle) { nextCycle = false; if (TDi & 0x10) { - PrintAndLogEx(NORMAL, "\t- TA%d: 0x%02x", vi, atr[2 + T1len + TD1len + TDilen]); + PrintAndLogEx(INFO, "\t- TA%d: 0x%02x", vi, atr[2 + T1len + TD1len + TDilen]); TDilen++; } if (TDi & 0x20) { - PrintAndLogEx(NORMAL, "\t- TB%d: 0x%02x", vi, atr[2 + T1len + TD1len + TDilen]); + PrintAndLogEx(INFO, "\t- TB%d: 0x%02x", vi, atr[2 + T1len + TD1len + TDilen]); TDilen++; } if (TDi & 0x40) { - PrintAndLogEx(NORMAL, "\t- TC%d: 0x%02x", vi, atr[2 + T1len + TD1len + TDilen]); + PrintAndLogEx(INFO, "\t- TC%d: 0x%02x", vi, atr[2 + T1len + TD1len + TDilen]); TDilen++; } if (TDi & 0x80) { TDi = atr[2 + T1len + TD1len + TDilen]; - PrintAndLogEx(NORMAL, "\t- TD%d [ 0x%02x ] Protocol T%d", vi, TDi, TDi & 0x0f); + PrintAndLogEx(INFO, "\t- TD%d [ 0x%02x ] Protocol T%d", vi, TDi, TDi & 0x0f); TDilen++; nextCycle = true; @@ -314,7 +314,7 @@ static int PrintATR(uint8_t *atr, size_t atrlen) { PrintAndLogEx(WARNING, "Invalid ATR length. len: %zu, T1len: %d, TD1len: %d, TDilen: %d, K: %d", atrlen, T1len, TD1len, TDilen, K); if (K > 0) - PrintAndLogEx(INFO, "\nHistorical bytes | len 0x%02d | format %02x", K, atr[2 + T1len + TD1len + TDilen]); + PrintAndLogEx(INFO, "Historical bytes | len 0x%02d | format %02x", K, atr[2 + T1len + TD1len + TDilen]); if (K > 1) { PrintAndLogEx(INFO, "\tHistorical bytes"); @@ -361,7 +361,9 @@ static int smart_responseEx(uint8_t *data, bool silent) { if (needGetData) { int len = data[datalen - 1]; + if (!silent) PrintAndLogEx(INFO, "Requesting 0x%02X bytes response", len); + uint8_t getstatus[] = {0x00, ISO7816_GET_RESPONSE, 0x00, 0x00, len}; clearCommandBuffer(); SendCommandOLD(CMD_SMART_RAW, SC_RAW, sizeof(getstatus), 0, getstatus, sizeof(getstatus)); @@ -740,10 +742,9 @@ static int CmdSmartInfo(const char *Cmd) { PrintAndLogEx(INFO, "--- Smartcard Information ---------"); PrintAndLogEx(INFO, "-------------------------------------------------------------"); PrintAndLogEx(INFO, "ISO7618-3 ATR : %s", sprint_hex(card.atr, card.atr_len)); - PrintAndLogEx(INFO, "\nhttp://smartcard-atr.apdu.fr/parse?ATR=%s", sprint_hex_inrow(card.atr, card.atr_len)); + PrintAndLogEx(INFO, "http://smartcard-atr.apdu.fr/parse?ATR=%s", sprint_hex_inrow(card.atr, card.atr_len)); // print ATR - PrintAndLogEx(NORMAL, ""); PrintAndLogEx(INFO, "ATR"); PrintATR(card.atr, card.atr_len); @@ -756,14 +757,14 @@ static int CmdSmartInfo(const char *Cmd) { if (GetATRTA1(card.atr, card.atr_len) == 0x11) PrintAndLogEx(INFO, "Using default values..."); - PrintAndLogEx(NORMAL, "\t- Di %d", Di); - PrintAndLogEx(NORMAL, "\t- Fi %d", Fi); - PrintAndLogEx(NORMAL, "\t- F %.1f MHz", F); + PrintAndLogEx(INFO, "\t- Di %d", Di); + PrintAndLogEx(INFO, "\t- Fi %d", Fi); + PrintAndLogEx(INFO, "\t- F %.1f MHz", F); if (Di && Fi) { - PrintAndLogEx(NORMAL, "\t- Cycles/ETU %d", Fi / Di); - PrintAndLogEx(NORMAL, "\t- %.1f bits/sec at 4 MHz", (float)4000000 / (Fi / Di)); - PrintAndLogEx(NORMAL, "\t- %.1f bits/sec at Fmax (%.1fMHz)", (F * 1000000) / (Fi / Di), F); + PrintAndLogEx(INFO, "\t- Cycles/ETU %d", Fi / Di); + PrintAndLogEx(INFO, "\t- %.1f bits/sec at 4 MHz", (float)4000000 / (Fi / Di)); + PrintAndLogEx(INFO, "\t- %.1f bits/sec at Fmax (%.1fMHz)", (F * 1000000) / (Fi / Di), F); } else { PrintAndLogEx(WARNING, "\t- Di or Fi is RFU."); }; @@ -1156,11 +1157,12 @@ int CmdSmartcard(const char *Cmd) { return CmdsParse(CommandTable, Cmd); } -int ExchangeAPDUSC(uint8_t *datain, int datainlen, bool activateCard, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen) { +int ExchangeAPDUSC(bool silent, uint8_t *datain, int datainlen, bool activateCard, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen) { + *dataoutlen = 0; if (activateCard) - smart_select(false, NULL); + smart_select(true, NULL); PrintAndLogEx(DEBUG, "APDU SC"); @@ -1168,10 +1170,11 @@ int ExchangeAPDUSC(uint8_t *datain, int datainlen, bool activateCard, bool leave if (activateCard) { flags |= SC_SELECT | SC_CONNECT; } + clearCommandBuffer(); SendCommandOLD(CMD_SMART_RAW, flags, datainlen, 0, datain, datainlen); - int len = smart_responseEx(dataout, true); + int len = smart_responseEx(dataout, silent); if (len < 0) { return 1; @@ -1189,7 +1192,7 @@ int ExchangeAPDUSC(uint8_t *datain, int datainlen, bool activateCard, bool leave // something fishy: we have only 5 bytes but we put datainlen in arg1? SendCommandOLD(CMD_SMART_RAW, SC_RAW_T0, datainlen, 0, data, sizeof(data)); - len = smart_responseEx(dataout, true); + len = smart_responseEx(dataout, silent); } *dataoutlen = len; @@ -1204,6 +1207,7 @@ bool smart_select(bool silent, smart_card_atr_t *atr) { SendCommandNG(CMD_SMART_ATR, NULL, 0); PacketResponseNG resp; if (!WaitForResponseTimeout(CMD_ACK, &resp, 2500)) { + if (!silent) PrintAndLogEx(WARNING, "smart card select failed"); return false; } diff --git a/client/cmdsmartcard.h b/client/cmdsmartcard.h index 74c305a0d..798ea4678 100644 --- a/client/cmdsmartcard.h +++ b/client/cmdsmartcard.h @@ -17,6 +17,6 @@ int CmdSmartcard(const char *Cmd); bool smart_select(bool silent, smart_card_atr_t *atr); -int ExchangeAPDUSC(uint8_t *datain, int datainlen, bool activateCard, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen); +int ExchangeAPDUSC(bool silent, uint8_t *datain, int datainlen, bool activateCard, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen); #endif diff --git a/client/emv/emvcore.c b/client/emv/emvcore.c index 5bf330fe4..fe5ff3a31 100644 --- a/client/emv/emvcore.c +++ b/client/emv/emvcore.c @@ -305,7 +305,7 @@ static int EMVExchangeEx(EMVCommandChannel channel, bool ActivateField, bool Lea break; case ECC_CONTACT: if (IfPm3Smartcard()) - res = ExchangeAPDUSC(data, datalen, ActivateField, LeaveFieldON, Result, (int)MaxResultLen, (int *)ResultLen); + res = ExchangeAPDUSC(true, data, datalen, ActivateField, LeaveFieldON, Result, (int)MaxResultLen, (int *)ResultLen); else res = 1; if (res) { diff --git a/common/cardhelper.c b/common/cardhelper.c new file mode 100644 index 000000000..704a4f749 --- /dev/null +++ b/common/cardhelper.c @@ -0,0 +1,83 @@ +//----------------------------------------------------------------------------- +// Iceman, February 2020 +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// Support functions for smart card +//----------------------------------------------------------------------------- +#include "cardhelper.h" +#include +#include +#include "cmdparser.h" +#include "cmdsmartcard.h" +#include "ui.h" +#include "util.h" + +#define CARD_INS_DECRYPT 0x01 +#define CARD_INS_ENCRYPT 0x02 +#define CARD_INS_DECODE 0x06 +static uint8_t cmd[] = {0x96, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + +// look for CryptoHelper +bool IsCryptoHelperPresent(void) { + + if (IfPm3Smartcard()) { + int resp_len = 0; + uint8_t version[] = {0x96, 0x69, 0x00, 0x00, 0x00}; + uint8_t resp[20] = {0}; + ExchangeAPDUSC(true, version, sizeof(version), true, true, resp, sizeof(resp), &resp_len); + + if (strstr("CryptoHelper", (char*)resp) == 0) { + PrintAndLogEx(INFO, "Found smart card helper"); + return true; + } else { + return false; + } + } else { + return false; + } +} + +static bool executeCrypto(uint8_t ins, uint8_t *src, uint8_t *dest) { + int resp_len = 0; + uint8_t dec[11] = {0}; + + cmd[1] = ins; + memcpy(cmd + 5, src, 8); + + ExchangeAPDUSC(true, cmd, sizeof(cmd), false, true, dec, sizeof(dec), &resp_len); + + if (resp_len == 10) { + memcpy(dest, dec, 8); + return true; + } + return false; +} + +bool Decrypt(uint8_t *src, uint8_t *dest){ + return executeCrypto(CARD_INS_DECRYPT, src, dest); +} + +bool Encrypt(uint8_t *src, uint8_t *dest){ + return executeCrypto(CARD_INS_ENCRYPT, src, dest); +} + +void DecodeBlock6(uint8_t *src) { + int resp_len = 0; + uint8_t resp[254] = {0}; + + uint8_t c[] = {0x96, CARD_INS_DECODE, 0x00, 0x00, 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + memcpy(c + 6, src, 8); + + // first part + ExchangeAPDUSC(true, c, sizeof(c), false, true, resp, sizeof(resp), &resp_len); + PrintAndLogEx(SUCCESS, "%0.*s", resp_len - 11, resp + 9); + + // second part + c[5] = 0x02; + ExchangeAPDUSC(true, c, sizeof(c), false, true, resp, sizeof(resp), &resp_len); + PrintAndLogEx(SUCCESS, "%0.*s", resp_len - 11, resp + 9); +} + diff --git a/common/cardhelper.h b/common/cardhelper.h new file mode 100644 index 000000000..14ae23d1f --- /dev/null +++ b/common/cardhelper.h @@ -0,0 +1,21 @@ +//----------------------------------------------------------------------------- +// Iceman, February 2020 +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// Utility functions used in many places, not specific to any piece of code. +//----------------------------------------------------------------------------- + +#ifndef __CARDHELPER_H +#define __CARDHELPER_H + +#include +#include "common.h" + +bool IsCryptoHelperPresent(void); +bool Encrypt(uint8_t *src, uint8_t *dest); +bool Decrypt(uint8_t *src, uint8_t *dest); +void DecodeBlock6(uint8_t *src); +#endif From e14c11e1c804fc6d8986025f037eb265e418355b Mon Sep 17 00:00:00 2001 From: capnkrunchy <47148444+capnkrunchy@users.noreply.github.com> Date: Thu, 27 Feb 2020 11:26:16 -0600 Subject: [PATCH 1601/1854] Fix lf hid brute --- client/cmdlfhid.c | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/client/cmdlfhid.c b/client/cmdlfhid.c index 201dcef84..1e77cff08 100644 --- a/client/cmdlfhid.c +++ b/client/cmdlfhid.c @@ -369,9 +369,11 @@ static int CmdHIDBrute(const char *Cmd) { uint8_t cmdp = 0; int format_idx = -1; char format[16] = {0}; - wiegand_card_t data; - memset(&data, 0, sizeof(wiegand_card_t)); - + wiegand_card_t datahi; + memset(&datahi, 0, sizeof(wiegand_card_t)); + wiegand_card_t datalo; + memset(&datalo, 0, sizeof(wiegand_card_t)); + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { case 'h': @@ -386,7 +388,8 @@ static int CmdHIDBrute(const char *Cmd) { cmdp += 2; break; case 'c': - data.CardNumber = param_get32ex(Cmd, cmdp + 1, 0, 10); + datahi.CardNumber = param_get32ex(Cmd, cmdp + 1, 0, 10); + datalo.CardNumber = param_get32ex(Cmd, cmdp + 1, 0, 10); cmdp += 2; break; case 'd': @@ -395,15 +398,18 @@ static int CmdHIDBrute(const char *Cmd) { cmdp += 2; break; case 'f': - data.FacilityCode = param_get32ex(Cmd, cmdp + 1, 0, 10); + datahi.FacilityCode = param_get32ex(Cmd, cmdp + 1, 0, 10); + datalo.FacilityCode = param_get32ex(Cmd, cmdp + 1, 0, 10); cmdp += 2; break; case 'i': - data.IssueLevel = param_get32ex(Cmd, cmdp + 1, 0, 10); + datahi.IssueLevel = param_get32ex(Cmd, cmdp + 1, 0, 10); + datalo.IssueLevel = param_get32ex(Cmd, cmdp + 1, 0, 10); cmdp += 2; break; case 'o': - data.OEM = param_get32ex(Cmd, cmdp + 1, 0, 10); + datahi.OEM = param_get32ex(Cmd, cmdp + 1, 0, 10); + datalo.OEM = param_get32ex(Cmd, cmdp + 1, 0, 10); cmdp += 2; break; case 'v': @@ -435,15 +441,15 @@ static int CmdHIDBrute(const char *Cmd) { } // Do one up - if (data.CardNumber < 0xFFFF) { - data.CardNumber++; - if (sendTry(format_idx, &data, delay, verbose) != PM3_SUCCESS) return PM3_ESOFT; + if (datahi.CardNumber < 0xFFFF) { + datahi.CardNumber++; + if (sendTry(format_idx, &datahi, delay, verbose) != PM3_SUCCESS) return PM3_ESOFT; } - - // Do one down (if cardnumber is given) - if (data.CardNumber > 1) { - data.CardNumber--; - if (sendTry(format_idx, &data, delay, verbose) != PM3_SUCCESS) return PM3_ESOFT; + + // Do one up + if (datalo.CardNumber > 1) { + datalo.CardNumber--; + if (sendTry(format_idx, &datalo, delay, verbose) != PM3_SUCCESS) return PM3_ESOFT; } } return PM3_SUCCESS; From de65a431cfd9a5dd45f3004bbe2ed220c0050b84 Mon Sep 17 00:00:00 2001 From: mwalker33 Date: Fri, 28 Feb 2020 19:28:51 +1100 Subject: [PATCH 1602/1854] Update cmdlfkeri.c --- client/cmdlfkeri.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/client/cmdlfkeri.c b/client/cmdlfkeri.c index b0f45da04..4a0c3c8fd 100644 --- a/client/cmdlfkeri.c +++ b/client/cmdlfkeri.c @@ -181,7 +181,10 @@ static int CmdKeriDemod(const char *Cmd) { uint32_t raw2 = bytebits_to_byte(DemodBuffer + 32, 32); //get internal id - uint32_t ID = bytebits_to_byte(DemodBuffer + 29, 32); + // uint32_t ID = bytebits_to_byte(DemodBuffer + 29, 32); + // Due to the 3 sync bits being at the start of the capture + // We can take the last 32bits as the internal ID. + uint32_t ID = raw2; ID &= 0x7FFFFFFF; /* From 9dc419cec5803412c28d43c105efd5159232e801 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 28 Feb 2020 10:01:52 +0100 Subject: [PATCH 1603/1854] partial fix for mattyrun --- armsrc/Standalone/hf_mattyrun.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/armsrc/Standalone/hf_mattyrun.c b/armsrc/Standalone/hf_mattyrun.c index 3e53fffe9..60619e657 100644 --- a/armsrc/Standalone/hf_mattyrun.c +++ b/armsrc/Standalone/hf_mattyrun.c @@ -323,7 +323,7 @@ void RunMod() { Dbprintf("\tCurrent sector:%3d, block:%3d, key type: %c, key count: %i ", sec, block, type ? 'B' : 'A', mfKeysCnt); int key = saMifareChkKeys(block, type, true, size, &keyBlock[0], &key64); if (key == -1) { - LED(LED_RED, 50); //red + LED(LED_RED, 50); Dbprintf("\t✕ Key not found for this sector!"); allKeysFound = false; // break; @@ -348,21 +348,24 @@ void RunMod() { TODO: - Get UID from tag and set accordingly in emulator memory and call mifaresim with right flags (iceman) */ - if (!allKeysFound && keyFound) { - Dbprintf("\t✕ There's currently no nested attack in MattyRun, sorry!"); - LED_C_ON(); //red - LED_A_ON(); //yellow - // no room to run nested attack on device (iceman) - // Do nested attack, set allKeysFound = true; - // allKeysFound = true; + if (allKeysFound) { + Dbprintf("\t✓ All keys found"); } else { - Dbprintf("\t✕ There's nothing I can do without at least a one valid key, sorry!"); - LED_C_ON(); //red + if (keyFound) { + Dbprintf("\t✕ There's currently no nested attack in MattyRun, sorry!"); + LED_C_ON(); //red + LED_A_ON(); //yellow + // no room to run nested attack on device (iceman) + // Do nested attack, set allKeysFound = true; + // allKeysFound = true; + } else { + Dbprintf("\t✕ There's nothing I can do without at least a one valid key, sorry!"); + LED_C_ON(); //red + } } - /* - If enabled, transfers found keys to memory and loads target content in emulator memory. Then it simulates to be the tag it has basically cloned. - */ + // If enabled, transfers found keys to memory and loads target content in emulator memory. Then it simulates to be the tag it has basically cloned. + if ((transferToEml) && (allKeysFound)) { emlClearMem(); From c30bb354ac6d38a69a8e8d545e42c9020a1a0131 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 29 Feb 2020 09:27:55 +0100 Subject: [PATCH 1604/1854] chg: 'lf hid brute' - now uses UP/DOWN to specify direction only, more verbose and actually exits when done. --- client/cmdlfhid.c | 121 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 96 insertions(+), 25 deletions(-) diff --git a/client/cmdlfhid.c b/client/cmdlfhid.c index 1e77cff08..c10c5c56c 100644 --- a/client/cmdlfhid.c +++ b/client/cmdlfhid.c @@ -83,16 +83,18 @@ static int usage_lf_hid_brute(void) { PrintAndLogEx(NORMAL, "This is a attack against reader. if cardnumber is given, it starts with it and goes up / down one step"); PrintAndLogEx(NORMAL, "if cardnumber is not given, it starts with 1 and goes up to 65535"); PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Usage: lf hid brute [h] [v] w [ (decimal)>] {...}"); + PrintAndLogEx(NORMAL, "Usage: lf hid brute [h] [v] w [ (decimal)>] [up|down] {...}"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h : This help"); - PrintAndLogEx(NORMAL, " w : see `wiegand list` for available formats"); + PrintAndLogEx(NORMAL, " w : see " _YELLOW_("`wiegand list`") "for available formats"); PrintAndLogEx(NORMAL, " f : facility code"); PrintAndLogEx(NORMAL, " c : card number to start with"); PrintAndLogEx(NORMAL, " i : issue level"); PrintAndLogEx(NORMAL, " o : OEM code"); PrintAndLogEx(NORMAL, " d : delay betweens attempts in ms. Default 1000ms"); PrintAndLogEx(NORMAL, " v : verbose logging, show all tries"); + PrintAndLogEx(NORMAL, " up : direction to increment card number. (default is both directions)"); + PrintAndLogEx(NORMAL, " down : direction to decrement card number. (default is both directions)"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf hid brute w H10301 f 224"); @@ -368,13 +370,28 @@ static int CmdHIDBrute(const char *Cmd) { uint32_t delay = 1000; uint8_t cmdp = 0; int format_idx = -1; + int direction = 0; char format[16] = {0}; - wiegand_card_t datahi; - memset(&datahi, 0, sizeof(wiegand_card_t)); - wiegand_card_t datalo; - memset(&datalo, 0, sizeof(wiegand_card_t)); + + wiegand_card_t cn_hi, cn_low; + memset(&cn_hi, 0, sizeof(wiegand_card_t)); while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + + char s[10] = {0}; + if (param_getstr(Cmd, cmdp, s, sizeof(s)) > 0) { + if (strlen(s) > 1) { + str_lower((char *)s); + if (str_startswith(s, "up")) { + direction = 1; + } else if (str_startswith(s, "do")) { + direction = 2; + } + cmdp++; + continue; + } + } + switch (tolower(param_getchar(Cmd, cmdp))) { case 'h': return usage_lf_hid_brute(); @@ -388,8 +405,7 @@ static int CmdHIDBrute(const char *Cmd) { cmdp += 2; break; case 'c': - datahi.CardNumber = param_get32ex(Cmd, cmdp + 1, 0, 10); - datalo.CardNumber = param_get32ex(Cmd, cmdp + 1, 0, 10); + cn_hi.CardNumber = param_get32ex(Cmd, cmdp + 1, 0, 10); cmdp += 2; break; case 'd': @@ -398,18 +414,15 @@ static int CmdHIDBrute(const char *Cmd) { cmdp += 2; break; case 'f': - datahi.FacilityCode = param_get32ex(Cmd, cmdp + 1, 0, 10); - datalo.FacilityCode = param_get32ex(Cmd, cmdp + 1, 0, 10); + cn_hi.FacilityCode = param_get32ex(Cmd, cmdp + 1, 0, 10); cmdp += 2; break; case 'i': - datahi.IssueLevel = param_get32ex(Cmd, cmdp + 1, 0, 10); - datalo.IssueLevel = param_get32ex(Cmd, cmdp + 1, 0, 10); + cn_hi.IssueLevel = param_get32ex(Cmd, cmdp + 1, 0, 10); cmdp += 2; break; case 'o': - datahi.OEM = param_get32ex(Cmd, cmdp + 1, 0, 10); - datalo.OEM = param_get32ex(Cmd, cmdp + 1, 0, 10); + cn_hi.OEM = param_get32ex(Cmd, cmdp + 1, 0, 10); cmdp += 2; break; case 'v': @@ -422,13 +435,45 @@ static int CmdHIDBrute(const char *Cmd) { break; } } + + if (format_idx == -1) { + PrintAndLogEx(ERR, "You must select a wiegand format. See " _YELLOW_("`wiegand list`") "for available formats\n"); + errors = true; + } + if (errors) return usage_lf_hid_brute(); + if (verbose) { + PrintAndLogEx(INFO, "Wiegand format#.. %i", format_idx); + PrintAndLogEx(INFO, "OEM#............. %u", cn_hi.OEM); + PrintAndLogEx(INFO, "ISSUE#........... %u", cn_hi.IssueLevel); + PrintAndLogEx(INFO, "Facility#........ %u", cn_hi.FacilityCode); + PrintAndLogEx(INFO, "Card#............ %u", cn_hi.CardNumber); + switch( direction) { + case 0: + PrintAndLogEx(INFO, "Brute-forcing direction: " _YELLOW_("BOTH")); + break; + case 1: + PrintAndLogEx(INFO, "Brute-forcing direction: " _YELLOW_("UP")); + break; + case 2: + PrintAndLogEx(INFO, "Brute-forcing direction: " _YELLOW_("DOWN")); + break; + default: break; + } + } PrintAndLogEx(INFO, "Brute-forcing HID reader"); - PrintAndLogEx(INFO, "Press pm3-button to abort simulation or run another command"); + PrintAndLogEx(INFO, "Press pm3-button to abort simulation or press `enter` to exit"); + + // copy values to low. + cn_low = cn_hi; // main loop - for (;;) { + // iceman: could add options for bruteforcing OEM, ISSUE or FC aswell.. + bool exitloop = false; + bool fin_hi, fin_low; + fin_hi = fin_low = false; + do { if (!session.pm3_present) { PrintAndLogEx(WARNING, "Device offline\n"); @@ -440,18 +485,44 @@ static int CmdHIDBrute(const char *Cmd) { return sendPing(); } - // Do one up - if (datahi.CardNumber < 0xFFFF) { - datahi.CardNumber++; - if (sendTry(format_idx, &datahi, delay, verbose) != PM3_SUCCESS) return PM3_ESOFT; + // do one up + if (direction != 2) { + if (cn_hi.CardNumber < 0xFFFF) { + cn_hi.CardNumber++; + if (sendTry(format_idx, &cn_hi, delay, verbose) != PM3_SUCCESS) return PM3_ESOFT; + } else { + fin_hi = true; + } } - // Do one up - if (datalo.CardNumber > 1) { - datalo.CardNumber--; - if (sendTry(format_idx, &datalo, delay, verbose) != PM3_SUCCESS) return PM3_ESOFT; + // do one down + if (direction != 1) { + if (cn_low.CardNumber > 0) { + cn_low.CardNumber--; + if (sendTry(format_idx, &cn_low, delay, verbose) != PM3_SUCCESS) return PM3_ESOFT; + } else { + fin_low = true; + } } - } + + switch (direction) { + case 0: + if (fin_hi && fin_low) { + exitloop = true; + } + break; + case 1: + exitloop = fin_hi; + break; + case 2: + exitloop = fin_low; + break; + default: break; + } + + } while (exitloop == false); + + PrintAndLogEx(INFO, "Brute forcing finished"); return PM3_SUCCESS; } From 8617acee7135b1140fc4cd7083d19262e39c9dda Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 29 Feb 2020 16:22:18 +0100 Subject: [PATCH 1605/1854] textual --- CHANGELOG.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index af8b073ca..8015a76f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,16 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Chnage `lf keri demod` - adjusted the internal id. (@mwalker33) + - Added seamless integration with cryptohelper (@iceman1001) + - Change `lf hid brute` - new params for direction (UP/DOWN); textual and main loop actually exit. (@capnkrunchy and @iceman1001) + - Fix `lf hid brute` - made it work again (@capnkrunchy) + - Fix standalone mode HF_MATTYRUN - correct logic when all keys found in printing. partial fix (@iceman1001) + - Change static nonce detection got tighter (@iceman1001) + - Improved termux notes (@msoose) + - Fix `hf mf autopwn` - works on debian 10 *nix. Bad exit commands in hardnested (@iceman1001) + - Fix `hf mf hardnested` - bad mutex strategies (@msoose) + - Change `lf hitag` - now obeys `lf config` (@iceman1001) - Ported all python 2 scripts to python 3 (@doegox and @sigwinch28) - Removed undefined exit behaviour from `analyzesize` tool: it now exits with code 2 when called with wrong args (@sigwinch28) - Replaced shebangs in scripts with more portable versions which use `/usr/bin/env` (@sigwinch28) From 05dc1f7e5f77e70a4e1544f76319886cdba6cf38 Mon Sep 17 00:00:00 2001 From: bosb <12600404+bosb@users.noreply.github.com> Date: Sat, 29 Feb 2020 18:35:56 +0100 Subject: [PATCH 1606/1854] fix send frame, some config bytes from tag, use global dbg level --- armsrc/hitagS.c | 59 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 46 insertions(+), 13 deletions(-) diff --git a/armsrc/hitagS.c b/armsrc/hitagS.c index 68fa825e1..50a96f178 100644 --- a/armsrc/hitagS.c +++ b/armsrc/hitagS.c @@ -86,7 +86,7 @@ bool end = false; #define HITAG_T_TAG_CAPTURE_THREE_HALF 41 #define HITAG_T_TAG_CAPTURE_FOUR_HALF 57 -#define DEBUG 0 +#define DBGLEVEL 4 /* * Implementation of the crc8 calculation from Hitag S @@ -207,6 +207,22 @@ static void hitag_send_bit(int bit) { } static void hitag_send_frame(const uint8_t *frame, size_t frame_len) { + // The beginning of the frame is hidden in some high level; pause until our bits come out + AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; + HIGH(GPIO_SSC_DOUT); + switch (m) { + case AC4K: + while (AT91C_BASE_TC0->TC_CV < T0 * 40) {}; //FADV + break; + case AC2K: + while (AT91C_BASE_TC0->TC_CV < T0 * 20) {}; //STD + ADV + break; + case MC4K: + break; + case MC8K: + break; + } + // SOF - send start of frame for (size_t i = 0; i < sof_bits; i++) { hitag_send_bit(1); @@ -318,20 +334,28 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen, switch (rxlen) { case 5: { //UID request with a selected response protocol mode + if (DBGLEVEL >= DBG_EXTENDED) + Dbprintf("...UID req %i %02x", rxlen, rx[0]); tag.pstate = HT_READY; tag.tstate = HT_NO_OP; if ((rx[0] & 0xf0) == 0x30) { + if (DBGLEVEL >= DBG_EXTENDED) + Dbprintf("HT_STANDARD"); tag.mode = HT_STANDARD; sof_bits = 1; m = AC2K; } if ((rx[0] & 0xf0) == 0xc0) { tag.mode = HT_ADVANCED; + if (DBGLEVEL >= DBG_EXTENDED) + Dbprintf("HT_ADVANCED"); sof_bits = 3; m = AC2K; } if ((rx[0] & 0xf0) == 0xd0) { + if (DBGLEVEL >= DBG_EXTENDED) + Dbprintf("HT_FAST_ADVANCED"); tag.mode = HT_FAST_ADVANCED; sof_bits = 3; m = AC4K; @@ -344,7 +368,9 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen, break; case 45: { //select command from reader received + DbpString("...select"); if (check_select(rx, tag.uid) == 1) { + DbpString("...select match"); //if the right tag was selected *txlen = 32; switch (tag.mode) { @@ -366,7 +392,7 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen, //send configuration for (int i = 0; i < 4; i++) - tx[i] = (tag.pages[0][1] >> (i * 8)) & 0xff; + tx[i] = tag.pages[1][i]; tx[3] = 0xff; if (tag.mode != HT_STANDARD) { *txlen = 40; @@ -439,6 +465,7 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen, */ } case 40: + Dbprintf("....write"); //data received to be written if (tag.tstate == HT_WRITING_PAGE_DATA) { tag.tstate = HT_NO_OP; @@ -495,6 +522,7 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen, } break; case 20: { + Dbprintf("....read"); //write page, write block, read page or read block command received if ((rx[0] & 0xf0) == 0xc0) { //read page //send page data @@ -644,7 +672,11 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen, } break; default: - + if (DBGLEVEL >= DBG_EXTENDED) { + Dbprintf("rxlen: %i", rxlen); + for (int i = 0; i < 4; i++) + Dbprintf("%i: %02X",i,rx[i]); + } break; } } @@ -722,7 +754,7 @@ static int hitagS_handle_tag_auth(hitag_function htf, uint64_t key, uint64_t NrA | (uid[30] << 1) | uid[31]; - if (DEBUG) + if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("UID: %02X %02X %02X %02X", uid1, uid2, uid3, uid4); tag.uid = (uid4 << 24 | uid3 << 16 | uid2 << 8 | uid1); @@ -816,7 +848,7 @@ static int hitagS_handle_tag_auth(hitag_function htf, uint64_t key, uint64_t NrA tag.LCK1 = response_bit[26]; tag.LCK0 = response_bit[27]; - if (DEBUG) + if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("conf0: %02X conf1: %02X conf2: %02X", conf_pages[0], conf_pages[1], conf_pages[2]); if (tag.auth == 1) { @@ -839,7 +871,7 @@ static int hitagS_handle_tag_auth(hitag_function htf, uint64_t key, uint64_t NrA tx[5] = auth_ks[1]; tx[6] = auth_ks[2]; tx[7] = auth_ks[3]; - if (DEBUG) + if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("%02X %02X %02X %02X %02X %02X %02X %02X", tx[0], tx[1], tx[2], tx[3], tx[4], tx[5], tx[6], tx[7]); } else if (htf == 01 || htf == 03) { //RHTS_CHALLENGE //WHTS_CHALLENGE @@ -864,7 +896,7 @@ static int hitagS_handle_tag_auth(hitag_function htf, uint64_t key, uint64_t NrA calc_crc(&crc, ((rx[1] & 0x0f) * 16 + ((rx[2] & 0xf0) / 16)), 8); calc_crc(&crc, ((rx[2] & 0x0f) * 16 + ((rx[3] & 0xf0) / 16)), 8); calc_crc(&crc, ((rx[3] & 0x0f) * 16 + ((rx[4] & 0xf0) / 16)), 8); - if (DEBUG) { + if (DBGLEVEL >= DBG_EXTENDED) { Dbprintf("UID:::%X", tag.uid); Dbprintf("RND:::%X", rnd); } @@ -884,7 +916,7 @@ static int hitagS_handle_tag_auth(hitag_function htf, uint64_t key, uint64_t NrA pwdl1 = ((rx[3] & 0x0f) * 16 + ((rx[4] & 0xf0) / 16)) ^ _hitag2_byte(&state); } - if (DEBUG) + if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("pwdh0 %02X pwdl0 %02X pwdl1 %02X", pwdh0, pwdl0, pwdl1); //Dbprintf("%X %02X", rnd, ((rx[4] & 0x0f) * 16) + ((rx[5] & 0xf0) / 16)); @@ -941,12 +973,12 @@ void SimulateHitagSTag(bool tag_mem_supplied, uint8_t *data) { } tag.uid = (tag.pages[0][3] << 24 | tag.pages[0][2] << 16 | tag.pages[0][1] << 8 | tag.pages[0][0]); - tag.key = (intptr_t)tag.pages[3]; + tag.key = (tag.pages[3][3] << 24 | tag.pages[3][2] << 16 | tag.pages[3][1] << 8 | tag.pages[3][0]); tag.key <<= 16; - tag.key += ((tag.pages[2][0]) << 8) + tag.pages[2][1]; - tag.pwdl0 = tag.pages[2][3]; - tag.pwdl1 = tag.pages[2][2]; - tag.pwdh0 = tag.pages[1][0]; + tag.key += ((tag.pages[2][3]) << 8) + tag.pages[2][2]; + tag.pwdl0 = tag.pages[2][0]; + tag.pwdl1 = tag.pages[2][1]; + tag.pwdh0 = tag.pages[1][3]; //con0 tag.max_page = 64; if ((tag.pages[1][3] & 0x2) == 0 && (tag.pages[1][3] & 0x1) == 1) @@ -1114,6 +1146,7 @@ void SimulateHitagSTag(bool tag_mem_supplied, uint8_t *data) { overflow += (AT91C_BASE_TC1->TC_CV / T0); // Reset the timer to restart while-loop that receives frames AT91C_BASE_TC1->TC_CCR = AT91C_TC_SWTRG; + } LEDsoff(); From bf975af358e1694bd48f37458e709b05311bf92c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 29 Feb 2020 21:09:16 +0100 Subject: [PATCH 1607/1854] fix coverty 267216 resource leak --- client/mifare/mifarehost.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/client/mifare/mifarehost.c b/client/mifare/mifarehost.c index 31085a629..3668f3332 100644 --- a/client/mifare/mifarehost.c +++ b/client/mifare/mifarehost.c @@ -676,6 +676,7 @@ int mfStaticNested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBl //flush queue while (kbd_enter_pressed()) { SendCommandNG(CMD_BREAK_LOOP, NULL, 0); + free(mem); return PM3_EOPABORTED; } @@ -695,6 +696,7 @@ int mfStaticNested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBl res = flashmem_spiffs_load(destfn, mem, 5 + (chunk * 6) ); if (res != PM3_SUCCESS) { PrintAndLogEx(WARNING, "SPIFFS upload failed"); + free(mem); return res; } @@ -717,6 +719,7 @@ int mfStaticNested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBl ); return PM3_SUCCESS; } else if (res == PM3_ETIMEOUT || res == PM3_EOPABORTED) { + free(mem); return res; } From 8908798efda9e9fab47a16674a7702995dc94e5b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 1 Mar 2020 16:38:01 +0100 Subject: [PATCH 1608/1854] fix coverity 267218 --- client/mifare/mifarehost.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/client/mifare/mifarehost.c b/client/mifare/mifarehost.c index 3668f3332..388cc029e 100644 --- a/client/mifare/mifarehost.c +++ b/client/mifare/mifarehost.c @@ -544,8 +544,7 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, return -5; } - uint64_t t2 = msclock(); - float bruteforce_per_second = (float)KEYS_IN_BLOCK / (float)(t2 - start_time) * 1000.0; + float bruteforce_per_second = (float)KEYS_IN_BLOCK / (msclock() - start_time) * 1000.0; if ( i + 1 % 10 == 0) PrintAndLogEx(INFO, " %6d/%u keys | %5.1f keys/sec | worst case %6.1f seconds remaining", i, keycnt , bruteforce_per_second, (keycnt-i) / bruteforce_per_second); @@ -724,7 +723,7 @@ int mfStaticNested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBl } // if (i%10 == 0) { - float bruteforce_per_second = (float)i + max_keys_chunk / (float)(msclock() - start_time) * 1000.0; + float bruteforce_per_second = (float)i + max_keys_chunk / (msclock() - start_time) * 1000.0; PrintAndLogEx(INFO, "Chunk %6u/%u keys | %5.1f keys/sec | worst case %6.1f seconds remaining", i, keycnt, bruteforce_per_second, (keycnt-i) / bruteforce_per_second); // } } From d11716110f0a0377fa11b11c96d0f1ae186f5da6 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 1 Mar 2020 16:39:25 +0100 Subject: [PATCH 1609/1854] fix coverity 267215 --- armsrc/lfadc.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/armsrc/lfadc.c b/armsrc/lfadc.c index 63b246025..32d1e73b6 100644 --- a/armsrc/lfadc.c +++ b/armsrc/lfadc.c @@ -133,16 +133,18 @@ size_t lf_detect_gap(size_t max) { } void lf_reset_counter() { + // TODO: find out the correct reset settings for tag and reader mode - if (reader_mode) { +// if (reader_mode) { // Reset values for reader mode rising_edge = false; previous_adc_val = 0xFF; - } else { + +// } else { // Reset values for tag/transponder mode - rising_edge = false; - previous_adc_val = 0xFF; - } +// rising_edge = false; +// previous_adc_val = 0xFF; +// } } bool lf_get_tag_modulation() { From 9c9906c823b0fe7ec3dcd608ad6fb6e9384c8663 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 1 Mar 2020 16:46:31 +0100 Subject: [PATCH 1610/1854] fix coverity 267213 --- common/cardhelper.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/cardhelper.c b/common/cardhelper.c index 704a4f749..93e361f60 100644 --- a/common/cardhelper.c +++ b/common/cardhelper.c @@ -73,11 +73,11 @@ void DecodeBlock6(uint8_t *src) { // first part ExchangeAPDUSC(true, c, sizeof(c), false, true, resp, sizeof(resp), &resp_len); - PrintAndLogEx(SUCCESS, "%0.*s", resp_len - 11, resp + 9); + PrintAndLogEx(SUCCESS, "%.*s", resp_len - 11, resp + 9); // second part c[5] = 0x02; ExchangeAPDUSC(true, c, sizeof(c), false, true, resp, sizeof(resp), &resp_len); - PrintAndLogEx(SUCCESS, "%0.*s", resp_len - 11, resp + 9); + PrintAndLogEx(SUCCESS, "%.*s", resp_len - 11, resp + 9); } From 4bd9f183dfec3824485fae7e3a8b7381848207b6 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 1 Mar 2020 17:11:25 +0100 Subject: [PATCH 1611/1854] fix coverity 267206 --- armsrc/hitag2.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index 37c716efb..87d6bf221 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -94,7 +94,7 @@ uint8_t nonce[4]; bool key_no; static uint64_t cipher_state; -size_t blocknr; +int16_t blocknr; size_t flipped_bit = 0; uint32_t byte_value = 0; @@ -582,7 +582,7 @@ bool hitag1_authenticate(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t *t Dbhexdump(4, logdata_1, false); bSuccessful = true; return false; - +/* // read next page of card until done tx[0] = 0xe0 | blocknr >> 4; // RDCPAGE tx[1] = blocknr << 4; @@ -590,6 +590,7 @@ bool hitag1_authenticate(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t *t tx[1] |= crc >> 4; tx[2] = crc << 4; *txlen = 20; +*/ } } break; @@ -1288,10 +1289,10 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { uint8_t *tx = txbuf; size_t txlen = 0; - int t_wait_1; + int t_wait_1 = 204; int t_wait_1_guard = 8; - int t_wait_2; - size_t tag_size; + int t_wait_2 = 128; + size_t tag_size = 48; bool bStop = false; // Raw demodulation/decoding by sampling edge periods @@ -1417,9 +1418,6 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { t_wait_2 = HITAG_T_WAIT_2_MIN; tag_size = 48; DBG DbpString("Configured for hitag2 reader"); - } else { - DBG Dbprintf("Error, unknown hitag reader type: %d", htf); - return; } // init as reader @@ -1665,10 +1663,12 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) { uint8_t txbuf[HITAG_FRAME_LEN]; uint8_t *tx = txbuf; size_t txlen = 0; - int t_wait_1; + + int t_wait_1 = 204; int t_wait_1_guard = 8; - int t_wait_2; - size_t tag_size; + int t_wait_2 = 128; + size_t tag_size = 48; + bool bStop = false; // Raw demodulation/decoding by sampling edge periods @@ -1743,9 +1743,6 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) { t_wait_2 = HITAG_T_WAIT_2_MIN; tag_size = 48; DbpString("Configured for hitag2 writer"); - } else { - DBG Dbprintf("Error, unknown hitag writer type: %d", htf); - return; } uint8_t tag_modulation; From da21f94b665573e1832769c30bef240f817e9b2f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 1 Mar 2020 17:15:48 +0100 Subject: [PATCH 1612/1854] fix coverity 267478 --- client/cmdlfhid.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/client/cmdlfhid.c b/client/cmdlfhid.c index c10c5c56c..3a4d16cf3 100644 --- a/client/cmdlfhid.c +++ b/client/cmdlfhid.c @@ -367,7 +367,7 @@ static int CmdHIDClone(const char *Cmd) { static int CmdHIDBrute(const char *Cmd) { bool errors = false, verbose = false; - uint32_t delay = 1000; + uint32_t delay = 1000; uint8_t cmdp = 0; int format_idx = -1; int direction = 0; @@ -375,9 +375,9 @@ static int CmdHIDBrute(const char *Cmd) { wiegand_card_t cn_hi, cn_low; memset(&cn_hi, 0, sizeof(wiegand_card_t)); - + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { - + char s[10] = {0}; if (param_getstr(Cmd, cmdp, s, sizeof(s)) > 0) { if (strlen(s) > 1) { @@ -448,12 +448,12 @@ static int CmdHIDBrute(const char *Cmd) { PrintAndLogEx(INFO, "OEM#............. %u", cn_hi.OEM); PrintAndLogEx(INFO, "ISSUE#........... %u", cn_hi.IssueLevel); PrintAndLogEx(INFO, "Facility#........ %u", cn_hi.FacilityCode); - PrintAndLogEx(INFO, "Card#............ %u", cn_hi.CardNumber); + PrintAndLogEx(INFO, "Card#............ %" PRIu64, cn_hi.CardNumber); switch( direction) { case 0: PrintAndLogEx(INFO, "Brute-forcing direction: " _YELLOW_("BOTH")); break; - case 1: + case 1: PrintAndLogEx(INFO, "Brute-forcing direction: " _YELLOW_("UP")); break; case 2: From 95b759a7997aa95edbbb892e067492530255d513 Mon Sep 17 00:00:00 2001 From: bosb <12600404+bosb@users.noreply.github.com> Date: Sun, 1 Mar 2020 22:48:49 +0100 Subject: [PATCH 1613/1854] removed duplicate code --- armsrc/hitagS.c | 596 +++++++++++++++--------------------------------- 1 file changed, 182 insertions(+), 414 deletions(-) diff --git a/armsrc/hitagS.c b/armsrc/hitagS.c index 50a96f178..38cb4d478 100644 --- a/armsrc/hitagS.c +++ b/armsrc/hitagS.c @@ -10,6 +10,7 @@ //----------------------------------------------------------------------------- // Some code was copied from Hitag2.c //----------------------------------------------------------------------------- +// bosb 2020 #include "hitagS.h" @@ -23,6 +24,7 @@ #include "string.h" #include "commonutil.h" #include "hitag2_crypto.h" +#include "lfadc.h" #define CRC_PRESET 0xFF #define CRC_POLYNOM 0x1D @@ -50,6 +52,22 @@ size_t blocknr; bool end = false; //#define SENDBIT_TEST +/* array index 3 2 1 0 // bytes in sim.bin file are 0 1 2 3 +// UID is 0 1 2 3 // tag.uid is 3210 +// datasheet HitagS_V11.pdf bytes in tables printed 3 2 1 0 + +#db# UID: 5F C2 11 84 +#db# conf0: C9 conf1: 00 conf2: 00 + 3 2 1 0 +#db# Page[ 0]: 84 11 C2 5F uid +#db# Page[ 1]: AA 00 00 C9 conf +#db# Page[ 2]: 4E 4F 54 48 +#db# Page[ 3]: 52 4B 49 4D +#db# Page[ 4]: 00 00 00 00 +#db# Page[ 5]: 00 00 00 00 +#db# Page[ 6]: 00 00 00 00 +#db# Page[ 7]: 4B 4F 5F 57 */ + #define ht2bs_4a(a,b,c,d) (~(((a|b)&c)^(a|d)^b)) #define ht2bs_4b(a,b,c,d) (~(((d|c)&(a^b))^(d|a|b))) #define ht2bs_5c(a,b,c,d,e) (~((((((c^e)|d)&a)^b)&(c^b))^(((d^e)|a)&((d^b)|c)))) @@ -207,19 +225,17 @@ static void hitag_send_bit(int bit) { } static void hitag_send_frame(const uint8_t *frame, size_t frame_len) { - // The beginning of the frame is hidden in some high level; pause until our bits come out + // The beginning of the frame is hidden in some high level; pause until our bits will have an effect AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; HIGH(GPIO_SSC_DOUT); switch (m) { case AC4K: + case MC8K: while (AT91C_BASE_TC0->TC_CV < T0 * 40) {}; //FADV break; case AC2K: - while (AT91C_BASE_TC0->TC_CV < T0 * 20) {}; //STD + ADV - break; case MC4K: - break; - case MC8K: + while (AT91C_BASE_TC0->TC_CV < T0 * 20) {}; //STD + ADV break; } @@ -315,6 +331,25 @@ static int check_select(uint8_t *rx, uint32_t uid) { return 0; } +void hitagS_set_frame_modulation() { + switch (tag.mode) { + case HT_STANDARD: + sof_bits = 1; + m = MC4K; + break; + case HT_ADVANCED: + sof_bits = 6; + m = MC4K; + break; + case HT_FAST_ADVANCED: + sof_bits = 6; + m = MC8K; + break; + default: + break; + } +} + /* * handles all commands from a reader */ @@ -368,27 +403,14 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen, break; case 45: { //select command from reader received - DbpString("...select"); + if (DBGLEVEL >= DBG_EXTENDED) + DbpString("...select"); if (check_select(rx, tag.uid) == 1) { - DbpString("...select match"); + if (DBGLEVEL >= DBG_EXTENDED) + DbpString("...select match"); //if the right tag was selected *txlen = 32; - switch (tag.mode) { - case HT_STANDARD: - sof_bits = 1; - m = MC4K; - break; - case HT_ADVANCED: - sof_bits = 6; - m = MC4K; - break; - case HT_FAST_ADVANCED: - sof_bits = 6; - m = MC8K; - break; - default: - break; - } + hitagS_set_frame_modulation(); //send configuration for (int i = 0; i < 4; i++) @@ -416,22 +438,7 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen, Dbprintf(",{0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X}", rx[0], rx[1], rx[2], rx[3], rx[4], rx[5], rx[6], rx[7]); - switch (tag.mode) { - case HT_STANDARD: - sof_bits = 1; - m = MC4K; - break; - case HT_ADVANCED: - sof_bits = 6; - m = MC4K; - break; - case HT_FAST_ADVANCED: - sof_bits = 6; - m = MC8K; - break; - default: - break; - } + hitagS_set_frame_modulation(); for (int i = 0; i < 4; i++) _hitag2_byte(&state); @@ -465,7 +472,8 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen, */ } case 40: - Dbprintf("....write"); + if (DBGLEVEL >= DBG_EXTENDED) + Dbprintf("....write"); //data received to be written if (tag.tstate == HT_WRITING_PAGE_DATA) { tag.tstate = HT_NO_OP; @@ -475,44 +483,14 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen, *txlen = 2; tx[0] = 0x40; page_to_be_written = 0; - switch (tag.mode) { - case HT_STANDARD: - sof_bits = 1; - m = MC4K; - break; - case HT_ADVANCED: - sof_bits = 6; - m = MC4K; - break; - case HT_FAST_ADVANCED: - sof_bits = 6; - m = MC8K; - break; - default: - break; - } + hitagS_set_frame_modulation(); } else if (tag.tstate == HT_WRITING_BLOCK_DATA) { tag.pages[page_to_be_written / 4][page_to_be_written % 4] = (rx[0] << 24) + (rx[1] << 16) + (rx[2] << 8) + rx[3]; //send ack *txlen = 2; tx[0] = 0x40; - switch (tag.mode) { - case HT_STANDARD: - sof_bits = 1; - m = MC4K; - break; - case HT_ADVANCED: - sof_bits = 6; - m = MC4K; - break; - case HT_FAST_ADVANCED: - sof_bits = 6; - m = MC8K; - break; - default: - break; - } + hitagS_set_frame_modulation(); page_to_be_written++; block_data_left--; if (block_data_left == 0) { @@ -522,35 +500,23 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen, } break; case 20: { - Dbprintf("....read"); + if (DBGLEVEL >= DBG_EXTENDED) + Dbprintf("....read"); //write page, write block, read page or read block command received if ((rx[0] & 0xf0) == 0xc0) { //read page //send page data uint8_t page = ((rx[0] & 0x0f) * 16) + ((rx[1] & 0xf0) / 16); + if (DBGLEVEL >= DBG_EXTENDED) + Dbprintf("....page %i", page); *txlen = 32; - tx[0] = (tag.pages[page / 4][page % 4]) & 0xff; - tx[1] = (tag.pages[page / 4][page % 4] >> 8) & 0xff; - tx[2] = (tag.pages[page / 4][page % 4] >> 16) & 0xff; - tx[3] = (tag.pages[page / 4][page % 4] >> 24) & 0xff; + tx[0] = tag.pages[page][0]; + tx[1] = tag.pages[page][1]; + tx[2] = tag.pages[page][2]; + tx[3] = tag.pages[page][3]; if (tag.LKP && page == 1) tx[3] = 0xff; - switch (tag.mode) { - case HT_STANDARD: - sof_bits = 1; - m = MC4K; - break; - case HT_ADVANCED: - sof_bits = 6; - m = MC4K; - break; - case HT_FAST_ADVANCED: - sof_bits = 6; - m = MC8K; - break; - default: - break; - } + hitagS_set_frame_modulation(); if (tag.mode != HT_STANDARD) { //add crc8 @@ -568,32 +534,18 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen, } } else if ((rx[0] & 0xf0) == 0xd0) { //read block uint8_t page = ((rx[0] & 0x0f) * 16) + ((rx[1] & 0xf0) / 16); + if (DBGLEVEL >= DBG_EXTENDED) + Dbprintf("....block %i", page); *txlen = 32 * 4; //send page,...,page+3 data for (int i = 0; i < 4; i++) { - tx[0 + i * 4] = (tag.pages[page / 4][page % 4]) & 0xff; - tx[1 + i * 4] = (tag.pages[page / 4][page % 4] >> 8) & 0xff; - tx[2 + i * 4] = (tag.pages[page / 4][page % 4] >> 16) & 0xff; - tx[3 + i * 4] = (tag.pages[page / 4][page % 4] >> 24) & 0xff; - page++; + tx[0 + i * 4] = tag.pages[page + 0 + i * 4][0]; + tx[1 + i * 4] = tag.pages[page + 1 + i * 4][1]; + tx[2 + i * 4] = tag.pages[page + 2 + i * 4][2]; + tx[3 + i * 4] = tag.pages[page + 3 + i * 4][3]; } - switch (tag.mode) { - case HT_STANDARD: - sof_bits = 1; - m = MC4K; - break; - case HT_ADVANCED: - sof_bits = 6; - m = MC4K; - break; - case HT_FAST_ADVANCED: - sof_bits = 6; - m = MC8K; - break; - default: - break; - } + hitagS_set_frame_modulation(); if (tag.mode != HT_STANDARD) { //add crc8 @@ -604,29 +556,16 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen, tx[16] = crc; } - if ((page - 4) % 4 != 0 || (tag.LKP && (page - 4) == 0)) { + if ((page) % 4 != 0 || (tag.LKP && (page) == 0)) { sof_bits = 0; *txlen = 0; } } else if ((rx[0] & 0xf0) == 0x80) { //write page uint8_t page = ((rx[0] & 0x0f) * 16) + ((rx[1] & 0xf0) / 16); + if (DBGLEVEL >= DBG_EXTENDED) + Dbprintf("....write page: %i", page); - switch (tag.mode) { - case HT_STANDARD: - sof_bits = 1; - m = MC4K; - break; - case HT_ADVANCED: - sof_bits = 6; - m = MC4K; - break; - case HT_FAST_ADVANCED: - sof_bits = 6; - m = MC8K; - break; - default: - break; - } + hitagS_set_frame_modulation(); if ((tag.LCON && page == 1) || (tag.LKP && (page == 2 || page == 3))) { //deny @@ -641,22 +580,9 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen, } else if ((rx[0] & 0xf0) == 0x90) { //write block uint8_t page = ((rx[0] & 0x0f) * 6) + ((rx[1] & 0xf0) / 16); - switch (tag.mode) { - case HT_STANDARD: - sof_bits = 1; - m = MC4K; - break; - case HT_ADVANCED: - sof_bits = 6; - m = MC4K; - break; - case HT_FAST_ADVANCED: - sof_bits = 6; - m = MC8K; - break; - default: - break; - } + if (DBGLEVEL >= DBG_EXTENDED) + Dbprintf("....write block: %i", page); + hitagS_set_frame_modulation(); if (page % 4 != 0 || page == 0) { //deny *txlen = 0; @@ -672,11 +598,8 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen, } break; default: - if (DBGLEVEL >= DBG_EXTENDED) { - Dbprintf("rxlen: %i", rxlen); - for (int i = 0; i < 4; i++) - Dbprintf("%i: %02X",i,rx[i]); - } + if (DBGLEVEL >= DBG_EXTENDED) + Dbprintf("unknown rxlen: (%i) %02X %02X %02X %02X", rxlen, rx[0], rx[1], rx[2], rx[3]); break; } } @@ -962,14 +885,16 @@ void SimulateHitagSTag(bool tag_mem_supplied, uint8_t *data) { tag.pstate = HT_READY; tag.tstate = HT_NO_OP; - for (i = 0; i < 16; i++) - for (j = 0; j < 4; j++) - tag.pages[i][j] = 0x0; - // read tag data into memory if (tag_mem_supplied) { + for (i = 0; i < 16; i++) + for (j = 0; j < 4; j++) + tag.pages[i][j] = 0x0; + DbpString("Loading hitagS memory..."); memcpy((uint8_t *)tag.pages, data, 4 * 64); + } else { + // use the last read tag } tag.uid = (tag.pages[0][3] << 24 | tag.pages[0][2] << 16 | tag.pages[0][1] << 8 | tag.pages[0][0]); @@ -981,9 +906,9 @@ void SimulateHitagSTag(bool tag_mem_supplied, uint8_t *data) { tag.pwdh0 = tag.pages[1][3]; //con0 tag.max_page = 64; - if ((tag.pages[1][3] & 0x2) == 0 && (tag.pages[1][3] & 0x1) == 1) + if ((tag.pages[1][0] & 0x2) == 0 && (tag.pages[1][0] & 0x1) == 1) tag.max_page = 8; - if ((tag.pages[1][3] & 0x2) == 0 && (tag.pages[1][3] & 0x1) == 0) + if ((tag.pages[1][0] & 0x2) == 0 && (tag.pages[1][0] & 0x1) == 0) tag.max_page = 0; if (DBGLEVEL >= DBG_EXTENDED) for (i = 0; i < tag.max_page; i++) @@ -994,41 +919,42 @@ void SimulateHitagSTag(bool tag_mem_supplied, uint8_t *data) { tag.pages[i][0] & 0xff); //con1 tag.auth = 0; - if ((tag.pages[1][2] & 0x80) == 0x80) + if ((tag.pages[1][1] & 0x80) == 0x80) tag.auth = 1; tag.LCON = 0; - if ((tag.pages[1][2] & 0x2) == 0x02) + if ((tag.pages[1][1] & 0x2) == 0x02) tag.LCON = 1; tag.LKP = 0; - if ((tag.pages[1][2] & 0x1) == 0x01) + if ((tag.pages[1][1] & 0x1) == 0x01) tag.LKP = 1; //con2 //0=read write 1=read only tag.LCK7 = 0; - if ((tag.pages[1][1] & 0x80) == 0x80) + if ((tag.pages[1][2] & 0x80) == 0x80) tag.LCK7 = 1; tag.LCK6 = 0; - if ((tag.pages[1][1] & 0x40) == 0x040) + if ((tag.pages[1][2] & 0x40) == 0x040) tag.LCK6 = 1; tag.LCK5 = 0; - if ((tag.pages[1][1] & 0x20) == 0x20) + if ((tag.pages[1][2] & 0x20) == 0x20) tag.LCK5 = 1; tag.LCK4 = 0; - if ((tag.pages[1][1] & 0x10) == 0x10) + if ((tag.pages[1][2] & 0x10) == 0x10) tag.LCK4 = 1; tag.LCK3 = 0; - if ((tag.pages[1][1] & 0x8) == 0x08) + if ((tag.pages[1][2] & 0x8) == 0x08) tag.LCK3 = 1; tag.LCK2 = 0; - if ((tag.pages[1][1] & 0x4) == 0x04) + if ((tag.pages[1][2] & 0x4) == 0x04) tag.LCK2 = 1; tag.LCK1 = 0; - if ((tag.pages[1][1] & 0x2) == 0x02) + if ((tag.pages[1][2] & 0x2) == 0x02) tag.LCK1 = 1; tag.LCK0 = 0; - if ((tag.pages[1][1] & 0x1) == 0x01) + if ((tag.pages[1][2] & 0x1) == 0x01) tag.LCK0 = 1; + // Set up simulator mode, frequency divisor which will drive the FPGA // and analog mux selection. FpgaDownloadAndGo(FPGA_BITSTREAM_LF); @@ -1060,7 +986,7 @@ void SimulateHitagSTag(bool tag_mem_supplied, uint8_t *data) { // TC1: Capture mode, default timer source = MCK/2 (TIMER_CLOCK1), TIOA is external trigger, // external trigger rising edge, load RA on rising edge of TIOA. AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK - | AT91C_TC_ETRGEDG_RISING | AT91C_TC_ABETRG | AT91C_TC_LDRA_RISING; + | AT91C_TC_ETRGEDG_RISING | AT91C_TC_ABETRG | AT91C_TC_LDRA_RISING; // Enable and reset counter AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; @@ -1132,12 +1058,13 @@ void SimulateHitagSTag(bool tag_mem_supplied, uint8_t *data) { LogTrace(tx, nbytes(txlen), 0, 0, NULL, false); } + // Enable and reset external trigger in timer for capturing future frames + AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; + // Reset the received frame and response timing info memset(rx, 0x00, sizeof(rx)); response = 0; - // Enable and reset external trigger in timer for capturing future frames - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; LED_B_OFF(); } // Reset the frame length @@ -1149,20 +1076,89 @@ void SimulateHitagSTag(bool tag_mem_supplied, uint8_t *data) { } - LEDsoff(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); set_tracing(false); - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; - AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; - + lf_finalize(); // release allocated memory from BigBuff. BigBuf_free(); - StartTicks(); - DbpString("Sim Stopped"); } +void hitagS_receive_frame(uint8_t *rx, size_t *rxlen, int *response) { + + // Reset values for receiving frames + memset(rx, 0x00, HITAG_FRAME_LEN * sizeof(uint8_t)); + *rxlen = 0; + int lastbit = 1; + bool bSkip = true; + int tag_sof = 1; + *response = 0; + uint32_t errorCount = 0; + + // Receive frame, watch for at most T0*EOF periods + while (AT91C_BASE_TC1->TC_CV < T0 * HITAG_T_WAIT_MAX) { + // Check if falling edge in tag modulation is detected + if (AT91C_BASE_TC1->TC_SR & AT91C_TC_LDRAS) { + // Retrieve the new timing values + int ra = (AT91C_BASE_TC1->TC_RA / T0); + + // Reset timer every frame, we have to capture the last edge for timing + AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; + + LED_B_ON(); + + // Capture tag frame (manchester decoding using only falling edges) + if (ra >= HITAG_T_EOF) { + if (*rxlen != 0) { + //DbpString("wierd1?"); + } + // Capture the T0 periods that have passed since last communication or field drop (reset) + // We always recieve a 'one' first, which has the falling edge after a half period |-_| + *response = ra - HITAG_T_TAG_HALF_PERIOD; + } else if (ra >= HITAG_T_TAG_CAPTURE_FOUR_HALF) { + // Manchester coding example |-_|_-|-_| (101) + rx[(*rxlen) / 8] |= 0 << (7 - ((*rxlen) % 8)); + (*rxlen)++; + rx[(*rxlen) / 8] |= 1 << (7 - ((*rxlen) % 8)); + (*rxlen)++; + } else if (ra >= HITAG_T_TAG_CAPTURE_THREE_HALF) { + // Manchester coding example |_-|...|_-|-_| (0...01) + rx[(*rxlen) / 8] |= 0 << (7 - ((*rxlen) % 8)); + (*rxlen)++; + // We have to skip this half period at start and add the 'one' the second time + if (!bSkip) { + rx[(*rxlen) / 8] |= 1 << (7 - ((*rxlen) % 8)); + (*rxlen)++; + } + lastbit = !lastbit; + bSkip = !bSkip; + } else if (ra >= HITAG_T_TAG_CAPTURE_TWO_HALF) { + // Manchester coding example |_-|_-| (00) or |-_|-_| (11) + if (tag_sof) { + // Ignore bits that are transmitted during SOF + tag_sof--; + } else { + // bit is same as last bit + rx[(*rxlen) / 8] |= lastbit << (7 - ((*rxlen) % 8)); + (*rxlen)++; + } + } else { + // Ignore wierd value, is to small to mean anything + errorCount++; + } + } + + // if we saw over 100 wierd values break it probably isn't hitag... + if (errorCount > 100) break; + + // We can break this loop if we received the last bit from a frame + if (AT91C_BASE_TC1->TC_CV > T0 * HITAG_T_EOF) { + if ((*rxlen) > 0) + break; + } + } +} + /* * Authenticates to the Tag with the given key or challenge. * If the key was given the password will be decrypted. @@ -1182,7 +1178,6 @@ void ReadHitagS(hitag_function htf, hitag_data *htd) { uint8_t *tx = txbuf; size_t txlen = 0; int lastbit = 1; - int reset_sof = 1; int t_wait = HITAG_T_WAIT_MAX; bool bStop = false; int pageNum = 0; @@ -1271,10 +1266,8 @@ void ReadHitagS(hitag_function htf, hitag_data *htd) { // synchronized startup procedure while (AT91C_BASE_TC0->TC_CV > 0); // wait until TC0 returned to zero - // Reset the received frame, frame count and timing info t_wait = 200; - while (!bStop && !BUTTON_PRESS() && !data_available()) { WDT_HIT(); @@ -1414,85 +1407,12 @@ void ReadHitagS(hitag_function htf, hitag_data *htd) { LogTrace(tx, nbytes(txlen), HITAG_T_WAIT_2, 0, NULL, true); } - // Reset values for receiving frames - memset(rx, 0x00, sizeof(rx)); - rxlen = 0; - lastbit = 1; - bool bSkip = true; - int tag_sof = reset_sof; - response = 0; - - // Receive frame, watch for at most T0*EOF periods - while (AT91C_BASE_TC1->TC_CV < T0 * HITAG_T_WAIT_MAX) { - // Check if falling edge in tag modulation is detected - if (AT91C_BASE_TC1->TC_SR & AT91C_TC_LDRAS) { - // Retrieve the new timing values - int ra = (AT91C_BASE_TC1->TC_RA / T0); - - // Reset timer every frame, we have to capture the last edge for timing - AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; - - LED_B_ON(); - - // Capture tag frame (manchester decoding using only falling edges) - if (ra >= HITAG_T_EOF) { - if (rxlen != 0) { - //DbpString("wierd1?"); - } - // Capture the T0 periods that have passed since last communication or field drop (reset) - // We always recieve a 'one' first, which has the falling edge after a half period |-_| - response = ra - HITAG_T_TAG_HALF_PERIOD; - } else if (ra >= HITAG_T_TAG_CAPTURE_FOUR_HALF) { - // Manchester coding example |-_|_-|-_| (101) - rx[rxlen / 8] |= 0 << (7 - (rxlen % 8)); - rxlen++; - rx[rxlen / 8] |= 1 << (7 - (rxlen % 8)); - rxlen++; - } else if (ra >= HITAG_T_TAG_CAPTURE_THREE_HALF) { - // Manchester coding example |_-|...|_-|-_| (0...01) - rx[rxlen / 8] |= 0 << (7 - (rxlen % 8)); - rxlen++; - // We have to skip this half period at start and add the 'one' the second time - if (!bSkip) { - rx[rxlen / 8] |= 1 << (7 - (rxlen % 8)); - rxlen++; - } - lastbit = !lastbit; - bSkip = !bSkip; - } else if (ra >= HITAG_T_TAG_CAPTURE_TWO_HALF) { - // Manchester coding example |_-|_-| (00) or |-_|-_| (11) - if (tag_sof) { - // Ignore bits that are transmitted during SOF - tag_sof--; - } else { - // bit is same as last bit - rx[rxlen / 8] |= lastbit << (7 - (rxlen % 8)); - rxlen++; - } - } else { - // Ignore wierd value, is to small to mean anything - } - } - - // We can break this loop if we received the last bit from a frame - if (AT91C_BASE_TC1->TC_CV > T0 * HITAG_T_EOF) { - if (rxlen > 0) - break; - } - } + hitagS_receive_frame(rx, &rxlen, &response); } end = false; - - LEDsoff(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); set_tracing(false); - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; - AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - - StartTicks(); - + lf_finalize(); reply_old(CMD_ACK, bSuccessful, 0, 0, 0, 0); } @@ -1512,7 +1432,6 @@ void WritePageHitagS(hitag_function htf, hitag_data *htd, int page) { uint8_t *tx = txbuf; size_t txlen = 0; int lastbit; - int reset_sof; int t_wait = HITAG_T_WAIT_MAX; bool bStop; unsigned char crc; @@ -1604,7 +1523,6 @@ void WritePageHitagS(hitag_function htf, hitag_data *htd, int page) { // Reset the received frame, frame count and timing info lastbit = 1; bStop = false; - reset_sof = 1; t_wait = 200; while (!bStop && !BUTTON_PRESS() && !data_available()) { @@ -1704,87 +1622,13 @@ void WritePageHitagS(hitag_function htf, hitag_data *htd, int page) { LogTrace(tx, nbytes(txlen), HITAG_T_WAIT_2, 0, NULL, true); } - // Reset values for receiving frames - memset(rx, 0x00, sizeof(rx)); - rxlen = 0; - lastbit = 1; - bool bSkip = true; - int tag_sof = reset_sof; - response = 0; - uint32_t errorCount = 0; + hitagS_receive_frame(rx, &rxlen, &response); - // Receive frame, watch for at most T0*EOF periods - while (AT91C_BASE_TC1->TC_CV < T0 * HITAG_T_WAIT_MAX) { - // Check if falling edge in tag modulation is detected - if (AT91C_BASE_TC1->TC_SR & AT91C_TC_LDRAS) { - // Retrieve the new timing values - int ra = (AT91C_BASE_TC1->TC_RA / T0); - - // Reset timer every frame, we have to capture the last edge for timing - AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; - - LED_B_ON(); - - // Capture tag frame (manchester decoding using only falling edges) - if (ra >= HITAG_T_EOF) { - if (rxlen != 0) { - //DbpString("wierd1?"); - } - // Capture the T0 periods that have passed since last communication or field drop (reset) - // We always recieve a 'one' first, which has the falling edge after a half period |-_| - response = ra - HITAG_T_TAG_HALF_PERIOD; - } else if (ra >= HITAG_T_TAG_CAPTURE_FOUR_HALF) { - // Manchester coding example |-_|_-|-_| (101) - rx[rxlen / 8] |= 0 << (7 - (rxlen % 8)); - rxlen++; - rx[rxlen / 8] |= 1 << (7 - (rxlen % 8)); - rxlen++; - } else if (ra >= HITAG_T_TAG_CAPTURE_THREE_HALF) { - // Manchester coding example |_-|...|_-|-_| (0...01) - rx[rxlen / 8] |= 0 << (7 - (rxlen % 8)); - rxlen++; - // We have to skip this half period at start and add the 'one' the second time - if (!bSkip) { - rx[rxlen / 8] |= 1 << (7 - (rxlen % 8)); - rxlen++; - } - lastbit = !lastbit; - bSkip = !bSkip; - } else if (ra >= HITAG_T_TAG_CAPTURE_TWO_HALF) { - // Manchester coding example |_-|_-| (00) or |-_|-_| (11) - if (tag_sof) { - // Ignore bits that are transmitted during SOF - tag_sof--; - } else { - // bit is same as last bit - rx[rxlen / 8] |= lastbit << (7 - (rxlen % 8)); - rxlen++; - } - } else { - // Ignore wierd value, is to small to mean anything - errorCount++; - } - } - - // if we saw over 100 wierd values break it probably isn't hitag... - if (errorCount > 100) break; - - // We can break this loop if we received the last bit from a frame - if (AT91C_BASE_TC1->TC_CV > T0 * HITAG_T_EOF) { - if (rxlen > 0) - break; - } - } } end = false; - LEDsoff(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); set_tracing(false); - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; - AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; - - StartTicks(); + lf_finalize(); reply_old(CMD_ACK, bSuccessful, 0, 0, 0, 0); } @@ -1807,7 +1651,7 @@ void check_challenges(bool file_given, uint8_t *data) { size_t rxlen = 0; uint8_t txbuf[HITAG_FRAME_LEN]; int t_wait = HITAG_T_WAIT_MAX; - int lastbit, reset_sof, STATE = 0;; + int lastbit, STATE = 0;; bool bStop; int response_bit[200]; unsigned char mask = 1; @@ -1868,7 +1712,6 @@ void check_challenges(bool file_given, uint8_t *data) { // Reset the received frame, frame count and timing info lastbit = 1; bStop = false; - reset_sof = 1; t_wait = 200; if (file_given) { @@ -2018,85 +1861,10 @@ void check_challenges(bool file_given, uint8_t *data) { LogTrace(tx, nbytes(txlen), HITAG_T_WAIT_2, 0, NULL, true); } - // Reset values for receiving frames - memset(rx, 0x00, sizeof(rx)); - rxlen = 0; - lastbit = 1; - bool bSkip = true; - int tag_sof = reset_sof; - response = 0; - - // Receive frame, watch for at most T0*EOF periods - while (AT91C_BASE_TC1->TC_CV < T0 * HITAG_T_WAIT_MAX) { - // Check if falling edge in tag modulation is detected - if (AT91C_BASE_TC1->TC_SR & AT91C_TC_LDRAS) { - // Retrieve the new timing values - int ra = (AT91C_BASE_TC1->TC_RA / T0); - - // Reset timer every frame, we have to capture the last edge for timing - AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; - - LED_B_ON(); - - // Capture tag frame (manchester decoding using only falling edges) - if (ra >= HITAG_T_EOF) { - if (rxlen != 0) { - //DbpString("wierd1?"); - } - // Capture the T0 periods that have passed since last communication or field drop (reset) - // We always recieve a 'one' first, which has the falling edge after a half period |-_| - response = ra - HITAG_T_TAG_HALF_PERIOD; - } else if (ra >= HITAG_T_TAG_CAPTURE_FOUR_HALF) { - // Manchester coding example |-_|_-|-_| (101) - rx[rxlen / 8] |= 0 << (7 - (rxlen % 8)); - rxlen++; - rx[rxlen / 8] |= 1 << (7 - (rxlen % 8)); - rxlen++; - } else if (ra >= HITAG_T_TAG_CAPTURE_THREE_HALF) { - // Manchester coding example |_-|...|_-|-_| (0...01) - rx[rxlen / 8] |= 0 << (7 - (rxlen % 8)); - rxlen++; - // We have to skip this half period at start and add the 'one' the second time - if (!bSkip) { - rx[rxlen / 8] |= 1 << (7 - (rxlen % 8)); - rxlen++; - } - lastbit = !lastbit; - bSkip = !bSkip; - } else if (ra >= HITAG_T_TAG_CAPTURE_TWO_HALF) { - // Manchester coding example |_-|_-| (00) or |-_|-_| (11) - if (tag_sof) { - // Ignore bits that are transmitted during SOF - tag_sof--; - } else { - // bit is same as last bit - rx[rxlen / 8] |= lastbit << (7 - (rxlen % 8)); - rxlen++; - } - } else { - // Ignore wierd value, is to small to mean anything - } - } - - // We can break this loop if we received the last bit from a frame - if (AT91C_BASE_TC1->TC_CV > T0 * HITAG_T_EOF) { - if (rxlen > 0) - break; - } - } + hitagS_receive_frame(rx, &rxlen, &response); } - LEDsoff(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); set_tracing(false); - - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; - AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; - - StartTicks(); - + lf_finalize(); reply_old(CMD_ACK, bSuccessful, 0, 0, 0, 0); } - - - From 9205b2d3906bcbb644a5e1364252f15218f1cf71 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 2 Mar 2020 11:12:13 +0100 Subject: [PATCH 1614/1854] text --- client/cmdscript.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/client/cmdscript.c b/client/cmdscript.c index 322fd6adb..4f4a372d8 100644 --- a/client/cmdscript.c +++ b/client/cmdscript.c @@ -59,11 +59,13 @@ static int CmdScriptRun(const char *Cmd) { if ((!str_endswith(preferredName, ".cmd")) && (searchFile(&script_path, LUA_SCRIPTS_SUBDIR, preferredName, ".lua", true) == PM3_SUCCESS)) { int error; if (luascriptfile_idx == MAX_NESTED_LUASCRIPT) { - PrintAndLogEx(ERR, "Too many nested scripts, skipping %s\n", script_path); + PrintAndLogEx(ERR, "too many nested scripts, skipping %s\n", script_path); free(script_path); return PM3_EMALLOC; } - PrintAndLogEx(SUCCESS, "Executing Lua script: %s, args '%s'\n", script_path, arguments); + PrintAndLogEx(SUCCESS, "executing lua " _YELLOW_("%s"), script_path); + PrintAndLogEx(SUCCESS, "args " _YELLOW_("'%s'"), arguments); + luascriptfile_idx++; // create new Lua state @@ -94,7 +96,7 @@ static int CmdScriptRun(const char *Cmd) { if (error) { // if non-0, then an error // the top of the stack should be the error string if (!lua_isstring(lua_state, lua_gettop(lua_state))) - PrintAndLogEx(FAILED, "Error - but no error (?!)"); + PrintAndLogEx(FAILED, "error - but no error (?!)"); // get the top of the stack as the error and pop it off const char *str = lua_tostring(lua_state, lua_gettop(lua_state)); @@ -106,17 +108,22 @@ static int CmdScriptRun(const char *Cmd) { // close the Lua state lua_close(lua_state); luascriptfile_idx--; - PrintAndLogEx(SUCCESS, "\nFinished %s\n", preferredName); + PrintAndLogEx(SUCCESS, "\nfinished " _YELLOW_("%s"), preferredName); return PM3_SUCCESS; } + if ((!str_endswith(preferredName, ".lua")) && (searchFile(&script_path, CMD_SCRIPTS_SUBDIR, preferredName, ".cmd", true) == PM3_SUCCESS)) { - PrintAndLogEx(SUCCESS, "Executing Cmd script: %s, args '%s'\n", script_path, arguments); + + PrintAndLogEx(SUCCESS, "executing Cmd " _YELLOW_("%s"), script_path); + PrintAndLogEx(SUCCESS, "args " _YELLOW_("'%s'"), arguments); + int ret = push_cmdscriptfile(script_path, true); if (ret != PM3_SUCCESS) PrintAndLogEx(ERR, "could not open " _YELLOW_("%s") "...", script_path); free(script_path); return ret; } + // file not found, let's search again to display the error messages int ret = PM3_EUNDEF; if (!str_endswith(preferredName, ".cmd")) ret = searchFile(&script_path, LUA_SCRIPTS_SUBDIR, preferredName, ".lua", false); @@ -141,7 +148,7 @@ static command_t CommandTable[] = { static int CmdHelp(const char *Cmd) { (void)Cmd; // Cmd is not used so far PrintAndLogEx(NORMAL, "This is a feature to run Lua-scripts. You can place Lua-scripts within the luascripts/-folder. "); - return 0; + return PM3_SUCCESS; } /** From 783d97bd09386057421e86948b3a2068735e3979 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 2 Mar 2020 13:59:41 +0100 Subject: [PATCH 1615/1854] Chg: added hint texts to lf clone commands --- client/cmdlf.c | 2 +- client/cmdlfawid.c | 5 ++++- client/cmdlfem4x.c | 12 +++++++++--- client/cmdlffdx.c | 5 ++++- client/cmdlfgallagher.c | 5 ++++- client/cmdlfhid.c | 3 ++- client/cmdlfindala.c | 5 ++++- client/cmdlfio.c | 5 ++++- client/cmdlfkeri.c | 5 ++++- client/cmdlfmotorola.c | 5 ++++- client/cmdlfnedap.c | 2 ++ client/cmdlfnexwatch.c | 6 ++++-- client/cmdlft55xx.c | 1 - 13 files changed, 46 insertions(+), 15 deletions(-) diff --git a/client/cmdlf.c b/client/cmdlf.c index b83ed0c89..f153ba1c3 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -1339,10 +1339,10 @@ static command_t CommandTable[] = { {"io", CmdLFIO, AlwaysAvailable, "{ ioProx RFIDs... }"}, {"jablotron", CmdLFJablotron, AlwaysAvailable, "{ Jablotron RFIDs... }"}, {"keri", CmdLFKeri, AlwaysAvailable, "{ KERI RFIDs... }"}, + {"motorola", CmdLFMotorola, AlwaysAvailable, "{ Motorola RFIDs... }"}, {"nedap", CmdLFNedap, AlwaysAvailable, "{ Nedap RFIDs... }"}, {"nexwatch", CmdLFNEXWATCH, AlwaysAvailable, "{ NexWatch RFIDs... }"}, {"noralsy", CmdLFNoralsy, AlwaysAvailable, "{ Noralsy RFIDs... }"}, - {"motorola", CmdLFMotorola, AlwaysAvailable, "{ Motorola RFIDs... }"}, {"pac", CmdLFPac, AlwaysAvailable, "{ PAC/Stanley RFIDs... }"}, {"paradox", CmdLFParadox, AlwaysAvailable, "{ Paradox RFIDs... }"}, {"pcf7931", CmdLFPCF7931, AlwaysAvailable, "{ PCF7931 CHIPs... }"}, diff --git a/client/cmdlfawid.c b/client/cmdlfawid.c index 38c3675d1..9bcf9e874 100644 --- a/client/cmdlfawid.c +++ b/client/cmdlfawid.c @@ -422,7 +422,10 @@ static int CmdAWIDClone(const char *Cmd) { PrintAndLogEx(INFO, "Preparing to clone AWID %u to T55x7 with FC: %u, CN: %u", fmtlen, fc, cn); print_blocks(blocks, ARRAYLEN(blocks)); - return clone_t55xx_tag(blocks, ARRAYLEN(blocks)); + int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks)); + PrintAndLogEx(SUCCESS, "Done"); + PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf awid read`") "to verify"); + return res; } static int CmdAWIDBrute(const char *Cmd) { diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c index a8d7e06e3..9b7fe51de 100644 --- a/client/cmdlfem4x.c +++ b/client/cmdlfem4x.c @@ -700,6 +700,8 @@ static int CmdEM410xWrite(const char *Cmd) { } SendCommandMIX(CMD_LF_EM410X_WRITE, card, (uint32_t)(id >> 32), (uint32_t)id, NULL, 0); + PrintAndLogEx(SUCCESS, "Done"); + PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf em 410x_read`") "to verify"); return PM3_SUCCESS; } @@ -1037,6 +1039,9 @@ static int CmdEM4x50Write(const char *Cmd) { uint8_t ctmp = tolower(param_getchar(Cmd, 0)); if (ctmp == 'h') return usage_lf_em4x50_write(); PrintAndLogEx(NORMAL, "no implemented yet"); +// +// PrintAndLogEx(SUCCESS, "Done"); +// PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf em 4x50_read`") "to verify"); return PM3_SUCCESS; } @@ -1434,9 +1439,10 @@ static int CmdEM4x05Write(const char *Cmd) { uint32_t dummy = 0; int status = demodEM4x05resp(&dummy); if (status == PM3_SUCCESS) - PrintAndLogEx(NORMAL, "Write " _GREEN_("Verified")); - else - PrintAndLogEx(NORMAL, "Write could " _RED_("not") "be verified"); + PrintAndLogEx(SUCCESS, "Success writing to tag"); + + PrintAndLogEx(SUCCESS, "Done"); + PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf em 4x05_read`") "to verify"); return status; } static int CmdEM4x05Wipe(const char *Cmd) { diff --git a/client/cmdlffdx.c b/client/cmdlffdx.c index 2f3f81d1d..11ec2dd64 100644 --- a/client/cmdlffdx.c +++ b/client/cmdlffdx.c @@ -301,7 +301,10 @@ static int CmdFdxClone(const char *Cmd) { PrintAndLogEx(INFO, "Preparing to clone FDX-B to T55x7 with animal ID: %04u-%"PRIu64, countryid, animalid); print_blocks(blocks, ARRAYLEN(blocks)); - return clone_t55xx_tag(blocks, ARRAYLEN(blocks)); + int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks)); + PrintAndLogEx(SUCCESS, "Done"); + PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf fdx read`") "to verify"); + return res; } static int CmdFdxSim(const char *Cmd) { diff --git a/client/cmdlfgallagher.c b/client/cmdlfgallagher.c index ef28f1326..e44682e2b 100644 --- a/client/cmdlfgallagher.c +++ b/client/cmdlfgallagher.c @@ -178,7 +178,10 @@ static int CmdGallagherClone(const char *Cmd) { PrintAndLogEx(INFO, "Preparing to clone Gallagher to T55x7 with raw hex"); print_blocks(blocks, ARRAYLEN(blocks)); - return clone_t55xx_tag(blocks, ARRAYLEN(blocks)); + int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks)); + PrintAndLogEx(SUCCESS, "Done"); + PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf gallagher read`") "to verify"); + return res; } static int CmdGallagherSim(const char *Cmd) { diff --git a/client/cmdlfhid.c b/client/cmdlfhid.c index 3a4d16cf3..dbe027dc3 100644 --- a/client/cmdlfhid.c +++ b/client/cmdlfhid.c @@ -345,7 +345,8 @@ static int CmdHIDClone(const char *Cmd) { clearCommandBuffer(); SendCommandMIX(CMD_LF_HID_CLONE, hi2, hi, lo, longid, sizeof(longid)); - PrintAndLogEx(INFO, "Clone command sent. Try "_YELLOW_("'lf hid read'") " to verify"); + PrintAndLogEx(SUCCESS, "Done"); + PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf hid read`") "to verify"); return PM3_SUCCESS; } diff --git a/client/cmdlfindala.c b/client/cmdlfindala.c index 9aa98524c..01eb4b8f8 100644 --- a/client/cmdlfindala.c +++ b/client/cmdlfindala.c @@ -620,7 +620,10 @@ static int CmdIndalaClone(const char *Cmd) { } print_blocks(blocks, max); - return clone_t55xx_tag(blocks, max); + int res = clone_t55xx_tag(blocks, max); + PrintAndLogEx(SUCCESS, "Done"); + PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf indala read`") "to verify"); + return res; } static command_t CommandTable[] = { diff --git a/client/cmdlfio.c b/client/cmdlfio.c index 1a25fca17..994c69a7d 100644 --- a/client/cmdlfio.c +++ b/client/cmdlfio.c @@ -275,7 +275,10 @@ static int CmdIOProxClone(const char *Cmd) { PrintAndLogEx(INFO, "Preparing to clone IOProx to T55x7 with Version: %u FC: %u, CN: %u", version, fc, cn); print_blocks(blocks, ARRAYLEN(blocks)); - return clone_t55xx_tag(blocks, ARRAYLEN(blocks)); + int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks)); + PrintAndLogEx(SUCCESS, "Done"); + PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf io read`") "to verify"); + return res; } static command_t CommandTable[] = { diff --git a/client/cmdlfkeri.c b/client/cmdlfkeri.c index 4a0c3c8fd..3c7863361 100644 --- a/client/cmdlfkeri.c +++ b/client/cmdlfkeri.c @@ -280,7 +280,10 @@ static int CmdKeriClone(const char *Cmd) { print_blocks(blocks, ARRAYLEN(blocks)); - return clone_t55xx_tag(blocks, ARRAYLEN(blocks)); + int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks)); + PrintAndLogEx(SUCCESS, "Done"); + PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf keri read`") "to verify"); + return res; } static int CmdKeriSim(const char *Cmd) { diff --git a/client/cmdlfmotorola.c b/client/cmdlfmotorola.c index 9f0ee1f41..c34b48d8e 100644 --- a/client/cmdlfmotorola.c +++ b/client/cmdlfmotorola.c @@ -177,7 +177,10 @@ static int CmdMotorolaClone(const char *Cmd) { blocks[2] = bytes_to_num(data + 4, 4); print_blocks(blocks, ARRAYLEN(blocks)); - return clone_t55xx_tag(blocks, ARRAYLEN(blocks)); + int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks)); + PrintAndLogEx(SUCCESS, "Done"); + PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf motorola read`") "to verify"); + return res; } static int CmdMotorolaSim(const char *Cmd) { diff --git a/client/cmdlfnedap.c b/client/cmdlfnedap.c index c3d6d1ace..a1d23cd91 100644 --- a/client/cmdlfnedap.c +++ b/client/cmdlfnedap.c @@ -475,6 +475,8 @@ static int CmdLFNedapClone(const char *Cmd) { } else { PrintAndLogEx(NORMAL, ""); } + PrintAndLogEx(SUCCESS, "Done"); + PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf nedap read`") "to verify"); return res; } diff --git a/client/cmdlfnexwatch.c b/client/cmdlfnexwatch.c index 68be0e0bc..d288eeadc 100644 --- a/client/cmdlfnexwatch.c +++ b/client/cmdlfnexwatch.c @@ -158,8 +158,10 @@ static int CmdNexWatchClone(const char *Cmd) { PrintAndLogEx(INFO, "Preparing to clone NexWatch to T55x7 with raw hex"); print_blocks(blocks, ARRAYLEN(blocks)); - return clone_t55xx_tag(blocks, ARRAYLEN(blocks)); - + int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks)); + PrintAndLogEx(SUCCESS, "Done"); + PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf nexwatch read`") "to verify"); + return res; } static int CmdNexWatchSim(const char *Cmd) { diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index f25626d94..c88b8a051 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -1028,7 +1028,6 @@ void T55xx_Print_DownlinkMode(uint8_t downlink_mode) { PrintAndLogEx(NORMAL, msg); } - static int CmdT55xxDetect(const char *Cmd) { bool errors = false; From 61e6ff6991169fd072b31a82a7372d6902db4040 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 2 Mar 2020 14:15:51 +0100 Subject: [PATCH 1616/1854] chg: added hint text for lf clone part2 --- client/cmdlfnoralsy.c | 5 ++++- client/cmdlfpac.c | 5 ++++- client/cmdlfparadox.c | 5 ++++- client/cmdlfpcf7931.c | 47 ++++++++++++++++++++++------------------- client/cmdlfpresco.c | 5 ++++- client/cmdlfpyramid.c | 5 ++++- client/cmdlfsecurakey.c | 5 ++++- client/cmdlfti.c | 2 ++ client/cmdlfverichip.c | 5 ++++- client/cmdlfviking.c | 2 ++ client/cmdlfvisa2000.c | 5 ++++- 11 files changed, 61 insertions(+), 30 deletions(-) diff --git a/client/cmdlfnoralsy.c b/client/cmdlfnoralsy.c index d7728a3d9..bbb7de0c9 100644 --- a/client/cmdlfnoralsy.c +++ b/client/cmdlfnoralsy.c @@ -169,7 +169,10 @@ static int CmdNoralsyClone(const char *Cmd) { PrintAndLogEx(INFO, "Preparing to clone Noralsy to T55x7 with CardId: %u", id); print_blocks(blocks, ARRAYLEN(blocks)); - return clone_t55xx_tag(blocks, ARRAYLEN(blocks)); + int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks)); + PrintAndLogEx(SUCCESS, "Done"); + PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf noralsy read`") "to verify"); + return res; } static int CmdNoralsySim(const char *Cmd) { diff --git a/client/cmdlfpac.c b/client/cmdlfpac.c index 24c549a4b..9ac9aa511 100644 --- a/client/cmdlfpac.c +++ b/client/cmdlfpac.c @@ -239,7 +239,10 @@ static int CmdPacClone(const char *Cmd) { PrintAndLogEx(INFO, "Preparing to clone PAC/Stanley tag to T55x7 with raw hex"); print_blocks(blocks, ARRAYLEN(blocks)); - return clone_t55xx_tag(blocks, ARRAYLEN(blocks)); + int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks)); + PrintAndLogEx(SUCCESS, "Done"); + PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf pac read`") "to verify"); + return res; } static int CmdPacSim(const char *Cmd) { diff --git a/client/cmdlfparadox.c b/client/cmdlfparadox.c index 29e247b59..12c1bc9b8 100644 --- a/client/cmdlfparadox.c +++ b/client/cmdlfparadox.c @@ -169,7 +169,10 @@ static int CmdParadoxClone(const char *Cmd) { PrintAndLogEx(INFO, "Preparing to clone Paradox to T55x7 with raw hex"); print_blocks(blocks, ARRAYLEN(blocks)); - return clone_t55xx_tag(blocks, ARRAYLEN(blocks)); + int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks)); + PrintAndLogEx(SUCCESS, "Done"); + PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf paradox read`") "to verify"); + return res; } static int CmdParadoxSim(const char *Cmd) { diff --git a/client/cmdlfpcf7931.c b/client/cmdlfpcf7931.c index e4a14a47e..ddcad195d 100644 --- a/client/cmdlfpcf7931.c +++ b/client/cmdlfpcf7931.c @@ -11,6 +11,7 @@ #include "cmdlfpcf7931.h" #include +#include #include "cmdparser.h" // command_t #include "comms.h" @@ -36,7 +37,7 @@ int pcf7931_resetConfig() { configPcf.InitDelay = PCF7931_DEFAULT_INITDELAY; configPcf.OffsetWidth = PCF7931_DEFAULT_OFFSET_WIDTH; configPcf.OffsetPosition = PCF7931_DEFAULT_OFFSET_POSITION; - return 0; + return PM3_SUCCESS; } int pcf7931_printConfig() { @@ -44,7 +45,7 @@ int pcf7931_printConfig() { PrintAndLogEx(NORMAL, "Tag initialization delay : %d us", configPcf.InitDelay); PrintAndLogEx(NORMAL, "Offset low pulses width : %d us", configPcf.OffsetWidth); PrintAndLogEx(NORMAL, "Offset low pulses position : %d us", configPcf.OffsetPosition); - return 0; + return PM3_SUCCESS; } static int usage_pcf7931_read() { @@ -54,7 +55,7 @@ static int usage_pcf7931_read() { PrintAndLogEx(NORMAL, " h This help"); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf pcf7931 read"); - return 0; + return PM3_SUCCESS; } static int usage_pcf7931_write() { @@ -67,7 +68,7 @@ static int usage_pcf7931_write() { PrintAndLogEx(NORMAL, " data one byte of data (hex)"); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf pcf7931 write 2 1 FF"); - return 0; + return PM3_SUCCESS; } static int usage_pcf7931_config() { @@ -87,30 +88,30 @@ static int usage_pcf7931_config() { PrintAndLogEx(NORMAL, " lf pcf7931 config r"); PrintAndLogEx(NORMAL, " lf pcf7931 config 11223344556677 20000"); PrintAndLogEx(NORMAL, " lf pcf7931 config 11223344556677 17500 -10 30"); - return 0; + return PM3_SUCCESS; } static int CmdLFPCF7931Read(const char *Cmd) { - uint8_t ctmp = param_getchar(Cmd, 0); - if (ctmp == 'H' || ctmp == 'h') return usage_pcf7931_read(); + uint8_t ctmp = tolower(param_getchar(Cmd, 0)); + if (ctmp == 'h') return usage_pcf7931_read(); PacketResponseNG resp; clearCommandBuffer(); SendCommandNG(CMD_LF_PCF7931_READ, NULL, 0); if (!WaitForResponseTimeout(CMD_ACK, &resp, 2500)) { PrintAndLogEx(WARNING, "command execution time out"); - return 1; + return PM3_ETIMEOUT; } - return 0; + return PM3_SUCCESS; } static int CmdLFPCF7931Config(const char *Cmd) { - uint8_t ctmp = param_getchar(Cmd, 0); + uint8_t ctmp = tolower(param_getchar(Cmd, 0)); if (ctmp == 0) return pcf7931_printConfig(); - if (ctmp == 'H' || ctmp == 'h') return usage_pcf7931_config(); - if (ctmp == 'R' || ctmp == 'r') return pcf7931_resetConfig(); + if (ctmp == 'h') return usage_pcf7931_config(); + if (ctmp == 'r') return pcf7931_resetConfig(); if (param_gethex(Cmd, 0, configPcf.Pwd, 14)) return usage_pcf7931_config(); @@ -119,13 +120,13 @@ static int CmdLFPCF7931Config(const char *Cmd) { configPcf.OffsetPosition = (int)(param_get32ex(Cmd, 3, 0, 10) & 0xFFFF); pcf7931_printConfig(); - return 0; + return PM3_SUCCESS; } static int CmdLFPCF7931Write(const char *Cmd) { - uint8_t ctmp = param_getchar(Cmd, 0); - if (strlen(Cmd) < 1 || ctmp == 'h' || ctmp == 'H') return usage_pcf7931_write(); + uint8_t ctmp = tolower(param_getchar(Cmd, 0)); + if (strlen(Cmd) < 1 || ctmp == 'h') return usage_pcf7931_write(); uint8_t block = 0, bytepos = 0, data = 0; @@ -136,9 +137,9 @@ static int CmdLFPCF7931Write(const char *Cmd) { data = param_get8ex(Cmd, 2, 0, 16); - PrintAndLogEx(NORMAL, "Writing block: %d", block); - PrintAndLogEx(NORMAL, " pos: %d", bytepos); - PrintAndLogEx(NORMAL, " data: 0x%02X", data); + PrintAndLogEx(INFO, "Writing block: %d", block); + PrintAndLogEx(INFO, " pos: %d", bytepos); + PrintAndLogEx(INFO, " data: 0x%02X", data); uint32_t buf[10]; // TODO sparse struct, 7 *bytes* then words at offset 4*7! memcpy(buf, configPcf.Pwd, sizeof(configPcf.Pwd)); @@ -147,9 +148,11 @@ static int CmdLFPCF7931Write(const char *Cmd) { buf[9] = configPcf.InitDelay; clearCommandBuffer(); - SendCommandOLD(CMD_LF_PCF7931_WRITE, block, bytepos, data, buf, sizeof(buf)); - //no ack? - return 0; + SendCommandMIX(CMD_LF_PCF7931_WRITE, block, bytepos, data, buf, sizeof(buf)); + + PrintAndLogEx(SUCCESS, "Done"); + PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf pcf7931 read`") "to verify"); + return PM3_SUCCESS; } static command_t CommandTable[] = { @@ -163,7 +166,7 @@ static command_t CommandTable[] = { static int CmdHelp(const char *Cmd) { (void)Cmd; // Cmd is not used so far CmdsHelp(CommandTable); - return 0; + return PM3_SUCCESS; } int CmdLFPCF7931(const char *Cmd) { diff --git a/client/cmdlfpresco.c b/client/cmdlfpresco.c index a0619d794..9f00dbdce 100644 --- a/client/cmdlfpresco.c +++ b/client/cmdlfpresco.c @@ -136,7 +136,10 @@ static int CmdPrescoClone(const char *Cmd) { PrintAndLogEx(INFO, "Preparing to clone Presco to T55x7 with SiteCode: %u, UserCode: %u, FullCode: %08x", sitecode, usercode, fullcode); print_blocks(blocks, ARRAYLEN(blocks)); - return clone_t55xx_tag(blocks, ARRAYLEN(blocks)); + int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks)); + PrintAndLogEx(SUCCESS, "Done"); + PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf presco read`") "to verify"); + return res; } // takes base 12 ID converts to hex diff --git a/client/cmdlfpyramid.c b/client/cmdlfpyramid.c index 5737c87b9..14357201a 100644 --- a/client/cmdlfpyramid.c +++ b/client/cmdlfpyramid.c @@ -250,7 +250,10 @@ static int CmdPyramidClone(const char *Cmd) { PrintAndLogEx(INFO, "Preparing to clone Farpointe/Pyramid to T55x7 with Facility Code: %u, Card Number: %u", facilitycode, cardnumber); print_blocks(blocks, ARRAYLEN(blocks)); - return clone_t55xx_tag(blocks, ARRAYLEN(blocks)); + int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks)); + PrintAndLogEx(SUCCESS, "Done"); + PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf pyramid read`") "to verify"); + return res; } static int CmdPyramidSim(const char *Cmd) { diff --git a/client/cmdlfsecurakey.c b/client/cmdlfsecurakey.c index ef4b5be8e..0061d56c4 100644 --- a/client/cmdlfsecurakey.c +++ b/client/cmdlfsecurakey.c @@ -168,7 +168,10 @@ static int CmdSecurakeyClone(const char *Cmd) { PrintAndLogEx(INFO, "Preparing to clone Securakey to T55x7 with raw hex"); print_blocks(blocks, ARRAYLEN(blocks)); - return clone_t55xx_tag(blocks, ARRAYLEN(blocks)); + int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks)); + PrintAndLogEx(SUCCESS, "Done"); + PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf securakey read`") "to verify"); + return res; } static int CmdSecurakeySim(const char *Cmd) { diff --git a/client/cmdlfti.c b/client/cmdlfti.c index cf01abb73..8507fa36a 100644 --- a/client/cmdlfti.c +++ b/client/cmdlfti.c @@ -296,6 +296,8 @@ static int CmdTIWrite(const char *Cmd) { } clearCommandBuffer(); SendCommandMIX(CMD_LF_TI_WRITE, arg0, arg1, arg2, NULL, 0); + PrintAndLogEx(SUCCESS, "Done"); + PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf ti read`") "to verify"); return PM3_SUCCESS; } diff --git a/client/cmdlfverichip.c b/client/cmdlfverichip.c index fb2e4e777..91b49b8f4 100644 --- a/client/cmdlfverichip.c +++ b/client/cmdlfverichip.c @@ -121,7 +121,10 @@ static int CmdVerichipClone(const char *Cmd) { PrintAndLogEx(INFO, "Preparing to clone Verichip to T55x7 with raw hex"); print_blocks(blocks, ARRAYLEN(blocks)); - return clone_t55xx_tag(blocks, ARRAYLEN(blocks)); + int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks)); + PrintAndLogEx(SUCCESS, "Done"); + PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf verichip read`") "to verify"); + return res; } static int CmdVerichipSim(const char *Cmd) { diff --git a/client/cmdlfviking.c b/client/cmdlfviking.c index 69d8aee65..407c28f7e 100644 --- a/client/cmdlfviking.c +++ b/client/cmdlfviking.c @@ -117,6 +117,8 @@ static int CmdVikingClone(const char *Cmd) { PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); return PM3_ETIMEOUT; } + PrintAndLogEx(SUCCESS, "Done"); + PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf viking read`") "to verify"); return resp.status; } diff --git a/client/cmdlfvisa2000.c b/client/cmdlfvisa2000.c index 551a1efbb..1a628e51d 100644 --- a/client/cmdlfvisa2000.c +++ b/client/cmdlfvisa2000.c @@ -184,7 +184,10 @@ static int CmdVisa2kClone(const char *Cmd) { PrintAndLogEx(INFO, "Preparing to clone Visa2000 to T55x7 with CardId: %"PRIu64, id); print_blocks(blocks, ARRAYLEN(blocks)); - return clone_t55xx_tag(blocks, ARRAYLEN(blocks)); + int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks)); + PrintAndLogEx(SUCCESS, "Done"); + PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf visa2000 read`") "to verify"); + return res; } static int CmdVisa2kSim(const char *Cmd) { From ce88d8b3ae45ff9d1706ae3c3478214762a01e14 Mon Sep 17 00:00:00 2001 From: Joan Bono Date: Mon, 2 Mar 2020 16:02:48 +0100 Subject: [PATCH 1617/1854] Update cmdlfparadox.c --- client/cmdlfparadox.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdlfparadox.c b/client/cmdlfparadox.c index 12c1bc9b8..c540290f8 100644 --- a/client/cmdlfparadox.c +++ b/client/cmdlfparadox.c @@ -36,7 +36,7 @@ static int usage_lf_paradox_clone(void) { PrintAndLogEx(NORMAL, " b : raw hex data. 12 bytes max"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " lf paradox clone 0f55555695596a6a9999a59a"); + PrintAndLogEx(NORMAL, " lf paradox clone b 0f55555695596a6a9999a59a"); return PM3_SUCCESS; } From 48971fdd5b276959cbb746e8f6c121d5d09aebda Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 2 Mar 2020 16:46:20 +0100 Subject: [PATCH 1618/1854] text --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8015a76f5..8896f223c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,8 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] - - Chnage `lf keri demod` - adjusted the internal id. (@mwalker33) + - Change - hint texts added to all lf clone commands (@iceman1001) + - Change `lf keri demod` - adjusted the internal id. (@mwalker33) - Added seamless integration with cryptohelper (@iceman1001) - Change `lf hid brute` - new params for direction (UP/DOWN); textual and main loop actually exit. (@capnkrunchy and @iceman1001) - Fix `lf hid brute` - made it work again (@capnkrunchy) From 1794acc65892c5ea33559452a4e65e56b0525ab3 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 2 Mar 2020 16:47:55 +0100 Subject: [PATCH 1619/1854] #586 - ignore html files --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 349ef5efb..1b352bcfe 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ .profile *.log *.eml +*.html *.o *.a *.d From 201f4acb8fb935a910d274e7388abc5a2526982f Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 5 Mar 2020 09:24:11 +0530 Subject: [PATCH 1620/1854] highlight first doc to read --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 96a8d2693..e48802b81 100644 --- a/README.md +++ b/README.md @@ -11,10 +11,10 @@ | FAQ's & Updates | Installation | Use of the Proxmark | | ------------------- |:-------------------:| -------------------:| -|[What has changed?](#what-has-changed) | [Setup and build for Linux](/doc/md/Installation_Instructions/Linux-Installation-Instructions.md) | [Compilation Instructions](/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md)| -|[Development](#development) | [Important notes on ModemManager for Linux users](/doc/md/Installation_Instructions/ModemManager-Must-Be-Discarded.md) | [Validating proxmark client functionality](/doc/md/Use_of_Proxmark/1_Validation.md) | -|[Why didn't you base it on official Proxmark3 Master?](#why-didnt-you-base-it-on-official-proxmark3-master)| [Homebrew (Mac OS X) & Upgrading HomeBrew Tap Formula](/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md) | [First Use and Verification](/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md)| -|[Proxmark3 GUI](#proxmark3-gui)|[Setup and build for Windows](/doc/md/Installation_Instructions/Windows-Installation-Instructions.md)|[Commands & Features](/doc/md/Use_of_Proxmark/3_Commands-and-Features.md)| +|[What has changed?](#what-has-changed) | **[Setup and build for Linux](/doc/md/Installation_Instructions/Linux-Installation-Instructions.md)** | [Compilation Instructions](/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md)| +|[Development](#development) | **[Important notes on ModemManager for Linux users](/doc/md/Installation_Instructions/ModemManager-Must-Be-Discarded.md)** | [Validating proxmark client functionality](/doc/md/Use_of_Proxmark/1_Validation.md) | +|[Why didn't you base it on official Proxmark3 Master?](#why-didnt-you-base-it-on-official-proxmark3-master)| **[Homebrew (Mac OS X) & Upgrading HomeBrew Tap Formula](/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md)** | [First Use and Verification](/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md)| +|[Proxmark3 GUI](#proxmark3-gui)|**[Setup and build for Windows](/doc/md/Installation_Instructions/Windows-Installation-Instructions.md)**|[Commands & Features](/doc/md/Use_of_Proxmark/3_Commands-and-Features.md)| |[Issues](#issues)|[Blue shark manual](/doc/bt_manual_v10.md) |[Advanced compilation parameters](/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md)| |[Notes on UART](/doc/uart_notes.md)|[Maintainers](/doc/md/Development/Maintainers.md)|[Command Cheat sheet](/doc/cheatsheet.md)| |[Notes on frame format](/doc/new_frame_format.md)||[More cheat sheets](https://github.com/RfidResearchGroup/proxmark3/wiki/More-cheat-sheets)| From b6dcfbf078bb8595f0c03e079b058b2410381025 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 5 Mar 2020 11:16:05 +0100 Subject: [PATCH 1621/1854] =?UTF-8?q?chg:=20allow=20to=20download=20=C2=B4?= =?UTF-8?q?lf=20config=C2=B4=20settings=20to=20client?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- armsrc/appmain.c | 9 ++++++++- armsrc/lfsampling.c | 2 +- client/cmdlf.c | 21 ++++++++++++++++++++- client/cmdlf.h | 1 + include/pm3_cmd.h | 3 ++- 5 files changed, 32 insertions(+), 4 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 415e03291..88c85ad57 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -721,10 +721,17 @@ static void PacketReceived(PacketCommandNG *packet) { setT55xxConfig(packet->oldarg[0], (t55xx_configurations_t *) packet->data.asBytes); break; } - case CMD_LF_SAMPLING_GET_CONFIG: { + case CMD_LF_SAMPLING_PRINT_CONFIG: { printConfig(); break; } + case CMD_LF_SAMPLING_GET_CONFIG: { + sample_config *c; + c = getSamplingConfig(); + Dbprintf("CMD_LF_SAMPLING_GET_CONFIG - before answer"); + reply_ng(CMD_LF_SAMPLING_GET_CONFIG, PM3_SUCCESS, (uint8_t *)c, sizeof(sample_config)); + break; + } case CMD_LF_SAMPLING_SET_CONFIG: { sample_config c; memcpy(&c, packet->data.asBytes, sizeof(sample_config)); diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index 2e33ec434..3ce7bc5da 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -81,7 +81,7 @@ void setSamplingConfig(sample_config *sc) { printConfig(); } -sample_config *getSamplingConfig() { +sample_config *getSamplingConfig(void) { return &config; } diff --git a/client/cmdlf.c b/client/cmdlf.c index f153ba1c3..c44764fd0 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -457,6 +457,25 @@ int CmdFlexdemod(const char *Cmd) { return PM3_SUCCESS; } +int lf_getconfig(sample_config *config) { + if (!session.pm3_present) return PM3_ENOTTY; + + if (config == NULL) + return PM3_EINVARG; + + clearCommandBuffer(); + + SendCommandNG(CMD_LF_SAMPLING_GET_CONFIG, NULL, 0); + PacketResponseNG resp; + if (!WaitForResponseTimeout(CMD_LF_SAMPLING_GET_CONFIG, &resp, 2000)) { + PrintAndLogEx(WARNING, "command execution time out"); + return PM3_ETIMEOUT; + } + + config = (sample_config *) resp.data.asBytes; + return PM3_SUCCESS; +} + int lf_config(sample_config *config) { if (!session.pm3_present) return PM3_ENOTTY; @@ -464,7 +483,7 @@ int lf_config(sample_config *config) { if (config != NULL) SendCommandNG(CMD_LF_SAMPLING_SET_CONFIG, (uint8_t *)config, sizeof(sample_config)); else - SendCommandNG(CMD_LF_SAMPLING_GET_CONFIG, NULL, 0); + SendCommandNG(CMD_LF_SAMPLING_PRINT_CONFIG, NULL, 0); return PM3_SUCCESS; } diff --git a/client/cmdlf.h b/client/cmdlf.h index 7393405ba..bb0628609 100644 --- a/client/cmdlf.h +++ b/client/cmdlf.h @@ -34,5 +34,6 @@ int CmdLFfind(const char *Cmd); int lf_read(bool verbose, uint32_t samples); int lf_config(sample_config *config); +int lf_getconfig(sample_config *config); #endif diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 32b2ba35c..cff1f891f 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -392,7 +392,8 @@ typedef struct { #define CMD_LF_T55XX_WAKEUP 0x0224 #define CMD_LF_COTAG_READ 0x0225 #define CMD_LF_T55XX_SET_CONFIG 0x0226 -#define CMD_LF_SAMPLING_GET_CONFIG 0x0227 +#define CMD_LF_SAMPLING_PRINT_CONFIG 0x0227 +#define CMD_LF_SAMPLING_GET_CONFIG 0x0228 #define CMD_LF_T55XX_CHK_PWDS 0x0230 #define CMD_LF_T55XX_DANGERRAW 0x0231 From 393d998ad95ec3a0460c144e89176b2bc4b67385 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 5 Mar 2020 11:27:42 +0100 Subject: [PATCH 1622/1854] fix downloading lf config --- armsrc/appmain.c | 6 ++---- client/cmdlf.c | 3 +-- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 88c85ad57..1c76fad7d 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -726,10 +726,8 @@ static void PacketReceived(PacketCommandNG *packet) { break; } case CMD_LF_SAMPLING_GET_CONFIG: { - sample_config *c; - c = getSamplingConfig(); - Dbprintf("CMD_LF_SAMPLING_GET_CONFIG - before answer"); - reply_ng(CMD_LF_SAMPLING_GET_CONFIG, PM3_SUCCESS, (uint8_t *)c, sizeof(sample_config)); + sample_config *config = getSamplingConfig(); + reply_ng(CMD_LF_SAMPLING_GET_CONFIG, PM3_SUCCESS, (uint8_t *)config, sizeof(sample_config)); break; } case CMD_LF_SAMPLING_SET_CONFIG: { diff --git a/client/cmdlf.c b/client/cmdlf.c index c44764fd0..7fa73818d 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -471,8 +471,7 @@ int lf_getconfig(sample_config *config) { PrintAndLogEx(WARNING, "command execution time out"); return PM3_ETIMEOUT; } - - config = (sample_config *) resp.data.asBytes; + memcpy(config, resp.data.asBytes, sizeof(sample_config)); return PM3_SUCCESS; } From df6bc7e9f3e75c13c7afb95f3eff17912849956d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marlin=20S=C3=B6=C3=B6se?= <30473690+msoose@users.noreply.github.com> Date: Fri, 6 Mar 2020 10:58:18 +0800 Subject: [PATCH 1623/1854] Update mfc_default_keys.dic add key --- client/dictionaries/mfc_default_keys.dic | 1 + 1 file changed, 1 insertion(+) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index 0d838d435..3001edb61 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -1083,3 +1083,4 @@ fc9839273862 4D8B8B95FDEE 354A787087F1 4a306e62e9b6 +B9C874AE63D0 From 0cde69ee22bb05015865b9b0f1134f7441873b2c Mon Sep 17 00:00:00 2001 From: bosb <12600404+bosb@users.noreply.github.com> Date: Fri, 6 Mar 2020 17:08:08 +0100 Subject: [PATCH 1624/1854] cleanup --- armsrc/hitagS.c | 32 +++++++++++++------------------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/armsrc/hitagS.c b/armsrc/hitagS.c index 38cb4d478..dc43c4cd3 100644 --- a/armsrc/hitagS.c +++ b/armsrc/hitagS.c @@ -60,7 +60,7 @@ bool end = false; #db# conf0: C9 conf1: 00 conf2: 00 3 2 1 0 #db# Page[ 0]: 84 11 C2 5F uid -#db# Page[ 1]: AA 00 00 C9 conf +#db# Page[ 1]: AA 00 00 C9 conf, HITAG S 256 #db# Page[ 2]: 4E 4F 54 48 #db# Page[ 3]: 52 4B 49 4D #db# Page[ 4]: 00 00 00 00 @@ -104,7 +104,7 @@ bool end = false; #define HITAG_T_TAG_CAPTURE_THREE_HALF 41 #define HITAG_T_TAG_CAPTURE_FOUR_HALF 57 -#define DBGLEVEL 4 +#define DBGLEVEL 0 /* * Implementation of the crc8 calculation from Hitag S @@ -225,6 +225,8 @@ static void hitag_send_bit(int bit) { } static void hitag_send_frame(const uint8_t *frame, size_t frame_len) { + if (DBGLEVEL >= DBG_EXTENDED) + Dbprintf("hitag_send_frame: (%i) %02X %02X %02X %02X", frame_len, frame[0], frame[1], frame[2], frame[3]); // The beginning of the frame is hidden in some high level; pause until our bits will have an effect AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; HIGH(GPIO_SSC_DOUT); @@ -370,7 +372,7 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen, case 5: { //UID request with a selected response protocol mode if (DBGLEVEL >= DBG_EXTENDED) - Dbprintf("...UID req %i %02x", rxlen, rx[0]); + Dbprintf("UID request: length: %i first byte: %02x", rxlen, rx[0]); tag.pstate = HT_READY; tag.tstate = HT_NO_OP; if ((rx[0] & 0xf0) == 0x30) { @@ -404,10 +406,10 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen, case 45: { //select command from reader received if (DBGLEVEL >= DBG_EXTENDED) - DbpString("...select"); + DbpString("SELECT"); if (check_select(rx, tag.uid) == 1) { if (DBGLEVEL >= DBG_EXTENDED) - DbpString("...select match"); + DbpString("SELECT match"); //if the right tag was selected *txlen = 32; hitagS_set_frame_modulation(); @@ -471,9 +473,10 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen, } */ } + break; case 40: if (DBGLEVEL >= DBG_EXTENDED) - Dbprintf("....write"); + Dbprintf("WRITE"); //data received to be written if (tag.tstate == HT_WRITING_PAGE_DATA) { tag.tstate = HT_NO_OP; @@ -500,14 +503,10 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen, } break; case 20: { - if (DBGLEVEL >= DBG_EXTENDED) - Dbprintf("....read"); //write page, write block, read page or read block command received if ((rx[0] & 0xf0) == 0xc0) { //read page //send page data uint8_t page = ((rx[0] & 0x0f) * 16) + ((rx[1] & 0xf0) / 16); - if (DBGLEVEL >= DBG_EXTENDED) - Dbprintf("....page %i", page); *txlen = 32; tx[0] = tag.pages[page][0]; tx[1] = tag.pages[page][1]; @@ -534,8 +533,6 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen, } } else if ((rx[0] & 0xf0) == 0xd0) { //read block uint8_t page = ((rx[0] & 0x0f) * 16) + ((rx[1] & 0xf0) / 16); - if (DBGLEVEL >= DBG_EXTENDED) - Dbprintf("....block %i", page); *txlen = 32 * 4; //send page,...,page+3 data for (int i = 0; i < 4; i++) { @@ -562,10 +559,6 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen, } } else if ((rx[0] & 0xf0) == 0x80) { //write page uint8_t page = ((rx[0] & 0x0f) * 16) + ((rx[1] & 0xf0) / 16); - if (DBGLEVEL >= DBG_EXTENDED) - Dbprintf("....write page: %i", page); - - hitagS_set_frame_modulation(); if ((tag.LCON && page == 1) || (tag.LKP && (page == 2 || page == 3))) { //deny @@ -580,8 +573,6 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen, } else if ((rx[0] & 0xf0) == 0x90) { //write block uint8_t page = ((rx[0] & 0x0f) * 6) + ((rx[1] & 0xf0) / 16); - if (DBGLEVEL >= DBG_EXTENDED) - Dbprintf("....write block: %i", page); hitagS_set_frame_modulation(); if (page % 4 != 0 || page == 0) { //deny @@ -599,7 +590,7 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen, break; default: if (DBGLEVEL >= DBG_EXTENDED) - Dbprintf("unknown rxlen: (%i) %02X %02X %02X %02X", rxlen, rx[0], rx[1], rx[2], rx[3]); + Dbprintf("unknown rxlen: (%i) %02X %02X %02X %02X ...", rxlen, rx[0], rx[1], rx[2], rx[3]); break; } } @@ -1192,6 +1183,9 @@ void ReadHitagS(hitag_function htf, hitag_data *htd) { uint64_t NrAr = 0; uint8_t key_[6]; + tag.pstate = HT_READY; + tag.tstate = HT_NO_OP; + switch (htf) { case RHTSF_CHALLENGE: { DbpString("Authenticating using nr,ar pair:"); From 40f553ffdcdf4898679e47d7ddc4241e3869bf75 Mon Sep 17 00:00:00 2001 From: Daniel Underhay <27876907+dunderhay@users.noreply.github.com> Date: Sun, 8 Mar 2020 02:03:24 +1100 Subject: [PATCH 1625/1854] Add Mifare Ultralight commands to cheatsheet.md --- doc/cheatsheet.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/doc/cheatsheet.md b/doc/cheatsheet.md index 3fc446ec8..b5ccd39b8 100644 --- a/doc/cheatsheet.md +++ b/doc/cheatsheet.md @@ -277,6 +277,19 @@ pm3 --> hf mf dump pm3 --> hf mf restore 1 u 4A6CE843 k hf-mf-A29558E4-key.bin f hf-mf-A29558E4-data.bin ``` +Read Mifare Ultralight EV1 +``` +pm3 --> hf mfu info +``` + +Clone Mifare Ultralight EV1 Sequence +``` +pm3 --> hf mfu dump k FFFFFFFF +pm3 --> script run dumptoemul-mfu -i hf-mfu-XXXX-dump.bin -o hf-mfu-XXXX-dump.eml +pm3 --> hf mfu eload u hf-mfu-XXXX-dump.eml +pm3 --> hf mfu sim t 7 u hf-mfu-XXXX-dump.eml +``` + ## Wiegand manipulation ^[Top](#top) From 618925b15cd5c79834a668eccc1560dbacc1339f Mon Sep 17 00:00:00 2001 From: Artem Gnatyuk Date: Sat, 7 Mar 2020 23:25:24 +0700 Subject: [PATCH 1626/1854] Final version --- armsrc/Standalone/Makefile.hal | 12 +++++++++++- armsrc/Standalone/Makefile.inc | 14 +++++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/armsrc/Standalone/Makefile.hal b/armsrc/Standalone/Makefile.hal index 2dec4cfde..776ae3f0f 100644 --- a/armsrc/Standalone/Makefile.hal +++ b/armsrc/Standalone/Makefile.hal @@ -41,9 +41,19 @@ define KNOWN_STANDALONE_DEFINITIONS | LF_ICEHID | LF HID collector to flashmem | | (RDV4 only) | | +----------------------------------------------------------+ +| LF_EM4100EMULV1 | Simulate predefined em4100 tags only | +| | | ++----------------------------------------------------------+ +| LF_EM4100EMULV2 | Read/simulate em4100 tags | +| | | ++----------------------------------------------------------+ +| LF_EM4100EMULV3 | Read/simulate em4100 tags & clone it | +| | to T555x tags | ++----------------------------------------------------------+ + endef -STANDALONE_MODES := LF_SAMYRUN LF_ICERUN LF_PROXBRUTE LF_HIDBRUTE LF_ICEHID +STANDALONE_MODES := LF_SAMYRUN LF_ICERUN LF_PROXBRUTE LF_HIDBRUTE LF_ICEHID LF_EM4100EMULV1 LF_EM4100EMULV2 LF_EM4100EMULV3 STANDALONE_MODES += HF_YOUNG HF_MATTYRUN HF_COLIN HF_BOG HF_14ASNIFF STANDALONE_MODES_REQ_SMARTCARD := STANDALONE_MODES_REQ_FLASH := HF_COLIN HF_BOG HF_14ASNIFF LF_ICEHID diff --git a/armsrc/Standalone/Makefile.inc b/armsrc/Standalone/Makefile.inc index d4de0411e..e7ca1bfe0 100644 --- a/armsrc/Standalone/Makefile.inc +++ b/armsrc/Standalone/Makefile.inc @@ -40,4 +40,16 @@ endif # WITH_STANDALONE_LF_ICEHID ifneq (,$(findstring WITH_STANDALONE_LF_ICEHID,$(APP_CFLAGS))) SRC_STANDALONE = lf_icehid.c -endif \ No newline at end of file +endif +# WITH_STANDALONE_LF_EM4100EMULV1 +ifneq (,$(findstring WITH_STANDALONE_LF_EM4100EMULV1,$(APP_CFLAGS))) + SRC_STANDALONE = lf_em4100emulV1.c +endif +# WITH_STANDALONE_LF_EM4100EMULV2 +ifneq (,$(findstring WITH_STANDALONE_LF_EM4100EMULV2,$(APP_CFLAGS))) + SRC_STANDALONE = lf_em4100emulV2.c +endif +# WITH_STANDALONE_LF_EM4100EMULV3 +ifneq (,$(findstring WITH_STANDALONE_LF_EM4100EMULV3,$(APP_CFLAGS))) + SRC_STANDALONE = lf_em4100emulV3.c +endif From 4b07fecd6b8cdea074bea7ed6ec82266ae8049c6 Mon Sep 17 00:00:00 2001 From: Artem Gnatyuk Date: Sun, 8 Mar 2020 00:07:38 +0700 Subject: [PATCH 1627/1854] Add missed files --- armsrc/Standalone/lf_em4100emulV1.c | 107 +++++++++++++++ armsrc/Standalone/lf_em4100emulV2.c | 171 ++++++++++++++++++++++++ armsrc/Standalone/lf_em4100emulV3.c | 197 ++++++++++++++++++++++++++++ 3 files changed, 475 insertions(+) create mode 100644 armsrc/Standalone/lf_em4100emulV1.c create mode 100644 armsrc/Standalone/lf_em4100emulV2.c create mode 100644 armsrc/Standalone/lf_em4100emulV3.c diff --git a/armsrc/Standalone/lf_em4100emulV1.c b/armsrc/Standalone/lf_em4100emulV1.c new file mode 100644 index 000000000..d132f3650 --- /dev/null +++ b/armsrc/Standalone/lf_em4100emulV1.c @@ -0,0 +1,107 @@ +//----------------------------------------------------------------------------- +// Artyom Gnatyuk, 2020 +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// LF emul V1 - Very simple mode. Simulate only predefined in low[] IDs +// Short click - change current slot +// Long press - simulate tag ID from current slot +//----------------------------------------------------------------------------- +#include "standalone.h" +#include "proxmark3_arm.h" +#include "appmain.h" +#include "fpgaloader.h" +#include "lfops.h" +#include "util.h" +#include "dbprint.h" +#include "ticks.h" +#include "string.h" +#include "BigBuf.h" + +#define MAX_IND 16 // 4 LEDs - 2^4 combinations +#define CLOCK 64 //for 125kHz + +// low & high - array for storage IDs. Its length must be equal. +// Predefined IDs must be stored in low[]. +// In high[] must be nulls +uint64_t low[] = {0x565A1140BE,0x365A398149,0x5555555555,0xFFFFFFFFFF}; +uint32_t high[] = {0,0,0,0}; +uint8_t *bba,slots_count; +int buflen; + +void ModInfo(void) { + DbpString(" LF EM4100 simulate standalone V1"); +} + +uint64_t ReversQuads(uint64_t bits){ + uint64_t result = 0; + for (int i = 0; i < 16; i++){ + result += ((bits >> (60 - 4 *i)) & 0xf) << (4 * i); + } + return result >> 24; +} + +void FillBuff(uint8_t bit) { + memset (bba + buflen, bit, CLOCK / 2); + buflen += (CLOCK / 2); + memset (bba + buflen, bit^1,CLOCK / 2); + buflen += (CLOCK / 2); +} + +void ConstructEM410xEmulBuf(uint64_t id) { + + int i, j, binary[4], parity[4]; + buflen = 0; + for (i = 0; i < 9; i++) + FillBuff(1); + parity[0] = parity[1] = parity[2] = parity[3] = 0; + for (i = 0; i < 10; i++) { + for (j = 3; j >= 0; j--, id /= 2) + binary[j] = id % 2; + for (j = 0; j < 4; j++) + FillBuff(binary[j]); + FillBuff(binary[0] ^ binary[1] ^ binary[2] ^ binary[3]); + for (j = 0; j < 4; j++) + parity[j] ^= binary[j]; + } + for (j = 0; j < 4; j++) + FillBuff(parity[j]); + FillBuff(0); +} + +void LED_Slot(int i) { + if (slots_count > 4) { + LED(i % MAX_IND, 0); //binary indication for slots_count > 4 + } else { + LED(1 << i,0); //simple indication for slots_count <=4 + } +} + +void RunMod() { + StandAloneMode(); + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + int selected = 0; + slots_count = sizeof(low)/sizeof(low[0]); + bba = BigBuf_get_addr(); + LED_Slot(selected); + for (;;) { + WDT_HIT(); + if (data_available()) break; + int button_pressed = BUTTON_HELD(1000); + SpinDelay(300); + if (button_pressed == 1) { + SpinUp(100); + SpinOff(10); + LED_Slot(selected); + ConstructEM410xEmulBuf(ReversQuads(low[selected])); + SimulateTagLowFrequency(buflen, 0, true); + LED_Slot(selected); + } else if (button_pressed < 0) { + selected = (selected + 1) % slots_count; + LEDsoff(); + LED_Slot(selected); + } + } +} diff --git a/armsrc/Standalone/lf_em4100emulV2.c b/armsrc/Standalone/lf_em4100emulV2.c new file mode 100644 index 000000000..2b48aeced --- /dev/null +++ b/armsrc/Standalone/lf_em4100emulV2.c @@ -0,0 +1,171 @@ +//----------------------------------------------------------------------------- +// Artyom Gnatyuk, 2020 +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// LF emul V2 - This mode can simulate tag ID from selected slot and read tag ID +// to selected slot and to flash (only RDV4). Also you can set +// predefined IDs in any slot. +// To recall stored ID from flash execute: +// mem dump o offset l 5 p +// where offset = 5 * selected slot +//----------------------------------------------------------------------------- +#include "standalone.h" +#include "proxmark3_arm.h" +#include "appmain.h" +#include "fpgaloader.h" +#include "lfops.h" +#include "util.h" +#include "dbprint.h" +#include "ticks.h" +#include "string.h" +#include "BigBuf.h" + +#ifdef WITH_FLASH +#include "flashmem.h" +#endif + +#define MAX_IND 16 // 4 LEDs - 2^4 combinations +#define CLOCK 64 //for 125kHz + +// low & high - array for storage IDs. Its length must be equal. +// Predefined IDs must be stored in low[]. +// In high[] must be nulls +uint64_t low[] = {0x565AF781C7,0x540053E4E2,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +uint32_t high[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +uint8_t *bba,slots_count; +int buflen; + +void ModInfo(void) { + DbpString(" LF EM4100 simulate standalone V2"); +} + +uint64_t ReversQuads(uint64_t bits){ + uint64_t result = 0; + for (int i = 0; i < 16; i++){ + result += ((bits >> (60 - 4 *i)) & 0xf) << (4 * i); + } + return result >> 24; +} + +void FillBuff(uint8_t bit) { + memset (bba + buflen, bit, CLOCK / 2); + buflen += (CLOCK / 2); + memset (bba + buflen, bit^1,CLOCK / 2); + buflen += (CLOCK / 2); +} + +void ConstructEM410xEmulBuf(uint64_t id) { + + int i, j, binary[4], parity[4]; + buflen = 0; + for (i = 0; i < 9; i++) + FillBuff(1); + parity[0] = parity[1] = parity[2] = parity[3] = 0; + for (i = 0; i < 10; i++) { + for (j = 3; j >= 0; j--, id /= 2) + binary[j] = id % 2; + for (j = 0; j < 4; j++) + FillBuff(binary[j]); + FillBuff(binary[0] ^ binary[1] ^ binary[2] ^ binary[3]); + for (j = 0; j < 4; j++) + parity[j] ^= binary[j]; + } + for (j = 0; j < 4; j++) + FillBuff(parity[j]); + FillBuff(0); +} + +void LED_Slot(int i) { + if (slots_count > 4) { + LED(i % MAX_IND, 0); //binary indication, usefully for slots_count > 4 + } else { + LED(1 << i,0); //simple indication for slots_count <=4 + } +} + +void FlashLEDs(uint32_t speed, uint8_t times) { + for (int i = 0; i < times * 2; i++) { + LED_A_INV(); + LED_B_INV(); + LED_C_INV(); + LED_D_INV(); + SpinDelay(speed); + } +} + +#ifdef WITH_FLASH +void SaveIDtoFlash (int addr, uint64_t id) { + uint8_t b, *ptr; + for (int i = 0; i < 5; i++) { + b = (uint8_t) (id >> 8 * i & 0xff); + ptr = &b; + Flash_WriteData(addr * 5 + 4 - i,ptr,1); + } +} +#endif + +void RunMod() { + StandAloneMode(); + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + int selected = 0; + //state 0 - select slot, + // 1 - read tag to selected slot, + // 2 - simulate tag from selected slot + uint8_t state = 0; + slots_count = sizeof(low)/sizeof(low[0]); + bba = BigBuf_get_addr(); + LED_Slot(selected); + for (;;) { + WDT_HIT(); + if (data_available()) break; + int button_pressed = BUTTON_HELD(1000); + SpinDelay(300); + switch (state){ + case 0: + // Select mode + if (button_pressed == 1) { + // Long press - switch to simulate mode + SpinUp(100); + SpinOff(100); + LED_Slot(selected); + state = 2; + } else if (button_pressed < 0) { + // Click - switch to next slot + selected = (selected + 1) % slots_count; + LEDsoff(); + LED_Slot(selected); + } + break; + case 1: + // Read mode. Click - exit to select mode + CmdEM410xdemod(1, &high[selected], &low[selected], 0); + FlashLEDs(100,5); + #ifdef WITH_FLASH + SaveIDtoFlash(selected, low[selected]); + #endif + state = 0; + break; + case 2: + // Simulate mode + if (button_pressed > 0) { + // Long press - switch to read mode + SpinDown(100); + SpinOff(10); + LED_Slot(selected); + state = 1; + } else if (button_pressed < 0) { + // Click - start simulating. Click again to exit from simelate mode + LED_Slot(selected); + ConstructEM410xEmulBuf(ReversQuads(low[selected])); + FlashLEDs(100,5); + SimulateTagLowFrequency(buflen, 0, 1); + LED_Slot(selected); + state = 0; // Switch to select mode + } + break; + } + } +} diff --git a/armsrc/Standalone/lf_em4100emulV3.c b/armsrc/Standalone/lf_em4100emulV3.c new file mode 100644 index 000000000..98247c390 --- /dev/null +++ b/armsrc/Standalone/lf_em4100emulV3.c @@ -0,0 +1,197 @@ +//----------------------------------------------------------------------------- +// Artyom Gnatyuk, 2020 +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// LF emul V3 - This mode can simulate ID from selected slot, read ID to +// selected slot, write from selected slot to T5555 tag and store +// readed ID to flash (only RDV4). Also you can set predefined IDs +// in any slot. +// To recall stored ID from flash execute: +// mem dump o offset l 5 p +// where offset = 5 * selected slot +//----------------------------------------------------------------------------- +#include "standalone.h" +#include "proxmark3_arm.h" +#include "appmain.h" +#include "fpgaloader.h" +#include "lfops.h" +#include "util.h" +#include "dbprint.h" +#include "ticks.h" +#include "string.h" +#include "BigBuf.h" + +#ifdef WITH_FLASH +#include "flashmem.h" +#endif + +#define MAX_IND 16 // 4 LEDs - 2^4 combinations +#define CLOCK 64 //for 125kHz + +// low & high - array for storage IDs. Its length must be equal. +// Predefined IDs must be stored in low[]. +// In high[] must be nulls +uint64_t low[] = {0x565AF781C7,0x540053E4E2,0x1234567890,0,0,0,0,0,0,0,0,0,0,0,0,0}; +uint32_t high[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +uint8_t *bba,slots_count; +int buflen; + +void ModInfo(void) { + DbpString(" LF EM4100 simulate standalone V2"); +} + +uint64_t ReversQuads(uint64_t bits){ + uint64_t result = 0; + for (int i = 0; i < 16; i++){ + result += ((bits >> (60 - 4 *i)) & 0xf) << (4 * i); + } + return result >> 24; +} + +void FillBuff(uint8_t bit) { + memset (bba + buflen, bit, CLOCK / 2); + buflen += (CLOCK / 2); + memset (bba + buflen, bit^1,CLOCK / 2); + buflen += (CLOCK / 2); +} + +void ConstructEM410xEmulBuf(uint64_t id) { + + int i, j, binary[4], parity[4]; + buflen = 0; + for (i = 0; i < 9; i++) + FillBuff(1); + parity[0] = parity[1] = parity[2] = parity[3] = 0; + for (i = 0; i < 10; i++) { + for (j = 3; j >= 0; j--, id /= 2) + binary[j] = id % 2; + for (j = 0; j < 4; j++) + FillBuff(binary[j]); + FillBuff(binary[0] ^ binary[1] ^ binary[2] ^ binary[3]); + for (j = 0; j < 4; j++) + parity[j] ^= binary[j]; + } + for (j = 0; j < 4; j++) + FillBuff(parity[j]); + FillBuff(0); +} + +void LED_Slot(int i) { + if (slots_count > 4) { + LED(i % MAX_IND, 0); //binary indication, usefully for slots_count > 4 + } else { + LED(1 << i,0); //simple indication for slots_count <=4 + } +} + +void FlashLEDs(uint32_t speed, uint8_t times) { + for (int i = 0; i < times * 2; i++) { + LED_A_INV(); + LED_B_INV(); + LED_C_INV(); + LED_D_INV(); + SpinDelay(speed); + } +} + +#ifdef WITH_FLASH +void SaveIDtoFlash (int addr, uint64_t id) { + uint8_t b, *ptr; + for (int i = 0; i < 5; i++) { + b = (uint8_t) (id >> 8 * i & 0xff); + ptr = &b; + Flash_WriteData(addr * 5 + 4 - i,ptr,1); + } +} +#endif + +void RunMod() { + StandAloneMode(); + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + int selected = 0; + //state 0 - select slot + // 1 - read tag to selected slot, + // 2 - simulate tag from selected slot + // 3 - write to T5555 tag + uint8_t state = 0; + slots_count = sizeof(low)/sizeof(low[0]); + bba = BigBuf_get_addr(); + LED_Slot(selected); + for (;;) { + WDT_HIT(); + if (data_available()) break; + int button_pressed = BUTTON_HELD(1000); + SpinDelay(300); + switch (state){ + case 0: + // Select mode + if (button_pressed == 1) { + // Long press - switch to simulate mode + SpinUp(100); + SpinOff(100); + LED_Slot(selected); + state = 2; + } else if (button_pressed < 0) { + // Click - switch to next slot + selected = (selected + 1) % slots_count; + LEDsoff(); + LED_Slot(selected); + } + break; + case 1: + // Read mode. + if (button_pressed > 0) { + // Long press - switch to read mode + SpinUp(100); + SpinOff(10); + LED_Slot(selected); + state = 3; + } else if (button_pressed < 0) { + // Click - exit to select mode + CmdEM410xdemod(1, &high[selected], &low[selected], 0); + FlashLEDs(100,5); + #ifdef WITH_FLASH + SaveIDtoFlash(selected, low[selected]); + #endif + state = 0; + } + break; + case 2: + // Simulate mode + if (button_pressed > 0) { + // Long press - switch to read mode + SpinDown(100); + SpinOff(10); + LED_Slot(selected); + state = 1; + } else if (button_pressed < 0) { + // Click - start simulating. Click again to exit from simelate mode + LED_Slot(selected); + ConstructEM410xEmulBuf(ReversQuads(low[selected])); + FlashLEDs(100,5); + SimulateTagLowFrequency(buflen, 0, 1); + LED_Slot(selected); + state = 0; // Switch to select mode + } + break; + case 3: + // Write tag mode + if (button_pressed > 0) { + // Long press - switch to select mode + SpinDown(100); + SpinOff(10); + LED_Slot(selected); + state = 0; + } else if (button_pressed < 0) { + // Click - write ID to tag + WriteEM410x(0, (uint32_t) (low[selected] >> 32), (uint32_t) (low[selected] & 0xffffffff)); + LED_Slot(selected); + state = 0; // Switch to select mode + } + break; + } + } +} From a4b8c14e1e559a32cd9c24be49c23a8cdf854c02 Mon Sep 17 00:00:00 2001 From: Artem Gnatyuk Date: Sun, 8 Mar 2020 00:13:13 +0700 Subject: [PATCH 1628/1854] Fix version number --- armsrc/Standalone/lf_em4100emulV3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/Standalone/lf_em4100emulV3.c b/armsrc/Standalone/lf_em4100emulV3.c index 98247c390..b1bf0d930 100644 --- a/armsrc/Standalone/lf_em4100emulV3.c +++ b/armsrc/Standalone/lf_em4100emulV3.c @@ -40,7 +40,7 @@ uint8_t *bba,slots_count; int buflen; void ModInfo(void) { - DbpString(" LF EM4100 simulate standalone V2"); + DbpString(" LF EM4100 simulate standalone V3"); } uint64_t ReversQuads(uint64_t bits){ From 074f6c374ee0122076476531df5a3bde4aa6ca7f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 9 Mar 2020 11:02:26 +0100 Subject: [PATCH 1629/1854] add: hf mf personlize - Personalize the UID of a Mifare Classic EV1 card (@pwpiwi) see https://github.com/Proxmark/proxmark3/commit/0b4efbdef20ccf33ba7b5f6dbe36ab80cfe5477a --- armsrc/appmain.c | 12 ++++++ armsrc/mifarecmd.c | 66 +++++++++++++++++++++++++++++--- armsrc/mifarecmd.h | 2 + client/cmdhfmf.c | 91 ++++++++++++++++++++++++++++++++++++++++++++- include/pm3_cmd.h | 2 + include/protocols.h | 4 ++ 6 files changed, 171 insertions(+), 6 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 1c76fad7d..5464d7ddb 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -42,6 +42,7 @@ #include "Standalone/standalone.h" #include "util.h" #include "ticks.h" +#include "commonutil.h" #ifdef WITH_LCD #include "LCD.h" @@ -1247,6 +1248,17 @@ static void PacketReceived(PacketCommandNG *packet) { // SniffMifare(packet->oldarg[0]); // break; // } + case CMD_HF_MIFARE_PERSONALIZE_UID: { + struct p { + uint8_t keytype; + uint8_t pers_option; + uint8_t key[6]; + } PACKED; + struct p *payload = (struct p *) packet->data.asBytes; + uint64_t authkey = bytes_to_num(payload->key, 6); + MifarePersonalizeUID(payload->keytype, payload->pers_option, authkey); + break; + } case CMD_HF_MIFARE_SETMOD: { MifareSetMod(packet->data.asBytes); break; diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index b869489ab..3669e13ea 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -1805,6 +1805,63 @@ void MifareChkKeys_file(uint8_t *fn) { #endif } +//----------------------------------------------------------------------------- +// MIFARE Personalize UID. Only for Mifare Classic EV1 7Byte UID +//----------------------------------------------------------------------------- +void MifarePersonalizeUID(uint8_t keyType, uint8_t perso_option, uint64_t key) { + + uint16_t isOK = PM3_EUNDEF; + uint8_t uid[10]; + uint32_t cuid; + struct Crypto1State mpcs = {0, 0}; + struct Crypto1State *pcs; + pcs = &mpcs; + + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + clear_trace(); + set_tracing(true); + + LED_A_ON(); + + while (true) { + if (!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) { + if (DBGLEVEL >= DBG_ERROR) Dbprintf("Can't select card"); + break; + } + + uint8_t block_number = 0; + if (mifare_classic_auth(pcs, cuid, block_number, keyType, key, AUTH_FIRST)) { + if (DBGLEVEL >= DBG_ERROR) Dbprintf("Auth error"); + break; + } + + uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE]; + uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE]; + int len = mifare_sendcmd_short(pcs, true, MIFARE_EV1_PERSONAL_UID, perso_option, receivedAnswer, receivedAnswerPar, NULL); + if (len != 1 || receivedAnswer[0] != CARD_ACK) { + if (DBGLEVEL >= DBG_ERROR) Dbprintf("Cmd Error: %02x", receivedAnswer[0]); + break;; + } + + if (mifare_classic_halt(pcs, cuid)) { + if (DBGLEVEL >= DBG_ERROR) Dbprintf("Halt error"); + break; + } + isOK = PM3_SUCCESS; + break; + } + + crypto1_deinit(pcs); + + LED_B_ON(); + reply_ng(CMD_HF_MIFARE_PERSONALIZE_UID, isOK, NULL, 0); + LED_B_OFF(); + + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LEDsoff(); +} + + //----------------------------------------------------------------------------- // Work with emulator memory // @@ -2276,23 +2333,23 @@ void MifareSetMod(uint8_t *datain) { while (true) { if (!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) { - if (DBGLEVEL >= 1) Dbprintf("Can't select card"); + if (DBGLEVEL >= DBG_ERROR) Dbprintf("Can't select card"); break; } if (mifare_classic_auth(pcs, cuid, 0, 0, ui64Key, AUTH_FIRST)) { - if (DBGLEVEL >= 1) Dbprintf("Auth error"); + if (DBGLEVEL >= DBG_ERROR) Dbprintf("Auth error"); break; } int respLen; if (((respLen = mifare_sendcmd_short(pcs, CRYPT_ALL, 0x43, mod, receivedAnswer, receivedAnswerPar, NULL)) != 1) || (receivedAnswer[0] != 0x0a)) { - if (DBGLEVEL >= 1) Dbprintf("SetMod error; response[0]: %hhX, len: %d", receivedAnswer[0], respLen); + if (DBGLEVEL >= DBG_ERROR) Dbprintf("SetMod error; response[0]: %hhX, len: %d", receivedAnswer[0], respLen); break; } if (mifare_classic_halt(pcs, cuid)) { - if (DBGLEVEL >= 1) Dbprintf("Halt error"); + if (DBGLEVEL >= DBG_ERROR) Dbprintf("Halt error"); break; } @@ -2304,7 +2361,6 @@ void MifareSetMod(uint8_t *datain) { LED_B_ON(); reply_ng(CMD_HF_MIFARE_SETMOD, isOK, NULL, 0); - LED_B_OFF(); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); diff --git a/armsrc/mifarecmd.h b/armsrc/mifarecmd.h index 1f5ee63a4..91adba3b1 100644 --- a/armsrc/mifarecmd.h +++ b/armsrc/mifarecmd.h @@ -45,6 +45,8 @@ void MifareCIdent(); // is "magic chinese" card? void MifareHasStaticNonce(); // Has the tag a static nonce? void MifareSetMod(uint8_t *datain); +void MifarePersonalizeUID(uint8_t keyType, uint8_t perso_option, uint64_t key); + void MifareUSetPwd(uint8_t arg0, uint8_t *datain); void OnSuccessMagic(); void OnErrorMagic(uint8_t reason); diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 24296b31d..6a57491fc 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -4798,6 +4798,95 @@ static int CmdHFMFNDEF(const char *Cmd) { return PM3_SUCCESS; } +int CmdHFMFPersonalize(const char *cmd) { + + CLIParserInit("hf mf personalize", + "Personalize the UID of a Mifare Classic EV1 card. This is only possible if it is a 7Byte UID card and if it is not already personalized.", + "Usage:\n\thf mf personalize UIDF0 -> double size UID according to ISO/IEC14443-3\n" + "\thf mf personalize UIDF1 -> double size UID according to ISO/IEC14443-3, optional usage of selection process shortcut\n" + "\thf mf personalize UIDF2 -> single size random ID according to ISO/IEC14443-3\n" + "\thf mf personalize UIDF3 -> single size NUID according to ISO/IEC14443-3\n" + "\thf mf personalize -t B -k B0B1B2B3B4B5 UIDF3 -> use key B = 0xB0B1B2B3B4B5 instead of default key A\n"); + + void *argtable[] = { + arg_param_begin, + arg_str0("tT", "keytype", "", "key type (A or B) to authenticate sector 0 (default: A)"), + arg_str0("kK", "key", "", "key to authenticate sector 0 (default: FFFFFFFFFFFF)"), + arg_str1(NULL, NULL, "", "Personalization Option"), + arg_param_end + }; + CLIExecWithReturn(cmd, argtable, true); + + char keytypestr[2] = "a"; + uint8_t keytype = 0x00; + int keytypestr_len; + int res = CLIParamStrToBuf(arg_get_str(1), (uint8_t*)keytypestr, 1, &keytypestr_len); + str_lower(keytypestr); + + if (res || (keytypestr[0] != 'a' && keytypestr[0] != 'b')) { + PrintAndLogEx(ERR, "ERROR: not a valid key type. Key type must be A or B"); + CLIParserFree(); + return PM3_EINVARG; + } + if (keytypestr[0] == 'b') { + keytype = 0x01; + } + + uint8_t key[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + int key_len; + res = CLIParamHexToBuf(arg_get_str(2), key, 6, &key_len); + if (res || (!res && key_len > 0 && key_len != 6)) { + PrintAndLogEx(ERR, "ERROR: not a valid key. Key must be 12 hex digits"); + CLIParserFree(); + return PM3_EINVARG; + } + + char pers_optionstr[6]; + int opt_len; + uint8_t pers_option; + res = CLIParamStrToBuf(arg_get_str(3), (uint8_t*)pers_optionstr, 5, &opt_len); + str_lower(pers_optionstr); + + if (res || (!res && opt_len > 0 && opt_len != 5) + || (strncmp(pers_optionstr, "uidf0", 5) && strncmp(pers_optionstr, "uidf1", 5) && strncmp(pers_optionstr, "uidf2", 5) && strncmp(pers_optionstr, "uidf3", 5))) { + PrintAndLogEx(ERR, "ERROR: invalid personalization option. Must be one of UIDF0, UIDF1, UIDF2, or UIDF3"); + CLIParserFree(); + return PM3_EINVARG; + } + if (!strncmp(pers_optionstr, "uidf0", 5)) { + pers_option = MIFARE_EV1_UIDF0; + } else if (!strncmp(pers_optionstr, "uidf1", 5)) { + pers_option = MIFARE_EV1_UIDF1; + } else if (!strncmp(pers_optionstr, "uidf2", 5)) { + pers_option = MIFARE_EV1_UIDF2; + } else { + pers_option = MIFARE_EV1_UIDF3; + } + + CLIParserFree(); + + clearCommandBuffer(); + + struct { + uint8_t keytype; + uint8_t pers_option; + uint8_t key[6]; + } PACKED payload; + payload.keytype = keytype; + payload.pers_option = pers_option; + + memcpy(payload.key, key, 6); + + SendCommandNG(CMD_HF_MIFARE_PERSONALIZE_UID, (uint8_t *)&payload, sizeof(payload)); + + PacketResponseNG resp; + if (!WaitForResponseTimeout(CMD_HF_MIFARE_PERSONALIZE_UID, &resp, 2500)) return PM3_ETIMEOUT; + + PrintAndLogEx(SUCCESS, "Personalization %s", resp.status == PM3_SUCCESS ? "SUCCEEDED" : "FAILED"); + + return PM3_SUCCESS; +} + static int CmdHF14AMfList(const char *Cmd) { (void)Cmd; // Cmd is not used so far return CmdTraceList("mf"); @@ -4845,7 +4934,7 @@ static command_t CommandTable[] = { {"-----------", CmdHelp, IfPm3Iso14443a, ""}, {"mad", CmdHF14AMfMAD, IfPm3Iso14443a, "Checks and prints MAD"}, {"ndef", CmdHFMFNDEF, IfPm3Iso14443a, "Prints NDEF records from card"}, - + {"personalize", CmdHFMFPersonalize, IfPm3Iso14443a, "Personalize UID (Mifare Classic EV1 only)"}, {"ice", CmdHF14AMfice, IfPm3Iso14443a, "collect MIFARE Classic nonces to file"}, {NULL, NULL, NULL, NULL} }; diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index cff1f891f..8cffa892a 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -505,6 +505,8 @@ typedef struct { #define CMD_HF_MIFARE_SNIFF 0x0630 #define CMD_HF_MIFARE_MFKEY 0x0631 +#define CMD_HF_MIFARE_PERSONALIZE_UID 0x0632 + //ultralightC #define CMD_HF_MIFAREUC_AUTH 0x0724 //0x0725 and 0x0726 no longer used diff --git a/include/protocols.h b/include/protocols.h index e1d898d53..e992a97ee 100644 --- a/include/protocols.h +++ b/include/protocols.h @@ -163,6 +163,10 @@ ISO 7816-4 Basic interindustry commands. For command APDU's. #define MIFARE_EV1_PERSONAL_UID 0x40 #define MIFARE_EV1_SETMODE 0x43 +#define MIFARE_EV1_UIDF0 0x00 +#define MIFARE_EV1_UIDF1 0x40 +#define MIFARE_EV1_UIDF2 0x20 +#define MIFARE_EV1_UIDF3 0x60 #define MIFARE_ULC_WRITE 0xA2 #define MIFARE_ULC_COMP_WRITE 0xA0 From 0f16070c0913948b6aec7d5973ab687c759c2320 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 9 Mar 2020 11:04:32 +0100 Subject: [PATCH 1630/1854] text --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8896f223c..a0391fdf2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Added `hf mf personlize` - personalize the UID of a Mifare Classic EV1 card (@pwpiwi) - Change - hint texts added to all lf clone commands (@iceman1001) - Change `lf keri demod` - adjusted the internal id. (@mwalker33) - Added seamless integration with cryptohelper (@iceman1001) From 111af2bacba142fff7daa9caf17fa7a3dc608cc1 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 9 Mar 2020 16:39:52 +0100 Subject: [PATCH 1631/1854] Chg: 'lf indala clone' - now can use FC/CN for 26b format. Checksum is still not known. --- client/cmdlfindala.c | 130 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 111 insertions(+), 19 deletions(-) diff --git a/client/cmdlfindala.c b/client/cmdlfindala.c index 01eb4b8f8..08b869378 100644 --- a/client/cmdlfindala.c +++ b/client/cmdlfindala.c @@ -28,6 +28,8 @@ #include "protocols.h" // t55 defines #include "cmdlft55xx.h" // verifywrite +#define INDALA_ARR_LEN 64 + static int CmdHelp(const char *Cmd); //large 224 bit indala formats (different preamble too...) @@ -140,7 +142,7 @@ static void decodeHeden2L(uint8_t *bits) { if (bits[offset + 7]) cardnumber += 16384; if (bits[offset + 23]) cardnumber += 32768; - PrintAndLogEx(SUCCESS, "\tHeden-2L | %u", cardnumber); + PrintAndLogEx(SUCCESS, "\tHeden-2L | " _YELLOW_("%u"), cardnumber); } // Indala 26 bit decode @@ -192,7 +194,7 @@ static int CmdIndalaDemod(const char *Cmd) { if (DemodBufferLen == 64) { PrintAndLogEx( SUCCESS - , "Indala Found - bitlength %zu, Raw %x%08x" + , "Indala Found - bitlength %zu, Raw " _YELLOW_("%x%08x") , DemodBufferLen , uid1 , uid2 @@ -244,14 +246,18 @@ static int CmdIndalaDemod(const char *Cmd) { checksum |= DemodBuffer[63] << 0; // b1 PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(SUCCESS, "Fmt 26 bit FC " _YELLOW_("%u") ", CN " _YELLOW_("%u") ", checksum %1d%1d" + , fc + , csn + , checksum >> 1 & 0x01 + , checksum & 0x01 + ); + PrintAndLogEx(SUCCESS, "Possible de-scramble patterns"); PrintAndLogEx(SUCCESS, "\tPrinted | __%04d__ [0x%X]", p1, p1); PrintAndLogEx(SUCCESS, "\tInternal ID | %" PRIu64, foo); decodeHeden2L(DemodBuffer); - PrintAndLogEx(SUCCESS, "Fmt 26 bit FC %u , CSN %u , checksum %1d%1d", fc, csn, checksum >> 1 & 0x01, checksum & 0x01); - - } else { uint32_t uid3 = bytebits_to_byte(DemodBuffer + 64, 32); uint32_t uid4 = bytebits_to_byte(DemodBuffer + 96, 32); @@ -542,49 +548,62 @@ static int CmdIndalaSim(const char *Cmd) { static int CmdIndalaClone(const char *Cmd) { - bool is_long_uid = false, got_cn = false; + bool is_long_uid = false, got_cn = false, got_26 = false; bool is_t5555 = false; int32_t cardnumber; uint32_t blocks[8] = {0}; uint8_t max = 0; uint8_t data[7 * 4]; int datalen = 0; + uint8_t fc = 0; + uint16_t cn = 0; CLIParserInit("lf indala clone", "clone INDALA tag to T55x7 (or to q5/T5555)", "Examples:\n" "\tlf indala clone -c 888\n" + "\tlf indala clone -fc 123 -csn 1337\n" "\tlf indala clone -r a0000000a0002021\n" "\tlf indala clone -l -r 80000001b23523a6c2e31eba3cbee4afb3c6ad1fcf649393928c14e5"); void *argtable[] = { arg_param_begin, - arg_lit0("lL", "long", "optional - long UID 224 bits"), - arg_int0("cC", "cn", "", "Cardnumber for Heden 2L format"), - arg_strx0("rR", "raw", "", "raw bytes"), - arg_lit0("qQ", "Q5", "optional - specify write to Q5 (t5555 instead of t55x7)"), + arg_lit0("lL", "long", "optional - long UID 224 bits"), + arg_int0("cC", "heden", "", "Cardnumber for Heden 2L format"), + arg_strx0("rR", "raw", "", "raw bytes"), + arg_lit0("qQ", "Q5", "optional - specify write to Q5 (t5555 instead of t55x7)"), + arg_int0("", "fc", "", "Facility Code (26 bit format)"), + arg_int0("", "cn", "", "Cardnumber (26 bit format)"), arg_param_end }; CLIExecWithReturn(Cmd, argtable, false); is_long_uid = arg_get_lit(1); - if (is_long_uid == false) { - cardnumber = arg_get_int_def(2, -1); - got_cn = (cardnumber != -1); - } - if (got_cn == false) { - CLIGetHexWithReturn(3, data, &datalen); - } + // raw param + CLIGetHexWithReturn(3, data, &datalen); is_t5555 = arg_get_lit(4); + if (is_long_uid == false) { + + // Heden param + cardnumber = arg_get_int_def(2, -1); + got_cn = (cardnumber != -1); + + // 26b FC/CN param + fc = arg_get_int_def(5, 0); + cn = arg_get_int_def(6, 0); + got_26 = (fc != 0 && cn != 0); + } + CLIParserFree(); if (is_long_uid) { // 224 BIT UID // config for Indala (RF/32;PSK2 with RF/2;Maxblock=7) - PrintAndLogEx(INFO, "Preparing to clone Indala 224bit tag with RawID %s", sprint_hex(data, datalen)); + PrintAndLogEx(INFO, "Preparing to clone Indala 224bit tag"); + PrintAndLogEx(INFO, "RawID %s", sprint_hex(data, datalen)); if (is_t5555) blocks[0] = T5555_SET_BITRATE(32) | T5555_MODULATION_PSK2 | (7 << T5555_MAXBLOCK_SHIFT); @@ -602,12 +621,41 @@ static int CmdIndalaClone(const char *Cmd) { } else { // 64 BIT UID if (got_cn) { + PrintAndLogEx(INFO, "Using Indala HEDEN cardnumber %u", cardnumber); encodeHeden2L(data, cardnumber); datalen = 8; + } else if (got_26) { + + PrintAndLogEx(INFO, "Using Indala 26b FC %u CN %u", fc, cn); + + // Used with the 26bit FC/CSN + uint8_t *bits = calloc(INDALA_ARR_LEN, sizeof(uint8_t)); + if (bits == NULL) { + PrintAndLogEx(WARNING, "Failed to allocate memory"); + return PM3_EMALLOC; + } + + if (getIndalaBits(fc, cn, bits) != PM3_SUCCESS) { + PrintAndLogEx(ERR, "Error with tag bitstream generation."); + return PM3_ESOFT; + } + + data[0] = bytebits_to_byte(bits, 8); + data[1] = bytebits_to_byte(bits + 8, 8); + data[2] = bytebits_to_byte(bits + 16, 8); + data[3] = bytebits_to_byte(bits + 24, 8); + data[4] = bytebits_to_byte(bits + 32, 8); + data[5] = bytebits_to_byte(bits + 40, 8); + data[6] = bytebits_to_byte(bits + 48, 8); + data[7] = bytebits_to_byte(bits + 56, 8); + datalen = 8; + + free(bits); } // config for Indala 64 format (RF/32;PSK1 with RF/2;Maxblock=2) - PrintAndLogEx(INFO, "Preparing to clone Indala 64bit tag with RawID %s", sprint_hex(data, datalen)); + PrintAndLogEx(INFO, "Preparing to clone Indala 64bit tag"); + PrintAndLogEx(INFO, "RawID %s", sprint_hex(data, datalen)); if (is_t5555) blocks[0] = T5555_SET_BITRATE(32) | T5555_MODULATION_PSK1 | (2 << T5555_MAXBLOCK_SHIFT); @@ -647,6 +695,50 @@ int CmdLFINDALA(const char *Cmd) { return CmdsParse(CommandTable, Cmd); } +int getIndalaBits(uint8_t fc, uint16_t cn, uint8_t *bits) { + // preamble + // is there a preamble? + bits[0] = 1; + bits[2] = 1; + bits[32] = 1; + + // add fc + bits[57] = ((fc >> 7) & 1); // b8 + bits[49] = ((fc >> 6) & 1); // b7 + bits[44] = ((fc >> 5) & 1); // b6 + bits[47] = ((fc >> 4) & 1); // b5 + bits[48] = ((fc >> 3) & 1); // b4 + bits[53] = ((fc >> 2) & 1); // b3 + bits[39] = ((fc >> 1) & 1); // b2 + bits[58] = (fc & 1); // b1 + + // add cn + bits[42] = ((cn >> 15) & 1); // b16 + bits[45] = ((cn >> 14) & 1); // b15 + bits[43] = ((cn >> 13) & 1); // b14 + bits[40] = ((cn >> 12) & 1); // b13 + bits[52] = ((cn >> 11) & 1); // b12 + bits[36] = ((cn >> 10) & 1); // b11 + bits[35] = ((cn >> 9) & 1); // b10 + bits[51] = ((cn >> 8) & 1); // b9 + bits[46] = ((cn >> 7) & 1); // b8 + bits[33] = ((cn >> 6) & 1); // b7 + bits[37] = ((cn >> 5) & 1); // b6 + bits[54] = ((cn >> 4) & 1); // b5 + bits[56] = ((cn >> 3) & 1); // b4 + bits[59] = ((cn >> 2) & 1); // b3 + bits[50] = ((cn >> 1) & 1); // b2 + bits[41] = (cn & 1); // b1 + + // checksum + // ICEMAN: todo: needs to calc + uint8_t chk = 3; + bits[62] = ((chk >> 1) & 1); // b2 + bits[63] = (chk & 1); // b1 + + return PM3_SUCCESS; +} + // redesigned by marshmellow adjusted from existing decode functions // indala id decoding int detectIndala(uint8_t *dest, size_t *size, uint8_t *invert) { From b485461fba132633931d8cfc185e54521039edf6 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 9 Mar 2020 16:43:14 +0100 Subject: [PATCH 1632/1854] style --- tools/hitag2crack/crack2/HardwareProfile.h | 8 +- tools/hitag2crack/crack2/hitagcrypto.c | 32 ++++---- tools/hitag2crack/crack2/hitagcrypto.h | 4 +- .../hitag2crack/crack2/ht2crack2buildtable.c | 79 ++++++++----------- tools/hitag2crack/crack2/ht2crack2gentest.c | 12 ++- tools/hitag2crack/crack2/ht2crack2search.c | 53 ++++++------- tools/hitag2crack/crack2/ht2crack2utils.c | 67 ++++++---------- tools/hitag2crack/crack2/rfidler.h | 2 +- tools/hitag2crack/crack2/util.h | 2 +- tools/hitag2crack/crack2/utilpart.c | 29 +++---- 10 files changed, 121 insertions(+), 167 deletions(-) diff --git a/tools/hitag2crack/crack2/HardwareProfile.h b/tools/hitag2crack/crack2/HardwareProfile.h index a2f804be6..bce139042 100644 --- a/tools/hitag2crack/crack2/HardwareProfile.h +++ b/tools/hitag2crack/crack2/HardwareProfile.h @@ -142,11 +142,11 @@ typedef int rtccDate; #ifndef __PIC32MX__ - #define __PIC32MX__ +#define __PIC32MX__ #endif - + #define GetSystemClock() (80000000ul) -#define GetPeripheralClock() (GetSystemClock()) +#define GetPeripheralClock() (GetSystemClock()) #define GetInstructionClock() (GetSystemClock()) //#define USE_SELF_POWER_SENSE_IO @@ -322,7 +322,7 @@ typedef int rtccDate; // spi for SD card #define SD_CARD_DET LATFbits.LATF0 #define SD_CARD_WE LATFbits.LATF1 // write enable - unused for microsd but allocated anyway as library checks it - // (held LOW by default - cut solder bridge to GND to free pin if required) +// (held LOW by default - cut solder bridge to GND to free pin if required) #define SPI_SD SPI_CHANNEL1 #define SPI_SD_BUFF SPI1BUF #define SPI_SD_STAT SPI1STATbits diff --git a/tools/hitag2crack/crack2/hitagcrypto.c b/tools/hitag2crack/crack2/hitagcrypto.c index 2334f8288..5ebfc5ae9 100644 --- a/tools/hitag2crack/crack2/hitagcrypto.c +++ b/tools/hitag2crack/crack2/hitagcrypto.c @@ -229,17 +229,16 @@ static uint32_t hitag2_crypt(uint64_t x); ((S >> (C - 3)) & 8) ) -static uint32_t hitag2_crypt(uint64_t s) -{ +static uint32_t hitag2_crypt(uint64_t s) { const uint32_t ht2_function4a = 0x2C79; // 0010 1100 0111 1001 const uint32_t ht2_function4b = 0x6671; // 0110 0110 0111 0001 const uint32_t ht2_function5c = 0x7907287B; // 0111 1001 0000 0111 0010 1000 0111 1011 uint32_t bitindex; - bitindex = (ht2_function4a >> pickbits2_2 (s, 1, 4)) & 1; - bitindex |= ((ht2_function4b << 1) >> pickbits1_1_2 (s, 7, 11, 13)) & 0x02; - bitindex |= ((ht2_function4b << 2) >> pickbits1x4 (s, 16, 20, 22, 25)) & 0x04; - bitindex |= ((ht2_function4b << 3) >> pickbits2_1_1 (s, 27, 30, 32)) & 0x08; + bitindex = (ht2_function4a >> pickbits2_2(s, 1, 4)) & 1; + bitindex |= ((ht2_function4b << 1) >> pickbits1_1_2(s, 7, 11, 13)) & 0x02; + bitindex |= ((ht2_function4b << 2) >> pickbits1x4(s, 16, 20, 22, 25)) & 0x04; + bitindex |= ((ht2_function4b << 3) >> pickbits2_1_1(s, 27, 30, 32)) & 0x08; bitindex |= ((ht2_function4a << 4) >> pickbits1_2_1(s, 33, 42, 45)) & 0x10; DEBUG_PRINTF("hitag2_crypt bitindex = %02x\n", bitindex); @@ -253,13 +252,12 @@ static uint32_t hitag2_crypt(uint64_t s) * uint32_t serialnum - 32 bit tag serial number * uint32_t initvector - 32 bit random IV from reader, part of tag authentication */ -void hitag2_init(Hitag_State* pstate, uint64_t sharedkey, uint32_t serialnum, uint32_t initvector) -{ +void hitag2_init(Hitag_State *pstate, uint64_t sharedkey, uint32_t serialnum, uint32_t initvector) { // init state, from serial number and lowest 16 bits of shared key uint64_t state = ((sharedkey & 0xFFFF) << 32) | serialnum; // mix the initialisation vector and highest 32 bits of the shared key - initvector ^= (uint32_t) (sharedkey >> 16); + initvector ^= (uint32_t)(sharedkey >> 16); // move 16 bits from (IV xor Shared Key) to top of uint64_t state // these will be XORed in turn with output of the crypto function @@ -320,9 +318,9 @@ void hitag2_init(Hitag_State* pstate, uint64_t sharedkey, uint32_t serialnum, ui // optimise with one 64-bit intermediate uint64_t temp = state ^ (state >> 1); pstate->lfsr = state ^ (state >> 6) ^ (state >> 16) - ^ (state >> 26) ^ (state >> 30) ^ (state >> 41) - ^ (temp >> 2) ^ (temp >> 7) ^ (temp >> 22) - ^ (temp >> 42) ^ (temp >> 46); + ^ (state >> 26) ^ (state >> 30) ^ (state >> 41) + ^ (temp >> 2) ^ (temp >> 7) ^ (temp >> 22) + ^ (temp >> 42) ^ (temp >> 46); } } @@ -338,8 +336,7 @@ void hitag2_init(Hitag_State* pstate, uint64_t sharedkey, uint32_t serialnum, ui * Hitag_State* pstate - in/out, internal cipher state after initialisation * uint32_t steps - number of bits requested, (capped at 32) */ -uint32_t hitag2_nstep(Hitag_State* pstate, uint32_t steps) -{ +uint32_t hitag2_nstep(Hitag_State *pstate, uint32_t steps) { uint64_t state = pstate->shiftreg; uint32_t result = 0; uint64_t lfsr = pstate->lfsr; @@ -448,7 +445,7 @@ unsigned hitag2_verifytest() const uint64_t key = rev64 (0x524B494D4E4FUL); const uint32_t serial = rev32 (0x69574349); const uint32_t initvec = rev32 (0x72456E65); - + uint32_t i; Hitag_State state; @@ -471,11 +468,10 @@ unsigned hitag2_verifytest() #ifdef UNIT_TEST -int main(int argc, char* argv[]) -{ +int main(int argc, char *argv[]) { unsigned pass = hitag2_verifytest(); - printf ("Crypto Verify test = %s\n\n", pass ? "PASS" : "FAIL"); + printf("Crypto Verify test = %s\n\n", pass ? "PASS" : "FAIL"); if (pass) { hitag2_benchtest(10000); diff --git a/tools/hitag2crack/crack2/hitagcrypto.h b/tools/hitag2crack/crack2/hitagcrypto.h index d5aa9104c..46d447370 100644 --- a/tools/hitag2crack/crack2/hitagcrypto.h +++ b/tools/hitag2crack/crack2/hitagcrypto.h @@ -159,9 +159,9 @@ typedef struct { uint64_t lfsr; // fast lfsr, used to make software faster } Hitag_State; -void hitag2_init(Hitag_State* pstate, uint64_t sharedkey, uint32_t serialnum, uint32_t initvector); +void hitag2_init(Hitag_State *pstate, uint64_t sharedkey, uint32_t serialnum, uint32_t initvector); -uint32_t hitag2_nstep(Hitag_State* pstate, uint32_t steps); +uint32_t hitag2_nstep(Hitag_State *pstate, uint32_t steps); unsigned int hitag2_benchtest_gen32(); unsigned int hitag2_benchtest(uint32_t count); diff --git a/tools/hitag2crack/crack2/ht2crack2buildtable.c b/tools/hitag2crack/crack2/ht2crack2buildtable.c index 402c5b245..ffabd8f2e 100644 --- a/tools/hitag2crack/crack2/ht2crack2buildtable.c +++ b/tools/hitag2crack/crack2/ht2crack2buildtable.c @@ -18,7 +18,7 @@ // // If sorting fails with a 'bus error' then that is likely because your disk I/O can't keep up with // the read/write demands of the multi-threaded sorting. In this case, reduce the number of sorting -// threads. This will most likely only be a problem with network disks; SATA should be okay; +// threads. This will most likely only be a problem with network disks; SATA should be okay; // USB2/3 should keep up. // // These MUST be a power of 2 for the maths to work - you have been warned! @@ -53,8 +53,7 @@ uint64_t d2[48]; int nsteps2; // create table entry -void create_table(struct table *t, int d1, int d2) -{ +void create_table(struct table *t, int d1, int d2) { if (!t) { printf("create_table: t is NULL\n"); exit(1); @@ -83,8 +82,7 @@ void create_table(struct table *t, int d1, int d2) // create all table entries -void create_tables(struct table *t) -{ +void create_tables(struct table *t) { int i, j; if (!t) { @@ -92,8 +90,8 @@ void create_tables(struct table *t) exit(1); } - for (i=0; i<0x100; i++) { - for (j=0; j<0x100; j++) { + for (i = 0; i < 0x100; i++) { + for (j = 0; j < 0x100; j++) { create_table(t + ((i * 0x100) + j), i, j); } } @@ -101,8 +99,7 @@ void create_tables(struct table *t) // free the table memory -void free_tables(struct table *t) -{ +void free_tables(struct table *t) { int i; struct table *ttmp; @@ -111,7 +108,7 @@ void free_tables(struct table *t) exit(1); } - for (i=0; i<0x10000; i++) { + for (i = 0; i < 0x10000; i++) { ttmp = t + i; free(ttmp->data); } @@ -120,8 +117,7 @@ void free_tables(struct table *t) // write (partial) table to file -void writetable(struct table *t1) -{ +void writetable(struct table *t1) { int fd; if (debug) printf("writetable %s\n", t1->path); @@ -146,8 +142,7 @@ void writetable(struct table *t1) // store value in table -void store(unsigned char *data) -{ +void store(unsigned char *data) { unsigned char d1, d2; int offset; struct table *t1; @@ -171,7 +166,7 @@ void store(unsigned char *data) if (debug) printf("store, offset = %d, got lock\n", offset); // store the entry - memcpy(t1->ptr, data+2, 10); + memcpy(t1->ptr, data + 2, 10); if (debug) printf("store, offset = %d, copied data\n", offset); @@ -199,14 +194,13 @@ void store(unsigned char *data) } // writes the ks (keystream) and s (state) -void write_ks_s(uint32_t ks1, uint32_t ks2, uint64_t shiftreg) -{ +void write_ks_s(uint32_t ks1, uint32_t ks2, uint64_t shiftreg) { unsigned char buf[16]; // create buffer writebuf(buf, ks1, 3); - writebuf(buf+3, ks2, 3); - writebuf(buf+6, shiftreg, 6); + writebuf(buf + 3, ks2, 3); + writebuf(buf + 6, shiftreg, 6); // store buffer store(buf); @@ -215,8 +209,7 @@ void write_ks_s(uint32_t ks1, uint32_t ks2, uint64_t shiftreg) // builds the di table for jumping -void builddi(int steps, int table) -{ +void builddi(int steps, int table) { uint64_t statemask; int i; Hitag_State mystate; @@ -237,7 +230,7 @@ void builddi(int steps, int table) } // build di states - for (i=0; i<48; i++) { + for (i = 0; i < 48; i++) { mystate.shiftreg = statemask; buildlfsr(&mystate); hitag2_nstep(&mystate, steps); @@ -248,8 +241,7 @@ void builddi(int steps, int table) } // jump function - quickly jumps a load of steps -void jumpnsteps(Hitag_State *hstate, int table) -{ +void jumpnsteps(Hitag_State *hstate, int table) { uint64_t output = 0; uint64_t bitmask; int i; @@ -271,7 +263,7 @@ void jumpnsteps(Hitag_State *hstate, int table) // if si is 1, di.si = di; if si is 0, di.si = 0 bitmask = 1; - for (i=0; i<48; i++) { + for (i = 0; i < 48; i++) { if (hstate->shiftreg & bitmask) { output = output ^ thisd[i]; } @@ -281,12 +273,11 @@ void jumpnsteps(Hitag_State *hstate, int table) hstate->shiftreg = output; buildlfsr(hstate); -} +} // thread to build a part of the table -void *buildtable(void *d) -{ +void *buildtable(void *d) { Hitag_State hstate; Hitag_State hstate2; unsigned long i; @@ -301,7 +292,7 @@ void *buildtable(void *d) buildlfsr(&hstate); /* jump to offset using jump table 2 (2048) */ - for (i=0; iptr > t1->data) { writetable(t1); @@ -531,7 +518,7 @@ int main(int argc, char *argv[]) // start the threads - for (i=0; ilen); i++) { + for (i = 0; (i < filestat.st_size) && (j < r->len); i++) { if ((data[i] != 0x0a) && (data[i] != 0x0d) && (data[i] != 0x20)) { if (!nibble) { r->data[j] = hex2bin(data[i]) << 4; @@ -93,8 +91,7 @@ int loadrngdata(struct rngdata *r, char *file) return 1; } -int makecand(unsigned char *c, struct rngdata *r, int bitoffset) -{ +int makecand(unsigned char *c, struct rngdata *r, int bitoffset) { int bytenum; int bitnum; int i; @@ -107,7 +104,7 @@ int makecand(unsigned char *c, struct rngdata *r, int bitoffset) bytenum = bitoffset / 8; bitnum = bitoffset % 8; - for (i=0; i<6; i++) { + for (i = 0; i < 6; i++) { if (!bitnum) { c[i] = r->data[bytenum + i]; } else { @@ -120,8 +117,7 @@ int makecand(unsigned char *c, struct rngdata *r, int bitoffset) // test the candidate against the next or previous rng data -int testcand(unsigned char *f, unsigned char *rt, int fwd) -{ +int testcand(unsigned char *f, unsigned char *rt, int fwd) { Hitag_State hstate; int i; uint32_t ks1; @@ -130,8 +126,8 @@ int testcand(unsigned char *f, unsigned char *rt, int fwd) // build the prng state at the candidate hstate.shiftreg = 0; - for (i=0; i<6; i++) { - hstate.shiftreg = (hstate.shiftreg << 8) | f[i+4]; + for (i = 0; i < 6; i++) { + hstate.shiftreg = (hstate.shiftreg << 8) | f[i + 4]; } buildlfsr(&hstate); @@ -149,7 +145,7 @@ int testcand(unsigned char *f, unsigned char *rt, int fwd) ks2 = hitag2_nstep(&hstate, 24); writebuf(buf, ks1, 3); - writebuf(buf+3, ks2, 3); + writebuf(buf + 3, ks2, 3); // compare them if (!memcmp(buf, rt, 6)) { @@ -159,8 +155,7 @@ int testcand(unsigned char *f, unsigned char *rt, int fwd) } } -int searchcand(unsigned char *c, unsigned char *rt, int fwd, unsigned char *m, unsigned char *s) -{ +int searchcand(unsigned char *c, unsigned char *rt, int fwd, unsigned char *m, unsigned char *s) { int fd; struct stat filestat; char file[64]; @@ -193,7 +188,7 @@ int searchcand(unsigned char *c, unsigned char *rt, int fwd, unsigned char *m, u exit(1); } - memcpy(item, c+2, 4); + memcpy(item, c + 2, 4); found = (unsigned char *)bsearch(item, data, filestat.st_size / DATASIZE, DATASIZE, datacmp); @@ -209,13 +204,13 @@ int searchcand(unsigned char *c, unsigned char *rt, int fwd, unsigned char *m, u while (((found - data) <= (filestat.st_size - DATASIZE)) && (!memcmp(found, item, 4))) { if (testcand(found, rt, fwd)) { memcpy(m, c, 2); - memcpy(m+2, found, 4); - memcpy(s, found+4, 6); + memcpy(m + 2, found, 4); + memcpy(s, found + 4, 6); munmap(data, filestat.st_size); close(fd); return 1; - } + } found = found + DATASIZE; } @@ -228,8 +223,7 @@ int searchcand(unsigned char *c, unsigned char *rt, int fwd, unsigned char *m, u } -int findmatch(struct rngdata *r, unsigned char *outmatch, unsigned char *outstate, int *bitoffset) -{ +int findmatch(struct rngdata *r, unsigned char *outmatch, unsigned char *outstate, int *bitoffset) { int i; int bitlen; unsigned char cand[6]; @@ -243,7 +237,7 @@ int findmatch(struct rngdata *r, unsigned char *outmatch, unsigned char *outstat bitlen = r->len * 8; - for (i=0; i<=bitlen - 48; i++) { + for (i = 0; i <= bitlen - 48; i++) { // print progress if ((i % 100) == 0) { printf("searching on bit %d\n", i); @@ -283,8 +277,7 @@ int findmatch(struct rngdata *r, unsigned char *outmatch, unsigned char *outstat -void rollbackrng(Hitag_State *hstate, unsigned char *s, int offset) -{ +void rollbackrng(Hitag_State *hstate, unsigned char *s, int offset) { int i; if (!s) { @@ -294,7 +287,7 @@ void rollbackrng(Hitag_State *hstate, unsigned char *s, int offset) // build prng at recovered offset hstate->shiftreg = 0; - for (i=0; i<6; i++) { + for (i = 0; i < 6; i++) { hstate->shiftreg = (hstate->shiftreg << 8) | s[i]; } @@ -313,8 +306,7 @@ void rollbackrng(Hitag_State *hstate, unsigned char *s, int offset) } -uint64_t recoverkey(Hitag_State *hstate, char *uidstr, char *nRstr) -{ +uint64_t recoverkey(Hitag_State *hstate, char *uidstr, char *nRstr) { uint64_t key; uint64_t keyupper; uint32_t uid; @@ -333,7 +325,7 @@ uint64_t recoverkey(Hitag_State *hstate, char *uidstr, char *nRstr) uidtmp = uid; // rollback and extract bits b - for (i=0; i<32; i++) { + for (i = 0; i < 32; i++) { hstate->shiftreg = ((hstate->shiftreg) << 1) | ((uidtmp >> 31) & 0x1); uidtmp = uidtmp << 1; b = (b << 1) | fnf(hstate->shiftreg); @@ -364,8 +356,7 @@ uint64_t recoverkey(Hitag_State *hstate, char *uidstr, char *nRstr) } -int main(int argc, char *argv[]) -{ +int main(int argc, char *argv[]) { Hitag_State hstate; struct rngdata rng; int bitoffset = 0; @@ -420,7 +411,7 @@ int main(int argc, char *argv[]) printf("\n"); printf("KEY:\t\t"); - for (i=0; i<6; i++) { + for (i = 0; i < 6; i++) { printf("%02X", (int)(key & 0xff)); key = key >> 8; } diff --git a/tools/hitag2crack/crack2/ht2crack2utils.c b/tools/hitag2crack/crack2/ht2crack2utils.c index 2152f8ef3..75d4c27a9 100644 --- a/tools/hitag2crack/crack2/ht2crack2utils.c +++ b/tools/hitag2crack/crack2/ht2crack2utils.c @@ -1,13 +1,11 @@ #include "ht2crack2utils.h" // writes a value into a buffer as a series of bytes -void writebuf(unsigned char *buf, uint64_t val, unsigned int len) -{ +void writebuf(unsigned char *buf, uint64_t val, unsigned int len) { int i; char c; - for (i=len-1; i>=0; i--) - { + for (i = len - 1; i >= 0; i--) { c = val & 0xff; buf[i] = c; val = val >> 8; @@ -17,18 +15,17 @@ void writebuf(unsigned char *buf, uint64_t val, unsigned int len) /* simple hexdump for testing purposes */ -void shexdump(unsigned char *data, int data_len) -{ +void shexdump(unsigned char *data, int data_len) { int i; if (!data || (data_len <= 0)) { printf("shexdump: invalid parameters\n"); return; } - + printf("Hexdump from %p:\n", data); - for (i=0; i> 7); x = x << 1; } @@ -60,14 +56,13 @@ void printbin(unsigned char *c) } -void printbin2(uint64_t val, unsigned int size) -{ +void printbin2(uint64_t val, unsigned int size) { int i; uint64_t mask = 1; mask = mask << (size - 1); - for (i=0; ishiftreg, 48); printf("\n"); @@ -89,8 +83,7 @@ void printstate(Hitag_State *hstate) // convert hex char to binary -unsigned char hex2bin(unsigned char c) -{ +unsigned char hex2bin(unsigned char c) { if ((c >= '0') && (c <= '9')) { return (c - '0'); } else if ((c >= 'a') && (c <= 'f')) { @@ -103,8 +96,7 @@ unsigned char hex2bin(unsigned char c) } // return a single bit from a value -int bitn(uint64_t x, int bit) -{ +int bitn(uint64_t x, int bit) { uint64_t bitmask = 1; bitmask = bitmask << bit; @@ -118,20 +110,18 @@ int bitn(uint64_t x, int bit) // the sub-function R that rollback depends upon -int fnR(uint64_t x) -{ +int fnR(uint64_t x) { // renumbered bits because my state is 0-47, not 1-48 return (bitn(x, 1) ^ bitn(x, 2) ^ bitn(x, 5) ^ bitn(x, 6) ^ bitn(x, 7) ^ - bitn(x, 15) ^ bitn(x, 21) ^ bitn(x, 22) ^ bitn(x, 25) ^ bitn(x, 29) ^ bitn(x, 40) ^ - bitn(x, 41) ^ bitn(x, 42) ^ bitn(x, 45) ^ bitn(x, 46) ^ bitn(x, 47)); + bitn(x, 15) ^ bitn(x, 21) ^ bitn(x, 22) ^ bitn(x, 25) ^ bitn(x, 29) ^ bitn(x, 40) ^ + bitn(x, 41) ^ bitn(x, 42) ^ bitn(x, 45) ^ bitn(x, 46) ^ bitn(x, 47)); } // the rollback function that lets us go backwards in time -void rollback(Hitag_State *hstate, unsigned int steps) -{ +void rollback(Hitag_State *hstate, unsigned int steps) { int i; - for (i=0; ishiftreg = ((hstate->shiftreg << 1) & 0xffffffffffff) | fnR(hstate->shiftreg); } @@ -139,24 +129,20 @@ void rollback(Hitag_State *hstate, unsigned int steps) // the three filter sub-functions that feed fnf -int fa(unsigned int i) -{ +int fa(unsigned int i) { return bitn(0x2C79, i); } -int fb(unsigned int i) -{ +int fb(unsigned int i) { return bitn(0x6671, i); } -int fc(unsigned int i) -{ +int fc(unsigned int i) { return bitn(0x7907287B, i); } // the filter function that generates a bit of output from the prng state -int fnf(uint64_t s) -{ +int fnf(uint64_t s) { unsigned int x1, x2, x3, x4, x5, x6; x1 = (bitn(s, 2) << 0) | (bitn(s, 3) << 1) | (bitn(s, 5) << 2) | (bitn(s, 6) << 3); @@ -171,16 +157,15 @@ int fnf(uint64_t s) } // builds the lfsr for the prng (quick calcs for hitag2_nstep()) -void buildlfsr(Hitag_State *hstate) -{ +void buildlfsr(Hitag_State *hstate) { uint64_t state = hstate->shiftreg; uint64_t temp; temp = state ^ (state >> 1); hstate->lfsr = state ^ (state >> 6) ^ (state >> 16) - ^ (state >> 26) ^ (state >> 30) ^ (state >> 41) - ^ (temp >> 2) ^ (temp >> 7) ^ (temp >> 22) - ^ (temp >> 42) ^ (temp >> 46); + ^ (state >> 26) ^ (state >> 30) ^ (state >> 41) + ^ (temp >> 2) ^ (temp >> 7) ^ (temp >> 22) + ^ (temp >> 42) ^ (temp >> 46); } diff --git a/tools/hitag2crack/crack2/rfidler.h b/tools/hitag2crack/crack2/rfidler.h index c8ce90396..933547e6b 100644 --- a/tools/hitag2crack/crack2/rfidler.h +++ b/tools/hitag2crack/crack2/rfidler.h @@ -336,7 +336,7 @@ extern rtccDate RTC_date; // date structure #define TAG_TYPE_AWID_26 17 #define TAG_TYPE_EM4X05 18 #define TAG_TYPE_TAMAGOTCHI 19 -#define TAG_TYPE_HDX 20 // same underlying data as FDX-B, but different modulation & telegram +#define TAG_TYPE_HDX 20 // same underlying data as FDX-B, but different modulation & telegram // various diff --git a/tools/hitag2crack/crack2/util.h b/tools/hitag2crack/crack2/util.h index c0d4c156a..c20fdf3c2 100644 --- a/tools/hitag2crack/crack2/util.h +++ b/tools/hitag2crack/crack2/util.h @@ -182,7 +182,7 @@ unsigned char getbit(unsigned char byte, unsigned char bit); void bytestohex(unsigned char *target, unsigned char *source, unsigned int length); unsigned int manchester_encode(unsigned char *target, unsigned char *source, unsigned int length); unsigned int manchester_decode(unsigned char *target, unsigned char *source, unsigned int length); -char * strip_newline(char *buff); +char *strip_newline(char *buff); BOOL command_ack(BOOL data); BOOL command_nack(BYTE *reason); BOOL command_unknown(void); diff --git a/tools/hitag2crack/crack2/utilpart.c b/tools/hitag2crack/crack2/utilpart.c index 210853ec1..c46148491 100644 --- a/tools/hitag2crack/crack2/utilpart.c +++ b/tools/hitag2crack/crack2/utilpart.c @@ -142,19 +142,17 @@ rtccTime RTC_time; // time structure rtccDate RTC_date; // date structure // convert byte-reversed 8 digit hex to unsigned long -unsigned long hexreversetoulong(BYTE *hex) -{ - unsigned long ret= 0L; +unsigned long hexreversetoulong(BYTE *hex) { + unsigned long ret = 0L; unsigned int x; BYTE i; - if(strlen(hex) != 8) + if (strlen(hex) != 8) return 0L; - for(i= 0 ; i < 4 ; ++i) - { - if(sscanf(hex, "%2X", &x) != 1) - return 0L; + for (i = 0 ; i < 4 ; ++i) { + if (sscanf(hex, "%2X", &x) != 1) + return 0L; ret += ((unsigned long) x) << i * 8; hex += 2; } @@ -162,18 +160,17 @@ unsigned long hexreversetoulong(BYTE *hex) } // convert byte-reversed 12 digit hex to unsigned long -unsigned long long hexreversetoulonglong(BYTE *hex) -{ - unsigned long long ret= 0LL; +unsigned long long hexreversetoulonglong(BYTE *hex) { + unsigned long long ret = 0LL; BYTE tmp[9]; - - // this may seem an odd way to do it, but weird compiler issues were + + // this may seem an odd way to do it, but weird compiler issues were // breaking direct conversion! - - tmp[8]= '\0'; + + tmp[8] = '\0'; memset(tmp + 4, '0', 4); memcpy(tmp, hex + 8, 4); - ret= hexreversetoulong(tmp); + ret = hexreversetoulong(tmp); ret <<= 32; memcpy(tmp, hex, 8); ret += hexreversetoulong(tmp); From c73517b64db3c00ca50e8fedd8c6281ea9ad7af9 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 9 Mar 2020 16:44:07 +0100 Subject: [PATCH 1633/1854] style --- tools/hitag2crack/crack3/HardwareProfile.h | 8 +- tools/hitag2crack/crack3/hitagcrypto.c | 32 ++- tools/hitag2crack/crack3/hitagcrypto.h | 4 +- tools/hitag2crack/crack3/ht2crack3.c | 70 +++--- tools/hitag2crack/crack3/ht2test.c | 5 +- tools/hitag2crack/crack3/rfidler.h | 2 +- tools/hitag2crack/crack3/utilpart.c | 29 ++- tools/hitag2crack/crack4/HardwareProfile.h | 8 +- tools/hitag2crack/crack4/hitagcrypto.c | 32 ++- tools/hitag2crack/crack4/hitagcrypto.h | 4 +- tools/hitag2crack/crack4/ht2crack2utils.c | 67 +++--- tools/hitag2crack/crack4/ht2crack4.c | 234 ++++++++++----------- tools/hitag2crack/crack4/rfidler.h | 2 +- tools/hitag2crack/crack4/utilpart.c | 29 ++- 14 files changed, 233 insertions(+), 293 deletions(-) diff --git a/tools/hitag2crack/crack3/HardwareProfile.h b/tools/hitag2crack/crack3/HardwareProfile.h index a2f804be6..bce139042 100644 --- a/tools/hitag2crack/crack3/HardwareProfile.h +++ b/tools/hitag2crack/crack3/HardwareProfile.h @@ -142,11 +142,11 @@ typedef int rtccDate; #ifndef __PIC32MX__ - #define __PIC32MX__ +#define __PIC32MX__ #endif - + #define GetSystemClock() (80000000ul) -#define GetPeripheralClock() (GetSystemClock()) +#define GetPeripheralClock() (GetSystemClock()) #define GetInstructionClock() (GetSystemClock()) //#define USE_SELF_POWER_SENSE_IO @@ -322,7 +322,7 @@ typedef int rtccDate; // spi for SD card #define SD_CARD_DET LATFbits.LATF0 #define SD_CARD_WE LATFbits.LATF1 // write enable - unused for microsd but allocated anyway as library checks it - // (held LOW by default - cut solder bridge to GND to free pin if required) +// (held LOW by default - cut solder bridge to GND to free pin if required) #define SPI_SD SPI_CHANNEL1 #define SPI_SD_BUFF SPI1BUF #define SPI_SD_STAT SPI1STATbits diff --git a/tools/hitag2crack/crack3/hitagcrypto.c b/tools/hitag2crack/crack3/hitagcrypto.c index 422efbe92..23b88228d 100644 --- a/tools/hitag2crack/crack3/hitagcrypto.c +++ b/tools/hitag2crack/crack3/hitagcrypto.c @@ -229,17 +229,16 @@ static uint32_t hitag2_crypt(uint64_t x); ((S >> (C - 3)) & 8) ) -static uint32_t hitag2_crypt(uint64_t s) -{ +static uint32_t hitag2_crypt(uint64_t s) { const uint32_t ht2_function4a = 0x2C79; // 0010 1100 0111 1001 const uint32_t ht2_function4b = 0x6671; // 0110 0110 0111 0001 const uint32_t ht2_function5c = 0x7907287B; // 0111 1001 0000 0111 0010 1000 0111 1011 uint32_t bitindex; - bitindex = (ht2_function4a >> pickbits2_2 (s, 1, 4)) & 1; - bitindex |= ((ht2_function4b << 1) >> pickbits1_1_2 (s, 7, 11, 13)) & 0x02; - bitindex |= ((ht2_function4b << 2) >> pickbits1x4 (s, 16, 20, 22, 25)) & 0x04; - bitindex |= ((ht2_function4b << 3) >> pickbits2_1_1 (s, 27, 30, 32)) & 0x08; + bitindex = (ht2_function4a >> pickbits2_2(s, 1, 4)) & 1; + bitindex |= ((ht2_function4b << 1) >> pickbits1_1_2(s, 7, 11, 13)) & 0x02; + bitindex |= ((ht2_function4b << 2) >> pickbits1x4(s, 16, 20, 22, 25)) & 0x04; + bitindex |= ((ht2_function4b << 3) >> pickbits2_1_1(s, 27, 30, 32)) & 0x08; bitindex |= ((ht2_function4a << 4) >> pickbits1_2_1(s, 33, 42, 45)) & 0x10; DEBUG_PRINTF("hitag2_crypt bitindex = %02x\n", bitindex); @@ -253,13 +252,12 @@ static uint32_t hitag2_crypt(uint64_t s) * uint32_t serialnum - 32 bit tag serial number * uint32_t initvector - 32 bit random IV from reader, part of tag authentication */ -void hitag2_init(Hitag_State* pstate, uint64_t sharedkey, uint32_t serialnum, uint32_t initvector) -{ +void hitag2_init(Hitag_State *pstate, uint64_t sharedkey, uint32_t serialnum, uint32_t initvector) { // init state, from serial number and lowest 16 bits of shared key uint64_t state = ((sharedkey & 0xFFFF) << 32) | serialnum; // mix the initialisation vector and highest 32 bits of the shared key - initvector ^= (uint32_t) (sharedkey >> 16); + initvector ^= (uint32_t)(sharedkey >> 16); // move 16 bits from (IV xor Shared Key) to top of uint64_t state // these will be XORed in turn with output of the crypto function @@ -320,9 +318,9 @@ void hitag2_init(Hitag_State* pstate, uint64_t sharedkey, uint32_t serialnum, ui // optimise with one 64-bit intermediate uint64_t temp = state ^ (state >> 1); pstate->lfsr = state ^ (state >> 6) ^ (state >> 16) - ^ (state >> 26) ^ (state >> 30) ^ (state >> 41) - ^ (temp >> 2) ^ (temp >> 7) ^ (temp >> 22) - ^ (temp >> 42) ^ (temp >> 46); + ^ (state >> 26) ^ (state >> 30) ^ (state >> 41) + ^ (temp >> 2) ^ (temp >> 7) ^ (temp >> 22) + ^ (temp >> 42) ^ (temp >> 46); } } @@ -338,8 +336,7 @@ void hitag2_init(Hitag_State* pstate, uint64_t sharedkey, uint32_t serialnum, ui * Hitag_State* pstate - in/out, internal cipher state after initialisation * uint32_t steps - number of bits requested, (capped at 32) */ -uint32_t hitag2_nstep(Hitag_State* pstate, uint32_t steps) -{ +uint32_t hitag2_nstep(Hitag_State *pstate, uint32_t steps) { uint64_t state = pstate->shiftreg; uint32_t result = 0; uint64_t lfsr = pstate->lfsr; @@ -446,7 +443,7 @@ unsigned hitag2_verifytest() const uint64_t key = rev64 (0x524B494D4E4FUL); const uint32_t serial = rev32 (0x69574349); const uint32_t initvec = rev32 (0x72456E65); - + uint32_t i; Hitag_State state; @@ -469,11 +466,10 @@ unsigned hitag2_verifytest() #ifdef UNIT_TEST -int main(int argc, char* argv[]) -{ +int main(int argc, char *argv[]) { unsigned pass = hitag2_verifytest(); - printf ("Crypto Verify test = %s\n\n", pass ? "PASS" : "FAIL"); + printf("Crypto Verify test = %s\n\n", pass ? "PASS" : "FAIL"); if (pass) { hitag2_benchtest(10000); diff --git a/tools/hitag2crack/crack3/hitagcrypto.h b/tools/hitag2crack/crack3/hitagcrypto.h index d5aa9104c..46d447370 100644 --- a/tools/hitag2crack/crack3/hitagcrypto.h +++ b/tools/hitag2crack/crack3/hitagcrypto.h @@ -159,9 +159,9 @@ typedef struct { uint64_t lfsr; // fast lfsr, used to make software faster } Hitag_State; -void hitag2_init(Hitag_State* pstate, uint64_t sharedkey, uint32_t serialnum, uint32_t initvector); +void hitag2_init(Hitag_State *pstate, uint64_t sharedkey, uint32_t serialnum, uint32_t initvector); -uint32_t hitag2_nstep(Hitag_State* pstate, uint32_t steps); +uint32_t hitag2_nstep(Hitag_State *pstate, uint32_t steps); unsigned int hitag2_benchtest_gen32(); unsigned int hitag2_benchtest(uint32_t count); diff --git a/tools/hitag2crack/crack3/ht2crack3.c b/tools/hitag2crack/crack3/ht2crack3.c index 190f8197d..747f7785c 100644 --- a/tools/hitag2crack/crack3/ht2crack3.c +++ b/tools/hitag2crack/crack3/ht2crack3.c @@ -34,11 +34,10 @@ struct threaddata { uint64_t klowerrange; }; -void printbin(uint64_t val) -{ +void printbin(uint64_t val) { int i; - for (i=0; i<64; i++) { + for (i = 0; i < 64; i++) { if (val & 0x8000000000000000) { printf("1"); } else { @@ -48,8 +47,7 @@ void printbin(uint64_t val) } } -void printstate(Hitag_State *hstate) -{ +void printstate(Hitag_State *hstate) { printf("shiftreg =\t"); printbin(hstate->shiftreg); printf("\n"); @@ -70,17 +68,16 @@ void printstate(Hitag_State *hstate) ((S >> (C - 3)) & 8) ) -static uint32_t hitag2_crypt(uint64_t s) -{ +static uint32_t hitag2_crypt(uint64_t s) { const uint32_t ht2_function4a = 0x2C79; // 0010 1100 0111 1001 const uint32_t ht2_function4b = 0x6671; // 0110 0110 0111 0001 const uint32_t ht2_function5c = 0x7907287B; // 0111 1001 0000 0111 0010 1000 0111 1011 uint32_t bitindex; - bitindex = (ht2_function4a >> pickbits2_2 (s, 1, 4)) & 1; - bitindex |= ((ht2_function4b << 1) >> pickbits1_1_2 (s, 7, 11, 13)) & 0x02; - bitindex |= ((ht2_function4b << 2) >> pickbits1x4 (s, 16, 20, 22, 25)) & 0x04; - bitindex |= ((ht2_function4b << 3) >> pickbits2_1_1 (s, 27, 30, 32)) & 0x08; + bitindex = (ht2_function4a >> pickbits2_2(s, 1, 4)) & 1; + bitindex |= ((ht2_function4b << 1) >> pickbits1_1_2(s, 7, 11, 13)) & 0x02; + bitindex |= ((ht2_function4b << 2) >> pickbits1x4(s, 16, 20, 22, 25)) & 0x04; + bitindex |= ((ht2_function4b << 3) >> pickbits2_1_1(s, 27, 30, 32)) & 0x08; bitindex |= ((ht2_function4a << 4) >> pickbits1_2_1(s, 33, 42, 45)) & 0x10; return (ht2_function5c >> bitindex) & 1; @@ -89,17 +86,16 @@ static uint32_t hitag2_crypt(uint64_t s) // this function is a modification of the filter function f, based heavily // on the hitag2_crypt function in Rfidler -int fnP(uint64_t klowery) -{ +int fnP(uint64_t klowery) { const uint32_t ht2_function4a = 0x2C79; // 0010 1100 0111 1001 const uint32_t ht2_function4b = 0x6671; // 0110 0110 0111 0001 const uint32_t ht2_function4p = 0xAE83; // 1010 1110 1000 0011 uint32_t i; - i = (ht2_function4a >> pickbits2_2 (klowery, 2, 5)) & 1; - i |= ((ht2_function4b << 1) >> pickbits1_1_2 (klowery, 8, 12, 14)) & 0x02; - i |= ((ht2_function4b << 2) >> pickbits1x4 (klowery, 17, 21, 23, 26)) & 0x04; - i |= ((ht2_function4b << 3) >> pickbits2_1_1 (klowery, 28, 31, 33)) & 0x08; + i = (ht2_function4a >> pickbits2_2(klowery, 2, 5)) & 1; + i |= ((ht2_function4b << 1) >> pickbits1_1_2(klowery, 8, 12, 14)) & 0x02; + i |= ((ht2_function4b << 2) >> pickbits1x4(klowery, 17, 21, 23, 26)) & 0x04; + i |= ((ht2_function4b << 3) >> pickbits2_1_1(klowery, 28, 31, 33)) & 0x08; // modified to use reference implementation approach // orig fc table is 0x7907287B = 0111 1001 0000 0111 0010 1000 0111 1011 @@ -109,8 +105,7 @@ int fnP(uint64_t klowery) } // comparison function for sorting/searching Tklower entries -int Tk_cmp(const void *v1, const void *v2) -{ +int Tk_cmp(const void *v1, const void *v2) { const struct Tklower *Tk1 = (struct Tklower *)v1; const struct Tklower *Tk2 = (struct Tklower *)v2; @@ -148,8 +143,7 @@ int is_kmiddle_badguess(uint64_t z, struct Tklower *Tk, int max, int aR0) { } // function to test if a partial key is valid -int testkey(uint64_t *out, uint64_t uid, uint64_t pkey, uint64_t nR, uint64_t aR) -{ +int testkey(uint64_t *out, uint64_t uid, uint64_t pkey, uint64_t nR, uint64_t aR) { uint64_t kupper; uint64_t key; Hitag_State hstate; @@ -162,7 +156,7 @@ int testkey(uint64_t *out, uint64_t uid, uint64_t pkey, uint64_t nR, uint64_t aR normaR = ((revaR >> 24) | ((revaR >> 8) & 0xff00) | ((revaR << 8) & 0xff0000) | (revaR << 24)); // search for remaining 14 bits - for (kupper=0; kupper < 0x3fff; kupper++) { + for (kupper = 0; kupper < 0x3fff; kupper++) { key = (kupper << 34) | pkey; hitag2_init(&hstate, key, uid, nR); b = hitag2_nstep(&hstate, 32); @@ -170,7 +164,7 @@ int testkey(uint64_t *out, uint64_t uid, uint64_t pkey, uint64_t nR, uint64_t aR *out = key; return 1; } - } + } return 0; } @@ -205,8 +199,7 @@ int testkey(uint64_t *out, uint64_t uid, uint64_t pkey, uint64_t nR, uint64_t aR // effectively work out candidates for the lower 34 bits of the key. -void *crack(void *d) -{ +void *crack(void *d) { struct threaddata *data = (struct threaddata *)d; uint64_t uid; struct nRaR *TnRaR; @@ -249,11 +242,11 @@ void *crack(void *d) } // find keys - for (klower=data->klowerstart; klower < (data->klowerstart + data->klowerrange); klower++) { + for (klower = data->klowerstart; klower < (data->klowerstart + data->klowerrange); klower++) { printf("trying klower = 0x%05lx\n", klower); // build table count = 0; - for (y=0; y<0x40000; y++) { + for (y = 0; y < 0x40000; y++) { // create klowery klowery = (y << 16) | klower; // check for cases where right most bit of fc doesn't matter @@ -268,9 +261,9 @@ void *crack(void *d) // insert y into shiftreg and extract keystream, reversed order b = 0; ytmp = y; - for (j=0; j<2; j++) { + for (j = 0; j < 2; j++) { hstate.shiftreg = hstate.shiftreg | ((ytmp & 0xffff) << 48); - for (i=0; i<16; i++) { + for (i = 0; i < 16; i++) { hstate.shiftreg = hstate.shiftreg >> 1; bit = hitag2_crypt(hstate.shiftreg); b = (b >> 1) | (bit << 31); @@ -295,11 +288,11 @@ void *crack(void *d) qsort(Tk, count, sizeof(struct Tklower), Tk_cmp); // look for matches - for (kmiddle=0; kmiddle<0x40000; kmiddle++) { + for (kmiddle = 0; kmiddle < 0x40000; kmiddle++) { // loop over nRaR pairs badguess = 0; found = 0; - for (i=0; (i> 40) & 0xff) | ((revkey >> 24) & 0xff00) | ((revkey >> 8) & 0xff0000) | ((revkey << 8) & 0xff000000) | ((revkey << 24) & 0xff00000000) | ((revkey << 40) & 0xff0000000000); @@ -331,8 +324,7 @@ void *crack(void *d) return NULL; } -int main(int argc, char *argv[]) -{ +int main(int argc, char *argv[]) { FILE *fp; int i; pthread_t threads[NUM_THREADS]; @@ -401,8 +393,8 @@ int main(int argc, char *argv[]) } *buft2 = 0x00; if (!strncmp(buf, "0x", 2)) { - TnRaR[numnrar].nR = rev32(hexreversetoulong(buf+2)); - TnRaR[numnrar].aR = rev32(hexreversetoulong(buft1+2)); + TnRaR[numnrar].nR = rev32(hexreversetoulong(buf + 2)); + TnRaR[numnrar].aR = rev32(hexreversetoulong(buft1 + 2)); } else { TnRaR[numnrar].nR = rev32(hexreversetoulong(buf)); TnRaR[numnrar].aR = rev32(hexreversetoulong(buft1)); @@ -423,7 +415,7 @@ int main(int argc, char *argv[]) exit(1); } - for (i=0; i> (C - 3)) & 8) ) -static uint32_t hitag2_crypt(uint64_t s) -{ +static uint32_t hitag2_crypt(uint64_t s) { const uint32_t ht2_function4a = 0x2C79; // 0010 1100 0111 1001 const uint32_t ht2_function4b = 0x6671; // 0110 0110 0111 0001 const uint32_t ht2_function5c = 0x7907287B; // 0111 1001 0000 0111 0010 1000 0111 1011 uint32_t bitindex; - bitindex = (ht2_function4a >> pickbits2_2 (s, 1, 4)) & 1; - bitindex |= ((ht2_function4b << 1) >> pickbits1_1_2 (s, 7, 11, 13)) & 0x02; - bitindex |= ((ht2_function4b << 2) >> pickbits1x4 (s, 16, 20, 22, 25)) & 0x04; - bitindex |= ((ht2_function4b << 3) >> pickbits2_1_1 (s, 27, 30, 32)) & 0x08; + bitindex = (ht2_function4a >> pickbits2_2(s, 1, 4)) & 1; + bitindex |= ((ht2_function4b << 1) >> pickbits1_1_2(s, 7, 11, 13)) & 0x02; + bitindex |= ((ht2_function4b << 2) >> pickbits1x4(s, 16, 20, 22, 25)) & 0x04; + bitindex |= ((ht2_function4b << 3) >> pickbits2_1_1(s, 27, 30, 32)) & 0x08; bitindex |= ((ht2_function4a << 4) >> pickbits1_2_1(s, 33, 42, 45)) & 0x10; DEBUG_PRINTF("hitag2_crypt bitindex = %02x\n", bitindex); @@ -253,13 +252,12 @@ static uint32_t hitag2_crypt(uint64_t s) * uint32_t serialnum - 32 bit tag serial number * uint32_t initvector - 32 bit random IV from reader, part of tag authentication */ -void hitag2_init(Hitag_State* pstate, uint64_t sharedkey, uint32_t serialnum, uint32_t initvector) -{ +void hitag2_init(Hitag_State *pstate, uint64_t sharedkey, uint32_t serialnum, uint32_t initvector) { // init state, from serial number and lowest 16 bits of shared key uint64_t state = ((sharedkey & 0xFFFF) << 32) | serialnum; // mix the initialisation vector and highest 32 bits of the shared key - initvector ^= (uint32_t) (sharedkey >> 16); + initvector ^= (uint32_t)(sharedkey >> 16); // move 16 bits from (IV xor Shared Key) to top of uint64_t state // these will be XORed in turn with output of the crypto function @@ -320,9 +318,9 @@ void hitag2_init(Hitag_State* pstate, uint64_t sharedkey, uint32_t serialnum, ui // optimise with one 64-bit intermediate uint64_t temp = state ^ (state >> 1); pstate->lfsr = state ^ (state >> 6) ^ (state >> 16) - ^ (state >> 26) ^ (state >> 30) ^ (state >> 41) - ^ (temp >> 2) ^ (temp >> 7) ^ (temp >> 22) - ^ (temp >> 42) ^ (temp >> 46); + ^ (state >> 26) ^ (state >> 30) ^ (state >> 41) + ^ (temp >> 2) ^ (temp >> 7) ^ (temp >> 22) + ^ (temp >> 42) ^ (temp >> 46); } } @@ -338,8 +336,7 @@ void hitag2_init(Hitag_State* pstate, uint64_t sharedkey, uint32_t serialnum, ui * Hitag_State* pstate - in/out, internal cipher state after initialisation * uint32_t steps - number of bits requested, (capped at 32) */ -uint32_t hitag2_nstep(Hitag_State* pstate, uint32_t steps) -{ +uint32_t hitag2_nstep(Hitag_State *pstate, uint32_t steps) { uint64_t state = pstate->shiftreg; uint32_t result = 0; uint64_t lfsr = pstate->lfsr; @@ -446,7 +443,7 @@ unsigned hitag2_verifytest() const uint64_t key = rev64 (0x524B494D4E4FUL); const uint32_t serial = rev32 (0x69574349); const uint32_t initvec = rev32 (0x72456E65); - + uint32_t i; Hitag_State state; @@ -469,11 +466,10 @@ unsigned hitag2_verifytest() #ifdef UNIT_TEST -int main(int argc, char* argv[]) -{ +int main(int argc, char *argv[]) { unsigned pass = hitag2_verifytest(); - printf ("Crypto Verify test = %s\n\n", pass ? "PASS" : "FAIL"); + printf("Crypto Verify test = %s\n\n", pass ? "PASS" : "FAIL"); if (pass) { hitag2_benchtest(10000); diff --git a/tools/hitag2crack/crack4/hitagcrypto.h b/tools/hitag2crack/crack4/hitagcrypto.h index d5aa9104c..46d447370 100644 --- a/tools/hitag2crack/crack4/hitagcrypto.h +++ b/tools/hitag2crack/crack4/hitagcrypto.h @@ -159,9 +159,9 @@ typedef struct { uint64_t lfsr; // fast lfsr, used to make software faster } Hitag_State; -void hitag2_init(Hitag_State* pstate, uint64_t sharedkey, uint32_t serialnum, uint32_t initvector); +void hitag2_init(Hitag_State *pstate, uint64_t sharedkey, uint32_t serialnum, uint32_t initvector); -uint32_t hitag2_nstep(Hitag_State* pstate, uint32_t steps); +uint32_t hitag2_nstep(Hitag_State *pstate, uint32_t steps); unsigned int hitag2_benchtest_gen32(); unsigned int hitag2_benchtest(uint32_t count); diff --git a/tools/hitag2crack/crack4/ht2crack2utils.c b/tools/hitag2crack/crack4/ht2crack2utils.c index 2152f8ef3..75d4c27a9 100644 --- a/tools/hitag2crack/crack4/ht2crack2utils.c +++ b/tools/hitag2crack/crack4/ht2crack2utils.c @@ -1,13 +1,11 @@ #include "ht2crack2utils.h" // writes a value into a buffer as a series of bytes -void writebuf(unsigned char *buf, uint64_t val, unsigned int len) -{ +void writebuf(unsigned char *buf, uint64_t val, unsigned int len) { int i; char c; - for (i=len-1; i>=0; i--) - { + for (i = len - 1; i >= 0; i--) { c = val & 0xff; buf[i] = c; val = val >> 8; @@ -17,18 +15,17 @@ void writebuf(unsigned char *buf, uint64_t val, unsigned int len) /* simple hexdump for testing purposes */ -void shexdump(unsigned char *data, int data_len) -{ +void shexdump(unsigned char *data, int data_len) { int i; if (!data || (data_len <= 0)) { printf("shexdump: invalid parameters\n"); return; } - + printf("Hexdump from %p:\n", data); - for (i=0; i> 7); x = x << 1; } @@ -60,14 +56,13 @@ void printbin(unsigned char *c) } -void printbin2(uint64_t val, unsigned int size) -{ +void printbin2(uint64_t val, unsigned int size) { int i; uint64_t mask = 1; mask = mask << (size - 1); - for (i=0; ishiftreg, 48); printf("\n"); @@ -89,8 +83,7 @@ void printstate(Hitag_State *hstate) // convert hex char to binary -unsigned char hex2bin(unsigned char c) -{ +unsigned char hex2bin(unsigned char c) { if ((c >= '0') && (c <= '9')) { return (c - '0'); } else if ((c >= 'a') && (c <= 'f')) { @@ -103,8 +96,7 @@ unsigned char hex2bin(unsigned char c) } // return a single bit from a value -int bitn(uint64_t x, int bit) -{ +int bitn(uint64_t x, int bit) { uint64_t bitmask = 1; bitmask = bitmask << bit; @@ -118,20 +110,18 @@ int bitn(uint64_t x, int bit) // the sub-function R that rollback depends upon -int fnR(uint64_t x) -{ +int fnR(uint64_t x) { // renumbered bits because my state is 0-47, not 1-48 return (bitn(x, 1) ^ bitn(x, 2) ^ bitn(x, 5) ^ bitn(x, 6) ^ bitn(x, 7) ^ - bitn(x, 15) ^ bitn(x, 21) ^ bitn(x, 22) ^ bitn(x, 25) ^ bitn(x, 29) ^ bitn(x, 40) ^ - bitn(x, 41) ^ bitn(x, 42) ^ bitn(x, 45) ^ bitn(x, 46) ^ bitn(x, 47)); + bitn(x, 15) ^ bitn(x, 21) ^ bitn(x, 22) ^ bitn(x, 25) ^ bitn(x, 29) ^ bitn(x, 40) ^ + bitn(x, 41) ^ bitn(x, 42) ^ bitn(x, 45) ^ bitn(x, 46) ^ bitn(x, 47)); } // the rollback function that lets us go backwards in time -void rollback(Hitag_State *hstate, unsigned int steps) -{ +void rollback(Hitag_State *hstate, unsigned int steps) { int i; - for (i=0; ishiftreg = ((hstate->shiftreg << 1) & 0xffffffffffff) | fnR(hstate->shiftreg); } @@ -139,24 +129,20 @@ void rollback(Hitag_State *hstate, unsigned int steps) // the three filter sub-functions that feed fnf -int fa(unsigned int i) -{ +int fa(unsigned int i) { return bitn(0x2C79, i); } -int fb(unsigned int i) -{ +int fb(unsigned int i) { return bitn(0x6671, i); } -int fc(unsigned int i) -{ +int fc(unsigned int i) { return bitn(0x7907287B, i); } // the filter function that generates a bit of output from the prng state -int fnf(uint64_t s) -{ +int fnf(uint64_t s) { unsigned int x1, x2, x3, x4, x5, x6; x1 = (bitn(s, 2) << 0) | (bitn(s, 3) << 1) | (bitn(s, 5) << 2) | (bitn(s, 6) << 3); @@ -171,16 +157,15 @@ int fnf(uint64_t s) } // builds the lfsr for the prng (quick calcs for hitag2_nstep()) -void buildlfsr(Hitag_State *hstate) -{ +void buildlfsr(Hitag_State *hstate) { uint64_t state = hstate->shiftreg; uint64_t temp; temp = state ^ (state >> 1); hstate->lfsr = state ^ (state >> 6) ^ (state >> 16) - ^ (state >> 26) ^ (state >> 30) ^ (state >> 41) - ^ (temp >> 2) ^ (temp >> 7) ^ (temp >> 22) - ^ (temp >> 42) ^ (temp >> 46); + ^ (state >> 26) ^ (state >> 30) ^ (state >> 41) + ^ (temp >> 2) ^ (temp >> 7) ^ (temp >> 22) + ^ (temp >> 42) ^ (temp >> 46); } diff --git a/tools/hitag2crack/crack4/ht2crack4.c b/tools/hitag2crack/crack4/ht2crack4.c index da439692f..44952f4b7 100644 --- a/tools/hitag2crack/crack4/ht2crack4.c +++ b/tools/hitag2crack/crack4/ht2crack4.c @@ -93,8 +93,7 @@ uint64_t uid; int maxtablesize = 800000; uint64_t supplied_testkey = 0; -void usage() -{ +void usage() { printf("ht2crack4 - K Sheldrake, based on the work of Garcia et al\n\n"); printf("Cracks a HiTag2 key using a small number (4 to 16) of encrypted\n"); printf("nonce and challenge response pairs, using a fast correlation\n"); @@ -130,46 +129,44 @@ const uint64_t ht2_function5c = 0x7907287B; // 0111 1001 0000 0111 0010 1000 011 * a known least-sig pattern. first index is num bits in known part, second is the * bit pattern of the known part. */ double pfna[][8] = { -{0.50000, 0.50000, }, -{0.50000, 0.50000, 0.50000, 0.50000, }, -{0.50000, 0.00000, 0.50000, 1.00000, 0.50000, 1.00000, 0.50000, 0.00000, }, + {0.50000, 0.50000, }, + {0.50000, 0.50000, 0.50000, 0.50000, }, + {0.50000, 0.00000, 0.50000, 1.00000, 0.50000, 1.00000, 0.50000, 0.00000, }, }; double pfnb[][8] = { -{0.62500, 0.37500, }, -{0.50000, 0.75000, 0.75000, 0.00000, }, -{0.50000, 0.50000, 0.50000, 0.00000, 0.50000, 1.00000, 1.00000, 0.00000, }, + {0.62500, 0.37500, }, + {0.50000, 0.75000, 0.75000, 0.00000, }, + {0.50000, 0.50000, 0.50000, 0.00000, 0.50000, 1.00000, 1.00000, 0.00000, }, }; double pfnc[][16] = { -{0.50000, 0.50000, }, -{0.62500, 0.62500, 0.37500, 0.37500, }, -{0.75000, 0.50000, 0.25000, 0.75000, 0.50000, 0.75000, 0.50000, 0.00000, }, -{1.00000, 1.00000, 0.50000, 0.50000, 0.50000, 0.50000, 0.50000, 0.00000, 0.50000, 0.00000, 0.00000, 1.00000, 0.50000, 1.00000, 0.50000, 0.00000, }, + {0.50000, 0.50000, }, + {0.62500, 0.62500, 0.37500, 0.37500, }, + {0.75000, 0.50000, 0.25000, 0.75000, 0.50000, 0.75000, 0.50000, 0.00000, }, + {1.00000, 1.00000, 0.50000, 0.50000, 0.50000, 0.50000, 0.50000, 0.00000, 0.50000, 0.00000, 0.00000, 1.00000, 0.50000, 1.00000, 0.50000, 0.00000, }, }; /* hitag2_crypt works on the post-shifted form of the lfsr; this is the ref in rfidler code */ -static uint32_t hitag2_crypt(uint64_t s) -{ +static uint32_t hitag2_crypt(uint64_t s) { uint32_t bitindex; - bitindex = (ht2_function4a >> pickbits2_2 (s, 1, 4)) & 1; - bitindex |= ((ht2_function4b << 1) >> pickbits1_1_2 (s, 7, 11, 13)) & 0x02; - bitindex |= ((ht2_function4b << 2) >> pickbits1x4 (s, 16, 20, 22, 25)) & 0x04; - bitindex |= ((ht2_function4b << 3) >> pickbits2_1_1 (s, 27, 30, 32)) & 0x08; + bitindex = (ht2_function4a >> pickbits2_2(s, 1, 4)) & 1; + bitindex |= ((ht2_function4b << 1) >> pickbits1_1_2(s, 7, 11, 13)) & 0x02; + bitindex |= ((ht2_function4b << 2) >> pickbits1x4(s, 16, 20, 22, 25)) & 0x04; + bitindex |= ((ht2_function4b << 3) >> pickbits2_1_1(s, 27, 30, 32)) & 0x08; bitindex |= ((ht2_function4a << 4) >> pickbits1_2_1(s, 33, 42, 45)) & 0x10; return (ht2_function5c >> bitindex) & 1; } /* ht2crypt works on the pre-shifted form of the lfsr; this is the ref in the paper */ -uint64_t ht2crypt(uint64_t s) -{ +uint64_t ht2crypt(uint64_t s) { uint64_t bitindex; - bitindex = (ht2_function4a >> pickbits2_2 (s, 2, 5)) & 1; - bitindex |= ((ht2_function4b << 1) >> pickbits1_1_2 (s, 8, 12, 14)) & 0x02; - bitindex |= ((ht2_function4b << 2) >> pickbits1x4 (s, 17, 21, 23, 26)) & 0x04; - bitindex |= ((ht2_function4b << 3) >> pickbits2_1_1 (s, 28, 31, 33)) & 0x08; + bitindex = (ht2_function4a >> pickbits2_2(s, 2, 5)) & 1; + bitindex |= ((ht2_function4b << 1) >> pickbits1_1_2(s, 8, 12, 14)) & 0x02; + bitindex |= ((ht2_function4b << 2) >> pickbits1x4(s, 17, 21, 23, 26)) & 0x04; + bitindex |= ((ht2_function4b << 3) >> pickbits2_1_1(s, 28, 31, 33)) & 0x08; bitindex |= ((ht2_function4a << 4) >> pickbits1_2_1(s, 34, 43, 46)) & 0x10; return (ht2_function5c >> bitindex) & 1; @@ -177,11 +174,10 @@ uint64_t ht2crypt(uint64_t s) /* fnL is the feedback function for the reference code */ -uint64_t fnL(uint64_t x) -{ +uint64_t fnL(uint64_t x) { return (bitn(x, 0) ^ bitn(x, 2) ^ bitn(x, 3) ^ bitn(x, 6) ^ bitn(x, 7) ^ bitn(x, 8) ^ - bitn(x, 16) ^ bitn(x, 22) ^ bitn(x, 23) ^ bitn(x, 26) ^ bitn(x, 30) ^ bitn(x, 41) ^ - bitn(x, 42) ^ bitn(x, 43) ^ bitn(x, 46) ^ bitn(x, 47)); + bitn(x, 16) ^ bitn(x, 22) ^ bitn(x, 23) ^ bitn(x, 26) ^ bitn(x, 30) ^ bitn(x, 41) ^ + bitn(x, 42) ^ bitn(x, 43) ^ bitn(x, 46) ^ bitn(x, 47)); } @@ -189,18 +185,18 @@ uint64_t fnL(uint64_t x) * the number of relevant bits. * e.g. if there are 16 confirmed bits in a state, then packed_size[16] = 8 relevant bits. * this is for pre-shifted lfsr */ -unsigned int packed_size[] = { 0, 0, 0, 1, 2, 2, 3, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8, +unsigned int packed_size[] = { 0, 0, 0, 1, 2, 2, 3, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8, 8, 9, 9, 9, 9, 10, 10, 11, 11, 11, 12, 12, 13, 14, 14, 15, - 15, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 18, 19, 19, 20, 20 }; + 15, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 18, 19, 19, 20, 20 + }; /* f20 is the same as hitag2_crypt except it works on the packed version * of the state where all 20 relevant bits are squashed together */ -uint64_t f20(uint64_t y) -{ +uint64_t f20(uint64_t y) { uint64_t bitindex; - bitindex = (ht2_function4a >> (y & 0xf)) & 1; + bitindex = (ht2_function4a >> (y & 0xf)) & 1; bitindex |= ((ht2_function4b << 1) >> ((y >> 4) & 0xf)) & 0x02; bitindex |= ((ht2_function4b << 2) >> ((y >> 8) & 0xf)) & 0x04; bitindex |= ((ht2_function4b << 3) >> ((y >> 12) & 0xf)) & 0x08; @@ -211,14 +207,13 @@ uint64_t f20(uint64_t y) /* packstate packs the relevant bits from LFSR state into 20 bits for pre-shifted lfsr */ -uint64_t packstate(uint64_t s) -{ +uint64_t packstate(uint64_t s) { uint64_t packed; - packed = pickbits2_2 (s, 2, 5); - packed |= (pickbits1_1_2 (s, 8, 12, 14) << 4); - packed |= (pickbits1x4 (s, 17, 21, 23, 26) << 8); - packed |= (pickbits2_1_1 (s, 28, 31, 33) << 12); + packed = pickbits2_2(s, 2, 5); + packed |= (pickbits1_1_2(s, 8, 12, 14) << 4); + packed |= (pickbits1x4(s, 17, 21, 23, 26) << 8); + packed |= (pickbits2_1_1(s, 28, 31, 33) << 12); packed |= (pickbits1_2_1(s, 34, 43, 46) << 16); return packed; @@ -226,8 +221,7 @@ uint64_t packstate(uint64_t s) /* create_guess_table mallocs the tables */ -void create_guess_table() -{ +void create_guess_table() { guesses = (struct guess *)malloc(sizeof(struct guess) * maxtablesize); if (!guesses) { printf("cannot malloc guess table\n"); @@ -238,8 +232,7 @@ void create_guess_table() /* init the guess table by reading in the encrypted nR,aR values and * setting the first 2^16 key guesses */ -void init_guess_table(char *filename, char *uidstr) -{ +void init_guess_table(char *filename, char *uidstr) { unsigned int i, j; FILE *fp; char *buf = NULL; @@ -289,8 +282,8 @@ void init_guess_table(char *filename, char *uidstr) } *buft2 = 0x00; if (!strncmp(buf, "0x", 2)) { - nonces[num_nRaR].enc_nR = rev32(hexreversetoulong(buf+2)); - nonces[num_nRaR].ks = rev32(hexreversetoulong(buft1+2)) ^ 0xffffffff; + nonces[num_nRaR].enc_nR = rev32(hexreversetoulong(buf + 2)); + nonces[num_nRaR].ks = rev32(hexreversetoulong(buft1 + 2)) ^ 0xffffffff; } else { nonces[num_nRaR].enc_nR = rev32(hexreversetoulong(buf)); nonces[num_nRaR].ks = rev32(hexreversetoulong(buft1)) ^ 0xffffffff; @@ -303,12 +296,12 @@ void init_guess_table(char *filename, char *uidstr) fprintf(stderr, "Loaded %d nRaR pairs\n", num_nRaR); - // set key and copy in enc_nR and ks values + // set key and copy in enc_nR and ks values // set score to -1.0 to distinguish them from 0 scores - for (i=0; i<65536; i++) { + for (i = 0; i < 65536; i++) { guesses[i].key = i; guesses[i].score = -1.0; - for (j=0; j> (packed & 0xf)) & 1; + fncinput = (ht2_function4a >> (packed & 0xf)) & 1; fncinput |= ((ht2_function4b << 1) >> ((packed >> 4) & 0xf)) & 0x02; fncinput |= ((ht2_function4b << 2) >> ((packed >> 8) & 0xf)) & 0x04; fncinput |= ((ht2_function4b << 3) >> ((packed >> 12) & 0xf)) & 0x08; @@ -404,8 +396,7 @@ double bit_score(uint64_t s, uint64_t size, uint64_t b) * bit_scores together until no bits remain. bit_scores are * multiplied by the number of relevant bits in the scored state * to give weight to more complete states. */ -double score(uint64_t s, unsigned int size, uint64_t ks, unsigned int kssize) -{ +double score(uint64_t s, unsigned int size, uint64_t ks, unsigned int kssize) { double sc, sc2; if ((size == 1) || (kssize == 1)) { @@ -436,8 +427,7 @@ double score(uint64_t s, unsigned int size, uint64_t ks, unsigned int kssize) /* score_traces runs score for each encrypted nonce */ -void score_traces(struct guess *g, unsigned int size) -{ +void score_traces(struct guess *g, unsigned int size) { uint64_t lfsr; unsigned int i; double sc; @@ -448,13 +438,13 @@ void score_traces(struct guess *g, unsigned int size) return; } - for (i=0; i> (size - 16)) | ((g->key << (48 - size)) ^ - ((nonces[i].enc_nR ^ g->b0to31[i]) << (64 - size))); + ((nonces[i].enc_nR ^ g->b0to31[i]) << (64 - size))); g->b0to31[i] = g->b0to31[i] | (ht2crypt(lfsr) << (size - 16)); // create lfsr - lower 16 bits are lower 16 bits of key @@ -491,12 +481,11 @@ void score_all_traces(unsigned int size) */ /* score_some_traces runs score_traces for every key guess in a section of the table */ -void *score_some_traces(void *data) -{ +void *score_some_traces(void *data) { unsigned int i; struct thread_data *tdata = (struct thread_data *)data; - for (i=tdata->start; iend; i++) { + for (i = tdata->start; i < tdata->end; i++) { score_traces(&(guesses[i]), tdata->size); } @@ -505,8 +494,7 @@ void *score_some_traces(void *data) /* score_all_traces runs score_traces for every key guess in the table */ -void score_all_traces(unsigned int size) -{ +void score_all_traces(unsigned int size) { pthread_t threads[NUM_THREADS]; void *status; struct thread_data tdata[NUM_THREADS]; @@ -516,9 +504,9 @@ void score_all_traces(unsigned int size) chunk_size = num_guesses / NUM_THREADS; // create thread data - for (i=0; i> 1) | (hitag2_nstep(&hstate, 1) << 31); } printf("ks = 0x%08" PRIx64 ", enc_aR = 0x%08" PRIx64 ", aR = 0x%08" PRIx64 "\n", b0to31, nonces[0].ks ^ 0xffffffff, nonces[0].ks ^ 0xffffffff ^ b0to31); @@ -679,7 +661,7 @@ void testkey(uint64_t key) // xor upper part of key with encrypted nonce nRxorkey = nonces[0].enc_nR ^ (key >> 16); // insert keyupper xor encrypted nonce xor ks - for (i=0; i<32; i++) { + for (i = 0; i < 32; i++) { // store ks - when done, the first ks bit will be bit 0 and the last will be bit 31 b0to31 = (b0to31 >> 1) | (ht2crypt(lfsr) << 31); // insert new bit @@ -693,7 +675,7 @@ void testkey(uint64_t key) printf("\n"); // iterate lfsr with fnL, extracting ks - for (i=0; i<32; i++) { + for (i = 0; i < 32; i++) { // store ks - when done, the first ks bit will be bit 0 and the last will be bit 31 ks = (ks >> 1) | (ht2crypt(lfsr) << 31); // insert new bit @@ -710,38 +692,37 @@ void testkey(uint64_t key) /* test function to generate test data */ -void gen_bitstreams_testks(struct guess *g, uint64_t key) -{ - unsigned int i, j; - uint64_t nRxorkey, lfsr, ks; +void gen_bitstreams_testks(struct guess *g, uint64_t key) { + unsigned int i, j; + uint64_t nRxorkey, lfsr, ks; - for (j=0; jb0to31[j] = 0; - // xor upper part of key with encrypted nonce - nRxorkey = nonces[j].enc_nR ^ (key >> 16); - // insert keyupper xor encrypted nonce xor ks - for (i=0; i<32; i++) { - // store ks - when done, the first ks bit will be bit 0 and the last will be bit 31 - g->b0to31[j] = (g->b0to31[j] >> 1) | (ht2crypt(lfsr) << 31); - // insert new bit - lfsr = lfsr | ((((nRxorkey >> i) & 0x1) ^ ((g->b0to31[j] >> 31) & 0x1)) << 48); - // shift lfsr - lfsr = lfsr >> 1; - } + // build initial lfsr + lfsr = uid | ((key & 0xffff) << 32); + g->b0to31[j] = 0; + // xor upper part of key with encrypted nonce + nRxorkey = nonces[j].enc_nR ^ (key >> 16); + // insert keyupper xor encrypted nonce xor ks + for (i = 0; i < 32; i++) { + // store ks - when done, the first ks bit will be bit 0 and the last will be bit 31 + g->b0to31[j] = (g->b0to31[j] >> 1) | (ht2crypt(lfsr) << 31); + // insert new bit + lfsr = lfsr | ((((nRxorkey >> i) & 0x1) ^ ((g->b0to31[j] >> 31) & 0x1)) << 48); + // shift lfsr + lfsr = lfsr >> 1; + } ks = 0; - // iterate lfsr with fnL, extracting ks - for (i=0; i<32; i++) { - // store ks - when done, the first ks bit will be bit 0 and the last will be bit 31 - ks = (ks >> 1) | (ht2crypt(lfsr) << 31); - // insert new bit - lfsr = lfsr | (fnL(lfsr) << 48); - // shift lfsr - lfsr = lfsr >> 1; - } + // iterate lfsr with fnL, extracting ks + for (i = 0; i < 32; i++) { + // store ks - when done, the first ks bit will be bit 0 and the last will be bit 31 + ks = (ks >> 1) | (ht2crypt(lfsr) << 31); + // insert new bit + lfsr = lfsr | (fnL(lfsr) << 48); + // shift lfsr + lfsr = lfsr >> 1; + } printf("orig ks = 0x%08" PRIx64 ", gen ks = 0x%08" PRIx64 ", b0to31 = 0x%08" PRIx64 "\n", nonces[j].ks, ks, g->b0to31[j]); if (nonces[j].ks != ks) { @@ -752,15 +733,14 @@ void gen_bitstreams_testks(struct guess *g, uint64_t key) /* test function */ -void test() -{ +void test() { uint64_t lfsr; uint64_t packed; uint64_t i; - for (i=0; i<1000; i++) { + for (i = 0; i < 1000; i++) { lfsr = ((uint64_t)rand() << 32) | rand(); packed = packstate(lfsr); @@ -774,15 +754,14 @@ void test() /* check_key tests the potential key against an encrypted nonce, ks pair */ -int check_key(uint64_t key, uint64_t enc_nR, uint64_t ks) -{ +int check_key(uint64_t key, uint64_t enc_nR, uint64_t ks) { Hitag_State hstate; uint64_t bits; int i; hitag2_init(&hstate, key, uid, enc_nR); bits = 0; - for (i=0; i<32; i++) { + for (i = 0; i < 32; i++) { bits = (bits >> 1) | (hitag2_nstep(&hstate, 1) << 31); } if (ks == bits) { @@ -794,8 +773,7 @@ int check_key(uint64_t key, uint64_t enc_nR, uint64_t ks) /* start up */ -int main(int argc, char *argv[]) -{ +int main(int argc, char *argv[]) { unsigned int i; uint64_t revkey; uint64_t foundkey; @@ -808,7 +786,7 @@ int main(int argc, char *argv[]) // exit(0); while ((c = getopt(argc, argv, "u:n:N:t:T:h")) != -1) { - switch(c) { + switch (c) { case 'u': uidstr = optarg; break; @@ -848,7 +826,7 @@ int main(int argc, char *argv[]) crack(); // test all key guesses and stop if one works - for (i=0; i Date: Mon, 9 Mar 2020 16:54:42 +0100 Subject: [PATCH 1634/1854] style --- include/protocols.h | 4 ++-- tools/fpga_compress/Makefile | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/protocols.h b/include/protocols.h index e992a97ee..de38e1aea 100644 --- a/include/protocols.h +++ b/include/protocols.h @@ -312,7 +312,7 @@ ISO 7816-4 Basic interindustry commands. For command APDU's. #define PROTO_HITAG1 10 #define THINFILM 11 #define LTO 12 -#define PROTO_HITAG2 13 +#define PROTO_HITAG2 13 #define PROTO_HITAGS 14 //-- Picopass fuses @@ -599,7 +599,7 @@ ISO 7816-4 Basic interindustry commands. For command APDU's. #define HITAG2_READ_PAGE 0x3 // page number in bits 5 to 3, page number inverted in bit 0 and following 2 bits #define HITAG2_READ_PAGE_INVERTED 0x1 // page number in bits 5 to 3, page number inverted in bit 0 and following 2 bits -#define HITAG2_WRITE_PAGE 0x2 // page number in bits 5 to 3, page number +#define HITAG2_WRITE_PAGE 0x2 // page number in bits 5 to 3, page number // HITAG S commands diff --git a/tools/fpga_compress/Makefile b/tools/fpga_compress/Makefile index 47f3c278c..5452f9083 100644 --- a/tools/fpga_compress/Makefile +++ b/tools/fpga_compress/Makefile @@ -22,4 +22,4 @@ $(OBJDIR)/libz.a: tarbin: $(BINS) $(info [=] TAR ../proxmark3-$(platform)-bin.tar) - $(Q)$(TAR) $(TARFLAGS) ../../proxmark3-$(platform)-bin.tar $(BINS:%=fpga_compress/%) $(WINBINS:%=fpga_compress/%) \ No newline at end of file + $(Q)$(TAR) $(TARFLAGS) ../../proxmark3-$(platform)-bin.tar $(BINS:%=fpga_compress/%) $(WINBINS:%=fpga_compress/%) From 59bae5000c582778707b04d2bce20707537014d9 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 9 Mar 2020 16:57:13 +0100 Subject: [PATCH 1635/1854] style --- armsrc/Standalone/hf_14asniff.c | 6 +-- armsrc/Standalone/lf_icehid.c | 72 ++++++++++++++++----------------- 2 files changed, 39 insertions(+), 39 deletions(-) diff --git a/armsrc/Standalone/hf_14asniff.c b/armsrc/Standalone/hf_14asniff.c index d8bf6ab82..706a41b8b 100644 --- a/armsrc/Standalone/hf_14asniff.c +++ b/armsrc/Standalone/hf_14asniff.c @@ -45,7 +45,7 @@ * This module emits debug strings during normal operation -- so try it out in * the lab connected to PM3 client before taking it into the field. * - * To delete the trace data from flash: + * To delete the trace data from flash: * * Caveats / notes: * - Trace buffer will be cleared on starting stand-alone mode. Data in flash @@ -97,7 +97,7 @@ void RunMod() { if (trace_len > 0) { Dbprintf("[!] Trace length (bytes) = %u", trace_len); - uint8_t* trace_buffer = BigBuf_get_addr(); + uint8_t *trace_buffer = BigBuf_get_addr(); if (!exists_in_spiffs(HF_14ASNIFF_LOGFILE)) { rdv40_spiffs_write( HF_14ASNIFF_LOGFILE, trace_buffer, trace_len, RDV40_SPIFFS_SAFETY_SAFE); @@ -117,7 +117,7 @@ void RunMod() { SpinErr(LED_A, 200, 5); SpinDelay(100); - + LEDsoff(); SpinDelay(300); DownloadTraceInstructions(); diff --git a/armsrc/Standalone/lf_icehid.c b/armsrc/Standalone/lf_icehid.c index 77f04024e..d66186c9d 100644 --- a/armsrc/Standalone/lf_icehid.c +++ b/armsrc/Standalone/lf_icehid.c @@ -63,7 +63,7 @@ void DownloadLogInstructions() { bool log_exists; -void append(uint8_t* entry, size_t entry_len) { +void append(uint8_t *entry, size_t entry_len) { LED_B_ON(); if (log_exists == false) { @@ -106,22 +106,22 @@ uint32_t IceEM410xdemod() { if (size == 128) { sprintf((char *)entry, "EM XL TAG ID: %06lx%08lx%08lx - (%05ld_%03ld_%08ld)\n", - hi, - (uint32_t)(lo >> 32), - (uint32_t)lo, - (uint32_t)(lo & 0xFFFF), - (uint32_t)((lo >> 16LL) & 0xFF), - (uint32_t)(lo & 0xFFFFFF)); + hi, + (uint32_t)(lo >> 32), + (uint32_t)lo, + (uint32_t)(lo & 0xFFFF), + (uint32_t)((lo >> 16LL) & 0xFF), + (uint32_t)(lo & 0xFFFFFF)); } else { sprintf((char *)entry, "EM TAG ID: %02lx%08lx - (%05ld_%03ld_%08ld)\n", - (uint32_t)(lo >> 32), - (uint32_t)lo, - (uint32_t)(lo & 0xFFFF), - (uint32_t)((lo >> 16LL) & 0xFF), - (uint32_t)(lo & 0xFFFFFF)); + (uint32_t)(lo >> 32), + (uint32_t)lo, + (uint32_t)(lo & 0xFFFF), + (uint32_t)((lo >> 16LL) & 0xFF), + (uint32_t)(lo & 0xFFFFFF)); } - append(entry, strlen((char*)entry)); + append(entry, strlen((char *)entry)); Dbprintf("%s", entry); BigBuf_free(); return PM3_SUCCESS; @@ -173,7 +173,7 @@ uint32_t IceAWIDdemod() { } } - append(entry, strlen((char*)entry)); + append(entry, strlen((char *)entry)); Dbprintf("%s", entry); BigBuf_free(); return PM3_SUCCESS; @@ -210,14 +210,14 @@ uint32_t IceIOdemod() { memset(entry, 0, sizeof(entry)); sprintf((char *)entry, "IO Prox XSF(%02d)%02x:%05d (%08lx%08lx)\n" - , version - , facilitycode - , number - , hi - , lo - ); + , version + , facilitycode + , number + , hi + , lo + ); - append(entry, strlen((char*)entry)); + append(entry, strlen((char *)entry)); Dbprintf("%s", entry); BigBuf_free(); return PM3_SUCCESS; @@ -250,13 +250,13 @@ uint32_t IceHIDDemod() { if (hi2 != 0) { //extra large HID tags 88/192 bits sprintf((char *)entry, "HID large: %lx%08lx%08lx (%ld)\n", - hi2, - hi, - lo, - (lo >> 1) & 0xFFFF - ); + hi2, + hi, + lo, + (lo >> 1) & 0xFFFF + ); - append(entry, strlen((char*)entry)); + append(entry, strlen((char *)entry)); } else { //standard HID tags 44/96 bits uint8_t bitlen = 0; @@ -297,15 +297,15 @@ uint32_t IceHIDDemod() { } sprintf((char *)entry, "HID: %lx%08lx (%ld) Format: %d bit FC: %ld Card: %ld\n", - hi, - lo, - (lo >> 1) & 0xFFFF, - bitlen, - fac, - cardnum - ); + hi, + lo, + (lo >> 1) & 0xFFFF, + bitlen, + fac, + cardnum + ); - append(entry, strlen((char*)entry)); + append(entry, strlen((char *)entry)); } Dbprintf("%s", entry); @@ -349,7 +349,7 @@ void RunMod() { uint32_t res; - // since we steal 12800 from bigbuffer, no need to sample it. + // since we steal 12800 from bigbuffer, no need to sample it. DoAcquisition_config(false, 28000); res = IceHIDDemod(); if (res == PM3_SUCCESS) { From e1490f62240c113aa7e391161de5299902ee252c Mon Sep 17 00:00:00 2001 From: bosb <12600404+bosb@users.noreply.github.com> Date: Mon, 9 Mar 2020 17:02:03 +0100 Subject: [PATCH 1636/1854] add CHANGELOG entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index af8b073ca..afa16fec6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -420,6 +420,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Added `hf mf mad` and `hf mfp mad` MAD decode, check and print commands (@merlokk) - Added `script run luxeodump` (@0xdrrb) - Fix `lf hitag reader 02` - print all bytes (@bosb) + - Fix hitag S simulation (still not working), write, add example HITAG S 256 (@bosb) ### Fixed From c28a71b58688683999e1ce0cd82c4e6a8340ca5e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 9 Mar 2020 17:07:25 +0100 Subject: [PATCH 1637/1854] header --- client/cmdlfindala.h | 1 + 1 file changed, 1 insertion(+) diff --git a/client/cmdlfindala.h b/client/cmdlfindala.h index 830017117..1d0762f5f 100644 --- a/client/cmdlfindala.h +++ b/client/cmdlfindala.h @@ -19,5 +19,6 @@ int detectIndala26(uint8_t *bitStream, size_t *size, uint8_t *invert); int detectIndala64(uint8_t *bitStream, size_t *size, uint8_t *invert); int detectIndala224(uint8_t *bitStream, size_t *size, uint8_t *invert); int demodIndala(void); +int getIndalaBits(uint8_t fc, uint16_t csn, uint8_t *bits); #endif From 9a921d6944cb5485c20ed40dab47bac37b571032 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 9 Mar 2020 17:09:07 +0100 Subject: [PATCH 1638/1854] style --- common/lfdemod.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/lfdemod.c b/common/lfdemod.c index 4dcd46172..bc753f45d 100644 --- a/common/lfdemod.c +++ b/common/lfdemod.c @@ -206,7 +206,7 @@ void getHiLo(int *high, int *low, uint8_t fuzzHi, uint8_t fuzzLo) { *low = signalprop.low; } - // prnt("getHiLo fuzzed: High %d | Low %d", *high, *low); + // prnt("getHiLo fuzzed: High %d | Low %d", *high, *low); } // by marshmellow From cef1f21a34bd6855b5b4b6d5e93154a37d45c83a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 9 Mar 2020 17:09:41 +0100 Subject: [PATCH 1639/1854] style --- common/cardhelper.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/common/cardhelper.c b/common/cardhelper.c index 93e361f60..5cebf4322 100644 --- a/common/cardhelper.c +++ b/common/cardhelper.c @@ -29,7 +29,7 @@ bool IsCryptoHelperPresent(void) { uint8_t resp[20] = {0}; ExchangeAPDUSC(true, version, sizeof(version), true, true, resp, sizeof(resp), &resp_len); - if (strstr("CryptoHelper", (char*)resp) == 0) { + if (strstr("CryptoHelper", (char *)resp) == 0) { PrintAndLogEx(INFO, "Found smart card helper"); return true; } else { @@ -56,11 +56,11 @@ static bool executeCrypto(uint8_t ins, uint8_t *src, uint8_t *dest) { return false; } -bool Decrypt(uint8_t *src, uint8_t *dest){ +bool Decrypt(uint8_t *src, uint8_t *dest) { return executeCrypto(CARD_INS_DECRYPT, src, dest); } -bool Encrypt(uint8_t *src, uint8_t *dest){ +bool Encrypt(uint8_t *src, uint8_t *dest) { return executeCrypto(CARD_INS_ENCRYPT, src, dest); } From a751684a31c6b457a536023bf2a8a7d5c087d6e1 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 9 Mar 2020 17:11:11 +0100 Subject: [PATCH 1640/1854] style --- armsrc/appmain.c | 8 +++--- armsrc/mifarecmd.c | 62 +++++++++++++++++++++++----------------------- armsrc/mifaresim.c | 4 +-- 3 files changed, 37 insertions(+), 37 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 5464d7ddb..5bec32364 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -549,7 +549,7 @@ void ListenReaderField(uint8_t limit) { // iceman, useless, since we are measuring readerfield, not our field. My tests shows a max of 20v from a reader. hf_av = hf_max = AvgAdc(ADC_CHAN_HF_RDV40); #else - hf_av = hf_max = AvgAdc(ADC_CHAN_HF); + hf_av = hf_max = AvgAdc(ADC_CHAN_HF); #endif Dbprintf("HF 13.56MHz Baseline: %dmV", (MAX_ADC_HF_VOLTAGE * hf_av) >> 10); hf_baseline = hf_av; @@ -1248,7 +1248,7 @@ static void PacketReceived(PacketCommandNG *packet) { // SniffMifare(packet->oldarg[0]); // break; // } - case CMD_HF_MIFARE_PERSONALIZE_UID: { + case CMD_HF_MIFARE_PERSONALIZE_UID: { struct p { uint8_t keytype; uint8_t pers_option; @@ -1256,8 +1256,8 @@ static void PacketReceived(PacketCommandNG *packet) { } PACKED; struct p *payload = (struct p *) packet->data.asBytes; uint64_t authkey = bytes_to_num(payload->key, 6); - MifarePersonalizeUID(payload->keytype, payload->pers_option, authkey); - break; + MifarePersonalizeUID(payload->keytype, payload->pers_option, authkey); + break; } case CMD_HF_MIFARE_SETMOD: { MifareSetMod(packet->data.asBytes); diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 3669e13ea..0136ed6c9 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -1811,54 +1811,54 @@ void MifareChkKeys_file(uint8_t *fn) { void MifarePersonalizeUID(uint8_t keyType, uint8_t perso_option, uint64_t key) { uint16_t isOK = PM3_EUNDEF; - uint8_t uid[10]; - uint32_t cuid; - struct Crypto1State mpcs = {0, 0}; - struct Crypto1State *pcs; - pcs = &mpcs; + uint8_t uid[10]; + uint32_t cuid; + struct Crypto1State mpcs = {0, 0}; + struct Crypto1State *pcs; + pcs = &mpcs; - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); clear_trace(); set_tracing(true); - - LED_A_ON(); - while (true) { - if (!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) { - if (DBGLEVEL >= DBG_ERROR) Dbprintf("Can't select card"); - break; - } + LED_A_ON(); - uint8_t block_number = 0; - if (mifare_classic_auth(pcs, cuid, block_number, keyType, key, AUTH_FIRST)) { - if (DBGLEVEL >= DBG_ERROR) Dbprintf("Auth error"); - break; - } + while (true) { + if (!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) { + if (DBGLEVEL >= DBG_ERROR) Dbprintf("Can't select card"); + break; + } - uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE]; - uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE]; - int len = mifare_sendcmd_short(pcs, true, MIFARE_EV1_PERSONAL_UID, perso_option, receivedAnswer, receivedAnswerPar, NULL); - if (len != 1 || receivedAnswer[0] != CARD_ACK) { - if (DBGLEVEL >= DBG_ERROR) Dbprintf("Cmd Error: %02x", receivedAnswer[0]); - break;; - } + uint8_t block_number = 0; + if (mifare_classic_auth(pcs, cuid, block_number, keyType, key, AUTH_FIRST)) { + if (DBGLEVEL >= DBG_ERROR) Dbprintf("Auth error"); + break; + } + + uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE]; + uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE]; + int len = mifare_sendcmd_short(pcs, true, MIFARE_EV1_PERSONAL_UID, perso_option, receivedAnswer, receivedAnswerPar, NULL); + if (len != 1 || receivedAnswer[0] != CARD_ACK) { + if (DBGLEVEL >= DBG_ERROR) Dbprintf("Cmd Error: %02x", receivedAnswer[0]); + break;; + } if (mifare_classic_halt(pcs, cuid)) { if (DBGLEVEL >= DBG_ERROR) Dbprintf("Halt error"); break; } - isOK = PM3_SUCCESS; - break; - } + isOK = PM3_SUCCESS; + break; + } - crypto1_deinit(pcs); + crypto1_deinit(pcs); LED_B_ON(); reply_ng(CMD_HF_MIFARE_PERSONALIZE_UID, isOK, NULL, 0); LED_B_OFF(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LEDsoff(); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LEDsoff(); } diff --git a/armsrc/mifaresim.c b/armsrc/mifaresim.c index 0dcbe404a..0fbfecb85 100644 --- a/armsrc/mifaresim.c +++ b/armsrc/mifaresim.c @@ -537,13 +537,13 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1 // find reader field if (cardSTATE == MFEMUL_NOFIELD) { - + #if defined RDV4 vHf = (MAX_ADC_HF_VOLTAGE_RDV40 * AvgAdc(ADC_CHAN_HF_RDV40)) >> 10; #else vHf = (MAX_ADC_HF_VOLTAGE * AvgAdc(ADC_CHAN_HF)) >> 10; #endif - + if (vHf > MF_MINFIELDV) { cardSTATE_TO_IDLE(); LED_A_ON(); From c27d84b06c85b663f910eb85ebec1a073bd6710e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 9 Mar 2020 19:00:27 +0100 Subject: [PATCH 1641/1854] text --- client/cmdlfindala.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/client/cmdlfindala.c b/client/cmdlfindala.c index 08b869378..8cfdfebd3 100644 --- a/client/cmdlfindala.c +++ b/client/cmdlfindala.c @@ -561,8 +561,8 @@ static int CmdIndalaClone(const char *Cmd) { CLIParserInit("lf indala clone", "clone INDALA tag to T55x7 (or to q5/T5555)", "Examples:\n" - "\tlf indala clone -c 888\n" - "\tlf indala clone -fc 123 -csn 1337\n" + "\tlf indala clone --heden 888\n" + "\tlf indala clone --fc 123 --cn 1337\n" "\tlf indala clone -r a0000000a0002021\n" "\tlf indala clone -l -r 80000001b23523a6c2e31eba3cbee4afb3c6ad1fcf649393928c14e5"); @@ -732,9 +732,19 @@ int getIndalaBits(uint8_t fc, uint16_t cn, uint8_t *bits) { // checksum // ICEMAN: todo: needs to calc - uint8_t chk = 3; - bits[62] = ((chk >> 1) & 1); // b2 - bits[63] = (chk & 1); // b1 + uint8_t chk = 0; + //sum(y2, y4, y7, y8, y10, y11, y14, y16 + chk += 0; //y == 75 + + if ((chk & 1) == 0) { + bits[62] = 1; + bits[63] = 0; + } else { + bits[62] = 0; + bits[63] = 1; + } + // 92 = 62 + // 93 = 63 return PM3_SUCCESS; } From 8b1482d72d10985bc4b3eb149a93bd9acef081ac Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 10 Mar 2020 10:26:33 +0100 Subject: [PATCH 1642/1854] fix: hf 14a sim x - above 16 sectors.. --- client/cmdhfmf.c | 124 +++++++++++++++++++++++------------------------ 1 file changed, 62 insertions(+), 62 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 6a57491fc..77278ee9a 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -3129,7 +3129,7 @@ out: } sector_t *k_sector = NULL; -uint8_t k_sectorsCount = 16; +uint8_t k_sectorsCount = 40; void showSectorTable() { if (k_sector != NULL) { @@ -4800,72 +4800,72 @@ static int CmdHFMFNDEF(const char *Cmd) { int CmdHFMFPersonalize(const char *cmd) { - CLIParserInit("hf mf personalize", - "Personalize the UID of a Mifare Classic EV1 card. This is only possible if it is a 7Byte UID card and if it is not already personalized.", - "Usage:\n\thf mf personalize UIDF0 -> double size UID according to ISO/IEC14443-3\n" - "\thf mf personalize UIDF1 -> double size UID according to ISO/IEC14443-3, optional usage of selection process shortcut\n" - "\thf mf personalize UIDF2 -> single size random ID according to ISO/IEC14443-3\n" - "\thf mf personalize UIDF3 -> single size NUID according to ISO/IEC14443-3\n" - "\thf mf personalize -t B -k B0B1B2B3B4B5 UIDF3 -> use key B = 0xB0B1B2B3B4B5 instead of default key A\n"); + CLIParserInit("hf mf personalize", + "Personalize the UID of a Mifare Classic EV1 card. This is only possible if it is a 7Byte UID card and if it is not already personalized.", + "Usage:\n\thf mf personalize UIDF0 -> double size UID according to ISO/IEC14443-3\n" + "\thf mf personalize UIDF1 -> double size UID according to ISO/IEC14443-3, optional usage of selection process shortcut\n" + "\thf mf personalize UIDF2 -> single size random ID according to ISO/IEC14443-3\n" + "\thf mf personalize UIDF3 -> single size NUID according to ISO/IEC14443-3\n" + "\thf mf personalize -t B -k B0B1B2B3B4B5 UIDF3 -> use key B = 0xB0B1B2B3B4B5 instead of default key A\n"); - void *argtable[] = { - arg_param_begin, - arg_str0("tT", "keytype", "", "key type (A or B) to authenticate sector 0 (default: A)"), - arg_str0("kK", "key", "", "key to authenticate sector 0 (default: FFFFFFFFFFFF)"), - arg_str1(NULL, NULL, "", "Personalization Option"), - arg_param_end - }; - CLIExecWithReturn(cmd, argtable, true); + void *argtable[] = { + arg_param_begin, + arg_str0("tT", "keytype", "", "key type (A or B) to authenticate sector 0 (default: A)"), + arg_str0("kK", "key", "", "key to authenticate sector 0 (default: FFFFFFFFFFFF)"), + arg_str1(NULL, NULL, "", "Personalization Option"), + arg_param_end + }; + CLIExecWithReturn(cmd, argtable, true); - char keytypestr[2] = "a"; - uint8_t keytype = 0x00; - int keytypestr_len; - int res = CLIParamStrToBuf(arg_get_str(1), (uint8_t*)keytypestr, 1, &keytypestr_len); + char keytypestr[2] = "a"; + uint8_t keytype = 0x00; + int keytypestr_len; + int res = CLIParamStrToBuf(arg_get_str(1), (uint8_t *)keytypestr, 1, &keytypestr_len); str_lower(keytypestr); - - if (res || (keytypestr[0] != 'a' && keytypestr[0] != 'b')) { - PrintAndLogEx(ERR, "ERROR: not a valid key type. Key type must be A or B"); - CLIParserFree(); - return PM3_EINVARG; - } - if (keytypestr[0] == 'b') { - keytype = 0x01; - } - uint8_t key[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - int key_len; - res = CLIParamHexToBuf(arg_get_str(2), key, 6, &key_len); - if (res || (!res && key_len > 0 && key_len != 6)) { - PrintAndLogEx(ERR, "ERROR: not a valid key. Key must be 12 hex digits"); - CLIParserFree(); - return PM3_EINVARG; - } + if (res || (keytypestr[0] != 'a' && keytypestr[0] != 'b')) { + PrintAndLogEx(ERR, "ERROR: not a valid key type. Key type must be A or B"); + CLIParserFree(); + return PM3_EINVARG; + } + if (keytypestr[0] == 'b') { + keytype = 0x01; + } - char pers_optionstr[6]; - int opt_len; - uint8_t pers_option; - res = CLIParamStrToBuf(arg_get_str(3), (uint8_t*)pers_optionstr, 5, &opt_len); + uint8_t key[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + int key_len; + res = CLIParamHexToBuf(arg_get_str(2), key, 6, &key_len); + if (res || (!res && key_len > 0 && key_len != 6)) { + PrintAndLogEx(ERR, "ERROR: not a valid key. Key must be 12 hex digits"); + CLIParserFree(); + return PM3_EINVARG; + } + + char pers_optionstr[6]; + int opt_len; + uint8_t pers_option; + res = CLIParamStrToBuf(arg_get_str(3), (uint8_t *)pers_optionstr, 5, &opt_len); str_lower(pers_optionstr); - if (res || (!res && opt_len > 0 && opt_len != 5) - || (strncmp(pers_optionstr, "uidf0", 5) && strncmp(pers_optionstr, "uidf1", 5) && strncmp(pers_optionstr, "uidf2", 5) && strncmp(pers_optionstr, "uidf3", 5))) { - PrintAndLogEx(ERR, "ERROR: invalid personalization option. Must be one of UIDF0, UIDF1, UIDF2, or UIDF3"); - CLIParserFree(); - return PM3_EINVARG; - } - if (!strncmp(pers_optionstr, "uidf0", 5)) { - pers_option = MIFARE_EV1_UIDF0; - } else if (!strncmp(pers_optionstr, "uidf1", 5)) { - pers_option = MIFARE_EV1_UIDF1; - } else if (!strncmp(pers_optionstr, "uidf2", 5)) { - pers_option = MIFARE_EV1_UIDF2; - } else { - pers_option = MIFARE_EV1_UIDF3; - } + if (res || (!res && opt_len > 0 && opt_len != 5) + || (strncmp(pers_optionstr, "uidf0", 5) && strncmp(pers_optionstr, "uidf1", 5) && strncmp(pers_optionstr, "uidf2", 5) && strncmp(pers_optionstr, "uidf3", 5))) { + PrintAndLogEx(ERR, "ERROR: invalid personalization option. Must be one of UIDF0, UIDF1, UIDF2, or UIDF3"); + CLIParserFree(); + return PM3_EINVARG; + } + if (!strncmp(pers_optionstr, "uidf0", 5)) { + pers_option = MIFARE_EV1_UIDF0; + } else if (!strncmp(pers_optionstr, "uidf1", 5)) { + pers_option = MIFARE_EV1_UIDF1; + } else if (!strncmp(pers_optionstr, "uidf2", 5)) { + pers_option = MIFARE_EV1_UIDF2; + } else { + pers_option = MIFARE_EV1_UIDF3; + } - CLIParserFree(); + CLIParserFree(); - clearCommandBuffer(); + clearCommandBuffer(); struct { uint8_t keytype; @@ -4875,16 +4875,16 @@ int CmdHFMFPersonalize(const char *cmd) { payload.keytype = keytype; payload.pers_option = pers_option; - memcpy(payload.key, key, 6); + memcpy(payload.key, key, 6); SendCommandNG(CMD_HF_MIFARE_PERSONALIZE_UID, (uint8_t *)&payload, sizeof(payload)); - PacketResponseNG resp; + PacketResponseNG resp; if (!WaitForResponseTimeout(CMD_HF_MIFARE_PERSONALIZE_UID, &resp, 2500)) return PM3_ETIMEOUT; PrintAndLogEx(SUCCESS, "Personalization %s", resp.status == PM3_SUCCESS ? "SUCCEEDED" : "FAILED"); - return PM3_SUCCESS; + return PM3_SUCCESS; } static int CmdHF14AMfList(const char *Cmd) { @@ -4934,7 +4934,7 @@ static command_t CommandTable[] = { {"-----------", CmdHelp, IfPm3Iso14443a, ""}, {"mad", CmdHF14AMfMAD, IfPm3Iso14443a, "Checks and prints MAD"}, {"ndef", CmdHFMFNDEF, IfPm3Iso14443a, "Prints NDEF records from card"}, - {"personalize", CmdHFMFPersonalize, IfPm3Iso14443a, "Personalize UID (Mifare Classic EV1 only)"}, + {"personalize", CmdHFMFPersonalize, IfPm3Iso14443a, "Personalize UID (Mifare Classic EV1 only)"}, {"ice", CmdHF14AMfice, IfPm3Iso14443a, "collect MIFARE Classic nonces to file"}, {NULL, NULL, NULL, NULL} }; From e749174d79174f81cf70aebedb38cb4dfc36e658 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 10 Mar 2020 10:41:16 +0100 Subject: [PATCH 1643/1854] text --- client/cmdlf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdlf.c b/client/cmdlf.c index 7fa73818d..29854c6b6 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -1351,7 +1351,7 @@ static command_t CommandTable[] = { {"fdx", CmdLFFdx, AlwaysAvailable, "{ FDX-B RFIDs... }"}, {"gallagher", CmdLFGallagher, AlwaysAvailable, "{ GALLAGHER RFIDs... }"}, {"gproxii", CmdLFGuard, AlwaysAvailable, "{ Guardall Prox II RFIDs... }"}, - {"hid", CmdLFHID, AlwaysAvailable, "{ HID RFIDs... }"}, + {"hid", CmdLFHID, AlwaysAvailable, "{ HID Prox RFIDs... }"}, {"hitag", CmdLFHitag, AlwaysAvailable, "{ Hitag CHIPs... }"}, {"indala", CmdLFINDALA, AlwaysAvailable, "{ Indala RFIDs... }"}, {"io", CmdLFIO, AlwaysAvailable, "{ ioProx RFIDs... }"}, From 66d3abafb2e3f41ba99c84fb68c8528f59e48d3a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 10 Mar 2020 10:45:01 +0100 Subject: [PATCH 1644/1854] chg: checksum test --- client/cmdlfindala.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/client/cmdlfindala.c b/client/cmdlfindala.c index 8cfdfebd3..52640fb9f 100644 --- a/client/cmdlfindala.c +++ b/client/cmdlfindala.c @@ -714,27 +714,33 @@ int getIndalaBits(uint8_t fc, uint16_t cn, uint8_t *bits) { // add cn bits[42] = ((cn >> 15) & 1); // b16 - bits[45] = ((cn >> 14) & 1); // b15 + bits[45] = ((cn >> 14) & 1); // b15 - c bits[43] = ((cn >> 13) & 1); // b14 - bits[40] = ((cn >> 12) & 1); // b13 + bits[40] = ((cn >> 12) & 1); // b13 - c bits[52] = ((cn >> 11) & 1); // b12 bits[36] = ((cn >> 10) & 1); // b11 - bits[35] = ((cn >> 9) & 1); // b10 - bits[51] = ((cn >> 8) & 1); // b9 + bits[35] = ((cn >> 9) & 1); // b10 - c + bits[51] = ((cn >> 8) & 1); // b9 - c bits[46] = ((cn >> 7) & 1); // b8 - bits[33] = ((cn >> 6) & 1); // b7 - bits[37] = ((cn >> 5) & 1); // b6 + bits[33] = ((cn >> 6) & 1); // b7 - c + bits[37] = ((cn >> 5) & 1); // b6 - c bits[54] = ((cn >> 4) & 1); // b5 bits[56] = ((cn >> 3) & 1); // b4 - bits[59] = ((cn >> 2) & 1); // b3 + bits[59] = ((cn >> 2) & 1); // b3 - c bits[50] = ((cn >> 1) & 1); // b2 - bits[41] = (cn & 1); // b1 + bits[41] = (cn & 1); // b1 - c // checksum - // ICEMAN: todo: needs to calc uint8_t chk = 0; //sum(y2, y4, y7, y8, y10, y11, y14, y16 - chk += 0; //y == 75 + chk += ((cn >> 14) & 1); //y2 == 75 - 30 = 45 + chk += ((cn >> 12) & 1); //y4 == 70 - 30 = 40 + chk += ((cn >> 9) & 1); //y7 == 65 - 30 = 35 + chk += ((cn >> 8) & 1); //y8 == 81 - 30 = 51 + chk += ((cn >> 6) & 1); //y10 == 63 - 30 = 33 + chk += ((cn >> 5) & 1); //y11 == 67 - 30 = 37 + chk += ((cn >> 2) & 1); //y14 == 89 - 30 = 59 + chk += (cn & 1); //y16 == 71 - 30 = 41 if ((chk & 1) == 0) { bits[62] = 1; From f6940f1d8e8678fe68403bc7212a189780a1fc7d Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 10 Mar 2020 10:53:02 +0100 Subject: [PATCH 1645/1854] chg: checksum test2 --- client/cmdlfindala.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/cmdlfindala.c b/client/cmdlfindala.c index 52640fb9f..6da2aa8f2 100644 --- a/client/cmdlfindala.c +++ b/client/cmdlfindala.c @@ -741,13 +741,13 @@ int getIndalaBits(uint8_t fc, uint16_t cn, uint8_t *bits) { chk += ((cn >> 5) & 1); //y11 == 67 - 30 = 37 chk += ((cn >> 2) & 1); //y14 == 89 - 30 = 59 chk += (cn & 1); //y16 == 71 - 30 = 41 - + if ((chk & 1) == 0) { - bits[62] = 1; - bits[63] = 0; - } else { bits[62] = 0; bits[63] = 1; + } else { + bits[62] = 1; + bits[63] = 0; } // 92 = 62 // 93 = 63 From adee34083e1ef8a5c8430c67e569651b22736f47 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 10 Mar 2020 17:00:59 +0100 Subject: [PATCH 1646/1854] whitespace --- client/flash.c | 6 +++--- client/mifare/mifarehost.c | 26 +++++++++++++------------- client/proxguiqt.cpp | 4 ++-- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/client/flash.c b/client/flash.c index 698e39187..ad3d8fd93 100644 --- a/client/flash.c +++ b/client/flash.c @@ -529,7 +529,7 @@ const char ice[] = " !!: :!! !!: !!: !!: !!: !!! !!: !!!\n : :: :: : : :: ::: : : : : : :: : \n" _RED_(" . .. .. . . .. ... . . . . . .. . ") "\n...................................................................\n" -; + ; // Write a file's segments to Flash int flash_write(flash_file_t *ctx) { @@ -566,8 +566,8 @@ int flash_write(flash_file_t *ctx) { baddr += block_size; length -= block_size; block++; - if ( len < strlen(ice) ) { - if (filter_ansi && !isalpha(ice[len]) ) { + if (len < strlen(ice)) { + if (filter_ansi && !isalpha(ice[len])) { len++; } else { fprintf(stdout, "%c", ice[len++]); diff --git a/client/mifare/mifarehost.c b/client/mifare/mifarehost.c index 388cc029e..6ab6943cf 100644 --- a/client/mifare/mifarehost.c +++ b/client/mifare/mifarehost.c @@ -546,8 +546,8 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, float bruteforce_per_second = (float)KEYS_IN_BLOCK / (msclock() - start_time) * 1000.0; - if ( i + 1 % 10 == 0) - PrintAndLogEx(INFO, " %6d/%u keys | %5.1f keys/sec | worst case %6.1f seconds remaining", i, keycnt , bruteforce_per_second, (keycnt-i) / bruteforce_per_second); + if (i + 1 % 10 == 0) + PrintAndLogEx(INFO, " %6d/%u keys | %5.1f keys/sec | worst case %6.1f seconds remaining", i, keycnt, bruteforce_per_second, (keycnt - i) / bruteforce_per_second); } @@ -653,7 +653,7 @@ int mfStaticNested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBl uint32_t maxkeysinblock = IfPm3Flash() ? 1000 : KEYS_IN_BLOCK; uint32_t max_keys_chunk = keycnt > maxkeysinblock ? maxkeysinblock : keycnt; - uint8_t *mem = calloc( (maxkeysinblock * 6) + 5, sizeof(uint8_t)); + uint8_t *mem = calloc((maxkeysinblock * 6) + 5, sizeof(uint8_t)); if (mem == NULL) { free(statelists[0].head.slhead); return PM3_EMALLOC; @@ -667,7 +667,7 @@ int mfStaticNested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBl mem[4] = (max_keys_chunk & 0xFF); uint8_t destfn[32]; - strncpy((char*)destfn, "static_nested_000.bin", sizeof(destfn) - 1); + strncpy((char *)destfn, "static_nested_000.bin", sizeof(destfn) - 1); uint64_t start_time = msclock(); for (uint32_t i = 0; i < keycnt; i += max_keys_chunk) { @@ -691,8 +691,8 @@ int mfStaticNested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBl // check a block of generated candidate keys. if (IfPm3Flash()) { - // upload to flash. - res = flashmem_spiffs_load(destfn, mem, 5 + (chunk * 6) ); + // upload to flash. + res = flashmem_spiffs_load(destfn, mem, 5 + (chunk * 6)); if (res != PM3_SUCCESS) { PrintAndLogEx(WARNING, "SPIFFS upload failed"); free(mem); @@ -705,13 +705,13 @@ int mfStaticNested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBl } if (res == PM3_SUCCESS) { - p_keyblock = NULL; - free(statelists[0].head.slhead); - free(mem); + p_keyblock = NULL; + free(statelists[0].head.slhead); + free(mem); - num_to_bytes(key64, 6, resultKey); + num_to_bytes(key64, 6, resultKey); - PrintAndLogEx(SUCCESS, "target block:%3u key type: %c -- found valid key [ " _YELLOW_("%s") "]", + PrintAndLogEx(SUCCESS, "target block:%3u key type: %c -- found valid key [ " _YELLOW_("%s") "]", package->block, package->keytype ? 'B' : 'A', sprint_hex_inrow(resultKey, 6) @@ -723,8 +723,8 @@ int mfStaticNested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBl } // if (i%10 == 0) { - float bruteforce_per_second = (float)i + max_keys_chunk / (msclock() - start_time) * 1000.0; - PrintAndLogEx(INFO, "Chunk %6u/%u keys | %5.1f keys/sec | worst case %6.1f seconds remaining", i, keycnt, bruteforce_per_second, (keycnt-i) / bruteforce_per_second); + float bruteforce_per_second = (float)i + max_keys_chunk / (msclock() - start_time) * 1000.0; + PrintAndLogEx(INFO, "Chunk %6u/%u keys | %5.1f keys/sec | worst case %6.1f seconds remaining", i, keycnt, bruteforce_per_second, (keycnt - i) / bruteforce_per_second); // } } diff --git a/client/proxguiqt.cpp b/client/proxguiqt.cpp index a481f31d2..dc67953e6 100644 --- a/client/proxguiqt.cpp +++ b/client/proxguiqt.cpp @@ -199,7 +199,7 @@ ProxWidget::ProxWidget(QWidget *parent, ProxGuiQT *master) : QWidget(parent) { setLayout(layout); // plot window title - QString pt = QString("[*]Plot [ %1 ]").arg((char*)gui_serial_port_name); + QString pt = QString("[*]Plot [ %1 ]").arg((char *)gui_serial_port_name); setWindowTitle(pt); // shows plot window on the screen. @@ -210,7 +210,7 @@ ProxWidget::ProxWidget(QWidget *parent, ProxGuiQT *master) : QWidget(parent) { controlWidget->resize(size().width(), 200); // Olverlays / slider window title - QString ct = QString("[*]Slider [ %1 ]").arg((char*)gui_serial_port_name); + QString ct = QString("[*]Slider [ %1 ]").arg((char *)gui_serial_port_name); controlWidget->setWindowTitle(ct); controlWidget->show(); From 107b474b8a56380bd4fdde9ba8aeea718e6aa011 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 10 Mar 2020 17:05:45 +0100 Subject: [PATCH 1647/1854] whitespace --- client/cmdhflto.c | 45 ++++++++++++++++++++++---------------------- client/cmdhfmfhard.c | 4 ++-- client/cmdlfem4x.c | 6 +++--- client/cmdlfhid.c | 14 ++++++++------ 4 files changed, 36 insertions(+), 33 deletions(-) diff --git a/client/cmdhflto.c b/client/cmdhflto.c index 7057fab36..dfbca68c1 100644 --- a/client/cmdhflto.c +++ b/client/cmdhflto.c @@ -218,15 +218,15 @@ static int lto_rdbl(uint8_t blk, uint8_t *block_responce, uint8_t *block_cnt_res uint16_t resp_len = 18; uint8_t rdbl_cmd[] = {0x30, blk}; - uint8_t rdbl_cnt_cmd[] ={0x80}; + uint8_t rdbl_cnt_cmd[] = {0x80}; int status = lto_send_cmd_raw(rdbl_cmd, sizeof(rdbl_cmd), block_responce, &resp_len, true, false, verbose); - if (status == PM3_ETIMEOUT || status == PM3_ESOFT ) { + if (status == PM3_ETIMEOUT || status == PM3_ESOFT) { return PM3_EWRONGANSVER; // READ BLOCK failed } status = lto_send_cmd_raw(rdbl_cnt_cmd, sizeof(rdbl_cnt_cmd), block_cnt_responce, &resp_len, false, false, verbose); - if (status == PM3_ETIMEOUT || status == PM3_ESOFT ) { + if (status == PM3_ETIMEOUT || status == PM3_ESOFT) { return PM3_EWRONGANSVER; // READ BLOCK CONTINUE failed } @@ -252,7 +252,7 @@ int rdblLTO(uint8_t st_blk, uint8_t end_blk, bool verbose) { uint8_t block_data_d16_d31[18]; uint8_t block_data[32]; - for(uint8_t i = st_blk; i < end_blk + 1; i++) { + for (uint8_t i = st_blk; i < end_blk + 1; i++) { ret_val = lto_rdbl(i, block_data_d00_d15, block_data_d16_d31, verbose); @@ -286,8 +286,8 @@ static int CmdHfLTOReadBlock(const char *Cmd) { case 'h': return usage_lto_rdbl(); case 's': - st_blk = param_get8(Cmd, cmdp+1); - if ( end_blk < st_blk ) { + st_blk = param_get8(Cmd, cmdp + 1); + if (end_blk < st_blk) { errors = true; break; } @@ -295,10 +295,11 @@ static int CmdHfLTOReadBlock(const char *Cmd) { break; case 'e': - end_blk = param_get8(Cmd, cmdp+1); - if ( end_blk < st_blk ) { + end_blk = param_get8(Cmd, cmdp + 1); + if (end_blk < st_blk) { errors = true; - break; } + break; + } cmdp += 2; break; @@ -328,7 +329,7 @@ static int lto_wrbl(uint8_t blk, uint8_t *data, bool verbose) { for (int i = 0; i < 16; i++) { wrbl_d00_d15[i] = data[i]; - wrbl_d16_d31[i] = data[i+16]; + wrbl_d16_d31[i] = data[i + 16]; } int status = lto_send_cmd_raw(wrbl_cmd, sizeof(wrbl_cmd), resp, &resp_len, true, false, verbose); @@ -390,15 +391,15 @@ static int CmdHfLTOWriteBlock(const char *Cmd) { case 'h': return usage_lto_wrbl(); case 'b': - blk = param_get8(Cmd, cmdp+1); + blk = param_get8(Cmd, cmdp + 1); b_opt_selected = true; cmdp += 2; break; case 'd': - if (param_gethex(Cmd, cmdp+1, blkData, 64)) { + if (param_gethex(Cmd, cmdp + 1, blkData, 64)) { PrintAndLogEx(WARNING, "block data must include 64 HEX symbols"); errors = true; - break; + break; } d_opt_selected = true; cmdp += 2; @@ -409,7 +410,7 @@ static int CmdHfLTOWriteBlock(const char *Cmd) { break; } } - + //Validations if (errors) { usage_lto_wrbl(); @@ -440,7 +441,7 @@ int dumpLTO(uint8_t *dump, bool verbose) { uint8_t block_data_d00_d15[18]; uint8_t block_data_d16_d31[18]; - for(uint8_t i = 0; i < 255; i++) { + for (uint8_t i = 0; i < 255; i++) { ret_val = lto_rdbl(i, block_data_d00_d15, block_data_d16_d31, verbose); @@ -504,10 +505,10 @@ static int CmdHfLTODump(const char *Cmd) { int ret_val = dumpLTO(dump, true); if (ret_val != PM3_SUCCESS) { free(dump); - return ret_val; + return ret_val; } - // save to file + // save to file if (filename[0] == '\0') { memcpy(serial_number, sprint_hex_inrow(dump, sizeof(serial_number)), sizeof(serial_number)); char tmp_name[17] = "hf_lto_"; @@ -538,10 +539,10 @@ int restoreLTO(uint8_t *dump_data, bool verbose) { return ret_val; } - uint8_t blkData[32] = {0}; + uint8_t blkData[32] = {0}; //Block address 0 and 1 are read-only - for(uint8_t blk = 2; blk < 255; blk++) { + for (uint8_t blk = 2; blk < 255; blk++) { for (int i = 0; i < 32; i++) { blkData[i] = dump_data[i + blk * 32]; @@ -550,7 +551,7 @@ int restoreLTO(uint8_t *dump_data, bool verbose) { ret_val = lto_wrbl(blk, blkData, verbose); if (ret_val == PM3_SUCCESS) { - PrintAndLogEx(SUCCESS, "BLK %03d: " _YELLOW_("write success"), blk); + PrintAndLogEx(SUCCESS, "BLK %03d: " _YELLOW_("write success"), blk); } else { lto_switch_off_field(); return ret_val; @@ -566,7 +567,7 @@ static int CmdHfLTRestore(const char *Cmd) { uint8_t cmdp = 0; bool errors = false; int is_data_loaded = PM3_ESOFT; - + char filename[FILE_PATH_SIZE] = {0}; char extension[FILE_PATH_SIZE] = {0}; @@ -623,7 +624,7 @@ static int CmdHfLTRestore(const char *Cmd) { } else { return PM3_EFILE; } - + } static command_t CommandTable[] = { diff --git a/client/cmdhfmfhard.c b/client/cmdhfmfhard.c index beb85df5b..9f6c458ae 100644 --- a/client/cmdhfmfhard.c +++ b/client/cmdhfmfhard.c @@ -1505,7 +1505,7 @@ static int acquire_nonces(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_ SendCommandNG(CMD_FPGA_MAJOR_MODE_OFF, NULL, 0); return 1; } - + // error during nested_hard if (resp.oldarg[0]) { if (nonce_file_write) { @@ -2034,7 +2034,7 @@ static void generate_candidates(uint8_t sum_a0_idx, uint8_t sum_a8_idx) { // create mutexes for accessing the statelist cache and our "book of work" pthread_mutex_init(&statelist_cache_mutex, NULL); pthread_mutex_init(&book_of_work_mutex, NULL); - + init_statelist_cache(); init_book_of_work(); diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c index 9b7fe51de..02a86c2da 100644 --- a/client/cmdlfem4x.c +++ b/client/cmdlfem4x.c @@ -1039,9 +1039,9 @@ static int CmdEM4x50Write(const char *Cmd) { uint8_t ctmp = tolower(param_getchar(Cmd, 0)); if (ctmp == 'h') return usage_lf_em4x50_write(); PrintAndLogEx(NORMAL, "no implemented yet"); -// +// // PrintAndLogEx(SUCCESS, "Done"); -// PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf em 4x50_read`") "to verify"); +// PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf em 4x50_read`") "to verify"); return PM3_SUCCESS; } @@ -1440,7 +1440,7 @@ static int CmdEM4x05Write(const char *Cmd) { int status = demodEM4x05resp(&dummy); if (status == PM3_SUCCESS) PrintAndLogEx(SUCCESS, "Success writing to tag"); - + PrintAndLogEx(SUCCESS, "Done"); PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf em 4x05_read`") "to verify"); return status; diff --git a/client/cmdlfhid.c b/client/cmdlfhid.c index dbe027dc3..eb388faa6 100644 --- a/client/cmdlfhid.c +++ b/client/cmdlfhid.c @@ -346,7 +346,7 @@ static int CmdHIDClone(const char *Cmd) { clearCommandBuffer(); SendCommandMIX(CMD_LF_HID_CLONE, hi2, hi, lo, longid, sizeof(longid)); PrintAndLogEx(SUCCESS, "Done"); - PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf hid read`") "to verify"); + PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf hid read`") "to verify"); return PM3_SUCCESS; } @@ -450,7 +450,7 @@ static int CmdHIDBrute(const char *Cmd) { PrintAndLogEx(INFO, "ISSUE#........... %u", cn_hi.IssueLevel); PrintAndLogEx(INFO, "Facility#........ %u", cn_hi.FacilityCode); PrintAndLogEx(INFO, "Card#............ %" PRIu64, cn_hi.CardNumber); - switch( direction) { + switch (direction) { case 0: PrintAndLogEx(INFO, "Brute-forcing direction: " _YELLOW_("BOTH")); break; @@ -460,7 +460,8 @@ static int CmdHIDBrute(const char *Cmd) { case 2: PrintAndLogEx(INFO, "Brute-forcing direction: " _YELLOW_("DOWN")); break; - default: break; + default: + break; } } PrintAndLogEx(INFO, "Brute-forcing HID reader"); @@ -495,7 +496,7 @@ static int CmdHIDBrute(const char *Cmd) { fin_hi = true; } } - + // do one down if (direction != 1) { if (cn_low.CardNumber > 0) { @@ -507,7 +508,7 @@ static int CmdHIDBrute(const char *Cmd) { } switch (direction) { - case 0: + case 0: if (fin_hi && fin_low) { exitloop = true; } @@ -518,7 +519,8 @@ static int CmdHIDBrute(const char *Cmd) { case 2: exitloop = fin_low; break; - default: break; + default: + break; } } while (exitloop == false); From bccad7b9d5a776dd0113daa4084064098855830c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 10 Mar 2020 17:06:00 +0100 Subject: [PATCH 1648/1854] hint message --- client/cmdlfguard.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/client/cmdlfguard.c b/client/cmdlfguard.c index 8597f4759..ba9023c21 100644 --- a/client/cmdlfguard.c +++ b/client/cmdlfguard.c @@ -187,7 +187,10 @@ static int CmdGuardClone(const char *Cmd) { PrintAndLogEx(INFO, "Preparing to clone Guardall to T55x7 with Facility Code: %u, Card Number: %u", facilitycode, cardnumber); print_blocks(blocks, ARRAYLEN(blocks)); - return clone_t55xx_tag(blocks, ARRAYLEN(blocks)); + int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks)); + PrintAndLogEx(SUCCESS, "Done"); + PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf gprox read`") "to verify"); + return res; } static int CmdGuardSim(const char *Cmd) { From f805e5c7c747f3b7ee70f4cf9a0d3f7d073a6d14 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 10 Mar 2020 17:10:05 +0100 Subject: [PATCH 1649/1854] whitespace --- armsrc/lfsampling.c | 8 ++++---- client/Makefile | 2 +- client/cmdflashmemspiffs.c | 18 +++++++++--------- client/cmdhficlass.c | 38 +++++++++++++++++++------------------- 4 files changed, 33 insertions(+), 33 deletions(-) diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index 3ce7bc5da..3769e3565 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -117,8 +117,8 @@ void initSampleBufferEx(uint32_t *sample_size, bool use_malloc) { if (use_malloc) { - if (sample_size == NULL || *sample_size == 0 ) { - *sample_size = BigBuf_max_traceLen(); + if (sample_size == NULL || *sample_size == 0) { + *sample_size = BigBuf_max_traceLen(); data.buffer = BigBuf_get_addr(); } else { *sample_size = MIN(*sample_size, BigBuf_max_traceLen()); @@ -127,7 +127,7 @@ void initSampleBufferEx(uint32_t *sample_size, bool use_malloc) { } } else { - if (sample_size == NULL || *sample_size == 0 ) { + if (sample_size == NULL || *sample_size == 0) { *sample_size = BigBuf_max_traceLen(); } data.buffer = BigBuf_get_addr(); @@ -221,7 +221,7 @@ void LFSetupFPGAForADC(int divisor, bool reader_field) { SetAdcMuxFor(GPIO_MUXSEL_LOPKD); // 50ms for the resonant antenna to settle. if (reader_field) - SpinDelay(50); + SpinDelay(50); // Now set up the SSC to get the ADC samples that are now streaming at us. FpgaSetupSsc(); diff --git a/client/Makefile b/client/Makefile index fae411a52..a09a033d9 100644 --- a/client/Makefile +++ b/client/Makefile @@ -130,7 +130,7 @@ CORESRCS = uart_posix.c \ util_posix.c \ scandir.c \ crc16.c \ - comms.c + comms.c CMDSRCS = crapto1/crapto1.c \ crapto1/crypto1.c \ diff --git a/client/cmdflashmemspiffs.c b/client/cmdflashmemspiffs.c index bdc51dc5d..fa8cdbf16 100644 --- a/client/cmdflashmemspiffs.c +++ b/client/cmdflashmemspiffs.c @@ -315,7 +315,7 @@ static int CmdFlashMemSpiFFSDump(const char *Cmd) { } int flashmem_spiffs_load(uint8_t *destfn, uint8_t *data, size_t datalen) { - + int ret_val = PM3_SUCCESS; // We want to mount before multiple operation so the lazy writes/append will not @@ -349,7 +349,7 @@ int flashmem_spiffs_load(uint8_t *destfn, uint8_t *data, size_t datalen) { bytes_sent += bytes_in_packet; PacketResponseNG resp; - + uint8_t retry = 3; while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { PrintAndLogEx(WARNING, "timeout while waiting for reply."); @@ -377,7 +377,7 @@ out: // We want to unmount after these to set things back to normal but more than this // unmouting ensure that SPIFFS CACHES are all flushed so our file is actually written on memory SendCommandNG(CMD_SPIFFS_UNMOUNT, NULL, 0); - + return ret_val; } @@ -400,8 +400,8 @@ static int CmdFlashMemSpiFFSLoad(const char *Cmd) { cmdp += 2; break; case 'o': - param_getstr(Cmd, cmdp + 1, (char*)destfilename, 32); - if (strlen((char*)destfilename) == 0) { + param_getstr(Cmd, cmdp + 1, (char *)destfilename, 32); + if (strlen((char *)destfilename) == 0) { PrintAndLogEx(FAILED, "Destination Filename missing or invalid"); errors = true; } @@ -429,12 +429,12 @@ static int CmdFlashMemSpiFFSLoad(const char *Cmd) { } res = flashmem_spiffs_load(destfilename, data, datalen); - + free(data); - - if ( res == PM3_SUCCESS ) + + if (res == PM3_SUCCESS) PrintAndLogEx(SUCCESS, "Wrote "_GREEN_("%zu") "bytes to file "_GREEN_("%s"), datalen, destfilename); - + return res; } diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index d69efd475..4e944c178 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -861,7 +861,7 @@ static int CmdHFiClassDecrypt(const char *Cmd) { getMemConfig(mem, chip, &max_blk, &app_areas, &kb); uint8_t empty[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; - + BLOCK79ENCRYPTION aa1_encryption = (decrypted[(6 * 8) + 7] & 0x03); for (uint16_t blocknum = 0; blocknum < applimit; ++blocknum) { @@ -894,36 +894,36 @@ static int CmdHFiClassDecrypt(const char *Cmd) { saveFileJSON(fptr, jsfIclass, decrypted, decryptedlen); printIclassDumpContents(decrypted, 1, (decryptedlen / 8), decryptedlen); - + // decode block 6 - if (memcmp(decrypted + (8*6), empty, 8) != 0 ) { + if (memcmp(decrypted + (8 * 6), empty, 8) != 0) { if (use_sc) { - DecodeBlock6(decrypted + (8*6)); + DecodeBlock6(decrypted + (8 * 6)); } } - // decode block 7-8-9 - if (memcmp(decrypted + (8*7), empty, 8) != 0 ) { - + // decode block 7-8-9 + if (memcmp(decrypted + (8 * 7), empty, 8) != 0) { + //todo: remove preamble/sentinal uint32_t top = 0, mid, bot; - mid = bytes_to_num(decrypted + (8*7), 4); - bot = bytes_to_num(decrypted + (8*7) + 4, 4); + mid = bytes_to_num(decrypted + (8 * 7), 4); + bot = bytes_to_num(decrypted + (8 * 7) + 4, 4); - PrintAndLogEx(INFO, "Block 7 binary"); + PrintAndLogEx(INFO, "Block 7 binary"); - char hexstr[8+1] = {0}; - hex_to_buffer((uint8_t *)hexstr, decrypted + (8*7), 8, sizeof(hexstr) - 1, 0, 0, true); - - char binstr[8*8+1] = {0}; + char hexstr[8 + 1] = {0}; + hex_to_buffer((uint8_t *)hexstr, decrypted + (8 * 7), 8, sizeof(hexstr) - 1, 0, 0, true); + + char binstr[8 * 8 + 1] = {0}; hextobinstring(binstr, hexstr); - uint8_t i=0; - while (iblockdata, sizeof(result->blockdata))); - + if (blockno == 6) { if (IsCryptoHelperPresent()) { DecodeBlock6(result->blockdata); From 57788d57516539a832f2b0598ffd7ea0f03fec48 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 10 Mar 2020 17:11:57 +0100 Subject: [PATCH 1650/1854] whitespace --- armsrc/hitag2.c | 65 +++--- armsrc/hitag2crack.c | 458 +++++++++++++++++-------------------------- armsrc/hitagS.c | 10 +- armsrc/iso14443a.c | 18 +- 4 files changed, 230 insertions(+), 321 deletions(-) diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index 87d6bf221..2df49ac3d 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -408,7 +408,7 @@ void fix_ac_decoding(uint8_t *input, size_t len) { */ -// looks at number of received bits. +// looks at number of received bits. // 0 = collision? // 32 = good response bool hitag_plain(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t *txlen, bool hitag_s) { @@ -582,15 +582,15 @@ bool hitag1_authenticate(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t *t Dbhexdump(4, logdata_1, false); bSuccessful = true; return false; -/* - // read next page of card until done - tx[0] = 0xe0 | blocknr >> 4; // RDCPAGE - tx[1] = blocknr << 4; - crc = hitag_crc(tx, 12); - tx[1] |= crc >> 4; - tx[2] = crc << 4; - *txlen = 20; -*/ + /* + // read next page of card until done + tx[0] = 0xe0 | blocknr >> 4; // RDCPAGE + tx[1] = blocknr << 4; + crc = hitag_crc(tx, 12); + tx[1] |= crc >> 4; + tx[2] = crc << 4; + *txlen = 20; + */ } } break; @@ -1091,7 +1091,7 @@ void SimulateHitag2(bool tag_mem_supplied, uint8_t *data) { uint32_t block = 0; for (size_t i = 0; i < 12; i++) { - // num2bytes? + // num2bytes? for (size_t j = 0; j < 4; j++) { block <<= 8; block |= tag.sectors[i][j]; @@ -1105,30 +1105,30 @@ void SimulateHitag2(bool tag_mem_supplied, uint8_t *data) { size_t nrzs = 0, periods = 0; // uint32_t command_start = 0, command_duration = 0; - // int16_t checked = 0; + // int16_t checked = 0; // SIMULATE while (!BUTTON_PRESS()) { LED_D_ON(); - + // lf_reset_counter(); LED_A_OFF(); WDT_HIT(); -/* - // only every 1000th times, in order to save time when collecting samples. - if (checked == 100) { - if (data_available()) { - checked = -1; - break; - } else { - checked = 0; - } - } - ++checked; -*/ + /* + // only every 1000th times, in order to save time when collecting samples. + if (checked == 100) { + if (data_available()) { + checked = -1; + break; + } else { + checked = 0; + } + } + ++checked; + */ rxlen = 0; @@ -1220,8 +1220,8 @@ void SimulateHitag2(bool tag_mem_supplied, uint8_t *data) { if (nrzs < 5) { Dbprintf("Detected unexpected number of manchester decoded samples [%d]", nrzs); continue; - } else { - for (size_t i = 0; i < 5; i++){ + } else { + for (size_t i = 0; i < 5; i++) { if (nrz_samples[i] != 1) { Dbprintf("Detected incorrect header, the bit [%d] is zero instead of one", i); } @@ -1229,7 +1229,7 @@ void SimulateHitag2(bool tag_mem_supplied, uint8_t *data) { } // Pack the response into a byte array - for (size_t i = 5; i < 37; i++){ + for (size_t i = 5; i < 37; i++) { uint8_t bit = nrz_samples[i]; rx[rxlen / 8] |= bit << (7 - (rxlen % 8)); rxlen++; @@ -1401,7 +1401,6 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { // hitagS settings t_wait_1 = 204; t_wait_2 = 128; - /*tag_size = 256;*/ flipped_bit = 0; tag_size = 8; DBG DbpString("Configured for hitagS reader"); @@ -1657,7 +1656,7 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) { uint32_t command_start = 0; uint32_t command_duration = 0; uint32_t response_start = 0; - uint32_t response_duration = 0; + uint32_t response_duration = 0; uint8_t rx[HITAG_FRAME_LEN]; size_t rxlen = 0; uint8_t txbuf[HITAG_FRAME_LEN]; @@ -1731,14 +1730,14 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) { tag_size = 8; DbpString("Configured for hitagS writer"); } else if (htf < 20) { - // hitag1 settings + // hitag1 settings t_wait_1 = 204; t_wait_2 = 128; tag_size = 256; flipped_bit = 0; DbpString("Configured for hitag1 writer"); } else if (htf < 30) { - // hitag2 settings + // hitag2 settings t_wait_1 = HITAG_T_WAIT_1_MIN; t_wait_2 = HITAG_T_WAIT_2_MIN; tag_size = 48; @@ -1783,7 +1782,7 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) { } } - // Wait for t_wait_2 carrier periods after the last tag bit before transmitting, + // Wait for t_wait_2 carrier periods after the last tag bit before transmitting, lf_wait_periods(t_wait_2); command_start += t_wait_2; diff --git a/armsrc/hitag2crack.c b/armsrc/hitag2crack.c index c6b61b019..2d0d868b9 100644 --- a/armsrc/hitag2crack.c +++ b/armsrc/hitag2crack.c @@ -38,70 +38,60 @@ bool hitag2_crack(uint8_t *response, uint8_t *nrarhex) { uint8_t temp[20]; int i; uint8_t *spaceptr = NULL; - + // get uid as hexstring - if(!hitag2_get_uid(uidhex)) - { + if (!hitag2_get_uid(uidhex)) { UserMessage("Cannot get UID\r\n"); return false; } // convert uid hexstring to binarray hextobinarray(uid, uidhex); - + // convert nR and aR hexstrings to binarray spaceptr = strchr(nrarhex, ' '); - if (!spaceptr) - { + if (!spaceptr) { UserMessage("Please supply a valid nR aR pair\r\n"); return false; } *spaceptr = 0x00; - - if (hextobinarray(nrar, nrarhex) != 32) - { + + if (hextobinarray(nrar, nrarhex) != 32) { UserMessage("nR is not 32 bits long\r\n"); return false; } - - if (hextobinarray(nrar + 32, spaceptr + 1) != 32) - { + + if (hextobinarray(nrar + 32, spaceptr + 1) != 32) { UserMessage("aR is not 32 bits long\r\n"); return false; } // find a valid encrypted command - if (!hitag2crack_find_valid_e_cmd(e_firstcmd, nrar)) - { + if (!hitag2crack_find_valid_e_cmd(e_firstcmd, nrar)) { UserMessage("Cannot find a valid encrypted command\r\n"); return false; } - + // find the 'read page 0' command and recover key stream - if (!hitag2crack_find_e_page0_cmd(keybits, e_firstcmd, nrar, uid)) - { + if (!hitag2crack_find_e_page0_cmd(keybits, e_firstcmd, nrar, uid)) { UserMessage("Cannot find encrypted 'read page0' command\r\n"); return false; } - + // empty the response string response[0] = 0x00; - + // read all pages using key stream - for (i=0; i<8; i++) - { - if (hitag2crack_read_page(pagehex, i, nrar, keybits)) - { + for (i = 0; i < 8; i++) { + if (hitag2crack_read_page(pagehex, i, nrar, keybits)) { sprintf(temp, "%1d: %s\r\n", i, pagehex); - } - else - { + } else { sprintf(temp, "%1d:\r\n", i); } // add page string to response strcat(response, temp); } - + return true; } @@ -113,16 +103,16 @@ bool hitag2_crack(uint8_t *response, uint8_t *nrarhex) { bool hitag2crack_find_valid_e_cmd(uint8_t e_cmd[], uint8_t nrar[]) { uint8_t guess[10]; uint8_t responsestr[9]; - + // UserMessage("Finding valid encrypted command:"); // we're going to hold bits 5, 7, 8 and 9 and brute force the rest // e.g. x x x x x 0 x 0 0 0 - for (uint8_t a=0; a<2; a++) { - for (uint8_t b=0; b<2; b++) { - for (uint8_t c=0; c<2; c++) { - for (uint8_t d=0; d<2; d++) { - for (uint8_t e=0; e<2; e++) { - for (uint8_t g=0; g<2; g++) { + for (uint8_t a = 0; a < 2; a++) { + for (uint8_t b = 0; b < 2; b++) { + for (uint8_t c = 0; c < 2; c++) { + for (uint8_t d = 0; d < 2; d++) { + for (uint8_t e = 0; e < 2; e++) { + for (uint8_t g = 0; g < 2; g++) { // build binarray guess[0] = a; guess[1] = b; @@ -175,65 +165,50 @@ bool hitag2crack_find_e_page0_cmd(uint8_t keybits[], uint8_t e_firstcmd[], uint8 UserMessage("Finding 'read page 0' command:"); // we're going to brute the missing 4 bits of the valid encrypted command - for (a=0; a<2; a++) - { - for (b=0; b<2; b++) - { - for (c=0; c<2; c++) - { - for (d=0; d<2; d++) - { + for (a = 0; a < 2; a++) { + for (b = 0; b < 2; b++) { + for (c = 0; c < 2; c++) { + for (d = 0; d < 2; d++) { // create our guess by bit flipping the pattern of bits // representing the inverted bit and the 3 page bits // in both the non-inverted and inverted parts of the // encrypted command. memcpy(guess, e_firstcmd, 10); - if (a) - { + if (a) { guess[5] = !guess[5]; guess[0] = !guess[0]; } - if (b) - { + if (b) { guess[7] = !guess[7]; guess[2] = !guess[2]; } - if (c) - { + if (c) { guess[8] = !guess[8]; guess[3] = !guess[3]; } - if (d) - { + if (d) { guess[9] = !guess[9]; guess[4] = !guess[4]; } - + // try the guess - if (hitag2crack_send_e_cmd(responsestr, nrar, guess, 10)) - { + if (hitag2crack_send_e_cmd(responsestr, nrar, guess, 10)) { // check if it was valid - if (strcmp(responsestr, ERROR_RESPONSE) != 0) - { + if (strcmp(responsestr, ERROR_RESPONSE) != 0) { // convert response to binarray hextobinarray(e_uid, responsestr); // test if the guess was 'read page 0' command - if (hitag2crack_test_e_p0cmd(keybits, nrar, guess, uid, e_uid)) - { - + if (hitag2crack_test_e_p0cmd(keybits, nrar, guess, uid, e_uid)) { + return true; } - } - else - { + } else { #ifdef RFIDLER_DEBUG UserMessage("hitag2crack_find_e_page0_cmd:\r\n hitag2crack_send_e_cmd returned ERROR_RESPONSE\r\n"); #endif } - } - else - { - #ifdef RFIDLER_DEBUG + } else { +#ifdef RFIDLER_DEBUG UserMessage("hitag2crack_find_e_page0_cmd:\r\n hitag2crack_send_e_cmd failed\r\n"); #endif } @@ -262,56 +237,51 @@ bool hitag2crack_test_e_p0cmd(uint8_t *keybits, uint8_t *nrar, uint8_t *e_cmd, u uint8_t e_ext_cmd[40]; uint8_t responsestr[9]; int i; - + // copy encrypted cmd to cipherbits memcpy(cipherbits, e_cmd, 10); - + // copy encrypted uid to cipherbits memcpy(cipherbits + 10, e_uid, 32); - + // copy cmd to plainbits binstringtobinarray(plainbits, READP0CMD); - + // copy uid to plainbits memcpy(plainbits + 10, uid, 32); // xor the plainbits with the cipherbits to get keybits hitag2crack_xor(keybits, plainbits, cipherbits, 42); - + // create extended cmd -> 4 * READP0CMD = 40 bits - for (i=0; i<4; i++) - { + for (i = 0; i < 4; i++) { binstringtobinarray(ext_cmd + (i * 10), READP0CMD); } - + // xor extended cmd with keybits hitag2crack_xor(e_ext_cmd, ext_cmd, keybits, 40); - + // send extended encrypted cmd - if (hitag2crack_send_e_cmd(responsestr, nrar, e_ext_cmd, 40)) - { + if (hitag2crack_send_e_cmd(responsestr, nrar, e_ext_cmd, 40)) { // test if it was valid - if (strcmp(responsestr, ERROR_RESPONSE) != 0) - { + if (strcmp(responsestr, ERROR_RESPONSE) != 0) { return true; } - } - else - { + } else { #ifdef RFIDLER_DEBUG UserMessage("hitag2crack_test_e_p0cmd:\r\n hitag2crack_send_e_cmd failed\r\n"); #endif } - + return false; - + } // hitag2crack_xor XORs the source with the pad to produce the target. // source, target and pad are binarrays of length len. void hitag2crack_xor(uint8_t *target, uint8_t *source, uint8_t *pad, unsigned int len) { - for (int i=0; i 7)) - { + + if ((pagenum < 0) || (pagenum > 7)) { UserMessage("hitag2crack_read_page:\r\n invalid pagenum\r\n"); return false; } - + // create cmd binstringtobinarray(cmd, READP0CMD); - if (pagenum & 0x1) - { + if (pagenum & 0x1) { cmd[9] = !cmd[9]; cmd[4] = !cmd[4]; } - if (pagenum & 0x2) - { + if (pagenum & 0x2) { cmd[8] = !cmd[8]; cmd[3] = !cmd[3]; } - if (pagenum & 0x4) - { + if (pagenum & 0x4) { cmd[7] = !cmd[7]; cmd[2] = !cmd[2]; } - + // encrypt command hitag2crack_xor(e_cmd, cmd, keybits, 10); - + // send encrypted command - if (hitag2crack_send_e_cmd(e_responsestr, nrar, e_cmd, 10)) - { + if (hitag2crack_send_e_cmd(e_responsestr, nrar, e_cmd, 10)) { // check if it is valid - if (strcmp(e_responsestr, ERROR_RESPONSE) != 0) - { + if (strcmp(e_responsestr, ERROR_RESPONSE) != 0) { // convert to binarray hextobinarray(e_response, e_responsestr); // decrypt response @@ -370,17 +334,13 @@ bool hitag2crack_read_page(uint8_t *responsestr, uint8_t pagenum, uint8_t *nrar, // convert to hexstring binarraytohex(responsestr, response, 32); return true; - } - else - { + } else { UserMessage("hitag2crack_read_page:\r\n hitag2crack_send_e_cmd returned ERROR_RESPONSE\r\n"); } - } - else - { + } else { UserMessage("hitag2crack_read_page:\r\n hitag2crack_send_e_cmd failed\r\n"); } - + return false; } @@ -397,8 +357,7 @@ bool hitag2crack_send_e_cmd(uint8_t *responsestr, uint8_t *nrar, uint8_t *cmd, i int ret = 0; // get the UID - if(!hitag2_get_uid(uid)) - { + if (!hitag2_get_uid(uid)) { UserMessage("hitag2crack_send_e_cmd:\r\n cannot get UID\r\n"); return false; } @@ -407,22 +366,19 @@ bool hitag2crack_send_e_cmd(uint8_t *responsestr, uint8_t *nrar, uint8_t *cmd, i CryptoActive = false; // get the UID again - if(!hitag2_get_uid(uid)) - { + if (!hitag2_get_uid(uid)) { UserMessage("hitag2crack_send_e_cmd:\r\n cannot get UID (2nd time)\r\n"); return false; } - + // send nrar and receive (useless) encrypted page 3 value - if (!hitag2crack_tx_rx(e_page3str, nrar, 64, RWD_STATE_WAKING, false)) - { + if (!hitag2crack_tx_rx(e_page3str, nrar, 64, RWD_STATE_WAKING, false)) { UserMessage("hitag2crack_send_e_cmd:\r\n tx/rx nrar failed\r\n"); return false; } - + // send encrypted command - if (!hitag2crack_tx_rx(responsestr, cmd, len, RWD_STATE_WAKING, false)) - { + if (!hitag2crack_tx_rx(responsestr, cmd, len, RWD_STATE_WAKING, false)) { #ifdef RFIDLER_DEBUG UserMessage("hitag2crack_send_e_cmd:\r\n tx/rx cmd failed\r\n"); #endif @@ -442,34 +398,29 @@ bool hitag2crack_tx_rx(uint8_t *responsestr, uint8_t *msg, int len, int state, b int ret = 0; // START_AUTH kills active crypto session - CryptoActive= false; - - if(!rwd_send(msg, len, reset, BLOCK, state, RFIDlerConfig.FrameClock, 0, RFIDlerConfig.RWD_Wait_Switch_RX_TX, RFIDlerConfig.RWD_Zero_Period, RFIDlerConfig.RWD_One_Period, RFIDlerConfig.RWD_Gap_Period, RFIDlerConfig.RWD_Wait_Switch_TX_RX)) - { + CryptoActive = false; + + if (!rwd_send(msg, len, reset, BLOCK, state, RFIDlerConfig.FrameClock, 0, RFIDlerConfig.RWD_Wait_Switch_RX_TX, RFIDlerConfig.RWD_Zero_Period, RFIDlerConfig.RWD_One_Period, RFIDlerConfig.RWD_Gap_Period, RFIDlerConfig.RWD_Wait_Switch_TX_RX)) { UserMessage("hitag2crack_tx_rx: rwd_send failed\r\n"); return false; } - + // skip 1/2 bit to synchronise manchester HW_Skip_Bits = 1; ret = read_ask_data(RFIDlerConfig.FrameClock, RFIDlerConfig.DataRate, tmp, 37, RFIDlerConfig.Sync, RFIDlerConfig.SyncBits, RFIDlerConfig.Timeout, ONESHOT_READ, BINARY); // check if response was a valid length (5 sync bits + 32 bits response) - if (ret == 37) - { + if (ret == 37) { // check sync bits - if (memcmp(tmp, Hitag2Sync, 5) != 0) - { + if (memcmp(tmp, Hitag2Sync, 5) != 0) { UserMessage("hitag2crack_tx_rx: no sync\r\n"); return false; } - + // convert response to hexstring binarraytohex(responsestr, tmp + 5, 32); return true; - } - else - { + } else { #ifdef RFIDLER_DEBUG UserMessage("hitag2crack_tx_rx: wrong rx len\r\n"); #endif @@ -485,58 +436,53 @@ bool hitag2crack_rng_init(uint8_t *response, uint8_t *input) { uint32_t initvector; uint8_t *spaceptr; uint8_t *dataptr; - + // extract vals from input dataptr = input; spaceptr = strchr(dataptr, ' '); - if (!spaceptr) - { + if (!spaceptr) { UserMessage("/r/nformat is 'sharedkey UID nR' in hex\r\n"); return false; } - + *spaceptr = 0x00; - - if (strlen(dataptr) != 12) - { + + if (strlen(dataptr) != 12) { UserMessage("/r/nsharedkey should be 48 bits long (12 hexchars)\r\n"); return false; } sharedkey = rev64(hexreversetoulonglong(dataptr)); - - dataptr = spaceptr+1; + + dataptr = spaceptr + 1; spaceptr = strchr(dataptr, ' '); - if (!spaceptr) - { + if (!spaceptr) { UserMessage("/r/nno UID\r\n"); return false; } - + *spaceptr = 0x00; - if (strlen(dataptr) != 8) - { + if (strlen(dataptr) != 8) { UserMessage("/r/nUID should be 32 bits long (8 hexchars)\r\n"); return false; } - + serialnum = rev32(hexreversetoulong(dataptr)); - - dataptr = spaceptr+1; - - if (strlen(dataptr) != 8) - { + + dataptr = spaceptr + 1; + + if (strlen(dataptr) != 8) { UserMessage("/r/nnR should be 32 bits long (8 hexchars)\r\n"); return false; } - + initvector = rev32(hexreversetoulong(dataptr)); - + // start up crypto engine hitag2_init(&Hitag_Crypto_State, sharedkey, serialnum, initvector); - + strcpy(response, "Success\r\n"); - + return true; } @@ -545,21 +491,20 @@ bool hitag2crack_decrypt_hex(uint8_t *response, uint8_t *hex) { uint8_t binhex[9]; uint8_t binstr[33]; uint32_t binulong; - - if (strlen(hex) != 8) - { + + if (strlen(hex) != 8) { UserMessage("/r/nhex must be 32bits (8 hex chars)\r\n"); return false; } - + binulong = hextoulong(hex); - + ulongtobinarray(bin, hitag2_crypt(binulong, 32), 32); binarraytobinstring(binstr, bin, 32); binarraytohex(binhex, bin, 32); // UserMessage("ar = %s\r\n", binstr); // UserMessage("arhex = %s\r\n", binhex); - + strcpy(response, binhex); return true; } @@ -570,17 +515,16 @@ bool hitag2crack_decrypt_bin(uint8_t *response, uint8_t *e_binstr) { uint8_t binstr[33]; uint32_t binulong; int len; - + len = strlen(e_binstr); - if (len > 32) - { + if (len > 32) { UserMessage("\r\nbinary string must be <= 32 bits\r\n"); return false; } - + binstringtobinarray(e_bin, e_binstr); binulong = binarraytoulong(e_bin, len); - + ulongtobinarray(bin, hitag2_crypt(binulong, len), len); binarraytobinstring(binstr, bin, len); strcpy(response, binstr); @@ -595,7 +539,7 @@ bool hitag2crack_encrypt_hex(uint8_t *response, uint8_t *hex) { bool hitag2crack_encrypt_bin(uint8_t *response, uint8_t *e_binstr) { return hitag2crack_decrypt_bin(response, e_binstr); } - + // hitag2_keystream uses the first crack algorithm described in the paper, // Gone In 360 Seconds by Verdult, Garcia and Balasch, to retrieve 2048 bits // of keystream. @@ -618,102 +562,90 @@ bool hitag2_keystream(uint8_t *response, uint8_t *nrarhex) { int i; uint8_t *spaceptr = NULL; -/* - keybits = malloc(2080); - if (!keybits) { - UserMessage("cannot malloc keybits\r\n"); - return false; - } -*/ - + /* + keybits = malloc(2080); + if (!keybits) { + UserMessage("cannot malloc keybits\r\n"); + return false; + } + */ + // get uid as hexstring - if(!hitag2_get_uid(uidhex)) - { + if (!hitag2_get_uid(uidhex)) { UserMessage("Cannot get UID\r\n"); return false; } // convert uid hexstring to binarray hextobinarray(uid, uidhex); - + // convert nR and aR hexstrings to binarray spaceptr = strchr(nrarhex, ' '); - if (!spaceptr) - { + if (!spaceptr) { UserMessage("Please supply a valid nR aR pair\r\n"); return false; } *spaceptr = 0x00; - - if (hextobinarray(nrar, nrarhex) != 32) - { + + if (hextobinarray(nrar, nrarhex) != 32) { UserMessage("nR is not 32 bits long\r\n"); return false; } - - if (hextobinarray(nrar + 32, spaceptr + 1) != 32) - { + + if (hextobinarray(nrar + 32, spaceptr + 1) != 32) { UserMessage("aR is not 32 bits long\r\n"); return false; } // find a valid encrypted command - if (!hitag2crack_find_valid_e_cmd(e_firstcmd, nrar)) - { + if (!hitag2crack_find_valid_e_cmd(e_firstcmd, nrar)) { UserMessage("Cannot find a valid encrypted command\r\n"); return false; } - + // find the 'read page 0' command and recover key stream - if (!hitag2crack_find_e_page0_cmd(keybits, e_firstcmd, nrar, uid)) - { + if (!hitag2crack_find_e_page0_cmd(keybits, e_firstcmd, nrar, uid)) { UserMessage("Cannot find encrypted 'read page0' command\r\n"); return false; } - + // using the 40 bits of keystream in keybits, sending commands with ever // increasing lengths to acquire 2048 bits of key stream. kslen = 40; - - while (kslen < 2048) - { + + while (kslen < 2048) { ksoffset = 0; - if (!hitag2crack_send_auth(nrar)) - { + if (!hitag2crack_send_auth(nrar)) { UserMessage("hitag2crack_send_auth failed\r\n"); return false; } // while we have at least 52 bits of keystream, consume it with // extended read page 0 commands. 52 = 10 (min command len) + // 32 (response) + 10 (min command len we'll send) - while ((kslen - ksoffset) >= 52) - { + while ((kslen - ksoffset) >= 52) { // consume the keystream, updating ksoffset as we go - if (!hitag2crack_consume_keystream(keybits, kslen, &ksoffset, nrar)) - { + if (!hitag2crack_consume_keystream(keybits, kslen, &ksoffset, nrar)) { UserMessage("hitag2crack_consume_keystream failed\r\n"); return false; } } // send an extended command to retrieve more keystream, updating kslen // as we go - if (!hitag2crack_extend_keystream(keybits, &kslen, ksoffset, nrar, uid)) - { + if (!hitag2crack_extend_keystream(keybits, &kslen, ksoffset, nrar, uid)) { UserMessage("hitag2crack_extend_keystream failed\r\n"); return false; } UserMessage("Recovered %d bits of keystream\r\n", kslen); } - - for (i=0; i<2048; i+=256) - { + + for (i = 0; i < 2048; i += 256) { binarraytohex(keybitshex, keybits + i, 256); UserMessage("%s\r\n", keybitshex); } response[0] = 0x00; - + return true; } @@ -724,8 +656,7 @@ bool hitag2crack_send_auth(uint8_t *nrar) { uint8_t e_page3str[9]; // get the UID - if(!hitag2_get_uid(uid)) - { + if (!hitag2_get_uid(uid)) { UserMessage("hitag2crack_send_auth:\r\n cannot get UID\r\n"); return false; } @@ -734,15 +665,13 @@ bool hitag2crack_send_auth(uint8_t *nrar) { CryptoActive = false; // get the UID again - if(!hitag2_get_uid(uid)) - { + if (!hitag2_get_uid(uid)) { UserMessage("hitag2crack_send_auth:\r\n cannot get UID (2nd time)\r\n"); return false; } - + // send nrar and receive (useless) encrypted page 3 value - if (!hitag2crack_tx_rx(e_page3str, nrar, 64, RWD_STATE_WAKING, false)) - { + if (!hitag2crack_tx_rx(e_page3str, nrar, 64, RWD_STATE_WAKING, false)) { UserMessage("hitag2crack_send_auth:\r\n tx/rx nrar failed\r\n"); return false; } @@ -767,46 +696,41 @@ bool hitag2crack_consume_keystream(uint8_t *keybits, int kslen, int *ksoffset, u // 42 = 32 bit response + 10 bit command reserved for next command. conlen // cannot be longer than 510 bits to fit into the small RWD buffer. conlen = kslen - *ksoffset - 42; - if (conlen < 10) - { + if (conlen < 10) { UserMessage("hitag2crack_consume_keystream:\r\n conlen < 10\r\n"); return false; } - + // sanitise conlen - if (conlen > 510) - { + if (conlen > 510) { conlen = 510; } - + // calculate how many repeated commands to send in this extended command. numcmds = conlen / 10; - + // build extended command - for (i=0; i= 44) { - Dbprintf("Challenge success: %02X%02X%02X%02X %02X%02X%02X%02X", - unlocker[u1 - 1][0], unlocker[u1 - 1][1], - unlocker[u1 - 1][2], unlocker[u1 - 1][3], - unlocker[u1 - 1][4], unlocker[u1 - 1][5], - unlocker[u1 - 1][6], unlocker[u1 - 1][7]); + Dbprintf("Challenge success: %02X%02X%02X%02X %02X%02X%02X%02X", + unlocker[u1 - 1][0], unlocker[u1 - 1][1], + unlocker[u1 - 1][2], unlocker[u1 - 1][3], + unlocker[u1 - 1][4], unlocker[u1 - 1][5], + unlocker[u1 - 1][6], unlocker[u1 - 1][7]); STATE = 0; } diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index abfe07f10..23b3a2239 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -1817,15 +1817,15 @@ int EmGetCmd(uint8_t *received, uint16_t *len, uint8_t *par) { ++check; // test if the field exists -#if defined RDV4 +#if defined RDV4 if (AT91C_BASE_ADC->ADC_SR & ADC_END_OF_CONVERSION(ADC_CHAN_HF_RDV40)) { - + analogCnt++; - + analogAVG += AT91C_BASE_ADC->ADC_CDR[ADC_CHAN_HF_RDV40]; - + AT91C_BASE_ADC->ADC_CR = AT91C_ADC_START; - + if (analogCnt >= 32) { if ((MAX_ADC_HF_VOLTAGE_RDV40 * (analogAVG / analogCnt) >> 10) < MF_MINFIELDV) { @@ -1847,13 +1847,13 @@ int EmGetCmd(uint8_t *received, uint16_t *len, uint8_t *par) { } #else if (AT91C_BASE_ADC->ADC_SR & ADC_END_OF_CONVERSION(ADC_CHAN_HF)) { - + analogCnt++; - + analogAVG += AT91C_BASE_ADC->ADC_CDR[ADC_CHAN_HF]; - + AT91C_BASE_ADC->ADC_CR = AT91C_ADC_START; - + if (analogCnt >= 32) { if ((MAX_ADC_HF_VOLTAGE * (analogAVG / analogCnt) >> 10) < MF_MINFIELDV) { From 698ea94bc332f1dd9a62c089d573825b3e69e023 Mon Sep 17 00:00:00 2001 From: Jonathan Farley Date: Tue, 10 Mar 2020 12:40:58 -0400 Subject: [PATCH 1651/1854] Update Mac-OS-X-Homebrew-Installation-Instructions.md Spelling. --- .../Mac-OS-X-Homebrew-Installation-Instructions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md b/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md index 76f5ee6f3..6ce8b5990 100644 --- a/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md @@ -33,7 +33,7 @@ brew upgrade --fetch-HEAD proxmark3 ## Flash the BOOTROM & FULLIMAGE -With your Proxmark3 unplugged from your machine, press and hold the button on your Proxmark3 as you plug it into a USB port. You can release the button, two of the four LEDs should stay on. You're un bootloader mode, ready for the next step. In case the two LEDs don't stay on when you're releasing the button, you've an old bootloader, start over and keep the button pressed during the whole flashing procedure. +With your Proxmark3 unplugged from your machine, press and hold the button on your Proxmark3 as you plug it into a USB port. You can release the button, two of the four LEDs should stay on. You're in bootloader mode, ready for the next step. In case the two LEDs don't stay on when you're releasing the button, you've an old bootloader, start over and keep the button pressed during the whole flashing procedure. In principle, the helper script `pm3-flash-all` should auto-detect your port, so you can just try: From 9124b3c988bff35806cf0987ea6d12885d7cece2 Mon Sep 17 00:00:00 2001 From: ikarus Date: Tue, 10 Mar 2020 21:37:23 +0100 Subject: [PATCH 1652/1854] fix: (static)nested time and keys/sec also some wording and consistency --- client/mifare/mifarehost.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/client/mifare/mifarehost.c b/client/mifare/mifarehost.c index 6ab6943cf..b5d1cb267 100644 --- a/client/mifare/mifarehost.c +++ b/client/mifare/mifarehost.c @@ -152,7 +152,7 @@ int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) { if (*key != UINT64_C(-1)) { break; } else { - PrintAndLogEx(FAILED, "all candidate keys failed. Restarting darkside attack"); + PrintAndLogEx(FAILED, "all key candidates failed. Restarting darkside attack"); free(last_keylist); last_keylist = keylist; first_run = true; @@ -345,7 +345,7 @@ int mfKeyBrute(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint64_t *resultk // copy candidatekeys to test key block memcpy(keyBlock, candidates + i, KEYBLOCK_SIZE); - // check a block of generated candidate keys. + // check a block of generated key candidates. if (mfCheckKeys(blockNo, keyType, true, KEYS_IN_BLOCK, keyBlock, &key64) == PM3_SUCCESS) { *resultkey = key64; found = true; @@ -510,7 +510,7 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, uint32_t keycnt = statelists[0].len; if (keycnt == 0) goto out; - PrintAndLogEx(SUCCESS, "Found " _YELLOW_("%u") "candidate keys", keycnt); + PrintAndLogEx(SUCCESS, "Found " _YELLOW_("%u") "key candidates", keycnt); memset(resultKey, 0, 6); uint64_t key64 = -1; @@ -544,10 +544,10 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, return -5; } - float bruteforce_per_second = (float)KEYS_IN_BLOCK / (msclock() - start_time) * 1000.0; - - if (i + 1 % 10 == 0) - PrintAndLogEx(INFO, " %6d/%u keys | %5.1f keys/sec | worst case %6.1f seconds remaining", i, keycnt, bruteforce_per_second, (keycnt - i) / bruteforce_per_second); +// if (i + 1 % 10 == 0) { + float bruteforce_per_second = (float)(i + max_keys) / ((msclock() - start_time) / 1000.0); + PrintAndLogEx(INFO, "%6d/%u keys | %5.1f keys/sec | worst case %6.1f seconds remaining", i, keycnt, bruteforce_per_second, (keycnt - i) / bruteforce_per_second); +// } } @@ -644,7 +644,7 @@ int mfStaticNested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBl uint32_t keycnt = statelists[0].len; if (keycnt == 0) goto out; - PrintAndLogEx(SUCCESS, "Found " _YELLOW_("%u") "candidate keys", keycnt); + PrintAndLogEx(SUCCESS, "Found " _YELLOW_("%u") "key candidates", keycnt); memset(resultKey, 0, 6); uint64_t key64 = -1; @@ -689,7 +689,7 @@ int mfStaticNested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBl num_to_bytes(key64, 6, p_keyblock + j * 6); } - // check a block of generated candidate keys. + // check a block of generated key candidates. if (IfPm3Flash()) { // upload to flash. res = flashmem_spiffs_load(destfn, mem, 5 + (chunk * 6)); @@ -723,8 +723,8 @@ int mfStaticNested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBl } // if (i%10 == 0) { - float bruteforce_per_second = (float)i + max_keys_chunk / (msclock() - start_time) * 1000.0; - PrintAndLogEx(INFO, "Chunk %6u/%u keys | %5.1f keys/sec | worst case %6.1f seconds remaining", i, keycnt, bruteforce_per_second, (keycnt - i) / bruteforce_per_second); + float bruteforce_per_second = (float)(i + max_keys_chunk) / ((msclock() - start_time) / 1000.0); + PrintAndLogEx(INFO, "%6u/%u keys | %5.1f keys/sec | worst case %6.1f seconds remaining", i, keycnt, bruteforce_per_second, (keycnt - i) / bruteforce_per_second); // } } From fa1103bbc38239bc978c51a56d1fbdb3b5b7a434 Mon Sep 17 00:00:00 2001 From: Daniel Underhay <27876907+dunderhay@users.noreply.github.com> Date: Wed, 11 Mar 2020 18:23:37 +1100 Subject: [PATCH 1653/1854] Add Mifare Ultralight bruteforce support to hf_bruteforce lua script --- CHANGELOG.md | 8 ++-- client/luascripts/hf_bruteforce.lua | 68 +++++++++++++++++------------ doc/cheatsheet.md | 10 +++++ 3 files changed, 56 insertions(+), 30 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a0391fdf2..085778f36 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Change `script run hf_bruteforce -s start_id -e end_id -t timeout -x mifare_card_type` - The hf_bruteforce card script now requires Mifare type (mfc or mfu) (@dunderhay) + - Updated `hf_bruteforce.lua` script - added support for brute forcing Mifare Ultralight EV1 cards (@dunderhay) - Added `hf mf personlize` - personalize the UID of a Mifare Classic EV1 card (@pwpiwi) - Change - hint texts added to all lf clone commands (@iceman1001) - Change `lf keri demod` - adjusted the internal id. (@mwalker33) @@ -36,7 +38,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Added `commands.md` - document with all proxmark client commands. Generated with XX_internal_command_dump_markdown_XX. (@iceman1001) - Change `lf pac clone` - new option `c ` to allow cloning PAC/Stanley tag from card ID (@danshuk) - Change `lf pac read` - decoded PAC/Stanley card ID (@danshuk) - - Change mifare classic keytable output refactored and uses colors (@iceman1001) + - Change mifare classic keytable output refactored and uses colors (@iceman1001) - Fix `hf mf nested` - now writes the correct blockno (@iceman1001) - Change `lf t55xx dump` - now supports saving to JSON (@iceman1001) - Change `hf mf chk | fchk` faster authentication by lower timeout limit. (@pwpiwi) @@ -606,8 +608,8 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Updated the Reveng 1.31 sourcecode to 1.40 from Reveng project homepage (@iceman1001) - Added possibility to write direct to a Legic Prime Tag (MIM256/1024) without using values from the `BigBuffer` -> `hf legic writeRaw ` (@icsom) - Added possibility to decrease DCF values at address 0x05 & 0x06 on a Legic Prime Tag - DCF-value will be pulled from the BigBuffer (address 0x05 & 0x06) so you have to - load the data into the BigBuffer before with `hf legic load ` & then + DCF-value will be pulled from the BigBuffer (address 0x05 & 0x06) so you have to + load the data into the BigBuffer before with `hf legic load ` & then write the DCF-Values (both at once) with `hf legic write 0x05 0x02` (@icsom) - Added script `legic.lua` for display and edit Data of Legic-Prime Tags (@icsom) - Added the experimental HITAG_S support (@spenneb) diff --git a/client/luascripts/hf_bruteforce.lua b/client/luascripts/hf_bruteforce.lua index a3a6636b8..ff8ba6764 100644 --- a/client/luascripts/hf_bruteforce.lua +++ b/client/luascripts/hf_bruteforce.lua @@ -1,27 +1,34 @@ --- Run me like this: proxmark3 /dev/rfcomm0 -l ./hf_bruteforce.lua +-- Run me like this (connected via USB): ./pm3 -l hf_bruteforce.lua +-- Run me like this (connected via Blueshark addon): ./client/proxmark3 /dev/rfcomm0 -l ./hf_bruteforce.lua local getopt = require('getopt') copyright = '' -author = 'Keld Norman' -version = 'v1.0.0' -desc = [[ - -]] -example = [[ - -- (the above example would bruteforce card number, starting at 1, ending at 10, and waiting 1 second between each card) - - script run hf_bruteforce -s 1 -e 10 -t 1000 -]] +author = 'Daniel Underhay (updated), Keld Norman(original)' +version = 'v2.0.0' usage = [[ -script run hf_bruteforce -s start_id -e end_id -t timeout -d direction +pm3 --> script run hf_bruteforce -s start_id -e end_id -t timeout -x mifare_card_type Arguments: -h this help -s 0-0xFFFFFFFF start id -e 0-0xFFFFFFFF end id - -t 0-99999, pause timeout (ms) between cards (use the word 'pause' to wait for user input) + -t 0-99999, pause timeout (ms) between cards (use the word 'pause' to wait for user input) + -x mfc, mfu mifare type: mfc for Mifare Classic (default) or mfu for Mifare Ultralight EV1 + + +Example: + +pm3 --> script run hf_bruteforce -s 0x11223344 -e 0x11223346 -t 1000 -x mfc + +Bruteforce a 4 byte UID Mifare classic card number, starting at 11223344, ending at 11223346. + + +pm3 --> script run hf_bruteforce -s 0x11223344556677 -e 0x11223344556679 -t 1000 -x mfu + +Bruteforce a 7 byte UID Mifare Ultralight card number, starting at 11223344556677, ending at 11223344556679. + ]] @@ -60,41 +67,49 @@ local function help() print(usage) end --- --- Exit message -local function exitMsg(msg) +--- Print user message +local function msg(msg) print( string.rep('--',20) ) + print('') print(msg) + print('') print( string.rep('--',20) ) - print() end --- -- Start local function main(args) - print( string.rep('--',20) ) - print( string.rep('--',20) ) - print() local timeout = 0 local start_id = 0 - local end_id = 0xFFFFFFFF + local end_id = 0xFFFFFFFFFFFFFF + local mftype = 'mfc' - for o, a in getopt.getopt(args, 'e:s:t:h') do + for o, a in getopt.getopt(args, 'e:s:t:x:h') do if o == 's' then start_id = a end if o == 'e' then end_id = a end if o == 't' then timeout = a end + if o == 'x' then mftype = a end if o == 'h' then return print(usage) end end -- template - local command = 'hf 14a sim t 1 u %08X' + local command = '' - print(' Bruteforcing MFC card numbers from 00000000 to FFFFFFFF using delay: '..timeout) - print('') - print( string.rep('--',20) ) + if mftype == 'mfc' then + command = 'hf 14a sim t 1 u %14X' + msg('Bruteforcing Mifare Classic card numbers') + elseif mftype == 'mfu' then + command = 'hf 14a sim t 2 u %14X' + msg('Bruteforcing Mifare Ultralight card numbers') + else + return print(usage) + end + + if command == '' then return print(usage) end for n = start_id, end_id do local c = string.format( command, n ) - print(' Running: "'..c..'"') + print('Running: "'..c..'"') core.console(c) core.console('msleep '..timeout); core.console('hw ping') @@ -102,4 +117,3 @@ local function main(args) end main(args) - diff --git a/doc/cheatsheet.md b/doc/cheatsheet.md index b5ccd39b8..a3e0a220c 100644 --- a/doc/cheatsheet.md +++ b/doc/cheatsheet.md @@ -290,6 +290,16 @@ pm3 --> hf mfu eload u hf-mfu-XXXX-dump.eml pm3 --> hf mfu sim t 7 u hf-mfu-XXXX-dump.eml ``` +Bruteforce Mifare Classic card numbers from 11223344 to 11223346 +``` +pm3 --> script run hf_bruteforce -s 0x11223344 -e 0x11223346 -t 1000 -x mfc +``` + +Bruteforce Mifare Ultralight EV1 card numbers from 11223344556677 to 11223344556679 +``` +pm3 --> script run hf_bruteforce -s 0x11223344556677 -e 0x11223344556679 -t 1000 -x mfu +``` + ## Wiegand manipulation ^[Top](#top) From b96585483d3cda770d18c7bad8735ddf5949b2d3 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 11 Mar 2020 17:08:03 +0100 Subject: [PATCH 1654/1854] fix: hf iclass decrypt - making sure we use available bytes even if app limit reports much more data --- client/cmdhficlass.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 4e944c178..f3216e58d 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -785,7 +785,7 @@ static int CmdHFiClassDecrypt(const char *Cmd) { return usage_hf_iclass_decrypt(); case 'd': if (param_gethex(Cmd, cmdp + 1, enc_data, 16)) { - PrintAndLogEx(ERR, "data must be 16 HEX symbols"); + PrintAndLogEx(ERR, "Data must be 16 HEX symbols"); errors = true; break; } @@ -794,7 +794,7 @@ static int CmdHFiClassDecrypt(const char *Cmd) { break; case 'f': if (param_getstr(Cmd, cmdp + 1, filename, sizeof(filename)) == 0) { - PrintAndLogEx(WARNING, "no filename found after f"); + PrintAndLogEx(WARNING, "No filename found after f"); errors = true; break; } @@ -864,7 +864,14 @@ static int CmdHFiClassDecrypt(const char *Cmd) { BLOCK79ENCRYPTION aa1_encryption = (decrypted[(6 * 8) + 7] & 0x03); - for (uint16_t blocknum = 0; blocknum < applimit; ++blocknum) { + uint32_t limit = MIN(applimit, decryptedlen / 8); + + if (decryptedlen / 8 != applimit) { + PrintAndLogEx(WARNING, "Actual file len " _YELLOW_("%u") "vs HID app-limit len " _YELLOW_("%u"), decryptedlen, applimit * 8); + PrintAndLogEx(INFO, "Setting limit to " _GREEN_("%u"), limit * 8); + } + + for (uint16_t blocknum = 0; blocknum < limit; ++blocknum) { uint8_t idx = blocknum * 8; memcpy(enc_data, decrypted + idx, 8); @@ -885,7 +892,12 @@ static int CmdHFiClassDecrypt(const char *Cmd) { } //Use the first block (CSN) for filename - char *fptr = calloc(42, sizeof(uint8_t)); + char *fptr = calloc(50, sizeof(uint8_t)); + if (!fptr) { + PrintAndLogEx(WARNING, "Failed to allocate memory"); + free(decrypted); + return PM3_EMALLOC; + } strcat(fptr, "hf-iclass-"); FillFileNameByUID(fptr, hdr->csn, "-data-decrypted", sizeof(hdr->csn)); @@ -893,9 +905,9 @@ static int CmdHFiClassDecrypt(const char *Cmd) { saveFileEML(fptr, decrypted, decryptedlen, 8); saveFileJSON(fptr, jsfIclass, decrypted, decryptedlen); + PrintAndLogEx(INFO, "Following output skips CSN / block0"); printIclassDumpContents(decrypted, 1, (decryptedlen / 8), decryptedlen); - // decode block 6 if (memcmp(decrypted + (8 * 6), empty, 8) != 0) { if (use_sc) { From 5c2d4a0bbd89d764352d6576eb6a72bd5e615fba Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 11 Mar 2020 18:38:07 +0100 Subject: [PATCH 1655/1854] text --- client/cmdhficlass.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index f3216e58d..e471f3fbe 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -1263,7 +1263,7 @@ static int CmdHFiClassReader_Dump(const char *Cmd) { if (kbd_enter_pressed()) { PrintAndLogEx(WARNING, "\n[!] aborted via keyboard!\n"); DropField(); - return 0; + return PM3_EOPABORTED; } if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) @@ -1355,8 +1355,8 @@ static int CmdHFiClassReader_Dump(const char *Cmd) { // print the dump PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "------+--+-------------------------+"); - PrintAndLogEx(NORMAL, "CSN |00| %s|", sprint_hex(tag_data, 8)); + PrintAndLogEx(INFO, "------+--+-------------------------+"); + PrintAndLogEx(INFO, "CSN |00| %s|", sprint_hex(tag_data, 8)); printIclassDumpContents(tag_data, 1, (gotBytes / 8), gotBytes); if (filename[0] == 0) { From dfd408db8daea19a05cecda7eda236de155411fe Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 11 Mar 2020 21:00:19 +0100 Subject: [PATCH 1656/1854] cardhelper --- client/cmdhficlass.c | 13 ++++++------- common/cardhelper.c | 17 ++++++++++++++--- common/cardhelper.h | 1 + 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index e471f3fbe..827cbcc38 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -870,19 +870,18 @@ static int CmdHFiClassDecrypt(const char *Cmd) { PrintAndLogEx(WARNING, "Actual file len " _YELLOW_("%u") "vs HID app-limit len " _YELLOW_("%u"), decryptedlen, applimit * 8); PrintAndLogEx(INFO, "Setting limit to " _GREEN_("%u"), limit * 8); } + uint8_t numblocks4userid = GetNumberBlocksForUserId(decrypted + (6 * 8)); for (uint16_t blocknum = 0; blocknum < limit; ++blocknum) { uint8_t idx = blocknum * 8; memcpy(enc_data, decrypted + idx, 8); - // block 7 or higher, and not empty 0xFF - // look inside block 6 to determine if aa1 is encrypted. - if (blocknum > 6 && memcmp(enc_data, empty, 8) != 0) { - - if (aa1_encryption == RFU || aa1_encryption == None) - continue; - + if (aa1_encryption == RFU || aa1_encryption == None) + continue; + + // Decrypted block 7,8,9 if configured. + if (blocknum > 6 && blocknum <= 6 + numblocks4userid && memcmp(enc_data, empty, 8) != 0) { if (use_sc) { Decrypt(enc_data, decrypted + idx); } else { diff --git a/common/cardhelper.c b/common/cardhelper.c index 5cebf4322..df3aff5be 100644 --- a/common/cardhelper.c +++ b/common/cardhelper.c @@ -15,9 +15,10 @@ #include "ui.h" #include "util.h" -#define CARD_INS_DECRYPT 0x01 -#define CARD_INS_ENCRYPT 0x02 -#define CARD_INS_DECODE 0x06 +#define CARD_INS_DECRYPT 0x01 +#define CARD_INS_ENCRYPT 0x02 +#define CARD_INS_DECODE 0x06 +#define CARD_INS_NUMBLOCKS 0x07 static uint8_t cmd[] = {0x96, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // look for CryptoHelper @@ -64,6 +65,7 @@ bool Encrypt(uint8_t *src, uint8_t *dest) { return executeCrypto(CARD_INS_ENCRYPT, src, dest); } +// Call with block6 void DecodeBlock6(uint8_t *src) { int resp_len = 0; uint8_t resp[254] = {0}; @@ -81,3 +83,12 @@ void DecodeBlock6(uint8_t *src) { PrintAndLogEx(SUCCESS, "%.*s", resp_len - 11, resp + 9); } +// Call with block6 +uint8_t GetNumberBlocksForUserId(uint8_t *src) { + int resp_len = 0; + uint8_t resp[254] = {0}; + uint8_t c[] = {0x96, CARD_INS_NUMBLOCKS, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + memcpy(c + 5, src, 8); + ExchangeAPDUSC(true, c, sizeof(c), false, true, resp, sizeof(resp), &resp_len); + return resp[8]; +} \ No newline at end of file diff --git a/common/cardhelper.h b/common/cardhelper.h index 14ae23d1f..fcdd73cfe 100644 --- a/common/cardhelper.h +++ b/common/cardhelper.h @@ -18,4 +18,5 @@ bool IsCryptoHelperPresent(void); bool Encrypt(uint8_t *src, uint8_t *dest); bool Decrypt(uint8_t *src, uint8_t *dest); void DecodeBlock6(uint8_t *src); +uint8_t GetNumberBlocksForUserId(uint8_t *src); #endif From adb6a9abaa1c28f4834879ffe6040bcca3f7ed29 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Thu, 12 Mar 2020 12:42:50 +0200 Subject: [PATCH 1657/1854] disable RDP access --- appveyor.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index b2ab84fb4..230bb44bf 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -24,7 +24,7 @@ init: Add-AppveyorMessage -Message "[$env:APPVEYOR_REPO_COMMIT_SHORT]$env:appveyor_repo_name($env:APPVEYOR_REPO_BRANCH)" -Category Information -Details "repository: $env:appveyor_repo_name branch: $env:APPVEYOR_REPO_BRANCH release: $releasename" - iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) + # iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) clone_script: - ps: >- Write-Host "Removing ProxSpace..." -NoNewLine @@ -409,4 +409,4 @@ on_success: on_failure: - ps: Write-Host "Build error." -ForegroundColor Red on_finish: -- ps: $blockRdp = $false; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) +- ps: # $blockRdp = $false; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) From 22e2599ce0bd4e2e37b9807084161a7c9f9c52d4 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 13 Mar 2020 10:53:25 +0100 Subject: [PATCH 1658/1854] chg: hf mfu info - colors --- client/cmdhfmfu.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index 5387cc855..78822ab06 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -527,7 +527,7 @@ static int ul_print_default(uint8_t *data) { uid[5] = data[6]; uid[6] = data[7]; - PrintAndLogEx(NORMAL, " UID : %s ", sprint_hex(uid, 7)); + PrintAndLogEx(NORMAL, " UID : " _YELLOW_("%s"), sprint_hex(uid, 7)); PrintAndLogEx(NORMAL, " UID[0] : %02X, %s", uid[0], getTagInfo(uid[0])); if (uid[0] == 0x05 && ((uid[1] & 0xf0) >> 4) == 2) { // is infineon and 66RxxP uint8_t chip = (data[8] & 0xC7); // 11000111 mask, bit 3,4,5 RFU @@ -546,17 +546,17 @@ static int ul_print_default(uint8_t *data) { // CT (cascade tag byte) 0x88 xor SN0 xor SN1 xor SN2 int crc0 = 0x88 ^ uid[0] ^ uid[1] ^ uid[2]; if (data[3] == crc0) - PrintAndLogEx(NORMAL, " BCC0 : %02X, Ok", data[3]); + PrintAndLogEx(NORMAL, " BCC0 : %02X ( " _GREEN_("ok") ")", data[3]); else PrintAndLogEx(NORMAL, " BCC0 : %02X, crc should be %02X", data[3], crc0); int crc1 = uid[3] ^ uid[4] ^ uid[5] ^ uid[6]; if (data[8] == crc1) - PrintAndLogEx(NORMAL, " BCC1 : %02X, Ok", data[8]); + PrintAndLogEx(NORMAL, " BCC1 : %02X ( " _GREEN_("ok") ")", data[8]); else PrintAndLogEx(NORMAL, " BCC1 : %02X, crc should be %02X", data[8], crc1); - PrintAndLogEx(NORMAL, " Internal : %02X, %sdefault", data[9], (data[9] == 0x48) ? "" : "not "); + PrintAndLogEx(NORMAL, " Internal : %02X ( %s)", data[9], (data[9] == 0x48) ? _GREEN_("default") : _RED_("not default") ); PrintAndLogEx(NORMAL, " Lock : %s - %s", sprint_hex(data + 10, 2), @@ -648,10 +648,10 @@ static int ndef_print_CC(uint8_t *data) { PrintAndLogEx(NORMAL, " Additional feature information"); PrintAndLogEx(NORMAL, " %02X", data[3]); PrintAndLogEx(NORMAL, " 00000000"); - PrintAndLogEx(NORMAL, " xxx - %02X : RFU (%s)", msb3, (msb3 == 0) ? _GREEN_("OK") : _RED_("Fail")); + PrintAndLogEx(NORMAL, " xxx - %02X : RFU ( %s)", msb3, (msb3 == 0) ? _GREEN_("ok") : _RED_("fail")); PrintAndLogEx(NORMAL, " x - %02X : %s special frame", sf, (sf) ? "support" : "don\'t support"); PrintAndLogEx(NORMAL, " x - %02X : %s lock block", lb, (lb) ? "support" : "don\'t support"); - PrintAndLogEx(NORMAL, " xx - %02X : RFU (%s)", mlrule, (mlrule == 0) ? _GREEN_("OK") : _RED_("Fail")); + PrintAndLogEx(NORMAL, " xx - %02X : RFU ( %s)", mlrule, (mlrule == 0) ? _GREEN_("ok") : _RED_("fail")); PrintAndLogEx(NORMAL, " x - %02X : IC %s multiple block reads", mbread, (mbread) ? "support" : "don\'t support"); return PM3_SUCCESS; } @@ -845,7 +845,7 @@ static int ulev1_print_configuration(uint32_t tagtype, uint8_t *data, uint8_t st if (authlim == 0) PrintAndLogEx(NORMAL, " - Unlimited password attempts"); else - PrintAndLogEx(NORMAL, " - Max number of password attempts is %d", authlim); + PrintAndLogEx(NORMAL, " - Max number of password attempts is " _YELLOW_("%d"), authlim); PrintAndLogEx(NORMAL, " - NFC counter %s", (nfc_cnf_en) ? "enabled" : "disabled"); PrintAndLogEx(NORMAL, " - NFC counter %s", (nfc_cnf_prot_pwd) ? "not protected" : "password protection enabled"); From 14e0b8e2dffa99b3bff97bfe5cae96a765d17867 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 13 Mar 2020 11:40:55 +0100 Subject: [PATCH 1659/1854] text --- client/cmdhfmfu.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index 78822ab06..a13e45d9b 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -62,19 +62,19 @@ static int usage_hf_mfu_info(void) { static int usage_hf_mfu_dump(void) { PrintAndLogEx(NORMAL, "Reads all pages from Ultralight, Ultralight-C, Ultralight EV1"); PrintAndLogEx(NORMAL, "NTAG 203, NTAG 210, NTAG 212, NTAG 213, NTAG 215, NTAG 216"); - PrintAndLogEx(NORMAL, "and saves binary dump into the file `filename.bin` or `cardUID.bin`"); + PrintAndLogEx(NORMAL, "and saves binary dump into the file " _YELLOW_("`filename.bin`") " or " _YELLOW_("`cardUID.bin`") ); PrintAndLogEx(NORMAL, "It autodetects card type.\n"); PrintAndLogEx(NORMAL, "Usage: hf mfu dump k l f p q <#pages>"); PrintAndLogEx(NORMAL, " Options :"); PrintAndLogEx(NORMAL, " k : (optional) key for authentication [UL-C 16bytes, EV1/NTAG 4bytes]"); PrintAndLogEx(NORMAL, " l : (optional) swap entered key's endianness"); - PrintAndLogEx(NORMAL, " f : filename w/o .bin to save the dump as"); - PrintAndLogEx(NORMAL, " p : starting Page number to manually set a page to start the dump at"); + PrintAndLogEx(NORMAL, " f : " _YELLOW_("filename w/o .bin") "to save the dump as"); + PrintAndLogEx(NORMAL, " p : starting Page number to manually set a page to start the dump at"); PrintAndLogEx(NORMAL, " q : number of Pages to manually set how many pages to dump"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf mfu dump"); - PrintAndLogEx(NORMAL, " hf mfu dump n myfile"); + PrintAndLogEx(NORMAL, " hf mfu dump f myfile"); PrintAndLogEx(NORMAL, " hf mfu dump k 00112233445566778899AABBCCDDEEFF"); PrintAndLogEx(NORMAL, " hf mfu dump k AABBCCDD\n"); return PM3_SUCCESS; @@ -86,10 +86,10 @@ static int usage_hf_mfu_restore(void) { PrintAndLogEx(NORMAL, " Options :"); PrintAndLogEx(NORMAL, " k : (optional) key for authentication [UL-C 16bytes, EV1/NTAG 4bytes]"); PrintAndLogEx(NORMAL, " l : (optional) swap entered key's endianness"); - PrintAndLogEx(NORMAL, " s : (optional) enable special write UID -MAGIC TAG ONLY-"); - PrintAndLogEx(NORMAL, " e : (optional) enable special write version/signature -MAGIC NTAG 21* ONLY-"); - PrintAndLogEx(NORMAL, " r : (optional) use the password found in dumpfile to configure tag. requires 'e' parameter to work"); - PrintAndLogEx(NORMAL, " f : filename w/o .bin to restore"); + PrintAndLogEx(NORMAL, " s : (optional) enable special write UID " _BLUE_("-MAGIC TAG ONLY-") ); + PrintAndLogEx(NORMAL, " e : (optional) enable special write version/signature " _BLUE_("-MAGIC NTAG 21* ONLY-") ); + PrintAndLogEx(NORMAL, " r : (optional) use the password found in dumpfile to configure tag. requires " _YELLOW_("'e'") "parameter to work"); + PrintAndLogEx(NORMAL, " f : " _YELLOW_("filename w/o .bin") "to restore"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf mfu restore s f myfile"); @@ -129,7 +129,7 @@ static int usage_hf_mfu_wrbl(void) { } static int usage_hf_mfu_eload(void) { - PrintAndLogEx(NORMAL, "It loads emul dump from the file `filename.eml`"); + PrintAndLogEx(NORMAL, "It loads emul dump from the file " _YELLOW_("`filename.eml`") ); PrintAndLogEx(NORMAL, "Hint: See script dumptoemul-mfu.lua to convert the .bin to the eml"); PrintAndLogEx(NORMAL, "Usage: hf mfu eload u [numblocks]"); PrintAndLogEx(NORMAL, " Options:"); From 08f40ef310b0ac1a88815c53d6ebcda19f9881fc Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 13 Mar 2020 12:09:11 +0100 Subject: [PATCH 1660/1854] fix: hf mfu pwdgen - xyz --- common/generator.c | 76 ++++++++++++++++++++++++---------------------- 1 file changed, 39 insertions(+), 37 deletions(-) diff --git a/common/generator.c b/common/generator.c index 6dbac2feb..768917492 100644 --- a/common/generator.c +++ b/common/generator.c @@ -34,42 +34,38 @@ // XYZ 3D printing // Vinglock //------------------------------------ -static void transform_D(uint8_t *ru) { - - const uint32_t c_D[] = { - 0x6D835AFC, 0x7D15CD97, 0x0942B409, 0x32F9C923, 0xA811FB02, 0x64F121E8, - 0xD1CC8B4E, 0xE8873E6F, 0x61399BBB, 0xF1B91926, 0xAC661520, 0xA21A31C9, - 0xD424808D, 0xFE118E07, 0xD18E728D, 0xABAC9E17, 0x18066433, 0x00E18E79, - 0x65A77305, 0x5AE9E297, 0x11FC628C, 0x7BB3431F, 0x942A8308, 0xB2F8FD20, +void transform_D(uint8_t* ru) { + + const uint32_t c_D[] = { + 0x6D835AFC, 0x7D15CD97, 0x0942B409, 0x32F9C923, 0xA811FB02, 0x64F121E8, + 0xD1CC8B4E, 0xE8873E6F, 0x61399BBB, 0xF1B91926, 0xAC661520, 0xA21A31C9, + 0xD424808D, 0xFE118E07, 0xD18E728D, 0xABAC9E17, 0x18066433, 0x00E18E79, + 0x65A77305, 0x5AE9E297, 0x11FC628C, 0x7BB3431F, 0x942A8308, 0xB2F8FD20, 0x5728B869, 0x30726D5A - }; + }; - //Transform - uint8_t i; - uint8_t p = 0; - uint32_t v1 = ((ru[3] << 24) | (ru[2] << 16) | (ru[1] << 8) | ru[0]) + c_D[p++]; - uint32_t v2 = ((ru[7] << 24) | (ru[6] << 16) | (ru[5] << 8) | ru[4]) + c_D[p++]; + //Transform + uint8_t i; + uint8_t p = 0; + uint32_t v1 = ((ru[3] << 24) | (ru[2] << 16) | (ru[1] << 8) | ru[0]) + c_D[p++]; + uint32_t v2 = ((ru[7] << 24) | (ru[6] << 16) | (ru[5] << 8) | ru[4]) + c_D[p++]; + for (i = 0; i < 12; i += 2) + { + uint32_t t1 = PM3_ROTL(v1 ^ v2, v2 & 0x1F) + c_D[p++]; + uint32_t t2 = PM3_ROTL(v2 ^ t1, t1 & 0x1F) + c_D[p++]; + v1 = PM3_ROTL(t1 ^ t2, t2 & 0x1F) + c_D[p++]; + v2 = PM3_ROTL(t2 ^ v1, v1 & 0x1F) + c_D[p++]; + } - for (i = 0; i < 12; i += 2) { - uint32_t xor1 = v1 ^ v2; - uint32_t t1 = ROTL(xor1, v2 & 0x1F) + c_D[p++]; - uint32_t xor2 = v2 ^ t1; - uint32_t t2 = ROTL(xor2, t1 & 0x1F) + c_D[p++]; - uint32_t xor3 = t1 ^ t2; - uint32_t xor4 = t2 ^ v1; - v1 = ROTL(xor3, t2 & 0x1F) + c_D[p++]; - v2 = ROTL(xor4, v1 & 0x1F) + c_D[p++]; - } - - //Re-use ru - ru[0] = v1 & 0xFF; - ru[1] = (v1 >> 8) & 0xFF; - ru[2] = (v1 >> 16) & 0xFF; - ru[3] = (v1 >> 24) & 0xFF; - ru[4] = v2 & 0xFF; - ru[5] = (v2 >> 8) & 0xFF; - ru[6] = (v2 >> 16) & 0xFF; - ru[7] = (v2 >> 24) & 0xFF; + //Re-use ru + ru[0] = v1 & 0xFF; + ru[1] = (v1 >> 8) & 0xFF; + ru[2] = (v1 >> 16) & 0xFF; + ru[3] = (v1 >> 24) & 0xFF; + ru[4] = v2 & 0xFF; + ru[5] = (v2 >> 8) & 0xFF; + ru[6] = (v2 >> 16) & 0xFF; + ru[7] = (v2 >> 24) & 0xFF; } // Transport system (IT) pwd generation algo nickname A. @@ -130,17 +126,23 @@ uint32_t ul_ev1_pwdgenC(uint8_t *uid) { // XYZ 3d printing pwd generation algo nickname D. uint32_t ul_ev1_pwdgenD(uint8_t *uid) { + uint8_t i; - uint8_t r = (uid[1] + uid[3] + uid[5]) & 7; // rotation offset - uint8_t ru[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // rotated UID + // rotation offset + uint8_t r = (uid[1] + uid[3] + uid[5]) & 7; + + // rotated UID + uint8_t ru[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; for (i = 0; i < 7; i++) ru[(i + r) & 7] = uid[i]; transform_D(ru); - // calc key + // offset + r = (ru[0] + ru[2] + ru[4] + ru[6]) & 3; + + // calc key uint32_t pwd = 0; - r = (ru[0] + ru[2] + ru[4] + ru[6]) & 3; // offset for (i = 0; i < 4; i++) pwd = ru[i + r] + (pwd << 8); From 437504eae67c2b37910cc31ffed064c2e3bd9a1b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 13 Mar 2020 12:09:49 +0100 Subject: [PATCH 1661/1854] fix: hf mfu pwdgen - xyz forgot header --- include/common.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/common.h b/include/common.h index 653000409..e7d6bba90 100644 --- a/include/common.h +++ b/include/common.h @@ -64,8 +64,8 @@ extern int DBGLEVEL; # define ROTR(x,n) (((uintmax_t)(x) >> (n)) | ((uintmax_t)(x) << ((sizeof(x) * 8) - (n)))) #endif -#ifndef ROTL -# define ROTL(x,n) (((uintmax_t)(x) << (n)) | ((uintmax_t)(x) >> ((sizeof(x) * 8) - (n)))) +#ifndef PM3_ROTL +# define PM3_ROTL(x,n) (((uintmax_t)(x) << (n)) | ((uintmax_t)(x) >> ((sizeof(x) * 8) - (n)))) #endif // endian change for 64bit From 656f35036d5096e052864693156e99fbc1a5493a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 13 Mar 2020 13:01:23 +0100 Subject: [PATCH 1662/1854] text --- client/cmdhfmfu.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index a13e45d9b..120db2a9c 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -62,7 +62,7 @@ static int usage_hf_mfu_info(void) { static int usage_hf_mfu_dump(void) { PrintAndLogEx(NORMAL, "Reads all pages from Ultralight, Ultralight-C, Ultralight EV1"); PrintAndLogEx(NORMAL, "NTAG 203, NTAG 210, NTAG 212, NTAG 213, NTAG 215, NTAG 216"); - PrintAndLogEx(NORMAL, "and saves binary dump into the file " _YELLOW_("`filename.bin`") " or " _YELLOW_("`cardUID.bin`") ); + PrintAndLogEx(NORMAL, "and saves binary dump into the file " _YELLOW_("`filename.bin`") "or " _YELLOW_("`cardUID.bin`") ); PrintAndLogEx(NORMAL, "It autodetects card type.\n"); PrintAndLogEx(NORMAL, "Usage: hf mfu dump k l f p q <#pages>"); PrintAndLogEx(NORMAL, " Options :"); @@ -82,14 +82,14 @@ static int usage_hf_mfu_dump(void) { static int usage_hf_mfu_restore(void) { PrintAndLogEx(NORMAL, "Restore dumpfile onto card."); - PrintAndLogEx(NORMAL, "Usage: hf mfu restore [h] [l] [s] k n "); + PrintAndLogEx(NORMAL, "Usage: hf mfu restore [h] [l] [s] k n "); PrintAndLogEx(NORMAL, " Options :"); PrintAndLogEx(NORMAL, " k : (optional) key for authentication [UL-C 16bytes, EV1/NTAG 4bytes]"); PrintAndLogEx(NORMAL, " l : (optional) swap entered key's endianness"); PrintAndLogEx(NORMAL, " s : (optional) enable special write UID " _BLUE_("-MAGIC TAG ONLY-") ); PrintAndLogEx(NORMAL, " e : (optional) enable special write version/signature " _BLUE_("-MAGIC NTAG 21* ONLY-") ); PrintAndLogEx(NORMAL, " r : (optional) use the password found in dumpfile to configure tag. requires " _YELLOW_("'e'") "parameter to work"); - PrintAndLogEx(NORMAL, " f : " _YELLOW_("filename w/o .bin") "to restore"); + PrintAndLogEx(NORMAL, " f : " _YELLOW_("filename w .bin") "to restore"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf mfu restore s f myfile"); @@ -130,7 +130,7 @@ static int usage_hf_mfu_wrbl(void) { static int usage_hf_mfu_eload(void) { PrintAndLogEx(NORMAL, "It loads emul dump from the file " _YELLOW_("`filename.eml`") ); - PrintAndLogEx(NORMAL, "Hint: See script dumptoemul-mfu.lua to convert the .bin to the eml"); + PrintAndLogEx(NORMAL, "Hint: See " _YELLOW_("`script run dumptoemul-mfu`") "to convert the .bin to the eml"); PrintAndLogEx(NORMAL, "Usage: hf mfu eload u [numblocks]"); PrintAndLogEx(NORMAL, " Options:"); PrintAndLogEx(NORMAL, " h : this help"); @@ -174,6 +174,7 @@ static int usage_hf_mfu_ucauth(void) { } static int usage_hf_mfu_ucsetpwd(void) { + PrintAndLogEx(NORMAL, "Set 3DES password on Mifare Ultralight-C tag."); PrintAndLogEx(NORMAL, "Usage: hf mfu setpwd "); PrintAndLogEx(NORMAL, " [password] - (32 hex symbols)"); PrintAndLogEx(NORMAL, ""); @@ -186,7 +187,8 @@ static int usage_hf_mfu_ucsetpwd(void) { static int usage_hf_mfu_ucsetuid(void) { PrintAndLogEx(NORMAL, "Usage: hf mfu setuid "); PrintAndLogEx(NORMAL, " [uid] - (14 hex symbols)"); - PrintAndLogEx(NORMAL, "\nThis only works for Magic Ultralight tags."); + PrintAndLogEx(NORMAL, "\n"); + PrintAndLogEx(NORMAL, "This only works for " _BLUE_("Magic Ultralight") "tags."); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf mfu setuid 11223344556677"); @@ -223,7 +225,7 @@ static int usage_hf_mfu_pwdgen(void) { } static int usage_hf_mfu_otp_tearoff(void) { - PrintAndLogEx(NORMAL, "Tear-off test against OTP block on MFU tags - More help sooner or later\n"); + PrintAndLogEx(NORMAL, "Tear-off test against OTP block on MFU tags."); PrintAndLogEx(NORMAL, "Usage: hf mfu otptear [h]"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h : this help"); @@ -1276,7 +1278,7 @@ static int CmdHF14AMfUInfo(const char *Cmd) { num_to_bytes(ul_ev1_pwdgenA(card.uid), 4, key); len = ulev1_requestAuthentication(key, pack, sizeof(pack)); if (len > -1) { - PrintAndLogEx(SUCCESS, "Found a default password:" _GREEN_("%s") " || Pack: %02X %02X", sprint_hex(key, 4), pack[0], pack[1]); + PrintAndLogEx(SUCCESS, "Found a default password: " _GREEN_("%s") "|| Pack: %02X %02X", sprint_hex(key, 4), pack[0], pack[1]); goto out; } @@ -1286,7 +1288,7 @@ static int CmdHF14AMfUInfo(const char *Cmd) { num_to_bytes(ul_ev1_pwdgenB(card.uid), 4, key); len = ulev1_requestAuthentication(key, pack, sizeof(pack)); if (len > -1) { - PrintAndLogEx(SUCCESS, "Found a default password:" _GREEN_("%s") " || Pack: %02X %02X", sprint_hex(key, 4), pack[0], pack[1]); + PrintAndLogEx(SUCCESS, "Found a default password: " _GREEN_("%s") "|| Pack: %02X %02X", sprint_hex(key, 4), pack[0], pack[1]); goto out; } @@ -1296,7 +1298,7 @@ static int CmdHF14AMfUInfo(const char *Cmd) { num_to_bytes(ul_ev1_pwdgenC(card.uid), 4, key); len = ulev1_requestAuthentication(key, pack, sizeof(pack)); if (len > -1) { - PrintAndLogEx(SUCCESS, "Found a default password:" _GREEN_("%s") " || Pack: %02X %02X", sprint_hex(key, 4), pack[0], pack[1]); + PrintAndLogEx(SUCCESS, "Found a default password: " _GREEN_("%s") "|| Pack: %02X %02X", sprint_hex(key, 4), pack[0], pack[1]); goto out; } @@ -1316,7 +1318,7 @@ static int CmdHF14AMfUInfo(const char *Cmd) { key = default_pwd_pack[i]; len = ulev1_requestAuthentication(key, pack, sizeof(pack)); if (len > -1) { - PrintAndLogEx(SUCCESS, "Found a default password:" _GREEN_("%s") " || Pack: %02X %02X", sprint_hex(key, 4), pack[0], pack[1]); + PrintAndLogEx(SUCCESS, "Found a default password: " _GREEN_("%s") "|| Pack: %02X %02X", sprint_hex(key, 4), pack[0], pack[1]); break; } else { if (ul_auth_select(&card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack)) == PM3_ESOFT) return PM3_ESOFT; From 6f1ed5a9bf90466534dfa12e8c6702f332bfb979 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 13 Mar 2020 13:51:54 +0100 Subject: [PATCH 1663/1854] cppchecker shadow var --- tools/hitag2crack/crack2/ht2crack2buildtable.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/hitag2crack/crack2/ht2crack2buildtable.c b/tools/hitag2crack/crack2/ht2crack2buildtable.c index ffabd8f2e..70a6c51ef 100644 --- a/tools/hitag2crack/crack2/ht2crack2buildtable.c +++ b/tools/hitag2crack/crack2/ht2crack2buildtable.c @@ -143,16 +143,16 @@ void writetable(struct table *t1) { // store value in table void store(unsigned char *data) { - unsigned char d1, d2; + unsigned char d_1, d_2; int offset; struct table *t1; // use the first two bytes as an index - d1 = data[0]; - d2 = data[1]; - offset = (d1 * 0x100) + d2; + d_1 = data[0]; + d_2 = data[1]; + offset = (d_1 * 0x100) + d_2; - if (debug) printf("store, d1=%02X, d2=%02X, offset = %d\n", d1, d2, offset); + if (debug) printf("store, d1=%02X, d2=%02X, offset = %d\n", d_1, d_2, offset); // get pointer to table entry t1 = t + offset; From c7d2ccb8bd4177e240d836759b64a2802641847f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 13 Mar 2020 13:52:08 +0100 Subject: [PATCH 1664/1854] cppchecker function name --- tools/hitag2crack/crack2/hitagcrypto.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/tools/hitag2crack/crack2/hitagcrypto.c b/tools/hitag2crack/crack2/hitagcrypto.c index 5ebfc5ae9..3c4f84bc6 100644 --- a/tools/hitag2crack/crack2/hitagcrypto.c +++ b/tools/hitag2crack/crack2/hitagcrypto.c @@ -228,18 +228,17 @@ static uint32_t hitag2_crypt(uint64_t x); #define pickbits1_2_1(S, A, B, C) ( ((S >> A) & 1) | ((S >> (B - 1)) & 6) | \ ((S >> (C - 3)) & 8) ) - -static uint32_t hitag2_crypt(uint64_t s) { +static uint32_t hitag2_crypt(uint64_t x) { const uint32_t ht2_function4a = 0x2C79; // 0010 1100 0111 1001 const uint32_t ht2_function4b = 0x6671; // 0110 0110 0111 0001 const uint32_t ht2_function5c = 0x7907287B; // 0111 1001 0000 0111 0010 1000 0111 1011 uint32_t bitindex; - bitindex = (ht2_function4a >> pickbits2_2(s, 1, 4)) & 1; - bitindex |= ((ht2_function4b << 1) >> pickbits1_1_2(s, 7, 11, 13)) & 0x02; - bitindex |= ((ht2_function4b << 2) >> pickbits1x4(s, 16, 20, 22, 25)) & 0x04; - bitindex |= ((ht2_function4b << 3) >> pickbits2_1_1(s, 27, 30, 32)) & 0x08; - bitindex |= ((ht2_function4a << 4) >> pickbits1_2_1(s, 33, 42, 45)) & 0x10; + bitindex = (ht2_function4a >> pickbits2_2(x, 1, 4)) & 1; + bitindex |= ((ht2_function4b << 1) >> pickbits1_1_2(x, 7, 11, 13)) & 0x02; + bitindex |= ((ht2_function4b << 2) >> pickbits1x4(x, 16, 20, 22, 25)) & 0x04; + bitindex |= ((ht2_function4b << 3) >> pickbits2_1_1(x, 27, 30, 32)) & 0x08; + bitindex |= ((ht2_function4a << 4) >> pickbits1_2_1(x, 33, 42, 45)) & 0x10; DEBUG_PRINTF("hitag2_crypt bitindex = %02x\n", bitindex); return (ht2_function5c >> bitindex) & 1; From f6e013c7fc5a28166623496c2a179ac57f16b2c4 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 13 Mar 2020 13:52:23 +0100 Subject: [PATCH 1665/1854] cppchecker --- armsrc/hitag2crack.c | 10 +++++----- armsrc/hitag2crack.h | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/armsrc/hitag2crack.c b/armsrc/hitag2crack.c index 2d0d868b9..d66f740bc 100644 --- a/armsrc/hitag2crack.c +++ b/armsrc/hitag2crack.c @@ -300,7 +300,7 @@ bool hitag2crack_read_page(uint8_t *responsestr, uint8_t pagenum, uint8_t *nrar, uint8_t response[32]; int i; - if ((pagenum < 0) || (pagenum > 7)) { + if (pagenum > 7) { UserMessage("hitag2crack_read_page:\r\n invalid pagenum\r\n"); return false; } @@ -351,7 +351,7 @@ bool hitag2crack_read_page(uint8_t *responsestr, uint8_t pagenum, uint8_t *nrar, // cmd is the binarray of the encrypted command to send; // len is the length of the encrypted command. bool hitag2crack_send_e_cmd(uint8_t *responsestr, uint8_t *nrar, uint8_t *cmd, int len) { - uint8_t tmp[37]; +// uint8_t tmp[37]; uint8_t uid[9]; uint8_t e_page3str[9]; int ret = 0; @@ -551,14 +551,14 @@ bool hitag2_keystream(uint8_t *response, uint8_t *nrarhex) { uint8_t uid[32]; uint8_t nrar[64]; uint8_t e_firstcmd[10]; - uint8_t e_page0cmd[10]; +// uint8_t e_page0cmd[10]; // uint8_t keybits[2080]; uint8_t *keybits = DataBuff; uint8_t keybitshex[67]; int kslen; int ksoffset; - uint8_t pagehex[9]; - uint8_t temp[20]; +// uint8_t pagehex[9]; +// uint8_t temp[20]; int i; uint8_t *spaceptr = NULL; diff --git a/armsrc/hitag2crack.h b/armsrc/hitag2crack.h index 75fa54546..af3e41d14 100644 --- a/armsrc/hitag2crack.h +++ b/armsrc/hitag2crack.h @@ -19,9 +19,9 @@ bool hitag2crack_tx_rx(uint8_t *responsestr, uint8_t *msg, int len, int state, b bool hitag2crack_rng_init(uint8_t *response, uint8_t *input); bool hitag2crack_decrypt_hex(uint8_t *response, uint8_t *hex); -bool hitag2crack_decrypt_bin(uint8_t *response, uint8_t *hex); +bool hitag2crack_decrypt_bin(uint8_t *response, uint8_t *e_binstr); bool hitag2crack_encrypt_hex(uint8_t *response, uint8_t *hex); -bool hitag2crack_encrypt_bin(uint8_t *response, uint8_t *hex); +bool hitag2crack_encrypt_bin(uint8_t *response, uint8_t *e_binstr); bool hitag2_keystream(uint8_t *response, uint8_t *nrarhex); bool hitag2crack_send_auth(uint8_t *nrar); From 294d2aa96b2c76107875419a1f540287bbc63c9d Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 13 Mar 2020 13:52:29 +0100 Subject: [PATCH 1666/1854] cppchecker --- armsrc/hitag2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index 2df49ac3d..7e4c7ca14 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -544,7 +544,7 @@ bool hitag1_authenticate(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t *t // will receive 32-bit configuration page } else if (bSelecting) { // Initiate auth - tx[0] = 0xa0 | key_no >> 4; // WRCPAGE + tx[0] = 0xa0 | (key_no); // WRCPAGE tx[1] = blocknr << 4; crc = hitag_crc(tx, 12); tx[1] |= crc >> 4; From f13149826c22b7917da90e3aa66429d87a0f6203 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 13 Mar 2020 13:52:55 +0100 Subject: [PATCH 1667/1854] cppchecker format macro --- armsrc/Standalone/lf_icehid.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/armsrc/Standalone/lf_icehid.c b/armsrc/Standalone/lf_icehid.c index d66186c9d..d68f8423d 100644 --- a/armsrc/Standalone/lf_icehid.c +++ b/armsrc/Standalone/lf_icehid.c @@ -105,7 +105,7 @@ uint32_t IceEM410xdemod() { memset(entry, 0, sizeof(entry)); if (size == 128) { - sprintf((char *)entry, "EM XL TAG ID: %06lx%08lx%08lx - (%05ld_%03ld_%08ld)\n", + sprintf((char *)entry, "EM XL TAG ID: %06"PRIx32"%08"PRIx32"%08"PRIx32" - (%05"PRIu32"_%03"PRIu32"_%08"PRIu32")\n", hi, (uint32_t)(lo >> 32), (uint32_t)lo, @@ -113,7 +113,7 @@ uint32_t IceEM410xdemod() { (uint32_t)((lo >> 16LL) & 0xFF), (uint32_t)(lo & 0xFFFFFF)); } else { - sprintf((char *)entry, "EM TAG ID: %02lx%08lx - (%05ld_%03ld_%08ld)\n", + sprintf((char *)entry, "EM TAG ID: %02"PRIx32"%08"PRIx32" - (%05"PRIu32"_%03"PRIu32"_%08"PRIu32")\n", (uint32_t)(lo >> 32), (uint32_t)lo, (uint32_t)(lo & 0xFFFF), @@ -160,16 +160,16 @@ uint32_t IceAWIDdemod() { uint8_t fac = bytebits_to_byte(dest + 9, 8); uint32_t cardnum = bytebits_to_byte(dest + 17, 16); uint32_t code1 = bytebits_to_byte(dest + 8, fmtLen); - sprintf((char *)entry, "AWID bit len: %d, FC: %d, Card: %ld - Wiegand: %lx, Raw: %08lx%08lx%08lx\n", fmtLen, fac, cardnum, code1, rawHi2, rawHi, rawLo); + sprintf((char *)entry, "AWID bit len: %d, FC: %d, Card: %"PRIu32" - Wiegand: %"PRIx32", Raw: %08"PRIx32"%08"PRIx32"%08"PRIx32"\n", fmtLen, fac, cardnum, code1, rawHi2, rawHi, rawLo); } else { uint32_t cardnum = bytebits_to_byte(dest + 8 + (fmtLen - 17), 16); if (fmtLen > 32) { uint32_t code1 = bytebits_to_byte(dest + 8, fmtLen - 32); uint32_t code2 = bytebits_to_byte(dest + 8 + (fmtLen - 32), 32); - sprintf((char *)entry, "AWID bit len: %d -unk bit len - Card: %ld - Wiegand: %lx%08lx, Raw: %08lx%08lx%08lx\n", fmtLen, cardnum, code1, code2, rawHi2, rawHi, rawLo); + sprintf((char *)entry, "AWID bit len: %d -unk bit len - Card: %"PRIu32" - Wiegand: %"PRIx32"%08"PRIx32", Raw: %08"PRIx32"%08"PRIx32"%08"PRIx32"\n", fmtLen, cardnum, code1, code2, rawHi2, rawHi, rawLo); } else { uint32_t code1 = bytebits_to_byte(dest + 8, fmtLen); - sprintf((char *)entry, "AWID bit len: %d -unk bit len - Card: %ld - Wiegand: %lx, Raw: %08lx%08lx%08lx\n", fmtLen, cardnum, code1, rawHi2, rawHi, rawLo); + sprintf((char *)entry, "AWID bit len: %d -unk bit len - Card: %"PRIu32" - Wiegand: %"PRIx32", Raw: %08"PRIx32"%08"PRIx32"%08"PRIx32"\n", fmtLen, cardnum, code1, rawHi2, rawHi, rawLo); } } @@ -209,7 +209,7 @@ uint32_t IceIOdemod() { uint8_t entry[64]; memset(entry, 0, sizeof(entry)); - sprintf((char *)entry, "IO Prox XSF(%02d)%02x:%05d (%08lx%08lx)\n" + sprintf((char *)entry, "IO Prox XSF(%02u)%02x:%05u (%08"PRIx32"%08"PRIx32")\n" , version , facilitycode , number @@ -249,7 +249,7 @@ uint32_t IceHIDDemod() { // go over previously decoded manchester data and decode into usable tag ID if (hi2 != 0) { //extra large HID tags 88/192 bits - sprintf((char *)entry, "HID large: %lx%08lx%08lx (%ld)\n", + sprintf((char *)entry, "HID large: %"PRIx32"%08"PRIx32"%08"PRIx32" (%"PRIu32")\n", hi2, hi, lo, @@ -296,7 +296,7 @@ uint32_t IceHIDDemod() { fac = ((hi & 0xF) << 12) | (lo >> 20); } - sprintf((char *)entry, "HID: %lx%08lx (%ld) Format: %d bit FC: %ld Card: %ld\n", + sprintf((char *)entry, "HID: %"PRIx32"%08"PRIx32" (%"PRIu32") Format: %d bit FC: %"PRIu32" Card: %"PRIu32"\n", hi, lo, (lo >> 1) & 0xFFFF, From f761874347a864421c66db0372e4b7e945f34782 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 13 Mar 2020 14:13:59 +0100 Subject: [PATCH 1668/1854] cppcheck macro sizeof --- common/generator.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/common/generator.c b/common/generator.c index 768917492..4be63a925 100644 --- a/common/generator.c +++ b/common/generator.c @@ -35,14 +35,14 @@ // Vinglock //------------------------------------ void transform_D(uint8_t* ru) { - - const uint32_t c_D[] = { - 0x6D835AFC, 0x7D15CD97, 0x0942B409, 0x32F9C923, 0xA811FB02, 0x64F121E8, - 0xD1CC8B4E, 0xE8873E6F, 0x61399BBB, 0xF1B91926, 0xAC661520, 0xA21A31C9, - 0xD424808D, 0xFE118E07, 0xD18E728D, 0xABAC9E17, 0x18066433, 0x00E18E79, - 0x65A77305, 0x5AE9E297, 0x11FC628C, 0x7BB3431F, 0x942A8308, 0xB2F8FD20, + + const uint32_t c_D[] = { + 0x6D835AFC, 0x7D15CD97, 0x0942B409, 0x32F9C923, 0xA811FB02, 0x64F121E8, + 0xD1CC8B4E, 0xE8873E6F, 0x61399BBB, 0xF1B91926, 0xAC661520, 0xA21A31C9, + 0xD424808D, 0xFE118E07, 0xD18E728D, 0xABAC9E17, 0x18066433, 0x00E18E79, + 0x65A77305, 0x5AE9E297, 0x11FC628C, 0x7BB3431F, 0x942A8308, 0xB2F8FD20, 0x5728B869, 0x30726D5A - }; + }; //Transform uint8_t i; @@ -51,10 +51,14 @@ void transform_D(uint8_t* ru) { uint32_t v2 = ((ru[7] << 24) | (ru[6] << 16) | (ru[5] << 8) | ru[4]) + c_D[p++]; for (i = 0; i < 12; i += 2) { - uint32_t t1 = PM3_ROTL(v1 ^ v2, v2 & 0x1F) + c_D[p++]; - uint32_t t2 = PM3_ROTL(v2 ^ t1, t1 & 0x1F) + c_D[p++]; - v1 = PM3_ROTL(t1 ^ t2, t2 & 0x1F) + c_D[p++]; - v2 = PM3_ROTL(t2 ^ v1, v1 & 0x1F) + c_D[p++]; + uint32_t tempA = v1 ^ v2; + uint32_t t1 = PM3_ROTL(tempA, v2 & 0x1F) + c_D[p++]; + uint32_t tempB = v2 ^ t1; + uint32_t t2 = PM3_ROTL(tempB, t1 & 0x1F) + c_D[p++]; + tempA = t1 ^ t2; + v1 = PM3_ROTL(tempA, t2 & 0x1F) + c_D[p++]; + tempB = t2 ^ v1; + v2 = PM3_ROTL(tempB, v1 & 0x1F) + c_D[p++]; } //Re-use ru From c3024fe9f256e27b4238a4e016a879db29f6b657 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 13 Mar 2020 14:14:19 +0100 Subject: [PATCH 1669/1854] cppcheck shadow --- tools/hitag2crack/crack2/ht2crack2buildtable.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/hitag2crack/crack2/ht2crack2buildtable.c b/tools/hitag2crack/crack2/ht2crack2buildtable.c index 70a6c51ef..0aca200ef 100644 --- a/tools/hitag2crack/crack2/ht2crack2buildtable.c +++ b/tools/hitag2crack/crack2/ht2crack2buildtable.c @@ -362,10 +362,10 @@ void makedirs() { } static int datacmp(const void *p1, const void *p2, void *dummy) { - unsigned char *d1 = (unsigned char *)p1; - unsigned char *d2 = (unsigned char *)p2; + unsigned char *d_1 = (unsigned char *)p1; + unsigned char *d_2 = (unsigned char *)p2; - return memcmp(d1, d2, DATASIZE); + return memcmp(d_1, d_2, DATASIZE); } void *sorttable(void *d) { From 53ecdaf78f9fab0654df3b656a9889f296a9607a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 13 Mar 2020 14:14:30 +0100 Subject: [PATCH 1670/1854] cppcheck func name --- tools/hitag2crack/crack3/hitagcrypto.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tools/hitag2crack/crack3/hitagcrypto.c b/tools/hitag2crack/crack3/hitagcrypto.c index 23b88228d..21662b43e 100644 --- a/tools/hitag2crack/crack3/hitagcrypto.c +++ b/tools/hitag2crack/crack3/hitagcrypto.c @@ -229,17 +229,17 @@ static uint32_t hitag2_crypt(uint64_t x); ((S >> (C - 3)) & 8) ) -static uint32_t hitag2_crypt(uint64_t s) { +static uint32_t hitag2_crypt(uint64_t x) { const uint32_t ht2_function4a = 0x2C79; // 0010 1100 0111 1001 const uint32_t ht2_function4b = 0x6671; // 0110 0110 0111 0001 const uint32_t ht2_function5c = 0x7907287B; // 0111 1001 0000 0111 0010 1000 0111 1011 uint32_t bitindex; - bitindex = (ht2_function4a >> pickbits2_2(s, 1, 4)) & 1; - bitindex |= ((ht2_function4b << 1) >> pickbits1_1_2(s, 7, 11, 13)) & 0x02; - bitindex |= ((ht2_function4b << 2) >> pickbits1x4(s, 16, 20, 22, 25)) & 0x04; - bitindex |= ((ht2_function4b << 3) >> pickbits2_1_1(s, 27, 30, 32)) & 0x08; - bitindex |= ((ht2_function4a << 4) >> pickbits1_2_1(s, 33, 42, 45)) & 0x10; + bitindex = (ht2_function4a >> pickbits2_2(x, 1, 4)) & 1; + bitindex |= ((ht2_function4b << 1) >> pickbits1_1_2(x, 7, 11, 13)) & 0x02; + bitindex |= ((ht2_function4b << 2) >> pickbits1x4(x, 16, 20, 22, 25)) & 0x04; + bitindex |= ((ht2_function4b << 3) >> pickbits2_1_1(x, 27, 30, 32)) & 0x08; + bitindex |= ((ht2_function4a << 4) >> pickbits1_2_1(x, 33, 42, 45)) & 0x10; DEBUG_PRINTF("hitag2_crypt bitindex = %02x\n", bitindex); return (ht2_function5c >> bitindex) & 1; From 6f20f86c2d7eb2f6900172dac6d678bfbff061b6 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 13 Mar 2020 14:22:53 +0100 Subject: [PATCH 1671/1854] cppchecker - param name --- client/cmdhflto.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/cmdhflto.c b/client/cmdhflto.c index dfbca68c1..c5b73c0c6 100644 --- a/client/cmdhflto.c +++ b/client/cmdhflto.c @@ -524,7 +524,7 @@ static int CmdHfLTODump(const char *Cmd) { return PM3_SUCCESS; } -int restoreLTO(uint8_t *dump_data, bool verbose) { +int restoreLTO(uint8_t *dump, bool verbose) { clearCommandBuffer(); lto_switch_on_field(); @@ -545,13 +545,13 @@ int restoreLTO(uint8_t *dump_data, bool verbose) { for (uint8_t blk = 2; blk < 255; blk++) { for (int i = 0; i < 32; i++) { - blkData[i] = dump_data[i + blk * 32]; + blkData[i] = dump[i + blk * 32]; } ret_val = lto_wrbl(blk, blkData, verbose); if (ret_val == PM3_SUCCESS) { - PrintAndLogEx(SUCCESS, "BLK %03d: " _YELLOW_("write success"), blk); + PrintAndLogEx(SUCCESS, "Block %03d - " _YELLOW_("write success"), blk); } else { lto_switch_off_field(); return ret_val; From e460a4e6ca6fe054ff9a2b58e65ad58679566e68 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 13 Mar 2020 14:23:34 +0100 Subject: [PATCH 1672/1854] cppchecker - param name --- client/cmdlfindala.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdlfindala.h b/client/cmdlfindala.h index 1d0762f5f..65ed29e61 100644 --- a/client/cmdlfindala.h +++ b/client/cmdlfindala.h @@ -19,6 +19,6 @@ int detectIndala26(uint8_t *bitStream, size_t *size, uint8_t *invert); int detectIndala64(uint8_t *bitStream, size_t *size, uint8_t *invert); int detectIndala224(uint8_t *bitStream, size_t *size, uint8_t *invert); int demodIndala(void); -int getIndalaBits(uint8_t fc, uint16_t csn, uint8_t *bits); +int getIndalaBits(uint8_t fc, uint16_t cn, uint8_t *bits); #endif From 43e1c5f22deb0b1e1f337fbb81f2f2bf46bc5703 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 13 Mar 2020 14:27:50 +0100 Subject: [PATCH 1673/1854] cppchecker - shadow --- client/fileutils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/fileutils.c b/client/fileutils.c index d9e6e4445..f47e32b73 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -70,7 +70,7 @@ struct wave_info_t { char tag[4]; uint32_t size; } PACKED audio_data; -} PACKED wave_info; +} PACKED; /** * @brief checks if a file exists From bf597dd2d22d678782da0c49e5bfc27dfca188a6 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 13 Mar 2020 14:28:02 +0100 Subject: [PATCH 1674/1854] cppchecker - signed shift --- client/cmdlfkeri.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdlfkeri.c b/client/cmdlfkeri.c index 3c7863361..c698842a6 100644 --- a/client/cmdlfkeri.c +++ b/client/cmdlfkeri.c @@ -144,7 +144,7 @@ static int CmdKeriMSScramble (KeriMSScramble_t Action, uint32_t *FC, uint32_t *I *CardID = *CardID | Parity; // Bit 31 was fixed but not in check/parity bits - *CardID |= (1 << 31); + *CardID |= (uint32_t)(1 << 31); PrintAndLogEx(SUCCESS, "Scrambled FC : %d - Card ID : %d to RAW : E0000000%08X",*FC,*ID,*CardID); } From a9aaa3040ec12900b86294b4273645771b1f0a6e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 13 Mar 2020 14:34:18 +0100 Subject: [PATCH 1675/1854] cppchecker - format print --- tools/hitag2crack/crack3/ht2crack3.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/hitag2crack/crack3/ht2crack3.c b/tools/hitag2crack/crack3/ht2crack3.c index 747f7785c..11cab5ed9 100644 --- a/tools/hitag2crack/crack3/ht2crack3.c +++ b/tools/hitag2crack/crack3/ht2crack3.c @@ -381,14 +381,14 @@ int main(int argc, char *argv[]) { while (getline(&buf, &lenbuf, fp) > 0) { buft1 = strchr(buf, ' '); if (!buft1) { - printf("invalid file input on line %d\n", numnrar + 1); + printf("invalid file input on line %u\n", numnrar + 1); exit(1); } *buft1 = 0x00; buft1++; buft2 = strchr(buft1, '\n'); if (!buft2) { - printf("no CR on line %d\n", numnrar + 1); + printf("no CR on line %u\n", numnrar + 1); exit(1); } *buft2 = 0x00; @@ -406,7 +406,7 @@ int main(int argc, char *argv[]) { fclose(fp); fp = NULL; - printf("Loaded %d NrAr pairs\n", numnrar); + printf("Loaded %u NrAr pairs\n", numnrar); // create table of thread data tdata = (struct threaddata *)malloc(sizeof(struct threaddata) * NUM_THREADS); From 022eacecdce350151345f1e0ca4f031b5b4252d9 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 13 Mar 2020 14:37:49 +0100 Subject: [PATCH 1676/1854] format --- tools/hitag2crack/crack3/ht2crack3.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/hitag2crack/crack3/ht2crack3.c b/tools/hitag2crack/crack3/ht2crack3.c index 11cab5ed9..da35bbd14 100644 --- a/tools/hitag2crack/crack3/ht2crack3.c +++ b/tools/hitag2crack/crack3/ht2crack3.c @@ -1,6 +1,7 @@ #include #include #include +#include #include "HardwareProfile.h" #include "rfidler.h" @@ -243,7 +244,7 @@ void *crack(void *d) { // find keys for (klower = data->klowerstart; klower < (data->klowerstart + data->klowerrange); klower++) { - printf("trying klower = 0x%05lx\n", klower); + printf("trying klower = 0x%05"PRIx64"\n", klower); // build table count = 0; for (y = 0; y < 0x40000; y++) { @@ -304,7 +305,7 @@ void *crack(void *d) { if ((found) && (!badguess)) { // brute - printf("possible partial key found: 0x%012lx\n", ((uint64_t)kmiddle << 16) | klower); + printf("possible partial key found: 0x%012"PRIx64"\n", ((uint64_t)kmiddle << 16) | klower); if (testkey(&foundkey, uid, (kmiddle << 16 | klower), TnRaR[0].nR, TnRaR[0].aR) && testkey(&foundkey, uid, (kmiddle << 16 | klower), TnRaR[1].nR, TnRaR[1].aR)) { From 21e6cff4ba96b23076a1a37345b4771c074c4989 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 13 Mar 2020 14:42:04 +0100 Subject: [PATCH 1677/1854] format printf --- tools/hitag2crack/crack4/ht2crack4.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tools/hitag2crack/crack4/ht2crack4.c b/tools/hitag2crack/crack4/ht2crack4.c index 44952f4b7..5c2d11c2e 100644 --- a/tools/hitag2crack/crack4/ht2crack4.c +++ b/tools/hitag2crack/crack4/ht2crack4.c @@ -270,14 +270,14 @@ void init_guess_table(char *filename, char *uidstr) { while ((getline(&buf, &lenbuf, fp) > 0) && (num_nRaR < MAX_NONCES)) { buft1 = strchr(buf, ' '); if (!buft1) { - printf("invalid file input on line %d\n", num_nRaR + 1); + printf("invalid file input on line %u\n", num_nRaR + 1); exit(1); } *buft1 = 0x00; buft1++; buft2 = strchr(buft1, '\n'); if (!buft2) { - printf("no CR on line %d\n", num_nRaR + 1); + printf("no CR on line %u\n", num_nRaR + 1); exit(1); } *buft2 = 0x00; @@ -294,7 +294,7 @@ void init_guess_table(char *filename, char *uidstr) { fclose(fp); fp = NULL; - fprintf(stderr, "Loaded %d nRaR pairs\n", num_nRaR); + fprintf(stderr, "Loaded %u nRaR pairs\n", num_nRaR); // set key and copy in enc_nR and ks values // set score to -1.0 to distinguish them from 0 scores @@ -516,7 +516,7 @@ void score_all_traces(unsigned int size) { // start the threads for (i = 0; i < NUM_THREADS; i++) { if (pthread_create(&(threads[i]), NULL, score_some_traces, (void *)(tdata + i))) { - printf("cannot start thread %d\n", i); + printf("cannot start thread %u\n", i); exit(1); } } @@ -524,7 +524,7 @@ void score_all_traces(unsigned int size) { // wait for threads to end for (i = 0; i < NUM_THREADS; i++) { if (pthread_join(threads[i], &status)) { - printf("cannot join thread %d\n", i); + printf("cannot join thread %u\n", i); exit(1); } } @@ -620,13 +620,13 @@ void crack() { uint64_t foundkey; for (i = 16; i <= 48; i++) { - fprintf(stderr, "round %2d, size=%2d\n", i - 16, i); + fprintf(stderr, "round %2u, size=%2u\n", i - 16, i); execute_round(i); // print some metrics revkey = rev64(guesses[0].key); foundkey = ((revkey >> 40) & 0xff) | ((revkey >> 24) & 0xff00) | ((revkey >> 8) & 0xff0000) | ((revkey << 8) & 0xff000000) | ((revkey << 24) & 0xff00000000) | ((revkey << 40) & 0xff0000000000); - fprintf(stderr, " guess=%012" PRIx64 ", num_guesses = %d, top score=%1.10f, min score=%1.10f\n", foundkey, num_guesses, guesses[0].score, guesses[num_guesses - 1].score); + fprintf(stderr, " guess=%012" PRIx64 ", num_guesses = %u, top score=%1.10f, min score=%1.10f\n", foundkey, num_guesses, guesses[0].score, guesses[num_guesses - 1].score); } } @@ -745,7 +745,7 @@ void test() { packed = packstate(lfsr); if (hitag2_crypt(lfsr) != f20(packed)) { - printf(" * * * FAIL: %3" PRIu64 ": 0x%012" PRIx64 " = %d, 0x%012" PRIx64 " = 0x%05" PRIx64 "\n", i, lfsr, hitag2_crypt(lfsr), packed, f20(packed)); + printf(" * * * FAIL: %3" PRIu64 ": 0x%012" PRIx64 " = %u, 0x%012" PRIx64 " = 0x%05" PRIx64 "\n", i, lfsr, hitag2_crypt(lfsr), packed, f20(packed)); } } @@ -821,7 +821,7 @@ int main(int argc, char *argv[]) { if ((tot_nRaR > 0) && (tot_nRaR <= num_nRaR)) { num_nRaR = tot_nRaR; } - fprintf(stderr, "Using %d nRaR pairs\n", num_nRaR); + fprintf(stderr, "Using %u nRaR pairs\n", num_nRaR); crack(); From c46119d7553d1366ada9b875a259ff057b53a4a9 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 13 Mar 2020 15:03:11 +0100 Subject: [PATCH 1678/1854] cppchecker - format print --- tools/hitag2crack/crack4/ht2crack4.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/hitag2crack/crack4/ht2crack4.c b/tools/hitag2crack/crack4/ht2crack4.c index 5c2d11c2e..54e23d550 100644 --- a/tools/hitag2crack/crack4/ht2crack4.c +++ b/tools/hitag2crack/crack4/ht2crack4.c @@ -575,7 +575,7 @@ void check_supplied_testkey(unsigned int size) { for (i = 0; i < num_guesses; i++) { if (guesses[i].key == partkey) { - fprintf(stderr, " supplied test key score = %1.10f, position = %d\n", guesses[i].score, i); + fprintf(stderr, " supplied test key score = %1.10f, position = %u\n", guesses[i].score, i); return; } } From 2f85bced17dee80fbe0b3cb0e8b481388c570693 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 13 Mar 2020 15:04:07 +0100 Subject: [PATCH 1679/1854] cppchecker func name --- tools/hitag2crack/crack4/hitagcrypto.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tools/hitag2crack/crack4/hitagcrypto.c b/tools/hitag2crack/crack4/hitagcrypto.c index 23b88228d..21662b43e 100644 --- a/tools/hitag2crack/crack4/hitagcrypto.c +++ b/tools/hitag2crack/crack4/hitagcrypto.c @@ -229,17 +229,17 @@ static uint32_t hitag2_crypt(uint64_t x); ((S >> (C - 3)) & 8) ) -static uint32_t hitag2_crypt(uint64_t s) { +static uint32_t hitag2_crypt(uint64_t x) { const uint32_t ht2_function4a = 0x2C79; // 0010 1100 0111 1001 const uint32_t ht2_function4b = 0x6671; // 0110 0110 0111 0001 const uint32_t ht2_function5c = 0x7907287B; // 0111 1001 0000 0111 0010 1000 0111 1011 uint32_t bitindex; - bitindex = (ht2_function4a >> pickbits2_2(s, 1, 4)) & 1; - bitindex |= ((ht2_function4b << 1) >> pickbits1_1_2(s, 7, 11, 13)) & 0x02; - bitindex |= ((ht2_function4b << 2) >> pickbits1x4(s, 16, 20, 22, 25)) & 0x04; - bitindex |= ((ht2_function4b << 3) >> pickbits2_1_1(s, 27, 30, 32)) & 0x08; - bitindex |= ((ht2_function4a << 4) >> pickbits1_2_1(s, 33, 42, 45)) & 0x10; + bitindex = (ht2_function4a >> pickbits2_2(x, 1, 4)) & 1; + bitindex |= ((ht2_function4b << 1) >> pickbits1_1_2(x, 7, 11, 13)) & 0x02; + bitindex |= ((ht2_function4b << 2) >> pickbits1x4(x, 16, 20, 22, 25)) & 0x04; + bitindex |= ((ht2_function4b << 3) >> pickbits2_1_1(x, 27, 30, 32)) & 0x08; + bitindex |= ((ht2_function4a << 4) >> pickbits1_2_1(x, 33, 42, 45)) & 0x10; DEBUG_PRINTF("hitag2_crypt bitindex = %02x\n", bitindex); return (ht2_function5c >> bitindex) & 1; From 266f2f0fc89799c7e1d6c5515a690c110562b60e Mon Sep 17 00:00:00 2001 From: Daniel Underhay <27876907+dunderhay@users.noreply.github.com> Date: Sat, 14 Mar 2020 01:09:25 +1100 Subject: [PATCH 1680/1854] Add colour to `lf hid` commands --- CHANGELOG.md | 1 + client/cmdlfhid.c | 36 ++++++++++++++++++------------------ 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aa81e6baa..3f84700e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Add colour to `lf hid` commands in cmdlfhid.c - Change `script run hf_bruteforce -s start_id -e end_id -t timeout -x mifare_card_type` - The hf_bruteforce card script now requires Mifare type (mfc or mfu) (@dunderhay) - Updated `hf_bruteforce.lua` script - added support for brute forcing Mifare Ultralight EV1 cards (@dunderhay) - Added `hf mf personlize` - personalize the UID of a Mifare Classic EV1 card (@pwpiwi) diff --git a/client/cmdlfhid.c b/client/cmdlfhid.c index eb388faa6..c13882221 100644 --- a/client/cmdlfhid.c +++ b/client/cmdlfhid.c @@ -162,7 +162,7 @@ static int CmdHIDDemod(const char *Cmd) { uint8_t bits[GraphTraceLen]; size_t size = getFromGraphBuf(bits); if (size == 0) { - PrintAndLogEx(DEBUG, "DEBUG: Error - HID not enough samples"); + PrintAndLogEx(DEBUG, "DEBUG: Error - " _RED_("HID not enough samples")); return PM3_ESOFT; } //get binary from fsk wave @@ -171,17 +171,17 @@ static int CmdHIDDemod(const char *Cmd) { if (idx < 0) { if (idx == -1) - PrintAndLogEx(DEBUG, "DEBUG: Error - HID not enough samples"); + PrintAndLogEx(DEBUG, "DEBUG: Error - " _RED_("HID not enough samples")); else if (idx == -2) - PrintAndLogEx(DEBUG, "DEBUG: Error - HID just noise detected"); + PrintAndLogEx(DEBUG, "DEBUG: Error - " _RED_("HID just noise detected")); else if (idx == -3) - PrintAndLogEx(DEBUG, "DEBUG: Error - HID problem during FSK demod"); + PrintAndLogEx(DEBUG, "DEBUG: Error - " _RED_("HID problem during FSK demod")); else if (idx == -4) - PrintAndLogEx(DEBUG, "DEBUG: Error - HID preamble not found"); + PrintAndLogEx(DEBUG, "DEBUG: Error - " _RED_("HID preamble not found")); else if (idx == -5) - PrintAndLogEx(DEBUG, "DEBUG: Error - HID error in Manchester data, size %zu", size); + PrintAndLogEx(DEBUG, "DEBUG: Error - " _RED_("HID error in Manchester data, size %zu, size")); else - PrintAndLogEx(DEBUG, "DEBUG: Error - HID error demoding fsk %d", idx); + PrintAndLogEx(DEBUG, "DEBUG: Error - " _RED_("HID error demoding fsk %d, idx")); return PM3_ESOFT; } @@ -190,12 +190,12 @@ static int CmdHIDDemod(const char *Cmd) { setClockGrid(50, waveIdx + (idx * 50)); if (hi2 == 0 && hi == 0 && lo == 0) { - PrintAndLogEx(DEBUG, "DEBUG: Error - HID no values found"); + PrintAndLogEx(DEBUG, "DEBUG: Error - " _RED_("HID no values found")); return PM3_ESOFT; } if (hi2 != 0) { //extra large HID tags - PrintAndLogEx(SUCCESS, "HID Prox TAG ID: %x%08x%08x (%u)", hi2, hi, lo, (lo >> 1) & 0xFFFF); + PrintAndLogEx(SUCCESS, "HID Prox TAG ID: " _GREEN_("%x%08x%08x (%u)"), hi2, hi, lo, (lo >> 1) & 0xFFFF); } else { //standard HID tags <38 bits uint8_t fmtLen = 0; uint32_t cc = 0; @@ -241,14 +241,14 @@ static int CmdHIDDemod(const char *Cmd) { fc = ((hi & 0xF) << 12) | (lo >> 20); } if (fmtLen == 32 && (lo & 0x40000000)) { //if 32 bit and Kastle bit set - PrintAndLogEx(SUCCESS, "HID Prox TAG (Kastle format) ID: %x%08x (%u) - Format Len: 32bit - CC: %u - FC: %u - Card: %u", hi, lo, (lo >> 1) & 0xFFFF, cc, fc, cardnum); + PrintAndLogEx(SUCCESS, "HID Prox TAG (Kastle format) ID: " _GREEN_("%x%08x (%u)")"- Format Len: 32bit - CC: %u - FC: %u - Card: %u", hi, lo, (lo >> 1) & 0xFFFF, cc, fc, cardnum); } else { - PrintAndLogEx(SUCCESS, "HID Prox TAG ID: %x%08x (%u) - Format Len: %ubit - OEM: %03u - FC: %u - Card: %u", + PrintAndLogEx(SUCCESS, "HID Prox TAG ID: " _GREEN_("%x%08x (%u)")"- Format Len: %ubit - OEM: %03u - FC: %u - Card: %u", hi, lo, cardnum, fmtLen, oem, fc, cardnum); } } - PrintAndLogEx(DEBUG, "DEBUG: HID idx: %d, Len: %zu, Printing Demod Buffer:", idx, size); + PrintAndLogEx(DEBUG, "DEBUG: HID idx: " _GREEN_("%d, Len: %zu")", Printing Demod Buffer:", idx, size); if (g_debugMode) printDemodBuff(); @@ -288,14 +288,14 @@ static int CmdHIDSim(const char *Cmd) { lo = (lo << 4) | (n & 0xf); } - PrintAndLogEx(INFO, "Simulating HID tag with long ID %x%08x%08x", hi2, hi, lo); + PrintAndLogEx(INFO, "Simulating HID tag with long ID: " _GREEN_("%x%08x%08x"), hi2, hi, lo); payload.longFMT = 1; } else { while (sscanf(&Cmd[i++], "%1x", &n) == 1) { hi = (hi << 4) | (lo >> 28); lo = (lo << 4) | (n & 0xf); } - PrintAndLogEx(SUCCESS, "Simulating HID tag with ID %x%08x", hi, lo); + PrintAndLogEx(SUCCESS, "Simulating HID tag with ID: " _GREEN_("%x%08x"), hi, lo); hi2 = 0; } @@ -331,7 +331,7 @@ static int CmdHIDClone(const char *Cmd) { lo = (lo << 4) | (n & 0xf); } - PrintAndLogEx(INFO, "Preparing to clone HID tag with long ID %x%08x%08x", hi2, hi, lo); + PrintAndLogEx(INFO, "Preparing to clone HID tag with long ID: " _GREEN_("%x%08x%08x"), hi2, hi, lo); longid[0] = 1; } else { @@ -339,7 +339,7 @@ static int CmdHIDClone(const char *Cmd) { hi = (hi << 4) | (lo >> 28); lo = (lo << 4) | (n & 0xf); } - PrintAndLogEx(INFO, "Preparing to clone HID tag with ID %x%08x", hi, lo); + PrintAndLogEx(INFO, "Preparing to clone HID tag with ID: " _GREEN_("%x%08x"), hi, lo); hi2 = 0; } @@ -400,7 +400,7 @@ static int CmdHIDBrute(const char *Cmd) { param_getstr(Cmd, cmdp + 1, format, sizeof(format)); format_idx = HIDFindCardFormat(format); if (format_idx == -1) { - PrintAndLogEx(WARNING, "Unknown format: %s", format); + PrintAndLogEx(WARNING, _YELLOW_("Unknown format: %s"), format); errors = true; } cmdp += 2; @@ -431,7 +431,7 @@ static int CmdHIDBrute(const char *Cmd) { cmdp++; break; default: - PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + PrintAndLogEx(WARNING, _YELLOW_("Unknown parameter '%c'"), param_getchar(Cmd, cmdp)); errors = true; break; } From e041e625c0f596feba915ee730f4edf7a5566e14 Mon Sep 17 00:00:00 2001 From: Daniel Underhay <27876907+dunderhay@users.noreply.github.com> Date: Sat, 14 Mar 2020 01:17:31 +1100 Subject: [PATCH 1681/1854] Colour fixes --- client/cmdlfhid.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/cmdlfhid.c b/client/cmdlfhid.c index c13882221..80d647437 100644 --- a/client/cmdlfhid.c +++ b/client/cmdlfhid.c @@ -248,7 +248,7 @@ static int CmdHIDDemod(const char *Cmd) { } } - PrintAndLogEx(DEBUG, "DEBUG: HID idx: " _GREEN_("%d, Len: %zu")", Printing Demod Buffer:", idx, size); + PrintAndLogEx(DEBUG, "DEBUG: HID idx: " _GREEN_("%d"), " Len: %zu", Printing Demod Buffer:", idx, size); if (g_debugMode) printDemodBuff(); @@ -400,7 +400,7 @@ static int CmdHIDBrute(const char *Cmd) { param_getstr(Cmd, cmdp + 1, format, sizeof(format)); format_idx = HIDFindCardFormat(format); if (format_idx == -1) { - PrintAndLogEx(WARNING, _YELLOW_("Unknown format: %s"), format); + PrintAndLogEx(WARNING, "Unknown format: " _YELLOW_("%s"), format); errors = true; } cmdp += 2; @@ -431,7 +431,7 @@ static int CmdHIDBrute(const char *Cmd) { cmdp++; break; default: - PrintAndLogEx(WARNING, _YELLOW_("Unknown parameter '%c'"), param_getchar(Cmd, cmdp)); + PrintAndLogEx(WARNING, "Unknown parameter: " _YELLOW_("%c"), param_getchar(Cmd, cmdp)); errors = true; break; } From 3e8c4b21731fb046f61f611e7ec425759e1c8b3f Mon Sep 17 00:00:00 2001 From: Daniel Underhay <27876907+dunderhay@users.noreply.github.com> Date: Sat, 14 Mar 2020 01:22:22 +1100 Subject: [PATCH 1682/1854] Typo --- client/cmdlfhid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdlfhid.c b/client/cmdlfhid.c index 80d647437..71517695d 100644 --- a/client/cmdlfhid.c +++ b/client/cmdlfhid.c @@ -431,7 +431,7 @@ static int CmdHIDBrute(const char *Cmd) { cmdp++; break; default: - PrintAndLogEx(WARNING, "Unknown parameter: " _YELLOW_("%c"), param_getchar(Cmd, cmdp)); + PrintAndLogEx(WARNING, "Unknown parameter: " _YELLOW_("'%c'"), param_getchar(Cmd, cmdp)); errors = true; break; } From 267063a05cf8156d7d564adc0c5fc6d4b7cd5588 Mon Sep 17 00:00:00 2001 From: Daniel Underhay <27876907+dunderhay@users.noreply.github.com> Date: Sat, 14 Mar 2020 01:52:25 +1100 Subject: [PATCH 1683/1854] Fix compile errors --- client/cmdlfhid.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/cmdlfhid.c b/client/cmdlfhid.c index 71517695d..fa3d4878d 100644 --- a/client/cmdlfhid.c +++ b/client/cmdlfhid.c @@ -179,9 +179,9 @@ static int CmdHIDDemod(const char *Cmd) { else if (idx == -4) PrintAndLogEx(DEBUG, "DEBUG: Error - " _RED_("HID preamble not found")); else if (idx == -5) - PrintAndLogEx(DEBUG, "DEBUG: Error - " _RED_("HID error in Manchester data, size %zu, size")); + PrintAndLogEx(DEBUG, "DEBUG: Error - " _RED_("HID error in Manchester data, size %zu"), size); else - PrintAndLogEx(DEBUG, "DEBUG: Error - " _RED_("HID error demoding fsk %d, idx")); + PrintAndLogEx(DEBUG, "DEBUG: Error - " _RED_("HID error demoding fsk %d"), idx); return PM3_ESOFT; } @@ -248,7 +248,7 @@ static int CmdHIDDemod(const char *Cmd) { } } - PrintAndLogEx(DEBUG, "DEBUG: HID idx: " _GREEN_("%d"), " Len: %zu", Printing Demod Buffer:", idx, size); + PrintAndLogEx(DEBUG, "DEBUG: HID idx: %d, Len: %zu, Printing Demod Buffer: ", idx, size); if (g_debugMode) printDemodBuff(); From 875aaee795d1e5ea6566b7b6d5c5ec6df79b5288 Mon Sep 17 00:00:00 2001 From: Daniel Underhay <27876907+dunderhay@users.noreply.github.com> Date: Sat, 14 Mar 2020 01:58:14 +1100 Subject: [PATCH 1684/1854] Last changes --- client/cmdlfhid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdlfhid.c b/client/cmdlfhid.c index fa3d4878d..ea76d3fd2 100644 --- a/client/cmdlfhid.c +++ b/client/cmdlfhid.c @@ -243,7 +243,7 @@ static int CmdHIDDemod(const char *Cmd) { if (fmtLen == 32 && (lo & 0x40000000)) { //if 32 bit and Kastle bit set PrintAndLogEx(SUCCESS, "HID Prox TAG (Kastle format) ID: " _GREEN_("%x%08x (%u)")"- Format Len: 32bit - CC: %u - FC: %u - Card: %u", hi, lo, (lo >> 1) & 0xFFFF, cc, fc, cardnum); } else { - PrintAndLogEx(SUCCESS, "HID Prox TAG ID: " _GREEN_("%x%08x (%u)")"- Format Len: %ubit - OEM: %03u - FC: %u - Card: %u", + PrintAndLogEx(SUCCESS, "HID Prox TAG ID: " _GREEN_("%x%08x (%u)")"- Format Len: " _GREEN_("%u bit")"- OEM: %03u - FC: " _GREEN_("%u")"- Card: " _GREEN_("%u"), hi, lo, cardnum, fmtLen, oem, fc, cardnum); } } From 78a2a6891f523cbbc113744407cc81f11dbf68f1 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 13 Mar 2020 18:03:48 +0100 Subject: [PATCH 1685/1854] Add PRIx64 for gcc-arm-none-eabi v8 --- armsrc/util.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/armsrc/util.h b/armsrc/util.h index 9748152ef..052ae266c 100644 --- a/armsrc/util.h +++ b/armsrc/util.h @@ -13,6 +13,11 @@ #include "common.h" +// PRIx64 definition missing with gcc-arm-none-eabi v8? +#ifndef PRIx64 + #define PRIx64 "llx" +#endif + // Basic macros #ifndef SHORT_COIL From aa0c2845cbc39fc18ec9b12056d84e341b980580 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 13 Mar 2020 13:15:06 -0400 Subject: [PATCH 1686/1854] more temp fix for PRIx32, PRIu32 : lf_icehid , hf_young --- armsrc/util.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/armsrc/util.h b/armsrc/util.h index 052ae266c..4ae95a5d1 100644 --- a/armsrc/util.h +++ b/armsrc/util.h @@ -17,6 +17,12 @@ #ifndef PRIx64 #define PRIx64 "llx" #endif +#ifndef PRIx32 + #define PRIx32 "lx" +#endif +#ifndef PRIu32 + #define PRIu32 "lu" +#endif // Basic macros From 7ad649130a275a7d3c8eccfabe6dbe888b9a82b3 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 13 Mar 2020 18:18:05 +0100 Subject: [PATCH 1687/1854] fix lf_icehid on gcc v8 --- armsrc/Standalone/lf_icehid.c | 1 + armsrc/util.h | 6 ------ 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/armsrc/Standalone/lf_icehid.c b/armsrc/Standalone/lf_icehid.c index d68f8423d..34d4439a0 100644 --- a/armsrc/Standalone/lf_icehid.c +++ b/armsrc/Standalone/lf_icehid.c @@ -7,6 +7,7 @@ //----------------------------------------------------------------------------- // main code for HID collector aka IceHID by Iceman //----------------------------------------------------------------------------- +#include #include "standalone.h" // standalone definitions #include "proxmark3_arm.h" #include "appmain.h" diff --git a/armsrc/util.h b/armsrc/util.h index 4ae95a5d1..052ae266c 100644 --- a/armsrc/util.h +++ b/armsrc/util.h @@ -17,12 +17,6 @@ #ifndef PRIx64 #define PRIx64 "llx" #endif -#ifndef PRIx32 - #define PRIx32 "lx" -#endif -#ifndef PRIu32 - #define PRIu32 "lu" -#endif // Basic macros From f2a287c6219a810b433c055b7c27d66ac2754913 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 14 Mar 2020 11:04:50 +0100 Subject: [PATCH 1688/1854] maur keys --- client/dictionaries/mfc_default_keys.dic | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index 3001edb61..1e26f948b 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -1076,7 +1076,7 @@ f0f0172066b2 f3864fcca693 f3f0172066b2 fc9839273862 - +# # various hotel keys 34D3C568B348 91FF18E63887 @@ -1084,3 +1084,21 @@ fc9839273862 354A787087F1 4a306e62e9b6 B9C874AE63D0 +# +# Data from offical repo +f00dfeedd0d0 +0bb31dc123e5 +7578bf2c66a9 +cd212889c3ed +6936c035ae1b +c6c866aa421e +590bd659cdd2 +aa734d2f40e0 +09800ff94aaf +5a12f83326e7 +c554ef6a6015 +0d8ca561bdf3 +b8937130b6ba +d7744a1a0c44 +82908b57ef4f +fe04ecfe5577 \ No newline at end of file From 132bd6c1f77bd38f5fbc9c2b9cf9ac914a3fc3c3 Mon Sep 17 00:00:00 2001 From: Daniel Underhay <27876907+dunderhay@users.noreply.github.com> Date: Sun, 15 Mar 2020 19:57:47 +1100 Subject: [PATCH 1689/1854] Add colour to hf 14a and hf mfu commands --- armsrc/lfops.c | 2 +- client/cmdhf14a.c | 39 +++++----- client/cmdhf14b.c | 1 - client/cmdhfmfu.c | 176 ++++++++++++++++++++++++---------------------- client/cmdlfhid.c | 20 +++--- 5 files changed, 124 insertions(+), 114 deletions(-) diff --git a/armsrc/lfops.c b/armsrc/lfops.c index b7b928ff2..84bddc192 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -1291,7 +1291,7 @@ void CmdHIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol) cardnum = (lo >> 1) & 0x7FFFF; fac = ((hi & 0xF) << 12) | (lo >> 20); } - Dbprintf("TAG ID: " _YELLOW_("%x%08x (%d)") "- Format Len: " _YELLOW_("%d") "bit - FC: " _YELLOW_("%d") "- Card: "_YELLOW_("%d"), + Dbprintf("TAG ID: " _GREEN_("%x%08x (%d)") "- Format Len: " _GREEN_("%d") "bit - FC: " _GREEN_("%d") "- Card: "_GREEN_("%d"), hi, lo, (lo >> 1) & 0xFFFF, diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index c611caa1f..6d52f25e7 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -189,9 +189,9 @@ static int usage_hf_14a_sim(void) { PrintAndLogEx(NORMAL, " e : (Optional) Fill simulator keys from found keys"); PrintAndLogEx(NORMAL, " v : (Optional) Verbose"); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf 14a sim t 1 u 11223344 x"); - PrintAndLogEx(NORMAL, " hf 14a sim t 1 u 11223344"); - PrintAndLogEx(NORMAL, " hf 14a sim t 1 u 11223344556677"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf 14a sim t 1 u 11223344 x")); + PrintAndLogEx(NORMAL, _YELLOW_(" hf 14a sim t 1 u 11223344")); + PrintAndLogEx(NORMAL, _YELLOW_(" hf 14a sim t 1 u 11223344556677")); // PrintAndLogEx(NORMAL, " hf 14a sim t 1 u 11223445566778899AA\n"); return 0; } @@ -202,7 +202,7 @@ static int usage_hf_14a_sniff(void) { PrintAndLogEx(NORMAL, "c - triggered by first data from card"); PrintAndLogEx(NORMAL, "r - triggered by first 7-bit request from reader (REQ,WUP,...)"); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf 14a sniff c r"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf 14a sniff c r")); return 0; } static int usage_hf_14a_raw(void) { @@ -261,7 +261,7 @@ int Hf14443_4aGetCardData(iso14a_card_select_t *card) { return 1; } - PrintAndLogEx(SUCCESS, " UID: %s", sprint_hex(card->uid, card->uidlen)); + PrintAndLogEx(SUCCESS, " UID: " _GREEN_("%s"), sprint_hex(card->uid, card->uidlen)); PrintAndLogEx(SUCCESS, "ATQA: %02x %02x", card->atqa[1], card->atqa[0]); PrintAndLogEx(SUCCESS, " SAK: %02x [%" PRIu64 "]", card->sak, resp.oldarg[0]); if (card->ats_len < 3) { // a valid ATS consists of at least the length byte (TL) and 2 CRC bytes @@ -335,17 +335,17 @@ static int CmdHF14AReader(const char *Cmd) { if (select_status == 3) { PrintAndLogEx(INFO, "Card doesn't support standard iso14443-3 anticollision"); - PrintAndLogEx(SUCCESS, "ATQA : %02x %02x", card.atqa[1], card.atqa[0]); + PrintAndLogEx(SUCCESS, "ATQA: %02x %02x", card.atqa[1], card.atqa[0]); DropField(); return 1; } - PrintAndLogEx(SUCCESS, " UID : %s", sprint_hex(card.uid, card.uidlen)); - PrintAndLogEx(SUCCESS, "ATQA : %02x %02x", card.atqa[1], card.atqa[0]); - PrintAndLogEx(SUCCESS, " SAK : %02x [%" PRIu64 "]", card.sak, resp.oldarg[0]); + PrintAndLogEx(SUCCESS, " UID: " _GREEN_("%s"), sprint_hex(card.uid, card.uidlen)); + PrintAndLogEx(SUCCESS, "ATQA: " _GREEN_("%02x %02x"), card.atqa[1], card.atqa[0]); + PrintAndLogEx(SUCCESS, " SAK: " _GREEN_("%02x [%" PRIu64 "]"), card.sak, resp.oldarg[0]); if (card.ats_len >= 3) { // a valid ATS consists of at least the length byte (TL) and 2 CRC bytes - PrintAndLogEx(SUCCESS, " ATS : %s", sprint_hex(card.ats, card.ats_len)); + PrintAndLogEx(SUCCESS, " ATS: " _GREEN_("%s"), sprint_hex(card.ats, card.ats_len)); } if (!disconnectAfter) { @@ -354,7 +354,7 @@ static int CmdHF14AReader(const char *Cmd) { } if (disconnectAfter) { - if (!silent) PrintAndLogEx(SUCCESS, "field dropped."); + if (!silent) PrintAndLogEx(INFO, "field dropped."); } return 0; @@ -467,7 +467,7 @@ int CmdHF14ASim(const char *Cmd) { break; } if (!errors) { - PrintAndLogEx(SUCCESS, "Emulating ISO/IEC 14443 type A tag with %d byte UID (%s)", uidlen, sprint_hex(uid, uidlen)); + PrintAndLogEx(SUCCESS, "Emulating " _YELLOW_("ISO/IEC 14443 type A tag")"with " _GREEN_("%d byte UID (%s)"), uidlen, sprint_hex(uid, uidlen)); useUIDfromEML = false; } cmdp += 2; @@ -485,7 +485,7 @@ int CmdHF14ASim(const char *Cmd) { cmdp++; break; default: - PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + PrintAndLogEx(WARNING, "Unknown parameter " _RED_("'%c'"), param_getchar(Cmd, cmdp)); errors = true; break; } @@ -511,7 +511,7 @@ int CmdHF14ASim(const char *Cmd) { SendCommandNG(CMD_HF_ISO14443A_SIMULATE, (uint8_t *)&payload, sizeof(payload)); PacketResponseNG resp; - PrintAndLogEx(SUCCESS, "press pm3-button to abort simulation"); + PrintAndLogEx(INFO, "Press pm3-button to abort simulation"); bool keypress = kbd_enter_pressed(); while (!keypress) { @@ -1276,14 +1276,14 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { if (select_status == 3) { PrintAndLogEx(INFO, "Card doesn't support standard iso14443-3 anticollision"); - PrintAndLogEx(SUCCESS, "ATQA : %02x %02x", card.atqa[1], card.atqa[0]); + PrintAndLogEx(SUCCESS, "ATQA: %02x %02x", card.atqa[1], card.atqa[0]); DropField(); return select_status; } - PrintAndLogEx(SUCCESS, " UID : %s", sprint_hex(card.uid, card.uidlen)); - PrintAndLogEx(SUCCESS, "ATQA : %02x %02x", card.atqa[1], card.atqa[0]); - PrintAndLogEx(SUCCESS, " SAK : %02x [%" PRIu64 "]", card.sak, resp.oldarg[0]); + PrintAndLogEx(SUCCESS, " UID: " _GREEN_("%s"), sprint_hex(card.uid, card.uidlen)); + PrintAndLogEx(SUCCESS, "ATQA: " _GREEN_("%02x %02x"), card.atqa[1], card.atqa[0]); + PrintAndLogEx(SUCCESS, " SAK: " _GREEN_("%02x [%" PRIu64 "]"), card.sak, resp.oldarg[0]); bool isMifareClassic = true; switch (card.sak) { @@ -1364,7 +1364,7 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { // Double & triple sized UID, can be mapped to a manufacturer. if (card.uidlen > 4) { - PrintAndLogEx(SUCCESS, "MANUFACTURER : %s", getTagInfo(card.uid[0])); + PrintAndLogEx(SUCCESS, "MANUFACTURER: " _GREEN_("%s"), getTagInfo(card.uid[0])); } // try to request ATS even if tag claims not to support it @@ -1608,4 +1608,3 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { return select_status; } - diff --git a/client/cmdhf14b.c b/client/cmdhf14b.c index c57055e4b..859df4a23 100644 --- a/client/cmdhf14b.c +++ b/client/cmdhf14b.c @@ -1142,4 +1142,3 @@ int readHF14B(bool verbose) { if (verbose) PrintAndLogEx(FAILED, "no 14443-B tag found"); return 0; } - diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index 120db2a9c..ccc749708 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -53,9 +53,10 @@ static int usage_hf_mfu_info(void) { PrintAndLogEx(NORMAL, " l : (optional) swap entered key's endianness"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf mfu info"); - PrintAndLogEx(NORMAL, " hf mfu info k 00112233445566778899AABBCCDDEEFF"); - PrintAndLogEx(NORMAL, " hf mfu info k AABBCCDD"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mfu info")); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mfu info k 00112233445566778899AABBCCDDEEFF")); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mfu info k AABBCCDD")); + PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } @@ -73,10 +74,11 @@ static int usage_hf_mfu_dump(void) { PrintAndLogEx(NORMAL, " q : number of Pages to manually set how many pages to dump"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf mfu dump"); - PrintAndLogEx(NORMAL, " hf mfu dump f myfile"); - PrintAndLogEx(NORMAL, " hf mfu dump k 00112233445566778899AABBCCDDEEFF"); - PrintAndLogEx(NORMAL, " hf mfu dump k AABBCCDD\n"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mfu dump")); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mfu dump f myfile")); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mfu dump k 00112233445566778899AABBCCDDEEFF")); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mfu dump k AABBCCDD")); + PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } @@ -92,9 +94,10 @@ static int usage_hf_mfu_restore(void) { PrintAndLogEx(NORMAL, " f : " _YELLOW_("filename w .bin") "to restore"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf mfu restore s f myfile"); - PrintAndLogEx(NORMAL, " hf mfu restore k AABBCCDD s f myfile\n"); - PrintAndLogEx(NORMAL, " hf mfu restore k AABBCCDD s e r f myfile\n"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mfu restore s f myfile")); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mfu restore k AABBCCDD s f myfile")); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mfu restore k AABBCCDD s e r f myfile")); + PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } @@ -107,9 +110,10 @@ static int usage_hf_mfu_rdbl(void) { PrintAndLogEx(NORMAL, " l : (optional) swap entered key's endianness"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf mfu rdbl b 0"); - PrintAndLogEx(NORMAL, " hf mfu rdbl b 0 k 00112233445566778899AABBCCDDEEFF"); - PrintAndLogEx(NORMAL, " hf mfu rdbl b 0 k AABBCCDD\n"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mfu rdbl b 0")); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mfu rdbl b 0 k 00112233445566778899AABBCCDDEEFF")); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mfu rdbl b 0 k AABBCCDD")); + PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } @@ -123,8 +127,9 @@ static int usage_hf_mfu_wrbl(void) { PrintAndLogEx(NORMAL, " l : (optional) swap entered key's endianness"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf mfu wrbl b 0 d 01234567"); - PrintAndLogEx(NORMAL, " hf mfu wrbl b 0 d 01234567 k AABBCCDD\n"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mfu wrbl b 0 d 01234567")); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mfu wrbl b 0 d 01234567 k AABBCCDD")); + PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } @@ -138,8 +143,10 @@ static int usage_hf_mfu_eload(void) { PrintAndLogEx(NORMAL, " [filename] : without `.eml` (required)"); PrintAndLogEx(NORMAL, " numblocks : number of blocks to load from eml file (optional)"); PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, " sample: hf mfu eload u filename"); - PrintAndLogEx(NORMAL, " hf mfu eload u filename 57"); + PrintAndLogEx(NORMAL, "Examples:"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mfu eload u filename")); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mfu eload u filename 57")); + PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } @@ -153,8 +160,9 @@ static int usage_hf_mfu_sim(void) { PrintAndLogEx(NORMAL, " u : 4 or 7 byte UID (optional)"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf mfu sim t 7"); - PrintAndLogEx(NORMAL, " hf mfu sim t 7 u 1122344556677\n"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mfu sim t 7")); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mfu sim t 7 u 1122344556677")); + PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } @@ -168,8 +176,9 @@ static int usage_hf_mfu_ucauth(void) { PrintAndLogEx(NORMAL, " 5 : all 0xff key"); PrintAndLogEx(NORMAL, " 6 : 0x00-0xFF key"); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf mfu cauth k"); - PrintAndLogEx(NORMAL, " hf mfu cauth k 3"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mfu cauth k")); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mfu cauth k 3")); + PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } @@ -179,7 +188,7 @@ static int usage_hf_mfu_ucsetpwd(void) { PrintAndLogEx(NORMAL, " [password] - (32 hex symbols)"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf mfu setpwd 000102030405060708090a0b0c0d0e0f"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mfu setpwd 000102030405060708090a0b0c0d0e0f")); PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } @@ -191,7 +200,7 @@ static int usage_hf_mfu_ucsetuid(void) { PrintAndLogEx(NORMAL, "This only works for " _BLUE_("Magic Ultralight") "tags."); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf mfu setuid 11223344556677"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mfu setuid 11223344556677")); PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } @@ -203,8 +212,8 @@ static int usage_hf_mfu_gendiverse(void) { PrintAndLogEx(NORMAL, " r : read uid from tag"); PrintAndLogEx(NORMAL, " : 4 byte UID (optional)"); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf mfu gen r"); - PrintAndLogEx(NORMAL, " hf mfu gen 11223344"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mfu gen r")); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mfu gen 11223344")); PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } @@ -217,9 +226,9 @@ static int usage_hf_mfu_pwdgen(void) { PrintAndLogEx(NORMAL, " r : read uid from tag"); PrintAndLogEx(NORMAL, " : 7 byte UID (optional)"); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf mfu pwdgen r"); - PrintAndLogEx(NORMAL, " hf mfu pwdgen 11223344556677"); - PrintAndLogEx(NORMAL, " hf mfu pwdgen t"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mfu pwdgen r")); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mfu pwdgen 11223344556677")); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mfu pwdgen t")); PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } @@ -230,7 +239,8 @@ static int usage_hf_mfu_otp_tearoff(void) { PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h : this help"); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf mfu otptear"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mfu otptear")); + PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } @@ -529,43 +539,43 @@ static int ul_print_default(uint8_t *data) { uid[5] = data[6]; uid[6] = data[7]; - PrintAndLogEx(NORMAL, " UID : " _YELLOW_("%s"), sprint_hex(uid, 7)); - PrintAndLogEx(NORMAL, " UID[0] : %02X, %s", uid[0], getTagInfo(uid[0])); + PrintAndLogEx(SUCCESS, " UID: " _GREEN_("%s"), sprint_hex(uid, 7)); + PrintAndLogEx(SUCCESS, " UID[0]: %02X, %s", uid[0], getTagInfo(uid[0])); if (uid[0] == 0x05 && ((uid[1] & 0xf0) >> 4) == 2) { // is infineon and 66RxxP uint8_t chip = (data[8] & 0xC7); // 11000111 mask, bit 3,4,5 RFU switch (chip) { case 0xC2: - PrintAndLogEx(NORMAL, " IC type : SLE 66R04P 770 Bytes"); + PrintAndLogEx(SUCCESS, " IC type: SLE 66R04P 770 Bytes"); break; //77 pages case 0xC4: - PrintAndLogEx(NORMAL, " IC type : SLE 66R16P 2560 Bytes"); + PrintAndLogEx(SUCCESS, " IC type: SLE 66R16P 2560 Bytes"); break; //256 pages case 0xC6: - PrintAndLogEx(NORMAL, " IC type : SLE 66R32P 5120 Bytes"); + PrintAndLogEx(SUCCESS, " IC type: SLE 66R32P 5120 Bytes"); break; //512 pages /2 sectors } } // CT (cascade tag byte) 0x88 xor SN0 xor SN1 xor SN2 int crc0 = 0x88 ^ uid[0] ^ uid[1] ^ uid[2]; if (data[3] == crc0) - PrintAndLogEx(NORMAL, " BCC0 : %02X ( " _GREEN_("ok") ")", data[3]); + PrintAndLogEx(SUCCESS, " BCC0: %02X ( " _GREEN_("ok") ")", data[3]); else - PrintAndLogEx(NORMAL, " BCC0 : %02X, crc should be %02X", data[3], crc0); + PrintAndLogEx(NORMAL, " BCC0: %02X, crc should be %02X", data[3], crc0); int crc1 = uid[3] ^ uid[4] ^ uid[5] ^ uid[6]; if (data[8] == crc1) - PrintAndLogEx(NORMAL, " BCC1 : %02X ( " _GREEN_("ok") ")", data[8]); + PrintAndLogEx(SUCCESS, " BCC1: %02X ( " _GREEN_("ok") ")", data[8]); else - PrintAndLogEx(NORMAL, " BCC1 : %02X, crc should be %02X", data[8], crc1); + PrintAndLogEx(NORMAL, " BCC1: %02X, crc should be %02X", data[8], crc1); - PrintAndLogEx(NORMAL, " Internal : %02X ( %s)", data[9], (data[9] == 0x48) ? _GREEN_("default") : _RED_("not default") ); + PrintAndLogEx(SUCCESS, " Internal: %02X ( %s)", data[9], (data[9] == 0x48) ? _GREEN_("default") : _RED_("not default") ); - PrintAndLogEx(NORMAL, " Lock : %s - %s", + PrintAndLogEx(SUCCESS, " Lock: %s - %s", sprint_hex(data + 10, 2), sprint_bin(data + 10, 2) ); - PrintAndLogEx(NORMAL, "OneTimePad : %s - %s\n", + PrintAndLogEx(SUCCESS, "OneTimePad : %s - %s\n", sprint_hex(data + 12, 4), sprint_bin(data + 12, 4) ); @@ -669,57 +679,57 @@ int ul_print_type(uint32_t tagtype, uint8_t spaces) { char *spacer = spc + (10 - spaces); if (tagtype & UL) - PrintAndLogEx(NORMAL, "%sTYPE : MIFARE Ultralight (MF0ICU1) %s", spacer, (tagtype & MAGIC) ? "" : ""); + PrintAndLogEx(SUCCESS, "%sTYPE: " _GREEN_("MIFARE Ultralight (MF0ICU1) %s"), spacer, (tagtype & MAGIC) ? "" : ""); else if (tagtype & UL_C) - PrintAndLogEx(NORMAL, "%sTYPE : MIFARE Ultralight C (MF0ULC) %s", spacer, (tagtype & MAGIC) ? "" : ""); + PrintAndLogEx(SUCCESS, "%sTYPE: " _GREEN_("MIFARE Ultralight C (MF0ULC) %s"), spacer, (tagtype & MAGIC) ? "" : ""); else if (tagtype & UL_NANO_40) - PrintAndLogEx(NORMAL, "%sTYPE : MIFARE Ultralight Nano 40bytes (MF0UNH00)", spacer); + PrintAndLogEx(SUCCESS, "%sTYPE: " _GREEN_("MIFARE Ultralight Nano 40bytes (MF0UNH00)"), spacer); else if (tagtype & UL_EV1_48) - PrintAndLogEx(NORMAL, "%sTYPE : MIFARE Ultralight EV1 48bytes (MF0UL1101)", spacer); + PrintAndLogEx(SUCCESS, "%sTYPE: " _GREEN_("MIFARE Ultralight EV1 48bytes (MF0UL1101)"), spacer); else if (tagtype & UL_EV1_128) - PrintAndLogEx(NORMAL, "%sTYPE : MIFARE Ultralight EV1 128bytes (MF0UL2101)", spacer); + PrintAndLogEx(SUCCESS, "%sTYPE: " _GREEN_("MIFARE Ultralight EV1 128bytes (MF0UL2101)"), spacer); else if (tagtype & UL_EV1) - PrintAndLogEx(NORMAL, "%sTYPE : MIFARE Ultralight EV1 UNKNOWN", spacer); + PrintAndLogEx(NORMAL, "%sTYPE: " _YELLOW_("MIFARE Ultralight EV1 UNKNOWN"), spacer); else if (tagtype & NTAG) - PrintAndLogEx(NORMAL, "%sTYPE : NTAG UNKNOWN", spacer); + PrintAndLogEx(NORMAL, "%sTYPE: " _YELLOW_("NTAG UNKNOWN"), spacer); else if (tagtype & NTAG_203) - PrintAndLogEx(NORMAL, "%sTYPE : NTAG 203 144bytes (NT2H0301F0DT)", spacer); + PrintAndLogEx(SUCCESS, "%sTYPE: " _GREEN_("NTAG 203 144bytes (NT2H0301F0DT)"), spacer); else if (tagtype & NTAG_210) - PrintAndLogEx(NORMAL, "%sTYPE : NTAG 210 48bytes (NT2L1011G0DU)", spacer); + PrintAndLogEx(SUCCESS, "%sTYPE: " _GREEN_("NTAG 210 48bytes (NT2L1011G0DU)"), spacer); else if (tagtype & NTAG_212) - PrintAndLogEx(NORMAL, "%sTYPE : NTAG 212 128bytes (NT2L1211G0DU)", spacer); + PrintAndLogEx(SUCCESS, "%sTYPE: " _GREEN_("NTAG 212 128bytes (NT2L1211G0DU)"), spacer); else if (tagtype & NTAG_213) - PrintAndLogEx(NORMAL, "%sTYPE : NTAG 213 144bytes (NT2H1311G0DU)", spacer); + PrintAndLogEx(SUCCESS, "%sTYPE: " _GREEN_("NTAG 213 144bytes (NT2H1311G0DU)"), spacer); else if (tagtype & NTAG_213_F) - PrintAndLogEx(NORMAL, "%sTYPE : NTAG 213F 144bytes (NT2H1311F0DTL)", spacer); + PrintAndLogEx(SUCCESS, "%sTYPE: " _GREEN_("NTAG 213F 144bytes (NT2H1311F0DTL)"), spacer); else if (tagtype & NTAG_215) - PrintAndLogEx(NORMAL, "%sTYPE : NTAG 215 504bytes (NT2H1511G0DU)", spacer); + PrintAndLogEx(SUCCESS, "%sTYPE: " _GREEN_("NTAG 215 504bytes (NT2H1511G0DU)"), spacer); else if (tagtype & NTAG_216) - PrintAndLogEx(NORMAL, "%sTYPE : NTAG 216 888bytes (NT2H1611G0DU)", spacer); + PrintAndLogEx(SUCCESS, "%sTYPE: " _GREEN_("NTAG 216 888bytes (NT2H1611G0DU)"), spacer); else if (tagtype & NTAG_216_F) - PrintAndLogEx(NORMAL, "%sTYPE : NTAG 216F 888bytes (NT2H1611F0DTL)", spacer); + PrintAndLogEx(SUCCESS, "%sTYPE: " _GREEN_("NTAG 216F 888bytes (NT2H1611F0DTL)"), spacer); else if (tagtype & NTAG_I2C_1K) - PrintAndLogEx(NORMAL, "%sTYPE : NTAG I2C 888bytes (NT3H1101FHK)", spacer); + PrintAndLogEx(SUCCESS, "%sTYPE: " _GREEN_("NTAG I2C 888bytes (NT3H1101FHK)"), spacer); else if (tagtype & NTAG_I2C_2K) - PrintAndLogEx(NORMAL, "%sTYPE : NTAG I2C 1904bytes (NT3H1201FHK)", spacer); + PrintAndLogEx(SUCCESS, "%sTYPE: " _GREEN_("NTAG I2C 1904bytes (NT3H1201FHK)"), spacer); else if (tagtype & NTAG_I2C_1K_PLUS) - PrintAndLogEx(NORMAL, "%sTYPE : NTAG I2C plus 888bytes (NT3H2111FHK)", spacer); + PrintAndLogEx(SUCCESS, "%sTYPE: " _GREEN_("NTAG I2C plus 888bytes (NT3H2111FHK)"), spacer); else if (tagtype & NTAG_I2C_2K_PLUS) - PrintAndLogEx(NORMAL, "%sTYPE : NTAG I2C plus 1912bytes (NT3H2211FHK)", spacer); + PrintAndLogEx(SUCCESS, "%sTYPE: " _GREEN_("NTAG I2C plus 1912bytes (NT3H2211FHK)"), spacer); else if (tagtype & MY_D) - PrintAndLogEx(NORMAL, "%sTYPE : INFINEON my-d\x99 (SLE 66RxxS)", spacer); + PrintAndLogEx(SUCCESS, "%sTYPE: " _GREEN_("INFINEON my-d\x99 (SLE 66RxxS)"), spacer); else if (tagtype & MY_D_NFC) - PrintAndLogEx(NORMAL, "%sTYPE : INFINEON my-d\x99 NFC (SLE 66RxxP)", spacer); + PrintAndLogEx(SUCCESS, "%sTYPE: " _GREEN_("INFINEON my-d\x99 NFC (SLE 66RxxP)"), spacer); else if (tagtype & MY_D_MOVE) - PrintAndLogEx(NORMAL, "%sTYPE : INFINEON my-d\x99 move (SLE 66R01P)", spacer); + PrintAndLogEx(SUCCESS, "%sTYPE: " _GREEN_("INFINEON my-d\x99 move (SLE 66R01P)"), spacer); else if (tagtype & MY_D_MOVE_NFC) - PrintAndLogEx(NORMAL, "%sTYPE : INFINEON my-d\x99 move NFC (SLE 66R01P)", spacer); + PrintAndLogEx(SUCCESS, "%sTYPE: " _GREEN_("INFINEON my-d\x99 move NFC (SLE 66R01P)"), spacer); else if (tagtype & MY_D_MOVE_LEAN) - PrintAndLogEx(NORMAL, "%sTYPE : INFINEON my-d\x99 move lean (SLE 66R01L)", spacer); + PrintAndLogEx(SUCCESS, "%sTYPE: " _GREEN_("INFINEON my-d\x99 move lean (SLE 66R01L)"), spacer); else if (tagtype & FUDAN_UL) - PrintAndLogEx(NORMAL, "%sTYPE : FUDAN Ultralight Compatible (or other compatible) %s", spacer, (tagtype & MAGIC) ? "" : ""); + PrintAndLogEx(SUCCESS, "%sTYPE: " _GREEN_("FUDAN Ultralight Compatible (or other compatible) %s"), spacer, (tagtype & MAGIC) ? "" : ""); else - PrintAndLogEx(NORMAL, "%sTYPE : Unknown %06x", spacer, tagtype); + PrintAndLogEx(NORMAL, "%sTYPE: " _YELLOW_("Unknown %06x"), spacer, tagtype); return PM3_SUCCESS; } @@ -896,14 +906,14 @@ static int ulev1_print_signature(TagTypeUL_t tagtype, uint8_t *uid, uint8_t *sig static int ulev1_print_version(uint8_t *data) { PrintAndLogEx(NORMAL, "\n--- Tag Version"); - PrintAndLogEx(NORMAL, " Raw bytes : %s", sprint_hex(data, 8)); - PrintAndLogEx(NORMAL, " Vendor ID : %02X, %s", data[1], getTagInfo(data[1])); - PrintAndLogEx(NORMAL, " Product type : %s", getProductTypeStr(data[2])); - PrintAndLogEx(NORMAL, " Product subtype : %02X, %s", data[3], (data[3] == 1) ? "17 pF" : "50pF"); - PrintAndLogEx(NORMAL, " Major version : %02X", data[4]); - PrintAndLogEx(NORMAL, " Minor version : %02X", data[5]); - PrintAndLogEx(NORMAL, " Size : %s", getUlev1CardSizeStr(data[6])); - PrintAndLogEx(NORMAL, " Protocol type : %02X %s", data[7], (data[7] == 0x3) ? "(ISO14443-3 Compliant)" : ""); + PrintAndLogEx(NORMAL, " Raw bytes: %s", sprint_hex(data, 8)); + PrintAndLogEx(NORMAL, " Vendor ID: %02X, %s", data[1], getTagInfo(data[1])); + PrintAndLogEx(NORMAL, " Product type: %s", getProductTypeStr(data[2])); + PrintAndLogEx(NORMAL, " Product subtype: %02X, %s", data[3], (data[3] == 1) ? "17 pF" : "50pF"); + PrintAndLogEx(NORMAL, " Major version: %02X", data[4]); + PrintAndLogEx(NORMAL, " Minor version: %02X", data[5]); + PrintAndLogEx(NORMAL, " Size: %s", getUlev1CardSizeStr(data[6])); + PrintAndLogEx(NORMAL, " Protocol type: %02X %s", data[7], (data[7] == 0x3) ? "(ISO14443-3 Compliant)" : ""); return PM3_SUCCESS; } @@ -1112,7 +1122,7 @@ static int CmdHF14AMfUInfo(const char *Cmd) { cmdp++; break; default: - PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + PrintAndLogEx(WARNING, "Unknown parameter: " _RED_("'%c'"), param_getchar(Cmd, cmdp)); errors = true; break; } @@ -1273,7 +1283,8 @@ static int CmdHF14AMfUInfo(const char *Cmd) { // 1-7 = limit. No automatic tries then. // hasAuthKey, if we was called with key, skip test. if (!authlim && !hasAuthKey) { - PrintAndLogEx(NORMAL, "\n--- Known EV1/NTAG passwords."); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(SUCCESS, _GREEN_("--- Known EV1/NTAG passwords ---")); // test pwd gen A num_to_bytes(ul_ev1_pwdgenA(card.uid), 4, key); len = ulev1_requestAuthentication(key, pack, sizeof(pack)); @@ -1324,7 +1335,7 @@ static int CmdHF14AMfUInfo(const char *Cmd) { if (ul_auth_select(&card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack)) == PM3_ESOFT) return PM3_ESOFT; } } - if (len < 1) PrintAndLogEx(WARNING, "password not known"); + if (len < 1) PrintAndLogEx(WARNING, _YELLOW_("password not known")); } } out: @@ -1397,7 +1408,7 @@ static int CmdHF14AMfUWrBl(const char *Cmd) { cmdp += 2; break; default: - PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + PrintAndLogEx(WARNING, "Unknown parameter: " _RED_("'%c'"), param_getchar(Cmd, cmdp)); errors = true; break; } @@ -1511,7 +1522,7 @@ static int CmdHF14AMfURdBl(const char *Cmd) { cmdp++; break; default: - PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + PrintAndLogEx(WARNING, "Unknown parameter: " _RED_("'%c'"), param_getchar(Cmd, cmdp)); errors = true; break; } @@ -1781,7 +1792,7 @@ static int CmdHF14AMfUDump(const char *Cmd) { manualPages = true; break; default: - PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + PrintAndLogEx(WARNING, "Unknown parameter: " _RED_("'%c'"), param_getchar(Cmd, cmdp)); errors = true; break; } @@ -2022,7 +2033,7 @@ static int CmdHF14AMfURestore(const char *Cmd) { read_key = true; break; default: - PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + PrintAndLogEx(WARNING, "Unknown parameter: " _RED_("'%c'"), param_getchar(Cmd, cmdp)); errors = true; break; } @@ -2673,4 +2684,3 @@ int CmdHFMFUltra(const char *Cmd) { clearCommandBuffer(); return CmdsParse(CommandTable, Cmd); } - diff --git a/client/cmdlfhid.c b/client/cmdlfhid.c index ea76d3fd2..b5d449623 100644 --- a/client/cmdlfhid.c +++ b/client/cmdlfhid.c @@ -50,7 +50,7 @@ static int usage_lf_hid_watch(void) { PrintAndLogEx(NORMAL, "Usage: lf hid watch"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " lf hid watch"); + PrintAndLogEx(NORMAL, _YELLOW_(" lf hid watch")); return PM3_SUCCESS; } static int usage_lf_hid_sim(void) { @@ -62,11 +62,11 @@ static int usage_lf_hid_sim(void) { PrintAndLogEx(NORMAL, " h - This help"); PrintAndLogEx(NORMAL, " ID - HID id"); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " lf hid sim 2006ec0c86"); + PrintAndLogEx(NORMAL, _YELLOW_(" lf hid sim 2006ec0c86")); return PM3_SUCCESS; } static int usage_lf_hid_clone(void) { - PrintAndLogEx(NORMAL, "Clone HID to T55x7. Tag must be on antenna. "); + PrintAndLogEx(NORMAL, "Clone HID to T55x7. " _BLUE_("Tag must be on antenna!")); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Usage: lf hid clone [h] [l] ID"); PrintAndLogEx(NORMAL, "Options:"); @@ -74,8 +74,8 @@ static int usage_lf_hid_clone(void) { PrintAndLogEx(NORMAL, " l - 84bit ID"); PrintAndLogEx(NORMAL, " ID - HID id"); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " lf hid clone 2006ec0c86"); - PrintAndLogEx(NORMAL, " lf hid clone l 2006ec0c86"); + PrintAndLogEx(NORMAL, _YELLOW_(" lf hid clone 2006ec0c86")); + PrintAndLogEx(NORMAL, _YELLOW_(" lf hid clone l 2006ec0c86")); return PM3_SUCCESS; } static int usage_lf_hid_brute(void) { @@ -97,9 +97,9 @@ static int usage_lf_hid_brute(void) { PrintAndLogEx(NORMAL, " down : direction to decrement card number. (default is both directions)"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " lf hid brute w H10301 f 224"); - PrintAndLogEx(NORMAL, " lf hid brute w H10301 f 21 d 2000"); - PrintAndLogEx(NORMAL, " lf hid brute v w H10301 f 21 c 200 d 2000"); + PrintAndLogEx(NORMAL, _YELLOW_(" lf hid brute w H10301 f 224")); + PrintAndLogEx(NORMAL, _YELLOW_(" lf hid brute w H10301 f 21 d 2000")); + PrintAndLogEx(NORMAL, _YELLOW_(" lf hid brute v w H10301 f 21 c 200 d 2000")); return PM3_SUCCESS; } @@ -268,6 +268,8 @@ static int CmdHIDWatch(const char *Cmd) { if (ctmp == 'h') return usage_lf_hid_watch(); clearCommandBuffer(); SendCommandNG(CMD_LF_HID_DEMOD, NULL, 0); + PrintAndLogEx(SUCCESS, "Watching for new HID cards - place tag on antenna"); + PrintAndLogEx(INFO, "Press pm3-button to stop reading new cards"); return PM3_SUCCESS; } @@ -299,7 +301,7 @@ static int CmdHIDSim(const char *Cmd) { hi2 = 0; } - PrintAndLogEx(SUCCESS, "Press pm3-button to abort simulation"); + PrintAndLogEx(INFO, "Press pm3-button to abort simulation"); payload.hi2 = hi2; payload.hi = hi; From 367334750c5a442db1ada4655bd33766c57dab0d Mon Sep 17 00:00:00 2001 From: Daniel Underhay <27876907+dunderhay@users.noreply.github.com> Date: Sun, 15 Mar 2020 19:59:16 +1100 Subject: [PATCH 1690/1854] Add colour lf hid, hf 14a and hf mfu command output --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f84700e6..be95a700d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,8 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] - - Add colour to `lf hid` commands in cmdlfhid.c + - Add colour to `hf 14a` and `hf mfu` commands (@dunderhay) + - Add colour to `lf hid` commands (@dunderhay) - Change `script run hf_bruteforce -s start_id -e end_id -t timeout -x mifare_card_type` - The hf_bruteforce card script now requires Mifare type (mfc or mfu) (@dunderhay) - Updated `hf_bruteforce.lua` script - added support for brute forcing Mifare Ultralight EV1 cards (@dunderhay) - Added `hf mf personlize` - personalize the UID of a Mifare Classic EV1 card (@pwpiwi) From 6172eccefd87f6450561df23d0237a8ac90042ee Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 15 Mar 2020 11:03:23 +0100 Subject: [PATCH 1691/1854] chg: hf 14a info - some hint texts added and static nonce text changed. --- client/cmdhf14a.c | 52 ++++++++++++++++++++++++++++++-------- client/mifare/mifarehost.c | 2 ++ 2 files changed, 44 insertions(+), 10 deletions(-) diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index 6d52f25e7..389c16fe5 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -230,7 +230,6 @@ static int usage_hf_14a_reader(void) { static int CmdHF14AList(const char *Cmd) { (void)Cmd; // Cmd is not used so far - //PrintAndLogEx(NORMAL, "Deprecated command, use 'hf list 14a' instead"); CmdTraceList("14a"); return 0; } @@ -361,7 +360,7 @@ static int CmdHF14AReader(const char *Cmd) { } static int CmdHF14AInfo(const char *Cmd) { - bool verbose = false; + bool verbose = true; bool do_nack_test = false; bool do_aid_search = false; @@ -1281,11 +1280,19 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { return select_status; } + if (verbose) { + PrintAndLogEx(SUCCESS, "-- ISO14443-a Information -----------------------------------"); + PrintAndLogEx(SUCCESS, "-------------------------------------------------------------"); + } PrintAndLogEx(SUCCESS, " UID: " _GREEN_("%s"), sprint_hex(card.uid, card.uidlen)); PrintAndLogEx(SUCCESS, "ATQA: " _GREEN_("%02x %02x"), card.atqa[1], card.atqa[0]); PrintAndLogEx(SUCCESS, " SAK: " _GREEN_("%02x [%" PRIu64 "]"), card.sak, resp.oldarg[0]); bool isMifareClassic = true; + bool isMifareDesfire = false; + bool isMifarePlus = false; + bool isMifareUltralight = false; + switch (card.sak) { case 0x00: isMifareClassic = false; @@ -1294,10 +1301,12 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { DropField(); uint32_t tagT = GetHF14AMfU_Type(); - if (tagT != UL_ERROR) + if (tagT != UL_ERROR) { ul_print_type(tagT, 0); - else + isMifareUltralight = true; + } else { PrintAndLogEx(SUCCESS, "TYPE: Possible AZTEK (iso14443a compliant)"); + } // reconnect for further tests clearCommandBuffer(); @@ -1319,6 +1328,7 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { case 0x04: PrintAndLogEx(SUCCESS, "TYPE : NXP MIFARE (various !DESFire !DESFire EV1)"); isMifareClassic = false; + isMifareDesfire = true; break; case 0x08: PrintAndLogEx(SUCCESS, "TYPE : NXP MIFARE CLASSIC 1k | Plus 2k SL1 | 1k Ev1"); @@ -1331,9 +1341,11 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { break; case 0x10: PrintAndLogEx(SUCCESS, "TYPE : NXP MIFARE Plus 2k SL2"); + isMifarePlus = true; break; case 0x11: PrintAndLogEx(SUCCESS, "TYPE : NXP MIFARE Plus 4k SL2"); + isMifarePlus = true; break; case 0x18: PrintAndLogEx(SUCCESS, "TYPE : NXP MIFARE Classic 4k | Plus 4k SL1 | 4k Ev1"); @@ -1341,10 +1353,13 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { case 0x20: PrintAndLogEx(SUCCESS, "TYPE : NXP MIFARE DESFire 4k | DESFire EV1 2k/4k/8k | Plus 2k/4k SL3 | JCOP 31/41"); isMifareClassic = false; + isMifareDesfire = true; + isMifarePlus = true; break; case 0x24: PrintAndLogEx(SUCCESS, "TYPE : NXP MIFARE DESFire | DESFire EV1"); isMifareClassic = false; + isMifareDesfire = true; break; case 0x28: PrintAndLogEx(SUCCESS, "TYPE : JCOP31 or JCOP41 v2.3.1"); @@ -1461,9 +1476,15 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { switch (card.ats[pos + 2] & 0xf0) { case 0x10: PrintAndLogEx(SUCCESS, " 1x -> MIFARE DESFire"); + isMifareDesfire = true; + isMifareClassic = false; + isMifarePlus = false; break; case 0x20: PrintAndLogEx(SUCCESS, " 2x -> MIFARE Plus"); + isMifarePlus = true; + isMifareDesfire = false; + isMifareClassic = false; break; } switch (card.ats[pos + 2] & 0x0f) { @@ -1590,21 +1611,32 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { if (isMifareClassic) { int res = detect_classic_prng(); if (res == 1) - PrintAndLogEx(SUCCESS, "Prng detection: " _GREEN_("WEAK")); + PrintAndLogEx(SUCCESS, "Prng detection: " _GREEN_("weak")); else if (res == 0) - PrintAndLogEx(SUCCESS, "Prng detection: " _YELLOW_("HARD")); + PrintAndLogEx(SUCCESS, "Prng detection: " _YELLOW_("hard")); else - PrintAndLogEx(FAILED, "prng detection: " _RED_("Fail")); + PrintAndLogEx(FAILED, "prng detection: " _RED_("fail")); if (do_nack_test) - detect_classic_nackbug(!verbose); + detect_classic_nackbug(false); res = detect_classic_static_nonce(); if (res == 1) - PrintAndLogEx(SUCCESS, "Static nonce detected"); + PrintAndLogEx(SUCCESS, "Static nonce: " _YELLOW_("yes") ); if (res == 2 && verbose) - PrintAndLogEx(SUCCESS, "Static nonce detection failed"); + PrintAndLogEx(SUCCESS, "Static nonce: " _RED_("fail")); } + + if (isMifareUltralight) { + PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`hf mfu info`")); + } + if (isMifarePlus) { + PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`hf mfp info`")); + } + if (isMifareDesfire) { + PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`hf mfdes info`")); + } + return select_status; } diff --git a/client/mifare/mifarehost.c b/client/mifare/mifarehost.c index b5d1cb267..e4e1832b5 100644 --- a/client/mifare/mifarehost.c +++ b/client/mifare/mifarehost.c @@ -1316,6 +1316,8 @@ int detect_classic_nackbug(bool verbose) { SendCommandNG(CMD_HF_MIFARE_NACK_DETECT, NULL, 0); PacketResponseNG resp; + PrintAndLogEx(INFO, "Checking for NACK bug"); + if (verbose) PrintAndLogEx(SUCCESS, "press pm3-button on the Proxmark3 device to abort both Proxmark3 and client.\n"); From 945e508e234d3772458ea50590af353005236a47 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 15 Mar 2020 11:51:09 +0100 Subject: [PATCH 1692/1854] new command: hints h - will set hint messages on / off. default mode is OFF. Hint texts makes its easier for beginners but adds text to anyone who knows the pm3 client --- CHANGELOG.md | 1 + client/cmdhf14a.c | 6 +-- client/cmdmain.c | 106 +++++++++++++++++++++++++++++++++++++++++++++- client/proxgui.h | 2 +- client/ui.c | 5 +++ client/ui.h | 2 +- 6 files changed, 116 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index be95a700d..0fa346660 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Add 'HINTS' command. Will turn off / on hint messages. Default mode is OFF. (@iceman1001) - Add colour to `hf 14a` and `hf mfu` commands (@dunderhay) - Add colour to `lf hid` commands (@dunderhay) - Change `script run hf_bruteforce -s start_id -e end_id -t timeout -x mifare_card_type` - The hf_bruteforce card script now requires Mifare type (mfc or mfu) (@dunderhay) diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index 389c16fe5..0355abe85 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -1628,13 +1628,13 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { } if (isMifareUltralight) { - PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`hf mfu info`")); + PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`hf mfu info`")); } if (isMifarePlus) { - PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`hf mfp info`")); + PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`hf mfp info`")); } if (isMifareDesfire) { - PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`hf mfdes info`")); + PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`hf mfdes info`")); } diff --git a/client/cmdmain.c b/client/cmdmain.c index c2364d8f1..d9cbbac74 100644 --- a/client/cmdmain.c +++ b/client/cmdmain.c @@ -36,9 +36,23 @@ #include "cmdwiegand.h" // wiegand commands #include "ui.h" #include "util_posix.h" +#include "commonutil.h" // ARRAYLEN static int CmdHelp(const char *Cmd); +static int usage_hints(void) { + PrintAndLogEx(NORMAL, "Turn on/off hints"); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Usage: hints [h] <0|1>"); + PrintAndLogEx(NORMAL, "Options:"); + PrintAndLogEx(NORMAL, " h This help"); + PrintAndLogEx(NORMAL, " <0|1> off or on"); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Examples:"); + PrintAndLogEx(NORMAL, " hints 1"); + return PM3_SUCCESS; +} + static int usage_msleep(void) { PrintAndLogEx(NORMAL, "Sleep for given amount of milliseconds"); PrintAndLogEx(NORMAL, ""); @@ -78,6 +92,70 @@ static void AppendDate(char *s, size_t slen, char *fmt) { strftime(s, slen, fmt, ct); } +static int lf_search_plus(const char *Cmd) { + + sample_config oldconfig; + memset(&oldconfig, 0, sizeof(sample_config)); + + int retval = lf_getconfig(&oldconfig); + + if (retval != PM3_SUCCESS) { + PrintAndLogEx(ERR, "failed to get current device config"); + return retval; + } + + // Divisor : frequency(khz) + // 95 88 47 31 23 + // 125.00 134.83 250.00 375.00 500.00 + + int16_t default_divisor[] = {95, 88, 47, 31, 23}; + + /* + default LF config is set to: + decimation = 1 + bits_per_sample = 8 + averaging = YES + divisor = 95 (125kHz) + trigger_threshold = 0 + samples_to_skip = 0 + verbose = YES + */ + sample_config config = { + .decimation = 1, + .bits_per_sample = 8, + .averaging = 1, + .trigger_threshold = 0, + .samples_to_skip = 0, + .verbose = false + }; + + // Iteration defaults + for (int i = 0; i < ARRAYLEN(default_divisor); ++i) { + + if (kbd_enter_pressed()) { + PrintAndLogEx(INFO, "Keyboard pressed. Done."); + break; + } + // Try to change config! + uint32_t d; + d = config.divisor = default_divisor[i]; + PrintAndLogEx(INFO, "--> trying ( " _GREEN_("%d.%02d kHz")")", 12000 / (d + 1), ((1200000 + (d + 1) / 2) / (d + 1)) - ((12000 / (d + 1)) * 100)); + + retval = lf_config(&config); + if (retval != PM3_SUCCESS) + break; + + // The config for pm3 is changed, we can trying search! + retval = CmdLFfind(Cmd); + if (retval == PM3_SUCCESS) + break; + + } + + lf_config(&oldconfig); + return retval; +} + static int CmdAuto(const char *Cmd) { char ctmp = tolower(param_getchar(Cmd, 0)); if (ctmp == 'h') return usage_auto(); @@ -90,8 +168,12 @@ static int CmdAuto(const char *Cmd) { if (ret == PM3_SUCCESS) return ret; + ret = lf_search_plus(""); + if (ret == PM3_SUCCESS) + return ret; + PrintAndLogEx(INFO, "Failed both LF / HF SEARCH,"); - PrintAndLogEx(INFO, "Trying 'lf read' and save a trace for you..."); + PrintAndLogEx(INFO, "Trying " _YELLOW_("`lf read`") "and save a trace for you"); CmdPlot(""); lf_read(false, 40000); @@ -109,6 +191,27 @@ int CmdRem(const char *Cmd) { return PM3_SUCCESS; } +static int CmdHints(const char *Cmd) { + uint32_t ms = 0; + char ctmp = tolower(param_getchar(Cmd, 0)); + if (ctmp == 'h') return usage_hints(); + + if (strlen(Cmd) < 1) { + PrintAndLogEx(INFO, "Hints are %s", (g_showhints) ? "ON" : "OFF"); + return PM3_SUCCESS; + } + + if (param_getchar(Cmd, 0) != 0x00) { + ms = param_get32ex(Cmd, 0, 0, 10); + if (ms == 0) + g_showhints = false; + else + g_showhints = true; + } + PrintAndLogEx(INFO, "Hints are %s", (g_showhints) ? "ON" : "OFF"); + return PM3_SUCCESS; +} + static int CmdMsleep(const char *Cmd) { uint32_t ms = 0; char ctmp = tolower(param_getchar(Cmd, 0)); @@ -149,6 +252,7 @@ static command_t CommandTable[] = { {"usart", CmdUsart, IfPm3FpcUsartFromUsb, "{ USART commands... }"}, {"wiegand", CmdWiegand, AlwaysAvailable, "{ Wiegand format manipulation... }"}, {"", CmdHelp, AlwaysAvailable, ""}, + {"hints", CmdHints, AlwaysAvailable, "Turn hints on / off"}, {"msleep", CmdMsleep, AlwaysAvailable, "Add a pause in milliseconds"}, {"rem", CmdRem, AlwaysAvailable, "Add a text line in log file"}, {"quit", CmdQuit, AlwaysAvailable, ""}, diff --git a/client/proxgui.h b/client/proxgui.h index 8e0868b12..fea28d62b 100644 --- a/client/proxgui.h +++ b/client/proxgui.h @@ -55,7 +55,7 @@ extern size_t DemodBufferLen; extern size_t g_DemodStartIdx; extern bool showDemod; extern uint8_t g_debugMode; - +extern uint8_t g_showhints; #ifndef FILE_PATH_SIZE #define FILE_PATH_SIZE 1000 diff --git a/client/ui.c b/client/ui.c index 215bd66bc..91a2a49e6 100644 --- a/client/ui.c +++ b/client/ui.c @@ -127,6 +127,10 @@ void PrintAndLogEx(logLevel_t level, const char *fmt, ...) { // skip debug messages if client debugging is turned off i.e. 'DATA SETDEBUG 0' if (g_debugMode == 0 && level == DEBUG) return; + + // skip HINT messages if client has hints turned off i.e. 'HINT 0' + if (g_showhints == 0 && level == HINT) + return; char prefix[20] = {0}; char buffer[MAX_PRINT_BUFFER] = {0}; @@ -146,6 +150,7 @@ void PrintAndLogEx(logLevel_t level, const char *fmt, ...) { case DEBUG: strncpy(prefix, _BLUE_("[#]"), sizeof(prefix) - 1); break; + case HINT: case SUCCESS: strncpy(prefix, _GREEN_("[+]"), sizeof(prefix) - 1); break; diff --git a/client/ui.h b/client/ui.h index 7e00ab52b..c67865593 100644 --- a/client/ui.h +++ b/client/ui.h @@ -31,7 +31,7 @@ extern session_arg_t session; #define M_PI 3.14159265358979323846264338327 #endif #define MAX_PRINT_BUFFER 2048 -typedef enum logLevel {NORMAL, SUCCESS, INFO, FAILED, WARNING, ERR, DEBUG, INPLACE} logLevel_t; +typedef enum logLevel {NORMAL, SUCCESS, INFO, FAILED, WARNING, ERR, DEBUG, INPLACE, HINT} logLevel_t; void ShowGui(void); void HideGraphWindow(void); From 64ee9885d0c13598baf3a401d9f57ceb1c2a1dcc Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 15 Mar 2020 11:51:26 +0100 Subject: [PATCH 1693/1854] nack text --- client/mifare/mifarehost.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/mifare/mifarehost.c b/client/mifare/mifarehost.c index e4e1832b5..9d1293b5b 100644 --- a/client/mifare/mifarehost.c +++ b/client/mifare/mifarehost.c @@ -1360,16 +1360,16 @@ int detect_classic_nackbug(bool verbose) { return PM3_SUCCESS; } case 2 : - PrintAndLogEx(SUCCESS, _GREEN_("always leak NACK detected")); + PrintAndLogEx(SUCCESS, "NACK test: " _GREEN_("always leak NACK")); return PM3_SUCCESS; case 1 : - PrintAndLogEx(SUCCESS, _GREEN_("NACK bug detected")); + PrintAndLogEx(SUCCESS, "NACK test: " _GREEN_("detected")); return PM3_SUCCESS; case 0 : - PrintAndLogEx(SUCCESS, "No NACK bug detected"); + PrintAndLogEx(SUCCESS, "NACK test: " _GREEN_("no bug")); return PM3_SUCCESS; default : - PrintAndLogEx(ERR, "errorcode from device [%i]", ok); + PrintAndLogEx(ERR, "errorcode from device " _RED_("[%i]"), ok); return PM3_EUNDEF; } break; From 7d2e65ce91bb240ec7b43e6b11e4953e055e8263 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 15 Mar 2020 11:52:13 +0100 Subject: [PATCH 1694/1854] forgot a hint part --- client/util.h | 1 + 1 file changed, 1 insertion(+) diff --git a/client/util.h b/client/util.h index fb31e6013..e010175a6 100644 --- a/client/util.h +++ b/client/util.h @@ -23,6 +23,7 @@ uint8_t g_debugMode; uint8_t g_printAndLog; +uint8_t g_showhints; #define PRINTANDLOG_PRINT 1 #define PRINTANDLOG_LOG 2 From 8387bdbdadf09a022612fdd85a4c6aff2806f044 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 15 Mar 2020 13:23:02 +0100 Subject: [PATCH 1695/1854] change hint loglevel --- client/cmdlf.c | 4 ++-- client/cmdlfpyramid.c | 2 +- client/cmdlfti.c | 2 +- client/cmdlfverichip.c | 2 +- client/cmdlfviking.c | 2 +- client/cmdlfvisa2000.c | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/client/cmdlf.c b/client/cmdlf.c index 29854c6b6..31d10ce49 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -1189,7 +1189,7 @@ static bool CheckChipType(bool getDeviceData) { uint32_t word = 0; if (EM4x05IsBlock0(&word)) { PrintAndLogEx(SUCCESS, "Chipset detection: " _GREEN_("EM4x05/EM4x69")); - PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf em 4x05`") "commands"); + PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf em 4x05`") "commands"); retval = true; goto out; } @@ -1197,7 +1197,7 @@ static bool CheckChipType(bool getDeviceData) { //check for t55xx chip... if (tryDetectP1(true)) { PrintAndLogEx(SUCCESS, "Chipset detection: " _GREEN_("T55xx")); - PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf t55xx`") "commands"); + PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf t55xx`") "commands"); retval = true; } diff --git a/client/cmdlfpyramid.c b/client/cmdlfpyramid.c index 14357201a..91b2fb25e 100644 --- a/client/cmdlfpyramid.c +++ b/client/cmdlfpyramid.c @@ -252,7 +252,7 @@ static int CmdPyramidClone(const char *Cmd) { int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks)); PrintAndLogEx(SUCCESS, "Done"); - PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf pyramid read`") "to verify"); + PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf pyramid read`") "to verify"); return res; } diff --git a/client/cmdlfti.c b/client/cmdlfti.c index 8507fa36a..7aa04ca28 100644 --- a/client/cmdlfti.c +++ b/client/cmdlfti.c @@ -297,7 +297,7 @@ static int CmdTIWrite(const char *Cmd) { clearCommandBuffer(); SendCommandMIX(CMD_LF_TI_WRITE, arg0, arg1, arg2, NULL, 0); PrintAndLogEx(SUCCESS, "Done"); - PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf ti read`") "to verify"); + PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf ti read`") "to verify"); return PM3_SUCCESS; } diff --git a/client/cmdlfverichip.c b/client/cmdlfverichip.c index 91b49b8f4..a8cd68195 100644 --- a/client/cmdlfverichip.c +++ b/client/cmdlfverichip.c @@ -123,7 +123,7 @@ static int CmdVerichipClone(const char *Cmd) { int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks)); PrintAndLogEx(SUCCESS, "Done"); - PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf verichip read`") "to verify"); + PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf verichip read`") "to verify"); return res; } diff --git a/client/cmdlfviking.c b/client/cmdlfviking.c index 407c28f7e..e30234e5a 100644 --- a/client/cmdlfviking.c +++ b/client/cmdlfviking.c @@ -118,7 +118,7 @@ static int CmdVikingClone(const char *Cmd) { return PM3_ETIMEOUT; } PrintAndLogEx(SUCCESS, "Done"); - PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf viking read`") "to verify"); + PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf viking read`") "to verify"); return resp.status; } diff --git a/client/cmdlfvisa2000.c b/client/cmdlfvisa2000.c index 1a628e51d..7293b5efc 100644 --- a/client/cmdlfvisa2000.c +++ b/client/cmdlfvisa2000.c @@ -186,7 +186,7 @@ static int CmdVisa2kClone(const char *Cmd) { int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks)); PrintAndLogEx(SUCCESS, "Done"); - PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf visa2000 read`") "to verify"); + PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf visa2000 read`") "to verify"); return res; } From 3e11d8d522c22ddcd8e8db2d11ba94bf7d032010 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 15 Mar 2020 13:26:15 +0100 Subject: [PATCH 1696/1854] update hint loglevel --- client/cmdlfawid.c | 2 +- client/cmdlfem4x.c | 6 +++--- client/cmdlffdx.c | 2 +- client/cmdlfgallagher.c | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/client/cmdlfawid.c b/client/cmdlfawid.c index 9bcf9e874..468941022 100644 --- a/client/cmdlfawid.c +++ b/client/cmdlfawid.c @@ -424,7 +424,7 @@ static int CmdAWIDClone(const char *Cmd) { int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks)); PrintAndLogEx(SUCCESS, "Done"); - PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf awid read`") "to verify"); + PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf awid read`") "to verify"); return res; } diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c index 02a86c2da..e759a4cf3 100644 --- a/client/cmdlfem4x.c +++ b/client/cmdlfem4x.c @@ -701,7 +701,7 @@ static int CmdEM410xWrite(const char *Cmd) { SendCommandMIX(CMD_LF_EM410X_WRITE, card, (uint32_t)(id >> 32), (uint32_t)id, NULL, 0); PrintAndLogEx(SUCCESS, "Done"); - PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf em 410x_read`") "to verify"); + PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf em 410x_read`") "to verify"); return PM3_SUCCESS; } @@ -1041,7 +1041,7 @@ static int CmdEM4x50Write(const char *Cmd) { PrintAndLogEx(NORMAL, "no implemented yet"); // // PrintAndLogEx(SUCCESS, "Done"); -// PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf em 4x50_read`") "to verify"); +// PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf em 4x50_read`") "to verify"); return PM3_SUCCESS; } @@ -1442,7 +1442,7 @@ static int CmdEM4x05Write(const char *Cmd) { PrintAndLogEx(SUCCESS, "Success writing to tag"); PrintAndLogEx(SUCCESS, "Done"); - PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf em 4x05_read`") "to verify"); + PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf em 4x05_read`") "to verify"); return status; } static int CmdEM4x05Wipe(const char *Cmd) { diff --git a/client/cmdlffdx.c b/client/cmdlffdx.c index 11ec2dd64..58f427a3d 100644 --- a/client/cmdlffdx.c +++ b/client/cmdlffdx.c @@ -303,7 +303,7 @@ static int CmdFdxClone(const char *Cmd) { int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks)); PrintAndLogEx(SUCCESS, "Done"); - PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf fdx read`") "to verify"); + PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf fdx read`") "to verify"); return res; } diff --git a/client/cmdlfgallagher.c b/client/cmdlfgallagher.c index e44682e2b..97a7e0e09 100644 --- a/client/cmdlfgallagher.c +++ b/client/cmdlfgallagher.c @@ -180,7 +180,7 @@ static int CmdGallagherClone(const char *Cmd) { int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks)); PrintAndLogEx(SUCCESS, "Done"); - PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf gallagher read`") "to verify"); + PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf gallagher read`") "to verify"); return res; } From 3cf06cf478e7860b88bec53408d14f76eef0469a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 15 Mar 2020 13:27:43 +0100 Subject: [PATCH 1697/1854] update hint loglevel --- client/cmdlfguard.c | 2 +- client/cmdlfhid.c | 2 +- client/cmdlfindala.c | 10 ++++++++-- client/cmdlfio.c | 2 +- client/cmdlfkeri.c | 2 +- client/cmdlfmotorola.c | 2 +- client/cmdlfnedap.c | 2 +- 7 files changed, 14 insertions(+), 8 deletions(-) diff --git a/client/cmdlfguard.c b/client/cmdlfguard.c index ba9023c21..a1dbf0587 100644 --- a/client/cmdlfguard.c +++ b/client/cmdlfguard.c @@ -189,7 +189,7 @@ static int CmdGuardClone(const char *Cmd) { int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks)); PrintAndLogEx(SUCCESS, "Done"); - PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf gprox read`") "to verify"); + PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf gprox read`") "to verify"); return res; } diff --git a/client/cmdlfhid.c b/client/cmdlfhid.c index b5d449623..53af57ab7 100644 --- a/client/cmdlfhid.c +++ b/client/cmdlfhid.c @@ -348,7 +348,7 @@ static int CmdHIDClone(const char *Cmd) { clearCommandBuffer(); SendCommandMIX(CMD_LF_HID_CLONE, hi2, hi, lo, longid, sizeof(longid)); PrintAndLogEx(SUCCESS, "Done"); - PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf hid read`") "to verify"); + PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf hid read`") "to verify"); return PM3_SUCCESS; } diff --git a/client/cmdlfindala.c b/client/cmdlfindala.c index 6da2aa8f2..e5651a3ad 100644 --- a/client/cmdlfindala.c +++ b/client/cmdlfindala.c @@ -246,7 +246,7 @@ static int CmdIndalaDemod(const char *Cmd) { checksum |= DemodBuffer[63] << 0; // b1 PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(SUCCESS, "Fmt 26 bit FC " _YELLOW_("%u") ", CN " _YELLOW_("%u") ", checksum %1d%1d" + PrintAndLogEx(SUCCESS, "Fmt 26 bit FC " _YELLOW_("%u") ", CN " _YELLOW_("%u") ", checksum " _YELLOW_("%1d%1d") , fc , csn , checksum >> 1 & 0x01 @@ -505,6 +505,7 @@ static int CmdIndalaSim(const char *Cmd) { uint8_t hexuid[100]; int len = 0; param_gethex_ex(Cmd, 0, hexuid, &len); + if (len > 28) return usage_lf_indala_sim(); @@ -670,7 +671,7 @@ static int CmdIndalaClone(const char *Cmd) { print_blocks(blocks, max); int res = clone_t55xx_tag(blocks, max); PrintAndLogEx(SUCCESS, "Done"); - PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf indala read`") "to verify"); + PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf indala read`") "to verify"); return res; } @@ -749,6 +750,11 @@ int getIndalaBits(uint8_t fc, uint16_t cn, uint8_t *bits) { bits[62] = 1; bits[63] = 0; } + + // add parity + bits[34] = 1; // p1 64 - 30 = 34 + bits[38] = 1; // p2 68 - 30 = 38 + // 92 = 62 // 93 = 63 diff --git a/client/cmdlfio.c b/client/cmdlfio.c index 994c69a7d..28c653ab4 100644 --- a/client/cmdlfio.c +++ b/client/cmdlfio.c @@ -277,7 +277,7 @@ static int CmdIOProxClone(const char *Cmd) { int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks)); PrintAndLogEx(SUCCESS, "Done"); - PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf io read`") "to verify"); + PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf io read`") "to verify"); return res; } diff --git a/client/cmdlfkeri.c b/client/cmdlfkeri.c index c698842a6..801307fd3 100644 --- a/client/cmdlfkeri.c +++ b/client/cmdlfkeri.c @@ -282,7 +282,7 @@ static int CmdKeriClone(const char *Cmd) { int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks)); PrintAndLogEx(SUCCESS, "Done"); - PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf keri read`") "to verify"); + PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf keri read`") "to verify"); return res; } diff --git a/client/cmdlfmotorola.c b/client/cmdlfmotorola.c index c34b48d8e..66427a49a 100644 --- a/client/cmdlfmotorola.c +++ b/client/cmdlfmotorola.c @@ -179,7 +179,7 @@ static int CmdMotorolaClone(const char *Cmd) { print_blocks(blocks, ARRAYLEN(blocks)); int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks)); PrintAndLogEx(SUCCESS, "Done"); - PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf motorola read`") "to verify"); + PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf motorola read`") "to verify"); return res; } diff --git a/client/cmdlfnedap.c b/client/cmdlfnedap.c index a1d23cd91..5ac4e07fa 100644 --- a/client/cmdlfnedap.c +++ b/client/cmdlfnedap.c @@ -476,7 +476,7 @@ static int CmdLFNedapClone(const char *Cmd) { PrintAndLogEx(NORMAL, ""); } PrintAndLogEx(SUCCESS, "Done"); - PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf nedap read`") "to verify"); + PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf nedap read`") "to verify"); return res; } From 3f8157387871fc11378d070673fe54dab0591d77 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 15 Mar 2020 13:28:39 +0100 Subject: [PATCH 1698/1854] update hint loglevel --- client/cmdlfnexwatch.c | 2 +- client/cmdlfnoralsy.c | 2 +- client/cmdlfpac.c | 2 +- client/cmdlfparadox.c | 2 +- client/cmdlfpcf7931.c | 2 +- client/cmdlfpresco.c | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/client/cmdlfnexwatch.c b/client/cmdlfnexwatch.c index d288eeadc..5e3801118 100644 --- a/client/cmdlfnexwatch.c +++ b/client/cmdlfnexwatch.c @@ -160,7 +160,7 @@ static int CmdNexWatchClone(const char *Cmd) { int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks)); PrintAndLogEx(SUCCESS, "Done"); - PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf nexwatch read`") "to verify"); + PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf nexwatch read`") "to verify"); return res; } diff --git a/client/cmdlfnoralsy.c b/client/cmdlfnoralsy.c index bbb7de0c9..dc8fb4df0 100644 --- a/client/cmdlfnoralsy.c +++ b/client/cmdlfnoralsy.c @@ -171,7 +171,7 @@ static int CmdNoralsyClone(const char *Cmd) { int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks)); PrintAndLogEx(SUCCESS, "Done"); - PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf noralsy read`") "to verify"); + PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf noralsy read`") "to verify"); return res; } diff --git a/client/cmdlfpac.c b/client/cmdlfpac.c index 9ac9aa511..c633ccc1a 100644 --- a/client/cmdlfpac.c +++ b/client/cmdlfpac.c @@ -241,7 +241,7 @@ static int CmdPacClone(const char *Cmd) { int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks)); PrintAndLogEx(SUCCESS, "Done"); - PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf pac read`") "to verify"); + PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf pac read`") "to verify"); return res; } diff --git a/client/cmdlfparadox.c b/client/cmdlfparadox.c index c540290f8..8422f0f6f 100644 --- a/client/cmdlfparadox.c +++ b/client/cmdlfparadox.c @@ -171,7 +171,7 @@ static int CmdParadoxClone(const char *Cmd) { int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks)); PrintAndLogEx(SUCCESS, "Done"); - PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf paradox read`") "to verify"); + PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf paradox read`") "to verify"); return res; } diff --git a/client/cmdlfpcf7931.c b/client/cmdlfpcf7931.c index ddcad195d..c37fc9470 100644 --- a/client/cmdlfpcf7931.c +++ b/client/cmdlfpcf7931.c @@ -151,7 +151,7 @@ static int CmdLFPCF7931Write(const char *Cmd) { SendCommandMIX(CMD_LF_PCF7931_WRITE, block, bytepos, data, buf, sizeof(buf)); PrintAndLogEx(SUCCESS, "Done"); - PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf pcf7931 read`") "to verify"); + PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf pcf7931 read`") "to verify"); return PM3_SUCCESS; } diff --git a/client/cmdlfpresco.c b/client/cmdlfpresco.c index 9f00dbdce..fe4f3dd1c 100644 --- a/client/cmdlfpresco.c +++ b/client/cmdlfpresco.c @@ -138,7 +138,7 @@ static int CmdPrescoClone(const char *Cmd) { int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks)); PrintAndLogEx(SUCCESS, "Done"); - PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf presco read`") "to verify"); + PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf presco read`") "to verify"); return res; } From fb3f4ecd361fe09a9b20d976812b8d995ea4d933 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 15 Mar 2020 13:29:00 +0100 Subject: [PATCH 1699/1854] update hint loglevel --- client/cmdlfsecurakey.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdlfsecurakey.c b/client/cmdlfsecurakey.c index 0061d56c4..643ab980d 100644 --- a/client/cmdlfsecurakey.c +++ b/client/cmdlfsecurakey.c @@ -170,7 +170,7 @@ static int CmdSecurakeyClone(const char *Cmd) { int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks)); PrintAndLogEx(SUCCESS, "Done"); - PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf securakey read`") "to verify"); + PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf securakey read`") "to verify"); return res; } From 3d2c0bfdefd3cfb711ea662cb26b7748560d4b31 Mon Sep 17 00:00:00 2001 From: Daniel Underhay <27876907+dunderhay@users.noreply.github.com> Date: Sun, 15 Mar 2020 23:32:53 +1100 Subject: [PATCH 1700/1854] Add colour to hf mfdes command --- client/cmdhf14a.c | 44 ++++++------ client/cmdhfmfdes.c | 164 ++++++++++++++++++++++---------------------- 2 files changed, 103 insertions(+), 105 deletions(-) diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index 0355abe85..13a5a9213 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -1323,55 +1323,55 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { } break; case 0x01: - PrintAndLogEx(SUCCESS, "TYPE : NXP TNP3xxx Activision Game Appliance"); + PrintAndLogEx(SUCCESS, "TYPE: " _YELLOW_("NXP TNP3xxx Activision Game Appliance")); break; case 0x04: - PrintAndLogEx(SUCCESS, "TYPE : NXP MIFARE (various !DESFire !DESFire EV1)"); + PrintAndLogEx(SUCCESS, "TYPE: " _YELLOW_("NXP MIFARE (various !DESFire !DESFire EV1)")); isMifareClassic = false; isMifareDesfire = true; break; case 0x08: - PrintAndLogEx(SUCCESS, "TYPE : NXP MIFARE CLASSIC 1k | Plus 2k SL1 | 1k Ev1"); + PrintAndLogEx(SUCCESS, "TYPE: " _YELLOW_("NXP MIFARE CLASSIC 1k | Plus 2k SL1 | 1k Ev1")); break; case 0x09: - PrintAndLogEx(SUCCESS, "TYPE : NXP MIFARE Mini 0.3k"); + PrintAndLogEx(SUCCESS, "TYPE: " _YELLOW_("NXP MIFARE Mini 0.3k")); break; case 0x0A: - PrintAndLogEx(SUCCESS, "TYPE : FM11RF005SH (Shanghai Metro)"); + PrintAndLogEx(SUCCESS, "TYPE: " _YELLOW_("FM11RF005SH (Shanghai Metro)")); break; case 0x10: - PrintAndLogEx(SUCCESS, "TYPE : NXP MIFARE Plus 2k SL2"); + PrintAndLogEx(SUCCESS, "TYPE: " _YELLOW_("NXP MIFARE Plus 2k SL2")); isMifarePlus = true; break; case 0x11: - PrintAndLogEx(SUCCESS, "TYPE : NXP MIFARE Plus 4k SL2"); + PrintAndLogEx(SUCCESS, "TYPE: " _YELLOW_("NXP MIFARE Plus 4k SL2")); isMifarePlus = true; break; case 0x18: - PrintAndLogEx(SUCCESS, "TYPE : NXP MIFARE Classic 4k | Plus 4k SL1 | 4k Ev1"); + PrintAndLogEx(SUCCESS, "TYPE: " _YELLOW_("NXP MIFARE Classic 4k | Plus 4k SL1 | 4k Ev1")); break; case 0x20: - PrintAndLogEx(SUCCESS, "TYPE : NXP MIFARE DESFire 4k | DESFire EV1 2k/4k/8k | Plus 2k/4k SL3 | JCOP 31/41"); + PrintAndLogEx(SUCCESS, "TYPE: " _YELLOW_("NXP MIFARE DESFire 4k | DESFire EV1 2k/4k/8k | Plus 2k/4k SL3 | JCOP 31/41")); isMifareClassic = false; isMifareDesfire = true; isMifarePlus = true; break; case 0x24: - PrintAndLogEx(SUCCESS, "TYPE : NXP MIFARE DESFire | DESFire EV1"); + PrintAndLogEx(SUCCESS, "TYPE: " _YELLOW_("NXP MIFARE DESFire | DESFire EV1")); isMifareClassic = false; - isMifareDesfire = true; + isMifareDesfire = true; break; case 0x28: - PrintAndLogEx(SUCCESS, "TYPE : JCOP31 or JCOP41 v2.3.1"); + PrintAndLogEx(SUCCESS, "TYPE: " _YELLOW_("JCOP31 or JCOP41 v2.3.1")); break; case 0x38: - PrintAndLogEx(SUCCESS, "TYPE : Nokia 6212 or 6131 MIFARE CLASSIC 4K"); + PrintAndLogEx(SUCCESS, "TYPE: " _YELLOW_("Nokia 6212 or 6131 MIFARE CLASSIC 4K")); break; case 0x88: - PrintAndLogEx(SUCCESS, "TYPE : Infineon MIFARE CLASSIC 1K"); + PrintAndLogEx(SUCCESS, "TYPE: " _YELLOW_("Infineon MIFARE CLASSIC 1K")); break; case 0x98: - PrintAndLogEx(SUCCESS, "TYPE : Gemplus MPCOS"); + PrintAndLogEx(SUCCESS, "TYPE: " _YELLOW_("Gemplus MPCOS")); break; default: ; @@ -1379,7 +1379,7 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { // Double & triple sized UID, can be mapped to a manufacturer. if (card.uidlen > 4) { - PrintAndLogEx(SUCCESS, "MANUFACTURER: " _GREEN_("%s"), getTagInfo(card.uid[0])); + PrintAndLogEx(SUCCESS, "MANUFACTURER: " _YELLOW_("%s"), getTagInfo(card.uid[0])); } // try to request ATS even if tag claims not to support it @@ -1400,7 +1400,7 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { if (select_status == 2) { PrintAndLogEx(INFO, "SAK incorrectly claims that card doesn't support RATS"); } - PrintAndLogEx(SUCCESS, " ATS : %s", sprint_hex(card.ats, card.ats_len)); + PrintAndLogEx(SUCCESS, " ATS: %s", sprint_hex(card.ats, card.ats_len)); PrintAndLogEx(SUCCESS, " - TL : length is %d bytes", card.ats[0]); if (card.ats[0] != card.ats_len - 2) { PrintAndLogEx(SUCCESS, "ATS may be corrupted. Length of ATS (%d bytes incl. 2 Bytes CRC) doesn't match TL", card.ats_len); @@ -1626,17 +1626,17 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { if (res == 2 && verbose) PrintAndLogEx(SUCCESS, "Static nonce: " _RED_("fail")); } - - if (isMifareUltralight) { + + if (isMifareUltralight) { PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`hf mfu info`")); } - if (isMifarePlus) { + if (isMifarePlus) { PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`hf mfp info`")); } - if (isMifareDesfire) { + if (isMifareDesfire) { PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`hf mfdes info`")); } - + return select_status; } diff --git a/client/cmdhfmfdes.c b/client/cmdhfmfdes.c index 9c35a195d..80f9ea250 100644 --- a/client/cmdhfmfdes.c +++ b/client/cmdhfmfdes.c @@ -46,34 +46,34 @@ static int CmdHF14ADesInfo(const char *Cmd) { break; case 3: default: - PrintAndLogEx(WARNING, "Command unsuccessful"); + PrintAndLogEx(WARNING, _RED_("Command unsuccessful")); break; } return PM3_ESOFT; } PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "-- Desfire Information --------------------------------------"); - PrintAndLogEx(NORMAL, "-------------------------------------------------------------"); - PrintAndLogEx(NORMAL, " UID : %s", sprint_hex(resp.data.asBytes, 7)); - PrintAndLogEx(NORMAL, " Batch number : %s", sprint_hex(resp.data.asBytes + 28, 5)); - PrintAndLogEx(NORMAL, " Production date : week %02x, 20%02x", resp.data.asBytes[33], resp.data.asBytes[34]); - PrintAndLogEx(NORMAL, " -----------------------------------------------------------"); - PrintAndLogEx(NORMAL, " Hardware Information"); - PrintAndLogEx(NORMAL, " Vendor Id : %s", getTagInfo(resp.data.asBytes[7])); - PrintAndLogEx(NORMAL, " Type : 0x%02X", resp.data.asBytes[8]); - PrintAndLogEx(NORMAL, " Subtype : 0x%02X", resp.data.asBytes[9]); - PrintAndLogEx(NORMAL, " Version : %s", getVersionStr(resp.data.asBytes[10], resp.data.asBytes[11])); - PrintAndLogEx(NORMAL, " Storage size : %s", getCardSizeStr(resp.data.asBytes[12])); - PrintAndLogEx(NORMAL, " Protocol : %s", getProtocolStr(resp.data.asBytes[13])); - PrintAndLogEx(NORMAL, " -----------------------------------------------------------"); - PrintAndLogEx(NORMAL, " Software Information"); - PrintAndLogEx(NORMAL, " Vendor Id : %s", getTagInfo(resp.data.asBytes[14])); - PrintAndLogEx(NORMAL, " Type : 0x%02X", resp.data.asBytes[15]); - PrintAndLogEx(NORMAL, " Subtype : 0x%02X", resp.data.asBytes[16]); - PrintAndLogEx(NORMAL, " Version : %d.%d", resp.data.asBytes[17], resp.data.asBytes[18]); - PrintAndLogEx(NORMAL, " storage size : %s", getCardSizeStr(resp.data.asBytes[19])); - PrintAndLogEx(NORMAL, " Protocol : %s", getProtocolStr(resp.data.asBytes[20])); - PrintAndLogEx(NORMAL, "-------------------------------------------------------------"); + PrintAndLogEx(INFO, "-- Desfire Information --------------------------------------"); + PrintAndLogEx(INFO, "-------------------------------------------------------------"); + PrintAndLogEx(SUCCESS, " UID : " _GREEN_("%s"), sprint_hex(resp.data.asBytes, 7)); + PrintAndLogEx(SUCCESS, " Batch number : " _GREEN_("%s"), sprint_hex(resp.data.asBytes + 28, 5)); + PrintAndLogEx(SUCCESS, " Production date : week %02x, 20%02x", resp.data.asBytes[33], resp.data.asBytes[34]); + PrintAndLogEx(INFO, " -----------------------------------------------------------"); + PrintAndLogEx(INFO, " Hardware Information"); + PrintAndLogEx(SUCCESS, " Vendor Id : " _YELLOW_("%s"), getTagInfo(resp.data.asBytes[7])); + PrintAndLogEx(SUCCESS, " Type : " _YELLOW_("0x%02X"), resp.data.asBytes[8]); + PrintAndLogEx(SUCCESS, " Subtype : " _YELLOW_("0x%02X"), resp.data.asBytes[9]); + PrintAndLogEx(SUCCESS, " Version : " _YELLOW_("%s"), getVersionStr(resp.data.asBytes[10], resp.data.asBytes[11])); + PrintAndLogEx(SUCCESS, " Storage size : " _YELLOW_("%s"), getCardSizeStr(resp.data.asBytes[12])); + PrintAndLogEx(SUCCESS, " Protocol : " _YELLOW_("%s"), getProtocolStr(resp.data.asBytes[13])); + PrintAndLogEx(INFO, " -----------------------------------------------------------"); + PrintAndLogEx(INFO, " Software Information"); + PrintAndLogEx(SUCCESS, " Vendor Id : " _YELLOW_("%s"), getTagInfo(resp.data.asBytes[14])); + PrintAndLogEx(SUCCESS, " Type : " _YELLOW_("0x%02X"), resp.data.asBytes[15]); + PrintAndLogEx(SUCCESS, " Subtype : " _YELLOW_("0x%02X"), resp.data.asBytes[16]); + PrintAndLogEx(SUCCESS, " Version : " _YELLOW_("%d.%d"), resp.data.asBytes[17], resp.data.asBytes[18]); + PrintAndLogEx(SUCCESS, " storage size : " _YELLOW_("%s"), getCardSizeStr(resp.data.asBytes[19])); + PrintAndLogEx(SUCCESS, " Protocol : " _YELLOW_("%s"), getProtocolStr(resp.data.asBytes[20])); + PrintAndLogEx(INFO, "-------------------------------------------------------------"); // Master Key settings getKeySettings(NULL); @@ -87,8 +87,8 @@ static int CmdHF14ADesInfo(const char *Cmd) { uint8_t tmp[3]; memcpy(tmp, resp.data.asBytes + 3, 3); - PrintAndLogEx(NORMAL, " Available free memory on card : %d bytes", le24toh(tmp)); - PrintAndLogEx(NORMAL, "-------------------------------------------------------------"); + PrintAndLogEx(SUCCESS, " Available free memory on card : " _GREEN_("%d bytes"), le24toh(tmp)); + PrintAndLogEx(INFO, "-------------------------------------------------------------"); /* Card Master key (CMK) 0x00 AID = 00 00 00 (card level) @@ -168,8 +168,8 @@ void getKeySettings(uint8_t *aid) { //memset(messStr, 0x00, 512); if (aid == NULL) { - PrintAndLogEx(NORMAL, " CMK - PICC, Card Master Key settings "); - PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(SUCCESS, " CMK - PICC, Card Master Key settings"); + PrintAndLogEx(INFO, "-------------------------------------------------------------"); { uint8_t data[1] = {GET_KEY_SETTINGS}; // 0x45 SendCommandOLD(CMD_HF_DESFIRE_COMMAND, INIT | DISCONNECT, sizeof(data), 0, data, sizeof(data)); @@ -177,18 +177,18 @@ void getKeySettings(uint8_t *aid) { if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)) {return;} isOK = resp.oldarg[0] & 0xff; if (!isOK) { - PrintAndLogEx(WARNING, " Can't select master application"); + PrintAndLogEx(WARNING, _RED_(" Can't select master application")); return; } - str = (resp.data.asBytes[3] & (1 << 3)) ? "YES" : "NO"; - PrintAndLogEx(NORMAL, " [0x08] Configuration changeable : %s", str); - str = (resp.data.asBytes[3] & (1 << 2)) ? "NO" : "YES"; - PrintAndLogEx(NORMAL, " [0x04] CMK required for create/delete : %s", str); - str = (resp.data.asBytes[3] & (1 << 1)) ? "NO" : "YES"; - PrintAndLogEx(NORMAL, " [0x02] Directory list access with CMK : %s", str); - str = (resp.data.asBytes[3] & (1 << 0)) ? "YES" : "NO"; - PrintAndLogEx(NORMAL, " [0x01] CMK is changeable : %s", str); + str = (resp.data.asBytes[3] & (1 << 3)) ? _GREEN_("YES") : _RED_("NO"); + PrintAndLogEx(SUCCESS, " [0x08] Configuration changeable : %s", str); + str = (resp.data.asBytes[3] & (1 << 2)) ? _RED_("NO") : _GREEN_("YES"); + PrintAndLogEx(SUCCESS, " [0x04] CMK required for create/delete : %s", str); + str = (resp.data.asBytes[3] & (1 << 1)) ? _RED_("NO") : _GREEN_("YES"); + PrintAndLogEx(SUCCESS, " [0x02] Directory list access with CMK : %s", str); + str = (resp.data.asBytes[3] & (1 << 0)) ? _GREEN_("YES") : _RED_("NO"); + PrintAndLogEx(SUCCESS, " [0x01] CMK is changeable : %s", str); { uint8_t data[2] = {GET_KEY_VERSION, 0}; // 0x64 @@ -198,13 +198,13 @@ void getKeySettings(uint8_t *aid) { if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)) { return; } isOK = resp.oldarg[0] & 0xff; if (!isOK) { - PrintAndLogEx(WARNING, " Can't read key-version"); + PrintAndLogEx(WARNING, _RED_(" Can't read key-version")); return; } - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, " Max number of keys : %d", resp.data.asBytes[4]); - PrintAndLogEx(NORMAL, " Master key Version : %d (0x%02x)", resp.data.asBytes[3], resp.data.asBytes[3]); - PrintAndLogEx(NORMAL, " ----------------------------------------------------------"); + PrintAndLogEx(SUCCESS, ""); + PrintAndLogEx(SUCCESS, " Max number of keys : %d", resp.data.asBytes[4]); + PrintAndLogEx(SUCCESS, " Master key Version : %d (0x%02x)", resp.data.asBytes[3], resp.data.asBytes[3]); + PrintAndLogEx(INFO, " ----------------------------------------------------------"); { uint8_t data[2] = {AUTHENTICATE, 0}; // 0x0A, KEY 0 @@ -213,7 +213,7 @@ void getKeySettings(uint8_t *aid) { if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)) {return;} isOK = resp.data.asBytes[2] & 0xff; - PrintAndLogEx(NORMAL, " [0x0A] Authenticate : %s", (isOK == 0xAE) ? "NO" : "YES"); + PrintAndLogEx(SUCCESS, " [0x0A] Authenticate : %s", (isOK == 0xAE) ? "NO" : _YELLOW_("YES")); { uint8_t data[2] = {AUTHENTICATE_ISO, 0}; // 0x1A, KEY 0 @@ -222,7 +222,7 @@ void getKeySettings(uint8_t *aid) { if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)) {return;} isOK = resp.data.asBytes[2] & 0xff; - PrintAndLogEx(NORMAL, " [0x1A] Authenticate ISO : %s", (isOK == 0xAE) ? "NO" : "YES"); + PrintAndLogEx(SUCCESS, " [0x1A] Authenticate ISO : %s", (isOK == 0xAE) ? "NO" : _YELLOW_("YES")); { uint8_t data[2] = {AUTHENTICATE_AES, 0}; // 0xAA, KEY 0 @@ -231,12 +231,12 @@ void getKeySettings(uint8_t *aid) { if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)) {return;} isOK = resp.data.asBytes[2] & 0xff; - PrintAndLogEx(NORMAL, " [0xAA] Authenticate AES : %s", (isOK == 0xAE) ? "NO" : "YES"); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, " ----------------------------------------------------------"); + PrintAndLogEx(SUCCESS, " [0xAA] Authenticate AES : %s", (isOK == 0xAE) ? "NO" : _YELLOW_("YES")); + PrintAndLogEx(INFO, "-------------------------------------------------------------"); } else { - PrintAndLogEx(NORMAL, " AMK - Application Master Key settings"); + PrintAndLogEx(SUCCESS, " AMK - Application Master Key settings"); + PrintAndLogEx(INFO, " ----------------------------------------------------------"); // SELECT AID { @@ -245,12 +245,12 @@ void getKeySettings(uint8_t *aid) { SendCommandMIX(CMD_HF_DESFIRE_COMMAND, INIT | CLEARTRACE, sizeof(data), 0, data, sizeof(data)); } if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { - PrintAndLogEx(WARNING, " Timed-out"); + PrintAndLogEx(WARNING, _RED_(" Timed-out")); return; } isOK = resp.oldarg[0] & 0xff; if (!isOK) { - PrintAndLogEx(WARNING, " Can't select AID: %s", sprint_hex(aid, 3)); + PrintAndLogEx(WARNING, " Can't select AID: " _RED_("%s"), sprint_hex(aid, 3)); return; } @@ -265,7 +265,7 @@ void getKeySettings(uint8_t *aid) { } isOK = resp.oldarg[0] & 0xff; if (!isOK) { - PrintAndLogEx(WARNING, " Can't read Application Master key settings"); + PrintAndLogEx(WARNING, _RED_(" Can't read Application Master key settings")); } else { // Access rights. uint8_t rights = (resp.data.asBytes[3] >> 4 & 0xff); @@ -283,18 +283,18 @@ void getKeySettings(uint8_t *aid) { str = "Authentication with the specified key is necessary to change any key. A change key and a PICC master key (CMK) can only be changed after authentication with the master key. For keys other then the master or change key, an authentication with the same key is needed."; break; } - PrintAndLogEx(NORMAL, "Changekey Access rights"); - PrintAndLogEx(NORMAL, "-- %s", str); - PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(SUCCESS, "Changekey Access rights"); + PrintAndLogEx(SUCCESS, "-- " _GREEN_("%s"), str); + PrintAndLogEx(SUCCESS, ""); // same as CMK str = (resp.data.asBytes[3] & (1 << 3)) ? "YES" : "NO"; - PrintAndLogEx(NORMAL, " 0x08 Configuration changeable : %s", str); + PrintAndLogEx(SUCCESS, " 0x08 Configuration changeable : %s", str); str = (resp.data.asBytes[3] & (1 << 2)) ? "NO" : "YES"; - PrintAndLogEx(NORMAL, " 0x04 AMK required for create/delete : %s", str); + PrintAndLogEx(SUCCESS, " 0x04 AMK required for create/delete : %s", str); str = (resp.data.asBytes[3] & (1 << 1)) ? "NO" : "YES"; - PrintAndLogEx(NORMAL, " 0x02 Directory list access with AMK : %s", str); + PrintAndLogEx(SUCCESS, " 0x02 Directory list access with AMK : %s", str); str = (resp.data.asBytes[3] & (1 << 0)) ? "YES" : "NO"; - PrintAndLogEx(NORMAL, " 0x01 AMK is changeable : %s", str); + PrintAndLogEx(SUCCESS, " 0x01 AMK is changeable : %s", str); } // KEY VERSION - AMK @@ -304,7 +304,7 @@ void getKeySettings(uint8_t *aid) { } if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { - PrintAndLogEx(WARNING, " Timed-out"); + PrintAndLogEx(WARNING, _RED_(" Timed-out")); return; } @@ -316,10 +316,9 @@ void getKeySettings(uint8_t *aid) { //numOfKeys = MAX_NUM_KEYS; } else { numOfKeys = resp.data.asBytes[4]; - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, " Max number of keys : %d", numOfKeys); - PrintAndLogEx(NORMAL, " Application Master key Version : %d (0x%02x)", resp.data.asBytes[3], resp.data.asBytes[3]); - PrintAndLogEx(NORMAL, "-------------------------------------------------------------"); + PrintAndLogEx(SUCCESS, " Max number of keys : %d", numOfKeys); + PrintAndLogEx(SUCCESS, " Application Master key Version : %d (0x%02x)", resp.data.asBytes[3], resp.data.asBytes[3]); + PrintAndLogEx(INFO, "-------------------------------------------------------------"); } // LOOP over numOfKeys that we got before. @@ -349,12 +348,12 @@ static int CmdHF14ADesEnumApplications(const char *Cmd) { isOK = resp.oldarg[0] & 0xff; if (!isOK) { - PrintAndLogEx(NORMAL, "Command unsuccessful"); + PrintAndLogEx(WARNING, _RED_("Command unsuccessful")); return PM3_ESOFT; } PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "-- Desfire Enumerate Applications ---------------------------"); - PrintAndLogEx(NORMAL, "-------------------------------------------------------------"); + PrintAndLogEx(SUCCESS, "-- Desfire Enumerate Applications ---------------------------"); + PrintAndLogEx(INFO, "-------------------------------------------------------------"); PacketResponseNG respAid; PacketResponseNG respFiles; @@ -363,7 +362,7 @@ static int CmdHF14ADesEnumApplications(const char *Cmd) { int max = resp.oldarg[1] - 3 - 2; for (int i = 3; i <= max; i += 3) { - PrintAndLogEx(NORMAL, " Aid %d : %02X %02X %02X ", num, resp.data.asBytes[i], resp.data.asBytes[i + 1], resp.data.asBytes[i + 2]); + PrintAndLogEx(SUCCESS, " Aid %d : %02X %02X %02X ", num, resp.data.asBytes[i], resp.data.asBytes[i + 1], resp.data.asBytes[i + 2]); num++; aid[0] = resp.data.asBytes[i]; @@ -379,12 +378,12 @@ static int CmdHF14ADesEnumApplications(const char *Cmd) { } if (!WaitForResponseTimeout(CMD_ACK, &respAid, 1500)) { - PrintAndLogEx(WARNING, " Timed-out"); + PrintAndLogEx(WARNING, _RED_(" Timed-out")); continue; } isOK = respAid.data.asBytes[2] & 0xff; if (isOK != 0x00) { - PrintAndLogEx(WARNING, " Can't select AID: %s", sprint_hex(resp.data.asBytes + i, 3)); + PrintAndLogEx(WARNING, " Can't select AID: " _RED_("%s"), sprint_hex(resp.data.asBytes + i, 3)); continue; } @@ -395,16 +394,16 @@ static int CmdHF14ADesEnumApplications(const char *Cmd) { } if (!WaitForResponseTimeout(CMD_ACK, &respFiles, 1500)) { - PrintAndLogEx(WARNING, " Timed-out"); + PrintAndLogEx(WARNING, _RED_(" Timed-out")); continue; } else { isOK = respFiles.data.asBytes[2] & 0xff; if (!isOK) { - PrintAndLogEx(WARNING, " Can't get file ids "); + PrintAndLogEx(WARNING, _RED_(" Can't get file ids ")); } else { int respfileLen = resp.oldarg[1] - 3 - 2; for (int j = 0; j < respfileLen; ++j) { - PrintAndLogEx(NORMAL, " Fileid %d :", resp.data.asBytes[j + 3]); + PrintAndLogEx(SUCCESS, " Fileid %d :", resp.data.asBytes[j + 3]); } } } @@ -416,21 +415,21 @@ static int CmdHF14ADesEnumApplications(const char *Cmd) { } if (!WaitForResponseTimeout(CMD_ACK, &respFiles, 1500)) { - PrintAndLogEx(WARNING, " Timed-out"); + PrintAndLogEx(WARNING, _RED_(" Timed-out")); continue; } else { isOK = respFiles.data.asBytes[2] & 0xff; if (!isOK) { - PrintAndLogEx(WARNING, " Can't get ISO file ids "); + PrintAndLogEx(WARNING, _RED_(" Can't get ISO file ids")); } else { int respfileLen = resp.oldarg[1] - 3 - 2; for (int j = 0; j < respfileLen; ++j) { - PrintAndLogEx(NORMAL, " ISO Fileid %d :", resp.data.asBytes[j + 3]); + PrintAndLogEx(SUCCESS, " ISO Fileid %d :", resp.data.asBytes[j + 3]); } } } } - PrintAndLogEx(NORMAL, "-------------------------------------------------------------"); + PrintAndLogEx(INFO, "-------------------------------------------------------------"); return PM3_SUCCESS; } @@ -457,8 +456,8 @@ static int CmdHF14ADesAuth(const char *Cmd) { PrintAndLogEx(NORMAL, " 1 = DES 2 = 3DES 3 = 3K3DES 4 = AES"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf mfdes auth 1 1 0 11223344"); - PrintAndLogEx(NORMAL, " hf mfdes auth 3 4 0 404142434445464748494a4b4c4d4e4f"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mfdes auth 1 1 0 11223344")); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mfdes auth 3 4 0 404142434445464748494a4b4c4d4e4f")); return PM3_SUCCESS; } uint8_t cmdAuthMode = param_get8(Cmd, 0); @@ -531,14 +530,14 @@ static int CmdHF14ADesAuth(const char *Cmd) { if (isOK) { uint8_t *session_key = resp.data.asBytes; - PrintAndLogEx(NORMAL, " Key :%s", sprint_hex(key, keylength)); - PrintAndLogEx(NORMAL, " SESSION :%s", sprint_hex(session_key, keylength)); - PrintAndLogEx(NORMAL, "-------------------------------------------------------------"); + PrintAndLogEx(SUCCESS, " Key : " _GREEN_("%s"), sprint_hex(key, keylength)); + PrintAndLogEx(SUCCESS, " SESSION : " _GREEN_("%s"), sprint_hex(session_key, keylength)); + PrintAndLogEx(INFO, "-------------------------------------------------------------"); //PrintAndLogEx(NORMAL, " Expected :B5 21 9E E8 1A A7 49 9D 21 96 68 7E 13 97 38 56"); } else { - PrintAndLogEx(NORMAL, "Client command failed."); + PrintAndLogEx(WARNING, _RED_("Client command failed.")); } - PrintAndLogEx(NORMAL, "-------------------------------------------------------------"); + PrintAndLogEx(INFO, "-------------------------------------------------------------"); return PM3_SUCCESS; } @@ -564,4 +563,3 @@ int CmdHFMFDes(const char *Cmd) { clearCommandBuffer(); return CmdsParse(CommandTable, Cmd); } - From daba35687143d52ae076318a575c3e4d3ee17fb3 Mon Sep 17 00:00:00 2001 From: Daniel Underhay <27876907+dunderhay@users.noreply.github.com> Date: Sun, 15 Mar 2020 23:32:53 +1100 Subject: [PATCH 1701/1854] Add colour to hf mfdes command --- CHANGELOG.md | 2 + client/cmdhf14a.c | 44 ++++++------ client/cmdhfmfdes.c | 164 ++++++++++++++++++++++---------------------- 3 files changed, 105 insertions(+), 105 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0fa346660..bddf4c141 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Add colour to `hf mfdes` command (@dunderhay) + - Change type colour for `hf 14a` card types (@dunderhay) - Add 'HINTS' command. Will turn off / on hint messages. Default mode is OFF. (@iceman1001) - Add colour to `hf 14a` and `hf mfu` commands (@dunderhay) - Add colour to `lf hid` commands (@dunderhay) diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index 0355abe85..13a5a9213 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -1323,55 +1323,55 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { } break; case 0x01: - PrintAndLogEx(SUCCESS, "TYPE : NXP TNP3xxx Activision Game Appliance"); + PrintAndLogEx(SUCCESS, "TYPE: " _YELLOW_("NXP TNP3xxx Activision Game Appliance")); break; case 0x04: - PrintAndLogEx(SUCCESS, "TYPE : NXP MIFARE (various !DESFire !DESFire EV1)"); + PrintAndLogEx(SUCCESS, "TYPE: " _YELLOW_("NXP MIFARE (various !DESFire !DESFire EV1)")); isMifareClassic = false; isMifareDesfire = true; break; case 0x08: - PrintAndLogEx(SUCCESS, "TYPE : NXP MIFARE CLASSIC 1k | Plus 2k SL1 | 1k Ev1"); + PrintAndLogEx(SUCCESS, "TYPE: " _YELLOW_("NXP MIFARE CLASSIC 1k | Plus 2k SL1 | 1k Ev1")); break; case 0x09: - PrintAndLogEx(SUCCESS, "TYPE : NXP MIFARE Mini 0.3k"); + PrintAndLogEx(SUCCESS, "TYPE: " _YELLOW_("NXP MIFARE Mini 0.3k")); break; case 0x0A: - PrintAndLogEx(SUCCESS, "TYPE : FM11RF005SH (Shanghai Metro)"); + PrintAndLogEx(SUCCESS, "TYPE: " _YELLOW_("FM11RF005SH (Shanghai Metro)")); break; case 0x10: - PrintAndLogEx(SUCCESS, "TYPE : NXP MIFARE Plus 2k SL2"); + PrintAndLogEx(SUCCESS, "TYPE: " _YELLOW_("NXP MIFARE Plus 2k SL2")); isMifarePlus = true; break; case 0x11: - PrintAndLogEx(SUCCESS, "TYPE : NXP MIFARE Plus 4k SL2"); + PrintAndLogEx(SUCCESS, "TYPE: " _YELLOW_("NXP MIFARE Plus 4k SL2")); isMifarePlus = true; break; case 0x18: - PrintAndLogEx(SUCCESS, "TYPE : NXP MIFARE Classic 4k | Plus 4k SL1 | 4k Ev1"); + PrintAndLogEx(SUCCESS, "TYPE: " _YELLOW_("NXP MIFARE Classic 4k | Plus 4k SL1 | 4k Ev1")); break; case 0x20: - PrintAndLogEx(SUCCESS, "TYPE : NXP MIFARE DESFire 4k | DESFire EV1 2k/4k/8k | Plus 2k/4k SL3 | JCOP 31/41"); + PrintAndLogEx(SUCCESS, "TYPE: " _YELLOW_("NXP MIFARE DESFire 4k | DESFire EV1 2k/4k/8k | Plus 2k/4k SL3 | JCOP 31/41")); isMifareClassic = false; isMifareDesfire = true; isMifarePlus = true; break; case 0x24: - PrintAndLogEx(SUCCESS, "TYPE : NXP MIFARE DESFire | DESFire EV1"); + PrintAndLogEx(SUCCESS, "TYPE: " _YELLOW_("NXP MIFARE DESFire | DESFire EV1")); isMifareClassic = false; - isMifareDesfire = true; + isMifareDesfire = true; break; case 0x28: - PrintAndLogEx(SUCCESS, "TYPE : JCOP31 or JCOP41 v2.3.1"); + PrintAndLogEx(SUCCESS, "TYPE: " _YELLOW_("JCOP31 or JCOP41 v2.3.1")); break; case 0x38: - PrintAndLogEx(SUCCESS, "TYPE : Nokia 6212 or 6131 MIFARE CLASSIC 4K"); + PrintAndLogEx(SUCCESS, "TYPE: " _YELLOW_("Nokia 6212 or 6131 MIFARE CLASSIC 4K")); break; case 0x88: - PrintAndLogEx(SUCCESS, "TYPE : Infineon MIFARE CLASSIC 1K"); + PrintAndLogEx(SUCCESS, "TYPE: " _YELLOW_("Infineon MIFARE CLASSIC 1K")); break; case 0x98: - PrintAndLogEx(SUCCESS, "TYPE : Gemplus MPCOS"); + PrintAndLogEx(SUCCESS, "TYPE: " _YELLOW_("Gemplus MPCOS")); break; default: ; @@ -1379,7 +1379,7 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { // Double & triple sized UID, can be mapped to a manufacturer. if (card.uidlen > 4) { - PrintAndLogEx(SUCCESS, "MANUFACTURER: " _GREEN_("%s"), getTagInfo(card.uid[0])); + PrintAndLogEx(SUCCESS, "MANUFACTURER: " _YELLOW_("%s"), getTagInfo(card.uid[0])); } // try to request ATS even if tag claims not to support it @@ -1400,7 +1400,7 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { if (select_status == 2) { PrintAndLogEx(INFO, "SAK incorrectly claims that card doesn't support RATS"); } - PrintAndLogEx(SUCCESS, " ATS : %s", sprint_hex(card.ats, card.ats_len)); + PrintAndLogEx(SUCCESS, " ATS: %s", sprint_hex(card.ats, card.ats_len)); PrintAndLogEx(SUCCESS, " - TL : length is %d bytes", card.ats[0]); if (card.ats[0] != card.ats_len - 2) { PrintAndLogEx(SUCCESS, "ATS may be corrupted. Length of ATS (%d bytes incl. 2 Bytes CRC) doesn't match TL", card.ats_len); @@ -1626,17 +1626,17 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { if (res == 2 && verbose) PrintAndLogEx(SUCCESS, "Static nonce: " _RED_("fail")); } - - if (isMifareUltralight) { + + if (isMifareUltralight) { PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`hf mfu info`")); } - if (isMifarePlus) { + if (isMifarePlus) { PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`hf mfp info`")); } - if (isMifareDesfire) { + if (isMifareDesfire) { PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`hf mfdes info`")); } - + return select_status; } diff --git a/client/cmdhfmfdes.c b/client/cmdhfmfdes.c index 9c35a195d..80f9ea250 100644 --- a/client/cmdhfmfdes.c +++ b/client/cmdhfmfdes.c @@ -46,34 +46,34 @@ static int CmdHF14ADesInfo(const char *Cmd) { break; case 3: default: - PrintAndLogEx(WARNING, "Command unsuccessful"); + PrintAndLogEx(WARNING, _RED_("Command unsuccessful")); break; } return PM3_ESOFT; } PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "-- Desfire Information --------------------------------------"); - PrintAndLogEx(NORMAL, "-------------------------------------------------------------"); - PrintAndLogEx(NORMAL, " UID : %s", sprint_hex(resp.data.asBytes, 7)); - PrintAndLogEx(NORMAL, " Batch number : %s", sprint_hex(resp.data.asBytes + 28, 5)); - PrintAndLogEx(NORMAL, " Production date : week %02x, 20%02x", resp.data.asBytes[33], resp.data.asBytes[34]); - PrintAndLogEx(NORMAL, " -----------------------------------------------------------"); - PrintAndLogEx(NORMAL, " Hardware Information"); - PrintAndLogEx(NORMAL, " Vendor Id : %s", getTagInfo(resp.data.asBytes[7])); - PrintAndLogEx(NORMAL, " Type : 0x%02X", resp.data.asBytes[8]); - PrintAndLogEx(NORMAL, " Subtype : 0x%02X", resp.data.asBytes[9]); - PrintAndLogEx(NORMAL, " Version : %s", getVersionStr(resp.data.asBytes[10], resp.data.asBytes[11])); - PrintAndLogEx(NORMAL, " Storage size : %s", getCardSizeStr(resp.data.asBytes[12])); - PrintAndLogEx(NORMAL, " Protocol : %s", getProtocolStr(resp.data.asBytes[13])); - PrintAndLogEx(NORMAL, " -----------------------------------------------------------"); - PrintAndLogEx(NORMAL, " Software Information"); - PrintAndLogEx(NORMAL, " Vendor Id : %s", getTagInfo(resp.data.asBytes[14])); - PrintAndLogEx(NORMAL, " Type : 0x%02X", resp.data.asBytes[15]); - PrintAndLogEx(NORMAL, " Subtype : 0x%02X", resp.data.asBytes[16]); - PrintAndLogEx(NORMAL, " Version : %d.%d", resp.data.asBytes[17], resp.data.asBytes[18]); - PrintAndLogEx(NORMAL, " storage size : %s", getCardSizeStr(resp.data.asBytes[19])); - PrintAndLogEx(NORMAL, " Protocol : %s", getProtocolStr(resp.data.asBytes[20])); - PrintAndLogEx(NORMAL, "-------------------------------------------------------------"); + PrintAndLogEx(INFO, "-- Desfire Information --------------------------------------"); + PrintAndLogEx(INFO, "-------------------------------------------------------------"); + PrintAndLogEx(SUCCESS, " UID : " _GREEN_("%s"), sprint_hex(resp.data.asBytes, 7)); + PrintAndLogEx(SUCCESS, " Batch number : " _GREEN_("%s"), sprint_hex(resp.data.asBytes + 28, 5)); + PrintAndLogEx(SUCCESS, " Production date : week %02x, 20%02x", resp.data.asBytes[33], resp.data.asBytes[34]); + PrintAndLogEx(INFO, " -----------------------------------------------------------"); + PrintAndLogEx(INFO, " Hardware Information"); + PrintAndLogEx(SUCCESS, " Vendor Id : " _YELLOW_("%s"), getTagInfo(resp.data.asBytes[7])); + PrintAndLogEx(SUCCESS, " Type : " _YELLOW_("0x%02X"), resp.data.asBytes[8]); + PrintAndLogEx(SUCCESS, " Subtype : " _YELLOW_("0x%02X"), resp.data.asBytes[9]); + PrintAndLogEx(SUCCESS, " Version : " _YELLOW_("%s"), getVersionStr(resp.data.asBytes[10], resp.data.asBytes[11])); + PrintAndLogEx(SUCCESS, " Storage size : " _YELLOW_("%s"), getCardSizeStr(resp.data.asBytes[12])); + PrintAndLogEx(SUCCESS, " Protocol : " _YELLOW_("%s"), getProtocolStr(resp.data.asBytes[13])); + PrintAndLogEx(INFO, " -----------------------------------------------------------"); + PrintAndLogEx(INFO, " Software Information"); + PrintAndLogEx(SUCCESS, " Vendor Id : " _YELLOW_("%s"), getTagInfo(resp.data.asBytes[14])); + PrintAndLogEx(SUCCESS, " Type : " _YELLOW_("0x%02X"), resp.data.asBytes[15]); + PrintAndLogEx(SUCCESS, " Subtype : " _YELLOW_("0x%02X"), resp.data.asBytes[16]); + PrintAndLogEx(SUCCESS, " Version : " _YELLOW_("%d.%d"), resp.data.asBytes[17], resp.data.asBytes[18]); + PrintAndLogEx(SUCCESS, " storage size : " _YELLOW_("%s"), getCardSizeStr(resp.data.asBytes[19])); + PrintAndLogEx(SUCCESS, " Protocol : " _YELLOW_("%s"), getProtocolStr(resp.data.asBytes[20])); + PrintAndLogEx(INFO, "-------------------------------------------------------------"); // Master Key settings getKeySettings(NULL); @@ -87,8 +87,8 @@ static int CmdHF14ADesInfo(const char *Cmd) { uint8_t tmp[3]; memcpy(tmp, resp.data.asBytes + 3, 3); - PrintAndLogEx(NORMAL, " Available free memory on card : %d bytes", le24toh(tmp)); - PrintAndLogEx(NORMAL, "-------------------------------------------------------------"); + PrintAndLogEx(SUCCESS, " Available free memory on card : " _GREEN_("%d bytes"), le24toh(tmp)); + PrintAndLogEx(INFO, "-------------------------------------------------------------"); /* Card Master key (CMK) 0x00 AID = 00 00 00 (card level) @@ -168,8 +168,8 @@ void getKeySettings(uint8_t *aid) { //memset(messStr, 0x00, 512); if (aid == NULL) { - PrintAndLogEx(NORMAL, " CMK - PICC, Card Master Key settings "); - PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(SUCCESS, " CMK - PICC, Card Master Key settings"); + PrintAndLogEx(INFO, "-------------------------------------------------------------"); { uint8_t data[1] = {GET_KEY_SETTINGS}; // 0x45 SendCommandOLD(CMD_HF_DESFIRE_COMMAND, INIT | DISCONNECT, sizeof(data), 0, data, sizeof(data)); @@ -177,18 +177,18 @@ void getKeySettings(uint8_t *aid) { if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)) {return;} isOK = resp.oldarg[0] & 0xff; if (!isOK) { - PrintAndLogEx(WARNING, " Can't select master application"); + PrintAndLogEx(WARNING, _RED_(" Can't select master application")); return; } - str = (resp.data.asBytes[3] & (1 << 3)) ? "YES" : "NO"; - PrintAndLogEx(NORMAL, " [0x08] Configuration changeable : %s", str); - str = (resp.data.asBytes[3] & (1 << 2)) ? "NO" : "YES"; - PrintAndLogEx(NORMAL, " [0x04] CMK required for create/delete : %s", str); - str = (resp.data.asBytes[3] & (1 << 1)) ? "NO" : "YES"; - PrintAndLogEx(NORMAL, " [0x02] Directory list access with CMK : %s", str); - str = (resp.data.asBytes[3] & (1 << 0)) ? "YES" : "NO"; - PrintAndLogEx(NORMAL, " [0x01] CMK is changeable : %s", str); + str = (resp.data.asBytes[3] & (1 << 3)) ? _GREEN_("YES") : _RED_("NO"); + PrintAndLogEx(SUCCESS, " [0x08] Configuration changeable : %s", str); + str = (resp.data.asBytes[3] & (1 << 2)) ? _RED_("NO") : _GREEN_("YES"); + PrintAndLogEx(SUCCESS, " [0x04] CMK required for create/delete : %s", str); + str = (resp.data.asBytes[3] & (1 << 1)) ? _RED_("NO") : _GREEN_("YES"); + PrintAndLogEx(SUCCESS, " [0x02] Directory list access with CMK : %s", str); + str = (resp.data.asBytes[3] & (1 << 0)) ? _GREEN_("YES") : _RED_("NO"); + PrintAndLogEx(SUCCESS, " [0x01] CMK is changeable : %s", str); { uint8_t data[2] = {GET_KEY_VERSION, 0}; // 0x64 @@ -198,13 +198,13 @@ void getKeySettings(uint8_t *aid) { if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)) { return; } isOK = resp.oldarg[0] & 0xff; if (!isOK) { - PrintAndLogEx(WARNING, " Can't read key-version"); + PrintAndLogEx(WARNING, _RED_(" Can't read key-version")); return; } - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, " Max number of keys : %d", resp.data.asBytes[4]); - PrintAndLogEx(NORMAL, " Master key Version : %d (0x%02x)", resp.data.asBytes[3], resp.data.asBytes[3]); - PrintAndLogEx(NORMAL, " ----------------------------------------------------------"); + PrintAndLogEx(SUCCESS, ""); + PrintAndLogEx(SUCCESS, " Max number of keys : %d", resp.data.asBytes[4]); + PrintAndLogEx(SUCCESS, " Master key Version : %d (0x%02x)", resp.data.asBytes[3], resp.data.asBytes[3]); + PrintAndLogEx(INFO, " ----------------------------------------------------------"); { uint8_t data[2] = {AUTHENTICATE, 0}; // 0x0A, KEY 0 @@ -213,7 +213,7 @@ void getKeySettings(uint8_t *aid) { if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)) {return;} isOK = resp.data.asBytes[2] & 0xff; - PrintAndLogEx(NORMAL, " [0x0A] Authenticate : %s", (isOK == 0xAE) ? "NO" : "YES"); + PrintAndLogEx(SUCCESS, " [0x0A] Authenticate : %s", (isOK == 0xAE) ? "NO" : _YELLOW_("YES")); { uint8_t data[2] = {AUTHENTICATE_ISO, 0}; // 0x1A, KEY 0 @@ -222,7 +222,7 @@ void getKeySettings(uint8_t *aid) { if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)) {return;} isOK = resp.data.asBytes[2] & 0xff; - PrintAndLogEx(NORMAL, " [0x1A] Authenticate ISO : %s", (isOK == 0xAE) ? "NO" : "YES"); + PrintAndLogEx(SUCCESS, " [0x1A] Authenticate ISO : %s", (isOK == 0xAE) ? "NO" : _YELLOW_("YES")); { uint8_t data[2] = {AUTHENTICATE_AES, 0}; // 0xAA, KEY 0 @@ -231,12 +231,12 @@ void getKeySettings(uint8_t *aid) { if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)) {return;} isOK = resp.data.asBytes[2] & 0xff; - PrintAndLogEx(NORMAL, " [0xAA] Authenticate AES : %s", (isOK == 0xAE) ? "NO" : "YES"); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, " ----------------------------------------------------------"); + PrintAndLogEx(SUCCESS, " [0xAA] Authenticate AES : %s", (isOK == 0xAE) ? "NO" : _YELLOW_("YES")); + PrintAndLogEx(INFO, "-------------------------------------------------------------"); } else { - PrintAndLogEx(NORMAL, " AMK - Application Master Key settings"); + PrintAndLogEx(SUCCESS, " AMK - Application Master Key settings"); + PrintAndLogEx(INFO, " ----------------------------------------------------------"); // SELECT AID { @@ -245,12 +245,12 @@ void getKeySettings(uint8_t *aid) { SendCommandMIX(CMD_HF_DESFIRE_COMMAND, INIT | CLEARTRACE, sizeof(data), 0, data, sizeof(data)); } if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { - PrintAndLogEx(WARNING, " Timed-out"); + PrintAndLogEx(WARNING, _RED_(" Timed-out")); return; } isOK = resp.oldarg[0] & 0xff; if (!isOK) { - PrintAndLogEx(WARNING, " Can't select AID: %s", sprint_hex(aid, 3)); + PrintAndLogEx(WARNING, " Can't select AID: " _RED_("%s"), sprint_hex(aid, 3)); return; } @@ -265,7 +265,7 @@ void getKeySettings(uint8_t *aid) { } isOK = resp.oldarg[0] & 0xff; if (!isOK) { - PrintAndLogEx(WARNING, " Can't read Application Master key settings"); + PrintAndLogEx(WARNING, _RED_(" Can't read Application Master key settings")); } else { // Access rights. uint8_t rights = (resp.data.asBytes[3] >> 4 & 0xff); @@ -283,18 +283,18 @@ void getKeySettings(uint8_t *aid) { str = "Authentication with the specified key is necessary to change any key. A change key and a PICC master key (CMK) can only be changed after authentication with the master key. For keys other then the master or change key, an authentication with the same key is needed."; break; } - PrintAndLogEx(NORMAL, "Changekey Access rights"); - PrintAndLogEx(NORMAL, "-- %s", str); - PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(SUCCESS, "Changekey Access rights"); + PrintAndLogEx(SUCCESS, "-- " _GREEN_("%s"), str); + PrintAndLogEx(SUCCESS, ""); // same as CMK str = (resp.data.asBytes[3] & (1 << 3)) ? "YES" : "NO"; - PrintAndLogEx(NORMAL, " 0x08 Configuration changeable : %s", str); + PrintAndLogEx(SUCCESS, " 0x08 Configuration changeable : %s", str); str = (resp.data.asBytes[3] & (1 << 2)) ? "NO" : "YES"; - PrintAndLogEx(NORMAL, " 0x04 AMK required for create/delete : %s", str); + PrintAndLogEx(SUCCESS, " 0x04 AMK required for create/delete : %s", str); str = (resp.data.asBytes[3] & (1 << 1)) ? "NO" : "YES"; - PrintAndLogEx(NORMAL, " 0x02 Directory list access with AMK : %s", str); + PrintAndLogEx(SUCCESS, " 0x02 Directory list access with AMK : %s", str); str = (resp.data.asBytes[3] & (1 << 0)) ? "YES" : "NO"; - PrintAndLogEx(NORMAL, " 0x01 AMK is changeable : %s", str); + PrintAndLogEx(SUCCESS, " 0x01 AMK is changeable : %s", str); } // KEY VERSION - AMK @@ -304,7 +304,7 @@ void getKeySettings(uint8_t *aid) { } if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { - PrintAndLogEx(WARNING, " Timed-out"); + PrintAndLogEx(WARNING, _RED_(" Timed-out")); return; } @@ -316,10 +316,9 @@ void getKeySettings(uint8_t *aid) { //numOfKeys = MAX_NUM_KEYS; } else { numOfKeys = resp.data.asBytes[4]; - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, " Max number of keys : %d", numOfKeys); - PrintAndLogEx(NORMAL, " Application Master key Version : %d (0x%02x)", resp.data.asBytes[3], resp.data.asBytes[3]); - PrintAndLogEx(NORMAL, "-------------------------------------------------------------"); + PrintAndLogEx(SUCCESS, " Max number of keys : %d", numOfKeys); + PrintAndLogEx(SUCCESS, " Application Master key Version : %d (0x%02x)", resp.data.asBytes[3], resp.data.asBytes[3]); + PrintAndLogEx(INFO, "-------------------------------------------------------------"); } // LOOP over numOfKeys that we got before. @@ -349,12 +348,12 @@ static int CmdHF14ADesEnumApplications(const char *Cmd) { isOK = resp.oldarg[0] & 0xff; if (!isOK) { - PrintAndLogEx(NORMAL, "Command unsuccessful"); + PrintAndLogEx(WARNING, _RED_("Command unsuccessful")); return PM3_ESOFT; } PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "-- Desfire Enumerate Applications ---------------------------"); - PrintAndLogEx(NORMAL, "-------------------------------------------------------------"); + PrintAndLogEx(SUCCESS, "-- Desfire Enumerate Applications ---------------------------"); + PrintAndLogEx(INFO, "-------------------------------------------------------------"); PacketResponseNG respAid; PacketResponseNG respFiles; @@ -363,7 +362,7 @@ static int CmdHF14ADesEnumApplications(const char *Cmd) { int max = resp.oldarg[1] - 3 - 2; for (int i = 3; i <= max; i += 3) { - PrintAndLogEx(NORMAL, " Aid %d : %02X %02X %02X ", num, resp.data.asBytes[i], resp.data.asBytes[i + 1], resp.data.asBytes[i + 2]); + PrintAndLogEx(SUCCESS, " Aid %d : %02X %02X %02X ", num, resp.data.asBytes[i], resp.data.asBytes[i + 1], resp.data.asBytes[i + 2]); num++; aid[0] = resp.data.asBytes[i]; @@ -379,12 +378,12 @@ static int CmdHF14ADesEnumApplications(const char *Cmd) { } if (!WaitForResponseTimeout(CMD_ACK, &respAid, 1500)) { - PrintAndLogEx(WARNING, " Timed-out"); + PrintAndLogEx(WARNING, _RED_(" Timed-out")); continue; } isOK = respAid.data.asBytes[2] & 0xff; if (isOK != 0x00) { - PrintAndLogEx(WARNING, " Can't select AID: %s", sprint_hex(resp.data.asBytes + i, 3)); + PrintAndLogEx(WARNING, " Can't select AID: " _RED_("%s"), sprint_hex(resp.data.asBytes + i, 3)); continue; } @@ -395,16 +394,16 @@ static int CmdHF14ADesEnumApplications(const char *Cmd) { } if (!WaitForResponseTimeout(CMD_ACK, &respFiles, 1500)) { - PrintAndLogEx(WARNING, " Timed-out"); + PrintAndLogEx(WARNING, _RED_(" Timed-out")); continue; } else { isOK = respFiles.data.asBytes[2] & 0xff; if (!isOK) { - PrintAndLogEx(WARNING, " Can't get file ids "); + PrintAndLogEx(WARNING, _RED_(" Can't get file ids ")); } else { int respfileLen = resp.oldarg[1] - 3 - 2; for (int j = 0; j < respfileLen; ++j) { - PrintAndLogEx(NORMAL, " Fileid %d :", resp.data.asBytes[j + 3]); + PrintAndLogEx(SUCCESS, " Fileid %d :", resp.data.asBytes[j + 3]); } } } @@ -416,21 +415,21 @@ static int CmdHF14ADesEnumApplications(const char *Cmd) { } if (!WaitForResponseTimeout(CMD_ACK, &respFiles, 1500)) { - PrintAndLogEx(WARNING, " Timed-out"); + PrintAndLogEx(WARNING, _RED_(" Timed-out")); continue; } else { isOK = respFiles.data.asBytes[2] & 0xff; if (!isOK) { - PrintAndLogEx(WARNING, " Can't get ISO file ids "); + PrintAndLogEx(WARNING, _RED_(" Can't get ISO file ids")); } else { int respfileLen = resp.oldarg[1] - 3 - 2; for (int j = 0; j < respfileLen; ++j) { - PrintAndLogEx(NORMAL, " ISO Fileid %d :", resp.data.asBytes[j + 3]); + PrintAndLogEx(SUCCESS, " ISO Fileid %d :", resp.data.asBytes[j + 3]); } } } } - PrintAndLogEx(NORMAL, "-------------------------------------------------------------"); + PrintAndLogEx(INFO, "-------------------------------------------------------------"); return PM3_SUCCESS; } @@ -457,8 +456,8 @@ static int CmdHF14ADesAuth(const char *Cmd) { PrintAndLogEx(NORMAL, " 1 = DES 2 = 3DES 3 = 3K3DES 4 = AES"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf mfdes auth 1 1 0 11223344"); - PrintAndLogEx(NORMAL, " hf mfdes auth 3 4 0 404142434445464748494a4b4c4d4e4f"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mfdes auth 1 1 0 11223344")); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mfdes auth 3 4 0 404142434445464748494a4b4c4d4e4f")); return PM3_SUCCESS; } uint8_t cmdAuthMode = param_get8(Cmd, 0); @@ -531,14 +530,14 @@ static int CmdHF14ADesAuth(const char *Cmd) { if (isOK) { uint8_t *session_key = resp.data.asBytes; - PrintAndLogEx(NORMAL, " Key :%s", sprint_hex(key, keylength)); - PrintAndLogEx(NORMAL, " SESSION :%s", sprint_hex(session_key, keylength)); - PrintAndLogEx(NORMAL, "-------------------------------------------------------------"); + PrintAndLogEx(SUCCESS, " Key : " _GREEN_("%s"), sprint_hex(key, keylength)); + PrintAndLogEx(SUCCESS, " SESSION : " _GREEN_("%s"), sprint_hex(session_key, keylength)); + PrintAndLogEx(INFO, "-------------------------------------------------------------"); //PrintAndLogEx(NORMAL, " Expected :B5 21 9E E8 1A A7 49 9D 21 96 68 7E 13 97 38 56"); } else { - PrintAndLogEx(NORMAL, "Client command failed."); + PrintAndLogEx(WARNING, _RED_("Client command failed.")); } - PrintAndLogEx(NORMAL, "-------------------------------------------------------------"); + PrintAndLogEx(INFO, "-------------------------------------------------------------"); return PM3_SUCCESS; } @@ -564,4 +563,3 @@ int CmdHFMFDes(const char *Cmd) { clearCommandBuffer(); return CmdsParse(CommandTable, Cmd); } - From e5b38c46c60dd199f1b923f5f835358bbad1597d Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 15 Mar 2020 13:48:50 +0100 Subject: [PATCH 1702/1854] chg: hints - allow ON/OFF --- client/cmdmain.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/client/cmdmain.c b/client/cmdmain.c index d9cbbac74..57cd4d10a 100644 --- a/client/cmdmain.c +++ b/client/cmdmain.c @@ -194,20 +194,31 @@ int CmdRem(const char *Cmd) { static int CmdHints(const char *Cmd) { uint32_t ms = 0; char ctmp = tolower(param_getchar(Cmd, 0)); - if (ctmp == 'h') return usage_hints(); + if (ctmp == 'h') return usage_hints(); if (strlen(Cmd) < 1) { PrintAndLogEx(INFO, "Hints are %s", (g_showhints) ? "ON" : "OFF"); return PM3_SUCCESS; } - if (param_getchar(Cmd, 0) != 0x00) { - ms = param_get32ex(Cmd, 0, 0, 10); - if (ms == 0) + if (strlen(Cmd) > 1){ + str_lower((char *)Cmd); + if (str_startswith(Cmd, "of")) { g_showhints = false; - else - g_showhints = true; + } else { + g_showhints = true; + } + } else { + if (param_getchar(Cmd, 0) != 0x00) { + ms = param_get32ex(Cmd, 0, 0, 10); + if (ms == 0) { + g_showhints = false; + } else { + g_showhints = true; + } + } } + PrintAndLogEx(INFO, "Hints are %s", (g_showhints) ? "ON" : "OFF"); return PM3_SUCCESS; } From eb99a09d474be9b4047b283d55e103c9776fa12b Mon Sep 17 00:00:00 2001 From: Daniel Underhay <27876907+dunderhay@users.noreply.github.com> Date: Sun, 15 Mar 2020 23:52:05 +1100 Subject: [PATCH 1703/1854] Change mf card type colour from green to yellow --- CHANGELOG.md | 2 +- client/cmdhfmfu.c | 46 +++++++++++++++++++++++----------------------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bddf4c141..f6d2e03c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,8 +3,8 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] - - Add colour to `hf mfdes` command (@dunderhay) - Change type colour for `hf 14a` card types (@dunderhay) + - Add colour to `hf mfdes` command (@dunderhay) - Add 'HINTS' command. Will turn off / on hint messages. Default mode is OFF. (@iceman1001) - Add colour to `hf 14a` and `hf mfu` commands (@dunderhay) - Add colour to `lf hid` commands (@dunderhay) diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index ccc749708..5c70f37cd 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -679,55 +679,55 @@ int ul_print_type(uint32_t tagtype, uint8_t spaces) { char *spacer = spc + (10 - spaces); if (tagtype & UL) - PrintAndLogEx(SUCCESS, "%sTYPE: " _GREEN_("MIFARE Ultralight (MF0ICU1) %s"), spacer, (tagtype & MAGIC) ? "" : ""); + PrintAndLogEx(SUCCESS, "%sTYPE: " _YELLOW_("MIFARE Ultralight (MF0ICU1) %s"), spacer, (tagtype & MAGIC) ? "" : ""); else if (tagtype & UL_C) - PrintAndLogEx(SUCCESS, "%sTYPE: " _GREEN_("MIFARE Ultralight C (MF0ULC) %s"), spacer, (tagtype & MAGIC) ? "" : ""); + PrintAndLogEx(SUCCESS, "%sTYPE: " _YELLOW_("MIFARE Ultralight C (MF0ULC) %s"), spacer, (tagtype & MAGIC) ? "" : ""); else if (tagtype & UL_NANO_40) - PrintAndLogEx(SUCCESS, "%sTYPE: " _GREEN_("MIFARE Ultralight Nano 40bytes (MF0UNH00)"), spacer); + PrintAndLogEx(SUCCESS, "%sTYPE: " _YELLOW_("MIFARE Ultralight Nano 40bytes (MF0UNH00)"), spacer); else if (tagtype & UL_EV1_48) - PrintAndLogEx(SUCCESS, "%sTYPE: " _GREEN_("MIFARE Ultralight EV1 48bytes (MF0UL1101)"), spacer); + PrintAndLogEx(SUCCESS, "%sTYPE: " _YELLOW_("MIFARE Ultralight EV1 48bytes (MF0UL1101)"), spacer); else if (tagtype & UL_EV1_128) - PrintAndLogEx(SUCCESS, "%sTYPE: " _GREEN_("MIFARE Ultralight EV1 128bytes (MF0UL2101)"), spacer); + PrintAndLogEx(SUCCESS, "%sTYPE: " _YELLOW_("MIFARE Ultralight EV1 128bytes (MF0UL2101)"), spacer); else if (tagtype & UL_EV1) PrintAndLogEx(NORMAL, "%sTYPE: " _YELLOW_("MIFARE Ultralight EV1 UNKNOWN"), spacer); else if (tagtype & NTAG) PrintAndLogEx(NORMAL, "%sTYPE: " _YELLOW_("NTAG UNKNOWN"), spacer); else if (tagtype & NTAG_203) - PrintAndLogEx(SUCCESS, "%sTYPE: " _GREEN_("NTAG 203 144bytes (NT2H0301F0DT)"), spacer); + PrintAndLogEx(SUCCESS, "%sTYPE: " _YELLOW_("NTAG 203 144bytes (NT2H0301F0DT)"), spacer); else if (tagtype & NTAG_210) - PrintAndLogEx(SUCCESS, "%sTYPE: " _GREEN_("NTAG 210 48bytes (NT2L1011G0DU)"), spacer); + PrintAndLogEx(SUCCESS, "%sTYPE: " _YELLOW_("NTAG 210 48bytes (NT2L1011G0DU)"), spacer); else if (tagtype & NTAG_212) - PrintAndLogEx(SUCCESS, "%sTYPE: " _GREEN_("NTAG 212 128bytes (NT2L1211G0DU)"), spacer); + PrintAndLogEx(SUCCESS, "%sTYPE: " _YELLOW_("NTAG 212 128bytes (NT2L1211G0DU)"), spacer); else if (tagtype & NTAG_213) - PrintAndLogEx(SUCCESS, "%sTYPE: " _GREEN_("NTAG 213 144bytes (NT2H1311G0DU)"), spacer); + PrintAndLogEx(SUCCESS, "%sTYPE: " _YELLOW_("NTAG 213 144bytes (NT2H1311G0DU)"), spacer); else if (tagtype & NTAG_213_F) - PrintAndLogEx(SUCCESS, "%sTYPE: " _GREEN_("NTAG 213F 144bytes (NT2H1311F0DTL)"), spacer); + PrintAndLogEx(SUCCESS, "%sTYPE: " _YELLOW_("NTAG 213F 144bytes (NT2H1311F0DTL)"), spacer); else if (tagtype & NTAG_215) - PrintAndLogEx(SUCCESS, "%sTYPE: " _GREEN_("NTAG 215 504bytes (NT2H1511G0DU)"), spacer); + PrintAndLogEx(SUCCESS, "%sTYPE: " _YELLOW_("NTAG 215 504bytes (NT2H1511G0DU)"), spacer); else if (tagtype & NTAG_216) - PrintAndLogEx(SUCCESS, "%sTYPE: " _GREEN_("NTAG 216 888bytes (NT2H1611G0DU)"), spacer); + PrintAndLogEx(SUCCESS, "%sTYPE: " _YELLOW_("NTAG 216 888bytes (NT2H1611G0DU)"), spacer); else if (tagtype & NTAG_216_F) - PrintAndLogEx(SUCCESS, "%sTYPE: " _GREEN_("NTAG 216F 888bytes (NT2H1611F0DTL)"), spacer); + PrintAndLogEx(SUCCESS, "%sTYPE: " _YELLOW_("NTAG 216F 888bytes (NT2H1611F0DTL)"), spacer); else if (tagtype & NTAG_I2C_1K) - PrintAndLogEx(SUCCESS, "%sTYPE: " _GREEN_("NTAG I2C 888bytes (NT3H1101FHK)"), spacer); + PrintAndLogEx(SUCCESS, "%sTYPE: " _YELLOW_("NTAG I2C 888bytes (NT3H1101FHK)"), spacer); else if (tagtype & NTAG_I2C_2K) - PrintAndLogEx(SUCCESS, "%sTYPE: " _GREEN_("NTAG I2C 1904bytes (NT3H1201FHK)"), spacer); + PrintAndLogEx(SUCCESS, "%sTYPE: " _YELLOW_("NTAG I2C 1904bytes (NT3H1201FHK)"), spacer); else if (tagtype & NTAG_I2C_1K_PLUS) - PrintAndLogEx(SUCCESS, "%sTYPE: " _GREEN_("NTAG I2C plus 888bytes (NT3H2111FHK)"), spacer); + PrintAndLogEx(SUCCESS, "%sTYPE: " _YELLOW_("NTAG I2C plus 888bytes (NT3H2111FHK)"), spacer); else if (tagtype & NTAG_I2C_2K_PLUS) - PrintAndLogEx(SUCCESS, "%sTYPE: " _GREEN_("NTAG I2C plus 1912bytes (NT3H2211FHK)"), spacer); + PrintAndLogEx(SUCCESS, "%sTYPE: " _YELLOW_("NTAG I2C plus 1912bytes (NT3H2211FHK)"), spacer); else if (tagtype & MY_D) - PrintAndLogEx(SUCCESS, "%sTYPE: " _GREEN_("INFINEON my-d\x99 (SLE 66RxxS)"), spacer); + PrintAndLogEx(SUCCESS, "%sTYPE: " _YELLOW_("INFINEON my-d\x99 (SLE 66RxxS)"), spacer); else if (tagtype & MY_D_NFC) - PrintAndLogEx(SUCCESS, "%sTYPE: " _GREEN_("INFINEON my-d\x99 NFC (SLE 66RxxP)"), spacer); + PrintAndLogEx(SUCCESS, "%sTYPE: " _YELLOW_("INFINEON my-d\x99 NFC (SLE 66RxxP)"), spacer); else if (tagtype & MY_D_MOVE) - PrintAndLogEx(SUCCESS, "%sTYPE: " _GREEN_("INFINEON my-d\x99 move (SLE 66R01P)"), spacer); + PrintAndLogEx(SUCCESS, "%sTYPE: " _YELLOW_("INFINEON my-d\x99 move (SLE 66R01P)"), spacer); else if (tagtype & MY_D_MOVE_NFC) - PrintAndLogEx(SUCCESS, "%sTYPE: " _GREEN_("INFINEON my-d\x99 move NFC (SLE 66R01P)"), spacer); + PrintAndLogEx(SUCCESS, "%sTYPE: " _YELLOW_("INFINEON my-d\x99 move NFC (SLE 66R01P)"), spacer); else if (tagtype & MY_D_MOVE_LEAN) - PrintAndLogEx(SUCCESS, "%sTYPE: " _GREEN_("INFINEON my-d\x99 move lean (SLE 66R01L)"), spacer); + PrintAndLogEx(SUCCESS, "%sTYPE: " _YELLOW_("INFINEON my-d\x99 move lean (SLE 66R01L)"), spacer); else if (tagtype & FUDAN_UL) - PrintAndLogEx(SUCCESS, "%sTYPE: " _GREEN_("FUDAN Ultralight Compatible (or other compatible) %s"), spacer, (tagtype & MAGIC) ? "" : ""); + PrintAndLogEx(SUCCESS, "%sTYPE: " _YELLOW_("FUDAN Ultralight Compatible (or other compatible) %s"), spacer, (tagtype & MAGIC) ? "" : ""); else PrintAndLogEx(NORMAL, "%sTYPE: " _YELLOW_("Unknown %06x"), spacer, tagtype); return PM3_SUCCESS; From 4a8a0eca981c30bc5137e7d7b1e1179becba82b3 Mon Sep 17 00:00:00 2001 From: Daniel Underhay <27876907+dunderhay@users.noreply.github.com> Date: Mon, 16 Mar 2020 00:02:18 +1100 Subject: [PATCH 1704/1854] Additional colour changes --- CHANGELOG.md | 1 + client/cmdhfmfdes.c | 12 ++++++------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f6d2e03c2..1066a1f92 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Additional colour changes as recommended by @iceman (@dunderhay) - Change type colour for `hf 14a` card types (@dunderhay) - Add colour to `hf mfdes` command (@dunderhay) - Add 'HINTS' command. Will turn off / on hint messages. Default mode is OFF. (@iceman1001) diff --git a/client/cmdhfmfdes.c b/client/cmdhfmfdes.c index 80f9ea250..698af4a2d 100644 --- a/client/cmdhfmfdes.c +++ b/client/cmdhfmfdes.c @@ -181,13 +181,13 @@ void getKeySettings(uint8_t *aid) { return; } - str = (resp.data.asBytes[3] & (1 << 3)) ? _GREEN_("YES") : _RED_("NO"); + str = (resp.data.asBytes[3] & (1 << 3)) ? _GREEN_("YES") : "NO"; PrintAndLogEx(SUCCESS, " [0x08] Configuration changeable : %s", str); - str = (resp.data.asBytes[3] & (1 << 2)) ? _RED_("NO") : _GREEN_("YES"); + str = (resp.data.asBytes[3] & (1 << 2)) ? "NO" : _GREEN_("YES"); PrintAndLogEx(SUCCESS, " [0x04] CMK required for create/delete : %s", str); - str = (resp.data.asBytes[3] & (1 << 1)) ? _RED_("NO") : _GREEN_("YES"); + str = (resp.data.asBytes[3] & (1 << 1)) ? "NO" : _GREEN_("YES"); PrintAndLogEx(SUCCESS, " [0x02] Directory list access with CMK : %s", str); - str = (resp.data.asBytes[3] & (1 << 0)) ? _GREEN_("YES") : _RED_("NO"); + str = (resp.data.asBytes[3] & (1 << 0)) ? _GREEN_("YES") : "NO"; PrintAndLogEx(SUCCESS, " [0x01] CMK is changeable : %s", str); { @@ -202,8 +202,8 @@ void getKeySettings(uint8_t *aid) { return; } PrintAndLogEx(SUCCESS, ""); - PrintAndLogEx(SUCCESS, " Max number of keys : %d", resp.data.asBytes[4]); - PrintAndLogEx(SUCCESS, " Master key Version : %d (0x%02x)", resp.data.asBytes[3], resp.data.asBytes[3]); + PrintAndLogEx(SUCCESS, " Max number of keys : " _YELLOW_("%d"), resp.data.asBytes[4]); + PrintAndLogEx(SUCCESS, " Master key Version : " _YELLOW_("%d (0x%02x)"), resp.data.asBytes[3], resp.data.asBytes[3]); PrintAndLogEx(INFO, " ----------------------------------------------------------"); { From 5e3c070ab9c950b12528ff7a168a71a61b44cb2a Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 15 Mar 2020 22:41:05 +0100 Subject: [PATCH 1705/1854] emojis support --- client/cmdhf.c | 4 +- client/cmdlf.c | 4 +- client/emojis.h | 1862 +++++++++++++++++++++++++++++++++ client/emojis_alt.h | 15 + client/emojis_scrap_github.py | 35 + client/proxmark3.c | 7 +- client/ui.c | 159 ++- client/ui.h | 6 +- 8 files changed, 2070 insertions(+), 22 deletions(-) create mode 100644 client/emojis.h create mode 100644 client/emojis_alt.h create mode 100755 client/emojis_scrap_github.py diff --git a/client/cmdhf.c b/client/cmdhf.c index 35b50b852..418cc8b90 100644 --- a/client/cmdhf.c +++ b/client/cmdhf.c @@ -178,7 +178,7 @@ int CmdHFTune(const char *Cmd) { if (cmdp == 'h') return usage_hf_tune(); int iter = param_get32ex(Cmd, 0, 0, 10); - PrintAndLogEx(SUCCESS, "Measuring HF antenna, click " _GREEN_("pm3 button") "or press " _GREEN_("Enter") "to exit"); + PrintAndLogEx(INFO, "Measuring HF antenna, click " _GREEN_("pm3 button") "or press " _GREEN_("Enter") "to exit"); PacketResponseNG resp; clearCommandBuffer(); @@ -218,7 +218,7 @@ int CmdHFTune(const char *Cmd) { return PM3_ETIMEOUT; } PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(SUCCESS, "Done."); + PrintAndLogEx(INFO, "Done."); return PM3_SUCCESS; } diff --git a/client/cmdlf.c b/client/cmdlf.c index 29854c6b6..d61aff0ca 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -253,7 +253,7 @@ static int CmdLFTune(const char *Cmd) { //Validations if (errors) return usage_lf_tune(); - PrintAndLogEx(SUCCESS, "Measuring LF antenna at " _YELLOW_("%.2f") "kHz, click " _GREEN_("pm3 button") "or press " _GREEN_("Enter") "to exit", LF_DIV2FREQ(divisor)); + PrintAndLogEx(INFO, "Measuring LF antenna at " _YELLOW_("%.2f") "kHz, click " _GREEN_("pm3 button") "or press " _GREEN_("Enter") "to exit", LF_DIV2FREQ(divisor)); uint8_t params[] = {1, 0}; params[1] = divisor; @@ -295,7 +295,7 @@ static int CmdLFTune(const char *Cmd) { return PM3_ETIMEOUT; } PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(SUCCESS, "Done."); + PrintAndLogEx(INFO, "Done."); return PM3_SUCCESS; } diff --git a/client/emojis.h b/client/emojis.h new file mode 100644 index 000000000..b7ef0e92a --- /dev/null +++ b/client/emojis.h @@ -0,0 +1,1862 @@ +#ifndef EMOJIS_H__ +#define EMOJIS_H__ + +typedef struct emoji_s { + const char *alias; + const char *emoji; +} emoji_t; +// emoji_t array are expected to be NULL terminated + +static emoji_t EmojiTable[] = { + {":grinning:", "😀"}, + {":smiley:", "😃"}, + {":smile:", "😄"}, + {":grin:", "😁"}, + {":laughing:", "😆"}, + {":satisfied:", "😆"}, + {":sweat_smile:", "😅"}, + {":rofl:", "🤣"}, + {":joy:", "😂"}, + {":slightly_smiling_face:", "🙂"}, + {":upside_down_face:", "🙃"}, + {":wink:", "😉"}, + {":blush:", "😊"}, + {":innocent:", "😇"}, + {":smiling_face_with_three_hearts:", "🥰"}, + {":heart_eyes:", "😍"}, + {":star_struck:", "🤩"}, + {":kissing_heart:", "😘"}, + {":kissing:", "😗"}, + {":relaxed:", "☺️"}, + {":kissing_closed_eyes:", "😚"}, + {":kissing_smiling_eyes:", "😙"}, + {":smiling_face_with_tear:", "🥲"}, + {":yum:", "😋"}, + {":stuck_out_tongue:", "😛"}, + {":stuck_out_tongue_winking_eye:", "😜"}, + {":zany_face:", "🤪"}, + {":stuck_out_tongue_closed_eyes:", "😝"}, + {":money_mouth_face:", "🤑"}, + {":hugs:", "🤗"}, + {":hand_over_mouth:", "🤭"}, + {":shushing_face:", "🤫"}, + {":thinking:", "🤔"}, + {":zipper_mouth_face:", "🤐"}, + {":raised_eyebrow:", "🤨"}, + {":neutral_face:", "😐"}, + {":expressionless:", "😑"}, + {":no_mouth:", "😶"}, + {":smirk:", "😏"}, + {":unamused:", "😒"}, + {":roll_eyes:", "🙄"}, + {":grimacing:", "😬"}, + {":lying_face:", "🤥"}, + {":relieved:", "😌"}, + {":pensive:", "😔"}, + {":sleepy:", "😪"}, + {":drooling_face:", "🤤"}, + {":sleeping:", "😴"}, + {":mask:", "😷"}, + {":face_with_thermometer:", "🤒"}, + {":face_with_head_bandage:", "🤕"}, + {":nauseated_face:", "🤢"}, + {":vomiting_face:", "🤮"}, + {":sneezing_face:", "🤧"}, + {":hot_face:", "🥵"}, + {":cold_face:", "🥶"}, + {":woozy_face:", "🥴"}, + {":dizzy_face:", "😵"}, + {":exploding_head:", "🤯"}, + {":cowboy_hat_face:", "🤠"}, + {":partying_face:", "🥳"}, + {":disguised_face:", "🥸"}, + {":sunglasses:", "😎"}, + {":nerd_face:", "🤓"}, + {":monocle_face:", "🧐"}, + {":confused:", "😕"}, + {":worried:", "😟"}, + {":slightly_frowning_face:", "🙁"}, + {":frowning_face:", "☹️"}, + {":open_mouth:", "😮"}, + {":hushed:", "😯"}, + {":astonished:", "😲"}, + {":flushed:", "😳"}, + {":pleading_face:", "🥺"}, + {":frowning:", "😦"}, + {":anguished:", "😧"}, + {":fearful:", "😨"}, + {":cold_sweat:", "😰"}, + {":disappointed_relieved:", "😥"}, + {":cry:", "😢"}, + {":sob:", "😭"}, + {":scream:", "😱"}, + {":confounded:", "😖"}, + {":persevere:", "😣"}, + {":disappointed:", "😞"}, + {":sweat:", "😓"}, + {":weary:", "😩"}, + {":tired_face:", "😫"}, + {":yawning_face:", "🥱"}, + {":triumph:", "😤"}, + {":rage:", "😡"}, + {":pout:", "😡"}, + {":angry:", "😠"}, + {":cursing_face:", "🤬"}, + {":smiling_imp:", "😈"}, + {":imp:", "👿"}, + {":skull:", "💀"}, + {":skull_and_crossbones:", "☠️"}, + {":hankey:", "💩"}, + {":poop:", "💩"}, + {":shit:", "💩"}, + {":clown_face:", "🤡"}, + {":japanese_ogre:", "👹"}, + {":japanese_goblin:", "👺"}, + {":ghost:", "👻"}, + {":alien:", "👽"}, + {":space_invader:", "👾"}, + {":robot:", "🤖"}, + {":smiley_cat:", "😺"}, + {":smile_cat:", "😸"}, + {":joy_cat:", "😹"}, + {":heart_eyes_cat:", "😻"}, + {":smirk_cat:", "😼"}, + {":kissing_cat:", "😽"}, + {":scream_cat:", "🙀"}, + {":crying_cat_face:", "😿"}, + {":pouting_cat:", "😾"}, + {":see_no_evil:", "🙈"}, + {":hear_no_evil:", "🙉"}, + {":speak_no_evil:", "🙊"}, + {":kiss:", "💋"}, + {":love_letter:", "💌"}, + {":cupid:", "💘"}, + {":gift_heart:", "💝"}, + {":sparkling_heart:", "💖"}, + {":heartpulse:", "💗"}, + {":heartbeat:", "💓"}, + {":revolving_hearts:", "💞"}, + {":two_hearts:", "💕"}, + {":heart_decoration:", "💟"}, + {":heavy_heart_exclamation:", "❣️"}, + {":broken_heart:", "💔"}, + {":heart:", "❤️"}, + {":orange_heart:", "🧡"}, + {":yellow_heart:", "💛"}, + {":green_heart:", "💚"}, + {":blue_heart:", "💙"}, + {":purple_heart:", "💜"}, + {":brown_heart:", "🤎"}, + {":black_heart:", "🖤"}, + {":white_heart:", "🤍"}, + {":100:", "💯"}, + {":anger:", "💢"}, + {":boom:", "💥"}, + {":collision:", "💥"}, + {":dizzy:", "💫"}, + {":sweat_drops:", "💦"}, + {":dash:", "💨"}, + {":hole:", "🕳️"}, + {":bomb:", "💣"}, + {":speech_balloon:", "💬"}, + {":eye_speech_bubble:", "👁️‍🗨️"}, + {":left_speech_bubble:", "🗨️"}, + {":right_anger_bubble:", "🗯️"}, + {":thought_balloon:", "💭"}, + {":zzz:", "💤"}, + {":wave:", "👋"}, + {":raised_back_of_hand:", "🤚"}, + {":raised_hand_with_fingers_splayed:", "🖐️"}, + {":hand:", "✋"}, + {":raised_hand:", "✋"}, + {":vulcan_salute:", "🖖"}, + {":ok_hand:", "👌"}, + {":pinched_fingers:", "🤌"}, + {":pinching_hand:", "🤏"}, + {":v:", "✌️"}, + {":crossed_fingers:", "🤞"}, + {":love_you_gesture:", "🤟"}, + {":metal:", "🤘"}, + {":call_me_hand:", "🤙"}, + {":point_left:", "👈"}, + {":point_right:", "👉"}, + {":point_up_2:", "👆"}, + {":middle_finger:", "🖕"}, + {":fu:", "🖕"}, + {":point_down:", "👇"}, + {":point_up:", "☝️"}, + {":+1:", "👍"}, + {":thumbsup:", "👍"}, + {":-1:", "👎"}, + {":thumbsdown:", "👎"}, + {":fist_raised:", "✊"}, + {":fist:", "✊"}, + {":fist_oncoming:", "👊"}, + {":facepunch:", "👊"}, + {":punch:", "👊"}, + {":fist_left:", "🤛"}, + {":fist_right:", "🤜"}, + {":clap:", "👏"}, + {":raised_hands:", "🙌"}, + {":open_hands:", "👐"}, + {":palms_up_together:", "🤲"}, + {":handshake:", "🤝"}, + {":pray:", "🙏"}, + {":writing_hand:", "✍️"}, + {":nail_care:", "💅"}, + {":selfie:", "🤳"}, + {":muscle:", "💪"}, + {":mechanical_arm:", "🦾"}, + {":mechanical_leg:", "🦿"}, + {":leg:", "🦵"}, + {":foot:", "🦶"}, + {":ear:", "👂"}, + {":ear_with_hearing_aid:", "🦻"}, + {":nose:", "👃"}, + {":brain:", "🧠"}, + {":anatomical_heart:", "🫀"}, + {":lungs:", "🫁"}, + {":tooth:", "🦷"}, + {":bone:", "🦴"}, + {":eyes:", "👀"}, + {":eye:", "👁️"}, + {":tongue:", "👅"}, + {":lips:", "👄"}, + {":baby:", "👶"}, + {":child:", "🧒"}, + {":boy:", "👦"}, + {":girl:", "👧"}, + {":adult:", "🧑"}, + {":blond_haired_person:", "👱"}, + {":man:", "👨"}, + {":bearded_person:", "🧔"}, + {":red_haired_man:", "👨‍🦰"}, + {":curly_haired_man:", "👨‍🦱"}, + {":white_haired_man:", "👨‍🦳"}, + {":bald_man:", "👨‍🦲"}, + {":woman:", "👩"}, + {":red_haired_woman:", "👩‍🦰"}, + {":person_red_hair:", "🧑‍🦰"}, + {":curly_haired_woman:", "👩‍🦱"}, + {":person_curly_hair:", "🧑‍🦱"}, + {":white_haired_woman:", "👩‍🦳"}, + {":person_white_hair:", "🧑‍🦳"}, + {":bald_woman:", "👩‍🦲"}, + {":person_bald:", "🧑‍🦲"}, + {":blond_haired_woman:", "👱‍♀️"}, + {":blonde_woman:", "👱‍♀️"}, + {":blond_haired_man:", "👱‍♂️"}, + {":older_adult:", "🧓"}, + {":older_man:", "👴"}, + {":older_woman:", "👵"}, + {":frowning_person:", "🙍"}, + {":frowning_man:", "🙍‍♂️"}, + {":frowning_woman:", "🙍‍♀️"}, + {":pouting_face:", "🙎"}, + {":pouting_man:", "🙎‍♂️"}, + {":pouting_woman:", "🙎‍♀️"}, + {":no_good:", "🙅"}, + {":no_good_man:", "🙅‍♂️"}, + {":ng_man:", "🙅‍♂️"}, + {":no_good_woman:", "🙅‍♀️"}, + {":ng_woman:", "🙅‍♀️"}, + {":ok_person:", "🙆"}, + {":ok_man:", "🙆‍♂️"}, + {":ok_woman:", "🙆‍♀️"}, + {":tipping_hand_person:", "💁"}, + {":information_desk_person:", "💁"}, + {":tipping_hand_man:", "💁‍♂️"}, + {":sassy_man:", "💁‍♂️"}, + {":tipping_hand_woman:", "💁‍♀️"}, + {":sassy_woman:", "💁‍♀️"}, + {":raising_hand:", "🙋"}, + {":raising_hand_man:", "🙋‍♂️"}, + {":raising_hand_woman:", "🙋‍♀️"}, + {":deaf_person:", "🧏"}, + {":deaf_man:", "🧏‍♂️"}, + {":deaf_woman:", "🧏‍♀️"}, + {":bow:", "🙇"}, + {":bowing_man:", "🙇‍♂️"}, + {":bowing_woman:", "🙇‍♀️"}, + {":facepalm:", "🤦"}, + {":man_facepalming:", "🤦‍♂️"}, + {":woman_facepalming:", "🤦‍♀️"}, + {":shrug:", "🤷"}, + {":man_shrugging:", "🤷‍♂️"}, + {":woman_shrugging:", "🤷‍♀️"}, + {":health_worker:", "🧑‍⚕️"}, + {":man_health_worker:", "👨‍⚕️"}, + {":woman_health_worker:", "👩‍⚕️"}, + {":student:", "🧑‍🎓"}, + {":man_student:", "👨‍🎓"}, + {":woman_student:", "👩‍🎓"}, + {":teacher:", "🧑‍🏫"}, + {":man_teacher:", "👨‍🏫"}, + {":woman_teacher:", "👩‍🏫"}, + {":judge:", "🧑‍⚖️"}, + {":man_judge:", "👨‍⚖️"}, + {":woman_judge:", "👩‍⚖️"}, + {":farmer:", "🧑‍🌾"}, + {":man_farmer:", "👨‍🌾"}, + {":woman_farmer:", "👩‍🌾"}, + {":cook:", "🧑‍🍳"}, + {":man_cook:", "👨‍🍳"}, + {":woman_cook:", "👩‍🍳"}, + {":mechanic:", "🧑‍🔧"}, + {":man_mechanic:", "👨‍🔧"}, + {":woman_mechanic:", "👩‍🔧"}, + {":factory_worker:", "🧑‍🏭"}, + {":man_factory_worker:", "👨‍🏭"}, + {":woman_factory_worker:", "👩‍🏭"}, + {":office_worker:", "🧑‍💼"}, + {":man_office_worker:", "👨‍💼"}, + {":woman_office_worker:", "👩‍💼"}, + {":scientist:", "🧑‍🔬"}, + {":man_scientist:", "👨‍🔬"}, + {":woman_scientist:", "👩‍🔬"}, + {":technologist:", "🧑‍💻"}, + {":man_technologist:", "👨‍💻"}, + {":woman_technologist:", "👩‍💻"}, + {":singer:", "🧑‍🎤"}, + {":man_singer:", "👨‍🎤"}, + {":woman_singer:", "👩‍🎤"}, + {":artist:", "🧑‍🎨"}, + {":man_artist:", "👨‍🎨"}, + {":woman_artist:", "👩‍🎨"}, + {":pilot:", "🧑‍✈️"}, + {":man_pilot:", "👨‍✈️"}, + {":woman_pilot:", "👩‍✈️"}, + {":astronaut:", "🧑‍🚀"}, + {":man_astronaut:", "👨‍🚀"}, + {":woman_astronaut:", "👩‍🚀"}, + {":firefighter:", "🧑‍🚒"}, + {":man_firefighter:", "👨‍🚒"}, + {":woman_firefighter:", "👩‍🚒"}, + {":police_officer:", "👮"}, + {":cop:", "👮"}, + {":policeman:", "👮‍♂️"}, + {":policewoman:", "👮‍♀️"}, + {":detective:", "🕵️"}, + {":male_detective:", "🕵️‍♂️"}, + {":female_detective:", "🕵️‍♀️"}, + {":guard:", "💂"}, + {":guardsman:", "💂‍♂️"}, + {":guardswoman:", "💂‍♀️"}, + {":ninja:", "🥷"}, + {":construction_worker:", "👷"}, + {":construction_worker_man:", "👷‍♂️"}, + {":construction_worker_woman:", "👷‍♀️"}, + {":prince:", "🤴"}, + {":princess:", "👸"}, + {":person_with_turban:", "👳"}, + {":man_with_turban:", "👳‍♂️"}, + {":woman_with_turban:", "👳‍♀️"}, + {":man_with_gua_pi_mao:", "👲"}, + {":woman_with_headscarf:", "🧕"}, + {":person_in_tuxedo:", "🤵"}, + {":man_in_tuxedo:", "🤵‍♂️"}, + {":woman_in_tuxedo:", "🤵‍♀️"}, + {":person_with_veil:", "👰"}, + {":man_with_veil:", "👰‍♂️"}, + {":woman_with_veil:", "👰‍♀️"}, + {":bride_with_veil:", "👰‍♀️"}, + {":pregnant_woman:", "🤰"}, + {":breast_feeding:", "🤱"}, + {":woman_feeding_baby:", "👩‍🍼"}, + {":man_feeding_baby:", "👨‍🍼"}, + {":person_feeding_baby:", "🧑‍🍼"}, + {":angel:", "👼"}, + {":santa:", "🎅"}, + {":mrs_claus:", "🤶"}, + {":mx_claus:", "🧑‍🎄"}, + {":superhero:", "🦸"}, + {":superhero_man:", "🦸‍♂️"}, + {":superhero_woman:", "🦸‍♀️"}, + {":supervillain:", "🦹"}, + {":supervillain_man:", "🦹‍♂️"}, + {":supervillain_woman:", "🦹‍♀️"}, + {":mage:", "🧙"}, + {":mage_man:", "🧙‍♂️"}, + {":mage_woman:", "🧙‍♀️"}, + {":fairy:", "🧚"}, + {":fairy_man:", "🧚‍♂️"}, + {":fairy_woman:", "🧚‍♀️"}, + {":vampire:", "🧛"}, + {":vampire_man:", "🧛‍♂️"}, + {":vampire_woman:", "🧛‍♀️"}, + {":merperson:", "🧜"}, + {":merman:", "🧜‍♂️"}, + {":mermaid:", "🧜‍♀️"}, + {":elf:", "🧝"}, + {":elf_man:", "🧝‍♂️"}, + {":elf_woman:", "🧝‍♀️"}, + {":genie:", "🧞"}, + {":genie_man:", "🧞‍♂️"}, + {":genie_woman:", "🧞‍♀️"}, + {":zombie:", "🧟"}, + {":zombie_man:", "🧟‍♂️"}, + {":zombie_woman:", "🧟‍♀️"}, + {":massage:", "💆"}, + {":massage_man:", "💆‍♂️"}, + {":massage_woman:", "💆‍♀️"}, + {":haircut:", "💇"}, + {":haircut_man:", "💇‍♂️"}, + {":haircut_woman:", "💇‍♀️"}, + {":walking:", "🚶"}, + {":walking_man:", "🚶‍♂️"}, + {":walking_woman:", "🚶‍♀️"}, + {":standing_person:", "🧍"}, + {":standing_man:", "🧍‍♂️"}, + {":standing_woman:", "🧍‍♀️"}, + {":kneeling_person:", "🧎"}, + {":kneeling_man:", "🧎‍♂️"}, + {":kneeling_woman:", "🧎‍♀️"}, + {":person_with_probing_cane:", "🧑‍🦯"}, + {":man_with_probing_cane:", "👨‍🦯"}, + {":woman_with_probing_cane:", "👩‍🦯"}, + {":person_in_motorized_wheelchair:", "🧑‍🦼"}, + {":man_in_motorized_wheelchair:", "👨‍🦼"}, + {":woman_in_motorized_wheelchair:", "👩‍🦼"}, + {":person_in_manual_wheelchair:", "🧑‍🦽"}, + {":man_in_manual_wheelchair:", "👨‍🦽"}, + {":woman_in_manual_wheelchair:", "👩‍🦽"}, + {":runner:", "🏃"}, + {":running:", "🏃"}, + {":running_man:", "🏃‍♂️"}, + {":running_woman:", "🏃‍♀️"}, + {":woman_dancing:", "💃"}, + {":dancer:", "💃"}, + {":man_dancing:", "🕺"}, + {":business_suit_levitating:", "🕴️"}, + {":dancers:", "👯"}, + {":dancing_men:", "👯‍♂️"}, + {":dancing_women:", "👯‍♀️"}, + {":sauna_person:", "🧖"}, + {":sauna_man:", "🧖‍♂️"}, + {":sauna_woman:", "🧖‍♀️"}, + {":climbing:", "🧗"}, + {":climbing_man:", "🧗‍♂️"}, + {":climbing_woman:", "🧗‍♀️"}, + {":person_fencing:", "🤺"}, + {":horse_racing:", "🏇"}, + {":skier:", "⛷️"}, + {":snowboarder:", "🏂"}, + {":golfing:", "🏌️"}, + {":golfing_man:", "🏌️‍♂️"}, + {":golfing_woman:", "🏌️‍♀️"}, + {":surfer:", "🏄"}, + {":surfing_man:", "🏄‍♂️"}, + {":surfing_woman:", "🏄‍♀️"}, + {":rowboat:", "🚣"}, + {":rowing_man:", "🚣‍♂️"}, + {":rowing_woman:", "🚣‍♀️"}, + {":swimmer:", "🏊"}, + {":swimming_man:", "🏊‍♂️"}, + {":swimming_woman:", "🏊‍♀️"}, + {":bouncing_ball_person:", "⛹️"}, + {":bouncing_ball_man:", "⛹️‍♂️"}, + {":basketball_man:", "⛹️‍♂️"}, + {":bouncing_ball_woman:", "⛹️‍♀️"}, + {":basketball_woman:", "⛹️‍♀️"}, + {":weight_lifting:", "🏋️"}, + {":weight_lifting_man:", "🏋️‍♂️"}, + {":weight_lifting_woman:", "🏋️‍♀️"}, + {":bicyclist:", "🚴"}, + {":biking_man:", "🚴‍♂️"}, + {":biking_woman:", "🚴‍♀️"}, + {":mountain_bicyclist:", "🚵"}, + {":mountain_biking_man:", "🚵‍♂️"}, + {":mountain_biking_woman:", "🚵‍♀️"}, + {":cartwheeling:", "🤸"}, + {":man_cartwheeling:", "🤸‍♂️"}, + {":woman_cartwheeling:", "🤸‍♀️"}, + {":wrestling:", "🤼"}, + {":men_wrestling:", "🤼‍♂️"}, + {":women_wrestling:", "🤼‍♀️"}, + {":water_polo:", "🤽"}, + {":man_playing_water_polo:", "🤽‍♂️"}, + {":woman_playing_water_polo:", "🤽‍♀️"}, + {":handball_person:", "🤾"}, + {":man_playing_handball:", "🤾‍♂️"}, + {":woman_playing_handball:", "🤾‍♀️"}, + {":juggling_person:", "🤹"}, + {":man_juggling:", "🤹‍♂️"}, + {":woman_juggling:", "🤹‍♀️"}, + {":lotus_position:", "🧘"}, + {":lotus_position_man:", "🧘‍♂️"}, + {":lotus_position_woman:", "🧘‍♀️"}, + {":bath:", "🛀"}, + {":sleeping_bed:", "🛌"}, + {":people_holding_hands:", "🧑‍🤝‍🧑"}, + {":two_women_holding_hands:", "👭"}, + {":couple:", "👫"}, + {":two_men_holding_hands:", "👬"}, + {":couplekiss:", "💏"}, + {":couplekiss_man_woman:", "👩‍❤️‍💋‍👨"}, + {":couplekiss_man_man:", "👨‍❤️‍💋‍👨"}, + {":couplekiss_woman_woman:", "👩‍❤️‍💋‍👩"}, + {":couple_with_heart:", "💑"}, + {":couple_with_heart_woman_man:", "👩‍❤️‍👨"}, + {":couple_with_heart_man_man:", "👨‍❤️‍👨"}, + {":couple_with_heart_woman_woman:", "👩‍❤️‍👩"}, + {":family:", "👪"}, + {":family_man_woman_boy:", "👨‍👩‍👦"}, + {":family_man_woman_girl:", "👨‍👩‍👧"}, + {":family_man_woman_girl_boy:", "👨‍👩‍👧‍👦"}, + {":family_man_woman_boy_boy:", "👨‍👩‍👦‍👦"}, + {":family_man_woman_girl_girl:", "👨‍👩‍👧‍👧"}, + {":family_man_man_boy:", "👨‍👨‍👦"}, + {":family_man_man_girl:", "👨‍👨‍👧"}, + {":family_man_man_girl_boy:", "👨‍👨‍👧‍👦"}, + {":family_man_man_boy_boy:", "👨‍👨‍👦‍👦"}, + {":family_man_man_girl_girl:", "👨‍👨‍👧‍👧"}, + {":family_woman_woman_boy:", "👩‍👩‍👦"}, + {":family_woman_woman_girl:", "👩‍👩‍👧"}, + {":family_woman_woman_girl_boy:", "👩‍👩‍👧‍👦"}, + {":family_woman_woman_boy_boy:", "👩‍👩‍👦‍👦"}, + {":family_woman_woman_girl_girl:", "👩‍👩‍👧‍👧"}, + {":family_man_boy:", "👨‍👦"}, + {":family_man_boy_boy:", "👨‍👦‍👦"}, + {":family_man_girl:", "👨‍👧"}, + {":family_man_girl_boy:", "👨‍👧‍👦"}, + {":family_man_girl_girl:", "👨‍👧‍👧"}, + {":family_woman_boy:", "👩‍👦"}, + {":family_woman_boy_boy:", "👩‍👦‍👦"}, + {":family_woman_girl:", "👩‍👧"}, + {":family_woman_girl_boy:", "👩‍👧‍👦"}, + {":family_woman_girl_girl:", "👩‍👧‍👧"}, + {":speaking_head:", "🗣️"}, + {":bust_in_silhouette:", "👤"}, + {":busts_in_silhouette:", "👥"}, + {":people_hugging:", "🫂"}, + {":footprints:", "👣"}, + {":monkey_face:", "🐵"}, + {":monkey:", "🐒"}, + {":gorilla:", "🦍"}, + {":orangutan:", "🦧"}, + {":dog:", "🐶"}, + {":dog2:", "🐕"}, + {":guide_dog:", "🦮"}, + {":service_dog:", "🐕‍🦺"}, + {":poodle:", "🐩"}, + {":wolf:", "🐺"}, + {":fox_face:", "🦊"}, + {":raccoon:", "🦝"}, + {":cat:", "🐱"}, + {":cat2:", "🐈"}, + {":black_cat:", "🐈‍⬛"}, + {":lion:", "🦁"}, + {":tiger:", "🐯"}, + {":tiger2:", "🐅"}, + {":leopard:", "🐆"}, + {":horse:", "🐴"}, + {":racehorse:", "🐎"}, + {":unicorn:", "🦄"}, + {":zebra:", "🦓"}, + {":deer:", "🦌"}, + {":bison:", "🦬"}, + {":cow:", "🐮"}, + {":ox:", "🐂"}, + {":water_buffalo:", "🐃"}, + {":cow2:", "🐄"}, + {":pig:", "🐷"}, + {":pig2:", "🐖"}, + {":boar:", "🐗"}, + {":pig_nose:", "🐽"}, + {":ram:", "🐏"}, + {":sheep:", "🐑"}, + {":goat:", "🐐"}, + {":dromedary_camel:", "🐪"}, + {":camel:", "🐫"}, + {":llama:", "🦙"}, + {":giraffe:", "🦒"}, + {":elephant:", "🐘"}, + {":mammoth:", "🦣"}, + {":rhinoceros:", "🦏"}, + {":hippopotamus:", "🦛"}, + {":mouse:", "🐭"}, + {":mouse2:", "🐁"}, + {":rat:", "🐀"}, + {":hamster:", "🐹"}, + {":rabbit:", "🐰"}, + {":rabbit2:", "🐇"}, + {":chipmunk:", "🐿️"}, + {":beaver:", "🦫"}, + {":hedgehog:", "🦔"}, + {":bat:", "🦇"}, + {":bear:", "🐻"}, + {":polar_bear:", "🐻‍❄️"}, + {":koala:", "🐨"}, + {":panda_face:", "🐼"}, + {":sloth:", "🦥"}, + {":otter:", "🦦"}, + {":skunk:", "🦨"}, + {":kangaroo:", "🦘"}, + {":badger:", "🦡"}, + {":feet:", "🐾"}, + {":paw_prints:", "🐾"}, + {":turkey:", "🦃"}, + {":chicken:", "🐔"}, + {":rooster:", "🐓"}, + {":hatching_chick:", "🐣"}, + {":baby_chick:", "🐤"}, + {":hatched_chick:", "🐥"}, + {":bird:", "🐦"}, + {":penguin:", "🐧"}, + {":dove:", "🕊️"}, + {":eagle:", "🦅"}, + {":duck:", "🦆"}, + {":swan:", "🦢"}, + {":owl:", "🦉"}, + {":dodo:", "🦤"}, + {":feather:", "🪶"}, + {":flamingo:", "🦩"}, + {":peacock:", "🦚"}, + {":parrot:", "🦜"}, + {":frog:", "🐸"}, + {":crocodile:", "🐊"}, + {":turtle:", "🐢"}, + {":lizard:", "🦎"}, + {":snake:", "🐍"}, + {":dragon_face:", "🐲"}, + {":dragon:", "🐉"}, + {":sauropod:", "🦕"}, + {":t-rex:", "🦖"}, + {":whale:", "🐳"}, + {":whale2:", "🐋"}, + {":dolphin:", "🐬"}, + {":flipper:", "🐬"}, + {":seal:", "🦭"}, + {":fish:", "🐟"}, + {":tropical_fish:", "🐠"}, + {":blowfish:", "🐡"}, + {":shark:", "🦈"}, + {":octopus:", "🐙"}, + {":shell:", "🐚"}, + {":snail:", "🐌"}, + {":butterfly:", "🦋"}, + {":bug:", "🐛"}, + {":ant:", "🐜"}, + {":bee:", "🐝"}, + {":honeybee:", "🐝"}, + {":beetle:", "🪲"}, + {":lady_beetle:", "🐞"}, + {":cricket:", "🦗"}, + {":cockroach:", "🪳"}, + {":spider:", "🕷️"}, + {":spider_web:", "🕸️"}, + {":scorpion:", "🦂"}, + {":mosquito:", "🦟"}, + {":fly:", "🪰"}, + {":worm:", "🪱"}, + {":microbe:", "🦠"}, + {":bouquet:", "💐"}, + {":cherry_blossom:", "🌸"}, + {":white_flower:", "💮"}, + {":rosette:", "🏵️"}, + {":rose:", "🌹"}, + {":wilted_flower:", "🥀"}, + {":hibiscus:", "🌺"}, + {":sunflower:", "🌻"}, + {":blossom:", "🌼"}, + {":tulip:", "🌷"}, + {":seedling:", "🌱"}, + {":potted_plant:", "🪴"}, + {":evergreen_tree:", "🌲"}, + {":deciduous_tree:", "🌳"}, + {":palm_tree:", "🌴"}, + {":cactus:", "🌵"}, + {":ear_of_rice:", "🌾"}, + {":herb:", "🌿"}, + {":shamrock:", "☘️"}, + {":four_leaf_clover:", "🍀"}, + {":maple_leaf:", "🍁"}, + {":fallen_leaf:", "🍂"}, + {":leaves:", "🍃"}, + {":grapes:", "🍇"}, + {":melon:", "🍈"}, + {":watermelon:", "🍉"}, + {":tangerine:", "🍊"}, + {":orange:", "🍊"}, + {":mandarin:", "🍊"}, + {":lemon:", "🍋"}, + {":banana:", "🍌"}, + {":pineapple:", "🍍"}, + {":mango:", "🥭"}, + {":apple:", "🍎"}, + {":green_apple:", "🍏"}, + {":pear:", "🍐"}, + {":peach:", "🍑"}, + {":cherries:", "🍒"}, + {":strawberry:", "🍓"}, + {":blueberries:", "🫐"}, + {":kiwi_fruit:", "🥝"}, + {":tomato:", "🍅"}, + {":olive:", "🫒"}, + {":coconut:", "🥥"}, + {":avocado:", "🥑"}, + {":eggplant:", "🍆"}, + {":potato:", "🥔"}, + {":carrot:", "🥕"}, + {":corn:", "🌽"}, + {":hot_pepper:", "🌶️"}, + {":bell_pepper:", "🫑"}, + {":cucumber:", "🥒"}, + {":leafy_green:", "🥬"}, + {":broccoli:", "🥦"}, + {":garlic:", "🧄"}, + {":onion:", "🧅"}, + {":mushroom:", "🍄"}, + {":peanuts:", "🥜"}, + {":chestnut:", "🌰"}, + {":bread:", "🍞"}, + {":croissant:", "🥐"}, + {":baguette_bread:", "🥖"}, + {":flatbread:", "🫓"}, + {":pretzel:", "🥨"}, + {":bagel:", "🥯"}, + {":pancakes:", "🥞"}, + {":waffle:", "🧇"}, + {":cheese:", "🧀"}, + {":meat_on_bone:", "🍖"}, + {":poultry_leg:", "🍗"}, + {":cut_of_meat:", "🥩"}, + {":bacon:", "🥓"}, + {":hamburger:", "🍔"}, + {":fries:", "🍟"}, + {":pizza:", "🍕"}, + {":hotdog:", "🌭"}, + {":sandwich:", "🥪"}, + {":taco:", "🌮"}, + {":burrito:", "🌯"}, + {":tamale:", "🫔"}, + {":stuffed_flatbread:", "🥙"}, + {":falafel:", "🧆"}, + {":egg:", "🥚"}, + {":fried_egg:", "🍳"}, + {":shallow_pan_of_food:", "🥘"}, + {":stew:", "🍲"}, + {":fondue:", "🫕"}, + {":bowl_with_spoon:", "🥣"}, + {":green_salad:", "🥗"}, + {":popcorn:", "🍿"}, + {":butter:", "🧈"}, + {":salt:", "🧂"}, + {":canned_food:", "🥫"}, + {":bento:", "🍱"}, + {":rice_cracker:", "🍘"}, + {":rice_ball:", "🍙"}, + {":rice:", "🍚"}, + {":curry:", "🍛"}, + {":ramen:", "🍜"}, + {":spaghetti:", "🍝"}, + {":sweet_potato:", "🍠"}, + {":oden:", "🍢"}, + {":sushi:", "🍣"}, + {":fried_shrimp:", "🍤"}, + {":fish_cake:", "🍥"}, + {":moon_cake:", "🥮"}, + {":dango:", "🍡"}, + {":dumpling:", "🥟"}, + {":fortune_cookie:", "🥠"}, + {":takeout_box:", "🥡"}, + {":crab:", "🦀"}, + {":lobster:", "🦞"}, + {":shrimp:", "🦐"}, + {":squid:", "🦑"}, + {":oyster:", "🦪"}, + {":icecream:", "🍦"}, + {":shaved_ice:", "🍧"}, + {":ice_cream:", "🍨"}, + {":doughnut:", "🍩"}, + {":cookie:", "🍪"}, + {":birthday:", "🎂"}, + {":cake:", "🍰"}, + {":cupcake:", "🧁"}, + {":pie:", "🥧"}, + {":chocolate_bar:", "🍫"}, + {":candy:", "🍬"}, + {":lollipop:", "🍭"}, + {":custard:", "🍮"}, + {":honey_pot:", "🍯"}, + {":baby_bottle:", "🍼"}, + {":milk_glass:", "🥛"}, + {":coffee:", "☕"}, + {":teapot:", "🫖"}, + {":tea:", "🍵"}, + {":sake:", "🍶"}, + {":champagne:", "🍾"}, + {":wine_glass:", "🍷"}, + {":cocktail:", "🍸"}, + {":tropical_drink:", "🍹"}, + {":beer:", "🍺"}, + {":beers:", "🍻"}, + {":clinking_glasses:", "🥂"}, + {":tumbler_glass:", "🥃"}, + {":cup_with_straw:", "🥤"}, + {":bubble_tea:", "🧋"}, + {":beverage_box:", "🧃"}, + {":mate:", "🧉"}, + {":ice_cube:", "🧊"}, + {":chopsticks:", "🥢"}, + {":plate_with_cutlery:", "🍽️"}, + {":fork_and_knife:", "🍴"}, + {":spoon:", "🥄"}, + {":hocho:", "🔪"}, + {":knife:", "🔪"}, + {":amphora:", "🏺"}, + {":earth_africa:", "🌍"}, + {":earth_americas:", "🌎"}, + {":earth_asia:", "🌏"}, + {":globe_with_meridians:", "🌐"}, + {":world_map:", "🗺️"}, + {":japan:", "🗾"}, + {":compass:", "🧭"}, + {":mountain_snow:", "🏔️"}, + {":mountain:", "⛰️"}, + {":volcano:", "🌋"}, + {":mount_fuji:", "🗻"}, + {":camping:", "🏕️"}, + {":beach_umbrella:", "🏖️"}, + {":desert:", "🏜️"}, + {":desert_island:", "🏝️"}, + {":national_park:", "🏞️"}, + {":stadium:", "🏟️"}, + {":classical_building:", "🏛️"}, + {":building_construction:", "🏗️"}, + {":bricks:", "🧱"}, + {":rock:", "🪨"}, + {":wood:", "🪵"}, + {":hut:", "🛖"}, + {":houses:", "🏘️"}, + {":derelict_house:", "🏚️"}, + {":house:", "🏠"}, + {":house_with_garden:", "🏡"}, + {":office:", "🏢"}, + {":post_office:", "🏣"}, + {":european_post_office:", "🏤"}, + {":hospital:", "🏥"}, + {":bank:", "🏦"}, + {":hotel:", "🏨"}, + {":love_hotel:", "🏩"}, + {":convenience_store:", "🏪"}, + {":school:", "🏫"}, + {":department_store:", "🏬"}, + {":factory:", "🏭"}, + {":japanese_castle:", "🏯"}, + {":european_castle:", "🏰"}, + {":wedding:", "💒"}, + {":tokyo_tower:", "🗼"}, + {":statue_of_liberty:", "🗽"}, + {":church:", "⛪"}, + {":mosque:", "🕌"}, + {":hindu_temple:", "🛕"}, + {":synagogue:", "🕍"}, + {":shinto_shrine:", "⛩️"}, + {":kaaba:", "🕋"}, + {":fountain:", "⛲"}, + {":tent:", "⛺"}, + {":foggy:", "🌁"}, + {":night_with_stars:", "🌃"}, + {":cityscape:", "🏙️"}, + {":sunrise_over_mountains:", "🌄"}, + {":sunrise:", "🌅"}, + {":city_sunset:", "🌆"}, + {":city_sunrise:", "🌇"}, + {":bridge_at_night:", "🌉"}, + {":hotsprings:", "♨️"}, + {":carousel_horse:", "🎠"}, + {":ferris_wheel:", "🎡"}, + {":roller_coaster:", "🎢"}, + {":barber:", "💈"}, + {":circus_tent:", "🎪"}, + {":steam_locomotive:", "🚂"}, + {":railway_car:", "🚃"}, + {":bullettrain_side:", "🚄"}, + {":bullettrain_front:", "🚅"}, + {":train2:", "🚆"}, + {":metro:", "🚇"}, + {":light_rail:", "🚈"}, + {":station:", "🚉"}, + {":tram:", "🚊"}, + {":monorail:", "🚝"}, + {":mountain_railway:", "🚞"}, + {":train:", "🚋"}, + {":bus:", "🚌"}, + {":oncoming_bus:", "🚍"}, + {":trolleybus:", "🚎"}, + {":minibus:", "🚐"}, + {":ambulance:", "🚑"}, + {":fire_engine:", "🚒"}, + {":police_car:", "🚓"}, + {":oncoming_police_car:", "🚔"}, + {":taxi:", "🚕"}, + {":oncoming_taxi:", "🚖"}, + {":car:", "🚗"}, + {":red_car:", "🚗"}, + {":oncoming_automobile:", "🚘"}, + {":blue_car:", "🚙"}, + {":pickup_truck:", "🛻"}, + {":truck:", "🚚"}, + {":articulated_lorry:", "🚛"}, + {":tractor:", "🚜"}, + {":racing_car:", "🏎️"}, + {":motorcycle:", "🏍️"}, + {":motor_scooter:", "🛵"}, + {":manual_wheelchair:", "🦽"}, + {":motorized_wheelchair:", "🦼"}, + {":auto_rickshaw:", "🛺"}, + {":bike:", "🚲"}, + {":kick_scooter:", "🛴"}, + {":skateboard:", "🛹"}, + {":roller_skate:", "🛼"}, + {":busstop:", "🚏"}, + {":motorway:", "🛣️"}, + {":railway_track:", "🛤️"}, + {":oil_drum:", "🛢️"}, + {":fuelpump:", "⛽"}, + {":rotating_light:", "🚨"}, + {":traffic_light:", "🚥"}, + {":vertical_traffic_light:", "🚦"}, + {":stop_sign:", "🛑"}, + {":construction:", "🚧"}, + {":anchor:", "⚓"}, + {":boat:", "⛵"}, + {":sailboat:", "⛵"}, + {":canoe:", "🛶"}, + {":speedboat:", "🚤"}, + {":passenger_ship:", "🛳️"}, + {":ferry:", "⛴️"}, + {":motor_boat:", "🛥️"}, + {":ship:", "🚢"}, + {":airplane:", "✈️"}, + {":small_airplane:", "🛩️"}, + {":flight_departure:", "🛫"}, + {":flight_arrival:", "🛬"}, + {":parachute:", "🪂"}, + {":seat:", "💺"}, + {":helicopter:", "🚁"}, + {":suspension_railway:", "🚟"}, + {":mountain_cableway:", "🚠"}, + {":aerial_tramway:", "🚡"}, + {":artificial_satellite:", "🛰️"}, + {":rocket:", "🚀"}, + {":flying_saucer:", "🛸"}, + {":bellhop_bell:", "🛎️"}, + {":luggage:", "🧳"}, + {":hourglass:", "⌛"}, + {":hourglass_flowing_sand:", "⏳"}, + {":watch:", "⌚"}, + {":alarm_clock:", "⏰"}, + {":stopwatch:", "⏱️"}, + {":timer_clock:", "⏲️"}, + {":mantelpiece_clock:", "🕰️"}, + {":clock12:", "🕛"}, + {":clock1230:", "🕧"}, + {":clock1:", "🕐"}, + {":clock130:", "🕜"}, + {":clock2:", "🕑"}, + {":clock230:", "🕝"}, + {":clock3:", "🕒"}, + {":clock330:", "🕞"}, + {":clock4:", "🕓"}, + {":clock430:", "🕟"}, + {":clock5:", "🕔"}, + {":clock530:", "🕠"}, + {":clock6:", "🕕"}, + {":clock630:", "🕡"}, + {":clock7:", "🕖"}, + {":clock730:", "🕢"}, + {":clock8:", "🕗"}, + {":clock830:", "🕣"}, + {":clock9:", "🕘"}, + {":clock930:", "🕤"}, + {":clock10:", "🕙"}, + {":clock1030:", "🕥"}, + {":clock11:", "🕚"}, + {":clock1130:", "🕦"}, + {":new_moon:", "🌑"}, + {":waxing_crescent_moon:", "🌒"}, + {":first_quarter_moon:", "🌓"}, + {":moon:", "🌔"}, + {":waxing_gibbous_moon:", "🌔"}, + {":full_moon:", "🌕"}, + {":waning_gibbous_moon:", "🌖"}, + {":last_quarter_moon:", "🌗"}, + {":waning_crescent_moon:", "🌘"}, + {":crescent_moon:", "🌙"}, + {":new_moon_with_face:", "🌚"}, + {":first_quarter_moon_with_face:", "🌛"}, + {":last_quarter_moon_with_face:", "🌜"}, + {":thermometer:", "🌡️"}, + {":sunny:", "☀️"}, + {":full_moon_with_face:", "🌝"}, + {":sun_with_face:", "🌞"}, + {":ringed_planet:", "🪐"}, + {":star:", "⭐"}, + {":star2:", "🌟"}, + {":stars:", "🌠"}, + {":milky_way:", "🌌"}, + {":cloud:", "☁️"}, + {":partly_sunny:", "⛅"}, + {":cloud_with_lightning_and_rain:", "⛈️"}, + {":sun_behind_small_cloud:", "🌤️"}, + {":sun_behind_large_cloud:", "🌥️"}, + {":sun_behind_rain_cloud:", "🌦️"}, + {":cloud_with_rain:", "🌧️"}, + {":cloud_with_snow:", "🌨️"}, + {":cloud_with_lightning:", "🌩️"}, + {":tornado:", "🌪️"}, + {":fog:", "🌫️"}, + {":wind_face:", "🌬️"}, + {":cyclone:", "🌀"}, + {":rainbow:", "🌈"}, + {":closed_umbrella:", "🌂"}, + {":open_umbrella:", "☂️"}, + {":umbrella:", "☔"}, + {":parasol_on_ground:", "⛱️"}, + {":zap:", "⚡"}, + {":snowflake:", "❄️"}, + {":snowman_with_snow:", "☃️"}, + {":snowman:", "⛄"}, + {":comet:", "☄️"}, + {":fire:", "🔥"}, + {":droplet:", "💧"}, + {":ocean:", "🌊"}, + {":jack_o_lantern:", "🎃"}, + {":christmas_tree:", "🎄"}, + {":fireworks:", "🎆"}, + {":sparkler:", "🎇"}, + {":firecracker:", "🧨"}, + {":sparkles:", "✨"}, + {":balloon:", "🎈"}, + {":tada:", "🎉"}, + {":confetti_ball:", "🎊"}, + {":tanabata_tree:", "🎋"}, + {":bamboo:", "🎍"}, + {":dolls:", "🎎"}, + {":flags:", "🎏"}, + {":wind_chime:", "🎐"}, + {":rice_scene:", "🎑"}, + {":red_envelope:", "🧧"}, + {":ribbon:", "🎀"}, + {":gift:", "🎁"}, + {":reminder_ribbon:", "🎗️"}, + {":tickets:", "🎟️"}, + {":ticket:", "🎫"}, + {":medal_military:", "🎖️"}, + {":trophy:", "🏆"}, + {":medal_sports:", "🏅"}, + {":1st_place_medal:", "🥇"}, + {":2nd_place_medal:", "🥈"}, + {":3rd_place_medal:", "🥉"}, + {":soccer:", "⚽"}, + {":baseball:", "⚾"}, + {":softball:", "🥎"}, + {":basketball:", "🏀"}, + {":volleyball:", "🏐"}, + {":football:", "🏈"}, + {":rugby_football:", "🏉"}, + {":tennis:", "🎾"}, + {":flying_disc:", "🥏"}, + {":bowling:", "🎳"}, + {":cricket_game:", "🏏"}, + {":field_hockey:", "🏑"}, + {":ice_hockey:", "🏒"}, + {":lacrosse:", "🥍"}, + {":ping_pong:", "🏓"}, + {":badminton:", "🏸"}, + {":boxing_glove:", "🥊"}, + {":martial_arts_uniform:", "🥋"}, + {":goal_net:", "🥅"}, + {":golf:", "⛳"}, + {":ice_skate:", "⛸️"}, + {":fishing_pole_and_fish:", "🎣"}, + {":diving_mask:", "🤿"}, + {":running_shirt_with_sash:", "🎽"}, + {":ski:", "🎿"}, + {":sled:", "🛷"}, + {":curling_stone:", "🥌"}, + {":dart:", "🎯"}, + {":yo_yo:", "🪀"}, + {":kite:", "🪁"}, + {":8ball:", "🎱"}, + {":crystal_ball:", "🔮"}, + {":magic_wand:", "🪄"}, + {":nazar_amulet:", "🧿"}, + {":video_game:", "🎮"}, + {":joystick:", "🕹️"}, + {":slot_machine:", "🎰"}, + {":game_die:", "🎲"}, + {":jigsaw:", "🧩"}, + {":teddy_bear:", "🧸"}, + {":pi_ata:", "🪅"}, + {":nesting_dolls:", "🪆"}, + {":spades:", "♠️"}, + {":hearts:", "♥️"}, + {":diamonds:", "♦️"}, + {":clubs:", "♣️"}, + {":chess_pawn:", "♟️"}, + {":black_joker:", "🃏"}, + {":mahjong:", "🀄"}, + {":flower_playing_cards:", "🎴"}, + {":performing_arts:", "🎭"}, + {":framed_picture:", "🖼️"}, + {":art:", "🎨"}, + {":thread:", "🧵"}, + {":sewing_needle:", "🪡"}, + {":yarn:", "🧶"}, + {":knot:", "🪢"}, + {":eyeglasses:", "👓"}, + {":dark_sunglasses:", "🕶️"}, + {":goggles:", "🥽"}, + {":lab_coat:", "🥼"}, + {":safety_vest:", "🦺"}, + {":necktie:", "👔"}, + {":shirt:", "👕"}, + {":tshirt:", "👕"}, + {":jeans:", "👖"}, + {":scarf:", "🧣"}, + {":gloves:", "🧤"}, + {":coat:", "🧥"}, + {":socks:", "🧦"}, + {":dress:", "👗"}, + {":kimono:", "👘"}, + {":sari:", "🥻"}, + {":one_piece_swimsuit:", "🩱"}, + {":swim_brief:", "🩲"}, + {":shorts:", "🩳"}, + {":bikini:", "👙"}, + {":womans_clothes:", "👚"}, + {":purse:", "👛"}, + {":handbag:", "👜"}, + {":pouch:", "👝"}, + {":shopping:", "🛍️"}, + {":school_satchel:", "🎒"}, + {":thong_sandal:", "🩴"}, + {":mans_shoe:", "👞"}, + {":shoe:", "👞"}, + {":athletic_shoe:", "👟"}, + {":hiking_boot:", "🥾"}, + {":flat_shoe:", "🥿"}, + {":high_heel:", "👠"}, + {":sandal:", "👡"}, + {":ballet_shoes:", "🩰"}, + {":boot:", "👢"}, + {":crown:", "👑"}, + {":womans_hat:", "👒"}, + {":tophat:", "🎩"}, + {":mortar_board:", "🎓"}, + {":billed_cap:", "🧢"}, + {":military_helmet:", "🪖"}, + {":rescue_worker_helmet:", "⛑️"}, + {":prayer_beads:", "📿"}, + {":lipstick:", "💄"}, + {":ring:", "💍"}, + {":gem:", "💎"}, + {":mute:", "🔇"}, + {":speaker:", "🔈"}, + {":sound:", "🔉"}, + {":loud_sound:", "🔊"}, + {":loudspeaker:", "📢"}, + {":mega:", "📣"}, + {":postal_horn:", "📯"}, + {":bell:", "🔔"}, + {":no_bell:", "🔕"}, + {":musical_score:", "🎼"}, + {":musical_note:", "🎵"}, + {":notes:", "🎶"}, + {":studio_microphone:", "🎙️"}, + {":level_slider:", "🎚️"}, + {":control_knobs:", "🎛️"}, + {":microphone:", "🎤"}, + {":headphones:", "🎧"}, + {":radio:", "📻"}, + {":saxophone:", "🎷"}, + {":accordion:", "🪗"}, + {":guitar:", "🎸"}, + {":musical_keyboard:", "🎹"}, + {":trumpet:", "🎺"}, + {":violin:", "🎻"}, + {":banjo:", "🪕"}, + {":drum:", "🥁"}, + {":long_drum:", "🪘"}, + {":iphone:", "📱"}, + {":calling:", "📲"}, + {":phone:", "☎️"}, + {":telephone:", "☎️"}, + {":telephone_receiver:", "📞"}, + {":pager:", "📟"}, + {":fax:", "📠"}, + {":battery:", "🔋"}, + {":electric_plug:", "🔌"}, + {":computer:", "💻"}, + {":desktop_computer:", "🖥️"}, + {":printer:", "🖨️"}, + {":keyboard:", "⌨️"}, + {":computer_mouse:", "🖱️"}, + {":trackball:", "🖲️"}, + {":minidisc:", "💽"}, + {":floppy_disk:", "💾"}, + {":cd:", "💿"}, + {":dvd:", "📀"}, + {":abacus:", "🧮"}, + {":movie_camera:", "🎥"}, + {":film_strip:", "🎞️"}, + {":film_projector:", "📽️"}, + {":clapper:", "🎬"}, + {":tv:", "📺"}, + {":camera:", "📷"}, + {":camera_flash:", "📸"}, + {":video_camera:", "📹"}, + {":vhs:", "📼"}, + {":mag:", "🔍"}, + {":mag_right:", "🔎"}, + {":candle:", "🕯️"}, + {":bulb:", "💡"}, + {":flashlight:", "🔦"}, + {":izakaya_lantern:", "🏮"}, + {":lantern:", "🏮"}, + {":diya_lamp:", "🪔"}, + {":notebook_with_decorative_cover:", "📔"}, + {":closed_book:", "📕"}, + {":book:", "📖"}, + {":open_book:", "📖"}, + {":green_book:", "📗"}, + {":blue_book:", "📘"}, + {":orange_book:", "📙"}, + {":books:", "📚"}, + {":notebook:", "📓"}, + {":ledger:", "📒"}, + {":page_with_curl:", "📃"}, + {":scroll:", "📜"}, + {":page_facing_up:", "📄"}, + {":newspaper:", "📰"}, + {":newspaper_roll:", "🗞️"}, + {":bookmark_tabs:", "📑"}, + {":bookmark:", "🔖"}, + {":label:", "🏷️"}, + {":moneybag:", "💰"}, + {":coin:", "🪙"}, + {":yen:", "💴"}, + {":dollar:", "💵"}, + {":euro:", "💶"}, + {":pound:", "💷"}, + {":money_with_wings:", "💸"}, + {":credit_card:", "💳"}, + {":receipt:", "🧾"}, + {":chart:", "💹"}, + {":email:", "✉️"}, + {":envelope:", "✉️"}, + {":e-mail:", "📧"}, + {":incoming_envelope:", "📨"}, + {":envelope_with_arrow:", "📩"}, + {":outbox_tray:", "📤"}, + {":inbox_tray:", "📥"}, + {":package:", "📦"}, + {":mailbox:", "📫"}, + {":mailbox_closed:", "📪"}, + {":mailbox_with_mail:", "📬"}, + {":mailbox_with_no_mail:", "📭"}, + {":postbox:", "📮"}, + {":ballot_box:", "🗳️"}, + {":pencil2:", "✏️"}, + {":black_nib:", "✒️"}, + {":fountain_pen:", "🖋️"}, + {":pen:", "🖊️"}, + {":paintbrush:", "🖌️"}, + {":crayon:", "🖍️"}, + {":memo:", "📝"}, + {":pencil:", "📝"}, + {":briefcase:", "💼"}, + {":file_folder:", "📁"}, + {":open_file_folder:", "📂"}, + {":card_index_dividers:", "🗂️"}, + {":date:", "📅"}, + {":calendar:", "📆"}, + {":spiral_notepad:", "🗒️"}, + {":spiral_calendar:", "🗓️"}, + {":card_index:", "📇"}, + {":chart_with_upwards_trend:", "📈"}, + {":chart_with_downwards_trend:", "📉"}, + {":bar_chart:", "📊"}, + {":clipboard:", "📋"}, + {":pushpin:", "📌"}, + {":round_pushpin:", "📍"}, + {":paperclip:", "📎"}, + {":paperclips:", "🖇️"}, + {":straight_ruler:", "📏"}, + {":triangular_ruler:", "📐"}, + {":scissors:", "✂️"}, + {":card_file_box:", "🗃️"}, + {":file_cabinet:", "🗄️"}, + {":wastebasket:", "🗑️"}, + {":lock:", "🔒"}, + {":unlock:", "🔓"}, + {":lock_with_ink_pen:", "🔏"}, + {":closed_lock_with_key:", "🔐"}, + {":key:", "🔑"}, + {":old_key:", "🗝️"}, + {":hammer:", "🔨"}, + {":axe:", "🪓"}, + {":pick:", "⛏️"}, + {":hammer_and_pick:", "⚒️"}, + {":hammer_and_wrench:", "🛠️"}, + {":dagger:", "🗡️"}, + {":crossed_swords:", "⚔️"}, + {":gun:", "🔫"}, + {":boomerang:", "🪃"}, + {":bow_and_arrow:", "🏹"}, + {":shield:", "🛡️"}, + {":carpentry_saw:", "🪚"}, + {":wrench:", "🔧"}, + {":screwdriver:", "🪛"}, + {":nut_and_bolt:", "🔩"}, + {":gear:", "⚙️"}, + {":clamp:", "🗜️"}, + {":balance_scale:", "⚖️"}, + {":probing_cane:", "🦯"}, + {":link:", "🔗"}, + {":chains:", "⛓️"}, + {":hook:", "🪝"}, + {":toolbox:", "🧰"}, + {":magnet:", "🧲"}, + {":ladder:", "🪜"}, + {":alembic:", "⚗️"}, + {":test_tube:", "🧪"}, + {":petri_dish:", "🧫"}, + {":dna:", "🧬"}, + {":microscope:", "🔬"}, + {":telescope:", "🔭"}, + {":satellite:", "📡"}, + {":syringe:", "💉"}, + {":drop_of_blood:", "🩸"}, + {":pill:", "💊"}, + {":adhesive_bandage:", "🩹"}, + {":stethoscope:", "🩺"}, + {":door:", "🚪"}, + {":elevator:", "🛗"}, + {":mirror:", "🪞"}, + {":window:", "🪟"}, + {":bed:", "🛏️"}, + {":couch_and_lamp:", "🛋️"}, + {":chair:", "🪑"}, + {":toilet:", "🚽"}, + {":plunger:", "🪠"}, + {":shower:", "🚿"}, + {":bathtub:", "🛁"}, + {":mouse_trap:", "🪤"}, + {":razor:", "🪒"}, + {":lotion_bottle:", "🧴"}, + {":safety_pin:", "🧷"}, + {":broom:", "🧹"}, + {":basket:", "🧺"}, + {":roll_of_paper:", "🧻"}, + {":bucket:", "🪣"}, + {":soap:", "🧼"}, + {":toothbrush:", "🪥"}, + {":sponge:", "🧽"}, + {":fire_extinguisher:", "🧯"}, + {":shopping_cart:", "🛒"}, + {":smoking:", "🚬"}, + {":coffin:", "⚰️"}, + {":headstone:", "🪦"}, + {":funeral_urn:", "⚱️"}, + {":moyai:", "🗿"}, + {":placard:", "🪧"}, + {":atm:", "🏧"}, + {":put_litter_in_its_place:", "🚮"}, + {":potable_water:", "🚰"}, + {":wheelchair:", "♿"}, + {":mens:", "🚹"}, + {":womens:", "🚺"}, + {":restroom:", "🚻"}, + {":baby_symbol:", "🚼"}, + {":wc:", "🚾"}, + {":passport_control:", "🛂"}, + {":customs:", "🛃"}, + {":baggage_claim:", "🛄"}, + {":left_luggage:", "🛅"}, + {":warning:", "⚠️"}, + {":children_crossing:", "🚸"}, + {":no_entry:", "⛔"}, + {":no_entry_sign:", "🚫"}, + {":no_bicycles:", "🚳"}, + {":no_smoking:", "🚭"}, + {":do_not_litter:", "🚯"}, + {":non-potable_water:", "🚱"}, + {":no_pedestrians:", "🚷"}, + {":no_mobile_phones:", "📵"}, + {":underage:", "🔞"}, + {":radioactive:", "☢️"}, + {":biohazard:", "☣️"}, + {":arrow_up:", "⬆️"}, + {":arrow_upper_right:", "↗️"}, + {":arrow_right:", "➡️"}, + {":arrow_lower_right:", "↘️"}, + {":arrow_down:", "⬇️"}, + {":arrow_lower_left:", "↙️"}, + {":arrow_left:", "⬅️"}, + {":arrow_upper_left:", "↖️"}, + {":arrow_up_down:", "↕️"}, + {":left_right_arrow:", "↔️"}, + {":leftwards_arrow_with_hook:", "↩️"}, + {":arrow_right_hook:", "↪️"}, + {":arrow_heading_up:", "⤴️"}, + {":arrow_heading_down:", "⤵️"}, + {":arrows_clockwise:", "🔃"}, + {":arrows_counterclockwise:", "🔄"}, + {":back:", "🔙"}, + {":end:", "🔚"}, + {":on:", "🔛"}, + {":soon:", "🔜"}, + {":top:", "🔝"}, + {":place_of_worship:", "🛐"}, + {":atom_symbol:", "⚛️"}, + {":om:", "🕉️"}, + {":star_of_david:", "✡️"}, + {":wheel_of_dharma:", "☸️"}, + {":yin_yang:", "☯️"}, + {":latin_cross:", "✝️"}, + {":orthodox_cross:", "☦️"}, + {":star_and_crescent:", "☪️"}, + {":peace_symbol:", "☮️"}, + {":menorah:", "🕎"}, + {":six_pointed_star:", "🔯"}, + {":aries:", "♈"}, + {":taurus:", "♉"}, + {":gemini:", "♊"}, + {":cancer:", "♋"}, + {":leo:", "♌"}, + {":virgo:", "♍"}, + {":libra:", "♎"}, + {":scorpius:", "♏"}, + {":sagittarius:", "♐"}, + {":capricorn:", "♑"}, + {":aquarius:", "♒"}, + {":pisces:", "♓"}, + {":ophiuchus:", "⛎"}, + {":twisted_rightwards_arrows:", "🔀"}, + {":repeat:", "🔁"}, + {":repeat_one:", "🔂"}, + {":arrow_forward:", "▶️"}, + {":fast_forward:", "⏩"}, + {":next_track_button:", "⏭️"}, + {":play_or_pause_button:", "⏯️"}, + {":arrow_backward:", "◀️"}, + {":rewind:", "⏪"}, + {":previous_track_button:", "⏮️"}, + {":arrow_up_small:", "🔼"}, + {":arrow_double_up:", "⏫"}, + {":arrow_down_small:", "🔽"}, + {":arrow_double_down:", "⏬"}, + {":pause_button:", "⏸️"}, + {":stop_button:", "⏹️"}, + {":record_button:", "⏺️"}, + {":eject_button:", "⏏️"}, + {":cinema:", "🎦"}, + {":low_brightness:", "🔅"}, + {":high_brightness:", "🔆"}, + {":signal_strength:", "📶"}, + {":vibration_mode:", "📳"}, + {":mobile_phone_off:", "📴"}, + {":female_sign:", "♀️"}, + {":male_sign:", "♂️"}, + {":transgender_symbol:", "⚧️"}, + {":heavy_multiplication_x:", "✖️"}, + {":heavy_plus_sign:", "➕"}, + {":heavy_minus_sign:", "➖"}, + {":heavy_division_sign:", "➗"}, + {":infinity:", "♾️"}, + {":bangbang:", "‼️"}, + {":interrobang:", "⁉️"}, + {":question:", "❓"}, + {":grey_question:", "❔"}, + {":grey_exclamation:", "❕"}, + {":exclamation:", "❗"}, + {":heavy_exclamation_mark:", "❗"}, + {":wavy_dash:", "〰️"}, + {":currency_exchange:", "💱"}, + {":heavy_dollar_sign:", "💲"}, + {":medical_symbol:", "⚕️"}, + {":recycle:", "♻️"}, + {":fleur_de_lis:", "⚜️"}, + {":trident:", "🔱"}, + {":name_badge:", "📛"}, + {":beginner:", "🔰"}, + {":o:", "⭕"}, + {":white_check_mark:", "✅"}, + {":ballot_box_with_check:", "☑️"}, + {":heavy_check_mark:", "✔️"}, + {":x:", "❌"}, + {":negative_squared_cross_mark:", "❎"}, + {":curly_loop:", "➰"}, + {":loop:", "➿"}, + {":part_alternation_mark:", "〽️"}, + {":eight_spoked_asterisk:", "✳️"}, + {":eight_pointed_black_star:", "✴️"}, + {":sparkle:", "❇️"}, + {":copyright:", "©️"}, + {":registered:", "®️"}, + {":tm:", "™️"}, + {":hash:", "#️⃣"}, + {":asterisk:", "*️⃣"}, + {":zero:", "0️⃣"}, + {":one:", "1️⃣"}, + {":two:", "2️⃣"}, + {":three:", "3️⃣"}, + {":four:", "4️⃣"}, + {":five:", "5️⃣"}, + {":six:", "6️⃣"}, + {":seven:", "7️⃣"}, + {":eight:", "8️⃣"}, + {":nine:", "9️⃣"}, + {":keycap_ten:", "🔟"}, + {":capital_abcd:", "🔠"}, + {":abcd:", "🔡"}, + {":1234:", "🔢"}, + {":symbols:", "🔣"}, + {":abc:", "🔤"}, + {":a:", "🅰️"}, + {":ab:", "🆎"}, + {":b:", "🅱️"}, + {":cl:", "🆑"}, + {":cool:", "🆒"}, + {":free:", "🆓"}, + {":information_source:", "ℹ️"}, + {":id:", "🆔"}, + {":m:", "Ⓜ️"}, + {":new:", "🆕"}, + {":ng:", "🆖"}, + {":o2:", "🅾️"}, + {":ok:", "🆗"}, + {":parking:", "🅿️"}, + {":sos:", "🆘"}, + {":up:", "🆙"}, + {":vs:", "🆚"}, + {":koko:", "🈁"}, + {":sa:", "🈂️"}, + {":u6708:", "🈷️"}, + {":u6709:", "🈶"}, + {":u6307:", "🈯"}, + {":ideograph_advantage:", "🉐"}, + {":u5272:", "🈹"}, + {":u7121:", "🈚"}, + {":u7981:", "🈲"}, + {":accept:", "🉑"}, + {":u7533:", "🈸"}, + {":u5408:", "🈴"}, + {":u7a7a:", "🈳"}, + {":congratulations:", "㊗️"}, + {":secret:", "㊙️"}, + {":u55b6:", "🈺"}, + {":u6e80:", "🈵"}, + {":red_circle:", "🔴"}, + {":orange_circle:", "🟠"}, + {":yellow_circle:", "🟡"}, + {":green_circle:", "🟢"}, + {":large_blue_circle:", "🔵"}, + {":purple_circle:", "🟣"}, + {":brown_circle:", "🟤"}, + {":black_circle:", "⚫"}, + {":white_circle:", "⚪"}, + {":red_square:", "🟥"}, + {":orange_square:", "🟧"}, + {":yellow_square:", "🟨"}, + {":green_square:", "🟩"}, + {":blue_square:", "🟦"}, + {":purple_square:", "🟪"}, + {":brown_square:", "🟫"}, + {":black_large_square:", "⬛"}, + {":white_large_square:", "⬜"}, + {":black_medium_square:", "◼️"}, + {":white_medium_square:", "◻️"}, + {":black_medium_small_square:", "◾"}, + {":white_medium_small_square:", "◽"}, + {":black_small_square:", "▪️"}, + {":white_small_square:", "▫️"}, + {":large_orange_diamond:", "🔶"}, + {":large_blue_diamond:", "🔷"}, + {":small_orange_diamond:", "🔸"}, + {":small_blue_diamond:", "🔹"}, + {":small_red_triangle:", "🔺"}, + {":small_red_triangle_down:", "🔻"}, + {":diamond_shape_with_a_dot_inside:", "💠"}, + {":radio_button:", "🔘"}, + {":white_square_button:", "🔳"}, + {":black_square_button:", "🔲"}, + {":checkered_flag:", "🏁"}, + {":triangular_flag_on_post:", "🚩"}, + {":crossed_flags:", "🎌"}, + {":black_flag:", "🏴"}, + {":white_flag:", "🏳️"}, + {":rainbow_flag:", "🏳️‍🌈"}, + {":transgender_flag:", "🏳️‍⚧️"}, + {":pirate_flag:", "🏴‍☠️"}, + {":ascension_island:", "🇦🇨"}, + {":andorra:", "🇦🇩"}, + {":united_arab_emirates:", "🇦🇪"}, + {":afghanistan:", "🇦🇫"}, + {":antigua_barbuda:", "🇦🇬"}, + {":anguilla:", "🇦🇮"}, + {":albania:", "🇦🇱"}, + {":armenia:", "🇦🇲"}, + {":angola:", "🇦🇴"}, + {":antarctica:", "🇦🇶"}, + {":argentina:", "🇦🇷"}, + {":american_samoa:", "🇦🇸"}, + {":austria:", "🇦🇹"}, + {":australia:", "🇦🇺"}, + {":aruba:", "🇦🇼"}, + {":aland_islands:", "🇦🇽"}, + {":azerbaijan:", "🇦🇿"}, + {":bosnia_herzegovina:", "🇧🇦"}, + {":barbados:", "🇧🇧"}, + {":bangladesh:", "🇧🇩"}, + {":belgium:", "🇧🇪"}, + {":burkina_faso:", "🇧🇫"}, + {":bulgaria:", "🇧🇬"}, + {":bahrain:", "🇧🇭"}, + {":burundi:", "🇧🇮"}, + {":benin:", "🇧🇯"}, + {":st_barthelemy:", "🇧🇱"}, + {":bermuda:", "🇧🇲"}, + {":brunei:", "🇧🇳"}, + {":bolivia:", "🇧🇴"}, + {":caribbean_netherlands:", "🇧🇶"}, + {":brazil:", "🇧🇷"}, + {":bahamas:", "🇧🇸"}, + {":bhutan:", "🇧🇹"}, + {":bouvet_island:", "🇧🇻"}, + {":botswana:", "🇧🇼"}, + {":belarus:", "🇧🇾"}, + {":belize:", "🇧🇿"}, + {":canada:", "🇨🇦"}, + {":cocos_islands:", "🇨🇨"}, + {":congo_kinshasa:", "🇨🇩"}, + {":central_african_republic:", "🇨🇫"}, + {":congo_brazzaville:", "🇨🇬"}, + {":switzerland:", "🇨🇭"}, + {":cote_divoire:", "🇨🇮"}, + {":cook_islands:", "🇨🇰"}, + {":chile:", "🇨🇱"}, + {":cameroon:", "🇨🇲"}, + {":cn:", "🇨🇳"}, + {":colombia:", "🇨🇴"}, + {":clipperton_island:", "🇨🇵"}, + {":costa_rica:", "🇨🇷"}, + {":cuba:", "🇨🇺"}, + {":cape_verde:", "🇨🇻"}, + {":curacao:", "🇨🇼"}, + {":christmas_island:", "🇨🇽"}, + {":cyprus:", "🇨🇾"}, + {":czech_republic:", "🇨🇿"}, + {":de:", "🇩🇪"}, + {":diego_garcia:", "🇩🇬"}, + {":djibouti:", "🇩🇯"}, + {":denmark:", "🇩🇰"}, + {":dominica:", "🇩🇲"}, + {":dominican_republic:", "🇩🇴"}, + {":algeria:", "🇩🇿"}, + {":ceuta_melilla:", "🇪🇦"}, + {":ecuador:", "🇪🇨"}, + {":estonia:", "🇪🇪"}, + {":egypt:", "🇪🇬"}, + {":western_sahara:", "🇪🇭"}, + {":eritrea:", "🇪🇷"}, + {":es:", "🇪🇸"}, + {":ethiopia:", "🇪🇹"}, + {":eu:", "🇪🇺"}, + {":european_union:", "🇪🇺"}, + {":finland:", "🇫🇮"}, + {":fiji:", "🇫🇯"}, + {":falkland_islands:", "🇫🇰"}, + {":micronesia:", "🇫🇲"}, + {":faroe_islands:", "🇫🇴"}, + {":fr:", "🇫🇷"}, + {":gabon:", "🇬🇦"}, + {":gb:", "🇬🇧"}, + {":uk:", "🇬🇧"}, + {":grenada:", "🇬🇩"}, + {":georgia:", "🇬🇪"}, + {":french_guiana:", "🇬🇫"}, + {":guernsey:", "🇬🇬"}, + {":ghana:", "🇬🇭"}, + {":gibraltar:", "🇬🇮"}, + {":greenland:", "🇬🇱"}, + {":gambia:", "🇬🇲"}, + {":guinea:", "🇬🇳"}, + {":guadeloupe:", "🇬🇵"}, + {":equatorial_guinea:", "🇬🇶"}, + {":greece:", "🇬🇷"}, + {":south_georgia_south_sandwich_islands:", "🇬🇸"}, + {":guatemala:", "🇬🇹"}, + {":guam:", "🇬🇺"}, + {":guinea_bissau:", "🇬🇼"}, + {":guyana:", "🇬🇾"}, + {":hong_kong:", "🇭🇰"}, + {":heard_mcdonald_islands:", "🇭🇲"}, + {":honduras:", "🇭🇳"}, + {":croatia:", "🇭🇷"}, + {":haiti:", "🇭🇹"}, + {":hungary:", "🇭🇺"}, + {":canary_islands:", "🇮🇨"}, + {":indonesia:", "🇮🇩"}, + {":ireland:", "🇮🇪"}, + {":israel:", "🇮🇱"}, + {":isle_of_man:", "🇮🇲"}, + {":india:", "🇮🇳"}, + {":british_indian_ocean_territory:", "🇮🇴"}, + {":iraq:", "🇮🇶"}, + {":iran:", "🇮🇷"}, + {":iceland:", "🇮🇸"}, + {":it:", "🇮🇹"}, + {":jersey:", "🇯🇪"}, + {":jamaica:", "🇯🇲"}, + {":jordan:", "🇯🇴"}, + {":jp:", "🇯🇵"}, + {":kenya:", "🇰🇪"}, + {":kyrgyzstan:", "🇰🇬"}, + {":cambodia:", "🇰🇭"}, + {":kiribati:", "🇰🇮"}, + {":comoros:", "🇰🇲"}, + {":st_kitts_nevis:", "🇰🇳"}, + {":north_korea:", "🇰🇵"}, + {":kr:", "🇰🇷"}, + {":kuwait:", "🇰🇼"}, + {":cayman_islands:", "🇰🇾"}, + {":kazakhstan:", "🇰🇿"}, + {":laos:", "🇱🇦"}, + {":lebanon:", "🇱🇧"}, + {":st_lucia:", "🇱🇨"}, + {":liechtenstein:", "🇱🇮"}, + {":sri_lanka:", "🇱🇰"}, + {":liberia:", "🇱🇷"}, + {":lesotho:", "🇱🇸"}, + {":lithuania:", "🇱🇹"}, + {":luxembourg:", "🇱🇺"}, + {":latvia:", "🇱🇻"}, + {":libya:", "🇱🇾"}, + {":morocco:", "🇲🇦"}, + {":monaco:", "🇲🇨"}, + {":moldova:", "🇲🇩"}, + {":montenegro:", "🇲🇪"}, + {":st_martin:", "🇲🇫"}, + {":madagascar:", "🇲🇬"}, + {":marshall_islands:", "🇲🇭"}, + {":macedonia:", "🇲🇰"}, + {":mali:", "🇲🇱"}, + {":myanmar:", "🇲🇲"}, + {":mongolia:", "🇲🇳"}, + {":macau:", "🇲🇴"}, + {":northern_mariana_islands:", "🇲🇵"}, + {":martinique:", "🇲🇶"}, + {":mauritania:", "🇲🇷"}, + {":montserrat:", "🇲🇸"}, + {":malta:", "🇲🇹"}, + {":mauritius:", "🇲🇺"}, + {":maldives:", "🇲🇻"}, + {":malawi:", "🇲🇼"}, + {":mexico:", "🇲🇽"}, + {":malaysia:", "🇲🇾"}, + {":mozambique:", "🇲🇿"}, + {":namibia:", "🇳🇦"}, + {":new_caledonia:", "🇳🇨"}, + {":niger:", "🇳🇪"}, + {":norfolk_island:", "🇳🇫"}, + {":nigeria:", "🇳🇬"}, + {":nicaragua:", "🇳🇮"}, + {":netherlands:", "🇳🇱"}, + {":norway:", "🇳🇴"}, + {":nepal:", "🇳🇵"}, + {":nauru:", "🇳🇷"}, + {":niue:", "🇳🇺"}, + {":new_zealand:", "🇳🇿"}, + {":oman:", "🇴🇲"}, + {":panama:", "🇵🇦"}, + {":peru:", "🇵🇪"}, + {":french_polynesia:", "🇵🇫"}, + {":papua_new_guinea:", "🇵🇬"}, + {":philippines:", "🇵🇭"}, + {":pakistan:", "🇵🇰"}, + {":poland:", "🇵🇱"}, + {":st_pierre_miquelon:", "🇵🇲"}, + {":pitcairn_islands:", "🇵🇳"}, + {":puerto_rico:", "🇵🇷"}, + {":palestinian_territories:", "🇵🇸"}, + {":portugal:", "🇵🇹"}, + {":palau:", "🇵🇼"}, + {":paraguay:", "🇵🇾"}, + {":qatar:", "🇶🇦"}, + {":reunion:", "🇷🇪"}, + {":romania:", "🇷🇴"}, + {":serbia:", "🇷🇸"}, + {":ru:", "🇷🇺"}, + {":rwanda:", "🇷🇼"}, + {":saudi_arabia:", "🇸🇦"}, + {":solomon_islands:", "🇸🇧"}, + {":seychelles:", "🇸🇨"}, + {":sudan:", "🇸🇩"}, + {":sweden:", "🇸🇪"}, + {":singapore:", "🇸🇬"}, + {":st_helena:", "🇸🇭"}, + {":slovenia:", "🇸🇮"}, + {":svalbard_jan_mayen:", "🇸🇯"}, + {":slovakia:", "🇸🇰"}, + {":sierra_leone:", "🇸🇱"}, + {":san_marino:", "🇸🇲"}, + {":senegal:", "🇸🇳"}, + {":somalia:", "🇸🇴"}, + {":suriname:", "🇸🇷"}, + {":south_sudan:", "🇸🇸"}, + {":sao_tome_principe:", "🇸🇹"}, + {":el_salvador:", "🇸🇻"}, + {":sint_maarten:", "🇸🇽"}, + {":syria:", "🇸🇾"}, + {":swaziland:", "🇸🇿"}, + {":tristan_da_cunha:", "🇹🇦"}, + {":turks_caicos_islands:", "🇹🇨"}, + {":chad:", "🇹🇩"}, + {":french_southern_territories:", "🇹🇫"}, + {":togo:", "🇹🇬"}, + {":thailand:", "🇹🇭"}, + {":tajikistan:", "🇹🇯"}, + {":tokelau:", "🇹🇰"}, + {":timor_leste:", "🇹🇱"}, + {":turkmenistan:", "🇹🇲"}, + {":tunisia:", "🇹🇳"}, + {":tonga:", "🇹🇴"}, + {":tr:", "🇹🇷"}, + {":trinidad_tobago:", "🇹🇹"}, + {":tuvalu:", "🇹🇻"}, + {":taiwan:", "🇹🇼"}, + {":tanzania:", "🇹🇿"}, + {":ukraine:", "🇺🇦"}, + {":uganda:", "🇺🇬"}, + {":us_outlying_islands:", "🇺🇲"}, + {":united_nations:", "🇺🇳"}, + {":us:", "🇺🇸"}, + {":uruguay:", "🇺🇾"}, + {":uzbekistan:", "🇺🇿"}, + {":vatican_city:", "🇻🇦"}, + {":st_vincent_grenadines:", "🇻🇨"}, + {":venezuela:", "🇻🇪"}, + {":british_virgin_islands:", "🇻🇬"}, + {":us_virgin_islands:", "🇻🇮"}, + {":vietnam:", "🇻🇳"}, + {":vanuatu:", "🇻🇺"}, + {":wallis_futuna:", "🇼🇫"}, + {":samoa:", "🇼🇸"}, + {":kosovo:", "🇽🇰"}, + {":yemen:", "🇾🇪"}, + {":mayotte:", "🇾🇹"}, + {":south_africa:", "🇿🇦"}, + {":zambia:", "🇿🇲"}, + {":zimbabwe:", "🇿🇼"}, + {":england:", "🏴󠁧󠁢󠁥󠁮󠁧󠁿"}, + {":scotland:", "🏴󠁧󠁢󠁳󠁣󠁴󠁿"}, + {":wales:", "🏴󠁧󠁢󠁷󠁬󠁳󠁿"}, + {NULL, NULL} +}; + +#endif diff --git a/client/emojis_alt.h b/client/emojis_alt.h new file mode 100644 index 000000000..9d11f73b9 --- /dev/null +++ b/client/emojis_alt.h @@ -0,0 +1,15 @@ +#ifndef EMOJIS_ALT_H__ +#define EMOJIS_ALT_H__ + +typedef struct emoji_alt_s { + const char *alias; + const char *alttext; +} emoji_alt_t; +// emoji_alt_t array are expected to be NULL terminated + +static emoji_alt_t EmojiAltTable[] = { + {":wink:", ";)"}, + {NULL, NULL} +}; + +#endif diff --git a/client/emojis_scrap_github.py b/client/emojis_scrap_github.py new file mode 100755 index 000000000..777bf8aa5 --- /dev/null +++ b/client/emojis_scrap_github.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python3 + +# Mostly derived from https://github.com/mrowa44/emojify Copyright (c) 2015 Justyna Rachowicz + +from urllib.request import urlopen +import json + + +EMOJI_JSON_URL = 'https://raw.githubusercontent.com/github/gemoji/master/db/emoji.json' + +def print_emoji(emoji_json): + for alias in emoji_json['aliases']: + print(' {{":{0}:", "{1}"}},'.format(alias, emoji_json['emoji'])) + +print( +"""#ifndef EMOJIS_H__ +#define EMOJIS_H__ + +typedef struct emoji_s { + const char *alias; + const char *emoji; +} emoji_t; +// emoji_t array are expected to be NULL terminated + +static emoji_t EmojiTable[] = {""") +with urlopen(EMOJI_JSON_URL) as conn: + emojis_json = json.loads(conn.read().decode('utf-8')) + for emoji_json in emojis_json: + print_emoji(emoji_json) + +print( +""" {NULL, NULL} +}; + +#endif""") diff --git a/client/proxmark3.c b/client/proxmark3.c index 522d982c7..c21852852 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -36,7 +36,7 @@ static void showBanner(void) { PrintAndLogEx(NORMAL, " " _BLUE_("██████╗ ███╗ ███╗ ████╗ ")); PrintAndLogEx(NORMAL, " " _BLUE_("██╔══██╗████╗ ████║ ══█║")); PrintAndLogEx(NORMAL, " " _BLUE_("██████╔╝██╔████╔██║ ████╔╝")); - PrintAndLogEx(NORMAL, " " _BLUE_("██╔═══╝ ██║╚██╔╝██║ ══█║") " iceman@icesql.net"); + PrintAndLogEx(NORMAL, " " _BLUE_("██╔═══╝ ██║╚██╔╝██║ ══█║") " :snowflake: iceman@icesql.net"); PrintAndLogEx(NORMAL, " " _BLUE_("██║ ██║ ╚═╝ ██║ ████╔╝") " https://github.com/rfidresearchgroup/proxmark3/"); PrintAndLogEx(NORMAL, " " _BLUE_("╚═╝ ╚═╝ ╚═╝ ╚═══╝ ") "pre-release v4.0"); #else @@ -756,6 +756,7 @@ int main(int argc, char *argv[]) { } session.supports_colors = DetectWindowsAnsiSupport(); + session.emoji_mode = ALTTEXT; session.stdinOnTTY = isatty(STDIN_FILENO); session.stdoutOnTTY = isatty(STDOUT_FILENO); @@ -766,8 +767,10 @@ int main(int argc, char *argv[]) { // For info, grep --color=auto is doing sth like this, plus test getenv("TERM") != "dumb": // struct stat tmp_stat; // if ((fstat (STDOUT_FILENO, &tmp_stat) == 0) && (S_ISCHR (tmp_stat.st_mode)) && isatty(STDIN_FILENO)) - if (session.stdinOnTTY && session.stdoutOnTTY) + if (session.stdinOnTTY && session.stdoutOnTTY) { session.supports_colors = true; + session.emoji_mode = EMOJI; + } #endif // Let's take a baudrate ok for real UART, USB-CDC & BT don't use that info anyway if (speed == 0) diff --git a/client/ui.c b/client/ui.c index 91a2a49e6..1c04def6c 100644 --- a/client/ui.c +++ b/client/ui.c @@ -31,6 +31,8 @@ # include // _mkdir #endif #include +#include "emojis.h" +#include "emojis_alt.h" session_arg_t session; double CursorScaleFactor = 1; @@ -132,39 +134,66 @@ void PrintAndLogEx(logLevel_t level, const char *fmt, ...) { if (g_showhints == 0 && level == HINT) return; - char prefix[20] = {0}; + char prefix[40] = {0}; char buffer[MAX_PRINT_BUFFER] = {0}; - char buffer2[MAX_PRINT_BUFFER + 20] = {0}; + char buffer2[MAX_PRINT_BUFFER + sizeof(prefix)] = {0}; char *token = NULL; char *tmp_ptr = NULL; FILE *stream = stdout; const char *spinner[] = {_YELLOW_("[\\]"), _YELLOW_("[|]"), _YELLOW_("[/]"), _YELLOW_("[-]")}; + const char *spinner_emoji[] = {" :clock1: ", " :clock2: ", " :clock3: ", " :clock4: ", " :clock5: ", " :clock6: ", + " :clock7: ", " :clock8: ", " :clock9: ", " :clock10: ", " :clock11: ", " :clock12: "}; switch (level) { case ERR: - strncpy(prefix, _RED_("[!!]"), sizeof(prefix) - 1); + if (session.emoji_mode == EMOJI) + strncpy(prefix, " :rotating_light: ", sizeof(prefix) - 1); + else + strncpy(prefix, _RED_("[!!]"), sizeof(prefix) - 1); stream = stderr; break; case FAILED: - strncpy(prefix, _RED_("[-]"), sizeof(prefix) - 1); + if (session.emoji_mode == EMOJI) + strncpy(prefix, " :no_entry: ", sizeof(prefix) - 1); + else + strncpy(prefix, _RED_("[-]"), sizeof(prefix) - 1); break; case DEBUG: - strncpy(prefix, _BLUE_("[#]"), sizeof(prefix) - 1); + if (session.emoji_mode == EMOJI) + strncpy(prefix, " :speech_balloon: ", sizeof(prefix) - 1); + else + strncpy(prefix, _BLUE_("[#]"), sizeof(prefix) - 1); break; case HINT: case SUCCESS: - strncpy(prefix, _GREEN_("[+]"), sizeof(prefix) - 1); + if (session.emoji_mode == EMOJI) + strncpy(prefix, " :star: ", sizeof(prefix) - 1); + else + strncpy(prefix, _GREEN_("[+]"), sizeof(prefix) - 1); break; case WARNING: - strncpy(prefix, _CYAN_("[!]"), sizeof(prefix) - 1); + if (session.emoji_mode == EMOJI) + strncpy(prefix, " :warning: ", sizeof(prefix) - 1); + else + strncpy(prefix, _CYAN_("[!]"), sizeof(prefix) - 1); break; case INFO: - strncpy(prefix, _YELLOW_("[=]"), sizeof(prefix) - 1); + if (session.emoji_mode == EMOJI) + strncpy(prefix, " :information_source: ", sizeof(prefix) - 1); + else + strncpy(prefix, _YELLOW_("[=]"), sizeof(prefix) - 1); break; case INPLACE: - strncpy(prefix, spinner[PrintAndLogEx_spinidx], sizeof(prefix) - 1); - PrintAndLogEx_spinidx++; - if (PrintAndLogEx_spinidx == ARRAYLEN(spinner)) - PrintAndLogEx_spinidx = 0; + if (session.emoji_mode == EMOJI) { + strncpy(prefix, spinner_emoji[PrintAndLogEx_spinidx], sizeof(prefix) - 1); + PrintAndLogEx_spinidx++; + if (PrintAndLogEx_spinidx >= ARRAYLEN(spinner_emoji)) + PrintAndLogEx_spinidx = 0; + } else { + strncpy(prefix, spinner[PrintAndLogEx_spinidx], sizeof(prefix) - 1); + PrintAndLogEx_spinidx++; + if (PrintAndLogEx_spinidx >= ARRAYLEN(spinner)) + PrintAndLogEx_spinidx = 0; + } break; case NORMAL: // no prefixes for normal @@ -207,9 +236,11 @@ void PrintAndLogEx(logLevel_t level, const char *fmt, ...) { } else { snprintf(buffer2, sizeof(buffer2), "%s%s", prefix, buffer); if (level == INPLACE) { - char buffer3[MAX_PRINT_BUFFER + 20] = {0}; + char buffer3[sizeof(buffer2)] = {0}; + char buffer4[sizeof(buffer2)] = {0}; memcpy_filter_ansi(buffer3, buffer2, sizeof(buffer2), !session.supports_colors); - fprintf(stream, "\r%s", buffer3); + memcpy_filter_emoji(buffer4, buffer3, sizeof(buffer3), session.emoji_mode); + fprintf(stream, "\r%s", buffer4); fflush(stream); } else { fPrintAndLog(stream, "%s", buffer2); @@ -225,6 +256,7 @@ static void fPrintAndLog(FILE *stream, const char *fmt, ...) { static int logging = 1; char buffer[MAX_PRINT_BUFFER] = {0}; char buffer2[MAX_PRINT_BUFFER] = {0}; + char buffer3[MAX_PRINT_BUFFER] = {0}; // lock this section to avoid interlacing prints from different threads pthread_mutex_lock(&print_lock); @@ -281,7 +313,8 @@ static void fPrintAndLog(FILE *stream, const char *fmt, ...) { bool filter_ansi = !session.supports_colors; memcpy_filter_ansi(buffer2, buffer, sizeof(buffer), filter_ansi); if (g_printAndLog & PRINTANDLOG_PRINT) { - fprintf(stream, "%s", buffer2); + memcpy_filter_emoji(buffer3, buffer2, sizeof(buffer2), session.emoji_mode); + fprintf(stream, "%s", buffer3); fprintf(stream, " "); // cleaning prompt fprintf(stream, "\n"); } @@ -356,6 +389,102 @@ void memcpy_filter_ansi(void *dest, const void *src, size_t n, bool filter) { } } +static bool emojify_token(const char *token, uint8_t token_length, const char **emojified_token, uint8_t *emojified_token_length, emojiMode_t mode) { + int i = 0; + while (EmojiTable[i].alias) { + if ((strlen(EmojiTable[i].alias) == token_length) && (0 == memcmp(EmojiTable[i].alias, token, token_length))) { + switch (mode) { + case EMOJI: { + *emojified_token = EmojiTable[i].emoji; + *emojified_token_length = strlen(EmojiTable[i].emoji); + break; + } + case ALTTEXT: { + int j = 0; + *emojified_token_length = 0; + while (EmojiAltTable[j].alias) { + if ((strlen(EmojiAltTable[j].alias) == token_length) && (0 == memcmp(EmojiAltTable[j].alias, token, token_length))) { + *emojified_token = EmojiAltTable[j].alttext; + *emojified_token_length = strlen(EmojiAltTable[j].alttext); + break; + } + ++j; + } + break; + } + default: {// ERASE + *emojified_token_length = 0; + break; + } + } + return true; + } + ++i; + } + return false; +} + +static bool token_charset(uint8_t c) { + if ((c >= '0') && (c <= '9')) return true; + if ((c >= 'a') && (c <= 'z')) return true; + if ((c >= 'A') && (c <= 'Z')) return true; + if ((c == '_') || (c == '+') || (c == '-')) return true; + return false; +} + +void memcpy_filter_emoji(void *dest, const void *src, size_t n, emojiMode_t mode) { + if (mode == ALIAS) { + memcpy(dest, src, n); + } else { + // tokenize emoji + const char *emojified_token = NULL; + uint8_t emojified_token_length = 0; + char *current_token = NULL; + uint8_t current_token_length=0; + char current_char; + char *rdest = (char *)dest; + char *rsrc = (char *)src; + uint16_t si = 0; + for (uint16_t i = 0; i < n; i++) { + current_char = rsrc[i]; + + if (current_token_length == 0) { + // starting a new token. + if (current_char == ':') { + current_token = rsrc + i; + current_token_length = 1; + } else { // not starting a new token. + rdest[si++] = current_char; + } + } else { + // finishing the current token. + if (current_char == ':') { + // nothing changed? we still need the ending ':' as it might serve for an upcoming emoji + if (! emojify_token(current_token, current_token_length + 1, &emojified_token, &emojified_token_length, mode)) { + memcpy(rdest + si, current_token, current_token_length); + si += current_token_length; + current_token = rsrc + i; + current_token_length = 1; + } else { + memcpy(rdest + si, emojified_token, emojified_token_length); + si += emojified_token_length; + current_token_length = 0; + } + } else if (token_charset(current_char)) { // continuing the current token. + current_token_length++; + } else { // dropping the current token. + current_token_length++; + memcpy(rdest + si, current_token, current_token_length); + si += current_token_length; + current_token_length = 0; + } + } + } + memcpy(rdest + si, current_token, current_token_length); + si += current_token_length; + } +} + void iceIIR_Butterworth(int *data, const size_t len) { int *output = (int *) calloc(sizeof(int) * len, sizeof(uint8_t)); diff --git a/client/ui.h b/client/ui.h index c67865593..3b07caf46 100644 --- a/client/ui.h +++ b/client/ui.h @@ -17,10 +17,14 @@ #define _USE_MATH_DEFINES +typedef enum logLevel {NORMAL, SUCCESS, INFO, FAILED, WARNING, ERR, DEBUG, INPLACE, HINT} logLevel_t; +typedef enum emojiMode {ALIAS, EMOJI, ALTTEXT, ERASE} emojiMode_t; + typedef struct { bool stdinOnTTY; bool stdoutOnTTY; bool supports_colors; + emojiMode_t emoji_mode; bool pm3_present; bool help_dump_mode; } session_arg_t; @@ -31,7 +35,6 @@ extern session_arg_t session; #define M_PI 3.14159265358979323846264338327 #endif #define MAX_PRINT_BUFFER 2048 -typedef enum logLevel {NORMAL, SUCCESS, INFO, FAILED, WARNING, ERR, DEBUG, INPLACE, HINT} logLevel_t; void ShowGui(void); void HideGraphWindow(void); @@ -41,6 +44,7 @@ void PrintAndLogOptions(const char *str[][2], size_t size, size_t space); void PrintAndLogEx(logLevel_t level, const char *fmt, ...); void SetFlushAfterWrite(bool value); void memcpy_filter_ansi(void *dest, const void *src, size_t n, bool filter); +void memcpy_filter_emoji(void *dest, const void *src, size_t n, emojiMode_t mode); extern double CursorScaleFactor; extern int PlotGridX, PlotGridY, PlotGridXdefault, PlotGridYdefault, GridOffset; From 82b3bfd936d85bd89efbdc41075fcd10ed5111dc Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 16 Mar 2020 11:38:13 +0100 Subject: [PATCH 1706/1854] :smiling_imp: support in changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1066a1f92..2b75de3ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - :smiling_imp: support (@doegox) - Additional colour changes as recommended by @iceman (@dunderhay) - Change type colour for `hf 14a` card types (@dunderhay) - Add colour to `hf mfdes` command (@dunderhay) From 9ebfe0908f1557476becbc4f1a773b114010f6c0 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 16 Mar 2020 17:47:13 +0100 Subject: [PATCH 1707/1854] Prevent emoji on ProxSpace --- client/emojis.h | 3697 ++++++++++++++++----------------- client/emojis_scrap_github.py | 11 +- client/ui.c | 4 +- 3 files changed, 1857 insertions(+), 1855 deletions(-) diff --git a/client/emojis.h b/client/emojis.h index b7ef0e92a..2e5a75c62 100644 --- a/client/emojis.h +++ b/client/emojis.h @@ -8,1855 +8,1854 @@ typedef struct emoji_s { // emoji_t array are expected to be NULL terminated static emoji_t EmojiTable[] = { - {":grinning:", "😀"}, - {":smiley:", "😃"}, - {":smile:", "😄"}, - {":grin:", "😁"}, - {":laughing:", "😆"}, - {":satisfied:", "😆"}, - {":sweat_smile:", "😅"}, - {":rofl:", "🤣"}, - {":joy:", "😂"}, - {":slightly_smiling_face:", "🙂"}, - {":upside_down_face:", "🙃"}, - {":wink:", "😉"}, - {":blush:", "😊"}, - {":innocent:", "😇"}, - {":smiling_face_with_three_hearts:", "🥰"}, - {":heart_eyes:", "😍"}, - {":star_struck:", "🤩"}, - {":kissing_heart:", "😘"}, - {":kissing:", "😗"}, - {":relaxed:", "☺️"}, - {":kissing_closed_eyes:", "😚"}, - {":kissing_smiling_eyes:", "😙"}, - {":smiling_face_with_tear:", "🥲"}, - {":yum:", "😋"}, - {":stuck_out_tongue:", "😛"}, - {":stuck_out_tongue_winking_eye:", "😜"}, - {":zany_face:", "🤪"}, - {":stuck_out_tongue_closed_eyes:", "😝"}, - {":money_mouth_face:", "🤑"}, - {":hugs:", "🤗"}, - {":hand_over_mouth:", "🤭"}, - {":shushing_face:", "🤫"}, - {":thinking:", "🤔"}, - {":zipper_mouth_face:", "🤐"}, - {":raised_eyebrow:", "🤨"}, - {":neutral_face:", "😐"}, - {":expressionless:", "😑"}, - {":no_mouth:", "😶"}, - {":smirk:", "😏"}, - {":unamused:", "😒"}, - {":roll_eyes:", "🙄"}, - {":grimacing:", "😬"}, - {":lying_face:", "🤥"}, - {":relieved:", "😌"}, - {":pensive:", "😔"}, - {":sleepy:", "😪"}, - {":drooling_face:", "🤤"}, - {":sleeping:", "😴"}, - {":mask:", "😷"}, - {":face_with_thermometer:", "🤒"}, - {":face_with_head_bandage:", "🤕"}, - {":nauseated_face:", "🤢"}, - {":vomiting_face:", "🤮"}, - {":sneezing_face:", "🤧"}, - {":hot_face:", "🥵"}, - {":cold_face:", "🥶"}, - {":woozy_face:", "🥴"}, - {":dizzy_face:", "😵"}, - {":exploding_head:", "🤯"}, - {":cowboy_hat_face:", "🤠"}, - {":partying_face:", "🥳"}, - {":disguised_face:", "🥸"}, - {":sunglasses:", "😎"}, - {":nerd_face:", "🤓"}, - {":monocle_face:", "🧐"}, - {":confused:", "😕"}, - {":worried:", "😟"}, - {":slightly_frowning_face:", "🙁"}, - {":frowning_face:", "☹️"}, - {":open_mouth:", "😮"}, - {":hushed:", "😯"}, - {":astonished:", "😲"}, - {":flushed:", "😳"}, - {":pleading_face:", "🥺"}, - {":frowning:", "😦"}, - {":anguished:", "😧"}, - {":fearful:", "😨"}, - {":cold_sweat:", "😰"}, - {":disappointed_relieved:", "😥"}, - {":cry:", "😢"}, - {":sob:", "😭"}, - {":scream:", "😱"}, - {":confounded:", "😖"}, - {":persevere:", "😣"}, - {":disappointed:", "😞"}, - {":sweat:", "😓"}, - {":weary:", "😩"}, - {":tired_face:", "😫"}, - {":yawning_face:", "🥱"}, - {":triumph:", "😤"}, - {":rage:", "😡"}, - {":pout:", "😡"}, - {":angry:", "😠"}, - {":cursing_face:", "🤬"}, - {":smiling_imp:", "😈"}, - {":imp:", "👿"}, - {":skull:", "💀"}, - {":skull_and_crossbones:", "☠️"}, - {":hankey:", "💩"}, - {":poop:", "💩"}, - {":shit:", "💩"}, - {":clown_face:", "🤡"}, - {":japanese_ogre:", "👹"}, - {":japanese_goblin:", "👺"}, - {":ghost:", "👻"}, - {":alien:", "👽"}, - {":space_invader:", "👾"}, - {":robot:", "🤖"}, - {":smiley_cat:", "😺"}, - {":smile_cat:", "😸"}, - {":joy_cat:", "😹"}, - {":heart_eyes_cat:", "😻"}, - {":smirk_cat:", "😼"}, - {":kissing_cat:", "😽"}, - {":scream_cat:", "🙀"}, - {":crying_cat_face:", "😿"}, - {":pouting_cat:", "😾"}, - {":see_no_evil:", "🙈"}, - {":hear_no_evil:", "🙉"}, - {":speak_no_evil:", "🙊"}, - {":kiss:", "💋"}, - {":love_letter:", "💌"}, - {":cupid:", "💘"}, - {":gift_heart:", "💝"}, - {":sparkling_heart:", "💖"}, - {":heartpulse:", "💗"}, - {":heartbeat:", "💓"}, - {":revolving_hearts:", "💞"}, - {":two_hearts:", "💕"}, - {":heart_decoration:", "💟"}, - {":heavy_heart_exclamation:", "❣️"}, - {":broken_heart:", "💔"}, - {":heart:", "❤️"}, - {":orange_heart:", "🧡"}, - {":yellow_heart:", "💛"}, - {":green_heart:", "💚"}, - {":blue_heart:", "💙"}, - {":purple_heart:", "💜"}, - {":brown_heart:", "🤎"}, - {":black_heart:", "🖤"}, - {":white_heart:", "🤍"}, - {":100:", "💯"}, - {":anger:", "💢"}, - {":boom:", "💥"}, - {":collision:", "💥"}, - {":dizzy:", "💫"}, - {":sweat_drops:", "💦"}, - {":dash:", "💨"}, - {":hole:", "🕳️"}, - {":bomb:", "💣"}, - {":speech_balloon:", "💬"}, - {":eye_speech_bubble:", "👁️‍🗨️"}, - {":left_speech_bubble:", "🗨️"}, - {":right_anger_bubble:", "🗯️"}, - {":thought_balloon:", "💭"}, - {":zzz:", "💤"}, - {":wave:", "👋"}, - {":raised_back_of_hand:", "🤚"}, - {":raised_hand_with_fingers_splayed:", "🖐️"}, - {":hand:", "✋"}, - {":raised_hand:", "✋"}, - {":vulcan_salute:", "🖖"}, - {":ok_hand:", "👌"}, - {":pinched_fingers:", "🤌"}, - {":pinching_hand:", "🤏"}, - {":v:", "✌️"}, - {":crossed_fingers:", "🤞"}, - {":love_you_gesture:", "🤟"}, - {":metal:", "🤘"}, - {":call_me_hand:", "🤙"}, - {":point_left:", "👈"}, - {":point_right:", "👉"}, - {":point_up_2:", "👆"}, - {":middle_finger:", "🖕"}, - {":fu:", "🖕"}, - {":point_down:", "👇"}, - {":point_up:", "☝️"}, - {":+1:", "👍"}, - {":thumbsup:", "👍"}, - {":-1:", "👎"}, - {":thumbsdown:", "👎"}, - {":fist_raised:", "✊"}, - {":fist:", "✊"}, - {":fist_oncoming:", "👊"}, - {":facepunch:", "👊"}, - {":punch:", "👊"}, - {":fist_left:", "🤛"}, - {":fist_right:", "🤜"}, - {":clap:", "👏"}, - {":raised_hands:", "🙌"}, - {":open_hands:", "👐"}, - {":palms_up_together:", "🤲"}, - {":handshake:", "🤝"}, - {":pray:", "🙏"}, - {":writing_hand:", "✍️"}, - {":nail_care:", "💅"}, - {":selfie:", "🤳"}, - {":muscle:", "💪"}, - {":mechanical_arm:", "🦾"}, - {":mechanical_leg:", "🦿"}, - {":leg:", "🦵"}, - {":foot:", "🦶"}, - {":ear:", "👂"}, - {":ear_with_hearing_aid:", "🦻"}, - {":nose:", "👃"}, - {":brain:", "🧠"}, - {":anatomical_heart:", "🫀"}, - {":lungs:", "🫁"}, - {":tooth:", "🦷"}, - {":bone:", "🦴"}, - {":eyes:", "👀"}, - {":eye:", "👁️"}, - {":tongue:", "👅"}, - {":lips:", "👄"}, - {":baby:", "👶"}, - {":child:", "🧒"}, - {":boy:", "👦"}, - {":girl:", "👧"}, - {":adult:", "🧑"}, - {":blond_haired_person:", "👱"}, - {":man:", "👨"}, - {":bearded_person:", "🧔"}, - {":red_haired_man:", "👨‍🦰"}, - {":curly_haired_man:", "👨‍🦱"}, - {":white_haired_man:", "👨‍🦳"}, - {":bald_man:", "👨‍🦲"}, - {":woman:", "👩"}, - {":red_haired_woman:", "👩‍🦰"}, - {":person_red_hair:", "🧑‍🦰"}, - {":curly_haired_woman:", "👩‍🦱"}, - {":person_curly_hair:", "🧑‍🦱"}, - {":white_haired_woman:", "👩‍🦳"}, - {":person_white_hair:", "🧑‍🦳"}, - {":bald_woman:", "👩‍🦲"}, - {":person_bald:", "🧑‍🦲"}, - {":blond_haired_woman:", "👱‍♀️"}, - {":blonde_woman:", "👱‍♀️"}, - {":blond_haired_man:", "👱‍♂️"}, - {":older_adult:", "🧓"}, - {":older_man:", "👴"}, - {":older_woman:", "👵"}, - {":frowning_person:", "🙍"}, - {":frowning_man:", "🙍‍♂️"}, - {":frowning_woman:", "🙍‍♀️"}, - {":pouting_face:", "🙎"}, - {":pouting_man:", "🙎‍♂️"}, - {":pouting_woman:", "🙎‍♀️"}, - {":no_good:", "🙅"}, - {":no_good_man:", "🙅‍♂️"}, - {":ng_man:", "🙅‍♂️"}, - {":no_good_woman:", "🙅‍♀️"}, - {":ng_woman:", "🙅‍♀️"}, - {":ok_person:", "🙆"}, - {":ok_man:", "🙆‍♂️"}, - {":ok_woman:", "🙆‍♀️"}, - {":tipping_hand_person:", "💁"}, - {":information_desk_person:", "💁"}, - {":tipping_hand_man:", "💁‍♂️"}, - {":sassy_man:", "💁‍♂️"}, - {":tipping_hand_woman:", "💁‍♀️"}, - {":sassy_woman:", "💁‍♀️"}, - {":raising_hand:", "🙋"}, - {":raising_hand_man:", "🙋‍♂️"}, - {":raising_hand_woman:", "🙋‍♀️"}, - {":deaf_person:", "🧏"}, - {":deaf_man:", "🧏‍♂️"}, - {":deaf_woman:", "🧏‍♀️"}, - {":bow:", "🙇"}, - {":bowing_man:", "🙇‍♂️"}, - {":bowing_woman:", "🙇‍♀️"}, - {":facepalm:", "🤦"}, - {":man_facepalming:", "🤦‍♂️"}, - {":woman_facepalming:", "🤦‍♀️"}, - {":shrug:", "🤷"}, - {":man_shrugging:", "🤷‍♂️"}, - {":woman_shrugging:", "🤷‍♀️"}, - {":health_worker:", "🧑‍⚕️"}, - {":man_health_worker:", "👨‍⚕️"}, - {":woman_health_worker:", "👩‍⚕️"}, - {":student:", "🧑‍🎓"}, - {":man_student:", "👨‍🎓"}, - {":woman_student:", "👩‍🎓"}, - {":teacher:", "🧑‍🏫"}, - {":man_teacher:", "👨‍🏫"}, - {":woman_teacher:", "👩‍🏫"}, - {":judge:", "🧑‍⚖️"}, - {":man_judge:", "👨‍⚖️"}, - {":woman_judge:", "👩‍⚖️"}, - {":farmer:", "🧑‍🌾"}, - {":man_farmer:", "👨‍🌾"}, - {":woman_farmer:", "👩‍🌾"}, - {":cook:", "🧑‍🍳"}, - {":man_cook:", "👨‍🍳"}, - {":woman_cook:", "👩‍🍳"}, - {":mechanic:", "🧑‍🔧"}, - {":man_mechanic:", "👨‍🔧"}, - {":woman_mechanic:", "👩‍🔧"}, - {":factory_worker:", "🧑‍🏭"}, - {":man_factory_worker:", "👨‍🏭"}, - {":woman_factory_worker:", "👩‍🏭"}, - {":office_worker:", "🧑‍💼"}, - {":man_office_worker:", "👨‍💼"}, - {":woman_office_worker:", "👩‍💼"}, - {":scientist:", "🧑‍🔬"}, - {":man_scientist:", "👨‍🔬"}, - {":woman_scientist:", "👩‍🔬"}, - {":technologist:", "🧑‍💻"}, - {":man_technologist:", "👨‍💻"}, - {":woman_technologist:", "👩‍💻"}, - {":singer:", "🧑‍🎤"}, - {":man_singer:", "👨‍🎤"}, - {":woman_singer:", "👩‍🎤"}, - {":artist:", "🧑‍🎨"}, - {":man_artist:", "👨‍🎨"}, - {":woman_artist:", "👩‍🎨"}, - {":pilot:", "🧑‍✈️"}, - {":man_pilot:", "👨‍✈️"}, - {":woman_pilot:", "👩‍✈️"}, - {":astronaut:", "🧑‍🚀"}, - {":man_astronaut:", "👨‍🚀"}, - {":woman_astronaut:", "👩‍🚀"}, - {":firefighter:", "🧑‍🚒"}, - {":man_firefighter:", "👨‍🚒"}, - {":woman_firefighter:", "👩‍🚒"}, - {":police_officer:", "👮"}, - {":cop:", "👮"}, - {":policeman:", "👮‍♂️"}, - {":policewoman:", "👮‍♀️"}, - {":detective:", "🕵️"}, - {":male_detective:", "🕵️‍♂️"}, - {":female_detective:", "🕵️‍♀️"}, - {":guard:", "💂"}, - {":guardsman:", "💂‍♂️"}, - {":guardswoman:", "💂‍♀️"}, - {":ninja:", "🥷"}, - {":construction_worker:", "👷"}, - {":construction_worker_man:", "👷‍♂️"}, - {":construction_worker_woman:", "👷‍♀️"}, - {":prince:", "🤴"}, - {":princess:", "👸"}, - {":person_with_turban:", "👳"}, - {":man_with_turban:", "👳‍♂️"}, - {":woman_with_turban:", "👳‍♀️"}, - {":man_with_gua_pi_mao:", "👲"}, - {":woman_with_headscarf:", "🧕"}, - {":person_in_tuxedo:", "🤵"}, - {":man_in_tuxedo:", "🤵‍♂️"}, - {":woman_in_tuxedo:", "🤵‍♀️"}, - {":person_with_veil:", "👰"}, - {":man_with_veil:", "👰‍♂️"}, - {":woman_with_veil:", "👰‍♀️"}, - {":bride_with_veil:", "👰‍♀️"}, - {":pregnant_woman:", "🤰"}, - {":breast_feeding:", "🤱"}, - {":woman_feeding_baby:", "👩‍🍼"}, - {":man_feeding_baby:", "👨‍🍼"}, - {":person_feeding_baby:", "🧑‍🍼"}, - {":angel:", "👼"}, - {":santa:", "🎅"}, - {":mrs_claus:", "🤶"}, - {":mx_claus:", "🧑‍🎄"}, - {":superhero:", "🦸"}, - {":superhero_man:", "🦸‍♂️"}, - {":superhero_woman:", "🦸‍♀️"}, - {":supervillain:", "🦹"}, - {":supervillain_man:", "🦹‍♂️"}, - {":supervillain_woman:", "🦹‍♀️"}, - {":mage:", "🧙"}, - {":mage_man:", "🧙‍♂️"}, - {":mage_woman:", "🧙‍♀️"}, - {":fairy:", "🧚"}, - {":fairy_man:", "🧚‍♂️"}, - {":fairy_woman:", "🧚‍♀️"}, - {":vampire:", "🧛"}, - {":vampire_man:", "🧛‍♂️"}, - {":vampire_woman:", "🧛‍♀️"}, - {":merperson:", "🧜"}, - {":merman:", "🧜‍♂️"}, - {":mermaid:", "🧜‍♀️"}, - {":elf:", "🧝"}, - {":elf_man:", "🧝‍♂️"}, - {":elf_woman:", "🧝‍♀️"}, - {":genie:", "🧞"}, - {":genie_man:", "🧞‍♂️"}, - {":genie_woman:", "🧞‍♀️"}, - {":zombie:", "🧟"}, - {":zombie_man:", "🧟‍♂️"}, - {":zombie_woman:", "🧟‍♀️"}, - {":massage:", "💆"}, - {":massage_man:", "💆‍♂️"}, - {":massage_woman:", "💆‍♀️"}, - {":haircut:", "💇"}, - {":haircut_man:", "💇‍♂️"}, - {":haircut_woman:", "💇‍♀️"}, - {":walking:", "🚶"}, - {":walking_man:", "🚶‍♂️"}, - {":walking_woman:", "🚶‍♀️"}, - {":standing_person:", "🧍"}, - {":standing_man:", "🧍‍♂️"}, - {":standing_woman:", "🧍‍♀️"}, - {":kneeling_person:", "🧎"}, - {":kneeling_man:", "🧎‍♂️"}, - {":kneeling_woman:", "🧎‍♀️"}, - {":person_with_probing_cane:", "🧑‍🦯"}, - {":man_with_probing_cane:", "👨‍🦯"}, - {":woman_with_probing_cane:", "👩‍🦯"}, - {":person_in_motorized_wheelchair:", "🧑‍🦼"}, - {":man_in_motorized_wheelchair:", "👨‍🦼"}, - {":woman_in_motorized_wheelchair:", "👩‍🦼"}, - {":person_in_manual_wheelchair:", "🧑‍🦽"}, - {":man_in_manual_wheelchair:", "👨‍🦽"}, - {":woman_in_manual_wheelchair:", "👩‍🦽"}, - {":runner:", "🏃"}, - {":running:", "🏃"}, - {":running_man:", "🏃‍♂️"}, - {":running_woman:", "🏃‍♀️"}, - {":woman_dancing:", "💃"}, - {":dancer:", "💃"}, - {":man_dancing:", "🕺"}, - {":business_suit_levitating:", "🕴️"}, - {":dancers:", "👯"}, - {":dancing_men:", "👯‍♂️"}, - {":dancing_women:", "👯‍♀️"}, - {":sauna_person:", "🧖"}, - {":sauna_man:", "🧖‍♂️"}, - {":sauna_woman:", "🧖‍♀️"}, - {":climbing:", "🧗"}, - {":climbing_man:", "🧗‍♂️"}, - {":climbing_woman:", "🧗‍♀️"}, - {":person_fencing:", "🤺"}, - {":horse_racing:", "🏇"}, - {":skier:", "⛷️"}, - {":snowboarder:", "🏂"}, - {":golfing:", "🏌️"}, - {":golfing_man:", "🏌️‍♂️"}, - {":golfing_woman:", "🏌️‍♀️"}, - {":surfer:", "🏄"}, - {":surfing_man:", "🏄‍♂️"}, - {":surfing_woman:", "🏄‍♀️"}, - {":rowboat:", "🚣"}, - {":rowing_man:", "🚣‍♂️"}, - {":rowing_woman:", "🚣‍♀️"}, - {":swimmer:", "🏊"}, - {":swimming_man:", "🏊‍♂️"}, - {":swimming_woman:", "🏊‍♀️"}, - {":bouncing_ball_person:", "⛹️"}, - {":bouncing_ball_man:", "⛹️‍♂️"}, - {":basketball_man:", "⛹️‍♂️"}, - {":bouncing_ball_woman:", "⛹️‍♀️"}, - {":basketball_woman:", "⛹️‍♀️"}, - {":weight_lifting:", "🏋️"}, - {":weight_lifting_man:", "🏋️‍♂️"}, - {":weight_lifting_woman:", "🏋️‍♀️"}, - {":bicyclist:", "🚴"}, - {":biking_man:", "🚴‍♂️"}, - {":biking_woman:", "🚴‍♀️"}, - {":mountain_bicyclist:", "🚵"}, - {":mountain_biking_man:", "🚵‍♂️"}, - {":mountain_biking_woman:", "🚵‍♀️"}, - {":cartwheeling:", "🤸"}, - {":man_cartwheeling:", "🤸‍♂️"}, - {":woman_cartwheeling:", "🤸‍♀️"}, - {":wrestling:", "🤼"}, - {":men_wrestling:", "🤼‍♂️"}, - {":women_wrestling:", "🤼‍♀️"}, - {":water_polo:", "🤽"}, - {":man_playing_water_polo:", "🤽‍♂️"}, - {":woman_playing_water_polo:", "🤽‍♀️"}, - {":handball_person:", "🤾"}, - {":man_playing_handball:", "🤾‍♂️"}, - {":woman_playing_handball:", "🤾‍♀️"}, - {":juggling_person:", "🤹"}, - {":man_juggling:", "🤹‍♂️"}, - {":woman_juggling:", "🤹‍♀️"}, - {":lotus_position:", "🧘"}, - {":lotus_position_man:", "🧘‍♂️"}, - {":lotus_position_woman:", "🧘‍♀️"}, - {":bath:", "🛀"}, - {":sleeping_bed:", "🛌"}, - {":people_holding_hands:", "🧑‍🤝‍🧑"}, - {":two_women_holding_hands:", "👭"}, - {":couple:", "👫"}, - {":two_men_holding_hands:", "👬"}, - {":couplekiss:", "💏"}, - {":couplekiss_man_woman:", "👩‍❤️‍💋‍👨"}, - {":couplekiss_man_man:", "👨‍❤️‍💋‍👨"}, - {":couplekiss_woman_woman:", "👩‍❤️‍💋‍👩"}, - {":couple_with_heart:", "💑"}, - {":couple_with_heart_woman_man:", "👩‍❤️‍👨"}, - {":couple_with_heart_man_man:", "👨‍❤️‍👨"}, - {":couple_with_heart_woman_woman:", "👩‍❤️‍👩"}, - {":family:", "👪"}, - {":family_man_woman_boy:", "👨‍👩‍👦"}, - {":family_man_woman_girl:", "👨‍👩‍👧"}, - {":family_man_woman_girl_boy:", "👨‍👩‍👧‍👦"}, - {":family_man_woman_boy_boy:", "👨‍👩‍👦‍👦"}, - {":family_man_woman_girl_girl:", "👨‍👩‍👧‍👧"}, - {":family_man_man_boy:", "👨‍👨‍👦"}, - {":family_man_man_girl:", "👨‍👨‍👧"}, - {":family_man_man_girl_boy:", "👨‍👨‍👧‍👦"}, - {":family_man_man_boy_boy:", "👨‍👨‍👦‍👦"}, - {":family_man_man_girl_girl:", "👨‍👨‍👧‍👧"}, - {":family_woman_woman_boy:", "👩‍👩‍👦"}, - {":family_woman_woman_girl:", "👩‍👩‍👧"}, - {":family_woman_woman_girl_boy:", "👩‍👩‍👧‍👦"}, - {":family_woman_woman_boy_boy:", "👩‍👩‍👦‍👦"}, - {":family_woman_woman_girl_girl:", "👩‍👩‍👧‍👧"}, - {":family_man_boy:", "👨‍👦"}, - {":family_man_boy_boy:", "👨‍👦‍👦"}, - {":family_man_girl:", "👨‍👧"}, - {":family_man_girl_boy:", "👨‍👧‍👦"}, - {":family_man_girl_girl:", "👨‍👧‍👧"}, - {":family_woman_boy:", "👩‍👦"}, - {":family_woman_boy_boy:", "👩‍👦‍👦"}, - {":family_woman_girl:", "👩‍👧"}, - {":family_woman_girl_boy:", "👩‍👧‍👦"}, - {":family_woman_girl_girl:", "👩‍👧‍👧"}, - {":speaking_head:", "🗣️"}, - {":bust_in_silhouette:", "👤"}, - {":busts_in_silhouette:", "👥"}, - {":people_hugging:", "🫂"}, - {":footprints:", "👣"}, - {":monkey_face:", "🐵"}, - {":monkey:", "🐒"}, - {":gorilla:", "🦍"}, - {":orangutan:", "🦧"}, - {":dog:", "🐶"}, - {":dog2:", "🐕"}, - {":guide_dog:", "🦮"}, - {":service_dog:", "🐕‍🦺"}, - {":poodle:", "🐩"}, - {":wolf:", "🐺"}, - {":fox_face:", "🦊"}, - {":raccoon:", "🦝"}, - {":cat:", "🐱"}, - {":cat2:", "🐈"}, - {":black_cat:", "🐈‍⬛"}, - {":lion:", "🦁"}, - {":tiger:", "🐯"}, - {":tiger2:", "🐅"}, - {":leopard:", "🐆"}, - {":horse:", "🐴"}, - {":racehorse:", "🐎"}, - {":unicorn:", "🦄"}, - {":zebra:", "🦓"}, - {":deer:", "🦌"}, - {":bison:", "🦬"}, - {":cow:", "🐮"}, - {":ox:", "🐂"}, - {":water_buffalo:", "🐃"}, - {":cow2:", "🐄"}, - {":pig:", "🐷"}, - {":pig2:", "🐖"}, - {":boar:", "🐗"}, - {":pig_nose:", "🐽"}, - {":ram:", "🐏"}, - {":sheep:", "🐑"}, - {":goat:", "🐐"}, - {":dromedary_camel:", "🐪"}, - {":camel:", "🐫"}, - {":llama:", "🦙"}, - {":giraffe:", "🦒"}, - {":elephant:", "🐘"}, - {":mammoth:", "🦣"}, - {":rhinoceros:", "🦏"}, - {":hippopotamus:", "🦛"}, - {":mouse:", "🐭"}, - {":mouse2:", "🐁"}, - {":rat:", "🐀"}, - {":hamster:", "🐹"}, - {":rabbit:", "🐰"}, - {":rabbit2:", "🐇"}, - {":chipmunk:", "🐿️"}, - {":beaver:", "🦫"}, - {":hedgehog:", "🦔"}, - {":bat:", "🦇"}, - {":bear:", "🐻"}, - {":polar_bear:", "🐻‍❄️"}, - {":koala:", "🐨"}, - {":panda_face:", "🐼"}, - {":sloth:", "🦥"}, - {":otter:", "🦦"}, - {":skunk:", "🦨"}, - {":kangaroo:", "🦘"}, - {":badger:", "🦡"}, - {":feet:", "🐾"}, - {":paw_prints:", "🐾"}, - {":turkey:", "🦃"}, - {":chicken:", "🐔"}, - {":rooster:", "🐓"}, - {":hatching_chick:", "🐣"}, - {":baby_chick:", "🐤"}, - {":hatched_chick:", "🐥"}, - {":bird:", "🐦"}, - {":penguin:", "🐧"}, - {":dove:", "🕊️"}, - {":eagle:", "🦅"}, - {":duck:", "🦆"}, - {":swan:", "🦢"}, - {":owl:", "🦉"}, - {":dodo:", "🦤"}, - {":feather:", "🪶"}, - {":flamingo:", "🦩"}, - {":peacock:", "🦚"}, - {":parrot:", "🦜"}, - {":frog:", "🐸"}, - {":crocodile:", "🐊"}, - {":turtle:", "🐢"}, - {":lizard:", "🦎"}, - {":snake:", "🐍"}, - {":dragon_face:", "🐲"}, - {":dragon:", "🐉"}, - {":sauropod:", "🦕"}, - {":t-rex:", "🦖"}, - {":whale:", "🐳"}, - {":whale2:", "🐋"}, - {":dolphin:", "🐬"}, - {":flipper:", "🐬"}, - {":seal:", "🦭"}, - {":fish:", "🐟"}, - {":tropical_fish:", "🐠"}, - {":blowfish:", "🐡"}, - {":shark:", "🦈"}, - {":octopus:", "🐙"}, - {":shell:", "🐚"}, - {":snail:", "🐌"}, - {":butterfly:", "🦋"}, - {":bug:", "🐛"}, - {":ant:", "🐜"}, - {":bee:", "🐝"}, - {":honeybee:", "🐝"}, - {":beetle:", "🪲"}, - {":lady_beetle:", "🐞"}, - {":cricket:", "🦗"}, - {":cockroach:", "🪳"}, - {":spider:", "🕷️"}, - {":spider_web:", "🕸️"}, - {":scorpion:", "🦂"}, - {":mosquito:", "🦟"}, - {":fly:", "🪰"}, - {":worm:", "🪱"}, - {":microbe:", "🦠"}, - {":bouquet:", "💐"}, - {":cherry_blossom:", "🌸"}, - {":white_flower:", "💮"}, - {":rosette:", "🏵️"}, - {":rose:", "🌹"}, - {":wilted_flower:", "🥀"}, - {":hibiscus:", "🌺"}, - {":sunflower:", "🌻"}, - {":blossom:", "🌼"}, - {":tulip:", "🌷"}, - {":seedling:", "🌱"}, - {":potted_plant:", "🪴"}, - {":evergreen_tree:", "🌲"}, - {":deciduous_tree:", "🌳"}, - {":palm_tree:", "🌴"}, - {":cactus:", "🌵"}, - {":ear_of_rice:", "🌾"}, - {":herb:", "🌿"}, - {":shamrock:", "☘️"}, - {":four_leaf_clover:", "🍀"}, - {":maple_leaf:", "🍁"}, - {":fallen_leaf:", "🍂"}, - {":leaves:", "🍃"}, - {":grapes:", "🍇"}, - {":melon:", "🍈"}, - {":watermelon:", "🍉"}, - {":tangerine:", "🍊"}, - {":orange:", "🍊"}, - {":mandarin:", "🍊"}, - {":lemon:", "🍋"}, - {":banana:", "🍌"}, - {":pineapple:", "🍍"}, - {":mango:", "🥭"}, - {":apple:", "🍎"}, - {":green_apple:", "🍏"}, - {":pear:", "🍐"}, - {":peach:", "🍑"}, - {":cherries:", "🍒"}, - {":strawberry:", "🍓"}, - {":blueberries:", "🫐"}, - {":kiwi_fruit:", "🥝"}, - {":tomato:", "🍅"}, - {":olive:", "🫒"}, - {":coconut:", "🥥"}, - {":avocado:", "🥑"}, - {":eggplant:", "🍆"}, - {":potato:", "🥔"}, - {":carrot:", "🥕"}, - {":corn:", "🌽"}, - {":hot_pepper:", "🌶️"}, - {":bell_pepper:", "🫑"}, - {":cucumber:", "🥒"}, - {":leafy_green:", "🥬"}, - {":broccoli:", "🥦"}, - {":garlic:", "🧄"}, - {":onion:", "🧅"}, - {":mushroom:", "🍄"}, - {":peanuts:", "🥜"}, - {":chestnut:", "🌰"}, - {":bread:", "🍞"}, - {":croissant:", "🥐"}, - {":baguette_bread:", "🥖"}, - {":flatbread:", "🫓"}, - {":pretzel:", "🥨"}, - {":bagel:", "🥯"}, - {":pancakes:", "🥞"}, - {":waffle:", "🧇"}, - {":cheese:", "🧀"}, - {":meat_on_bone:", "🍖"}, - {":poultry_leg:", "🍗"}, - {":cut_of_meat:", "🥩"}, - {":bacon:", "🥓"}, - {":hamburger:", "🍔"}, - {":fries:", "🍟"}, - {":pizza:", "🍕"}, - {":hotdog:", "🌭"}, - {":sandwich:", "🥪"}, - {":taco:", "🌮"}, - {":burrito:", "🌯"}, - {":tamale:", "🫔"}, - {":stuffed_flatbread:", "🥙"}, - {":falafel:", "🧆"}, - {":egg:", "🥚"}, - {":fried_egg:", "🍳"}, - {":shallow_pan_of_food:", "🥘"}, - {":stew:", "🍲"}, - {":fondue:", "🫕"}, - {":bowl_with_spoon:", "🥣"}, - {":green_salad:", "🥗"}, - {":popcorn:", "🍿"}, - {":butter:", "🧈"}, - {":salt:", "🧂"}, - {":canned_food:", "🥫"}, - {":bento:", "🍱"}, - {":rice_cracker:", "🍘"}, - {":rice_ball:", "🍙"}, - {":rice:", "🍚"}, - {":curry:", "🍛"}, - {":ramen:", "🍜"}, - {":spaghetti:", "🍝"}, - {":sweet_potato:", "🍠"}, - {":oden:", "🍢"}, - {":sushi:", "🍣"}, - {":fried_shrimp:", "🍤"}, - {":fish_cake:", "🍥"}, - {":moon_cake:", "🥮"}, - {":dango:", "🍡"}, - {":dumpling:", "🥟"}, - {":fortune_cookie:", "🥠"}, - {":takeout_box:", "🥡"}, - {":crab:", "🦀"}, - {":lobster:", "🦞"}, - {":shrimp:", "🦐"}, - {":squid:", "🦑"}, - {":oyster:", "🦪"}, - {":icecream:", "🍦"}, - {":shaved_ice:", "🍧"}, - {":ice_cream:", "🍨"}, - {":doughnut:", "🍩"}, - {":cookie:", "🍪"}, - {":birthday:", "🎂"}, - {":cake:", "🍰"}, - {":cupcake:", "🧁"}, - {":pie:", "🥧"}, - {":chocolate_bar:", "🍫"}, - {":candy:", "🍬"}, - {":lollipop:", "🍭"}, - {":custard:", "🍮"}, - {":honey_pot:", "🍯"}, - {":baby_bottle:", "🍼"}, - {":milk_glass:", "🥛"}, - {":coffee:", "☕"}, - {":teapot:", "🫖"}, - {":tea:", "🍵"}, - {":sake:", "🍶"}, - {":champagne:", "🍾"}, - {":wine_glass:", "🍷"}, - {":cocktail:", "🍸"}, - {":tropical_drink:", "🍹"}, - {":beer:", "🍺"}, - {":beers:", "🍻"}, - {":clinking_glasses:", "🥂"}, - {":tumbler_glass:", "🥃"}, - {":cup_with_straw:", "🥤"}, - {":bubble_tea:", "🧋"}, - {":beverage_box:", "🧃"}, - {":mate:", "🧉"}, - {":ice_cube:", "🧊"}, - {":chopsticks:", "🥢"}, - {":plate_with_cutlery:", "🍽️"}, - {":fork_and_knife:", "🍴"}, - {":spoon:", "🥄"}, - {":hocho:", "🔪"}, - {":knife:", "🔪"}, - {":amphora:", "🏺"}, - {":earth_africa:", "🌍"}, - {":earth_americas:", "🌎"}, - {":earth_asia:", "🌏"}, - {":globe_with_meridians:", "🌐"}, - {":world_map:", "🗺️"}, - {":japan:", "🗾"}, - {":compass:", "🧭"}, - {":mountain_snow:", "🏔️"}, - {":mountain:", "⛰️"}, - {":volcano:", "🌋"}, - {":mount_fuji:", "🗻"}, - {":camping:", "🏕️"}, - {":beach_umbrella:", "🏖️"}, - {":desert:", "🏜️"}, - {":desert_island:", "🏝️"}, - {":national_park:", "🏞️"}, - {":stadium:", "🏟️"}, - {":classical_building:", "🏛️"}, - {":building_construction:", "🏗️"}, - {":bricks:", "🧱"}, - {":rock:", "🪨"}, - {":wood:", "🪵"}, - {":hut:", "🛖"}, - {":houses:", "🏘️"}, - {":derelict_house:", "🏚️"}, - {":house:", "🏠"}, - {":house_with_garden:", "🏡"}, - {":office:", "🏢"}, - {":post_office:", "🏣"}, - {":european_post_office:", "🏤"}, - {":hospital:", "🏥"}, - {":bank:", "🏦"}, - {":hotel:", "🏨"}, - {":love_hotel:", "🏩"}, - {":convenience_store:", "🏪"}, - {":school:", "🏫"}, - {":department_store:", "🏬"}, - {":factory:", "🏭"}, - {":japanese_castle:", "🏯"}, - {":european_castle:", "🏰"}, - {":wedding:", "💒"}, - {":tokyo_tower:", "🗼"}, - {":statue_of_liberty:", "🗽"}, - {":church:", "⛪"}, - {":mosque:", "🕌"}, - {":hindu_temple:", "🛕"}, - {":synagogue:", "🕍"}, - {":shinto_shrine:", "⛩️"}, - {":kaaba:", "🕋"}, - {":fountain:", "⛲"}, - {":tent:", "⛺"}, - {":foggy:", "🌁"}, - {":night_with_stars:", "🌃"}, - {":cityscape:", "🏙️"}, - {":sunrise_over_mountains:", "🌄"}, - {":sunrise:", "🌅"}, - {":city_sunset:", "🌆"}, - {":city_sunrise:", "🌇"}, - {":bridge_at_night:", "🌉"}, - {":hotsprings:", "♨️"}, - {":carousel_horse:", "🎠"}, - {":ferris_wheel:", "🎡"}, - {":roller_coaster:", "🎢"}, - {":barber:", "💈"}, - {":circus_tent:", "🎪"}, - {":steam_locomotive:", "🚂"}, - {":railway_car:", "🚃"}, - {":bullettrain_side:", "🚄"}, - {":bullettrain_front:", "🚅"}, - {":train2:", "🚆"}, - {":metro:", "🚇"}, - {":light_rail:", "🚈"}, - {":station:", "🚉"}, - {":tram:", "🚊"}, - {":monorail:", "🚝"}, - {":mountain_railway:", "🚞"}, - {":train:", "🚋"}, - {":bus:", "🚌"}, - {":oncoming_bus:", "🚍"}, - {":trolleybus:", "🚎"}, - {":minibus:", "🚐"}, - {":ambulance:", "🚑"}, - {":fire_engine:", "🚒"}, - {":police_car:", "🚓"}, - {":oncoming_police_car:", "🚔"}, - {":taxi:", "🚕"}, - {":oncoming_taxi:", "🚖"}, - {":car:", "🚗"}, - {":red_car:", "🚗"}, - {":oncoming_automobile:", "🚘"}, - {":blue_car:", "🚙"}, - {":pickup_truck:", "🛻"}, - {":truck:", "🚚"}, - {":articulated_lorry:", "🚛"}, - {":tractor:", "🚜"}, - {":racing_car:", "🏎️"}, - {":motorcycle:", "🏍️"}, - {":motor_scooter:", "🛵"}, - {":manual_wheelchair:", "🦽"}, - {":motorized_wheelchair:", "🦼"}, - {":auto_rickshaw:", "🛺"}, - {":bike:", "🚲"}, - {":kick_scooter:", "🛴"}, - {":skateboard:", "🛹"}, - {":roller_skate:", "🛼"}, - {":busstop:", "🚏"}, - {":motorway:", "🛣️"}, - {":railway_track:", "🛤️"}, - {":oil_drum:", "🛢️"}, - {":fuelpump:", "⛽"}, - {":rotating_light:", "🚨"}, - {":traffic_light:", "🚥"}, - {":vertical_traffic_light:", "🚦"}, - {":stop_sign:", "🛑"}, - {":construction:", "🚧"}, - {":anchor:", "⚓"}, - {":boat:", "⛵"}, - {":sailboat:", "⛵"}, - {":canoe:", "🛶"}, - {":speedboat:", "🚤"}, - {":passenger_ship:", "🛳️"}, - {":ferry:", "⛴️"}, - {":motor_boat:", "🛥️"}, - {":ship:", "🚢"}, - {":airplane:", "✈️"}, - {":small_airplane:", "🛩️"}, - {":flight_departure:", "🛫"}, - {":flight_arrival:", "🛬"}, - {":parachute:", "🪂"}, - {":seat:", "💺"}, - {":helicopter:", "🚁"}, - {":suspension_railway:", "🚟"}, - {":mountain_cableway:", "🚠"}, - {":aerial_tramway:", "🚡"}, - {":artificial_satellite:", "🛰️"}, - {":rocket:", "🚀"}, - {":flying_saucer:", "🛸"}, - {":bellhop_bell:", "🛎️"}, - {":luggage:", "🧳"}, - {":hourglass:", "⌛"}, - {":hourglass_flowing_sand:", "⏳"}, - {":watch:", "⌚"}, - {":alarm_clock:", "⏰"}, - {":stopwatch:", "⏱️"}, - {":timer_clock:", "⏲️"}, - {":mantelpiece_clock:", "🕰️"}, - {":clock12:", "🕛"}, - {":clock1230:", "🕧"}, - {":clock1:", "🕐"}, - {":clock130:", "🕜"}, - {":clock2:", "🕑"}, - {":clock230:", "🕝"}, - {":clock3:", "🕒"}, - {":clock330:", "🕞"}, - {":clock4:", "🕓"}, - {":clock430:", "🕟"}, - {":clock5:", "🕔"}, - {":clock530:", "🕠"}, - {":clock6:", "🕕"}, - {":clock630:", "🕡"}, - {":clock7:", "🕖"}, - {":clock730:", "🕢"}, - {":clock8:", "🕗"}, - {":clock830:", "🕣"}, - {":clock9:", "🕘"}, - {":clock930:", "🕤"}, - {":clock10:", "🕙"}, - {":clock1030:", "🕥"}, - {":clock11:", "🕚"}, - {":clock1130:", "🕦"}, - {":new_moon:", "🌑"}, - {":waxing_crescent_moon:", "🌒"}, - {":first_quarter_moon:", "🌓"}, - {":moon:", "🌔"}, - {":waxing_gibbous_moon:", "🌔"}, - {":full_moon:", "🌕"}, - {":waning_gibbous_moon:", "🌖"}, - {":last_quarter_moon:", "🌗"}, - {":waning_crescent_moon:", "🌘"}, - {":crescent_moon:", "🌙"}, - {":new_moon_with_face:", "🌚"}, - {":first_quarter_moon_with_face:", "🌛"}, - {":last_quarter_moon_with_face:", "🌜"}, - {":thermometer:", "🌡️"}, - {":sunny:", "☀️"}, - {":full_moon_with_face:", "🌝"}, - {":sun_with_face:", "🌞"}, - {":ringed_planet:", "🪐"}, - {":star:", "⭐"}, - {":star2:", "🌟"}, - {":stars:", "🌠"}, - {":milky_way:", "🌌"}, - {":cloud:", "☁️"}, - {":partly_sunny:", "⛅"}, - {":cloud_with_lightning_and_rain:", "⛈️"}, - {":sun_behind_small_cloud:", "🌤️"}, - {":sun_behind_large_cloud:", "🌥️"}, - {":sun_behind_rain_cloud:", "🌦️"}, - {":cloud_with_rain:", "🌧️"}, - {":cloud_with_snow:", "🌨️"}, - {":cloud_with_lightning:", "🌩️"}, - {":tornado:", "🌪️"}, - {":fog:", "🌫️"}, - {":wind_face:", "🌬️"}, - {":cyclone:", "🌀"}, - {":rainbow:", "🌈"}, - {":closed_umbrella:", "🌂"}, - {":open_umbrella:", "☂️"}, - {":umbrella:", "☔"}, - {":parasol_on_ground:", "⛱️"}, - {":zap:", "⚡"}, - {":snowflake:", "❄️"}, - {":snowman_with_snow:", "☃️"}, - {":snowman:", "⛄"}, - {":comet:", "☄️"}, - {":fire:", "🔥"}, - {":droplet:", "💧"}, - {":ocean:", "🌊"}, - {":jack_o_lantern:", "🎃"}, - {":christmas_tree:", "🎄"}, - {":fireworks:", "🎆"}, - {":sparkler:", "🎇"}, - {":firecracker:", "🧨"}, - {":sparkles:", "✨"}, - {":balloon:", "🎈"}, - {":tada:", "🎉"}, - {":confetti_ball:", "🎊"}, - {":tanabata_tree:", "🎋"}, - {":bamboo:", "🎍"}, - {":dolls:", "🎎"}, - {":flags:", "🎏"}, - {":wind_chime:", "🎐"}, - {":rice_scene:", "🎑"}, - {":red_envelope:", "🧧"}, - {":ribbon:", "🎀"}, - {":gift:", "🎁"}, - {":reminder_ribbon:", "🎗️"}, - {":tickets:", "🎟️"}, - {":ticket:", "🎫"}, - {":medal_military:", "🎖️"}, - {":trophy:", "🏆"}, - {":medal_sports:", "🏅"}, - {":1st_place_medal:", "🥇"}, - {":2nd_place_medal:", "🥈"}, - {":3rd_place_medal:", "🥉"}, - {":soccer:", "⚽"}, - {":baseball:", "⚾"}, - {":softball:", "🥎"}, - {":basketball:", "🏀"}, - {":volleyball:", "🏐"}, - {":football:", "🏈"}, - {":rugby_football:", "🏉"}, - {":tennis:", "🎾"}, - {":flying_disc:", "🥏"}, - {":bowling:", "🎳"}, - {":cricket_game:", "🏏"}, - {":field_hockey:", "🏑"}, - {":ice_hockey:", "🏒"}, - {":lacrosse:", "🥍"}, - {":ping_pong:", "🏓"}, - {":badminton:", "🏸"}, - {":boxing_glove:", "🥊"}, - {":martial_arts_uniform:", "🥋"}, - {":goal_net:", "🥅"}, - {":golf:", "⛳"}, - {":ice_skate:", "⛸️"}, - {":fishing_pole_and_fish:", "🎣"}, - {":diving_mask:", "🤿"}, - {":running_shirt_with_sash:", "🎽"}, - {":ski:", "🎿"}, - {":sled:", "🛷"}, - {":curling_stone:", "🥌"}, - {":dart:", "🎯"}, - {":yo_yo:", "🪀"}, - {":kite:", "🪁"}, - {":8ball:", "🎱"}, - {":crystal_ball:", "🔮"}, - {":magic_wand:", "🪄"}, - {":nazar_amulet:", "🧿"}, - {":video_game:", "🎮"}, - {":joystick:", "🕹️"}, - {":slot_machine:", "🎰"}, - {":game_die:", "🎲"}, - {":jigsaw:", "🧩"}, - {":teddy_bear:", "🧸"}, - {":pi_ata:", "🪅"}, - {":nesting_dolls:", "🪆"}, - {":spades:", "♠️"}, - {":hearts:", "♥️"}, - {":diamonds:", "♦️"}, - {":clubs:", "♣️"}, - {":chess_pawn:", "♟️"}, - {":black_joker:", "🃏"}, - {":mahjong:", "🀄"}, - {":flower_playing_cards:", "🎴"}, - {":performing_arts:", "🎭"}, - {":framed_picture:", "🖼️"}, - {":art:", "🎨"}, - {":thread:", "🧵"}, - {":sewing_needle:", "🪡"}, - {":yarn:", "🧶"}, - {":knot:", "🪢"}, - {":eyeglasses:", "👓"}, - {":dark_sunglasses:", "🕶️"}, - {":goggles:", "🥽"}, - {":lab_coat:", "🥼"}, - {":safety_vest:", "🦺"}, - {":necktie:", "👔"}, - {":shirt:", "👕"}, - {":tshirt:", "👕"}, - {":jeans:", "👖"}, - {":scarf:", "🧣"}, - {":gloves:", "🧤"}, - {":coat:", "🧥"}, - {":socks:", "🧦"}, - {":dress:", "👗"}, - {":kimono:", "👘"}, - {":sari:", "🥻"}, - {":one_piece_swimsuit:", "🩱"}, - {":swim_brief:", "🩲"}, - {":shorts:", "🩳"}, - {":bikini:", "👙"}, - {":womans_clothes:", "👚"}, - {":purse:", "👛"}, - {":handbag:", "👜"}, - {":pouch:", "👝"}, - {":shopping:", "🛍️"}, - {":school_satchel:", "🎒"}, - {":thong_sandal:", "🩴"}, - {":mans_shoe:", "👞"}, - {":shoe:", "👞"}, - {":athletic_shoe:", "👟"}, - {":hiking_boot:", "🥾"}, - {":flat_shoe:", "🥿"}, - {":high_heel:", "👠"}, - {":sandal:", "👡"}, - {":ballet_shoes:", "🩰"}, - {":boot:", "👢"}, - {":crown:", "👑"}, - {":womans_hat:", "👒"}, - {":tophat:", "🎩"}, - {":mortar_board:", "🎓"}, - {":billed_cap:", "🧢"}, - {":military_helmet:", "🪖"}, - {":rescue_worker_helmet:", "⛑️"}, - {":prayer_beads:", "📿"}, - {":lipstick:", "💄"}, - {":ring:", "💍"}, - {":gem:", "💎"}, - {":mute:", "🔇"}, - {":speaker:", "🔈"}, - {":sound:", "🔉"}, - {":loud_sound:", "🔊"}, - {":loudspeaker:", "📢"}, - {":mega:", "📣"}, - {":postal_horn:", "📯"}, - {":bell:", "🔔"}, - {":no_bell:", "🔕"}, - {":musical_score:", "🎼"}, - {":musical_note:", "🎵"}, - {":notes:", "🎶"}, - {":studio_microphone:", "🎙️"}, - {":level_slider:", "🎚️"}, - {":control_knobs:", "🎛️"}, - {":microphone:", "🎤"}, - {":headphones:", "🎧"}, - {":radio:", "📻"}, - {":saxophone:", "🎷"}, - {":accordion:", "🪗"}, - {":guitar:", "🎸"}, - {":musical_keyboard:", "🎹"}, - {":trumpet:", "🎺"}, - {":violin:", "🎻"}, - {":banjo:", "🪕"}, - {":drum:", "🥁"}, - {":long_drum:", "🪘"}, - {":iphone:", "📱"}, - {":calling:", "📲"}, - {":phone:", "☎️"}, - {":telephone:", "☎️"}, - {":telephone_receiver:", "📞"}, - {":pager:", "📟"}, - {":fax:", "📠"}, - {":battery:", "🔋"}, - {":electric_plug:", "🔌"}, - {":computer:", "💻"}, - {":desktop_computer:", "🖥️"}, - {":printer:", "🖨️"}, - {":keyboard:", "⌨️"}, - {":computer_mouse:", "🖱️"}, - {":trackball:", "🖲️"}, - {":minidisc:", "💽"}, - {":floppy_disk:", "💾"}, - {":cd:", "💿"}, - {":dvd:", "📀"}, - {":abacus:", "🧮"}, - {":movie_camera:", "🎥"}, - {":film_strip:", "🎞️"}, - {":film_projector:", "📽️"}, - {":clapper:", "🎬"}, - {":tv:", "📺"}, - {":camera:", "📷"}, - {":camera_flash:", "📸"}, - {":video_camera:", "📹"}, - {":vhs:", "📼"}, - {":mag:", "🔍"}, - {":mag_right:", "🔎"}, - {":candle:", "🕯️"}, - {":bulb:", "💡"}, - {":flashlight:", "🔦"}, - {":izakaya_lantern:", "🏮"}, - {":lantern:", "🏮"}, - {":diya_lamp:", "🪔"}, - {":notebook_with_decorative_cover:", "📔"}, - {":closed_book:", "📕"}, - {":book:", "📖"}, - {":open_book:", "📖"}, - {":green_book:", "📗"}, - {":blue_book:", "📘"}, - {":orange_book:", "📙"}, - {":books:", "📚"}, - {":notebook:", "📓"}, - {":ledger:", "📒"}, - {":page_with_curl:", "📃"}, - {":scroll:", "📜"}, - {":page_facing_up:", "📄"}, - {":newspaper:", "📰"}, - {":newspaper_roll:", "🗞️"}, - {":bookmark_tabs:", "📑"}, - {":bookmark:", "🔖"}, - {":label:", "🏷️"}, - {":moneybag:", "💰"}, - {":coin:", "🪙"}, - {":yen:", "💴"}, - {":dollar:", "💵"}, - {":euro:", "💶"}, - {":pound:", "💷"}, - {":money_with_wings:", "💸"}, - {":credit_card:", "💳"}, - {":receipt:", "🧾"}, - {":chart:", "💹"}, - {":email:", "✉️"}, - {":envelope:", "✉️"}, - {":e-mail:", "📧"}, - {":incoming_envelope:", "📨"}, - {":envelope_with_arrow:", "📩"}, - {":outbox_tray:", "📤"}, - {":inbox_tray:", "📥"}, - {":package:", "📦"}, - {":mailbox:", "📫"}, - {":mailbox_closed:", "📪"}, - {":mailbox_with_mail:", "📬"}, - {":mailbox_with_no_mail:", "📭"}, - {":postbox:", "📮"}, - {":ballot_box:", "🗳️"}, - {":pencil2:", "✏️"}, - {":black_nib:", "✒️"}, - {":fountain_pen:", "🖋️"}, - {":pen:", "🖊️"}, - {":paintbrush:", "🖌️"}, - {":crayon:", "🖍️"}, - {":memo:", "📝"}, - {":pencil:", "📝"}, - {":briefcase:", "💼"}, - {":file_folder:", "📁"}, - {":open_file_folder:", "📂"}, - {":card_index_dividers:", "🗂️"}, - {":date:", "📅"}, - {":calendar:", "📆"}, - {":spiral_notepad:", "🗒️"}, - {":spiral_calendar:", "🗓️"}, - {":card_index:", "📇"}, - {":chart_with_upwards_trend:", "📈"}, - {":chart_with_downwards_trend:", "📉"}, - {":bar_chart:", "📊"}, - {":clipboard:", "📋"}, - {":pushpin:", "📌"}, - {":round_pushpin:", "📍"}, - {":paperclip:", "📎"}, - {":paperclips:", "🖇️"}, - {":straight_ruler:", "📏"}, - {":triangular_ruler:", "📐"}, - {":scissors:", "✂️"}, - {":card_file_box:", "🗃️"}, - {":file_cabinet:", "🗄️"}, - {":wastebasket:", "🗑️"}, - {":lock:", "🔒"}, - {":unlock:", "🔓"}, - {":lock_with_ink_pen:", "🔏"}, - {":closed_lock_with_key:", "🔐"}, - {":key:", "🔑"}, - {":old_key:", "🗝️"}, - {":hammer:", "🔨"}, - {":axe:", "🪓"}, - {":pick:", "⛏️"}, - {":hammer_and_pick:", "⚒️"}, - {":hammer_and_wrench:", "🛠️"}, - {":dagger:", "🗡️"}, - {":crossed_swords:", "⚔️"}, - {":gun:", "🔫"}, - {":boomerang:", "🪃"}, - {":bow_and_arrow:", "🏹"}, - {":shield:", "🛡️"}, - {":carpentry_saw:", "🪚"}, - {":wrench:", "🔧"}, - {":screwdriver:", "🪛"}, - {":nut_and_bolt:", "🔩"}, - {":gear:", "⚙️"}, - {":clamp:", "🗜️"}, - {":balance_scale:", "⚖️"}, - {":probing_cane:", "🦯"}, - {":link:", "🔗"}, - {":chains:", "⛓️"}, - {":hook:", "🪝"}, - {":toolbox:", "🧰"}, - {":magnet:", "🧲"}, - {":ladder:", "🪜"}, - {":alembic:", "⚗️"}, - {":test_tube:", "🧪"}, - {":petri_dish:", "🧫"}, - {":dna:", "🧬"}, - {":microscope:", "🔬"}, - {":telescope:", "🔭"}, - {":satellite:", "📡"}, - {":syringe:", "💉"}, - {":drop_of_blood:", "🩸"}, - {":pill:", "💊"}, - {":adhesive_bandage:", "🩹"}, - {":stethoscope:", "🩺"}, - {":door:", "🚪"}, - {":elevator:", "🛗"}, - {":mirror:", "🪞"}, - {":window:", "🪟"}, - {":bed:", "🛏️"}, - {":couch_and_lamp:", "🛋️"}, - {":chair:", "🪑"}, - {":toilet:", "🚽"}, - {":plunger:", "🪠"}, - {":shower:", "🚿"}, - {":bathtub:", "🛁"}, - {":mouse_trap:", "🪤"}, - {":razor:", "🪒"}, - {":lotion_bottle:", "🧴"}, - {":safety_pin:", "🧷"}, - {":broom:", "🧹"}, - {":basket:", "🧺"}, - {":roll_of_paper:", "🧻"}, - {":bucket:", "🪣"}, - {":soap:", "🧼"}, - {":toothbrush:", "🪥"}, - {":sponge:", "🧽"}, - {":fire_extinguisher:", "🧯"}, - {":shopping_cart:", "🛒"}, - {":smoking:", "🚬"}, - {":coffin:", "⚰️"}, - {":headstone:", "🪦"}, - {":funeral_urn:", "⚱️"}, - {":moyai:", "🗿"}, - {":placard:", "🪧"}, - {":atm:", "🏧"}, - {":put_litter_in_its_place:", "🚮"}, - {":potable_water:", "🚰"}, - {":wheelchair:", "♿"}, - {":mens:", "🚹"}, - {":womens:", "🚺"}, - {":restroom:", "🚻"}, - {":baby_symbol:", "🚼"}, - {":wc:", "🚾"}, - {":passport_control:", "🛂"}, - {":customs:", "🛃"}, - {":baggage_claim:", "🛄"}, - {":left_luggage:", "🛅"}, - {":warning:", "⚠️"}, - {":children_crossing:", "🚸"}, - {":no_entry:", "⛔"}, - {":no_entry_sign:", "🚫"}, - {":no_bicycles:", "🚳"}, - {":no_smoking:", "🚭"}, - {":do_not_litter:", "🚯"}, - {":non-potable_water:", "🚱"}, - {":no_pedestrians:", "🚷"}, - {":no_mobile_phones:", "📵"}, - {":underage:", "🔞"}, - {":radioactive:", "☢️"}, - {":biohazard:", "☣️"}, - {":arrow_up:", "⬆️"}, - {":arrow_upper_right:", "↗️"}, - {":arrow_right:", "➡️"}, - {":arrow_lower_right:", "↘️"}, - {":arrow_down:", "⬇️"}, - {":arrow_lower_left:", "↙️"}, - {":arrow_left:", "⬅️"}, - {":arrow_upper_left:", "↖️"}, - {":arrow_up_down:", "↕️"}, - {":left_right_arrow:", "↔️"}, - {":leftwards_arrow_with_hook:", "↩️"}, - {":arrow_right_hook:", "↪️"}, - {":arrow_heading_up:", "⤴️"}, - {":arrow_heading_down:", "⤵️"}, - {":arrows_clockwise:", "🔃"}, - {":arrows_counterclockwise:", "🔄"}, - {":back:", "🔙"}, - {":end:", "🔚"}, - {":on:", "🔛"}, - {":soon:", "🔜"}, - {":top:", "🔝"}, - {":place_of_worship:", "🛐"}, - {":atom_symbol:", "⚛️"}, - {":om:", "🕉️"}, - {":star_of_david:", "✡️"}, - {":wheel_of_dharma:", "☸️"}, - {":yin_yang:", "☯️"}, - {":latin_cross:", "✝️"}, - {":orthodox_cross:", "☦️"}, - {":star_and_crescent:", "☪️"}, - {":peace_symbol:", "☮️"}, - {":menorah:", "🕎"}, - {":six_pointed_star:", "🔯"}, - {":aries:", "♈"}, - {":taurus:", "♉"}, - {":gemini:", "♊"}, - {":cancer:", "♋"}, - {":leo:", "♌"}, - {":virgo:", "♍"}, - {":libra:", "♎"}, - {":scorpius:", "♏"}, - {":sagittarius:", "♐"}, - {":capricorn:", "♑"}, - {":aquarius:", "♒"}, - {":pisces:", "♓"}, - {":ophiuchus:", "⛎"}, - {":twisted_rightwards_arrows:", "🔀"}, - {":repeat:", "🔁"}, - {":repeat_one:", "🔂"}, - {":arrow_forward:", "▶️"}, - {":fast_forward:", "⏩"}, - {":next_track_button:", "⏭️"}, - {":play_or_pause_button:", "⏯️"}, - {":arrow_backward:", "◀️"}, - {":rewind:", "⏪"}, - {":previous_track_button:", "⏮️"}, - {":arrow_up_small:", "🔼"}, - {":arrow_double_up:", "⏫"}, - {":arrow_down_small:", "🔽"}, - {":arrow_double_down:", "⏬"}, - {":pause_button:", "⏸️"}, - {":stop_button:", "⏹️"}, - {":record_button:", "⏺️"}, - {":eject_button:", "⏏️"}, - {":cinema:", "🎦"}, - {":low_brightness:", "🔅"}, - {":high_brightness:", "🔆"}, - {":signal_strength:", "📶"}, - {":vibration_mode:", "📳"}, - {":mobile_phone_off:", "📴"}, - {":female_sign:", "♀️"}, - {":male_sign:", "♂️"}, - {":transgender_symbol:", "⚧️"}, - {":heavy_multiplication_x:", "✖️"}, - {":heavy_plus_sign:", "➕"}, - {":heavy_minus_sign:", "➖"}, - {":heavy_division_sign:", "➗"}, - {":infinity:", "♾️"}, - {":bangbang:", "‼️"}, - {":interrobang:", "⁉️"}, - {":question:", "❓"}, - {":grey_question:", "❔"}, - {":grey_exclamation:", "❕"}, - {":exclamation:", "❗"}, - {":heavy_exclamation_mark:", "❗"}, - {":wavy_dash:", "〰️"}, - {":currency_exchange:", "💱"}, - {":heavy_dollar_sign:", "💲"}, - {":medical_symbol:", "⚕️"}, - {":recycle:", "♻️"}, - {":fleur_de_lis:", "⚜️"}, - {":trident:", "🔱"}, - {":name_badge:", "📛"}, - {":beginner:", "🔰"}, - {":o:", "⭕"}, - {":white_check_mark:", "✅"}, - {":ballot_box_with_check:", "☑️"}, - {":heavy_check_mark:", "✔️"}, - {":x:", "❌"}, - {":negative_squared_cross_mark:", "❎"}, - {":curly_loop:", "➰"}, - {":loop:", "➿"}, - {":part_alternation_mark:", "〽️"}, - {":eight_spoked_asterisk:", "✳️"}, - {":eight_pointed_black_star:", "✴️"}, - {":sparkle:", "❇️"}, - {":copyright:", "©️"}, - {":registered:", "®️"}, - {":tm:", "™️"}, - {":hash:", "#️⃣"}, - {":asterisk:", "*️⃣"}, - {":zero:", "0️⃣"}, - {":one:", "1️⃣"}, - {":two:", "2️⃣"}, - {":three:", "3️⃣"}, - {":four:", "4️⃣"}, - {":five:", "5️⃣"}, - {":six:", "6️⃣"}, - {":seven:", "7️⃣"}, - {":eight:", "8️⃣"}, - {":nine:", "9️⃣"}, - {":keycap_ten:", "🔟"}, - {":capital_abcd:", "🔠"}, - {":abcd:", "🔡"}, - {":1234:", "🔢"}, - {":symbols:", "🔣"}, - {":abc:", "🔤"}, - {":a:", "🅰️"}, - {":ab:", "🆎"}, - {":b:", "🅱️"}, - {":cl:", "🆑"}, - {":cool:", "🆒"}, - {":free:", "🆓"}, - {":information_source:", "ℹ️"}, - {":id:", "🆔"}, - {":m:", "Ⓜ️"}, - {":new:", "🆕"}, - {":ng:", "🆖"}, - {":o2:", "🅾️"}, - {":ok:", "🆗"}, - {":parking:", "🅿️"}, - {":sos:", "🆘"}, - {":up:", "🆙"}, - {":vs:", "🆚"}, - {":koko:", "🈁"}, - {":sa:", "🈂️"}, - {":u6708:", "🈷️"}, - {":u6709:", "🈶"}, - {":u6307:", "🈯"}, - {":ideograph_advantage:", "🉐"}, - {":u5272:", "🈹"}, - {":u7121:", "🈚"}, - {":u7981:", "🈲"}, - {":accept:", "🉑"}, - {":u7533:", "🈸"}, - {":u5408:", "🈴"}, - {":u7a7a:", "🈳"}, - {":congratulations:", "㊗️"}, - {":secret:", "㊙️"}, - {":u55b6:", "🈺"}, - {":u6e80:", "🈵"}, - {":red_circle:", "🔴"}, - {":orange_circle:", "🟠"}, - {":yellow_circle:", "🟡"}, - {":green_circle:", "🟢"}, - {":large_blue_circle:", "🔵"}, - {":purple_circle:", "🟣"}, - {":brown_circle:", "🟤"}, - {":black_circle:", "⚫"}, - {":white_circle:", "⚪"}, - {":red_square:", "🟥"}, - {":orange_square:", "🟧"}, - {":yellow_square:", "🟨"}, - {":green_square:", "🟩"}, - {":blue_square:", "🟦"}, - {":purple_square:", "🟪"}, - {":brown_square:", "🟫"}, - {":black_large_square:", "⬛"}, - {":white_large_square:", "⬜"}, - {":black_medium_square:", "◼️"}, - {":white_medium_square:", "◻️"}, - {":black_medium_small_square:", "◾"}, - {":white_medium_small_square:", "◽"}, - {":black_small_square:", "▪️"}, - {":white_small_square:", "▫️"}, - {":large_orange_diamond:", "🔶"}, - {":large_blue_diamond:", "🔷"}, - {":small_orange_diamond:", "🔸"}, - {":small_blue_diamond:", "🔹"}, - {":small_red_triangle:", "🔺"}, - {":small_red_triangle_down:", "🔻"}, - {":diamond_shape_with_a_dot_inside:", "💠"}, - {":radio_button:", "🔘"}, - {":white_square_button:", "🔳"}, - {":black_square_button:", "🔲"}, - {":checkered_flag:", "🏁"}, - {":triangular_flag_on_post:", "🚩"}, - {":crossed_flags:", "🎌"}, - {":black_flag:", "🏴"}, - {":white_flag:", "🏳️"}, - {":rainbow_flag:", "🏳️‍🌈"}, - {":transgender_flag:", "🏳️‍⚧️"}, - {":pirate_flag:", "🏴‍☠️"}, - {":ascension_island:", "🇦🇨"}, - {":andorra:", "🇦🇩"}, - {":united_arab_emirates:", "🇦🇪"}, - {":afghanistan:", "🇦🇫"}, - {":antigua_barbuda:", "🇦🇬"}, - {":anguilla:", "🇦🇮"}, - {":albania:", "🇦🇱"}, - {":armenia:", "🇦🇲"}, - {":angola:", "🇦🇴"}, - {":antarctica:", "🇦🇶"}, - {":argentina:", "🇦🇷"}, - {":american_samoa:", "🇦🇸"}, - {":austria:", "🇦🇹"}, - {":australia:", "🇦🇺"}, - {":aruba:", "🇦🇼"}, - {":aland_islands:", "🇦🇽"}, - {":azerbaijan:", "🇦🇿"}, - {":bosnia_herzegovina:", "🇧🇦"}, - {":barbados:", "🇧🇧"}, - {":bangladesh:", "🇧🇩"}, - {":belgium:", "🇧🇪"}, - {":burkina_faso:", "🇧🇫"}, - {":bulgaria:", "🇧🇬"}, - {":bahrain:", "🇧🇭"}, - {":burundi:", "🇧🇮"}, - {":benin:", "🇧🇯"}, - {":st_barthelemy:", "🇧🇱"}, - {":bermuda:", "🇧🇲"}, - {":brunei:", "🇧🇳"}, - {":bolivia:", "🇧🇴"}, - {":caribbean_netherlands:", "🇧🇶"}, - {":brazil:", "🇧🇷"}, - {":bahamas:", "🇧🇸"}, - {":bhutan:", "🇧🇹"}, - {":bouvet_island:", "🇧🇻"}, - {":botswana:", "🇧🇼"}, - {":belarus:", "🇧🇾"}, - {":belize:", "🇧🇿"}, - {":canada:", "🇨🇦"}, - {":cocos_islands:", "🇨🇨"}, - {":congo_kinshasa:", "🇨🇩"}, - {":central_african_republic:", "🇨🇫"}, - {":congo_brazzaville:", "🇨🇬"}, - {":switzerland:", "🇨🇭"}, - {":cote_divoire:", "🇨🇮"}, - {":cook_islands:", "🇨🇰"}, - {":chile:", "🇨🇱"}, - {":cameroon:", "🇨🇲"}, - {":cn:", "🇨🇳"}, - {":colombia:", "🇨🇴"}, - {":clipperton_island:", "🇨🇵"}, - {":costa_rica:", "🇨🇷"}, - {":cuba:", "🇨🇺"}, - {":cape_verde:", "🇨🇻"}, - {":curacao:", "🇨🇼"}, - {":christmas_island:", "🇨🇽"}, - {":cyprus:", "🇨🇾"}, - {":czech_republic:", "🇨🇿"}, - {":de:", "🇩🇪"}, - {":diego_garcia:", "🇩🇬"}, - {":djibouti:", "🇩🇯"}, - {":denmark:", "🇩🇰"}, - {":dominica:", "🇩🇲"}, - {":dominican_republic:", "🇩🇴"}, - {":algeria:", "🇩🇿"}, - {":ceuta_melilla:", "🇪🇦"}, - {":ecuador:", "🇪🇨"}, - {":estonia:", "🇪🇪"}, - {":egypt:", "🇪🇬"}, - {":western_sahara:", "🇪🇭"}, - {":eritrea:", "🇪🇷"}, - {":es:", "🇪🇸"}, - {":ethiopia:", "🇪🇹"}, - {":eu:", "🇪🇺"}, - {":european_union:", "🇪🇺"}, - {":finland:", "🇫🇮"}, - {":fiji:", "🇫🇯"}, - {":falkland_islands:", "🇫🇰"}, - {":micronesia:", "🇫🇲"}, - {":faroe_islands:", "🇫🇴"}, - {":fr:", "🇫🇷"}, - {":gabon:", "🇬🇦"}, - {":gb:", "🇬🇧"}, - {":uk:", "🇬🇧"}, - {":grenada:", "🇬🇩"}, - {":georgia:", "🇬🇪"}, - {":french_guiana:", "🇬🇫"}, - {":guernsey:", "🇬🇬"}, - {":ghana:", "🇬🇭"}, - {":gibraltar:", "🇬🇮"}, - {":greenland:", "🇬🇱"}, - {":gambia:", "🇬🇲"}, - {":guinea:", "🇬🇳"}, - {":guadeloupe:", "🇬🇵"}, - {":equatorial_guinea:", "🇬🇶"}, - {":greece:", "🇬🇷"}, - {":south_georgia_south_sandwich_islands:", "🇬🇸"}, - {":guatemala:", "🇬🇹"}, - {":guam:", "🇬🇺"}, - {":guinea_bissau:", "🇬🇼"}, - {":guyana:", "🇬🇾"}, - {":hong_kong:", "🇭🇰"}, - {":heard_mcdonald_islands:", "🇭🇲"}, - {":honduras:", "🇭🇳"}, - {":croatia:", "🇭🇷"}, - {":haiti:", "🇭🇹"}, - {":hungary:", "🇭🇺"}, - {":canary_islands:", "🇮🇨"}, - {":indonesia:", "🇮🇩"}, - {":ireland:", "🇮🇪"}, - {":israel:", "🇮🇱"}, - {":isle_of_man:", "🇮🇲"}, - {":india:", "🇮🇳"}, - {":british_indian_ocean_territory:", "🇮🇴"}, - {":iraq:", "🇮🇶"}, - {":iran:", "🇮🇷"}, - {":iceland:", "🇮🇸"}, - {":it:", "🇮🇹"}, - {":jersey:", "🇯🇪"}, - {":jamaica:", "🇯🇲"}, - {":jordan:", "🇯🇴"}, - {":jp:", "🇯🇵"}, - {":kenya:", "🇰🇪"}, - {":kyrgyzstan:", "🇰🇬"}, - {":cambodia:", "🇰🇭"}, - {":kiribati:", "🇰🇮"}, - {":comoros:", "🇰🇲"}, - {":st_kitts_nevis:", "🇰🇳"}, - {":north_korea:", "🇰🇵"}, - {":kr:", "🇰🇷"}, - {":kuwait:", "🇰🇼"}, - {":cayman_islands:", "🇰🇾"}, - {":kazakhstan:", "🇰🇿"}, - {":laos:", "🇱🇦"}, - {":lebanon:", "🇱🇧"}, - {":st_lucia:", "🇱🇨"}, - {":liechtenstein:", "🇱🇮"}, - {":sri_lanka:", "🇱🇰"}, - {":liberia:", "🇱🇷"}, - {":lesotho:", "🇱🇸"}, - {":lithuania:", "🇱🇹"}, - {":luxembourg:", "🇱🇺"}, - {":latvia:", "🇱🇻"}, - {":libya:", "🇱🇾"}, - {":morocco:", "🇲🇦"}, - {":monaco:", "🇲🇨"}, - {":moldova:", "🇲🇩"}, - {":montenegro:", "🇲🇪"}, - {":st_martin:", "🇲🇫"}, - {":madagascar:", "🇲🇬"}, - {":marshall_islands:", "🇲🇭"}, - {":macedonia:", "🇲🇰"}, - {":mali:", "🇲🇱"}, - {":myanmar:", "🇲🇲"}, - {":mongolia:", "🇲🇳"}, - {":macau:", "🇲🇴"}, - {":northern_mariana_islands:", "🇲🇵"}, - {":martinique:", "🇲🇶"}, - {":mauritania:", "🇲🇷"}, - {":montserrat:", "🇲🇸"}, - {":malta:", "🇲🇹"}, - {":mauritius:", "🇲🇺"}, - {":maldives:", "🇲🇻"}, - {":malawi:", "🇲🇼"}, - {":mexico:", "🇲🇽"}, - {":malaysia:", "🇲🇾"}, - {":mozambique:", "🇲🇿"}, - {":namibia:", "🇳🇦"}, - {":new_caledonia:", "🇳🇨"}, - {":niger:", "🇳🇪"}, - {":norfolk_island:", "🇳🇫"}, - {":nigeria:", "🇳🇬"}, - {":nicaragua:", "🇳🇮"}, - {":netherlands:", "🇳🇱"}, - {":norway:", "🇳🇴"}, - {":nepal:", "🇳🇵"}, - {":nauru:", "🇳🇷"}, - {":niue:", "🇳🇺"}, - {":new_zealand:", "🇳🇿"}, - {":oman:", "🇴🇲"}, - {":panama:", "🇵🇦"}, - {":peru:", "🇵🇪"}, - {":french_polynesia:", "🇵🇫"}, - {":papua_new_guinea:", "🇵🇬"}, - {":philippines:", "🇵🇭"}, - {":pakistan:", "🇵🇰"}, - {":poland:", "🇵🇱"}, - {":st_pierre_miquelon:", "🇵🇲"}, - {":pitcairn_islands:", "🇵🇳"}, - {":puerto_rico:", "🇵🇷"}, - {":palestinian_territories:", "🇵🇸"}, - {":portugal:", "🇵🇹"}, - {":palau:", "🇵🇼"}, - {":paraguay:", "🇵🇾"}, - {":qatar:", "🇶🇦"}, - {":reunion:", "🇷🇪"}, - {":romania:", "🇷🇴"}, - {":serbia:", "🇷🇸"}, - {":ru:", "🇷🇺"}, - {":rwanda:", "🇷🇼"}, - {":saudi_arabia:", "🇸🇦"}, - {":solomon_islands:", "🇸🇧"}, - {":seychelles:", "🇸🇨"}, - {":sudan:", "🇸🇩"}, - {":sweden:", "🇸🇪"}, - {":singapore:", "🇸🇬"}, - {":st_helena:", "🇸🇭"}, - {":slovenia:", "🇸🇮"}, - {":svalbard_jan_mayen:", "🇸🇯"}, - {":slovakia:", "🇸🇰"}, - {":sierra_leone:", "🇸🇱"}, - {":san_marino:", "🇸🇲"}, - {":senegal:", "🇸🇳"}, - {":somalia:", "🇸🇴"}, - {":suriname:", "🇸🇷"}, - {":south_sudan:", "🇸🇸"}, - {":sao_tome_principe:", "🇸🇹"}, - {":el_salvador:", "🇸🇻"}, - {":sint_maarten:", "🇸🇽"}, - {":syria:", "🇸🇾"}, - {":swaziland:", "🇸🇿"}, - {":tristan_da_cunha:", "🇹🇦"}, - {":turks_caicos_islands:", "🇹🇨"}, - {":chad:", "🇹🇩"}, - {":french_southern_territories:", "🇹🇫"}, - {":togo:", "🇹🇬"}, - {":thailand:", "🇹🇭"}, - {":tajikistan:", "🇹🇯"}, - {":tokelau:", "🇹🇰"}, - {":timor_leste:", "🇹🇱"}, - {":turkmenistan:", "🇹🇲"}, - {":tunisia:", "🇹🇳"}, - {":tonga:", "🇹🇴"}, - {":tr:", "🇹🇷"}, - {":trinidad_tobago:", "🇹🇹"}, - {":tuvalu:", "🇹🇻"}, - {":taiwan:", "🇹🇼"}, - {":tanzania:", "🇹🇿"}, - {":ukraine:", "🇺🇦"}, - {":uganda:", "🇺🇬"}, - {":us_outlying_islands:", "🇺🇲"}, - {":united_nations:", "🇺🇳"}, - {":us:", "🇺🇸"}, - {":uruguay:", "🇺🇾"}, - {":uzbekistan:", "🇺🇿"}, - {":vatican_city:", "🇻🇦"}, - {":st_vincent_grenadines:", "🇻🇨"}, - {":venezuela:", "🇻🇪"}, - {":british_virgin_islands:", "🇻🇬"}, - {":us_virgin_islands:", "🇻🇮"}, - {":vietnam:", "🇻🇳"}, - {":vanuatu:", "🇻🇺"}, - {":wallis_futuna:", "🇼🇫"}, - {":samoa:", "🇼🇸"}, - {":kosovo:", "🇽🇰"}, - {":yemen:", "🇾🇪"}, - {":mayotte:", "🇾🇹"}, - {":south_africa:", "🇿🇦"}, - {":zambia:", "🇿🇲"}, - {":zimbabwe:", "🇿🇼"}, - {":england:", "🏴󠁧󠁢󠁥󠁮󠁧󠁿"}, - {":scotland:", "🏴󠁧󠁢󠁳󠁣󠁴󠁿"}, - {":wales:", "🏴󠁧󠁢󠁷󠁬󠁳󠁿"}, + {":grinning:", "\xf0\x9f\x98\x80"}, // 😀 + {":smiley:", "\xf0\x9f\x98\x83"}, // 😃 + {":smile:", "\xf0\x9f\x98\x84"}, // 😄 + {":grin:", "\xf0\x9f\x98\x81"}, // 😁 + {":laughing:", "\xf0\x9f\x98\x86"}, // 😆 + {":satisfied:", "\xf0\x9f\x98\x86"}, // 😆 + {":sweat_smile:", "\xf0\x9f\x98\x85"}, // 😅 + {":rofl:", "\xf0\x9f\xa4\xa3"}, // 🤣 + {":joy:", "\xf0\x9f\x98\x82"}, // 😂 + {":slightly_smiling_face:", "\xf0\x9f\x99\x82"}, // 🙂 + {":upside_down_face:", "\xf0\x9f\x99\x83"}, // 🙃 + {":wink:", "\xf0\x9f\x98\x89"}, // 😉 + {":blush:", "\xf0\x9f\x98\x8a"}, // 😊 + {":innocent:", "\xf0\x9f\x98\x87"}, // 😇 + {":smiling_face_with_three_hearts:", "\xf0\x9f\xa5\xb0"}, // 🥰 + {":heart_eyes:", "\xf0\x9f\x98\x8d"}, // 😍 + {":star_struck:", "\xf0\x9f\xa4\xa9"}, // 🤩 + {":kissing_heart:", "\xf0\x9f\x98\x98"}, // 😘 + {":kissing:", "\xf0\x9f\x98\x97"}, // 😗 + {":relaxed:", "\xe2\x98\xba\xef\xb8\x8f"}, // ☺️ + {":kissing_closed_eyes:", "\xf0\x9f\x98\x9a"}, // 😚 + {":kissing_smiling_eyes:", "\xf0\x9f\x98\x99"}, // 😙 + {":smiling_face_with_tear:", "\xf0\x9f\xa5\xb2"}, // 🥲 + {":yum:", "\xf0\x9f\x98\x8b"}, // 😋 + {":stuck_out_tongue:", "\xf0\x9f\x98\x9b"}, // 😛 + {":stuck_out_tongue_winking_eye:", "\xf0\x9f\x98\x9c"}, // 😜 + {":zany_face:", "\xf0\x9f\xa4\xaa"}, // 🤪 + {":stuck_out_tongue_closed_eyes:", "\xf0\x9f\x98\x9d"}, // 😝 + {":money_mouth_face:", "\xf0\x9f\xa4\x91"}, // 🤑 + {":hugs:", "\xf0\x9f\xa4\x97"}, // 🤗 + {":hand_over_mouth:", "\xf0\x9f\xa4\xad"}, // 🤭 + {":shushing_face:", "\xf0\x9f\xa4\xab"}, // 🤫 + {":thinking:", "\xf0\x9f\xa4\x94"}, // 🤔 + {":zipper_mouth_face:", "\xf0\x9f\xa4\x90"}, // 🤐 + {":raised_eyebrow:", "\xf0\x9f\xa4\xa8"}, // 🤨 + {":neutral_face:", "\xf0\x9f\x98\x90"}, // 😐 + {":expressionless:", "\xf0\x9f\x98\x91"}, // 😑 + {":no_mouth:", "\xf0\x9f\x98\xb6"}, // 😶 + {":smirk:", "\xf0\x9f\x98\x8f"}, // 😏 + {":unamused:", "\xf0\x9f\x98\x92"}, // 😒 + {":roll_eyes:", "\xf0\x9f\x99\x84"}, // 🙄 + {":grimacing:", "\xf0\x9f\x98\xac"}, // 😬 + {":lying_face:", "\xf0\x9f\xa4\xa5"}, // 🤥 + {":relieved:", "\xf0\x9f\x98\x8c"}, // 😌 + {":pensive:", "\xf0\x9f\x98\x94"}, // 😔 + {":sleepy:", "\xf0\x9f\x98\xaa"}, // 😪 + {":drooling_face:", "\xf0\x9f\xa4\xa4"}, // 🤤 + {":sleeping:", "\xf0\x9f\x98\xb4"}, // 😴 + {":mask:", "\xf0\x9f\x98\xb7"}, // 😷 + {":face_with_thermometer:", "\xf0\x9f\xa4\x92"}, // 🤒 + {":face_with_head_bandage:", "\xf0\x9f\xa4\x95"}, // 🤕 + {":nauseated_face:", "\xf0\x9f\xa4\xa2"}, // 🤢 + {":vomiting_face:", "\xf0\x9f\xa4\xae"}, // 🤮 + {":sneezing_face:", "\xf0\x9f\xa4\xa7"}, // 🤧 + {":hot_face:", "\xf0\x9f\xa5\xb5"}, // 🥵 + {":cold_face:", "\xf0\x9f\xa5\xb6"}, // 🥶 + {":woozy_face:", "\xf0\x9f\xa5\xb4"}, // 🥴 + {":dizzy_face:", "\xf0\x9f\x98\xb5"}, // 😵 + {":exploding_head:", "\xf0\x9f\xa4\xaf"}, // 🤯 + {":cowboy_hat_face:", "\xf0\x9f\xa4\xa0"}, // 🤠 + {":partying_face:", "\xf0\x9f\xa5\xb3"}, // 🥳 + {":disguised_face:", "\xf0\x9f\xa5\xb8"}, // 🥸 + {":sunglasses:", "\xf0\x9f\x98\x8e"}, // 😎 + {":nerd_face:", "\xf0\x9f\xa4\x93"}, // 🤓 + {":monocle_face:", "\xf0\x9f\xa7\x90"}, // 🧐 + {":confused:", "\xf0\x9f\x98\x95"}, // 😕 + {":worried:", "\xf0\x9f\x98\x9f"}, // 😟 + {":slightly_frowning_face:", "\xf0\x9f\x99\x81"}, // 🙁 + {":frowning_face:", "\xe2\x98\xb9\xef\xb8\x8f"}, // ☹️ + {":open_mouth:", "\xf0\x9f\x98\xae"}, // 😮 + {":hushed:", "\xf0\x9f\x98\xaf"}, // 😯 + {":astonished:", "\xf0\x9f\x98\xb2"}, // 😲 + {":flushed:", "\xf0\x9f\x98\xb3"}, // 😳 + {":pleading_face:", "\xf0\x9f\xa5\xba"}, // 🥺 + {":frowning:", "\xf0\x9f\x98\xa6"}, // 😦 + {":anguished:", "\xf0\x9f\x98\xa7"}, // 😧 + {":fearful:", "\xf0\x9f\x98\xa8"}, // 😨 + {":cold_sweat:", "\xf0\x9f\x98\xb0"}, // 😰 + {":disappointed_relieved:", "\xf0\x9f\x98\xa5"}, // 😥 + {":cry:", "\xf0\x9f\x98\xa2"}, // 😢 + {":sob:", "\xf0\x9f\x98\xad"}, // 😭 + {":scream:", "\xf0\x9f\x98\xb1"}, // 😱 + {":confounded:", "\xf0\x9f\x98\x96"}, // 😖 + {":persevere:", "\xf0\x9f\x98\xa3"}, // 😣 + {":disappointed:", "\xf0\x9f\x98\x9e"}, // 😞 + {":sweat:", "\xf0\x9f\x98\x93"}, // 😓 + {":weary:", "\xf0\x9f\x98\xa9"}, // 😩 + {":tired_face:", "\xf0\x9f\x98\xab"}, // 😫 + {":yawning_face:", "\xf0\x9f\xa5\xb1"}, // 🥱 + {":triumph:", "\xf0\x9f\x98\xa4"}, // 😤 + {":rage:", "\xf0\x9f\x98\xa1"}, // 😡 + {":pout:", "\xf0\x9f\x98\xa1"}, // 😡 + {":angry:", "\xf0\x9f\x98\xa0"}, // 😠 + {":cursing_face:", "\xf0\x9f\xa4\xac"}, // 🤬 + {":smiling_imp:", "\xf0\x9f\x98\x88"}, // 😈 + {":imp:", "\xf0\x9f\x91\xbf"}, // 👿 + {":skull:", "\xf0\x9f\x92\x80"}, // 💀 + {":skull_and_crossbones:", "\xe2\x98\xa0\xef\xb8\x8f"}, // ☠️ + {":hankey:", "\xf0\x9f\x92\xa9"}, // 💩 + {":poop:", "\xf0\x9f\x92\xa9"}, // 💩 + {":shit:", "\xf0\x9f\x92\xa9"}, // 💩 + {":clown_face:", "\xf0\x9f\xa4\xa1"}, // 🤡 + {":japanese_ogre:", "\xf0\x9f\x91\xb9"}, // 👹 + {":japanese_goblin:", "\xf0\x9f\x91\xba"}, // 👺 + {":ghost:", "\xf0\x9f\x91\xbb"}, // 👻 + {":alien:", "\xf0\x9f\x91\xbd"}, // 👽 + {":space_invader:", "\xf0\x9f\x91\xbe"}, // 👾 + {":robot:", "\xf0\x9f\xa4\x96"}, // 🤖 + {":smiley_cat:", "\xf0\x9f\x98\xba"}, // 😺 + {":smile_cat:", "\xf0\x9f\x98\xb8"}, // 😸 + {":joy_cat:", "\xf0\x9f\x98\xb9"}, // 😹 + {":heart_eyes_cat:", "\xf0\x9f\x98\xbb"}, // 😻 + {":smirk_cat:", "\xf0\x9f\x98\xbc"}, // 😼 + {":kissing_cat:", "\xf0\x9f\x98\xbd"}, // 😽 + {":scream_cat:", "\xf0\x9f\x99\x80"}, // 🙀 + {":crying_cat_face:", "\xf0\x9f\x98\xbf"}, // 😿 + {":pouting_cat:", "\xf0\x9f\x98\xbe"}, // 😾 + {":see_no_evil:", "\xf0\x9f\x99\x88"}, // 🙈 + {":hear_no_evil:", "\xf0\x9f\x99\x89"}, // 🙉 + {":speak_no_evil:", "\xf0\x9f\x99\x8a"}, // 🙊 + {":kiss:", "\xf0\x9f\x92\x8b"}, // 💋 + {":love_letter:", "\xf0\x9f\x92\x8c"}, // 💌 + {":cupid:", "\xf0\x9f\x92\x98"}, // 💘 + {":gift_heart:", "\xf0\x9f\x92\x9d"}, // 💝 + {":sparkling_heart:", "\xf0\x9f\x92\x96"}, // 💖 + {":heartpulse:", "\xf0\x9f\x92\x97"}, // 💗 + {":heartbeat:", "\xf0\x9f\x92\x93"}, // 💓 + {":revolving_hearts:", "\xf0\x9f\x92\x9e"}, // 💞 + {":two_hearts:", "\xf0\x9f\x92\x95"}, // 💕 + {":heart_decoration:", "\xf0\x9f\x92\x9f"}, // 💟 + {":heavy_heart_exclamation:", "\xe2\x9d\xa3\xef\xb8\x8f"}, // ❣️ + {":broken_heart:", "\xf0\x9f\x92\x94"}, // 💔 + {":heart:", "\xe2\x9d\xa4\xef\xb8\x8f"}, // ❤️ + {":orange_heart:", "\xf0\x9f\xa7\xa1"}, // 🧡 + {":yellow_heart:", "\xf0\x9f\x92\x9b"}, // 💛 + {":green_heart:", "\xf0\x9f\x92\x9a"}, // 💚 + {":blue_heart:", "\xf0\x9f\x92\x99"}, // 💙 + {":purple_heart:", "\xf0\x9f\x92\x9c"}, // 💜 + {":brown_heart:", "\xf0\x9f\xa4\x8e"}, // 🤎 + {":black_heart:", "\xf0\x9f\x96\xa4"}, // 🖤 + {":white_heart:", "\xf0\x9f\xa4\x8d"}, // 🤍 + {":100:", "\xf0\x9f\x92\xaf"}, // 💯 + {":anger:", "\xf0\x9f\x92\xa2"}, // 💢 + {":boom:", "\xf0\x9f\x92\xa5"}, // 💥 + {":collision:", "\xf0\x9f\x92\xa5"}, // 💥 + {":dizzy:", "\xf0\x9f\x92\xab"}, // 💫 + {":sweat_drops:", "\xf0\x9f\x92\xa6"}, // 💦 + {":dash:", "\xf0\x9f\x92\xa8"}, // 💨 + {":hole:", "\xf0\x9f\x95\xb3\xef\xb8\x8f"}, // 🕳️ + {":bomb:", "\xf0\x9f\x92\xa3"}, // 💣 + {":speech_balloon:", "\xf0\x9f\x92\xac"}, // 💬 + {":eye_speech_bubble:", "\xf0\x9f\x91\x81\xef\xb8\x8f\xe2\x80\x8d\xf0\x9f\x97\xa8\xef\xb8\x8f"}, // 👁️‍🗨️ + {":left_speech_bubble:", "\xf0\x9f\x97\xa8\xef\xb8\x8f"}, // 🗨️ + {":right_anger_bubble:", "\xf0\x9f\x97\xaf\xef\xb8\x8f"}, // 🗯️ + {":thought_balloon:", "\xf0\x9f\x92\xad"}, // 💭 + {":zzz:", "\xf0\x9f\x92\xa4"}, // 💤 + {":wave:", "\xf0\x9f\x91\x8b"}, // 👋 + {":raised_back_of_hand:", "\xf0\x9f\xa4\x9a"}, // 🤚 + {":raised_hand_with_fingers_splayed:", "\xf0\x9f\x96\x90\xef\xb8\x8f"}, // 🖐️ + {":hand:", "\xe2\x9c\x8b"}, // ✋ + {":raised_hand:", "\xe2\x9c\x8b"}, // ✋ + {":vulcan_salute:", "\xf0\x9f\x96\x96"}, // 🖖 + {":ok_hand:", "\xf0\x9f\x91\x8c"}, // 👌 + {":pinched_fingers:", "\xf0\x9f\xa4\x8c"}, // 🤌 + {":pinching_hand:", "\xf0\x9f\xa4\x8f"}, // 🤏 + {":v:", "\xe2\x9c\x8c\xef\xb8\x8f"}, // ✌️ + {":crossed_fingers:", "\xf0\x9f\xa4\x9e"}, // 🤞 + {":love_you_gesture:", "\xf0\x9f\xa4\x9f"}, // 🤟 + {":metal:", "\xf0\x9f\xa4\x98"}, // 🤘 + {":call_me_hand:", "\xf0\x9f\xa4\x99"}, // 🤙 + {":point_left:", "\xf0\x9f\x91\x88"}, // 👈 + {":point_right:", "\xf0\x9f\x91\x89"}, // 👉 + {":point_up_2:", "\xf0\x9f\x91\x86"}, // 👆 + {":middle_finger:", "\xf0\x9f\x96\x95"}, // 🖕 + {":fu:", "\xf0\x9f\x96\x95"}, // 🖕 + {":point_down:", "\xf0\x9f\x91\x87"}, // 👇 + {":point_up:", "\xe2\x98\x9d\xef\xb8\x8f"}, // ☝️ + {":+1:", "\xf0\x9f\x91\x8d"}, // 👍 + {":thumbsup:", "\xf0\x9f\x91\x8d"}, // 👍 + {":-1:", "\xf0\x9f\x91\x8e"}, // 👎 + {":thumbsdown:", "\xf0\x9f\x91\x8e"}, // 👎 + {":fist_raised:", "\xe2\x9c\x8a"}, // ✊ + {":fist:", "\xe2\x9c\x8a"}, // ✊ + {":fist_oncoming:", "\xf0\x9f\x91\x8a"}, // 👊 + {":facepunch:", "\xf0\x9f\x91\x8a"}, // 👊 + {":punch:", "\xf0\x9f\x91\x8a"}, // 👊 + {":fist_left:", "\xf0\x9f\xa4\x9b"}, // 🤛 + {":fist_right:", "\xf0\x9f\xa4\x9c"}, // 🤜 + {":clap:", "\xf0\x9f\x91\x8f"}, // 👏 + {":raised_hands:", "\xf0\x9f\x99\x8c"}, // 🙌 + {":open_hands:", "\xf0\x9f\x91\x90"}, // 👐 + {":palms_up_together:", "\xf0\x9f\xa4\xb2"}, // 🤲 + {":handshake:", "\xf0\x9f\xa4\x9d"}, // 🤝 + {":pray:", "\xf0\x9f\x99\x8f"}, // 🙏 + {":writing_hand:", "\xe2\x9c\x8d\xef\xb8\x8f"}, // ✍️ + {":nail_care:", "\xf0\x9f\x92\x85"}, // 💅 + {":selfie:", "\xf0\x9f\xa4\xb3"}, // 🤳 + {":muscle:", "\xf0\x9f\x92\xaa"}, // 💪 + {":mechanical_arm:", "\xf0\x9f\xa6\xbe"}, // 🦾 + {":mechanical_leg:", "\xf0\x9f\xa6\xbf"}, // 🦿 + {":leg:", "\xf0\x9f\xa6\xb5"}, // 🦵 + {":foot:", "\xf0\x9f\xa6\xb6"}, // 🦶 + {":ear:", "\xf0\x9f\x91\x82"}, // 👂 + {":ear_with_hearing_aid:", "\xf0\x9f\xa6\xbb"}, // 🦻 + {":nose:", "\xf0\x9f\x91\x83"}, // 👃 + {":brain:", "\xf0\x9f\xa7\xa0"}, // 🧠 + {":anatomical_heart:", "\xf0\x9f\xab\x80"}, // 🫀 + {":lungs:", "\xf0\x9f\xab\x81"}, // 🫁 + {":tooth:", "\xf0\x9f\xa6\xb7"}, // 🦷 + {":bone:", "\xf0\x9f\xa6\xb4"}, // 🦴 + {":eyes:", "\xf0\x9f\x91\x80"}, // 👀 + {":eye:", "\xf0\x9f\x91\x81\xef\xb8\x8f"}, // 👁️ + {":tongue:", "\xf0\x9f\x91\x85"}, // 👅 + {":lips:", "\xf0\x9f\x91\x84"}, // 👄 + {":baby:", "\xf0\x9f\x91\xb6"}, // 👶 + {":child:", "\xf0\x9f\xa7\x92"}, // 🧒 + {":boy:", "\xf0\x9f\x91\xa6"}, // 👦 + {":girl:", "\xf0\x9f\x91\xa7"}, // 👧 + {":adult:", "\xf0\x9f\xa7\x91"}, // 🧑 + {":blond_haired_person:", "\xf0\x9f\x91\xb1"}, // 👱 + {":man:", "\xf0\x9f\x91\xa8"}, // 👨 + {":bearded_person:", "\xf0\x9f\xa7\x94"}, // 🧔 + {":red_haired_man:", "\xf0\x9f\x91\xa8\xe2\x80\x8d\xf0\x9f\xa6\xb0"}, // 👨‍🦰 + {":curly_haired_man:", "\xf0\x9f\x91\xa8\xe2\x80\x8d\xf0\x9f\xa6\xb1"}, // 👨‍🦱 + {":white_haired_man:", "\xf0\x9f\x91\xa8\xe2\x80\x8d\xf0\x9f\xa6\xb3"}, // 👨‍🦳 + {":bald_man:", "\xf0\x9f\x91\xa8\xe2\x80\x8d\xf0\x9f\xa6\xb2"}, // 👨‍🦲 + {":woman:", "\xf0\x9f\x91\xa9"}, // 👩 + {":red_haired_woman:", "\xf0\x9f\x91\xa9\xe2\x80\x8d\xf0\x9f\xa6\xb0"}, // 👩‍🦰 + {":person_red_hair:", "\xf0\x9f\xa7\x91\xe2\x80\x8d\xf0\x9f\xa6\xb0"}, // 🧑‍🦰 + {":curly_haired_woman:", "\xf0\x9f\x91\xa9\xe2\x80\x8d\xf0\x9f\xa6\xb1"}, // 👩‍🦱 + {":person_curly_hair:", "\xf0\x9f\xa7\x91\xe2\x80\x8d\xf0\x9f\xa6\xb1"}, // 🧑‍🦱 + {":white_haired_woman:", "\xf0\x9f\x91\xa9\xe2\x80\x8d\xf0\x9f\xa6\xb3"}, // 👩‍🦳 + {":person_white_hair:", "\xf0\x9f\xa7\x91\xe2\x80\x8d\xf0\x9f\xa6\xb3"}, // 🧑‍🦳 + {":bald_woman:", "\xf0\x9f\x91\xa9\xe2\x80\x8d\xf0\x9f\xa6\xb2"}, // 👩‍🦲 + {":person_bald:", "\xf0\x9f\xa7\x91\xe2\x80\x8d\xf0\x9f\xa6\xb2"}, // 🧑‍🦲 + {":blond_haired_woman:", "\xf0\x9f\x91\xb1\xe2\x80\x8d\xe2\x99\x80\xef\xb8\x8f"}, // 👱‍♀️ + {":blonde_woman:", "\xf0\x9f\x91\xb1\xe2\x80\x8d\xe2\x99\x80\xef\xb8\x8f"}, // 👱‍♀️ + {":blond_haired_man:", "\xf0\x9f\x91\xb1\xe2\x80\x8d\xe2\x99\x82\xef\xb8\x8f"}, // 👱‍♂️ + {":older_adult:", "\xf0\x9f\xa7\x93"}, // 🧓 + {":older_man:", "\xf0\x9f\x91\xb4"}, // 👴 + {":older_woman:", "\xf0\x9f\x91\xb5"}, // 👵 + {":frowning_person:", "\xf0\x9f\x99\x8d"}, // 🙍 + {":frowning_man:", "\xf0\x9f\x99\x8d\xe2\x80\x8d\xe2\x99\x82\xef\xb8\x8f"}, // 🙍‍♂️ + {":frowning_woman:", "\xf0\x9f\x99\x8d\xe2\x80\x8d\xe2\x99\x80\xef\xb8\x8f"}, // 🙍‍♀️ + {":pouting_face:", "\xf0\x9f\x99\x8e"}, // 🙎 + {":pouting_man:", "\xf0\x9f\x99\x8e\xe2\x80\x8d\xe2\x99\x82\xef\xb8\x8f"}, // 🙎‍♂️ + {":pouting_woman:", "\xf0\x9f\x99\x8e\xe2\x80\x8d\xe2\x99\x80\xef\xb8\x8f"}, // 🙎‍♀️ + {":no_good:", "\xf0\x9f\x99\x85"}, // 🙅 + {":no_good_man:", "\xf0\x9f\x99\x85\xe2\x80\x8d\xe2\x99\x82\xef\xb8\x8f"}, // 🙅‍♂️ + {":ng_man:", "\xf0\x9f\x99\x85\xe2\x80\x8d\xe2\x99\x82\xef\xb8\x8f"}, // 🙅‍♂️ + {":no_good_woman:", "\xf0\x9f\x99\x85\xe2\x80\x8d\xe2\x99\x80\xef\xb8\x8f"}, // 🙅‍♀️ + {":ng_woman:", "\xf0\x9f\x99\x85\xe2\x80\x8d\xe2\x99\x80\xef\xb8\x8f"}, // 🙅‍♀️ + {":ok_person:", "\xf0\x9f\x99\x86"}, // 🙆 + {":ok_man:", "\xf0\x9f\x99\x86\xe2\x80\x8d\xe2\x99\x82\xef\xb8\x8f"}, // 🙆‍♂️ + {":ok_woman:", "\xf0\x9f\x99\x86\xe2\x80\x8d\xe2\x99\x80\xef\xb8\x8f"}, // 🙆‍♀️ + {":tipping_hand_person:", "\xf0\x9f\x92\x81"}, // 💁 + {":information_desk_person:", "\xf0\x9f\x92\x81"}, // 💁 + {":tipping_hand_man:", "\xf0\x9f\x92\x81\xe2\x80\x8d\xe2\x99\x82\xef\xb8\x8f"}, // 💁‍♂️ + {":sassy_man:", "\xf0\x9f\x92\x81\xe2\x80\x8d\xe2\x99\x82\xef\xb8\x8f"}, // 💁‍♂️ + {":tipping_hand_woman:", "\xf0\x9f\x92\x81\xe2\x80\x8d\xe2\x99\x80\xef\xb8\x8f"}, // 💁‍♀️ + {":sassy_woman:", "\xf0\x9f\x92\x81\xe2\x80\x8d\xe2\x99\x80\xef\xb8\x8f"}, // 💁‍♀️ + {":raising_hand:", "\xf0\x9f\x99\x8b"}, // 🙋 + {":raising_hand_man:", "\xf0\x9f\x99\x8b\xe2\x80\x8d\xe2\x99\x82\xef\xb8\x8f"}, // 🙋‍♂️ + {":raising_hand_woman:", "\xf0\x9f\x99\x8b\xe2\x80\x8d\xe2\x99\x80\xef\xb8\x8f"}, // 🙋‍♀️ + {":deaf_person:", "\xf0\x9f\xa7\x8f"}, // 🧏 + {":deaf_man:", "\xf0\x9f\xa7\x8f\xe2\x80\x8d\xe2\x99\x82\xef\xb8\x8f"}, // 🧏‍♂️ + {":deaf_woman:", "\xf0\x9f\xa7\x8f\xe2\x80\x8d\xe2\x99\x80\xef\xb8\x8f"}, // 🧏‍♀️ + {":bow:", "\xf0\x9f\x99\x87"}, // 🙇 + {":bowing_man:", "\xf0\x9f\x99\x87\xe2\x80\x8d\xe2\x99\x82\xef\xb8\x8f"}, // 🙇‍♂️ + {":bowing_woman:", "\xf0\x9f\x99\x87\xe2\x80\x8d\xe2\x99\x80\xef\xb8\x8f"}, // 🙇‍♀️ + {":facepalm:", "\xf0\x9f\xa4\xa6"}, // 🤦 + {":man_facepalming:", "\xf0\x9f\xa4\xa6\xe2\x80\x8d\xe2\x99\x82\xef\xb8\x8f"}, // 🤦‍♂️ + {":woman_facepalming:", "\xf0\x9f\xa4\xa6\xe2\x80\x8d\xe2\x99\x80\xef\xb8\x8f"}, // 🤦‍♀️ + {":shrug:", "\xf0\x9f\xa4\xb7"}, // 🤷 + {":man_shrugging:", "\xf0\x9f\xa4\xb7\xe2\x80\x8d\xe2\x99\x82\xef\xb8\x8f"}, // 🤷‍♂️ + {":woman_shrugging:", "\xf0\x9f\xa4\xb7\xe2\x80\x8d\xe2\x99\x80\xef\xb8\x8f"}, // 🤷‍♀️ + {":health_worker:", "\xf0\x9f\xa7\x91\xe2\x80\x8d\xe2\x9a\x95\xef\xb8\x8f"}, // 🧑‍⚕️ + {":man_health_worker:", "\xf0\x9f\x91\xa8\xe2\x80\x8d\xe2\x9a\x95\xef\xb8\x8f"}, // 👨‍⚕️ + {":woman_health_worker:", "\xf0\x9f\x91\xa9\xe2\x80\x8d\xe2\x9a\x95\xef\xb8\x8f"}, // 👩‍⚕️ + {":student:", "\xf0\x9f\xa7\x91\xe2\x80\x8d\xf0\x9f\x8e\x93"}, // 🧑‍🎓 + {":man_student:", "\xf0\x9f\x91\xa8\xe2\x80\x8d\xf0\x9f\x8e\x93"}, // 👨‍🎓 + {":woman_student:", "\xf0\x9f\x91\xa9\xe2\x80\x8d\xf0\x9f\x8e\x93"}, // 👩‍🎓 + {":teacher:", "\xf0\x9f\xa7\x91\xe2\x80\x8d\xf0\x9f\x8f\xab"}, // 🧑‍🏫 + {":man_teacher:", "\xf0\x9f\x91\xa8\xe2\x80\x8d\xf0\x9f\x8f\xab"}, // 👨‍🏫 + {":woman_teacher:", "\xf0\x9f\x91\xa9\xe2\x80\x8d\xf0\x9f\x8f\xab"}, // 👩‍🏫 + {":judge:", "\xf0\x9f\xa7\x91\xe2\x80\x8d\xe2\x9a\x96\xef\xb8\x8f"}, // 🧑‍⚖️ + {":man_judge:", "\xf0\x9f\x91\xa8\xe2\x80\x8d\xe2\x9a\x96\xef\xb8\x8f"}, // 👨‍⚖️ + {":woman_judge:", "\xf0\x9f\x91\xa9\xe2\x80\x8d\xe2\x9a\x96\xef\xb8\x8f"}, // 👩‍⚖️ + {":farmer:", "\xf0\x9f\xa7\x91\xe2\x80\x8d\xf0\x9f\x8c\xbe"}, // 🧑‍🌾 + {":man_farmer:", "\xf0\x9f\x91\xa8\xe2\x80\x8d\xf0\x9f\x8c\xbe"}, // 👨‍🌾 + {":woman_farmer:", "\xf0\x9f\x91\xa9\xe2\x80\x8d\xf0\x9f\x8c\xbe"}, // 👩‍🌾 + {":cook:", "\xf0\x9f\xa7\x91\xe2\x80\x8d\xf0\x9f\x8d\xb3"}, // 🧑‍🍳 + {":man_cook:", "\xf0\x9f\x91\xa8\xe2\x80\x8d\xf0\x9f\x8d\xb3"}, // 👨‍🍳 + {":woman_cook:", "\xf0\x9f\x91\xa9\xe2\x80\x8d\xf0\x9f\x8d\xb3"}, // 👩‍🍳 + {":mechanic:", "\xf0\x9f\xa7\x91\xe2\x80\x8d\xf0\x9f\x94\xa7"}, // 🧑‍🔧 + {":man_mechanic:", "\xf0\x9f\x91\xa8\xe2\x80\x8d\xf0\x9f\x94\xa7"}, // 👨‍🔧 + {":woman_mechanic:", "\xf0\x9f\x91\xa9\xe2\x80\x8d\xf0\x9f\x94\xa7"}, // 👩‍🔧 + {":factory_worker:", "\xf0\x9f\xa7\x91\xe2\x80\x8d\xf0\x9f\x8f\xad"}, // 🧑‍🏭 + {":man_factory_worker:", "\xf0\x9f\x91\xa8\xe2\x80\x8d\xf0\x9f\x8f\xad"}, // 👨‍🏭 + {":woman_factory_worker:", "\xf0\x9f\x91\xa9\xe2\x80\x8d\xf0\x9f\x8f\xad"}, // 👩‍🏭 + {":office_worker:", "\xf0\x9f\xa7\x91\xe2\x80\x8d\xf0\x9f\x92\xbc"}, // 🧑‍💼 + {":man_office_worker:", "\xf0\x9f\x91\xa8\xe2\x80\x8d\xf0\x9f\x92\xbc"}, // 👨‍💼 + {":woman_office_worker:", "\xf0\x9f\x91\xa9\xe2\x80\x8d\xf0\x9f\x92\xbc"}, // 👩‍💼 + {":scientist:", "\xf0\x9f\xa7\x91\xe2\x80\x8d\xf0\x9f\x94\xac"}, // 🧑‍🔬 + {":man_scientist:", "\xf0\x9f\x91\xa8\xe2\x80\x8d\xf0\x9f\x94\xac"}, // 👨‍🔬 + {":woman_scientist:", "\xf0\x9f\x91\xa9\xe2\x80\x8d\xf0\x9f\x94\xac"}, // 👩‍🔬 + {":technologist:", "\xf0\x9f\xa7\x91\xe2\x80\x8d\xf0\x9f\x92\xbb"}, // 🧑‍💻 + {":man_technologist:", "\xf0\x9f\x91\xa8\xe2\x80\x8d\xf0\x9f\x92\xbb"}, // 👨‍💻 + {":woman_technologist:", "\xf0\x9f\x91\xa9\xe2\x80\x8d\xf0\x9f\x92\xbb"}, // 👩‍💻 + {":singer:", "\xf0\x9f\xa7\x91\xe2\x80\x8d\xf0\x9f\x8e\xa4"}, // 🧑‍🎤 + {":man_singer:", "\xf0\x9f\x91\xa8\xe2\x80\x8d\xf0\x9f\x8e\xa4"}, // 👨‍🎤 + {":woman_singer:", "\xf0\x9f\x91\xa9\xe2\x80\x8d\xf0\x9f\x8e\xa4"}, // 👩‍🎤 + {":artist:", "\xf0\x9f\xa7\x91\xe2\x80\x8d\xf0\x9f\x8e\xa8"}, // 🧑‍🎨 + {":man_artist:", "\xf0\x9f\x91\xa8\xe2\x80\x8d\xf0\x9f\x8e\xa8"}, // 👨‍🎨 + {":woman_artist:", "\xf0\x9f\x91\xa9\xe2\x80\x8d\xf0\x9f\x8e\xa8"}, // 👩‍🎨 + {":pilot:", "\xf0\x9f\xa7\x91\xe2\x80\x8d\xe2\x9c\x88\xef\xb8\x8f"}, // 🧑‍✈️ + {":man_pilot:", "\xf0\x9f\x91\xa8\xe2\x80\x8d\xe2\x9c\x88\xef\xb8\x8f"}, // 👨‍✈️ + {":woman_pilot:", "\xf0\x9f\x91\xa9\xe2\x80\x8d\xe2\x9c\x88\xef\xb8\x8f"}, // 👩‍✈️ + {":astronaut:", "\xf0\x9f\xa7\x91\xe2\x80\x8d\xf0\x9f\x9a\x80"}, // 🧑‍🚀 + {":man_astronaut:", "\xf0\x9f\x91\xa8\xe2\x80\x8d\xf0\x9f\x9a\x80"}, // 👨‍🚀 + {":woman_astronaut:", "\xf0\x9f\x91\xa9\xe2\x80\x8d\xf0\x9f\x9a\x80"}, // 👩‍🚀 + {":firefighter:", "\xf0\x9f\xa7\x91\xe2\x80\x8d\xf0\x9f\x9a\x92"}, // 🧑‍🚒 + {":man_firefighter:", "\xf0\x9f\x91\xa8\xe2\x80\x8d\xf0\x9f\x9a\x92"}, // 👨‍🚒 + {":woman_firefighter:", "\xf0\x9f\x91\xa9\xe2\x80\x8d\xf0\x9f\x9a\x92"}, // 👩‍🚒 + {":police_officer:", "\xf0\x9f\x91\xae"}, // 👮 + {":cop:", "\xf0\x9f\x91\xae"}, // 👮 + {":policeman:", "\xf0\x9f\x91\xae\xe2\x80\x8d\xe2\x99\x82\xef\xb8\x8f"}, // 👮‍♂️ + {":policewoman:", "\xf0\x9f\x91\xae\xe2\x80\x8d\xe2\x99\x80\xef\xb8\x8f"}, // 👮‍♀️ + {":detective:", "\xf0\x9f\x95\xb5\xef\xb8\x8f"}, // 🕵️ + {":male_detective:", "\xf0\x9f\x95\xb5\xef\xb8\x8f\xe2\x80\x8d\xe2\x99\x82\xef\xb8\x8f"}, // 🕵️‍♂️ + {":female_detective:", "\xf0\x9f\x95\xb5\xef\xb8\x8f\xe2\x80\x8d\xe2\x99\x80\xef\xb8\x8f"}, // 🕵️‍♀️ + {":guard:", "\xf0\x9f\x92\x82"}, // 💂 + {":guardsman:", "\xf0\x9f\x92\x82\xe2\x80\x8d\xe2\x99\x82\xef\xb8\x8f"}, // 💂‍♂️ + {":guardswoman:", "\xf0\x9f\x92\x82\xe2\x80\x8d\xe2\x99\x80\xef\xb8\x8f"}, // 💂‍♀️ + {":ninja:", "\xf0\x9f\xa5\xb7"}, // 🥷 + {":construction_worker:", "\xf0\x9f\x91\xb7"}, // 👷 + {":construction_worker_man:", "\xf0\x9f\x91\xb7\xe2\x80\x8d\xe2\x99\x82\xef\xb8\x8f"}, // 👷‍♂️ + {":construction_worker_woman:", "\xf0\x9f\x91\xb7\xe2\x80\x8d\xe2\x99\x80\xef\xb8\x8f"}, // 👷‍♀️ + {":prince:", "\xf0\x9f\xa4\xb4"}, // 🤴 + {":princess:", "\xf0\x9f\x91\xb8"}, // 👸 + {":person_with_turban:", "\xf0\x9f\x91\xb3"}, // 👳 + {":man_with_turban:", "\xf0\x9f\x91\xb3\xe2\x80\x8d\xe2\x99\x82\xef\xb8\x8f"}, // 👳‍♂️ + {":woman_with_turban:", "\xf0\x9f\x91\xb3\xe2\x80\x8d\xe2\x99\x80\xef\xb8\x8f"}, // 👳‍♀️ + {":man_with_gua_pi_mao:", "\xf0\x9f\x91\xb2"}, // 👲 + {":woman_with_headscarf:", "\xf0\x9f\xa7\x95"}, // 🧕 + {":person_in_tuxedo:", "\xf0\x9f\xa4\xb5"}, // 🤵 + {":man_in_tuxedo:", "\xf0\x9f\xa4\xb5\xe2\x80\x8d\xe2\x99\x82\xef\xb8\x8f"}, // 🤵‍♂️ + {":woman_in_tuxedo:", "\xf0\x9f\xa4\xb5\xe2\x80\x8d\xe2\x99\x80\xef\xb8\x8f"}, // 🤵‍♀️ + {":person_with_veil:", "\xf0\x9f\x91\xb0"}, // 👰 + {":man_with_veil:", "\xf0\x9f\x91\xb0\xe2\x80\x8d\xe2\x99\x82\xef\xb8\x8f"}, // 👰‍♂️ + {":woman_with_veil:", "\xf0\x9f\x91\xb0\xe2\x80\x8d\xe2\x99\x80\xef\xb8\x8f"}, // 👰‍♀️ + {":bride_with_veil:", "\xf0\x9f\x91\xb0\xe2\x80\x8d\xe2\x99\x80\xef\xb8\x8f"}, // 👰‍♀️ + {":pregnant_woman:", "\xf0\x9f\xa4\xb0"}, // 🤰 + {":breast_feeding:", "\xf0\x9f\xa4\xb1"}, // 🤱 + {":woman_feeding_baby:", "\xf0\x9f\x91\xa9\xe2\x80\x8d\xf0\x9f\x8d\xbc"}, // 👩‍🍼 + {":man_feeding_baby:", "\xf0\x9f\x91\xa8\xe2\x80\x8d\xf0\x9f\x8d\xbc"}, // 👨‍🍼 + {":person_feeding_baby:", "\xf0\x9f\xa7\x91\xe2\x80\x8d\xf0\x9f\x8d\xbc"}, // 🧑‍🍼 + {":angel:", "\xf0\x9f\x91\xbc"}, // 👼 + {":santa:", "\xf0\x9f\x8e\x85"}, // 🎅 + {":mrs_claus:", "\xf0\x9f\xa4\xb6"}, // 🤶 + {":mx_claus:", "\xf0\x9f\xa7\x91\xe2\x80\x8d\xf0\x9f\x8e\x84"}, // 🧑‍🎄 + {":superhero:", "\xf0\x9f\xa6\xb8"}, // 🦸 + {":superhero_man:", "\xf0\x9f\xa6\xb8\xe2\x80\x8d\xe2\x99\x82\xef\xb8\x8f"}, // 🦸‍♂️ + {":superhero_woman:", "\xf0\x9f\xa6\xb8\xe2\x80\x8d\xe2\x99\x80\xef\xb8\x8f"}, // 🦸‍♀️ + {":supervillain:", "\xf0\x9f\xa6\xb9"}, // 🦹 + {":supervillain_man:", "\xf0\x9f\xa6\xb9\xe2\x80\x8d\xe2\x99\x82\xef\xb8\x8f"}, // 🦹‍♂️ + {":supervillain_woman:", "\xf0\x9f\xa6\xb9\xe2\x80\x8d\xe2\x99\x80\xef\xb8\x8f"}, // 🦹‍♀️ + {":mage:", "\xf0\x9f\xa7\x99"}, // 🧙 + {":mage_man:", "\xf0\x9f\xa7\x99\xe2\x80\x8d\xe2\x99\x82\xef\xb8\x8f"}, // 🧙‍♂️ + {":mage_woman:", "\xf0\x9f\xa7\x99\xe2\x80\x8d\xe2\x99\x80\xef\xb8\x8f"}, // 🧙‍♀️ + {":fairy:", "\xf0\x9f\xa7\x9a"}, // 🧚 + {":fairy_man:", "\xf0\x9f\xa7\x9a\xe2\x80\x8d\xe2\x99\x82\xef\xb8\x8f"}, // 🧚‍♂️ + {":fairy_woman:", "\xf0\x9f\xa7\x9a\xe2\x80\x8d\xe2\x99\x80\xef\xb8\x8f"}, // 🧚‍♀️ + {":vampire:", "\xf0\x9f\xa7\x9b"}, // 🧛 + {":vampire_man:", "\xf0\x9f\xa7\x9b\xe2\x80\x8d\xe2\x99\x82\xef\xb8\x8f"}, // 🧛‍♂️ + {":vampire_woman:", "\xf0\x9f\xa7\x9b\xe2\x80\x8d\xe2\x99\x80\xef\xb8\x8f"}, // 🧛‍♀️ + {":merperson:", "\xf0\x9f\xa7\x9c"}, // 🧜 + {":merman:", "\xf0\x9f\xa7\x9c\xe2\x80\x8d\xe2\x99\x82\xef\xb8\x8f"}, // 🧜‍♂️ + {":mermaid:", "\xf0\x9f\xa7\x9c\xe2\x80\x8d\xe2\x99\x80\xef\xb8\x8f"}, // 🧜‍♀️ + {":elf:", "\xf0\x9f\xa7\x9d"}, // 🧝 + {":elf_man:", "\xf0\x9f\xa7\x9d\xe2\x80\x8d\xe2\x99\x82\xef\xb8\x8f"}, // 🧝‍♂️ + {":elf_woman:", "\xf0\x9f\xa7\x9d\xe2\x80\x8d\xe2\x99\x80\xef\xb8\x8f"}, // 🧝‍♀️ + {":genie:", "\xf0\x9f\xa7\x9e"}, // 🧞 + {":genie_man:", "\xf0\x9f\xa7\x9e\xe2\x80\x8d\xe2\x99\x82\xef\xb8\x8f"}, // 🧞‍♂️ + {":genie_woman:", "\xf0\x9f\xa7\x9e\xe2\x80\x8d\xe2\x99\x80\xef\xb8\x8f"}, // 🧞‍♀️ + {":zombie:", "\xf0\x9f\xa7\x9f"}, // 🧟 + {":zombie_man:", "\xf0\x9f\xa7\x9f\xe2\x80\x8d\xe2\x99\x82\xef\xb8\x8f"}, // 🧟‍♂️ + {":zombie_woman:", "\xf0\x9f\xa7\x9f\xe2\x80\x8d\xe2\x99\x80\xef\xb8\x8f"}, // 🧟‍♀️ + {":massage:", "\xf0\x9f\x92\x86"}, // 💆 + {":massage_man:", "\xf0\x9f\x92\x86\xe2\x80\x8d\xe2\x99\x82\xef\xb8\x8f"}, // 💆‍♂️ + {":massage_woman:", "\xf0\x9f\x92\x86\xe2\x80\x8d\xe2\x99\x80\xef\xb8\x8f"}, // 💆‍♀️ + {":haircut:", "\xf0\x9f\x92\x87"}, // 💇 + {":haircut_man:", "\xf0\x9f\x92\x87\xe2\x80\x8d\xe2\x99\x82\xef\xb8\x8f"}, // 💇‍♂️ + {":haircut_woman:", "\xf0\x9f\x92\x87\xe2\x80\x8d\xe2\x99\x80\xef\xb8\x8f"}, // 💇‍♀️ + {":walking:", "\xf0\x9f\x9a\xb6"}, // 🚶 + {":walking_man:", "\xf0\x9f\x9a\xb6\xe2\x80\x8d\xe2\x99\x82\xef\xb8\x8f"}, // 🚶‍♂️ + {":walking_woman:", "\xf0\x9f\x9a\xb6\xe2\x80\x8d\xe2\x99\x80\xef\xb8\x8f"}, // 🚶‍♀️ + {":standing_person:", "\xf0\x9f\xa7\x8d"}, // 🧍 + {":standing_man:", "\xf0\x9f\xa7\x8d\xe2\x80\x8d\xe2\x99\x82\xef\xb8\x8f"}, // 🧍‍♂️ + {":standing_woman:", "\xf0\x9f\xa7\x8d\xe2\x80\x8d\xe2\x99\x80\xef\xb8\x8f"}, // 🧍‍♀️ + {":kneeling_person:", "\xf0\x9f\xa7\x8e"}, // 🧎 + {":kneeling_man:", "\xf0\x9f\xa7\x8e\xe2\x80\x8d\xe2\x99\x82\xef\xb8\x8f"}, // 🧎‍♂️ + {":kneeling_woman:", "\xf0\x9f\xa7\x8e\xe2\x80\x8d\xe2\x99\x80\xef\xb8\x8f"}, // 🧎‍♀️ + {":person_with_probing_cane:", "\xf0\x9f\xa7\x91\xe2\x80\x8d\xf0\x9f\xa6\xaf"}, // 🧑‍🦯 + {":man_with_probing_cane:", "\xf0\x9f\x91\xa8\xe2\x80\x8d\xf0\x9f\xa6\xaf"}, // 👨‍🦯 + {":woman_with_probing_cane:", "\xf0\x9f\x91\xa9\xe2\x80\x8d\xf0\x9f\xa6\xaf"}, // 👩‍🦯 + {":person_in_motorized_wheelchair:", "\xf0\x9f\xa7\x91\xe2\x80\x8d\xf0\x9f\xa6\xbc"}, // 🧑‍🦼 + {":man_in_motorized_wheelchair:", "\xf0\x9f\x91\xa8\xe2\x80\x8d\xf0\x9f\xa6\xbc"}, // 👨‍🦼 + {":woman_in_motorized_wheelchair:", "\xf0\x9f\x91\xa9\xe2\x80\x8d\xf0\x9f\xa6\xbc"}, // 👩‍🦼 + {":person_in_manual_wheelchair:", "\xf0\x9f\xa7\x91\xe2\x80\x8d\xf0\x9f\xa6\xbd"}, // 🧑‍🦽 + {":man_in_manual_wheelchair:", "\xf0\x9f\x91\xa8\xe2\x80\x8d\xf0\x9f\xa6\xbd"}, // 👨‍🦽 + {":woman_in_manual_wheelchair:", "\xf0\x9f\x91\xa9\xe2\x80\x8d\xf0\x9f\xa6\xbd"}, // 👩‍🦽 + {":runner:", "\xf0\x9f\x8f\x83"}, // 🏃 + {":running:", "\xf0\x9f\x8f\x83"}, // 🏃 + {":running_man:", "\xf0\x9f\x8f\x83\xe2\x80\x8d\xe2\x99\x82\xef\xb8\x8f"}, // 🏃‍♂️ + {":running_woman:", "\xf0\x9f\x8f\x83\xe2\x80\x8d\xe2\x99\x80\xef\xb8\x8f"}, // 🏃‍♀️ + {":woman_dancing:", "\xf0\x9f\x92\x83"}, // 💃 + {":dancer:", "\xf0\x9f\x92\x83"}, // 💃 + {":man_dancing:", "\xf0\x9f\x95\xba"}, // 🕺 + {":business_suit_levitating:", "\xf0\x9f\x95\xb4\xef\xb8\x8f"}, // 🕴️ + {":dancers:", "\xf0\x9f\x91\xaf"}, // 👯 + {":dancing_men:", "\xf0\x9f\x91\xaf\xe2\x80\x8d\xe2\x99\x82\xef\xb8\x8f"}, // 👯‍♂️ + {":dancing_women:", "\xf0\x9f\x91\xaf\xe2\x80\x8d\xe2\x99\x80\xef\xb8\x8f"}, // 👯‍♀️ + {":sauna_person:", "\xf0\x9f\xa7\x96"}, // 🧖 + {":sauna_man:", "\xf0\x9f\xa7\x96\xe2\x80\x8d\xe2\x99\x82\xef\xb8\x8f"}, // 🧖‍♂️ + {":sauna_woman:", "\xf0\x9f\xa7\x96\xe2\x80\x8d\xe2\x99\x80\xef\xb8\x8f"}, // 🧖‍♀️ + {":climbing:", "\xf0\x9f\xa7\x97"}, // 🧗 + {":climbing_man:", "\xf0\x9f\xa7\x97\xe2\x80\x8d\xe2\x99\x82\xef\xb8\x8f"}, // 🧗‍♂️ + {":climbing_woman:", "\xf0\x9f\xa7\x97\xe2\x80\x8d\xe2\x99\x80\xef\xb8\x8f"}, // 🧗‍♀️ + {":person_fencing:", "\xf0\x9f\xa4\xba"}, // 🤺 + {":horse_racing:", "\xf0\x9f\x8f\x87"}, // 🏇 + {":skier:", "\xe2\x9b\xb7\xef\xb8\x8f"}, // ⛷️ + {":snowboarder:", "\xf0\x9f\x8f\x82"}, // 🏂 + {":golfing:", "\xf0\x9f\x8f\x8c\xef\xb8\x8f"}, // 🏌️ + {":golfing_man:", "\xf0\x9f\x8f\x8c\xef\xb8\x8f\xe2\x80\x8d\xe2\x99\x82\xef\xb8\x8f"}, // 🏌️‍♂️ + {":golfing_woman:", "\xf0\x9f\x8f\x8c\xef\xb8\x8f\xe2\x80\x8d\xe2\x99\x80\xef\xb8\x8f"}, // 🏌️‍♀️ + {":surfer:", "\xf0\x9f\x8f\x84"}, // 🏄 + {":surfing_man:", "\xf0\x9f\x8f\x84\xe2\x80\x8d\xe2\x99\x82\xef\xb8\x8f"}, // 🏄‍♂️ + {":surfing_woman:", "\xf0\x9f\x8f\x84\xe2\x80\x8d\xe2\x99\x80\xef\xb8\x8f"}, // 🏄‍♀️ + {":rowboat:", "\xf0\x9f\x9a\xa3"}, // 🚣 + {":rowing_man:", "\xf0\x9f\x9a\xa3\xe2\x80\x8d\xe2\x99\x82\xef\xb8\x8f"}, // 🚣‍♂️ + {":rowing_woman:", "\xf0\x9f\x9a\xa3\xe2\x80\x8d\xe2\x99\x80\xef\xb8\x8f"}, // 🚣‍♀️ + {":swimmer:", "\xf0\x9f\x8f\x8a"}, // 🏊 + {":swimming_man:", "\xf0\x9f\x8f\x8a\xe2\x80\x8d\xe2\x99\x82\xef\xb8\x8f"}, // 🏊‍♂️ + {":swimming_woman:", "\xf0\x9f\x8f\x8a\xe2\x80\x8d\xe2\x99\x80\xef\xb8\x8f"}, // 🏊‍♀️ + {":bouncing_ball_person:", "\xe2\x9b\xb9\xef\xb8\x8f"}, // ⛹️ + {":bouncing_ball_man:", "\xe2\x9b\xb9\xef\xb8\x8f\xe2\x80\x8d\xe2\x99\x82\xef\xb8\x8f"}, // ⛹️‍♂️ + {":basketball_man:", "\xe2\x9b\xb9\xef\xb8\x8f\xe2\x80\x8d\xe2\x99\x82\xef\xb8\x8f"}, // ⛹️‍♂️ + {":bouncing_ball_woman:", "\xe2\x9b\xb9\xef\xb8\x8f\xe2\x80\x8d\xe2\x99\x80\xef\xb8\x8f"}, // ⛹️‍♀️ + {":basketball_woman:", "\xe2\x9b\xb9\xef\xb8\x8f\xe2\x80\x8d\xe2\x99\x80\xef\xb8\x8f"}, // ⛹️‍♀️ + {":weight_lifting:", "\xf0\x9f\x8f\x8b\xef\xb8\x8f"}, // 🏋️ + {":weight_lifting_man:", "\xf0\x9f\x8f\x8b\xef\xb8\x8f\xe2\x80\x8d\xe2\x99\x82\xef\xb8\x8f"}, // 🏋️‍♂️ + {":weight_lifting_woman:", "\xf0\x9f\x8f\x8b\xef\xb8\x8f\xe2\x80\x8d\xe2\x99\x80\xef\xb8\x8f"}, // 🏋️‍♀️ + {":bicyclist:", "\xf0\x9f\x9a\xb4"}, // 🚴 + {":biking_man:", "\xf0\x9f\x9a\xb4\xe2\x80\x8d\xe2\x99\x82\xef\xb8\x8f"}, // 🚴‍♂️ + {":biking_woman:", "\xf0\x9f\x9a\xb4\xe2\x80\x8d\xe2\x99\x80\xef\xb8\x8f"}, // 🚴‍♀️ + {":mountain_bicyclist:", "\xf0\x9f\x9a\xb5"}, // 🚵 + {":mountain_biking_man:", "\xf0\x9f\x9a\xb5\xe2\x80\x8d\xe2\x99\x82\xef\xb8\x8f"}, // 🚵‍♂️ + {":mountain_biking_woman:", "\xf0\x9f\x9a\xb5\xe2\x80\x8d\xe2\x99\x80\xef\xb8\x8f"}, // 🚵‍♀️ + {":cartwheeling:", "\xf0\x9f\xa4\xb8"}, // 🤸 + {":man_cartwheeling:", "\xf0\x9f\xa4\xb8\xe2\x80\x8d\xe2\x99\x82\xef\xb8\x8f"}, // 🤸‍♂️ + {":woman_cartwheeling:", "\xf0\x9f\xa4\xb8\xe2\x80\x8d\xe2\x99\x80\xef\xb8\x8f"}, // 🤸‍♀️ + {":wrestling:", "\xf0\x9f\xa4\xbc"}, // 🤼 + {":men_wrestling:", "\xf0\x9f\xa4\xbc\xe2\x80\x8d\xe2\x99\x82\xef\xb8\x8f"}, // 🤼‍♂️ + {":women_wrestling:", "\xf0\x9f\xa4\xbc\xe2\x80\x8d\xe2\x99\x80\xef\xb8\x8f"}, // 🤼‍♀️ + {":water_polo:", "\xf0\x9f\xa4\xbd"}, // 🤽 + {":man_playing_water_polo:", "\xf0\x9f\xa4\xbd\xe2\x80\x8d\xe2\x99\x82\xef\xb8\x8f"}, // 🤽‍♂️ + {":woman_playing_water_polo:", "\xf0\x9f\xa4\xbd\xe2\x80\x8d\xe2\x99\x80\xef\xb8\x8f"}, // 🤽‍♀️ + {":handball_person:", "\xf0\x9f\xa4\xbe"}, // 🤾 + {":man_playing_handball:", "\xf0\x9f\xa4\xbe\xe2\x80\x8d\xe2\x99\x82\xef\xb8\x8f"}, // 🤾‍♂️ + {":woman_playing_handball:", "\xf0\x9f\xa4\xbe\xe2\x80\x8d\xe2\x99\x80\xef\xb8\x8f"}, // 🤾‍♀️ + {":juggling_person:", "\xf0\x9f\xa4\xb9"}, // 🤹 + {":man_juggling:", "\xf0\x9f\xa4\xb9\xe2\x80\x8d\xe2\x99\x82\xef\xb8\x8f"}, // 🤹‍♂️ + {":woman_juggling:", "\xf0\x9f\xa4\xb9\xe2\x80\x8d\xe2\x99\x80\xef\xb8\x8f"}, // 🤹‍♀️ + {":lotus_position:", "\xf0\x9f\xa7\x98"}, // 🧘 + {":lotus_position_man:", "\xf0\x9f\xa7\x98\xe2\x80\x8d\xe2\x99\x82\xef\xb8\x8f"}, // 🧘‍♂️ + {":lotus_position_woman:", "\xf0\x9f\xa7\x98\xe2\x80\x8d\xe2\x99\x80\xef\xb8\x8f"}, // 🧘‍♀️ + {":bath:", "\xf0\x9f\x9b\x80"}, // 🛀 + {":sleeping_bed:", "\xf0\x9f\x9b\x8c"}, // 🛌 + {":people_holding_hands:", "\xf0\x9f\xa7\x91\xe2\x80\x8d\xf0\x9f\xa4\x9d\xe2\x80\x8d\xf0\x9f\xa7\x91"}, // 🧑‍🤝‍🧑 + {":two_women_holding_hands:", "\xf0\x9f\x91\xad"}, // 👭 + {":couple:", "\xf0\x9f\x91\xab"}, // 👫 + {":two_men_holding_hands:", "\xf0\x9f\x91\xac"}, // 👬 + {":couplekiss:", "\xf0\x9f\x92\x8f"}, // 💏 + {":couplekiss_man_woman:", "\xf0\x9f\x91\xa9\xe2\x80\x8d\xe2\x9d\xa4\xef\xb8\x8f\xe2\x80\x8d\xf0\x9f\x92\x8b\xe2\x80\x8d\xf0\x9f\x91\xa8"}, // 👩‍❤️‍💋‍👨 + {":couplekiss_man_man:", "\xf0\x9f\x91\xa8\xe2\x80\x8d\xe2\x9d\xa4\xef\xb8\x8f\xe2\x80\x8d\xf0\x9f\x92\x8b\xe2\x80\x8d\xf0\x9f\x91\xa8"}, // 👨‍❤️‍💋‍👨 + {":couplekiss_woman_woman:", "\xf0\x9f\x91\xa9\xe2\x80\x8d\xe2\x9d\xa4\xef\xb8\x8f\xe2\x80\x8d\xf0\x9f\x92\x8b\xe2\x80\x8d\xf0\x9f\x91\xa9"}, // 👩‍❤️‍💋‍👩 + {":couple_with_heart:", "\xf0\x9f\x92\x91"}, // 💑 + {":couple_with_heart_woman_man:", "\xf0\x9f\x91\xa9\xe2\x80\x8d\xe2\x9d\xa4\xef\xb8\x8f\xe2\x80\x8d\xf0\x9f\x91\xa8"}, // 👩‍❤️‍👨 + {":couple_with_heart_man_man:", "\xf0\x9f\x91\xa8\xe2\x80\x8d\xe2\x9d\xa4\xef\xb8\x8f\xe2\x80\x8d\xf0\x9f\x91\xa8"}, // 👨‍❤️‍👨 + {":couple_with_heart_woman_woman:", "\xf0\x9f\x91\xa9\xe2\x80\x8d\xe2\x9d\xa4\xef\xb8\x8f\xe2\x80\x8d\xf0\x9f\x91\xa9"}, // 👩‍❤️‍👩 + {":family:", "\xf0\x9f\x91\xaa"}, // 👪 + {":family_man_woman_boy:", "\xf0\x9f\x91\xa8\xe2\x80\x8d\xf0\x9f\x91\xa9\xe2\x80\x8d\xf0\x9f\x91\xa6"}, // 👨‍👩‍👦 + {":family_man_woman_girl:", "\xf0\x9f\x91\xa8\xe2\x80\x8d\xf0\x9f\x91\xa9\xe2\x80\x8d\xf0\x9f\x91\xa7"}, // 👨‍👩‍👧 + {":family_man_woman_girl_boy:", "\xf0\x9f\x91\xa8\xe2\x80\x8d\xf0\x9f\x91\xa9\xe2\x80\x8d\xf0\x9f\x91\xa7\xe2\x80\x8d\xf0\x9f\x91\xa6"}, // 👨‍👩‍👧‍👦 + {":family_man_woman_boy_boy:", "\xf0\x9f\x91\xa8\xe2\x80\x8d\xf0\x9f\x91\xa9\xe2\x80\x8d\xf0\x9f\x91\xa6\xe2\x80\x8d\xf0\x9f\x91\xa6"}, // 👨‍👩‍👦‍👦 + {":family_man_woman_girl_girl:", "\xf0\x9f\x91\xa8\xe2\x80\x8d\xf0\x9f\x91\xa9\xe2\x80\x8d\xf0\x9f\x91\xa7\xe2\x80\x8d\xf0\x9f\x91\xa7"}, // 👨‍👩‍👧‍👧 + {":family_man_man_boy:", "\xf0\x9f\x91\xa8\xe2\x80\x8d\xf0\x9f\x91\xa8\xe2\x80\x8d\xf0\x9f\x91\xa6"}, // 👨‍👨‍👦 + {":family_man_man_girl:", "\xf0\x9f\x91\xa8\xe2\x80\x8d\xf0\x9f\x91\xa8\xe2\x80\x8d\xf0\x9f\x91\xa7"}, // 👨‍👨‍👧 + {":family_man_man_girl_boy:", "\xf0\x9f\x91\xa8\xe2\x80\x8d\xf0\x9f\x91\xa8\xe2\x80\x8d\xf0\x9f\x91\xa7\xe2\x80\x8d\xf0\x9f\x91\xa6"}, // 👨‍👨‍👧‍👦 + {":family_man_man_boy_boy:", "\xf0\x9f\x91\xa8\xe2\x80\x8d\xf0\x9f\x91\xa8\xe2\x80\x8d\xf0\x9f\x91\xa6\xe2\x80\x8d\xf0\x9f\x91\xa6"}, // 👨‍👨‍👦‍👦 + {":family_man_man_girl_girl:", "\xf0\x9f\x91\xa8\xe2\x80\x8d\xf0\x9f\x91\xa8\xe2\x80\x8d\xf0\x9f\x91\xa7\xe2\x80\x8d\xf0\x9f\x91\xa7"}, // 👨‍👨‍👧‍👧 + {":family_woman_woman_boy:", "\xf0\x9f\x91\xa9\xe2\x80\x8d\xf0\x9f\x91\xa9\xe2\x80\x8d\xf0\x9f\x91\xa6"}, // 👩‍👩‍👦 + {":family_woman_woman_girl:", "\xf0\x9f\x91\xa9\xe2\x80\x8d\xf0\x9f\x91\xa9\xe2\x80\x8d\xf0\x9f\x91\xa7"}, // 👩‍👩‍👧 + {":family_woman_woman_girl_boy:", "\xf0\x9f\x91\xa9\xe2\x80\x8d\xf0\x9f\x91\xa9\xe2\x80\x8d\xf0\x9f\x91\xa7\xe2\x80\x8d\xf0\x9f\x91\xa6"}, // 👩‍👩‍👧‍👦 + {":family_woman_woman_boy_boy:", "\xf0\x9f\x91\xa9\xe2\x80\x8d\xf0\x9f\x91\xa9\xe2\x80\x8d\xf0\x9f\x91\xa6\xe2\x80\x8d\xf0\x9f\x91\xa6"}, // 👩‍👩‍👦‍👦 + {":family_woman_woman_girl_girl:", "\xf0\x9f\x91\xa9\xe2\x80\x8d\xf0\x9f\x91\xa9\xe2\x80\x8d\xf0\x9f\x91\xa7\xe2\x80\x8d\xf0\x9f\x91\xa7"}, // 👩‍👩‍👧‍👧 + {":family_man_boy:", "\xf0\x9f\x91\xa8\xe2\x80\x8d\xf0\x9f\x91\xa6"}, // 👨‍👦 + {":family_man_boy_boy:", "\xf0\x9f\x91\xa8\xe2\x80\x8d\xf0\x9f\x91\xa6\xe2\x80\x8d\xf0\x9f\x91\xa6"}, // 👨‍👦‍👦 + {":family_man_girl:", "\xf0\x9f\x91\xa8\xe2\x80\x8d\xf0\x9f\x91\xa7"}, // 👨‍👧 + {":family_man_girl_boy:", "\xf0\x9f\x91\xa8\xe2\x80\x8d\xf0\x9f\x91\xa7\xe2\x80\x8d\xf0\x9f\x91\xa6"}, // 👨‍👧‍👦 + {":family_man_girl_girl:", "\xf0\x9f\x91\xa8\xe2\x80\x8d\xf0\x9f\x91\xa7\xe2\x80\x8d\xf0\x9f\x91\xa7"}, // 👨‍👧‍👧 + {":family_woman_boy:", "\xf0\x9f\x91\xa9\xe2\x80\x8d\xf0\x9f\x91\xa6"}, // 👩‍👦 + {":family_woman_boy_boy:", "\xf0\x9f\x91\xa9\xe2\x80\x8d\xf0\x9f\x91\xa6\xe2\x80\x8d\xf0\x9f\x91\xa6"}, // 👩‍👦‍👦 + {":family_woman_girl:", "\xf0\x9f\x91\xa9\xe2\x80\x8d\xf0\x9f\x91\xa7"}, // 👩‍👧 + {":family_woman_girl_boy:", "\xf0\x9f\x91\xa9\xe2\x80\x8d\xf0\x9f\x91\xa7\xe2\x80\x8d\xf0\x9f\x91\xa6"}, // 👩‍👧‍👦 + {":family_woman_girl_girl:", "\xf0\x9f\x91\xa9\xe2\x80\x8d\xf0\x9f\x91\xa7\xe2\x80\x8d\xf0\x9f\x91\xa7"}, // 👩‍👧‍👧 + {":speaking_head:", "\xf0\x9f\x97\xa3\xef\xb8\x8f"}, // 🗣️ + {":bust_in_silhouette:", "\xf0\x9f\x91\xa4"}, // 👤 + {":busts_in_silhouette:", "\xf0\x9f\x91\xa5"}, // 👥 + {":people_hugging:", "\xf0\x9f\xab\x82"}, // 🫂 + {":footprints:", "\xf0\x9f\x91\xa3"}, // 👣 + {":monkey_face:", "\xf0\x9f\x90\xb5"}, // 🐵 + {":monkey:", "\xf0\x9f\x90\x92"}, // 🐒 + {":gorilla:", "\xf0\x9f\xa6\x8d"}, // 🦍 + {":orangutan:", "\xf0\x9f\xa6\xa7"}, // 🦧 + {":dog:", "\xf0\x9f\x90\xb6"}, // 🐶 + {":dog2:", "\xf0\x9f\x90\x95"}, // 🐕 + {":guide_dog:", "\xf0\x9f\xa6\xae"}, // 🦮 + {":service_dog:", "\xf0\x9f\x90\x95\xe2\x80\x8d\xf0\x9f\xa6\xba"}, // 🐕‍🦺 + {":poodle:", "\xf0\x9f\x90\xa9"}, // 🐩 + {":wolf:", "\xf0\x9f\x90\xba"}, // 🐺 + {":fox_face:", "\xf0\x9f\xa6\x8a"}, // 🦊 + {":raccoon:", "\xf0\x9f\xa6\x9d"}, // 🦝 + {":cat:", "\xf0\x9f\x90\xb1"}, // 🐱 + {":cat2:", "\xf0\x9f\x90\x88"}, // 🐈 + {":black_cat:", "\xf0\x9f\x90\x88\xe2\x80\x8d\xe2\xac\x9b"}, // 🐈‍⬛ + {":lion:", "\xf0\x9f\xa6\x81"}, // 🦁 + {":tiger:", "\xf0\x9f\x90\xaf"}, // 🐯 + {":tiger2:", "\xf0\x9f\x90\x85"}, // 🐅 + {":leopard:", "\xf0\x9f\x90\x86"}, // 🐆 + {":horse:", "\xf0\x9f\x90\xb4"}, // 🐴 + {":racehorse:", "\xf0\x9f\x90\x8e"}, // 🐎 + {":unicorn:", "\xf0\x9f\xa6\x84"}, // 🦄 + {":zebra:", "\xf0\x9f\xa6\x93"}, // 🦓 + {":deer:", "\xf0\x9f\xa6\x8c"}, // 🦌 + {":bison:", "\xf0\x9f\xa6\xac"}, // 🦬 + {":cow:", "\xf0\x9f\x90\xae"}, // 🐮 + {":ox:", "\xf0\x9f\x90\x82"}, // 🐂 + {":water_buffalo:", "\xf0\x9f\x90\x83"}, // 🐃 + {":cow2:", "\xf0\x9f\x90\x84"}, // 🐄 + {":pig:", "\xf0\x9f\x90\xb7"}, // 🐷 + {":pig2:", "\xf0\x9f\x90\x96"}, // 🐖 + {":boar:", "\xf0\x9f\x90\x97"}, // 🐗 + {":pig_nose:", "\xf0\x9f\x90\xbd"}, // 🐽 + {":ram:", "\xf0\x9f\x90\x8f"}, // 🐏 + {":sheep:", "\xf0\x9f\x90\x91"}, // 🐑 + {":goat:", "\xf0\x9f\x90\x90"}, // 🐐 + {":dromedary_camel:", "\xf0\x9f\x90\xaa"}, // 🐪 + {":camel:", "\xf0\x9f\x90\xab"}, // 🐫 + {":llama:", "\xf0\x9f\xa6\x99"}, // 🦙 + {":giraffe:", "\xf0\x9f\xa6\x92"}, // 🦒 + {":elephant:", "\xf0\x9f\x90\x98"}, // 🐘 + {":mammoth:", "\xf0\x9f\xa6\xa3"}, // 🦣 + {":rhinoceros:", "\xf0\x9f\xa6\x8f"}, // 🦏 + {":hippopotamus:", "\xf0\x9f\xa6\x9b"}, // 🦛 + {":mouse:", "\xf0\x9f\x90\xad"}, // 🐭 + {":mouse2:", "\xf0\x9f\x90\x81"}, // 🐁 + {":rat:", "\xf0\x9f\x90\x80"}, // 🐀 + {":hamster:", "\xf0\x9f\x90\xb9"}, // 🐹 + {":rabbit:", "\xf0\x9f\x90\xb0"}, // 🐰 + {":rabbit2:", "\xf0\x9f\x90\x87"}, // 🐇 + {":chipmunk:", "\xf0\x9f\x90\xbf\xef\xb8\x8f"}, // 🐿️ + {":beaver:", "\xf0\x9f\xa6\xab"}, // 🦫 + {":hedgehog:", "\xf0\x9f\xa6\x94"}, // 🦔 + {":bat:", "\xf0\x9f\xa6\x87"}, // 🦇 + {":bear:", "\xf0\x9f\x90\xbb"}, // 🐻 + {":polar_bear:", "\xf0\x9f\x90\xbb\xe2\x80\x8d\xe2\x9d\x84\xef\xb8\x8f"}, // 🐻‍❄️ + {":koala:", "\xf0\x9f\x90\xa8"}, // 🐨 + {":panda_face:", "\xf0\x9f\x90\xbc"}, // 🐼 + {":sloth:", "\xf0\x9f\xa6\xa5"}, // 🦥 + {":otter:", "\xf0\x9f\xa6\xa6"}, // 🦦 + {":skunk:", "\xf0\x9f\xa6\xa8"}, // 🦨 + {":kangaroo:", "\xf0\x9f\xa6\x98"}, // 🦘 + {":badger:", "\xf0\x9f\xa6\xa1"}, // 🦡 + {":feet:", "\xf0\x9f\x90\xbe"}, // 🐾 + {":paw_prints:", "\xf0\x9f\x90\xbe"}, // 🐾 + {":turkey:", "\xf0\x9f\xa6\x83"}, // 🦃 + {":chicken:", "\xf0\x9f\x90\x94"}, // 🐔 + {":rooster:", "\xf0\x9f\x90\x93"}, // 🐓 + {":hatching_chick:", "\xf0\x9f\x90\xa3"}, // 🐣 + {":baby_chick:", "\xf0\x9f\x90\xa4"}, // 🐤 + {":hatched_chick:", "\xf0\x9f\x90\xa5"}, // 🐥 + {":bird:", "\xf0\x9f\x90\xa6"}, // 🐦 + {":penguin:", "\xf0\x9f\x90\xa7"}, // 🐧 + {":dove:", "\xf0\x9f\x95\x8a\xef\xb8\x8f"}, // 🕊️ + {":eagle:", "\xf0\x9f\xa6\x85"}, // 🦅 + {":duck:", "\xf0\x9f\xa6\x86"}, // 🦆 + {":swan:", "\xf0\x9f\xa6\xa2"}, // 🦢 + {":owl:", "\xf0\x9f\xa6\x89"}, // 🦉 + {":dodo:", "\xf0\x9f\xa6\xa4"}, // 🦤 + {":feather:", "\xf0\x9f\xaa\xb6"}, // 🪶 + {":flamingo:", "\xf0\x9f\xa6\xa9"}, // 🦩 + {":peacock:", "\xf0\x9f\xa6\x9a"}, // 🦚 + {":parrot:", "\xf0\x9f\xa6\x9c"}, // 🦜 + {":frog:", "\xf0\x9f\x90\xb8"}, // 🐸 + {":crocodile:", "\xf0\x9f\x90\x8a"}, // 🐊 + {":turtle:", "\xf0\x9f\x90\xa2"}, // 🐢 + {":lizard:", "\xf0\x9f\xa6\x8e"}, // 🦎 + {":snake:", "\xf0\x9f\x90\x8d"}, // 🐍 + {":dragon_face:", "\xf0\x9f\x90\xb2"}, // 🐲 + {":dragon:", "\xf0\x9f\x90\x89"}, // 🐉 + {":sauropod:", "\xf0\x9f\xa6\x95"}, // 🦕 + {":t-rex:", "\xf0\x9f\xa6\x96"}, // 🦖 + {":whale:", "\xf0\x9f\x90\xb3"}, // 🐳 + {":whale2:", "\xf0\x9f\x90\x8b"}, // 🐋 + {":dolphin:", "\xf0\x9f\x90\xac"}, // 🐬 + {":flipper:", "\xf0\x9f\x90\xac"}, // 🐬 + {":seal:", "\xf0\x9f\xa6\xad"}, // 🦭 + {":fish:", "\xf0\x9f\x90\x9f"}, // 🐟 + {":tropical_fish:", "\xf0\x9f\x90\xa0"}, // 🐠 + {":blowfish:", "\xf0\x9f\x90\xa1"}, // 🐡 + {":shark:", "\xf0\x9f\xa6\x88"}, // 🦈 + {":octopus:", "\xf0\x9f\x90\x99"}, // 🐙 + {":shell:", "\xf0\x9f\x90\x9a"}, // 🐚 + {":snail:", "\xf0\x9f\x90\x8c"}, // 🐌 + {":butterfly:", "\xf0\x9f\xa6\x8b"}, // 🦋 + {":bug:", "\xf0\x9f\x90\x9b"}, // 🐛 + {":ant:", "\xf0\x9f\x90\x9c"}, // 🐜 + {":bee:", "\xf0\x9f\x90\x9d"}, // 🐝 + {":honeybee:", "\xf0\x9f\x90\x9d"}, // 🐝 + {":beetle:", "\xf0\x9f\xaa\xb2"}, // 🪲 + {":lady_beetle:", "\xf0\x9f\x90\x9e"}, // 🐞 + {":cricket:", "\xf0\x9f\xa6\x97"}, // 🦗 + {":cockroach:", "\xf0\x9f\xaa\xb3"}, // 🪳 + {":spider:", "\xf0\x9f\x95\xb7\xef\xb8\x8f"}, // 🕷️ + {":spider_web:", "\xf0\x9f\x95\xb8\xef\xb8\x8f"}, // 🕸️ + {":scorpion:", "\xf0\x9f\xa6\x82"}, // 🦂 + {":mosquito:", "\xf0\x9f\xa6\x9f"}, // 🦟 + {":fly:", "\xf0\x9f\xaa\xb0"}, // 🪰 + {":worm:", "\xf0\x9f\xaa\xb1"}, // 🪱 + {":microbe:", "\xf0\x9f\xa6\xa0"}, // 🦠 + {":bouquet:", "\xf0\x9f\x92\x90"}, // 💐 + {":cherry_blossom:", "\xf0\x9f\x8c\xb8"}, // 🌸 + {":white_flower:", "\xf0\x9f\x92\xae"}, // 💮 + {":rosette:", "\xf0\x9f\x8f\xb5\xef\xb8\x8f"}, // 🏵️ + {":rose:", "\xf0\x9f\x8c\xb9"}, // 🌹 + {":wilted_flower:", "\xf0\x9f\xa5\x80"}, // 🥀 + {":hibiscus:", "\xf0\x9f\x8c\xba"}, // 🌺 + {":sunflower:", "\xf0\x9f\x8c\xbb"}, // 🌻 + {":blossom:", "\xf0\x9f\x8c\xbc"}, // 🌼 + {":tulip:", "\xf0\x9f\x8c\xb7"}, // 🌷 + {":seedling:", "\xf0\x9f\x8c\xb1"}, // 🌱 + {":potted_plant:", "\xf0\x9f\xaa\xb4"}, // 🪴 + {":evergreen_tree:", "\xf0\x9f\x8c\xb2"}, // 🌲 + {":deciduous_tree:", "\xf0\x9f\x8c\xb3"}, // 🌳 + {":palm_tree:", "\xf0\x9f\x8c\xb4"}, // 🌴 + {":cactus:", "\xf0\x9f\x8c\xb5"}, // 🌵 + {":ear_of_rice:", "\xf0\x9f\x8c\xbe"}, // 🌾 + {":herb:", "\xf0\x9f\x8c\xbf"}, // 🌿 + {":shamrock:", "\xe2\x98\x98\xef\xb8\x8f"}, // ☘️ + {":four_leaf_clover:", "\xf0\x9f\x8d\x80"}, // 🍀 + {":maple_leaf:", "\xf0\x9f\x8d\x81"}, // 🍁 + {":fallen_leaf:", "\xf0\x9f\x8d\x82"}, // 🍂 + {":leaves:", "\xf0\x9f\x8d\x83"}, // 🍃 + {":grapes:", "\xf0\x9f\x8d\x87"}, // 🍇 + {":melon:", "\xf0\x9f\x8d\x88"}, // 🍈 + {":watermelon:", "\xf0\x9f\x8d\x89"}, // 🍉 + {":tangerine:", "\xf0\x9f\x8d\x8a"}, // 🍊 + {":orange:", "\xf0\x9f\x8d\x8a"}, // 🍊 + {":mandarin:", "\xf0\x9f\x8d\x8a"}, // 🍊 + {":lemon:", "\xf0\x9f\x8d\x8b"}, // 🍋 + {":banana:", "\xf0\x9f\x8d\x8c"}, // 🍌 + {":pineapple:", "\xf0\x9f\x8d\x8d"}, // 🍍 + {":mango:", "\xf0\x9f\xa5\xad"}, // 🥭 + {":apple:", "\xf0\x9f\x8d\x8e"}, // 🍎 + {":green_apple:", "\xf0\x9f\x8d\x8f"}, // 🍏 + {":pear:", "\xf0\x9f\x8d\x90"}, // 🍐 + {":peach:", "\xf0\x9f\x8d\x91"}, // 🍑 + {":cherries:", "\xf0\x9f\x8d\x92"}, // 🍒 + {":strawberry:", "\xf0\x9f\x8d\x93"}, // 🍓 + {":blueberries:", "\xf0\x9f\xab\x90"}, // 🫐 + {":kiwi_fruit:", "\xf0\x9f\xa5\x9d"}, // 🥝 + {":tomato:", "\xf0\x9f\x8d\x85"}, // 🍅 + {":olive:", "\xf0\x9f\xab\x92"}, // 🫒 + {":coconut:", "\xf0\x9f\xa5\xa5"}, // 🥥 + {":avocado:", "\xf0\x9f\xa5\x91"}, // 🥑 + {":eggplant:", "\xf0\x9f\x8d\x86"}, // 🍆 + {":potato:", "\xf0\x9f\xa5\x94"}, // 🥔 + {":carrot:", "\xf0\x9f\xa5\x95"}, // 🥕 + {":corn:", "\xf0\x9f\x8c\xbd"}, // 🌽 + {":hot_pepper:", "\xf0\x9f\x8c\xb6\xef\xb8\x8f"}, // 🌶️ + {":bell_pepper:", "\xf0\x9f\xab\x91"}, // 🫑 + {":cucumber:", "\xf0\x9f\xa5\x92"}, // 🥒 + {":leafy_green:", "\xf0\x9f\xa5\xac"}, // 🥬 + {":broccoli:", "\xf0\x9f\xa5\xa6"}, // 🥦 + {":garlic:", "\xf0\x9f\xa7\x84"}, // 🧄 + {":onion:", "\xf0\x9f\xa7\x85"}, // 🧅 + {":mushroom:", "\xf0\x9f\x8d\x84"}, // 🍄 + {":peanuts:", "\xf0\x9f\xa5\x9c"}, // 🥜 + {":chestnut:", "\xf0\x9f\x8c\xb0"}, // 🌰 + {":bread:", "\xf0\x9f\x8d\x9e"}, // 🍞 + {":croissant:", "\xf0\x9f\xa5\x90"}, // 🥐 + {":baguette_bread:", "\xf0\x9f\xa5\x96"}, // 🥖 + {":flatbread:", "\xf0\x9f\xab\x93"}, // 🫓 + {":pretzel:", "\xf0\x9f\xa5\xa8"}, // 🥨 + {":bagel:", "\xf0\x9f\xa5\xaf"}, // 🥯 + {":pancakes:", "\xf0\x9f\xa5\x9e"}, // 🥞 + {":waffle:", "\xf0\x9f\xa7\x87"}, // 🧇 + {":cheese:", "\xf0\x9f\xa7\x80"}, // 🧀 + {":meat_on_bone:", "\xf0\x9f\x8d\x96"}, // 🍖 + {":poultry_leg:", "\xf0\x9f\x8d\x97"}, // 🍗 + {":cut_of_meat:", "\xf0\x9f\xa5\xa9"}, // 🥩 + {":bacon:", "\xf0\x9f\xa5\x93"}, // 🥓 + {":hamburger:", "\xf0\x9f\x8d\x94"}, // 🍔 + {":fries:", "\xf0\x9f\x8d\x9f"}, // 🍟 + {":pizza:", "\xf0\x9f\x8d\x95"}, // 🍕 + {":hotdog:", "\xf0\x9f\x8c\xad"}, // 🌭 + {":sandwich:", "\xf0\x9f\xa5\xaa"}, // 🥪 + {":taco:", "\xf0\x9f\x8c\xae"}, // 🌮 + {":burrito:", "\xf0\x9f\x8c\xaf"}, // 🌯 + {":tamale:", "\xf0\x9f\xab\x94"}, // 🫔 + {":stuffed_flatbread:", "\xf0\x9f\xa5\x99"}, // 🥙 + {":falafel:", "\xf0\x9f\xa7\x86"}, // 🧆 + {":egg:", "\xf0\x9f\xa5\x9a"}, // 🥚 + {":fried_egg:", "\xf0\x9f\x8d\xb3"}, // 🍳 + {":shallow_pan_of_food:", "\xf0\x9f\xa5\x98"}, // 🥘 + {":stew:", "\xf0\x9f\x8d\xb2"}, // 🍲 + {":fondue:", "\xf0\x9f\xab\x95"}, // 🫕 + {":bowl_with_spoon:", "\xf0\x9f\xa5\xa3"}, // 🥣 + {":green_salad:", "\xf0\x9f\xa5\x97"}, // 🥗 + {":popcorn:", "\xf0\x9f\x8d\xbf"}, // 🍿 + {":butter:", "\xf0\x9f\xa7\x88"}, // 🧈 + {":salt:", "\xf0\x9f\xa7\x82"}, // 🧂 + {":canned_food:", "\xf0\x9f\xa5\xab"}, // 🥫 + {":bento:", "\xf0\x9f\x8d\xb1"}, // 🍱 + {":rice_cracker:", "\xf0\x9f\x8d\x98"}, // 🍘 + {":rice_ball:", "\xf0\x9f\x8d\x99"}, // 🍙 + {":rice:", "\xf0\x9f\x8d\x9a"}, // 🍚 + {":curry:", "\xf0\x9f\x8d\x9b"}, // 🍛 + {":ramen:", "\xf0\x9f\x8d\x9c"}, // 🍜 + {":spaghetti:", "\xf0\x9f\x8d\x9d"}, // 🍝 + {":sweet_potato:", "\xf0\x9f\x8d\xa0"}, // 🍠 + {":oden:", "\xf0\x9f\x8d\xa2"}, // 🍢 + {":sushi:", "\xf0\x9f\x8d\xa3"}, // 🍣 + {":fried_shrimp:", "\xf0\x9f\x8d\xa4"}, // 🍤 + {":fish_cake:", "\xf0\x9f\x8d\xa5"}, // 🍥 + {":moon_cake:", "\xf0\x9f\xa5\xae"}, // 🥮 + {":dango:", "\xf0\x9f\x8d\xa1"}, // 🍡 + {":dumpling:", "\xf0\x9f\xa5\x9f"}, // 🥟 + {":fortune_cookie:", "\xf0\x9f\xa5\xa0"}, // 🥠 + {":takeout_box:", "\xf0\x9f\xa5\xa1"}, // 🥡 + {":crab:", "\xf0\x9f\xa6\x80"}, // 🦀 + {":lobster:", "\xf0\x9f\xa6\x9e"}, // 🦞 + {":shrimp:", "\xf0\x9f\xa6\x90"}, // 🦐 + {":squid:", "\xf0\x9f\xa6\x91"}, // 🦑 + {":oyster:", "\xf0\x9f\xa6\xaa"}, // 🦪 + {":icecream:", "\xf0\x9f\x8d\xa6"}, // 🍦 + {":shaved_ice:", "\xf0\x9f\x8d\xa7"}, // 🍧 + {":ice_cream:", "\xf0\x9f\x8d\xa8"}, // 🍨 + {":doughnut:", "\xf0\x9f\x8d\xa9"}, // 🍩 + {":cookie:", "\xf0\x9f\x8d\xaa"}, // 🍪 + {":birthday:", "\xf0\x9f\x8e\x82"}, // 🎂 + {":cake:", "\xf0\x9f\x8d\xb0"}, // 🍰 + {":cupcake:", "\xf0\x9f\xa7\x81"}, // 🧁 + {":pie:", "\xf0\x9f\xa5\xa7"}, // 🥧 + {":chocolate_bar:", "\xf0\x9f\x8d\xab"}, // 🍫 + {":candy:", "\xf0\x9f\x8d\xac"}, // 🍬 + {":lollipop:", "\xf0\x9f\x8d\xad"}, // 🍭 + {":custard:", "\xf0\x9f\x8d\xae"}, // 🍮 + {":honey_pot:", "\xf0\x9f\x8d\xaf"}, // 🍯 + {":baby_bottle:", "\xf0\x9f\x8d\xbc"}, // 🍼 + {":milk_glass:", "\xf0\x9f\xa5\x9b"}, // 🥛 + {":coffee:", "\xe2\x98\x95"}, // ☕ + {":teapot:", "\xf0\x9f\xab\x96"}, // 🫖 + {":tea:", "\xf0\x9f\x8d\xb5"}, // 🍵 + {":sake:", "\xf0\x9f\x8d\xb6"}, // 🍶 + {":champagne:", "\xf0\x9f\x8d\xbe"}, // 🍾 + {":wine_glass:", "\xf0\x9f\x8d\xb7"}, // 🍷 + {":cocktail:", "\xf0\x9f\x8d\xb8"}, // 🍸 + {":tropical_drink:", "\xf0\x9f\x8d\xb9"}, // 🍹 + {":beer:", "\xf0\x9f\x8d\xba"}, // 🍺 + {":beers:", "\xf0\x9f\x8d\xbb"}, // 🍻 + {":clinking_glasses:", "\xf0\x9f\xa5\x82"}, // 🥂 + {":tumbler_glass:", "\xf0\x9f\xa5\x83"}, // 🥃 + {":cup_with_straw:", "\xf0\x9f\xa5\xa4"}, // 🥤 + {":bubble_tea:", "\xf0\x9f\xa7\x8b"}, // 🧋 + {":beverage_box:", "\xf0\x9f\xa7\x83"}, // 🧃 + {":mate:", "\xf0\x9f\xa7\x89"}, // 🧉 + {":ice_cube:", "\xf0\x9f\xa7\x8a"}, // 🧊 + {":chopsticks:", "\xf0\x9f\xa5\xa2"}, // 🥢 + {":plate_with_cutlery:", "\xf0\x9f\x8d\xbd\xef\xb8\x8f"}, // 🍽️ + {":fork_and_knife:", "\xf0\x9f\x8d\xb4"}, // 🍴 + {":spoon:", "\xf0\x9f\xa5\x84"}, // 🥄 + {":hocho:", "\xf0\x9f\x94\xaa"}, // 🔪 + {":knife:", "\xf0\x9f\x94\xaa"}, // 🔪 + {":amphora:", "\xf0\x9f\x8f\xba"}, // 🏺 + {":earth_africa:", "\xf0\x9f\x8c\x8d"}, // 🌍 + {":earth_americas:", "\xf0\x9f\x8c\x8e"}, // 🌎 + {":earth_asia:", "\xf0\x9f\x8c\x8f"}, // 🌏 + {":globe_with_meridians:", "\xf0\x9f\x8c\x90"}, // 🌐 + {":world_map:", "\xf0\x9f\x97\xba\xef\xb8\x8f"}, // 🗺️ + {":japan:", "\xf0\x9f\x97\xbe"}, // 🗾 + {":compass:", "\xf0\x9f\xa7\xad"}, // 🧭 + {":mountain_snow:", "\xf0\x9f\x8f\x94\xef\xb8\x8f"}, // 🏔️ + {":mountain:", "\xe2\x9b\xb0\xef\xb8\x8f"}, // ⛰️ + {":volcano:", "\xf0\x9f\x8c\x8b"}, // 🌋 + {":mount_fuji:", "\xf0\x9f\x97\xbb"}, // 🗻 + {":camping:", "\xf0\x9f\x8f\x95\xef\xb8\x8f"}, // 🏕️ + {":beach_umbrella:", "\xf0\x9f\x8f\x96\xef\xb8\x8f"}, // 🏖️ + {":desert:", "\xf0\x9f\x8f\x9c\xef\xb8\x8f"}, // 🏜️ + {":desert_island:", "\xf0\x9f\x8f\x9d\xef\xb8\x8f"}, // 🏝️ + {":national_park:", "\xf0\x9f\x8f\x9e\xef\xb8\x8f"}, // 🏞️ + {":stadium:", "\xf0\x9f\x8f\x9f\xef\xb8\x8f"}, // 🏟️ + {":classical_building:", "\xf0\x9f\x8f\x9b\xef\xb8\x8f"}, // 🏛️ + {":building_construction:", "\xf0\x9f\x8f\x97\xef\xb8\x8f"}, // 🏗️ + {":bricks:", "\xf0\x9f\xa7\xb1"}, // 🧱 + {":rock:", "\xf0\x9f\xaa\xa8"}, // 🪨 + {":wood:", "\xf0\x9f\xaa\xb5"}, // 🪵 + {":hut:", "\xf0\x9f\x9b\x96"}, // 🛖 + {":houses:", "\xf0\x9f\x8f\x98\xef\xb8\x8f"}, // 🏘️ + {":derelict_house:", "\xf0\x9f\x8f\x9a\xef\xb8\x8f"}, // 🏚️ + {":house:", "\xf0\x9f\x8f\xa0"}, // 🏠 + {":house_with_garden:", "\xf0\x9f\x8f\xa1"}, // 🏡 + {":office:", "\xf0\x9f\x8f\xa2"}, // 🏢 + {":post_office:", "\xf0\x9f\x8f\xa3"}, // 🏣 + {":european_post_office:", "\xf0\x9f\x8f\xa4"}, // 🏤 + {":hospital:", "\xf0\x9f\x8f\xa5"}, // 🏥 + {":bank:", "\xf0\x9f\x8f\xa6"}, // 🏦 + {":hotel:", "\xf0\x9f\x8f\xa8"}, // 🏨 + {":love_hotel:", "\xf0\x9f\x8f\xa9"}, // 🏩 + {":convenience_store:", "\xf0\x9f\x8f\xaa"}, // 🏪 + {":school:", "\xf0\x9f\x8f\xab"}, // 🏫 + {":department_store:", "\xf0\x9f\x8f\xac"}, // 🏬 + {":factory:", "\xf0\x9f\x8f\xad"}, // 🏭 + {":japanese_castle:", "\xf0\x9f\x8f\xaf"}, // 🏯 + {":european_castle:", "\xf0\x9f\x8f\xb0"}, // 🏰 + {":wedding:", "\xf0\x9f\x92\x92"}, // 💒 + {":tokyo_tower:", "\xf0\x9f\x97\xbc"}, // 🗼 + {":statue_of_liberty:", "\xf0\x9f\x97\xbd"}, // 🗽 + {":church:", "\xe2\x9b\xaa"}, // ⛪ + {":mosque:", "\xf0\x9f\x95\x8c"}, // 🕌 + {":hindu_temple:", "\xf0\x9f\x9b\x95"}, // 🛕 + {":synagogue:", "\xf0\x9f\x95\x8d"}, // 🕍 + {":shinto_shrine:", "\xe2\x9b\xa9\xef\xb8\x8f"}, // ⛩️ + {":kaaba:", "\xf0\x9f\x95\x8b"}, // 🕋 + {":fountain:", "\xe2\x9b\xb2"}, // ⛲ + {":tent:", "\xe2\x9b\xba"}, // ⛺ + {":foggy:", "\xf0\x9f\x8c\x81"}, // 🌁 + {":night_with_stars:", "\xf0\x9f\x8c\x83"}, // 🌃 + {":cityscape:", "\xf0\x9f\x8f\x99\xef\xb8\x8f"}, // 🏙️ + {":sunrise_over_mountains:", "\xf0\x9f\x8c\x84"}, // 🌄 + {":sunrise:", "\xf0\x9f\x8c\x85"}, // 🌅 + {":city_sunset:", "\xf0\x9f\x8c\x86"}, // 🌆 + {":city_sunrise:", "\xf0\x9f\x8c\x87"}, // 🌇 + {":bridge_at_night:", "\xf0\x9f\x8c\x89"}, // 🌉 + {":hotsprings:", "\xe2\x99\xa8\xef\xb8\x8f"}, // ♨️ + {":carousel_horse:", "\xf0\x9f\x8e\xa0"}, // 🎠 + {":ferris_wheel:", "\xf0\x9f\x8e\xa1"}, // 🎡 + {":roller_coaster:", "\xf0\x9f\x8e\xa2"}, // 🎢 + {":barber:", "\xf0\x9f\x92\x88"}, // 💈 + {":circus_tent:", "\xf0\x9f\x8e\xaa"}, // 🎪 + {":steam_locomotive:", "\xf0\x9f\x9a\x82"}, // 🚂 + {":railway_car:", "\xf0\x9f\x9a\x83"}, // 🚃 + {":bullettrain_side:", "\xf0\x9f\x9a\x84"}, // 🚄 + {":bullettrain_front:", "\xf0\x9f\x9a\x85"}, // 🚅 + {":train2:", "\xf0\x9f\x9a\x86"}, // 🚆 + {":metro:", "\xf0\x9f\x9a\x87"}, // 🚇 + {":light_rail:", "\xf0\x9f\x9a\x88"}, // 🚈 + {":station:", "\xf0\x9f\x9a\x89"}, // 🚉 + {":tram:", "\xf0\x9f\x9a\x8a"}, // 🚊 + {":monorail:", "\xf0\x9f\x9a\x9d"}, // 🚝 + {":mountain_railway:", "\xf0\x9f\x9a\x9e"}, // 🚞 + {":train:", "\xf0\x9f\x9a\x8b"}, // 🚋 + {":bus:", "\xf0\x9f\x9a\x8c"}, // 🚌 + {":oncoming_bus:", "\xf0\x9f\x9a\x8d"}, // 🚍 + {":trolleybus:", "\xf0\x9f\x9a\x8e"}, // 🚎 + {":minibus:", "\xf0\x9f\x9a\x90"}, // 🚐 + {":ambulance:", "\xf0\x9f\x9a\x91"}, // 🚑 + {":fire_engine:", "\xf0\x9f\x9a\x92"}, // 🚒 + {":police_car:", "\xf0\x9f\x9a\x93"}, // 🚓 + {":oncoming_police_car:", "\xf0\x9f\x9a\x94"}, // 🚔 + {":taxi:", "\xf0\x9f\x9a\x95"}, // 🚕 + {":oncoming_taxi:", "\xf0\x9f\x9a\x96"}, // 🚖 + {":car:", "\xf0\x9f\x9a\x97"}, // 🚗 + {":red_car:", "\xf0\x9f\x9a\x97"}, // 🚗 + {":oncoming_automobile:", "\xf0\x9f\x9a\x98"}, // 🚘 + {":blue_car:", "\xf0\x9f\x9a\x99"}, // 🚙 + {":pickup_truck:", "\xf0\x9f\x9b\xbb"}, // 🛻 + {":truck:", "\xf0\x9f\x9a\x9a"}, // 🚚 + {":articulated_lorry:", "\xf0\x9f\x9a\x9b"}, // 🚛 + {":tractor:", "\xf0\x9f\x9a\x9c"}, // 🚜 + {":racing_car:", "\xf0\x9f\x8f\x8e\xef\xb8\x8f"}, // 🏎️ + {":motorcycle:", "\xf0\x9f\x8f\x8d\xef\xb8\x8f"}, // 🏍️ + {":motor_scooter:", "\xf0\x9f\x9b\xb5"}, // 🛵 + {":manual_wheelchair:", "\xf0\x9f\xa6\xbd"}, // 🦽 + {":motorized_wheelchair:", "\xf0\x9f\xa6\xbc"}, // 🦼 + {":auto_rickshaw:", "\xf0\x9f\x9b\xba"}, // 🛺 + {":bike:", "\xf0\x9f\x9a\xb2"}, // 🚲 + {":kick_scooter:", "\xf0\x9f\x9b\xb4"}, // 🛴 + {":skateboard:", "\xf0\x9f\x9b\xb9"}, // 🛹 + {":roller_skate:", "\xf0\x9f\x9b\xbc"}, // 🛼 + {":busstop:", "\xf0\x9f\x9a\x8f"}, // 🚏 + {":motorway:", "\xf0\x9f\x9b\xa3\xef\xb8\x8f"}, // 🛣️ + {":railway_track:", "\xf0\x9f\x9b\xa4\xef\xb8\x8f"}, // 🛤️ + {":oil_drum:", "\xf0\x9f\x9b\xa2\xef\xb8\x8f"}, // 🛢️ + {":fuelpump:", "\xe2\x9b\xbd"}, // ⛽ + {":rotating_light:", "\xf0\x9f\x9a\xa8"}, // 🚨 + {":traffic_light:", "\xf0\x9f\x9a\xa5"}, // 🚥 + {":vertical_traffic_light:", "\xf0\x9f\x9a\xa6"}, // 🚦 + {":stop_sign:", "\xf0\x9f\x9b\x91"}, // 🛑 + {":construction:", "\xf0\x9f\x9a\xa7"}, // 🚧 + {":anchor:", "\xe2\x9a\x93"}, // ⚓ + {":boat:", "\xe2\x9b\xb5"}, // ⛵ + {":sailboat:", "\xe2\x9b\xb5"}, // ⛵ + {":canoe:", "\xf0\x9f\x9b\xb6"}, // 🛶 + {":speedboat:", "\xf0\x9f\x9a\xa4"}, // 🚤 + {":passenger_ship:", "\xf0\x9f\x9b\xb3\xef\xb8\x8f"}, // 🛳️ + {":ferry:", "\xe2\x9b\xb4\xef\xb8\x8f"}, // ⛴️ + {":motor_boat:", "\xf0\x9f\x9b\xa5\xef\xb8\x8f"}, // 🛥️ + {":ship:", "\xf0\x9f\x9a\xa2"}, // 🚢 + {":airplane:", "\xe2\x9c\x88\xef\xb8\x8f"}, // ✈️ + {":small_airplane:", "\xf0\x9f\x9b\xa9\xef\xb8\x8f"}, // 🛩️ + {":flight_departure:", "\xf0\x9f\x9b\xab"}, // 🛫 + {":flight_arrival:", "\xf0\x9f\x9b\xac"}, // 🛬 + {":parachute:", "\xf0\x9f\xaa\x82"}, // 🪂 + {":seat:", "\xf0\x9f\x92\xba"}, // 💺 + {":helicopter:", "\xf0\x9f\x9a\x81"}, // 🚁 + {":suspension_railway:", "\xf0\x9f\x9a\x9f"}, // 🚟 + {":mountain_cableway:", "\xf0\x9f\x9a\xa0"}, // 🚠 + {":aerial_tramway:", "\xf0\x9f\x9a\xa1"}, // 🚡 + {":artificial_satellite:", "\xf0\x9f\x9b\xb0\xef\xb8\x8f"}, // 🛰️ + {":rocket:", "\xf0\x9f\x9a\x80"}, // 🚀 + {":flying_saucer:", "\xf0\x9f\x9b\xb8"}, // 🛸 + {":bellhop_bell:", "\xf0\x9f\x9b\x8e\xef\xb8\x8f"}, // 🛎️ + {":luggage:", "\xf0\x9f\xa7\xb3"}, // 🧳 + {":hourglass:", "\xe2\x8c\x9b"}, // ⌛ + {":hourglass_flowing_sand:", "\xe2\x8f\xb3"}, // ⏳ + {":watch:", "\xe2\x8c\x9a"}, // ⌚ + {":alarm_clock:", "\xe2\x8f\xb0"}, // ⏰ + {":stopwatch:", "\xe2\x8f\xb1\xef\xb8\x8f"}, // ⏱️ + {":timer_clock:", "\xe2\x8f\xb2\xef\xb8\x8f"}, // ⏲️ + {":mantelpiece_clock:", "\xf0\x9f\x95\xb0\xef\xb8\x8f"}, // 🕰️ + {":clock12:", "\xf0\x9f\x95\x9b"}, // 🕛 + {":clock1230:", "\xf0\x9f\x95\xa7"}, // 🕧 + {":clock1:", "\xf0\x9f\x95\x90"}, // 🕐 + {":clock130:", "\xf0\x9f\x95\x9c"}, // 🕜 + {":clock2:", "\xf0\x9f\x95\x91"}, // 🕑 + {":clock230:", "\xf0\x9f\x95\x9d"}, // 🕝 + {":clock3:", "\xf0\x9f\x95\x92"}, // 🕒 + {":clock330:", "\xf0\x9f\x95\x9e"}, // 🕞 + {":clock4:", "\xf0\x9f\x95\x93"}, // 🕓 + {":clock430:", "\xf0\x9f\x95\x9f"}, // 🕟 + {":clock5:", "\xf0\x9f\x95\x94"}, // 🕔 + {":clock530:", "\xf0\x9f\x95\xa0"}, // 🕠 + {":clock6:", "\xf0\x9f\x95\x95"}, // 🕕 + {":clock630:", "\xf0\x9f\x95\xa1"}, // 🕡 + {":clock7:", "\xf0\x9f\x95\x96"}, // 🕖 + {":clock730:", "\xf0\x9f\x95\xa2"}, // 🕢 + {":clock8:", "\xf0\x9f\x95\x97"}, // 🕗 + {":clock830:", "\xf0\x9f\x95\xa3"}, // 🕣 + {":clock9:", "\xf0\x9f\x95\x98"}, // 🕘 + {":clock930:", "\xf0\x9f\x95\xa4"}, // 🕤 + {":clock10:", "\xf0\x9f\x95\x99"}, // 🕙 + {":clock1030:", "\xf0\x9f\x95\xa5"}, // 🕥 + {":clock11:", "\xf0\x9f\x95\x9a"}, // 🕚 + {":clock1130:", "\xf0\x9f\x95\xa6"}, // 🕦 + {":new_moon:", "\xf0\x9f\x8c\x91"}, // 🌑 + {":waxing_crescent_moon:", "\xf0\x9f\x8c\x92"}, // 🌒 + {":first_quarter_moon:", "\xf0\x9f\x8c\x93"}, // 🌓 + {":moon:", "\xf0\x9f\x8c\x94"}, // 🌔 + {":waxing_gibbous_moon:", "\xf0\x9f\x8c\x94"}, // 🌔 + {":full_moon:", "\xf0\x9f\x8c\x95"}, // 🌕 + {":waning_gibbous_moon:", "\xf0\x9f\x8c\x96"}, // 🌖 + {":last_quarter_moon:", "\xf0\x9f\x8c\x97"}, // 🌗 + {":waning_crescent_moon:", "\xf0\x9f\x8c\x98"}, // 🌘 + {":crescent_moon:", "\xf0\x9f\x8c\x99"}, // 🌙 + {":new_moon_with_face:", "\xf0\x9f\x8c\x9a"}, // 🌚 + {":first_quarter_moon_with_face:", "\xf0\x9f\x8c\x9b"}, // 🌛 + {":last_quarter_moon_with_face:", "\xf0\x9f\x8c\x9c"}, // 🌜 + {":thermometer:", "\xf0\x9f\x8c\xa1\xef\xb8\x8f"}, // 🌡️ + {":sunny:", "\xe2\x98\x80\xef\xb8\x8f"}, // ☀️ + {":full_moon_with_face:", "\xf0\x9f\x8c\x9d"}, // 🌝 + {":sun_with_face:", "\xf0\x9f\x8c\x9e"}, // 🌞 + {":ringed_planet:", "\xf0\x9f\xaa\x90"}, // 🪐 + {":star:", "\xe2\xad\x90"}, // ⭐ + {":star2:", "\xf0\x9f\x8c\x9f"}, // 🌟 + {":stars:", "\xf0\x9f\x8c\xa0"}, // 🌠 + {":milky_way:", "\xf0\x9f\x8c\x8c"}, // 🌌 + {":cloud:", "\xe2\x98\x81\xef\xb8\x8f"}, // ☁️ + {":partly_sunny:", "\xe2\x9b\x85"}, // ⛅ + {":cloud_with_lightning_and_rain:", "\xe2\x9b\x88\xef\xb8\x8f"}, // ⛈️ + {":sun_behind_small_cloud:", "\xf0\x9f\x8c\xa4\xef\xb8\x8f"}, // 🌤️ + {":sun_behind_large_cloud:", "\xf0\x9f\x8c\xa5\xef\xb8\x8f"}, // 🌥️ + {":sun_behind_rain_cloud:", "\xf0\x9f\x8c\xa6\xef\xb8\x8f"}, // 🌦️ + {":cloud_with_rain:", "\xf0\x9f\x8c\xa7\xef\xb8\x8f"}, // 🌧️ + {":cloud_with_snow:", "\xf0\x9f\x8c\xa8\xef\xb8\x8f"}, // 🌨️ + {":cloud_with_lightning:", "\xf0\x9f\x8c\xa9\xef\xb8\x8f"}, // 🌩️ + {":tornado:", "\xf0\x9f\x8c\xaa\xef\xb8\x8f"}, // 🌪️ + {":fog:", "\xf0\x9f\x8c\xab\xef\xb8\x8f"}, // 🌫️ + {":wind_face:", "\xf0\x9f\x8c\xac\xef\xb8\x8f"}, // 🌬️ + {":cyclone:", "\xf0\x9f\x8c\x80"}, // 🌀 + {":rainbow:", "\xf0\x9f\x8c\x88"}, // 🌈 + {":closed_umbrella:", "\xf0\x9f\x8c\x82"}, // 🌂 + {":open_umbrella:", "\xe2\x98\x82\xef\xb8\x8f"}, // ☂️ + {":umbrella:", "\xe2\x98\x94"}, // ☔ + {":parasol_on_ground:", "\xe2\x9b\xb1\xef\xb8\x8f"}, // ⛱️ + {":zap:", "\xe2\x9a\xa1"}, // ⚡ + {":snowflake:", "\xe2\x9d\x84\xef\xb8\x8f"}, // ❄️ + {":snowman_with_snow:", "\xe2\x98\x83\xef\xb8\x8f"}, // ☃️ + {":snowman:", "\xe2\x9b\x84"}, // ⛄ + {":comet:", "\xe2\x98\x84\xef\xb8\x8f"}, // ☄️ + {":fire:", "\xf0\x9f\x94\xa5"}, // 🔥 + {":droplet:", "\xf0\x9f\x92\xa7"}, // 💧 + {":ocean:", "\xf0\x9f\x8c\x8a"}, // 🌊 + {":jack_o_lantern:", "\xf0\x9f\x8e\x83"}, // 🎃 + {":christmas_tree:", "\xf0\x9f\x8e\x84"}, // 🎄 + {":fireworks:", "\xf0\x9f\x8e\x86"}, // 🎆 + {":sparkler:", "\xf0\x9f\x8e\x87"}, // 🎇 + {":firecracker:", "\xf0\x9f\xa7\xa8"}, // 🧨 + {":sparkles:", "\xe2\x9c\xa8"}, // ✨ + {":balloon:", "\xf0\x9f\x8e\x88"}, // 🎈 + {":tada:", "\xf0\x9f\x8e\x89"}, // 🎉 + {":confetti_ball:", "\xf0\x9f\x8e\x8a"}, // 🎊 + {":tanabata_tree:", "\xf0\x9f\x8e\x8b"}, // 🎋 + {":bamboo:", "\xf0\x9f\x8e\x8d"}, // 🎍 + {":dolls:", "\xf0\x9f\x8e\x8e"}, // 🎎 + {":flags:", "\xf0\x9f\x8e\x8f"}, // 🎏 + {":wind_chime:", "\xf0\x9f\x8e\x90"}, // 🎐 + {":rice_scene:", "\xf0\x9f\x8e\x91"}, // 🎑 + {":red_envelope:", "\xf0\x9f\xa7\xa7"}, // 🧧 + {":ribbon:", "\xf0\x9f\x8e\x80"}, // 🎀 + {":gift:", "\xf0\x9f\x8e\x81"}, // 🎁 + {":reminder_ribbon:", "\xf0\x9f\x8e\x97\xef\xb8\x8f"}, // 🎗️ + {":tickets:", "\xf0\x9f\x8e\x9f\xef\xb8\x8f"}, // 🎟️ + {":ticket:", "\xf0\x9f\x8e\xab"}, // 🎫 + {":medal_military:", "\xf0\x9f\x8e\x96\xef\xb8\x8f"}, // 🎖️ + {":trophy:", "\xf0\x9f\x8f\x86"}, // 🏆 + {":medal_sports:", "\xf0\x9f\x8f\x85"}, // 🏅 + {":1st_place_medal:", "\xf0\x9f\xa5\x87"}, // 🥇 + {":2nd_place_medal:", "\xf0\x9f\xa5\x88"}, // 🥈 + {":3rd_place_medal:", "\xf0\x9f\xa5\x89"}, // 🥉 + {":soccer:", "\xe2\x9a\xbd"}, // ⚽ + {":baseball:", "\xe2\x9a\xbe"}, // ⚾ + {":softball:", "\xf0\x9f\xa5\x8e"}, // 🥎 + {":basketball:", "\xf0\x9f\x8f\x80"}, // 🏀 + {":volleyball:", "\xf0\x9f\x8f\x90"}, // 🏐 + {":football:", "\xf0\x9f\x8f\x88"}, // 🏈 + {":rugby_football:", "\xf0\x9f\x8f\x89"}, // 🏉 + {":tennis:", "\xf0\x9f\x8e\xbe"}, // 🎾 + {":flying_disc:", "\xf0\x9f\xa5\x8f"}, // 🥏 + {":bowling:", "\xf0\x9f\x8e\xb3"}, // 🎳 + {":cricket_game:", "\xf0\x9f\x8f\x8f"}, // 🏏 + {":field_hockey:", "\xf0\x9f\x8f\x91"}, // 🏑 + {":ice_hockey:", "\xf0\x9f\x8f\x92"}, // 🏒 + {":lacrosse:", "\xf0\x9f\xa5\x8d"}, // 🥍 + {":ping_pong:", "\xf0\x9f\x8f\x93"}, // 🏓 + {":badminton:", "\xf0\x9f\x8f\xb8"}, // 🏸 + {":boxing_glove:", "\xf0\x9f\xa5\x8a"}, // 🥊 + {":martial_arts_uniform:", "\xf0\x9f\xa5\x8b"}, // 🥋 + {":goal_net:", "\xf0\x9f\xa5\x85"}, // 🥅 + {":golf:", "\xe2\x9b\xb3"}, // ⛳ + {":ice_skate:", "\xe2\x9b\xb8\xef\xb8\x8f"}, // ⛸️ + {":fishing_pole_and_fish:", "\xf0\x9f\x8e\xa3"}, // 🎣 + {":diving_mask:", "\xf0\x9f\xa4\xbf"}, // 🤿 + {":running_shirt_with_sash:", "\xf0\x9f\x8e\xbd"}, // 🎽 + {":ski:", "\xf0\x9f\x8e\xbf"}, // 🎿 + {":sled:", "\xf0\x9f\x9b\xb7"}, // 🛷 + {":curling_stone:", "\xf0\x9f\xa5\x8c"}, // 🥌 + {":dart:", "\xf0\x9f\x8e\xaf"}, // 🎯 + {":yo_yo:", "\xf0\x9f\xaa\x80"}, // 🪀 + {":kite:", "\xf0\x9f\xaa\x81"}, // 🪁 + {":8ball:", "\xf0\x9f\x8e\xb1"}, // 🎱 + {":crystal_ball:", "\xf0\x9f\x94\xae"}, // 🔮 + {":magic_wand:", "\xf0\x9f\xaa\x84"}, // 🪄 + {":nazar_amulet:", "\xf0\x9f\xa7\xbf"}, // 🧿 + {":video_game:", "\xf0\x9f\x8e\xae"}, // 🎮 + {":joystick:", "\xf0\x9f\x95\xb9\xef\xb8\x8f"}, // 🕹️ + {":slot_machine:", "\xf0\x9f\x8e\xb0"}, // 🎰 + {":game_die:", "\xf0\x9f\x8e\xb2"}, // 🎲 + {":jigsaw:", "\xf0\x9f\xa7\xa9"}, // 🧩 + {":teddy_bear:", "\xf0\x9f\xa7\xb8"}, // 🧸 + {":pi_ata:", "\xf0\x9f\xaa\x85"}, // 🪅 + {":nesting_dolls:", "\xf0\x9f\xaa\x86"}, // 🪆 + {":spades:", "\xe2\x99\xa0\xef\xb8\x8f"}, // ♠️ + {":hearts:", "\xe2\x99\xa5\xef\xb8\x8f"}, // ♥️ + {":diamonds:", "\xe2\x99\xa6\xef\xb8\x8f"}, // ♦️ + {":clubs:", "\xe2\x99\xa3\xef\xb8\x8f"}, // ♣️ + {":chess_pawn:", "\xe2\x99\x9f\xef\xb8\x8f"}, // ♟️ + {":black_joker:", "\xf0\x9f\x83\x8f"}, // 🃏 + {":mahjong:", "\xf0\x9f\x80\x84"}, // 🀄 + {":flower_playing_cards:", "\xf0\x9f\x8e\xb4"}, // 🎴 + {":performing_arts:", "\xf0\x9f\x8e\xad"}, // 🎭 + {":framed_picture:", "\xf0\x9f\x96\xbc\xef\xb8\x8f"}, // 🖼️ + {":art:", "\xf0\x9f\x8e\xa8"}, // 🎨 + {":thread:", "\xf0\x9f\xa7\xb5"}, // 🧵 + {":sewing_needle:", "\xf0\x9f\xaa\xa1"}, // 🪡 + {":yarn:", "\xf0\x9f\xa7\xb6"}, // 🧶 + {":knot:", "\xf0\x9f\xaa\xa2"}, // 🪢 + {":eyeglasses:", "\xf0\x9f\x91\x93"}, // 👓 + {":dark_sunglasses:", "\xf0\x9f\x95\xb6\xef\xb8\x8f"}, // 🕶️ + {":goggles:", "\xf0\x9f\xa5\xbd"}, // 🥽 + {":lab_coat:", "\xf0\x9f\xa5\xbc"}, // 🥼 + {":safety_vest:", "\xf0\x9f\xa6\xba"}, // 🦺 + {":necktie:", "\xf0\x9f\x91\x94"}, // 👔 + {":shirt:", "\xf0\x9f\x91\x95"}, // 👕 + {":tshirt:", "\xf0\x9f\x91\x95"}, // 👕 + {":jeans:", "\xf0\x9f\x91\x96"}, // 👖 + {":scarf:", "\xf0\x9f\xa7\xa3"}, // 🧣 + {":gloves:", "\xf0\x9f\xa7\xa4"}, // 🧤 + {":coat:", "\xf0\x9f\xa7\xa5"}, // 🧥 + {":socks:", "\xf0\x9f\xa7\xa6"}, // 🧦 + {":dress:", "\xf0\x9f\x91\x97"}, // 👗 + {":kimono:", "\xf0\x9f\x91\x98"}, // 👘 + {":sari:", "\xf0\x9f\xa5\xbb"}, // 🥻 + {":one_piece_swimsuit:", "\xf0\x9f\xa9\xb1"}, // 🩱 + {":swim_brief:", "\xf0\x9f\xa9\xb2"}, // 🩲 + {":shorts:", "\xf0\x9f\xa9\xb3"}, // 🩳 + {":bikini:", "\xf0\x9f\x91\x99"}, // 👙 + {":womans_clothes:", "\xf0\x9f\x91\x9a"}, // 👚 + {":purse:", "\xf0\x9f\x91\x9b"}, // 👛 + {":handbag:", "\xf0\x9f\x91\x9c"}, // 👜 + {":pouch:", "\xf0\x9f\x91\x9d"}, // 👝 + {":shopping:", "\xf0\x9f\x9b\x8d\xef\xb8\x8f"}, // 🛍️ + {":school_satchel:", "\xf0\x9f\x8e\x92"}, // 🎒 + {":thong_sandal:", "\xf0\x9f\xa9\xb4"}, // 🩴 + {":mans_shoe:", "\xf0\x9f\x91\x9e"}, // 👞 + {":shoe:", "\xf0\x9f\x91\x9e"}, // 👞 + {":athletic_shoe:", "\xf0\x9f\x91\x9f"}, // 👟 + {":hiking_boot:", "\xf0\x9f\xa5\xbe"}, // 🥾 + {":flat_shoe:", "\xf0\x9f\xa5\xbf"}, // 🥿 + {":high_heel:", "\xf0\x9f\x91\xa0"}, // 👠 + {":sandal:", "\xf0\x9f\x91\xa1"}, // 👡 + {":ballet_shoes:", "\xf0\x9f\xa9\xb0"}, // 🩰 + {":boot:", "\xf0\x9f\x91\xa2"}, // 👢 + {":crown:", "\xf0\x9f\x91\x91"}, // 👑 + {":womans_hat:", "\xf0\x9f\x91\x92"}, // 👒 + {":tophat:", "\xf0\x9f\x8e\xa9"}, // 🎩 + {":mortar_board:", "\xf0\x9f\x8e\x93"}, // 🎓 + {":billed_cap:", "\xf0\x9f\xa7\xa2"}, // 🧢 + {":military_helmet:", "\xf0\x9f\xaa\x96"}, // 🪖 + {":rescue_worker_helmet:", "\xe2\x9b\x91\xef\xb8\x8f"}, // ⛑️ + {":prayer_beads:", "\xf0\x9f\x93\xbf"}, // 📿 + {":lipstick:", "\xf0\x9f\x92\x84"}, // 💄 + {":ring:", "\xf0\x9f\x92\x8d"}, // 💍 + {":gem:", "\xf0\x9f\x92\x8e"}, // 💎 + {":mute:", "\xf0\x9f\x94\x87"}, // 🔇 + {":speaker:", "\xf0\x9f\x94\x88"}, // 🔈 + {":sound:", "\xf0\x9f\x94\x89"}, // 🔉 + {":loud_sound:", "\xf0\x9f\x94\x8a"}, // 🔊 + {":loudspeaker:", "\xf0\x9f\x93\xa2"}, // 📢 + {":mega:", "\xf0\x9f\x93\xa3"}, // 📣 + {":postal_horn:", "\xf0\x9f\x93\xaf"}, // 📯 + {":bell:", "\xf0\x9f\x94\x94"}, // 🔔 + {":no_bell:", "\xf0\x9f\x94\x95"}, // 🔕 + {":musical_score:", "\xf0\x9f\x8e\xbc"}, // 🎼 + {":musical_note:", "\xf0\x9f\x8e\xb5"}, // 🎵 + {":notes:", "\xf0\x9f\x8e\xb6"}, // 🎶 + {":studio_microphone:", "\xf0\x9f\x8e\x99\xef\xb8\x8f"}, // 🎙️ + {":level_slider:", "\xf0\x9f\x8e\x9a\xef\xb8\x8f"}, // 🎚️ + {":control_knobs:", "\xf0\x9f\x8e\x9b\xef\xb8\x8f"}, // 🎛️ + {":microphone:", "\xf0\x9f\x8e\xa4"}, // 🎤 + {":headphones:", "\xf0\x9f\x8e\xa7"}, // 🎧 + {":radio:", "\xf0\x9f\x93\xbb"}, // 📻 + {":saxophone:", "\xf0\x9f\x8e\xb7"}, // 🎷 + {":accordion:", "\xf0\x9f\xaa\x97"}, // 🪗 + {":guitar:", "\xf0\x9f\x8e\xb8"}, // 🎸 + {":musical_keyboard:", "\xf0\x9f\x8e\xb9"}, // 🎹 + {":trumpet:", "\xf0\x9f\x8e\xba"}, // 🎺 + {":violin:", "\xf0\x9f\x8e\xbb"}, // 🎻 + {":banjo:", "\xf0\x9f\xaa\x95"}, // 🪕 + {":drum:", "\xf0\x9f\xa5\x81"}, // 🥁 + {":long_drum:", "\xf0\x9f\xaa\x98"}, // 🪘 + {":iphone:", "\xf0\x9f\x93\xb1"}, // 📱 + {":calling:", "\xf0\x9f\x93\xb2"}, // 📲 + {":phone:", "\xe2\x98\x8e\xef\xb8\x8f"}, // ☎️ + {":telephone:", "\xe2\x98\x8e\xef\xb8\x8f"}, // ☎️ + {":telephone_receiver:", "\xf0\x9f\x93\x9e"}, // 📞 + {":pager:", "\xf0\x9f\x93\x9f"}, // 📟 + {":fax:", "\xf0\x9f\x93\xa0"}, // 📠 + {":battery:", "\xf0\x9f\x94\x8b"}, // 🔋 + {":electric_plug:", "\xf0\x9f\x94\x8c"}, // 🔌 + {":computer:", "\xf0\x9f\x92\xbb"}, // 💻 + {":desktop_computer:", "\xf0\x9f\x96\xa5\xef\xb8\x8f"}, // 🖥️ + {":printer:", "\xf0\x9f\x96\xa8\xef\xb8\x8f"}, // 🖨️ + {":keyboard:", "\xe2\x8c\xa8\xef\xb8\x8f"}, // ⌨️ + {":computer_mouse:", "\xf0\x9f\x96\xb1\xef\xb8\x8f"}, // 🖱️ + {":trackball:", "\xf0\x9f\x96\xb2\xef\xb8\x8f"}, // 🖲️ + {":minidisc:", "\xf0\x9f\x92\xbd"}, // 💽 + {":floppy_disk:", "\xf0\x9f\x92\xbe"}, // 💾 + {":cd:", "\xf0\x9f\x92\xbf"}, // 💿 + {":dvd:", "\xf0\x9f\x93\x80"}, // 📀 + {":abacus:", "\xf0\x9f\xa7\xae"}, // 🧮 + {":movie_camera:", "\xf0\x9f\x8e\xa5"}, // 🎥 + {":film_strip:", "\xf0\x9f\x8e\x9e\xef\xb8\x8f"}, // 🎞️ + {":film_projector:", "\xf0\x9f\x93\xbd\xef\xb8\x8f"}, // 📽️ + {":clapper:", "\xf0\x9f\x8e\xac"}, // 🎬 + {":tv:", "\xf0\x9f\x93\xba"}, // 📺 + {":camera:", "\xf0\x9f\x93\xb7"}, // 📷 + {":camera_flash:", "\xf0\x9f\x93\xb8"}, // 📸 + {":video_camera:", "\xf0\x9f\x93\xb9"}, // 📹 + {":vhs:", "\xf0\x9f\x93\xbc"}, // 📼 + {":mag:", "\xf0\x9f\x94\x8d"}, // 🔍 + {":mag_right:", "\xf0\x9f\x94\x8e"}, // 🔎 + {":candle:", "\xf0\x9f\x95\xaf\xef\xb8\x8f"}, // 🕯️ + {":bulb:", "\xf0\x9f\x92\xa1"}, // 💡 + {":flashlight:", "\xf0\x9f\x94\xa6"}, // 🔦 + {":izakaya_lantern:", "\xf0\x9f\x8f\xae"}, // 🏮 + {":lantern:", "\xf0\x9f\x8f\xae"}, // 🏮 + {":diya_lamp:", "\xf0\x9f\xaa\x94"}, // 🪔 + {":notebook_with_decorative_cover:", "\xf0\x9f\x93\x94"}, // 📔 + {":closed_book:", "\xf0\x9f\x93\x95"}, // 📕 + {":book:", "\xf0\x9f\x93\x96"}, // 📖 + {":open_book:", "\xf0\x9f\x93\x96"}, // 📖 + {":green_book:", "\xf0\x9f\x93\x97"}, // 📗 + {":blue_book:", "\xf0\x9f\x93\x98"}, // 📘 + {":orange_book:", "\xf0\x9f\x93\x99"}, // 📙 + {":books:", "\xf0\x9f\x93\x9a"}, // 📚 + {":notebook:", "\xf0\x9f\x93\x93"}, // 📓 + {":ledger:", "\xf0\x9f\x93\x92"}, // 📒 + {":page_with_curl:", "\xf0\x9f\x93\x83"}, // 📃 + {":scroll:", "\xf0\x9f\x93\x9c"}, // 📜 + {":page_facing_up:", "\xf0\x9f\x93\x84"}, // 📄 + {":newspaper:", "\xf0\x9f\x93\xb0"}, // 📰 + {":newspaper_roll:", "\xf0\x9f\x97\x9e\xef\xb8\x8f"}, // 🗞️ + {":bookmark_tabs:", "\xf0\x9f\x93\x91"}, // 📑 + {":bookmark:", "\xf0\x9f\x94\x96"}, // 🔖 + {":label:", "\xf0\x9f\x8f\xb7\xef\xb8\x8f"}, // 🏷️ + {":moneybag:", "\xf0\x9f\x92\xb0"}, // 💰 + {":coin:", "\xf0\x9f\xaa\x99"}, // 🪙 + {":yen:", "\xf0\x9f\x92\xb4"}, // 💴 + {":dollar:", "\xf0\x9f\x92\xb5"}, // 💵 + {":euro:", "\xf0\x9f\x92\xb6"}, // 💶 + {":pound:", "\xf0\x9f\x92\xb7"}, // 💷 + {":money_with_wings:", "\xf0\x9f\x92\xb8"}, // 💸 + {":credit_card:", "\xf0\x9f\x92\xb3"}, // 💳 + {":receipt:", "\xf0\x9f\xa7\xbe"}, // 🧾 + {":chart:", "\xf0\x9f\x92\xb9"}, // 💹 + {":email:", "\xe2\x9c\x89\xef\xb8\x8f"}, // ✉️ + {":envelope:", "\xe2\x9c\x89\xef\xb8\x8f"}, // ✉️ + {":e-mail:", "\xf0\x9f\x93\xa7"}, // 📧 + {":incoming_envelope:", "\xf0\x9f\x93\xa8"}, // 📨 + {":envelope_with_arrow:", "\xf0\x9f\x93\xa9"}, // 📩 + {":outbox_tray:", "\xf0\x9f\x93\xa4"}, // 📤 + {":inbox_tray:", "\xf0\x9f\x93\xa5"}, // 📥 + {":package:", "\xf0\x9f\x93\xa6"}, // 📦 + {":mailbox:", "\xf0\x9f\x93\xab"}, // 📫 + {":mailbox_closed:", "\xf0\x9f\x93\xaa"}, // 📪 + {":mailbox_with_mail:", "\xf0\x9f\x93\xac"}, // 📬 + {":mailbox_with_no_mail:", "\xf0\x9f\x93\xad"}, // 📭 + {":postbox:", "\xf0\x9f\x93\xae"}, // 📮 + {":ballot_box:", "\xf0\x9f\x97\xb3\xef\xb8\x8f"}, // 🗳️ + {":pencil2:", "\xe2\x9c\x8f\xef\xb8\x8f"}, // ✏️ + {":black_nib:", "\xe2\x9c\x92\xef\xb8\x8f"}, // ✒️ + {":fountain_pen:", "\xf0\x9f\x96\x8b\xef\xb8\x8f"}, // 🖋️ + {":pen:", "\xf0\x9f\x96\x8a\xef\xb8\x8f"}, // 🖊️ + {":paintbrush:", "\xf0\x9f\x96\x8c\xef\xb8\x8f"}, // 🖌️ + {":crayon:", "\xf0\x9f\x96\x8d\xef\xb8\x8f"}, // 🖍️ + {":memo:", "\xf0\x9f\x93\x9d"}, // 📝 + {":pencil:", "\xf0\x9f\x93\x9d"}, // 📝 + {":briefcase:", "\xf0\x9f\x92\xbc"}, // 💼 + {":file_folder:", "\xf0\x9f\x93\x81"}, // 📁 + {":open_file_folder:", "\xf0\x9f\x93\x82"}, // 📂 + {":card_index_dividers:", "\xf0\x9f\x97\x82\xef\xb8\x8f"}, // 🗂️ + {":date:", "\xf0\x9f\x93\x85"}, // 📅 + {":calendar:", "\xf0\x9f\x93\x86"}, // 📆 + {":spiral_notepad:", "\xf0\x9f\x97\x92\xef\xb8\x8f"}, // 🗒️ + {":spiral_calendar:", "\xf0\x9f\x97\x93\xef\xb8\x8f"}, // 🗓️ + {":card_index:", "\xf0\x9f\x93\x87"}, // 📇 + {":chart_with_upwards_trend:", "\xf0\x9f\x93\x88"}, // 📈 + {":chart_with_downwards_trend:", "\xf0\x9f\x93\x89"}, // 📉 + {":bar_chart:", "\xf0\x9f\x93\x8a"}, // 📊 + {":clipboard:", "\xf0\x9f\x93\x8b"}, // 📋 + {":pushpin:", "\xf0\x9f\x93\x8c"}, // 📌 + {":round_pushpin:", "\xf0\x9f\x93\x8d"}, // 📍 + {":paperclip:", "\xf0\x9f\x93\x8e"}, // 📎 + {":paperclips:", "\xf0\x9f\x96\x87\xef\xb8\x8f"}, // 🖇️ + {":straight_ruler:", "\xf0\x9f\x93\x8f"}, // 📏 + {":triangular_ruler:", "\xf0\x9f\x93\x90"}, // 📐 + {":scissors:", "\xe2\x9c\x82\xef\xb8\x8f"}, // ✂️ + {":card_file_box:", "\xf0\x9f\x97\x83\xef\xb8\x8f"}, // 🗃️ + {":file_cabinet:", "\xf0\x9f\x97\x84\xef\xb8\x8f"}, // 🗄️ + {":wastebasket:", "\xf0\x9f\x97\x91\xef\xb8\x8f"}, // 🗑️ + {":lock:", "\xf0\x9f\x94\x92"}, // 🔒 + {":unlock:", "\xf0\x9f\x94\x93"}, // 🔓 + {":lock_with_ink_pen:", "\xf0\x9f\x94\x8f"}, // 🔏 + {":closed_lock_with_key:", "\xf0\x9f\x94\x90"}, // 🔐 + {":key:", "\xf0\x9f\x94\x91"}, // 🔑 + {":old_key:", "\xf0\x9f\x97\x9d\xef\xb8\x8f"}, // 🗝️ + {":hammer:", "\xf0\x9f\x94\xa8"}, // 🔨 + {":axe:", "\xf0\x9f\xaa\x93"}, // 🪓 + {":pick:", "\xe2\x9b\x8f\xef\xb8\x8f"}, // ⛏️ + {":hammer_and_pick:", "\xe2\x9a\x92\xef\xb8\x8f"}, // ⚒️ + {":hammer_and_wrench:", "\xf0\x9f\x9b\xa0\xef\xb8\x8f"}, // 🛠️ + {":dagger:", "\xf0\x9f\x97\xa1\xef\xb8\x8f"}, // 🗡️ + {":crossed_swords:", "\xe2\x9a\x94\xef\xb8\x8f"}, // ⚔️ + {":gun:", "\xf0\x9f\x94\xab"}, // 🔫 + {":boomerang:", "\xf0\x9f\xaa\x83"}, // 🪃 + {":bow_and_arrow:", "\xf0\x9f\x8f\xb9"}, // 🏹 + {":shield:", "\xf0\x9f\x9b\xa1\xef\xb8\x8f"}, // 🛡️ + {":carpentry_saw:", "\xf0\x9f\xaa\x9a"}, // 🪚 + {":wrench:", "\xf0\x9f\x94\xa7"}, // 🔧 + {":screwdriver:", "\xf0\x9f\xaa\x9b"}, // 🪛 + {":nut_and_bolt:", "\xf0\x9f\x94\xa9"}, // 🔩 + {":gear:", "\xe2\x9a\x99\xef\xb8\x8f"}, // ⚙️ + {":clamp:", "\xf0\x9f\x97\x9c\xef\xb8\x8f"}, // 🗜️ + {":balance_scale:", "\xe2\x9a\x96\xef\xb8\x8f"}, // ⚖️ + {":probing_cane:", "\xf0\x9f\xa6\xaf"}, // 🦯 + {":link:", "\xf0\x9f\x94\x97"}, // 🔗 + {":chains:", "\xe2\x9b\x93\xef\xb8\x8f"}, // ⛓️ + {":hook:", "\xf0\x9f\xaa\x9d"}, // 🪝 + {":toolbox:", "\xf0\x9f\xa7\xb0"}, // 🧰 + {":magnet:", "\xf0\x9f\xa7\xb2"}, // 🧲 + {":ladder:", "\xf0\x9f\xaa\x9c"}, // 🪜 + {":alembic:", "\xe2\x9a\x97\xef\xb8\x8f"}, // ⚗️ + {":test_tube:", "\xf0\x9f\xa7\xaa"}, // 🧪 + {":petri_dish:", "\xf0\x9f\xa7\xab"}, // 🧫 + {":dna:", "\xf0\x9f\xa7\xac"}, // 🧬 + {":microscope:", "\xf0\x9f\x94\xac"}, // 🔬 + {":telescope:", "\xf0\x9f\x94\xad"}, // 🔭 + {":satellite:", "\xf0\x9f\x93\xa1"}, // 📡 + {":syringe:", "\xf0\x9f\x92\x89"}, // 💉 + {":drop_of_blood:", "\xf0\x9f\xa9\xb8"}, // 🩸 + {":pill:", "\xf0\x9f\x92\x8a"}, // 💊 + {":adhesive_bandage:", "\xf0\x9f\xa9\xb9"}, // 🩹 + {":stethoscope:", "\xf0\x9f\xa9\xba"}, // 🩺 + {":door:", "\xf0\x9f\x9a\xaa"}, // 🚪 + {":elevator:", "\xf0\x9f\x9b\x97"}, // 🛗 + {":mirror:", "\xf0\x9f\xaa\x9e"}, // 🪞 + {":window:", "\xf0\x9f\xaa\x9f"}, // 🪟 + {":bed:", "\xf0\x9f\x9b\x8f\xef\xb8\x8f"}, // 🛏️ + {":couch_and_lamp:", "\xf0\x9f\x9b\x8b\xef\xb8\x8f"}, // 🛋️ + {":chair:", "\xf0\x9f\xaa\x91"}, // 🪑 + {":toilet:", "\xf0\x9f\x9a\xbd"}, // 🚽 + {":plunger:", "\xf0\x9f\xaa\xa0"}, // 🪠 + {":shower:", "\xf0\x9f\x9a\xbf"}, // 🚿 + {":bathtub:", "\xf0\x9f\x9b\x81"}, // 🛁 + {":mouse_trap:", "\xf0\x9f\xaa\xa4"}, // 🪤 + {":razor:", "\xf0\x9f\xaa\x92"}, // 🪒 + {":lotion_bottle:", "\xf0\x9f\xa7\xb4"}, // 🧴 + {":safety_pin:", "\xf0\x9f\xa7\xb7"}, // 🧷 + {":broom:", "\xf0\x9f\xa7\xb9"}, // 🧹 + {":basket:", "\xf0\x9f\xa7\xba"}, // 🧺 + {":roll_of_paper:", "\xf0\x9f\xa7\xbb"}, // 🧻 + {":bucket:", "\xf0\x9f\xaa\xa3"}, // 🪣 + {":soap:", "\xf0\x9f\xa7\xbc"}, // 🧼 + {":toothbrush:", "\xf0\x9f\xaa\xa5"}, // 🪥 + {":sponge:", "\xf0\x9f\xa7\xbd"}, // 🧽 + {":fire_extinguisher:", "\xf0\x9f\xa7\xaf"}, // 🧯 + {":shopping_cart:", "\xf0\x9f\x9b\x92"}, // 🛒 + {":smoking:", "\xf0\x9f\x9a\xac"}, // 🚬 + {":coffin:", "\xe2\x9a\xb0\xef\xb8\x8f"}, // ⚰️ + {":headstone:", "\xf0\x9f\xaa\xa6"}, // 🪦 + {":funeral_urn:", "\xe2\x9a\xb1\xef\xb8\x8f"}, // ⚱️ + {":moyai:", "\xf0\x9f\x97\xbf"}, // 🗿 + {":placard:", "\xf0\x9f\xaa\xa7"}, // 🪧 + {":atm:", "\xf0\x9f\x8f\xa7"}, // 🏧 + {":put_litter_in_its_place:", "\xf0\x9f\x9a\xae"}, // 🚮 + {":potable_water:", "\xf0\x9f\x9a\xb0"}, // 🚰 + {":wheelchair:", "\xe2\x99\xbf"}, // ♿ + {":mens:", "\xf0\x9f\x9a\xb9"}, // 🚹 + {":womens:", "\xf0\x9f\x9a\xba"}, // 🚺 + {":restroom:", "\xf0\x9f\x9a\xbb"}, // 🚻 + {":baby_symbol:", "\xf0\x9f\x9a\xbc"}, // 🚼 + {":wc:", "\xf0\x9f\x9a\xbe"}, // 🚾 + {":passport_control:", "\xf0\x9f\x9b\x82"}, // 🛂 + {":customs:", "\xf0\x9f\x9b\x83"}, // 🛃 + {":baggage_claim:", "\xf0\x9f\x9b\x84"}, // 🛄 + {":left_luggage:", "\xf0\x9f\x9b\x85"}, // 🛅 + {":warning:", "\xe2\x9a\xa0\xef\xb8\x8f"}, // ⚠️ + {":children_crossing:", "\xf0\x9f\x9a\xb8"}, // 🚸 + {":no_entry:", "\xe2\x9b\x94"}, // ⛔ + {":no_entry_sign:", "\xf0\x9f\x9a\xab"}, // 🚫 + {":no_bicycles:", "\xf0\x9f\x9a\xb3"}, // 🚳 + {":no_smoking:", "\xf0\x9f\x9a\xad"}, // 🚭 + {":do_not_litter:", "\xf0\x9f\x9a\xaf"}, // 🚯 + {":non-potable_water:", "\xf0\x9f\x9a\xb1"}, // 🚱 + {":no_pedestrians:", "\xf0\x9f\x9a\xb7"}, // 🚷 + {":no_mobile_phones:", "\xf0\x9f\x93\xb5"}, // 📵 + {":underage:", "\xf0\x9f\x94\x9e"}, // 🔞 + {":radioactive:", "\xe2\x98\xa2\xef\xb8\x8f"}, // ☢️ + {":biohazard:", "\xe2\x98\xa3\xef\xb8\x8f"}, // ☣️ + {":arrow_up:", "\xe2\xac\x86\xef\xb8\x8f"}, // ⬆️ + {":arrow_upper_right:", "\xe2\x86\x97\xef\xb8\x8f"}, // ↗️ + {":arrow_right:", "\xe2\x9e\xa1\xef\xb8\x8f"}, // ➡️ + {":arrow_lower_right:", "\xe2\x86\x98\xef\xb8\x8f"}, // ↘️ + {":arrow_down:", "\xe2\xac\x87\xef\xb8\x8f"}, // ⬇️ + {":arrow_lower_left:", "\xe2\x86\x99\xef\xb8\x8f"}, // ↙️ + {":arrow_left:", "\xe2\xac\x85\xef\xb8\x8f"}, // ⬅️ + {":arrow_upper_left:", "\xe2\x86\x96\xef\xb8\x8f"}, // ↖️ + {":arrow_up_down:", "\xe2\x86\x95\xef\xb8\x8f"}, // ↕️ + {":left_right_arrow:", "\xe2\x86\x94\xef\xb8\x8f"}, // ↔️ + {":leftwards_arrow_with_hook:", "\xe2\x86\xa9\xef\xb8\x8f"}, // ↩️ + {":arrow_right_hook:", "\xe2\x86\xaa\xef\xb8\x8f"}, // ↪️ + {":arrow_heading_up:", "\xe2\xa4\xb4\xef\xb8\x8f"}, // ⤴️ + {":arrow_heading_down:", "\xe2\xa4\xb5\xef\xb8\x8f"}, // ⤵️ + {":arrows_clockwise:", "\xf0\x9f\x94\x83"}, // 🔃 + {":arrows_counterclockwise:", "\xf0\x9f\x94\x84"}, // 🔄 + {":back:", "\xf0\x9f\x94\x99"}, // 🔙 + {":end:", "\xf0\x9f\x94\x9a"}, // 🔚 + {":on:", "\xf0\x9f\x94\x9b"}, // 🔛 + {":soon:", "\xf0\x9f\x94\x9c"}, // 🔜 + {":top:", "\xf0\x9f\x94\x9d"}, // 🔝 + {":place_of_worship:", "\xf0\x9f\x9b\x90"}, // 🛐 + {":atom_symbol:", "\xe2\x9a\x9b\xef\xb8\x8f"}, // ⚛️ + {":om:", "\xf0\x9f\x95\x89\xef\xb8\x8f"}, // 🕉️ + {":star_of_david:", "\xe2\x9c\xa1\xef\xb8\x8f"}, // ✡️ + {":wheel_of_dharma:", "\xe2\x98\xb8\xef\xb8\x8f"}, // ☸️ + {":yin_yang:", "\xe2\x98\xaf\xef\xb8\x8f"}, // ☯️ + {":latin_cross:", "\xe2\x9c\x9d\xef\xb8\x8f"}, // ✝️ + {":orthodox_cross:", "\xe2\x98\xa6\xef\xb8\x8f"}, // ☦️ + {":star_and_crescent:", "\xe2\x98\xaa\xef\xb8\x8f"}, // ☪️ + {":peace_symbol:", "\xe2\x98\xae\xef\xb8\x8f"}, // ☮️ + {":menorah:", "\xf0\x9f\x95\x8e"}, // 🕎 + {":six_pointed_star:", "\xf0\x9f\x94\xaf"}, // 🔯 + {":aries:", "\xe2\x99\x88"}, // ♈ + {":taurus:", "\xe2\x99\x89"}, // ♉ + {":gemini:", "\xe2\x99\x8a"}, // ♊ + {":cancer:", "\xe2\x99\x8b"}, // ♋ + {":leo:", "\xe2\x99\x8c"}, // ♌ + {":virgo:", "\xe2\x99\x8d"}, // ♍ + {":libra:", "\xe2\x99\x8e"}, // ♎ + {":scorpius:", "\xe2\x99\x8f"}, // ♏ + {":sagittarius:", "\xe2\x99\x90"}, // ♐ + {":capricorn:", "\xe2\x99\x91"}, // ♑ + {":aquarius:", "\xe2\x99\x92"}, // ♒ + {":pisces:", "\xe2\x99\x93"}, // ♓ + {":ophiuchus:", "\xe2\x9b\x8e"}, // ⛎ + {":twisted_rightwards_arrows:", "\xf0\x9f\x94\x80"}, // 🔀 + {":repeat:", "\xf0\x9f\x94\x81"}, // 🔁 + {":repeat_one:", "\xf0\x9f\x94\x82"}, // 🔂 + {":arrow_forward:", "\xe2\x96\xb6\xef\xb8\x8f"}, // ▶️ + {":fast_forward:", "\xe2\x8f\xa9"}, // ⏩ + {":next_track_button:", "\xe2\x8f\xad\xef\xb8\x8f"}, // ⏭️ + {":play_or_pause_button:", "\xe2\x8f\xaf\xef\xb8\x8f"}, // ⏯️ + {":arrow_backward:", "\xe2\x97\x80\xef\xb8\x8f"}, // ◀️ + {":rewind:", "\xe2\x8f\xaa"}, // ⏪ + {":previous_track_button:", "\xe2\x8f\xae\xef\xb8\x8f"}, // ⏮️ + {":arrow_up_small:", "\xf0\x9f\x94\xbc"}, // 🔼 + {":arrow_double_up:", "\xe2\x8f\xab"}, // ⏫ + {":arrow_down_small:", "\xf0\x9f\x94\xbd"}, // 🔽 + {":arrow_double_down:", "\xe2\x8f\xac"}, // ⏬ + {":pause_button:", "\xe2\x8f\xb8\xef\xb8\x8f"}, // ⏸️ + {":stop_button:", "\xe2\x8f\xb9\xef\xb8\x8f"}, // ⏹️ + {":record_button:", "\xe2\x8f\xba\xef\xb8\x8f"}, // ⏺️ + {":eject_button:", "\xe2\x8f\x8f\xef\xb8\x8f"}, // ⏏️ + {":cinema:", "\xf0\x9f\x8e\xa6"}, // 🎦 + {":low_brightness:", "\xf0\x9f\x94\x85"}, // 🔅 + {":high_brightness:", "\xf0\x9f\x94\x86"}, // 🔆 + {":signal_strength:", "\xf0\x9f\x93\xb6"}, // 📶 + {":vibration_mode:", "\xf0\x9f\x93\xb3"}, // 📳 + {":mobile_phone_off:", "\xf0\x9f\x93\xb4"}, // 📴 + {":female_sign:", "\xe2\x99\x80\xef\xb8\x8f"}, // ♀️ + {":male_sign:", "\xe2\x99\x82\xef\xb8\x8f"}, // ♂️ + {":transgender_symbol:", "\xe2\x9a\xa7\xef\xb8\x8f"}, // ⚧️ + {":heavy_multiplication_x:", "\xe2\x9c\x96\xef\xb8\x8f"}, // ✖️ + {":heavy_plus_sign:", "\xe2\x9e\x95"}, // ➕ + {":heavy_minus_sign:", "\xe2\x9e\x96"}, // ➖ + {":heavy_division_sign:", "\xe2\x9e\x97"}, // ➗ + {":infinity:", "\xe2\x99\xbe\xef\xb8\x8f"}, // ♾️ + {":bangbang:", "\xe2\x80\xbc\xef\xb8\x8f"}, // ‼️ + {":interrobang:", "\xe2\x81\x89\xef\xb8\x8f"}, // ⁉️ + {":question:", "\xe2\x9d\x93"}, // ❓ + {":grey_question:", "\xe2\x9d\x94"}, // ❔ + {":grey_exclamation:", "\xe2\x9d\x95"}, // ❕ + {":exclamation:", "\xe2\x9d\x97"}, // ❗ + {":heavy_exclamation_mark:", "\xe2\x9d\x97"}, // ❗ + {":wavy_dash:", "\xe3\x80\xb0\xef\xb8\x8f"}, // 〰️ + {":currency_exchange:", "\xf0\x9f\x92\xb1"}, // 💱 + {":heavy_dollar_sign:", "\xf0\x9f\x92\xb2"}, // 💲 + {":medical_symbol:", "\xe2\x9a\x95\xef\xb8\x8f"}, // ⚕️ + {":recycle:", "\xe2\x99\xbb\xef\xb8\x8f"}, // ♻️ + {":fleur_de_lis:", "\xe2\x9a\x9c\xef\xb8\x8f"}, // ⚜️ + {":trident:", "\xf0\x9f\x94\xb1"}, // 🔱 + {":name_badge:", "\xf0\x9f\x93\x9b"}, // 📛 + {":beginner:", "\xf0\x9f\x94\xb0"}, // 🔰 + {":o:", "\xe2\xad\x95"}, // ⭕ + {":white_check_mark:", "\xe2\x9c\x85"}, // ✅ + {":ballot_box_with_check:", "\xe2\x98\x91\xef\xb8\x8f"}, // ☑️ + {":heavy_check_mark:", "\xe2\x9c\x94\xef\xb8\x8f"}, // ✔️ + {":x:", "\xe2\x9d\x8c"}, // ❌ + {":negative_squared_cross_mark:", "\xe2\x9d\x8e"}, // ❎ + {":curly_loop:", "\xe2\x9e\xb0"}, // ➰ + {":loop:", "\xe2\x9e\xbf"}, // ➿ + {":part_alternation_mark:", "\xe3\x80\xbd\xef\xb8\x8f"}, // 〽️ + {":eight_spoked_asterisk:", "\xe2\x9c\xb3\xef\xb8\x8f"}, // ✳️ + {":eight_pointed_black_star:", "\xe2\x9c\xb4\xef\xb8\x8f"}, // ✴️ + {":sparkle:", "\xe2\x9d\x87\xef\xb8\x8f"}, // ❇️ + {":copyright:", "\xc2\xa9\xef\xb8\x8f"}, // ©️ + {":registered:", "\xc2\xae\xef\xb8\x8f"}, // ®️ + {":tm:", "\xe2\x84\xa2\xef\xb8\x8f"}, // ™️ + {":hash:", "\x23\xef\xb8\x8f\xe2\x83\xa3"}, // #️⃣ + {":asterisk:", "\x2a\xef\xb8\x8f\xe2\x83\xa3"}, // *️⃣ + {":zero:", "\x30\xef\xb8\x8f\xe2\x83\xa3"}, // 0️⃣ + {":one:", "\x31\xef\xb8\x8f\xe2\x83\xa3"}, // 1️⃣ + {":two:", "\x32\xef\xb8\x8f\xe2\x83\xa3"}, // 2️⃣ + {":three:", "\x33\xef\xb8\x8f\xe2\x83\xa3"}, // 3️⃣ + {":four:", "\x34\xef\xb8\x8f\xe2\x83\xa3"}, // 4️⃣ + {":five:", "\x35\xef\xb8\x8f\xe2\x83\xa3"}, // 5️⃣ + {":six:", "\x36\xef\xb8\x8f\xe2\x83\xa3"}, // 6️⃣ + {":seven:", "\x37\xef\xb8\x8f\xe2\x83\xa3"}, // 7️⃣ + {":eight:", "\x38\xef\xb8\x8f\xe2\x83\xa3"}, // 8️⃣ + {":nine:", "\x39\xef\xb8\x8f\xe2\x83\xa3"}, // 9️⃣ + {":keycap_ten:", "\xf0\x9f\x94\x9f"}, // 🔟 + {":capital_abcd:", "\xf0\x9f\x94\xa0"}, // 🔠 + {":abcd:", "\xf0\x9f\x94\xa1"}, // 🔡 + {":1234:", "\xf0\x9f\x94\xa2"}, // 🔢 + {":symbols:", "\xf0\x9f\x94\xa3"}, // 🔣 + {":abc:", "\xf0\x9f\x94\xa4"}, // 🔤 + {":a:", "\xf0\x9f\x85\xb0\xef\xb8\x8f"}, // 🅰️ + {":ab:", "\xf0\x9f\x86\x8e"}, // 🆎 + {":b:", "\xf0\x9f\x85\xb1\xef\xb8\x8f"}, // 🅱️ + {":cl:", "\xf0\x9f\x86\x91"}, // 🆑 + {":cool:", "\xf0\x9f\x86\x92"}, // 🆒 + {":free:", "\xf0\x9f\x86\x93"}, // 🆓 + {":information_source:", "\xe2\x84\xb9\xef\xb8\x8f"}, // ℹ️ + {":id:", "\xf0\x9f\x86\x94"}, // 🆔 + {":m:", "\xe2\x93\x82\xef\xb8\x8f"}, // Ⓜ️ + {":new:", "\xf0\x9f\x86\x95"}, // 🆕 + {":ng:", "\xf0\x9f\x86\x96"}, // 🆖 + {":o2:", "\xf0\x9f\x85\xbe\xef\xb8\x8f"}, // 🅾️ + {":ok:", "\xf0\x9f\x86\x97"}, // 🆗 + {":parking:", "\xf0\x9f\x85\xbf\xef\xb8\x8f"}, // 🅿️ + {":sos:", "\xf0\x9f\x86\x98"}, // 🆘 + {":up:", "\xf0\x9f\x86\x99"}, // 🆙 + {":vs:", "\xf0\x9f\x86\x9a"}, // 🆚 + {":koko:", "\xf0\x9f\x88\x81"}, // 🈁 + {":sa:", "\xf0\x9f\x88\x82\xef\xb8\x8f"}, // 🈂️ + {":u6708:", "\xf0\x9f\x88\xb7\xef\xb8\x8f"}, // 🈷️ + {":u6709:", "\xf0\x9f\x88\xb6"}, // 🈶 + {":u6307:", "\xf0\x9f\x88\xaf"}, // 🈯 + {":ideograph_advantage:", "\xf0\x9f\x89\x90"}, // 🉐 + {":u5272:", "\xf0\x9f\x88\xb9"}, // 🈹 + {":u7121:", "\xf0\x9f\x88\x9a"}, // 🈚 + {":u7981:", "\xf0\x9f\x88\xb2"}, // 🈲 + {":accept:", "\xf0\x9f\x89\x91"}, // 🉑 + {":u7533:", "\xf0\x9f\x88\xb8"}, // 🈸 + {":u5408:", "\xf0\x9f\x88\xb4"}, // 🈴 + {":u7a7a:", "\xf0\x9f\x88\xb3"}, // 🈳 + {":congratulations:", "\xe3\x8a\x97\xef\xb8\x8f"}, // ㊗️ + {":secret:", "\xe3\x8a\x99\xef\xb8\x8f"}, // ㊙️ + {":u55b6:", "\xf0\x9f\x88\xba"}, // 🈺 + {":u6e80:", "\xf0\x9f\x88\xb5"}, // 🈵 + {":red_circle:", "\xf0\x9f\x94\xb4"}, // 🔴 + {":orange_circle:", "\xf0\x9f\x9f\xa0"}, // 🟠 + {":yellow_circle:", "\xf0\x9f\x9f\xa1"}, // 🟡 + {":green_circle:", "\xf0\x9f\x9f\xa2"}, // 🟢 + {":large_blue_circle:", "\xf0\x9f\x94\xb5"}, // 🔵 + {":purple_circle:", "\xf0\x9f\x9f\xa3"}, // 🟣 + {":brown_circle:", "\xf0\x9f\x9f\xa4"}, // 🟤 + {":black_circle:", "\xe2\x9a\xab"}, // ⚫ + {":white_circle:", "\xe2\x9a\xaa"}, // ⚪ + {":red_square:", "\xf0\x9f\x9f\xa5"}, // 🟥 + {":orange_square:", "\xf0\x9f\x9f\xa7"}, // 🟧 + {":yellow_square:", "\xf0\x9f\x9f\xa8"}, // 🟨 + {":green_square:", "\xf0\x9f\x9f\xa9"}, // 🟩 + {":blue_square:", "\xf0\x9f\x9f\xa6"}, // 🟦 + {":purple_square:", "\xf0\x9f\x9f\xaa"}, // 🟪 + {":brown_square:", "\xf0\x9f\x9f\xab"}, // 🟫 + {":black_large_square:", "\xe2\xac\x9b"}, // ⬛ + {":white_large_square:", "\xe2\xac\x9c"}, // ⬜ + {":black_medium_square:", "\xe2\x97\xbc\xef\xb8\x8f"}, // ◼️ + {":white_medium_square:", "\xe2\x97\xbb\xef\xb8\x8f"}, // ◻️ + {":black_medium_small_square:", "\xe2\x97\xbe"}, // ◾ + {":white_medium_small_square:", "\xe2\x97\xbd"}, // ◽ + {":black_small_square:", "\xe2\x96\xaa\xef\xb8\x8f"}, // ▪️ + {":white_small_square:", "\xe2\x96\xab\xef\xb8\x8f"}, // ▫️ + {":large_orange_diamond:", "\xf0\x9f\x94\xb6"}, // 🔶 + {":large_blue_diamond:", "\xf0\x9f\x94\xb7"}, // 🔷 + {":small_orange_diamond:", "\xf0\x9f\x94\xb8"}, // 🔸 + {":small_blue_diamond:", "\xf0\x9f\x94\xb9"}, // 🔹 + {":small_red_triangle:", "\xf0\x9f\x94\xba"}, // 🔺 + {":small_red_triangle_down:", "\xf0\x9f\x94\xbb"}, // 🔻 + {":diamond_shape_with_a_dot_inside:", "\xf0\x9f\x92\xa0"}, // 💠 + {":radio_button:", "\xf0\x9f\x94\x98"}, // 🔘 + {":white_square_button:", "\xf0\x9f\x94\xb3"}, // 🔳 + {":black_square_button:", "\xf0\x9f\x94\xb2"}, // 🔲 + {":checkered_flag:", "\xf0\x9f\x8f\x81"}, // 🏁 + {":triangular_flag_on_post:", "\xf0\x9f\x9a\xa9"}, // 🚩 + {":crossed_flags:", "\xf0\x9f\x8e\x8c"}, // 🎌 + {":black_flag:", "\xf0\x9f\x8f\xb4"}, // 🏴 + {":white_flag:", "\xf0\x9f\x8f\xb3\xef\xb8\x8f"}, // 🏳️ + {":rainbow_flag:", "\xf0\x9f\x8f\xb3\xef\xb8\x8f\xe2\x80\x8d\xf0\x9f\x8c\x88"}, // 🏳️‍🌈 + {":transgender_flag:", "\xf0\x9f\x8f\xb3\xef\xb8\x8f\xe2\x80\x8d\xe2\x9a\xa7\xef\xb8\x8f"}, // 🏳️‍⚧️ + {":pirate_flag:", "\xf0\x9f\x8f\xb4\xe2\x80\x8d\xe2\x98\xa0\xef\xb8\x8f"}, // 🏴‍☠️ + {":ascension_island:", "\xf0\x9f\x87\xa6\xf0\x9f\x87\xa8"}, // 🇦🇨 + {":andorra:", "\xf0\x9f\x87\xa6\xf0\x9f\x87\xa9"}, // 🇦🇩 + {":united_arab_emirates:", "\xf0\x9f\x87\xa6\xf0\x9f\x87\xaa"}, // 🇦🇪 + {":afghanistan:", "\xf0\x9f\x87\xa6\xf0\x9f\x87\xab"}, // 🇦🇫 + {":antigua_barbuda:", "\xf0\x9f\x87\xa6\xf0\x9f\x87\xac"}, // 🇦🇬 + {":anguilla:", "\xf0\x9f\x87\xa6\xf0\x9f\x87\xae"}, // 🇦🇮 + {":albania:", "\xf0\x9f\x87\xa6\xf0\x9f\x87\xb1"}, // 🇦🇱 + {":armenia:", "\xf0\x9f\x87\xa6\xf0\x9f\x87\xb2"}, // 🇦🇲 + {":angola:", "\xf0\x9f\x87\xa6\xf0\x9f\x87\xb4"}, // 🇦🇴 + {":antarctica:", "\xf0\x9f\x87\xa6\xf0\x9f\x87\xb6"}, // 🇦🇶 + {":argentina:", "\xf0\x9f\x87\xa6\xf0\x9f\x87\xb7"}, // 🇦🇷 + {":american_samoa:", "\xf0\x9f\x87\xa6\xf0\x9f\x87\xb8"}, // 🇦🇸 + {":austria:", "\xf0\x9f\x87\xa6\xf0\x9f\x87\xb9"}, // 🇦🇹 + {":australia:", "\xf0\x9f\x87\xa6\xf0\x9f\x87\xba"}, // 🇦🇺 + {":aruba:", "\xf0\x9f\x87\xa6\xf0\x9f\x87\xbc"}, // 🇦🇼 + {":aland_islands:", "\xf0\x9f\x87\xa6\xf0\x9f\x87\xbd"}, // 🇦🇽 + {":azerbaijan:", "\xf0\x9f\x87\xa6\xf0\x9f\x87\xbf"}, // 🇦🇿 + {":bosnia_herzegovina:", "\xf0\x9f\x87\xa7\xf0\x9f\x87\xa6"}, // 🇧🇦 + {":barbados:", "\xf0\x9f\x87\xa7\xf0\x9f\x87\xa7"}, // 🇧🇧 + {":bangladesh:", "\xf0\x9f\x87\xa7\xf0\x9f\x87\xa9"}, // 🇧🇩 + {":belgium:", "\xf0\x9f\x87\xa7\xf0\x9f\x87\xaa"}, // 🇧🇪 + {":burkina_faso:", "\xf0\x9f\x87\xa7\xf0\x9f\x87\xab"}, // 🇧🇫 + {":bulgaria:", "\xf0\x9f\x87\xa7\xf0\x9f\x87\xac"}, // 🇧🇬 + {":bahrain:", "\xf0\x9f\x87\xa7\xf0\x9f\x87\xad"}, // 🇧🇭 + {":burundi:", "\xf0\x9f\x87\xa7\xf0\x9f\x87\xae"}, // 🇧🇮 + {":benin:", "\xf0\x9f\x87\xa7\xf0\x9f\x87\xaf"}, // 🇧🇯 + {":st_barthelemy:", "\xf0\x9f\x87\xa7\xf0\x9f\x87\xb1"}, // 🇧🇱 + {":bermuda:", "\xf0\x9f\x87\xa7\xf0\x9f\x87\xb2"}, // 🇧🇲 + {":brunei:", "\xf0\x9f\x87\xa7\xf0\x9f\x87\xb3"}, // 🇧🇳 + {":bolivia:", "\xf0\x9f\x87\xa7\xf0\x9f\x87\xb4"}, // 🇧🇴 + {":caribbean_netherlands:", "\xf0\x9f\x87\xa7\xf0\x9f\x87\xb6"}, // 🇧🇶 + {":brazil:", "\xf0\x9f\x87\xa7\xf0\x9f\x87\xb7"}, // 🇧🇷 + {":bahamas:", "\xf0\x9f\x87\xa7\xf0\x9f\x87\xb8"}, // 🇧🇸 + {":bhutan:", "\xf0\x9f\x87\xa7\xf0\x9f\x87\xb9"}, // 🇧🇹 + {":bouvet_island:", "\xf0\x9f\x87\xa7\xf0\x9f\x87\xbb"}, // 🇧🇻 + {":botswana:", "\xf0\x9f\x87\xa7\xf0\x9f\x87\xbc"}, // 🇧🇼 + {":belarus:", "\xf0\x9f\x87\xa7\xf0\x9f\x87\xbe"}, // 🇧🇾 + {":belize:", "\xf0\x9f\x87\xa7\xf0\x9f\x87\xbf"}, // 🇧🇿 + {":canada:", "\xf0\x9f\x87\xa8\xf0\x9f\x87\xa6"}, // 🇨🇦 + {":cocos_islands:", "\xf0\x9f\x87\xa8\xf0\x9f\x87\xa8"}, // 🇨🇨 + {":congo_kinshasa:", "\xf0\x9f\x87\xa8\xf0\x9f\x87\xa9"}, // 🇨🇩 + {":central_african_republic:", "\xf0\x9f\x87\xa8\xf0\x9f\x87\xab"}, // 🇨🇫 + {":congo_brazzaville:", "\xf0\x9f\x87\xa8\xf0\x9f\x87\xac"}, // 🇨🇬 + {":switzerland:", "\xf0\x9f\x87\xa8\xf0\x9f\x87\xad"}, // 🇨🇭 + {":cote_divoire:", "\xf0\x9f\x87\xa8\xf0\x9f\x87\xae"}, // 🇨🇮 + {":cook_islands:", "\xf0\x9f\x87\xa8\xf0\x9f\x87\xb0"}, // 🇨🇰 + {":chile:", "\xf0\x9f\x87\xa8\xf0\x9f\x87\xb1"}, // 🇨🇱 + {":cameroon:", "\xf0\x9f\x87\xa8\xf0\x9f\x87\xb2"}, // 🇨🇲 + {":cn:", "\xf0\x9f\x87\xa8\xf0\x9f\x87\xb3"}, // 🇨🇳 + {":colombia:", "\xf0\x9f\x87\xa8\xf0\x9f\x87\xb4"}, // 🇨🇴 + {":clipperton_island:", "\xf0\x9f\x87\xa8\xf0\x9f\x87\xb5"}, // 🇨🇵 + {":costa_rica:", "\xf0\x9f\x87\xa8\xf0\x9f\x87\xb7"}, // 🇨🇷 + {":cuba:", "\xf0\x9f\x87\xa8\xf0\x9f\x87\xba"}, // 🇨🇺 + {":cape_verde:", "\xf0\x9f\x87\xa8\xf0\x9f\x87\xbb"}, // 🇨🇻 + {":curacao:", "\xf0\x9f\x87\xa8\xf0\x9f\x87\xbc"}, // 🇨🇼 + {":christmas_island:", "\xf0\x9f\x87\xa8\xf0\x9f\x87\xbd"}, // 🇨🇽 + {":cyprus:", "\xf0\x9f\x87\xa8\xf0\x9f\x87\xbe"}, // 🇨🇾 + {":czech_republic:", "\xf0\x9f\x87\xa8\xf0\x9f\x87\xbf"}, // 🇨🇿 + {":de:", "\xf0\x9f\x87\xa9\xf0\x9f\x87\xaa"}, // 🇩🇪 + {":diego_garcia:", "\xf0\x9f\x87\xa9\xf0\x9f\x87\xac"}, // 🇩🇬 + {":djibouti:", "\xf0\x9f\x87\xa9\xf0\x9f\x87\xaf"}, // 🇩🇯 + {":denmark:", "\xf0\x9f\x87\xa9\xf0\x9f\x87\xb0"}, // 🇩🇰 + {":dominica:", "\xf0\x9f\x87\xa9\xf0\x9f\x87\xb2"}, // 🇩🇲 + {":dominican_republic:", "\xf0\x9f\x87\xa9\xf0\x9f\x87\xb4"}, // 🇩🇴 + {":algeria:", "\xf0\x9f\x87\xa9\xf0\x9f\x87\xbf"}, // 🇩🇿 + {":ceuta_melilla:", "\xf0\x9f\x87\xaa\xf0\x9f\x87\xa6"}, // 🇪🇦 + {":ecuador:", "\xf0\x9f\x87\xaa\xf0\x9f\x87\xa8"}, // 🇪🇨 + {":estonia:", "\xf0\x9f\x87\xaa\xf0\x9f\x87\xaa"}, // 🇪🇪 + {":egypt:", "\xf0\x9f\x87\xaa\xf0\x9f\x87\xac"}, // 🇪🇬 + {":western_sahara:", "\xf0\x9f\x87\xaa\xf0\x9f\x87\xad"}, // 🇪🇭 + {":eritrea:", "\xf0\x9f\x87\xaa\xf0\x9f\x87\xb7"}, // 🇪🇷 + {":es:", "\xf0\x9f\x87\xaa\xf0\x9f\x87\xb8"}, // 🇪🇸 + {":ethiopia:", "\xf0\x9f\x87\xaa\xf0\x9f\x87\xb9"}, // 🇪🇹 + {":eu:", "\xf0\x9f\x87\xaa\xf0\x9f\x87\xba"}, // 🇪🇺 + {":european_union:", "\xf0\x9f\x87\xaa\xf0\x9f\x87\xba"}, // 🇪🇺 + {":finland:", "\xf0\x9f\x87\xab\xf0\x9f\x87\xae"}, // 🇫🇮 + {":fiji:", "\xf0\x9f\x87\xab\xf0\x9f\x87\xaf"}, // 🇫🇯 + {":falkland_islands:", "\xf0\x9f\x87\xab\xf0\x9f\x87\xb0"}, // 🇫🇰 + {":micronesia:", "\xf0\x9f\x87\xab\xf0\x9f\x87\xb2"}, // 🇫🇲 + {":faroe_islands:", "\xf0\x9f\x87\xab\xf0\x9f\x87\xb4"}, // 🇫🇴 + {":fr:", "\xf0\x9f\x87\xab\xf0\x9f\x87\xb7"}, // 🇫🇷 + {":gabon:", "\xf0\x9f\x87\xac\xf0\x9f\x87\xa6"}, // 🇬🇦 + {":gb:", "\xf0\x9f\x87\xac\xf0\x9f\x87\xa7"}, // 🇬🇧 + {":uk:", "\xf0\x9f\x87\xac\xf0\x9f\x87\xa7"}, // 🇬🇧 + {":grenada:", "\xf0\x9f\x87\xac\xf0\x9f\x87\xa9"}, // 🇬🇩 + {":georgia:", "\xf0\x9f\x87\xac\xf0\x9f\x87\xaa"}, // 🇬🇪 + {":french_guiana:", "\xf0\x9f\x87\xac\xf0\x9f\x87\xab"}, // 🇬🇫 + {":guernsey:", "\xf0\x9f\x87\xac\xf0\x9f\x87\xac"}, // 🇬🇬 + {":ghana:", "\xf0\x9f\x87\xac\xf0\x9f\x87\xad"}, // 🇬🇭 + {":gibraltar:", "\xf0\x9f\x87\xac\xf0\x9f\x87\xae"}, // 🇬🇮 + {":greenland:", "\xf0\x9f\x87\xac\xf0\x9f\x87\xb1"}, // 🇬🇱 + {":gambia:", "\xf0\x9f\x87\xac\xf0\x9f\x87\xb2"}, // 🇬🇲 + {":guinea:", "\xf0\x9f\x87\xac\xf0\x9f\x87\xb3"}, // 🇬🇳 + {":guadeloupe:", "\xf0\x9f\x87\xac\xf0\x9f\x87\xb5"}, // 🇬🇵 + {":equatorial_guinea:", "\xf0\x9f\x87\xac\xf0\x9f\x87\xb6"}, // 🇬🇶 + {":greece:", "\xf0\x9f\x87\xac\xf0\x9f\x87\xb7"}, // 🇬🇷 + {":south_georgia_south_sandwich_islands:", "\xf0\x9f\x87\xac\xf0\x9f\x87\xb8"}, // 🇬🇸 + {":guatemala:", "\xf0\x9f\x87\xac\xf0\x9f\x87\xb9"}, // 🇬🇹 + {":guam:", "\xf0\x9f\x87\xac\xf0\x9f\x87\xba"}, // 🇬🇺 + {":guinea_bissau:", "\xf0\x9f\x87\xac\xf0\x9f\x87\xbc"}, // 🇬🇼 + {":guyana:", "\xf0\x9f\x87\xac\xf0\x9f\x87\xbe"}, // 🇬🇾 + {":hong_kong:", "\xf0\x9f\x87\xad\xf0\x9f\x87\xb0"}, // 🇭🇰 + {":heard_mcdonald_islands:", "\xf0\x9f\x87\xad\xf0\x9f\x87\xb2"}, // 🇭🇲 + {":honduras:", "\xf0\x9f\x87\xad\xf0\x9f\x87\xb3"}, // 🇭🇳 + {":croatia:", "\xf0\x9f\x87\xad\xf0\x9f\x87\xb7"}, // 🇭🇷 + {":haiti:", "\xf0\x9f\x87\xad\xf0\x9f\x87\xb9"}, // 🇭🇹 + {":hungary:", "\xf0\x9f\x87\xad\xf0\x9f\x87\xba"}, // 🇭🇺 + {":canary_islands:", "\xf0\x9f\x87\xae\xf0\x9f\x87\xa8"}, // 🇮🇨 + {":indonesia:", "\xf0\x9f\x87\xae\xf0\x9f\x87\xa9"}, // 🇮🇩 + {":ireland:", "\xf0\x9f\x87\xae\xf0\x9f\x87\xaa"}, // 🇮🇪 + {":israel:", "\xf0\x9f\x87\xae\xf0\x9f\x87\xb1"}, // 🇮🇱 + {":isle_of_man:", "\xf0\x9f\x87\xae\xf0\x9f\x87\xb2"}, // 🇮🇲 + {":india:", "\xf0\x9f\x87\xae\xf0\x9f\x87\xb3"}, // 🇮🇳 + {":british_indian_ocean_territory:", "\xf0\x9f\x87\xae\xf0\x9f\x87\xb4"}, // 🇮🇴 + {":iraq:", "\xf0\x9f\x87\xae\xf0\x9f\x87\xb6"}, // 🇮🇶 + {":iran:", "\xf0\x9f\x87\xae\xf0\x9f\x87\xb7"}, // 🇮🇷 + {":iceland:", "\xf0\x9f\x87\xae\xf0\x9f\x87\xb8"}, // 🇮🇸 + {":it:", "\xf0\x9f\x87\xae\xf0\x9f\x87\xb9"}, // 🇮🇹 + {":jersey:", "\xf0\x9f\x87\xaf\xf0\x9f\x87\xaa"}, // 🇯🇪 + {":jamaica:", "\xf0\x9f\x87\xaf\xf0\x9f\x87\xb2"}, // 🇯🇲 + {":jordan:", "\xf0\x9f\x87\xaf\xf0\x9f\x87\xb4"}, // 🇯🇴 + {":jp:", "\xf0\x9f\x87\xaf\xf0\x9f\x87\xb5"}, // 🇯🇵 + {":kenya:", "\xf0\x9f\x87\xb0\xf0\x9f\x87\xaa"}, // 🇰🇪 + {":kyrgyzstan:", "\xf0\x9f\x87\xb0\xf0\x9f\x87\xac"}, // 🇰🇬 + {":cambodia:", "\xf0\x9f\x87\xb0\xf0\x9f\x87\xad"}, // 🇰🇭 + {":kiribati:", "\xf0\x9f\x87\xb0\xf0\x9f\x87\xae"}, // 🇰🇮 + {":comoros:", "\xf0\x9f\x87\xb0\xf0\x9f\x87\xb2"}, // 🇰🇲 + {":st_kitts_nevis:", "\xf0\x9f\x87\xb0\xf0\x9f\x87\xb3"}, // 🇰🇳 + {":north_korea:", "\xf0\x9f\x87\xb0\xf0\x9f\x87\xb5"}, // 🇰🇵 + {":kr:", "\xf0\x9f\x87\xb0\xf0\x9f\x87\xb7"}, // 🇰🇷 + {":kuwait:", "\xf0\x9f\x87\xb0\xf0\x9f\x87\xbc"}, // 🇰🇼 + {":cayman_islands:", "\xf0\x9f\x87\xb0\xf0\x9f\x87\xbe"}, // 🇰🇾 + {":kazakhstan:", "\xf0\x9f\x87\xb0\xf0\x9f\x87\xbf"}, // 🇰🇿 + {":laos:", "\xf0\x9f\x87\xb1\xf0\x9f\x87\xa6"}, // 🇱🇦 + {":lebanon:", "\xf0\x9f\x87\xb1\xf0\x9f\x87\xa7"}, // 🇱🇧 + {":st_lucia:", "\xf0\x9f\x87\xb1\xf0\x9f\x87\xa8"}, // 🇱🇨 + {":liechtenstein:", "\xf0\x9f\x87\xb1\xf0\x9f\x87\xae"}, // 🇱🇮 + {":sri_lanka:", "\xf0\x9f\x87\xb1\xf0\x9f\x87\xb0"}, // 🇱🇰 + {":liberia:", "\xf0\x9f\x87\xb1\xf0\x9f\x87\xb7"}, // 🇱🇷 + {":lesotho:", "\xf0\x9f\x87\xb1\xf0\x9f\x87\xb8"}, // 🇱🇸 + {":lithuania:", "\xf0\x9f\x87\xb1\xf0\x9f\x87\xb9"}, // 🇱🇹 + {":luxembourg:", "\xf0\x9f\x87\xb1\xf0\x9f\x87\xba"}, // 🇱🇺 + {":latvia:", "\xf0\x9f\x87\xb1\xf0\x9f\x87\xbb"}, // 🇱🇻 + {":libya:", "\xf0\x9f\x87\xb1\xf0\x9f\x87\xbe"}, // 🇱🇾 + {":morocco:", "\xf0\x9f\x87\xb2\xf0\x9f\x87\xa6"}, // 🇲🇦 + {":monaco:", "\xf0\x9f\x87\xb2\xf0\x9f\x87\xa8"}, // 🇲🇨 + {":moldova:", "\xf0\x9f\x87\xb2\xf0\x9f\x87\xa9"}, // 🇲🇩 + {":montenegro:", "\xf0\x9f\x87\xb2\xf0\x9f\x87\xaa"}, // 🇲🇪 + {":st_martin:", "\xf0\x9f\x87\xb2\xf0\x9f\x87\xab"}, // 🇲🇫 + {":madagascar:", "\xf0\x9f\x87\xb2\xf0\x9f\x87\xac"}, // 🇲🇬 + {":marshall_islands:", "\xf0\x9f\x87\xb2\xf0\x9f\x87\xad"}, // 🇲🇭 + {":macedonia:", "\xf0\x9f\x87\xb2\xf0\x9f\x87\xb0"}, // 🇲🇰 + {":mali:", "\xf0\x9f\x87\xb2\xf0\x9f\x87\xb1"}, // 🇲🇱 + {":myanmar:", "\xf0\x9f\x87\xb2\xf0\x9f\x87\xb2"}, // 🇲🇲 + {":mongolia:", "\xf0\x9f\x87\xb2\xf0\x9f\x87\xb3"}, // 🇲🇳 + {":macau:", "\xf0\x9f\x87\xb2\xf0\x9f\x87\xb4"}, // 🇲🇴 + {":northern_mariana_islands:", "\xf0\x9f\x87\xb2\xf0\x9f\x87\xb5"}, // 🇲🇵 + {":martinique:", "\xf0\x9f\x87\xb2\xf0\x9f\x87\xb6"}, // 🇲🇶 + {":mauritania:", "\xf0\x9f\x87\xb2\xf0\x9f\x87\xb7"}, // 🇲🇷 + {":montserrat:", "\xf0\x9f\x87\xb2\xf0\x9f\x87\xb8"}, // 🇲🇸 + {":malta:", "\xf0\x9f\x87\xb2\xf0\x9f\x87\xb9"}, // 🇲🇹 + {":mauritius:", "\xf0\x9f\x87\xb2\xf0\x9f\x87\xba"}, // 🇲🇺 + {":maldives:", "\xf0\x9f\x87\xb2\xf0\x9f\x87\xbb"}, // 🇲🇻 + {":malawi:", "\xf0\x9f\x87\xb2\xf0\x9f\x87\xbc"}, // 🇲🇼 + {":mexico:", "\xf0\x9f\x87\xb2\xf0\x9f\x87\xbd"}, // 🇲🇽 + {":malaysia:", "\xf0\x9f\x87\xb2\xf0\x9f\x87\xbe"}, // 🇲🇾 + {":mozambique:", "\xf0\x9f\x87\xb2\xf0\x9f\x87\xbf"}, // 🇲🇿 + {":namibia:", "\xf0\x9f\x87\xb3\xf0\x9f\x87\xa6"}, // 🇳🇦 + {":new_caledonia:", "\xf0\x9f\x87\xb3\xf0\x9f\x87\xa8"}, // 🇳🇨 + {":niger:", "\xf0\x9f\x87\xb3\xf0\x9f\x87\xaa"}, // 🇳🇪 + {":norfolk_island:", "\xf0\x9f\x87\xb3\xf0\x9f\x87\xab"}, // 🇳🇫 + {":nigeria:", "\xf0\x9f\x87\xb3\xf0\x9f\x87\xac"}, // 🇳🇬 + {":nicaragua:", "\xf0\x9f\x87\xb3\xf0\x9f\x87\xae"}, // 🇳🇮 + {":netherlands:", "\xf0\x9f\x87\xb3\xf0\x9f\x87\xb1"}, // 🇳🇱 + {":norway:", "\xf0\x9f\x87\xb3\xf0\x9f\x87\xb4"}, // 🇳🇴 + {":nepal:", "\xf0\x9f\x87\xb3\xf0\x9f\x87\xb5"}, // 🇳🇵 + {":nauru:", "\xf0\x9f\x87\xb3\xf0\x9f\x87\xb7"}, // 🇳🇷 + {":niue:", "\xf0\x9f\x87\xb3\xf0\x9f\x87\xba"}, // 🇳🇺 + {":new_zealand:", "\xf0\x9f\x87\xb3\xf0\x9f\x87\xbf"}, // 🇳🇿 + {":oman:", "\xf0\x9f\x87\xb4\xf0\x9f\x87\xb2"}, // 🇴🇲 + {":panama:", "\xf0\x9f\x87\xb5\xf0\x9f\x87\xa6"}, // 🇵🇦 + {":peru:", "\xf0\x9f\x87\xb5\xf0\x9f\x87\xaa"}, // 🇵🇪 + {":french_polynesia:", "\xf0\x9f\x87\xb5\xf0\x9f\x87\xab"}, // 🇵🇫 + {":papua_new_guinea:", "\xf0\x9f\x87\xb5\xf0\x9f\x87\xac"}, // 🇵🇬 + {":philippines:", "\xf0\x9f\x87\xb5\xf0\x9f\x87\xad"}, // 🇵🇭 + {":pakistan:", "\xf0\x9f\x87\xb5\xf0\x9f\x87\xb0"}, // 🇵🇰 + {":poland:", "\xf0\x9f\x87\xb5\xf0\x9f\x87\xb1"}, // 🇵🇱 + {":st_pierre_miquelon:", "\xf0\x9f\x87\xb5\xf0\x9f\x87\xb2"}, // 🇵🇲 + {":pitcairn_islands:", "\xf0\x9f\x87\xb5\xf0\x9f\x87\xb3"}, // 🇵🇳 + {":puerto_rico:", "\xf0\x9f\x87\xb5\xf0\x9f\x87\xb7"}, // 🇵🇷 + {":palestinian_territories:", "\xf0\x9f\x87\xb5\xf0\x9f\x87\xb8"}, // 🇵🇸 + {":portugal:", "\xf0\x9f\x87\xb5\xf0\x9f\x87\xb9"}, // 🇵🇹 + {":palau:", "\xf0\x9f\x87\xb5\xf0\x9f\x87\xbc"}, // 🇵🇼 + {":paraguay:", "\xf0\x9f\x87\xb5\xf0\x9f\x87\xbe"}, // 🇵🇾 + {":qatar:", "\xf0\x9f\x87\xb6\xf0\x9f\x87\xa6"}, // 🇶🇦 + {":reunion:", "\xf0\x9f\x87\xb7\xf0\x9f\x87\xaa"}, // 🇷🇪 + {":romania:", "\xf0\x9f\x87\xb7\xf0\x9f\x87\xb4"}, // 🇷🇴 + {":serbia:", "\xf0\x9f\x87\xb7\xf0\x9f\x87\xb8"}, // 🇷🇸 + {":ru:", "\xf0\x9f\x87\xb7\xf0\x9f\x87\xba"}, // 🇷🇺 + {":rwanda:", "\xf0\x9f\x87\xb7\xf0\x9f\x87\xbc"}, // 🇷🇼 + {":saudi_arabia:", "\xf0\x9f\x87\xb8\xf0\x9f\x87\xa6"}, // 🇸🇦 + {":solomon_islands:", "\xf0\x9f\x87\xb8\xf0\x9f\x87\xa7"}, // 🇸🇧 + {":seychelles:", "\xf0\x9f\x87\xb8\xf0\x9f\x87\xa8"}, // 🇸🇨 + {":sudan:", "\xf0\x9f\x87\xb8\xf0\x9f\x87\xa9"}, // 🇸🇩 + {":sweden:", "\xf0\x9f\x87\xb8\xf0\x9f\x87\xaa"}, // 🇸🇪 + {":singapore:", "\xf0\x9f\x87\xb8\xf0\x9f\x87\xac"}, // 🇸🇬 + {":st_helena:", "\xf0\x9f\x87\xb8\xf0\x9f\x87\xad"}, // 🇸🇭 + {":slovenia:", "\xf0\x9f\x87\xb8\xf0\x9f\x87\xae"}, // 🇸🇮 + {":svalbard_jan_mayen:", "\xf0\x9f\x87\xb8\xf0\x9f\x87\xaf"}, // 🇸🇯 + {":slovakia:", "\xf0\x9f\x87\xb8\xf0\x9f\x87\xb0"}, // 🇸🇰 + {":sierra_leone:", "\xf0\x9f\x87\xb8\xf0\x9f\x87\xb1"}, // 🇸🇱 + {":san_marino:", "\xf0\x9f\x87\xb8\xf0\x9f\x87\xb2"}, // 🇸🇲 + {":senegal:", "\xf0\x9f\x87\xb8\xf0\x9f\x87\xb3"}, // 🇸🇳 + {":somalia:", "\xf0\x9f\x87\xb8\xf0\x9f\x87\xb4"}, // 🇸🇴 + {":suriname:", "\xf0\x9f\x87\xb8\xf0\x9f\x87\xb7"}, // 🇸🇷 + {":south_sudan:", "\xf0\x9f\x87\xb8\xf0\x9f\x87\xb8"}, // 🇸🇸 + {":sao_tome_principe:", "\xf0\x9f\x87\xb8\xf0\x9f\x87\xb9"}, // 🇸🇹 + {":el_salvador:", "\xf0\x9f\x87\xb8\xf0\x9f\x87\xbb"}, // 🇸🇻 + {":sint_maarten:", "\xf0\x9f\x87\xb8\xf0\x9f\x87\xbd"}, // 🇸🇽 + {":syria:", "\xf0\x9f\x87\xb8\xf0\x9f\x87\xbe"}, // 🇸🇾 + {":swaziland:", "\xf0\x9f\x87\xb8\xf0\x9f\x87\xbf"}, // 🇸🇿 + {":tristan_da_cunha:", "\xf0\x9f\x87\xb9\xf0\x9f\x87\xa6"}, // 🇹🇦 + {":turks_caicos_islands:", "\xf0\x9f\x87\xb9\xf0\x9f\x87\xa8"}, // 🇹🇨 + {":chad:", "\xf0\x9f\x87\xb9\xf0\x9f\x87\xa9"}, // 🇹🇩 + {":french_southern_territories:", "\xf0\x9f\x87\xb9\xf0\x9f\x87\xab"}, // 🇹🇫 + {":togo:", "\xf0\x9f\x87\xb9\xf0\x9f\x87\xac"}, // 🇹🇬 + {":thailand:", "\xf0\x9f\x87\xb9\xf0\x9f\x87\xad"}, // 🇹🇭 + {":tajikistan:", "\xf0\x9f\x87\xb9\xf0\x9f\x87\xaf"}, // 🇹🇯 + {":tokelau:", "\xf0\x9f\x87\xb9\xf0\x9f\x87\xb0"}, // 🇹🇰 + {":timor_leste:", "\xf0\x9f\x87\xb9\xf0\x9f\x87\xb1"}, // 🇹🇱 + {":turkmenistan:", "\xf0\x9f\x87\xb9\xf0\x9f\x87\xb2"}, // 🇹🇲 + {":tunisia:", "\xf0\x9f\x87\xb9\xf0\x9f\x87\xb3"}, // 🇹🇳 + {":tonga:", "\xf0\x9f\x87\xb9\xf0\x9f\x87\xb4"}, // 🇹🇴 + {":tr:", "\xf0\x9f\x87\xb9\xf0\x9f\x87\xb7"}, // 🇹🇷 + {":trinidad_tobago:", "\xf0\x9f\x87\xb9\xf0\x9f\x87\xb9"}, // 🇹🇹 + {":tuvalu:", "\xf0\x9f\x87\xb9\xf0\x9f\x87\xbb"}, // 🇹🇻 + {":taiwan:", "\xf0\x9f\x87\xb9\xf0\x9f\x87\xbc"}, // 🇹🇼 + {":tanzania:", "\xf0\x9f\x87\xb9\xf0\x9f\x87\xbf"}, // 🇹🇿 + {":ukraine:", "\xf0\x9f\x87\xba\xf0\x9f\x87\xa6"}, // 🇺🇦 + {":uganda:", "\xf0\x9f\x87\xba\xf0\x9f\x87\xac"}, // 🇺🇬 + {":us_outlying_islands:", "\xf0\x9f\x87\xba\xf0\x9f\x87\xb2"}, // 🇺🇲 + {":united_nations:", "\xf0\x9f\x87\xba\xf0\x9f\x87\xb3"}, // 🇺🇳 + {":us:", "\xf0\x9f\x87\xba\xf0\x9f\x87\xb8"}, // 🇺🇸 + {":uruguay:", "\xf0\x9f\x87\xba\xf0\x9f\x87\xbe"}, // 🇺🇾 + {":uzbekistan:", "\xf0\x9f\x87\xba\xf0\x9f\x87\xbf"}, // 🇺🇿 + {":vatican_city:", "\xf0\x9f\x87\xbb\xf0\x9f\x87\xa6"}, // 🇻🇦 + {":st_vincent_grenadines:", "\xf0\x9f\x87\xbb\xf0\x9f\x87\xa8"}, // 🇻🇨 + {":venezuela:", "\xf0\x9f\x87\xbb\xf0\x9f\x87\xaa"}, // 🇻🇪 + {":british_virgin_islands:", "\xf0\x9f\x87\xbb\xf0\x9f\x87\xac"}, // 🇻🇬 + {":us_virgin_islands:", "\xf0\x9f\x87\xbb\xf0\x9f\x87\xae"}, // 🇻🇮 + {":vietnam:", "\xf0\x9f\x87\xbb\xf0\x9f\x87\xb3"}, // 🇻🇳 + {":vanuatu:", "\xf0\x9f\x87\xbb\xf0\x9f\x87\xba"}, // 🇻🇺 + {":wallis_futuna:", "\xf0\x9f\x87\xbc\xf0\x9f\x87\xab"}, // 🇼🇫 + {":samoa:", "\xf0\x9f\x87\xbc\xf0\x9f\x87\xb8"}, // 🇼🇸 + {":kosovo:", "\xf0\x9f\x87\xbd\xf0\x9f\x87\xb0"}, // 🇽🇰 + {":yemen:", "\xf0\x9f\x87\xbe\xf0\x9f\x87\xaa"}, // 🇾🇪 + {":mayotte:", "\xf0\x9f\x87\xbe\xf0\x9f\x87\xb9"}, // 🇾🇹 + {":south_africa:", "\xf0\x9f\x87\xbf\xf0\x9f\x87\xa6"}, // 🇿🇦 + {":zambia:", "\xf0\x9f\x87\xbf\xf0\x9f\x87\xb2"}, // 🇿🇲 + {":zimbabwe:", "\xf0\x9f\x87\xbf\xf0\x9f\x87\xbc"}, // 🇿🇼 + {":england:", "\xf0\x9f\x8f\xb4\xf3\xa0\x81\xa7\xf3\xa0\x81\xa2\xf3\xa0\x81\xa5\xf3\xa0\x81\xae\xf3\xa0\x81\xa7\xf3\xa0\x81\xbf"}, // 🏴󠁧󠁢󠁥󠁮󠁧󠁿 + {":scotland:", "\xf0\x9f\x8f\xb4\xf3\xa0\x81\xa7\xf3\xa0\x81\xa2\xf3\xa0\x81\xb3\xf3\xa0\x81\xa3\xf3\xa0\x81\xb4\xf3\xa0\x81\xbf"}, // 🏴󠁧󠁢󠁳󠁣󠁴󠁿 + {":wales:", "\xf0\x9f\x8f\xb4\xf3\xa0\x81\xa7\xf3\xa0\x81\xa2\xf3\xa0\x81\xb7\xf3\xa0\x81\xac\xf3\xa0\x81\xb3\xf3\xa0\x81\xbf"}, // 🏴󠁧󠁢󠁷󠁬󠁳󠁿 {NULL, NULL} }; - #endif diff --git a/client/emojis_scrap_github.py b/client/emojis_scrap_github.py index 777bf8aa5..4c102e644 100755 --- a/client/emojis_scrap_github.py +++ b/client/emojis_scrap_github.py @@ -10,7 +10,11 @@ EMOJI_JSON_URL = 'https://raw.githubusercontent.com/github/gemoji/master/db/emoj def print_emoji(emoji_json): for alias in emoji_json['aliases']: - print(' {{":{0}:", "{1}"}},'.format(alias, emoji_json['emoji'])) + print(' {{":{0}:", "{1}"}}, // {2}'.format(alias, + +''.join('\\x{:02x}'.format(b) for b in emoji_json['emoji'].encode('utf8')), + +emoji_json['emoji'])) print( """#ifndef EMOJIS_H__ @@ -23,13 +27,12 @@ typedef struct emoji_s { // emoji_t array are expected to be NULL terminated static emoji_t EmojiTable[] = {""") + with urlopen(EMOJI_JSON_URL) as conn: emojis_json = json.loads(conn.read().decode('utf-8')) for emoji_json in emojis_json: print_emoji(emoji_json) -print( -""" {NULL, NULL} +print(""" {NULL, NULL} }; - #endif""") diff --git a/client/ui.c b/client/ui.c index 1c04def6c..e4343fec3 100644 --- a/client/ui.c +++ b/client/ui.c @@ -391,7 +391,7 @@ void memcpy_filter_ansi(void *dest, const void *src, size_t n, bool filter) { static bool emojify_token(const char *token, uint8_t token_length, const char **emojified_token, uint8_t *emojified_token_length, emojiMode_t mode) { int i = 0; - while (EmojiTable[i].alias) { + while (EmojiTable[i].alias && EmojiTable[i].emoji) { if ((strlen(EmojiTable[i].alias) == token_length) && (0 == memcmp(EmojiTable[i].alias, token, token_length))) { switch (mode) { case EMOJI: { @@ -402,7 +402,7 @@ static bool emojify_token(const char *token, uint8_t token_length, const char ** case ALTTEXT: { int j = 0; *emojified_token_length = 0; - while (EmojiAltTable[j].alias) { + while (EmojiAltTable[j].alias && EmojiAltTable[i].alttext) { if ((strlen(EmojiAltTable[j].alias) == token_length) && (0 == memcmp(EmojiAltTable[j].alias, token, token_length))) { *emojified_token = EmojiAltTable[j].alttext; *emojified_token_length = strlen(EmojiAltTable[j].alttext); From 82077b2f1ce159cf225d58721086a2d724562a8c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 16 Mar 2020 18:42:34 +0100 Subject: [PATCH 1708/1854] hint now uses session struct, in preperation for a preference file. --- client/cmdmain.c | 17 ++++++----------- client/proxgui.h | 1 - client/ui.c | 2 +- client/ui.h | 1 + 4 files changed, 8 insertions(+), 13 deletions(-) diff --git a/client/cmdmain.c b/client/cmdmain.c index 57cd4d10a..8d4b1c8b7 100644 --- a/client/cmdmain.c +++ b/client/cmdmain.c @@ -196,30 +196,25 @@ static int CmdHints(const char *Cmd) { char ctmp = tolower(param_getchar(Cmd, 0)); if (ctmp == 'h') return usage_hints(); - if (strlen(Cmd) < 1) { - PrintAndLogEx(INFO, "Hints are %s", (g_showhints) ? "ON" : "OFF"); - return PM3_SUCCESS; - } - if (strlen(Cmd) > 1){ str_lower((char *)Cmd); if (str_startswith(Cmd, "of")) { - g_showhints = false; + session.show_hints = false; } else { - g_showhints = true; + session.show_hints = true; } - } else { + } else if (strlen(Cmd) == 1) { if (param_getchar(Cmd, 0) != 0x00) { ms = param_get32ex(Cmd, 0, 0, 10); if (ms == 0) { - g_showhints = false; + session.show_hints = false; } else { - g_showhints = true; + session.show_hints = true; } } } - PrintAndLogEx(INFO, "Hints are %s", (g_showhints) ? "ON" : "OFF"); + PrintAndLogEx(INFO, "Hints are %s", (session.show_hints) ? "ON" : "OFF"); return PM3_SUCCESS; } diff --git a/client/proxgui.h b/client/proxgui.h index fea28d62b..c9cd0096d 100644 --- a/client/proxgui.h +++ b/client/proxgui.h @@ -55,7 +55,6 @@ extern size_t DemodBufferLen; extern size_t g_DemodStartIdx; extern bool showDemod; extern uint8_t g_debugMode; -extern uint8_t g_showhints; #ifndef FILE_PATH_SIZE #define FILE_PATH_SIZE 1000 diff --git a/client/ui.c b/client/ui.c index e4343fec3..d470647b7 100644 --- a/client/ui.c +++ b/client/ui.c @@ -131,7 +131,7 @@ void PrintAndLogEx(logLevel_t level, const char *fmt, ...) { return; // skip HINT messages if client has hints turned off i.e. 'HINT 0' - if (g_showhints == 0 && level == HINT) + if (session.show_hints == false && level == HINT) return; char prefix[40] = {0}; diff --git a/client/ui.h b/client/ui.h index 3b07caf46..5bb814b81 100644 --- a/client/ui.h +++ b/client/ui.h @@ -27,6 +27,7 @@ typedef struct { emojiMode_t emoji_mode; bool pm3_present; bool help_dump_mode; + bool show_hints; } session_arg_t; extern session_arg_t session; From 9f787faea647e013b838dd72b47115ed2a4ba92c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 16 Mar 2020 18:43:24 +0100 Subject: [PATCH 1709/1854] remove var --- client/util.h | 1 - 1 file changed, 1 deletion(-) diff --git a/client/util.h b/client/util.h index e010175a6..fb31e6013 100644 --- a/client/util.h +++ b/client/util.h @@ -23,7 +23,6 @@ uint8_t g_debugMode; uint8_t g_printAndLog; -uint8_t g_showhints; #define PRINTANDLOG_PRINT 1 #define PRINTANDLOG_LOG 2 From c769d661f135ad1002da63fd226dfee4996d940d Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 16 Mar 2020 21:34:27 +0100 Subject: [PATCH 1710/1854] emoji -> alttext in logfiles --- client/ui.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/client/ui.c b/client/ui.c index d470647b7..177e495aa 100644 --- a/client/ui.c +++ b/client/ui.c @@ -331,10 +331,11 @@ static void fPrintAndLog(FILE *stream, const char *fmt, ...) { #endif if ((g_printAndLog & PRINTANDLOG_LOG) && logging && logfile) { + memcpy_filter_emoji(buffer3, buffer2, sizeof(buffer2), ALTTEXT); if (filter_ansi) { // already done - fprintf(logfile, "%s\n", buffer2); + fprintf(logfile, "%s\n", buffer3); } else { - memcpy_filter_ansi(buffer, buffer2, sizeof(buffer2), true); + memcpy_filter_ansi(buffer, buffer3, sizeof(buffer3), true); fprintf(logfile, "%s\n", buffer); } fflush(logfile); From 0a616d61f713781d95696c0e96f1562b9d7a3ca8 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 16 Mar 2020 21:45:08 +0100 Subject: [PATCH 1711/1854] less emoji --- client/ui.c | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/client/ui.c b/client/ui.c index 177e495aa..df62b9bff 100644 --- a/client/ui.c +++ b/client/ui.c @@ -146,41 +146,31 @@ void PrintAndLogEx(logLevel_t level, const char *fmt, ...) { switch (level) { case ERR: if (session.emoji_mode == EMOJI) - strncpy(prefix, " :rotating_light: ", sizeof(prefix) - 1); + strncpy(prefix, _RED_("[!!]") " :rotating_light: ", sizeof(prefix) - 1); else strncpy(prefix, _RED_("[!!]"), sizeof(prefix) - 1); stream = stderr; break; case FAILED: if (session.emoji_mode == EMOJI) - strncpy(prefix, " :no_entry: ", sizeof(prefix) - 1); + strncpy(prefix, _RED_("[-]") " :no_entry: ", sizeof(prefix) - 1); else strncpy(prefix, _RED_("[-]"), sizeof(prefix) - 1); break; case DEBUG: - if (session.emoji_mode == EMOJI) - strncpy(prefix, " :speech_balloon: ", sizeof(prefix) - 1); - else - strncpy(prefix, _BLUE_("[#]"), sizeof(prefix) - 1); - break; + strncpy(prefix, _BLUE_("[#]"), sizeof(prefix) - 1); case HINT: case SUCCESS: - if (session.emoji_mode == EMOJI) - strncpy(prefix, " :star: ", sizeof(prefix) - 1); - else - strncpy(prefix, _GREEN_("[+]"), sizeof(prefix) - 1); + strncpy(prefix, _GREEN_("[+]"), sizeof(prefix) - 1); break; case WARNING: if (session.emoji_mode == EMOJI) - strncpy(prefix, " :warning: ", sizeof(prefix) - 1); + strncpy(prefix, _CYAN_("[!]") " :warning: ", sizeof(prefix) - 1); else strncpy(prefix, _CYAN_("[!]"), sizeof(prefix) - 1); break; case INFO: - if (session.emoji_mode == EMOJI) - strncpy(prefix, " :information_source: ", sizeof(prefix) - 1); - else - strncpy(prefix, _YELLOW_("[=]"), sizeof(prefix) - 1); + strncpy(prefix, _YELLOW_("[=]"), sizeof(prefix) - 1); break; case INPLACE: if (session.emoji_mode == EMOJI) { From 3fa86bf80b3cd978acc0964b9e0f5558cf6ddec4 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 16 Mar 2020 21:45:17 +0100 Subject: [PATCH 1712/1854] iceman needs his coffee --- client/proxmark3.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/proxmark3.c b/client/proxmark3.c index c21852852..3217d0583 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -36,14 +36,14 @@ static void showBanner(void) { PrintAndLogEx(NORMAL, " " _BLUE_("██████╗ ███╗ ███╗ ████╗ ")); PrintAndLogEx(NORMAL, " " _BLUE_("██╔══██╗████╗ ████║ ══█║")); PrintAndLogEx(NORMAL, " " _BLUE_("██████╔╝██╔████╔██║ ████╔╝")); - PrintAndLogEx(NORMAL, " " _BLUE_("██╔═══╝ ██║╚██╔╝██║ ══█║") " :snowflake: iceman@icesql.net"); + PrintAndLogEx(NORMAL, " " _BLUE_("██╔═══╝ ██║╚██╔╝██║ ══█║") " :snowflake: iceman@icesql.net :coffee:"); PrintAndLogEx(NORMAL, " " _BLUE_("██║ ██║ ╚═╝ ██║ ████╔╝") " https://github.com/rfidresearchgroup/proxmark3/"); PrintAndLogEx(NORMAL, " " _BLUE_("╚═╝ ╚═╝ ╚═╝ ╚═══╝ ") "pre-release v4.0"); #else PrintAndLogEx(NORMAL, " ======. ===. ===. ====."); PrintAndLogEx(NORMAL, " ==...==.====. ====. ..=."); PrintAndLogEx(NORMAL, " ======..==.====.==. ====.."); - PrintAndLogEx(NORMAL, " ==..... ==..==..==. ..=. iceman@icesql.net"); + PrintAndLogEx(NORMAL, " ==..... ==..==..==. ..=. iceman@icesql.net :coffee:"); PrintAndLogEx(NORMAL, " ==. ==. ... ==. ====.. https://github.com/rfidresearchgroup/proxmark3/"); PrintAndLogEx(NORMAL, " ... ... ... ..... pre-release v4.0"); #endif From 7a7a3d014e8800f5644664962bf7d9089b819b53 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 16 Mar 2020 21:51:45 +0100 Subject: [PATCH 1713/1854] hf mfdes info - remake to work with Desfire Light. Switch to apdu framing. WIP --- armsrc/mifaredesfire.c | 77 +++++++++++------- client/cmdhfmfdes.c | 175 ++++++++++++++++++++++++++--------------- 2 files changed, 160 insertions(+), 92 deletions(-) diff --git a/armsrc/mifaredesfire.c b/armsrc/mifaredesfire.c index c13311051..cd47b5ca9 100644 --- a/armsrc/mifaredesfire.c +++ b/armsrc/mifaredesfire.c @@ -14,6 +14,7 @@ #include "crc16.h" #include "mbedtls/aes.h" #include "commonutil.h" +#include "util.h" #define MAX_APPLICATION_COUNT 28 #define MAX_FILE_COUNT 16 @@ -83,7 +84,7 @@ void MifareSendCommand(uint8_t arg0, uint8_t arg1, uint8_t *datain) { int len = DesfireAPDU(datain, datalen, resp); if (DBGLEVEL >= 4) - print_result("ERR <--: ", resp, len); + print_result("RESP <--: ", resp, len); if (!len) { OnError(2); @@ -96,16 +97,25 @@ void MifareSendCommand(uint8_t arg0, uint8_t arg1, uint8_t *datain) { if (flags & DISCONNECT) OnSuccess(); - reply_old(CMD_ACK, 1, len, 0, resp, len); + reply_mix(CMD_ACK, 1, len, 0, resp, len); } void MifareDesfireGetInformation() { + LEDsoff(); + int len = 0; iso14a_card_select_t card; uint8_t resp[PM3_CMD_DATA_SIZE] = {0x00}; - uint8_t dataout[PM3_CMD_DATA_SIZE] = {0x00}; + struct p { + uint8_t isOK; + uint8_t uid[7]; + uint8_t versionHW[7]; + uint8_t versionSW[7]; + uint8_t details[14]; + } PACKED payload; + /* 1 = PCB 1 2 = cid 2 @@ -122,61 +132,65 @@ void MifareDesfireGetInformation() { // card select - information if (!iso14443a_select_card(NULL, &card, NULL, true, 0, false)) { if (DBGLEVEL >= DBG_ERROR) DbpString("Can't select card"); - OnError(1); + payload.isOK = 1; // 2 == can not select + reply_ng(CMD_HF_DESFIRE_INFO, PM3_ESOFT, (uint8_t *)&payload, sizeof(payload)); + switch_off(); return; } if (card.uidlen != 7) { if (DBGLEVEL >= DBG_ERROR) Dbprintf("Wrong UID size. Expected 7byte got %d", card.uidlen); - OnError(2); + payload.isOK = 2; // 2 == WRONG UID + reply_ng(CMD_HF_DESFIRE_INFO, PM3_ESOFT, (uint8_t *)&payload, sizeof(payload)); + switch_off(); return; } - - memcpy(dataout, card.uid, 7); + // add uid. + memcpy(payload.uid, card.uid, sizeof(card.uid)); LED_A_ON(); - LED_B_OFF(); - LED_C_OFF(); - - uint8_t cmd[] = {GET_VERSION}; + uint8_t cmd[] = {GET_VERSION, 0x00, 0x00, 0x00}; size_t cmd_len = sizeof(cmd); len = DesfireAPDU(cmd, cmd_len, resp); if (!len) { print_result("ERROR <--: ", resp, len); - OnError(3); + payload.isOK = 3; // 3 == DOESNT ANSWER TO GET_VERSION + reply_ng(CMD_HF_DESFIRE_INFO, PM3_ESOFT, (uint8_t *)&payload, sizeof(payload)); + switch_off(); return; } - LED_A_OFF(); - LED_B_ON(); - memcpy(dataout + 7, resp + 3, 7); + memcpy(payload.versionHW, resp + 1, sizeof(payload.versionHW)); // ADDITION_FRAME 1 cmd[0] = ADDITIONAL_FRAME; len = DesfireAPDU(cmd, cmd_len, resp); if (!len) { print_result("ERROR <--: ", resp, len); - OnError(3); + payload.isOK = 3; // 3 == DOESNT ANSWER TO GET_VERSION + reply_ng(CMD_HF_DESFIRE_INFO, PM3_ESOFT, (uint8_t *)&payload, sizeof(payload)); + switch_off(); return; } - - LED_B_OFF(); - LED_C_ON(); - memcpy(dataout + 7 + 7, resp + 3, 7); + memcpy(payload.versionSW, resp + 1, sizeof(payload.versionSW)); // ADDITION_FRAME 2 len = DesfireAPDU(cmd, cmd_len, resp); if (!len) { print_result("ERROR <--: ", resp, len); - OnError(3); + payload.isOK = 3; // 3 == DOESNT ANSWER TO GET_VERSION + reply_ng(CMD_HF_DESFIRE_INFO, PM3_ESOFT, (uint8_t *)&payload, sizeof(payload)); + switch_off(); return; } - memcpy(dataout + 7 + 7 + 7, resp + 3, 14); - - reply_old(CMD_ACK, 1, 0, 0, dataout, sizeof(dataout)); + memcpy(payload.details, resp + 1, sizeof(payload.details)); + LED_B_ON(); + reply_ng(CMD_HF_DESFIRE_INFO, PM3_SUCCESS, (uint8_t *)&payload, sizeof(payload)); + LED_B_OFF(); + // reset the pcb_blocknum, pcb_blocknum = 0; OnSuccess(); @@ -517,7 +531,7 @@ void MifareDES_Auth1(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) } OnSuccess(); - reply_old(CMD_ACK, 1, len, 0, resp, len); + reply_mix(CMD_ACK, 1, len, 0, resp, len); } // 3 different ISO ways to send data to a DESFIRE (direct, capsuled, capsuled ISO) @@ -565,15 +579,20 @@ size_t CreateAPDU(uint8_t *datain, size_t len, uint8_t *dataout) { uint8_t cmd[cmdlen]; memset(cmd, 0, cmdlen); - cmd[0] = 0x0A; // 0x0A = send cid, 0x02 = no cid. + cmd[0] = 0x02; // 0x0A = send cid, 0x02 = no cid. cmd[0] |= pcb_blocknum; // OR the block number into the PCB - cmd[1] = 0x00; // CID: 0x00 //TODO: allow multiple selected cards + + cmd[1] = 0x90; // CID: 0x00 //TODO: allow multiple selected cards memcpy(cmd + 2, datain, len); AddCrc14A(cmd, len + 2); - + +/* +hf 14a apdu -sk 90 60 00 00 00 +hf 14a apdu -k 90 AF 00 00 00 +hf 14a apdu 90AF000000 +*/ memcpy(dataout, cmd, cmdlen); - return cmdlen; } diff --git a/client/cmdhfmfdes.c b/client/cmdhfmfdes.c index 698af4a2d..d9790726d 100644 --- a/client/cmdhfmfdes.c +++ b/client/cmdhfmfdes.c @@ -31,13 +31,24 @@ static int CmdHF14ADesInfo(const char *Cmd) { SendCommandNG(CMD_HF_DESFIRE_INFO, NULL, 0); PacketResponseNG resp; - if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { + if (!WaitForResponseTimeout(CMD_HF_DESFIRE_INFO, &resp, 1500)) { PrintAndLogEx(WARNING, "Command execute timeout"); return PM3_ETIMEOUT; } - uint8_t isOK = resp.oldarg[0] & 0xff; - if (!isOK) { - switch (resp.oldarg[1]) { + + struct p { + uint8_t isOK; + uint8_t uid[7]; + uint8_t versionHW[7]; + uint8_t versionSW[7]; + uint8_t details[14]; + } PACKED; + + struct p *package = (struct p *) resp.data.asBytes; + + if (resp.status != PM3_SUCCESS) { + + switch (package->isOK) { case 1: PrintAndLogEx(WARNING, "Can't select card"); break; @@ -51,45 +62,49 @@ static int CmdHF14ADesInfo(const char *Cmd) { } return PM3_ESOFT; } + PrintAndLogEx(NORMAL, ""); PrintAndLogEx(INFO, "-- Desfire Information --------------------------------------"); PrintAndLogEx(INFO, "-------------------------------------------------------------"); - PrintAndLogEx(SUCCESS, " UID : " _GREEN_("%s"), sprint_hex(resp.data.asBytes, 7)); - PrintAndLogEx(SUCCESS, " Batch number : " _GREEN_("%s"), sprint_hex(resp.data.asBytes + 28, 5)); - PrintAndLogEx(SUCCESS, " Production date : week %02x, 20%02x", resp.data.asBytes[33], resp.data.asBytes[34]); + PrintAndLogEx(SUCCESS, " UID : " _GREEN_("%s"), sprint_hex(package->uid, sizeof(package->uid))); + PrintAndLogEx(SUCCESS, " Batch number : " _GREEN_("%s"), sprint_hex(package->details + 7, 5)); + PrintAndLogEx(SUCCESS, " Production date : week " _GREEN_("%02x") "/ " _GREEN_("20%02x"), package->details[12], package->details[13]); PrintAndLogEx(INFO, " -----------------------------------------------------------"); PrintAndLogEx(INFO, " Hardware Information"); - PrintAndLogEx(SUCCESS, " Vendor Id : " _YELLOW_("%s"), getTagInfo(resp.data.asBytes[7])); - PrintAndLogEx(SUCCESS, " Type : " _YELLOW_("0x%02X"), resp.data.asBytes[8]); - PrintAndLogEx(SUCCESS, " Subtype : " _YELLOW_("0x%02X"), resp.data.asBytes[9]); - PrintAndLogEx(SUCCESS, " Version : " _YELLOW_("%s"), getVersionStr(resp.data.asBytes[10], resp.data.asBytes[11])); - PrintAndLogEx(SUCCESS, " Storage size : " _YELLOW_("%s"), getCardSizeStr(resp.data.asBytes[12])); - PrintAndLogEx(SUCCESS, " Protocol : " _YELLOW_("%s"), getProtocolStr(resp.data.asBytes[13])); + PrintAndLogEx(SUCCESS, " Vendor Id : " _YELLOW_("%s"), getTagInfo(package->versionHW[0])); + PrintAndLogEx(SUCCESS, " Type : " _YELLOW_("0x%02X"), package->versionHW[1]); + PrintAndLogEx(SUCCESS, " Subtype : " _YELLOW_("0x%02X"), package->versionHW[2]); + PrintAndLogEx(SUCCESS, " Version : %s", getVersionStr(package->versionHW[3], package->versionHW[4])); + PrintAndLogEx(SUCCESS, " Storage size : %s", getCardSizeStr(package->versionHW[5])); + PrintAndLogEx(SUCCESS, " Protocol : %s", getProtocolStr(package->versionHW[6])); PrintAndLogEx(INFO, " -----------------------------------------------------------"); PrintAndLogEx(INFO, " Software Information"); - PrintAndLogEx(SUCCESS, " Vendor Id : " _YELLOW_("%s"), getTagInfo(resp.data.asBytes[14])); - PrintAndLogEx(SUCCESS, " Type : " _YELLOW_("0x%02X"), resp.data.asBytes[15]); - PrintAndLogEx(SUCCESS, " Subtype : " _YELLOW_("0x%02X"), resp.data.asBytes[16]); - PrintAndLogEx(SUCCESS, " Version : " _YELLOW_("%d.%d"), resp.data.asBytes[17], resp.data.asBytes[18]); - PrintAndLogEx(SUCCESS, " storage size : " _YELLOW_("%s"), getCardSizeStr(resp.data.asBytes[19])); - PrintAndLogEx(SUCCESS, " Protocol : " _YELLOW_("%s"), getProtocolStr(resp.data.asBytes[20])); + PrintAndLogEx(SUCCESS, " Vendor Id : " _YELLOW_("%s"), getTagInfo(package->versionSW[0])); + PrintAndLogEx(SUCCESS, " Type : " _YELLOW_("0x%02X"), package->versionSW[1]); + PrintAndLogEx(SUCCESS, " Subtype : " _YELLOW_("0x%02X"), package->versionSW[2]); + PrintAndLogEx(SUCCESS, " Version : " _YELLOW_("%d.%d"), package->versionSW[3], package->versionSW[4]); + PrintAndLogEx(SUCCESS, " storage size : %s", getCardSizeStr(package->versionSW[5])); + PrintAndLogEx(SUCCESS, " Protocol : %s", getProtocolStr(package->versionSW[6])); PrintAndLogEx(INFO, "-------------------------------------------------------------"); // Master Key settings getKeySettings(NULL); // Free memory on card - uint8_t data[1] = {GET_FREE_MEMORY}; - SendCommandOLD(CMD_HF_DESFIRE_COMMAND, (INIT | DISCONNECT), 0x01, 0, data, sizeof(data)); + uint8_t c[] = {GET_FREE_MEMORY, 0x00, 0x00, 0x00}; // 0x6E + SendCommandMIX(CMD_HF_DESFIRE_COMMAND, (INIT | DISCONNECT), sizeof(c), 0, c, sizeof(c)); if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) return PM3_ETIMEOUT; - uint8_t tmp[3]; - memcpy(tmp, resp.data.asBytes + 3, 3); - - PrintAndLogEx(SUCCESS, " Available free memory on card : " _GREEN_("%d bytes"), le24toh(tmp)); + // Desfire Light doesn't support FREEMEM (len = 5) + if (resp.length == 8) { + uint8_t tmp[3]; + memcpy(tmp, resp.data.asBytes + 1, 3); + PrintAndLogEx(SUCCESS, " Available free memory on card : " _GREEN_("%d bytes"), le24toh(tmp)); + } else { + PrintAndLogEx(SUCCESS, " Card doesn't support 'free mem' cmd"); + } PrintAndLogEx(INFO, "-------------------------------------------------------------"); - /* Card Master key (CMK) 0x00 AID = 00 00 00 (card level) Application Master Key (AMK) 0x00 AID != 00 00 00 @@ -116,7 +131,7 @@ static int CmdHF14ADesInfo(const char *Cmd) { */ char *getCardSizeStr(uint8_t fsize) { - static char buf[30] = {0x00}; + static char buf[40] = {0x00}; char *retStr = buf; uint16_t usize = 1 << ((fsize >> 1) + 1); @@ -124,37 +139,39 @@ char *getCardSizeStr(uint8_t fsize) { // is LSB set? if (fsize & 1) - sprintf(retStr, "0x%02X (%d - %d bytes)", fsize, usize, lsize); + sprintf(retStr, "0x%02X ( " _YELLOW_("%d - %d bytes") ")", fsize, usize, lsize); else - sprintf(retStr, "0x%02X (%d bytes)", fsize, lsize); + sprintf(retStr, "0x%02X ( " _YELLOW_("%d bytes") ")", fsize, lsize); return buf; } char *getProtocolStr(uint8_t id) { - static char buf[30] = {0x00}; + static char buf[40] = {0x00}; char *retStr = buf; if (id == 0x05) - sprintf(retStr, "0x%02X (ISO 14443-3, 14443-4)", id); + sprintf(retStr, "0x%02X ( " _YELLOW_("ISO 14443-3, 14443-4") ")", id); else - sprintf(retStr, "0x%02X (Unknown)", id); + sprintf(retStr, "0x%02X ( " _YELLOW_("Unknown") ")", id); return buf; } char *getVersionStr(uint8_t major, uint8_t minor) { - static char buf[30] = {0x00}; + static char buf[40] = {0x00}; char *retStr = buf; if (major == 0x00) - sprintf(retStr, "%d.%d (Desfire MF3ICD40)", major, minor); + sprintf(retStr, "%x.%x ( " _YELLOW_("Desfire MF3ICD40") ")", major, minor); else if (major == 0x01 && minor == 0x00) - sprintf(retStr, "%d.%d (Desfire EV1)", major, minor); + sprintf(retStr, "%x.%x ( " _YELLOW_("Desfire EV1") ")", major, minor); else if (major == 0x12 && minor == 0x00) - sprintf(retStr, "%d.%d (Desfire EV2)", major, minor); + sprintf(retStr, "%x.%x ( " _YELLOW_("Desfire EV2") ")", major, minor); + else if (major == 0x30 && minor == 0x00) + sprintf(retStr, "%x.%x ( " _YELLOW_("Desfire Light") ")", major, minor); else - sprintf(retStr, "%d.%d (Unknown)", major, minor); + sprintf(retStr, "%x.%x ( " _YELLOW_("Unknown") ")", major, minor); return buf; } @@ -165,14 +182,15 @@ void getKeySettings(uint8_t *aid) { uint8_t isOK = 0; PacketResponseNG resp; - //memset(messStr, 0x00, 512); - if (aid == NULL) { + + // CARD MASTER KEY + PrintAndLogEx(SUCCESS, " CMK - PICC, Card Master Key settings"); PrintAndLogEx(INFO, "-------------------------------------------------------------"); { - uint8_t data[1] = {GET_KEY_SETTINGS}; // 0x45 - SendCommandOLD(CMD_HF_DESFIRE_COMMAND, INIT | DISCONNECT, sizeof(data), 0, data, sizeof(data)); + uint8_t data[] = {GET_KEY_SETTINGS, 0x00, 0x00, 0x00}; // 0x45 + SendCommandMIX(CMD_HF_DESFIRE_COMMAND, INIT | DISCONNECT, sizeof(data), 0, data, sizeof(data)); } if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)) {return;} isOK = resp.oldarg[0] & 0xff; @@ -180,18 +198,41 @@ void getKeySettings(uint8_t *aid) { PrintAndLogEx(WARNING, _RED_(" Can't select master application")); return; } + // Not supported 02 91 1c c4 ca + // OK - 02 0f 01 91 00 7e fe + if (resp.length == 7 ) { + + // number of Master keys (0x01) + PrintAndLogEx(SUCCESS, " [0x08] Number of Masterkeys : %u", resp.data.asBytes[2]); + uint8_t setting = (resp.data.asBytes[2] >> 6); + switch(setting) { + case 0: + PrintAndLogEx(SUCCESS, " [00] (3)DES operation of PICC master key"); + break; + case 1: + PrintAndLogEx(SUCCESS, " [01] 3K3DES operation of PICC master key"); + break; + case 2: + PrintAndLogEx(SUCCESS, " [02] AES operation of PICC master key"); + break; + default: + break; + } + + str = (resp.data.asBytes[2] & (1 << 3)) ? _GREEN_("YES") : "NO"; + PrintAndLogEx(SUCCESS, " [0x08] Configuration changeable : %s", str); + str = (resp.data.asBytes[2] & (1 << 2)) ? "NO" : _GREEN_("YES"); + PrintAndLogEx(SUCCESS, " [0x04] CMK required for create/delete : %s", str); + str = (resp.data.asBytes[2] & (1 << 1)) ? "NO" : _GREEN_("YES"); + PrintAndLogEx(SUCCESS, " [0x02] Directory list access with CMK : %s", str); + str = (resp.data.asBytes[2] & (1 << 0)) ? _GREEN_("YES") : "NO"; + PrintAndLogEx(SUCCESS, " [0x01] CMK is changeable : %s", str); + } - str = (resp.data.asBytes[3] & (1 << 3)) ? _GREEN_("YES") : "NO"; - PrintAndLogEx(SUCCESS, " [0x08] Configuration changeable : %s", str); - str = (resp.data.asBytes[3] & (1 << 2)) ? "NO" : _GREEN_("YES"); - PrintAndLogEx(SUCCESS, " [0x04] CMK required for create/delete : %s", str); - str = (resp.data.asBytes[3] & (1 << 1)) ? "NO" : _GREEN_("YES"); - PrintAndLogEx(SUCCESS, " [0x02] Directory list access with CMK : %s", str); - str = (resp.data.asBytes[3] & (1 << 0)) ? _GREEN_("YES") : "NO"; - PrintAndLogEx(SUCCESS, " [0x01] CMK is changeable : %s", str); - - { - uint8_t data[2] = {GET_KEY_VERSION, 0}; // 0x64 + // dd == key version + // cla ins p1 p2 lc dd le + { // 90, 64, + uint8_t data[] = {GET_KEY_VERSION, 0x00, 0x00, 0x01, 0x00, 0x00}; // 0x64 SendCommandMIX(CMD_HF_DESFIRE_COMMAND, INIT | DISCONNECT, sizeof(data), 0, data, sizeof(data)); } @@ -201,13 +242,17 @@ void getKeySettings(uint8_t *aid) { PrintAndLogEx(WARNING, _RED_(" Can't read key-version")); return; } - PrintAndLogEx(SUCCESS, ""); - PrintAndLogEx(SUCCESS, " Max number of keys : " _YELLOW_("%d"), resp.data.asBytes[4]); - PrintAndLogEx(SUCCESS, " Master key Version : " _YELLOW_("%d (0x%02x)"), resp.data.asBytes[3], resp.data.asBytes[3]); - PrintAndLogEx(INFO, " ----------------------------------------------------------"); + if (resp.length == 6) { + PrintAndLogEx(SUCCESS, ""); + PrintAndLogEx(SUCCESS, " Max number of keys : " _YELLOW_("%d"), resp.data.asBytes[1]); + PrintAndLogEx(SUCCESS, " Master key Version : " _YELLOW_("%d (0x%02x)"), resp.data.asBytes[3], resp.data.asBytes[3]); + PrintAndLogEx(INFO, " ----------------------------------------------------------"); + } + { - uint8_t data[2] = {AUTHENTICATE, 0}; // 0x0A, KEY 0 + // cla ins p1 p2 lc dd le + uint8_t data[] = {AUTHENTICATE, 0x00, 0x00, 0x01, 0x00, 0x00}; // 0x0A, KEY 0 SendCommandMIX(CMD_HF_DESFIRE_COMMAND, INIT | DISCONNECT, sizeof(data), 0, data, sizeof(data)); } @@ -216,7 +261,7 @@ void getKeySettings(uint8_t *aid) { PrintAndLogEx(SUCCESS, " [0x0A] Authenticate : %s", (isOK == 0xAE) ? "NO" : _YELLOW_("YES")); { - uint8_t data[2] = {AUTHENTICATE_ISO, 0}; // 0x1A, KEY 0 + uint8_t data[] = {AUTHENTICATE_ISO, 0x00, 0x00, 0x01, 0x00, 0x00}; // 0x1A, KEY 0 SendCommandMIX(CMD_HF_DESFIRE_COMMAND, INIT | DISCONNECT, sizeof(data), 0, data, sizeof(data)); } @@ -225,7 +270,7 @@ void getKeySettings(uint8_t *aid) { PrintAndLogEx(SUCCESS, " [0x1A] Authenticate ISO : %s", (isOK == 0xAE) ? "NO" : _YELLOW_("YES")); { - uint8_t data[2] = {AUTHENTICATE_AES, 0}; // 0xAA, KEY 0 + uint8_t data[] = {AUTHENTICATE_AES, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00}; // 0xAA, KEY 0 SendCommandMIX(CMD_HF_DESFIRE_COMMAND, INIT | DISCONNECT, sizeof(data), 0, data, sizeof(data)); } @@ -235,15 +280,20 @@ void getKeySettings(uint8_t *aid) { PrintAndLogEx(INFO, "-------------------------------------------------------------"); } else { + + // AID - APPLICATIO MASTER KEYS + PrintAndLogEx(SUCCESS, " AMK - Application Master Key settings"); PrintAndLogEx(INFO, " ----------------------------------------------------------"); + PrintAndLogEx(INFO, "Selecting AID: %s", sprint_hex(aid, 3) ); // SELECT AID { - uint8_t data[4] = {SELECT_APPLICATION}; // 0x5a + uint8_t data[] = {SELECT_APPLICATION, 0x00, 0x00, 0x00}; // 0x5a memcpy(data + 1, aid, 3); SendCommandMIX(CMD_HF_DESFIRE_COMMAND, INIT | CLEARTRACE, sizeof(data), 0, data, sizeof(data)); } + if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { PrintAndLogEx(WARNING, _RED_(" Timed-out")); return; @@ -256,7 +306,7 @@ void getKeySettings(uint8_t *aid) { // KEY SETTINGS { - uint8_t data[1] = {GET_KEY_SETTINGS}; // 0x45 + uint8_t data[] = {GET_KEY_SETTINGS, 0x00, 0x00, 0x00}; // 0x45 SendCommandMIX(CMD_HF_DESFIRE_COMMAND, NONE, sizeof(data), 0, data, sizeof(data)); } @@ -299,7 +349,7 @@ void getKeySettings(uint8_t *aid) { // KEY VERSION - AMK { - uint8_t data[2] = {GET_KEY_VERSION, 0}; // 0x64 + uint8_t data[] = {GET_KEY_VERSION, 0x00, 0x00, 0x00}; // 0x64 SendCommandMIX(CMD_HF_DESFIRE_COMMAND, NONE, sizeof(data), 0, data, sizeof(data)); } @@ -541,7 +591,6 @@ static int CmdHF14ADesAuth(const char *Cmd) { return PM3_SUCCESS; } - static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, {"info", CmdHF14ADesInfo, IfPm3Iso14443a, "Tag information"}, From 1cb495e40b479ed88d5bec4d7a3ff7f3f9fa5c2a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 17 Mar 2020 01:50:27 +0100 Subject: [PATCH 1714/1854] add desfire light signature verification check --- armsrc/mifaredesfire.c | 1 + client/cmdhfmfdes.c | 70 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 69 insertions(+), 2 deletions(-) diff --git a/armsrc/mifaredesfire.c b/armsrc/mifaredesfire.c index cd47b5ca9..3a3d0007c 100644 --- a/armsrc/mifaredesfire.c +++ b/armsrc/mifaredesfire.c @@ -32,6 +32,7 @@ static uint8_t deselect_cmd[] = {0xc2, 0xe0, 0xb4}; /* PCB CID CMD PAYLOAD */ //static uint8_t __res[MAX_FRAME_SIZE]; + bool InitDesfireCard() { iso14a_card_select_t card; diff --git a/client/cmdhfmfdes.c b/client/cmdhfmfdes.c index d9790726d..7d6a6162c 100644 --- a/client/cmdhfmfdes.c +++ b/client/cmdhfmfdes.c @@ -17,6 +17,8 @@ #include "ui.h" #include "cmdhf14a.h" #include "mbedtls/des.h" +#include "crypto/libpcrypto.h" +#include "protocols.h" uint8_t key_zero_data[16] = { 0x00 }; uint8_t key_ones_data[16] = { 0x01 }; @@ -25,6 +27,63 @@ uint8_t key_picc_data[16] = { 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x static int CmdHelp(const char *Cmd); +static int desfire_print_signature(uint8_t *uid, uint8_t *signature, size_t signature_len) { + #define PUBLIC_DESFIRE_ECDA_KEYLEN 57 + + // ref: MIFARE Desfire Originality Signature Validation + uint8_t nxp_desfire_keys[1][PUBLIC_DESFIRE_ECDA_KEYLEN] = { + // DESFire Light + { + 0x04, 0x0E, 0x98, 0xE1, 0x17, 0xAA, 0xA3, 0x64, + 0x57, 0xF4, 0x31, 0x73, 0xDC, 0x92, 0x0A, 0x87, + 0x57, 0x26, 0x7F, 0x44, 0xCE, 0x4E, 0xC5, 0xAD, + 0xD3, 0xC5, 0x40, 0x75, 0x57, 0x1A, 0xEB, 0xBF, + 0x7B, 0x94, 0x2A, 0x97, 0x74, 0xA1, 0xD9, 0x4A, + 0xD0, 0x25, 0x72, 0x42, 0x7E, 0x5A, 0xE0, 0xA2, + 0xDD, 0x36, 0x59, 0x1B, 0x1F, 0xB3, 0x4F, 0xCF, 0x3D + } + // DESFire Ev2 + + }; + + uint8_t public_key = 0; + int res = ecdsa_signature_r_s_verify(MBEDTLS_ECP_DP_SECP224R1, nxp_desfire_keys[public_key], uid, 7, signature, signature_len, false); + bool is_valid = (res == 0); + + PrintAndLogEx(INFO, " Tag Signature"); + PrintAndLogEx(INFO, " IC signature public key name : NXP ???"); + PrintAndLogEx(INFO, " IC signature public key value : %s", sprint_hex(nxp_desfire_keys[public_key], 16)); + PrintAndLogEx(INFO, " : %s", sprint_hex(nxp_desfire_keys[public_key] + 16, 16)); + PrintAndLogEx(INFO, " : %s", sprint_hex(nxp_desfire_keys[public_key] + 32, 16)); + PrintAndLogEx(INFO, " : %s", sprint_hex(nxp_desfire_keys[public_key] + 48, PUBLIC_DESFIRE_ECDA_KEYLEN - 48)); + PrintAndLogEx(INFO, " Elliptic curve parameters : NID_secp224r1"); + PrintAndLogEx(INFO, " TAG IC Signature : %s", sprint_hex(signature, 16)); + PrintAndLogEx(INFO, " : %s", sprint_hex(signature + 16, 16)); + PrintAndLogEx(INFO, " : %s", sprint_hex(signature + 32, 16)); + PrintAndLogEx(INFO, " : %s", sprint_hex(signature + 48, signature_len - 48)); + PrintAndLogEx( (is_valid) ? SUCCESS : WARNING, " Signature verified %s", (is_valid) ? _GREEN_("successful") : _RED_("failed")); + PrintAndLogEx(INFO, "-------------------------------------------------------------"); + return PM3_SUCCESS; +} +static int get_desfire_signature(uint8_t *signature, size_t *signature_len) { + + PacketResponseNG resp; + + uint8_t c[] = {MFDES_READSIG, 0x00, 0x00, 0x01, 0x00, 0x00}; // 0x3C + SendCommandMIX(CMD_HF_DESFIRE_COMMAND, (INIT | DISCONNECT), sizeof(c), 0, c, sizeof(c)); + if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) + return PM3_ETIMEOUT; + + if (resp.length == 61) { + memcpy(signature, resp.data.asBytes + 1, 56); + *signature_len = 56; + return PM3_SUCCESS; + } else { + *signature_len = 0; + return PM3_ESOFT; + } +} + static int CmdHF14ADesInfo(const char *Cmd) { (void)Cmd; // Cmd is not used so far @@ -87,6 +146,13 @@ static int CmdHF14ADesInfo(const char *Cmd) { PrintAndLogEx(SUCCESS, " Protocol : %s", getProtocolStr(package->versionSW[6])); PrintAndLogEx(INFO, "-------------------------------------------------------------"); + // Signature originality check + uint8_t signature[56] = {0}; + size_t signature_len = 0; + + if (get_desfire_signature(signature, &signature_len) == PM3_SUCCESS) + desfire_print_signature(package->uid, signature, signature_len); + // Master Key settings getKeySettings(NULL); @@ -96,6 +162,7 @@ static int CmdHF14ADesInfo(const char *Cmd) { if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) return PM3_ETIMEOUT; + PrintAndLogEx(INFO, " Free memory"); // Desfire Light doesn't support FREEMEM (len = 5) if (resp.length == 8) { uint8_t tmp[3]; @@ -119,7 +186,6 @@ static int CmdHF14ADesInfo(const char *Cmd) { keys 12,13,14,15 R */ - return PM3_SUCCESS; } @@ -186,7 +252,7 @@ void getKeySettings(uint8_t *aid) { // CARD MASTER KEY - PrintAndLogEx(SUCCESS, " CMK - PICC, Card Master Key settings"); + PrintAndLogEx(INFO, " CMK - PICC, Card Master Key settings"); PrintAndLogEx(INFO, "-------------------------------------------------------------"); { uint8_t data[] = {GET_KEY_SETTINGS, 0x00, 0x00, 0x00}; // 0x45 From 5f29601947d6f4869c1dcac2f82788ab7182c705 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 17 Mar 2020 01:50:45 +0100 Subject: [PATCH 1715/1854] add desfire light signature verification check --- include/protocols.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/protocols.h b/include/protocols.h index de38e1aea..519172af6 100644 --- a/include/protocols.h +++ b/include/protocols.h @@ -385,6 +385,7 @@ ISO 7816-4 Basic interindustry commands. For command APDU's. #define MFDES_CHANGE_KEY 0xc4 #define MFDES_GET_KEY_VERSION 0x64 #define MFDES_AUTHENTICATION_FRAME 0xAF +#define MFDES_READSIG 0x3C // LEGIC Commands #define LEGIC_MIM_22 0x0D From 6d7682fdb3e3adb2011d0d3407e16546607fb623 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marlin=20S=C3=B6=C3=B6se?= <30473690+msoose@users.noreply.github.com> Date: Mon, 16 Mar 2020 21:04:46 -0400 Subject: [PATCH 1716/1854] Update mfc_default_keys.dic --- client/dictionaries/mfc_default_keys.dic | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index 1e26f948b..405f0d6f0 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -1101,4 +1101,7 @@ c554ef6a6015 b8937130b6ba d7744a1a0c44 82908b57ef4f -fe04ecfe5577 \ No newline at end of file +fe04ecfe5577 +# comfort inn hotel +4d57414c5648 +4d48414c5648 From 8cf88c5cd51ddf3cd25ade6b7dfebd6a6af989b3 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 17 Mar 2020 02:30:25 +0100 Subject: [PATCH 1717/1854] hf mfdes info - textual --- client/cmdhfmfdes.c | 52 +++++++++++++++++---------------------------- 1 file changed, 19 insertions(+), 33 deletions(-) diff --git a/client/cmdhfmfdes.c b/client/cmdhfmfdes.c index 7d6a6162c..2479270fa 100644 --- a/client/cmdhfmfdes.c +++ b/client/cmdhfmfdes.c @@ -269,39 +269,25 @@ void getKeySettings(uint8_t *aid) { if (resp.length == 7 ) { // number of Master keys (0x01) - PrintAndLogEx(SUCCESS, " [0x08] Number of Masterkeys : %u", resp.data.asBytes[2]); - uint8_t setting = (resp.data.asBytes[2] >> 6); - switch(setting) { - case 0: - PrintAndLogEx(SUCCESS, " [00] (3)DES operation of PICC master key"); - break; - case 1: - PrintAndLogEx(SUCCESS, " [01] 3K3DES operation of PICC master key"); - break; - case 2: - PrintAndLogEx(SUCCESS, " [02] AES operation of PICC master key"); - break; - default: - break; - } - - str = (resp.data.asBytes[2] & (1 << 3)) ? _GREEN_("YES") : "NO"; + PrintAndLogEx(SUCCESS, " Number of Masterkeys : " _YELLOW_("%u"), resp.data.asBytes[2]); + + str = (resp.data.asBytes[1] & (1 << 3)) ? _GREEN_("YES") : "NO"; PrintAndLogEx(SUCCESS, " [0x08] Configuration changeable : %s", str); - str = (resp.data.asBytes[2] & (1 << 2)) ? "NO" : _GREEN_("YES"); + + str = (resp.data.asBytes[1] & (1 << 2)) ? _GREEN_("YES") : "NO"; PrintAndLogEx(SUCCESS, " [0x04] CMK required for create/delete : %s", str); - str = (resp.data.asBytes[2] & (1 << 1)) ? "NO" : _GREEN_("YES"); + + str = (resp.data.asBytes[1] & (1 << 1)) ? _GREEN_("YES") : "NO"; PrintAndLogEx(SUCCESS, " [0x02] Directory list access with CMK : %s", str); - str = (resp.data.asBytes[2] & (1 << 0)) ? _GREEN_("YES") : "NO"; + + str = (resp.data.asBytes[1] & (1 << 0)) ? _GREEN_("YES") : "NO"; PrintAndLogEx(SUCCESS, " [0x01] CMK is changeable : %s", str); } - // dd == key version - // cla ins p1 p2 lc dd le - { // 90, 64, - uint8_t data[] = {GET_KEY_VERSION, 0x00, 0x00, 0x01, 0x00, 0x00}; // 0x64 + { + uint8_t data[] = {GET_KEY_VERSION, 0x00, 0x00, 0x01, 0x0, 0x00}; // 0x64 SendCommandMIX(CMD_HF_DESFIRE_COMMAND, INIT | DISCONNECT, sizeof(data), 0, data, sizeof(data)); } - if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)) { return; } isOK = resp.oldarg[0] & 0xff; if (!isOK) { @@ -310,21 +296,18 @@ void getKeySettings(uint8_t *aid) { } if (resp.length == 6) { PrintAndLogEx(SUCCESS, ""); - PrintAndLogEx(SUCCESS, " Max number of keys : " _YELLOW_("%d"), resp.data.asBytes[1]); PrintAndLogEx(SUCCESS, " Master key Version : " _YELLOW_("%d (0x%02x)"), resp.data.asBytes[3], resp.data.asBytes[3]); PrintAndLogEx(INFO, " ----------------------------------------------------------"); } - { - // cla ins p1 p2 lc dd le uint8_t data[] = {AUTHENTICATE, 0x00, 0x00, 0x01, 0x00, 0x00}; // 0x0A, KEY 0 SendCommandMIX(CMD_HF_DESFIRE_COMMAND, INIT | DISCONNECT, sizeof(data), 0, data, sizeof(data)); } - if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)) {return;} isOK = resp.data.asBytes[2] & 0xff; - PrintAndLogEx(SUCCESS, " [0x0A] Authenticate : %s", (isOK == 0xAE) ? "NO" : _YELLOW_("YES")); + if (resp.length == 13) + PrintAndLogEx(SUCCESS, " [0x0A] Authenticate : %s", (isOK == 0xAE) ? "NO" : _YELLOW_("YES")); { uint8_t data[] = {AUTHENTICATE_ISO, 0x00, 0x00, 0x01, 0x00, 0x00}; // 0x1A, KEY 0 @@ -333,16 +316,19 @@ void getKeySettings(uint8_t *aid) { if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)) {return;} isOK = resp.data.asBytes[2] & 0xff; - PrintAndLogEx(SUCCESS, " [0x1A] Authenticate ISO : %s", (isOK == 0xAE) ? "NO" : _YELLOW_("YES")); + if (resp.length >= 13) + PrintAndLogEx(SUCCESS, " [0x1A] Authenticate ISO : %s", (isOK == 0xAE) ? "NO" : _YELLOW_("YES")); { - uint8_t data[] = {AUTHENTICATE_AES, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00}; // 0xAA, KEY 0 + uint8_t data[] = {AUTHENTICATE_AES, 0x00, 0x00, 0x01, 0x00, 0x00}; // 0xAA, KEY 0 SendCommandMIX(CMD_HF_DESFIRE_COMMAND, INIT | DISCONNECT, sizeof(data), 0, data, sizeof(data)); } if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)) {return;} isOK = resp.data.asBytes[2] & 0xff; - PrintAndLogEx(SUCCESS, " [0xAA] Authenticate AES : %s", (isOK == 0xAE) ? "NO" : _YELLOW_("YES")); + if (resp.length == 13) + PrintAndLogEx(SUCCESS, " [0xAA] Authenticate AES : %s", (isOK == 0xAE) ? "NO" : _YELLOW_("YES")); + PrintAndLogEx(INFO, "-------------------------------------------------------------"); } else { From fe0d9c8d9faf3d467b214dbc747242006bf1f6bf Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 17 Mar 2020 11:37:38 +0100 Subject: [PATCH 1718/1854] hf mfdes enum - fixes WIP --- armsrc/mifaredesfire.c | 41 ++++++++------------- client/cmdhfmfdes.c | 82 +++++++++++++++++++++--------------------- client/cmdhfmfdes.h | 10 ------ include/mifare.h | 10 ++++++ 4 files changed, 65 insertions(+), 78 deletions(-) diff --git a/armsrc/mifaredesfire.c b/armsrc/mifaredesfire.c index 3a3d0007c..06a3f3f8c 100644 --- a/armsrc/mifaredesfire.c +++ b/armsrc/mifaredesfire.c @@ -15,6 +15,7 @@ #include "mbedtls/aes.h" #include "commonutil.h" #include "util.h" +#include "mifare.h" #define MAX_APPLICATION_COUNT 28 #define MAX_FILE_COUNT 16 @@ -35,6 +36,8 @@ static uint8_t deselect_cmd[] = {0xc2, 0xe0, 0xb4}; bool InitDesfireCard() { + pcb_blocknum = 0; + iso14a_card_select_t card; iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); @@ -48,28 +51,14 @@ bool InitDesfireCard() { return true; } -// ARG0 flag enums -enum { - NONE = 0x00, - INIT = 0x01, - DISCONNECT = 0x02, - CLEARTRACE = 0x04, - BAR = 0x08, -} CmdOptions ; - void MifareSendCommand(uint8_t arg0, uint8_t arg1, uint8_t *datain) { - /* ARG0 contains flags. - 0x01 = init card. - 0x02 = Disconnect - 0x03 - */ uint8_t flags = arg0; size_t datalen = arg1; uint8_t resp[RECEIVE_SIZE]; memset(resp, 0, sizeof(resp)); - if (DBGLEVEL >= 4) { + if (DBGLEVEL >= DBG_EXTENDED) { Dbprintf(" flags : %02X", flags); Dbprintf(" len : %02X", datalen); print_result(" RX : ", datain, datalen); @@ -79,12 +68,13 @@ void MifareSendCommand(uint8_t arg0, uint8_t arg1, uint8_t *datain) { clear_trace(); if (flags & INIT) { - if (!InitDesfireCard()) + if (!InitDesfireCard()) { return; + } } int len = DesfireAPDU(datain, datalen, resp); - if (DBGLEVEL >= 4) + if (DBGLEVEL >= DBG_EXTENDED) print_result("RESP <--: ", resp, len); if (!len) { @@ -92,9 +82,6 @@ void MifareSendCommand(uint8_t arg0, uint8_t arg1, uint8_t *datain) { return; } - // reset the pcb_blocknum, - pcb_blocknum = 0; - if (flags & DISCONNECT) OnSuccess(); @@ -482,7 +469,7 @@ void MifareDES_Auth1(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) // dekryptera tagnonce. if (mbedtls_aes_setkey_dec(&ctx, key->data, 128) != 0) { - if (DBGLEVEL >= 4) { + if (DBGLEVEL >= DBG_EXTENDED) { DbpString("mbedtls_aes_setkey_dec failed"); } OnError(7); @@ -495,7 +482,7 @@ void MifareDES_Auth1(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) memcpy(both + 16, decRndB, 16); uint8_t encBoth[32] = {0x00}; if (mbedtls_aes_setkey_enc(&ctx, key->data, 128) != 0) { - if (DBGLEVEL >= 4) { + if (DBGLEVEL >= DBG_EXTENDED) { DbpString("mbedtls_aes_setkey_enc failed"); } OnError(7); @@ -549,23 +536,23 @@ int DesfireAPDU(uint8_t *cmd, size_t cmd_len, uint8_t *dataout) { wrappedLen = CreateAPDU(cmd, cmd_len, wCmd); - if (DBGLEVEL >= 4) + if (DBGLEVEL >= DBG_EXTENDED) print_result("WCMD <--: ", wCmd, wrappedLen); ReaderTransmit(wCmd, wrappedLen, NULL); len = ReaderReceive(resp, par); if (!len) { - if (DBGLEVEL >= 4) Dbprintf("fukked"); + if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("fukked"); return false; //DATA LINK ERROR } // if we received an I- or R(ACK)-Block with a block number equal to the // current block number, toggle the current block number - else if (len >= 4 // PCB+CID+CRC = 4 bytes + if (len >= 4 // PCB+CID+CRC = 4 bytes && ((resp[0] & 0xC0) == 0 // I-Block || (resp[0] & 0xD0) == 0x80) // R-Block with ACK bit set to 0 && (resp[0] & 0x01) == pcb_blocknum) { // equal block numbers - pcb_blocknum ^= 1; //toggle next block + pcb_blocknum ^= 1; //toggle next block } memcpy(dataout, resp, len); @@ -583,6 +570,8 @@ size_t CreateAPDU(uint8_t *datain, size_t len, uint8_t *dataout) { cmd[0] = 0x02; // 0x0A = send cid, 0x02 = no cid. cmd[0] |= pcb_blocknum; // OR the block number into the PCB + if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("pcb_blocknum %d == %d ", pcb_blocknum, cmd[0] ); + cmd[1] = 0x90; // CID: 0x00 //TODO: allow multiple selected cards memcpy(cmd + 2, datain, len); diff --git a/client/cmdhfmfdes.c b/client/cmdhfmfdes.c index 2479270fa..1aade35fb 100644 --- a/client/cmdhfmfdes.c +++ b/client/cmdhfmfdes.c @@ -19,6 +19,7 @@ #include "mbedtls/des.h" #include "crypto/libpcrypto.h" #include "protocols.h" +#include "mifare.h" // desfire raw command options uint8_t key_zero_data[16] = { 0x00 }; uint8_t key_ones_data[16] = { 0x01 }; @@ -299,54 +300,49 @@ void getKeySettings(uint8_t *aid) { PrintAndLogEx(SUCCESS, " Master key Version : " _YELLOW_("%d (0x%02x)"), resp.data.asBytes[3], resp.data.asBytes[3]); PrintAndLogEx(INFO, " ----------------------------------------------------------"); } - + { + // 0x0A uint8_t data[] = {AUTHENTICATE, 0x00, 0x00, 0x01, 0x00, 0x00}; // 0x0A, KEY 0 SendCommandMIX(CMD_HF_DESFIRE_COMMAND, INIT | DISCONNECT, sizeof(data), 0, data, sizeof(data)); } if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)) {return;} - isOK = resp.data.asBytes[2] & 0xff; - if (resp.length == 13) - PrintAndLogEx(SUCCESS, " [0x0A] Authenticate : %s", (isOK == 0xAE) ? "NO" : _YELLOW_("YES")); + PrintAndLogEx(SUCCESS, " [0x0A] Authenticate : %s", (resp.length == 13) ? _YELLOW_("YES") : "NO"); { + // 0x1A uint8_t data[] = {AUTHENTICATE_ISO, 0x00, 0x00, 0x01, 0x00, 0x00}; // 0x1A, KEY 0 SendCommandMIX(CMD_HF_DESFIRE_COMMAND, INIT | DISCONNECT, sizeof(data), 0, data, sizeof(data)); } - if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)) {return;} - isOK = resp.data.asBytes[2] & 0xff; - if (resp.length >= 13) - PrintAndLogEx(SUCCESS, " [0x1A] Authenticate ISO : %s", (isOK == 0xAE) ? "NO" : _YELLOW_("YES")); + PrintAndLogEx(SUCCESS, " [0x1A] Authenticate ISO : %s", (resp.length >= 13) ? _YELLOW_("YES") : "NO"); { + // 0xAA uint8_t data[] = {AUTHENTICATE_AES, 0x00, 0x00, 0x01, 0x00, 0x00}; // 0xAA, KEY 0 SendCommandMIX(CMD_HF_DESFIRE_COMMAND, INIT | DISCONNECT, sizeof(data), 0, data, sizeof(data)); } - if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)) {return;} - isOK = resp.data.asBytes[2] & 0xff; - if (resp.length == 13) - PrintAndLogEx(SUCCESS, " [0xAA] Authenticate AES : %s", (isOK == 0xAE) ? "NO" : _YELLOW_("YES")); + PrintAndLogEx(SUCCESS, " [0xAA] Authenticate AES : %s", (resp.length >= 13) ? _YELLOW_("YES") : "NO"); PrintAndLogEx(INFO, "-------------------------------------------------------------"); } else { - // AID - APPLICATIO MASTER KEYS + // AID - APPLICATION MASTER KEYS PrintAndLogEx(SUCCESS, " AMK - Application Master Key settings"); - PrintAndLogEx(INFO, " ----------------------------------------------------------"); - PrintAndLogEx(INFO, "Selecting AID: %s", sprint_hex(aid, 3) ); + PrintAndLogEx(INFO, " ----------------------------------------------------------"); + PrintAndLogEx(INFO, " select AID: " _YELLOW_("%s"), sprint_hex(aid, 3) ); // SELECT AID { - uint8_t data[] = {SELECT_APPLICATION, 0x00, 0x00, 0x00}; // 0x5a - memcpy(data + 1, aid, 3); - SendCommandMIX(CMD_HF_DESFIRE_COMMAND, INIT | CLEARTRACE, sizeof(data), 0, data, sizeof(data)); + uint8_t data[] = {SELECT_APPLICATION, 0x00, 0x00, 0x03, aid[0], aid[1], aid[2], 0x00}; // 0x5a + //memcpy(data + 1, aid, 3); + SendCommandMIX(CMD_HF_DESFIRE_COMMAND, INIT, sizeof(data), 0, data, sizeof(data)); } - if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { + if (!WaitForResponseTimeout(CMD_ACK, &resp, 3000)) { PrintAndLogEx(WARNING, _RED_(" Timed-out")); return; } @@ -362,7 +358,7 @@ void getKeySettings(uint8_t *aid) { SendCommandMIX(CMD_HF_DESFIRE_COMMAND, NONE, sizeof(data), 0, data, sizeof(data)); } - if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { + if (!WaitForResponseTimeout(CMD_ACK, &resp, 3000)) { return; } isOK = resp.oldarg[0] & 0xff; @@ -370,15 +366,15 @@ void getKeySettings(uint8_t *aid) { PrintAndLogEx(WARNING, _RED_(" Can't read Application Master key settings")); } else { // Access rights. - uint8_t rights = (resp.data.asBytes[3] >> 4 & 0xff); + uint8_t rights = (resp.data.asBytes[1] >> 4 & 0x0F); switch (rights) { - case 0x00: + case 0x0: str = "AMK authentication is necessary to change any key (default)"; break; - case 0x0e: + case 0xE: str = "Authentication with the key to be changed (same KeyNo) is necessary to change a key"; break; - case 0x0f: + case 0xF: str = "All keys (except AMK,see Bit0) within this application are frozen"; break; default: @@ -389,20 +385,20 @@ void getKeySettings(uint8_t *aid) { PrintAndLogEx(SUCCESS, "-- " _GREEN_("%s"), str); PrintAndLogEx(SUCCESS, ""); // same as CMK - str = (resp.data.asBytes[3] & (1 << 3)) ? "YES" : "NO"; + str = (resp.data.asBytes[1] & (1 << 3)) ? "YES" : "NO"; PrintAndLogEx(SUCCESS, " 0x08 Configuration changeable : %s", str); - str = (resp.data.asBytes[3] & (1 << 2)) ? "NO" : "YES"; + str = (resp.data.asBytes[1] & (1 << 2)) ? "NO" : "YES"; PrintAndLogEx(SUCCESS, " 0x04 AMK required for create/delete : %s", str); - str = (resp.data.asBytes[3] & (1 << 1)) ? "NO" : "YES"; + str = (resp.data.asBytes[1] & (1 << 1)) ? "NO" : "YES"; PrintAndLogEx(SUCCESS, " 0x02 Directory list access with AMK : %s", str); - str = (resp.data.asBytes[3] & (1 << 0)) ? "YES" : "NO"; + str = (resp.data.asBytes[1] & (1 << 0)) ? "YES" : "NO"; PrintAndLogEx(SUCCESS, " 0x01 AMK is changeable : %s", str); } // KEY VERSION - AMK { - uint8_t data[] = {GET_KEY_VERSION, 0x00, 0x00, 0x00}; // 0x64 - SendCommandMIX(CMD_HF_DESFIRE_COMMAND, NONE, sizeof(data), 0, data, sizeof(data)); + uint8_t data[] = {GET_KEY_VERSION, 0x00, 0x00, 0x01, 0x00, 0x00}; // 0x64 + SendCommandMIX(CMD_HF_DESFIRE_COMMAND, DISCONNECT, sizeof(data), 0, data, sizeof(data)); } if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { @@ -439,8 +435,8 @@ static int CmdHF14ADesEnumApplications(const char *Cmd) { uint8_t isOK = 0x00; uint8_t aid[3]; { - uint8_t data[1] = {GET_APPLICATION_IDS}; //0x6a - SendCommandMIX(CMD_HF_DESFIRE_COMMAND, INIT | DISCONNECT, sizeof(data), 0, data, sizeof(data)); + uint8_t data[] = {GET_APPLICATION_IDS, 0x00, 0x00, 0x00}; //0x6a + SendCommandMIX(CMD_HF_DESFIRE_COMMAND, INIT | CLEARTRACE | DISCONNECT, sizeof(data), 0, data, sizeof(data)); } PacketResponseNG resp; @@ -454,17 +450,18 @@ static int CmdHF14ADesEnumApplications(const char *Cmd) { return PM3_ESOFT; } PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(SUCCESS, "-- Desfire Enumerate Applications ---------------------------"); + PrintAndLogEx(INFO, "-- Desfire Enumerate Applications ---------------------------"); PrintAndLogEx(INFO, "-------------------------------------------------------------"); - PacketResponseNG respAid; - PacketResponseNG respFiles; +// PacketResponseNG respAid; +// PacketResponseNG respFiles; uint8_t num = 0; int max = resp.oldarg[1] - 3 - 2; + PrintAndLogEx(INFO," MAX %d", max); - for (int i = 3; i <= max; i += 3) { - PrintAndLogEx(SUCCESS, " Aid %d : %02X %02X %02X ", num, resp.data.asBytes[i], resp.data.asBytes[i + 1], resp.data.asBytes[i + 2]); + for (int i = 1; i < max; i += 3) { + PrintAndLogEx(SUCCESS, " Aid %d : %02X %02X %02X ", num, resp.data.asBytes[i], resp.data.asBytes[i+1], resp.data.asBytes[i+2]); num++; aid[0] = resp.data.asBytes[i]; @@ -472,11 +469,11 @@ static int CmdHF14ADesEnumApplications(const char *Cmd) { aid[2] = resp.data.asBytes[i + 2]; getKeySettings(aid); +/* // Select Application { - uint8_t data[4] = {SELECT_APPLICATION}; // 0x5a - memcpy(data + 1, &resp.data.asBytes[i], 3); - SendCommandMIX(CMD_HF_DESFIRE_COMMAND, INIT, sizeof(data), 0, data, sizeof(data)); + uint8_t data[] = {SELECT_APPLICATION, 0x00, 0x00, 0x03, aid[0], aid[1], aid[2], 0x00}; // 0x5a + SendCommandMIX(CMD_HF_DESFIRE_COMMAND, NONE, sizeof(data), 0, data, sizeof(data)); } if (!WaitForResponseTimeout(CMD_ACK, &respAid, 1500)) { @@ -491,7 +488,7 @@ static int CmdHF14ADesEnumApplications(const char *Cmd) { // Get File IDs { - uint8_t data[1] = {GET_FILE_IDS}; // 0x6f + uint8_t data[] = {GET_FILE_IDS, 0x00, 0x00, 0x00}; // 0x6f SendCommandMIX(CMD_HF_DESFIRE_COMMAND, NONE, sizeof(data), 0, data, sizeof(data)); } @@ -512,7 +509,7 @@ static int CmdHF14ADesEnumApplications(const char *Cmd) { // Get ISO File IDs { - uint8_t data[1] = {GET_ISOFILE_IDS}; // 0x61 + uint8_t data[] = {GET_ISOFILE_IDS, 0x00, 0x00, 0x00}; // 0x61 SendCommandMIX(CMD_HF_DESFIRE_COMMAND, DISCONNECT, sizeof(data), 0, data, sizeof(data)); } @@ -530,6 +527,7 @@ static int CmdHF14ADesEnumApplications(const char *Cmd) { } } } + */ } PrintAndLogEx(INFO, "-------------------------------------------------------------"); return PM3_SUCCESS; diff --git a/client/cmdhfmfdes.h b/client/cmdhfmfdes.h index 3a19f6d83..5c4dcb5e2 100644 --- a/client/cmdhfmfdes.h +++ b/client/cmdhfmfdes.h @@ -19,16 +19,6 @@ char *getProtocolStr(uint8_t id); char *getVersionStr(uint8_t major, uint8_t minor); void getKeySettings(uint8_t *aid); -// Command options for Desfire behavior. -enum { - NONE = 0x00, - INIT = 0x01, - DISCONNECT = 0x02, - CLEARTRACE = 0x04, - BAR = 0x08, -} CmdOptions ; - - #define CREATE_APPLICATION 0xca #define DELETE_APPLICATION 0xda #define GET_APPLICATION_IDS 0x6a diff --git a/include/mifare.h b/include/mifare.h index 63b14c117..b8df9a2ec 100644 --- a/include/mifare.h +++ b/include/mifare.h @@ -70,6 +70,16 @@ typedef struct { uint32_t ProxToAirDuration; uint8_t par; // enough for precalculated parity of 8 Byte responses } PACKED tag_response_info_t; + +// DESFIRE_RAW flag enums +typedef enum DESFIRE_COMMAND { + NONE = 0x00, + INIT = 0x01, + DISCONNECT = 0x02, + CLEARTRACE = 0x04, + BAR = 0x10, +} desfire_command_t; + //----------------------------------------------------------------------------- // ISO 14443B //----------------------------------------------------------------------------- From 9ff3ed2933d5d7927790e0d87275566be86c3ed4 Mon Sep 17 00:00:00 2001 From: Winds <60715874+Windslab@users.noreply.github.com> Date: Tue, 17 Mar 2020 13:37:38 +0300 Subject: [PATCH 1719/1854] Create hf-writer.lua --- client/luascripts/hf-writer.lua | 124 ++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 client/luascripts/hf-writer.lua diff --git a/client/luascripts/hf-writer.lua b/client/luascripts/hf-writer.lua new file mode 100644 index 000000000..512a17f2e --- /dev/null +++ b/client/luascripts/hf-writer.lua @@ -0,0 +1,124 @@ +local utils = require('utils') +local read14a = require('read14a') +local uid = {} -- Array for eml files +local B = {} -- Array for B keys +local eml = {} -- Array for data in block 32 dig +local a = 0 +local b = 0 +local tab = string.rep('-', 64) + +local function read() + u = read14a.read(true, true).uid + return u +end + +local function fkey() + f = 'FFFFFFFFFFFF' + return f +end + +local function finish() + read14a.disconnect() + core.clearCommandBuffer() +end + +local function wait() read14a.waitFor14443a() end + +wait() + +print(tab) + +if string.len(read()) == 14 then -- Detect 7 byte card + l = 29 -- 7 byte length of eml file + s = 7 + e = 20 +else + l = 23 -- 4 byte length of eml file + s = 7 + e = 14 +end + +for _ in io.popen([[dir ".\" /b]]):lines() do -- for UNIX: ls + if string.find(_, '%.eml$') then + if string.len(_) == l then -- There length of eml file + a = a + 1 + uid[a] = string.sub(tostring(_), s, e) -- Cut UID from eml file + print(' ' .. a .. ' ' .. '|' .. ' ' .. uid[a]) + end + end +end + +print(tab) +print(' Your card has ' .. read() .. ' UID number\n') +print(' Choice your dump number to write (from 1 until ' .. a .. ')') +print(tab) +io.write(' --> ') + +local no = tonumber(io.read()) +local dump = io.open('./hf-mf-' .. uid[no] .. '-data.eml', 'r'); + +print(tab) +print(' You have been selected ' .. no .. ' card dump, it UID is ' .. uid[no]) + +for _ in dump:lines() do table.insert(eml, _); end +for i = 1, #eml do + if (i % 4 == 0) then + repeat + b = b + 1 + B[b] = string.sub(tostring(eml[i]), (string.len(eml[i]) - 11), + string.len(eml[i])) -- Cut key from block + until b % 4 == 0 + end +end + +print(tab) + +if (utils.confirm(' Do the UID changing?') == true) then + wait() + core.console('hf 14a raw -s -c -t 2000 90f0cccc10' .. tostring(eml[1])) + print(tab) + print(' The new card UID is: ' .. read()) +end + +print(tab) + +if (utils.confirm(' Would you like to BLOCK the UID for any changing?') == true) then + wait() + core.console('hf 14a raw -s -c -t 2000 90fd111100') +end + +print(tab) + +if (utils.confirm(' At this case are you using a Blank Card?') == true) then + wait() + for i = 1, #eml do + core.console('hf mf wrbl ' .. (i - 1) .. ' B ' .. fkey() .. ' ' .. + tostring(eml[i])) + end + print(tab) +else + print(tab) + if (utils.confirm( + ' Do you wishing DELETE ALL DATA and rewrite all keys to ' .. fkey() .. + '?') == true) then + wait() + for i = 1, #eml do + if (i % 4 == 0) then + core.console( + 'hf mf wrbl ' .. (i - 1) .. ' B ' .. tostring(B[i]) .. ' ' .. + fkey() .. '78778800' .. fkey()) + else + core.console( + 'hf mf wrbl ' .. (i - 1) .. ' B ' .. tostring(B[i]) .. ' ' .. + string.rep('0', 32)) + end + end + else + wait() + for i = 1, #eml do + core.console('hf mf wrbl ' .. (i - 1) .. ' B ' .. tostring(B[i]) .. + ' ' .. tostring(eml[i])) + end + end +end +finish() From e9b293e8e9a06bd0bb74f632df90483953936b4f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 17 Mar 2020 13:38:51 +0100 Subject: [PATCH 1720/1854] hf mfp info - textual / colours --- client/cmdhfmfp.c | 43 ++++++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/client/cmdhfmfp.c b/client/cmdhfmfp.c index 9c7b9cb3c..a5619756d 100644 --- a/client/cmdhfmfp.c +++ b/client/cmdhfmfp.c @@ -39,6 +39,10 @@ static int CmdHFMFPInfo(const char *Cmd) { if (Cmd && strlen(Cmd) > 0) PrintAndLogEx(WARNING, "command don't have any parameters.\n"); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "-- Mifare Plus Tag Information ------------------------------"); + PrintAndLogEx(INFO, "-------------------------------------------------------------"); + // info about 14a part infoHF14A(false, false, false); @@ -54,57 +58,62 @@ static int CmdHFMFPInfo(const char *Cmd) { uint64_t select_status = resp.oldarg[0]; // 0: couldn't read, 1: OK, with ATS, 2: OK, no ATS, 3: proprietary Anticollision if (select_status == 1 || select_status == 2) { - PrintAndLogEx(NORMAL, "----------------------------------------------"); - PrintAndLogEx(NORMAL, "Mifare Plus info:"); + PrintAndLogEx(INFO, "-------------------------------------------------------------"); + PrintAndLogEx(INFO, " Fingerprint"); + // MIFARE Type Identification Procedure // https://www.nxp.com/docs/en/application-note/AN10833.pdf uint16_t ATQA = card.atqa[0] + (card.atqa[1] << 8); - if (ATQA == 0x0004) PrintAndLogEx(INFO, "ATQA: Mifare Plus 2k 4bUID"); - if (ATQA == 0x0002) PrintAndLogEx(INFO, "ATQA: Mifare Plus 4k 4bUID"); - if (ATQA == 0x0044) PrintAndLogEx(INFO, "ATQA: Mifare Plus 2k 7bUID"); - if (ATQA == 0x0042) PrintAndLogEx(INFO, "ATQA: Mifare Plus 4k 7bUID"); + if (ATQA == 0x0004) PrintAndLogEx(INFO, " ATQA - " _GREEN_("Mifare Plus 2K") " (4b UID)"); + if (ATQA == 0x0002) PrintAndLogEx(INFO, " ATQA - " _GREEN_("Mifare Plus 4K") " (4b UID)"); + if (ATQA == 0x0044) PrintAndLogEx(INFO, " ATQA - " _GREEN_("Mifare Plus 2K") " (7b UID)"); + if (ATQA == 0x0042) PrintAndLogEx(INFO, " ATQA - " _GREEN_("Mifare Plus 4K") " (7b UID)"); uint8_t SLmode = 0xff; if (card.sak == 0x08) { - PrintAndLogEx(INFO, "SAK: Mifare Plus 2k 7bUID"); + PrintAndLogEx(INFO, " SAK - " _GREEN_("Mifare Plus 2K 7b UID")); if (select_status == 2) SLmode = 1; } if (card.sak == 0x18) { - PrintAndLogEx(INFO, "SAK: Mifare Plus 4k 7bUID"); + PrintAndLogEx(INFO, " SAK - " _GREEN_("Mifare Plus 4K 7b UID")); if (select_status == 2) SLmode = 1; } if (card.sak == 0x10) { - PrintAndLogEx(INFO, "SAK: Mifare Plus 2k"); + PrintAndLogEx(INFO, " SAK - " _GREEN_("Mifare Plus 2K")); if (select_status == 2) SLmode = 2; } if (card.sak == 0x11) { - PrintAndLogEx(INFO, "SAK: Mifare Plus 4k"); + PrintAndLogEx(INFO, " SAK - " _GREEN_("Mifare Plus 4K")); if (select_status == 2) SLmode = 2; } if (card.sak == 0x20) { - PrintAndLogEx(INFO, "SAK: Mifare Plus SL0/SL3 or Mifare desfire"); - if (card.ats_len > 0) { - SLmode = 3; + PrintAndLogEx(INFO, " SAK - " _GREEN_("Mifare Plus SL0/SL3") "or " _GREEN_("Mifare DESFire")); + if (card.ats_len > 0) { + + PrintAndLogEx(INFO, ""); + PrintAndLogEx(INFO, " SL fingerprint"); + SLmode = 3; // check SL0 uint8_t data[250] = {0}; int datalen = 0; // https://github.com/Proxmark/proxmark3/blob/master/client/luascripts/mifarePlus.lua#L161 uint8_t cmd[3 + 16] = {0xa8, 0x90, 0x90, 0x00}; int res = ExchangeRAW14a(cmd, sizeof(cmd), false, false, data, sizeof(data), &datalen, false); + if (!res && datalen > 1 && data[0] == 0x09) { SLmode = 0; } } } - if (SLmode != 0xff) - PrintAndLogEx(INFO, "Mifare Plus SL mode: SL%d", SLmode); + if (SLmode != 0xFF) + PrintAndLogEx(SUCCESS, "\tMifare Plus SL mode: " _YELLOW_("SL%d"), SLmode); else - PrintAndLogEx(WARNING, "Mifare Plus SL mode: unknown("); + PrintAndLogEx(WARNING, "\tMifare Plus SL mode: " _YELLOW_("unknown")); } else { - PrintAndLogEx(INFO, "Mifare Plus info not available."); + PrintAndLogEx(INFO, "\tMifare Plus info not available."); } DropField(); From 53d00dc7c35080d778d93e9c4e82f01a2759ca7b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 17 Mar 2020 13:40:28 +0100 Subject: [PATCH 1721/1854] whitespace --- client/cmdhfmfu.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index 5c70f37cd..51d13ce53 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -895,12 +895,12 @@ static int ulev1_print_signature(TagTypeUL_t tagtype, uint8_t *uid, uint8_t *sig int res = ecdsa_signature_r_s_verify(MBEDTLS_ECP_DP_SECP128R1, public_keys[public_key], uid, 7, signature, signature_len, false); bool is_valid = (res == 0); - PrintAndLogEx(NORMAL, "\n--- Tag Signature"); - PrintAndLogEx(NORMAL, "IC signature public key name : NXP NTAG21x (2013)"); - PrintAndLogEx(NORMAL, "IC signature public key value : %s", sprint_hex(public_keys[public_key], PUBLIC_ECDA_KEYLEN)); - PrintAndLogEx(NORMAL, " Elliptic curve parameters : NID_secp128r1"); - PrintAndLogEx(NORMAL, " TAG IC Signature : %s", sprint_hex(signature, signature_len)); - PrintAndLogEx(NORMAL, "Signature verified %s", (is_valid) ? _GREEN_("successful") : _RED_("failed")); + PrintAndLogEx(INFO, "\n--- Tag Signature"); + PrintAndLogEx(INFO, "IC signature public key name : NXP NTAG21x (2013)"); + PrintAndLogEx(INFO, "IC signature public key value : %s", sprint_hex(public_keys[public_key], PUBLIC_ECDA_KEYLEN)); + PrintAndLogEx(INFO, " Elliptic curve parameters : NID_secp128r1"); + PrintAndLogEx(INFO, " TAG IC Signature : %s", sprint_hex(signature, signature_len)); + PrintAndLogEx(SUCCESS, "Signature verified %s", (is_valid) ? _GREEN_("successful") : _RED_("failed")); return PM3_SUCCESS; } From 6783986fca514a3153dc51e71d2e6bf19d514f27 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 17 Mar 2020 13:41:46 +0100 Subject: [PATCH 1722/1854] hf mfdes info - textual --- client/cmdhfmfdes.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/client/cmdhfmfdes.c b/client/cmdhfmfdes.c index 1aade35fb..b921b0914 100644 --- a/client/cmdhfmfdes.c +++ b/client/cmdhfmfdes.c @@ -52,7 +52,7 @@ static int desfire_print_signature(uint8_t *uid, uint8_t *signature, size_t sign bool is_valid = (res == 0); PrintAndLogEx(INFO, " Tag Signature"); - PrintAndLogEx(INFO, " IC signature public key name : NXP ???"); + PrintAndLogEx(INFO, " IC signature public key name : NXP DESFire Light"); PrintAndLogEx(INFO, " IC signature public key value : %s", sprint_hex(nxp_desfire_keys[public_key], 16)); PrintAndLogEx(INFO, " : %s", sprint_hex(nxp_desfire_keys[public_key] + 16, 16)); PrintAndLogEx(INFO, " : %s", sprint_hex(nxp_desfire_keys[public_key] + 32, 16)); @@ -124,7 +124,7 @@ static int CmdHF14ADesInfo(const char *Cmd) { } PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(INFO, "-- Desfire Information --------------------------------------"); + PrintAndLogEx(INFO, "-- Mifare DESFire Tag Information ---------------------------"); PrintAndLogEx(INFO, "-------------------------------------------------------------"); PrintAndLogEx(SUCCESS, " UID : " _GREEN_("%s"), sprint_hex(package->uid, sizeof(package->uid))); PrintAndLogEx(SUCCESS, " Batch number : " _GREEN_("%s"), sprint_hex(package->details + 7, 5)); @@ -413,7 +413,7 @@ void getKeySettings(uint8_t *aid) { PrintAndLogEx(WARNING, " Can't read Application Master key version. Trying all keys"); //numOfKeys = MAX_NUM_KEYS; } else { - numOfKeys = resp.data.asBytes[4]; + numOfKeys = resp.data.asBytes[1]; PrintAndLogEx(SUCCESS, " Max number of keys : %d", numOfKeys); PrintAndLogEx(SUCCESS, " Application Master key Version : %d (0x%02x)", resp.data.asBytes[3], resp.data.asBytes[3]); PrintAndLogEx(INFO, "-------------------------------------------------------------"); @@ -533,6 +533,7 @@ static int CmdHF14ADesEnumApplications(const char *Cmd) { return PM3_SUCCESS; } + // MIAFRE DesFire Authentication // #define BUFSIZE 256 From eab2ebafaeb137caac7db9b1c2f05611aedd557b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 17 Mar 2020 17:12:27 +0100 Subject: [PATCH 1723/1854] added pwdgen test --- client/cmdhfmfu.c | 22 +--------------------- common/generator.c | 33 +++++++++++++++++++++++---------- pm3test.sh | 4 +++- 3 files changed, 27 insertions(+), 32 deletions(-) diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index 51d13ce53..c1cd5d31a 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -296,26 +296,6 @@ uint8_t UL_MEMORY_ARRAY[ARRAYLEN(UL_TYPES_ARRAY)] = { MAX_ULEV1a_BLOCKS, MAX_NTAG_213, MAX_NTAG_216, MAX_UL_NANO_40, MAX_NTAG_I2C_1K }; -static int ul_ev1_pwdgen_selftest() { - - uint8_t uid1[] = {0x04, 0x11, 0x12, 0x11, 0x12, 0x11, 0x10}; - uint32_t pwd1 = ul_ev1_pwdgenA(uid1); - PrintAndLogEx(NORMAL, "UID | %s | %08X | %s", sprint_hex(uid1, 7), pwd1, (pwd1 == 0x8432EB17) ? "OK" : "->8432EB17<-"); - - uint8_t uid2[] = {0x04, 0x1f, 0x98, 0xea, 0x1e, 0x3e, 0x81}; - uint32_t pwd2 = ul_ev1_pwdgenB(uid2); - PrintAndLogEx(NORMAL, "UID | %s | %08X | %s", sprint_hex(uid2, 7), pwd2, (pwd2 == 0x5fd37eca) ? "OK" : "->5fd37eca<--"); - - uint8_t uid3[] = {0x04, 0x62, 0xB6, 0x8A, 0xB4, 0x42, 0x80}; - uint32_t pwd3 = ul_ev1_pwdgenC(uid3); - PrintAndLogEx(NORMAL, "UID | %s | %08X | %s", sprint_hex(uid3, 7), pwd3, (pwd3 == 0x5a349515) ? "OK" : "->5a349515<--"); - - uint8_t uid4[] = {0x04, 0xC5, 0xDF, 0x4A, 0x6D, 0x51, 0x80}; - uint32_t pwd4 = ul_ev1_pwdgenD(uid4); - PrintAndLogEx(NORMAL, "UID | %s | %08X | %s", sprint_hex(uid4, 7), pwd4, (pwd4 == 0x72B1EC61) ? "OK" : "->72B1EC61<--"); - return PM3_SUCCESS; -} - //------------------------------------ // get version nxp product type static char *getProductTypeStr(uint8_t id) { @@ -2578,7 +2558,7 @@ static int CmdHF14AMfUPwdGen(const char *Cmd) { char cmdp = tolower(param_getchar(Cmd, 0)); if (strlen(Cmd) == 0 || cmdp == 'h') return usage_hf_mfu_pwdgen(); - if (cmdp == 't') return ul_ev1_pwdgen_selftest(); + if (cmdp == 't') return generator_selftest(); if (cmdp == 'r') { // read uid from tag diff --git a/common/generator.c b/common/generator.c index 4be63a925..fa1fd7cd3 100644 --- a/common/generator.c +++ b/common/generator.c @@ -418,43 +418,56 @@ int mfc_algo_sky_all(uint8_t *uid, uint8_t *keys) { //------------------------------------ int generator_selftest() { - PrintAndLogEx(SUCCESS, "Generators selftest"); - PrintAndLogEx(SUCCESS, "-------------------"); +#define NUM_OF_TEST 5 - bool success; + PrintAndLogEx(INFO, "PWD / KEY generator selftest"); + PrintAndLogEx(INFO, "----------------------------"); + + bool success = false; + uint8_t testresult = 0; uint8_t uid1[] = {0x04, 0x11, 0x12, 0x11, 0x12, 0x11, 0x10}; uint32_t pwd1 = ul_ev1_pwdgenA(uid1); success = (pwd1 == 0x8432EB17); - PrintAndLogEx(success ? SUCCESS : WARNING, "UID | %s | %08X | %s", sprint_hex(uid1, 7), pwd1, success ? "OK" : "->8432EB17<-"); + if (success) + testresult++; + PrintAndLogEx(success ? SUCCESS : WARNING, "UID | %s | %08X - %s", sprint_hex(uid1, 7), pwd1, success ? "OK" : "->8432EB17<-"); uint8_t uid2[] = {0x04, 0x1f, 0x98, 0xea, 0x1e, 0x3e, 0x81}; uint32_t pwd2 = ul_ev1_pwdgenB(uid2); success = (pwd2 == 0x5fd37eca); - PrintAndLogEx(success ? SUCCESS : WARNING, "UID | %s | %08X | %s", sprint_hex(uid2, 7), pwd2, success ? "OK" : "->5fd37eca<--"); + if (success) + testresult++; + PrintAndLogEx(success ? SUCCESS : WARNING, "UID | %s | %08X - %s", sprint_hex(uid2, 7), pwd2, success ? "OK" : "->5fd37eca<--"); uint8_t uid3[] = {0x04, 0x62, 0xB6, 0x8A, 0xB4, 0x42, 0x80}; uint32_t pwd3 = ul_ev1_pwdgenC(uid3); success = (pwd3 == 0x5a349515); - PrintAndLogEx(success ? SUCCESS : WARNING, "UID | %s | %08X | %s", sprint_hex(uid3, 7), pwd3, success ? "OK" : "->5a349515<--"); + if (success) + testresult++; + PrintAndLogEx(success ? SUCCESS : WARNING, "UID | %s | %08X - %s", sprint_hex(uid3, 7), pwd3, success ? "OK" : "->5a349515<--"); uint8_t uid4[] = {0x04, 0xC5, 0xDF, 0x4A, 0x6D, 0x51, 0x80}; uint32_t pwd4 = ul_ev1_pwdgenD(uid4); success = (pwd4 == 0x72B1EC61); - PrintAndLogEx(success ? SUCCESS : WARNING, "UID | %s | %08X | %s", sprint_hex(uid4, 7), pwd4, success ? "OK" : "->72B1EC61<--"); + if (success) + testresult++; + PrintAndLogEx(success ? SUCCESS : WARNING, "UID | %s | %08X - %s", sprint_hex(uid4, 7), pwd4, success ? "OK" : "->72B1EC61<--"); // uint8_t uid5[] = {0x11, 0x22, 0x33, 0x44}; // uint64_t key1 = mfc_algo_a(uid5); // success = (key1 == 0xD1E2AA68E39A); -// PrintAndLogEx(success ? SUCCESS : WARNING, "UID | %s | %"PRIx64" | %s", sprint_hex(uid5, 4), key1, success ? "OK" : "->D1E2AA68E39A<--"); +// PrintAndLogEx(success ? SUCCESS : WARNING, "UID | %s | %"PRIx64" - %s", sprint_hex(uid5, 4), key1, success ? "OK" : "->D1E2AA68E39A<--"); uint8_t uid6[] = {0x74, 0x57, 0xCA, 0xA9}; uint64_t key6 = 0; mfc_algo_sky_one(uid6, 15, 0, &key6); success = (key6 == 0x82c7e64bc565); - PrintAndLogEx(success ? SUCCESS : WARNING, "UID | %s | %"PRIx64" | %s", sprint_hex(uid6, 4), key6, success ? "OK" : "->82C7E64BC565<--"); + if (success) + testresult++; + PrintAndLogEx(success ? SUCCESS : WARNING, "UID | %s | %"PRIx64" - %s", sprint_hex(uid6, 4), key6, success ? "OK" : "->82C7E64BC565<--"); - PrintAndLogEx(SUCCESS, "-------------------"); + PrintAndLogEx(SUCCESS, "------------------- Selftest %s", (testresult == NUM_OF_TEST) ? "OK" : "fail"); return PM3_SUCCESS; } diff --git a/pm3test.sh b/pm3test.sh index 6a2256192..11b459ab4 100755 --- a/pm3test.sh +++ b/pm3test.sh @@ -95,7 +95,8 @@ while true; do printf "\n${C_BLUE}Testing data manipulation:${C_NC}\n" if ! CheckExecute "reveng test" "./client/proxmark3 -c 'reveng -w 8 -s 01020304e3 010204039d'" "CRC-8/SMBUS"; then break; fi - + if ! CheckExecute "mfu pwdgen test" "./client/proxmark3 -c 'hf mfu pwdgen t'" "Selftest OK"; then break; fi + printf "\n${C_BLUE}Testing LF:${C_NC}\n" if ! CheckExecute "lf em4x05 test" "./client/proxmark3 -c 'data load traces/em4x05.pm3;lf search'" "FDX-B ID found"; then break; fi @@ -120,6 +121,7 @@ while true; do if ! CheckExecute "findbits test" "tools/findbits.py 73 0110010101110011" "Match at bit 9: 011001010"; then break; fi if ! CheckExecute "findbits_test test" "tools/findbits_test.py 2>&1" "OK"; then break; fi if ! CheckExecute "pm3_eml_mfd test" "tools/pm3_eml_mfd_test.py 2>&1" "OK"; then break; fi + printf "\n${C_GREEN}Tests [OK]${C_NC}\n\n" exit 0 done From 6b30e1ab0076c2fabd7c9ad2e3a53c2ccc80a219 Mon Sep 17 00:00:00 2001 From: Winds <60715874+Windslab@users.noreply.github.com> Date: Wed, 18 Mar 2020 13:39:10 +0300 Subject: [PATCH 1724/1854] Update hf-writer.lua Adapted your script to the coding standards --- client/luascripts/hf-writer.lua | 211 ++++++++++++++++++-------------- 1 file changed, 122 insertions(+), 89 deletions(-) diff --git a/client/luascripts/hf-writer.lua b/client/luascripts/hf-writer.lua index 512a17f2e..0c15dff56 100644 --- a/client/luascripts/hf-writer.lua +++ b/client/luascripts/hf-writer.lua @@ -7,6 +7,28 @@ local a = 0 local b = 0 local tab = string.rep('-', 64) +copyright = '' +author = 'Winds' +version = 'v1.0.0' +desc = [[ + That's script gives for you a easy way to write your an *.eml dumps, using a Proxmark 3. + It's working for 4 and 7 bytes NXP MIFARE Classic 1K cards. + The script has including an injection of UID changig for the Chinese Magic Cards GEN 3. + + Whith choosen an *.eml file you can do: + + 1. Write it to the equals of current card UID. + 2. Write it to anther card with changable UID. + 3. Send command to lock UID for the Chinese Magic Cards GEN 3. + 4. Erease all data at the card and set the FFFFFFFFFFFF keys, and Access Conditions to 78778800. +]] +example = [[ + 1. script run hf-writer +]] +usage = [[ + You should choose your *.eml dump from being list to write it to the card by wizard +]] + local function read() u = read14a.read(true, true).uid return u @@ -22,103 +44,114 @@ local function finish() core.clearCommandBuffer() end -local function wait() read14a.waitFor14443a() end - -wait() - -print(tab) - -if string.len(read()) == 14 then -- Detect 7 byte card - l = 29 -- 7 byte length of eml file - s = 7 - e = 20 -else - l = 23 -- 4 byte length of eml file - s = 7 - e = 14 +local function wait() + read14a.waitFor14443a() end -for _ in io.popen([[dir ".\" /b]]):lines() do -- for UNIX: ls - if string.find(_, '%.eml$') then - if string.len(_) == l then -- There length of eml file - a = a + 1 - uid[a] = string.sub(tostring(_), s, e) -- Cut UID from eml file - print(' ' .. a .. ' ' .. '|' .. ' ' .. uid[a]) - end - end -end - -print(tab) -print(' Your card has ' .. read() .. ' UID number\n') -print(' Choice your dump number to write (from 1 until ' .. a .. ')') -print(tab) -io.write(' --> ') - -local no = tonumber(io.read()) -local dump = io.open('./hf-mf-' .. uid[no] .. '-data.eml', 'r'); - -print(tab) -print(' You have been selected ' .. no .. ' card dump, it UID is ' .. uid[no]) - -for _ in dump:lines() do table.insert(eml, _); end -for i = 1, #eml do - if (i % 4 == 0) then - repeat - b = b + 1 - B[b] = string.sub(tostring(eml[i]), (string.len(eml[i]) - 11), - string.len(eml[i])) -- Cut key from block - until b % 4 == 0 - end -end - -print(tab) - -if (utils.confirm(' Do the UID changing?') == true) then +local function main(args) + --File lienght check for detect 4 or 7 bytes wait() - core.console('hf 14a raw -s -c -t 2000 90f0cccc10' .. tostring(eml[1])) print(tab) - print(' The new card UID is: ' .. read()) -end - -print(tab) - -if (utils.confirm(' Would you like to BLOCK the UID for any changing?') == true) then - wait() - core.console('hf 14a raw -s -c -t 2000 90fd111100') -end - -print(tab) - -if (utils.confirm(' At this case are you using a Blank Card?') == true) then - wait() - for i = 1, #eml do - core.console('hf mf wrbl ' .. (i - 1) .. ' B ' .. fkey() .. ' ' .. - tostring(eml[i])) - end - print(tab) -else - print(tab) - if (utils.confirm( - ' Do you wishing DELETE ALL DATA and rewrite all keys to ' .. fkey() .. - '?') == true) then - wait() - for i = 1, #eml do - if (i % 4 == 0) then - core.console( - 'hf mf wrbl ' .. (i - 1) .. ' B ' .. tostring(B[i]) .. ' ' .. - fkey() .. '78778800' .. fkey()) - else - core.console( - 'hf mf wrbl ' .. (i - 1) .. ' B ' .. tostring(B[i]) .. ' ' .. - string.rep('0', 32)) + if string.len(read()) == 14 then -- Detect 7 byte card + l = 29 -- 7 byte length of eml file + s = 7 + e = 20 + else + l = 23 -- 4 byte length of eml file + s = 7 + e = 14 + end + ---Listern EML files at Client catalog + for _ in io.popen([[dir ".\" /b]]):lines() do -- for UNIX: ls + if string.find(_, '%.eml$') then + if string.len(_) == l then -- There length of eml file + a = a + 1 + uid[a] = string.sub(tostring(_), s, e) -- Cut UID from eml file + print(' ' .. a .. ' ' .. '|' .. ' ' .. uid[a]) end end - else + end + + print(tab) + print(' Your card has ' .. read() .. ' UID number\n') + print(' Choice your dump number to write (from 1 until ' .. a .. ')') + print(tab) + io.write(' --> ') + + local no = tonumber(io.read()) + local dump = io.open('./hf-mf-' .. uid[no] .. '-data.eml', 'r'); + + print(tab) + print(' You have been selected ' .. no .. ' card dump, it UID is ' .. uid[no]) + ---EML get B key from opened EML file + for _ in dump:lines() do table.insert(eml, _); end + for i = 1, #eml do + if (i % 4 == 0) then + repeat + b = b + 1 + B[b] = string.sub(tostring(eml[i]), (string.len(eml[i]) - 11), + string.len(eml[i])) -- Cut key from block + until b % 4 == 0 + end + end + + print(tab) + ---UID Changing + if (utils.confirm(' Do the UID changing?') == true) then + wait() + core.console('hf 14a raw -s -c -t 2000 90f0cccc10' .. tostring(eml[1])) + print(tab) + print(' The new card UID is: ' .. read()) + end + + print(tab) + ---UID Blocking + if (utils.confirm(' Would you like to BLOCK the UID for any changing?') == true) then + wait() + core.console('hf 14a raw -s -c -t 2000 90fd111100') + end + + print(tab) + ---Wriiting block + if (utils.confirm(' At this case are you using a Blank Card?') == true) then wait() for i = 1, #eml do - core.console('hf mf wrbl ' .. (i - 1) .. ' B ' .. tostring(B[i]) .. - ' ' .. tostring(eml[i])) + core.console('hf mf wrbl ' .. (i - 1) .. ' B ' .. fkey() .. ' ' .. + tostring(eml[i])) + end + print(tab) + else + print(tab) + if (utils.confirm( + ' Do you wishing DELETE ALL DATA and rewrite all keys to ' .. fkey() .. + '?') == true) then + wait() + for i = 1, #eml do + if (i % 4 == 0) then + core.console( + 'hf mf wrbl ' .. (i - 1) .. ' B ' .. tostring(B[i]) .. ' ' .. + fkey() .. '78778800' .. fkey()) + else + core.console( + 'hf mf wrbl ' .. (i - 1) .. ' B ' .. tostring(B[i]) .. ' ' .. + string.rep('0', 32)) + end + end + else + wait() + for i = 1, #eml do + core.console('hf mf wrbl ' .. (i - 1) .. ' B ' .. tostring(B[i]) .. + ' ' .. tostring(eml[i])) + end end end + finish() end -finish() +main(args) + +---General thinks for the future: +---Add support another types of dumps: BIN, JSON +---Maybe it will be not only as `hf-writer`, like a universal dump manager. +---Add undependence from the operation system. At the moment code not working in Linux. +---Add more chinesse backdoors RAW commands for UID changing (find RAW for the 4 byte familiar chinese card, from native it soft: http://bit.ly/39VIDsU) +---Hide system messages when you writing a dumps, replace it to some of like [#####----------] 40% From 3947528996d75a50d6836e9720fb1119579569d6 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 19 Mar 2020 05:44:47 +0100 Subject: [PATCH 1725/1854] optional color for serial text in prompt --- client/proxmark3.c | 14 +++++++++----- client/proxmark3.h | 8 ++++++++ 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/client/proxmark3.c b/client/proxmark3.c index 3217d0583..5a6ae23a9 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -58,7 +58,11 @@ static void showBanner(void) { static int check_comm(void) { // If communications thread goes down. Device disconnected then this should hook up PM3 again. if (IsCommunicationThreadDead() && session.pm3_present) { - rl_set_prompt(PROXPROMPT_OFFLINE); + if (session.supports_colors) + rl_set_prompt(PROXPROMPT_OFFLINE_COLOR); + else + rl_set_prompt(PROXPROMPT_OFFLINE); + rl_forced_update_display(); CloseProxmark(); PrintAndLogEx(INFO, "Running in " _YELLOW_("OFFLINE") "mode. Use "_YELLOW_("\"hw connect\"") "to reconnect\n"); @@ -150,7 +154,7 @@ main_loop(char *script_cmds_file, char *script_cmd, bool stayInCommandLoop) { // loops every time enter is pressed... while (1) { bool printprompt = false; - const char *prompt = PROXPROMPT_CON; + const char *prompt = (session.supports_colors) ? PROXPROMPT_CON_COLOR : PROXPROMPT_CON; check_script: // If there is a script file @@ -214,11 +218,11 @@ check_script: rl_event_hook = check_comm; if (session.pm3_present) { if (conn.send_via_fpc_usart == false) - prompt = PROXPROMPT_USB; + prompt = (session.supports_colors) ? PROXPROMPT_USB_COLOR : PROXPROMPT_USB; else - prompt = PROXPROMPT_FPC; + prompt = (session.supports_colors) ? PROXPROMPT_FPC_COLOR : PROXPROMPT_FPC; } else { - prompt = PROXPROMPT_OFFLINE; + prompt = (session.supports_colors) ? PROXPROMPT_OFFLINE_COLOR : PROXPROMPT_OFFLINE; } cmd = readline(prompt); fflush(NULL); diff --git a/client/proxmark3.h b/client/proxmark3.h index d3e3629ec..107e64859 100644 --- a/client/proxmark3.h +++ b/client/proxmark3.h @@ -15,9 +15,17 @@ #include "common.h" #define PROXPROMPT_CON "[con] pm3 --> " +#define PROXPROMPT_CON_COLOR "[\001\033[1;32m\002con\001\033[0m\002] pm3 --> " + #define PROXPROMPT_USB "[usb] pm3 --> " +#define PROXPROMPT_USB_COLOR "[\001\033[1;32m\002usb\001\033[0m\002] pm3 --> " + #define PROXPROMPT_FPC "[fpc] pm3 --> " +#define PROXPROMPT_FPC_COLOR "[\001\033[1;32m\002fpc\001\033[0m\002] pm3 --> " + #define PROXPROMPT_OFFLINE "[offline] pm3 --> " +#define PROXPROMPT_OFFLINE_COLOR "[\001\033[1;31m\002offline\001\033[0m\002] pm3 --> " + #define PROXHISTORY "history.txt" #define PROXLOG "log_%Y%m%d.txt" #define MAX_NESTED_CMDSCRIPT 10 From 37011158e1dbc302a40e0bab2ec641617c301201 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 19 Mar 2020 09:26:56 +0100 Subject: [PATCH 1726/1854] chg: hf mfp info - more text / better detection between DESFire and Plus --- client/cmdhfmfp.c | 85 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 63 insertions(+), 22 deletions(-) diff --git a/client/cmdhfmfp.c b/client/cmdhfmfp.c index a5619756d..641e959a1 100644 --- a/client/cmdhfmfp.c +++ b/client/cmdhfmfp.c @@ -65,35 +65,51 @@ static int CmdHFMFPInfo(const char *Cmd) { // MIFARE Type Identification Procedure // https://www.nxp.com/docs/en/application-note/AN10833.pdf uint16_t ATQA = card.atqa[0] + (card.atqa[1] << 8); - if (ATQA == 0x0004) PrintAndLogEx(INFO, " ATQA - " _GREEN_("Mifare Plus 2K") " (4b UID)"); - if (ATQA == 0x0002) PrintAndLogEx(INFO, " ATQA - " _GREEN_("Mifare Plus 4K") " (4b UID)"); - if (ATQA == 0x0044) PrintAndLogEx(INFO, " ATQA - " _GREEN_("Mifare Plus 2K") " (7b UID)"); - if (ATQA == 0x0042) PrintAndLogEx(INFO, " ATQA - " _GREEN_("Mifare Plus 4K") " (7b UID)"); + + bool isPlus = false; + + if (ATQA == 0x0004) { + PrintAndLogEx(INFO, " ATQA - " _GREEN_("Mifare Plus 2K") " (4b UID)"); + isPlus = true; + } + if (ATQA == 0x0002) { + PrintAndLogEx(INFO, " ATQA - " _GREEN_("Mifare Plus 4K") " (4b UID)"); + isPlus = true; + } + if (ATQA == 0x0044) { + PrintAndLogEx(INFO, " ATQA - " _GREEN_("Mifare Plus 2K") " (7b UID)"); + isPlus = true; + } + if (ATQA == 0x0042) { + PrintAndLogEx(INFO, " ATQA - " _GREEN_("Mifare Plus 4K") " (7b UID)"); + isPlus = true; + } uint8_t SLmode = 0xff; - if (card.sak == 0x08) { - PrintAndLogEx(INFO, " SAK - " _GREEN_("Mifare Plus 2K 7b UID")); - if (select_status == 2) SLmode = 1; - } - if (card.sak == 0x18) { - PrintAndLogEx(INFO, " SAK - " _GREEN_("Mifare Plus 4K 7b UID")); - if (select_status == 2) SLmode = 1; - } - if (card.sak == 0x10) { - PrintAndLogEx(INFO, " SAK - " _GREEN_("Mifare Plus 2K")); - if (select_status == 2) SLmode = 2; - } - if (card.sak == 0x11) { - PrintAndLogEx(INFO, " SAK - " _GREEN_("Mifare Plus 4K")); - if (select_status == 2) SLmode = 2; + if (isPlus) { + if (card.sak == 0x08) { + PrintAndLogEx(INFO, " SAK - " _GREEN_("Mifare Plus 2K 7b UID")); + if (select_status == 2) SLmode = 1; + } + if (card.sak == 0x18) { + PrintAndLogEx(INFO, " SAK - " _GREEN_("Mifare Plus 4K 7b UID")); + if (select_status == 2) SLmode = 1; + } + if (card.sak == 0x10) { + PrintAndLogEx(INFO, " SAK - " _GREEN_("Mifare Plus 2K")); + if (select_status == 2) SLmode = 2; + } + if (card.sak == 0x11) { + PrintAndLogEx(INFO, " SAK - " _GREEN_("Mifare Plus 4K")); + if (select_status == 2) SLmode = 2; + } } + if (card.sak == 0x20) { PrintAndLogEx(INFO, " SAK - " _GREEN_("Mifare Plus SL0/SL3") "or " _GREEN_("Mifare DESFire")); if (card.ats_len > 0) { - PrintAndLogEx(INFO, ""); - PrintAndLogEx(INFO, " SL fingerprint"); SLmode = 3; // check SL0 uint8_t data[250] = {0}; @@ -102,12 +118,38 @@ static int CmdHFMFPInfo(const char *Cmd) { uint8_t cmd[3 + 16] = {0xa8, 0x90, 0x90, 0x00}; int res = ExchangeRAW14a(cmd, sizeof(cmd), false, false, data, sizeof(data), &datalen, false); + if (memcmp(data, "\x67\x00", 2) == 0) { + PrintAndLogEx(INFO, "\tMost likely a Mifare DESFire tag"); + PrintAndLogEx(HINT, "Hint: Try " _YELLOW_("`hf mfdes info`")); + DropField(); + return PM3_SUCCESS; + } + if (!res && datalen > 1 && data[0] == 0x09) { SLmode = 0; } } } +// How do we detect SL0 / SL1 / SL2 / SL3 modes?!? + PrintAndLogEx(INFO, "Security Level (SL)"); + switch(SLmode) { + case 0: + PrintAndLogEx(INFO, "SL 0: initial delivery configuration, used for card personalization"); + break; + case 1: + PrintAndLogEx(INFO, "SL 1: backwards functional compatibility mode (with MIFARE Classic 1K and MIFARE Classic 4K) with an optional AES authentication"); + break; + case 2: + PrintAndLogEx(INFO, "SL 2: "); + break; + case 3: + PrintAndLogEx(INFO, "SL 3: 3-Pass authentication based on AES, data manipulation commands secured by AES encryption and an AES based MACing method."); + break; + default: + break; + } + if (SLmode != 0xFF) PrintAndLogEx(SUCCESS, "\tMifare Plus SL mode: " _YELLOW_("SL%d"), SLmode); else @@ -117,7 +159,6 @@ static int CmdHFMFPInfo(const char *Cmd) { } DropField(); - return PM3_SUCCESS; } From 4bbe0827f5d743824a6f10584b63a005b0bd49c7 Mon Sep 17 00:00:00 2001 From: Winds <60715874+Windslab@users.noreply.github.com> Date: Thu, 19 Mar 2020 12:29:39 +0300 Subject: [PATCH 1727/1854] Update hf-writer.lua Add the possibility for a -h helptext param --- client/luascripts/hf-writer.lua | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/client/luascripts/hf-writer.lua b/client/luascripts/hf-writer.lua index 0c15dff56..8c5740af6 100644 --- a/client/luascripts/hf-writer.lua +++ b/client/luascripts/hf-writer.lua @@ -1,4 +1,5 @@ local utils = require('utils') +local getopt = require('getopt') local read14a = require('read14a') local uid = {} -- Array for eml files local B = {} -- Array for B keys @@ -29,6 +30,17 @@ usage = [[ You should choose your *.eml dump from being list to write it to the card by wizard ]] +--- +-- Usage help +local function help() + print(copyright) + print(author) + print(version) + print(desc) + print(example) + print(usage) +end + local function read() u = read14a.read(true, true).uid return u @@ -49,6 +61,11 @@ local function wait() end local function main(args) + -- Arguments for the script + for o, a in getopt.getopt(args, 'h') do + if o == 'h' then return help() end + end + --File lienght check for detect 4 or 7 bytes wait() print(tab) From 7a1c65d1af5009244920d5213177da387a4c80e8 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 19 Mar 2020 12:05:29 +0100 Subject: [PATCH 1728/1854] chg: hf mfdes info - refactored a bit. \nchg: hf mfdes enum - now works again --- client/cmdhfmfdes.c | 626 ++++++++++++++++++++++++++++---------------- 1 file changed, 401 insertions(+), 225 deletions(-) diff --git a/client/cmdhfmfdes.c b/client/cmdhfmfdes.c index b921b0914..5ab35a12d 100644 --- a/client/cmdhfmfdes.c +++ b/client/cmdhfmfdes.c @@ -28,6 +28,73 @@ uint8_t key_picc_data[16] = { 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x static int CmdHelp(const char *Cmd); +//ICEMAN: Turn on field method? +//none +static int test_desfire_authenticate() { + uint8_t c[] = {AUTHENTICATE, 0x00, 0x00, 0x01, 0x00, 0x00}; // 0x0A, KEY 0 + SendCommandMIX(CMD_HF_DESFIRE_COMMAND, NONE, sizeof(c), 0, c, sizeof(c)); + PacketResponseNG resp; + if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)) { + DropField(); + return PM3_ETIMEOUT; + } + if (resp.length == 13) + return PM3_SUCCESS; + return PM3_ESOFT; +} +// none +static int test_desfire_authenticate_iso() { + uint8_t c[] = {AUTHENTICATE_ISO, 0x00, 0x00, 0x01, 0x00, 0x00}; // 0x1A, KEY 0 + SendCommandMIX(CMD_HF_DESFIRE_COMMAND, NONE, sizeof(c), 0, c, sizeof(c)); + PacketResponseNG resp; + if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)) { + DropField(); + return PM3_ETIMEOUT; + } + if (resp.length >= 13) + return PM3_SUCCESS; + return PM3_ESOFT; +} +//none +static int test_desfire_authenticate_aes() { + uint8_t c[] = {AUTHENTICATE_AES, 0x00, 0x00, 0x01, 0x00, 0x00}; // 0xAA, KEY 0 + SendCommandMIX(CMD_HF_DESFIRE_COMMAND, NONE, sizeof(c), 0, c, sizeof(c)); + PacketResponseNG resp; + if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)) { + DropField(); + return PM3_ETIMEOUT; + } + if (resp.length >= 13) + return PM3_SUCCESS; + return PM3_ESOFT; +} + +// --- FREE MEM +static int desfire_print_freemem(uint32_t free_mem) { + PrintAndLogEx(SUCCESS, " Available free memory on card : " _GREEN_("%d bytes"), free_mem); + return PM3_SUCCESS; +} + +// init / disconnect +static int get_desfire_freemem(uint32_t *free_mem) { + uint8_t c[] = {GET_FREE_MEMORY, 0x00, 0x00, 0x00}; // 0x6E + SendCommandMIX(CMD_HF_DESFIRE_COMMAND, (INIT | DISCONNECT), sizeof(c), 0, c, sizeof(c)); + PacketResponseNG resp; + if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { + return PM3_ETIMEOUT; + } + + if (resp.length == 8) { + *free_mem = le24toh(resp.data.asBytes + 1); + return PM3_SUCCESS; + } + + *free_mem = 0; + return PM3_ESOFT; +} + + +// --- GET SIGNATURE static int desfire_print_signature(uint8_t *uid, uint8_t *signature, size_t signature_len) { #define PUBLIC_DESFIRE_ECDA_KEYLEN 57 @@ -66,12 +133,12 @@ static int desfire_print_signature(uint8_t *uid, uint8_t *signature, size_t sign PrintAndLogEx(INFO, "-------------------------------------------------------------"); return PM3_SUCCESS; } + +// init / disconnect static int get_desfire_signature(uint8_t *signature, size_t *signature_len) { - - PacketResponseNG resp; - uint8_t c[] = {MFDES_READSIG, 0x00, 0x00, 0x01, 0x00, 0x00}; // 0x3C SendCommandMIX(CMD_HF_DESFIRE_COMMAND, (INIT | DISCONNECT), sizeof(c), 0, c, sizeof(c)); + PacketResponseNG resp; if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) return PM3_ETIMEOUT; @@ -85,6 +152,190 @@ static int get_desfire_signature(uint8_t *signature, size_t *signature_len) { } } + +// --- KEY SETTING +static int desfire_print_keysetting(uint8_t key_settings, uint8_t num_keys) { + + PrintAndLogEx(SUCCESS, " AID Key settings : %02x", key_settings); + PrintAndLogEx(SUCCESS, " Max number of keys in AID : %d", num_keys); + PrintAndLogEx(INFO, "-------------------------------------------------------------"); + PrintAndLogEx(SUCCESS, " Changekey Access rights"); + + // Access rights. + uint8_t rights = (key_settings >> 4 & 0x0F); + switch (rights) { + case 0x0: + PrintAndLogEx(SUCCESS, " -- AMK authentication is necessary to change any key (default)"); + break; + case 0xE: + PrintAndLogEx(SUCCESS, " -- Authentication with the key to be changed (same KeyNo) is necessary to change a key"); + break; + case 0xF: + PrintAndLogEx(SUCCESS, " -- All keys (except AMK,see Bit0) within this application are frozen"); + break; + default: + PrintAndLogEx(SUCCESS, " -- Authentication with the specified key is necessary to change any key.\nA change key and a PICC master key (CMK) can only be changed after authentication with the master key.\nFor keys other then the master or change key, an authentication with the same key is needed."); + break; + } + + PrintAndLogEx(SUCCESS, " [0x08] Configuration changeable : %s", (key_settings & (1 << 3)) ? _GREEN_("YES") : "NO"); + PrintAndLogEx(SUCCESS, " [0x04] AMK required for create/delete : %s", (key_settings & (1 << 2)) ? "NO" : "YES"); + PrintAndLogEx(SUCCESS, " [0x02] Directory list access with AMK : %s", (key_settings & (1 << 1)) ? "NO" : "YES"); + PrintAndLogEx(SUCCESS, " [0x01] AMK is changeable : %s", (key_settings & (1 << 0)) ? _GREEN_("YES") : "NO"); + return PM3_SUCCESS; +} + +// none +static int get_desfire_keysettings(uint8_t *key_settings, uint8_t *num_keys) { + PacketResponseNG resp; + uint8_t c[] = {MFDES_GET_KEY_SETTINGS, 0x00, 0x00, 0x00}; // 0x45 + SendCommandMIX(CMD_HF_DESFIRE_COMMAND, NONE, sizeof(c), 0, c, sizeof(c)); + if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { + PrintAndLogEx(WARNING, _RED_(" Timed-out")); + return PM3_ETIMEOUT; + } + + uint8_t isOK = resp.oldarg[0] & 0xFF; + if (isOK == false) { + return PM3_ESOFT; + } + + if (resp.data.asBytes[1] == 0x91 && resp.data.asBytes[2] == 0xae) { + PrintAndLogEx(WARNING, _RED_(" authentication error")); + return PM3_ESOFT; + } +// PrintAndLogEx(INFO, "ICE: KEYSETTING resp :: %s", sprint_hex(resp.data.asBytes, resp.length)); + *key_settings = resp.data.asBytes[1]; + *num_keys = resp.data.asBytes[2]; + return PM3_SUCCESS; +} + +// --- KEY VERSION +static int desfire_print_keyversion(uint8_t key_idx, uint8_t key_version) { + PrintAndLogEx(SUCCESS, " Key [%u] Version : %d (0x%02x)", key_idx, key_version, key_version); + return PM3_SUCCESS; +} + +// none +static int get_desfire_keyversion(uint8_t curr_key, uint8_t *num_versions) { + PacketResponseNG resp; + uint8_t c[] = {MFDES_GET_KEY_VERSION, 0x00, 0x00, 0x01, curr_key, 0x00}; // 0x64 + SendCommandMIX(CMD_HF_DESFIRE_COMMAND, NONE, sizeof(c), 0, c, sizeof(c)); + if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { + PrintAndLogEx(WARNING, _RED_(" Timed-out")); + return PM3_ETIMEOUT; + } + + uint8_t isOK = resp.oldarg[0] & 0xFF; + if (isOK == false) { + return PM3_ESOFT; + } + + if ( resp.data.asBytes[1] == 0x91 && resp.data.asBytes[2] == 0x40) { + return PM3_ESOFT; + } + + *num_versions = resp.data.asBytes[1]; + return PM3_SUCCESS; +} + + +// init +static int get_desfire_select_application(uint8_t *aid) { + if (aid == NULL) return PM3_ESOFT; + + uint8_t c[] = {SELECT_APPLICATION, 0x00, 0x00, 0x03, aid[0], aid[1], aid[2], 0x00}; // 0x5a + SendCommandMIX(CMD_HF_DESFIRE_COMMAND, INIT, sizeof(c), 0, c, sizeof(c)); + + PacketResponseNG resp; + if (!WaitForResponseTimeout(CMD_ACK, &resp, 3000)) { + PrintAndLogEx(WARNING, _RED_(" timed-out")); + return PM3_ETIMEOUT; + } + + uint8_t isOK = resp.oldarg[0] & 0xff; + if (!isOK) { + PrintAndLogEx(WARNING, " Can't select AID: " _RED_("%s"), sprint_hex(aid, 3)); + return PM3_ESOFT; + } + + if (resp.data.asBytes[1] == 0x91 && resp.data.asBytes[2] == 0x00) { + return PM3_SUCCESS; + } + + return PM3_ESOFT; +} + + +// init / disconnect +static int get_desfire_appids(uint8_t *dest, uint8_t *app_ids_len) { + + uint8_t c[] = {GET_APPLICATION_IDS, 0x00, 0x00, 0x00}; //0x6a + SendCommandMIX(CMD_HF_DESFIRE_COMMAND, INIT | CLEARTRACE | DISCONNECT , sizeof(c), 0, c, sizeof(c)); + PacketResponseNG resp; + if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { + return PM3_ETIMEOUT; + } + + uint8_t isOK = resp.oldarg[0] & 0xff; + if (!isOK) { + PrintAndLogEx(WARNING, _RED_("Command unsuccessful")); + return PM3_ESOFT; + } + + *app_ids_len = resp.length - 5; + + // resp.length - 2crc, 2status, 1pcb... + memcpy(dest, resp.data.asBytes + 1, *app_ids_len); + + if (resp.data.asBytes[resp.length - 3] == MFDES_ADDITIONAL_FRAME) { + + c[0] = MFDES_ADDITIONAL_FRAME; //0xAF + SendCommandMIX(CMD_HF_DESFIRE_COMMAND, NONE, sizeof(c), 0, c, sizeof(c)); + + if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { + return PM3_ETIMEOUT; + } + + isOK = resp.oldarg[0] & 0xff; + if (!isOK) { + PrintAndLogEx(WARNING, _RED_("Command unsuccessful")); + return PM3_ESOFT; + } + + memcpy(dest + *app_ids_len, resp.data.asBytes + 1, resp.length - 5); + + *app_ids_len += (resp.length - 5); + } + return PM3_SUCCESS; +} + + +// none +static int get_desfire_fileids(uint8_t *dest, uint8_t *file_ids_len) { + uint8_t c[] = {MFDES_GET_FILE_IDS, 0x00, 0x00, 0x00}; // 0x6f + SendCommandMIX(CMD_HF_DESFIRE_COMMAND, NONE, sizeof(c), 0, c, sizeof(c)); + PacketResponseNG resp; + if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { + PrintAndLogEx(WARNING, _RED_(" Timed-out")); + return PM3_ETIMEOUT; + } + + uint8_t isOK = resp.oldarg[0] & 0xff; + if (!isOK) { + PrintAndLogEx(WARNING, _RED_("Command unsuccessful")); + return PM3_ESOFT; + } + + if (resp.data.asBytes[resp.length - 4] == 0x91 && resp.data.asBytes[resp.length - 3] == 0x00) { + *file_ids_len = resp.length - 5; + memcpy(dest, resp.data.asBytes + 1, *file_ids_len); + return PM3_SUCCESS; + } + + return PM3_ESOFT; +} + static int CmdHF14ADesInfo(const char *Cmd) { (void)Cmd; // Cmd is not used so far @@ -93,6 +344,7 @@ static int CmdHF14ADesInfo(const char *Cmd) { if (!WaitForResponseTimeout(CMD_HF_DESFIRE_INFO, &resp, 1500)) { PrintAndLogEx(WARNING, "Command execute timeout"); + DropField(); return PM3_ETIMEOUT; } @@ -147,6 +399,27 @@ static int CmdHF14ADesInfo(const char *Cmd) { PrintAndLogEx(SUCCESS, " Protocol : %s", getProtocolStr(package->versionSW[6])); PrintAndLogEx(INFO, "-------------------------------------------------------------"); + PrintAndLogEx(INFO, "Card capabilities"); + uint8_t major = package->versionSW[3]; + uint8_t minor = package->versionSW[4]; + if (major == 0 && minor == 4) + PrintAndLogEx(INFO, "\t0.4 - DESFire MF3ICD40, No support for APDU (only native commands)"); + if (major == 0 && minor == 5) + PrintAndLogEx(INFO, "\t0.5 - DESFire MF3ICD40, Support for wrapping commands inside ISO 7816 style APDUs"); + if (major == 0 && minor == 6) + PrintAndLogEx(INFO, "\t0.6 - DESFire MF3ICD40, Add ISO/IEC 7816 command set compatibility"); + if (major == 1 && minor == 3) + PrintAndLogEx(INFO, "\t1.3 - DESFire Ev1, Support extended APDU commands"); + if (major == 1 && minor == 4) + PrintAndLogEx(INFO, "\t1.4 - DESFire Ev1, N/A information about this version. report to iceman!"); + if (major == 2 && minor == 0) + PrintAndLogEx(INFO, "\t2.0 - DESFire Ev2, Originality check, proximity check"); + + if (major == 0 && minor == 2) + PrintAndLogEx(INFO, "\t0.2 - DESFire Light, Originality check, "); + + PrintAndLogEx(INFO, "-------------------------------------------------------------"); + // Signature originality check uint8_t signature[56] = {0}; size_t signature_len = 0; @@ -155,24 +428,19 @@ static int CmdHF14ADesInfo(const char *Cmd) { desfire_print_signature(package->uid, signature, signature_len); // Master Key settings - getKeySettings(NULL); + uint8_t master_aid[3] = {0x00, 0x00, 0x00}; + getKeySettings(master_aid); // Free memory on card - uint8_t c[] = {GET_FREE_MEMORY, 0x00, 0x00, 0x00}; // 0x6E - SendCommandMIX(CMD_HF_DESFIRE_COMMAND, (INIT | DISCONNECT), sizeof(c), 0, c, sizeof(c)); - if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) - return PM3_ETIMEOUT; - - PrintAndLogEx(INFO, " Free memory"); - // Desfire Light doesn't support FREEMEM (len = 5) - if (resp.length == 8) { - uint8_t tmp[3]; - memcpy(tmp, resp.data.asBytes + 1, 3); - PrintAndLogEx(SUCCESS, " Available free memory on card : " _GREEN_("%d bytes"), le24toh(tmp)); + PrintAndLogEx(INFO, " Free memory"); + uint32_t free_mem = 0; + if (get_desfire_freemem(&free_mem) == PM3_SUCCESS) { + desfire_print_freemem(free_mem); } else { PrintAndLogEx(SUCCESS, " Card doesn't support 'free mem' cmd"); } PrintAndLogEx(INFO, "-------------------------------------------------------------"); + /* Card Master key (CMK) 0x00 AID = 00 00 00 (card level) Application Master Key (AMK) 0x00 AID != 00 00 00 @@ -187,6 +455,8 @@ static int CmdHF14ADesInfo(const char *Cmd) { keys 12,13,14,15 R */ + + DropField(); return PM3_SUCCESS; } @@ -230,13 +500,13 @@ char *getVersionStr(uint8_t major, uint8_t minor) { char *retStr = buf; if (major == 0x00) - sprintf(retStr, "%x.%x ( " _YELLOW_("Desfire MF3ICD40") ")", major, minor); + sprintf(retStr, "%x.%x ( " _YELLOW_("DESFire MF3ICD40") ")", major, minor); else if (major == 0x01 && minor == 0x00) - sprintf(retStr, "%x.%x ( " _YELLOW_("Desfire EV1") ")", major, minor); + sprintf(retStr, "%x.%x ( " _YELLOW_("DESFire EV1") ")", major, minor); else if (major == 0x12 && minor == 0x00) - sprintf(retStr, "%x.%x ( " _YELLOW_("Desfire EV2") ")", major, minor); + sprintf(retStr, "%x.%x ( " _YELLOW_("DESFire EV2") ")", major, minor); else if (major == 0x30 && minor == 0x00) - sprintf(retStr, "%x.%x ( " _YELLOW_("Desfire Light") ")", major, minor); + sprintf(retStr, "%x.%x ( " _YELLOW_("DESFire Light") ")", major, minor); else sprintf(retStr, "%x.%x ( " _YELLOW_("Unknown") ")", major, minor); return buf; @@ -246,267 +516,162 @@ void getKeySettings(uint8_t *aid) { char messStr[512] = {0x00}; const char *str = messStr; - uint8_t isOK = 0; - PacketResponseNG resp; - if (aid == NULL) { + if (memcmp(aid, "\x00\x00\x00", 3) == 0) { // CARD MASTER KEY - PrintAndLogEx(INFO, " CMK - PICC, Card Master Key settings"); PrintAndLogEx(INFO, "-------------------------------------------------------------"); - { - uint8_t data[] = {GET_KEY_SETTINGS, 0x00, 0x00, 0x00}; // 0x45 - SendCommandMIX(CMD_HF_DESFIRE_COMMAND, INIT | DISCONNECT, sizeof(data), 0, data, sizeof(data)); - } - if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)) {return;} - isOK = resp.oldarg[0] & 0xff; - if (!isOK) { - PrintAndLogEx(WARNING, _RED_(" Can't select master application")); + + if (get_desfire_select_application(aid) != PM3_SUCCESS) { + PrintAndLogEx(WARNING, _RED_(" Can't select AID")); + DropField(); return; } - // Not supported 02 91 1c c4 ca - // OK - 02 0f 01 91 00 7e fe - if (resp.length == 7 ) { - + + // KEY Settings - AMK + uint8_t num_keys = 0; + uint8_t key_setting = 0; + if (get_desfire_keysettings(&key_setting, &num_keys) == PM3_SUCCESS) { // number of Master keys (0x01) - PrintAndLogEx(SUCCESS, " Number of Masterkeys : " _YELLOW_("%u"), resp.data.asBytes[2]); - - str = (resp.data.asBytes[1] & (1 << 3)) ? _GREEN_("YES") : "NO"; - PrintAndLogEx(SUCCESS, " [0x08] Configuration changeable : %s", str); + PrintAndLogEx(SUCCESS, " Number of Masterkeys : " _YELLOW_("%u"), (num_keys & 0x3F) ); - str = (resp.data.asBytes[1] & (1 << 2)) ? _GREEN_("YES") : "NO"; - PrintAndLogEx(SUCCESS, " [0x04] CMK required for create/delete : %s", str); - - str = (resp.data.asBytes[1] & (1 << 1)) ? _GREEN_("YES") : "NO"; - PrintAndLogEx(SUCCESS, " [0x02] Directory list access with CMK : %s", str); - - str = (resp.data.asBytes[1] & (1 << 0)) ? _GREEN_("YES") : "NO"; - PrintAndLogEx(SUCCESS, " [0x01] CMK is changeable : %s", str); + PrintAndLogEx(SUCCESS, " [0x08] Configuration changeable : %s", (key_setting & (1 << 3)) ? _GREEN_("YES") : "NO"); + PrintAndLogEx(SUCCESS, " [0x04] CMK required for create/delete : %s", (key_setting & (1 << 2)) ? _GREEN_("YES") : "NO"); + PrintAndLogEx(SUCCESS, " [0x02] Directory list access with CMK : %s", (key_setting & (1 << 1)) ? _GREEN_("YES") : "NO"); + PrintAndLogEx(SUCCESS, " [0x01] CMK is changeable : %s", (key_setting & (1 << 0)) ? _GREEN_("YES") : "NO"); + } else { + PrintAndLogEx(WARNING, _RED_(" Can't read Application Master key settings")); } - { - uint8_t data[] = {GET_KEY_VERSION, 0x00, 0x00, 0x01, 0x0, 0x00}; // 0x64 - SendCommandMIX(CMD_HF_DESFIRE_COMMAND, INIT | DISCONNECT, sizeof(data), 0, data, sizeof(data)); + + memset(messStr, 0x00, sizeof(messStr)); + str = " Operation of PICC master key : " _YELLOW_("%s"); + + // 2 MSB denotes + switch (num_keys >> 6) { + case 0: + PrintAndLogEx(SUCCESS, str, "(3)DES"); + break; + case 1: + PrintAndLogEx(SUCCESS, str, "3K3DES"); + break; + case 2: + PrintAndLogEx(SUCCESS, str, "AES"); + break; + default: + break; } - if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)) { return; } - isOK = resp.oldarg[0] & 0xff; - if (!isOK) { - PrintAndLogEx(WARNING, _RED_(" Can't read key-version")); - return; - } - if (resp.length == 6) { - PrintAndLogEx(SUCCESS, ""); - PrintAndLogEx(SUCCESS, " Master key Version : " _YELLOW_("%d (0x%02x)"), resp.data.asBytes[3], resp.data.asBytes[3]); + + uint8_t cmk_num_versions = 0; + if (get_desfire_keyversion(0, &cmk_num_versions) == PM3_SUCCESS) { + PrintAndLogEx(SUCCESS, " PICC Master key Version : " _YELLOW_("%d (0x%02x)"), cmk_num_versions, cmk_num_versions); PrintAndLogEx(INFO, " ----------------------------------------------------------"); } - - { - // 0x0A - uint8_t data[] = {AUTHENTICATE, 0x00, 0x00, 0x01, 0x00, 0x00}; // 0x0A, KEY 0 - SendCommandMIX(CMD_HF_DESFIRE_COMMAND, INIT | DISCONNECT, sizeof(data), 0, data, sizeof(data)); - } - if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)) {return;} - PrintAndLogEx(SUCCESS, " [0x0A] Authenticate : %s", (resp.length == 13) ? _YELLOW_("YES") : "NO"); - { - // 0x1A - uint8_t data[] = {AUTHENTICATE_ISO, 0x00, 0x00, 0x01, 0x00, 0x00}; // 0x1A, KEY 0 - SendCommandMIX(CMD_HF_DESFIRE_COMMAND, INIT | DISCONNECT, sizeof(data), 0, data, sizeof(data)); - } - if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)) {return;} - PrintAndLogEx(SUCCESS, " [0x1A] Authenticate ISO : %s", (resp.length >= 13) ? _YELLOW_("YES") : "NO"); + // Authentication tests + int res = test_desfire_authenticate(); + if (res == PM3_ETIMEOUT) return; + PrintAndLogEx(SUCCESS, " [0x0A] Authenticate : %s", (res == PM3_SUCCESS) ? _YELLOW_("YES") : "NO"); - { - // 0xAA - uint8_t data[] = {AUTHENTICATE_AES, 0x00, 0x00, 0x01, 0x00, 0x00}; // 0xAA, KEY 0 - SendCommandMIX(CMD_HF_DESFIRE_COMMAND, INIT | DISCONNECT, sizeof(data), 0, data, sizeof(data)); - } - if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)) {return;} - PrintAndLogEx(SUCCESS, " [0xAA] Authenticate AES : %s", (resp.length >= 13) ? _YELLOW_("YES") : "NO"); + res = test_desfire_authenticate_iso(); + if (res == PM3_ETIMEOUT) return; + PrintAndLogEx(SUCCESS, " [0x1A] Authenticate ISO : %s", (res == PM3_SUCCESS) ? _YELLOW_("YES") : "NO"); + + res = test_desfire_authenticate_aes(); + if (res == PM3_ETIMEOUT) return; + PrintAndLogEx(SUCCESS, " [0xAA] Authenticate AES : %s", (res == PM3_SUCCESS) ? _YELLOW_("YES") : "NO"); PrintAndLogEx(INFO, "-------------------------------------------------------------"); } else { // AID - APPLICATION MASTER KEYS - PrintAndLogEx(SUCCESS, " AMK - Application Master Key settings"); PrintAndLogEx(INFO, " ----------------------------------------------------------"); - PrintAndLogEx(INFO, " select AID: " _YELLOW_("%s"), sprint_hex(aid, 3) ); - // SELECT AID - { - uint8_t data[] = {SELECT_APPLICATION, 0x00, 0x00, 0x03, aid[0], aid[1], aid[2], 0x00}; // 0x5a - //memcpy(data + 1, aid, 3); - SendCommandMIX(CMD_HF_DESFIRE_COMMAND, INIT, sizeof(data), 0, data, sizeof(data)); - } - - if (!WaitForResponseTimeout(CMD_ACK, &resp, 3000)) { - PrintAndLogEx(WARNING, _RED_(" Timed-out")); - return; - } - isOK = resp.oldarg[0] & 0xff; - if (!isOK) { - PrintAndLogEx(WARNING, " Can't select AID: " _RED_("%s"), sprint_hex(aid, 3)); + if (get_desfire_select_application(aid) != PM3_SUCCESS) { + PrintAndLogEx(WARNING, _RED_(" Can't select AID")); + DropField(); return; } - // KEY SETTINGS - { - uint8_t data[] = {GET_KEY_SETTINGS, 0x00, 0x00, 0x00}; // 0x45 - SendCommandMIX(CMD_HF_DESFIRE_COMMAND, NONE, sizeof(data), 0, data, sizeof(data)); - } - - if (!WaitForResponseTimeout(CMD_ACK, &resp, 3000)) { - return; - } - isOK = resp.oldarg[0] & 0xff; - if (!isOK) { - PrintAndLogEx(WARNING, _RED_(" Can't read Application Master key settings")); + // KEY Settings - AMK + uint8_t num_keys = 0; + uint8_t key_setting = 0; + if (get_desfire_keysettings(&key_setting, &num_keys) == PM3_SUCCESS) { + desfire_print_keysetting(key_setting, num_keys); } else { - // Access rights. - uint8_t rights = (resp.data.asBytes[1] >> 4 & 0x0F); - switch (rights) { - case 0x0: - str = "AMK authentication is necessary to change any key (default)"; - break; - case 0xE: - str = "Authentication with the key to be changed (same KeyNo) is necessary to change a key"; - break; - case 0xF: - str = "All keys (except AMK,see Bit0) within this application are frozen"; - break; - default: - str = "Authentication with the specified key is necessary to change any key. A change key and a PICC master key (CMK) can only be changed after authentication with the master key. For keys other then the master or change key, an authentication with the same key is needed."; - break; - } - PrintAndLogEx(SUCCESS, "Changekey Access rights"); - PrintAndLogEx(SUCCESS, "-- " _GREEN_("%s"), str); - PrintAndLogEx(SUCCESS, ""); - // same as CMK - str = (resp.data.asBytes[1] & (1 << 3)) ? "YES" : "NO"; - PrintAndLogEx(SUCCESS, " 0x08 Configuration changeable : %s", str); - str = (resp.data.asBytes[1] & (1 << 2)) ? "NO" : "YES"; - PrintAndLogEx(SUCCESS, " 0x04 AMK required for create/delete : %s", str); - str = (resp.data.asBytes[1] & (1 << 1)) ? "NO" : "YES"; - PrintAndLogEx(SUCCESS, " 0x02 Directory list access with AMK : %s", str); - str = (resp.data.asBytes[1] & (1 << 0)) ? "YES" : "NO"; - PrintAndLogEx(SUCCESS, " 0x01 AMK is changeable : %s", str); + PrintAndLogEx(WARNING, _RED_(" Can't read Application Master key settings")); } // KEY VERSION - AMK - { - uint8_t data[] = {GET_KEY_VERSION, 0x00, 0x00, 0x01, 0x00, 0x00}; // 0x64 - SendCommandMIX(CMD_HF_DESFIRE_COMMAND, DISCONNECT, sizeof(data), 0, data, sizeof(data)); - } - - if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { - PrintAndLogEx(WARNING, _RED_(" Timed-out")); - return; - } - - int numOfKeys; - - isOK = resp.oldarg[0] & 0xff; - if (isOK == false) { - PrintAndLogEx(WARNING, " Can't read Application Master key version. Trying all keys"); - //numOfKeys = MAX_NUM_KEYS; - } else { - numOfKeys = resp.data.asBytes[1]; - PrintAndLogEx(SUCCESS, " Max number of keys : %d", numOfKeys); - PrintAndLogEx(SUCCESS, " Application Master key Version : %d (0x%02x)", resp.data.asBytes[3], resp.data.asBytes[3]); + uint8_t num_version = 0; + if (get_desfire_keyversion(0, &num_version) == PM3_SUCCESS) { PrintAndLogEx(INFO, "-------------------------------------------------------------"); + PrintAndLogEx(INFO, " Application keys"); + desfire_print_keyversion(0, num_version); + } else { + PrintAndLogEx(WARNING, " Can't read AID master key version. Trying all keys"); } - // LOOP over numOfKeys that we got before. // From 0x01 to numOfKeys. We already got 0x00. (AMK) - // TODO (iceman) - /* - for (int i = 0x01; i <= 0x0f; ++i) { + num_keys &= 0x3F; + if (num_keys > 1) { + for (uint8_t i = 0x01; i < num_keys; ++i) { + if (get_desfire_keyversion(i, &num_version) == PM3_SUCCESS) { + desfire_print_keyversion(i, num_version); + } else { + PrintAndLogEx(WARNING, " Can't read key %d (0x%02x) version", i, i); } - */ + } + } + PrintAndLogEx(INFO, "-------------------------------------------------------------"); } + + DropField(); } static int CmdHF14ADesEnumApplications(const char *Cmd) { (void)Cmd; // Cmd is not used so far - uint8_t isOK = 0x00; +// uint8_t isOK = 0x00; uint8_t aid[3]; - { - uint8_t data[] = {GET_APPLICATION_IDS, 0x00, 0x00, 0x00}; //0x6a - SendCommandMIX(CMD_HF_DESFIRE_COMMAND, INIT | CLEARTRACE | DISCONNECT, sizeof(data), 0, data, sizeof(data)); - } - PacketResponseNG resp; - - if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { - return PM3_ETIMEOUT; - } - - isOK = resp.oldarg[0] & 0xff; - if (!isOK) { - PrintAndLogEx(WARNING, _RED_("Command unsuccessful")); + uint8_t app_ids[78] = {0}; + uint8_t app_ids_len = 0; + + uint8_t file_ids[33] = {0}; + uint8_t file_ids_len = 0; + + if (get_desfire_appids(app_ids, &app_ids_len) != PM3_SUCCESS) { + PrintAndLogEx(ERR, "Can't get list of applications on tag"); return PM3_ESOFT; } + PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(INFO, "-- Desfire Enumerate Applications ---------------------------"); + PrintAndLogEx(INFO, "-- Mifare DESFire Enumerate applications --------------------"); PrintAndLogEx(INFO, "-------------------------------------------------------------"); + PrintAndLogEx(SUCCESS, " Tag report " _GREEN_("%d") "application%c", app_ids_len / 3, (app_ids_len == 3) ? ' ' : 's'); + + for (int i = 0; i < app_ids_len; i += 3) { -// PacketResponseNG respAid; -// PacketResponseNG respFiles; + aid[0] = app_ids[i]; + aid[1] = app_ids[i + 1]; + aid[2] = app_ids[i + 2]; + + PrintAndLogEx(SUCCESS, " AID %d : " _GREEN_("%02X %02X %02X"), i, app_ids[i], app_ids[i+1], app_ids[i+2]); - uint8_t num = 0; - int max = resp.oldarg[1] - 3 - 2; - PrintAndLogEx(INFO," MAX %d", max); - - for (int i = 1; i < max; i += 3) { - PrintAndLogEx(SUCCESS, " Aid %d : %02X %02X %02X ", num, resp.data.asBytes[i], resp.data.asBytes[i+1], resp.data.asBytes[i+2]); - num++; - - aid[0] = resp.data.asBytes[i]; - aid[1] = resp.data.asBytes[i + 1]; - aid[2] = resp.data.asBytes[i + 2]; getKeySettings(aid); -/* - // Select Application - { - uint8_t data[] = {SELECT_APPLICATION, 0x00, 0x00, 0x03, aid[0], aid[1], aid[2], 0x00}; // 0x5a - SendCommandMIX(CMD_HF_DESFIRE_COMMAND, NONE, sizeof(data), 0, data, sizeof(data)); - } - - if (!WaitForResponseTimeout(CMD_ACK, &respAid, 1500)) { - PrintAndLogEx(WARNING, _RED_(" Timed-out")); - continue; - } - isOK = respAid.data.asBytes[2] & 0xff; - if (isOK != 0x00) { - PrintAndLogEx(WARNING, " Can't select AID: " _RED_("%s"), sprint_hex(resp.data.asBytes + i, 3)); - continue; - } - // Get File IDs - { - uint8_t data[] = {GET_FILE_IDS, 0x00, 0x00, 0x00}; // 0x6f - SendCommandMIX(CMD_HF_DESFIRE_COMMAND, NONE, sizeof(data), 0, data, sizeof(data)); - } - - if (!WaitForResponseTimeout(CMD_ACK, &respFiles, 1500)) { - PrintAndLogEx(WARNING, _RED_(" Timed-out")); - continue; - } else { - isOK = respFiles.data.asBytes[2] & 0xff; - if (!isOK) { - PrintAndLogEx(WARNING, _RED_(" Can't get file ids ")); - } else { - int respfileLen = resp.oldarg[1] - 3 - 2; - for (int j = 0; j < respfileLen; ++j) { - PrintAndLogEx(SUCCESS, " Fileid %d :", resp.data.asBytes[j + 3]); - } + if (get_desfire_fileids(file_ids, &file_ids_len) == PM3_SUCCESS) { + PrintAndLogEx(SUCCESS, " Tag report " _GREEN_("%d") "file%c", file_ids_len, (file_ids_len == 1) ? ' ' : 's'); + for (int i = 0; i < file_ids_len; ++i) { + PrintAndLogEx(SUCCESS, " Fileid %d (0x%02x)", file_ids[i], file_ids[i]); } } +/* // Get ISO File IDs { uint8_t data[] = {GET_ISOFILE_IDS, 0x00, 0x00, 0x00}; // 0x61 @@ -530,11 +695,22 @@ static int CmdHF14ADesEnumApplications(const char *Cmd) { */ } PrintAndLogEx(INFO, "-------------------------------------------------------------"); + DropField(); return PM3_SUCCESS; } +/* + uint8_t cmd[3 + 16] = {0xa8, 0x90, 0x90, 0x00}; + int res = ExchangeRAW14a(cmd, sizeof(cmd), false, false, data, sizeof(data), &datalen, false); + + if (!res && datalen > 1 && data[0] == 0x09) { + SLmode = 0; + } + +*/ -// MIAFRE DesFire Authentication + +// MIAFRE DESFire Authentication // #define BUFSIZE 256 static int CmdHF14ADesAuth(const char *Cmd) { From be3932d3c0a3306c73a872361819cfd138c2b6a6 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 19 Mar 2020 12:05:48 +0100 Subject: [PATCH 1729/1854] textual --- client/cmdhfmfp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/cmdhfmfp.c b/client/cmdhfmfp.c index 641e959a1..2a1533344 100644 --- a/client/cmdhfmfp.c +++ b/client/cmdhfmfp.c @@ -138,10 +138,10 @@ static int CmdHFMFPInfo(const char *Cmd) { PrintAndLogEx(INFO, "SL 0: initial delivery configuration, used for card personalization"); break; case 1: - PrintAndLogEx(INFO, "SL 1: backwards functional compatibility mode (with MIFARE Classic 1K and MIFARE Classic 4K) with an optional AES authentication"); + PrintAndLogEx(INFO, "SL 1: backwards functional compatibility mode (with MIFARE Classic 1K / 4K) with an optional AES authentication"); break; case 2: - PrintAndLogEx(INFO, "SL 2: "); + PrintAndLogEx(INFO, "SL 2: 3-Pass Authentication based on AES followed by MIFARE CRYPTO1 authentication, communication secured by MIFARE CRYPTO1"); break; case 3: PrintAndLogEx(INFO, "SL 3: 3-Pass authentication based on AES, data manipulation commands secured by AES encryption and an AES based MACing method."); From 4d335b1fbe1039ad7e84b84620c86ad2f6c6cad8 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 19 Mar 2020 12:16:55 +0100 Subject: [PATCH 1730/1854] text --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b75de3ee..607bcd64e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Fix 'hf mfdes enum' - now actually manages to enumerate files under all AID's. :smiley: (@iceman1001) + - Fix 'hf mfdes info' - now detects DESFire light and work properly Wrapped commands :+1: (@iceman1001) - :smiling_imp: support (@doegox) - Additional colour changes as recommended by @iceman (@dunderhay) - Change type colour for `hf 14a` card types (@dunderhay) From cf47e50267b7dd15a2228a8bee23a6a80fd34c26 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 19 Mar 2020 12:18:29 +0100 Subject: [PATCH 1731/1854] define additional frame --- include/protocols.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/protocols.h b/include/protocols.h index 519172af6..89038a789 100644 --- a/include/protocols.h +++ b/include/protocols.h @@ -385,6 +385,7 @@ ISO 7816-4 Basic interindustry commands. For command APDU's. #define MFDES_CHANGE_KEY 0xc4 #define MFDES_GET_KEY_VERSION 0x64 #define MFDES_AUTHENTICATION_FRAME 0xAF +#define MFDES_ADDITIONAL_FRAME 0xAF #define MFDES_READSIG 0x3C // LEGIC Commands From 8ef3f3438435157faf613d1b816c83c08d81915c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 20 Mar 2020 11:09:23 +0100 Subject: [PATCH 1732/1854] update ex4x05 timing, @mwalker (@marshmellow42, https://github.com/marshmellow42/proxmark3/commit/1ebf9f25602371b3542097efe94c56edc42638c4) --- armsrc/lfops.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 84bddc192..904d37c61 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -2399,13 +2399,13 @@ void SendForward(uint8_t fwd_bit_count) { TurnReadLF_off(EM_START_GAP); TurnReadLFOn(18 * 8); - // now start writting with bitbanging the antenna. + // now start writting with bitbanging the antenna. (each bit should be 32*8 total length) while (fwd_bit_sz-- > 0) { //prepare next bit modulation if (((*fwd_write_ptr++) & 1) == 1) { WaitUS(32 * 8); } else { TurnReadLF_off(23 * 8); - TurnReadLFOn(18 * 8); + TurnReadLFOn(32-23 * 8); } } } From d870b52d7bac48d294c5966829c1b8a41ed18dd3 Mon Sep 17 00:00:00 2001 From: mwalker33 Date: Sat, 21 Mar 2020 13:37:33 +1100 Subject: [PATCH 1733/1854] Update cmdlfkeri.c --- client/cmdlfkeri.c | 40 ++++++++-------------------------------- 1 file changed, 8 insertions(+), 32 deletions(-) diff --git a/client/cmdlfkeri.c b/client/cmdlfkeri.c index 4a0c3c8fd..982eb8193 100644 --- a/client/cmdlfkeri.c +++ b/client/cmdlfkeri.c @@ -59,20 +59,15 @@ typedef enum {Scramble = 0,Descramble = 1} KeriMSScramble_t; static int CmdKeriMSScramble (KeriMSScramble_t Action, uint32_t *FC, uint32_t *ID, uint32_t *CardID) { // 255 = Not used/Unknown other values are the bit offset in the ID/FC values - uint8_t CardToID [] = { 255,255,255,255, 13, 12, 17, 5,255, 6,255, 18, 8,255, 0, 7, - 10,255,255, 11, 4, 1,255, 19,255, 20, 2,255, 3, 9,255,255 }; - uint8_t CardToFC [] = { 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, - 255,255, 2,255,255,255,255,255,255,255,255,255,255,255, 1,255 }; + uint8_t CardToID [] = { 255,255,255,255, 13, 12, 20, 5, 16, 6, 21, 17, 8,255, 0, 7, + 10, 15,255, 11, 4, 1,255, 18,255, 19, 2, 14, 3, 9,255,255 }; + + uint8_t CardToFC [] = { 255,255,255,255,255,255,255,255,255,255,255,255,255, 0,255,255, + 255,255, 2,255,255,255, 3,255, 4,255,255,255,255,255, 1,255 }; uint8_t CardIdx; // 0 - 31 bool BitState; - // Used to track known bit states - remove when all bit maps are known - char IDDecodeState[33] = {0x00}; - char FCDecodeState[33] = {0x00}; - memset (IDDecodeState,'-',32); - memset (FCDecodeState,'-',32); - if (Action == Descramble) { *FC = 0; *ID = 0; @@ -82,31 +77,12 @@ static int CmdKeriMSScramble (KeriMSScramble_t Action, uint32_t *FC, uint32_t *I // Card ID if (CardToID[CardIdx] < 32) { *ID = *ID | (BitState << CardToID[CardIdx]); - // Remove when all bits are known - IDDecodeState[31-CardToID[CardIdx]] = '0'+BitState; } // Card FC if (CardToFC[CardIdx] < 32) { *FC = *FC | (BitState << CardToFC[CardIdx]); - // Remove when all bits are known - FCDecodeState[31-CardToFC[CardIdx]] = '0'+BitState; } } - - // Patch for bit order group unknown - remove when all Keri MS Bits maps are known - // Reverse order for easy mapping for unknowns - // I know that these bit groups are a in the correct location, unknown order. - if (IDDecodeState[31-17] == '1') IDDecodeState[31-17] = '?'; - if (IDDecodeState[31-18] == '1') IDDecodeState[31-18] = '?'; - if (IDDecodeState[31-19] == '1') IDDecodeState[31-19] = '?'; - if (IDDecodeState[31-20] == '1') IDDecodeState[31-20] = '?'; - - if (FCDecodeState[31- 1] == '1') FCDecodeState[31- 1] = '?'; - if (FCDecodeState[31- 2] == '1') FCDecodeState[31- 2] = '?'; - - PrintAndLogEx(SUCCESS, "Partial Keri MS decode"); - PrintAndLogEx(SUCCESS, "BitState ID : %s",IDDecodeState); - PrintAndLogEx(SUCCESS, "BitState FC : %s",FCDecodeState); } if (Action == Scramble) @@ -119,12 +95,12 @@ static int CmdKeriMSScramble (KeriMSScramble_t Action, uint32_t *FC, uint32_t *I if (CardToID[CardIdx] < 32) { if ((*ID & (1 << CardToID[CardIdx])) > 0) *CardID |= (1 << CardIdx); - } - // Card FC + } + // Card FC if (CardToFC[CardIdx] < 32) { if ((*ID & (1 << CardToFC[CardIdx])) > 0) *CardID |= (1 << CardIdx); - } + } } // Fixed bits and parity/check bits From 311f43172f1056fab458e3c35b1bc119b0679477 Mon Sep 17 00:00:00 2001 From: Artem Gnatyuk Date: Sat, 21 Mar 2020 15:48:16 +0700 Subject: [PATCH 1734/1854] LF_EM4100EMULV1 - renamed to LF_EM4100EMUL. Make more easy control. Short click - switch slot and satrt simulation LF_EM4100EMULV2 - deleted. LF_EM4100EMULV3 - renamed to LF_EM4100RWC --- armsrc/Standalone/Makefile.hal | 19 +- armsrc/Standalone/Makefile.inc | 26 +-- .../{lf_em4100emulV1.c => lf_em4100emul.c} | 31 +-- armsrc/Standalone/lf_em4100emulV3.c | 197 ------------------ .../{lf_em4100emulV2.c => lf_em4100rwc.c} | 8 +- 5 files changed, 26 insertions(+), 255 deletions(-) rename armsrc/Standalone/{lf_em4100emulV1.c => lf_em4100emul.c} (77%) delete mode 100644 armsrc/Standalone/lf_em4100emulV3.c rename armsrc/Standalone/{lf_em4100emulV2.c => lf_em4100rwc.c} (96%) diff --git a/armsrc/Standalone/Makefile.hal b/armsrc/Standalone/Makefile.hal index 776ae3f0f..fd52817db 100644 --- a/armsrc/Standalone/Makefile.hal +++ b/armsrc/Standalone/Makefile.hal @@ -35,28 +35,19 @@ define KNOWN_STANDALONE_DEFINITIONS | HF_BOG | 14a sniff with ULC/ULEV1/NTAG auth | | (RDV4 only) | storing in flashmem - Bogito | +----------------------------------------------------------+ -| HF_14ASNIFF | 14a sniff to flashmem | -| (RDV4 only) | | -+----------------------------------------------------------+ -| LF_ICEHID | LF HID collector to flashmem | -| (RDV4 only) | | -+----------------------------------------------------------+ -| LF_EM4100EMULV1 | Simulate predefined em4100 tags only | +| LF_EM4100EMUL | Simulate predefined em4100 tags only | | | | +----------------------------------------------------------+ -| LF_EM4100EMULV2 | Read/simulate em4100 tags | -| | | -+----------------------------------------------------------+ -| LF_EM4100EMULV3 | Read/simulate em4100 tags & clone it | +| LF_EM4100RWC | Read/simulate em4100 tags & clone it | | | to T555x tags | +----------------------------------------------------------+ endef -STANDALONE_MODES := LF_SAMYRUN LF_ICERUN LF_PROXBRUTE LF_HIDBRUTE LF_ICEHID LF_EM4100EMULV1 LF_EM4100EMULV2 LF_EM4100EMULV3 -STANDALONE_MODES += HF_YOUNG HF_MATTYRUN HF_COLIN HF_BOG HF_14ASNIFF +STANDALONE_MODES := LF_SAMYRUN LF_ICERUN LF_PROXBRUTE LF_HIDBRUTE LF_EM4100EMUL LF_EM4100RWC +STANDALONE_MODES += HF_YOUNG HF_MATTYRUN HF_COLIN HF_BOG STANDALONE_MODES_REQ_SMARTCARD := -STANDALONE_MODES_REQ_FLASH := HF_COLIN HF_BOG HF_14ASNIFF LF_ICEHID +STANDALONE_MODES_REQ_FLASH := HF_COLIN HF_BOG ifneq ($(filter $(STANDALONE),$(STANDALONE_MODES)),) STANDALONE_PLATFORM_DEFS += -DWITH_STANDALONE_$(STANDALONE) ifneq ($(filter $(STANDALONE),$(STANDALONE_MODES_REQ_SMARTCARD)),) diff --git a/armsrc/Standalone/Makefile.inc b/armsrc/Standalone/Makefile.inc index e7ca1bfe0..686cc66f0 100644 --- a/armsrc/Standalone/Makefile.inc +++ b/armsrc/Standalone/Makefile.inc @@ -33,23 +33,11 @@ endif ifneq (,$(findstring WITH_STANDALONE_HF_BOG,$(APP_CFLAGS))) SRC_STANDALONE = hf_bog.c endif -# WITH_STANDALONE_HF_14ASNIFF -ifneq (,$(findstring WITH_STANDALONE_HF_14ASNIFF,$(APP_CFLAGS))) - SRC_STANDALONE = hf_14asniff.c -endif -# WITH_STANDALONE_LF_ICEHID -ifneq (,$(findstring WITH_STANDALONE_LF_ICEHID,$(APP_CFLAGS))) - SRC_STANDALONE = lf_icehid.c -endif -# WITH_STANDALONE_LF_EM4100EMULV1 -ifneq (,$(findstring WITH_STANDALONE_LF_EM4100EMULV1,$(APP_CFLAGS))) - SRC_STANDALONE = lf_em4100emulV1.c -endif -# WITH_STANDALONE_LF_EM4100EMULV2 -ifneq (,$(findstring WITH_STANDALONE_LF_EM4100EMULV2,$(APP_CFLAGS))) - SRC_STANDALONE = lf_em4100emulV2.c -endif -# WITH_STANDALONE_LF_EM4100EMULV3 -ifneq (,$(findstring WITH_STANDALONE_LF_EM4100EMULV3,$(APP_CFLAGS))) - SRC_STANDALONE = lf_em4100emulV3.c +# WITH_STANDALONE_LF_EM4100EMUL +ifneq (,$(findstring WITH_STANDALONE_LF_EM4100EMUL,$(APP_CFLAGS))) + SRC_STANDALONE = lf_em4100emul.c endif +# WITH_STANDALONE_LF_EM4100RWC +ifneq (,$(findstring WITH_STANDALONE_LF_EM4100RWC,$(APP_CFLAGS))) + SRC_STANDALONE = lf_em4100rwc.c +endif \ No newline at end of file diff --git a/armsrc/Standalone/lf_em4100emulV1.c b/armsrc/Standalone/lf_em4100emul.c similarity index 77% rename from armsrc/Standalone/lf_em4100emulV1.c rename to armsrc/Standalone/lf_em4100emul.c index d132f3650..907445912 100644 --- a/armsrc/Standalone/lf_em4100emulV1.c +++ b/armsrc/Standalone/lf_em4100emul.c @@ -5,9 +5,8 @@ // at your option, any later version. See the LICENSE.txt file for the text of // the license. //----------------------------------------------------------------------------- -// LF emul V1 - Very simple mode. Simulate only predefined in low[] IDs -// Short click - change current slot -// Long press - simulate tag ID from current slot +// LF emul - Very simple mode. Simulate only predefined in low[] IDs +// Short click - select next slot and start simulation //----------------------------------------------------------------------------- #include "standalone.h" #include "proxmark3_arm.h" @@ -32,7 +31,7 @@ uint8_t *bba,slots_count; int buflen; void ModInfo(void) { - DbpString(" LF EM4100 simulate standalone V1"); + DbpString(" LF EM4100 simulator standalone mode"); } uint64_t ReversQuads(uint64_t bits){ @@ -72,6 +71,7 @@ void ConstructEM410xEmulBuf(uint64_t id) { } void LED_Slot(int i) { + LEDsoff(); if (slots_count > 4) { LED(i % MAX_IND, 0); //binary indication for slots_count > 4 } else { @@ -82,26 +82,17 @@ void LED_Slot(int i) { void RunMod() { StandAloneMode(); FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - int selected = 0; + int selected = 0; //selected slot after start slots_count = sizeof(low)/sizeof(low[0]); bba = BigBuf_get_addr(); - LED_Slot(selected); for (;;) { WDT_HIT(); if (data_available()) break; - int button_pressed = BUTTON_HELD(1000); - SpinDelay(300); - if (button_pressed == 1) { - SpinUp(100); - SpinOff(10); - LED_Slot(selected); - ConstructEM410xEmulBuf(ReversQuads(low[selected])); - SimulateTagLowFrequency(buflen, 0, true); - LED_Slot(selected); - } else if (button_pressed < 0) { - selected = (selected + 1) % slots_count; - LEDsoff(); - LED_Slot(selected); - } + SpinDelay(100); + SpinUp(100); + LED_Slot(selected); + ConstructEM410xEmulBuf(ReversQuads(low[selected])); + SimulateTagLowFrequency(buflen, 0, true); + selected = (selected + 1) % slots_count; } } diff --git a/armsrc/Standalone/lf_em4100emulV3.c b/armsrc/Standalone/lf_em4100emulV3.c deleted file mode 100644 index b1bf0d930..000000000 --- a/armsrc/Standalone/lf_em4100emulV3.c +++ /dev/null @@ -1,197 +0,0 @@ -//----------------------------------------------------------------------------- -// Artyom Gnatyuk, 2020 -// -// This code is licensed to you under the terms of the GNU GPL, version 2 or, -// at your option, any later version. See the LICENSE.txt file for the text of -// the license. -//----------------------------------------------------------------------------- -// LF emul V3 - This mode can simulate ID from selected slot, read ID to -// selected slot, write from selected slot to T5555 tag and store -// readed ID to flash (only RDV4). Also you can set predefined IDs -// in any slot. -// To recall stored ID from flash execute: -// mem dump o offset l 5 p -// where offset = 5 * selected slot -//----------------------------------------------------------------------------- -#include "standalone.h" -#include "proxmark3_arm.h" -#include "appmain.h" -#include "fpgaloader.h" -#include "lfops.h" -#include "util.h" -#include "dbprint.h" -#include "ticks.h" -#include "string.h" -#include "BigBuf.h" - -#ifdef WITH_FLASH -#include "flashmem.h" -#endif - -#define MAX_IND 16 // 4 LEDs - 2^4 combinations -#define CLOCK 64 //for 125kHz - -// low & high - array for storage IDs. Its length must be equal. -// Predefined IDs must be stored in low[]. -// In high[] must be nulls -uint64_t low[] = {0x565AF781C7,0x540053E4E2,0x1234567890,0,0,0,0,0,0,0,0,0,0,0,0,0}; -uint32_t high[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; -uint8_t *bba,slots_count; -int buflen; - -void ModInfo(void) { - DbpString(" LF EM4100 simulate standalone V3"); -} - -uint64_t ReversQuads(uint64_t bits){ - uint64_t result = 0; - for (int i = 0; i < 16; i++){ - result += ((bits >> (60 - 4 *i)) & 0xf) << (4 * i); - } - return result >> 24; -} - -void FillBuff(uint8_t bit) { - memset (bba + buflen, bit, CLOCK / 2); - buflen += (CLOCK / 2); - memset (bba + buflen, bit^1,CLOCK / 2); - buflen += (CLOCK / 2); -} - -void ConstructEM410xEmulBuf(uint64_t id) { - - int i, j, binary[4], parity[4]; - buflen = 0; - for (i = 0; i < 9; i++) - FillBuff(1); - parity[0] = parity[1] = parity[2] = parity[3] = 0; - for (i = 0; i < 10; i++) { - for (j = 3; j >= 0; j--, id /= 2) - binary[j] = id % 2; - for (j = 0; j < 4; j++) - FillBuff(binary[j]); - FillBuff(binary[0] ^ binary[1] ^ binary[2] ^ binary[3]); - for (j = 0; j < 4; j++) - parity[j] ^= binary[j]; - } - for (j = 0; j < 4; j++) - FillBuff(parity[j]); - FillBuff(0); -} - -void LED_Slot(int i) { - if (slots_count > 4) { - LED(i % MAX_IND, 0); //binary indication, usefully for slots_count > 4 - } else { - LED(1 << i,0); //simple indication for slots_count <=4 - } -} - -void FlashLEDs(uint32_t speed, uint8_t times) { - for (int i = 0; i < times * 2; i++) { - LED_A_INV(); - LED_B_INV(); - LED_C_INV(); - LED_D_INV(); - SpinDelay(speed); - } -} - -#ifdef WITH_FLASH -void SaveIDtoFlash (int addr, uint64_t id) { - uint8_t b, *ptr; - for (int i = 0; i < 5; i++) { - b = (uint8_t) (id >> 8 * i & 0xff); - ptr = &b; - Flash_WriteData(addr * 5 + 4 - i,ptr,1); - } -} -#endif - -void RunMod() { - StandAloneMode(); - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - int selected = 0; - //state 0 - select slot - // 1 - read tag to selected slot, - // 2 - simulate tag from selected slot - // 3 - write to T5555 tag - uint8_t state = 0; - slots_count = sizeof(low)/sizeof(low[0]); - bba = BigBuf_get_addr(); - LED_Slot(selected); - for (;;) { - WDT_HIT(); - if (data_available()) break; - int button_pressed = BUTTON_HELD(1000); - SpinDelay(300); - switch (state){ - case 0: - // Select mode - if (button_pressed == 1) { - // Long press - switch to simulate mode - SpinUp(100); - SpinOff(100); - LED_Slot(selected); - state = 2; - } else if (button_pressed < 0) { - // Click - switch to next slot - selected = (selected + 1) % slots_count; - LEDsoff(); - LED_Slot(selected); - } - break; - case 1: - // Read mode. - if (button_pressed > 0) { - // Long press - switch to read mode - SpinUp(100); - SpinOff(10); - LED_Slot(selected); - state = 3; - } else if (button_pressed < 0) { - // Click - exit to select mode - CmdEM410xdemod(1, &high[selected], &low[selected], 0); - FlashLEDs(100,5); - #ifdef WITH_FLASH - SaveIDtoFlash(selected, low[selected]); - #endif - state = 0; - } - break; - case 2: - // Simulate mode - if (button_pressed > 0) { - // Long press - switch to read mode - SpinDown(100); - SpinOff(10); - LED_Slot(selected); - state = 1; - } else if (button_pressed < 0) { - // Click - start simulating. Click again to exit from simelate mode - LED_Slot(selected); - ConstructEM410xEmulBuf(ReversQuads(low[selected])); - FlashLEDs(100,5); - SimulateTagLowFrequency(buflen, 0, 1); - LED_Slot(selected); - state = 0; // Switch to select mode - } - break; - case 3: - // Write tag mode - if (button_pressed > 0) { - // Long press - switch to select mode - SpinDown(100); - SpinOff(10); - LED_Slot(selected); - state = 0; - } else if (button_pressed < 0) { - // Click - write ID to tag - WriteEM410x(0, (uint32_t) (low[selected] >> 32), (uint32_t) (low[selected] & 0xffffffff)); - LED_Slot(selected); - state = 0; // Switch to select mode - } - break; - } - } -} diff --git a/armsrc/Standalone/lf_em4100emulV2.c b/armsrc/Standalone/lf_em4100rwc.c similarity index 96% rename from armsrc/Standalone/lf_em4100emulV2.c rename to armsrc/Standalone/lf_em4100rwc.c index 2b48aeced..a336112ba 100644 --- a/armsrc/Standalone/lf_em4100emulV2.c +++ b/armsrc/Standalone/lf_em4100rwc.c @@ -5,7 +5,7 @@ // at your option, any later version. See the LICENSE.txt file for the text of // the license. //----------------------------------------------------------------------------- -// LF emul V2 - This mode can simulate tag ID from selected slot and read tag ID +// LF rwc - This mode can simulate tag ID from selected slot and read tag ID // to selected slot and to flash (only RDV4). Also you can set // predefined IDs in any slot. // To recall stored ID from flash execute: @@ -39,7 +39,7 @@ uint8_t *bba,slots_count; int buflen; void ModInfo(void) { - DbpString(" LF EM4100 simulate standalone V2"); + DbpString(" LF EM4100 read/write/clone standalone mode"); } uint64_t ReversQuads(uint64_t bits){ @@ -79,6 +79,7 @@ void ConstructEM410xEmulBuf(uint64_t id) { } void LED_Slot(int i) { + LEDsoff(); if (slots_count > 4) { LED(i % MAX_IND, 0); //binary indication, usefully for slots_count > 4 } else { @@ -130,12 +131,10 @@ void RunMod() { // Long press - switch to simulate mode SpinUp(100); SpinOff(100); - LED_Slot(selected); state = 2; } else if (button_pressed < 0) { // Click - switch to next slot selected = (selected + 1) % slots_count; - LEDsoff(); LED_Slot(selected); } break; @@ -153,7 +152,6 @@ void RunMod() { if (button_pressed > 0) { // Long press - switch to read mode SpinDown(100); - SpinOff(10); LED_Slot(selected); state = 1; } else if (button_pressed < 0) { From 19aa618fbd94b3d4cac0ee2c2fd6104850a29e83 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 21 Mar 2020 10:03:36 +0100 Subject: [PATCH 1735/1854] keys --- client/dictionaries/mfc_default_keys.dic | 3 +++ 1 file changed, 3 insertions(+) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index 405f0d6f0..b3dfbd128 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -1105,3 +1105,6 @@ fe04ecfe5577 # comfort inn hotel 4d57414c5648 4d48414c5648 +# +# unknown hotel key +6d9b485a4845 From 4443ae5500384e9dbced87a533aa4464e047e9f0 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 21 Mar 2020 10:04:03 +0100 Subject: [PATCH 1736/1854] rework script --- client/luascripts/hf-writer.lua | 189 ++++++++++++++++++-------------- 1 file changed, 105 insertions(+), 84 deletions(-) diff --git a/client/luascripts/hf-writer.lua b/client/luascripts/hf-writer.lua index 8c5740af6..010a0eb30 100644 --- a/client/luascripts/hf-writer.lua +++ b/client/luascripts/hf-writer.lua @@ -1,33 +1,45 @@ local utils = require('utils') local getopt = require('getopt') local read14a = require('read14a') -local uid = {} -- Array for eml files -local B = {} -- Array for B keys -local eml = {} -- Array for data in block 32 dig -local a = 0 -local b = 0 -local tab = string.rep('-', 64) + +[[-- +---Suggestions of improvement: +--- Add support another types of dumps: BIN, JSON +--- Maybe it will be not only as `mfc_gen3_writer`, like a universal dump manager. +--- Add undependence from the operation system. At the moment code not working in Linux. +--- Add more chinesse backdoors RAW commands for UID changing (find RAW for the 4 byte familiar chinese card, from native it soft: http://bit.ly/39VIDsU) +--- Hide system messages when you writing a dumps, replace it to some of like [#####----------] 40% + +-- iceman notes: +-- doesn't take consideration filepaths for dump files. +-- doesn't allow A keys for authenticating when writing +-- doesn't verify that card is magic gen3. +--]] copyright = '' author = 'Winds' version = 'v1.0.0' desc = [[ - That's script gives for you a easy way to write your an *.eml dumps, using a Proxmark 3. - It's working for 4 and 7 bytes NXP MIFARE Classic 1K cards. - The script has including an injection of UID changig for the Chinese Magic Cards GEN 3. - - Whith choosen an *.eml file you can do: + The script gives you a easy way to write your *.eml dumps onto normal MFC and magic Gen3 cards. - 1. Write it to the equals of current card UID. - 2. Write it to anther card with changable UID. - 3. Send command to lock UID for the Chinese Magic Cards GEN 3. - 4. Erease all data at the card and set the FFFFFFFFFFFF keys, and Access Conditions to 78778800. + Works with both 4 and 7 bytes NXP MIFARE Classic 1K cards. + The script also has the possibility to change UID and permanent lock uid on magic Gen3 cards. + + It supports the following functionality. + + 1. Write it to the same of current card UID. + 2. Write it to magic Gen3 card. + 3. Change uid to match dump on magic Gen3 card. + 4. Permanent lock UID on magic Gen3 card. + 5. Erase all data at the card and set the FF FF FF FF FF FF keys, and Access Conditions to 78778800. + + Script works in a wizard styled way. ]] example = [[ - 1. script run hf-writer + 1. script run mfc_gen3_writer ]] usage = [[ - You should choose your *.eml dump from being list to write it to the card by wizard + Select your *.eml dump from list to write to the card. ]] --- @@ -40,135 +52,144 @@ local function help() print(example) print(usage) end - -local function read() - u = read14a.read(true, true).uid - return u +--- +-- GetUID +local function GetUID() + return read14a.read(true, true).uid end - -local function fkey() - f = 'FFFFFFFFFFFF' - return f -end - -local function finish() +--- +-- +local function dropfield() read14a.disconnect() core.clearCommandBuffer() end - +--- +-- Wait for tag (MFC) local function wait() read14a.waitFor14443a() end - +--- +-- local function main(args) + -- Arguments for the script for o, a in getopt.getopt(args, 'h') do if o == 'h' then return help() end end - --File lienght check for detect 4 or 7 bytes + local files = {} -- Array for eml files + local b_keys = {} -- Array for B keys + local eml = {} -- Array for data in block 32 + local num_dumps = 0 -- num of found eml dump files + + local tab = string.rep('-', 64) + -- wait() print(tab) - if string.len(read()) == 14 then -- Detect 7 byte card - l = 29 -- 7 byte length of eml file - s = 7 + + local length = 23 + local e = 14 + -- Detect 7 byte card + if string.len(GetUID()) == 14 then + length = 29 e = 20 - else - l = 23 -- 4 byte length of eml file - s = 7 - e = 14 end - ---Listern EML files at Client catalog + + ---List all EML files in /client for _ in io.popen([[dir ".\" /b]]):lines() do -- for UNIX: ls + if string.find(_, '%.eml$') then - if string.len(_) == l then -- There length of eml file - a = a + 1 - uid[a] = string.sub(tostring(_), s, e) -- Cut UID from eml file - print(' ' .. a .. ' ' .. '|' .. ' ' .. uid[a]) + + if string.len(_) == length then -- The length of eml file + num_dumps = num_dumps + 1 + files[num_dumps] = string.sub(tostring(_), 7, e) -- Cut UID from eml file + print(' '..num_dumps..' | '..files[a]) end + end end print(tab) - print(' Your card has ' .. read() .. ' UID number\n') - print(' Choice your dump number to write (from 1 until ' .. a .. ')') + print(' Your card has UID '..GetUID()) + print('') + print(' Select which dump to write (1 until '..num_dumps..')') print(tab) - io.write(' --> ') + io.write(' --> ') local no = tonumber(io.read()) - local dump = io.open('./hf-mf-' .. uid[no] .. '-data.eml', 'r'); + local dump = io.open('./hf-mf-' .. files[no] .. '-data.eml', 'r'); print(tab) - print(' You have been selected ' .. no .. ' card dump, it UID is ' .. uid[no]) - ---EML get B key from opened EML file + print(' You have been selected ' .. no .. ' card dump, with UID : '..files[no]) + + --- Load eml file for _ in dump:lines() do table.insert(eml, _); end + + --- Extract B key from EML file + local b = 0 for i = 1, #eml do + print('line is type: ', type(eml[i]) ) + if (i % 4 == 0) then repeat b = b + 1 - B[b] = string.sub(tostring(eml[i]), (string.len(eml[i]) - 11), - string.len(eml[i])) -- Cut key from block + -- Cut key from block + b_keys[b] = string.sub(tostring(eml[i]), (string.len(eml[i]) - 11), string.len(eml[i])) until b % 4 == 0 end end + print(tab) - print(tab) - ---UID Changing - if (utils.confirm(' Do the UID changing?') == true) then + --- Change UID on certain version of magic Gen3 card. + if (utils.confirm(' Change UID ?') == true) then wait() - core.console('hf 14a raw -s -c -t 2000 90f0cccc10' .. tostring(eml[1])) + core.console('hf 14a raw -s -c -t 2000 90f0cccc10'..tostring(eml[1])) print(tab) - print(' The new card UID is: ' .. read()) + print(' The new card UID : ' .. GetUID()) end - print(tab) - ---UID Blocking - if (utils.confirm(' Would you like to BLOCK the UID for any changing?') == true) then + + --- Lock UID + if (utils.confirm(' Permanent lock UID ? (card can never change uid again) ') == true) then wait() core.console('hf 14a raw -s -c -t 2000 90fd111100') end + print(tab) + + --- Writing blocks + local default_key = 'FFFFFFFFFFFF' + local default_key_blk = 'FFFFFFFFFFFF78778800FFFFFFFFFFFF' + local empty = string.rep('0', 32) + local cmd_wrbl = 'hf mf wrbl %d B %s %s' - print(tab) - ---Wriiting block - if (utils.confirm(' At this case are you using a Blank Card?') == true) then + if (utils.confirm(' Are you using a empty card with default key?') == true) then wait() for i = 1, #eml do - core.console('hf mf wrbl ' .. (i - 1) .. ' B ' .. fkey() .. ' ' .. - tostring(eml[i])) + core.console(string.format(cmd_wrbl, (i-1), default_key, eml[i])) end - print(tab) else print(tab) - if (utils.confirm( - ' Do you wishing DELETE ALL DATA and rewrite all keys to ' .. fkey() .. - '?') == true) then + if (utils.confirm(' Delete ALL data and write all keys to 0x'..default_key..' ?') == true) then wait() for i = 1, #eml do if (i % 4 == 0) then - core.console( - 'hf mf wrbl ' .. (i - 1) .. ' B ' .. tostring(B[i]) .. ' ' .. - fkey() .. '78778800' .. fkey()) + core.console(string.format(cmd_wrbl, (i-1), b_keys[i], default_key_blk)) else - core.console( - 'hf mf wrbl ' .. (i - 1) .. ' B ' .. tostring(B[i]) .. ' ' .. - string.rep('0', 32)) + core.console(string.format(cmd_wrbl, (i-1), b_keys[i], empty)) end end else + print(tab) + print('Writing to card') wait() for i = 1, #eml do - core.console('hf mf wrbl ' .. (i - 1) .. ' B ' .. tostring(B[i]) .. - ' ' .. tostring(eml[i])) + core.console(string.format(cmd_wrbl, (i-1), b_keys[i], eml[i])) end end end - finish() + dropfield() + print(tab) + print('Done') end -main(args) ----General thinks for the future: ----Add support another types of dumps: BIN, JSON ----Maybe it will be not only as `hf-writer`, like a universal dump manager. ----Add undependence from the operation system. At the moment code not working in Linux. ----Add more chinesse backdoors RAW commands for UID changing (find RAW for the 4 byte familiar chinese card, from native it soft: http://bit.ly/39VIDsU) ----Hide system messages when you writing a dumps, replace it to some of like [#####----------] 40% +main(args) From 3125812f93c3f5ca0a596b22c241fd7111907957 Mon Sep 17 00:00:00 2001 From: mwalker33 Date: Sat, 21 Mar 2020 20:08:11 +1100 Subject: [PATCH 1737/1854] Update cmdlfkeri.c Added clone for FC and CardID --- client/cmdlfkeri.c | 83 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 72 insertions(+), 11 deletions(-) diff --git a/client/cmdlfkeri.c b/client/cmdlfkeri.c index 982eb8193..2fa8181b3 100644 --- a/client/cmdlfkeri.c +++ b/client/cmdlfkeri.c @@ -30,13 +30,21 @@ static int CmdHelp(const char *Cmd); static int usage_lf_keri_clone(void) { PrintAndLogEx(NORMAL, "clone a KERI tag to a T55x7 tag."); PrintAndLogEx(NORMAL, "Usage: lf keri clone [h] "); + PrintAndLogEx(NORMAL, "Usage extended: lf keri clone [h] t [f ] i [Q5]"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h : This help"); PrintAndLogEx(NORMAL, " : Keri Internal ID"); PrintAndLogEx(NORMAL, " : specify write to Q5 (t5555 instead of t55x7)"); + // New format + PrintAndLogEx(NORMAL, " [m|i] : Type. m - MS, i - Internal ID"); + PrintAndLogEx(NORMAL, " : Facility Code"); + PrintAndLogEx(NORMAL, " : Card ID"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf keri clone 112233"); + PrintAndLogEx(NORMAL, " lf keri clone type ms fc 6 id 12345"); + PrintAndLogEx(NORMAL, " lf keri clone t m f 6 i 12345"); + return PM3_SUCCESS; } @@ -98,7 +106,7 @@ static int CmdKeriMSScramble (KeriMSScramble_t Action, uint32_t *FC, uint32_t *I } // Card FC if (CardToFC[CardIdx] < 32) { - if ((*ID & (1 << CardToFC[CardIdx])) > 0) + if ((*FC & (1 << CardToFC[CardIdx])) > 0) *CardID |= (1 << CardIdx); } } @@ -122,7 +130,7 @@ static int CmdKeriMSScramble (KeriMSScramble_t Action, uint32_t *FC, uint32_t *I // Bit 31 was fixed but not in check/parity bits *CardID |= (1 << 31); - PrintAndLogEx(SUCCESS, "Scrambled FC : %d - Card ID : %d to RAW : E0000000%08X",*FC,*ID,*CardID); + PrintAndLogEx(SUCCESS, "Scrambled MS : FC %d - Card ID %d to RAW : E0000000%08X",*FC,*ID,*CardID); } return PM3_SUCCESS; } @@ -192,10 +200,10 @@ static int CmdKeriDemod(const char *Cmd) { /* Scamble: For dev testing only, will/should move to the create keri-ms code when added. - - uint32_t testCard = 0; - CmdKeriMSScramble (Scramble,&fc,&cardid,&testCard); -*/ + */ + // uint32_t testCard = 0; + // CmdKeriMSScramble (Scramble,&fc,&cardid,&testCard); + // End Descramble test @@ -216,6 +224,11 @@ static int CmdKeriRead(const char *Cmd) { static int CmdKeriClone(const char *Cmd) { + uint8_t cmdptr = 0; + char format = 'r'; // default to raw + uint32_t fc = 0; + uint32_t cid = 0; + uint32_t cardid = 0; uint32_t internalid = 0; uint32_t blocks[3] = { T55x7_TESTMODE_DISABLED | @@ -233,8 +246,45 @@ static int CmdKeriClone(const char *Cmd) { char cmdp = tolower(param_getchar(Cmd, 0)); if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_keri_clone(); - internalid = param_get32ex(Cmd, 0, 0, 10); + // Assume old format for backwards compatibility and only parameter is the internal id + cid = param_get32ex(Cmd, 0, 0, 10); + // find other options + while (param_getchar(Cmd, cmdptr) != 0x00) { // && !errors) { + PrintAndLogEx (SUCCESS,"[%c]",param_getchar(Cmd, cmdptr)); + switch (tolower(param_getchar(Cmd, cmdptr))) { + case 'h': // help + return usage_lf_keri_clone(); + case 't': // format type + format = tolower(param_getchar(Cmd,cmdptr+1)); + cmdptr += 2; + break; + case 'f': // fc + fc = param_get32ex(Cmd,cmdptr+1,0,10); + cmdptr += 2; + break; + case 'c': // cardid + cid = param_get32ex(Cmd,cmdptr+1,0,10); + cmdptr += 2; + break; + case 'q': // q5 + blocks[0] = + T5555_MODULATION_PSK1 | + T5555_SET_BITRATE(128) | + T5555_PSK_RF_2 | + 2 << T5555_MAXBLOCK_SHIFT; + cmdptr++; + break; + default: + // Skip unknown + cmdptr++; + } + } + + // this is managed in above code + // internalid = param_get32ex(Cmd, 0, 0, 10); +/* + // Q5 is caught in the while loop //Q5 if (tolower(param_getchar(Cmd, 1)) == 'q') { blocks[0] = @@ -243,10 +293,21 @@ static int CmdKeriClone(const char *Cmd) { T5555_PSK_RF_2 | 2 << T5555_MAXBLOCK_SHIFT; } - - // MSB is ONE - internalid |= 0x80000000; - +*/ + // Setup card data + switch (format) { + case 'i' : // Internal ID + // MSB is ONE + internalid = cid | 0x80000000; + break; + case 'm' : // MS + cardid = 0; + CmdKeriMSScramble (Scramble,&fc,&cid,&cardid); + internalid = 0xE000000000000000 + cardid; + break; + } + + // Prepare and write to card // 3 LSB is ONE uint64_t data = ((uint64_t)internalid << 3) + 7; PrintAndLogEx(INFO, "Preparing to clone KERI to T55x7 with Internal Id: %" PRIx32, internalid); From 6440f4c5b0d6797607b14b322e5ac3f4f56dc817 Mon Sep 17 00:00:00 2001 From: mwalker33 Date: Sat, 21 Mar 2020 21:36:37 +1100 Subject: [PATCH 1738/1854] Update cmdlfkeri.c --- client/cmdlfkeri.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/cmdlfkeri.c b/client/cmdlfkeri.c index 2fa8181b3..9f292c091 100644 --- a/client/cmdlfkeri.c +++ b/client/cmdlfkeri.c @@ -30,7 +30,7 @@ static int CmdHelp(const char *Cmd); static int usage_lf_keri_clone(void) { PrintAndLogEx(NORMAL, "clone a KERI tag to a T55x7 tag."); PrintAndLogEx(NORMAL, "Usage: lf keri clone [h] "); - PrintAndLogEx(NORMAL, "Usage extended: lf keri clone [h] t [f ] i [Q5]"); + PrintAndLogEx(NORMAL, "Usage extended: lf keri clone [h] t [f ] c [Q5]"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h : This help"); PrintAndLogEx(NORMAL, " : Keri Internal ID"); @@ -225,7 +225,7 @@ static int CmdKeriRead(const char *Cmd) { static int CmdKeriClone(const char *Cmd) { uint8_t cmdptr = 0; - char format = 'r'; // default to raw + char format = 'i'; // default to raw uint32_t fc = 0; uint32_t cid = 0; uint32_t cardid = 0; @@ -294,7 +294,7 @@ static int CmdKeriClone(const char *Cmd) { 2 << T5555_MAXBLOCK_SHIFT; } */ - // Setup card data + // Setup card data/build internal id switch (format) { case 'i' : // Internal ID // MSB is ONE From 4175297f57af0d44b6a067276c52ac3990814486 Mon Sep 17 00:00:00 2001 From: mwalker33 Date: Sat, 21 Mar 2020 21:42:00 +1100 Subject: [PATCH 1739/1854] Update cmdlfkeri.c help update --- client/cmdlfkeri.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/client/cmdlfkeri.c b/client/cmdlfkeri.c index 9f292c091..a5d66caff 100644 --- a/client/cmdlfkeri.c +++ b/client/cmdlfkeri.c @@ -32,18 +32,18 @@ static int usage_lf_keri_clone(void) { PrintAndLogEx(NORMAL, "Usage: lf keri clone [h] "); PrintAndLogEx(NORMAL, "Usage extended: lf keri clone [h] t [f ] c [Q5]"); PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " h : This help"); - PrintAndLogEx(NORMAL, " : Keri Internal ID"); - PrintAndLogEx(NORMAL, " : specify write to Q5 (t5555 instead of t55x7)"); + PrintAndLogEx(NORMAL, " h : This help"); + PrintAndLogEx(NORMAL, " : Keri Internal ID"); + PrintAndLogEx(NORMAL, " : specify write to Q5 (t5555 instead of t55x7)"); // New format - PrintAndLogEx(NORMAL, " [m|i] : Type. m - MS, i - Internal ID"); - PrintAndLogEx(NORMAL, " : Facility Code"); - PrintAndLogEx(NORMAL, " : Card ID"); + PrintAndLogEx(NORMAL, " [m|i] : Type. m - MS, i - Internal ID"); + PrintAndLogEx(NORMAL, " : Facility Code"); + PrintAndLogEx(NORMAL, " : Card ID"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf keri clone 112233"); - PrintAndLogEx(NORMAL, " lf keri clone type ms fc 6 id 12345"); - PrintAndLogEx(NORMAL, " lf keri clone t m f 6 i 12345"); + PrintAndLogEx(NORMAL, " lf keri clone type ms fc 6 cardid 12345"); + PrintAndLogEx(NORMAL, " lf keri clone t m f 6 c 12345"); return PM3_SUCCESS; } From e80eb37b5e6e2080525cd8bf51a1e404072a1b6d Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 21 Mar 2020 12:34:58 +0100 Subject: [PATCH 1740/1854] more rework --- client/luascripts/hf-writer.lua | 88 +++++++++++++++++++++++---------- 1 file changed, 63 insertions(+), 25 deletions(-) diff --git a/client/luascripts/hf-writer.lua b/client/luascripts/hf-writer.lua index 010a0eb30..167c2e896 100644 --- a/client/luascripts/hf-writer.lua +++ b/client/luascripts/hf-writer.lua @@ -2,7 +2,7 @@ local utils = require('utils') local getopt = require('getopt') local read14a = require('read14a') -[[-- +--[[ ---Suggestions of improvement: --- Add support another types of dumps: BIN, JSON --- Maybe it will be not only as `mfc_gen3_writer`, like a universal dump manager. @@ -14,6 +14,7 @@ local read14a = require('read14a') -- doesn't take consideration filepaths for dump files. -- doesn't allow A keys for authenticating when writing -- doesn't verify that card is magic gen3. +-- doesn't take several versions of same dump ( -1, -2, -3 ) styles. --]] copyright = '' @@ -42,6 +43,34 @@ usage = [[ Select your *.eml dump from list to write to the card. ]] +-- Some globals +local DEBUG = false -- the debug flag + +------------------------------- +-- Some utilities +------------------------------- + +--- +-- A debug printout-function +local function dbg(args) + if not DEBUG then return end + if type(args) == 'table' then + local i = 1 + while args[i] do + dbg(args[i]) + i = i+1 + end + else + print('###', args) + end +end +--- +-- This is only meant to be used when errors occur +local function oops(err) + print('ERROR:', err) + core.clearCommandBuffer() + return nil, err +end --- -- Usage help local function help() @@ -49,6 +78,7 @@ local function help() print(author) print(version) print(desc) + print('Example usage') print(example) print(usage) end @@ -87,28 +117,31 @@ local function main(args) wait() print(tab) - local length = 23 - local e = 14 + local length = 25 + local e = 16 -- Detect 7 byte card if string.len(GetUID()) == 14 then - length = 29 - e = 20 + length = 31 + e = 22 end + dropfield() ---List all EML files in /client - for _ in io.popen([[dir ".\" /b]]):lines() do -- for UNIX: ls - - if string.find(_, '%.eml$') then - - if string.len(_) == length then -- The length of eml file - num_dumps = num_dumps + 1 - files[num_dumps] = string.sub(tostring(_), 7, e) -- Cut UID from eml file - print(' '..num_dumps..' | '..files[a]) - end - + local dumpEML = "find '.' -iname '*dump.eml' -type f" + local p = assert(io.popen(dumpEML)) + for _ in p:lines() do + + -- The length of eml file + if string.len(_) == length then + num_dumps = num_dumps + 1 + -- cut UID from eml file + files[num_dumps] = string.sub(_, 9, e) + print(' '..num_dumps..' | '..files[num_dumps]) end end + if num_dumps == 0 then return oops("Didn't find any dump files") end + print(tab) print(' Your card has UID '..GetUID()) print('') @@ -117,10 +150,10 @@ local function main(args) io.write(' --> ') local no = tonumber(io.read()) - local dump = io.open('./hf-mf-' .. files[no] .. '-data.eml', 'r'); + local dump = assert(io.open('./hf-mf-' .. files[no] .. '-dump.eml', 'r')) print(tab) - print(' You have been selected ' .. no .. ' card dump, with UID : '..files[no]) + print(' You have been selected card dump ' .. no .. ', with UID : '..files[no]) --- Load eml file for _ in dump:lines() do table.insert(eml, _); end @@ -128,22 +161,23 @@ local function main(args) --- Extract B key from EML file local b = 0 for i = 1, #eml do - print('line is type: ', type(eml[i]) ) - if (i % 4 == 0) then repeat b = b + 1 -- Cut key from block - b_keys[b] = string.sub(tostring(eml[i]), (string.len(eml[i]) - 11), string.len(eml[i])) + b_keys[b] = string.sub(eml[i], (#eml[i] - 11), #eml[i]) until b % 4 == 0 end end print(tab) + dbg(b_keys) + dbg(eml) --- Change UID on certain version of magic Gen3 card. if (utils.confirm(' Change UID ?') == true) then wait() - core.console('hf 14a raw -s -c -t 2000 90f0cccc10'..tostring(eml[1])) + --core.console('hf 14a raw -s -c -t 2000 90f0cccc10'..tostring(eml[1])) + print('hf 14a raw -s -c -t 2000 90f0cccc10'..tostring(eml[1])) print(tab) print(' The new card UID : ' .. GetUID()) end @@ -165,7 +199,8 @@ local function main(args) if (utils.confirm(' Are you using a empty card with default key?') == true) then wait() for i = 1, #eml do - core.console(string.format(cmd_wrbl, (i-1), default_key, eml[i])) + --core.console(string.format(cmd_wrbl, (i-1), default_key, eml[i])) + print(string.format(cmd_wrbl, (i-1), default_key, eml[i])) end else print(tab) @@ -173,9 +208,11 @@ local function main(args) wait() for i = 1, #eml do if (i % 4 == 0) then - core.console(string.format(cmd_wrbl, (i-1), b_keys[i], default_key_blk)) + --core.console(string.format(cmd_wrbl, (i-1), b_keys[i], default_key_blk)) + print(string.format(cmd_wrbl, (i-1), b_keys[i], default_key_blk)) else - core.console(string.format(cmd_wrbl, (i-1), b_keys[i], empty)) + --core.console(string.format(cmd_wrbl, (i-1), b_keys[i], empty)) + print(string.format(cmd_wrbl, (i-1), b_keys[i], empty)) end end else @@ -183,7 +220,8 @@ local function main(args) print('Writing to card') wait() for i = 1, #eml do - core.console(string.format(cmd_wrbl, (i-1), b_keys[i], eml[i])) + --core.console(string.format(cmd_wrbl, (i-1), b_keys[i], eml[i])) + print(string.format(cmd_wrbl, (i-1), b_keys[i], eml[i])) end end end From 80f79b10668b847b33ea108f49babc5b78573878 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 21 Mar 2020 12:37:40 +0100 Subject: [PATCH 1741/1854] swap to live execution --- client/luascripts/hf-writer.lua | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/client/luascripts/hf-writer.lua b/client/luascripts/hf-writer.lua index 167c2e896..76e7708e4 100644 --- a/client/luascripts/hf-writer.lua +++ b/client/luascripts/hf-writer.lua @@ -103,8 +103,9 @@ end local function main(args) -- Arguments for the script - for o, a in getopt.getopt(args, 'h') do + for o, a in getopt.getopt(args, 'hd') do if o == 'h' then return help() end + if o == 'd' then DEBUG = true end end local files = {} -- Array for eml files @@ -199,8 +200,7 @@ local function main(args) if (utils.confirm(' Are you using a empty card with default key?') == true) then wait() for i = 1, #eml do - --core.console(string.format(cmd_wrbl, (i-1), default_key, eml[i])) - print(string.format(cmd_wrbl, (i-1), default_key, eml[i])) + core.console(string.format(cmd_wrbl, (i-1), default_key, eml[i])) end else print(tab) @@ -208,11 +208,9 @@ local function main(args) wait() for i = 1, #eml do if (i % 4 == 0) then - --core.console(string.format(cmd_wrbl, (i-1), b_keys[i], default_key_blk)) - print(string.format(cmd_wrbl, (i-1), b_keys[i], default_key_blk)) + core.console(string.format(cmd_wrbl, (i-1), b_keys[i], default_key_blk)) else - --core.console(string.format(cmd_wrbl, (i-1), b_keys[i], empty)) - print(string.format(cmd_wrbl, (i-1), b_keys[i], empty)) + core.console(string.format(cmd_wrbl, (i-1), b_keys[i], empty)) end end else @@ -220,8 +218,7 @@ local function main(args) print('Writing to card') wait() for i = 1, #eml do - --core.console(string.format(cmd_wrbl, (i-1), b_keys[i], eml[i])) - print(string.format(cmd_wrbl, (i-1), b_keys[i], eml[i])) + core.console(string.format(cmd_wrbl, (i-1), b_keys[i], eml[i])) end end end From 9a2fc52a9284980b852187221a45d2bc0cc6ee00 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 21 Mar 2020 12:40:16 +0100 Subject: [PATCH 1742/1854] closing files are use... --- client/luascripts/hf-writer.lua | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/client/luascripts/hf-writer.lua b/client/luascripts/hf-writer.lua index 76e7708e4..c1812902d 100644 --- a/client/luascripts/hf-writer.lua +++ b/client/luascripts/hf-writer.lua @@ -140,6 +140,7 @@ local function main(args) print(' '..num_dumps..' | '..files[num_dumps]) end end + p.close() if num_dumps == 0 then return oops("Didn't find any dump files") end @@ -151,13 +152,13 @@ local function main(args) io.write(' --> ') local no = tonumber(io.read()) - local dump = assert(io.open('./hf-mf-' .. files[no] .. '-dump.eml', 'r')) - print(tab) print(' You have been selected card dump ' .. no .. ', with UID : '..files[no]) --- Load eml file - for _ in dump:lines() do table.insert(eml, _); end + local dumpfile = assert(io.open('./hf-mf-' .. files[no] .. '-dump.eml', 'r')) + for _ in dumpfile:lines() do table.insert(eml, _); end + dumpfile.close() --- Extract B key from EML file local b = 0 From 097595cdefdef75b0e266cda45360aaa9ba3aceb Mon Sep 17 00:00:00 2001 From: Artem Gnatyuk Date: Sat, 21 Mar 2020 21:27:57 +0700 Subject: [PATCH 1743/1854] [RDV4] Readed IDs store to file in spiffs --- armsrc/Standalone/lf_em4100rwc.c | 75 +++++++++++++++++++++++--------- 1 file changed, 54 insertions(+), 21 deletions(-) diff --git a/armsrc/Standalone/lf_em4100rwc.c b/armsrc/Standalone/lf_em4100rwc.c index a336112ba..08ab76cc1 100644 --- a/armsrc/Standalone/lf_em4100rwc.c +++ b/armsrc/Standalone/lf_em4100rwc.c @@ -5,12 +5,16 @@ // at your option, any later version. See the LICENSE.txt file for the text of // the license. //----------------------------------------------------------------------------- -// LF rwc - This mode can simulate tag ID from selected slot and read tag ID -// to selected slot and to flash (only RDV4). Also you can set -// predefined IDs in any slot. +// LF rwc - This mode can simulate ID from selected slot, read ID to +// selected slot, write from selected slot to T5555 tag and store +// readed ID to flash (only RDV4). Also you can set predefined IDs +// in any slot. // To recall stored ID from flash execute: -// mem dump o offset l 5 p -// where offset = 5 * selected slot +// mem spifss dump o emdump p +// or: +// mem spifss dump o emdump f emdump +// then from shell: +// hexdump emdump -e '5/1 "%02X" /0 "\n"' //----------------------------------------------------------------------------- #include "standalone.h" #include "proxmark3_arm.h" @@ -22,6 +26,7 @@ #include "ticks.h" #include "string.h" #include "BigBuf.h" +#include "spiffs.h" #ifdef WITH_FLASH #include "flashmem.h" @@ -33,13 +38,13 @@ // low & high - array for storage IDs. Its length must be equal. // Predefined IDs must be stored in low[]. // In high[] must be nulls -uint64_t low[] = {0x565AF781C7,0x540053E4E2,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +uint64_t low[] = {0x565AF781C7,0x540053E4E2,0x1234567890,0,0,0,0,0,0,0,0,0,0,0,0,0}; uint32_t high[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; uint8_t *bba,slots_count; int buflen; void ModInfo(void) { - DbpString(" LF EM4100 read/write/clone standalone mode"); + DbpString(" LF EM4100 simulate standalone V2"); } uint64_t ReversQuads(uint64_t bits){ @@ -99,11 +104,16 @@ void FlashLEDs(uint32_t speed, uint8_t times) { #ifdef WITH_FLASH void SaveIDtoFlash (int addr, uint64_t id) { - uint8_t b, *ptr; + uint8_t bt[5]; + char *filename = "emdump"; + rdv40_spiffs_mount(); for (int i = 0; i < 5; i++) { - b = (uint8_t) (id >> 8 * i & 0xff); - ptr = &b; - Flash_WriteData(addr * 5 + 4 - i,ptr,1); + bt[4-i] = (uint8_t) (id >> 8 * i & 0xff); + } + if (exists_in_spiffs(filename) == false){ + rdv40_spiffs_write(filename, &bt[0], 5, RDV40_SPIFFS_SAFETY_NORMAL); + } else { + rdv40_spiffs_append(filename, &bt[0], 5, RDV40_SPIFFS_SAFETY_NORMAL); } } #endif @@ -112,9 +122,10 @@ void RunMod() { StandAloneMode(); FpgaDownloadAndGo(FPGA_BITSTREAM_LF); int selected = 0; - //state 0 - select slot, + //state 0 - select slot // 1 - read tag to selected slot, // 2 - simulate tag from selected slot + // 3 - write to T5555 tag uint8_t state = 0; slots_count = sizeof(low)/sizeof(low[0]); bba = BigBuf_get_addr(); @@ -130,7 +141,7 @@ void RunMod() { if (button_pressed == 1) { // Long press - switch to simulate mode SpinUp(100); - SpinOff(100); + LED_Slot(selected); state = 2; } else if (button_pressed < 0) { // Click - switch to next slot @@ -139,13 +150,21 @@ void RunMod() { } break; case 1: - // Read mode. Click - exit to select mode - CmdEM410xdemod(1, &high[selected], &low[selected], 0); - FlashLEDs(100,5); - #ifdef WITH_FLASH - SaveIDtoFlash(selected, low[selected]); - #endif - state = 0; + // Read mode. + if (button_pressed > 0) { + // Long press - switch to read mode + SpinUp(100); + LED_Slot(selected); + state = 3; + } else if (button_pressed < 0) { + // Click - exit to select mode + CmdEM410xdemod(1, &high[selected], &low[selected], 0); + FlashLEDs(100,5); + #ifdef WITH_FLASH + SaveIDtoFlash(selected, low[selected]); + #endif + state = 0; + } break; case 2: // Simulate mode @@ -155,7 +174,7 @@ void RunMod() { LED_Slot(selected); state = 1; } else if (button_pressed < 0) { - // Click - start simulating. Click again to exit from simelate mode + // Click - start simulating. Click again to exit from simulate mode LED_Slot(selected); ConstructEM410xEmulBuf(ReversQuads(low[selected])); FlashLEDs(100,5); @@ -164,6 +183,20 @@ void RunMod() { state = 0; // Switch to select mode } break; + case 3: + // Write tag mode + if (button_pressed > 0) { + // Long press - switch to select mode + SpinDown(100); + LED_Slot(selected); + state = 0; + } else if (button_pressed < 0) { + // Click - write ID to tag + WriteEM410x(0, (uint32_t) (low[selected] >> 32), (uint32_t) (low[selected] & 0xffffffff)); + LED_Slot(selected); + state = 0; // Switch to select mode + } + break; } } } From c36d86bc010a50537d6e0a6b265ea1ee09c07c43 Mon Sep 17 00:00:00 2001 From: Artem Gnatyuk Date: Sat, 21 Mar 2020 21:39:30 +0700 Subject: [PATCH 1744/1854] Make style --- armsrc/Standalone/lf_em4100emul.c | 76 +++++----- armsrc/Standalone/lf_em4100rwc.c | 236 +++++++++++++++--------------- 2 files changed, 156 insertions(+), 156 deletions(-) diff --git a/armsrc/Standalone/lf_em4100emul.c b/armsrc/Standalone/lf_em4100emul.c index 907445912..f3939f923 100644 --- a/armsrc/Standalone/lf_em4100emul.c +++ b/armsrc/Standalone/lf_em4100emul.c @@ -23,36 +23,36 @@ #define CLOCK 64 //for 125kHz // low & high - array for storage IDs. Its length must be equal. -// Predefined IDs must be stored in low[]. +// Predefined IDs must be stored in low[]. // In high[] must be nulls -uint64_t low[] = {0x565A1140BE,0x365A398149,0x5555555555,0xFFFFFFFFFF}; -uint32_t high[] = {0,0,0,0}; -uint8_t *bba,slots_count; +uint64_t low[] = {0x565A1140BE, 0x365A398149, 0x5555555555, 0xFFFFFFFFFF}; +uint32_t high[] = {0, 0, 0, 0}; +uint8_t *bba, slots_count; int buflen; void ModInfo(void) { DbpString(" LF EM4100 simulator standalone mode"); } -uint64_t ReversQuads(uint64_t bits){ - uint64_t result = 0; - for (int i = 0; i < 16; i++){ - result += ((bits >> (60 - 4 *i)) & 0xf) << (4 * i); - } - return result >> 24; +uint64_t ReversQuads(uint64_t bits) { + uint64_t result = 0; + for (int i = 0; i < 16; i++) { + result += ((bits >> (60 - 4 * i)) & 0xf) << (4 * i); + } + return result >> 24; } void FillBuff(uint8_t bit) { - memset (bba + buflen, bit, CLOCK / 2); - buflen += (CLOCK / 2); - memset (bba + buflen, bit^1,CLOCK / 2); - buflen += (CLOCK / 2); + memset(bba + buflen, bit, CLOCK / 2); + buflen += (CLOCK / 2); + memset(bba + buflen, bit ^ 1, CLOCK / 2); + buflen += (CLOCK / 2); } void ConstructEM410xEmulBuf(uint64_t id) { - + int i, j, binary[4], parity[4]; - buflen = 0; + buflen = 0; for (i = 0; i < 9; i++) FillBuff(1); parity[0] = parity[1] = parity[2] = parity[3] = 0; @@ -60,39 +60,39 @@ void ConstructEM410xEmulBuf(uint64_t id) { for (j = 3; j >= 0; j--, id /= 2) binary[j] = id % 2; for (j = 0; j < 4; j++) - FillBuff(binary[j]); + FillBuff(binary[j]); FillBuff(binary[0] ^ binary[1] ^ binary[2] ^ binary[3]); for (j = 0; j < 4; j++) - parity[j] ^= binary[j]; + parity[j] ^= binary[j]; } - for (j = 0; j < 4; j++) - FillBuff(parity[j]); + for (j = 0; j < 4; j++) + FillBuff(parity[j]); FillBuff(0); } void LED_Slot(int i) { - LEDsoff(); - if (slots_count > 4) { - LED(i % MAX_IND, 0); //binary indication for slots_count > 4 - } else { - LED(1 << i,0); //simple indication for slots_count <=4 - } + LEDsoff(); + if (slots_count > 4) { + LED(i % MAX_IND, 0); //binary indication for slots_count > 4 + } else { + LED(1 << i, 0); //simple indication for slots_count <=4 + } } void RunMod() { StandAloneMode(); FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - int selected = 0; //selected slot after start - slots_count = sizeof(low)/sizeof(low[0]); - bba = BigBuf_get_addr(); - for (;;) { - WDT_HIT(); + int selected = 0; //selected slot after start + slots_count = sizeof(low) / sizeof(low[0]); + bba = BigBuf_get_addr(); + for (;;) { + WDT_HIT(); if (data_available()) break; - SpinDelay(100); - SpinUp(100); - LED_Slot(selected); - ConstructEM410xEmulBuf(ReversQuads(low[selected])); - SimulateTagLowFrequency(buflen, 0, true); - selected = (selected + 1) % slots_count; - } + SpinDelay(100); + SpinUp(100); + LED_Slot(selected); + ConstructEM410xEmulBuf(ReversQuads(low[selected])); + SimulateTagLowFrequency(buflen, 0, true); + selected = (selected + 1) % slots_count; + } } diff --git a/armsrc/Standalone/lf_em4100rwc.c b/armsrc/Standalone/lf_em4100rwc.c index 08ab76cc1..b7394db69 100644 --- a/armsrc/Standalone/lf_em4100rwc.c +++ b/armsrc/Standalone/lf_em4100rwc.c @@ -5,10 +5,10 @@ // at your option, any later version. See the LICENSE.txt file for the text of // the license. //----------------------------------------------------------------------------- -// LF rwc - This mode can simulate ID from selected slot, read ID to -// selected slot, write from selected slot to T5555 tag and store +// LF rwc - This mode can simulate ID from selected slot, read ID to +// selected slot, write from selected slot to T5555 tag and store // readed ID to flash (only RDV4). Also you can set predefined IDs -// in any slot. +// in any slot. // To recall stored ID from flash execute: // mem spifss dump o emdump p // or: @@ -36,36 +36,36 @@ #define CLOCK 64 //for 125kHz // low & high - array for storage IDs. Its length must be equal. -// Predefined IDs must be stored in low[]. +// Predefined IDs must be stored in low[]. // In high[] must be nulls -uint64_t low[] = {0x565AF781C7,0x540053E4E2,0x1234567890,0,0,0,0,0,0,0,0,0,0,0,0,0}; -uint32_t high[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; -uint8_t *bba,slots_count; +uint64_t low[] = {0x565AF781C7, 0x540053E4E2, 0x1234567890, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +uint32_t high[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +uint8_t *bba, slots_count; int buflen; void ModInfo(void) { DbpString(" LF EM4100 simulate standalone V2"); } -uint64_t ReversQuads(uint64_t bits){ - uint64_t result = 0; - for (int i = 0; i < 16; i++){ - result += ((bits >> (60 - 4 *i)) & 0xf) << (4 * i); - } - return result >> 24; +uint64_t ReversQuads(uint64_t bits) { + uint64_t result = 0; + for (int i = 0; i < 16; i++) { + result += ((bits >> (60 - 4 * i)) & 0xf) << (4 * i); + } + return result >> 24; } void FillBuff(uint8_t bit) { - memset (bba + buflen, bit, CLOCK / 2); - buflen += (CLOCK / 2); - memset (bba + buflen, bit^1,CLOCK / 2); - buflen += (CLOCK / 2); + memset(bba + buflen, bit, CLOCK / 2); + buflen += (CLOCK / 2); + memset(bba + buflen, bit ^ 1, CLOCK / 2); + buflen += (CLOCK / 2); } void ConstructEM410xEmulBuf(uint64_t id) { - + int i, j, binary[4], parity[4]; - buflen = 0; + buflen = 0; for (i = 0; i < 9; i++) FillBuff(1); parity[0] = parity[1] = parity[2] = parity[3] = 0; @@ -73,23 +73,23 @@ void ConstructEM410xEmulBuf(uint64_t id) { for (j = 3; j >= 0; j--, id /= 2) binary[j] = id % 2; for (j = 0; j < 4; j++) - FillBuff(binary[j]); + FillBuff(binary[j]); FillBuff(binary[0] ^ binary[1] ^ binary[2] ^ binary[3]); for (j = 0; j < 4; j++) - parity[j] ^= binary[j]; + parity[j] ^= binary[j]; } - for (j = 0; j < 4; j++) - FillBuff(parity[j]); + for (j = 0; j < 4; j++) + FillBuff(parity[j]); FillBuff(0); } void LED_Slot(int i) { - LEDsoff(); - if (slots_count > 4) { - LED(i % MAX_IND, 0); //binary indication, usefully for slots_count > 4 - } else { - LED(1 << i,0); //simple indication for slots_count <=4 - } + LEDsoff(); + if (slots_count > 4) { + LED(i % MAX_IND, 0); //binary indication, usefully for slots_count > 4 + } else { + LED(1 << i, 0); //simple indication for slots_count <=4 + } } void FlashLEDs(uint32_t speed, uint8_t times) { @@ -103,100 +103,100 @@ void FlashLEDs(uint32_t speed, uint8_t times) { } #ifdef WITH_FLASH -void SaveIDtoFlash (int addr, uint64_t id) { - uint8_t bt[5]; - char *filename = "emdump"; - rdv40_spiffs_mount(); - for (int i = 0; i < 5; i++) { - bt[4-i] = (uint8_t) (id >> 8 * i & 0xff); - } - if (exists_in_spiffs(filename) == false){ - rdv40_spiffs_write(filename, &bt[0], 5, RDV40_SPIFFS_SAFETY_NORMAL); - } else { - rdv40_spiffs_append(filename, &bt[0], 5, RDV40_SPIFFS_SAFETY_NORMAL); - } +void SaveIDtoFlash(int addr, uint64_t id) { + uint8_t bt[5]; + char *filename = "emdump"; + rdv40_spiffs_mount(); + for (int i = 0; i < 5; i++) { + bt[4 - i] = (uint8_t)(id >> 8 * i & 0xff); + } + if (exists_in_spiffs(filename) == false) { + rdv40_spiffs_write(filename, &bt[0], 5, RDV40_SPIFFS_SAFETY_NORMAL); + } else { + rdv40_spiffs_append(filename, &bt[0], 5, RDV40_SPIFFS_SAFETY_NORMAL); + } } #endif void RunMod() { StandAloneMode(); FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - int selected = 0; - //state 0 - select slot - // 1 - read tag to selected slot, - // 2 - simulate tag from selected slot - // 3 - write to T5555 tag - uint8_t state = 0; - slots_count = sizeof(low)/sizeof(low[0]); - bba = BigBuf_get_addr(); - LED_Slot(selected); - for (;;) { - WDT_HIT(); + int selected = 0; + //state 0 - select slot + // 1 - read tag to selected slot, + // 2 - simulate tag from selected slot + // 3 - write to T5555 tag + uint8_t state = 0; + slots_count = sizeof(low) / sizeof(low[0]); + bba = BigBuf_get_addr(); + LED_Slot(selected); + for (;;) { + WDT_HIT(); if (data_available()) break; - int button_pressed = BUTTON_HELD(1000); - SpinDelay(300); - switch (state){ - case 0: - // Select mode - if (button_pressed == 1) { - // Long press - switch to simulate mode - SpinUp(100); - LED_Slot(selected); - state = 2; - } else if (button_pressed < 0) { - // Click - switch to next slot - selected = (selected + 1) % slots_count; - LED_Slot(selected); - } - break; - case 1: - // Read mode. - if (button_pressed > 0) { - // Long press - switch to read mode - SpinUp(100); - LED_Slot(selected); - state = 3; - } else if (button_pressed < 0) { - // Click - exit to select mode - CmdEM410xdemod(1, &high[selected], &low[selected], 0); - FlashLEDs(100,5); - #ifdef WITH_FLASH - SaveIDtoFlash(selected, low[selected]); - #endif - state = 0; - } - break; - case 2: - // Simulate mode - if (button_pressed > 0) { - // Long press - switch to read mode - SpinDown(100); - LED_Slot(selected); - state = 1; - } else if (button_pressed < 0) { - // Click - start simulating. Click again to exit from simulate mode - LED_Slot(selected); - ConstructEM410xEmulBuf(ReversQuads(low[selected])); - FlashLEDs(100,5); - SimulateTagLowFrequency(buflen, 0, 1); - LED_Slot(selected); - state = 0; // Switch to select mode - } - break; - case 3: - // Write tag mode - if (button_pressed > 0) { - // Long press - switch to select mode - SpinDown(100); - LED_Slot(selected); - state = 0; - } else if (button_pressed < 0) { - // Click - write ID to tag - WriteEM410x(0, (uint32_t) (low[selected] >> 32), (uint32_t) (low[selected] & 0xffffffff)); - LED_Slot(selected); - state = 0; // Switch to select mode - } - break; - } - } + int button_pressed = BUTTON_HELD(1000); + SpinDelay(300); + switch (state) { + case 0: + // Select mode + if (button_pressed == 1) { + // Long press - switch to simulate mode + SpinUp(100); + LED_Slot(selected); + state = 2; + } else if (button_pressed < 0) { + // Click - switch to next slot + selected = (selected + 1) % slots_count; + LED_Slot(selected); + } + break; + case 1: + // Read mode. + if (button_pressed > 0) { + // Long press - switch to read mode + SpinUp(100); + LED_Slot(selected); + state = 3; + } else if (button_pressed < 0) { + // Click - exit to select mode + CmdEM410xdemod(1, &high[selected], &low[selected], 0); + FlashLEDs(100, 5); +#ifdef WITH_FLASH + SaveIDtoFlash(selected, low[selected]); +#endif + state = 0; + } + break; + case 2: + // Simulate mode + if (button_pressed > 0) { + // Long press - switch to read mode + SpinDown(100); + LED_Slot(selected); + state = 1; + } else if (button_pressed < 0) { + // Click - start simulating. Click again to exit from simulate mode + LED_Slot(selected); + ConstructEM410xEmulBuf(ReversQuads(low[selected])); + FlashLEDs(100, 5); + SimulateTagLowFrequency(buflen, 0, 1); + LED_Slot(selected); + state = 0; // Switch to select mode + } + break; + case 3: + // Write tag mode + if (button_pressed > 0) { + // Long press - switch to select mode + SpinDown(100); + LED_Slot(selected); + state = 0; + } else if (button_pressed < 0) { + // Click - write ID to tag + WriteEM410x(0, (uint32_t)(low[selected] >> 32), (uint32_t)(low[selected] & 0xffffffff)); + LED_Slot(selected); + state = 0; // Switch to select mode + } + break; + } + } } From 0abba96eb6605c90682eb4290a2aaa3617e82ebc Mon Sep 17 00:00:00 2001 From: Artem Gnatyuk Date: Sun, 22 Mar 2020 00:03:16 +0700 Subject: [PATCH 1745/1854] Add my modes after merging. --- armsrc/Standalone/Makefile.hal | 13 +++++++++---- armsrc/Standalone/Makefile.inc | 8 ++++++++ armsrc/Standalone/lf_em4100rwc.c | 2 +- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/armsrc/Standalone/Makefile.hal b/armsrc/Standalone/Makefile.hal index fd52817db..5c2352aaf 100644 --- a/armsrc/Standalone/Makefile.hal +++ b/armsrc/Standalone/Makefile.hal @@ -35,19 +35,24 @@ define KNOWN_STANDALONE_DEFINITIONS | HF_BOG | 14a sniff with ULC/ULEV1/NTAG auth | | (RDV4 only) | storing in flashmem - Bogito | +----------------------------------------------------------+ +| HF_14ASNIFF | 14a sniff to flashmem | +| (RDV4 only) | | ++----------------------------------------------------------+ +| LF_ICEHID | LF HID collector to flashmem | +| (RDV4 only) | | ++----------------------------------------------------------+ | LF_EM4100EMUL | Simulate predefined em4100 tags only | | | | +----------------------------------------------------------+ | LF_EM4100RWC | Read/simulate em4100 tags & clone it | | | to T555x tags | +----------------------------------------------------------+ - endef -STANDALONE_MODES := LF_SAMYRUN LF_ICERUN LF_PROXBRUTE LF_HIDBRUTE LF_EM4100EMUL LF_EM4100RWC -STANDALONE_MODES += HF_YOUNG HF_MATTYRUN HF_COLIN HF_BOG +STANDALONE_MODES := LF_SAMYRUN LF_ICERUN LF_PROXBRUTE LF_HIDBRUTE LF_ICEHID LF_EM4100EMUL LF_EM4100RWC +STANDALONE_MODES += HF_YOUNG HF_MATTYRUN HF_COLIN HF_BOG HF_14ASNIFF STANDALONE_MODES_REQ_SMARTCARD := -STANDALONE_MODES_REQ_FLASH := HF_COLIN HF_BOG +STANDALONE_MODES_REQ_FLASH := HF_COLIN HF_BOG HF_14ASNIFF LF_ICEHID ifneq ($(filter $(STANDALONE),$(STANDALONE_MODES)),) STANDALONE_PLATFORM_DEFS += -DWITH_STANDALONE_$(STANDALONE) ifneq ($(filter $(STANDALONE),$(STANDALONE_MODES_REQ_SMARTCARD)),) diff --git a/armsrc/Standalone/Makefile.inc b/armsrc/Standalone/Makefile.inc index 686cc66f0..e5a3304a8 100644 --- a/armsrc/Standalone/Makefile.inc +++ b/armsrc/Standalone/Makefile.inc @@ -33,6 +33,14 @@ endif ifneq (,$(findstring WITH_STANDALONE_HF_BOG,$(APP_CFLAGS))) SRC_STANDALONE = hf_bog.c endif +# WITH_STANDALONE_HF_14ASNIFF +ifneq (,$(findstring WITH_STANDALONE_HF_14ASNIFF,$(APP_CFLAGS))) + SRC_STANDALONE = hf_14asniff.c +endif +# WITH_STANDALONE_LF_ICEHID +ifneq (,$(findstring WITH_STANDALONE_LF_ICEHID,$(APP_CFLAGS))) + SRC_STANDALONE = lf_icehid.c +endif # WITH_STANDALONE_LF_EM4100EMUL ifneq (,$(findstring WITH_STANDALONE_LF_EM4100EMUL,$(APP_CFLAGS))) SRC_STANDALONE = lf_em4100emul.c diff --git a/armsrc/Standalone/lf_em4100rwc.c b/armsrc/Standalone/lf_em4100rwc.c index b7394db69..a2414a6fa 100644 --- a/armsrc/Standalone/lf_em4100rwc.c +++ b/armsrc/Standalone/lf_em4100rwc.c @@ -44,7 +44,7 @@ uint8_t *bba, slots_count; int buflen; void ModInfo(void) { - DbpString(" LF EM4100 simulate standalone V2"); + DbpString(" LF EM4100 read/write/clone mode"); } uint64_t ReversQuads(uint64_t bits) { From 7e97062381da5c049f7605055bd617f94e466e55 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 21 Mar 2020 20:18:42 +0100 Subject: [PATCH 1746/1854] change for bionic only to zero out if set --- client/comms.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/client/comms.c b/client/comms.c index 7a9086873..a551e59e3 100644 --- a/client/comms.c +++ b/client/comms.c @@ -671,7 +671,13 @@ void CloseProxmark(void) { // Clean up our state sp = NULL; +#ifdef __BIONIC__ + if (communication_thread != 0) { + memset(&communication_thread, 0, sizeof(pthread_t)); + } +#else memset(&communication_thread, 0, sizeof(pthread_t)); +#endif session.pm3_present = false; } From 5ceb83673fd44777456ef7201a96b9dc2504a572 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 21 Mar 2020 20:34:57 +0100 Subject: [PATCH 1747/1854] save json, added basic support for 14b/15/t555/legic --- client/fileutils.c | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/client/fileutils.c b/client/fileutils.c index f47e32b73..3343ebc05 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -233,6 +233,7 @@ out: int saveFileJSON(const char *preferredName, JSONFileType ftype, uint8_t *data, size_t datalen) { if (data == NULL) return PM3_EINVARG; + char *fileName = newfilenamemcopy(preferredName, ".json"); if (fileName == NULL) return PM3_EMALLOC; @@ -368,10 +369,34 @@ int saveFileJSON(const char *preferredName, JSONFileType ftype, uint8_t *data, s } break; } - case jsf14b: - case jsf15: - case jsfLegic: - case jsfT5555: + case jsf14b: { + JsonSaveStr(root, "FileType", "14b"); + JsonSaveBufAsHexCompact(root, "raw", data, datalen); + break; + } + case jsf15: { + JsonSaveStr(root, "FileType", "15693"); + JsonSaveBufAsHexCompact(root, "raw", data, datalen); + break; + } + case jsfLegic: { + JsonSaveStr(root, "FileType", "legic"); + JsonSaveBufAsHexCompact(root, "raw", data, datalen); + break; + } + case jsfT5555: { + JsonSaveStr(root, "FileType", "t5555"); + uint8_t conf[4] = {0}; + memcpy(conf, data, 4); + JsonSaveBufAsHexCompact(root, "$.Card.ConfigBlock", conf, sizeof(conf)); + + for (size_t i = 0; i < (datalen / 4); i++) { + char path[PATH_MAX_LENGTH] = {0}; + sprintf(path, "$.blocks.%zu", i); + JsonSaveBufAsHexCompact(root, path, data + (i * 4), 4); + } + break; + } case jsfMfPlusKeys: JsonSaveStr(root, "FileType", "mfp"); JsonSaveBufAsHexCompact(root, "$.Card.UID", &data[0], 7); From dd3bd72af461d07963be62b47ca587665be2c425 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 21 Mar 2020 20:38:58 +0100 Subject: [PATCH 1748/1854] chg: 'hf 15 dump' - add basic json format when saving\nchg: 'hf 15 restore' - match file template to hf-(tyoe)-(uid)-dump.(extension) --- client/cmdhf15.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/client/cmdhf15.c b/client/cmdhf15.c index 9a5665a31..9b0b8dbf1 100644 --- a/client/cmdhf15.c +++ b/client/cmdhf15.c @@ -399,7 +399,7 @@ static int usage_15_restore(void) { {"-2", "use slower '1 out of 256' mode"}, {"-o", "set OPTION Flag (needed for TI)"}, {"r ", "numbers of retries on error, default is 3"}, - {"u ", "load hf-15-dump-.bin"}, + {"u ", "load hf-15--dump.bin"}, {"f ", "load "}, {"b ", "block size, default is 4"} }; @@ -1214,8 +1214,9 @@ static int CmdHF15Dump(const char *Cmd) { PrintAndLogEx(NORMAL, "\n"); size_t datalen = blocknum * 4; + saveFile(filename, ".bin", data, datalen); saveFileEML(filename, data, datalen, 4); - saveFile(filename, ".bin", data, datalen); + saveFileJSON(filename, jsf15, data, datalen); return PM3_SUCCESS; } @@ -1603,7 +1604,7 @@ static int CmdHF15Restore(const char *Cmd) { case 'u': param_getstr(Cmd, cmdp + 1, buff, FILE_PATH_SIZE); cmdp++; - snprintf(filename, sizeof(filename), "hf-15-dump-%s-bin", buff); + snprintf(filename, sizeof(filename), "hf-15-%s-dump.bin", buff); break; case 'h': return usage_15_restore(); @@ -1622,6 +1623,7 @@ static int CmdHF15Restore(const char *Cmd) { } if ((f = fopen(filename, "rb")) == NULL) { + PrintAndLogEx(WARNING, "Could not find file %s", filename); return PM3_EFILE; } From 64e027faf70bff8fa5d3e3046a675aa6cd45b44b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 21 Mar 2020 20:58:20 +0100 Subject: [PATCH 1749/1854] chg: unify dump file template used in this repo. hf-mf-(uid)-dump.(bin/eml/json) is the prefeered style. --- client/cmdhficlass.c | 4 ++-- client/cmdhfmf.c | 18 +++++++++--------- client/cmdlfem4x.c | 2 +- client/cmdlft55xx.c | 4 ++-- client/luascripts/mifare_autopwn.lua | 2 +- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 827cbcc38..1dccaef5c 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -898,7 +898,7 @@ static int CmdHFiClassDecrypt(const char *Cmd) { return PM3_EMALLOC; } strcat(fptr, "hf-iclass-"); - FillFileNameByUID(fptr, hdr->csn, "-data-decrypted", sizeof(hdr->csn)); + FillFileNameByUID(fptr, hdr->csn, "-dump-decrypted", sizeof(hdr->csn)); saveFile(fptr, ".bin", decrypted, decryptedlen); saveFileEML(fptr, decrypted, decryptedlen, 8); @@ -1361,7 +1361,7 @@ static int CmdHFiClassReader_Dump(const char *Cmd) { if (filename[0] == 0) { //Use the first block (CSN) for filename strcat(filename, "hf-iclass-"); - FillFileNameByUID(filename, tag_data, "-data", 8); + FillFileNameByUID(filename, tag_data, "-dump", 8); } // save the dump to .bin file diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 77278ee9a..6425e10a3 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -300,15 +300,15 @@ static int usage_hf14_restore(void) { PrintAndLogEx(NORMAL, "Usage: hf mf restore [card memory] u k f "); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K"); - PrintAndLogEx(NORMAL, " u : uid, try to restore from hf-mf--key.bin and hf-mf--data.bin"); + PrintAndLogEx(NORMAL, " u : uid, try to restore from hf-mf--key.bin and hf-mf--dump.bin"); PrintAndLogEx(NORMAL, " k : key filename, specific the full filename of key file"); PrintAndLogEx(NORMAL, " f : data filename, specific the full filename of data file"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf mf restore -- read the UID from tag first, then restore from hf-mf--key.bin and and hf-mf--data.bin"); - PrintAndLogEx(NORMAL, " hf mf restore 1 u 12345678 -- restore from hf-mf-12345678-key.bin and hf-mf-12345678-data.bin"); - PrintAndLogEx(NORMAL, " hf mf restore 1 u 12345678 k dumpkey.bin -- restore from dumpkey.bin and hf-mf-12345678-data.bin"); - PrintAndLogEx(NORMAL, " hf mf restore 4 -- read the UID from tag with 4K memory first, then restore from hf-mf--key.bin and and hf-mf--data.bin"); + PrintAndLogEx(NORMAL, " hf mf restore -- read the UID from tag first, then restore from hf-mf--key.bin and and hf-mf--dump.bin"); + PrintAndLogEx(NORMAL, " hf mf restore 1 u 12345678 -- restore from hf-mf-12345678-key.bin and hf-mf-12345678-dump.bin"); + PrintAndLogEx(NORMAL, " hf mf restore 1 u 12345678 k dumpkey.bin -- restore from dumpkey.bin and hf-mf-12345678-dump.bin"); + PrintAndLogEx(NORMAL, " hf mf restore 4 -- read the UID from tag with 4K memory first, then restore from hf-mf--key.bin and and hf-mf--dump.bin"); return PM3_SUCCESS; } static int usage_hf14_decryptbytes(void) { @@ -1064,7 +1064,7 @@ static int CmdHF14AMfDump(const char *Cmd) { PrintAndLogEx(SUCCESS, "\nSucceeded in dumping all blocks"); if (strlen(dataFilename) < 1) { - fptr = GenerateFilename("hf-mf-", "-data"); + fptr = GenerateFilename("hf-mf-", "-dump"); if (fptr == NULL) return PM3_ESOFT; @@ -1103,7 +1103,7 @@ static int CmdHF14AMfRestore(const char *Cmd) { if (keyFilename[0] == 0x00) snprintf(keyFilename, FILE_PATH_SIZE, "hf-mf-%s-key.bin", szTemp); if (dataFilename[0] == 0x00) - snprintf(dataFilename, FILE_PATH_SIZE, "hf-mf-%s-data.bin", szTemp); + snprintf(dataFilename, FILE_PATH_SIZE, "hf-mf-%s-dump.bin", szTemp); cmdp += 2; break; case 'k': @@ -1161,7 +1161,7 @@ static int CmdHF14AMfRestore(const char *Cmd) { fclose(fkeys); if (dataFilename[0] == 0x00) { - fptr = GenerateFilename("hf-mf-", "-data.bin"); + fptr = GenerateFilename("hf-mf-", "-dump.bin"); if (fptr == NULL) return 1; @@ -2507,7 +2507,7 @@ all_found: return PM3_ETIMEOUT; } - fnameptr = GenerateFilename("hf-mf-", "-data"); + fnameptr = GenerateFilename("hf-mf-", "-dump"); if (fnameptr == NULL) { free(dump); free(e_sector); diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c index e759a4cf3..841f26652 100644 --- a/client/cmdlfem4x.c +++ b/client/cmdlfem4x.c @@ -1349,7 +1349,7 @@ static int CmdEM4x05Dump(const char *Cmd) { // saveFileEML will add .eml extension to filename // saveFile (binary) passes in the .bin extension. if (strcmp(preferredName, "") == 0) // Set default filename, if not set by user - sprintf(preferredName, "lf-4x05-%08X-data", BSWAP_32(data[1])); + sprintf(preferredName, "lf-4x05-%08X-dump", BSWAP_32(data[1])); saveFileEML(preferredName, (uint8_t *)data, 16 * sizeof(uint32_t), sizeof(uint32_t)); saveFile(preferredName, ".bin", data, sizeof(data)); diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index c88b8a051..fafb5d2da 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -202,7 +202,7 @@ static int usage_t55xx_restore() { PrintAndLogEx(NORMAL, _YELLOW_(" Assumes lf t55 detect has been run first!")); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " lf t55xx restore f lf-t55xx-00148040-data.bin"); + PrintAndLogEx(NORMAL, " lf t55xx restore f lf-t55xx-00148040-dump.bin"); PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } @@ -2315,7 +2315,7 @@ static int CmdT55xxDump(const char *Cmd) { else break; } - strcat(preferredName, "-data"); + strcat(preferredName, "-dump"); } // Swap endian so the files match the txt display diff --git a/client/luascripts/mifare_autopwn.lua b/client/luascripts/mifare_autopwn.lua index 624cea419..bc7582760 100644 --- a/client/luascripts/mifare_autopwn.lua +++ b/client/luascripts/mifare_autopwn.lua @@ -115,7 +115,7 @@ local function dump_tag(uid, numsectors) if utils.confirm('Do you wish to create a memory dump of tag?') then - local dumpfile = 'hf-mf-'..uid..'-data' + local dumpfile = 'hf-mf-'..uid..'-dump' local dmp = ('hf mf dump %s f %s'):format(typ, dumpfile) core.console(dmp) From fc1c133c46aefc65dae10eb4fe81b39cd847c610 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 21 Mar 2020 23:13:41 +0100 Subject: [PATCH 1750/1854] fix: script hf_bruteforce - ensure zeropadding --- client/luascripts/hf_bruteforce.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/luascripts/hf_bruteforce.lua b/client/luascripts/hf_bruteforce.lua index ff8ba6764..485d72809 100644 --- a/client/luascripts/hf_bruteforce.lua +++ b/client/luascripts/hf_bruteforce.lua @@ -96,10 +96,10 @@ local function main(args) local command = '' if mftype == 'mfc' then - command = 'hf 14a sim t 1 u %14X' + command = 'hf 14a sim t 1 u %014x' msg('Bruteforcing Mifare Classic card numbers') elseif mftype == 'mfu' then - command = 'hf 14a sim t 2 u %14X' + command = 'hf 14a sim t 2 u %014x' msg('Bruteforcing Mifare Ultralight card numbers') else return print(usage) From dfe36a2d606f41898867103ba509a48add38fecf Mon Sep 17 00:00:00 2001 From: mwalker33 Date: Sun, 22 Mar 2020 11:55:38 +1100 Subject: [PATCH 1751/1854] Update cmdlfkeri.c Code clean and tune --- client/cmdlfkeri.c | 41 ++++++++++++++--------------------------- 1 file changed, 14 insertions(+), 27 deletions(-) diff --git a/client/cmdlfkeri.c b/client/cmdlfkeri.c index a5d66caff..8bc3c7e54 100644 --- a/client/cmdlfkeri.c +++ b/client/cmdlfkeri.c @@ -197,15 +197,6 @@ static int CmdKeriDemod(const char *Cmd) { CmdKeriMSScramble (Descramble,&fc,&cardid,&raw2); PrintAndLogEx (SUCCESS,"Descrambled MS : FC %d - Card ID %d\n",fc,cardid); - -/* - Scamble: For dev testing only, will/should move to the create keri-ms code when added. - */ - // uint32_t testCard = 0; - // CmdKeriMSScramble (Scramble,&fc,&cardid,&testCard); - - -// End Descramble test if (invert) { PrintAndLogEx(INFO, "Had to Invert - probably KERI"); @@ -224,11 +215,10 @@ static int CmdKeriRead(const char *Cmd) { static int CmdKeriClone(const char *Cmd) { - uint8_t cmdptr = 0; - char format = 'i'; // default to raw + uint8_t cmdidx = 0; + char keritype = 'i'; // default to internalid uint32_t fc = 0; uint32_t cid = 0; - uint32_t cardid = 0; uint32_t internalid = 0; uint32_t blocks[3] = { T55x7_TESTMODE_DISABLED | @@ -250,22 +240,21 @@ static int CmdKeriClone(const char *Cmd) { cid = param_get32ex(Cmd, 0, 0, 10); // find other options - while (param_getchar(Cmd, cmdptr) != 0x00) { // && !errors) { - PrintAndLogEx (SUCCESS,"[%c]",param_getchar(Cmd, cmdptr)); - switch (tolower(param_getchar(Cmd, cmdptr))) { + while (param_getchar(Cmd, cmdidx) != 0x00) { // && !errors) { + switch (tolower(param_getchar(Cmd, cmdidx))) { case 'h': // help return usage_lf_keri_clone(); case 't': // format type - format = tolower(param_getchar(Cmd,cmdptr+1)); - cmdptr += 2; + keritype = tolower(param_getchar(Cmd,cmdidx+1)); + cmdidx += 2; break; case 'f': // fc - fc = param_get32ex(Cmd,cmdptr+1,0,10); - cmdptr += 2; + fc = param_get32ex(Cmd,cmdidx+1,0,10); + cmdidx += 2; break; case 'c': // cardid - cid = param_get32ex(Cmd,cmdptr+1,0,10); - cmdptr += 2; + cid = param_get32ex(Cmd,cmdidx+1,0,10); + cmdidx += 2; break; case 'q': // q5 blocks[0] = @@ -273,11 +262,11 @@ static int CmdKeriClone(const char *Cmd) { T5555_SET_BITRATE(128) | T5555_PSK_RF_2 | 2 << T5555_MAXBLOCK_SHIFT; - cmdptr++; + cmdidx++; break; default: // Skip unknown - cmdptr++; + cmdidx++; } } @@ -295,15 +284,13 @@ static int CmdKeriClone(const char *Cmd) { } */ // Setup card data/build internal id - switch (format) { + switch (keritype) { case 'i' : // Internal ID // MSB is ONE internalid = cid | 0x80000000; break; case 'm' : // MS - cardid = 0; - CmdKeriMSScramble (Scramble,&fc,&cid,&cardid); - internalid = 0xE000000000000000 + cardid; + CmdKeriMSScramble (Scramble,&fc,&cid,&internalid); break; } From 1df6782312b61332a9a438e857527093585d75bc Mon Sep 17 00:00:00 2001 From: mwalker33 Date: Sun, 22 Mar 2020 17:47:35 +1100 Subject: [PATCH 1752/1854] Update cmdlfkeri.c Card ID change to CN/Card Number --- client/cmdlfkeri.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/cmdlfkeri.c b/client/cmdlfkeri.c index 8bc3c7e54..ced67ad86 100644 --- a/client/cmdlfkeri.c +++ b/client/cmdlfkeri.c @@ -38,11 +38,11 @@ static int usage_lf_keri_clone(void) { // New format PrintAndLogEx(NORMAL, " [m|i] : Type. m - MS, i - Internal ID"); PrintAndLogEx(NORMAL, " : Facility Code"); - PrintAndLogEx(NORMAL, " : Card ID"); + PrintAndLogEx(NORMAL, " : Card Number"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf keri clone 112233"); - PrintAndLogEx(NORMAL, " lf keri clone type ms fc 6 cardid 12345"); + PrintAndLogEx(NORMAL, " lf keri clone type ms fc 6 cn 12345"); PrintAndLogEx(NORMAL, " lf keri clone t m f 6 c 12345"); return PM3_SUCCESS; @@ -130,7 +130,7 @@ static int CmdKeriMSScramble (KeriMSScramble_t Action, uint32_t *FC, uint32_t *I // Bit 31 was fixed but not in check/parity bits *CardID |= (1 << 31); - PrintAndLogEx(SUCCESS, "Scrambled MS : FC %d - Card ID %d to RAW : E0000000%08X",*FC,*ID,*CardID); + PrintAndLogEx(SUCCESS, "Scrambled MS : FC %d - CN %d to RAW : E0000000%08X",*FC,*ID,*CardID); } return PM3_SUCCESS; } @@ -196,7 +196,7 @@ static int CmdKeriDemod(const char *Cmd) { // Just need to the low 32 bits without the 111 trailer CmdKeriMSScramble (Descramble,&fc,&cardid,&raw2); - PrintAndLogEx (SUCCESS,"Descrambled MS : FC %d - Card ID %d\n",fc,cardid); + PrintAndLogEx (SUCCESS,"Descrambled MS : FC %d - CN %d\n",fc,cardid); if (invert) { PrintAndLogEx(INFO, "Had to Invert - probably KERI"); From 8319b18bc76b62add81a8475417d8884ed9b82f5 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 22 Mar 2020 08:10:10 +0100 Subject: [PATCH 1753/1854] chg: hf mf sim - adapt number of sectors to print on type --- client/cmdhfmf.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 6425e10a3..89519b282 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -3217,18 +3217,22 @@ static int CmdHF14AMfSim(const char *Cmd) { case 0: flags |= FLAG_MF_MINI; sprintf(csize, "MINI"); + k_sectorsCount = MIFARE_MINI_MAXSECTOR; break; case 1: flags |= FLAG_MF_1K; sprintf(csize, "1K"); + k_sectorsCount = MIFARE_1K_MAXSECTOR; break; case 2: flags |= FLAG_MF_2K; sprintf(csize, "2K with RATS"); + k_sectorsCount = MIFARE_2K_MAXSECTOR; break; case 4: flags |= FLAG_MF_4K; sprintf(csize, "4K"); + k_sectorsCount = MIFARE_4K_MAXSECTOR; break; default: PrintAndLogEx(WARNING, "Unknown parameter for option t"); @@ -3342,6 +3346,8 @@ static int CmdHF14AMfSim(const char *Cmd) { } showSectorTable(); } + + k_sectorsCount = MIFARE_4K_MAXSECTOR; return PM3_SUCCESS; } /* From 371e534ad422ec2791c81aa0beb08161585b352d Mon Sep 17 00:00:00 2001 From: mwalker33 Date: Sun, 22 Mar 2020 21:05:27 +1100 Subject: [PATCH 1754/1854] Update CHANGELOG.md Keri MS support --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a36b58da..f4eeee148 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Added keri MS decode/encode and update 'lf keri clone' to support MS fc/cid cloning. (@mwalker33) - Added `hf lto restore` - restore LTO cartridge memory from dump file [.bin|.eml] (@Kevin-Nakamoto) - Added `LF_ICEHID` standalone mode which searches for lf HID credentials and store to RDV4 flashmem (@iceman1001) - Added `HF_14ASNIFF` standalone mode with storing trace to RDV4 flashmem (@micolous) From d6f6f810944ab614ab71f0da883770eccd4f724b Mon Sep 17 00:00:00 2001 From: BarikMana <42164118+BarikMana@users.noreply.github.com> Date: Sun, 22 Mar 2020 23:44:06 +0900 Subject: [PATCH 1755/1854] Bosch Solution 6000 Key Sector 0 Key A&B Works with any Bosch Solution 6000 PR11xB reader. --- client/dictionaries/mfc_default_keys.dic | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index b3dfbd128..4682ad0e5 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -1108,3 +1108,5 @@ fe04ecfe5577 # # unknown hotel key 6d9b485a4845 +# +5a7a52d5e20d # Bosch Solution 6000 From bc6de92771cddda46071e835b095d8f325a86389 Mon Sep 17 00:00:00 2001 From: Robert Quattlebaum Date: Mon, 23 Mar 2020 21:32:20 -0700 Subject: [PATCH 1756/1854] Updates to the Tesla AIDs Now includes the AIDs that are used in the key fob and phone. Removed some AIDs that can't be selected. --- client/resources/aidlist.json | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/client/resources/aidlist.json b/client/resources/aidlist.json index 13e140e49..ddf844023 100644 --- a/client/resources/aidlist.json +++ b/client/resources/aidlist.json @@ -2128,27 +2128,19 @@ "Type": "EMV" }, { - "AID": "7465736C6153746F7265303032", + "AID": "7465736C614C6F6769633", "Vendor": "Tesla", "Country": "", - "Name": "teslaStore002", - "Description": "Tesla car key", + "Name": "teslaLogic (Original AID)", + "Description": "Key for Tesla vehicles", "Type": "Tesla" }, { - "AID": "7465736C614C6F67696330303201", + "AID": "F465736C614C6F6769633", "Vendor": "Tesla", "Country": "", - "Name": "teslaLogic002", - "Description": "Tesla car key", - "Type": "Tesla" - }, - { - "AID": "7465736C61", - "Vendor": "Tesla", - "Country": "", - "Name": "tesla", - "Description": "Tesla car key generic AID", + "Name": "teslaLogic (Alternate AID)", + "Description": "Key for Tesla vehicles", "Type": "Tesla" } -] \ No newline at end of file +] From 1e37c577294edd73f386f9484d9bba3a4241ebed Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 24 Mar 2020 09:50:17 +0100 Subject: [PATCH 1757/1854] chg: hf mfdes info - adapted to support multiple keys --- client/cmdhfmfdes.c | 55 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 49 insertions(+), 6 deletions(-) diff --git a/client/cmdhfmfdes.c b/client/cmdhfmfdes.c index 5ab35a12d..697ec596e 100644 --- a/client/cmdhfmfdes.c +++ b/client/cmdhfmfdes.c @@ -26,8 +26,32 @@ uint8_t key_ones_data[16] = { 0x01 }; uint8_t key_defa_data[16] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }; uint8_t key_picc_data[16] = { 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f }; + +typedef enum { + UNKNOWN = 0, + MF3ICD40, + EV1, + EV2, + LIGHT, +} desfire_cardtype_t; + + static int CmdHelp(const char *Cmd); +static desfire_cardtype_t getCardType(uint8_t major, uint8_t minor) { + + if (major == 0x00) + return MF3ICD40; + else if (major == 0x01 && minor == 0x00) + return EV1; + else if (major == 0x12 && minor == 0x00) + return EV2; + else if (major == 0x30 && minor == 0x00) + return LIGHT; + else + return UNKNOWN; +} + //ICEMAN: Turn on field method? //none static int test_desfire_authenticate() { @@ -95,11 +119,20 @@ static int get_desfire_freemem(uint32_t *free_mem) { // --- GET SIGNATURE -static int desfire_print_signature(uint8_t *uid, uint8_t *signature, size_t signature_len) { +static int desfire_print_signature(uint8_t *uid, uint8_t *signature, size_t signature_len, desfire_cardtype_t card_type) { + + uint8_t public_key; + if (card_type == LIGHT) + public_key = 0; + else if (card_type == EV2) + public_key = 1; + else + return PM3_EINVARG; + #define PUBLIC_DESFIRE_ECDA_KEYLEN 57 // ref: MIFARE Desfire Originality Signature Validation - uint8_t nxp_desfire_keys[1][PUBLIC_DESFIRE_ECDA_KEYLEN] = { + uint8_t nxp_desfire_keys[2][PUBLIC_DESFIRE_ECDA_KEYLEN] = { // DESFire Light { 0x04, 0x0E, 0x98, 0xE1, 0x17, 0xAA, 0xA3, 0x64, @@ -109,17 +142,26 @@ static int desfire_print_signature(uint8_t *uid, uint8_t *signature, size_t sign 0x7B, 0x94, 0x2A, 0x97, 0x74, 0xA1, 0xD9, 0x4A, 0xD0, 0x25, 0x72, 0x42, 0x7E, 0x5A, 0xE0, 0xA2, 0xDD, 0x36, 0x59, 0x1B, 0x1F, 0xB3, 0x4F, 0xCF, 0x3D - } + }, // DESFire Ev2 + { + 0x04, 0x8A, 0x9B, 0x38, 0x0A, 0xF2, 0xEE, 0x1B, + 0x98, 0xDC, 0x41, 0x7F, 0xEC, 0xC2, 0x63, 0xF8, + 0x44, 0x9C, 0x76, 0x25, 0xCE, 0xCE, 0x82, 0xD9, + 0xB9, 0x16, 0xC9, 0x92, 0xDA, 0x20, 0x9D, 0x68, + 0x42, 0x2B, 0x81, 0xEC, 0x20, 0xB6, 0x5A, 0x66, + 0xB5, 0x10, 0x2A, 0x61, 0x59, 0x6A, 0xF3, 0x37, + 0x92, 0x00, 0x59, 0x93, 0x16, 0xA0, 0x0A, 0x14, 0x10 + } }; - uint8_t public_key = 0; + int res = ecdsa_signature_r_s_verify(MBEDTLS_ECP_DP_SECP224R1, nxp_desfire_keys[public_key], uid, 7, signature, signature_len, false); bool is_valid = (res == 0); PrintAndLogEx(INFO, " Tag Signature"); - PrintAndLogEx(INFO, " IC signature public key name : NXP DESFire Light"); + PrintAndLogEx(INFO, " IC signature public key name : %s", (card_type == LIGHT) ? "NXP DESFire Light" : "NXP DESFire Ev2"); PrintAndLogEx(INFO, " IC signature public key value : %s", sprint_hex(nxp_desfire_keys[public_key], 16)); PrintAndLogEx(INFO, " : %s", sprint_hex(nxp_desfire_keys[public_key] + 16, 16)); PrintAndLogEx(INFO, " : %s", sprint_hex(nxp_desfire_keys[public_key] + 32, 16)); @@ -423,9 +465,10 @@ static int CmdHF14ADesInfo(const char *Cmd) { // Signature originality check uint8_t signature[56] = {0}; size_t signature_len = 0; + desfire_cardtype_t cardtype = getCardType(package->versionHW[3], package->versionHW[4]); if (get_desfire_signature(signature, &signature_len) == PM3_SUCCESS) - desfire_print_signature(package->uid, signature, signature_len); + desfire_print_signature(package->uid, signature, signature_len, cardtype); // Master Key settings uint8_t master_aid[3] = {0x00, 0x00, 0x00}; From 1f5de5debd9ae1edc6a0a7564748ba93edf9ca94 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 24 Mar 2020 10:08:11 +0100 Subject: [PATCH 1758/1854] hitag sniff, use edgemode --- armsrc/lfadc.c | 57 +++++++++++++++++++++++++------------------------- 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/armsrc/lfadc.c b/armsrc/lfadc.c index 32d1e73b6..0a85312bc 100644 --- a/armsrc/lfadc.c +++ b/armsrc/lfadc.c @@ -58,7 +58,7 @@ void lf_sample_mean(void) { periods++; } } - // division by 32 + // division by 32 adc_avg = adc_sum >> 5; if (DBGLEVEL >= DBG_EXTENDED) @@ -74,16 +74,16 @@ size_t lf_count_edge_periods_ex(size_t max, bool wait, bool detect_gap) { while (!BUTTON_PRESS()) { // only every 100th times, in order to save time when collecting samples. -/* - if (checked == 1000) { - if (data_available()) { - break; - } else { - checked = 0; - } - } - ++checked; -*/ + /* + if (checked == 1000) { + if (data_available()) { + break; + } else { + checked = 0; + } + } + ++checked; + */ WDT_HIT(); if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { @@ -136,12 +136,12 @@ void lf_reset_counter() { // TODO: find out the correct reset settings for tag and reader mode // if (reader_mode) { - // Reset values for reader mode - rising_edge = false; - previous_adc_val = 0xFF; + // Reset values for reader mode + rising_edge = false; + previous_adc_val = 0xFF; // } else { - // Reset values for tag/transponder mode + // Reset values for tag/transponder mode // rising_edge = false; // previous_adc_val = 0xFF; // } @@ -179,7 +179,8 @@ void lf_init(bool reader, bool simulate) { // FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT); FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC); else - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC); + // Sniff + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_TOGGLE_MODE); } @@ -249,18 +250,18 @@ size_t lf_detect_field_drop(size_t max) { while (!BUTTON_PRESS()) { -/* - // only every 1000th times, in order to save time when collecting samples. - if (checked == 1000) { - if (data_available()) { - checked = -1; - break; - } else { - checked = 0; - } - } - ++checked; -*/ + /* + // only every 1000th times, in order to save time when collecting samples. + if (checked == 1000) { + if (data_available()) { + checked = -1; + break; + } else { + checked = 0; + } + } + ++checked; + */ WDT_HIT(); From 4f78edff3149f50de7665956cce6b64b2692f628 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 24 Mar 2020 11:31:23 +0100 Subject: [PATCH 1759/1854] textual --- client/cmdlft55xx.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index fafb5d2da..574030f01 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -482,12 +482,16 @@ static bool t55xxProtect(bool lock, bool usepwd, uint8_t override, uint32_t pass int res = T55xxReadBlockEx(T55x7_CONFIGURATION_BLOCK, T55x7_PAGE0, usepwd, override, password, downlink_mode, false); if (res != PM3_SUCCESS) { - PrintAndLogEx(WARNING, "Failed to read block0, use `p` password parameter?"); + PrintAndLogEx(WARNING, "Failed to read block0, use " _YELLOW_("`p`") "password parameter?"); return false; } - if (GetT55xxBlockData(&block0) == false) + if (GetT55xxBlockData(&block0) == false) { + PrintAndLogEx(DEBUG, "ERROR decoded block0 == %08x", block0); return false; + } + PrintAndLogEx(DEBUG, "OK read block0 == %08x", block0); + bool isPwdBitAlreadySet = (block0 >> (32 - 28) & 1); if (isPwdBitAlreadySet) { @@ -3679,7 +3683,7 @@ static int CmdT55xxProtect(const char *Cmd) { // lock if (t55xxProtect(true, usepwd, override, password, downlink_mode, new_password) == false) { - PrintAndLogEx(WARNING, "Command failed. Did you run `lf t55xx detect` before?"); + PrintAndLogEx(WARNING, "Command failed. Did you run " _YELLOW_("`lf t55xx detect`") "before?"); return PM3_ESOFT; } return PM3_SUCCESS; From f5a8b0601b93b3cfccd9895149a8e64cba31ac7e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 24 Mar 2020 11:33:52 +0100 Subject: [PATCH 1760/1854] fix: coverity 274220 --- client/ui.c | 1 + 1 file changed, 1 insertion(+) diff --git a/client/ui.c b/client/ui.c index df62b9bff..bac8b2956 100644 --- a/client/ui.c +++ b/client/ui.c @@ -159,6 +159,7 @@ void PrintAndLogEx(logLevel_t level, const char *fmt, ...) { break; case DEBUG: strncpy(prefix, _BLUE_("[#]"), sizeof(prefix) - 1); + break; case HINT: case SUCCESS: strncpy(prefix, _GREEN_("[+]"), sizeof(prefix) - 1); From a8aadb27515819c52c6068a29340566616d59a4d Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 24 Mar 2020 11:45:57 +0100 Subject: [PATCH 1761/1854] cppchecker missing includes --- armsrc/LCD_disabled.c | 2 +- client/cmdhfmfdesfire_disabled.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/armsrc/LCD_disabled.c b/armsrc/LCD_disabled.c index 32a917928..97bf6da71 100644 --- a/armsrc/LCD_disabled.c +++ b/armsrc/LCD_disabled.c @@ -5,7 +5,7 @@ //----------------------------------------------------------------------------- // LCD code //----------------------------------------------------------------------------- -#include "LCD.h" +#include "LCD_disabled.h" void LCDSend(unsigned int data) { // 9th bit set for data, clear for command diff --git a/client/cmdhfmfdesfire_disabled.c b/client/cmdhfmfdesfire_disabled.c index fc123667b..e2d43630f 100644 --- a/client/cmdhfmfdesfire_disabled.c +++ b/client/cmdhfmfdesfire_disabled.c @@ -8,7 +8,7 @@ // High frequency MIFARE commands //----------------------------------------------------------------------------- -#include "cmdhfmfdesfire.h" +#include "cmdhfmfdesfire_disabled.h" #include "cmdparser.h" // command_t From b63495cce72d3bd192a64358d6db01de4f6f8002 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 24 Mar 2020 11:56:03 +0100 Subject: [PATCH 1762/1854] cppchecker missing includes --- armsrc/buzzer_disabled.c | 2 +- armsrc/desfire_crypto_disabled.c | 4 +--- armsrc/fonts_disabled.c | 2 +- armsrc/mifaresniff_disabled.c | 2 +- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/armsrc/buzzer_disabled.c b/armsrc/buzzer_disabled.c index 708b7d3f7..579ffaa4e 100644 --- a/armsrc/buzzer_disabled.c +++ b/armsrc/buzzer_disabled.c @@ -1,4 +1,4 @@ -#include "buzzer.h" +#include "buzzer_disabled.h" void Ring_BEE_ONCE(uint16_t music_note) { BEE_ON(); diff --git a/armsrc/desfire_crypto_disabled.c b/armsrc/desfire_crypto_disabled.c index d835a55d4..02896afa8 100644 --- a/armsrc/desfire_crypto_disabled.c +++ b/armsrc/desfire_crypto_disabled.c @@ -26,9 +26,7 @@ * May 2005 */ #include - -#include "desfire_crypto.h" - +#include "desfire_crypto_disabled.h" #include "crc32.h" #include "printf.h" #include "desfire.h" diff --git a/armsrc/fonts_disabled.c b/armsrc/fonts_disabled.c index 97079f48a..45a85e679 100644 --- a/armsrc/fonts_disabled.c +++ b/armsrc/fonts_disabled.c @@ -6,7 +6,7 @@ // Fonts for the LCD //----------------------------------------------------------------------------- -#include "fonts.h" +#include "fonts_disabled.h" const char FONT6x8[97][8] = { {0x06, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00}, // columns, rows, bytes per char diff --git a/armsrc/mifaresniff_disabled.c b/armsrc/mifaresniff_disabled.c index 799fd62be..6ccdc8e6c 100644 --- a/armsrc/mifaresniff_disabled.c +++ b/armsrc/mifaresniff_disabled.c @@ -8,7 +8,7 @@ // Routines to support mifare classic sniffer. //----------------------------------------------------------------------------- -#include "mifaresniff.h" +#include "mifaresniff_disabled.h" #ifndef CheckCrc14A # define CheckCrc14A(data, len) check_crc(CRC_14443_A, (data), (len)) From 90a9c215de47d48c4dbf867149f1a06a63f6d017 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 24 Mar 2020 11:59:22 +0100 Subject: [PATCH 1763/1854] cppchecker missing includes --- armsrc/hitag2crack.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/hitag2crack.c b/armsrc/hitag2crack.c index d66f740bc..34d35ada6 100644 --- a/armsrc/hitag2crack.c +++ b/armsrc/hitag2crack.c @@ -11,7 +11,7 @@ // hitag2 attack functions //----------------------------------------------------------------------------- -#include "hitagcrypto.h" +#include "hitag2_crypto.h" #include "hitag2crack.h" #define READP0CMD "1100000111" From 0fbf7d6328ed2088c72564f55bfa3e9b56cc75e8 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 24 Mar 2020 13:06:09 +0100 Subject: [PATCH 1764/1854] cppchecker - shadow --- client/cmdhfmfdes.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/client/cmdhfmfdes.c b/client/cmdhfmfdes.c index 697ec596e..7209a5a71 100644 --- a/client/cmdhfmfdes.c +++ b/client/cmdhfmfdes.c @@ -557,9 +557,6 @@ char *getVersionStr(uint8_t major, uint8_t minor) { void getKeySettings(uint8_t *aid) { - char messStr[512] = {0x00}; - const char *str = messStr; - if (memcmp(aid, "\x00\x00\x00", 3) == 0) { // CARD MASTER KEY @@ -587,9 +584,7 @@ void getKeySettings(uint8_t *aid) { PrintAndLogEx(WARNING, _RED_(" Can't read Application Master key settings")); } - - memset(messStr, 0x00, sizeof(messStr)); - str = " Operation of PICC master key : " _YELLOW_("%s"); + const char *str = " Operation of PICC master key : " _YELLOW_("%s"); // 2 MSB denotes switch (num_keys >> 6) { @@ -709,8 +704,8 @@ static int CmdHF14ADesEnumApplications(const char *Cmd) { // Get File IDs if (get_desfire_fileids(file_ids, &file_ids_len) == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, " Tag report " _GREEN_("%d") "file%c", file_ids_len, (file_ids_len == 1) ? ' ' : 's'); - for (int i = 0; i < file_ids_len; ++i) { - PrintAndLogEx(SUCCESS, " Fileid %d (0x%02x)", file_ids[i], file_ids[i]); + for (int j = 0; j < file_ids_len; ++j) { + PrintAndLogEx(SUCCESS, " Fileid %d (0x%02x)", file_ids[j], file_ids[j]); } } From 5acd681f8f72ced055d4dc5f129dbfdcacb94427 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 24 Mar 2020 13:11:50 +0100 Subject: [PATCH 1765/1854] cppchecker - too many shifts --- client/cmdlfkeri.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdlfkeri.c b/client/cmdlfkeri.c index 1299d767a..a77f3c477 100644 --- a/client/cmdlfkeri.c +++ b/client/cmdlfkeri.c @@ -128,7 +128,7 @@ static int CmdKeriMSScramble (KeriMSScramble_t Action, uint32_t *FC, uint32_t *I *CardID = *CardID | Parity; // Bit 31 was fixed but not in check/parity bits - *CardID |= (uint32_t)(1 << 31); + *CardID |= 1UL << 31; PrintAndLogEx(SUCCESS, "Scrambled MS : FC %d - CN %d to RAW : E0000000%08X",*FC,*ID,*CardID); } From 10243d9bce05782ca8300c7d5ea361657295e06b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 24 Mar 2020 13:16:47 +0100 Subject: [PATCH 1766/1854] cppchecker - too many shifts --- client/wiegand_formatutils.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/client/wiegand_formatutils.c b/client/wiegand_formatutils.c index ba446957a..836da717d 100644 --- a/client/wiegand_formatutils.c +++ b/client/wiegand_formatutils.c @@ -36,21 +36,21 @@ bool set_bit_by_position(wiegand_message_t *data, bool value, uint8_t pos) { return false; } else if (pos > 63) { if (value) - data->Top |= (1 << (pos - 64)); + data->Top |= (1UL << (pos - 64)); else - data->Top &= ~(1 << (pos - 64)); + data->Top &= ~(1UL << (pos - 64)); return true; } else if (pos > 31) { if (value) - data->Mid |= (1 << (pos - 32)); + data->Mid |= (1UL << (pos - 32)); else - data->Mid &= ~(1 << (pos - 32)); + data->Mid &= ~(1UL << (pos - 32)); return true; } else { if (value) - data->Bot |= (1 << pos); + data->Bot |= (1UL << pos); else - data->Bot &= ~(1 << pos); + data->Bot &= ~(1UL << pos); return true; } } From a24c7334cfe84fd1651b0810ebb48ffba1fbddb0 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 24 Mar 2020 13:20:50 +0100 Subject: [PATCH 1767/1854] cppchecker - invalidprintf --- tools/hitag2crack/crack3/ht2crack3.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/hitag2crack/crack3/ht2crack3.c b/tools/hitag2crack/crack3/ht2crack3.c index da35bbd14..9e39a8e09 100644 --- a/tools/hitag2crack/crack3/ht2crack3.c +++ b/tools/hitag2crack/crack3/ht2crack3.c @@ -214,15 +214,15 @@ void *crack(void *d) { uint64_t y; uint64_t ytmp; uint64_t klowery; - unsigned int count = 0; + unsigned int count; uint64_t bit; uint64_t b; uint64_t z; uint64_t foundkey; uint64_t revkey; int ret; - unsigned int found = 0; - unsigned int badguess = 0; + unsigned int found; + unsigned int badguess; struct Tklower *Tk = NULL; @@ -312,7 +312,7 @@ void *crack(void *d) { // normalise foundkey revkey = rev64(foundkey); foundkey = ((revkey >> 40) & 0xff) | ((revkey >> 24) & 0xff00) | ((revkey >> 8) & 0xff0000) | ((revkey << 8) & 0xff000000) | ((revkey << 24) & 0xff00000000) | ((revkey << 40) & 0xff0000000000); - printf("\n\nSuccess - key = %012lX\n", foundkey); + printf("\n\nSuccess - key = %012"PRIx64"\n", foundkey); exit(0); return (void *)foundkey; @@ -446,7 +446,7 @@ int main(int argc, char *argv[]) { } printf("thread %i finished\n", i); if (status) { - printf("Key = %012lX\n", (uint64_t)status); + printf("Key = %012"PRIx64"\n", (uint64_t)status); exit(0); } } From 20547d773b8e1c940fcfd34d35ea4f13edf1048e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 24 Mar 2020 13:27:33 +0100 Subject: [PATCH 1768/1854] cppchecker - buffer overflow --- armsrc/mifaredesfire.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/mifaredesfire.c b/armsrc/mifaredesfire.c index 06a3f3f8c..5b8ed289e 100644 --- a/armsrc/mifaredesfire.c +++ b/armsrc/mifaredesfire.c @@ -134,7 +134,7 @@ void MifareDesfireGetInformation() { return; } // add uid. - memcpy(payload.uid, card.uid, sizeof(card.uid)); + memcpy(payload.uid, card.uid, sizeof(payload.uid)); LED_A_ON(); uint8_t cmd[] = {GET_VERSION, 0x00, 0x00, 0x00}; From 0033715a595d34e1e603a144c8af35c21587a9fb Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 24 Mar 2020 13:35:33 +0100 Subject: [PATCH 1769/1854] cppchecker --- client/tinycbor/cborpretty.c | 4 ++-- client/tinycbor/cbortojson.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/client/tinycbor/cborpretty.c b/client/tinycbor/cborpretty.c index 775d90925..71f05522f 100644 --- a/client/tinycbor/cborpretty.c +++ b/client/tinycbor/cborpretty.c @@ -488,14 +488,14 @@ static CborError value_to_pretty(CborStreamFunction stream, void *out, CborValue case CborFloatType: cbor_value_get_float(it, &f); val = f; - suffix = flags & CborPrettyNumericEncodingIndicators ? "_2" : "f"; + suffix = (flags & CborPrettyNumericEncodingIndicators) ? "_2" : "f"; } else if (false) { uint16_t f16; case CborHalfFloatType: #ifndef CBOR_NO_HALF_FLOAT_TYPE cbor_value_get_half_float(it, &f16); val = decode_half(f16); - suffix = flags & CborPrettyNumericEncodingIndicators ? "_1" : "f16"; + suffix = (flags & CborPrettyNumericEncodingIndicators) ? "_1" : "f16"; #else (void)f16; err = CborErrorUnsupportedType; diff --git a/client/tinycbor/cbortojson.c b/client/tinycbor/cbortojson.c index 3ea90cee8..8d39303bc 100644 --- a/client/tinycbor/cbortojson.c +++ b/client/tinycbor/cbortojson.c @@ -146,7 +146,7 @@ * the keys for the metadata clash with existing keys in the JSON map. */ -extern FILE *open_memstream(char **bufptr, size_t *sizeptr); +extern FILE *open_memstream(char **bufptr, size_t *lenptr); enum ConversionStatusFlags { TypeWasNotNative = 0x100, /* anything but strings, boolean, null, arrays and maps */ From f593efebf4b6fc5e3e7522d7d1a002574fea5ffe Mon Sep 17 00:00:00 2001 From: Robert Quattlebaum Date: Tue, 24 Mar 2020 09:18:16 -0700 Subject: [PATCH 1770/1854] Re-added `teslaStore` AID, also added `TeslaDAP` AID --- client/resources/aidlist.json | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/client/resources/aidlist.json b/client/resources/aidlist.json index ddf844023..e427e34bf 100644 --- a/client/resources/aidlist.json +++ b/client/resources/aidlist.json @@ -2127,6 +2127,14 @@ "Description": "Brazilian Bank Banco Bradesco", "Type": "EMV" }, + { + "AID": "7465736C6153746F7265", + "Vendor": "Tesla", + "Country": "", + "Name": "teslaStore", + "Description": "Undocumented AID associated with official Tesla Key Cards", + "Type": "Tesla" + }, { "AID": "7465736C614C6F6769633", "Vendor": "Tesla", @@ -2142,5 +2150,13 @@ "Name": "teslaLogic (Alternate AID)", "Description": "Key for Tesla vehicles", "Type": "Tesla" + }, + { + "AID": "5465736c61444150", + "Vendor": "Tesla", + "Country": "", + "Name": "TeslaDAP", + "Description": "Undocumented AID associated with official Tesla BTLE Key Fobs", + "Type": "Tesla" } ] From 0c25f85c9f93269e7cf68ad5b5d4bfbc3d075c32 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 25 Mar 2020 11:19:20 +0100 Subject: [PATCH 1771/1854] empty string. --- client/scripting.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/scripting.c b/client/scripting.c index 7ba38ee8b..756799626 100644 --- a/client/scripting.c +++ b/client/scripting.c @@ -790,6 +790,7 @@ static int l_reveng_runmodel(lua_State *L) { // l = little endian input and output, L = little endian output only, t = left justified} //result = calculated crc hex string char result[50]; + memset(result, 0x00, sizeof(result)); const char *inModel = luaL_checkstring(L, 1); const char *inHexStr = luaL_checkstring(L, 2); @@ -800,7 +801,7 @@ static int l_reveng_runmodel(lua_State *L) { if (!ans) return returnToLuaWithError(L, "Reveng failed"); - lua_pushstring(L, (const char *)result); + lua_pushstring(L, result); return 1; } From dc4bd2c1f70cc5b50a88e3af2d9ebae0b79e15a5 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 25 Mar 2020 11:20:35 +0100 Subject: [PATCH 1772/1854] fix: bizarr behavior in Proxspace lua, where io.read("*l") default behavior swaps to io.read("*L") . So lets make *L default a strip away all newlines... --- client/lualibs/utils.lua | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/client/lualibs/utils.lua b/client/lualibs/utils.lua index c265a5d8c..2f27b6c38 100644 --- a/client/lualibs/utils.lua +++ b/client/lualibs/utils.lua @@ -20,17 +20,17 @@ local Utils = end, --- -- Asks the user for input - input = function (message , default) - local answer + input = function (message, default) + local answer = '' if default ~= nil then message = message .. " (default: ".. default.. " )" end - message = message .." \n > " - io.write(message) + io.write(message, "\n > ") io.flush() - answer = io.read() - if answer == '' then answer = default end - + answer = io.read("*L") + answer = string.gsub(answer, "\r\n", "") + answer = string.gsub(answer, "\n", "") + if answer == '' or answer == nil then answer = default end return answer end, From 6e49d94a821addf9b158be3232dfe2dab6f4d2ac Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 25 Mar 2020 16:35:31 +0100 Subject: [PATCH 1773/1854] fix coverity 205241 --- client/cliparser/argtable3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cliparser/argtable3.c b/client/cliparser/argtable3.c index 3acbce48e..b8644dd86 100644 --- a/client/cliparser/argtable3.c +++ b/client/cliparser/argtable3.c @@ -250,7 +250,7 @@ const char *optarg; /* argument associated with option */ #define BADARG ((*options == ':') ? (int)':' : (int)'?') #define INORDER (int)1 -#define EMSG "" +#define EMSG " " static int getopt_internal(int, char *const *, const char *, const struct option *, int *, int); From a9571d26b02e2a74c44878f6d579f580d6b390c1 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 25 Mar 2020 16:49:19 +0100 Subject: [PATCH 1774/1854] fix coverity 274113 --- client/cmdhficlass.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 1dccaef5c..b7ebdca9f 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -867,7 +867,7 @@ static int CmdHFiClassDecrypt(const char *Cmd) { uint32_t limit = MIN(applimit, decryptedlen / 8); if (decryptedlen / 8 != applimit) { - PrintAndLogEx(WARNING, "Actual file len " _YELLOW_("%u") "vs HID app-limit len " _YELLOW_("%u"), decryptedlen, applimit * 8); + PrintAndLogEx(WARNING, "Actual file len " _YELLOW_("%zu") "vs HID app-limit len " _YELLOW_("%u"), decryptedlen, applimit * 8); PrintAndLogEx(INFO, "Setting limit to " _GREEN_("%u"), limit * 8); } uint8_t numblocks4userid = GetNumberBlocksForUserId(decrypted + (6 * 8)); From b0b5bcda762a3fcf74e4ef776219f18c34f97644 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 25 Mar 2020 17:27:19 +0100 Subject: [PATCH 1775/1854] textual --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e48802b81..6192c23cd 100644 --- a/README.md +++ b/README.md @@ -47,9 +47,9 @@ On the software side: quite a lot, see the [Changelog file](CHANGELOG.md). > ⚠ **Note**: This is a bleeding edge repository. The maintainers actively is working out of this repository and will be periodically re-structuring the code to make it easier to comprehend, navigate, build, test, and contribute to, so **DO expect significant changes to code layout on a regular basis**. This repo compiles nicely on - - Proxspace v3.2 + - Proxspace v3.x - Windows/mingw environment with Qt5.6.1 & GCC 4.8 - - Ubuntu 1404, 1510, 1604, 1804, 1904 + - Ubuntu 1604, 1804, 1904 - Mac OS X / Homebrew - ParrotOS, Gentoo, Pentoo, Kali, Nethunter, Archlinux, Fedora - WSL, WSL2 (Windows subsystem linux) on Windows 10 From 5e21566201d6bc57a1d9a944acbaa6e671387bae Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 25 Mar 2020 17:41:10 +0100 Subject: [PATCH 1776/1854] coverity 274112 - unintended sign extension --- armsrc/hitagS.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/armsrc/hitagS.c b/armsrc/hitagS.c index 07b445434..78009496e 100644 --- a/armsrc/hitagS.c +++ b/armsrc/hitagS.c @@ -888,8 +888,8 @@ void SimulateHitagSTag(bool tag_mem_supplied, uint8_t *data) { // use the last read tag } - tag.uid = (tag.pages[0][3] << 24 | tag.pages[0][2] << 16 | tag.pages[0][1] << 8 | tag.pages[0][0]); - tag.key = (tag.pages[3][3] << 24 | tag.pages[3][2] << 16 | tag.pages[3][1] << 8 | tag.pages[3][0]); + tag.uid = ((tag.pages[0][3]) << 24) | ((tag.pages[0][2]) << 16) | ((tag.pages[0][1]) << 8) | tag.pages[0][0]; + tag.key = ((tag.pages[3][3]) << 24) | ((tag.pages[3][2]) << 16) | ((tag.pages[3][1]) << 8) | tag.pages[3][0]; tag.key <<= 16; tag.key += ((tag.pages[2][3]) << 8) + tag.pages[2][2]; tag.pwdl0 = tag.pages[2][0]; From 15726268bf5478bb5b40d4022b5b4b5a047cfc48 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 26 Mar 2020 09:30:59 +0100 Subject: [PATCH 1777/1854] fix: hf mf fchk - exit on button press --- armsrc/mifarecmd.c | 70 +++++++++++++++++++++++----------------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 0136ed6c9..a8f829144 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -82,22 +82,22 @@ void MifareReadBlock(uint8_t blockNo, uint8_t keyType, uint8_t *datain) { while (true) { if (!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) { - if (DBGLEVEL >= 1) Dbprintf("Can't select card"); + if (DBGLEVEL >= DBG_ERROR) Dbprintf("Can't select card"); break; }; if (mifare_classic_auth(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST)) { - if (DBGLEVEL >= 1) Dbprintf("Auth error"); + if (DBGLEVEL >= DBG_ERROR) Dbprintf("Auth error"); break; }; if (mifare_classic_readblock(pcs, cuid, blockNo, dataoutbuf)) { - if (DBGLEVEL >= 1) Dbprintf("Read block error"); + if (DBGLEVEL >= DBG_ERROR) Dbprintf("Read block error"); break; }; if (mifare_classic_halt(pcs, cuid)) { - if (DBGLEVEL >= 1) Dbprintf("Halt error"); + if (DBGLEVEL >= DBG_ERROR) Dbprintf("Halt error"); break; }; @@ -243,25 +243,25 @@ void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t *datain) { isOK = 1; if (!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) { isOK = 0; - if (DBGLEVEL >= 1) Dbprintf("Can't select card"); + if (DBGLEVEL >= DBG_ERROR) Dbprintf("Can't select card"); } if (isOK && mifare_classic_auth(pcs, cuid, FirstBlockOfSector(sectorNo), keyType, ui64Key, AUTH_FIRST)) { isOK = 0; - if (DBGLEVEL >= 1) Dbprintf("Auth error"); + if (DBGLEVEL >= DBG_ERROR) Dbprintf("Auth error"); } for (uint8_t blockNo = 0; isOK && blockNo < NumBlocksPerSector(sectorNo); blockNo++) { if (mifare_classic_readblock(pcs, cuid, FirstBlockOfSector(sectorNo) + blockNo, dataoutbuf + 16 * blockNo)) { isOK = 0; - if (DBGLEVEL >= 1) Dbprintf("Read sector %2d block %2d error", sectorNo, blockNo); + if (DBGLEVEL >= DBG_ERROR) Dbprintf("Read sector %2d block %2d error", sectorNo, blockNo); break; } } if (mifare_classic_halt(pcs, cuid)) { - if (DBGLEVEL >= 1) Dbprintf("Halt error"); + if (DBGLEVEL >= DBG_ERROR) Dbprintf("Halt error"); } if (DBGLEVEL >= 2) DbpString("READ SECTOR FINISHED"); @@ -409,22 +409,22 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain) { while (true) { if (!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) { - if (DBGLEVEL >= 1) Dbprintf("Can't select card"); + if (DBGLEVEL >= DBG_ERROR) Dbprintf("Can't select card"); break; }; if (mifare_classic_auth(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST)) { - if (DBGLEVEL >= 1) Dbprintf("Auth error"); + if (DBGLEVEL >= DBG_ERROR) Dbprintf("Auth error"); break; }; if (mifare_classic_writeblock(pcs, cuid, blockNo, blockdata)) { - if (DBGLEVEL >= 1) Dbprintf("Write block error"); + if (DBGLEVEL >= DBG_ERROR) Dbprintf("Write block error"); break; }; if (mifare_classic_halt(pcs, cuid)) { - if (DBGLEVEL >= 1) Dbprintf("Halt error"); + if (DBGLEVEL >= DBG_ERROR) Dbprintf("Halt error"); break; }; @@ -460,18 +460,18 @@ void MifareUWriteBlockCompat(uint8_t arg0, uint8_t *datain) iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); if(!iso14443a_select_card(uid, NULL, NULL, true, 0, true)) { - if (DBGLEVEL >= 1) Dbprintf("Can't select card"); + if (DBGLEVEL >= DBG_ERROR) Dbprintf("Can't select card"); OnError(0); return; }; if(mifare_ultra_writeblock_compat(blockNo, blockdata)) { - if (DBGLEVEL >= 1) Dbprintf("Write block error"); + if (DBGLEVEL >= DBG_ERROR) Dbprintf("Write block error"); OnError(0); return; }; if(mifare_ultra_halt()) { - if (DBGLEVEL >= 1) Dbprintf("Halt error"); + if (DBGLEVEL >= DBG_ERROR) Dbprintf("Halt error"); OnError(0); return; }; @@ -506,7 +506,7 @@ void MifareUWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain) { set_tracing(true); if (!iso14443a_select_card(NULL, NULL, NULL, true, 0, true)) { - if (DBGLEVEL >= 1) Dbprintf("Can't select card"); + if (DBGLEVEL >= DBG_ERROR) Dbprintf("Can't select card"); OnError(0); return; }; @@ -534,13 +534,13 @@ void MifareUWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain) { } if (mifare_ultra_writeblock(blockNo, blockdata)) { - if (DBGLEVEL >= 1) Dbprintf("Write block error"); + if (DBGLEVEL >= DBG_ERROR) Dbprintf("Write block error"); OnError(0); return; }; if (mifare_ultra_halt()) { - if (DBGLEVEL >= 1) Dbprintf("Halt error"); + if (DBGLEVEL >= DBG_ERROR) Dbprintf("Halt error"); OnError(0); return; }; @@ -569,7 +569,7 @@ void MifareUSetPwd(uint8_t arg0, uint8_t *datain) { set_tracing(true); if (!iso14443a_select_card(NULL, NULL, NULL, true, 0, true)) { - if (DBGLEVEL >= 1) Dbprintf("Can't select card"); + if (DBGLEVEL >= DBG_ERROR) Dbprintf("Can't select card"); OnError(0); return; }; @@ -579,7 +579,7 @@ void MifareUSetPwd(uint8_t arg0, uint8_t *datain) { blockdata[2] = pwd[5]; blockdata[3] = pwd[4]; if (mifare_ultra_writeblock(44, blockdata)) { - if (DBGLEVEL >= 1) Dbprintf("Write block error"); + if (DBGLEVEL >= DBG_ERROR) Dbprintf("Write block error"); OnError(44); return; }; @@ -589,7 +589,7 @@ void MifareUSetPwd(uint8_t arg0, uint8_t *datain) { blockdata[2] = pwd[1]; blockdata[3] = pwd[0]; if (mifare_ultra_writeblock(45, blockdata)) { - if (DBGLEVEL >= 1) Dbprintf("Write block error"); + if (DBGLEVEL >= DBG_ERROR) Dbprintf("Write block error"); OnError(45); return; }; @@ -599,7 +599,7 @@ void MifareUSetPwd(uint8_t arg0, uint8_t *datain) { blockdata[2] = pwd[13]; blockdata[3] = pwd[12]; if (mifare_ultra_writeblock(46, blockdata)) { - if (DBGLEVEL >= 1) Dbprintf("Write block error"); + if (DBGLEVEL >= DBG_ERROR) Dbprintf("Write block error"); OnError(46); return; }; @@ -609,13 +609,13 @@ void MifareUSetPwd(uint8_t arg0, uint8_t *datain) { blockdata[2] = pwd[9]; blockdata[3] = pwd[8]; if (mifare_ultra_writeblock(47, blockdata)) { - if (DBGLEVEL >= 1) Dbprintf("Write block error"); + if (DBGLEVEL >= DBG_ERROR) Dbprintf("Write block error"); OnError(47); return; }; if (mifare_ultra_halt()) { - if (DBGLEVEL >= 1) Dbprintf("Halt error"); + if (DBGLEVEL >= DBG_ERROR) Dbprintf("Halt error"); OnError(0); return; }; @@ -674,7 +674,7 @@ void MifareAcquireNonces(uint32_t arg0, uint32_t flags) { if (!have_uid) { // need a full select cycle to get the uid first iso14a_card_select_t card_info; if (!iso14443a_select_card(uid, &card_info, &cuid, true, 0, true)) { - if (DBGLEVEL >= 1) Dbprintf("AcquireNonces: Can't select card (ALL)"); + if (DBGLEVEL >= DBG_ERROR) Dbprintf("AcquireNonces: Can't select card (ALL)"); continue; } switch (card_info.uidlen) { @@ -693,7 +693,7 @@ void MifareAcquireNonces(uint32_t arg0, uint32_t flags) { have_uid = true; } else { // no need for anticollision. We can directly select the card if (!iso14443a_fast_select_card(uid, cascade_levels)) { - if (DBGLEVEL >= 1) Dbprintf("AcquireNonces: Can't select card (UID)"); + if (DBGLEVEL >= DBG_ERROR) Dbprintf("AcquireNonces: Can't select card (UID)"); continue; } } @@ -792,7 +792,7 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, if (!have_uid) { // need a full select cycle to get the uid first iso14a_card_select_t card_info; if (!iso14443a_select_card(uid, &card_info, &cuid, true, 0, true)) { - if (DBGLEVEL >= 1) Dbprintf("AcquireNonces: Can't select card (ALL)"); + if (DBGLEVEL >= DBG_ERROR) Dbprintf("AcquireNonces: Can't select card (ALL)"); continue; } switch (card_info.uidlen) { @@ -811,7 +811,7 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, have_uid = true; } else { // no need for anticollision. We can directly select the card if (!iso14443a_fast_select_card(uid, cascade_levels)) { - if (DBGLEVEL >= 1) Dbprintf("AcquireNonces: Can't select card (UID)"); + if (DBGLEVEL >= DBG_ERROR) Dbprintf("AcquireNonces: Can't select card (UID)"); continue; } } @@ -821,7 +821,7 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, uint32_t nt1; if (mifare_classic_authex(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST, &nt1, NULL)) { - if (DBGLEVEL >= 1) Dbprintf("AcquireNonces: Auth1 error"); + if (DBGLEVEL >= DBG_ERROR) Dbprintf("AcquireNonces: Auth1 error"); continue; } @@ -832,7 +832,7 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, CHK_TIMEOUT(); if (len != 4) { - if (DBGLEVEL >= 1) Dbprintf("AcquireNonces: Auth2 error len=%d", len); + if (DBGLEVEL >= DBG_ERROR) Dbprintf("AcquireNonces: Auth2 error len=%d", len); continue; } @@ -1422,7 +1422,7 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da iso14a_card_select_t card_info; if (!iso14443a_select_card(uid, &card_info, &cuid, true, 0, true)) { - if (DBGLEVEL >= 1) Dbprintf("ChkKeys_fast: Can't select card (ALL)"); + if (DBGLEVEL >= DBG_ERROR) Dbprintf("ChkKeys_fast: Can't select card (ALL)"); goto OUT; } @@ -1470,7 +1470,7 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da for (uint16_t i = s_point; i < keyCount; ++i) { // Allow button press / usb cmd to interrupt device - if (BUTTON_PRESS() && data_available()) { + if (BUTTON_PRESS() || data_available()) { goto OUT; } @@ -1562,7 +1562,7 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da for (uint16_t i = 0; i < keyCount; i++) { // Allow button press / usb cmd to interrupt device - if (BUTTON_PRESS() && data_available()) break; + if (BUTTON_PRESS() || data_available()) break; // found all keys? if (foundkeys == allkeys) @@ -1731,7 +1731,7 @@ void MifareChkKeys(uint8_t *datain) { if (!have_uid) { // need a full select cycle to get the uid first iso14a_card_select_t card_info; if (!iso14443a_select_card(uid, &card_info, &cuid, true, 0, true)) { - if (DBGLEVEL >= 1) Dbprintf("ChkKeys: Can't select card (ALL)"); + if (DBGLEVEL >= DBG_ERROR) Dbprintf("ChkKeys: Can't select card (ALL)"); --i; // try same key once again continue; } @@ -1751,7 +1751,7 @@ void MifareChkKeys(uint8_t *datain) { have_uid = true; } else { // no need for anticollision. We can directly select the card if (!iso14443a_select_card(uid, NULL, NULL, false, cascade_levels, true)) { - if (DBGLEVEL >= 1) Dbprintf("ChkKeys: Can't select card (UID)"); + if (DBGLEVEL >= DBG_ERROR) Dbprintf("ChkKeys: Can't select card (UID)"); --i; // try same key once again continue; } From 063b393eba57df3810cdce3808f159305b437a7a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 26 Mar 2020 20:36:38 +0100 Subject: [PATCH 1778/1854] textual --- client/cmdhfmfp.c | 25 ++++++++++++------------ client/dictionaries/mfp_default_keys.dic | 3 +++ 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/client/cmdhfmfp.c b/client/cmdhfmfp.c index 2a1533344..ff1b87cf5 100644 --- a/client/cmdhfmfp.c +++ b/client/cmdhfmfp.c @@ -42,7 +42,7 @@ static int CmdHFMFPInfo(const char *Cmd) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(INFO, "-- Mifare Plus Tag Information ------------------------------"); PrintAndLogEx(INFO, "-------------------------------------------------------------"); - + // info about 14a part infoHF14A(false, false, false); @@ -61,13 +61,12 @@ static int CmdHFMFPInfo(const char *Cmd) { PrintAndLogEx(INFO, "-------------------------------------------------------------"); PrintAndLogEx(INFO, " Fingerprint"); - + // MIFARE Type Identification Procedure // https://www.nxp.com/docs/en/application-note/AN10833.pdf uint16_t ATQA = card.atqa[0] + (card.atqa[1] << 8); - bool isPlus = false; - + if (ATQA == 0x0004) { PrintAndLogEx(INFO, " ATQA - " _GREEN_("Mifare Plus 2K") " (4b UID)"); isPlus = true; @@ -131,25 +130,25 @@ static int CmdHFMFPInfo(const char *Cmd) { } } -// How do we detect SL0 / SL1 / SL2 / SL3 modes?!? + // How do we detect SL0 / SL1 / SL2 / SL3 modes?!? PrintAndLogEx(INFO, "Security Level (SL)"); switch(SLmode) { - case 0: + case 0: PrintAndLogEx(INFO, "SL 0: initial delivery configuration, used for card personalization"); break; case 1: PrintAndLogEx(INFO, "SL 1: backwards functional compatibility mode (with MIFARE Classic 1K / 4K) with an optional AES authentication"); break; - case 2: + case 2: PrintAndLogEx(INFO, "SL 2: 3-Pass Authentication based on AES followed by MIFARE CRYPTO1 authentication, communication secured by MIFARE CRYPTO1"); break; - case 3: + case 3: PrintAndLogEx(INFO, "SL 3: 3-Pass authentication based on AES, data manipulation commands secured by AES encryption and an AES based MACing method."); break; - default: + default: break; } - + if (SLmode != 0xFF) PrintAndLogEx(SUCCESS, "\tMifare Plus SL mode: " _YELLOW_("SL%d"), SLmode); else @@ -966,9 +965,9 @@ static int CmdHFMFPChk(const char *Cmd) { if (foundKeys[0][sector][0] || foundKeys[1][sector][0]) { if (!printedHeader) { PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(INFO, ".------.--------------------------------.--------------------------------."); + PrintAndLogEx(INFO, "-------+--------------------------------+---------------------------------"); PrintAndLogEx(INFO, "|sector| key A | key B |"); - PrintAndLogEx(INFO, "|------|--------------------------------|--------------------------------|"); + PrintAndLogEx(INFO, "|------+--------------------------------+--------------------------------|"); printedHeader = true; } PrintAndLogEx(INFO, "| %02d |%32s|%32s|", @@ -980,7 +979,7 @@ static int CmdHFMFPChk(const char *Cmd) { if (!printedHeader) PrintAndLogEx(INFO, "No keys found("); else - PrintAndLogEx(INFO, "'------'--------------------------------'--------------------------------'\n"); + PrintAndLogEx(INFO, "'------+--------------------------------+--------------------------------'\n"); // save keys to json if ((jsonnamelen > 0) && printedHeader) { diff --git a/client/dictionaries/mfp_default_keys.dic b/client/dictionaries/mfp_default_keys.dic index 0f20b69bf..e492e2686 100644 --- a/client/dictionaries/mfp_default_keys.dic +++ b/client/dictionaries/mfp_default_keys.dic @@ -25,3 +25,6 @@ eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee 15141312111009080706050403020100 0f0e0d0c0b0a09080706050403020100 100f0e0d0c0b0a090807060504030201 +404142434445464748494a4b4c4d4e4f +303132333435363738393a3b3c3d3e3f + From ffb8ad98737372db3c7b8d1bcc8a294cb995c3cb Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 26 Mar 2020 21:04:58 +0100 Subject: [PATCH 1779/1854] defaults --- client/mifare/mifaredefault.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/client/mifare/mifaredefault.c b/client/mifare/mifaredefault.c index b41859f09..8c9a26071 100644 --- a/client/mifare/mifaredefault.c +++ b/client/mifare/mifaredefault.c @@ -34,6 +34,8 @@ const char *g_mifare_plus_default_keys[] = { "000102030405060708090a0b0c0d0e0f", "0102030405060708090a0b0c0d0e0f10", "00010203040506070809101112131415", - "01020304050607080910111213141516" + "01020304050607080910111213141516", + "404142434445464748494a4b4c4d4e4f", + "303132333435363738393a3b3c3d3e3f", }; size_t g_mifare_plus_default_keys_len = ARRAYLEN(g_mifare_plus_default_keys); From 82d99522b4858251952773215ff48d8e08c91fc5 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 27 Mar 2020 11:56:47 +0100 Subject: [PATCH 1780/1854] textual --- client/cmdhficlass.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index b7ebdca9f..f4a62b6c1 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -122,9 +122,9 @@ static int usage_hf_iclass_clone(void) { PrintAndLogEx(NORMAL, "Usage: hf iclass clone f b l k c e|r"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " f : specify a filename to clone from"); - PrintAndLogEx(NORMAL, " b : The first block to clone as 2 hex symbols"); - PrintAndLogEx(NORMAL, " l : Set the Data to write as 16 hex symbols"); - PrintAndLogEx(NORMAL, " k : Access Key as 16 hex symbols or 1 hex to select key from memory"); + PrintAndLogEx(NORMAL, " b : The first block to clone as 2 hex symbols"); + PrintAndLogEx(NORMAL, " l : Set the Data to write as 16 hex symbols"); + PrintAndLogEx(NORMAL, " k : Access Key as 16 hex symbols or 1 hex to select key from memory"); PrintAndLogEx(NORMAL, " c : If 'c' is specified, the key set is assumed to be the credit key\n"); PrintAndLogEx(NORMAL, " e : If 'e' is specified, elite computations applied to key"); PrintAndLogEx(NORMAL, " r : If 'r' is specified, no computations applied to key"); @@ -135,18 +135,18 @@ static int usage_hf_iclass_clone(void) { return PM3_SUCCESS; } static int usage_hf_iclass_writeblock(void) { - PrintAndLogEx(NORMAL, "Usage: hf iclass writeblk b d k [c|e|r|v]\n"); + PrintAndLogEx(NORMAL, "Usage: hf iclass wrbl b d k [c|e|r|v]\n"); PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " b : The block number as 2 hex symbols"); + PrintAndLogEx(NORMAL, " b : The block number as 2 hex symbols"); PrintAndLogEx(NORMAL, " d : set the Data to write as 16 hex symbols"); - PrintAndLogEx(NORMAL, " k : access Key as 16 hex symbols or 1 hex to select key from memory"); + PrintAndLogEx(NORMAL, " k : access Key as 16 hex symbols or 1 hex to select key from memory"); PrintAndLogEx(NORMAL, " c : credit key assumed\n"); PrintAndLogEx(NORMAL, " e : elite computations applied to key"); PrintAndLogEx(NORMAL, " r : raw, no computations applied to key"); PrintAndLogEx(NORMAL, " v : verbose output"); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf iclass writeblk b 0A d AAAAAAAAAAAAAAAA k 001122334455667B"); - PrintAndLogEx(NORMAL, " hf iclass writeblk b 1B d AAAAAAAAAAAAAAAA k 001122334455667B c"); + PrintAndLogEx(NORMAL, " hf iclass wrbl b 0A d AAAAAAAAAAAAAAAA k 001122334455667B"); + PrintAndLogEx(NORMAL, " hf iclass wrbl b 1B d AAAAAAAAAAAAAAAA k 001122334455667B c"); return PM3_SUCCESS; } static int usage_hf_iclass_readblock(void) { From 8c8a86cb835b6363e142e924d12fa4777b86b302 Mon Sep 17 00:00:00 2001 From: Uli Heilmeier Date: Tue, 25 Feb 2020 22:24:16 +0100 Subject: [PATCH 1781/1854] Standalone mode: Adding Legic Prime read/sim run This commit adds a standalone mode for Legic Prime. It reads and simulates a Legic tag. Tested with MIM1024 tags. MIM256 and MIM512 should work to. We just read the data and for simulating we pretend to be a MIM1024 card. Co-authored-by: Stefanie Hofmann <> --- armsrc/Standalone/Makefile.hal | 2 +- armsrc/Standalone/Makefile.inc | 6 ++- armsrc/Standalone/hf_legic.c | 81 ++++++++++++++++++++++++++++++++++ armsrc/legicrf.c | 5 +++ armsrc/legicrf.h | 2 +- 5 files changed, 93 insertions(+), 3 deletions(-) create mode 100644 armsrc/Standalone/hf_legic.c diff --git a/armsrc/Standalone/Makefile.hal b/armsrc/Standalone/Makefile.hal index 5c2352aaf..bd018e15b 100644 --- a/armsrc/Standalone/Makefile.hal +++ b/armsrc/Standalone/Makefile.hal @@ -50,7 +50,7 @@ define KNOWN_STANDALONE_DEFINITIONS endef STANDALONE_MODES := LF_SAMYRUN LF_ICERUN LF_PROXBRUTE LF_HIDBRUTE LF_ICEHID LF_EM4100EMUL LF_EM4100RWC -STANDALONE_MODES += HF_YOUNG HF_MATTYRUN HF_COLIN HF_BOG HF_14ASNIFF +STANDALONE_MODES += HF_YOUNG HF_MATTYRUN HF_COLIN HF_BOG HF_14ASNIFF HF_LEGIC STANDALONE_MODES_REQ_SMARTCARD := STANDALONE_MODES_REQ_FLASH := HF_COLIN HF_BOG HF_14ASNIFF LF_ICEHID ifneq ($(filter $(STANDALONE),$(STANDALONE_MODES)),) diff --git a/armsrc/Standalone/Makefile.inc b/armsrc/Standalone/Makefile.inc index e5a3304a8..4b480ad3a 100644 --- a/armsrc/Standalone/Makefile.inc +++ b/armsrc/Standalone/Makefile.inc @@ -48,4 +48,8 @@ endif # WITH_STANDALONE_LF_EM4100RWC ifneq (,$(findstring WITH_STANDALONE_LF_EM4100RWC,$(APP_CFLAGS))) SRC_STANDALONE = lf_em4100rwc.c -endif \ No newline at end of file +endif +# WITH_STANDALONE_HF_LEGIC +ifneq (,$(findstring WITH_STANDALONE_HF_LEGIC,$(APP_CFLAGS))) + SRC_STANDALONE = hf_legic.c +endif diff --git a/armsrc/Standalone/hf_legic.c b/armsrc/Standalone/hf_legic.c new file mode 100644 index 000000000..f4a395737 --- /dev/null +++ b/armsrc/Standalone/hf_legic.c @@ -0,0 +1,81 @@ +//----------------------------------------------------------------------------- +// Stefanie Hofmann, 2020 +// Uli Heilmeier, 2020 +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// main code for Legic Prime read/sim +//----------------------------------------------------------------------------- +#include "standalone.h" +#include "proxmark3_arm.h" +#include "appmain.h" +#include "fpgaloader.h" +#include "util.h" +#include "dbprint.h" +#include "ticks.h" + +#include "legicrf.h" +#include "legicrfsim.h" + +void ModInfo(void) { + DbpString(" HF Legic Prime standalone "); +} + +// Searching for Legic card until found and read. +// Simulating recorded Legic Prime card. +// C = Searching +// A, B, C = Reading +// A, D = Simulating + +void RunMod(){ + StandAloneMode(); + FpgaDownloadAndGo(FPGA_BITSTREAM_HF); + Dbprintf(">> HF Legic Prime Read/Simulate Started <<"); + + int read_success; + for(;;){ + WDT_HIT(); + + //exit from hf_legic, send usbcommand + if(data_available()) break; + + //Was our button held down or pressed? + int button_pressed = BUTTON_HELD(280); + if(button_pressed != BUTTON_HOLD) continue; + + LED_A_OFF(); + LED_B_OFF(); + LED_C_ON(); + LED_D_OFF(); + + WAIT_BUTTON_RELEASED(); + + //record + DbpString("[=] start recording"); + + //search for legic card until reading successfull or button pressed + do{ + LED_C_ON(); + SpinDelay(1000); + // We don't care if we read a MIM256, MIM512 or MIM1024 + // we just read 1024 bytes + LegicRfReader(0, 1024, 0x55); + read_success = check_success(); + }while(read_success == 0 && !BUTTON_PRESS()); + + //simulate if read successfully + if(read_success == 1){ + LED_A_OFF(); + LED_B_OFF(); + LED_C_OFF(); + LED_D_ON(); + // The read data is migrated to a MIM1024 card + LegicRfSimulate(2); + }else{ + LEDsoff(); + WAIT_BUTTON_RELEASED(); + } + } +} diff --git a/armsrc/legicrf.c b/armsrc/legicrf.c index 0665705b6..78e6e19b4 100644 --- a/armsrc/legicrf.c +++ b/armsrc/legicrf.c @@ -28,6 +28,7 @@ static uint8_t *legic_mem; /* card memory, used for read, write */ static legic_card_select_t card;/* metadata of currently selected card */ static crc_t legic_crc; +int read_success = 0; //----------------------------------------------------------------------------- // Frame timing and pseudorandom number generator @@ -444,6 +445,7 @@ OUT: void LegicRfReader(uint16_t offset, uint16_t len, uint8_t iv) { // configure ARM and FPGA init_reader(false); + read_success = 0; // establish shared secret and detect card type uint8_t card_type = setup_phase(iv); @@ -467,6 +469,7 @@ void LegicRfReader(uint16_t offset, uint16_t len, uint8_t iv) { } // OK + read_success = 1; reply_old(CMD_ACK, 1, len, 0, legic_mem, len); OUT: @@ -512,3 +515,5 @@ OUT: switch_off(); StopTicks(); } + +int check_success(void){return read_success;} diff --git a/armsrc/legicrf.h b/armsrc/legicrf.h index 47a7f89d6..77233406d 100644 --- a/armsrc/legicrf.h +++ b/armsrc/legicrf.h @@ -17,5 +17,5 @@ void LegicRfInfo(void); void LegicRfReader(uint16_t offset, uint16_t len, uint8_t iv); void LegicRfWriter(uint16_t offset, uint16_t len, uint8_t iv, uint8_t *data); - +int check_success(void); #endif /* __LEGICRF_H */ From efeff2d0f68e209597e8dae07c70b029cbdf156f Mon Sep 17 00:00:00 2001 From: Iceman Date: Sat, 28 Mar 2020 15:05:52 +0100 Subject: [PATCH 1782/1854] Update cheatsheet.md --- doc/cheatsheet.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/doc/cheatsheet.md b/doc/cheatsheet.md index a3e0a220c..74a061b10 100644 --- a/doc/cheatsheet.md +++ b/doc/cheatsheet.md @@ -60,7 +60,7 @@ Dump iClass card contents ``` Options --- -k : *Access Key as 16 hex symbols or 1 hex to select key from memory +k : *Access Key as 16 hex symbols or 1 hex to select key from memory m3 --> hf iclass dump k 0 ``` @@ -69,8 +69,8 @@ Read iClass Block ``` Options --- -b : The block number as 2 hex symbols -k : Access Key as 16 hex symbols or 1 hex to select key from memory +b : The block number as 2 hex symbols +k : Access Key as 16 hex symbols or 1 hex to select key from memory pm3 --> hf iclass rdbl b 7 k 0 ``` @@ -79,9 +79,9 @@ Write to iClass Block ``` Options --- -b : The block number as 2 hex symbols +b : The block number as 2 hex symbols d : Set the Data to write as 16 hex symbols -k : Access Key as 16 hex symbols or 1 hex to select key from memory +k : Access Key as 16 hex symbols or 1 hex to select key from memory pm3 --> hf iclass wrbl b 07 d 6ce099fe7e614fd0 k 0 ``` @@ -102,7 +102,7 @@ Options n : specify the keyNbr to set in memory k : set a key in memory -pm3 --> hf iclass managekeys n 0 k AFA785A7DAB33378 +pm3 --> hf iclass managekeys n 3 k AFA785A7DAB33378 ``` Encrypt iClass Block @@ -124,9 +124,10 @@ Simulate iClass Options --- 0 simulate the given CSN -2 Runs part 1 of LOCLASS attack 1 simulate default CSN +2 Runs online part of LOCLASS attack 3 Full simulation using emulator memory (see 'hf iclass eload') +4 Runs online part of LOCLASS attack against reader in keyroll mode pm3 --> hf iclass sim 3 ``` @@ -149,7 +150,7 @@ Extract custom iClass key (loclass attack) Options --- f : specify a filename to clone from -k : Access Key as 16 hex symbols or 1 hex to select key from memory +k : Access Key as 16 hex symbols or 1 hex to select key from memory e : If 'e' is specified, elite computations applied to key pm3 --> hf iclass sim 2 From 9356549bc6592d391f72c6f623553ac912c4b75f Mon Sep 17 00:00:00 2001 From: Winds <60715874+Windslab@users.noreply.github.com> Date: Sat, 28 Mar 2020 18:23:05 +0300 Subject: [PATCH 1783/1854] textual Correcting a script name --- client/luascripts/{hf-writer.lua => hf_writer.lua} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename client/luascripts/{hf-writer.lua => hf_writer.lua} (100%) diff --git a/client/luascripts/hf-writer.lua b/client/luascripts/hf_writer.lua similarity index 100% rename from client/luascripts/hf-writer.lua rename to client/luascripts/hf_writer.lua From a79a11256a887e6c435bee8aa1b4dbffe35be700 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 29 Mar 2020 07:48:01 +0200 Subject: [PATCH 1784/1854] revert --- client/cliparser/argtable3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cliparser/argtable3.c b/client/cliparser/argtable3.c index b8644dd86..3acbce48e 100644 --- a/client/cliparser/argtable3.c +++ b/client/cliparser/argtable3.c @@ -250,7 +250,7 @@ const char *optarg; /* argument associated with option */ #define BADARG ((*options == ':') ? (int)':' : (int)'?') #define INORDER (int)1 -#define EMSG " " +#define EMSG "" static int getopt_internal(int, char *const *, const char *, const struct option *, int *, int); From db02a1f3065583804ad1f8e404fd3c7ebd4dd946 Mon Sep 17 00:00:00 2001 From: Uli Heilmeier Date: Mon, 30 Mar 2020 10:22:45 +0200 Subject: [PATCH 1785/1854] HF_Legic: remove global variable and cleanup As requested by @iceman1001: * removed global variable * updated according to make style * added entry in CHANGELOG.md --- CHANGELOG.md | 1 + armsrc/Standalone/hf_legic.c | 81 ++++++++++++++++++------------------ armsrc/legicrf.c | 8 ++-- armsrc/legicrf.h | 3 +- 4 files changed, 45 insertions(+), 48 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6192b8068..3032b04fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Added `HF_LEGIC` standalone mode to read and simulate a Legic prime tag (@Pizza_4u) - Added keri MS decode/encode and update 'lf keri clone' to support MS fc/cid cloning. (@mwalker33) - Fix 'hf mfdes enum' - now actually manages to enumerate files under all AID's. :smiley: (@iceman1001) - Fix 'hf mfdes info' - now detects DESFire light and work properly Wrapped commands :+1: (@iceman1001) diff --git a/armsrc/Standalone/hf_legic.c b/armsrc/Standalone/hf_legic.c index f4a395737..1e7aa7114 100644 --- a/armsrc/Standalone/hf_legic.c +++ b/armsrc/Standalone/hf_legic.c @@ -20,7 +20,7 @@ #include "legicrfsim.h" void ModInfo(void) { - DbpString(" HF Legic Prime standalone "); + DbpString(" HF Legic Prime standalone "); } // Searching for Legic card until found and read. @@ -29,53 +29,52 @@ void ModInfo(void) { // A, B, C = Reading // A, D = Simulating -void RunMod(){ - StandAloneMode(); - FpgaDownloadAndGo(FPGA_BITSTREAM_HF); - Dbprintf(">> HF Legic Prime Read/Simulate Started <<"); +void RunMod() { + StandAloneMode(); + FpgaDownloadAndGo(FPGA_BITSTREAM_HF); + Dbprintf(">> HF Legic Prime Read/Simulate Started <<"); - int read_success; - for(;;){ - WDT_HIT(); + int read_success; + for (;;) { + WDT_HIT(); - //exit from hf_legic, send usbcommand - if(data_available()) break; + //exit from hf_legic, send usbcommand + if (data_available()) break; - //Was our button held down or pressed? - int button_pressed = BUTTON_HELD(280); - if(button_pressed != BUTTON_HOLD) continue; + //Was our button held down or pressed? + int button_pressed = BUTTON_HELD(280); + if (button_pressed != BUTTON_HOLD) continue; - LED_A_OFF(); - LED_B_OFF(); - LED_C_ON(); - LED_D_OFF(); + LED_A_OFF(); + LED_B_OFF(); + LED_C_ON(); + LED_D_OFF(); - WAIT_BUTTON_RELEASED(); + WAIT_BUTTON_RELEASED(); - //record - DbpString("[=] start recording"); + //record + DbpString("[=] start recording"); - //search for legic card until reading successfull or button pressed - do{ - LED_C_ON(); - SpinDelay(1000); - // We don't care if we read a MIM256, MIM512 or MIM1024 - // we just read 1024 bytes - LegicRfReader(0, 1024, 0x55); - read_success = check_success(); - }while(read_success == 0 && !BUTTON_PRESS()); + //search for legic card until reading successfull or button pressed + do { + LED_C_ON(); + SpinDelay(1000); + // We don't care if we read a MIM256, MIM512 or MIM1024 + // we just read 1024 bytes + read_success = LegicRfReader(0, 1024, 0x55); + } while (read_success == 0 && !BUTTON_PRESS()); - //simulate if read successfully - if(read_success == 1){ - LED_A_OFF(); - LED_B_OFF(); - LED_C_OFF(); - LED_D_ON(); - // The read data is migrated to a MIM1024 card - LegicRfSimulate(2); - }else{ - LEDsoff(); - WAIT_BUTTON_RELEASED(); + //simulate if read successfully + if (read_success == 1) { + LED_A_OFF(); + LED_B_OFF(); + LED_C_OFF(); + LED_D_ON(); + // The read data is migrated to a MIM1024 card + LegicRfSimulate(2); + } else { + LEDsoff(); + WAIT_BUTTON_RELEASED(); + } } - } } diff --git a/armsrc/legicrf.c b/armsrc/legicrf.c index 78e6e19b4..313b38fc5 100644 --- a/armsrc/legicrf.c +++ b/armsrc/legicrf.c @@ -28,7 +28,6 @@ static uint8_t *legic_mem; /* card memory, used for read, write */ static legic_card_select_t card;/* metadata of currently selected card */ static crc_t legic_crc; -int read_success = 0; //----------------------------------------------------------------------------- // Frame timing and pseudorandom number generator @@ -442,10 +441,10 @@ OUT: StopTicks(); } -void LegicRfReader(uint16_t offset, uint16_t len, uint8_t iv) { +int LegicRfReader(uint16_t offset, uint16_t len, uint8_t iv) { + int read_success = 0; // configure ARM and FPGA init_reader(false); - read_success = 0; // establish shared secret and detect card type uint8_t card_type = setup_phase(iv); @@ -475,6 +474,7 @@ void LegicRfReader(uint16_t offset, uint16_t len, uint8_t iv) { OUT: switch_off(); StopTicks(); + return read_success; } void LegicRfWriter(uint16_t offset, uint16_t len, uint8_t iv, uint8_t *data) { @@ -515,5 +515,3 @@ OUT: switch_off(); StopTicks(); } - -int check_success(void){return read_success;} diff --git a/armsrc/legicrf.h b/armsrc/legicrf.h index 77233406d..6e59f4ca7 100644 --- a/armsrc/legicrf.h +++ b/armsrc/legicrf.h @@ -15,7 +15,6 @@ #include "common.h" void LegicRfInfo(void); -void LegicRfReader(uint16_t offset, uint16_t len, uint8_t iv); +int LegicRfReader(uint16_t offset, uint16_t len, uint8_t iv); void LegicRfWriter(uint16_t offset, uint16_t len, uint8_t iv, uint8_t *data); -int check_success(void); #endif /* __LEGICRF_H */ From 0733310300dcb80f79e0ae0c99b3fd8865ece616 Mon Sep 17 00:00:00 2001 From: Uli Heilmeier Date: Mon, 30 Mar 2020 11:03:43 +0200 Subject: [PATCH 1786/1854] Makefile: target checks for macOS recode is missing on macOS by default. grep on macOS is BSD grep by default. --- Makefile | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Makefile b/Makefile index 783b5fa27..5c7947fc5 100644 --- a/Makefile +++ b/Makefile @@ -210,13 +210,20 @@ style: # Detecting weird codepages and tabs. checks: + # Make sure recode is installed + @which recode >/dev/null || ( echo "Please install 'recode' package first" ; exit 1 ) @echo "Files with suspicious chars:" @find . \( -name "*.[ch]" -or -name "*.cpp" -or -name "*.lua" -or -name "*.py" -or -name "*.pl" -or -name "Makefile" -or -name "*.v" \) \ -exec sh -c "cat {} |recode utf8.. >/dev/null || echo {}" \; @echo "Files with tabs:" # to remove tabs within lines, one can try with: vi $file -c ':set tabstop=4' -c ':set et|retab' -c ':wq' +ifeq ($(platform),Darwin) + @find . \( -name "*.[ch]" -or \( -name "*.cpp" -and -not -name "*.moc.cpp" \) -or -name "*.lua" -or -name "*.py" -or -name "*.pl" -or -name "*.md" -or -name "*.txt" -or -name "*.awk" -or -name "*.v" \) \ + -exec egrep -l '\t' {} \; +else @find . \( -name "*.[ch]" -or \( -name "*.cpp" -and -not -name "*.moc.cpp" \) -or -name "*.lua" -or -name "*.py" -or -name "*.pl" -or -name "*.md" -or -name "*.txt" -or -name "*.awk" -or -name "*.v" \) \ -exec grep -lP '\t' {} \; +endif # @echo "Files with printf \\\\t:" # @find . \( -name "*.[ch]" -or \( -name "*.cpp" -and -not -name "*.moc.cpp" \) -or -name "*.lua" -or -name "*.py" -or -name "*.pl" -or -name "*.md" -or -name "*.txt" -or -name "*.awk" -or -name "*.v" \) \ # -exec grep -lP '\\t' {} \; From c8b51ccf255166537c640272201c6df73aab9e8c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 30 Mar 2020 15:11:48 +0200 Subject: [PATCH 1787/1854] chg: legic standalone - now saves read cards to flashmemory (RDV4)\n also simulates correct cardtype.\n It goes direct into recording / reading a tag. Once a complete dump is done, it starts to simulate --- armsrc/Standalone/hf_legic.c | 147 ++++++++++++++++++++++++++++------- armsrc/legicrf.c | 51 +++++++++++- armsrc/legicrf.h | 7 +- armsrc/legicrfsim.c | 6 +- 4 files changed, 176 insertions(+), 35 deletions(-) diff --git a/armsrc/Standalone/hf_legic.c b/armsrc/Standalone/hf_legic.c index 1e7aa7114..2b826528f 100644 --- a/armsrc/Standalone/hf_legic.c +++ b/armsrc/Standalone/hf_legic.c @@ -1,6 +1,6 @@ //----------------------------------------------------------------------------- -// Stefanie Hofmann, 2020 -// Uli Heilmeier, 2020 +// (c) Stefanie Hofmann, 2020 +// (c) Uli Heilmeier, 2020 // // This code is licensed to you under the terms of the GNU GPL, version 2 or, // at your option, any later version. See the LICENSE.txt file for the text of @@ -8,19 +8,89 @@ //----------------------------------------------------------------------------- // main code for Legic Prime read/sim //----------------------------------------------------------------------------- + #include "standalone.h" #include "proxmark3_arm.h" +#include "BigBuf.h" #include "appmain.h" #include "fpgaloader.h" #include "util.h" #include "dbprint.h" #include "ticks.h" - #include "legicrf.h" #include "legicrfsim.h" +#include "legic.h" // legic_card_select_t struct +#include "spiffs.h" // flashmem + + +/* + * To list all dump files from flash: + * + * 1. mem spiffs tree + * + * + * To retrieve dump files from flash: + * + * 1. mem spiffs dump o hf-legic-XXYYZZWW-dump.bin f hf-legic-XXYYZZWW-dump.bin + * Copies log file from flash to your client. + * + * + * This module emits debug strings during normal operation -- so try it out in + * the lab connected to PM3 client before taking it into the field. + * + * To delete a dump file from flash: + * + * 1. mem spiffs remove hf-legic-XXYYZZWW-dump.bin + * +*/ + +void DownloadLogInstructions() { + Dbprintf(""); + Dbprintf("[=] List all dumps from flash:"); + Dbprintf("[=] " _YELLOW_("-") "mem spiffs tree"); + Dbprintf(""); + Dbprintf("[=] To save a dump file from flash to client:"); + Dbprintf("[=] " _YELLOW_("-") "mem spiffs dump o hf-legic-UID-dump.bin f hf-legic-UID-dump.bin"); +} + +void save_dump_to_file(legic_card_select_t *p_card) { + +#ifdef WITH_FLASH + + // legic functions puts it memory in Emulator reserved memory. + uint8_t *mem = BigBuf_get_EM_addr(); + + char *preferredName = (char*)BigBuf_malloc(30); + if (preferredName == NULL) { + goto OUT; + } + + sprintf(preferredName, "hf-legic-%02X%02X%02X%02X-dump", p_card->uid[0], p_card->uid[1], p_card->uid[2], p_card->uid[3]); + uint16_t preferredNameLen = strlen(preferredName); + + char *filename = (char*)BigBuf_malloc(preferredNameLen + 4 + 1 + 10); + if (filename == NULL) { + goto OUT; + } + + sprintf(filename, "%.*s%s", preferredNameLen, preferredName, ".bin"); + uint16_t num = 1; + while (exists_in_spiffs(filename)) { + sprintf(filename, "%.*s-%d%s", preferredNameLen, preferredName, num, ".bin"); + num++; + } + + rdv40_spiffs_write(filename, mem, p_card->cardsize, RDV40_SPIFFS_SAFETY_SAFE); + + Dbprintf("[=] saved card dump to flashmem::" _YELLOW_("%s"), filename); +OUT: + BigBuf_free_keep_EM(); +#endif + +} void ModInfo(void) { - DbpString(" HF Legic Prime standalone "); + DbpString(" HF Legic Prime standalone"); } // Searching for Legic card until found and read. @@ -32,49 +102,72 @@ void ModInfo(void) { void RunMod() { StandAloneMode(); FpgaDownloadAndGo(FPGA_BITSTREAM_HF); - Dbprintf(">> HF Legic Prime Read/Simulate Started <<"); - - int read_success; + Dbprintf("[=] >> HF Legic Prime Read/Simulate Started <<"); + DbpString("[=] press and HOLD button to exit standalone mode"); for (;;) { WDT_HIT(); - + //exit from hf_legic, send usbcommand if (data_available()) break; //Was our button held down or pressed? int button_pressed = BUTTON_HELD(280); - if (button_pressed != BUTTON_HOLD) continue; + if (button_pressed == BUTTON_HOLD) { + break; + } - LED_A_OFF(); - LED_B_OFF(); + LEDsoff(); LED_C_ON(); - LED_D_OFF(); - WAIT_BUTTON_RELEASED(); - - //record - DbpString("[=] start recording"); + DbpString("[=] looking for tags"); + int read_success = PM3_ESOFT; //search for legic card until reading successfull or button pressed do { LED_C_ON(); - SpinDelay(1000); + SpinDelay(500); // We don't care if we read a MIM256, MIM512 or MIM1024 // we just read 1024 bytes - read_success = LegicRfReader(0, 1024, 0x55); - } while (read_success == 0 && !BUTTON_PRESS()); + read_success = LegicRfReaderEx(0, 1024, 0x55); + + } while (read_success == PM3_ESOFT && !BUTTON_PRESS()); + + LEDsoff(); //simulate if read successfully - if (read_success == 1) { - LED_A_OFF(); - LED_B_OFF(); - LED_C_OFF(); + if (read_success != PM3_ESOFT) { + + legic_card_select_t *p_card; + p_card = getLegicCardInfo(); + if (p_card->cardsize == 0) + continue; + + save_dump_to_file(p_card); + LED_D_ON(); + uint8_t ct; + switch(p_card->tagtype) { + case 0x0D: + ct = 0; + break; + case 0x1D: + ct = 1; + break; + case 0x3D: + ct = 2; + break; + default: + continue; + } + // The read data is migrated to a MIM1024 card - LegicRfSimulate(2); - } else { - LEDsoff(); - WAIT_BUTTON_RELEASED(); + LegicRfSimulate(ct); } } + + LEDsoff(); +#ifdef WITH_FLASH + DownloadLogInstructions(); +#endif + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); } diff --git a/armsrc/legicrf.c b/armsrc/legicrf.c index 313b38fc5..35b638298 100644 --- a/armsrc/legicrf.c +++ b/armsrc/legicrf.c @@ -404,6 +404,10 @@ bool write_byte(uint16_t index, uint8_t byte, uint8_t addr_sz) { // // Only this functions are public / called from appmain.c //----------------------------------------------------------------------------- +legic_card_select_t* getLegicCardInfo(void) { + return &card; +} + void LegicRfInfo(void) { // configure ARM and FPGA init_reader(false); @@ -441,8 +445,45 @@ OUT: StopTicks(); } -int LegicRfReader(uint16_t offset, uint16_t len, uint8_t iv) { - int read_success = 0; +int LegicRfReaderEx(uint16_t offset, uint16_t len, uint8_t iv) { + + int res = PM3_SUCCESS; + + // configure ARM and FPGA + init_reader(false); + + // establish shared secret and detect card type + uint8_t card_type = setup_phase(iv); + if (init_card(card_type, &card) != 0) { + res = PM3_ESOFT; + goto OUT; + } + + // do not read beyond card memory + if (len + offset > card.cardsize) { + len = card.cardsize - offset; + } + + for (uint16_t i = 0; i < len; ++i) { + int16_t byte = read_byte(offset + i, card.cmdsize); + if (byte == -1) { + res = PM3_EOVFLOW; + goto OUT; + } + legic_mem[i] = byte; + + if (i < 4) { + card.uid[i] = byte; + } + } + +OUT: + switch_off(); + StopTicks(); + return res; +} + +void LegicRfReader(uint16_t offset, uint16_t len, uint8_t iv) { // configure ARM and FPGA init_reader(false); @@ -465,16 +506,18 @@ int LegicRfReader(uint16_t offset, uint16_t len, uint8_t iv) { goto OUT; } legic_mem[i] = byte; + + if (i < 4) { + card.uid[i] = byte; + } } // OK - read_success = 1; reply_old(CMD_ACK, 1, len, 0, legic_mem, len); OUT: switch_off(); StopTicks(); - return read_success; } void LegicRfWriter(uint16_t offset, uint16_t len, uint8_t iv, uint8_t *data) { diff --git a/armsrc/legicrf.h b/armsrc/legicrf.h index 6e59f4ca7..ae4c78cdc 100644 --- a/armsrc/legicrf.h +++ b/armsrc/legicrf.h @@ -1,6 +1,7 @@ //----------------------------------------------------------------------------- // (c) 2009 Henryk Plötz // 2018 AntiCat +// 2020 iceman // // This code is licensed to you under the terms of the GNU GPL, version 2 or, // at your option, any later version. See the LICENSE.txt file for the text of @@ -13,8 +14,12 @@ #define __LEGICRF_H #include "common.h" +#include "legic.h" /* legic_card_select_t struct */ void LegicRfInfo(void); -int LegicRfReader(uint16_t offset, uint16_t len, uint8_t iv); +int LegicRfReaderEx(uint16_t offset, uint16_t len, uint8_t iv); +void LegicRfReader(uint16_t offset, uint16_t len, uint8_t iv); void LegicRfWriter(uint16_t offset, uint16_t len, uint8_t iv, uint8_t *data); + +legic_card_select_t* getLegicCardInfo(void); #endif /* __LEGICRF_H */ diff --git a/armsrc/legicrfsim.c b/armsrc/legicrfsim.c index 34f8458ce..bbec86fa5 100644 --- a/armsrc/legicrfsim.c +++ b/armsrc/legicrfsim.c @@ -460,12 +460,12 @@ void LegicRfSimulate(uint8_t cardtype) { // verify command line input if (init_card(cardtype, &card) != 0) { - DbpString("Unknown tagtype."); + DbpString("[!] Unknown tagtype."); goto OUT; } LED_A_ON(); - DbpString("Starting Legic emulator, press button to end"); + DbpString("[=] Starting Legic emulator, press " _YELLOW_("button") "to end"); while (!BUTTON_PRESS() && !data_available()) { WDT_HIT(); @@ -486,7 +486,7 @@ void LegicRfSimulate(uint8_t cardtype) { } OUT: - DbpString("Stopped"); + DbpString("[=] Sim stopped"); switch_off(); StopTicks(); } From 924ad84c59d90f6685a26c3faea665c04db68995 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 30 Mar 2020 15:12:06 +0200 Subject: [PATCH 1788/1854] textual --- armsrc/Standalone/lf_icehid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/Standalone/lf_icehid.c b/armsrc/Standalone/lf_icehid.c index 34d4439a0..33d4ed764 100644 --- a/armsrc/Standalone/lf_icehid.c +++ b/armsrc/Standalone/lf_icehid.c @@ -37,7 +37,7 @@ * To retrieve log file from flash: * * 1. mem spiffs dump o lf_hidcollect.log f lf_hidcollect.log - * Copies log file from flash to your PC. + * Copies log file from flash to your client. * * 2. exit the Proxmark3 client * From 83a5ffbb1084f010ce60b96294c25ebf37220877 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 30 Mar 2020 15:12:37 +0200 Subject: [PATCH 1789/1854] textual --- armsrc/Standalone/lf_em4100rwc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/armsrc/Standalone/lf_em4100rwc.c b/armsrc/Standalone/lf_em4100rwc.c index a2414a6fa..02366d0a6 100644 --- a/armsrc/Standalone/lf_em4100rwc.c +++ b/armsrc/Standalone/lf_em4100rwc.c @@ -121,6 +121,8 @@ void SaveIDtoFlash(int addr, uint64_t id) { void RunMod() { StandAloneMode(); FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + Dbprintf("[=] >> LF EM4100 read/write/clone started <<"); + int selected = 0; //state 0 - select slot // 1 - read tag to selected slot, From 690a2b89e08779ee97095d7b85372769be6b2044 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 30 Mar 2020 15:16:11 +0200 Subject: [PATCH 1790/1854] textual --- armsrc/Standalone/lf_em4100emul.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/armsrc/Standalone/lf_em4100emul.c b/armsrc/Standalone/lf_em4100emul.c index f3939f923..7b38133bc 100644 --- a/armsrc/Standalone/lf_em4100emul.c +++ b/armsrc/Standalone/lf_em4100emul.c @@ -82,6 +82,8 @@ void LED_Slot(int i) { void RunMod() { StandAloneMode(); FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + Dbprintf("[=] >> LF EM4100 simulator started <<"); + int selected = 0; //selected slot after start slots_count = sizeof(low) / sizeof(low[0]); bba = BigBuf_get_addr(); From 41780175366c08ff50b4381de4cfb1a5dd4892e1 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 30 Mar 2020 15:18:25 +0200 Subject: [PATCH 1791/1854] chg: hf legic dump - change filename template --- client/cmdhflegic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdhflegic.c b/client/cmdhflegic.c index 022857584..2060b64e2 100644 --- a/client/cmdhflegic.c +++ b/client/cmdhflegic.c @@ -948,7 +948,7 @@ static int CmdLegicDump(const char *Cmd) { // user supplied filename? if (fileNlen < 1) - sprintf(fnameptr, "%02X%02X%02X%02X.bin", data[0], data[1], data[2], data[3]); + sprintf(fnameptr, "hf-legic-%02X%02X%02X%02X-dump.bin", data[0], data[1], data[2], data[3]); else sprintf(fnameptr + fileNlen, ".bin"); From 9ca14acf5e858a323178912cc27c3db5c97b82a3 Mon Sep 17 00:00:00 2001 From: Iceman Date: Mon, 30 Mar 2020 15:27:32 +0200 Subject: [PATCH 1792/1854] Update Mac-OS-X-Homebrew-Installation-Instructions.md --- .../Mac-OS-X-Homebrew-Installation-Instructions.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md b/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md index 6ce8b5990..367452454 100644 --- a/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md @@ -85,6 +85,12 @@ These instructions will show how to setup the environment on OSX to the point wh brew install readline qt5 pkgconfig brew install RfidResearchGroup/proxmark3/arm-none-eabi-gcc ``` +3. (optional) Install makefile dependencies: +``` +brew install recode +brew install astyle +``` + ## Compile and use the project From 4920bd8ab055f07b8c035167018c83d0f4e90351 Mon Sep 17 00:00:00 2001 From: Iceman Date: Mon, 30 Mar 2020 16:31:54 +0200 Subject: [PATCH 1793/1854] Update Makefile.hal --- armsrc/Standalone/Makefile.hal | 3 +++ 1 file changed, 3 insertions(+) diff --git a/armsrc/Standalone/Makefile.hal b/armsrc/Standalone/Makefile.hal index bd018e15b..e3ad8accb 100644 --- a/armsrc/Standalone/Makefile.hal +++ b/armsrc/Standalone/Makefile.hal @@ -47,6 +47,9 @@ define KNOWN_STANDALONE_DEFINITIONS | LF_EM4100RWC | Read/simulate em4100 tags & clone it | | | to T555x tags | +----------------------------------------------------------+ +| HF_LEGIC | Read/simulate Legic Prime tags | +| | storing in flashmem | ++----------------------------------------------------------+ endef STANDALONE_MODES := LF_SAMYRUN LF_ICERUN LF_PROXBRUTE LF_HIDBRUTE LF_ICEHID LF_EM4100EMUL LF_EM4100RWC From 09d96888006b633fc2bd2df7ba797c3ffa332eb3 Mon Sep 17 00:00:00 2001 From: Iceman Date: Mon, 30 Mar 2020 16:36:05 +0200 Subject: [PATCH 1794/1854] Update 4_Advanced-compilation-parameters.md --- doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md b/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md index 01b7d083a..561cae95d 100644 --- a/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md +++ b/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md @@ -82,6 +82,9 @@ Here are the supported values you can assign to `STANDALONE` in `Makefile.platfo | HF_BOG | 14a sniff with ULC/ULEV1/NTAG auth storing in flashmem - Bogito | HF_14ASNIFF | 14a sniff storing to flashmem - Micolous | LF_ICEHID | LF HID collector to flashmem - Iceman +| LF_EM4100EMUL | LF EM4100 simulator standalone mode - temskiy +| LF_EM4100RWC | LF EM4100 read/write/clone mode - temskiy +| HF_LEGIC | HF Legic Prime standalone - uhei By default `STANDALONE=LF_SAMYRUN`. From 8eef5d188c30a5c70fe3af87cc96fe8d1f8e54f2 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 30 Mar 2020 22:25:00 +0200 Subject: [PATCH 1795/1854] fix coverity 226432 --- client/emv/cmdemv.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c index e3c88c3e3..baef18d04 100644 --- a/client/emv/cmdemv.c +++ b/client/emv/cmdemv.c @@ -662,10 +662,7 @@ static void InitTransactionParameters(struct tlvdb *tlvRoot, bool paramLoadJSON, } //9F66:(Terminal Transaction Qualifiers (TTQ)) len:4 - const char *qVSDC = "\x26\x00\x00\x00"; - if (GenACGPO) { - qVSDC = "\x26\x80\x00\x00"; - } + switch (TrType) { case TT_MSD: TLV_ADD(0x9F66, "\x86\x00\x00\x00"); // MSD @@ -675,10 +672,20 @@ static void InitTransactionParameters(struct tlvdb *tlvRoot, bool paramLoadJSON, TLV_ADD(0x9F66, "\x46\x00\x00\x00"); // VSDC break; case TT_QVSDCMCHIP: - TLV_ADD(0x9F66, qVSDC); // qVSDC + // qVSDC + if (GenACGPO) { + TLV_ADD(0x9F66, "\x26\x80\x00\x00"); + } else { + TLV_ADD(0x9F66, "\x26\x00\x00\x00"); + } break; case TT_CDA: - TLV_ADD(0x9F66, qVSDC); // qVSDC (VISA CDA not enabled) + // qVSDC (VISA CDA not enabled) + if (GenACGPO) { + TLV_ADD(0x9F66, "\x26\x80\x00\x00"); + } else { + TLV_ADD(0x9F66, "\x26\x00\x00\x00"); + } break; default: break; From 978dde98a976bac379b98aa21af31664da57ee52 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 31 Mar 2020 08:06:45 +0200 Subject: [PATCH 1796/1854] added more sigs --- client/mifare/ndef.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/client/mifare/ndef.c b/client/mifare/ndef.c index 392a550af..e359e03fa 100644 --- a/client/mifare/ndef.c +++ b/client/mifare/ndef.c @@ -32,16 +32,24 @@ static const char *TypeNameFormat_s[] = { static const char *ndefSigType_s[] = { "Not present", // No signature present - "RSASSA_PSS_SHA_1", // PKCS_1 - "RSASSA_PKCS1_v1_5_WITH_SHA_1", // PKCS_1 - "DSA", - "ECDSA", + "RSASSA_PSS_SHA_1 (1024)", // PKCS_1 + "RSASSA_PKCS1_v1_5_WITH_SHA_1 (1024)", // PKCS_1 + "DSA-1024", + "ECDSA-P192", + "RSASSA-PSS-2048", + "RSASSA-PKCS1-v1_5-2048", + "DSA-2048", + "ECDSA-P224", + "ECDSA-K233", + "ECDSA-B233", + "ECDSA-P256", "n/a" + }; static const char *ndefCertificateFormat_s[] = { "X_509", - "X9_68", + "X9_68 (M2M)", "n/a" }; From e13a25902fcb50fc7fb6e0344addde1c497981f0 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 31 Mar 2020 08:11:27 +0200 Subject: [PATCH 1797/1854] added more sigs --- client/mifare/ndef.c | 2 +- client/mifare/ndef.h | 17 ++++++++++++----- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/client/mifare/ndef.c b/client/mifare/ndef.c index e359e03fa..df8264330 100644 --- a/client/mifare/ndef.c +++ b/client/mifare/ndef.c @@ -177,7 +177,7 @@ static int ndefDecodeSig(uint8_t *sig, size_t siglen) { size_t intsiglen = (sig[indx + 1] << 8) + sig[indx + 2]; // ecdsa 0x04 - if (sigType == stECDSA) { + if (sigType == stECDSA_P192) { indx += 3; PrintAndLogEx(NORMAL, "\tsignature [%zu]: %s", intsiglen, sprint_hex_inrow(&sig[indx], intsiglen)); diff --git a/client/mifare/ndef.h b/client/mifare/ndef.h index 7d9ca2fbf..71afda2ee 100644 --- a/client/mifare/ndef.h +++ b/client/mifare/ndef.h @@ -24,12 +24,19 @@ typedef enum { } TypeNameFormat_t; typedef enum { - stNotPresent = 0x00, - stRSASSA_PSS_SHA_1 = 0x01, + stNotPresent = 0x00, + stRSASSA_PSS_SHA_1 = 0x01, stRSASSA_PKCS1_v1_5_WITH_SHA_1 = 0x02, - stDSA = 0x03, - stECDSA = 0x04, - stNA = 0x05 + stDSA_1024 = 0x03, + stECDSA_P192 = 0x04, + stRSASSA_PSS_2048 = 0x05, + stRSASSA_PKCS1_v1_5_2048 = 0x06, + stDSA_2048 = 0x07, + stECDSA_P224 = 0x08, + stECDSA_K233 = 0x09, + stECDSA_B233 = 0x0a, + stECDSA_P256 = 0x0b, + stNA = 0x0c } ndefSigType_t; typedef enum { From 392da6400ae1d3e9882919d3193d47f723a16f3d Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 31 Mar 2020 09:44:36 +0200 Subject: [PATCH 1798/1854] chg: waiting for shiftregisters (@pwpiwi) --- common_arm/usb_cdc.c | 82 ++++++++++++++++++++++++++++---------------- 1 file changed, 53 insertions(+), 29 deletions(-) diff --git a/common_arm/usb_cdc.c b/common_arm/usb_cdc.c index b146715a1..ca2c1986a 100644 --- a/common_arm/usb_cdc.c +++ b/common_arm/usb_cdc.c @@ -289,7 +289,7 @@ static const char CompatIDFeatureDescriptor[] = { MS_EXTENDED_COMPAT_ID, 0x00, // Compatibility ID Descriptor Index 0x0004 0x01, // Number of sections. 0x1 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Reserved (7bytes) - //-----function section 1------ + // -----function section 1------ 0x00, // Interface Number #0 0x01, // reserved (0x1) 0x57, 0x49, 0x4E, 0x55, 0x53, 0x42, 0x00, 0x00, // Compatible ID ('WINUSB\0\0') (8bytes) @@ -310,7 +310,7 @@ static const char OSprop[] = { // u16 wCount -- three section 3, 0, - //-----property section 1------ + // -----property section 1------ // u32 size ( 14+40+78 == 132) 132, 0, 0, 0, // u32 type @@ -326,7 +326,7 @@ static const char OSprop[] = { '-',0,'1',0,'1',0,'c',0,'e',0,'-',0,'b',0,'f',0,'c',0,'1',0,'-',0,'0',0,'8',0,'0',0, '0',0,'2',0,'b',0,'e',0,'1',0,'0',0,'3',0,'1',0,'8',0,'}',0,0,0, - //-----property section 2------ + // -----property section 2------ // u32 size ( 14+12+38 == 64) 64, 0, 0, 0, // u32 type @@ -340,7 +340,7 @@ static const char OSprop[] = { // data 'Awesome PM3 Device' 'A',0,'w',0,'e',0,'s',0,'o',0,'m',0,'e',0,' ',0,'P',0,'M',0,'3',0,' ',0,'D',0,'e',0,'v',0,'i',0,'c',0,'e',0,0,0, - //-----property section 3------ + // -----property section 3------ // u32 size ( 14+12+76 == 102) 102, 0, 0, 0, // u32 type @@ -473,10 +473,12 @@ static void SpinDelayUs(int us) { } } -//*---------------------------------------------------------------------------- -//* \fn usb_disable -//* \brief This function deactivates the USB device -//*---------------------------------------------------------------------------- +/* + *---------------------------------------------------------------------------- + * \fn usb_disable + * \brief This function deactivates the USB device + *---------------------------------------------------------------------------- +*/ void usb_disable() { // Disconnect the USB device AT91C_BASE_PIOA->PIO_ODR = GPIO_USB_PU; @@ -487,10 +489,12 @@ void usb_disable() { } } -//*---------------------------------------------------------------------------- -//* \fn usb_enable -//* \brief This function Activates the USB device -//*---------------------------------------------------------------------------- +/* + *---------------------------------------------------------------------------- + * \fn usb_enable + * \brief This function Activates the USB device + *---------------------------------------------------------------------------- +*/ void usb_enable() { // Set the PLL USB Divider AT91C_BASE_CKGR->CKGR_PLLR |= AT91C_CKGR_USBDIV_1 ; @@ -523,10 +527,12 @@ void usb_enable() { AT91C_BASE_PIOA->PIO_OER = GPIO_USB_PU; } -//*---------------------------------------------------------------------------- -//* \fn usb_check -//* \brief Test if the device is configured and handle enumeration -//*---------------------------------------------------------------------------- +/* + *---------------------------------------------------------------------------- + * \fn usb_check + * \brief Test if the device is configured and handle enumeration + *---------------------------------------------------------------------------- +*/ static int usb_reconnect = 0; static int usb_configured = 0; void SetUSBreconnect(int value) { @@ -612,10 +618,12 @@ bool usb_poll_validate_length() { return ((pUdp->UDP_CSR[AT91C_EP_OUT] & AT91C_UDP_RXBYTECNT) >> 16) > 0; } -//*---------------------------------------------------------------------------- -//* \fn usb_read -//* \brief Read available data from Endpoint 1 OUT (host to device) -//*---------------------------------------------------------------------------- +/* + *---------------------------------------------------------------------------- + * \fn usb_read + * \brief Read available data from Endpoint 1 OUT (host to device) + *---------------------------------------------------------------------------- +*/ uint32_t usb_read(uint8_t *data, size_t len) { if (len == 0) return 0; @@ -709,10 +717,12 @@ uint32_t usb_read_ng(uint8_t *data, size_t len) { return nbBytesRcv; } -//*---------------------------------------------------------------------------- -//* \fn usb_write -//* \brief Send through endpoint 2 (device to host) -//*---------------------------------------------------------------------------- +/* + *---------------------------------------------------------------------------- + * \fn usb_write + * \brief Send through endpoint 2 (device to host) + *---------------------------------------------------------------------------- +*/ int usb_write(const uint8_t *data, const size_t len) { if (!len) return PM3_EINVARG; @@ -733,6 +743,7 @@ int usb_write(const uint8_t *data, const size_t len) { } UDP_SET_EP_FLAGS(AT91C_EP_IN, AT91C_UDP_TXPKTRDY); + while (pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXPKTRDY) {}; while (length) { // Send next chunk @@ -750,8 +761,9 @@ int usb_write(const uint8_t *data, const size_t len) { UDP_CLEAR_EP_FLAGS(AT91C_EP_IN, AT91C_UDP_TXCOMP); while (pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP) {}; - UDP_SET_EP_FLAGS(AT91C_EP_IN, AT91C_UDP_TXPKTRDY); + UDP_SET_EP_FLAGS(AT91C_EP_IN, AT91C_UDP_TXPKTRDY); + while (pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXPKTRDY) {}; } // Wait for the end of transfer @@ -762,13 +774,25 @@ int usb_write(const uint8_t *data, const size_t len) { UDP_CLEAR_EP_FLAGS(AT91C_EP_IN, AT91C_UDP_TXCOMP); while (pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP) {}; + + if (len % AT91C_EP_IN_SIZE == 0) { + + UDP_SET_EP_FLAGS(AT91C_EP_IN, AT91C_UDP_TXPKTRDY); + while (!(pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP)) {}; + + UDP_CLEAR_EP_FLAGS(AT91C_EP_IN, AT91C_UDP_TXCOMP); + while (pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP) {}; + } + return PM3_SUCCESS; } -//*---------------------------------------------------------------------------- -//* \fn AT91F_USB_SendData -//* \brief Send Data through the control endpoint -//*---------------------------------------------------------------------------- +/* + *---------------------------------------------------------------------------- + * \fn AT91F_USB_SendData + * \brief Send Data through the control endpoint + *---------------------------------------------------------------------------- +*/ void AT91F_USB_SendData(AT91PS_UDP pUdp, const char *pData, uint32_t length) { AT91_REG csr; From 6eb36c54386ec3fd8c90334855ea2ca038549ff4 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 31 Mar 2020 15:33:07 +0200 Subject: [PATCH 1799/1854] added new command 'data ndef' - for easy decoding of NDEF messages inside pm3 client --- client/cmddata.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/client/cmddata.c b/client/cmddata.c index 14f8ac259..af82e7a4b 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -26,6 +26,8 @@ #include "loclass/cipherutils.h" // for decimating samples in getsamples #include "cmdlfem4x.h" // askem410xdecode #include "fileutils.h" // searchFile +#include "mifare/ndef.h" +#include "cliparser/cliparser.h" uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN]; size_t DemodBufferLen = 0; @@ -2289,6 +2291,35 @@ static int CmdDataIIR(const char *Cmd) { return PM3_SUCCESS; } +static int CmdDataNDEF(const char *Cmd) { + +#ifndef MAX_NDEF_LEN +#define MAX_NDEF_LEN 2048 +#endif + + CLIParserInit("data ndef", + "Prints NFC Data Exchange Format (NDEF)", + "Usage:\n\tdata ndef -d 9101085402656e48656c6c6f5101085402656e576f726c64\n"); + + void *argtable[] = { + arg_param_begin, + arg_strx0("dD", "data", "", "NDEF data to decode"), + arg_param_end + }; + CLIExecWithReturn(Cmd, argtable, true); + + int datalen = 0; + uint8_t data[MAX_NDEF_LEN] = {0}; + CLIGetHexWithReturn(1, data, &datalen); + + CLIParserFree(); + + PrintAndLogEx(NORMAL, "ice: %s", sprint_hex(data, datalen)); + + NDEFDecodeAndPrint(data, datalen, true); + return PM3_SUCCESS; +} + static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, {"askedgedetect", CmdAskEdgeDetect, AlwaysAvailable, "[threshold] Adjust Graph for manual ASK demod using the length of sample differences to detect the edge of a wave (use 20-45, def:25)"}, @@ -2327,6 +2358,7 @@ static command_t CommandTable[] = { {"undec", CmdUndec, AlwaysAvailable, "Un-decimate samples by 2"}, {"zerocrossings", CmdZerocrossings, AlwaysAvailable, "Count time between zero-crossings"}, {"iir", CmdDataIIR, AlwaysAvailable, "apply IIR buttersworth filter on plotdata"}, + {"ndef", CmdDataNDEF, AlwaysAvailable, "Decode NDEF records"}, {NULL, NULL, NULL, NULL} }; From 160f150dce50bb17e687c7b285daadb0a7ce4def Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 31 Mar 2020 15:47:33 +0200 Subject: [PATCH 1800/1854] fixing NDEF --- client/cmddata.c | 20 ++++++++------------ client/mifare/ndef.c | 38 +++++++++++++++++++------------------- client/mifare/ndef.h | 1 + 3 files changed, 28 insertions(+), 31 deletions(-) diff --git a/client/cmddata.c b/client/cmddata.c index af82e7a4b..52d3df314 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -10,22 +10,20 @@ // Data and Graph commands //----------------------------------------------------------------------------- #include "cmddata.h" - #include #include #include // for CmdNorm INT_MIN && INT_MAX #include // pow #include // tolower - -#include "commonutil.h" // ARRAYLEN -#include "cmdparser.h" // for command_t -#include "ui.h" // for show graph controls -#include "graph.h" // for graph data +#include "commonutil.h" // ARRAYLEN +#include "cmdparser.h" // for command_t +#include "ui.h" // for show graph controls +#include "graph.h" // for graph data #include "comms.h" -#include "lfdemod.h" // for demod code +#include "lfdemod.h" // for demod code #include "loclass/cipherutils.h" // for decimating samples in getsamples -#include "cmdlfem4x.h" // askem410xdecode -#include "fileutils.h" // searchFile +#include "cmdlfem4x.h" // askem410xdecode +#include "fileutils.h" // searchFile #include "mifare/ndef.h" #include "cliparser/cliparser.h" @@ -2314,9 +2312,7 @@ static int CmdDataNDEF(const char *Cmd) { CLIParserFree(); - PrintAndLogEx(NORMAL, "ice: %s", sprint_hex(data, datalen)); - - NDEFDecodeAndPrint(data, datalen, true); + NDEFRecordsDecodeAndPrint(data, datalen); return PM3_SUCCESS; } diff --git a/client/mifare/ndef.c b/client/mifare/ndef.c index df8264330..844c7ccd0 100644 --- a/client/mifare/ndef.c +++ b/client/mifare/ndef.c @@ -16,6 +16,7 @@ #include "util.h" // sprint_hex... #include "emv/dump.h" #include "crypto/asn1utils.h" +#include "pm3_cmd.h" #define STRBOOL(p) ((p) ? "+" : "-") @@ -118,7 +119,7 @@ static int ndefDecodeHeader(uint8_t *data, size_t datalen, NDEFHeader_t *header) header->TypeNameFormat = data[0] & 0x07; header->len = 1 + 1 + (header->ShortRecordBit ? 1 : 4) + (header->IDLenPresent ? 1 : 0); // header + typelen + payloadlen + idlen if (header->len > datalen) - return 1; + return PM3_ESOFT; header->TypeLen = data[1]; header->Type = data + header->len; @@ -138,7 +139,7 @@ static int ndefDecodeHeader(uint8_t *data, size_t datalen, NDEFHeader_t *header) if (header->RecLen > datalen) return 3; - return 0; + return PM3_SUCCESS; } static int ndefPrintHeader(NDEFHeader_t *header) { @@ -156,8 +157,7 @@ static int ndefPrintHeader(NDEFHeader_t *header) { PrintAndLogEx(NORMAL, "\tPayload length : %zu", header->PayloadLen); PrintAndLogEx(NORMAL, "\tID length : %zu", header->IDLen); PrintAndLogEx(NORMAL, "\tRecord length : %zu", header->RecLen); - - return 0; + return PM3_SUCCESS; } static int ndefDecodeSig(uint8_t *sig, size_t siglen) { @@ -165,7 +165,7 @@ static int ndefDecodeSig(uint8_t *sig, size_t siglen) { PrintAndLogEx(NORMAL, "\tsignature version: 0x%02x", sig[0]); if (sig[0] != 0x01) { PrintAndLogEx(ERR, "signature version unknown."); - return 1; + return PM3_ESOFT; } indx++; @@ -222,7 +222,7 @@ static int ndefDecodeSig(uint8_t *sig, size_t siglen) { PrintAndLogEx(NORMAL, "\tcertificate uri [%zu]: %.*s", inturilen, (int)inturilen, &sig[indx]); } - return 0; + return PM3_SUCCESS; }; static int ndefDecodePayload(NDEFHeader_t *ndef) { @@ -262,13 +262,13 @@ static int ndefDecodePayload(NDEFHeader_t *ndef) { case tnfUnknownRecord: break; } - return 0; + return PM3_SUCCESS; } static int ndefRecordDecodeAndPrint(uint8_t *ndefRecord, size_t ndefRecordLen) { NDEFHeader_t NDEFHeader = {0}; int res = ndefDecodeHeader(ndefRecord, ndefRecordLen, &NDEFHeader); - if (res) + if (res != PM3_SUCCESS) return res; ndefPrintHeader(&NDEFHeader); @@ -288,30 +288,30 @@ static int ndefRecordDecodeAndPrint(uint8_t *ndefRecord, size_t ndefRecordLen) { ndefDecodePayload(&NDEFHeader); } - return 0; + return PM3_SUCCESS; } -static int ndefRecordsDecodeAndPrint(uint8_t *ndefRecord, size_t ndefRecordLen) { +int NDEFRecordsDecodeAndPrint(uint8_t *ndefRecord, size_t ndefRecordLen) { bool firstRec = true; size_t len = 0; while (len < ndefRecordLen) { NDEFHeader_t NDEFHeader = {0}; int res = ndefDecodeHeader(&ndefRecord[len], ndefRecordLen - len, &NDEFHeader); - if (res) + if (res != PM3_SUCCESS) return res; if (firstRec) { if (!NDEFHeader.MessageBegin) { PrintAndLogEx(ERR, "NDEF first record have MessageBegin=false!"); - return 1; + return PM3_ESOFT; } firstRec = false; } if (NDEFHeader.MessageEnd && len + NDEFHeader.RecLen != ndefRecordLen) { PrintAndLogEx(ERR, "NDEF records have wrong length. Must be %zu, calculated %zu", ndefRecordLen, len + NDEFHeader.RecLen); - return 1; + return PM3_ESOFT; } ndefRecordDecodeAndPrint(&ndefRecord[len], NDEFHeader.RecLen); @@ -322,7 +322,7 @@ static int ndefRecordsDecodeAndPrint(uint8_t *ndefRecord, size_t ndefRecordLen) break; } - return 0; + return PM3_SUCCESS; } int NDEFDecodeAndPrint(uint8_t *ndef, size_t ndefLen, bool verbose) { @@ -346,8 +346,8 @@ int NDEFDecodeAndPrint(uint8_t *ndef, size_t ndefLen, bool verbose) { uint16_t len = ndefTLVGetLength(&ndef[indx], &indx); PrintAndLogEx(INFO, "-- NDEF message. len: %d", len); - int res = ndefRecordsDecodeAndPrint(&ndef[indx], len); - if (res) + int res = NDEFRecordsDecodeAndPrint(&ndef[indx], len); + if (res != PM3_SUCCESS) return res; indx += len; @@ -362,13 +362,13 @@ int NDEFDecodeAndPrint(uint8_t *ndef, size_t ndefLen, bool verbose) { } case 0xfe: { PrintAndLogEx(INFO, "-- NDEF Terminator. Done."); - return 0; + return PM3_SUCCESS; } default: { PrintAndLogEx(ERR, "unknown tag 0x%02x", ndef[indx]); - return 1; + return PM3_ESOFT; } } } - return 0; + return PM3_SUCCESS; } diff --git a/client/mifare/ndef.h b/client/mifare/ndef.h index 71afda2ee..12a6646e8 100644 --- a/client/mifare/ndef.h +++ b/client/mifare/ndef.h @@ -63,5 +63,6 @@ typedef struct { } NDEFHeader_t; int NDEFDecodeAndPrint(uint8_t *ndef, size_t ndefLen, bool verbose); +int NDEFRecordsDecodeAndPrint(uint8_t *ndefRecord, size_t ndefRecordLen); #endif // _NDEF_H_ From 5618f71ac709716cb9aa3dc70d7685b8415f74f7 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 31 Mar 2020 15:56:34 +0200 Subject: [PATCH 1801/1854] textual --- client/cmddata.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/cmddata.c b/client/cmddata.c index 52d3df314..cf6d9b2e6 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -2312,8 +2312,8 @@ static int CmdDataNDEF(const char *Cmd) { CLIParserFree(); - NDEFRecordsDecodeAndPrint(data, datalen); - return PM3_SUCCESS; + PrintAndLogEx(INFO, "Parsed NDEF Records"); + return NDEFRecordsDecodeAndPrint(data, datalen); } static command_t CommandTable[] = { From 63e06e1738515bf0dd9cb108103134c5458c2e95 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 31 Mar 2020 16:05:19 +0200 Subject: [PATCH 1802/1854] textual --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3032b04fb..d117ab8be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,10 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Added `data ndef` - decode NDEF messages (@iceman1001) + - Change - usb write's now waits for shiftregisters (@pwpiwi) + - Change - NDEF supports more signatures now (@iceman1001) + - OSX Makefile now supports `make style` and `make checks` (@Pizza_4u) - Added `HF_LEGIC` standalone mode to read and simulate a Legic prime tag (@Pizza_4u) - Added keri MS decode/encode and update 'lf keri clone' to support MS fc/cid cloning. (@mwalker33) - Fix 'hf mfdes enum' - now actually manages to enumerate files under all AID's. :smiley: (@iceman1001) From 8dd19a00c5968ea0008bcaf97261eb05a3f19f41 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 31 Mar 2020 16:11:01 +0200 Subject: [PATCH 1803/1854] support v2.0 ndef sigs --- client/mifare/ndef.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/mifare/ndef.c b/client/mifare/ndef.c index 844c7ccd0..5870fb1dd 100644 --- a/client/mifare/ndef.c +++ b/client/mifare/ndef.c @@ -163,7 +163,7 @@ static int ndefPrintHeader(NDEFHeader_t *header) { static int ndefDecodeSig(uint8_t *sig, size_t siglen) { size_t indx = 0; PrintAndLogEx(NORMAL, "\tsignature version: 0x%02x", sig[0]); - if (sig[0] != 0x01) { + if (sig[0] != 0x01 && sig[0] != 0x20) { PrintAndLogEx(ERR, "signature version unknown."); return PM3_ESOFT; } From 74243fcb036240f53330c2450193f345cd36d26e Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Tue, 31 Mar 2020 18:09:41 +0300 Subject: [PATCH 1804/1854] signatures v1 and v2 --- client/mifare/ndef.c | 89 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 81 insertions(+), 8 deletions(-) diff --git a/client/mifare/ndef.c b/client/mifare/ndef.c index 5870fb1dd..dead65a8e 100644 --- a/client/mifare/ndef.c +++ b/client/mifare/ndef.c @@ -160,14 +160,8 @@ static int ndefPrintHeader(NDEFHeader_t *header) { return PM3_SUCCESS; } -static int ndefDecodeSig(uint8_t *sig, size_t siglen) { - size_t indx = 0; - PrintAndLogEx(NORMAL, "\tsignature version: 0x%02x", sig[0]); - if (sig[0] != 0x01 && sig[0] != 0x20) { - PrintAndLogEx(ERR, "signature version unknown."); - return PM3_ESOFT; - } - indx++; +static int ndefDecodeSig1(uint8_t *sig, size_t siglen) { + size_t indx = 1; uint8_t sigType = sig[indx] & 0x7f; bool sigURI = sig[indx] & 0x80; @@ -225,6 +219,85 @@ static int ndefDecodeSig(uint8_t *sig, size_t siglen) { return PM3_SUCCESS; }; +// https://github.com/nfcpy/ndeflib/blob/master/src/ndef/signature.py#L292 +static int ndefDecodeSig2(uint8_t *sig, size_t siglen) { + size_t indx = 1; + + uint8_t sigType = sig[indx] & 0x7f; + bool sigURI = sig[indx] & 0x80; + indx++; + + uint8_t hashType = sig[indx]; + indx++; + + PrintAndLogEx(NORMAL, "\tsignature type: %s", ((sigType < stNA) ? ndefSigType_s[sigType] : ndefSigType_s[stNA])); + PrintAndLogEx(NORMAL, "\tsignature uri: %s", (sigURI ? "present" : "not present")); + PrintAndLogEx(NORMAL, "\thash type: %s", ((hashType == 0x02) ? "SHA-256" : "unknown"); + + if (sigURI) { + size_t intsigurilen = (sig[indx] << 8) + sig[indx + 1]; + indx += 2; + PrintAndLogEx(NORMAL, "\tsignature uri [%zu]: %.*s", intsigurilen, (int)intsigurilen, &sig[indx]); + indx += intsigurilen; + } +return 0; + /* if (sigType == stECDSA_P192 || sigType == stECDSA_P256) { + indx += 3; + PrintAndLogEx(NORMAL, "\tsignature [%zu]: %s", intsiglen, sprint_hex_inrow(&sig[indx], intsiglen)); + + uint8_t rval[300] = {0}; + uint8_t sval[300] = {0}; + int res = ecdsa_asn1_get_signature(&sig[indx], intsiglen, rval, sval); + if (!res) { + PrintAndLogEx(NORMAL, "\t\tr: %s", sprint_hex(rval, 32)); + PrintAndLogEx(NORMAL, "\t\ts: %s", sprint_hex(sval, 32)); + } + } + indx += intsiglen;*/ + + uint8_t certFormat = (sig[indx] >> 4) & 0x07; + uint8_t certCount = sig[indx] & 0x0f; + bool certURI = sig[indx] & 0x80; + + PrintAndLogEx(NORMAL, "\tcertificate format: %s", ((certFormat < sfNA) ? ndefCertificateFormat_s[certFormat] : ndefCertificateFormat_s[sfNA])); + PrintAndLogEx(NORMAL, "\tcertificates count: %d", certCount); + + // print certificates + indx++; + for (int i = 0; i < certCount; i++) { + size_t intcertlen = (sig[indx + 1] << 8) + sig[indx + 2]; + indx += 2; + + PrintAndLogEx(NORMAL, "\tcertificate %d [%zu]: %s", i + 1, intcertlen, sprint_hex_inrow(&sig[indx], intcertlen)); + indx += intcertlen; + } + + // have certificate uri + if ((indx <= siglen) && certURI) { + size_t inturilen = (sig[indx] << 8) + sig[indx + 1]; + indx += 2; + PrintAndLogEx(NORMAL, "\tcertificate uri [%zu]: %.*s", inturilen, (int)inturilen, &sig[indx]); + } + + return PM3_SUCCESS; +}; + +static int ndefDecodeSig(uint8_t *sig, size_t siglen) { + PrintAndLogEx(NORMAL, "\tsignature version: 0x%02x", sig[0]); + if (sig[0] != 0x01 && sig[0] != 0x20) { + PrintAndLogEx(ERR, "signature version unknown."); + return PM3_ESOFT; + } + + if (sig[0] == 0x01) + return ndefDecodeSig1(sig, siglen); + + if (sig[0] == 0x20) + return ndefDecodeSig2(sig, siglen); + + return PM3_ESOFT; +} + static int ndefDecodePayload(NDEFHeader_t *ndef) { switch (ndef->TypeNameFormat) { From 38004f9db59cd1d88fed0e69f54956baf1008265 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Tue, 31 Mar 2020 18:25:17 +0300 Subject: [PATCH 1805/1854] decode works --- client/mifare/ndef.c | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/client/mifare/ndef.c b/client/mifare/ndef.c index dead65a8e..66b00a159 100644 --- a/client/mifare/ndef.c +++ b/client/mifare/ndef.c @@ -232,28 +232,33 @@ static int ndefDecodeSig2(uint8_t *sig, size_t siglen) { PrintAndLogEx(NORMAL, "\tsignature type: %s", ((sigType < stNA) ? ndefSigType_s[sigType] : ndefSigType_s[stNA])); PrintAndLogEx(NORMAL, "\tsignature uri: %s", (sigURI ? "present" : "not present")); - PrintAndLogEx(NORMAL, "\thash type: %s", ((hashType == 0x02) ? "SHA-256" : "unknown"); + PrintAndLogEx(NORMAL, "\thash type: %s", ((hashType == 0x02) ? "SHA-256" : "unknown")); + size_t intsiglen = (sig[indx] << 8) + sig[indx + 1]; + indx += 2; + if (sigURI) { - size_t intsigurilen = (sig[indx] << 8) + sig[indx + 1]; indx += 2; - PrintAndLogEx(NORMAL, "\tsignature uri [%zu]: %.*s", intsigurilen, (int)intsigurilen, &sig[indx]); - indx += intsigurilen; - } -return 0; - /* if (sigType == stECDSA_P192 || sigType == stECDSA_P256) { - indx += 3; + PrintAndLogEx(NORMAL, "\tsignature uri [%zu]: %.*s", intsiglen, (int)intsiglen, &sig[indx]); + indx += intsiglen; + } else { PrintAndLogEx(NORMAL, "\tsignature [%zu]: %s", intsiglen, sprint_hex_inrow(&sig[indx], intsiglen)); - - uint8_t rval[300] = {0}; - uint8_t sval[300] = {0}; - int res = ecdsa_asn1_get_signature(&sig[indx], intsiglen, rval, sval); - if (!res) { - PrintAndLogEx(NORMAL, "\t\tr: %s", sprint_hex(rval, 32)); - PrintAndLogEx(NORMAL, "\t\ts: %s", sprint_hex(sval, 32)); + if (sigType == stECDSA_P192 || sigType == stECDSA_P256) { + PrintAndLogEx(NORMAL, "\tsignature: ECDSA"); + uint8_t rval[300] = {0}; + uint8_t sval[300] = {0}; + int res = ecdsa_asn1_get_signature(&sig[indx], intsiglen, rval, sval); + if (!res) { + PrintAndLogEx(NORMAL, "\t\tr: %s", sprint_hex(rval, 32)); + PrintAndLogEx(NORMAL, "\t\ts: %s", sprint_hex(sval, 32)); + } else { + PrintAndLogEx(NORMAL, "\t\error signature decode"); + } + } else { + PrintAndLogEx(NORMAL, "\tsignature: unknown type"); } + indx += intsiglen; } - indx += intsiglen;*/ uint8_t certFormat = (sig[indx] >> 4) & 0x07; uint8_t certCount = sig[indx] & 0x0f; From 5b9c51fb7e3b7157a5cf15f10567952929296562 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Tue, 31 Mar 2020 18:30:44 +0300 Subject: [PATCH 1806/1854] signature decode r and s works --- client/mifare/ndef.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/client/mifare/ndef.c b/client/mifare/ndef.c index 66b00a159..e2399b0fd 100644 --- a/client/mifare/ndef.c +++ b/client/mifare/ndef.c @@ -244,15 +244,12 @@ static int ndefDecodeSig2(uint8_t *sig, size_t siglen) { } else { PrintAndLogEx(NORMAL, "\tsignature [%zu]: %s", intsiglen, sprint_hex_inrow(&sig[indx], intsiglen)); if (sigType == stECDSA_P192 || sigType == stECDSA_P256) { - PrintAndLogEx(NORMAL, "\tsignature: ECDSA"); - uint8_t rval[300] = {0}; - uint8_t sval[300] = {0}; - int res = ecdsa_asn1_get_signature(&sig[indx], intsiglen, rval, sval); - if (!res) { - PrintAndLogEx(NORMAL, "\t\tr: %s", sprint_hex(rval, 32)); - PrintAndLogEx(NORMAL, "\t\ts: %s", sprint_hex(sval, 32)); - } else { - PrintAndLogEx(NORMAL, "\t\error signature decode"); + int slen = intsiglen / 2; + if (slen == 24 || slen == 32) { + PrintAndLogEx(NORMAL, "\tsignature: ECDSA-%d", slen * 8); + PrintAndLogEx(NORMAL, "\t\tr: %s", sprint_hex(&sig[indx], slen)); + indx += slen; + PrintAndLogEx(NORMAL, "\t\ts: %s", sprint_hex(&sig[indx], slen)); } } else { PrintAndLogEx(NORMAL, "\tsignature: unknown type"); From 0f6a1cd8c3673c6b1050f1af95f32dd52e34d0a6 Mon Sep 17 00:00:00 2001 From: Uli Heilmeier Date: Tue, 31 Mar 2020 17:54:51 +0200 Subject: [PATCH 1807/1854] Doc: Update trace notes First draft of some informations regarding trace command. --- README.md | 4 +- ...race_wireshark_notes.md => trace_notes.md} | 37 +++++++++++++++++++ 2 files changed, 39 insertions(+), 2 deletions(-) rename doc/{trace_wireshark_notes.md => trace_notes.md} (62%) diff --git a/README.md b/README.md index 6192c23cd..d183309b4 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ |[Notes on frame format](/doc/new_frame_format.md)||[More cheat sheets](https://github.com/RfidResearchGroup/proxmark3/wiki/More-cheat-sheets)| |[Notes on external flash](/doc/ext_flash_notes.md)||[EMV](/doc/emv_notes.md)| |[Notes on Termux / Android](/doc/termux_notes.md)||[Troubleshooting](/doc/md/Installation_Instructions/Troubleshooting.md)| -|[Notes on wireshark / tracedata](/doc/trace_wireshark_notes.md)||[JTAG](/doc/jtag_notes.md)| +|[Notes on tracedata / wireshark](/doc/trace_notes.md)||[JTAG](/doc/jtag_notes.md)| |[Notes on loclass](/doc/loclass_notes.md)||[Complete client command set](/doc/commands.md)| |[Notes on paths](/doc/path_notes.md)||| |[Developing standalone mode](/armsrc/Standalone/readme.md)|[Wiki about standalone mode](https://github.com/RfidResearchGroup/proxmark3/wiki/Standalone-mode) || @@ -67,7 +67,7 @@ We usually merge your contributions fast since we do like the idea of getting a - notes on [external flash](/doc/ext_flash_notes.md) - notes on [standalone mode](https://github.com/RfidResearchGroup/proxmark3/wiki/Standalone-mode) - notes on [Termux / Android](/doc/termux_notes.md) -- notes on [Wireshark / tracedata](/doc/trace_wireshark_notes.md) +- notes on [tracedata / Wireshark](/doc/trace_notes.md) - notes on [loclass](/doc/loclass_notes.md) - notes on [EMV](/doc/emv_notes.md) - notes on [Paths](/doc/path_notes.md) diff --git a/doc/trace_wireshark_notes.md b/doc/trace_notes.md similarity index 62% rename from doc/trace_wireshark_notes.md rename to doc/trace_notes.md index 50dd9d082..a126a238f 100644 --- a/doc/trace_wireshark_notes.md +++ b/doc/trace_notes.md @@ -4,6 +4,43 @@ The `trace` command lists the data exchange by the proxmark3 and a tag or a read With `trace list` a table is shown which gives timing information, the src of the data bytes, the transmitted/received bytes itself, a check if the CRC was correct and some decoding of the command. +## Timing + +The Start and the End coloumn lists timestamps when the transmission of the shown data started (time of first bit) and when it ended (end of last modulation). + +The unit for this time information depends on the protocol in use: + +* ISO14443A and Thinfilm: all times are in carrier periods (1/13.56MHz) +* For Legic timing information depends also on direction: + * Reader Mode: Timings are in ticks (1us == 1.5ticks) + * Tag Mode: Timings are in sub carrier periods (1/212 kHz == 4.7us) +* Hitag1 / Hitag2 / HitagS: Elementary Time Unit (ETU) is 8µs +* iClass, ISO15693, ISO18092 and FeliCa have no accurate timing information at the moment +* For others timing is not available + +By specifing the option ```f``` (e.g. ```trace list 14a f```) the frame delay times are shown. (So you don't have to do the math by your own). + +## Sources + +If the data is marked as a response the source is shown as Tag. Otherwise it is marked as Reader (Rdr). + +## Data + +This coloumn show the raw bytes trasmitted over the air. With option ```c``` CRC bytes are marked in square brackets. + +## CRC + +Marks if the transmitted CRC matches with the calculated CRC. + +## Annotation + +Annotations provide a rough decoding of the transmitted data. For ISO14443A a more detailed decoding is available with Wireshark (s. next chapter) + + +-- + +# Trace and Wireshark + To get a more detailed explanation of the transmitted data for ISO14443A traces the output can be converted to a pcapng file to read it with [Wireshark](https://www.wireshark.org/). To do so From 6d3c13c49acf6ff7bbd9ce2d9db539db7abe427c Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Tue, 31 Mar 2020 19:13:03 +0300 Subject: [PATCH 1808/1854] fix mfp behavior in info command --- client/cmdhf14a.c | 1 + client/cmdhfmfp.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index 13a5a9213..a3ee49503 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -557,6 +557,7 @@ int ExchangeRAW14a(uint8_t *datain, int datainlen, bool activateField, bool leav if (activateField) { PacketResponseNG resp; + responseNum = 0; // Anticollision + SELECT card SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0, NULL, 0); diff --git a/client/cmdhfmfp.c b/client/cmdhfmfp.c index ff1b87cf5..56963819c 100644 --- a/client/cmdhfmfp.c +++ b/client/cmdhfmfp.c @@ -47,7 +47,7 @@ static int CmdHFMFPInfo(const char *Cmd) { infoHF14A(false, false, false); // Mifare Plus info - SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0, NULL, 0); + SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT, 0, 0, NULL, 0); PacketResponseNG resp; WaitForResponse(CMD_ACK, &resp); @@ -115,7 +115,7 @@ static int CmdHFMFPInfo(const char *Cmd) { int datalen = 0; // https://github.com/Proxmark/proxmark3/blob/master/client/luascripts/mifarePlus.lua#L161 uint8_t cmd[3 + 16] = {0xa8, 0x90, 0x90, 0x00}; - int res = ExchangeRAW14a(cmd, sizeof(cmd), false, false, data, sizeof(data), &datalen, false); + int res = ExchangeRAW14a(cmd, sizeof(cmd), true, false, data, sizeof(data), &datalen, false); if (memcmp(data, "\x67\x00", 2) == 0) { PrintAndLogEx(INFO, "\tMost likely a Mifare DESFire tag"); From 737ebf9ab885f4ba3bd87f021d407ee20dec4618 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Tue, 31 Mar 2020 19:26:09 +0300 Subject: [PATCH 1809/1854] ndef signature1 length fix --- client/mifare/ndef.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/client/mifare/ndef.c b/client/mifare/ndef.c index e2399b0fd..f1b3e42bd 100644 --- a/client/mifare/ndef.c +++ b/client/mifare/ndef.c @@ -171,16 +171,19 @@ static int ndefDecodeSig1(uint8_t *sig, size_t siglen) { size_t intsiglen = (sig[indx + 1] << 8) + sig[indx + 2]; // ecdsa 0x04 - if (sigType == stECDSA_P192) { + if (sigType == stECDSA_P192 || sigType == stECDSA_P256) { indx += 3; + int slen = 24; + if (sigType == stECDSA_P256) + slen = 32; PrintAndLogEx(NORMAL, "\tsignature [%zu]: %s", intsiglen, sprint_hex_inrow(&sig[indx], intsiglen)); uint8_t rval[300] = {0}; uint8_t sval[300] = {0}; int res = ecdsa_asn1_get_signature(&sig[indx], intsiglen, rval, sval); if (!res) { - PrintAndLogEx(NORMAL, "\t\tr: %s", sprint_hex(rval, 32)); - PrintAndLogEx(NORMAL, "\t\ts: %s", sprint_hex(sval, 32)); + PrintAndLogEx(NORMAL, "\t\tr: %s", sprint_hex(rval + 32 - slen, slen)); + PrintAndLogEx(NORMAL, "\t\ts: %s", sprint_hex(sval + 32 - slen, slen)); } } indx += intsiglen; From 83e92c64559bb6b3b2ad718a49fe4a0d77387c8b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 1 Apr 2020 09:25:54 +0200 Subject: [PATCH 1810/1854] Add: 'hf mfu ndef' - read and parse NDEF type2 records --- client/cmdhfmfu.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index c1cd5d31a..ce2528b89 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -21,6 +21,9 @@ #include "fileutils.h" #include "protocols.h" #include "generator.h" +#include "mifare/ndef.h" +#include "cliparser/cliparser.h" + #define MAX_UL_BLOCKS 0x0F #define MAX_ULC_BLOCKS 0x2B @@ -563,6 +566,22 @@ static int ul_print_default(uint8_t *data) { return PM3_SUCCESS; } +static int ndef_get_maxsize(uint8_t *data) { + // no NDEF message + if (data[0] != 0xE1) + return 0; + + if (data[2] == 0x06) + return 48; + else if (data[2] == 0x12) + return 144; + else if (data[2] == 0x3E) + return 496; + else if (data[2] == 0x6D) + return 872; + return 0; +} + static int ndef_print_CC(uint8_t *data) { // no NDEF message if (data[0] != 0xE1) @@ -2633,6 +2652,100 @@ static int CmdHF14AMfuOtpTearoff(const char *Cmd) { return PM3_SUCCESS; } +static int CmdHF14MfuNDEF(const char *Cmd) { + + int keylen; + int maxsize = 16, status; + bool hasAuthKey = false; + bool swapEndian = false; + + iso14a_card_select_t card; + uint8_t data[16] = {0x00}; + uint8_t key[16] = {0x00}; + uint8_t *p_key = key; + uint8_t pack[4] = {0, 0, 0, 0}; + + CLIParserInit("hf mfu ndef", + "Prints NFC Data Exchange Format (NDEF)", + "Usage:\n\thf mfu ndef -> shows NDEF data\n" + "\thf mfu ndef -k ffffffff -> shows NDEF data with key\n"); + + void *argtable[] = { + arg_param_begin, + arg_str0("kK", "key", "replace default key for NDEF", NULL), + arg_lit0("lL", "key", "(optional) swap entered key's endianness"), + arg_param_end + }; + CLIExecWithReturn(Cmd, argtable, true); + + CLIGetHexWithReturn(1, key, &keylen); + swapEndian = arg_get_lit(2); + CLIParserFree(); + + switch(keylen) { + case 0: + break; + case 4: + case 16: + hasAuthKey = true; + break; + default: + PrintAndLogEx(WARNING, "ERROR: Key is incorrect length\n"); + return PM3_EINVARG; + } + + // Get tag type + TagTypeUL_t tagtype = GetHF14AMfU_Type(); + if (tagtype == UL_ERROR) return PM3_ESOFT; + + // Is tag UL/NTAG? + + // Swap endianness + if (swapEndian && hasAuthKey) p_key = SwapEndian64(key, keylen, (keylen == 16) ? 8 : 4); + + // Select and Auth + if (ul_auth_select(&card, tagtype, hasAuthKey, p_key, pack, sizeof(pack)) == PM3_ESOFT) return PM3_ESOFT; + + // read pages 0,1,2,3 (should read 4pages) + status = ul_read(0, data, sizeof(data)); + if (status == -1) { + DropField(); + PrintAndLogEx(ERR, "Error: tag didn't answer to READ"); + return PM3_ESOFT; + } else if (status == 16) { + + status = ndef_print_CC(data + 12); + if (status == PM3_ESOFT) { + DropField(); + PrintAndLogEx(ERR, "Error: tag didn't contain a NDEF Container"); + return PM3_ESOFT; + } + + // max datasize; + maxsize = ndef_get_maxsize(data + 12); + } + + // allocate mem + uint8_t *records = calloc(maxsize, sizeof(uint8_t)); + if (records == NULL) { + DropField(); + return PM3_EMALLOC; + } + + // read NDEF records. + for(uint16_t i = 0, j = 0; i < maxsize; i += 16, j += 4) { + status = ul_read(4 + j, records + i, 16); + if (status == -1) { + DropField(); + PrintAndLogEx(ERR, "Error: tag didn't answer to READ"); + return PM3_ESOFT; + } + } + DropField(); + status = NDEFDecodeAndPrint(records, (size_t)maxsize, true); + free(records); + return status; +} //------------------------------------ // Menu Stuff //------------------------------------ @@ -2651,6 +2764,7 @@ static command_t CommandTable[] = { {"gen", CmdHF14AMfUGenDiverseKeys, AlwaysAvailable, "Generate 3des mifare diversified keys"}, {"pwdgen", CmdHF14AMfUPwdGen, AlwaysAvailable, "Generate pwd from known algos"}, {"otptear", CmdHF14AMfuOtpTearoff, IfPm3Iso14443a, "Tear-off test on OTP bits"}, + {"ndef", CmdHF14MfuNDEF, IfPm3Iso14443a, "Prints NDEF records from card"}, {NULL, NULL, NULL, NULL} }; From d633340a1a49b62fc9abfcb34b3cadff516821ee Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 1 Apr 2020 09:26:39 +0200 Subject: [PATCH 1811/1854] Chg: 'data ndef' - cleaner output if called with no hex --- client/cmddata.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/cmddata.c b/client/cmddata.c index cf6d9b2e6..74c33da55 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -2309,8 +2309,9 @@ static int CmdDataNDEF(const char *Cmd) { int datalen = 0; uint8_t data[MAX_NDEF_LEN] = {0}; CLIGetHexWithReturn(1, data, &datalen); - CLIParserFree(); + if (datalen == 0) + return PM3_EINVARG; PrintAndLogEx(INFO, "Parsed NDEF Records"); return NDEFRecordsDecodeAndPrint(data, datalen); From 426246178fecb259cde62e8eb06fd8b0c18100e8 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 1 Apr 2020 09:27:50 +0200 Subject: [PATCH 1812/1854] textual --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d117ab8be..1ef686269 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Added `hf mfu ndef` - read and decode NDEF Type2 messages (@iceman1001) - Added `data ndef` - decode NDEF messages (@iceman1001) - Change - usb write's now waits for shiftregisters (@pwpiwi) - Change - NDEF supports more signatures now (@iceman1001) From 3f54fdf2528d3f310933d9ccb618ecc2eb43072e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 1 Apr 2020 09:49:11 +0200 Subject: [PATCH 1813/1854] textual --- client/mifare/ndef.c | 50 ++++++++++++++++++++++++++++++++------------ 1 file changed, 37 insertions(+), 13 deletions(-) diff --git a/client/mifare/ndef.c b/client/mifare/ndef.c index f1b3e42bd..e3ba3997d 100644 --- a/client/mifare/ndef.c +++ b/client/mifare/ndef.c @@ -308,15 +308,15 @@ static int ndefDecodePayload(NDEFHeader_t *ndef) { switch (ndef->TypeNameFormat) { case tnfWellKnownRecord: PrintAndLogEx(INFO, "Well Known Record"); - PrintAndLogEx(NORMAL, "\ttype: %.*s", (int)ndef->TypeLen, ndef->Type); + PrintAndLogEx(INFO, "\ttype : %.*s", (int)ndef->TypeLen, ndef->Type); if (!strncmp((char *)ndef->Type, "T", ndef->TypeLen)) { - PrintAndLogEx(NORMAL, "\ttext : %.*s", (int)ndef->PayloadLen, ndef->Payload); + PrintAndLogEx(INFO, "\ttext : " _GREEN_("%.*s"), (int)ndef->PayloadLen, ndef->Payload); } if (!strncmp((char *)ndef->Type, "U", ndef->TypeLen)) { - PrintAndLogEx(NORMAL - , "\turi : %s%.*s" + PrintAndLogEx(INFO + , "\turi : " _GREEN_("%s%.*s") , (ndef->Payload[0] <= 0x23 ? URI_s[ndef->Payload[0]] : "[err]") , (int)(ndef->PayloadLen - 1) , &ndef->Payload[1] @@ -330,14 +330,28 @@ static int ndefDecodePayload(NDEFHeader_t *ndef) { break; case tnfAbsoluteURIRecord: PrintAndLogEx(INFO, "Absolute URI Record"); - PrintAndLogEx(NORMAL, "\ttype: %.*s", (int)ndef->TypeLen, ndef->Type); - PrintAndLogEx(NORMAL, "\tpayload: %.*s", (int)ndef->PayloadLen, ndef->Payload); + PrintAndLogEx(INFO, "\ttype : %.*s", (int)ndef->TypeLen, ndef->Type); + PrintAndLogEx(INFO, "\tpayload : %.*s", (int)ndef->PayloadLen, ndef->Payload); break; case tnfEmptyRecord: + PrintAndLogEx(INFO, "Empty Record"); + PrintAndLogEx(INFO, "\t -to be impl-"); + break; case tnfMIMEMediaRecord: + PrintAndLogEx(INFO, "MIME Media Record"); + PrintAndLogEx(INFO, "\t -to be impl-"); + break; case tnfExternalRecord: + PrintAndLogEx(INFO, "External Record"); + PrintAndLogEx(INFO, "\t -to be impl-"); + break; case tnfUnchangedRecord: + PrintAndLogEx(INFO, "Unchanged Record"); + PrintAndLogEx(INFO, "\t -to be impl-"); + break; case tnfUnknownRecord: + PrintAndLogEx(INFO, "Unknown Record"); + PrintAndLogEx(INFO, "\t -to be impl-"); break; } return PM3_SUCCESS; @@ -372,8 +386,11 @@ static int ndefRecordDecodeAndPrint(uint8_t *ndefRecord, size_t ndefRecordLen) { int NDEFRecordsDecodeAndPrint(uint8_t *ndefRecord, size_t ndefRecordLen) { bool firstRec = true; size_t len = 0; + size_t counter = 0; while (len < ndefRecordLen) { + counter++; + NDEFHeader_t NDEFHeader = {0}; int res = ndefDecodeHeader(&ndefRecord[len], ndefRecordLen - len, &NDEFHeader); if (res != PM3_SUCCESS) @@ -381,7 +398,7 @@ int NDEFRecordsDecodeAndPrint(uint8_t *ndefRecord, size_t ndefRecordLen) { if (firstRec) { if (!NDEFHeader.MessageBegin) { - PrintAndLogEx(ERR, "NDEF first record have MessageBegin=false!"); + PrintAndLogEx(ERR, "NDEF first record have MessageBegin = false!"); return PM3_ESOFT; } firstRec = false; @@ -392,6 +409,9 @@ int NDEFRecordsDecodeAndPrint(uint8_t *ndefRecord, size_t ndefRecordLen) { return PM3_ESOFT; } + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(SUCCESS, "Record " _YELLOW_("%zu"), counter); + PrintAndLogEx(INFO, "-----------------------------------------------------"); ndefRecordDecodeAndPrint(&ndefRecord[len], NDEFHeader.RecLen); len += NDEFHeader.RecLen; @@ -407,22 +427,26 @@ int NDEFDecodeAndPrint(uint8_t *ndef, size_t ndefLen, bool verbose) { size_t indx = 0; - PrintAndLogEx(INFO, "NDEF decoding:"); + PrintAndLogEx(INFO, ""); + PrintAndLogEx(INFO, "NDEF parsing"); while (indx < ndefLen) { + + PrintAndLogEx(INFO, "-----------------------------------------------------"); switch (ndef[indx]) { case 0x00: { indx++; uint16_t len = ndefTLVGetLength(&ndef[indx], &indx); - PrintAndLogEx(INFO, "-- NDEF NULL block."); + + PrintAndLogEx(SUCCESS, "-- NDEF NULL block."); if (len) - PrintAndLogEx(WARNING, "NDEF NULL block size must be 0 instead of %d.", len); + PrintAndLogEx(WARNING, "NDEF NULL block size must be 0, got %d bytes", len); indx += len; break; } case 0x03: { indx++; uint16_t len = ndefTLVGetLength(&ndef[indx], &indx); - PrintAndLogEx(INFO, "-- NDEF message. len: %d", len); + PrintAndLogEx(SUCCESS, "Found NDEF message (%d bytes)", len); int res = NDEFRecordsDecodeAndPrint(&ndef[indx], len); if (res != PM3_SUCCESS) @@ -434,12 +458,12 @@ int NDEFDecodeAndPrint(uint8_t *ndef, size_t ndefLen, bool verbose) { case 0xfd: { indx++; uint16_t len = ndefTLVGetLength(&ndef[indx], &indx); - PrintAndLogEx(INFO, "-- NDEF proprietary info. Skipped %d bytes.", len); + PrintAndLogEx(SUCCESS, "-- NDEF proprietary info. Skipped %d bytes.", len); indx += len; break; } case 0xfe: { - PrintAndLogEx(INFO, "-- NDEF Terminator. Done."); + PrintAndLogEx(SUCCESS, "-- NDEF Terminator. Done."); return PM3_SUCCESS; } default: { From 07d16bba51b60a9e4075c032fc80f1b6ed9e58a5 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 1 Apr 2020 15:10:50 +0200 Subject: [PATCH 1814/1854] added some more originality keys --- client/cmdhfmfu.c | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index ce2528b89..d5a632f8f 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -267,7 +267,7 @@ uint8_t default_pwd_pack[][4] = { // known public keys for the originality check (source: https://github.com/alexbatalov/node-nxp-originality-verifier) // ref: AN11350 NTAG 21x Originality Signature Validation // ref: AN11341 MIFARE Ultralight EV1 Originality Signature Validation -uint8_t public_keys[2][PUBLIC_ECDA_KEYLEN] = { +uint8_t nxp_mfu_public_keys[6][PUBLIC_ECDA_KEYLEN] = { // UL, NTAG21x and NDEF { 0x04, 0x49, 0x4e, 0x1a, 0x38, 0x6d, 0x3d, 0x3c, @@ -281,6 +281,34 @@ uint8_t public_keys[2][PUBLIC_ECDA_KEYLEN] = { 0x4e, 0x25, 0x5e, 0x3d, 0xa5, 0x53, 0x89, 0xa8, 0x27, 0x56, 0x4e, 0x11, 0x71, 0x8e, 0x01, 0x72, 0x92, 0xfa, 0xf2, 0x32, 0x26, 0xa9, 0x66, 0x14, 0xb8 + }, + // unknown. Needs identification + { + 0x04, 0x4F, 0x6D, 0x3F, 0x29, 0x4D, 0xEA, 0x57, + 0x37, 0xF0, 0xF4, 0x6F, 0xFE, 0xE8, 0x8A, 0x35, + 0x6E, 0xED, 0x95, 0x69, 0x5D, 0xD7, 0xE0, 0xC2, + 0x7A, 0x59, 0x1E, 0x6F, 0x6F, 0x65, 0x96, 0x2B, 0xAF + }, + // unknown. Needs identification + { + 0x04, 0xA7, 0x48, 0xB6, 0xA6, 0x32, 0xFB, 0xEE, + 0x2C, 0x08, 0x97, 0x70, 0x2B, 0x33, 0xBE, 0xA1, + 0xC0, 0x74, 0x99, 0x8E, 0x17, 0xB8, 0x4A, 0xCA, + 0x04, 0xFF, 0x26, 0x7E, 0x5D, 0x2C, 0x91, 0xF6, 0xDC + }, + // manufacturer public key + { + 0x04, 0x6F, 0x70, 0xAC, 0x55, 0x7F, 0x54, 0x61, + 0xCE, 0x50, 0x52, 0xC8, 0xE4, 0xA7, 0x83, 0x8C, + 0x11, 0xC7, 0xA2, 0x36, 0x79, 0x7E, 0x8A, 0x07, + 0x30, 0xA1, 0x01, 0x83, 0x7C, 0x00, 0x40, 0x39, 0xC2 + }, + // MIKRON public key. + { + 0x04, 0xf9, 0x71, 0xed, 0xa7, 0x42, 0xa4, 0xa8, + 0x0d, 0x32, 0xdc, 0xf6, 0xa8, 0x14, 0xa7, 0x07, + 0xcc, 0x3d, 0xc3, 0x96, 0xd3, 0x59, 0x02, 0xf7, + 0x29, 0x29, 0xfd, 0xcd, 0x69, 0x8b, 0x34, 0x68, 0xf2 } }; @@ -891,12 +919,12 @@ static int ulev1_print_signature(TagTypeUL_t tagtype, uint8_t *uid, uint8_t *sig if (tagtype == UL_EV1_48 || tagtype == UL_EV1_128) { public_key = 1; } - int res = ecdsa_signature_r_s_verify(MBEDTLS_ECP_DP_SECP128R1, public_keys[public_key], uid, 7, signature, signature_len, false); + int res = ecdsa_signature_r_s_verify(MBEDTLS_ECP_DP_SECP128R1, nxp_mfu_public_keys[public_key], uid, 7, signature, signature_len, false); bool is_valid = (res == 0); PrintAndLogEx(INFO, "\n--- Tag Signature"); PrintAndLogEx(INFO, "IC signature public key name : NXP NTAG21x (2013)"); - PrintAndLogEx(INFO, "IC signature public key value : %s", sprint_hex(public_keys[public_key], PUBLIC_ECDA_KEYLEN)); + PrintAndLogEx(INFO, "IC signature public key value : %s", sprint_hex(nxp_mfu_public_keys[public_key], PUBLIC_ECDA_KEYLEN)); PrintAndLogEx(INFO, " Elliptic curve parameters : NID_secp128r1"); PrintAndLogEx(INFO, " TAG IC Signature : %s", sprint_hex(signature, signature_len)); PrintAndLogEx(SUCCESS, "Signature verified %s", (is_valid) ? _GREEN_("successful") : _RED_("failed")); From cc6fda9b758aedcb40dfb174208ebf6bfe051f04 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 1 Apr 2020 15:54:59 +0200 Subject: [PATCH 1815/1854] added checks for unknown public keys --- client/cmdhf15.c | 76 ++++++++++++++++++++--- client/cmdhfmfdes.c | 68 +++++++++++++++------ client/cmdhfmfu.c | 146 ++++++++++++++++++++++++++------------------ 3 files changed, 202 insertions(+), 88 deletions(-) diff --git a/client/cmdhf15.c b/client/cmdhf15.c index 9b0b8dbf1..2003fd924 100644 --- a/client/cmdhf15.c +++ b/client/cmdhf15.c @@ -208,7 +208,8 @@ const productName uidmapping[] = { { 0, 0, "no tag-info available" } // must be the last entry }; -uint8_t nxp_public_keys[][33] = { +#define PUBLIC_ECDA_KEYLEN 33 +uint8_t nxp_15693_public_keys[][PUBLIC_ECDA_KEYLEN] = { // ICODE SLIX2 / DNA { 0x04, 0x88, 0x78, 0xA2, 0xA2, 0xD3, 0xEE, 0xC3, @@ -216,10 +217,67 @@ uint8_t nxp_public_keys[][33] = { 0xF9, 0xBE, 0x11, 0xC4, 0xE2, 0xE8, 0x96, 0x64, 0x8B, 0x32, 0xEF, 0xA5, 0x9C, 0xEA, 0x6E, 0x59, 0xF0 }, + // unknown. Needs identification + { + 0x04, 0x4F, 0x6D, 0x3F, 0x29, 0x4D, 0xEA, 0x57, + 0x37, 0xF0, 0xF4, 0x6F, 0xFE, 0xE8, 0x8A, 0x35, + 0x6E, 0xED, 0x95, 0x69, 0x5D, 0xD7, 0xE0, 0xC2, + 0x7A, 0x59, 0x1E, 0x6F, 0x6F, 0x65, 0x96, 0x2B, 0xAF + }, + // unknown. Needs identification + { + 0x04, 0xA7, 0x48, 0xB6, 0xA6, 0x32, 0xFB, 0xEE, + 0x2C, 0x08, 0x97, 0x70, 0x2B, 0x33, 0xBE, 0xA1, + 0xC0, 0x74, 0x99, 0x8E, 0x17, 0xB8, 0x4A, 0xCA, + 0x04, 0xFF, 0x26, 0x7E, 0x5D, 0x2C, 0x91, 0xF6, 0xDC + }, + // manufacturer public key + { + 0x04, 0x6F, 0x70, 0xAC, 0x55, 0x7F, 0x54, 0x61, + 0xCE, 0x50, 0x52, 0xC8, 0xE4, 0xA7, 0x83, 0x8C, + 0x11, 0xC7, 0xA2, 0x36, 0x79, 0x7E, 0x8A, 0x07, + 0x30, 0xA1, 0x01, 0x83, 0x7C, 0x00, 0x40, 0x39, 0xC2 + }, + // MIKRON public key. + { + 0x04, 0xf9, 0x71, 0xed, 0xa7, 0x42, 0xa4, 0xa8, + 0x0d, 0x32, 0xdc, 0xf6, 0xa8, 0x14, 0xa7, 0x07, + 0xcc, 0x3d, 0xc3, 0x96, 0xd3, 0x59, 0x02, 0xf7, + 0x29, 0x29, 0xfd, 0xcd, 0x69, 0x8b, 0x34, 0x68, 0xf2 + } }; static int CmdHF15Help(const char *Cmd); +static int nxp_15693_print_signature(uint8_t *uid, uint8_t *signature) { + + uint8_t i; + int res; + bool is_valid = false; + for (i = 0; i< ARRAYLEN(nxp_15693_public_keys); i++) { + + res = ecdsa_signature_r_s_verify(MBEDTLS_ECP_DP_SECP128R1, nxp_15693_public_keys[i], uid, 8, signature, 32, false); + + is_valid = (res == 0); + if (is_valid) + break; + } + + PrintAndLogEx(NORMAL, ""); + if (is_valid == false) { + PrintAndLogEx(SUCCESS, "Signature verification " _RED_("failed")); + return PM3_ESOFT; + } + + PrintAndLogEx(INFO, "\n--- Tag Signature"); + PrintAndLogEx(INFO, " IC signature public key name : %s", (i == 0)? "NXP ICODE SLIX2 / DNA" : "unknown, post on forum"); + PrintAndLogEx(INFO, " IC signature public key value : %s", sprint_hex(nxp_15693_public_keys[i], 33)); + PrintAndLogEx(INFO, " Elliptic curve parameters : NID_secp128r1"); + PrintAndLogEx(INFO, " TAG IC Signature : %s", sprint_hex(signature, 32)); + PrintAndLogEx(INFO, " Signature verification " _GREEN_("successful")); + return PM3_SUCCESS; +} + // fast method to just read the UID of a tag (collision detection not supported) // *buf should be large enough to fit the 64bit uid // returns 1 if succeeded @@ -796,16 +854,8 @@ static int NxpSysInfo(uint8_t *uid) { uint8_t signature[32] = {0x00}; memcpy(signature, recv + 1, 32); - int res = ecdsa_signature_r_s_verify(MBEDTLS_ECP_DP_SECP128R1, nxp_public_keys[0], uid, 8, signature, 32, false); - bool is_valid = (res == 0); + nxp_15693_print_signature(uid, signature); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, " Tag Signature"); - PrintAndLogEx(NORMAL, " IC signature public key name : NXP ICODE SLIX2 / DNA"); - PrintAndLogEx(NORMAL, " IC signature public key value : %s", sprint_hex(nxp_public_keys[0], 33)); - PrintAndLogEx(NORMAL, " Elliptic curve parameters : NID_secp128r1"); - PrintAndLogEx(NORMAL, " TAG IC Signature : %s", sprint_hex(signature, 32)); - PrintAndLogEx(NORMAL, " Signature verification %s", (is_valid) ? _GREEN_("successful") : _RED_("failed")); } } @@ -901,10 +951,16 @@ static int CmdHF15Info(const char *Cmd) { } // Check if SLIX2 and attempt to get NXP System Information + PrintAndLogEx(INFO, "4 & 08 :: %02x 7 == 1 :: %u 8 == 4 :: %u", recv[4], recv[7], recv[8]); if (recv[8] == 0x04 && recv[7] == 0x01 && recv[4] & 0x80) { return NxpSysInfo(uid); } +// if (recv[8] == 0x04 && recv[7] == 0x02 && recv[4] & 0x80) { + return NxpSysInfo(uid); + //} + + PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; diff --git a/client/cmdhfmfdes.c b/client/cmdhfmfdes.c index 7209a5a71..d44f3443d 100644 --- a/client/cmdhfmfdes.c +++ b/client/cmdhfmfdes.c @@ -12,6 +12,7 @@ #include #include +#include "commonutil.h" // ARRAYLEN #include "cmdparser.h" // command_t #include "comms.h" #include "ui.h" @@ -121,18 +122,10 @@ static int get_desfire_freemem(uint32_t *free_mem) { // --- GET SIGNATURE static int desfire_print_signature(uint8_t *uid, uint8_t *signature, size_t signature_len, desfire_cardtype_t card_type) { - uint8_t public_key; - if (card_type == LIGHT) - public_key = 0; - else if (card_type == EV2) - public_key = 1; - else - return PM3_EINVARG; - #define PUBLIC_DESFIRE_ECDA_KEYLEN 57 // ref: MIFARE Desfire Originality Signature Validation - uint8_t nxp_desfire_keys[2][PUBLIC_DESFIRE_ECDA_KEYLEN] = { + uint8_t nxp_desfire_keys[][PUBLIC_DESFIRE_ECDA_KEYLEN] = { // DESFire Light { 0x04, 0x0E, 0x98, 0xE1, 0x17, 0xAA, 0xA3, 0x64, @@ -143,7 +136,11 @@ static int desfire_print_signature(uint8_t *uid, uint8_t *signature, size_t sign 0xD0, 0x25, 0x72, 0x42, 0x7E, 0x5A, 0xE0, 0xA2, 0xDD, 0x36, 0x59, 0x1B, 0x1F, 0xB3, 0x4F, 0xCF, 0x3D }, - // DESFire Ev2 + + // DESFire Ev2 - wanted + // DESFire Ev3 - wanted + + // Unknown - needs identification { 0x04, 0x8A, 0x9B, 0x38, 0x0A, 0xF2, 0xEE, 0x1B, 0x98, 0xDC, 0x41, 0x7F, 0xEC, 0xC2, 0x63, 0xF8, @@ -152,26 +149,59 @@ static int desfire_print_signature(uint8_t *uid, uint8_t *signature, size_t sign 0x42, 0x2B, 0x81, 0xEC, 0x20, 0xB6, 0x5A, 0x66, 0xB5, 0x10, 0x2A, 0x61, 0x59, 0x6A, 0xF3, 0x37, 0x92, 0x00, 0x59, 0x93, 0x16, 0xA0, 0x0A, 0x14, 0x10 - } + }, + // Unknown - needs identification + { + 0x04, 0x44, 0x09, 0xAD, 0xC4, 0x2F, 0x91, 0xA8, + 0x39, 0x40, 0x66, 0xBA, 0x83, 0xD8, 0x72, 0xFB, + 0x1D, 0x16, 0x80, 0x37, 0x34, 0xE9, 0x11, 0x17, + 0x04, 0x12, 0xDD, 0xF8, 0xBA, 0xD1, 0xA4, 0xDA, + 0xDF, 0xD0, 0x41, 0x62, 0x91, 0xAF, 0xE1, 0xC7, + 0x48, 0x25, 0x39, 0x25, 0xDA, 0x39, 0xA5, 0xF3, + 0x9A, 0x1C, 0x55, 0x7F, 0xFA, 0xCD, 0x34, 0xC6, 0x2E + } }; + + uint8_t i; + int res; + bool is_valid = false; + for (i = 0; i< ARRAYLEN(nxp_desfire_keys); i++) { + + res = ecdsa_signature_r_s_verify(MBEDTLS_ECP_DP_SECP224R1, nxp_desfire_keys[i], uid, 7, signature, signature_len, false); + + is_valid = (res == 0); + if (is_valid) + break; + } + if (is_valid == false) { + PrintAndLogEx(SUCCESS, "Signature verification " _RED_("failed")); + return PM3_ESOFT; + } - int res = ecdsa_signature_r_s_verify(MBEDTLS_ECP_DP_SECP224R1, nxp_desfire_keys[public_key], uid, 7, signature, signature_len, false); - bool is_valid = (res == 0); + char *publickeyname; + switch(i) { + case 0: + publickeyname = "NXP DESFire Light"; + break; + default: + publickeyname = "Unknown DESFire, post on forum"; + break; + } PrintAndLogEx(INFO, " Tag Signature"); - PrintAndLogEx(INFO, " IC signature public key name : %s", (card_type == LIGHT) ? "NXP DESFire Light" : "NXP DESFire Ev2"); - PrintAndLogEx(INFO, " IC signature public key value : %s", sprint_hex(nxp_desfire_keys[public_key], 16)); - PrintAndLogEx(INFO, " : %s", sprint_hex(nxp_desfire_keys[public_key] + 16, 16)); - PrintAndLogEx(INFO, " : %s", sprint_hex(nxp_desfire_keys[public_key] + 32, 16)); - PrintAndLogEx(INFO, " : %s", sprint_hex(nxp_desfire_keys[public_key] + 48, PUBLIC_DESFIRE_ECDA_KEYLEN - 48)); + PrintAndLogEx(INFO, " IC signature public key name : %s", publickeyname); + PrintAndLogEx(INFO, " IC signature public key value : %s", sprint_hex(nxp_desfire_keys[i], 16)); + PrintAndLogEx(INFO, " : %s", sprint_hex(nxp_desfire_keys[i] + 16, 16)); + PrintAndLogEx(INFO, " : %s", sprint_hex(nxp_desfire_keys[i] + 32, 16)); + PrintAndLogEx(INFO, " : %s", sprint_hex(nxp_desfire_keys[i] + 48, PUBLIC_DESFIRE_ECDA_KEYLEN - 48)); PrintAndLogEx(INFO, " Elliptic curve parameters : NID_secp224r1"); PrintAndLogEx(INFO, " TAG IC Signature : %s", sprint_hex(signature, 16)); PrintAndLogEx(INFO, " : %s", sprint_hex(signature + 16, 16)); PrintAndLogEx(INFO, " : %s", sprint_hex(signature + 32, 16)); PrintAndLogEx(INFO, " : %s", sprint_hex(signature + 48, signature_len - 48)); - PrintAndLogEx( (is_valid) ? SUCCESS : WARNING, " Signature verified %s", (is_valid) ? _GREEN_("successful") : _RED_("failed")); + PrintAndLogEx( (is_valid) ? SUCCESS : WARNING, " Signature verified " _GREEN_("successful")); PrintAndLogEx(INFO, "-------------------------------------------------------------"); return PM3_SUCCESS; } diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index d5a632f8f..7acf7379b 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -262,57 +262,6 @@ uint8_t default_pwd_pack[][4] = { {0xFF, 0xFF, 0xFF, 0xFF}, // PACK 0x00,0x00 -- factory default }; -#define PUBLIC_ECDA_KEYLEN 33 - -// known public keys for the originality check (source: https://github.com/alexbatalov/node-nxp-originality-verifier) -// ref: AN11350 NTAG 21x Originality Signature Validation -// ref: AN11341 MIFARE Ultralight EV1 Originality Signature Validation -uint8_t nxp_mfu_public_keys[6][PUBLIC_ECDA_KEYLEN] = { - // UL, NTAG21x and NDEF - { - 0x04, 0x49, 0x4e, 0x1a, 0x38, 0x6d, 0x3d, 0x3c, - 0xfe, 0x3d, 0xc1, 0x0e, 0x5d, 0xe6, 0x8a, 0x49, - 0x9b, 0x1c, 0x20, 0x2d, 0xb5, 0xb1, 0x32, 0x39, - 0x3e, 0x89, 0xed, 0x19, 0xfe, 0x5b, 0xe8, 0xbc, 0x61 - }, - // UL EV1 - { - 0x04, 0x90, 0x93, 0x3b, 0xdc, 0xd6, 0xe9, 0x9b, - 0x4e, 0x25, 0x5e, 0x3d, 0xa5, 0x53, 0x89, 0xa8, - 0x27, 0x56, 0x4e, 0x11, 0x71, 0x8e, 0x01, 0x72, - 0x92, 0xfa, 0xf2, 0x32, 0x26, 0xa9, 0x66, 0x14, 0xb8 - }, - // unknown. Needs identification - { - 0x04, 0x4F, 0x6D, 0x3F, 0x29, 0x4D, 0xEA, 0x57, - 0x37, 0xF0, 0xF4, 0x6F, 0xFE, 0xE8, 0x8A, 0x35, - 0x6E, 0xED, 0x95, 0x69, 0x5D, 0xD7, 0xE0, 0xC2, - 0x7A, 0x59, 0x1E, 0x6F, 0x6F, 0x65, 0x96, 0x2B, 0xAF - }, - // unknown. Needs identification - { - 0x04, 0xA7, 0x48, 0xB6, 0xA6, 0x32, 0xFB, 0xEE, - 0x2C, 0x08, 0x97, 0x70, 0x2B, 0x33, 0xBE, 0xA1, - 0xC0, 0x74, 0x99, 0x8E, 0x17, 0xB8, 0x4A, 0xCA, - 0x04, 0xFF, 0x26, 0x7E, 0x5D, 0x2C, 0x91, 0xF6, 0xDC - }, - // manufacturer public key - { - 0x04, 0x6F, 0x70, 0xAC, 0x55, 0x7F, 0x54, 0x61, - 0xCE, 0x50, 0x52, 0xC8, 0xE4, 0xA7, 0x83, 0x8C, - 0x11, 0xC7, 0xA2, 0x36, 0x79, 0x7E, 0x8A, 0x07, - 0x30, 0xA1, 0x01, 0x83, 0x7C, 0x00, 0x40, 0x39, 0xC2 - }, - // MIKRON public key. - { - 0x04, 0xf9, 0x71, 0xed, 0xa7, 0x42, 0xa4, 0xa8, - 0x0d, 0x32, 0xdc, 0xf6, 0xa8, 0x14, 0xa7, 0x07, - 0xcc, 0x3d, 0xc3, 0x96, 0xd3, 0x59, 0x02, 0xf7, - 0x29, 0x29, 0xfd, 0xcd, 0x69, 0x8b, 0x34, 0x68, 0xf2 - } -}; - - uint32_t UL_TYPES_ARRAY[] = { UNKNOWN, UL, UL_C, UL_EV1_48, UL_EV1_128, NTAG, NTAG_203, NTAG_210, NTAG_212, NTAG_213, NTAG_215, NTAG_216, @@ -915,19 +864,98 @@ static int ulev1_print_counters() { } static int ulev1_print_signature(TagTypeUL_t tagtype, uint8_t *uid, uint8_t *signature, size_t signature_len) { - uint8_t public_key = 0; - if (tagtype == UL_EV1_48 || tagtype == UL_EV1_128) { - public_key = 1; + + #define PUBLIC_ECDA_KEYLEN 33 + + // known public keys for the originality check (source: https://github.com/alexbatalov/node-nxp-originality-verifier) + // ref: AN11350 NTAG 21x Originality Signature Validation + // ref: AN11341 MIFARE Ultralight EV1 Originality Signature Validation + uint8_t nxp_mfu_public_keys[6][PUBLIC_ECDA_KEYLEN] = { + // UL, NTAG21x and NDEF + { + 0x04, 0x49, 0x4e, 0x1a, 0x38, 0x6d, 0x3d, 0x3c, + 0xfe, 0x3d, 0xc1, 0x0e, 0x5d, 0xe6, 0x8a, 0x49, + 0x9b, 0x1c, 0x20, 0x2d, 0xb5, 0xb1, 0x32, 0x39, + 0x3e, 0x89, 0xed, 0x19, 0xfe, 0x5b, 0xe8, 0xbc, 0x61 + }, + // UL EV1 + { + 0x04, 0x90, 0x93, 0x3b, 0xdc, 0xd6, 0xe9, 0x9b, + 0x4e, 0x25, 0x5e, 0x3d, 0xa5, 0x53, 0x89, 0xa8, + 0x27, 0x56, 0x4e, 0x11, 0x71, 0x8e, 0x01, 0x72, + 0x92, 0xfa, 0xf2, 0x32, 0x26, 0xa9, 0x66, 0x14, 0xb8 + }, + // unknown. Needs identification + { + 0x04, 0x4F, 0x6D, 0x3F, 0x29, 0x4D, 0xEA, 0x57, + 0x37, 0xF0, 0xF4, 0x6F, 0xFE, 0xE8, 0x8A, 0x35, + 0x6E, 0xED, 0x95, 0x69, 0x5D, 0xD7, 0xE0, 0xC2, + 0x7A, 0x59, 0x1E, 0x6F, 0x6F, 0x65, 0x96, 0x2B, 0xAF + }, + // unknown. Needs identification + { + 0x04, 0xA7, 0x48, 0xB6, 0xA6, 0x32, 0xFB, 0xEE, + 0x2C, 0x08, 0x97, 0x70, 0x2B, 0x33, 0xBE, 0xA1, + 0xC0, 0x74, 0x99, 0x8E, 0x17, 0xB8, 0x4A, 0xCA, + 0x04, 0xFF, 0x26, 0x7E, 0x5D, 0x2C, 0x91, 0xF6, 0xDC + }, + // manufacturer public key + { + 0x04, 0x6F, 0x70, 0xAC, 0x55, 0x7F, 0x54, 0x61, + 0xCE, 0x50, 0x52, 0xC8, 0xE4, 0xA7, 0x83, 0x8C, + 0x11, 0xC7, 0xA2, 0x36, 0x79, 0x7E, 0x8A, 0x07, + 0x30, 0xA1, 0x01, 0x83, 0x7C, 0x00, 0x40, 0x39, 0xC2 + }, + // MIKRON public key. + { + 0x04, 0xf9, 0x71, 0xed, 0xa7, 0x42, 0xa4, 0xa8, + 0x0d, 0x32, 0xdc, 0xf6, 0xa8, 0x14, 0xa7, 0x07, + 0xcc, 0x3d, 0xc3, 0x96, 0xd3, 0x59, 0x02, 0xf7, + 0x29, 0x29, 0xfd, 0xcd, 0x69, 0x8b, 0x34, 0x68, 0xf2 + } + }; + + uint8_t i; + int res; + bool is_valid = false; + for (i = 0; i< ARRAYLEN(nxp_mfu_public_keys); i++) { + + res = ecdsa_signature_r_s_verify(MBEDTLS_ECP_DP_SECP128R1, nxp_mfu_public_keys[i], uid, 7, signature, signature_len, false); + + is_valid = (res == 0); + if (is_valid) + break; + } + if (is_valid == false) { + PrintAndLogEx(SUCCESS, "Signature verification " _RED_("failed")); + return PM3_ESOFT; + } + + char *publickeyname; + switch(i) { + case 0: + publickeyname = "NXP NTAG21x (2013)"; + break; + case 1: + publickeyname = "NXP Ev1"; + break; + case 4: + publickeyname = "Manufacturer, post on forum"; + break; + case 5: + publickeyname = "MIKRON"; + break; + default: + publickeyname = "Unknown, post on forum"; + break; } - int res = ecdsa_signature_r_s_verify(MBEDTLS_ECP_DP_SECP128R1, nxp_mfu_public_keys[public_key], uid, 7, signature, signature_len, false); - bool is_valid = (res == 0); PrintAndLogEx(INFO, "\n--- Tag Signature"); - PrintAndLogEx(INFO, "IC signature public key name : NXP NTAG21x (2013)"); - PrintAndLogEx(INFO, "IC signature public key value : %s", sprint_hex(nxp_mfu_public_keys[public_key], PUBLIC_ECDA_KEYLEN)); + PrintAndLogEx(INFO, "IC signature public key name : %s", publickeyname); + PrintAndLogEx(INFO, "IC signature public key value : %s", sprint_hex(nxp_mfu_public_keys[i], PUBLIC_ECDA_KEYLEN)); PrintAndLogEx(INFO, " Elliptic curve parameters : NID_secp128r1"); PrintAndLogEx(INFO, " TAG IC Signature : %s", sprint_hex(signature, signature_len)); - PrintAndLogEx(SUCCESS, "Signature verified %s", (is_valid) ? _GREEN_("successful") : _RED_("failed")); + PrintAndLogEx(SUCCESS, "Signature verified " _GREEN_("successful")); return PM3_SUCCESS; } From d67c55cd2accc065fcac6404360433e93137c18b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 2 Apr 2020 06:38:45 +0200 Subject: [PATCH 1816/1854] entries from taginfo app\n removed duplicates --- client/dictionaries/mfc_default_keys.dic | 118 ++++++++++++----------- 1 file changed, 63 insertions(+), 55 deletions(-) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index 4682ad0e5..6e2a2f4da 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -5,7 +5,8 @@ # ffffffffffff # Defaultkey(firstkeyusedbyprogramifnouserdefinedkey) 000000000000 # Blankkey -a0a1a2a3a4a5 # NFCForumMADkey +a0a1a2a3a4a5 # NFC Forum MADkey +A5A4A3A2A1A0 # MAD access key (reversed) b0b1b2b3b4b5 c0c1c2c3c4c5 d0d1d2d3d4d5 @@ -20,19 +21,49 @@ a0478cc39091 533cb6c723f6 8fd0a4f256e9 # -d2ece8b9395e # lib +d2ece8b9395e # lib / Nat Bieb # NSCP default key 1494E81663D7 # +# Kiev keys +569369c5a0e5 # kiev +632193be1c3c # kiev +644672bd4afe # kiev +8fe644038790 # kiev +9de89e070277 # kiev +b5ff67cba951 # kiev / ov-chipkaart +eff603e1efe9 # kiev +f14ee7cae863 # kiev +# +# RKF +fc00018778f7 # Västtrafiken KeyA, RKF ÖstgötaTrafiken KeyA +0297927c0f77 # Västtrafiken KeyA +54726176656c # Västtrafiken KeyA +00000ffe2488 # Västtrafiken KeyB +776974687573 # Västtrafiken KeyB +ee0042f88840 # Västtrafiken KeyB +26940b21ff5d # RKF SLKeyA +a64598a77478 # RKF SLKeyA +5c598c9c58b5 # RKF SLKeyB +e4d2770a89be # RKF SLKeyB +722bfcc5375f # RKF RejskortDanmark KeyA +f1d83f964314 # RKF RejskortDanmark KeyB +505249564141 # RKF JOJOPRIVAKeyA +505249564142 # RKF JOJOPRIVAKeyB +47524f555041 # RKF JOJOGROUPKeyA +47524f555042 # RKF JOJOGROUPKeyB +434f4d4d4f41 # RKF JOJOGROUPKeyA +434f4d4d4f42 # RKF JOJOGROUPKeyB +# +4b0b20107ccb # TNP3xxx +# # more Keys from mfc_default_keys.lua 000000000001 000000000002 00000000000a 00000000000b -00000ffe2488 # VästtrafikenKeyB 010203040506 0123456789ab -0297927c0f77 # VästtrafikenKeyA 100000000000 111111111111 123456789abc @@ -41,72 +72,39 @@ d2ece8b9395e # lib 1999a3554a55 200000000000 222222222222 -26940b21ff5d # RKFSLKeyA 27dd91f1fcf1 2BA9621E0A36 # DirectoryandeventlogKeyB +4AF9D7ADEBE4 # DirectoryandeventlogKeyA 333333333333 33f974b42769 34d1df9934c5 -434f4d4d4f41 # RKFJOJOGROUPKeyA -434f4d4d4f42 # RKFJOJOGROUPKeyB 43ab19ef5c31 444444444444 -47524f555041 # RKFJOJOGROUPKeyA -47524f555042 # RKFJOJOGROUPKeyB -4AF9D7ADEBE4 # DirectoryandeventlogKeyA -4b0b20107ccb # TNP3xxx -505249564141 # RKFJOJOPRIVAKeyA -505249564142 # RKFJOJOPRIVAKeyB 505249565441 505249565442 -54726176656c # VästtrafikenKeyA 555555555555 55f5a5dd38c9 -569369c5a0e5 # kiev -5c598c9c58b5 # RKFSLKeyB -632193be1c3c # kiev -644672bd4afe # kiev 666666666666 -722bfcc5375f # RKFRejskortDanmarkKeyA -776974687573 # VästtrafikenKeyB 777777777777 888888888888 -8fe644038790 # kiev 999999999999 99c636334433 -9de89e070277 # kiev a00000000000 a053a292a4af -a64598a77478 # RKFSLKeyA a94133013401 aaaaaaaaaaaa abcdef123456 # Keyfromladyada.net b00000000000 b127c6f41436 -b5ff67cba951 # kiev bbbbbbbbbbbb bd493a3962b6 c934fe34d934 cccccccccccc dddddddddddd -e4d2770a89be # RKFSLKeyB -ee0042f88840 # VästtrafikenKeyB eeeeeeeeeeee -eff603e1efe9 # kiev -f14ee7cae863 # kiev f1a97341a9fc -f1d83f964314 # RKFRejskortDanmarkKeyB -fc00018778f7 # VästtrafikenKeyA, RKFÖstgötaTrafikenKeyA 44ab09010845 # hotel system 85fed980ea5a # hotel system -314B49474956 # VIGIK1 A -564c505f4d41 # VIGIK1 B -ba5b895da162 # VIGIK1 B -# Vigik mystery Keys Mifare 1k EV1 (S50) -5c8ff9990da2 # 16 A -75ccb59c9bed # 17 A -d01afeeb890a # 16 B -4b791bea7bcc # 17 B # 43454952534E # ARD (fr) key A 4A2B29111213 # ARD (fr) key B @@ -361,11 +359,29 @@ a56c2df9a26d # 68d3f7307c89 568c9083f71c # Smart Rider. Western Australian Public Transport Cards +# +# +97F5DA640B18 # Bangkok metro key +A8844B0BCA06 # Metro Valencia key +857464D3AAD1 # HTC Eindhoven key +# # Vigik Keys # Various sources : # * https://github.com/DumpDos/Vigik # * http://newffr.com/viewtopic.php?&forum=235&topic=11559 # * Own dumps +# +# French VIGIK +314B49474956 # VIGIK1 A +564c505f4d41 # VIGIK1 B +ba5b895da162 # VIGIK1 B +# +# Vigik mystery Keys Mifare 1k EV1 (S50) +5c8ff9990da2 # 16 A +75ccb59c9bed # 17 A +d01afeeb890a # 16 B +4b791bea7bcc # 17 B +# 021209197591 # BTCINO UNDETERMINED SPREAKD 0x01->0x13 key 2ef720f2af76 414c41524f4e @@ -543,11 +559,13 @@ B66AC040203A 2E641D99AD5B AD4FB33388BF 69FB7B7CD8EE -2A6D9205E7CA +2A6D9205E7CA # Hotel 2a2c13cc242a 27FBC86A00D0 01FA3FC68349 # +13B91C226E56 # Hotel +# 6D44B5AAF464 # Smart Rider. Western Australian Public Transport Cards 1717E34A7A8A # Smart Rider. Western Australian Public Transport Cards # @@ -1044,37 +1062,21 @@ a2a3cca2a3cc # # Granada, ES Transport Card 000000270000 -0172066b2f03 -0172066b2f33 -066b2f230172 -0b0172066b2f 0f385ffb6529 -172066b2f2f0 -2066b2f27017 29173860fc76 -2f130172066b 2fca8492f386 385efa542907 3864fcba5937 -3b0172066b2f 3f3865fccb69 5c8ff9990da2 6291b3860fc8 63fca9492f38 -66b2f1f01720 -6b2f1b017206 -70172066b2f0 -70172066b2f3 -72066b2f2b01 863fcb959373 87291f3861fc 913385ffb752 -b2f170172066 b385efa64290 c9739233861f -f0f0172066b2 f3864fcca693 -f3f0172066b2 fc9839273862 # # various hotel keys @@ -1110,3 +1112,9 @@ fe04ecfe5577 6d9b485a4845 # 5a7a52d5e20d # Bosch Solution 6000 +# +# Found in TagInfo app +8A19D40CF2B5 # Hotel key card key +C1E51C63B8F5 # RATB key +1DB710648A65 +18F34C92A56E # E-GO card key From cd4b44008c0893122ccfa49550ec56694011c14e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 2 Apr 2020 06:41:19 +0200 Subject: [PATCH 1817/1854] text --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ef686269..2250e33c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Change - mfc default keys removed dublicates (@iceman1001) + . Change - mfc default keys got new entries found on TagInfo app (@anon) - Added `hf mfu ndef` - read and decode NDEF Type2 messages (@iceman1001) - Added `data ndef` - decode NDEF messages (@iceman1001) - Change - usb write's now waits for shiftregisters (@pwpiwi) From 1bb9b2b11253f17e6992633b1e0d1e2208d18b2f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 2 Apr 2020 07:55:35 +0200 Subject: [PATCH 1818/1854] chg: fixed the h param in filename became help bug --- client/cmdflashmemspiffs.c | 133 +++++++++++++++++++++---------------- 1 file changed, 74 insertions(+), 59 deletions(-) diff --git a/client/cmdflashmemspiffs.c b/client/cmdflashmemspiffs.c index fa8cdbf16..788851f1a 100644 --- a/client/cmdflashmemspiffs.c +++ b/client/cmdflashmemspiffs.c @@ -18,48 +18,6 @@ static int CmdHelp(const char *Cmd); -static int CmdFlashMemSpiFFSMount(const char *Cmd) { - (void)Cmd; // Cmd is not used so far - clearCommandBuffer(); - SendCommandNG(CMD_SPIFFS_MOUNT, NULL, 0); - return PM3_SUCCESS; -} - -static int CmdFlashMemSpiFFSUnmount(const char *Cmd) { - (void)Cmd; // Cmd is not used so far - clearCommandBuffer(); - SendCommandNG(CMD_SPIFFS_UNMOUNT, NULL, 0); - return PM3_SUCCESS; -} - -static int CmdFlashMemSpiFFSTest(const char *Cmd) { - (void)Cmd; // Cmd is not used so far - clearCommandBuffer(); - SendCommandNG(CMD_SPIFFS_TEST, NULL, 0); - return PM3_SUCCESS; -} - -static int CmdFlashMemSpiFFSCheck(const char *Cmd) { - (void)Cmd; // Cmd is not used so far - clearCommandBuffer(); - SendCommandNG(CMD_SPIFFS_CHECK, NULL, 0); - return PM3_SUCCESS; -} - -static int CmdFlashMemSpiFFSTree(const char *Cmd) { - (void)Cmd; // Cmd is not used so far - clearCommandBuffer(); - SendCommandNG(CMD_SPIFFS_PRINT_TREE, NULL, 0); - return PM3_SUCCESS; -} - -static int CmdFlashMemSpiFFSInfo(const char *Cmd) { - (void)Cmd; // Cmd is not used so far - clearCommandBuffer(); - SendCommandNG(CMD_SPIFFS_PRINT_FSINFO, NULL, 0); - return PM3_SUCCESS; -} - static int usage_flashmemspiffs_remove(void) { PrintAndLogEx(NORMAL, "Remove a file from spiffs filesystem"); PrintAndLogEx(NORMAL, " Usage: mem spiffs remove "); @@ -107,16 +65,64 @@ static int usage_flashmemspiffs_load(void) { return PM3_SUCCESS; } + +static int CmdFlashMemSpiFFSMount(const char *Cmd) { + (void)Cmd; // Cmd is not used so far + clearCommandBuffer(); + SendCommandNG(CMD_SPIFFS_MOUNT, NULL, 0); + return PM3_SUCCESS; +} + +static int CmdFlashMemSpiFFSUnmount(const char *Cmd) { + (void)Cmd; // Cmd is not used so far + clearCommandBuffer(); + SendCommandNG(CMD_SPIFFS_UNMOUNT, NULL, 0); + return PM3_SUCCESS; +} + +static int CmdFlashMemSpiFFSTest(const char *Cmd) { + (void)Cmd; // Cmd is not used so far + clearCommandBuffer(); + SendCommandNG(CMD_SPIFFS_TEST, NULL, 0); + return PM3_SUCCESS; +} + +static int CmdFlashMemSpiFFSCheck(const char *Cmd) { + (void)Cmd; // Cmd is not used so far + clearCommandBuffer(); + SendCommandNG(CMD_SPIFFS_CHECK, NULL, 0); + return PM3_SUCCESS; +} + +static int CmdFlashMemSpiFFSTree(const char *Cmd) { + (void)Cmd; // Cmd is not used so far + clearCommandBuffer(); + SendCommandNG(CMD_SPIFFS_PRINT_TREE, NULL, 0); + return PM3_SUCCESS; +} + +static int CmdFlashMemSpiFFSInfo(const char *Cmd) { + (void)Cmd; // Cmd is not used so far + clearCommandBuffer(); + SendCommandNG(CMD_SPIFFS_PRINT_FSINFO, NULL, 0); + return PM3_SUCCESS; +} + static int CmdFlashMemSpiFFSRemove(const char *Cmd) { + int len = strlen(Cmd); + if (len < 1) { + return usage_flashmemspiffs_remove(); + } + + char ctmp = tolower(param_getchar(Cmd, 0)); + if (len == 1 && ctmp == 'h') { + return usage_flashmemspiffs_remove(); + } + char filename[32] = {0}; bool errors = false; - /*char ctmp = tolower(param_getchar(Cmd, 0)); - if (strlen(Cmd) < 1 || ctmp == 'h') { - return usage_flashmemspiffs_remove(); - }*/ - if (param_getstr(Cmd, 0, filename, 32) >= 32) { PrintAndLogEx(FAILED, "Filename too long"); errors = true; @@ -134,15 +140,20 @@ static int CmdFlashMemSpiFFSRemove(const char *Cmd) { static int CmdFlashMemSpiFFSRename(const char *Cmd) { + int len = strlen(Cmd); + if (len < 1) { + return usage_flashmemspiffs_rename(); + } + + char ctmp = tolower(param_getchar(Cmd, 0)); + if (len == 1 && ctmp == 'h') { + return usage_flashmemspiffs_rename(); + } + char srcfilename[32] = {0}; char destfilename[32] = {0}; bool errors = false; - /*char ctmp = tolower(param_getchar(Cmd, 0)); - if (strlen(Cmd) < 1 || ctmp == 'h') { - return usage_flashmemspiffs_rename(); - }*/ - if (param_getstr(Cmd, 0, srcfilename, 32) >= 32) { PrintAndLogEx(FAILED, "Source Filename too long"); errors = true; @@ -174,16 +185,21 @@ static int CmdFlashMemSpiFFSRename(const char *Cmd) { } static int CmdFlashMemSpiFFSCopy(const char *Cmd) { + int len = strlen(Cmd); + if (len < 1) { + return usage_flashmemspiffs_copy(); + } + char ctmp = tolower(param_getchar(Cmd, 0)); + if (len == 1 && ctmp == 'h') { + return usage_flashmemspiffs_copy(); + } + + char srcfilename[32] = {0}; char destfilename[32] = {0}; bool errors = false; - /*char ctmp = tolower(param_getchar(Cmd, 0)); - if (strlen(Cmd) < 1 || ctmp == 'h') { - return usage_flashmemspiffs_copy(); - }*/ - if (param_getstr(Cmd, 0, srcfilename, 32) >= 32) { PrintAndLogEx(FAILED, "Source Filename too long"); errors = true; @@ -441,8 +457,7 @@ static int CmdFlashMemSpiFFSLoad(const char *Cmd) { static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, - { - "copy", CmdFlashMemSpiFFSCopy, IfPm3Flash, + {"copy", CmdFlashMemSpiFFSCopy, IfPm3Flash, "Copy a file to another (destructively) in SPIFFS FileSystem in FlashMEM (spiffs)" }, {"check", CmdFlashMemSpiFFSCheck, IfPm3Flash, "Check/try to defrag faulty/fragmented Filesystem"}, From 761860656eaa6ae5a7cedca1d45abe3d43fe8197 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 2 Apr 2020 08:09:18 +0200 Subject: [PATCH 1819/1854] more pulic keys (@anon) --- client/cmdhfmfdes.c | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/client/cmdhfmfdes.c b/client/cmdhfmfdes.c index d44f3443d..1ec0621f4 100644 --- a/client/cmdhfmfdes.c +++ b/client/cmdhfmfdes.c @@ -140,7 +140,7 @@ static int desfire_print_signature(uint8_t *uid, uint8_t *signature, size_t sign // DESFire Ev2 - wanted // DESFire Ev3 - wanted - // Unknown - needs identification + // NTAG42x 1-3 NTAG 424 DNA TagTamper, NTAG426 TT { 0x04, 0x8A, 0x9B, 0x38, 0x0A, 0xF2, 0xEE, 0x1B, 0x98, 0xDC, 0x41, 0x7F, 0xEC, 0xC2, 0x63, 0xF8, @@ -160,7 +160,29 @@ static int desfire_print_signature(uint8_t *uid, uint8_t *signature, size_t sign 0xDF, 0xD0, 0x41, 0x62, 0x91, 0xAF, 0xE1, 0xC7, 0x48, 0x25, 0x39, 0x25, 0xDA, 0x39, 0xA5, 0xF3, 0x9A, 0x1C, 0x55, 0x7F, 0xFA, 0xCD, 0x34, 0xC6, 0x2E - } + }, + + // NTAG42x 4 - NTAG426 + { + 0x04, 0xB3, 0x04, 0xDC, 0x4C, 0x61, 0x5F, 0x53, + 0x26, 0xFE, 0x93, 0x83, 0xDD, 0xEC, 0x9A, 0xA8, + 0x92, 0xDF, 0x3A, 0x57, 0xFA, 0x7F, 0xFB, 0x32, + 0x76, 0x19, 0x2B, 0xC0, 0xEA, 0xA2, 0x52, 0xED, + 0x45, 0xA8, 0x65, 0xE3, 0xB0, 0x93, 0xA3, 0xD0, + 0xDC, 0xE5, 0xBE, 0x29, 0xE9, 0x2F, 0x13, 0x92, + 0xCE, 0x7D, 0xE3, 0x21, 0xE3, 0xE5, 0xC5, 0x2B, 0x3A + }, + + // NTAG42x 3 - NTAG 424 DNA + { + 0x04, 0x0E, 0x98, 0xE1, 0x17, 0xAA, 0xA3, 0x64, + 0x57, 0xF4, 0x31, 0x73, 0xDC, 0x92, 0x0A, 0x87, + 0x57, 0x26, 0x7F, 0x44, 0xCE, 0x4E, 0xC5, 0xAD, + 0xD3, 0xC5, 0x40, 0x75, 0x57, 0x1A, 0xEB, 0xBF, + 0x7B, 0x94, 0x2A, 0x97, 0x74, 0xA1, 0xD9, 0x4A, + 0xD0, 0x25, 0x72, 0x42, 0x7E, 0x5A, 0xE0, 0xA2, + 0xDD, 0x36, 0x59, 0x1B, 0x1F, 0xB3, 0x4F, 0xCF, 0x3D + }, }; uint8_t i; @@ -185,6 +207,16 @@ static int desfire_print_signature(uint8_t *uid, uint8_t *signature, size_t sign case 0: publickeyname = "NXP DESFire Light"; break; + case 1: + publickeyname = "NTAG42x 1-3 NTAG 424 DNA TagTamper, NTAG426 TT"; + break; + + case 3: + publickeyname = "NTAG42x 4 - NTAG426"; + break; + case 4: + publickeyname = "NTAG42x 3 - NTAG 424 DNA"; + break; default: publickeyname = "Unknown DESFire, post on forum"; break; From b91c4977af8126b1fbada47be79d8a3c8a9ee021 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 2 Apr 2020 08:14:31 +0200 Subject: [PATCH 1820/1854] textual --- CHANGELOG.md | 1 + client/cmdhfmfdes.c | 6 ++---- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2250e33c2..0bb2efbf7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Change - updated public keys info (@anon) - Change - mfc default keys removed dublicates (@iceman1001) . Change - mfc default keys got new entries found on TagInfo app (@anon) - Added `hf mfu ndef` - read and decode NDEF Type2 messages (@iceman1001) diff --git a/client/cmdhfmfdes.c b/client/cmdhfmfdes.c index 1ec0621f4..d9a30a877 100644 --- a/client/cmdhfmfdes.c +++ b/client/cmdhfmfdes.c @@ -137,7 +137,6 @@ static int desfire_print_signature(uint8_t *uid, uint8_t *signature, size_t sign 0xDD, 0x36, 0x59, 0x1B, 0x1F, 0xB3, 0x4F, 0xCF, 0x3D }, - // DESFire Ev2 - wanted // DESFire Ev3 - wanted // NTAG42x 1-3 NTAG 424 DNA TagTamper, NTAG426 TT @@ -162,7 +161,7 @@ static int desfire_print_signature(uint8_t *uid, uint8_t *signature, size_t sign 0x9A, 0x1C, 0x55, 0x7F, 0xFA, 0xCD, 0x34, 0xC6, 0x2E }, - // NTAG42x 4 - NTAG426 + // NTAG42x 4 - NTAG426, DESFire Ev2 { 0x04, 0xB3, 0x04, 0xDC, 0x4C, 0x61, 0x5F, 0x53, 0x26, 0xFE, 0x93, 0x83, 0xDD, 0xEC, 0x9A, 0xA8, @@ -210,9 +209,8 @@ static int desfire_print_signature(uint8_t *uid, uint8_t *signature, size_t sign case 1: publickeyname = "NTAG42x 1-3 NTAG 424 DNA TagTamper, NTAG426 TT"; break; - case 3: - publickeyname = "NTAG42x 4 - NTAG426"; + publickeyname = "NTAG42x 4 - NTAG426, DESFire Ev2"; break; case 4: publickeyname = "NTAG42x 3 - NTAG 424 DNA"; From 3b4d5b56767b725a8beb22bf5ab221764459baad Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 2 Apr 2020 08:25:24 +0200 Subject: [PATCH 1821/1854] remove dublicate --- client/cmdhfmfdes.c | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/client/cmdhfmfdes.c b/client/cmdhfmfdes.c index d9a30a877..bfc842071 100644 --- a/client/cmdhfmfdes.c +++ b/client/cmdhfmfdes.c @@ -124,9 +124,10 @@ static int desfire_print_signature(uint8_t *uid, uint8_t *signature, size_t sign #define PUBLIC_DESFIRE_ECDA_KEYLEN 57 + // DESFire Ev3 - wanted // ref: MIFARE Desfire Originality Signature Validation uint8_t nxp_desfire_keys[][PUBLIC_DESFIRE_ECDA_KEYLEN] = { - // DESFire Light + // NTAG42x 3 - NTAG 424 DNA, DESFire Light { 0x04, 0x0E, 0x98, 0xE1, 0x17, 0xAA, 0xA3, 0x64, 0x57, 0xF4, 0x31, 0x73, 0xDC, 0x92, 0x0A, 0x87, @@ -136,8 +137,6 @@ static int desfire_print_signature(uint8_t *uid, uint8_t *signature, size_t sign 0xD0, 0x25, 0x72, 0x42, 0x7E, 0x5A, 0xE0, 0xA2, 0xDD, 0x36, 0x59, 0x1B, 0x1F, 0xB3, 0x4F, 0xCF, 0x3D }, - - // DESFire Ev3 - wanted // NTAG42x 1-3 NTAG 424 DNA TagTamper, NTAG426 TT { @@ -161,7 +160,7 @@ static int desfire_print_signature(uint8_t *uid, uint8_t *signature, size_t sign 0x9A, 0x1C, 0x55, 0x7F, 0xFA, 0xCD, 0x34, 0xC6, 0x2E }, - // NTAG42x 4 - NTAG426, DESFire Ev2 + // NTAG42x 4 - NTAG426, DESFire Ev2 { 0x04, 0xB3, 0x04, 0xDC, 0x4C, 0x61, 0x5F, 0x53, 0x26, 0xFE, 0x93, 0x83, 0xDD, 0xEC, 0x9A, 0xA8, @@ -172,16 +171,6 @@ static int desfire_print_signature(uint8_t *uid, uint8_t *signature, size_t sign 0xCE, 0x7D, 0xE3, 0x21, 0xE3, 0xE5, 0xC5, 0x2B, 0x3A }, - // NTAG42x 3 - NTAG 424 DNA - { - 0x04, 0x0E, 0x98, 0xE1, 0x17, 0xAA, 0xA3, 0x64, - 0x57, 0xF4, 0x31, 0x73, 0xDC, 0x92, 0x0A, 0x87, - 0x57, 0x26, 0x7F, 0x44, 0xCE, 0x4E, 0xC5, 0xAD, - 0xD3, 0xC5, 0x40, 0x75, 0x57, 0x1A, 0xEB, 0xBF, - 0x7B, 0x94, 0x2A, 0x97, 0x74, 0xA1, 0xD9, 0x4A, - 0xD0, 0x25, 0x72, 0x42, 0x7E, 0x5A, 0xE0, 0xA2, - 0xDD, 0x36, 0x59, 0x1B, 0x1F, 0xB3, 0x4F, 0xCF, 0x3D - }, }; uint8_t i; @@ -204,7 +193,7 @@ static int desfire_print_signature(uint8_t *uid, uint8_t *signature, size_t sign char *publickeyname; switch(i) { case 0: - publickeyname = "NXP DESFire Light"; + publickeyname = "NTAG42x 3 - NTAG 424 DNA / DESFire Light"; break; case 1: publickeyname = "NTAG42x 1-3 NTAG 424 DNA TagTamper, NTAG426 TT"; @@ -212,9 +201,6 @@ static int desfire_print_signature(uint8_t *uid, uint8_t *signature, size_t sign case 3: publickeyname = "NTAG42x 4 - NTAG426, DESFire Ev2"; break; - case 4: - publickeyname = "NTAG42x 3 - NTAG 424 DNA"; - break; default: publickeyname = "Unknown DESFire, post on forum"; break; From 61e59fa9138805238220a610c991759a228d46a1 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 2 Apr 2020 09:25:04 +0200 Subject: [PATCH 1822/1854] fix: 'hf mfu ndef - sig2 uses wrong index --- client/cmdhfmfu.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index 7acf7379b..09e0aff56 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -2797,6 +2797,8 @@ static int CmdHF14MfuNDEF(const char *Cmd) { return PM3_ESOFT; } } + + PrintAndLogEx(INFO, "ICE:: %s", sprint_hex(records, maxsize)); DropField(); status = NDEFDecodeAndPrint(records, (size_t)maxsize, true); free(records); From 47d43cfc569957d44709a7645869827f4cac9273 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 2 Apr 2020 09:34:03 +0200 Subject: [PATCH 1823/1854] text --- client/cmdhfmfu.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index 09e0aff56..af501d8f2 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -2797,8 +2797,7 @@ static int CmdHF14MfuNDEF(const char *Cmd) { return PM3_ESOFT; } } - - PrintAndLogEx(INFO, "ICE:: %s", sprint_hex(records, maxsize)); + DropField(); status = NDEFDecodeAndPrint(records, (size_t)maxsize, true); free(records); From 16110985caf1bec1f0b8c7d393ad4e5cb27419ae Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 2 Apr 2020 09:34:52 +0200 Subject: [PATCH 1824/1854] text --- client/mifare/ndef.c | 73 ++++++++++++++++++++++---------------------- 1 file changed, 36 insertions(+), 37 deletions(-) diff --git a/client/mifare/ndef.c b/client/mifare/ndef.c index e3ba3997d..8f5e93a2e 100644 --- a/client/mifare/ndef.c +++ b/client/mifare/ndef.c @@ -145,18 +145,18 @@ static int ndefDecodeHeader(uint8_t *data, size_t datalen, NDEFHeader_t *header) static int ndefPrintHeader(NDEFHeader_t *header) { PrintAndLogEx(INFO, "Header:"); - PrintAndLogEx(NORMAL, "\tMessage Begin: %s", STRBOOL(header->MessageBegin)); - PrintAndLogEx(NORMAL, "\tMessage End: %s", STRBOOL(header->MessageEnd)); - PrintAndLogEx(NORMAL, "\tChunk Flag: %s", STRBOOL(header->ChunkFlag)); - PrintAndLogEx(NORMAL, "\tShort Record Bit: %s", STRBOOL(header->ShortRecordBit)); - PrintAndLogEx(NORMAL, "\tID Len Present: %s", STRBOOL(header->IDLenPresent)); - PrintAndLogEx(NORMAL, "\tType Name Format: [0x%02x] %s", header->TypeNameFormat, TypeNameFormat_s[header->TypeNameFormat]); + PrintAndLogEx(SUCCESS, "\tMessage Begin: %s", STRBOOL(header->MessageBegin)); + PrintAndLogEx(SUCCESS, "\tMessage End: %s", STRBOOL(header->MessageEnd)); + PrintAndLogEx(SUCCESS, "\tChunk Flag: %s", STRBOOL(header->ChunkFlag)); + PrintAndLogEx(SUCCESS, "\tShort Record Bit: %s", STRBOOL(header->ShortRecordBit)); + PrintAndLogEx(SUCCESS, "\tID Len Present: %s", STRBOOL(header->IDLenPresent)); + PrintAndLogEx(SUCCESS, "\tType Name Format: [0x%02x] %s", header->TypeNameFormat, TypeNameFormat_s[header->TypeNameFormat]); - PrintAndLogEx(NORMAL, "\tHeader length : %zu", header->len); - PrintAndLogEx(NORMAL, "\tType length : %zu", header->TypeLen); - PrintAndLogEx(NORMAL, "\tPayload length : %zu", header->PayloadLen); - PrintAndLogEx(NORMAL, "\tID length : %zu", header->IDLen); - PrintAndLogEx(NORMAL, "\tRecord length : %zu", header->RecLen); + PrintAndLogEx(SUCCESS, "\tHeader length : %zu", header->len); + PrintAndLogEx(SUCCESS, "\tType length : %zu", header->TypeLen); + PrintAndLogEx(SUCCESS, "\tPayload length : %zu", header->PayloadLen); + PrintAndLogEx(SUCCESS, "\tID length : %zu", header->IDLen); + PrintAndLogEx(SUCCESS, "\tRecord length : %zu", header->RecLen); return PM3_SUCCESS; } @@ -166,8 +166,8 @@ static int ndefDecodeSig1(uint8_t *sig, size_t siglen) { uint8_t sigType = sig[indx] & 0x7f; bool sigURI = sig[indx] & 0x80; - PrintAndLogEx(NORMAL, "\tsignature type: %s", ((sigType < stNA) ? ndefSigType_s[sigType] : ndefSigType_s[stNA])); - PrintAndLogEx(NORMAL, "\tsignature uri: %s", (sigURI ? "present" : "not present")); + PrintAndLogEx(SUCCESS, "\tsignature type: %s", ((sigType < stNA) ? ndefSigType_s[sigType] : ndefSigType_s[stNA])); + PrintAndLogEx(SUCCESS, "\tsignature uri: %s", (sigURI ? "present" : "not present")); size_t intsiglen = (sig[indx + 1] << 8) + sig[indx + 2]; // ecdsa 0x04 @@ -176,14 +176,14 @@ static int ndefDecodeSig1(uint8_t *sig, size_t siglen) { int slen = 24; if (sigType == stECDSA_P256) slen = 32; - PrintAndLogEx(NORMAL, "\tsignature [%zu]: %s", intsiglen, sprint_hex_inrow(&sig[indx], intsiglen)); + PrintAndLogEx(SUCCESS, "\tsignature [%zu]: %s", intsiglen, sprint_hex_inrow(&sig[indx], intsiglen)); uint8_t rval[300] = {0}; uint8_t sval[300] = {0}; int res = ecdsa_asn1_get_signature(&sig[indx], intsiglen, rval, sval); if (!res) { - PrintAndLogEx(NORMAL, "\t\tr: %s", sprint_hex(rval + 32 - slen, slen)); - PrintAndLogEx(NORMAL, "\t\ts: %s", sprint_hex(sval + 32 - slen, slen)); + PrintAndLogEx(SUCCESS, "\t\tr: %s", sprint_hex(rval + 32 - slen, slen)); + PrintAndLogEx(SUCCESS, "\t\ts: %s", sprint_hex(sval + 32 - slen, slen)); } } indx += intsiglen; @@ -191,7 +191,7 @@ static int ndefDecodeSig1(uint8_t *sig, size_t siglen) { if (sigURI) { size_t intsigurilen = (sig[indx] << 8) + sig[indx + 1]; indx += 2; - PrintAndLogEx(NORMAL, "\tsignature uri [%zu]: %.*s", intsigurilen, (int)intsigurilen, &sig[indx]); + PrintAndLogEx(SUCCESS, "\tsignature uri [%zu]: %.*s", intsigurilen, (int)intsigurilen, &sig[indx]); indx += intsigurilen; } @@ -199,8 +199,8 @@ static int ndefDecodeSig1(uint8_t *sig, size_t siglen) { uint8_t certCount = sig[indx] & 0x0f; bool certURI = sig[indx] & 0x80; - PrintAndLogEx(NORMAL, "\tcertificate format: %s", ((certFormat < sfNA) ? ndefCertificateFormat_s[certFormat] : ndefCertificateFormat_s[sfNA])); - PrintAndLogEx(NORMAL, "\tcertificates count: %d", certCount); + PrintAndLogEx(SUCCESS, "\tcertificate format: %s", ((certFormat < sfNA) ? ndefCertificateFormat_s[certFormat] : ndefCertificateFormat_s[sfNA])); + PrintAndLogEx(SUCCESS, "\tcertificates count: %d", certCount); // print certificates indx++; @@ -208,7 +208,7 @@ static int ndefDecodeSig1(uint8_t *sig, size_t siglen) { size_t intcertlen = (sig[indx + 1] << 8) + sig[indx + 2]; indx += 2; - PrintAndLogEx(NORMAL, "\tcertificate %d [%zu]: %s", i + 1, intcertlen, sprint_hex_inrow(&sig[indx], intcertlen)); + PrintAndLogEx(SUCCESS, "\tcertificate %d [%zu]: %s", i + 1, intcertlen, sprint_hex_inrow(&sig[indx], intcertlen)); indx += intcertlen; } @@ -216,7 +216,7 @@ static int ndefDecodeSig1(uint8_t *sig, size_t siglen) { if ((indx <= siglen) && certURI) { size_t inturilen = (sig[indx] << 8) + sig[indx + 1]; indx += 2; - PrintAndLogEx(NORMAL, "\tcertificate uri [%zu]: %.*s", inturilen, (int)inturilen, &sig[indx]); + PrintAndLogEx(SUCCESS, "\tcertificate uri [%zu]: %.*s", inturilen, (int)inturilen, &sig[indx]); } return PM3_SUCCESS; @@ -233,29 +233,28 @@ static int ndefDecodeSig2(uint8_t *sig, size_t siglen) { uint8_t hashType = sig[indx]; indx++; - PrintAndLogEx(NORMAL, "\tsignature type: %s", ((sigType < stNA) ? ndefSigType_s[sigType] : ndefSigType_s[stNA])); - PrintAndLogEx(NORMAL, "\tsignature uri: %s", (sigURI ? "present" : "not present")); - PrintAndLogEx(NORMAL, "\thash type: %s", ((hashType == 0x02) ? "SHA-256" : "unknown")); + PrintAndLogEx(SUCCESS, "\tsignature type :\t" _GREEN_("%s"), ((sigType < stNA) ? ndefSigType_s[sigType] : ndefSigType_s[stNA])); + PrintAndLogEx(SUCCESS, "\tsignature uri :\t\t%s", (sigURI ? "present" : "not present")); + PrintAndLogEx(SUCCESS, "\thash type :\t\t%s", ((hashType == 0x02) ? _GREEN_("SHA-256") : _RED_("unknown"))); size_t intsiglen = (sig[indx] << 8) + sig[indx + 1]; indx += 2; - + if (sigURI) { indx += 2; - PrintAndLogEx(NORMAL, "\tsignature uri [%zu]: %.*s", intsiglen, (int)intsiglen, &sig[indx]); + PrintAndLogEx(SUCCESS, "\tsignature uri [%zu]: %.*s", intsiglen, (int)intsiglen, &sig[indx]); indx += intsiglen; } else { - PrintAndLogEx(NORMAL, "\tsignature [%zu]: %s", intsiglen, sprint_hex_inrow(&sig[indx], intsiglen)); + PrintAndLogEx(SUCCESS, "\tsignature [%zu]: %s", intsiglen, sprint_hex_inrow(&sig[indx], intsiglen)); if (sigType == stECDSA_P192 || sigType == stECDSA_P256) { int slen = intsiglen / 2; if (slen == 24 || slen == 32) { - PrintAndLogEx(NORMAL, "\tsignature: ECDSA-%d", slen * 8); - PrintAndLogEx(NORMAL, "\t\tr: %s", sprint_hex(&sig[indx], slen)); - indx += slen; - PrintAndLogEx(NORMAL, "\t\ts: %s", sprint_hex(&sig[indx], slen)); + PrintAndLogEx(SUCCESS, "\tsignature : " _GREEN_("ECDSA-%d"), slen * 8); + PrintAndLogEx(SUCCESS, "\t\tr: %s", sprint_hex(&sig[indx], slen)); + PrintAndLogEx(SUCCESS, "\t\ts: %s", sprint_hex(&sig[indx + slen], slen)); } } else { - PrintAndLogEx(NORMAL, "\tsignature: unknown type"); + PrintAndLogEx(INFO, "\tsignature: unknown type"); } indx += intsiglen; } @@ -264,8 +263,8 @@ static int ndefDecodeSig2(uint8_t *sig, size_t siglen) { uint8_t certCount = sig[indx] & 0x0f; bool certURI = sig[indx] & 0x80; - PrintAndLogEx(NORMAL, "\tcertificate format: %s", ((certFormat < sfNA) ? ndefCertificateFormat_s[certFormat] : ndefCertificateFormat_s[sfNA])); - PrintAndLogEx(NORMAL, "\tcertificates count: %d", certCount); + PrintAndLogEx(SUCCESS, "\tcertificate format : " _GREEN_("%s"), ((certFormat < sfNA) ? ndefCertificateFormat_s[certFormat] : ndefCertificateFormat_s[sfNA])); + PrintAndLogEx(SUCCESS, "\tcertificates count : %d", certCount); // print certificates indx++; @@ -273,7 +272,7 @@ static int ndefDecodeSig2(uint8_t *sig, size_t siglen) { size_t intcertlen = (sig[indx + 1] << 8) + sig[indx + 2]; indx += 2; - PrintAndLogEx(NORMAL, "\tcertificate %d [%zu]: %s", i + 1, intcertlen, sprint_hex_inrow(&sig[indx], intcertlen)); + PrintAndLogEx(SUCCESS, "\tcertificate %d [%zu]: %s", i + 1, intcertlen, sprint_hex_inrow(&sig[indx], intcertlen)); indx += intcertlen; } @@ -281,14 +280,14 @@ static int ndefDecodeSig2(uint8_t *sig, size_t siglen) { if ((indx <= siglen) && certURI) { size_t inturilen = (sig[indx] << 8) + sig[indx + 1]; indx += 2; - PrintAndLogEx(NORMAL, "\tcertificate uri [%zu]: %.*s", inturilen, (int)inturilen, &sig[indx]); + PrintAndLogEx(SUCCESS, "\tcertificate uri [%zu]: %.*s", inturilen, (int)inturilen, &sig[indx]); } return PM3_SUCCESS; }; static int ndefDecodeSig(uint8_t *sig, size_t siglen) { - PrintAndLogEx(NORMAL, "\tsignature version: 0x%02x", sig[0]); + PrintAndLogEx(SUCCESS, "\tsignature version : \t" _GREEN_("0x%02x"), sig[0]); if (sig[0] != 0x01 && sig[0] != 0x20) { PrintAndLogEx(ERR, "signature version unknown."); return PM3_ESOFT; From f0ffe79569d1ae31d03a430db429da7de5dd5ef2 Mon Sep 17 00:00:00 2001 From: Daniel Underhay <27876907+dunderhay@users.noreply.github.com> Date: Fri, 3 Apr 2020 00:14:15 +1100 Subject: [PATCH 1825/1854] Add colour to hf mf chk and fchk output --- CHANGELOG.md | 1 + client/cmdhfmf.c | 51 +++++++++++++++++++------------------- client/mifare/mifarehost.c | 2 +- 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0bb2efbf7..9091fd4ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Add colour to `hf mf chk` and `hf mf fchk` (@dunderhay) - Change - updated public keys info (@anon) - Change - mfc default keys removed dublicates (@iceman1001) . Change - mfc default keys got new entries found on TagInfo app (@anon) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 89519b282..1a3c86972 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -248,10 +248,10 @@ static int usage_hf14_chk(void) { PrintAndLogEx(NORMAL, " t write keys to emulator memory\n"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf mf chk 0 A 1234567890ab -- target block 0, Key A using key 1234567890ab"); - PrintAndLogEx(NORMAL, " hf mf chk 0 A mfc_default_keys.dic -- target block 0, Key A using default dictionary file"); - PrintAndLogEx(NORMAL, " hf mf chk *1 ? t -- target all blocks, all keys, 1K, write to emulator memory"); - PrintAndLogEx(NORMAL, " hf mf chk *1 ? d -- target all blocks, all keys, 1K, write to file"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf chk 0 A 1234567890ab")" -- target block 0, Key A using key 1234567890ab"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf chk 0 A mfc_default_keys.dic")" -- target block 0, Key A using default dictionary file"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf chk *1 ? t")" -- target all blocks, all keys, 1K, write to emulator memory"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf chk *1 ? d")" -- target all blocks, all keys, 1K, write to file"); return PM3_SUCCESS; } static int usage_hf14_chk_fast(void) { @@ -269,12 +269,12 @@ static int usage_hf14_chk_fast(void) { PrintAndLogEx(NORMAL, " m use dictionary from flashmemory\n"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf mf fchk 1 1234567890ab -- target 1K using key 1234567890ab"); - PrintAndLogEx(NORMAL, " hf mf fchk 1 mfc_default_keys.dic -- target 1K using default dictionary file"); - PrintAndLogEx(NORMAL, " hf mf fchk 1 t -- target 1K, write to emulator memory"); - PrintAndLogEx(NORMAL, " hf mf fchk 1 d -- target 1K, write to file"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf fchk 1 1234567890ab")" -- target 1K using key 1234567890ab"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf fchk 1 mfc_default_keys.dic")" -- target 1K using default dictionary file"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf fchk 1 t")" -- target 1K, write to emulator memory"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf fchk 1 d")" -- target 1K, write to file"); if (IfPm3Flash()) - PrintAndLogEx(NORMAL, " hf mf fchk 1 m -- target 1K, use dictionary from flashmemory"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf fchk 1 m")" -- target 1K, use dictionary from flashmemory"); return PM3_SUCCESS; } /* @@ -1447,7 +1447,7 @@ static int CmdHF14AMfNested(const char *Cmd) { jumptoend: PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(INFO, "found keys:"); + PrintAndLogEx(SUCCESS, _GREEN_("found keys:")); //print them printKeyTable(SectorsCnt, e_sector); @@ -1652,7 +1652,7 @@ static int CmdHF14AMfNestedStatic(const char *Cmd) { jumptoend: PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(INFO, "found keys:"); + PrintAndLogEx(SUCCESS, _GREEN_("found keys:")); //print them printKeyTable(SectorsCnt, e_sector); @@ -2463,7 +2463,7 @@ all_found: // Show the results to the user PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(INFO, "found keys:"); + PrintAndLogEx(SUCCESS, _GREEN_("found keys:")); printKeyTable(sectors_cnt, e_sector); @@ -2715,7 +2715,7 @@ static int CmdHF14AMfChk_fast(const char *Cmd) { // strategys. 1= deep first on sector 0 AB, 2= width first on all sectors for (uint8_t strategy = 1; strategy < 3; strategy++) { - PrintAndLogEx(SUCCESS, "Running strategy %u", strategy); + PrintAndLogEx(INFO, "Running strategy %u", strategy); // main keychunk loop for (i = 0; i < keycnt; i += chunksize) { @@ -2746,7 +2746,7 @@ static int CmdHF14AMfChk_fast(const char *Cmd) { } out: t1 = msclock() - t1; - PrintAndLogEx(SUCCESS, "Time in checkkeys (fast): %.1fs\n", (float)(t1 / 1000.0)); + PrintAndLogEx(INFO, "Time in checkkeys (fast): %.1fs\n", (float)(t1 / 1000.0)); // check.. uint8_t found_keys = 0; @@ -2764,7 +2764,7 @@ out: } else { PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(INFO, "found keys:"); + PrintAndLogEx(SUCCESS, _GREEN_("found keys:")); printKeyTable(sectorsCnt, e_sector); @@ -3027,7 +3027,7 @@ static int CmdHF14AMfChk(const char *Cmd) { } } t1 = msclock() - t1; - PrintAndLogEx(SUCCESS, "\nTime in checkkeys: %.0f seconds\n", (float)t1 / 1000.0); + PrintAndLogEx(INFO, "\nTime in checkkeys: %.0f seconds\n", (float)t1 / 1000.0); // 20160116 If Sector A is found, but not Sector B, try just reading it of the tag? @@ -3075,7 +3075,7 @@ static int CmdHF14AMfChk(const char *Cmd) { out: PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(INFO, "found keys:"); + PrintAndLogEx(SUCCESS, _GREEN_("found keys:")); //print keys if (SectorsCnt == 1) @@ -3346,7 +3346,7 @@ static int CmdHF14AMfSim(const char *Cmd) { } showSectorTable(); } - + k_sectorsCount = MIFARE_4K_MAXSECTOR; return PM3_SUCCESS; } @@ -3549,9 +3549,9 @@ void printKeyTable(uint8_t sectorscnt, sector_t *e_sector) { void printKeyTableEx(uint8_t sectorscnt, sector_t *e_sector, uint8_t start_sector) { char strA[12 + 1] = {0}; char strB[12 + 1] = {0}; - PrintAndLogEx(NORMAL, "|---|----------------|---|----------------|---|"); - PrintAndLogEx(NORMAL, "|sec| key A |res| key B |res|"); - PrintAndLogEx(NORMAL, "|---|----------------|---|----------------|---|"); + PrintAndLogEx(SUCCESS, "|-----|----------------|---|----------------|---|"); + PrintAndLogEx(SUCCESS, "| Sec | key A |res| key B |res|"); + PrintAndLogEx(SUCCESS, "|-----|----------------|---|----------------|---|"); for (uint8_t i = 0; i < sectorscnt; i++) { snprintf(strA, sizeof(strA), "------------"); @@ -3564,7 +3564,7 @@ void printKeyTableEx(uint8_t sectorscnt, sector_t *e_sector, uint8_t start_secto snprintf(strB, sizeof(strB), "%012" PRIx64, e_sector[i].Key[1]); if (e_sector[i].foundKey[0] > 1) { - PrintAndLogEx(NORMAL, "|%03d| %s | " _YELLOW_("%c")"| %s | " _YELLOW_("%c")"|" + PrintAndLogEx(SUCCESS, "| "_YELLOW_("%03d")"| " _GREEN_("%s")" | " _YELLOW_("%c")"| " _GREEN_("%s")" | " _YELLOW_("%c")"|" , i , strA, e_sector[i].foundKey[0] , strB, e_sector[i].foundKey[1] @@ -3576,14 +3576,14 @@ void printKeyTableEx(uint8_t sectorscnt, sector_t *e_sector, uint8_t start_secto if (start_sector == 0) s = i; - PrintAndLogEx(NORMAL, "|%03d| %s | " _YELLOW_("%d")"| %s | " _YELLOW_("%d")"|" + PrintAndLogEx(SUCCESS, "| "_YELLOW_("%03d")"| " _GREEN_("%s")" | " _YELLOW_("%d")"| " _GREEN_("%s")" | " _YELLOW_("%d")"|" , s , strA, e_sector[i].foundKey[0] , strB, e_sector[i].foundKey[1] ); } } - PrintAndLogEx(NORMAL, "|---|----------------|---|----------------|---|"); + PrintAndLogEx(SUCCESS, "|-----|----------------|---|----------------|---|"); if (e_sector[0].foundKey[0] > 1) { PrintAndLogEx(INFO, "( " @@ -3597,7 +3597,7 @@ void printKeyTableEx(uint8_t sectorscnt, sector_t *e_sector, uint8_t start_secto ")" ); } else { - PrintAndLogEx(INFO, "( " _YELLOW_("0") ":Failed / " _YELLOW_("1") ":Success)"); + PrintAndLogEx(SUCCESS, "( " _YELLOW_("0") ":Failed / " _YELLOW_("1") ":Success)"); } } @@ -4955,4 +4955,3 @@ int CmdHFMF(const char *Cmd) { clearCommandBuffer(); return CmdsParse(CommandTable, Cmd); } - diff --git a/client/mifare/mifarehost.c b/client/mifare/mifarehost.c index 9d1293b5b..1d19a7c6d 100644 --- a/client/mifare/mifarehost.c +++ b/client/mifare/mifarehost.c @@ -221,7 +221,7 @@ int mfCheckKeys_fast(uint8_t sectorsCnt, uint8_t firstChunk, uint8_t lastChunk, // time to convert the returned data. uint8_t curr_keys = resp.oldarg[0]; - PrintAndLogEx(SUCCESS, "\nChunk: %.1fs | found %u/%u keys (%u)", (float)(t2 / 1000.0), curr_keys, (sectorsCnt << 1), size); + PrintAndLogEx(INFO, "\nChunk: %.1fs | found %u/%u keys (%u)", (float)(t2 / 1000.0), curr_keys, (sectorsCnt << 1), size); // all keys? if (curr_keys == sectorsCnt * 2 || lastChunk) { From e64e5fb65c15102123b68fec463f8ff98cf55477 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Thu, 2 Apr 2020 18:42:44 +0300 Subject: [PATCH 1826/1854] added some ndef tlv types --- client/mifare/ndef.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/client/mifare/ndef.c b/client/mifare/ndef.c index 8f5e93a2e..b7c4a8108 100644 --- a/client/mifare/ndef.c +++ b/client/mifare/ndef.c @@ -422,6 +422,7 @@ int NDEFRecordsDecodeAndPrint(uint8_t *ndefRecord, size_t ndefRecordLen) { return PM3_SUCCESS; } +// http://apps4android.org/nfc-specifications/NFCForum-TS-Type-2-Tag_1.1.pdf int NDEFDecodeAndPrint(uint8_t *ndef, size_t ndefLen, bool verbose) { size_t indx = 0; @@ -442,6 +443,24 @@ int NDEFDecodeAndPrint(uint8_t *ndef, size_t ndefLen, bool verbose) { indx += len; break; } + case 0x01: { + indx++; + uint16_t len = ndefTLVGetLength(&ndef[indx], &indx); + PrintAndLogEx(INFO, "-- NDEF Lock Control."); + if (len != 3) + PrintAndLogEx(WARNING, "NDEF Lock Control block size must be 3 instead of %d.", len); + indx += len; + break; + } + case 0x02: { + indx++; + uint16_t len = ndefTLVGetLength(&ndef[indx], &indx); + PrintAndLogEx(INFO, "-- NDEF Memory Control."); + if (len != 3) + PrintAndLogEx(WARNING, "NDEF Memory Control block size must be 3 instead of %d.", len); + indx += len; + break; + } case 0x03: { indx++; uint16_t len = ndefTLVGetLength(&ndef[indx], &indx); From 627499247f37c4a7df03673e539bc566d1ccbd65 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Thu, 2 Apr 2020 20:21:51 +0300 Subject: [PATCH 1827/1854] TLV ndef lock and memory control decoding --- client/mifare/ndef.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/client/mifare/ndef.c b/client/mifare/ndef.c index b7c4a8108..8974334eb 100644 --- a/client/mifare/ndef.c +++ b/client/mifare/ndef.c @@ -447,8 +447,20 @@ int NDEFDecodeAndPrint(uint8_t *ndef, size_t ndefLen, bool verbose) { indx++; uint16_t len = ndefTLVGetLength(&ndef[indx], &indx); PrintAndLogEx(INFO, "-- NDEF Lock Control."); - if (len != 3) + if (len != 3) { PrintAndLogEx(WARNING, "NDEF Lock Control block size must be 3 instead of %d.", len); + } else { + uint8_t ByteOffset = (ndef[indx] >> 4) & 0x0f; + uint8_t PagesAddr = ndef[indx] & 0x0f; + uint8_t Size = ndef[indx + 1]; + uint8_t BytesPerPage = (ndef[indx + 2] >> 4) & 0x0f; + uint8_t BytesLockedPerLockBit = ndef[indx + 2] & 0x0f; + PrintAndLogEx(SUCCESS, "PagesAddr. number of pages: %d", PagesAddr); + PrintAndLogEx(SUCCESS, "ByteOffset. number of bytes: %d", ByteOffset); + PrintAndLogEx(SUCCESS, "Size. size in bits of the lock area: %d. bytes approx: %d", Size, Size / 8); + PrintAndLogEx(SUCCESS, "BytesPerPage. number of bytes per page: %d", BytesPerPage); + PrintAndLogEx(SUCCESS, "BytesLockedPerLockBit. number of bytes that each dynamic lock bit is able to lock: %d", BytesLockedPerLockBit); + } indx += len; break; } @@ -456,8 +468,18 @@ int NDEFDecodeAndPrint(uint8_t *ndef, size_t ndefLen, bool verbose) { indx++; uint16_t len = ndefTLVGetLength(&ndef[indx], &indx); PrintAndLogEx(INFO, "-- NDEF Memory Control."); - if (len != 3) + if (len != 3) { PrintAndLogEx(WARNING, "NDEF Memory Control block size must be 3 instead of %d.", len); + } else { + uint8_t PagesAddr = (ndef[indx] >> 4) & 0x0f; + uint8_t ByteOffset = ndef[indx] & 0x0f; + uint8_t Size = ndef[indx + 1]; + uint8_t BytesPerPage = (ndef[indx + 2] >> 4) & 0x0f; + PrintAndLogEx(SUCCESS, "PagesAddr. number of pages: %d", PagesAddr); + PrintAndLogEx(SUCCESS, "ByteOffset. number of bytes: %d", ByteOffset); + PrintAndLogEx(SUCCESS, "Size. size in bits of the reserved area: %d. bytes approx: %d", Size, Size / 8); + PrintAndLogEx(SUCCESS, "BytesPerPage. number of bytes per page: %d", BytesPerPage); + } indx += len; break; } From 13d3b38eee9710f7730610db786951a1bc6e92a9 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Thu, 2 Apr 2020 20:26:46 +0300 Subject: [PATCH 1828/1854] byte order according to http://apps4android.org/nfc-specifications/NFCForum-TS-Type-2-Tag_1.1.pdf page 10, sample: page 31 --- client/mifare/ndef.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/client/mifare/ndef.c b/client/mifare/ndef.c index 8974334eb..a563e9fd5 100644 --- a/client/mifare/ndef.c +++ b/client/mifare/ndef.c @@ -450,11 +450,11 @@ int NDEFDecodeAndPrint(uint8_t *ndef, size_t ndefLen, bool verbose) { if (len != 3) { PrintAndLogEx(WARNING, "NDEF Lock Control block size must be 3 instead of %d.", len); } else { - uint8_t ByteOffset = (ndef[indx] >> 4) & 0x0f; - uint8_t PagesAddr = ndef[indx] & 0x0f; + uint8_t PagesAddr = (ndef[indx] >> 4) & 0x0f; + uint8_t ByteOffset = ndef[indx] & 0x0f; uint8_t Size = ndef[indx + 1]; - uint8_t BytesPerPage = (ndef[indx + 2] >> 4) & 0x0f; - uint8_t BytesLockedPerLockBit = ndef[indx + 2] & 0x0f; + uint8_t BytesLockedPerLockBit = (ndef[indx + 2] >> 4) & 0x0f; + uint8_t BytesPerPage = ndef[indx + 2] & 0x0f; PrintAndLogEx(SUCCESS, "PagesAddr. number of pages: %d", PagesAddr); PrintAndLogEx(SUCCESS, "ByteOffset. number of bytes: %d", ByteOffset); PrintAndLogEx(SUCCESS, "Size. size in bits of the lock area: %d. bytes approx: %d", Size, Size / 8); @@ -474,7 +474,7 @@ int NDEFDecodeAndPrint(uint8_t *ndef, size_t ndefLen, bool verbose) { uint8_t PagesAddr = (ndef[indx] >> 4) & 0x0f; uint8_t ByteOffset = ndef[indx] & 0x0f; uint8_t Size = ndef[indx + 1]; - uint8_t BytesPerPage = (ndef[indx + 2] >> 4) & 0x0f; + uint8_t BytesPerPage = ndef[indx + 2] & 0x0f; PrintAndLogEx(SUCCESS, "PagesAddr. number of pages: %d", PagesAddr); PrintAndLogEx(SUCCESS, "ByteOffset. number of bytes: %d", ByteOffset); PrintAndLogEx(SUCCESS, "Size. size in bits of the reserved area: %d. bytes approx: %d", Size, Size / 8); From 4418281284656c4811da7f296ae385221582f20d Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 2 Apr 2020 21:16:28 +0200 Subject: [PATCH 1829/1854] chg: 'hf mfu ndef' - text record now correctly decode language and text parts. Thanks @bettse! --- client/mifare/ndef.c | 43 +++++++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/client/mifare/ndef.c b/client/mifare/ndef.c index a563e9fd5..996d8d767 100644 --- a/client/mifare/ndef.c +++ b/client/mifare/ndef.c @@ -45,7 +45,6 @@ static const char *ndefSigType_s[] = { "ECDSA-B233", "ECDSA-P256", "n/a" - }; static const char *ndefCertificateFormat_s[] = { @@ -229,7 +228,7 @@ static int ndefDecodeSig2(uint8_t *sig, size_t siglen) { uint8_t sigType = sig[indx] & 0x7f; bool sigURI = sig[indx] & 0x80; indx++; - + uint8_t hashType = sig[indx]; indx++; @@ -292,13 +291,13 @@ static int ndefDecodeSig(uint8_t *sig, size_t siglen) { PrintAndLogEx(ERR, "signature version unknown."); return PM3_ESOFT; } - + if (sig[0] == 0x01) return ndefDecodeSig1(sig, siglen); - + if (sig[0] == 0x20) return ndefDecodeSig2(sig, siglen); - + return PM3_ESOFT; } @@ -307,15 +306,24 @@ static int ndefDecodePayload(NDEFHeader_t *ndef) { switch (ndef->TypeNameFormat) { case tnfWellKnownRecord: PrintAndLogEx(INFO, "Well Known Record"); - PrintAndLogEx(INFO, "\ttype : %.*s", (int)ndef->TypeLen, ndef->Type); + PrintAndLogEx(INFO, "\ttype\t: %.*s", (int)ndef->TypeLen, ndef->Type); if (!strncmp((char *)ndef->Type, "T", ndef->TypeLen)) { - PrintAndLogEx(INFO, "\ttext : " _GREEN_("%.*s"), (int)ndef->PayloadLen, ndef->Payload); + uint8_t utf8 = (ndef->Payload[0] >> 7); + uint8_t lc_len = ndef->Payload[0] & 0x3F; + PrintAndLogEx(INFO, + "\tUTF %d\t: " _GREEN_("%.*s") ", " _GREEN_("%.*s"), + (utf8 == 0) ? 8 : 16, + lc_len, + ndef->Payload + 1, + (int)ndef->PayloadLen - 1 - lc_len, + ndef->Payload + 1 + lc_len + ); } if (!strncmp((char *)ndef->Type, "U", ndef->TypeLen)) { PrintAndLogEx(INFO - , "\turi : " _GREEN_("%s%.*s") + , "\turi\t: " _GREEN_("%s%.*s") , (ndef->Payload[0] <= 0x23 ? URI_s[ndef->Payload[0]] : "[err]") , (int)(ndef->PayloadLen - 1) , &ndef->Payload[1] @@ -436,7 +444,6 @@ int NDEFDecodeAndPrint(uint8_t *ndef, size_t ndefLen, bool verbose) { case 0x00: { indx++; uint16_t len = ndefTLVGetLength(&ndef[indx], &indx); - PrintAndLogEx(SUCCESS, "-- NDEF NULL block."); if (len) PrintAndLogEx(WARNING, "NDEF NULL block size must be 0, got %d bytes", len); @@ -455,11 +462,11 @@ int NDEFDecodeAndPrint(uint8_t *ndef, size_t ndefLen, bool verbose) { uint8_t Size = ndef[indx + 1]; uint8_t BytesLockedPerLockBit = (ndef[indx + 2] >> 4) & 0x0f; uint8_t BytesPerPage = ndef[indx + 2] & 0x0f; - PrintAndLogEx(SUCCESS, "PagesAddr. number of pages: %d", PagesAddr); - PrintAndLogEx(SUCCESS, "ByteOffset. number of bytes: %d", ByteOffset); - PrintAndLogEx(SUCCESS, "Size. size in bits of the lock area: %d. bytes approx: %d", Size, Size / 8); - PrintAndLogEx(SUCCESS, "BytesPerPage. number of bytes per page: %d", BytesPerPage); - PrintAndLogEx(SUCCESS, "BytesLockedPerLockBit. number of bytes that each dynamic lock bit is able to lock: %d", BytesLockedPerLockBit); + PrintAndLogEx(SUCCESS, "PagesAddr. number of pages: %d", PagesAddr); + PrintAndLogEx(SUCCESS, "ByteOffset. number of bytes: %d", ByteOffset); + PrintAndLogEx(SUCCESS, "Size. size in bits of the lock area: %d. bytes approx: %d", Size, Size / 8); + PrintAndLogEx(SUCCESS, "BytesPerPage. number of bytes per page: %d", BytesPerPage); + PrintAndLogEx(SUCCESS, "BytesLockedPerLockBit. number of bytes that each dynamic lock bit is able to lock: %d", BytesLockedPerLockBit); } indx += len; break; @@ -475,10 +482,10 @@ int NDEFDecodeAndPrint(uint8_t *ndef, size_t ndefLen, bool verbose) { uint8_t ByteOffset = ndef[indx] & 0x0f; uint8_t Size = ndef[indx + 1]; uint8_t BytesPerPage = ndef[indx + 2] & 0x0f; - PrintAndLogEx(SUCCESS, "PagesAddr. number of pages: %d", PagesAddr); - PrintAndLogEx(SUCCESS, "ByteOffset. number of bytes: %d", ByteOffset); - PrintAndLogEx(SUCCESS, "Size. size in bits of the reserved area: %d. bytes approx: %d", Size, Size / 8); - PrintAndLogEx(SUCCESS, "BytesPerPage. number of bytes per page: %d", BytesPerPage); + PrintAndLogEx(SUCCESS, "PagesAddr. number of pages: %d", PagesAddr); + PrintAndLogEx(SUCCESS, "ByteOffset. number of bytes: %d", ByteOffset); + PrintAndLogEx(SUCCESS, "Size. size in bits of the reserved area: %d. bytes approx: %d", Size, Size / 8); + PrintAndLogEx(SUCCESS, "BytesPerPage. number of bytes per page: %d", BytesPerPage); } indx += len; break; From 3484cf165565dc84db851a49b2a06084063b5d3f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 3 Apr 2020 07:22:54 +0200 Subject: [PATCH 1830/1854] text and return codes --- client/cmdhficlass.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index f4a62b6c1..72c5d885d 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -462,7 +462,7 @@ static int CmdHFiClassSim(const char *Cmd) { PrintAndLogEx(ERR, "A CSN should consist of 16 HEX symbols"); return usage_hf_iclass_sim(); } - PrintAndLogEx(NORMAL, " simtype: %02x csn: %s", simType, sprint_hex(CSN, 8)); + PrintAndLogEx(INFO, " simtype: %02x CSN: %s", simType, sprint_hex(CSN, 8)); } if (simType > 4) { @@ -505,7 +505,7 @@ static int CmdHFiClassSim(const char *Cmd) { PrintAndLogEx(INFO, "press Enter to cancel"); PacketResponseNG resp; clearCommandBuffer(); - SendCommandOLD(CMD_HF_ICLASS_SIMULATE, simType, NUM_CSNS, 0, csns, 8 * NUM_CSNS); + SendCommandMIX(CMD_HF_ICLASS_SIMULATE, simType, NUM_CSNS, 0, csns, 8 * NUM_CSNS); while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { tries++; @@ -520,7 +520,7 @@ static int CmdHFiClassSim(const char *Cmd) { } uint8_t num_mac = resp.oldarg[1]; bool success = (NUM_CSNS == num_mac); - PrintAndLogEx(NORMAL, "[%c] %d out of %d MAC obtained [%s]", (success) ? '+' : '!', num_mac, NUM_CSNS, (success) ? "OK" : "FAIL"); + PrintAndLogEx( (success) ? SUCCESS : WARNING, "[%c] %d out of %d MAC obtained [%s]", (success) ? '+' : '!', num_mac, NUM_CSNS, (success) ? "OK" : "FAIL"); if (num_mac == 0) break; @@ -554,7 +554,7 @@ static int CmdHFiClassSim(const char *Cmd) { PrintAndLogEx(INFO, "press Enter to cancel"); PacketResponseNG resp; clearCommandBuffer(); - SendCommandOLD(CMD_HF_ICLASS_SIMULATE, simType, NUM_CSNS, 0, csns, 8 * NUM_CSNS); + SendCommandMIX(CMD_HF_ICLASS_SIMULATE, simType, NUM_CSNS, 0, csns, 8 * NUM_CSNS); while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { tries++; @@ -569,7 +569,7 @@ static int CmdHFiClassSim(const char *Cmd) { } uint8_t num_mac = resp.oldarg[1]; bool success = ((NUM_CSNS * 2) == num_mac); - PrintAndLogEx(NORMAL, "[%c] %d out of %d MAC obtained [%s]", (success) ? '+' : '!', num_mac, NUM_CSNS * 2, (success) ? "OK" : "FAIL"); + PrintAndLogEx((success) ? SUCCESS : WARNING, "[%c] %d out of %d MAC obtained [%s]", (success) ? '+' : '!', num_mac, NUM_CSNS * 2, (success) ? "OK" : "FAIL"); if (num_mac == 0) break; @@ -645,7 +645,7 @@ static int CmdHFiClassReader_Replay(const char *Cmd) { if (param_gethex(Cmd, 0, MAC, 8)) { PrintAndLogEx(FAILED, "MAC must include 8 HEX symbols"); - return 1; + return PM3_EINVARG; } clearCommandBuffer(); @@ -1269,7 +1269,7 @@ static int CmdHFiClassReader_Dump(const char *Cmd) { break; } // dump cmd switch off at device when finised. - + uint32_t blocksRead = resp.oldarg[1]; uint8_t isOK = resp.oldarg[0] & 0xff; if (!isOK && !blocksRead) { @@ -1949,21 +1949,21 @@ static int CmdHFiClassReadTagFile(const char *Cmd) { if (fsize <= 0) { PrintAndLogEx(ERR, "Error, when getting filesize"); fclose(f); - return 1; + return PM3_EFILE; } uint8_t *dump = calloc(fsize, sizeof(uint8_t)); if (!dump) { PrintAndLogEx(WARNING, "Failed to allocate memory"); fclose(f); - return 1; + return PM3_EMALLOC; } size_t bytes_read = fread(dump, 1, fsize, f); fclose(f); uint8_t *csn = dump; - PrintAndLogEx(NORMAL, "------+--+-------------------------+\n"); - PrintAndLogEx(NORMAL, "CSN |00| %s|\n", sprint_hex(csn, 8)); + PrintAndLogEx(INFO, "------+--+-------------------------+\n"); + PrintAndLogEx(INFO, "CSN |00| %s|\n", sprint_hex(csn, 8)); printIclassDumpContents(dump, startblock, endblock, bytes_read); free(dump); return PM3_SUCCESS; @@ -2087,7 +2087,7 @@ static int CmdHFiClassCalcNewKey(const char *Cmd) { uint8_t CCNR[12] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; if (!select_only(CSN, CCNR, false, true)) { DropField(); - return 0; + return PM3_ESOFT; } } @@ -2109,21 +2109,21 @@ static int loadKeys(char *filename) { if (fsize <= 0) { PrintAndLogEx(ERR, "Error, when getting filesize"); fclose(f); - return 1; + return PM3_EFILE; } uint8_t *dump = calloc(fsize, sizeof(uint8_t)); if (!dump) { PrintAndLogEx(WARNING, "Failed to allocate memory"); fclose(f); - return 1; + return PM3_EMALLOC; } size_t bytes_read = fread(dump, 1, fsize, f); fclose(f); if (bytes_read > ICLASS_KEYS_MAX * 8) { PrintAndLogEx(WARNING, "File is too long to load - bytes: %zu", bytes_read); free(dump); - return 0; + return PM3_EFILE; } uint8_t i = 0; for (; i < bytes_read / 8; i++) From 1b6164be07917fcbef5cba7d9f6bf759569aa27b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 3 Apr 2020 08:35:32 +0200 Subject: [PATCH 1831/1854] change, sprint_hex no long has an extra space in the end. This will break some output designs :smile: --- client/ui.c | 5 +++-- client/util.c | 5 ++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/client/ui.c b/client/ui.c index bac8b2956..5097b28f1 100644 --- a/client/ui.c +++ b/client/ui.c @@ -80,10 +80,11 @@ int searchHomeFilePath(char **foundpath, const char *filename, bool create_home) if ((result != 0) && create_home) { #ifdef _WIN32 - if (_mkdir(path)) { + if (_mkdir(path)) #else - if (mkdir(path, 0700)) { + if (mkdir(path, 0700)) #endif + { fprintf(stderr, "Could not create user directory %s\n", path); free(path); return PM3_EFILE; diff --git a/client/util.c b/client/util.c index 226255536..36362f83b 100644 --- a/client/util.c +++ b/client/util.c @@ -211,6 +211,9 @@ void hex_to_buffer(const uint8_t *buf, const uint8_t *hex_data, const size_t hex for (; i < minStrLen; i++, tmp += 1) sprintf(tmp, " "); + // remove last space + --tmp; + *tmp = '\0'; return; } @@ -346,7 +349,7 @@ char *sprint_hex_ascii(const uint8_t *data, const size_t len) { memset(buf, 0x00, UTIL_BUFFER_SIZE_SPRINT); size_t max_len = (len > 1010) ? 1010 : len; - snprintf(tmp, UTIL_BUFFER_SIZE_SPRINT, "%s| ", sprint_hex(data, max_len)); + snprintf(tmp, UTIL_BUFFER_SIZE_SPRINT, "%s | ", sprint_hex(data, max_len)); size_t i = 0; size_t pos = (max_len * 3) + 2; From 98553439aa5a2233bab3426e62a54ac50bdbca8b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 3 Apr 2020 08:36:55 +0200 Subject: [PATCH 1832/1854] change 'hf iclass readtagfile' - improved param handling, better helptext, f filename s startblock e endblock --- client/cmdhficlass.c | 87 +++++++++++++++++++++++++++++++------------- 1 file changed, 62 insertions(+), 25 deletions(-) diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 72c5d885d..a1a8c93b2 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -48,7 +48,7 @@ static uint8_t iClass_Key_Table[ICLASS_KEYS_MAX][8] = { }; static int usage_hf_iclass_sim(void) { - PrintAndLogEx(NORMAL, "Usage: hf iclass sim
] + +``` +pm3 --> lf hitag sniff l +``` + +It creates a file `Hitag2____collection.txt`. +Stop once you got enough pairs. + +``` +./ht2crack4 -u -n Hitag2____collection.txt [-N ] [-t
] +``` Start with -N 16 and -t 500000. If the attack fails to find the key, double the table size and try again, repeating if it still fails. -Once the key has been recovered using one of these attacks, the RFIDler can +Usage details: Next steps +------------------------- + +Once the key has been recovered using one of these attacks, the Proxmark3 can be configured to operate as a RWD and will capture tags using that key. -RFIDler: SET TAG HITAG2 -RFIDler: HITAG2-READER -Both the SNIFF-PWM and HITAG2-READER commands can be used as AUTORUN commands -for when the RFIDler is powered from a USB power supply without interaction. - -RFIDler: SET TAG HITAG2 -RFIDler: SNIFF-PWM C -RFIDler: AUTORUN SNIFF-PWM S -RFIDler: SAVE -Capture encrypted nonce and challenge response pairs. -RFIDler: SET TAG HITAG2 -RFIDler: SNIFF-PWM L - - -RFIDler: SET TAG HITAG2 -RFIDler: HITAG2-CLEARSTOREDTAGS -RFIDler: AUTORUN HITAG2-READER S -RFIDler: SAVE -Capture tags. -RFIDler: HITAG2-COUNTSTOREDTAGS -RFIDler: HITAG2-LISTSTOREDTAGS [START] [END] - - -Tags can be copied with standard RFIDler commands. - -RFIDler: SET TAG HITAG2 -RFIDler: COPY -RFIDler: VTAG -Replace original tag with a blank tag. -RFIDler: CLONE - -OR: - -RFIDler: SET TAG HITAG2 -RFIDler: SET VTAG HITAG2 -RFIDler: VWRITE 0 -RFIDler: VWRITE 1 -... -RFIDler: VWRITE 7 -RFIDler: VTAG -Place blank tag on coil. -RFIDler: CLONE - -OR: - -RFIDler: SET TAG HITAG2 -RFIDler: SET VTAG HITAG2 -RFIDler: VWRITE 0 -RFIDler: VTAG -Place blank tag on coil. -RFIDler: CLONE +**TODO** example +Tags can be copied with standard Proxmark3 commands. +**TODO** example diff --git a/tools/hitag2crack/crack2/Makefile b/tools/hitag2crack/crack2/Makefile index 3ec604530..cacb6abd1 100644 --- a/tools/hitag2crack/crack2/Makefile +++ b/tools/hitag2crack/crack2/Makefile @@ -1,24 +1,22 @@ -WARN=-Wall -INCLUDE=-I../include -CFLAGS=-c $(WARN) $(INCLUDE) +CFLAGS?=-Wall # Linux libs LIBS=-pthread -D_GNU_SOURCE # Mac libs # LIBS= all: ht2crack2buildtable.c ht2crack2search.c ht2crack2gentest.c hitagcrypto.o utilpart.o ht2crack2utils.o - cc $(WARN) -o ht2crack2buildtable ht2crack2buildtable.c hitagcrypto.o ht2crack2utils.o $(LIBS) - cc $(WARN) -o ht2crack2search ht2crack2search.c hitagcrypto.o utilpart.o ht2crack2utils.o $(LIBS) - cc $(WARN) -o ht2crack2gentest ht2crack2gentest.c hitagcrypto.o utilpart.o ht2crack2utils.o $(LIBS) + $(CC) $(CFLAGS) -o ht2crack2buildtable ht2crack2buildtable.c hitagcrypto.o ht2crack2utils.o $(LIBS) + $(CC) $(CFLAGS) -o ht2crack2search ht2crack2search.c hitagcrypto.o utilpart.o ht2crack2utils.o $(LIBS) + $(CC) $(CFLAGS) -o ht2crack2gentest ht2crack2gentest.c hitagcrypto.o utilpart.o ht2crack2utils.o $(LIBS) ht2crack2utils.o: ht2crack2utils.c ht2crack2utils.h - cc $(CFLAGS) ht2crack2utils.c + $(CC) $(CFLAGS) -c ht2crack2utils.c hitagcrypto.o: hitagcrypto.c hitagcrypto.h - cc $(CFLAGS) hitagcrypto.c + $(CC) $(CFLAGS) -c hitagcrypto.c utilpart.o: utilpart.c util.h - cc $(CFLAGS) utilpart.c + $(CC) $(CFLAGS) -c utilpart.c clean: rm -rf *.o ht2crack2buildtable ht2crack2search ht2crack2gentest diff --git a/tools/hitag2crack/crack2/readme.md b/tools/hitag2crack/crack2/README.md similarity index 97% rename from tools/hitag2crack/crack2/readme.md rename to tools/hitag2crack/crack2/README.md index dd0872260..1f922dbec 100644 --- a/tools/hitag2crack/crack2/readme.md +++ b/tools/hitag2crack/crack2/README.md @@ -15,15 +15,19 @@ Calculate DATAMAX = free RAM available / 65536, and then round down to a power o The Makefile is configured for linux. To compile on Mac, edit it and swap the LIBS= lines. +``` make clean make - +``` Run ht2crack2buildtable ----------------------- Make sure you are in a directory on a disk with at least 1.5TB of space. + +``` ./ht2crack2buildtable +``` Wait a very long time. Maybe a few days. @@ -36,19 +40,28 @@ original files. It will then exit and you'll have your shiny table. Test with ht2crack2gentests --------------------------- +``` ./ht2crack2gentests NUMBER_OF_TESTS +``` to generate NUMBER_OF_TESTS test files. These will all be named keystream.key-KEYVALUE.uid-UIDVALUE.nR-NRVALUE Test a single test with -./runtest.sh KEYSTREAMFILE +``` +./runtest.sh KEYSTREAMFILE +``` or manually with + +``` ./ht2crack2search KEYSTREAMFILE UIDVALUE NRVALUE +``` or run all tests with +``` ./runalltests.sh +``` Feel free to edit the shell scripts to find your tools. You might want to create a symbolic link to your sorted/ directory called 'sorted' to help ht2crack2seach find the @@ -63,6 +76,6 @@ Search for key in real keystream Recover 2048 bits of keystream from the target RFID tag with the RFIDler. You will have had to supply an NR value and you should know the tag's UID (you can get this using the RFIDler). +``` ./ht2crack2search KEYSTREAMFILE UIDVALUE NRVALUE - - +``` diff --git a/tools/hitag2crack/crack3/Makefile b/tools/hitag2crack/crack3/Makefile index 6f6b7b57c..04965b55f 100644 --- a/tools/hitag2crack/crack3/Makefile +++ b/tools/hitag2crack/crack3/Makefile @@ -1,17 +1,15 @@ -WARN=-Wall -INCLUDE=-I../include -CFLAGS=-c $(WARN) $(INCLUDE) +CFLAGS?=-Wall LIBS= all: ht2crack3.c ht2test.c hitagcrypto.o utilpart.o - cc $(WARN) -o ht2crack3 ht2crack3.c hitagcrypto.o utilpart.o -lpthread $(LIBS) - cc $(WARN) -o ht2test ht2test.c hitagcrypto.o utilpart.o $(LIBS) + $(CC) $(CFLAGS) -o ht2crack3 ht2crack3.c hitagcrypto.o utilpart.o -lpthread $(LIBS) + $(CC) $(CFLAGS) -o ht2test ht2test.c hitagcrypto.o utilpart.o $(LIBS) hitagcrypto.o: hitagcrypto.c hitagcrypto.h - cc $(CFLAGS) hitagcrypto.c + $(CC) $(CFLAGS) -c hitagcrypto.c utilpart.o: utilpart.c util.h - cc $(CFLAGS) utilpart.c + $(CC) $(CFLAGS) -c utilpart.c clean: rm -rf *.o ht2crack3 ht2test diff --git a/tools/hitag2crack/crack3/readme.md b/tools/hitag2crack/crack3/README.md similarity index 96% rename from tools/hitag2crack/crack3/readme.md rename to tools/hitag2crack/crack3/README.md index 4d35ad7e0..57d5d2aa8 100644 --- a/tools/hitag2crack/crack3/readme.md +++ b/tools/hitag2crack/crack3/README.md @@ -5,9 +5,10 @@ ht2crack3 Build ----- +``` make clean make - +``` Run --- @@ -17,7 +18,9 @@ encrypted nonces and challenge response values. They should be in hex with one pair per line, e.g.: 0x12345678 0x9abcdef0 +``` ./ht2crack3 UID NRARFILE +``` UID is the UID of the tag that you used to gather the nR aR values. NRARFILE is the file containing the nR aR values. @@ -31,5 +34,6 @@ are valid (for high-powered demonstrations only, really) then you can use the ht2test program to check them. It's otherwise massively pointless and a complete waste of space. +``` ./ht2test NRARFILE KEY UID - +``` diff --git a/tools/hitag2crack/crack4/Makefile b/tools/hitag2crack/crack4/Makefile index 82e7f2560..0c3e6ec3f 100644 --- a/tools/hitag2crack/crack4/Makefile +++ b/tools/hitag2crack/crack4/Makefile @@ -1,18 +1,17 @@ -WARN=-Wall -CFLAGS=-c $(WARN) $(INCLUDE) +CFLAGS?=-Wall LIBS=-lpthread all: ht2crack4.c HardwareProfile.h rfidler.h util.h utilpart.o hitagcrypto.o ht2crack2utils.o - cc $(WARN) -o ht2crack4 ht2crack4.c utilpart.o hitagcrypto.o ht2crack2utils.o $(LIBS) + $(CC) $(CFLAGS) -o ht2crack4 ht2crack4.c utilpart.o hitagcrypto.o ht2crack2utils.o $(LIBS) utilpart.o: utilpart.c util.h - cc $(CFLAGS) utilpart.c + $(CC) $(CFLAGS) -c utilpart.c hitagcrypto.o: hitagcrypto.c hitagcrypto.h - cc $(CFLAGS) hitagcrypto.c + $(CC) $(CFLAGS) -c hitagcrypto.c ht2crack2utils.o: ht2crack2utils.c ht2crack2utils.h - cc $(CFLAGS) ht2crack2utils.c + $(CC) $(CFLAGS) -c ht2crack2utils.c clean: rm -rf *.o ht2crack4 diff --git a/tools/hitag2crack/crack4/readme.md b/tools/hitag2crack/crack4/README.md similarity index 97% rename from tools/hitag2crack/crack4/readme.md rename to tools/hitag2crack/crack4/README.md index a906700b1..1a9b28f95 100644 --- a/tools/hitag2crack/crack4/readme.md +++ b/tools/hitag2crack/crack4/README.md @@ -5,9 +5,10 @@ ht2crack4 Build ----- +``` make clean make - +``` Run --- @@ -17,7 +18,9 @@ encrypted nonces and challenge response values. They should be in hex with one pair per line, e.g.: 0x12345678 0x9abcdef0 +``` ./ht2crack4 -u UID -n NRARFILE [-N nonces to use] [-t table size] +``` UID is the UID of the tag that you used to gather the nR aR values. NRARFILE is the file containing the nR aR values. From 5277a95364ef32130aa43a59f0c73e03c217d22f Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 4 Apr 2020 13:59:54 +0200 Subject: [PATCH 1851/1854] clean a bit ht2 helpers --- tools/hitag2crack/crack2/hitagcrypto.c | 115 +------------------------ tools/hitag2crack/crack2/hitagcrypto.h | 4 - tools/hitag2crack/crack3/hitagcrypto.c | 108 ----------------------- tools/hitag2crack/crack3/hitagcrypto.h | 4 - tools/hitag2crack/crack4/hitagcrypto.c | 108 ----------------------- tools/hitag2crack/crack4/hitagcrypto.h | 4 - 6 files changed, 3 insertions(+), 340 deletions(-) diff --git a/tools/hitag2crack/crack2/hitagcrypto.c b/tools/hitag2crack/crack2/hitagcrypto.c index 3c4f84bc6..47449c3e3 100644 --- a/tools/hitag2crack/crack2/hitagcrypto.c +++ b/tools/hitag2crack/crack2/hitagcrypto.c @@ -211,7 +211,7 @@ // We want the crypto functions to be as fast as possible, so optimize! // The best compiler optimization in Microchip's free XC32 edition is -O1 -//#pragma GCC optimize("O1") +#pragma GCC optimize("O1") // private, nonlinear function to generate 1 crypto bit static uint32_t hitag2_crypt(uint64_t x); @@ -228,6 +228,7 @@ static uint32_t hitag2_crypt(uint64_t x); #define pickbits1_2_1(S, A, B, C) ( ((S >> A) & 1) | ((S >> (B - 1)) & 6) | \ ((S >> (C - 3)) & 8) ) + static uint32_t hitag2_crypt(uint64_t x) { const uint32_t ht2_function4a = 0x2C79; // 0010 1100 0111 1001 const uint32_t ht2_function4b = 0x6671; // 0110 0110 0111 0001 @@ -343,8 +344,6 @@ uint32_t hitag2_nstep(Hitag_State *pstate, uint32_t steps) { if (steps == 0) return 0; -// commented out the restriction on number of steps so we can step further in one go. -// this still only returns 32 bits obviously // if (steps > 32) // steps = 32; @@ -371,112 +370,4 @@ uint32_t hitag2_nstep(Hitag_State *pstate, uint32_t steps) { } // end of crypto core, revert to default optimization level -//#pragma GCC reset_options - - -/* Test code - - Test data and below information about it comes from - http://www.mikrocontroller.net/attachment/102194/hitag2.c - Written by "I.C. Wiener 2006-2007" - - "MIKRON" = O N M I K R - Key = 4F 4E 4D 49 4B 52 - Secret 48-bit key - Serial = 49 43 57 69 - Serial number of the tag, transmitted in clear - Random = 65 6E 45 72 - Random IV, transmitted in clear - ~28~DC~80~31 = D7 23 7F CE - Authenticator value = inverted first 4 bytes of the keystream - - The code below must print out "D7 23 7F CE 8C D0 37 A9 57 49 C1 E6 48 00 8A B6". - The inverse of the first 4 bytes is sent to the tag to authenticate. - The rest is encrypted by XORing it with the subsequent keystream. - -*/ - - -/* -unsigned int hitag2_benchtest_gen32() -{ - const uint64_t key = 0x4ad292b272f2; - const uint32_t serial = 0x96eac292; - const uint32_t initvec = 0x4ea276a6; - Hitag_State state; - - // init crypto - hitag2_init(&state, key, serial, initvec); - - // benchmark: generation of 32 bit stream (excludes initialisation) - GetTimer_us(RESET); - - (void) hitag2_nstep(&state, 32); - - return GetTimer_us(NO_RESET); -} - - -unsigned int hitag2_benchtest(uint32_t count) -{ - const uint64_t key = 0x4ad292b272f2; - const uint32_t serial = 0x96eac292; - const uint32_t initvec = 0x4ea276a6; - Hitag_State state; - uint32_t i; - - // start timer - GetTimer_us(RESET); - - // benchmark: initialise crypto & generate 32 bit authentication - // adding i stops gcc optimizer moving init function call out of loop - for (i = 0; i < count; i++) { - hitag2_init(&state, key, serial, initvec + i); - (void) hitag2_nstep(&state, 32); - } - - return GetTimer_us(NO_RESET); -} - - -unsigned hitag2_verifytest() -{ - uint8_t expected[16] = { 0xD7, 0x23, 0x7F, 0xCE, 0x8C, 0xD0, 0x37, 0xA9, 0x57, 0x49, 0xC1, 0xE6, 0x48, 0x00, 0x8A, 0xB6 }; - // key = 0x4ad292b272f2 after each byte has its bit order reversed - // serial = 0x96eac292 ditto - // initvec = 0x4ea276a6 ditto - const uint64_t key = rev64 (0x524B494D4E4FUL); - const uint32_t serial = rev32 (0x69574349); - const uint32_t initvec = rev32 (0x72456E65); - - uint32_t i; - Hitag_State state; - - // initialise - hitag2_init(&state, key, serial, initvec); - - for (i = 0; i < 16; i++) { - // get 8 bits of keystream - uint8_t x = (uint8_t) hitag2_nstep(&state, 8); - uint8_t y = expected[i]; - - DEBUG_PRINTF ("%02X (%02X) \n", x, y); - if (x != y) - return 0; - } - - return 1; -} -*/ - -#ifdef UNIT_TEST - -int main(int argc, char *argv[]) { - unsigned pass = hitag2_verifytest(); - - printf("Crypto Verify test = %s\n\n", pass ? "PASS" : "FAIL"); - - if (pass) { - hitag2_benchtest(10000); - } - - return 0; -} - -#endif // UNIT_TEST +#pragma GCC reset_options diff --git a/tools/hitag2crack/crack2/hitagcrypto.h b/tools/hitag2crack/crack2/hitagcrypto.h index 46d447370..274d3d82c 100644 --- a/tools/hitag2crack/crack2/hitagcrypto.h +++ b/tools/hitag2crack/crack2/hitagcrypto.h @@ -163,9 +163,5 @@ void hitag2_init(Hitag_State *pstate, uint64_t sharedkey, uint32_t serialnum, ui uint32_t hitag2_nstep(Hitag_State *pstate, uint32_t steps); -unsigned int hitag2_benchtest_gen32(); -unsigned int hitag2_benchtest(uint32_t count); -unsigned hitag2_verifytest(); - #endif /* HITAGCRYPTO_H */ diff --git a/tools/hitag2crack/crack3/hitagcrypto.c b/tools/hitag2crack/crack3/hitagcrypto.c index 21662b43e..47449c3e3 100644 --- a/tools/hitag2crack/crack3/hitagcrypto.c +++ b/tools/hitag2crack/crack3/hitagcrypto.c @@ -371,111 +371,3 @@ uint32_t hitag2_nstep(Hitag_State *pstate, uint32_t steps) { // end of crypto core, revert to default optimization level #pragma GCC reset_options - - -/* Test code - - Test data and below information about it comes from - http://www.mikrocontroller.net/attachment/102194/hitag2.c - Written by "I.C. Wiener 2006-2007" - - "MIKRON" = O N M I K R - Key = 4F 4E 4D 49 4B 52 - Secret 48-bit key - Serial = 49 43 57 69 - Serial number of the tag, transmitted in clear - Random = 65 6E 45 72 - Random IV, transmitted in clear - ~28~DC~80~31 = D7 23 7F CE - Authenticator value = inverted first 4 bytes of the keystream - - The code below must print out "D7 23 7F CE 8C D0 37 A9 57 49 C1 E6 48 00 8A B6". - The inverse of the first 4 bytes is sent to the tag to authenticate. - The rest is encrypted by XORing it with the subsequent keystream. - -*/ - - -/* -unsigned int hitag2_benchtest_gen32() -{ - const uint64_t key = 0x4ad292b272f2; - const uint32_t serial = 0x96eac292; - const uint32_t initvec = 0x4ea276a6; - Hitag_State state; - - // init crypto - hitag2_init(&state, key, serial, initvec); - - // benchmark: generation of 32 bit stream (excludes initialisation) - GetTimer_us(RESET); - - (void) hitag2_nstep(&state, 32); - - return GetTimer_us(NO_RESET); -} - - -unsigned int hitag2_benchtest(uint32_t count) -{ - const uint64_t key = 0x4ad292b272f2; - const uint32_t serial = 0x96eac292; - const uint32_t initvec = 0x4ea276a6; - Hitag_State state; - uint32_t i; - - // start timer - GetTimer_us(RESET); - - // benchmark: initialise crypto & generate 32 bit authentication - // adding i stops gcc optimizer moving init function call out of loop - for (i = 0; i < count; i++) { - hitag2_init(&state, key, serial, initvec + i); - (void) hitag2_nstep(&state, 32); - } - - return GetTimer_us(NO_RESET); -} - - -unsigned hitag2_verifytest() -{ - uint8_t expected[16] = { 0xD7, 0x23, 0x7F, 0xCE, 0x8C, 0xD0, 0x37, 0xA9, 0x57, 0x49, 0xC1, 0xE6, 0x48, 0x00, 0x8A, 0xB6 }; - // key = 0x4ad292b272f2 after each byte has its bit order reversed - // serial = 0x96eac292 ditto - // initvec = 0x4ea276a6 ditto - const uint64_t key = rev64 (0x524B494D4E4FUL); - const uint32_t serial = rev32 (0x69574349); - const uint32_t initvec = rev32 (0x72456E65); - - uint32_t i; - Hitag_State state; - - // initialise - hitag2_init(&state, key, serial, initvec); - - for (i = 0; i < 16; i++) { - // get 8 bits of keystream - uint8_t x = (uint8_t) hitag2_nstep(&state, 8); - uint8_t y = expected[i]; - - DEBUG_PRINTF ("%02X (%02X) \n", x, y); - if (x != y) - return 0; - } - - return 1; -} -*/ - -#ifdef UNIT_TEST - -int main(int argc, char *argv[]) { - unsigned pass = hitag2_verifytest(); - - printf("Crypto Verify test = %s\n\n", pass ? "PASS" : "FAIL"); - - if (pass) { - hitag2_benchtest(10000); - } - - return 0; -} - -#endif // UNIT_TEST diff --git a/tools/hitag2crack/crack3/hitagcrypto.h b/tools/hitag2crack/crack3/hitagcrypto.h index 46d447370..274d3d82c 100644 --- a/tools/hitag2crack/crack3/hitagcrypto.h +++ b/tools/hitag2crack/crack3/hitagcrypto.h @@ -163,9 +163,5 @@ void hitag2_init(Hitag_State *pstate, uint64_t sharedkey, uint32_t serialnum, ui uint32_t hitag2_nstep(Hitag_State *pstate, uint32_t steps); -unsigned int hitag2_benchtest_gen32(); -unsigned int hitag2_benchtest(uint32_t count); -unsigned hitag2_verifytest(); - #endif /* HITAGCRYPTO_H */ diff --git a/tools/hitag2crack/crack4/hitagcrypto.c b/tools/hitag2crack/crack4/hitagcrypto.c index 21662b43e..47449c3e3 100644 --- a/tools/hitag2crack/crack4/hitagcrypto.c +++ b/tools/hitag2crack/crack4/hitagcrypto.c @@ -371,111 +371,3 @@ uint32_t hitag2_nstep(Hitag_State *pstate, uint32_t steps) { // end of crypto core, revert to default optimization level #pragma GCC reset_options - - -/* Test code - - Test data and below information about it comes from - http://www.mikrocontroller.net/attachment/102194/hitag2.c - Written by "I.C. Wiener 2006-2007" - - "MIKRON" = O N M I K R - Key = 4F 4E 4D 49 4B 52 - Secret 48-bit key - Serial = 49 43 57 69 - Serial number of the tag, transmitted in clear - Random = 65 6E 45 72 - Random IV, transmitted in clear - ~28~DC~80~31 = D7 23 7F CE - Authenticator value = inverted first 4 bytes of the keystream - - The code below must print out "D7 23 7F CE 8C D0 37 A9 57 49 C1 E6 48 00 8A B6". - The inverse of the first 4 bytes is sent to the tag to authenticate. - The rest is encrypted by XORing it with the subsequent keystream. - -*/ - - -/* -unsigned int hitag2_benchtest_gen32() -{ - const uint64_t key = 0x4ad292b272f2; - const uint32_t serial = 0x96eac292; - const uint32_t initvec = 0x4ea276a6; - Hitag_State state; - - // init crypto - hitag2_init(&state, key, serial, initvec); - - // benchmark: generation of 32 bit stream (excludes initialisation) - GetTimer_us(RESET); - - (void) hitag2_nstep(&state, 32); - - return GetTimer_us(NO_RESET); -} - - -unsigned int hitag2_benchtest(uint32_t count) -{ - const uint64_t key = 0x4ad292b272f2; - const uint32_t serial = 0x96eac292; - const uint32_t initvec = 0x4ea276a6; - Hitag_State state; - uint32_t i; - - // start timer - GetTimer_us(RESET); - - // benchmark: initialise crypto & generate 32 bit authentication - // adding i stops gcc optimizer moving init function call out of loop - for (i = 0; i < count; i++) { - hitag2_init(&state, key, serial, initvec + i); - (void) hitag2_nstep(&state, 32); - } - - return GetTimer_us(NO_RESET); -} - - -unsigned hitag2_verifytest() -{ - uint8_t expected[16] = { 0xD7, 0x23, 0x7F, 0xCE, 0x8C, 0xD0, 0x37, 0xA9, 0x57, 0x49, 0xC1, 0xE6, 0x48, 0x00, 0x8A, 0xB6 }; - // key = 0x4ad292b272f2 after each byte has its bit order reversed - // serial = 0x96eac292 ditto - // initvec = 0x4ea276a6 ditto - const uint64_t key = rev64 (0x524B494D4E4FUL); - const uint32_t serial = rev32 (0x69574349); - const uint32_t initvec = rev32 (0x72456E65); - - uint32_t i; - Hitag_State state; - - // initialise - hitag2_init(&state, key, serial, initvec); - - for (i = 0; i < 16; i++) { - // get 8 bits of keystream - uint8_t x = (uint8_t) hitag2_nstep(&state, 8); - uint8_t y = expected[i]; - - DEBUG_PRINTF ("%02X (%02X) \n", x, y); - if (x != y) - return 0; - } - - return 1; -} -*/ - -#ifdef UNIT_TEST - -int main(int argc, char *argv[]) { - unsigned pass = hitag2_verifytest(); - - printf("Crypto Verify test = %s\n\n", pass ? "PASS" : "FAIL"); - - if (pass) { - hitag2_benchtest(10000); - } - - return 0; -} - -#endif // UNIT_TEST diff --git a/tools/hitag2crack/crack4/hitagcrypto.h b/tools/hitag2crack/crack4/hitagcrypto.h index 46d447370..274d3d82c 100644 --- a/tools/hitag2crack/crack4/hitagcrypto.h +++ b/tools/hitag2crack/crack4/hitagcrypto.h @@ -163,9 +163,5 @@ void hitag2_init(Hitag_State *pstate, uint64_t sharedkey, uint32_t serialnum, ui uint32_t hitag2_nstep(Hitag_State *pstate, uint32_t steps); -unsigned int hitag2_benchtest_gen32(); -unsigned int hitag2_benchtest(uint32_t count); -unsigned hitag2_verifytest(); - #endif /* HITAGCRYPTO_H */ From 8ab297ae6a4fa1bae423f0fd11b65b845f5a9405 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 4 Apr 2020 14:03:21 +0200 Subject: [PATCH 1852/1854] add new ht2 tools, thanks to anonymous donator --- tools/hitag2crack/README.md | 50 +- tools/hitag2crack/crack5/HardwareProfile.h | 524 ++++++++++++ tools/hitag2crack/crack5/Makefile | 18 + tools/hitag2crack/crack5/README.md | 23 + tools/hitag2crack/crack5/hitagcrypto.c | 373 +++++++++ tools/hitag2crack/crack5/hitagcrypto.h | 167 ++++ tools/hitag2crack/crack5/ht2crack2utils.c | 172 ++++ tools/hitag2crack/crack5/ht2crack2utils.h | 35 + tools/hitag2crack/crack5/ht2crack5.c | 751 ++++++++++++++++++ tools/hitag2crack/crack5/rfidler.h | 412 ++++++++++ tools/hitag2crack/crack5/util.h | 147 ++++ tools/hitag2crack/crack5/utilpart.c | 180 +++++ tools/hitag2crack/crack5gpu/HardwareProfile.h | 524 ++++++++++++ tools/hitag2crack/crack5gpu/Makefile | 24 + tools/hitag2crack/crack5gpu/README.md | 27 + tools/hitag2crack/crack5gpu/hitagcrypto.c | 373 +++++++++ tools/hitag2crack/crack5gpu/hitagcrypto.h | 167 ++++ tools/hitag2crack/crack5gpu/ht2crack2utils.c | 172 ++++ tools/hitag2crack/crack5gpu/ht2crack2utils.h | 35 + tools/hitag2crack/crack5gpu/ht2crack5.c | 421 ++++++++++ .../hitag2crack/crack5gpu/ht2crack5kernel.cl | 429 ++++++++++ tools/hitag2crack/crack5gpu/rfidler.h | 412 ++++++++++ tools/hitag2crack/crack5gpu/util.h | 147 ++++ tools/hitag2crack/crack5gpu/utilpart.c | 180 +++++ 24 files changed, 5762 insertions(+), 1 deletion(-) create mode 100644 tools/hitag2crack/crack5/HardwareProfile.h create mode 100644 tools/hitag2crack/crack5/Makefile create mode 100644 tools/hitag2crack/crack5/README.md create mode 100644 tools/hitag2crack/crack5/hitagcrypto.c create mode 100644 tools/hitag2crack/crack5/hitagcrypto.h create mode 100644 tools/hitag2crack/crack5/ht2crack2utils.c create mode 100644 tools/hitag2crack/crack5/ht2crack2utils.h create mode 100644 tools/hitag2crack/crack5/ht2crack5.c create mode 100644 tools/hitag2crack/crack5/rfidler.h create mode 100644 tools/hitag2crack/crack5/util.h create mode 100644 tools/hitag2crack/crack5/utilpart.c create mode 100644 tools/hitag2crack/crack5gpu/HardwareProfile.h create mode 100644 tools/hitag2crack/crack5gpu/Makefile create mode 100644 tools/hitag2crack/crack5gpu/README.md create mode 100644 tools/hitag2crack/crack5gpu/hitagcrypto.c create mode 100644 tools/hitag2crack/crack5gpu/hitagcrypto.h create mode 100644 tools/hitag2crack/crack5gpu/ht2crack2utils.c create mode 100644 tools/hitag2crack/crack5gpu/ht2crack2utils.h create mode 100644 tools/hitag2crack/crack5gpu/ht2crack5.c create mode 100644 tools/hitag2crack/crack5gpu/ht2crack5kernel.cl create mode 100644 tools/hitag2crack/crack5gpu/rfidler.h create mode 100644 tools/hitag2crack/crack5gpu/util.h create mode 100644 tools/hitag2crack/crack5gpu/utilpart.c diff --git a/tools/hitag2crack/README.md b/tools/hitag2crack/README.md index a43d7a1fd..9f31f6d62 100644 --- a/tools/hitag2crack/README.md +++ b/tools/hitag2crack/README.md @@ -1,7 +1,10 @@ HiTag2 Cracking Suite --------------------- -Author: Kevin Sheldrake +Authors: + +* Attacks 1, 2, 3, 4 : Kevin Sheldrake +* Attacks 5, 5gpu : anonymous, based on https://github.com/factoritbv/hitag2hell by FactorIT B.V. Introduction ------------ @@ -89,6 +92,21 @@ encrypted nonces and the keystream they should produce. Each guess is then expanded by 1 bit and the process iterates, with only the best guesses taken forward to the next iteration. +Attack 5 +-------- + +Attack 5 is heavily based on the HiTag2 Hell CPU implementation from https://github.com/factoritbv/hitag2hell by FactorIT B.V., +with the following changes: + +* Main takes a UID and 2 {nR},{aR} pairs as arguments and searches for states producing the first aR sample, reconstructs the corresponding key candidates and tests them against the second nR,aR pair; +* Reuses the Hitag helping functions of the other attacks. + +Attack 5gpu +----------- + +Attack 5gpu is identical to attack 5, simply the code has been ported to OpenCL +to run on GPUs and is therefore much faster than attack 5. + Usage details: Attack 1 ----------------------- @@ -172,6 +190,36 @@ Stop once you got enough pairs. Start with -N 16 and -t 500000. If the attack fails to find the key, double the table size and try again, repeating if it still fails. +Usage details: Attack 5 +----------------------- + +Attack 5 requires two encrypted nonce and challenge +response value pairs (nR, aR) for the tag's UID. + +``` +pm3 --> lf hitag sniff +``` +Stop once you got two pairs. + +``` +$ ./ht2crack5 +``` + +Usage details: Attack 5gpu +-------------------------- + +Attack 5gpu requires two encrypted nonce and challenge +response value pairs (nR, aR) for the tag's UID. + +``` +pm3 --> lf hitag sniff +``` +Stop once you got two pairs. + +``` +$ ./ht2crack5gpu +``` + Usage details: Next steps ------------------------- diff --git a/tools/hitag2crack/crack5/HardwareProfile.h b/tools/hitag2crack/crack5/HardwareProfile.h new file mode 100644 index 000000000..bce139042 --- /dev/null +++ b/tools/hitag2crack/crack5/HardwareProfile.h @@ -0,0 +1,524 @@ +/*************************************************************************** + * A copy of the GNU GPL is appended to this file. * + * * + * This licence is based on the nmap licence, and we express our gratitude * + * for the work that went into producing it. There is no other connection * + * between RFIDler and nmap either expressed or implied. * + * * + ********************** IMPORTANT RFIDler LICENSE TERMS ******************** + * * + * * + * All references to RFIDler herein imply all it's derivatives, namely: * + * * + * o RFIDler-LF Standard * + * o RFIDler-LF Lite * + * o RFIDler-LF Nekkid * + * * + * * + * RFIDler is (C) 2013-2014 Aperture Labs Ltd. * + * * + * This program is free software; you may redistribute and/or modify it * + * under the terms of the GNU General Public License as published by the * + * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE * + * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your * + * right to use, modify, and redistribute this software under certain * + * conditions. If you wish to embed RFIDler technology into proprietary * + * software or hardware, we sell alternative licenses * + * (contact sales@aperturelabs.com). * + * * + * Note that the GPL places important restrictions on "derivative works", * + * yet it does not provide a detailed definition of that term. To avoid * + * misunderstandings, we interpret that term as broadly as copyright law * + * allows. For example, we consider an application to constitute a * + * derivative work for the purpose of this license if it does any of the * + * following with any software or content covered by this license * + * ("Covered Software"): * + * * + * o Integrates source code from Covered Software. * + * * + * o Is designed specifically to execute Covered Software and parse the * + * results (as opposed to typical shell or execution-menu apps, which will * + * execute anything you tell them to). * + * * + * o Includes Covered Software in a proprietary executable installer. The * + * installers produced by InstallShield are an example of this. Including * + * RFIDler with other software in compressed or archival form does not * + * trigger this provision, provided appropriate open source decompression * + * or de-archiving software is widely available for no charge. For the * + * purposes of this license, an installer is considered to include Covered * + * Software even if it actually retrieves a copy of Covered Software from * + * another source during runtime (such as by downloading it from the * + * Internet). * + * * + * o Links (statically or dynamically) to a library which does any of the * + * above. * + * * + * o Executes a helper program, module, or script to do any of the above. * + * * + * This list is not exclusive, but is meant to clarify our interpretation * + * of derived works with some common examples. Other people may interpret * + * the plain GPL differently, so we consider this a special exception to * + * the GPL that we apply to Covered Software. Works which meet any of * + * these conditions must conform to all of the terms of this license, * + * particularly including the GPL Section 3 requirements of providing * + * source code and allowing free redistribution of the work as a whole. * + * * + * As another special exception to the GPL terms, Aperture Labs Ltd. grants* + * permission to link the code of this program with any version of the * + * OpenSSL library which is distributed under a license identical to that * + * listed in the included docs/licenses/OpenSSL.txt file, and distribute * + * linked combinations including the two. * + * * + * Any redistribution of Covered Software, including any derived works, * + * must obey and carry forward all of the terms of this license, including * + * obeying all GPL rules and restrictions. For example, source code of * + * the whole work must be provided and free redistribution must be * + * allowed. All GPL references to "this License", are to be treated as * + * including the terms and conditions of this license text as well. * + * * + * Because this license imposes special exceptions to the GPL, Covered * + * Work may not be combined (even as part of a larger work) with plain GPL * + * software. The terms, conditions, and exceptions of this license must * + * be included as well. This license is incompatible with some other open * + * source licenses as well. In some cases we can relicense portions of * + * RFIDler or grant special permissions to use it in other open source * + * software. Please contact sales@aperturelabs.com with any such requests.* + * Similarly, we don't incorporate incompatible open source software into * + * Covered Software without special permission from the copyright holders. * + * * + * If you have any questions about the licensing restrictions on using * + * RFIDler in other works, are happy to help. As mentioned above, we also * + * offer alternative license to integrate RFIDler into proprietary * + * applications and appliances. These contracts have been sold to dozens * + * of software vendors, and generally include a perpetual license as well * + * as providing for priority support and updates. They also fund the * + * continued development of RFIDler. Please email sales@aperturelabs.com * + * for further information. * + * If you have received a written license agreement or contract for * + * Covered Software stating terms other than these, you may choose to use * + * and redistribute Covered Software under those terms instead of these. * + * * + * Source is provided to this software because we believe users have a * + * right to know exactly what a program is going to do before they run it. * + * This also allows you to audit the software for security holes (none * + * have been found so far). * + * * + * Source code also allows you to port RFIDler to new platforms, fix bugs, * + * and add new features. You are highly encouraged to send your changes * + * to the RFIDler mailing list for possible incorporation into the * + * main distribution. By sending these changes to Aperture Labs Ltd. or * + * one of the Aperture Labs Ltd. development mailing lists, or checking * + * them into the RFIDler source code repository, it is understood (unless * + * you specify otherwise) that you are offering the RFIDler Project * + * (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, * + * modify, and relicense the code. RFIDler will always be available Open * + * Source, but this is important because the inability to relicense code * + * has caused devastating problems for other Free Software projects (such * + * as KDE and NASM). We also occasionally relicense the code to third * + * parties as discussed above. If you wish to specify special license * + * conditions of your contributions, just say so when you send them. * + * * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler * + * license file for more details (it's in a COPYING file included with * + * RFIDler, and also available from * + * https://github.com/ApertureLabsLtd/RFIDler/COPYING * + * * + ***************************************************************************/ + +// Author: Adam Laurie + + + +#ifndef HARDWARE_PROFILE_UBW32_H +#define HARDWARE_PROFILE_UBW32_H + +//#include "plib.h" +typedef char BOOL; +typedef char BYTE; +typedef int rtccTime; +typedef int rtccDate; + + +#ifndef __PIC32MX__ +#define __PIC32MX__ +#endif + +#define GetSystemClock() (80000000ul) +#define GetPeripheralClock() (GetSystemClock()) +#define GetInstructionClock() (GetSystemClock()) + +//#define USE_SELF_POWER_SENSE_IO +#define tris_self_power TRISAbits.TRISA2 // Input +#define self_power 1 + +//#define USE_USB_BUS_SENSE_IO +#define tris_usb_bus_sense TRISBbits.TRISB5 // Input +#define USB_BUS_SENSE 1 + +// LEDs +#define mLED_1 LATEbits.LATE3 + +#define mLED_2 LATEbits.LATE2 +#define mLED_Comms mLED_2 + +#define mLED_3 LATEbits.LATE1 +#define mLED_Clock mLED_3 + +#define mLED_4 LATEbits.LATE0 +#define mLED_Emulate mLED_4 + +#define mLED_5 LATGbits.LATG6 +#define mLED_Read mLED_5 + +#define mLED_6 LATAbits.LATA15 +#define mLED_User mLED_6 + +#define mLED_7 LATDbits.LATD11 +#define mLED_Error mLED_7 + +// active low +#define mLED_ON 0 +#define mLED_OFF 1 + +#define mGetLED_1() mLED_1 +#define mGetLED_USB() mLED_1 +#define mGetLED_2() mLED_2 +#define mGetLED_Comms() mLED_2 +#define mGetLED_3() mLED_3 +#define mGetLED_Clock() mLED_3 +#define mGetLED_4() mLED_4 +#define mGetLED_Emulate() mLED_4 +#define mGetLED_5() mLED_5 +#define mGetLED_Read() mLED_5 +#define mGetLED_6() mLED_6 +#define mGetLED_User() mLED_6 +#define mGetLED_7() mLED_7 +#define mGetLED_Error() mLED_7 + +#define mLED_1_On() mLED_1 = mLED_ON +#define mLED_USB_On() mLED_1_On() +#define mLED_2_On() mLED_2 = mLED_ON +#define mLED_Comms_On() mLED_2_On() +#define mLED_3_On() mLED_3 = mLED_ON +#define mLED_Clock_On() mLED_3_On() +#define mLED_4_On() mLED_4 = mLED_ON +#define mLED_Emulate_On() mLED_4_On() +#define mLED_5_On() mLED_5 = mLED_ON +#define mLED_Read_On() mLED_5_On() +#define mLED_6_On() mLED_6 = mLED_ON +#define mLED_User_On() mLED_6_On() +#define mLED_7_On() mLED_7 = mLED_ON +#define mLED_Error_On() mLED_7_On() + +#define mLED_1_Off() mLED_1 = mLED_OFF +#define mLED_USB_Off() mLED_1_Off() +#define mLED_2_Off() mLED_2 = mLED_OFF +#define mLED_Comms_Off() mLED_2_Off() +#define mLED_3_Off() mLED_3 = mLED_OFF +#define mLED_Clock_Off() mLED_3_Off() +#define mLED_4_Off() mLED_4 = mLED_OFF +#define mLED_Emulate_Off() mLED_4_Off() +#define mLED_5_Off() mLED_5 = mLED_OFF +#define mLED_Read_Off() mLED_5_Off() +#define mLED_6_Off() mLED_6 = mLED_OFF +#define mLED_User_Off() mLED_6_Off() +#define mLED_7_Off() mLED_7 = mLED_OFF +#define mLED_Error_Off() mLED_7_Off() + +#define mLED_1_Toggle() mLED_1 = !mLED_1 +#define mLED_USB_Toggle() mLED_1_Toggle() +#define mLED_2_Toggle() mLED_2 = !mLED_2 +#define mLED_Comms_Toggle() mLED_2_Toggle() +#define mLED_3_Toggle() mLED_3 = !mLED_3 +#define mLED_Clock_Toggle() mLED_3_Toggle() +#define mLED_4_Toggle() mLED_4 = !mLED_4 +#define mLED_Emulate_Toggle() mLED_4_Toggle() +#define mLED_5_Toggle() mLED_5 = !mLED_5 +#define mLED_Read_Toggle( ) mLED_5_Toggle() +#define mLED_6_Toggle() mLED_6 = !mLED_6 +#define mLED_User_Toggle() mLED_6_Toggle() +#define mLED_7_Toggle() mLED_7 = !mLED_7 +#define mLED_Error_Toggle() mLED_7_Toggle() + +#define mLED_All_On() { mLED_1_On(); mLED_2_On(); mLED_3_On(); mLED_4_On(); mLED_5_On(); mLED_6_On(); mLED_7_On(); } +#define mLED_All_Off() { mLED_1_Off(); mLED_2_Off(); mLED_3_Off(); mLED_4_Off(); mLED_5_Off(); mLED_6_Off(); mLED_7_Off(); } + +// usb status lights +#define mLED_Both_Off() {mLED_USB_Off();mLED_Comms_Off();} +#define mLED_Both_On() {mLED_USB_On();mLED_Comms_On();} +#define mLED_Only_USB_On() {mLED_USB_On();mLED_Comms_Off();} +#define mLED_Only_Comms_On() {mLED_USB_Off();mLED_Comms_On();} + +/** SWITCH *********************************************************/ +#define swBootloader PORTEbits.RE7 +#define swUser PORTEbits.RE6 + +/** I/O pin definitions ********************************************/ +#define INPUT_PIN 1 +#define OUTPUT_PIN 0 + +#define TRUE 1 +#define FALSE 0 + +#define ENABLE 1 +#define DISABE 0 + +#define EVEN 0 +#define ODD 1 + +#define LOW FALSE +#define HIGH TRUE + +#define CLOCK_ON LOW +#define CLOCK_OFF HIGH + +// output coil control - select between reader/emulator circuits +#define COIL_MODE LATBbits.LATB4 +#define COIL_MODE_READER() COIL_MODE= LOW +#define COIL_MODE_EMULATOR() COIL_MODE= HIGH + +// coil for emulation +#define COIL_OUT LATGbits.LATG9 +#define COIL_OUT_HIGH() COIL_OUT=HIGH +#define COIL_OUT_LOW() COIL_OUT=LOW + +// door relay (active low) +#define DOOR_RELAY LATAbits.LATA14 +#define DOOR_RELAY_OPEN() DOOR_RELAY= HIGH +#define DOOR_RELAY_CLOSE() DOOR_RELAY= LOW + +// inductance/capacitance freq +#define IC_FREQUENCY PORTAbits.RA2 + +#define SNIFFER_COIL PORTDbits.RD12 // external reader clock detect +#define READER_ANALOGUE PORTBbits.RB11 // reader coil analogue +#define DIV_LOW_ANALOGUE PORTBbits.RB12 // voltage divider LOW analogue +#define DIV_HIGH_ANALOGUE PORTBbits.RB13 // voltage divider HIGH analogue + +// clock coil (normally controlled by OC Module, but defined here so we can force it high or low) +#define CLOCK_COIL PORTDbits.RD4 +#define CLOCK_COIL_MOVED PORTDbits.RD0 // temporary for greenwire + +// digital output after analogue reader circuit +#define READER_DATA PORTDbits.RD8 + +// trace / debug +#define DEBUG_PIN_1 LATCbits.LATC1 +#define DEBUG_PIN_1_TOGGLE() DEBUG_PIN_1= !DEBUG_PIN_1 +#define DEBUG_PIN_2 LATCbits.LATC2 +#define DEBUG_PIN_2_TOGGLE() DEBUG_PIN_2= !DEBUG_PIN_2 +#define DEBUG_PIN_3 LATCbits.LATC3 +#define DEBUG_PIN_3_TOGGLE() DEBUG_PIN_3= !DEBUG_PIN_3 +#define DEBUG_PIN_4 LATEbits.LATE5 +#define DEBUG_PIN_4_TOGGLE() DEBUG_PIN_4= !DEBUG_PIN_4 + +// spi (sdi1) for sd card (not directly referenced) +//#define SD_CARD_RX LATCbits.LATC4 +//#define SD_CARD_TX LATDbits.LATD0 +//#define SD_CARD_CLK LATDbits.LATD10 +//#define SD_CARD_SS LATDbits.LATD9 +// spi for SD card +#define SD_CARD_DET LATFbits.LATF0 +#define SD_CARD_WE LATFbits.LATF1 // write enable - unused for microsd but allocated anyway as library checks it +// (held LOW by default - cut solder bridge to GND to free pin if required) +#define SPI_SD SPI_CHANNEL1 +#define SPI_SD_BUFF SPI1BUF +#define SPI_SD_STAT SPI1STATbits +// see section below for more defines! + +// iso 7816 smartcard +// microchip SC module defines pins so we don't need to, but +// they are listed here to help avoid conflicts +#define ISO_7816_RX LATBbits.LATF2 // RX +#define ISO_7816_TX LATBbits.LATF8 // TX +#define ISO_7816_VCC LATBbits.LATB9 // Power +#define ISO_7816_CLK LATCbits.LATD1 // Clock +#define ISO_7816_RST LATEbits.LATE8 // Reset + +// user LED +#define USER_LED LATDbits.LATD7 +#define USER_LED_ON() LATDbits.LATD7=1 +#define USER_LED_OFF() LATDbits.LATD7=0 + +// LCR +#define LCR_CALIBRATE LATBbits.LATB5 + +// wiegand / clock & data +#define WIEGAND_IN_0 PORTDbits.RD5 +#define WIEGAND_IN_0_PULLUP CNPUEbits.CNPUE14 +#define WIEGAND_IN_0_PULLDOWN CNPDbits.CNPD14 +#define WIEGAND_IN_1 PORTDbits.RD6 +#define WIEGAND_IN_1_PULLUP CNPUEbits.CNPUE15 +#define WIEGAND_IN_1_PULLDOWN CNPDbits.CNPD15 +#define CAND_IN_DATA WIEGAND_IN_0 +#define CAND_IN_CLOCK WIEGAND_IN_1 + +#define WIEGAND_OUT_0 LATDbits.LATD3 +#define WIEGAND_OUT_1 LATDbits.LATD2 +#define WIEGAND_OUT_0_TRIS TRISDbits.TRISD3 +#define WIEGAND_OUT_1_TRIS TRISDbits.TRISD2 +#define CAND_OUT_DATA WIEGAND_OUT_0 +#define CAND_OUT_CLOCK WIEGAND_OUT_1 + +// connect/disconnect reader clock from coil - used to send RWD signals by creating gaps in carrier +#define READER_CLOCK_ENABLE LATEbits.LATE9 +#define READER_CLOCK_ENABLE_ON() READER_CLOCK_ENABLE=CLOCK_ON +#define READER_CLOCK_ENABLE_OFF(x) {READER_CLOCK_ENABLE=CLOCK_OFF; COIL_OUT=x;} + +// these input pins must NEVER bet set to output or they will cause short circuits! +// they can be used to see data from reader before it goes into or gate +#define OR_IN_A PORTAbits.RA4 +#define OR_IN_B PORTAbits.RA5 + + +// CNCON and CNEN are set to allow wiegand input pin weak pullups to be switched on +#define Init_GPIO() { \ + CNCONbits.ON= TRUE; \ + CNENbits.CNEN14= TRUE; \ + CNENbits.CNEN15= TRUE; \ + TRISAbits.TRISA2= INPUT_PIN; \ + TRISAbits.TRISA4= INPUT_PIN; \ + TRISAbits.TRISA5= INPUT_PIN; \ + TRISAbits.TRISA14= OUTPUT_PIN; \ + TRISAbits.TRISA15= OUTPUT_PIN; \ + TRISBbits.TRISB4= OUTPUT_PIN; \ + TRISBbits.TRISB5= OUTPUT_PIN; \ + TRISBbits.TRISB9= OUTPUT_PIN; \ + TRISBbits.TRISB11= INPUT_PIN; \ + TRISBbits.TRISB12= INPUT_PIN; \ + TRISBbits.TRISB13= INPUT_PIN; \ + TRISCbits.TRISC1= OUTPUT_PIN; \ + TRISCbits.TRISC2= OUTPUT_PIN; \ + TRISCbits.TRISC3= OUTPUT_PIN; \ + TRISCbits.TRISC4= INPUT_PIN; \ + TRISDbits.TRISD0= INPUT_PIN; \ + TRISDbits.TRISD1= OUTPUT_PIN; \ + TRISDbits.TRISD2= OUTPUT_PIN; \ + TRISDbits.TRISD3= OUTPUT_PIN; \ + TRISDbits.TRISD4= OUTPUT_PIN; \ + TRISDbits.TRISD5= INPUT_PIN; \ + TRISDbits.TRISD6= INPUT_PIN; \ + TRISDbits.TRISD7= OUTPUT_PIN; \ + TRISDbits.TRISD8= INPUT_PIN; \ + TRISDbits.TRISD11= OUTPUT_PIN; \ + TRISDbits.TRISD12= INPUT_PIN; \ + TRISEbits.TRISE0= OUTPUT_PIN; \ + TRISEbits.TRISE1= OUTPUT_PIN; \ + TRISEbits.TRISE2= OUTPUT_PIN; \ + TRISEbits.TRISE3= OUTPUT_PIN; \ + TRISEbits.TRISE5= OUTPUT_PIN; \ + TRISEbits.TRISE6= INPUT_PIN; \ + TRISEbits.TRISE7= INPUT_PIN; \ + TRISEbits.TRISE8= OUTPUT_PIN; \ + TRISEbits.TRISE9= OUTPUT_PIN; \ + TRISFbits.TRISF0= INPUT_PIN; \ + TRISFbits.TRISF1= INPUT_PIN; \ + TRISFbits.TRISF2= INPUT_PIN; \ + TRISFbits.TRISF8= OUTPUT_PIN; \ + TRISGbits.TRISG6= OUTPUT_PIN; \ + TRISGbits.TRISG12= INPUT_PIN; \ + TRISGbits.TRISG13= INPUT_PIN; \ + TRISGbits.TRISG9= OUTPUT_PIN; \ + LATBbits.LATB9= LOW; \ + LATCbits.LATC1= LOW; \ + LATCbits.LATC2= LOW; \ + LATCbits.LATC3= LOW; \ + LATDbits.LATD2= WIEGAND_IN_1; \ + LATDbits.LATD3= WIEGAND_IN_0; \ + LATEbits.LATE5= LOW; \ + LATEbits.LATE9= HIGH; \ + } + +// uart3 (CLI/API) speed +#define BAUDRATE3 115200UL +#define BRG_DIV3 4 +#define BRGH3 1 + +// spi for potentiometer +#define SPI_POT SPI_CHANNEL4 +#define SPI_POT_BUFF SPI4BUF +#define SPI_POT_STAT SPI4STATbits + +// spi for sd card - defines required for Microchip SD-SPI libs +// define interface type +#define USE_SD_INTERFACE_WITH_SPI + +#define MDD_USE_SPI_1 +#define SPI_START_CFG_1 (PRI_PRESCAL_64_1 | SEC_PRESCAL_8_1 | MASTER_ENABLE_ON | SPI_CKE_ON | SPI_SMP_ON) +#define SPI_START_CFG_2 (SPI_ENABLE) +// Define the SPI frequency +#define SPI_FREQUENCY (20000000) +// Description: SD-SPI Card Detect Input bit +#define SD_CD PORTFbits.RF0 +// Description: SD-SPI Card Detect TRIS bit +#define SD_CD_TRIS TRISFbits.TRISF0 +// Description: SD-SPI Write Protect Check Input bit +#define SD_WE PORTFbits.RF1 +// Description: SD-SPI Write Protect Check TRIS bit +#define SD_WE_TRIS TRISFbits.TRISF1 +// Description: The main SPI control register +#define SPICON1 SPI1CON +// Description: The SPI status register +#define SPISTAT SPI1STAT +// Description: The SPI Buffer +#define SPIBUF SPI1BUF +// Description: The receive buffer full bit in the SPI status register +#define SPISTAT_RBF SPI1STATbits.SPIRBF +// Description: The bitwise define for the SPI control register (i.e. _____bits) +#define SPICON1bits SPI1CONbits +// Description: The bitwise define for the SPI status register (i.e. _____bits) +#define SPISTATbits SPI1STATbits +// Description: The enable bit for the SPI module +#define SPIENABLE SPICON1bits.ON +// Description: The definition for the SPI baud rate generator register (PIC32) +#define SPIBRG SPI1BRG +// Description: The TRIS bit for the SCK pin +#define SPICLOCK TRISDbits.TRISD10 +// Description: The TRIS bit for the SDI pin +#define SPIIN TRISCbits.TRISC4 +// Description: The TRIS bit for the SDO pin +#define SPIOUT TRISDbits.TRISD0 +#define SD_CS LATDbits.LATD9 +// Description: SD-SPI Chip Select TRIS bit +#define SD_CS_TRIS TRISDbits.TRISD9 +//SPI library functions +#define putcSPI putcSPI1 +#define getcSPI getcSPI1 +#define OpenSPI(config1, config2) OpenSPI1(config1, config2) + +// Define setup parameters for OpenADC10 function +// Turn module on | Ouput in integer format | Trigger mode auto | Enable autosample +#define ADC_CONFIG1 (ADC_FORMAT_INTG | ADC_CLK_AUTO | ADC_AUTO_SAMPLING_ON) +// ADC ref external | Disable offset test | Disable scan mode | Perform 2 samples | Use dual buffers | Use alternate mode +#define ADC_CONFIG2 (ADC_VREF_AVDD_AVSS | ADC_OFFSET_CAL_DISABLE | ADC_SCAN_OFF | ADC_SAMPLES_PER_INT_1 | ADC_ALT_BUF_ON | ADC_ALT_INPUT_ON) + +// Use ADC internal clock | Set sample time +#define ADC_CONFIG3 (ADC_CONV_CLK_INTERNAL_RC | ADC_SAMPLE_TIME_0) + +// slow sample rate for tuning coils +#define ADC_CONFIG2_SLOW (ADC_VREF_AVDD_AVSS | ADC_OFFSET_CAL_DISABLE | ADC_SCAN_OFF | ADC_SAMPLES_PER_INT_16 | ADC_ALT_BUF_ON | ADC_ALT_INPUT_ON) +#define ADC_CONFIG3_SLOW (ADC_CONV_CLK_INTERNAL_RC | ADC_SAMPLE_TIME_31) + +// use AN11 +#define ADC_CONFIGPORT ENABLE_AN11_ANA +// Do not assign channels to scan +#define ADC_CONFIGSCAN SKIP_SCAN_ALL + +#define ADC_TO_VOLTS 0.003208F + + +// flash memory - int myvar = *(int*)(myflashmemoryaddress); + +// memory is 0x9D005000 to 0x9D07FFFF + +#define NVM_MEMORY_END 0x9D07FFFF +#define NVM_PAGE_SIZE 4096 +#define NVM_PAGES 2 // config & VTAG +#define RFIDLER_NVM_ADDRESS (NVM_MEMORY_END - (NVM_PAGE_SIZE * NVM_PAGES)) + +// UART timeout in us +#define SERIAL_TIMEOUT 100 + +#endif diff --git a/tools/hitag2crack/crack5/Makefile b/tools/hitag2crack/crack5/Makefile new file mode 100644 index 000000000..e38c821d1 --- /dev/null +++ b/tools/hitag2crack/crack5/Makefile @@ -0,0 +1,18 @@ +CFLAGS?=-Wall +LIBS=-lpthread + +all: ht2crack5.c utilpart.o ht2crack2utils.o hitagcrypto.o + $(CC) $(CFLAGS) -O3 ht2crack5.c -o ht2crack5 utilpart.o ht2crack2utils.o hitagcrypto.o $(LIBS) + +utilpart.o: util.h utilpart.c + $(CC) $(CFLAGS) -c utilpart.c + +hitagcrypto.o: hitagcrypto.h hitagcrypto.c + $(CC) $(CFLAGS) -c hitagcrypto.c + +ht2crack2utils.o: ht2crack2utils.h ht2crack2utils.c + $(CC) $(CFLAGS) -c ht2crack2utils.c + +clean: + rm -f *.o ht2crack5 +fresh: clean all diff --git a/tools/hitag2crack/crack5/README.md b/tools/hitag2crack/crack5/README.md new file mode 100644 index 000000000..5c900122b --- /dev/null +++ b/tools/hitag2crack/crack5/README.md @@ -0,0 +1,23 @@ +ht2crack5 + + + +Build +----- + +``` +make clean +make +``` + +Run +--- + +You'll need just two nR aR pairs. These are the +encrypted nonces and challenge response values. They should be in hex. + +``` +./ht2crack5 +``` + +UID is the UID of the tag that you used to gather the nR aR values. diff --git a/tools/hitag2crack/crack5/hitagcrypto.c b/tools/hitag2crack/crack5/hitagcrypto.c new file mode 100644 index 000000000..47449c3e3 --- /dev/null +++ b/tools/hitag2crack/crack5/hitagcrypto.c @@ -0,0 +1,373 @@ +/*************************************************************************** + * A copy of the GNU GPL is appended to this file. * + * * + * This licence is based on the nmap licence, and we express our gratitude * + * for the work that went into producing it. There is no other connection * + * between RFIDler and nmap either expressed or implied. * + * * + ********************** IMPORTANT RFIDler LICENSE TERMS ******************** + * * + * * + * All references to RFIDler herein imply all it's derivatives, namely: * + * * + * o RFIDler-LF Standard * + * o RFIDler-LF Lite * + * o RFIDler-LF Nekkid * + * * + * * + * RFIDler is (C) 2013-2015 Aperture Labs Ltd. * + * * + * This program is free software; you may redistribute and/or modify it * + * under the terms of the GNU General Public License as published by the * + * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE * + * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your * + * right to use, modify, and redistribute this software under certain * + * conditions. If you wish to embed RFIDler technology into proprietary * + * software or hardware, we sell alternative licenses * + * (contact sales@aperturelabs.com). * + * * + * Note that the GPL places important restrictions on "derivative works", * + * yet it does not provide a detailed definition of that term. To avoid * + * misunderstandings, we interpret that term as broadly as copyright law * + * allows. For example, we consider an application to constitute a * + * derivative work for the purpose of this license if it does any of the * + * following with any software or content covered by this license * + * ("Covered Software"): * + * * + * o Integrates source code from Covered Software. * + * * + * o Is designed specifically to execute Covered Software and parse the * + * results (as opposed to typical shell or execution-menu apps, which will * + * execute anything you tell them to). * + * * + * o Includes Covered Software in a proprietary executable installer. The * + * installers produced by InstallShield are an example of this. Including * + * RFIDler with other software in compressed or archival form does not * + * trigger this provision, provided appropriate open source decompression * + * or de-archiving software is widely available for no charge. For the * + * purposes of this license, an installer is considered to include Covered * + * Software even if it actually retrieves a copy of Covered Software from * + * another source during runtime (such as by downloading it from the * + * Internet). * + * * + * o Links (statically or dynamically) to a library which does any of the * + * above. * + * * + * o Executes a helper program, module, or script to do any of the above. * + * * + * This list is not exclusive, but is meant to clarify our interpretation * + * of derived works with some common examples. Other people may interpret * + * the plain GPL differently, so we consider this a special exception to * + * the GPL that we apply to Covered Software. Works which meet any of * + * these conditions must conform to all of the terms of this license, * + * particularly including the GPL Section 3 requirements of providing * + * source code and allowing free redistribution of the work as a whole. * + * * + * As another special exception to the GPL terms, Aperture Labs Ltd. grants* + * permission to link the code of this program with any version of the * + * OpenSSL library which is distributed under a license identical to that * + * listed in the included docs/licenses/OpenSSL.txt file, and distribute * + * linked combinations including the two. * + * * + * Any redistribution of Covered Software, including any derived works, * + * must obey and carry forward all of the terms of this license, including * + * obeying all GPL rules and restrictions. For example, source code of * + * the whole work must be provided and free redistribution must be * + * allowed. All GPL references to "this License", are to be treated as * + * including the terms and conditions of this license text as well. * + * * + * Because this license imposes special exceptions to the GPL, Covered * + * Work may not be combined (even as part of a larger work) with plain GPL * + * software. The terms, conditions, and exceptions of this license must * + * be included as well. This license is incompatible with some other open * + * source licenses as well. In some cases we can relicense portions of * + * RFIDler or grant special permissions to use it in other open source * + * software. Please contact sales@aperturelabs.com with any such requests.* + * Similarly, we don't incorporate incompatible open source software into * + * Covered Software without special permission from the copyright holders. * + * * + * If you have any questions about the licensing restrictions on using * + * RFIDler in other works, are happy to help. As mentioned above, we also * + * offer alternative license to integrate RFIDler into proprietary * + * applications and appliances. These contracts have been sold to dozens * + * of software vendors, and generally include a perpetual license as well * + * as providing for priority support and updates. They also fund the * + * continued development of RFIDler. Please email sales@aperturelabs.com * + * for further information. * + * If you have received a written license agreement or contract for * + * Covered Software stating terms other than these, you may choose to use * + * and redistribute Covered Software under those terms instead of these. * + * * + * Source is provided to this software because we believe users have a * + * right to know exactly what a program is going to do before they run it. * + * This also allows you to audit the software for security holes (none * + * have been found so far). * + * * + * Source code also allows you to port RFIDler to new platforms, fix bugs, * + * and add new features. You are highly encouraged to send your changes * + * to the RFIDler mailing list for possible incorporation into the * + * main distribution. By sending these changes to Aperture Labs Ltd. or * + * one of the Aperture Labs Ltd. development mailing lists, or checking * + * them into the RFIDler source code repository, it is understood (unless * + * you specify otherwise) that you are offering the RFIDler Project * + * (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, * + * modify, and relicense the code. RFIDler will always be available Open * + * Source, but this is important because the inability to relicense code * + * has caused devastating problems for other Free Software projects (such * + * as KDE and NASM). We also occasionally relicense the code to third * + * parties as discussed above. If you wish to specify special license * + * conditions of your contributions, just say so when you send them. * + * * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler * + * license file for more details (it's in a COPYING file included with * + * RFIDler, and also available from * + * https://github.com/ApertureLabsLtd/RFIDler/COPYING * + * * + ***************************************************************************/ + +// Author: unknown. +// Modifications for RFIDler: Tony Naggs , Adam Laurie + +// uncomment this to build file as a standalone crypto test program +// #define UNIT_TEST +// also uncomment to include verbose debug prints +// #define TEST_DEBUG + +//#include +#include "HardwareProfile.h" +#include "rfidler.h" +#include "hitagcrypto.h" +#include "util.h" + +#ifdef UNIT_TEST +#include +#endif + +#if defined(UNIT_TEST) && defined(TEST_DEBUG) +// Note that printf format %I64x prints 64 bit ints in MS Visual C/C++. +// This may need changing for other compilers/platforms. +#define DEBUG_PRINTF(...) printf(__VA_ARGS__) +#else +#define DEBUG_PRINTF(...) +#endif + + +/* Brief info about NXP Hitag 1, Hitag 2, Hitag S and Hitag u (mu) + + Hitag 125kHz RFID was created by a company called Mikron (Mikron Gesellschaft + fur Integrierte Mikroelektronik Mbh), of Austria, for micropayment applications. + At about the same time, late 1980s to early 1990s, Mikron developed the + similarly featured Mifare micropayment card for 13.56MHz RFID. + (Mikron's European Patent EP 0473569 A2 was filed 23 August 1991, with a + priority date of 23 Aug 1990.) + Mikron was subsequently acquired by Philips Semiconductors in 1995. + Philips Semiconductors divsion subsequently became NXP. + + + Modulation read/write device -> transponder: 100 % ASK and binary pulse + length coding + + Modulation transponder -> read/write device: Strong ASK modulation, + selectable Manchester or Biphase coding + + Hitag S, Hitag u; anti-collision procedure + + Fast anti-collision protocol + + Hitag u; optional Cyclic Redundancy Check (CRC) + + Reader Talks First mode + + Hitag 2 & later; Transponder Talks First (TTF) mode + + Temporary switch from Transponder Talks First into Reader Talks First + (RTF) Mode + + Data rate read/write device to transponder: 5.2 kbit/s + + Data rates transponder to read/write device: 2 kbit/s, 4 kbit/s, 8 kbit/s + + 32-bit password feature + + Hitag 2, S = 32-bit Unique Identifier + + Hitag u = 48-bit Unique Identifier + + Selectable password modes for reader / tag mutual authentication + (Hitag 1 has 2 pairs of keys, later versions have 1 pair) + + Hitag 2 & Hitag S; Selectable encrypted mode, 48 bit key + + Known tag types: + + HITAG 1 2048 bits total memory + + HITAG 2 256 Bit total memory Read/Write + 8 pages of 32 bits, inc UID (32), + secret key (64), password (24), config (8) + + HITAG S 32 32 bits Unique Identifier Read Only + HITAG S 256 256 bits total memory Read/Write + HITAG S 2048 2048 bits total memory Read/Write + + HITAG u RO64 64 bits total memory Read Only + HITAG u 128 bits total memory Read/Write + HITAG u Advanced 512 bits total memory Read/Write + HITAG u Advanced+ 1760 bits total memory Read/Write + + Default 48-bit key for Hitag 2, S encryption: + "MIKRON" = O N M I K R + Key = 4F 4E 4D 49 4B 52 + +*/ + + +// We want the crypto functions to be as fast as possible, so optimize! +// The best compiler optimization in Microchip's free XC32 edition is -O1 +#pragma GCC optimize("O1") + +// private, nonlinear function to generate 1 crypto bit +static uint32_t hitag2_crypt(uint64_t x); + + +// macros to pick out 4 bits in various patterns of 1s & 2s & make a new number +#define pickbits2_2(S, A, B) ( ((S >> A) & 3) | ((S >> (B - 2)) & 0xC) ) +#define pickbits1x4(S, A, B, C, D) ( ((S >> A) & 1) | ((S >> (B - 1)) & 2) | \ + ((S >> (C - 2)) & 4) | ((S >> (D - 3)) & 8) ) +#define pickbits1_1_2(S, A, B, C) ( ((S >> A) & 1) | ((S >> (B - 1)) & 2) | \ + ((S >> (C - 2)) & 0xC) ) +#define pickbits2_1_1(S, A, B, C) ( ((S >> A) & 3) | ((S >> (B - 2)) & 4) | \ + ((S >> (C - 3)) & 8) ) +#define pickbits1_2_1(S, A, B, C) ( ((S >> A) & 1) | ((S >> (B - 1)) & 6) | \ + ((S >> (C - 3)) & 8) ) + + +static uint32_t hitag2_crypt(uint64_t x) { + const uint32_t ht2_function4a = 0x2C79; // 0010 1100 0111 1001 + const uint32_t ht2_function4b = 0x6671; // 0110 0110 0111 0001 + const uint32_t ht2_function5c = 0x7907287B; // 0111 1001 0000 0111 0010 1000 0111 1011 + uint32_t bitindex; + + bitindex = (ht2_function4a >> pickbits2_2(x, 1, 4)) & 1; + bitindex |= ((ht2_function4b << 1) >> pickbits1_1_2(x, 7, 11, 13)) & 0x02; + bitindex |= ((ht2_function4b << 2) >> pickbits1x4(x, 16, 20, 22, 25)) & 0x04; + bitindex |= ((ht2_function4b << 3) >> pickbits2_1_1(x, 27, 30, 32)) & 0x08; + bitindex |= ((ht2_function4a << 4) >> pickbits1_2_1(x, 33, 42, 45)) & 0x10; + + DEBUG_PRINTF("hitag2_crypt bitindex = %02x\n", bitindex); + return (ht2_function5c >> bitindex) & 1; +} + +/* + * Parameters: + * Hitag_State* pstate - output, internal state after initialisation + * uint64_t sharedkey - 48 bit key shared between reader & tag + * uint32_t serialnum - 32 bit tag serial number + * uint32_t initvector - 32 bit random IV from reader, part of tag authentication + */ +void hitag2_init(Hitag_State *pstate, uint64_t sharedkey, uint32_t serialnum, uint32_t initvector) { + // init state, from serial number and lowest 16 bits of shared key + uint64_t state = ((sharedkey & 0xFFFF) << 32) | serialnum; + + // mix the initialisation vector and highest 32 bits of the shared key + initvector ^= (uint32_t)(sharedkey >> 16); + + // move 16 bits from (IV xor Shared Key) to top of uint64_t state + // these will be XORed in turn with output of the crypto function + state |= (uint64_t) initvector << 48; + initvector >>= 16; + + // unrolled loop is faster on PIC32 (MIPS), do 32 times + // shift register, then calc new bit + state >>= 1; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + + // highest 16 bits of IV XOR Shared Key + state |= (uint64_t) initvector << 47; + + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state ^= (uint64_t) hitag2_crypt(state) << 47; + + DEBUG_PRINTF("hitag2_init result = %012I64x\n", state); + pstate->shiftreg = state; + /* naive version for reference, LFSR has 16 taps + pstate->lfsr = state ^ (state >> 2) ^ (state >> 3) ^ (state >> 6) + ^ (state >> 7) ^ (state >> 8) ^ (state >> 16) ^ (state >> 22) + ^ (state >> 23) ^ (state >> 26) ^ (state >> 30) ^ (state >> 41) + ^ (state >> 42) ^ (state >> 43) ^ (state >> 46) ^ (state >> 47); + */ + { + // optimise with one 64-bit intermediate + uint64_t temp = state ^ (state >> 1); + pstate->lfsr = state ^ (state >> 6) ^ (state >> 16) + ^ (state >> 26) ^ (state >> 30) ^ (state >> 41) + ^ (temp >> 2) ^ (temp >> 7) ^ (temp >> 22) + ^ (temp >> 42) ^ (temp >> 46); + } +} + + +/* + * Return up to 32 crypto bits. + * Last bit is in least significant bit, earlier bits are shifted left. + * Note that the Hitag transmission protocol is least significant bit, + * so we may want to change this, or add a function, that returns the + * crypto output bits in the other order. + * + * Parameters: + * Hitag_State* pstate - in/out, internal cipher state after initialisation + * uint32_t steps - number of bits requested, (capped at 32) + */ +uint32_t hitag2_nstep(Hitag_State *pstate, uint32_t steps) { + uint64_t state = pstate->shiftreg; + uint32_t result = 0; + uint64_t lfsr = pstate->lfsr; + + if (steps == 0) + return 0; + +// if (steps > 32) +// steps = 32; + + do { + // update shift registers + if (lfsr & 1) { + state = (state >> 1) | 0x800000000000; + lfsr = (lfsr >> 1) ^ 0xB38083220073; + + // accumulate next bit of crypto + result = (result << 1) | hitag2_crypt(state); + } else { + state >>= 1; + lfsr >>= 1; + + result = (result << 1) | hitag2_crypt(state); + } + } while (--steps); + + DEBUG_PRINTF("hitag2_nstep state = %012I64x, result %02x\n", state, result); + pstate->shiftreg = state; + pstate->lfsr = lfsr; + return result; +} + +// end of crypto core, revert to default optimization level +#pragma GCC reset_options diff --git a/tools/hitag2crack/crack5/hitagcrypto.h b/tools/hitag2crack/crack5/hitagcrypto.h new file mode 100644 index 000000000..274d3d82c --- /dev/null +++ b/tools/hitag2crack/crack5/hitagcrypto.h @@ -0,0 +1,167 @@ +/*************************************************************************** + * A copy of the GNU GPL is appended to this file. * + * * + * This licence is based on the nmap licence, and we express our gratitude * + * for the work that went into producing it. There is no other connection * + * between RFIDler and nmap either expressed or implied. * + * * + ********************** IMPORTANT RFIDler LICENSE TERMS ******************** + * * + * * + * All references to RFIDler herein imply all it's derivatives, namely: * + * * + * o RFIDler-LF Standard * + * o RFIDler-LF Lite * + * o RFIDler-LF Nekkid * + * * + * * + * RFIDler is (C) 2013-2014 Aperture Labs Ltd. * + * * + * This program is free software; you may redistribute and/or modify it * + * under the terms of the GNU General Public License as published by the * + * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE * + * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your * + * right to use, modify, and redistribute this software under certain * + * conditions. If you wish to embed RFIDler technology into proprietary * + * software or hardware, we sell alternative licenses * + * (contact sales@aperturelabs.com). * + * * + * Note that the GPL places important restrictions on "derivative works", * + * yet it does not provide a detailed definition of that term. To avoid * + * misunderstandings, we interpret that term as broadly as copyright law * + * allows. For example, we consider an application to constitute a * + * derivative work for the purpose of this license if it does any of the * + * following with any software or content covered by this license * + * ("Covered Software"): * + * * + * o Integrates source code from Covered Software. * + * * + * o Is designed specifically to execute Covered Software and parse the * + * results (as opposed to typical shell or execution-menu apps, which will * + * execute anything you tell them to). * + * * + * o Includes Covered Software in a proprietary executable installer. The * + * installers produced by InstallShield are an example of this. Including * + * RFIDler with other software in compressed or archival form does not * + * trigger this provision, provided appropriate open source decompression * + * or de-archiving software is widely available for no charge. For the * + * purposes of this license, an installer is considered to include Covered * + * Software even if it actually retrieves a copy of Covered Software from * + * another source during runtime (such as by downloading it from the * + * Internet). * + * * + * o Links (statically or dynamically) to a library which does any of the * + * above. * + * * + * o Executes a helper program, module, or script to do any of the above. * + * * + * This list is not exclusive, but is meant to clarify our interpretation * + * of derived works with some common examples. Other people may interpret * + * the plain GPL differently, so we consider this a special exception to * + * the GPL that we apply to Covered Software. Works which meet any of * + * these conditions must conform to all of the terms of this license, * + * particularly including the GPL Section 3 requirements of providing * + * source code and allowing free redistribution of the work as a whole. * + * * + * As another special exception to the GPL terms, Aperture Labs Ltd. grants* + * permission to link the code of this program with any version of the * + * OpenSSL library which is distributed under a license identical to that * + * listed in the included docs/licenses/OpenSSL.txt file, and distribute * + * linked combinations including the two. * + * * + * Any redistribution of Covered Software, including any derived works, * + * must obey and carry forward all of the terms of this license, including * + * obeying all GPL rules and restrictions. For example, source code of * + * the whole work must be provided and free redistribution must be * + * allowed. All GPL references to "this License", are to be treated as * + * including the terms and conditions of this license text as well. * + * * + * Because this license imposes special exceptions to the GPL, Covered * + * Work may not be combined (even as part of a larger work) with plain GPL * + * software. The terms, conditions, and exceptions of this license must * + * be included as well. This license is incompatible with some other open * + * source licenses as well. In some cases we can relicense portions of * + * RFIDler or grant special permissions to use it in other open source * + * software. Please contact sales@aperturelabs.com with any such requests.* + * Similarly, we don't incorporate incompatible open source software into * + * Covered Software without special permission from the copyright holders. * + * * + * If you have any questions about the licensing restrictions on using * + * RFIDler in other works, are happy to help. As mentioned above, we also * + * offer alternative license to integrate RFIDler into proprietary * + * applications and appliances. These contracts have been sold to dozens * + * of software vendors, and generally include a perpetual license as well * + * as providing for priority support and updates. They also fund the * + * continued development of RFIDler. Please email sales@aperturelabs.com * + * for further information. * + * If you have received a written license agreement or contract for * + * Covered Software stating terms other than these, you may choose to use * + * and redistribute Covered Software under those terms instead of these. * + * * + * Source is provided to this software because we believe users have a * + * right to know exactly what a program is going to do before they run it. * + * This also allows you to audit the software for security holes (none * + * have been found so far). * + * * + * Source code also allows you to port RFIDler to new platforms, fix bugs, * + * and add new features. You are highly encouraged to send your changes * + * to the RFIDler mailing list for possible incorporation into the * + * main distribution. By sending these changes to Aperture Labs Ltd. or * + * one of the Aperture Labs Ltd. development mailing lists, or checking * + * them into the RFIDler source code repository, it is understood (unless * + * you specify otherwise) that you are offering the RFIDler Project * + * (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, * + * modify, and relicense the code. RFIDler will always be available Open * + * Source, but this is important because the inability to relicense code * + * has caused devastating problems for other Free Software projects (such * + * as KDE and NASM). We also occasionally relicense the code to third * + * parties as discussed above. If you wish to specify special license * + * conditions of your contributions, just say so when you send them. * + * * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler * + * license file for more details (it's in a COPYING file included with * + * RFIDler, and also available from * + * https://github.com/ApertureLabsLtd/RFIDler/COPYING * + * * + ***************************************************************************/ + +// Author: unknown. +// Modifications for RFIDler: Tony Naggs , Adam Laurie + + +#ifndef HITAGCRYPTO_H +#define HITAGCRYPTO_H + +#include + +/* + Our model of Hitag 2 crypto uses 2 parallel shift registers: + a. 48 bit Feedback Shift Register, required for inputs to the nonlinear function. + b. 48 bit Linear Feedback Shift Register (LFSR). + A transform of initial register (a) value, which is then run in parallel. + Enables much faster calculation of the feedback values. + + API: + void hitag2_init(Hitag_State* pstate, uint64_t sharedkey, uint32_t serialnum, + uint32_t initvector); + Initialise state from 48 bit shared (secret) reader/tag key, + 32 bit tag serial number and 32 bit initialisation vector from reader. + + uint32_t hitag2_nstep(Hitag_State* pstate, uint32_t steps); + update shift register state and generate N cipher bits (N should be <= 32) + */ + + +typedef struct { + uint64_t shiftreg; // naive shift register, required for nonlinear fn input + uint64_t lfsr; // fast lfsr, used to make software faster +} Hitag_State; + +void hitag2_init(Hitag_State *pstate, uint64_t sharedkey, uint32_t serialnum, uint32_t initvector); + +uint32_t hitag2_nstep(Hitag_State *pstate, uint32_t steps); + +#endif /* HITAGCRYPTO_H */ + diff --git a/tools/hitag2crack/crack5/ht2crack2utils.c b/tools/hitag2crack/crack5/ht2crack2utils.c new file mode 100644 index 000000000..75d4c27a9 --- /dev/null +++ b/tools/hitag2crack/crack5/ht2crack2utils.c @@ -0,0 +1,172 @@ +#include "ht2crack2utils.h" + +// writes a value into a buffer as a series of bytes +void writebuf(unsigned char *buf, uint64_t val, unsigned int len) { + int i; + char c; + + for (i = len - 1; i >= 0; i--) { + c = val & 0xff; + buf[i] = c; + val = val >> 8; + } + +} + + +/* simple hexdump for testing purposes */ +void shexdump(unsigned char *data, int data_len) { + int i; + + if (!data || (data_len <= 0)) { + printf("shexdump: invalid parameters\n"); + return; + } + + printf("Hexdump from %p:\n", data); + + for (i = 0; i < data_len; i++) { + if ((i % HEX_PER_ROW) == 0) { + printf("\n0x%04x: ", i); + } + printf("%02x ", data[i]); + } + printf("\n\n"); +} + + + +void printbin(unsigned char *c) { + int i, j; + unsigned char x; + + if (!c) { + printf("printbin: invalid params\n"); + return; + } + + for (i = 0; i < 6; i++) { + x = c[i]; + for (j = 0; j < 8; j++) { + printf("%d", (x & 0x80) >> 7); + x = x << 1; + } + } + printf("\n"); +} + + +void printbin2(uint64_t val, unsigned int size) { + int i; + uint64_t mask = 1; + + mask = mask << (size - 1); + + for (i = 0; i < size; i++) { + if (val & mask) { + printf("1"); + } else { + printf("0"); + } + val = val << 1; + } +} + + +void printstate(Hitag_State *hstate) { + printf("shiftreg =\t"); + printbin2(hstate->shiftreg, 48); + printf("\n"); +} + + + + +// convert hex char to binary +unsigned char hex2bin(unsigned char c) { + if ((c >= '0') && (c <= '9')) { + return (c - '0'); + } else if ((c >= 'a') && (c <= 'f')) { + return (c - 'a' + 10); + } else if ((c >= 'A') && (c <= 'F')) { + return (c - 'A' + 10); + } else { + return 0; + } +} + +// return a single bit from a value +int bitn(uint64_t x, int bit) { + uint64_t bitmask = 1; + + bitmask = bitmask << bit; + + if (x & bitmask) { + return 1; + } else { + return 0; + } +} + + +// the sub-function R that rollback depends upon +int fnR(uint64_t x) { + // renumbered bits because my state is 0-47, not 1-48 + return (bitn(x, 1) ^ bitn(x, 2) ^ bitn(x, 5) ^ bitn(x, 6) ^ bitn(x, 7) ^ + bitn(x, 15) ^ bitn(x, 21) ^ bitn(x, 22) ^ bitn(x, 25) ^ bitn(x, 29) ^ bitn(x, 40) ^ + bitn(x, 41) ^ bitn(x, 42) ^ bitn(x, 45) ^ bitn(x, 46) ^ bitn(x, 47)); +} + +// the rollback function that lets us go backwards in time +void rollback(Hitag_State *hstate, unsigned int steps) { + int i; + + for (i = 0; i < steps; i++) { + hstate->shiftreg = ((hstate->shiftreg << 1) & 0xffffffffffff) | fnR(hstate->shiftreg); + } + +} + + +// the three filter sub-functions that feed fnf +int fa(unsigned int i) { + return bitn(0x2C79, i); +} + +int fb(unsigned int i) { + return bitn(0x6671, i); +} + +int fc(unsigned int i) { + return bitn(0x7907287B, i); +} + +// the filter function that generates a bit of output from the prng state +int fnf(uint64_t s) { + unsigned int x1, x2, x3, x4, x5, x6; + + x1 = (bitn(s, 2) << 0) | (bitn(s, 3) << 1) | (bitn(s, 5) << 2) | (bitn(s, 6) << 3); + x2 = (bitn(s, 8) << 0) | (bitn(s, 12) << 1) | (bitn(s, 14) << 2) | (bitn(s, 15) << 3); + x3 = (bitn(s, 17) << 0) | (bitn(s, 21) << 1) | (bitn(s, 23) << 2) | (bitn(s, 26) << 3); + x4 = (bitn(s, 28) << 0) | (bitn(s, 29) << 1) | (bitn(s, 31) << 2) | (bitn(s, 33) << 3); + x5 = (bitn(s, 34) << 0) | (bitn(s, 43) << 1) | (bitn(s, 44) << 2) | (bitn(s, 46) << 3); + + x6 = (fa(x1) << 0) | (fb(x2) << 1) | (fb(x3) << 2) | (fb(x4) << 3) | (fa(x5) << 4); + + return fc(x6); +} + +// builds the lfsr for the prng (quick calcs for hitag2_nstep()) +void buildlfsr(Hitag_State *hstate) { + uint64_t state = hstate->shiftreg; + uint64_t temp; + + temp = state ^ (state >> 1); + hstate->lfsr = state ^ (state >> 6) ^ (state >> 16) + ^ (state >> 26) ^ (state >> 30) ^ (state >> 41) + ^ (temp >> 2) ^ (temp >> 7) ^ (temp >> 22) + ^ (temp >> 42) ^ (temp >> 46); +} + + + diff --git a/tools/hitag2crack/crack5/ht2crack2utils.h b/tools/hitag2crack/crack5/ht2crack2utils.h new file mode 100644 index 000000000..33e0e3036 --- /dev/null +++ b/tools/hitag2crack/crack5/ht2crack2utils.h @@ -0,0 +1,35 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "HardwareProfile.h" +#include "rfidler.h" +#include "util.h" + +#include "hitagcrypto.h" + +#define HEX_PER_ROW 16 + + + +void writebuf(unsigned char *buf, uint64_t val, unsigned int len); +void shexdump(unsigned char *data, int data_len); +void printbin(unsigned char *c); +void printbin2(uint64_t val, unsigned int size); +void printstate(Hitag_State *hstate); +unsigned char hex2bin(unsigned char c); +int bitn(uint64_t x, int bit); +int fnR(uint64_t x); +void rollback(Hitag_State *hstate, unsigned int steps); +int fa(unsigned int i); +int fb(unsigned int i); +int fc(unsigned int i); +int fnf(uint64_t s); +void buildlfsr(Hitag_State *hstate); diff --git a/tools/hitag2crack/crack5/ht2crack5.c b/tools/hitag2crack/crack5/ht2crack5.c new file mode 100644 index 000000000..38e57ffa7 --- /dev/null +++ b/tools/hitag2crack/crack5/ht2crack5.c @@ -0,0 +1,751 @@ +/* ht2crack5.c + * + * This code is heavily based on the HiTag2 Hell CPU implementation + * from https://github.com/factoritbv/hitag2hell by FactorIT B.V., + * with the following changes: + * * Main takes a UID and 2 {nR},{aR} pairs as arguments + * and searches for states producing the first aR sample, + * reconstructs the corresponding key candidates + * and tests them against the second nR,aR pair; + * * Reuses the Hitag helping functions of the other attacks. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "ht2crack2utils.h" + +const uint8_t bits[9] = {20, 14, 4, 3, 1, 1, 1, 1, 1}; +#define lfsr_inv(state) (((state)<<1) | (__builtin_parityll((state) & ((0xce0044c101cd>>1)|(1ull<<(47)))))) +#define i4(x,a,b,c,d) ((uint32_t)((((x)>>(a))&1)<<3)|(((x)>>(b))&1)<<2|(((x)>>(c))&1)<<1|(((x)>>(d))&1)) +#define f(state) ((0xdd3929b >> ( (((0x3c65 >> i4(state, 2, 3, 5, 6) ) & 1) <<4) \ + | ((( 0xee5 >> i4(state, 8,12,14,15) ) & 1) <<3) \ + | ((( 0xee5 >> i4(state,17,21,23,26) ) & 1) <<2) \ + | ((( 0xee5 >> i4(state,28,29,31,33) ) & 1) <<1) \ + | (((0x3c65 >> i4(state,34,43,44,46) ) & 1) ))) & 1) + +#define MAX_BITSLICES 256 +#define VECTOR_SIZE (MAX_BITSLICES/8) + +typedef unsigned int __attribute__((aligned(VECTOR_SIZE))) __attribute__((vector_size(VECTOR_SIZE))) bitslice_value_t; +typedef union { + bitslice_value_t value; + uint64_t bytes64[MAX_BITSLICES / 64]; + uint8_t bytes[MAX_BITSLICES / 8]; +} bitslice_t; + +// we never actually set or use the lowest 2 bits the initial state, so we can save 2 bitslices everywhere +__thread bitslice_t state[-2 + 32 + 48]; + +bitslice_t keystream[32]; +bitslice_t bs_zeroes, bs_ones; + +#define f_a_bs(a,b,c,d) (~(((a|b)&c)^(a|d)^b)) // 6 ops +#define f_b_bs(a,b,c,d) (~(((d|c)&(a^b))^(d|a|b))) // 7 ops +#define f_c_bs(a,b,c,d,e) (~((((((c^e)|d)&a)^b)&(c^b))^(((d^e)|a)&((d^b)|c)))) // 13 ops +#define lfsr_bs(i) (state[-2+i+ 0].value ^ state[-2+i+ 2].value ^ state[-2+i+ 3].value ^ state[-2+i+ 6].value ^ \ + state[-2+i+ 7].value ^ state[-2+i+ 8].value ^ state[-2+i+16].value ^ state[-2+i+22].value ^ \ + state[-2+i+23].value ^ state[-2+i+26].value ^ state[-2+i+30].value ^ state[-2+i+41].value ^ \ + state[-2+i+42].value ^ state[-2+i+43].value ^ state[-2+i+46].value ^ state[-2+i+47].value); +#define get_bit(n, word) ((word >> (n)) & 1) +#define get_vector_bit(slice, value) get_bit(slice&0x3f, value.bytes64[slice>>6]) + +const uint64_t expand(uint64_t mask, uint64_t value) { + uint64_t fill = 0; + for (uint64_t bit_index = 0; bit_index < 48; bit_index++) { + if (mask & 1) { + fill |= (value & 1) << bit_index; + value >>= 1; + } + mask >>= 1; + } + return fill; +} + +void bitslice(const uint64_t value, bitslice_t *restrict bitsliced_value, const size_t bit_len, bool reverse) { + size_t bit_idx; + for (bit_idx = 0; bit_idx < bit_len; bit_idx++) { + bool bit; + if (reverse) { + bit = get_bit(bit_len - 1 - bit_idx, value); + } else { + bit = get_bit(bit_idx, value); + } + if (bit) { + bitsliced_value[bit_idx].value = bs_ones.value; + } else { + bitsliced_value[bit_idx].value = bs_zeroes.value; + } + } +} + +const uint64_t unbitslice(const bitslice_t *restrict b, const uint8_t s, const uint8_t n) { + uint64_t result = 0; + for (uint8_t i = 0; i < n; ++i) { + result <<= 1; + result |= get_vector_bit(s, b[n - 1 - i]); + } + return result; +} + +uint32_t uid, nR1, aR1, nR2, aR2; + +uint64_t candidates[(1 << 20)]; +bitslice_t initial_bitslices[48]; +size_t filter_pos[20] = {4, 7, 9, 13, 16, 18, 22, 24, 27, 30, 32, 35, 45, 47 }; +size_t thread_count = 8; +size_t layer_0_found; +void *find_state(void *thread_d); +static void try_state(uint64_t s); + +int main(int argc, char *argv[]) { + // set constants + memset(bs_ones.bytes, 0xff, VECTOR_SIZE); + memset(bs_zeroes.bytes, 0x00, VECTOR_SIZE); + + uint32_t target = 0; + + if (argc < 6) { + printf("%s UID {nR1} {aR1} {nR2} {aR2}\n", argv[0]); + exit(1); + } + + if (!strncmp(argv[1], "0x", 2) || !strncmp(argv[1], "0X", 2)) { + uid = rev32(hexreversetoulong(argv[1] + 2)); + } else { + uid = rev32(hexreversetoulong(argv[1])); + } + + if (!strncmp(argv[2], "0x", 2) || !strncmp(argv[2], "0X", 2)) { + nR1 = rev32(hexreversetoulong(argv[2] + 2)); + } else { + nR1 = rev32(hexreversetoulong(argv[2])); + } + + aR1 = strtol(argv[3], NULL, 16); + + if (!strncmp(argv[4], "0x", 2) || !strncmp(argv[4], "0X", 2)) { + nR2 = rev32(hexreversetoulong(argv[4] + 2)); + } else { + nR2 = rev32(hexreversetoulong(argv[4])); + } + + aR2 = strtol(argv[5], NULL, 16); + + target = ~aR1; + // bitslice inverse target bits + bitslice(~target, keystream, 32, true); + + // bitslice all possible 256 values in the lowest 8 bits + memset(initial_bitslices[0].bytes, 0xaa, VECTOR_SIZE); + memset(initial_bitslices[1].bytes, 0xcc, VECTOR_SIZE); + memset(initial_bitslices[2].bytes, 0xf0, VECTOR_SIZE); + size_t interval = 1; + for (size_t bit = 3; bit < 8; bit++) { + for (size_t byte = 0; byte < VECTOR_SIZE;) { + for (size_t length = 0; length < interval; length++) { + initial_bitslices[bit].bytes[byte++] = 0x00; + } + for (size_t length = 0; length < interval; length++) { + initial_bitslices[bit].bytes[byte++] = 0xff; + } + } + interval <<= 1; + } + + // compute layer 0 output + for (size_t i0 = 0; i0 < 1 << 20; i0++) { + uint64_t state0 = expand(0x5806b4a2d16c, i0); + + if (f(state0) == target >> 31) { + candidates[layer_0_found++] = state0; + } + } + + // start threads and wait on them + pthread_t thread_handles[thread_count]; + for (size_t thread = 0; thread < thread_count; thread++) { + pthread_create(&thread_handles[thread], NULL, find_state, (void *) thread); + } + for (size_t thread = 0; thread < thread_count; thread++) { + pthread_join(thread_handles[thread], NULL); + } + + printf("Key not found\n"); + exit(1); +} + +void *find_state(void *thread_d) { + size_t thread = (size_t)thread_d; + + for (size_t index = thread; index < layer_0_found; index += thread_count) { + if (((index / thread_count) & 0xFF) == 0) + printf("Thread %lu slice %lu/%lu\n", thread, index / thread_count / 256 + 1, layer_0_found / thread_count / 256); + uint64_t state0 = candidates[index]; + bitslice(state0 >> 2, &state[0], 46, false); + for (size_t bit = 0; bit < 8; bit++) { + state[-2 + filter_pos[bit]] = initial_bitslices[bit]; + } + for (uint16_t i1 = 0; i1 < (1 << (bits[1] + 1) >> 8); i1++) { + state[-2 + 27].value = ((bool)(i1 & 0x1)) ? bs_ones.value : bs_zeroes.value; + state[-2 + 30].value = ((bool)(i1 & 0x2)) ? bs_ones.value : bs_zeroes.value; + state[-2 + 32].value = ((bool)(i1 & 0x4)) ? bs_ones.value : bs_zeroes.value; + state[-2 + 35].value = ((bool)(i1 & 0x8)) ? bs_ones.value : bs_zeroes.value; + state[-2 + 45].value = ((bool)(i1 & 0x10)) ? bs_ones.value : bs_zeroes.value; + state[-2 + 47].value = ((bool)(i1 & 0x20)) ? bs_ones.value : bs_zeroes.value; + state[-2 + 48].value = ((bool)(i1 & 0x40)) ? bs_ones.value : bs_zeroes.value; // guess lfsr output 0 + // 0xfc07fef3f9fe + const bitslice_value_t filter1_0 = f_a_bs(state[-2 + 3].value, state[-2 + 4].value, state[-2 + 6].value, state[-2 + 7].value); + const bitslice_value_t filter1_1 = f_b_bs(state[-2 + 9].value, state[-2 + 13].value, state[-2 + 15].value, state[-2 + 16].value); + const bitslice_value_t filter1_2 = f_b_bs(state[-2 + 18].value, state[-2 + 22].value, state[-2 + 24].value, state[-2 + 27].value); + const bitslice_value_t filter1_3 = f_b_bs(state[-2 + 29].value, state[-2 + 30].value, state[-2 + 32].value, state[-2 + 34].value); + const bitslice_value_t filter1_4 = f_a_bs(state[-2 + 35].value, state[-2 + 44].value, state[-2 + 45].value, state[-2 + 47].value); + const bitslice_value_t filter1 = f_c_bs(filter1_0, filter1_1, filter1_2, filter1_3, filter1_4); + bitslice_t results1; + results1.value = filter1 ^ keystream[1].value; + if (results1.bytes64[0] == 0 + && results1.bytes64[1] == 0 + && results1.bytes64[2] == 0 + && results1.bytes64[3] == 0 + ) { + continue; + } + const bitslice_value_t filter2_0 = f_a_bs(state[-2 + 4].value, state[-2 + 5].value, state[-2 + 7].value, state[-2 + 8].value); + const bitslice_value_t filter2_3 = f_b_bs(state[-2 + 30].value, state[-2 + 31].value, state[-2 + 33].value, state[-2 + 35].value); + const bitslice_value_t filter3_0 = f_a_bs(state[-2 + 5].value, state[-2 + 6].value, state[-2 + 8].value, state[-2 + 9].value); + const bitslice_value_t filter5_2 = f_b_bs(state[-2 + 22].value, state[-2 + 26].value, state[-2 + 28].value, state[-2 + 31].value); + const bitslice_value_t filter6_2 = f_b_bs(state[-2 + 23].value, state[-2 + 27].value, state[-2 + 29].value, state[-2 + 32].value); + const bitslice_value_t filter7_2 = f_b_bs(state[-2 + 24].value, state[-2 + 28].value, state[-2 + 30].value, state[-2 + 33].value); + const bitslice_value_t filter9_1 = f_b_bs(state[-2 + 17].value, state[-2 + 21].value, state[-2 + 23].value, state[-2 + 24].value); + const bitslice_value_t filter9_2 = f_b_bs(state[-2 + 26].value, state[-2 + 30].value, state[-2 + 32].value, state[-2 + 35].value); + const bitslice_value_t filter10_0 = f_a_bs(state[-2 + 12].value, state[-2 + 13].value, state[-2 + 15].value, state[-2 + 16].value); + const bitslice_value_t filter11_0 = f_a_bs(state[-2 + 13].value, state[-2 + 14].value, state[-2 + 16].value, state[-2 + 17].value); + const bitslice_value_t filter12_0 = f_a_bs(state[-2 + 14].value, state[-2 + 15].value, state[-2 + 17].value, state[-2 + 18].value); + for (uint16_t i2 = 0; i2 < (1 << (bits[2] + 1)); i2++) { + state[-2 + 10].value = ((bool)(i2 & 0x1)) ? bs_ones.value : bs_zeroes.value; + state[-2 + 19].value = ((bool)(i2 & 0x2)) ? bs_ones.value : bs_zeroes.value; + state[-2 + 25].value = ((bool)(i2 & 0x4)) ? bs_ones.value : bs_zeroes.value; + state[-2 + 36].value = ((bool)(i2 & 0x8)) ? bs_ones.value : bs_zeroes.value; + state[-2 + 49].value = ((bool)(i2 & 0x10)) ? bs_ones.value : bs_zeroes.value; // guess lfsr output 1 + // 0xfe07fffbfdff + const bitslice_value_t filter2_1 = f_b_bs(state[-2 + 10].value, state[-2 + 14].value, state[-2 + 16].value, state[-2 + 17].value); + const bitslice_value_t filter2_2 = f_b_bs(state[-2 + 19].value, state[-2 + 23].value, state[-2 + 25].value, state[-2 + 28].value); + const bitslice_value_t filter2_4 = f_a_bs(state[-2 + 36].value, state[-2 + 45].value, state[-2 + 46].value, state[-2 + 48].value); + const bitslice_value_t filter2 = f_c_bs(filter2_0, filter2_1, filter2_2, filter2_3, filter2_4); + bitslice_t results2; + results2.value = results1.value & (filter2 ^ keystream[2].value); + if (results2.bytes64[0] == 0 + && results2.bytes64[1] == 0 + && results2.bytes64[2] == 0 + && results2.bytes64[3] == 0 + ) { + continue; + } + state[-2 + 50].value = lfsr_bs(2); + const bitslice_value_t filter3_3 = f_b_bs(state[-2 + 31].value, state[-2 + 32].value, state[-2 + 34].value, state[-2 + 36].value); + const bitslice_value_t filter4_0 = f_a_bs(state[-2 + 6].value, state[-2 + 7].value, state[-2 + 9].value, state[-2 + 10].value); + const bitslice_value_t filter4_1 = f_b_bs(state[-2 + 12].value, state[-2 + 16].value, state[-2 + 18].value, state[-2 + 19].value); + const bitslice_value_t filter4_2 = f_b_bs(state[-2 + 21].value, state[-2 + 25].value, state[-2 + 27].value, state[-2 + 30].value); + const bitslice_value_t filter7_0 = f_a_bs(state[-2 + 9].value, state[-2 + 10].value, state[-2 + 12].value, state[-2 + 13].value); + const bitslice_value_t filter7_1 = f_b_bs(state[-2 + 15].value, state[-2 + 19].value, state[-2 + 21].value, state[-2 + 22].value); + const bitslice_value_t filter8_2 = f_b_bs(state[-2 + 25].value, state[-2 + 29].value, state[-2 + 31].value, state[-2 + 34].value); + const bitslice_value_t filter10_1 = f_b_bs(state[-2 + 18].value, state[-2 + 22].value, state[-2 + 24].value, state[-2 + 25].value); + const bitslice_value_t filter10_2 = f_b_bs(state[-2 + 27].value, state[-2 + 31].value, state[-2 + 33].value, state[-2 + 36].value); + const bitslice_value_t filter11_1 = f_b_bs(state[-2 + 19].value, state[-2 + 23].value, state[-2 + 25].value, state[-2 + 26].value); + for (uint8_t i3 = 0; i3 < (1 << bits[3]); i3++) { + state[-2 + 11].value = ((bool)(i3 & 0x1)) ? bs_ones.value : bs_zeroes.value; + state[-2 + 20].value = ((bool)(i3 & 0x2)) ? bs_ones.value : bs_zeroes.value; + state[-2 + 37].value = ((bool)(i3 & 0x4)) ? bs_ones.value : bs_zeroes.value; + // 0xff07ffffffff + const bitslice_value_t filter3_1 = f_b_bs(state[-2 + 11].value, state[-2 + 15].value, state[-2 + 17].value, state[-2 + 18].value); + const bitslice_value_t filter3_2 = f_b_bs(state[-2 + 20].value, state[-2 + 24].value, state[-2 + 26].value, state[-2 + 29].value); + const bitslice_value_t filter3_4 = f_a_bs(state[-2 + 37].value, state[-2 + 46].value, state[-2 + 47].value, state[-2 + 49].value); + const bitslice_value_t filter3 = f_c_bs(filter3_0, filter3_1, filter3_2, filter3_3, filter3_4); + bitslice_t results3; + results3.value = results2.value & (filter3 ^ keystream[3].value); + if (results3.bytes64[0] == 0 + && results3.bytes64[1] == 0 + && results3.bytes64[2] == 0 + && results3.bytes64[3] == 0 + ) { + continue; + } + state[-2 + 51].value = lfsr_bs(3); + state[-2 + 52].value = lfsr_bs(4); + state[-2 + 53].value = lfsr_bs(5); + state[-2 + 54].value = lfsr_bs(6); + state[-2 + 55].value = lfsr_bs(7); + const bitslice_value_t filter4_3 = f_b_bs(state[-2 + 32].value, state[-2 + 33].value, state[-2 + 35].value, state[-2 + 37].value); + const bitslice_value_t filter5_0 = f_a_bs(state[-2 + 7].value, state[-2 + 8].value, state[-2 + 10].value, state[-2 + 11].value); + const bitslice_value_t filter5_1 = f_b_bs(state[-2 + 13].value, state[-2 + 17].value, state[-2 + 19].value, state[-2 + 20].value); + const bitslice_value_t filter6_0 = f_a_bs(state[-2 + 8].value, state[-2 + 9].value, state[-2 + 11].value, state[-2 + 12].value); + const bitslice_value_t filter6_1 = f_b_bs(state[-2 + 14].value, state[-2 + 18].value, state[-2 + 20].value, state[-2 + 21].value); + const bitslice_value_t filter8_0 = f_a_bs(state[-2 + 10].value, state[-2 + 11].value, state[-2 + 13].value, state[-2 + 14].value); + const bitslice_value_t filter8_1 = f_b_bs(state[-2 + 16].value, state[-2 + 20].value, state[-2 + 22].value, state[-2 + 23].value); + const bitslice_value_t filter9_0 = f_a_bs(state[-2 + 11].value, state[-2 + 12].value, state[-2 + 14].value, state[-2 + 15].value); + const bitslice_value_t filter9_4 = f_a_bs(state[-2 + 43].value, state[-2 + 52].value, state[-2 + 53].value, state[-2 + 55].value); + const bitslice_value_t filter11_2 = f_b_bs(state[-2 + 28].value, state[-2 + 32].value, state[-2 + 34].value, state[-2 + 37].value); + const bitslice_value_t filter12_1 = f_b_bs(state[-2 + 20].value, state[-2 + 24].value, state[-2 + 26].value, state[-2 + 27].value); + for (uint8_t i4 = 0; i4 < (1 << bits[4]); i4++) { + state[-2 + 38].value = ((bool)(i4 & 0x1)) ? bs_ones.value : bs_zeroes.value; + // 0xff87ffffffff + const bitslice_value_t filter4_4 = f_a_bs(state[-2 + 38].value, state[-2 + 47].value, state[-2 + 48].value, state[-2 + 50].value); + const bitslice_value_t filter4 = f_c_bs(filter4_0, filter4_1, filter4_2, filter4_3, filter4_4); + bitslice_t results4; + results4.value = results3.value & (filter4 ^ keystream[4].value); + if (results4.bytes64[0] == 0 + && results4.bytes64[1] == 0 + && results4.bytes64[2] == 0 + && results4.bytes64[3] == 0 + ) { + continue; + } + const bitslice_value_t filter5_3 = f_b_bs(state[-2 + 33].value, state[-2 + 34].value, state[-2 + 36].value, state[-2 + 38].value); + const bitslice_value_t filter12_2 = f_b_bs(state[-2 + 29].value, state[-2 + 33].value, state[-2 + 35].value, state[-2 + 38].value); + for (uint8_t i5 = 0; i5 < (1 << bits[5]); i5++) { + state[-2 + 39].value = ((bool)(i5 & 0x1)) ? bs_ones.value : bs_zeroes.value; + // 0xffc7ffffffff + const bitslice_value_t filter5_4 = f_a_bs(state[-2 + 39].value, state[-2 + 48].value, state[-2 + 49].value, state[-2 + 51].value); + const bitslice_value_t filter5 = f_c_bs(filter5_0, filter5_1, filter5_2, filter5_3, filter5_4); + bitslice_t results5; + results5.value = results4.value & (filter5 ^ keystream[5].value); + if (results5.bytes64[0] == 0 + && results5.bytes64[1] == 0 + && results5.bytes64[2] == 0 + && results5.bytes64[3] == 0 + ) { + continue; + } + const bitslice_value_t filter6_3 = f_b_bs(state[-2 + 34].value, state[-2 + 35].value, state[-2 + 37].value, state[-2 + 39].value); + for (uint8_t i6 = 0; i6 < (1 << bits[6]); i6++) { + state[-2 + 40].value = ((bool)(i6 & 0x1)) ? bs_ones.value : bs_zeroes.value; + // 0xffe7ffffffff + const bitslice_value_t filter6_4 = f_a_bs(state[-2 + 40].value, state[-2 + 49].value, state[-2 + 50].value, state[-2 + 52].value); + const bitslice_value_t filter6 = f_c_bs(filter6_0, filter6_1, filter6_2, filter6_3, filter6_4); + bitslice_t results6; + results6.value = results5.value & (filter6 ^ keystream[6].value); + if (results6.bytes64[0] == 0 + && results6.bytes64[1] == 0 + && results6.bytes64[2] == 0 + && results6.bytes64[3] == 0 + ) { + continue; + } + const bitslice_value_t filter7_3 = f_b_bs(state[-2 + 35].value, state[-2 + 36].value, state[-2 + 38].value, state[-2 + 40].value); + for (uint8_t i7 = 0; i7 < (1 << bits[7]); i7++) { + state[-2 + 41].value = ((bool)(i7 & 0x1)) ? bs_ones.value : bs_zeroes.value; + // 0xfff7ffffffff + const bitslice_value_t filter7_4 = f_a_bs(state[-2 + 41].value, state[-2 + 50].value, state[-2 + 51].value, state[-2 + 53].value); + const bitslice_value_t filter7 = f_c_bs(filter7_0, filter7_1, filter7_2, filter7_3, filter7_4); + bitslice_t results7; + results7.value = results6.value & (filter7 ^ keystream[7].value); + if (results7.bytes64[0] == 0 + && results7.bytes64[1] == 0 + && results7.bytes64[2] == 0 + && results7.bytes64[3] == 0 + ) { + continue; + } + const bitslice_value_t filter8_3 = f_b_bs(state[-2 + 36].value, state[-2 + 37].value, state[-2 + 39].value, state[-2 + 41].value); + const bitslice_value_t filter10_3 = f_b_bs(state[-2 + 38].value, state[-2 + 39].value, state[-2 + 41].value, state[-2 + 43].value); + const bitslice_value_t filter12_3 = f_b_bs(state[-2 + 40].value, state[-2 + 41].value, state[-2 + 43].value, state[-2 + 45].value); + for (uint8_t i8 = 0; i8 < (1 << bits[8]); i8++) { + state[-2 + 42].value = ((bool)(i8 & 0x1)) ? bs_ones.value : bs_zeroes.value; + // 0xffffffffffff + const bitslice_value_t filter8_4 = f_a_bs(state[-2 + 42].value, state[-2 + 51].value, state[-2 + 52].value, state[-2 + 54].value); + const bitslice_value_t filter9_3 = f_b_bs(state[-2 + 37].value, state[-2 + 38].value, state[-2 + 40].value, state[-2 + 42].value); + const bitslice_value_t filter11_3 = f_b_bs(state[-2 + 39].value, state[-2 + 40].value, state[-2 + 42].value, state[-2 + 44].value); + const bitslice_value_t filter8 = f_c_bs(filter8_0, filter8_1, filter8_2, filter8_3, filter8_4); + bitslice_t results8; + results8.value = results7.value & (filter8 ^ keystream[8].value); + if (results8.bytes64[0] == 0 + && results8.bytes64[1] == 0 + && results8.bytes64[2] == 0 + && results8.bytes64[3] == 0 + ) { + continue; + } + const bitslice_value_t filter9 = f_c_bs(filter9_0, filter9_1, filter9_2, filter9_3, filter9_4); + results8.value &= (filter9 ^ keystream[9].value); + if (results8.bytes64[0] == 0 + && results8.bytes64[1] == 0 + && results8.bytes64[2] == 0 + && results8.bytes64[3] == 0 + ) { + continue; + } + state[-2 + 56].value = lfsr_bs(8); + const bitslice_value_t filter10_4 = f_a_bs(state[-2 + 44].value, state[-2 + 53].value, state[-2 + 54].value, state[-2 + 56].value); + const bitslice_value_t filter10 = f_c_bs(filter10_0, filter10_1, filter10_2, filter10_3, filter10_4); + results8.value &= (filter10 ^ keystream[10].value); + if (results8.bytes64[0] == 0 + && results8.bytes64[1] == 0 + && results8.bytes64[2] == 0 + && results8.bytes64[3] == 0 + ) { + continue; + } + state[-2 + 57].value = lfsr_bs(9); + const bitslice_value_t filter11_4 = f_a_bs(state[-2 + 45].value, state[-2 + 54].value, state[-2 + 55].value, state[-2 + 57].value); + const bitslice_value_t filter11 = f_c_bs(filter11_0, filter11_1, filter11_2, filter11_3, filter11_4); + results8.value &= (filter11 ^ keystream[11].value); + if (results8.bytes64[0] == 0 + && results8.bytes64[1] == 0 + && results8.bytes64[2] == 0 + && results8.bytes64[3] == 0 + ) { + continue; + } + state[-2 + 58].value = lfsr_bs(10); + const bitslice_value_t filter12_4 = f_a_bs(state[-2 + 46].value, state[-2 + 55].value, state[-2 + 56].value, state[-2 + 58].value); + const bitslice_value_t filter12 = f_c_bs(filter12_0, filter12_1, filter12_2, filter12_3, filter12_4); + results8.value &= (filter12 ^ keystream[12].value); + if (results8.bytes64[0] == 0 + && results8.bytes64[1] == 0 + && results8.bytes64[2] == 0 + && results8.bytes64[3] == 0 + ) { + continue; + } + state[-2 + 59].value = lfsr_bs(11); + const bitslice_value_t filter13_0 = f_a_bs(state[-2 + 15].value, state[-2 + 16].value, state[-2 + 18].value, state[-2 + 19].value); + const bitslice_value_t filter13_1 = f_b_bs(state[-2 + 21].value, state[-2 + 25].value, state[-2 + 27].value, state[-2 + 28].value); + const bitslice_value_t filter13_2 = f_b_bs(state[-2 + 30].value, state[-2 + 34].value, state[-2 + 36].value, state[-2 + 39].value); + const bitslice_value_t filter13_3 = f_b_bs(state[-2 + 41].value, state[-2 + 42].value, state[-2 + 44].value, state[-2 + 46].value); + const bitslice_value_t filter13_4 = f_a_bs(state[-2 + 47].value, state[-2 + 56].value, state[-2 + 57].value, state[-2 + 59].value); + const bitslice_value_t filter13 = f_c_bs(filter13_0, filter13_1, filter13_2, filter13_3, filter13_4); + results8.value &= (filter13 ^ keystream[13].value); + if (results8.bytes64[0] == 0 + && results8.bytes64[1] == 0 + && results8.bytes64[2] == 0 + && results8.bytes64[3] == 0 + ) { + continue; + } + state[-2 + 60].value = lfsr_bs(12); + const bitslice_value_t filter14_0 = f_a_bs(state[-2 + 16].value, state[-2 + 17].value, state[-2 + 19].value, state[-2 + 20].value); + const bitslice_value_t filter14_1 = f_b_bs(state[-2 + 22].value, state[-2 + 26].value, state[-2 + 28].value, state[-2 + 29].value); + const bitslice_value_t filter14_2 = f_b_bs(state[-2 + 31].value, state[-2 + 35].value, state[-2 + 37].value, state[-2 + 40].value); + const bitslice_value_t filter14_3 = f_b_bs(state[-2 + 42].value, state[-2 + 43].value, state[-2 + 45].value, state[-2 + 47].value); + const bitslice_value_t filter14_4 = f_a_bs(state[-2 + 48].value, state[-2 + 57].value, state[-2 + 58].value, state[-2 + 60].value); + const bitslice_value_t filter14 = f_c_bs(filter14_0, filter14_1, filter14_2, filter14_3, filter14_4); + results8.value &= (filter14 ^ keystream[14].value); + if (results8.bytes64[0] == 0 + && results8.bytes64[1] == 0 + && results8.bytes64[2] == 0 + && results8.bytes64[3] == 0 + ) { + continue; + } + state[-2 + 61].value = lfsr_bs(13); + const bitslice_value_t filter15_0 = f_a_bs(state[-2 + 17].value, state[-2 + 18].value, state[-2 + 20].value, state[-2 + 21].value); + const bitslice_value_t filter15_1 = f_b_bs(state[-2 + 23].value, state[-2 + 27].value, state[-2 + 29].value, state[-2 + 30].value); + const bitslice_value_t filter15_2 = f_b_bs(state[-2 + 32].value, state[-2 + 36].value, state[-2 + 38].value, state[-2 + 41].value); + const bitslice_value_t filter15_3 = f_b_bs(state[-2 + 43].value, state[-2 + 44].value, state[-2 + 46].value, state[-2 + 48].value); + const bitslice_value_t filter15_4 = f_a_bs(state[-2 + 49].value, state[-2 + 58].value, state[-2 + 59].value, state[-2 + 61].value); + const bitslice_value_t filter15 = f_c_bs(filter15_0, filter15_1, filter15_2, filter15_3, filter15_4); + results8.value &= (filter15 ^ keystream[15].value); + if (results8.bytes64[0] == 0 + && results8.bytes64[1] == 0 + && results8.bytes64[2] == 0 + && results8.bytes64[3] == 0 + ) { + continue; + } + state[-2 + 62].value = lfsr_bs(14); + const bitslice_value_t filter16_0 = f_a_bs(state[-2 + 18].value, state[-2 + 19].value, state[-2 + 21].value, state[-2 + 22].value); + const bitslice_value_t filter16_1 = f_b_bs(state[-2 + 24].value, state[-2 + 28].value, state[-2 + 30].value, state[-2 + 31].value); + const bitslice_value_t filter16_2 = f_b_bs(state[-2 + 33].value, state[-2 + 37].value, state[-2 + 39].value, state[-2 + 42].value); + const bitslice_value_t filter16_3 = f_b_bs(state[-2 + 44].value, state[-2 + 45].value, state[-2 + 47].value, state[-2 + 49].value); + const bitslice_value_t filter16_4 = f_a_bs(state[-2 + 50].value, state[-2 + 59].value, state[-2 + 60].value, state[-2 + 62].value); + const bitslice_value_t filter16 = f_c_bs(filter16_0, filter16_1, filter16_2, filter16_3, filter16_4); + results8.value &= (filter16 ^ keystream[16].value); + if (results8.bytes64[0] == 0 + && results8.bytes64[1] == 0 + && results8.bytes64[2] == 0 + && results8.bytes64[3] == 0 + ) { + continue; + } + state[-2 + 63].value = lfsr_bs(15); + const bitslice_value_t filter17_0 = f_a_bs(state[-2 + 19].value, state[-2 + 20].value, state[-2 + 22].value, state[-2 + 23].value); + const bitslice_value_t filter17_1 = f_b_bs(state[-2 + 25].value, state[-2 + 29].value, state[-2 + 31].value, state[-2 + 32].value); + const bitslice_value_t filter17_2 = f_b_bs(state[-2 + 34].value, state[-2 + 38].value, state[-2 + 40].value, state[-2 + 43].value); + const bitslice_value_t filter17_3 = f_b_bs(state[-2 + 45].value, state[-2 + 46].value, state[-2 + 48].value, state[-2 + 50].value); + const bitslice_value_t filter17_4 = f_a_bs(state[-2 + 51].value, state[-2 + 60].value, state[-2 + 61].value, state[-2 + 63].value); + const bitslice_value_t filter17 = f_c_bs(filter17_0, filter17_1, filter17_2, filter17_3, filter17_4); + results8.value &= (filter17 ^ keystream[17].value); + if (results8.bytes64[0] == 0 + && results8.bytes64[1] == 0 + && results8.bytes64[2] == 0 + && results8.bytes64[3] == 0 + ) { + continue; + } + state[-2 + 64].value = lfsr_bs(16); + const bitslice_value_t filter18_0 = f_a_bs(state[-2 + 20].value, state[-2 + 21].value, state[-2 + 23].value, state[-2 + 24].value); + const bitslice_value_t filter18_1 = f_b_bs(state[-2 + 26].value, state[-2 + 30].value, state[-2 + 32].value, state[-2 + 33].value); + const bitslice_value_t filter18_2 = f_b_bs(state[-2 + 35].value, state[-2 + 39].value, state[-2 + 41].value, state[-2 + 44].value); + const bitslice_value_t filter18_3 = f_b_bs(state[-2 + 46].value, state[-2 + 47].value, state[-2 + 49].value, state[-2 + 51].value); + const bitslice_value_t filter18_4 = f_a_bs(state[-2 + 52].value, state[-2 + 61].value, state[-2 + 62].value, state[-2 + 64].value); + const bitslice_value_t filter18 = f_c_bs(filter18_0, filter18_1, filter18_2, filter18_3, filter18_4); + results8.value &= (filter18 ^ keystream[18].value); + if (results8.bytes64[0] == 0 + && results8.bytes64[1] == 0 + && results8.bytes64[2] == 0 + && results8.bytes64[3] == 0 + ) { + continue; + } + state[-2 + 65].value = lfsr_bs(17); + const bitslice_value_t filter19_0 = f_a_bs(state[-2 + 21].value, state[-2 + 22].value, state[-2 + 24].value, state[-2 + 25].value); + const bitslice_value_t filter19_1 = f_b_bs(state[-2 + 27].value, state[-2 + 31].value, state[-2 + 33].value, state[-2 + 34].value); + const bitslice_value_t filter19_2 = f_b_bs(state[-2 + 36].value, state[-2 + 40].value, state[-2 + 42].value, state[-2 + 45].value); + const bitslice_value_t filter19_3 = f_b_bs(state[-2 + 47].value, state[-2 + 48].value, state[-2 + 50].value, state[-2 + 52].value); + const bitslice_value_t filter19_4 = f_a_bs(state[-2 + 53].value, state[-2 + 62].value, state[-2 + 63].value, state[-2 + 65].value); + const bitslice_value_t filter19 = f_c_bs(filter19_0, filter19_1, filter19_2, filter19_3, filter19_4); + results8.value &= (filter19 ^ keystream[19].value); + if (results8.bytes64[0] == 0 + && results8.bytes64[1] == 0 + && results8.bytes64[2] == 0 + && results8.bytes64[3] == 0 + ) { + continue; + } + state[-2 + 66].value = lfsr_bs(18); + const bitslice_value_t filter20_0 = f_a_bs(state[-2 + 22].value, state[-2 + 23].value, state[-2 + 25].value, state[-2 + 26].value); + const bitslice_value_t filter20_1 = f_b_bs(state[-2 + 28].value, state[-2 + 32].value, state[-2 + 34].value, state[-2 + 35].value); + const bitslice_value_t filter20_2 = f_b_bs(state[-2 + 37].value, state[-2 + 41].value, state[-2 + 43].value, state[-2 + 46].value); + const bitslice_value_t filter20_3 = f_b_bs(state[-2 + 48].value, state[-2 + 49].value, state[-2 + 51].value, state[-2 + 53].value); + const bitslice_value_t filter20_4 = f_a_bs(state[-2 + 54].value, state[-2 + 63].value, state[-2 + 64].value, state[-2 + 66].value); + const bitslice_value_t filter20 = f_c_bs(filter20_0, filter20_1, filter20_2, filter20_3, filter20_4); + results8.value &= (filter20 ^ keystream[20].value); + if (results8.bytes64[0] == 0 + && results8.bytes64[1] == 0 + && results8.bytes64[2] == 0 + && results8.bytes64[3] == 0 + ) { + continue; + } + state[-2 + 67].value = lfsr_bs(19); + const bitslice_value_t filter21_0 = f_a_bs(state[-2 + 23].value, state[-2 + 24].value, state[-2 + 26].value, state[-2 + 27].value); + const bitslice_value_t filter21_1 = f_b_bs(state[-2 + 29].value, state[-2 + 33].value, state[-2 + 35].value, state[-2 + 36].value); + const bitslice_value_t filter21_2 = f_b_bs(state[-2 + 38].value, state[-2 + 42].value, state[-2 + 44].value, state[-2 + 47].value); + const bitslice_value_t filter21_3 = f_b_bs(state[-2 + 49].value, state[-2 + 50].value, state[-2 + 52].value, state[-2 + 54].value); + const bitslice_value_t filter21_4 = f_a_bs(state[-2 + 55].value, state[-2 + 64].value, state[-2 + 65].value, state[-2 + 67].value); + const bitslice_value_t filter21 = f_c_bs(filter21_0, filter21_1, filter21_2, filter21_3, filter21_4); + results8.value &= (filter21 ^ keystream[21].value); + if (results8.bytes64[0] == 0 + && results8.bytes64[1] == 0 + && results8.bytes64[2] == 0 + && results8.bytes64[3] == 0 + ) { + continue; + } + state[-2 + 68].value = lfsr_bs(20); + const bitslice_value_t filter22_0 = f_a_bs(state[-2 + 24].value, state[-2 + 25].value, state[-2 + 27].value, state[-2 + 28].value); + const bitslice_value_t filter22_1 = f_b_bs(state[-2 + 30].value, state[-2 + 34].value, state[-2 + 36].value, state[-2 + 37].value); + const bitslice_value_t filter22_2 = f_b_bs(state[-2 + 39].value, state[-2 + 43].value, state[-2 + 45].value, state[-2 + 48].value); + const bitslice_value_t filter22_3 = f_b_bs(state[-2 + 50].value, state[-2 + 51].value, state[-2 + 53].value, state[-2 + 55].value); + const bitslice_value_t filter22_4 = f_a_bs(state[-2 + 56].value, state[-2 + 65].value, state[-2 + 66].value, state[-2 + 68].value); + const bitslice_value_t filter22 = f_c_bs(filter22_0, filter22_1, filter22_2, filter22_3, filter22_4); + results8.value &= (filter22 ^ keystream[22].value); + if (results8.bytes64[0] == 0 + && results8.bytes64[1] == 0 + && results8.bytes64[2] == 0 + && results8.bytes64[3] == 0 + ) { + continue; + } + state[-2 + 69].value = lfsr_bs(21); + const bitslice_value_t filter23_0 = f_a_bs(state[-2 + 25].value, state[-2 + 26].value, state[-2 + 28].value, state[-2 + 29].value); + const bitslice_value_t filter23_1 = f_b_bs(state[-2 + 31].value, state[-2 + 35].value, state[-2 + 37].value, state[-2 + 38].value); + const bitslice_value_t filter23_2 = f_b_bs(state[-2 + 40].value, state[-2 + 44].value, state[-2 + 46].value, state[-2 + 49].value); + const bitslice_value_t filter23_3 = f_b_bs(state[-2 + 51].value, state[-2 + 52].value, state[-2 + 54].value, state[-2 + 56].value); + const bitslice_value_t filter23_4 = f_a_bs(state[-2 + 57].value, state[-2 + 66].value, state[-2 + 67].value, state[-2 + 69].value); + const bitslice_value_t filter23 = f_c_bs(filter23_0, filter23_1, filter23_2, filter23_3, filter23_4); + results8.value &= (filter23 ^ keystream[23].value); + if (results8.bytes64[0] == 0 + && results8.bytes64[1] == 0 + && results8.bytes64[2] == 0 + && results8.bytes64[3] == 0 + ) { + continue; + } + state[-2 + 70].value = lfsr_bs(22); + const bitslice_value_t filter24_0 = f_a_bs(state[-2 + 26].value, state[-2 + 27].value, state[-2 + 29].value, state[-2 + 30].value); + const bitslice_value_t filter24_1 = f_b_bs(state[-2 + 32].value, state[-2 + 36].value, state[-2 + 38].value, state[-2 + 39].value); + const bitslice_value_t filter24_2 = f_b_bs(state[-2 + 41].value, state[-2 + 45].value, state[-2 + 47].value, state[-2 + 50].value); + const bitslice_value_t filter24_3 = f_b_bs(state[-2 + 52].value, state[-2 + 53].value, state[-2 + 55].value, state[-2 + 57].value); + const bitslice_value_t filter24_4 = f_a_bs(state[-2 + 58].value, state[-2 + 67].value, state[-2 + 68].value, state[-2 + 70].value); + const bitslice_value_t filter24 = f_c_bs(filter24_0, filter24_1, filter24_2, filter24_3, filter24_4); + results8.value &= (filter24 ^ keystream[24].value); + if (results8.bytes64[0] == 0 + && results8.bytes64[1] == 0 + && results8.bytes64[2] == 0 + && results8.bytes64[3] == 0 + ) { + continue; + } + state[-2 + 71].value = lfsr_bs(23); + const bitslice_value_t filter25_0 = f_a_bs(state[-2 + 27].value, state[-2 + 28].value, state[-2 + 30].value, state[-2 + 31].value); + const bitslice_value_t filter25_1 = f_b_bs(state[-2 + 33].value, state[-2 + 37].value, state[-2 + 39].value, state[-2 + 40].value); + const bitslice_value_t filter25_2 = f_b_bs(state[-2 + 42].value, state[-2 + 46].value, state[-2 + 48].value, state[-2 + 51].value); + const bitslice_value_t filter25_3 = f_b_bs(state[-2 + 53].value, state[-2 + 54].value, state[-2 + 56].value, state[-2 + 58].value); + const bitslice_value_t filter25_4 = f_a_bs(state[-2 + 59].value, state[-2 + 68].value, state[-2 + 69].value, state[-2 + 71].value); + const bitslice_value_t filter25 = f_c_bs(filter25_0, filter25_1, filter25_2, filter25_3, filter25_4); + results8.value &= (filter25 ^ keystream[25].value); + if (results8.bytes64[0] == 0 + && results8.bytes64[1] == 0 + && results8.bytes64[2] == 0 + && results8.bytes64[3] == 0 + ) { + continue; + } + state[-2 + 72].value = lfsr_bs(24); + const bitslice_value_t filter26_0 = f_a_bs(state[-2 + 28].value, state[-2 + 29].value, state[-2 + 31].value, state[-2 + 32].value); + const bitslice_value_t filter26_1 = f_b_bs(state[-2 + 34].value, state[-2 + 38].value, state[-2 + 40].value, state[-2 + 41].value); + const bitslice_value_t filter26_2 = f_b_bs(state[-2 + 43].value, state[-2 + 47].value, state[-2 + 49].value, state[-2 + 52].value); + const bitslice_value_t filter26_3 = f_b_bs(state[-2 + 54].value, state[-2 + 55].value, state[-2 + 57].value, state[-2 + 59].value); + const bitslice_value_t filter26_4 = f_a_bs(state[-2 + 60].value, state[-2 + 69].value, state[-2 + 70].value, state[-2 + 72].value); + const bitslice_value_t filter26 = f_c_bs(filter26_0, filter26_1, filter26_2, filter26_3, filter26_4); + results8.value &= (filter26 ^ keystream[26].value); + if (results8.bytes64[0] == 0 + && results8.bytes64[1] == 0 + && results8.bytes64[2] == 0 + && results8.bytes64[3] == 0 + ) { + continue; + } + state[-2 + 73].value = lfsr_bs(25); + const bitslice_value_t filter27_0 = f_a_bs(state[-2 + 29].value, state[-2 + 30].value, state[-2 + 32].value, state[-2 + 33].value); + const bitslice_value_t filter27_1 = f_b_bs(state[-2 + 35].value, state[-2 + 39].value, state[-2 + 41].value, state[-2 + 42].value); + const bitslice_value_t filter27_2 = f_b_bs(state[-2 + 44].value, state[-2 + 48].value, state[-2 + 50].value, state[-2 + 53].value); + const bitslice_value_t filter27_3 = f_b_bs(state[-2 + 55].value, state[-2 + 56].value, state[-2 + 58].value, state[-2 + 60].value); + const bitslice_value_t filter27_4 = f_a_bs(state[-2 + 61].value, state[-2 + 70].value, state[-2 + 71].value, state[-2 + 73].value); + const bitslice_value_t filter27 = f_c_bs(filter27_0, filter27_1, filter27_2, filter27_3, filter27_4); + results8.value &= (filter27 ^ keystream[27].value); + if (results8.bytes64[0] == 0 + && results8.bytes64[1] == 0 + && results8.bytes64[2] == 0 + && results8.bytes64[3] == 0 + ) { + continue; + } + state[-2 + 74].value = lfsr_bs(26); + const bitslice_value_t filter28_0 = f_a_bs(state[-2 + 30].value, state[-2 + 31].value, state[-2 + 33].value, state[-2 + 34].value); + const bitslice_value_t filter28_1 = f_b_bs(state[-2 + 36].value, state[-2 + 40].value, state[-2 + 42].value, state[-2 + 43].value); + const bitslice_value_t filter28_2 = f_b_bs(state[-2 + 45].value, state[-2 + 49].value, state[-2 + 51].value, state[-2 + 54].value); + const bitslice_value_t filter28_3 = f_b_bs(state[-2 + 56].value, state[-2 + 57].value, state[-2 + 59].value, state[-2 + 61].value); + const bitslice_value_t filter28_4 = f_a_bs(state[-2 + 62].value, state[-2 + 71].value, state[-2 + 72].value, state[-2 + 74].value); + const bitslice_value_t filter28 = f_c_bs(filter28_0, filter28_1, filter28_2, filter28_3, filter28_4); + results8.value &= (filter28 ^ keystream[28].value); + if (results8.bytes64[0] == 0 + && results8.bytes64[1] == 0 + && results8.bytes64[2] == 0 + && results8.bytes64[3] == 0 + ) { + continue; + } + state[-2 + 75].value = lfsr_bs(27); + const bitslice_value_t filter29_0 = f_a_bs(state[-2 + 31].value, state[-2 + 32].value, state[-2 + 34].value, state[-2 + 35].value); + const bitslice_value_t filter29_1 = f_b_bs(state[-2 + 37].value, state[-2 + 41].value, state[-2 + 43].value, state[-2 + 44].value); + const bitslice_value_t filter29_2 = f_b_bs(state[-2 + 46].value, state[-2 + 50].value, state[-2 + 52].value, state[-2 + 55].value); + const bitslice_value_t filter29_3 = f_b_bs(state[-2 + 57].value, state[-2 + 58].value, state[-2 + 60].value, state[-2 + 62].value); + const bitslice_value_t filter29_4 = f_a_bs(state[-2 + 63].value, state[-2 + 72].value, state[-2 + 73].value, state[-2 + 75].value); + const bitslice_value_t filter29 = f_c_bs(filter29_0, filter29_1, filter29_2, filter29_3, filter29_4); + results8.value &= (filter29 ^ keystream[29].value); + if (results8.bytes64[0] == 0 + && results8.bytes64[1] == 0 + && results8.bytes64[2] == 0 + && results8.bytes64[3] == 0 + ) { + continue; + } + state[-2 + 76].value = lfsr_bs(28); + const bitslice_value_t filter30_0 = f_a_bs(state[-2 + 32].value, state[-2 + 33].value, state[-2 + 35].value, state[-2 + 36].value); + const bitslice_value_t filter30_1 = f_b_bs(state[-2 + 38].value, state[-2 + 42].value, state[-2 + 44].value, state[-2 + 45].value); + const bitslice_value_t filter30_2 = f_b_bs(state[-2 + 47].value, state[-2 + 51].value, state[-2 + 53].value, state[-2 + 56].value); + const bitslice_value_t filter30_3 = f_b_bs(state[-2 + 58].value, state[-2 + 59].value, state[-2 + 61].value, state[-2 + 63].value); + const bitslice_value_t filter30_4 = f_a_bs(state[-2 + 64].value, state[-2 + 73].value, state[-2 + 74].value, state[-2 + 76].value); + const bitslice_value_t filter30 = f_c_bs(filter30_0, filter30_1, filter30_2, filter30_3, filter30_4); + results8.value &= (filter30 ^ keystream[30].value); + if (results8.bytes64[0] == 0 + && results8.bytes64[1] == 0 + && results8.bytes64[2] == 0 + && results8.bytes64[3] == 0 + ) { + continue; + } + state[-2 + 77].value = lfsr_bs(29); + const bitslice_value_t filter31_0 = f_a_bs(state[-2 + 33].value, state[-2 + 34].value, state[-2 + 36].value, state[-2 + 37].value); + const bitslice_value_t filter31_1 = f_b_bs(state[-2 + 39].value, state[-2 + 43].value, state[-2 + 45].value, state[-2 + 46].value); + const bitslice_value_t filter31_2 = f_b_bs(state[-2 + 48].value, state[-2 + 52].value, state[-2 + 54].value, state[-2 + 57].value); + const bitslice_value_t filter31_3 = f_b_bs(state[-2 + 59].value, state[-2 + 60].value, state[-2 + 62].value, state[-2 + 64].value); + const bitslice_value_t filter31_4 = f_a_bs(state[-2 + 65].value, state[-2 + 74].value, state[-2 + 75].value, state[-2 + 77].value); + const bitslice_value_t filter31 = f_c_bs(filter31_0, filter31_1, filter31_2, filter31_3, filter31_4); + results8.value &= (filter31 ^ keystream[31].value); + if (results8.bytes64[0] == 0 + && results8.bytes64[1] == 0 + && results8.bytes64[2] == 0 + && results8.bytes64[3] == 0 + ) { + continue; + } + + for (size_t r = 0; r < MAX_BITSLICES; r++) { + if (!get_vector_bit(r, results8)) continue; + // take the state from layer 2 so we can recover the lowest 2 bits by inverting the LFSR + uint64_t state31 = unbitslice(&state[-2 + 2], r, 48); + state31 = lfsr_inv(state31); + state31 = lfsr_inv(state31); + try_state(state31 & ((1ull << 48) - 1)); + } + } // 8 + } // 7 + } // 6 + } // 5 + } // 4 + } // 3 + } // 2 + } // 1 + } // 0 + return NULL; +} + +static void try_state(uint64_t s) { + Hitag_State hstate; + uint64_t keyrev, key, nR1xk; + uint32_t b = 0; + + hstate.shiftreg = s; + + // recover key + keyrev = hstate.shiftreg & 0xffff; + nR1xk = (hstate.shiftreg >> 16) & 0xffffffff; + for (int i = 0; i < 32; i++) { + hstate.shiftreg = ((hstate.shiftreg) << 1) | ((uid >> (31 - i)) & 0x1); + b = (b << 1) | fnf(hstate.shiftreg); + } + keyrev |= (nR1xk ^ nR1 ^ b) << 16; + + // test key + hitag2_init(&hstate, keyrev, uid, nR2); + if ((aR2 ^ hitag2_nstep(&hstate, 32)) == 0xffffffff) { + + key = rev64(keyrev); + + printf("Key: "); + for (int i = 0; i < 6; i++) { + printf("%02X", (uint8_t)(key & 0xff)); + key = key >> 8; + } + printf("\n"); + exit(0); + } +} diff --git a/tools/hitag2crack/crack5/rfidler.h b/tools/hitag2crack/crack5/rfidler.h new file mode 100644 index 000000000..933547e6b --- /dev/null +++ b/tools/hitag2crack/crack5/rfidler.h @@ -0,0 +1,412 @@ +/*************************************************************************** + * A copy of the GNU GPL is appended to this file. * + * * + * This licence is based on the nmap licence, and we express our gratitude * + * for the work that went into producing it. There is no other connection * + * between RFIDler and nmap either expressed or implied. * + * * + ********************** IMPORTANT RFIDler LICENSE TERMS ******************** + * * + * * + * All references to RFIDler herein imply all it's derivatives, namely: * + * * + * o RFIDler-LF Standard * + * o RFIDler-LF Lite * + * o RFIDler-LF Nekkid * + * * + * * + * RFIDler is (C) 2013-2015 Aperture Labs Ltd. * + * * + * This program is free software; you may redistribute and/or modify it * + * under the terms of the GNU General Public License as published by the * + * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE * + * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your * + * right to use, modify, and redistribute this software under certain * + * conditions. If you wish to embed RFIDler technology into proprietary * + * software or hardware, we sell alternative licenses * + * (contact sales@aperturelabs.com). * + * * + * Note that the GPL places important restrictions on "derivative works", * + * yet it does not provide a detailed definition of that term. To avoid * + * misunderstandings, we interpret that term as broadly as copyright law * + * allows. For example, we consider an application to constitute a * + * derivative work for the purpose of this license if it does any of the * + * following with any software or content covered by this license * + * ("Covered Software"): * + * * + * o Integrates source code from Covered Software. * + * * + * o Is designed specifically to execute Covered Software and parse the * + * results (as opposed to typical shell or execution-menu apps, which will * + * execute anything you tell them to). * + * * + * o Includes Covered Software in a proprietary executable installer. The * + * installers produced by InstallShield are an example of this. Including * + * RFIDler with other software in compressed or archival form does not * + * trigger this provision, provided appropriate open source decompression * + * or de-archiving software is widely available for no charge. For the * + * purposes of this license, an installer is considered to include Covered * + * Software even if it actually retrieves a copy of Covered Software from * + * another source during runtime (such as by downloading it from the * + * Internet). * + * * + * o Links (statically or dynamically) to a library which does any of the * + * above. * + * * + * o Executes a helper program, module, or script to do any of the above. * + * * + * This list is not exclusive, but is meant to clarify our interpretation * + * of derived works with some common examples. Other people may interpret * + * the plain GPL differently, so we consider this a special exception to * + * the GPL that we apply to Covered Software. Works which meet any of * + * these conditions must conform to all of the terms of this license, * + * particularly including the GPL Section 3 requirements of providing * + * source code and allowing free redistribution of the work as a whole. * + * * + * As another special exception to the GPL terms, Aperture Labs Ltd. grants* + * permission to link the code of this program with any version of the * + * OpenSSL library which is distributed under a license identical to that * + * listed in the included docs/licenses/OpenSSL.txt file, and distribute * + * linked combinations including the two. * + * * + * Any redistribution of Covered Software, including any derived works, * + * must obey and carry forward all of the terms of this license, including * + * obeying all GPL rules and restrictions. For example, source code of * + * the whole work must be provided and free redistribution must be * + * allowed. All GPL references to "this License", are to be treated as * + * including the terms and conditions of this license text as well. * + * * + * Because this license imposes special exceptions to the GPL, Covered * + * Work may not be combined (even as part of a larger work) with plain GPL * + * software. The terms, conditions, and exceptions of this license must * + * be included as well. This license is incompatible with some other open * + * source licenses as well. In some cases we can relicense portions of * + * RFIDler or grant special permissions to use it in other open source * + * software. Please contact sales@aperturelabs.com with any such requests.* + * Similarly, we don't incorporate incompatible open source software into * + * Covered Software without special permission from the copyright holders. * + * * + * If you have any questions about the licensing restrictions on using * + * RFIDler in other works, are happy to help. As mentioned above, we also * + * offer alternative license to integrate RFIDler into proprietary * + * applications and appliances. These contracts have been sold to dozens * + * of software vendors, and generally include a perpetual license as well * + * as providing for priority support and updates. They also fund the * + * continued development of RFIDler. Please email sales@aperturelabs.com * + * for further information. * + * If you have received a written license agreement or contract for * + * Covered Software stating terms other than these, you may choose to use * + * and redistribute Covered Software under those terms instead of these. * + * * + * Source is provided to this software because we believe users have a * + * right to know exactly what a program is going to do before they run it. * + * This also allows you to audit the software for security holes (none * + * have been found so far). * + * * + * Source code also allows you to port RFIDler to new platforms, fix bugs, * + * and add new features. You are highly encouraged to send your changes * + * to the RFIDler mailing list for possible incorporation into the * + * main distribution. By sending these changes to Aperture Labs Ltd. or * + * one of the Aperture Labs Ltd. development mailing lists, or checking * + * them into the RFIDler source code repository, it is understood (unless * + * you specify otherwise) that you are offering the RFIDler Project * + * (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, * + * modify, and relicense the code. RFIDler will always be available Open * + * Source, but this is important because the inability to relicense code * + * has caused devastating problems for other Free Software projects (such * + * as KDE and NASM). We also occasionally relicense the code to third * + * parties as discussed above. If you wish to specify special license * + * conditions of your contributions, just say so when you send them. * + * * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler * + * license file for more details (it's in a COPYING file included with * + * RFIDler, and also available from * + * https://github.com/ApertureLabsLtd/RFIDler/COPYING * + * * + ***************************************************************************/ + +// Author: Adam Laurie + +#include +#include + +// BCD hardware revision for usb descriptor (usb_descriptors.c) +#define RFIDLER_HW_VERSION 0x020 + +// max sizes in BITS +#define MAXBLOCKSIZE 512 +#define MAXTAGSIZE 4096 +#define MAXUID 512 + +#define TMP_LARGE_BUFF_LEN 2048 +#define TMP_SMALL_BUFF_LEN 256 +#define ANALOGUE_BUFF_LEN 8192 + +#define COMMS_BUFFER_SIZE 128 + +#define DETECT_BUFFER_SIZE 512 + +#define SAMPLEMASK ~(BIT_1 | BIT_0) // mask to remove two bottom bits from analogue sample - we will then use those for reader & bit period + +// globals + +extern BOOL WiegandOutput; // Output wiegand data whenenver UID is read +extern BYTE *EMU_Reset_Data; // Pointer to full array of bits as bytes, stored as 0x00/0x01, '*' terminated +extern BYTE *EMU_Data; // Pointer to current location in EMU_Reset_Data +extern BYTE EMU_ThisBit; // The next data bit to transmit +extern BYTE EMU_SubCarrier_T0; // Number of Frame Clocks for sub-carrier '0' +extern BYTE EMU_SubCarrier_T1; // Number of Frame Clocks for sub-carrier '1' +extern unsigned int EMU_Repeat; // Number of times to transmit full data set +extern BOOL EMU_Background; // Emulate in the background until told to stop +extern unsigned int EMU_DataBitRate; // Number of Frame Clocks per bit +extern BYTE TmpBits[TMP_LARGE_BUFF_LEN]; // Shared scratchpad +extern BYTE ReaderPeriod; // Flag for sample display +extern unsigned char Comms_In_Buffer[COMMS_BUFFER_SIZE]; // USB/Serial buffer +extern BYTE Interface; // user interface - CLI or API +extern BYTE CommsChannel; // user comms channel - USB or UART +extern BOOL FakeRead; // flag for analogue sampler to signal it wants access to buffers during read +extern BOOL PWD_Mode; // is this tag password protected? +extern BYTE Password[9]; // 32 bits as HEX string set with LOGIN +extern unsigned int Led_Count; // LED status counter, also used for entropy +extern unsigned long Reader_Bit_Count; // Reader ISR bit counter +extern char Previous; // Reader ISR previous bit type + +// RWD (read/write device) coil state +extern BYTE RWD_State; // current state of RWD coil +extern unsigned int RWD_Fc; // field clock in uS +extern unsigned int RWD_Gap_Period; // length of command gaps in OC5 ticks +extern unsigned int RWD_Zero_Period; // length of '0' in OC5 ticks +extern unsigned int RWD_One_Period; // length of '1' in OC5 ticks +extern unsigned int RWD_Sleep_Period; // length of initial sleep to reset tag in OC5 ticks +extern unsigned int RWD_Wake_Period; // length required for tag to restart in OC5 ticks +extern unsigned int RWD_Wait_Switch_TX_RX; // length to wait when switching from TX to RX in OC5 ticks +extern unsigned int RWD_Wait_Switch_RX_TX; // length to wait when switching from RX to TX in OC5 ticks +extern unsigned int RWD_Post_Wait; // low level ISR wait period in OC5 ticks +extern unsigned int RWD_OC5_config; // Output Compare Module settings +extern unsigned int RWD_OC5_r; // Output Compare Module primary compare value +extern unsigned int RWD_OC5_rs; // Output Compare Module secondary compare value +extern BYTE RWD_Command_Buff[TMP_SMALL_BUFF_LEN]; // Command buffer, array of bits as bytes, stored as 0x00/0x01, '*' terminated +extern BYTE *RWD_Command_ThisBit; // Current command bit +extern BOOL Reader_ISR_State; // current state of reader ISR + +// NVM variables +// timings etc. that want to survive a reboot should go here +typedef struct { + BYTE Name[7]; // will be set to "RFIDler" so we can test for new device + BYTE AutoRun[128]; // optional command to run at startup + unsigned char TagType; + unsigned int PSK_Quality; + unsigned int Timeout; + unsigned int Wiegand_Pulse; + unsigned int Wiegand_Gap; + BOOL Wiegand_IdleState; + unsigned int FrameClock; + unsigned char Modulation; + unsigned int DataRate; + unsigned int DataRateSub0; + unsigned int DataRateSub1; + unsigned int DataBits; + unsigned int DataBlocks; + unsigned int BlockSize; + unsigned char SyncBits; + BYTE Sync[4]; + BOOL BiPhase; + BOOL Invert; + BOOL Manchester; + BOOL HalfDuplex; + unsigned int Repeat; + unsigned int PotLow; + unsigned int PotHigh; + unsigned int RWD_Gap_Period; + unsigned int RWD_Zero_Period; + unsigned int RWD_One_Period; + unsigned int RWD_Sleep_Period; + unsigned int RWD_Wake_Period; + unsigned int RWD_Wait_Switch_TX_RX; + unsigned int RWD_Wait_Switch_RX_TX; +} StoredConfig; + +// somewhere to store TAG data. this will be interpreted according to the TAG +// type. +typedef struct { + BYTE TagType; // raw tag type + BYTE EmulatedTagType; // tag type this tag is configured to emulate + BYTE UID[MAXUID + 1]; // Null-terminated HEX string + BYTE Data[MAXTAGSIZE]; // raw data + unsigned char DataBlocks; // number of blocks in Data field + unsigned int BlockSize; // blocksize in bits +} VirtualTag; + +extern StoredConfig RFIDlerConfig; +extern VirtualTag RFIDlerVTag; +extern BYTE TmpBuff[NVM_PAGE_SIZE]; +extern BYTE DataBuff[ANALOGUE_BUFF_LEN]; +extern unsigned int DataBuffCount; +extern const BYTE *ModulationSchemes[]; +extern const BYTE *OnOff[]; +extern const BYTE *HighLow[]; +extern const BYTE *TagTypes[]; + +// globals for ISRs +extern BYTE EmulationMode; +extern unsigned long HW_Bits; +extern BYTE HW_Skip_Bits; +extern unsigned int PSK_Min_Pulse; +extern BOOL PSK_Read_Error; +extern BOOL Manchester_Error; +extern BOOL SnifferMode; +extern unsigned int Clock_Tick_Counter; +extern BOOL Clock_Tick_Counter_Reset; + +// smart card lib +#define MAX_ATR_LEN (BYTE)33 +extern BYTE scCardATR[MAX_ATR_LEN]; +extern BYTE scATRLength; + +// RTC +extern rtccTime RTC_time; // time structure +extern rtccDate RTC_date; // date structure + +// digital pots +#define POTLOW_DEFAULT 100 +#define POTHIGH_DEFAULT 150 +#define DC_OFFSET 60 // analogue circuit DC offset (as close as we can get without using 2 LSB) +#define VOLTS_TO_POT 0.019607843F + +// RWD/clock states +#define RWD_STATE_INACTIVE 0 // RWD not in use +#define RWD_STATE_GO_TO_SLEEP 1 // RWD coil shutdown request +#define RWD_STATE_SLEEPING 2 // RWD coil shutdown for sleep period +#define RWD_STATE_WAKING 3 // RWD active for pre-determined period after reset +#define RWD_STATE_START_SEND 4 // RWD starting send of data +#define RWD_STATE_SENDING_GAP 5 // RWD sending a gap +#define RWD_STATE_SENDING_BIT 6 // RWD sending a data bit +#define RWD_STATE_POST_WAIT 7 // RWD finished sending data, now in forced wait period +#define RWD_STATE_ACTIVE 8 // RWD finished, now just clocking a carrier + +// reader ISR states +#define READER_STOPPED 0 // reader not in use +#define READER_IDLING 1 // reader ISR running to preserve timing, but not reading +#define READER_RUNNING 2 // reader reading bits + + +// user interface types +#define INTERFACE_API 0 +#define INTERFACE_CLI 1 + +// comms channel +#define COMMS_NONE 0 +#define COMMS_USB 1 +#define COMMS_UART 2 + +#define MAX_HISTORY 2 // disable most of history for now - memory issue + +// tag write retries +#define TAG_WRITE_RETRY 5 + +// modulation modes - uppdate ModulationSchemes[] in tags.c if you change this +#define MOD_MODE_NONE 0 +#define MOD_MODE_ASK_OOK 1 +#define MOD_MODE_FSK1 2 +#define MOD_MODE_FSK2 3 +#define MOD_MODE_PSK1 4 +#define MOD_MODE_PSK2 5 +#define MOD_MODE_PSK3 6 + +// TAG types - update TagTypes[] in tags.c if you add to this list +#define TAG_TYPE_NONE 0 +#define TAG_TYPE_ASK_RAW 1 +#define TAG_TYPE_FSK1_RAW 2 +#define TAG_TYPE_FSK2_RAW 3 +#define TAG_TYPE_PSK1_RAW 4 +#define TAG_TYPE_PSK2_RAW 5 +#define TAG_TYPE_PSK3_RAW 6 +#define TAG_TYPE_HITAG1 7 +#define TAG_TYPE_HITAG2 8 +#define TAG_TYPE_EM4X02 9 +#define TAG_TYPE_Q5 10 +#define TAG_TYPE_HID_26 11 +#define TAG_TYPE_INDALA_64 12 +#define TAG_TYPE_INDALA_224 13 +#define TAG_TYPE_UNIQUE 14 +#define TAG_TYPE_FDXB 15 +#define TAG_TYPE_T55X7 16 // same as Q5 but different timings and no modulation-defeat +#define TAG_TYPE_AWID_26 17 +#define TAG_TYPE_EM4X05 18 +#define TAG_TYPE_TAMAGOTCHI 19 +#define TAG_TYPE_HDX 20 // same underlying data as FDX-B, but different modulation & telegram + +// various + +#define BINARY 0 +#define HEX 1 + +#define NO_ADDRESS -1 + +#define ACK TRUE +#define NO_ACK FALSE + +#define BLOCK TRUE +#define NO_BLOCK FALSE + +#define DATA TRUE +#define NO_DATA FALSE + +#define DEBUG_PIN_ON HIGH +#define DEBUG_PIN_OFF LOW + +#define FAST FALSE +#define SLOW TRUE + +#define NO_TRIGGER 0 + +#define LOCK TRUE +#define NO_LOCK FALSE + +#define NFC_MODE TRUE +#define NO_NFC_MODE FALSE + +#define ONESHOT_READ TRUE +#define NO_ONESHOT_READ FALSE + +#define RESET TRUE +#define NO_RESET FALSE + +#define SHUTDOWN_CLOCK TRUE +#define NO_SHUTDOWN_CLOCK FALSE + +#define SYNC TRUE +#define NO_SYNC FALSE + +#define VERIFY TRUE +#define NO_VERIFY FALSE + +#define VOLATILE FALSE +#define NON_VOLATILE TRUE + +#define NEWLINE TRUE +#define NO_NEWLINE FALSE + +#define WAIT TRUE +#define NO_WAIT FALSE + +#define WIPER_HIGH 0 +#define WIPER_LOW 1 + +// conversion for time to ticks +#define US_TO_TICKS 1000000L +#define US_OVER_10_TO_TICKS 10000000L +#define US_OVER_100_TO_TICKS 100000000L +// we can't get down to this level on pic, but we want to standardise on timings, so for now we fudge it +#define CONVERT_TO_TICKS(x) ((x / 10) * (GetSystemClock() / US_OVER_10_TO_TICKS)) +#define CONVERT_TICKS_TO_US(x) (x / (GetSystemClock() / US_TO_TICKS)) +#define TIMER5_PRESCALER 16 +#define MAX_TIMER5_TICKS (65535 * TIMER5_PRESCALER) + +// other conversions + +// bits to hex digits +#define HEXDIGITS(x) (x / 4) +#define HEXTOBITS(x) (x * 4) diff --git a/tools/hitag2crack/crack5/util.h b/tools/hitag2crack/crack5/util.h new file mode 100644 index 000000000..c2399c37c --- /dev/null +++ b/tools/hitag2crack/crack5/util.h @@ -0,0 +1,147 @@ +/*************************************************************************** + * A copy of the GNU GPL is appended to this file. * + * * + * This licence is based on the nmap licence, and we express our gratitude * + * for the work that went into producing it. There is no other connection * + * between RFIDler and nmap either expressed or implied. * + * * + ********************** IMPORTANT RFIDler LICENSE TERMS ******************** + * * + * * + * All references to RFIDler herein imply all it's derivatives, namely: * + * * + * o RFIDler-LF Standard * + * o RFIDler-LF Lite * + * o RFIDler-LF Nekkid * + * * + * * + * RFIDler is (C) 2013-2015 Aperture Labs Ltd. * + * * + * This program is free software; you may redistribute and/or modify it * + * under the terms of the GNU General Public License as published by the * + * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE * + * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your * + * right to use, modify, and redistribute this software under certain * + * conditions. If you wish to embed RFIDler technology into proprietary * + * software or hardware, we sell alternative licenses * + * (contact sales@aperturelabs.com). * + * * + * Note that the GPL places important restrictions on "derivative works", * + * yet it does not provide a detailed definition of that term. To avoid * + * misunderstandings, we interpret that term as broadly as copyright law * + * allows. For example, we consider an application to constitute a * + * derivative work for the purpose of this license if it does any of the * + * following with any software or content covered by this license * + * ("Covered Software"): * + * * + * o Integrates source code from Covered Software. * + * * + * o Is designed specifically to execute Covered Software and parse the * + * results (as opposed to typical shell or execution-menu apps, which will * + * execute anything you tell them to). * + * * + * o Includes Covered Software in a proprietary executable installer. The * + * installers produced by InstallShield are an example of this. Including * + * RFIDler with other software in compressed or archival form does not * + * trigger this provision, provided appropriate open source decompression * + * or de-archiving software is widely available for no charge. For the * + * purposes of this license, an installer is considered to include Covered * + * Software even if it actually retrieves a copy of Covered Software from * + * another source during runtime (such as by downloading it from the * + * Internet). * + * * + * o Links (statically or dynamically) to a library which does any of the * + * above. * + * * + * o Executes a helper program, module, or script to do any of the above. * + * * + * This list is not exclusive, but is meant to clarify our interpretation * + * of derived works with some common examples. Other people may interpret * + * the plain GPL differently, so we consider this a special exception to * + * the GPL that we apply to Covered Software. Works which meet any of * + * these conditions must conform to all of the terms of this license, * + * particularly including the GPL Section 3 requirements of providing * + * source code and allowing free redistribution of the work as a whole. * + * * + * As another special exception to the GPL terms, Aperture Labs Ltd. grants* + * permission to link the code of this program with any version of the * + * OpenSSL library which is distributed under a license identical to that * + * listed in the included docs/licenses/OpenSSL.txt file, and distribute * + * linked combinations including the two. * + * * + * Any redistribution of Covered Software, including any derived works, * + * must obey and carry forward all of the terms of this license, including * + * obeying all GPL rules and restrictions. For example, source code of * + * the whole work must be provided and free redistribution must be * + * allowed. All GPL references to "this License", are to be treated as * + * including the terms and conditions of this license text as well. * + * * + * Because this license imposes special exceptions to the GPL, Covered * + * Work may not be combined (even as part of a larger work) with plain GPL * + * software. The terms, conditions, and exceptions of this license must * + * be included as well. This license is incompatible with some other open * + * source licenses as well. In some cases we can relicense portions of * + * RFIDler or grant special permissions to use it in other open source * + * software. Please contact sales@aperturelabs.com with any such requests.* + * Similarly, we don't incorporate incompatible open source software into * + * Covered Software without special permission from the copyright holders. * + * * + * If you have any questions about the licensing restrictions on using * + * RFIDler in other works, are happy to help. As mentioned above, we also * + * offer alternative license to integrate RFIDler into proprietary * + * applications and appliances. These contracts have been sold to dozens * + * of software vendors, and generally include a perpetual license as well * + * as providing for priority support and updates. They also fund the * + * continued development of RFIDler. Please email sales@aperturelabs.com * + * for further information. * + * If you have received a written license agreement or contract for * + * Covered Software stating terms other than these, you may choose to use * + * and redistribute Covered Software under those terms instead of these. * + * * + * Source is provided to this software because we believe users have a * + * right to know exactly what a program is going to do before they run it. * + * This also allows you to audit the software for security holes (none * + * have been found so far). * + * * + * Source code also allows you to port RFIDler to new platforms, fix bugs, * + * and add new features. You are highly encouraged to send your changes * + * to the RFIDler mailing list for possible incorporation into the * + * main distribution. By sending these changes to Aperture Labs Ltd. or * + * one of the Aperture Labs Ltd. development mailing lists, or checking * + * them into the RFIDler source code repository, it is understood (unless * + * you specify otherwise) that you are offering the RFIDler Project * + * (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, * + * modify, and relicense the code. RFIDler will always be available Open * + * Source, but this is important because the inability to relicense code * + * has caused devastating problems for other Free Software projects (such * + * as KDE and NASM). We also occasionally relicense the code to third * + * parties as discussed above. If you wish to specify special license * + * conditions of your contributions, just say so when you send them. * + * * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler * + * license file for more details (it's in a COPYING file included with * + * RFIDler, and also available from * + * https://github.com/ApertureLabsLtd/RFIDler/COPYING * + * * + ***************************************************************************/ + +// Author: Adam Laurie + +/* + * Hitag Crypto support macros + * These macros reverse the bit order in a byte, or *within* each byte of a + * 16 , 32 or 64 bit unsigned integer. (Not across the whole 16 etc bits.) + */ +#define rev8(X) ((((X) >> 7) &1) + (((X) >> 5) &2) + (((X) >> 3) &4) \ + + (((X) >> 1) &8) + (((X) << 1) &16) + (((X) << 3) &32) \ + + (((X) << 5) &64) + (((X) << 7) &128) ) +#define rev16(X) (rev8 (X) + (rev8 (X >> 8) << 8)) +#define rev32(X) (rev16(X) + (rev16(X >> 16) << 16)) +#define rev64(X) (rev32(X) + (rev32(X >> 32) << 32)) + + +unsigned long hexreversetoulong(BYTE *hex); +unsigned long long hexreversetoulonglong(BYTE *hex); + diff --git a/tools/hitag2crack/crack5/utilpart.c b/tools/hitag2crack/crack5/utilpart.c new file mode 100644 index 000000000..c46148491 --- /dev/null +++ b/tools/hitag2crack/crack5/utilpart.c @@ -0,0 +1,180 @@ +/*************************************************************************** + * A copy of the GNU GPL is appended to this file. * + * * + * This licence is based on the nmap licence, and we express our gratitude * + * for the work that went into producing it. There is no other connection * + * between RFIDler and nmap either expressed or implied. * + * * + ********************** IMPORTANT RFIDler LICENSE TERMS ******************** + * * + * * + * All references to RFIDler herein imply all it's derivatives, namely: * + * * + * o RFIDler-LF Standard * + * o RFIDler-LF Lite * + * o RFIDler-LF Nekkid * + * * + * * + * RFIDler is (C) 2013-2014 Aperture Labs Ltd. * + * * + * This program is free software; you may redistribute and/or modify it * + * under the terms of the GNU General Public License as published by the * + * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE * + * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your * + * right to use, modify, and redistribute this software under certain * + * conditions. If you wish to embed RFIDler technology into proprietary * + * software or hardware, we sell alternative licenses * + * (contact sales@aperturelabs.com). * + * * + * Note that the GPL places important restrictions on "derivative works", * + * yet it does not provide a detailed definition of that term. To avoid * + * misunderstandings, we interpret that term as broadly as copyright law * + * allows. For example, we consider an application to constitute a * + * derivative work for the purpose of this license if it does any of the * + * following with any software or content covered by this license * + * ("Covered Software"): * + * * + * o Integrates source code from Covered Software. * + * * + * o Is designed specifically to execute Covered Software and parse the * + * results (as opposed to typical shell or execution-menu apps, which will * + * execute anything you tell them to). * + * * + * o Includes Covered Software in a proprietary executable installer. The * + * installers produced by InstallShield are an example of this. Including * + * RFIDler with other software in compressed or archival form does not * + * trigger this provision, provided appropriate open source decompression * + * or de-archiving software is widely available for no charge. For the * + * purposes of this license, an installer is considered to include Covered * + * Software even if it actually retrieves a copy of Covered Software from * + * another source during runtime (such as by downloading it from the * + * Internet). * + * * + * o Links (statically or dynamically) to a library which does any of the * + * above. * + * * + * o Executes a helper program, module, or script to do any of the above. * + * * + * This list is not exclusive, but is meant to clarify our interpretation * + * of derived works with some common examples. Other people may interpret * + * the plain GPL differently, so we consider this a special exception to * + * the GPL that we apply to Covered Software. Works which meet any of * + * these conditions must conform to all of the terms of this license, * + * particularly including the GPL Section 3 requirements of providing * + * source code and allowing free redistribution of the work as a whole. * + * * + * As another special exception to the GPL terms, Aperture Labs Ltd. grants* + * permission to link the code of this program with any version of the * + * OpenSSL library which is distributed under a license identical to that * + * listed in the included docs/licenses/OpenSSL.txt file, and distribute * + * linked combinations including the two. * + * * + * Any redistribution of Covered Software, including any derived works, * + * must obey and carry forward all of the terms of this license, including * + * obeying all GPL rules and restrictions. For example, source code of * + * the whole work must be provided and free redistribution must be * + * allowed. All GPL references to "this License", are to be treated as * + * including the terms and conditions of this license text as well. * + * * + * Because this license imposes special exceptions to the GPL, Covered * + * Work may not be combined (even as part of a larger work) with plain GPL * + * software. The terms, conditions, and exceptions of this license must * + * be included as well. This license is incompatible with some other open * + * source licenses as well. In some cases we can relicense portions of * + * RFIDler or grant special permissions to use it in other open source * + * software. Please contact sales@aperturelabs.com with any such requests.* + * Similarly, we don't incorporate incompatible open source software into * + * Covered Software without special permission from the copyright holders. * + * * + * If you have any questions about the licensing restrictions on using * + * RFIDler in other works, are happy to help. As mentioned above, we also * + * offer alternative license to integrate RFIDler into proprietary * + * applications and appliances. These contracts have been sold to dozens * + * of software vendors, and generally include a perpetual license as well * + * as providing for priority support and updates. They also fund the * + * continued development of RFIDler. Please email sales@aperturelabs.com * + * for further information. * + * If you have received a written license agreement or contract for * + * Covered Software stating terms other than these, you may choose to use * + * and redistribute Covered Software under those terms instead of these. * + * * + * Source is provided to this software because we believe users have a * + * right to know exactly what a program is going to do before they run it. * + * This also allows you to audit the software for security holes (none * + * have been found so far). * + * * + * Source code also allows you to port RFIDler to new platforms, fix bugs, * + * and add new features. You are highly encouraged to send your changes * + * to the RFIDler mailing list for possible incorporation into the * + * main distribution. By sending these changes to Aperture Labs Ltd. or * + * one of the Aperture Labs Ltd. development mailing lists, or checking * + * them into the RFIDler source code repository, it is understood (unless * + * you specify otherwise) that you are offering the RFIDler Project * + * (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, * + * modify, and relicense the code. RFIDler will always be available Open * + * Source, but this is important because the inability to relicense code * + * has caused devastating problems for other Free Software projects (such * + * as KDE and NASM). We also occasionally relicense the code to third * + * parties as discussed above. If you wish to specify special license * + * conditions of your contributions, just say so when you send them. * + * * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler * + * license file for more details (it's in a COPYING file included with * + * RFIDler, and also available from * + * https://github.com/ApertureLabsLtd/RFIDler/COPYING * + * * + ***************************************************************************/ + +// Author: Adam Laurie + + +#include +#include +#include "HardwareProfile.h" +#include "util.h" +#include "rfidler.h" +//#include "comms.h" + +// rtc +rtccTime RTC_time; // time structure +rtccDate RTC_date; // date structure + +// convert byte-reversed 8 digit hex to unsigned long +unsigned long hexreversetoulong(BYTE *hex) { + unsigned long ret = 0L; + unsigned int x; + BYTE i; + + if (strlen(hex) != 8) + return 0L; + + for (i = 0 ; i < 4 ; ++i) { + if (sscanf(hex, "%2X", &x) != 1) + return 0L; + ret += ((unsigned long) x) << i * 8; + hex += 2; + } + return ret; +} + +// convert byte-reversed 12 digit hex to unsigned long +unsigned long long hexreversetoulonglong(BYTE *hex) { + unsigned long long ret = 0LL; + BYTE tmp[9]; + + // this may seem an odd way to do it, but weird compiler issues were + // breaking direct conversion! + + tmp[8] = '\0'; + memset(tmp + 4, '0', 4); + memcpy(tmp, hex + 8, 4); + ret = hexreversetoulong(tmp); + ret <<= 32; + memcpy(tmp, hex, 8); + ret += hexreversetoulong(tmp); + return ret; +} + + diff --git a/tools/hitag2crack/crack5gpu/HardwareProfile.h b/tools/hitag2crack/crack5gpu/HardwareProfile.h new file mode 100644 index 000000000..bce139042 --- /dev/null +++ b/tools/hitag2crack/crack5gpu/HardwareProfile.h @@ -0,0 +1,524 @@ +/*************************************************************************** + * A copy of the GNU GPL is appended to this file. * + * * + * This licence is based on the nmap licence, and we express our gratitude * + * for the work that went into producing it. There is no other connection * + * between RFIDler and nmap either expressed or implied. * + * * + ********************** IMPORTANT RFIDler LICENSE TERMS ******************** + * * + * * + * All references to RFIDler herein imply all it's derivatives, namely: * + * * + * o RFIDler-LF Standard * + * o RFIDler-LF Lite * + * o RFIDler-LF Nekkid * + * * + * * + * RFIDler is (C) 2013-2014 Aperture Labs Ltd. * + * * + * This program is free software; you may redistribute and/or modify it * + * under the terms of the GNU General Public License as published by the * + * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE * + * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your * + * right to use, modify, and redistribute this software under certain * + * conditions. If you wish to embed RFIDler technology into proprietary * + * software or hardware, we sell alternative licenses * + * (contact sales@aperturelabs.com). * + * * + * Note that the GPL places important restrictions on "derivative works", * + * yet it does not provide a detailed definition of that term. To avoid * + * misunderstandings, we interpret that term as broadly as copyright law * + * allows. For example, we consider an application to constitute a * + * derivative work for the purpose of this license if it does any of the * + * following with any software or content covered by this license * + * ("Covered Software"): * + * * + * o Integrates source code from Covered Software. * + * * + * o Is designed specifically to execute Covered Software and parse the * + * results (as opposed to typical shell or execution-menu apps, which will * + * execute anything you tell them to). * + * * + * o Includes Covered Software in a proprietary executable installer. The * + * installers produced by InstallShield are an example of this. Including * + * RFIDler with other software in compressed or archival form does not * + * trigger this provision, provided appropriate open source decompression * + * or de-archiving software is widely available for no charge. For the * + * purposes of this license, an installer is considered to include Covered * + * Software even if it actually retrieves a copy of Covered Software from * + * another source during runtime (such as by downloading it from the * + * Internet). * + * * + * o Links (statically or dynamically) to a library which does any of the * + * above. * + * * + * o Executes a helper program, module, or script to do any of the above. * + * * + * This list is not exclusive, but is meant to clarify our interpretation * + * of derived works with some common examples. Other people may interpret * + * the plain GPL differently, so we consider this a special exception to * + * the GPL that we apply to Covered Software. Works which meet any of * + * these conditions must conform to all of the terms of this license, * + * particularly including the GPL Section 3 requirements of providing * + * source code and allowing free redistribution of the work as a whole. * + * * + * As another special exception to the GPL terms, Aperture Labs Ltd. grants* + * permission to link the code of this program with any version of the * + * OpenSSL library which is distributed under a license identical to that * + * listed in the included docs/licenses/OpenSSL.txt file, and distribute * + * linked combinations including the two. * + * * + * Any redistribution of Covered Software, including any derived works, * + * must obey and carry forward all of the terms of this license, including * + * obeying all GPL rules and restrictions. For example, source code of * + * the whole work must be provided and free redistribution must be * + * allowed. All GPL references to "this License", are to be treated as * + * including the terms and conditions of this license text as well. * + * * + * Because this license imposes special exceptions to the GPL, Covered * + * Work may not be combined (even as part of a larger work) with plain GPL * + * software. The terms, conditions, and exceptions of this license must * + * be included as well. This license is incompatible with some other open * + * source licenses as well. In some cases we can relicense portions of * + * RFIDler or grant special permissions to use it in other open source * + * software. Please contact sales@aperturelabs.com with any such requests.* + * Similarly, we don't incorporate incompatible open source software into * + * Covered Software without special permission from the copyright holders. * + * * + * If you have any questions about the licensing restrictions on using * + * RFIDler in other works, are happy to help. As mentioned above, we also * + * offer alternative license to integrate RFIDler into proprietary * + * applications and appliances. These contracts have been sold to dozens * + * of software vendors, and generally include a perpetual license as well * + * as providing for priority support and updates. They also fund the * + * continued development of RFIDler. Please email sales@aperturelabs.com * + * for further information. * + * If you have received a written license agreement or contract for * + * Covered Software stating terms other than these, you may choose to use * + * and redistribute Covered Software under those terms instead of these. * + * * + * Source is provided to this software because we believe users have a * + * right to know exactly what a program is going to do before they run it. * + * This also allows you to audit the software for security holes (none * + * have been found so far). * + * * + * Source code also allows you to port RFIDler to new platforms, fix bugs, * + * and add new features. You are highly encouraged to send your changes * + * to the RFIDler mailing list for possible incorporation into the * + * main distribution. By sending these changes to Aperture Labs Ltd. or * + * one of the Aperture Labs Ltd. development mailing lists, or checking * + * them into the RFIDler source code repository, it is understood (unless * + * you specify otherwise) that you are offering the RFIDler Project * + * (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, * + * modify, and relicense the code. RFIDler will always be available Open * + * Source, but this is important because the inability to relicense code * + * has caused devastating problems for other Free Software projects (such * + * as KDE and NASM). We also occasionally relicense the code to third * + * parties as discussed above. If you wish to specify special license * + * conditions of your contributions, just say so when you send them. * + * * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler * + * license file for more details (it's in a COPYING file included with * + * RFIDler, and also available from * + * https://github.com/ApertureLabsLtd/RFIDler/COPYING * + * * + ***************************************************************************/ + +// Author: Adam Laurie + + + +#ifndef HARDWARE_PROFILE_UBW32_H +#define HARDWARE_PROFILE_UBW32_H + +//#include "plib.h" +typedef char BOOL; +typedef char BYTE; +typedef int rtccTime; +typedef int rtccDate; + + +#ifndef __PIC32MX__ +#define __PIC32MX__ +#endif + +#define GetSystemClock() (80000000ul) +#define GetPeripheralClock() (GetSystemClock()) +#define GetInstructionClock() (GetSystemClock()) + +//#define USE_SELF_POWER_SENSE_IO +#define tris_self_power TRISAbits.TRISA2 // Input +#define self_power 1 + +//#define USE_USB_BUS_SENSE_IO +#define tris_usb_bus_sense TRISBbits.TRISB5 // Input +#define USB_BUS_SENSE 1 + +// LEDs +#define mLED_1 LATEbits.LATE3 + +#define mLED_2 LATEbits.LATE2 +#define mLED_Comms mLED_2 + +#define mLED_3 LATEbits.LATE1 +#define mLED_Clock mLED_3 + +#define mLED_4 LATEbits.LATE0 +#define mLED_Emulate mLED_4 + +#define mLED_5 LATGbits.LATG6 +#define mLED_Read mLED_5 + +#define mLED_6 LATAbits.LATA15 +#define mLED_User mLED_6 + +#define mLED_7 LATDbits.LATD11 +#define mLED_Error mLED_7 + +// active low +#define mLED_ON 0 +#define mLED_OFF 1 + +#define mGetLED_1() mLED_1 +#define mGetLED_USB() mLED_1 +#define mGetLED_2() mLED_2 +#define mGetLED_Comms() mLED_2 +#define mGetLED_3() mLED_3 +#define mGetLED_Clock() mLED_3 +#define mGetLED_4() mLED_4 +#define mGetLED_Emulate() mLED_4 +#define mGetLED_5() mLED_5 +#define mGetLED_Read() mLED_5 +#define mGetLED_6() mLED_6 +#define mGetLED_User() mLED_6 +#define mGetLED_7() mLED_7 +#define mGetLED_Error() mLED_7 + +#define mLED_1_On() mLED_1 = mLED_ON +#define mLED_USB_On() mLED_1_On() +#define mLED_2_On() mLED_2 = mLED_ON +#define mLED_Comms_On() mLED_2_On() +#define mLED_3_On() mLED_3 = mLED_ON +#define mLED_Clock_On() mLED_3_On() +#define mLED_4_On() mLED_4 = mLED_ON +#define mLED_Emulate_On() mLED_4_On() +#define mLED_5_On() mLED_5 = mLED_ON +#define mLED_Read_On() mLED_5_On() +#define mLED_6_On() mLED_6 = mLED_ON +#define mLED_User_On() mLED_6_On() +#define mLED_7_On() mLED_7 = mLED_ON +#define mLED_Error_On() mLED_7_On() + +#define mLED_1_Off() mLED_1 = mLED_OFF +#define mLED_USB_Off() mLED_1_Off() +#define mLED_2_Off() mLED_2 = mLED_OFF +#define mLED_Comms_Off() mLED_2_Off() +#define mLED_3_Off() mLED_3 = mLED_OFF +#define mLED_Clock_Off() mLED_3_Off() +#define mLED_4_Off() mLED_4 = mLED_OFF +#define mLED_Emulate_Off() mLED_4_Off() +#define mLED_5_Off() mLED_5 = mLED_OFF +#define mLED_Read_Off() mLED_5_Off() +#define mLED_6_Off() mLED_6 = mLED_OFF +#define mLED_User_Off() mLED_6_Off() +#define mLED_7_Off() mLED_7 = mLED_OFF +#define mLED_Error_Off() mLED_7_Off() + +#define mLED_1_Toggle() mLED_1 = !mLED_1 +#define mLED_USB_Toggle() mLED_1_Toggle() +#define mLED_2_Toggle() mLED_2 = !mLED_2 +#define mLED_Comms_Toggle() mLED_2_Toggle() +#define mLED_3_Toggle() mLED_3 = !mLED_3 +#define mLED_Clock_Toggle() mLED_3_Toggle() +#define mLED_4_Toggle() mLED_4 = !mLED_4 +#define mLED_Emulate_Toggle() mLED_4_Toggle() +#define mLED_5_Toggle() mLED_5 = !mLED_5 +#define mLED_Read_Toggle( ) mLED_5_Toggle() +#define mLED_6_Toggle() mLED_6 = !mLED_6 +#define mLED_User_Toggle() mLED_6_Toggle() +#define mLED_7_Toggle() mLED_7 = !mLED_7 +#define mLED_Error_Toggle() mLED_7_Toggle() + +#define mLED_All_On() { mLED_1_On(); mLED_2_On(); mLED_3_On(); mLED_4_On(); mLED_5_On(); mLED_6_On(); mLED_7_On(); } +#define mLED_All_Off() { mLED_1_Off(); mLED_2_Off(); mLED_3_Off(); mLED_4_Off(); mLED_5_Off(); mLED_6_Off(); mLED_7_Off(); } + +// usb status lights +#define mLED_Both_Off() {mLED_USB_Off();mLED_Comms_Off();} +#define mLED_Both_On() {mLED_USB_On();mLED_Comms_On();} +#define mLED_Only_USB_On() {mLED_USB_On();mLED_Comms_Off();} +#define mLED_Only_Comms_On() {mLED_USB_Off();mLED_Comms_On();} + +/** SWITCH *********************************************************/ +#define swBootloader PORTEbits.RE7 +#define swUser PORTEbits.RE6 + +/** I/O pin definitions ********************************************/ +#define INPUT_PIN 1 +#define OUTPUT_PIN 0 + +#define TRUE 1 +#define FALSE 0 + +#define ENABLE 1 +#define DISABE 0 + +#define EVEN 0 +#define ODD 1 + +#define LOW FALSE +#define HIGH TRUE + +#define CLOCK_ON LOW +#define CLOCK_OFF HIGH + +// output coil control - select between reader/emulator circuits +#define COIL_MODE LATBbits.LATB4 +#define COIL_MODE_READER() COIL_MODE= LOW +#define COIL_MODE_EMULATOR() COIL_MODE= HIGH + +// coil for emulation +#define COIL_OUT LATGbits.LATG9 +#define COIL_OUT_HIGH() COIL_OUT=HIGH +#define COIL_OUT_LOW() COIL_OUT=LOW + +// door relay (active low) +#define DOOR_RELAY LATAbits.LATA14 +#define DOOR_RELAY_OPEN() DOOR_RELAY= HIGH +#define DOOR_RELAY_CLOSE() DOOR_RELAY= LOW + +// inductance/capacitance freq +#define IC_FREQUENCY PORTAbits.RA2 + +#define SNIFFER_COIL PORTDbits.RD12 // external reader clock detect +#define READER_ANALOGUE PORTBbits.RB11 // reader coil analogue +#define DIV_LOW_ANALOGUE PORTBbits.RB12 // voltage divider LOW analogue +#define DIV_HIGH_ANALOGUE PORTBbits.RB13 // voltage divider HIGH analogue + +// clock coil (normally controlled by OC Module, but defined here so we can force it high or low) +#define CLOCK_COIL PORTDbits.RD4 +#define CLOCK_COIL_MOVED PORTDbits.RD0 // temporary for greenwire + +// digital output after analogue reader circuit +#define READER_DATA PORTDbits.RD8 + +// trace / debug +#define DEBUG_PIN_1 LATCbits.LATC1 +#define DEBUG_PIN_1_TOGGLE() DEBUG_PIN_1= !DEBUG_PIN_1 +#define DEBUG_PIN_2 LATCbits.LATC2 +#define DEBUG_PIN_2_TOGGLE() DEBUG_PIN_2= !DEBUG_PIN_2 +#define DEBUG_PIN_3 LATCbits.LATC3 +#define DEBUG_PIN_3_TOGGLE() DEBUG_PIN_3= !DEBUG_PIN_3 +#define DEBUG_PIN_4 LATEbits.LATE5 +#define DEBUG_PIN_4_TOGGLE() DEBUG_PIN_4= !DEBUG_PIN_4 + +// spi (sdi1) for sd card (not directly referenced) +//#define SD_CARD_RX LATCbits.LATC4 +//#define SD_CARD_TX LATDbits.LATD0 +//#define SD_CARD_CLK LATDbits.LATD10 +//#define SD_CARD_SS LATDbits.LATD9 +// spi for SD card +#define SD_CARD_DET LATFbits.LATF0 +#define SD_CARD_WE LATFbits.LATF1 // write enable - unused for microsd but allocated anyway as library checks it +// (held LOW by default - cut solder bridge to GND to free pin if required) +#define SPI_SD SPI_CHANNEL1 +#define SPI_SD_BUFF SPI1BUF +#define SPI_SD_STAT SPI1STATbits +// see section below for more defines! + +// iso 7816 smartcard +// microchip SC module defines pins so we don't need to, but +// they are listed here to help avoid conflicts +#define ISO_7816_RX LATBbits.LATF2 // RX +#define ISO_7816_TX LATBbits.LATF8 // TX +#define ISO_7816_VCC LATBbits.LATB9 // Power +#define ISO_7816_CLK LATCbits.LATD1 // Clock +#define ISO_7816_RST LATEbits.LATE8 // Reset + +// user LED +#define USER_LED LATDbits.LATD7 +#define USER_LED_ON() LATDbits.LATD7=1 +#define USER_LED_OFF() LATDbits.LATD7=0 + +// LCR +#define LCR_CALIBRATE LATBbits.LATB5 + +// wiegand / clock & data +#define WIEGAND_IN_0 PORTDbits.RD5 +#define WIEGAND_IN_0_PULLUP CNPUEbits.CNPUE14 +#define WIEGAND_IN_0_PULLDOWN CNPDbits.CNPD14 +#define WIEGAND_IN_1 PORTDbits.RD6 +#define WIEGAND_IN_1_PULLUP CNPUEbits.CNPUE15 +#define WIEGAND_IN_1_PULLDOWN CNPDbits.CNPD15 +#define CAND_IN_DATA WIEGAND_IN_0 +#define CAND_IN_CLOCK WIEGAND_IN_1 + +#define WIEGAND_OUT_0 LATDbits.LATD3 +#define WIEGAND_OUT_1 LATDbits.LATD2 +#define WIEGAND_OUT_0_TRIS TRISDbits.TRISD3 +#define WIEGAND_OUT_1_TRIS TRISDbits.TRISD2 +#define CAND_OUT_DATA WIEGAND_OUT_0 +#define CAND_OUT_CLOCK WIEGAND_OUT_1 + +// connect/disconnect reader clock from coil - used to send RWD signals by creating gaps in carrier +#define READER_CLOCK_ENABLE LATEbits.LATE9 +#define READER_CLOCK_ENABLE_ON() READER_CLOCK_ENABLE=CLOCK_ON +#define READER_CLOCK_ENABLE_OFF(x) {READER_CLOCK_ENABLE=CLOCK_OFF; COIL_OUT=x;} + +// these input pins must NEVER bet set to output or they will cause short circuits! +// they can be used to see data from reader before it goes into or gate +#define OR_IN_A PORTAbits.RA4 +#define OR_IN_B PORTAbits.RA5 + + +// CNCON and CNEN are set to allow wiegand input pin weak pullups to be switched on +#define Init_GPIO() { \ + CNCONbits.ON= TRUE; \ + CNENbits.CNEN14= TRUE; \ + CNENbits.CNEN15= TRUE; \ + TRISAbits.TRISA2= INPUT_PIN; \ + TRISAbits.TRISA4= INPUT_PIN; \ + TRISAbits.TRISA5= INPUT_PIN; \ + TRISAbits.TRISA14= OUTPUT_PIN; \ + TRISAbits.TRISA15= OUTPUT_PIN; \ + TRISBbits.TRISB4= OUTPUT_PIN; \ + TRISBbits.TRISB5= OUTPUT_PIN; \ + TRISBbits.TRISB9= OUTPUT_PIN; \ + TRISBbits.TRISB11= INPUT_PIN; \ + TRISBbits.TRISB12= INPUT_PIN; \ + TRISBbits.TRISB13= INPUT_PIN; \ + TRISCbits.TRISC1= OUTPUT_PIN; \ + TRISCbits.TRISC2= OUTPUT_PIN; \ + TRISCbits.TRISC3= OUTPUT_PIN; \ + TRISCbits.TRISC4= INPUT_PIN; \ + TRISDbits.TRISD0= INPUT_PIN; \ + TRISDbits.TRISD1= OUTPUT_PIN; \ + TRISDbits.TRISD2= OUTPUT_PIN; \ + TRISDbits.TRISD3= OUTPUT_PIN; \ + TRISDbits.TRISD4= OUTPUT_PIN; \ + TRISDbits.TRISD5= INPUT_PIN; \ + TRISDbits.TRISD6= INPUT_PIN; \ + TRISDbits.TRISD7= OUTPUT_PIN; \ + TRISDbits.TRISD8= INPUT_PIN; \ + TRISDbits.TRISD11= OUTPUT_PIN; \ + TRISDbits.TRISD12= INPUT_PIN; \ + TRISEbits.TRISE0= OUTPUT_PIN; \ + TRISEbits.TRISE1= OUTPUT_PIN; \ + TRISEbits.TRISE2= OUTPUT_PIN; \ + TRISEbits.TRISE3= OUTPUT_PIN; \ + TRISEbits.TRISE5= OUTPUT_PIN; \ + TRISEbits.TRISE6= INPUT_PIN; \ + TRISEbits.TRISE7= INPUT_PIN; \ + TRISEbits.TRISE8= OUTPUT_PIN; \ + TRISEbits.TRISE9= OUTPUT_PIN; \ + TRISFbits.TRISF0= INPUT_PIN; \ + TRISFbits.TRISF1= INPUT_PIN; \ + TRISFbits.TRISF2= INPUT_PIN; \ + TRISFbits.TRISF8= OUTPUT_PIN; \ + TRISGbits.TRISG6= OUTPUT_PIN; \ + TRISGbits.TRISG12= INPUT_PIN; \ + TRISGbits.TRISG13= INPUT_PIN; \ + TRISGbits.TRISG9= OUTPUT_PIN; \ + LATBbits.LATB9= LOW; \ + LATCbits.LATC1= LOW; \ + LATCbits.LATC2= LOW; \ + LATCbits.LATC3= LOW; \ + LATDbits.LATD2= WIEGAND_IN_1; \ + LATDbits.LATD3= WIEGAND_IN_0; \ + LATEbits.LATE5= LOW; \ + LATEbits.LATE9= HIGH; \ + } + +// uart3 (CLI/API) speed +#define BAUDRATE3 115200UL +#define BRG_DIV3 4 +#define BRGH3 1 + +// spi for potentiometer +#define SPI_POT SPI_CHANNEL4 +#define SPI_POT_BUFF SPI4BUF +#define SPI_POT_STAT SPI4STATbits + +// spi for sd card - defines required for Microchip SD-SPI libs +// define interface type +#define USE_SD_INTERFACE_WITH_SPI + +#define MDD_USE_SPI_1 +#define SPI_START_CFG_1 (PRI_PRESCAL_64_1 | SEC_PRESCAL_8_1 | MASTER_ENABLE_ON | SPI_CKE_ON | SPI_SMP_ON) +#define SPI_START_CFG_2 (SPI_ENABLE) +// Define the SPI frequency +#define SPI_FREQUENCY (20000000) +// Description: SD-SPI Card Detect Input bit +#define SD_CD PORTFbits.RF0 +// Description: SD-SPI Card Detect TRIS bit +#define SD_CD_TRIS TRISFbits.TRISF0 +// Description: SD-SPI Write Protect Check Input bit +#define SD_WE PORTFbits.RF1 +// Description: SD-SPI Write Protect Check TRIS bit +#define SD_WE_TRIS TRISFbits.TRISF1 +// Description: The main SPI control register +#define SPICON1 SPI1CON +// Description: The SPI status register +#define SPISTAT SPI1STAT +// Description: The SPI Buffer +#define SPIBUF SPI1BUF +// Description: The receive buffer full bit in the SPI status register +#define SPISTAT_RBF SPI1STATbits.SPIRBF +// Description: The bitwise define for the SPI control register (i.e. _____bits) +#define SPICON1bits SPI1CONbits +// Description: The bitwise define for the SPI status register (i.e. _____bits) +#define SPISTATbits SPI1STATbits +// Description: The enable bit for the SPI module +#define SPIENABLE SPICON1bits.ON +// Description: The definition for the SPI baud rate generator register (PIC32) +#define SPIBRG SPI1BRG +// Description: The TRIS bit for the SCK pin +#define SPICLOCK TRISDbits.TRISD10 +// Description: The TRIS bit for the SDI pin +#define SPIIN TRISCbits.TRISC4 +// Description: The TRIS bit for the SDO pin +#define SPIOUT TRISDbits.TRISD0 +#define SD_CS LATDbits.LATD9 +// Description: SD-SPI Chip Select TRIS bit +#define SD_CS_TRIS TRISDbits.TRISD9 +//SPI library functions +#define putcSPI putcSPI1 +#define getcSPI getcSPI1 +#define OpenSPI(config1, config2) OpenSPI1(config1, config2) + +// Define setup parameters for OpenADC10 function +// Turn module on | Ouput in integer format | Trigger mode auto | Enable autosample +#define ADC_CONFIG1 (ADC_FORMAT_INTG | ADC_CLK_AUTO | ADC_AUTO_SAMPLING_ON) +// ADC ref external | Disable offset test | Disable scan mode | Perform 2 samples | Use dual buffers | Use alternate mode +#define ADC_CONFIG2 (ADC_VREF_AVDD_AVSS | ADC_OFFSET_CAL_DISABLE | ADC_SCAN_OFF | ADC_SAMPLES_PER_INT_1 | ADC_ALT_BUF_ON | ADC_ALT_INPUT_ON) + +// Use ADC internal clock | Set sample time +#define ADC_CONFIG3 (ADC_CONV_CLK_INTERNAL_RC | ADC_SAMPLE_TIME_0) + +// slow sample rate for tuning coils +#define ADC_CONFIG2_SLOW (ADC_VREF_AVDD_AVSS | ADC_OFFSET_CAL_DISABLE | ADC_SCAN_OFF | ADC_SAMPLES_PER_INT_16 | ADC_ALT_BUF_ON | ADC_ALT_INPUT_ON) +#define ADC_CONFIG3_SLOW (ADC_CONV_CLK_INTERNAL_RC | ADC_SAMPLE_TIME_31) + +// use AN11 +#define ADC_CONFIGPORT ENABLE_AN11_ANA +// Do not assign channels to scan +#define ADC_CONFIGSCAN SKIP_SCAN_ALL + +#define ADC_TO_VOLTS 0.003208F + + +// flash memory - int myvar = *(int*)(myflashmemoryaddress); + +// memory is 0x9D005000 to 0x9D07FFFF + +#define NVM_MEMORY_END 0x9D07FFFF +#define NVM_PAGE_SIZE 4096 +#define NVM_PAGES 2 // config & VTAG +#define RFIDLER_NVM_ADDRESS (NVM_MEMORY_END - (NVM_PAGE_SIZE * NVM_PAGES)) + +// UART timeout in us +#define SERIAL_TIMEOUT 100 + +#endif diff --git a/tools/hitag2crack/crack5gpu/Makefile b/tools/hitag2crack/crack5gpu/Makefile new file mode 100644 index 000000000..adcf61113 --- /dev/null +++ b/tools/hitag2crack/crack5gpu/Makefile @@ -0,0 +1,24 @@ +CFLAGS?=-Wall +#INCLUDE=-I/usr/local/cuda-7.5/include +INCLUDE=-I/opt/nvidia/cuda/include +#Linux +#LIBS=-L/usr/local/cuda-7.5/lib64 -lOpenCL +LIBS=-L/opt/nvidia/cuda/lib64 -lOpenCL +#Mac +#LIBS=-framework OpenCL + +all: ht2crack5.c utilpart.o ht2crack2utils.o hitagcrypto.o + $(CC) $(CFLAGS) ht2crack5.c -o ht2crack5gpu utilpart.o ht2crack2utils.o hitagcrypto.o $(LIBS) -lpthread + +utilpart.o: util.h utilpart.c + $(CC) $(CFLAGS) $(INCLUDE) -c utilpart.c + +hitagcrypto.o: hitagcrypto.h hitagcrypto.c + $(CC) $(CFLAGS) $(INCLUDE) -c hitagcrypto.c + +ht2crack2utils.o: ht2crack2utils.h ht2crack2utils.c + $(CC) $(CFLAGS) $(INCLUDE) -c ht2crack2utils.c + +clean: + rm -f *.o ht2crack5gpu +fresh: clean all diff --git a/tools/hitag2crack/crack5gpu/README.md b/tools/hitag2crack/crack5gpu/README.md new file mode 100644 index 000000000..292da2fc0 --- /dev/null +++ b/tools/hitag2crack/crack5gpu/README.md @@ -0,0 +1,27 @@ +ht2crack5gpu + + + +Build +----- + +It requires an OpenCL framework. + +If required, edit Makefile and adjust INCLUDE and LIBS directives to your setup. + +``` +make clean +make +``` + +Run +--- + +You'll need just two nR aR pairs. These are the +encrypted nonces and challenge response values. They should be in hex. + +``` +./ht2crack5gpu +``` + +UID is the UID of the tag that you used to gather the nR aR values. diff --git a/tools/hitag2crack/crack5gpu/hitagcrypto.c b/tools/hitag2crack/crack5gpu/hitagcrypto.c new file mode 100644 index 000000000..47449c3e3 --- /dev/null +++ b/tools/hitag2crack/crack5gpu/hitagcrypto.c @@ -0,0 +1,373 @@ +/*************************************************************************** + * A copy of the GNU GPL is appended to this file. * + * * + * This licence is based on the nmap licence, and we express our gratitude * + * for the work that went into producing it. There is no other connection * + * between RFIDler and nmap either expressed or implied. * + * * + ********************** IMPORTANT RFIDler LICENSE TERMS ******************** + * * + * * + * All references to RFIDler herein imply all it's derivatives, namely: * + * * + * o RFIDler-LF Standard * + * o RFIDler-LF Lite * + * o RFIDler-LF Nekkid * + * * + * * + * RFIDler is (C) 2013-2015 Aperture Labs Ltd. * + * * + * This program is free software; you may redistribute and/or modify it * + * under the terms of the GNU General Public License as published by the * + * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE * + * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your * + * right to use, modify, and redistribute this software under certain * + * conditions. If you wish to embed RFIDler technology into proprietary * + * software or hardware, we sell alternative licenses * + * (contact sales@aperturelabs.com). * + * * + * Note that the GPL places important restrictions on "derivative works", * + * yet it does not provide a detailed definition of that term. To avoid * + * misunderstandings, we interpret that term as broadly as copyright law * + * allows. For example, we consider an application to constitute a * + * derivative work for the purpose of this license if it does any of the * + * following with any software or content covered by this license * + * ("Covered Software"): * + * * + * o Integrates source code from Covered Software. * + * * + * o Is designed specifically to execute Covered Software and parse the * + * results (as opposed to typical shell or execution-menu apps, which will * + * execute anything you tell them to). * + * * + * o Includes Covered Software in a proprietary executable installer. The * + * installers produced by InstallShield are an example of this. Including * + * RFIDler with other software in compressed or archival form does not * + * trigger this provision, provided appropriate open source decompression * + * or de-archiving software is widely available for no charge. For the * + * purposes of this license, an installer is considered to include Covered * + * Software even if it actually retrieves a copy of Covered Software from * + * another source during runtime (such as by downloading it from the * + * Internet). * + * * + * o Links (statically or dynamically) to a library which does any of the * + * above. * + * * + * o Executes a helper program, module, or script to do any of the above. * + * * + * This list is not exclusive, but is meant to clarify our interpretation * + * of derived works with some common examples. Other people may interpret * + * the plain GPL differently, so we consider this a special exception to * + * the GPL that we apply to Covered Software. Works which meet any of * + * these conditions must conform to all of the terms of this license, * + * particularly including the GPL Section 3 requirements of providing * + * source code and allowing free redistribution of the work as a whole. * + * * + * As another special exception to the GPL terms, Aperture Labs Ltd. grants* + * permission to link the code of this program with any version of the * + * OpenSSL library which is distributed under a license identical to that * + * listed in the included docs/licenses/OpenSSL.txt file, and distribute * + * linked combinations including the two. * + * * + * Any redistribution of Covered Software, including any derived works, * + * must obey and carry forward all of the terms of this license, including * + * obeying all GPL rules and restrictions. For example, source code of * + * the whole work must be provided and free redistribution must be * + * allowed. All GPL references to "this License", are to be treated as * + * including the terms and conditions of this license text as well. * + * * + * Because this license imposes special exceptions to the GPL, Covered * + * Work may not be combined (even as part of a larger work) with plain GPL * + * software. The terms, conditions, and exceptions of this license must * + * be included as well. This license is incompatible with some other open * + * source licenses as well. In some cases we can relicense portions of * + * RFIDler or grant special permissions to use it in other open source * + * software. Please contact sales@aperturelabs.com with any such requests.* + * Similarly, we don't incorporate incompatible open source software into * + * Covered Software without special permission from the copyright holders. * + * * + * If you have any questions about the licensing restrictions on using * + * RFIDler in other works, are happy to help. As mentioned above, we also * + * offer alternative license to integrate RFIDler into proprietary * + * applications and appliances. These contracts have been sold to dozens * + * of software vendors, and generally include a perpetual license as well * + * as providing for priority support and updates. They also fund the * + * continued development of RFIDler. Please email sales@aperturelabs.com * + * for further information. * + * If you have received a written license agreement or contract for * + * Covered Software stating terms other than these, you may choose to use * + * and redistribute Covered Software under those terms instead of these. * + * * + * Source is provided to this software because we believe users have a * + * right to know exactly what a program is going to do before they run it. * + * This also allows you to audit the software for security holes (none * + * have been found so far). * + * * + * Source code also allows you to port RFIDler to new platforms, fix bugs, * + * and add new features. You are highly encouraged to send your changes * + * to the RFIDler mailing list for possible incorporation into the * + * main distribution. By sending these changes to Aperture Labs Ltd. or * + * one of the Aperture Labs Ltd. development mailing lists, or checking * + * them into the RFIDler source code repository, it is understood (unless * + * you specify otherwise) that you are offering the RFIDler Project * + * (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, * + * modify, and relicense the code. RFIDler will always be available Open * + * Source, but this is important because the inability to relicense code * + * has caused devastating problems for other Free Software projects (such * + * as KDE and NASM). We also occasionally relicense the code to third * + * parties as discussed above. If you wish to specify special license * + * conditions of your contributions, just say so when you send them. * + * * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler * + * license file for more details (it's in a COPYING file included with * + * RFIDler, and also available from * + * https://github.com/ApertureLabsLtd/RFIDler/COPYING * + * * + ***************************************************************************/ + +// Author: unknown. +// Modifications for RFIDler: Tony Naggs , Adam Laurie + +// uncomment this to build file as a standalone crypto test program +// #define UNIT_TEST +// also uncomment to include verbose debug prints +// #define TEST_DEBUG + +//#include +#include "HardwareProfile.h" +#include "rfidler.h" +#include "hitagcrypto.h" +#include "util.h" + +#ifdef UNIT_TEST +#include +#endif + +#if defined(UNIT_TEST) && defined(TEST_DEBUG) +// Note that printf format %I64x prints 64 bit ints in MS Visual C/C++. +// This may need changing for other compilers/platforms. +#define DEBUG_PRINTF(...) printf(__VA_ARGS__) +#else +#define DEBUG_PRINTF(...) +#endif + + +/* Brief info about NXP Hitag 1, Hitag 2, Hitag S and Hitag u (mu) + + Hitag 125kHz RFID was created by a company called Mikron (Mikron Gesellschaft + fur Integrierte Mikroelektronik Mbh), of Austria, for micropayment applications. + At about the same time, late 1980s to early 1990s, Mikron developed the + similarly featured Mifare micropayment card for 13.56MHz RFID. + (Mikron's European Patent EP 0473569 A2 was filed 23 August 1991, with a + priority date of 23 Aug 1990.) + Mikron was subsequently acquired by Philips Semiconductors in 1995. + Philips Semiconductors divsion subsequently became NXP. + + + Modulation read/write device -> transponder: 100 % ASK and binary pulse + length coding + + Modulation transponder -> read/write device: Strong ASK modulation, + selectable Manchester or Biphase coding + + Hitag S, Hitag u; anti-collision procedure + + Fast anti-collision protocol + + Hitag u; optional Cyclic Redundancy Check (CRC) + + Reader Talks First mode + + Hitag 2 & later; Transponder Talks First (TTF) mode + + Temporary switch from Transponder Talks First into Reader Talks First + (RTF) Mode + + Data rate read/write device to transponder: 5.2 kbit/s + + Data rates transponder to read/write device: 2 kbit/s, 4 kbit/s, 8 kbit/s + + 32-bit password feature + + Hitag 2, S = 32-bit Unique Identifier + + Hitag u = 48-bit Unique Identifier + + Selectable password modes for reader / tag mutual authentication + (Hitag 1 has 2 pairs of keys, later versions have 1 pair) + + Hitag 2 & Hitag S; Selectable encrypted mode, 48 bit key + + Known tag types: + + HITAG 1 2048 bits total memory + + HITAG 2 256 Bit total memory Read/Write + 8 pages of 32 bits, inc UID (32), + secret key (64), password (24), config (8) + + HITAG S 32 32 bits Unique Identifier Read Only + HITAG S 256 256 bits total memory Read/Write + HITAG S 2048 2048 bits total memory Read/Write + + HITAG u RO64 64 bits total memory Read Only + HITAG u 128 bits total memory Read/Write + HITAG u Advanced 512 bits total memory Read/Write + HITAG u Advanced+ 1760 bits total memory Read/Write + + Default 48-bit key for Hitag 2, S encryption: + "MIKRON" = O N M I K R + Key = 4F 4E 4D 49 4B 52 + +*/ + + +// We want the crypto functions to be as fast as possible, so optimize! +// The best compiler optimization in Microchip's free XC32 edition is -O1 +#pragma GCC optimize("O1") + +// private, nonlinear function to generate 1 crypto bit +static uint32_t hitag2_crypt(uint64_t x); + + +// macros to pick out 4 bits in various patterns of 1s & 2s & make a new number +#define pickbits2_2(S, A, B) ( ((S >> A) & 3) | ((S >> (B - 2)) & 0xC) ) +#define pickbits1x4(S, A, B, C, D) ( ((S >> A) & 1) | ((S >> (B - 1)) & 2) | \ + ((S >> (C - 2)) & 4) | ((S >> (D - 3)) & 8) ) +#define pickbits1_1_2(S, A, B, C) ( ((S >> A) & 1) | ((S >> (B - 1)) & 2) | \ + ((S >> (C - 2)) & 0xC) ) +#define pickbits2_1_1(S, A, B, C) ( ((S >> A) & 3) | ((S >> (B - 2)) & 4) | \ + ((S >> (C - 3)) & 8) ) +#define pickbits1_2_1(S, A, B, C) ( ((S >> A) & 1) | ((S >> (B - 1)) & 6) | \ + ((S >> (C - 3)) & 8) ) + + +static uint32_t hitag2_crypt(uint64_t x) { + const uint32_t ht2_function4a = 0x2C79; // 0010 1100 0111 1001 + const uint32_t ht2_function4b = 0x6671; // 0110 0110 0111 0001 + const uint32_t ht2_function5c = 0x7907287B; // 0111 1001 0000 0111 0010 1000 0111 1011 + uint32_t bitindex; + + bitindex = (ht2_function4a >> pickbits2_2(x, 1, 4)) & 1; + bitindex |= ((ht2_function4b << 1) >> pickbits1_1_2(x, 7, 11, 13)) & 0x02; + bitindex |= ((ht2_function4b << 2) >> pickbits1x4(x, 16, 20, 22, 25)) & 0x04; + bitindex |= ((ht2_function4b << 3) >> pickbits2_1_1(x, 27, 30, 32)) & 0x08; + bitindex |= ((ht2_function4a << 4) >> pickbits1_2_1(x, 33, 42, 45)) & 0x10; + + DEBUG_PRINTF("hitag2_crypt bitindex = %02x\n", bitindex); + return (ht2_function5c >> bitindex) & 1; +} + +/* + * Parameters: + * Hitag_State* pstate - output, internal state after initialisation + * uint64_t sharedkey - 48 bit key shared between reader & tag + * uint32_t serialnum - 32 bit tag serial number + * uint32_t initvector - 32 bit random IV from reader, part of tag authentication + */ +void hitag2_init(Hitag_State *pstate, uint64_t sharedkey, uint32_t serialnum, uint32_t initvector) { + // init state, from serial number and lowest 16 bits of shared key + uint64_t state = ((sharedkey & 0xFFFF) << 32) | serialnum; + + // mix the initialisation vector and highest 32 bits of the shared key + initvector ^= (uint32_t)(sharedkey >> 16); + + // move 16 bits from (IV xor Shared Key) to top of uint64_t state + // these will be XORed in turn with output of the crypto function + state |= (uint64_t) initvector << 48; + initvector >>= 16; + + // unrolled loop is faster on PIC32 (MIPS), do 32 times + // shift register, then calc new bit + state >>= 1; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + + // highest 16 bits of IV XOR Shared Key + state |= (uint64_t) initvector << 47; + + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; + state ^= (uint64_t) hitag2_crypt(state) << 47; + + DEBUG_PRINTF("hitag2_init result = %012I64x\n", state); + pstate->shiftreg = state; + /* naive version for reference, LFSR has 16 taps + pstate->lfsr = state ^ (state >> 2) ^ (state >> 3) ^ (state >> 6) + ^ (state >> 7) ^ (state >> 8) ^ (state >> 16) ^ (state >> 22) + ^ (state >> 23) ^ (state >> 26) ^ (state >> 30) ^ (state >> 41) + ^ (state >> 42) ^ (state >> 43) ^ (state >> 46) ^ (state >> 47); + */ + { + // optimise with one 64-bit intermediate + uint64_t temp = state ^ (state >> 1); + pstate->lfsr = state ^ (state >> 6) ^ (state >> 16) + ^ (state >> 26) ^ (state >> 30) ^ (state >> 41) + ^ (temp >> 2) ^ (temp >> 7) ^ (temp >> 22) + ^ (temp >> 42) ^ (temp >> 46); + } +} + + +/* + * Return up to 32 crypto bits. + * Last bit is in least significant bit, earlier bits are shifted left. + * Note that the Hitag transmission protocol is least significant bit, + * so we may want to change this, or add a function, that returns the + * crypto output bits in the other order. + * + * Parameters: + * Hitag_State* pstate - in/out, internal cipher state after initialisation + * uint32_t steps - number of bits requested, (capped at 32) + */ +uint32_t hitag2_nstep(Hitag_State *pstate, uint32_t steps) { + uint64_t state = pstate->shiftreg; + uint32_t result = 0; + uint64_t lfsr = pstate->lfsr; + + if (steps == 0) + return 0; + +// if (steps > 32) +// steps = 32; + + do { + // update shift registers + if (lfsr & 1) { + state = (state >> 1) | 0x800000000000; + lfsr = (lfsr >> 1) ^ 0xB38083220073; + + // accumulate next bit of crypto + result = (result << 1) | hitag2_crypt(state); + } else { + state >>= 1; + lfsr >>= 1; + + result = (result << 1) | hitag2_crypt(state); + } + } while (--steps); + + DEBUG_PRINTF("hitag2_nstep state = %012I64x, result %02x\n", state, result); + pstate->shiftreg = state; + pstate->lfsr = lfsr; + return result; +} + +// end of crypto core, revert to default optimization level +#pragma GCC reset_options diff --git a/tools/hitag2crack/crack5gpu/hitagcrypto.h b/tools/hitag2crack/crack5gpu/hitagcrypto.h new file mode 100644 index 000000000..274d3d82c --- /dev/null +++ b/tools/hitag2crack/crack5gpu/hitagcrypto.h @@ -0,0 +1,167 @@ +/*************************************************************************** + * A copy of the GNU GPL is appended to this file. * + * * + * This licence is based on the nmap licence, and we express our gratitude * + * for the work that went into producing it. There is no other connection * + * between RFIDler and nmap either expressed or implied. * + * * + ********************** IMPORTANT RFIDler LICENSE TERMS ******************** + * * + * * + * All references to RFIDler herein imply all it's derivatives, namely: * + * * + * o RFIDler-LF Standard * + * o RFIDler-LF Lite * + * o RFIDler-LF Nekkid * + * * + * * + * RFIDler is (C) 2013-2014 Aperture Labs Ltd. * + * * + * This program is free software; you may redistribute and/or modify it * + * under the terms of the GNU General Public License as published by the * + * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE * + * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your * + * right to use, modify, and redistribute this software under certain * + * conditions. If you wish to embed RFIDler technology into proprietary * + * software or hardware, we sell alternative licenses * + * (contact sales@aperturelabs.com). * + * * + * Note that the GPL places important restrictions on "derivative works", * + * yet it does not provide a detailed definition of that term. To avoid * + * misunderstandings, we interpret that term as broadly as copyright law * + * allows. For example, we consider an application to constitute a * + * derivative work for the purpose of this license if it does any of the * + * following with any software or content covered by this license * + * ("Covered Software"): * + * * + * o Integrates source code from Covered Software. * + * * + * o Is designed specifically to execute Covered Software and parse the * + * results (as opposed to typical shell or execution-menu apps, which will * + * execute anything you tell them to). * + * * + * o Includes Covered Software in a proprietary executable installer. The * + * installers produced by InstallShield are an example of this. Including * + * RFIDler with other software in compressed or archival form does not * + * trigger this provision, provided appropriate open source decompression * + * or de-archiving software is widely available for no charge. For the * + * purposes of this license, an installer is considered to include Covered * + * Software even if it actually retrieves a copy of Covered Software from * + * another source during runtime (such as by downloading it from the * + * Internet). * + * * + * o Links (statically or dynamically) to a library which does any of the * + * above. * + * * + * o Executes a helper program, module, or script to do any of the above. * + * * + * This list is not exclusive, but is meant to clarify our interpretation * + * of derived works with some common examples. Other people may interpret * + * the plain GPL differently, so we consider this a special exception to * + * the GPL that we apply to Covered Software. Works which meet any of * + * these conditions must conform to all of the terms of this license, * + * particularly including the GPL Section 3 requirements of providing * + * source code and allowing free redistribution of the work as a whole. * + * * + * As another special exception to the GPL terms, Aperture Labs Ltd. grants* + * permission to link the code of this program with any version of the * + * OpenSSL library which is distributed under a license identical to that * + * listed in the included docs/licenses/OpenSSL.txt file, and distribute * + * linked combinations including the two. * + * * + * Any redistribution of Covered Software, including any derived works, * + * must obey and carry forward all of the terms of this license, including * + * obeying all GPL rules and restrictions. For example, source code of * + * the whole work must be provided and free redistribution must be * + * allowed. All GPL references to "this License", are to be treated as * + * including the terms and conditions of this license text as well. * + * * + * Because this license imposes special exceptions to the GPL, Covered * + * Work may not be combined (even as part of a larger work) with plain GPL * + * software. The terms, conditions, and exceptions of this license must * + * be included as well. This license is incompatible with some other open * + * source licenses as well. In some cases we can relicense portions of * + * RFIDler or grant special permissions to use it in other open source * + * software. Please contact sales@aperturelabs.com with any such requests.* + * Similarly, we don't incorporate incompatible open source software into * + * Covered Software without special permission from the copyright holders. * + * * + * If you have any questions about the licensing restrictions on using * + * RFIDler in other works, are happy to help. As mentioned above, we also * + * offer alternative license to integrate RFIDler into proprietary * + * applications and appliances. These contracts have been sold to dozens * + * of software vendors, and generally include a perpetual license as well * + * as providing for priority support and updates. They also fund the * + * continued development of RFIDler. Please email sales@aperturelabs.com * + * for further information. * + * If you have received a written license agreement or contract for * + * Covered Software stating terms other than these, you may choose to use * + * and redistribute Covered Software under those terms instead of these. * + * * + * Source is provided to this software because we believe users have a * + * right to know exactly what a program is going to do before they run it. * + * This also allows you to audit the software for security holes (none * + * have been found so far). * + * * + * Source code also allows you to port RFIDler to new platforms, fix bugs, * + * and add new features. You are highly encouraged to send your changes * + * to the RFIDler mailing list for possible incorporation into the * + * main distribution. By sending these changes to Aperture Labs Ltd. or * + * one of the Aperture Labs Ltd. development mailing lists, or checking * + * them into the RFIDler source code repository, it is understood (unless * + * you specify otherwise) that you are offering the RFIDler Project * + * (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, * + * modify, and relicense the code. RFIDler will always be available Open * + * Source, but this is important because the inability to relicense code * + * has caused devastating problems for other Free Software projects (such * + * as KDE and NASM). We also occasionally relicense the code to third * + * parties as discussed above. If you wish to specify special license * + * conditions of your contributions, just say so when you send them. * + * * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler * + * license file for more details (it's in a COPYING file included with * + * RFIDler, and also available from * + * https://github.com/ApertureLabsLtd/RFIDler/COPYING * + * * + ***************************************************************************/ + +// Author: unknown. +// Modifications for RFIDler: Tony Naggs , Adam Laurie + + +#ifndef HITAGCRYPTO_H +#define HITAGCRYPTO_H + +#include + +/* + Our model of Hitag 2 crypto uses 2 parallel shift registers: + a. 48 bit Feedback Shift Register, required for inputs to the nonlinear function. + b. 48 bit Linear Feedback Shift Register (LFSR). + A transform of initial register (a) value, which is then run in parallel. + Enables much faster calculation of the feedback values. + + API: + void hitag2_init(Hitag_State* pstate, uint64_t sharedkey, uint32_t serialnum, + uint32_t initvector); + Initialise state from 48 bit shared (secret) reader/tag key, + 32 bit tag serial number and 32 bit initialisation vector from reader. + + uint32_t hitag2_nstep(Hitag_State* pstate, uint32_t steps); + update shift register state and generate N cipher bits (N should be <= 32) + */ + + +typedef struct { + uint64_t shiftreg; // naive shift register, required for nonlinear fn input + uint64_t lfsr; // fast lfsr, used to make software faster +} Hitag_State; + +void hitag2_init(Hitag_State *pstate, uint64_t sharedkey, uint32_t serialnum, uint32_t initvector); + +uint32_t hitag2_nstep(Hitag_State *pstate, uint32_t steps); + +#endif /* HITAGCRYPTO_H */ + diff --git a/tools/hitag2crack/crack5gpu/ht2crack2utils.c b/tools/hitag2crack/crack5gpu/ht2crack2utils.c new file mode 100644 index 000000000..75d4c27a9 --- /dev/null +++ b/tools/hitag2crack/crack5gpu/ht2crack2utils.c @@ -0,0 +1,172 @@ +#include "ht2crack2utils.h" + +// writes a value into a buffer as a series of bytes +void writebuf(unsigned char *buf, uint64_t val, unsigned int len) { + int i; + char c; + + for (i = len - 1; i >= 0; i--) { + c = val & 0xff; + buf[i] = c; + val = val >> 8; + } + +} + + +/* simple hexdump for testing purposes */ +void shexdump(unsigned char *data, int data_len) { + int i; + + if (!data || (data_len <= 0)) { + printf("shexdump: invalid parameters\n"); + return; + } + + printf("Hexdump from %p:\n", data); + + for (i = 0; i < data_len; i++) { + if ((i % HEX_PER_ROW) == 0) { + printf("\n0x%04x: ", i); + } + printf("%02x ", data[i]); + } + printf("\n\n"); +} + + + +void printbin(unsigned char *c) { + int i, j; + unsigned char x; + + if (!c) { + printf("printbin: invalid params\n"); + return; + } + + for (i = 0; i < 6; i++) { + x = c[i]; + for (j = 0; j < 8; j++) { + printf("%d", (x & 0x80) >> 7); + x = x << 1; + } + } + printf("\n"); +} + + +void printbin2(uint64_t val, unsigned int size) { + int i; + uint64_t mask = 1; + + mask = mask << (size - 1); + + for (i = 0; i < size; i++) { + if (val & mask) { + printf("1"); + } else { + printf("0"); + } + val = val << 1; + } +} + + +void printstate(Hitag_State *hstate) { + printf("shiftreg =\t"); + printbin2(hstate->shiftreg, 48); + printf("\n"); +} + + + + +// convert hex char to binary +unsigned char hex2bin(unsigned char c) { + if ((c >= '0') && (c <= '9')) { + return (c - '0'); + } else if ((c >= 'a') && (c <= 'f')) { + return (c - 'a' + 10); + } else if ((c >= 'A') && (c <= 'F')) { + return (c - 'A' + 10); + } else { + return 0; + } +} + +// return a single bit from a value +int bitn(uint64_t x, int bit) { + uint64_t bitmask = 1; + + bitmask = bitmask << bit; + + if (x & bitmask) { + return 1; + } else { + return 0; + } +} + + +// the sub-function R that rollback depends upon +int fnR(uint64_t x) { + // renumbered bits because my state is 0-47, not 1-48 + return (bitn(x, 1) ^ bitn(x, 2) ^ bitn(x, 5) ^ bitn(x, 6) ^ bitn(x, 7) ^ + bitn(x, 15) ^ bitn(x, 21) ^ bitn(x, 22) ^ bitn(x, 25) ^ bitn(x, 29) ^ bitn(x, 40) ^ + bitn(x, 41) ^ bitn(x, 42) ^ bitn(x, 45) ^ bitn(x, 46) ^ bitn(x, 47)); +} + +// the rollback function that lets us go backwards in time +void rollback(Hitag_State *hstate, unsigned int steps) { + int i; + + for (i = 0; i < steps; i++) { + hstate->shiftreg = ((hstate->shiftreg << 1) & 0xffffffffffff) | fnR(hstate->shiftreg); + } + +} + + +// the three filter sub-functions that feed fnf +int fa(unsigned int i) { + return bitn(0x2C79, i); +} + +int fb(unsigned int i) { + return bitn(0x6671, i); +} + +int fc(unsigned int i) { + return bitn(0x7907287B, i); +} + +// the filter function that generates a bit of output from the prng state +int fnf(uint64_t s) { + unsigned int x1, x2, x3, x4, x5, x6; + + x1 = (bitn(s, 2) << 0) | (bitn(s, 3) << 1) | (bitn(s, 5) << 2) | (bitn(s, 6) << 3); + x2 = (bitn(s, 8) << 0) | (bitn(s, 12) << 1) | (bitn(s, 14) << 2) | (bitn(s, 15) << 3); + x3 = (bitn(s, 17) << 0) | (bitn(s, 21) << 1) | (bitn(s, 23) << 2) | (bitn(s, 26) << 3); + x4 = (bitn(s, 28) << 0) | (bitn(s, 29) << 1) | (bitn(s, 31) << 2) | (bitn(s, 33) << 3); + x5 = (bitn(s, 34) << 0) | (bitn(s, 43) << 1) | (bitn(s, 44) << 2) | (bitn(s, 46) << 3); + + x6 = (fa(x1) << 0) | (fb(x2) << 1) | (fb(x3) << 2) | (fb(x4) << 3) | (fa(x5) << 4); + + return fc(x6); +} + +// builds the lfsr for the prng (quick calcs for hitag2_nstep()) +void buildlfsr(Hitag_State *hstate) { + uint64_t state = hstate->shiftreg; + uint64_t temp; + + temp = state ^ (state >> 1); + hstate->lfsr = state ^ (state >> 6) ^ (state >> 16) + ^ (state >> 26) ^ (state >> 30) ^ (state >> 41) + ^ (temp >> 2) ^ (temp >> 7) ^ (temp >> 22) + ^ (temp >> 42) ^ (temp >> 46); +} + + + diff --git a/tools/hitag2crack/crack5gpu/ht2crack2utils.h b/tools/hitag2crack/crack5gpu/ht2crack2utils.h new file mode 100644 index 000000000..33e0e3036 --- /dev/null +++ b/tools/hitag2crack/crack5gpu/ht2crack2utils.h @@ -0,0 +1,35 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "HardwareProfile.h" +#include "rfidler.h" +#include "util.h" + +#include "hitagcrypto.h" + +#define HEX_PER_ROW 16 + + + +void writebuf(unsigned char *buf, uint64_t val, unsigned int len); +void shexdump(unsigned char *data, int data_len); +void printbin(unsigned char *c); +void printbin2(uint64_t val, unsigned int size); +void printstate(Hitag_State *hstate); +unsigned char hex2bin(unsigned char c); +int bitn(uint64_t x, int bit); +int fnR(uint64_t x); +void rollback(Hitag_State *hstate, unsigned int steps); +int fa(unsigned int i); +int fb(unsigned int i); +int fc(unsigned int i); +int fnf(uint64_t s); +void buildlfsr(Hitag_State *hstate); diff --git a/tools/hitag2crack/crack5gpu/ht2crack5.c b/tools/hitag2crack/crack5gpu/ht2crack5.c new file mode 100644 index 000000000..82a80c3ea --- /dev/null +++ b/tools/hitag2crack/crack5gpu/ht2crack5.c @@ -0,0 +1,421 @@ +/* ht2crack5.c + * + * This code is heavily based on the HiTag2 Hell CPU implementation + * from https://github.com/factoritbv/hitag2hell by FactorIT B.V., + * with the following changes: + * * Main takes a UID and 2 {nR},{aR} pairs as arguments + * and searches for states producing the first aR sample, + * reconstructs the corresponding key candidates + * and tests them against the second nR,aR pair; + * * Reduce max_bitslices and some type sizes to fit OpenCL + * * Reuses the Hitag helping functions of the other attacks. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef __APPLE__ +#include +#else +#define CL_TARGET_OPENCL_VERSION 220 +#define CL_USE_DEPRECATED_OPENCL_1_2_APIS +#include +#endif +#include "ht2crack2utils.h" + +const uint8_t bits[9] = {20, 14, 4, 3, 1, 1, 1, 1, 1}; +#define lfsr_inv(state) (((state)<<1) | (__builtin_parityll((state) & ((0xce0044c101cd>>1)|(1ull<<(47)))))) +#define i4(x,a,b,c,d) ((uint32_t)((((x)>>(a))&1)<<3)|(((x)>>(b))&1)<<2|(((x)>>(c))&1)<<1|(((x)>>(d))&1)) +#define f(state) ((0xdd3929b >> ( (((0x3c65 >> i4(state, 2, 3, 5, 6) ) & 1) <<4) \ + | ((( 0xee5 >> i4(state, 8,12,14,15) ) & 1) <<3) \ + | ((( 0xee5 >> i4(state,17,21,23,26) ) & 1) <<2) \ + | ((( 0xee5 >> i4(state,28,29,31,33) ) & 1) <<1) \ + | (((0x3c65 >> i4(state,34,43,44,46) ) & 1) ))) & 1) + +#define MAX_BITSLICES 32 +#define VECTOR_SIZE (MAX_BITSLICES/8) +#define KERNELFILENAME "ht2crack5kernel.cl" + +typedef unsigned int __attribute__((aligned(VECTOR_SIZE))) __attribute__((vector_size(VECTOR_SIZE))) bitslice_value_t; +typedef union { + bitslice_value_t value; + uint8_t bytes[MAX_BITSLICES / 8]; +} bitslice_t; + +// we never actually set or use the lowest 2 bits the initial state, so we can save 2 bitslices everywhere +__thread bitslice_t state[-2 + 32 + 48]; + +bitslice_t keystream[32]; +bitslice_t bs_zeroes, bs_ones; + +#define f_a_bs(a,b,c,d) (~(((a|b)&c)^(a|d)^b)) // 6 ops +#define f_b_bs(a,b,c,d) (~(((d|c)&(a^b))^(d|a|b))) // 7 ops +#define f_c_bs(a,b,c,d,e) (~((((((c^e)|d)&a)^b)&(c^b))^(((d^e)|a)&((d^b)|c)))) // 13 ops +#define lfsr_bs(i) (state[-2+i+ 0].value ^ state[-2+i+ 2].value ^ state[-2+i+ 3].value ^ state[-2+i+ 6].value ^ \ + state[-2+i+ 7].value ^ state[-2+i+ 8].value ^ state[-2+i+16].value ^ state[-2+i+22].value ^ \ + state[-2+i+23].value ^ state[-2+i+26].value ^ state[-2+i+30].value ^ state[-2+i+41].value ^ \ + state[-2+i+42].value ^ state[-2+i+43].value ^ state[-2+i+46].value ^ state[-2+i+47].value); +#define get_bit(n, word) ((word >> (n)) & 1) + +const uint64_t expand(uint64_t mask, uint64_t value) { + uint64_t fill = 0; + for (uint64_t bit_index = 0; bit_index < 48; bit_index++) { + if (mask & 1) { + fill |= (value & 1) << bit_index; + value >>= 1; + } + mask >>= 1; + } + return fill; +} + +void bitslice(const uint64_t value, bitslice_t *restrict bitsliced_value, const size_t bit_len, bool reverse) { + size_t bit_idx; + for (bit_idx = 0; bit_idx < bit_len; bit_idx++) { + bool bit; + if (reverse) { + bit = get_bit(bit_len - 1 - bit_idx, value); + } else { + bit = get_bit(bit_idx, value); + } + if (bit) { + bitsliced_value[bit_idx].value = bs_ones.value; + } else { + bitsliced_value[bit_idx].value = bs_zeroes.value; + } + } +} + +uint32_t uid, nR1, aR1, nR2, aR2; + +// Reduce type size of candidates array to fit OpenCL +uint16_t candidates[(1 << 20) * 3]; +bitslice_t initial_bitslices[48]; +size_t filter_pos[20] = {4, 7, 9, 13, 16, 18, 22, 24, 27, 30, 32, 35, 45, 47 }; +size_t thread_count = 8; +size_t layer_0_found; + +static void try_state(uint64_t s); + +struct context { + char *kernelSource; // source for kernel + + cl_platform_id platform_id; // compute platform id + cl_device_id device_id; // compute device id + cl_context context; // compute context + cl_command_queue commands; // compute command queue + cl_program program; // compute program + cl_kernel kernel; // compute kernel + +// cl_mem cand_base; // device memory used for the candidate base + cl_mem keystream; // device memory used for the keystream array + cl_mem candidates; // device memory used for the candidates array + cl_mem matches; // device memory used for the matches array + cl_mem matches_found; // device memory used for the matches_found array +}; + + +void runKernel(struct context *ctx, uint32_t cand_base, uint64_t *matches, uint32_t *matches_found) { + int err; + size_t global[2]; + + // Write our data set into the input array in device memory + err = clEnqueueWriteBuffer(ctx->commands, ctx->matches_found, CL_TRUE, 0, sizeof(uint32_t), matches_found, 0, NULL, NULL); + // Set the arguments to our compute kernel + err = clSetKernelArg(ctx->kernel, 0, sizeof(uint32_t), &cand_base); + err |= clSetKernelArg(ctx->kernel, 4, sizeof(cl_mem), &ctx->matches_found); + if (err != CL_SUCCESS) { + printf("Error: Failed to set kernel arguments in runKernel! %d\n", err); + exit(1); + } + + // Execute the kernel over the entire range of our 2d input data set using 8K * 1K threads + global[0] = 8192; + global[1] = 1024; + err = clEnqueueNDRangeKernel(ctx->commands, ctx->kernel, 2, NULL, global, NULL, 0, NULL, NULL); + if (err) { + printf("Error: Failed to execute kernel!\n"); + exit(1); + } + + // Wait for the command commands to get serviced before reading back results + err = clFinish(ctx->commands); + if (err) { + printf("Error: Failed to execute kernel! clFinish = %d\n", err); + exit(1); + } + + // Read back the results from the device to verify the output + err = clEnqueueReadBuffer(ctx->commands, ctx->matches, CL_TRUE, 0, sizeof(uint64_t) * 8192, matches, 0, NULL, NULL); + if (err != CL_SUCCESS) { + printf("Error: Failed to read matches array! %d\n", err); + exit(1); + } + + err = clEnqueueReadBuffer(ctx->commands, ctx->matches_found, CL_TRUE, 0, sizeof(uint32_t), matches_found, 0, NULL, NULL); + if (err != CL_SUCCESS) { + printf("Error: Failed to read matches_found! %d\n", err); + exit(1); + } +} + +int main(int argc, char *argv[]) { + memset(candidates, 0, sizeof(candidates)); + struct context ctx; + uint64_t matches[8192]; + uint32_t matches_found[1]; + + // set constants + memset(bs_ones.bytes, 0xff, VECTOR_SIZE); + memset(bs_zeroes.bytes, 0x00, VECTOR_SIZE); + + uint32_t target = 0; + + if (argc < 6) { + printf("%s UID {nR1} {aR1} {nR2} {aR2}\n", argv[0]); + exit(1); + } + + if (!strncmp(argv[1], "0x", 2) || !strncmp(argv[1], "0X", 2)) { + uid = rev32(hexreversetoulong(argv[1] + 2)); + } else { + uid = rev32(hexreversetoulong(argv[1])); + } + + if (!strncmp(argv[2], "0x", 2) || !strncmp(argv[2], "0X", 2)) { + nR1 = rev32(hexreversetoulong(argv[2] + 2)); + } else { + nR1 = rev32(hexreversetoulong(argv[2])); + } + + aR1 = strtol(argv[3], NULL, 16); + + if (!strncmp(argv[4], "0x", 2) || !strncmp(argv[4], "0X", 2)) { + nR2 = rev32(hexreversetoulong(argv[4] + 2)); + } else { + nR2 = rev32(hexreversetoulong(argv[4])); + } + + aR2 = strtol(argv[5], NULL, 16); + + target = ~aR1; + // bitslice inverse target bits + bitslice(~target, keystream, 32, true); + + // bitslice all possible 256 values in the lowest 8 bits + memset(initial_bitslices[0].bytes, 0xaa, VECTOR_SIZE); + memset(initial_bitslices[1].bytes, 0xcc, VECTOR_SIZE); + memset(initial_bitslices[2].bytes, 0xf0, VECTOR_SIZE); + size_t interval = 1; + for (size_t bit = 3; bit < 8; bit++) { + for (size_t byte = 0; byte < VECTOR_SIZE;) { + for (size_t length = 0; length < interval; length++) { + initial_bitslices[bit].bytes[byte++] = 0x00; + } + for (size_t length = 0; length < interval; length++) { + initial_bitslices[bit].bytes[byte++] = 0xff; + } + } + interval <<= 1; + } + + // compute layer 0 output + for (size_t i0 = 0; i0 < 1 << 20; i0++) { + uint64_t state0 = expand(0x5806b4a2d16c, i0); + + if (f(state0) == target >> 31) { + // cf kernel, state is now split in 3 shorts >> 2 + candidates[(layer_0_found * 3) + 0] = (uint16_t)((state0 >> (32 + 2)) & 0xffff); + candidates[(layer_0_found * 3) + 1] = (uint16_t)((state0 >> (16 + 2)) & 0xffff); + candidates[(layer_0_found * 3) + 2] = (uint16_t)((state0 >> (0 + 2)) & 0xffff); + layer_0_found++; + } + } + + // load OpenCL kernel source + //////////////////////////// + struct stat filestat; + int fd; + + fd = open(KERNELFILENAME, O_RDONLY); + if (fd <= 0) { + printf("Cannot open %s\n", KERNELFILENAME); + exit(1); + } + + if (fstat(fd, &filestat)) { + printf("Cannot stat %s\n", KERNELFILENAME); + exit(1); + } + + ctx.kernelSource = (char *)malloc(filestat.st_size); + if (!ctx.kernelSource) { + printf("Cannot malloc kernelSource\n"); + exit(1); + } + + if (read(fd, ctx.kernelSource, filestat.st_size) < filestat.st_size) { + printf("Cannot read %s\n", KERNELFILENAME); + exit(1); + } + + close(fd); + + // discover and set up compute device + ///////////////////////////////////// + int err; + + // Connect to a compute device + err = clGetPlatformIDs(1, &(ctx.platform_id), NULL); + if (err != CL_SUCCESS) { + printf("Error: Failed to get platform id: %d\n", err); + exit(1); + } + + int gpu = 1; + err = clGetDeviceIDs(ctx.platform_id, gpu ? CL_DEVICE_TYPE_GPU : CL_DEVICE_TYPE_CPU, 1, &(ctx.device_id), NULL); + if (err != CL_SUCCESS) { + printf("Error: Failed to create a device group!: %d\n", err); + exit(1); + } + + // Create a compute context + ctx.context = clCreateContext(0, 1, &(ctx.device_id), NULL, NULL, &err); + if (!ctx.context) { + printf("Error: Failed to create a compute context!\n"); + exit(1); + } + + // Create a command commands + ctx.commands = clCreateCommandQueue(ctx.context, ctx.device_id, 0, &err); + if (!ctx.commands) { + printf("Error: Failed to create a command commands!\n"); + exit(1); + } + + // Create the compute program from the source buffer + ctx.program = clCreateProgramWithSource(ctx.context, 1, (const char **) & (ctx.kernelSource), NULL, &err); + if (!ctx.program) { + printf("Error: Failed to create compute program!\n"); + exit(1); + } + + // Build the program executable + err = clBuildProgram(ctx.program, 0, NULL, "-Werror", NULL, NULL); + + if (err != CL_SUCCESS) { + size_t len; + char buffer[1024 * 1024]; + + printf("Error: Failed to build program executable!\n"); + err = clGetProgramBuildInfo(ctx.program, ctx.device_id, CL_PROGRAM_BUILD_LOG, sizeof(buffer), buffer, &len); + if (err != CL_SUCCESS) { + printf("clGetProgramBuildInfo failed: %d\n", err); + exit(1); + } else { + printf("%s\n", buffer); + exit(1); + } + } + + // Create the compute kernel in the program we wish to run + ctx.kernel = clCreateKernel(ctx.program, "find_state", &err); + if (!ctx.kernel || err != CL_SUCCESS) { + printf("Error: Failed to create compute kernel!\n"); + exit(1); + } + + ctx.candidates = clCreateBuffer(ctx.context, CL_MEM_READ_ONLY, sizeof(uint16_t) * ((1 << 20) * 3), NULL, NULL); + ctx.keystream = clCreateBuffer(ctx.context, CL_MEM_READ_ONLY, VECTOR_SIZE * 32, NULL, NULL); + + ctx.matches = clCreateBuffer(ctx.context, CL_MEM_WRITE_ONLY, sizeof(uint64_t) * 8192, NULL, NULL); + ctx.matches_found = clCreateBuffer(ctx.context, CL_MEM_READ_WRITE, sizeof(uint32_t), NULL, NULL); + + if (!ctx.candidates || !ctx.keystream || !ctx.matches || !ctx.matches_found) { + printf("Error: Failed to allocate device memory!\n"); + exit(1); + } + + // set up constant vars + /////////////////////// + + // Write our data set into the input array in device memory + err = clEnqueueWriteBuffer(ctx.commands, ctx.keystream, CL_TRUE, 0, VECTOR_SIZE * 32, keystream, 0, NULL, NULL); + if (err != CL_SUCCESS) { + printf("Error: Failed to write to keystream array!\n"); + exit(1); + } + + err = clEnqueueWriteBuffer(ctx.commands, ctx.candidates, CL_TRUE, 0, sizeof(uint16_t) * ((1 << 20) * 3), candidates, 0, NULL, NULL); + if (err != CL_SUCCESS) { + printf("Error: Failed to write to candidates array!\n"); + exit(1); + } + + // Set the arguments to our compute kernel + err = clSetKernelArg(ctx.kernel, 1, sizeof(cl_mem), &ctx.candidates); + err |= clSetKernelArg(ctx.kernel, 2, sizeof(cl_mem), &ctx.keystream); + err |= clSetKernelArg(ctx.kernel, 3, sizeof(cl_mem), &ctx.matches); + if (err != CL_SUCCESS) { + printf("Error: Failed to set kernel arguments! %d\n", err); + exit(1); + } + + // run kernel + ///////////// + for (uint32_t step = 0; step < 64; step++) { + printf("slice %3u/64: ", step + 1); + fflush(stdout); + matches_found[0] = 0; + runKernel(&ctx, step << 13, matches, matches_found); + + printf("%5u candidates\n", matches_found[0]); + for (uint32_t match = 0; match < matches_found[0]; match++) { + try_state(matches[match]); + } + } + + printf("Key not found\n"); + exit(1); +} + +static void try_state(uint64_t s) { + Hitag_State hstate; + uint64_t keyrev, key, nR1xk; + uint32_t b = 0; + + hstate.shiftreg = s; + rollback(&hstate, 2); + + // recover key + keyrev = hstate.shiftreg & 0xffff; + nR1xk = (hstate.shiftreg >> 16) & 0xffffffff; + for (int i = 0; i < 32; i++) { + hstate.shiftreg = ((hstate.shiftreg) << 1) | ((uid >> (31 - i)) & 0x1); + b = (b << 1) | fnf(hstate.shiftreg); + } + keyrev |= (nR1xk ^ nR1 ^ b) << 16; + + // test key + hitag2_init(&hstate, keyrev, uid, nR2); + if ((aR2 ^ hitag2_nstep(&hstate, 32)) == 0xffffffff) { + + key = rev64(keyrev); + + printf("Key: "); + for (int i = 0; i < 6; i++) { + printf("%02X", (uint8_t)(key & 0xff)); + key = key >> 8; + } + printf("\n"); + exit(0); + } +} diff --git a/tools/hitag2crack/crack5gpu/ht2crack5kernel.cl b/tools/hitag2crack/crack5gpu/ht2crack5kernel.cl new file mode 100644 index 000000000..3f1803ee8 --- /dev/null +++ b/tools/hitag2crack/crack5gpu/ht2crack5kernel.cl @@ -0,0 +1,429 @@ +/* ht2crack5kernel.cl + * + * This code is heavily based on the HiTag2 Hell CPU implementation + * from https://github.com/factoritbv/hitag2hell by FactorIT B.V. + * This file is the file openocl.cl with the following change: + * * promote keystream from constant to argument. + */ + +#define MAX_BITSLICES 32 +#define KEYSTREAM_LENGTH 32 +typedef uint bitslice_t __attribute__((aligned(MAX_BITSLICES / 8))); + +inline uint lut3(uint a, uint b, uint c, uint imm) { + uint r; + asm("lop3.b32 %0, %1, %2, %3, %4;" + : "=r"(r) + : "r"(a), "r"(b), "r"(c), "i"(imm)); + return r; +} +#define f_a_bs_lut_1 (((0xf0|0xcc)&0xaa)^0xcc) +#define f_a_bs_lut_2 (~((0xf0|0xcc)^0xaa)) +#define f_a_bs(a,b,c,d) ((lut3(a,d,lut3(a,b,c,f_a_bs_lut_1),f_a_bs_lut_2))) // 2 luts + +#define f_b_bs_lut_1 (((0xf0|0xcc)&0xaa)) +#define f_b_bs_lut_2 (~((0xf0|0xcc|0xaa))) +#define f_b_bs(a,b,c,d) ((lut3(d,c,a^b,f_b_bs_lut_1)^lut3(d,a,b, f_b_bs_lut_2))) // 2 luts, 2 xors + +#define f_c_bs_lut_1 (((0xf0^0xcc)|0xaa)) +#define f_c_bs_lut_2 (~((0xf0^0xcc)&(0xaa^0xcc))) + +// 4 luts, 2 ands, 1 xor +#define f_c_bs(a,b,c,d,e) (((lut3((lut3(c,e,d, f_c_bs_lut_1) & a), b, c, f_c_bs_lut_2)) ^ (lut3(d,e,a, f_c_bs_lut_1) & lut3(d,b,c,f_c_bs_lut_1)))) + +// non-lut version of F: 20 lookups + 6*2 + 7*3 + 13 + = 66 ops +// lut version: 20 lookups + 2*2 + 4*3 + 7 + = 43 ops + +#define lfsr_lut (0xf0^0xaa^0xcc) +// 7 luts, 1 xor +#define lfsr_bs(i) ( lut3(lut3(lut3(state[-2+i+ 0], state[-2+i+ 2], state[-2+i+ 3], lfsr_lut), \ + lut3(state[-2+i+ 6], state[-2+i+ 7], state[-2+i+ 8], lfsr_lut), \ + lut3(state[-2+i+16], state[-2+i+22], state[-2+i+23], lfsr_lut), \ + lfsr_lut), \ + lut3(state[-2+i+26], state[-2+i+30], state[-2+i+41], lfsr_lut), \ + lut3(state[-2+i+42], state[-2+i+43], state[-2+i+46], lfsr_lut), lfsr_lut) ^ state[-2+i+47]) + +// 46 iterations * 4 ops +inline void bitslice(bitslice_t *restrict b, ulong x, const uchar n) { + for (uchar i = 0; i < n; ++i) { + b[i] = -(x & 1); + x >>= 1; + } +} + +// don't care about the complexity of this function +inline ulong unbitslice(const bitslice_t *restrict b, const uchar s, const uchar n) { + const bitslice_t mask = ((bitslice_t) 1) << s; + ulong result = 0; + for (char i = n - 1; i >= 0; --i) { + result <<= 1; + result |= (bool)(b[i] & mask); + } + return result; +} + +// format this array with 32 bitsliced vectors of ones and zeroes representing the inverted keystream + +__kernel +__attribute__((vec_type_hint(bitslice_t))) +void find_state(const uint candidate_index_base, + __global const ushort *restrict candidates, + __global const bitslice_t *restrict keystream, + __global ulong *restrict matches, + __global uint *restrict matches_found) { + // we never actually set or use the lowest 2 bits the initial state, so we can save 2 bitslices everywhere + bitslice_t state[-2 + 48 + KEYSTREAM_LENGTH]; + // set bits 0+2, 0+3, 0+5, 0+6, 0+8, 0+12, 0+14, 0+15, 0+17, 0+21, 0+23, 0+26, 0+28, 0+29, 0+31, 0+33, 0+34, 0+43, 0+44, 0+46 + // get the 48-bit cipher states as 3 16-bit words from the host memory queue (to save 25% throughput) + const uint index = 3 * (candidate_index_base + get_global_id(0)); // dimension 0 should at least keep the execution units saturated - 8k is fine + const ulong candidate = ((ulong) candidates[index] << 32) | ((ulong) candidates[index + 1] << 16) | candidates[index + 2]; + // set all 48 state bits except the lowest 2 + bitslice(&state[-2 + 2], candidate, 46); + // set bits 3, 6, 8, 12, 15 + state[-2 + 1 + 3] = 0xaaaaaaaa; + state[-2 + 1 + 6] = 0xcccccccc; + state[-2 + 1 + 8] = 0xf0f0f0f0; + state[-2 + 1 + 12] = 0xff00ff00; + state[-2 + 1 + 15] = 0xffff0000; + ushort i1 = get_global_id(1); // dimension 1 should be 1024 + state[-2 + 18] = -((bool)(i1 & 0x1)); + state[-2 + 22] = -((bool)(i1 & 0x2)); + state[-2 + 24] = -((bool)(i1 & 0x4)); + state[-2 + 27] = -((bool)(i1 & 0x8)); + state[-2 + 30] = -((bool)(i1 & 0x10)); + state[-2 + 32] = -((bool)(i1 & 0x20)); + state[-2 + 35] = -((bool)(i1 & 0x40)); + state[-2 + 45] = -((bool)(i1 & 0x80)); + state[-2 + 47] = -((bool)(i1 & 0x100)); + state[-2 + 48] = -((bool)(i1 & 0x200)); // guess lfsr output 0 + // 0xfc07fef3f9fe + const bitslice_t filter1_0 = f_a_bs(state[-2 + 3], state[-2 + 4], state[-2 + 6], state[-2 + 7]); + const bitslice_t filter1_1 = f_b_bs(state[-2 + 9], state[-2 + 13], state[-2 + 15], state[-2 + 16]); + const bitslice_t filter1_2 = f_b_bs(state[-2 + 18], state[-2 + 22], state[-2 + 24], state[-2 + 27]); + const bitslice_t filter1_3 = f_b_bs(state[-2 + 29], state[-2 + 30], state[-2 + 32], state[-2 + 34]); + const bitslice_t filter1_4 = f_a_bs(state[-2 + 35], state[-2 + 44], state[-2 + 45], state[-2 + 47]); + const bitslice_t filter1 = f_c_bs(filter1_0, filter1_1, filter1_2, filter1_3, filter1_4); + const bitslice_t results1 = filter1 ^ keystream[1]; + if (!results1) return; + const bitslice_t filter2_0 = f_a_bs(state[-2 + 4], state[-2 + 5], state[-2 + 7], state[-2 + 8]); + const bitslice_t filter2_3 = f_b_bs(state[-2 + 30], state[-2 + 31], state[-2 + 33], state[-2 + 35]); + const bitslice_t filter3_0 = f_a_bs(state[-2 + 5], state[-2 + 6], state[-2 + 8], state[-2 + 9]); + const bitslice_t filter5_2 = f_b_bs(state[-2 + 22], state[-2 + 26], state[-2 + 28], state[-2 + 31]); + const bitslice_t filter6_2 = f_b_bs(state[-2 + 23], state[-2 + 27], state[-2 + 29], state[-2 + 32]); + const bitslice_t filter7_2 = f_b_bs(state[-2 + 24], state[-2 + 28], state[-2 + 30], state[-2 + 33]); + const bitslice_t filter9_1 = f_b_bs(state[-2 + 17], state[-2 + 21], state[-2 + 23], state[-2 + 24]); + const bitslice_t filter9_2 = f_b_bs(state[-2 + 26], state[-2 + 30], state[-2 + 32], state[-2 + 35]); + const bitslice_t filter10_0 = f_a_bs(state[-2 + 12], state[-2 + 13], state[-2 + 15], state[-2 + 16]); + const bitslice_t filter11_0 = f_a_bs(state[-2 + 13], state[-2 + 14], state[-2 + 16], state[-2 + 17]); + const bitslice_t filter12_0 = f_a_bs(state[-2 + 14], state[-2 + 15], state[-2 + 17], state[-2 + 18]); + const bitslice_t filter14_1 = f_b_bs(state[-2 + 22], state[-2 + 26], state[-2 + 28], state[-2 + 29]); + const bitslice_t filter15_1 = f_b_bs(state[-2 + 23], state[-2 + 27], state[-2 + 29], state[-2 + 30]); + const bitslice_t filter15_3 = f_b_bs(state[-2 + 43], state[-2 + 44], state[-2 + 46], state[-2 + 48]); + const bitslice_t filter16_1 = f_b_bs(state[-2 + 24], state[-2 + 28], state[-2 + 30], state[-2 + 31]); + for (uchar i2 = 0; i2 < (1 << 5);) { + state[-2 + 10] = -((bool)(i2 & 0x1)); + state[-2 + 19] = -((bool)(i2 & 0x2)); + state[-2 + 25] = -((bool)(i2 & 0x4)); + state[-2 + 36] = -((bool)(i2 & 0x8)); + state[-2 + 49] = -((bool)(i2 & 0x10)); // guess lfsr output 1 + i2++; + // 0xfe07fffbfdff + const bitslice_t filter2_1 = f_b_bs(state[-2 + 10], state[-2 + 14], state[-2 + 16], state[-2 + 17]); + const bitslice_t filter2_2 = f_b_bs(state[-2 + 19], state[-2 + 23], state[-2 + 25], state[-2 + 28]); + const bitslice_t filter2_4 = f_a_bs(state[-2 + 36], state[-2 + 45], state[-2 + 46], state[-2 + 48]); + const bitslice_t filter2 = f_c_bs(filter2_0, filter2_1, filter2_2, filter2_3, filter2_4); + const bitslice_t results2 = results1 & (filter2 ^ keystream[2]); + if (!results2) continue; + state[-2 + 50] = lfsr_bs(2); + const bitslice_t filter3_3 = f_b_bs(state[-2 + 31], state[-2 + 32], state[-2 + 34], state[-2 + 36]); + const bitslice_t filter4_0 = f_a_bs(state[-2 + 6], state[-2 + 7], state[-2 + 9], state[-2 + 10]); + const bitslice_t filter4_1 = f_b_bs(state[-2 + 12], state[-2 + 16], state[-2 + 18], state[-2 + 19]); + const bitslice_t filter4_2 = f_b_bs(state[-2 + 21], state[-2 + 25], state[-2 + 27], state[-2 + 30]); + const bitslice_t filter7_0 = f_a_bs(state[-2 + 9], state[-2 + 10], state[-2 + 12], state[-2 + 13]); + const bitslice_t filter7_1 = f_b_bs(state[-2 + 15], state[-2 + 19], state[-2 + 21], state[-2 + 22]); + const bitslice_t filter8_2 = f_b_bs(state[-2 + 25], state[-2 + 29], state[-2 + 31], state[-2 + 34]); + const bitslice_t filter10_1 = f_b_bs(state[-2 + 18], state[-2 + 22], state[-2 + 24], state[-2 + 25]); + const bitslice_t filter10_2 = f_b_bs(state[-2 + 27], state[-2 + 31], state[-2 + 33], state[-2 + 36]); + const bitslice_t filter11_1 = f_b_bs(state[-2 + 19], state[-2 + 23], state[-2 + 25], state[-2 + 26]); + const bitslice_t filter13_0 = f_a_bs(state[-2 + 15], state[-2 + 16], state[-2 + 18], state[-2 + 19]); + const bitslice_t filter13_1 = f_b_bs(state[-2 + 21], state[-2 + 25], state[-2 + 27], state[-2 + 28]); + const bitslice_t filter16_0 = f_a_bs(state[-2 + 18], state[-2 + 19], state[-2 + 21], state[-2 + 22]); + const bitslice_t filter16_3 = f_b_bs(state[-2 + 44], state[-2 + 45], state[-2 + 47], state[-2 + 49]); + const bitslice_t filter17_1 = f_b_bs(state[-2 + 25], state[-2 + 29], state[-2 + 31], state[-2 + 32]); + const bitslice_t filter17_3 = f_b_bs(state[-2 + 45], state[-2 + 46], state[-2 + 48], state[-2 + 50]); + for (uchar i3 = 0; i3 < (1 << 3);) { + state[-2 + 11] = -((bool)(i3 & 0x1)); + state[-2 + 20] = -((bool)(i3 & 0x2)); + state[-2 + 37] = -((bool)(i3 & 0x4)); + i3++; + // 0xff07ffffffff + const bitslice_t filter3_1 = f_b_bs(state[-2 + 11], state[-2 + 15], state[-2 + 17], state[-2 + 18]); + const bitslice_t filter3_2 = f_b_bs(state[-2 + 20], state[-2 + 24], state[-2 + 26], state[-2 + 29]); + const bitslice_t filter3_4 = f_a_bs(state[-2 + 37], state[-2 + 46], state[-2 + 47], state[-2 + 49]); + const bitslice_t filter3 = f_c_bs(filter3_0, filter3_1, filter3_2, filter3_3, filter3_4); + const bitslice_t results3 = results2 & (filter3 ^ keystream[3]); + if (!results3) continue; + state[-2 + 51] = lfsr_bs(3); + state[-2 + 52] = lfsr_bs(4); + state[-2 + 53] = lfsr_bs(5); + state[-2 + 54] = lfsr_bs(6); + state[-2 + 55] = lfsr_bs(7); + const bitslice_t filter4_3 = f_b_bs(state[-2 + 32], state[-2 + 33], state[-2 + 35], state[-2 + 37]); + const bitslice_t filter5_0 = f_a_bs(state[-2 + 7], state[-2 + 8], state[-2 + 10], state[-2 + 11]); + const bitslice_t filter5_1 = f_b_bs(state[-2 + 13], state[-2 + 17], state[-2 + 19], state[-2 + 20]); + const bitslice_t filter6_0 = f_a_bs(state[-2 + 8], state[-2 + 9], state[-2 + 11], state[-2 + 12]); + const bitslice_t filter6_1 = f_b_bs(state[-2 + 14], state[-2 + 18], state[-2 + 20], state[-2 + 21]); + const bitslice_t filter8_0 = f_a_bs(state[-2 + 10], state[-2 + 11], state[-2 + 13], state[-2 + 14]); + const bitslice_t filter8_1 = f_b_bs(state[-2 + 16], state[-2 + 20], state[-2 + 22], state[-2 + 23]); + const bitslice_t filter9_0 = f_a_bs(state[-2 + 11], state[-2 + 12], state[-2 + 14], state[-2 + 15]); + const bitslice_t filter9_4 = f_a_bs(state[-2 + 43], state[-2 + 52], state[-2 + 53], state[-2 + 55]); + const bitslice_t filter11_2 = f_b_bs(state[-2 + 28], state[-2 + 32], state[-2 + 34], state[-2 + 37]); + const bitslice_t filter12_1 = f_b_bs(state[-2 + 20], state[-2 + 24], state[-2 + 26], state[-2 + 27]); + const bitslice_t filter14_0 = f_a_bs(state[-2 + 16], state[-2 + 17], state[-2 + 19], state[-2 + 20]); + const bitslice_t filter15_0 = f_a_bs(state[-2 + 17], state[-2 + 18], state[-2 + 20], state[-2 + 21]); + const bitslice_t filter17_0 = f_a_bs(state[-2 + 19], state[-2 + 20], state[-2 + 22], state[-2 + 23]); + for (uchar i4 = 0; i4 < (1 << 1);) { + state[-2 + 38] = -i4; + i4++; + // 0xff87ffffffff + const bitslice_t filter4_4 = f_a_bs(state[-2 + 38], state[-2 + 47], state[-2 + 48], state[-2 + 50]); + const bitslice_t filter4 = f_c_bs(filter4_0, filter4_1, filter4_2, filter4_3, filter4_4); + const bitslice_t results4 = results3 & (filter4 ^ keystream[4]); + if (!results4) continue; + state[-2 + 56] = lfsr_bs(8); + const bitslice_t filter5_3 = f_b_bs(state[-2 + 33], state[-2 + 34], state[-2 + 36], state[-2 + 38]); + const bitslice_t filter10_4 = f_a_bs(state[-2 + 44], state[-2 + 53], state[-2 + 54], state[-2 + 56]); + const bitslice_t filter12_2 = f_b_bs(state[-2 + 29], state[-2 + 33], state[-2 + 35], state[-2 + 38]); + for (uchar i5 = 0; i5 < (1 << 1);) { + state[-2 + 39] = -i5; + i5++; + // 0xffc7ffffffff + const bitslice_t filter5_4 = f_a_bs(state[-2 + 39], state[-2 + 48], state[-2 + 49], state[-2 + 51]); + const bitslice_t filter5 = f_c_bs(filter5_0, filter5_1, filter5_2, filter5_3, filter5_4); + const bitslice_t results5 = results4 & (filter5 ^ keystream[5]); + if (!results5) continue; + state[-2 + 57] = lfsr_bs(9); + const bitslice_t filter6_3 = f_b_bs(state[-2 + 34], state[-2 + 35], state[-2 + 37], state[-2 + 39]); + const bitslice_t filter11_4 = f_a_bs(state[-2 + 45], state[-2 + 54], state[-2 + 55], state[-2 + 57]); + const bitslice_t filter13_2 = f_b_bs(state[-2 + 30], state[-2 + 34], state[-2 + 36], state[-2 + 39]); + for (uchar i6 = 0; i6 < (1 << 1);) { + state[-2 + 40] = -i6; + i6++; + // 0xffe7ffffffff + const bitslice_t filter6_4 = f_a_bs(state[-2 + 40], state[-2 + 49], state[-2 + 50], state[-2 + 52]); + const bitslice_t filter6 = f_c_bs(filter6_0, filter6_1, filter6_2, filter6_3, filter6_4); + const bitslice_t results6 = results5 & (filter6 ^ keystream[6]); + if (!results6) continue; + state[-2 + 58] = lfsr_bs(10); + const bitslice_t filter7_3 = f_b_bs(state[-2 + 35], state[-2 + 36], state[-2 + 38], state[-2 + 40]); + const bitslice_t filter12_4 = f_a_bs(state[-2 + 46], state[-2 + 55], state[-2 + 56], state[-2 + 58]); + const bitslice_t filter14_2 = f_b_bs(state[-2 + 31], state[-2 + 35], state[-2 + 37], state[-2 + 40]); + const bitslice_t filter17_2 = f_b_bs(state[-2 + 34], state[-2 + 38], state[-2 + 40], state[-2 + 43]); +#pragma unroll + for (uchar i7 = 0; i7 < (1 << 1);) { + state[-2 + 41] = -i7; + i7++; + // 0xfff7ffffffff + const bitslice_t filter7_4 = f_a_bs(state[-2 + 41], state[-2 + 50], state[-2 + 51], state[-2 + 53]); + const bitslice_t filter7 = f_c_bs(filter7_0, filter7_1, filter7_2, filter7_3, filter7_4); + const bitslice_t results7 = results6 & (filter7 ^ keystream[7]); + if (!results7) continue; + state[-2 + 59] = lfsr_bs(11); + const bitslice_t filter8_3 = f_b_bs(state[-2 + 36], state[-2 + 37], state[-2 + 39], state[-2 + 41]); + const bitslice_t filter10_3 = f_b_bs(state[-2 + 38], state[-2 + 39], state[-2 + 41], state[-2 + 43]); + const bitslice_t filter10 = f_c_bs(filter10_0, filter10_1, filter10_2, filter10_3, filter10_4); + const bitslice_t filter12_3 = f_b_bs(state[-2 + 40], state[-2 + 41], state[-2 + 43], state[-2 + 45]); + const bitslice_t filter12 = f_c_bs(filter12_0, filter12_1, filter12_2, filter12_3, filter12_4); + const bitslice_t filter13_4 = f_a_bs(state[-2 + 47], state[-2 + 56], state[-2 + 57], state[-2 + 59]); + const bitslice_t filter15_2 = f_b_bs(state[-2 + 32], state[-2 + 36], state[-2 + 38], state[-2 + 41]); +#pragma unroll + for (uchar i8 = 0; i8 < (1 << 1);) { + state[-2 + 42] = -i8; + i8++; + // 0xffffffffffff + const bitslice_t filter8_4 = f_a_bs(state[-2 + 42], state[-2 + 51], state[-2 + 52], state[-2 + 54]); + const bitslice_t filter8 = f_c_bs(filter8_0, filter8_1, filter8_2, filter8_3, filter8_4); + bitslice_t results8 = results7 & (filter8 ^ keystream[8]); + if (!results8) continue; + const bitslice_t filter9_3 = f_b_bs(state[-2 + 37], state[-2 + 38], state[-2 + 40], state[-2 + 42]); + const bitslice_t filter9 = f_c_bs(filter9_0, filter9_1, filter9_2, filter9_3, filter9_4); + results8 &= (filter9 ^ keystream[9]); + if (!results8) continue; + results8 &= (filter10 ^ keystream[10]); + if (!results8) continue; + const bitslice_t filter11_3 = f_b_bs(state[-2 + 39], state[-2 + 40], state[-2 + 42], state[-2 + 44]); + const bitslice_t filter11 = f_c_bs(filter11_0, filter11_1, filter11_2, filter11_3, filter11_4); + results8 &= (filter11 ^ keystream[11]); + if (!results8) continue; + results8 &= (filter12 ^ keystream[12]); + if (!results8) continue; + const bitslice_t filter13_3 = f_b_bs(state[-2 + 41], state[-2 + 42], state[-2 + 44], state[-2 + 46]); + const bitslice_t filter13 = f_c_bs(filter13_0, filter13_1, filter13_2, filter13_3, filter13_4); + results8 &= (filter13 ^ keystream[13]); + if (!results8) continue; + state[-2 + 60] = lfsr_bs(12); + const bitslice_t filter14_3 = f_b_bs(state[-2 + 42], state[-2 + 43], state[-2 + 45], state[-2 + 47]); + const bitslice_t filter14_4 = f_a_bs(state[-2 + 48], state[-2 + 57], state[-2 + 58], state[-2 + 60]); + const bitslice_t filter14 = f_c_bs(filter14_0, filter14_1, filter14_2, filter14_3, filter14_4); + results8 &= (filter14 ^ keystream[14]); + if (!results8) continue; + state[-2 + 61] = lfsr_bs(13); + const bitslice_t filter15_4 = f_a_bs(state[-2 + 49], state[-2 + 58], state[-2 + 59], state[-2 + 61]); + const bitslice_t filter15 = f_c_bs(filter15_0, filter15_1, filter15_2, filter15_3, filter15_4); + results8 &= (filter15 ^ keystream[15]); + if (!results8) continue; + state[-2 + 62] = lfsr_bs(14); + const bitslice_t filter16_2 = f_b_bs(state[-2 + 33], state[-2 + 37], state[-2 + 39], state[-2 + 42]); + const bitslice_t filter16_4 = f_a_bs(state[-2 + 50], state[-2 + 59], state[-2 + 60], state[-2 + 62]); + const bitslice_t filter16 = f_c_bs(filter16_0, filter16_1, filter16_2, filter16_3, filter16_4); + results8 &= (filter16 ^ keystream[16]); + if (!results8) continue; + state[-2 + 63] = lfsr_bs(15); + const bitslice_t filter17_4 = f_a_bs(state[-2 + 51], state[-2 + 60], state[-2 + 61], state[-2 + 63]); + const bitslice_t filter17 = f_c_bs(filter17_0, filter17_1, filter17_2, filter17_3, filter17_4); + results8 &= (filter17 ^ keystream[17]); + if (!results8) continue; + state[-2 + 64] = lfsr_bs(16); + const bitslice_t filter18_0 = f_a_bs(state[-2 + 20], state[-2 + 21], state[-2 + 23], state[-2 + 24]); + const bitslice_t filter18_1 = f_b_bs(state[-2 + 26], state[-2 + 30], state[-2 + 32], state[-2 + 33]); + const bitslice_t filter18_2 = f_b_bs(state[-2 + 35], state[-2 + 39], state[-2 + 41], state[-2 + 44]); + const bitslice_t filter18_3 = f_b_bs(state[-2 + 46], state[-2 + 47], state[-2 + 49], state[-2 + 51]); + const bitslice_t filter18_4 = f_a_bs(state[-2 + 52], state[-2 + 61], state[-2 + 62], state[-2 + 64]); + const bitslice_t filter18 = f_c_bs(filter18_0, filter18_1, filter18_2, filter18_3, filter18_4); + results8 &= (filter18 ^ keystream[18]); + if (!results8) continue; + state[-2 + 65] = lfsr_bs(17); + const bitslice_t filter19_0 = f_a_bs(state[-2 + 21], state[-2 + 22], state[-2 + 24], state[-2 + 25]); + const bitslice_t filter19_1 = f_b_bs(state[-2 + 27], state[-2 + 31], state[-2 + 33], state[-2 + 34]); + const bitslice_t filter19_2 = f_b_bs(state[-2 + 36], state[-2 + 40], state[-2 + 42], state[-2 + 45]); + const bitslice_t filter19_3 = f_b_bs(state[-2 + 47], state[-2 + 48], state[-2 + 50], state[-2 + 52]); + const bitslice_t filter19_4 = f_a_bs(state[-2 + 53], state[-2 + 62], state[-2 + 63], state[-2 + 65]); + const bitslice_t filter19 = f_c_bs(filter19_0, filter19_1, filter19_2, filter19_3, filter19_4); + results8 &= (filter19 ^ keystream[19]); + if (!results8) continue; + state[-2 + 66] = lfsr_bs(18); + const bitslice_t filter20_0 = f_a_bs(state[-2 + 22], state[-2 + 23], state[-2 + 25], state[-2 + 26]); + const bitslice_t filter20_1 = f_b_bs(state[-2 + 28], state[-2 + 32], state[-2 + 34], state[-2 + 35]); + const bitslice_t filter20_2 = f_b_bs(state[-2 + 37], state[-2 + 41], state[-2 + 43], state[-2 + 46]); + const bitslice_t filter20_3 = f_b_bs(state[-2 + 48], state[-2 + 49], state[-2 + 51], state[-2 + 53]); + const bitslice_t filter20_4 = f_a_bs(state[-2 + 54], state[-2 + 63], state[-2 + 64], state[-2 + 66]); + const bitslice_t filter20 = f_c_bs(filter20_0, filter20_1, filter20_2, filter20_3, filter20_4); + results8 &= (filter20 ^ keystream[20]); + if (!results8) continue; + state[-2 + 67] = lfsr_bs(19); + const bitslice_t filter21_0 = f_a_bs(state[-2 + 23], state[-2 + 24], state[-2 + 26], state[-2 + 27]); + const bitslice_t filter21_1 = f_b_bs(state[-2 + 29], state[-2 + 33], state[-2 + 35], state[-2 + 36]); + const bitslice_t filter21_2 = f_b_bs(state[-2 + 38], state[-2 + 42], state[-2 + 44], state[-2 + 47]); + const bitslice_t filter21_3 = f_b_bs(state[-2 + 49], state[-2 + 50], state[-2 + 52], state[-2 + 54]); + const bitslice_t filter21_4 = f_a_bs(state[-2 + 55], state[-2 + 64], state[-2 + 65], state[-2 + 67]); + const bitslice_t filter21 = f_c_bs(filter21_0, filter21_1, filter21_2, filter21_3, filter21_4); + results8 &= (filter21 ^ keystream[21]); + if (!results8) continue; + state[-2 + 68] = lfsr_bs(20); + const bitslice_t filter22_0 = f_a_bs(state[-2 + 24], state[-2 + 25], state[-2 + 27], state[-2 + 28]); + const bitslice_t filter22_1 = f_b_bs(state[-2 + 30], state[-2 + 34], state[-2 + 36], state[-2 + 37]); + const bitslice_t filter22_2 = f_b_bs(state[-2 + 39], state[-2 + 43], state[-2 + 45], state[-2 + 48]); + const bitslice_t filter22_3 = f_b_bs(state[-2 + 50], state[-2 + 51], state[-2 + 53], state[-2 + 55]); + const bitslice_t filter22_4 = f_a_bs(state[-2 + 56], state[-2 + 65], state[-2 + 66], state[-2 + 68]); + const bitslice_t filter22 = f_c_bs(filter22_0, filter22_1, filter22_2, filter22_3, filter22_4); + results8 &= (filter22 ^ keystream[22]); + if (!results8) continue; + state[-2 + 69] = lfsr_bs(21); + const bitslice_t filter23_0 = f_a_bs(state[-2 + 25], state[-2 + 26], state[-2 + 28], state[-2 + 29]); + const bitslice_t filter23_1 = f_b_bs(state[-2 + 31], state[-2 + 35], state[-2 + 37], state[-2 + 38]); + const bitslice_t filter23_2 = f_b_bs(state[-2 + 40], state[-2 + 44], state[-2 + 46], state[-2 + 49]); + const bitslice_t filter23_3 = f_b_bs(state[-2 + 51], state[-2 + 52], state[-2 + 54], state[-2 + 56]); + const bitslice_t filter23_4 = f_a_bs(state[-2 + 57], state[-2 + 66], state[-2 + 67], state[-2 + 69]); + const bitslice_t filter23 = f_c_bs(filter23_0, filter23_1, filter23_2, filter23_3, filter23_4); + results8 &= (filter23 ^ keystream[23]); + if (!results8) continue; + state[-2 + 70] = lfsr_bs(22); + const bitslice_t filter24_0 = f_a_bs(state[-2 + 26], state[-2 + 27], state[-2 + 29], state[-2 + 30]); + const bitslice_t filter24_1 = f_b_bs(state[-2 + 32], state[-2 + 36], state[-2 + 38], state[-2 + 39]); + const bitslice_t filter24_2 = f_b_bs(state[-2 + 41], state[-2 + 45], state[-2 + 47], state[-2 + 50]); + const bitslice_t filter24_3 = f_b_bs(state[-2 + 52], state[-2 + 53], state[-2 + 55], state[-2 + 57]); + const bitslice_t filter24_4 = f_a_bs(state[-2 + 58], state[-2 + 67], state[-2 + 68], state[-2 + 70]); + const bitslice_t filter24 = f_c_bs(filter24_0, filter24_1, filter24_2, filter24_3, filter24_4); + results8 &= (filter24 ^ keystream[24]); + if (!results8) continue; + state[-2 + 71] = lfsr_bs(23); + const bitslice_t filter25_0 = f_a_bs(state[-2 + 27], state[-2 + 28], state[-2 + 30], state[-2 + 31]); + const bitslice_t filter25_1 = f_b_bs(state[-2 + 33], state[-2 + 37], state[-2 + 39], state[-2 + 40]); + const bitslice_t filter25_2 = f_b_bs(state[-2 + 42], state[-2 + 46], state[-2 + 48], state[-2 + 51]); + const bitslice_t filter25_3 = f_b_bs(state[-2 + 53], state[-2 + 54], state[-2 + 56], state[-2 + 58]); + const bitslice_t filter25_4 = f_a_bs(state[-2 + 59], state[-2 + 68], state[-2 + 69], state[-2 + 71]); + const bitslice_t filter25 = f_c_bs(filter25_0, filter25_1, filter25_2, filter25_3, filter25_4); + results8 &= (filter25 ^ keystream[25]); + if (!results8) continue; + state[-2 + 72] = lfsr_bs(24); + const bitslice_t filter26_0 = f_a_bs(state[-2 + 28], state[-2 + 29], state[-2 + 31], state[-2 + 32]); + const bitslice_t filter26_1 = f_b_bs(state[-2 + 34], state[-2 + 38], state[-2 + 40], state[-2 + 41]); + const bitslice_t filter26_2 = f_b_bs(state[-2 + 43], state[-2 + 47], state[-2 + 49], state[-2 + 52]); + const bitslice_t filter26_3 = f_b_bs(state[-2 + 54], state[-2 + 55], state[-2 + 57], state[-2 + 59]); + const bitslice_t filter26_4 = f_a_bs(state[-2 + 60], state[-2 + 69], state[-2 + 70], state[-2 + 72]); + const bitslice_t filter26 = f_c_bs(filter26_0, filter26_1, filter26_2, filter26_3, filter26_4); + results8 &= (filter26 ^ keystream[26]); + if (!results8) continue; + state[-2 + 73] = lfsr_bs(25); + const bitslice_t filter27_0 = f_a_bs(state[-2 + 29], state[-2 + 30], state[-2 + 32], state[-2 + 33]); + const bitslice_t filter27_1 = f_b_bs(state[-2 + 35], state[-2 + 39], state[-2 + 41], state[-2 + 42]); + const bitslice_t filter27_2 = f_b_bs(state[-2 + 44], state[-2 + 48], state[-2 + 50], state[-2 + 53]); + const bitslice_t filter27_3 = f_b_bs(state[-2 + 55], state[-2 + 56], state[-2 + 58], state[-2 + 60]); + const bitslice_t filter27_4 = f_a_bs(state[-2 + 61], state[-2 + 70], state[-2 + 71], state[-2 + 73]); + const bitslice_t filter27 = f_c_bs(filter27_0, filter27_1, filter27_2, filter27_3, filter27_4); + results8 &= (filter27 ^ keystream[27]); + if (!results8) continue; + state[-2 + 74] = lfsr_bs(26); + const bitslice_t filter28_0 = f_a_bs(state[-2 + 30], state[-2 + 31], state[-2 + 33], state[-2 + 34]); + const bitslice_t filter28_1 = f_b_bs(state[-2 + 36], state[-2 + 40], state[-2 + 42], state[-2 + 43]); + const bitslice_t filter28_2 = f_b_bs(state[-2 + 45], state[-2 + 49], state[-2 + 51], state[-2 + 54]); + const bitslice_t filter28_3 = f_b_bs(state[-2 + 56], state[-2 + 57], state[-2 + 59], state[-2 + 61]); + const bitslice_t filter28_4 = f_a_bs(state[-2 + 62], state[-2 + 71], state[-2 + 72], state[-2 + 74]); + const bitslice_t filter28 = f_c_bs(filter28_0, filter28_1, filter28_2, filter28_3, filter28_4); + results8 &= (filter28 ^ keystream[28]); + if (!results8) continue; + state[-2 + 75] = lfsr_bs(27); + const bitslice_t filter29_0 = f_a_bs(state[-2 + 31], state[-2 + 32], state[-2 + 34], state[-2 + 35]); + const bitslice_t filter29_1 = f_b_bs(state[-2 + 37], state[-2 + 41], state[-2 + 43], state[-2 + 44]); + const bitslice_t filter29_2 = f_b_bs(state[-2 + 46], state[-2 + 50], state[-2 + 52], state[-2 + 55]); + const bitslice_t filter29_3 = f_b_bs(state[-2 + 57], state[-2 + 58], state[-2 + 60], state[-2 + 62]); + const bitslice_t filter29_4 = f_a_bs(state[-2 + 63], state[-2 + 72], state[-2 + 73], state[-2 + 75]); + const bitslice_t filter29 = f_c_bs(filter29_0, filter29_1, filter29_2, filter29_3, filter29_4); + results8 &= (filter29 ^ keystream[29]); + if (!results8) continue; + state[-2 + 76] = lfsr_bs(28); + const bitslice_t filter30_0 = f_a_bs(state[-2 + 32], state[-2 + 33], state[-2 + 35], state[-2 + 36]); + const bitslice_t filter30_1 = f_b_bs(state[-2 + 38], state[-2 + 42], state[-2 + 44], state[-2 + 45]); + const bitslice_t filter30_2 = f_b_bs(state[-2 + 47], state[-2 + 51], state[-2 + 53], state[-2 + 56]); + const bitslice_t filter30_3 = f_b_bs(state[-2 + 58], state[-2 + 59], state[-2 + 61], state[-2 + 63]); + const bitslice_t filter30_4 = f_a_bs(state[-2 + 64], state[-2 + 73], state[-2 + 74], state[-2 + 76]); + const bitslice_t filter30 = f_c_bs(filter30_0, filter30_1, filter30_2, filter30_3, filter30_4); + results8 &= (filter30 ^ keystream[30]); + if (!results8) continue; + state[-2 + 77] = lfsr_bs(29); + const bitslice_t filter31_0 = f_a_bs(state[-2 + 33], state[-2 + 34], state[-2 + 36], state[-2 + 37]); + const bitslice_t filter31_1 = f_b_bs(state[-2 + 39], state[-2 + 43], state[-2 + 45], state[-2 + 46]); + const bitslice_t filter31_2 = f_b_bs(state[-2 + 48], state[-2 + 52], state[-2 + 54], state[-2 + 57]); + const bitslice_t filter31_3 = f_b_bs(state[-2 + 59], state[-2 + 60], state[-2 + 62], state[-2 + 64]); + const bitslice_t filter31_4 = f_a_bs(state[-2 + 65], state[-2 + 74], state[-2 + 75], state[-2 + 77]); + const bitslice_t filter31 = f_c_bs(filter31_0, filter31_1, filter31_2, filter31_3, filter31_4); + results8 &= (filter31 ^ keystream[31]); + if (!results8) continue; + uchar match_index = 0; + // Save results + while (results8 && (match_index < MAX_BITSLICES)) { + uchar shift = clz(results8) + 1; + match_index += shift; + // take the state from layer 2 so we can recover the lowest 2 bits on the host by inverting the LFSR + matches[atomic_inc(matches_found)] = unbitslice(&state[-2 + 2], MAX_BITSLICES - match_index, 48); + results8 <<= shift; + } + } // 8 + } // 7 + } // 6 + } // 5 + } // 4 + } // 3 + } // 2 +} // 1 + diff --git a/tools/hitag2crack/crack5gpu/rfidler.h b/tools/hitag2crack/crack5gpu/rfidler.h new file mode 100644 index 000000000..933547e6b --- /dev/null +++ b/tools/hitag2crack/crack5gpu/rfidler.h @@ -0,0 +1,412 @@ +/*************************************************************************** + * A copy of the GNU GPL is appended to this file. * + * * + * This licence is based on the nmap licence, and we express our gratitude * + * for the work that went into producing it. There is no other connection * + * between RFIDler and nmap either expressed or implied. * + * * + ********************** IMPORTANT RFIDler LICENSE TERMS ******************** + * * + * * + * All references to RFIDler herein imply all it's derivatives, namely: * + * * + * o RFIDler-LF Standard * + * o RFIDler-LF Lite * + * o RFIDler-LF Nekkid * + * * + * * + * RFIDler is (C) 2013-2015 Aperture Labs Ltd. * + * * + * This program is free software; you may redistribute and/or modify it * + * under the terms of the GNU General Public License as published by the * + * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE * + * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your * + * right to use, modify, and redistribute this software under certain * + * conditions. If you wish to embed RFIDler technology into proprietary * + * software or hardware, we sell alternative licenses * + * (contact sales@aperturelabs.com). * + * * + * Note that the GPL places important restrictions on "derivative works", * + * yet it does not provide a detailed definition of that term. To avoid * + * misunderstandings, we interpret that term as broadly as copyright law * + * allows. For example, we consider an application to constitute a * + * derivative work for the purpose of this license if it does any of the * + * following with any software or content covered by this license * + * ("Covered Software"): * + * * + * o Integrates source code from Covered Software. * + * * + * o Is designed specifically to execute Covered Software and parse the * + * results (as opposed to typical shell or execution-menu apps, which will * + * execute anything you tell them to). * + * * + * o Includes Covered Software in a proprietary executable installer. The * + * installers produced by InstallShield are an example of this. Including * + * RFIDler with other software in compressed or archival form does not * + * trigger this provision, provided appropriate open source decompression * + * or de-archiving software is widely available for no charge. For the * + * purposes of this license, an installer is considered to include Covered * + * Software even if it actually retrieves a copy of Covered Software from * + * another source during runtime (such as by downloading it from the * + * Internet). * + * * + * o Links (statically or dynamically) to a library which does any of the * + * above. * + * * + * o Executes a helper program, module, or script to do any of the above. * + * * + * This list is not exclusive, but is meant to clarify our interpretation * + * of derived works with some common examples. Other people may interpret * + * the plain GPL differently, so we consider this a special exception to * + * the GPL that we apply to Covered Software. Works which meet any of * + * these conditions must conform to all of the terms of this license, * + * particularly including the GPL Section 3 requirements of providing * + * source code and allowing free redistribution of the work as a whole. * + * * + * As another special exception to the GPL terms, Aperture Labs Ltd. grants* + * permission to link the code of this program with any version of the * + * OpenSSL library which is distributed under a license identical to that * + * listed in the included docs/licenses/OpenSSL.txt file, and distribute * + * linked combinations including the two. * + * * + * Any redistribution of Covered Software, including any derived works, * + * must obey and carry forward all of the terms of this license, including * + * obeying all GPL rules and restrictions. For example, source code of * + * the whole work must be provided and free redistribution must be * + * allowed. All GPL references to "this License", are to be treated as * + * including the terms and conditions of this license text as well. * + * * + * Because this license imposes special exceptions to the GPL, Covered * + * Work may not be combined (even as part of a larger work) with plain GPL * + * software. The terms, conditions, and exceptions of this license must * + * be included as well. This license is incompatible with some other open * + * source licenses as well. In some cases we can relicense portions of * + * RFIDler or grant special permissions to use it in other open source * + * software. Please contact sales@aperturelabs.com with any such requests.* + * Similarly, we don't incorporate incompatible open source software into * + * Covered Software without special permission from the copyright holders. * + * * + * If you have any questions about the licensing restrictions on using * + * RFIDler in other works, are happy to help. As mentioned above, we also * + * offer alternative license to integrate RFIDler into proprietary * + * applications and appliances. These contracts have been sold to dozens * + * of software vendors, and generally include a perpetual license as well * + * as providing for priority support and updates. They also fund the * + * continued development of RFIDler. Please email sales@aperturelabs.com * + * for further information. * + * If you have received a written license agreement or contract for * + * Covered Software stating terms other than these, you may choose to use * + * and redistribute Covered Software under those terms instead of these. * + * * + * Source is provided to this software because we believe users have a * + * right to know exactly what a program is going to do before they run it. * + * This also allows you to audit the software for security holes (none * + * have been found so far). * + * * + * Source code also allows you to port RFIDler to new platforms, fix bugs, * + * and add new features. You are highly encouraged to send your changes * + * to the RFIDler mailing list for possible incorporation into the * + * main distribution. By sending these changes to Aperture Labs Ltd. or * + * one of the Aperture Labs Ltd. development mailing lists, or checking * + * them into the RFIDler source code repository, it is understood (unless * + * you specify otherwise) that you are offering the RFIDler Project * + * (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, * + * modify, and relicense the code. RFIDler will always be available Open * + * Source, but this is important because the inability to relicense code * + * has caused devastating problems for other Free Software projects (such * + * as KDE and NASM). We also occasionally relicense the code to third * + * parties as discussed above. If you wish to specify special license * + * conditions of your contributions, just say so when you send them. * + * * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler * + * license file for more details (it's in a COPYING file included with * + * RFIDler, and also available from * + * https://github.com/ApertureLabsLtd/RFIDler/COPYING * + * * + ***************************************************************************/ + +// Author: Adam Laurie + +#include +#include + +// BCD hardware revision for usb descriptor (usb_descriptors.c) +#define RFIDLER_HW_VERSION 0x020 + +// max sizes in BITS +#define MAXBLOCKSIZE 512 +#define MAXTAGSIZE 4096 +#define MAXUID 512 + +#define TMP_LARGE_BUFF_LEN 2048 +#define TMP_SMALL_BUFF_LEN 256 +#define ANALOGUE_BUFF_LEN 8192 + +#define COMMS_BUFFER_SIZE 128 + +#define DETECT_BUFFER_SIZE 512 + +#define SAMPLEMASK ~(BIT_1 | BIT_0) // mask to remove two bottom bits from analogue sample - we will then use those for reader & bit period + +// globals + +extern BOOL WiegandOutput; // Output wiegand data whenenver UID is read +extern BYTE *EMU_Reset_Data; // Pointer to full array of bits as bytes, stored as 0x00/0x01, '*' terminated +extern BYTE *EMU_Data; // Pointer to current location in EMU_Reset_Data +extern BYTE EMU_ThisBit; // The next data bit to transmit +extern BYTE EMU_SubCarrier_T0; // Number of Frame Clocks for sub-carrier '0' +extern BYTE EMU_SubCarrier_T1; // Number of Frame Clocks for sub-carrier '1' +extern unsigned int EMU_Repeat; // Number of times to transmit full data set +extern BOOL EMU_Background; // Emulate in the background until told to stop +extern unsigned int EMU_DataBitRate; // Number of Frame Clocks per bit +extern BYTE TmpBits[TMP_LARGE_BUFF_LEN]; // Shared scratchpad +extern BYTE ReaderPeriod; // Flag for sample display +extern unsigned char Comms_In_Buffer[COMMS_BUFFER_SIZE]; // USB/Serial buffer +extern BYTE Interface; // user interface - CLI or API +extern BYTE CommsChannel; // user comms channel - USB or UART +extern BOOL FakeRead; // flag for analogue sampler to signal it wants access to buffers during read +extern BOOL PWD_Mode; // is this tag password protected? +extern BYTE Password[9]; // 32 bits as HEX string set with LOGIN +extern unsigned int Led_Count; // LED status counter, also used for entropy +extern unsigned long Reader_Bit_Count; // Reader ISR bit counter +extern char Previous; // Reader ISR previous bit type + +// RWD (read/write device) coil state +extern BYTE RWD_State; // current state of RWD coil +extern unsigned int RWD_Fc; // field clock in uS +extern unsigned int RWD_Gap_Period; // length of command gaps in OC5 ticks +extern unsigned int RWD_Zero_Period; // length of '0' in OC5 ticks +extern unsigned int RWD_One_Period; // length of '1' in OC5 ticks +extern unsigned int RWD_Sleep_Period; // length of initial sleep to reset tag in OC5 ticks +extern unsigned int RWD_Wake_Period; // length required for tag to restart in OC5 ticks +extern unsigned int RWD_Wait_Switch_TX_RX; // length to wait when switching from TX to RX in OC5 ticks +extern unsigned int RWD_Wait_Switch_RX_TX; // length to wait when switching from RX to TX in OC5 ticks +extern unsigned int RWD_Post_Wait; // low level ISR wait period in OC5 ticks +extern unsigned int RWD_OC5_config; // Output Compare Module settings +extern unsigned int RWD_OC5_r; // Output Compare Module primary compare value +extern unsigned int RWD_OC5_rs; // Output Compare Module secondary compare value +extern BYTE RWD_Command_Buff[TMP_SMALL_BUFF_LEN]; // Command buffer, array of bits as bytes, stored as 0x00/0x01, '*' terminated +extern BYTE *RWD_Command_ThisBit; // Current command bit +extern BOOL Reader_ISR_State; // current state of reader ISR + +// NVM variables +// timings etc. that want to survive a reboot should go here +typedef struct { + BYTE Name[7]; // will be set to "RFIDler" so we can test for new device + BYTE AutoRun[128]; // optional command to run at startup + unsigned char TagType; + unsigned int PSK_Quality; + unsigned int Timeout; + unsigned int Wiegand_Pulse; + unsigned int Wiegand_Gap; + BOOL Wiegand_IdleState; + unsigned int FrameClock; + unsigned char Modulation; + unsigned int DataRate; + unsigned int DataRateSub0; + unsigned int DataRateSub1; + unsigned int DataBits; + unsigned int DataBlocks; + unsigned int BlockSize; + unsigned char SyncBits; + BYTE Sync[4]; + BOOL BiPhase; + BOOL Invert; + BOOL Manchester; + BOOL HalfDuplex; + unsigned int Repeat; + unsigned int PotLow; + unsigned int PotHigh; + unsigned int RWD_Gap_Period; + unsigned int RWD_Zero_Period; + unsigned int RWD_One_Period; + unsigned int RWD_Sleep_Period; + unsigned int RWD_Wake_Period; + unsigned int RWD_Wait_Switch_TX_RX; + unsigned int RWD_Wait_Switch_RX_TX; +} StoredConfig; + +// somewhere to store TAG data. this will be interpreted according to the TAG +// type. +typedef struct { + BYTE TagType; // raw tag type + BYTE EmulatedTagType; // tag type this tag is configured to emulate + BYTE UID[MAXUID + 1]; // Null-terminated HEX string + BYTE Data[MAXTAGSIZE]; // raw data + unsigned char DataBlocks; // number of blocks in Data field + unsigned int BlockSize; // blocksize in bits +} VirtualTag; + +extern StoredConfig RFIDlerConfig; +extern VirtualTag RFIDlerVTag; +extern BYTE TmpBuff[NVM_PAGE_SIZE]; +extern BYTE DataBuff[ANALOGUE_BUFF_LEN]; +extern unsigned int DataBuffCount; +extern const BYTE *ModulationSchemes[]; +extern const BYTE *OnOff[]; +extern const BYTE *HighLow[]; +extern const BYTE *TagTypes[]; + +// globals for ISRs +extern BYTE EmulationMode; +extern unsigned long HW_Bits; +extern BYTE HW_Skip_Bits; +extern unsigned int PSK_Min_Pulse; +extern BOOL PSK_Read_Error; +extern BOOL Manchester_Error; +extern BOOL SnifferMode; +extern unsigned int Clock_Tick_Counter; +extern BOOL Clock_Tick_Counter_Reset; + +// smart card lib +#define MAX_ATR_LEN (BYTE)33 +extern BYTE scCardATR[MAX_ATR_LEN]; +extern BYTE scATRLength; + +// RTC +extern rtccTime RTC_time; // time structure +extern rtccDate RTC_date; // date structure + +// digital pots +#define POTLOW_DEFAULT 100 +#define POTHIGH_DEFAULT 150 +#define DC_OFFSET 60 // analogue circuit DC offset (as close as we can get without using 2 LSB) +#define VOLTS_TO_POT 0.019607843F + +// RWD/clock states +#define RWD_STATE_INACTIVE 0 // RWD not in use +#define RWD_STATE_GO_TO_SLEEP 1 // RWD coil shutdown request +#define RWD_STATE_SLEEPING 2 // RWD coil shutdown for sleep period +#define RWD_STATE_WAKING 3 // RWD active for pre-determined period after reset +#define RWD_STATE_START_SEND 4 // RWD starting send of data +#define RWD_STATE_SENDING_GAP 5 // RWD sending a gap +#define RWD_STATE_SENDING_BIT 6 // RWD sending a data bit +#define RWD_STATE_POST_WAIT 7 // RWD finished sending data, now in forced wait period +#define RWD_STATE_ACTIVE 8 // RWD finished, now just clocking a carrier + +// reader ISR states +#define READER_STOPPED 0 // reader not in use +#define READER_IDLING 1 // reader ISR running to preserve timing, but not reading +#define READER_RUNNING 2 // reader reading bits + + +// user interface types +#define INTERFACE_API 0 +#define INTERFACE_CLI 1 + +// comms channel +#define COMMS_NONE 0 +#define COMMS_USB 1 +#define COMMS_UART 2 + +#define MAX_HISTORY 2 // disable most of history for now - memory issue + +// tag write retries +#define TAG_WRITE_RETRY 5 + +// modulation modes - uppdate ModulationSchemes[] in tags.c if you change this +#define MOD_MODE_NONE 0 +#define MOD_MODE_ASK_OOK 1 +#define MOD_MODE_FSK1 2 +#define MOD_MODE_FSK2 3 +#define MOD_MODE_PSK1 4 +#define MOD_MODE_PSK2 5 +#define MOD_MODE_PSK3 6 + +// TAG types - update TagTypes[] in tags.c if you add to this list +#define TAG_TYPE_NONE 0 +#define TAG_TYPE_ASK_RAW 1 +#define TAG_TYPE_FSK1_RAW 2 +#define TAG_TYPE_FSK2_RAW 3 +#define TAG_TYPE_PSK1_RAW 4 +#define TAG_TYPE_PSK2_RAW 5 +#define TAG_TYPE_PSK3_RAW 6 +#define TAG_TYPE_HITAG1 7 +#define TAG_TYPE_HITAG2 8 +#define TAG_TYPE_EM4X02 9 +#define TAG_TYPE_Q5 10 +#define TAG_TYPE_HID_26 11 +#define TAG_TYPE_INDALA_64 12 +#define TAG_TYPE_INDALA_224 13 +#define TAG_TYPE_UNIQUE 14 +#define TAG_TYPE_FDXB 15 +#define TAG_TYPE_T55X7 16 // same as Q5 but different timings and no modulation-defeat +#define TAG_TYPE_AWID_26 17 +#define TAG_TYPE_EM4X05 18 +#define TAG_TYPE_TAMAGOTCHI 19 +#define TAG_TYPE_HDX 20 // same underlying data as FDX-B, but different modulation & telegram + +// various + +#define BINARY 0 +#define HEX 1 + +#define NO_ADDRESS -1 + +#define ACK TRUE +#define NO_ACK FALSE + +#define BLOCK TRUE +#define NO_BLOCK FALSE + +#define DATA TRUE +#define NO_DATA FALSE + +#define DEBUG_PIN_ON HIGH +#define DEBUG_PIN_OFF LOW + +#define FAST FALSE +#define SLOW TRUE + +#define NO_TRIGGER 0 + +#define LOCK TRUE +#define NO_LOCK FALSE + +#define NFC_MODE TRUE +#define NO_NFC_MODE FALSE + +#define ONESHOT_READ TRUE +#define NO_ONESHOT_READ FALSE + +#define RESET TRUE +#define NO_RESET FALSE + +#define SHUTDOWN_CLOCK TRUE +#define NO_SHUTDOWN_CLOCK FALSE + +#define SYNC TRUE +#define NO_SYNC FALSE + +#define VERIFY TRUE +#define NO_VERIFY FALSE + +#define VOLATILE FALSE +#define NON_VOLATILE TRUE + +#define NEWLINE TRUE +#define NO_NEWLINE FALSE + +#define WAIT TRUE +#define NO_WAIT FALSE + +#define WIPER_HIGH 0 +#define WIPER_LOW 1 + +// conversion for time to ticks +#define US_TO_TICKS 1000000L +#define US_OVER_10_TO_TICKS 10000000L +#define US_OVER_100_TO_TICKS 100000000L +// we can't get down to this level on pic, but we want to standardise on timings, so for now we fudge it +#define CONVERT_TO_TICKS(x) ((x / 10) * (GetSystemClock() / US_OVER_10_TO_TICKS)) +#define CONVERT_TICKS_TO_US(x) (x / (GetSystemClock() / US_TO_TICKS)) +#define TIMER5_PRESCALER 16 +#define MAX_TIMER5_TICKS (65535 * TIMER5_PRESCALER) + +// other conversions + +// bits to hex digits +#define HEXDIGITS(x) (x / 4) +#define HEXTOBITS(x) (x * 4) diff --git a/tools/hitag2crack/crack5gpu/util.h b/tools/hitag2crack/crack5gpu/util.h new file mode 100644 index 000000000..c2399c37c --- /dev/null +++ b/tools/hitag2crack/crack5gpu/util.h @@ -0,0 +1,147 @@ +/*************************************************************************** + * A copy of the GNU GPL is appended to this file. * + * * + * This licence is based on the nmap licence, and we express our gratitude * + * for the work that went into producing it. There is no other connection * + * between RFIDler and nmap either expressed or implied. * + * * + ********************** IMPORTANT RFIDler LICENSE TERMS ******************** + * * + * * + * All references to RFIDler herein imply all it's derivatives, namely: * + * * + * o RFIDler-LF Standard * + * o RFIDler-LF Lite * + * o RFIDler-LF Nekkid * + * * + * * + * RFIDler is (C) 2013-2015 Aperture Labs Ltd. * + * * + * This program is free software; you may redistribute and/or modify it * + * under the terms of the GNU General Public License as published by the * + * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE * + * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your * + * right to use, modify, and redistribute this software under certain * + * conditions. If you wish to embed RFIDler technology into proprietary * + * software or hardware, we sell alternative licenses * + * (contact sales@aperturelabs.com). * + * * + * Note that the GPL places important restrictions on "derivative works", * + * yet it does not provide a detailed definition of that term. To avoid * + * misunderstandings, we interpret that term as broadly as copyright law * + * allows. For example, we consider an application to constitute a * + * derivative work for the purpose of this license if it does any of the * + * following with any software or content covered by this license * + * ("Covered Software"): * + * * + * o Integrates source code from Covered Software. * + * * + * o Is designed specifically to execute Covered Software and parse the * + * results (as opposed to typical shell or execution-menu apps, which will * + * execute anything you tell them to). * + * * + * o Includes Covered Software in a proprietary executable installer. The * + * installers produced by InstallShield are an example of this. Including * + * RFIDler with other software in compressed or archival form does not * + * trigger this provision, provided appropriate open source decompression * + * or de-archiving software is widely available for no charge. For the * + * purposes of this license, an installer is considered to include Covered * + * Software even if it actually retrieves a copy of Covered Software from * + * another source during runtime (such as by downloading it from the * + * Internet). * + * * + * o Links (statically or dynamically) to a library which does any of the * + * above. * + * * + * o Executes a helper program, module, or script to do any of the above. * + * * + * This list is not exclusive, but is meant to clarify our interpretation * + * of derived works with some common examples. Other people may interpret * + * the plain GPL differently, so we consider this a special exception to * + * the GPL that we apply to Covered Software. Works which meet any of * + * these conditions must conform to all of the terms of this license, * + * particularly including the GPL Section 3 requirements of providing * + * source code and allowing free redistribution of the work as a whole. * + * * + * As another special exception to the GPL terms, Aperture Labs Ltd. grants* + * permission to link the code of this program with any version of the * + * OpenSSL library which is distributed under a license identical to that * + * listed in the included docs/licenses/OpenSSL.txt file, and distribute * + * linked combinations including the two. * + * * + * Any redistribution of Covered Software, including any derived works, * + * must obey and carry forward all of the terms of this license, including * + * obeying all GPL rules and restrictions. For example, source code of * + * the whole work must be provided and free redistribution must be * + * allowed. All GPL references to "this License", are to be treated as * + * including the terms and conditions of this license text as well. * + * * + * Because this license imposes special exceptions to the GPL, Covered * + * Work may not be combined (even as part of a larger work) with plain GPL * + * software. The terms, conditions, and exceptions of this license must * + * be included as well. This license is incompatible with some other open * + * source licenses as well. In some cases we can relicense portions of * + * RFIDler or grant special permissions to use it in other open source * + * software. Please contact sales@aperturelabs.com with any such requests.* + * Similarly, we don't incorporate incompatible open source software into * + * Covered Software without special permission from the copyright holders. * + * * + * If you have any questions about the licensing restrictions on using * + * RFIDler in other works, are happy to help. As mentioned above, we also * + * offer alternative license to integrate RFIDler into proprietary * + * applications and appliances. These contracts have been sold to dozens * + * of software vendors, and generally include a perpetual license as well * + * as providing for priority support and updates. They also fund the * + * continued development of RFIDler. Please email sales@aperturelabs.com * + * for further information. * + * If you have received a written license agreement or contract for * + * Covered Software stating terms other than these, you may choose to use * + * and redistribute Covered Software under those terms instead of these. * + * * + * Source is provided to this software because we believe users have a * + * right to know exactly what a program is going to do before they run it. * + * This also allows you to audit the software for security holes (none * + * have been found so far). * + * * + * Source code also allows you to port RFIDler to new platforms, fix bugs, * + * and add new features. You are highly encouraged to send your changes * + * to the RFIDler mailing list for possible incorporation into the * + * main distribution. By sending these changes to Aperture Labs Ltd. or * + * one of the Aperture Labs Ltd. development mailing lists, or checking * + * them into the RFIDler source code repository, it is understood (unless * + * you specify otherwise) that you are offering the RFIDler Project * + * (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, * + * modify, and relicense the code. RFIDler will always be available Open * + * Source, but this is important because the inability to relicense code * + * has caused devastating problems for other Free Software projects (such * + * as KDE and NASM). We also occasionally relicense the code to third * + * parties as discussed above. If you wish to specify special license * + * conditions of your contributions, just say so when you send them. * + * * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler * + * license file for more details (it's in a COPYING file included with * + * RFIDler, and also available from * + * https://github.com/ApertureLabsLtd/RFIDler/COPYING * + * * + ***************************************************************************/ + +// Author: Adam Laurie + +/* + * Hitag Crypto support macros + * These macros reverse the bit order in a byte, or *within* each byte of a + * 16 , 32 or 64 bit unsigned integer. (Not across the whole 16 etc bits.) + */ +#define rev8(X) ((((X) >> 7) &1) + (((X) >> 5) &2) + (((X) >> 3) &4) \ + + (((X) >> 1) &8) + (((X) << 1) &16) + (((X) << 3) &32) \ + + (((X) << 5) &64) + (((X) << 7) &128) ) +#define rev16(X) (rev8 (X) + (rev8 (X >> 8) << 8)) +#define rev32(X) (rev16(X) + (rev16(X >> 16) << 16)) +#define rev64(X) (rev32(X) + (rev32(X >> 32) << 32)) + + +unsigned long hexreversetoulong(BYTE *hex); +unsigned long long hexreversetoulonglong(BYTE *hex); + diff --git a/tools/hitag2crack/crack5gpu/utilpart.c b/tools/hitag2crack/crack5gpu/utilpart.c new file mode 100644 index 000000000..c46148491 --- /dev/null +++ b/tools/hitag2crack/crack5gpu/utilpart.c @@ -0,0 +1,180 @@ +/*************************************************************************** + * A copy of the GNU GPL is appended to this file. * + * * + * This licence is based on the nmap licence, and we express our gratitude * + * for the work that went into producing it. There is no other connection * + * between RFIDler and nmap either expressed or implied. * + * * + ********************** IMPORTANT RFIDler LICENSE TERMS ******************** + * * + * * + * All references to RFIDler herein imply all it's derivatives, namely: * + * * + * o RFIDler-LF Standard * + * o RFIDler-LF Lite * + * o RFIDler-LF Nekkid * + * * + * * + * RFIDler is (C) 2013-2014 Aperture Labs Ltd. * + * * + * This program is free software; you may redistribute and/or modify it * + * under the terms of the GNU General Public License as published by the * + * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE * + * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your * + * right to use, modify, and redistribute this software under certain * + * conditions. If you wish to embed RFIDler technology into proprietary * + * software or hardware, we sell alternative licenses * + * (contact sales@aperturelabs.com). * + * * + * Note that the GPL places important restrictions on "derivative works", * + * yet it does not provide a detailed definition of that term. To avoid * + * misunderstandings, we interpret that term as broadly as copyright law * + * allows. For example, we consider an application to constitute a * + * derivative work for the purpose of this license if it does any of the * + * following with any software or content covered by this license * + * ("Covered Software"): * + * * + * o Integrates source code from Covered Software. * + * * + * o Is designed specifically to execute Covered Software and parse the * + * results (as opposed to typical shell or execution-menu apps, which will * + * execute anything you tell them to). * + * * + * o Includes Covered Software in a proprietary executable installer. The * + * installers produced by InstallShield are an example of this. Including * + * RFIDler with other software in compressed or archival form does not * + * trigger this provision, provided appropriate open source decompression * + * or de-archiving software is widely available for no charge. For the * + * purposes of this license, an installer is considered to include Covered * + * Software even if it actually retrieves a copy of Covered Software from * + * another source during runtime (such as by downloading it from the * + * Internet). * + * * + * o Links (statically or dynamically) to a library which does any of the * + * above. * + * * + * o Executes a helper program, module, or script to do any of the above. * + * * + * This list is not exclusive, but is meant to clarify our interpretation * + * of derived works with some common examples. Other people may interpret * + * the plain GPL differently, so we consider this a special exception to * + * the GPL that we apply to Covered Software. Works which meet any of * + * these conditions must conform to all of the terms of this license, * + * particularly including the GPL Section 3 requirements of providing * + * source code and allowing free redistribution of the work as a whole. * + * * + * As another special exception to the GPL terms, Aperture Labs Ltd. grants* + * permission to link the code of this program with any version of the * + * OpenSSL library which is distributed under a license identical to that * + * listed in the included docs/licenses/OpenSSL.txt file, and distribute * + * linked combinations including the two. * + * * + * Any redistribution of Covered Software, including any derived works, * + * must obey and carry forward all of the terms of this license, including * + * obeying all GPL rules and restrictions. For example, source code of * + * the whole work must be provided and free redistribution must be * + * allowed. All GPL references to "this License", are to be treated as * + * including the terms and conditions of this license text as well. * + * * + * Because this license imposes special exceptions to the GPL, Covered * + * Work may not be combined (even as part of a larger work) with plain GPL * + * software. The terms, conditions, and exceptions of this license must * + * be included as well. This license is incompatible with some other open * + * source licenses as well. In some cases we can relicense portions of * + * RFIDler or grant special permissions to use it in other open source * + * software. Please contact sales@aperturelabs.com with any such requests.* + * Similarly, we don't incorporate incompatible open source software into * + * Covered Software without special permission from the copyright holders. * + * * + * If you have any questions about the licensing restrictions on using * + * RFIDler in other works, are happy to help. As mentioned above, we also * + * offer alternative license to integrate RFIDler into proprietary * + * applications and appliances. These contracts have been sold to dozens * + * of software vendors, and generally include a perpetual license as well * + * as providing for priority support and updates. They also fund the * + * continued development of RFIDler. Please email sales@aperturelabs.com * + * for further information. * + * If you have received a written license agreement or contract for * + * Covered Software stating terms other than these, you may choose to use * + * and redistribute Covered Software under those terms instead of these. * + * * + * Source is provided to this software because we believe users have a * + * right to know exactly what a program is going to do before they run it. * + * This also allows you to audit the software for security holes (none * + * have been found so far). * + * * + * Source code also allows you to port RFIDler to new platforms, fix bugs, * + * and add new features. You are highly encouraged to send your changes * + * to the RFIDler mailing list for possible incorporation into the * + * main distribution. By sending these changes to Aperture Labs Ltd. or * + * one of the Aperture Labs Ltd. development mailing lists, or checking * + * them into the RFIDler source code repository, it is understood (unless * + * you specify otherwise) that you are offering the RFIDler Project * + * (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, * + * modify, and relicense the code. RFIDler will always be available Open * + * Source, but this is important because the inability to relicense code * + * has caused devastating problems for other Free Software projects (such * + * as KDE and NASM). We also occasionally relicense the code to third * + * parties as discussed above. If you wish to specify special license * + * conditions of your contributions, just say so when you send them. * + * * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler * + * license file for more details (it's in a COPYING file included with * + * RFIDler, and also available from * + * https://github.com/ApertureLabsLtd/RFIDler/COPYING * + * * + ***************************************************************************/ + +// Author: Adam Laurie + + +#include +#include +#include "HardwareProfile.h" +#include "util.h" +#include "rfidler.h" +//#include "comms.h" + +// rtc +rtccTime RTC_time; // time structure +rtccDate RTC_date; // date structure + +// convert byte-reversed 8 digit hex to unsigned long +unsigned long hexreversetoulong(BYTE *hex) { + unsigned long ret = 0L; + unsigned int x; + BYTE i; + + if (strlen(hex) != 8) + return 0L; + + for (i = 0 ; i < 4 ; ++i) { + if (sscanf(hex, "%2X", &x) != 1) + return 0L; + ret += ((unsigned long) x) << i * 8; + hex += 2; + } + return ret; +} + +// convert byte-reversed 12 digit hex to unsigned long +unsigned long long hexreversetoulonglong(BYTE *hex) { + unsigned long long ret = 0LL; + BYTE tmp[9]; + + // this may seem an odd way to do it, but weird compiler issues were + // breaking direct conversion! + + tmp[8] = '\0'; + memset(tmp + 4, '0', 4); + memcpy(tmp, hex + 8, 4); + ret = hexreversetoulong(tmp); + ret <<= 32; + memcpy(tmp, hex, 8); + ret += hexreversetoulong(tmp); + return ret; +} + + From b513300ea45456b8a9b19f8d898aff68470d04ca Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 4 Apr 2020 14:07:39 +0200 Subject: [PATCH 1853/1854] ht2 common files --- .../{crack2 => common}/HardwareProfile.h | 0 .../{crack2 => common}/hitagcrypto.c | 0 .../{crack2 => common}/hitagcrypto.h | 0 .../ht2crackutils.c} | 2 +- .../ht2crackutils.h} | 0 .../hitag2crack/{crack2 => common}/rfidler.h | 0 tools/hitag2crack/{crack3 => common}/util.h | 0 .../hitag2crack/{crack2 => common}/utilpart.c | 0 tools/hitag2crack/crack2/Makefile | 18 +- .../hitag2crack/crack2/ht2crack2buildtable.c | 2 +- tools/hitag2crack/crack2/ht2crack2gentest.c | 2 +- tools/hitag2crack/crack2/ht2crack2search.c | 2 +- tools/hitag2crack/crack2/util.h | 206 ------- tools/hitag2crack/crack3/HardwareProfile.h | 524 ------------------ tools/hitag2crack/crack3/Makefile | 10 +- tools/hitag2crack/crack3/hitagcrypto.c | 373 ------------- tools/hitag2crack/crack3/hitagcrypto.h | 167 ------ tools/hitag2crack/crack3/rfidler.h | 412 -------------- tools/hitag2crack/crack3/utilpart.c | 180 ------ tools/hitag2crack/crack4/HardwareProfile.h | 524 ------------------ tools/hitag2crack/crack4/Makefile | 14 +- tools/hitag2crack/crack4/hitagcrypto.c | 373 ------------- tools/hitag2crack/crack4/hitagcrypto.h | 167 ------ tools/hitag2crack/crack4/ht2crack2utils.c | 172 ------ tools/hitag2crack/crack4/ht2crack2utils.h | 34 -- tools/hitag2crack/crack4/ht2crack4.c | 2 +- tools/hitag2crack/crack4/rfidler.h | 412 -------------- tools/hitag2crack/crack4/util.h | 147 ----- tools/hitag2crack/crack4/utilpart.c | 180 ------ tools/hitag2crack/crack5/.gitignore | 3 + tools/hitag2crack/crack5/HardwareProfile.h | 524 ------------------ tools/hitag2crack/crack5/Makefile | 18 +- tools/hitag2crack/crack5/hitagcrypto.c | 373 ------------- tools/hitag2crack/crack5/hitagcrypto.h | 167 ------ tools/hitag2crack/crack5/ht2crack2utils.c | 172 ------ tools/hitag2crack/crack5/ht2crack2utils.h | 35 -- tools/hitag2crack/crack5/ht2crack5.c | 2 +- tools/hitag2crack/crack5/rfidler.h | 412 -------------- tools/hitag2crack/crack5/util.h | 147 ----- tools/hitag2crack/crack5/utilpart.c | 180 ------ tools/hitag2crack/crack5gpu/.gitignore | 3 + tools/hitag2crack/crack5gpu/HardwareProfile.h | 524 ------------------ tools/hitag2crack/crack5gpu/Makefile | 18 +- tools/hitag2crack/crack5gpu/hitagcrypto.c | 373 ------------- tools/hitag2crack/crack5gpu/hitagcrypto.h | 167 ------ tools/hitag2crack/crack5gpu/ht2crack2utils.c | 172 ------ tools/hitag2crack/crack5gpu/ht2crack2utils.h | 35 -- tools/hitag2crack/crack5gpu/ht2crack5.c | 2 +- tools/hitag2crack/crack5gpu/rfidler.h | 412 -------------- tools/hitag2crack/crack5gpu/util.h | 147 ----- tools/hitag2crack/crack5gpu/utilpart.c | 180 ------ 51 files changed, 57 insertions(+), 7932 deletions(-) rename tools/hitag2crack/{crack2 => common}/HardwareProfile.h (100%) rename tools/hitag2crack/{crack2 => common}/hitagcrypto.c (100%) rename tools/hitag2crack/{crack2 => common}/hitagcrypto.h (100%) rename tools/hitag2crack/{crack2/ht2crack2utils.c => common/ht2crackutils.c} (99%) rename tools/hitag2crack/{crack2/ht2crack2utils.h => common/ht2crackutils.h} (100%) rename tools/hitag2crack/{crack2 => common}/rfidler.h (100%) rename tools/hitag2crack/{crack3 => common}/util.h (100%) rename tools/hitag2crack/{crack2 => common}/utilpart.c (100%) delete mode 100644 tools/hitag2crack/crack2/util.h delete mode 100644 tools/hitag2crack/crack3/HardwareProfile.h delete mode 100644 tools/hitag2crack/crack3/hitagcrypto.c delete mode 100644 tools/hitag2crack/crack3/hitagcrypto.h delete mode 100644 tools/hitag2crack/crack3/rfidler.h delete mode 100644 tools/hitag2crack/crack3/utilpart.c delete mode 100644 tools/hitag2crack/crack4/HardwareProfile.h delete mode 100644 tools/hitag2crack/crack4/hitagcrypto.c delete mode 100644 tools/hitag2crack/crack4/hitagcrypto.h delete mode 100644 tools/hitag2crack/crack4/ht2crack2utils.c delete mode 100644 tools/hitag2crack/crack4/ht2crack2utils.h delete mode 100644 tools/hitag2crack/crack4/rfidler.h delete mode 100644 tools/hitag2crack/crack4/util.h delete mode 100644 tools/hitag2crack/crack4/utilpart.c create mode 100644 tools/hitag2crack/crack5/.gitignore delete mode 100644 tools/hitag2crack/crack5/HardwareProfile.h delete mode 100644 tools/hitag2crack/crack5/hitagcrypto.c delete mode 100644 tools/hitag2crack/crack5/hitagcrypto.h delete mode 100644 tools/hitag2crack/crack5/ht2crack2utils.c delete mode 100644 tools/hitag2crack/crack5/ht2crack2utils.h delete mode 100644 tools/hitag2crack/crack5/rfidler.h delete mode 100644 tools/hitag2crack/crack5/util.h delete mode 100644 tools/hitag2crack/crack5/utilpart.c create mode 100644 tools/hitag2crack/crack5gpu/.gitignore delete mode 100644 tools/hitag2crack/crack5gpu/HardwareProfile.h delete mode 100644 tools/hitag2crack/crack5gpu/hitagcrypto.c delete mode 100644 tools/hitag2crack/crack5gpu/hitagcrypto.h delete mode 100644 tools/hitag2crack/crack5gpu/ht2crack2utils.c delete mode 100644 tools/hitag2crack/crack5gpu/ht2crack2utils.h delete mode 100644 tools/hitag2crack/crack5gpu/rfidler.h delete mode 100644 tools/hitag2crack/crack5gpu/util.h delete mode 100644 tools/hitag2crack/crack5gpu/utilpart.c diff --git a/tools/hitag2crack/crack2/HardwareProfile.h b/tools/hitag2crack/common/HardwareProfile.h similarity index 100% rename from tools/hitag2crack/crack2/HardwareProfile.h rename to tools/hitag2crack/common/HardwareProfile.h diff --git a/tools/hitag2crack/crack2/hitagcrypto.c b/tools/hitag2crack/common/hitagcrypto.c similarity index 100% rename from tools/hitag2crack/crack2/hitagcrypto.c rename to tools/hitag2crack/common/hitagcrypto.c diff --git a/tools/hitag2crack/crack2/hitagcrypto.h b/tools/hitag2crack/common/hitagcrypto.h similarity index 100% rename from tools/hitag2crack/crack2/hitagcrypto.h rename to tools/hitag2crack/common/hitagcrypto.h diff --git a/tools/hitag2crack/crack2/ht2crack2utils.c b/tools/hitag2crack/common/ht2crackutils.c similarity index 99% rename from tools/hitag2crack/crack2/ht2crack2utils.c rename to tools/hitag2crack/common/ht2crackutils.c index 75d4c27a9..69061759c 100644 --- a/tools/hitag2crack/crack2/ht2crack2utils.c +++ b/tools/hitag2crack/common/ht2crackutils.c @@ -1,4 +1,4 @@ -#include "ht2crack2utils.h" +#include "ht2crackutils.h" // writes a value into a buffer as a series of bytes void writebuf(unsigned char *buf, uint64_t val, unsigned int len) { diff --git a/tools/hitag2crack/crack2/ht2crack2utils.h b/tools/hitag2crack/common/ht2crackutils.h similarity index 100% rename from tools/hitag2crack/crack2/ht2crack2utils.h rename to tools/hitag2crack/common/ht2crackutils.h diff --git a/tools/hitag2crack/crack2/rfidler.h b/tools/hitag2crack/common/rfidler.h similarity index 100% rename from tools/hitag2crack/crack2/rfidler.h rename to tools/hitag2crack/common/rfidler.h diff --git a/tools/hitag2crack/crack3/util.h b/tools/hitag2crack/common/util.h similarity index 100% rename from tools/hitag2crack/crack3/util.h rename to tools/hitag2crack/common/util.h diff --git a/tools/hitag2crack/crack2/utilpart.c b/tools/hitag2crack/common/utilpart.c similarity index 100% rename from tools/hitag2crack/crack2/utilpart.c rename to tools/hitag2crack/common/utilpart.c diff --git a/tools/hitag2crack/crack2/Makefile b/tools/hitag2crack/crack2/Makefile index cacb6abd1..63ba045b4 100644 --- a/tools/hitag2crack/crack2/Makefile +++ b/tools/hitag2crack/crack2/Makefile @@ -3,20 +3,22 @@ CFLAGS?=-Wall LIBS=-pthread -D_GNU_SOURCE # Mac libs # LIBS= +VPATH=../common +INC=-I ../common -all: ht2crack2buildtable.c ht2crack2search.c ht2crack2gentest.c hitagcrypto.o utilpart.o ht2crack2utils.o - $(CC) $(CFLAGS) -o ht2crack2buildtable ht2crack2buildtable.c hitagcrypto.o ht2crack2utils.o $(LIBS) - $(CC) $(CFLAGS) -o ht2crack2search ht2crack2search.c hitagcrypto.o utilpart.o ht2crack2utils.o $(LIBS) - $(CC) $(CFLAGS) -o ht2crack2gentest ht2crack2gentest.c hitagcrypto.o utilpart.o ht2crack2utils.o $(LIBS) +all: ht2crack2buildtable.c ht2crack2search.c ht2crack2gentest.c hitagcrypto.o utilpart.o ht2crackutils.o + $(CC) $(CFLAGS) $(INC) -o ht2crack2buildtable ht2crack2buildtable.c hitagcrypto.o ht2crackutils.o $(LIBS) + $(CC) $(CFLAGS) $(INC) -o ht2crack2search ht2crack2search.c hitagcrypto.o utilpart.o ht2crackutils.o $(LIBS) + $(CC) $(CFLAGS) $(INC) -o ht2crack2gentest ht2crack2gentest.c hitagcrypto.o utilpart.o ht2crackutils.o $(LIBS) -ht2crack2utils.o: ht2crack2utils.c ht2crack2utils.h - $(CC) $(CFLAGS) -c ht2crack2utils.c +ht2crackutils.o: ht2crackutils.c ht2crackutils.h + $(CC) $(CFLAGS) -c $< hitagcrypto.o: hitagcrypto.c hitagcrypto.h - $(CC) $(CFLAGS) -c hitagcrypto.c + $(CC) $(CFLAGS) -c $< utilpart.o: utilpart.c util.h - $(CC) $(CFLAGS) -c utilpart.c + $(CC) $(CFLAGS) -c $< clean: rm -rf *.o ht2crack2buildtable ht2crack2search ht2crack2gentest diff --git a/tools/hitag2crack/crack2/ht2crack2buildtable.c b/tools/hitag2crack/crack2/ht2crack2buildtable.c index 0aca200ef..8bf67a8ac 100644 --- a/tools/hitag2crack/crack2/ht2crack2buildtable.c +++ b/tools/hitag2crack/crack2/ht2crack2buildtable.c @@ -3,7 +3,7 @@ * This builds the 1.2TB table and sorts it. */ -#include "ht2crack2utils.h" +#include "ht2crackutils.h" // DATAMAX is the size of each bucket (bytes). There are 65536 buckets so choose a value such that diff --git a/tools/hitag2crack/crack2/ht2crack2gentest.c b/tools/hitag2crack/crack2/ht2crack2gentest.c index 7034d10d3..0393d7f23 100644 --- a/tools/hitag2crack/crack2/ht2crack2gentest.c +++ b/tools/hitag2crack/crack2/ht2crack2gentest.c @@ -3,7 +3,7 @@ * this uses the RFIDler hitag2 PRNG code to generate test cases to test the tables */ -#include "ht2crack2utils.h" +#include "ht2crackutils.h" int makerandom(char *hex, unsigned int len, int fd) { diff --git a/tools/hitag2crack/crack2/ht2crack2search.c b/tools/hitag2crack/crack2/ht2crack2search.c index 8d93066b3..7570df652 100644 --- a/tools/hitag2crack/crack2/ht2crack2search.c +++ b/tools/hitag2crack/crack2/ht2crack2search.c @@ -4,7 +4,7 @@ * PRNG state, checks it is correct, and then rolls back the PRNG to recover the key */ -#include "ht2crack2utils.h" +#include "ht2crackutils.h" #define INPUTFILE "sorted/%02x/%02x.bin" diff --git a/tools/hitag2crack/crack2/util.h b/tools/hitag2crack/crack2/util.h deleted file mode 100644 index c20fdf3c2..000000000 --- a/tools/hitag2crack/crack2/util.h +++ /dev/null @@ -1,206 +0,0 @@ -/*************************************************************************** - * A copy of the GNU GPL is appended to this file. * - * * - * This licence is based on the nmap licence, and we express our gratitude * - * for the work that went into producing it. There is no other connection * - * between RFIDler and nmap either expressed or implied. * - * * - ********************** IMPORTANT RFIDler LICENSE TERMS ******************** - * * - * * - * All references to RFIDler herein imply all it's derivatives, namely: * - * * - * o RFIDler-LF Standard * - * o RFIDler-LF Lite * - * o RFIDler-LF Nekkid * - * * - * * - * RFIDler is (C) 2013-2015 Aperture Labs Ltd. * - * * - * This program is free software; you may redistribute and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE * - * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your * - * right to use, modify, and redistribute this software under certain * - * conditions. If you wish to embed RFIDler technology into proprietary * - * software or hardware, we sell alternative licenses * - * (contact sales@aperturelabs.com). * - * * - * Note that the GPL places important restrictions on "derivative works", * - * yet it does not provide a detailed definition of that term. To avoid * - * misunderstandings, we interpret that term as broadly as copyright law * - * allows. For example, we consider an application to constitute a * - * derivative work for the purpose of this license if it does any of the * - * following with any software or content covered by this license * - * ("Covered Software"): * - * * - * o Integrates source code from Covered Software. * - * * - * o Is designed specifically to execute Covered Software and parse the * - * results (as opposed to typical shell or execution-menu apps, which will * - * execute anything you tell them to). * - * * - * o Includes Covered Software in a proprietary executable installer. The * - * installers produced by InstallShield are an example of this. Including * - * RFIDler with other software in compressed or archival form does not * - * trigger this provision, provided appropriate open source decompression * - * or de-archiving software is widely available for no charge. For the * - * purposes of this license, an installer is considered to include Covered * - * Software even if it actually retrieves a copy of Covered Software from * - * another source during runtime (such as by downloading it from the * - * Internet). * - * * - * o Links (statically or dynamically) to a library which does any of the * - * above. * - * * - * o Executes a helper program, module, or script to do any of the above. * - * * - * This list is not exclusive, but is meant to clarify our interpretation * - * of derived works with some common examples. Other people may interpret * - * the plain GPL differently, so we consider this a special exception to * - * the GPL that we apply to Covered Software. Works which meet any of * - * these conditions must conform to all of the terms of this license, * - * particularly including the GPL Section 3 requirements of providing * - * source code and allowing free redistribution of the work as a whole. * - * * - * As another special exception to the GPL terms, Aperture Labs Ltd. grants* - * permission to link the code of this program with any version of the * - * OpenSSL library which is distributed under a license identical to that * - * listed in the included docs/licenses/OpenSSL.txt file, and distribute * - * linked combinations including the two. * - * * - * Any redistribution of Covered Software, including any derived works, * - * must obey and carry forward all of the terms of this license, including * - * obeying all GPL rules and restrictions. For example, source code of * - * the whole work must be provided and free redistribution must be * - * allowed. All GPL references to "this License", are to be treated as * - * including the terms and conditions of this license text as well. * - * * - * Because this license imposes special exceptions to the GPL, Covered * - * Work may not be combined (even as part of a larger work) with plain GPL * - * software. The terms, conditions, and exceptions of this license must * - * be included as well. This license is incompatible with some other open * - * source licenses as well. In some cases we can relicense portions of * - * RFIDler or grant special permissions to use it in other open source * - * software. Please contact sales@aperturelabs.com with any such requests.* - * Similarly, we don't incorporate incompatible open source software into * - * Covered Software without special permission from the copyright holders. * - * * - * If you have any questions about the licensing restrictions on using * - * RFIDler in other works, are happy to help. As mentioned above, we also * - * offer alternative license to integrate RFIDler into proprietary * - * applications and appliances. These contracts have been sold to dozens * - * of software vendors, and generally include a perpetual license as well * - * as providing for priority support and updates. They also fund the * - * continued development of RFIDler. Please email sales@aperturelabs.com * - * for further information. * - * If you have received a written license agreement or contract for * - * Covered Software stating terms other than these, you may choose to use * - * and redistribute Covered Software under those terms instead of these. * - * * - * Source is provided to this software because we believe users have a * - * right to know exactly what a program is going to do before they run it. * - * This also allows you to audit the software for security holes (none * - * have been found so far). * - * * - * Source code also allows you to port RFIDler to new platforms, fix bugs, * - * and add new features. You are highly encouraged to send your changes * - * to the RFIDler mailing list for possible incorporation into the * - * main distribution. By sending these changes to Aperture Labs Ltd. or * - * one of the Aperture Labs Ltd. development mailing lists, or checking * - * them into the RFIDler source code repository, it is understood (unless * - * you specify otherwise) that you are offering the RFIDler Project * - * (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, * - * modify, and relicense the code. RFIDler will always be available Open * - * Source, but this is important because the inability to relicense code * - * has caused devastating problems for other Free Software projects (such * - * as KDE and NASM). We also occasionally relicense the code to third * - * parties as discussed above. If you wish to specify special license * - * conditions of your contributions, just say so when you send them. * - * * - * This program is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler * - * license file for more details (it's in a COPYING file included with * - * RFIDler, and also available from * - * https://github.com/ApertureLabsLtd/RFIDler/COPYING * - * * - ***************************************************************************/ - -// Author: Adam Laurie - -#define CRC16_MASK_CCITT 0x1021 // CRC-CCITT mask (ISO 3309, used in X25, HDLC) -#define CRC16_MASK_ISO_11785 0x8408 // ISO 11785 animal tags -#define CRC16_MASK_CRC16 0xA001 // standard CRC16 mask (used in ARC files) - -/* - * Hitag Crypto support macros - * These macros reverse the bit order in a byte, or *within* each byte of a - * 16 , 32 or 64 bit unsigned integer. (Not across the whole 16 etc bits.) - */ -#define rev8(X) ((((X) >> 7) &1) + (((X) >> 5) &2) + (((X) >> 3) &4) \ - + (((X) >> 1) &8) + (((X) << 1) &16) + (((X) << 3) &32) \ - + (((X) << 5) &64) + (((X) << 7) &128) ) -#define rev16(X) (rev8 (X) + (rev8 (X >> 8) << 8)) -#define rev32(X) (rev16(X) + (rev16(X >> 16) << 16)) -#define rev64(X) (rev32(X) + (rev32(X >> 32) << 32)) - - -BYTE approx(unsigned long number, unsigned long target, unsigned char percentage); -unsigned int bcdtouint(BYTE *bcd, BYTE length); -unsigned long long bcdtoulonglong(BYTE *bcd, BYTE length); -void inttobinarray(BYTE *target, unsigned int source, unsigned int bits); -void ulongtobinarray(BYTE *target, unsigned long source, unsigned int bits); -void ulonglongtobinarray(BYTE *target, unsigned long long source, unsigned int bits); -void inttobinstring(BYTE *target, unsigned int source, unsigned int bits); -void ulongtobinstring(BYTE *target, unsigned long source, unsigned int bits); -BOOL ulongtohex(BYTE *target, unsigned long source); -unsigned int binarraytoint(BYTE *bin, BYTE length); -unsigned long long binarraytolonglong(BYTE *bin, BYTE length); -unsigned long binarraytoulong(BYTE *bin, BYTE length); -BYTE hextobyte(BYTE *hex); -void printhexreadable(BYTE *hex, BYTE maxlength); -unsigned long hextoulong(BYTE *hex); -unsigned long hexreversetoulong(BYTE *hex); -unsigned long long hextoulonglong(BYTE *hex); -unsigned long long hexreversetoulonglong(BYTE *hex); -char hextolonglong(unsigned long long *out, unsigned char *hex); -unsigned int hextobinarray(unsigned char *target, unsigned char *source); -unsigned int hextobinstring(unsigned char *target, unsigned char *source); -unsigned int binarraytohex(unsigned char *target, unsigned char *source, unsigned int length); -void hexprintbinarray(BYTE *bin, unsigned int length); -unsigned int binstringtohex(unsigned char *target, unsigned char *source); -unsigned int binstringtobinarray(BYTE *target, BYTE *source); -void binstringtobyte(BYTE *target, unsigned char *source, BYTE length); -void binarraytobinstring(BYTE *target, BYTE *source, unsigned int length); -void printhexasbin(unsigned char *hex); -void printbinashex(unsigned char *bin); -void invertbinarray(BYTE *target, BYTE *source, unsigned int length); -void invertbinstring(BYTE *target, BYTE *source); -void printbinarray(unsigned char *bin, unsigned int length); -unsigned char getbit(unsigned char byte, unsigned char bit); -void bytestohex(unsigned char *target, unsigned char *source, unsigned int length); -unsigned int manchester_encode(unsigned char *target, unsigned char *source, unsigned int length); -unsigned int manchester_decode(unsigned char *target, unsigned char *source, unsigned int length); -char *strip_newline(char *buff); -BOOL command_ack(BOOL data); -BOOL command_nack(BYTE *reason); -BOOL command_unknown(void); -void ToUpper(char *string); -void string_reverse(unsigned char *string, unsigned int length); -BOOL string_byteswap(unsigned char *string, unsigned int length); -BYTE parity(unsigned char *string, BYTE type, unsigned int length); -unsigned long get_reader_pulse(unsigned int timeout_us); -unsigned long get_reader_gap(unsigned int timeout_us); -unsigned int crc_ccitt(BYTE *data, unsigned int length); -unsigned int crc16(unsigned int crc, BYTE *data, unsigned int length, unsigned int mask); -void space_indent(BYTE count); -void xml_version(void); -void xml_header(BYTE *item, BYTE *indent); -void xml_footer(BYTE *item, BYTE *indent, BOOL newline); -void xml_indented_text(BYTE *data, BYTE indent); -void xml_item_text(BYTE *item, BYTE *data, BYTE *indent); -void xml_item_decimal(BYTE *item, BYTE num, BYTE *indent); -void xml_indented_array(BYTE *data, BYTE mask, unsigned int length, BYTE indent); -void xml_item_array(BYTE *item, BYTE *data, BYTE mask, unsigned int length, BYTE *indent); - diff --git a/tools/hitag2crack/crack3/HardwareProfile.h b/tools/hitag2crack/crack3/HardwareProfile.h deleted file mode 100644 index bce139042..000000000 --- a/tools/hitag2crack/crack3/HardwareProfile.h +++ /dev/null @@ -1,524 +0,0 @@ -/*************************************************************************** - * A copy of the GNU GPL is appended to this file. * - * * - * This licence is based on the nmap licence, and we express our gratitude * - * for the work that went into producing it. There is no other connection * - * between RFIDler and nmap either expressed or implied. * - * * - ********************** IMPORTANT RFIDler LICENSE TERMS ******************** - * * - * * - * All references to RFIDler herein imply all it's derivatives, namely: * - * * - * o RFIDler-LF Standard * - * o RFIDler-LF Lite * - * o RFIDler-LF Nekkid * - * * - * * - * RFIDler is (C) 2013-2014 Aperture Labs Ltd. * - * * - * This program is free software; you may redistribute and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE * - * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your * - * right to use, modify, and redistribute this software under certain * - * conditions. If you wish to embed RFIDler technology into proprietary * - * software or hardware, we sell alternative licenses * - * (contact sales@aperturelabs.com). * - * * - * Note that the GPL places important restrictions on "derivative works", * - * yet it does not provide a detailed definition of that term. To avoid * - * misunderstandings, we interpret that term as broadly as copyright law * - * allows. For example, we consider an application to constitute a * - * derivative work for the purpose of this license if it does any of the * - * following with any software or content covered by this license * - * ("Covered Software"): * - * * - * o Integrates source code from Covered Software. * - * * - * o Is designed specifically to execute Covered Software and parse the * - * results (as opposed to typical shell or execution-menu apps, which will * - * execute anything you tell them to). * - * * - * o Includes Covered Software in a proprietary executable installer. The * - * installers produced by InstallShield are an example of this. Including * - * RFIDler with other software in compressed or archival form does not * - * trigger this provision, provided appropriate open source decompression * - * or de-archiving software is widely available for no charge. For the * - * purposes of this license, an installer is considered to include Covered * - * Software even if it actually retrieves a copy of Covered Software from * - * another source during runtime (such as by downloading it from the * - * Internet). * - * * - * o Links (statically or dynamically) to a library which does any of the * - * above. * - * * - * o Executes a helper program, module, or script to do any of the above. * - * * - * This list is not exclusive, but is meant to clarify our interpretation * - * of derived works with some common examples. Other people may interpret * - * the plain GPL differently, so we consider this a special exception to * - * the GPL that we apply to Covered Software. Works which meet any of * - * these conditions must conform to all of the terms of this license, * - * particularly including the GPL Section 3 requirements of providing * - * source code and allowing free redistribution of the work as a whole. * - * * - * As another special exception to the GPL terms, Aperture Labs Ltd. grants* - * permission to link the code of this program with any version of the * - * OpenSSL library which is distributed under a license identical to that * - * listed in the included docs/licenses/OpenSSL.txt file, and distribute * - * linked combinations including the two. * - * * - * Any redistribution of Covered Software, including any derived works, * - * must obey and carry forward all of the terms of this license, including * - * obeying all GPL rules and restrictions. For example, source code of * - * the whole work must be provided and free redistribution must be * - * allowed. All GPL references to "this License", are to be treated as * - * including the terms and conditions of this license text as well. * - * * - * Because this license imposes special exceptions to the GPL, Covered * - * Work may not be combined (even as part of a larger work) with plain GPL * - * software. The terms, conditions, and exceptions of this license must * - * be included as well. This license is incompatible with some other open * - * source licenses as well. In some cases we can relicense portions of * - * RFIDler or grant special permissions to use it in other open source * - * software. Please contact sales@aperturelabs.com with any such requests.* - * Similarly, we don't incorporate incompatible open source software into * - * Covered Software without special permission from the copyright holders. * - * * - * If you have any questions about the licensing restrictions on using * - * RFIDler in other works, are happy to help. As mentioned above, we also * - * offer alternative license to integrate RFIDler into proprietary * - * applications and appliances. These contracts have been sold to dozens * - * of software vendors, and generally include a perpetual license as well * - * as providing for priority support and updates. They also fund the * - * continued development of RFIDler. Please email sales@aperturelabs.com * - * for further information. * - * If you have received a written license agreement or contract for * - * Covered Software stating terms other than these, you may choose to use * - * and redistribute Covered Software under those terms instead of these. * - * * - * Source is provided to this software because we believe users have a * - * right to know exactly what a program is going to do before they run it. * - * This also allows you to audit the software for security holes (none * - * have been found so far). * - * * - * Source code also allows you to port RFIDler to new platforms, fix bugs, * - * and add new features. You are highly encouraged to send your changes * - * to the RFIDler mailing list for possible incorporation into the * - * main distribution. By sending these changes to Aperture Labs Ltd. or * - * one of the Aperture Labs Ltd. development mailing lists, or checking * - * them into the RFIDler source code repository, it is understood (unless * - * you specify otherwise) that you are offering the RFIDler Project * - * (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, * - * modify, and relicense the code. RFIDler will always be available Open * - * Source, but this is important because the inability to relicense code * - * has caused devastating problems for other Free Software projects (such * - * as KDE and NASM). We also occasionally relicense the code to third * - * parties as discussed above. If you wish to specify special license * - * conditions of your contributions, just say so when you send them. * - * * - * This program is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler * - * license file for more details (it's in a COPYING file included with * - * RFIDler, and also available from * - * https://github.com/ApertureLabsLtd/RFIDler/COPYING * - * * - ***************************************************************************/ - -// Author: Adam Laurie - - - -#ifndef HARDWARE_PROFILE_UBW32_H -#define HARDWARE_PROFILE_UBW32_H - -//#include "plib.h" -typedef char BOOL; -typedef char BYTE; -typedef int rtccTime; -typedef int rtccDate; - - -#ifndef __PIC32MX__ -#define __PIC32MX__ -#endif - -#define GetSystemClock() (80000000ul) -#define GetPeripheralClock() (GetSystemClock()) -#define GetInstructionClock() (GetSystemClock()) - -//#define USE_SELF_POWER_SENSE_IO -#define tris_self_power TRISAbits.TRISA2 // Input -#define self_power 1 - -//#define USE_USB_BUS_SENSE_IO -#define tris_usb_bus_sense TRISBbits.TRISB5 // Input -#define USB_BUS_SENSE 1 - -// LEDs -#define mLED_1 LATEbits.LATE3 - -#define mLED_2 LATEbits.LATE2 -#define mLED_Comms mLED_2 - -#define mLED_3 LATEbits.LATE1 -#define mLED_Clock mLED_3 - -#define mLED_4 LATEbits.LATE0 -#define mLED_Emulate mLED_4 - -#define mLED_5 LATGbits.LATG6 -#define mLED_Read mLED_5 - -#define mLED_6 LATAbits.LATA15 -#define mLED_User mLED_6 - -#define mLED_7 LATDbits.LATD11 -#define mLED_Error mLED_7 - -// active low -#define mLED_ON 0 -#define mLED_OFF 1 - -#define mGetLED_1() mLED_1 -#define mGetLED_USB() mLED_1 -#define mGetLED_2() mLED_2 -#define mGetLED_Comms() mLED_2 -#define mGetLED_3() mLED_3 -#define mGetLED_Clock() mLED_3 -#define mGetLED_4() mLED_4 -#define mGetLED_Emulate() mLED_4 -#define mGetLED_5() mLED_5 -#define mGetLED_Read() mLED_5 -#define mGetLED_6() mLED_6 -#define mGetLED_User() mLED_6 -#define mGetLED_7() mLED_7 -#define mGetLED_Error() mLED_7 - -#define mLED_1_On() mLED_1 = mLED_ON -#define mLED_USB_On() mLED_1_On() -#define mLED_2_On() mLED_2 = mLED_ON -#define mLED_Comms_On() mLED_2_On() -#define mLED_3_On() mLED_3 = mLED_ON -#define mLED_Clock_On() mLED_3_On() -#define mLED_4_On() mLED_4 = mLED_ON -#define mLED_Emulate_On() mLED_4_On() -#define mLED_5_On() mLED_5 = mLED_ON -#define mLED_Read_On() mLED_5_On() -#define mLED_6_On() mLED_6 = mLED_ON -#define mLED_User_On() mLED_6_On() -#define mLED_7_On() mLED_7 = mLED_ON -#define mLED_Error_On() mLED_7_On() - -#define mLED_1_Off() mLED_1 = mLED_OFF -#define mLED_USB_Off() mLED_1_Off() -#define mLED_2_Off() mLED_2 = mLED_OFF -#define mLED_Comms_Off() mLED_2_Off() -#define mLED_3_Off() mLED_3 = mLED_OFF -#define mLED_Clock_Off() mLED_3_Off() -#define mLED_4_Off() mLED_4 = mLED_OFF -#define mLED_Emulate_Off() mLED_4_Off() -#define mLED_5_Off() mLED_5 = mLED_OFF -#define mLED_Read_Off() mLED_5_Off() -#define mLED_6_Off() mLED_6 = mLED_OFF -#define mLED_User_Off() mLED_6_Off() -#define mLED_7_Off() mLED_7 = mLED_OFF -#define mLED_Error_Off() mLED_7_Off() - -#define mLED_1_Toggle() mLED_1 = !mLED_1 -#define mLED_USB_Toggle() mLED_1_Toggle() -#define mLED_2_Toggle() mLED_2 = !mLED_2 -#define mLED_Comms_Toggle() mLED_2_Toggle() -#define mLED_3_Toggle() mLED_3 = !mLED_3 -#define mLED_Clock_Toggle() mLED_3_Toggle() -#define mLED_4_Toggle() mLED_4 = !mLED_4 -#define mLED_Emulate_Toggle() mLED_4_Toggle() -#define mLED_5_Toggle() mLED_5 = !mLED_5 -#define mLED_Read_Toggle( ) mLED_5_Toggle() -#define mLED_6_Toggle() mLED_6 = !mLED_6 -#define mLED_User_Toggle() mLED_6_Toggle() -#define mLED_7_Toggle() mLED_7 = !mLED_7 -#define mLED_Error_Toggle() mLED_7_Toggle() - -#define mLED_All_On() { mLED_1_On(); mLED_2_On(); mLED_3_On(); mLED_4_On(); mLED_5_On(); mLED_6_On(); mLED_7_On(); } -#define mLED_All_Off() { mLED_1_Off(); mLED_2_Off(); mLED_3_Off(); mLED_4_Off(); mLED_5_Off(); mLED_6_Off(); mLED_7_Off(); } - -// usb status lights -#define mLED_Both_Off() {mLED_USB_Off();mLED_Comms_Off();} -#define mLED_Both_On() {mLED_USB_On();mLED_Comms_On();} -#define mLED_Only_USB_On() {mLED_USB_On();mLED_Comms_Off();} -#define mLED_Only_Comms_On() {mLED_USB_Off();mLED_Comms_On();} - -/** SWITCH *********************************************************/ -#define swBootloader PORTEbits.RE7 -#define swUser PORTEbits.RE6 - -/** I/O pin definitions ********************************************/ -#define INPUT_PIN 1 -#define OUTPUT_PIN 0 - -#define TRUE 1 -#define FALSE 0 - -#define ENABLE 1 -#define DISABE 0 - -#define EVEN 0 -#define ODD 1 - -#define LOW FALSE -#define HIGH TRUE - -#define CLOCK_ON LOW -#define CLOCK_OFF HIGH - -// output coil control - select between reader/emulator circuits -#define COIL_MODE LATBbits.LATB4 -#define COIL_MODE_READER() COIL_MODE= LOW -#define COIL_MODE_EMULATOR() COIL_MODE= HIGH - -// coil for emulation -#define COIL_OUT LATGbits.LATG9 -#define COIL_OUT_HIGH() COIL_OUT=HIGH -#define COIL_OUT_LOW() COIL_OUT=LOW - -// door relay (active low) -#define DOOR_RELAY LATAbits.LATA14 -#define DOOR_RELAY_OPEN() DOOR_RELAY= HIGH -#define DOOR_RELAY_CLOSE() DOOR_RELAY= LOW - -// inductance/capacitance freq -#define IC_FREQUENCY PORTAbits.RA2 - -#define SNIFFER_COIL PORTDbits.RD12 // external reader clock detect -#define READER_ANALOGUE PORTBbits.RB11 // reader coil analogue -#define DIV_LOW_ANALOGUE PORTBbits.RB12 // voltage divider LOW analogue -#define DIV_HIGH_ANALOGUE PORTBbits.RB13 // voltage divider HIGH analogue - -// clock coil (normally controlled by OC Module, but defined here so we can force it high or low) -#define CLOCK_COIL PORTDbits.RD4 -#define CLOCK_COIL_MOVED PORTDbits.RD0 // temporary for greenwire - -// digital output after analogue reader circuit -#define READER_DATA PORTDbits.RD8 - -// trace / debug -#define DEBUG_PIN_1 LATCbits.LATC1 -#define DEBUG_PIN_1_TOGGLE() DEBUG_PIN_1= !DEBUG_PIN_1 -#define DEBUG_PIN_2 LATCbits.LATC2 -#define DEBUG_PIN_2_TOGGLE() DEBUG_PIN_2= !DEBUG_PIN_2 -#define DEBUG_PIN_3 LATCbits.LATC3 -#define DEBUG_PIN_3_TOGGLE() DEBUG_PIN_3= !DEBUG_PIN_3 -#define DEBUG_PIN_4 LATEbits.LATE5 -#define DEBUG_PIN_4_TOGGLE() DEBUG_PIN_4= !DEBUG_PIN_4 - -// spi (sdi1) for sd card (not directly referenced) -//#define SD_CARD_RX LATCbits.LATC4 -//#define SD_CARD_TX LATDbits.LATD0 -//#define SD_CARD_CLK LATDbits.LATD10 -//#define SD_CARD_SS LATDbits.LATD9 -// spi for SD card -#define SD_CARD_DET LATFbits.LATF0 -#define SD_CARD_WE LATFbits.LATF1 // write enable - unused for microsd but allocated anyway as library checks it -// (held LOW by default - cut solder bridge to GND to free pin if required) -#define SPI_SD SPI_CHANNEL1 -#define SPI_SD_BUFF SPI1BUF -#define SPI_SD_STAT SPI1STATbits -// see section below for more defines! - -// iso 7816 smartcard -// microchip SC module defines pins so we don't need to, but -// they are listed here to help avoid conflicts -#define ISO_7816_RX LATBbits.LATF2 // RX -#define ISO_7816_TX LATBbits.LATF8 // TX -#define ISO_7816_VCC LATBbits.LATB9 // Power -#define ISO_7816_CLK LATCbits.LATD1 // Clock -#define ISO_7816_RST LATEbits.LATE8 // Reset - -// user LED -#define USER_LED LATDbits.LATD7 -#define USER_LED_ON() LATDbits.LATD7=1 -#define USER_LED_OFF() LATDbits.LATD7=0 - -// LCR -#define LCR_CALIBRATE LATBbits.LATB5 - -// wiegand / clock & data -#define WIEGAND_IN_0 PORTDbits.RD5 -#define WIEGAND_IN_0_PULLUP CNPUEbits.CNPUE14 -#define WIEGAND_IN_0_PULLDOWN CNPDbits.CNPD14 -#define WIEGAND_IN_1 PORTDbits.RD6 -#define WIEGAND_IN_1_PULLUP CNPUEbits.CNPUE15 -#define WIEGAND_IN_1_PULLDOWN CNPDbits.CNPD15 -#define CAND_IN_DATA WIEGAND_IN_0 -#define CAND_IN_CLOCK WIEGAND_IN_1 - -#define WIEGAND_OUT_0 LATDbits.LATD3 -#define WIEGAND_OUT_1 LATDbits.LATD2 -#define WIEGAND_OUT_0_TRIS TRISDbits.TRISD3 -#define WIEGAND_OUT_1_TRIS TRISDbits.TRISD2 -#define CAND_OUT_DATA WIEGAND_OUT_0 -#define CAND_OUT_CLOCK WIEGAND_OUT_1 - -// connect/disconnect reader clock from coil - used to send RWD signals by creating gaps in carrier -#define READER_CLOCK_ENABLE LATEbits.LATE9 -#define READER_CLOCK_ENABLE_ON() READER_CLOCK_ENABLE=CLOCK_ON -#define READER_CLOCK_ENABLE_OFF(x) {READER_CLOCK_ENABLE=CLOCK_OFF; COIL_OUT=x;} - -// these input pins must NEVER bet set to output or they will cause short circuits! -// they can be used to see data from reader before it goes into or gate -#define OR_IN_A PORTAbits.RA4 -#define OR_IN_B PORTAbits.RA5 - - -// CNCON and CNEN are set to allow wiegand input pin weak pullups to be switched on -#define Init_GPIO() { \ - CNCONbits.ON= TRUE; \ - CNENbits.CNEN14= TRUE; \ - CNENbits.CNEN15= TRUE; \ - TRISAbits.TRISA2= INPUT_PIN; \ - TRISAbits.TRISA4= INPUT_PIN; \ - TRISAbits.TRISA5= INPUT_PIN; \ - TRISAbits.TRISA14= OUTPUT_PIN; \ - TRISAbits.TRISA15= OUTPUT_PIN; \ - TRISBbits.TRISB4= OUTPUT_PIN; \ - TRISBbits.TRISB5= OUTPUT_PIN; \ - TRISBbits.TRISB9= OUTPUT_PIN; \ - TRISBbits.TRISB11= INPUT_PIN; \ - TRISBbits.TRISB12= INPUT_PIN; \ - TRISBbits.TRISB13= INPUT_PIN; \ - TRISCbits.TRISC1= OUTPUT_PIN; \ - TRISCbits.TRISC2= OUTPUT_PIN; \ - TRISCbits.TRISC3= OUTPUT_PIN; \ - TRISCbits.TRISC4= INPUT_PIN; \ - TRISDbits.TRISD0= INPUT_PIN; \ - TRISDbits.TRISD1= OUTPUT_PIN; \ - TRISDbits.TRISD2= OUTPUT_PIN; \ - TRISDbits.TRISD3= OUTPUT_PIN; \ - TRISDbits.TRISD4= OUTPUT_PIN; \ - TRISDbits.TRISD5= INPUT_PIN; \ - TRISDbits.TRISD6= INPUT_PIN; \ - TRISDbits.TRISD7= OUTPUT_PIN; \ - TRISDbits.TRISD8= INPUT_PIN; \ - TRISDbits.TRISD11= OUTPUT_PIN; \ - TRISDbits.TRISD12= INPUT_PIN; \ - TRISEbits.TRISE0= OUTPUT_PIN; \ - TRISEbits.TRISE1= OUTPUT_PIN; \ - TRISEbits.TRISE2= OUTPUT_PIN; \ - TRISEbits.TRISE3= OUTPUT_PIN; \ - TRISEbits.TRISE5= OUTPUT_PIN; \ - TRISEbits.TRISE6= INPUT_PIN; \ - TRISEbits.TRISE7= INPUT_PIN; \ - TRISEbits.TRISE8= OUTPUT_PIN; \ - TRISEbits.TRISE9= OUTPUT_PIN; \ - TRISFbits.TRISF0= INPUT_PIN; \ - TRISFbits.TRISF1= INPUT_PIN; \ - TRISFbits.TRISF2= INPUT_PIN; \ - TRISFbits.TRISF8= OUTPUT_PIN; \ - TRISGbits.TRISG6= OUTPUT_PIN; \ - TRISGbits.TRISG12= INPUT_PIN; \ - TRISGbits.TRISG13= INPUT_PIN; \ - TRISGbits.TRISG9= OUTPUT_PIN; \ - LATBbits.LATB9= LOW; \ - LATCbits.LATC1= LOW; \ - LATCbits.LATC2= LOW; \ - LATCbits.LATC3= LOW; \ - LATDbits.LATD2= WIEGAND_IN_1; \ - LATDbits.LATD3= WIEGAND_IN_0; \ - LATEbits.LATE5= LOW; \ - LATEbits.LATE9= HIGH; \ - } - -// uart3 (CLI/API) speed -#define BAUDRATE3 115200UL -#define BRG_DIV3 4 -#define BRGH3 1 - -// spi for potentiometer -#define SPI_POT SPI_CHANNEL4 -#define SPI_POT_BUFF SPI4BUF -#define SPI_POT_STAT SPI4STATbits - -// spi for sd card - defines required for Microchip SD-SPI libs -// define interface type -#define USE_SD_INTERFACE_WITH_SPI - -#define MDD_USE_SPI_1 -#define SPI_START_CFG_1 (PRI_PRESCAL_64_1 | SEC_PRESCAL_8_1 | MASTER_ENABLE_ON | SPI_CKE_ON | SPI_SMP_ON) -#define SPI_START_CFG_2 (SPI_ENABLE) -// Define the SPI frequency -#define SPI_FREQUENCY (20000000) -// Description: SD-SPI Card Detect Input bit -#define SD_CD PORTFbits.RF0 -// Description: SD-SPI Card Detect TRIS bit -#define SD_CD_TRIS TRISFbits.TRISF0 -// Description: SD-SPI Write Protect Check Input bit -#define SD_WE PORTFbits.RF1 -// Description: SD-SPI Write Protect Check TRIS bit -#define SD_WE_TRIS TRISFbits.TRISF1 -// Description: The main SPI control register -#define SPICON1 SPI1CON -// Description: The SPI status register -#define SPISTAT SPI1STAT -// Description: The SPI Buffer -#define SPIBUF SPI1BUF -// Description: The receive buffer full bit in the SPI status register -#define SPISTAT_RBF SPI1STATbits.SPIRBF -// Description: The bitwise define for the SPI control register (i.e. _____bits) -#define SPICON1bits SPI1CONbits -// Description: The bitwise define for the SPI status register (i.e. _____bits) -#define SPISTATbits SPI1STATbits -// Description: The enable bit for the SPI module -#define SPIENABLE SPICON1bits.ON -// Description: The definition for the SPI baud rate generator register (PIC32) -#define SPIBRG SPI1BRG -// Description: The TRIS bit for the SCK pin -#define SPICLOCK TRISDbits.TRISD10 -// Description: The TRIS bit for the SDI pin -#define SPIIN TRISCbits.TRISC4 -// Description: The TRIS bit for the SDO pin -#define SPIOUT TRISDbits.TRISD0 -#define SD_CS LATDbits.LATD9 -// Description: SD-SPI Chip Select TRIS bit -#define SD_CS_TRIS TRISDbits.TRISD9 -//SPI library functions -#define putcSPI putcSPI1 -#define getcSPI getcSPI1 -#define OpenSPI(config1, config2) OpenSPI1(config1, config2) - -// Define setup parameters for OpenADC10 function -// Turn module on | Ouput in integer format | Trigger mode auto | Enable autosample -#define ADC_CONFIG1 (ADC_FORMAT_INTG | ADC_CLK_AUTO | ADC_AUTO_SAMPLING_ON) -// ADC ref external | Disable offset test | Disable scan mode | Perform 2 samples | Use dual buffers | Use alternate mode -#define ADC_CONFIG2 (ADC_VREF_AVDD_AVSS | ADC_OFFSET_CAL_DISABLE | ADC_SCAN_OFF | ADC_SAMPLES_PER_INT_1 | ADC_ALT_BUF_ON | ADC_ALT_INPUT_ON) - -// Use ADC internal clock | Set sample time -#define ADC_CONFIG3 (ADC_CONV_CLK_INTERNAL_RC | ADC_SAMPLE_TIME_0) - -// slow sample rate for tuning coils -#define ADC_CONFIG2_SLOW (ADC_VREF_AVDD_AVSS | ADC_OFFSET_CAL_DISABLE | ADC_SCAN_OFF | ADC_SAMPLES_PER_INT_16 | ADC_ALT_BUF_ON | ADC_ALT_INPUT_ON) -#define ADC_CONFIG3_SLOW (ADC_CONV_CLK_INTERNAL_RC | ADC_SAMPLE_TIME_31) - -// use AN11 -#define ADC_CONFIGPORT ENABLE_AN11_ANA -// Do not assign channels to scan -#define ADC_CONFIGSCAN SKIP_SCAN_ALL - -#define ADC_TO_VOLTS 0.003208F - - -// flash memory - int myvar = *(int*)(myflashmemoryaddress); - -// memory is 0x9D005000 to 0x9D07FFFF - -#define NVM_MEMORY_END 0x9D07FFFF -#define NVM_PAGE_SIZE 4096 -#define NVM_PAGES 2 // config & VTAG -#define RFIDLER_NVM_ADDRESS (NVM_MEMORY_END - (NVM_PAGE_SIZE * NVM_PAGES)) - -// UART timeout in us -#define SERIAL_TIMEOUT 100 - -#endif diff --git a/tools/hitag2crack/crack3/Makefile b/tools/hitag2crack/crack3/Makefile index 04965b55f..ebd4aca83 100644 --- a/tools/hitag2crack/crack3/Makefile +++ b/tools/hitag2crack/crack3/Makefile @@ -1,15 +1,17 @@ CFLAGS?=-Wall LIBS= +VPATH=../common +INC=-I ../common all: ht2crack3.c ht2test.c hitagcrypto.o utilpart.o - $(CC) $(CFLAGS) -o ht2crack3 ht2crack3.c hitagcrypto.o utilpart.o -lpthread $(LIBS) - $(CC) $(CFLAGS) -o ht2test ht2test.c hitagcrypto.o utilpart.o $(LIBS) + $(CC) $(CFLAGS) $(INC) -o ht2crack3 $< hitagcrypto.o utilpart.o -lpthread $(LIBS) + $(CC) $(CFLAGS) $(INC) -o ht2test ht2test.c hitagcrypto.o utilpart.o $(LIBS) hitagcrypto.o: hitagcrypto.c hitagcrypto.h - $(CC) $(CFLAGS) -c hitagcrypto.c + $(CC) $(CFLAGS) -c $< utilpart.o: utilpart.c util.h - $(CC) $(CFLAGS) -c utilpart.c + $(CC) $(CFLAGS) -c $< clean: rm -rf *.o ht2crack3 ht2test diff --git a/tools/hitag2crack/crack3/hitagcrypto.c b/tools/hitag2crack/crack3/hitagcrypto.c deleted file mode 100644 index 47449c3e3..000000000 --- a/tools/hitag2crack/crack3/hitagcrypto.c +++ /dev/null @@ -1,373 +0,0 @@ -/*************************************************************************** - * A copy of the GNU GPL is appended to this file. * - * * - * This licence is based on the nmap licence, and we express our gratitude * - * for the work that went into producing it. There is no other connection * - * between RFIDler and nmap either expressed or implied. * - * * - ********************** IMPORTANT RFIDler LICENSE TERMS ******************** - * * - * * - * All references to RFIDler herein imply all it's derivatives, namely: * - * * - * o RFIDler-LF Standard * - * o RFIDler-LF Lite * - * o RFIDler-LF Nekkid * - * * - * * - * RFIDler is (C) 2013-2015 Aperture Labs Ltd. * - * * - * This program is free software; you may redistribute and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE * - * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your * - * right to use, modify, and redistribute this software under certain * - * conditions. If you wish to embed RFIDler technology into proprietary * - * software or hardware, we sell alternative licenses * - * (contact sales@aperturelabs.com). * - * * - * Note that the GPL places important restrictions on "derivative works", * - * yet it does not provide a detailed definition of that term. To avoid * - * misunderstandings, we interpret that term as broadly as copyright law * - * allows. For example, we consider an application to constitute a * - * derivative work for the purpose of this license if it does any of the * - * following with any software or content covered by this license * - * ("Covered Software"): * - * * - * o Integrates source code from Covered Software. * - * * - * o Is designed specifically to execute Covered Software and parse the * - * results (as opposed to typical shell or execution-menu apps, which will * - * execute anything you tell them to). * - * * - * o Includes Covered Software in a proprietary executable installer. The * - * installers produced by InstallShield are an example of this. Including * - * RFIDler with other software in compressed or archival form does not * - * trigger this provision, provided appropriate open source decompression * - * or de-archiving software is widely available for no charge. For the * - * purposes of this license, an installer is considered to include Covered * - * Software even if it actually retrieves a copy of Covered Software from * - * another source during runtime (such as by downloading it from the * - * Internet). * - * * - * o Links (statically or dynamically) to a library which does any of the * - * above. * - * * - * o Executes a helper program, module, or script to do any of the above. * - * * - * This list is not exclusive, but is meant to clarify our interpretation * - * of derived works with some common examples. Other people may interpret * - * the plain GPL differently, so we consider this a special exception to * - * the GPL that we apply to Covered Software. Works which meet any of * - * these conditions must conform to all of the terms of this license, * - * particularly including the GPL Section 3 requirements of providing * - * source code and allowing free redistribution of the work as a whole. * - * * - * As another special exception to the GPL terms, Aperture Labs Ltd. grants* - * permission to link the code of this program with any version of the * - * OpenSSL library which is distributed under a license identical to that * - * listed in the included docs/licenses/OpenSSL.txt file, and distribute * - * linked combinations including the two. * - * * - * Any redistribution of Covered Software, including any derived works, * - * must obey and carry forward all of the terms of this license, including * - * obeying all GPL rules and restrictions. For example, source code of * - * the whole work must be provided and free redistribution must be * - * allowed. All GPL references to "this License", are to be treated as * - * including the terms and conditions of this license text as well. * - * * - * Because this license imposes special exceptions to the GPL, Covered * - * Work may not be combined (even as part of a larger work) with plain GPL * - * software. The terms, conditions, and exceptions of this license must * - * be included as well. This license is incompatible with some other open * - * source licenses as well. In some cases we can relicense portions of * - * RFIDler or grant special permissions to use it in other open source * - * software. Please contact sales@aperturelabs.com with any such requests.* - * Similarly, we don't incorporate incompatible open source software into * - * Covered Software without special permission from the copyright holders. * - * * - * If you have any questions about the licensing restrictions on using * - * RFIDler in other works, are happy to help. As mentioned above, we also * - * offer alternative license to integrate RFIDler into proprietary * - * applications and appliances. These contracts have been sold to dozens * - * of software vendors, and generally include a perpetual license as well * - * as providing for priority support and updates. They also fund the * - * continued development of RFIDler. Please email sales@aperturelabs.com * - * for further information. * - * If you have received a written license agreement or contract for * - * Covered Software stating terms other than these, you may choose to use * - * and redistribute Covered Software under those terms instead of these. * - * * - * Source is provided to this software because we believe users have a * - * right to know exactly what a program is going to do before they run it. * - * This also allows you to audit the software for security holes (none * - * have been found so far). * - * * - * Source code also allows you to port RFIDler to new platforms, fix bugs, * - * and add new features. You are highly encouraged to send your changes * - * to the RFIDler mailing list for possible incorporation into the * - * main distribution. By sending these changes to Aperture Labs Ltd. or * - * one of the Aperture Labs Ltd. development mailing lists, or checking * - * them into the RFIDler source code repository, it is understood (unless * - * you specify otherwise) that you are offering the RFIDler Project * - * (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, * - * modify, and relicense the code. RFIDler will always be available Open * - * Source, but this is important because the inability to relicense code * - * has caused devastating problems for other Free Software projects (such * - * as KDE and NASM). We also occasionally relicense the code to third * - * parties as discussed above. If you wish to specify special license * - * conditions of your contributions, just say so when you send them. * - * * - * This program is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler * - * license file for more details (it's in a COPYING file included with * - * RFIDler, and also available from * - * https://github.com/ApertureLabsLtd/RFIDler/COPYING * - * * - ***************************************************************************/ - -// Author: unknown. -// Modifications for RFIDler: Tony Naggs , Adam Laurie - -// uncomment this to build file as a standalone crypto test program -// #define UNIT_TEST -// also uncomment to include verbose debug prints -// #define TEST_DEBUG - -//#include -#include "HardwareProfile.h" -#include "rfidler.h" -#include "hitagcrypto.h" -#include "util.h" - -#ifdef UNIT_TEST -#include -#endif - -#if defined(UNIT_TEST) && defined(TEST_DEBUG) -// Note that printf format %I64x prints 64 bit ints in MS Visual C/C++. -// This may need changing for other compilers/platforms. -#define DEBUG_PRINTF(...) printf(__VA_ARGS__) -#else -#define DEBUG_PRINTF(...) -#endif - - -/* Brief info about NXP Hitag 1, Hitag 2, Hitag S and Hitag u (mu) - - Hitag 125kHz RFID was created by a company called Mikron (Mikron Gesellschaft - fur Integrierte Mikroelektronik Mbh), of Austria, for micropayment applications. - At about the same time, late 1980s to early 1990s, Mikron developed the - similarly featured Mifare micropayment card for 13.56MHz RFID. - (Mikron's European Patent EP 0473569 A2 was filed 23 August 1991, with a - priority date of 23 Aug 1990.) - Mikron was subsequently acquired by Philips Semiconductors in 1995. - Philips Semiconductors divsion subsequently became NXP. - - + Modulation read/write device -> transponder: 100 % ASK and binary pulse - length coding - + Modulation transponder -> read/write device: Strong ASK modulation, - selectable Manchester or Biphase coding - + Hitag S, Hitag u; anti-collision procedure - + Fast anti-collision protocol - + Hitag u; optional Cyclic Redundancy Check (CRC) - + Reader Talks First mode - + Hitag 2 & later; Transponder Talks First (TTF) mode - + Temporary switch from Transponder Talks First into Reader Talks First - (RTF) Mode - + Data rate read/write device to transponder: 5.2 kbit/s - + Data rates transponder to read/write device: 2 kbit/s, 4 kbit/s, 8 kbit/s - + 32-bit password feature - + Hitag 2, S = 32-bit Unique Identifier - + Hitag u = 48-bit Unique Identifier - + Selectable password modes for reader / tag mutual authentication - (Hitag 1 has 2 pairs of keys, later versions have 1 pair) - + Hitag 2 & Hitag S; Selectable encrypted mode, 48 bit key - - Known tag types: - - HITAG 1 2048 bits total memory - - HITAG 2 256 Bit total memory Read/Write - 8 pages of 32 bits, inc UID (32), - secret key (64), password (24), config (8) - - HITAG S 32 32 bits Unique Identifier Read Only - HITAG S 256 256 bits total memory Read/Write - HITAG S 2048 2048 bits total memory Read/Write - - HITAG u RO64 64 bits total memory Read Only - HITAG u 128 bits total memory Read/Write - HITAG u Advanced 512 bits total memory Read/Write - HITAG u Advanced+ 1760 bits total memory Read/Write - - Default 48-bit key for Hitag 2, S encryption: - "MIKRON" = O N M I K R - Key = 4F 4E 4D 49 4B 52 - -*/ - - -// We want the crypto functions to be as fast as possible, so optimize! -// The best compiler optimization in Microchip's free XC32 edition is -O1 -#pragma GCC optimize("O1") - -// private, nonlinear function to generate 1 crypto bit -static uint32_t hitag2_crypt(uint64_t x); - - -// macros to pick out 4 bits in various patterns of 1s & 2s & make a new number -#define pickbits2_2(S, A, B) ( ((S >> A) & 3) | ((S >> (B - 2)) & 0xC) ) -#define pickbits1x4(S, A, B, C, D) ( ((S >> A) & 1) | ((S >> (B - 1)) & 2) | \ - ((S >> (C - 2)) & 4) | ((S >> (D - 3)) & 8) ) -#define pickbits1_1_2(S, A, B, C) ( ((S >> A) & 1) | ((S >> (B - 1)) & 2) | \ - ((S >> (C - 2)) & 0xC) ) -#define pickbits2_1_1(S, A, B, C) ( ((S >> A) & 3) | ((S >> (B - 2)) & 4) | \ - ((S >> (C - 3)) & 8) ) -#define pickbits1_2_1(S, A, B, C) ( ((S >> A) & 1) | ((S >> (B - 1)) & 6) | \ - ((S >> (C - 3)) & 8) ) - - -static uint32_t hitag2_crypt(uint64_t x) { - const uint32_t ht2_function4a = 0x2C79; // 0010 1100 0111 1001 - const uint32_t ht2_function4b = 0x6671; // 0110 0110 0111 0001 - const uint32_t ht2_function5c = 0x7907287B; // 0111 1001 0000 0111 0010 1000 0111 1011 - uint32_t bitindex; - - bitindex = (ht2_function4a >> pickbits2_2(x, 1, 4)) & 1; - bitindex |= ((ht2_function4b << 1) >> pickbits1_1_2(x, 7, 11, 13)) & 0x02; - bitindex |= ((ht2_function4b << 2) >> pickbits1x4(x, 16, 20, 22, 25)) & 0x04; - bitindex |= ((ht2_function4b << 3) >> pickbits2_1_1(x, 27, 30, 32)) & 0x08; - bitindex |= ((ht2_function4a << 4) >> pickbits1_2_1(x, 33, 42, 45)) & 0x10; - - DEBUG_PRINTF("hitag2_crypt bitindex = %02x\n", bitindex); - return (ht2_function5c >> bitindex) & 1; -} - -/* - * Parameters: - * Hitag_State* pstate - output, internal state after initialisation - * uint64_t sharedkey - 48 bit key shared between reader & tag - * uint32_t serialnum - 32 bit tag serial number - * uint32_t initvector - 32 bit random IV from reader, part of tag authentication - */ -void hitag2_init(Hitag_State *pstate, uint64_t sharedkey, uint32_t serialnum, uint32_t initvector) { - // init state, from serial number and lowest 16 bits of shared key - uint64_t state = ((sharedkey & 0xFFFF) << 32) | serialnum; - - // mix the initialisation vector and highest 32 bits of the shared key - initvector ^= (uint32_t)(sharedkey >> 16); - - // move 16 bits from (IV xor Shared Key) to top of uint64_t state - // these will be XORed in turn with output of the crypto function - state |= (uint64_t) initvector << 48; - initvector >>= 16; - - // unrolled loop is faster on PIC32 (MIPS), do 32 times - // shift register, then calc new bit - state >>= 1; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - - // highest 16 bits of IV XOR Shared Key - state |= (uint64_t) initvector << 47; - - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state ^= (uint64_t) hitag2_crypt(state) << 47; - - DEBUG_PRINTF("hitag2_init result = %012I64x\n", state); - pstate->shiftreg = state; - /* naive version for reference, LFSR has 16 taps - pstate->lfsr = state ^ (state >> 2) ^ (state >> 3) ^ (state >> 6) - ^ (state >> 7) ^ (state >> 8) ^ (state >> 16) ^ (state >> 22) - ^ (state >> 23) ^ (state >> 26) ^ (state >> 30) ^ (state >> 41) - ^ (state >> 42) ^ (state >> 43) ^ (state >> 46) ^ (state >> 47); - */ - { - // optimise with one 64-bit intermediate - uint64_t temp = state ^ (state >> 1); - pstate->lfsr = state ^ (state >> 6) ^ (state >> 16) - ^ (state >> 26) ^ (state >> 30) ^ (state >> 41) - ^ (temp >> 2) ^ (temp >> 7) ^ (temp >> 22) - ^ (temp >> 42) ^ (temp >> 46); - } -} - - -/* - * Return up to 32 crypto bits. - * Last bit is in least significant bit, earlier bits are shifted left. - * Note that the Hitag transmission protocol is least significant bit, - * so we may want to change this, or add a function, that returns the - * crypto output bits in the other order. - * - * Parameters: - * Hitag_State* pstate - in/out, internal cipher state after initialisation - * uint32_t steps - number of bits requested, (capped at 32) - */ -uint32_t hitag2_nstep(Hitag_State *pstate, uint32_t steps) { - uint64_t state = pstate->shiftreg; - uint32_t result = 0; - uint64_t lfsr = pstate->lfsr; - - if (steps == 0) - return 0; - -// if (steps > 32) -// steps = 32; - - do { - // update shift registers - if (lfsr & 1) { - state = (state >> 1) | 0x800000000000; - lfsr = (lfsr >> 1) ^ 0xB38083220073; - - // accumulate next bit of crypto - result = (result << 1) | hitag2_crypt(state); - } else { - state >>= 1; - lfsr >>= 1; - - result = (result << 1) | hitag2_crypt(state); - } - } while (--steps); - - DEBUG_PRINTF("hitag2_nstep state = %012I64x, result %02x\n", state, result); - pstate->shiftreg = state; - pstate->lfsr = lfsr; - return result; -} - -// end of crypto core, revert to default optimization level -#pragma GCC reset_options diff --git a/tools/hitag2crack/crack3/hitagcrypto.h b/tools/hitag2crack/crack3/hitagcrypto.h deleted file mode 100644 index 274d3d82c..000000000 --- a/tools/hitag2crack/crack3/hitagcrypto.h +++ /dev/null @@ -1,167 +0,0 @@ -/*************************************************************************** - * A copy of the GNU GPL is appended to this file. * - * * - * This licence is based on the nmap licence, and we express our gratitude * - * for the work that went into producing it. There is no other connection * - * between RFIDler and nmap either expressed or implied. * - * * - ********************** IMPORTANT RFIDler LICENSE TERMS ******************** - * * - * * - * All references to RFIDler herein imply all it's derivatives, namely: * - * * - * o RFIDler-LF Standard * - * o RFIDler-LF Lite * - * o RFIDler-LF Nekkid * - * * - * * - * RFIDler is (C) 2013-2014 Aperture Labs Ltd. * - * * - * This program is free software; you may redistribute and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE * - * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your * - * right to use, modify, and redistribute this software under certain * - * conditions. If you wish to embed RFIDler technology into proprietary * - * software or hardware, we sell alternative licenses * - * (contact sales@aperturelabs.com). * - * * - * Note that the GPL places important restrictions on "derivative works", * - * yet it does not provide a detailed definition of that term. To avoid * - * misunderstandings, we interpret that term as broadly as copyright law * - * allows. For example, we consider an application to constitute a * - * derivative work for the purpose of this license if it does any of the * - * following with any software or content covered by this license * - * ("Covered Software"): * - * * - * o Integrates source code from Covered Software. * - * * - * o Is designed specifically to execute Covered Software and parse the * - * results (as opposed to typical shell or execution-menu apps, which will * - * execute anything you tell them to). * - * * - * o Includes Covered Software in a proprietary executable installer. The * - * installers produced by InstallShield are an example of this. Including * - * RFIDler with other software in compressed or archival form does not * - * trigger this provision, provided appropriate open source decompression * - * or de-archiving software is widely available for no charge. For the * - * purposes of this license, an installer is considered to include Covered * - * Software even if it actually retrieves a copy of Covered Software from * - * another source during runtime (such as by downloading it from the * - * Internet). * - * * - * o Links (statically or dynamically) to a library which does any of the * - * above. * - * * - * o Executes a helper program, module, or script to do any of the above. * - * * - * This list is not exclusive, but is meant to clarify our interpretation * - * of derived works with some common examples. Other people may interpret * - * the plain GPL differently, so we consider this a special exception to * - * the GPL that we apply to Covered Software. Works which meet any of * - * these conditions must conform to all of the terms of this license, * - * particularly including the GPL Section 3 requirements of providing * - * source code and allowing free redistribution of the work as a whole. * - * * - * As another special exception to the GPL terms, Aperture Labs Ltd. grants* - * permission to link the code of this program with any version of the * - * OpenSSL library which is distributed under a license identical to that * - * listed in the included docs/licenses/OpenSSL.txt file, and distribute * - * linked combinations including the two. * - * * - * Any redistribution of Covered Software, including any derived works, * - * must obey and carry forward all of the terms of this license, including * - * obeying all GPL rules and restrictions. For example, source code of * - * the whole work must be provided and free redistribution must be * - * allowed. All GPL references to "this License", are to be treated as * - * including the terms and conditions of this license text as well. * - * * - * Because this license imposes special exceptions to the GPL, Covered * - * Work may not be combined (even as part of a larger work) with plain GPL * - * software. The terms, conditions, and exceptions of this license must * - * be included as well. This license is incompatible with some other open * - * source licenses as well. In some cases we can relicense portions of * - * RFIDler or grant special permissions to use it in other open source * - * software. Please contact sales@aperturelabs.com with any such requests.* - * Similarly, we don't incorporate incompatible open source software into * - * Covered Software without special permission from the copyright holders. * - * * - * If you have any questions about the licensing restrictions on using * - * RFIDler in other works, are happy to help. As mentioned above, we also * - * offer alternative license to integrate RFIDler into proprietary * - * applications and appliances. These contracts have been sold to dozens * - * of software vendors, and generally include a perpetual license as well * - * as providing for priority support and updates. They also fund the * - * continued development of RFIDler. Please email sales@aperturelabs.com * - * for further information. * - * If you have received a written license agreement or contract for * - * Covered Software stating terms other than these, you may choose to use * - * and redistribute Covered Software under those terms instead of these. * - * * - * Source is provided to this software because we believe users have a * - * right to know exactly what a program is going to do before they run it. * - * This also allows you to audit the software for security holes (none * - * have been found so far). * - * * - * Source code also allows you to port RFIDler to new platforms, fix bugs, * - * and add new features. You are highly encouraged to send your changes * - * to the RFIDler mailing list for possible incorporation into the * - * main distribution. By sending these changes to Aperture Labs Ltd. or * - * one of the Aperture Labs Ltd. development mailing lists, or checking * - * them into the RFIDler source code repository, it is understood (unless * - * you specify otherwise) that you are offering the RFIDler Project * - * (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, * - * modify, and relicense the code. RFIDler will always be available Open * - * Source, but this is important because the inability to relicense code * - * has caused devastating problems for other Free Software projects (such * - * as KDE and NASM). We also occasionally relicense the code to third * - * parties as discussed above. If you wish to specify special license * - * conditions of your contributions, just say so when you send them. * - * * - * This program is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler * - * license file for more details (it's in a COPYING file included with * - * RFIDler, and also available from * - * https://github.com/ApertureLabsLtd/RFIDler/COPYING * - * * - ***************************************************************************/ - -// Author: unknown. -// Modifications for RFIDler: Tony Naggs , Adam Laurie - - -#ifndef HITAGCRYPTO_H -#define HITAGCRYPTO_H - -#include - -/* - Our model of Hitag 2 crypto uses 2 parallel shift registers: - a. 48 bit Feedback Shift Register, required for inputs to the nonlinear function. - b. 48 bit Linear Feedback Shift Register (LFSR). - A transform of initial register (a) value, which is then run in parallel. - Enables much faster calculation of the feedback values. - - API: - void hitag2_init(Hitag_State* pstate, uint64_t sharedkey, uint32_t serialnum, - uint32_t initvector); - Initialise state from 48 bit shared (secret) reader/tag key, - 32 bit tag serial number and 32 bit initialisation vector from reader. - - uint32_t hitag2_nstep(Hitag_State* pstate, uint32_t steps); - update shift register state and generate N cipher bits (N should be <= 32) - */ - - -typedef struct { - uint64_t shiftreg; // naive shift register, required for nonlinear fn input - uint64_t lfsr; // fast lfsr, used to make software faster -} Hitag_State; - -void hitag2_init(Hitag_State *pstate, uint64_t sharedkey, uint32_t serialnum, uint32_t initvector); - -uint32_t hitag2_nstep(Hitag_State *pstate, uint32_t steps); - -#endif /* HITAGCRYPTO_H */ - diff --git a/tools/hitag2crack/crack3/rfidler.h b/tools/hitag2crack/crack3/rfidler.h deleted file mode 100644 index 933547e6b..000000000 --- a/tools/hitag2crack/crack3/rfidler.h +++ /dev/null @@ -1,412 +0,0 @@ -/*************************************************************************** - * A copy of the GNU GPL is appended to this file. * - * * - * This licence is based on the nmap licence, and we express our gratitude * - * for the work that went into producing it. There is no other connection * - * between RFIDler and nmap either expressed or implied. * - * * - ********************** IMPORTANT RFIDler LICENSE TERMS ******************** - * * - * * - * All references to RFIDler herein imply all it's derivatives, namely: * - * * - * o RFIDler-LF Standard * - * o RFIDler-LF Lite * - * o RFIDler-LF Nekkid * - * * - * * - * RFIDler is (C) 2013-2015 Aperture Labs Ltd. * - * * - * This program is free software; you may redistribute and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE * - * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your * - * right to use, modify, and redistribute this software under certain * - * conditions. If you wish to embed RFIDler technology into proprietary * - * software or hardware, we sell alternative licenses * - * (contact sales@aperturelabs.com). * - * * - * Note that the GPL places important restrictions on "derivative works", * - * yet it does not provide a detailed definition of that term. To avoid * - * misunderstandings, we interpret that term as broadly as copyright law * - * allows. For example, we consider an application to constitute a * - * derivative work for the purpose of this license if it does any of the * - * following with any software or content covered by this license * - * ("Covered Software"): * - * * - * o Integrates source code from Covered Software. * - * * - * o Is designed specifically to execute Covered Software and parse the * - * results (as opposed to typical shell or execution-menu apps, which will * - * execute anything you tell them to). * - * * - * o Includes Covered Software in a proprietary executable installer. The * - * installers produced by InstallShield are an example of this. Including * - * RFIDler with other software in compressed or archival form does not * - * trigger this provision, provided appropriate open source decompression * - * or de-archiving software is widely available for no charge. For the * - * purposes of this license, an installer is considered to include Covered * - * Software even if it actually retrieves a copy of Covered Software from * - * another source during runtime (such as by downloading it from the * - * Internet). * - * * - * o Links (statically or dynamically) to a library which does any of the * - * above. * - * * - * o Executes a helper program, module, or script to do any of the above. * - * * - * This list is not exclusive, but is meant to clarify our interpretation * - * of derived works with some common examples. Other people may interpret * - * the plain GPL differently, so we consider this a special exception to * - * the GPL that we apply to Covered Software. Works which meet any of * - * these conditions must conform to all of the terms of this license, * - * particularly including the GPL Section 3 requirements of providing * - * source code and allowing free redistribution of the work as a whole. * - * * - * As another special exception to the GPL terms, Aperture Labs Ltd. grants* - * permission to link the code of this program with any version of the * - * OpenSSL library which is distributed under a license identical to that * - * listed in the included docs/licenses/OpenSSL.txt file, and distribute * - * linked combinations including the two. * - * * - * Any redistribution of Covered Software, including any derived works, * - * must obey and carry forward all of the terms of this license, including * - * obeying all GPL rules and restrictions. For example, source code of * - * the whole work must be provided and free redistribution must be * - * allowed. All GPL references to "this License", are to be treated as * - * including the terms and conditions of this license text as well. * - * * - * Because this license imposes special exceptions to the GPL, Covered * - * Work may not be combined (even as part of a larger work) with plain GPL * - * software. The terms, conditions, and exceptions of this license must * - * be included as well. This license is incompatible with some other open * - * source licenses as well. In some cases we can relicense portions of * - * RFIDler or grant special permissions to use it in other open source * - * software. Please contact sales@aperturelabs.com with any such requests.* - * Similarly, we don't incorporate incompatible open source software into * - * Covered Software without special permission from the copyright holders. * - * * - * If you have any questions about the licensing restrictions on using * - * RFIDler in other works, are happy to help. As mentioned above, we also * - * offer alternative license to integrate RFIDler into proprietary * - * applications and appliances. These contracts have been sold to dozens * - * of software vendors, and generally include a perpetual license as well * - * as providing for priority support and updates. They also fund the * - * continued development of RFIDler. Please email sales@aperturelabs.com * - * for further information. * - * If you have received a written license agreement or contract for * - * Covered Software stating terms other than these, you may choose to use * - * and redistribute Covered Software under those terms instead of these. * - * * - * Source is provided to this software because we believe users have a * - * right to know exactly what a program is going to do before they run it. * - * This also allows you to audit the software for security holes (none * - * have been found so far). * - * * - * Source code also allows you to port RFIDler to new platforms, fix bugs, * - * and add new features. You are highly encouraged to send your changes * - * to the RFIDler mailing list for possible incorporation into the * - * main distribution. By sending these changes to Aperture Labs Ltd. or * - * one of the Aperture Labs Ltd. development mailing lists, or checking * - * them into the RFIDler source code repository, it is understood (unless * - * you specify otherwise) that you are offering the RFIDler Project * - * (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, * - * modify, and relicense the code. RFIDler will always be available Open * - * Source, but this is important because the inability to relicense code * - * has caused devastating problems for other Free Software projects (such * - * as KDE and NASM). We also occasionally relicense the code to third * - * parties as discussed above. If you wish to specify special license * - * conditions of your contributions, just say so when you send them. * - * * - * This program is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler * - * license file for more details (it's in a COPYING file included with * - * RFIDler, and also available from * - * https://github.com/ApertureLabsLtd/RFIDler/COPYING * - * * - ***************************************************************************/ - -// Author: Adam Laurie - -#include -#include - -// BCD hardware revision for usb descriptor (usb_descriptors.c) -#define RFIDLER_HW_VERSION 0x020 - -// max sizes in BITS -#define MAXBLOCKSIZE 512 -#define MAXTAGSIZE 4096 -#define MAXUID 512 - -#define TMP_LARGE_BUFF_LEN 2048 -#define TMP_SMALL_BUFF_LEN 256 -#define ANALOGUE_BUFF_LEN 8192 - -#define COMMS_BUFFER_SIZE 128 - -#define DETECT_BUFFER_SIZE 512 - -#define SAMPLEMASK ~(BIT_1 | BIT_0) // mask to remove two bottom bits from analogue sample - we will then use those for reader & bit period - -// globals - -extern BOOL WiegandOutput; // Output wiegand data whenenver UID is read -extern BYTE *EMU_Reset_Data; // Pointer to full array of bits as bytes, stored as 0x00/0x01, '*' terminated -extern BYTE *EMU_Data; // Pointer to current location in EMU_Reset_Data -extern BYTE EMU_ThisBit; // The next data bit to transmit -extern BYTE EMU_SubCarrier_T0; // Number of Frame Clocks for sub-carrier '0' -extern BYTE EMU_SubCarrier_T1; // Number of Frame Clocks for sub-carrier '1' -extern unsigned int EMU_Repeat; // Number of times to transmit full data set -extern BOOL EMU_Background; // Emulate in the background until told to stop -extern unsigned int EMU_DataBitRate; // Number of Frame Clocks per bit -extern BYTE TmpBits[TMP_LARGE_BUFF_LEN]; // Shared scratchpad -extern BYTE ReaderPeriod; // Flag for sample display -extern unsigned char Comms_In_Buffer[COMMS_BUFFER_SIZE]; // USB/Serial buffer -extern BYTE Interface; // user interface - CLI or API -extern BYTE CommsChannel; // user comms channel - USB or UART -extern BOOL FakeRead; // flag for analogue sampler to signal it wants access to buffers during read -extern BOOL PWD_Mode; // is this tag password protected? -extern BYTE Password[9]; // 32 bits as HEX string set with LOGIN -extern unsigned int Led_Count; // LED status counter, also used for entropy -extern unsigned long Reader_Bit_Count; // Reader ISR bit counter -extern char Previous; // Reader ISR previous bit type - -// RWD (read/write device) coil state -extern BYTE RWD_State; // current state of RWD coil -extern unsigned int RWD_Fc; // field clock in uS -extern unsigned int RWD_Gap_Period; // length of command gaps in OC5 ticks -extern unsigned int RWD_Zero_Period; // length of '0' in OC5 ticks -extern unsigned int RWD_One_Period; // length of '1' in OC5 ticks -extern unsigned int RWD_Sleep_Period; // length of initial sleep to reset tag in OC5 ticks -extern unsigned int RWD_Wake_Period; // length required for tag to restart in OC5 ticks -extern unsigned int RWD_Wait_Switch_TX_RX; // length to wait when switching from TX to RX in OC5 ticks -extern unsigned int RWD_Wait_Switch_RX_TX; // length to wait when switching from RX to TX in OC5 ticks -extern unsigned int RWD_Post_Wait; // low level ISR wait period in OC5 ticks -extern unsigned int RWD_OC5_config; // Output Compare Module settings -extern unsigned int RWD_OC5_r; // Output Compare Module primary compare value -extern unsigned int RWD_OC5_rs; // Output Compare Module secondary compare value -extern BYTE RWD_Command_Buff[TMP_SMALL_BUFF_LEN]; // Command buffer, array of bits as bytes, stored as 0x00/0x01, '*' terminated -extern BYTE *RWD_Command_ThisBit; // Current command bit -extern BOOL Reader_ISR_State; // current state of reader ISR - -// NVM variables -// timings etc. that want to survive a reboot should go here -typedef struct { - BYTE Name[7]; // will be set to "RFIDler" so we can test for new device - BYTE AutoRun[128]; // optional command to run at startup - unsigned char TagType; - unsigned int PSK_Quality; - unsigned int Timeout; - unsigned int Wiegand_Pulse; - unsigned int Wiegand_Gap; - BOOL Wiegand_IdleState; - unsigned int FrameClock; - unsigned char Modulation; - unsigned int DataRate; - unsigned int DataRateSub0; - unsigned int DataRateSub1; - unsigned int DataBits; - unsigned int DataBlocks; - unsigned int BlockSize; - unsigned char SyncBits; - BYTE Sync[4]; - BOOL BiPhase; - BOOL Invert; - BOOL Manchester; - BOOL HalfDuplex; - unsigned int Repeat; - unsigned int PotLow; - unsigned int PotHigh; - unsigned int RWD_Gap_Period; - unsigned int RWD_Zero_Period; - unsigned int RWD_One_Period; - unsigned int RWD_Sleep_Period; - unsigned int RWD_Wake_Period; - unsigned int RWD_Wait_Switch_TX_RX; - unsigned int RWD_Wait_Switch_RX_TX; -} StoredConfig; - -// somewhere to store TAG data. this will be interpreted according to the TAG -// type. -typedef struct { - BYTE TagType; // raw tag type - BYTE EmulatedTagType; // tag type this tag is configured to emulate - BYTE UID[MAXUID + 1]; // Null-terminated HEX string - BYTE Data[MAXTAGSIZE]; // raw data - unsigned char DataBlocks; // number of blocks in Data field - unsigned int BlockSize; // blocksize in bits -} VirtualTag; - -extern StoredConfig RFIDlerConfig; -extern VirtualTag RFIDlerVTag; -extern BYTE TmpBuff[NVM_PAGE_SIZE]; -extern BYTE DataBuff[ANALOGUE_BUFF_LEN]; -extern unsigned int DataBuffCount; -extern const BYTE *ModulationSchemes[]; -extern const BYTE *OnOff[]; -extern const BYTE *HighLow[]; -extern const BYTE *TagTypes[]; - -// globals for ISRs -extern BYTE EmulationMode; -extern unsigned long HW_Bits; -extern BYTE HW_Skip_Bits; -extern unsigned int PSK_Min_Pulse; -extern BOOL PSK_Read_Error; -extern BOOL Manchester_Error; -extern BOOL SnifferMode; -extern unsigned int Clock_Tick_Counter; -extern BOOL Clock_Tick_Counter_Reset; - -// smart card lib -#define MAX_ATR_LEN (BYTE)33 -extern BYTE scCardATR[MAX_ATR_LEN]; -extern BYTE scATRLength; - -// RTC -extern rtccTime RTC_time; // time structure -extern rtccDate RTC_date; // date structure - -// digital pots -#define POTLOW_DEFAULT 100 -#define POTHIGH_DEFAULT 150 -#define DC_OFFSET 60 // analogue circuit DC offset (as close as we can get without using 2 LSB) -#define VOLTS_TO_POT 0.019607843F - -// RWD/clock states -#define RWD_STATE_INACTIVE 0 // RWD not in use -#define RWD_STATE_GO_TO_SLEEP 1 // RWD coil shutdown request -#define RWD_STATE_SLEEPING 2 // RWD coil shutdown for sleep period -#define RWD_STATE_WAKING 3 // RWD active for pre-determined period after reset -#define RWD_STATE_START_SEND 4 // RWD starting send of data -#define RWD_STATE_SENDING_GAP 5 // RWD sending a gap -#define RWD_STATE_SENDING_BIT 6 // RWD sending a data bit -#define RWD_STATE_POST_WAIT 7 // RWD finished sending data, now in forced wait period -#define RWD_STATE_ACTIVE 8 // RWD finished, now just clocking a carrier - -// reader ISR states -#define READER_STOPPED 0 // reader not in use -#define READER_IDLING 1 // reader ISR running to preserve timing, but not reading -#define READER_RUNNING 2 // reader reading bits - - -// user interface types -#define INTERFACE_API 0 -#define INTERFACE_CLI 1 - -// comms channel -#define COMMS_NONE 0 -#define COMMS_USB 1 -#define COMMS_UART 2 - -#define MAX_HISTORY 2 // disable most of history for now - memory issue - -// tag write retries -#define TAG_WRITE_RETRY 5 - -// modulation modes - uppdate ModulationSchemes[] in tags.c if you change this -#define MOD_MODE_NONE 0 -#define MOD_MODE_ASK_OOK 1 -#define MOD_MODE_FSK1 2 -#define MOD_MODE_FSK2 3 -#define MOD_MODE_PSK1 4 -#define MOD_MODE_PSK2 5 -#define MOD_MODE_PSK3 6 - -// TAG types - update TagTypes[] in tags.c if you add to this list -#define TAG_TYPE_NONE 0 -#define TAG_TYPE_ASK_RAW 1 -#define TAG_TYPE_FSK1_RAW 2 -#define TAG_TYPE_FSK2_RAW 3 -#define TAG_TYPE_PSK1_RAW 4 -#define TAG_TYPE_PSK2_RAW 5 -#define TAG_TYPE_PSK3_RAW 6 -#define TAG_TYPE_HITAG1 7 -#define TAG_TYPE_HITAG2 8 -#define TAG_TYPE_EM4X02 9 -#define TAG_TYPE_Q5 10 -#define TAG_TYPE_HID_26 11 -#define TAG_TYPE_INDALA_64 12 -#define TAG_TYPE_INDALA_224 13 -#define TAG_TYPE_UNIQUE 14 -#define TAG_TYPE_FDXB 15 -#define TAG_TYPE_T55X7 16 // same as Q5 but different timings and no modulation-defeat -#define TAG_TYPE_AWID_26 17 -#define TAG_TYPE_EM4X05 18 -#define TAG_TYPE_TAMAGOTCHI 19 -#define TAG_TYPE_HDX 20 // same underlying data as FDX-B, but different modulation & telegram - -// various - -#define BINARY 0 -#define HEX 1 - -#define NO_ADDRESS -1 - -#define ACK TRUE -#define NO_ACK FALSE - -#define BLOCK TRUE -#define NO_BLOCK FALSE - -#define DATA TRUE -#define NO_DATA FALSE - -#define DEBUG_PIN_ON HIGH -#define DEBUG_PIN_OFF LOW - -#define FAST FALSE -#define SLOW TRUE - -#define NO_TRIGGER 0 - -#define LOCK TRUE -#define NO_LOCK FALSE - -#define NFC_MODE TRUE -#define NO_NFC_MODE FALSE - -#define ONESHOT_READ TRUE -#define NO_ONESHOT_READ FALSE - -#define RESET TRUE -#define NO_RESET FALSE - -#define SHUTDOWN_CLOCK TRUE -#define NO_SHUTDOWN_CLOCK FALSE - -#define SYNC TRUE -#define NO_SYNC FALSE - -#define VERIFY TRUE -#define NO_VERIFY FALSE - -#define VOLATILE FALSE -#define NON_VOLATILE TRUE - -#define NEWLINE TRUE -#define NO_NEWLINE FALSE - -#define WAIT TRUE -#define NO_WAIT FALSE - -#define WIPER_HIGH 0 -#define WIPER_LOW 1 - -// conversion for time to ticks -#define US_TO_TICKS 1000000L -#define US_OVER_10_TO_TICKS 10000000L -#define US_OVER_100_TO_TICKS 100000000L -// we can't get down to this level on pic, but we want to standardise on timings, so for now we fudge it -#define CONVERT_TO_TICKS(x) ((x / 10) * (GetSystemClock() / US_OVER_10_TO_TICKS)) -#define CONVERT_TICKS_TO_US(x) (x / (GetSystemClock() / US_TO_TICKS)) -#define TIMER5_PRESCALER 16 -#define MAX_TIMER5_TICKS (65535 * TIMER5_PRESCALER) - -// other conversions - -// bits to hex digits -#define HEXDIGITS(x) (x / 4) -#define HEXTOBITS(x) (x * 4) diff --git a/tools/hitag2crack/crack3/utilpart.c b/tools/hitag2crack/crack3/utilpart.c deleted file mode 100644 index c46148491..000000000 --- a/tools/hitag2crack/crack3/utilpart.c +++ /dev/null @@ -1,180 +0,0 @@ -/*************************************************************************** - * A copy of the GNU GPL is appended to this file. * - * * - * This licence is based on the nmap licence, and we express our gratitude * - * for the work that went into producing it. There is no other connection * - * between RFIDler and nmap either expressed or implied. * - * * - ********************** IMPORTANT RFIDler LICENSE TERMS ******************** - * * - * * - * All references to RFIDler herein imply all it's derivatives, namely: * - * * - * o RFIDler-LF Standard * - * o RFIDler-LF Lite * - * o RFIDler-LF Nekkid * - * * - * * - * RFIDler is (C) 2013-2014 Aperture Labs Ltd. * - * * - * This program is free software; you may redistribute and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE * - * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your * - * right to use, modify, and redistribute this software under certain * - * conditions. If you wish to embed RFIDler technology into proprietary * - * software or hardware, we sell alternative licenses * - * (contact sales@aperturelabs.com). * - * * - * Note that the GPL places important restrictions on "derivative works", * - * yet it does not provide a detailed definition of that term. To avoid * - * misunderstandings, we interpret that term as broadly as copyright law * - * allows. For example, we consider an application to constitute a * - * derivative work for the purpose of this license if it does any of the * - * following with any software or content covered by this license * - * ("Covered Software"): * - * * - * o Integrates source code from Covered Software. * - * * - * o Is designed specifically to execute Covered Software and parse the * - * results (as opposed to typical shell or execution-menu apps, which will * - * execute anything you tell them to). * - * * - * o Includes Covered Software in a proprietary executable installer. The * - * installers produced by InstallShield are an example of this. Including * - * RFIDler with other software in compressed or archival form does not * - * trigger this provision, provided appropriate open source decompression * - * or de-archiving software is widely available for no charge. For the * - * purposes of this license, an installer is considered to include Covered * - * Software even if it actually retrieves a copy of Covered Software from * - * another source during runtime (such as by downloading it from the * - * Internet). * - * * - * o Links (statically or dynamically) to a library which does any of the * - * above. * - * * - * o Executes a helper program, module, or script to do any of the above. * - * * - * This list is not exclusive, but is meant to clarify our interpretation * - * of derived works with some common examples. Other people may interpret * - * the plain GPL differently, so we consider this a special exception to * - * the GPL that we apply to Covered Software. Works which meet any of * - * these conditions must conform to all of the terms of this license, * - * particularly including the GPL Section 3 requirements of providing * - * source code and allowing free redistribution of the work as a whole. * - * * - * As another special exception to the GPL terms, Aperture Labs Ltd. grants* - * permission to link the code of this program with any version of the * - * OpenSSL library which is distributed under a license identical to that * - * listed in the included docs/licenses/OpenSSL.txt file, and distribute * - * linked combinations including the two. * - * * - * Any redistribution of Covered Software, including any derived works, * - * must obey and carry forward all of the terms of this license, including * - * obeying all GPL rules and restrictions. For example, source code of * - * the whole work must be provided and free redistribution must be * - * allowed. All GPL references to "this License", are to be treated as * - * including the terms and conditions of this license text as well. * - * * - * Because this license imposes special exceptions to the GPL, Covered * - * Work may not be combined (even as part of a larger work) with plain GPL * - * software. The terms, conditions, and exceptions of this license must * - * be included as well. This license is incompatible with some other open * - * source licenses as well. In some cases we can relicense portions of * - * RFIDler or grant special permissions to use it in other open source * - * software. Please contact sales@aperturelabs.com with any such requests.* - * Similarly, we don't incorporate incompatible open source software into * - * Covered Software without special permission from the copyright holders. * - * * - * If you have any questions about the licensing restrictions on using * - * RFIDler in other works, are happy to help. As mentioned above, we also * - * offer alternative license to integrate RFIDler into proprietary * - * applications and appliances. These contracts have been sold to dozens * - * of software vendors, and generally include a perpetual license as well * - * as providing for priority support and updates. They also fund the * - * continued development of RFIDler. Please email sales@aperturelabs.com * - * for further information. * - * If you have received a written license agreement or contract for * - * Covered Software stating terms other than these, you may choose to use * - * and redistribute Covered Software under those terms instead of these. * - * * - * Source is provided to this software because we believe users have a * - * right to know exactly what a program is going to do before they run it. * - * This also allows you to audit the software for security holes (none * - * have been found so far). * - * * - * Source code also allows you to port RFIDler to new platforms, fix bugs, * - * and add new features. You are highly encouraged to send your changes * - * to the RFIDler mailing list for possible incorporation into the * - * main distribution. By sending these changes to Aperture Labs Ltd. or * - * one of the Aperture Labs Ltd. development mailing lists, or checking * - * them into the RFIDler source code repository, it is understood (unless * - * you specify otherwise) that you are offering the RFIDler Project * - * (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, * - * modify, and relicense the code. RFIDler will always be available Open * - * Source, but this is important because the inability to relicense code * - * has caused devastating problems for other Free Software projects (such * - * as KDE and NASM). We also occasionally relicense the code to third * - * parties as discussed above. If you wish to specify special license * - * conditions of your contributions, just say so when you send them. * - * * - * This program is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler * - * license file for more details (it's in a COPYING file included with * - * RFIDler, and also available from * - * https://github.com/ApertureLabsLtd/RFIDler/COPYING * - * * - ***************************************************************************/ - -// Author: Adam Laurie - - -#include -#include -#include "HardwareProfile.h" -#include "util.h" -#include "rfidler.h" -//#include "comms.h" - -// rtc -rtccTime RTC_time; // time structure -rtccDate RTC_date; // date structure - -// convert byte-reversed 8 digit hex to unsigned long -unsigned long hexreversetoulong(BYTE *hex) { - unsigned long ret = 0L; - unsigned int x; - BYTE i; - - if (strlen(hex) != 8) - return 0L; - - for (i = 0 ; i < 4 ; ++i) { - if (sscanf(hex, "%2X", &x) != 1) - return 0L; - ret += ((unsigned long) x) << i * 8; - hex += 2; - } - return ret; -} - -// convert byte-reversed 12 digit hex to unsigned long -unsigned long long hexreversetoulonglong(BYTE *hex) { - unsigned long long ret = 0LL; - BYTE tmp[9]; - - // this may seem an odd way to do it, but weird compiler issues were - // breaking direct conversion! - - tmp[8] = '\0'; - memset(tmp + 4, '0', 4); - memcpy(tmp, hex + 8, 4); - ret = hexreversetoulong(tmp); - ret <<= 32; - memcpy(tmp, hex, 8); - ret += hexreversetoulong(tmp); - return ret; -} - - diff --git a/tools/hitag2crack/crack4/HardwareProfile.h b/tools/hitag2crack/crack4/HardwareProfile.h deleted file mode 100644 index bce139042..000000000 --- a/tools/hitag2crack/crack4/HardwareProfile.h +++ /dev/null @@ -1,524 +0,0 @@ -/*************************************************************************** - * A copy of the GNU GPL is appended to this file. * - * * - * This licence is based on the nmap licence, and we express our gratitude * - * for the work that went into producing it. There is no other connection * - * between RFIDler and nmap either expressed or implied. * - * * - ********************** IMPORTANT RFIDler LICENSE TERMS ******************** - * * - * * - * All references to RFIDler herein imply all it's derivatives, namely: * - * * - * o RFIDler-LF Standard * - * o RFIDler-LF Lite * - * o RFIDler-LF Nekkid * - * * - * * - * RFIDler is (C) 2013-2014 Aperture Labs Ltd. * - * * - * This program is free software; you may redistribute and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE * - * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your * - * right to use, modify, and redistribute this software under certain * - * conditions. If you wish to embed RFIDler technology into proprietary * - * software or hardware, we sell alternative licenses * - * (contact sales@aperturelabs.com). * - * * - * Note that the GPL places important restrictions on "derivative works", * - * yet it does not provide a detailed definition of that term. To avoid * - * misunderstandings, we interpret that term as broadly as copyright law * - * allows. For example, we consider an application to constitute a * - * derivative work for the purpose of this license if it does any of the * - * following with any software or content covered by this license * - * ("Covered Software"): * - * * - * o Integrates source code from Covered Software. * - * * - * o Is designed specifically to execute Covered Software and parse the * - * results (as opposed to typical shell or execution-menu apps, which will * - * execute anything you tell them to). * - * * - * o Includes Covered Software in a proprietary executable installer. The * - * installers produced by InstallShield are an example of this. Including * - * RFIDler with other software in compressed or archival form does not * - * trigger this provision, provided appropriate open source decompression * - * or de-archiving software is widely available for no charge. For the * - * purposes of this license, an installer is considered to include Covered * - * Software even if it actually retrieves a copy of Covered Software from * - * another source during runtime (such as by downloading it from the * - * Internet). * - * * - * o Links (statically or dynamically) to a library which does any of the * - * above. * - * * - * o Executes a helper program, module, or script to do any of the above. * - * * - * This list is not exclusive, but is meant to clarify our interpretation * - * of derived works with some common examples. Other people may interpret * - * the plain GPL differently, so we consider this a special exception to * - * the GPL that we apply to Covered Software. Works which meet any of * - * these conditions must conform to all of the terms of this license, * - * particularly including the GPL Section 3 requirements of providing * - * source code and allowing free redistribution of the work as a whole. * - * * - * As another special exception to the GPL terms, Aperture Labs Ltd. grants* - * permission to link the code of this program with any version of the * - * OpenSSL library which is distributed under a license identical to that * - * listed in the included docs/licenses/OpenSSL.txt file, and distribute * - * linked combinations including the two. * - * * - * Any redistribution of Covered Software, including any derived works, * - * must obey and carry forward all of the terms of this license, including * - * obeying all GPL rules and restrictions. For example, source code of * - * the whole work must be provided and free redistribution must be * - * allowed. All GPL references to "this License", are to be treated as * - * including the terms and conditions of this license text as well. * - * * - * Because this license imposes special exceptions to the GPL, Covered * - * Work may not be combined (even as part of a larger work) with plain GPL * - * software. The terms, conditions, and exceptions of this license must * - * be included as well. This license is incompatible with some other open * - * source licenses as well. In some cases we can relicense portions of * - * RFIDler or grant special permissions to use it in other open source * - * software. Please contact sales@aperturelabs.com with any such requests.* - * Similarly, we don't incorporate incompatible open source software into * - * Covered Software without special permission from the copyright holders. * - * * - * If you have any questions about the licensing restrictions on using * - * RFIDler in other works, are happy to help. As mentioned above, we also * - * offer alternative license to integrate RFIDler into proprietary * - * applications and appliances. These contracts have been sold to dozens * - * of software vendors, and generally include a perpetual license as well * - * as providing for priority support and updates. They also fund the * - * continued development of RFIDler. Please email sales@aperturelabs.com * - * for further information. * - * If you have received a written license agreement or contract for * - * Covered Software stating terms other than these, you may choose to use * - * and redistribute Covered Software under those terms instead of these. * - * * - * Source is provided to this software because we believe users have a * - * right to know exactly what a program is going to do before they run it. * - * This also allows you to audit the software for security holes (none * - * have been found so far). * - * * - * Source code also allows you to port RFIDler to new platforms, fix bugs, * - * and add new features. You are highly encouraged to send your changes * - * to the RFIDler mailing list for possible incorporation into the * - * main distribution. By sending these changes to Aperture Labs Ltd. or * - * one of the Aperture Labs Ltd. development mailing lists, or checking * - * them into the RFIDler source code repository, it is understood (unless * - * you specify otherwise) that you are offering the RFIDler Project * - * (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, * - * modify, and relicense the code. RFIDler will always be available Open * - * Source, but this is important because the inability to relicense code * - * has caused devastating problems for other Free Software projects (such * - * as KDE and NASM). We also occasionally relicense the code to third * - * parties as discussed above. If you wish to specify special license * - * conditions of your contributions, just say so when you send them. * - * * - * This program is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler * - * license file for more details (it's in a COPYING file included with * - * RFIDler, and also available from * - * https://github.com/ApertureLabsLtd/RFIDler/COPYING * - * * - ***************************************************************************/ - -// Author: Adam Laurie - - - -#ifndef HARDWARE_PROFILE_UBW32_H -#define HARDWARE_PROFILE_UBW32_H - -//#include "plib.h" -typedef char BOOL; -typedef char BYTE; -typedef int rtccTime; -typedef int rtccDate; - - -#ifndef __PIC32MX__ -#define __PIC32MX__ -#endif - -#define GetSystemClock() (80000000ul) -#define GetPeripheralClock() (GetSystemClock()) -#define GetInstructionClock() (GetSystemClock()) - -//#define USE_SELF_POWER_SENSE_IO -#define tris_self_power TRISAbits.TRISA2 // Input -#define self_power 1 - -//#define USE_USB_BUS_SENSE_IO -#define tris_usb_bus_sense TRISBbits.TRISB5 // Input -#define USB_BUS_SENSE 1 - -// LEDs -#define mLED_1 LATEbits.LATE3 - -#define mLED_2 LATEbits.LATE2 -#define mLED_Comms mLED_2 - -#define mLED_3 LATEbits.LATE1 -#define mLED_Clock mLED_3 - -#define mLED_4 LATEbits.LATE0 -#define mLED_Emulate mLED_4 - -#define mLED_5 LATGbits.LATG6 -#define mLED_Read mLED_5 - -#define mLED_6 LATAbits.LATA15 -#define mLED_User mLED_6 - -#define mLED_7 LATDbits.LATD11 -#define mLED_Error mLED_7 - -// active low -#define mLED_ON 0 -#define mLED_OFF 1 - -#define mGetLED_1() mLED_1 -#define mGetLED_USB() mLED_1 -#define mGetLED_2() mLED_2 -#define mGetLED_Comms() mLED_2 -#define mGetLED_3() mLED_3 -#define mGetLED_Clock() mLED_3 -#define mGetLED_4() mLED_4 -#define mGetLED_Emulate() mLED_4 -#define mGetLED_5() mLED_5 -#define mGetLED_Read() mLED_5 -#define mGetLED_6() mLED_6 -#define mGetLED_User() mLED_6 -#define mGetLED_7() mLED_7 -#define mGetLED_Error() mLED_7 - -#define mLED_1_On() mLED_1 = mLED_ON -#define mLED_USB_On() mLED_1_On() -#define mLED_2_On() mLED_2 = mLED_ON -#define mLED_Comms_On() mLED_2_On() -#define mLED_3_On() mLED_3 = mLED_ON -#define mLED_Clock_On() mLED_3_On() -#define mLED_4_On() mLED_4 = mLED_ON -#define mLED_Emulate_On() mLED_4_On() -#define mLED_5_On() mLED_5 = mLED_ON -#define mLED_Read_On() mLED_5_On() -#define mLED_6_On() mLED_6 = mLED_ON -#define mLED_User_On() mLED_6_On() -#define mLED_7_On() mLED_7 = mLED_ON -#define mLED_Error_On() mLED_7_On() - -#define mLED_1_Off() mLED_1 = mLED_OFF -#define mLED_USB_Off() mLED_1_Off() -#define mLED_2_Off() mLED_2 = mLED_OFF -#define mLED_Comms_Off() mLED_2_Off() -#define mLED_3_Off() mLED_3 = mLED_OFF -#define mLED_Clock_Off() mLED_3_Off() -#define mLED_4_Off() mLED_4 = mLED_OFF -#define mLED_Emulate_Off() mLED_4_Off() -#define mLED_5_Off() mLED_5 = mLED_OFF -#define mLED_Read_Off() mLED_5_Off() -#define mLED_6_Off() mLED_6 = mLED_OFF -#define mLED_User_Off() mLED_6_Off() -#define mLED_7_Off() mLED_7 = mLED_OFF -#define mLED_Error_Off() mLED_7_Off() - -#define mLED_1_Toggle() mLED_1 = !mLED_1 -#define mLED_USB_Toggle() mLED_1_Toggle() -#define mLED_2_Toggle() mLED_2 = !mLED_2 -#define mLED_Comms_Toggle() mLED_2_Toggle() -#define mLED_3_Toggle() mLED_3 = !mLED_3 -#define mLED_Clock_Toggle() mLED_3_Toggle() -#define mLED_4_Toggle() mLED_4 = !mLED_4 -#define mLED_Emulate_Toggle() mLED_4_Toggle() -#define mLED_5_Toggle() mLED_5 = !mLED_5 -#define mLED_Read_Toggle( ) mLED_5_Toggle() -#define mLED_6_Toggle() mLED_6 = !mLED_6 -#define mLED_User_Toggle() mLED_6_Toggle() -#define mLED_7_Toggle() mLED_7 = !mLED_7 -#define mLED_Error_Toggle() mLED_7_Toggle() - -#define mLED_All_On() { mLED_1_On(); mLED_2_On(); mLED_3_On(); mLED_4_On(); mLED_5_On(); mLED_6_On(); mLED_7_On(); } -#define mLED_All_Off() { mLED_1_Off(); mLED_2_Off(); mLED_3_Off(); mLED_4_Off(); mLED_5_Off(); mLED_6_Off(); mLED_7_Off(); } - -// usb status lights -#define mLED_Both_Off() {mLED_USB_Off();mLED_Comms_Off();} -#define mLED_Both_On() {mLED_USB_On();mLED_Comms_On();} -#define mLED_Only_USB_On() {mLED_USB_On();mLED_Comms_Off();} -#define mLED_Only_Comms_On() {mLED_USB_Off();mLED_Comms_On();} - -/** SWITCH *********************************************************/ -#define swBootloader PORTEbits.RE7 -#define swUser PORTEbits.RE6 - -/** I/O pin definitions ********************************************/ -#define INPUT_PIN 1 -#define OUTPUT_PIN 0 - -#define TRUE 1 -#define FALSE 0 - -#define ENABLE 1 -#define DISABE 0 - -#define EVEN 0 -#define ODD 1 - -#define LOW FALSE -#define HIGH TRUE - -#define CLOCK_ON LOW -#define CLOCK_OFF HIGH - -// output coil control - select between reader/emulator circuits -#define COIL_MODE LATBbits.LATB4 -#define COIL_MODE_READER() COIL_MODE= LOW -#define COIL_MODE_EMULATOR() COIL_MODE= HIGH - -// coil for emulation -#define COIL_OUT LATGbits.LATG9 -#define COIL_OUT_HIGH() COIL_OUT=HIGH -#define COIL_OUT_LOW() COIL_OUT=LOW - -// door relay (active low) -#define DOOR_RELAY LATAbits.LATA14 -#define DOOR_RELAY_OPEN() DOOR_RELAY= HIGH -#define DOOR_RELAY_CLOSE() DOOR_RELAY= LOW - -// inductance/capacitance freq -#define IC_FREQUENCY PORTAbits.RA2 - -#define SNIFFER_COIL PORTDbits.RD12 // external reader clock detect -#define READER_ANALOGUE PORTBbits.RB11 // reader coil analogue -#define DIV_LOW_ANALOGUE PORTBbits.RB12 // voltage divider LOW analogue -#define DIV_HIGH_ANALOGUE PORTBbits.RB13 // voltage divider HIGH analogue - -// clock coil (normally controlled by OC Module, but defined here so we can force it high or low) -#define CLOCK_COIL PORTDbits.RD4 -#define CLOCK_COIL_MOVED PORTDbits.RD0 // temporary for greenwire - -// digital output after analogue reader circuit -#define READER_DATA PORTDbits.RD8 - -// trace / debug -#define DEBUG_PIN_1 LATCbits.LATC1 -#define DEBUG_PIN_1_TOGGLE() DEBUG_PIN_1= !DEBUG_PIN_1 -#define DEBUG_PIN_2 LATCbits.LATC2 -#define DEBUG_PIN_2_TOGGLE() DEBUG_PIN_2= !DEBUG_PIN_2 -#define DEBUG_PIN_3 LATCbits.LATC3 -#define DEBUG_PIN_3_TOGGLE() DEBUG_PIN_3= !DEBUG_PIN_3 -#define DEBUG_PIN_4 LATEbits.LATE5 -#define DEBUG_PIN_4_TOGGLE() DEBUG_PIN_4= !DEBUG_PIN_4 - -// spi (sdi1) for sd card (not directly referenced) -//#define SD_CARD_RX LATCbits.LATC4 -//#define SD_CARD_TX LATDbits.LATD0 -//#define SD_CARD_CLK LATDbits.LATD10 -//#define SD_CARD_SS LATDbits.LATD9 -// spi for SD card -#define SD_CARD_DET LATFbits.LATF0 -#define SD_CARD_WE LATFbits.LATF1 // write enable - unused for microsd but allocated anyway as library checks it -// (held LOW by default - cut solder bridge to GND to free pin if required) -#define SPI_SD SPI_CHANNEL1 -#define SPI_SD_BUFF SPI1BUF -#define SPI_SD_STAT SPI1STATbits -// see section below for more defines! - -// iso 7816 smartcard -// microchip SC module defines pins so we don't need to, but -// they are listed here to help avoid conflicts -#define ISO_7816_RX LATBbits.LATF2 // RX -#define ISO_7816_TX LATBbits.LATF8 // TX -#define ISO_7816_VCC LATBbits.LATB9 // Power -#define ISO_7816_CLK LATCbits.LATD1 // Clock -#define ISO_7816_RST LATEbits.LATE8 // Reset - -// user LED -#define USER_LED LATDbits.LATD7 -#define USER_LED_ON() LATDbits.LATD7=1 -#define USER_LED_OFF() LATDbits.LATD7=0 - -// LCR -#define LCR_CALIBRATE LATBbits.LATB5 - -// wiegand / clock & data -#define WIEGAND_IN_0 PORTDbits.RD5 -#define WIEGAND_IN_0_PULLUP CNPUEbits.CNPUE14 -#define WIEGAND_IN_0_PULLDOWN CNPDbits.CNPD14 -#define WIEGAND_IN_1 PORTDbits.RD6 -#define WIEGAND_IN_1_PULLUP CNPUEbits.CNPUE15 -#define WIEGAND_IN_1_PULLDOWN CNPDbits.CNPD15 -#define CAND_IN_DATA WIEGAND_IN_0 -#define CAND_IN_CLOCK WIEGAND_IN_1 - -#define WIEGAND_OUT_0 LATDbits.LATD3 -#define WIEGAND_OUT_1 LATDbits.LATD2 -#define WIEGAND_OUT_0_TRIS TRISDbits.TRISD3 -#define WIEGAND_OUT_1_TRIS TRISDbits.TRISD2 -#define CAND_OUT_DATA WIEGAND_OUT_0 -#define CAND_OUT_CLOCK WIEGAND_OUT_1 - -// connect/disconnect reader clock from coil - used to send RWD signals by creating gaps in carrier -#define READER_CLOCK_ENABLE LATEbits.LATE9 -#define READER_CLOCK_ENABLE_ON() READER_CLOCK_ENABLE=CLOCK_ON -#define READER_CLOCK_ENABLE_OFF(x) {READER_CLOCK_ENABLE=CLOCK_OFF; COIL_OUT=x;} - -// these input pins must NEVER bet set to output or they will cause short circuits! -// they can be used to see data from reader before it goes into or gate -#define OR_IN_A PORTAbits.RA4 -#define OR_IN_B PORTAbits.RA5 - - -// CNCON and CNEN are set to allow wiegand input pin weak pullups to be switched on -#define Init_GPIO() { \ - CNCONbits.ON= TRUE; \ - CNENbits.CNEN14= TRUE; \ - CNENbits.CNEN15= TRUE; \ - TRISAbits.TRISA2= INPUT_PIN; \ - TRISAbits.TRISA4= INPUT_PIN; \ - TRISAbits.TRISA5= INPUT_PIN; \ - TRISAbits.TRISA14= OUTPUT_PIN; \ - TRISAbits.TRISA15= OUTPUT_PIN; \ - TRISBbits.TRISB4= OUTPUT_PIN; \ - TRISBbits.TRISB5= OUTPUT_PIN; \ - TRISBbits.TRISB9= OUTPUT_PIN; \ - TRISBbits.TRISB11= INPUT_PIN; \ - TRISBbits.TRISB12= INPUT_PIN; \ - TRISBbits.TRISB13= INPUT_PIN; \ - TRISCbits.TRISC1= OUTPUT_PIN; \ - TRISCbits.TRISC2= OUTPUT_PIN; \ - TRISCbits.TRISC3= OUTPUT_PIN; \ - TRISCbits.TRISC4= INPUT_PIN; \ - TRISDbits.TRISD0= INPUT_PIN; \ - TRISDbits.TRISD1= OUTPUT_PIN; \ - TRISDbits.TRISD2= OUTPUT_PIN; \ - TRISDbits.TRISD3= OUTPUT_PIN; \ - TRISDbits.TRISD4= OUTPUT_PIN; \ - TRISDbits.TRISD5= INPUT_PIN; \ - TRISDbits.TRISD6= INPUT_PIN; \ - TRISDbits.TRISD7= OUTPUT_PIN; \ - TRISDbits.TRISD8= INPUT_PIN; \ - TRISDbits.TRISD11= OUTPUT_PIN; \ - TRISDbits.TRISD12= INPUT_PIN; \ - TRISEbits.TRISE0= OUTPUT_PIN; \ - TRISEbits.TRISE1= OUTPUT_PIN; \ - TRISEbits.TRISE2= OUTPUT_PIN; \ - TRISEbits.TRISE3= OUTPUT_PIN; \ - TRISEbits.TRISE5= OUTPUT_PIN; \ - TRISEbits.TRISE6= INPUT_PIN; \ - TRISEbits.TRISE7= INPUT_PIN; \ - TRISEbits.TRISE8= OUTPUT_PIN; \ - TRISEbits.TRISE9= OUTPUT_PIN; \ - TRISFbits.TRISF0= INPUT_PIN; \ - TRISFbits.TRISF1= INPUT_PIN; \ - TRISFbits.TRISF2= INPUT_PIN; \ - TRISFbits.TRISF8= OUTPUT_PIN; \ - TRISGbits.TRISG6= OUTPUT_PIN; \ - TRISGbits.TRISG12= INPUT_PIN; \ - TRISGbits.TRISG13= INPUT_PIN; \ - TRISGbits.TRISG9= OUTPUT_PIN; \ - LATBbits.LATB9= LOW; \ - LATCbits.LATC1= LOW; \ - LATCbits.LATC2= LOW; \ - LATCbits.LATC3= LOW; \ - LATDbits.LATD2= WIEGAND_IN_1; \ - LATDbits.LATD3= WIEGAND_IN_0; \ - LATEbits.LATE5= LOW; \ - LATEbits.LATE9= HIGH; \ - } - -// uart3 (CLI/API) speed -#define BAUDRATE3 115200UL -#define BRG_DIV3 4 -#define BRGH3 1 - -// spi for potentiometer -#define SPI_POT SPI_CHANNEL4 -#define SPI_POT_BUFF SPI4BUF -#define SPI_POT_STAT SPI4STATbits - -// spi for sd card - defines required for Microchip SD-SPI libs -// define interface type -#define USE_SD_INTERFACE_WITH_SPI - -#define MDD_USE_SPI_1 -#define SPI_START_CFG_1 (PRI_PRESCAL_64_1 | SEC_PRESCAL_8_1 | MASTER_ENABLE_ON | SPI_CKE_ON | SPI_SMP_ON) -#define SPI_START_CFG_2 (SPI_ENABLE) -// Define the SPI frequency -#define SPI_FREQUENCY (20000000) -// Description: SD-SPI Card Detect Input bit -#define SD_CD PORTFbits.RF0 -// Description: SD-SPI Card Detect TRIS bit -#define SD_CD_TRIS TRISFbits.TRISF0 -// Description: SD-SPI Write Protect Check Input bit -#define SD_WE PORTFbits.RF1 -// Description: SD-SPI Write Protect Check TRIS bit -#define SD_WE_TRIS TRISFbits.TRISF1 -// Description: The main SPI control register -#define SPICON1 SPI1CON -// Description: The SPI status register -#define SPISTAT SPI1STAT -// Description: The SPI Buffer -#define SPIBUF SPI1BUF -// Description: The receive buffer full bit in the SPI status register -#define SPISTAT_RBF SPI1STATbits.SPIRBF -// Description: The bitwise define for the SPI control register (i.e. _____bits) -#define SPICON1bits SPI1CONbits -// Description: The bitwise define for the SPI status register (i.e. _____bits) -#define SPISTATbits SPI1STATbits -// Description: The enable bit for the SPI module -#define SPIENABLE SPICON1bits.ON -// Description: The definition for the SPI baud rate generator register (PIC32) -#define SPIBRG SPI1BRG -// Description: The TRIS bit for the SCK pin -#define SPICLOCK TRISDbits.TRISD10 -// Description: The TRIS bit for the SDI pin -#define SPIIN TRISCbits.TRISC4 -// Description: The TRIS bit for the SDO pin -#define SPIOUT TRISDbits.TRISD0 -#define SD_CS LATDbits.LATD9 -// Description: SD-SPI Chip Select TRIS bit -#define SD_CS_TRIS TRISDbits.TRISD9 -//SPI library functions -#define putcSPI putcSPI1 -#define getcSPI getcSPI1 -#define OpenSPI(config1, config2) OpenSPI1(config1, config2) - -// Define setup parameters for OpenADC10 function -// Turn module on | Ouput in integer format | Trigger mode auto | Enable autosample -#define ADC_CONFIG1 (ADC_FORMAT_INTG | ADC_CLK_AUTO | ADC_AUTO_SAMPLING_ON) -// ADC ref external | Disable offset test | Disable scan mode | Perform 2 samples | Use dual buffers | Use alternate mode -#define ADC_CONFIG2 (ADC_VREF_AVDD_AVSS | ADC_OFFSET_CAL_DISABLE | ADC_SCAN_OFF | ADC_SAMPLES_PER_INT_1 | ADC_ALT_BUF_ON | ADC_ALT_INPUT_ON) - -// Use ADC internal clock | Set sample time -#define ADC_CONFIG3 (ADC_CONV_CLK_INTERNAL_RC | ADC_SAMPLE_TIME_0) - -// slow sample rate for tuning coils -#define ADC_CONFIG2_SLOW (ADC_VREF_AVDD_AVSS | ADC_OFFSET_CAL_DISABLE | ADC_SCAN_OFF | ADC_SAMPLES_PER_INT_16 | ADC_ALT_BUF_ON | ADC_ALT_INPUT_ON) -#define ADC_CONFIG3_SLOW (ADC_CONV_CLK_INTERNAL_RC | ADC_SAMPLE_TIME_31) - -// use AN11 -#define ADC_CONFIGPORT ENABLE_AN11_ANA -// Do not assign channels to scan -#define ADC_CONFIGSCAN SKIP_SCAN_ALL - -#define ADC_TO_VOLTS 0.003208F - - -// flash memory - int myvar = *(int*)(myflashmemoryaddress); - -// memory is 0x9D005000 to 0x9D07FFFF - -#define NVM_MEMORY_END 0x9D07FFFF -#define NVM_PAGE_SIZE 4096 -#define NVM_PAGES 2 // config & VTAG -#define RFIDLER_NVM_ADDRESS (NVM_MEMORY_END - (NVM_PAGE_SIZE * NVM_PAGES)) - -// UART timeout in us -#define SERIAL_TIMEOUT 100 - -#endif diff --git a/tools/hitag2crack/crack4/Makefile b/tools/hitag2crack/crack4/Makefile index 0c3e6ec3f..fff1dfb64 100644 --- a/tools/hitag2crack/crack4/Makefile +++ b/tools/hitag2crack/crack4/Makefile @@ -1,17 +1,19 @@ CFLAGS?=-Wall LIBS=-lpthread +VPATH=../common +INC=-I ../common -all: ht2crack4.c HardwareProfile.h rfidler.h util.h utilpart.o hitagcrypto.o ht2crack2utils.o - $(CC) $(CFLAGS) -o ht2crack4 ht2crack4.c utilpart.o hitagcrypto.o ht2crack2utils.o $(LIBS) +all: ht2crack4.c HardwareProfile.h rfidler.h util.h utilpart.o hitagcrypto.o ht2crackutils.o + $(CC) $(CFLAGS) $(INC) -o ht2crack4 $< utilpart.o hitagcrypto.o ht2crackutils.o $(LIBS) utilpart.o: utilpart.c util.h - $(CC) $(CFLAGS) -c utilpart.c + $(CC) $(CFLAGS) -c $< hitagcrypto.o: hitagcrypto.c hitagcrypto.h - $(CC) $(CFLAGS) -c hitagcrypto.c + $(CC) $(CFLAGS) -c $< -ht2crack2utils.o: ht2crack2utils.c ht2crack2utils.h - $(CC) $(CFLAGS) -c ht2crack2utils.c +ht2crackutils.o: ht2crackutils.c ht2crackutils.h + $(CC) $(CFLAGS) -c $< clean: rm -rf *.o ht2crack4 diff --git a/tools/hitag2crack/crack4/hitagcrypto.c b/tools/hitag2crack/crack4/hitagcrypto.c deleted file mode 100644 index 47449c3e3..000000000 --- a/tools/hitag2crack/crack4/hitagcrypto.c +++ /dev/null @@ -1,373 +0,0 @@ -/*************************************************************************** - * A copy of the GNU GPL is appended to this file. * - * * - * This licence is based on the nmap licence, and we express our gratitude * - * for the work that went into producing it. There is no other connection * - * between RFIDler and nmap either expressed or implied. * - * * - ********************** IMPORTANT RFIDler LICENSE TERMS ******************** - * * - * * - * All references to RFIDler herein imply all it's derivatives, namely: * - * * - * o RFIDler-LF Standard * - * o RFIDler-LF Lite * - * o RFIDler-LF Nekkid * - * * - * * - * RFIDler is (C) 2013-2015 Aperture Labs Ltd. * - * * - * This program is free software; you may redistribute and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE * - * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your * - * right to use, modify, and redistribute this software under certain * - * conditions. If you wish to embed RFIDler technology into proprietary * - * software or hardware, we sell alternative licenses * - * (contact sales@aperturelabs.com). * - * * - * Note that the GPL places important restrictions on "derivative works", * - * yet it does not provide a detailed definition of that term. To avoid * - * misunderstandings, we interpret that term as broadly as copyright law * - * allows. For example, we consider an application to constitute a * - * derivative work for the purpose of this license if it does any of the * - * following with any software or content covered by this license * - * ("Covered Software"): * - * * - * o Integrates source code from Covered Software. * - * * - * o Is designed specifically to execute Covered Software and parse the * - * results (as opposed to typical shell or execution-menu apps, which will * - * execute anything you tell them to). * - * * - * o Includes Covered Software in a proprietary executable installer. The * - * installers produced by InstallShield are an example of this. Including * - * RFIDler with other software in compressed or archival form does not * - * trigger this provision, provided appropriate open source decompression * - * or de-archiving software is widely available for no charge. For the * - * purposes of this license, an installer is considered to include Covered * - * Software even if it actually retrieves a copy of Covered Software from * - * another source during runtime (such as by downloading it from the * - * Internet). * - * * - * o Links (statically or dynamically) to a library which does any of the * - * above. * - * * - * o Executes a helper program, module, or script to do any of the above. * - * * - * This list is not exclusive, but is meant to clarify our interpretation * - * of derived works with some common examples. Other people may interpret * - * the plain GPL differently, so we consider this a special exception to * - * the GPL that we apply to Covered Software. Works which meet any of * - * these conditions must conform to all of the terms of this license, * - * particularly including the GPL Section 3 requirements of providing * - * source code and allowing free redistribution of the work as a whole. * - * * - * As another special exception to the GPL terms, Aperture Labs Ltd. grants* - * permission to link the code of this program with any version of the * - * OpenSSL library which is distributed under a license identical to that * - * listed in the included docs/licenses/OpenSSL.txt file, and distribute * - * linked combinations including the two. * - * * - * Any redistribution of Covered Software, including any derived works, * - * must obey and carry forward all of the terms of this license, including * - * obeying all GPL rules and restrictions. For example, source code of * - * the whole work must be provided and free redistribution must be * - * allowed. All GPL references to "this License", are to be treated as * - * including the terms and conditions of this license text as well. * - * * - * Because this license imposes special exceptions to the GPL, Covered * - * Work may not be combined (even as part of a larger work) with plain GPL * - * software. The terms, conditions, and exceptions of this license must * - * be included as well. This license is incompatible with some other open * - * source licenses as well. In some cases we can relicense portions of * - * RFIDler or grant special permissions to use it in other open source * - * software. Please contact sales@aperturelabs.com with any such requests.* - * Similarly, we don't incorporate incompatible open source software into * - * Covered Software without special permission from the copyright holders. * - * * - * If you have any questions about the licensing restrictions on using * - * RFIDler in other works, are happy to help. As mentioned above, we also * - * offer alternative license to integrate RFIDler into proprietary * - * applications and appliances. These contracts have been sold to dozens * - * of software vendors, and generally include a perpetual license as well * - * as providing for priority support and updates. They also fund the * - * continued development of RFIDler. Please email sales@aperturelabs.com * - * for further information. * - * If you have received a written license agreement or contract for * - * Covered Software stating terms other than these, you may choose to use * - * and redistribute Covered Software under those terms instead of these. * - * * - * Source is provided to this software because we believe users have a * - * right to know exactly what a program is going to do before they run it. * - * This also allows you to audit the software for security holes (none * - * have been found so far). * - * * - * Source code also allows you to port RFIDler to new platforms, fix bugs, * - * and add new features. You are highly encouraged to send your changes * - * to the RFIDler mailing list for possible incorporation into the * - * main distribution. By sending these changes to Aperture Labs Ltd. or * - * one of the Aperture Labs Ltd. development mailing lists, or checking * - * them into the RFIDler source code repository, it is understood (unless * - * you specify otherwise) that you are offering the RFIDler Project * - * (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, * - * modify, and relicense the code. RFIDler will always be available Open * - * Source, but this is important because the inability to relicense code * - * has caused devastating problems for other Free Software projects (such * - * as KDE and NASM). We also occasionally relicense the code to third * - * parties as discussed above. If you wish to specify special license * - * conditions of your contributions, just say so when you send them. * - * * - * This program is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler * - * license file for more details (it's in a COPYING file included with * - * RFIDler, and also available from * - * https://github.com/ApertureLabsLtd/RFIDler/COPYING * - * * - ***************************************************************************/ - -// Author: unknown. -// Modifications for RFIDler: Tony Naggs , Adam Laurie - -// uncomment this to build file as a standalone crypto test program -// #define UNIT_TEST -// also uncomment to include verbose debug prints -// #define TEST_DEBUG - -//#include -#include "HardwareProfile.h" -#include "rfidler.h" -#include "hitagcrypto.h" -#include "util.h" - -#ifdef UNIT_TEST -#include -#endif - -#if defined(UNIT_TEST) && defined(TEST_DEBUG) -// Note that printf format %I64x prints 64 bit ints in MS Visual C/C++. -// This may need changing for other compilers/platforms. -#define DEBUG_PRINTF(...) printf(__VA_ARGS__) -#else -#define DEBUG_PRINTF(...) -#endif - - -/* Brief info about NXP Hitag 1, Hitag 2, Hitag S and Hitag u (mu) - - Hitag 125kHz RFID was created by a company called Mikron (Mikron Gesellschaft - fur Integrierte Mikroelektronik Mbh), of Austria, for micropayment applications. - At about the same time, late 1980s to early 1990s, Mikron developed the - similarly featured Mifare micropayment card for 13.56MHz RFID. - (Mikron's European Patent EP 0473569 A2 was filed 23 August 1991, with a - priority date of 23 Aug 1990.) - Mikron was subsequently acquired by Philips Semiconductors in 1995. - Philips Semiconductors divsion subsequently became NXP. - - + Modulation read/write device -> transponder: 100 % ASK and binary pulse - length coding - + Modulation transponder -> read/write device: Strong ASK modulation, - selectable Manchester or Biphase coding - + Hitag S, Hitag u; anti-collision procedure - + Fast anti-collision protocol - + Hitag u; optional Cyclic Redundancy Check (CRC) - + Reader Talks First mode - + Hitag 2 & later; Transponder Talks First (TTF) mode - + Temporary switch from Transponder Talks First into Reader Talks First - (RTF) Mode - + Data rate read/write device to transponder: 5.2 kbit/s - + Data rates transponder to read/write device: 2 kbit/s, 4 kbit/s, 8 kbit/s - + 32-bit password feature - + Hitag 2, S = 32-bit Unique Identifier - + Hitag u = 48-bit Unique Identifier - + Selectable password modes for reader / tag mutual authentication - (Hitag 1 has 2 pairs of keys, later versions have 1 pair) - + Hitag 2 & Hitag S; Selectable encrypted mode, 48 bit key - - Known tag types: - - HITAG 1 2048 bits total memory - - HITAG 2 256 Bit total memory Read/Write - 8 pages of 32 bits, inc UID (32), - secret key (64), password (24), config (8) - - HITAG S 32 32 bits Unique Identifier Read Only - HITAG S 256 256 bits total memory Read/Write - HITAG S 2048 2048 bits total memory Read/Write - - HITAG u RO64 64 bits total memory Read Only - HITAG u 128 bits total memory Read/Write - HITAG u Advanced 512 bits total memory Read/Write - HITAG u Advanced+ 1760 bits total memory Read/Write - - Default 48-bit key for Hitag 2, S encryption: - "MIKRON" = O N M I K R - Key = 4F 4E 4D 49 4B 52 - -*/ - - -// We want the crypto functions to be as fast as possible, so optimize! -// The best compiler optimization in Microchip's free XC32 edition is -O1 -#pragma GCC optimize("O1") - -// private, nonlinear function to generate 1 crypto bit -static uint32_t hitag2_crypt(uint64_t x); - - -// macros to pick out 4 bits in various patterns of 1s & 2s & make a new number -#define pickbits2_2(S, A, B) ( ((S >> A) & 3) | ((S >> (B - 2)) & 0xC) ) -#define pickbits1x4(S, A, B, C, D) ( ((S >> A) & 1) | ((S >> (B - 1)) & 2) | \ - ((S >> (C - 2)) & 4) | ((S >> (D - 3)) & 8) ) -#define pickbits1_1_2(S, A, B, C) ( ((S >> A) & 1) | ((S >> (B - 1)) & 2) | \ - ((S >> (C - 2)) & 0xC) ) -#define pickbits2_1_1(S, A, B, C) ( ((S >> A) & 3) | ((S >> (B - 2)) & 4) | \ - ((S >> (C - 3)) & 8) ) -#define pickbits1_2_1(S, A, B, C) ( ((S >> A) & 1) | ((S >> (B - 1)) & 6) | \ - ((S >> (C - 3)) & 8) ) - - -static uint32_t hitag2_crypt(uint64_t x) { - const uint32_t ht2_function4a = 0x2C79; // 0010 1100 0111 1001 - const uint32_t ht2_function4b = 0x6671; // 0110 0110 0111 0001 - const uint32_t ht2_function5c = 0x7907287B; // 0111 1001 0000 0111 0010 1000 0111 1011 - uint32_t bitindex; - - bitindex = (ht2_function4a >> pickbits2_2(x, 1, 4)) & 1; - bitindex |= ((ht2_function4b << 1) >> pickbits1_1_2(x, 7, 11, 13)) & 0x02; - bitindex |= ((ht2_function4b << 2) >> pickbits1x4(x, 16, 20, 22, 25)) & 0x04; - bitindex |= ((ht2_function4b << 3) >> pickbits2_1_1(x, 27, 30, 32)) & 0x08; - bitindex |= ((ht2_function4a << 4) >> pickbits1_2_1(x, 33, 42, 45)) & 0x10; - - DEBUG_PRINTF("hitag2_crypt bitindex = %02x\n", bitindex); - return (ht2_function5c >> bitindex) & 1; -} - -/* - * Parameters: - * Hitag_State* pstate - output, internal state after initialisation - * uint64_t sharedkey - 48 bit key shared between reader & tag - * uint32_t serialnum - 32 bit tag serial number - * uint32_t initvector - 32 bit random IV from reader, part of tag authentication - */ -void hitag2_init(Hitag_State *pstate, uint64_t sharedkey, uint32_t serialnum, uint32_t initvector) { - // init state, from serial number and lowest 16 bits of shared key - uint64_t state = ((sharedkey & 0xFFFF) << 32) | serialnum; - - // mix the initialisation vector and highest 32 bits of the shared key - initvector ^= (uint32_t)(sharedkey >> 16); - - // move 16 bits from (IV xor Shared Key) to top of uint64_t state - // these will be XORed in turn with output of the crypto function - state |= (uint64_t) initvector << 48; - initvector >>= 16; - - // unrolled loop is faster on PIC32 (MIPS), do 32 times - // shift register, then calc new bit - state >>= 1; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - - // highest 16 bits of IV XOR Shared Key - state |= (uint64_t) initvector << 47; - - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state ^= (uint64_t) hitag2_crypt(state) << 47; - - DEBUG_PRINTF("hitag2_init result = %012I64x\n", state); - pstate->shiftreg = state; - /* naive version for reference, LFSR has 16 taps - pstate->lfsr = state ^ (state >> 2) ^ (state >> 3) ^ (state >> 6) - ^ (state >> 7) ^ (state >> 8) ^ (state >> 16) ^ (state >> 22) - ^ (state >> 23) ^ (state >> 26) ^ (state >> 30) ^ (state >> 41) - ^ (state >> 42) ^ (state >> 43) ^ (state >> 46) ^ (state >> 47); - */ - { - // optimise with one 64-bit intermediate - uint64_t temp = state ^ (state >> 1); - pstate->lfsr = state ^ (state >> 6) ^ (state >> 16) - ^ (state >> 26) ^ (state >> 30) ^ (state >> 41) - ^ (temp >> 2) ^ (temp >> 7) ^ (temp >> 22) - ^ (temp >> 42) ^ (temp >> 46); - } -} - - -/* - * Return up to 32 crypto bits. - * Last bit is in least significant bit, earlier bits are shifted left. - * Note that the Hitag transmission protocol is least significant bit, - * so we may want to change this, or add a function, that returns the - * crypto output bits in the other order. - * - * Parameters: - * Hitag_State* pstate - in/out, internal cipher state after initialisation - * uint32_t steps - number of bits requested, (capped at 32) - */ -uint32_t hitag2_nstep(Hitag_State *pstate, uint32_t steps) { - uint64_t state = pstate->shiftreg; - uint32_t result = 0; - uint64_t lfsr = pstate->lfsr; - - if (steps == 0) - return 0; - -// if (steps > 32) -// steps = 32; - - do { - // update shift registers - if (lfsr & 1) { - state = (state >> 1) | 0x800000000000; - lfsr = (lfsr >> 1) ^ 0xB38083220073; - - // accumulate next bit of crypto - result = (result << 1) | hitag2_crypt(state); - } else { - state >>= 1; - lfsr >>= 1; - - result = (result << 1) | hitag2_crypt(state); - } - } while (--steps); - - DEBUG_PRINTF("hitag2_nstep state = %012I64x, result %02x\n", state, result); - pstate->shiftreg = state; - pstate->lfsr = lfsr; - return result; -} - -// end of crypto core, revert to default optimization level -#pragma GCC reset_options diff --git a/tools/hitag2crack/crack4/hitagcrypto.h b/tools/hitag2crack/crack4/hitagcrypto.h deleted file mode 100644 index 274d3d82c..000000000 --- a/tools/hitag2crack/crack4/hitagcrypto.h +++ /dev/null @@ -1,167 +0,0 @@ -/*************************************************************************** - * A copy of the GNU GPL is appended to this file. * - * * - * This licence is based on the nmap licence, and we express our gratitude * - * for the work that went into producing it. There is no other connection * - * between RFIDler and nmap either expressed or implied. * - * * - ********************** IMPORTANT RFIDler LICENSE TERMS ******************** - * * - * * - * All references to RFIDler herein imply all it's derivatives, namely: * - * * - * o RFIDler-LF Standard * - * o RFIDler-LF Lite * - * o RFIDler-LF Nekkid * - * * - * * - * RFIDler is (C) 2013-2014 Aperture Labs Ltd. * - * * - * This program is free software; you may redistribute and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE * - * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your * - * right to use, modify, and redistribute this software under certain * - * conditions. If you wish to embed RFIDler technology into proprietary * - * software or hardware, we sell alternative licenses * - * (contact sales@aperturelabs.com). * - * * - * Note that the GPL places important restrictions on "derivative works", * - * yet it does not provide a detailed definition of that term. To avoid * - * misunderstandings, we interpret that term as broadly as copyright law * - * allows. For example, we consider an application to constitute a * - * derivative work for the purpose of this license if it does any of the * - * following with any software or content covered by this license * - * ("Covered Software"): * - * * - * o Integrates source code from Covered Software. * - * * - * o Is designed specifically to execute Covered Software and parse the * - * results (as opposed to typical shell or execution-menu apps, which will * - * execute anything you tell them to). * - * * - * o Includes Covered Software in a proprietary executable installer. The * - * installers produced by InstallShield are an example of this. Including * - * RFIDler with other software in compressed or archival form does not * - * trigger this provision, provided appropriate open source decompression * - * or de-archiving software is widely available for no charge. For the * - * purposes of this license, an installer is considered to include Covered * - * Software even if it actually retrieves a copy of Covered Software from * - * another source during runtime (such as by downloading it from the * - * Internet). * - * * - * o Links (statically or dynamically) to a library which does any of the * - * above. * - * * - * o Executes a helper program, module, or script to do any of the above. * - * * - * This list is not exclusive, but is meant to clarify our interpretation * - * of derived works with some common examples. Other people may interpret * - * the plain GPL differently, so we consider this a special exception to * - * the GPL that we apply to Covered Software. Works which meet any of * - * these conditions must conform to all of the terms of this license, * - * particularly including the GPL Section 3 requirements of providing * - * source code and allowing free redistribution of the work as a whole. * - * * - * As another special exception to the GPL terms, Aperture Labs Ltd. grants* - * permission to link the code of this program with any version of the * - * OpenSSL library which is distributed under a license identical to that * - * listed in the included docs/licenses/OpenSSL.txt file, and distribute * - * linked combinations including the two. * - * * - * Any redistribution of Covered Software, including any derived works, * - * must obey and carry forward all of the terms of this license, including * - * obeying all GPL rules and restrictions. For example, source code of * - * the whole work must be provided and free redistribution must be * - * allowed. All GPL references to "this License", are to be treated as * - * including the terms and conditions of this license text as well. * - * * - * Because this license imposes special exceptions to the GPL, Covered * - * Work may not be combined (even as part of a larger work) with plain GPL * - * software. The terms, conditions, and exceptions of this license must * - * be included as well. This license is incompatible with some other open * - * source licenses as well. In some cases we can relicense portions of * - * RFIDler or grant special permissions to use it in other open source * - * software. Please contact sales@aperturelabs.com with any such requests.* - * Similarly, we don't incorporate incompatible open source software into * - * Covered Software without special permission from the copyright holders. * - * * - * If you have any questions about the licensing restrictions on using * - * RFIDler in other works, are happy to help. As mentioned above, we also * - * offer alternative license to integrate RFIDler into proprietary * - * applications and appliances. These contracts have been sold to dozens * - * of software vendors, and generally include a perpetual license as well * - * as providing for priority support and updates. They also fund the * - * continued development of RFIDler. Please email sales@aperturelabs.com * - * for further information. * - * If you have received a written license agreement or contract for * - * Covered Software stating terms other than these, you may choose to use * - * and redistribute Covered Software under those terms instead of these. * - * * - * Source is provided to this software because we believe users have a * - * right to know exactly what a program is going to do before they run it. * - * This also allows you to audit the software for security holes (none * - * have been found so far). * - * * - * Source code also allows you to port RFIDler to new platforms, fix bugs, * - * and add new features. You are highly encouraged to send your changes * - * to the RFIDler mailing list for possible incorporation into the * - * main distribution. By sending these changes to Aperture Labs Ltd. or * - * one of the Aperture Labs Ltd. development mailing lists, or checking * - * them into the RFIDler source code repository, it is understood (unless * - * you specify otherwise) that you are offering the RFIDler Project * - * (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, * - * modify, and relicense the code. RFIDler will always be available Open * - * Source, but this is important because the inability to relicense code * - * has caused devastating problems for other Free Software projects (such * - * as KDE and NASM). We also occasionally relicense the code to third * - * parties as discussed above. If you wish to specify special license * - * conditions of your contributions, just say so when you send them. * - * * - * This program is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler * - * license file for more details (it's in a COPYING file included with * - * RFIDler, and also available from * - * https://github.com/ApertureLabsLtd/RFIDler/COPYING * - * * - ***************************************************************************/ - -// Author: unknown. -// Modifications for RFIDler: Tony Naggs , Adam Laurie - - -#ifndef HITAGCRYPTO_H -#define HITAGCRYPTO_H - -#include - -/* - Our model of Hitag 2 crypto uses 2 parallel shift registers: - a. 48 bit Feedback Shift Register, required for inputs to the nonlinear function. - b. 48 bit Linear Feedback Shift Register (LFSR). - A transform of initial register (a) value, which is then run in parallel. - Enables much faster calculation of the feedback values. - - API: - void hitag2_init(Hitag_State* pstate, uint64_t sharedkey, uint32_t serialnum, - uint32_t initvector); - Initialise state from 48 bit shared (secret) reader/tag key, - 32 bit tag serial number and 32 bit initialisation vector from reader. - - uint32_t hitag2_nstep(Hitag_State* pstate, uint32_t steps); - update shift register state and generate N cipher bits (N should be <= 32) - */ - - -typedef struct { - uint64_t shiftreg; // naive shift register, required for nonlinear fn input - uint64_t lfsr; // fast lfsr, used to make software faster -} Hitag_State; - -void hitag2_init(Hitag_State *pstate, uint64_t sharedkey, uint32_t serialnum, uint32_t initvector); - -uint32_t hitag2_nstep(Hitag_State *pstate, uint32_t steps); - -#endif /* HITAGCRYPTO_H */ - diff --git a/tools/hitag2crack/crack4/ht2crack2utils.c b/tools/hitag2crack/crack4/ht2crack2utils.c deleted file mode 100644 index 75d4c27a9..000000000 --- a/tools/hitag2crack/crack4/ht2crack2utils.c +++ /dev/null @@ -1,172 +0,0 @@ -#include "ht2crack2utils.h" - -// writes a value into a buffer as a series of bytes -void writebuf(unsigned char *buf, uint64_t val, unsigned int len) { - int i; - char c; - - for (i = len - 1; i >= 0; i--) { - c = val & 0xff; - buf[i] = c; - val = val >> 8; - } - -} - - -/* simple hexdump for testing purposes */ -void shexdump(unsigned char *data, int data_len) { - int i; - - if (!data || (data_len <= 0)) { - printf("shexdump: invalid parameters\n"); - return; - } - - printf("Hexdump from %p:\n", data); - - for (i = 0; i < data_len; i++) { - if ((i % HEX_PER_ROW) == 0) { - printf("\n0x%04x: ", i); - } - printf("%02x ", data[i]); - } - printf("\n\n"); -} - - - -void printbin(unsigned char *c) { - int i, j; - unsigned char x; - - if (!c) { - printf("printbin: invalid params\n"); - return; - } - - for (i = 0; i < 6; i++) { - x = c[i]; - for (j = 0; j < 8; j++) { - printf("%d", (x & 0x80) >> 7); - x = x << 1; - } - } - printf("\n"); -} - - -void printbin2(uint64_t val, unsigned int size) { - int i; - uint64_t mask = 1; - - mask = mask << (size - 1); - - for (i = 0; i < size; i++) { - if (val & mask) { - printf("1"); - } else { - printf("0"); - } - val = val << 1; - } -} - - -void printstate(Hitag_State *hstate) { - printf("shiftreg =\t"); - printbin2(hstate->shiftreg, 48); - printf("\n"); -} - - - - -// convert hex char to binary -unsigned char hex2bin(unsigned char c) { - if ((c >= '0') && (c <= '9')) { - return (c - '0'); - } else if ((c >= 'a') && (c <= 'f')) { - return (c - 'a' + 10); - } else if ((c >= 'A') && (c <= 'F')) { - return (c - 'A' + 10); - } else { - return 0; - } -} - -// return a single bit from a value -int bitn(uint64_t x, int bit) { - uint64_t bitmask = 1; - - bitmask = bitmask << bit; - - if (x & bitmask) { - return 1; - } else { - return 0; - } -} - - -// the sub-function R that rollback depends upon -int fnR(uint64_t x) { - // renumbered bits because my state is 0-47, not 1-48 - return (bitn(x, 1) ^ bitn(x, 2) ^ bitn(x, 5) ^ bitn(x, 6) ^ bitn(x, 7) ^ - bitn(x, 15) ^ bitn(x, 21) ^ bitn(x, 22) ^ bitn(x, 25) ^ bitn(x, 29) ^ bitn(x, 40) ^ - bitn(x, 41) ^ bitn(x, 42) ^ bitn(x, 45) ^ bitn(x, 46) ^ bitn(x, 47)); -} - -// the rollback function that lets us go backwards in time -void rollback(Hitag_State *hstate, unsigned int steps) { - int i; - - for (i = 0; i < steps; i++) { - hstate->shiftreg = ((hstate->shiftreg << 1) & 0xffffffffffff) | fnR(hstate->shiftreg); - } - -} - - -// the three filter sub-functions that feed fnf -int fa(unsigned int i) { - return bitn(0x2C79, i); -} - -int fb(unsigned int i) { - return bitn(0x6671, i); -} - -int fc(unsigned int i) { - return bitn(0x7907287B, i); -} - -// the filter function that generates a bit of output from the prng state -int fnf(uint64_t s) { - unsigned int x1, x2, x3, x4, x5, x6; - - x1 = (bitn(s, 2) << 0) | (bitn(s, 3) << 1) | (bitn(s, 5) << 2) | (bitn(s, 6) << 3); - x2 = (bitn(s, 8) << 0) | (bitn(s, 12) << 1) | (bitn(s, 14) << 2) | (bitn(s, 15) << 3); - x3 = (bitn(s, 17) << 0) | (bitn(s, 21) << 1) | (bitn(s, 23) << 2) | (bitn(s, 26) << 3); - x4 = (bitn(s, 28) << 0) | (bitn(s, 29) << 1) | (bitn(s, 31) << 2) | (bitn(s, 33) << 3); - x5 = (bitn(s, 34) << 0) | (bitn(s, 43) << 1) | (bitn(s, 44) << 2) | (bitn(s, 46) << 3); - - x6 = (fa(x1) << 0) | (fb(x2) << 1) | (fb(x3) << 2) | (fb(x4) << 3) | (fa(x5) << 4); - - return fc(x6); -} - -// builds the lfsr for the prng (quick calcs for hitag2_nstep()) -void buildlfsr(Hitag_State *hstate) { - uint64_t state = hstate->shiftreg; - uint64_t temp; - - temp = state ^ (state >> 1); - hstate->lfsr = state ^ (state >> 6) ^ (state >> 16) - ^ (state >> 26) ^ (state >> 30) ^ (state >> 41) - ^ (temp >> 2) ^ (temp >> 7) ^ (temp >> 22) - ^ (temp >> 42) ^ (temp >> 46); -} - - - diff --git a/tools/hitag2crack/crack4/ht2crack2utils.h b/tools/hitag2crack/crack4/ht2crack2utils.h deleted file mode 100644 index 14eea840c..000000000 --- a/tools/hitag2crack/crack4/ht2crack2utils.h +++ /dev/null @@ -1,34 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "HardwareProfile.h" -#include "rfidler.h" -#include "util.h" - -#include "hitagcrypto.h" - -#define HEX_PER_ROW 16 - - - -void writebuf(unsigned char *buf, uint64_t val, unsigned int len); -void shexdump(unsigned char *data, int data_len); -void printbin(unsigned char *c); -void printbin2(uint64_t val, unsigned int size); -void printstate(Hitag_State *hstate); -unsigned char hex2bin(unsigned char c); -int bitn(uint64_t x, int bit); -int fnR(uint64_t x); -void rollback(Hitag_State *hstate, unsigned int steps); -int fa(unsigned int i); -int fb(unsigned int i); -int fc(unsigned int i); -int fnf(uint64_t s); -void buildlfsr(Hitag_State *hstate); diff --git a/tools/hitag2crack/crack4/ht2crack4.c b/tools/hitag2crack/crack4/ht2crack4.c index 54e23d550..4c923737f 100644 --- a/tools/hitag2crack/crack4/ht2crack4.c +++ b/tools/hitag2crack/crack4/ht2crack4.c @@ -49,7 +49,7 @@ #include #include #include -#include "ht2crack2utils.h" +#include "ht2crackutils.h" /* you could have more than 32 traces, but you shouldn't really need * more than 16. You can still win with 8 if you're lucky. */ diff --git a/tools/hitag2crack/crack4/rfidler.h b/tools/hitag2crack/crack4/rfidler.h deleted file mode 100644 index 933547e6b..000000000 --- a/tools/hitag2crack/crack4/rfidler.h +++ /dev/null @@ -1,412 +0,0 @@ -/*************************************************************************** - * A copy of the GNU GPL is appended to this file. * - * * - * This licence is based on the nmap licence, and we express our gratitude * - * for the work that went into producing it. There is no other connection * - * between RFIDler and nmap either expressed or implied. * - * * - ********************** IMPORTANT RFIDler LICENSE TERMS ******************** - * * - * * - * All references to RFIDler herein imply all it's derivatives, namely: * - * * - * o RFIDler-LF Standard * - * o RFIDler-LF Lite * - * o RFIDler-LF Nekkid * - * * - * * - * RFIDler is (C) 2013-2015 Aperture Labs Ltd. * - * * - * This program is free software; you may redistribute and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE * - * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your * - * right to use, modify, and redistribute this software under certain * - * conditions. If you wish to embed RFIDler technology into proprietary * - * software or hardware, we sell alternative licenses * - * (contact sales@aperturelabs.com). * - * * - * Note that the GPL places important restrictions on "derivative works", * - * yet it does not provide a detailed definition of that term. To avoid * - * misunderstandings, we interpret that term as broadly as copyright law * - * allows. For example, we consider an application to constitute a * - * derivative work for the purpose of this license if it does any of the * - * following with any software or content covered by this license * - * ("Covered Software"): * - * * - * o Integrates source code from Covered Software. * - * * - * o Is designed specifically to execute Covered Software and parse the * - * results (as opposed to typical shell or execution-menu apps, which will * - * execute anything you tell them to). * - * * - * o Includes Covered Software in a proprietary executable installer. The * - * installers produced by InstallShield are an example of this. Including * - * RFIDler with other software in compressed or archival form does not * - * trigger this provision, provided appropriate open source decompression * - * or de-archiving software is widely available for no charge. For the * - * purposes of this license, an installer is considered to include Covered * - * Software even if it actually retrieves a copy of Covered Software from * - * another source during runtime (such as by downloading it from the * - * Internet). * - * * - * o Links (statically or dynamically) to a library which does any of the * - * above. * - * * - * o Executes a helper program, module, or script to do any of the above. * - * * - * This list is not exclusive, but is meant to clarify our interpretation * - * of derived works with some common examples. Other people may interpret * - * the plain GPL differently, so we consider this a special exception to * - * the GPL that we apply to Covered Software. Works which meet any of * - * these conditions must conform to all of the terms of this license, * - * particularly including the GPL Section 3 requirements of providing * - * source code and allowing free redistribution of the work as a whole. * - * * - * As another special exception to the GPL terms, Aperture Labs Ltd. grants* - * permission to link the code of this program with any version of the * - * OpenSSL library which is distributed under a license identical to that * - * listed in the included docs/licenses/OpenSSL.txt file, and distribute * - * linked combinations including the two. * - * * - * Any redistribution of Covered Software, including any derived works, * - * must obey and carry forward all of the terms of this license, including * - * obeying all GPL rules and restrictions. For example, source code of * - * the whole work must be provided and free redistribution must be * - * allowed. All GPL references to "this License", are to be treated as * - * including the terms and conditions of this license text as well. * - * * - * Because this license imposes special exceptions to the GPL, Covered * - * Work may not be combined (even as part of a larger work) with plain GPL * - * software. The terms, conditions, and exceptions of this license must * - * be included as well. This license is incompatible with some other open * - * source licenses as well. In some cases we can relicense portions of * - * RFIDler or grant special permissions to use it in other open source * - * software. Please contact sales@aperturelabs.com with any such requests.* - * Similarly, we don't incorporate incompatible open source software into * - * Covered Software without special permission from the copyright holders. * - * * - * If you have any questions about the licensing restrictions on using * - * RFIDler in other works, are happy to help. As mentioned above, we also * - * offer alternative license to integrate RFIDler into proprietary * - * applications and appliances. These contracts have been sold to dozens * - * of software vendors, and generally include a perpetual license as well * - * as providing for priority support and updates. They also fund the * - * continued development of RFIDler. Please email sales@aperturelabs.com * - * for further information. * - * If you have received a written license agreement or contract for * - * Covered Software stating terms other than these, you may choose to use * - * and redistribute Covered Software under those terms instead of these. * - * * - * Source is provided to this software because we believe users have a * - * right to know exactly what a program is going to do before they run it. * - * This also allows you to audit the software for security holes (none * - * have been found so far). * - * * - * Source code also allows you to port RFIDler to new platforms, fix bugs, * - * and add new features. You are highly encouraged to send your changes * - * to the RFIDler mailing list for possible incorporation into the * - * main distribution. By sending these changes to Aperture Labs Ltd. or * - * one of the Aperture Labs Ltd. development mailing lists, or checking * - * them into the RFIDler source code repository, it is understood (unless * - * you specify otherwise) that you are offering the RFIDler Project * - * (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, * - * modify, and relicense the code. RFIDler will always be available Open * - * Source, but this is important because the inability to relicense code * - * has caused devastating problems for other Free Software projects (such * - * as KDE and NASM). We also occasionally relicense the code to third * - * parties as discussed above. If you wish to specify special license * - * conditions of your contributions, just say so when you send them. * - * * - * This program is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler * - * license file for more details (it's in a COPYING file included with * - * RFIDler, and also available from * - * https://github.com/ApertureLabsLtd/RFIDler/COPYING * - * * - ***************************************************************************/ - -// Author: Adam Laurie - -#include -#include - -// BCD hardware revision for usb descriptor (usb_descriptors.c) -#define RFIDLER_HW_VERSION 0x020 - -// max sizes in BITS -#define MAXBLOCKSIZE 512 -#define MAXTAGSIZE 4096 -#define MAXUID 512 - -#define TMP_LARGE_BUFF_LEN 2048 -#define TMP_SMALL_BUFF_LEN 256 -#define ANALOGUE_BUFF_LEN 8192 - -#define COMMS_BUFFER_SIZE 128 - -#define DETECT_BUFFER_SIZE 512 - -#define SAMPLEMASK ~(BIT_1 | BIT_0) // mask to remove two bottom bits from analogue sample - we will then use those for reader & bit period - -// globals - -extern BOOL WiegandOutput; // Output wiegand data whenenver UID is read -extern BYTE *EMU_Reset_Data; // Pointer to full array of bits as bytes, stored as 0x00/0x01, '*' terminated -extern BYTE *EMU_Data; // Pointer to current location in EMU_Reset_Data -extern BYTE EMU_ThisBit; // The next data bit to transmit -extern BYTE EMU_SubCarrier_T0; // Number of Frame Clocks for sub-carrier '0' -extern BYTE EMU_SubCarrier_T1; // Number of Frame Clocks for sub-carrier '1' -extern unsigned int EMU_Repeat; // Number of times to transmit full data set -extern BOOL EMU_Background; // Emulate in the background until told to stop -extern unsigned int EMU_DataBitRate; // Number of Frame Clocks per bit -extern BYTE TmpBits[TMP_LARGE_BUFF_LEN]; // Shared scratchpad -extern BYTE ReaderPeriod; // Flag for sample display -extern unsigned char Comms_In_Buffer[COMMS_BUFFER_SIZE]; // USB/Serial buffer -extern BYTE Interface; // user interface - CLI or API -extern BYTE CommsChannel; // user comms channel - USB or UART -extern BOOL FakeRead; // flag for analogue sampler to signal it wants access to buffers during read -extern BOOL PWD_Mode; // is this tag password protected? -extern BYTE Password[9]; // 32 bits as HEX string set with LOGIN -extern unsigned int Led_Count; // LED status counter, also used for entropy -extern unsigned long Reader_Bit_Count; // Reader ISR bit counter -extern char Previous; // Reader ISR previous bit type - -// RWD (read/write device) coil state -extern BYTE RWD_State; // current state of RWD coil -extern unsigned int RWD_Fc; // field clock in uS -extern unsigned int RWD_Gap_Period; // length of command gaps in OC5 ticks -extern unsigned int RWD_Zero_Period; // length of '0' in OC5 ticks -extern unsigned int RWD_One_Period; // length of '1' in OC5 ticks -extern unsigned int RWD_Sleep_Period; // length of initial sleep to reset tag in OC5 ticks -extern unsigned int RWD_Wake_Period; // length required for tag to restart in OC5 ticks -extern unsigned int RWD_Wait_Switch_TX_RX; // length to wait when switching from TX to RX in OC5 ticks -extern unsigned int RWD_Wait_Switch_RX_TX; // length to wait when switching from RX to TX in OC5 ticks -extern unsigned int RWD_Post_Wait; // low level ISR wait period in OC5 ticks -extern unsigned int RWD_OC5_config; // Output Compare Module settings -extern unsigned int RWD_OC5_r; // Output Compare Module primary compare value -extern unsigned int RWD_OC5_rs; // Output Compare Module secondary compare value -extern BYTE RWD_Command_Buff[TMP_SMALL_BUFF_LEN]; // Command buffer, array of bits as bytes, stored as 0x00/0x01, '*' terminated -extern BYTE *RWD_Command_ThisBit; // Current command bit -extern BOOL Reader_ISR_State; // current state of reader ISR - -// NVM variables -// timings etc. that want to survive a reboot should go here -typedef struct { - BYTE Name[7]; // will be set to "RFIDler" so we can test for new device - BYTE AutoRun[128]; // optional command to run at startup - unsigned char TagType; - unsigned int PSK_Quality; - unsigned int Timeout; - unsigned int Wiegand_Pulse; - unsigned int Wiegand_Gap; - BOOL Wiegand_IdleState; - unsigned int FrameClock; - unsigned char Modulation; - unsigned int DataRate; - unsigned int DataRateSub0; - unsigned int DataRateSub1; - unsigned int DataBits; - unsigned int DataBlocks; - unsigned int BlockSize; - unsigned char SyncBits; - BYTE Sync[4]; - BOOL BiPhase; - BOOL Invert; - BOOL Manchester; - BOOL HalfDuplex; - unsigned int Repeat; - unsigned int PotLow; - unsigned int PotHigh; - unsigned int RWD_Gap_Period; - unsigned int RWD_Zero_Period; - unsigned int RWD_One_Period; - unsigned int RWD_Sleep_Period; - unsigned int RWD_Wake_Period; - unsigned int RWD_Wait_Switch_TX_RX; - unsigned int RWD_Wait_Switch_RX_TX; -} StoredConfig; - -// somewhere to store TAG data. this will be interpreted according to the TAG -// type. -typedef struct { - BYTE TagType; // raw tag type - BYTE EmulatedTagType; // tag type this tag is configured to emulate - BYTE UID[MAXUID + 1]; // Null-terminated HEX string - BYTE Data[MAXTAGSIZE]; // raw data - unsigned char DataBlocks; // number of blocks in Data field - unsigned int BlockSize; // blocksize in bits -} VirtualTag; - -extern StoredConfig RFIDlerConfig; -extern VirtualTag RFIDlerVTag; -extern BYTE TmpBuff[NVM_PAGE_SIZE]; -extern BYTE DataBuff[ANALOGUE_BUFF_LEN]; -extern unsigned int DataBuffCount; -extern const BYTE *ModulationSchemes[]; -extern const BYTE *OnOff[]; -extern const BYTE *HighLow[]; -extern const BYTE *TagTypes[]; - -// globals for ISRs -extern BYTE EmulationMode; -extern unsigned long HW_Bits; -extern BYTE HW_Skip_Bits; -extern unsigned int PSK_Min_Pulse; -extern BOOL PSK_Read_Error; -extern BOOL Manchester_Error; -extern BOOL SnifferMode; -extern unsigned int Clock_Tick_Counter; -extern BOOL Clock_Tick_Counter_Reset; - -// smart card lib -#define MAX_ATR_LEN (BYTE)33 -extern BYTE scCardATR[MAX_ATR_LEN]; -extern BYTE scATRLength; - -// RTC -extern rtccTime RTC_time; // time structure -extern rtccDate RTC_date; // date structure - -// digital pots -#define POTLOW_DEFAULT 100 -#define POTHIGH_DEFAULT 150 -#define DC_OFFSET 60 // analogue circuit DC offset (as close as we can get without using 2 LSB) -#define VOLTS_TO_POT 0.019607843F - -// RWD/clock states -#define RWD_STATE_INACTIVE 0 // RWD not in use -#define RWD_STATE_GO_TO_SLEEP 1 // RWD coil shutdown request -#define RWD_STATE_SLEEPING 2 // RWD coil shutdown for sleep period -#define RWD_STATE_WAKING 3 // RWD active for pre-determined period after reset -#define RWD_STATE_START_SEND 4 // RWD starting send of data -#define RWD_STATE_SENDING_GAP 5 // RWD sending a gap -#define RWD_STATE_SENDING_BIT 6 // RWD sending a data bit -#define RWD_STATE_POST_WAIT 7 // RWD finished sending data, now in forced wait period -#define RWD_STATE_ACTIVE 8 // RWD finished, now just clocking a carrier - -// reader ISR states -#define READER_STOPPED 0 // reader not in use -#define READER_IDLING 1 // reader ISR running to preserve timing, but not reading -#define READER_RUNNING 2 // reader reading bits - - -// user interface types -#define INTERFACE_API 0 -#define INTERFACE_CLI 1 - -// comms channel -#define COMMS_NONE 0 -#define COMMS_USB 1 -#define COMMS_UART 2 - -#define MAX_HISTORY 2 // disable most of history for now - memory issue - -// tag write retries -#define TAG_WRITE_RETRY 5 - -// modulation modes - uppdate ModulationSchemes[] in tags.c if you change this -#define MOD_MODE_NONE 0 -#define MOD_MODE_ASK_OOK 1 -#define MOD_MODE_FSK1 2 -#define MOD_MODE_FSK2 3 -#define MOD_MODE_PSK1 4 -#define MOD_MODE_PSK2 5 -#define MOD_MODE_PSK3 6 - -// TAG types - update TagTypes[] in tags.c if you add to this list -#define TAG_TYPE_NONE 0 -#define TAG_TYPE_ASK_RAW 1 -#define TAG_TYPE_FSK1_RAW 2 -#define TAG_TYPE_FSK2_RAW 3 -#define TAG_TYPE_PSK1_RAW 4 -#define TAG_TYPE_PSK2_RAW 5 -#define TAG_TYPE_PSK3_RAW 6 -#define TAG_TYPE_HITAG1 7 -#define TAG_TYPE_HITAG2 8 -#define TAG_TYPE_EM4X02 9 -#define TAG_TYPE_Q5 10 -#define TAG_TYPE_HID_26 11 -#define TAG_TYPE_INDALA_64 12 -#define TAG_TYPE_INDALA_224 13 -#define TAG_TYPE_UNIQUE 14 -#define TAG_TYPE_FDXB 15 -#define TAG_TYPE_T55X7 16 // same as Q5 but different timings and no modulation-defeat -#define TAG_TYPE_AWID_26 17 -#define TAG_TYPE_EM4X05 18 -#define TAG_TYPE_TAMAGOTCHI 19 -#define TAG_TYPE_HDX 20 // same underlying data as FDX-B, but different modulation & telegram - -// various - -#define BINARY 0 -#define HEX 1 - -#define NO_ADDRESS -1 - -#define ACK TRUE -#define NO_ACK FALSE - -#define BLOCK TRUE -#define NO_BLOCK FALSE - -#define DATA TRUE -#define NO_DATA FALSE - -#define DEBUG_PIN_ON HIGH -#define DEBUG_PIN_OFF LOW - -#define FAST FALSE -#define SLOW TRUE - -#define NO_TRIGGER 0 - -#define LOCK TRUE -#define NO_LOCK FALSE - -#define NFC_MODE TRUE -#define NO_NFC_MODE FALSE - -#define ONESHOT_READ TRUE -#define NO_ONESHOT_READ FALSE - -#define RESET TRUE -#define NO_RESET FALSE - -#define SHUTDOWN_CLOCK TRUE -#define NO_SHUTDOWN_CLOCK FALSE - -#define SYNC TRUE -#define NO_SYNC FALSE - -#define VERIFY TRUE -#define NO_VERIFY FALSE - -#define VOLATILE FALSE -#define NON_VOLATILE TRUE - -#define NEWLINE TRUE -#define NO_NEWLINE FALSE - -#define WAIT TRUE -#define NO_WAIT FALSE - -#define WIPER_HIGH 0 -#define WIPER_LOW 1 - -// conversion for time to ticks -#define US_TO_TICKS 1000000L -#define US_OVER_10_TO_TICKS 10000000L -#define US_OVER_100_TO_TICKS 100000000L -// we can't get down to this level on pic, but we want to standardise on timings, so for now we fudge it -#define CONVERT_TO_TICKS(x) ((x / 10) * (GetSystemClock() / US_OVER_10_TO_TICKS)) -#define CONVERT_TICKS_TO_US(x) (x / (GetSystemClock() / US_TO_TICKS)) -#define TIMER5_PRESCALER 16 -#define MAX_TIMER5_TICKS (65535 * TIMER5_PRESCALER) - -// other conversions - -// bits to hex digits -#define HEXDIGITS(x) (x / 4) -#define HEXTOBITS(x) (x * 4) diff --git a/tools/hitag2crack/crack4/util.h b/tools/hitag2crack/crack4/util.h deleted file mode 100644 index c2399c37c..000000000 --- a/tools/hitag2crack/crack4/util.h +++ /dev/null @@ -1,147 +0,0 @@ -/*************************************************************************** - * A copy of the GNU GPL is appended to this file. * - * * - * This licence is based on the nmap licence, and we express our gratitude * - * for the work that went into producing it. There is no other connection * - * between RFIDler and nmap either expressed or implied. * - * * - ********************** IMPORTANT RFIDler LICENSE TERMS ******************** - * * - * * - * All references to RFIDler herein imply all it's derivatives, namely: * - * * - * o RFIDler-LF Standard * - * o RFIDler-LF Lite * - * o RFIDler-LF Nekkid * - * * - * * - * RFIDler is (C) 2013-2015 Aperture Labs Ltd. * - * * - * This program is free software; you may redistribute and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE * - * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your * - * right to use, modify, and redistribute this software under certain * - * conditions. If you wish to embed RFIDler technology into proprietary * - * software or hardware, we sell alternative licenses * - * (contact sales@aperturelabs.com). * - * * - * Note that the GPL places important restrictions on "derivative works", * - * yet it does not provide a detailed definition of that term. To avoid * - * misunderstandings, we interpret that term as broadly as copyright law * - * allows. For example, we consider an application to constitute a * - * derivative work for the purpose of this license if it does any of the * - * following with any software or content covered by this license * - * ("Covered Software"): * - * * - * o Integrates source code from Covered Software. * - * * - * o Is designed specifically to execute Covered Software and parse the * - * results (as opposed to typical shell or execution-menu apps, which will * - * execute anything you tell them to). * - * * - * o Includes Covered Software in a proprietary executable installer. The * - * installers produced by InstallShield are an example of this. Including * - * RFIDler with other software in compressed or archival form does not * - * trigger this provision, provided appropriate open source decompression * - * or de-archiving software is widely available for no charge. For the * - * purposes of this license, an installer is considered to include Covered * - * Software even if it actually retrieves a copy of Covered Software from * - * another source during runtime (such as by downloading it from the * - * Internet). * - * * - * o Links (statically or dynamically) to a library which does any of the * - * above. * - * * - * o Executes a helper program, module, or script to do any of the above. * - * * - * This list is not exclusive, but is meant to clarify our interpretation * - * of derived works with some common examples. Other people may interpret * - * the plain GPL differently, so we consider this a special exception to * - * the GPL that we apply to Covered Software. Works which meet any of * - * these conditions must conform to all of the terms of this license, * - * particularly including the GPL Section 3 requirements of providing * - * source code and allowing free redistribution of the work as a whole. * - * * - * As another special exception to the GPL terms, Aperture Labs Ltd. grants* - * permission to link the code of this program with any version of the * - * OpenSSL library which is distributed under a license identical to that * - * listed in the included docs/licenses/OpenSSL.txt file, and distribute * - * linked combinations including the two. * - * * - * Any redistribution of Covered Software, including any derived works, * - * must obey and carry forward all of the terms of this license, including * - * obeying all GPL rules and restrictions. For example, source code of * - * the whole work must be provided and free redistribution must be * - * allowed. All GPL references to "this License", are to be treated as * - * including the terms and conditions of this license text as well. * - * * - * Because this license imposes special exceptions to the GPL, Covered * - * Work may not be combined (even as part of a larger work) with plain GPL * - * software. The terms, conditions, and exceptions of this license must * - * be included as well. This license is incompatible with some other open * - * source licenses as well. In some cases we can relicense portions of * - * RFIDler or grant special permissions to use it in other open source * - * software. Please contact sales@aperturelabs.com with any such requests.* - * Similarly, we don't incorporate incompatible open source software into * - * Covered Software without special permission from the copyright holders. * - * * - * If you have any questions about the licensing restrictions on using * - * RFIDler in other works, are happy to help. As mentioned above, we also * - * offer alternative license to integrate RFIDler into proprietary * - * applications and appliances. These contracts have been sold to dozens * - * of software vendors, and generally include a perpetual license as well * - * as providing for priority support and updates. They also fund the * - * continued development of RFIDler. Please email sales@aperturelabs.com * - * for further information. * - * If you have received a written license agreement or contract for * - * Covered Software stating terms other than these, you may choose to use * - * and redistribute Covered Software under those terms instead of these. * - * * - * Source is provided to this software because we believe users have a * - * right to know exactly what a program is going to do before they run it. * - * This also allows you to audit the software for security holes (none * - * have been found so far). * - * * - * Source code also allows you to port RFIDler to new platforms, fix bugs, * - * and add new features. You are highly encouraged to send your changes * - * to the RFIDler mailing list for possible incorporation into the * - * main distribution. By sending these changes to Aperture Labs Ltd. or * - * one of the Aperture Labs Ltd. development mailing lists, or checking * - * them into the RFIDler source code repository, it is understood (unless * - * you specify otherwise) that you are offering the RFIDler Project * - * (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, * - * modify, and relicense the code. RFIDler will always be available Open * - * Source, but this is important because the inability to relicense code * - * has caused devastating problems for other Free Software projects (such * - * as KDE and NASM). We also occasionally relicense the code to third * - * parties as discussed above. If you wish to specify special license * - * conditions of your contributions, just say so when you send them. * - * * - * This program is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler * - * license file for more details (it's in a COPYING file included with * - * RFIDler, and also available from * - * https://github.com/ApertureLabsLtd/RFIDler/COPYING * - * * - ***************************************************************************/ - -// Author: Adam Laurie - -/* - * Hitag Crypto support macros - * These macros reverse the bit order in a byte, or *within* each byte of a - * 16 , 32 or 64 bit unsigned integer. (Not across the whole 16 etc bits.) - */ -#define rev8(X) ((((X) >> 7) &1) + (((X) >> 5) &2) + (((X) >> 3) &4) \ - + (((X) >> 1) &8) + (((X) << 1) &16) + (((X) << 3) &32) \ - + (((X) << 5) &64) + (((X) << 7) &128) ) -#define rev16(X) (rev8 (X) + (rev8 (X >> 8) << 8)) -#define rev32(X) (rev16(X) + (rev16(X >> 16) << 16)) -#define rev64(X) (rev32(X) + (rev32(X >> 32) << 32)) - - -unsigned long hexreversetoulong(BYTE *hex); -unsigned long long hexreversetoulonglong(BYTE *hex); - diff --git a/tools/hitag2crack/crack4/utilpart.c b/tools/hitag2crack/crack4/utilpart.c deleted file mode 100644 index c46148491..000000000 --- a/tools/hitag2crack/crack4/utilpart.c +++ /dev/null @@ -1,180 +0,0 @@ -/*************************************************************************** - * A copy of the GNU GPL is appended to this file. * - * * - * This licence is based on the nmap licence, and we express our gratitude * - * for the work that went into producing it. There is no other connection * - * between RFIDler and nmap either expressed or implied. * - * * - ********************** IMPORTANT RFIDler LICENSE TERMS ******************** - * * - * * - * All references to RFIDler herein imply all it's derivatives, namely: * - * * - * o RFIDler-LF Standard * - * o RFIDler-LF Lite * - * o RFIDler-LF Nekkid * - * * - * * - * RFIDler is (C) 2013-2014 Aperture Labs Ltd. * - * * - * This program is free software; you may redistribute and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE * - * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your * - * right to use, modify, and redistribute this software under certain * - * conditions. If you wish to embed RFIDler technology into proprietary * - * software or hardware, we sell alternative licenses * - * (contact sales@aperturelabs.com). * - * * - * Note that the GPL places important restrictions on "derivative works", * - * yet it does not provide a detailed definition of that term. To avoid * - * misunderstandings, we interpret that term as broadly as copyright law * - * allows. For example, we consider an application to constitute a * - * derivative work for the purpose of this license if it does any of the * - * following with any software or content covered by this license * - * ("Covered Software"): * - * * - * o Integrates source code from Covered Software. * - * * - * o Is designed specifically to execute Covered Software and parse the * - * results (as opposed to typical shell or execution-menu apps, which will * - * execute anything you tell them to). * - * * - * o Includes Covered Software in a proprietary executable installer. The * - * installers produced by InstallShield are an example of this. Including * - * RFIDler with other software in compressed or archival form does not * - * trigger this provision, provided appropriate open source decompression * - * or de-archiving software is widely available for no charge. For the * - * purposes of this license, an installer is considered to include Covered * - * Software even if it actually retrieves a copy of Covered Software from * - * another source during runtime (such as by downloading it from the * - * Internet). * - * * - * o Links (statically or dynamically) to a library which does any of the * - * above. * - * * - * o Executes a helper program, module, or script to do any of the above. * - * * - * This list is not exclusive, but is meant to clarify our interpretation * - * of derived works with some common examples. Other people may interpret * - * the plain GPL differently, so we consider this a special exception to * - * the GPL that we apply to Covered Software. Works which meet any of * - * these conditions must conform to all of the terms of this license, * - * particularly including the GPL Section 3 requirements of providing * - * source code and allowing free redistribution of the work as a whole. * - * * - * As another special exception to the GPL terms, Aperture Labs Ltd. grants* - * permission to link the code of this program with any version of the * - * OpenSSL library which is distributed under a license identical to that * - * listed in the included docs/licenses/OpenSSL.txt file, and distribute * - * linked combinations including the two. * - * * - * Any redistribution of Covered Software, including any derived works, * - * must obey and carry forward all of the terms of this license, including * - * obeying all GPL rules and restrictions. For example, source code of * - * the whole work must be provided and free redistribution must be * - * allowed. All GPL references to "this License", are to be treated as * - * including the terms and conditions of this license text as well. * - * * - * Because this license imposes special exceptions to the GPL, Covered * - * Work may not be combined (even as part of a larger work) with plain GPL * - * software. The terms, conditions, and exceptions of this license must * - * be included as well. This license is incompatible with some other open * - * source licenses as well. In some cases we can relicense portions of * - * RFIDler or grant special permissions to use it in other open source * - * software. Please contact sales@aperturelabs.com with any such requests.* - * Similarly, we don't incorporate incompatible open source software into * - * Covered Software without special permission from the copyright holders. * - * * - * If you have any questions about the licensing restrictions on using * - * RFIDler in other works, are happy to help. As mentioned above, we also * - * offer alternative license to integrate RFIDler into proprietary * - * applications and appliances. These contracts have been sold to dozens * - * of software vendors, and generally include a perpetual license as well * - * as providing for priority support and updates. They also fund the * - * continued development of RFIDler. Please email sales@aperturelabs.com * - * for further information. * - * If you have received a written license agreement or contract for * - * Covered Software stating terms other than these, you may choose to use * - * and redistribute Covered Software under those terms instead of these. * - * * - * Source is provided to this software because we believe users have a * - * right to know exactly what a program is going to do before they run it. * - * This also allows you to audit the software for security holes (none * - * have been found so far). * - * * - * Source code also allows you to port RFIDler to new platforms, fix bugs, * - * and add new features. You are highly encouraged to send your changes * - * to the RFIDler mailing list for possible incorporation into the * - * main distribution. By sending these changes to Aperture Labs Ltd. or * - * one of the Aperture Labs Ltd. development mailing lists, or checking * - * them into the RFIDler source code repository, it is understood (unless * - * you specify otherwise) that you are offering the RFIDler Project * - * (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, * - * modify, and relicense the code. RFIDler will always be available Open * - * Source, but this is important because the inability to relicense code * - * has caused devastating problems for other Free Software projects (such * - * as KDE and NASM). We also occasionally relicense the code to third * - * parties as discussed above. If you wish to specify special license * - * conditions of your contributions, just say so when you send them. * - * * - * This program is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler * - * license file for more details (it's in a COPYING file included with * - * RFIDler, and also available from * - * https://github.com/ApertureLabsLtd/RFIDler/COPYING * - * * - ***************************************************************************/ - -// Author: Adam Laurie - - -#include -#include -#include "HardwareProfile.h" -#include "util.h" -#include "rfidler.h" -//#include "comms.h" - -// rtc -rtccTime RTC_time; // time structure -rtccDate RTC_date; // date structure - -// convert byte-reversed 8 digit hex to unsigned long -unsigned long hexreversetoulong(BYTE *hex) { - unsigned long ret = 0L; - unsigned int x; - BYTE i; - - if (strlen(hex) != 8) - return 0L; - - for (i = 0 ; i < 4 ; ++i) { - if (sscanf(hex, "%2X", &x) != 1) - return 0L; - ret += ((unsigned long) x) << i * 8; - hex += 2; - } - return ret; -} - -// convert byte-reversed 12 digit hex to unsigned long -unsigned long long hexreversetoulonglong(BYTE *hex) { - unsigned long long ret = 0LL; - BYTE tmp[9]; - - // this may seem an odd way to do it, but weird compiler issues were - // breaking direct conversion! - - tmp[8] = '\0'; - memset(tmp + 4, '0', 4); - memcpy(tmp, hex + 8, 4); - ret = hexreversetoulong(tmp); - ret <<= 32; - memcpy(tmp, hex, 8); - ret += hexreversetoulong(tmp); - return ret; -} - - diff --git a/tools/hitag2crack/crack5/.gitignore b/tools/hitag2crack/crack5/.gitignore new file mode 100644 index 000000000..0e7066a3d --- /dev/null +++ b/tools/hitag2crack/crack5/.gitignore @@ -0,0 +1,3 @@ +ht2crack5 + +ht2crack5.exe diff --git a/tools/hitag2crack/crack5/HardwareProfile.h b/tools/hitag2crack/crack5/HardwareProfile.h deleted file mode 100644 index bce139042..000000000 --- a/tools/hitag2crack/crack5/HardwareProfile.h +++ /dev/null @@ -1,524 +0,0 @@ -/*************************************************************************** - * A copy of the GNU GPL is appended to this file. * - * * - * This licence is based on the nmap licence, and we express our gratitude * - * for the work that went into producing it. There is no other connection * - * between RFIDler and nmap either expressed or implied. * - * * - ********************** IMPORTANT RFIDler LICENSE TERMS ******************** - * * - * * - * All references to RFIDler herein imply all it's derivatives, namely: * - * * - * o RFIDler-LF Standard * - * o RFIDler-LF Lite * - * o RFIDler-LF Nekkid * - * * - * * - * RFIDler is (C) 2013-2014 Aperture Labs Ltd. * - * * - * This program is free software; you may redistribute and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE * - * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your * - * right to use, modify, and redistribute this software under certain * - * conditions. If you wish to embed RFIDler technology into proprietary * - * software or hardware, we sell alternative licenses * - * (contact sales@aperturelabs.com). * - * * - * Note that the GPL places important restrictions on "derivative works", * - * yet it does not provide a detailed definition of that term. To avoid * - * misunderstandings, we interpret that term as broadly as copyright law * - * allows. For example, we consider an application to constitute a * - * derivative work for the purpose of this license if it does any of the * - * following with any software or content covered by this license * - * ("Covered Software"): * - * * - * o Integrates source code from Covered Software. * - * * - * o Is designed specifically to execute Covered Software and parse the * - * results (as opposed to typical shell or execution-menu apps, which will * - * execute anything you tell them to). * - * * - * o Includes Covered Software in a proprietary executable installer. The * - * installers produced by InstallShield are an example of this. Including * - * RFIDler with other software in compressed or archival form does not * - * trigger this provision, provided appropriate open source decompression * - * or de-archiving software is widely available for no charge. For the * - * purposes of this license, an installer is considered to include Covered * - * Software even if it actually retrieves a copy of Covered Software from * - * another source during runtime (such as by downloading it from the * - * Internet). * - * * - * o Links (statically or dynamically) to a library which does any of the * - * above. * - * * - * o Executes a helper program, module, or script to do any of the above. * - * * - * This list is not exclusive, but is meant to clarify our interpretation * - * of derived works with some common examples. Other people may interpret * - * the plain GPL differently, so we consider this a special exception to * - * the GPL that we apply to Covered Software. Works which meet any of * - * these conditions must conform to all of the terms of this license, * - * particularly including the GPL Section 3 requirements of providing * - * source code and allowing free redistribution of the work as a whole. * - * * - * As another special exception to the GPL terms, Aperture Labs Ltd. grants* - * permission to link the code of this program with any version of the * - * OpenSSL library which is distributed under a license identical to that * - * listed in the included docs/licenses/OpenSSL.txt file, and distribute * - * linked combinations including the two. * - * * - * Any redistribution of Covered Software, including any derived works, * - * must obey and carry forward all of the terms of this license, including * - * obeying all GPL rules and restrictions. For example, source code of * - * the whole work must be provided and free redistribution must be * - * allowed. All GPL references to "this License", are to be treated as * - * including the terms and conditions of this license text as well. * - * * - * Because this license imposes special exceptions to the GPL, Covered * - * Work may not be combined (even as part of a larger work) with plain GPL * - * software. The terms, conditions, and exceptions of this license must * - * be included as well. This license is incompatible with some other open * - * source licenses as well. In some cases we can relicense portions of * - * RFIDler or grant special permissions to use it in other open source * - * software. Please contact sales@aperturelabs.com with any such requests.* - * Similarly, we don't incorporate incompatible open source software into * - * Covered Software without special permission from the copyright holders. * - * * - * If you have any questions about the licensing restrictions on using * - * RFIDler in other works, are happy to help. As mentioned above, we also * - * offer alternative license to integrate RFIDler into proprietary * - * applications and appliances. These contracts have been sold to dozens * - * of software vendors, and generally include a perpetual license as well * - * as providing for priority support and updates. They also fund the * - * continued development of RFIDler. Please email sales@aperturelabs.com * - * for further information. * - * If you have received a written license agreement or contract for * - * Covered Software stating terms other than these, you may choose to use * - * and redistribute Covered Software under those terms instead of these. * - * * - * Source is provided to this software because we believe users have a * - * right to know exactly what a program is going to do before they run it. * - * This also allows you to audit the software for security holes (none * - * have been found so far). * - * * - * Source code also allows you to port RFIDler to new platforms, fix bugs, * - * and add new features. You are highly encouraged to send your changes * - * to the RFIDler mailing list for possible incorporation into the * - * main distribution. By sending these changes to Aperture Labs Ltd. or * - * one of the Aperture Labs Ltd. development mailing lists, or checking * - * them into the RFIDler source code repository, it is understood (unless * - * you specify otherwise) that you are offering the RFIDler Project * - * (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, * - * modify, and relicense the code. RFIDler will always be available Open * - * Source, but this is important because the inability to relicense code * - * has caused devastating problems for other Free Software projects (such * - * as KDE and NASM). We also occasionally relicense the code to third * - * parties as discussed above. If you wish to specify special license * - * conditions of your contributions, just say so when you send them. * - * * - * This program is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler * - * license file for more details (it's in a COPYING file included with * - * RFIDler, and also available from * - * https://github.com/ApertureLabsLtd/RFIDler/COPYING * - * * - ***************************************************************************/ - -// Author: Adam Laurie - - - -#ifndef HARDWARE_PROFILE_UBW32_H -#define HARDWARE_PROFILE_UBW32_H - -//#include "plib.h" -typedef char BOOL; -typedef char BYTE; -typedef int rtccTime; -typedef int rtccDate; - - -#ifndef __PIC32MX__ -#define __PIC32MX__ -#endif - -#define GetSystemClock() (80000000ul) -#define GetPeripheralClock() (GetSystemClock()) -#define GetInstructionClock() (GetSystemClock()) - -//#define USE_SELF_POWER_SENSE_IO -#define tris_self_power TRISAbits.TRISA2 // Input -#define self_power 1 - -//#define USE_USB_BUS_SENSE_IO -#define tris_usb_bus_sense TRISBbits.TRISB5 // Input -#define USB_BUS_SENSE 1 - -// LEDs -#define mLED_1 LATEbits.LATE3 - -#define mLED_2 LATEbits.LATE2 -#define mLED_Comms mLED_2 - -#define mLED_3 LATEbits.LATE1 -#define mLED_Clock mLED_3 - -#define mLED_4 LATEbits.LATE0 -#define mLED_Emulate mLED_4 - -#define mLED_5 LATGbits.LATG6 -#define mLED_Read mLED_5 - -#define mLED_6 LATAbits.LATA15 -#define mLED_User mLED_6 - -#define mLED_7 LATDbits.LATD11 -#define mLED_Error mLED_7 - -// active low -#define mLED_ON 0 -#define mLED_OFF 1 - -#define mGetLED_1() mLED_1 -#define mGetLED_USB() mLED_1 -#define mGetLED_2() mLED_2 -#define mGetLED_Comms() mLED_2 -#define mGetLED_3() mLED_3 -#define mGetLED_Clock() mLED_3 -#define mGetLED_4() mLED_4 -#define mGetLED_Emulate() mLED_4 -#define mGetLED_5() mLED_5 -#define mGetLED_Read() mLED_5 -#define mGetLED_6() mLED_6 -#define mGetLED_User() mLED_6 -#define mGetLED_7() mLED_7 -#define mGetLED_Error() mLED_7 - -#define mLED_1_On() mLED_1 = mLED_ON -#define mLED_USB_On() mLED_1_On() -#define mLED_2_On() mLED_2 = mLED_ON -#define mLED_Comms_On() mLED_2_On() -#define mLED_3_On() mLED_3 = mLED_ON -#define mLED_Clock_On() mLED_3_On() -#define mLED_4_On() mLED_4 = mLED_ON -#define mLED_Emulate_On() mLED_4_On() -#define mLED_5_On() mLED_5 = mLED_ON -#define mLED_Read_On() mLED_5_On() -#define mLED_6_On() mLED_6 = mLED_ON -#define mLED_User_On() mLED_6_On() -#define mLED_7_On() mLED_7 = mLED_ON -#define mLED_Error_On() mLED_7_On() - -#define mLED_1_Off() mLED_1 = mLED_OFF -#define mLED_USB_Off() mLED_1_Off() -#define mLED_2_Off() mLED_2 = mLED_OFF -#define mLED_Comms_Off() mLED_2_Off() -#define mLED_3_Off() mLED_3 = mLED_OFF -#define mLED_Clock_Off() mLED_3_Off() -#define mLED_4_Off() mLED_4 = mLED_OFF -#define mLED_Emulate_Off() mLED_4_Off() -#define mLED_5_Off() mLED_5 = mLED_OFF -#define mLED_Read_Off() mLED_5_Off() -#define mLED_6_Off() mLED_6 = mLED_OFF -#define mLED_User_Off() mLED_6_Off() -#define mLED_7_Off() mLED_7 = mLED_OFF -#define mLED_Error_Off() mLED_7_Off() - -#define mLED_1_Toggle() mLED_1 = !mLED_1 -#define mLED_USB_Toggle() mLED_1_Toggle() -#define mLED_2_Toggle() mLED_2 = !mLED_2 -#define mLED_Comms_Toggle() mLED_2_Toggle() -#define mLED_3_Toggle() mLED_3 = !mLED_3 -#define mLED_Clock_Toggle() mLED_3_Toggle() -#define mLED_4_Toggle() mLED_4 = !mLED_4 -#define mLED_Emulate_Toggle() mLED_4_Toggle() -#define mLED_5_Toggle() mLED_5 = !mLED_5 -#define mLED_Read_Toggle( ) mLED_5_Toggle() -#define mLED_6_Toggle() mLED_6 = !mLED_6 -#define mLED_User_Toggle() mLED_6_Toggle() -#define mLED_7_Toggle() mLED_7 = !mLED_7 -#define mLED_Error_Toggle() mLED_7_Toggle() - -#define mLED_All_On() { mLED_1_On(); mLED_2_On(); mLED_3_On(); mLED_4_On(); mLED_5_On(); mLED_6_On(); mLED_7_On(); } -#define mLED_All_Off() { mLED_1_Off(); mLED_2_Off(); mLED_3_Off(); mLED_4_Off(); mLED_5_Off(); mLED_6_Off(); mLED_7_Off(); } - -// usb status lights -#define mLED_Both_Off() {mLED_USB_Off();mLED_Comms_Off();} -#define mLED_Both_On() {mLED_USB_On();mLED_Comms_On();} -#define mLED_Only_USB_On() {mLED_USB_On();mLED_Comms_Off();} -#define mLED_Only_Comms_On() {mLED_USB_Off();mLED_Comms_On();} - -/** SWITCH *********************************************************/ -#define swBootloader PORTEbits.RE7 -#define swUser PORTEbits.RE6 - -/** I/O pin definitions ********************************************/ -#define INPUT_PIN 1 -#define OUTPUT_PIN 0 - -#define TRUE 1 -#define FALSE 0 - -#define ENABLE 1 -#define DISABE 0 - -#define EVEN 0 -#define ODD 1 - -#define LOW FALSE -#define HIGH TRUE - -#define CLOCK_ON LOW -#define CLOCK_OFF HIGH - -// output coil control - select between reader/emulator circuits -#define COIL_MODE LATBbits.LATB4 -#define COIL_MODE_READER() COIL_MODE= LOW -#define COIL_MODE_EMULATOR() COIL_MODE= HIGH - -// coil for emulation -#define COIL_OUT LATGbits.LATG9 -#define COIL_OUT_HIGH() COIL_OUT=HIGH -#define COIL_OUT_LOW() COIL_OUT=LOW - -// door relay (active low) -#define DOOR_RELAY LATAbits.LATA14 -#define DOOR_RELAY_OPEN() DOOR_RELAY= HIGH -#define DOOR_RELAY_CLOSE() DOOR_RELAY= LOW - -// inductance/capacitance freq -#define IC_FREQUENCY PORTAbits.RA2 - -#define SNIFFER_COIL PORTDbits.RD12 // external reader clock detect -#define READER_ANALOGUE PORTBbits.RB11 // reader coil analogue -#define DIV_LOW_ANALOGUE PORTBbits.RB12 // voltage divider LOW analogue -#define DIV_HIGH_ANALOGUE PORTBbits.RB13 // voltage divider HIGH analogue - -// clock coil (normally controlled by OC Module, but defined here so we can force it high or low) -#define CLOCK_COIL PORTDbits.RD4 -#define CLOCK_COIL_MOVED PORTDbits.RD0 // temporary for greenwire - -// digital output after analogue reader circuit -#define READER_DATA PORTDbits.RD8 - -// trace / debug -#define DEBUG_PIN_1 LATCbits.LATC1 -#define DEBUG_PIN_1_TOGGLE() DEBUG_PIN_1= !DEBUG_PIN_1 -#define DEBUG_PIN_2 LATCbits.LATC2 -#define DEBUG_PIN_2_TOGGLE() DEBUG_PIN_2= !DEBUG_PIN_2 -#define DEBUG_PIN_3 LATCbits.LATC3 -#define DEBUG_PIN_3_TOGGLE() DEBUG_PIN_3= !DEBUG_PIN_3 -#define DEBUG_PIN_4 LATEbits.LATE5 -#define DEBUG_PIN_4_TOGGLE() DEBUG_PIN_4= !DEBUG_PIN_4 - -// spi (sdi1) for sd card (not directly referenced) -//#define SD_CARD_RX LATCbits.LATC4 -//#define SD_CARD_TX LATDbits.LATD0 -//#define SD_CARD_CLK LATDbits.LATD10 -//#define SD_CARD_SS LATDbits.LATD9 -// spi for SD card -#define SD_CARD_DET LATFbits.LATF0 -#define SD_CARD_WE LATFbits.LATF1 // write enable - unused for microsd but allocated anyway as library checks it -// (held LOW by default - cut solder bridge to GND to free pin if required) -#define SPI_SD SPI_CHANNEL1 -#define SPI_SD_BUFF SPI1BUF -#define SPI_SD_STAT SPI1STATbits -// see section below for more defines! - -// iso 7816 smartcard -// microchip SC module defines pins so we don't need to, but -// they are listed here to help avoid conflicts -#define ISO_7816_RX LATBbits.LATF2 // RX -#define ISO_7816_TX LATBbits.LATF8 // TX -#define ISO_7816_VCC LATBbits.LATB9 // Power -#define ISO_7816_CLK LATCbits.LATD1 // Clock -#define ISO_7816_RST LATEbits.LATE8 // Reset - -// user LED -#define USER_LED LATDbits.LATD7 -#define USER_LED_ON() LATDbits.LATD7=1 -#define USER_LED_OFF() LATDbits.LATD7=0 - -// LCR -#define LCR_CALIBRATE LATBbits.LATB5 - -// wiegand / clock & data -#define WIEGAND_IN_0 PORTDbits.RD5 -#define WIEGAND_IN_0_PULLUP CNPUEbits.CNPUE14 -#define WIEGAND_IN_0_PULLDOWN CNPDbits.CNPD14 -#define WIEGAND_IN_1 PORTDbits.RD6 -#define WIEGAND_IN_1_PULLUP CNPUEbits.CNPUE15 -#define WIEGAND_IN_1_PULLDOWN CNPDbits.CNPD15 -#define CAND_IN_DATA WIEGAND_IN_0 -#define CAND_IN_CLOCK WIEGAND_IN_1 - -#define WIEGAND_OUT_0 LATDbits.LATD3 -#define WIEGAND_OUT_1 LATDbits.LATD2 -#define WIEGAND_OUT_0_TRIS TRISDbits.TRISD3 -#define WIEGAND_OUT_1_TRIS TRISDbits.TRISD2 -#define CAND_OUT_DATA WIEGAND_OUT_0 -#define CAND_OUT_CLOCK WIEGAND_OUT_1 - -// connect/disconnect reader clock from coil - used to send RWD signals by creating gaps in carrier -#define READER_CLOCK_ENABLE LATEbits.LATE9 -#define READER_CLOCK_ENABLE_ON() READER_CLOCK_ENABLE=CLOCK_ON -#define READER_CLOCK_ENABLE_OFF(x) {READER_CLOCK_ENABLE=CLOCK_OFF; COIL_OUT=x;} - -// these input pins must NEVER bet set to output or they will cause short circuits! -// they can be used to see data from reader before it goes into or gate -#define OR_IN_A PORTAbits.RA4 -#define OR_IN_B PORTAbits.RA5 - - -// CNCON and CNEN are set to allow wiegand input pin weak pullups to be switched on -#define Init_GPIO() { \ - CNCONbits.ON= TRUE; \ - CNENbits.CNEN14= TRUE; \ - CNENbits.CNEN15= TRUE; \ - TRISAbits.TRISA2= INPUT_PIN; \ - TRISAbits.TRISA4= INPUT_PIN; \ - TRISAbits.TRISA5= INPUT_PIN; \ - TRISAbits.TRISA14= OUTPUT_PIN; \ - TRISAbits.TRISA15= OUTPUT_PIN; \ - TRISBbits.TRISB4= OUTPUT_PIN; \ - TRISBbits.TRISB5= OUTPUT_PIN; \ - TRISBbits.TRISB9= OUTPUT_PIN; \ - TRISBbits.TRISB11= INPUT_PIN; \ - TRISBbits.TRISB12= INPUT_PIN; \ - TRISBbits.TRISB13= INPUT_PIN; \ - TRISCbits.TRISC1= OUTPUT_PIN; \ - TRISCbits.TRISC2= OUTPUT_PIN; \ - TRISCbits.TRISC3= OUTPUT_PIN; \ - TRISCbits.TRISC4= INPUT_PIN; \ - TRISDbits.TRISD0= INPUT_PIN; \ - TRISDbits.TRISD1= OUTPUT_PIN; \ - TRISDbits.TRISD2= OUTPUT_PIN; \ - TRISDbits.TRISD3= OUTPUT_PIN; \ - TRISDbits.TRISD4= OUTPUT_PIN; \ - TRISDbits.TRISD5= INPUT_PIN; \ - TRISDbits.TRISD6= INPUT_PIN; \ - TRISDbits.TRISD7= OUTPUT_PIN; \ - TRISDbits.TRISD8= INPUT_PIN; \ - TRISDbits.TRISD11= OUTPUT_PIN; \ - TRISDbits.TRISD12= INPUT_PIN; \ - TRISEbits.TRISE0= OUTPUT_PIN; \ - TRISEbits.TRISE1= OUTPUT_PIN; \ - TRISEbits.TRISE2= OUTPUT_PIN; \ - TRISEbits.TRISE3= OUTPUT_PIN; \ - TRISEbits.TRISE5= OUTPUT_PIN; \ - TRISEbits.TRISE6= INPUT_PIN; \ - TRISEbits.TRISE7= INPUT_PIN; \ - TRISEbits.TRISE8= OUTPUT_PIN; \ - TRISEbits.TRISE9= OUTPUT_PIN; \ - TRISFbits.TRISF0= INPUT_PIN; \ - TRISFbits.TRISF1= INPUT_PIN; \ - TRISFbits.TRISF2= INPUT_PIN; \ - TRISFbits.TRISF8= OUTPUT_PIN; \ - TRISGbits.TRISG6= OUTPUT_PIN; \ - TRISGbits.TRISG12= INPUT_PIN; \ - TRISGbits.TRISG13= INPUT_PIN; \ - TRISGbits.TRISG9= OUTPUT_PIN; \ - LATBbits.LATB9= LOW; \ - LATCbits.LATC1= LOW; \ - LATCbits.LATC2= LOW; \ - LATCbits.LATC3= LOW; \ - LATDbits.LATD2= WIEGAND_IN_1; \ - LATDbits.LATD3= WIEGAND_IN_0; \ - LATEbits.LATE5= LOW; \ - LATEbits.LATE9= HIGH; \ - } - -// uart3 (CLI/API) speed -#define BAUDRATE3 115200UL -#define BRG_DIV3 4 -#define BRGH3 1 - -// spi for potentiometer -#define SPI_POT SPI_CHANNEL4 -#define SPI_POT_BUFF SPI4BUF -#define SPI_POT_STAT SPI4STATbits - -// spi for sd card - defines required for Microchip SD-SPI libs -// define interface type -#define USE_SD_INTERFACE_WITH_SPI - -#define MDD_USE_SPI_1 -#define SPI_START_CFG_1 (PRI_PRESCAL_64_1 | SEC_PRESCAL_8_1 | MASTER_ENABLE_ON | SPI_CKE_ON | SPI_SMP_ON) -#define SPI_START_CFG_2 (SPI_ENABLE) -// Define the SPI frequency -#define SPI_FREQUENCY (20000000) -// Description: SD-SPI Card Detect Input bit -#define SD_CD PORTFbits.RF0 -// Description: SD-SPI Card Detect TRIS bit -#define SD_CD_TRIS TRISFbits.TRISF0 -// Description: SD-SPI Write Protect Check Input bit -#define SD_WE PORTFbits.RF1 -// Description: SD-SPI Write Protect Check TRIS bit -#define SD_WE_TRIS TRISFbits.TRISF1 -// Description: The main SPI control register -#define SPICON1 SPI1CON -// Description: The SPI status register -#define SPISTAT SPI1STAT -// Description: The SPI Buffer -#define SPIBUF SPI1BUF -// Description: The receive buffer full bit in the SPI status register -#define SPISTAT_RBF SPI1STATbits.SPIRBF -// Description: The bitwise define for the SPI control register (i.e. _____bits) -#define SPICON1bits SPI1CONbits -// Description: The bitwise define for the SPI status register (i.e. _____bits) -#define SPISTATbits SPI1STATbits -// Description: The enable bit for the SPI module -#define SPIENABLE SPICON1bits.ON -// Description: The definition for the SPI baud rate generator register (PIC32) -#define SPIBRG SPI1BRG -// Description: The TRIS bit for the SCK pin -#define SPICLOCK TRISDbits.TRISD10 -// Description: The TRIS bit for the SDI pin -#define SPIIN TRISCbits.TRISC4 -// Description: The TRIS bit for the SDO pin -#define SPIOUT TRISDbits.TRISD0 -#define SD_CS LATDbits.LATD9 -// Description: SD-SPI Chip Select TRIS bit -#define SD_CS_TRIS TRISDbits.TRISD9 -//SPI library functions -#define putcSPI putcSPI1 -#define getcSPI getcSPI1 -#define OpenSPI(config1, config2) OpenSPI1(config1, config2) - -// Define setup parameters for OpenADC10 function -// Turn module on | Ouput in integer format | Trigger mode auto | Enable autosample -#define ADC_CONFIG1 (ADC_FORMAT_INTG | ADC_CLK_AUTO | ADC_AUTO_SAMPLING_ON) -// ADC ref external | Disable offset test | Disable scan mode | Perform 2 samples | Use dual buffers | Use alternate mode -#define ADC_CONFIG2 (ADC_VREF_AVDD_AVSS | ADC_OFFSET_CAL_DISABLE | ADC_SCAN_OFF | ADC_SAMPLES_PER_INT_1 | ADC_ALT_BUF_ON | ADC_ALT_INPUT_ON) - -// Use ADC internal clock | Set sample time -#define ADC_CONFIG3 (ADC_CONV_CLK_INTERNAL_RC | ADC_SAMPLE_TIME_0) - -// slow sample rate for tuning coils -#define ADC_CONFIG2_SLOW (ADC_VREF_AVDD_AVSS | ADC_OFFSET_CAL_DISABLE | ADC_SCAN_OFF | ADC_SAMPLES_PER_INT_16 | ADC_ALT_BUF_ON | ADC_ALT_INPUT_ON) -#define ADC_CONFIG3_SLOW (ADC_CONV_CLK_INTERNAL_RC | ADC_SAMPLE_TIME_31) - -// use AN11 -#define ADC_CONFIGPORT ENABLE_AN11_ANA -// Do not assign channels to scan -#define ADC_CONFIGSCAN SKIP_SCAN_ALL - -#define ADC_TO_VOLTS 0.003208F - - -// flash memory - int myvar = *(int*)(myflashmemoryaddress); - -// memory is 0x9D005000 to 0x9D07FFFF - -#define NVM_MEMORY_END 0x9D07FFFF -#define NVM_PAGE_SIZE 4096 -#define NVM_PAGES 2 // config & VTAG -#define RFIDLER_NVM_ADDRESS (NVM_MEMORY_END - (NVM_PAGE_SIZE * NVM_PAGES)) - -// UART timeout in us -#define SERIAL_TIMEOUT 100 - -#endif diff --git a/tools/hitag2crack/crack5/Makefile b/tools/hitag2crack/crack5/Makefile index e38c821d1..1b40e2141 100644 --- a/tools/hitag2crack/crack5/Makefile +++ b/tools/hitag2crack/crack5/Makefile @@ -1,17 +1,19 @@ CFLAGS?=-Wall LIBS=-lpthread +VPATH=../common +INC=-I ../common -all: ht2crack5.c utilpart.o ht2crack2utils.o hitagcrypto.o - $(CC) $(CFLAGS) -O3 ht2crack5.c -o ht2crack5 utilpart.o ht2crack2utils.o hitagcrypto.o $(LIBS) +all: ht2crack5.c utilpart.o ht2crackutils.o hitagcrypto.o + $(CC) $(CFLAGS) $(INC) -O3 $< -o ht2crack5 utilpart.o ht2crackutils.o hitagcrypto.o $(LIBS) -utilpart.o: util.h utilpart.c - $(CC) $(CFLAGS) -c utilpart.c +utilpart.o: utilpart.c util.h + $(CC) $(CFLAGS) -c $< -hitagcrypto.o: hitagcrypto.h hitagcrypto.c - $(CC) $(CFLAGS) -c hitagcrypto.c +hitagcrypto.o: hitagcrypto.c hitagcrypto.h + $(CC) $(CFLAGS) -c $< -ht2crack2utils.o: ht2crack2utils.h ht2crack2utils.c - $(CC) $(CFLAGS) -c ht2crack2utils.c +ht2crackutils.o: ht2crackutils.c ht2crackutils.h + $(CC) $(CFLAGS) -c $< clean: rm -f *.o ht2crack5 diff --git a/tools/hitag2crack/crack5/hitagcrypto.c b/tools/hitag2crack/crack5/hitagcrypto.c deleted file mode 100644 index 47449c3e3..000000000 --- a/tools/hitag2crack/crack5/hitagcrypto.c +++ /dev/null @@ -1,373 +0,0 @@ -/*************************************************************************** - * A copy of the GNU GPL is appended to this file. * - * * - * This licence is based on the nmap licence, and we express our gratitude * - * for the work that went into producing it. There is no other connection * - * between RFIDler and nmap either expressed or implied. * - * * - ********************** IMPORTANT RFIDler LICENSE TERMS ******************** - * * - * * - * All references to RFIDler herein imply all it's derivatives, namely: * - * * - * o RFIDler-LF Standard * - * o RFIDler-LF Lite * - * o RFIDler-LF Nekkid * - * * - * * - * RFIDler is (C) 2013-2015 Aperture Labs Ltd. * - * * - * This program is free software; you may redistribute and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE * - * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your * - * right to use, modify, and redistribute this software under certain * - * conditions. If you wish to embed RFIDler technology into proprietary * - * software or hardware, we sell alternative licenses * - * (contact sales@aperturelabs.com). * - * * - * Note that the GPL places important restrictions on "derivative works", * - * yet it does not provide a detailed definition of that term. To avoid * - * misunderstandings, we interpret that term as broadly as copyright law * - * allows. For example, we consider an application to constitute a * - * derivative work for the purpose of this license if it does any of the * - * following with any software or content covered by this license * - * ("Covered Software"): * - * * - * o Integrates source code from Covered Software. * - * * - * o Is designed specifically to execute Covered Software and parse the * - * results (as opposed to typical shell or execution-menu apps, which will * - * execute anything you tell them to). * - * * - * o Includes Covered Software in a proprietary executable installer. The * - * installers produced by InstallShield are an example of this. Including * - * RFIDler with other software in compressed or archival form does not * - * trigger this provision, provided appropriate open source decompression * - * or de-archiving software is widely available for no charge. For the * - * purposes of this license, an installer is considered to include Covered * - * Software even if it actually retrieves a copy of Covered Software from * - * another source during runtime (such as by downloading it from the * - * Internet). * - * * - * o Links (statically or dynamically) to a library which does any of the * - * above. * - * * - * o Executes a helper program, module, or script to do any of the above. * - * * - * This list is not exclusive, but is meant to clarify our interpretation * - * of derived works with some common examples. Other people may interpret * - * the plain GPL differently, so we consider this a special exception to * - * the GPL that we apply to Covered Software. Works which meet any of * - * these conditions must conform to all of the terms of this license, * - * particularly including the GPL Section 3 requirements of providing * - * source code and allowing free redistribution of the work as a whole. * - * * - * As another special exception to the GPL terms, Aperture Labs Ltd. grants* - * permission to link the code of this program with any version of the * - * OpenSSL library which is distributed under a license identical to that * - * listed in the included docs/licenses/OpenSSL.txt file, and distribute * - * linked combinations including the two. * - * * - * Any redistribution of Covered Software, including any derived works, * - * must obey and carry forward all of the terms of this license, including * - * obeying all GPL rules and restrictions. For example, source code of * - * the whole work must be provided and free redistribution must be * - * allowed. All GPL references to "this License", are to be treated as * - * including the terms and conditions of this license text as well. * - * * - * Because this license imposes special exceptions to the GPL, Covered * - * Work may not be combined (even as part of a larger work) with plain GPL * - * software. The terms, conditions, and exceptions of this license must * - * be included as well. This license is incompatible with some other open * - * source licenses as well. In some cases we can relicense portions of * - * RFIDler or grant special permissions to use it in other open source * - * software. Please contact sales@aperturelabs.com with any such requests.* - * Similarly, we don't incorporate incompatible open source software into * - * Covered Software without special permission from the copyright holders. * - * * - * If you have any questions about the licensing restrictions on using * - * RFIDler in other works, are happy to help. As mentioned above, we also * - * offer alternative license to integrate RFIDler into proprietary * - * applications and appliances. These contracts have been sold to dozens * - * of software vendors, and generally include a perpetual license as well * - * as providing for priority support and updates. They also fund the * - * continued development of RFIDler. Please email sales@aperturelabs.com * - * for further information. * - * If you have received a written license agreement or contract for * - * Covered Software stating terms other than these, you may choose to use * - * and redistribute Covered Software under those terms instead of these. * - * * - * Source is provided to this software because we believe users have a * - * right to know exactly what a program is going to do before they run it. * - * This also allows you to audit the software for security holes (none * - * have been found so far). * - * * - * Source code also allows you to port RFIDler to new platforms, fix bugs, * - * and add new features. You are highly encouraged to send your changes * - * to the RFIDler mailing list for possible incorporation into the * - * main distribution. By sending these changes to Aperture Labs Ltd. or * - * one of the Aperture Labs Ltd. development mailing lists, or checking * - * them into the RFIDler source code repository, it is understood (unless * - * you specify otherwise) that you are offering the RFIDler Project * - * (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, * - * modify, and relicense the code. RFIDler will always be available Open * - * Source, but this is important because the inability to relicense code * - * has caused devastating problems for other Free Software projects (such * - * as KDE and NASM). We also occasionally relicense the code to third * - * parties as discussed above. If you wish to specify special license * - * conditions of your contributions, just say so when you send them. * - * * - * This program is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler * - * license file for more details (it's in a COPYING file included with * - * RFIDler, and also available from * - * https://github.com/ApertureLabsLtd/RFIDler/COPYING * - * * - ***************************************************************************/ - -// Author: unknown. -// Modifications for RFIDler: Tony Naggs , Adam Laurie - -// uncomment this to build file as a standalone crypto test program -// #define UNIT_TEST -// also uncomment to include verbose debug prints -// #define TEST_DEBUG - -//#include -#include "HardwareProfile.h" -#include "rfidler.h" -#include "hitagcrypto.h" -#include "util.h" - -#ifdef UNIT_TEST -#include -#endif - -#if defined(UNIT_TEST) && defined(TEST_DEBUG) -// Note that printf format %I64x prints 64 bit ints in MS Visual C/C++. -// This may need changing for other compilers/platforms. -#define DEBUG_PRINTF(...) printf(__VA_ARGS__) -#else -#define DEBUG_PRINTF(...) -#endif - - -/* Brief info about NXP Hitag 1, Hitag 2, Hitag S and Hitag u (mu) - - Hitag 125kHz RFID was created by a company called Mikron (Mikron Gesellschaft - fur Integrierte Mikroelektronik Mbh), of Austria, for micropayment applications. - At about the same time, late 1980s to early 1990s, Mikron developed the - similarly featured Mifare micropayment card for 13.56MHz RFID. - (Mikron's European Patent EP 0473569 A2 was filed 23 August 1991, with a - priority date of 23 Aug 1990.) - Mikron was subsequently acquired by Philips Semiconductors in 1995. - Philips Semiconductors divsion subsequently became NXP. - - + Modulation read/write device -> transponder: 100 % ASK and binary pulse - length coding - + Modulation transponder -> read/write device: Strong ASK modulation, - selectable Manchester or Biphase coding - + Hitag S, Hitag u; anti-collision procedure - + Fast anti-collision protocol - + Hitag u; optional Cyclic Redundancy Check (CRC) - + Reader Talks First mode - + Hitag 2 & later; Transponder Talks First (TTF) mode - + Temporary switch from Transponder Talks First into Reader Talks First - (RTF) Mode - + Data rate read/write device to transponder: 5.2 kbit/s - + Data rates transponder to read/write device: 2 kbit/s, 4 kbit/s, 8 kbit/s - + 32-bit password feature - + Hitag 2, S = 32-bit Unique Identifier - + Hitag u = 48-bit Unique Identifier - + Selectable password modes for reader / tag mutual authentication - (Hitag 1 has 2 pairs of keys, later versions have 1 pair) - + Hitag 2 & Hitag S; Selectable encrypted mode, 48 bit key - - Known tag types: - - HITAG 1 2048 bits total memory - - HITAG 2 256 Bit total memory Read/Write - 8 pages of 32 bits, inc UID (32), - secret key (64), password (24), config (8) - - HITAG S 32 32 bits Unique Identifier Read Only - HITAG S 256 256 bits total memory Read/Write - HITAG S 2048 2048 bits total memory Read/Write - - HITAG u RO64 64 bits total memory Read Only - HITAG u 128 bits total memory Read/Write - HITAG u Advanced 512 bits total memory Read/Write - HITAG u Advanced+ 1760 bits total memory Read/Write - - Default 48-bit key for Hitag 2, S encryption: - "MIKRON" = O N M I K R - Key = 4F 4E 4D 49 4B 52 - -*/ - - -// We want the crypto functions to be as fast as possible, so optimize! -// The best compiler optimization in Microchip's free XC32 edition is -O1 -#pragma GCC optimize("O1") - -// private, nonlinear function to generate 1 crypto bit -static uint32_t hitag2_crypt(uint64_t x); - - -// macros to pick out 4 bits in various patterns of 1s & 2s & make a new number -#define pickbits2_2(S, A, B) ( ((S >> A) & 3) | ((S >> (B - 2)) & 0xC) ) -#define pickbits1x4(S, A, B, C, D) ( ((S >> A) & 1) | ((S >> (B - 1)) & 2) | \ - ((S >> (C - 2)) & 4) | ((S >> (D - 3)) & 8) ) -#define pickbits1_1_2(S, A, B, C) ( ((S >> A) & 1) | ((S >> (B - 1)) & 2) | \ - ((S >> (C - 2)) & 0xC) ) -#define pickbits2_1_1(S, A, B, C) ( ((S >> A) & 3) | ((S >> (B - 2)) & 4) | \ - ((S >> (C - 3)) & 8) ) -#define pickbits1_2_1(S, A, B, C) ( ((S >> A) & 1) | ((S >> (B - 1)) & 6) | \ - ((S >> (C - 3)) & 8) ) - - -static uint32_t hitag2_crypt(uint64_t x) { - const uint32_t ht2_function4a = 0x2C79; // 0010 1100 0111 1001 - const uint32_t ht2_function4b = 0x6671; // 0110 0110 0111 0001 - const uint32_t ht2_function5c = 0x7907287B; // 0111 1001 0000 0111 0010 1000 0111 1011 - uint32_t bitindex; - - bitindex = (ht2_function4a >> pickbits2_2(x, 1, 4)) & 1; - bitindex |= ((ht2_function4b << 1) >> pickbits1_1_2(x, 7, 11, 13)) & 0x02; - bitindex |= ((ht2_function4b << 2) >> pickbits1x4(x, 16, 20, 22, 25)) & 0x04; - bitindex |= ((ht2_function4b << 3) >> pickbits2_1_1(x, 27, 30, 32)) & 0x08; - bitindex |= ((ht2_function4a << 4) >> pickbits1_2_1(x, 33, 42, 45)) & 0x10; - - DEBUG_PRINTF("hitag2_crypt bitindex = %02x\n", bitindex); - return (ht2_function5c >> bitindex) & 1; -} - -/* - * Parameters: - * Hitag_State* pstate - output, internal state after initialisation - * uint64_t sharedkey - 48 bit key shared between reader & tag - * uint32_t serialnum - 32 bit tag serial number - * uint32_t initvector - 32 bit random IV from reader, part of tag authentication - */ -void hitag2_init(Hitag_State *pstate, uint64_t sharedkey, uint32_t serialnum, uint32_t initvector) { - // init state, from serial number and lowest 16 bits of shared key - uint64_t state = ((sharedkey & 0xFFFF) << 32) | serialnum; - - // mix the initialisation vector and highest 32 bits of the shared key - initvector ^= (uint32_t)(sharedkey >> 16); - - // move 16 bits from (IV xor Shared Key) to top of uint64_t state - // these will be XORed in turn with output of the crypto function - state |= (uint64_t) initvector << 48; - initvector >>= 16; - - // unrolled loop is faster on PIC32 (MIPS), do 32 times - // shift register, then calc new bit - state >>= 1; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - - // highest 16 bits of IV XOR Shared Key - state |= (uint64_t) initvector << 47; - - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state ^= (uint64_t) hitag2_crypt(state) << 47; - - DEBUG_PRINTF("hitag2_init result = %012I64x\n", state); - pstate->shiftreg = state; - /* naive version for reference, LFSR has 16 taps - pstate->lfsr = state ^ (state >> 2) ^ (state >> 3) ^ (state >> 6) - ^ (state >> 7) ^ (state >> 8) ^ (state >> 16) ^ (state >> 22) - ^ (state >> 23) ^ (state >> 26) ^ (state >> 30) ^ (state >> 41) - ^ (state >> 42) ^ (state >> 43) ^ (state >> 46) ^ (state >> 47); - */ - { - // optimise with one 64-bit intermediate - uint64_t temp = state ^ (state >> 1); - pstate->lfsr = state ^ (state >> 6) ^ (state >> 16) - ^ (state >> 26) ^ (state >> 30) ^ (state >> 41) - ^ (temp >> 2) ^ (temp >> 7) ^ (temp >> 22) - ^ (temp >> 42) ^ (temp >> 46); - } -} - - -/* - * Return up to 32 crypto bits. - * Last bit is in least significant bit, earlier bits are shifted left. - * Note that the Hitag transmission protocol is least significant bit, - * so we may want to change this, or add a function, that returns the - * crypto output bits in the other order. - * - * Parameters: - * Hitag_State* pstate - in/out, internal cipher state after initialisation - * uint32_t steps - number of bits requested, (capped at 32) - */ -uint32_t hitag2_nstep(Hitag_State *pstate, uint32_t steps) { - uint64_t state = pstate->shiftreg; - uint32_t result = 0; - uint64_t lfsr = pstate->lfsr; - - if (steps == 0) - return 0; - -// if (steps > 32) -// steps = 32; - - do { - // update shift registers - if (lfsr & 1) { - state = (state >> 1) | 0x800000000000; - lfsr = (lfsr >> 1) ^ 0xB38083220073; - - // accumulate next bit of crypto - result = (result << 1) | hitag2_crypt(state); - } else { - state >>= 1; - lfsr >>= 1; - - result = (result << 1) | hitag2_crypt(state); - } - } while (--steps); - - DEBUG_PRINTF("hitag2_nstep state = %012I64x, result %02x\n", state, result); - pstate->shiftreg = state; - pstate->lfsr = lfsr; - return result; -} - -// end of crypto core, revert to default optimization level -#pragma GCC reset_options diff --git a/tools/hitag2crack/crack5/hitagcrypto.h b/tools/hitag2crack/crack5/hitagcrypto.h deleted file mode 100644 index 274d3d82c..000000000 --- a/tools/hitag2crack/crack5/hitagcrypto.h +++ /dev/null @@ -1,167 +0,0 @@ -/*************************************************************************** - * A copy of the GNU GPL is appended to this file. * - * * - * This licence is based on the nmap licence, and we express our gratitude * - * for the work that went into producing it. There is no other connection * - * between RFIDler and nmap either expressed or implied. * - * * - ********************** IMPORTANT RFIDler LICENSE TERMS ******************** - * * - * * - * All references to RFIDler herein imply all it's derivatives, namely: * - * * - * o RFIDler-LF Standard * - * o RFIDler-LF Lite * - * o RFIDler-LF Nekkid * - * * - * * - * RFIDler is (C) 2013-2014 Aperture Labs Ltd. * - * * - * This program is free software; you may redistribute and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE * - * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your * - * right to use, modify, and redistribute this software under certain * - * conditions. If you wish to embed RFIDler technology into proprietary * - * software or hardware, we sell alternative licenses * - * (contact sales@aperturelabs.com). * - * * - * Note that the GPL places important restrictions on "derivative works", * - * yet it does not provide a detailed definition of that term. To avoid * - * misunderstandings, we interpret that term as broadly as copyright law * - * allows. For example, we consider an application to constitute a * - * derivative work for the purpose of this license if it does any of the * - * following with any software or content covered by this license * - * ("Covered Software"): * - * * - * o Integrates source code from Covered Software. * - * * - * o Is designed specifically to execute Covered Software and parse the * - * results (as opposed to typical shell or execution-menu apps, which will * - * execute anything you tell them to). * - * * - * o Includes Covered Software in a proprietary executable installer. The * - * installers produced by InstallShield are an example of this. Including * - * RFIDler with other software in compressed or archival form does not * - * trigger this provision, provided appropriate open source decompression * - * or de-archiving software is widely available for no charge. For the * - * purposes of this license, an installer is considered to include Covered * - * Software even if it actually retrieves a copy of Covered Software from * - * another source during runtime (such as by downloading it from the * - * Internet). * - * * - * o Links (statically or dynamically) to a library which does any of the * - * above. * - * * - * o Executes a helper program, module, or script to do any of the above. * - * * - * This list is not exclusive, but is meant to clarify our interpretation * - * of derived works with some common examples. Other people may interpret * - * the plain GPL differently, so we consider this a special exception to * - * the GPL that we apply to Covered Software. Works which meet any of * - * these conditions must conform to all of the terms of this license, * - * particularly including the GPL Section 3 requirements of providing * - * source code and allowing free redistribution of the work as a whole. * - * * - * As another special exception to the GPL terms, Aperture Labs Ltd. grants* - * permission to link the code of this program with any version of the * - * OpenSSL library which is distributed under a license identical to that * - * listed in the included docs/licenses/OpenSSL.txt file, and distribute * - * linked combinations including the two. * - * * - * Any redistribution of Covered Software, including any derived works, * - * must obey and carry forward all of the terms of this license, including * - * obeying all GPL rules and restrictions. For example, source code of * - * the whole work must be provided and free redistribution must be * - * allowed. All GPL references to "this License", are to be treated as * - * including the terms and conditions of this license text as well. * - * * - * Because this license imposes special exceptions to the GPL, Covered * - * Work may not be combined (even as part of a larger work) with plain GPL * - * software. The terms, conditions, and exceptions of this license must * - * be included as well. This license is incompatible with some other open * - * source licenses as well. In some cases we can relicense portions of * - * RFIDler or grant special permissions to use it in other open source * - * software. Please contact sales@aperturelabs.com with any such requests.* - * Similarly, we don't incorporate incompatible open source software into * - * Covered Software without special permission from the copyright holders. * - * * - * If you have any questions about the licensing restrictions on using * - * RFIDler in other works, are happy to help. As mentioned above, we also * - * offer alternative license to integrate RFIDler into proprietary * - * applications and appliances. These contracts have been sold to dozens * - * of software vendors, and generally include a perpetual license as well * - * as providing for priority support and updates. They also fund the * - * continued development of RFIDler. Please email sales@aperturelabs.com * - * for further information. * - * If you have received a written license agreement or contract for * - * Covered Software stating terms other than these, you may choose to use * - * and redistribute Covered Software under those terms instead of these. * - * * - * Source is provided to this software because we believe users have a * - * right to know exactly what a program is going to do before they run it. * - * This also allows you to audit the software for security holes (none * - * have been found so far). * - * * - * Source code also allows you to port RFIDler to new platforms, fix bugs, * - * and add new features. You are highly encouraged to send your changes * - * to the RFIDler mailing list for possible incorporation into the * - * main distribution. By sending these changes to Aperture Labs Ltd. or * - * one of the Aperture Labs Ltd. development mailing lists, or checking * - * them into the RFIDler source code repository, it is understood (unless * - * you specify otherwise) that you are offering the RFIDler Project * - * (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, * - * modify, and relicense the code. RFIDler will always be available Open * - * Source, but this is important because the inability to relicense code * - * has caused devastating problems for other Free Software projects (such * - * as KDE and NASM). We also occasionally relicense the code to third * - * parties as discussed above. If you wish to specify special license * - * conditions of your contributions, just say so when you send them. * - * * - * This program is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler * - * license file for more details (it's in a COPYING file included with * - * RFIDler, and also available from * - * https://github.com/ApertureLabsLtd/RFIDler/COPYING * - * * - ***************************************************************************/ - -// Author: unknown. -// Modifications for RFIDler: Tony Naggs , Adam Laurie - - -#ifndef HITAGCRYPTO_H -#define HITAGCRYPTO_H - -#include - -/* - Our model of Hitag 2 crypto uses 2 parallel shift registers: - a. 48 bit Feedback Shift Register, required for inputs to the nonlinear function. - b. 48 bit Linear Feedback Shift Register (LFSR). - A transform of initial register (a) value, which is then run in parallel. - Enables much faster calculation of the feedback values. - - API: - void hitag2_init(Hitag_State* pstate, uint64_t sharedkey, uint32_t serialnum, - uint32_t initvector); - Initialise state from 48 bit shared (secret) reader/tag key, - 32 bit tag serial number and 32 bit initialisation vector from reader. - - uint32_t hitag2_nstep(Hitag_State* pstate, uint32_t steps); - update shift register state and generate N cipher bits (N should be <= 32) - */ - - -typedef struct { - uint64_t shiftreg; // naive shift register, required for nonlinear fn input - uint64_t lfsr; // fast lfsr, used to make software faster -} Hitag_State; - -void hitag2_init(Hitag_State *pstate, uint64_t sharedkey, uint32_t serialnum, uint32_t initvector); - -uint32_t hitag2_nstep(Hitag_State *pstate, uint32_t steps); - -#endif /* HITAGCRYPTO_H */ - diff --git a/tools/hitag2crack/crack5/ht2crack2utils.c b/tools/hitag2crack/crack5/ht2crack2utils.c deleted file mode 100644 index 75d4c27a9..000000000 --- a/tools/hitag2crack/crack5/ht2crack2utils.c +++ /dev/null @@ -1,172 +0,0 @@ -#include "ht2crack2utils.h" - -// writes a value into a buffer as a series of bytes -void writebuf(unsigned char *buf, uint64_t val, unsigned int len) { - int i; - char c; - - for (i = len - 1; i >= 0; i--) { - c = val & 0xff; - buf[i] = c; - val = val >> 8; - } - -} - - -/* simple hexdump for testing purposes */ -void shexdump(unsigned char *data, int data_len) { - int i; - - if (!data || (data_len <= 0)) { - printf("shexdump: invalid parameters\n"); - return; - } - - printf("Hexdump from %p:\n", data); - - for (i = 0; i < data_len; i++) { - if ((i % HEX_PER_ROW) == 0) { - printf("\n0x%04x: ", i); - } - printf("%02x ", data[i]); - } - printf("\n\n"); -} - - - -void printbin(unsigned char *c) { - int i, j; - unsigned char x; - - if (!c) { - printf("printbin: invalid params\n"); - return; - } - - for (i = 0; i < 6; i++) { - x = c[i]; - for (j = 0; j < 8; j++) { - printf("%d", (x & 0x80) >> 7); - x = x << 1; - } - } - printf("\n"); -} - - -void printbin2(uint64_t val, unsigned int size) { - int i; - uint64_t mask = 1; - - mask = mask << (size - 1); - - for (i = 0; i < size; i++) { - if (val & mask) { - printf("1"); - } else { - printf("0"); - } - val = val << 1; - } -} - - -void printstate(Hitag_State *hstate) { - printf("shiftreg =\t"); - printbin2(hstate->shiftreg, 48); - printf("\n"); -} - - - - -// convert hex char to binary -unsigned char hex2bin(unsigned char c) { - if ((c >= '0') && (c <= '9')) { - return (c - '0'); - } else if ((c >= 'a') && (c <= 'f')) { - return (c - 'a' + 10); - } else if ((c >= 'A') && (c <= 'F')) { - return (c - 'A' + 10); - } else { - return 0; - } -} - -// return a single bit from a value -int bitn(uint64_t x, int bit) { - uint64_t bitmask = 1; - - bitmask = bitmask << bit; - - if (x & bitmask) { - return 1; - } else { - return 0; - } -} - - -// the sub-function R that rollback depends upon -int fnR(uint64_t x) { - // renumbered bits because my state is 0-47, not 1-48 - return (bitn(x, 1) ^ bitn(x, 2) ^ bitn(x, 5) ^ bitn(x, 6) ^ bitn(x, 7) ^ - bitn(x, 15) ^ bitn(x, 21) ^ bitn(x, 22) ^ bitn(x, 25) ^ bitn(x, 29) ^ bitn(x, 40) ^ - bitn(x, 41) ^ bitn(x, 42) ^ bitn(x, 45) ^ bitn(x, 46) ^ bitn(x, 47)); -} - -// the rollback function that lets us go backwards in time -void rollback(Hitag_State *hstate, unsigned int steps) { - int i; - - for (i = 0; i < steps; i++) { - hstate->shiftreg = ((hstate->shiftreg << 1) & 0xffffffffffff) | fnR(hstate->shiftreg); - } - -} - - -// the three filter sub-functions that feed fnf -int fa(unsigned int i) { - return bitn(0x2C79, i); -} - -int fb(unsigned int i) { - return bitn(0x6671, i); -} - -int fc(unsigned int i) { - return bitn(0x7907287B, i); -} - -// the filter function that generates a bit of output from the prng state -int fnf(uint64_t s) { - unsigned int x1, x2, x3, x4, x5, x6; - - x1 = (bitn(s, 2) << 0) | (bitn(s, 3) << 1) | (bitn(s, 5) << 2) | (bitn(s, 6) << 3); - x2 = (bitn(s, 8) << 0) | (bitn(s, 12) << 1) | (bitn(s, 14) << 2) | (bitn(s, 15) << 3); - x3 = (bitn(s, 17) << 0) | (bitn(s, 21) << 1) | (bitn(s, 23) << 2) | (bitn(s, 26) << 3); - x4 = (bitn(s, 28) << 0) | (bitn(s, 29) << 1) | (bitn(s, 31) << 2) | (bitn(s, 33) << 3); - x5 = (bitn(s, 34) << 0) | (bitn(s, 43) << 1) | (bitn(s, 44) << 2) | (bitn(s, 46) << 3); - - x6 = (fa(x1) << 0) | (fb(x2) << 1) | (fb(x3) << 2) | (fb(x4) << 3) | (fa(x5) << 4); - - return fc(x6); -} - -// builds the lfsr for the prng (quick calcs for hitag2_nstep()) -void buildlfsr(Hitag_State *hstate) { - uint64_t state = hstate->shiftreg; - uint64_t temp; - - temp = state ^ (state >> 1); - hstate->lfsr = state ^ (state >> 6) ^ (state >> 16) - ^ (state >> 26) ^ (state >> 30) ^ (state >> 41) - ^ (temp >> 2) ^ (temp >> 7) ^ (temp >> 22) - ^ (temp >> 42) ^ (temp >> 46); -} - - - diff --git a/tools/hitag2crack/crack5/ht2crack2utils.h b/tools/hitag2crack/crack5/ht2crack2utils.h deleted file mode 100644 index 33e0e3036..000000000 --- a/tools/hitag2crack/crack5/ht2crack2utils.h +++ /dev/null @@ -1,35 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "HardwareProfile.h" -#include "rfidler.h" -#include "util.h" - -#include "hitagcrypto.h" - -#define HEX_PER_ROW 16 - - - -void writebuf(unsigned char *buf, uint64_t val, unsigned int len); -void shexdump(unsigned char *data, int data_len); -void printbin(unsigned char *c); -void printbin2(uint64_t val, unsigned int size); -void printstate(Hitag_State *hstate); -unsigned char hex2bin(unsigned char c); -int bitn(uint64_t x, int bit); -int fnR(uint64_t x); -void rollback(Hitag_State *hstate, unsigned int steps); -int fa(unsigned int i); -int fb(unsigned int i); -int fc(unsigned int i); -int fnf(uint64_t s); -void buildlfsr(Hitag_State *hstate); diff --git a/tools/hitag2crack/crack5/ht2crack5.c b/tools/hitag2crack/crack5/ht2crack5.c index 38e57ffa7..42afbde88 100644 --- a/tools/hitag2crack/crack5/ht2crack5.c +++ b/tools/hitag2crack/crack5/ht2crack5.c @@ -18,7 +18,7 @@ #include #include #include -#include "ht2crack2utils.h" +#include "ht2crackutils.h" const uint8_t bits[9] = {20, 14, 4, 3, 1, 1, 1, 1, 1}; #define lfsr_inv(state) (((state)<<1) | (__builtin_parityll((state) & ((0xce0044c101cd>>1)|(1ull<<(47)))))) diff --git a/tools/hitag2crack/crack5/rfidler.h b/tools/hitag2crack/crack5/rfidler.h deleted file mode 100644 index 933547e6b..000000000 --- a/tools/hitag2crack/crack5/rfidler.h +++ /dev/null @@ -1,412 +0,0 @@ -/*************************************************************************** - * A copy of the GNU GPL is appended to this file. * - * * - * This licence is based on the nmap licence, and we express our gratitude * - * for the work that went into producing it. There is no other connection * - * between RFIDler and nmap either expressed or implied. * - * * - ********************** IMPORTANT RFIDler LICENSE TERMS ******************** - * * - * * - * All references to RFIDler herein imply all it's derivatives, namely: * - * * - * o RFIDler-LF Standard * - * o RFIDler-LF Lite * - * o RFIDler-LF Nekkid * - * * - * * - * RFIDler is (C) 2013-2015 Aperture Labs Ltd. * - * * - * This program is free software; you may redistribute and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE * - * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your * - * right to use, modify, and redistribute this software under certain * - * conditions. If you wish to embed RFIDler technology into proprietary * - * software or hardware, we sell alternative licenses * - * (contact sales@aperturelabs.com). * - * * - * Note that the GPL places important restrictions on "derivative works", * - * yet it does not provide a detailed definition of that term. To avoid * - * misunderstandings, we interpret that term as broadly as copyright law * - * allows. For example, we consider an application to constitute a * - * derivative work for the purpose of this license if it does any of the * - * following with any software or content covered by this license * - * ("Covered Software"): * - * * - * o Integrates source code from Covered Software. * - * * - * o Is designed specifically to execute Covered Software and parse the * - * results (as opposed to typical shell or execution-menu apps, which will * - * execute anything you tell them to). * - * * - * o Includes Covered Software in a proprietary executable installer. The * - * installers produced by InstallShield are an example of this. Including * - * RFIDler with other software in compressed or archival form does not * - * trigger this provision, provided appropriate open source decompression * - * or de-archiving software is widely available for no charge. For the * - * purposes of this license, an installer is considered to include Covered * - * Software even if it actually retrieves a copy of Covered Software from * - * another source during runtime (such as by downloading it from the * - * Internet). * - * * - * o Links (statically or dynamically) to a library which does any of the * - * above. * - * * - * o Executes a helper program, module, or script to do any of the above. * - * * - * This list is not exclusive, but is meant to clarify our interpretation * - * of derived works with some common examples. Other people may interpret * - * the plain GPL differently, so we consider this a special exception to * - * the GPL that we apply to Covered Software. Works which meet any of * - * these conditions must conform to all of the terms of this license, * - * particularly including the GPL Section 3 requirements of providing * - * source code and allowing free redistribution of the work as a whole. * - * * - * As another special exception to the GPL terms, Aperture Labs Ltd. grants* - * permission to link the code of this program with any version of the * - * OpenSSL library which is distributed under a license identical to that * - * listed in the included docs/licenses/OpenSSL.txt file, and distribute * - * linked combinations including the two. * - * * - * Any redistribution of Covered Software, including any derived works, * - * must obey and carry forward all of the terms of this license, including * - * obeying all GPL rules and restrictions. For example, source code of * - * the whole work must be provided and free redistribution must be * - * allowed. All GPL references to "this License", are to be treated as * - * including the terms and conditions of this license text as well. * - * * - * Because this license imposes special exceptions to the GPL, Covered * - * Work may not be combined (even as part of a larger work) with plain GPL * - * software. The terms, conditions, and exceptions of this license must * - * be included as well. This license is incompatible with some other open * - * source licenses as well. In some cases we can relicense portions of * - * RFIDler or grant special permissions to use it in other open source * - * software. Please contact sales@aperturelabs.com with any such requests.* - * Similarly, we don't incorporate incompatible open source software into * - * Covered Software without special permission from the copyright holders. * - * * - * If you have any questions about the licensing restrictions on using * - * RFIDler in other works, are happy to help. As mentioned above, we also * - * offer alternative license to integrate RFIDler into proprietary * - * applications and appliances. These contracts have been sold to dozens * - * of software vendors, and generally include a perpetual license as well * - * as providing for priority support and updates. They also fund the * - * continued development of RFIDler. Please email sales@aperturelabs.com * - * for further information. * - * If you have received a written license agreement or contract for * - * Covered Software stating terms other than these, you may choose to use * - * and redistribute Covered Software under those terms instead of these. * - * * - * Source is provided to this software because we believe users have a * - * right to know exactly what a program is going to do before they run it. * - * This also allows you to audit the software for security holes (none * - * have been found so far). * - * * - * Source code also allows you to port RFIDler to new platforms, fix bugs, * - * and add new features. You are highly encouraged to send your changes * - * to the RFIDler mailing list for possible incorporation into the * - * main distribution. By sending these changes to Aperture Labs Ltd. or * - * one of the Aperture Labs Ltd. development mailing lists, or checking * - * them into the RFIDler source code repository, it is understood (unless * - * you specify otherwise) that you are offering the RFIDler Project * - * (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, * - * modify, and relicense the code. RFIDler will always be available Open * - * Source, but this is important because the inability to relicense code * - * has caused devastating problems for other Free Software projects (such * - * as KDE and NASM). We also occasionally relicense the code to third * - * parties as discussed above. If you wish to specify special license * - * conditions of your contributions, just say so when you send them. * - * * - * This program is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler * - * license file for more details (it's in a COPYING file included with * - * RFIDler, and also available from * - * https://github.com/ApertureLabsLtd/RFIDler/COPYING * - * * - ***************************************************************************/ - -// Author: Adam Laurie - -#include -#include - -// BCD hardware revision for usb descriptor (usb_descriptors.c) -#define RFIDLER_HW_VERSION 0x020 - -// max sizes in BITS -#define MAXBLOCKSIZE 512 -#define MAXTAGSIZE 4096 -#define MAXUID 512 - -#define TMP_LARGE_BUFF_LEN 2048 -#define TMP_SMALL_BUFF_LEN 256 -#define ANALOGUE_BUFF_LEN 8192 - -#define COMMS_BUFFER_SIZE 128 - -#define DETECT_BUFFER_SIZE 512 - -#define SAMPLEMASK ~(BIT_1 | BIT_0) // mask to remove two bottom bits from analogue sample - we will then use those for reader & bit period - -// globals - -extern BOOL WiegandOutput; // Output wiegand data whenenver UID is read -extern BYTE *EMU_Reset_Data; // Pointer to full array of bits as bytes, stored as 0x00/0x01, '*' terminated -extern BYTE *EMU_Data; // Pointer to current location in EMU_Reset_Data -extern BYTE EMU_ThisBit; // The next data bit to transmit -extern BYTE EMU_SubCarrier_T0; // Number of Frame Clocks for sub-carrier '0' -extern BYTE EMU_SubCarrier_T1; // Number of Frame Clocks for sub-carrier '1' -extern unsigned int EMU_Repeat; // Number of times to transmit full data set -extern BOOL EMU_Background; // Emulate in the background until told to stop -extern unsigned int EMU_DataBitRate; // Number of Frame Clocks per bit -extern BYTE TmpBits[TMP_LARGE_BUFF_LEN]; // Shared scratchpad -extern BYTE ReaderPeriod; // Flag for sample display -extern unsigned char Comms_In_Buffer[COMMS_BUFFER_SIZE]; // USB/Serial buffer -extern BYTE Interface; // user interface - CLI or API -extern BYTE CommsChannel; // user comms channel - USB or UART -extern BOOL FakeRead; // flag for analogue sampler to signal it wants access to buffers during read -extern BOOL PWD_Mode; // is this tag password protected? -extern BYTE Password[9]; // 32 bits as HEX string set with LOGIN -extern unsigned int Led_Count; // LED status counter, also used for entropy -extern unsigned long Reader_Bit_Count; // Reader ISR bit counter -extern char Previous; // Reader ISR previous bit type - -// RWD (read/write device) coil state -extern BYTE RWD_State; // current state of RWD coil -extern unsigned int RWD_Fc; // field clock in uS -extern unsigned int RWD_Gap_Period; // length of command gaps in OC5 ticks -extern unsigned int RWD_Zero_Period; // length of '0' in OC5 ticks -extern unsigned int RWD_One_Period; // length of '1' in OC5 ticks -extern unsigned int RWD_Sleep_Period; // length of initial sleep to reset tag in OC5 ticks -extern unsigned int RWD_Wake_Period; // length required for tag to restart in OC5 ticks -extern unsigned int RWD_Wait_Switch_TX_RX; // length to wait when switching from TX to RX in OC5 ticks -extern unsigned int RWD_Wait_Switch_RX_TX; // length to wait when switching from RX to TX in OC5 ticks -extern unsigned int RWD_Post_Wait; // low level ISR wait period in OC5 ticks -extern unsigned int RWD_OC5_config; // Output Compare Module settings -extern unsigned int RWD_OC5_r; // Output Compare Module primary compare value -extern unsigned int RWD_OC5_rs; // Output Compare Module secondary compare value -extern BYTE RWD_Command_Buff[TMP_SMALL_BUFF_LEN]; // Command buffer, array of bits as bytes, stored as 0x00/0x01, '*' terminated -extern BYTE *RWD_Command_ThisBit; // Current command bit -extern BOOL Reader_ISR_State; // current state of reader ISR - -// NVM variables -// timings etc. that want to survive a reboot should go here -typedef struct { - BYTE Name[7]; // will be set to "RFIDler" so we can test for new device - BYTE AutoRun[128]; // optional command to run at startup - unsigned char TagType; - unsigned int PSK_Quality; - unsigned int Timeout; - unsigned int Wiegand_Pulse; - unsigned int Wiegand_Gap; - BOOL Wiegand_IdleState; - unsigned int FrameClock; - unsigned char Modulation; - unsigned int DataRate; - unsigned int DataRateSub0; - unsigned int DataRateSub1; - unsigned int DataBits; - unsigned int DataBlocks; - unsigned int BlockSize; - unsigned char SyncBits; - BYTE Sync[4]; - BOOL BiPhase; - BOOL Invert; - BOOL Manchester; - BOOL HalfDuplex; - unsigned int Repeat; - unsigned int PotLow; - unsigned int PotHigh; - unsigned int RWD_Gap_Period; - unsigned int RWD_Zero_Period; - unsigned int RWD_One_Period; - unsigned int RWD_Sleep_Period; - unsigned int RWD_Wake_Period; - unsigned int RWD_Wait_Switch_TX_RX; - unsigned int RWD_Wait_Switch_RX_TX; -} StoredConfig; - -// somewhere to store TAG data. this will be interpreted according to the TAG -// type. -typedef struct { - BYTE TagType; // raw tag type - BYTE EmulatedTagType; // tag type this tag is configured to emulate - BYTE UID[MAXUID + 1]; // Null-terminated HEX string - BYTE Data[MAXTAGSIZE]; // raw data - unsigned char DataBlocks; // number of blocks in Data field - unsigned int BlockSize; // blocksize in bits -} VirtualTag; - -extern StoredConfig RFIDlerConfig; -extern VirtualTag RFIDlerVTag; -extern BYTE TmpBuff[NVM_PAGE_SIZE]; -extern BYTE DataBuff[ANALOGUE_BUFF_LEN]; -extern unsigned int DataBuffCount; -extern const BYTE *ModulationSchemes[]; -extern const BYTE *OnOff[]; -extern const BYTE *HighLow[]; -extern const BYTE *TagTypes[]; - -// globals for ISRs -extern BYTE EmulationMode; -extern unsigned long HW_Bits; -extern BYTE HW_Skip_Bits; -extern unsigned int PSK_Min_Pulse; -extern BOOL PSK_Read_Error; -extern BOOL Manchester_Error; -extern BOOL SnifferMode; -extern unsigned int Clock_Tick_Counter; -extern BOOL Clock_Tick_Counter_Reset; - -// smart card lib -#define MAX_ATR_LEN (BYTE)33 -extern BYTE scCardATR[MAX_ATR_LEN]; -extern BYTE scATRLength; - -// RTC -extern rtccTime RTC_time; // time structure -extern rtccDate RTC_date; // date structure - -// digital pots -#define POTLOW_DEFAULT 100 -#define POTHIGH_DEFAULT 150 -#define DC_OFFSET 60 // analogue circuit DC offset (as close as we can get without using 2 LSB) -#define VOLTS_TO_POT 0.019607843F - -// RWD/clock states -#define RWD_STATE_INACTIVE 0 // RWD not in use -#define RWD_STATE_GO_TO_SLEEP 1 // RWD coil shutdown request -#define RWD_STATE_SLEEPING 2 // RWD coil shutdown for sleep period -#define RWD_STATE_WAKING 3 // RWD active for pre-determined period after reset -#define RWD_STATE_START_SEND 4 // RWD starting send of data -#define RWD_STATE_SENDING_GAP 5 // RWD sending a gap -#define RWD_STATE_SENDING_BIT 6 // RWD sending a data bit -#define RWD_STATE_POST_WAIT 7 // RWD finished sending data, now in forced wait period -#define RWD_STATE_ACTIVE 8 // RWD finished, now just clocking a carrier - -// reader ISR states -#define READER_STOPPED 0 // reader not in use -#define READER_IDLING 1 // reader ISR running to preserve timing, but not reading -#define READER_RUNNING 2 // reader reading bits - - -// user interface types -#define INTERFACE_API 0 -#define INTERFACE_CLI 1 - -// comms channel -#define COMMS_NONE 0 -#define COMMS_USB 1 -#define COMMS_UART 2 - -#define MAX_HISTORY 2 // disable most of history for now - memory issue - -// tag write retries -#define TAG_WRITE_RETRY 5 - -// modulation modes - uppdate ModulationSchemes[] in tags.c if you change this -#define MOD_MODE_NONE 0 -#define MOD_MODE_ASK_OOK 1 -#define MOD_MODE_FSK1 2 -#define MOD_MODE_FSK2 3 -#define MOD_MODE_PSK1 4 -#define MOD_MODE_PSK2 5 -#define MOD_MODE_PSK3 6 - -// TAG types - update TagTypes[] in tags.c if you add to this list -#define TAG_TYPE_NONE 0 -#define TAG_TYPE_ASK_RAW 1 -#define TAG_TYPE_FSK1_RAW 2 -#define TAG_TYPE_FSK2_RAW 3 -#define TAG_TYPE_PSK1_RAW 4 -#define TAG_TYPE_PSK2_RAW 5 -#define TAG_TYPE_PSK3_RAW 6 -#define TAG_TYPE_HITAG1 7 -#define TAG_TYPE_HITAG2 8 -#define TAG_TYPE_EM4X02 9 -#define TAG_TYPE_Q5 10 -#define TAG_TYPE_HID_26 11 -#define TAG_TYPE_INDALA_64 12 -#define TAG_TYPE_INDALA_224 13 -#define TAG_TYPE_UNIQUE 14 -#define TAG_TYPE_FDXB 15 -#define TAG_TYPE_T55X7 16 // same as Q5 but different timings and no modulation-defeat -#define TAG_TYPE_AWID_26 17 -#define TAG_TYPE_EM4X05 18 -#define TAG_TYPE_TAMAGOTCHI 19 -#define TAG_TYPE_HDX 20 // same underlying data as FDX-B, but different modulation & telegram - -// various - -#define BINARY 0 -#define HEX 1 - -#define NO_ADDRESS -1 - -#define ACK TRUE -#define NO_ACK FALSE - -#define BLOCK TRUE -#define NO_BLOCK FALSE - -#define DATA TRUE -#define NO_DATA FALSE - -#define DEBUG_PIN_ON HIGH -#define DEBUG_PIN_OFF LOW - -#define FAST FALSE -#define SLOW TRUE - -#define NO_TRIGGER 0 - -#define LOCK TRUE -#define NO_LOCK FALSE - -#define NFC_MODE TRUE -#define NO_NFC_MODE FALSE - -#define ONESHOT_READ TRUE -#define NO_ONESHOT_READ FALSE - -#define RESET TRUE -#define NO_RESET FALSE - -#define SHUTDOWN_CLOCK TRUE -#define NO_SHUTDOWN_CLOCK FALSE - -#define SYNC TRUE -#define NO_SYNC FALSE - -#define VERIFY TRUE -#define NO_VERIFY FALSE - -#define VOLATILE FALSE -#define NON_VOLATILE TRUE - -#define NEWLINE TRUE -#define NO_NEWLINE FALSE - -#define WAIT TRUE -#define NO_WAIT FALSE - -#define WIPER_HIGH 0 -#define WIPER_LOW 1 - -// conversion for time to ticks -#define US_TO_TICKS 1000000L -#define US_OVER_10_TO_TICKS 10000000L -#define US_OVER_100_TO_TICKS 100000000L -// we can't get down to this level on pic, but we want to standardise on timings, so for now we fudge it -#define CONVERT_TO_TICKS(x) ((x / 10) * (GetSystemClock() / US_OVER_10_TO_TICKS)) -#define CONVERT_TICKS_TO_US(x) (x / (GetSystemClock() / US_TO_TICKS)) -#define TIMER5_PRESCALER 16 -#define MAX_TIMER5_TICKS (65535 * TIMER5_PRESCALER) - -// other conversions - -// bits to hex digits -#define HEXDIGITS(x) (x / 4) -#define HEXTOBITS(x) (x * 4) diff --git a/tools/hitag2crack/crack5/util.h b/tools/hitag2crack/crack5/util.h deleted file mode 100644 index c2399c37c..000000000 --- a/tools/hitag2crack/crack5/util.h +++ /dev/null @@ -1,147 +0,0 @@ -/*************************************************************************** - * A copy of the GNU GPL is appended to this file. * - * * - * This licence is based on the nmap licence, and we express our gratitude * - * for the work that went into producing it. There is no other connection * - * between RFIDler and nmap either expressed or implied. * - * * - ********************** IMPORTANT RFIDler LICENSE TERMS ******************** - * * - * * - * All references to RFIDler herein imply all it's derivatives, namely: * - * * - * o RFIDler-LF Standard * - * o RFIDler-LF Lite * - * o RFIDler-LF Nekkid * - * * - * * - * RFIDler is (C) 2013-2015 Aperture Labs Ltd. * - * * - * This program is free software; you may redistribute and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE * - * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your * - * right to use, modify, and redistribute this software under certain * - * conditions. If you wish to embed RFIDler technology into proprietary * - * software or hardware, we sell alternative licenses * - * (contact sales@aperturelabs.com). * - * * - * Note that the GPL places important restrictions on "derivative works", * - * yet it does not provide a detailed definition of that term. To avoid * - * misunderstandings, we interpret that term as broadly as copyright law * - * allows. For example, we consider an application to constitute a * - * derivative work for the purpose of this license if it does any of the * - * following with any software or content covered by this license * - * ("Covered Software"): * - * * - * o Integrates source code from Covered Software. * - * * - * o Is designed specifically to execute Covered Software and parse the * - * results (as opposed to typical shell or execution-menu apps, which will * - * execute anything you tell them to). * - * * - * o Includes Covered Software in a proprietary executable installer. The * - * installers produced by InstallShield are an example of this. Including * - * RFIDler with other software in compressed or archival form does not * - * trigger this provision, provided appropriate open source decompression * - * or de-archiving software is widely available for no charge. For the * - * purposes of this license, an installer is considered to include Covered * - * Software even if it actually retrieves a copy of Covered Software from * - * another source during runtime (such as by downloading it from the * - * Internet). * - * * - * o Links (statically or dynamically) to a library which does any of the * - * above. * - * * - * o Executes a helper program, module, or script to do any of the above. * - * * - * This list is not exclusive, but is meant to clarify our interpretation * - * of derived works with some common examples. Other people may interpret * - * the plain GPL differently, so we consider this a special exception to * - * the GPL that we apply to Covered Software. Works which meet any of * - * these conditions must conform to all of the terms of this license, * - * particularly including the GPL Section 3 requirements of providing * - * source code and allowing free redistribution of the work as a whole. * - * * - * As another special exception to the GPL terms, Aperture Labs Ltd. grants* - * permission to link the code of this program with any version of the * - * OpenSSL library which is distributed under a license identical to that * - * listed in the included docs/licenses/OpenSSL.txt file, and distribute * - * linked combinations including the two. * - * * - * Any redistribution of Covered Software, including any derived works, * - * must obey and carry forward all of the terms of this license, including * - * obeying all GPL rules and restrictions. For example, source code of * - * the whole work must be provided and free redistribution must be * - * allowed. All GPL references to "this License", are to be treated as * - * including the terms and conditions of this license text as well. * - * * - * Because this license imposes special exceptions to the GPL, Covered * - * Work may not be combined (even as part of a larger work) with plain GPL * - * software. The terms, conditions, and exceptions of this license must * - * be included as well. This license is incompatible with some other open * - * source licenses as well. In some cases we can relicense portions of * - * RFIDler or grant special permissions to use it in other open source * - * software. Please contact sales@aperturelabs.com with any such requests.* - * Similarly, we don't incorporate incompatible open source software into * - * Covered Software without special permission from the copyright holders. * - * * - * If you have any questions about the licensing restrictions on using * - * RFIDler in other works, are happy to help. As mentioned above, we also * - * offer alternative license to integrate RFIDler into proprietary * - * applications and appliances. These contracts have been sold to dozens * - * of software vendors, and generally include a perpetual license as well * - * as providing for priority support and updates. They also fund the * - * continued development of RFIDler. Please email sales@aperturelabs.com * - * for further information. * - * If you have received a written license agreement or contract for * - * Covered Software stating terms other than these, you may choose to use * - * and redistribute Covered Software under those terms instead of these. * - * * - * Source is provided to this software because we believe users have a * - * right to know exactly what a program is going to do before they run it. * - * This also allows you to audit the software for security holes (none * - * have been found so far). * - * * - * Source code also allows you to port RFIDler to new platforms, fix bugs, * - * and add new features. You are highly encouraged to send your changes * - * to the RFIDler mailing list for possible incorporation into the * - * main distribution. By sending these changes to Aperture Labs Ltd. or * - * one of the Aperture Labs Ltd. development mailing lists, or checking * - * them into the RFIDler source code repository, it is understood (unless * - * you specify otherwise) that you are offering the RFIDler Project * - * (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, * - * modify, and relicense the code. RFIDler will always be available Open * - * Source, but this is important because the inability to relicense code * - * has caused devastating problems for other Free Software projects (such * - * as KDE and NASM). We also occasionally relicense the code to third * - * parties as discussed above. If you wish to specify special license * - * conditions of your contributions, just say so when you send them. * - * * - * This program is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler * - * license file for more details (it's in a COPYING file included with * - * RFIDler, and also available from * - * https://github.com/ApertureLabsLtd/RFIDler/COPYING * - * * - ***************************************************************************/ - -// Author: Adam Laurie - -/* - * Hitag Crypto support macros - * These macros reverse the bit order in a byte, or *within* each byte of a - * 16 , 32 or 64 bit unsigned integer. (Not across the whole 16 etc bits.) - */ -#define rev8(X) ((((X) >> 7) &1) + (((X) >> 5) &2) + (((X) >> 3) &4) \ - + (((X) >> 1) &8) + (((X) << 1) &16) + (((X) << 3) &32) \ - + (((X) << 5) &64) + (((X) << 7) &128) ) -#define rev16(X) (rev8 (X) + (rev8 (X >> 8) << 8)) -#define rev32(X) (rev16(X) + (rev16(X >> 16) << 16)) -#define rev64(X) (rev32(X) + (rev32(X >> 32) << 32)) - - -unsigned long hexreversetoulong(BYTE *hex); -unsigned long long hexreversetoulonglong(BYTE *hex); - diff --git a/tools/hitag2crack/crack5/utilpart.c b/tools/hitag2crack/crack5/utilpart.c deleted file mode 100644 index c46148491..000000000 --- a/tools/hitag2crack/crack5/utilpart.c +++ /dev/null @@ -1,180 +0,0 @@ -/*************************************************************************** - * A copy of the GNU GPL is appended to this file. * - * * - * This licence is based on the nmap licence, and we express our gratitude * - * for the work that went into producing it. There is no other connection * - * between RFIDler and nmap either expressed or implied. * - * * - ********************** IMPORTANT RFIDler LICENSE TERMS ******************** - * * - * * - * All references to RFIDler herein imply all it's derivatives, namely: * - * * - * o RFIDler-LF Standard * - * o RFIDler-LF Lite * - * o RFIDler-LF Nekkid * - * * - * * - * RFIDler is (C) 2013-2014 Aperture Labs Ltd. * - * * - * This program is free software; you may redistribute and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE * - * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your * - * right to use, modify, and redistribute this software under certain * - * conditions. If you wish to embed RFIDler technology into proprietary * - * software or hardware, we sell alternative licenses * - * (contact sales@aperturelabs.com). * - * * - * Note that the GPL places important restrictions on "derivative works", * - * yet it does not provide a detailed definition of that term. To avoid * - * misunderstandings, we interpret that term as broadly as copyright law * - * allows. For example, we consider an application to constitute a * - * derivative work for the purpose of this license if it does any of the * - * following with any software or content covered by this license * - * ("Covered Software"): * - * * - * o Integrates source code from Covered Software. * - * * - * o Is designed specifically to execute Covered Software and parse the * - * results (as opposed to typical shell or execution-menu apps, which will * - * execute anything you tell them to). * - * * - * o Includes Covered Software in a proprietary executable installer. The * - * installers produced by InstallShield are an example of this. Including * - * RFIDler with other software in compressed or archival form does not * - * trigger this provision, provided appropriate open source decompression * - * or de-archiving software is widely available for no charge. For the * - * purposes of this license, an installer is considered to include Covered * - * Software even if it actually retrieves a copy of Covered Software from * - * another source during runtime (such as by downloading it from the * - * Internet). * - * * - * o Links (statically or dynamically) to a library which does any of the * - * above. * - * * - * o Executes a helper program, module, or script to do any of the above. * - * * - * This list is not exclusive, but is meant to clarify our interpretation * - * of derived works with some common examples. Other people may interpret * - * the plain GPL differently, so we consider this a special exception to * - * the GPL that we apply to Covered Software. Works which meet any of * - * these conditions must conform to all of the terms of this license, * - * particularly including the GPL Section 3 requirements of providing * - * source code and allowing free redistribution of the work as a whole. * - * * - * As another special exception to the GPL terms, Aperture Labs Ltd. grants* - * permission to link the code of this program with any version of the * - * OpenSSL library which is distributed under a license identical to that * - * listed in the included docs/licenses/OpenSSL.txt file, and distribute * - * linked combinations including the two. * - * * - * Any redistribution of Covered Software, including any derived works, * - * must obey and carry forward all of the terms of this license, including * - * obeying all GPL rules and restrictions. For example, source code of * - * the whole work must be provided and free redistribution must be * - * allowed. All GPL references to "this License", are to be treated as * - * including the terms and conditions of this license text as well. * - * * - * Because this license imposes special exceptions to the GPL, Covered * - * Work may not be combined (even as part of a larger work) with plain GPL * - * software. The terms, conditions, and exceptions of this license must * - * be included as well. This license is incompatible with some other open * - * source licenses as well. In some cases we can relicense portions of * - * RFIDler or grant special permissions to use it in other open source * - * software. Please contact sales@aperturelabs.com with any such requests.* - * Similarly, we don't incorporate incompatible open source software into * - * Covered Software without special permission from the copyright holders. * - * * - * If you have any questions about the licensing restrictions on using * - * RFIDler in other works, are happy to help. As mentioned above, we also * - * offer alternative license to integrate RFIDler into proprietary * - * applications and appliances. These contracts have been sold to dozens * - * of software vendors, and generally include a perpetual license as well * - * as providing for priority support and updates. They also fund the * - * continued development of RFIDler. Please email sales@aperturelabs.com * - * for further information. * - * If you have received a written license agreement or contract for * - * Covered Software stating terms other than these, you may choose to use * - * and redistribute Covered Software under those terms instead of these. * - * * - * Source is provided to this software because we believe users have a * - * right to know exactly what a program is going to do before they run it. * - * This also allows you to audit the software for security holes (none * - * have been found so far). * - * * - * Source code also allows you to port RFIDler to new platforms, fix bugs, * - * and add new features. You are highly encouraged to send your changes * - * to the RFIDler mailing list for possible incorporation into the * - * main distribution. By sending these changes to Aperture Labs Ltd. or * - * one of the Aperture Labs Ltd. development mailing lists, or checking * - * them into the RFIDler source code repository, it is understood (unless * - * you specify otherwise) that you are offering the RFIDler Project * - * (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, * - * modify, and relicense the code. RFIDler will always be available Open * - * Source, but this is important because the inability to relicense code * - * has caused devastating problems for other Free Software projects (such * - * as KDE and NASM). We also occasionally relicense the code to third * - * parties as discussed above. If you wish to specify special license * - * conditions of your contributions, just say so when you send them. * - * * - * This program is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler * - * license file for more details (it's in a COPYING file included with * - * RFIDler, and also available from * - * https://github.com/ApertureLabsLtd/RFIDler/COPYING * - * * - ***************************************************************************/ - -// Author: Adam Laurie - - -#include -#include -#include "HardwareProfile.h" -#include "util.h" -#include "rfidler.h" -//#include "comms.h" - -// rtc -rtccTime RTC_time; // time structure -rtccDate RTC_date; // date structure - -// convert byte-reversed 8 digit hex to unsigned long -unsigned long hexreversetoulong(BYTE *hex) { - unsigned long ret = 0L; - unsigned int x; - BYTE i; - - if (strlen(hex) != 8) - return 0L; - - for (i = 0 ; i < 4 ; ++i) { - if (sscanf(hex, "%2X", &x) != 1) - return 0L; - ret += ((unsigned long) x) << i * 8; - hex += 2; - } - return ret; -} - -// convert byte-reversed 12 digit hex to unsigned long -unsigned long long hexreversetoulonglong(BYTE *hex) { - unsigned long long ret = 0LL; - BYTE tmp[9]; - - // this may seem an odd way to do it, but weird compiler issues were - // breaking direct conversion! - - tmp[8] = '\0'; - memset(tmp + 4, '0', 4); - memcpy(tmp, hex + 8, 4); - ret = hexreversetoulong(tmp); - ret <<= 32; - memcpy(tmp, hex, 8); - ret += hexreversetoulong(tmp); - return ret; -} - - diff --git a/tools/hitag2crack/crack5gpu/.gitignore b/tools/hitag2crack/crack5gpu/.gitignore new file mode 100644 index 000000000..ffa667731 --- /dev/null +++ b/tools/hitag2crack/crack5gpu/.gitignore @@ -0,0 +1,3 @@ +ht2crack5gpu + +ht2crack5gpu.exe diff --git a/tools/hitag2crack/crack5gpu/HardwareProfile.h b/tools/hitag2crack/crack5gpu/HardwareProfile.h deleted file mode 100644 index bce139042..000000000 --- a/tools/hitag2crack/crack5gpu/HardwareProfile.h +++ /dev/null @@ -1,524 +0,0 @@ -/*************************************************************************** - * A copy of the GNU GPL is appended to this file. * - * * - * This licence is based on the nmap licence, and we express our gratitude * - * for the work that went into producing it. There is no other connection * - * between RFIDler and nmap either expressed or implied. * - * * - ********************** IMPORTANT RFIDler LICENSE TERMS ******************** - * * - * * - * All references to RFIDler herein imply all it's derivatives, namely: * - * * - * o RFIDler-LF Standard * - * o RFIDler-LF Lite * - * o RFIDler-LF Nekkid * - * * - * * - * RFIDler is (C) 2013-2014 Aperture Labs Ltd. * - * * - * This program is free software; you may redistribute and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE * - * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your * - * right to use, modify, and redistribute this software under certain * - * conditions. If you wish to embed RFIDler technology into proprietary * - * software or hardware, we sell alternative licenses * - * (contact sales@aperturelabs.com). * - * * - * Note that the GPL places important restrictions on "derivative works", * - * yet it does not provide a detailed definition of that term. To avoid * - * misunderstandings, we interpret that term as broadly as copyright law * - * allows. For example, we consider an application to constitute a * - * derivative work for the purpose of this license if it does any of the * - * following with any software or content covered by this license * - * ("Covered Software"): * - * * - * o Integrates source code from Covered Software. * - * * - * o Is designed specifically to execute Covered Software and parse the * - * results (as opposed to typical shell or execution-menu apps, which will * - * execute anything you tell them to). * - * * - * o Includes Covered Software in a proprietary executable installer. The * - * installers produced by InstallShield are an example of this. Including * - * RFIDler with other software in compressed or archival form does not * - * trigger this provision, provided appropriate open source decompression * - * or de-archiving software is widely available for no charge. For the * - * purposes of this license, an installer is considered to include Covered * - * Software even if it actually retrieves a copy of Covered Software from * - * another source during runtime (such as by downloading it from the * - * Internet). * - * * - * o Links (statically or dynamically) to a library which does any of the * - * above. * - * * - * o Executes a helper program, module, or script to do any of the above. * - * * - * This list is not exclusive, but is meant to clarify our interpretation * - * of derived works with some common examples. Other people may interpret * - * the plain GPL differently, so we consider this a special exception to * - * the GPL that we apply to Covered Software. Works which meet any of * - * these conditions must conform to all of the terms of this license, * - * particularly including the GPL Section 3 requirements of providing * - * source code and allowing free redistribution of the work as a whole. * - * * - * As another special exception to the GPL terms, Aperture Labs Ltd. grants* - * permission to link the code of this program with any version of the * - * OpenSSL library which is distributed under a license identical to that * - * listed in the included docs/licenses/OpenSSL.txt file, and distribute * - * linked combinations including the two. * - * * - * Any redistribution of Covered Software, including any derived works, * - * must obey and carry forward all of the terms of this license, including * - * obeying all GPL rules and restrictions. For example, source code of * - * the whole work must be provided and free redistribution must be * - * allowed. All GPL references to "this License", are to be treated as * - * including the terms and conditions of this license text as well. * - * * - * Because this license imposes special exceptions to the GPL, Covered * - * Work may not be combined (even as part of a larger work) with plain GPL * - * software. The terms, conditions, and exceptions of this license must * - * be included as well. This license is incompatible with some other open * - * source licenses as well. In some cases we can relicense portions of * - * RFIDler or grant special permissions to use it in other open source * - * software. Please contact sales@aperturelabs.com with any such requests.* - * Similarly, we don't incorporate incompatible open source software into * - * Covered Software without special permission from the copyright holders. * - * * - * If you have any questions about the licensing restrictions on using * - * RFIDler in other works, are happy to help. As mentioned above, we also * - * offer alternative license to integrate RFIDler into proprietary * - * applications and appliances. These contracts have been sold to dozens * - * of software vendors, and generally include a perpetual license as well * - * as providing for priority support and updates. They also fund the * - * continued development of RFIDler. Please email sales@aperturelabs.com * - * for further information. * - * If you have received a written license agreement or contract for * - * Covered Software stating terms other than these, you may choose to use * - * and redistribute Covered Software under those terms instead of these. * - * * - * Source is provided to this software because we believe users have a * - * right to know exactly what a program is going to do before they run it. * - * This also allows you to audit the software for security holes (none * - * have been found so far). * - * * - * Source code also allows you to port RFIDler to new platforms, fix bugs, * - * and add new features. You are highly encouraged to send your changes * - * to the RFIDler mailing list for possible incorporation into the * - * main distribution. By sending these changes to Aperture Labs Ltd. or * - * one of the Aperture Labs Ltd. development mailing lists, or checking * - * them into the RFIDler source code repository, it is understood (unless * - * you specify otherwise) that you are offering the RFIDler Project * - * (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, * - * modify, and relicense the code. RFIDler will always be available Open * - * Source, but this is important because the inability to relicense code * - * has caused devastating problems for other Free Software projects (such * - * as KDE and NASM). We also occasionally relicense the code to third * - * parties as discussed above. If you wish to specify special license * - * conditions of your contributions, just say so when you send them. * - * * - * This program is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler * - * license file for more details (it's in a COPYING file included with * - * RFIDler, and also available from * - * https://github.com/ApertureLabsLtd/RFIDler/COPYING * - * * - ***************************************************************************/ - -// Author: Adam Laurie - - - -#ifndef HARDWARE_PROFILE_UBW32_H -#define HARDWARE_PROFILE_UBW32_H - -//#include "plib.h" -typedef char BOOL; -typedef char BYTE; -typedef int rtccTime; -typedef int rtccDate; - - -#ifndef __PIC32MX__ -#define __PIC32MX__ -#endif - -#define GetSystemClock() (80000000ul) -#define GetPeripheralClock() (GetSystemClock()) -#define GetInstructionClock() (GetSystemClock()) - -//#define USE_SELF_POWER_SENSE_IO -#define tris_self_power TRISAbits.TRISA2 // Input -#define self_power 1 - -//#define USE_USB_BUS_SENSE_IO -#define tris_usb_bus_sense TRISBbits.TRISB5 // Input -#define USB_BUS_SENSE 1 - -// LEDs -#define mLED_1 LATEbits.LATE3 - -#define mLED_2 LATEbits.LATE2 -#define mLED_Comms mLED_2 - -#define mLED_3 LATEbits.LATE1 -#define mLED_Clock mLED_3 - -#define mLED_4 LATEbits.LATE0 -#define mLED_Emulate mLED_4 - -#define mLED_5 LATGbits.LATG6 -#define mLED_Read mLED_5 - -#define mLED_6 LATAbits.LATA15 -#define mLED_User mLED_6 - -#define mLED_7 LATDbits.LATD11 -#define mLED_Error mLED_7 - -// active low -#define mLED_ON 0 -#define mLED_OFF 1 - -#define mGetLED_1() mLED_1 -#define mGetLED_USB() mLED_1 -#define mGetLED_2() mLED_2 -#define mGetLED_Comms() mLED_2 -#define mGetLED_3() mLED_3 -#define mGetLED_Clock() mLED_3 -#define mGetLED_4() mLED_4 -#define mGetLED_Emulate() mLED_4 -#define mGetLED_5() mLED_5 -#define mGetLED_Read() mLED_5 -#define mGetLED_6() mLED_6 -#define mGetLED_User() mLED_6 -#define mGetLED_7() mLED_7 -#define mGetLED_Error() mLED_7 - -#define mLED_1_On() mLED_1 = mLED_ON -#define mLED_USB_On() mLED_1_On() -#define mLED_2_On() mLED_2 = mLED_ON -#define mLED_Comms_On() mLED_2_On() -#define mLED_3_On() mLED_3 = mLED_ON -#define mLED_Clock_On() mLED_3_On() -#define mLED_4_On() mLED_4 = mLED_ON -#define mLED_Emulate_On() mLED_4_On() -#define mLED_5_On() mLED_5 = mLED_ON -#define mLED_Read_On() mLED_5_On() -#define mLED_6_On() mLED_6 = mLED_ON -#define mLED_User_On() mLED_6_On() -#define mLED_7_On() mLED_7 = mLED_ON -#define mLED_Error_On() mLED_7_On() - -#define mLED_1_Off() mLED_1 = mLED_OFF -#define mLED_USB_Off() mLED_1_Off() -#define mLED_2_Off() mLED_2 = mLED_OFF -#define mLED_Comms_Off() mLED_2_Off() -#define mLED_3_Off() mLED_3 = mLED_OFF -#define mLED_Clock_Off() mLED_3_Off() -#define mLED_4_Off() mLED_4 = mLED_OFF -#define mLED_Emulate_Off() mLED_4_Off() -#define mLED_5_Off() mLED_5 = mLED_OFF -#define mLED_Read_Off() mLED_5_Off() -#define mLED_6_Off() mLED_6 = mLED_OFF -#define mLED_User_Off() mLED_6_Off() -#define mLED_7_Off() mLED_7 = mLED_OFF -#define mLED_Error_Off() mLED_7_Off() - -#define mLED_1_Toggle() mLED_1 = !mLED_1 -#define mLED_USB_Toggle() mLED_1_Toggle() -#define mLED_2_Toggle() mLED_2 = !mLED_2 -#define mLED_Comms_Toggle() mLED_2_Toggle() -#define mLED_3_Toggle() mLED_3 = !mLED_3 -#define mLED_Clock_Toggle() mLED_3_Toggle() -#define mLED_4_Toggle() mLED_4 = !mLED_4 -#define mLED_Emulate_Toggle() mLED_4_Toggle() -#define mLED_5_Toggle() mLED_5 = !mLED_5 -#define mLED_Read_Toggle( ) mLED_5_Toggle() -#define mLED_6_Toggle() mLED_6 = !mLED_6 -#define mLED_User_Toggle() mLED_6_Toggle() -#define mLED_7_Toggle() mLED_7 = !mLED_7 -#define mLED_Error_Toggle() mLED_7_Toggle() - -#define mLED_All_On() { mLED_1_On(); mLED_2_On(); mLED_3_On(); mLED_4_On(); mLED_5_On(); mLED_6_On(); mLED_7_On(); } -#define mLED_All_Off() { mLED_1_Off(); mLED_2_Off(); mLED_3_Off(); mLED_4_Off(); mLED_5_Off(); mLED_6_Off(); mLED_7_Off(); } - -// usb status lights -#define mLED_Both_Off() {mLED_USB_Off();mLED_Comms_Off();} -#define mLED_Both_On() {mLED_USB_On();mLED_Comms_On();} -#define mLED_Only_USB_On() {mLED_USB_On();mLED_Comms_Off();} -#define mLED_Only_Comms_On() {mLED_USB_Off();mLED_Comms_On();} - -/** SWITCH *********************************************************/ -#define swBootloader PORTEbits.RE7 -#define swUser PORTEbits.RE6 - -/** I/O pin definitions ********************************************/ -#define INPUT_PIN 1 -#define OUTPUT_PIN 0 - -#define TRUE 1 -#define FALSE 0 - -#define ENABLE 1 -#define DISABE 0 - -#define EVEN 0 -#define ODD 1 - -#define LOW FALSE -#define HIGH TRUE - -#define CLOCK_ON LOW -#define CLOCK_OFF HIGH - -// output coil control - select between reader/emulator circuits -#define COIL_MODE LATBbits.LATB4 -#define COIL_MODE_READER() COIL_MODE= LOW -#define COIL_MODE_EMULATOR() COIL_MODE= HIGH - -// coil for emulation -#define COIL_OUT LATGbits.LATG9 -#define COIL_OUT_HIGH() COIL_OUT=HIGH -#define COIL_OUT_LOW() COIL_OUT=LOW - -// door relay (active low) -#define DOOR_RELAY LATAbits.LATA14 -#define DOOR_RELAY_OPEN() DOOR_RELAY= HIGH -#define DOOR_RELAY_CLOSE() DOOR_RELAY= LOW - -// inductance/capacitance freq -#define IC_FREQUENCY PORTAbits.RA2 - -#define SNIFFER_COIL PORTDbits.RD12 // external reader clock detect -#define READER_ANALOGUE PORTBbits.RB11 // reader coil analogue -#define DIV_LOW_ANALOGUE PORTBbits.RB12 // voltage divider LOW analogue -#define DIV_HIGH_ANALOGUE PORTBbits.RB13 // voltage divider HIGH analogue - -// clock coil (normally controlled by OC Module, but defined here so we can force it high or low) -#define CLOCK_COIL PORTDbits.RD4 -#define CLOCK_COIL_MOVED PORTDbits.RD0 // temporary for greenwire - -// digital output after analogue reader circuit -#define READER_DATA PORTDbits.RD8 - -// trace / debug -#define DEBUG_PIN_1 LATCbits.LATC1 -#define DEBUG_PIN_1_TOGGLE() DEBUG_PIN_1= !DEBUG_PIN_1 -#define DEBUG_PIN_2 LATCbits.LATC2 -#define DEBUG_PIN_2_TOGGLE() DEBUG_PIN_2= !DEBUG_PIN_2 -#define DEBUG_PIN_3 LATCbits.LATC3 -#define DEBUG_PIN_3_TOGGLE() DEBUG_PIN_3= !DEBUG_PIN_3 -#define DEBUG_PIN_4 LATEbits.LATE5 -#define DEBUG_PIN_4_TOGGLE() DEBUG_PIN_4= !DEBUG_PIN_4 - -// spi (sdi1) for sd card (not directly referenced) -//#define SD_CARD_RX LATCbits.LATC4 -//#define SD_CARD_TX LATDbits.LATD0 -//#define SD_CARD_CLK LATDbits.LATD10 -//#define SD_CARD_SS LATDbits.LATD9 -// spi for SD card -#define SD_CARD_DET LATFbits.LATF0 -#define SD_CARD_WE LATFbits.LATF1 // write enable - unused for microsd but allocated anyway as library checks it -// (held LOW by default - cut solder bridge to GND to free pin if required) -#define SPI_SD SPI_CHANNEL1 -#define SPI_SD_BUFF SPI1BUF -#define SPI_SD_STAT SPI1STATbits -// see section below for more defines! - -// iso 7816 smartcard -// microchip SC module defines pins so we don't need to, but -// they are listed here to help avoid conflicts -#define ISO_7816_RX LATBbits.LATF2 // RX -#define ISO_7816_TX LATBbits.LATF8 // TX -#define ISO_7816_VCC LATBbits.LATB9 // Power -#define ISO_7816_CLK LATCbits.LATD1 // Clock -#define ISO_7816_RST LATEbits.LATE8 // Reset - -// user LED -#define USER_LED LATDbits.LATD7 -#define USER_LED_ON() LATDbits.LATD7=1 -#define USER_LED_OFF() LATDbits.LATD7=0 - -// LCR -#define LCR_CALIBRATE LATBbits.LATB5 - -// wiegand / clock & data -#define WIEGAND_IN_0 PORTDbits.RD5 -#define WIEGAND_IN_0_PULLUP CNPUEbits.CNPUE14 -#define WIEGAND_IN_0_PULLDOWN CNPDbits.CNPD14 -#define WIEGAND_IN_1 PORTDbits.RD6 -#define WIEGAND_IN_1_PULLUP CNPUEbits.CNPUE15 -#define WIEGAND_IN_1_PULLDOWN CNPDbits.CNPD15 -#define CAND_IN_DATA WIEGAND_IN_0 -#define CAND_IN_CLOCK WIEGAND_IN_1 - -#define WIEGAND_OUT_0 LATDbits.LATD3 -#define WIEGAND_OUT_1 LATDbits.LATD2 -#define WIEGAND_OUT_0_TRIS TRISDbits.TRISD3 -#define WIEGAND_OUT_1_TRIS TRISDbits.TRISD2 -#define CAND_OUT_DATA WIEGAND_OUT_0 -#define CAND_OUT_CLOCK WIEGAND_OUT_1 - -// connect/disconnect reader clock from coil - used to send RWD signals by creating gaps in carrier -#define READER_CLOCK_ENABLE LATEbits.LATE9 -#define READER_CLOCK_ENABLE_ON() READER_CLOCK_ENABLE=CLOCK_ON -#define READER_CLOCK_ENABLE_OFF(x) {READER_CLOCK_ENABLE=CLOCK_OFF; COIL_OUT=x;} - -// these input pins must NEVER bet set to output or they will cause short circuits! -// they can be used to see data from reader before it goes into or gate -#define OR_IN_A PORTAbits.RA4 -#define OR_IN_B PORTAbits.RA5 - - -// CNCON and CNEN are set to allow wiegand input pin weak pullups to be switched on -#define Init_GPIO() { \ - CNCONbits.ON= TRUE; \ - CNENbits.CNEN14= TRUE; \ - CNENbits.CNEN15= TRUE; \ - TRISAbits.TRISA2= INPUT_PIN; \ - TRISAbits.TRISA4= INPUT_PIN; \ - TRISAbits.TRISA5= INPUT_PIN; \ - TRISAbits.TRISA14= OUTPUT_PIN; \ - TRISAbits.TRISA15= OUTPUT_PIN; \ - TRISBbits.TRISB4= OUTPUT_PIN; \ - TRISBbits.TRISB5= OUTPUT_PIN; \ - TRISBbits.TRISB9= OUTPUT_PIN; \ - TRISBbits.TRISB11= INPUT_PIN; \ - TRISBbits.TRISB12= INPUT_PIN; \ - TRISBbits.TRISB13= INPUT_PIN; \ - TRISCbits.TRISC1= OUTPUT_PIN; \ - TRISCbits.TRISC2= OUTPUT_PIN; \ - TRISCbits.TRISC3= OUTPUT_PIN; \ - TRISCbits.TRISC4= INPUT_PIN; \ - TRISDbits.TRISD0= INPUT_PIN; \ - TRISDbits.TRISD1= OUTPUT_PIN; \ - TRISDbits.TRISD2= OUTPUT_PIN; \ - TRISDbits.TRISD3= OUTPUT_PIN; \ - TRISDbits.TRISD4= OUTPUT_PIN; \ - TRISDbits.TRISD5= INPUT_PIN; \ - TRISDbits.TRISD6= INPUT_PIN; \ - TRISDbits.TRISD7= OUTPUT_PIN; \ - TRISDbits.TRISD8= INPUT_PIN; \ - TRISDbits.TRISD11= OUTPUT_PIN; \ - TRISDbits.TRISD12= INPUT_PIN; \ - TRISEbits.TRISE0= OUTPUT_PIN; \ - TRISEbits.TRISE1= OUTPUT_PIN; \ - TRISEbits.TRISE2= OUTPUT_PIN; \ - TRISEbits.TRISE3= OUTPUT_PIN; \ - TRISEbits.TRISE5= OUTPUT_PIN; \ - TRISEbits.TRISE6= INPUT_PIN; \ - TRISEbits.TRISE7= INPUT_PIN; \ - TRISEbits.TRISE8= OUTPUT_PIN; \ - TRISEbits.TRISE9= OUTPUT_PIN; \ - TRISFbits.TRISF0= INPUT_PIN; \ - TRISFbits.TRISF1= INPUT_PIN; \ - TRISFbits.TRISF2= INPUT_PIN; \ - TRISFbits.TRISF8= OUTPUT_PIN; \ - TRISGbits.TRISG6= OUTPUT_PIN; \ - TRISGbits.TRISG12= INPUT_PIN; \ - TRISGbits.TRISG13= INPUT_PIN; \ - TRISGbits.TRISG9= OUTPUT_PIN; \ - LATBbits.LATB9= LOW; \ - LATCbits.LATC1= LOW; \ - LATCbits.LATC2= LOW; \ - LATCbits.LATC3= LOW; \ - LATDbits.LATD2= WIEGAND_IN_1; \ - LATDbits.LATD3= WIEGAND_IN_0; \ - LATEbits.LATE5= LOW; \ - LATEbits.LATE9= HIGH; \ - } - -// uart3 (CLI/API) speed -#define BAUDRATE3 115200UL -#define BRG_DIV3 4 -#define BRGH3 1 - -// spi for potentiometer -#define SPI_POT SPI_CHANNEL4 -#define SPI_POT_BUFF SPI4BUF -#define SPI_POT_STAT SPI4STATbits - -// spi for sd card - defines required for Microchip SD-SPI libs -// define interface type -#define USE_SD_INTERFACE_WITH_SPI - -#define MDD_USE_SPI_1 -#define SPI_START_CFG_1 (PRI_PRESCAL_64_1 | SEC_PRESCAL_8_1 | MASTER_ENABLE_ON | SPI_CKE_ON | SPI_SMP_ON) -#define SPI_START_CFG_2 (SPI_ENABLE) -// Define the SPI frequency -#define SPI_FREQUENCY (20000000) -// Description: SD-SPI Card Detect Input bit -#define SD_CD PORTFbits.RF0 -// Description: SD-SPI Card Detect TRIS bit -#define SD_CD_TRIS TRISFbits.TRISF0 -// Description: SD-SPI Write Protect Check Input bit -#define SD_WE PORTFbits.RF1 -// Description: SD-SPI Write Protect Check TRIS bit -#define SD_WE_TRIS TRISFbits.TRISF1 -// Description: The main SPI control register -#define SPICON1 SPI1CON -// Description: The SPI status register -#define SPISTAT SPI1STAT -// Description: The SPI Buffer -#define SPIBUF SPI1BUF -// Description: The receive buffer full bit in the SPI status register -#define SPISTAT_RBF SPI1STATbits.SPIRBF -// Description: The bitwise define for the SPI control register (i.e. _____bits) -#define SPICON1bits SPI1CONbits -// Description: The bitwise define for the SPI status register (i.e. _____bits) -#define SPISTATbits SPI1STATbits -// Description: The enable bit for the SPI module -#define SPIENABLE SPICON1bits.ON -// Description: The definition for the SPI baud rate generator register (PIC32) -#define SPIBRG SPI1BRG -// Description: The TRIS bit for the SCK pin -#define SPICLOCK TRISDbits.TRISD10 -// Description: The TRIS bit for the SDI pin -#define SPIIN TRISCbits.TRISC4 -// Description: The TRIS bit for the SDO pin -#define SPIOUT TRISDbits.TRISD0 -#define SD_CS LATDbits.LATD9 -// Description: SD-SPI Chip Select TRIS bit -#define SD_CS_TRIS TRISDbits.TRISD9 -//SPI library functions -#define putcSPI putcSPI1 -#define getcSPI getcSPI1 -#define OpenSPI(config1, config2) OpenSPI1(config1, config2) - -// Define setup parameters for OpenADC10 function -// Turn module on | Ouput in integer format | Trigger mode auto | Enable autosample -#define ADC_CONFIG1 (ADC_FORMAT_INTG | ADC_CLK_AUTO | ADC_AUTO_SAMPLING_ON) -// ADC ref external | Disable offset test | Disable scan mode | Perform 2 samples | Use dual buffers | Use alternate mode -#define ADC_CONFIG2 (ADC_VREF_AVDD_AVSS | ADC_OFFSET_CAL_DISABLE | ADC_SCAN_OFF | ADC_SAMPLES_PER_INT_1 | ADC_ALT_BUF_ON | ADC_ALT_INPUT_ON) - -// Use ADC internal clock | Set sample time -#define ADC_CONFIG3 (ADC_CONV_CLK_INTERNAL_RC | ADC_SAMPLE_TIME_0) - -// slow sample rate for tuning coils -#define ADC_CONFIG2_SLOW (ADC_VREF_AVDD_AVSS | ADC_OFFSET_CAL_DISABLE | ADC_SCAN_OFF | ADC_SAMPLES_PER_INT_16 | ADC_ALT_BUF_ON | ADC_ALT_INPUT_ON) -#define ADC_CONFIG3_SLOW (ADC_CONV_CLK_INTERNAL_RC | ADC_SAMPLE_TIME_31) - -// use AN11 -#define ADC_CONFIGPORT ENABLE_AN11_ANA -// Do not assign channels to scan -#define ADC_CONFIGSCAN SKIP_SCAN_ALL - -#define ADC_TO_VOLTS 0.003208F - - -// flash memory - int myvar = *(int*)(myflashmemoryaddress); - -// memory is 0x9D005000 to 0x9D07FFFF - -#define NVM_MEMORY_END 0x9D07FFFF -#define NVM_PAGE_SIZE 4096 -#define NVM_PAGES 2 // config & VTAG -#define RFIDLER_NVM_ADDRESS (NVM_MEMORY_END - (NVM_PAGE_SIZE * NVM_PAGES)) - -// UART timeout in us -#define SERIAL_TIMEOUT 100 - -#endif diff --git a/tools/hitag2crack/crack5gpu/Makefile b/tools/hitag2crack/crack5gpu/Makefile index adcf61113..cda40abee 100644 --- a/tools/hitag2crack/crack5gpu/Makefile +++ b/tools/hitag2crack/crack5gpu/Makefile @@ -6,18 +6,20 @@ INCLUDE=-I/opt/nvidia/cuda/include LIBS=-L/opt/nvidia/cuda/lib64 -lOpenCL #Mac #LIBS=-framework OpenCL +VPATH=../common +INC=-I ../common -all: ht2crack5.c utilpart.o ht2crack2utils.o hitagcrypto.o - $(CC) $(CFLAGS) ht2crack5.c -o ht2crack5gpu utilpart.o ht2crack2utils.o hitagcrypto.o $(LIBS) -lpthread +all: ht2crack5.c utilpart.o ht2crackutils.o hitagcrypto.o + $(CC) $(CFLAGS) $(INC) -o ht2crack5gpu $< utilpart.o ht2crackutils.o hitagcrypto.o $(LIBS) -lpthread -utilpart.o: util.h utilpart.c - $(CC) $(CFLAGS) $(INCLUDE) -c utilpart.c +utilpart.o: utilpart.c util.h + $(CC) $(CFLAGS) $(INCLUDE) -c $< -hitagcrypto.o: hitagcrypto.h hitagcrypto.c - $(CC) $(CFLAGS) $(INCLUDE) -c hitagcrypto.c +hitagcrypto.o: hitagcrypto.c hitagcrypto.h + $(CC) $(CFLAGS) $(INCLUDE) -c $< -ht2crack2utils.o: ht2crack2utils.h ht2crack2utils.c - $(CC) $(CFLAGS) $(INCLUDE) -c ht2crack2utils.c +ht2crackutils.o: ht2crackutils.c ht2crackutils.h + $(CC) $(CFLAGS) $(INCLUDE) -c $< clean: rm -f *.o ht2crack5gpu diff --git a/tools/hitag2crack/crack5gpu/hitagcrypto.c b/tools/hitag2crack/crack5gpu/hitagcrypto.c deleted file mode 100644 index 47449c3e3..000000000 --- a/tools/hitag2crack/crack5gpu/hitagcrypto.c +++ /dev/null @@ -1,373 +0,0 @@ -/*************************************************************************** - * A copy of the GNU GPL is appended to this file. * - * * - * This licence is based on the nmap licence, and we express our gratitude * - * for the work that went into producing it. There is no other connection * - * between RFIDler and nmap either expressed or implied. * - * * - ********************** IMPORTANT RFIDler LICENSE TERMS ******************** - * * - * * - * All references to RFIDler herein imply all it's derivatives, namely: * - * * - * o RFIDler-LF Standard * - * o RFIDler-LF Lite * - * o RFIDler-LF Nekkid * - * * - * * - * RFIDler is (C) 2013-2015 Aperture Labs Ltd. * - * * - * This program is free software; you may redistribute and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE * - * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your * - * right to use, modify, and redistribute this software under certain * - * conditions. If you wish to embed RFIDler technology into proprietary * - * software or hardware, we sell alternative licenses * - * (contact sales@aperturelabs.com). * - * * - * Note that the GPL places important restrictions on "derivative works", * - * yet it does not provide a detailed definition of that term. To avoid * - * misunderstandings, we interpret that term as broadly as copyright law * - * allows. For example, we consider an application to constitute a * - * derivative work for the purpose of this license if it does any of the * - * following with any software or content covered by this license * - * ("Covered Software"): * - * * - * o Integrates source code from Covered Software. * - * * - * o Is designed specifically to execute Covered Software and parse the * - * results (as opposed to typical shell or execution-menu apps, which will * - * execute anything you tell them to). * - * * - * o Includes Covered Software in a proprietary executable installer. The * - * installers produced by InstallShield are an example of this. Including * - * RFIDler with other software in compressed or archival form does not * - * trigger this provision, provided appropriate open source decompression * - * or de-archiving software is widely available for no charge. For the * - * purposes of this license, an installer is considered to include Covered * - * Software even if it actually retrieves a copy of Covered Software from * - * another source during runtime (such as by downloading it from the * - * Internet). * - * * - * o Links (statically or dynamically) to a library which does any of the * - * above. * - * * - * o Executes a helper program, module, or script to do any of the above. * - * * - * This list is not exclusive, but is meant to clarify our interpretation * - * of derived works with some common examples. Other people may interpret * - * the plain GPL differently, so we consider this a special exception to * - * the GPL that we apply to Covered Software. Works which meet any of * - * these conditions must conform to all of the terms of this license, * - * particularly including the GPL Section 3 requirements of providing * - * source code and allowing free redistribution of the work as a whole. * - * * - * As another special exception to the GPL terms, Aperture Labs Ltd. grants* - * permission to link the code of this program with any version of the * - * OpenSSL library which is distributed under a license identical to that * - * listed in the included docs/licenses/OpenSSL.txt file, and distribute * - * linked combinations including the two. * - * * - * Any redistribution of Covered Software, including any derived works, * - * must obey and carry forward all of the terms of this license, including * - * obeying all GPL rules and restrictions. For example, source code of * - * the whole work must be provided and free redistribution must be * - * allowed. All GPL references to "this License", are to be treated as * - * including the terms and conditions of this license text as well. * - * * - * Because this license imposes special exceptions to the GPL, Covered * - * Work may not be combined (even as part of a larger work) with plain GPL * - * software. The terms, conditions, and exceptions of this license must * - * be included as well. This license is incompatible with some other open * - * source licenses as well. In some cases we can relicense portions of * - * RFIDler or grant special permissions to use it in other open source * - * software. Please contact sales@aperturelabs.com with any such requests.* - * Similarly, we don't incorporate incompatible open source software into * - * Covered Software without special permission from the copyright holders. * - * * - * If you have any questions about the licensing restrictions on using * - * RFIDler in other works, are happy to help. As mentioned above, we also * - * offer alternative license to integrate RFIDler into proprietary * - * applications and appliances. These contracts have been sold to dozens * - * of software vendors, and generally include a perpetual license as well * - * as providing for priority support and updates. They also fund the * - * continued development of RFIDler. Please email sales@aperturelabs.com * - * for further information. * - * If you have received a written license agreement or contract for * - * Covered Software stating terms other than these, you may choose to use * - * and redistribute Covered Software under those terms instead of these. * - * * - * Source is provided to this software because we believe users have a * - * right to know exactly what a program is going to do before they run it. * - * This also allows you to audit the software for security holes (none * - * have been found so far). * - * * - * Source code also allows you to port RFIDler to new platforms, fix bugs, * - * and add new features. You are highly encouraged to send your changes * - * to the RFIDler mailing list for possible incorporation into the * - * main distribution. By sending these changes to Aperture Labs Ltd. or * - * one of the Aperture Labs Ltd. development mailing lists, or checking * - * them into the RFIDler source code repository, it is understood (unless * - * you specify otherwise) that you are offering the RFIDler Project * - * (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, * - * modify, and relicense the code. RFIDler will always be available Open * - * Source, but this is important because the inability to relicense code * - * has caused devastating problems for other Free Software projects (such * - * as KDE and NASM). We also occasionally relicense the code to third * - * parties as discussed above. If you wish to specify special license * - * conditions of your contributions, just say so when you send them. * - * * - * This program is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler * - * license file for more details (it's in a COPYING file included with * - * RFIDler, and also available from * - * https://github.com/ApertureLabsLtd/RFIDler/COPYING * - * * - ***************************************************************************/ - -// Author: unknown. -// Modifications for RFIDler: Tony Naggs , Adam Laurie - -// uncomment this to build file as a standalone crypto test program -// #define UNIT_TEST -// also uncomment to include verbose debug prints -// #define TEST_DEBUG - -//#include -#include "HardwareProfile.h" -#include "rfidler.h" -#include "hitagcrypto.h" -#include "util.h" - -#ifdef UNIT_TEST -#include -#endif - -#if defined(UNIT_TEST) && defined(TEST_DEBUG) -// Note that printf format %I64x prints 64 bit ints in MS Visual C/C++. -// This may need changing for other compilers/platforms. -#define DEBUG_PRINTF(...) printf(__VA_ARGS__) -#else -#define DEBUG_PRINTF(...) -#endif - - -/* Brief info about NXP Hitag 1, Hitag 2, Hitag S and Hitag u (mu) - - Hitag 125kHz RFID was created by a company called Mikron (Mikron Gesellschaft - fur Integrierte Mikroelektronik Mbh), of Austria, for micropayment applications. - At about the same time, late 1980s to early 1990s, Mikron developed the - similarly featured Mifare micropayment card for 13.56MHz RFID. - (Mikron's European Patent EP 0473569 A2 was filed 23 August 1991, with a - priority date of 23 Aug 1990.) - Mikron was subsequently acquired by Philips Semiconductors in 1995. - Philips Semiconductors divsion subsequently became NXP. - - + Modulation read/write device -> transponder: 100 % ASK and binary pulse - length coding - + Modulation transponder -> read/write device: Strong ASK modulation, - selectable Manchester or Biphase coding - + Hitag S, Hitag u; anti-collision procedure - + Fast anti-collision protocol - + Hitag u; optional Cyclic Redundancy Check (CRC) - + Reader Talks First mode - + Hitag 2 & later; Transponder Talks First (TTF) mode - + Temporary switch from Transponder Talks First into Reader Talks First - (RTF) Mode - + Data rate read/write device to transponder: 5.2 kbit/s - + Data rates transponder to read/write device: 2 kbit/s, 4 kbit/s, 8 kbit/s - + 32-bit password feature - + Hitag 2, S = 32-bit Unique Identifier - + Hitag u = 48-bit Unique Identifier - + Selectable password modes for reader / tag mutual authentication - (Hitag 1 has 2 pairs of keys, later versions have 1 pair) - + Hitag 2 & Hitag S; Selectable encrypted mode, 48 bit key - - Known tag types: - - HITAG 1 2048 bits total memory - - HITAG 2 256 Bit total memory Read/Write - 8 pages of 32 bits, inc UID (32), - secret key (64), password (24), config (8) - - HITAG S 32 32 bits Unique Identifier Read Only - HITAG S 256 256 bits total memory Read/Write - HITAG S 2048 2048 bits total memory Read/Write - - HITAG u RO64 64 bits total memory Read Only - HITAG u 128 bits total memory Read/Write - HITAG u Advanced 512 bits total memory Read/Write - HITAG u Advanced+ 1760 bits total memory Read/Write - - Default 48-bit key for Hitag 2, S encryption: - "MIKRON" = O N M I K R - Key = 4F 4E 4D 49 4B 52 - -*/ - - -// We want the crypto functions to be as fast as possible, so optimize! -// The best compiler optimization in Microchip's free XC32 edition is -O1 -#pragma GCC optimize("O1") - -// private, nonlinear function to generate 1 crypto bit -static uint32_t hitag2_crypt(uint64_t x); - - -// macros to pick out 4 bits in various patterns of 1s & 2s & make a new number -#define pickbits2_2(S, A, B) ( ((S >> A) & 3) | ((S >> (B - 2)) & 0xC) ) -#define pickbits1x4(S, A, B, C, D) ( ((S >> A) & 1) | ((S >> (B - 1)) & 2) | \ - ((S >> (C - 2)) & 4) | ((S >> (D - 3)) & 8) ) -#define pickbits1_1_2(S, A, B, C) ( ((S >> A) & 1) | ((S >> (B - 1)) & 2) | \ - ((S >> (C - 2)) & 0xC) ) -#define pickbits2_1_1(S, A, B, C) ( ((S >> A) & 3) | ((S >> (B - 2)) & 4) | \ - ((S >> (C - 3)) & 8) ) -#define pickbits1_2_1(S, A, B, C) ( ((S >> A) & 1) | ((S >> (B - 1)) & 6) | \ - ((S >> (C - 3)) & 8) ) - - -static uint32_t hitag2_crypt(uint64_t x) { - const uint32_t ht2_function4a = 0x2C79; // 0010 1100 0111 1001 - const uint32_t ht2_function4b = 0x6671; // 0110 0110 0111 0001 - const uint32_t ht2_function5c = 0x7907287B; // 0111 1001 0000 0111 0010 1000 0111 1011 - uint32_t bitindex; - - bitindex = (ht2_function4a >> pickbits2_2(x, 1, 4)) & 1; - bitindex |= ((ht2_function4b << 1) >> pickbits1_1_2(x, 7, 11, 13)) & 0x02; - bitindex |= ((ht2_function4b << 2) >> pickbits1x4(x, 16, 20, 22, 25)) & 0x04; - bitindex |= ((ht2_function4b << 3) >> pickbits2_1_1(x, 27, 30, 32)) & 0x08; - bitindex |= ((ht2_function4a << 4) >> pickbits1_2_1(x, 33, 42, 45)) & 0x10; - - DEBUG_PRINTF("hitag2_crypt bitindex = %02x\n", bitindex); - return (ht2_function5c >> bitindex) & 1; -} - -/* - * Parameters: - * Hitag_State* pstate - output, internal state after initialisation - * uint64_t sharedkey - 48 bit key shared between reader & tag - * uint32_t serialnum - 32 bit tag serial number - * uint32_t initvector - 32 bit random IV from reader, part of tag authentication - */ -void hitag2_init(Hitag_State *pstate, uint64_t sharedkey, uint32_t serialnum, uint32_t initvector) { - // init state, from serial number and lowest 16 bits of shared key - uint64_t state = ((sharedkey & 0xFFFF) << 32) | serialnum; - - // mix the initialisation vector and highest 32 bits of the shared key - initvector ^= (uint32_t)(sharedkey >> 16); - - // move 16 bits from (IV xor Shared Key) to top of uint64_t state - // these will be XORed in turn with output of the crypto function - state |= (uint64_t) initvector << 48; - initvector >>= 16; - - // unrolled loop is faster on PIC32 (MIPS), do 32 times - // shift register, then calc new bit - state >>= 1; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - - // highest 16 bits of IV XOR Shared Key - state |= (uint64_t) initvector << 47; - - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46; - state ^= (uint64_t) hitag2_crypt(state) << 47; - - DEBUG_PRINTF("hitag2_init result = %012I64x\n", state); - pstate->shiftreg = state; - /* naive version for reference, LFSR has 16 taps - pstate->lfsr = state ^ (state >> 2) ^ (state >> 3) ^ (state >> 6) - ^ (state >> 7) ^ (state >> 8) ^ (state >> 16) ^ (state >> 22) - ^ (state >> 23) ^ (state >> 26) ^ (state >> 30) ^ (state >> 41) - ^ (state >> 42) ^ (state >> 43) ^ (state >> 46) ^ (state >> 47); - */ - { - // optimise with one 64-bit intermediate - uint64_t temp = state ^ (state >> 1); - pstate->lfsr = state ^ (state >> 6) ^ (state >> 16) - ^ (state >> 26) ^ (state >> 30) ^ (state >> 41) - ^ (temp >> 2) ^ (temp >> 7) ^ (temp >> 22) - ^ (temp >> 42) ^ (temp >> 46); - } -} - - -/* - * Return up to 32 crypto bits. - * Last bit is in least significant bit, earlier bits are shifted left. - * Note that the Hitag transmission protocol is least significant bit, - * so we may want to change this, or add a function, that returns the - * crypto output bits in the other order. - * - * Parameters: - * Hitag_State* pstate - in/out, internal cipher state after initialisation - * uint32_t steps - number of bits requested, (capped at 32) - */ -uint32_t hitag2_nstep(Hitag_State *pstate, uint32_t steps) { - uint64_t state = pstate->shiftreg; - uint32_t result = 0; - uint64_t lfsr = pstate->lfsr; - - if (steps == 0) - return 0; - -// if (steps > 32) -// steps = 32; - - do { - // update shift registers - if (lfsr & 1) { - state = (state >> 1) | 0x800000000000; - lfsr = (lfsr >> 1) ^ 0xB38083220073; - - // accumulate next bit of crypto - result = (result << 1) | hitag2_crypt(state); - } else { - state >>= 1; - lfsr >>= 1; - - result = (result << 1) | hitag2_crypt(state); - } - } while (--steps); - - DEBUG_PRINTF("hitag2_nstep state = %012I64x, result %02x\n", state, result); - pstate->shiftreg = state; - pstate->lfsr = lfsr; - return result; -} - -// end of crypto core, revert to default optimization level -#pragma GCC reset_options diff --git a/tools/hitag2crack/crack5gpu/hitagcrypto.h b/tools/hitag2crack/crack5gpu/hitagcrypto.h deleted file mode 100644 index 274d3d82c..000000000 --- a/tools/hitag2crack/crack5gpu/hitagcrypto.h +++ /dev/null @@ -1,167 +0,0 @@ -/*************************************************************************** - * A copy of the GNU GPL is appended to this file. * - * * - * This licence is based on the nmap licence, and we express our gratitude * - * for the work that went into producing it. There is no other connection * - * between RFIDler and nmap either expressed or implied. * - * * - ********************** IMPORTANT RFIDler LICENSE TERMS ******************** - * * - * * - * All references to RFIDler herein imply all it's derivatives, namely: * - * * - * o RFIDler-LF Standard * - * o RFIDler-LF Lite * - * o RFIDler-LF Nekkid * - * * - * * - * RFIDler is (C) 2013-2014 Aperture Labs Ltd. * - * * - * This program is free software; you may redistribute and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE * - * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your * - * right to use, modify, and redistribute this software under certain * - * conditions. If you wish to embed RFIDler technology into proprietary * - * software or hardware, we sell alternative licenses * - * (contact sales@aperturelabs.com). * - * * - * Note that the GPL places important restrictions on "derivative works", * - * yet it does not provide a detailed definition of that term. To avoid * - * misunderstandings, we interpret that term as broadly as copyright law * - * allows. For example, we consider an application to constitute a * - * derivative work for the purpose of this license if it does any of the * - * following with any software or content covered by this license * - * ("Covered Software"): * - * * - * o Integrates source code from Covered Software. * - * * - * o Is designed specifically to execute Covered Software and parse the * - * results (as opposed to typical shell or execution-menu apps, which will * - * execute anything you tell them to). * - * * - * o Includes Covered Software in a proprietary executable installer. The * - * installers produced by InstallShield are an example of this. Including * - * RFIDler with other software in compressed or archival form does not * - * trigger this provision, provided appropriate open source decompression * - * or de-archiving software is widely available for no charge. For the * - * purposes of this license, an installer is considered to include Covered * - * Software even if it actually retrieves a copy of Covered Software from * - * another source during runtime (such as by downloading it from the * - * Internet). * - * * - * o Links (statically or dynamically) to a library which does any of the * - * above. * - * * - * o Executes a helper program, module, or script to do any of the above. * - * * - * This list is not exclusive, but is meant to clarify our interpretation * - * of derived works with some common examples. Other people may interpret * - * the plain GPL differently, so we consider this a special exception to * - * the GPL that we apply to Covered Software. Works which meet any of * - * these conditions must conform to all of the terms of this license, * - * particularly including the GPL Section 3 requirements of providing * - * source code and allowing free redistribution of the work as a whole. * - * * - * As another special exception to the GPL terms, Aperture Labs Ltd. grants* - * permission to link the code of this program with any version of the * - * OpenSSL library which is distributed under a license identical to that * - * listed in the included docs/licenses/OpenSSL.txt file, and distribute * - * linked combinations including the two. * - * * - * Any redistribution of Covered Software, including any derived works, * - * must obey and carry forward all of the terms of this license, including * - * obeying all GPL rules and restrictions. For example, source code of * - * the whole work must be provided and free redistribution must be * - * allowed. All GPL references to "this License", are to be treated as * - * including the terms and conditions of this license text as well. * - * * - * Because this license imposes special exceptions to the GPL, Covered * - * Work may not be combined (even as part of a larger work) with plain GPL * - * software. The terms, conditions, and exceptions of this license must * - * be included as well. This license is incompatible with some other open * - * source licenses as well. In some cases we can relicense portions of * - * RFIDler or grant special permissions to use it in other open source * - * software. Please contact sales@aperturelabs.com with any such requests.* - * Similarly, we don't incorporate incompatible open source software into * - * Covered Software without special permission from the copyright holders. * - * * - * If you have any questions about the licensing restrictions on using * - * RFIDler in other works, are happy to help. As mentioned above, we also * - * offer alternative license to integrate RFIDler into proprietary * - * applications and appliances. These contracts have been sold to dozens * - * of software vendors, and generally include a perpetual license as well * - * as providing for priority support and updates. They also fund the * - * continued development of RFIDler. Please email sales@aperturelabs.com * - * for further information. * - * If you have received a written license agreement or contract for * - * Covered Software stating terms other than these, you may choose to use * - * and redistribute Covered Software under those terms instead of these. * - * * - * Source is provided to this software because we believe users have a * - * right to know exactly what a program is going to do before they run it. * - * This also allows you to audit the software for security holes (none * - * have been found so far). * - * * - * Source code also allows you to port RFIDler to new platforms, fix bugs, * - * and add new features. You are highly encouraged to send your changes * - * to the RFIDler mailing list for possible incorporation into the * - * main distribution. By sending these changes to Aperture Labs Ltd. or * - * one of the Aperture Labs Ltd. development mailing lists, or checking * - * them into the RFIDler source code repository, it is understood (unless * - * you specify otherwise) that you are offering the RFIDler Project * - * (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, * - * modify, and relicense the code. RFIDler will always be available Open * - * Source, but this is important because the inability to relicense code * - * has caused devastating problems for other Free Software projects (such * - * as KDE and NASM). We also occasionally relicense the code to third * - * parties as discussed above. If you wish to specify special license * - * conditions of your contributions, just say so when you send them. * - * * - * This program is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler * - * license file for more details (it's in a COPYING file included with * - * RFIDler, and also available from * - * https://github.com/ApertureLabsLtd/RFIDler/COPYING * - * * - ***************************************************************************/ - -// Author: unknown. -// Modifications for RFIDler: Tony Naggs , Adam Laurie - - -#ifndef HITAGCRYPTO_H -#define HITAGCRYPTO_H - -#include - -/* - Our model of Hitag 2 crypto uses 2 parallel shift registers: - a. 48 bit Feedback Shift Register, required for inputs to the nonlinear function. - b. 48 bit Linear Feedback Shift Register (LFSR). - A transform of initial register (a) value, which is then run in parallel. - Enables much faster calculation of the feedback values. - - API: - void hitag2_init(Hitag_State* pstate, uint64_t sharedkey, uint32_t serialnum, - uint32_t initvector); - Initialise state from 48 bit shared (secret) reader/tag key, - 32 bit tag serial number and 32 bit initialisation vector from reader. - - uint32_t hitag2_nstep(Hitag_State* pstate, uint32_t steps); - update shift register state and generate N cipher bits (N should be <= 32) - */ - - -typedef struct { - uint64_t shiftreg; // naive shift register, required for nonlinear fn input - uint64_t lfsr; // fast lfsr, used to make software faster -} Hitag_State; - -void hitag2_init(Hitag_State *pstate, uint64_t sharedkey, uint32_t serialnum, uint32_t initvector); - -uint32_t hitag2_nstep(Hitag_State *pstate, uint32_t steps); - -#endif /* HITAGCRYPTO_H */ - diff --git a/tools/hitag2crack/crack5gpu/ht2crack2utils.c b/tools/hitag2crack/crack5gpu/ht2crack2utils.c deleted file mode 100644 index 75d4c27a9..000000000 --- a/tools/hitag2crack/crack5gpu/ht2crack2utils.c +++ /dev/null @@ -1,172 +0,0 @@ -#include "ht2crack2utils.h" - -// writes a value into a buffer as a series of bytes -void writebuf(unsigned char *buf, uint64_t val, unsigned int len) { - int i; - char c; - - for (i = len - 1; i >= 0; i--) { - c = val & 0xff; - buf[i] = c; - val = val >> 8; - } - -} - - -/* simple hexdump for testing purposes */ -void shexdump(unsigned char *data, int data_len) { - int i; - - if (!data || (data_len <= 0)) { - printf("shexdump: invalid parameters\n"); - return; - } - - printf("Hexdump from %p:\n", data); - - for (i = 0; i < data_len; i++) { - if ((i % HEX_PER_ROW) == 0) { - printf("\n0x%04x: ", i); - } - printf("%02x ", data[i]); - } - printf("\n\n"); -} - - - -void printbin(unsigned char *c) { - int i, j; - unsigned char x; - - if (!c) { - printf("printbin: invalid params\n"); - return; - } - - for (i = 0; i < 6; i++) { - x = c[i]; - for (j = 0; j < 8; j++) { - printf("%d", (x & 0x80) >> 7); - x = x << 1; - } - } - printf("\n"); -} - - -void printbin2(uint64_t val, unsigned int size) { - int i; - uint64_t mask = 1; - - mask = mask << (size - 1); - - for (i = 0; i < size; i++) { - if (val & mask) { - printf("1"); - } else { - printf("0"); - } - val = val << 1; - } -} - - -void printstate(Hitag_State *hstate) { - printf("shiftreg =\t"); - printbin2(hstate->shiftreg, 48); - printf("\n"); -} - - - - -// convert hex char to binary -unsigned char hex2bin(unsigned char c) { - if ((c >= '0') && (c <= '9')) { - return (c - '0'); - } else if ((c >= 'a') && (c <= 'f')) { - return (c - 'a' + 10); - } else if ((c >= 'A') && (c <= 'F')) { - return (c - 'A' + 10); - } else { - return 0; - } -} - -// return a single bit from a value -int bitn(uint64_t x, int bit) { - uint64_t bitmask = 1; - - bitmask = bitmask << bit; - - if (x & bitmask) { - return 1; - } else { - return 0; - } -} - - -// the sub-function R that rollback depends upon -int fnR(uint64_t x) { - // renumbered bits because my state is 0-47, not 1-48 - return (bitn(x, 1) ^ bitn(x, 2) ^ bitn(x, 5) ^ bitn(x, 6) ^ bitn(x, 7) ^ - bitn(x, 15) ^ bitn(x, 21) ^ bitn(x, 22) ^ bitn(x, 25) ^ bitn(x, 29) ^ bitn(x, 40) ^ - bitn(x, 41) ^ bitn(x, 42) ^ bitn(x, 45) ^ bitn(x, 46) ^ bitn(x, 47)); -} - -// the rollback function that lets us go backwards in time -void rollback(Hitag_State *hstate, unsigned int steps) { - int i; - - for (i = 0; i < steps; i++) { - hstate->shiftreg = ((hstate->shiftreg << 1) & 0xffffffffffff) | fnR(hstate->shiftreg); - } - -} - - -// the three filter sub-functions that feed fnf -int fa(unsigned int i) { - return bitn(0x2C79, i); -} - -int fb(unsigned int i) { - return bitn(0x6671, i); -} - -int fc(unsigned int i) { - return bitn(0x7907287B, i); -} - -// the filter function that generates a bit of output from the prng state -int fnf(uint64_t s) { - unsigned int x1, x2, x3, x4, x5, x6; - - x1 = (bitn(s, 2) << 0) | (bitn(s, 3) << 1) | (bitn(s, 5) << 2) | (bitn(s, 6) << 3); - x2 = (bitn(s, 8) << 0) | (bitn(s, 12) << 1) | (bitn(s, 14) << 2) | (bitn(s, 15) << 3); - x3 = (bitn(s, 17) << 0) | (bitn(s, 21) << 1) | (bitn(s, 23) << 2) | (bitn(s, 26) << 3); - x4 = (bitn(s, 28) << 0) | (bitn(s, 29) << 1) | (bitn(s, 31) << 2) | (bitn(s, 33) << 3); - x5 = (bitn(s, 34) << 0) | (bitn(s, 43) << 1) | (bitn(s, 44) << 2) | (bitn(s, 46) << 3); - - x6 = (fa(x1) << 0) | (fb(x2) << 1) | (fb(x3) << 2) | (fb(x4) << 3) | (fa(x5) << 4); - - return fc(x6); -} - -// builds the lfsr for the prng (quick calcs for hitag2_nstep()) -void buildlfsr(Hitag_State *hstate) { - uint64_t state = hstate->shiftreg; - uint64_t temp; - - temp = state ^ (state >> 1); - hstate->lfsr = state ^ (state >> 6) ^ (state >> 16) - ^ (state >> 26) ^ (state >> 30) ^ (state >> 41) - ^ (temp >> 2) ^ (temp >> 7) ^ (temp >> 22) - ^ (temp >> 42) ^ (temp >> 46); -} - - - diff --git a/tools/hitag2crack/crack5gpu/ht2crack2utils.h b/tools/hitag2crack/crack5gpu/ht2crack2utils.h deleted file mode 100644 index 33e0e3036..000000000 --- a/tools/hitag2crack/crack5gpu/ht2crack2utils.h +++ /dev/null @@ -1,35 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "HardwareProfile.h" -#include "rfidler.h" -#include "util.h" - -#include "hitagcrypto.h" - -#define HEX_PER_ROW 16 - - - -void writebuf(unsigned char *buf, uint64_t val, unsigned int len); -void shexdump(unsigned char *data, int data_len); -void printbin(unsigned char *c); -void printbin2(uint64_t val, unsigned int size); -void printstate(Hitag_State *hstate); -unsigned char hex2bin(unsigned char c); -int bitn(uint64_t x, int bit); -int fnR(uint64_t x); -void rollback(Hitag_State *hstate, unsigned int steps); -int fa(unsigned int i); -int fb(unsigned int i); -int fc(unsigned int i); -int fnf(uint64_t s); -void buildlfsr(Hitag_State *hstate); diff --git a/tools/hitag2crack/crack5gpu/ht2crack5.c b/tools/hitag2crack/crack5gpu/ht2crack5.c index 82a80c3ea..37df9df65 100644 --- a/tools/hitag2crack/crack5gpu/ht2crack5.c +++ b/tools/hitag2crack/crack5gpu/ht2crack5.c @@ -29,7 +29,7 @@ #define CL_USE_DEPRECATED_OPENCL_1_2_APIS #include #endif -#include "ht2crack2utils.h" +#include "ht2crackutils.h" const uint8_t bits[9] = {20, 14, 4, 3, 1, 1, 1, 1, 1}; #define lfsr_inv(state) (((state)<<1) | (__builtin_parityll((state) & ((0xce0044c101cd>>1)|(1ull<<(47)))))) diff --git a/tools/hitag2crack/crack5gpu/rfidler.h b/tools/hitag2crack/crack5gpu/rfidler.h deleted file mode 100644 index 933547e6b..000000000 --- a/tools/hitag2crack/crack5gpu/rfidler.h +++ /dev/null @@ -1,412 +0,0 @@ -/*************************************************************************** - * A copy of the GNU GPL is appended to this file. * - * * - * This licence is based on the nmap licence, and we express our gratitude * - * for the work that went into producing it. There is no other connection * - * between RFIDler and nmap either expressed or implied. * - * * - ********************** IMPORTANT RFIDler LICENSE TERMS ******************** - * * - * * - * All references to RFIDler herein imply all it's derivatives, namely: * - * * - * o RFIDler-LF Standard * - * o RFIDler-LF Lite * - * o RFIDler-LF Nekkid * - * * - * * - * RFIDler is (C) 2013-2015 Aperture Labs Ltd. * - * * - * This program is free software; you may redistribute and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE * - * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your * - * right to use, modify, and redistribute this software under certain * - * conditions. If you wish to embed RFIDler technology into proprietary * - * software or hardware, we sell alternative licenses * - * (contact sales@aperturelabs.com). * - * * - * Note that the GPL places important restrictions on "derivative works", * - * yet it does not provide a detailed definition of that term. To avoid * - * misunderstandings, we interpret that term as broadly as copyright law * - * allows. For example, we consider an application to constitute a * - * derivative work for the purpose of this license if it does any of the * - * following with any software or content covered by this license * - * ("Covered Software"): * - * * - * o Integrates source code from Covered Software. * - * * - * o Is designed specifically to execute Covered Software and parse the * - * results (as opposed to typical shell or execution-menu apps, which will * - * execute anything you tell them to). * - * * - * o Includes Covered Software in a proprietary executable installer. The * - * installers produced by InstallShield are an example of this. Including * - * RFIDler with other software in compressed or archival form does not * - * trigger this provision, provided appropriate open source decompression * - * or de-archiving software is widely available for no charge. For the * - * purposes of this license, an installer is considered to include Covered * - * Software even if it actually retrieves a copy of Covered Software from * - * another source during runtime (such as by downloading it from the * - * Internet). * - * * - * o Links (statically or dynamically) to a library which does any of the * - * above. * - * * - * o Executes a helper program, module, or script to do any of the above. * - * * - * This list is not exclusive, but is meant to clarify our interpretation * - * of derived works with some common examples. Other people may interpret * - * the plain GPL differently, so we consider this a special exception to * - * the GPL that we apply to Covered Software. Works which meet any of * - * these conditions must conform to all of the terms of this license, * - * particularly including the GPL Section 3 requirements of providing * - * source code and allowing free redistribution of the work as a whole. * - * * - * As another special exception to the GPL terms, Aperture Labs Ltd. grants* - * permission to link the code of this program with any version of the * - * OpenSSL library which is distributed under a license identical to that * - * listed in the included docs/licenses/OpenSSL.txt file, and distribute * - * linked combinations including the two. * - * * - * Any redistribution of Covered Software, including any derived works, * - * must obey and carry forward all of the terms of this license, including * - * obeying all GPL rules and restrictions. For example, source code of * - * the whole work must be provided and free redistribution must be * - * allowed. All GPL references to "this License", are to be treated as * - * including the terms and conditions of this license text as well. * - * * - * Because this license imposes special exceptions to the GPL, Covered * - * Work may not be combined (even as part of a larger work) with plain GPL * - * software. The terms, conditions, and exceptions of this license must * - * be included as well. This license is incompatible with some other open * - * source licenses as well. In some cases we can relicense portions of * - * RFIDler or grant special permissions to use it in other open source * - * software. Please contact sales@aperturelabs.com with any such requests.* - * Similarly, we don't incorporate incompatible open source software into * - * Covered Software without special permission from the copyright holders. * - * * - * If you have any questions about the licensing restrictions on using * - * RFIDler in other works, are happy to help. As mentioned above, we also * - * offer alternative license to integrate RFIDler into proprietary * - * applications and appliances. These contracts have been sold to dozens * - * of software vendors, and generally include a perpetual license as well * - * as providing for priority support and updates. They also fund the * - * continued development of RFIDler. Please email sales@aperturelabs.com * - * for further information. * - * If you have received a written license agreement or contract for * - * Covered Software stating terms other than these, you may choose to use * - * and redistribute Covered Software under those terms instead of these. * - * * - * Source is provided to this software because we believe users have a * - * right to know exactly what a program is going to do before they run it. * - * This also allows you to audit the software for security holes (none * - * have been found so far). * - * * - * Source code also allows you to port RFIDler to new platforms, fix bugs, * - * and add new features. You are highly encouraged to send your changes * - * to the RFIDler mailing list for possible incorporation into the * - * main distribution. By sending these changes to Aperture Labs Ltd. or * - * one of the Aperture Labs Ltd. development mailing lists, or checking * - * them into the RFIDler source code repository, it is understood (unless * - * you specify otherwise) that you are offering the RFIDler Project * - * (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, * - * modify, and relicense the code. RFIDler will always be available Open * - * Source, but this is important because the inability to relicense code * - * has caused devastating problems for other Free Software projects (such * - * as KDE and NASM). We also occasionally relicense the code to third * - * parties as discussed above. If you wish to specify special license * - * conditions of your contributions, just say so when you send them. * - * * - * This program is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler * - * license file for more details (it's in a COPYING file included with * - * RFIDler, and also available from * - * https://github.com/ApertureLabsLtd/RFIDler/COPYING * - * * - ***************************************************************************/ - -// Author: Adam Laurie - -#include -#include - -// BCD hardware revision for usb descriptor (usb_descriptors.c) -#define RFIDLER_HW_VERSION 0x020 - -// max sizes in BITS -#define MAXBLOCKSIZE 512 -#define MAXTAGSIZE 4096 -#define MAXUID 512 - -#define TMP_LARGE_BUFF_LEN 2048 -#define TMP_SMALL_BUFF_LEN 256 -#define ANALOGUE_BUFF_LEN 8192 - -#define COMMS_BUFFER_SIZE 128 - -#define DETECT_BUFFER_SIZE 512 - -#define SAMPLEMASK ~(BIT_1 | BIT_0) // mask to remove two bottom bits from analogue sample - we will then use those for reader & bit period - -// globals - -extern BOOL WiegandOutput; // Output wiegand data whenenver UID is read -extern BYTE *EMU_Reset_Data; // Pointer to full array of bits as bytes, stored as 0x00/0x01, '*' terminated -extern BYTE *EMU_Data; // Pointer to current location in EMU_Reset_Data -extern BYTE EMU_ThisBit; // The next data bit to transmit -extern BYTE EMU_SubCarrier_T0; // Number of Frame Clocks for sub-carrier '0' -extern BYTE EMU_SubCarrier_T1; // Number of Frame Clocks for sub-carrier '1' -extern unsigned int EMU_Repeat; // Number of times to transmit full data set -extern BOOL EMU_Background; // Emulate in the background until told to stop -extern unsigned int EMU_DataBitRate; // Number of Frame Clocks per bit -extern BYTE TmpBits[TMP_LARGE_BUFF_LEN]; // Shared scratchpad -extern BYTE ReaderPeriod; // Flag for sample display -extern unsigned char Comms_In_Buffer[COMMS_BUFFER_SIZE]; // USB/Serial buffer -extern BYTE Interface; // user interface - CLI or API -extern BYTE CommsChannel; // user comms channel - USB or UART -extern BOOL FakeRead; // flag for analogue sampler to signal it wants access to buffers during read -extern BOOL PWD_Mode; // is this tag password protected? -extern BYTE Password[9]; // 32 bits as HEX string set with LOGIN -extern unsigned int Led_Count; // LED status counter, also used for entropy -extern unsigned long Reader_Bit_Count; // Reader ISR bit counter -extern char Previous; // Reader ISR previous bit type - -// RWD (read/write device) coil state -extern BYTE RWD_State; // current state of RWD coil -extern unsigned int RWD_Fc; // field clock in uS -extern unsigned int RWD_Gap_Period; // length of command gaps in OC5 ticks -extern unsigned int RWD_Zero_Period; // length of '0' in OC5 ticks -extern unsigned int RWD_One_Period; // length of '1' in OC5 ticks -extern unsigned int RWD_Sleep_Period; // length of initial sleep to reset tag in OC5 ticks -extern unsigned int RWD_Wake_Period; // length required for tag to restart in OC5 ticks -extern unsigned int RWD_Wait_Switch_TX_RX; // length to wait when switching from TX to RX in OC5 ticks -extern unsigned int RWD_Wait_Switch_RX_TX; // length to wait when switching from RX to TX in OC5 ticks -extern unsigned int RWD_Post_Wait; // low level ISR wait period in OC5 ticks -extern unsigned int RWD_OC5_config; // Output Compare Module settings -extern unsigned int RWD_OC5_r; // Output Compare Module primary compare value -extern unsigned int RWD_OC5_rs; // Output Compare Module secondary compare value -extern BYTE RWD_Command_Buff[TMP_SMALL_BUFF_LEN]; // Command buffer, array of bits as bytes, stored as 0x00/0x01, '*' terminated -extern BYTE *RWD_Command_ThisBit; // Current command bit -extern BOOL Reader_ISR_State; // current state of reader ISR - -// NVM variables -// timings etc. that want to survive a reboot should go here -typedef struct { - BYTE Name[7]; // will be set to "RFIDler" so we can test for new device - BYTE AutoRun[128]; // optional command to run at startup - unsigned char TagType; - unsigned int PSK_Quality; - unsigned int Timeout; - unsigned int Wiegand_Pulse; - unsigned int Wiegand_Gap; - BOOL Wiegand_IdleState; - unsigned int FrameClock; - unsigned char Modulation; - unsigned int DataRate; - unsigned int DataRateSub0; - unsigned int DataRateSub1; - unsigned int DataBits; - unsigned int DataBlocks; - unsigned int BlockSize; - unsigned char SyncBits; - BYTE Sync[4]; - BOOL BiPhase; - BOOL Invert; - BOOL Manchester; - BOOL HalfDuplex; - unsigned int Repeat; - unsigned int PotLow; - unsigned int PotHigh; - unsigned int RWD_Gap_Period; - unsigned int RWD_Zero_Period; - unsigned int RWD_One_Period; - unsigned int RWD_Sleep_Period; - unsigned int RWD_Wake_Period; - unsigned int RWD_Wait_Switch_TX_RX; - unsigned int RWD_Wait_Switch_RX_TX; -} StoredConfig; - -// somewhere to store TAG data. this will be interpreted according to the TAG -// type. -typedef struct { - BYTE TagType; // raw tag type - BYTE EmulatedTagType; // tag type this tag is configured to emulate - BYTE UID[MAXUID + 1]; // Null-terminated HEX string - BYTE Data[MAXTAGSIZE]; // raw data - unsigned char DataBlocks; // number of blocks in Data field - unsigned int BlockSize; // blocksize in bits -} VirtualTag; - -extern StoredConfig RFIDlerConfig; -extern VirtualTag RFIDlerVTag; -extern BYTE TmpBuff[NVM_PAGE_SIZE]; -extern BYTE DataBuff[ANALOGUE_BUFF_LEN]; -extern unsigned int DataBuffCount; -extern const BYTE *ModulationSchemes[]; -extern const BYTE *OnOff[]; -extern const BYTE *HighLow[]; -extern const BYTE *TagTypes[]; - -// globals for ISRs -extern BYTE EmulationMode; -extern unsigned long HW_Bits; -extern BYTE HW_Skip_Bits; -extern unsigned int PSK_Min_Pulse; -extern BOOL PSK_Read_Error; -extern BOOL Manchester_Error; -extern BOOL SnifferMode; -extern unsigned int Clock_Tick_Counter; -extern BOOL Clock_Tick_Counter_Reset; - -// smart card lib -#define MAX_ATR_LEN (BYTE)33 -extern BYTE scCardATR[MAX_ATR_LEN]; -extern BYTE scATRLength; - -// RTC -extern rtccTime RTC_time; // time structure -extern rtccDate RTC_date; // date structure - -// digital pots -#define POTLOW_DEFAULT 100 -#define POTHIGH_DEFAULT 150 -#define DC_OFFSET 60 // analogue circuit DC offset (as close as we can get without using 2 LSB) -#define VOLTS_TO_POT 0.019607843F - -// RWD/clock states -#define RWD_STATE_INACTIVE 0 // RWD not in use -#define RWD_STATE_GO_TO_SLEEP 1 // RWD coil shutdown request -#define RWD_STATE_SLEEPING 2 // RWD coil shutdown for sleep period -#define RWD_STATE_WAKING 3 // RWD active for pre-determined period after reset -#define RWD_STATE_START_SEND 4 // RWD starting send of data -#define RWD_STATE_SENDING_GAP 5 // RWD sending a gap -#define RWD_STATE_SENDING_BIT 6 // RWD sending a data bit -#define RWD_STATE_POST_WAIT 7 // RWD finished sending data, now in forced wait period -#define RWD_STATE_ACTIVE 8 // RWD finished, now just clocking a carrier - -// reader ISR states -#define READER_STOPPED 0 // reader not in use -#define READER_IDLING 1 // reader ISR running to preserve timing, but not reading -#define READER_RUNNING 2 // reader reading bits - - -// user interface types -#define INTERFACE_API 0 -#define INTERFACE_CLI 1 - -// comms channel -#define COMMS_NONE 0 -#define COMMS_USB 1 -#define COMMS_UART 2 - -#define MAX_HISTORY 2 // disable most of history for now - memory issue - -// tag write retries -#define TAG_WRITE_RETRY 5 - -// modulation modes - uppdate ModulationSchemes[] in tags.c if you change this -#define MOD_MODE_NONE 0 -#define MOD_MODE_ASK_OOK 1 -#define MOD_MODE_FSK1 2 -#define MOD_MODE_FSK2 3 -#define MOD_MODE_PSK1 4 -#define MOD_MODE_PSK2 5 -#define MOD_MODE_PSK3 6 - -// TAG types - update TagTypes[] in tags.c if you add to this list -#define TAG_TYPE_NONE 0 -#define TAG_TYPE_ASK_RAW 1 -#define TAG_TYPE_FSK1_RAW 2 -#define TAG_TYPE_FSK2_RAW 3 -#define TAG_TYPE_PSK1_RAW 4 -#define TAG_TYPE_PSK2_RAW 5 -#define TAG_TYPE_PSK3_RAW 6 -#define TAG_TYPE_HITAG1 7 -#define TAG_TYPE_HITAG2 8 -#define TAG_TYPE_EM4X02 9 -#define TAG_TYPE_Q5 10 -#define TAG_TYPE_HID_26 11 -#define TAG_TYPE_INDALA_64 12 -#define TAG_TYPE_INDALA_224 13 -#define TAG_TYPE_UNIQUE 14 -#define TAG_TYPE_FDXB 15 -#define TAG_TYPE_T55X7 16 // same as Q5 but different timings and no modulation-defeat -#define TAG_TYPE_AWID_26 17 -#define TAG_TYPE_EM4X05 18 -#define TAG_TYPE_TAMAGOTCHI 19 -#define TAG_TYPE_HDX 20 // same underlying data as FDX-B, but different modulation & telegram - -// various - -#define BINARY 0 -#define HEX 1 - -#define NO_ADDRESS -1 - -#define ACK TRUE -#define NO_ACK FALSE - -#define BLOCK TRUE -#define NO_BLOCK FALSE - -#define DATA TRUE -#define NO_DATA FALSE - -#define DEBUG_PIN_ON HIGH -#define DEBUG_PIN_OFF LOW - -#define FAST FALSE -#define SLOW TRUE - -#define NO_TRIGGER 0 - -#define LOCK TRUE -#define NO_LOCK FALSE - -#define NFC_MODE TRUE -#define NO_NFC_MODE FALSE - -#define ONESHOT_READ TRUE -#define NO_ONESHOT_READ FALSE - -#define RESET TRUE -#define NO_RESET FALSE - -#define SHUTDOWN_CLOCK TRUE -#define NO_SHUTDOWN_CLOCK FALSE - -#define SYNC TRUE -#define NO_SYNC FALSE - -#define VERIFY TRUE -#define NO_VERIFY FALSE - -#define VOLATILE FALSE -#define NON_VOLATILE TRUE - -#define NEWLINE TRUE -#define NO_NEWLINE FALSE - -#define WAIT TRUE -#define NO_WAIT FALSE - -#define WIPER_HIGH 0 -#define WIPER_LOW 1 - -// conversion for time to ticks -#define US_TO_TICKS 1000000L -#define US_OVER_10_TO_TICKS 10000000L -#define US_OVER_100_TO_TICKS 100000000L -// we can't get down to this level on pic, but we want to standardise on timings, so for now we fudge it -#define CONVERT_TO_TICKS(x) ((x / 10) * (GetSystemClock() / US_OVER_10_TO_TICKS)) -#define CONVERT_TICKS_TO_US(x) (x / (GetSystemClock() / US_TO_TICKS)) -#define TIMER5_PRESCALER 16 -#define MAX_TIMER5_TICKS (65535 * TIMER5_PRESCALER) - -// other conversions - -// bits to hex digits -#define HEXDIGITS(x) (x / 4) -#define HEXTOBITS(x) (x * 4) diff --git a/tools/hitag2crack/crack5gpu/util.h b/tools/hitag2crack/crack5gpu/util.h deleted file mode 100644 index c2399c37c..000000000 --- a/tools/hitag2crack/crack5gpu/util.h +++ /dev/null @@ -1,147 +0,0 @@ -/*************************************************************************** - * A copy of the GNU GPL is appended to this file. * - * * - * This licence is based on the nmap licence, and we express our gratitude * - * for the work that went into producing it. There is no other connection * - * between RFIDler and nmap either expressed or implied. * - * * - ********************** IMPORTANT RFIDler LICENSE TERMS ******************** - * * - * * - * All references to RFIDler herein imply all it's derivatives, namely: * - * * - * o RFIDler-LF Standard * - * o RFIDler-LF Lite * - * o RFIDler-LF Nekkid * - * * - * * - * RFIDler is (C) 2013-2015 Aperture Labs Ltd. * - * * - * This program is free software; you may redistribute and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE * - * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your * - * right to use, modify, and redistribute this software under certain * - * conditions. If you wish to embed RFIDler technology into proprietary * - * software or hardware, we sell alternative licenses * - * (contact sales@aperturelabs.com). * - * * - * Note that the GPL places important restrictions on "derivative works", * - * yet it does not provide a detailed definition of that term. To avoid * - * misunderstandings, we interpret that term as broadly as copyright law * - * allows. For example, we consider an application to constitute a * - * derivative work for the purpose of this license if it does any of the * - * following with any software or content covered by this license * - * ("Covered Software"): * - * * - * o Integrates source code from Covered Software. * - * * - * o Is designed specifically to execute Covered Software and parse the * - * results (as opposed to typical shell or execution-menu apps, which will * - * execute anything you tell them to). * - * * - * o Includes Covered Software in a proprietary executable installer. The * - * installers produced by InstallShield are an example of this. Including * - * RFIDler with other software in compressed or archival form does not * - * trigger this provision, provided appropriate open source decompression * - * or de-archiving software is widely available for no charge. For the * - * purposes of this license, an installer is considered to include Covered * - * Software even if it actually retrieves a copy of Covered Software from * - * another source during runtime (such as by downloading it from the * - * Internet). * - * * - * o Links (statically or dynamically) to a library which does any of the * - * above. * - * * - * o Executes a helper program, module, or script to do any of the above. * - * * - * This list is not exclusive, but is meant to clarify our interpretation * - * of derived works with some common examples. Other people may interpret * - * the plain GPL differently, so we consider this a special exception to * - * the GPL that we apply to Covered Software. Works which meet any of * - * these conditions must conform to all of the terms of this license, * - * particularly including the GPL Section 3 requirements of providing * - * source code and allowing free redistribution of the work as a whole. * - * * - * As another special exception to the GPL terms, Aperture Labs Ltd. grants* - * permission to link the code of this program with any version of the * - * OpenSSL library which is distributed under a license identical to that * - * listed in the included docs/licenses/OpenSSL.txt file, and distribute * - * linked combinations including the two. * - * * - * Any redistribution of Covered Software, including any derived works, * - * must obey and carry forward all of the terms of this license, including * - * obeying all GPL rules and restrictions. For example, source code of * - * the whole work must be provided and free redistribution must be * - * allowed. All GPL references to "this License", are to be treated as * - * including the terms and conditions of this license text as well. * - * * - * Because this license imposes special exceptions to the GPL, Covered * - * Work may not be combined (even as part of a larger work) with plain GPL * - * software. The terms, conditions, and exceptions of this license must * - * be included as well. This license is incompatible with some other open * - * source licenses as well. In some cases we can relicense portions of * - * RFIDler or grant special permissions to use it in other open source * - * software. Please contact sales@aperturelabs.com with any such requests.* - * Similarly, we don't incorporate incompatible open source software into * - * Covered Software without special permission from the copyright holders. * - * * - * If you have any questions about the licensing restrictions on using * - * RFIDler in other works, are happy to help. As mentioned above, we also * - * offer alternative license to integrate RFIDler into proprietary * - * applications and appliances. These contracts have been sold to dozens * - * of software vendors, and generally include a perpetual license as well * - * as providing for priority support and updates. They also fund the * - * continued development of RFIDler. Please email sales@aperturelabs.com * - * for further information. * - * If you have received a written license agreement or contract for * - * Covered Software stating terms other than these, you may choose to use * - * and redistribute Covered Software under those terms instead of these. * - * * - * Source is provided to this software because we believe users have a * - * right to know exactly what a program is going to do before they run it. * - * This also allows you to audit the software for security holes (none * - * have been found so far). * - * * - * Source code also allows you to port RFIDler to new platforms, fix bugs, * - * and add new features. You are highly encouraged to send your changes * - * to the RFIDler mailing list for possible incorporation into the * - * main distribution. By sending these changes to Aperture Labs Ltd. or * - * one of the Aperture Labs Ltd. development mailing lists, or checking * - * them into the RFIDler source code repository, it is understood (unless * - * you specify otherwise) that you are offering the RFIDler Project * - * (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, * - * modify, and relicense the code. RFIDler will always be available Open * - * Source, but this is important because the inability to relicense code * - * has caused devastating problems for other Free Software projects (such * - * as KDE and NASM). We also occasionally relicense the code to third * - * parties as discussed above. If you wish to specify special license * - * conditions of your contributions, just say so when you send them. * - * * - * This program is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler * - * license file for more details (it's in a COPYING file included with * - * RFIDler, and also available from * - * https://github.com/ApertureLabsLtd/RFIDler/COPYING * - * * - ***************************************************************************/ - -// Author: Adam Laurie - -/* - * Hitag Crypto support macros - * These macros reverse the bit order in a byte, or *within* each byte of a - * 16 , 32 or 64 bit unsigned integer. (Not across the whole 16 etc bits.) - */ -#define rev8(X) ((((X) >> 7) &1) + (((X) >> 5) &2) + (((X) >> 3) &4) \ - + (((X) >> 1) &8) + (((X) << 1) &16) + (((X) << 3) &32) \ - + (((X) << 5) &64) + (((X) << 7) &128) ) -#define rev16(X) (rev8 (X) + (rev8 (X >> 8) << 8)) -#define rev32(X) (rev16(X) + (rev16(X >> 16) << 16)) -#define rev64(X) (rev32(X) + (rev32(X >> 32) << 32)) - - -unsigned long hexreversetoulong(BYTE *hex); -unsigned long long hexreversetoulonglong(BYTE *hex); - diff --git a/tools/hitag2crack/crack5gpu/utilpart.c b/tools/hitag2crack/crack5gpu/utilpart.c deleted file mode 100644 index c46148491..000000000 --- a/tools/hitag2crack/crack5gpu/utilpart.c +++ /dev/null @@ -1,180 +0,0 @@ -/*************************************************************************** - * A copy of the GNU GPL is appended to this file. * - * * - * This licence is based on the nmap licence, and we express our gratitude * - * for the work that went into producing it. There is no other connection * - * between RFIDler and nmap either expressed or implied. * - * * - ********************** IMPORTANT RFIDler LICENSE TERMS ******************** - * * - * * - * All references to RFIDler herein imply all it's derivatives, namely: * - * * - * o RFIDler-LF Standard * - * o RFIDler-LF Lite * - * o RFIDler-LF Nekkid * - * * - * * - * RFIDler is (C) 2013-2014 Aperture Labs Ltd. * - * * - * This program is free software; you may redistribute and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE * - * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your * - * right to use, modify, and redistribute this software under certain * - * conditions. If you wish to embed RFIDler technology into proprietary * - * software or hardware, we sell alternative licenses * - * (contact sales@aperturelabs.com). * - * * - * Note that the GPL places important restrictions on "derivative works", * - * yet it does not provide a detailed definition of that term. To avoid * - * misunderstandings, we interpret that term as broadly as copyright law * - * allows. For example, we consider an application to constitute a * - * derivative work for the purpose of this license if it does any of the * - * following with any software or content covered by this license * - * ("Covered Software"): * - * * - * o Integrates source code from Covered Software. * - * * - * o Is designed specifically to execute Covered Software and parse the * - * results (as opposed to typical shell or execution-menu apps, which will * - * execute anything you tell them to). * - * * - * o Includes Covered Software in a proprietary executable installer. The * - * installers produced by InstallShield are an example of this. Including * - * RFIDler with other software in compressed or archival form does not * - * trigger this provision, provided appropriate open source decompression * - * or de-archiving software is widely available for no charge. For the * - * purposes of this license, an installer is considered to include Covered * - * Software even if it actually retrieves a copy of Covered Software from * - * another source during runtime (such as by downloading it from the * - * Internet). * - * * - * o Links (statically or dynamically) to a library which does any of the * - * above. * - * * - * o Executes a helper program, module, or script to do any of the above. * - * * - * This list is not exclusive, but is meant to clarify our interpretation * - * of derived works with some common examples. Other people may interpret * - * the plain GPL differently, so we consider this a special exception to * - * the GPL that we apply to Covered Software. Works which meet any of * - * these conditions must conform to all of the terms of this license, * - * particularly including the GPL Section 3 requirements of providing * - * source code and allowing free redistribution of the work as a whole. * - * * - * As another special exception to the GPL terms, Aperture Labs Ltd. grants* - * permission to link the code of this program with any version of the * - * OpenSSL library which is distributed under a license identical to that * - * listed in the included docs/licenses/OpenSSL.txt file, and distribute * - * linked combinations including the two. * - * * - * Any redistribution of Covered Software, including any derived works, * - * must obey and carry forward all of the terms of this license, including * - * obeying all GPL rules and restrictions. For example, source code of * - * the whole work must be provided and free redistribution must be * - * allowed. All GPL references to "this License", are to be treated as * - * including the terms and conditions of this license text as well. * - * * - * Because this license imposes special exceptions to the GPL, Covered * - * Work may not be combined (even as part of a larger work) with plain GPL * - * software. The terms, conditions, and exceptions of this license must * - * be included as well. This license is incompatible with some other open * - * source licenses as well. In some cases we can relicense portions of * - * RFIDler or grant special permissions to use it in other open source * - * software. Please contact sales@aperturelabs.com with any such requests.* - * Similarly, we don't incorporate incompatible open source software into * - * Covered Software without special permission from the copyright holders. * - * * - * If you have any questions about the licensing restrictions on using * - * RFIDler in other works, are happy to help. As mentioned above, we also * - * offer alternative license to integrate RFIDler into proprietary * - * applications and appliances. These contracts have been sold to dozens * - * of software vendors, and generally include a perpetual license as well * - * as providing for priority support and updates. They also fund the * - * continued development of RFIDler. Please email sales@aperturelabs.com * - * for further information. * - * If you have received a written license agreement or contract for * - * Covered Software stating terms other than these, you may choose to use * - * and redistribute Covered Software under those terms instead of these. * - * * - * Source is provided to this software because we believe users have a * - * right to know exactly what a program is going to do before they run it. * - * This also allows you to audit the software for security holes (none * - * have been found so far). * - * * - * Source code also allows you to port RFIDler to new platforms, fix bugs, * - * and add new features. You are highly encouraged to send your changes * - * to the RFIDler mailing list for possible incorporation into the * - * main distribution. By sending these changes to Aperture Labs Ltd. or * - * one of the Aperture Labs Ltd. development mailing lists, or checking * - * them into the RFIDler source code repository, it is understood (unless * - * you specify otherwise) that you are offering the RFIDler Project * - * (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, * - * modify, and relicense the code. RFIDler will always be available Open * - * Source, but this is important because the inability to relicense code * - * has caused devastating problems for other Free Software projects (such * - * as KDE and NASM). We also occasionally relicense the code to third * - * parties as discussed above. If you wish to specify special license * - * conditions of your contributions, just say so when you send them. * - * * - * This program is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler * - * license file for more details (it's in a COPYING file included with * - * RFIDler, and also available from * - * https://github.com/ApertureLabsLtd/RFIDler/COPYING * - * * - ***************************************************************************/ - -// Author: Adam Laurie - - -#include -#include -#include "HardwareProfile.h" -#include "util.h" -#include "rfidler.h" -//#include "comms.h" - -// rtc -rtccTime RTC_time; // time structure -rtccDate RTC_date; // date structure - -// convert byte-reversed 8 digit hex to unsigned long -unsigned long hexreversetoulong(BYTE *hex) { - unsigned long ret = 0L; - unsigned int x; - BYTE i; - - if (strlen(hex) != 8) - return 0L; - - for (i = 0 ; i < 4 ; ++i) { - if (sscanf(hex, "%2X", &x) != 1) - return 0L; - ret += ((unsigned long) x) << i * 8; - hex += 2; - } - return ret; -} - -// convert byte-reversed 12 digit hex to unsigned long -unsigned long long hexreversetoulonglong(BYTE *hex) { - unsigned long long ret = 0LL; - BYTE tmp[9]; - - // this may seem an odd way to do it, but weird compiler issues were - // breaking direct conversion! - - tmp[8] = '\0'; - memset(tmp + 4, '0', 4); - memcpy(tmp, hex + 8, 4); - ret = hexreversetoulong(tmp); - ret <<= 32; - memcpy(tmp, hex, 8); - ret += hexreversetoulong(tmp); - return ret; -} - - From 0181d5c8f037b1589176f1a28f1f525755174f56 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 4 Apr 2020 14:41:11 +0200 Subject: [PATCH 1854/1854] ht2 cleaning tools --- tools/hitag2crack/common/HardwareProfile.h | 524 -------------------- tools/hitag2crack/common/hitagcrypto.c | 3 - tools/hitag2crack/common/ht2crackutils.c | 35 ++ tools/hitag2crack/common/ht2crackutils.h | 21 +- tools/hitag2crack/common/rfidler.h | 412 --------------- tools/hitag2crack/common/util.h | 147 ------ tools/hitag2crack/common/utilpart.c | 180 ------- tools/hitag2crack/crack2/Makefile | 9 +- tools/hitag2crack/crack2/ht2crack2gentest.c | 1 - tools/hitag2crack/crack2/ht2crack2search.c | 1 - tools/hitag2crack/crack3/Makefile | 10 +- tools/hitag2crack/crack3/ht2crack3.c | 26 +- tools/hitag2crack/crack3/ht2test.c | 8 +- tools/hitag2crack/crack4/Makefile | 7 +- tools/hitag2crack/crack5/Makefile | 7 +- tools/hitag2crack/crack5gpu/Makefile | 7 +- 16 files changed, 68 insertions(+), 1330 deletions(-) delete mode 100644 tools/hitag2crack/common/HardwareProfile.h delete mode 100644 tools/hitag2crack/common/rfidler.h delete mode 100644 tools/hitag2crack/common/util.h delete mode 100644 tools/hitag2crack/common/utilpart.c diff --git a/tools/hitag2crack/common/HardwareProfile.h b/tools/hitag2crack/common/HardwareProfile.h deleted file mode 100644 index bce139042..000000000 --- a/tools/hitag2crack/common/HardwareProfile.h +++ /dev/null @@ -1,524 +0,0 @@ -/*************************************************************************** - * A copy of the GNU GPL is appended to this file. * - * * - * This licence is based on the nmap licence, and we express our gratitude * - * for the work that went into producing it. There is no other connection * - * between RFIDler and nmap either expressed or implied. * - * * - ********************** IMPORTANT RFIDler LICENSE TERMS ******************** - * * - * * - * All references to RFIDler herein imply all it's derivatives, namely: * - * * - * o RFIDler-LF Standard * - * o RFIDler-LF Lite * - * o RFIDler-LF Nekkid * - * * - * * - * RFIDler is (C) 2013-2014 Aperture Labs Ltd. * - * * - * This program is free software; you may redistribute and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE * - * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your * - * right to use, modify, and redistribute this software under certain * - * conditions. If you wish to embed RFIDler technology into proprietary * - * software or hardware, we sell alternative licenses * - * (contact sales@aperturelabs.com). * - * * - * Note that the GPL places important restrictions on "derivative works", * - * yet it does not provide a detailed definition of that term. To avoid * - * misunderstandings, we interpret that term as broadly as copyright law * - * allows. For example, we consider an application to constitute a * - * derivative work for the purpose of this license if it does any of the * - * following with any software or content covered by this license * - * ("Covered Software"): * - * * - * o Integrates source code from Covered Software. * - * * - * o Is designed specifically to execute Covered Software and parse the * - * results (as opposed to typical shell or execution-menu apps, which will * - * execute anything you tell them to). * - * * - * o Includes Covered Software in a proprietary executable installer. The * - * installers produced by InstallShield are an example of this. Including * - * RFIDler with other software in compressed or archival form does not * - * trigger this provision, provided appropriate open source decompression * - * or de-archiving software is widely available for no charge. For the * - * purposes of this license, an installer is considered to include Covered * - * Software even if it actually retrieves a copy of Covered Software from * - * another source during runtime (such as by downloading it from the * - * Internet). * - * * - * o Links (statically or dynamically) to a library which does any of the * - * above. * - * * - * o Executes a helper program, module, or script to do any of the above. * - * * - * This list is not exclusive, but is meant to clarify our interpretation * - * of derived works with some common examples. Other people may interpret * - * the plain GPL differently, so we consider this a special exception to * - * the GPL that we apply to Covered Software. Works which meet any of * - * these conditions must conform to all of the terms of this license, * - * particularly including the GPL Section 3 requirements of providing * - * source code and allowing free redistribution of the work as a whole. * - * * - * As another special exception to the GPL terms, Aperture Labs Ltd. grants* - * permission to link the code of this program with any version of the * - * OpenSSL library which is distributed under a license identical to that * - * listed in the included docs/licenses/OpenSSL.txt file, and distribute * - * linked combinations including the two. * - * * - * Any redistribution of Covered Software, including any derived works, * - * must obey and carry forward all of the terms of this license, including * - * obeying all GPL rules and restrictions. For example, source code of * - * the whole work must be provided and free redistribution must be * - * allowed. All GPL references to "this License", are to be treated as * - * including the terms and conditions of this license text as well. * - * * - * Because this license imposes special exceptions to the GPL, Covered * - * Work may not be combined (even as part of a larger work) with plain GPL * - * software. The terms, conditions, and exceptions of this license must * - * be included as well. This license is incompatible with some other open * - * source licenses as well. In some cases we can relicense portions of * - * RFIDler or grant special permissions to use it in other open source * - * software. Please contact sales@aperturelabs.com with any such requests.* - * Similarly, we don't incorporate incompatible open source software into * - * Covered Software without special permission from the copyright holders. * - * * - * If you have any questions about the licensing restrictions on using * - * RFIDler in other works, are happy to help. As mentioned above, we also * - * offer alternative license to integrate RFIDler into proprietary * - * applications and appliances. These contracts have been sold to dozens * - * of software vendors, and generally include a perpetual license as well * - * as providing for priority support and updates. They also fund the * - * continued development of RFIDler. Please email sales@aperturelabs.com * - * for further information. * - * If you have received a written license agreement or contract for * - * Covered Software stating terms other than these, you may choose to use * - * and redistribute Covered Software under those terms instead of these. * - * * - * Source is provided to this software because we believe users have a * - * right to know exactly what a program is going to do before they run it. * - * This also allows you to audit the software for security holes (none * - * have been found so far). * - * * - * Source code also allows you to port RFIDler to new platforms, fix bugs, * - * and add new features. You are highly encouraged to send your changes * - * to the RFIDler mailing list for possible incorporation into the * - * main distribution. By sending these changes to Aperture Labs Ltd. or * - * one of the Aperture Labs Ltd. development mailing lists, or checking * - * them into the RFIDler source code repository, it is understood (unless * - * you specify otherwise) that you are offering the RFIDler Project * - * (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, * - * modify, and relicense the code. RFIDler will always be available Open * - * Source, but this is important because the inability to relicense code * - * has caused devastating problems for other Free Software projects (such * - * as KDE and NASM). We also occasionally relicense the code to third * - * parties as discussed above. If you wish to specify special license * - * conditions of your contributions, just say so when you send them. * - * * - * This program is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler * - * license file for more details (it's in a COPYING file included with * - * RFIDler, and also available from * - * https://github.com/ApertureLabsLtd/RFIDler/COPYING * - * * - ***************************************************************************/ - -// Author: Adam Laurie - - - -#ifndef HARDWARE_PROFILE_UBW32_H -#define HARDWARE_PROFILE_UBW32_H - -//#include "plib.h" -typedef char BOOL; -typedef char BYTE; -typedef int rtccTime; -typedef int rtccDate; - - -#ifndef __PIC32MX__ -#define __PIC32MX__ -#endif - -#define GetSystemClock() (80000000ul) -#define GetPeripheralClock() (GetSystemClock()) -#define GetInstructionClock() (GetSystemClock()) - -//#define USE_SELF_POWER_SENSE_IO -#define tris_self_power TRISAbits.TRISA2 // Input -#define self_power 1 - -//#define USE_USB_BUS_SENSE_IO -#define tris_usb_bus_sense TRISBbits.TRISB5 // Input -#define USB_BUS_SENSE 1 - -// LEDs -#define mLED_1 LATEbits.LATE3 - -#define mLED_2 LATEbits.LATE2 -#define mLED_Comms mLED_2 - -#define mLED_3 LATEbits.LATE1 -#define mLED_Clock mLED_3 - -#define mLED_4 LATEbits.LATE0 -#define mLED_Emulate mLED_4 - -#define mLED_5 LATGbits.LATG6 -#define mLED_Read mLED_5 - -#define mLED_6 LATAbits.LATA15 -#define mLED_User mLED_6 - -#define mLED_7 LATDbits.LATD11 -#define mLED_Error mLED_7 - -// active low -#define mLED_ON 0 -#define mLED_OFF 1 - -#define mGetLED_1() mLED_1 -#define mGetLED_USB() mLED_1 -#define mGetLED_2() mLED_2 -#define mGetLED_Comms() mLED_2 -#define mGetLED_3() mLED_3 -#define mGetLED_Clock() mLED_3 -#define mGetLED_4() mLED_4 -#define mGetLED_Emulate() mLED_4 -#define mGetLED_5() mLED_5 -#define mGetLED_Read() mLED_5 -#define mGetLED_6() mLED_6 -#define mGetLED_User() mLED_6 -#define mGetLED_7() mLED_7 -#define mGetLED_Error() mLED_7 - -#define mLED_1_On() mLED_1 = mLED_ON -#define mLED_USB_On() mLED_1_On() -#define mLED_2_On() mLED_2 = mLED_ON -#define mLED_Comms_On() mLED_2_On() -#define mLED_3_On() mLED_3 = mLED_ON -#define mLED_Clock_On() mLED_3_On() -#define mLED_4_On() mLED_4 = mLED_ON -#define mLED_Emulate_On() mLED_4_On() -#define mLED_5_On() mLED_5 = mLED_ON -#define mLED_Read_On() mLED_5_On() -#define mLED_6_On() mLED_6 = mLED_ON -#define mLED_User_On() mLED_6_On() -#define mLED_7_On() mLED_7 = mLED_ON -#define mLED_Error_On() mLED_7_On() - -#define mLED_1_Off() mLED_1 = mLED_OFF -#define mLED_USB_Off() mLED_1_Off() -#define mLED_2_Off() mLED_2 = mLED_OFF -#define mLED_Comms_Off() mLED_2_Off() -#define mLED_3_Off() mLED_3 = mLED_OFF -#define mLED_Clock_Off() mLED_3_Off() -#define mLED_4_Off() mLED_4 = mLED_OFF -#define mLED_Emulate_Off() mLED_4_Off() -#define mLED_5_Off() mLED_5 = mLED_OFF -#define mLED_Read_Off() mLED_5_Off() -#define mLED_6_Off() mLED_6 = mLED_OFF -#define mLED_User_Off() mLED_6_Off() -#define mLED_7_Off() mLED_7 = mLED_OFF -#define mLED_Error_Off() mLED_7_Off() - -#define mLED_1_Toggle() mLED_1 = !mLED_1 -#define mLED_USB_Toggle() mLED_1_Toggle() -#define mLED_2_Toggle() mLED_2 = !mLED_2 -#define mLED_Comms_Toggle() mLED_2_Toggle() -#define mLED_3_Toggle() mLED_3 = !mLED_3 -#define mLED_Clock_Toggle() mLED_3_Toggle() -#define mLED_4_Toggle() mLED_4 = !mLED_4 -#define mLED_Emulate_Toggle() mLED_4_Toggle() -#define mLED_5_Toggle() mLED_5 = !mLED_5 -#define mLED_Read_Toggle( ) mLED_5_Toggle() -#define mLED_6_Toggle() mLED_6 = !mLED_6 -#define mLED_User_Toggle() mLED_6_Toggle() -#define mLED_7_Toggle() mLED_7 = !mLED_7 -#define mLED_Error_Toggle() mLED_7_Toggle() - -#define mLED_All_On() { mLED_1_On(); mLED_2_On(); mLED_3_On(); mLED_4_On(); mLED_5_On(); mLED_6_On(); mLED_7_On(); } -#define mLED_All_Off() { mLED_1_Off(); mLED_2_Off(); mLED_3_Off(); mLED_4_Off(); mLED_5_Off(); mLED_6_Off(); mLED_7_Off(); } - -// usb status lights -#define mLED_Both_Off() {mLED_USB_Off();mLED_Comms_Off();} -#define mLED_Both_On() {mLED_USB_On();mLED_Comms_On();} -#define mLED_Only_USB_On() {mLED_USB_On();mLED_Comms_Off();} -#define mLED_Only_Comms_On() {mLED_USB_Off();mLED_Comms_On();} - -/** SWITCH *********************************************************/ -#define swBootloader PORTEbits.RE7 -#define swUser PORTEbits.RE6 - -/** I/O pin definitions ********************************************/ -#define INPUT_PIN 1 -#define OUTPUT_PIN 0 - -#define TRUE 1 -#define FALSE 0 - -#define ENABLE 1 -#define DISABE 0 - -#define EVEN 0 -#define ODD 1 - -#define LOW FALSE -#define HIGH TRUE - -#define CLOCK_ON LOW -#define CLOCK_OFF HIGH - -// output coil control - select between reader/emulator circuits -#define COIL_MODE LATBbits.LATB4 -#define COIL_MODE_READER() COIL_MODE= LOW -#define COIL_MODE_EMULATOR() COIL_MODE= HIGH - -// coil for emulation -#define COIL_OUT LATGbits.LATG9 -#define COIL_OUT_HIGH() COIL_OUT=HIGH -#define COIL_OUT_LOW() COIL_OUT=LOW - -// door relay (active low) -#define DOOR_RELAY LATAbits.LATA14 -#define DOOR_RELAY_OPEN() DOOR_RELAY= HIGH -#define DOOR_RELAY_CLOSE() DOOR_RELAY= LOW - -// inductance/capacitance freq -#define IC_FREQUENCY PORTAbits.RA2 - -#define SNIFFER_COIL PORTDbits.RD12 // external reader clock detect -#define READER_ANALOGUE PORTBbits.RB11 // reader coil analogue -#define DIV_LOW_ANALOGUE PORTBbits.RB12 // voltage divider LOW analogue -#define DIV_HIGH_ANALOGUE PORTBbits.RB13 // voltage divider HIGH analogue - -// clock coil (normally controlled by OC Module, but defined here so we can force it high or low) -#define CLOCK_COIL PORTDbits.RD4 -#define CLOCK_COIL_MOVED PORTDbits.RD0 // temporary for greenwire - -// digital output after analogue reader circuit -#define READER_DATA PORTDbits.RD8 - -// trace / debug -#define DEBUG_PIN_1 LATCbits.LATC1 -#define DEBUG_PIN_1_TOGGLE() DEBUG_PIN_1= !DEBUG_PIN_1 -#define DEBUG_PIN_2 LATCbits.LATC2 -#define DEBUG_PIN_2_TOGGLE() DEBUG_PIN_2= !DEBUG_PIN_2 -#define DEBUG_PIN_3 LATCbits.LATC3 -#define DEBUG_PIN_3_TOGGLE() DEBUG_PIN_3= !DEBUG_PIN_3 -#define DEBUG_PIN_4 LATEbits.LATE5 -#define DEBUG_PIN_4_TOGGLE() DEBUG_PIN_4= !DEBUG_PIN_4 - -// spi (sdi1) for sd card (not directly referenced) -//#define SD_CARD_RX LATCbits.LATC4 -//#define SD_CARD_TX LATDbits.LATD0 -//#define SD_CARD_CLK LATDbits.LATD10 -//#define SD_CARD_SS LATDbits.LATD9 -// spi for SD card -#define SD_CARD_DET LATFbits.LATF0 -#define SD_CARD_WE LATFbits.LATF1 // write enable - unused for microsd but allocated anyway as library checks it -// (held LOW by default - cut solder bridge to GND to free pin if required) -#define SPI_SD SPI_CHANNEL1 -#define SPI_SD_BUFF SPI1BUF -#define SPI_SD_STAT SPI1STATbits -// see section below for more defines! - -// iso 7816 smartcard -// microchip SC module defines pins so we don't need to, but -// they are listed here to help avoid conflicts -#define ISO_7816_RX LATBbits.LATF2 // RX -#define ISO_7816_TX LATBbits.LATF8 // TX -#define ISO_7816_VCC LATBbits.LATB9 // Power -#define ISO_7816_CLK LATCbits.LATD1 // Clock -#define ISO_7816_RST LATEbits.LATE8 // Reset - -// user LED -#define USER_LED LATDbits.LATD7 -#define USER_LED_ON() LATDbits.LATD7=1 -#define USER_LED_OFF() LATDbits.LATD7=0 - -// LCR -#define LCR_CALIBRATE LATBbits.LATB5 - -// wiegand / clock & data -#define WIEGAND_IN_0 PORTDbits.RD5 -#define WIEGAND_IN_0_PULLUP CNPUEbits.CNPUE14 -#define WIEGAND_IN_0_PULLDOWN CNPDbits.CNPD14 -#define WIEGAND_IN_1 PORTDbits.RD6 -#define WIEGAND_IN_1_PULLUP CNPUEbits.CNPUE15 -#define WIEGAND_IN_1_PULLDOWN CNPDbits.CNPD15 -#define CAND_IN_DATA WIEGAND_IN_0 -#define CAND_IN_CLOCK WIEGAND_IN_1 - -#define WIEGAND_OUT_0 LATDbits.LATD3 -#define WIEGAND_OUT_1 LATDbits.LATD2 -#define WIEGAND_OUT_0_TRIS TRISDbits.TRISD3 -#define WIEGAND_OUT_1_TRIS TRISDbits.TRISD2 -#define CAND_OUT_DATA WIEGAND_OUT_0 -#define CAND_OUT_CLOCK WIEGAND_OUT_1 - -// connect/disconnect reader clock from coil - used to send RWD signals by creating gaps in carrier -#define READER_CLOCK_ENABLE LATEbits.LATE9 -#define READER_CLOCK_ENABLE_ON() READER_CLOCK_ENABLE=CLOCK_ON -#define READER_CLOCK_ENABLE_OFF(x) {READER_CLOCK_ENABLE=CLOCK_OFF; COIL_OUT=x;} - -// these input pins must NEVER bet set to output or they will cause short circuits! -// they can be used to see data from reader before it goes into or gate -#define OR_IN_A PORTAbits.RA4 -#define OR_IN_B PORTAbits.RA5 - - -// CNCON and CNEN are set to allow wiegand input pin weak pullups to be switched on -#define Init_GPIO() { \ - CNCONbits.ON= TRUE; \ - CNENbits.CNEN14= TRUE; \ - CNENbits.CNEN15= TRUE; \ - TRISAbits.TRISA2= INPUT_PIN; \ - TRISAbits.TRISA4= INPUT_PIN; \ - TRISAbits.TRISA5= INPUT_PIN; \ - TRISAbits.TRISA14= OUTPUT_PIN; \ - TRISAbits.TRISA15= OUTPUT_PIN; \ - TRISBbits.TRISB4= OUTPUT_PIN; \ - TRISBbits.TRISB5= OUTPUT_PIN; \ - TRISBbits.TRISB9= OUTPUT_PIN; \ - TRISBbits.TRISB11= INPUT_PIN; \ - TRISBbits.TRISB12= INPUT_PIN; \ - TRISBbits.TRISB13= INPUT_PIN; \ - TRISCbits.TRISC1= OUTPUT_PIN; \ - TRISCbits.TRISC2= OUTPUT_PIN; \ - TRISCbits.TRISC3= OUTPUT_PIN; \ - TRISCbits.TRISC4= INPUT_PIN; \ - TRISDbits.TRISD0= INPUT_PIN; \ - TRISDbits.TRISD1= OUTPUT_PIN; \ - TRISDbits.TRISD2= OUTPUT_PIN; \ - TRISDbits.TRISD3= OUTPUT_PIN; \ - TRISDbits.TRISD4= OUTPUT_PIN; \ - TRISDbits.TRISD5= INPUT_PIN; \ - TRISDbits.TRISD6= INPUT_PIN; \ - TRISDbits.TRISD7= OUTPUT_PIN; \ - TRISDbits.TRISD8= INPUT_PIN; \ - TRISDbits.TRISD11= OUTPUT_PIN; \ - TRISDbits.TRISD12= INPUT_PIN; \ - TRISEbits.TRISE0= OUTPUT_PIN; \ - TRISEbits.TRISE1= OUTPUT_PIN; \ - TRISEbits.TRISE2= OUTPUT_PIN; \ - TRISEbits.TRISE3= OUTPUT_PIN; \ - TRISEbits.TRISE5= OUTPUT_PIN; \ - TRISEbits.TRISE6= INPUT_PIN; \ - TRISEbits.TRISE7= INPUT_PIN; \ - TRISEbits.TRISE8= OUTPUT_PIN; \ - TRISEbits.TRISE9= OUTPUT_PIN; \ - TRISFbits.TRISF0= INPUT_PIN; \ - TRISFbits.TRISF1= INPUT_PIN; \ - TRISFbits.TRISF2= INPUT_PIN; \ - TRISFbits.TRISF8= OUTPUT_PIN; \ - TRISGbits.TRISG6= OUTPUT_PIN; \ - TRISGbits.TRISG12= INPUT_PIN; \ - TRISGbits.TRISG13= INPUT_PIN; \ - TRISGbits.TRISG9= OUTPUT_PIN; \ - LATBbits.LATB9= LOW; \ - LATCbits.LATC1= LOW; \ - LATCbits.LATC2= LOW; \ - LATCbits.LATC3= LOW; \ - LATDbits.LATD2= WIEGAND_IN_1; \ - LATDbits.LATD3= WIEGAND_IN_0; \ - LATEbits.LATE5= LOW; \ - LATEbits.LATE9= HIGH; \ - } - -// uart3 (CLI/API) speed -#define BAUDRATE3 115200UL -#define BRG_DIV3 4 -#define BRGH3 1 - -// spi for potentiometer -#define SPI_POT SPI_CHANNEL4 -#define SPI_POT_BUFF SPI4BUF -#define SPI_POT_STAT SPI4STATbits - -// spi for sd card - defines required for Microchip SD-SPI libs -// define interface type -#define USE_SD_INTERFACE_WITH_SPI - -#define MDD_USE_SPI_1 -#define SPI_START_CFG_1 (PRI_PRESCAL_64_1 | SEC_PRESCAL_8_1 | MASTER_ENABLE_ON | SPI_CKE_ON | SPI_SMP_ON) -#define SPI_START_CFG_2 (SPI_ENABLE) -// Define the SPI frequency -#define SPI_FREQUENCY (20000000) -// Description: SD-SPI Card Detect Input bit -#define SD_CD PORTFbits.RF0 -// Description: SD-SPI Card Detect TRIS bit -#define SD_CD_TRIS TRISFbits.TRISF0 -// Description: SD-SPI Write Protect Check Input bit -#define SD_WE PORTFbits.RF1 -// Description: SD-SPI Write Protect Check TRIS bit -#define SD_WE_TRIS TRISFbits.TRISF1 -// Description: The main SPI control register -#define SPICON1 SPI1CON -// Description: The SPI status register -#define SPISTAT SPI1STAT -// Description: The SPI Buffer -#define SPIBUF SPI1BUF -// Description: The receive buffer full bit in the SPI status register -#define SPISTAT_RBF SPI1STATbits.SPIRBF -// Description: The bitwise define for the SPI control register (i.e. _____bits) -#define SPICON1bits SPI1CONbits -// Description: The bitwise define for the SPI status register (i.e. _____bits) -#define SPISTATbits SPI1STATbits -// Description: The enable bit for the SPI module -#define SPIENABLE SPICON1bits.ON -// Description: The definition for the SPI baud rate generator register (PIC32) -#define SPIBRG SPI1BRG -// Description: The TRIS bit for the SCK pin -#define SPICLOCK TRISDbits.TRISD10 -// Description: The TRIS bit for the SDI pin -#define SPIIN TRISCbits.TRISC4 -// Description: The TRIS bit for the SDO pin -#define SPIOUT TRISDbits.TRISD0 -#define SD_CS LATDbits.LATD9 -// Description: SD-SPI Chip Select TRIS bit -#define SD_CS_TRIS TRISDbits.TRISD9 -//SPI library functions -#define putcSPI putcSPI1 -#define getcSPI getcSPI1 -#define OpenSPI(config1, config2) OpenSPI1(config1, config2) - -// Define setup parameters for OpenADC10 function -// Turn module on | Ouput in integer format | Trigger mode auto | Enable autosample -#define ADC_CONFIG1 (ADC_FORMAT_INTG | ADC_CLK_AUTO | ADC_AUTO_SAMPLING_ON) -// ADC ref external | Disable offset test | Disable scan mode | Perform 2 samples | Use dual buffers | Use alternate mode -#define ADC_CONFIG2 (ADC_VREF_AVDD_AVSS | ADC_OFFSET_CAL_DISABLE | ADC_SCAN_OFF | ADC_SAMPLES_PER_INT_1 | ADC_ALT_BUF_ON | ADC_ALT_INPUT_ON) - -// Use ADC internal clock | Set sample time -#define ADC_CONFIG3 (ADC_CONV_CLK_INTERNAL_RC | ADC_SAMPLE_TIME_0) - -// slow sample rate for tuning coils -#define ADC_CONFIG2_SLOW (ADC_VREF_AVDD_AVSS | ADC_OFFSET_CAL_DISABLE | ADC_SCAN_OFF | ADC_SAMPLES_PER_INT_16 | ADC_ALT_BUF_ON | ADC_ALT_INPUT_ON) -#define ADC_CONFIG3_SLOW (ADC_CONV_CLK_INTERNAL_RC | ADC_SAMPLE_TIME_31) - -// use AN11 -#define ADC_CONFIGPORT ENABLE_AN11_ANA -// Do not assign channels to scan -#define ADC_CONFIGSCAN SKIP_SCAN_ALL - -#define ADC_TO_VOLTS 0.003208F - - -// flash memory - int myvar = *(int*)(myflashmemoryaddress); - -// memory is 0x9D005000 to 0x9D07FFFF - -#define NVM_MEMORY_END 0x9D07FFFF -#define NVM_PAGE_SIZE 4096 -#define NVM_PAGES 2 // config & VTAG -#define RFIDLER_NVM_ADDRESS (NVM_MEMORY_END - (NVM_PAGE_SIZE * NVM_PAGES)) - -// UART timeout in us -#define SERIAL_TIMEOUT 100 - -#endif diff --git a/tools/hitag2crack/common/hitagcrypto.c b/tools/hitag2crack/common/hitagcrypto.c index 47449c3e3..03341f216 100644 --- a/tools/hitag2crack/common/hitagcrypto.c +++ b/tools/hitag2crack/common/hitagcrypto.c @@ -136,10 +136,7 @@ // #define TEST_DEBUG //#include -#include "HardwareProfile.h" -#include "rfidler.h" #include "hitagcrypto.h" -#include "util.h" #ifdef UNIT_TEST #include diff --git a/tools/hitag2crack/common/ht2crackutils.c b/tools/hitag2crack/common/ht2crackutils.c index 69061759c..8b67cf789 100644 --- a/tools/hitag2crack/common/ht2crackutils.c +++ b/tools/hitag2crack/common/ht2crackutils.c @@ -1,3 +1,5 @@ +#include +#include #include "ht2crackutils.h" // writes a value into a buffer as a series of bytes @@ -168,5 +170,38 @@ void buildlfsr(Hitag_State *hstate) { ^ (temp >> 42) ^ (temp >> 46); } +// convert byte-reversed 8 digit hex to unsigned long +unsigned long hexreversetoulong(char *hex) { + unsigned long ret = 0L; + unsigned int x; + char i; + if (strlen(hex) != 8) + return 0L; + for (i = 0 ; i < 4 ; ++i) { + if (sscanf(hex, "%2X", &x) != 1) + return 0L; + ret += ((unsigned long) x) << i * 8; + hex += 2; + } + return ret; +} + +// convert byte-reversed 12 digit hex to unsigned long +unsigned long long hexreversetoulonglong(char *hex) { + unsigned long long ret = 0LL; + char tmp[9]; + + // this may seem an odd way to do it, but weird compiler issues were + // breaking direct conversion! + + tmp[8] = '\0'; + memset(tmp + 4, '0', 4); + memcpy(tmp, hex + 8, 4); + ret = hexreversetoulong(tmp); + ret <<= 32; + memcpy(tmp, hex, 8); + ret += hexreversetoulong(tmp); + return ret; +} diff --git a/tools/hitag2crack/common/ht2crackutils.h b/tools/hitag2crack/common/ht2crackutils.h index 14eea840c..41c3a07c2 100644 --- a/tools/hitag2crack/common/ht2crackutils.h +++ b/tools/hitag2crack/common/ht2crackutils.h @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -8,16 +9,10 @@ #include #include -#include "HardwareProfile.h" -#include "rfidler.h" -#include "util.h" - #include "hitagcrypto.h" #define HEX_PER_ROW 16 - - void writebuf(unsigned char *buf, uint64_t val, unsigned int len); void shexdump(unsigned char *data, int data_len); void printbin(unsigned char *c); @@ -32,3 +27,17 @@ int fb(unsigned int i); int fc(unsigned int i); int fnf(uint64_t s); void buildlfsr(Hitag_State *hstate); + +/* + * Hitag Crypto support macros + * These macros reverse the bit order in a byte, or *within* each byte of a + * 16 , 32 or 64 bit unsigned integer. (Not across the whole 16 etc bits.) + */ +#define rev8(X) ((((X) >> 7) &1) + (((X) >> 5) &2) + (((X) >> 3) &4) \ + + (((X) >> 1) &8) + (((X) << 1) &16) + (((X) << 3) &32) \ + + (((X) << 5) &64) + (((X) << 7) &128) ) +#define rev16(X) (rev8 (X) + (rev8 (X >> 8) << 8)) +#define rev32(X) (rev16(X) + (rev16(X >> 16) << 16)) +#define rev64(X) (rev32(X) + (rev32(X >> 32) << 32)) +unsigned long hexreversetoulong(char *hex); +unsigned long long hexreversetoulonglong(char *hex); diff --git a/tools/hitag2crack/common/rfidler.h b/tools/hitag2crack/common/rfidler.h deleted file mode 100644 index 933547e6b..000000000 --- a/tools/hitag2crack/common/rfidler.h +++ /dev/null @@ -1,412 +0,0 @@ -/*************************************************************************** - * A copy of the GNU GPL is appended to this file. * - * * - * This licence is based on the nmap licence, and we express our gratitude * - * for the work that went into producing it. There is no other connection * - * between RFIDler and nmap either expressed or implied. * - * * - ********************** IMPORTANT RFIDler LICENSE TERMS ******************** - * * - * * - * All references to RFIDler herein imply all it's derivatives, namely: * - * * - * o RFIDler-LF Standard * - * o RFIDler-LF Lite * - * o RFIDler-LF Nekkid * - * * - * * - * RFIDler is (C) 2013-2015 Aperture Labs Ltd. * - * * - * This program is free software; you may redistribute and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE * - * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your * - * right to use, modify, and redistribute this software under certain * - * conditions. If you wish to embed RFIDler technology into proprietary * - * software or hardware, we sell alternative licenses * - * (contact sales@aperturelabs.com). * - * * - * Note that the GPL places important restrictions on "derivative works", * - * yet it does not provide a detailed definition of that term. To avoid * - * misunderstandings, we interpret that term as broadly as copyright law * - * allows. For example, we consider an application to constitute a * - * derivative work for the purpose of this license if it does any of the * - * following with any software or content covered by this license * - * ("Covered Software"): * - * * - * o Integrates source code from Covered Software. * - * * - * o Is designed specifically to execute Covered Software and parse the * - * results (as opposed to typical shell or execution-menu apps, which will * - * execute anything you tell them to). * - * * - * o Includes Covered Software in a proprietary executable installer. The * - * installers produced by InstallShield are an example of this. Including * - * RFIDler with other software in compressed or archival form does not * - * trigger this provision, provided appropriate open source decompression * - * or de-archiving software is widely available for no charge. For the * - * purposes of this license, an installer is considered to include Covered * - * Software even if it actually retrieves a copy of Covered Software from * - * another source during runtime (such as by downloading it from the * - * Internet). * - * * - * o Links (statically or dynamically) to a library which does any of the * - * above. * - * * - * o Executes a helper program, module, or script to do any of the above. * - * * - * This list is not exclusive, but is meant to clarify our interpretation * - * of derived works with some common examples. Other people may interpret * - * the plain GPL differently, so we consider this a special exception to * - * the GPL that we apply to Covered Software. Works which meet any of * - * these conditions must conform to all of the terms of this license, * - * particularly including the GPL Section 3 requirements of providing * - * source code and allowing free redistribution of the work as a whole. * - * * - * As another special exception to the GPL terms, Aperture Labs Ltd. grants* - * permission to link the code of this program with any version of the * - * OpenSSL library which is distributed under a license identical to that * - * listed in the included docs/licenses/OpenSSL.txt file, and distribute * - * linked combinations including the two. * - * * - * Any redistribution of Covered Software, including any derived works, * - * must obey and carry forward all of the terms of this license, including * - * obeying all GPL rules and restrictions. For example, source code of * - * the whole work must be provided and free redistribution must be * - * allowed. All GPL references to "this License", are to be treated as * - * including the terms and conditions of this license text as well. * - * * - * Because this license imposes special exceptions to the GPL, Covered * - * Work may not be combined (even as part of a larger work) with plain GPL * - * software. The terms, conditions, and exceptions of this license must * - * be included as well. This license is incompatible with some other open * - * source licenses as well. In some cases we can relicense portions of * - * RFIDler or grant special permissions to use it in other open source * - * software. Please contact sales@aperturelabs.com with any such requests.* - * Similarly, we don't incorporate incompatible open source software into * - * Covered Software without special permission from the copyright holders. * - * * - * If you have any questions about the licensing restrictions on using * - * RFIDler in other works, are happy to help. As mentioned above, we also * - * offer alternative license to integrate RFIDler into proprietary * - * applications and appliances. These contracts have been sold to dozens * - * of software vendors, and generally include a perpetual license as well * - * as providing for priority support and updates. They also fund the * - * continued development of RFIDler. Please email sales@aperturelabs.com * - * for further information. * - * If you have received a written license agreement or contract for * - * Covered Software stating terms other than these, you may choose to use * - * and redistribute Covered Software under those terms instead of these. * - * * - * Source is provided to this software because we believe users have a * - * right to know exactly what a program is going to do before they run it. * - * This also allows you to audit the software for security holes (none * - * have been found so far). * - * * - * Source code also allows you to port RFIDler to new platforms, fix bugs, * - * and add new features. You are highly encouraged to send your changes * - * to the RFIDler mailing list for possible incorporation into the * - * main distribution. By sending these changes to Aperture Labs Ltd. or * - * one of the Aperture Labs Ltd. development mailing lists, or checking * - * them into the RFIDler source code repository, it is understood (unless * - * you specify otherwise) that you are offering the RFIDler Project * - * (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, * - * modify, and relicense the code. RFIDler will always be available Open * - * Source, but this is important because the inability to relicense code * - * has caused devastating problems for other Free Software projects (such * - * as KDE and NASM). We also occasionally relicense the code to third * - * parties as discussed above. If you wish to specify special license * - * conditions of your contributions, just say so when you send them. * - * * - * This program is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler * - * license file for more details (it's in a COPYING file included with * - * RFIDler, and also available from * - * https://github.com/ApertureLabsLtd/RFIDler/COPYING * - * * - ***************************************************************************/ - -// Author: Adam Laurie - -#include -#include - -// BCD hardware revision for usb descriptor (usb_descriptors.c) -#define RFIDLER_HW_VERSION 0x020 - -// max sizes in BITS -#define MAXBLOCKSIZE 512 -#define MAXTAGSIZE 4096 -#define MAXUID 512 - -#define TMP_LARGE_BUFF_LEN 2048 -#define TMP_SMALL_BUFF_LEN 256 -#define ANALOGUE_BUFF_LEN 8192 - -#define COMMS_BUFFER_SIZE 128 - -#define DETECT_BUFFER_SIZE 512 - -#define SAMPLEMASK ~(BIT_1 | BIT_0) // mask to remove two bottom bits from analogue sample - we will then use those for reader & bit period - -// globals - -extern BOOL WiegandOutput; // Output wiegand data whenenver UID is read -extern BYTE *EMU_Reset_Data; // Pointer to full array of bits as bytes, stored as 0x00/0x01, '*' terminated -extern BYTE *EMU_Data; // Pointer to current location in EMU_Reset_Data -extern BYTE EMU_ThisBit; // The next data bit to transmit -extern BYTE EMU_SubCarrier_T0; // Number of Frame Clocks for sub-carrier '0' -extern BYTE EMU_SubCarrier_T1; // Number of Frame Clocks for sub-carrier '1' -extern unsigned int EMU_Repeat; // Number of times to transmit full data set -extern BOOL EMU_Background; // Emulate in the background until told to stop -extern unsigned int EMU_DataBitRate; // Number of Frame Clocks per bit -extern BYTE TmpBits[TMP_LARGE_BUFF_LEN]; // Shared scratchpad -extern BYTE ReaderPeriod; // Flag for sample display -extern unsigned char Comms_In_Buffer[COMMS_BUFFER_SIZE]; // USB/Serial buffer -extern BYTE Interface; // user interface - CLI or API -extern BYTE CommsChannel; // user comms channel - USB or UART -extern BOOL FakeRead; // flag for analogue sampler to signal it wants access to buffers during read -extern BOOL PWD_Mode; // is this tag password protected? -extern BYTE Password[9]; // 32 bits as HEX string set with LOGIN -extern unsigned int Led_Count; // LED status counter, also used for entropy -extern unsigned long Reader_Bit_Count; // Reader ISR bit counter -extern char Previous; // Reader ISR previous bit type - -// RWD (read/write device) coil state -extern BYTE RWD_State; // current state of RWD coil -extern unsigned int RWD_Fc; // field clock in uS -extern unsigned int RWD_Gap_Period; // length of command gaps in OC5 ticks -extern unsigned int RWD_Zero_Period; // length of '0' in OC5 ticks -extern unsigned int RWD_One_Period; // length of '1' in OC5 ticks -extern unsigned int RWD_Sleep_Period; // length of initial sleep to reset tag in OC5 ticks -extern unsigned int RWD_Wake_Period; // length required for tag to restart in OC5 ticks -extern unsigned int RWD_Wait_Switch_TX_RX; // length to wait when switching from TX to RX in OC5 ticks -extern unsigned int RWD_Wait_Switch_RX_TX; // length to wait when switching from RX to TX in OC5 ticks -extern unsigned int RWD_Post_Wait; // low level ISR wait period in OC5 ticks -extern unsigned int RWD_OC5_config; // Output Compare Module settings -extern unsigned int RWD_OC5_r; // Output Compare Module primary compare value -extern unsigned int RWD_OC5_rs; // Output Compare Module secondary compare value -extern BYTE RWD_Command_Buff[TMP_SMALL_BUFF_LEN]; // Command buffer, array of bits as bytes, stored as 0x00/0x01, '*' terminated -extern BYTE *RWD_Command_ThisBit; // Current command bit -extern BOOL Reader_ISR_State; // current state of reader ISR - -// NVM variables -// timings etc. that want to survive a reboot should go here -typedef struct { - BYTE Name[7]; // will be set to "RFIDler" so we can test for new device - BYTE AutoRun[128]; // optional command to run at startup - unsigned char TagType; - unsigned int PSK_Quality; - unsigned int Timeout; - unsigned int Wiegand_Pulse; - unsigned int Wiegand_Gap; - BOOL Wiegand_IdleState; - unsigned int FrameClock; - unsigned char Modulation; - unsigned int DataRate; - unsigned int DataRateSub0; - unsigned int DataRateSub1; - unsigned int DataBits; - unsigned int DataBlocks; - unsigned int BlockSize; - unsigned char SyncBits; - BYTE Sync[4]; - BOOL BiPhase; - BOOL Invert; - BOOL Manchester; - BOOL HalfDuplex; - unsigned int Repeat; - unsigned int PotLow; - unsigned int PotHigh; - unsigned int RWD_Gap_Period; - unsigned int RWD_Zero_Period; - unsigned int RWD_One_Period; - unsigned int RWD_Sleep_Period; - unsigned int RWD_Wake_Period; - unsigned int RWD_Wait_Switch_TX_RX; - unsigned int RWD_Wait_Switch_RX_TX; -} StoredConfig; - -// somewhere to store TAG data. this will be interpreted according to the TAG -// type. -typedef struct { - BYTE TagType; // raw tag type - BYTE EmulatedTagType; // tag type this tag is configured to emulate - BYTE UID[MAXUID + 1]; // Null-terminated HEX string - BYTE Data[MAXTAGSIZE]; // raw data - unsigned char DataBlocks; // number of blocks in Data field - unsigned int BlockSize; // blocksize in bits -} VirtualTag; - -extern StoredConfig RFIDlerConfig; -extern VirtualTag RFIDlerVTag; -extern BYTE TmpBuff[NVM_PAGE_SIZE]; -extern BYTE DataBuff[ANALOGUE_BUFF_LEN]; -extern unsigned int DataBuffCount; -extern const BYTE *ModulationSchemes[]; -extern const BYTE *OnOff[]; -extern const BYTE *HighLow[]; -extern const BYTE *TagTypes[]; - -// globals for ISRs -extern BYTE EmulationMode; -extern unsigned long HW_Bits; -extern BYTE HW_Skip_Bits; -extern unsigned int PSK_Min_Pulse; -extern BOOL PSK_Read_Error; -extern BOOL Manchester_Error; -extern BOOL SnifferMode; -extern unsigned int Clock_Tick_Counter; -extern BOOL Clock_Tick_Counter_Reset; - -// smart card lib -#define MAX_ATR_LEN (BYTE)33 -extern BYTE scCardATR[MAX_ATR_LEN]; -extern BYTE scATRLength; - -// RTC -extern rtccTime RTC_time; // time structure -extern rtccDate RTC_date; // date structure - -// digital pots -#define POTLOW_DEFAULT 100 -#define POTHIGH_DEFAULT 150 -#define DC_OFFSET 60 // analogue circuit DC offset (as close as we can get without using 2 LSB) -#define VOLTS_TO_POT 0.019607843F - -// RWD/clock states -#define RWD_STATE_INACTIVE 0 // RWD not in use -#define RWD_STATE_GO_TO_SLEEP 1 // RWD coil shutdown request -#define RWD_STATE_SLEEPING 2 // RWD coil shutdown for sleep period -#define RWD_STATE_WAKING 3 // RWD active for pre-determined period after reset -#define RWD_STATE_START_SEND 4 // RWD starting send of data -#define RWD_STATE_SENDING_GAP 5 // RWD sending a gap -#define RWD_STATE_SENDING_BIT 6 // RWD sending a data bit -#define RWD_STATE_POST_WAIT 7 // RWD finished sending data, now in forced wait period -#define RWD_STATE_ACTIVE 8 // RWD finished, now just clocking a carrier - -// reader ISR states -#define READER_STOPPED 0 // reader not in use -#define READER_IDLING 1 // reader ISR running to preserve timing, but not reading -#define READER_RUNNING 2 // reader reading bits - - -// user interface types -#define INTERFACE_API 0 -#define INTERFACE_CLI 1 - -// comms channel -#define COMMS_NONE 0 -#define COMMS_USB 1 -#define COMMS_UART 2 - -#define MAX_HISTORY 2 // disable most of history for now - memory issue - -// tag write retries -#define TAG_WRITE_RETRY 5 - -// modulation modes - uppdate ModulationSchemes[] in tags.c if you change this -#define MOD_MODE_NONE 0 -#define MOD_MODE_ASK_OOK 1 -#define MOD_MODE_FSK1 2 -#define MOD_MODE_FSK2 3 -#define MOD_MODE_PSK1 4 -#define MOD_MODE_PSK2 5 -#define MOD_MODE_PSK3 6 - -// TAG types - update TagTypes[] in tags.c if you add to this list -#define TAG_TYPE_NONE 0 -#define TAG_TYPE_ASK_RAW 1 -#define TAG_TYPE_FSK1_RAW 2 -#define TAG_TYPE_FSK2_RAW 3 -#define TAG_TYPE_PSK1_RAW 4 -#define TAG_TYPE_PSK2_RAW 5 -#define TAG_TYPE_PSK3_RAW 6 -#define TAG_TYPE_HITAG1 7 -#define TAG_TYPE_HITAG2 8 -#define TAG_TYPE_EM4X02 9 -#define TAG_TYPE_Q5 10 -#define TAG_TYPE_HID_26 11 -#define TAG_TYPE_INDALA_64 12 -#define TAG_TYPE_INDALA_224 13 -#define TAG_TYPE_UNIQUE 14 -#define TAG_TYPE_FDXB 15 -#define TAG_TYPE_T55X7 16 // same as Q5 but different timings and no modulation-defeat -#define TAG_TYPE_AWID_26 17 -#define TAG_TYPE_EM4X05 18 -#define TAG_TYPE_TAMAGOTCHI 19 -#define TAG_TYPE_HDX 20 // same underlying data as FDX-B, but different modulation & telegram - -// various - -#define BINARY 0 -#define HEX 1 - -#define NO_ADDRESS -1 - -#define ACK TRUE -#define NO_ACK FALSE - -#define BLOCK TRUE -#define NO_BLOCK FALSE - -#define DATA TRUE -#define NO_DATA FALSE - -#define DEBUG_PIN_ON HIGH -#define DEBUG_PIN_OFF LOW - -#define FAST FALSE -#define SLOW TRUE - -#define NO_TRIGGER 0 - -#define LOCK TRUE -#define NO_LOCK FALSE - -#define NFC_MODE TRUE -#define NO_NFC_MODE FALSE - -#define ONESHOT_READ TRUE -#define NO_ONESHOT_READ FALSE - -#define RESET TRUE -#define NO_RESET FALSE - -#define SHUTDOWN_CLOCK TRUE -#define NO_SHUTDOWN_CLOCK FALSE - -#define SYNC TRUE -#define NO_SYNC FALSE - -#define VERIFY TRUE -#define NO_VERIFY FALSE - -#define VOLATILE FALSE -#define NON_VOLATILE TRUE - -#define NEWLINE TRUE -#define NO_NEWLINE FALSE - -#define WAIT TRUE -#define NO_WAIT FALSE - -#define WIPER_HIGH 0 -#define WIPER_LOW 1 - -// conversion for time to ticks -#define US_TO_TICKS 1000000L -#define US_OVER_10_TO_TICKS 10000000L -#define US_OVER_100_TO_TICKS 100000000L -// we can't get down to this level on pic, but we want to standardise on timings, so for now we fudge it -#define CONVERT_TO_TICKS(x) ((x / 10) * (GetSystemClock() / US_OVER_10_TO_TICKS)) -#define CONVERT_TICKS_TO_US(x) (x / (GetSystemClock() / US_TO_TICKS)) -#define TIMER5_PRESCALER 16 -#define MAX_TIMER5_TICKS (65535 * TIMER5_PRESCALER) - -// other conversions - -// bits to hex digits -#define HEXDIGITS(x) (x / 4) -#define HEXTOBITS(x) (x * 4) diff --git a/tools/hitag2crack/common/util.h b/tools/hitag2crack/common/util.h deleted file mode 100644 index c2399c37c..000000000 --- a/tools/hitag2crack/common/util.h +++ /dev/null @@ -1,147 +0,0 @@ -/*************************************************************************** - * A copy of the GNU GPL is appended to this file. * - * * - * This licence is based on the nmap licence, and we express our gratitude * - * for the work that went into producing it. There is no other connection * - * between RFIDler and nmap either expressed or implied. * - * * - ********************** IMPORTANT RFIDler LICENSE TERMS ******************** - * * - * * - * All references to RFIDler herein imply all it's derivatives, namely: * - * * - * o RFIDler-LF Standard * - * o RFIDler-LF Lite * - * o RFIDler-LF Nekkid * - * * - * * - * RFIDler is (C) 2013-2015 Aperture Labs Ltd. * - * * - * This program is free software; you may redistribute and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE * - * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your * - * right to use, modify, and redistribute this software under certain * - * conditions. If you wish to embed RFIDler technology into proprietary * - * software or hardware, we sell alternative licenses * - * (contact sales@aperturelabs.com). * - * * - * Note that the GPL places important restrictions on "derivative works", * - * yet it does not provide a detailed definition of that term. To avoid * - * misunderstandings, we interpret that term as broadly as copyright law * - * allows. For example, we consider an application to constitute a * - * derivative work for the purpose of this license if it does any of the * - * following with any software or content covered by this license * - * ("Covered Software"): * - * * - * o Integrates source code from Covered Software. * - * * - * o Is designed specifically to execute Covered Software and parse the * - * results (as opposed to typical shell or execution-menu apps, which will * - * execute anything you tell them to). * - * * - * o Includes Covered Software in a proprietary executable installer. The * - * installers produced by InstallShield are an example of this. Including * - * RFIDler with other software in compressed or archival form does not * - * trigger this provision, provided appropriate open source decompression * - * or de-archiving software is widely available for no charge. For the * - * purposes of this license, an installer is considered to include Covered * - * Software even if it actually retrieves a copy of Covered Software from * - * another source during runtime (such as by downloading it from the * - * Internet). * - * * - * o Links (statically or dynamically) to a library which does any of the * - * above. * - * * - * o Executes a helper program, module, or script to do any of the above. * - * * - * This list is not exclusive, but is meant to clarify our interpretation * - * of derived works with some common examples. Other people may interpret * - * the plain GPL differently, so we consider this a special exception to * - * the GPL that we apply to Covered Software. Works which meet any of * - * these conditions must conform to all of the terms of this license, * - * particularly including the GPL Section 3 requirements of providing * - * source code and allowing free redistribution of the work as a whole. * - * * - * As another special exception to the GPL terms, Aperture Labs Ltd. grants* - * permission to link the code of this program with any version of the * - * OpenSSL library which is distributed under a license identical to that * - * listed in the included docs/licenses/OpenSSL.txt file, and distribute * - * linked combinations including the two. * - * * - * Any redistribution of Covered Software, including any derived works, * - * must obey and carry forward all of the terms of this license, including * - * obeying all GPL rules and restrictions. For example, source code of * - * the whole work must be provided and free redistribution must be * - * allowed. All GPL references to "this License", are to be treated as * - * including the terms and conditions of this license text as well. * - * * - * Because this license imposes special exceptions to the GPL, Covered * - * Work may not be combined (even as part of a larger work) with plain GPL * - * software. The terms, conditions, and exceptions of this license must * - * be included as well. This license is incompatible with some other open * - * source licenses as well. In some cases we can relicense portions of * - * RFIDler or grant special permissions to use it in other open source * - * software. Please contact sales@aperturelabs.com with any such requests.* - * Similarly, we don't incorporate incompatible open source software into * - * Covered Software without special permission from the copyright holders. * - * * - * If you have any questions about the licensing restrictions on using * - * RFIDler in other works, are happy to help. As mentioned above, we also * - * offer alternative license to integrate RFIDler into proprietary * - * applications and appliances. These contracts have been sold to dozens * - * of software vendors, and generally include a perpetual license as well * - * as providing for priority support and updates. They also fund the * - * continued development of RFIDler. Please email sales@aperturelabs.com * - * for further information. * - * If you have received a written license agreement or contract for * - * Covered Software stating terms other than these, you may choose to use * - * and redistribute Covered Software under those terms instead of these. * - * * - * Source is provided to this software because we believe users have a * - * right to know exactly what a program is going to do before they run it. * - * This also allows you to audit the software for security holes (none * - * have been found so far). * - * * - * Source code also allows you to port RFIDler to new platforms, fix bugs, * - * and add new features. You are highly encouraged to send your changes * - * to the RFIDler mailing list for possible incorporation into the * - * main distribution. By sending these changes to Aperture Labs Ltd. or * - * one of the Aperture Labs Ltd. development mailing lists, or checking * - * them into the RFIDler source code repository, it is understood (unless * - * you specify otherwise) that you are offering the RFIDler Project * - * (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, * - * modify, and relicense the code. RFIDler will always be available Open * - * Source, but this is important because the inability to relicense code * - * has caused devastating problems for other Free Software projects (such * - * as KDE and NASM). We also occasionally relicense the code to third * - * parties as discussed above. If you wish to specify special license * - * conditions of your contributions, just say so when you send them. * - * * - * This program is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler * - * license file for more details (it's in a COPYING file included with * - * RFIDler, and also available from * - * https://github.com/ApertureLabsLtd/RFIDler/COPYING * - * * - ***************************************************************************/ - -// Author: Adam Laurie - -/* - * Hitag Crypto support macros - * These macros reverse the bit order in a byte, or *within* each byte of a - * 16 , 32 or 64 bit unsigned integer. (Not across the whole 16 etc bits.) - */ -#define rev8(X) ((((X) >> 7) &1) + (((X) >> 5) &2) + (((X) >> 3) &4) \ - + (((X) >> 1) &8) + (((X) << 1) &16) + (((X) << 3) &32) \ - + (((X) << 5) &64) + (((X) << 7) &128) ) -#define rev16(X) (rev8 (X) + (rev8 (X >> 8) << 8)) -#define rev32(X) (rev16(X) + (rev16(X >> 16) << 16)) -#define rev64(X) (rev32(X) + (rev32(X >> 32) << 32)) - - -unsigned long hexreversetoulong(BYTE *hex); -unsigned long long hexreversetoulonglong(BYTE *hex); - diff --git a/tools/hitag2crack/common/utilpart.c b/tools/hitag2crack/common/utilpart.c deleted file mode 100644 index c46148491..000000000 --- a/tools/hitag2crack/common/utilpart.c +++ /dev/null @@ -1,180 +0,0 @@ -/*************************************************************************** - * A copy of the GNU GPL is appended to this file. * - * * - * This licence is based on the nmap licence, and we express our gratitude * - * for the work that went into producing it. There is no other connection * - * between RFIDler and nmap either expressed or implied. * - * * - ********************** IMPORTANT RFIDler LICENSE TERMS ******************** - * * - * * - * All references to RFIDler herein imply all it's derivatives, namely: * - * * - * o RFIDler-LF Standard * - * o RFIDler-LF Lite * - * o RFIDler-LF Nekkid * - * * - * * - * RFIDler is (C) 2013-2014 Aperture Labs Ltd. * - * * - * This program is free software; you may redistribute and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE * - * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your * - * right to use, modify, and redistribute this software under certain * - * conditions. If you wish to embed RFIDler technology into proprietary * - * software or hardware, we sell alternative licenses * - * (contact sales@aperturelabs.com). * - * * - * Note that the GPL places important restrictions on "derivative works", * - * yet it does not provide a detailed definition of that term. To avoid * - * misunderstandings, we interpret that term as broadly as copyright law * - * allows. For example, we consider an application to constitute a * - * derivative work for the purpose of this license if it does any of the * - * following with any software or content covered by this license * - * ("Covered Software"): * - * * - * o Integrates source code from Covered Software. * - * * - * o Is designed specifically to execute Covered Software and parse the * - * results (as opposed to typical shell or execution-menu apps, which will * - * execute anything you tell them to). * - * * - * o Includes Covered Software in a proprietary executable installer. The * - * installers produced by InstallShield are an example of this. Including * - * RFIDler with other software in compressed or archival form does not * - * trigger this provision, provided appropriate open source decompression * - * or de-archiving software is widely available for no charge. For the * - * purposes of this license, an installer is considered to include Covered * - * Software even if it actually retrieves a copy of Covered Software from * - * another source during runtime (such as by downloading it from the * - * Internet). * - * * - * o Links (statically or dynamically) to a library which does any of the * - * above. * - * * - * o Executes a helper program, module, or script to do any of the above. * - * * - * This list is not exclusive, but is meant to clarify our interpretation * - * of derived works with some common examples. Other people may interpret * - * the plain GPL differently, so we consider this a special exception to * - * the GPL that we apply to Covered Software. Works which meet any of * - * these conditions must conform to all of the terms of this license, * - * particularly including the GPL Section 3 requirements of providing * - * source code and allowing free redistribution of the work as a whole. * - * * - * As another special exception to the GPL terms, Aperture Labs Ltd. grants* - * permission to link the code of this program with any version of the * - * OpenSSL library which is distributed under a license identical to that * - * listed in the included docs/licenses/OpenSSL.txt file, and distribute * - * linked combinations including the two. * - * * - * Any redistribution of Covered Software, including any derived works, * - * must obey and carry forward all of the terms of this license, including * - * obeying all GPL rules and restrictions. For example, source code of * - * the whole work must be provided and free redistribution must be * - * allowed. All GPL references to "this License", are to be treated as * - * including the terms and conditions of this license text as well. * - * * - * Because this license imposes special exceptions to the GPL, Covered * - * Work may not be combined (even as part of a larger work) with plain GPL * - * software. The terms, conditions, and exceptions of this license must * - * be included as well. This license is incompatible with some other open * - * source licenses as well. In some cases we can relicense portions of * - * RFIDler or grant special permissions to use it in other open source * - * software. Please contact sales@aperturelabs.com with any such requests.* - * Similarly, we don't incorporate incompatible open source software into * - * Covered Software without special permission from the copyright holders. * - * * - * If you have any questions about the licensing restrictions on using * - * RFIDler in other works, are happy to help. As mentioned above, we also * - * offer alternative license to integrate RFIDler into proprietary * - * applications and appliances. These contracts have been sold to dozens * - * of software vendors, and generally include a perpetual license as well * - * as providing for priority support and updates. They also fund the * - * continued development of RFIDler. Please email sales@aperturelabs.com * - * for further information. * - * If you have received a written license agreement or contract for * - * Covered Software stating terms other than these, you may choose to use * - * and redistribute Covered Software under those terms instead of these. * - * * - * Source is provided to this software because we believe users have a * - * right to know exactly what a program is going to do before they run it. * - * This also allows you to audit the software for security holes (none * - * have been found so far). * - * * - * Source code also allows you to port RFIDler to new platforms, fix bugs, * - * and add new features. You are highly encouraged to send your changes * - * to the RFIDler mailing list for possible incorporation into the * - * main distribution. By sending these changes to Aperture Labs Ltd. or * - * one of the Aperture Labs Ltd. development mailing lists, or checking * - * them into the RFIDler source code repository, it is understood (unless * - * you specify otherwise) that you are offering the RFIDler Project * - * (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, * - * modify, and relicense the code. RFIDler will always be available Open * - * Source, but this is important because the inability to relicense code * - * has caused devastating problems for other Free Software projects (such * - * as KDE and NASM). We also occasionally relicense the code to third * - * parties as discussed above. If you wish to specify special license * - * conditions of your contributions, just say so when you send them. * - * * - * This program is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler * - * license file for more details (it's in a COPYING file included with * - * RFIDler, and also available from * - * https://github.com/ApertureLabsLtd/RFIDler/COPYING * - * * - ***************************************************************************/ - -// Author: Adam Laurie - - -#include -#include -#include "HardwareProfile.h" -#include "util.h" -#include "rfidler.h" -//#include "comms.h" - -// rtc -rtccTime RTC_time; // time structure -rtccDate RTC_date; // date structure - -// convert byte-reversed 8 digit hex to unsigned long -unsigned long hexreversetoulong(BYTE *hex) { - unsigned long ret = 0L; - unsigned int x; - BYTE i; - - if (strlen(hex) != 8) - return 0L; - - for (i = 0 ; i < 4 ; ++i) { - if (sscanf(hex, "%2X", &x) != 1) - return 0L; - ret += ((unsigned long) x) << i * 8; - hex += 2; - } - return ret; -} - -// convert byte-reversed 12 digit hex to unsigned long -unsigned long long hexreversetoulonglong(BYTE *hex) { - unsigned long long ret = 0LL; - BYTE tmp[9]; - - // this may seem an odd way to do it, but weird compiler issues were - // breaking direct conversion! - - tmp[8] = '\0'; - memset(tmp + 4, '0', 4); - memcpy(tmp, hex + 8, 4); - ret = hexreversetoulong(tmp); - ret <<= 32; - memcpy(tmp, hex, 8); - ret += hexreversetoulong(tmp); - return ret; -} - - diff --git a/tools/hitag2crack/crack2/Makefile b/tools/hitag2crack/crack2/Makefile index 63ba045b4..55c6a5bd9 100644 --- a/tools/hitag2crack/crack2/Makefile +++ b/tools/hitag2crack/crack2/Makefile @@ -6,10 +6,10 @@ LIBS=-pthread -D_GNU_SOURCE VPATH=../common INC=-I ../common -all: ht2crack2buildtable.c ht2crack2search.c ht2crack2gentest.c hitagcrypto.o utilpart.o ht2crackutils.o +all: ht2crack2buildtable.c ht2crack2search.c ht2crack2gentest.c hitagcrypto.o ht2crackutils.o $(CC) $(CFLAGS) $(INC) -o ht2crack2buildtable ht2crack2buildtable.c hitagcrypto.o ht2crackutils.o $(LIBS) - $(CC) $(CFLAGS) $(INC) -o ht2crack2search ht2crack2search.c hitagcrypto.o utilpart.o ht2crackutils.o $(LIBS) - $(CC) $(CFLAGS) $(INC) -o ht2crack2gentest ht2crack2gentest.c hitagcrypto.o utilpart.o ht2crackutils.o $(LIBS) + $(CC) $(CFLAGS) $(INC) -o ht2crack2search ht2crack2search.c hitagcrypto.o ht2crackutils.o $(LIBS) + $(CC) $(CFLAGS) $(INC) -o ht2crack2gentest ht2crack2gentest.c hitagcrypto.o ht2crackutils.o $(LIBS) ht2crackutils.o: ht2crackutils.c ht2crackutils.h $(CC) $(CFLAGS) -c $< @@ -17,9 +17,6 @@ ht2crackutils.o: ht2crackutils.c ht2crackutils.h hitagcrypto.o: hitagcrypto.c hitagcrypto.h $(CC) $(CFLAGS) -c $< -utilpart.o: utilpart.c util.h - $(CC) $(CFLAGS) -c $< - clean: rm -rf *.o ht2crack2buildtable ht2crack2search ht2crack2gentest diff --git a/tools/hitag2crack/crack2/ht2crack2gentest.c b/tools/hitag2crack/crack2/ht2crack2gentest.c index 0393d7f23..fb9ff484b 100644 --- a/tools/hitag2crack/crack2/ht2crack2gentest.c +++ b/tools/hitag2crack/crack2/ht2crack2gentest.c @@ -5,7 +5,6 @@ #include "ht2crackutils.h" - int makerandom(char *hex, unsigned int len, int fd) { unsigned char raw[32]; int i; diff --git a/tools/hitag2crack/crack2/ht2crack2search.c b/tools/hitag2crack/crack2/ht2crack2search.c index 7570df652..16a2e00b8 100644 --- a/tools/hitag2crack/crack2/ht2crack2search.c +++ b/tools/hitag2crack/crack2/ht2crack2search.c @@ -6,7 +6,6 @@ #include "ht2crackutils.h" - #define INPUTFILE "sorted/%02x/%02x.bin" #define DATASIZE 10 diff --git a/tools/hitag2crack/crack3/Makefile b/tools/hitag2crack/crack3/Makefile index ebd4aca83..80f1ed863 100644 --- a/tools/hitag2crack/crack3/Makefile +++ b/tools/hitag2crack/crack3/Makefile @@ -3,14 +3,14 @@ LIBS= VPATH=../common INC=-I ../common -all: ht2crack3.c ht2test.c hitagcrypto.o utilpart.o - $(CC) $(CFLAGS) $(INC) -o ht2crack3 $< hitagcrypto.o utilpart.o -lpthread $(LIBS) - $(CC) $(CFLAGS) $(INC) -o ht2test ht2test.c hitagcrypto.o utilpart.o $(LIBS) +all: ht2crack3.c ht2test.c hitagcrypto.o ht2crackutils.o + $(CC) $(CFLAGS) $(INC) -o ht2crack3 $< hitagcrypto.o ht2crackutils.o -lpthread $(LIBS) + $(CC) $(CFLAGS) $(INC) -o ht2test ht2test.c hitagcrypto.o ht2crackutils.o $(LIBS) -hitagcrypto.o: hitagcrypto.c hitagcrypto.h +ht2crackutils.o: ht2crackutils.c ht2crackutils.h $(CC) $(CFLAGS) -c $< -utilpart.o: utilpart.c util.h +hitagcrypto.o: hitagcrypto.c hitagcrypto.h $(CC) $(CFLAGS) -c $< clean: diff --git a/tools/hitag2crack/crack3/ht2crack3.c b/tools/hitag2crack/crack3/ht2crack3.c index 9e39a8e09..4f481fbf7 100644 --- a/tools/hitag2crack/crack3/ht2crack3.c +++ b/tools/hitag2crack/crack3/ht2crack3.c @@ -2,11 +2,10 @@ #include #include #include +#include -#include "HardwareProfile.h" -#include "rfidler.h" #include "hitagcrypto.h" -#include "util.h" +#include "ht2crackutils.h" // max number of NrAr pairs to load - you only need 136 good pairs, but this // is the max @@ -35,27 +34,6 @@ struct threaddata { uint64_t klowerrange; }; -void printbin(uint64_t val) { - int i; - - for (i = 0; i < 64; i++) { - if (val & 0x8000000000000000) { - printf("1"); - } else { - printf("0"); - } - val = val << 1; - } -} - -void printstate(Hitag_State *hstate) { - printf("shiftreg =\t"); - printbin(hstate->shiftreg); - printf("\n"); -} - - - // macros to pick out 4 bits in various patterns of 1s & 2s & make a new number // these and the following hitag2_crypt function taken from Rfidler #define pickbits2_2(S, A, B) ( ((S >> A) & 3) | ((S >> (B - 2)) & 0xC) ) diff --git a/tools/hitag2crack/crack3/ht2test.c b/tools/hitag2crack/crack3/ht2test.c index 0a4dabdc7..53d47cfca 100644 --- a/tools/hitag2crack/crack3/ht2test.c +++ b/tools/hitag2crack/crack3/ht2test.c @@ -1,13 +1,9 @@ #include #include +#include - -#include "HardwareProfile.h" -#include "rfidler.h" #include "hitagcrypto.h" -#include "util.h" - - +#include "ht2crackutils.h" int main(int argc, char *argv[]) { Hitag_State hstate; diff --git a/tools/hitag2crack/crack4/Makefile b/tools/hitag2crack/crack4/Makefile index fff1dfb64..418fb9930 100644 --- a/tools/hitag2crack/crack4/Makefile +++ b/tools/hitag2crack/crack4/Makefile @@ -3,11 +3,8 @@ LIBS=-lpthread VPATH=../common INC=-I ../common -all: ht2crack4.c HardwareProfile.h rfidler.h util.h utilpart.o hitagcrypto.o ht2crackutils.o - $(CC) $(CFLAGS) $(INC) -o ht2crack4 $< utilpart.o hitagcrypto.o ht2crackutils.o $(LIBS) - -utilpart.o: utilpart.c util.h - $(CC) $(CFLAGS) -c $< +all: ht2crack4.c hitagcrypto.o ht2crackutils.o + $(CC) $(CFLAGS) $(INC) -o ht2crack4 $< hitagcrypto.o ht2crackutils.o $(LIBS) hitagcrypto.o: hitagcrypto.c hitagcrypto.h $(CC) $(CFLAGS) -c $< diff --git a/tools/hitag2crack/crack5/Makefile b/tools/hitag2crack/crack5/Makefile index 1b40e2141..6ddc0150f 100644 --- a/tools/hitag2crack/crack5/Makefile +++ b/tools/hitag2crack/crack5/Makefile @@ -3,11 +3,8 @@ LIBS=-lpthread VPATH=../common INC=-I ../common -all: ht2crack5.c utilpart.o ht2crackutils.o hitagcrypto.o - $(CC) $(CFLAGS) $(INC) -O3 $< -o ht2crack5 utilpart.o ht2crackutils.o hitagcrypto.o $(LIBS) - -utilpart.o: utilpart.c util.h - $(CC) $(CFLAGS) -c $< +all: ht2crack5.c ht2crackutils.o hitagcrypto.o + $(CC) $(CFLAGS) $(INC) -O3 $< -o ht2crack5 ht2crackutils.o hitagcrypto.o $(LIBS) hitagcrypto.o: hitagcrypto.c hitagcrypto.h $(CC) $(CFLAGS) -c $< diff --git a/tools/hitag2crack/crack5gpu/Makefile b/tools/hitag2crack/crack5gpu/Makefile index cda40abee..b88fa00e8 100644 --- a/tools/hitag2crack/crack5gpu/Makefile +++ b/tools/hitag2crack/crack5gpu/Makefile @@ -9,11 +9,8 @@ LIBS=-L/opt/nvidia/cuda/lib64 -lOpenCL VPATH=../common INC=-I ../common -all: ht2crack5.c utilpart.o ht2crackutils.o hitagcrypto.o - $(CC) $(CFLAGS) $(INC) -o ht2crack5gpu $< utilpart.o ht2crackutils.o hitagcrypto.o $(LIBS) -lpthread - -utilpart.o: utilpart.c util.h - $(CC) $(CFLAGS) $(INCLUDE) -c $< +all: ht2crack5.c ht2crackutils.o hitagcrypto.o + $(CC) $(CFLAGS) $(INC) -o ht2crack5gpu $< ht2crackutils.o hitagcrypto.o $(LIBS) -lpthread hitagcrypto.o: hitagcrypto.c hitagcrypto.h $(CC) $(CFLAGS) $(INCLUDE) -c $<